sonamu 0.9.19 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +36 -0
  2. package/dist/ai/agents/agent.js +5 -7
  3. package/dist/ai/agents/index.js +1 -2
  4. package/dist/ai/agents/types.js +1 -1
  5. package/dist/ai/index.js +1 -2
  6. package/dist/ai/providers/rtzr/api.js +2 -3
  7. package/dist/ai/providers/rtzr/error.js +14 -29
  8. package/dist/ai/providers/rtzr/index.js +1 -2
  9. package/dist/ai/providers/rtzr/model.js +13 -20
  10. package/dist/ai/providers/rtzr/options.js +2 -3
  11. package/dist/ai/providers/rtzr/provider.js +2 -3
  12. package/dist/ai/providers/rtzr/utils.js +12 -21
  13. package/dist/api/base-frame.js +4 -4
  14. package/dist/api/caster.js +21 -38
  15. package/dist/api/code-converters.js +41 -98
  16. package/dist/api/config.d.ts +1 -10
  17. package/dist/api/config.d.ts.map +1 -1
  18. package/dist/api/config.js +9 -8
  19. package/dist/api/context.js +2 -3
  20. package/dist/api/decorators.js +80 -116
  21. package/dist/api/index.js +2 -3
  22. package/dist/api/secret.js +6 -10
  23. package/dist/api/sonamu.d.ts.map +1 -1
  24. package/dist/api/sonamu.js +200 -387
  25. package/dist/api/validator.js +5 -8
  26. package/dist/api/websocket-helpers.js +21 -32
  27. package/dist/auth/audit-log/builders.js +2 -3
  28. package/dist/auth/audit-log/events.js +2 -2
  29. package/dist/auth/audit-log/plugin.js +30 -61
  30. package/dist/auth/audit-log-ingestor.js +19 -41
  31. package/dist/auth/auth-generator.js +16 -41
  32. package/dist/auth/better-auth-entities.js +3 -4
  33. package/dist/auth/index.js +2 -3
  34. package/dist/auth/knex-adapter.js +18 -45
  35. package/dist/auth/plugins/entity-definitions/admin.js +2 -2
  36. package/dist/auth/plugins/entity-definitions/anonymous.js +2 -2
  37. package/dist/auth/plugins/entity-definitions/api-key.js +2 -2
  38. package/dist/auth/plugins/entity-definitions/audit-log.js +2 -2
  39. package/dist/auth/plugins/entity-definitions/index.js +2 -3
  40. package/dist/auth/plugins/entity-definitions/jwt.js +2 -2
  41. package/dist/auth/plugins/entity-definitions/organization.js +2 -2
  42. package/dist/auth/plugins/entity-definitions/passkey.js +2 -2
  43. package/dist/auth/plugins/entity-definitions/phone-number.js +2 -2
  44. package/dist/auth/plugins/entity-definitions/sso.js +2 -2
  45. package/dist/auth/plugins/entity-definitions/two-factor.js +2 -2
  46. package/dist/auth/plugins/entity-definitions/types.js +1 -1
  47. package/dist/auth/plugins/entity-definitions/username.js +2 -2
  48. package/dist/auth/plugins/index.js +1 -2
  49. package/dist/auth/plugins/wrappers/admin.js +2 -3
  50. package/dist/auth/plugins/wrappers/anonymous.js +2 -3
  51. package/dist/auth/plugins/wrappers/api-key.js +2 -3
  52. package/dist/auth/plugins/wrappers/index.js +1 -2
  53. package/dist/auth/plugins/wrappers/jwt.js +2 -3
  54. package/dist/auth/plugins/wrappers/organization.js +2 -3
  55. package/dist/auth/plugins/wrappers/passkey.js +2 -3
  56. package/dist/auth/plugins/wrappers/phone-number.js +2 -3
  57. package/dist/auth/plugins/wrappers/sso.js +2 -3
  58. package/dist/auth/plugins/wrappers/two-factor.js +2 -3
  59. package/dist/auth/plugins/wrappers/username.js +2 -3
  60. package/dist/bin/build-config.js +2 -2
  61. package/dist/bin/cli.js +151 -258
  62. package/dist/bin/fixture.d.ts.map +1 -1
  63. package/dist/bin/fixture.js +55 -97
  64. package/dist/bin/hmr-hook-register.js +3 -3
  65. package/dist/bin/migrate-targets.d.ts +3 -0
  66. package/dist/bin/migrate-targets.d.ts.map +1 -0
  67. package/dist/bin/migrate-targets.js +11 -0
  68. package/dist/bin/test-command.js +25 -55
  69. package/dist/bin/ts-loader-register.js +5 -6
  70. package/dist/bin/ts-loader-registration.js +6 -13
  71. package/dist/cache/cache-manager.js +3 -4
  72. package/dist/cache/decorator.js +11 -21
  73. package/dist/cache/drivers.js +2 -3
  74. package/dist/cache/index.js +2 -3
  75. package/dist/cache/types.js +1 -1
  76. package/dist/cache-control/cache-control.js +21 -34
  77. package/dist/cache-control/types.js +1 -1
  78. package/dist/compress/compress.js +10 -10
  79. package/dist/compress/index.js +1 -2
  80. package/dist/compress/types.js +1 -1
  81. package/dist/cone/cone-generator.js +25 -63
  82. package/dist/database/_batch_update.js +26 -46
  83. package/dist/database/base-model.js +44 -97
  84. package/dist/database/base-model.types.js +1 -1
  85. package/dist/database/db.d.ts +8 -14
  86. package/dist/database/db.d.ts.map +1 -1
  87. package/dist/database/db.js +127 -72
  88. package/dist/database/knex.js +5 -8
  89. package/dist/database/puri-subset.types.js +1 -1
  90. package/dist/database/puri-wrapper.js +11 -15
  91. package/dist/database/puri.js +117 -234
  92. package/dist/database/puri.types.js +3 -4
  93. package/dist/database/transaction-context.js +4 -5
  94. package/dist/database/upsert-builder.js +109 -176
  95. package/dist/dict/en.d.ts +1 -0
  96. package/dist/dict/en.d.ts.map +1 -1
  97. package/dist/dict/en.js +4 -4
  98. package/dist/dict/index.js +2 -3
  99. package/dist/dict/ko.d.ts +1 -0
  100. package/dist/dict/ko.d.ts.map +1 -1
  101. package/dist/dict/ko.js +4 -4
  102. package/dist/dict/rc-keys.js +3 -4
  103. package/dist/dict/sd.js +8 -19
  104. package/dist/dict/sonamu-dictionary.js +141 -284
  105. package/dist/dict/types.js +1 -1
  106. package/dist/dict/utils.js +4 -5
  107. package/dist/entity/entity-manager.d.ts +2 -2
  108. package/dist/entity/entity-manager.js +34 -82
  109. package/dist/entity/entity-template-cone.js +33 -66
  110. package/dist/entity/entity.js +156 -310
  111. package/dist/env.d.ts +14 -0
  112. package/dist/env.d.ts.map +1 -0
  113. package/dist/env.js +75 -0
  114. package/dist/exceptions/error-handler.js +2 -3
  115. package/dist/exceptions/so-exceptions.js +7 -5
  116. package/dist/filter/index.js +1 -2
  117. package/dist/filter/types.js +3 -4
  118. package/dist/filter/utils.js +21 -54
  119. package/dist/index.js +8 -7
  120. package/dist/logger/category.js +6 -12
  121. package/dist/logger/configure.js +23 -34
  122. package/dist/migration/code-generation.js +146 -314
  123. package/dist/migration/index-where-predicate.js +52 -144
  124. package/dist/migration/migration-set.js +19 -33
  125. package/dist/migration/migrator.d.ts +2 -0
  126. package/dist/migration/migrator.d.ts.map +1 -1
  127. package/dist/migration/migrator.js +69 -53
  128. package/dist/migration/postgresql-schema-reader.js +126 -225
  129. package/dist/migration/slack-confirm.d.ts +1 -0
  130. package/dist/migration/slack-confirm.d.ts.map +1 -1
  131. package/dist/migration/slack-confirm.js +28 -38
  132. package/dist/migration/types.js +1 -1
  133. package/dist/naite/messaging-types.js +1 -1
  134. package/dist/naite/naite-reporter.js +15 -32
  135. package/dist/naite/naite.js +43 -76
  136. package/dist/ssr/index.js +6 -9
  137. package/dist/ssr/registry.js +10 -18
  138. package/dist/ssr/renderer.js +10 -21
  139. package/dist/ssr/types.js +1 -1
  140. package/dist/storage/base-file.js +5 -10
  141. package/dist/storage/buffered-file.js +3 -4
  142. package/dist/storage/drivers.js +2 -3
  143. package/dist/storage/index.js +2 -3
  144. package/dist/storage/s3-driver.js +5 -9
  145. package/dist/storage/storage-manager.js +5 -5
  146. package/dist/storage/types.js +1 -1
  147. package/dist/storage/uploaded-file.js +4 -6
  148. package/dist/stream/index.js +1 -2
  149. package/dist/stream/sse.js +8 -13
  150. package/dist/stream/ws-audience-resolver.js +5 -5
  151. package/dist/stream/ws-audience.js +3 -4
  152. package/dist/stream/ws-cluster-bus.js +3 -4
  153. package/dist/stream/ws-core.js +1 -1
  154. package/dist/stream/ws-delivery.js +11 -25
  155. package/dist/stream/ws-local-connection-store.js +9 -18
  156. package/dist/stream/ws-presence-store.js +43 -97
  157. package/dist/stream/ws-registry.js +17 -22
  158. package/dist/stream/ws-telemetry-memory.js +38 -45
  159. package/dist/stream/ws-telemetry-trace.js +4 -6
  160. package/dist/stream/ws-telemetry.js +82 -135
  161. package/dist/stream/ws.js +47 -91
  162. package/dist/syncer/api-parser.js +81 -147
  163. package/dist/syncer/checksum.js +9 -20
  164. package/dist/syncer/code-generator.js +29 -47
  165. package/dist/syncer/entity-operations.js +17 -27
  166. package/dist/syncer/event-batcher.js +8 -15
  167. package/dist/syncer/file-patterns.js +3 -4
  168. package/dist/syncer/file-tracking.js +6 -10
  169. package/dist/syncer/index.js +1 -2
  170. package/dist/syncer/module-loader.js +10 -26
  171. package/dist/syncer/syncer-actions.js +19 -37
  172. package/dist/syncer/syncer.js +46 -98
  173. package/dist/syncer/watcher.js +12 -26
  174. package/dist/tasks/decorator.js +7 -11
  175. package/dist/tasks/step-wrapper.js +7 -8
  176. package/dist/tasks/workflow-manager.js +18 -25
  177. package/dist/template/entity-converter.js +40 -64
  178. package/dist/template/helpers.js +32 -63
  179. package/dist/template/implementations/entity.template.js +7 -11
  180. package/dist/template/implementations/entry-server.template.js +2 -3
  181. package/dist/template/implementations/generated.template.js +25 -51
  182. package/dist/template/implementations/generated_http.template.js +31 -58
  183. package/dist/template/implementations/generated_sso.template.js +45 -85
  184. package/dist/template/implementations/init_types.template.js +4 -7
  185. package/dist/template/implementations/model.template.js +5 -10
  186. package/dist/template/implementations/model_test.template.js +2 -3
  187. package/dist/template/implementations/queries.template.js +4 -7
  188. package/dist/template/implementations/sd.template.js +17 -35
  189. package/dist/template/implementations/services.template.js +18 -30
  190. package/dist/template/implementations/view_form.template.js +72 -125
  191. package/dist/template/implementations/view_id_all_select.template.js +2 -3
  192. package/dist/template/implementations/view_list.template.js +86 -143
  193. package/dist/template/implementations/view_search_input.template.js +2 -3
  194. package/dist/template/index.js +5 -8
  195. package/dist/template/template-manager.js +13 -26
  196. package/dist/template/template-types.js +2 -3
  197. package/dist/template/template.js +7 -11
  198. package/dist/template/zod-converter.js +173 -348
  199. package/dist/testing/_relation-graph.js +18 -37
  200. package/dist/testing/bootstrap.js +5 -8
  201. package/dist/testing/data-explorer.js +34 -78
  202. package/dist/testing/dev-test-routes.js +54 -60
  203. package/dist/testing/dev-vitest-manager.js +33 -84
  204. package/dist/testing/faker-mappings.js +3 -4
  205. package/dist/testing/fixture-generator.d.ts +2 -1
  206. package/dist/testing/fixture-generator.d.ts.map +1 -1
  207. package/dist/testing/fixture-generator.js +159 -321
  208. package/dist/testing/fixture-loader.js +2 -2
  209. package/dist/testing/fixture-manager.d.ts.map +1 -1
  210. package/dist/testing/fixture-manager.js +124 -227
  211. package/dist/testing/global-setup.d.ts.map +1 -1
  212. package/dist/testing/global-setup.js +29 -17
  213. package/dist/testing/index.js +1 -2
  214. package/dist/testing/naite-vitest-reporter.js +2 -3
  215. package/dist/testing/parallel-db-manager.js +5 -3
  216. package/dist/testing/vitest-helpers.d.ts.map +1 -1
  217. package/dist/testing/vitest-helpers.js +15 -12
  218. package/dist/types/types.d.ts +14 -14
  219. package/dist/types/types.js +27 -50
  220. package/dist/ui/ai-api.js +6 -11
  221. package/dist/ui/ai-client.js +86 -134
  222. package/dist/ui/api.js +99 -195
  223. package/dist/ui/cdd-service.js +78 -130
  224. package/dist/ui/cdd-types.js +1 -1
  225. package/dist/ui-web/assets/{index-Df8q-fhb.js → index-DFStGyd0.js} +49 -49
  226. package/dist/ui-web/assets/index-Dx4ap5i4.css +1 -0
  227. package/dist/ui-web/index.html +2 -2
  228. package/dist/utils/async-utils.js +13 -25
  229. package/dist/utils/class-name.js +3 -4
  230. package/dist/utils/console-util.js +11 -26
  231. package/dist/utils/controller.d.ts.map +1 -1
  232. package/dist/utils/controller.js +14 -12
  233. package/dist/utils/esm-utils.js +5 -8
  234. package/dist/utils/formatter.js +10 -22
  235. package/dist/utils/fs-utils.js +14 -25
  236. package/dist/utils/lodash-able.js +3 -4
  237. package/dist/utils/model.js +7 -14
  238. package/dist/utils/object-utils.js +41 -73
  239. package/dist/utils/path-utils.js +5 -9
  240. package/dist/utils/process-utils.js +4 -7
  241. package/dist/utils/sql-parser.js +6 -13
  242. package/dist/utils/type-utils.js +16 -26
  243. package/dist/utils/utils.js +18 -40
  244. package/dist/utils/zod-error.js +9 -16
  245. package/dist/vector/chunking.js +24 -37
  246. package/dist/vector/config.js +2 -2
  247. package/dist/vector/embedding.js +8 -19
  248. package/dist/vector/index.js +1 -2
  249. package/dist/vector/types.js +1 -1
  250. package/package.json +7 -7
  251. package/src/__tests__/env.test.ts +127 -0
  252. package/src/api/__tests__/config.test.ts +10 -1
  253. package/src/api/config.ts +4 -12
  254. package/src/api/sonamu.ts +14 -4
  255. package/src/bin/__tests__/migrate-targets.test.ts +28 -0
  256. package/src/bin/__tests__/test-command.test.ts +82 -1
  257. package/src/bin/cli.ts +9 -18
  258. package/src/bin/fixture.ts +5 -4
  259. package/src/bin/migrate-targets.ts +7 -0
  260. package/src/bin/test-command.ts +2 -2
  261. package/src/database/__tests__/db.test.ts +175 -0
  262. package/src/database/db.ts +193 -71
  263. package/src/dict/en.ts +2 -0
  264. package/src/dict/ko.ts +2 -0
  265. package/src/env.ts +123 -0
  266. package/src/migration/__tests__/migrator.test.ts +149 -0
  267. package/src/migration/migrator.ts +74 -17
  268. package/src/migration/slack-confirm.ts +21 -0
  269. package/src/skills/sonamu/database.md +1 -1
  270. package/src/skills/sonamu/entity-basic.md +31 -0
  271. package/src/skills/sonamu/puri.md +22 -0
  272. package/src/skills/sonamu/testing-devrunner.md +1 -1
  273. package/src/skills/sonamu/upsert.md +53 -6
  274. package/src/stream/ws-telemetry-memory.ts +2 -2
  275. package/src/testing/fixture-generator.ts +2 -1
  276. package/src/testing/fixture-manager.ts +3 -4
  277. package/src/testing/global-setup.ts +42 -18
  278. package/src/testing/vitest-helpers.ts +14 -0
  279. package/src/utils/controller.ts +14 -7
  280. package/tsdown.api.config.ts +6 -0
  281. package/dist/_virtual/rolldown_runtime.js +0 -39
  282. package/dist/ui-web/assets/index-D4rYm-Xz.css +0 -1
@@ -1,15 +1,14 @@
1
- import { __esmMin } from "../_virtual/rolldown_runtime.js";
1
+ import { __esmMin } from "../_virtual/_rolldown/runtime.js";
2
2
  import { SD, init_sd } from "./sd.js";
3
3
  import { BadRequestException, init_so_exceptions } from "../exceptions/so-exceptions.js";
4
4
  import { formatCode, init_formatter } from "../utils/formatter.js";
5
5
  import { Sonamu, init_sonamu } from "../api/sonamu.js";
6
6
  import { EntityManager, init_entity_manager } from "../entity/entity-manager.js";
7
+ import fs from "fs";
7
8
  import path from "path";
8
9
  import { execSync } from "child_process";
9
- import fs from "fs";
10
10
  import { Workbook } from "@sheetkit/node";
11
11
  import ts from "typescript";
12
-
13
12
  //#region src/dict/sonamu-dictionary.ts
14
13
  /**
15
14
  * 0-based 컬럼 인덱스를 엑셀 컬럼 문자로 변환 (0 -> "A", 25 -> "Z", 26 -> "AA")
@@ -47,9 +46,7 @@ var init_sonamu_dictionary = __esmMin((() => {
47
46
  ts.forEachChild(sourceFile, (node) => {
48
47
  if (ts.isExportAssignment(node)) {
49
48
  const objectLiteral = this.unwrapToObjectLiteral(node.expression);
50
- if (objectLiteral) {
51
- this.extractEntriesFromObject(objectLiteral, sourceFile, entries);
52
- }
49
+ if (objectLiteral) this.extractEntriesFromObject(objectLiteral, sourceFile, entries);
53
50
  }
54
51
  });
55
52
  return entries;
@@ -64,13 +61,9 @@ var init_sonamu_dictionary = __esmMin((() => {
64
61
  const entries = [];
65
62
  ts.forEachChild(sourceFile, (node) => {
66
63
  if (ts.isVariableStatement(node)) {
67
- for (const decl of node.declarationList.declarations) {
68
- if (ts.isIdentifier(decl.name) && decl.name.text === varName && decl.initializer) {
69
- const objectLiteral = this.unwrapToObjectLiteral(decl.initializer);
70
- if (objectLiteral) {
71
- this.extractEntriesFromObject(objectLiteral, sourceFile, entries);
72
- }
73
- }
64
+ for (const decl of node.declarationList.declarations) if (ts.isIdentifier(decl.name) && decl.name.text === varName && decl.initializer) {
65
+ const objectLiteral = this.unwrapToObjectLiteral(decl.initializer);
66
+ if (objectLiteral) this.extractEntriesFromObject(objectLiteral, sourceFile, entries);
74
67
  }
75
68
  }
76
69
  });
@@ -80,11 +73,8 @@ var init_sonamu_dictionary = __esmMin((() => {
80
73
  * 문자열이 화살표 함수 또는 함수 표현식인지 판별
81
74
  */
82
75
  isExpressionFunction(code) {
83
- if (!code.trim()) {
84
- return false;
85
- }
86
- const ARROW_FUNCTION_PATTERN = /^\s*\([^)]*\)\s*=>/;
87
- return ARROW_FUNCTION_PATTERN.test(code);
76
+ if (!code.trim()) return false;
77
+ return /^\s*\([^)]*\)\s*=>/.test(code);
88
78
  }
89
79
  /**
90
80
  * export default 표현식에서 ObjectLiteralExpression 추출
@@ -92,17 +82,11 @@ var init_sonamu_dictionary = __esmMin((() => {
92
82
  * - defineLocale({ ... }) 호출 처리
93
83
  */
94
84
  unwrapToObjectLiteral(expr) {
95
- if (ts.isAsExpression(expr)) {
96
- return this.unwrapToObjectLiteral(expr.expression);
97
- }
98
- if (ts.isObjectLiteralExpression(expr)) {
99
- return expr;
100
- }
85
+ if (ts.isAsExpression(expr)) return this.unwrapToObjectLiteral(expr.expression);
86
+ if (ts.isObjectLiteralExpression(expr)) return expr;
101
87
  if (ts.isCallExpression(expr)) {
102
88
  const firstArg = expr.arguments[0];
103
- if (firstArg && ts.isObjectLiteralExpression(firstArg)) {
104
- return firstArg;
105
- }
89
+ if (firstArg && ts.isObjectLiteralExpression(firstArg)) return firstArg;
106
90
  }
107
91
  return null;
108
92
  }
