sonamu 0.9.20 → 0.10.1

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 (299) 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 +210 -406
  25. package/dist/api/validator.js +5 -8
  26. package/dist/api/websocket-helpers.js +22 -33
  27. package/dist/auth/audit-log/builders.d.ts.map +1 -1
  28. package/dist/auth/audit-log/builders.js +4 -3
  29. package/dist/auth/audit-log/client-ip.d.ts +3 -0
  30. package/dist/auth/audit-log/client-ip.d.ts.map +1 -0
  31. package/dist/auth/audit-log/client-ip.js +27 -0
  32. package/dist/auth/audit-log/events.d.ts +1 -0
  33. package/dist/auth/audit-log/events.d.ts.map +1 -1
  34. package/dist/auth/audit-log/events.js +2 -2
  35. package/dist/auth/audit-log/plugin.js +30 -61
  36. package/dist/auth/audit-log-ingestor.d.ts.map +1 -1
  37. package/dist/auth/audit-log-ingestor.js +26 -43
  38. package/dist/auth/auth-generator.js +16 -41
  39. package/dist/auth/better-auth-entities.js +3 -4
  40. package/dist/auth/better-auth-request.d.ts +3 -0
  41. package/dist/auth/better-auth-request.d.ts.map +1 -0
  42. package/dist/auth/better-auth-request.js +23 -0
  43. package/dist/auth/index.js +2 -3
  44. package/dist/auth/knex-adapter.js +18 -45
  45. package/dist/auth/plugins/entity-definitions/admin.js +2 -2
  46. package/dist/auth/plugins/entity-definitions/anonymous.js +2 -2
  47. package/dist/auth/plugins/entity-definitions/api-key.js +2 -2
  48. package/dist/auth/plugins/entity-definitions/audit-log.js +2 -2
  49. package/dist/auth/plugins/entity-definitions/index.js +2 -3
  50. package/dist/auth/plugins/entity-definitions/jwt.js +2 -2
  51. package/dist/auth/plugins/entity-definitions/organization.js +2 -2
  52. package/dist/auth/plugins/entity-definitions/passkey.js +2 -2
  53. package/dist/auth/plugins/entity-definitions/phone-number.js +2 -2
  54. package/dist/auth/plugins/entity-definitions/sso.js +2 -2
  55. package/dist/auth/plugins/entity-definitions/two-factor.js +2 -2
  56. package/dist/auth/plugins/entity-definitions/types.js +1 -1
  57. package/dist/auth/plugins/entity-definitions/username.js +2 -2
  58. package/dist/auth/plugins/index.js +1 -2
  59. package/dist/auth/plugins/wrappers/admin.js +2 -3
  60. package/dist/auth/plugins/wrappers/anonymous.js +2 -3
  61. package/dist/auth/plugins/wrappers/api-key.js +2 -3
  62. package/dist/auth/plugins/wrappers/index.js +1 -2
  63. package/dist/auth/plugins/wrappers/jwt.js +2 -3
  64. package/dist/auth/plugins/wrappers/organization.js +2 -3
  65. package/dist/auth/plugins/wrappers/passkey.js +2 -3
  66. package/dist/auth/plugins/wrappers/phone-number.js +2 -3
  67. package/dist/auth/plugins/wrappers/sso.js +2 -3
  68. package/dist/auth/plugins/wrappers/two-factor.js +2 -3
  69. package/dist/auth/plugins/wrappers/username.js +2 -3
  70. package/dist/bin/build-config.js +2 -2
  71. package/dist/bin/cli.js +152 -259
  72. package/dist/bin/fixture.d.ts.map +1 -1
  73. package/dist/bin/fixture.js +55 -97
  74. package/dist/bin/hmr-hook-register.js +3 -3
  75. package/dist/bin/migrate-targets.d.ts +3 -0
  76. package/dist/bin/migrate-targets.d.ts.map +1 -0
  77. package/dist/bin/migrate-targets.js +11 -0
  78. package/dist/bin/test-command.js +25 -55
  79. package/dist/bin/ts-loader-register.js +5 -6
  80. package/dist/bin/ts-loader-registration.js +6 -13
  81. package/dist/cache/cache-manager.js +3 -4
  82. package/dist/cache/decorator.js +11 -21
  83. package/dist/cache/drivers.js +2 -3
  84. package/dist/cache/index.js +2 -3
  85. package/dist/cache/types.js +1 -1
  86. package/dist/cache-control/cache-control.js +21 -34
  87. package/dist/cache-control/types.js +1 -1
  88. package/dist/compress/compress.js +10 -10
  89. package/dist/compress/index.js +1 -2
  90. package/dist/compress/types.js +1 -1
  91. package/dist/cone/cone-generator.js +25 -63
  92. package/dist/database/_batch_update.js +26 -46
  93. package/dist/database/base-model.js +44 -97
  94. package/dist/database/base-model.types.js +1 -1
  95. package/dist/database/db.d.ts +8 -14
  96. package/dist/database/db.d.ts.map +1 -1
  97. package/dist/database/db.js +127 -72
  98. package/dist/database/knex.js +5 -8
  99. package/dist/database/puri-subset.types.js +1 -1
  100. package/dist/database/puri-wrapper.js +11 -15
  101. package/dist/database/puri.js +117 -234
  102. package/dist/database/puri.types.js +3 -4
  103. package/dist/database/transaction-context.js +4 -5
  104. package/dist/database/upsert-builder.js +109 -176
  105. package/dist/dict/en.d.ts +1 -0
  106. package/dist/dict/en.d.ts.map +1 -1
  107. package/dist/dict/en.js +4 -4
  108. package/dist/dict/index.js +2 -3
  109. package/dist/dict/ko.d.ts +1 -0
  110. package/dist/dict/ko.d.ts.map +1 -1
  111. package/dist/dict/ko.js +4 -4
  112. package/dist/dict/rc-keys.js +3 -4
  113. package/dist/dict/sd.js +8 -19
  114. package/dist/dict/sonamu-dictionary.js +141 -284
  115. package/dist/dict/types.js +1 -1
  116. package/dist/dict/utils.js +4 -5
  117. package/dist/entity/entity-manager.d.ts +2 -2
  118. package/dist/entity/entity-manager.js +34 -82
  119. package/dist/entity/entity-template-cone.js +33 -66
  120. package/dist/entity/entity.js +157 -311
  121. package/dist/env.d.ts +14 -0
  122. package/dist/env.d.ts.map +1 -0
  123. package/dist/env.js +75 -0
  124. package/dist/exceptions/error-handler.js +2 -3
  125. package/dist/exceptions/so-exceptions.js +7 -5
  126. package/dist/filter/index.js +1 -2
  127. package/dist/filter/types.js +3 -4
  128. package/dist/filter/utils.js +21 -54
  129. package/dist/index.js +9 -8
  130. package/dist/logger/category.js +6 -12
  131. package/dist/logger/configure.js +23 -34
  132. package/dist/migration/code-generation.js +147 -315
  133. package/dist/migration/index-where-predicate.js +52 -144
  134. package/dist/migration/migration-set.js +19 -33
  135. package/dist/migration/migrator.d.ts +2 -0
  136. package/dist/migration/migrator.d.ts.map +1 -1
  137. package/dist/migration/migrator.js +69 -53
  138. package/dist/migration/postgresql-schema-reader.js +126 -225
  139. package/dist/migration/slack-confirm.d.ts +1 -0
  140. package/dist/migration/slack-confirm.d.ts.map +1 -1
  141. package/dist/migration/slack-confirm.js +28 -38
  142. package/dist/migration/types.js +1 -1
  143. package/dist/naite/messaging-types.js +1 -1
  144. package/dist/naite/naite-reporter.js +15 -32
  145. package/dist/naite/naite.js +43 -76
  146. package/dist/ssr/index.js +6 -9
  147. package/dist/ssr/registry.js +10 -18
  148. package/dist/ssr/renderer.js +10 -21
  149. package/dist/ssr/types.js +1 -1
  150. package/dist/storage/base-file.js +5 -10
  151. package/dist/storage/buffered-file.js +3 -4
  152. package/dist/storage/drivers.js +2 -3
  153. package/dist/storage/index.js +2 -3
  154. package/dist/storage/s3-driver.js +5 -9
  155. package/dist/storage/storage-manager.js +5 -5
  156. package/dist/storage/types.js +1 -1
  157. package/dist/storage/uploaded-file.js +4 -6
  158. package/dist/stream/index.js +1 -2
  159. package/dist/stream/sse.js +8 -13
  160. package/dist/stream/ws-audience-resolver.js +5 -5
  161. package/dist/stream/ws-audience.js +3 -4
  162. package/dist/stream/ws-cluster-bus.js +3 -4
  163. package/dist/stream/ws-core.js +1 -1
  164. package/dist/stream/ws-delivery.js +11 -25
  165. package/dist/stream/ws-local-connection-store.js +9 -18
  166. package/dist/stream/ws-presence-store.js +43 -97
  167. package/dist/stream/ws-registry.js +17 -22
  168. package/dist/stream/ws-telemetry-memory.js +38 -45
  169. package/dist/stream/ws-telemetry-trace.js +4 -6
  170. package/dist/stream/ws-telemetry.js +82 -135
  171. package/dist/stream/ws.js +47 -91
  172. package/dist/syncer/api-parser.js +81 -147
  173. package/dist/syncer/checksum.js +14 -32
  174. package/dist/syncer/code-generator.js +29 -47
  175. package/dist/syncer/entity-operations.js +17 -27
  176. package/dist/syncer/event-batcher.js +8 -15
  177. package/dist/syncer/file-patterns.js +3 -4
  178. package/dist/syncer/file-tracking.js +6 -10
  179. package/dist/syncer/index.js +1 -2
  180. package/dist/syncer/module-loader.js +10 -26
  181. package/dist/syncer/syncer-actions.js +19 -37
  182. package/dist/syncer/syncer.js +46 -98
  183. package/dist/syncer/watcher.js +12 -26
  184. package/dist/tasks/decorator.js +7 -11
  185. package/dist/tasks/step-wrapper.js +7 -8
  186. package/dist/tasks/workflow-manager.js +18 -25
  187. package/dist/template/entity-converter.js +40 -64
  188. package/dist/template/helpers.js +32 -63
  189. package/dist/template/implementations/entity.template.js +7 -11
  190. package/dist/template/implementations/entry-server.template.js +2 -3
  191. package/dist/template/implementations/generated.template.js +25 -51
  192. package/dist/template/implementations/generated_http.template.js +31 -58
  193. package/dist/template/implementations/generated_sso.template.js +45 -85
  194. package/dist/template/implementations/init_types.template.js +4 -7
  195. package/dist/template/implementations/model.template.js +5 -10
  196. package/dist/template/implementations/model_test.template.js +2 -3
  197. package/dist/template/implementations/queries.template.js +4 -7
  198. package/dist/template/implementations/sd.template.js +17 -35
  199. package/dist/template/implementations/services.template.js +18 -30
  200. package/dist/template/implementations/view_form.template.js +72 -125
  201. package/dist/template/implementations/view_id_all_select.template.js +2 -3
  202. package/dist/template/implementations/view_list.template.js +86 -143
  203. package/dist/template/implementations/view_search_input.template.js +2 -3
  204. package/dist/template/index.js +5 -8
  205. package/dist/template/template-manager.js +13 -26
  206. package/dist/template/template-types.js +2 -3
  207. package/dist/template/template.js +7 -11
  208. package/dist/template/zod-converter.js +173 -348
  209. package/dist/testing/_relation-graph.js +18 -37
  210. package/dist/testing/bootstrap.js +5 -8
  211. package/dist/testing/data-explorer.js +34 -78
  212. package/dist/testing/dev-test-routes.js +54 -60
  213. package/dist/testing/dev-vitest-manager.js +33 -84
  214. package/dist/testing/faker-mappings.js +3 -4
  215. package/dist/testing/fixture-generator.d.ts +2 -1
  216. package/dist/testing/fixture-generator.d.ts.map +1 -1
  217. package/dist/testing/fixture-generator.js +159 -321
  218. package/dist/testing/fixture-loader.js +2 -2
  219. package/dist/testing/fixture-manager.d.ts.map +1 -1
  220. package/dist/testing/fixture-manager.js +124 -227
  221. package/dist/testing/global-setup.d.ts.map +1 -1
  222. package/dist/testing/global-setup.js +29 -17
  223. package/dist/testing/index.d.ts +1 -0
  224. package/dist/testing/index.d.ts.map +1 -1
  225. package/dist/testing/index.js +5 -4
  226. package/dist/testing/naite-vitest-reporter.js +2 -3
  227. package/dist/testing/parallel-db-manager.js +5 -3
  228. package/dist/testing/vitest-helpers.d.ts.map +1 -1
  229. package/dist/testing/vitest-helpers.js +15 -12
  230. package/dist/types/types.d.ts +14 -14
  231. package/dist/types/types.js +27 -50
  232. package/dist/ui/ai-api.js +6 -11
  233. package/dist/ui/ai-client.js +86 -134
  234. package/dist/ui/api.js +100 -196
  235. package/dist/ui/cdd-service.js +78 -130
  236. package/dist/ui/cdd-types.js +1 -1
  237. package/dist/ui-web/assets/{index-Df8q-fhb.js → index-DFStGyd0.js} +49 -49
  238. package/dist/ui-web/assets/index-Dx4ap5i4.css +1 -0
  239. package/dist/ui-web/index.html +2 -2
  240. package/dist/utils/async-utils.js +13 -25
  241. package/dist/utils/class-name.js +3 -4
  242. package/dist/utils/console-util.js +11 -26
  243. package/dist/utils/controller.d.ts.map +1 -1
  244. package/dist/utils/controller.js +14 -12
  245. package/dist/utils/esm-utils.js +5 -8
  246. package/dist/utils/formatter.js +10 -22
  247. package/dist/utils/fs-utils.js +14 -25
  248. package/dist/utils/lodash-able.js +3 -4
  249. package/dist/utils/model.js +7 -14
  250. package/dist/utils/object-utils.js +41 -73
  251. package/dist/utils/path-utils.js +5 -9
  252. package/dist/utils/process-utils.js +4 -7
  253. package/dist/utils/sql-parser.js +6 -13
  254. package/dist/utils/type-utils.js +16 -26
  255. package/dist/utils/utils.js +18 -40
  256. package/dist/utils/zod-error.js +9 -16
  257. package/dist/vector/chunking.js +24 -37
  258. package/dist/vector/config.js +2 -2
  259. package/dist/vector/embedding.js +8 -19
  260. package/dist/vector/index.js +1 -2
  261. package/dist/vector/types.js +1 -1
  262. package/package.json +8 -8
  263. package/src/__tests__/env.test.ts +127 -0
  264. package/src/api/__tests__/config.test.ts +10 -1
  265. package/src/api/config.ts +4 -12
  266. package/src/api/sonamu.ts +28 -33
  267. package/src/auth/audit-log/builders.ts +3 -0
  268. package/src/auth/audit-log/client-ip.ts +38 -0
  269. package/src/auth/audit-log/events.ts +1 -0
  270. package/src/auth/audit-log-ingestor.ts +22 -15
  271. package/src/auth/better-auth-request.ts +20 -0
  272. package/src/bin/__tests__/migrate-targets.test.ts +28 -0
  273. package/src/bin/__tests__/test-command.test.ts +82 -1
  274. package/src/bin/cli.ts +9 -18
  275. package/src/bin/fixture.ts +5 -4
  276. package/src/bin/migrate-targets.ts +7 -0
  277. package/src/bin/test-command.ts +2 -2
  278. package/src/database/__tests__/db.test.ts +175 -0
  279. package/src/database/db.ts +193 -71
  280. package/src/dict/en.ts +2 -0
  281. package/src/dict/ko.ts +2 -0
  282. package/src/env.ts +123 -0
  283. package/src/migration/__tests__/migrator.test.ts +149 -0
  284. package/src/migration/migrator.ts +74 -17
  285. package/src/migration/slack-confirm.ts +21 -0
  286. package/src/skills/sonamu/database.md +1 -1
  287. package/src/skills/sonamu/puri.md +33 -0
  288. package/src/skills/sonamu/testing-devrunner.md +1 -1
  289. package/src/stream/ws-telemetry-memory.ts +2 -2
  290. package/src/syncer/checksum.ts +7 -12
  291. package/src/testing/fixture-generator.ts +2 -1
  292. package/src/testing/fixture-manager.ts +3 -4
  293. package/src/testing/global-setup.ts +42 -18
  294. package/src/testing/index.ts +1 -0
  295. package/src/testing/vitest-helpers.ts +14 -0
  296. package/src/utils/controller.ts +14 -7
  297. package/tsdown.api.config.ts +6 -0
  298. package/dist/_virtual/rolldown_runtime.js +0 -39
  299. package/dist/ui-web/assets/index-D4rYm-Xz.css +0 -1
@@ -1,6 +1,9 @@
1
- import { __esmMin } from "../_virtual/rolldown_runtime.js";
1
+ import { __esmMin } from "../_virtual/_rolldown/runtime.js";
2
+ import { getSonamuEnvironment, init_env, readAllEnvironmentSnapshots } from "../env.js";
2
3
  import { DB, init_db } from "../database/db.js";
3
4
  import { BASE_FIELD_MAPPINGS, init_better_auth_entities } from "../auth/better-auth-entities.js";
5
+ import { convertFastifyHeadersToStandard, init_utils, merge } from "../utils/utils.js";
6
+ import { createBetterAuthRequest, init_better_auth_request } from "../auth/better-auth-request.js";
4
7
  import { CachePresets, applyCacheHeaders, init_cache_control } from "../cache-control/cache-control.js";
5
8
  import { init_compress, toFastifyCompressOption } from "../compress/compress.js";
6
9
  import { SD, init_sd, setSDConfig } from "../dict/sd.js";
@@ -12,22 +15,18 @@ import { WebSocketRuntime, init_ws } from "../stream/ws.js";
12
15
  import { centerText, init_console_util } from "../utils/console-util.js";
13
16
  import { init_controller, isDaemonServer } from "../utils/controller.js";
14
17
  import { exists, fileExists, init_fs_utils } from "../utils/fs-utils.js";
15
- import { convertFastifyHeadersToStandard, init_utils, merge } from "../utils/utils.js";
16
18
  import { getSecrets, init_secret } from "./secret.js";
17
19
  import { createWebSocketReplyStub, init_websocket_helpers, resolveIntegratedViteHmrOptions, resolveWebSocketCloseDescriptor, resolveWebSocketPluginOptions } from "./websocket-helpers.js";
18
20
  import { AsyncLocalStorage } from "async_hooks";
19
21
  import { dispose } from "@logtape/logtape";
20
- import fs from "fs/promises";
21
22
  import path from "path";
23
+ import fs from "fs/promises";
22
24
  import chalk from "chalk";
23
25
  import os from "os";
24
26
  import mime, { lookup } from "mime-types";
25
-
26
27
  //#region src/api/sonamu.ts
27
28
  function getWebSocketTelemetryContext(ws) {
28
- if (!isTelemetryContextProvider(ws)) {
29
- return {};
30
- }
29
+ if (!isTelemetryContextProvider(ws)) return {};
31
30
  return ws.getTelemetryContext();
32
31
  }
33
32
  function isTelemetryContextProvider(ws) {
@@ -38,29 +37,26 @@ function isTelemetryContextProvider(ws) {
38
37
  */
39
38
  function defaultKeyGenerator(file) {
40
39
  const ext = mime.extension(file.mimetype) || "bin";
41
- const timestamp = Date.now();
42
- const random = Math.random().toString(36).slice(2, 8);
43
- return `uploads/${timestamp}-${random}.${ext}`;
40
+ return `uploads/${Date.now()}-${Math.random().toString(36).slice(2, 8)}.${ext}`;
44
41
  }
45
42
  function formatTime(ms) {
46
- const formatted = ms >= 1e3 ? `${(ms / 1e3).toFixed(2)}s` : `${Math.round(ms)}ms`;
47
- return ` (${formatted})`;
43
+ return ` (${ms >= 1e3 ? `${(ms / 1e3).toFixed(2)}s` : `${Math.round(ms)}ms`})`;
48
44
  }
49
45
  function isLocalHost(host) {
50
46
  return LOCAL_HOSTS.has(host) || host.endsWith(".local");
51
47
  }
52
48
  function runGuards({ guards, config, request, api }) {
53
- for (const guard of guards ?? []) {
54
- config.guardHandler(guard, request, api);
55
- }
49
+ for (const guard of guards ?? []) config.guardHandler(guard, request, api);
56
50
  }
57
51
  var SonamuClass, Sonamu, LOCAL_HOSTS;
58
52
  var init_sonamu = __esmMin((() => {
59
53
  init_better_auth_entities();
54
+ init_better_auth_request();
60
55
  init_cache_control();
61
56
  init_compress();
62
57
  init_db();
63
58
  init_sd();
59
+ init_env();
64
60
  init_so_exceptions();
65
61
  init_buffered_file();
66
62
  init_uploaded_file();
@@ -78,33 +74,26 @@ var init_sonamu = __esmMin((() => {
78
74
  asyncLocalStorage = new AsyncLocalStorage();
79
75
  getContext() {
80
76
  const store = this.asyncLocalStorage.getStore();
81
- if (store?.context) {
82
- return store.context;
83
- }
84
- if (process.env.NODE_ENV === "test") {
85
- return {
86
- transport: "http",
87
- request: null,
88
- reply: null,
89
- headers: {},
90
- createSSE: (schema) => createMockSSEFactory(schema),
91
- locale: "",
92
- user: null,
93
- session: null,
94
- naiteStore: new Map()
95
- };
96
- } else {
97
- throw new Error("Sonamu cannot find context");
98
- }
77
+ if (store?.context) return store.context;
78
+ if (process.env.NODE_ENV === "test") return {
79
+ transport: "http",
80
+ request: null,
81
+ reply: null,
82
+ headers: {},
83
+ createSSE: (schema) => createMockSSEFactory(schema),
84
+ locale: "",
85
+ user: null,
86
+ session: null,
87
+ naiteStore: /* @__PURE__ */ new Map()
88
+ };
89
+ else throw new Error("Sonamu cannot find context");
99
90
  }
100
91
  _apiRootPath = null;
101
92
  set apiRootPath(apiRootPath) {
102
93
  this._apiRootPath = apiRootPath;
103
94
  }
104
95
  get apiRootPath() {
105
- if (this._apiRootPath === null) {
106
- throw new Error("Sonamu has not been initialized");
107
- }
96
+ if (this._apiRootPath === null) throw new Error("Sonamu has not been initialized");
108
97
  return this._apiRootPath;
109
98
  }
110
99
  get appRootPath() {
@@ -115,9 +104,7 @@ var init_sonamu = __esmMin((() => {
115
104
  this._dbConfig = dbConfig;
116
105
  }
117
106
  get dbConfig() {
118
- if (this._dbConfig === null) {
119
- throw new Error("Sonamu has not been initialized");
120
- }
107
+ if (this._dbConfig === null) throw new Error("Sonamu has not been initialized");
121
108
  return this._dbConfig;
122
109
  }
123
110
  _syncer = null;
@@ -125,9 +112,7 @@ var init_sonamu = __esmMin((() => {
125
112
  this._syncer = syncer;
126
113
  }
127
114
  get syncer() {
128
- if (this._syncer === null) {
129
- throw new Error("Sonamu has not been initialized");
130
- }
115
+ if (this._syncer === null) throw new Error("Sonamu has not been initialized");
131
116
  return this._syncer;
132
117
  }
133
118
  _config = null;
@@ -135,9 +120,7 @@ var init_sonamu = __esmMin((() => {
135
120
  this._config = config;
136
121
  }
137
122
  get config() {
138
- if (this._config === null) {
139
- throw new Error("Sonamu has not been initialized");
140
- }
123
+ if (this._config === null) throw new Error("Sonamu has not been initialized");
141
124
  return this._config;
142
125
  }
143
126
  secrets = getSecrets();
@@ -146,9 +129,7 @@ var init_sonamu = __esmMin((() => {
146
129
  * StorageManager 인스턴스
147
130
  */
148
131
  get storage() {
149
- if (!this._storage) {
150
- throw new Error("Storage has not been initialized. Check storage config.");
151
- }
132
+ if (!this._storage) throw new Error("Storage has not been initialized. Check storage config.");
152
133
  return this._storage;
153
134
  }
154
135
  _cache = null;
@@ -156,23 +137,17 @@ var init_sonamu = __esmMin((() => {
156
137
  * CacheManager 인스턴스 (BentoCache)
157
138
  */
158
139
  get cache() {
159
- if (!this._cache) {
160
- throw new Error("Cache has not been initialized. Check cache config in sonamu.config.ts.");
161
- }
140
+ if (!this._cache) throw new Error("Cache has not been initialized. Check cache config in sonamu.config.ts.");
162
141
  return this._cache;
163
142
  }
164
143
  _workflows = null;
165
144
  get workflows() {
166
- if (this._workflows === null) {
167
- throw new Error("Sonamu has not been initialized");
168
- }
145
+ if (this._workflows === null) throw new Error("Sonamu has not been initialized");
169
146
  return this._workflows;
170
147
  }
171
148
  _auth = null;
172
149
  get auth() {
173
- if (!this._auth) {
174
- throw new Error("Auth has not been initialized. Check auth config in sonamu.config.ts.");
175
- }
150
+ if (!this._auth) throw new Error("Auth has not been initialized. Check auth config in sonamu.config.ts.");
176
151
  return this._auth;
177
152
  }
178
153
  _devVitestManager = null;
@@ -183,11 +158,9 @@ var init_sonamu = __esmMin((() => {
183
158
  this._devVitestManager = manager;
184
159
  }
185
160
  _websocketRuntime = null;
186
- websocketPluginServers = new WeakSet();
161
+ websocketPluginServers = /* @__PURE__ */ new WeakSet();
187
162
  get websocketRuntime() {
188
- if (!this._websocketRuntime) {
189
- throw new Error("WebSocket runtime has not been initialized.");
190
- }
163
+ if (!this._websocketRuntime) throw new Error("WebSocket runtime has not been initialized.");
191
164
  return this._websocketRuntime;
192
165
  }
193
166
  set websocketRuntime(runtime) {
@@ -196,30 +169,30 @@ var init_sonamu = __esmMin((() => {
196
169
  watcher = null;
197
170
  server = null;
198
171
  async initForTesting() {
199
- await this.init(true, false, undefined, true);
172
+ await this.init(true, false, void 0, true);
200
173
  }
201
174
  async init(doSilent = false, enableSync = true, apiRootPath, forTesting = false) {
202
175
  this.forTesting = forTesting;
203
- if (this.isInitialized) {
204
- return;
205
- }
176
+ if (this.isInitialized) return;
206
177
  const initStart = performance.now();
207
178
  const { findApiRootPath } = await import("../utils/utils.js");
208
179
  this.apiRootPath = apiRootPath ?? findApiRootPath();
180
+ const baseEnvBeforeConfigLoad = { ...process.env };
209
181
  const configStart = performance.now();
210
182
  const { loadConfig } = await import("./config.js");
211
183
  this.config = await loadConfig(this.apiRootPath);
212
184
  const configTime = performance.now() - configStart;
213
185
  setSDConfig(this.config.i18n);
214
186
  this.config.database.database = this.config.database.database ?? "pg";
187
+ this.config.database.defaultOptions = this.config.database.defaultOptions ?? {};
215
188
  this.config.database.defaultOptions.client = this.config.database.database ?? "pg";
216
189
  const { configureLogTape } = await import("../logger/configure.js");
217
- if (this.config.logging !== false) {
218
- await configureLogTape({ ...this.config.logging });
219
- }
220
- const { DB: DB$1 } = await import("../database/db.js");
221
- this.dbConfig = DB$1.generateDBConfig(this.config.database);
222
- DB$1.setConfig(this.dbConfig);
190
+ if (this.config.logging !== false) await configureLogTape({ ...this.config.logging });
191
+ const { DB } = await import("../database/db.js");
192
+ const { isLocal: isLocalEnvironment } = await import("../utils/controller.js");
193
+ const environmentSnapshots = isLocalEnvironment() ? readAllEnvironmentSnapshots(this.apiRootPath, baseEnvBeforeConfigLoad) : void 0;
194
+ this.dbConfig = DB.generateDBConfig(this.config.database, this.config.projectName, environmentSnapshots);
195
+ DB.setConfig(this.dbConfig);
223
196
  const { EntityManager } = await import("../entity/entity-manager.js");
224
197
  await EntityManager.autoload(doSilent);
225
198
  await this.initializeCache(this.config.server.cache, forTesting);
@@ -260,15 +233,13 @@ var init_sonamu = __esmMin((() => {
260
233
  _initElapsed = 0;
261
234
  _configElapsed = 0;
262
235
  async createServer(initOptions) {
263
- if (!this.isInitialized) {
264
- await this.init(initOptions?.doSilent, initOptions?.enableSync);
265
- }
236
+ if (!this.isInitialized) await this.init(initOptions?.doSilent, initOptions?.enableSync);
266
237
  const options = this.config.server;
267
238
  const { default: fastify } = await import("fastify");
268
239
  const { getLogTapeFastifyLogger } = await import("@logtape/fastify");
269
240
  const server = fastify({
270
241
  ...options.fastify,
271
- logger: this.config.logging !== false ? getLogTapeFastifyLogger({ category: this.config.logging?.fastifyCategory ?? ["fastify"] }) : undefined
242
+ logger: this.config.logging !== false ? getLogTapeFastifyLogger({ category: this.config.logging?.fastifyCategory ?? ["fastify"] }) : void 0
272
243
  });
273
244
  this.server = server;
274
245
  this.websocketRuntime = new WebSocketRuntime(options.websocket);
@@ -276,26 +247,18 @@ var init_sonamu = __esmMin((() => {
276
247
  const { StorageManager } = await import("../storage/storage-manager.js");
277
248
  this._storage = new StorageManager(options.storage);
278
249
  }
279
- if (options.plugins) {
280
- await this.registerPlugins(server, options.plugins);
281
- }
282
- if (options.auth) {
283
- await this.registerBetterAuth(server, options.auth);
284
- }
250
+ if (options.plugins) await this.registerPlugins(server, options.plugins);
251
+ if (options.auth) await this.registerBetterAuth(server, options.auth);
285
252
  await this.withFastify(server, options.apiConfig, {
286
253
  enableSync: initOptions?.enableSync,
287
254
  doSilent: initOptions?.doSilent
288
255
  });
289
256
  await this.boot(server, options);
290
- if (!initOptions?.doSilent) {
291
- this.printStartupSummary();
292
- }
257
+ if (!initOptions?.doSilent) this.printStartupSummary();
293
258
  return server;
294
259
  }
295
260
  async withFastify(server, config, options) {
296
- if (!this.isInitialized) {
297
- await this.init(options?.doSilent, options?.enableSync);
298
- }
261
+ if (!this.isInitialized) await this.init(options?.doSilent, options?.enableSync);
299
262
  this.server = server;
300
263
  this.websocketRuntime ??= new WebSocketRuntime(this.config.server.websocket);
301
264
  const timezone = this.config.api.timezone;
@@ -305,9 +268,7 @@ var init_sonamu = __esmMin((() => {
305
268
  const DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssXXX";
306
269
  server.setReplySerializer((payload) => {
307
270
  return JSON.stringify(payload, (_key, value) => {
308
- if (typeof value === "string" && ISO_DATE_REGEX.test(value)) {
309
- return formatInTimeZone(new Date(value), timezone, DATE_FORMAT);
310
- }
271
+ if (typeof value === "string" && ISO_DATE_REGEX.test(value)) return formatInTimeZone(new Date(value), timezone, DATE_FORMAT);
311
272
  return value;
312
273
  });
313
274
  });
@@ -341,19 +302,14 @@ var init_sonamu = __esmMin((() => {
341
302
  threshold: pluginCompress.threshold,
342
303
  encodings: pluginCompress.encodings,
343
304
  customTypes: pluginCompress.customTypes
344
- } : undefined;
305
+ } : void 0;
345
306
  if (isLocal()) {
346
307
  const disableIntegratedWeb = process.env.SONAMU_DISABLE_INTEGRATED_WEB === "yes";
347
- if (hasWeb && !disableIntegratedWeb) {
348
- await this.setupDevServerWithVite(server, webPath, config);
349
- } else {
350
- this.setupDevServer(server, config);
351
- }
308
+ if (hasWeb && !disableIntegratedWeb) await this.setupDevServerWithVite(server, webPath, config);
309
+ else this.setupDevServer(server, config);
352
310
  } else {
353
311
  for (const api of this.syncer.apis) {
354
- if (this.syncer.models[api.modelName] === undefined) {
355
- throw new Error(`정의되지 않은 모델에 접근 ${api.modelName}`);
356
- }
312
+ if (this.syncer.models[api.modelName] === void 0) throw new Error(`정의되지 않은 모델에 접근 ${api.modelName}`);
357
313
  if (api.websocketOptions) {
358
314
  server.route({
359
315
  method: "GET",
@@ -382,26 +338,17 @@ var init_sonamu = __esmMin((() => {
382
338
  */
383
339
  handleDevApiRequest(request, config) {
384
340
  const matchedApi = this.findMatchedApi(request);
385
- if (!matchedApi) {
386
- throw new NotFoundException(SD("error.api.notFound"));
387
- }
388
- if (matchedApi.websocketOptions) {
389
- return this.createWebSocketUpgradeRequiredHandler();
390
- }
341
+ if (!matchedApi) throw new NotFoundException(SD("error.api.notFound"));
342
+ if (matchedApi.websocketOptions) return this.createWebSocketUpgradeRequiredHandler();
391
343
  return this.createApiHandler(matchedApi, config);
392
344
  }
393
345
  findMatchedApi(request) {
394
346
  const url = this.getPathnameFromUrl(request.url);
395
347
  const method = request.method;
396
- if (!url.startsWith(this.config.api.route.prefix)) {
397
- return undefined;
398
- }
348
+ if (!url.startsWith(this.config.api.route.prefix)) return;
399
349
  return this.syncer.apis.find((api) => {
400
- if (this.syncer.models[api.modelName] === undefined) {
401
- return false;
402
- }
403
- const apiMethod = api.options.httpMethod ?? "GET";
404
- if (apiMethod !== method) return false;
350
+ if (this.syncer.models[api.modelName] === void 0) return false;
351
+ if ((api.options.httpMethod ?? "GET") !== method) return false;
405
352
  const fullPath = this.config.api.route.prefix + api.path;
406
353
  return this.isPathPatternMatch(fullPath, url);
407
354
  });
@@ -416,9 +363,7 @@ var init_sonamu = __esmMin((() => {
416
363
  url: `${this.config.api.route.prefix}/*`,
417
364
  handler: async (request, reply) => {
418
365
  const handler = this.handleDevApiRequest(request, config);
419
- if (handler) {
420
- return handler(request, reply);
421
- }
366
+ if (handler) return handler(request, reply);
422
367
  throw new NotFoundException(SD("error.api.notFound"));
423
368
  },
424
369
  wsHandler: async (connection, request) => {
@@ -436,9 +381,7 @@ var init_sonamu = __esmMin((() => {
436
381
  url: `${this.config.api.route.prefix}/*`,
437
382
  handler: async (request, reply) => {
438
383
  const handler = this.handleDevApiRequest(request, config);
439
- if (handler) {
440
- return handler(request, reply);
441
- }
384
+ if (handler) return handler(request, reply);
442
385
  throw new NotFoundException(SD("error.api.notFound"));
443
386
  }
444
387
  });
@@ -465,9 +408,7 @@ var init_sonamu = __esmMin((() => {
465
408
  appType: "custom"
466
409
  });
467
410
  server.use((req, res, next) => {
468
- if (req.url?.startsWith(this.config.api.route.prefix) || req.url?.startsWith("/sonamu-ui")) {
469
- return next();
470
- }
411
+ if (req.url?.startsWith(this.config.api.route.prefix) || req.url?.startsWith("/sonamu-ui")) return next();
471
412
  return this.viteServer.middlewares(req, res, next);
472
413
  });
473
414
  server.route({
@@ -475,9 +416,7 @@ var init_sonamu = __esmMin((() => {
475
416
  url: `${this.config.api.route.prefix}/*`,
476
417
  handler: async (request, reply) => {
477
418
  const result = this.handleDevApiRequest(request, config);
478
- if (result) {
479
- return result(request, reply);
480
- }
419
+ if (result) return result(request, reply);
481
420
  throw new NotFoundException(SD("error.api.notFound"));
482
421
  },
483
422
  wsHandler: async (connection, request) => {
@@ -495,9 +434,7 @@ var init_sonamu = __esmMin((() => {
495
434
  url: `${this.config.api.route.prefix}/*`,
496
435
  handler: async (request, reply) => {
497
436
  const result = this.handleDevApiRequest(request, config);
498
- if (result) {
499
- return result(request, reply);
500
- }
437
+ if (result) return result(request, reply);
501
438
  throw new NotFoundException(SD("error.api.notFound"));
502
439
  }
503
440
  });
@@ -515,8 +452,7 @@ var init_sonamu = __esmMin((() => {
515
452
  return html;
516
453
  }
517
454
  try {
518
- const fs$1 = await import("node:fs/promises");
519
- let template = await fs$1.readFile(path.join(this.viteServer.config.root, "index.html"), "utf-8");
455
+ let template = await (await import("node:fs/promises")).readFile(path.join(this.viteServer.config.root, "index.html"), "utf-8");
520
456
  template = await this.viteServer.transformIndexHtml(url, template);
521
457
  reply.type("text/html");
522
458
  return template;
@@ -531,11 +467,9 @@ var init_sonamu = __esmMin((() => {
531
467
  server.addHook("onClose", async () => {
532
468
  await this.viteServer.close();
533
469
  });
534
- const chalk$1 = (await import("chalk")).default;
535
- if ("port" in hmr) {
536
- console.log(chalk$1.dim(`✓ Vite HMR using dedicated websocket port ${hmr.port} to avoid Fastify websocket conflicts`));
537
- }
538
- console.log(chalk$1.dim("✓ Vite dev server integrated"));
470
+ const chalk = (await import("chalk")).default;
471
+ if ("port" in hmr) console.log(chalk.dim(`✓ Vite HMR using dedicated websocket port ${hmr.port} to avoid Fastify websocket conflicts`));
472
+ console.log(chalk.dim("✓ Vite dev server integrated"));
539
473
  }
540
474
  async setupStaticWebServer(server, config, globalCompressOptions) {
541
475
  const webDistPath = path.join(this.apiRootPath, "web-dist", "client");
@@ -551,14 +485,10 @@ var init_sonamu = __esmMin((() => {
551
485
  console.warn(`⚠ SSR entry not found: ${ssrEntryPath}`);
552
486
  console.warn(" SSR will be disabled. Only CSR will work.");
553
487
  }
554
- if (ssrAvailable) {
555
- if (await exists(ssrRoutesPath)) {
556
- await import(ssrRoutesPath);
557
- console.log("✓ SSR routes loaded");
558
- } else {
559
- console.warn(`⚠ SSR routes not found: ${ssrRoutesPath}`);
560
- }
561
- }
488
+ if (ssrAvailable) if (await exists(ssrRoutesPath)) {
489
+ await import(ssrRoutesPath);
490
+ console.log("✓ SSR routes loaded");
491
+ } else console.warn(`⚠ SSR routes not found: ${ssrRoutesPath}`);
562
492
  server.get("/assets/:filename", async (request, reply) => {
563
493
  const requestedFile = request.params.filename;
564
494
  const assetsDir = path.join(webDistPath, "assets");
@@ -584,11 +514,10 @@ var init_sonamu = __esmMin((() => {
584
514
  };
585
515
  if (/^index-[a-f0-9]+\.(js|css)$/.test(normalizedRequestedFile)) {
586
516
  const ext = normalizedRequestedFile.split(".").pop();
587
- const files = await fs.readdir(assetsDir);
588
- const currentFile = files.find((f) => f.startsWith("index-") && f.endsWith(`.${ext}`));
517
+ const currentFile = (await fs.readdir(assetsDir)).find((f) => f.startsWith("index-") && f.endsWith(`.${ext}`));
589
518
  if (currentFile) {
590
- const filePath$1 = path.join(assetsDir, currentFile);
591
- const content = await fs.readFile(filePath$1);
519
+ const filePath = path.join(assetsDir, currentFile);
520
+ const content = await fs.readFile(filePath);
592
521
  reply.type(ext === "js" ? "application/javascript" : "text/css");
593
522
  applyCacheHeaders(reply, getCacheControlForAsset());
594
523
  return reply.send(content);
@@ -599,9 +528,7 @@ var init_sonamu = __esmMin((() => {
599
528
  const content = await fs.readFile(filePath);
600
529
  const ext = normalizedRequestedFile.split(".").pop();
601
530
  reply.type(ext === "js" ? "application/javascript" : ext === "css" ? "text/css" : "");
602
- if (normalizedRequestedFile.includes("-")) {
603
- applyCacheHeaders(reply, getCacheControlForAsset());
604
- }
531
+ if (normalizedRequestedFile.includes("-")) applyCacheHeaders(reply, getCacheControlForAsset());
605
532
  return reply.send(content);
606
533
  }
607
534
  reply.status(404).send();
@@ -610,21 +537,18 @@ var init_sonamu = __esmMin((() => {
610
537
  const { getSSRRoutes } = await import("../ssr/index.js");
611
538
  const { renderSSR } = await import("../ssr/renderer.js");
612
539
  const ssrRoutes = getSSRRoutes();
613
- for (const route of ssrRoutes) {
614
- server.route({
615
- method: ["GET", "HEAD"],
616
- url: route.path,
617
- compress: toFastifyCompressOption(route.compress ?? true, globalCompressOptions),
618
- handler: async (request, reply) => {
619
- const url = request.url;
620
- console.log(`[SSR] Matched route: ${route.path}`);
621
- const params = this.extractPathParams(route.path, url);
622
- const html = await renderSSR(url, route, params, request, reply, config);
623
- reply.type("text/html");
624
- return html;
625
- }
626
- });
627
- }
540
+ for (const route of ssrRoutes) server.route({
541
+ method: ["GET", "HEAD"],
542
+ url: route.path,
543
+ compress: toFastifyCompressOption(route.compress ?? true, globalCompressOptions),
544
+ handler: async (request, reply) => {
545
+ const url = request.url;
546
+ console.log(`[SSR] Matched route: ${route.path}`);
547
+ const html = await renderSSR(url, route, this.extractPathParams(route.path, url), request, reply, config);
548
+ reply.type("text/html");
549
+ return html;
550
+ }
551
+ });
628
552
  }
629
553
  server.route({
630
554
  method: ["GET", "HEAD"],
@@ -642,9 +566,7 @@ var init_sonamu = __esmMin((() => {
642
566
  method: request.method
643
567
  };
644
568
  const csrCacheConfig = config.cacheControlHandler(csrCacheReq);
645
- if (csrCacheConfig) {
646
- applyCacheHeaders(reply, csrCacheConfig);
647
- }
569
+ if (csrCacheConfig) applyCacheHeaders(reply, csrCacheConfig);
648
570
  }
649
571
  const requestPath = this.getPathnameFromUrl(request.url);
650
572
  const safeFilePath = this.resolvePathWithinBaseDir(webDistPath, requestPath);
@@ -686,43 +608,34 @@ var init_sonamu = __esmMin((() => {
686
608
  const parts = request.parts({ limits: api.uploadOptions.limits });
687
609
  const fields = {};
688
610
  if (api.uploadOptions.consume === "buffer" || !api.uploadOptions.consume) {
689
- for await (const part of parts) {
690
- if (part.type === "file") {
691
- const buffer = await part.toBuffer();
692
- files.bufferedFiles.push(new BufferedFile(part, buffer));
693
- } else if (part.type === "field") {
694
- fields[part.fieldname] = String(part.value);
695
- }
696
- }
611
+ for await (const part of parts) if (part.type === "file") {
612
+ const buffer = await part.toBuffer();
613
+ files.bufferedFiles.push(new BufferedFile(part, buffer));
614
+ } else if (part.type === "field") fields[part.fieldname] = String(part.value);
697
615
  } else if (api.uploadOptions.consume === "stream") {
698
616
  const diskName = api.uploadOptions.destination;
699
617
  const disk = this.storage.use(diskName);
700
618
  const keyGenerator = api.uploadOptions.keyGenerator ?? this.config.server.storage?.keyGenerator ?? defaultKeyGenerator;
701
- for await (const part of parts) {
702
- if (part.type === "file") {
703
- const key = await keyGenerator({
704
- filename: part.filename,
705
- mimetype: part.mimetype
706
- });
707
- await disk.putStream(key, part.file, { contentType: part.mimetype });
708
- const url = await disk.getUrl(key);
709
- const signedUrl = await disk.getSignedUrl(key);
710
- files.uploadedFiles.push(new UploadedFile({
711
- filename: part.filename,
712
- mimetype: part.mimetype,
713
- size: part.file.bytesRead,
714
- url,
715
- signedUrl,
716
- key,
717
- diskName
718
- }));
719
- } else if (part.type === "field") {
720
- fields[part.fieldname] = String(part.value);
721
- }
722
- }
619
+ for await (const part of parts) if (part.type === "file") {
620
+ const key = await keyGenerator({
621
+ filename: part.filename,
622
+ mimetype: part.mimetype
623
+ });
624
+ await disk.putStream(key, part.file, { contentType: part.mimetype });
625
+ const url = await disk.getUrl(key);
626
+ const signedUrl = await disk.getSignedUrl(key);
627
+ files.uploadedFiles.push(new UploadedFile({
628
+ filename: part.filename,
629
+ mimetype: part.mimetype,
630
+ size: part.file.bytesRead,
631
+ url,
632
+ signedUrl,
633
+ key,
634
+ diskName
635
+ }));
636
+ } else if (part.type === "field") fields[part.fieldname] = String(part.value);
723
637
  }
724
- const qs = await import("qs");
725
- const parsed = qs.default.parse(fields);
638
+ const parsed = (await import("qs")).default.parse(fields);
726
639
  Object.assign(body, parsed);
727
640
  }
728
641
  const { fastifyCaster } = await import("./caster.js");
@@ -734,30 +647,20 @@ var init_sonamu = __esmMin((() => {
734
647
  const messages = humanizeZodError(e).map((issue) => issue.message).join(" ");
735
648
  const { BadRequestException } = await import("../exceptions/so-exceptions.js");
736
649
  throw new BadRequestException(messages, { zodError: e });
737
- } else {
738
- throw e;
739
- }
650
+ } else throw e;
740
651
  }
741
652
  reply.type(api.options.contentType ?? "application/json");
742
653
  const apiCacheConfig = this.getApiCacheControl(api, request, config);
743
- if (apiCacheConfig) {
744
- applyCacheHeaders(reply, apiCacheConfig);
745
- }
654
+ if (apiCacheConfig) applyCacheHeaders(reply, apiCacheConfig);
746
655
  if (api.uploadOptions) {
747
656
  const consume = api.uploadOptions.consume ?? "buffer";
748
- if (consume === "buffer") {
749
- context.bufferedFiles = files.bufferedFiles;
750
- } else if (consume === "stream") {
751
- context.uploadedFiles = files.uploadedFiles;
752
- }
657
+ if (consume === "buffer") context.bufferedFiles = files.bufferedFiles;
658
+ else if (consume === "stream") context.uploadedFiles = files.uploadedFiles;
753
659
  }
754
660
  const { ApiParamType } = await import("../types/types.js");
755
661
  const args = api.parameters.map((param) => {
756
- if (ApiParamType.isContext(param.type)) {
757
- return context;
758
- } else {
759
- return reqBody[param.name];
760
- }
662
+ if (ApiParamType.isContext(param.type)) return context;
663
+ else return reqBody[param.name];
761
664
  });
762
665
  return this.invokeModelMethod(api, args, reply);
763
666
  });
@@ -787,8 +690,7 @@ var init_sonamu = __esmMin((() => {
787
690
  socket.close(1008, "WebSocket route not found");
788
691
  return;
789
692
  }
790
- const handler = this.createWebSocketHandler(matchedApi, config);
791
- await handler({ socket }, request);
693
+ await this.createWebSocketHandler(matchedApi, config)({ socket }, request);
792
694
  }
793
695
  createWebSocketHandler(api, config) {
794
696
  return async (connection, request) => {
@@ -799,12 +701,6 @@ var init_sonamu = __esmMin((() => {
799
701
  let traceContext = {};
800
702
  try {
801
703
  traceContext = this.websocketRuntime.telemetryController.createConnectionContext({ headers: request.headers });
802
- runGuards({
803
- guards: api.options.guards,
804
- config,
805
- request,
806
- api
807
- });
808
704
  preRegisterPhase = "query";
809
705
  const reqBody = await this.parseWebSocketRequestParams(api, request);
810
706
  preRegisterPhase = "register";
@@ -821,13 +717,19 @@ var init_sonamu = __esmMin((() => {
821
717
  });
822
718
  const scopedWs = this.createScopedWebSocketConnection(rawWs, () => wsContext);
823
719
  wsContext = await this.createWebSocketContext(config, request, scopedWs);
720
+ await this.asyncLocalStorage.run({ context: wsContext }, async () => {
721
+ runGuards({
722
+ guards: api.options.guards,
723
+ config,
724
+ request,
725
+ api
726
+ });
727
+ });
824
728
  this.websocketRuntime.activateConnection(rawWs.id);
825
729
  preRegisterPhase = "handler";
826
730
  const { ApiParamType } = await import("../types/types.js");
827
731
  const args = api.parameters.map((param) => {
828
- if (ApiParamType.isContext(param.type)) {
829
- return wsContext;
830
- }
732
+ if (ApiParamType.isContext(param.type)) return wsContext;
831
733
  return reqBody[param.name];
832
734
  });
833
735
  await this.asyncLocalStorage.run({ context: wsContext }, async () => {
@@ -835,26 +737,21 @@ var init_sonamu = __esmMin((() => {
835
737
  });
836
738
  } catch (error) {
837
739
  const closeDescriptor = resolveWebSocketCloseDescriptor(error);
838
- if (!rawWs) {
839
- this.websocketRuntime.telemetryController.emit({
840
- name: "ws.connection.rejected",
841
- level: closeDescriptor.logLevel === "warn" ? "warn" : "error",
842
- detail: {
843
- reason: preRegisterPhase,
844
- code: closeDescriptor.code,
845
- path: api.path
846
- },
847
- traceId: traceContext.traceId,
848
- spanId: traceContext.spanId,
849
- parentSpanId: traceContext.parentSpanId,
850
- sampled: traceContext.sampled
851
- });
852
- }
853
- if (rawWs) {
854
- rawWs.close(closeDescriptor.code, closeDescriptor.reason);
855
- } else if (socket.readyState < 2) {
856
- socket.close(closeDescriptor.code, closeDescriptor.reason);
857
- }
740
+ if (!rawWs) this.websocketRuntime.telemetryController.emit({
741
+ name: "ws.connection.rejected",
742
+ level: closeDescriptor.logLevel === "warn" ? "warn" : "error",
743
+ detail: {
744
+ reason: preRegisterPhase,
745
+ code: closeDescriptor.code,
746
+ path: api.path
747
+ },
748
+ traceId: traceContext.traceId,
749
+ spanId: traceContext.spanId,
750
+ parentSpanId: traceContext.parentSpanId,
751
+ sampled: traceContext.sampled
752
+ });
753
+ if (rawWs) rawWs.close(closeDescriptor.code, closeDescriptor.reason);
754
+ else if (socket.readyState < 2) socket.close(closeDescriptor.code, closeDescriptor.reason);
858
755
  if (this.server?.log) {
859
756
  const payload = {
860
757
  err: error,
@@ -862,18 +759,10 @@ var init_sonamu = __esmMin((() => {
862
759
  methodName: api.methodName,
863
760
  path: api.path
864
761
  };
865
- if (closeDescriptor.logLevel === "warn") {
866
- this.server.log.warn(payload, closeDescriptor.reason);
867
- } else {
868
- this.server.log.error(payload, closeDescriptor.reason);
869
- }
870
- } else {
871
- if (closeDescriptor.logLevel === "warn") {
872
- console.warn(closeDescriptor.reason, error);
873
- } else {
874
- console.error(closeDescriptor.reason, error);
875
- }
876
- }
762
+ if (closeDescriptor.logLevel === "warn") this.server.log.warn(payload, closeDescriptor.reason);
763
+ else this.server.log.error(payload, closeDescriptor.reason);
764
+ } else if (closeDescriptor.logLevel === "warn") console.warn(closeDescriptor.reason, error);
765
+ else console.error(closeDescriptor.reason, error);
877
766
  }
878
767
  };
879
768
  }
@@ -881,9 +770,7 @@ var init_sonamu = __esmMin((() => {
881
770
  const telemetryController = this._websocketRuntime?.telemetryController;
882
771
  const runInContext = (callback) => {
883
772
  const context = getContext();
884
- if (!context) {
885
- return callback();
886
- }
773
+ if (!context) return callback();
887
774
  return this.asyncLocalStorage.run({ context }, callback);
888
775
  };
889
776
  return {
@@ -1019,28 +906,18 @@ var init_sonamu = __esmMin((() => {
1019
906
  const patternParts = pattern.split("/").filter(Boolean);
1020
907
  const urlParts = this.getPathnameFromUrl(url).split("/").filter(Boolean);
1021
908
  const params = {};
1022
- for (let i = 0; i < patternParts.length; i++) {
1023
- if (patternParts[i].startsWith(":")) {
1024
- params[patternParts[i].slice(1)] = urlParts[i];
1025
- }
1026
- }
909
+ for (let i = 0; i < patternParts.length; i++) if (patternParts[i].startsWith(":")) params[patternParts[i].slice(1)] = urlParts[i];
1027
910
  return params;
1028
911
  }
1029
912
  isPathPatternMatch(pattern, url) {
1030
913
  const patternParts = pattern.split("/").filter(Boolean);
1031
914
  const urlParts = this.getPathnameFromUrl(url).split("/").filter(Boolean);
1032
- if (patternParts.length !== urlParts.length) {
1033
- return false;
1034
- }
915
+ if (patternParts.length !== urlParts.length) return false;
1035
916
  for (let i = 0; i < patternParts.length; i++) {
1036
917
  const patternPart = patternParts[i];
1037
918
  const urlPart = urlParts[i];
1038
- if (patternPart.startsWith(":")) {
1039
- continue;
1040
- }
1041
- if (patternPart !== urlPart) {
1042
- return false;
1043
- }
919
+ if (patternPart.startsWith(":")) continue;
920
+ if (patternPart !== urlPart) return false;
1044
921
  }
1045
922
  return true;
1046
923
  }
@@ -1050,15 +927,11 @@ var init_sonamu = __esmMin((() => {
1050
927
  resolvePathWithinBaseDir(baseDir, inputPath) {
1051
928
  try {
1052
929
  const decoded = decodeURIComponent(inputPath).replace(/\\/g, "/");
1053
- if (decoded.includes("\0")) {
1054
- return null;
1055
- }
930
+ if (decoded.includes("\0")) return null;
1056
931
  const relativePath = decoded.replace(/^\/+/, "");
1057
932
  const resolvedPath = path.resolve(baseDir, relativePath);
1058
933
  const relativeFromBase = path.relative(baseDir, resolvedPath);
1059
- if (relativeFromBase.startsWith("..") || path.isAbsolute(relativeFromBase)) {
1060
- return null;
1061
- }
934
+ if (relativeFromBase.startsWith("..") || path.isAbsolute(relativeFromBase)) return null;
1062
935
  return resolvedPath;
1063
936
  } catch {
1064
937
  return null;
@@ -1069,9 +942,7 @@ var init_sonamu = __esmMin((() => {
1069
942
  * 우선순위: 개별 지정 > cacheControlHandler
1070
943
  */
1071
944
  getApiCacheControl(api, request, config) {
1072
- if (api.options.cacheControl) {
1073
- return api.options.cacheControl;
1074
- }
945
+ if (api.options.cacheControl) return api.options.cacheControl;
1075
946
  if (config.cacheControlHandler) {
1076
947
  const cacheReq = {
1077
948
  type: "api",
@@ -1095,9 +966,7 @@ var init_sonamu = __esmMin((() => {
1095
966
  const { ApiParamType } = await import("../types/types.js");
1096
967
  let paramsIndex = 0;
1097
968
  const args = api.parameters.map((param) => {
1098
- if (ApiParamType.isContext(param.type)) {
1099
- return context;
1100
- }
969
+ if (ApiParamType.isContext(param.type)) return context;
1101
970
  return params[paramsIndex++];
1102
971
  });
1103
972
  return this.invokeModelMethod(api, args, reply);
@@ -1115,18 +984,17 @@ var init_sonamu = __esmMin((() => {
1115
984
  const locale = this.detectLocale(request.headers["accept-language"], this.config.i18n.supportedLocales) ?? this.config.i18n.defaultLocale;
1116
985
  const headers = convertFastifyHeadersToStandard(request.headers);
1117
986
  const session = await this._auth?.api.getSession({ headers }) ?? null;
1118
- const context = await Promise.resolve(config.contextProvider({
987
+ return await Promise.resolve(config.contextProvider({
1119
988
  transport: "http",
1120
989
  request,
1121
990
  reply,
1122
991
  headers: request.headers,
1123
992
  createSSE,
1124
- naiteStore: new Map(),
993
+ naiteStore: /* @__PURE__ */ new Map(),
1125
994
  locale,
1126
995
  user: session?.user ?? null,
1127
996
  session: session?.session ?? null
1128
997
  }, request, reply));
1129
- return context;
1130
998
  }
1131
999
  async createWebSocketContext(config, request, ws) {
1132
1000
  const locale = this.detectLocale(request.headers["accept-language"], this.config.i18n.supportedLocales) ?? this.config.i18n.defaultLocale;
@@ -1137,19 +1005,17 @@ var init_sonamu = __esmMin((() => {
1137
1005
  request,
1138
1006
  headers: request.headers,
1139
1007
  ws,
1140
- naiteStore: new Map(),
1008
+ naiteStore: /* @__PURE__ */ new Map(),
1141
1009
  locale,
1142
1010
  user: session?.user ?? null,
1143
1011
  session: session?.session ?? null
1144
1012
  };
1145
- if (config.websocketContextProvider) {
1146
- return { ...await Promise.resolve(config.websocketContextProvider(defaultContext, request)) };
1147
- }
1013
+ if (config.websocketContextProvider) return { ...await Promise.resolve(config.websocketContextProvider(defaultContext, request)) };
1148
1014
  const replyStub = createWebSocketReplyStub();
1149
1015
  const createSSE = (_events) => {
1150
1016
  throw new Error("createSSE is not available in websocket context. Define websocketContextProvider if your context setup depends on SSE helpers.");
1151
1017
  };
1152
- const httpLikeContext = await Promise.resolve(config.contextProvider({
1018
+ const { transport: _transport, reply: _reply, createSSE: _createSSE, bufferedFiles: _bufferedFiles, uploadedFiles: _uploadedFiles, ...rest } = await Promise.resolve(config.contextProvider({
1153
1019
  transport: "http",
1154
1020
  request,
1155
1021
  reply: replyStub,
@@ -1160,7 +1026,6 @@ var init_sonamu = __esmMin((() => {
1160
1026
  user: defaultContext.user,
1161
1027
  session: defaultContext.session
1162
1028
  }, request, replyStub));
1163
- const { transport: _transport, reply: _reply, createSSE: _createSSE, bufferedFiles: _bufferedFiles, uploadedFiles: _uploadedFiles, ...rest } = httpLikeContext;
1164
1029
  return {
1165
1030
  ...rest,
1166
1031
  transport: "ws",
@@ -1174,12 +1039,11 @@ var init_sonamu = __esmMin((() => {
1174
1039
  * @example "ko-KR,ko;q=0.9,en;q=0.8" → "ko"
1175
1040
  */
1176
1041
  detectLocale(acceptLanguage, supported) {
1177
- if (!acceptLanguage) return undefined;
1178
- const langs = acceptLanguage.split(",").map((lang) => {
1042
+ if (!acceptLanguage) return void 0;
1043
+ return acceptLanguage.split(",").map((lang) => {
1179
1044
  const [code] = lang.split(";");
1180
1045
  return code.trim().split("-")[0];
1181
- });
1182
- return langs.find((lang) => supported.includes(lang));
1046
+ }).find((lang) => supported.includes(lang));
1183
1047
  }
1184
1048
  async startWatcher() {
1185
1049
  const { setupWatcher } = await import("../syncer/watcher.js");
@@ -1202,7 +1066,7 @@ var init_sonamu = __esmMin((() => {
1202
1066
  console.log(chalk.black.bgGreen(centerText(msg)));
1203
1067
  }
1204
1068
  async runScript(fn) {
1205
- await this.init(true, false, undefined, false);
1069
+ await this.init(true, false, void 0, false);
1206
1070
  try {
1207
1071
  await fn();
1208
1072
  } finally {
@@ -1210,9 +1074,7 @@ var init_sonamu = __esmMin((() => {
1210
1074
  }
1211
1075
  }
1212
1076
  async registerPlugins(server, plugins) {
1213
- if (!plugins) {
1214
- return;
1215
- }
1077
+ if (!plugins) return;
1216
1078
  if (plugins.compress) {
1217
1079
  const compressPlugin = (await import("@fastify/compress")).default;
1218
1080
  const defaultOptions = {
@@ -1223,14 +1085,11 @@ var init_sonamu = __esmMin((() => {
1223
1085
  "deflate"
1224
1086
  ]
1225
1087
  };
1226
- if (plugins.compress === true) {
1227
- server.register(compressPlugin, defaultOptions);
1228
- } else {
1229
- server.register(compressPlugin, {
1230
- ...defaultOptions,
1231
- ...plugins.compress
1232
- });
1233
- }
1088
+ if (plugins.compress === true) server.register(compressPlugin, defaultOptions);
1089
+ else server.register(compressPlugin, {
1090
+ ...defaultOptions,
1091
+ ...plugins.compress
1092
+ });
1234
1093
  }
1235
1094
  const pluginsModules = {
1236
1095
  cors: "@fastify/cors",
@@ -1243,56 +1102,34 @@ var init_sonamu = __esmMin((() => {
1243
1102
  const registerPlugin = async (key, pluginName) => {
1244
1103
  const option = plugins[key];
1245
1104
  if (!option) return;
1246
- if (option === true) {
1247
- server.register((await import(pluginName)).default);
1248
- } else {
1249
- server.register((await import(pluginName)).default, option);
1250
- }
1105
+ if (option === true) server.register((await import(pluginName)).default);
1106
+ else server.register((await import(pluginName)).default, option);
1251
1107
  };
1252
- for (const [key, pluginName] of Object.entries(pluginsModules)) {
1253
- await registerPlugin(key, pluginName);
1254
- }
1255
- if (plugins.ws) {
1256
- await this.ensureWebSocketPlugin(server);
1257
- }
1258
- if (plugins.custom) {
1259
- plugins.custom(server);
1260
- }
1108
+ for (const [key, pluginName] of Object.entries(pluginsModules)) await registerPlugin(key, pluginName);
1109
+ if (plugins.ws) await this.ensureWebSocketPlugin(server);
1110
+ if (plugins.custom) plugins.custom(server);
1261
1111
  }
1262
1112
  async ensureWebSocketPlugin(server) {
1263
- if (this.websocketPluginServers.has(server)) {
1264
- return;
1265
- }
1113
+ if (this.websocketPluginServers.has(server)) return;
1266
1114
  const pluginOption = this.config.server.plugins?.ws;
1267
- if (!pluginOption) {
1268
- return;
1269
- }
1115
+ if (!pluginOption) return;
1270
1116
  const websocketPlugin = (await import("@fastify/websocket")).default;
1271
1117
  const resolvedPluginOptions = resolveWebSocketPluginOptions({ rawPluginOption: pluginOption });
1272
- if (resolvedPluginOptions) {
1273
- await server.register(websocketPlugin, resolvedPluginOptions);
1274
- } else {
1275
- await server.register(websocketPlugin);
1276
- }
1118
+ if (resolvedPluginOptions) await server.register(websocketPlugin, resolvedPluginOptions);
1119
+ else await server.register(websocketPlugin);
1277
1120
  this.websocketPluginServers.add(server);
1278
1121
  this.warnOnPotentialWebSocketTimeoutConflicts(server);
1279
1122
  }
1280
1123
  warnOnPotentialWebSocketTimeoutConflicts(server) {
1281
1124
  const heartbeats = this.syncer.apis.map((api) => api.websocketOptions?.heartbeat ?? 3e4).filter((heartbeat) => heartbeat > 0);
1282
- if (heartbeats.length === 0) {
1283
- return;
1284
- }
1125
+ if (heartbeats.length === 0) return;
1285
1126
  const keepAliveTimeout = this.config.server.fastify?.keepAliveTimeout;
1286
- if (!keepAliveTimeout || keepAliveTimeout <= 0) {
1287
- return;
1288
- }
1127
+ if (!keepAliveTimeout || keepAliveTimeout <= 0) return;
1289
1128
  const largestHeartbeat = Math.max(...heartbeats);
1290
- if (largestHeartbeat >= keepAliveTimeout) {
1291
- server.log.warn({
1292
- keepAliveTimeout,
1293
- largestHeartbeat
1294
- }, "WebSocket heartbeat is greater than or equal to keepAliveTimeout; align infrastructure idle timeouts to avoid unexpected disconnects.");
1295
- }
1129
+ if (largestHeartbeat >= keepAliveTimeout) server.log.warn({
1130
+ keepAliveTimeout,
1131
+ largestHeartbeat
1132
+ }, "WebSocket heartbeat is greater than or equal to keepAliveTimeout; align infrastructure idle timeouts to avoid unexpected disconnects.");
1296
1133
  }
1297
1134
  /**
1298
1135
  * better-auth 라우트를 등록합니다.
@@ -1305,23 +1142,7 @@ var init_sonamu = __esmMin((() => {
1305
1142
  method: ["GET", "POST"],
1306
1143
  url: `${basePath}/*`,
1307
1144
  handler: async (request, reply) => {
1308
- const url = new URL(request.url, `http://${request.headers.host}`);
1309
- const headers = convertFastifyHeadersToStandard(request.headers);
1310
- const IP_HEADERS = [
1311
- "cf-connecting-ip",
1312
- "x-forwarded-for",
1313
- "x-real-ip",
1314
- "x-vercel-forwarded-for"
1315
- ];
1316
- if (request.ip && !IP_HEADERS.some((h) => headers.has(h))) {
1317
- headers.set("x-real-ip", request.ip);
1318
- }
1319
- const req = new Request(url.toString(), {
1320
- method: request.method,
1321
- headers,
1322
- ...request.body ? { body: JSON.stringify(request.body) } : {}
1323
- });
1324
- const response = await this.auth.handler(req);
1145
+ const response = await this.auth.handler(createBetterAuthRequest(request, options.advanced?.ipAddress?.ipAddressHeaders));
1325
1146
  reply.status(response.status);
1326
1147
  response.headers.forEach((value, key) => {
1327
1148
  reply.header(key, value);
@@ -1331,11 +1152,10 @@ var init_sonamu = __esmMin((() => {
1331
1152
  });
1332
1153
  }
1333
1154
  async printStartupSummary() {
1334
- const chalk$1 = (await import("chalk")).default;
1335
- const env = process.env.NODE_ENV ?? "development";
1336
- const activePreset = env === "production" ? "production_master" : "development_master";
1337
- const dim = (msg) => console.log(chalk$1.dim(`✓ ${msg}`));
1338
- const green = (msg) => console.log(chalk$1.green(`✓ ${msg}`));
1155
+ const chalk = (await import("chalk")).default;
1156
+ const activePreset = getSonamuEnvironment();
1157
+ const dim = (msg) => console.log(chalk.dim(`✓ ${msg}`));
1158
+ const green = (msg) => console.log(chalk.green(`✓ ${msg}`));
1339
1159
  dim(`Config loaded${formatTime(this._configElapsed)}`);
1340
1160
  green("DB");
1341
1161
  const { isLocal } = await import("../utils/controller.js");
@@ -1344,22 +1164,14 @@ var init_sonamu = __esmMin((() => {
1344
1164
  for (const name of presetNames) {
1345
1165
  const conn = this.dbConfig[name].connection;
1346
1166
  const host = conn?.host ?? "localhost";
1347
- const addr = `@ ${host}:${conn?.port ?? 5432}/${conn?.database ?? this.config.database.name}`;
1167
+ const addr = `@ ${host}:${conn?.port ?? 5432}/${conn?.database ?? "(unknown)"}`;
1348
1168
  const padded = name.padEnd(maxLen);
1349
- const remoteTag = isLocal() && !isLocalHost(host) ? chalk$1.yellow(` \u26a0 remote`) : "";
1350
- if (name === activePreset) {
1351
- console.log(chalk$1.green(` \u25b8 ${padded} ${addr}`) + remoteTag);
1352
- } else {
1353
- console.log(chalk$1.dim(` ${padded} ${addr}`) + remoteTag);
1354
- }
1355
- }
1356
- if (this.config.server.auth) {
1357
- const basePath = this.config.server.auth.basePath ?? "/api/auth";
1358
- dim(`Auth: better-auth at ${basePath}/*`);
1359
- }
1360
- if (this.config.api.timezone) {
1361
- dim(`Timezone: ${this.config.api.timezone}`);
1169
+ const remoteTag = isLocal() && !isLocalHost(host) ? chalk.yellow(` \u26a0 remote`) : "";
1170
+ if (name === activePreset) console.log(chalk.green(` \u25b8 ${padded} ${addr}`) + remoteTag);
1171
+ else console.log(chalk.dim(` ${padded} ${addr}`) + remoteTag);
1362
1172
  }
1173
+ if (this.config.server.auth) dim(`Auth: better-auth at ${this.config.server.auth.basePath ?? "/api/auth"}/*`);
1174
+ if (this.config.api.timezone) dim(`Timezone: ${this.config.api.timezone}`);
1363
1175
  green(`Sonamu ready${formatTime(this._initElapsed)}`);
1364
1176
  }
1365
1177
  async initializeCache(config, forTesting) {
@@ -1381,21 +1193,17 @@ var init_sonamu = __esmMin((() => {
1381
1193
  async initializeWorkflows(options) {
1382
1194
  const { WorkflowManager } = await import("../tasks/workflow-manager.js");
1383
1195
  this._workflows = new WorkflowManager(DB.getDBConfig("w"));
1384
- if (!options) {
1385
- return;
1386
- }
1196
+ if (!options) return;
1387
1197
  const enableWorker = options.enableWorker ?? isDaemonServer();
1388
1198
  const defaultWorkerOptions = {
1389
1199
  concurrency: os.cpus().length - 1,
1390
1200
  usePubSub: true,
1391
1201
  listenDelay: 500
1392
1202
  };
1393
- if (enableWorker) {
1394
- this.workflows.setupWorker({
1395
- ...defaultWorkerOptions,
1396
- ...options.workerOptions
1397
- });
1398
- }
1203
+ if (enableWorker) this.workflows.setupWorker({
1204
+ ...defaultWorkerOptions,
1205
+ ...options.workerOptions
1206
+ });
1399
1207
  }
1400
1208
  async boot(server, options) {
1401
1209
  const port = options.listen?.port ?? 3e3;
@@ -1416,9 +1224,7 @@ var init_sonamu = __esmMin((() => {
1416
1224
  };
1417
1225
  process.on("SIGINT", shutdown);
1418
1226
  process.on("SIGTERM", shutdown);
1419
- if (options.lifecycle?.onError) {
1420
- server.setErrorHandler(options.lifecycle?.onError);
1421
- }
1227
+ if (options.lifecycle?.onError) server.setErrorHandler(options.lifecycle?.onError);
1422
1228
  server.listen({
1423
1229
  port,
1424
1230
  host
@@ -1426,17 +1232,15 @@ var init_sonamu = __esmMin((() => {
1426
1232
  await this.workflows.startWorker();
1427
1233
  await options.lifecycle?.onStart?.(server);
1428
1234
  }).catch(async (err) => {
1429
- const chalk$1 = (await import("chalk")).default;
1430
- console.error(chalk$1.red("Failed to start server:", err));
1235
+ const chalk = (await import("chalk")).default;
1236
+ console.error(chalk.red("Failed to start server:", err));
1431
1237
  await shutdown();
1432
1238
  });
1433
1239
  }
1434
1240
  async destroy() {
1435
1241
  const { BaseModel } = await import("../database/base-model.js");
1436
1242
  await BaseModel.destroy();
1437
- if (this._websocketRuntime) {
1438
- await this._websocketRuntime.shutdown();
1439
- }
1243
+ if (this._websocketRuntime) await this._websocketRuntime.shutdown();
1440
1244
  this._websocketRuntime = null;
1441
1245
  await Promise.allSettled([
1442
1246
  this._workflows?.destroy() ?? Promise.resolve(),
@@ -1448,15 +1252,15 @@ var init_sonamu = __esmMin((() => {
1448
1252
  }
1449
1253
  };
1450
1254
  Sonamu = new SonamuClass();
1451
- LOCAL_HOSTS = new Set([
1255
+ LOCAL_HOSTS = /* @__PURE__ */ new Set([
1452
1256
  "localhost",
1453
1257
  "127.0.0.1",
1454
1258
  "0.0.0.0",
1455
1259
  "::1"
1456
1260
  ]);
1457
1261
  }));
1458
-
1459
1262
  //#endregion
1460
1263
  init_sonamu();
1461
1264
  export { Sonamu, createWebSocketReplyStub, init_sonamu, resolveWebSocketCloseDescriptor, resolveWebSocketPluginOptions };
1462
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29uYW11LmpzIiwibmFtZXMiOlsiREIiLCJhdXRoT3B0aW9uczogQmV0dGVyQXV0aE9wdGlvbnMiLCJnbG9iYWxDb21wcmVzc09wdGlvbnM6IENvbXByZXNzT3B0aW9ucyB8IHVuZGVmaW5lZCIsImZzIiwiY2hhbGsiLCJjYWNoZVJlcTogQ2FjaGVDb250cm9sUmVxdWVzdCIsImZpbGVQYXRoIiwiY3NyQ2FjaGVSZXE6IENhY2hlQ29udHJvbFJlcXVlc3QiLCJtaW1lTG9va3VwIiwiY29udGV4dDogQ29udGV4dCIsInJlcUJvZHk6IHtcbiAgICAgICAgICBba2V5OiBzdHJpbmddOiB1bmtub3duO1xuICAgICAgICB9IiwiZmlsZXM6IHtcbiAgICAgICAgICBidWZmZXJlZEZpbGVzOiBCdWZmZXJlZEZpbGVbXTtcbiAgICAgICAgICB1cGxvYWRlZEZpbGVzOiBVcGxvYWRlZEZpbGVbXTtcbiAgICAgICAgfSIsImZpZWxkczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiIsImtleUdlbmVyYXRvcjogS2V5R2VuZXJhdG9yIiwid3NDb250ZXh0OiBXZWJTb2NrZXRDb250ZXh0IHwgbnVsbCIsInJhd1dzOiBSZXR1cm5UeXBlPFdlYlNvY2tldFJ1bnRpbWVbXCJyZWdpc3RlckNvbm5lY3Rpb25cIl0+IHwgbnVsbCIsInByZVJlZ2lzdGVyUGhhc2U6IFwiZ3VhcmRcIiB8IFwicXVlcnlcIiB8IFwicmVnaXN0ZXJcIiB8IFwiaGFuZGxlclwiIiwidHJhY2VDb250ZXh0OiBXZWJTb2NrZXRUZWxlbWV0cnlDb25uZWN0aW9uQ29udGV4dCIsInBhcmFtczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiIsImxvZ3RhcGVEaXNwb3NlIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwaS9zb25hbXUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQXN5bmNMb2NhbFN0b3JhZ2UgfSBmcm9tIFwiYXN5bmNfaG9va3NcIjtcbmltcG9ydCBmcyBmcm9tIFwiZnMvcHJvbWlzZXNcIjtcbmltcG9ydCB7IHR5cGUgSW5jb21pbmdNZXNzYWdlLCB0eXBlIFNlcnZlciwgdHlwZSBTZXJ2ZXJSZXNwb25zZSB9IGZyb20gXCJodHRwXCI7XG5pbXBvcnQgb3MgZnJvbSBcIm9zXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5pbXBvcnQgdHlwZSB7fSBmcm9tIFwiQGZhc3RpZnkvd2Vic29ja2V0XCI7XG5pbXBvcnQgeyBkaXNwb3NlIGFzIGxvZ3RhcGVEaXNwb3NlIH0gZnJvbSBcIkBsb2d0YXBlL2xvZ3RhcGVcIjtcbmltcG9ydCB7IHR5cGUgQXV0aCwgdHlwZSBCZXR0ZXJBdXRoT3B0aW9ucyB9IGZyb20gXCJiZXR0ZXItYXV0aFwiO1xuaW1wb3J0IGNoYWxrIGZyb20gXCJjaGFsa1wiO1xuaW1wb3J0IHsgdHlwZSBGU1dhdGNoZXIgfSBmcm9tIFwiY2hva2lkYXJcIjtcbmltcG9ydCB7IHR5cGUgRmFzdGlmeUluc3RhbmNlLCB0eXBlIEZhc3RpZnlSZXBseSwgdHlwZSBGYXN0aWZ5UmVxdWVzdCB9IGZyb20gXCJmYXN0aWZ5XCI7XG5pbXBvcnQgbWltZSwgeyBsb29rdXAgYXMgbWltZUxvb2t1cCB9IGZyb20gXCJtaW1lLXR5cGVzXCI7XG5pbXBvcnQgeyB0eXBlIFdlYlNvY2tldCB9IGZyb20gXCJ3c1wiO1xuaW1wb3J0IHsgdHlwZSBab2RPYmplY3QgfSBmcm9tIFwiem9kXCI7XG5cbmltcG9ydCB7IEJBU0VfRklFTERfTUFQUElOR1MgfSBmcm9tIFwiLi4vYXV0aC9iZXR0ZXItYXV0aC1lbnRpdGllc1wiO1xuaW1wb3J0IHsgYXBwbHlDYWNoZUhlYWRlcnMsIENhY2hlUHJlc2V0cyB9IGZyb20gXCIuLi9jYWNoZS1jb250cm9sL2NhY2hlLWNvbnRyb2xcIjtcbmltcG9ydCB7IHR5cGUgQ2FjaGVDb250cm9sQ29uZmlnLCB0eXBlIENhY2hlQ29udHJvbFJlcXVlc3QgfSBmcm9tIFwiLi4vY2FjaGUtY29udHJvbC90eXBlc1wiO1xuaW1wb3J0IHsgdHlwZSBDYWNoZUNvbmZpZywgdHlwZSBDYWNoZU1hbmFnZXIgfSBmcm9tIFwiLi4vY2FjaGUvdHlwZXNcIjtcbmltcG9ydCB7IHRvRmFzdGlmeUNvbXByZXNzT3B0aW9uIH0gZnJvbSBcIi4uL2NvbXByZXNzL2NvbXByZXNzXCI7XG5pbXBvcnQgeyB0eXBlIENvbXByZXNzT3B0aW9ucyB9IGZyb20gXCIuLi9jb21wcmVzcy90eXBlc1wiO1xuaW1wb3J0IHsgREIgfSBmcm9tIFwiLi4vZGF0YWJhc2UvZGJcIjtcbmltcG9ydCB7IHR5cGUgU29uYW11REJDb25maWcgfSBmcm9tIFwiLi4vZGF0YWJhc2UvZGJcIjtcbmltcG9ydCB7IFNELCBzZXRTRENvbmZpZyB9IGZyb20gXCIuLi9kaWN0L3NkXCI7XG5pbXBvcnQgeyB0eXBlIExvY2FsaXplZFN0cmluZyB9IGZyb20gXCIuLi9kaWN0L3R5cGVzXCI7XG5pbXBvcnQgeyBOb3RGb3VuZEV4Y2VwdGlvbiB9IGZyb20gXCIuLi9leGNlcHRpb25zL3NvLWV4Y2VwdGlvbnNcIjtcbmltcG9ydCB7IEJ1ZmZlcmVkRmlsZSB9IGZyb20gXCIuLi9zdG9yYWdlL2J1ZmZlcmVkLWZpbGVcIjtcbmltcG9ydCB7IHR5cGUgU3RvcmFnZU1hbmFnZXIgfSBmcm9tIFwiLi4vc3RvcmFnZS9zdG9yYWdlLW1hbmFnZXJcIjtcbmltcG9ydCB7IHR5cGUgS2V5R2VuZXJhdG9yIH0gZnJvbSBcIi4uL3N0b3JhZ2UvdHlwZXNcIjtcbmltcG9ydCB7IFVwbG9hZGVkRmlsZSB9IGZyb20gXCIuLi9zdG9yYWdlL3VwbG9hZGVkLWZpbGVcIjtcbmltcG9ydCB7IGNyZWF0ZU1vY2tTU0VGYWN0b3J5IH0gZnJvbSBcIi4uL3N0cmVhbS9zc2VcIjtcbmltcG9ydCB7IFdlYlNvY2tldFJ1bnRpbWUsIHR5cGUgV2ViU29ja2V0Q29ubmVjdGlvbiwgdHlwZSBXZWJTb2NrZXRFdmVudE1hcCB9IGZyb20gXCIuLi9zdHJlYW0vd3NcIjtcbmltcG9ydCB7XG4gIHR5cGUgVGVsZW1ldHJ5Q29udGV4dFByb3ZpZGVyLFxuICB0eXBlIFdlYlNvY2tldFRlbGVtZXRyeUNvbm5lY3Rpb25Db250ZXh0LFxufSBmcm9tIFwiLi4vc3RyZWFtL3dzLXRlbGVtZXRyeVwiO1xuaW1wb3J0IHsgdHlwZSBTeW5jZXIgfSBmcm9tIFwiLi4vc3luY2VyL3N5bmNlclwiO1xuaW1wb3J0IHsgdHlwZSBXb3JrZmxvd01hbmFnZXIgfSBmcm9tIFwiLi4vdGFza3Mvd29ya2Zsb3ctbWFuYWdlclwiO1xuaW1wb3J0IHsgdHlwZSBEZXZWaXRlc3RNYW5hZ2VyIH0gZnJvbSBcIi4uL3Rlc3RpbmcvZGV2LXZpdGVzdC1tYW5hZ2VyXCI7XG5pbXBvcnQgeyB0eXBlIFNvbmFtdUZhc3RpZnlDb25maWcgfSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IGNlbnRlclRleHQgfSBmcm9tIFwiLi4vdXRpbHMvY29uc29sZS11dGlsXCI7XG5pbXBvcnQgeyBpc0RhZW1vblNlcnZlciB9IGZyb20gXCIuLi91dGlscy9jb250cm9sbGVyXCI7XG5pbXBvcnQgeyBleGlzdHMsIGZpbGVFeGlzdHMgfSBmcm9tIFwiLi4vdXRpbHMvZnMtdXRpbHNcIjtcbmltcG9ydCB7IHR5cGUgQWJzb2x1dGVQYXRoIH0gZnJvbSBcIi4uL3V0aWxzL3BhdGgtdXRpbHNcIjtcbmltcG9ydCB7IGNvbnZlcnRGYXN0aWZ5SGVhZGVyc1RvU3RhbmRhcmQsIG1lcmdlIH0gZnJvbSBcIi4uL3V0aWxzL3V0aWxzXCI7XG5pbXBvcnQgeyB0eXBlIFNvbmFtdUNvbmZpZywgdHlwZSBTb25hbXVTZXJ2ZXJPcHRpb25zLCB0eXBlIFNvbmFtdVRhc2tPcHRpb25zIH0gZnJvbSBcIi4vY29uZmlnXCI7XG5pbXBvcnQgeyB0eXBlIENvbnRleHQsIHR5cGUgUnVudGltZUNvbnRleHQsIHR5cGUgV2ViU29ja2V0Q29udGV4dCB9IGZyb20gXCIuL2NvbnRleHRcIjtcbmltcG9ydCB7IHR5cGUgRXh0ZW5kZWRBcGkgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBnZXRTZWNyZXRzIH0gZnJvbSBcIi4vc2VjcmV0XCI7XG5pbXBvcnQgeyB0eXBlIFNvbmFtdVNlY3JldHMgfSBmcm9tIFwiLi9zZWNyZXRcIjtcbmltcG9ydCB7XG4gIGNyZWF0ZVdlYlNvY2tldFJlcGx5U3R1YixcbiAgcmVzb2x2ZVdlYlNvY2tldENsb3NlRGVzY3JpcHRvcixcbiAgcmVzb2x2ZVdlYlNvY2tldFBsdWdpbk9wdGlvbnMsXG4gIHJlc29sdmVJbnRlZ3JhdGVkVml0ZUhtck9wdGlvbnMsXG59IGZyb20gXCIuL3dlYnNvY2tldC1oZWxwZXJzXCI7XG5cbmV4cG9ydCB7XG4gIGNyZWF0ZVdlYlNvY2tldFJlcGx5U3R1YixcbiAgcmVzb2x2ZVdlYlNvY2tldENsb3NlRGVzY3JpcHRvcixcbiAgcmVzb2x2ZVdlYlNvY2tldFBsdWdpbk9wdGlvbnMsXG59IGZyb20gXCIuL3dlYnNvY2tldC1oZWxwZXJzXCI7XG5cbmNsYXNzIFNvbmFtdUNsYXNzIHtcbiAgcHVibGljIGlzSW5pdGlhbGl6ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHVibGljIGZvclRlc3Rpbmc6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHVibGljIGFzeW5jTG9jYWxTdG9yYWdlOiBBc3luY0xvY2FsU3RvcmFnZTx7XG4gICAgY29udGV4dDogUnVudGltZUNvbnRleHQ7XG4gIH0+ID0gbmV3IEFzeW5jTG9jYWxTdG9yYWdlKCk7XG5cbiAgcHVibGljIGdldENvbnRleHQ8VCBleHRlbmRzIFJ1bnRpbWVDb250ZXh0ID0gQ29udGV4dD4oKTogVCB7XG4gICAgY29uc3Qgc3RvcmUgPSB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLmdldFN0b3JlKCk7XG4gICAgaWYgKHN0b3JlPy5jb250ZXh0KSB7XG4gICAgICByZXR1cm4gc3RvcmUuY29udGV4dCBhcyBUO1xuICAgIH1cblxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gXCJ0ZXN0XCIpIHtcbiAgICAgIC8vIO2FjOyKpO2MhSDtmZjqsr3sl5DshJwg7Luo7YWN7Iqk7Yq46rCAIOyjvOyeheuQmOyngCDslYrsnYAg6rK97JqwIOu5iCDsu6jthY3siqTtirgg66as7YS0XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0cmFuc3BvcnQ6IFwiaHR0cFwiLFxuICAgICAgICByZXF1ZXN0OiBudWxsLFxuICAgICAgICByZXBseTogbnVsbCxcbiAgICAgICAgaGVhZGVyczoge30sXG4gICAgICAgIGNyZWF0ZVNTRTogKHNjaGVtYTogWm9kT2JqZWN0KSA9PiBjcmVhdGVNb2NrU1NFRmFjdG9yeShzY2hlbWEpLFxuICAgICAgICBsb2NhbGU6IFwiXCIsXG4gICAgICAgIHVzZXI6IG51bGwsXG4gICAgICAgIHNlc3Npb246IG51bGwsXG4gICAgICAgIG5haXRlU3RvcmU6IG5ldyBNYXA8c3RyaW5nLCBhbnk+KCksXG4gICAgICB9IGFzIHVua25vd24gYXMgVDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGNhbm5vdCBmaW5kIGNvbnRleHRcIik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfYXBpUm9vdFBhdGg6IEFic29sdXRlUGF0aCB8IG51bGwgPSBudWxsO1xuICBzZXQgYXBpUm9vdFBhdGgoYXBpUm9vdFBhdGg6IEFic29sdXRlUGF0aCkge1xuICAgIHRoaXMuX2FwaVJvb3RQYXRoID0gYXBpUm9vdFBhdGg7XG4gIH1cbiAgZ2V0IGFwaVJvb3RQYXRoKCk6IEFic29sdXRlUGF0aCB7XG4gICAgaWYgKHRoaXMuX2FwaVJvb3RQYXRoID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTb25hbXUgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fYXBpUm9vdFBhdGg7XG4gIH1cbiAgZ2V0IGFwcFJvb3RQYXRoKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuYXBpUm9vdFBhdGguc3BsaXQocGF0aC5zZXApLnNsaWNlKDAsIC0xKS5qb2luKHBhdGguc2VwKTtcbiAgfVxuXG4gIHByaXZhdGUgX2RiQ29uZmlnOiBTb25hbXVEQkNvbmZpZyB8IG51bGwgPSBudWxsO1xuICBzZXQgZGJDb25maWcoZGJDb25maWc6IFNvbmFtdURCQ29uZmlnKSB7XG4gICAgdGhpcy5fZGJDb25maWcgPSBkYkNvbmZpZztcbiAgfVxuICBnZXQgZGJDb25maWcoKTogU29uYW11REJDb25maWcge1xuICAgIGlmICh0aGlzLl9kYkNvbmZpZyA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2RiQ29uZmlnO1xuICB9XG5cbiAgcHJpdmF0ZSBfc3luY2VyOiBTeW5jZXIgfCBudWxsID0gbnVsbDtcbiAgc2V0IHN5bmNlcihzeW5jZXI6IFN5bmNlcikge1xuICAgIHRoaXMuX3N5bmNlciA9IHN5bmNlcjtcbiAgfVxuICBnZXQgc3luY2VyKCk6IFN5bmNlciB7XG4gICAgaWYgKHRoaXMuX3N5bmNlciA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3N5bmNlcjtcbiAgfVxuXG4gIHByaXZhdGUgX2NvbmZpZzogU29uYW11Q29uZmlnIHwgbnVsbCA9IG51bGw7XG4gIHNldCBjb25maWcoY29uZmlnOiBTb25hbXVDb25maWcpIHtcbiAgICB0aGlzLl9jb25maWcgPSBjb25maWc7XG4gIH1cbiAgZ2V0IGNvbmZpZygpOiBTb25hbXVDb25maWcge1xuICAgIGlmICh0aGlzLl9jb25maWcgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNvbmFtdSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRcIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9jb25maWc7XG4gIH1cblxuICBwdWJsaWMgcmVhZG9ubHkgc2VjcmV0czogU29uYW11U2VjcmV0cyA9IGdldFNlY3JldHMoKTtcblxuICBwcml2YXRlIF9zdG9yYWdlOiBTdG9yYWdlTWFuYWdlciB8IG51bGwgPSBudWxsO1xuICAvKipcbiAgICogU3RvcmFnZU1hbmFnZXIg7J247Iqk7YS07IqkXG4gICAqL1xuICBnZXQgc3RvcmFnZSgpOiBTdG9yYWdlTWFuYWdlciB7XG4gICAgaWYgKCF0aGlzLl9zdG9yYWdlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTdG9yYWdlIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZC4gQ2hlY2sgc3RvcmFnZSBjb25maWcuXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc3RvcmFnZTtcbiAgfVxuXG4gIHByaXZhdGUgX2NhY2hlOiBDYWNoZU1hbmFnZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqXG4gICAqIENhY2hlTWFuYWdlciDsnbjsiqTthLTsiqQgKEJlbnRvQ2FjaGUpXG4gICAqL1xuICBnZXQgY2FjaGUoKTogQ2FjaGVNYW5hZ2VyIHtcbiAgICBpZiAoIXRoaXMuX2NhY2hlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYWNoZSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQuIENoZWNrIGNhY2hlIGNvbmZpZyBpbiBzb25hbXUuY29uZmlnLnRzLlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2NhY2hlO1xuICB9XG5cbiAgcHJpdmF0ZSBfd29ya2Zsb3dzOiBXb3JrZmxvd01hbmFnZXIgfCBudWxsID0gbnVsbDtcbiAgZ2V0IHdvcmtmbG93cygpOiBXb3JrZmxvd01hbmFnZXIge1xuICAgIGlmICh0aGlzLl93b3JrZmxvd3MgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNvbmFtdSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3dvcmtmbG93cztcbiAgfVxuXG4gIHByaXZhdGUgX2F1dGg6IEF1dGg8QmV0dGVyQXV0aE9wdGlvbnM+IHwgbnVsbCA9IG51bGw7XG4gIGdldCBhdXRoKCk6IEF1dGg8QmV0dGVyQXV0aE9wdGlvbnM+IHtcbiAgICBpZiAoIXRoaXMuX2F1dGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkF1dGggaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkLiBDaGVjayBhdXRoIGNvbmZpZyBpbiBzb25hbXUuY29uZmlnLnRzLlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2F1dGg7XG4gIH1cblxuICBwcml2YXRlIF9kZXZWaXRlc3RNYW5hZ2VyOiBEZXZWaXRlc3RNYW5hZ2VyIHwgbnVsbCA9IG51bGw7XG4gIGdldCBkZXZWaXRlc3RNYW5hZ2VyKCk6IERldlZpdGVzdE1hbmFnZXIgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fZGV2Vml0ZXN0TWFuYWdlcjtcbiAgfVxuICBzZXQgZGV2Vml0ZXN0TWFuYWdlcihtYW5hZ2VyOiBEZXZWaXRlc3RNYW5hZ2VyIHwgbnVsbCkge1xuICAgIHRoaXMuX2RldlZpdGVzdE1hbmFnZXIgPSBtYW5hZ2VyO1xuICB9XG5cbiAgLy8gU29uYW116rCAIHJ1bnRpbWXsnYQg7KeB7KCRIOyGjOycoO2VtCByZWdpc3RyeS9jb25uZWN0aW9uIGxpZmVjeWNsZeydhCDslaDtlIzrpqzsvIDsnbTshZgg7IiY66qF7KO86riw7JmAIOuPmeq4sO2ZlO2VqFxuICBwcml2YXRlIF93ZWJzb2NrZXRSdW50aW1lOiBXZWJTb2NrZXRSdW50aW1lIHwgbnVsbCA9IG51bGw7XG4gIC8vIOqwmeydgCBGYXN0aWZ5IOyduOyKpO2EtOyKpOyXkCBAZmFzdGlmeS93ZWJzb2NrZXTsnYQg7KSR67O1IOuTseuhne2VmOuKlCDqsoPsnYQgV2Vha1NldOycvOuhnCDssKjri6jtlahcbiAgcHJpdmF0ZSByZWFkb25seSB3ZWJzb2NrZXRQbHVnaW5TZXJ2ZXJzID0gbmV3IFdlYWtTZXQ8XG4gICAgRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT5cbiAgPigpO1xuICBnZXQgd2Vic29ja2V0UnVudGltZSgpOiBXZWJTb2NrZXRSdW50aW1lIHtcbiAgICBpZiAoIXRoaXMuX3dlYnNvY2tldFJ1bnRpbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIldlYlNvY2tldCBydW50aW1lIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZC5cIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl93ZWJzb2NrZXRSdW50aW1lO1xuICB9XG4gIHNldCB3ZWJzb2NrZXRSdW50aW1lKHJ1bnRpbWU6IFdlYlNvY2tldFJ1bnRpbWUgfCBudWxsKSB7XG4gICAgdGhpcy5fd2Vic29ja2V0UnVudGltZSA9IHJ1bnRpbWU7XG4gIH1cblxuICAvLyBITVIg7LKY66asOiDtjIzsnbwg7Iuc7Iqk7YWcIOqwkOyLnCArIEhNUi9zeW5jIOyCrOydtO2BtCDsi6TtlonsnYAgd2F0Y2hlciDrqqjrk4jroZwg7JyE7J6E7ZWp64uI64ukLlxuICBwdWJsaWMgd2F0Y2hlcjogRlNXYXRjaGVyIHwgbnVsbCA9IG51bGw7XG5cbiAgcHVibGljIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlIHwgbnVsbCA9IG51bGw7XG5cbiAgYXN5bmMgaW5pdEZvclRlc3RpbmcoKSB7XG4gICAgYXdhaXQgdGhpcy5pbml0KHRydWUsIGZhbHNlLCB1bmRlZmluZWQsIHRydWUpO1xuICB9XG5cbiAgYXN5bmMgaW5pdChcbiAgICBkb1NpbGVudDogYm9vbGVhbiA9IGZhbHNlLFxuICAgIGVuYWJsZVN5bmM6IGJvb2xlYW4gPSB0cnVlLFxuICAgIGFwaVJvb3RQYXRoPzogQWJzb2x1dGVQYXRoLFxuICAgIGZvclRlc3Rpbmc6IGJvb2xlYW4gPSBmYWxzZSxcbiAgKSB7XG4gICAgdGhpcy5mb3JUZXN0aW5nID0gZm9yVGVzdGluZztcblxuICAgIGlmICh0aGlzLmlzSW5pdGlhbGl6ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBpbml0U3RhcnQgPSBwZXJmb3JtYW5jZS5ub3coKTtcblxuICAgIC8vIEFQSSDro6jtirgg7Yyo7IqkXG4gICAgY29uc3QgeyBmaW5kQXBpUm9vdFBhdGggfSA9IGF3YWl0IGltcG9ydChcIi4uL3V0aWxzL3V0aWxzXCIpO1xuICAgIHRoaXMuYXBpUm9vdFBhdGggPSBhcGlSb290UGF0aCA/PyBmaW5kQXBpUm9vdFBhdGgoKTtcblxuICAgIC8vIOyEpOygleydhCDroZzrlKntlZjripQg6rKD67aA7YSwIOyLnOyekVxuICAgIGNvbnN0IGNvbmZpZ1N0YXJ0ID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgY29uc3QgeyBsb2FkQ29uZmlnIH0gPSBhd2FpdCBpbXBvcnQoXCIuL2NvbmZpZ1wiKTtcbiAgICB0aGlzLmNvbmZpZyA9IGF3YWl0IGxvYWRDb25maWcodGhpcy5hcGlSb290UGF0aCk7XG4gICAgY29uc3QgY29uZmlnVGltZSA9IHBlcmZvcm1hbmNlLm5vdygpIC0gY29uZmlnU3RhcnQ7XG4gICAgc2V0U0RDb25maWcodGhpcy5jb25maWcuaTE4bik7XG4gICAgLy8gc29uYW11LmNvbmZpZy50cyDquLDrs7jqsJIg7ISk7KCVXG4gICAgdGhpcy5jb25maWcuZGF0YWJhc2UuZGF0YWJhc2UgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS5kYXRhYmFzZSA/PyBcInBnXCI7XG4gICAgdGhpcy5jb25maWcuZGF0YWJhc2UuZGVmYXVsdE9wdGlvbnMuY2xpZW50ID0gdGhpcy5jb25maWcuZGF0YWJhc2UuZGF0YWJhc2UgPz8gXCJwZ1wiO1xuXG4gICAgLy8g66Gc6rmFIOyEpOyglVxuICAgIGNvbnN0IHsgY29uZmlndXJlTG9nVGFwZSB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vbG9nZ2VyL2NvbmZpZ3VyZVwiKTtcbiAgICBpZiAodGhpcy5jb25maWcubG9nZ2luZyAhPT0gZmFsc2UpIHtcbiAgICAgIGF3YWl0IGNvbmZpZ3VyZUxvZ1RhcGUoe1xuICAgICAgICAuLi50aGlzLmNvbmZpZy5sb2dnaW5nLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gREIg66Gc65OcXG4gICAgY29uc3QgeyBEQiB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vZGF0YWJhc2UvZGJcIik7XG4gICAgdGhpcy5kYkNvbmZpZyA9IERCLmdlbmVyYXRlREJDb25maWcodGhpcy5jb25maWcuZGF0YWJhc2UpO1xuICAgIERCLnNldENvbmZpZyh0aGlzLmRiQ29uZmlnKTtcblxuICAgIC8vIEVudGl0eSDroZzrk5xcbiAgICAvLyDthYzsiqTtirjsl5DshJzrj4QgRW50aXR5IOygleuztOuKlCDtlYTsmpTtlanri4jri6QuXG4gICAgLy8gdXBzZXJ06rCAIOygnOuMgOuhnCDsnpHrj5ntlZjroKTrqbQgZW50aXR57J2YIHVuaXF1ZSBpbmRleCDsoJXrs7TqsIAg7ZWE7JqU7ZWY6riwIOuVjOusuOyeheuLiOuLpC5cbiAgICBjb25zdCB7IEVudGl0eU1hbmFnZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL2VudGl0eS9lbnRpdHktbWFuYWdlclwiKTtcbiAgICBhd2FpdCBFbnRpdHlNYW5hZ2VyLmF1dG9sb2FkKGRvU2lsZW50KTtcblxuICAgIC8vIENhY2hlIOy0iOq4sO2ZlFxuICAgIGF3YWl0IHRoaXMuaW5pdGlhbGl6ZUNhY2hlKHRoaXMuY29uZmlnLnNlcnZlci5jYWNoZSwgZm9yVGVzdGluZyk7XG5cbiAgICAvLyBCZXR0ZXJBdXRoIOy0iOq4sO2ZlFxuICAgIGNvbnN0IGF1dGhDb25maWcgPSB0aGlzLmNvbmZpZy5zZXJ2ZXIuYXV0aDtcbiAgICBpZiAoYXV0aENvbmZpZykge1xuICAgICAgLy8g7IKs7Jqp7J6QIOyEpOygleqzvCDquLDrs7jqsJLsnYQgbWVyZ2VcbiAgICAgIGNvbnN0IG1lcmdlZEZpZWxkTWFwcGluZ3MgPSBtZXJnZShCQVNFX0ZJRUxEX01BUFBJTkdTLCBhdXRoQ29uZmlnKTtcblxuICAgICAgLy8gYmV0dGVyLWF1dGgg7J247Iqk7YS07IqkIOyDneyEsVxuICAgICAgY29uc3QgeyBiZXR0ZXJBdXRoIH0gPSBhd2FpdCBpbXBvcnQoXCJiZXR0ZXItYXV0aFwiKTtcbiAgICAgIGNvbnN0IHsgc29uYW11S25leEFkYXB0ZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL2F1dGgva25leC1hZGFwdGVyXCIpO1xuXG4gICAgICBjb25zdCBhdXRoT3B0aW9uczogQmV0dGVyQXV0aE9wdGlvbnMgPSB7XG4gICAgICAgIGRhdGFiYXNlOiBzb25hbXVLbmV4QWRhcHRlcigpLFxuICAgICAgICAuLi5tZXJnZWRGaWVsZE1hcHBpbmdzLFxuICAgICAgfTtcbiAgICAgIHRoaXMuX2F1dGggPSBiZXR0ZXJBdXRoKGF1dGhPcHRpb25zKTtcbiAgICB9XG5cbiAgICAvLyDthYzsiqTtjIXsnbgg6rK97JqwIOyLse2BrCDsl4bsnbQg7KSR64uoXG4gICAgaWYgKGZvclRlc3RpbmcpIHtcbiAgICAgIHRoaXMuaXNJbml0aWFsaXplZCA9IHRydWU7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gVGFzayDrk7HroZ1cbiAgICBhd2FpdCB0aGlzLmluaXRpYWxpemVXb3JrZmxvd3ModGhpcy5jb25maWcudGFza3MpO1xuXG4gICAgLy8gU3luY2VyXG4gICAgY29uc3QgeyBTeW5jZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL3N5bmNlci9zeW5jZXJcIik7XG4gICAgdGhpcy5zeW5jZXIgPSBuZXcgU3luY2VyKCk7XG5cbiAgICAvLyBBdXRvbG9hZDogTW9kZWxzIC8gVHlwZXMgLyBBUElzIC8gV29ya2Zsb3dzIC8gVGVtcGxhdGVzIC8gU1NSIFJvdXRlc1xuICAgIGF3YWl0IHRoaXMuc3luY2VyLmF1dG9sb2FkVHlwZXMoKTtcbiAgICBhd2FpdCB0aGlzLnN5bmNlci5hdXRvbG9hZE1vZGVscygpO1xuICAgIGF3YWl0IHRoaXMuc3luY2VyLmF1dG9sb2FkQXBpcygpO1xuICAgIGF3YWl0IHRoaXMuc3luY2VyLmF1dG9sb2FkV29ya2Zsb3dzKCk7XG4gICAgY29uc3QgeyBUZW1wbGF0ZU1hbmFnZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL3RlbXBsYXRlXCIpO1xuICAgIGF3YWl0IFRlbXBsYXRlTWFuYWdlci5hdXRvbG9hZCgpO1xuICAgIGF3YWl0IHRoaXMuc3luY2VyLmF1dG9sb2FkU3NyUm91dGVzKCk7XG5cbiAgICBjb25zdCB7IGlzTG9jYWwsIGlzVGVzdCwgaXNIb3RSZWxvYWRTZXJ2ZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL3V0aWxzL2NvbnRyb2xsZXJcIik7XG4gICAgaWYgKGlzTG9jYWwoKSAmJiAhaXNUZXN0KCkgJiYgaXNIb3RSZWxvYWRTZXJ2ZXIoKSAmJiBlbmFibGVTeW5jKSB7XG4gICAgICBhd2FpdCB0aGlzLnN5bmNlci5zeW5jKCk7XG4gICAgICBhd2FpdCB0aGlzLnN0YXJ0V2F0Y2hlcigpO1xuICAgIH1cblxuICAgIHRoaXMuaXNJbml0aWFsaXplZCA9IHRydWU7XG4gICAgdGhpcy5faW5pdEVsYXBzZWQgPSBwZXJmb3JtYW5jZS5ub3coKSAtIGluaXRTdGFydDtcbiAgICB0aGlzLl9jb25maWdFbGFwc2VkID0gY29uZmlnVGltZTtcbiAgfVxuXG4gIHByaXZhdGUgX2luaXRFbGFwc2VkID0gMDtcbiAgcHJpdmF0ZSBfY29uZmlnRWxhcHNlZCA9IDA7XG5cbiAgYXN5bmMgY3JlYXRlU2VydmVyKGluaXRPcHRpb25zPzogeyBlbmFibGVTeW5jPzogYm9vbGVhbjsgZG9TaWxlbnQ/OiBib29sZWFuIH0pIHtcbiAgICBpZiAoIXRoaXMuaXNJbml0aWFsaXplZCkge1xuICAgICAgYXdhaXQgdGhpcy5pbml0KGluaXRPcHRpb25zPy5kb1NpbGVudCwgaW5pdE9wdGlvbnM/LmVuYWJsZVN5bmMpO1xuICAgIH1cblxuICAgIGNvbnN0IG9wdGlvbnMgPSB0aGlzLmNvbmZpZy5zZXJ2ZXI7XG4gICAgY29uc3QgeyBkZWZhdWx0OiBmYXN0aWZ5IH0gPSBhd2FpdCBpbXBvcnQoXCJmYXN0aWZ5XCIpO1xuICAgIGNvbnN0IHsgZ2V0TG9nVGFwZUZhc3RpZnlMb2dnZXIgfSA9IGF3YWl0IGltcG9ydChcIkBsb2d0YXBlL2Zhc3RpZnlcIik7XG4gICAgY29uc3Qgc2VydmVyID0gZmFzdGlmeSh7XG4gICAgICAuLi5vcHRpb25zLmZhc3RpZnksXG4gICAgICBsb2dnZXI6XG4gICAgICAgIHRoaXMuY29uZmlnLmxvZ2dpbmcgIT09IGZhbHNlXG4gICAgICAgICAgPyBnZXRMb2dUYXBlRmFzdGlmeUxvZ2dlcih7XG4gICAgICAgICAgICAgIGNhdGVnb3J5OiB0aGlzLmNvbmZpZy5sb2dnaW5nPy5mYXN0aWZ5Q2F0ZWdvcnkgPz8gW1wiZmFzdGlmeVwiXSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgfSk7XG4gICAgdGhpcy5zZXJ2ZXIgPSBzZXJ2ZXI7XG4gICAgdGhpcy53ZWJzb2NrZXRSdW50aW1lID0gbmV3IFdlYlNvY2tldFJ1bnRpbWUob3B0aW9ucy53ZWJzb2NrZXQpO1xuXG4gICAgLy8gU3RvcmFnZSDshKTsoJUg4oaSIFN0b3JhZ2VNYW5hZ2VyIOyDneyEsVxuICAgIGlmIChvcHRpb25zLnN0b3JhZ2UpIHtcbiAgICAgIGNvbnN0IHsgU3RvcmFnZU1hbmFnZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL3N0b3JhZ2Uvc3RvcmFnZS1tYW5hZ2VyXCIpO1xuICAgICAgdGhpcy5fc3RvcmFnZSA9IG5ldyBTdG9yYWdlTWFuYWdlcihvcHRpb25zLnN0b3JhZ2UpO1xuICAgIH1cblxuICAgIC8vIO2UjOufrOq3uOyduCDrk7HroZ1cbiAgICBpZiAob3B0aW9ucy5wbHVnaW5zKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlZ2lzdGVyUGx1Z2lucyhzZXJ2ZXIsIG9wdGlvbnMucGx1Z2lucyk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuYXV0aCkge1xuICAgICAgYXdhaXQgdGhpcy5yZWdpc3RlckJldHRlckF1dGgoc2VydmVyLCBvcHRpb25zLmF1dGgpO1xuICAgIH1cblxuICAgIC8vIEFQSSDrnbzsmrDtjIUg7ISk7KCVXG4gICAgYXdhaXQgdGhpcy53aXRoRmFzdGlmeShzZXJ2ZXIsIG9wdGlvbnMuYXBpQ29uZmlnLCB7XG4gICAgICBlbmFibGVTeW5jOiBpbml0T3B0aW9ucz8uZW5hYmxlU3luYyxcbiAgICAgIGRvU2lsZW50OiBpbml0T3B0aW9ucz8uZG9TaWxlbnQsXG4gICAgfSk7XG5cbiAgICAvLyDshJzrsoQg7Iuc7J6RXG4gICAgYXdhaXQgdGhpcy5ib290KHNlcnZlciwgb3B0aW9ucyk7XG5cbiAgICBpZiAoIWluaXRPcHRpb25zPy5kb1NpbGVudCkge1xuICAgICAgdGhpcy5wcmludFN0YXJ0dXBTdW1tYXJ5KCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlcnZlcjtcbiAgfVxuXG4gIGFzeW5jIHdpdGhGYXN0aWZ5KFxuICAgIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT4sXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICAgIG9wdGlvbnM/OiB7XG4gICAgICBlbmFibGVTeW5jPzogYm9vbGVhbjtcbiAgICAgIGRvU2lsZW50PzogYm9vbGVhbjtcbiAgICB9LFxuICApIHtcbiAgICBpZiAoIXRoaXMuaXNJbml0aWFsaXplZCkge1xuICAgICAgYXdhaXQgdGhpcy5pbml0KG9wdGlvbnM/LmRvU2lsZW50LCBvcHRpb25zPy5lbmFibGVTeW5jKTtcbiAgICB9XG5cbiAgICB0aGlzLnNlcnZlciA9IHNlcnZlcjtcbiAgICB0aGlzLndlYnNvY2tldFJ1bnRpbWUgPz89IG5ldyBXZWJTb2NrZXRSdW50aW1lKHRoaXMuY29uZmlnLnNlcnZlci53ZWJzb2NrZXQpO1xuXG4gICAgLy8gdGltZXpvbmUg7ISk7KCVXG4gICAgY29uc3QgdGltZXpvbmUgPSB0aGlzLmNvbmZpZy5hcGkudGltZXpvbmU7XG4gICAgaWYgKHRpbWV6b25lKSB7XG4gICAgICAvLyDtg4DsnoTsobTsl5Ag66ee6rKMIOydkeuLtSDrgqDsp5wg7Iqk7Yq466eB7J2EIOuzgO2ZmO2VtOyjvOyWtOyVvCDtlanri4jri6QuXG4gICAgICAvLyDqsIDroLkgdGltZXpvbmXsnbQgXCJBc2lhL1Nlb3VsXCIg7J2066m0XG4gICAgICAvLyBcIjIwMjUtMTEtMjFUMDA6MDA6MDAuMDAwWlwiIOulvCBcIjIwMjUtMTEtMjFUMDk6MDA6MDArMDk6MDBcIiDsnLzroZwg67OA7ZmY7ZW07KO87Ja07JW8IO2VqeuLiOuLpC5cbiAgICAgIGNvbnN0IHsgZm9ybWF0SW5UaW1lWm9uZSB9ID0gYXdhaXQgaW1wb3J0KFwiZGF0ZS1mbnMtdHpcIik7XG5cbiAgICAgIC8vIElTTyA4NjAxIOuCoOynnCDtmJXsi50g7KCV6rec7IudICjsmIg6IDIwMjQtMDEtMTVUMDk6MzA6MDAuMDAwWilcbiAgICAgIGNvbnN0IElTT19EQVRFX1JFR0VYID0gL15cXGR7NH0tXFxkezJ9LVxcZHsyfVRcXGR7Mn06XFxkezJ9OlxcZHsyfShcXC5cXGR7M30pP1okLztcblxuICAgICAgLy8gVOulvCDrkZjrn6zsi7wg7J6R7J2A65Sw7Ji07ZGc6rCAIOyXhuuLpOuptCBcIjIwMjUtMTEtMTkxNzYzNTQ2MTg5MDAwMTg6NTY6MjkrMDk6MDBcIuyZgCDqsJnsnYAg6rKw6rO86rCAIOuCmOyYteuLiOuLpC5cbiAgICAgIC8vIOydtOuKlCBkYXRlLWZucyDtirnsnoXri4jri6QuXG4gICAgICAvLyDsnbTroIfqsowg7ZW064+EIOq0nOywruyKteuLiOuLpC4gXCIyMDI1LTExLTE5VDE4OjU2OjI5KzA5OjAwXCIg66qo7JaR7Jy866GcIOyemCDrgpjsmLXri4jri6QuXG4gICAgICBjb25zdCBEQVRFX0ZPUk1BVCA9IFwieXl5eS1NTS1kZCdUJ0hIOm1tOnNzWFhYXCI7XG5cbiAgICAgIHNlcnZlci5zZXRSZXBseVNlcmlhbGl6ZXIoKHBheWxvYWQpID0+IHtcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHBheWxvYWQsIChfa2V5LCB2YWx1ZSkgPT4ge1xuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiYgSVNPX0RBVEVfUkVHRVgudGVzdCh2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmb3JtYXRJblRpbWVab25lKFxuICAgICAgICAgICAgICBuZXcgRGF0ZSh2YWx1ZSksXG4gICAgICAgICAgICAgIHRpbWV6b25lIGFzIGAke3N0cmluZ30vJHtzdHJpbmd9YCxcbiAgICAgICAgICAgICAgREFURV9GT1JNQVQsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgICAvLyBUaW1lem9uZSDroZzqt7jripQgcHJpbnRTdGFydHVwU3VtbWFyeeyXkOyEnCDthrXtlakg7Lac66ClXG4gICAgfVxuXG4gICAgLy8g7KCE7LK0IOudvOyasO2MhSDrpqzsiqTtirhcbiAgICBzZXJ2ZXIuZ2V0KFxuICAgICAgYCR7dGhpcy5jb25maWcuYXBpLnJvdXRlLnByZWZpeH0vcm91dGVzYCxcbiAgICAgIGFzeW5jIChfcmVxdWVzdCwgX3JlcGx5KTogUHJvbWlzZTx0eXBlb2YgdGhpcy5zeW5jZXIuYXBpcz4gPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5zeW5jZXIuYXBpcztcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIC8vIEhlYWx0aGNoZWNrIEFQSVxuICAgIHNlcnZlci5nZXQoXG4gICAgICBgJHt0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4fS9oZWFsdGhjaGVja2AsXG4gICAgICBhc3luYyAoX3JlcXVlc3QsIF9yZXBseSk6IFByb21pc2U8c3RyaW5nPiA9PiB7XG4gICAgICAgIHJldHVybiBcIm9rXCI7XG4gICAgICB9LFxuICAgICk7XG5cbiAgICAvLyBTb25hbXUgVUkgQVBJICjroZzsu6wg7ZmY6rK97JeQ7ISc66eMKVxuICAgIGNvbnN0IHsgaXNMb2NhbCB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvY29udHJvbGxlclwiKTtcbiAgICBpZiAoaXNMb2NhbCgpKSB7XG4gICAgICBjb25zdCB7IHNvbmFtdVVJQXBpUGx1Z2luIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi91aS9hcGlcIik7XG4gICAgICBzZXJ2ZXIucmVnaXN0ZXIoc29uYW11VUlBcGlQbHVnaW4pO1xuICAgIH1cblxuICAgIC8vIERldlJ1bm5lciDthYzsiqTtirgg7JeU65Oc7Y+s7J247Yq4ICjroZzsu6wg7ZmY6rK9ICsgZGV2UnVubmVyIO2ZnOyEse2ZlCDsi5wpXG4gICAgaWYgKGlzTG9jYWwoKSAmJiB0aGlzLmNvbmZpZy50ZXN0Py5kZXZSdW5uZXI/LmVuYWJsZWQpIHtcbiAgICAgIGNvbnN0IHsgcmVnaXN0ZXJEZXZUZXN0Um91dGVzIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi90ZXN0aW5nL2Rldi10ZXN0LXJvdXRlc1wiKTtcbiAgICAgIGF3YWl0IHJlZ2lzdGVyRGV2VGVzdFJvdXRlcyhzZXJ2ZXIsIHRoaXMuY29uZmlnLnRlc3QuZGV2UnVubmVyKTtcbiAgICB9XG5cbiAgICBjb25zdCB3ZWJQYXRoID0gcGF0aC5qb2luKHRoaXMuYXBwUm9vdFBhdGgsIFwid2ViXCIpO1xuICAgIGNvbnN0IGhhc1dlYiA9IGF3YWl0IGV4aXN0cyh3ZWJQYXRoKTtcblxuICAgIC8vIOyghOyXrSBjb21wcmVzcyDsmLXshZgg6rOE7IKwIChyb3V0ZS5jb21wcmVzczogdHJ1ZeydvCDrlYwg7IKs7JqpKVxuICAgIGNvbnN0IHBsdWdpbkNvbXByZXNzID0gdGhpcy5jb25maWcuc2VydmVyLnBsdWdpbnM/LmNvbXByZXNzO1xuICAgIGNvbnN0IGdsb2JhbENvbXByZXNzT3B0aW9uczogQ29tcHJlc3NPcHRpb25zIHwgdW5kZWZpbmVkID0gcGx1Z2luQ29tcHJlc3NcbiAgICAgID8gcGx1Z2luQ29tcHJlc3MgPT09IHRydWVcbiAgICAgICAgPyB7IHRocmVzaG9sZDogMTAyNCwgZW5jb2RpbmdzOiBbXCJiclwiLCBcImd6aXBcIiwgXCJkZWZsYXRlXCJdIH1cbiAgICAgICAgOiB7XG4gICAgICAgICAgICB0aHJlc2hvbGQ6IHBsdWdpbkNvbXByZXNzLnRocmVzaG9sZCxcbiAgICAgICAgICAgIGVuY29kaW5nczogcGx1Z2luQ29tcHJlc3MuZW5jb2RpbmdzLFxuICAgICAgICAgICAgY3VzdG9tVHlwZXM6IHBsdWdpbkNvbXByZXNzLmN1c3RvbVR5cGVzLFxuICAgICAgICAgIH1cbiAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgaWYgKGlzTG9jYWwoKSkge1xuICAgICAgLy8g66Gc7LusIOqwnOuwnCDtmZjqsr06IGNhdGNoLWFsbOuhnCBBUEnrpbwg64+Z7KCBIOunpOy5re2VmOyXrCBITVLsnYQg7KeA7JuQ7ZWp64uI64ukLlxuICAgICAgLy8gU09OQU1VX0RJU0FCTEVfSU5URUdSQVRFRF9XRUI9eWVz66GcIOyEpOygle2VmOuptCBkZXZfYXBpIOuqqOuTnOyXkOyEnCBWaXRlIO2Gte2VqeydhCDruYTtmZzshLHtmZTtlaAg7IiYIOyeiOyKteuLiOuLpC5cbiAgICAgIGNvbnN0IGRpc2FibGVJbnRlZ3JhdGVkV2ViID0gcHJvY2Vzcy5lbnYuU09OQU1VX0RJU0FCTEVfSU5URUdSQVRFRF9XRUIgPT09IFwieWVzXCI7XG4gICAgICBpZiAoaGFzV2ViICYmICFkaXNhYmxlSW50ZWdyYXRlZFdlYikge1xuICAgICAgICBhd2FpdCB0aGlzLnNldHVwRGV2U2VydmVyV2l0aFZpdGUoc2VydmVyLCB3ZWJQYXRoLCBjb25maWcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zZXR1cERldlNlcnZlcihzZXJ2ZXIsIGNvbmZpZyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIO2UhOuhnOuNleyFmCDtmZjqsr06IOqwnOuzhCBBUEkg65287Jqw7Yq4ICsg7KCV7KCBIO2MjOydvCDshJzruZlcbiAgICAgIGZvciAoY29uc3QgYXBpIG9mIHRoaXMuc3luY2VyLmFwaXMpIHtcbiAgICAgICAgaWYgKHRoaXMuc3luY2VyLm1vZGVsc1thcGkubW9kZWxOYW1lXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGDsoJXsnZjrkJjsp4Ag7JWK7J2AIOuqqOuNuOyXkCDsoJHqt7wgJHthcGkubW9kZWxOYW1lfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQHdlYnNvY2tldCByb3V0ZeuKlCB3c0hhbmRsZXLroZwg65Ox66Gd7ZWY6rOgLCDqsJnsnYAgcGF0aOydmCDsnbzrsJggSFRUUCBHRVTsnYAgNDI2IOydkeuLteycvOuhnCB1cGdyYWRl66W8IOqwleygnO2VqFxuICAgICAgICBpZiAoYXBpLndlYnNvY2tldE9wdGlvbnMpIHtcbiAgICAgICAgICBzZXJ2ZXIucm91dGUoe1xuICAgICAgICAgICAgbWV0aG9kOiBcIkdFVFwiLFxuICAgICAgICAgICAgdXJsOiB0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4ICsgYXBpLnBhdGgsXG4gICAgICAgICAgICBoYW5kbGVyOiB0aGlzLmNyZWF0ZVdlYlNvY2tldFVwZ3JhZGVSZXF1aXJlZEhhbmRsZXIoKSxcbiAgICAgICAgICAgIHdzSGFuZGxlcjogdGhpcy5jcmVhdGVXZWJTb2NrZXRIYW5kbGVyKGFwaSwgY29uZmlnKSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICAgICAgbWV0aG9kOiBhcGkub3B0aW9ucy5odHRwTWV0aG9kID8/IFwiR0VUXCIsXG4gICAgICAgICAgdXJsOiB0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4ICsgYXBpLnBhdGgsXG4gICAgICAgICAgaGFuZGxlcjogdGhpcy5jcmVhdGVBcGlIYW5kbGVyKGFwaSwgY29uZmlnKSxcbiAgICAgICAgICBjb21wcmVzczogdG9GYXN0aWZ5Q29tcHJlc3NPcHRpb24oYXBpLm9wdGlvbnMuY29tcHJlc3MsIGdsb2JhbENvbXByZXNzT3B0aW9ucyksXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICAvLyDtlITroZzrjZXshZjsl5DshJzripQgd2ViIOyGjOyKpChhcHBSb290L3dlYikg7Jyg66y07JmAIOustOq0gO2VmOqyjCxcbiAgICAgIC8vIGFwaS93ZWItZGlzdCDsobTsnqwg7Jes67aA66W8IHNldHVwU3RhdGljV2ViU2VydmVyIOuCtOu2gOyXkOyEnCDtjJDri6jtlanri4jri6QuXG4gICAgICBhd2FpdCB0aGlzLnNldHVwU3RhdGljV2ViU2VydmVyKHNlcnZlciwgY29uZmlnLCBnbG9iYWxDb21wcmVzc09wdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBkZXYg66qo65OcIOqzte2GtTogY2F0Y2gtYWxs7JeQ7IScIHN5bmNlci5hcGlz66W8IOuPmeyggeycvOuhnCDtg5Dsg4ntlZjsl6wgQVBJIOyalOyyreydhCDsspjrpqztlanri4jri6QuXG4gICAqIHNlcnZlci5yb3V0ZSgp66GcIOqwnOuzhCDrk7HroZ3tlZjrqbQgaGFuZGxlcuqwgCDqs6DsoJXrkJjslrQgSE1S7J20IOuPmeyeke2VmOyngCDslYrsnLzrr4DroZwsXG4gICAqIOunpCDsmpTssq3rp4jri6Qgc3luY2VyLmFwaXPrpbwg7KGw7ZqM7ZWY64qUIOydtCDrsKnsi53snYQg7IKs7Jqp7ZWp64uI64ukLlxuICAgKlxuICAgKiDsmpTssq3snbQgL2FwaSjsoJXtmZXtnojripQgdGhpcy5jb25maWcuYXBpLnJvdXRlLnByZWZpeCnroZwg7Iuc7J6R7ZWY7KeAIOyViuuKlCDqsr3smrDrnbzrqbQgbnVsbOydhCDrsJjtmZjtlZjrqbAg64Gd64OF64uI64ukLlxuICAgKi9cbiAgcHJpdmF0ZSBoYW5kbGVEZXZBcGlSZXF1ZXN0KFxuICAgIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgKTogKChyZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCwgcmVwbHk6IEZhc3RpZnlSZXBseSkgPT4gUHJvbWlzZTx1bmtub3duPikgfCBudWxsIHtcbiAgICBjb25zdCBtYXRjaGVkQXBpID0gdGhpcy5maW5kTWF0Y2hlZEFwaShyZXF1ZXN0KTtcblxuICAgIGlmICghbWF0Y2hlZEFwaSkge1xuICAgICAgdGhyb3cgbmV3IE5vdEZvdW5kRXhjZXB0aW9uKFNEKFwiZXJyb3IuYXBpLm5vdEZvdW5kXCIpKTtcbiAgICB9XG5cbiAgICAvLyB3ZWJzb2NrZXQgcm91dGXrpbwg7J2867CYIEhUVFDroZwg7KeB7KCRIO2YuOy2nO2VnCDqsr3smrAgNDI27J2EIOuPjOugpOykmCB1cGdyYWRlIOyXhuydtCDsoJHqt7ztlZjripQg6rKD7J2EIOywqOuLqO2VqFxuICAgIGlmIChtYXRjaGVkQXBpLndlYnNvY2tldE9wdGlvbnMpIHtcbiAgICAgIHJldHVybiB0aGlzLmNyZWF0ZVdlYlNvY2tldFVwZ3JhZGVSZXF1aXJlZEhhbmRsZXIoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5jcmVhdGVBcGlIYW5kbGVyKG1hdGNoZWRBcGksIGNvbmZpZyk7XG4gIH1cblxuICBwcml2YXRlIGZpbmRNYXRjaGVkQXBpKHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0KTogRXh0ZW5kZWRBcGkgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHVybCA9IHRoaXMuZ2V0UGF0aG5hbWVGcm9tVXJsKHJlcXVlc3QudXJsKTtcbiAgICBjb25zdCBtZXRob2QgPSByZXF1ZXN0Lm1ldGhvZDtcblxuICAgIGlmICghdXJsLnN0YXJ0c1dpdGgodGhpcy5jb25maWcuYXBpLnJvdXRlLnByZWZpeCkpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuc3luY2VyLmFwaXMuZmluZCgoYXBpKSA9PiB7XG4gICAgICBpZiAodGhpcy5zeW5jZXIubW9kZWxzW2FwaS5tb2RlbE5hbWVdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgY29uc3QgYXBpTWV0aG9kID0gYXBpLm9wdGlvbnMuaHR0cE1ldGhvZCA/PyBcIkdFVFwiO1xuICAgICAgaWYgKGFwaU1ldGhvZCAhPT0gbWV0aG9kKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgIGNvbnN0IGZ1bGxQYXRoID0gdGhpcy5jb25maWcuYXBpLnJvdXRlLnByZWZpeCArIGFwaS5wYXRoO1xuICAgICAgcmV0dXJuIHRoaXMuaXNQYXRoUGF0dGVybk1hdGNoKGZ1bGxQYXRoLCB1cmwpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIGRldiBhcGkg66qo65OcOiBWaXRlIOyXhuydtCBBUEkg64+Z7KCBIOudvOyasO2MheunjCDsoJzqs7Xtlanri4jri6QuXG4gICAqIEhNUuydhCDsnITtlbQgY2F0Y2gtYWxs7JeQ7IScIOunpCDsmpTssq3rp4jri6Qgc3luY2VyLmFwaXPrpbwg7KGw7ZqM7ZWp64uI64ukLlxuICAgKi9cbiAgcHJpdmF0ZSBzZXR1cERldlNlcnZlcihcbiAgICBzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZTxTZXJ2ZXIsIEluY29taW5nTWVzc2FnZSwgU2VydmVyUmVzcG9uc2U+LFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgKTogdm9pZCB7XG4gICAgLy8gdXBncmFkZeuKlCDsi6Tsp4jsoIHsnLzroZwgR0VU7JeQ7ISc66eMIOyEseumve2VmOuvgOuhnCBHRVQgKyB3c0hhbmRsZXIg7JmAIOq3uCDsmbggbWV0aG9k66W8IOuzhOuPhCByb3V0ZeuhnCDrtoTrpqztlahcbiAgICBzZXJ2ZXIucm91dGUoe1xuICAgICAgbWV0aG9kOiBcIkdFVFwiLFxuICAgICAgdXJsOiBgJHt0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4fS8qYCxcbiAgICAgIGhhbmRsZXI6IGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICBjb25zdCBoYW5kbGVyID0gdGhpcy5oYW5kbGVEZXZBcGlSZXF1ZXN0KHJlcXVlc3QsIGNvbmZpZyk7XG4gICAgICAgIGlmIChoYW5kbGVyKSB7XG4gICAgICAgICAgcmV0dXJuIGhhbmRsZXIocmVxdWVzdCwgcmVwbHkpO1xuICAgICAgICB9XG4gICAgICAgIC8vIOuTseuhneuQnCBBUEnsmYAg7J287LmY7ZWY7KeAIOyViuuKlCDsmpTssq3sl5Ag64yA7ZWcIGZhbGxiYWNr7J6F64uI64ukLlxuICAgICAgICB0aHJvdyBuZXcgTm90Rm91bmRFeGNlcHRpb24oU0QoXCJlcnJvci5hcGkubm90Rm91bmRcIikpO1xuICAgICAgfSxcbiAgICAgIHdzSGFuZGxlcjogYXN5bmMgKGNvbm5lY3Rpb24sIHJlcXVlc3QpID0+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVEZXZXZWJTb2NrZXRSZXF1ZXN0KGNvbm5lY3Rpb24uc29ja2V0LCByZXF1ZXN0LCBjb25maWcpO1xuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICBtZXRob2Q6IFtcIkhFQURcIiwgXCJQT1NUXCIsIFwiUFVUXCIsIFwiREVMRVRFXCIsIFwiUEFUQ0hcIl0sXG4gICAgICB1cmw6IGAke3RoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXh9LypgLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPSB0aGlzLmhhbmRsZURldkFwaVJlcXVlc3QocmVxdWVzdCwgY29uZmlnKTtcbiAgICAgICAgaWYgKGhhbmRsZXIpIHtcbiAgICAgICAgICByZXR1cm4gaGFuZGxlcihyZXF1ZXN0LCByZXBseSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IE5vdEZvdW5kRXhjZXB0aW9uKFNEKFwiZXJyb3IuYXBpLm5vdEZvdW5kXCIpKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHZpdGVTZXJ2ZXI6IGFueSA9IG51bGw7XG5cbiAgLyoqXG4gICAqIGRldiBhbGwg66qo65OcOiBWaXRlIERldiBTZXJ2ZXLrpbwg7Ya17ZWp7ZWY7JesIEFQSSArIFNTUiArIENTUuydhCDrqqjrkZAg7KCc6rO17ZWp64uI64ukLlxuICAgKiBBUEkg64+Z7KCBIOunpOy5reydgCBoYW5kbGVEZXZBcGlSZXF1ZXN066W8IOqzteycoO2VqeuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgc2V0dXBEZXZTZXJ2ZXJXaXRoVml0ZShcbiAgICBzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZTxTZXJ2ZXIsIEluY29taW5nTWVzc2FnZSwgU2VydmVyUmVzcG9uc2U+LFxuICAgIHdlYlBhdGg6IHN0cmluZyxcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIEBmYXN0aWZ5L21pZGRpZSDrk7HroZ0gKENvbm5lY3Qtc3R5bGUgbWlkZGxld2FyZSDsp4Dsm5ApXG4gICAgYXdhaXQgc2VydmVyLnJlZ2lzdGVyKChhd2FpdCBpbXBvcnQoXCJAZmFzdGlmeS9taWRkaWVcIikpLmRlZmF1bHQpO1xuXG4gICAgY29uc3Qgdml0ZSA9IGF3YWl0IGltcG9ydChcInZpdGVcIik7XG4gICAgLy8gQGZhc3RpZnkvd2Vic29ja2V0IO2UjOufrOq3uOyduOydtCDtmZzshLHtmZTrkJjrqbQgSE1SIHdlYnNvY2tldOqzvCBzZXJ2ZXIgc29ja2V07J20IOy2qeuPjO2VmOuvgOuhnCBkZWRpY2F0ZWQg7Y+s7Yq466GcIOu2hOumrO2VqFxuICAgIGNvbnN0IHJlcXVpcmVzRGVkaWNhdGVkSG1yU2VydmVyID0gQm9vbGVhbih0aGlzLmNvbmZpZy5zZXJ2ZXIucGx1Z2lucz8ud3MpO1xuICAgIGNvbnN0IGhtciA9IHJlc29sdmVJbnRlZ3JhdGVkVml0ZUhtck9wdGlvbnMoe1xuICAgICAgaHR0cFNlcnZlcjogc2VydmVyLnNlcnZlcixcbiAgICAgIHJlcXVpcmVzRGVkaWNhdGVkV2ViU29ja2V0U2VydmVyOiByZXF1aXJlc0RlZGljYXRlZEhtclNlcnZlcixcbiAgICB9KTtcblxuICAgIHRoaXMudml0ZVNlcnZlciA9IGF3YWl0IHZpdGUuY3JlYXRlU2VydmVyKHtcbiAgICAgIHJvb3Q6IHdlYlBhdGgsXG4gICAgICBzZXJ2ZXI6IHtcbiAgICAgICAgbWlkZGxld2FyZU1vZGU6IHRydWUsXG4gICAgICAgIGhtcixcbiAgICAgIH0sXG4gICAgICBhcHBUeXBlOiBcImN1c3RvbVwiLFxuICAgIH0pO1xuXG4gICAgLy8gVml0ZSBtaWRkbGV3YXJlIOuTseuhnSAoVml0ZSDsl5DshYsg7LKY66asKVxuICAgIHNlcnZlci51c2UoKHJlcSwgcmVzLCBuZXh0KSA9PiB7XG4gICAgICAvLyBBUEnsmYAgU29uYW11IFVJ64qUIEZhc3RpZnkg65287Jqw7Yq46rCAIOyymOumrO2VmOuPhOuhnSBza2lwXG4gICAgICBpZiAocmVxLnVybD8uc3RhcnRzV2l0aCh0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4KSB8fCByZXEudXJsPy5zdGFydHNXaXRoKFwiL3NvbmFtdS11aVwiKSkge1xuICAgICAgICByZXR1cm4gbmV4dCgpO1xuICAgICAgfVxuICAgICAgLy8g64KY66i47KeA64qUIFZpdGUgbWlkZGxld2FyZeuhnCDsoITri6xcbiAgICAgIHJldHVybiB0aGlzLnZpdGVTZXJ2ZXIubWlkZGxld2FyZXMocmVxLCByZXMsIG5leHQpO1xuICAgIH0pO1xuXG4gICAgLy8gV1MgdXBncmFkZSDqsr3roZwoR0VUKeyZgCDsnbzrsJggSFRUUCDrqZTshJzrk5zrpbwg67OE64+EIHJvdXRl66GcIOu2hOumrO2VtCB3ZWJzb2NrZXQgcm91dGXqsIAgSFRNTCBmYWxsYmFja+yXkCDrqLntnojsp4Ag7JWK64+E66GdIO2VqFxuICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgICB1cmw6IGAke3RoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXh9LypgLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuaGFuZGxlRGV2QXBpUmVxdWVzdChyZXF1ZXN0LCBjb25maWcpO1xuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdChyZXF1ZXN0LCByZXBseSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IE5vdEZvdW5kRXhjZXB0aW9uKFNEKFwiZXJyb3IuYXBpLm5vdEZvdW5kXCIpKTtcbiAgICAgIH0sXG4gICAgICB3c0hhbmRsZXI6IGFzeW5jIChjb25uZWN0aW9uLCByZXF1ZXN0KSA9PiB7XG4gICAgICAgIGF3YWl0IHRoaXMuaGFuZGxlRGV2V2ViU29ja2V0UmVxdWVzdChjb25uZWN0aW9uLnNvY2tldCwgcmVxdWVzdCwgY29uZmlnKTtcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBzZXJ2ZXIucm91dGUoe1xuICAgICAgbWV0aG9kOiBbXCJIRUFEXCIsIFwiUE9TVFwiLCBcIlBVVFwiLCBcIkRFTEVURVwiLCBcIlBBVENIXCJdLFxuICAgICAgdXJsOiBgJHt0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4fS8qYCxcbiAgICAgIGhhbmRsZXI6IGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLmhhbmRsZURldkFwaVJlcXVlc3QocmVxdWVzdCwgY29uZmlnKTtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgIHJldHVybiByZXN1bHQocmVxdWVzdCwgcmVwbHkpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBOb3RGb3VuZEV4Y2VwdGlvbihTRChcImVycm9yLmFwaS5ub3RGb3VuZFwiKSk7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgLy8gY2F0Y2gtYWxsIOudvOyasO2KuOyXkOyEnCBTU1IvQ1NSIOyymOumrFxuICAgIC8vIOqwnOuwnCDtmZjqsr3sl5DshJzripQg65287Jqw7Yq467OEIGNvbXByZXNzIOyYteyFmOydhCDtj6zquLDtlZjqs6AgSE1SIOydtOygkOydhCDst6jtlanri4jri6QuXG4gICAgc2VydmVyLnJvdXRlKHtcbiAgICAgIG1ldGhvZDogW1wiR0VUXCIsIFwiSEVBRFwiXSxcbiAgICAgIHVybDogXCIvKlwiLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IHVybCA9IHJlcXVlc3QudXJsO1xuXG4gICAgICAgIC8vIDEuIFNTUiDrnbzsmrDtirgg7LKY66asXG4gICAgICAgIGNvbnN0IHsgbWF0Y2hTU1JSb3V0ZSwgcmVuZGVyU1NSIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9zc3JcIik7XG4gICAgICAgIGNvbnN0IHNzck1hdGNoID0gbWF0Y2hTU1JSb3V0ZSh1cmwpO1xuICAgICAgICBpZiAoc3NyTWF0Y2gpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgW1NTUl0gTWF0Y2hlZCByb3V0ZTogJHtzc3JNYXRjaC5yb3V0ZS5wYXRofWApO1xuICAgICAgICAgIGNvbnN0IGh0bWwgPSBhd2FpdCByZW5kZXJTU1IoXG4gICAgICAgICAgICB1cmwsXG4gICAgICAgICAgICBzc3JNYXRjaC5yb3V0ZSxcbiAgICAgICAgICAgIHNzck1hdGNoLnBhcmFtcyxcbiAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICByZXBseSxcbiAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgIHRoaXMudml0ZVNlcnZlcixcbiAgICAgICAgICApO1xuICAgICAgICAgIHJlcGx5LnR5cGUoXCJ0ZXh0L2h0bWxcIik7XG4gICAgICAgICAgcmV0dXJuIGh0bWw7XG4gICAgICAgIH1cblxuICAgICAgICAvLyAyLiBDU1IgZmFsbGJhY2tcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBmcyA9IGF3YWl0IGltcG9ydChcIm5vZGU6ZnMvcHJvbWlzZXNcIik7XG4gICAgICAgICAgbGV0IHRlbXBsYXRlID0gYXdhaXQgZnMucmVhZEZpbGUoXG4gICAgICAgICAgICBwYXRoLmpvaW4odGhpcy52aXRlU2VydmVyLmNvbmZpZy5yb290LCBcImluZGV4Lmh0bWxcIiksXG4gICAgICAgICAgICBcInV0Zi04XCIsXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0ZW1wbGF0ZSA9IGF3YWl0IHRoaXMudml0ZVNlcnZlci50cmFuc2Zvcm1JbmRleEh0bWwodXJsLCB0ZW1wbGF0ZSk7XG5cbiAgICAgICAgICByZXBseS50eXBlKFwidGV4dC9odG1sXCIpO1xuICAgICAgICAgIHJldHVybiB0ZW1wbGF0ZTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHRoaXMudml0ZVNlcnZlci5zc3JGaXhTdGFja3RyYWNlKGUgYXMgRXJyb3IpO1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgICAgcmVwbHkuc3RhdHVzKDUwMCk7XG4gICAgICAgICAgcmV0dXJuIChlIGFzIEVycm9yKS5tZXNzYWdlO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgLy8g7ISc67KEIOyiheujjCDsi5wgVml0ZeuPhCDsooXro4xcbiAgICBzZXJ2ZXIuYWRkSG9vayhcIm9uQ2xvc2VcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgdGhpcy52aXRlU2VydmVyLmNsb3NlKCk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBjaGFsayA9IChhd2FpdCBpbXBvcnQoXCJjaGFsa1wiKSkuZGVmYXVsdDtcbiAgICBpZiAoXCJwb3J0XCIgaW4gaG1yKSB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgY2hhbGsuZGltKFxuICAgICAgICAgIGDinJMgVml0ZSBITVIgdXNpbmcgZGVkaWNhdGVkIHdlYnNvY2tldCBwb3J0ICR7aG1yLnBvcnR9IHRvIGF2b2lkIEZhc3RpZnkgd2Vic29ja2V0IGNvbmZsaWN0c2AsXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zb2xlLmxvZyhjaGFsay5kaW0oXCLinJMgVml0ZSBkZXYgc2VydmVyIGludGVncmF0ZWRcIikpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZXR1cFN0YXRpY1dlYlNlcnZlcihcbiAgICBzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZTxTZXJ2ZXIsIEluY29taW5nTWVzc2FnZSwgU2VydmVyUmVzcG9uc2U+LFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgICBnbG9iYWxDb21wcmVzc09wdGlvbnM6IENvbXByZXNzT3B0aW9ucyB8IHVuZGVmaW5lZCxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8g6rK966GcIOuqhe2Zle2ZlDogYXBpL3dlYi1kaXN0L2NsaWVudCAo7KCV7KCBIO2MjOydvCksIGFwaS93ZWItZGlzdC9zZXJ2ZXIgKFNTUiBlbnRyeSksIGFwaS9kaXN0L3NzciAoU1NSIHJvdXRlcyAtIEFQSSDshozsnKApXG4gICAgY29uc3Qgd2ViRGlzdFBhdGggPSBwYXRoLmpvaW4odGhpcy5hcGlSb290UGF0aCwgXCJ3ZWItZGlzdFwiLCBcImNsaWVudFwiKTtcbiAgICBjb25zdCBzc3JQYXRoID0gcGF0aC5qb2luKHRoaXMuYXBpUm9vdFBhdGgsIFwid2ViLWRpc3RcIiwgXCJzZXJ2ZXJcIik7XG4gICAgY29uc3Qgc3NyRW50cnlQYXRoID0gcGF0aC5qb2luKHNzclBhdGgsIFwiZW50cnktc2VydmVyLmdlbmVyYXRlZC5qc1wiKTtcbiAgICBjb25zdCBzc3JSb3V0ZXNQYXRoID0gcGF0aC5qb2luKHRoaXMuYXBpUm9vdFBhdGgsIFwiZGlzdFwiLCBcInNzclwiLCBcInJvdXRlcy5qc1wiKTtcblxuICAgIGlmICghKGF3YWl0IGV4aXN0cyh3ZWJEaXN0UGF0aCkpKSB7XG4gICAgICBjb25zb2xlLndhcm4oYOKaoCBXZWIgZGlzdCBub3QgZm91bmQ6ICR7d2ViRGlzdFBhdGh9YCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gU1NSIGVudHJ5IOyhtOyerCDsl6zrtoAg7ZmV7J24XG4gICAgY29uc3Qgc3NyQXZhaWxhYmxlID0gYXdhaXQgZXhpc3RzKHNzckVudHJ5UGF0aCk7XG5cbiAgICBpZiAoIXNzckF2YWlsYWJsZSkge1xuICAgICAgY29uc29sZS53YXJuKGDimqAgU1NSIGVudHJ5IG5vdCBmb3VuZDogJHtzc3JFbnRyeVBhdGh9YCk7XG4gICAgICBjb25zb2xlLndhcm4oXCIgIFNTUiB3aWxsIGJlIGRpc2FibGVkLiBPbmx5IENTUiB3aWxsIHdvcmsuXCIpO1xuICAgIH1cblxuICAgIC8vIFNTUiDrnbzsmrDtirgg66Gc65OcIChwcm9kdWN0aW9u7JeQ7ISc66eMLCDsgqzsmqnsnpAg7ZSE66Gc7KCd7Yq47J2YIHNzci9yb3V0ZXMudHMpXG4gICAgaWYgKHNzckF2YWlsYWJsZSkge1xuICAgICAgaWYgKGF3YWl0IGV4aXN0cyhzc3JSb3V0ZXNQYXRoKSkge1xuICAgICAgICAvLyB0cy1sb2FkZXLrnbzrqbQgXCJmaWxlOi8vXCLroZwg7Iuc7J6R7ZWY64qUIGZ1bGx5LXJlc29sdmVkIHBhdGjrp4wg67Cb6riw7JeQIOydtOulvCDsspjrpqztlbTso7zripQgaW1wb3J0TWVtYmVyc+ulvCDsgqzsmqntlbTslbwg7ZaI6rKg7KeA66eMLFxuICAgICAgICAvLyDsl6zquLDripQg7ZSE66Gc642V7IWYIO2ZmOqyveyXkOyEnCBsb2FkZXIg7JeG7J20IOuPjOyVhOqwgOq4sCDrlYzrrLjsl5AgXCLsp4Tsp5wganMg7YyM7J28XCLsnZggXCLqt7jrg6VcIiDsoIjrjIDqsr3roZzrpbwg67CU66GcIGltcG9ydO2VtOuPhCDrkKnri4jri6QuXG4gICAgICAgIC8vIOydtCDrgrTsmqnsnYAg7J20IO2VqOyImCDrgrTsl5DshJwg7JWE656Y7JeQIOuCmOyYrCDri6TrpbggaW1wb3J0IO2YuOy2nOyXkOuPhCDrj5nsnbztlZjqsowg7KCB7Jqp65Cp64uI64ukLlxuICAgICAgICBhd2FpdCBpbXBvcnQoc3NyUm91dGVzUGF0aCk7XG4gICAgICAgIGNvbnNvbGUubG9nKFwi4pyTIFNTUiByb3V0ZXMgbG9hZGVkXCIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS53YXJuKGDimqAgU1NSIHJvdXRlcyBub3QgZm91bmQ6ICR7c3NyUm91dGVzUGF0aH1gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyDroaTrp4Eg7JeF642w7J207Yq4IOuMgOydkTogYXNzZXQgaGFzaCDrtojsnbzsuZgg7IucIO2YhOyerCDrsoTsoIQg7KeB7KCRIOyEnOu5mVxuICAgIHNlcnZlci5nZXQoXCIvYXNzZXRzLzpmaWxlbmFtZVwiLCBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgIGNvbnN0IHJlcXVlc3RlZEZpbGUgPSAocmVxdWVzdC5wYXJhbXMgYXMgeyBmaWxlbmFtZTogc3RyaW5nIH0pLmZpbGVuYW1lO1xuICAgICAgY29uc3QgYXNzZXRzRGlyID0gcGF0aC5qb2luKHdlYkRpc3RQYXRoLCBcImFzc2V0c1wiKTtcbiAgICAgIGNvbnN0IHNhZmVGaWxlUGF0aCA9IHRoaXMucmVzb2x2ZVBhdGhXaXRoaW5CYXNlRGlyKGFzc2V0c0RpciwgcmVxdWVzdGVkRmlsZSk7XG4gICAgICBpZiAoc2FmZUZpbGVQYXRoID09PSBudWxsKSB7XG4gICAgICAgIHJlcGx5LnN0YXR1cyg0MDMpLnNlbmQoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3Qgbm9ybWFsaXplZFJlcXVlc3RlZEZpbGUgPSBwYXRoLnJlbGF0aXZlKGFzc2V0c0Rpciwgc2FmZUZpbGVQYXRoKS5yZXBsYWNlKC9cXFxcL2csIFwiL1wiKTtcblxuICAgICAgY29uc3QgYXNzZXRQYXRoID0gYC9hc3NldHMvJHtub3JtYWxpemVkUmVxdWVzdGVkRmlsZX1gO1xuXG4gICAgICAvLyBDYWNoZS1Db250cm9sIO2XpOuNlCDqsrDsoJVcbiAgICAgIGNvbnN0IGdldENhY2hlQ29udHJvbEZvckFzc2V0ID0gKCk6IENhY2hlQ29udHJvbENvbmZpZyA9PiB7XG4gICAgICAgIGNvbnN0IGNhY2hlUmVxOiBDYWNoZUNvbnRyb2xSZXF1ZXN0ID0ge1xuICAgICAgICAgIHR5cGU6IFwiYXNzZXRzXCIsXG4gICAgICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgICAgICBwYXRoOiBhc3NldFBhdGgsXG4gICAgICAgICAgbWV0aG9kOiByZXF1ZXN0Lm1ldGhvZCxcbiAgICAgICAgfTtcblxuICAgICAgICAvLyDsgqzsmqnsnpAg7KCV7J2YIO2VuOuTpOufrCDsmrDshKBcbiAgICAgICAgaWYgKGNvbmZpZy5jYWNoZUNvbnRyb2xIYW5kbGVyKSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gY29uZmlnLmNhY2hlQ29udHJvbEhhbmRsZXIoY2FjaGVSZXEpO1xuICAgICAgICAgIGlmIChyZXN1bHQpIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyDquLDrs7jqsJI6IGltbXV0YWJsZVxuICAgICAgICByZXR1cm4gQ2FjaGVQcmVzZXRzLmltbXV0YWJsZTtcbiAgICAgIH07XG5cbiAgICAgIC8vIGluZGV4LSouanMg65iQ64qUIGluZGV4LSouY3NzIOyalOyyreyduCDqsr3smrBcbiAgICAgIGlmICgvXmluZGV4LVthLWYwLTldK1xcLihqc3xjc3MpJC8udGVzdChub3JtYWxpemVkUmVxdWVzdGVkRmlsZSkpIHtcbiAgICAgICAgY29uc3QgZXh0ID0gbm9ybWFsaXplZFJlcXVlc3RlZEZpbGUuc3BsaXQoXCIuXCIpLnBvcCgpO1xuICAgICAgICBjb25zdCBmaWxlcyA9IGF3YWl0IGZzLnJlYWRkaXIoYXNzZXRzRGlyKTtcbiAgICAgICAgY29uc3QgY3VycmVudEZpbGUgPSBmaWxlcy5maW5kKChmKSA9PiBmLnN0YXJ0c1dpdGgoXCJpbmRleC1cIikgJiYgZi5lbmRzV2l0aChgLiR7ZXh0fWApKTtcblxuICAgICAgICBpZiAoY3VycmVudEZpbGUpIHtcbiAgICAgICAgICBjb25zdCBmaWxlUGF0aCA9IHBhdGguam9pbihhc3NldHNEaXIsIGN1cnJlbnRGaWxlKTtcbiAgICAgICAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUoZmlsZVBhdGgpO1xuICAgICAgICAgIHJlcGx5LnR5cGUoZXh0ID09PSBcImpzXCIgPyBcImFwcGxpY2F0aW9uL2phdmFzY3JpcHRcIiA6IFwidGV4dC9jc3NcIik7XG4gICAgICAgICAgYXBwbHlDYWNoZUhlYWRlcnMocmVwbHksIGdldENhY2hlQ29udHJvbEZvckFzc2V0KCkpO1xuICAgICAgICAgIHJldHVybiByZXBseS5zZW5kKGNvbnRlbnQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIOydvOuwmCDtjIzsnbwg7ISc67mZXG4gICAgICBjb25zdCBmaWxlUGF0aCA9IHNhZmVGaWxlUGF0aDtcbiAgICAgIGlmIChhd2FpdCBleGlzdHMoZmlsZVBhdGgpKSB7XG4gICAgICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCBmcy5yZWFkRmlsZShmaWxlUGF0aCk7XG4gICAgICAgIGNvbnN0IGV4dCA9IG5vcm1hbGl6ZWRSZXF1ZXN0ZWRGaWxlLnNwbGl0KFwiLlwiKS5wb3AoKTtcbiAgICAgICAgcmVwbHkudHlwZShleHQgPT09IFwianNcIiA/IFwiYXBwbGljYXRpb24vamF2YXNjcmlwdFwiIDogZXh0ID09PSBcImNzc1wiID8gXCJ0ZXh0L2Nzc1wiIDogXCJcIik7XG4gICAgICAgIGlmIChub3JtYWxpemVkUmVxdWVzdGVkRmlsZS5pbmNsdWRlcyhcIi1cIikpIHtcbiAgICAgICAgICBhcHBseUNhY2hlSGVhZGVycyhyZXBseSwgZ2V0Q2FjaGVDb250cm9sRm9yQXNzZXQoKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcGx5LnNlbmQoY29udGVudCk7XG4gICAgICB9XG5cbiAgICAgIHJlcGx5LnN0YXR1cyg0MDQpLnNlbmQoKTtcbiAgICB9KTtcblxuICAgIC8vIFNTUiDrnbzsmrDtirgg6rCc67OEIOuTseuhnSAoY29tcHJlc3Mg7Ji17IWY7J20IOudvOyasO2KuOuzhOuhnCDsoIHsmqnrkJjrj4TroZ0pXG4gICAgaWYgKHNzckF2YWlsYWJsZSkge1xuICAgICAgY29uc3QgeyBnZXRTU1JSb3V0ZXMgfSA9IGF3YWl0IGltcG9ydChcIi4uL3NzclwiKTtcbiAgICAgIGNvbnN0IHsgcmVuZGVyU1NSIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9zc3IvcmVuZGVyZXJcIik7XG4gICAgICBjb25zdCBzc3JSb3V0ZXMgPSBnZXRTU1JSb3V0ZXMoKTtcblxuICAgICAgZm9yIChjb25zdCByb3V0ZSBvZiBzc3JSb3V0ZXMpIHtcbiAgICAgICAgc2VydmVyLnJvdXRlKHtcbiAgICAgICAgICBtZXRob2Q6IFtcIkdFVFwiLCBcIkhFQURcIl0sXG4gICAgICAgICAgdXJsOiByb3V0ZS5wYXRoLFxuICAgICAgICAgIGNvbXByZXNzOiB0b0Zhc3RpZnlDb21wcmVzc09wdGlvbihyb3V0ZS5jb21wcmVzcyA/PyB0cnVlLCBnbG9iYWxDb21wcmVzc09wdGlvbnMpLFxuICAgICAgICAgIGhhbmRsZXI6IGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdXJsID0gcmVxdWVzdC51cmw7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgW1NTUl0gTWF0Y2hlZCByb3V0ZTogJHtyb3V0ZS5wYXRofWApO1xuXG4gICAgICAgICAgICBjb25zdCBwYXJhbXMgPSB0aGlzLmV4dHJhY3RQYXRoUGFyYW1zKHJvdXRlLnBhdGgsIHVybCk7XG4gICAgICAgICAgICBjb25zdCBodG1sID0gYXdhaXQgcmVuZGVyU1NSKHVybCwgcm91dGUsIHBhcmFtcywgcmVxdWVzdCwgcmVwbHksIGNvbmZpZyk7XG5cbiAgICAgICAgICAgIHJlcGx5LnR5cGUoXCJ0ZXh0L2h0bWxcIik7XG4gICAgICAgICAgICByZXR1cm4gaHRtbDtcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDU1Igb3IgU3RhdGljIEZpbGUgRmFsbGJhY2sgKFNTUiDrnbzsmrDtirjsl5Ag66ek7Lmt65CY7KeAIOyViuuKlCDrqqjrk6Ag7JqU7LKtKVxuICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICBtZXRob2Q6IFtcIkdFVFwiLCBcIkhFQURcIl0sXG4gICAgICB1cmw6IFwiKlwiLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIC8vIC9hcGksIC9zb25hbXUtdWnripQgNDA0IOq3uOuMgOuhnFxuICAgICAgICBpZiAocmVxdWVzdC51cmwuc3RhcnRzV2l0aChcIi9hcGlcIikgfHwgcmVxdWVzdC51cmwuc3RhcnRzV2l0aChcIi9zb25hbXUtdWlcIikpIHtcbiAgICAgICAgICByZXBseS5zdGF0dXMoNDA0KS5zZW5kKCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ1NS7JqpIENhY2hlLUNvbnRyb2wg7Zek642UIOyEpOyglVxuICAgICAgICBpZiAoY29uZmlnLmNhY2hlQ29udHJvbEhhbmRsZXIpIHtcbiAgICAgICAgICBjb25zdCBjc3JDYWNoZVJlcTogQ2FjaGVDb250cm9sUmVxdWVzdCA9IHtcbiAgICAgICAgICAgIHR5cGU6IFwiY3NyXCIsXG4gICAgICAgICAgICB1cmw6IHJlcXVlc3QudXJsLFxuICAgICAgICAgICAgcGF0aDogcmVxdWVzdC51cmwuc3BsaXQoXCI/XCIpWzBdLFxuICAgICAgICAgICAgbWV0aG9kOiByZXF1ZXN0Lm1ldGhvZCxcbiAgICAgICAgICB9O1xuICAgICAgICAgIGNvbnN0IGNzckNhY2hlQ29uZmlnID0gY29uZmlnLmNhY2hlQ29udHJvbEhhbmRsZXIoY3NyQ2FjaGVSZXEpO1xuXG4gICAgICAgICAgaWYgKGNzckNhY2hlQ29uZmlnKSB7XG4gICAgICAgICAgICBhcHBseUNhY2hlSGVhZGVycyhyZXBseSwgY3NyQ2FjaGVDb25maWcpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOygleyggSDtjIzsnbzsnbQg7KG07J6s7ZWgIOqyveyasCwg7KCV7KCBIO2MjOydvOydhCDrqLzsoIAg7ISc67mZ7ZW07JW87ZWoXG4gICAgICAgIGNvbnN0IHJlcXVlc3RQYXRoID0gdGhpcy5nZXRQYXRobmFtZUZyb21VcmwocmVxdWVzdC51cmwpO1xuICAgICAgICBjb25zdCBzYWZlRmlsZVBhdGggPSB0aGlzLnJlc29sdmVQYXRoV2l0aGluQmFzZURpcih3ZWJEaXN0UGF0aCwgcmVxdWVzdFBhdGgpO1xuICAgICAgICBpZiAoc2FmZUZpbGVQYXRoID09PSBudWxsKSB7XG4gICAgICAgICAgcmVwbHkuc3RhdHVzKDQwMykuc2VuZCgpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYXdhaXQgZmlsZUV4aXN0cyhzYWZlRmlsZVBhdGgpKSB7XG4gICAgICAgICAgY29uc3QgY29udGVudCA9IGF3YWl0IGZzLnJlYWRGaWxlKHNhZmVGaWxlUGF0aCk7XG4gICAgICAgICAgcmV0dXJuIHJlcGx5LnR5cGUobWltZUxvb2t1cChzYWZlRmlsZVBhdGgpIHx8IFwiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtXCIpLnNlbmQoY29udGVudCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDU1IgZmFsbGJhY2s6IGluZGV4Lmh0bWwg7ISc67mZXG4gICAgICAgIGNvbnN0IGluZGV4UGF0aCA9IHBhdGguam9pbih3ZWJEaXN0UGF0aCwgXCJpbmRleC5odG1sXCIpO1xuICAgICAgICByZXR1cm4gcmVwbHkudHlwZShcInRleHQvaHRtbFwiKS5zZW5kKGF3YWl0IGZzLnJlYWRGaWxlKGluZGV4UGF0aCwgXCJ1dGYtOFwiKSk7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc29sZS5sb2coYOKckyBTdGF0aWMgd2ViIHNlcnZlciBjb25maWd1cmVkIHdpdGggJHtzc3JBdmFpbGFibGUgPyBcIlNTUlwiIDogXCJDU1Igb25seVwifSBzdXBwb3J0YCk7XG4gIH1cblxuICBjcmVhdGVBcGlIYW5kbGVyKFxuICAgIGFwaTogRXh0ZW5kZWRBcGksXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICApOiAocmVxdWVzdDogRmFzdGlmeVJlcXVlc3QsIHJlcGx5OiBGYXN0aWZ5UmVwbHkpID0+IFByb21pc2U8dW5rbm93bj4ge1xuICAgIHJldHVybiBhc3luYyAocmVxdWVzdDogRmFzdGlmeVJlcXVlc3QsIHJlcGx5OiBGYXN0aWZ5UmVwbHkpOiBQcm9taXNlPHVua25vd24+ID0+IHtcbiAgICAgIC8vIENvbnRleHQg7IOd7ISxXG4gICAgICBjb25zdCBjb250ZXh0OiBDb250ZXh0ID0gYXdhaXQgdGhpcy5jcmVhdGVDb250ZXh0KGNvbmZpZywgcmVxdWVzdCwgcmVwbHkpO1xuXG4gICAgICByZXR1cm4gdGhpcy5hc3luY0xvY2FsU3RvcmFnZS5ydW4oeyBjb250ZXh0IH0sIGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8gZ3VhcmRzIOyymOumrFxuICAgICAgICBydW5HdWFyZHMoe1xuICAgICAgICAgIGd1YXJkczogYXBpLm9wdGlvbnMuZ3VhcmRzLFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgIGFwaSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8g7YyM652866+47YSwIOygleuztOuhnCB6b2Qg7Iqk7YKk66eIIOu5jOuTnFxuICAgICAgICBjb25zdCB7IGdldFpvZE9iamVjdEZyb21BcGkgfSA9IGF3YWl0IGltcG9ydChcIi4vY29kZS1jb252ZXJ0ZXJzXCIpO1xuICAgICAgICBjb25zdCBSZXFUeXBlID0gZ2V0Wm9kT2JqZWN0RnJvbUFwaShhcGksIHRoaXMuc3luY2VyLnR5cGVzKTtcblxuICAgICAgICAvLyByZXF1ZXN0IO2MjOyLsVxuICAgICAgICBjb25zdCB3aGljaCA9IGFwaS5vcHRpb25zLmh0dHBNZXRob2QgPT09IFwiR0VUXCIgPyBcInF1ZXJ5XCIgOiBcImJvZHlcIjtcbiAgICAgICAgbGV0IHJlcUJvZHk6IHtcbiAgICAgICAgICBba2V5OiBzdHJpbmddOiB1bmtub3duO1xuICAgICAgICB9O1xuICAgICAgICAvLyDtjIzsnbwg7JeF66Gc65OcIOyeiOuKlCDqsr3smrAg7J6E7IucIOuNsOydtO2EsFxuICAgICAgICBjb25zdCBmaWxlczoge1xuICAgICAgICAgIGJ1ZmZlcmVkRmlsZXM6IEJ1ZmZlcmVkRmlsZVtdO1xuICAgICAgICAgIHVwbG9hZGVkRmlsZXM6IFVwbG9hZGVkRmlsZVtdO1xuICAgICAgICB9ID0ge1xuICAgICAgICAgIGJ1ZmZlcmVkRmlsZXM6IFtdLFxuICAgICAgICAgIHVwbG9hZGVkRmlsZXM6IFtdLFxuICAgICAgICB9O1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgYm9keSA9IChyZXF1ZXN0W3doaWNoXSA/PyB7fSkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICAgICAgaWYgKGFwaS51cGxvYWRPcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJ0cyA9IHJlcXVlc3QucGFydHMoe1xuICAgICAgICAgICAgICBsaW1pdHM6IGFwaS51cGxvYWRPcHRpb25zLmxpbWl0cyxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBGb3JtRGF0YeydmCBmaWVsZOuTpOydhCDsnoTsi5zroZwg7KCA7J6lXG4gICAgICAgICAgICBjb25zdCBmaWVsZHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICAgICAgICAgICAgaWYgKGFwaS51cGxvYWRPcHRpb25zLmNvbnN1bWUgPT09IFwiYnVmZmVyXCIgfHwgIWFwaS51cGxvYWRPcHRpb25zLmNvbnN1bWUpIHtcbiAgICAgICAgICAgICAgLy8gQnVmZmVyIOuqqOuTnDog66mU66qo66as7JeQIOuhnOuTnFxuICAgICAgICAgICAgICBmb3IgYXdhaXQgKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcbiAgICAgICAgICAgICAgICBpZiAocGFydC50eXBlID09PSBcImZpbGVcIikge1xuICAgICAgICAgICAgICAgICAgLy8gQ1JJVElDQUw6IO2MjOydvCDsiqTtirjrprzsnYQg7KaJ7IucIGNvbnN1bWXtlbTslbwg64uk7J2MIHBhcnTroZwg64SY7Ja06rCIIOyImCDsnojsnYxcbiAgICAgICAgICAgICAgICAgIC8vIOydtCDtmLjstpzsnbQg7JeG7Jy866m0IOyiheyihSBtdWx0aXBhcnQg7YyM7Iux7J20IHBlbmRpbmcg7IOB7YOc66GcIO2DgOyehOyVhOybgyDrsJzsg51cbiAgICAgICAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IGF3YWl0IHBhcnQudG9CdWZmZXIoKTtcbiAgICAgICAgICAgICAgICAgIGZpbGVzLmJ1ZmZlcmVkRmlsZXMucHVzaChuZXcgQnVmZmVyZWRGaWxlKHBhcnQsIGJ1ZmZlcikpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocGFydC50eXBlID09PSBcImZpZWxkXCIpIHtcbiAgICAgICAgICAgICAgICAgIGZpZWxkc1twYXJ0LmZpZWxkbmFtZV0gPSBTdHJpbmcocGFydC52YWx1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGFwaS51cGxvYWRPcHRpb25zLmNvbnN1bWUgPT09IFwic3RyZWFtXCIpIHtcbiAgICAgICAgICAgICAgLy8gU3RyZWFtIOuqqOuTnDog7KaJ7IucIOyggOyepeyGjOuhnCDsiqTtirjrpqzrsI1cbiAgICAgICAgICAgICAgY29uc3QgZGlza05hbWUgPSBhcGkudXBsb2FkT3B0aW9ucy5kZXN0aW5hdGlvbjtcbiAgICAgICAgICAgICAgY29uc3QgZGlzayA9IHRoaXMuc3RvcmFnZS51c2UoZGlza05hbWUpO1xuXG4gICAgICAgICAgICAgIC8vIOyasOyEoOyInOychDog642w7L2U66CI7J207YSwID4g7KCE7JetIOyEpOyglSA+IOq4sOuzuOqwklxuICAgICAgICAgICAgICBjb25zdCBrZXlHZW5lcmF0b3I6IEtleUdlbmVyYXRvciA9XG4gICAgICAgICAgICAgICAgYXBpLnVwbG9hZE9wdGlvbnMua2V5R2VuZXJhdG9yID8/XG4gICAgICAgICAgICAgICAgdGhpcy5jb25maWcuc2VydmVyLnN0b3JhZ2U/LmtleUdlbmVyYXRvciA/P1xuICAgICAgICAgICAgICAgIGRlZmF1bHRLZXlHZW5lcmF0b3I7XG5cbiAgICAgICAgICAgICAgZm9yIGF3YWl0IChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHBhcnQudHlwZSA9PT0gXCJmaWxlXCIpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGtleSA9IGF3YWl0IGtleUdlbmVyYXRvcih7XG4gICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBwYXJ0LmZpbGVuYW1lLFxuICAgICAgICAgICAgICAgICAgICBtaW1ldHlwZTogcGFydC5taW1ldHlwZSxcbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICBhd2FpdCBkaXNrLnB1dFN0cmVhbShrZXksIHBhcnQuZmlsZSwge1xuICAgICAgICAgICAgICAgICAgICBjb250ZW50VHlwZTogcGFydC5taW1ldHlwZSxcbiAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICBjb25zdCB1cmwgPSBhd2FpdCBkaXNrLmdldFVybChrZXkpO1xuICAgICAgICAgICAgICAgICAgY29uc3Qgc2lnbmVkVXJsID0gYXdhaXQgZGlzay5nZXRTaWduZWRVcmwoa2V5KTtcblxuICAgICAgICAgICAgICAgICAgZmlsZXMudXBsb2FkZWRGaWxlcy5wdXNoKFxuICAgICAgICAgICAgICAgICAgICBuZXcgVXBsb2FkZWRGaWxlKHtcbiAgICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZTogcGFydC5maWxlbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICBtaW1ldHlwZTogcGFydC5taW1ldHlwZSxcbiAgICAgICAgICAgICAgICAgICAgICBzaXplOiBwYXJ0LmZpbGUuYnl0ZXNSZWFkLFxuICAgICAgICAgICAgICAgICAgICAgIHVybCxcbiAgICAgICAgICAgICAgICAgICAgICBzaWduZWRVcmwsXG4gICAgICAgICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgICAgICAgIGRpc2tOYW1lLFxuICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJ0LnR5cGUgPT09IFwiZmllbGRcIikge1xuICAgICAgICAgICAgICAgICAgZmllbGRzW3BhcnQuZmllbGRuYW1lXSA9IFN0cmluZyhwYXJ0LnZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gcXProZwg7KSR7LKpIOq1rOyhsCDtjIzsi7E6IHBhcmFtc1tjYXRlZ29yeV0g4oaSIHsgcGFyYW1zOiB7IGNhdGVnb3J5OiBcInRlc3RcIiB9IH1cbiAgICAgICAgICAgIGNvbnN0IHFzID0gYXdhaXQgaW1wb3J0KFwicXNcIik7XG4gICAgICAgICAgICBjb25zdCBwYXJzZWQgPSBxcy5kZWZhdWx0LnBhcnNlKGZpZWxkcyk7XG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKGJvZHksIHBhcnNlZCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgeyBmYXN0aWZ5Q2FzdGVyIH0gPSBhd2FpdCBpbXBvcnQoXCIuL2Nhc3RlclwiKTtcbiAgICAgICAgICByZXFCb2R5ID0gZmFzdGlmeUNhc3RlcihSZXFUeXBlKS5wYXJzZShib2R5KTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGNvbnN0IHsgWm9kRXJyb3IgfSA9IGF3YWl0IGltcG9ydChcInpvZFwiKTtcbiAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFpvZEVycm9yKSB7XG4gICAgICAgICAgICBjb25zdCB7IGh1bWFuaXplWm9kRXJyb3IgfSA9IGF3YWl0IGltcG9ydChcIi4uL3V0aWxzL3pvZC1lcnJvclwiKTtcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2VzID0gaHVtYW5pemVab2RFcnJvcihlKVxuICAgICAgICAgICAgICAubWFwKChpc3N1ZSkgPT4gaXNzdWUubWVzc2FnZSlcbiAgICAgICAgICAgICAgLmpvaW4oXCIgXCIpO1xuICAgICAgICAgICAgY29uc3QgeyBCYWRSZXF1ZXN0RXhjZXB0aW9uIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9leGNlcHRpb25zL3NvLWV4Y2VwdGlvbnNcIik7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihtZXNzYWdlcyBhcyBMb2NhbGl6ZWRTdHJpbmcsIHtcbiAgICAgICAgICAgICAgem9kRXJyb3I6IGUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDb250ZW50LVR5cGVcbiAgICAgICAgcmVwbHkudHlwZShhcGkub3B0aW9ucy5jb250ZW50VHlwZSA/PyBcImFwcGxpY2F0aW9uL2pzb25cIik7XG5cbiAgICAgICAgLy8gQ2FjaGUtQ29udHJvbCDtl6TrjZQg7ISk7KCVXG4gICAgICAgIGNvbnN0IGFwaUNhY2hlQ29uZmlnID0gdGhpcy5nZXRBcGlDYWNoZUNvbnRyb2woYXBpLCByZXF1ZXN0LCBjb25maWcpO1xuICAgICAgICBpZiAoYXBpQ2FjaGVDb25maWcpIHtcbiAgICAgICAgICBhcHBseUNhY2hlSGVhZGVycyhyZXBseSwgYXBpQ2FjaGVDb25maWcpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8g7JeF66Gc65OcIOyYteyFmOydtCDsnojripQg6rK97JqwIO2MjOydvCDrjbDsnbTthLDrpbwgQ29udGV4dOyXkCDstpTqsIBcbiAgICAgICAgaWYgKGFwaS51cGxvYWRPcHRpb25zKSB7XG4gICAgICAgICAgY29uc3QgY29uc3VtZSA9IGFwaS51cGxvYWRPcHRpb25zLmNvbnN1bWUgPz8gXCJidWZmZXJcIjtcbiAgICAgICAgICBpZiAoY29uc3VtZSA9PT0gXCJidWZmZXJcIikge1xuICAgICAgICAgICAgY29udGV4dC5idWZmZXJlZEZpbGVzID0gZmlsZXMuYnVmZmVyZWRGaWxlcztcbiAgICAgICAgICB9IGVsc2UgaWYgKGNvbnN1bWUgPT09IFwic3RyZWFtXCIpIHtcbiAgICAgICAgICAgIGNvbnRleHQudXBsb2FkZWRGaWxlcyA9IGZpbGVzLnVwbG9hZGVkRmlsZXM7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8g66qo6424IOuplOyGjOuTnCBhcmdzIOyDneyEse2VmOyXrCDtmLjstpxcbiAgICAgICAgY29uc3QgeyBBcGlQYXJhbVR5cGUgfSA9IGF3YWl0IGltcG9ydChcIi4uL3R5cGVzL3R5cGVzXCIpO1xuICAgICAgICBjb25zdCBhcmdzID0gYXBpLnBhcmFtZXRlcnMubWFwKChwYXJhbSkgPT4ge1xuICAgICAgICAgIC8vIENvbnRleHQg7J247KCd7IWYXG4gICAgICAgICAgaWYgKEFwaVBhcmFtVHlwZS5pc0NvbnRleHQocGFyYW0udHlwZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBjb250ZXh0O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gcmVxQm9keVtwYXJhbS5uYW1lXTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmludm9rZU1vZGVsTWV0aG9kKGFwaSwgYXJncywgcmVwbHkpO1xuICAgICAgfSk7XG4gICAgfTtcbiAgfVxuXG4gIC8vIFdTIHBhdGjrpbwg7J2867CYIEhUVFAgR0VU7Jy866GcIO2YuOy2nO2VnCDqsr3smrAgNDI2ICsgVXBncmFkZSDtl6TrjZTroZwg66qF7Iuc7KCB7Jy866GcIHdlYnNvY2tldCDsoJHsho3snYQg7Jyg64+E7ZWoXG4gIHByaXZhdGUgY3JlYXRlV2ViU29ja2V0VXBncmFkZVJlcXVpcmVkSGFuZGxlcigpIHtcbiAgICByZXR1cm4gYXN5bmMgKF9yZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCwgcmVwbHk6IEZhc3RpZnlSZXBseSk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgcmVwbHkuaGVhZGVyKFwiY29ubmVjdGlvblwiLCBcIlVwZ3JhZGVcIikuaGVhZGVyKFwidXBncmFkZVwiLCBcIndlYnNvY2tldFwiKS5zdGF0dXMoNDI2KS5zZW5kKHtcbiAgICAgICAgbWVzc2FnZTogXCJXZWJTb2NrZXQgdXBncmFkZSByZXF1aXJlZFwiLFxuICAgICAgfSk7XG4gICAgfTtcbiAgfVxuXG4gIC8vIGRldiDrqqjrk5zsnZggY2F0Y2gtYWxsIHdzSGFuZGxlcuyXkOyEnCDsi6TsoJwgV1MgQVBJ66GcIOuUlOyKpO2MqOy5mO2VqC4g66ek7Lmt65CY64qUIHJvdXRl6rCAIOyXhuycvOuptCAxMDA466GcIOuLq+ydjFxuICBwcml2YXRlIGFzeW5jIGhhbmRsZURldldlYlNvY2tldFJlcXVlc3QoXG4gICAgc29ja2V0OiBXZWJTb2NrZXQsXG4gICAgcmVxdWVzdDogRmFzdGlmeVJlcXVlc3QsXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBtYXRjaGVkQXBpID0gdGhpcy5maW5kTWF0Y2hlZEFwaShyZXF1ZXN0KTtcbiAgICBpZiAoIW1hdGNoZWRBcGk/LndlYnNvY2tldE9wdGlvbnMpIHtcbiAgICAgIGNvbnN0IHRyYWNlQ29udGV4dCA9IHRoaXMud2Vic29ja2V0UnVudGltZS50ZWxlbWV0cnlDb250cm9sbGVyLmNyZWF0ZUNvbm5lY3Rpb25Db250ZXh0KHtcbiAgICAgICAgaGVhZGVyczogcmVxdWVzdC5oZWFkZXJzLFxuICAgICAgfSk7XG4gICAgICB0aGlzLndlYnNvY2tldFJ1bnRpbWUudGVsZW1ldHJ5Q29udHJvbGxlci5lbWl0KHtcbiAgICAgICAgbmFtZTogXCJ3cy5jb25uZWN0aW9uLnJlamVjdGVkXCIsXG4gICAgICAgIGxldmVsOiBcIndhcm5cIixcbiAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgcmVhc29uOiBcInJvdXRlTm90Rm91bmRcIixcbiAgICAgICAgICBwYXRoOiByZXF1ZXN0LnVybCxcbiAgICAgICAgfSxcbiAgICAgICAgdHJhY2VJZDogdHJhY2VDb250ZXh0LnRyYWNlSWQsXG4gICAgICAgIHNwYW5JZDogdHJhY2VDb250ZXh0LnNwYW5JZCxcbiAgICAgICAgcGFyZW50U3BhbklkOiB0cmFjZUNvbnRleHQucGFyZW50U3BhbklkLFxuICAgICAgICBzYW1wbGVkOiB0cmFjZUNvbnRleHQuc2FtcGxlZCxcbiAgICAgIH0pO1xuICAgICAgc29ja2V0LmNsb3NlKDEwMDgsIFwiV2ViU29ja2V0IHJvdXRlIG5vdCBmb3VuZFwiKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBoYW5kbGVyID0gdGhpcy5jcmVhdGVXZWJTb2NrZXRIYW5kbGVyKG1hdGNoZWRBcGksIGNvbmZpZyk7XG4gICAgYXdhaXQgaGFuZGxlcih7IHNvY2tldCB9LCByZXF1ZXN0KTtcbiAgfVxuXG4gIC8vIFdTIHJvdXRlIO2VuOuTpOufrOydmCDsi6Ttlokg7Iic7ISc66W8IOqzoOygle2VqDpcbiAgLy8gMSkgZ3VhcmTrpbwgY29ubmVjdGlvbiDrk7HroZ0g7J207KCE7JeQIOuPjOugpCDsnbjspp0g7Iuk7YyoIOyLnCDrtoDrtoQg65Ox66GdIOyDge2DnOulvCDrgqjquLDsp4Ag7JWK7J2MXG4gIC8vIDIpIHF1ZXJ5IHBhcmFtIO2MjOyLseuPhCBhY3RpdmF0aW9uIOyghOyXkCDrgZ3rgrQgaGFuZHNoYWtlIOyLpO2MqOqwgCByZWdpc3RyeeyXkCDrhbjstpzrkJjsp4Ag7JWK6rKMIO2VqFxuICAvLyAzKSBgYWN0aXZlOiBmYWxzZWDroZwg66i87KCAIOuTseuhne2VmOqzoCwgY29udGV4dCDspIDruYTqsIAg64Gd64KcIOuSpCBgYWN0aXZhdGUoKWDtlbQg67iM66Gc65Oc7LqQ7Iqk7Yq46rCAIOy0iOq4sO2ZlCDspJHqsIQg7IOB7YOc66W8IOuztOyngCDrqrvtlZjqsowg7ZWoXG4gIC8vIOyXkOufrCDrsJzsg50g7Iuc7JeQ64qUIHJlc29sdmVXZWJTb2NrZXRDbG9zZURlc2NyaXB0b3Ig7KCV7LGF7JeQIOuUsOudvCBjbG9zZSBjb2Rl66W8IOunpO2Vke2VqFxuICBwcml2YXRlIGNyZWF0ZVdlYlNvY2tldEhhbmRsZXIoYXBpOiBFeHRlbmRlZEFwaSwgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnKSB7XG4gICAgcmV0dXJuIGFzeW5jIChcbiAgICAgIGNvbm5lY3Rpb246IHtcbiAgICAgICAgc29ja2V0OiBXZWJTb2NrZXQ7XG4gICAgICB9LFxuICAgICAgcmVxdWVzdDogRmFzdGlmeVJlcXVlc3QsXG4gICAgKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICBjb25zdCBzb2NrZXQgPSBjb25uZWN0aW9uLnNvY2tldDtcbiAgICAgIGxldCB3c0NvbnRleHQ6IFdlYlNvY2tldENvbnRleHQgfCBudWxsID0gbnVsbDtcbiAgICAgIGxldCByYXdXczogUmV0dXJuVHlwZTxXZWJTb2NrZXRSdW50aW1lW1wicmVnaXN0ZXJDb25uZWN0aW9uXCJdPiB8IG51bGwgPSBudWxsO1xuICAgICAgbGV0IHByZVJlZ2lzdGVyUGhhc2U6IFwiZ3VhcmRcIiB8IFwicXVlcnlcIiB8IFwicmVnaXN0ZXJcIiB8IFwiaGFuZGxlclwiID0gXCJndWFyZFwiO1xuICAgICAgbGV0IHRyYWNlQ29udGV4dDogV2ViU29ja2V0VGVsZW1ldHJ5Q29ubmVjdGlvbkNvbnRleHQgPSB7fTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgdHJhY2VDb250ZXh0ID0gdGhpcy53ZWJzb2NrZXRSdW50aW1lLnRlbGVtZXRyeUNvbnRyb2xsZXIuY3JlYXRlQ29ubmVjdGlvbkNvbnRleHQoe1xuICAgICAgICAgIGhlYWRlcnM6IHJlcXVlc3QuaGVhZGVycyxcbiAgICAgICAgfSk7XG4gICAgICAgIHJ1bkd1YXJkcyh7XG4gICAgICAgICAgZ3VhcmRzOiBhcGkub3B0aW9ucy5ndWFyZHMsXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgYXBpLFxuICAgICAgICB9KTtcblxuICAgICAgICBwcmVSZWdpc3RlclBoYXNlID0gXCJxdWVyeVwiO1xuICAgICAgICBjb25zdCByZXFCb2R5ID0gYXdhaXQgdGhpcy5wYXJzZVdlYlNvY2tldFJlcXVlc3RQYXJhbXMoYXBpLCByZXF1ZXN0KTtcbiAgICAgICAgcHJlUmVnaXN0ZXJQaGFzZSA9IFwicmVnaXN0ZXJcIjtcbiAgICAgICAgcmF3V3MgPSB0aGlzLndlYnNvY2tldFJ1bnRpbWUucmVnaXN0ZXJDb25uZWN0aW9uKHNvY2tldCwge1xuICAgICAgICAgIG91dEV2ZW50czogYXBpLndlYnNvY2tldE9wdGlvbnMhLm91dEV2ZW50cyxcbiAgICAgICAgICBpbkV2ZW50czogYXBpLndlYnNvY2tldE9wdGlvbnMhLmluRXZlbnRzLFxuICAgICAgICAgIG5hbWVzcGFjZTogYXBpLndlYnNvY2tldE9wdGlvbnMhLm5hbWVzcGFjZSxcbiAgICAgICAgICBoZWFydGJlYXQ6IGFwaS53ZWJzb2NrZXRPcHRpb25zIS5oZWFydGJlYXQsXG4gICAgICAgICAgYWN0aXZlOiBmYWxzZSxcbiAgICAgICAgICB0cmFjZUlkOiB0cmFjZUNvbnRleHQudHJhY2VJZCxcbiAgICAgICAgICBzcGFuSWQ6IHRyYWNlQ29udGV4dC5zcGFuSWQsXG4gICAgICAgICAgcGFyZW50U3BhbklkOiB0cmFjZUNvbnRleHQucGFyZW50U3BhbklkLFxuICAgICAgICAgIHNhbXBsZWQ6IHRyYWNlQ29udGV4dC5zYW1wbGVkLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBzY29wZWRXcyA9IHRoaXMuY3JlYXRlU2NvcGVkV2ViU29ja2V0Q29ubmVjdGlvbihyYXdXcywgKCkgPT4gd3NDb250ZXh0KTtcbiAgICAgICAgd3NDb250ZXh0ID0gYXdhaXQgdGhpcy5jcmVhdGVXZWJTb2NrZXRDb250ZXh0KGNvbmZpZywgcmVxdWVzdCwgc2NvcGVkV3MpO1xuICAgICAgICB0aGlzLndlYnNvY2tldFJ1bnRpbWUuYWN0aXZhdGVDb25uZWN0aW9uKHJhd1dzLmlkKTtcbiAgICAgICAgcHJlUmVnaXN0ZXJQaGFzZSA9IFwiaGFuZGxlclwiO1xuXG4gICAgICAgIGNvbnN0IHsgQXBpUGFyYW1UeXBlIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi90eXBlcy90eXBlc1wiKTtcbiAgICAgICAgY29uc3QgYXJncyA9IGFwaS5wYXJhbWV0ZXJzLm1hcCgocGFyYW0pID0+IHtcbiAgICAgICAgICBpZiAoQXBpUGFyYW1UeXBlLmlzQ29udGV4dChwYXJhbS50eXBlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHdzQ29udGV4dDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcmVxQm9keVtwYXJhbS5uYW1lXTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5hc3luY0xvY2FsU3RvcmFnZS5ydW4oeyBjb250ZXh0OiB3c0NvbnRleHQgfSwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGF3YWl0IHRoaXMuaW52b2tlTW9kZWxNZXRob2QoYXBpLCBhcmdzKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zdCBjbG9zZURlc2NyaXB0b3IgPSByZXNvbHZlV2ViU29ja2V0Q2xvc2VEZXNjcmlwdG9yKGVycm9yKTtcbiAgICAgICAgaWYgKCFyYXdXcykge1xuICAgICAgICAgIHRoaXMud2Vic29ja2V0UnVudGltZS50ZWxlbWV0cnlDb250cm9sbGVyLmVtaXQoe1xuICAgICAgICAgICAgbmFtZTogXCJ3cy5jb25uZWN0aW9uLnJlamVjdGVkXCIsXG4gICAgICAgICAgICBsZXZlbDogY2xvc2VEZXNjcmlwdG9yLmxvZ0xldmVsID09PSBcIndhcm5cIiA/IFwid2FyblwiIDogXCJlcnJvclwiLFxuICAgICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICAgIHJlYXNvbjogcHJlUmVnaXN0ZXJQaGFzZSxcbiAgICAgICAgICAgICAgY29kZTogY2xvc2VEZXNjcmlwdG9yLmNvZGUsXG4gICAgICAgICAgICAgIHBhdGg6IGFwaS5wYXRoLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRyYWNlSWQ6IHRyYWNlQ29udGV4dC50cmFjZUlkLFxuICAgICAgICAgICAgc3BhbklkOiB0cmFjZUNvbnRleHQuc3BhbklkLFxuICAgICAgICAgICAgcGFyZW50U3BhbklkOiB0cmFjZUNvbnRleHQucGFyZW50U3BhbklkLFxuICAgICAgICAgICAgc2FtcGxlZDogdHJhY2VDb250ZXh0LnNhbXBsZWQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmF3V3MpIHtcbiAgICAgICAgICByYXdXcy5jbG9zZShjbG9zZURlc2NyaXB0b3IuY29kZSwgY2xvc2VEZXNjcmlwdG9yLnJlYXNvbik7XG4gICAgICAgIH0gZWxzZSBpZiAoc29ja2V0LnJlYWR5U3RhdGUgPCAyKSB7XG4gICAgICAgICAgc29ja2V0LmNsb3NlKGNsb3NlRGVzY3JpcHRvci5jb2RlLCBjbG9zZURlc2NyaXB0b3IucmVhc29uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnNlcnZlcj8ubG9nKSB7XG4gICAgICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgICAgIGVycjogZXJyb3IsXG4gICAgICAgICAgICBtb2RlbE5hbWU6IGFwaS5tb2RlbE5hbWUsXG4gICAgICAgICAgICBtZXRob2ROYW1lOiBhcGkubWV0aG9kTmFtZSxcbiAgICAgICAgICAgIHBhdGg6IGFwaS5wYXRoLFxuICAgICAgICAgIH07XG4gICAgICAgICAgaWYgKGNsb3NlRGVzY3JpcHRvci5sb2dMZXZlbCA9PT0gXCJ3YXJuXCIpIHtcbiAgICAgICAgICAgIHRoaXMuc2VydmVyLmxvZy53YXJuKHBheWxvYWQsIGNsb3NlRGVzY3JpcHRvci5yZWFzb24pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNlcnZlci5sb2cuZXJyb3IocGF5bG9hZCwgY2xvc2VEZXNjcmlwdG9yLnJlYXNvbik7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChjbG9zZURlc2NyaXB0b3IubG9nTGV2ZWwgPT09IFwid2FyblwiKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oY2xvc2VEZXNjcmlwdG9yLnJlYXNvbiwgZXJyb3IpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGNsb3NlRGVzY3JpcHRvci5yZWFzb24sIGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLy8gb25NZXNzYWdlL29uQ2xvc2Xsspjrn7wg64uk66W4IHRpY2vsl5DshJwg7Iuk7ZaJ65CY64qUIGNhbGxiYWNr7J2AIEFMUyBjb250ZXh06rCAIOuBiuq4sOuvgOuhnCB3cmFwcGVy7JeQ7IScIGBhc3luY0xvY2FsU3RvcmFnZS5ydW5g7Jy866GcIOuLpOyLnCDqsJDsi7gg67O17JuQ7ZWoXG4gIC8vIHB1Ymxpc2gvam9pbi9sZWF2ZS9zZXRVc2VySWQg6rCZ7J2AIOymieyLnCDsi6TtlokgQVBJ64qUIOuLqOyInCDsnITsnoTrp4wg7ZWY6rOgLCBkZWZlcnJlZCBjYWxsYmFja+yXkOunjCBjb250ZXh0IOuzteybkOydhCDsoIHsmqntlahcbiAgcHJpdmF0ZSBjcmVhdGVTY29wZWRXZWJTb2NrZXRDb25uZWN0aW9uPFxuICAgIFRPdXQgZXh0ZW5kcyBXZWJTb2NrZXRFdmVudE1hcCxcbiAgICBUSW4gZXh0ZW5kcyBXZWJTb2NrZXRFdmVudE1hcCxcbiAgPihcbiAgICB3czogV2ViU29ja2V0Q29ubmVjdGlvbjxUT3V0LCBUSW4+LFxuICAgIGdldENvbnRleHQ6ICgpID0+IFdlYlNvY2tldENvbnRleHQgfCBudWxsLFxuICApOiBXZWJTb2NrZXRDb25uZWN0aW9uPFRPdXQsIFRJbj4ge1xuICAgIGNvbnN0IHRlbGVtZXRyeUNvbnRyb2xsZXIgPSB0aGlzLl93ZWJzb2NrZXRSdW50aW1lPy50ZWxlbWV0cnlDb250cm9sbGVyO1xuICAgIGNvbnN0IHJ1bkluQ29udGV4dCA9IDxUPihjYWxsYmFjazogKCkgPT4gVCk6IFQgPT4ge1xuICAgICAgY29uc3QgY29udGV4dCA9IGdldENvbnRleHQoKTtcbiAgICAgIGlmICghY29udGV4dCkge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuYXN5bmNMb2NhbFN0b3JhZ2UucnVuKHsgY29udGV4dCB9LCBjYWxsYmFjayk7XG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICBnZXQgaWQoKSB7XG4gICAgICAgIHJldHVybiB3cy5pZDtcbiAgICAgIH0sXG4gICAgICBnZXQgbmFtZXNwYWNlKCkge1xuICAgICAgICByZXR1cm4gd3MubmFtZXNwYWNlO1xuICAgICAgfSxcbiAgICAgIGdldCBjbG9zZWQoKSB7XG4gICAgICAgIHJldHVybiB3cy5jbG9zZWQ7XG4gICAgICB9LFxuICAgICAgZ2V0IHVzZXJJZCgpIHtcbiAgICAgICAgcmV0dXJuIHdzLnVzZXJJZDtcbiAgICAgIH0sXG4gICAgICB0cmFuc3BvcnQ6IFwid3NcIixcbiAgICAgIHB1Ymxpc2hVbnR5cGVkKGV2ZW50LCBkYXRhKSB7XG4gICAgICAgIHdzLnB1Ymxpc2hVbnR5cGVkKGV2ZW50LCBkYXRhKTtcbiAgICAgIH0sXG4gICAgICBjbG9zZShjb2RlLCByZWFzb24pIHtcbiAgICAgICAgd3MuY2xvc2UoY29kZSwgcmVhc29uKTtcbiAgICAgIH0sXG4gICAgICBvbkNsb3NlKGNhbGxiYWNrKSB7XG4gICAgICAgIHdzLm9uQ2xvc2UoKCkgPT4gcnVuSW5Db250ZXh0KGNhbGxiYWNrKSk7XG4gICAgICB9LFxuICAgICAgb25NZXNzYWdlKGV2ZW50LCBoYW5kbGVyKSB7XG4gICAgICAgIHdzLm9uTWVzc2FnZShldmVudCwgKGRhdGEsIG1lc3NhZ2VUcmFjZUNvbnRleHQpID0+XG4gICAgICAgICAgcnVuSW5Db250ZXh0KGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50TmFtZSA9IFN0cmluZyhldmVudCk7XG4gICAgICAgICAgICBjb25zdCB0cmFjZUNvbnRleHQgPSBtZXNzYWdlVHJhY2VDb250ZXh0ID8/IGdldFdlYlNvY2tldFRlbGVtZXRyeUNvbnRleHQod3MpO1xuICAgICAgICAgICAgY29uc3Qgc3RhcnRlZEF0ID0gcGVyZm9ybWFuY2Uubm93KCk7XG5cbiAgICAgICAgICAgIHRlbGVtZXRyeUNvbnRyb2xsZXI/LmVtaXQoe1xuICAgICAgICAgICAgICBuYW1lOiBcIndzLmhhbmRsZXIuc3RhcnRlZFwiLFxuICAgICAgICAgICAgICBsZXZlbDogXCJkZWJ1Z1wiLFxuICAgICAgICAgICAgICBjb25uZWN0aW9uSWQ6IHdzLmlkLFxuICAgICAgICAgICAgICBuYW1lc3BhY2U6IHdzLm5hbWVzcGFjZSxcbiAgICAgICAgICAgICAgdXNlcklkOiB3cy51c2VySWQsXG4gICAgICAgICAgICAgIGRldGFpbDogeyBldmVudDogZXZlbnROYW1lIH0sXG4gICAgICAgICAgICAgIC4uLnRyYWNlQ29udGV4dCxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBoYW5kbGVyKGRhdGEsIG1lc3NhZ2VUcmFjZUNvbnRleHQpO1xuICAgICAgICAgICAgICBjb25zdCBkdXJhdGlvbk1zID0gcGVyZm9ybWFuY2Uubm93KCkgLSBzdGFydGVkQXQ7XG4gICAgICAgICAgICAgIHRlbGVtZXRyeUNvbnRyb2xsZXI/LmVtaXQoe1xuICAgICAgICAgICAgICAgIG5hbWU6IFwid3MuaGFuZGxlci5jb21wbGV0ZWRcIixcbiAgICAgICAgICAgICAgICBsZXZlbDogXCJkZWJ1Z1wiLFxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25JZDogd3MuaWQsXG4gICAgICAgICAgICAgICAgbmFtZXNwYWNlOiB3cy5uYW1lc3BhY2UsXG4gICAgICAgICAgICAgICAgdXNlcklkOiB3cy51c2VySWQsXG4gICAgICAgICAgICAgICAgZGV0YWlsOiB7IGV2ZW50OiBldmVudE5hbWUgfSxcbiAgICAgICAgICAgICAgICAuLi50cmFjZUNvbnRleHQsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB0ZWxlbWV0cnlDb250cm9sbGVyPy5yZWNvcmRTcGFuKHtcbiAgICAgICAgICAgICAgICBvcGVyYXRpb25OYW1lOiBcIndzLm1lc3NhZ2UucHJvY2Vzc1wiLFxuICAgICAgICAgICAgICAgIGtpbmQ6IFwiaW50ZXJuYWxcIixcbiAgICAgICAgICAgICAgICBkdXJhdGlvbk1zLFxuICAgICAgICAgICAgICAgIHN0YXR1czogXCJ1bnNldFwiLFxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25JZDogd3MuaWQsXG4gICAgICAgICAgICAgICAgbmFtZXNwYWNlOiB3cy5uYW1lc3BhY2UsXG4gICAgICAgICAgICAgICAgdXNlcklkOiB3cy51c2VySWQsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlczogeyBldmVudDogZXZlbnROYW1lIH0sXG4gICAgICAgICAgICAgICAgLi4udHJhY2VDb250ZXh0LFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGR1cmF0aW9uTXMgPSBwZXJmb3JtYW5jZS5ub3coKSAtIHN0YXJ0ZWRBdDtcbiAgICAgICAgICAgICAgdGVsZW1ldHJ5Q29udHJvbGxlcj8uZW1pdCh7XG4gICAgICAgICAgICAgICAgbmFtZTogXCJ3cy5oYW5kbGVyLmZhaWxlZFwiLFxuICAgICAgICAgICAgICAgIGxldmVsOiBcImVycm9yXCIsXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbklkOiB3cy5pZCxcbiAgICAgICAgICAgICAgICBuYW1lc3BhY2U6IHdzLm5hbWVzcGFjZSxcbiAgICAgICAgICAgICAgICB1c2VySWQ6IHdzLnVzZXJJZCxcbiAgICAgICAgICAgICAgICBkZXRhaWw6IHsgZXZlbnQ6IGV2ZW50TmFtZSB9LFxuICAgICAgICAgICAgICAgIC4uLnRyYWNlQ29udGV4dCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHRlbGVtZXRyeUNvbnRyb2xsZXI/LnJlY29yZFNwYW4oe1xuICAgICAgICAgICAgICAgIG9wZXJhdGlvbk5hbWU6IFwid3MubWVzc2FnZS5wcm9jZXNzXCIsXG4gICAgICAgICAgICAgICAga2luZDogXCJpbnRlcm5hbFwiLFxuICAgICAgICAgICAgICAgIGR1cmF0aW9uTXMsXG4gICAgICAgICAgICAgICAgc3RhdHVzOiBcImVycm9yXCIsXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbklkOiB3cy5pZCxcbiAgICAgICAgICAgICAgICBuYW1lc3BhY2U6IHdzLm5hbWVzcGFjZSxcbiAgICAgICAgICAgICAgICB1c2VySWQ6IHdzLnVzZXJJZCxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7IGV2ZW50OiBldmVudE5hbWUgfSxcbiAgICAgICAgICAgICAgICBlcnJvclR5cGU6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5uYW1lIDogdHlwZW9mIGVycm9yLFxuICAgICAgICAgICAgICAgIC4uLnRyYWNlQ29udGV4dCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgfSxcbiAgICAgIHB1Ymxpc2goZXZlbnQsIGRhdGEpIHtcbiAgICAgICAgd3MucHVibGlzaChldmVudCwgZGF0YSk7XG4gICAgICB9LFxuICAgICAgd2FpdEZvckNsb3NlKCkge1xuICAgICAgICByZXR1cm4gd3Mud2FpdEZvckNsb3NlKCk7XG4gICAgICB9LFxuICAgICAgam9pbihyb29tSWQpIHtcbiAgICAgICAgd3Muam9pbihyb29tSWQpO1xuICAgICAgfSxcbiAgICAgIGxlYXZlKHJvb21JZCkge1xuICAgICAgICB3cy5sZWF2ZShyb29tSWQpO1xuICAgICAgfSxcbiAgICAgIHNldFVzZXJJZCh1c2VySWQpIHtcbiAgICAgICAgd3Muc2V0VXNlcklkKHVzZXJJZCk7XG4gICAgICB9LFxuICAgICAgY2xlYXJVc2VySWQoKSB7XG4gICAgICAgIHdzLmNsZWFyVXNlcklkKCk7XG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHBhcnNlV2ViU29ja2V0UmVxdWVzdFBhcmFtcyhcbiAgICBhcGk6IEV4dGVuZGVkQXBpLFxuICAgIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHVua25vd24+PiB7XG4gICAgY29uc3QgeyBnZXRab2RPYmplY3RGcm9tQXBpIH0gPSBhd2FpdCBpbXBvcnQoXCIuL2NvZGUtY29udmVydGVyc1wiKTtcbiAgICBjb25zdCBSZXFUeXBlID0gZ2V0Wm9kT2JqZWN0RnJvbUFwaShhcGksIHRoaXMuc3luY2VyLnR5cGVzKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IGZhc3RpZnlDYXN0ZXIgfSA9IGF3YWl0IGltcG9ydChcIi4vY2FzdGVyXCIpO1xuICAgICAgcmV0dXJuIGZhc3RpZnlDYXN0ZXIoUmVxVHlwZSkucGFyc2UoKHJlcXVlc3QucXVlcnkgPz8ge30pIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zdCB7IFpvZEVycm9yIH0gPSBhd2FpdCBpbXBvcnQoXCJ6b2RcIik7XG4gICAgICBpZiAoZSBpbnN0YW5jZW9mIFpvZEVycm9yKSB7XG4gICAgICAgIGNvbnN0IHsgaHVtYW5pemVab2RFcnJvciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvem9kLWVycm9yXCIpO1xuICAgICAgICBjb25zdCBtZXNzYWdlcyA9IGh1bWFuaXplWm9kRXJyb3IoZSlcbiAgICAgICAgICAubWFwKChpc3N1ZSkgPT4gaXNzdWUubWVzc2FnZSlcbiAgICAgICAgICAuam9pbihcIiBcIik7XG4gICAgICAgIGNvbnN0IHsgQmFkUmVxdWVzdEV4Y2VwdGlvbiB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vZXhjZXB0aW9ucy9zby1leGNlcHRpb25zXCIpO1xuICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihtZXNzYWdlcyBhcyBMb2NhbGl6ZWRTdHJpbmcsIHtcbiAgICAgICAgICB6b2RFcnJvcjogZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFVSTOyXkOyEnCBwYXRoIHBhcmFtc+ulvCDstpTstpztlanri4jri6QuXG4gICAqIOyYiDogcGF0dGVybj1cIi9hZG1pbi9jb21wYW5pZXMvOmNvbXBhbnlJZFwiLCB1cmw9XCIvYWRtaW4vY29tcGFuaWVzLzEyM1wiIOKGkiB7IGNvbXBhbnlJZDogXCIxMjNcIiB9XG4gICAqL1xuICBwcml2YXRlIGV4dHJhY3RQYXRoUGFyYW1zKHBhdHRlcm46IHN0cmluZywgdXJsOiBzdHJpbmcpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgICBjb25zdCBwYXR0ZXJuUGFydHMgPSBwYXR0ZXJuLnNwbGl0KFwiL1wiKS5maWx0ZXIoQm9vbGVhbik7XG4gICAgY29uc3QgdXJsUGFydHMgPSB0aGlzLmdldFBhdGhuYW1lRnJvbVVybCh1cmwpLnNwbGl0KFwiL1wiKS5maWx0ZXIoQm9vbGVhbik7XG4gICAgY29uc3QgcGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhdHRlcm5QYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHBhdHRlcm5QYXJ0c1tpXS5zdGFydHNXaXRoKFwiOlwiKSkge1xuICAgICAgICBwYXJhbXNbcGF0dGVyblBhcnRzW2ldLnNsaWNlKDEpXSA9IHVybFBhcnRzW2ldO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcGFyYW1zO1xuICB9XG5cbiAgcHJpdmF0ZSBpc1BhdGhQYXR0ZXJuTWF0Y2gocGF0dGVybjogc3RyaW5nLCB1cmw6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHBhdHRlcm5QYXJ0cyA9IHBhdHRlcm4uc3BsaXQoXCIvXCIpLmZpbHRlcihCb29sZWFuKTtcbiAgICBjb25zdCB1cmxQYXJ0cyA9IHRoaXMuZ2V0UGF0aG5hbWVGcm9tVXJsKHVybCkuc3BsaXQoXCIvXCIpLmZpbHRlcihCb29sZWFuKTtcblxuICAgIGlmIChwYXR0ZXJuUGFydHMubGVuZ3RoICE9PSB1cmxQYXJ0cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhdHRlcm5QYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgcGF0dGVyblBhcnQgPSBwYXR0ZXJuUGFydHNbaV07XG4gICAgICBjb25zdCB1cmxQYXJ0ID0gdXJsUGFydHNbaV07XG4gICAgICBpZiAocGF0dGVyblBhcnQuc3RhcnRzV2l0aChcIjpcIikpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAocGF0dGVyblBhcnQgIT09IHVybFBhcnQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRQYXRobmFtZUZyb21VcmwodXJsOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB1cmwuc3BsaXQoXCI/XCIpWzBdO1xuICB9XG5cbiAgcHJpdmF0ZSByZXNvbHZlUGF0aFdpdGhpbkJhc2VEaXIoYmFzZURpcjogc3RyaW5nLCBpbnB1dFBhdGg6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBkZWNvZGVkID0gZGVjb2RlVVJJQ29tcG9uZW50KGlucHV0UGF0aCkucmVwbGFjZSgvXFxcXC9nLCBcIi9cIik7XG4gICAgICBpZiAoZGVjb2RlZC5pbmNsdWRlcyhcIlxcMFwiKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlbGF0aXZlUGF0aCA9IGRlY29kZWQucmVwbGFjZSgvXlxcLysvLCBcIlwiKTtcbiAgICAgIGNvbnN0IHJlc29sdmVkUGF0aCA9IHBhdGgucmVzb2x2ZShiYXNlRGlyLCByZWxhdGl2ZVBhdGgpO1xuICAgICAgY29uc3QgcmVsYXRpdmVGcm9tQmFzZSA9IHBhdGgucmVsYXRpdmUoYmFzZURpciwgcmVzb2x2ZWRQYXRoKTtcbiAgICAgIGlmIChyZWxhdGl2ZUZyb21CYXNlLnN0YXJ0c1dpdGgoXCIuLlwiKSB8fCBwYXRoLmlzQWJzb2x1dGUocmVsYXRpdmVGcm9tQmFzZSkpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzb2x2ZWRQYXRoO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFQSSDsnZHri7Xsl5Ag7KCB7Jqp7ZWgIENhY2hlLUNvbnRyb2wg7ISk7KCV7J2EIOqysOygle2VqeuLiOuLpC5cbiAgICog7Jqw7ISg7Iic7JyEOiDqsJzrs4Qg7KeA7KCVID4gY2FjaGVDb250cm9sSGFuZGxlclxuICAgKi9cbiAgcHJpdmF0ZSBnZXRBcGlDYWNoZUNvbnRyb2woXG4gICAgYXBpOiBFeHRlbmRlZEFwaSxcbiAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICkge1xuICAgIC8vIOuNsOy9lOugiOydtO2EsCDshKTsoJUg7Jqw7ISgXG4gICAgaWYgKGFwaS5vcHRpb25zLmNhY2hlQ29udHJvbCkge1xuICAgICAgcmV0dXJuIGFwaS5vcHRpb25zLmNhY2hlQ29udHJvbDtcbiAgICB9XG5cbiAgICAvLyDsoITsl60g7ZW465Ok65+sXG4gICAgaWYgKGNvbmZpZy5jYWNoZUNvbnRyb2xIYW5kbGVyKSB7XG4gICAgICBjb25zdCBjYWNoZVJlcTogQ2FjaGVDb250cm9sUmVxdWVzdCA9IHtcbiAgICAgICAgdHlwZTogXCJhcGlcIixcbiAgICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgICAgcGF0aDogcmVxdWVzdC5yb3V0ZU9wdGlvbnM/LnVybCA/PyByZXF1ZXN0LnVybC5zcGxpdChcIj9cIilbMF0sXG4gICAgICAgIG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG4gICAgICAgIGFwaSxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXN1bHQgPSBjb25maWcuY2FjaGVDb250cm9sSGFuZGxlcihjYWNoZVJlcSk7XG4gICAgICBpZiAocmVzdWx0KSByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFNTUuyaqSBBUEkg7Zi47LacIChIVFRQIOyYpOuyhO2XpOuTnCDsl4bsnbQg7KeB7KCRIO2YuOy2nClcbiAgICogY3JlYXRlQXBpSGFuZGxlcuydmCDroZzsp4HsnYQg7J6s7IKs7Jqp7ZWY65CYLCByZXF1ZXN0IO2MjOyLsSDrjIDsi6AgcGFyYW1zIOyngeygkSDsgqzsmqlcbiAgICovXG4gIGFzeW5jIGludm9rZUFwaUZvclNTUihcbiAgICBhcGk6IEV4dGVuZGVkQXBpLFxuICAgIHBhcmFtczogYW55W10sXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICAgIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICAgIHJlcGx5OiBGYXN0aWZ5UmVwbHksXG4gICk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgIC8vIENvbnRleHQg7IOd7ISxICjquLDsobQg66mU7IaM65OcIOyerOyCrOyaqSlcbiAgICBjb25zdCBjb250ZXh0ID0gYXdhaXQgdGhpcy5jcmVhdGVDb250ZXh0KGNvbmZpZywgcmVxdWVzdCwgcmVwbHkpO1xuXG4gICAgcmV0dXJuIHRoaXMuYXN5bmNMb2NhbFN0b3JhZ2UucnVuKHsgY29udGV4dCB9LCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyBhcmdzIOyDneyEsTogQ29udGV4dCDtjIzrnbzrr7jthLDripQg7KO87J6FLCDrgpjrqLjsp4DripQgcGFyYW1z7JeQ7IScIOqwgOyguOyYpOq4sFxuICAgICAgY29uc3QgeyBBcGlQYXJhbVR5cGUgfSA9IGF3YWl0IGltcG9ydChcIi4uL3R5cGVzL3R5cGVzXCIpO1xuICAgICAgbGV0IHBhcmFtc0luZGV4ID0gMDtcbiAgICAgIGNvbnN0IGFyZ3MgPSBhcGkucGFyYW1ldGVycy5tYXAoKHBhcmFtKSA9PiB7XG4gICAgICAgIGlmIChBcGlQYXJhbVR5cGUuaXNDb250ZXh0KHBhcmFtLnR5cGUpKSB7XG4gICAgICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhcmFtc1twYXJhbXNJbmRleCsrXTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyDrqqjrjbgg66mU7ISc65OcIO2YuOy2nCAo6riw7KG0IOuplOyEnOuTnCDsnqzsgqzsmqkpXG4gICAgICByZXR1cm4gdGhpcy5pbnZva2VNb2RlbE1ldGhvZChhcGksIGFyZ3MsIHJlcGx5KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFdTIOqyveuhnOyXkOyEnOuKlCBIVFRQIHJlcGx56rCAIOyXhuycvOuvgOuhnCByZXBseeulvCBvcHRpb25hbOuhnCDrsJvslYQg6rO17Ya1IO2YuOy2nCDqsr3roZzrpbwg7Jyg7KeA7ZWoXG4gIGFzeW5jIGludm9rZU1vZGVsTWV0aG9kKFxuICAgIGFwaTogRXh0ZW5kZWRBcGksXG4gICAgYXJnczogdW5rbm93bltdLFxuICAgIHJlcGx5PzogRmFzdGlmeVJlcGx5LFxuICApOiBQcm9taXNlPHVua25vd24+IHtcbiAgICBjb25zdCBtb2RlbCA9IHRoaXMuc3luY2VyLm1vZGVsc1thcGkubW9kZWxOYW1lXTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCAobW9kZWwgYXMgYW55KVthcGkubWV0aG9kTmFtZV0uYXBwbHkobW9kZWwsIGFyZ3MpO1xuICAgIHJlcGx5Py50eXBlKGFwaS5vcHRpb25zLmNvbnRlbnRUeXBlID8/IFwiYXBwbGljYXRpb24vanNvblwiKTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBhc3luYyBjcmVhdGVDb250ZXh0KFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICByZXBseTogRmFzdGlmeVJlcGx5LFxuICApOiBQcm9taXNlPENvbnRleHQ+IHtcbiAgICAvLyBjcmVhdGVTU0VGYWN0b3J5IO2VqOyImOyXkCDrr7jrpqwgcmVxdWVzdOydmCBzb2NrZXTqs7wgcmVwbHnrpbwg67CU7J2465SpLlxuICAgIGNvbnN0IHsgY3JlYXRlU1NFRmFjdG9yeSB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3RyZWFtL3NzZVwiKTtcbiAgICBjb25zdCBjcmVhdGVTU0UgPSAoPFQgZXh0ZW5kcyBab2RPYmplY3Q+KFxuICAgICAgX3JlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICAgICAgX3JlcGx5OiBGYXN0aWZ5UmVwbHksXG4gICAgICBfZXZlbnRzOiBULFxuICAgICkgPT4gY3JlYXRlU1NFRmFjdG9yeShfcmVxdWVzdC5zb2NrZXQsIF9yZXBseSwgX2V2ZW50cykpLmJpbmQobnVsbCwgcmVxdWVzdCwgcmVwbHkpO1xuXG4gICAgLy8gbG9jYWxlIOqwkOyngFxuICAgIGNvbnN0IGxvY2FsZSA9XG4gICAgICB0aGlzLmRldGVjdExvY2FsZShyZXF1ZXN0LmhlYWRlcnNbXCJhY2NlcHQtbGFuZ3VhZ2VcIl0sIHRoaXMuY29uZmlnLmkxOG4uc3VwcG9ydGVkTG9jYWxlcykgPz9cbiAgICAgIHRoaXMuY29uZmlnLmkxOG4uZGVmYXVsdExvY2FsZTtcblxuICAgIC8vIGF1dGggY29udGV4dCDstpTqsIBcbiAgICBjb25zdCBoZWFkZXJzID0gY29udmVydEZhc3RpZnlIZWFkZXJzVG9TdGFuZGFyZChyZXF1ZXN0LmhlYWRlcnMpO1xuICAgIGNvbnN0IHNlc3Npb24gPSAoYXdhaXQgdGhpcy5fYXV0aD8uYXBpLmdldFNlc3Npb24oeyBoZWFkZXJzIH0pKSA/PyBudWxsO1xuXG4gICAgY29uc3QgY29udGV4dDogQ29udGV4dCA9IGF3YWl0IFByb21pc2UucmVzb2x2ZShcbiAgICAgIGNvbmZpZy5jb250ZXh0UHJvdmlkZXIoXG4gICAgICAgIHtcbiAgICAgICAgICB0cmFuc3BvcnQ6IFwiaHR0cFwiLFxuICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgcmVwbHksXG4gICAgICAgICAgaGVhZGVyczogcmVxdWVzdC5oZWFkZXJzLFxuICAgICAgICAgIGNyZWF0ZVNTRSxcbiAgICAgICAgICBuYWl0ZVN0b3JlOiBuZXcgTWFwKCksXG4gICAgICAgICAgbG9jYWxlLFxuICAgICAgICAgIC8vIGF1dGhcbiAgICAgICAgICB1c2VyOiBzZXNzaW9uPy51c2VyID8/IG51bGwsXG4gICAgICAgICAgc2Vzc2lvbjogc2Vzc2lvbj8uc2Vzc2lvbiA/PyBudWxsLFxuICAgICAgICB9LFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICByZXBseSxcbiAgICAgICksXG4gICAgKTtcbiAgICByZXR1cm4gY29udGV4dDtcbiAgfVxuXG4gIC8vIHNlc3Npb24vbG9jYWxlL3N0b3JlIOqwmeydgCDqs7XthrUgc3RhdGXripQgSFRUUCBjb250ZXh07JmAIOqzteycoO2VmOuQmCwgcmVwbHkvY3JlYXRlU1NFIOqwmeydgCBIVFRQIOyghOyaqSBoZWxwZXLripQg64W47Lac7ZWY7KeAIOyViuydjFxuICAvLyDsgqzsmqnsnpDqsIAgd2Vic29ja2V0Q29udGV4dFByb3ZpZGVy66W8IOyjvOuptCDqt7jrjIDroZwg7JyE7J6E7ZWY6rOgLCDsl4bsnLzrqbQg6riw7KG0IGNvbnRleHRQcm92aWRlcuulvCByZXBseS9TU0Ugc3R1YuqzvCDtlajqu5gg7J6s7Zmc7Jqp7ZWoXG4gIGFzeW5jIGNyZWF0ZVdlYlNvY2tldENvbnRleHQoXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICAgIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICAgIHdzOiBXZWJTb2NrZXRDb250ZXh0W1wid3NcIl0sXG4gICk6IFByb21pc2U8V2ViU29ja2V0Q29udGV4dD4ge1xuICAgIGNvbnN0IGxvY2FsZSA9XG4gICAgICB0aGlzLmRldGVjdExvY2FsZShyZXF1ZXN0LmhlYWRlcnNbXCJhY2NlcHQtbGFuZ3VhZ2VcIl0sIHRoaXMuY29uZmlnLmkxOG4uc3VwcG9ydGVkTG9jYWxlcykgPz9cbiAgICAgIHRoaXMuY29uZmlnLmkxOG4uZGVmYXVsdExvY2FsZTtcblxuICAgIGNvbnN0IGhlYWRlcnMgPSBjb252ZXJ0RmFzdGlmeUhlYWRlcnNUb1N0YW5kYXJkKHJlcXVlc3QuaGVhZGVycyk7XG4gICAgY29uc3Qgc2Vzc2lvbiA9IChhd2FpdCB0aGlzLl9hdXRoPy5hcGkuZ2V0U2Vzc2lvbih7IGhlYWRlcnMgfSkpID8/IG51bGw7XG5cbiAgICBjb25zdCBkZWZhdWx0Q29udGV4dCA9IHtcbiAgICAgIHRyYW5zcG9ydDogXCJ3c1wiIGFzIGNvbnN0LFxuICAgICAgcmVxdWVzdCxcbiAgICAgIGhlYWRlcnM6IHJlcXVlc3QuaGVhZGVycyxcbiAgICAgIHdzLFxuICAgICAgbmFpdGVTdG9yZTogbmV3IE1hcCgpLFxuICAgICAgbG9jYWxlLFxuICAgICAgdXNlcjogc2Vzc2lvbj8udXNlciA/PyBudWxsLFxuICAgICAgc2Vzc2lvbjogc2Vzc2lvbj8uc2Vzc2lvbiA/PyBudWxsLFxuICAgIH07XG5cbiAgICBpZiAoY29uZmlnLndlYnNvY2tldENvbnRleHRQcm92aWRlcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uKGF3YWl0IFByb21pc2UucmVzb2x2ZShjb25maWcud2Vic29ja2V0Q29udGV4dFByb3ZpZGVyKGRlZmF1bHRDb250ZXh0LCByZXF1ZXN0KSkpLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyByZXBseS9jcmVhdGVTU0Xsl5Ag7J2Y7KG07ZWY64qUIGNvbnRleHRQcm92aWRlcuqwgCDsnojsnLzrqbQg7KaJ7IucIOyXkOufrOulvCDrjZjsoLggdHJhbnNwb3J0IG1pc3VzZeulvCDruajrpqwg65Oc65+s64OEXG4gICAgY29uc3QgcmVwbHlTdHViID0gY3JlYXRlV2ViU29ja2V0UmVwbHlTdHViKCk7XG4gICAgY29uc3QgY3JlYXRlU1NFID0gPFQgZXh0ZW5kcyBab2RPYmplY3Q+KF9ldmVudHM6IFQpID0+IHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJjcmVhdGVTU0UgaXMgbm90IGF2YWlsYWJsZSBpbiB3ZWJzb2NrZXQgY29udGV4dC4gRGVmaW5lIHdlYnNvY2tldENvbnRleHRQcm92aWRlciBpZiB5b3VyIGNvbnRleHQgc2V0dXAgZGVwZW5kcyBvbiBTU0UgaGVscGVycy5cIixcbiAgICAgICk7XG4gICAgfTtcbiAgICBjb25zdCBodHRwTGlrZUNvbnRleHQgPSBhd2FpdCBQcm9taXNlLnJlc29sdmUoXG4gICAgICBjb25maWcuY29udGV4dFByb3ZpZGVyKFxuICAgICAgICB7XG4gICAgICAgICAgdHJhbnNwb3J0OiBcImh0dHBcIixcbiAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgIHJlcGx5OiByZXBseVN0dWIsXG4gICAgICAgICAgaGVhZGVyczogcmVxdWVzdC5oZWFkZXJzLFxuICAgICAgICAgIGNyZWF0ZVNTRSxcbiAgICAgICAgICBuYWl0ZVN0b3JlOiBkZWZhdWx0Q29udGV4dC5uYWl0ZVN0b3JlLFxuICAgICAgICAgIGxvY2FsZSxcbiAgICAgICAgICB1c2VyOiBkZWZhdWx0Q29udGV4dC51c2VyLFxuICAgICAgICAgIHNlc3Npb246IGRlZmF1bHRDb250ZXh0LnNlc3Npb24sXG4gICAgICAgIH0sXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIHJlcGx5U3R1YixcbiAgICAgICksXG4gICAgKTtcblxuICAgIGNvbnN0IHtcbiAgICAgIHRyYW5zcG9ydDogX3RyYW5zcG9ydCxcbiAgICAgIHJlcGx5OiBfcmVwbHksXG4gICAgICBjcmVhdGVTU0U6IF9jcmVhdGVTU0UsXG4gICAgICBidWZmZXJlZEZpbGVzOiBfYnVmZmVyZWRGaWxlcyxcbiAgICAgIHVwbG9hZGVkRmlsZXM6IF91cGxvYWRlZEZpbGVzLFxuICAgICAgLi4ucmVzdFxuICAgIH0gPSBodHRwTGlrZUNvbnRleHQ7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4ucmVzdCxcbiAgICAgIHRyYW5zcG9ydDogXCJ3c1wiLFxuICAgICAgcmVxdWVzdCxcbiAgICAgIGhlYWRlcnM6IHJlcXVlc3QuaGVhZGVycyxcbiAgICAgIHdzLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQWNjZXB0LUxhbmd1YWdlIO2XpOuNlOyXkOyEnCDsp4Dsm5DtlZjripQgbG9jYWxl7J2EIOywvuyKteuLiOuLpC5cbiAgICogQGV4YW1wbGUgXCJrby1LUixrbztxPTAuOSxlbjtxPTAuOFwiIOKGkiBcImtvXCJcbiAgICovXG4gIHByaXZhdGUgZGV0ZWN0TG9jYWxlKFxuICAgIGFjY2VwdExhbmd1YWdlOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgc3VwcG9ydGVkOiBzdHJpbmdbXSxcbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIWFjY2VwdExhbmd1YWdlKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgLy8gQWNjZXB0LUxhbmd1YWdlOiBrby1LUixrbztxPTAuOSxlbjtxPTAuOFxuICAgIGNvbnN0IGxhbmdzID0gYWNjZXB0TGFuZ3VhZ2Uuc3BsaXQoXCIsXCIpLm1hcCgobGFuZykgPT4ge1xuICAgICAgY29uc3QgW2NvZGVdID0gbGFuZy5zcGxpdChcIjtcIik7XG4gICAgICByZXR1cm4gY29kZS50cmltKCkuc3BsaXQoXCItXCIpWzBdOyAvLyBrby1LUiDihpIga29cbiAgICB9KTtcblxuICAgIHJldHVybiBsYW5ncy5maW5kKChsYW5nKSA9PiBzdXBwb3J0ZWQuaW5jbHVkZXMobGFuZykpO1xuICB9XG5cbiAgYXN5bmMgc3RhcnRXYXRjaGVyKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIHdhdGNoZXIg66qo65OI7J2AIGZpbGUtcGF0dGVybnMg4oaSIFNvbmFtdSDsiJztmZjsnYQg7ZS87ZWY6riwIOychO2VtCBkeW5hbWljIGltcG9ydCDtlanri4jri6QuXG4gICAgY29uc3QgeyBzZXR1cFdhdGNoZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL3N5bmNlci93YXRjaGVyXCIpO1xuICAgIHRoaXMud2F0Y2hlciA9IGF3YWl0IHNldHVwV2F0Y2hlcigoZmlsZUV2ZW50cykgPT4gdGhpcy5ydW5IbXJTeW5jQ3ljbGUoZmlsZUV2ZW50cykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFdhdGNoZXLqsIAgMTAwbXMgYmF0Y2jroZwg66qo7J2AIGZpbGVFdmVudHMg7ZWY64KY7JeQIOuMgO2VtCDtlZwg67KI7J2YIEhNUi9zeW5jIOyCrOydtO2BtOydhCDrj5Xri4jri6QuXG4gICAqIGJhdGNoIO2BkOyeiSDrjZXsl5Ag7ZWcIOyLnOygkOyXkCDtlZjrgpjrp4wg7Iuk7ZaJ65Co7J20IOuztOyepeuQqeuLiOuLpCAoZXZlbnQtYmF0Y2hlcuqwgCDsp4HroKztmZQpLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBydW5IbXJTeW5jQ3ljbGUoZmlsZUV2ZW50czogTWFwPEFic29sdXRlUGF0aCwgXCJjaGFuZ2VcIiB8IFwiYWRkXCI+KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgc3RhcnRlZEF0ID0gRGF0ZS5ub3coKTtcblxuICAgIGZvciAoY29uc3QgW2ZpbGVQYXRoLCBldmVudF0gb2YgZmlsZUV2ZW50cykge1xuICAgICAgY29uc3QgcmVsYXRpdmVQYXRoID0gcGF0aC5yZWxhdGl2ZSh0aGlzLmFwcFJvb3RQYXRoLCBmaWxlUGF0aCk7XG4gICAgICBjb25zb2xlLmxvZyhjaGFsay5ib2xkKGBEZXRlY3RlZCgke2V2ZW50fSk6ICR7Y2hhbGsuYmx1ZShyZWxhdGl2ZVBhdGgpfWApKTtcbiAgICB9XG5cbiAgICAvLyDrs7jssrQ6IOuzgOqyvSDtnaHsiJggKyDssrTtgazshKwg6rCx7IugLlxuICAgIGF3YWl0IHRoaXMuc3luY2VyLmhtckFuZFN5bmMoZmlsZUV2ZW50cyk7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIucmVuZXdDaGVja3N1bXMoKTtcblxuICAgIGNvbnN0IHRvdGFsVGltZSA9IERhdGUubm93KCkgLSBzdGFydGVkQXQ7XG4gICAgY29uc3QgbXNnID0gYEhNUiBEb25lISAke2NoYWxrLmJvbGQud2hpdGUoYCR7dG90YWxUaW1lfW1zYCl9YDtcbiAgICBjb25zb2xlLmxvZyhjaGFsay5ibGFjay5iZ0dyZWVuKGNlbnRlclRleHQobXNnKSkpO1xuICB9XG5cbiAgLypcbiAgICAgQSBmdW5jdGlvbiB0aGF0IGF1dG9tYXRpY2FsbHkgaGFuZGxlcyBpbml0IGFuZCBkZXN0cm95IHdoZW4gdXNpbmcgU29uYW11IHZpYSBzY3JpcHRzLlxuICAqL1xuICBhc3luYyBydW5TY3JpcHQoZm46ICgpID0+IFByb21pc2U8dm9pZD4pIHtcbiAgICBhd2FpdCB0aGlzLmluaXQodHJ1ZSwgZmFsc2UsIHVuZGVmaW5lZCwgZmFsc2UpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBmbigpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCB0aGlzLmRlc3Ryb3koKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlZ2lzdGVyUGx1Z2lucyhzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZSwgcGx1Z2luczogU29uYW11U2VydmVyT3B0aW9uc1tcInBsdWdpbnNcIl0pIHtcbiAgICBpZiAoIXBsdWdpbnMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBjb21wcmVzcyDtlIzrn6zqt7jsnbjsnYAg64uk66W4IO2UjOufrOq3uOyduOuztOuLpCDrqLzsoIAg65Ox66Gd65CY7Ja07JW8IO2VqeuLiOuLpC5cbiAgICBpZiAocGx1Z2lucy5jb21wcmVzcykge1xuICAgICAgY29uc3QgY29tcHJlc3NQbHVnaW4gPSAoYXdhaXQgaW1wb3J0KFwiQGZhc3RpZnkvY29tcHJlc3NcIikpLmRlZmF1bHQ7XG4gICAgICBjb25zdCBkZWZhdWx0T3B0aW9ucyA9IHtcbiAgICAgICAgdGhyZXNob2xkOiAxMDI0LFxuICAgICAgICBlbmNvZGluZ3M6IFtcImJyXCIsIFwiZ3ppcFwiLCBcImRlZmxhdGVcIl0gYXMgKFwiYnJcIiB8IFwiZ3ppcFwiIHwgXCJkZWZsYXRlXCIpW10sXG4gICAgICB9O1xuXG4gICAgICBpZiAocGx1Z2lucy5jb21wcmVzcyA9PT0gdHJ1ZSkge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoY29tcHJlc3NQbHVnaW4sIGRlZmF1bHRPcHRpb25zKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNlcnZlci5yZWdpc3Rlcihjb21wcmVzc1BsdWdpbiwge1xuICAgICAgICAgIC4uLmRlZmF1bHRPcHRpb25zLFxuICAgICAgICAgIC4uLnBsdWdpbnMuY29tcHJlc3MsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHBsdWdpbnNNb2R1bGVzID0ge1xuICAgICAgY29yczogXCJAZmFzdGlmeS9jb3JzXCIsXG4gICAgICBmb3JtYm9keTogXCJAZmFzdGlmeS9mb3JtYm9keVwiLFxuICAgICAgbXVsdGlwYXJ0OiBcIkBmYXN0aWZ5L211bHRpcGFydFwiLFxuICAgICAgcXM6IFwiZmFzdGlmeS1xc1wiLFxuICAgICAgc3NlOiBcImZhc3RpZnktc3NlLXYyXCIsXG4gICAgICBzdGF0aWM6IFwiQGZhc3RpZnkvc3RhdGljXCIsXG4gICAgfSBhcyBjb25zdDtcblxuICAgIGNvbnN0IHJlZ2lzdGVyUGx1Z2luID0gYXN5bmMgPEsgZXh0ZW5kcyBrZXlvZiBOb25OdWxsYWJsZTx0eXBlb2YgcGx1Z2lucz4+KFxuICAgICAga2V5OiBLLFxuICAgICAgcGx1Z2luTmFtZTogc3RyaW5nLFxuICAgICkgPT4ge1xuICAgICAgY29uc3Qgb3B0aW9uID0gcGx1Z2luc1trZXldO1xuICAgICAgaWYgKCFvcHRpb24pIHJldHVybjtcblxuICAgICAgaWYgKG9wdGlvbiA9PT0gdHJ1ZSkge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoKGF3YWl0IGltcG9ydChwbHVnaW5OYW1lKSkuZGVmYXVsdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoKGF3YWl0IGltcG9ydChwbHVnaW5OYW1lKSkuZGVmYXVsdCwgb3B0aW9uKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZm9yIChjb25zdCBba2V5LCBwbHVnaW5OYW1lXSBvZiBPYmplY3QuZW50cmllcyhwbHVnaW5zTW9kdWxlcykpIHtcbiAgICAgIGF3YWl0IHJlZ2lzdGVyUGx1Z2luKGtleSBhcyBrZXlvZiB0eXBlb2YgcGx1Z2lucywgcGx1Z2luTmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKHBsdWdpbnMud3MpIHtcbiAgICAgIGF3YWl0IHRoaXMuZW5zdXJlV2ViU29ja2V0UGx1Z2luKHNlcnZlcik7XG4gICAgfVxuXG4gICAgaWYgKHBsdWdpbnMuY3VzdG9tKSB7XG4gICAgICBwbHVnaW5zLmN1c3RvbShzZXJ2ZXIpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEBmYXN0aWZ5L3dlYnNvY2tldOydgCBwbHVnaW5zLndz6rCAIOyEpOygleuQnCDqsr3smrDsl5Drp4wg65Ox66Gd7ZWY6rOgLCDqsJnsnYAgc2VydmVy7JeQIOykkeuztSDrk7HroZ3rkJjsp4Ag7JWK64+E66GdIFdlYWtTZXTsnLzroZwg6riw66Gd7ZWoXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlV2ViU29ja2V0UGx1Z2luKFxuICAgIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT4sXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLndlYnNvY2tldFBsdWdpblNlcnZlcnMuaGFzKHNlcnZlcikpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwbHVnaW5PcHRpb24gPSB0aGlzLmNvbmZpZy5zZXJ2ZXIucGx1Z2lucz8ud3M7XG4gICAgaWYgKCFwbHVnaW5PcHRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB3ZWJzb2NrZXRQbHVnaW4gPSAoYXdhaXQgaW1wb3J0KFwiQGZhc3RpZnkvd2Vic29ja2V0XCIpKS5kZWZhdWx0O1xuICAgIGNvbnN0IHJlc29sdmVkUGx1Z2luT3B0aW9ucyA9IHJlc29sdmVXZWJTb2NrZXRQbHVnaW5PcHRpb25zKHtcbiAgICAgIHJhd1BsdWdpbk9wdGlvbjogcGx1Z2luT3B0aW9uLFxuICAgIH0pO1xuICAgIGlmIChyZXNvbHZlZFBsdWdpbk9wdGlvbnMpIHtcbiAgICAgIGF3YWl0IHNlcnZlci5yZWdpc3Rlcih3ZWJzb2NrZXRQbHVnaW4sIHJlc29sdmVkUGx1Z2luT3B0aW9ucyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHNlcnZlci5yZWdpc3Rlcih3ZWJzb2NrZXRQbHVnaW4pO1xuICAgIH1cblxuICAgIHRoaXMud2Vic29ja2V0UGx1Z2luU2VydmVycy5hZGQoc2VydmVyKTtcbiAgICB0aGlzLndhcm5PblBvdGVudGlhbFdlYlNvY2tldFRpbWVvdXRDb25mbGljdHMoc2VydmVyKTtcbiAgfVxuXG4gIC8vIGhlYXJ0YmVhdCBpbnRlcnZhbOydtCBGYXN0aWZ5IGtlZXBBbGl2ZVRpbWVvdXQg7J207IOB7J2066m0IOyduO2UhOudvOqwgCDrqLzsoIAgaWRsZSDsl7DqsrDsnYQg64GK7J2EIOyImCDsnojslrQg6rK96rOg66eMIOuCqOq4sOqzoCDrhJjslrTqsJBcbiAgcHJpdmF0ZSB3YXJuT25Qb3RlbnRpYWxXZWJTb2NrZXRUaW1lb3V0Q29uZmxpY3RzKFxuICAgIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT4sXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IGhlYXJ0YmVhdHMgPSB0aGlzLnN5bmNlci5hcGlzXG4gICAgICAubWFwKChhcGkpID0+IGFwaS53ZWJzb2NrZXRPcHRpb25zPy5oZWFydGJlYXQgPz8gMzAwMDApXG4gICAgICAuZmlsdGVyKChoZWFydGJlYXQpID0+IGhlYXJ0YmVhdCA+IDApO1xuXG4gICAgaWYgKGhlYXJ0YmVhdHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qga2VlcEFsaXZlVGltZW91dCA9IHRoaXMuY29uZmlnLnNlcnZlci5mYXN0aWZ5Py5rZWVwQWxpdmVUaW1lb3V0O1xuICAgIGlmICgha2VlcEFsaXZlVGltZW91dCB8fCBrZWVwQWxpdmVUaW1lb3V0IDw9IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBsYXJnZXN0SGVhcnRiZWF0ID0gTWF0aC5tYXgoLi4uaGVhcnRiZWF0cyk7XG4gICAgaWYgKGxhcmdlc3RIZWFydGJlYXQgPj0ga2VlcEFsaXZlVGltZW91dCkge1xuICAgICAgc2VydmVyLmxvZy53YXJuKFxuICAgICAgICB7XG4gICAgICAgICAga2VlcEFsaXZlVGltZW91dCxcbiAgICAgICAgICBsYXJnZXN0SGVhcnRiZWF0LFxuICAgICAgICB9LFxuICAgICAgICBcIldlYlNvY2tldCBoZWFydGJlYXQgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGtlZXBBbGl2ZVRpbWVvdXQ7IGFsaWduIGluZnJhc3RydWN0dXJlIGlkbGUgdGltZW91dHMgdG8gYXZvaWQgdW5leHBlY3RlZCBkaXNjb25uZWN0cy5cIixcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIGJldHRlci1hdXRoIOudvOyasO2KuOulvCDrk7HroZ3tlanri4jri6QuXG4gICAqIC9hcGkvYXV0aC8qIOqyveuhnOuhnCDsnbjspp0gQVBJ6rCAIOyekOuPmSDrk7HroZ3rkKnri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlZ2lzdGVyQmV0dGVyQXV0aChcbiAgICBzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZSxcbiAgICBvcHRpb25zOiBOb25OdWxsYWJsZTxTb25hbXVTZXJ2ZXJPcHRpb25zW1wiYXV0aFwiXT4sXG4gICkge1xuICAgIGlmICghb3B0aW9ucykgcmV0dXJuO1xuXG4gICAgY29uc3QgYmFzZVBhdGggPSBvcHRpb25zLmJhc2VQYXRoID8/IFwiL2FwaS9hdXRoXCI7XG5cbiAgICAvLyBiZXR0ZXItYXV0aCDrnbzsmrDtirgg65Ox66GdXG4gICAgc2VydmVyLnJvdXRlKHtcbiAgICAgIG1ldGhvZDogW1wiR0VUXCIsIFwiUE9TVFwiXSxcbiAgICAgIHVybDogYCR7YmFzZVBhdGh9LypgLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IHVybCA9IG5ldyBVUkwocmVxdWVzdC51cmwsIGBodHRwOi8vJHtyZXF1ZXN0LmhlYWRlcnMuaG9zdH1gKTtcbiAgICAgICAgY29uc3QgaGVhZGVycyA9IGNvbnZlcnRGYXN0aWZ5SGVhZGVyc1RvU3RhbmRhcmQocmVxdWVzdC5oZWFkZXJzKTtcblxuICAgICAgICAvLyBJUCDtl6TrjZQgZmFsbGJhY2s6IO2UhOuhneyLnOqwgCDtkZzspIAgSVAg7Zek642U66W8IOyjvOyehe2VmOyngCDslYrripQg7ZmY6rK97JeQ7ISc64+EXG4gICAgICAgIC8vIGJldHRlci1hdXRoL2luZnJh7J2YIGdldENsaWVudElwRnJvbVJlcXVlc3QoKeqwgCBJUOulvCDsnbjsi53tlaAg7IiYIOyeiOuPhOuhnVxuICAgICAgICAvLyBGYXN0aWZ56rCAIHJlc29sdmXtlZwgcmVxdWVzdC5pcOulvCB4LXJlYWwtaXDroZwg7KO87J6F7ZWc64ukLlxuICAgICAgICBjb25zdCBJUF9IRUFERVJTID0gW1xuICAgICAgICAgIFwiY2YtY29ubmVjdGluZy1pcFwiLFxuICAgICAgICAgIFwieC1mb3J3YXJkZWQtZm9yXCIsXG4gICAgICAgICAgXCJ4LXJlYWwtaXBcIixcbiAgICAgICAgICBcIngtdmVyY2VsLWZvcndhcmRlZC1mb3JcIixcbiAgICAgICAgXTtcbiAgICAgICAgaWYgKHJlcXVlc3QuaXAgJiYgIUlQX0hFQURFUlMuc29tZSgoaCkgPT4gaGVhZGVycy5oYXMoaCkpKSB7XG4gICAgICAgICAgaGVhZGVycy5zZXQoXCJ4LXJlYWwtaXBcIiwgcmVxdWVzdC5pcCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXEgPSBuZXcgUmVxdWVzdCh1cmwudG9TdHJpbmcoKSwge1xuICAgICAgICAgIG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG4gICAgICAgICAgaGVhZGVycyxcbiAgICAgICAgICAuLi4ocmVxdWVzdC5ib2R5ID8geyBib2R5OiBKU09OLnN0cmluZ2lmeShyZXF1ZXN0LmJvZHkpIH0gOiB7fSksXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5hdXRoLmhhbmRsZXIocmVxKTtcblxuICAgICAgICByZXBseS5zdGF0dXMocmVzcG9uc2Uuc3RhdHVzKTtcbiAgICAgICAgcmVzcG9uc2UuaGVhZGVycy5mb3JFYWNoKCh2YWx1ZTogc3RyaW5nLCBrZXk6IHN0cmluZykgPT4ge1xuICAgICAgICAgIHJlcGx5LmhlYWRlcihrZXksIHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiByZXBseS5zZW5kKHJlc3BvbnNlLmJvZHkgPyBhd2FpdCByZXNwb25zZS50ZXh0KCkgOiBudWxsKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHByaW50U3RhcnR1cFN1bW1hcnkoKSB7XG4gICAgY29uc3QgY2hhbGsgPSAoYXdhaXQgaW1wb3J0KFwiY2hhbGtcIikpLmRlZmF1bHQ7XG4gICAgY29uc3QgZW52ID0gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPz8gXCJkZXZlbG9wbWVudFwiO1xuICAgIGNvbnN0IGFjdGl2ZVByZXNldCA9IGVudiA9PT0gXCJwcm9kdWN0aW9uXCIgPyBcInByb2R1Y3Rpb25fbWFzdGVyXCIgOiBcImRldmVsb3BtZW50X21hc3RlclwiO1xuXG4gICAgY29uc3QgZGltID0gKG1zZzogc3RyaW5nKSA9PiBjb25zb2xlLmxvZyhjaGFsay5kaW0oYOKckyAke21zZ31gKSk7XG4gICAgY29uc3QgZ3JlZW4gPSAobXNnOiBzdHJpbmcpID0+IGNvbnNvbGUubG9nKGNoYWxrLmdyZWVuKGDinJMgJHttc2d9YCkpO1xuXG4gICAgZGltKGBDb25maWcgbG9hZGVkJHtmb3JtYXRUaW1lKHRoaXMuX2NvbmZpZ0VsYXBzZWQpfWApO1xuXG4gICAgLy8gREIgcHJlc2V0IOuqqeuhnVxuICAgIGdyZWVuKFwiREJcIik7XG4gICAgY29uc3QgeyBpc0xvY2FsIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi91dGlscy9jb250cm9sbGVyXCIpO1xuICAgIGNvbnN0IHByZXNldE5hbWVzID0gT2JqZWN0LmtleXModGhpcy5kYkNvbmZpZykgYXMgKGtleW9mIFNvbmFtdURCQ29uZmlnKVtdO1xuICAgIGNvbnN0IG1heExlbiA9IE1hdGgubWF4KC4uLnByZXNldE5hbWVzLm1hcCgobikgPT4gbi5sZW5ndGgpKTtcbiAgICBmb3IgKGNvbnN0IG5hbWUgb2YgcHJlc2V0TmFtZXMpIHtcbiAgICAgIGNvbnN0IGNvbm4gPSB0aGlzLmRiQ29uZmlnW25hbWVdLmNvbm5lY3Rpb24gYXNcbiAgICAgICAgfCB7IGhvc3Q/OiBzdHJpbmc7IHBvcnQ/OiBudW1iZXI7IGRhdGFiYXNlPzogc3RyaW5nIH1cbiAgICAgICAgfCB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBob3N0ID0gY29ubj8uaG9zdCA/PyBcImxvY2FsaG9zdFwiO1xuICAgICAgY29uc3QgYWRkciA9IGBAICR7aG9zdH06JHtjb25uPy5wb3J0ID8/IDU0MzJ9LyR7Y29ubj8uZGF0YWJhc2UgPz8gdGhpcy5jb25maWcuZGF0YWJhc2UubmFtZX1gO1xuICAgICAgY29uc3QgcGFkZGVkID0gbmFtZS5wYWRFbmQobWF4TGVuKTtcbiAgICAgIGNvbnN0IHJlbW90ZVRhZyA9IGlzTG9jYWwoKSAmJiAhaXNMb2NhbEhvc3QoaG9zdCkgPyBjaGFsay55ZWxsb3coYCBcXHUyNmEwIHJlbW90ZWApIDogXCJcIjtcblxuICAgICAgaWYgKG5hbWUgPT09IGFjdGl2ZVByZXNldCkge1xuICAgICAgICBjb25zb2xlLmxvZyhjaGFsay5ncmVlbihgICBcXHUyNWI4ICR7cGFkZGVkfSAke2FkZHJ9YCkgKyByZW1vdGVUYWcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5sb2coY2hhbGsuZGltKGAgICAgJHtwYWRkZWR9ICR7YWRkcn1gKSArIHJlbW90ZVRhZyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY29uZmlnLnNlcnZlci5hdXRoKSB7XG4gICAgICBjb25zdCBiYXNlUGF0aCA9IHRoaXMuY29uZmlnLnNlcnZlci5hdXRoLmJhc2VQYXRoID8/IFwiL2FwaS9hdXRoXCI7XG4gICAgICBkaW0oYEF1dGg6IGJldHRlci1hdXRoIGF0ICR7YmFzZVBhdGh9LypgKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuY29uZmlnLmFwaS50aW1lem9uZSkge1xuICAgICAgZGltKGBUaW1lem9uZTogJHt0aGlzLmNvbmZpZy5hcGkudGltZXpvbmV9YCk7XG4gICAgfVxuICAgIGdyZWVuKGBTb25hbXUgcmVhZHkke2Zvcm1hdFRpbWUodGhpcy5faW5pdEVsYXBzZWQpfWApO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBpbml0aWFsaXplQ2FjaGUoY29uZmlnOiBDYWNoZUNvbmZpZyB8IHVuZGVmaW5lZCwgZm9yVGVzdGluZzogYm9vbGVhbikge1xuICAgIGNvbnN0IHsgc2V0Q2FjaGVNYW5hZ2VyUmVmIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9jYWNoZS9kZWNvcmF0b3JcIik7XG5cbiAgICAvLyDthYzsiqTtirgg7ZmY6rK97JeQ7IScIOuplOuqqOumrCDrk5zrnbzsnbTrsoQg7J6Q64+ZIOyCrOyaqVxuICAgIGlmIChmb3JUZXN0aW5nKSB7XG4gICAgICBjb25zdCB7IGNyZWF0ZVRlc3RDYWNoZU1hbmFnZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL2NhY2hlL2NhY2hlLW1hbmFnZXJcIik7XG4gICAgICB0aGlzLl9jYWNoZSA9IGNyZWF0ZVRlc3RDYWNoZU1hbmFnZXIoKTtcbiAgICAgIHNldENhY2hlTWFuYWdlclJlZih0aGlzLl9jYWNoZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8g7ISk7KCV7J20IOyXhuycvOuptCDsupDsi5wg67mE7Zmc7ISx7ZmUXG4gICAgaWYgKCFjb25maWcpIHtcbiAgICAgIHNldENhY2hlTWFuYWdlclJlZihudWxsKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyDshKTsoJXsl5Ag65Sw6528IENhY2hlTWFuYWdlciDsg53shLFcbiAgICBjb25zdCB7IGNyZWF0ZUNhY2hlTWFuYWdlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vY2FjaGUvY2FjaGUtbWFuYWdlclwiKTtcbiAgICB0aGlzLl9jYWNoZSA9IGNyZWF0ZUNhY2hlTWFuYWdlcihjb25maWcpO1xuICAgIHNldENhY2hlTWFuYWdlclJlZih0aGlzLl9jYWNoZSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGluaXRpYWxpemVXb3JrZmxvd3Mob3B0aW9uczogU29uYW11VGFza09wdGlvbnMgfCB1bmRlZmluZWQpIHtcbiAgICBjb25zdCB7IFdvcmtmbG93TWFuYWdlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdGFza3Mvd29ya2Zsb3ctbWFuYWdlclwiKTtcbiAgICAvLyBOT1RFOiBAc29uYW11LWtpdC90YXNrcyDslYjsl5DshKAga25leCBjb25maWfrpbwg7IiY7KCV7ZWY6riwIOuVjOusuOyXkCBjb25uZWN0aW9u7J20IOyVhOuLjCBjb25maWcg7Ke466GcIOuztOuDheuLiOuLpC5cbiAgICB0aGlzLl93b3JrZmxvd3MgPSBuZXcgV29ya2Zsb3dNYW5hZ2VyKERCLmdldERCQ29uZmlnKFwid1wiKSk7XG4gICAgaWYgKCFvcHRpb25zKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZW5hYmxlV29ya2VyID0gb3B0aW9ucy5lbmFibGVXb3JrZXIgPz8gaXNEYWVtb25TZXJ2ZXIoKTtcbiAgICBjb25zdCBkZWZhdWx0V29ya2VyT3B0aW9ucyA9IHtcbiAgICAgIGNvbmN1cnJlbmN5OiBvcy5jcHVzKCkubGVuZ3RoIC0gMSxcbiAgICAgIHVzZVB1YlN1YjogdHJ1ZSxcbiAgICAgIGxpc3RlbkRlbGF5OiA1MDAsXG4gICAgfTtcblxuICAgIGlmIChlbmFibGVXb3JrZXIpIHtcbiAgICAgIHRoaXMud29ya2Zsb3dzLnNldHVwV29ya2VyKHtcbiAgICAgICAgLi4uZGVmYXVsdFdvcmtlck9wdGlvbnMsXG4gICAgICAgIC4uLm9wdGlvbnMud29ya2VyT3B0aW9ucyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgYm9vdChzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZSwgb3B0aW9uczogU29uYW11U2VydmVyT3B0aW9ucykge1xuICAgIGNvbnN0IHBvcnQgPSBvcHRpb25zLmxpc3Rlbj8ucG9ydCA/PyAzMDAwO1xuICAgIGNvbnN0IGhvc3QgPSBvcHRpb25zLmxpc3Rlbj8uaG9zdCA/PyBcImxvY2FsaG9zdFwiO1xuXG4gICAgc2VydmVyLmFkZEhvb2soXCJvbkNsb3NlXCIsIGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IG9wdGlvbnMubGlmZWN5Y2xlPy5vblNodXRkb3duPy4oc2VydmVyKTtcbiAgICAgIGF3YWl0IHRoaXMud29ya2Zsb3dzLmRlc3Ryb3koKTtcbiAgICAgIGF3YWl0IHRoaXMuZGVzdHJveSgpO1xuICAgIH0pO1xuXG4gICAgY29uc3Qgc2h1dGRvd24gPSBhc3luYyAoKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBzZXJ2ZXIuY2xvc2UoKTtcbiAgICAgICAgcHJvY2Vzcy5leGl0KDApO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBkdXJpbmcgc2h1dGRvd246XCIsIGVycik7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcHJvY2Vzcy5vbihcIlNJR0lOVFwiLCBzaHV0ZG93bik7XG4gICAgcHJvY2Vzcy5vbihcIlNJR1RFUk1cIiwgc2h1dGRvd24pO1xuXG4gICAgaWYgKG9wdGlvbnMubGlmZWN5Y2xlPy5vbkVycm9yKSB7XG4gICAgICBzZXJ2ZXIuc2V0RXJyb3JIYW5kbGVyKG9wdGlvbnMubGlmZWN5Y2xlPy5vbkVycm9yKTtcbiAgICB9XG5cbiAgICBzZXJ2ZXJcbiAgICAgIC5saXN0ZW4oeyBwb3J0LCBob3N0IH0pXG4gICAgICAudGhlbihhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHRoaXMud29ya2Zsb3dzLnN0YXJ0V29ya2VyKCk7XG4gICAgICAgIGF3YWl0IG9wdGlvbnMubGlmZWN5Y2xlPy5vblN0YXJ0Py4oc2VydmVyKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goYXN5bmMgKGVycikgPT4ge1xuICAgICAgICBjb25zdCBjaGFsayA9IChhd2FpdCBpbXBvcnQoXCJjaGFsa1wiKSkuZGVmYXVsdDtcbiAgICAgICAgY29uc29sZS5lcnJvcihjaGFsay5yZWQoXCJGYWlsZWQgdG8gc3RhcnQgc2VydmVyOlwiLCBlcnIpKTtcbiAgICAgICAgYXdhaXQgc2h1dGRvd24oKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgZGVzdHJveSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7IEJhc2VNb2RlbCB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vZGF0YWJhc2UvYmFzZS1tb2RlbFwiKTtcbiAgICAvLyDrqLzsoIAg7LKY66as7ZW07JW87ZWoLlxuICAgIGF3YWl0IEJhc2VNb2RlbC5kZXN0cm95KCk7XG4gICAgLy8gV2ViU29ja2V0IHNodXRkb3duIGZpcnN0IHRvIGZsdXNoIHRlbGVtZXRyeVxuICAgIGlmICh0aGlzLl93ZWJzb2NrZXRSdW50aW1lKSB7XG4gICAgICBhd2FpdCB0aGlzLl93ZWJzb2NrZXRSdW50aW1lLnNodXRkb3duKCk7XG4gICAgfVxuICAgIHRoaXMuX3dlYnNvY2tldFJ1bnRpbWUgPSBudWxsO1xuICAgIC8vIFRoZW4gc2h1dCBkb3duIHJlbWFpbmluZyByZXNvdXJjZXMgaW4gcGFyYWxsZWxcbiAgICBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoW1xuICAgICAgdGhpcy5fd29ya2Zsb3dzPy5kZXN0cm95KCkgPz8gUHJvbWlzZS5yZXNvbHZlKCksXG4gICAgICB0aGlzLl9jYWNoZT8uZGlzY29ubmVjdCgpID8/IFByb21pc2UucmVzb2x2ZSgpLFxuICAgICAgdGhpcy5fZGV2Vml0ZXN0TWFuYWdlcj8uc2h1dGRvd24oKSA/PyBQcm9taXNlLnJlc29sdmUoKSxcbiAgICAgIHRoaXMud2F0Y2hlcj8uY2xvc2UoKSA/PyBQcm9taXNlLnJlc29sdmUoKSxcbiAgICBdKTtcbiAgICAvLyBMb2dUYXBlIGRpc3Bvc2UgYWZ0ZXIgV1Mgc2h1dGRvd24gc28gdGVsZW1ldHJ5IHJlY29yZHMgYXJlIGZsdXNoZWQgZmlyc3RcbiAgICBhd2FpdCBsb2d0YXBlRGlzcG9zZSgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldFdlYlNvY2tldFRlbGVtZXRyeUNvbnRleHQoXG4gIHdzOiBXZWJTb2NrZXRDb25uZWN0aW9uPFdlYlNvY2tldEV2ZW50TWFwLCBXZWJTb2NrZXRFdmVudE1hcD4sXG4pOiBXZWJTb2NrZXRUZWxlbWV0cnlDb25uZWN0aW9uQ29udGV4dCB7XG4gIGlmICghaXNUZWxlbWV0cnlDb250ZXh0UHJvdmlkZXIod3MpKSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgcmV0dXJuIHdzLmdldFRlbGVtZXRyeUNvbnRleHQoKTtcbn1cblxuZnVuY3Rpb24gaXNUZWxlbWV0cnlDb250ZXh0UHJvdmlkZXIoXG4gIHdzOiBXZWJTb2NrZXRDb25uZWN0aW9uPFdlYlNvY2tldEV2ZW50TWFwLCBXZWJTb2NrZXRFdmVudE1hcD4sXG4pOiB3cyBpcyBXZWJTb2NrZXRDb25uZWN0aW9uPFdlYlNvY2tldEV2ZW50TWFwLCBXZWJTb2NrZXRFdmVudE1hcD4gJiBUZWxlbWV0cnlDb250ZXh0UHJvdmlkZXIge1xuICByZXR1cm4gXCJnZXRUZWxlbWV0cnlDb250ZXh0XCIgaW4gd3MgJiYgdHlwZW9mIHdzLmdldFRlbGVtZXRyeUNvbnRleHQgPT09IFwiZnVuY3Rpb25cIjtcbn1cblxuZXhwb3J0IGNvbnN0IFNvbmFtdSA9IG5ldyBTb25hbXVDbGFzcygpO1xuXG4vKipcbiAqIHN0cmVhbSDrqqjrk5zsl5DshJwg7YKkIOyDneyEsSDtlajsiJjqsIAg7KeA7KCV65CY7KeAIOyViuyVmOydhCDrlYwg7IKs7Jqp7ZWY64qUIOq4sOuzuCDtlajsiJjsnoXri4jri6QuXG4gKi9cbmZ1bmN0aW9uIGRlZmF1bHRLZXlHZW5lcmF0b3IoZmlsZTogeyBmaWxlbmFtZTogc3RyaW5nOyBtaW1ldHlwZTogc3RyaW5nIH0pOiBzdHJpbmcge1xuICBjb25zdCBleHQgPSBtaW1lLmV4dGVuc2lvbihmaWxlLm1pbWV0eXBlKSB8fCBcImJpblwiO1xuICBjb25zdCB0aW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuICBjb25zdCByYW5kb20gPSBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyLCA4KTtcbiAgcmV0dXJuIGB1cGxvYWRzLyR7dGltZXN0YW1wfS0ke3JhbmRvbX0uJHtleHR9YDtcbn1cblxuZnVuY3Rpb24gZm9ybWF0VGltZShtczogbnVtYmVyKTogc3RyaW5nIHtcbiAgY29uc3QgZm9ybWF0dGVkID0gbXMgPj0gMTAwMCA/IGAkeyhtcyAvIDEwMDApLnRvRml4ZWQoMil9c2AgOiBgJHtNYXRoLnJvdW5kKG1zKX1tc2A7XG4gIHJldHVybiBgICgke2Zvcm1hdHRlZH0pYDtcbn1cblxuY29uc3QgTE9DQUxfSE9TVFMgPSBuZXcgU2V0KFtcImxvY2FsaG9zdFwiLCBcIjEyNy4wLjAuMVwiLCBcIjAuMC4wLjBcIiwgXCI6OjFcIl0pO1xuZnVuY3Rpb24gaXNMb2NhbEhvc3QoaG9zdDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBMT0NBTF9IT1NUUy5oYXMoaG9zdCkgfHwgaG9zdC5lbmRzV2l0aChcIi5sb2NhbFwiKTtcbn1cblxuLy8gYC5ldmVyeSgpYOqwgCDssqsgZ3VhcmQg7J207ZuEIOyInO2ajOulvCDrqYjstpTripQg66y47KCc6rCAIOyeiOyWtCBgZm9yLi4ub2Zg66GcIOuqqOuToCBndWFyZOulvCDsiJzshJzrjIDroZwg7Iuk7ZaJ7ZWY64+E66GdIOqzoOygle2VqFxuZnVuY3Rpb24gcnVuR3VhcmRzKHtcbiAgZ3VhcmRzLFxuICBjb25maWcsXG4gIHJlcXVlc3QsXG4gIGFwaSxcbn06IHtcbiAgZ3VhcmRzOiBFeHRlbmRlZEFwaVtcIm9wdGlvbnNcIl1bXCJndWFyZHNcIl0gfCB1bmRlZmluZWQ7XG4gIGNvbmZpZzogUGljazxTb25hbXVGYXN0aWZ5Q29uZmlnLCBcImd1YXJkSGFuZGxlclwiPjtcbiAgcmVxdWVzdDogRmFzdGlmeVJlcXVlc3Q7XG4gIGFwaTogRXh0ZW5kZWRBcGk7XG59KTogdm9pZCB7XG4gIGZvciAoY29uc3QgZ3VhcmQgb2YgZ3VhcmRzID8/IFtdKSB7XG4gICAgY29uZmlnLmd1YXJkSGFuZGxlcihndWFyZCwgcmVxdWVzdCwgYXBpKTtcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXE3REEsU0FBUyw2QkFDUCxJQUNxQztBQUNyQyxLQUFJLENBQUMsMkJBQTJCLEdBQUcsRUFBRTtBQUNuQyxTQUFPLEVBQUU7O0FBR1gsUUFBTyxHQUFHLHFCQUFxQjs7QUFHakMsU0FBUywyQkFDUCxJQUM0RjtBQUM1RixRQUFPLHlCQUF5QixNQUFNLE9BQU8sR0FBRyx3QkFBd0I7Ozs7O0FBUTFFLFNBQVMsb0JBQW9CLE1BQXNEO0NBQ2pGLE1BQU0sTUFBTSxLQUFLLFVBQVUsS0FBSyxTQUFTLElBQUk7Q0FDN0MsTUFBTSxZQUFZLEtBQUssS0FBSztDQUM1QixNQUFNLFNBQVMsS0FBSyxRQUFRLENBQUMsU0FBUyxHQUFHLENBQUMsTUFBTSxHQUFHLEVBQUU7QUFDckQsUUFBTyxXQUFXLFVBQVUsR0FBRyxPQUFPLEdBQUc7O0FBRzNDLFNBQVMsV0FBVyxJQUFvQjtDQUN0QyxNQUFNLFlBQVksTUFBTSxNQUFPLElBQUksS0FBSyxLQUFNLFFBQVEsRUFBRSxDQUFDLEtBQUssR0FBRyxLQUFLLE1BQU0sR0FBRyxDQUFDO0FBQ2hGLFFBQU8sS0FBSyxVQUFVOztBQUl4QixTQUFTLFlBQVksTUFBdUI7QUFDMUMsUUFBTyxZQUFZLElBQUksS0FBSyxJQUFJLEtBQUssU0FBUyxTQUFTOztBQUl6RCxT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
1265
+
1266
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29uYW11LmpzIiwibmFtZXMiOlsibWltZUxvb2t1cCIsImxvZ3RhcGVEaXNwb3NlIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwaS9zb25hbXUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQXN5bmNMb2NhbFN0b3JhZ2UgfSBmcm9tIFwiYXN5bmNfaG9va3NcIjtcbmltcG9ydCBmcyBmcm9tIFwiZnMvcHJvbWlzZXNcIjtcbmltcG9ydCB7IHR5cGUgSW5jb21pbmdNZXNzYWdlLCB0eXBlIFNlcnZlciwgdHlwZSBTZXJ2ZXJSZXNwb25zZSB9IGZyb20gXCJodHRwXCI7XG5pbXBvcnQgb3MgZnJvbSBcIm9zXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5pbXBvcnQgdHlwZSB7fSBmcm9tIFwiQGZhc3RpZnkvd2Vic29ja2V0XCI7XG5pbXBvcnQgeyBkaXNwb3NlIGFzIGxvZ3RhcGVEaXNwb3NlIH0gZnJvbSBcIkBsb2d0YXBlL2xvZ3RhcGVcIjtcbmltcG9ydCB7IHR5cGUgQXV0aCwgdHlwZSBCZXR0ZXJBdXRoT3B0aW9ucyB9IGZyb20gXCJiZXR0ZXItYXV0aFwiO1xuaW1wb3J0IGNoYWxrIGZyb20gXCJjaGFsa1wiO1xuaW1wb3J0IHsgdHlwZSBGU1dhdGNoZXIgfSBmcm9tIFwiY2hva2lkYXJcIjtcbmltcG9ydCB7IHR5cGUgRmFzdGlmeUluc3RhbmNlLCB0eXBlIEZhc3RpZnlSZXBseSwgdHlwZSBGYXN0aWZ5UmVxdWVzdCB9IGZyb20gXCJmYXN0aWZ5XCI7XG5pbXBvcnQgbWltZSwgeyBsb29rdXAgYXMgbWltZUxvb2t1cCB9IGZyb20gXCJtaW1lLXR5cGVzXCI7XG5pbXBvcnQgeyB0eXBlIFdlYlNvY2tldCB9IGZyb20gXCJ3c1wiO1xuaW1wb3J0IHsgdHlwZSBab2RPYmplY3QgfSBmcm9tIFwiem9kXCI7XG5cbmltcG9ydCB7IEJBU0VfRklFTERfTUFQUElOR1MgfSBmcm9tIFwiLi4vYXV0aC9iZXR0ZXItYXV0aC1lbnRpdGllc1wiO1xuaW1wb3J0IHsgY3JlYXRlQmV0dGVyQXV0aFJlcXVlc3QgfSBmcm9tIFwiLi4vYXV0aC9iZXR0ZXItYXV0aC1yZXF1ZXN0XCI7XG5pbXBvcnQgeyBhcHBseUNhY2hlSGVhZGVycywgQ2FjaGVQcmVzZXRzIH0gZnJvbSBcIi4uL2NhY2hlLWNvbnRyb2wvY2FjaGUtY29udHJvbFwiO1xuaW1wb3J0IHsgdHlwZSBDYWNoZUNvbnRyb2xDb25maWcsIHR5cGUgQ2FjaGVDb250cm9sUmVxdWVzdCB9IGZyb20gXCIuLi9jYWNoZS1jb250cm9sL3R5cGVzXCI7XG5pbXBvcnQgeyB0eXBlIENhY2hlQ29uZmlnLCB0eXBlIENhY2hlTWFuYWdlciB9IGZyb20gXCIuLi9jYWNoZS90eXBlc1wiO1xuaW1wb3J0IHsgdG9GYXN0aWZ5Q29tcHJlc3NPcHRpb24gfSBmcm9tIFwiLi4vY29tcHJlc3MvY29tcHJlc3NcIjtcbmltcG9ydCB7IHR5cGUgQ29tcHJlc3NPcHRpb25zIH0gZnJvbSBcIi4uL2NvbXByZXNzL3R5cGVzXCI7XG5pbXBvcnQgeyBEQiB9IGZyb20gXCIuLi9kYXRhYmFzZS9kYlwiO1xuaW1wb3J0IHsgdHlwZSBTb25hbXVEQkNvbmZpZyB9IGZyb20gXCIuLi9kYXRhYmFzZS9kYlwiO1xuaW1wb3J0IHsgU0QsIHNldFNEQ29uZmlnIH0gZnJvbSBcIi4uL2RpY3Qvc2RcIjtcbmltcG9ydCB7IHR5cGUgTG9jYWxpemVkU3RyaW5nIH0gZnJvbSBcIi4uL2RpY3QvdHlwZXNcIjtcbmltcG9ydCB7IGdldFNvbmFtdUVudmlyb25tZW50LCByZWFkQWxsRW52aXJvbm1lbnRTbmFwc2hvdHMgfSBmcm9tIFwiLi4vZW52XCI7XG5pbXBvcnQgeyBOb3RGb3VuZEV4Y2VwdGlvbiB9IGZyb20gXCIuLi9leGNlcHRpb25zL3NvLWV4Y2VwdGlvbnNcIjtcbmltcG9ydCB7IEJ1ZmZlcmVkRmlsZSB9IGZyb20gXCIuLi9zdG9yYWdlL2J1ZmZlcmVkLWZpbGVcIjtcbmltcG9ydCB7IHR5cGUgU3RvcmFnZU1hbmFnZXIgfSBmcm9tIFwiLi4vc3RvcmFnZS9zdG9yYWdlLW1hbmFnZXJcIjtcbmltcG9ydCB7IHR5cGUgS2V5R2VuZXJhdG9yIH0gZnJvbSBcIi4uL3N0b3JhZ2UvdHlwZXNcIjtcbmltcG9ydCB7IFVwbG9hZGVkRmlsZSB9IGZyb20gXCIuLi9zdG9yYWdlL3VwbG9hZGVkLWZpbGVcIjtcbmltcG9ydCB7IGNyZWF0ZU1vY2tTU0VGYWN0b3J5IH0gZnJvbSBcIi4uL3N0cmVhbS9zc2VcIjtcbmltcG9ydCB7IFdlYlNvY2tldFJ1bnRpbWUsIHR5cGUgV2ViU29ja2V0Q29ubmVjdGlvbiwgdHlwZSBXZWJTb2NrZXRFdmVudE1hcCB9IGZyb20gXCIuLi9zdHJlYW0vd3NcIjtcbmltcG9ydCB7XG4gIHR5cGUgVGVsZW1ldHJ5Q29udGV4dFByb3ZpZGVyLFxuICB0eXBlIFdlYlNvY2tldFRlbGVtZXRyeUNvbm5lY3Rpb25Db250ZXh0LFxufSBmcm9tIFwiLi4vc3RyZWFtL3dzLXRlbGVtZXRyeVwiO1xuaW1wb3J0IHsgdHlwZSBTeW5jZXIgfSBmcm9tIFwiLi4vc3luY2VyL3N5bmNlclwiO1xuaW1wb3J0IHsgdHlwZSBXb3JrZmxvd01hbmFnZXIgfSBmcm9tIFwiLi4vdGFza3Mvd29ya2Zsb3ctbWFuYWdlclwiO1xuaW1wb3J0IHsgdHlwZSBEZXZWaXRlc3RNYW5hZ2VyIH0gZnJvbSBcIi4uL3Rlc3RpbmcvZGV2LXZpdGVzdC1tYW5hZ2VyXCI7XG5pbXBvcnQgeyB0eXBlIFNvbmFtdUZhc3RpZnlDb25maWcgfSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IGNlbnRlclRleHQgfSBmcm9tIFwiLi4vdXRpbHMvY29uc29sZS11dGlsXCI7XG5pbXBvcnQgeyBpc0RhZW1vblNlcnZlciB9IGZyb20gXCIuLi91dGlscy9jb250cm9sbGVyXCI7XG5pbXBvcnQgeyBleGlzdHMsIGZpbGVFeGlzdHMgfSBmcm9tIFwiLi4vdXRpbHMvZnMtdXRpbHNcIjtcbmltcG9ydCB7IHR5cGUgQWJzb2x1dGVQYXRoIH0gZnJvbSBcIi4uL3V0aWxzL3BhdGgtdXRpbHNcIjtcbmltcG9ydCB7IGNvbnZlcnRGYXN0aWZ5SGVhZGVyc1RvU3RhbmRhcmQsIG1lcmdlIH0gZnJvbSBcIi4uL3V0aWxzL3V0aWxzXCI7XG5pbXBvcnQgeyB0eXBlIFNvbmFtdUNvbmZpZywgdHlwZSBTb25hbXVTZXJ2ZXJPcHRpb25zLCB0eXBlIFNvbmFtdVRhc2tPcHRpb25zIH0gZnJvbSBcIi4vY29uZmlnXCI7XG5pbXBvcnQgeyB0eXBlIENvbnRleHQsIHR5cGUgUnVudGltZUNvbnRleHQsIHR5cGUgV2ViU29ja2V0Q29udGV4dCB9IGZyb20gXCIuL2NvbnRleHRcIjtcbmltcG9ydCB7IHR5cGUgRXh0ZW5kZWRBcGkgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBnZXRTZWNyZXRzIH0gZnJvbSBcIi4vc2VjcmV0XCI7XG5pbXBvcnQgeyB0eXBlIFNvbmFtdVNlY3JldHMgfSBmcm9tIFwiLi9zZWNyZXRcIjtcbmltcG9ydCB7XG4gIGNyZWF0ZVdlYlNvY2tldFJlcGx5U3R1YixcbiAgcmVzb2x2ZVdlYlNvY2tldENsb3NlRGVzY3JpcHRvcixcbiAgcmVzb2x2ZVdlYlNvY2tldFBsdWdpbk9wdGlvbnMsXG4gIHJlc29sdmVJbnRlZ3JhdGVkVml0ZUhtck9wdGlvbnMsXG59IGZyb20gXCIuL3dlYnNvY2tldC1oZWxwZXJzXCI7XG5cbmV4cG9ydCB7XG4gIGNyZWF0ZVdlYlNvY2tldFJlcGx5U3R1YixcbiAgcmVzb2x2ZVdlYlNvY2tldENsb3NlRGVzY3JpcHRvcixcbiAgcmVzb2x2ZVdlYlNvY2tldFBsdWdpbk9wdGlvbnMsXG59IGZyb20gXCIuL3dlYnNvY2tldC1oZWxwZXJzXCI7XG5cbmNsYXNzIFNvbmFtdUNsYXNzIHtcbiAgcHVibGljIGlzSW5pdGlhbGl6ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHVibGljIGZvclRlc3Rpbmc6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHVibGljIGFzeW5jTG9jYWxTdG9yYWdlOiBBc3luY0xvY2FsU3RvcmFnZTx7XG4gICAgY29udGV4dDogUnVudGltZUNvbnRleHQ7XG4gIH0+ID0gbmV3IEFzeW5jTG9jYWxTdG9yYWdlKCk7XG5cbiAgcHVibGljIGdldENvbnRleHQ8VCBleHRlbmRzIFJ1bnRpbWVDb250ZXh0ID0gQ29udGV4dD4oKTogVCB7XG4gICAgY29uc3Qgc3RvcmUgPSB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLmdldFN0b3JlKCk7XG4gICAgaWYgKHN0b3JlPy5jb250ZXh0KSB7XG4gICAgICByZXR1cm4gc3RvcmUuY29udGV4dCBhcyBUO1xuICAgIH1cblxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gXCJ0ZXN0XCIpIHtcbiAgICAgIC8vIO2FjOyKpO2MhSDtmZjqsr3sl5DshJwg7Luo7YWN7Iqk7Yq46rCAIOyjvOyeheuQmOyngCDslYrsnYAg6rK97JqwIOu5iCDsu6jthY3siqTtirgg66as7YS0XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0cmFuc3BvcnQ6IFwiaHR0cFwiLFxuICAgICAgICByZXF1ZXN0OiBudWxsLFxuICAgICAgICByZXBseTogbnVsbCxcbiAgICAgICAgaGVhZGVyczoge30sXG4gICAgICAgIGNyZWF0ZVNTRTogKHNjaGVtYTogWm9kT2JqZWN0KSA9PiBjcmVhdGVNb2NrU1NFRmFjdG9yeShzY2hlbWEpLFxuICAgICAgICBsb2NhbGU6IFwiXCIsXG4gICAgICAgIHVzZXI6IG51bGwsXG4gICAgICAgIHNlc3Npb246IG51bGwsXG4gICAgICAgIG5haXRlU3RvcmU6IG5ldyBNYXA8c3RyaW5nLCBhbnk+KCksXG4gICAgICB9IGFzIHVua25vd24gYXMgVDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGNhbm5vdCBmaW5kIGNvbnRleHRcIik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfYXBpUm9vdFBhdGg6IEFic29sdXRlUGF0aCB8IG51bGwgPSBudWxsO1xuICBzZXQgYXBpUm9vdFBhdGgoYXBpUm9vdFBhdGg6IEFic29sdXRlUGF0aCkge1xuICAgIHRoaXMuX2FwaVJvb3RQYXRoID0gYXBpUm9vdFBhdGg7XG4gIH1cbiAgZ2V0IGFwaVJvb3RQYXRoKCk6IEFic29sdXRlUGF0aCB7XG4gICAgaWYgKHRoaXMuX2FwaVJvb3RQYXRoID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTb25hbXUgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fYXBpUm9vdFBhdGg7XG4gIH1cbiAgZ2V0IGFwcFJvb3RQYXRoKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuYXBpUm9vdFBhdGguc3BsaXQocGF0aC5zZXApLnNsaWNlKDAsIC0xKS5qb2luKHBhdGguc2VwKTtcbiAgfVxuXG4gIHByaXZhdGUgX2RiQ29uZmlnOiBTb25hbXVEQkNvbmZpZyB8IG51bGwgPSBudWxsO1xuICBzZXQgZGJDb25maWcoZGJDb25maWc6IFNvbmFtdURCQ29uZmlnKSB7XG4gICAgdGhpcy5fZGJDb25maWcgPSBkYkNvbmZpZztcbiAgfVxuICBnZXQgZGJDb25maWcoKTogU29uYW11REJDb25maWcge1xuICAgIGlmICh0aGlzLl9kYkNvbmZpZyA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2RiQ29uZmlnO1xuICB9XG5cbiAgcHJpdmF0ZSBfc3luY2VyOiBTeW5jZXIgfCBudWxsID0gbnVsbDtcbiAgc2V0IHN5bmNlcihzeW5jZXI6IFN5bmNlcikge1xuICAgIHRoaXMuX3N5bmNlciA9IHN5bmNlcjtcbiAgfVxuICBnZXQgc3luY2VyKCk6IFN5bmNlciB7XG4gICAgaWYgKHRoaXMuX3N5bmNlciA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3N5bmNlcjtcbiAgfVxuXG4gIHByaXZhdGUgX2NvbmZpZzogU29uYW11Q29uZmlnIHwgbnVsbCA9IG51bGw7XG4gIHNldCBjb25maWcoY29uZmlnOiBTb25hbXVDb25maWcpIHtcbiAgICB0aGlzLl9jb25maWcgPSBjb25maWc7XG4gIH1cbiAgZ2V0IGNvbmZpZygpOiBTb25hbXVDb25maWcge1xuICAgIGlmICh0aGlzLl9jb25maWcgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNvbmFtdSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRcIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9jb25maWc7XG4gIH1cblxuICBwdWJsaWMgcmVhZG9ubHkgc2VjcmV0czogU29uYW11U2VjcmV0cyA9IGdldFNlY3JldHMoKTtcblxuICBwcml2YXRlIF9zdG9yYWdlOiBTdG9yYWdlTWFuYWdlciB8IG51bGwgPSBudWxsO1xuICAvKipcbiAgICogU3RvcmFnZU1hbmFnZXIg7J247Iqk7YS07IqkXG4gICAqL1xuICBnZXQgc3RvcmFnZSgpOiBTdG9yYWdlTWFuYWdlciB7XG4gICAgaWYgKCF0aGlzLl9zdG9yYWdlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTdG9yYWdlIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZC4gQ2hlY2sgc3RvcmFnZSBjb25maWcuXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fc3RvcmFnZTtcbiAgfVxuXG4gIHByaXZhdGUgX2NhY2hlOiBDYWNoZU1hbmFnZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqXG4gICAqIENhY2hlTWFuYWdlciDsnbjsiqTthLTsiqQgKEJlbnRvQ2FjaGUpXG4gICAqL1xuICBnZXQgY2FjaGUoKTogQ2FjaGVNYW5hZ2VyIHtcbiAgICBpZiAoIXRoaXMuX2NhY2hlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYWNoZSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQuIENoZWNrIGNhY2hlIGNvbmZpZyBpbiBzb25hbXUuY29uZmlnLnRzLlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2NhY2hlO1xuICB9XG5cbiAgcHJpdmF0ZSBfd29ya2Zsb3dzOiBXb3JrZmxvd01hbmFnZXIgfCBudWxsID0gbnVsbDtcbiAgZ2V0IHdvcmtmbG93cygpOiBXb3JrZmxvd01hbmFnZXIge1xuICAgIGlmICh0aGlzLl93b3JrZmxvd3MgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNvbmFtdSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3dvcmtmbG93cztcbiAgfVxuXG4gIHByaXZhdGUgX2F1dGg6IEF1dGg8QmV0dGVyQXV0aE9wdGlvbnM+IHwgbnVsbCA9IG51bGw7XG4gIGdldCBhdXRoKCk6IEF1dGg8QmV0dGVyQXV0aE9wdGlvbnM+IHtcbiAgICBpZiAoIXRoaXMuX2F1dGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkF1dGggaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkLiBDaGVjayBhdXRoIGNvbmZpZyBpbiBzb25hbXUuY29uZmlnLnRzLlwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2F1dGg7XG4gIH1cblxuICBwcml2YXRlIF9kZXZWaXRlc3RNYW5hZ2VyOiBEZXZWaXRlc3RNYW5hZ2VyIHwgbnVsbCA9IG51bGw7XG4gIGdldCBkZXZWaXRlc3RNYW5hZ2VyKCk6IERldlZpdGVzdE1hbmFnZXIgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fZGV2Vml0ZXN0TWFuYWdlcjtcbiAgfVxuICBzZXQgZGV2Vml0ZXN0TWFuYWdlcihtYW5hZ2VyOiBEZXZWaXRlc3RNYW5hZ2VyIHwgbnVsbCkge1xuICAgIHRoaXMuX2RldlZpdGVzdE1hbmFnZXIgPSBtYW5hZ2VyO1xuICB9XG5cbiAgLy8gU29uYW116rCAIHJ1bnRpbWXsnYQg7KeB7KCRIOyGjOycoO2VtCByZWdpc3RyeS9jb25uZWN0aW9uIGxpZmVjeWNsZeydhCDslaDtlIzrpqzsvIDsnbTshZgg7IiY66qF7KO86riw7JmAIOuPmeq4sO2ZlO2VqFxuICBwcml2YXRlIF93ZWJzb2NrZXRSdW50aW1lOiBXZWJTb2NrZXRSdW50aW1lIHwgbnVsbCA9IG51bGw7XG4gIC8vIOqwmeydgCBGYXN0aWZ5IOyduOyKpO2EtOyKpOyXkCBAZmFzdGlmeS93ZWJzb2NrZXTsnYQg7KSR67O1IOuTseuhne2VmOuKlCDqsoPsnYQgV2Vha1NldOycvOuhnCDssKjri6jtlahcbiAgcHJpdmF0ZSByZWFkb25seSB3ZWJzb2NrZXRQbHVnaW5TZXJ2ZXJzID0gbmV3IFdlYWtTZXQ8XG4gICAgRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT5cbiAgPigpO1xuICBnZXQgd2Vic29ja2V0UnVudGltZSgpOiBXZWJTb2NrZXRSdW50aW1lIHtcbiAgICBpZiAoIXRoaXMuX3dlYnNvY2tldFJ1bnRpbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIldlYlNvY2tldCBydW50aW1lIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZC5cIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl93ZWJzb2NrZXRSdW50aW1lO1xuICB9XG4gIHNldCB3ZWJzb2NrZXRSdW50aW1lKHJ1bnRpbWU6IFdlYlNvY2tldFJ1bnRpbWUgfCBudWxsKSB7XG4gICAgdGhpcy5fd2Vic29ja2V0UnVudGltZSA9IHJ1bnRpbWU7XG4gIH1cblxuICAvLyBITVIg7LKY66asOiDtjIzsnbwg7Iuc7Iqk7YWcIOqwkOyLnCArIEhNUi9zeW5jIOyCrOydtO2BtCDsi6TtlonsnYAgd2F0Y2hlciDrqqjrk4jroZwg7JyE7J6E7ZWp64uI64ukLlxuICBwdWJsaWMgd2F0Y2hlcjogRlNXYXRjaGVyIHwgbnVsbCA9IG51bGw7XG5cbiAgcHVibGljIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlIHwgbnVsbCA9IG51bGw7XG5cbiAgYXN5bmMgaW5pdEZvclRlc3RpbmcoKSB7XG4gICAgYXdhaXQgdGhpcy5pbml0KHRydWUsIGZhbHNlLCB1bmRlZmluZWQsIHRydWUpO1xuICB9XG5cbiAgYXN5bmMgaW5pdChcbiAgICBkb1NpbGVudDogYm9vbGVhbiA9IGZhbHNlLFxuICAgIGVuYWJsZVN5bmM6IGJvb2xlYW4gPSB0cnVlLFxuICAgIGFwaVJvb3RQYXRoPzogQWJzb2x1dGVQYXRoLFxuICAgIGZvclRlc3Rpbmc6IGJvb2xlYW4gPSBmYWxzZSxcbiAgKSB7XG4gICAgdGhpcy5mb3JUZXN0aW5nID0gZm9yVGVzdGluZztcblxuICAgIGlmICh0aGlzLmlzSW5pdGlhbGl6ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBpbml0U3RhcnQgPSBwZXJmb3JtYW5jZS5ub3coKTtcblxuICAgIC8vIEFQSSDro6jtirgg7Yyo7IqkXG4gICAgY29uc3QgeyBmaW5kQXBpUm9vdFBhdGggfSA9IGF3YWl0IGltcG9ydChcIi4uL3V0aWxzL3V0aWxzXCIpO1xuICAgIHRoaXMuYXBpUm9vdFBhdGggPSBhcGlSb290UGF0aCA/PyBmaW5kQXBpUm9vdFBhdGgoKTtcbiAgICBjb25zdCBiYXNlRW52QmVmb3JlQ29uZmlnTG9hZCA9IHsgLi4ucHJvY2Vzcy5lbnYgfTtcblxuICAgIC8vIOyEpOygleydhCDroZzrlKntlZjripQg6rKD67aA7YSwIOyLnOyekVxuICAgIGNvbnN0IGNvbmZpZ1N0YXJ0ID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgY29uc3QgeyBsb2FkQ29uZmlnIH0gPSBhd2FpdCBpbXBvcnQoXCIuL2NvbmZpZ1wiKTtcbiAgICB0aGlzLmNvbmZpZyA9IGF3YWl0IGxvYWRDb25maWcodGhpcy5hcGlSb290UGF0aCk7XG4gICAgY29uc3QgY29uZmlnVGltZSA9IHBlcmZvcm1hbmNlLm5vdygpIC0gY29uZmlnU3RhcnQ7XG4gICAgc2V0U0RDb25maWcodGhpcy5jb25maWcuaTE4bik7XG4gICAgLy8gc29uYW11LmNvbmZpZy50cyDquLDrs7jqsJIg7ISk7KCVXG4gICAgdGhpcy5jb25maWcuZGF0YWJhc2UuZGF0YWJhc2UgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS5kYXRhYmFzZSA/PyBcInBnXCI7XG4gICAgdGhpcy5jb25maWcuZGF0YWJhc2UuZGVmYXVsdE9wdGlvbnMgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS5kZWZhdWx0T3B0aW9ucyA/PyB7fTtcbiAgICB0aGlzLmNvbmZpZy5kYXRhYmFzZS5kZWZhdWx0T3B0aW9ucy5jbGllbnQgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS5kYXRhYmFzZSA/PyBcInBnXCI7XG5cbiAgICAvLyDroZzquYUg7ISk7KCVXG4gICAgY29uc3QgeyBjb25maWd1cmVMb2dUYXBlIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9sb2dnZXIvY29uZmlndXJlXCIpO1xuICAgIGlmICh0aGlzLmNvbmZpZy5sb2dnaW5nICE9PSBmYWxzZSkge1xuICAgICAgYXdhaXQgY29uZmlndXJlTG9nVGFwZSh7XG4gICAgICAgIC4uLnRoaXMuY29uZmlnLmxvZ2dpbmcsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBEQiDroZzrk5xcbiAgICBjb25zdCB7IERCIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9kYXRhYmFzZS9kYlwiKTtcbiAgICBjb25zdCB7IGlzTG9jYWw6IGlzTG9jYWxFbnZpcm9ubWVudCB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvY29udHJvbGxlclwiKTtcbiAgICBjb25zdCBlbnZpcm9ubWVudFNuYXBzaG90cyA9IGlzTG9jYWxFbnZpcm9ubWVudCgpXG4gICAgICA/IHJlYWRBbGxFbnZpcm9ubWVudFNuYXBzaG90cyh0aGlzLmFwaVJvb3RQYXRoLCBiYXNlRW52QmVmb3JlQ29uZmlnTG9hZClcbiAgICAgIDogdW5kZWZpbmVkO1xuICAgIHRoaXMuZGJDb25maWcgPSBEQi5nZW5lcmF0ZURCQ29uZmlnKFxuICAgICAgdGhpcy5jb25maWcuZGF0YWJhc2UsXG4gICAgICB0aGlzLmNvbmZpZy5wcm9qZWN0TmFtZSxcbiAgICAgIGVudmlyb25tZW50U25hcHNob3RzLFxuICAgICk7XG4gICAgREIuc2V0Q29uZmlnKHRoaXMuZGJDb25maWcpO1xuXG4gICAgLy8gRW50aXR5IOuhnOuTnFxuICAgIC8vIO2FjOyKpO2KuOyXkOyEnOuPhCBFbnRpdHkg7KCV67O064qUIO2VhOyalO2VqeuLiOuLpC5cbiAgICAvLyB1cHNlcnTqsIAg7KCc64yA66GcIOyekeuPme2VmOugpOuptCBlbnRpdHnsnZggdW5pcXVlIGluZGV4IOygleuztOqwgCDtlYTsmpTtlZjquLAg65WM66y47J6F64uI64ukLlxuICAgIGNvbnN0IHsgRW50aXR5TWFuYWdlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vZW50aXR5L2VudGl0eS1tYW5hZ2VyXCIpO1xuICAgIGF3YWl0IEVudGl0eU1hbmFnZXIuYXV0b2xvYWQoZG9TaWxlbnQpO1xuXG4gICAgLy8gQ2FjaGUg7LSI6riw7ZmUXG4gICAgYXdhaXQgdGhpcy5pbml0aWFsaXplQ2FjaGUodGhpcy5jb25maWcuc2VydmVyLmNhY2hlLCBmb3JUZXN0aW5nKTtcblxuICAgIC8vIEJldHRlckF1dGgg7LSI6riw7ZmUXG4gICAgY29uc3QgYXV0aENvbmZpZyA9IHRoaXMuY29uZmlnLnNlcnZlci5hdXRoO1xuICAgIGlmIChhdXRoQ29uZmlnKSB7XG4gICAgICAvLyDsgqzsmqnsnpAg7ISk7KCV6rO8IOq4sOuzuOqwkuydhCBtZXJnZVxuICAgICAgY29uc3QgbWVyZ2VkRmllbGRNYXBwaW5ncyA9IG1lcmdlKEJBU0VfRklFTERfTUFQUElOR1MsIGF1dGhDb25maWcpO1xuXG4gICAgICAvLyBiZXR0ZXItYXV0aCDsnbjsiqTthLTsiqQg7IOd7ISxXG4gICAgICBjb25zdCB7IGJldHRlckF1dGggfSA9IGF3YWl0IGltcG9ydChcImJldHRlci1hdXRoXCIpO1xuICAgICAgY29uc3QgeyBzb25hbXVLbmV4QWRhcHRlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vYXV0aC9rbmV4LWFkYXB0ZXJcIik7XG5cbiAgICAgIGNvbnN0IGF1dGhPcHRpb25zOiBCZXR0ZXJBdXRoT3B0aW9ucyA9IHtcbiAgICAgICAgZGF0YWJhc2U6IHNvbmFtdUtuZXhBZGFwdGVyKCksXG4gICAgICAgIC4uLm1lcmdlZEZpZWxkTWFwcGluZ3MsXG4gICAgICB9O1xuICAgICAgdGhpcy5fYXV0aCA9IGJldHRlckF1dGgoYXV0aE9wdGlvbnMpO1xuICAgIH1cblxuICAgIC8vIO2FjOyKpO2MheyduCDqsr3smrAg7Iux7YGsIOyXhuydtCDspJHri6hcbiAgICBpZiAoZm9yVGVzdGluZykge1xuICAgICAgdGhpcy5pc0luaXRpYWxpemVkID0gdHJ1ZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBUYXNrIOuTseuhnVxuICAgIGF3YWl0IHRoaXMuaW5pdGlhbGl6ZVdvcmtmbG93cyh0aGlzLmNvbmZpZy50YXNrcyk7XG5cbiAgICAvLyBTeW5jZXJcbiAgICBjb25zdCB7IFN5bmNlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3luY2VyL3N5bmNlclwiKTtcbiAgICB0aGlzLnN5bmNlciA9IG5ldyBTeW5jZXIoKTtcblxuICAgIC8vIEF1dG9sb2FkOiBNb2RlbHMgLyBUeXBlcyAvIEFQSXMgLyBXb3JrZmxvd3MgLyBUZW1wbGF0ZXMgLyBTU1IgUm91dGVzXG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuYXV0b2xvYWRUeXBlcygpO1xuICAgIGF3YWl0IHRoaXMuc3luY2VyLmF1dG9sb2FkTW9kZWxzKCk7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuYXV0b2xvYWRBcGlzKCk7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuYXV0b2xvYWRXb3JrZmxvd3MoKTtcbiAgICBjb25zdCB7IFRlbXBsYXRlTWFuYWdlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdGVtcGxhdGVcIik7XG4gICAgYXdhaXQgVGVtcGxhdGVNYW5hZ2VyLmF1dG9sb2FkKCk7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuYXV0b2xvYWRTc3JSb3V0ZXMoKTtcblxuICAgIGNvbnN0IHsgaXNMb2NhbCwgaXNUZXN0LCBpc0hvdFJlbG9hZFNlcnZlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvY29udHJvbGxlclwiKTtcbiAgICBpZiAoaXNMb2NhbCgpICYmICFpc1Rlc3QoKSAmJiBpc0hvdFJlbG9hZFNlcnZlcigpICYmIGVuYWJsZVN5bmMpIHtcbiAgICAgIGF3YWl0IHRoaXMuc3luY2VyLnN5bmMoKTtcbiAgICAgIGF3YWl0IHRoaXMuc3RhcnRXYXRjaGVyKCk7XG4gICAgfVxuXG4gICAgdGhpcy5pc0luaXRpYWxpemVkID0gdHJ1ZTtcbiAgICB0aGlzLl9pbml0RWxhcHNlZCA9IHBlcmZvcm1hbmNlLm5vdygpIC0gaW5pdFN0YXJ0O1xuICAgIHRoaXMuX2NvbmZpZ0VsYXBzZWQgPSBjb25maWdUaW1lO1xuICB9XG5cbiAgcHJpdmF0ZSBfaW5pdEVsYXBzZWQgPSAwO1xuICBwcml2YXRlIF9jb25maWdFbGFwc2VkID0gMDtcblxuICBhc3luYyBjcmVhdGVTZXJ2ZXIoaW5pdE9wdGlvbnM/OiB7IGVuYWJsZVN5bmM/OiBib29sZWFuOyBkb1NpbGVudD86IGJvb2xlYW4gfSkge1xuICAgIGlmICghdGhpcy5pc0luaXRpYWxpemVkKSB7XG4gICAgICBhd2FpdCB0aGlzLmluaXQoaW5pdE9wdGlvbnM/LmRvU2lsZW50LCBpbml0T3B0aW9ucz8uZW5hYmxlU3luYyk7XG4gICAgfVxuXG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuY29uZmlnLnNlcnZlcjtcbiAgICBjb25zdCB7IGRlZmF1bHQ6IGZhc3RpZnkgfSA9IGF3YWl0IGltcG9ydChcImZhc3RpZnlcIik7XG4gICAgY29uc3QgeyBnZXRMb2dUYXBlRmFzdGlmeUxvZ2dlciB9ID0gYXdhaXQgaW1wb3J0KFwiQGxvZ3RhcGUvZmFzdGlmeVwiKTtcbiAgICBjb25zdCBzZXJ2ZXIgPSBmYXN0aWZ5KHtcbiAgICAgIC4uLm9wdGlvbnMuZmFzdGlmeSxcbiAgICAgIGxvZ2dlcjpcbiAgICAgICAgdGhpcy5jb25maWcubG9nZ2luZyAhPT0gZmFsc2VcbiAgICAgICAgICA/IGdldExvZ1RhcGVGYXN0aWZ5TG9nZ2VyKHtcbiAgICAgICAgICAgICAgY2F0ZWdvcnk6IHRoaXMuY29uZmlnLmxvZ2dpbmc/LmZhc3RpZnlDYXRlZ29yeSA/PyBbXCJmYXN0aWZ5XCJdLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICB9KTtcbiAgICB0aGlzLnNlcnZlciA9IHNlcnZlcjtcbiAgICB0aGlzLndlYnNvY2tldFJ1bnRpbWUgPSBuZXcgV2ViU29ja2V0UnVudGltZShvcHRpb25zLndlYnNvY2tldCk7XG5cbiAgICAvLyBTdG9yYWdlIOyEpOyglSDihpIgU3RvcmFnZU1hbmFnZXIg7IOd7ISxXG4gICAgaWYgKG9wdGlvbnMuc3RvcmFnZSkge1xuICAgICAgY29uc3QgeyBTdG9yYWdlTWFuYWdlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3RvcmFnZS9zdG9yYWdlLW1hbmFnZXJcIik7XG4gICAgICB0aGlzLl9zdG9yYWdlID0gbmV3IFN0b3JhZ2VNYW5hZ2VyKG9wdGlvbnMuc3RvcmFnZSk7XG4gICAgfVxuXG4gICAgLy8g7ZSM65+s6re47J24IOuTseuhnVxuICAgIGlmIChvcHRpb25zLnBsdWdpbnMpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJQbHVnaW5zKHNlcnZlciwgb3B0aW9ucy5wbHVnaW5zKTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5hdXRoKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlZ2lzdGVyQmV0dGVyQXV0aChzZXJ2ZXIsIG9wdGlvbnMuYXV0aCk7XG4gICAgfVxuXG4gICAgLy8gQVBJIOudvOyasO2MhSDshKTsoJVcbiAgICBhd2FpdCB0aGlzLndpdGhGYXN0aWZ5KHNlcnZlciwgb3B0aW9ucy5hcGlDb25maWcsIHtcbiAgICAgIGVuYWJsZVN5bmM6IGluaXRPcHRpb25zPy5lbmFibGVTeW5jLFxuICAgICAgZG9TaWxlbnQ6IGluaXRPcHRpb25zPy5kb1NpbGVudCxcbiAgICB9KTtcblxuICAgIC8vIOyEnOuyhCDsi5zsnpFcbiAgICBhd2FpdCB0aGlzLmJvb3Qoc2VydmVyLCBvcHRpb25zKTtcblxuICAgIGlmICghaW5pdE9wdGlvbnM/LmRvU2lsZW50KSB7XG4gICAgICB0aGlzLnByaW50U3RhcnR1cFN1bW1hcnkoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2VydmVyO1xuICB9XG5cbiAgYXN5bmMgd2l0aEZhc3RpZnkoXG4gICAgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2U8U2VydmVyLCBJbmNvbWluZ01lc3NhZ2UsIFNlcnZlclJlc3BvbnNlPixcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICAgb3B0aW9ucz86IHtcbiAgICAgIGVuYWJsZVN5bmM/OiBib29sZWFuO1xuICAgICAgZG9TaWxlbnQ/OiBib29sZWFuO1xuICAgIH0sXG4gICkge1xuICAgIGlmICghdGhpcy5pc0luaXRpYWxpemVkKSB7XG4gICAgICBhd2FpdCB0aGlzLmluaXQob3B0aW9ucz8uZG9TaWxlbnQsIG9wdGlvbnM/LmVuYWJsZVN5bmMpO1xuICAgIH1cblxuICAgIHRoaXMuc2VydmVyID0gc2VydmVyO1xuICAgIHRoaXMud2Vic29ja2V0UnVudGltZSA/Pz0gbmV3IFdlYlNvY2tldFJ1bnRpbWUodGhpcy5jb25maWcuc2VydmVyLndlYnNvY2tldCk7XG5cbiAgICAvLyB0aW1lem9uZSDshKTsoJVcbiAgICBjb25zdCB0aW1lem9uZSA9IHRoaXMuY29uZmlnLmFwaS50aW1lem9uZTtcbiAgICBpZiAodGltZXpvbmUpIHtcbiAgICAgIC8vIO2DgOyehOyhtOyXkCDrp57qsowg7J2R64u1IOuCoOynnCDsiqTtirjrp4HsnYQg67OA7ZmY7ZW07KO87Ja07JW8IO2VqeuLiOuLpC5cbiAgICAgIC8vIOqwgOuguSB0aW1lem9uZeydtCBcIkFzaWEvU2VvdWxcIiDsnbTrqbRcbiAgICAgIC8vIFwiMjAyNS0xMS0yMVQwMDowMDowMC4wMDBaXCIg66W8IFwiMjAyNS0xMS0yMVQwOTowMDowMCswOTowMFwiIOycvOuhnCDrs4DtmZjtlbTso7zslrTslbwg7ZWp64uI64ukLlxuICAgICAgY29uc3QgeyBmb3JtYXRJblRpbWVab25lIH0gPSBhd2FpdCBpbXBvcnQoXCJkYXRlLWZucy10elwiKTtcblxuICAgICAgLy8gSVNPIDg2MDEg64Kg7KecIO2YleyLnSDsoJXqt5zsi50gKOyYiDogMjAyNC0wMS0xNVQwOTozMDowMC4wMDBaKVxuICAgICAgY29uc3QgSVNPX0RBVEVfUkVHRVggPSAvXlxcZHs0fS1cXGR7Mn0tXFxkezJ9VFxcZHsyfTpcXGR7Mn06XFxkezJ9KFxcLlxcZHszfSk/WiQvO1xuXG4gICAgICAvLyBU66W8IOuRmOufrOyLvCDsnpHsnYDrlLDsmLTtkZzqsIAg7JeG64uk66m0IFwiMjAyNS0xMS0xOTE3NjM1NDYxODkwMDAxODo1NjoyOSswOTowMFwi7JmAIOqwmeydgCDqsrDqs7zqsIAg64KY7Ji164uI64ukLlxuICAgICAgLy8g7J2064qUIGRhdGUtZm5zIO2KueyeheuLiOuLpC5cbiAgICAgIC8vIOydtOugh+qyjCDtlbTrj4Qg6rSc7LCu7Iq164uI64ukLiBcIjIwMjUtMTEtMTlUMTg6NTY6MjkrMDk6MDBcIiDrqqjslpHsnLzroZwg7J6YIOuCmOyYteuLiOuLpC5cbiAgICAgIGNvbnN0IERBVEVfRk9STUFUID0gXCJ5eXl5LU1NLWRkJ1QnSEg6bW06c3NYWFhcIjtcblxuICAgICAgc2VydmVyLnNldFJlcGx5U2VyaWFsaXplcigocGF5bG9hZCkgPT4ge1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkocGF5bG9hZCwgKF9rZXksIHZhbHVlKSA9PiB7XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiBJU09fREFURV9SRUdFWC50ZXN0KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZvcm1hdEluVGltZVpvbmUoXG4gICAgICAgICAgICAgIG5ldyBEYXRlKHZhbHVlKSxcbiAgICAgICAgICAgICAgdGltZXpvbmUgYXMgYCR7c3RyaW5nfS8ke3N0cmluZ31gLFxuICAgICAgICAgICAgICBEQVRFX0ZPUk1BVCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIC8vIFRpbWV6b25lIOuhnOq3uOuKlCBwcmludFN0YXJ0dXBTdW1tYXJ57JeQ7IScIO2Gte2VqSDstpzroKVcbiAgICB9XG5cbiAgICAvLyDsoITssrQg65287Jqw7YyFIOumrOyKpO2KuFxuICAgIHNlcnZlci5nZXQoXG4gICAgICBgJHt0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4fS9yb3V0ZXNgLFxuICAgICAgYXN5bmMgKF9yZXF1ZXN0LCBfcmVwbHkpOiBQcm9taXNlPHR5cGVvZiB0aGlzLnN5bmNlci5hcGlzPiA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnN5bmNlci5hcGlzO1xuICAgICAgfSxcbiAgICApO1xuXG4gICAgLy8gSGVhbHRoY2hlY2sgQVBJXG4gICAgc2VydmVyLmdldChcbiAgICAgIGAke3RoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXh9L2hlYWx0aGNoZWNrYCxcbiAgICAgIGFzeW5jIChfcmVxdWVzdCwgX3JlcGx5KTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgICAgICAgcmV0dXJuIFwib2tcIjtcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIC8vIFNvbmFtdSBVSSBBUEkgKOuhnOy7rCDtmZjqsr3sl5DshJzrp4wpXG4gICAgY29uc3QgeyBpc0xvY2FsIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi91dGlscy9jb250cm9sbGVyXCIpO1xuICAgIGlmIChpc0xvY2FsKCkpIHtcbiAgICAgIGNvbnN0IHsgc29uYW11VUlBcGlQbHVnaW4gfSA9IGF3YWl0IGltcG9ydChcIi4uL3VpL2FwaVwiKTtcbiAgICAgIHNlcnZlci5yZWdpc3Rlcihzb25hbXVVSUFwaVBsdWdpbik7XG4gICAgfVxuXG4gICAgLy8gRGV2UnVubmVyIO2FjOyKpO2KuCDsl5Trk5ztj6zsnbjtirggKOuhnOy7rCDtmZjqsr0gKyBkZXZSdW5uZXIg7Zmc7ISx7ZmUIOyLnClcbiAgICBpZiAoaXNMb2NhbCgpICYmIHRoaXMuY29uZmlnLnRlc3Q/LmRldlJ1bm5lcj8uZW5hYmxlZCkge1xuICAgICAgY29uc3QgeyByZWdpc3RlckRldlRlc3RSb3V0ZXMgfSA9IGF3YWl0IGltcG9ydChcIi4uL3Rlc3RpbmcvZGV2LXRlc3Qtcm91dGVzXCIpO1xuICAgICAgYXdhaXQgcmVnaXN0ZXJEZXZUZXN0Um91dGVzKHNlcnZlciwgdGhpcy5jb25maWcudGVzdC5kZXZSdW5uZXIpO1xuICAgIH1cblxuICAgIGNvbnN0IHdlYlBhdGggPSBwYXRoLmpvaW4odGhpcy5hcHBSb290UGF0aCwgXCJ3ZWJcIik7XG4gICAgY29uc3QgaGFzV2ViID0gYXdhaXQgZXhpc3RzKHdlYlBhdGgpO1xuXG4gICAgLy8g7KCE7JetIGNvbXByZXNzIOyYteyFmCDqs4TsgrAgKHJvdXRlLmNvbXByZXNzOiB0cnVl7J28IOuVjCDsgqzsmqkpXG4gICAgY29uc3QgcGx1Z2luQ29tcHJlc3MgPSB0aGlzLmNvbmZpZy5zZXJ2ZXIucGx1Z2lucz8uY29tcHJlc3M7XG4gICAgY29uc3QgZ2xvYmFsQ29tcHJlc3NPcHRpb25zOiBDb21wcmVzc09wdGlvbnMgfCB1bmRlZmluZWQgPSBwbHVnaW5Db21wcmVzc1xuICAgICAgPyBwbHVnaW5Db21wcmVzcyA9PT0gdHJ1ZVxuICAgICAgICA/IHsgdGhyZXNob2xkOiAxMDI0LCBlbmNvZGluZ3M6IFtcImJyXCIsIFwiZ3ppcFwiLCBcImRlZmxhdGVcIl0gfVxuICAgICAgICA6IHtcbiAgICAgICAgICAgIHRocmVzaG9sZDogcGx1Z2luQ29tcHJlc3MudGhyZXNob2xkLFxuICAgICAgICAgICAgZW5jb2RpbmdzOiBwbHVnaW5Db21wcmVzcy5lbmNvZGluZ3MsXG4gICAgICAgICAgICBjdXN0b21UeXBlczogcGx1Z2luQ29tcHJlc3MuY3VzdG9tVHlwZXMsXG4gICAgICAgICAgfVxuICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAoaXNMb2NhbCgpKSB7XG4gICAgICAvLyDroZzsu6wg6rCc67CcIO2ZmOqyvTogY2F0Y2gtYWxs66GcIEFQSeulvCDrj5nsoIEg66ek7Lmt7ZWY7JesIEhNUuydhCDsp4Dsm5Dtlanri4jri6QuXG4gICAgICAvLyBTT05BTVVfRElTQUJMRV9JTlRFR1JBVEVEX1dFQj15ZXProZwg7ISk7KCV7ZWY66m0IGRldl9hcGkg66qo65Oc7JeQ7IScIFZpdGUg7Ya17ZWp7J2EIOu5hO2ZnOyEse2ZlO2VoCDsiJgg7J6I7Iq164uI64ukLlxuICAgICAgY29uc3QgZGlzYWJsZUludGVncmF0ZWRXZWIgPSBwcm9jZXNzLmVudi5TT05BTVVfRElTQUJMRV9JTlRFR1JBVEVEX1dFQiA9PT0gXCJ5ZXNcIjtcbiAgICAgIGlmIChoYXNXZWIgJiYgIWRpc2FibGVJbnRlZ3JhdGVkV2ViKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuc2V0dXBEZXZTZXJ2ZXJXaXRoVml0ZShzZXJ2ZXIsIHdlYlBhdGgsIGNvbmZpZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNldHVwRGV2U2VydmVyKHNlcnZlciwgY29uZmlnKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8g7ZSE66Gc642V7IWYIO2ZmOqyvTog6rCc67OEIEFQSSDrnbzsmrDtirggKyDsoJXsoIEg7YyM7J28IOyEnOu5mVxuICAgICAgZm9yIChjb25zdCBhcGkgb2YgdGhpcy5zeW5jZXIuYXBpcykge1xuICAgICAgICBpZiAodGhpcy5zeW5jZXIubW9kZWxzW2FwaS5tb2RlbE5hbWVdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYOygleydmOuQmOyngCDslYrsnYAg66qo64247JeQIOygkeq3vCAke2FwaS5tb2RlbE5hbWV9YCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBAd2Vic29ja2V0IHJvdXRl64qUIHdzSGFuZGxlcuuhnCDrk7HroZ3tlZjqs6AsIOqwmeydgCBwYXRo7J2YIOydvOuwmCBIVFRQIEdFVOydgCA0MjYg7J2R64u17Jy866GcIHVwZ3JhZGXrpbwg6rCV7KCc7ZWoXG4gICAgICAgIGlmIChhcGkud2Vic29ja2V0T3B0aW9ucykge1xuICAgICAgICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICAgICAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgICAgICAgICB1cmw6IHRoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXggKyBhcGkucGF0aCxcbiAgICAgICAgICAgIGhhbmRsZXI6IHRoaXMuY3JlYXRlV2ViU29ja2V0VXBncmFkZVJlcXVpcmVkSGFuZGxlcigpLFxuICAgICAgICAgICAgd3NIYW5kbGVyOiB0aGlzLmNyZWF0ZVdlYlNvY2tldEhhbmRsZXIoYXBpLCBjb25maWcpLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgc2VydmVyLnJvdXRlKHtcbiAgICAgICAgICBtZXRob2Q6IGFwaS5vcHRpb25zLmh0dHBNZXRob2QgPz8gXCJHRVRcIixcbiAgICAgICAgICB1cmw6IHRoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXggKyBhcGkucGF0aCxcbiAgICAgICAgICBoYW5kbGVyOiB0aGlzLmNyZWF0ZUFwaUhhbmRsZXIoYXBpLCBjb25maWcpLFxuICAgICAgICAgIGNvbXByZXNzOiB0b0Zhc3RpZnlDb21wcmVzc09wdGlvbihhcGkub3B0aW9ucy5jb21wcmVzcywgZ2xvYmFsQ29tcHJlc3NPcHRpb25zKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIO2UhOuhnOuNleyFmOyXkOyEnOuKlCB3ZWIg7IaM7IqkKGFwcFJvb3Qvd2ViKSDsnKDrrLTsmYAg66y06rSA7ZWY6rKMLFxuICAgICAgLy8gYXBpL3dlYi1kaXN0IOyhtOyerCDsl6zrtoDrpbwgc2V0dXBTdGF0aWNXZWJTZXJ2ZXIg64K067aA7JeQ7IScIO2MkOuLqO2VqeuLiOuLpC5cbiAgICAgIGF3YWl0IHRoaXMuc2V0dXBTdGF0aWNXZWJTZXJ2ZXIoc2VydmVyLCBjb25maWcsIGdsb2JhbENvbXByZXNzT3B0aW9ucyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIGRldiDrqqjrk5wg6rO17Ya1OiBjYXRjaC1hbGzsl5DshJwgc3luY2VyLmFwaXPrpbwg64+Z7KCB7Jy866GcIO2DkOyDie2VmOyXrCBBUEkg7JqU7LKt7J2EIOyymOumrO2VqeuLiOuLpC5cbiAgICogc2VydmVyLnJvdXRlKCnroZwg6rCc67OEIOuTseuhne2VmOuptCBoYW5kbGVy6rCAIOqzoOygleuQmOyWtCBITVLsnbQg64+Z7J6R7ZWY7KeAIOyViuycvOuvgOuhnCxcbiAgICog66ekIOyalOyyreuniOuLpCBzeW5jZXIuYXBpc+ulvCDsobDtmoztlZjripQg7J20IOuwqeyLneydhCDsgqzsmqntlanri4jri6QuXG4gICAqXG4gICAqIOyalOyyreydtCAvYXBpKOygle2Zle2eiOuKlCB0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4KeuhnCDsi5zsnpHtlZjsp4Ag7JWK64qUIOqyveyasOudvOuptCBudWxs7J2EIOuwmO2ZmO2VmOupsCDrgZ3rg4Xri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGhhbmRsZURldkFwaVJlcXVlc3QoXG4gICAgcmVxdWVzdDogRmFzdGlmeVJlcXVlc3QsXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICApOiAoKHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LCByZXBseTogRmFzdGlmeVJlcGx5KSA9PiBQcm9taXNlPHVua25vd24+KSB8IG51bGwge1xuICAgIGNvbnN0IG1hdGNoZWRBcGkgPSB0aGlzLmZpbmRNYXRjaGVkQXBpKHJlcXVlc3QpO1xuXG4gICAgaWYgKCFtYXRjaGVkQXBpKSB7XG4gICAgICB0aHJvdyBuZXcgTm90Rm91bmRFeGNlcHRpb24oU0QoXCJlcnJvci5hcGkubm90Rm91bmRcIikpO1xuICAgIH1cblxuICAgIC8vIHdlYnNvY2tldCByb3V0ZeulvCDsnbzrsJggSFRUUOuhnCDsp4HsoJEg7Zi47Lac7ZWcIOqyveyasCA0MjbsnYQg64+M66Ck7KSYIHVwZ3JhZGUg7JeG7J20IOygkeq3vO2VmOuKlCDqsoPsnYQg7LCo64uo7ZWoXG4gICAgaWYgKG1hdGNoZWRBcGkud2Vic29ja2V0T3B0aW9ucykge1xuICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlV2ViU29ja2V0VXBncmFkZVJlcXVpcmVkSGFuZGxlcigpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNyZWF0ZUFwaUhhbmRsZXIobWF0Y2hlZEFwaSwgY29uZmlnKTtcbiAgfVxuXG4gIHByaXZhdGUgZmluZE1hdGNoZWRBcGkocmVxdWVzdDogRmFzdGlmeVJlcXVlc3QpOiBFeHRlbmRlZEFwaSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgdXJsID0gdGhpcy5nZXRQYXRobmFtZUZyb21VcmwocmVxdWVzdC51cmwpO1xuICAgIGNvbnN0IG1ldGhvZCA9IHJlcXVlc3QubWV0aG9kO1xuXG4gICAgaWYgKCF1cmwuc3RhcnRzV2l0aCh0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4KSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zeW5jZXIuYXBpcy5maW5kKChhcGkpID0+IHtcbiAgICAgIGlmICh0aGlzLnN5bmNlci5tb2RlbHNbYXBpLm1vZGVsTmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBjb25zdCBhcGlNZXRob2QgPSBhcGkub3B0aW9ucy5odHRwTWV0aG9kID8/IFwiR0VUXCI7XG4gICAgICBpZiAoYXBpTWV0aG9kICE9PSBtZXRob2QpIHJldHVybiBmYWxzZTtcblxuICAgICAgY29uc3QgZnVsbFBhdGggPSB0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4ICsgYXBpLnBhdGg7XG4gICAgICByZXR1cm4gdGhpcy5pc1BhdGhQYXR0ZXJuTWF0Y2goZnVsbFBhdGgsIHVybCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogZGV2IGFwaSDrqqjrk5w6IFZpdGUg7JeG7J20IEFQSSDrj5nsoIEg65287Jqw7YyF66eMIOygnOqzte2VqeuLiOuLpC5cbiAgICogSE1S7J2EIOychO2VtCBjYXRjaC1hbGzsl5DshJwg66ekIOyalOyyreuniOuLpCBzeW5jZXIuYXBpc+ulvCDsobDtmoztlanri4jri6QuXG4gICAqL1xuICBwcml2YXRlIHNldHVwRGV2U2VydmVyKFxuICAgIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT4sXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICApOiB2b2lkIHtcbiAgICAvLyB1cGdyYWRl64qUIOyLpOyniOyggeycvOuhnCBHRVTsl5DshJzrp4wg7ISx66a97ZWY66+A66GcIEdFVCArIHdzSGFuZGxlciDsmYAg6re4IOyZuCBtZXRob2Trpbwg67OE64+EIHJvdXRl66GcIOu2hOumrO2VqFxuICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICBtZXRob2Q6IFwiR0VUXCIsXG4gICAgICB1cmw6IGAke3RoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXh9LypgLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IGhhbmRsZXIgPSB0aGlzLmhhbmRsZURldkFwaVJlcXVlc3QocmVxdWVzdCwgY29uZmlnKTtcbiAgICAgICAgaWYgKGhhbmRsZXIpIHtcbiAgICAgICAgICByZXR1cm4gaGFuZGxlcihyZXF1ZXN0LCByZXBseSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8g65Ox66Gd65CcIEFQSeyZgCDsnbzsuZjtlZjsp4Ag7JWK64qUIOyalOyyreyXkCDrjIDtlZwgZmFsbGJhY2vsnoXri4jri6QuXG4gICAgICAgIHRocm93IG5ldyBOb3RGb3VuZEV4Y2VwdGlvbihTRChcImVycm9yLmFwaS5ub3RGb3VuZFwiKSk7XG4gICAgICB9LFxuICAgICAgd3NIYW5kbGVyOiBhc3luYyAoY29ubmVjdGlvbiwgcmVxdWVzdCkgPT4ge1xuICAgICAgICBhd2FpdCB0aGlzLmhhbmRsZURldldlYlNvY2tldFJlcXVlc3QoY29ubmVjdGlvbi5zb2NrZXQsIHJlcXVlc3QsIGNvbmZpZyk7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgc2VydmVyLnJvdXRlKHtcbiAgICAgIG1ldGhvZDogW1wiSEVBRFwiLCBcIlBPU1RcIiwgXCJQVVRcIiwgXCJERUxFVEVcIiwgXCJQQVRDSFwiXSxcbiAgICAgIHVybDogYCR7dGhpcy5jb25maWcuYXBpLnJvdXRlLnByZWZpeH0vKmAsXG4gICAgICBoYW5kbGVyOiBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgaGFuZGxlciA9IHRoaXMuaGFuZGxlRGV2QXBpUmVxdWVzdChyZXF1ZXN0LCBjb25maWcpO1xuICAgICAgICBpZiAoaGFuZGxlcikge1xuICAgICAgICAgIHJldHVybiBoYW5kbGVyKHJlcXVlc3QsIHJlcGx5KTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgTm90Rm91bmRFeGNlcHRpb24oU0QoXCJlcnJvci5hcGkubm90Rm91bmRcIikpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgdml0ZVNlcnZlcjogYW55ID0gbnVsbDtcblxuICAvKipcbiAgICogZGV2IGFsbCDrqqjrk5w6IFZpdGUgRGV2IFNlcnZlcuulvCDthrXtlantlZjsl6wgQVBJICsgU1NSICsgQ1NS7J2EIOuqqOuRkCDsoJzqs7Xtlanri4jri6QuXG4gICAqIEFQSSDrj5nsoIEg66ek7Lmt7J2AIGhhbmRsZURldkFwaVJlcXVlc3Trpbwg6rO17Jyg7ZWp64uI64ukLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBzZXR1cERldlNlcnZlcldpdGhWaXRlKFxuICAgIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT4sXG4gICAgd2ViUGF0aDogc3RyaW5nLFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gQGZhc3RpZnkvbWlkZGllIOuTseuhnSAoQ29ubmVjdC1zdHlsZSBtaWRkbGV3YXJlIOyngOybkClcbiAgICBhd2FpdCBzZXJ2ZXIucmVnaXN0ZXIoKGF3YWl0IGltcG9ydChcIkBmYXN0aWZ5L21pZGRpZVwiKSkuZGVmYXVsdCk7XG5cbiAgICBjb25zdCB2aXRlID0gYXdhaXQgaW1wb3J0KFwidml0ZVwiKTtcbiAgICAvLyBAZmFzdGlmeS93ZWJzb2NrZXQg7ZSM65+s6re47J247J20IO2ZnOyEse2ZlOuQmOuptCBITVIgd2Vic29ja2V06rO8IHNlcnZlciBzb2NrZXTsnbQg7Lap64+M7ZWY66+A66GcIGRlZGljYXRlZCDtj6ztirjroZwg67aE66as7ZWoXG4gICAgY29uc3QgcmVxdWlyZXNEZWRpY2F0ZWRIbXJTZXJ2ZXIgPSBCb29sZWFuKHRoaXMuY29uZmlnLnNlcnZlci5wbHVnaW5zPy53cyk7XG4gICAgY29uc3QgaG1yID0gcmVzb2x2ZUludGVncmF0ZWRWaXRlSG1yT3B0aW9ucyh7XG4gICAgICBodHRwU2VydmVyOiBzZXJ2ZXIuc2VydmVyLFxuICAgICAgcmVxdWlyZXNEZWRpY2F0ZWRXZWJTb2NrZXRTZXJ2ZXI6IHJlcXVpcmVzRGVkaWNhdGVkSG1yU2VydmVyLFxuICAgIH0pO1xuXG4gICAgdGhpcy52aXRlU2VydmVyID0gYXdhaXQgdml0ZS5jcmVhdGVTZXJ2ZXIoe1xuICAgICAgcm9vdDogd2ViUGF0aCxcbiAgICAgIHNlcnZlcjoge1xuICAgICAgICBtaWRkbGV3YXJlTW9kZTogdHJ1ZSxcbiAgICAgICAgaG1yLFxuICAgICAgfSxcbiAgICAgIGFwcFR5cGU6IFwiY3VzdG9tXCIsXG4gICAgfSk7XG5cbiAgICAvLyBWaXRlIG1pZGRsZXdhcmUg65Ox66GdIChWaXRlIOyXkOyFiyDsspjrpqwpXG4gICAgc2VydmVyLnVzZSgocmVxLCByZXMsIG5leHQpID0+IHtcbiAgICAgIC8vIEFQSeyZgCBTb25hbXUgVUnripQgRmFzdGlmeSDrnbzsmrDtirjqsIAg7LKY66as7ZWY64+E66GdIHNraXBcbiAgICAgIGlmIChyZXEudXJsPy5zdGFydHNXaXRoKHRoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXgpIHx8IHJlcS51cmw/LnN0YXJ0c1dpdGgoXCIvc29uYW11LXVpXCIpKSB7XG4gICAgICAgIHJldHVybiBuZXh0KCk7XG4gICAgICB9XG4gICAgICAvLyDrgpjrqLjsp4DripQgVml0ZSBtaWRkbGV3YXJl66GcIOyghOuLrFxuICAgICAgcmV0dXJuIHRoaXMudml0ZVNlcnZlci5taWRkbGV3YXJlcyhyZXEsIHJlcywgbmV4dCk7XG4gICAgfSk7XG5cbiAgICAvLyBXUyB1cGdyYWRlIOqyveuhnChHRVQp7JmAIOydvOuwmCBIVFRQIOuplOyEnOuTnOulvCDrs4Trj4Qgcm91dGXroZwg67aE66as7ZW0IHdlYnNvY2tldCByb3V0ZeqwgCBIVE1MIGZhbGxiYWNr7JeQIOuoue2eiOyngCDslYrrj4TroZ0g7ZWoXG4gICAgc2VydmVyLnJvdXRlKHtcbiAgICAgIG1ldGhvZDogXCJHRVRcIixcbiAgICAgIHVybDogYCR7dGhpcy5jb25maWcuYXBpLnJvdXRlLnByZWZpeH0vKmAsXG4gICAgICBoYW5kbGVyOiBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5oYW5kbGVEZXZBcGlSZXF1ZXN0KHJlcXVlc3QsIGNvbmZpZyk7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0KHJlcXVlc3QsIHJlcGx5KTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBuZXcgTm90Rm91bmRFeGNlcHRpb24oU0QoXCJlcnJvci5hcGkubm90Rm91bmRcIikpO1xuICAgICAgfSxcbiAgICAgIHdzSGFuZGxlcjogYXN5bmMgKGNvbm5lY3Rpb24sIHJlcXVlc3QpID0+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVEZXZXZWJTb2NrZXRSZXF1ZXN0KGNvbm5lY3Rpb24uc29ja2V0LCByZXF1ZXN0LCBjb25maWcpO1xuICAgICAgfSxcbiAgICB9KTtcblxuICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICBtZXRob2Q6IFtcIkhFQURcIiwgXCJQT1NUXCIsIFwiUFVUXCIsIFwiREVMRVRFXCIsIFwiUEFUQ0hcIl0sXG4gICAgICB1cmw6IGAke3RoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXh9LypgLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuaGFuZGxlRGV2QXBpUmVxdWVzdChyZXF1ZXN0LCBjb25maWcpO1xuICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdChyZXF1ZXN0LCByZXBseSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IE5vdEZvdW5kRXhjZXB0aW9uKFNEKFwiZXJyb3IuYXBpLm5vdEZvdW5kXCIpKTtcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvLyBjYXRjaC1hbGwg65287Jqw7Yq47JeQ7IScIFNTUi9DU1Ig7LKY66asXG4gICAgLy8g6rCc67CcIO2ZmOqyveyXkOyEnOuKlCDrnbzsmrDtirjrs4QgY29tcHJlc3Mg7Ji17IWY7J2EIO2PrOq4sO2VmOqzoCBITVIg7J207KCQ7J2EIOy3qO2VqeuLiOuLpC5cbiAgICBzZXJ2ZXIucm91dGUoe1xuICAgICAgbWV0aG9kOiBbXCJHRVRcIiwgXCJIRUFEXCJdLFxuICAgICAgdXJsOiBcIi8qXCIsXG4gICAgICBoYW5kbGVyOiBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgdXJsID0gcmVxdWVzdC51cmw7XG5cbiAgICAgICAgLy8gMS4gU1NSIOudvOyasO2KuCDsspjrpqxcbiAgICAgICAgY29uc3QgeyBtYXRjaFNTUlJvdXRlLCByZW5kZXJTU1IgfSA9IGF3YWl0IGltcG9ydChcIi4uL3NzclwiKTtcbiAgICAgICAgY29uc3Qgc3NyTWF0Y2ggPSBtYXRjaFNTUlJvdXRlKHVybCk7XG4gICAgICAgIGlmIChzc3JNYXRjaCkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBbU1NSXSBNYXRjaGVkIHJvdXRlOiAke3Nzck1hdGNoLnJvdXRlLnBhdGh9YCk7XG4gICAgICAgICAgY29uc3QgaHRtbCA9IGF3YWl0IHJlbmRlclNTUihcbiAgICAgICAgICAgIHVybCxcbiAgICAgICAgICAgIHNzck1hdGNoLnJvdXRlLFxuICAgICAgICAgICAgc3NyTWF0Y2gucGFyYW1zLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIHJlcGx5LFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgdGhpcy52aXRlU2VydmVyLFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmVwbHkudHlwZShcInRleHQvaHRtbFwiKTtcbiAgICAgICAgICByZXR1cm4gaHRtbDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIDIuIENTUiBmYWxsYmFja1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGZzID0gYXdhaXQgaW1wb3J0KFwibm9kZTpmcy9wcm9taXNlc1wiKTtcbiAgICAgICAgICBsZXQgdGVtcGxhdGUgPSBhd2FpdCBmcy5yZWFkRmlsZShcbiAgICAgICAgICAgIHBhdGguam9pbih0aGlzLnZpdGVTZXJ2ZXIuY29uZmlnLnJvb3QsIFwiaW5kZXguaHRtbFwiKSxcbiAgICAgICAgICAgIFwidXRmLThcIixcbiAgICAgICAgICApO1xuICAgICAgICAgIHRlbXBsYXRlID0gYXdhaXQgdGhpcy52aXRlU2VydmVyLnRyYW5zZm9ybUluZGV4SHRtbCh1cmwsIHRlbXBsYXRlKTtcblxuICAgICAgICAgIHJlcGx5LnR5cGUoXCJ0ZXh0L2h0bWxcIik7XG4gICAgICAgICAgcmV0dXJuIHRlbXBsYXRlO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgdGhpcy52aXRlU2VydmVyLnNzckZpeFN0YWNrdHJhY2UoZSBhcyBFcnJvcik7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgICByZXBseS5zdGF0dXMoNTAwKTtcbiAgICAgICAgICByZXR1cm4gKGUgYXMgRXJyb3IpLm1lc3NhZ2U7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvLyDshJzrsoQg7KKF66OMIOyLnCBWaXRl64+EIOyiheujjFxuICAgIHNlcnZlci5hZGRIb29rKFwib25DbG9zZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCB0aGlzLnZpdGVTZXJ2ZXIuY2xvc2UoKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGNoYWxrID0gKGF3YWl0IGltcG9ydChcImNoYWxrXCIpKS5kZWZhdWx0O1xuICAgIGlmIChcInBvcnRcIiBpbiBobXIpIHtcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBjaGFsay5kaW0oXG4gICAgICAgICAgYOKckyBWaXRlIEhNUiB1c2luZyBkZWRpY2F0ZWQgd2Vic29ja2V0IHBvcnQgJHtobXIucG9ydH0gdG8gYXZvaWQgRmFzdGlmeSB3ZWJzb2NrZXQgY29uZmxpY3RzYCxcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKGNoYWxrLmRpbShcIuKckyBWaXRlIGRldiBzZXJ2ZXIgaW50ZWdyYXRlZFwiKSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNldHVwU3RhdGljV2ViU2VydmVyKFxuICAgIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT4sXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICAgIGdsb2JhbENvbXByZXNzT3B0aW9uczogQ29tcHJlc3NPcHRpb25zIHwgdW5kZWZpbmVkLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyDqsr3roZwg66qF7ZmV7ZmUOiBhcGkvd2ViLWRpc3QvY2xpZW50ICjsoJXsoIEg7YyM7J28KSwgYXBpL3dlYi1kaXN0L3NlcnZlciAoU1NSIGVudHJ5KSwgYXBpL2Rpc3Qvc3NyIChTU1Igcm91dGVzIC0gQVBJIOyGjOycoClcbiAgICBjb25zdCB3ZWJEaXN0UGF0aCA9IHBhdGguam9pbih0aGlzLmFwaVJvb3RQYXRoLCBcIndlYi1kaXN0XCIsIFwiY2xpZW50XCIpO1xuICAgIGNvbnN0IHNzclBhdGggPSBwYXRoLmpvaW4odGhpcy5hcGlSb290UGF0aCwgXCJ3ZWItZGlzdFwiLCBcInNlcnZlclwiKTtcbiAgICBjb25zdCBzc3JFbnRyeVBhdGggPSBwYXRoLmpvaW4oc3NyUGF0aCwgXCJlbnRyeS1zZXJ2ZXIuZ2VuZXJhdGVkLmpzXCIpO1xuICAgIGNvbnN0IHNzclJvdXRlc1BhdGggPSBwYXRoLmpvaW4odGhpcy5hcGlSb290UGF0aCwgXCJkaXN0XCIsIFwic3NyXCIsIFwicm91dGVzLmpzXCIpO1xuXG4gICAgaWYgKCEoYXdhaXQgZXhpc3RzKHdlYkRpc3RQYXRoKSkpIHtcbiAgICAgIGNvbnNvbGUud2Fybihg4pqgIFdlYiBkaXN0IG5vdCBmb3VuZDogJHt3ZWJEaXN0UGF0aH1gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBTU1IgZW50cnkg7KG07J6sIOyXrOu2gCDtmZXsnbhcbiAgICBjb25zdCBzc3JBdmFpbGFibGUgPSBhd2FpdCBleGlzdHMoc3NyRW50cnlQYXRoKTtcblxuICAgIGlmICghc3NyQXZhaWxhYmxlKSB7XG4gICAgICBjb25zb2xlLndhcm4oYOKaoCBTU1IgZW50cnkgbm90IGZvdW5kOiAke3NzckVudHJ5UGF0aH1gKTtcbiAgICAgIGNvbnNvbGUud2FybihcIiAgU1NSIHdpbGwgYmUgZGlzYWJsZWQuIE9ubHkgQ1NSIHdpbGwgd29yay5cIik7XG4gICAgfVxuXG4gICAgLy8gU1NSIOudvOyasO2KuCDroZzrk5wgKHByb2R1Y3Rpb27sl5DshJzrp4wsIOyCrOyaqeyekCDtlITroZzsoJ3tirjsnZggc3NyL3JvdXRlcy50cylcbiAgICBpZiAoc3NyQXZhaWxhYmxlKSB7XG4gICAgICBpZiAoYXdhaXQgZXhpc3RzKHNzclJvdXRlc1BhdGgpKSB7XG4gICAgICAgIC8vIHRzLWxvYWRlcuudvOuptCBcImZpbGU6Ly9cIuuhnCDsi5zsnpHtlZjripQgZnVsbHktcmVzb2x2ZWQgcGF0aOunjCDrsJvquLDsl5Ag7J2066W8IOyymOumrO2VtOyjvOuKlCBpbXBvcnRNZW1iZXJz66W8IOyCrOyaqe2VtOyVvCDtlojqsqDsp4Drp4wsXG4gICAgICAgIC8vIOyXrOq4sOuKlCDtlITroZzrjZXshZgg7ZmY6rK97JeQ7IScIGxvYWRlciDsl4bsnbQg64+M7JWE6rCA6riwIOuVjOusuOyXkCBcIuynhOynnCBqcyDtjIzsnbxcIuydmCBcIuq3uOuDpVwiIOygiOuMgOqyveuhnOulvCDrsJTroZwgaW1wb3J07ZW064+EIOuQqeuLiOuLpC5cbiAgICAgICAgLy8g7J20IOuCtOyaqeydgCDsnbQg7ZWo7IiYIOuCtOyXkOyEnCDslYTrnpjsl5Ag64KY7JisIOuLpOuluCBpbXBvcnQg7Zi47Lac7JeQ64+EIOuPmeydvO2VmOqyjCDsoIHsmqnrkKnri4jri6QuXG4gICAgICAgIGF3YWl0IGltcG9ydChzc3JSb3V0ZXNQYXRoKTtcbiAgICAgICAgY29uc29sZS5sb2coXCLinJMgU1NSIHJvdXRlcyBsb2FkZWRcIik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLndhcm4oYOKaoCBTU1Igcm91dGVzIG5vdCBmb3VuZDogJHtzc3JSb3V0ZXNQYXRofWApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIOuhpOungSDsl4XrjbDsnbTtirgg64yA7J2ROiBhc3NldCBoYXNoIOu2iOydvOy5mCDsi5wg7ZiE7J6sIOuyhOyghCDsp4HsoJEg7ISc67mZXG4gICAgc2VydmVyLmdldChcIi9hc3NldHMvOmZpbGVuYW1lXCIsIGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgY29uc3QgcmVxdWVzdGVkRmlsZSA9IChyZXF1ZXN0LnBhcmFtcyBhcyB7IGZpbGVuYW1lOiBzdHJpbmcgfSkuZmlsZW5hbWU7XG4gICAgICBjb25zdCBhc3NldHNEaXIgPSBwYXRoLmpvaW4od2ViRGlzdFBhdGgsIFwiYXNzZXRzXCIpO1xuICAgICAgY29uc3Qgc2FmZUZpbGVQYXRoID0gdGhpcy5yZXNvbHZlUGF0aFdpdGhpbkJhc2VEaXIoYXNzZXRzRGlyLCByZXF1ZXN0ZWRGaWxlKTtcbiAgICAgIGlmIChzYWZlRmlsZVBhdGggPT09IG51bGwpIHtcbiAgICAgICAgcmVwbHkuc3RhdHVzKDQwMykuc2VuZCgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBub3JtYWxpemVkUmVxdWVzdGVkRmlsZSA9IHBhdGgucmVsYXRpdmUoYXNzZXRzRGlyLCBzYWZlRmlsZVBhdGgpLnJlcGxhY2UoL1xcXFwvZywgXCIvXCIpO1xuXG4gICAgICBjb25zdCBhc3NldFBhdGggPSBgL2Fzc2V0cy8ke25vcm1hbGl6ZWRSZXF1ZXN0ZWRGaWxlfWA7XG5cbiAgICAgIC8vIENhY2hlLUNvbnRyb2wg7Zek642UIOqysOyglVxuICAgICAgY29uc3QgZ2V0Q2FjaGVDb250cm9sRm9yQXNzZXQgPSAoKTogQ2FjaGVDb250cm9sQ29uZmlnID0+IHtcbiAgICAgICAgY29uc3QgY2FjaGVSZXE6IENhY2hlQ29udHJvbFJlcXVlc3QgPSB7XG4gICAgICAgICAgdHlwZTogXCJhc3NldHNcIixcbiAgICAgICAgICB1cmw6IHJlcXVlc3QudXJsLFxuICAgICAgICAgIHBhdGg6IGFzc2V0UGF0aCxcbiAgICAgICAgICBtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIOyCrOyaqeyekCDsoJXsnZgg7ZW465Ok65+sIOyasOyEoFxuICAgICAgICBpZiAoY29uZmlnLmNhY2hlQ29udHJvbEhhbmRsZXIpIHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBjb25maWcuY2FjaGVDb250cm9sSGFuZGxlcihjYWNoZVJlcSk7XG4gICAgICAgICAgaWYgKHJlc3VsdCkgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOq4sOuzuOqwkjogaW1tdXRhYmxlXG4gICAgICAgIHJldHVybiBDYWNoZVByZXNldHMuaW1tdXRhYmxlO1xuICAgICAgfTtcblxuICAgICAgLy8gaW5kZXgtKi5qcyDrmJDripQgaW5kZXgtKi5jc3Mg7JqU7LKt7J24IOqyveyasFxuICAgICAgaWYgKC9eaW5kZXgtW2EtZjAtOV0rXFwuKGpzfGNzcykkLy50ZXN0KG5vcm1hbGl6ZWRSZXF1ZXN0ZWRGaWxlKSkge1xuICAgICAgICBjb25zdCBleHQgPSBub3JtYWxpemVkUmVxdWVzdGVkRmlsZS5zcGxpdChcIi5cIikucG9wKCk7XG4gICAgICAgIGNvbnN0IGZpbGVzID0gYXdhaXQgZnMucmVhZGRpcihhc3NldHNEaXIpO1xuICAgICAgICBjb25zdCBjdXJyZW50RmlsZSA9IGZpbGVzLmZpbmQoKGYpID0+IGYuc3RhcnRzV2l0aChcImluZGV4LVwiKSAmJiBmLmVuZHNXaXRoKGAuJHtleHR9YCkpO1xuXG4gICAgICAgIGlmIChjdXJyZW50RmlsZSkge1xuICAgICAgICAgIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5qb2luKGFzc2V0c0RpciwgY3VycmVudEZpbGUpO1xuICAgICAgICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCBmcy5yZWFkRmlsZShmaWxlUGF0aCk7XG4gICAgICAgICAgcmVwbHkudHlwZShleHQgPT09IFwianNcIiA/IFwiYXBwbGljYXRpb24vamF2YXNjcmlwdFwiIDogXCJ0ZXh0L2Nzc1wiKTtcbiAgICAgICAgICBhcHBseUNhY2hlSGVhZGVycyhyZXBseSwgZ2V0Q2FjaGVDb250cm9sRm9yQXNzZXQoKSk7XG4gICAgICAgICAgcmV0dXJuIHJlcGx5LnNlbmQoY29udGVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8g7J2867CYIO2MjOydvCDshJzruZlcbiAgICAgIGNvbnN0IGZpbGVQYXRoID0gc2FmZUZpbGVQYXRoO1xuICAgICAgaWYgKGF3YWl0IGV4aXN0cyhmaWxlUGF0aCkpIHtcbiAgICAgICAgY29uc3QgY29udGVudCA9IGF3YWl0IGZzLnJlYWRGaWxlKGZpbGVQYXRoKTtcbiAgICAgICAgY29uc3QgZXh0ID0gbm9ybWFsaXplZFJlcXVlc3RlZEZpbGUuc3BsaXQoXCIuXCIpLnBvcCgpO1xuICAgICAgICByZXBseS50eXBlKGV4dCA9PT0gXCJqc1wiID8gXCJhcHBsaWNhdGlvbi9qYXZhc2NyaXB0XCIgOiBleHQgPT09IFwiY3NzXCIgPyBcInRleHQvY3NzXCIgOiBcIlwiKTtcbiAgICAgICAgaWYgKG5vcm1hbGl6ZWRSZXF1ZXN0ZWRGaWxlLmluY2x1ZGVzKFwiLVwiKSkge1xuICAgICAgICAgIGFwcGx5Q2FjaGVIZWFkZXJzKHJlcGx5LCBnZXRDYWNoZUNvbnRyb2xGb3JBc3NldCgpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVwbHkuc2VuZChjb250ZW50KTtcbiAgICAgIH1cblxuICAgICAgcmVwbHkuc3RhdHVzKDQwNCkuc2VuZCgpO1xuICAgIH0pO1xuXG4gICAgLy8gU1NSIOudvOyasO2KuCDqsJzrs4Qg65Ox66GdIChjb21wcmVzcyDsmLXshZjsnbQg65287Jqw7Yq467OE66GcIOyggeyaqeuQmOuPhOuhnSlcbiAgICBpZiAoc3NyQXZhaWxhYmxlKSB7XG4gICAgICBjb25zdCB7IGdldFNTUlJvdXRlcyB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3NyXCIpO1xuICAgICAgY29uc3QgeyByZW5kZXJTU1IgfSA9IGF3YWl0IGltcG9ydChcIi4uL3Nzci9yZW5kZXJlclwiKTtcbiAgICAgIGNvbnN0IHNzclJvdXRlcyA9IGdldFNTUlJvdXRlcygpO1xuXG4gICAgICBmb3IgKGNvbnN0IHJvdXRlIG9mIHNzclJvdXRlcykge1xuICAgICAgICBzZXJ2ZXIucm91dGUoe1xuICAgICAgICAgIG1ldGhvZDogW1wiR0VUXCIsIFwiSEVBRFwiXSxcbiAgICAgICAgICB1cmw6IHJvdXRlLnBhdGgsXG4gICAgICAgICAgY29tcHJlc3M6IHRvRmFzdGlmeUNvbXByZXNzT3B0aW9uKHJvdXRlLmNvbXByZXNzID8/IHRydWUsIGdsb2JhbENvbXByZXNzT3B0aW9ucyksXG4gICAgICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgICAgICBjb25zdCB1cmwgPSByZXF1ZXN0LnVybDtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBbU1NSXSBNYXRjaGVkIHJvdXRlOiAke3JvdXRlLnBhdGh9YCk7XG5cbiAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHRoaXMuZXh0cmFjdFBhdGhQYXJhbXMocm91dGUucGF0aCwgdXJsKTtcbiAgICAgICAgICAgIGNvbnN0IGh0bWwgPSBhd2FpdCByZW5kZXJTU1IodXJsLCByb3V0ZSwgcGFyYW1zLCByZXF1ZXN0LCByZXBseSwgY29uZmlnKTtcblxuICAgICAgICAgICAgcmVwbHkudHlwZShcInRleHQvaHRtbFwiKTtcbiAgICAgICAgICAgIHJldHVybiBodG1sO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIENTUiBvciBTdGF0aWMgRmlsZSBGYWxsYmFjayAoU1NSIOudvOyasO2KuOyXkCDrp6Tsua3rkJjsp4Ag7JWK64qUIOuqqOuToCDsmpTssq0pXG4gICAgc2VydmVyLnJvdXRlKHtcbiAgICAgIG1ldGhvZDogW1wiR0VUXCIsIFwiSEVBRFwiXSxcbiAgICAgIHVybDogXCIqXCIsXG4gICAgICBoYW5kbGVyOiBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgLy8gL2FwaSwgL3NvbmFtdS11aeuKlCA0MDQg6re464yA66GcXG4gICAgICAgIGlmIChyZXF1ZXN0LnVybC5zdGFydHNXaXRoKFwiL2FwaVwiKSB8fCByZXF1ZXN0LnVybC5zdGFydHNXaXRoKFwiL3NvbmFtdS11aVwiKSkge1xuICAgICAgICAgIHJlcGx5LnN0YXR1cyg0MDQpLnNlbmQoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDU1LsmqkgQ2FjaGUtQ29udHJvbCDtl6TrjZQg7ISk7KCVXG4gICAgICAgIGlmIChjb25maWcuY2FjaGVDb250cm9sSGFuZGxlcikge1xuICAgICAgICAgIGNvbnN0IGNzckNhY2hlUmVxOiBDYWNoZUNvbnRyb2xSZXF1ZXN0ID0ge1xuICAgICAgICAgICAgdHlwZTogXCJjc3JcIixcbiAgICAgICAgICAgIHVybDogcmVxdWVzdC51cmwsXG4gICAgICAgICAgICBwYXRoOiByZXF1ZXN0LnVybC5zcGxpdChcIj9cIilbMF0sXG4gICAgICAgICAgICBtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuICAgICAgICAgIH07XG4gICAgICAgICAgY29uc3QgY3NyQ2FjaGVDb25maWcgPSBjb25maWcuY2FjaGVDb250cm9sSGFuZGxlcihjc3JDYWNoZVJlcSk7XG5cbiAgICAgICAgICBpZiAoY3NyQ2FjaGVDb25maWcpIHtcbiAgICAgICAgICAgIGFwcGx5Q2FjaGVIZWFkZXJzKHJlcGx5LCBjc3JDYWNoZUNvbmZpZyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8g7KCV7KCBIO2MjOydvOydtCDsobTsnqztlaAg6rK97JqwLCDsoJXsoIEg7YyM7J287J2EIOuovOyggCDshJzruZntlbTslbztlahcbiAgICAgICAgY29uc3QgcmVxdWVzdFBhdGggPSB0aGlzLmdldFBhdGhuYW1lRnJvbVVybChyZXF1ZXN0LnVybCk7XG4gICAgICAgIGNvbnN0IHNhZmVGaWxlUGF0aCA9IHRoaXMucmVzb2x2ZVBhdGhXaXRoaW5CYXNlRGlyKHdlYkRpc3RQYXRoLCByZXF1ZXN0UGF0aCk7XG4gICAgICAgIGlmIChzYWZlRmlsZVBhdGggPT09IG51bGwpIHtcbiAgICAgICAgICByZXBseS5zdGF0dXMoNDAzKS5zZW5kKCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChhd2FpdCBmaWxlRXhpc3RzKHNhZmVGaWxlUGF0aCkpIHtcbiAgICAgICAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUoc2FmZUZpbGVQYXRoKTtcbiAgICAgICAgICByZXR1cm4gcmVwbHkudHlwZShtaW1lTG9va3VwKHNhZmVGaWxlUGF0aCkgfHwgXCJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW1cIikuc2VuZChjb250ZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENTUiBmYWxsYmFjazogaW5kZXguaHRtbCDshJzruZlcbiAgICAgICAgY29uc3QgaW5kZXhQYXRoID0gcGF0aC5qb2luKHdlYkRpc3RQYXRoLCBcImluZGV4Lmh0bWxcIik7XG4gICAgICAgIHJldHVybiByZXBseS50eXBlKFwidGV4dC9odG1sXCIpLnNlbmQoYXdhaXQgZnMucmVhZEZpbGUoaW5kZXhQYXRoLCBcInV0Zi04XCIpKTtcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBjb25zb2xlLmxvZyhg4pyTIFN0YXRpYyB3ZWIgc2VydmVyIGNvbmZpZ3VyZWQgd2l0aCAke3NzckF2YWlsYWJsZSA/IFwiU1NSXCIgOiBcIkNTUiBvbmx5XCJ9IHN1cHBvcnRgKTtcbiAgfVxuXG4gIGNyZWF0ZUFwaUhhbmRsZXIoXG4gICAgYXBpOiBFeHRlbmRlZEFwaSxcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICk6IChyZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCwgcmVwbHk6IEZhc3RpZnlSZXBseSkgPT4gUHJvbWlzZTx1bmtub3duPiB7XG4gICAgcmV0dXJuIGFzeW5jIChyZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCwgcmVwbHk6IEZhc3RpZnlSZXBseSk6IFByb21pc2U8dW5rbm93bj4gPT4ge1xuICAgICAgLy8gQ29udGV4dCDsg53shLFcbiAgICAgIGNvbnN0IGNvbnRleHQ6IENvbnRleHQgPSBhd2FpdCB0aGlzLmNyZWF0ZUNvbnRleHQoY29uZmlnLCByZXF1ZXN0LCByZXBseSk7XG5cbiAgICAgIHJldHVybiB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLnJ1bih7IGNvbnRleHQgfSwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAvLyBndWFyZHMg7LKY66asXG4gICAgICAgIHJ1bkd1YXJkcyh7XG4gICAgICAgICAgZ3VhcmRzOiBhcGkub3B0aW9ucy5ndWFyZHMsXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgYXBpLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyDtjIzrnbzrr7jthLAg7KCV67O066GcIHpvZCDsiqTtgqTrp4gg67mM65OcXG4gICAgICAgIGNvbnN0IHsgZ2V0Wm9kT2JqZWN0RnJvbUFwaSB9ID0gYXdhaXQgaW1wb3J0KFwiLi9jb2RlLWNvbnZlcnRlcnNcIik7XG4gICAgICAgIGNvbnN0IFJlcVR5cGUgPSBnZXRab2RPYmplY3RGcm9tQXBpKGFwaSwgdGhpcy5zeW5jZXIudHlwZXMpO1xuXG4gICAgICAgIC8vIHJlcXVlc3Qg7YyM7IuxXG4gICAgICAgIGNvbnN0IHdoaWNoID0gYXBpLm9wdGlvbnMuaHR0cE1ldGhvZCA9PT0gXCJHRVRcIiA/IFwicXVlcnlcIiA6IFwiYm9keVwiO1xuICAgICAgICBsZXQgcmVxQm9keToge1xuICAgICAgICAgIFtrZXk6IHN0cmluZ106IHVua25vd247XG4gICAgICAgIH07XG4gICAgICAgIC8vIO2MjOydvCDsl4XroZzrk5wg7J6I64qUIOqyveyasCDsnoTsi5wg642w7J207YSwXG4gICAgICAgIGNvbnN0IGZpbGVzOiB7XG4gICAgICAgICAgYnVmZmVyZWRGaWxlczogQnVmZmVyZWRGaWxlW107XG4gICAgICAgICAgdXBsb2FkZWRGaWxlczogVXBsb2FkZWRGaWxlW107XG4gICAgICAgIH0gPSB7XG4gICAgICAgICAgYnVmZmVyZWRGaWxlczogW10sXG4gICAgICAgICAgdXBsb2FkZWRGaWxlczogW10sXG4gICAgICAgIH07XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBib2R5ID0gKHJlcXVlc3Rbd2hpY2hdID8/IHt9KSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgICAgICBpZiAoYXBpLnVwbG9hZE9wdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHBhcnRzID0gcmVxdWVzdC5wYXJ0cyh7XG4gICAgICAgICAgICAgIGxpbWl0czogYXBpLnVwbG9hZE9wdGlvbnMubGltaXRzLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIEZvcm1EYXRh7J2YIGZpZWxk65Ok7J2EIOyehOyLnOuhnCDsoIDsnqVcbiAgICAgICAgICAgIGNvbnN0IGZpZWxkczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuXG4gICAgICAgICAgICBpZiAoYXBpLnVwbG9hZE9wdGlvbnMuY29uc3VtZSA9PT0gXCJidWZmZXJcIiB8fCAhYXBpLnVwbG9hZE9wdGlvbnMuY29uc3VtZSkge1xuICAgICAgICAgICAgICAvLyBCdWZmZXIg66qo65OcOiDrqZTrqqjrpqzsl5Ag66Gc65OcXG4gICAgICAgICAgICAgIGZvciBhd2FpdCAoY29uc3QgcGFydCBvZiBwYXJ0cykge1xuICAgICAgICAgICAgICAgIGlmIChwYXJ0LnR5cGUgPT09IFwiZmlsZVwiKSB7XG4gICAgICAgICAgICAgICAgICAvLyBDUklUSUNBTDog7YyM7J28IOyKpO2KuOumvOydhCDsponsi5wgY29uc3VtZe2VtOyVvCDri6TsnYwgcGFydOuhnCDrhJjslrTqsIgg7IiYIOyeiOydjFxuICAgICAgICAgICAgICAgICAgLy8g7J20IO2YuOy2nOydtCDsl4bsnLzrqbQg7KKF7KKFIG11bHRpcGFydCDtjIzsi7HsnbQgcGVuZGluZyDsg4Htg5zroZwg7YOA7J6E7JWE7JuDIOuwnOyDnVxuICAgICAgICAgICAgICAgICAgY29uc3QgYnVmZmVyID0gYXdhaXQgcGFydC50b0J1ZmZlcigpO1xuICAgICAgICAgICAgICAgICAgZmlsZXMuYnVmZmVyZWRGaWxlcy5wdXNoKG5ldyBCdWZmZXJlZEZpbGUocGFydCwgYnVmZmVyKSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChwYXJ0LnR5cGUgPT09IFwiZmllbGRcIikge1xuICAgICAgICAgICAgICAgICAgZmllbGRzW3BhcnQuZmllbGRuYW1lXSA9IFN0cmluZyhwYXJ0LnZhbHVlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoYXBpLnVwbG9hZE9wdGlvbnMuY29uc3VtZSA9PT0gXCJzdHJlYW1cIikge1xuICAgICAgICAgICAgICAvLyBTdHJlYW0g66qo65OcOiDsponsi5wg7KCA7J6l7IaM66GcIOyKpO2KuOumrOuwjVxuICAgICAgICAgICAgICBjb25zdCBkaXNrTmFtZSA9IGFwaS51cGxvYWRPcHRpb25zLmRlc3RpbmF0aW9uO1xuICAgICAgICAgICAgICBjb25zdCBkaXNrID0gdGhpcy5zdG9yYWdlLnVzZShkaXNrTmFtZSk7XG5cbiAgICAgICAgICAgICAgLy8g7Jqw7ISg7Iic7JyEOiDrjbDsvZTroIjsnbTthLAgPiDsoITsl60g7ISk7KCVID4g6riw67O46rCSXG4gICAgICAgICAgICAgIGNvbnN0IGtleUdlbmVyYXRvcjogS2V5R2VuZXJhdG9yID1cbiAgICAgICAgICAgICAgICBhcGkudXBsb2FkT3B0aW9ucy5rZXlHZW5lcmF0b3IgPz9cbiAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5zZXJ2ZXIuc3RvcmFnZT8ua2V5R2VuZXJhdG9yID8/XG4gICAgICAgICAgICAgICAgZGVmYXVsdEtleUdlbmVyYXRvcjtcblxuICAgICAgICAgICAgICBmb3IgYXdhaXQgKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcbiAgICAgICAgICAgICAgICBpZiAocGFydC50eXBlID09PSBcImZpbGVcIikge1xuICAgICAgICAgICAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQga2V5R2VuZXJhdG9yKHtcbiAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWU6IHBhcnQuZmlsZW5hbWUsXG4gICAgICAgICAgICAgICAgICAgIG1pbWV0eXBlOiBwYXJ0Lm1pbWV0eXBlLFxuICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgIGF3YWl0IGRpc2sucHV0U3RyZWFtKGtleSwgcGFydC5maWxlLCB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRlbnRUeXBlOiBwYXJ0Lm1pbWV0eXBlLFxuICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgIGNvbnN0IHVybCA9IGF3YWl0IGRpc2suZ2V0VXJsKGtleSk7XG4gICAgICAgICAgICAgICAgICBjb25zdCBzaWduZWRVcmwgPSBhd2FpdCBkaXNrLmdldFNpZ25lZFVybChrZXkpO1xuXG4gICAgICAgICAgICAgICAgICBmaWxlcy51cGxvYWRlZEZpbGVzLnB1c2goXG4gICAgICAgICAgICAgICAgICAgIG5ldyBVcGxvYWRlZEZpbGUoe1xuICAgICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBwYXJ0LmZpbGVuYW1lLFxuICAgICAgICAgICAgICAgICAgICAgIG1pbWV0eXBlOiBwYXJ0Lm1pbWV0eXBlLFxuICAgICAgICAgICAgICAgICAgICAgIHNpemU6IHBhcnQuZmlsZS5ieXRlc1JlYWQsXG4gICAgICAgICAgICAgICAgICAgICAgdXJsLFxuICAgICAgICAgICAgICAgICAgICAgIHNpZ25lZFVybCxcbiAgICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgICAgZGlza05hbWUsXG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PT0gXCJmaWVsZFwiKSB7XG4gICAgICAgICAgICAgICAgICBmaWVsZHNbcGFydC5maWVsZG5hbWVdID0gU3RyaW5nKHBhcnQudmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBxc+uhnCDspJHssqkg6rWs7KGwIO2MjOyLsTogcGFyYW1zW2NhdGVnb3J5XSDihpIgeyBwYXJhbXM6IHsgY2F0ZWdvcnk6IFwidGVzdFwiIH0gfVxuICAgICAgICAgICAgY29uc3QgcXMgPSBhd2FpdCBpbXBvcnQoXCJxc1wiKTtcbiAgICAgICAgICAgIGNvbnN0IHBhcnNlZCA9IHFzLmRlZmF1bHQucGFyc2UoZmllbGRzKTtcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oYm9keSwgcGFyc2VkKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCB7IGZhc3RpZnlDYXN0ZXIgfSA9IGF3YWl0IGltcG9ydChcIi4vY2FzdGVyXCIpO1xuICAgICAgICAgIHJlcUJvZHkgPSBmYXN0aWZ5Q2FzdGVyKFJlcVR5cGUpLnBhcnNlKGJvZHkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgY29uc3QgeyBab2RFcnJvciB9ID0gYXdhaXQgaW1wb3J0KFwiem9kXCIpO1xuICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgWm9kRXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgaHVtYW5pemVab2RFcnJvciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvem9kLWVycm9yXCIpO1xuICAgICAgICAgICAgY29uc3QgbWVzc2FnZXMgPSBodW1hbml6ZVpvZEVycm9yKGUpXG4gICAgICAgICAgICAgIC5tYXAoKGlzc3VlKSA9PiBpc3N1ZS5tZXNzYWdlKVxuICAgICAgICAgICAgICAuam9pbihcIiBcIik7XG4gICAgICAgICAgICBjb25zdCB7IEJhZFJlcXVlc3RFeGNlcHRpb24gfSA9IGF3YWl0IGltcG9ydChcIi4uL2V4Y2VwdGlvbnMvc28tZXhjZXB0aW9uc1wiKTtcbiAgICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKG1lc3NhZ2VzIGFzIExvY2FsaXplZFN0cmluZywge1xuICAgICAgICAgICAgICB6b2RFcnJvcjogZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENvbnRlbnQtVHlwZVxuICAgICAgICByZXBseS50eXBlKGFwaS5vcHRpb25zLmNvbnRlbnRUeXBlID8/IFwiYXBwbGljYXRpb24vanNvblwiKTtcblxuICAgICAgICAvLyBDYWNoZS1Db250cm9sIO2XpOuNlCDshKTsoJVcbiAgICAgICAgY29uc3QgYXBpQ2FjaGVDb25maWcgPSB0aGlzLmdldEFwaUNhY2hlQ29udHJvbChhcGksIHJlcXVlc3QsIGNvbmZpZyk7XG4gICAgICAgIGlmIChhcGlDYWNoZUNvbmZpZykge1xuICAgICAgICAgIGFwcGx5Q2FjaGVIZWFkZXJzKHJlcGx5LCBhcGlDYWNoZUNvbmZpZyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyDsl4XroZzrk5wg7Ji17IWY7J20IOyeiOuKlCDqsr3smrAg7YyM7J28IOuNsOydtO2EsOulvCBDb250ZXh07JeQIOy2lOqwgFxuICAgICAgICBpZiAoYXBpLnVwbG9hZE9wdGlvbnMpIHtcbiAgICAgICAgICBjb25zdCBjb25zdW1lID0gYXBpLnVwbG9hZE9wdGlvbnMuY29uc3VtZSA/PyBcImJ1ZmZlclwiO1xuICAgICAgICAgIGlmIChjb25zdW1lID09PSBcImJ1ZmZlclwiKSB7XG4gICAgICAgICAgICBjb250ZXh0LmJ1ZmZlcmVkRmlsZXMgPSBmaWxlcy5idWZmZXJlZEZpbGVzO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY29uc3VtZSA9PT0gXCJzdHJlYW1cIikge1xuICAgICAgICAgICAgY29udGV4dC51cGxvYWRlZEZpbGVzID0gZmlsZXMudXBsb2FkZWRGaWxlcztcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyDrqqjrjbgg66mU7IaM65OcIGFyZ3Mg7IOd7ISx7ZWY7JesIO2YuOy2nFxuICAgICAgICBjb25zdCB7IEFwaVBhcmFtVHlwZSB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdHlwZXMvdHlwZXNcIik7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSBhcGkucGFyYW1ldGVycy5tYXAoKHBhcmFtKSA9PiB7XG4gICAgICAgICAgLy8gQ29udGV4dCDsnbjsoJ3shZhcbiAgICAgICAgICBpZiAoQXBpUGFyYW1UeXBlLmlzQ29udGV4dChwYXJhbS50eXBlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiByZXFCb2R5W3BhcmFtLm5hbWVdO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuaW52b2tlTW9kZWxNZXRob2QoYXBpLCBhcmdzLCByZXBseSk7XG4gICAgICB9KTtcbiAgICB9O1xuICB9XG5cbiAgLy8gV1MgcGF0aOulvCDsnbzrsJggSFRUUCBHRVTsnLzroZwg7Zi47Lac7ZWcIOqyveyasCA0MjYgKyBVcGdyYWRlIO2XpOuNlOuhnCDrqoXsi5zsoIHsnLzroZwgd2Vic29ja2V0IOygkeyGjeydhCDsnKDrj4TtlahcbiAgcHJpdmF0ZSBjcmVhdGVXZWJTb2NrZXRVcGdyYWRlUmVxdWlyZWRIYW5kbGVyKCkge1xuICAgIHJldHVybiBhc3luYyAoX3JlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LCByZXBseTogRmFzdGlmeVJlcGx5KTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICByZXBseS5oZWFkZXIoXCJjb25uZWN0aW9uXCIsIFwiVXBncmFkZVwiKS5oZWFkZXIoXCJ1cGdyYWRlXCIsIFwid2Vic29ja2V0XCIpLnN0YXR1cyg0MjYpLnNlbmQoe1xuICAgICAgICBtZXNzYWdlOiBcIldlYlNvY2tldCB1cGdyYWRlIHJlcXVpcmVkXCIsXG4gICAgICB9KTtcbiAgICB9O1xuICB9XG5cbiAgLy8gZGV2IOuqqOuTnOydmCBjYXRjaC1hbGwgd3NIYW5kbGVy7JeQ7IScIOyLpOygnCBXUyBBUEnroZwg65SU7Iqk7Yyo7LmY7ZWoLiDrp6Tsua3rkJjripQgcm91dGXqsIAg7JeG7Jy866m0IDEwMDjroZwg64ur7J2MXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlRGV2V2ViU29ja2V0UmVxdWVzdChcbiAgICBzb2NrZXQ6IFdlYlNvY2tldCxcbiAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG1hdGNoZWRBcGkgPSB0aGlzLmZpbmRNYXRjaGVkQXBpKHJlcXVlc3QpO1xuICAgIGlmICghbWF0Y2hlZEFwaT8ud2Vic29ja2V0T3B0aW9ucykge1xuICAgICAgY29uc3QgdHJhY2VDb250ZXh0ID0gdGhpcy53ZWJzb2NrZXRSdW50aW1lLnRlbGVtZXRyeUNvbnRyb2xsZXIuY3JlYXRlQ29ubmVjdGlvbkNvbnRleHQoe1xuICAgICAgICBoZWFkZXJzOiByZXF1ZXN0LmhlYWRlcnMsXG4gICAgICB9KTtcbiAgICAgIHRoaXMud2Vic29ja2V0UnVudGltZS50ZWxlbWV0cnlDb250cm9sbGVyLmVtaXQoe1xuICAgICAgICBuYW1lOiBcIndzLmNvbm5lY3Rpb24ucmVqZWN0ZWRcIixcbiAgICAgICAgbGV2ZWw6IFwid2FyblwiLFxuICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICByZWFzb246IFwicm91dGVOb3RGb3VuZFwiLFxuICAgICAgICAgIHBhdGg6IHJlcXVlc3QudXJsLFxuICAgICAgICB9LFxuICAgICAgICB0cmFjZUlkOiB0cmFjZUNvbnRleHQudHJhY2VJZCxcbiAgICAgICAgc3BhbklkOiB0cmFjZUNvbnRleHQuc3BhbklkLFxuICAgICAgICBwYXJlbnRTcGFuSWQ6IHRyYWNlQ29udGV4dC5wYXJlbnRTcGFuSWQsXG4gICAgICAgIHNhbXBsZWQ6IHRyYWNlQ29udGV4dC5zYW1wbGVkLFxuICAgICAgfSk7XG4gICAgICBzb2NrZXQuY2xvc2UoMTAwOCwgXCJXZWJTb2NrZXQgcm91dGUgbm90IGZvdW5kXCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGhhbmRsZXIgPSB0aGlzLmNyZWF0ZVdlYlNvY2tldEhhbmRsZXIobWF0Y2hlZEFwaSwgY29uZmlnKTtcbiAgICBhd2FpdCBoYW5kbGVyKHsgc29ja2V0IH0sIHJlcXVlc3QpO1xuICB9XG5cbiAgLy8gV1Mgcm91dGUg7ZW465Ok65+s7J2YIOyLpO2WiSDsiJzshJzrpbwg6rOg7KCV7ZWoOlxuICAvLyAxKSBndWFyZOulvCBjb25uZWN0aW9uIOuTseuhnSDsnbTsoITsl5Ag64+M66CkIOyduOymnSDsi6TtjKgg7IucIOu2gOu2hCDrk7HroZ0g7IOB7YOc66W8IOuCqOq4sOyngCDslYrsnYxcbiAgLy8gMikgcXVlcnkgcGFyYW0g7YyM7Iux64+EIGFjdGl2YXRpb24g7KCE7JeQIOuBneuCtCBoYW5kc2hha2Ug7Iuk7Yyo6rCAIHJlZ2lzdHJ57JeQIOuFuOy2nOuQmOyngCDslYrqsowg7ZWoXG4gIC8vIDMpIGBhY3RpdmU6IGZhbHNlYOuhnCDrqLzsoIAg65Ox66Gd7ZWY6rOgLCBjb250ZXh0IOykgOu5hOqwgCDrgZ3rgpwg65KkIGBhY3RpdmF0ZSgpYO2VtCDruIzroZzrk5zsupDsiqTtirjqsIAg7LSI6riw7ZmUIOykkeqwhCDsg4Htg5zrpbwg67O07KeAIOuqu+2VmOqyjCDtlahcbiAgLy8g7JeQ65+sIOuwnOyDnSDsi5zsl5DripQgcmVzb2x2ZVdlYlNvY2tldENsb3NlRGVzY3JpcHRvciDsoJXssYXsl5Ag65Sw6528IGNsb3NlIGNvZGXrpbwg66ek7ZWR7ZWoXG4gIHByaXZhdGUgY3JlYXRlV2ViU29ja2V0SGFuZGxlcihhcGk6IEV4dGVuZGVkQXBpLCBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcpIHtcbiAgICByZXR1cm4gYXN5bmMgKFxuICAgICAgY29ubmVjdGlvbjoge1xuICAgICAgICBzb2NrZXQ6IFdlYlNvY2tldDtcbiAgICAgIH0sXG4gICAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICApOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgIGNvbnN0IHNvY2tldCA9IGNvbm5lY3Rpb24uc29ja2V0O1xuICAgICAgbGV0IHdzQ29udGV4dDogV2ViU29ja2V0Q29udGV4dCB8IG51bGwgPSBudWxsO1xuICAgICAgbGV0IHJhd1dzOiBSZXR1cm5UeXBlPFdlYlNvY2tldFJ1bnRpbWVbXCJyZWdpc3RlckNvbm5lY3Rpb25cIl0+IHwgbnVsbCA9IG51bGw7XG4gICAgICBsZXQgcHJlUmVnaXN0ZXJQaGFzZTogXCJndWFyZFwiIHwgXCJxdWVyeVwiIHwgXCJyZWdpc3RlclwiIHwgXCJoYW5kbGVyXCIgPSBcImd1YXJkXCI7XG4gICAgICBsZXQgdHJhY2VDb250ZXh0OiBXZWJTb2NrZXRUZWxlbWV0cnlDb25uZWN0aW9uQ29udGV4dCA9IHt9O1xuXG4gICAgICB0cnkge1xuICAgICAgICB0cmFjZUNvbnRleHQgPSB0aGlzLndlYnNvY2tldFJ1bnRpbWUudGVsZW1ldHJ5Q29udHJvbGxlci5jcmVhdGVDb25uZWN0aW9uQ29udGV4dCh7XG4gICAgICAgICAgaGVhZGVyczogcmVxdWVzdC5oZWFkZXJzLFxuICAgICAgICB9KTtcblxuICAgICAgICBwcmVSZWdpc3RlclBoYXNlID0gXCJxdWVyeVwiO1xuICAgICAgICBjb25zdCByZXFCb2R5ID0gYXdhaXQgdGhpcy5wYXJzZVdlYlNvY2tldFJlcXVlc3RQYXJhbXMoYXBpLCByZXF1ZXN0KTtcbiAgICAgICAgcHJlUmVnaXN0ZXJQaGFzZSA9IFwicmVnaXN0ZXJcIjtcbiAgICAgICAgcmF3V3MgPSB0aGlzLndlYnNvY2tldFJ1bnRpbWUucmVnaXN0ZXJDb25uZWN0aW9uKHNvY2tldCwge1xuICAgICAgICAgIG91dEV2ZW50czogYXBpLndlYnNvY2tldE9wdGlvbnMhLm91dEV2ZW50cyxcbiAgICAgICAgICBpbkV2ZW50czogYXBpLndlYnNvY2tldE9wdGlvbnMhLmluRXZlbnRzLFxuICAgICAgICAgIG5hbWVzcGFjZTogYXBpLndlYnNvY2tldE9wdGlvbnMhLm5hbWVzcGFjZSxcbiAgICAgICAgICBoZWFydGJlYXQ6IGFwaS53ZWJzb2NrZXRPcHRpb25zIS5oZWFydGJlYXQsXG4gICAgICAgICAgYWN0aXZlOiBmYWxzZSxcbiAgICAgICAgICB0cmFjZUlkOiB0cmFjZUNvbnRleHQudHJhY2VJZCxcbiAgICAgICAgICBzcGFuSWQ6IHRyYWNlQ29udGV4dC5zcGFuSWQsXG4gICAgICAgICAgcGFyZW50U3BhbklkOiB0cmFjZUNvbnRleHQucGFyZW50U3BhbklkLFxuICAgICAgICAgIHNhbXBsZWQ6IHRyYWNlQ29udGV4dC5zYW1wbGVkLFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBzY29wZWRXcyA9IHRoaXMuY3JlYXRlU2NvcGVkV2ViU29ja2V0Q29ubmVjdGlvbihyYXdXcywgKCkgPT4gd3NDb250ZXh0KTtcbiAgICAgICAgd3NDb250ZXh0ID0gYXdhaXQgdGhpcy5jcmVhdGVXZWJTb2NrZXRDb250ZXh0KGNvbmZpZywgcmVxdWVzdCwgc2NvcGVkV3MpO1xuXG4gICAgICAgIGF3YWl0IHRoaXMuYXN5bmNMb2NhbFN0b3JhZ2UucnVuKHsgY29udGV4dDogd3NDb250ZXh0IH0sIGFzeW5jICgpID0+IHtcbiAgICAgICAgICBydW5HdWFyZHMoe1xuICAgICAgICAgICAgZ3VhcmRzOiBhcGkub3B0aW9ucy5ndWFyZHMsXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgYXBpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLndlYnNvY2tldFJ1bnRpbWUuYWN0aXZhdGVDb25uZWN0aW9uKHJhd1dzLmlkKTtcbiAgICAgICAgcHJlUmVnaXN0ZXJQaGFzZSA9IFwiaGFuZGxlclwiO1xuXG4gICAgICAgIGNvbnN0IHsgQXBpUGFyYW1UeXBlIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi90eXBlcy90eXBlc1wiKTtcbiAgICAgICAgY29uc3QgYXJncyA9IGFwaS5wYXJhbWV0ZXJzLm1hcCgocGFyYW0pID0+IHtcbiAgICAgICAgICBpZiAoQXBpUGFyYW1UeXBlLmlzQ29udGV4dChwYXJhbS50eXBlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHdzQ29udGV4dDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcmVxQm9keVtwYXJhbS5uYW1lXTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5hc3luY0xvY2FsU3RvcmFnZS5ydW4oeyBjb250ZXh0OiB3c0NvbnRleHQgfSwgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGF3YWl0IHRoaXMuaW52b2tlTW9kZWxNZXRob2QoYXBpLCBhcmdzKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zdCBjbG9zZURlc2NyaXB0b3IgPSByZXNvbHZlV2ViU29ja2V0Q2xvc2VEZXNjcmlwdG9yKGVycm9yKTtcbiAgICAgICAgaWYgKCFyYXdXcykge1xuICAgICAgICAgIHRoaXMud2Vic29ja2V0UnVudGltZS50ZWxlbWV0cnlDb250cm9sbGVyLmVtaXQoe1xuICAgICAgICAgICAgbmFtZTogXCJ3cy5jb25uZWN0aW9uLnJlamVjdGVkXCIsXG4gICAgICAgICAgICBsZXZlbDogY2xvc2VEZXNjcmlwdG9yLmxvZ0xldmVsID09PSBcIndhcm5cIiA/IFwid2FyblwiIDogXCJlcnJvclwiLFxuICAgICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICAgIHJlYXNvbjogcHJlUmVnaXN0ZXJQaGFzZSxcbiAgICAgICAgICAgICAgY29kZTogY2xvc2VEZXNjcmlwdG9yLmNvZGUsXG4gICAgICAgICAgICAgIHBhdGg6IGFwaS5wYXRoLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRyYWNlSWQ6IHRyYWNlQ29udGV4dC50cmFjZUlkLFxuICAgICAgICAgICAgc3BhbklkOiB0cmFjZUNvbnRleHQuc3BhbklkLFxuICAgICAgICAgICAgcGFyZW50U3BhbklkOiB0cmFjZUNvbnRleHQucGFyZW50U3BhbklkLFxuICAgICAgICAgICAgc2FtcGxlZDogdHJhY2VDb250ZXh0LnNhbXBsZWQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmF3V3MpIHtcbiAgICAgICAgICByYXdXcy5jbG9zZShjbG9zZURlc2NyaXB0b3IuY29kZSwgY2xvc2VEZXNjcmlwdG9yLnJlYXNvbik7XG4gICAgICAgIH0gZWxzZSBpZiAoc29ja2V0LnJlYWR5U3RhdGUgPCAyKSB7XG4gICAgICAgICAgc29ja2V0LmNsb3NlKGNsb3NlRGVzY3JpcHRvci5jb2RlLCBjbG9zZURlc2NyaXB0b3IucmVhc29uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnNlcnZlcj8ubG9nKSB7XG4gICAgICAgICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgICAgIGVycjogZXJyb3IsXG4gICAgICAgICAgICBtb2RlbE5hbWU6IGFwaS5tb2RlbE5hbWUsXG4gICAgICAgICAgICBtZXRob2ROYW1lOiBhcGkubWV0aG9kTmFtZSxcbiAgICAgICAgICAgIHBhdGg6IGFwaS5wYXRoLFxuICAgICAgICAgIH07XG4gICAgICAgICAgaWYgKGNsb3NlRGVzY3JpcHRvci5sb2dMZXZlbCA9PT0gXCJ3YXJuXCIpIHtcbiAgICAgICAgICAgIHRoaXMuc2VydmVyLmxvZy53YXJuKHBheWxvYWQsIGNsb3NlRGVzY3JpcHRvci5yZWFzb24pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNlcnZlci5sb2cuZXJyb3IocGF5bG9hZCwgY2xvc2VEZXNjcmlwdG9yLnJlYXNvbik7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChjbG9zZURlc2NyaXB0b3IubG9nTGV2ZWwgPT09IFwid2FyblwiKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oY2xvc2VEZXNjcmlwdG9yLnJlYXNvbiwgZXJyb3IpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGNsb3NlRGVzY3JpcHRvci5yZWFzb24sIGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLy8gb25NZXNzYWdlL29uQ2xvc2Xsspjrn7wg64uk66W4IHRpY2vsl5DshJwg7Iuk7ZaJ65CY64qUIGNhbGxiYWNr7J2AIEFMUyBjb250ZXh06rCAIOuBiuq4sOuvgOuhnCB3cmFwcGVy7JeQ7IScIGBhc3luY0xvY2FsU3RvcmFnZS5ydW5g7Jy866GcIOuLpOyLnCDqsJDsi7gg67O17JuQ7ZWoXG4gIC8vIHB1Ymxpc2gvam9pbi9sZWF2ZS9zZXRVc2VySWQg6rCZ7J2AIOymieyLnCDsi6TtlokgQVBJ64qUIOuLqOyInCDsnITsnoTrp4wg7ZWY6rOgLCBkZWZlcnJlZCBjYWxsYmFja+yXkOunjCBjb250ZXh0IOuzteybkOydhCDsoIHsmqntlahcbiAgcHJpdmF0ZSBjcmVhdGVTY29wZWRXZWJTb2NrZXRDb25uZWN0aW9uPFxuICAgIFRPdXQgZXh0ZW5kcyBXZWJTb2NrZXRFdmVudE1hcCxcbiAgICBUSW4gZXh0ZW5kcyBXZWJTb2NrZXRFdmVudE1hcCxcbiAgPihcbiAgICB3czogV2ViU29ja2V0Q29ubmVjdGlvbjxUT3V0LCBUSW4+LFxuICAgIGdldENvbnRleHQ6ICgpID0+IFdlYlNvY2tldENvbnRleHQgfCBudWxsLFxuICApOiBXZWJTb2NrZXRDb25uZWN0aW9uPFRPdXQsIFRJbj4ge1xuICAgIGNvbnN0IHRlbGVtZXRyeUNvbnRyb2xsZXIgPSB0aGlzLl93ZWJzb2NrZXRSdW50aW1lPy50ZWxlbWV0cnlDb250cm9sbGVyO1xuICAgIGNvbnN0IHJ1bkluQ29udGV4dCA9IDxUPihjYWxsYmFjazogKCkgPT4gVCk6IFQgPT4ge1xuICAgICAgY29uc3QgY29udGV4dCA9IGdldENvbnRleHQoKTtcbiAgICAgIGlmICghY29udGV4dCkge1xuICAgICAgICByZXR1cm4gY2FsbGJhY2soKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuYXN5bmNMb2NhbFN0b3JhZ2UucnVuKHsgY29udGV4dCB9LCBjYWxsYmFjayk7XG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICBnZXQgaWQoKSB7XG4gICAgICAgIHJldHVybiB3cy5pZDtcbiAgICAgIH0sXG4gICAgICBnZXQgbmFtZXNwYWNlKCkge1xuICAgICAgICByZXR1cm4gd3MubmFtZXNwYWNlO1xuICAgICAgfSxcbiAgICAgIGdldCBjbG9zZWQoKSB7XG4gICAgICAgIHJldHVybiB3cy5jbG9zZWQ7XG4gICAgICB9LFxuICAgICAgZ2V0IHVzZXJJZCgpIHtcbiAgICAgICAgcmV0dXJuIHdzLnVzZXJJZDtcbiAgICAgIH0sXG4gICAgICB0cmFuc3BvcnQ6IFwid3NcIixcbiAgICAgIHB1Ymxpc2hVbnR5cGVkKGV2ZW50LCBkYXRhKSB7XG4gICAgICAgIHdzLnB1Ymxpc2hVbnR5cGVkKGV2ZW50LCBkYXRhKTtcbiAgICAgIH0sXG4gICAgICBjbG9zZShjb2RlLCByZWFzb24pIHtcbiAgICAgICAgd3MuY2xvc2UoY29kZSwgcmVhc29uKTtcbiAgICAgIH0sXG4gICAgICBvbkNsb3NlKGNhbGxiYWNrKSB7XG4gICAgICAgIHdzLm9uQ2xvc2UoKCkgPT4gcnVuSW5Db250ZXh0KGNhbGxiYWNrKSk7XG4gICAgICB9LFxuICAgICAgb25NZXNzYWdlKGV2ZW50LCBoYW5kbGVyKSB7XG4gICAgICAgIHdzLm9uTWVzc2FnZShldmVudCwgKGRhdGEsIG1lc3NhZ2VUcmFjZUNvbnRleHQpID0+XG4gICAgICAgICAgcnVuSW5Db250ZXh0KGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGV2ZW50TmFtZSA9IFN0cmluZyhldmVudCk7XG4gICAgICAgICAgICBjb25zdCB0cmFjZUNvbnRleHQgPSBtZXNzYWdlVHJhY2VDb250ZXh0ID8/IGdldFdlYlNvY2tldFRlbGVtZXRyeUNvbnRleHQod3MpO1xuICAgICAgICAgICAgY29uc3Qgc3RhcnRlZEF0ID0gcGVyZm9ybWFuY2Uubm93KCk7XG5cbiAgICAgICAgICAgIHRlbGVtZXRyeUNvbnRyb2xsZXI/LmVtaXQoe1xuICAgICAgICAgICAgICBuYW1lOiBcIndzLmhhbmRsZXIuc3RhcnRlZFwiLFxuICAgICAgICAgICAgICBsZXZlbDogXCJkZWJ1Z1wiLFxuICAgICAgICAgICAgICBjb25uZWN0aW9uSWQ6IHdzLmlkLFxuICAgICAgICAgICAgICBuYW1lc3BhY2U6IHdzLm5hbWVzcGFjZSxcbiAgICAgICAgICAgICAgdXNlcklkOiB3cy51c2VySWQsXG4gICAgICAgICAgICAgIGRldGFpbDogeyBldmVudDogZXZlbnROYW1lIH0sXG4gICAgICAgICAgICAgIC4uLnRyYWNlQ29udGV4dCxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBoYW5kbGVyKGRhdGEsIG1lc3NhZ2VUcmFjZUNvbnRleHQpO1xuICAgICAgICAgICAgICBjb25zdCBkdXJhdGlvbk1zID0gcGVyZm9ybWFuY2Uubm93KCkgLSBzdGFydGVkQXQ7XG4gICAgICAgICAgICAgIHRlbGVtZXRyeUNvbnRyb2xsZXI/LmVtaXQoe1xuICAgICAgICAgICAgICAgIG5hbWU6IFwid3MuaGFuZGxlci5jb21wbGV0ZWRcIixcbiAgICAgICAgICAgICAgICBsZXZlbDogXCJkZWJ1Z1wiLFxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25JZDogd3MuaWQsXG4gICAgICAgICAgICAgICAgbmFtZXNwYWNlOiB3cy5uYW1lc3BhY2UsXG4gICAgICAgICAgICAgICAgdXNlcklkOiB3cy51c2VySWQsXG4gICAgICAgICAgICAgICAgZGV0YWlsOiB7IGV2ZW50OiBldmVudE5hbWUgfSxcbiAgICAgICAgICAgICAgICAuLi50cmFjZUNvbnRleHQsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB0ZWxlbWV0cnlDb250cm9sbGVyPy5yZWNvcmRTcGFuKHtcbiAgICAgICAgICAgICAgICBvcGVyYXRpb25OYW1lOiBcIndzLm1lc3NhZ2UucHJvY2Vzc1wiLFxuICAgICAgICAgICAgICAgIGtpbmQ6IFwiaW50ZXJuYWxcIixcbiAgICAgICAgICAgICAgICBkdXJhdGlvbk1zLFxuICAgICAgICAgICAgICAgIHN0YXR1czogXCJ1bnNldFwiLFxuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb25JZDogd3MuaWQsXG4gICAgICAgICAgICAgICAgbmFtZXNwYWNlOiB3cy5uYW1lc3BhY2UsXG4gICAgICAgICAgICAgICAgdXNlcklkOiB3cy51c2VySWQsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlczogeyBldmVudDogZXZlbnROYW1lIH0sXG4gICAgICAgICAgICAgICAgLi4udHJhY2VDb250ZXh0LFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGR1cmF0aW9uTXMgPSBwZXJmb3JtYW5jZS5ub3coKSAtIHN0YXJ0ZWRBdDtcbiAgICAgICAgICAgICAgdGVsZW1ldHJ5Q29udHJvbGxlcj8uZW1pdCh7XG4gICAgICAgICAgICAgICAgbmFtZTogXCJ3cy5oYW5kbGVyLmZhaWxlZFwiLFxuICAgICAgICAgICAgICAgIGxldmVsOiBcImVycm9yXCIsXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbklkOiB3cy5pZCxcbiAgICAgICAgICAgICAgICBuYW1lc3BhY2U6IHdzLm5hbWVzcGFjZSxcbiAgICAgICAgICAgICAgICB1c2VySWQ6IHdzLnVzZXJJZCxcbiAgICAgICAgICAgICAgICBkZXRhaWw6IHsgZXZlbnQ6IGV2ZW50TmFtZSB9LFxuICAgICAgICAgICAgICAgIC4uLnRyYWNlQ29udGV4dCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHRlbGVtZXRyeUNvbnRyb2xsZXI/LnJlY29yZFNwYW4oe1xuICAgICAgICAgICAgICAgIG9wZXJhdGlvbk5hbWU6IFwid3MubWVzc2FnZS5wcm9jZXNzXCIsXG4gICAgICAgICAgICAgICAga2luZDogXCJpbnRlcm5hbFwiLFxuICAgICAgICAgICAgICAgIGR1cmF0aW9uTXMsXG4gICAgICAgICAgICAgICAgc3RhdHVzOiBcImVycm9yXCIsXG4gICAgICAgICAgICAgICAgY29ubmVjdGlvbklkOiB3cy5pZCxcbiAgICAgICAgICAgICAgICBuYW1lc3BhY2U6IHdzLm5hbWVzcGFjZSxcbiAgICAgICAgICAgICAgICB1c2VySWQ6IHdzLnVzZXJJZCxcbiAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzOiB7IGV2ZW50OiBldmVudE5hbWUgfSxcbiAgICAgICAgICAgICAgICBlcnJvclR5cGU6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5uYW1lIDogdHlwZW9mIGVycm9yLFxuICAgICAgICAgICAgICAgIC4uLnRyYWNlQ29udGV4dCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgfSxcbiAgICAgIHB1Ymxpc2goZXZlbnQsIGRhdGEpIHtcbiAgICAgICAgd3MucHVibGlzaChldmVudCwgZGF0YSk7XG4gICAgICB9LFxuICAgICAgd2FpdEZvckNsb3NlKCkge1xuICAgICAgICByZXR1cm4gd3Mud2FpdEZvckNsb3NlKCk7XG4gICAgICB9LFxuICAgICAgam9pbihyb29tSWQpIHtcbiAgICAgICAgd3Muam9pbihyb29tSWQpO1xuICAgICAgfSxcbiAgICAgIGxlYXZlKHJvb21JZCkge1xuICAgICAgICB3cy5sZWF2ZShyb29tSWQpO1xuICAgICAgfSxcbiAgICAgIHNldFVzZXJJZCh1c2VySWQpIHtcbiAgICAgICAgd3Muc2V0VXNlcklkKHVzZXJJZCk7XG4gICAgICB9LFxuICAgICAgY2xlYXJVc2VySWQoKSB7XG4gICAgICAgIHdzLmNsZWFyVXNlcklkKCk7XG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHBhcnNlV2ViU29ja2V0UmVxdWVzdFBhcmFtcyhcbiAgICBhcGk6IEV4dGVuZGVkQXBpLFxuICAgIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHVua25vd24+PiB7XG4gICAgY29uc3QgeyBnZXRab2RPYmplY3RGcm9tQXBpIH0gPSBhd2FpdCBpbXBvcnQoXCIuL2NvZGUtY29udmVydGVyc1wiKTtcbiAgICBjb25zdCBSZXFUeXBlID0gZ2V0Wm9kT2JqZWN0RnJvbUFwaShhcGksIHRoaXMuc3luY2VyLnR5cGVzKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IGZhc3RpZnlDYXN0ZXIgfSA9IGF3YWl0IGltcG9ydChcIi4vY2FzdGVyXCIpO1xuICAgICAgcmV0dXJuIGZhc3RpZnlDYXN0ZXIoUmVxVHlwZSkucGFyc2UoKHJlcXVlc3QucXVlcnkgPz8ge30pIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zdCB7IFpvZEVycm9yIH0gPSBhd2FpdCBpbXBvcnQoXCJ6b2RcIik7XG4gICAgICBpZiAoZSBpbnN0YW5jZW9mIFpvZEVycm9yKSB7XG4gICAgICAgIGNvbnN0IHsgaHVtYW5pemVab2RFcnJvciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvem9kLWVycm9yXCIpO1xuICAgICAgICBjb25zdCBtZXNzYWdlcyA9IGh1bWFuaXplWm9kRXJyb3IoZSlcbiAgICAgICAgICAubWFwKChpc3N1ZSkgPT4gaXNzdWUubWVzc2FnZSlcbiAgICAgICAgICAuam9pbihcIiBcIik7XG4gICAgICAgIGNvbnN0IHsgQmFkUmVxdWVzdEV4Y2VwdGlvbiB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vZXhjZXB0aW9ucy9zby1leGNlcHRpb25zXCIpO1xuICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihtZXNzYWdlcyBhcyBMb2NhbGl6ZWRTdHJpbmcsIHtcbiAgICAgICAgICB6b2RFcnJvcjogZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFVSTOyXkOyEnCBwYXRoIHBhcmFtc+ulvCDstpTstpztlanri4jri6QuXG4gICAqIOyYiDogcGF0dGVybj1cIi9hZG1pbi9jb21wYW5pZXMvOmNvbXBhbnlJZFwiLCB1cmw9XCIvYWRtaW4vY29tcGFuaWVzLzEyM1wiIOKGkiB7IGNvbXBhbnlJZDogXCIxMjNcIiB9XG4gICAqL1xuICBwcml2YXRlIGV4dHJhY3RQYXRoUGFyYW1zKHBhdHRlcm46IHN0cmluZywgdXJsOiBzdHJpbmcpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgICBjb25zdCBwYXR0ZXJuUGFydHMgPSBwYXR0ZXJuLnNwbGl0KFwiL1wiKS5maWx0ZXIoQm9vbGVhbik7XG4gICAgY29uc3QgdXJsUGFydHMgPSB0aGlzLmdldFBhdGhuYW1lRnJvbVVybCh1cmwpLnNwbGl0KFwiL1wiKS5maWx0ZXIoQm9vbGVhbik7XG4gICAgY29uc3QgcGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhdHRlcm5QYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKHBhdHRlcm5QYXJ0c1tpXS5zdGFydHNXaXRoKFwiOlwiKSkge1xuICAgICAgICBwYXJhbXNbcGF0dGVyblBhcnRzW2ldLnNsaWNlKDEpXSA9IHVybFBhcnRzW2ldO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcGFyYW1zO1xuICB9XG5cbiAgcHJpdmF0ZSBpc1BhdGhQYXR0ZXJuTWF0Y2gocGF0dGVybjogc3RyaW5nLCB1cmw6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHBhdHRlcm5QYXJ0cyA9IHBhdHRlcm4uc3BsaXQoXCIvXCIpLmZpbHRlcihCb29sZWFuKTtcbiAgICBjb25zdCB1cmxQYXJ0cyA9IHRoaXMuZ2V0UGF0aG5hbWVGcm9tVXJsKHVybCkuc3BsaXQoXCIvXCIpLmZpbHRlcihCb29sZWFuKTtcblxuICAgIGlmIChwYXR0ZXJuUGFydHMubGVuZ3RoICE9PSB1cmxQYXJ0cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhdHRlcm5QYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgcGF0dGVyblBhcnQgPSBwYXR0ZXJuUGFydHNbaV07XG4gICAgICBjb25zdCB1cmxQYXJ0ID0gdXJsUGFydHNbaV07XG4gICAgICBpZiAocGF0dGVyblBhcnQuc3RhcnRzV2l0aChcIjpcIikpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAocGF0dGVyblBhcnQgIT09IHVybFBhcnQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRQYXRobmFtZUZyb21VcmwodXJsOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB1cmwuc3BsaXQoXCI/XCIpWzBdO1xuICB9XG5cbiAgcHJpdmF0ZSByZXNvbHZlUGF0aFdpdGhpbkJhc2VEaXIoYmFzZURpcjogc3RyaW5nLCBpbnB1dFBhdGg6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBkZWNvZGVkID0gZGVjb2RlVVJJQ29tcG9uZW50KGlucHV0UGF0aCkucmVwbGFjZSgvXFxcXC9nLCBcIi9cIik7XG4gICAgICBpZiAoZGVjb2RlZC5pbmNsdWRlcyhcIlxcMFwiKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlbGF0aXZlUGF0aCA9IGRlY29kZWQucmVwbGFjZSgvXlxcLysvLCBcIlwiKTtcbiAgICAgIGNvbnN0IHJlc29sdmVkUGF0aCA9IHBhdGgucmVzb2x2ZShiYXNlRGlyLCByZWxhdGl2ZVBhdGgpO1xuICAgICAgY29uc3QgcmVsYXRpdmVGcm9tQmFzZSA9IHBhdGgucmVsYXRpdmUoYmFzZURpciwgcmVzb2x2ZWRQYXRoKTtcbiAgICAgIGlmIChyZWxhdGl2ZUZyb21CYXNlLnN0YXJ0c1dpdGgoXCIuLlwiKSB8fCBwYXRoLmlzQWJzb2x1dGUocmVsYXRpdmVGcm9tQmFzZSkpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzb2x2ZWRQYXRoO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFQSSDsnZHri7Xsl5Ag7KCB7Jqp7ZWgIENhY2hlLUNvbnRyb2wg7ISk7KCV7J2EIOqysOygle2VqeuLiOuLpC5cbiAgICog7Jqw7ISg7Iic7JyEOiDqsJzrs4Qg7KeA7KCVID4gY2FjaGVDb250cm9sSGFuZGxlclxuICAgKi9cbiAgcHJpdmF0ZSBnZXRBcGlDYWNoZUNvbnRyb2woXG4gICAgYXBpOiBFeHRlbmRlZEFwaSxcbiAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICkge1xuICAgIC8vIOuNsOy9lOugiOydtO2EsCDshKTsoJUg7Jqw7ISgXG4gICAgaWYgKGFwaS5vcHRpb25zLmNhY2hlQ29udHJvbCkge1xuICAgICAgcmV0dXJuIGFwaS5vcHRpb25zLmNhY2hlQ29udHJvbDtcbiAgICB9XG5cbiAgICAvLyDsoITsl60g7ZW465Ok65+sXG4gICAgaWYgKGNvbmZpZy5jYWNoZUNvbnRyb2xIYW5kbGVyKSB7XG4gICAgICBjb25zdCBjYWNoZVJlcTogQ2FjaGVDb250cm9sUmVxdWVzdCA9IHtcbiAgICAgICAgdHlwZTogXCJhcGlcIixcbiAgICAgICAgdXJsOiByZXF1ZXN0LnVybCxcbiAgICAgICAgcGF0aDogcmVxdWVzdC5yb3V0ZU9wdGlvbnM/LnVybCA/PyByZXF1ZXN0LnVybC5zcGxpdChcIj9cIilbMF0sXG4gICAgICAgIG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG4gICAgICAgIGFwaSxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXN1bHQgPSBjb25maWcuY2FjaGVDb250cm9sSGFuZGxlcihjYWNoZVJlcSk7XG4gICAgICBpZiAocmVzdWx0KSByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFNTUuyaqSBBUEkg7Zi47LacIChIVFRQIOyYpOuyhO2XpOuTnCDsl4bsnbQg7KeB7KCRIO2YuOy2nClcbiAgICogY3JlYXRlQXBpSGFuZGxlcuydmCDroZzsp4HsnYQg7J6s7IKs7Jqp7ZWY65CYLCByZXF1ZXN0IO2MjOyLsSDrjIDsi6AgcGFyYW1zIOyngeygkSDsgqzsmqlcbiAgICovXG4gIGFzeW5jIGludm9rZUFwaUZvclNTUihcbiAgICBhcGk6IEV4dGVuZGVkQXBpLFxuICAgIHBhcmFtczogYW55W10sXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICAgIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICAgIHJlcGx5OiBGYXN0aWZ5UmVwbHksXG4gICk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgIC8vIENvbnRleHQg7IOd7ISxICjquLDsobQg66mU7IaM65OcIOyerOyCrOyaqSlcbiAgICBjb25zdCBjb250ZXh0ID0gYXdhaXQgdGhpcy5jcmVhdGVDb250ZXh0KGNvbmZpZywgcmVxdWVzdCwgcmVwbHkpO1xuXG4gICAgcmV0dXJuIHRoaXMuYXN5bmNMb2NhbFN0b3JhZ2UucnVuKHsgY29udGV4dCB9LCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyBhcmdzIOyDneyEsTogQ29udGV4dCDtjIzrnbzrr7jthLDripQg7KO87J6FLCDrgpjrqLjsp4DripQgcGFyYW1z7JeQ7IScIOqwgOyguOyYpOq4sFxuICAgICAgY29uc3QgeyBBcGlQYXJhbVR5cGUgfSA9IGF3YWl0IGltcG9ydChcIi4uL3R5cGVzL3R5cGVzXCIpO1xuICAgICAgbGV0IHBhcmFtc0luZGV4ID0gMDtcbiAgICAgIGNvbnN0IGFyZ3MgPSBhcGkucGFyYW1ldGVycy5tYXAoKHBhcmFtKSA9PiB7XG4gICAgICAgIGlmIChBcGlQYXJhbVR5cGUuaXNDb250ZXh0KHBhcmFtLnR5cGUpKSB7XG4gICAgICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhcmFtc1twYXJhbXNJbmRleCsrXTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyDrqqjrjbgg66mU7ISc65OcIO2YuOy2nCAo6riw7KG0IOuplOyEnOuTnCDsnqzsgqzsmqkpXG4gICAgICByZXR1cm4gdGhpcy5pbnZva2VNb2RlbE1ldGhvZChhcGksIGFyZ3MsIHJlcGx5KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFdTIOqyveuhnOyXkOyEnOuKlCBIVFRQIHJlcGx56rCAIOyXhuycvOuvgOuhnCByZXBseeulvCBvcHRpb25hbOuhnCDrsJvslYQg6rO17Ya1IO2YuOy2nCDqsr3roZzrpbwg7Jyg7KeA7ZWoXG4gIGFzeW5jIGludm9rZU1vZGVsTWV0aG9kKFxuICAgIGFwaTogRXh0ZW5kZWRBcGksXG4gICAgYXJnczogdW5rbm93bltdLFxuICAgIHJlcGx5PzogRmFzdGlmeVJlcGx5LFxuICApOiBQcm9taXNlPHVua25vd24+IHtcbiAgICBjb25zdCBtb2RlbCA9IHRoaXMuc3luY2VyLm1vZGVsc1thcGkubW9kZWxOYW1lXTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCAobW9kZWwgYXMgYW55KVthcGkubWV0aG9kTmFtZV0uYXBwbHkobW9kZWwsIGFyZ3MpO1xuICAgIHJlcGx5Py50eXBlKGFwaS5vcHRpb25zLmNvbnRlbnRUeXBlID8/IFwiYXBwbGljYXRpb24vanNvblwiKTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBhc3luYyBjcmVhdGVDb250ZXh0KFxuICAgIGNvbmZpZzogU29uYW11RmFzdGlmeUNvbmZpZyxcbiAgICByZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICByZXBseTogRmFzdGlmeVJlcGx5LFxuICApOiBQcm9taXNlPENvbnRleHQ+IHtcbiAgICAvLyBjcmVhdGVTU0VGYWN0b3J5IO2VqOyImOyXkCDrr7jrpqwgcmVxdWVzdOydmCBzb2NrZXTqs7wgcmVwbHnrpbwg67CU7J2465SpLlxuICAgIGNvbnN0IHsgY3JlYXRlU1NFRmFjdG9yeSB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3RyZWFtL3NzZVwiKTtcbiAgICBjb25zdCBjcmVhdGVTU0UgPSAoPFQgZXh0ZW5kcyBab2RPYmplY3Q+KFxuICAgICAgX3JlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICAgICAgX3JlcGx5OiBGYXN0aWZ5UmVwbHksXG4gICAgICBfZXZlbnRzOiBULFxuICAgICkgPT4gY3JlYXRlU1NFRmFjdG9yeShfcmVxdWVzdC5zb2NrZXQsIF9yZXBseSwgX2V2ZW50cykpLmJpbmQobnVsbCwgcmVxdWVzdCwgcmVwbHkpO1xuXG4gICAgLy8gbG9jYWxlIOqwkOyngFxuICAgIGNvbnN0IGxvY2FsZSA9XG4gICAgICB0aGlzLmRldGVjdExvY2FsZShyZXF1ZXN0LmhlYWRlcnNbXCJhY2NlcHQtbGFuZ3VhZ2VcIl0sIHRoaXMuY29uZmlnLmkxOG4uc3VwcG9ydGVkTG9jYWxlcykgPz9cbiAgICAgIHRoaXMuY29uZmlnLmkxOG4uZGVmYXVsdExvY2FsZTtcblxuICAgIC8vIGF1dGggY29udGV4dCDstpTqsIBcbiAgICBjb25zdCBoZWFkZXJzID0gY29udmVydEZhc3RpZnlIZWFkZXJzVG9TdGFuZGFyZChyZXF1ZXN0LmhlYWRlcnMpO1xuICAgIGNvbnN0IHNlc3Npb24gPSAoYXdhaXQgdGhpcy5fYXV0aD8uYXBpLmdldFNlc3Npb24oeyBoZWFkZXJzIH0pKSA/PyBudWxsO1xuXG4gICAgY29uc3QgY29udGV4dDogQ29udGV4dCA9IGF3YWl0IFByb21pc2UucmVzb2x2ZShcbiAgICAgIGNvbmZpZy5jb250ZXh0UHJvdmlkZXIoXG4gICAgICAgIHtcbiAgICAgICAgICB0cmFuc3BvcnQ6IFwiaHR0cFwiLFxuICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgcmVwbHksXG4gICAgICAgICAgaGVhZGVyczogcmVxdWVzdC5oZWFkZXJzLFxuICAgICAgICAgIGNyZWF0ZVNTRSxcbiAgICAgICAgICBuYWl0ZVN0b3JlOiBuZXcgTWFwKCksXG4gICAgICAgICAgbG9jYWxlLFxuICAgICAgICAgIC8vIGF1dGhcbiAgICAgICAgICB1c2VyOiBzZXNzaW9uPy51c2VyID8/IG51bGwsXG4gICAgICAgICAgc2Vzc2lvbjogc2Vzc2lvbj8uc2Vzc2lvbiA/PyBudWxsLFxuICAgICAgICB9LFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICByZXBseSxcbiAgICAgICksXG4gICAgKTtcbiAgICByZXR1cm4gY29udGV4dDtcbiAgfVxuXG4gIC8vIHNlc3Npb24vbG9jYWxlL3N0b3JlIOqwmeydgCDqs7XthrUgc3RhdGXripQgSFRUUCBjb250ZXh07JmAIOqzteycoO2VmOuQmCwgcmVwbHkvY3JlYXRlU1NFIOqwmeydgCBIVFRQIOyghOyaqSBoZWxwZXLripQg64W47Lac7ZWY7KeAIOyViuydjFxuICAvLyDsgqzsmqnsnpDqsIAgd2Vic29ja2V0Q29udGV4dFByb3ZpZGVy66W8IOyjvOuptCDqt7jrjIDroZwg7JyE7J6E7ZWY6rOgLCDsl4bsnLzrqbQg6riw7KG0IGNvbnRleHRQcm92aWRlcuulvCByZXBseS9TU0Ugc3R1YuqzvCDtlajqu5gg7J6s7Zmc7Jqp7ZWoXG4gIGFzeW5jIGNyZWF0ZVdlYlNvY2tldENvbnRleHQoXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICAgIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICAgIHdzOiBXZWJTb2NrZXRDb250ZXh0W1wid3NcIl0sXG4gICk6IFByb21pc2U8V2ViU29ja2V0Q29udGV4dD4ge1xuICAgIGNvbnN0IGxvY2FsZSA9XG4gICAgICB0aGlzLmRldGVjdExvY2FsZShyZXF1ZXN0LmhlYWRlcnNbXCJhY2NlcHQtbGFuZ3VhZ2VcIl0sIHRoaXMuY29uZmlnLmkxOG4uc3VwcG9ydGVkTG9jYWxlcykgPz9cbiAgICAgIHRoaXMuY29uZmlnLmkxOG4uZGVmYXVsdExvY2FsZTtcblxuICAgIGNvbnN0IGhlYWRlcnMgPSBjb252ZXJ0RmFzdGlmeUhlYWRlcnNUb1N0YW5kYXJkKHJlcXVlc3QuaGVhZGVycyk7XG4gICAgY29uc3Qgc2Vzc2lvbiA9IChhd2FpdCB0aGlzLl9hdXRoPy5hcGkuZ2V0U2Vzc2lvbih7IGhlYWRlcnMgfSkpID8/IG51bGw7XG5cbiAgICBjb25zdCBkZWZhdWx0Q29udGV4dCA9IHtcbiAgICAgIHRyYW5zcG9ydDogXCJ3c1wiIGFzIGNvbnN0LFxuICAgICAgcmVxdWVzdCxcbiAgICAgIGhlYWRlcnM6IHJlcXVlc3QuaGVhZGVycyxcbiAgICAgIHdzLFxuICAgICAgbmFpdGVTdG9yZTogbmV3IE1hcCgpLFxuICAgICAgbG9jYWxlLFxuICAgICAgdXNlcjogc2Vzc2lvbj8udXNlciA/PyBudWxsLFxuICAgICAgc2Vzc2lvbjogc2Vzc2lvbj8uc2Vzc2lvbiA/PyBudWxsLFxuICAgIH07XG5cbiAgICBpZiAoY29uZmlnLndlYnNvY2tldENvbnRleHRQcm92aWRlcikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uKGF3YWl0IFByb21pc2UucmVzb2x2ZShjb25maWcud2Vic29ja2V0Q29udGV4dFByb3ZpZGVyKGRlZmF1bHRDb250ZXh0LCByZXF1ZXN0KSkpLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyByZXBseS9jcmVhdGVTU0Xsl5Ag7J2Y7KG07ZWY64qUIGNvbnRleHRQcm92aWRlcuqwgCDsnojsnLzrqbQg7KaJ7IucIOyXkOufrOulvCDrjZjsoLggdHJhbnNwb3J0IG1pc3VzZeulvCDruajrpqwg65Oc65+s64OEXG4gICAgY29uc3QgcmVwbHlTdHViID0gY3JlYXRlV2ViU29ja2V0UmVwbHlTdHViKCk7XG4gICAgY29uc3QgY3JlYXRlU1NFID0gPFQgZXh0ZW5kcyBab2RPYmplY3Q+KF9ldmVudHM6IFQpID0+IHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJjcmVhdGVTU0UgaXMgbm90IGF2YWlsYWJsZSBpbiB3ZWJzb2NrZXQgY29udGV4dC4gRGVmaW5lIHdlYnNvY2tldENvbnRleHRQcm92aWRlciBpZiB5b3VyIGNvbnRleHQgc2V0dXAgZGVwZW5kcyBvbiBTU0UgaGVscGVycy5cIixcbiAgICAgICk7XG4gICAgfTtcbiAgICBjb25zdCBodHRwTGlrZUNvbnRleHQgPSBhd2FpdCBQcm9taXNlLnJlc29sdmUoXG4gICAgICBjb25maWcuY29udGV4dFByb3ZpZGVyKFxuICAgICAgICB7XG4gICAgICAgICAgdHJhbnNwb3J0OiBcImh0dHBcIixcbiAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgIHJlcGx5OiByZXBseVN0dWIsXG4gICAgICAgICAgaGVhZGVyczogcmVxdWVzdC5oZWFkZXJzLFxuICAgICAgICAgIGNyZWF0ZVNTRSxcbiAgICAgICAgICBuYWl0ZVN0b3JlOiBkZWZhdWx0Q29udGV4dC5uYWl0ZVN0b3JlLFxuICAgICAgICAgIGxvY2FsZSxcbiAgICAgICAgICB1c2VyOiBkZWZhdWx0Q29udGV4dC51c2VyLFxuICAgICAgICAgIHNlc3Npb246IGRlZmF1bHRDb250ZXh0LnNlc3Npb24sXG4gICAgICAgIH0sXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIHJlcGx5U3R1YixcbiAgICAgICksXG4gICAgKTtcblxuICAgIGNvbnN0IHtcbiAgICAgIHRyYW5zcG9ydDogX3RyYW5zcG9ydCxcbiAgICAgIHJlcGx5OiBfcmVwbHksXG4gICAgICBjcmVhdGVTU0U6IF9jcmVhdGVTU0UsXG4gICAgICBidWZmZXJlZEZpbGVzOiBfYnVmZmVyZWRGaWxlcyxcbiAgICAgIHVwbG9hZGVkRmlsZXM6IF91cGxvYWRlZEZpbGVzLFxuICAgICAgLi4ucmVzdFxuICAgIH0gPSBodHRwTGlrZUNvbnRleHQ7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4ucmVzdCxcbiAgICAgIHRyYW5zcG9ydDogXCJ3c1wiLFxuICAgICAgcmVxdWVzdCxcbiAgICAgIGhlYWRlcnM6IHJlcXVlc3QuaGVhZGVycyxcbiAgICAgIHdzLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQWNjZXB0LUxhbmd1YWdlIO2XpOuNlOyXkOyEnCDsp4Dsm5DtlZjripQgbG9jYWxl7J2EIOywvuyKteuLiOuLpC5cbiAgICogQGV4YW1wbGUgXCJrby1LUixrbztxPTAuOSxlbjtxPTAuOFwiIOKGkiBcImtvXCJcbiAgICovXG4gIHByaXZhdGUgZGV0ZWN0TG9jYWxlKFxuICAgIGFjY2VwdExhbmd1YWdlOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICAgc3VwcG9ydGVkOiBzdHJpbmdbXSxcbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIWFjY2VwdExhbmd1YWdlKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgLy8gQWNjZXB0LUxhbmd1YWdlOiBrby1LUixrbztxPTAuOSxlbjtxPTAuOFxuICAgIGNvbnN0IGxhbmdzID0gYWNjZXB0TGFuZ3VhZ2Uuc3BsaXQoXCIsXCIpLm1hcCgobGFuZykgPT4ge1xuICAgICAgY29uc3QgW2NvZGVdID0gbGFuZy5zcGxpdChcIjtcIik7XG4gICAgICByZXR1cm4gY29kZS50cmltKCkuc3BsaXQoXCItXCIpWzBdOyAvLyBrby1LUiDihpIga29cbiAgICB9KTtcblxuICAgIHJldHVybiBsYW5ncy5maW5kKChsYW5nKSA9PiBzdXBwb3J0ZWQuaW5jbHVkZXMobGFuZykpO1xuICB9XG5cbiAgYXN5bmMgc3RhcnRXYXRjaGVyKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIHdhdGNoZXIg66qo65OI7J2AIGZpbGUtcGF0dGVybnMg4oaSIFNvbmFtdSDsiJztmZjsnYQg7ZS87ZWY6riwIOychO2VtCBkeW5hbWljIGltcG9ydCDtlanri4jri6QuXG4gICAgY29uc3QgeyBzZXR1cFdhdGNoZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL3N5bmNlci93YXRjaGVyXCIpO1xuICAgIHRoaXMud2F0Y2hlciA9IGF3YWl0IHNldHVwV2F0Y2hlcigoZmlsZUV2ZW50cykgPT4gdGhpcy5ydW5IbXJTeW5jQ3ljbGUoZmlsZUV2ZW50cykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFdhdGNoZXLqsIAgMTAwbXMgYmF0Y2jroZwg66qo7J2AIGZpbGVFdmVudHMg7ZWY64KY7JeQIOuMgO2VtCDtlZwg67KI7J2YIEhNUi9zeW5jIOyCrOydtO2BtOydhCDrj5Xri4jri6QuXG4gICAqIGJhdGNoIO2BkOyeiSDrjZXsl5Ag7ZWcIOyLnOygkOyXkCDtlZjrgpjrp4wg7Iuk7ZaJ65Co7J20IOuztOyepeuQqeuLiOuLpCAoZXZlbnQtYmF0Y2hlcuqwgCDsp4HroKztmZQpLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBydW5IbXJTeW5jQ3ljbGUoZmlsZUV2ZW50czogTWFwPEFic29sdXRlUGF0aCwgXCJjaGFuZ2VcIiB8IFwiYWRkXCI+KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgc3RhcnRlZEF0ID0gRGF0ZS5ub3coKTtcblxuICAgIGZvciAoY29uc3QgW2ZpbGVQYXRoLCBldmVudF0gb2YgZmlsZUV2ZW50cykge1xuICAgICAgY29uc3QgcmVsYXRpdmVQYXRoID0gcGF0aC5yZWxhdGl2ZSh0aGlzLmFwcFJvb3RQYXRoLCBmaWxlUGF0aCk7XG4gICAgICBjb25zb2xlLmxvZyhjaGFsay5ib2xkKGBEZXRlY3RlZCgke2V2ZW50fSk6ICR7Y2hhbGsuYmx1ZShyZWxhdGl2ZVBhdGgpfWApKTtcbiAgICB9XG5cbiAgICAvLyDrs7jssrQ6IOuzgOqyvSDtnaHsiJggKyDssrTtgazshKwg6rCx7IugLlxuICAgIGF3YWl0IHRoaXMuc3luY2VyLmhtckFuZFN5bmMoZmlsZUV2ZW50cyk7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIucmVuZXdDaGVja3N1bXMoKTtcblxuICAgIGNvbnN0IHRvdGFsVGltZSA9IERhdGUubm93KCkgLSBzdGFydGVkQXQ7XG4gICAgY29uc3QgbXNnID0gYEhNUiBEb25lISAke2NoYWxrLmJvbGQud2hpdGUoYCR7dG90YWxUaW1lfW1zYCl9YDtcbiAgICBjb25zb2xlLmxvZyhjaGFsay5ibGFjay5iZ0dyZWVuKGNlbnRlclRleHQobXNnKSkpO1xuICB9XG5cbiAgLypcbiAgICAgQSBmdW5jdGlvbiB0aGF0IGF1dG9tYXRpY2FsbHkgaGFuZGxlcyBpbml0IGFuZCBkZXN0cm95IHdoZW4gdXNpbmcgU29uYW11IHZpYSBzY3JpcHRzLlxuICAqL1xuICBhc3luYyBydW5TY3JpcHQoZm46ICgpID0+IFByb21pc2U8dm9pZD4pIHtcbiAgICBhd2FpdCB0aGlzLmluaXQodHJ1ZSwgZmFsc2UsIHVuZGVmaW5lZCwgZmFsc2UpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBmbigpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCB0aGlzLmRlc3Ryb3koKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlZ2lzdGVyUGx1Z2lucyhzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZSwgcGx1Z2luczogU29uYW11U2VydmVyT3B0aW9uc1tcInBsdWdpbnNcIl0pIHtcbiAgICBpZiAoIXBsdWdpbnMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBjb21wcmVzcyDtlIzrn6zqt7jsnbjsnYAg64uk66W4IO2UjOufrOq3uOyduOuztOuLpCDrqLzsoIAg65Ox66Gd65CY7Ja07JW8IO2VqeuLiOuLpC5cbiAgICBpZiAocGx1Z2lucy5jb21wcmVzcykge1xuICAgICAgY29uc3QgY29tcHJlc3NQbHVnaW4gPSAoYXdhaXQgaW1wb3J0KFwiQGZhc3RpZnkvY29tcHJlc3NcIikpLmRlZmF1bHQ7XG4gICAgICBjb25zdCBkZWZhdWx0T3B0aW9ucyA9IHtcbiAgICAgICAgdGhyZXNob2xkOiAxMDI0LFxuICAgICAgICBlbmNvZGluZ3M6IFtcImJyXCIsIFwiZ3ppcFwiLCBcImRlZmxhdGVcIl0gYXMgKFwiYnJcIiB8IFwiZ3ppcFwiIHwgXCJkZWZsYXRlXCIpW10sXG4gICAgICB9O1xuXG4gICAgICBpZiAocGx1Z2lucy5jb21wcmVzcyA9PT0gdHJ1ZSkge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoY29tcHJlc3NQbHVnaW4sIGRlZmF1bHRPcHRpb25zKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNlcnZlci5yZWdpc3Rlcihjb21wcmVzc1BsdWdpbiwge1xuICAgICAgICAgIC4uLmRlZmF1bHRPcHRpb25zLFxuICAgICAgICAgIC4uLnBsdWdpbnMuY29tcHJlc3MsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHBsdWdpbnNNb2R1bGVzID0ge1xuICAgICAgY29yczogXCJAZmFzdGlmeS9jb3JzXCIsXG4gICAgICBmb3JtYm9keTogXCJAZmFzdGlmeS9mb3JtYm9keVwiLFxuICAgICAgbXVsdGlwYXJ0OiBcIkBmYXN0aWZ5L211bHRpcGFydFwiLFxuICAgICAgcXM6IFwiZmFzdGlmeS1xc1wiLFxuICAgICAgc3NlOiBcImZhc3RpZnktc3NlLXYyXCIsXG4gICAgICBzdGF0aWM6IFwiQGZhc3RpZnkvc3RhdGljXCIsXG4gICAgfSBhcyBjb25zdDtcblxuICAgIGNvbnN0IHJlZ2lzdGVyUGx1Z2luID0gYXN5bmMgPEsgZXh0ZW5kcyBrZXlvZiBOb25OdWxsYWJsZTx0eXBlb2YgcGx1Z2lucz4+KFxuICAgICAga2V5OiBLLFxuICAgICAgcGx1Z2luTmFtZTogc3RyaW5nLFxuICAgICkgPT4ge1xuICAgICAgY29uc3Qgb3B0aW9uID0gcGx1Z2luc1trZXldO1xuICAgICAgaWYgKCFvcHRpb24pIHJldHVybjtcblxuICAgICAgaWYgKG9wdGlvbiA9PT0gdHJ1ZSkge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoKGF3YWl0IGltcG9ydChwbHVnaW5OYW1lKSkuZGVmYXVsdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoKGF3YWl0IGltcG9ydChwbHVnaW5OYW1lKSkuZGVmYXVsdCwgb3B0aW9uKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZm9yIChjb25zdCBba2V5LCBwbHVnaW5OYW1lXSBvZiBPYmplY3QuZW50cmllcyhwbHVnaW5zTW9kdWxlcykpIHtcbiAgICAgIGF3YWl0IHJlZ2lzdGVyUGx1Z2luKGtleSBhcyBrZXlvZiB0eXBlb2YgcGx1Z2lucywgcGx1Z2luTmFtZSk7XG4gICAgfVxuXG4gICAgaWYgKHBsdWdpbnMud3MpIHtcbiAgICAgIGF3YWl0IHRoaXMuZW5zdXJlV2ViU29ja2V0UGx1Z2luKHNlcnZlcik7XG4gICAgfVxuXG4gICAgaWYgKHBsdWdpbnMuY3VzdG9tKSB7XG4gICAgICBwbHVnaW5zLmN1c3RvbShzZXJ2ZXIpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEBmYXN0aWZ5L3dlYnNvY2tldOydgCBwbHVnaW5zLndz6rCAIOyEpOygleuQnCDqsr3smrDsl5Drp4wg65Ox66Gd7ZWY6rOgLCDqsJnsnYAgc2VydmVy7JeQIOykkeuztSDrk7HroZ3rkJjsp4Ag7JWK64+E66GdIFdlYWtTZXTsnLzroZwg6riw66Gd7ZWoXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlV2ViU29ja2V0UGx1Z2luKFxuICAgIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT4sXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLndlYnNvY2tldFBsdWdpblNlcnZlcnMuaGFzKHNlcnZlcikpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwbHVnaW5PcHRpb24gPSB0aGlzLmNvbmZpZy5zZXJ2ZXIucGx1Z2lucz8ud3M7XG4gICAgaWYgKCFwbHVnaW5PcHRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB3ZWJzb2NrZXRQbHVnaW4gPSAoYXdhaXQgaW1wb3J0KFwiQGZhc3RpZnkvd2Vic29ja2V0XCIpKS5kZWZhdWx0O1xuICAgIGNvbnN0IHJlc29sdmVkUGx1Z2luT3B0aW9ucyA9IHJlc29sdmVXZWJTb2NrZXRQbHVnaW5PcHRpb25zKHtcbiAgICAgIHJhd1BsdWdpbk9wdGlvbjogcGx1Z2luT3B0aW9uLFxuICAgIH0pO1xuICAgIGlmIChyZXNvbHZlZFBsdWdpbk9wdGlvbnMpIHtcbiAgICAgIGF3YWl0IHNlcnZlci5yZWdpc3Rlcih3ZWJzb2NrZXRQbHVnaW4sIHJlc29sdmVkUGx1Z2luT3B0aW9ucyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHNlcnZlci5yZWdpc3Rlcih3ZWJzb2NrZXRQbHVnaW4pO1xuICAgIH1cblxuICAgIHRoaXMud2Vic29ja2V0UGx1Z2luU2VydmVycy5hZGQoc2VydmVyKTtcbiAgICB0aGlzLndhcm5PblBvdGVudGlhbFdlYlNvY2tldFRpbWVvdXRDb25mbGljdHMoc2VydmVyKTtcbiAgfVxuXG4gIC8vIGhlYXJ0YmVhdCBpbnRlcnZhbOydtCBGYXN0aWZ5IGtlZXBBbGl2ZVRpbWVvdXQg7J207IOB7J2066m0IOyduO2UhOudvOqwgCDrqLzsoIAgaWRsZSDsl7DqsrDsnYQg64GK7J2EIOyImCDsnojslrQg6rK96rOg66eMIOuCqOq4sOqzoCDrhJjslrTqsJBcbiAgcHJpdmF0ZSB3YXJuT25Qb3RlbnRpYWxXZWJTb2NrZXRUaW1lb3V0Q29uZmxpY3RzKFxuICAgIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT4sXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IGhlYXJ0YmVhdHMgPSB0aGlzLnN5bmNlci5hcGlzXG4gICAgICAubWFwKChhcGkpID0+IGFwaS53ZWJzb2NrZXRPcHRpb25zPy5oZWFydGJlYXQgPz8gMzAwMDApXG4gICAgICAuZmlsdGVyKChoZWFydGJlYXQpID0+IGhlYXJ0YmVhdCA+IDApO1xuXG4gICAgaWYgKGhlYXJ0YmVhdHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qga2VlcEFsaXZlVGltZW91dCA9IHRoaXMuY29uZmlnLnNlcnZlci5mYXN0aWZ5Py5rZWVwQWxpdmVUaW1lb3V0O1xuICAgIGlmICgha2VlcEFsaXZlVGltZW91dCB8fCBrZWVwQWxpdmVUaW1lb3V0IDw9IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBsYXJnZXN0SGVhcnRiZWF0ID0gTWF0aC5tYXgoLi4uaGVhcnRiZWF0cyk7XG4gICAgaWYgKGxhcmdlc3RIZWFydGJlYXQgPj0ga2VlcEFsaXZlVGltZW91dCkge1xuICAgICAgc2VydmVyLmxvZy53YXJuKFxuICAgICAgICB7XG4gICAgICAgICAga2VlcEFsaXZlVGltZW91dCxcbiAgICAgICAgICBsYXJnZXN0SGVhcnRiZWF0LFxuICAgICAgICB9LFxuICAgICAgICBcIldlYlNvY2tldCBoZWFydGJlYXQgaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvIGtlZXBBbGl2ZVRpbWVvdXQ7IGFsaWduIGluZnJhc3RydWN0dXJlIGlkbGUgdGltZW91dHMgdG8gYXZvaWQgdW5leHBlY3RlZCBkaXNjb25uZWN0cy5cIixcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIGJldHRlci1hdXRoIOudvOyasO2KuOulvCDrk7HroZ3tlanri4jri6QuXG4gICAqIC9hcGkvYXV0aC8qIOqyveuhnOuhnCDsnbjspp0gQVBJ6rCAIOyekOuPmSDrk7HroZ3rkKnri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlZ2lzdGVyQmV0dGVyQXV0aChcbiAgICBzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZSxcbiAgICBvcHRpb25zOiBOb25OdWxsYWJsZTxTb25hbXVTZXJ2ZXJPcHRpb25zW1wiYXV0aFwiXT4sXG4gICkge1xuICAgIGlmICghb3B0aW9ucykgcmV0dXJuO1xuXG4gICAgY29uc3QgYmFzZVBhdGggPSBvcHRpb25zLmJhc2VQYXRoID8/IFwiL2FwaS9hdXRoXCI7XG5cbiAgICAvLyBiZXR0ZXItYXV0aCDrnbzsmrDtirgg65Ox66GdXG4gICAgc2VydmVyLnJvdXRlKHtcbiAgICAgIG1ldGhvZDogW1wiR0VUXCIsIFwiUE9TVFwiXSxcbiAgICAgIHVybDogYCR7YmFzZVBhdGh9LypgLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5hdXRoLmhhbmRsZXIoXG4gICAgICAgICAgY3JlYXRlQmV0dGVyQXV0aFJlcXVlc3QocmVxdWVzdCwgb3B0aW9ucy5hZHZhbmNlZD8uaXBBZGRyZXNzPy5pcEFkZHJlc3NIZWFkZXJzKSxcbiAgICAgICAgKTtcblxuICAgICAgICByZXBseS5zdGF0dXMocmVzcG9uc2Uuc3RhdHVzKTtcbiAgICAgICAgcmVzcG9uc2UuaGVhZGVycy5mb3JFYWNoKCh2YWx1ZTogc3RyaW5nLCBrZXk6IHN0cmluZykgPT4ge1xuICAgICAgICAgIHJlcGx5LmhlYWRlcihrZXksIHZhbHVlKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiByZXBseS5zZW5kKHJlc3BvbnNlLmJvZHkgPyBhd2FpdCByZXNwb25zZS50ZXh0KCkgOiBudWxsKTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHByaW50U3RhcnR1cFN1bW1hcnkoKSB7XG4gICAgY29uc3QgY2hhbGsgPSAoYXdhaXQgaW1wb3J0KFwiY2hhbGtcIikpLmRlZmF1bHQ7XG4gICAgY29uc3QgYWN0aXZlUHJlc2V0ID0gZ2V0U29uYW11RW52aXJvbm1lbnQoKTtcblxuICAgIGNvbnN0IGRpbSA9IChtc2c6IHN0cmluZykgPT4gY29uc29sZS5sb2coY2hhbGsuZGltKGDinJMgJHttc2d9YCkpO1xuICAgIGNvbnN0IGdyZWVuID0gKG1zZzogc3RyaW5nKSA9PiBjb25zb2xlLmxvZyhjaGFsay5ncmVlbihg4pyTICR7bXNnfWApKTtcblxuICAgIGRpbShgQ29uZmlnIGxvYWRlZCR7Zm9ybWF0VGltZSh0aGlzLl9jb25maWdFbGFwc2VkKX1gKTtcblxuICAgIC8vIERCIHByZXNldCDrqqnroZ1cbiAgICBncmVlbihcIkRCXCIpO1xuICAgIGNvbnN0IHsgaXNMb2NhbCB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvY29udHJvbGxlclwiKTtcbiAgICBjb25zdCBwcmVzZXROYW1lcyA9IE9iamVjdC5rZXlzKHRoaXMuZGJDb25maWcpIGFzIChrZXlvZiBTb25hbXVEQkNvbmZpZylbXTtcbiAgICBjb25zdCBtYXhMZW4gPSBNYXRoLm1heCguLi5wcmVzZXROYW1lcy5tYXAoKG4pID0+IG4ubGVuZ3RoKSk7XG4gICAgZm9yIChjb25zdCBuYW1lIG9mIHByZXNldE5hbWVzKSB7XG4gICAgICBjb25zdCBjb25uID0gdGhpcy5kYkNvbmZpZ1tuYW1lXS5jb25uZWN0aW9uIGFzXG4gICAgICAgIHwgeyBob3N0Pzogc3RyaW5nOyBwb3J0PzogbnVtYmVyOyBkYXRhYmFzZT86IHN0cmluZyB9XG4gICAgICAgIHwgdW5kZWZpbmVkO1xuICAgICAgY29uc3QgaG9zdCA9IGNvbm4/Lmhvc3QgPz8gXCJsb2NhbGhvc3RcIjtcbiAgICAgIGNvbnN0IGFkZHIgPSBgQCAke2hvc3R9OiR7Y29ubj8ucG9ydCA/PyA1NDMyfS8ke2Nvbm4/LmRhdGFiYXNlID8/IFwiKHVua25vd24pXCJ9YDtcbiAgICAgIGNvbnN0IHBhZGRlZCA9IG5hbWUucGFkRW5kKG1heExlbik7XG4gICAgICBjb25zdCByZW1vdGVUYWcgPSBpc0xvY2FsKCkgJiYgIWlzTG9jYWxIb3N0KGhvc3QpID8gY2hhbGsueWVsbG93KGAgXFx1MjZhMCByZW1vdGVgKSA6IFwiXCI7XG5cbiAgICAgIGlmIChuYW1lID09PSBhY3RpdmVQcmVzZXQpIHtcbiAgICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYCAgXFx1MjViOCAke3BhZGRlZH0gJHthZGRyfWApICsgcmVtb3RlVGFnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmRpbShgICAgICR7cGFkZGVkfSAke2FkZHJ9YCkgKyByZW1vdGVUYWcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmZpZy5zZXJ2ZXIuYXV0aCkge1xuICAgICAgY29uc3QgYmFzZVBhdGggPSB0aGlzLmNvbmZpZy5zZXJ2ZXIuYXV0aC5iYXNlUGF0aCA/PyBcIi9hcGkvYXV0aFwiO1xuICAgICAgZGltKGBBdXRoOiBiZXR0ZXItYXV0aCBhdCAke2Jhc2VQYXRofS8qYCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmNvbmZpZy5hcGkudGltZXpvbmUpIHtcbiAgICAgIGRpbShgVGltZXpvbmU6ICR7dGhpcy5jb25maWcuYXBpLnRpbWV6b25lfWApO1xuICAgIH1cbiAgICBncmVlbihgU29uYW11IHJlYWR5JHtmb3JtYXRUaW1lKHRoaXMuX2luaXRFbGFwc2VkKX1gKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaW5pdGlhbGl6ZUNhY2hlKGNvbmZpZzogQ2FjaGVDb25maWcgfCB1bmRlZmluZWQsIGZvclRlc3Rpbmc6IGJvb2xlYW4pIHtcbiAgICBjb25zdCB7IHNldENhY2hlTWFuYWdlclJlZiB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vY2FjaGUvZGVjb3JhdG9yXCIpO1xuXG4gICAgLy8g7YWM7Iqk7Yq4IO2ZmOqyveyXkOyEnCDrqZTrqqjrpqwg65Oc65287J2067KEIOyekOuPmSDsgqzsmqlcbiAgICBpZiAoZm9yVGVzdGluZykge1xuICAgICAgY29uc3QgeyBjcmVhdGVUZXN0Q2FjaGVNYW5hZ2VyIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9jYWNoZS9jYWNoZS1tYW5hZ2VyXCIpO1xuICAgICAgdGhpcy5fY2FjaGUgPSBjcmVhdGVUZXN0Q2FjaGVNYW5hZ2VyKCk7XG4gICAgICBzZXRDYWNoZU1hbmFnZXJSZWYodGhpcy5fY2FjaGUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIOyEpOygleydtCDsl4bsnLzrqbQg7LqQ7IucIOu5hO2ZnOyEse2ZlFxuICAgIGlmICghY29uZmlnKSB7XG4gICAgICBzZXRDYWNoZU1hbmFnZXJSZWYobnVsbCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8g7ISk7KCV7JeQIOuUsOudvCBDYWNoZU1hbmFnZXIg7IOd7ISxXG4gICAgY29uc3QgeyBjcmVhdGVDYWNoZU1hbmFnZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL2NhY2hlL2NhY2hlLW1hbmFnZXJcIik7XG4gICAgdGhpcy5fY2FjaGUgPSBjcmVhdGVDYWNoZU1hbmFnZXIoY29uZmlnKTtcbiAgICBzZXRDYWNoZU1hbmFnZXJSZWYodGhpcy5fY2FjaGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBpbml0aWFsaXplV29ya2Zsb3dzKG9wdGlvbnM6IFNvbmFtdVRhc2tPcHRpb25zIHwgdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgeyBXb3JrZmxvd01hbmFnZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL3Rhc2tzL3dvcmtmbG93LW1hbmFnZXJcIik7XG4gICAgLy8gTk9URTogQHNvbmFtdS1raXQvdGFza3Mg7JWI7JeQ7ISgIGtuZXggY29uZmln66W8IOyImOygle2VmOq4sCDrlYzrrLjsl5AgY29ubmVjdGlvbuydtCDslYTri4wgY29uZmlnIOynuOuhnCDrs7Trg4Xri4jri6QuXG4gICAgdGhpcy5fd29ya2Zsb3dzID0gbmV3IFdvcmtmbG93TWFuYWdlcihEQi5nZXREQkNvbmZpZyhcIndcIikpO1xuICAgIGlmICghb3B0aW9ucykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGVuYWJsZVdvcmtlciA9IG9wdGlvbnMuZW5hYmxlV29ya2VyID8/IGlzRGFlbW9uU2VydmVyKCk7XG4gICAgY29uc3QgZGVmYXVsdFdvcmtlck9wdGlvbnMgPSB7XG4gICAgICBjb25jdXJyZW5jeTogb3MuY3B1cygpLmxlbmd0aCAtIDEsXG4gICAgICB1c2VQdWJTdWI6IHRydWUsXG4gICAgICBsaXN0ZW5EZWxheTogNTAwLFxuICAgIH07XG5cbiAgICBpZiAoZW5hYmxlV29ya2VyKSB7XG4gICAgICB0aGlzLndvcmtmbG93cy5zZXR1cFdvcmtlcih7XG4gICAgICAgIC4uLmRlZmF1bHRXb3JrZXJPcHRpb25zLFxuICAgICAgICAuLi5vcHRpb25zLndvcmtlck9wdGlvbnMsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGJvb3Qoc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2UsIG9wdGlvbnM6IFNvbmFtdVNlcnZlck9wdGlvbnMpIHtcbiAgICBjb25zdCBwb3J0ID0gb3B0aW9ucy5saXN0ZW4/LnBvcnQgPz8gMzAwMDtcbiAgICBjb25zdCBob3N0ID0gb3B0aW9ucy5saXN0ZW4/Lmhvc3QgPz8gXCJsb2NhbGhvc3RcIjtcblxuICAgIHNlcnZlci5hZGRIb29rKFwib25DbG9zZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBvcHRpb25zLmxpZmVjeWNsZT8ub25TaHV0ZG93bj8uKHNlcnZlcik7XG4gICAgICBhd2FpdCB0aGlzLndvcmtmbG93cy5kZXN0cm95KCk7XG4gICAgICBhd2FpdCB0aGlzLmRlc3Ryb3koKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHNodXRkb3duID0gYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc2VydmVyLmNsb3NlKCk7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3IgZHVyaW5nIHNodXRkb3duOlwiLCBlcnIpO1xuICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHByb2Nlc3Mub24oXCJTSUdJTlRcIiwgc2h1dGRvd24pO1xuICAgIHByb2Nlc3Mub24oXCJTSUdURVJNXCIsIHNodXRkb3duKTtcblxuICAgIGlmIChvcHRpb25zLmxpZmVjeWNsZT8ub25FcnJvcikge1xuICAgICAgc2VydmVyLnNldEVycm9ySGFuZGxlcihvcHRpb25zLmxpZmVjeWNsZT8ub25FcnJvcik7XG4gICAgfVxuXG4gICAgc2VydmVyXG4gICAgICAubGlzdGVuKHsgcG9ydCwgaG9zdCB9KVxuICAgICAgLnRoZW4oYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB0aGlzLndvcmtmbG93cy5zdGFydFdvcmtlcigpO1xuICAgICAgICBhd2FpdCBvcHRpb25zLmxpZmVjeWNsZT8ub25TdGFydD8uKHNlcnZlcik7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGFzeW5jIChlcnIpID0+IHtcbiAgICAgICAgY29uc3QgY2hhbGsgPSAoYXdhaXQgaW1wb3J0KFwiY2hhbGtcIikpLmRlZmF1bHQ7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoY2hhbGsucmVkKFwiRmFpbGVkIHRvIHN0YXJ0IHNlcnZlcjpcIiwgZXJyKSk7XG4gICAgICAgIGF3YWl0IHNodXRkb3duKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGRlc3Ryb3koKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyBCYXNlTW9kZWwgfSA9IGF3YWl0IGltcG9ydChcIi4uL2RhdGFiYXNlL2Jhc2UtbW9kZWxcIik7XG4gICAgLy8g66i87KCAIOyymOumrO2VtOyVvO2VqC5cbiAgICBhd2FpdCBCYXNlTW9kZWwuZGVzdHJveSgpO1xuICAgIC8vIFdlYlNvY2tldCBzaHV0ZG93biBmaXJzdCB0byBmbHVzaCB0ZWxlbWV0cnlcbiAgICBpZiAodGhpcy5fd2Vic29ja2V0UnVudGltZSkge1xuICAgICAgYXdhaXQgdGhpcy5fd2Vic29ja2V0UnVudGltZS5zaHV0ZG93bigpO1xuICAgIH1cbiAgICB0aGlzLl93ZWJzb2NrZXRSdW50aW1lID0gbnVsbDtcbiAgICAvLyBUaGVuIHNodXQgZG93biByZW1haW5pbmcgcmVzb3VyY2VzIGluIHBhcmFsbGVsXG4gICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFtcbiAgICAgIHRoaXMuX3dvcmtmbG93cz8uZGVzdHJveSgpID8/IFByb21pc2UucmVzb2x2ZSgpLFxuICAgICAgdGhpcy5fY2FjaGU/LmRpc2Nvbm5lY3QoKSA/PyBQcm9taXNlLnJlc29sdmUoKSxcbiAgICAgIHRoaXMuX2RldlZpdGVzdE1hbmFnZXI/LnNodXRkb3duKCkgPz8gUHJvbWlzZS5yZXNvbHZlKCksXG4gICAgICB0aGlzLndhdGNoZXI/LmNsb3NlKCkgPz8gUHJvbWlzZS5yZXNvbHZlKCksXG4gICAgXSk7XG4gICAgLy8gTG9nVGFwZSBkaXNwb3NlIGFmdGVyIFdTIHNodXRkb3duIHNvIHRlbGVtZXRyeSByZWNvcmRzIGFyZSBmbHVzaGVkIGZpcnN0XG4gICAgYXdhaXQgbG9ndGFwZURpc3Bvc2UoKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRXZWJTb2NrZXRUZWxlbWV0cnlDb250ZXh0KFxuICB3czogV2ViU29ja2V0Q29ubmVjdGlvbjxXZWJTb2NrZXRFdmVudE1hcCwgV2ViU29ja2V0RXZlbnRNYXA+LFxuKTogV2ViU29ja2V0VGVsZW1ldHJ5Q29ubmVjdGlvbkNvbnRleHQge1xuICBpZiAoIWlzVGVsZW1ldHJ5Q29udGV4dFByb3ZpZGVyKHdzKSkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIHJldHVybiB3cy5nZXRUZWxlbWV0cnlDb250ZXh0KCk7XG59XG5cbmZ1bmN0aW9uIGlzVGVsZW1ldHJ5Q29udGV4dFByb3ZpZGVyKFxuICB3czogV2ViU29ja2V0Q29ubmVjdGlvbjxXZWJTb2NrZXRFdmVudE1hcCwgV2ViU29ja2V0RXZlbnRNYXA+LFxuKTogd3MgaXMgV2ViU29ja2V0Q29ubmVjdGlvbjxXZWJTb2NrZXRFdmVudE1hcCwgV2ViU29ja2V0RXZlbnRNYXA+ICYgVGVsZW1ldHJ5Q29udGV4dFByb3ZpZGVyIHtcbiAgcmV0dXJuIFwiZ2V0VGVsZW1ldHJ5Q29udGV4dFwiIGluIHdzICYmIHR5cGVvZiB3cy5nZXRUZWxlbWV0cnlDb250ZXh0ID09PSBcImZ1bmN0aW9uXCI7XG59XG5cbmV4cG9ydCBjb25zdCBTb25hbXUgPSBuZXcgU29uYW11Q2xhc3MoKTtcblxuLyoqXG4gKiBzdHJlYW0g66qo65Oc7JeQ7IScIO2CpCDsg53shLEg7ZWo7IiY6rCAIOyngOygleuQmOyngCDslYrslZjsnYQg65WMIOyCrOyaqe2VmOuKlCDquLDrs7gg7ZWo7IiY7J6F64uI64ukLlxuICovXG5mdW5jdGlvbiBkZWZhdWx0S2V5R2VuZXJhdG9yKGZpbGU6IHsgZmlsZW5hbWU6IHN0cmluZzsgbWltZXR5cGU6IHN0cmluZyB9KTogc3RyaW5nIHtcbiAgY29uc3QgZXh0ID0gbWltZS5leHRlbnNpb24oZmlsZS5taW1ldHlwZSkgfHwgXCJiaW5cIjtcbiAgY29uc3QgdGltZXN0YW1wID0gRGF0ZS5ub3coKTtcbiAgY29uc3QgcmFuZG9tID0gTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMiwgOCk7XG4gIHJldHVybiBgdXBsb2Fkcy8ke3RpbWVzdGFtcH0tJHtyYW5kb219LiR7ZXh0fWA7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFRpbWUobXM6IG51bWJlcik6IHN0cmluZyB7XG4gIGNvbnN0IGZvcm1hdHRlZCA9IG1zID49IDEwMDAgPyBgJHsobXMgLyAxMDAwKS50b0ZpeGVkKDIpfXNgIDogYCR7TWF0aC5yb3VuZChtcyl9bXNgO1xuICByZXR1cm4gYCAoJHtmb3JtYXR0ZWR9KWA7XG59XG5cbmNvbnN0IExPQ0FMX0hPU1RTID0gbmV3IFNldChbXCJsb2NhbGhvc3RcIiwgXCIxMjcuMC4wLjFcIiwgXCIwLjAuMC4wXCIsIFwiOjoxXCJdKTtcbmZ1bmN0aW9uIGlzTG9jYWxIb3N0KGhvc3Q6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gTE9DQUxfSE9TVFMuaGFzKGhvc3QpIHx8IGhvc3QuZW5kc1dpdGgoXCIubG9jYWxcIik7XG59XG5cbi8vIGAuZXZlcnkoKWDqsIAg7LKrIGd1YXJkIOydtO2bhCDsiJztmozrpbwg66mI7LaU64qUIOusuOygnOqwgCDsnojslrQgYGZvci4uLm9mYOuhnCDrqqjrk6AgZ3VhcmTrpbwg7Iic7ISc64yA66GcIOyLpO2Wie2VmOuPhOuhnSDqs6DsoJXtlahcbmZ1bmN0aW9uIHJ1bkd1YXJkcyh7XG4gIGd1YXJkcyxcbiAgY29uZmlnLFxuICByZXF1ZXN0LFxuICBhcGksXG59OiB7XG4gIGd1YXJkczogRXh0ZW5kZWRBcGlbXCJvcHRpb25zXCJdW1wiZ3VhcmRzXCJdIHwgdW5kZWZpbmVkO1xuICBjb25maWc6IFBpY2s8U29uYW11RmFzdGlmeUNvbmZpZywgXCJndWFyZEhhbmRsZXJcIj47XG4gIHJlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0O1xuICBhcGk6IEV4dGVuZGVkQXBpO1xufSk6IHZvaWQge1xuICBmb3IgKGNvbnN0IGd1YXJkIG9mIGd1YXJkcyA/PyBbXSkge1xuICAgIGNvbmZpZy5ndWFyZEhhbmRsZXIoZ3VhcmQsIHJlcXVlc3QsIGFwaSk7XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZzdEQSxTQUFTLDZCQUNQLElBQ3FDO0NBQ3JDLElBQUksQ0FBQywyQkFBMkIsRUFBRSxHQUNoQyxPQUFPLENBQUM7Q0FHVixPQUFPLEdBQUcsb0JBQW9CO0FBQ2hDO0FBRUEsU0FBUywyQkFDUCxJQUM0RjtDQUM1RixPQUFPLHlCQUF5QixNQUFNLE9BQU8sR0FBRyx3QkFBd0I7QUFDMUU7Ozs7QUFPQSxTQUFTLG9CQUFvQixNQUFzRDtDQUNqRixNQUFNLE1BQU0sS0FBSyxVQUFVLEtBQUssUUFBUSxLQUFLO0NBRzdDLE9BQU8sV0FGVyxLQUFLLElBRUwsRUFBVSxHQURiLEtBQUssT0FBTyxDQUFDLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FDcEIsRUFBTyxHQUFHO0FBQzNDO0FBRUEsU0FBUyxXQUFXLElBQW9CO0NBRXRDLE9BQU8sS0FEVyxNQUFNLE1BQU8sSUFBSSxLQUFLLElBQUEsQ0FBTSxRQUFRLENBQUMsRUFBRSxLQUFLLEdBQUcsS0FBSyxNQUFNLEVBQUUsRUFBRSxJQUMxRDtBQUN4QjtBQUdBLFNBQVMsWUFBWSxNQUF1QjtDQUMxQyxPQUFPLFlBQVksSUFBSSxJQUFJLEtBQUssS0FBSyxTQUFTLFFBQVE7QUFDeEQ7QUFHQSxTQUFTLFVBQVUsRUFDakIsUUFDQSxRQUNBLFNBQ0Es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