@@ -112,9 +96,7 @@ var init_sonamu_dictionary = __esmMin((() => {
112
96
  extractEntriesFromObject(objectLiteral, sourceFile, entries) {
113
97
  for (const prop of objectLiteral.properties) {
114
98
  const entry = this.extractDictEntry(prop, sourceFile);
115
- if (entry) {
116
- entries.push(entry);
117
- }
99
+ if (entry) entries.push(entry);
118
100
  }
119
101
  }
120
102
  /**
@@ -123,12 +105,8 @@ var init_sonamu_dictionary = __esmMin((() => {
123
105
  * - 식별자: key (unquoted)
124
106
  */
125
107
  getPropertyKey(name) {
126
- if (ts.isStringLiteral(name)) {
127
- return name.text;
128
- }
129
- if (ts.isIdentifier(name)) {
130
- return name.text;
131
- }
108
+ if (ts.isStringLiteral(name)) return name.text;
109
+ if (ts.isIdentifier(name)) return name.text;
132
110
  return null;
133
111
  }
134
112
  /**
@@ -137,35 +115,25 @@ var init_sonamu_dictionary = __esmMin((() => {
137
115
  * - 함수: 원본 소스 (여러 줄은 한 줄로 정규화)
138
116
  */
139
117
  extractDictEntry(prop, sourceFile) {
140
- if (!ts.isPropertyAssignment(prop)) {
141
- return null;
142
- }
118
+ if (!ts.isPropertyAssignment(prop)) return null;
143
119
  const key = this.getPropertyKey(prop.name);
144
120
  if (!key) return null;
145
121
  const init = prop.initializer;
146
- if (ts.isArrowFunction(init)) {
147
- const funcText = init.getText(sourceFile);
148
- const normalized = funcText.replace(/\s*\n\s*/g, " ").trim();
149
- return {
150
- key,
151
- value: normalized,
152
- isFunction: true
153
- };
154
- }
155
- if (ts.isStringLiteral(init)) {
156
- return {
157
- key,
158
- value: init.text,
159
- isFunction: false
160
- };
161
- }
162
- if (ts.isNoSubstitutionTemplateLiteral(init)) {
163
- return {
164
- key,
165
- value: init.text,
166
- isFunction: false
167
- };
168
- }
122
+ if (ts.isArrowFunction(init)) return {
123
+ key,
124
+ value: init.getText(sourceFile).replace(/\s*\n\s*/g, " ").trim(),
125
+ isFunction: true
126
+ };
127
+ if (ts.isStringLiteral(init)) return {
128
+ key,
129
+ value: init.text,
130
+ isFunction: false
131
+ };
132
+ if (ts.isNoSubstitutionTemplateLiteral(init)) return {
133
+ key,
134
+ value: init.text,
135
+ isFunction: false
136
+ };
169
137
  return {
170
138
  key,
171
139
  value: init.getText(sourceFile),
@@ -199,25 +167,17 @@ var init_sonamu_dictionary = __esmMin((() => {
199
167
  async ensureDictKeys(requiredKeys, target = "api") {
200
168
  const { defaultLocale } = Sonamu.config.i18n;
201
169
  const projectDictPath = this.getProjectDictPath(defaultLocale, target);
202
- if (!fs.existsSync(projectDictPath)) {
203
- return [];
204
- }
170
+ if (!fs.existsSync(projectDictPath)) return [];
205
171
  const projectEntries = this.parseDictFile(projectDictPath);
206
172
  const existingKeys = new Set(projectEntries.map((e) => e.key));
207
173
  const missingKeys = requiredKeys.filter((key) => !existingKeys.has(key));
208
- if (missingKeys.length === 0) {
209
- return [];
210
- }
174
+ if (missingKeys.length === 0) return [];
211
175
  const sonamuDictPath = this.getSonamuDictPath(defaultLocale);
212
- if (!fs.existsSync(sonamuDictPath)) {
213
- return [];
214
- }
176
+ if (!fs.existsSync(sonamuDictPath)) return [];
215
177
  const sonamuEntries = this.parseDictFile(sonamuDictPath);
216
178
  const sonamuDict = new Map(sonamuEntries.map((e) => [e.key, e]));
217
- const entriesToAdd = missingKeys.map((key) => sonamuDict.get(key)).filter((entry) => entry !== undefined);
218
- if (entriesToAdd.length === 0) {
219
- return [];
220
- }
179
+ const entriesToAdd = missingKeys.map((key) => sonamuDict.get(key)).filter((entry) => entry !== void 0);
180
+ if (entriesToAdd.length === 0) return [];
221
181
  await this.appendEntriesToDictFile(projectDictPath, entriesToAdd, defaultLocale, true);
222
182
  return entriesToAdd.map((e) => e.key);
223
183
  }
@@ -227,11 +187,8 @@ var init_sonamu_dictionary = __esmMin((() => {
227
187
  */
228
188
  async appendEntriesToDictFile(filePath, entries, locale, isDefaultLocale) {
229
189
  const existingEntries = this.parseDictFile(filePath);
230
- for (const entry of entries) {
231
- existingEntries.push(entry);
232
- }
233
- const content = this.generateProjectDict(locale, existingEntries, isDefaultLocale);
234
- const formatted = await formatCode(content, filePath);
190
+ for (const entry of entries) existingEntries.push(entry);
191
+ const formatted = await formatCode(this.generateProjectDict(locale, existingEntries, isDefaultLocale), filePath);
235
192
  fs.writeFileSync(filePath, formatted, "utf-8");
236
193
  }
237
194
  /**
@@ -242,15 +199,12 @@ var init_sonamu_dictionary = __esmMin((() => {
242
199
  const helpers = [];
243
200
  for (const helper of ["plural", "josa"]) {
244
201
  const pattern = new RegExp(`\\b${helper}\\s*\\(`);
245
- if (functionEntries.some((e) => pattern.test(e.value))) {
246
- helpers.push(helper);
247
- }
202
+ if (functionEntries.some((e) => pattern.test(e.value))) helpers.push(helper);
248
203
  }
249
204
  const formatPattern = /\bformat\.\w+\s*\(/;
250
- const usesFormat = functionEntries.some((e) => formatPattern.test(e.value));
251
205
  return {
252
206
  helpers,
253
- usesFormat
207
+ usesFormat: functionEntries.some((e) => formatPattern.test(e.value))
254
208
  };
255
209
  }
256
210
  /**
@@ -261,18 +215,10 @@ var init_sonamu_dictionary = __esmMin((() => {
261
215
  const lines = [];
262
216
  const { helpers, usesFormat } = this.detectUsedHelpers(entries);
263
217
  const imports = [...helpers];
264
- if (usesFormat) {
265
- imports.push("createFormat");
266
- }
267
- if (imports.length > 0) {
268
- lines.push(`import { ${imports.join(", ")} } from "sonamu/dict";`);
269
- }
270
- if (!isDefaultLocale) {
271
- lines.push("import { defineLocale } from \"./sd.generated\";");
272
- }
273
- if (imports.length > 0 || !isDefaultLocale) {
274
- lines.push("");
275
- }
218
+ if (usesFormat) imports.push("createFormat");
219
+ if (imports.length > 0) lines.push(`import { ${imports.join(", ")} } from "sonamu/dict";`);
220
+ if (!isDefaultLocale) lines.push("import { defineLocale } from \"./sd.generated\";");
221
+ if (imports.length > 0 || !isDefaultLocale) lines.push("");
276
222
  if (usesFormat) {
277
223
  lines.push(`const format = createFormat("${locale}");`);
278
224
  lines.push("");
@@ -280,23 +226,12 @@ var init_sonamu_dictionary = __esmMin((() => {
280
226
  lines.push("/**");
281
227
  lines.push(` * Project ${locale.toUpperCase()} Dictionary`);
282
228
  lines.push(" */");
283
- if (isDefaultLocale) {
284
- lines.push("export default {");
285
- } else {
286
- lines.push("export default defineLocale({");
287
- }
288
- for (const entry of sorted) {
289
- if (entry.isFunction) {
290
- lines.push(` "${entry.key}": ${entry.value},`);
291
- } else {
292
- lines.push(` "${entry.key}": ${JSON.stringify(entry.value)},`);
293
- }
294
- }
295
- if (isDefaultLocale) {
296
- lines.push("} as const;");
297
- } else {
298
- lines.push("});");
299
- }
229
+ if (isDefaultLocale) lines.push("export default {");
230
+ else lines.push("export default defineLocale({");
231
+ for (const entry of sorted) if (entry.isFunction) lines.push(` "${entry.key}": ${entry.value},`);
232
+ else lines.push(` "${entry.key}": ${JSON.stringify(entry.value)},`);
233
+ if (isDefaultLocale) lines.push("} as const;");
234
+ else lines.push("});");
300
235
  lines.push("");
301
236
  return lines.join("\n");
302
237
  }
@@ -311,9 +246,7 @@ var init_sonamu_dictionary = __esmMin((() => {
311
246
  */
312
247
  ensureI18nDir() {
313
248
  const i18nDir = path.join(Sonamu.apiRootPath, "src", "i18n");
314
- if (!fs.existsSync(i18nDir)) {
315
- fs.mkdirSync(i18nDir, { recursive: true });
316
- }
249
+ if (!fs.existsSync(i18nDir)) fs.mkdirSync(i18nDir, { recursive: true });
317
250
  return i18nDir;
318
251
  }
319
252
  /**
@@ -322,8 +255,7 @@ var init_sonamu_dictionary = __esmMin((() => {
322
255
  async saveDictFile(locale, entries, isDefaultLocale) {
323
256
  const i18nDir = this.ensureI18nDir();
324
257
  const dictPath = path.join(i18nDir, `${locale}.ts`);
325
- const content = this.generateProjectDict(locale, entries, isDefaultLocale);
326
- const formatted = await formatCode(content, dictPath);
258
+ const formatted = await formatCode(this.generateProjectDict(locale, entries, isDefaultLocale), dictPath);
327
259
  fs.writeFileSync(dictPath, formatted, "utf-8");
328
260
  }
329
261
  /**
@@ -331,28 +263,22 @@ var init_sonamu_dictionary = __esmMin((() => {
331
263
  */
332
264
  parseEntityKey(key) {
333
265
  const entityTitleMatch = key.match(/^entity\.([A-Z][a-zA-Z0-9]*)$/);
334
- if (entityTitleMatch && !key.includes(".list") && !key.includes(".create") && !key.includes(".edit")) {
335
- return {
336
- type: "entityTitle",
337
- entityId: entityTitleMatch[1]
338
- };
339
- }
266
+ if (entityTitleMatch && !key.includes(".list") && !key.includes(".create") && !key.includes(".edit")) return {
267
+ type: "entityTitle",
268
+ entityId: entityTitleMatch[1]
269
+ };
340
270
  const propDescMatch = key.match(/^entity\.([A-Z][a-zA-Z0-9]*)\.([a-z_][a-z0-9_]*)$/);
341
- if (propDescMatch) {
342
- return {
343
- type: "propDesc",
344
- entityId: propDescMatch[1],
345
- propName: propDescMatch[2]
346
- };
347
- }
271
+ if (propDescMatch) return {
272
+ type: "propDesc",
273
+ entityId: propDescMatch[1],
274
+ propName: propDescMatch[2]
275
+ };
348
276
  const enumLabelMatch = key.match(/^enum\.([A-Z][a-zA-Z0-9]*)\.(.+)$/);
349
- if (enumLabelMatch) {
350
- return {
351
- type: "enumLabel",
352
- enumId: enumLabelMatch[1],
353
- enumValue: enumLabelMatch[2]
354
- };
355
- }
277
+ if (enumLabelMatch) return {
278
+ type: "enumLabel",
279
+ enumId: enumLabelMatch[1],
280
+ enumValue: enumLabelMatch[2]
281
+ };
356
282
  return { type: "other" };
357
283
  }
358
284
  /**
@@ -362,7 +288,7 @@ var init_sonamu_dictionary = __esmMin((() => {
362
288
  async updateEntityByKey(key, value) {
363
289
  const keyInfo = this.parseEntityKey(key);
364
290
  switch (keyInfo.type) {
365
- case "entityTitle": {
291
+ case "entityTitle":
366
292
  try {
367
293
  const entity = EntityManager.get(keyInfo.entityId);
368
294
  if (entity.title !== value) {
@@ -372,8 +298,7 @@ var init_sonamu_dictionary = __esmMin((() => {
372
298
  }
373
299
  } catch {}
374
300
  return false;
375
- }
376
- case "propDesc": {
301
+ case "propDesc":
377
302
  try {
378
303
  const entity = EntityManager.get(keyInfo.entityId);
379
304
  const propIndex = entity.props.findIndex((p) => p.name === keyInfo.propName);
@@ -384,8 +309,7 @@ var init_sonamu_dictionary = __esmMin((() => {
384
309
  }
385
310
  } catch {}
386
311
  return false;
387
- }
388
- case "enumLabel": {
312
+ case "enumLabel":
389
313
  for (const entityId of EntityManager.getAllIds()) {
390
314
  const entity = EntityManager.get(entityId);
391
315
  if (entity.enumLabels[keyInfo.enumId]) {
@@ -398,7 +322,6 @@ var init_sonamu_dictionary = __esmMin((() => {
398
322
  }
399
323
  }
400
324
  return false;
401
- }
402
325
  default: return false;
403
326
  }
404
327
  }
@@ -408,9 +331,7 @@ var init_sonamu_dictionary = __esmMin((() => {
408
331
  */
409
332
  extractEntityLabels() {
410
333
  const sdPath = path.join(Sonamu.apiRootPath, "src", "i18n", "sd.generated.ts");
411
- if (!fs.existsSync(sdPath)) {
412
- return [];
413
- }
334
+ if (!fs.existsSync(sdPath)) return [];
414
335
  return this.parseConstObjectDeclaration(sdPath, "entityLabels");
415
336
  }
416
337
  /**
@@ -420,9 +341,7 @@ var init_sonamu_dictionary = __esmMin((() => {
420
341
  */
421
342
  extractRCKeys(locale) {
422
343
  const sdPath = path.join(Sonamu.apiRootPath, "src", "i18n", "sd.generated.ts");
423
- if (!fs.existsSync(sdPath)) {
424
- return [];
425
- }
344
+ if (!fs.existsSync(sdPath)) return [];
426
345
  const varName = (() => {
427
346
  if (locale === "ko") return "rcKeysKo";
428
347
  if (locale === "en") return "rcKeysEn";
@@ -435,9 +354,7 @@ var init_sonamu_dictionary = __esmMin((() => {
435
354
  */
436
355
  loadProjectDict(locale) {
437
356
  const dictPath = path.join(Sonamu.apiRootPath, "src", "i18n", `${locale}.ts`);
438
- if (!fs.existsSync(dictPath)) {
439
- return { entries: [] };
440
- }
357
+ if (!fs.existsSync(dictPath)) return { entries: [] };
441
358
  return { entries: this.parseDictFile(dictPath) };
442
359
  }
443
360
  /**
@@ -447,7 +364,7 @@ var init_sonamu_dictionary = __esmMin((() => {
447
364
  const { defaultLocale, supportedLocales } = this.getI18nConfig();
448
365
  const locales = supportedLocales;
449
366
  const rows = [];
450
- const rowMap = new Map();
367
+ const rowMap = /* @__PURE__ */ new Map();
451
368
  for (const locale of locales) {
452
369
  const rcKeys = this.extractRCKeys(locale);
453
370
  for (const rcKey of rcKeys) {
@@ -461,9 +378,7 @@ var init_sonamu_dictionary = __esmMin((() => {
461
378
  rowMap.set(rcKey.key, row);
462
379
  }
463
380
  row[locale] = rcKey.value;
464
- if (rcKey.isFunction) {
465
- row.isFunction = true;
466
- }
381
+ if (rcKey.isFunction) row.isFunction = true;
467
382
  }
468
383
  }
469
384
  const entityLabels = this.extractEntityLabels();
@@ -482,9 +397,7 @@ var init_sonamu_dictionary = __esmMin((() => {
482
397
  const existing = rowMap.get(entry.key);
483
398
  if (existing) {
484
399
  existing[locale] = entry.value;
485
- if (entry.isFunction) {
486
- existing.isFunction = true;
487
- }
400
+ if (entry.isFunction) existing.isFunction = true;
488
401
  } else {
489
402
  let row = rowMap.get(entry.key);
490
403
  if (!row) {
@@ -505,11 +418,10 @@ var init_sonamu_dictionary = __esmMin((() => {
505
418
  const total = rows.length;
506
419
  for (const locale of locales) {
507
420
  const filled = rows.filter((row) => !!row[locale]).length;
508
- const percent = total > 0 ? Math.round(filled / total * 100) : 0;
509
421
  stats[locale] = {
510
422
  total,
511
423
  filled,
512
- percent
424
+ percent: total > 0 ? Math.round(filled / total * 100) : 0
513
425
  };
514
426
  }
515
427
  return {
@@ -590,9 +502,7 @@ var init_sonamu_dictionary = __esmMin((() => {
590
502
  wb.setRowHeight(sheet, 1, 28);
591
503
  wb.setRowValues(sheet, 3, "A", headers);
592
504
  wb.setRowHeight(sheet, 3, 26);
593
- for (let col = 0; col < headers.length; col++) {
594
- wb.setCellStyle(sheet, `${colLetter(col)}3`, headerStyleId);
595
- }
505
+ for (let col = 0; col < headers.length; col++) wb.setCellStyle(sheet, `${colLetter(col)}3`, headerStyleId);
596
506
  for (let i = 0; i < rows.length; i++) {
597
507
  const row = rows[i];
598
508
  const values = [
@@ -603,29 +513,22 @@ var init_sonamu_dictionary = __esmMin((() => {
603
513
  const rowNum = i + 4;
604
514
  wb.setRowValues(sheet, rowNum, "A", values);
605
515
  wb.setRowHeight(sheet, rowNum, 24);
606
- for (let col = 0; col < values.length; col++) {
607
- wb.setCellStyle(sheet, `${colLetter(col)}${rowNum}`, dataStyleId);
608
- }
516
+ for (let col = 0; col < values.length; col++) wb.setCellStyle(sheet, `${colLetter(col)}${rowNum}`, dataStyleId);
609
517
  }
610
518
  const MAX_WIDTH = 50;
611
519
  const MIN_WIDTH = 10;
612
520
  const columnWidths = headers.map((header) => Math.max(header.length, MIN_WIDTH));
613
- for (const row of rows) {
614
- const values = [
615
- row.key,
616
- row.source,
617
- ...locales.map((locale) => row[locale] ?? "")
618
- ];
619
- values.forEach((value, idx) => {
620
- const textLength = String(value).length;
621
- columnWidths[idx] = Math.min(Math.max(columnWidths[idx], textLength), MAX_WIDTH);
622
- });
623
- }
624
- for (let col = 0; col < columnWidths.length; col++) {
625
- wb.setColWidth(sheet, colLetter(col), columnWidths[col] + 2);
626
- }
521
+ for (const row of rows) [
522
+ row.key,
523
+ row.source,
524
+ ...locales.map((locale) => row[locale] ?? "")
525
+ ].forEach((value, idx) => {
526
+ const textLength = String(value).length;
527
+ columnWidths[idx] = Math.min(Math.max(columnWidths[idx], textLength), MAX_WIDTH);
528
+ });
529
+ for (let col = 0; col < columnWidths.length; col++) wb.setColWidth(sheet, colLetter(col), columnWidths[col] + 2);
627
530
  return {
628
- filename: `${projectName}-${new Date().toISOString().split("T")[0]}.xlsx`,
531
+ filename: `${projectName}-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.xlsx`,
629
532
  buffer: wb.writeBufferSync()
630
533
  };
631
534
  }
@@ -647,36 +550,25 @@ var init_sonamu_dictionary = __esmMin((() => {
647
550
  let updatedEntities = 0;
648
551
  let updatedLocales = 0;
649
552
  const projectDictEntries = {};
650
- for (const locale of locales) {
651
- projectDictEntries[locale] = [];
652
- }
553
+ for (const locale of locales) projectDictEntries[locale] = [];
653
554
  let headerRowNum = 0;
654
555
  for (const rowData of allRows) {
655
556
  const firstCell = rowData.cells.find((c) => c.column === "A");
656
- const firstCellValue = String(firstCell?.value ?? "").trim().toLowerCase();
657
- if (firstCellValue === "key") {
557
+ if (String(firstCell?.value ?? "").trim().toLowerCase() === "key") {
658
558
  headerRowNum = rowData.row;
659
559
  break;
660
560
  }
661
561
  }
662
- if (headerRowNum === 0) {
663
- throw new BadRequestException(SD("sonamu.error.headerRowNotFound"));
664
- }
562
+ if (headerRowNum === 0) throw new BadRequestException(SD("sonamu.error.headerRowNotFound"));
665
563
  const headerRowData = allRows.find((r) => r.row === headerRowNum);
666
- const colToHeader = new Map();
667
- if (headerRowData) {
668
- for (const cell of headerRowData.cells) {
669
- colToHeader.set(cell.column, String(cell.value ?? ""));
670
- }
671
- }
564
+ const colToHeader = /* @__PURE__ */ new Map();
565
+ if (headerRowData) for (const cell of headerRowData.cells) colToHeader.set(cell.column, String(cell.value ?? ""));
672
566
  for (const rowData of allRows) {
673
567
  if (rowData.row <= headerRowNum) continue;
674
568
  const rowValues = {};
675
569
  for (const cell of rowData.cells) {
676
570
  const headerName = colToHeader.get(cell.column);
677
- if (headerName) {
678
- rowValues[headerName] = String(cell.value ?? "");
679
- }
571
+ if (headerName) rowValues[headerName] = String(cell.value ?? "");
680
572
  }
681
573
  const key = rowValues.key;
682
574
  const source = rowValues.source;
@@ -684,33 +576,24 @@ var init_sonamu_dictionary = __esmMin((() => {
684
576
  if (source === "entity") {
685
577
  const defaultValue = rowValues[defaultLocale];
686
578
  if (defaultValue) {
687
- const updated = await this.updateEntityByKey(key, defaultValue);
688
- if (updated) {
689
- updatedEntities++;
690
- }
579
+ if (await this.updateEntityByKey(key, defaultValue)) updatedEntities++;
691
580
  }
692
581
  for (const locale of locales) {
693
582
  if (locale === defaultLocale) continue;
694
583
  const cellValue = rowValues[locale]?.trim();
695
- if (cellValue) {
696
- projectDictEntries[locale].push({
697
- key,
698
- value: cellValue,
699
- isFunction: this.isExpressionFunction(cellValue)
700
- });
701
- }
702
- }
703
- } else if (source === "project") {
704
- for (const locale of locales) {
705
- const cellValue = rowValues[locale]?.trim();
706
- if (cellValue) {
707
- projectDictEntries[locale].push({
708
- key,
709
- value: cellValue,
710
- isFunction: this.isExpressionFunction(cellValue)
711
- });
712
- }
584
+ if (cellValue) projectDictEntries[locale].push({
585
+ key,
586
+ value: cellValue,
587
+ isFunction: this.isExpressionFunction(cellValue)
588
+ });
713
589
  }
590
+ } else if (source === "project") for (const locale of locales) {
591
+ const cellValue = rowValues[locale]?.trim();
592
+ if (cellValue) projectDictEntries[locale].push({
593
+ key,
594
+ value: cellValue,
595
+ isFunction: this.isExpressionFunction(cellValue)
596
+ });
714
597
  }
715
598
  }
716
599
  for (const locale of locales) {
@@ -733,9 +616,7 @@ var init_sonamu_dictionary = __esmMin((() => {
733
616
  const { oldKey, newKey, source, values } = params;
734
617
  const { defaultLocale, supportedLocales } = this.getI18nConfig();
735
618
  const locales = supportedLocales;
736
- if (source === "entity" && values[defaultLocale]) {
737
- await this.updateEntityByKey(newKey, values[defaultLocale]);
738
- }
619
+ if (source === "entity" && values[defaultLocale]) await this.updateEntityByKey(newKey, values[defaultLocale]);
739
620
  for (const locale of locales) {
740
621
  if (source === "entity" && locale === defaultLocale) continue;
741
622
  const cellValue = values[locale]?.trim();
@@ -743,9 +624,7 @@ var init_sonamu_dictionary = __esmMin((() => {
743
624
  const { entries } = this.loadProjectDict(locale);
744
625
  if (oldKey !== newKey) {
745
626
  const oldIndex = entries.findIndex((e) => e.key === oldKey);
746
- if (oldIndex !== -1) {
747
- entries.splice(oldIndex, 1);
748
- }
627
+ if (oldIndex !== -1) entries.splice(oldIndex, 1);
749
628
  }
750
629
  const existingIndex = entries.findIndex((e) => e.key === newKey);
751
630
  const newEntry = {
@@ -753,11 +632,8 @@ var init_sonamu_dictionary = __esmMin((() => {
753
632
  value: cellValue,
754
633
  isFunction: this.isExpressionFunction(cellValue)
755
634
  };
756
- if (existingIndex !== -1) {
757
- entries[existingIndex] = newEntry;
758
- } else {
759
- entries.push(newEntry);
760
- }
635
+ if (existingIndex !== -1) entries[existingIndex] = newEntry;
636
+ else entries.push(newEntry);
761
637
  await this.saveDictFile(locale, entries, locale === defaultLocale);
762
638
  }
763
639
  }
@@ -766,16 +642,12 @@ var init_sonamu_dictionary = __esmMin((() => {
766
642
  */
767
643
  async createEntry(params) {
768
644
  const { key, values } = params;
769
- if (!key?.trim()) {
770
- throw new BadRequestException(SD("sonamu.error.keyRequired"));
771
- }
645
+ if (!key?.trim()) throw new BadRequestException(SD("sonamu.error.keyRequired"));
772
646
  const { defaultLocale, supportedLocales } = this.getI18nConfig();
773
647
  const locales = supportedLocales;
774
648
  for (const locale of locales) {
775
649
  const { entries } = this.loadProjectDict(locale);
776
- if (entries.some((e) => e.key === key)) {
777
- throw new BadRequestException(SD("sonamu.error.keyAlreadyExists")(key));
778
- }
650
+ if (entries.some((e) => e.key === key)) throw new BadRequestException(SD("sonamu.error.keyAlreadyExists")(key));
779
651
  }
780
652
  for (const locale of locales) {
781
653
  const cellValue = values[locale]?.trim();
@@ -793,9 +665,7 @@ var init_sonamu_dictionary = __esmMin((() => {
793
665
  * 딕셔너리 항목 삭제
794
666
  */
795
667
  async deleteEntry(key) {
796
- if (!key) {
797
- throw new BadRequestException(SD("sonamu.error.keyRequired"));
798
- }
668
+ if (!key) throw new BadRequestException(SD("sonamu.error.keyRequired"));
799
669
  const { defaultLocale, supportedLocales } = this.getI18nConfig();
800
670
  const locales = supportedLocales;
801
671
  let deleted = false;
@@ -808,9 +678,7 @@ var init_sonamu_dictionary = __esmMin((() => {
808
678
  await this.saveDictFile(locale, entries, locale === defaultLocale);
809
679
  }
810
680
  }
811
- if (!deleted) {
812
- throw new BadRequestException(SD("sonamu.error.keyNotFound")(key));
813
- }
681
+ if (!deleted) throw new BadRequestException(SD("sonamu.error.keyNotFound")(key));
814
682
  }
815
683
  /**
816
684
  * 미사용 키 검사 (ast-grep 사용)
@@ -824,12 +692,10 @@ var init_sonamu_dictionary = __esmMin((() => {
824
692
  sgPath = execSync("which ast-grep", { encoding: "utf-8" }).trim();
825
693
  } catch {}
826
694
  }
827
- if (!sgPath) {
828
- return {
829
- error: "ast-grep이 설치되어 있지 않습니다. brew install ast-grep 또는 npm install -g @ast-grep/cli로 설치해주세요.",
830
- unusedKeys: []
831
- };
832
- }
695
+ if (!sgPath) return {
696
+ error: "ast-grep이 설치되어 있지 않습니다. brew install ast-grep 또는 npm install -g @ast-grep/cli로 설치해주세요.",
697
+ unusedKeys: []
698
+ };
833
699
  const searchPaths = [];
834
700
  for (const entry of [
835
701
  "api",
@@ -837,42 +703,33 @@ var init_sonamu_dictionary = __esmMin((() => {
837
703
  "app"
838
704
  ]) {
839
705
  const srcPath = path.join(Sonamu.appRootPath, entry, "src");
840
- if (fs.existsSync(srcPath)) {
841
- searchPaths.push(srcPath);
842
- }
843
- }
844
- if (searchPaths.length === 0) {
845
- return {
846
- error: "검색할 src 디렉토리를 찾을 수 없습니다.",
847
- unusedKeys: []
848
- };
706
+ if (fs.existsSync(srcPath)) searchPaths.push(srcPath);
849
707
  }
850
- const usedKeys = new Set();
708
+ if (searchPaths.length === 0) return {
709
+ error: "검색할 src 디렉토리를 찾을 수 없습니다.",
710
+ unusedKeys: []
711
+ };
712
+ const usedKeys = /* @__PURE__ */ new Set();
851
713
  try {
852
714
  const patterns = ["SD(\"$KEY\")", "SD('$KEY')"];
853
- for (const searchPath of searchPaths) {
854
- for (const pattern of patterns) {
855
- try {
856
- const result = execSync(`${sgPath} --pattern '${pattern}' --json ${searchPath}`, {
857
- encoding: "utf-8",
858
- maxBuffer: 50 * 1024 * 1024
859
- });
860
- if (result.trim()) {
861
- const matches = JSON.parse(result);
862
- for (const match of matches) {
863
- const keyText = match.metaVariables?.single?.KEY?.text;
864
- if (keyText) {
865
- const cleanKey = keyText.replace(/^["']|["']$/g, "");
866
- usedKeys.add(cleanKey);
867
- }
868
- }
715
+ for (const searchPath of searchPaths) for (const pattern of patterns) try {
716
+ const result = execSync(`${sgPath} --pattern '${pattern}' --json ${searchPath}`, {
717
+ encoding: "utf-8",
718
+ maxBuffer: 50 * 1024 * 1024
719
+ });
720
+ if (result.trim()) {
721
+ const matches = JSON.parse(result);
722
+ for (const match of matches) {
723
+ const keyText = match.metaVariables?.single?.KEY?.text;
724
+ if (keyText) {
725
+ const cleanKey = keyText.replace(/^["']|["']$/g, "");
726
+ usedKeys.add(cleanKey);
869
727
  }
870
- } catch {}
728
+ }
871
729
  }
872
- }
873
- const unusedKeys = keys.filter((k) => !usedKeys.has(k));
730
+ } catch {}
874
731
  return {
875
- unusedKeys,
732
+ unusedKeys: keys.filter((k) => !usedKeys.has(k)),
876
733
  usedKeysCount: usedKeys.size
877
734
  };
878
735
  } catch (e) {
@@ -885,8 +742,8 @@ var init_sonamu_dictionary = __esmMin((() => {
885
742
  };
886
743
  sonamuDictionary = new SonamuDictionary();
887
744
  }));
888
-
889
745
  //#endregion
890
746
  init_sonamu_dictionary();
891
747
  export { SonamuDictionary, init_sonamu_dictionary, sonamuDictionary };
892
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29uYW11LWRpY3Rpb25hcnkuanMiLCJuYW1lcyI6WyJlbnRyaWVzOiBEaWN0RW50cnlbXSIsImhlbHBlcnM6IHN0cmluZ1tdIiwibGluZXM6IHN0cmluZ1tdIiwicm93czogRGljdGlvbmFyeVJvd1tdIiwicm93OiBEaWN0aW9uYXJ5Um93Iiwic3RhdHM6IFJlY29yZDxzdHJpbmcsIHsgdG90YWw6IG51bWJlcjsgZmlsbGVkOiBudW1iZXI7IHBlcmNlbnQ6IG51bWJlciB9PiIsImNvbHVtbldpZHRoczogbnVtYmVyW10iLCJwcm9qZWN0RGljdEVudHJpZXM6IFJlY29yZDxzdHJpbmcsIERpY3RFbnRyeVtdPiIsImNvbFRvSGVhZGVyOiBNYXA8c3RyaW5nLCBzdHJpbmc+Iiwicm93VmFsdWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IiwibmV3RW50cnk6IERpY3RFbnRyeSIsInNnUGF0aDogc3RyaW5nIHwgbnVsbCIsInNlYXJjaFBhdGhzOiBzdHJpbmdbXSJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kaWN0L3NvbmFtdS1kaWN0aW9uYXJ5LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGV4ZWNTeW5jIH0gZnJvbSBcImNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5cbmltcG9ydCB7IFdvcmtib29rIH0gZnJvbSBcIkBzaGVldGtpdC9ub2RlXCI7XG5pbXBvcnQgdHMgZnJvbSBcInR5cGVzY3JpcHRcIjtcblxuaW1wb3J0IHsgU29uYW11IH0gZnJvbSBcIi4uL2FwaS9zb25hbXVcIjtcbmltcG9ydCB7IEVudGl0eU1hbmFnZXIgfSBmcm9tIFwiLi4vZW50aXR5L2VudGl0eS1tYW5hZ2VyXCI7XG5pbXBvcnQgeyBCYWRSZXF1ZXN0RXhjZXB0aW9uIH0gZnJvbSBcIi4uL2V4Y2VwdGlvbnMvc28tZXhjZXB0aW9uc1wiO1xuaW1wb3J0IHsgZm9ybWF0Q29kZSB9IGZyb20gXCIuLi91dGlscy9mb3JtYXR0ZXJcIjtcbmltcG9ydCB7IFNEIH0gZnJvbSBcIi4vc2RcIjtcbmltcG9ydCB7XG4gIHR5cGUgRGljdEVudHJ5LFxuICB0eXBlIERpY3Rpb25hcnlSZXN1bHQsXG4gIHR5cGUgRGljdGlvbmFyeVJvdyxcbiAgdHlwZSBFbnRpdHlLZXlJbmZvLFxuICB0eXBlIEkxOG5Db25maWcsXG4gIHR5cGUgSW1wb3J0UmVzdWx0LFxuICB0eXBlIFVzYWdlUmVzdWx0LFxufSBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIDAtYmFzZWQg7Lus65+8IOyduOuNseyKpOulvCDsl5HshYAg7Lus65+8IOusuOyekOuhnCDrs4DtmZggKDAgLT4gXCJBXCIsIDI1IC0+IFwiWlwiLCAyNiAtPiBcIkFBXCIpXG4gKi9cbmZ1bmN0aW9uIGNvbExldHRlcihpbmRleDogbnVtYmVyKTogc3RyaW5nIHtcbiAgbGV0IHJlc3VsdCA9IFwiXCI7XG4gIGxldCBuID0gaW5kZXg7XG4gIHdoaWxlIChuID49IDApIHtcbiAgICByZXN1bHQgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDY1ICsgKG4gJSAyNikpICsgcmVzdWx0O1xuICAgIG4gPSBNYXRoLmZsb29yKG4gLyAyNikgLSAxO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogU29uYW11IERpY3Rpb25hcnkg6rSA66asIO2BtOuemOyKpFxuICogaTE4biDrlJXshZTrhIjrpqzsnZggQ1JVRCDrsI8gRXhjZWwgaW1wb3J0L2V4cG9ydOulvCDri7Tri7ntlanri4jri6QuXG4gKi9cbmV4cG9ydCBjbGFzcyBTb25hbXVEaWN0aW9uYXJ5IHtcbiAgLyoqXG4gICAqIFR5cGVTY3JpcHQgQ29tcGlsZXIgQVBJ66W8IOyCrOyaqe2VmOyXrCBkaWN0IO2MjOydvCDtjIzsi7FcbiAgICpcbiAgICog7KeA7JuQIO2MqO2EtDpcbiAgICogLSBleHBvcnQgZGVmYXVsdCB7IC4uLiB9IGFzIGNvbnN0O1xuICAgKiAtIGV4cG9ydCBkZWZhdWx0IGRlZmluZUxvY2FsZSh7IC4uLiB9KTtcbiAgICogLSDrrLjsnpDsl7Qg6rCSOiBcImtleVwiOiBcInZhbHVlXCIg65iQ64qUIGtleTogYHZhbHVlYFxuICAgKiAtIO2VqOyImCDqsJI6IFwia2V5XCI6IChwYXJhbTogVHlwZSkgPT4gYHRlbXBsYXRlYFxuICAgKi9cbiAgcGFyc2VEaWN0RmlsZShmaWxlUGF0aDogc3RyaW5nKTogRGljdEVudHJ5W10ge1xuICAgIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoZmlsZVBhdGgsIFwidXRmLThcIik7XG4gICAgY29uc3Qgc291cmNlRmlsZSA9IHRzLmNyZWF0ZVNvdXJjZUZpbGUoZmlsZVBhdGgsIGNvbnRlbnQsIHRzLlNjcmlwdFRhcmdldC5MYXRlc3QsIHRydWUpO1xuXG4gICAgY29uc3QgZW50cmllczogRGljdEVudHJ5W10gPSBbXTtcblxuICAgIHRzLmZvckVhY2hDaGlsZChzb3VyY2VGaWxlLCAobm9kZSkgPT4ge1xuICAgICAgaWYgKHRzLmlzRXhwb3J0QXNzaWdubWVudChub2RlKSkge1xuICAgICAgICBjb25zdCBvYmplY3RMaXRlcmFsID0gdGhpcy51bndyYXBUb09iamVjdExpdGVyYWwobm9kZS5leHByZXNzaW9uKTtcbiAgICAgICAgaWYgKG9iamVjdExpdGVyYWwpIHtcbiAgICAgICAgICB0aGlzLmV4dHJhY3RFbnRyaWVzRnJvbU9iamVjdChvYmplY3RMaXRlcmFsLCBzb3VyY2VGaWxlLCBlbnRyaWVzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGVudHJpZXM7XG4gIH1cblxuICAvKipcbiAgICog7YyM7J287JeQ7IScIO2KueyglSDsnbTrpoTsnZggY29uc3Qg7ISg7Ja47J2EIOywvuyVhCBPYmplY3RMaXRlcmFsIO2MjOyLsVxuICAgKiDsmIg6IGNvbnN0IGVudGl0eUxhYmVscyA9IHsgLi4uIH0gYXMgY29uc3Q7XG4gICAqL1xuICBwYXJzZUNvbnN0T2JqZWN0RGVjbGFyYXRpb24oZmlsZVBhdGg6IHN0cmluZywgdmFyTmFtZTogc3RyaW5nKTogRGljdEVudHJ5W10ge1xuICAgIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoZmlsZVBhdGgsIFwidXRmLThcIik7XG4gICAgY29uc3Qgc291cmNlRmlsZSA9IHRzLmNyZWF0ZVNvdXJjZUZpbGUoZmlsZVBhdGgsIGNvbnRlbnQsIHRzLlNjcmlwdFRhcmdldC5MYXRlc3QsIHRydWUpO1xuXG4gICAgY29uc3QgZW50cmllczogRGljdEVudHJ5W10gPSBbXTtcblxuICAgIHRzLmZvckVhY2hDaGlsZChzb3VyY2VGaWxlLCAobm9kZSkgPT4ge1xuICAgICAgaWYgKHRzLmlzVmFyaWFibGVTdGF0ZW1lbnQobm9kZSkpIHtcbiAgICAgICAgZm9yIChjb25zdCBkZWNsIG9mIG5vZGUuZGVjbGFyYXRpb25MaXN0LmRlY2xhcmF0aW9ucykge1xuICAgICAgICAgIGlmICh0cy5pc0lkZW50aWZpZXIoZGVjbC5uYW1lKSAmJiBkZWNsLm5hbWUudGV4dCA9PT0gdmFyTmFtZSAmJiBkZWNsLmluaXRpYWxpemVyKSB7XG4gICAgICAgICAgICBjb25zdCBvYmplY3RMaXRlcmFsID0gdGhpcy51bndyYXBUb09iamVjdExpdGVyYWwoZGVjbC5pbml0aWFsaXplcik7XG4gICAgICAgICAgICBpZiAob2JqZWN0TGl0ZXJhbCkge1xuICAgICAgICAgICAgICB0aGlzLmV4dHJhY3RFbnRyaWVzRnJvbU9iamVjdChvYmplY3RMaXRlcmFsLCBzb3VyY2VGaWxlLCBlbnRyaWVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBlbnRyaWVzO1xuICB9XG5cbiAgLyoqXG4gICAqIOusuOyekOyXtOydtCDtmZTsgrTtkZwg7ZWo7IiYIOuYkOuKlCDtlajsiJgg7ZGc7ZiE7Iud7J247KeAIO2MkOuzhFxuICAgKi9cbiAgaXNFeHByZXNzaW9uRnVuY3Rpb24oY29kZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgLy8g67mIIOusuOyekOyXtOydtOuCmCDqs7XrsLHrp4wg7J6I64qUIOqyveyasFxuICAgIGlmICghY29kZS50cmltKCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBjb25zdCBBUlJPV19GVU5DVElPTl9QQVRURVJOID0gL15cXHMqXFwoW14pXSpcXClcXHMqPT4vO1xuXG4gICAgcmV0dXJuIEFSUk9XX0ZVTkNUSU9OX1BBVFRFUk4udGVzdChjb2RlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBleHBvcnQgZGVmYXVsdCDtkZztmITsi53sl5DshJwgT2JqZWN0TGl0ZXJhbEV4cHJlc3Npb24g7LaU7LacXG4gICAqIC0gYXMgY29uc3Qg7LKY66asXG4gICAqIC0gZGVmaW5lTG9jYWxlKHsgLi4uIH0pIO2YuOy2nCDsspjrpqxcbiAgICovXG4gIHByaXZhdGUgdW53cmFwVG9PYmplY3RMaXRlcmFsKGV4cHI6IHRzLkV4cHJlc3Npb24pOiB0cy5PYmplY3RMaXRlcmFsRXhwcmVzc2lvbiB8IG51bGwge1xuICAgIC8vIGFzIGNvbnN0IOyymOumrFxuICAgIGlmICh0cy5pc0FzRXhwcmVzc2lvbihleHByKSkge1xuICAgICAgcmV0dXJuIHRoaXMudW53cmFwVG9PYmplY3RMaXRlcmFsKGV4cHIuZXhwcmVzc2lvbik7XG4gICAgfVxuICAgIC8vIOyngeygkSDqsJ3ssrQg66as7YSw65+0XG4gICAgaWYgKHRzLmlzT2JqZWN0TGl0ZXJhbEV4cHJlc3Npb24oZXhwcikpIHtcbiAgICAgIHJldHVybiBleHByO1xuICAgIH1cbiAgICAvLyBkZWZpbmVMb2NhbGUoeyAuLi4gfSkg7Zi47LacXG4gICAgaWYgKHRzLmlzQ2FsbEV4cHJlc3Npb24oZXhwcikpIHtcbiAgICAgIGNvbnN0IGZpcnN0QXJnID0gZXhwci5hcmd1bWVudHNbMF07XG4gICAgICBpZiAoZmlyc3RBcmcgJiYgdHMuaXNPYmplY3RMaXRlcmFsRXhwcmVzc2lvbihmaXJzdEFyZykpIHtcbiAgICAgICAgcmV0dXJuIGZpcnN0QXJnO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBPYmplY3RMaXRlcmFsRXhwcmVzc2lvbuyXkOyEnCBEaWN0RW50cnkg7LaU7LacXG4gICAqL1xuICBwcml2YXRlIGV4dHJhY3RFbnRyaWVzRnJvbU9iamVjdChcbiAgICBvYmplY3RMaXRlcmFsOiB0cy5PYmplY3RMaXRlcmFsRXhwcmVzc2lvbixcbiAgICBzb3VyY2VGaWxlOiB0cy5Tb3VyY2VGaWxlLFxuICAgIGVudHJpZXM6IERpY3RFbnRyeVtdLFxuICApOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IHByb3Agb2Ygb2JqZWN0TGl0ZXJhbC5wcm9wZXJ0aWVzKSB7XG4gICAgICBjb25zdCBlbnRyeSA9IHRoaXMuZXh0cmFjdERpY3RFbnRyeShwcm9wLCBzb3VyY2VGaWxlKTtcbiAgICAgIGlmIChlbnRyeSkge1xuICAgICAgICBlbnRyaWVzLnB1c2goZW50cnkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9wZXJ0eU5hbWXsl5DshJwg7YKkIOusuOyekOyXtCDstpTstpxcbiAgICogLSDrrLjsnpDsl7Qg66as7YSw65+0OiBcImtleVwiXG4gICAqIC0g7Iud67OE7J6QOiBrZXkgKHVucXVvdGVkKVxuICAgKi9cbiAgcHJpdmF0ZSBnZXRQcm9wZXJ0eUtleShuYW1lOiB0cy5Qcm9wZXJ0eU5hbWUpOiBzdHJpbmcgfCBudWxsIHtcbiAgICBpZiAodHMuaXNTdHJpbmdMaXRlcmFsKG5hbWUpKSB7XG4gICAgICByZXR1cm4gbmFtZS50ZXh0O1xuICAgIH1cbiAgICBpZiAodHMuaXNJZGVudGlmaWVyKG5hbWUpKSB7XG4gICAgICByZXR1cm4gbmFtZS50ZXh0O1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiDtlITroZztjbzti7Dsl5DshJwgRGljdEVudHJ5IOy2lOy2nFxuICAgKiAtIOusuOyekOyXtDog7Iuk7KCcIOusuOyekOyXtCDqsJJcbiAgICogLSDtlajsiJg6IOybkOuzuCDshozsiqQgKOyXrOufrCDspITsnYAg7ZWcIOykhOuhnCDsoJXqt5ztmZQpXG4gICAqL1xuICBwcml2YXRlIGV4dHJhY3REaWN0RW50cnkoXG4gICAgcHJvcDogdHMuT2JqZWN0TGl0ZXJhbEVsZW1lbnRMaWtlLFxuICAgIHNvdXJjZUZpbGU6IHRzLlNvdXJjZUZpbGUsXG4gICk6IERpY3RFbnRyeSB8IG51bGwge1xuICAgIGlmICghdHMuaXNQcm9wZXJ0eUFzc2lnbm1lbnQocHJvcCkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IGtleSA9IHRoaXMuZ2V0UHJvcGVydHlLZXkocHJvcC5uYW1lKTtcbiAgICBpZiAoIWtleSkgcmV0dXJuIG51bGw7XG5cbiAgICBjb25zdCBpbml0ID0gcHJvcC5pbml0aWFsaXplcjtcblxuICAgIC8vIO2ZlOyCtO2RnCDtlajsiJhcbiAgICBpZiAodHMuaXNBcnJvd0Z1bmN0aW9uKGluaXQpKSB7XG4gICAgICBjb25zdCBmdW5jVGV4dCA9IGluaXQuZ2V0VGV4dChzb3VyY2VGaWxlKTtcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBmdW5jVGV4dC5yZXBsYWNlKC9cXHMqXFxuXFxzKi9nLCBcIiBcIikudHJpbSgpO1xuICAgICAgcmV0dXJuIHsga2V5LCB2YWx1ZTogbm9ybWFsaXplZCwgaXNGdW5jdGlvbjogdHJ1ZSB9O1xuICAgIH1cblxuICAgIC8vIOusuOyekOyXtCDrpqzthLDrn7RcbiAgICBpZiAodHMuaXNTdHJpbmdMaXRlcmFsKGluaXQpKSB7XG4gICAgICByZXR1cm4geyBrZXksIHZhbHVlOiBpbml0LnRleHQsIGlzRnVuY3Rpb246IGZhbHNlIH07XG4gICAgfVxuXG4gICAgLy8g7YWc7ZSM66a/IOumrO2EsOuftCAo67OA7IiYIOyXhuydjClcbiAgICBpZiAodHMuaXNOb1N1YnN0aXR1dGlvblRlbXBsYXRlTGl0ZXJhbChpbml0KSkge1xuICAgICAgcmV0dXJuIHsga2V5LCB2YWx1ZTogaW5pdC50ZXh0LCBpc0Z1bmN0aW9uOiBmYWxzZSB9O1xuICAgIH1cblxuICAgIC8vIOq4sO2DgCAo7JiIOiDtlajsiJgg7ZGc7ZiE7IudKVxuICAgIHJldHVybiB7XG4gICAgICBrZXksXG4gICAgICB2YWx1ZTogaW5pdC5nZXRUZXh0KHNvdXJjZUZpbGUpLFxuICAgICAgaXNGdW5jdGlvbjogdHMuaXNGdW5jdGlvbkV4cHJlc3Npb24oaW5pdCksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDtlITroZzsoJ3tirjsnZggaTE4biBkaWN0IO2MjOydvCDqsr3roZzrpbwg67CY7ZmY7ZWp64uI64ukLlxuICAgKiBAcGFyYW0gbG9jYWxlIC0g66Gc7LyA7J28IChrbywgZW4g65OxKVxuICAgKiBAcGFyYW0gdGFyZ2V0IC0g7YOA6rKfIOuUlOugie2GoOumrCAoYXBpLCB3ZWIsIGFwcClcbiAgICovXG4gIGdldFByb2plY3REaWN0UGF0aChsb2NhbGU6IHN0cmluZywgdGFyZ2V0OiBcImFwaVwiIHwgXCJ3ZWJcIiB8IFwiYXBwXCIgPSBcImFwaVwiKTogc3RyaW5nIHtcbiAgICBjb25zdCBkaXIgPSB0YXJnZXQgPT09IFwiYXBpXCIgPyBTb25hbXUuY29uZmlnLmFwaS5kaXIgOiB0YXJnZXQ7XG4gICAgcmV0dXJuIHBhdGguam9pbihTb25hbXUuYXBwUm9vdFBhdGgsIGRpciwgXCJzcmNcIiwgXCJpMThuXCIsIGAke2xvY2FsZX0udHNgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBzb25hbXUg64K07J6lIGRpY3Qg7YyM7J28IOqyveuhnOulvCDrsJjtmZjtlanri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGdldFNvbmFtdURpY3RQYXRoKGxvY2FsZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBwYWNrYWdlUm9vdCA9IHBhdGgucmVzb2x2ZShpbXBvcnQubWV0YS5kaXJuYW1lLCBcIi4uXCIsIFwiLi5cIik7XG4gICAgcmV0dXJuIHBhdGguam9pbihwYWNrYWdlUm9vdCwgXCJzcmNcIiwgXCJkaWN0XCIsIGAke2xvY2FsZX0udHNgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDtlYTsmpTtlZwgZGljdCDtgqTqsIAg7ZSE66Gc7KCd7Yq47JeQIOyhtOyerO2VmOuKlOyngCDtmZXsnbjtlZjqs6AsIOyXhuycvOuptCDstpTqsIDtlanri4jri6QuXG4gICAqIGRlZmF1bHRMb2NhbGXsl5Drp4wg7LaU6rCA7ZWY66mwLCDri6TrpbggbG9jYWxl7J2AIOyCrOyaqeyekOqwgCDsp4HsoJEg67KI7Jet7ZW07JW8IO2VqeuLiOuLpC5cbiAgICpcbiAgICogQHBhcmFtIHJlcXVpcmVkS2V5cyAtIO2VhOyalO2VnCDtgqQg66qp66GdXG4gICAqIEBwYXJhbSB0YXJnZXQgLSDtg4Dqsp8g65SU66CJ7Yag66asIChhcGksIHdlYiwgYXBwKVxuICAgKiBAcmV0dXJucyDstpTqsIDrkJwg7YKkIOuqqeuhnVxuICAgKi9cbiAgYXN5bmMgZW5zdXJlRGljdEtleXMoXG4gICAgcmVxdWlyZWRLZXlzOiBzdHJpbmdbXSxcbiAgICB0YXJnZXQ6IFwiYXBpXCIgfCBcIndlYlwiIHwgXCJhcHBcIiA9IFwiYXBpXCIsXG4gICk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICBjb25zdCB7IGRlZmF1bHRMb2NhbGUgfSA9IFNvbmFtdS5jb25maWcuaTE4bjtcbiAgICBjb25zdCBwcm9qZWN0RGljdFBhdGggPSB0aGlzLmdldFByb2plY3REaWN0UGF0aChkZWZhdWx0TG9jYWxlLCB0YXJnZXQpO1xuXG4gICAgLy8g7ZSE66Gc7KCd7Yq4IGRpY3Qg7YyM7J287J20IOyXhuycvOuptCDslYTrrLTqsoPrj4Qg7ZWY7KeAIOyViuydjFxuICAgIGlmICghZnMuZXhpc3RzU3luYyhwcm9qZWN0RGljdFBhdGgpKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgLy8g7ZSE66Gc7KCd7Yq4IGRpY3Tsl5DshJwg6riw7KG0IO2CpCDtjIzsi7FcbiAgICBjb25zdCBwcm9qZWN0RW50cmllcyA9IHRoaXMucGFyc2VEaWN0RmlsZShwcm9qZWN0RGljdFBhdGgpO1xuICAgIGNvbnN0IGV4aXN0aW5nS2V5cyA9IG5ldyBTZXQocHJvamVjdEVudHJpZXMubWFwKChlKSA9PiBlLmtleSkpO1xuXG4gICAgLy8g64iE652965CcIO2CpCDssL7quLBcbiAgICBjb25zdCBtaXNzaW5nS2V5cyA9IHJlcXVpcmVkS2V5cy5maWx0ZXIoKGtleSkgPT4gIWV4aXN0aW5nS2V5cy5oYXMoa2V5KSk7XG5cbiAgICBpZiAobWlzc2luZ0tleXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgLy8gc29uYW11IGRpY3Tsl5DshJwg6riw67O46rCSIOqwgOyguOyYpOq4sFxuICAgIGNvbnN0IHNvbmFtdURpY3RQYXRoID0gdGhpcy5nZXRTb25hbXVEaWN0UGF0aChkZWZhdWx0TG9jYWxlKTtcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoc29uYW11RGljdFBhdGgpKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgY29uc3Qgc29uYW11RW50cmllcyA9IHRoaXMucGFyc2VEaWN0RmlsZShzb25hbXVEaWN0UGF0aCk7XG4gICAgY29uc3Qgc29uYW11RGljdCA9IG5ldyBNYXAoc29uYW11RW50cmllcy5tYXAoKGUpID0+IFtlLmtleSwgZV0pKTtcblxuICAgIC8vIOy2lOqwgO2VoCDsl5Ttirjrpqwg7IOd7ISxXG4gICAgY29uc3QgZW50cmllc1RvQWRkID0gbWlzc2luZ0tleXNcbiAgICAgIC5tYXAoKGtleSkgPT4gc29uYW11RGljdC5nZXQoa2V5KSlcbiAgICAgIC5maWx0ZXIoKGVudHJ5KTogZW50cnkgaXMgTm9uTnVsbGFibGU8dHlwZW9mIGVudHJ5PiA9PiBlbnRyeSAhPT0gdW5kZWZpbmVkKTtcblxuICAgIGlmIChlbnRyaWVzVG9BZGQubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgLy8g7ZSE66Gc7KCd7Yq4IGRpY3Qg7YyM7J287JeQIOy2lOqwgFxuICAgIGF3YWl0IHRoaXMuYXBwZW5kRW50cmllc1RvRGljdEZpbGUocHJvamVjdERpY3RQYXRoLCBlbnRyaWVzVG9BZGQsIGRlZmF1bHRMb2NhbGUsIHRydWUpO1xuXG4gICAgcmV0dXJuIGVudHJpZXNUb0FkZC5tYXAoKGUpID0+IGUua2V5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBkaWN0IO2MjOydvOyXkCDsl5Ttirjrpqzrpbwg7LaU6rCA7ZWp64uI64ukLlxuICAgKiDquLDsobQg7YyM7J287J2EIO2MjOyLse2VmOqzoCwg7IOIIOyXlO2KuOumrOulvCDstpTqsIDtlZwg65KkLCDsoITssrQg7YyM7J287J2EIOyerOyDneyEse2VqeuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgYXBwZW5kRW50cmllc1RvRGljdEZpbGUoXG4gICAgZmlsZVBhdGg6IHN0cmluZyxcbiAgICBlbnRyaWVzOiBEaWN0RW50cnlbXSxcbiAgICBsb2NhbGU6IHN0cmluZyxcbiAgICBpc0RlZmF1bHRMb2NhbGU6IGJvb2xlYW4sXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIOq4sOyhtCBlbnRyaWVzIO2MjOyLsVxuICAgIGNvbnN0IGV4aXN0aW5nRW50cmllcyA9IHRoaXMucGFyc2VEaWN0RmlsZShmaWxlUGF0aCk7XG5cbiAgICAvLyDsg4ggZW50cmllcyDstpTqsIBcbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICAgIGV4aXN0aW5nRW50cmllcy5wdXNoKGVudHJ5KTtcbiAgICB9XG5cbiAgICAvLyDtjIzsnbwg7J6s7IOd7ISxXG4gICAgY29uc3QgY29udGVudCA9IHRoaXMuZ2VuZXJhdGVQcm9qZWN0RGljdChsb2NhbGUsIGV4aXN0aW5nRW50cmllcywgaXNEZWZhdWx0TG9jYWxlKTtcbiAgICBjb25zdCBmb3JtYXR0ZWQgPSBhd2FpdCBmb3JtYXRDb2RlKGNvbnRlbnQsIGZpbGVQYXRoKTtcbiAgICBmcy53cml0ZUZpbGVTeW5jKGZpbGVQYXRoLCBmb3JtYXR0ZWQsIFwidXRmLThcIik7XG4gIH1cblxuICAvKipcbiAgICog7ZWo7IiYIOqwkuuTpOyXkOyEnCDsgqzsmqnrkJjripQg7Zes7Y28IO2VqOyImOulvCDqsJDsp4Dtlanri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGRldGVjdFVzZWRIZWxwZXJzKGVudHJpZXM6IERpY3RFbnRyeVtdKToge1xuICAgIGhlbHBlcnM6IHN0cmluZ1tdO1xuICAgIHVzZXNGb3JtYXQ6IGJvb2xlYW47XG4gIH0ge1xuICAgIGNvbnN0IGZ1bmN0aW9uRW50cmllcyA9IGVudHJpZXMuZmlsdGVyKChlKSA9PiBlLmlzRnVuY3Rpb24pO1xuICAgIGNvbnN0IGhlbHBlcnM6IHN0cmluZ1tdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IGhlbHBlciBvZiBbXCJwbHVyYWxcIiwgXCJqb3NhXCJdKSB7XG4gICAgICAvLyDtlajsiJjrqoXsnbQg64uo7Ja0IOqyveqzhOuhnCDsgqzsmqnrkJjripTsp4Ag7ZmV7J24ICjsmIg6IHBsdXJhbCgg65iQ64qUIHBsdXJhbCwpXG4gICAgICBjb25zdCBwYXR0ZXJuID0gbmV3IFJlZ0V4cChgXFxcXGIke2hlbHBlcn1cXFxccypcXFxcKGApO1xuICAgICAgaWYgKGZ1bmN0aW9uRW50cmllcy5zb21lKChlKSA9PiBwYXR0ZXJuLnRlc3QoZS52YWx1ZSkpKSB7XG4gICAgICAgIGhlbHBlcnMucHVzaChoZWxwZXIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGZvcm1hdCDsgqzsmqkg7Jes67aAIOuzhOuPhCDqsJDsp4AgKGZvcm1hdC5udW1iZXIoLi4uKSwgZm9ybWF0LmRhdGUoLi4uKSDrk7EpXG4gICAgY29uc3QgZm9ybWF0UGF0dGVybiA9IC9cXGJmb3JtYXRcXC5cXHcrXFxzKlxcKC87XG4gICAgY29uc3QgdXNlc0Zvcm1hdCA9IGZ1bmN0aW9uRW50cmllcy5zb21lKChlKSA9PiBmb3JtYXRQYXR0ZXJuLnRlc3QoZS52YWx1ZSkpO1xuXG4gICAgcmV0dXJuIHsgaGVscGVycywgdXNlc0Zvcm1hdCB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2plY3QgZGljdCDtjIzsnbwg7IOd7ISxXG4gICAqL1xuICBnZW5lcmF0ZVByb2plY3REaWN0KGxvY2FsZTogc3RyaW5nLCBlbnRyaWVzOiBEaWN0RW50cnlbXSwgaXNEZWZhdWx0TG9jYWxlOiBib29sZWFuKTogc3RyaW5nIHtcbiAgICAvLyBrZXkg7JWM7YyM67KzIOyInCDsoJXroKxcbiAgICBjb25zdCBzb3J0ZWQgPSBbLi4uZW50cmllc10udG9Tb3J0ZWQoKGEsIGIpID0+IGEua2V5LmxvY2FsZUNvbXBhcmUoYi5rZXkpKTtcblxuICAgIGNvbnN0IGxpbmVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgLy8g7ZWo7IiYIOqwkuyXkOyEnCDsgqzsmqnrkJjripQg7Zes7Y28IO2VqOyImCDqsJDsp4BcbiAgICBjb25zdCB7IGhlbHBlcnMsIHVzZXNGb3JtYXQgfSA9IHRoaXMuZGV0ZWN0VXNlZEhlbHBlcnMoZW50cmllcyk7XG5cbiAgICAvLyDtl6ztjbwg7ZWo7IiYIGltcG9ydCDstpTqsIBcbiAgICBjb25zdCBpbXBvcnRzID0gWy4uLmhlbHBlcnNdO1xuICAgIGlmICh1c2VzRm9ybWF0KSB7XG4gICAgICBpbXBvcnRzLnB1c2goXCJjcmVhdGVGb3JtYXRcIik7XG4gICAgfVxuICAgIGlmIChpbXBvcnRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGxpbmVzLnB1c2goYGltcG9ydCB7ICR7aW1wb3J0cy5qb2luKFwiLCBcIil9IH0gZnJvbSBcInNvbmFtdS9kaWN0XCI7YCk7XG4gICAgfVxuXG4gICAgaWYgKCFpc0RlZmF1bHRMb2NhbGUpIHtcbiAgICAgIGxpbmVzLnB1c2goJ2ltcG9ydCB7IGRlZmluZUxvY2FsZSB9IGZyb20gXCIuL3NkLmdlbmVyYXRlZFwiOycpO1xuICAgIH1cblxuICAgIGlmIChpbXBvcnRzLmxlbmd0aCA+IDAgfHwgIWlzRGVmYXVsdExvY2FsZSkge1xuICAgICAgbGluZXMucHVzaChcIlwiKTtcbiAgICB9XG5cbiAgICAvLyBmb3JtYXQg7IKs7JqpIOyLnCBjcmVhdGVGb3JtYXQg7Zi47LacIOy2lOqwgFxuICAgIGlmICh1c2VzRm9ybWF0KSB7XG4gICAgICBsaW5lcy5wdXNoKGBjb25zdCBmb3JtYXQgPSBjcmVhdGVGb3JtYXQoXCIke2xvY2FsZX1cIik7YCk7XG4gICAgICBsaW5lcy5wdXNoKFwiXCIpO1xuICAgIH1cblxuICAgIGxpbmVzLnB1c2goXCIvKipcIik7XG4gICAgbGluZXMucHVzaChgICogUHJvamVjdCAke2xvY2FsZS50b1VwcGVyQ2FzZSgpfSBEaWN0aW9uYXJ5YCk7XG4gICAgbGluZXMucHVzaChcIiAqL1wiKTtcblxuICAgIGlmIChpc0RlZmF1bHRMb2NhbGUpIHtcbiAgICAgIGxpbmVzLnB1c2goXCJleHBvcnQgZGVmYXVsdCB7XCIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsaW5lcy5wdXNoKFwiZXhwb3J0IGRlZmF1bHQgZGVmaW5lTG9jYWxlKHtcIik7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBzb3J0ZWQpIHtcbiAgICAgIGlmIChlbnRyeS5pc0Z1bmN0aW9uKSB7XG4gICAgICAgIC8vIO2VqOyImOyduCDqsr3smrA6IOybkO2YlSDqt7jrjIDroZwg7Lac66ClXG4gICAgICAgIGxpbmVzLnB1c2goYCAgXCIke2VudHJ5LmtleX1cIjogJHtlbnRyeS52YWx1ZX0sYCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsaW5lcy5wdXNoKGAgIFwiJHtlbnRyeS5rZXl9XCI6ICR7SlNPTi5zdHJpbmdpZnkoZW50cnkudmFsdWUpfSxgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNEZWZhdWx0TG9jYWxlKSB7XG4gICAgICBsaW5lcy5wdXNoKFwifSBhcyBjb25zdDtcIik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxpbmVzLnB1c2goXCJ9KTtcIik7XG4gICAgfVxuICAgIGxpbmVzLnB1c2goXCJcIik7XG5cbiAgICByZXR1cm4gbGluZXMuam9pbihcIlxcblwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBpMThuIOyEpOygleydhCDqsIDsoLjsmLXri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGdldEkxOG5Db25maWcoKTogSTE4bkNvbmZpZyB7XG4gICAgcmV0dXJuIFNvbmFtdS5jb25maWcuaTE4bjtcbiAgfVxuXG4gIC8qKlxuICAgKiBpMThuIOuUlOugie2GoOumrCDqsr3roZzrpbwg67CY7ZmY7ZWY6rOgLCDsl4bsnLzrqbQg7IOd7ISx7ZWp64uI64ukLlxuICAgKi9cbiAgcHJpdmF0ZSBlbnN1cmVJMThuRGlyKCk6IHN0cmluZyB7XG4gICAgY29uc3QgaTE4bkRpciA9IHBhdGguam9pbihTb25hbXUuYXBpUm9vdFBhdGgsIFwic3JjXCIsIFwiaTE4blwiKTtcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoaTE4bkRpcikpIHtcbiAgICAgIGZzLm1rZGlyU3luYyhpMThuRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGkxOG5EaXI7XG4gIH1cblxuICAvKipcbiAgICogZGljdCDtjIzsnbzsnYQg7KCA7J6l7ZWp64uI64ukLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBzYXZlRGljdEZpbGUoXG4gICAgbG9jYWxlOiBzdHJpbmcsXG4gICAgZW50cmllczogRGljdEVudHJ5W10sXG4gICAgaXNEZWZhdWx0TG9jYWxlOiBib29sZWFuLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBpMThuRGlyID0gdGhpcy5lbnN1cmVJMThuRGlyKCk7XG4gICAgY29uc3QgZGljdFBhdGggPSBwYXRoLmpvaW4oaTE4bkRpciwgYCR7bG9jYWxlfS50c2ApO1xuICAgIGNvbnN0IGNvbnRlbnQgPSB0aGlzLmdlbmVyYXRlUHJvamVjdERpY3QobG9jYWxlLCBlbnRyaWVzLCBpc0RlZmF1bHRMb2NhbGUpO1xuICAgIGNvbnN0IGZvcm1hdHRlZCA9IGF3YWl0IGZvcm1hdENvZGUoY29udGVudCwgZGljdFBhdGgpO1xuICAgIGZzLndyaXRlRmlsZVN5bmMoZGljdFBhdGgsIGZvcm1hdHRlZCwgXCJ1dGYtOFwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBpMThuIGtleeulvCDtjIzsi7HtlZjsl6wgZW50aXR5IOq0gOugqCDsoJXrs7Qg7LaU7LacXG4gICAqL1xuICBwYXJzZUVudGl0eUtleShrZXk6IHN0cmluZyk6IEVudGl0eUtleUluZm8ge1xuICAgIC8vIGVudGl0eS57RW50aXR5SWR9IChsaXN0LCBjcmVhdGUsIGVkaXQg7KCc7Jm4KVxuICAgIGNvbnN0IGVudGl0eVRpdGxlTWF0Y2ggPSBrZXkubWF0Y2goL15lbnRpdHlcXC4oW0EtWl1bYS16QS1aMC05XSopJC8pO1xuICAgIGlmIChcbiAgICAgIGVudGl0eVRpdGxlTWF0Y2ggJiZcbiAgICAgICFrZXkuaW5jbHVkZXMoXCIubGlzdFwiKSAmJlxuICAgICAgIWtleS5pbmNsdWRlcyhcIi5jcmVhdGVcIikgJiZcbiAgICAgICFrZXkuaW5jbHVkZXMoXCIuZWRpdFwiKVxuICAgICkge1xuICAgICAgcmV0dXJuIHsgdHlwZTogXCJlbnRpdHlUaXRsZVwiLCBlbnRpdHlJZDogZW50aXR5VGl0bGVNYXRjaFsxXSB9O1xuICAgIH1cblxuICAgIC8vIGVudGl0eS57RW50aXR5SWR9Lntwcm9wTmFtZX1cbiAgICBjb25zdCBwcm9wRGVzY01hdGNoID0ga2V5Lm1hdGNoKC9eZW50aXR5XFwuKFtBLVpdW2EtekEtWjAtOV0qKVxcLihbYS16X11bYS16MC05X10qKSQvKTtcbiAgICBpZiAocHJvcERlc2NNYXRjaCkge1xuICAgICAgcmV0dXJuIHsgdHlwZTogXCJwcm9wRGVzY1wiLCBlbnRpdHlJZDogcHJvcERlc2NNYXRjaFsxXSwgcHJvcE5hbWU6IHByb3BEZXNjTWF0Y2hbMl0gfTtcbiAgICB9XG5cbiAgICAvLyBlbnVtLntFbnVtSWR9Lnt2YWx1ZX1cbiAgICBjb25zdCBlbnVtTGFiZWxNYXRjaCA9IGtleS5tYXRjaCgvXmVudW1cXC4oW0EtWl1bYS16QS1aMC05XSopXFwuKC4rKSQvKTtcbiAgICBpZiAoZW51bUxhYmVsTWF0Y2gpIHtcbiAgICAgIHJldHVybiB7IHR5cGU6IFwiZW51bUxhYmVsXCIsIGVudW1JZDogZW51bUxhYmVsTWF0Y2hbMV0sIGVudW1WYWx1ZTogZW51bUxhYmVsTWF0Y2hbMl0gfTtcbiAgICB9XG5cbiAgICByZXR1cm4geyB0eXBlOiBcIm90aGVyXCIgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBlbnRpdHkga2V57JeQIOuMgO2VtCBlbnRpdHkuanNvbiDsl4XrjbDsnbTtirgg7IiY7ZaJXG4gICAqIEByZXR1cm5zIOyXheuNsOydtO2KuCDsl6zrtoBcbiAgICovXG4gIGFzeW5jIHVwZGF0ZUVudGl0eUJ5S2V5KGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qga2V5SW5mbyA9IHRoaXMucGFyc2VFbnRpdHlLZXkoa2V5KTtcblxuICAgIHN3aXRjaCAoa2V5SW5mby50eXBlKSB7XG4gICAgICBjYXNlIFwiZW50aXR5VGl0bGVcIjoge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGtleUluZm8uZW50aXR5SWQpO1xuICAgICAgICAgIGlmIChlbnRpdHkudGl0bGUgIT09IHZhbHVlKSB7XG4gICAgICAgICAgICBlbnRpdHkudGl0bGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIC8vIGVudGl0eSBub3QgZm91bmRcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgXCJwcm9wRGVzY1wiOiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoa2V5SW5mby5lbnRpdHlJZCk7XG4gICAgICAgICAgY29uc3QgcHJvcEluZGV4ID0gZW50aXR5LnByb3BzLmZpbmRJbmRleCgocCkgPT4gcC5uYW1lID09PSBrZXlJbmZvLnByb3BOYW1lKTtcbiAgICAgICAgICBpZiAocHJvcEluZGV4ICE9PSAtMSAmJiBlbnRpdHkucHJvcHNbcHJvcEluZGV4XS5kZXNjICE9PSB2YWx1ZSkge1xuICAgICAgICAgICAgZW50aXR5LnByb3BzW3Byb3BJbmRleF0uZGVzYyA9IHZhbHVlO1xuICAgICAgICAgICAgYXdhaXQgZW50aXR5LnNhdmUoKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgLy8gZW50aXR5IG5vdCBmb3VuZFxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgY2FzZSBcImVudW1MYWJlbFwiOiB7XG4gICAgICAgIGZvciAoY29uc3QgZW50aXR5SWQgb2YgRW50aXR5TWFuYWdlci5nZXRBbGxJZHMoKSkge1xuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICBpZiAoZW50aXR5LmVudW1MYWJlbHNba2V5SW5mby5lbnVtSWRdKSB7XG4gICAgICAgICAgICBpZiAoZW50aXR5LmVudW1MYWJlbHNba2V5SW5mby5lbnVtSWRdW2tleUluZm8uZW51bVZhbHVlXSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgZW50aXR5LmVudW1MYWJlbHNba2V5SW5mby5lbnVtSWRdW2tleUluZm8uZW51bVZhbHVlXSA9IHZhbHVlO1xuICAgICAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogc2QuZ2VuZXJhdGVkLnRz7JeQ7IScIGVudGl0eSBsYWJlbHMg7LaU7LacXG4gICAqIGVudGl0eS5qc29u7JeQ7IScIOq0gOumrOuQmOuKlCDqsJLrp4wg7Y+s7ZWoICgubGlzdCwgLmNyZWF0ZSwgLmVkaXQg7KCc7Jm4KVxuICAgKi9cbiAgZXh0cmFjdEVudGl0eUxhYmVscygpOiBEaWN0RW50cnlbXSB7XG4gICAgY29uc3Qgc2RQYXRoID0gcGF0aC5qb2luKFNvbmFtdS5hcGlSb290UGF0aCwgXCJzcmNcIiwgXCJpMThuXCIsIFwic2QuZ2VuZXJhdGVkLnRzXCIpO1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhzZFBhdGgpKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucGFyc2VDb25zdE9iamVjdERlY2xhcmF0aW9uKHNkUGF0aCwgXCJlbnRpdHlMYWJlbHNcIik7XG4gIH1cblxuICAvKipcbiAgICogc2QuZ2VuZXJhdGVkLnRz7JeQ7IScIHJjLWtleXMg7LaU7LacXG4gICAqIHJlYWN0LWNvbXBvbmVudHPsl5DshJwg6rSA66as65CY64qUIGkxOG4g7YKk65OkXG4gICAqIEBwYXJhbSBsb2NhbGUgLSDroZzsvIDsnbwgKGtvLCBlbiDrk7EpXG4gICAqL1xuICBleHRyYWN0UkNLZXlzKGxvY2FsZTogc3RyaW5nKTogRGljdEVudHJ5W10ge1xuICAgIGNvbnN0IHNkUGF0aCA9IHBhdGguam9pbihTb25hbXUuYXBpUm9vdFBhdGgsIFwic3JjXCIsIFwiaTE4blwiLCBcInNkLmdlbmVyYXRlZC50c1wiKTtcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoc2RQYXRoKSkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIC8vIGxvY2FsZeuzhCDrs4DsiJjrqoUg66ek7ZWRIChzZC50ZW1wbGF0ZS50c+ydmCBnZXRSQ0tleXNWYXJOYW1l6rO8IOuPmeydvClcbiAgICBjb25zdCB2YXJOYW1lID0gKCgpID0+IHtcbiAgICAgIGlmIChsb2NhbGUgPT09IFwia29cIikgcmV0dXJuIFwicmNLZXlzS29cIjtcbiAgICAgIGlmIChsb2NhbGUgPT09IFwiZW5cIikgcmV0dXJuIFwicmNLZXlzRW5cIjtcbiAgICAgIC8vIOuLpOuluCBsb2NhbGXsnYAgZW7snYQgZmFsbGJhY2vsnLzroZwg7IKs7JqpXG4gICAgICByZXR1cm4gXCJyY0tleXNFblwiO1xuICAgIH0pKCk7XG5cbiAgICByZXR1cm4gdGhpcy5wYXJzZUNvbnN0T2JqZWN0RGVjbGFyYXRpb24oc2RQYXRoLCB2YXJOYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9qZWN0IGRpY3Qg7YyM7J28KFtsb2NhbGVdLnRzKeyXkOyEnCDrlJXshZTrhIjrpqwg66Gc65OcXG4gICAqL1xuICBsb2FkUHJvamVjdERpY3QobG9jYWxlOiBzdHJpbmcpOiB7IGVudHJpZXM6IERpY3RFbnRyeVtdIH0ge1xuICAgIGNvbnN0IGRpY3RQYXRoID0gcGF0aC5qb2luKFNvbmFtdS5hcGlSb290UGF0aCwgXCJzcmNcIiwgXCJpMThuXCIsIGAke2xvY2FsZX0udHNgKTtcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZGljdFBhdGgpKSB7XG4gICAgICByZXR1cm4geyBlbnRyaWVzOiBbXSB9O1xuICAgIH1cbiAgICByZXR1cm4geyBlbnRyaWVzOiB0aGlzLnBhcnNlRGljdEZpbGUoZGljdFBhdGgpIH07XG4gIH1cblxuICAvKipcbiAgICog65SV7IWU64SI66asIOuNsOydtO2EsCDsiJjsp5EgKHNvbmFtdSArIGVudGl0eSArIHByb2plY3QpXG4gICAqL1xuICBhc3luYyBjb2xsZWN0RGljdGlvbmFyeSgpOiBQcm9taXNlPERpY3Rpb25hcnlSZXN1bHQ+IHtcbiAgICBjb25zdCB7IGRlZmF1bHRMb2NhbGUsIHN1cHBvcnRlZExvY2FsZXMgfSA9IHRoaXMuZ2V0STE4bkNvbmZpZygpO1xuICAgIGNvbnN0IGxvY2FsZXMgPSBzdXBwb3J0ZWRMb2NhbGVzO1xuXG4gICAgY29uc3Qgcm93czogRGljdGlvbmFyeVJvd1tdID0gW107XG4gICAgY29uc3Qgcm93TWFwID0gbmV3IE1hcDxzdHJpbmcsIERpY3Rpb25hcnlSb3c+KCk7XG5cbiAgICAvLyAxLiBSQyBLZXlzIChzb25hbXUgc291cmNlLCDqsIEgbG9jYWxl67OEKVxuICAgIGZvciAoY29uc3QgbG9jYWxlIG9mIGxvY2FsZXMpIHtcbiAgICAgIGNvbnN0IHJjS2V5cyA9IHRoaXMuZXh0cmFjdFJDS2V5cyhsb2NhbGUpO1xuICAgICAgZm9yIChjb25zdCByY0tleSBvZiByY0tleXMpIHtcbiAgICAgICAgbGV0IHJvdyA9IHJvd01hcC5nZXQocmNLZXkua2V5KTtcbiAgICAgICAgaWYgKCFyb3cpIHtcbiAgICAgICAgICByb3cgPSB7XG4gICAgICAgICAgICBrZXk6IHJjS2V5LmtleSxcbiAgICAgICAgICAgIHNvdXJjZTogXCJzb25hbXVcIixcbiAgICAgICAgICAgIGlzRnVuY3Rpb246IHJjS2V5LmlzRnVuY3Rpb24gPz8gZmFsc2UsXG4gICAgICAgICAgfTtcbiAgICAgICAgICByb3dNYXAuc2V0KHJjS2V5LmtleSwgcm93KTtcbiAgICAgICAgfVxuICAgICAgICByb3dbbG9jYWxlXSA9IHJjS2V5LnZhbHVlO1xuICAgICAgICBpZiAocmNLZXkuaXNGdW5jdGlvbikge1xuICAgICAgICAgIHJvdy5pc0Z1bmN0aW9uID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIDIuIEVudGl0eSBsYWJlbHMgKGRlZmF1bHQgbG9jYWxlIOq4sOykgClcbiAgICBjb25zdCBlbnRpdHlMYWJlbHMgPSB0aGlzLmV4dHJhY3RFbnRpdHlMYWJlbHMoKTtcbiAgICBmb3IgKGNvbnN0IGxhYmVsIG9mIGVudGl0eUxhYmVscykge1xuICAgICAgY29uc3Qgcm93OiBEaWN0aW9uYXJ5Um93ID0ge1xuICAgICAgICBrZXk6IGxhYmVsLmtleSxcbiAgICAgICAgc291cmNlOiBcImVudGl0eVwiLFxuICAgICAgICBpc0Z1bmN0aW9uOiBsYWJlbC5pc0Z1bmN0aW9uID8/IGZhbHNlLFxuICAgICAgICBbZGVmYXVsdExvY2FsZV06IGxhYmVsLnZhbHVlLFxuICAgICAgfTtcbiAgICAgIHJvd01hcC5zZXQobGFiZWwua2V5LCByb3cpO1xuICAgIH1cblxuICAgIC8vIDMuIFByb2plY3QgZGljdCAo6rCBIGxvY2FsZeuzhClcbiAgICBmb3IgKGNvbnN0IGxvY2FsZSBvZiBsb2NhbGVzKSB7XG4gICAgICBjb25zdCB7IGVudHJpZXMgfSA9IHRoaXMubG9hZFByb2plY3REaWN0KGxvY2FsZSk7XG4gICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICAgICAgY29uc3QgZXhpc3RpbmcgPSByb3dNYXAuZ2V0KGVudHJ5LmtleSk7XG4gICAgICAgIGlmIChleGlzdGluZykge1xuICAgICAgICAgIC8vIHNvbmFtdSwgZW50aXR5IHNvdXJjZeqwgCDsnojsnLzrqbQg7ZW064u5IGxvY2FsZSDqsJLrp4wg7LaU6rCAXG4gICAgICAgICAgZXhpc3RpbmdbbG9jYWxlXSA9IGVudHJ5LnZhbHVlO1xuICAgICAgICAgIGlmIChlbnRyeS5pc0Z1bmN0aW9uKSB7XG4gICAgICAgICAgICBleGlzdGluZy5pc0Z1bmN0aW9uID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gcHJvamVjdCBzb3VyY2XroZwg7IOI66GcIOy2lOqwgFxuICAgICAgICAgIGxldCByb3cgPSByb3dNYXAuZ2V0KGVudHJ5LmtleSk7XG4gICAgICAgICAgaWYgKCFyb3cpIHtcbiAgICAgICAgICAgIHJvdyA9IHtcbiAgICAgICAgICAgICAga2V5OiBlbnRyeS5rZXksXG4gICAgICAgICAgICAgIHNvdXJjZTogXCJwcm9qZWN0XCIsXG4gICAgICAgICAgICAgIGlzRnVuY3Rpb246IGVudHJ5LmlzRnVuY3Rpb24sXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcm93TWFwLnNldChlbnRyeS5rZXksIHJvdyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJvd1tsb2NhbGVdID0gZW50cnkudmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByb3dzLnB1c2goLi4ucm93TWFwLnZhbHVlcygpKTtcbiAgICByb3dzLnNvcnQoKGEsIGIpID0+IGEua2V5LmxvY2FsZUNvbXBhcmUoYi5rZXkpKTtcblxuICAgIC8vIO2GteqzhCDqs4TsgrA6IGxvY2FsZeuzhCAo7LGE7JuM7KeEIOqwkiAvIOyghOyytCDtgqQg7IiYKVxuICAgIGNvbnN0IHN0YXRzOiBSZWNvcmQ8c3RyaW5nLCB7IHRvdGFsOiBudW1iZXI7IGZpbGxlZDogbnVtYmVyOyBwZXJjZW50OiBudW1iZXIgfT4gPSB7fTtcbiAgICBjb25zdCB0b3RhbCA9IHJvd3MubGVuZ3RoO1xuICAgIGZvciAoY29uc3QgbG9jYWxlIG9mIGxvY2FsZXMpIHtcbiAgICAgIGNvbnN0IGZpbGxlZCA9IHJvd3MuZmlsdGVyKChyb3cpID0+ICEhcm93W2xvY2FsZV0pLmxlbmd0aDtcbiAgICAgIGNvbnN0IHBlcmNlbnQgPSB0b3RhbCA+IDAgPyBNYXRoLnJvdW5kKChmaWxsZWQgLyB0b3RhbCkgKiAxMDApIDogMDtcbiAgICAgIHN0YXRzW2xvY2FsZV0gPSB7IHRvdGFsLCBmaWxsZWQsIHBlcmNlbnQgfTtcbiAgICB9XG5cbiAgICByZXR1cm4geyByb3dzLCBsb2NhbGVzLCBkZWZhdWx0TG9jYWxlLCBzdGF0cyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOuUleyFlOuEiOumrCDsobDtmoxcbiAgICovXG4gIGFzeW5jIGdldERpY3Rpb25hcnkoKTogUHJvbWlzZTxEaWN0aW9uYXJ5UmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMuY29sbGVjdERpY3Rpb25hcnkoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGNlbOuhnCDrgrTrs7TrgrTquLBcbiAgICovXG4gIGFzeW5jIGV4cG9ydFRvRXhjZWwoKTogUHJvbWlzZTx7IGZpbGVuYW1lOiBzdHJpbmc7IGJ1ZmZlcjogQnVmZmVyIH0+IHtcbiAgICBjb25zdCB7IHJvd3MsIGxvY2FsZXMgfSA9IGF3YWl0IHRoaXMuY29sbGVjdERpY3Rpb25hcnkoKTtcblxuICAgIGNvbnN0IHdiID0gbmV3IFdvcmtib29rKCk7XG4gICAgY29uc3Qgc2hlZXQgPSBcImkxOG5cIjtcbiAgICB3Yi5zZXRTaGVldE5hbWUoXCJTaGVldDFcIiwgc2hlZXQpO1xuXG4gICAgY29uc3QgcHJvamVjdE5hbWUgPSBgJHtTb25hbXUuY29uZmlnLnByb2plY3ROYW1lID8/IFwiU29uYW11XCJ9IERpY3Rpb25hcnlgO1xuICAgIGNvbnN0IGhlYWRlcnMgPSBbXCJrZXlcIiwgXCJzb3VyY2VcIiwgLi4ubG9jYWxlc107XG5cbiAgICAvLyDsiqTtg4Dsnbwg7KCV7J2YXG4gICAgY29uc3QgdGl0bGVTdHlsZUlkID0gd2IuYWRkU3R5bGUoe1xuICAgICAgZm9udDogeyBzaXplOiAyMyB9LFxuICAgICAgYWxpZ25tZW50OiB7IHZlcnRpY2FsOiBcImNlbnRlclwiLCBob3Jpem9udGFsOiBcImxlZnRcIiB9LFxuICAgIH0pO1xuICAgIGNvbnN0IGhlYWRlclN0eWxlSWQgPSB3Yi5hZGRTdHlsZSh7XG4gICAgICBmb250OiB7IGJvbGQ6IHRydWUsIHNpemU6IDExIH0sXG4gICAgICBhbGlnbm1lbnQ6IHsgaG9yaXpvbnRhbDogXCJjZW50ZXJcIiwgdmVydGljYWw6IFwiY2VudGVyXCIgfSxcbiAgICAgIGZpbGw6IHsgcGF0dGVybjogXCJzb2xpZFwiLCBmZ0NvbG9yOiBcIkYxRjFGMVwiIH0sXG4gICAgICBib3JkZXI6IHtcbiAgICAgICAgdG9wOiB7IHN0eWxlOiBcInRoaW5cIiwgY29sb3I6IFwiRDBEMEQwXCIgfSxcbiAgICAgICAgbGVmdDogeyBzdHlsZTogXCJ0aGluXCIsIGNvbG9yOiBcIkQwRDBEMFwiIH0sXG4gICAgICAgIGJvdHRvbTogeyBzdHlsZTogXCJ0aGluXCIsIGNvbG9yOiBcIkQwRDBEMFwiIH0sXG4gICAgICAgIHJpZ2h0OiB7IHN0eWxlOiBcInRoaW5cIiwgY29sb3I6IFwiRDBEMEQwXCIgfSxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgY29uc3QgZGF0YVN0eWxlSWQgPSB3Yi5hZGRTdHlsZSh7XG4gICAgICBmb250OiB7IHNpemU6IDExIH0sXG4gICAgICBhbGlnbm1lbnQ6IHsgdmVydGljYWw6IFwiY2VudGVyXCIsIGhvcml6b250YWw6IFwibGVmdFwiIH0sXG4gICAgfSk7XG5cbiAgICAvLyDtlokgMTog7ZSE66Gc7KCd7Yq466qFXG4gICAgd2Iuc2V0Q2VsbFZhbHVlKHNoZWV0LCBcIkExXCIsIHByb2plY3ROYW1lKTtcbiAgICB3Yi5zZXRDZWxsU3R5bGUoc2hlZXQsIFwiQTFcIiwgdGl0bGVTdHlsZUlkKTtcbiAgICB3Yi5zZXRSb3dIZWlnaHQoc2hlZXQsIDEsIDI4KTtcblxuICAgIC8vIO2WiSAyOiDruYgg7ZaJICjquLDrs7jqsJIpXG5cbiAgICAvLyDtlokgMzog7Zek642UXG4gICAgd2Iuc2V0Um93VmFsdWVzKHNoZWV0LCAzLCBcIkFcIiwgaGVhZGVycyk7XG4gICAgd2Iuc2V0Um93SGVpZ2h0KHNoZWV0LCAzLCAyNik7XG4gICAgZm9yIChsZXQgY29sID0gMDsgY29sIDwgaGVhZGVycy5sZW5ndGg7IGNvbCsrKSB7XG4gICAgICB3Yi5zZXRDZWxsU3R5bGUoc2hlZXQsIGAke2NvbExldHRlcihjb2wpfTNgLCBoZWFkZXJTdHlsZUlkKTtcbiAgICB9XG5cbiAgICAvLyDtlokgNCDsnbTtm4Q6IOuNsOydtO2EsFxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93cy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgcm93ID0gcm93c1tpXTtcbiAgICAgIGNvbnN0IHZhbHVlcyA9IFtyb3cua2V5LCByb3cuc291cmNlLCAuLi5sb2NhbGVzLm1hcCgobG9jYWxlKSA9PiByb3dbbG9jYWxlXSA/PyBcIlwiKV07XG4gICAgICBjb25zdCByb3dOdW0gPSBpICsgNDtcbiAgICAgIHdiLnNldFJvd1ZhbHVlcyhzaGVldCwgcm93TnVtLCBcIkFcIiwgdmFsdWVzKTtcbiAgICAgIHdiLnNldFJvd0hlaWdodChzaGVldCwgcm93TnVtLCAyNCk7XG4gICAgICBmb3IgKGxldCBjb2wgPSAwOyBjb2wgPCB2YWx1ZXMubGVuZ3RoOyBjb2wrKykge1xuICAgICAgICB3Yi5zZXRDZWxsU3R5bGUoc2hlZXQsIGAke2NvbExldHRlcihjb2wpfSR7cm93TnVtfWAsIGRhdGFTdHlsZUlkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyDsu6zrn7wg64SI67mEIOqzhOyCsFxuICAgIGNvbnN0IE1BWF9XSURUSCA9IDUwO1xuICAgIGNvbnN0IE1JTl9XSURUSCA9IDEwO1xuICAgIGNvbnN0IGNvbHVtbldpZHRoczogbnVtYmVyW10gPSBoZWFkZXJzLm1hcCgoaGVhZGVyKSA9PiBNYXRoLm1heChoZWFkZXIubGVuZ3RoLCBNSU5fV0lEVEgpKTtcblxuICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgIGNvbnN0IHZhbHVlcyA9IFtyb3cua2V5LCByb3cuc291cmNlLCAuLi5sb2NhbGVzLm1hcCgobG9jYWxlKSA9PiByb3dbbG9jYWxlXSA/PyBcIlwiKV07XG4gICAgICB2YWx1ZXMuZm9yRWFjaCgodmFsdWUsIGlkeCkgPT4ge1xuICAgICAgICBjb25zdCB0ZXh0TGVuZ3RoID0gU3RyaW5nKHZhbHVlKS5sZW5ndGg7XG4gICAgICAgIGNvbHVtbldpZHRoc1tpZHhdID0gTWF0aC5taW4oTWF0aC5tYXgoY29sdW1uV2lkdGhzW2lkeF0sIHRleHRMZW5ndGgpLCBNQVhfV0lEVEgpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8g7Lus65+8IOuEiOu5hCDsoIHsmqlcbiAgICBmb3IgKGxldCBjb2wgPSAwOyBjb2wgPCBjb2x1bW5XaWR0aHMubGVuZ3RoOyBjb2wrKykge1xuICAgICAgd2Iuc2V0Q29sV2lkdGgoc2hlZXQsIGNvbExldHRlcihjb2wpLCBjb2x1bW5XaWR0aHNbY29sXSArIDIpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBmaWxlbmFtZTogYCR7cHJvamVjdE5hbWV9LSR7bmV3IERhdGUoKS50b0lTT1N0cmluZygpLnNwbGl0KFwiVFwiKVswXX0ueGxzeGAsXG4gICAgICBidWZmZXI6IHdiLndyaXRlQnVmZmVyU3luYygpLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogRXhjZWzsl5DshJwg6rCA7KC47Jik6riwXG4gICAqXG4gICAqIO2YleyLnTpcbiAgICogLSAx7ZaJOiDtlITroZzsoJ3tirjrqoVcbiAgICogLSAy7ZaJOiDruYgg7ZaJXG4gICAqIC0gM+2WiTog7Zek642UIChrZXksIHNvdXJjZSwgbG9jYWxlcy4uLilcbiAgICogLSA07ZaJIOydtO2bhDog642w7J207YSwXG4gICAqL1xuICBhc3luYyBpbXBvcnRGcm9tRXhjZWwoYnVmZmVyOiBCdWZmZXIpOiBQcm9taXNlPEltcG9ydFJlc3VsdD4ge1xuICAgIGNvbnN0IHdiID0gV29ya2Jvb2sub3BlbkJ1ZmZlclN5bmMoYnVmZmVyKTtcbiAgICBjb25zdCBzaGVldCA9IHdiLnNoZWV0TmFtZXNbMF07XG4gICAgY29uc3QgYWxsUm93cyA9IHdiLmdldFJvd3Moc2hlZXQpO1xuXG4gICAgY29uc3QgeyBkZWZhdWx0TG9jYWxlLCBzdXBwb3J0ZWRMb2NhbGVzIH0gPSB0aGlzLmdldEkxOG5Db25maWcoKTtcbiAgICBjb25zdCBsb2NhbGVzID0gc3VwcG9ydGVkTG9jYWxlcztcblxuICAgIGxldCB1cGRhdGVkRW50aXRpZXMgPSAwO1xuICAgIGxldCB1cGRhdGVkTG9jYWxlcyA9IDA7XG5cbiAgICAvLyBsb2NhbGXrs4QgcHJvamVjdCBkaWN0IGVudHJpZXNcbiAgICBjb25zdCBwcm9qZWN0RGljdEVudHJpZXM6IFJlY29yZDxzdHJpbmcsIERpY3RFbnRyeVtdPiA9IHt9O1xuICAgIGZvciAoY29uc3QgbG9jYWxlIG9mIGxvY2FsZXMpIHtcbiAgICAgIHByb2plY3REaWN0RW50cmllc1tsb2NhbGVdID0gW107XG4gICAgfVxuXG4gICAgLy8g7Zek642UIO2WiSDssL7quLA6IOyyqyDrsojsp7gg7Lus65+8KEEp7J20IFwia2V5XCLsnbgg7ZaJXG4gICAgbGV0IGhlYWRlclJvd051bSA9IDA7XG4gICAgZm9yIChjb25zdCByb3dEYXRhIG9mIGFsbFJvd3MpIHtcbiAgICAgIGNvbnN0IGZpcnN0Q2VsbCA9IHJvd0RhdGEuY2VsbHMuZmluZCgoYykgPT4gYy5jb2x1bW4gPT09IFwiQVwiKTtcbiAgICAgIGNvbnN0IGZpcnN0Q2VsbFZhbHVlID0gU3RyaW5nKGZpcnN0Q2VsbD8udmFsdWUgPz8gXCJcIilcbiAgICAgICAgLnRyaW0oKVxuICAgICAgICAudG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmIChmaXJzdENlbGxWYWx1ZSA9PT0gXCJrZXlcIikge1xuICAgICAgICBoZWFkZXJSb3dOdW0gPSByb3dEYXRhLnJvdztcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGhlYWRlclJvd051bSA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oU0QoXCJzb25hbXUuZXJyb3IuaGVhZGVyUm93Tm90Rm91bmRcIikpO1xuICAgIH1cblxuICAgIC8vIO2XpOuNlCDtlonsl5DshJwg7Lus65+8IOunpO2VkSDqtazshLFcbiAgICBjb25zdCBoZWFkZXJSb3dEYXRhID0gYWxsUm93cy5maW5kKChyKSA9PiByLnJvdyA9PT0gaGVhZGVyUm93TnVtKTtcbiAgICBjb25zdCBjb2xUb0hlYWRlcjogTWFwPHN0cmluZywgc3RyaW5nPiA9IG5ldyBNYXAoKTtcbiAgICBpZiAoaGVhZGVyUm93RGF0YSkge1xuICAgICAgZm9yIChjb25zdCBjZWxsIG9mIGhlYWRlclJvd0RhdGEuY2VsbHMpIHtcbiAgICAgICAgY29sVG9IZWFkZXIuc2V0KGNlbGwuY29sdW1uLCBTdHJpbmcoY2VsbC52YWx1ZSA/PyBcIlwiKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8g642w7J207YSwIO2WiSDsnb3quLAgKO2XpOuNlCDri6TsnYwg7ZaJ67aA7YSwKVxuICAgIGZvciAoY29uc3Qgcm93RGF0YSBvZiBhbGxSb3dzKSB7XG4gICAgICBpZiAocm93RGF0YS5yb3cgPD0gaGVhZGVyUm93TnVtKSBjb250aW51ZTtcblxuICAgICAgY29uc3Qgcm93VmFsdWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gICAgICBmb3IgKGNvbnN0IGNlbGwgb2Ygcm93RGF0YS5jZWxscykge1xuICAgICAgICBjb25zdCBoZWFkZXJOYW1lID0gY29sVG9IZWFkZXIuZ2V0KGNlbGwuY29sdW1uKTtcbiAgICAgICAgaWYgKGhlYWRlck5hbWUpIHtcbiAgICAgICAgICByb3dWYWx1ZXNbaGVhZGVyTmFtZV0gPSBTdHJpbmcoY2VsbC52YWx1ZSA/PyBcIlwiKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBrZXkgPSByb3dWYWx1ZXMua2V5O1xuICAgICAgY29uc3Qgc291cmNlID0gcm93VmFsdWVzLnNvdXJjZSBhcyBcImVudGl0eVwiIHwgXCJwcm9qZWN0XCI7XG5cbiAgICAgIGlmICgha2V5IHx8ICFzb3VyY2UpIGNvbnRpbnVlO1xuXG4gICAgICBpZiAoc291cmNlID09PSBcImVudGl0eVwiKSB7XG4gICAgICAgIC8vIGVudGl0eSBzb3VyY2U6IGRlZmF1bHQgbG9jYWxl66eMIGVudGl0eS5qc29u7JeQIOyggOyepVxuICAgICAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSByb3dWYWx1ZXNbZGVmYXVsdExvY2FsZV07XG4gICAgICAgIGlmIChkZWZhdWx0VmFsdWUpIHtcbiAgICAgICAgICBjb25zdCB1cGRhdGVkID0gYXdhaXQgdGhpcy51cGRhdGVFbnRpdHlCeUtleShrZXksIGRlZmF1bHRWYWx1ZSk7XG4gICAgICAgICAgaWYgKHVwZGF0ZWQpIHtcbiAgICAgICAgICAgIHVwZGF0ZWRFbnRpdGllcysrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIG5vbi1kZWZhdWx0IGxvY2FsZeydgCBwcm9qZWN0IGRpY3Tsl5Ag7KCA7J6lXG4gICAgICAgIGZvciAoY29uc3QgbG9jYWxlIG9mIGxvY2FsZXMpIHtcbiAgICAgICAgICBpZiAobG9jYWxlID09PSBkZWZhdWx0TG9jYWxlKSBjb250aW51ZTtcbiAgICAgICAgICBjb25zdCBjZWxsVmFsdWUgPSByb3dWYWx1ZXNbbG9jYWxlXT8udHJpbSgpO1xuICAgICAgICAgIGlmIChjZWxsVmFsdWUpIHtcbiAgICAgICAgICAgIHByb2plY3REaWN0RW50cmllc1tsb2NhbGVdLnB1c2goe1xuICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgIHZhbHVlOiBjZWxsVmFsdWUsXG4gICAgICAgICAgICAgIGlzRnVuY3Rpb246IHRoaXMuaXNFeHByZXNzaW9uRnVuY3Rpb24oY2VsbFZhbHVlKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChzb3VyY2UgPT09IFwicHJvamVjdFwiKSB7XG4gICAgICAgIC8vIHByb2plY3Qgc291cmNlOiDrqqjrk6AgbG9jYWxl7J2EIHByb2plY3QgZGljdOyXkCDsoIDsnqVcbiAgICAgICAgZm9yIChjb25zdCBsb2NhbGUgb2YgbG9jYWxlcykge1xuICAgICAgICAgIGNvbnN0IGNlbGxWYWx1ZSA9IHJvd1ZhbHVlc1tsb2NhbGVdPy50cmltKCk7XG4gICAgICAgICAgaWYgKGNlbGxWYWx1ZSkge1xuICAgICAgICAgICAgcHJvamVjdERpY3RFbnRyaWVzW2xvY2FsZV0ucHVzaCh7XG4gICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgdmFsdWU6IGNlbGxWYWx1ZSxcbiAgICAgICAgICAgICAgaXNGdW5jdGlvbjogdGhpcy5pc0V4cHJlc3Npb25GdW5jdGlvbihjZWxsVmFsdWUpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUHJvamVjdCBkaWN0IO2MjOydvCDsg53shLFcbiAgICBmb3IgKGNvbnN0IGxvY2FsZSBvZiBsb2NhbGVzKSB7XG4gICAgICBjb25zdCBlbnRyaWVzID0gcHJvamVjdERpY3RFbnRyaWVzW2xvY2FsZV07XG4gICAgICBpZiAoZW50cmllcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuc2F2ZURpY3RGaWxlKGxvY2FsZSwgZW50cmllcywgbG9jYWxlID09PSBkZWZhdWx0TG9jYWxlKTtcbiAgICAgICAgdXBkYXRlZExvY2FsZXMrKztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgIHVwZGF0ZWRFbnRpdGllcyxcbiAgICAgIHVwZGF0ZWRMb2NhbGVzLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICog65SV7IWU64SI66asIO2VreuqqSDsiJjsoJVcbiAgICovXG4gIGFzeW5jIHVwZGF0ZUVudHJ5KHBhcmFtczoge1xuICAgIG9sZEtleTogc3RyaW5nO1xuICAgIG5ld0tleTogc3RyaW5nO1xuICAgIHNvdXJjZTogXCJlbnRpdHlcIiB8IFwicHJvamVjdFwiIHwgXCJzb25hbXVcIjtcbiAgICB2YWx1ZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7IG9sZEtleSwgbmV3S2V5LCBzb3VyY2UsIHZhbHVlcyB9ID0gcGFyYW1zO1xuXG4gICAgY29uc3QgeyBkZWZhdWx0TG9jYWxlLCBzdXBwb3J0ZWRMb2NhbGVzIH0gPSB0aGlzLmdldEkxOG5Db25maWcoKTtcbiAgICBjb25zdCBsb2NhbGVzID0gc3VwcG9ydGVkTG9jYWxlcztcblxuICAgIC8vIGVudGl0eSBzb3VyY2XsnZggZGVmYXVsdCBsb2NhbGUg7LKY66asXG4gICAgaWYgKHNvdXJjZSA9PT0gXCJlbnRpdHlcIiAmJiB2YWx1ZXNbZGVmYXVsdExvY2FsZV0pIHtcbiAgICAgIGF3YWl0IHRoaXMudXBkYXRlRW50aXR5QnlLZXkobmV3S2V5LCB2YWx1ZXNbZGVmYXVsdExvY2FsZV0pO1xuICAgIH1cblxuICAgIC8vIHByb2plY3QgZGljdCDsl4XrjbDsnbTtirhcbiAgICAvLyAtIGVudGl0eeydmCBub24tZGVmYXVsdCBsb2NhbGVcbiAgICAvLyAtIHByb2plY3Qgc291cmNl7J2YIOuqqOuToCBsb2NhbGVcbiAgICAvLyAtIHNvbmFtdSBzb3VyY2XsnZgg66qo65OgIGxvY2FsZSAob3ZlcnJpZGUpXG4gICAgZm9yIChjb25zdCBsb2NhbGUgb2YgbG9jYWxlcykge1xuICAgICAgLy8gZW50aXR5IHNvdXJjZeydmCBkZWZhdWx0IGxvY2FsZeydgCBlbnRpdHkuanNvbuyXkOyEnCDsspjrpqztlojsnLzrr4DroZwg7Iqk7YK1XG4gICAgICBpZiAoc291cmNlID09PSBcImVudGl0eVwiICYmIGxvY2FsZSA9PT0gZGVmYXVsdExvY2FsZSkgY29udGludWU7XG5cbiAgICAgIGNvbnN0IGNlbGxWYWx1ZSA9IHZhbHVlc1tsb2NhbGVdPy50cmltKCk7XG4gICAgICBpZiAoIWNlbGxWYWx1ZSkgY29udGludWU7XG5cbiAgICAgIC8vIOq4sOyhtCBkaWN0IOuhnOuTnFxuICAgICAgY29uc3QgeyBlbnRyaWVzIH0gPSB0aGlzLmxvYWRQcm9qZWN0RGljdChsb2NhbGUpO1xuXG4gICAgICAvLyBrZXkg67OA6rK9IOyLnCDquLDsobQga2V5IOygnOqxsFxuICAgICAgaWYgKG9sZEtleSAhPT0gbmV3S2V5KSB7XG4gICAgICAgIGNvbnN0IG9sZEluZGV4ID0gZW50cmllcy5maW5kSW5kZXgoKGUpID0+IGUua2V5ID09PSBvbGRLZXkpO1xuICAgICAgICBpZiAob2xkSW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgZW50cmllcy5zcGxpY2Uob2xkSW5kZXgsIDEpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIOyDiCDqsJIg7JeF642w7J207Yq4IOuYkOuKlCDstpTqsIBcbiAgICAgIGNvbnN0IGV4aXN0aW5nSW5kZXggPSBlbnRyaWVzLmZpbmRJbmRleCgoZSkgPT4gZS5rZXkgPT09IG5ld0tleSk7XG4gICAgICBjb25zdCBuZXdFbnRyeTogRGljdEVudHJ5ID0ge1xuICAgICAgICBrZXk6IG5ld0tleSxcbiAgICAgICAgdmFsdWU6IGNlbGxWYWx1ZSxcbiAgICAgICAgaXNGdW5jdGlvbjogdGhpcy5pc0V4cHJlc3Npb25GdW5jdGlvbihjZWxsVmFsdWUpLFxuICAgICAgfTtcblxuICAgICAgaWYgKGV4aXN0aW5nSW5kZXggIT09IC0xKSB7XG4gICAgICAgIGVudHJpZXNbZXhpc3RpbmdJbmRleF0gPSBuZXdFbnRyeTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVudHJpZXMucHVzaChuZXdFbnRyeSk7XG4gICAgICB9XG5cbiAgICAgIC8vIGRpY3Qg7YyM7J28IOyggOyepVxuICAgICAgYXdhaXQgdGhpcy5zYXZlRGljdEZpbGUobG9jYWxlLCBlbnRyaWVzLCBsb2NhbGUgPT09IGRlZmF1bHRMb2NhbGUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDrlJXshZTrhIjrpqwg7ZWt66qpIOy2lOqwgFxuICAgKi9cbiAgYXN5bmMgY3JlYXRlRW50cnkocGFyYW1zOiB7IGtleTogc3RyaW5nOyB2YWx1ZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsga2V5LCB2YWx1ZXMgfSA9IHBhcmFtcztcblxuICAgIGlmICgha2V5Py50cmltKCkpIHtcbiAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLmtleVJlcXVpcmVkXCIpKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGRlZmF1bHRMb2NhbGUsIHN1cHBvcnRlZExvY2FsZXMgfSA9IHRoaXMuZ2V0STE4bkNvbmZpZygpO1xuICAgIGNvbnN0IGxvY2FsZXMgPSBzdXBwb3J0ZWRMb2NhbGVzO1xuXG4gICAgLy8g7KSR67O1IO2CpCDssrTtgaxcbiAgICBmb3IgKGNvbnN0IGxvY2FsZSBvZiBsb2NhbGVzKSB7XG4gICAgICBjb25zdCB7IGVudHJpZXMgfSA9IHRoaXMubG9hZFByb2plY3REaWN0KGxvY2FsZSk7XG4gICAgICBpZiAoZW50cmllcy5zb21lKChlKSA9PiBlLmtleSA9PT0ga2V5KSkge1xuICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihTRChcInNvbmFtdS5lcnJvci5rZXlBbHJlYWR5RXhpc3RzXCIpKGtleSkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIOqwgSBsb2NhbGXsl5Ag7IOIIO2CpCDstpTqsIBcbiAgICBmb3IgKGNvbnN0IGxvY2FsZSBvZiBsb2NhbGVzKSB7XG4gICAgICBjb25zdCBjZWxsVmFsdWUgPSB2YWx1ZXNbbG9jYWxlXT8udHJpbSgpO1xuICAgICAgaWYgKCFjZWxsVmFsdWUpIGNvbnRpbnVlO1xuXG4gICAgICBjb25zdCB7IGVudHJpZXMgfSA9IHRoaXMubG9hZFByb2plY3REaWN0KGxvY2FsZSk7XG4gICAgICBlbnRyaWVzLnB1c2goe1xuICAgICAgICBrZXksXG4gICAgICAgIHZhbHVlOiBjZWxsVmFsdWUsXG4gICAgICAgIGlzRnVuY3Rpb246IHRoaXMuaXNFeHByZXNzaW9uRnVuY3Rpb24oY2VsbFZhbHVlKSxcbiAgICAgIH0pO1xuXG4gICAgICBhd2FpdCB0aGlzLnNhdmVEaWN0RmlsZShsb2NhbGUsIGVudHJpZXMsIGxvY2FsZSA9PT0gZGVmYXVsdExvY2FsZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOuUleyFlOuEiOumrCDtla3rqqkg7IKt7KCcXG4gICAqL1xuICBhc3luYyBkZWxldGVFbnRyeShrZXk6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICgha2V5KSB7XG4gICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihTRChcInNvbmFtdS5lcnJvci5rZXlSZXF1aXJlZFwiKSk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBkZWZhdWx0TG9jYWxlLCBzdXBwb3J0ZWRMb2NhbGVzIH0gPSB0aGlzLmdldEkxOG5Db25maWcoKTtcbiAgICBjb25zdCBsb2NhbGVzID0gc3VwcG9ydGVkTG9jYWxlcztcblxuICAgIGxldCBkZWxldGVkID0gZmFsc2U7XG4gICAgZm9yIChjb25zdCBsb2NhbGUgb2YgbG9jYWxlcykge1xuICAgICAgY29uc3QgeyBlbnRyaWVzIH0gPSB0aGlzLmxvYWRQcm9qZWN0RGljdChsb2NhbGUpO1xuICAgICAgY29uc3QgaW5kZXggPSBlbnRyaWVzLmZpbmRJbmRleCgoZSkgPT4gZS5rZXkgPT09IGtleSk7XG4gICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgIGVudHJpZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgZGVsZXRlZCA9IHRydWU7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5zYXZlRGljdEZpbGUobG9jYWxlLCBlbnRyaWVzLCBsb2NhbGUgPT09IGRlZmF1bHRMb2NhbGUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghZGVsZXRlZCkge1xuICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oU0QoXCJzb25hbXUuZXJyb3Iua2V5Tm90Rm91bmRcIikoa2V5KSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOuvuOyCrOyaqSDtgqQg6rKA7IKsIChhc3QtZ3JlcCDsgqzsmqkpXG4gICAqL1xuICBhc3luYyBjaGVja1VzYWdlKGtleXM6IHN0cmluZ1tdKTogUHJvbWlzZTxVc2FnZVJlc3VsdD4ge1xuICAgIC8vIGFzdC1ncmVwIOyEpOy5mCDtmZXsnbhcbiAgICBsZXQgc2dQYXRoOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgICB0cnkge1xuICAgICAgc2dQYXRoID0gZXhlY1N5bmMoXCJ3aGljaCBzZ1wiLCB7IGVuY29kaW5nOiBcInV0Zi04XCIgfSkudHJpbSgpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgdHJ5IHtcbiAgICAgICAgc2dQYXRoID0gZXhlY1N5bmMoXCJ3aGljaCBhc3QtZ3JlcFwiLCB7IGVuY29kaW5nOiBcInV0Zi04XCIgfSkudHJpbSgpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIGFzdC1ncmVwIG5vdCBpbnN0YWxsZWRcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXNnUGF0aCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZXJyb3I6XG4gICAgICAgICAgXCJhc3QtZ3JlcOydtCDshKTsuZjrkJjslrQg7J6I7KeAIOyViuyKteuLiOuLpC4gYnJldyBpbnN0YWxsIGFzdC1ncmVwIOuYkOuKlCBucG0gaW5zdGFsbCAtZyBAYXN0LWdyZXAvY2xp66GcIOyEpOy5mO2VtOyjvOyEuOyalC5cIixcbiAgICAgICAgdW51c2VkS2V5czogW10sXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IHNlYXJjaFBhdGhzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgZW50cnkgb2YgW1wiYXBpXCIsIFwid2ViXCIsIFwiYXBwXCJdKSB7XG4gICAgICBjb25zdCBzcmNQYXRoID0gcGF0aC5qb2luKFNvbmFtdS5hcHBSb290UGF0aCwgZW50cnksIFwic3JjXCIpO1xuICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoc3JjUGF0aCkpIHtcbiAgICAgICAgc2VhcmNoUGF0aHMucHVzaChzcmNQYXRoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc2VhcmNoUGF0aHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBlcnJvcjogXCLqsoDsg4ntlaAgc3JjIOuUlOugie2GoOumrOulvCDssL7snYQg7IiYIOyXhuyKteuLiOuLpC5cIixcbiAgICAgICAgdW51c2VkS2V5czogW10sXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IHVzZWRLZXlzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICB0cnkge1xuICAgICAgLy8gYXN0LWdyZXDsnLzroZwgU0QoXCIuLi5cIikg7Yyo7YS0IOqygOyDiVxuICAgICAgLy8g7Yyo7YS0OiBTRChcIktFWVwiKSDrmJDripQgU0QoJ0tFWScpIO2Yle2DnFxuICAgICAgY29uc3QgcGF0dGVybnMgPSBbJ1NEKFwiJEtFWVwiKScsIFwiU0QoJyRLRVknKVwiXTtcblxuICAgICAgZm9yIChjb25zdCBzZWFyY2hQYXRoIG9mIHNlYXJjaFBhdGhzKSB7XG4gICAgICAgIGZvciAoY29uc3QgcGF0dGVybiBvZiBwYXR0ZXJucykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBleGVjU3luYyhgJHtzZ1BhdGh9IC0tcGF0dGVybiAnJHtwYXR0ZXJufScgLS1qc29uICR7c2VhcmNoUGF0aH1gLCB7XG4gICAgICAgICAgICAgIGVuY29kaW5nOiBcInV0Zi04XCIsXG4gICAgICAgICAgICAgIG1heEJ1ZmZlcjogNTAgKiAxMDI0ICogMTAyNCwgLy8gNTBNQlxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmIChyZXN1bHQudHJpbSgpKSB7XG4gICAgICAgICAgICAgIGNvbnN0IG1hdGNoZXMgPSBKU09OLnBhcnNlKHJlc3VsdCk7XG4gICAgICAgICAgICAgIGZvciAoY29uc3QgbWF0Y2ggb2YgbWF0Y2hlcykge1xuICAgICAgICAgICAgICAgIC8vIG1ldGFWYXJpYWJsZXMuc2luZ2xlLktFWS50ZXh07JeQ7IScIO2CpCDstpTstpxcbiAgICAgICAgICAgICAgICBjb25zdCBrZXlUZXh0ID0gbWF0Y2gubWV0YVZhcmlhYmxlcz8uc2luZ2xlPy5LRVk/LnRleHQ7XG4gICAgICAgICAgICAgICAgaWYgKGtleVRleHQpIHtcbiAgICAgICAgICAgICAgICAgIC8vIOuUsOyYtO2RnCDsoJzqsbBcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGNsZWFuS2V5ID0ga2V5VGV4dC5yZXBsYWNlKC9eW1wiJ118W1wiJ10kL2csIFwiXCIpO1xuICAgICAgICAgICAgICAgICAgdXNlZEtleXMuYWRkKGNsZWFuS2V5KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8vIO2MqO2EtCDrp6TsuZgg7JeG7Jy866m0IOyXkOufrCAo66y07IucKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBrZXlzIOykkeyXkOyEnCB1c2VkS2V5c+yXkCDsl4bripQg6rKD65Ok7J20IOuvuOyCrOyaqSDtgqRcbiAgICAgIGNvbnN0IHVudXNlZEtleXMgPSBrZXlzLmZpbHRlcigoaykgPT4gIXVzZWRLZXlzLmhhcyhrKSk7XG5cbiAgICAgIHJldHVybiB7IHVudXNlZEtleXMsIHVzZWRLZXlzQ291bnQ6IHVzZWRLZXlzLnNpemUgfTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBlcnJvcjogYOqygOyDiSDspJEg7Jik66WYIOuwnOyDnTogJHtlIGluc3RhbmNlb2YgRXJyb3IgPyBlLm1lc3NhZ2UgOiBTdHJpbmcoZSl9YCxcbiAgICAgICAgdW51c2VkS2V5czogW10sXG4gICAgICB9O1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3Qgc29uYW11RGljdGlvbmFyeSA9IG5ldyBTb25hbXVEaWN0aW9uYXJ5KCk7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7QUF5QkEsU0FBUyxVQUFVLE9BQXVCO0NBQ3hDLElBQUksU0FBUztDQUNiLElBQUksSUFBSTtBQUNSLFFBQU8sS0FBSyxHQUFHO0FBQ2IsV0FBUyxPQUFPLGFBQWEsS0FBTSxJQUFJLEdBQUksR0FBRztBQUM5QyxNQUFJLEtBQUssTUFBTSxJQUFJLEdBQUcsR0FBRzs7QUFFM0IsUUFBTzs7OztjQXpCOEI7c0JBQ2tCO3FCQUNTO2lCQUNsQjtVQUN0QjtDQTRCYixtQkFBYixNQUE4Qjs7Ozs7Ozs7OztFQVU1QixjQUFjLFVBQStCO0dBQzNDLE1BQU0sVUFBVSxHQUFHLGFBQWEsVUFBVSxRQUFRO0dBQ2xELE1BQU0sYUFBYSxHQUFHLGlCQUFpQixVQUFVLFNB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
748
+
749
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic29uYW11LWRpY3Rpb25hcnkuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2RpY3Qvc29uYW11LWRpY3Rpb25hcnkudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhlY1N5bmMgfSBmcm9tIFwiY2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcblxuaW1wb3J0IHsgV29ya2Jvb2sgfSBmcm9tIFwiQHNoZWV0a2l0L25vZGVcIjtcbmltcG9ydCB0cyBmcm9tIFwidHlwZXNjcmlwdFwiO1xuXG5pbXBvcnQgeyBTb25hbXUgfSBmcm9tIFwiLi4vYXBpL3NvbmFtdVwiO1xuaW1wb3J0IHsgRW50aXR5TWFuYWdlciB9IGZyb20gXCIuLi9lbnRpdHkvZW50aXR5LW1hbmFnZXJcIjtcbmltcG9ydCB7IEJhZFJlcXVlc3RFeGNlcHRpb24gfSBmcm9tIFwiLi4vZXhjZXB0aW9ucy9zby1leGNlcHRpb25zXCI7XG5pbXBvcnQgeyBmb3JtYXRDb2RlIH0gZnJvbSBcIi4uL3V0aWxzL2Zvcm1hdHRlclwiO1xuaW1wb3J0IHsgU0QgfSBmcm9tIFwiLi9zZFwiO1xuaW1wb3J0IHtcbiAgdHlwZSBEaWN0RW50cnksXG4gIHR5cGUgRGljdGlvbmFyeVJlc3VsdCxcbiAgdHlwZSBEaWN0aW9uYXJ5Um93LFxuICB0eXBlIEVudGl0eUtleUluZm8sXG4gIHR5cGUgSTE4bkNvbmZpZyxcbiAgdHlwZSBJbXBvcnRSZXN1bHQsXG4gIHR5cGUgVXNhZ2VSZXN1bHQsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICogMC1iYXNlZCDsu6zrn7wg7J24642x7Iqk66W8IOyXkeyFgCDsu6zrn7wg66y47J6Q66GcIOuzgO2ZmCAoMCAtPiBcIkFcIiwgMjUgLT4gXCJaXCIsIDI2IC0+IFwiQUFcIilcbiAqL1xuZnVuY3Rpb24gY29sTGV0dGVyKGluZGV4OiBudW1iZXIpOiBzdHJpbmcge1xuICBsZXQgcmVzdWx0ID0gXCJcIjtcbiAgbGV0IG4gPSBpbmRleDtcbiAgd2hpbGUgKG4gPj0gMCkge1xuICAgIHJlc3VsdCA9IFN0cmluZy5mcm9tQ2hhckNvZGUoNjUgKyAobiAlIDI2KSkgKyByZXN1bHQ7XG4gICAgbiA9IE1hdGguZmxvb3IobiAvIDI2KSAtIDE7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBTb25hbXUgRGljdGlvbmFyeSDqtIDrpqwg7YG0656Y7IqkXG4gKiBpMThuIOuUleyFlOuEiOumrOydmCBDUlVEIOuwjyBFeGNlbCBpbXBvcnQvZXhwb3J066W8IOuLtOuLue2VqeuLiOuLpC5cbiAqL1xuZXhwb3J0IGNsYXNzIFNvbmFtdURpY3Rpb25hcnkge1xuICAvKipcbiAgICogVHlwZVNjcmlwdCBDb21waWxlciBBUEnrpbwg7IKs7Jqp7ZWY7JesIGRpY3Qg7YyM7J28IO2MjOyLsVxuICAgKlxuICAgKiDsp4Dsm5Ag7Yyo7YS0OlxuICAgKiAtIGV4cG9ydCBkZWZhdWx0IHsgLi4uIH0gYXMgY29uc3Q7XG4gICAqIC0gZXhwb3J0IGRlZmF1bHQgZGVmaW5lTG9jYWxlKHsgLi4uIH0pO1xuICAgKiAtIOusuOyekOyXtCDqsJI6IFwia2V5XCI6IFwidmFsdWVcIiDrmJDripQga2V5OiBgdmFsdWVgXG4gICAqIC0g7ZWo7IiYIOqwkjogXCJrZXlcIjogKHBhcmFtOiBUeXBlKSA9PiBgdGVtcGxhdGVgXG4gICAqL1xuICBwYXJzZURpY3RGaWxlKGZpbGVQYXRoOiBzdHJpbmcpOiBEaWN0RW50cnlbXSB7XG4gICAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwgXCJ1dGYtOFwiKTtcbiAgICBjb25zdCBzb3VyY2VGaWxlID0gdHMuY3JlYXRlU291cmNlRmlsZShmaWxlUGF0aCwgY29udGVudCwgdHMuU2NyaXB0VGFyZ2V0LkxhdGVzdCwgdHJ1ZSk7XG5cbiAgICBjb25zdCBlbnRyaWVzOiBEaWN0RW50cnlbXSA9IFtdO1xuXG4gICAgdHMuZm9yRWFjaENoaWxkKHNvdXJjZUZpbGUsIChub2RlKSA9PiB7XG4gICAgICBpZiAodHMuaXNFeHBvcnRBc3NpZ25tZW50KG5vZGUpKSB7XG4gICAgICAgIGNvbnN0IG9iamVjdExpdGVyYWwgPSB0aGlzLnVud3JhcFRvT2JqZWN0TGl0ZXJhbChub2RlLmV4cHJlc3Npb24pO1xuICAgICAgICBpZiAob2JqZWN0TGl0ZXJhbCkge1xuICAgICAgICAgIHRoaXMuZXh0cmFjdEVudHJpZXNGcm9tT2JqZWN0KG9iamVjdExpdGVyYWwsIHNvdXJjZUZpbGUsIGVudHJpZXMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZW50cmllcztcbiAgfVxuXG4gIC8qKlxuICAgKiDtjIzsnbzsl5DshJwg7Yq57KCVIOydtOumhOydmCBjb25zdCDshKDslrjsnYQg7LC+7JWEIE9iamVjdExpdGVyYWwg7YyM7IuxXG4gICAqIOyYiDogY29uc3QgZW50aXR5TGFiZWxzID0geyAuLi4gfSBhcyBjb25zdDtcbiAgICovXG4gIHBhcnNlQ29uc3RPYmplY3REZWNsYXJhdGlvbihmaWxlUGF0aDogc3RyaW5nLCB2YXJOYW1lOiBzdHJpbmcpOiBEaWN0RW50cnlbXSB7XG4gICAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwgXCJ1dGYtOFwiKTtcbiAgICBjb25zdCBzb3VyY2VGaWxlID0gdHMuY3JlYXRlU291cmNlRmlsZShmaWxlUGF0aCwgY29udGVudCwgdHMuU2NyaXB0VGFyZ2V0LkxhdGVzdCwgdHJ1ZSk7XG5cbiAgICBjb25zdCBlbnRyaWVzOiBEaWN0RW50cnlbXSA9IFtdO1xuXG4gICAgdHMuZm9yRWFjaENoaWxkKHNvdXJjZUZpbGUsIChub2RlKSA9PiB7XG4gICAgICBpZiAodHMuaXNWYXJpYWJsZVN0YXRlbWVudChub2RlKSkge1xuICAgICAgICBmb3IgKGNvbnN0IGRlY2wgb2Ygbm9kZS5kZWNsYXJhdGlvbkxpc3QuZGVjbGFyYXRpb25zKSB7XG4gICAgICAgICAgaWYgKHRzLmlzSWRlbnRpZmllcihkZWNsLm5hbWUpICYmIGRlY2wubmFtZS50ZXh0ID09PSB2YXJOYW1lICYmIGRlY2wuaW5pdGlhbGl6ZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IG9iamVjdExpdGVyYWwgPSB0aGlzLnVud3JhcFRvT2JqZWN0TGl0ZXJhbChkZWNsLmluaXRpYWxpemVyKTtcbiAgICAgICAgICAgIGlmIChvYmplY3RMaXRlcmFsKSB7XG4gICAgICAgICAgICAgIHRoaXMuZXh0cmFjdEVudHJpZXNGcm9tT2JqZWN0KG9iamVjdExpdGVyYWwsIHNvdXJjZUZpbGUsIGVudHJpZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGVudHJpZXM7XG4gIH1cblxuICAvKipcbiAgICog66y47J6Q7Je07J20IO2ZlOyCtO2RnCDtlajsiJgg65iQ64qUIO2VqOyImCDtkZztmITsi53snbjsp4Ag7YyQ67OEXG4gICAqL1xuICBpc0V4cHJlc3Npb25GdW5jdGlvbihjb2RlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAvLyDruYgg66y47J6Q7Je07J2064KYIOqzteuwseunjCDsnojripQg6rK97JqwXG4gICAgaWYgKCFjb2RlLnRyaW0oKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IEFSUk9XX0ZVTkNUSU9OX1BBVFRFUk4gPSAvXlxccypcXChbXildKlxcKVxccyo9Pi87XG5cbiAgICByZXR1cm4gQVJST1dfRlVOQ1RJT05fUEFUVEVSTi50ZXN0KGNvZGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIGV4cG9ydCBkZWZhdWx0IO2RnO2YhOyLneyXkOyEnCBPYmplY3RMaXRlcmFsRXhwcmVzc2lvbiDstpTstpxcbiAgICogLSBhcyBjb25zdCDsspjrpqxcbiAgICogLSBkZWZpbmVMb2NhbGUoeyAuLi4gfSkg7Zi47LacIOyymOumrFxuICAgKi9cbiAgcHJpdmF0ZSB1bndyYXBUb09iamVjdExpdGVyYWwoZXhwcjogdHMuRXhwcmVzc2lvbik6IHRzLk9iamVjdExpdGVyYWxFeHByZXNzaW9uIHwgbnVsbCB7XG4gICAgLy8gYXMgY29uc3Qg7LKY66asXG4gICAgaWYgKHRzLmlzQXNFeHByZXNzaW9uKGV4cHIpKSB7XG4gICAgICByZXR1cm4gdGhpcy51bndyYXBUb09iamVjdExpdGVyYWwoZXhwci5leHByZXNzaW9uKTtcbiAgICB9XG4gICAgLy8g7KeB7KCRIOqwneyytCDrpqzthLDrn7RcbiAgICBpZiAodHMuaXNPYmplY3RMaXRlcmFsRXhwcmVzc2lvbihleHByKSkge1xuICAgICAgcmV0dXJuIGV4cHI7XG4gICAgfVxuICAgIC8vIGRlZmluZUxvY2FsZSh7IC4uLiB9KSDtmLjstpxcbiAgICBpZiAodHMuaXNDYWxsRXhwcmVzc2lvbihleHByKSkge1xuICAgICAgY29uc3QgZmlyc3RBcmcgPSBleHByLmFyZ3VtZW50c1swXTtcbiAgICAgIGlmIChmaXJzdEFyZyAmJiB0cy5pc09iamVjdExpdGVyYWxFeHByZXNzaW9uKGZpcnN0QXJnKSkge1xuICAgICAgICByZXR1cm4gZmlyc3RBcmc7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIE9iamVjdExpdGVyYWxFeHByZXNzaW9u7JeQ7IScIERpY3RFbnRyeSDstpTstpxcbiAgICovXG4gIHByaXZhdGUgZXh0cmFjdEVudHJpZXNGcm9tT2JqZWN0KFxuICAgIG9iamVjdExpdGVyYWw6IHRzLk9iamVjdExpdGVyYWxFeHByZXNzaW9uLFxuICAgIHNvdXJjZUZpbGU6IHRzLlNvdXJjZUZpbGUsXG4gICAgZW50cmllczogRGljdEVudHJ5W10sXG4gICk6IHZvaWQge1xuICAgIGZvciAoY29uc3QgcHJvcCBvZiBvYmplY3RMaXRlcmFsLnByb3BlcnRpZXMpIHtcbiAgICAgIGNvbnN0IGVudHJ5ID0gdGhpcy5leHRyYWN0RGljdEVudHJ5KHByb3AsIHNvdXJjZUZpbGUpO1xuICAgICAgaWYgKGVudHJ5KSB7XG4gICAgICAgIGVudHJpZXMucHVzaChlbnRyeSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFByb3BlcnR5TmFtZeyXkOyEnCDtgqQg66y47J6Q7Je0IOy2lOy2nFxuICAgKiAtIOusuOyekOyXtCDrpqzthLDrn7Q6IFwia2V5XCJcbiAgICogLSDsi53rs4TsnpA6IGtleSAodW5xdW90ZWQpXG4gICAqL1xuICBwcml2YXRlIGdldFByb3BlcnR5S2V5KG5hbWU6IHRzLlByb3BlcnR5TmFtZSk6IHN0cmluZyB8IG51bGwge1xuICAgIGlmICh0cy5pc1N0cmluZ0xpdGVyYWwobmFtZSkpIHtcbiAgICAgIHJldHVybiBuYW1lLnRleHQ7XG4gICAgfVxuICAgIGlmICh0cy5pc0lkZW50aWZpZXIobmFtZSkpIHtcbiAgICAgIHJldHVybiBuYW1lLnRleHQ7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIO2UhOuhnO2NvO2LsOyXkOyEnCBEaWN0RW50cnkg7LaU7LacXG4gICAqIC0g66y47J6Q7Je0OiDsi6TsoJwg66y47J6Q7Je0IOqwklxuICAgKiAtIO2VqOyImDog7JuQ67O4IOyGjOyKpCAo7Jes65+sIOykhOydgCDtlZwg7KSE66GcIOygleq3nO2ZlClcbiAgICovXG4gIHByaXZhdGUgZXh0cmFjdERpY3RFbnRyeShcbiAgICBwcm9wOiB0cy5PYmplY3RMaXRlcmFsRWxlbWVudExpa2UsXG4gICAgc291cmNlRmlsZTogdHMuU291cmNlRmlsZSxcbiAgKTogRGljdEVudHJ5IHwgbnVsbCB7XG4gICAgaWYgKCF0cy5pc1Byb3BlcnR5QXNzaWdubWVudChwcm9wKSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3Qga2V5ID0gdGhpcy5nZXRQcm9wZXJ0eUtleShwcm9wLm5hbWUpO1xuICAgIGlmICgha2V5KSByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IGluaXQgPSBwcm9wLmluaXRpYWxpemVyO1xuXG4gICAgLy8g7ZmU7IK07ZGcIO2VqOyImFxuICAgIGlmICh0cy5pc0Fycm93RnVuY3Rpb24oaW5pdCkpIHtcbiAgICAgIGNvbnN0IGZ1bmNUZXh0ID0gaW5pdC5nZXRUZXh0KHNvdXJjZUZpbGUpO1xuICAgICAgY29uc3Qgbm9ybWFsaXplZCA9IGZ1bmNUZXh0LnJlcGxhY2UoL1xccypcXG5cXHMqL2csIFwiIFwiKS50cmltKCk7XG4gICAgICByZXR1cm4geyBrZXksIHZhbHVlOiBub3JtYWxpemVkLCBpc0Z1bmN0aW9uOiB0cnVlIH07XG4gICAgfVxuXG4gICAgLy8g66y47J6Q7Je0IOumrO2EsOuftFxuICAgIGlmICh0cy5pc1N0cmluZ0xpdGVyYWwoaW5pdCkpIHtcbiAgICAgIHJldHVybiB7IGtleSwgdmFsdWU6IGluaXQudGV4dCwgaXNGdW5jdGlvbjogZmFsc2UgfTtcbiAgICB9XG5cbiAgICAvLyDthZztlIzrpr8g66as7YSw65+0ICjrs4DsiJgg7JeG7J2MKVxuICAgIGlmICh0cy5pc05vU3Vic3RpdHV0aW9uVGVtcGxhdGVMaXRlcmFsKGluaXQpKSB7XG4gICAgICByZXR1cm4geyBrZXksIHZhbHVlOiBpbml0LnRleHQsIGlzRnVuY3Rpb246IGZhbHNlIH07XG4gICAgfVxuXG4gICAgLy8g6riw7YOAICjsmIg6IO2VqOyImCDtkZztmITsi50pXG4gICAgcmV0dXJuIHtcbiAgICAgIGtleSxcbiAgICAgIHZhbHVlOiBpbml0LmdldFRleHQoc291cmNlRmlsZSksXG4gICAgICBpc0Z1bmN0aW9uOiB0cy5pc0Z1bmN0aW9uRXhwcmVzc2lvbihpbml0KSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIO2UhOuhnOygne2KuOydmCBpMThuIGRpY3Qg7YyM7J28IOqyveuhnOulvCDrsJjtmZjtlanri4jri6QuXG4gICAqIEBwYXJhbSBsb2NhbGUgLSDroZzsvIDsnbwgKGtvLCBlbiDrk7EpXG4gICAqIEBwYXJhbSB0YXJnZXQgLSDtg4Dqsp8g65SU66CJ7Yag66asIChhcGksIHdlYiwgYXBwKVxuICAgKi9cbiAgZ2V0UHJvamVjdERpY3RQYXRoKGxvY2FsZTogc3RyaW5nLCB0YXJnZXQ6IFwiYXBpXCIgfCBcIndlYlwiIHwgXCJhcHBcIiA9IFwiYXBpXCIpOiBzdHJpbmcge1xuICAgIGNvbnN0IGRpciA9IHRhcmdldCA9PT0gXCJhcGlcIiA/IFNvbmFtdS5jb25maWcuYXBpLmRpciA6IHRhcmdldDtcbiAgICByZXR1cm4gcGF0aC5qb2luKFNvbmFtdS5hcHBSb290UGF0aCwgZGlyLCBcInNyY1wiLCBcImkxOG5cIiwgYCR7bG9jYWxlfS50c2ApO1xuICB9XG5cbiAgLyoqXG4gICAqIHNvbmFtdSDrgrTsnqUgZGljdCDtjIzsnbwg6rK966Gc66W8IOuwmO2ZmO2VqeuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgZ2V0U29uYW11RGljdFBhdGgobG9jYWxlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHBhY2thZ2VSb290ID0gcGF0aC5yZXNvbHZlKGltcG9ydC5tZXRhLmRpcm5hbWUsIFwiLi5cIiwgXCIuLlwiKTtcbiAgICByZXR1cm4gcGF0aC5qb2luKHBhY2thZ2VSb290LCBcInNyY1wiLCBcImRpY3RcIiwgYCR7bG9jYWxlfS50c2ApO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VhOyalO2VnCBkaWN0IO2CpOqwgCDtlITroZzsoJ3tirjsl5Ag7KG07J6s7ZWY64qU7KeAIO2ZleyduO2VmOqzoCwg7JeG7Jy866m0IOy2lOqwgO2VqeuLiOuLpC5cbiAgICogZGVmYXVsdExvY2FsZeyXkOunjCDstpTqsIDtlZjrqbAsIOuLpOuluCBsb2NhbGXsnYAg7IKs7Jqp7J6Q6rCAIOyngeygkSDrsojsl63tlbTslbwg7ZWp64uI64ukLlxuICAgKlxuICAgKiBAcGFyYW0gcmVxdWlyZWRLZXlzIC0g7ZWE7JqU7ZWcIO2CpCDrqqnroZ1cbiAgICogQHBhcmFtIHRhcmdldCAtIO2DgOqynyDrlJTroInthqDrpqwgKGFwaSwgd2ViLCBhcHApXG4gICAqIEByZXR1cm5zIOy2lOqwgOuQnCDtgqQg66qp66GdXG4gICAqL1xuICBhc3luYyBlbnN1cmVEaWN0S2V5cyhcbiAgICByZXF1aXJlZEtleXM6IHN0cmluZ1tdLFxuICAgIHRhcmdldDogXCJhcGlcIiB8IFwid2ViXCIgfCBcImFwcFwiID0gXCJhcGlcIixcbiAgKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIGNvbnN0IHsgZGVmYXVsdExvY2FsZSB9ID0gU29uYW11LmNvbmZpZy5pMThuO1xuICAgIGNvbnN0IHByb2plY3REaWN0UGF0aCA9IHRoaXMuZ2V0UHJvamVjdERpY3RQYXRoKGRlZmF1bHRMb2NhbGUsIHRhcmdldCk7XG5cbiAgICAvLyDtlITroZzsoJ3tirggZGljdCDtjIzsnbzsnbQg7JeG7Jy866m0IOyVhOustOqyg+uPhCDtlZjsp4Ag7JWK7J2MXG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKHByb2plY3REaWN0UGF0aCkpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICAvLyDtlITroZzsoJ3tirggZGljdOyXkOyEnCDquLDsobQg7YKkIO2MjOyLsVxuICAgIGNvbnN0IHByb2plY3RFbnRyaWVzID0gdGhpcy5wYXJzZURpY3RGaWxlKHByb2plY3REaWN0UGF0aCk7XG4gICAgY29uc3QgZXhpc3RpbmdLZXlzID0gbmV3IFNldChwcm9qZWN0RW50cmllcy5tYXAoKGUpID0+IGUua2V5KSk7XG5cbiAgICAvLyDriITrnb3rkJwg7YKkIOywvuq4sFxuICAgIGNvbnN0IG1pc3NpbmdLZXlzID0gcmVxdWlyZWRLZXlzLmZpbHRlcigoa2V5KSA9PiAhZXhpc3RpbmdLZXlzLmhhcyhrZXkpKTtcblxuICAgIGlmIChtaXNzaW5nS2V5cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICAvLyBzb25hbXUgZGljdOyXkOyEnCDquLDrs7jqsJIg6rCA7KC47Jik6riwXG4gICAgY29uc3Qgc29uYW11RGljdFBhdGggPSB0aGlzLmdldFNvbmFtdURpY3RQYXRoKGRlZmF1bHRMb2NhbGUpO1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhzb25hbXVEaWN0UGF0aCkpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBjb25zdCBzb25hbXVFbnRyaWVzID0gdGhpcy5wYXJzZURpY3RGaWxlKHNvbmFtdURpY3RQYXRoKTtcbiAgICBjb25zdCBzb25hbXVEaWN0ID0gbmV3IE1hcChzb25hbXVFbnRyaWVzLm1hcCgoZSkgPT4gW2Uua2V5LCBlXSkpO1xuXG4gICAgLy8g7LaU6rCA7ZWgIOyXlO2KuOumrCDsg53shLFcbiAgICBjb25zdCBlbnRyaWVzVG9BZGQgPSBtaXNzaW5nS2V5c1xuICAgICAgLm1hcCgoa2V5KSA9PiBzb25hbXVEaWN0LmdldChrZXkpKVxuICAgICAgLmZpbHRlcigoZW50cnkpOiBlbnRyeSBpcyBOb25OdWxsYWJsZTx0eXBlb2YgZW50cnk+ID0+IGVudHJ5ICE9PSB1bmRlZmluZWQpO1xuXG4gICAgaWYgKGVudHJpZXNUb0FkZC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICAvLyDtlITroZzsoJ3tirggZGljdCDtjIzsnbzsl5Ag7LaU6rCAXG4gICAgYXdhaXQgdGhpcy5hcHBlbmRFbnRyaWVzVG9EaWN0RmlsZShwcm9qZWN0RGljdFBhdGgsIGVudHJpZXNUb0FkZCwgZGVmYXVsdExvY2FsZSwgdHJ1ZSk7XG5cbiAgICByZXR1cm4gZW50cmllc1RvQWRkLm1hcCgoZSkgPT4gZS5rZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIGRpY3Qg7YyM7J287JeQIOyXlO2KuOumrOulvCDstpTqsIDtlanri4jri6QuXG4gICAqIOq4sOyhtCDtjIzsnbzsnYQg7YyM7Iux7ZWY6rOgLCDsg4gg7JeU7Yq466as66W8IOy2lOqwgO2VnCDrkqQsIOyghOyytCDtjIzsnbzsnYQg7J6s7IOd7ISx7ZWp64uI64ukLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBhcHBlbmRFbnRyaWVzVG9EaWN0RmlsZShcbiAgICBmaWxlUGF0aDogc3RyaW5nLFxuICAgIGVudHJpZXM6IERpY3RFbnRyeVtdLFxuICAgIGxvY2FsZTogc3RyaW5nLFxuICAgIGlzRGVmYXVsdExvY2FsZTogYm9vbGVhbixcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8g6riw7KG0IGVudHJpZXMg7YyM7IuxXG4gICAgY29uc3QgZXhpc3RpbmdFbnRyaWVzID0gdGhpcy5wYXJzZURpY3RGaWxlKGZpbGVQYXRoKTtcblxuICAgIC8vIOyDiCBlbnRyaWVzIOy2lOqwgFxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgICAgZXhpc3RpbmdFbnRyaWVzLnB1c2goZW50cnkpO1xuICAgIH1cblxuICAgIC8vIO2MjOydvCDsnqzsg53shLFcbiAgICBjb25zdCBjb250ZW50ID0gdGhpcy5nZW5lcmF0ZVByb2plY3REaWN0KGxvY2FsZSwgZXhpc3RpbmdFbnRyaWVzLCBpc0RlZmF1bHRMb2NhbGUpO1xuICAgIGNvbnN0IGZvcm1hdHRlZCA9IGF3YWl0IGZvcm1hdENvZGUoY29udGVudCwgZmlsZVBhdGgpO1xuICAgIGZzLndyaXRlRmlsZVN5bmMoZmlsZVBhdGgsIGZvcm1hdHRlZCwgXCJ1dGYtOFwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDtlajsiJgg6rCS65Ok7JeQ7IScIOyCrOyaqeuQmOuKlCDtl6ztjbwg7ZWo7IiY66W8IOqwkOyngO2VqeuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgZGV0ZWN0VXNlZEhlbHBlcnMoZW50cmllczogRGljdEVudHJ5W10pOiB7XG4gICAgaGVscGVyczogc3RyaW5nW107XG4gICAgdXNlc0Zvcm1hdDogYm9vbGVhbjtcbiAgfSB7XG4gICAgY29uc3QgZnVuY3Rpb25FbnRyaWVzID0gZW50cmllcy5maWx0ZXIoKGUpID0+IGUuaXNGdW5jdGlvbik7XG4gICAgY29uc3QgaGVscGVyczogc3RyaW5nW10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgaGVscGVyIG9mIFtcInBsdXJhbFwiLCBcImpvc2FcIl0pIHtcbiAgICAgIC8vIO2VqOyImOuqheydtCDri6jslrQg6rK96rOE66GcIOyCrOyaqeuQmOuKlOyngCDtmZXsnbggKOyYiDogcGx1cmFsKCDrmJDripQgcGx1cmFsLClcbiAgICAgIGNvbnN0IHBhdHRlcm4gPSBuZXcgUmVnRXhwKGBcXFxcYiR7aGVscGVyfVxcXFxzKlxcXFwoYCk7XG4gICAgICBpZiAoZnVuY3Rpb25FbnRyaWVzLnNvbWUoKGUpID0+IHBhdHRlcm4udGVzdChlLnZhbHVlKSkpIHtcbiAgICAgICAgaGVscGVycy5wdXNoKGhlbHBlcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gZm9ybWF0IOyCrOyaqSDsl6zrtoAg67OE64+EIOqwkOyngCAoZm9ybWF0Lm51bWJlciguLi4pLCBmb3JtYXQuZGF0ZSguLi4pIOuTsSlcbiAgICBjb25zdCBmb3JtYXRQYXR0ZXJuID0gL1xcYmZvcm1hdFxcLlxcdytcXHMqXFwoLztcbiAgICBjb25zdCB1c2VzRm9ybWF0ID0gZnVuY3Rpb25FbnRyaWVzLnNvbWUoKGUpID0+IGZvcm1hdFBhdHRlcm4udGVzdChlLnZhbHVlKSk7XG5cbiAgICByZXR1cm4geyBoZWxwZXJzLCB1c2VzRm9ybWF0IH07XG4gIH1cblxuICAvKipcbiAgICogUHJvamVjdCBkaWN0IO2MjOydvCDsg53shLFcbiAgICovXG4gIGdlbmVyYXRlUHJvamVjdERpY3QobG9jYWxlOiBzdHJpbmcsIGVudHJpZXM6IERpY3RFbnRyeVtdLCBpc0RlZmF1bHRMb2NhbGU6IGJvb2xlYW4pOiBzdHJpbmcge1xuICAgIC8vIGtleSDslYztjIzrsrMg7IicIOygleugrFxuICAgIGNvbnN0IHNvcnRlZCA9IFsuLi5lbnRyaWVzXS50b1NvcnRlZCgoYSwgYikgPT4gYS5rZXkubG9jYWxlQ29tcGFyZShiLmtleSkpO1xuXG4gICAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW107XG5cbiAgICAvLyDtlajsiJgg6rCS7JeQ7IScIOyCrOyaqeuQmOuKlCDtl6ztjbwg7ZWo7IiYIOqwkOyngFxuICAgIGNvbnN0IHsgaGVscGVycywgdXNlc0Zvcm1hdCB9ID0gdGhpcy5kZXRlY3RVc2VkSGVscGVycyhlbnRyaWVzKTtcblxuICAgIC8vIO2XrO2NvCDtlajsiJggaW1wb3J0IOy2lOqwgFxuICAgIGNvbnN0IGltcG9ydHMgPSBbLi4uaGVscGVyc107XG4gICAgaWYgKHVzZXNGb3JtYXQpIHtcbiAgICAgIGltcG9ydHMucHVzaChcImNyZWF0ZUZvcm1hdFwiKTtcbiAgICB9XG4gICAgaWYgKGltcG9ydHMubGVuZ3RoID4gMCkge1xuICAgICAgbGluZXMucHVzaChgaW1wb3J0IHsgJHtpbXBvcnRzLmpvaW4oXCIsIFwiKX0gfSBmcm9tIFwic29uYW11L2RpY3RcIjtgKTtcbiAgICB9XG5cbiAgICBpZiAoIWlzRGVmYXVsdExvY2FsZSkge1xuICAgICAgbGluZXMucHVzaCgnaW1wb3J0IHsgZGVmaW5lTG9jYWxlIH0gZnJvbSBcIi4vc2QuZ2VuZXJhdGVkXCI7Jyk7XG4gICAgfVxuXG4gICAgaWYgKGltcG9ydHMubGVuZ3RoID4gMCB8fCAhaXNEZWZhdWx0TG9jYWxlKSB7XG4gICAgICBsaW5lcy5wdXNoKFwiXCIpO1xuICAgIH1cblxuICAgIC8vIGZvcm1hdCDsgqzsmqkg7IucIGNyZWF0ZUZvcm1hdCDtmLjstpwg7LaU6rCAXG4gICAgaWYgKHVzZXNGb3JtYXQpIHtcbiAgICAgIGxpbmVzLnB1c2goYGNvbnN0IGZvcm1hdCA9IGNyZWF0ZUZvcm1hdChcIiR7bG9jYWxlfVwiKTtgKTtcbiAgICAgIGxpbmVzLnB1c2goXCJcIik7XG4gICAgfVxuXG4gICAgbGluZXMucHVzaChcIi8qKlwiKTtcbiAgICBsaW5lcy5wdXNoKGAgKiBQcm9qZWN0ICR7bG9jYWxlLnRvVXBwZXJDYXNlKCl9IERpY3Rpb25hcnlgKTtcbiAgICBsaW5lcy5wdXNoKFwiICovXCIpO1xuXG4gICAgaWYgKGlzRGVmYXVsdExvY2FsZSkge1xuICAgICAgbGluZXMucHVzaChcImV4cG9ydCBkZWZhdWx0IHtcIik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxpbmVzLnB1c2goXCJleHBvcnQgZGVmYXVsdCBkZWZpbmVMb2NhbGUoe1wiKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIHNvcnRlZCkge1xuICAgICAgaWYgKGVudHJ5LmlzRnVuY3Rpb24pIHtcbiAgICAgICAgLy8g7ZWo7IiY7J24IOqyveyasDog7JuQ7ZiVIOq3uOuMgOuhnCDstpzroKVcbiAgICAgICAgbGluZXMucHVzaChgICBcIiR7ZW50cnkua2V5fVwiOiAke2VudHJ5LnZhbHVlfSxgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxpbmVzLnB1c2goYCAgXCIke2VudHJ5LmtleX1cIjogJHtKU09OLnN0cmluZ2lmeShlbnRyeS52YWx1ZSl9LGApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpc0RlZmF1bHRMb2NhbGUpIHtcbiAgICAgIGxpbmVzLnB1c2goXCJ9IGFzIGNvbnN0O1wiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGluZXMucHVzaChcIn0pO1wiKTtcbiAgICB9XG4gICAgbGluZXMucHVzaChcIlwiKTtcblxuICAgIHJldHVybiBsaW5lcy5qb2luKFwiXFxuXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIGkxOG4g7ISk7KCV7J2EIOqwgOyguOyYteuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgZ2V0STE4bkNvbmZpZygpOiBJMThuQ29uZmlnIHtcbiAgICByZXR1cm4gU29uYW11LmNvbmZpZy5pMThuO1xuICB9XG5cbiAgLyoqXG4gICAqIGkxOG4g65SU66CJ7Yag66asIOqyveuhnOulvCDrsJjtmZjtlZjqs6AsIOyXhuycvOuptCDsg53shLHtlanri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGVuc3VyZUkxOG5EaXIoKTogc3RyaW5nIHtcbiAgICBjb25zdCBpMThuRGlyID0gcGF0aC5qb2luKFNvbmFtdS5hcGlSb290UGF0aCwgXCJzcmNcIiwgXCJpMThuXCIpO1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhpMThuRGlyKSkge1xuICAgICAgZnMubWtkaXJTeW5jKGkxOG5EaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIH1cbiAgICByZXR1cm4gaTE4bkRpcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBkaWN0IO2MjOydvOydhCDsoIDsnqXtlanri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHNhdmVEaWN0RmlsZShcbiAgICBsb2NhbGU6IHN0cmluZyxcbiAgICBlbnRyaWVzOiBEaWN0RW50cnlbXSxcbiAgICBpc0RlZmF1bHRMb2NhbGU6IGJvb2xlYW4sXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGkxOG5EaXIgPSB0aGlzLmVuc3VyZUkxOG5EaXIoKTtcbiAgICBjb25zdCBkaWN0UGF0aCA9IHBhdGguam9pbihpMThuRGlyLCBgJHtsb2NhbGV9LnRzYCk7XG4gICAgY29uc3QgY29udGVudCA9IHRoaXMuZ2VuZXJhdGVQcm9qZWN0RGljdChsb2NhbGUsIGVudHJpZXMsIGlzRGVmYXVsdExvY2FsZSk7XG4gICAgY29uc3QgZm9ybWF0dGVkID0gYXdhaXQgZm9ybWF0Q29kZShjb250ZW50LCBkaWN0UGF0aCk7XG4gICAgZnMud3JpdGVGaWxlU3luYyhkaWN0UGF0aCwgZm9ybWF0dGVkLCBcInV0Zi04XCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIGkxOG4ga2V566W8IO2MjOyLse2VmOyXrCBlbnRpdHkg6rSA66CoIOygleuztCDstpTstpxcbiAgICovXG4gIHBhcnNlRW50aXR5S2V5KGtleTogc3RyaW5nKTogRW50aXR5S2V5SW5mbyB7XG4gICAgLy8gZW50aXR5LntFbnRpdHlJZH0gKGxpc3QsIGNyZWF0ZSwgZWRpdCDsoJzsmbgpXG4gICAgY29uc3QgZW50aXR5VGl0bGVNYXRjaCA9IGtleS5tYXRjaCgvXmVudGl0eVxcLihbQS1aXVthLXpBLVowLTldKikkLyk7XG4gICAgaWYgKFxuICAgICAgZW50aXR5VGl0bGVNYXRjaCAmJlxuICAgICAgIWtleS5pbmNsdWRlcyhcIi5saXN0XCIpICYmXG4gICAgICAha2V5LmluY2x1ZGVzKFwiLmNyZWF0ZVwiKSAmJlxuICAgICAgIWtleS5pbmNsdWRlcyhcIi5lZGl0XCIpXG4gICAgKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBcImVudGl0eVRpdGxlXCIsIGVudGl0eUlkOiBlbnRpdHlUaXRsZU1hdGNoWzFdIH07XG4gICAgfVxuXG4gICAgLy8gZW50aXR5LntFbnRpdHlJZH0ue3Byb3BOYW1lfVxuICAgIGNvbnN0IHByb3BEZXNjTWF0Y2ggPSBrZXkubWF0Y2goL15lbnRpdHlcXC4oW0EtWl1bYS16QS1aMC05XSopXFwuKFthLXpfXVthLXowLTlfXSopJC8pO1xuICAgIGlmIChwcm9wRGVzY01hdGNoKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBcInByb3BEZXNjXCIsIGVudGl0eUlkOiBwcm9wRGVzY01hdGNoWzFdLCBwcm9wTmFtZTogcHJvcERlc2NNYXRjaFsyXSB9O1xuICAgIH1cblxuICAgIC8vIGVudW0ue0VudW1JZH0ue3ZhbHVlfVxuICAgIGNvbnN0IGVudW1MYWJlbE1hdGNoID0ga2V5Lm1hdGNoKC9eZW51bVxcLihbQS1aXVthLXpBLVowLTldKilcXC4oLispJC8pO1xuICAgIGlmIChlbnVtTGFiZWxNYXRjaCkge1xuICAgICAgcmV0dXJuIHsgdHlwZTogXCJlbnVtTGFiZWxcIiwgZW51bUlkOiBlbnVtTGFiZWxNYXRjaFsxXSwgZW51bVZhbHVlOiBlbnVtTGFiZWxNYXRjaFsyXSB9O1xuICAgIH1cblxuICAgIHJldHVybiB7IHR5cGU6IFwib3RoZXJcIiB9O1xuICB9XG5cbiAgLyoqXG4gICAqIGVudGl0eSBrZXnsl5Ag64yA7ZW0IGVudGl0eS5qc29uIOyXheuNsOydtO2KuCDsiJjtlolcbiAgICogQHJldHVybnMg7JeF642w7J207Yq4IOyXrOu2gFxuICAgKi9cbiAgYXN5bmMgdXBkYXRlRW50aXR5QnlLZXkoa2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBrZXlJbmZvID0gdGhpcy5wYXJzZUVudGl0eUtleShrZXkpO1xuXG4gICAgc3dpdGNoIChrZXlJbmZvLnR5cGUpIHtcbiAgICAgIGNhc2UgXCJlbnRpdHlUaXRsZVwiOiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoa2V5SW5mby5lbnRpdHlJZCk7XG4gICAgICAgICAgaWYgKGVudGl0eS50aXRsZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgICAgIGVudGl0eS50aXRsZSA9IHZhbHVlO1xuICAgICAgICAgICAgYXdhaXQgZW50aXR5LnNhdmUoKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgLy8gZW50aXR5IG5vdCBmb3VuZFxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgY2FzZSBcInByb3BEZXNjXCI6IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChrZXlJbmZvLmVudGl0eUlkKTtcbiAgICAgICAgICBjb25zdCBwcm9wSW5kZXggPSBlbnRpdHkucHJvcHMuZmluZEluZGV4KChwKSA9PiBwLm5hbWUgPT09IGtleUluZm8ucHJvcE5hbWUpO1xuICAgICAgICAgIGlmIChwcm9wSW5kZXggIT09IC0xICYmIGVudGl0eS5wcm9wc1twcm9wSW5kZXhdLmRlc2MgIT09IHZhbHVlKSB7XG4gICAgICAgICAgICBlbnRpdHkucHJvcHNbcHJvcEluZGV4XS5kZXNjID0gdmFsdWU7XG4gICAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAvLyBlbnRpdHkgbm90IGZvdW5kXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBjYXNlIFwiZW51bUxhYmVsXCI6IHtcbiAgICAgICAgZm9yIChjb25zdCBlbnRpdHlJZCBvZiBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpKSB7XG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgIGlmIChlbnRpdHkuZW51bUxhYmVsc1trZXlJbmZvLmVudW1JZF0pIHtcbiAgICAgICAgICAgIGlmIChlbnRpdHkuZW51bUxhYmVsc1trZXlJbmZvLmVudW1JZF1ba2V5SW5mby5lbnVtVmFsdWVdICE9PSB2YWx1ZSkge1xuICAgICAgICAgICAgICBlbnRpdHkuZW51bUxhYmVsc1trZXlJbmZvLmVudW1JZF1ba2V5SW5mby5lbnVtVmFsdWVdID0gdmFsdWU7XG4gICAgICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBzZC5nZW5lcmF0ZWQudHPsl5DshJwgZW50aXR5IGxhYmVscyDstpTstpxcbiAgICogZW50aXR5Lmpzb27sl5DshJwg6rSA66as65CY64qUIOqwkuunjCDtj6ztlaggKC5saXN0LCAuY3JlYXRlLCAuZWRpdCDsoJzsmbgpXG4gICAqL1xuICBleHRyYWN0RW50aXR5TGFiZWxzKCk6IERpY3RFbnRyeVtdIHtcbiAgICBjb25zdCBzZFBhdGggPSBwYXRoLmpvaW4oU29uYW11LmFwaVJvb3RQYXRoLCBcInNyY1wiLCBcImkxOG5cIiwgXCJzZC5nZW5lcmF0ZWQudHNcIik7XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKHNkUGF0aCkpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5wYXJzZUNvbnN0T2JqZWN0RGVjbGFyYXRpb24oc2RQYXRoLCBcImVudGl0eUxhYmVsc1wiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBzZC5nZW5lcmF0ZWQudHPsl5DshJwgcmMta2V5cyDstpTstpxcbiAgICogcmVhY3QtY29tcG9uZW50c+yXkOyEnCDqtIDrpqzrkJjripQgaTE4biDtgqTrk6RcbiAgICogQHBhcmFtIGxvY2FsZSAtIOuhnOy8gOydvCAoa28sIGVuIOuTsSlcbiAgICovXG4gIGV4dHJhY3RSQ0tleXMobG9jYWxlOiBzdHJpbmcpOiBEaWN0RW50cnlbXSB7XG4gICAgY29uc3Qgc2RQYXRoID0gcGF0aC5qb2luKFNvbmFtdS5hcGlSb290UGF0aCwgXCJzcmNcIiwgXCJpMThuXCIsIFwic2QuZ2VuZXJhdGVkLnRzXCIpO1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhzZFBhdGgpKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgLy8gbG9jYWxl67OEIOuzgOyImOuqhSDrp6TtlZEgKHNkLnRlbXBsYXRlLnRz7J2YIGdldFJDS2V5c1Zhck5hbWXqs7wg64+Z7J28KVxuICAgIGNvbnN0IHZhck5hbWUgPSAoKCkgPT4ge1xuICAgICAgaWYgKGxvY2FsZSA9PT0gXCJrb1wiKSByZXR1cm4gXCJyY0tleXNLb1wiO1xuICAgICAgaWYgKGxvY2FsZSA9PT0gXCJlblwiKSByZXR1cm4gXCJyY0tleXNFblwiO1xuICAgICAgLy8g64uk66W4IGxvY2FsZeydgCBlbuydhCBmYWxsYmFja+ycvOuhnCDsgqzsmqlcbiAgICAgIHJldHVybiBcInJjS2V5c0VuXCI7XG4gICAgfSkoKTtcblxuICAgIHJldHVybiB0aGlzLnBhcnNlQ29uc3RPYmplY3REZWNsYXJhdGlvbihzZFBhdGgsIHZhck5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByb2plY3QgZGljdCDtjIzsnbwoW2xvY2FsZV0udHMp7JeQ7IScIOuUleyFlOuEiOumrCDroZzrk5xcbiAgICovXG4gIGxvYWRQcm9qZWN0RGljdChsb2NhbGU6IHN0cmluZyk6IHsgZW50cmllczogRGljdEVudHJ5W10gfSB7XG4gICAgY29uc3QgZGljdFBhdGggPSBwYXRoLmpvaW4oU29uYW11LmFwaVJvb3RQYXRoLCBcInNyY1wiLCBcImkxOG5cIiwgYCR7bG9jYWxlfS50c2ApO1xuICAgIGlmICghZnMuZXhpc3RzU3luYyhkaWN0UGF0aCkpIHtcbiAgICAgIHJldHVybiB7IGVudHJpZXM6IFtdIH07XG4gICAgfVxuICAgIHJldHVybiB7IGVudHJpZXM6IHRoaXMucGFyc2VEaWN0RmlsZShkaWN0UGF0aCkgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDrlJXshZTrhIjrpqwg642w7J207YSwIOyImOynkSAoc29uYW11ICsgZW50aXR5ICsgcHJvamVjdClcbiAgICovXG4gIGFzeW5jIGNvbGxlY3REaWN0aW9uYXJ5KCk6IFByb21pc2U8RGljdGlvbmFyeVJlc3VsdD4ge1xuICAgIGNvbnN0IHsgZGVmYXVsdExvY2FsZSwgc3VwcG9ydGVkTG9jYWxlcyB9ID0gdGhpcy5nZXRJMThuQ29uZmlnKCk7XG4gICAgY29uc3QgbG9jYWxlcyA9IHN1cHBvcnRlZExvY2FsZXM7XG5cbiAgICBjb25zdCByb3dzOiBEaWN0aW9uYXJ5Um93W10gPSBbXTtcbiAgICBjb25zdCByb3dNYXAgPSBuZXcgTWFwPHN0cmluZywgRGljdGlvbmFyeVJvdz4oKTtcblxuICAgIC8vIDEuIFJDIEtleXMgKHNvbmFtdSBzb3VyY2UsIOqwgSBsb2NhbGXrs4QpXG4gICAgZm9yIChjb25zdCBsb2NhbGUgb2YgbG9jYWxlcykge1xuICAgICAgY29uc3QgcmNLZXlzID0gdGhpcy5leHRyYWN0UkNLZXlzKGxvY2FsZSk7XG4gICAgICBmb3IgKGNvbnN0IHJjS2V5IG9mIHJjS2V5cykge1xuICAgICAgICBsZXQgcm93ID0gcm93TWFwLmdldChyY0tleS5rZXkpO1xuICAgICAgICBpZiAoIXJvdykge1xuICAgICAgICAgIHJvdyA9IHtcbiAgICAgICAgICAgIGtleTogcmNLZXkua2V5LFxuICAgICAgICAgICAgc291cmNlOiBcInNvbmFtdVwiLFxuICAgICAgICAgICAgaXNGdW5jdGlvbjogcmNLZXkuaXNGdW5jdGlvbiA/PyBmYWxzZSxcbiAgICAgICAgICB9O1xuICAgICAgICAgIHJvd01hcC5zZXQocmNLZXkua2V5LCByb3cpO1xuICAgICAgICB9XG4gICAgICAgIHJvd1tsb2NhbGVdID0gcmNLZXkudmFsdWU7XG4gICAgICAgIGlmIChyY0tleS5pc0Z1bmN0aW9uKSB7XG4gICAgICAgICAgcm93LmlzRnVuY3Rpb24gPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gMi4gRW50aXR5IGxhYmVscyAoZGVmYXVsdCBsb2NhbGUg6riw7KSAKVxuICAgIGNvbnN0IGVudGl0eUxhYmVscyA9IHRoaXMuZXh0cmFjdEVudGl0eUxhYmVscygpO1xuICAgIGZvciAoY29uc3QgbGFiZWwgb2YgZW50aXR5TGFiZWxzKSB7XG4gICAgICBjb25zdCByb3c6IERpY3Rpb25hcnlSb3cgPSB7XG4gICAgICAgIGtleTogbGFiZWwua2V5LFxuICAgICAgICBzb3VyY2U6IFwiZW50aXR5XCIsXG4gICAgICAgIGlzRnVuY3Rpb246IGxhYmVsLmlzRnVuY3Rpb24gPz8gZmFsc2UsXG4gICAgICAgIFtkZWZhdWx0TG9jYWxlXTogbGFiZWwudmFsdWUsXG4gICAgICB9O1xuICAgICAgcm93TWFwLnNldChsYWJlbC5rZXksIHJvdyk7XG4gICAgfVxuXG4gICAgLy8gMy4gUHJvamVjdCBkaWN0ICjqsIEgbG9jYWxl67OEKVxuICAgIGZvciAoY29uc3QgbG9jYWxlIG9mIGxvY2FsZXMpIHtcbiAgICAgIGNvbnN0IHsgZW50cmllcyB9ID0gdGhpcy5sb2FkUHJvamVjdERpY3QobG9jYWxlKTtcbiAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgICAgICBjb25zdCBleGlzdGluZyA9IHJvd01hcC5nZXQoZW50cnkua2V5KTtcbiAgICAgICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICAgICAgLy8gc29uYW11LCBlbnRpdHkgc291cmNl6rCAIOyeiOycvOuptCDtlbTri7kgbG9jYWxlIOqwkuunjCDstpTqsIBcbiAgICAgICAgICBleGlzdGluZ1tsb2NhbGVdID0gZW50cnkudmFsdWU7XG4gICAgICAgICAgaWYgKGVudHJ5LmlzRnVuY3Rpb24pIHtcbiAgICAgICAgICAgIGV4aXN0aW5nLmlzRnVuY3Rpb24gPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBwcm9qZWN0IHNvdXJjZeuhnCDsg4jroZwg7LaU6rCAXG4gICAgICAgICAgbGV0IHJvdyA9IHJvd01hcC5nZXQoZW50cnkua2V5KTtcbiAgICAgICAgICBpZiAoIXJvdykge1xuICAgICAgICAgICAgcm93ID0ge1xuICAgICAgICAgICAgICBrZXk6IGVudHJ5LmtleSxcbiAgICAgICAgICAgICAgc291cmNlOiBcInByb2plY3RcIixcbiAgICAgICAgICAgICAgaXNGdW5jdGlvbjogZW50cnkuaXNGdW5jdGlvbixcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByb3dNYXAuc2V0KGVudHJ5LmtleSwgcm93KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcm93W2xvY2FsZV0gPSBlbnRyeS52YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJvd3MucHVzaCguLi5yb3dNYXAudmFsdWVzKCkpO1xuICAgIHJvd3Muc29ydCgoYSwgYikgPT4gYS5rZXkubG9jYWxlQ29tcGFyZShiLmtleSkpO1xuXG4gICAgLy8g7Ya16rOEIOqzhOyCsDogbG9jYWxl67OEICjssYTsm4zsp4Qg6rCSIC8g7KCE7LK0IO2CpCDsiJgpXG4gICAgY29uc3Qgc3RhdHM6IFJlY29yZDxzdHJpbmcsIHsgdG90YWw6IG51bWJlcjsgZmlsbGVkOiBudW1iZXI7IHBlcmNlbnQ6IG51bWJlciB9PiA9IHt9O1xuICAgIGNvbnN0IHRvdGFsID0gcm93cy5sZW5ndGg7XG4gICAgZm9yIChjb25zdCBsb2NhbGUgb2YgbG9jYWxlcykge1xuICAgICAgY29uc3QgZmlsbGVkID0gcm93cy5maWx0ZXIoKHJvdykgPT4gISFyb3dbbG9jYWxlXSkubGVuZ3RoO1xuICAgICAgY29uc3QgcGVyY2VudCA9IHRvdGFsID4gMCA/IE1hdGgucm91bmQoKGZpbGxlZCAvIHRvdGFsKSAqIDEwMCkgOiAwO1xuICAgICAgc3RhdHNbbG9jYWxlXSA9IHsgdG90YWwsIGZpbGxlZCwgcGVyY2VudCB9O1xuICAgIH1cblxuICAgIHJldHVybiB7IHJvd3MsIGxvY2FsZXMsIGRlZmF1bHRMb2NhbGUsIHN0YXRzIH07XG4gIH1cblxuICAvKipcbiAgICog65SV7IWU64SI66asIOyhsO2ajFxuICAgKi9cbiAgYXN5bmMgZ2V0RGljdGlvbmFyeSgpOiBQcm9taXNlPERpY3Rpb25hcnlSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5jb2xsZWN0RGljdGlvbmFyeSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4Y2Vs66GcIOuCtOuztOuCtOq4sFxuICAgKi9cbiAgYXN5bmMgZXhwb3J0VG9FeGNlbCgpOiBQcm9taXNlPHsgZmlsZW5hbWU6IHN0cmluZzsgYnVmZmVyOiBCdWZmZXIgfT4ge1xuICAgIGNvbnN0IHsgcm93cywgbG9jYWxlcyB9ID0gYXdhaXQgdGhpcy5jb2xsZWN0RGljdGlvbmFyeSgpO1xuXG4gICAgY29uc3Qgd2IgPSBuZXcgV29ya2Jvb2soKTtcbiAgICBjb25zdCBzaGVldCA9IFwiaTE4blwiO1xuICAgIHdiLnNldFNoZWV0TmFtZShcIlNoZWV0MVwiLCBzaGVldCk7XG5cbiAgICBjb25zdCBwcm9qZWN0TmFtZSA9IGAke1NvbmFtdS5jb25maWcucHJvamVjdE5hbWUgPz8gXCJTb25hbXVcIn0gRGljdGlvbmFyeWA7XG4gICAgY29uc3QgaGVhZGVycyA9IFtcImtleVwiLCBcInNvdXJjZVwiLCAuLi5sb2NhbGVzXTtcblxuICAgIC8vIOyKpO2DgOydvCDsoJXsnZhcbiAgICBjb25zdCB0aXRsZVN0eWxlSWQgPSB3Yi5hZGRTdHlsZSh7XG4gICAgICBmb250OiB7IHNpemU6IDIzIH0sXG4gICAgICBhbGlnbm1lbnQ6IHsgdmVydGljYWw6IFwiY2VudGVyXCIsIGhvcml6b250YWw6IFwibGVmdFwiIH0sXG4gICAgfSk7XG4gICAgY29uc3QgaGVhZGVyU3R5bGVJZCA9IHdiLmFkZFN0eWxlKHtcbiAgICAgIGZvbnQ6IHsgYm9sZDogdHJ1ZSwgc2l6ZTogMTEgfSxcbiAgICAgIGFsaWdubWVudDogeyBob3Jpem9udGFsOiBcImNlbnRlclwiLCB2ZXJ0aWNhbDogXCJjZW50ZXJcIiB9LFxuICAgICAgZmlsbDogeyBwYXR0ZXJuOiBcInNvbGlkXCIsIGZnQ29sb3I6IFwiRjFGMUYxXCIgfSxcbiAgICAgIGJvcmRlcjoge1xuICAgICAgICB0b3A6IHsgc3R5bGU6IFwidGhpblwiLCBjb2xvcjogXCJEMEQwRDBcIiB9LFxuICAgICAgICBsZWZ0OiB7IHN0eWxlOiBcInRoaW5cIiwgY29sb3I6IFwiRDBEMEQwXCIgfSxcbiAgICAgICAgYm90dG9tOiB7IHN0eWxlOiBcInRoaW5cIiwgY29sb3I6IFwiRDBEMEQwXCIgfSxcbiAgICAgICAgcmlnaHQ6IHsgc3R5bGU6IFwidGhpblwiLCBjb2xvcjogXCJEMEQwRDBcIiB9LFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBjb25zdCBkYXRhU3R5bGVJZCA9IHdiLmFkZFN0eWxlKHtcbiAgICAgIGZvbnQ6IHsgc2l6ZTogMTEgfSxcbiAgICAgIGFsaWdubWVudDogeyB2ZXJ0aWNhbDogXCJjZW50ZXJcIiwgaG9yaXpvbnRhbDogXCJsZWZ0XCIgfSxcbiAgICB9KTtcblxuICAgIC8vIO2WiSAxOiDtlITroZzsoJ3tirjrqoVcbiAgICB3Yi5zZXRDZWxsVmFsdWUoc2hlZXQsIFwiQTFcIiwgcHJvamVjdE5hbWUpO1xuICAgIHdiLnNldENlbGxTdHlsZShzaGVldCwgXCJBMVwiLCB0aXRsZVN0eWxlSWQpO1xuICAgIHdiLnNldFJvd0hlaWdodChzaGVldCwgMSwgMjgpO1xuXG4gICAgLy8g7ZaJIDI6IOu5iCDtlokgKOq4sOuzuOqwkilcblxuICAgIC8vIO2WiSAzOiDtl6TrjZRcbiAgICB3Yi5zZXRSb3dWYWx1ZXMoc2hlZXQsIDMsIFwiQVwiLCBoZWFkZXJzKTtcbiAgICB3Yi5zZXRSb3dIZWlnaHQoc2hlZXQsIDMsIDI2KTtcbiAgICBmb3IgKGxldCBjb2wgPSAwOyBjb2wgPCBoZWFkZXJzLmxlbmd0aDsgY29sKyspIHtcbiAgICAgIHdiLnNldENlbGxTdHlsZShzaGVldCwgYCR7Y29sTGV0dGVyKGNvbCl9M2AsIGhlYWRlclN0eWxlSWQpO1xuICAgIH1cblxuICAgIC8vIO2WiSA0IOydtO2bhDog642w7J207YSwXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3dzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCByb3cgPSByb3dzW2ldO1xuICAgICAgY29uc3QgdmFsdWVzID0gW3Jvdy5rZXksIHJvdy5zb3VyY2UsIC4uLmxvY2FsZXMubWFwKChsb2NhbGUpID0+IHJvd1tsb2NhbGVdID8/IFwiXCIpXTtcbiAgICAgIGNvbnN0IHJvd051bSA9IGkgKyA0O1xuICAgICAgd2Iuc2V0Um93VmFsdWVzKHNoZWV0LCByb3dOdW0sIFwiQVwiLCB2YWx1ZXMpO1xuICAgICAgd2Iuc2V0Um93SGVpZ2h0KHNoZWV0LCByb3dOdW0sIDI0KTtcbiAgICAgIGZvciAobGV0IGNvbCA9IDA7IGNvbCA8IHZhbHVlcy5sZW5ndGg7IGNvbCsrKSB7XG4gICAgICAgIHdiLnNldENlbGxTdHlsZShzaGVldCwgYCR7Y29sTGV0dGVyKGNvbCl9JHtyb3dOdW19YCwgZGF0YVN0eWxlSWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIOy7rOufvCDrhIjruYQg6rOE7IKwXG4gICAgY29uc3QgTUFYX1dJRFRIID0gNTA7XG4gICAgY29uc3QgTUlOX1dJRFRIID0gMTA7XG4gICAgY29uc3QgY29sdW1uV2lkdGhzOiBudW1iZXJbXSA9IGhlYWRlcnMubWFwKChoZWFkZXIpID0+IE1hdGgubWF4KGhlYWRlci5sZW5ndGgsIE1JTl9XSURUSCkpO1xuXG4gICAgZm9yIChjb25zdCByb3cgb2Ygcm93cykge1xuICAgICAgY29uc3QgdmFsdWVzID0gW3Jvdy5rZXksIHJvdy5zb3VyY2UsIC4uLmxvY2FsZXMubWFwKChsb2NhbGUpID0+IHJvd1tsb2NhbGVdID8/IFwiXCIpXTtcbiAgICAgIHZhbHVlcy5mb3JFYWNoKCh2YWx1ZSwgaWR4KSA9PiB7XG4gICAgICAgIGNvbnN0IHRleHRMZW5ndGggPSBTdHJpbmcodmFsdWUpLmxlbmd0aDtcbiAgICAgICAgY29sdW1uV2lkdGhzW2lkeF0gPSBNYXRoLm1pbihNYXRoLm1heChjb2x1bW5XaWR0aHNbaWR4XSwgdGV4dExlbmd0aCksIE1BWF9XSURUSCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyDsu6zrn7wg64SI67mEIOyggeyaqVxuICAgIGZvciAobGV0IGNvbCA9IDA7IGNvbCA8IGNvbHVtbldpZHRocy5sZW5ndGg7IGNvbCsrKSB7XG4gICAgICB3Yi5zZXRDb2xXaWR0aChzaGVldCwgY29sTGV0dGVyKGNvbCksIGNvbHVtbldpZHRoc1tjb2xdICsgMik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGZpbGVuYW1lOiBgJHtwcm9qZWN0TmFtZX0tJHtuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkuc3BsaXQoXCJUXCIpWzBdfS54bHN4YCxcbiAgICAgIGJ1ZmZlcjogd2Iud3JpdGVCdWZmZXJTeW5jKCksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGNlbOyXkOyEnCDqsIDsoLjsmKTquLBcbiAgICpcbiAgICog7ZiV7IudOlxuICAgKiAtIDHtlok6IO2UhOuhnOygne2KuOuqhVxuICAgKiAtIDLtlok6IOu5iCDtlolcbiAgICogLSAz7ZaJOiDtl6TrjZQgKGtleSwgc291cmNlLCBsb2NhbGVzLi4uKVxuICAgKiAtIDTtlokg7J207ZuEOiDrjbDsnbTthLBcbiAgICovXG4gIGFzeW5jIGltcG9ydEZyb21FeGNlbChidWZmZXI6IEJ1ZmZlcik6IFByb21pc2U8SW1wb3J0UmVzdWx0PiB7XG4gICAgY29uc3Qgd2IgPSBXb3JrYm9vay5vcGVuQnVmZmVyU3luYyhidWZmZXIpO1xuICAgIGNvbnN0IHNoZWV0ID0gd2Iuc2hlZXROYW1lc1swXTtcbiAgICBjb25zdCBhbGxSb3dzID0gd2IuZ2V0Um93cyhzaGVldCk7XG5cbiAgICBjb25zdCB7IGRlZmF1bHRMb2NhbGUsIHN1cHBvcnRlZExvY2FsZXMgfSA9IHRoaXMuZ2V0STE4bkNvbmZpZygpO1xuICAgIGNvbnN0IGxvY2FsZXMgPSBzdXBwb3J0ZWRMb2NhbGVzO1xuXG4gICAgbGV0IHVwZGF0ZWRFbnRpdGllcyA9IDA7XG4gICAgbGV0IHVwZGF0ZWRMb2NhbGVzID0gMDtcblxuICAgIC8vIGxvY2FsZeuzhCBwcm9qZWN0IGRpY3QgZW50cmllc1xuICAgIGNvbnN0IHByb2plY3REaWN0RW50cmllczogUmVjb3JkPHN0cmluZywgRGljdEVudHJ5W10+ID0ge307XG4gICAgZm9yIChjb25zdCBsb2NhbGUgb2YgbG9jYWxlcykge1xuICAgICAgcHJvamVjdERpY3RFbnRyaWVzW2xvY2FsZV0gPSBbXTtcbiAgICB9XG5cbiAgICAvLyDtl6TrjZQg7ZaJIOywvuq4sDog7LKrIOuyiOynuCDsu6zrn7woQSnsnbQgXCJrZXlcIuyduCDtlolcbiAgICBsZXQgaGVhZGVyUm93TnVtID0gMDtcbiAgICBmb3IgKGNvbnN0IHJvd0RhdGEgb2YgYWxsUm93cykge1xuICAgICAgY29uc3QgZmlyc3RDZWxsID0gcm93RGF0YS5jZWxscy5maW5kKChjKSA9PiBjLmNvbHVtbiA9PT0gXCJBXCIpO1xuICAgICAgY29uc3QgZmlyc3RDZWxsVmFsdWUgPSBTdHJpbmcoZmlyc3RDZWxsPy52YWx1ZSA/PyBcIlwiKVxuICAgICAgICAudHJpbSgpXG4gICAgICAgIC50b0xvd2VyQ2FzZSgpO1xuICAgICAgaWYgKGZpcnN0Q2VsbFZhbHVlID09PSBcImtleVwiKSB7XG4gICAgICAgIGhlYWRlclJvd051bSA9IHJvd0RhdGEucm93O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaGVhZGVyUm93TnVtID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihTRChcInNvbmFtdS5lcnJvci5oZWFkZXJSb3dOb3RGb3VuZFwiKSk7XG4gICAgfVxuXG4gICAgLy8g7Zek642UIO2WieyXkOyEnCDsu6zrn7wg66ek7ZWRIOq1rOyEsVxuICAgIGNvbnN0IGhlYWRlclJvd0RhdGEgPSBhbGxSb3dzLmZpbmQoKHIpID0+IHIucm93ID09PSBoZWFkZXJSb3dOdW0pO1xuICAgIGNvbnN0IGNvbFRvSGVhZGVyOiBNYXA8c3RyaW5nLCBzdHJpbmc+ID0gbmV3IE1hcCgpO1xuICAgIGlmIChoZWFkZXJSb3dEYXRhKSB7XG4gICAgICBmb3IgKGNvbnN0IGNlbGwgb2YgaGVhZGVyUm93RGF0YS5jZWxscykge1xuICAgICAgICBjb2xUb0hlYWRlci5zZXQoY2VsbC5jb2x1bW4sIFN0cmluZyhjZWxsLnZhbHVlID8/IFwiXCIpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyDrjbDsnbTthLAg7ZaJIOydveq4sCAo7Zek642UIOuLpOydjCDtlonrtoDthLApXG4gICAgZm9yIChjb25zdCByb3dEYXRhIG9mIGFsbFJvd3MpIHtcbiAgICAgIGlmIChyb3dEYXRhLnJvdyA8PSBoZWFkZXJSb3dOdW0pIGNvbnRpbnVlO1xuXG4gICAgICBjb25zdCByb3dWYWx1ZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgICAgIGZvciAoY29uc3QgY2VsbCBvZiByb3dEYXRhLmNlbGxzKSB7XG4gICAgICAgIGNvbnN0IGhlYWRlck5hbWUgPSBjb2xUb0hlYWRlci5nZXQoY2VsbC5jb2x1bW4pO1xuICAgICAgICBpZiAoaGVhZGVyTmFtZSkge1xuICAgICAgICAgIHJvd1ZhbHVlc1toZWFkZXJOYW1lXSA9IFN0cmluZyhjZWxsLnZhbHVlID8/IFwiXCIpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGtleSA9IHJvd1ZhbHVlcy5rZXk7XG4gICAgICBjb25zdCBzb3VyY2UgPSByb3dWYWx1ZXMuc291cmNlIGFzIFwiZW50aXR5XCIgfCBcInByb2plY3RcIjtcblxuICAgICAgaWYgKCFrZXkgfHwgIXNvdXJjZSkgY29udGludWU7XG5cbiAgICAgIGlmIChzb3VyY2UgPT09IFwiZW50aXR5XCIpIHtcbiAgICAgICAgLy8gZW50aXR5IHNvdXJjZTogZGVmYXVsdCBsb2NhbGXrp4wgZW50aXR5Lmpzb27sl5Ag7KCA7J6lXG4gICAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZSA9IHJvd1ZhbHVlc1tkZWZhdWx0TG9jYWxlXTtcbiAgICAgICAgaWYgKGRlZmF1bHRWYWx1ZSkge1xuICAgICAgICAgIGNvbnN0IHVwZGF0ZWQgPSBhd2FpdCB0aGlzLnVwZGF0ZUVudGl0eUJ5S2V5KGtleSwgZGVmYXVsdFZhbHVlKTtcbiAgICAgICAgICBpZiAodXBkYXRlZCkge1xuICAgICAgICAgICAgdXBkYXRlZEVudGl0aWVzKys7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gbm9uLWRlZmF1bHQgbG9jYWxl7J2AIHByb2plY3QgZGljdOyXkCDsoIDsnqVcbiAgICAgICAgZm9yIChjb25zdCBsb2NhbGUgb2YgbG9jYWxlcykge1xuICAgICAgICAgIGlmIChsb2NhbGUgPT09IGRlZmF1bHRMb2NhbGUpIGNvbnRpbnVlO1xuICAgICAgICAgIGNvbnN0IGNlbGxWYWx1ZSA9IHJvd1ZhbHVlc1tsb2NhbGVdPy50cmltKCk7XG4gICAgICAgICAgaWYgKGNlbGxWYWx1ZSkge1xuICAgICAgICAgICAgcHJvamVjdERpY3RFbnRyaWVzW2xvY2FsZV0ucHVzaCh7XG4gICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgdmFsdWU6IGNlbGxWYWx1ZSxcbiAgICAgICAgICAgICAgaXNGdW5jdGlvbjogdGhpcy5pc0V4cHJlc3Npb25GdW5jdGlvbihjZWxsVmFsdWUpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHNvdXJjZSA9PT0gXCJwcm9qZWN0XCIpIHtcbiAgICAgICAgLy8gcHJvamVjdCBzb3VyY2U6IOuqqOuToCBsb2NhbGXsnYQgcHJvamVjdCBkaWN07JeQIOyggOyepVxuICAgICAgICBmb3IgKGNvbnN0IGxvY2FsZSBvZiBsb2NhbGVzKSB7XG4gICAgICAgICAgY29uc3QgY2VsbFZhbHVlID0gcm93VmFsdWVzW2xvY2FsZV0/LnRyaW0oKTtcbiAgICAgICAgICBpZiAoY2VsbFZhbHVlKSB7XG4gICAgICAgICAgICBwcm9qZWN0RGljdEVudHJpZXNbbG9jYWxlXS5wdXNoKHtcbiAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICB2YWx1ZTogY2VsbFZhbHVlLFxuICAgICAgICAgICAgICBpc0Z1bmN0aW9uOiB0aGlzLmlzRXhwcmVzc2lvbkZ1bmN0aW9uKGNlbGxWYWx1ZSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBQcm9qZWN0IGRpY3Qg7YyM7J28IOyDneyEsVxuICAgIGZvciAoY29uc3QgbG9jYWxlIG9mIGxvY2FsZXMpIHtcbiAgICAgIGNvbnN0IGVudHJpZXMgPSBwcm9qZWN0RGljdEVudHJpZXNbbG9jYWxlXTtcbiAgICAgIGlmIChlbnRyaWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgYXdhaXQgdGhpcy5zYXZlRGljdEZpbGUobG9jYWxlLCBlbnRyaWVzLCBsb2NhbGUgPT09IGRlZmF1bHRMb2NhbGUpO1xuICAgICAgICB1cGRhdGVkTG9jYWxlcysrO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgdXBkYXRlZEVudGl0aWVzLFxuICAgICAgdXBkYXRlZExvY2FsZXMsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDrlJXshZTrhIjrpqwg7ZWt66qpIOyImOyglVxuICAgKi9cbiAgYXN5bmMgdXBkYXRlRW50cnkocGFyYW1zOiB7XG4gICAgb2xkS2V5OiBzdHJpbmc7XG4gICAgbmV3S2V5OiBzdHJpbmc7XG4gICAgc291cmNlOiBcImVudGl0eVwiIHwgXCJwcm9qZWN0XCIgfCBcInNvbmFtdVwiO1xuICAgIHZhbHVlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgfSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsgb2xkS2V5LCBuZXdLZXksIHNvdXJjZSwgdmFsdWVzIH0gPSBwYXJhbXM7XG5cbiAgICBjb25zdCB7IGRlZmF1bHRMb2NhbGUsIHN1cHBvcnRlZExvY2FsZXMgfSA9IHRoaXMuZ2V0STE4bkNvbmZpZygpO1xuICAgIGNvbnN0IGxvY2FsZXMgPSBzdXBwb3J0ZWRMb2NhbGVzO1xuXG4gICAgLy8gZW50aXR5IHNvdXJjZeydmCBkZWZhdWx0IGxvY2FsZSDsspjrpqxcbiAgICBpZiAoc291cmNlID09PSBcImVudGl0eVwiICYmIHZhbHVlc1tkZWZhdWx0TG9jYWxlXSkge1xuICAgICAgYXdhaXQgdGhpcy51cGRhdGVFbnRpdHlCeUtleShuZXdLZXksIHZhbHVlc1tkZWZhdWx0TG9jYWxlXSk7XG4gICAgfVxuXG4gICAgLy8gcHJvamVjdCBkaWN0IOyXheuNsOydtO2KuFxuICAgIC8vIC0gZW50aXR57J2YIG5vbi1kZWZhdWx0IGxvY2FsZVxuICAgIC8vIC0gcHJvamVjdCBzb3VyY2XsnZgg66qo65OgIGxvY2FsZVxuICAgIC8vIC0gc29uYW11IHNvdXJjZeydmCDrqqjrk6AgbG9jYWxlIChvdmVycmlkZSlcbiAgICBmb3IgKGNvbnN0IGxvY2FsZSBvZiBsb2NhbGVzKSB7XG4gICAgICAvLyBlbnRpdHkgc291cmNl7J2YIGRlZmF1bHQgbG9jYWxl7J2AIGVudGl0eS5qc29u7JeQ7IScIOyymOumrO2WiOycvOuvgOuhnCDsiqTtgrVcbiAgICAgIGlmIChzb3VyY2UgPT09IFwiZW50aXR5XCIgJiYgbG9jYWxlID09PSBkZWZhdWx0TG9jYWxlKSBjb250aW51ZTtcblxuICAgICAgY29uc3QgY2VsbFZhbHVlID0gdmFsdWVzW2xvY2FsZV0/LnRyaW0oKTtcbiAgICAgIGlmICghY2VsbFZhbHVlKSBjb250aW51ZTtcblxuICAgICAgLy8g6riw7KG0IGRpY3Qg66Gc65OcXG4gICAgICBjb25zdCB7IGVudHJpZXMgfSA9IHRoaXMubG9hZFByb2plY3REaWN0KGxvY2FsZSk7XG5cbiAgICAgIC8vIGtleSDrs4Dqsr0g7IucIOq4sOyhtCBrZXkg7KCc6rGwXG4gICAgICBpZiAob2xkS2V5ICE9PSBuZXdLZXkpIHtcbiAgICAgICAgY29uc3Qgb2xkSW5kZXggPSBlbnRyaWVzLmZpbmRJbmRleCgoZSkgPT4gZS5rZXkgPT09IG9sZEtleSk7XG4gICAgICAgIGlmIChvbGRJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICBlbnRyaWVzLnNwbGljZShvbGRJbmRleCwgMSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8g7IOIIOqwkiDsl4XrjbDsnbTtirgg65iQ64qUIOy2lOqwgFxuICAgICAgY29uc3QgZXhpc3RpbmdJbmRleCA9IGVudHJpZXMuZmluZEluZGV4KChlKSA9PiBlLmtleSA9PT0gbmV3S2V5KTtcbiAgICAgIGNvbnN0IG5ld0VudHJ5OiBEaWN0RW50cnkgPSB7XG4gICAgICAgIGtleTogbmV3S2V5LFxuICAgICAgICB2YWx1ZTogY2VsbFZhbHVlLFxuICAgICAgICBpc0Z1bmN0aW9uOiB0aGlzLmlzRXhwcmVzc2lvbkZ1bmN0aW9uKGNlbGxWYWx1ZSksXG4gICAgICB9O1xuXG4gICAgICBpZiAoZXhpc3RpbmdJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgZW50cmllc1tleGlzdGluZ0luZGV4XSA9IG5ld0VudHJ5O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZW50cmllcy5wdXNoKG5ld0VudHJ5KTtcbiAgICAgIH1cblxuICAgICAgLy8gZGljdCDtjIzsnbwg7KCA7J6lXG4gICAgICBhd2FpdCB0aGlzLnNhdmVEaWN0RmlsZShsb2NhbGUsIGVudHJpZXMsIGxvY2FsZSA9PT0gZGVmYXVsdExvY2FsZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOuUleyFlOuEiOumrCDtla3rqqkg7LaU6rCAXG4gICAqL1xuICBhc3luYyBjcmVhdGVFbnRyeShwYXJhbXM6IHsga2V5OiBzdHJpbmc7IHZhbHVlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyBrZXksIHZhbHVlcyB9ID0gcGFyYW1zO1xuXG4gICAgaWYgKCFrZXk/LnRyaW0oKSkge1xuICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oU0QoXCJzb25hbXUuZXJyb3Iua2V5UmVxdWlyZWRcIikpO1xuICAgIH1cblxuICAgIGNvbnN0IHsgZGVmYXVsdExvY2FsZSwgc3VwcG9ydGVkTG9jYWxlcyB9ID0gdGhpcy5nZXRJMThuQ29uZmlnKCk7XG4gICAgY29uc3QgbG9jYWxlcyA9IHN1cHBvcnRlZExvY2FsZXM7XG5cbiAgICAvLyDspJHrs7Ug7YKkIOyytO2BrFxuICAgIGZvciAoY29uc3QgbG9jYWxlIG9mIGxvY2FsZXMpIHtcbiAgICAgIGNvbnN0IHsgZW50cmllcyB9ID0gdGhpcy5sb2FkUHJvamVjdERpY3QobG9jYWxlKTtcbiAgICAgIGlmIChlbnRyaWVzLnNvbWUoKGUpID0+IGUua2V5ID09PSBrZXkpKSB7XG4gICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLmtleUFscmVhZHlFeGlzdHNcIikoa2V5KSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8g6rCBIGxvY2FsZeyXkCDsg4gg7YKkIOy2lOqwgFxuICAgIGZvciAoY29uc3QgbG9jYWxlIG9mIGxvY2FsZXMpIHtcbiAgICAgIGNvbnN0IGNlbGxWYWx1ZSA9IHZhbHVlc1tsb2NhbGVdPy50cmltKCk7XG4gICAgICBpZiAoIWNlbGxWYWx1ZSkgY29udGludWU7XG5cbiAgICAgIGNvbnN0IHsgZW50cmllcyB9ID0gdGhpcy5sb2FkUHJvamVjdERpY3QobG9jYWxlKTtcbiAgICAgIGVudHJpZXMucHVzaCh7XG4gICAgICAgIGtleSxcbiAgICAgICAgdmFsdWU6IGNlbGxWYWx1ZSxcbiAgICAgICAgaXNGdW5jdGlvbjogdGhpcy5pc0V4cHJlc3Npb25GdW5jdGlvbihjZWxsVmFsdWUpLFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IHRoaXMuc2F2ZURpY3RGaWxlKGxvY2FsZSwgZW50cmllcywgbG9jYWxlID09PSBkZWZhdWx0TG9jYWxlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog65SV7IWU64SI66asIO2VreuqqSDsgq3soJxcbiAgICovXG4gIGFzeW5jIGRlbGV0ZUVudHJ5KGtleTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCFrZXkpIHtcbiAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLmtleVJlcXVpcmVkXCIpKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IGRlZmF1bHRMb2NhbGUsIHN1cHBvcnRlZExvY2FsZXMgfSA9IHRoaXMuZ2V0STE4bkNvbmZpZygpO1xuICAgIGNvbnN0IGxvY2FsZXMgPSBzdXBwb3J0ZWRMb2NhbGVzO1xuXG4gICAgbGV0IGRlbGV0ZWQgPSBmYWxzZTtcbiAgICBmb3IgKGNvbnN0IGxvY2FsZSBvZiBsb2NhbGVzKSB7XG4gICAgICBjb25zdCB7IGVudHJpZXMgfSA9IHRoaXMubG9hZFByb2plY3REaWN0KGxvY2FsZSk7XG4gICAgICBjb25zdCBpbmRleCA9IGVudHJpZXMuZmluZEluZGV4KChlKSA9PiBlLmtleSA9PT0ga2V5KTtcbiAgICAgIGlmIChpbmRleCAhPT0gLTEpIHtcbiAgICAgICAgZW50cmllcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICBkZWxldGVkID0gdHJ1ZTtcblxuICAgICAgICBhd2FpdCB0aGlzLnNhdmVEaWN0RmlsZShsb2NhbGUsIGVudHJpZXMsIGxvY2FsZSA9PT0gZGVmYXVsdExvY2FsZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFkZWxldGVkKSB7XG4gICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihTRChcInNvbmFtdS5lcnJvci5rZXlOb3RGb3VuZFwiKShrZXkpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog66+47IKs7JqpIO2CpCDqsoDsgqwgKGFzdC1ncmVwIOyCrOyaqSlcbiAgICovXG4gIGFzeW5jIGNoZWNrVXNhZ2Uoa2V5czogc3RyaW5nW10pOiBQcm9taXNlPFVzYWdlUmVzdWx0PiB7XG4gICAgLy8gYXN0LWdyZXAg7ISk7LmYIO2ZleyduFxuICAgIGxldCBzZ1BhdGg6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAgIHRyeSB7XG4gICAgICBzZ1BhdGggPSBleGVjU3luYyhcIndoaWNoIHNnXCIsIHsgZW5jb2Rpbmc6IFwidXRmLThcIiB9KS50cmltKCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICB0cnkge1xuICAgICAgICBzZ1BhdGggPSBleGVjU3luYyhcIndoaWNoIGFzdC1ncmVwXCIsIHsgZW5jb2Rpbmc6IFwidXRmLThcIiB9KS50cmltKCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gYXN0LWdyZXAgbm90IGluc3RhbGxlZFxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghc2dQYXRoKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBlcnJvcjpcbiAgICAgICAgICBcImFzdC1ncmVw7J20IOyEpOy5mOuQmOyWtCDsnojsp4Ag7JWK7Iq164uI64ukLiBicmV3IGluc3RhbGwgYXN0LWdyZXAg65iQ64qUIG5wbSBpbnN0YWxsIC1nIEBhc3QtZ3JlcC9jbGnroZwg7ISk7LmY7ZW07KO87IS47JqULlwiLFxuICAgICAgICB1bnVzZWRLZXlzOiBbXSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3Qgc2VhcmNoUGF0aHM6IHN0cmluZ1tdID0gW107XG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBbXCJhcGlcIiwgXCJ3ZWJcIiwgXCJhcHBcIl0pIHtcbiAgICAgIGNvbnN0IHNyY1BhdGggPSBwYXRoLmpvaW4oU29uYW11LmFwcFJvb3RQYXRoLCBlbnRyeSwgXCJzcmNcIik7XG4gICAgICBpZiAoZnMuZXhpc3RzU3luYyhzcmNQYXRoKSkge1xuICAgICAgICBzZWFyY2hQYXRocy5wdXNoKHNyY1BhdGgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzZWFyY2hQYXRocy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGVycm9yOiBcIuqygOyDie2VoCBzcmMg65SU66CJ7Yag66as66W8IOywvuydhCDsiJgg7JeG7Iq164uI64ukLlwiLFxuICAgICAgICB1bnVzZWRLZXlzOiBbXSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgdXNlZEtleXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBhc3QtZ3JlcOycvOuhnCBTRChcIi4uLlwiKSDtjKjthLQg6rKA7IOJXG4gICAgICAvLyDtjKjthLQ6IFNEKFwiS0VZXCIpIOuYkOuKlCBTRCgnS0VZJykg7ZiV7YOcXG4gICAgICBjb25zdCBwYXR0ZXJucyA9IFsnU0QoXCIkS0VZXCIpJywgXCJTRCgnJEtFWScpXCJdO1xuXG4gICAgICBmb3IgKGNvbnN0IHNlYXJjaFBhdGggb2Ygc2VhcmNoUGF0aHMpIHtcbiAgICAgICAgZm9yIChjb25zdCBwYXR0ZXJuIG9mIHBhdHRlcm5zKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGV4ZWNTeW5jKGAke3NnUGF0aH0gLS1wYXR0ZXJuICcke3BhdHRlcm59JyAtLWpzb24gJHtzZWFyY2hQYXRofWAsIHtcbiAgICAgICAgICAgICAgZW5jb2Rpbmc6IFwidXRmLThcIixcbiAgICAgICAgICAgICAgbWF4QnVmZmVyOiA1MCAqIDEwMjQgKiAxMDI0LCAvLyA1ME1CXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKHJlc3VsdC50cmltKCkpIHtcbiAgICAgICAgICAgICAgY29uc3QgbWF0Y2hlcyA9IEpTT04ucGFyc2UocmVzdWx0KTtcbiAgICAgICAgICAgICAgZm9yIChjb25zdCBtYXRjaCBvZiBtYXRjaGVzKSB7XG4gICAgICAgICAgICAgICAgLy8gbWV0YVZhcmlhYmxlcy5zaW5nbGUuS0VZLnRleHTsl5DshJwg7YKkIOy2lOy2nFxuICAgICAgICAgICAgICAgIGNvbnN0IGtleVRleHQgPSBtYXRjaC5tZXRhVmFyaWFibGVzPy5zaW5nbGU/LktFWT8udGV4dDtcbiAgICAgICAgICAgICAgICBpZiAoa2V5VGV4dCkge1xuICAgICAgICAgICAgICAgICAgLy8g65Sw7Ji07ZGcIOygnOqxsFxuICAgICAgICAgICAgICAgICAgY29uc3QgY2xlYW5LZXkgPSBrZXlUZXh0LnJlcGxhY2UoL15bXCInXXxbXCInXSQvZywgXCJcIik7XG4gICAgICAgICAgICAgICAgICB1c2VkS2V5cy5hZGQoY2xlYW5LZXkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgLy8g7Yyo7YS0IOunpOy5mCDsl4bsnLzrqbQg7JeQ65+sICjrrLTsi5wpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIGtleXMg7KSR7JeQ7IScIHVzZWRLZXlz7JeQIOyXhuuKlCDqsoPrk6TsnbQg66+47IKs7JqpIO2CpFxuICAgICAgY29uc3QgdW51c2VkS2V5cyA9IGtleXMuZmlsdGVyKChrKSA9PiAhdXNlZEtleXMuaGFzKGspKTtcblxuICAgICAgcmV0dXJuIHsgdW51c2VkS2V5cywgdXNlZEtleXNDb3VudDogdXNlZEtleXMuc2l6ZSB9O1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGVycm9yOiBg6rKA7IOJIOykkSDsmKTrpZgg67Cc7IOdOiAke2UgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFN0cmluZyhlKX1gLFxuICAgICAgICB1bnVzZWRLZXlzOiBbXSxcbiAgICAgIH07XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBzb25hbXVEaWN0aW9uYXJ5ID0gbmV3IFNvbmFtdURpY3Rpb25hcnkoKTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7O0FBeUJBLFNBQVMsVUFBVSxPQUF1QjtDQUN4QyxJQUFJLFNBQVM7Q0FDYixJQUFJLElBQUk7Q0FDUixPQUFPLEtBQUssR0FBRztFQUNiLFNBQVMsT0FBTyxhQUFhLEtBQU0sSUFBSSxFQUFHLElBQUk7RUFDOUMsSUFBSSxLQUFLLE1BQU0sSUFBSSxFQUFFLElBQUk7Q0FDM0I7Q0FDQSxPQUFPO0FBQ1Q7OzthQTFCc0M7cUJBQ2tCO29CQUNTO2dCQUNsQjtTQUN0QjtDQTRCWixtQkFBYixNQUE4Qjs7Ozs7Ozs7OztFQVU1QixjQUFjLFVBQStCO0dBQzNDLE1BQU0sVUFBVSxHQUFHLGFBQWEsVUFBVSxPQUFPO0dBQ2pELE1BQU0sYUFBYSxHQUFHLGlCQUFpQixVQUFVLFNBQVMsR0FBRyxhQUFhLFFBQVEsSUFBSTtHQUV0RixNQUFNLFVBQXVCLENBQUM7R0FFOUIsR0FBRyxhQUFhLGFBQWEsU0FBUztJQUNwQyxJQUFJLEdBQUcsbUJBQW1CLElBQUksR0FBRztLQUMvQixNQUFNLGdCQUFnQixLQUFLLHNCQUFzQixLQUFLLFVBQVU7S0FDaEUsSUFBSSxlQUNGLEtBQUsseUJBQXlCLGVBQWUsWUFBWSxPQUFPO0lBRXBFO0dBQ0YsQ0FBQztHQUVELE9BQU87RUFDVDs7Ozs7RUFNQSw0QkFBNEIsVUFBa0IsU0FBOEI7R0FDMUUsTUFBTSxVQUFVLEdBQUcsYUFBYSxVQUFVLE9BQU87R0FDakQsTUFBTSxhQUFhLEdBQUcsaUJBQWlCLFVBQVUsU0FBUyxHQUFHLGFBQWEsUUFBUSxJQUFJO0dBRXRGLE1BQU0sVUFBdUIsQ0FBQztHQUU5QixHQUFHLGFBQWEsYUFBYSxTQUFTO0lB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