sonamu 0.10.12 → 0.10.13

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 (513) hide show
  1. package/dist/ai/agents/agent.d.ts +1 -1
  2. package/dist/ai/agents/agent.d.ts.map +1 -1
  3. package/dist/ai/agents/agent.js +5 -6
  4. package/dist/ai/agents/types.d.ts +1 -1
  5. package/dist/ai/agents/types.d.ts.map +1 -1
  6. package/dist/ai/providers/rtzr/api.js +18 -18
  7. package/dist/ai/providers/rtzr/error.d.ts.map +1 -1
  8. package/dist/ai/providers/rtzr/error.js +17 -15
  9. package/dist/ai/providers/rtzr/model.d.ts.map +1 -1
  10. package/dist/ai/providers/rtzr/model.js +3 -2
  11. package/dist/ai/providers/rtzr/options.d.ts.map +1 -1
  12. package/dist/ai/providers/rtzr/options.js +16 -16
  13. package/dist/ai/providers/rtzr/provider.d.ts.map +1 -1
  14. package/dist/ai/providers/rtzr/provider.js +9 -9
  15. package/dist/ai/providers/rtzr/utils.d.ts.map +1 -1
  16. package/dist/ai/providers/rtzr/utils.js +1 -1
  17. package/dist/api/caster.d.ts.map +1 -1
  18. package/dist/api/caster.js +17 -17
  19. package/dist/api/code-converters.d.ts +4 -2
  20. package/dist/api/code-converters.d.ts.map +1 -1
  21. package/dist/api/code-converters.js +100 -19
  22. package/dist/api/config.d.ts +16 -1
  23. package/dist/api/config.d.ts.map +1 -1
  24. package/dist/api/config.js +28 -21
  25. package/dist/api/context.d.ts +2 -2
  26. package/dist/api/context.d.ts.map +1 -1
  27. package/dist/api/context.js +1 -1
  28. package/dist/api/decorators.d.ts.map +1 -1
  29. package/dist/api/decorators.js +18 -11
  30. package/dist/api/http-validator.d.ts +36 -0
  31. package/dist/api/http-validator.d.ts.map +1 -0
  32. package/dist/api/http-validator.js +72 -0
  33. package/dist/api/index.js +6 -4
  34. package/dist/api/sonamu.d.ts +59 -20
  35. package/dist/api/sonamu.d.ts.map +1 -1
  36. package/dist/api/sonamu.js +250 -106
  37. package/dist/api/websocket-helpers.d.ts +7 -5
  38. package/dist/api/websocket-helpers.d.ts.map +1 -1
  39. package/dist/api/websocket-helpers.js +6 -6
  40. package/dist/auth/audit-log/builders.d.ts.map +1 -1
  41. package/dist/auth/audit-log/builders.js +1 -1
  42. package/dist/auth/audit-log/client-ip.d.ts +1 -1
  43. package/dist/auth/audit-log/client-ip.d.ts.map +1 -1
  44. package/dist/auth/audit-log/client-ip.js +4 -2
  45. package/dist/auth/audit-log/events.d.ts +5 -1
  46. package/dist/auth/audit-log/events.d.ts.map +1 -1
  47. package/dist/auth/audit-log/events.js +1 -1
  48. package/dist/auth/audit-log/plugin.d.ts +0 -8
  49. package/dist/auth/audit-log/plugin.d.ts.map +1 -1
  50. package/dist/auth/audit-log/plugin.js +48 -52
  51. package/dist/auth/audit-log-ingestor.d.ts.map +1 -1
  52. package/dist/auth/audit-log-ingestor.js +16 -12
  53. package/dist/auth/auth-generator.d.ts.map +1 -1
  54. package/dist/auth/auth-generator.js +1 -1
  55. package/dist/auth/better-auth-request.d.ts.map +1 -1
  56. package/dist/auth/better-auth-request.js +6 -5
  57. package/dist/auth/knex-adapter.js +1 -1
  58. package/dist/auth/plugins/entity-definitions/index.d.ts +13 -1
  59. package/dist/auth/plugins/entity-definitions/index.d.ts.map +1 -1
  60. package/dist/auth/plugins/entity-definitions/index.js +1 -1
  61. package/dist/auth/plugins/wrappers/admin.d.ts +1 -1
  62. package/dist/bin/build-config.d.ts +25 -0
  63. package/dist/bin/build-config.d.ts.map +1 -1
  64. package/dist/bin/build-config.js +105 -2
  65. package/dist/bin/cli.js +131 -27
  66. package/dist/bin/compiler-policy.d.ts +3 -0
  67. package/dist/bin/compiler-policy.d.ts.map +1 -0
  68. package/dist/bin/compiler-policy.js +24 -0
  69. package/dist/bin/fixture.d.ts.map +1 -1
  70. package/dist/bin/fixture.js +5 -3
  71. package/dist/bin/test-command.d.ts +22 -1
  72. package/dist/bin/test-command.d.ts.map +1 -1
  73. package/dist/bin/test-command.js +18 -10
  74. package/dist/bin/ts-loader-registration.d.ts +7 -1
  75. package/dist/bin/ts-loader-registration.d.ts.map +1 -1
  76. package/dist/bin/ts-loader-registration.js +13 -4
  77. package/dist/cache/decorator.d.ts.map +1 -1
  78. package/dist/cache/decorator.js +11 -4
  79. package/dist/compress/compress.d.ts.map +1 -1
  80. package/dist/compress/compress.js +1 -1
  81. package/dist/cone/cone-generator.d.ts +14 -1
  82. package/dist/cone/cone-generator.d.ts.map +1 -1
  83. package/dist/cone/cone-generator.js +13 -9
  84. package/dist/database/_batch_update.js +1 -1
  85. package/dist/database/base-model.d.ts +22 -10
  86. package/dist/database/base-model.d.ts.map +1 -1
  87. package/dist/database/base-model.js +26 -16
  88. package/dist/database/base-model.types.d.ts +15 -3
  89. package/dist/database/base-model.types.d.ts.map +1 -1
  90. package/dist/database/db.d.ts +12 -2
  91. package/dist/database/db.d.ts.map +1 -1
  92. package/dist/database/db.js +10 -7
  93. package/dist/database/knex.d.ts.map +1 -1
  94. package/dist/database/knex.js +17 -14
  95. package/dist/database/puri.d.ts +11 -9
  96. package/dist/database/puri.d.ts.map +1 -1
  97. package/dist/database/puri.js +93 -79
  98. package/dist/database/puri.types.d.ts +21 -21
  99. package/dist/database/puri.types.d.ts.map +1 -1
  100. package/dist/database/puri.types.js +1 -1
  101. package/dist/database/upsert-builder.d.ts +12 -10
  102. package/dist/database/upsert-builder.d.ts.map +1 -1
  103. package/dist/database/upsert-builder.js +20 -12
  104. package/dist/dict/sd.d.ts.map +1 -1
  105. package/dist/dict/sd.js +1 -1
  106. package/dist/dict/sonamu-dictionary.d.ts.map +1 -1
  107. package/dist/dict/sonamu-dictionary.js +1 -1
  108. package/dist/dict/utils.d.ts.map +1 -1
  109. package/dist/dict/utils.js +7 -2
  110. package/dist/entity/entity-manager.d.ts +13 -4
  111. package/dist/entity/entity-manager.d.ts.map +1 -1
  112. package/dist/entity/entity-manager.js +19 -11
  113. package/dist/entity/entity-template-cone.d.ts +73 -5
  114. package/dist/entity/entity-template-cone.d.ts.map +1 -1
  115. package/dist/entity/entity-template-cone.js +4 -2
  116. package/dist/entity/entity.d.ts +6 -2
  117. package/dist/entity/entity.d.ts.map +1 -1
  118. package/dist/entity/entity.js +30 -28
  119. package/dist/env.d.ts +3 -1
  120. package/dist/env.d.ts.map +1 -1
  121. package/dist/env.js +1 -1
  122. package/dist/exceptions/error-handler.d.ts.map +1 -1
  123. package/dist/exceptions/error-handler.js +7 -2
  124. package/dist/exceptions/so-exceptions.d.ts +24 -20
  125. package/dist/exceptions/so-exceptions.d.ts.map +1 -1
  126. package/dist/exceptions/so-exceptions.js +4 -2
  127. package/dist/filter/utils.d.ts +7 -2
  128. package/dist/filter/utils.d.ts.map +1 -1
  129. package/dist/filter/utils.js +8 -6
  130. package/dist/index.d.ts +3 -0
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +12 -6
  133. package/dist/logger/configure.d.ts.map +1 -1
  134. package/dist/logger/configure.js +10 -10
  135. package/dist/migration/code-generation.d.ts.map +1 -1
  136. package/dist/migration/code-generation.js +50 -46
  137. package/dist/migration/index-where-predicate.d.ts.map +1 -1
  138. package/dist/migration/index-where-predicate.js +22 -8
  139. package/dist/migration/migration-set.d.ts.map +1 -1
  140. package/dist/migration/migration-set.js +1 -1
  141. package/dist/migration/migrator.d.ts +3 -2
  142. package/dist/migration/migrator.d.ts.map +1 -1
  143. package/dist/migration/migrator.js +27 -21
  144. package/dist/migration/postgresql-schema-reader.d.ts.map +1 -1
  145. package/dist/migration/postgresql-schema-reader.js +51 -36
  146. package/dist/migration/slack-confirm.d.ts.map +1 -1
  147. package/dist/migration/slack-confirm.js +1 -1
  148. package/dist/naite/naite-reporter.js +2 -2
  149. package/dist/naite/naite.d.ts +74 -15
  150. package/dist/naite/naite.d.ts.map +1 -1
  151. package/dist/naite/naite.js +5 -19
  152. package/dist/runtime-type.d.ts +6 -0
  153. package/dist/runtime-type.d.ts.map +1 -0
  154. package/dist/runtime-type.js +26 -0
  155. package/dist/ssr/hmr-opt-out.d.ts +26 -0
  156. package/dist/ssr/hmr-opt-out.d.ts.map +1 -0
  157. package/dist/ssr/hmr-opt-out.js +59 -0
  158. package/dist/ssr/renderer.d.ts.map +1 -1
  159. package/dist/ssr/renderer.js +4 -1
  160. package/dist/storage/base-file.js +14 -14
  161. package/dist/storage/buffered-file.d.ts +2 -2
  162. package/dist/storage/buffered-file.d.ts.map +1 -1
  163. package/dist/storage/buffered-file.js +12 -12
  164. package/dist/storage/s3-driver.d.ts.map +1 -1
  165. package/dist/storage/s3-driver.js +1 -1
  166. package/dist/storage/uploaded-file.d.ts +2 -2
  167. package/dist/storage/uploaded-file.d.ts.map +1 -1
  168. package/dist/storage/uploaded-file.js +8 -8
  169. package/dist/stream/sse.js +11 -11
  170. package/dist/stream/ws-core.d.ts +1 -1
  171. package/dist/stream/ws-core.d.ts.map +1 -1
  172. package/dist/stream/ws-delivery.d.ts +1 -1
  173. package/dist/stream/ws-delivery.d.ts.map +1 -1
  174. package/dist/stream/ws-delivery.js +6 -4
  175. package/dist/stream/ws-local-connection-store.d.ts.map +1 -1
  176. package/dist/stream/ws-local-connection-store.js +4 -2
  177. package/dist/stream/ws-presence-store.js +1 -1
  178. package/dist/stream/ws-registry.d.ts +4 -4
  179. package/dist/stream/ws-registry.d.ts.map +1 -1
  180. package/dist/stream/ws-registry.js +4 -2
  181. package/dist/stream/ws-telemetry.d.ts +16 -12
  182. package/dist/stream/ws-telemetry.d.ts.map +1 -1
  183. package/dist/stream/ws-telemetry.js +22 -18
  184. package/dist/stream/ws.d.ts +18 -12
  185. package/dist/stream/ws.d.ts.map +1 -1
  186. package/dist/stream/ws.js +26 -22
  187. package/dist/syncer/api-parser.js +1 -1
  188. package/dist/syncer/checksum.d.ts.map +1 -1
  189. package/dist/syncer/checksum.js +7 -8
  190. package/dist/syncer/code-generator.d.ts.map +1 -1
  191. package/dist/syncer/code-generator.js +13 -14
  192. package/dist/syncer/entity-operations.d.ts.map +1 -1
  193. package/dist/syncer/entity-operations.js +5 -6
  194. package/dist/syncer/file-copy.d.ts +5 -0
  195. package/dist/syncer/file-copy.d.ts.map +1 -0
  196. package/dist/syncer/file-copy.js +36 -0
  197. package/dist/syncer/file-patterns.d.ts +1 -0
  198. package/dist/syncer/file-patterns.d.ts.map +1 -1
  199. package/dist/syncer/file-patterns.js +5 -2
  200. package/dist/syncer/file-tracking.d.ts.map +1 -1
  201. package/dist/syncer/file-tracking.js +5 -4
  202. package/dist/syncer/filesystem-dependencies.d.ts +15 -0
  203. package/dist/syncer/filesystem-dependencies.d.ts.map +1 -0
  204. package/dist/syncer/filesystem-dependencies.js +53 -0
  205. package/dist/syncer/module-loader.d.ts +1 -1
  206. package/dist/syncer/module-loader.d.ts.map +1 -1
  207. package/dist/syncer/module-loader.js +6 -4
  208. package/dist/syncer/syncer-actions.d.ts +4 -0
  209. package/dist/syncer/syncer-actions.d.ts.map +1 -1
  210. package/dist/syncer/syncer-actions.js +34 -17
  211. package/dist/syncer/syncer.d.ts +17 -6
  212. package/dist/syncer/syncer.d.ts.map +1 -1
  213. package/dist/syncer/syncer.js +71 -29
  214. package/dist/syncer/watcher.d.ts.map +1 -1
  215. package/dist/syncer/watcher.js +3 -3
  216. package/dist/tasks/decorator.d.ts +6 -6
  217. package/dist/tasks/decorator.d.ts.map +1 -1
  218. package/dist/tasks/decorator.js +4 -4
  219. package/dist/tasks/step-wrapper.d.ts +6 -4
  220. package/dist/tasks/step-wrapper.d.ts.map +1 -1
  221. package/dist/tasks/step-wrapper.js +5 -5
  222. package/dist/tasks/workflow-manager.d.ts.map +1 -1
  223. package/dist/tasks/workflow-manager.js +13 -7
  224. package/dist/template/entity-converter.d.ts +1 -1
  225. package/dist/template/entity-converter.d.ts.map +1 -1
  226. package/dist/template/entity-converter.js +2 -2
  227. package/dist/template/helpers.d.ts +8 -6
  228. package/dist/template/helpers.d.ts.map +1 -1
  229. package/dist/template/helpers.js +1 -1
  230. package/dist/template/implementations/generated.template.d.ts.map +1 -1
  231. package/dist/template/implementations/generated.template.js +4 -4
  232. package/dist/template/implementations/generated_http.template.d.ts +7 -4
  233. package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
  234. package/dist/template/implementations/generated_http.template.js +21 -21
  235. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
  236. package/dist/template/implementations/generated_sso.template.js +6 -3
  237. package/dist/template/implementations/http_validators.template.d.ts +18 -0
  238. package/dist/template/implementations/http_validators.template.d.ts.map +1 -0
  239. package/dist/template/implementations/http_validators.template.js +127 -0
  240. package/dist/template/implementations/model.template.d.ts.map +1 -1
  241. package/dist/template/implementations/model.template.js +1 -1
  242. package/dist/template/implementations/queries.template.js +1 -1
  243. package/dist/template/implementations/sd.template.d.ts.map +1 -1
  244. package/dist/template/implementations/sd.template.js +79 -39
  245. package/dist/template/implementations/services.template.d.ts.map +1 -1
  246. package/dist/template/implementations/services.template.js +6 -4
  247. package/dist/template/implementations/view_form.template.d.ts +6 -1
  248. package/dist/template/implementations/view_form.template.d.ts.map +1 -1
  249. package/dist/template/implementations/view_form.template.js +23 -15
  250. package/dist/template/implementations/view_list.template.d.ts.map +1 -1
  251. package/dist/template/implementations/view_list.template.js +11 -6
  252. package/dist/template/template-manager.d.ts.map +1 -1
  253. package/dist/template/template-manager.js +9 -7
  254. package/dist/template/template-types.d.ts +12 -5
  255. package/dist/template/template-types.d.ts.map +1 -1
  256. package/dist/template/template-types.js +1 -1
  257. package/dist/template/template.d.ts +2 -2
  258. package/dist/template/template.d.ts.map +1 -1
  259. package/dist/template/template.js +6 -4
  260. package/dist/template/zod-converter.d.ts +0 -19
  261. package/dist/template/zod-converter.d.ts.map +1 -1
  262. package/dist/template/zod-converter.js +100 -84
  263. package/dist/testing/_relation-graph.d.ts.map +1 -1
  264. package/dist/testing/_relation-graph.js +2 -1
  265. package/dist/testing/bootstrap.d.ts.map +1 -1
  266. package/dist/testing/bootstrap.js +9 -6
  267. package/dist/testing/data-explorer.d.ts +32 -7
  268. package/dist/testing/data-explorer.d.ts.map +1 -1
  269. package/dist/testing/data-explorer.js +77 -31
  270. package/dist/testing/dev-test-routes.d.ts +8 -1
  271. package/dist/testing/dev-test-routes.d.ts.map +1 -1
  272. package/dist/testing/dev-test-routes.js +125 -108
  273. package/dist/testing/dev-vitest-manager.d.ts +54 -8
  274. package/dist/testing/dev-vitest-manager.d.ts.map +1 -1
  275. package/dist/testing/dev-vitest-manager.js +24 -9
  276. package/dist/testing/faker-mappings.d.ts +412 -1
  277. package/dist/testing/faker-mappings.d.ts.map +1 -1
  278. package/dist/testing/faker-mappings.js +1 -1
  279. package/dist/testing/filesystem.d.ts +2 -0
  280. package/dist/testing/filesystem.d.ts.map +1 -0
  281. package/dist/testing/filesystem.js +7 -0
  282. package/dist/testing/fixture-generator.d.ts +25 -8
  283. package/dist/testing/fixture-generator.d.ts.map +1 -1
  284. package/dist/testing/fixture-generator.js +132 -73
  285. package/dist/testing/fixture-loader.d.ts +3 -1
  286. package/dist/testing/fixture-loader.d.ts.map +1 -1
  287. package/dist/testing/fixture-loader.js +1 -20
  288. package/dist/testing/fixture-manager.d.ts +8 -7
  289. package/dist/testing/fixture-manager.d.ts.map +1 -1
  290. package/dist/testing/fixture-manager.js +91 -59
  291. package/dist/testing/global-setup.d.ts.map +1 -1
  292. package/dist/testing/global-setup.js +5 -2
  293. package/dist/testing/index.d.ts +2 -0
  294. package/dist/testing/index.d.ts.map +1 -1
  295. package/dist/testing/index.js +6 -3
  296. package/dist/types/types.d.ts +101 -99
  297. package/dist/types/types.d.ts.map +1 -1
  298. package/dist/types/types.js +234 -225
  299. package/dist/ui/ai-api.d.ts.map +1 -1
  300. package/dist/ui/ai-api.js +1 -1
  301. package/dist/ui/ai-client.d.ts.map +1 -1
  302. package/dist/ui/ai-client.js +28 -18
  303. package/dist/ui/api.d.ts.map +1 -1
  304. package/dist/ui/api.js +135 -128
  305. package/dist/ui/async-route.d.ts +3 -0
  306. package/dist/ui/async-route.d.ts.map +1 -0
  307. package/dist/ui/async-route.js +12 -0
  308. package/dist/ui/cdd-service.d.ts +9 -7
  309. package/dist/ui/cdd-service.d.ts.map +1 -1
  310. package/dist/ui/cdd-service.js +7 -5
  311. package/dist/ui/migrations-api.d.ts.map +1 -1
  312. package/dist/ui/migrations-api.js +17 -15
  313. package/dist/ui-web/assets/index-DV1AAq6W.js +178 -0
  314. package/dist/ui-web/index.html +1 -1
  315. package/dist/utils/formatter.d.ts.map +1 -1
  316. package/dist/utils/formatter.js +7 -5
  317. package/dist/utils/fs-utils.d.ts +3 -3
  318. package/dist/utils/fs-utils.d.ts.map +1 -1
  319. package/dist/utils/fs-utils.js +6 -6
  320. package/dist/utils/model.d.ts +3 -5
  321. package/dist/utils/model.d.ts.map +1 -1
  322. package/dist/utils/model.js +1 -1
  323. package/dist/utils/object-utils.d.ts +1 -1
  324. package/dist/utils/object-utils.d.ts.map +1 -1
  325. package/dist/utils/object-utils.js +17 -16
  326. package/dist/utils/process-utils.d.ts.map +1 -1
  327. package/dist/utils/process-utils.js +4 -2
  328. package/dist/utils/runtime-value.d.ts +13 -0
  329. package/dist/utils/runtime-value.d.ts.map +1 -0
  330. package/dist/utils/runtime-value.js +40 -0
  331. package/dist/utils/sql-parser.d.ts +8 -1
  332. package/dist/utils/sql-parser.d.ts.map +1 -1
  333. package/dist/utils/sql-parser.js +6 -3
  334. package/dist/utils/type-utils.d.ts.map +1 -1
  335. package/dist/utils/type-utils.js +10 -8
  336. package/dist/utils/utils.d.ts +2 -2
  337. package/dist/utils/utils.d.ts.map +1 -1
  338. package/dist/utils/utils.js +11 -8
  339. package/dist/utils/zod-error.d.ts.map +1 -1
  340. package/dist/utils/zod-error.js +7 -4
  341. package/dist/vector/chunking.d.ts.map +1 -1
  342. package/dist/vector/chunking.js +1 -1
  343. package/dist/vector/embedding.d.ts.map +1 -1
  344. package/dist/vector/embedding.js +1 -1
  345. package/dist/vector/types.d.ts +3 -2
  346. package/dist/vector/types.d.ts.map +1 -1
  347. package/package.json +5 -3
  348. package/src/ai/agents/agent.ts +5 -5
  349. package/src/ai/agents/types.ts +1 -1
  350. package/src/ai/providers/rtzr/__tests__/model.test.ts +2 -2
  351. package/src/ai/providers/rtzr/error.ts +5 -3
  352. package/src/ai/providers/rtzr/model.ts +3 -2
  353. package/src/ai/providers/rtzr/options.ts +10 -5
  354. package/src/ai/providers/rtzr/provider.ts +10 -10
  355. package/src/ai/providers/rtzr/utils.ts +3 -1
  356. package/src/api/__tests__/config.test.ts +11 -21
  357. package/src/api/__tests__/sonamu.http-validator.test.ts +512 -0
  358. package/src/api/__tests__/sonamu.websocket.test.ts +51 -41
  359. package/src/api/__tests__/zod-compiler-policy.test.ts +95 -0
  360. package/src/api/caster.ts +6 -8
  361. package/src/api/code-converters.ts +136 -36
  362. package/src/api/config.ts +62 -4
  363. package/src/api/context.ts +3 -3
  364. package/src/api/decorators.ts +28 -17
  365. package/src/api/http-validator.ts +149 -0
  366. package/src/api/sonamu.ts +459 -152
  367. package/src/api/websocket-helpers.ts +24 -17
  368. package/src/auth/audit-log/builders.ts +3 -2
  369. package/src/auth/audit-log/client-ip.ts +4 -2
  370. package/src/auth/audit-log/events.ts +15 -1
  371. package/src/auth/audit-log/plugin.ts +129 -200
  372. package/src/auth/audit-log-ingestor.ts +19 -15
  373. package/src/auth/auth-generator.ts +10 -5
  374. package/src/auth/better-auth-request.ts +4 -3
  375. package/src/auth/knex-adapter.ts +8 -2
  376. package/src/auth/plugins/entity-definitions/index.ts +6 -5
  377. package/src/bin/__tests__/http-validator-benchmark.test.ts +94 -0
  378. package/src/bin/__tests__/test-command.test.ts +9 -15
  379. package/src/bin/__tests__/ts-loader-register.test.ts +15 -17
  380. package/src/bin/__tests__/zod-compiler-build.test.ts +307 -0
  381. package/src/bin/build-config.ts +167 -0
  382. package/src/bin/cli.ts +153 -36
  383. package/src/bin/compiler-policy.ts +35 -0
  384. package/src/bin/fixture.ts +14 -3
  385. package/src/bin/test-command.ts +74 -29
  386. package/src/bin/ts-loader-registration.ts +22 -4
  387. package/src/cache/decorator.ts +10 -3
  388. package/src/compress/compress.ts +17 -4
  389. package/src/cone/cone-generator.ts +34 -6
  390. package/src/database/__tests__/db.test.ts +1 -0
  391. package/src/database/__tests__/puri.test.ts +16 -15
  392. package/src/database/__tests__/transaction-scope.test.ts +5 -0
  393. package/src/database/_batch_update.ts +1 -0
  394. package/src/database/base-model.ts +81 -50
  395. package/src/database/base-model.types.ts +6 -6
  396. package/src/database/db.ts +29 -19
  397. package/src/database/knex.ts +30 -17
  398. package/src/database/puri-subset.test-d.ts +17 -0
  399. package/src/database/puri.ts +181 -143
  400. package/src/database/puri.types.test-d.ts +31 -1
  401. package/src/database/puri.types.ts +23 -21
  402. package/src/database/upsert-builder.ts +75 -53
  403. package/src/dict/sd.ts +15 -5
  404. package/src/dict/sonamu-dictionary.ts +6 -6
  405. package/src/dict/utils.ts +9 -1
  406. package/src/entity/entity-manager.ts +26 -9
  407. package/src/entity/entity-template-cone.ts +5 -10
  408. package/src/entity/entity.ts +50 -34
  409. package/src/env.ts +7 -3
  410. package/src/exceptions/error-handler.ts +17 -2
  411. package/src/exceptions/so-exceptions.ts +26 -20
  412. package/src/filter/utils.ts +21 -11
  413. package/src/index.ts +3 -0
  414. package/src/logger/configure.ts +26 -18
  415. package/src/migration/__tests__/migrator.test.ts +50 -57
  416. package/src/migration/code-generation.ts +132 -104
  417. package/src/migration/index-where-predicate.ts +51 -24
  418. package/src/migration/migration-set.ts +11 -5
  419. package/src/migration/migrator.ts +68 -41
  420. package/src/migration/postgresql-schema-reader.ts +52 -47
  421. package/src/migration/slack-confirm.ts +17 -15
  422. package/src/naite/naite-reporter.ts +1 -1
  423. package/src/naite/naite.ts +97 -24
  424. package/src/runtime-type.ts +34 -0
  425. package/src/ssr/hmr-opt-out.ts +78 -0
  426. package/src/ssr/renderer.ts +6 -0
  427. package/src/storage/base-file.ts +13 -13
  428. package/src/storage/buffered-file.ts +11 -11
  429. package/src/storage/s3-driver.ts +4 -1
  430. package/src/storage/uploaded-file.ts +8 -8
  431. package/src/stream/__tests__/ws-contracts.test.ts +4 -2
  432. package/src/stream/__tests__/ws-telemetry.test.ts +1 -1
  433. package/src/stream/__tests__/ws.test.ts +30 -6
  434. package/src/stream/sse.ts +12 -11
  435. package/src/stream/ws-core.ts +1 -1
  436. package/src/stream/ws-delivery.ts +16 -7
  437. package/src/stream/ws-local-connection-store.ts +2 -3
  438. package/src/stream/ws-presence-store.ts +6 -1
  439. package/src/stream/ws-registry.ts +16 -7
  440. package/src/stream/ws-telemetry.ts +66 -43
  441. package/src/stream/ws.ts +73 -39
  442. package/src/syncer/__tests__/api-parser.websocket-type-ref.test.ts +3 -2
  443. package/src/syncer/__tests__/http-validator-registry.test.ts +137 -0
  444. package/src/syncer/api-parser.ts +67 -27
  445. package/src/syncer/checksum.ts +17 -11
  446. package/src/syncer/code-generator.ts +25 -17
  447. package/src/syncer/entity-operations.ts +3 -5
  448. package/src/syncer/file-copy.ts +46 -0
  449. package/src/syncer/file-patterns.ts +11 -8
  450. package/src/syncer/file-tracking.ts +3 -4
  451. package/src/syncer/filesystem-dependencies.ts +73 -0
  452. package/src/syncer/module-loader.ts +8 -4
  453. package/src/syncer/syncer-actions.ts +56 -18
  454. package/src/syncer/syncer.ts +116 -43
  455. package/src/syncer/watcher.ts +8 -4
  456. package/src/tasks/decorator.ts +20 -12
  457. package/src/tasks/step-wrapper.ts +19 -9
  458. package/src/tasks/workflow-manager.ts +15 -9
  459. package/src/template/__tests__/http_validators.template.test.ts +160 -0
  460. package/src/template/__tests__/services.template.mutation.test.ts +24 -23
  461. package/src/template/__tests__/services.template.websocket.test.ts +21 -25
  462. package/src/template/entity-converter.ts +5 -2
  463. package/src/template/helpers.ts +8 -9
  464. package/src/template/implementations/generated.template.ts +5 -4
  465. package/src/template/implementations/generated_http.template.ts +61 -15
  466. package/src/template/implementations/generated_sso.template.ts +15 -4
  467. package/src/template/implementations/http_validators.template.ts +175 -0
  468. package/src/template/implementations/model.template.ts +3 -1
  469. package/src/template/implementations/sd.template.ts +81 -41
  470. package/src/template/implementations/services.template.ts +2 -2
  471. package/src/template/implementations/view_form.template.ts +56 -39
  472. package/src/template/implementations/view_list.template.ts +31 -23
  473. package/src/template/template-manager.ts +15 -13
  474. package/src/template/template-types.ts +13 -5
  475. package/src/template/template.ts +4 -3
  476. package/src/template/zod-converter.ts +206 -91
  477. package/src/testing/__tests__/dev-test-routes.test.ts +85 -25
  478. package/src/testing/__tests__/dev-vitest-manager.test.ts +15 -15
  479. package/src/testing/_relation-graph.ts +4 -1
  480. package/src/testing/bootstrap.ts +12 -5
  481. package/src/testing/data-explorer.ts +102 -53
  482. package/src/testing/dev-test-routes.ts +87 -50
  483. package/src/testing/dev-vitest-manager.ts +88 -32
  484. package/src/testing/faker-mappings.ts +2 -2
  485. package/src/testing/filesystem.ts +1 -0
  486. package/src/testing/fixture-generator.ts +191 -131
  487. package/src/testing/fixture-loader.ts +5 -1
  488. package/src/testing/fixture-manager.ts +129 -90
  489. package/src/testing/global-setup.ts +7 -3
  490. package/src/testing/index.ts +5 -0
  491. package/src/types/__tests__/entity-json-schema-search-text.test.ts +9 -3
  492. package/src/types/types.ts +184 -158
  493. package/src/ui/ai-api.ts +9 -7
  494. package/src/ui/ai-client.ts +61 -56
  495. package/src/ui/api.ts +727 -616
  496. package/src/ui/async-route.ts +4 -0
  497. package/src/ui/cdd-service.ts +35 -12
  498. package/src/ui/migrations-api.ts +63 -51
  499. package/src/utils/formatter.ts +7 -3
  500. package/src/utils/fs-utils.ts +5 -5
  501. package/src/utils/model.ts +4 -5
  502. package/src/utils/object-utils.ts +32 -22
  503. package/src/utils/process-utils.ts +4 -1
  504. package/src/utils/runtime-value.ts +43 -0
  505. package/src/utils/sql-parser.ts +13 -6
  506. package/src/utils/type-utils.ts +9 -7
  507. package/src/utils/utils.ts +19 -21
  508. package/src/utils/zod-error.ts +4 -2
  509. package/src/vector/chunking.ts +6 -1
  510. package/src/vector/embedding.ts +2 -1
  511. package/src/vector/types.ts +4 -2
  512. package/tsdown.api.config.ts +5 -2
  513. package/dist/ui-web/assets/index-C0m1pk6K.js +0 -177
package/dist/ui/api.js CHANGED
@@ -1,18 +1,20 @@
1
1
  import { __esmMin } from "../_virtual/_rolldown/runtime.js";
2
+ import { init_runtime_value, isObjectValue } from "../utils/runtime-value.js";
2
3
  import { createKnexInstance, init_knex } from "../database/knex.js";
3
4
  import { DB, init_db } from "../database/db.js";
4
5
  import { init_utils, nonNullable } from "../utils/utils.js";
5
6
  import { SD, init_sd } from "../dict/sd.js";
6
7
  import { BadRequestException, ServiceUnavailableException, init_so_exceptions, isSoException } from "../exceptions/so-exceptions.js";
7
- import { Sonamu, init_sonamu } from "../api/sonamu.js";
8
8
  import { BUILT_IN_TYPE_IDS, TemplateKey, init_types } from "../types/types.js";
9
+ import { Sonamu, init_sonamu } from "../api/sonamu.js";
9
10
  import { EntityManager, init_entity_manager } from "../entity/entity-manager.js";
10
- import { FixtureManager, init_fixture_manager } from "../testing/fixture-manager.js";
11
11
  import { DataExplorer, init_data_explorer } from "../testing/data-explorer.js";
12
+ import { FixtureManager, init_fixture_manager } from "../testing/fixture-manager.js";
12
13
  import { FixtureGenerator, init_fixture_generator } from "../testing/fixture-generator.js";
13
14
  import { init_sonamu_dictionary, sonamuDictionary } from "../dict/sonamu-dictionary.js";
14
15
  import { TemplateManager, init_template_manager } from "../template/template-manager.js";
15
16
  import { init_ai_api, setAiApi } from "./ai-api.js";
17
+ import { forwardAsyncErrors, init_async_route } from "./async-route.js";
16
18
  import { addRule, editContent, getAcList, getCddTree, init_cdd_service, listRules, openSourceFile, readContent, readRule } from "./cdd-service.js";
17
19
  import { init_migrations_api, registerMigrationsApi } from "./migrations-api.js";
18
20
  import inflection from "inflection";
@@ -21,30 +23,36 @@ import fs from "fs";
21
23
  import path from "path";
22
24
  import { execFileSync, execSync } from "child_process";
23
25
  //#region src/ui/api.ts
26
+ async function waitForHMRCompleted(fn) {
27
+ const waitPromise = new Promise((resolve) => {
28
+ const handler = () => {
29
+ clearTimeout(timeout);
30
+ resolve();
31
+ };
32
+ const timeout = setTimeout(() => {
33
+ Sonamu.syncer.eventEmitter.off("onHMRCompleted", handler);
34
+ resolve();
35
+ }, 1500);
36
+ Sonamu.syncer.eventEmitter.once("onHMRCompleted", handler);
37
+ });
38
+ const result = await fn();
39
+ await waitPromise;
40
+ return result;
41
+ }
42
+ function flattenSubsetRows(subsetRows) {
43
+ return subsetRows.flatMap((subsetRow) => {
44
+ const { children, ...sRow } = subsetRow;
45
+ return [sRow, ...flattenSubsetRows(children)];
46
+ });
47
+ }
24
48
  async function sonamuUIApiPlugin(fastify) {
25
49
  fastify.register(async (server) => {
26
- async function waitForHMRCompleted(fn) {
27
- const waitPromise = new Promise((resolve) => {
28
- const handler = () => {
29
- clearTimeout(timeout);
30
- resolve();
31
- };
32
- const timeout = setTimeout(() => {
33
- Sonamu.syncer.eventEmitter.off("onHMRCompleted", handler);
34
- resolve();
35
- }, 1500);
36
- Sonamu.syncer.eventEmitter.once("onHMRCompleted", handler);
37
- });
38
- const result = await fn();
39
- await waitPromise;
40
- return result;
41
- }
42
50
  await setAiApi(server);
43
51
  await registerMigrationsApi(server);
44
52
  server.get("/api/sonamu/config", async () => {
45
53
  return Sonamu.config;
46
54
  });
47
- server.get("/api/tools/openVscode", async (request) => {
55
+ server.get("/api/tools/openVscode", (request) => forwardAsyncErrors(async () => {
48
56
  const { entityId, preset, absPath } = request.query;
49
57
  execSync(`code ${(() => {
50
58
  if (entityId && preset) {
@@ -64,8 +72,8 @@ async function sonamuUIApiPlugin(fastify) {
64
72
  return absPath;
65
73
  }
66
74
  })()}`);
67
- });
68
- server.get("/api/tools/openEditor", async (request) => {
75
+ }));
76
+ server.get("/api/tools/openEditor", (request) => forwardAsyncErrors(async () => {
69
77
  const command = {
70
78
  vscode: "code",
71
79
  cursor: "cursor",
@@ -73,8 +81,8 @@ async function sonamuUIApiPlugin(fastify) {
73
81
  }[request.query.editor];
74
82
  if (command === void 0) throw new BadRequestException(SD("error.badRequest"));
75
83
  execFileSync(command, [request.query.absPath]);
76
- });
77
- server.get("/api/tools/getSuggestion", async (request) => {
84
+ }));
85
+ server.get("/api/tools/getSuggestion", (request) => forwardAsyncErrors(async () => {
78
86
  const { origin, entityId } = request.query;
79
87
  const glossary = /* @__PURE__ */ new Map([
80
88
  ["status", "상태"],
@@ -124,15 +132,15 @@ async function sonamuUIApiPlugin(fastify) {
124
132
  ["expected", "예상"],
125
133
  ["actual", "실제"]
126
134
  ]);
127
- for (const entityId of EntityManager.getAllIds()) {
128
- const entity = EntityManager.get(entityId);
129
- if ((entity.title ?? "") !== "") {
130
- glossary.set(inflection.underscore(entity.id), entity.title);
131
- glossary.set(inflection.underscore(inflection.pluralize(entity.id)), `${entity.title}리스트`);
135
+ for (const glossaryEntityId of EntityManager.getAllIds()) {
136
+ const glossaryEntity = EntityManager.get(glossaryEntityId);
137
+ if ((glossaryEntity.title ?? "") !== "") {
138
+ glossary.set(inflection.underscore(glossaryEntity.id), glossaryEntity.title);
139
+ glossary.set(inflection.underscore(inflection.pluralize(glossaryEntity.id)), `${glossaryEntity.title}리스트`);
132
140
  }
133
- entity.props.forEach((prop) => {
141
+ glossaryEntity.props.forEach((prop) => {
134
142
  if (glossary.has(prop.name)) return;
135
- if (prop.desc) glossary.set(prop.name, prop.desc.replace(entity.title ?? "", "{EntityID}"));
143
+ if (prop.desc) glossary.set(prop.name, prop.desc.replace(glossaryEntity.title ?? "", "{EntityID}"));
136
144
  });
137
145
  }
138
146
  return { suggested: (() => {
@@ -156,15 +164,9 @@ async function sonamuUIApiPlugin(fastify) {
156
164
  else return r.toUpperCase();
157
165
  }).join("").replace(/{EntityID}/g, entityId ? EntityManager.get(entityId).title : "");
158
166
  })() };
159
- });
167
+ }));
160
168
  server.get("/api/entity/findMany", async () => {
161
169
  const entityIds = EntityManager.getAllIds();
162
- function flattenSubsetRows(subsetRows) {
163
- return subsetRows.flatMap((subsetRow) => {
164
- const { children, ...sRow } = subsetRow;
165
- return [sRow, ...flattenSubsetRows(children)];
166
- });
167
- }
168
170
  const entities = await Promise.all(entityIds.map((entityId) => {
169
171
  const entity = EntityManager.get(entityId);
170
172
  const subsetRows = entity.getSubsetRows();
@@ -188,11 +190,14 @@ async function sonamuUIApiPlugin(fastify) {
188
190
  });
189
191
  return { entities };
190
192
  });
191
- server.get("/api/entity/typeIds", async (request) => {
193
+ server.get("/api/entity/typeIds", (request) => forwardAsyncErrors(async () => {
192
194
  const { filter, reload } = request.query;
193
195
  if (reload === "1") await Sonamu.syncer.autoloadTypes();
194
196
  return { typeIds: (() => {
195
- const projectTypeIds = Object.entries(Sonamu.syncer.types).filter(([_typeId, zodType]) => zodType._zod.def.type !== "enum").map(([typeId, _zodType]) => typeId);
197
+ const projectTypeIds = Object.entries(Sonamu.syncer.types).filter(([_typeId, zodType]) => {
198
+ const { _zod: zodMetadata } = zodType;
199
+ return zodMetadata.def.type !== "enum";
200
+ }).map(([typeId, _zodType]) => typeId);
196
201
  const allTypeIds = [...[...BUILT_IN_TYPE_IDS], ...projectTypeIds];
197
202
  if (filter === "types") return allTypeIds;
198
203
  const enumIds = EntityManager.getAllIds().flatMap((entityId) => {
@@ -202,8 +207,8 @@ async function sonamuUIApiPlugin(fastify) {
202
207
  if (filter === "enums") return enumIds;
203
208
  else return [...allTypeIds, ...enumIds];
204
209
  })() };
205
- });
206
- server.post("/api/entity/create", async (request) => {
210
+ }));
211
+ server.post("/api/entity/create", (request) => forwardAsyncErrors(async () => {
207
212
  return await waitForHMRCompleted(async () => {
208
213
  const { form } = request.body;
209
214
  await Sonamu.syncer.createEntity({
@@ -212,14 +217,14 @@ async function sonamuUIApiPlugin(fastify) {
212
217
  });
213
218
  return 1;
214
219
  });
215
- });
216
- server.post("/api/entity/del", async (request) => {
220
+ }));
221
+ server.post("/api/entity/del", (request) => forwardAsyncErrors(async () => {
217
222
  return await waitForHMRCompleted(async () => {
218
223
  const { entityId } = request.body;
219
224
  return await Sonamu.syncer.delEntity(entityId);
220
225
  });
221
- });
222
- server.post("/api/entity/modifyEntityBase", async (request) => {
226
+ }));
227
+ server.post("/api/entity/modifyEntityBase", (request) => forwardAsyncErrors(async () => {
223
228
  return await waitForHMRCompleted(async () => {
224
229
  const { entityId, newValues } = request.body;
225
230
  const entity = EntityManager.get(entityId);
@@ -229,8 +234,8 @@ async function sonamuUIApiPlugin(fastify) {
229
234
  await entity.save();
230
235
  return 1;
231
236
  });
232
- });
233
- server.post("/api/entity/modifySubset", async (request) => {
237
+ }));
238
+ server.post("/api/entity/modifySubset", (request) => forwardAsyncErrors(async () => {
234
239
  return await waitForHMRCompleted(async () => {
235
240
  const { entityId, subsetKey, fields, fieldsInternal } = request.body;
236
241
  const entity = EntityManager.get(entityId);
@@ -243,8 +248,8 @@ async function sonamuUIApiPlugin(fastify) {
243
248
  updatedInternal: fieldsInternal
244
249
  };
245
250
  });
246
- });
247
- server.post("/api/entity/delSubset", async (request) => {
251
+ }));
252
+ server.post("/api/entity/delSubset", (request) => forwardAsyncErrors(async () => {
248
253
  return await waitForHMRCompleted(async () => {
249
254
  const { entityId, subsetKey } = request.body;
250
255
  const entity = EntityManager.get(entityId);
@@ -253,36 +258,36 @@ async function sonamuUIApiPlugin(fastify) {
253
258
  await entity.save();
254
259
  return 1;
255
260
  });
256
- });
257
- server.post("/api/entity/createProp", async (request) => {
261
+ }));
262
+ server.post("/api/entity/createProp", (request) => forwardAsyncErrors(async () => {
258
263
  return await waitForHMRCompleted(async () => {
259
264
  const { entityId, at, newProp } = request.body;
260
265
  await EntityManager.get(entityId).createProp(newProp, at);
261
266
  return true;
262
267
  });
263
- });
264
- server.post("/api/entity/modifyProp", async (request) => {
268
+ }));
269
+ server.post("/api/entity/modifyProp", (request) => forwardAsyncErrors(async () => {
265
270
  return await waitForHMRCompleted(async () => {
266
271
  const { entityId, at, newProp } = request.body;
267
272
  EntityManager.get(entityId).modifyProp(newProp, at);
268
273
  return true;
269
274
  });
270
- });
271
- server.post("/api/entity/delProp", async (request) => {
275
+ }));
276
+ server.post("/api/entity/delProp", (request) => forwardAsyncErrors(async () => {
272
277
  return await waitForHMRCompleted(async () => {
273
278
  const { entityId, at } = request.body;
274
279
  EntityManager.get(entityId).delProp(at);
275
280
  return true;
276
281
  });
277
- });
278
- server.post("/api/entity/moveProp", async (request) => {
282
+ }));
283
+ server.post("/api/entity/moveProp", (request) => forwardAsyncErrors(async () => {
279
284
  return await waitForHMRCompleted(async () => {
280
285
  const { entityId, at, to } = request.body;
281
286
  EntityManager.get(entityId).moveProp(at, to);
282
287
  return true;
283
288
  });
284
- });
285
- server.post("/api/entity/modifyIndexes", async (request) => {
289
+ }));
290
+ server.post("/api/entity/modifyIndexes", (request) => forwardAsyncErrors(async () => {
286
291
  return await waitForHMRCompleted(async () => {
287
292
  const { entityId, indexes } = request.body;
288
293
  const entity = EntityManager.get(entityId);
@@ -290,8 +295,8 @@ async function sonamuUIApiPlugin(fastify) {
290
295
  await entity.save();
291
296
  return { updated: indexes };
292
297
  });
293
- });
294
- server.post("/api/entity/modifyEnumLabels", async (request) => {
298
+ }));
299
+ server.post("/api/entity/modifyEnumLabels", (request) => forwardAsyncErrors(async () => {
295
300
  return await waitForHMRCompleted(async () => {
296
301
  const { entityId, enumLabels } = request.body;
297
302
  const entity = EntityManager.get(entityId);
@@ -299,8 +304,8 @@ async function sonamuUIApiPlugin(fastify) {
299
304
  await entity.save();
300
305
  return { updated: enumLabels };
301
306
  });
302
- });
303
- server.post("/api/entity/createEnumId", async (request) => {
307
+ }));
308
+ server.post("/api/entity/createEnumId", (request) => forwardAsyncErrors(async () => {
304
309
  return await waitForHMRCompleted(async () => {
305
310
  const { entityId, newEnumId } = request.body;
306
311
  const entity = EntityManager.get(entityId);
@@ -312,36 +317,36 @@ async function sonamuUIApiPlugin(fastify) {
312
317
  await entity.save();
313
318
  return 1;
314
319
  });
315
- });
316
- server.post("/api/entity/modifyEnumId", async (request) => {
320
+ }));
321
+ server.post("/api/entity/modifyEnumId", (request) => forwardAsyncErrors(async () => {
317
322
  return await waitForHMRCompleted(async () => {
318
323
  const { entityId, enumId } = request.body;
319
324
  const entityIds = EntityManager.getAllIds();
320
- if (entityIds.some((entityId) => {
321
- const entity = EntityManager.get(entityId);
322
- return Object.keys(entity.enumLabels).includes(enumId.after);
325
+ if (entityIds.some((candidateEntityId) => {
326
+ const candidateEntity = EntityManager.get(candidateEntityId);
327
+ return Object.keys(candidateEntity.enumLabels).includes(enumId.after);
323
328
  })) throw new Error(`이미 존재하는 EnumId입니다: ${enumId.after}`);
324
329
  const entity = EntityManager.get(entityId);
325
330
  entity.enumLabels[enumId.after] = entity.enumLabels[enumId.before];
326
331
  delete entity.enumLabels[enumId.before];
327
332
  await entity.save();
328
- for (const entityId of entityIds) {
329
- const entity = EntityManager.get(entityId);
330
- for (const prop of entity.props) if (prop.type === "enum" && prop.id === enumId.before) prop.id = enumId.after;
331
- await entity.save();
333
+ for (const relatedEntityId of entityIds) {
334
+ const relatedEntity = EntityManager.get(relatedEntityId);
335
+ for (const prop of relatedEntity.props) if (prop.type === "enum" && prop.id === enumId.before) prop.id = enumId.after;
336
+ await relatedEntity.save();
332
337
  }
333
338
  });
334
- });
335
- server.post("/api/entity/deleteEnumId", async (request) => {
339
+ }));
340
+ server.post("/api/entity/deleteEnumId", (request) => forwardAsyncErrors(async () => {
336
341
  return await waitForHMRCompleted(async () => {
337
342
  const { entityId, enumId } = request.body;
338
- if (EntityManager.getAllIds().flatMap((entityId) => EntityManager.get(entityId).props).some((prop) => prop.type === "enum" && prop.id === enumId)) throw new Error(`${enumId}를 참조하는 프로퍼티가 존재합니다.`);
343
+ if (EntityManager.getAllIds().flatMap((referencingEntityId) => EntityManager.get(referencingEntityId).props).some((prop) => prop.type === "enum" && prop.id === enumId)) throw new Error(`${enumId}를 참조하는 프로퍼티가 존재합니다.`);
339
344
  const entity = EntityManager.get(entityId);
340
345
  delete entity.enumLabels[enumId];
341
346
  await entity.save();
342
347
  });
343
- });
344
- server.post("/api/entity/updateCone", async (request) => {
348
+ }));
349
+ server.post("/api/entity/updateCone", (request) => forwardAsyncErrors(async () => {
345
350
  return await waitForHMRCompleted(async () => {
346
351
  const { entityId, target, propName, enumId, subsetKey, cone } = request.body;
347
352
  const entity = EntityManager.get(entityId);
@@ -354,7 +359,7 @@ async function sonamuUIApiPlugin(fastify) {
354
359
  await entity.save();
355
360
  return true;
356
361
  });
357
- });
362
+ }));
358
363
  server.post("/api/entity/generateCones", async (request, reply) => {
359
364
  return await waitForHMRCompleted(async () => {
360
365
  const { entityId, preserveExisting, onlyEmpty, locale } = request.body;
@@ -397,11 +402,11 @@ async function sonamuUIApiPlugin(fastify) {
397
402
  }
398
403
  });
399
404
  });
400
- server.get("/api/entity/getTableColumns", async (request) => {
405
+ server.get("/api/entity/getTableColumns", (request) => forwardAsyncErrors(async () => {
401
406
  const { entityId } = request.query;
402
407
  return { columns: EntityManager.get(entityId).getTableColumns() };
403
- });
404
- server.post("/api/scaffolding/getStatus", async (request) => {
408
+ }));
409
+ server.post("/api/scaffolding/getStatus", (request) => forwardAsyncErrors(async () => {
405
410
  const { entityIds, templateKeys: _templateKeys } = request.body;
406
411
  if ((entityIds ?? []).length === 0) throw new BadRequestException(SD("sonamu.error.entityIdsRequired"));
407
412
  else if ((_templateKeys ?? []).length === 0) throw new BadRequestException(SD("sonamu.error.templateKeysRequired"));
@@ -420,8 +425,8 @@ async function sonamuUIApiPlugin(fastify) {
420
425
  isExists
421
426
  };
422
427
  })) };
423
- });
424
- server.post("/api/scaffolding/generate", async (request) => {
428
+ }));
429
+ server.post("/api/scaffolding/generate", (request) => forwardAsyncErrors(async () => {
425
430
  const { options } = request.body;
426
431
  if (options.length === 0) throw new BadRequestException(SD("sonamu.error.optionsRequired"));
427
432
  const keys = options.flatMap(({ templateKey }) => {
@@ -444,8 +449,8 @@ async function sonamuUIApiPlugin(fastify) {
444
449
  }));
445
450
  if (result.filter(nonNullable).length === 0) throw new ServiceUnavailableException(SD("sonamu.error.allFilesGenerated"));
446
451
  return result;
447
- });
448
- server.post("/api/scaffolding/preview", async (request) => {
452
+ }));
453
+ server.post("/api/scaffolding/preview", (request) => forwardAsyncErrors(async () => {
449
454
  const { option } = request.body;
450
455
  try {
451
456
  const { templateKey, ...templateOptions } = option;
@@ -454,19 +459,19 @@ async function sonamuUIApiPlugin(fastify) {
454
459
  console.error(e);
455
460
  throw e;
456
461
  }
457
- });
458
- server.post("/api/fixture", async (request) => {
462
+ }));
463
+ server.post("/api/fixture", (request) => forwardAsyncErrors(async () => {
459
464
  const { sourceDB, targetDB, search, duplicateCheck } = request.body;
460
465
  return FixtureManager.getFixtures(sourceDB, targetDB, search, duplicateCheck);
461
- });
462
- server.post("/api/fixture/import", async (request) => {
466
+ }));
467
+ server.post("/api/fixture/import", (request) => forwardAsyncErrors(async () => {
463
468
  const { db, fixtures } = request.body;
464
469
  return FixtureManager.insertFixtures(db, fixtures);
465
- });
466
- server.post("/api/fixture/addFixtureLoader", async (request) => {
470
+ }));
471
+ server.post("/api/fixture/addFixtureLoader", (request) => forwardAsyncErrors(async () => {
467
472
  const { code } = request.body;
468
473
  return FixtureManager.addFixtureLoader(code);
469
- });
474
+ }));
470
475
  server.get("/api/i18n/dictionary", async () => {
471
476
  return sonamuDictionary.getDictionary();
472
477
  });
@@ -474,27 +479,27 @@ async function sonamuUIApiPlugin(fastify) {
474
479
  const { filename, buffer } = await sonamuDictionary.exportToExcel();
475
480
  reply.header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet").header("Content-Disposition", `attachment; filename="${filename}"`).send(buffer);
476
481
  });
477
- server.post("/api/i18n/import", async (request) => {
482
+ server.post("/api/i18n/import", (request) => forwardAsyncErrors(async () => {
478
483
  const data = await request.file();
479
484
  if (!data) throw new BadRequestException(SD("sonamu.error.fileNotUploaded"));
480
485
  const buffer = await data.toBuffer();
481
486
  return sonamuDictionary.importFromExcel(buffer);
482
- });
483
- server.post("/api/i18n/update", async (request) => {
487
+ }));
488
+ server.post("/api/i18n/update", (request) => forwardAsyncErrors(async () => {
484
489
  await sonamuDictionary.updateEntry(request.body);
485
490
  return { success: true };
486
- });
487
- server.post("/api/i18n/create", async (request) => {
491
+ }));
492
+ server.post("/api/i18n/create", (request) => forwardAsyncErrors(async () => {
488
493
  await sonamuDictionary.createEntry(request.body);
489
494
  return { success: true };
490
- });
491
- server.post("/api/i18n/delete", async (request) => {
495
+ }));
496
+ server.post("/api/i18n/delete", (request) => forwardAsyncErrors(async () => {
492
497
  await sonamuDictionary.deleteEntry(request.body.key);
493
498
  return { success: true };
494
- });
495
- server.post("/api/i18n/checkUsage", async (request) => {
499
+ }));
500
+ server.post("/api/i18n/checkUsage", (request) => forwardAsyncErrors(async () => {
496
501
  return sonamuDictionary.checkUsage(request.body.keys);
497
- });
502
+ }));
498
503
  server.get("/api/tasks/status", async () => {
499
504
  try {
500
505
  Sonamu.workflows;
@@ -506,7 +511,7 @@ async function sonamuUIApiPlugin(fastify) {
506
511
  server.get("/api/tasks/workflowDefinitions", async () => {
507
512
  return { definitions: Sonamu.workflows.workflowDefinitions };
508
513
  });
509
- server.get("/api/tasks/workflowRuns", async (request) => {
514
+ server.get("/api/tasks/workflowRuns", (request) => forwardAsyncErrors(async () => {
510
515
  const backend = Sonamu.workflows.backend;
511
516
  const { limit, after, before, order, status, workflowName, createdAfter, createdBefore } = request.query;
512
517
  return backend.listWorkflowRuns({
@@ -519,22 +524,22 @@ async function sonamuUIApiPlugin(fastify) {
519
524
  createdAfter: createdAfter ? new Date(createdAfter) : void 0,
520
525
  createdBefore: createdBefore ? new Date(createdBefore) : void 0
521
526
  });
522
- });
523
- server.get("/api/tasks/workflowRuns/:id", async (request) => {
527
+ }));
528
+ server.get("/api/tasks/workflowRuns/:id", (request) => forwardAsyncErrors(async () => {
524
529
  const workflowRun = await Sonamu.workflows.backend.getWorkflowRun({ workflowRunId: request.params.id });
525
530
  if (!workflowRun) throw new Error(`Workflow run not found: ${request.params.id}`);
526
531
  return workflowRun;
527
- });
528
- server.post("/api/tasks/workflowRuns/:id/cancel", async (request) => {
532
+ }));
533
+ server.post("/api/tasks/workflowRuns/:id/cancel", (request) => forwardAsyncErrors(async () => {
529
534
  return Sonamu.workflows.backend.cancelWorkflowRun({ workflowRunId: request.params.id });
530
- });
531
- server.post("/api/tasks/workflowRuns/:id/pause", async (request) => {
535
+ }));
536
+ server.post("/api/tasks/workflowRuns/:id/pause", (request) => forwardAsyncErrors(async () => {
532
537
  return Sonamu.workflows.backend.pauseWorkflowRun({ workflowRunId: request.params.id });
533
- });
534
- server.post("/api/tasks/workflowRuns/:id/resume", async (request) => {
538
+ }));
539
+ server.post("/api/tasks/workflowRuns/:id/resume", (request) => forwardAsyncErrors(async () => {
535
540
  return Sonamu.workflows.backend.resumeWorkflowRun({ workflowRunId: request.params.id });
536
- });
537
- server.get("/api/tasks/workflowRuns/:id/steps", async (request) => {
541
+ }));
542
+ server.get("/api/tasks/workflowRuns/:id/steps", (request) => forwardAsyncErrors(async () => {
538
543
  const backend = Sonamu.workflows.backend;
539
544
  const { limit, after, before } = request.query;
540
545
  return backend.listStepAttempts({
@@ -543,21 +548,21 @@ async function sonamuUIApiPlugin(fastify) {
543
548
  after,
544
549
  before
545
550
  });
546
- });
551
+ }));
547
552
  /**
548
553
  * Health Check API
549
554
  * MCP 도구가 Sonamu 서버를 자동 감지하기 위한 엔드포인트
550
555
  */
551
- server.get("/api/sonamu/health", async (request) => {
556
+ server.get("/api/sonamu/health", (request) => forwardAsyncErrors(async () => {
552
557
  const address = request.server.server.address();
553
- const port = address && typeof address === "object" ? address.port : 0;
558
+ const port = address && isObjectValue(address) ? address.port : 0;
554
559
  return {
555
560
  ok: true,
556
561
  project: process.cwd().split("/").pop() || "unknown",
557
562
  port,
558
563
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
559
564
  };
560
- });
565
+ }));
561
566
  /**
562
567
  * Fixture 생성 API
563
568
  */
@@ -679,29 +684,29 @@ async function sonamuUIApiPlugin(fastify) {
679
684
  server.get("/api/cdd/tree", async () => {
680
685
  return getCddTree();
681
686
  });
682
- server.post("/api/cdd/readContent", async (request) => {
687
+ server.post("/api/cdd/readContent", (request) => forwardAsyncErrors(async () => {
683
688
  const { filePath } = request.body;
684
689
  return readContent(filePath);
685
- });
686
- server.post("/api/cdd/editContent", async (request) => {
690
+ }));
691
+ server.post("/api/cdd/editContent", (request) => forwardAsyncErrors(async () => {
687
692
  const { filePath } = request.body;
688
693
  return editContent(filePath);
689
- });
690
- server.post("/api/cdd/openSource", async (request) => {
694
+ }));
695
+ server.post("/api/cdd/openSource", (request) => forwardAsyncErrors(async () => {
691
696
  const { filePath } = request.body;
692
697
  openSourceFile(filePath);
693
698
  return { success: true };
694
- });
699
+ }));
695
700
  server.get("/api/cdd/rules", async () => {
696
701
  return listRules();
697
702
  });
698
- server.post("/api/cdd/readRule", async (request) => {
703
+ server.post("/api/cdd/readRule", (request) => forwardAsyncErrors(async () => {
699
704
  const { ruleKey } = request.body;
700
705
  return readRule(ruleKey);
701
- });
702
- server.post("/api/cdd/addRule", async (request) => {
706
+ }));
707
+ server.post("/api/cdd/addRule", (request) => forwardAsyncErrors(async () => {
703
708
  return addRule(request.body);
704
- });
709
+ }));
705
710
  server.get("/api/cdd/ac", async () => {
706
711
  return getAcList();
707
712
  });
@@ -731,11 +736,13 @@ __esmMin((() => {
731
736
  init_fixture_generator();
732
737
  init_fixture_manager();
733
738
  init_types();
739
+ init_runtime_value();
734
740
  init_utils();
735
741
  init_ai_api();
742
+ init_async_route();
736
743
  init_cdd_service();
737
744
  init_migrations_api();
738
745
  }))();
739
746
  export { sonamuUIApiPlugin };
740
747
 
741
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91aS9hcGkudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhlY0ZpbGVTeW5jLCBleGVjU3luYyB9IGZyb20gXCJjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5pbXBvcnQgeyB0eXBlIEZhc3RpZnlJbnN0YW5jZSB9IGZyb20gXCJmYXN0aWZ5XCI7XG5pbXBvcnQgaW5mbGVjdGlvbiBmcm9tIFwiaW5mbGVjdGlvblwiO1xuaW1wb3J0IHsgcmFuZ2UgfSBmcm9tIFwicmFkYXNoaVwiO1xuXG5pbXBvcnQgeyBTb25hbXUgfSBmcm9tIFwiLi4vYXBpL3NvbmFtdVwiO1xuaW1wb3J0IHsgREIgfSBmcm9tIFwiLi4vZGF0YWJhc2UvZGJcIjtcbmltcG9ydCB7IHR5cGUgU29uYW11REJDb25maWcgfSBmcm9tIFwiLi4vZGF0YWJhc2UvZGJcIjtcbmltcG9ydCB7IGNyZWF0ZUtuZXhJbnN0YW5jZSB9IGZyb20gXCIuLi9kYXRhYmFzZS9rbmV4XCI7XG5pbXBvcnQgeyBTRCB9IGZyb20gXCIuLi9kaWN0L3NkXCI7XG5pbXBvcnQgeyBzb25hbXVEaWN0aW9uYXJ5IH0gZnJvbSBcIi4uL2RpY3Qvc29uYW11LWRpY3Rpb25hcnlcIjtcbmltcG9ydCB7IHR5cGUgRW50aXR5IH0gZnJvbSBcIi4uL2VudGl0eS9lbnRpdHlcIjtcbmltcG9ydCB7IEVudGl0eU1hbmFnZXIgfSBmcm9tIFwiLi4vZW50aXR5L2VudGl0eS1tYW5hZ2VyXCI7XG5pbXBvcnQge1xuICBCYWRSZXF1ZXN0RXhjZXB0aW9uLFxuICBpc1NvRXhjZXB0aW9uLFxuICBTZXJ2aWNlVW5hdmFpbGFibGVFeGNlcHRpb24sXG59IGZyb20gXCIuLi9leGNlcHRpb25zL3NvLWV4Y2VwdGlvbnNcIjtcbmltcG9ydCB7IFRlbXBsYXRlTWFuYWdlciB9IGZyb20gXCIuLi90ZW1wbGF0ZS90ZW1wbGF0ZS1tYW5hZ2VyXCI7XG5pbXBvcnQgeyBEYXRhRXhwbG9yZXIgfSBmcm9tIFwiLi4vdGVzdGluZy9kYXRhLWV4cGxvcmVyXCI7XG5pbXBvcnQgeyBGaXh0dXJlR2VuZXJhdG9yIH0gZnJvbSBcIi4uL3Rlc3RpbmcvZml4dHVyZS1nZW5lcmF0b3JcIjtcbmltcG9ydCB7IEZpeHR1cmVNYW5hZ2VyIH0gZnJvbSBcIi4uL3Rlc3RpbmcvZml4dHVyZS1tYW5hZ2VyXCI7XG5pbXBvcnQgeyB0eXBlIER1cGxpY2F0ZUNoZWNrT3B0aW9ucyB9IGZyb20gXCIuLi90ZXN0aW5nL2ZpeHR1cmUtbWFuYWdlclwiO1xuaW1wb3J0IHsgQlVJTFRfSU5fVFlQRV9JRFMsIFRlbXBsYXRlS2V5IH0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQge1xuICB0eXBlIENvbmUsXG4gIHR5cGUgRW50aXR5SW5kZXgsXG4gIHR5cGUgRW50aXR5UHJvcCxcbiAgdHlwZSBFbnRpdHlTdWJzZXRSb3csXG4gIHR5cGUgRml4dHVyZVJlY29yZCxcbiAgdHlwZSBGaXh0dXJlU2VhcmNoT3B0aW9ucyxcbiAgdHlwZSBGbGF0dGVuU3Vic2V0Um93LFxuICB0eXBlIFBhdGhBbmRDb2RlLFxufSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IG5vbk51bGxhYmxlIH0gZnJvbSBcIi4uL3V0aWxzL3V0aWxzXCI7XG5pbXBvcnQgeyBzZXRBaUFwaSB9IGZyb20gXCIuL2FpLWFwaVwiO1xuaW1wb3J0IHsgdHlwZSBDZGRBZGRSdWxlUmVxdWVzdCB9IGZyb20gXCIuL2NkZC1zZXJ2aWNlXCI7XG5pbXBvcnQge1xuICBhZGRSdWxlLFxuICBlZGl0Q29udGVudCxcbiAgZ2V0QWNMaXN0LFxuICBnZXRDZGRUcmVlLFxuICBsaXN0UnVsZXMsXG4gIG9wZW5Tb3VyY2VGaWxlLFxuICByZWFkQ29udGVudCxcbiAgcmVhZFJ1bGUsXG59IGZyb20gXCIuL2NkZC1zZXJ2aWNlXCI7XG5pbXBvcnQgeyByZWdpc3Rlck1pZ3JhdGlvbnNBcGkgfSBmcm9tIFwiLi9taWdyYXRpb25zLWFwaVwiO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc29uYW11VUlBcGlQbHVnaW4oZmFzdGlmeTogRmFzdGlmeUluc3RhbmNlKSB7XG4gIGZhc3RpZnkucmVnaXN0ZXIoXG4gICAgYXN5bmMgKHNlcnZlcikgPT4ge1xuICAgICAgLy8gd2FpdEZvckhNUkNvbXBsZXRlZFxuICAgICAgYXN5bmMgZnVuY3Rpb24gd2FpdEZvckhNUkNvbXBsZXRlZDxUPihmbjogKCkgPT4gUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICAgICAgICBjb25zdCB3YWl0UHJvbWlzZSA9IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgY29uc3QgaGFuZGxlciA9ICgpID0+IHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgU29uYW11LnN5bmNlci5ldmVudEVtaXR0ZXIub2ZmKFwib25ITVJDb21wbGV0ZWRcIiwgaGFuZGxlcik7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgfSwgMTUwMCk7XG5cbiAgICAgICAgICBTb25hbXUuc3luY2VyLmV2ZW50RW1pdHRlci5vbmNlKFwib25ITVJDb21wbGV0ZWRcIiwgaGFuZGxlcik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZuKCk7XG4gICAgICAgIGF3YWl0IHdhaXRQcm9taXNlO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBzZXRBaUFwaShzZXJ2ZXIpO1xuICAgICAgYXdhaXQgcmVnaXN0ZXJNaWdyYXRpb25zQXBpKHNlcnZlcik7XG5cbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL3NvbmFtdS9jb25maWdcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgICByZXR1cm4gU29uYW11LmNvbmZpZztcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIuZ2V0PHtcbiAgICAgICAgUXVlcnlzdHJpbmc6IHtcbiAgICAgICAgICBlbnRpdHlJZD86IHN0cmluZztcbiAgICAgICAgICBwcmVzZXQ/OiBcInR5cGVzXCIgfCBcImVudGl0eS5qc29uXCIgfCBcImdlbmVyYXRlZFwiO1xuICAgICAgICAgIGFic1BhdGg/OiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvdG9vbHMvb3BlblZzY29kZVwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBwcmVzZXQsIGFic1BhdGggfSA9IHJlcXVlc3QucXVlcnk7XG5cbiAgICAgICAgY29uc3QgdGFyZ2V0UGF0aCA9ICgoKSA9PiB7XG4gICAgICAgICAgaWYgKGVudGl0eUlkICYmIHByZXNldCkge1xuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgICAgY29uc3QgeyBuYW1lcyB9ID0gZW50aXR5O1xuXG4gICAgICAgICAgICBjb25zdCB7IGFwaVJvb3RQYXRoIH0gPSBTb25hbXU7XG4gICAgICAgICAgICBjb25zdCBmaWxlbmFtZSA9ICgoKSA9PiB7XG4gICAgICAgICAgICAgIHN3aXRjaCAocHJlc2V0KSB7XG4gICAgICAgICAgICAgICAgY2FzZSBcInR5cGVzXCI6XG4gICAgICAgICAgICAgICAgICByZXR1cm4gYCR7bmFtZXMuZnN9LnR5cGVzLnRzYDtcbiAgICAgICAgICAgICAgICBjYXNlIFwiZW50aXR5Lmpzb25cIjpcbiAgICAgICAgICAgICAgICAgIHJldHVybiBgJHtuYW1lcy5mc30uZW50aXR5Lmpzb25gO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJnZW5lcmF0ZWRcIjpcbiAgICAgICAgICAgICAgICAgIHJldHVybiBgJHtuYW1lcy5mc30uZ2VuZXJhdGVkLnRzYDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgICAgIHJldHVybiBgJHthcGlSb290UGF0aH0vc3JjL2FwcGxpY2F0aW9uLyR7ZW50aXR5Lm5hbWVzLnBhcmVudEZzfS8ke2ZpbGVuYW1lfWA7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmICghYWJzUGF0aCkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihTRChcInNvbmFtdS5lcnJvci5wcmVzZXRPckFic1BhdGhSZXF1aXJlZFwiKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gYWJzUGF0aDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pKCk7XG4gICAgICAgIGV4ZWNTeW5jKGBjb2RlICR7dGFyZ2V0UGF0aH1gKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIuZ2V0PHtcbiAgICAgICAgUXVlcnlzdHJpbmc6IHtcbiAgICAgICAgICBlZGl0b3I6IFwidnNjb2RlXCIgfCBcImN1cnNvclwiIHwgXCJ6ZWRcIjtcbiAgICAgICAgICBhYnNQYXRoOiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvdG9vbHMvb3BlbkVkaXRvclwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCBjb21tYW5kcyA9IHtcbiAgICAgICAgICB2c2NvZGU6IFwiY29kZVwiLFxuICAgICAgICAgIGN1cnNvcjogXCJjdXJzb3JcIixcbiAgICAgICAgICB6ZWQ6IFwiemVkXCIsXG4gICAgICAgIH0gYXMgY29uc3Q7XG4gICAgICAgIGNvbnN0IGNvbW1hbmQgPSBjb21tYW5kc1tyZXF1ZXN0LnF1ZXJ5LmVkaXRvcl07XG4gICAgICAgIGlmIChjb21tYW5kID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihTRChcImVycm9yLmJhZFJlcXVlc3RcIikpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8g7IW47J2EIOqxsOy5mOyngCDslYrslYQg7YyM7J28IOqyveuhnOqwgCDrqoXroLnsnLzroZwg7ZW07ISd65CY7KeAIOyViuuPhOuhnSDtlanri4jri6QuXG4gICAgICAgIGV4ZWNGaWxlU3luYyhjb21tYW5kLCBbcmVxdWVzdC5xdWVyeS5hYnNQYXRoXSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldDx7XG4gICAgICAgIFF1ZXJ5c3RyaW5nOiB7XG4gICAgICAgICAgb3JpZ2luOiBzdHJpbmc7XG4gICAgICAgICAgZW50aXR5SWQ/OiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvdG9vbHMvZ2V0U3VnZ2VzdGlvblwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCB7IG9yaWdpbiwgZW50aXR5SWQgfSA9IHJlcXVlc3QucXVlcnk7XG5cbiAgICAgICAgLy8g7LmY7ZmYIOyaqeyWtOynkVxuICAgICAgICBjb25zdCBnbG9zc2FyeSA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KFtcbiAgICAgICAgICBbXCJzdGF0dXNcIiwgXCLsg4Htg5xcIl0sXG4gICAgICAgICAgW1widHlwZVwiLCBcIu2DgOyehVwiXSxcbiAgICAgICAgICBbXCJpbWFnZVwiLCBcIuydtOuvuOyngFwiXSxcbiAgICAgICAgICBbXCJpbWFnZXNcIiwgXCLsnbTrr7jsp4DrpqzsiqTtirhcIl0sXG4gICAgICAgICAgW1widXJsXCIsIFwiVVJMXCJdLFxuICAgICAgICAgIFtcImlkXCIsIFwiSURcIl0sXG4gICAgICAgICAgW1wibmFtZVwiLCBge0VudGl0eUlEfeuqhWBdLFxuICAgICAgICAgIFtcInRpdGxlXCIsIFwie0VudGl0eUlEfeuqhVwiXSxcbiAgICAgICAgICBbXCJwYXJlbnRcIiwgXCLsg4HsnIR7RW50aXR5SUR9XCJdLFxuICAgICAgICAgIFtcImRlc2NcIiwgXCLshKTrqoVcIl0sXG4gICAgICAgICAgW1wiYXRcIiwgXCLsnbzsi5xcIl0sXG4gICAgICAgICAgW1wiY3JlYXRlZFwiLCBcIuuTseuhnVwiXSxcbiAgICAgICAgICBbXCJ1cGRhdGVkXCIsIFwi7IiY7KCVXCJdLFxuICAgICAgICAgIFtcImRlbGV0ZWRcIiwgXCLsgq3soJxcIl0sXG4gICAgICAgICAgW1wiYnlcIiwgXCLsnKDsoIBcIl0sXG4gICAgICAgICAgW1wiZGF0ZVwiLCBcIuydvOyekFwiXSxcbiAgICAgICAgICBbXCJ0aW1lXCIsIFwi7Iuc6rCEXCJdLFxuICAgICAgICAgIFtcImtvXCIsIFwiKO2VnOq4gClcIl0sXG4gICAgICAgICAgW1wiZW5cIiwgXCIo7JiB66y4KVwiXSxcbiAgICAgICAgICBbXCJrcndcIiwgXCIo7JuQKVwiXSxcbiAgICAgICAgICBbXCJ1c2RcIiwgXCIoVVNEKVwiXSxcbiAgICAgICAgICBbXCJjb2xvclwiLCBcIuy7rOufrFwiXSxcbiAgICAgICAgICBbXCJjb2RlXCIsIFwi7L2U65OcXCJdLFxuICAgICAgICAgIFtcInhcIiwgXCJY7KKM7ZGcXCJdLFxuICAgICAgICAgIFtcInlcIiwgXCJZ7KKM7ZGcXCJdLFxuICAgICAgICAgIFtcImN1cnJlbnRcIiwgXCLtmITsnqxcIl0sXG4gICAgICAgICAgW1wic3RvY2tcIiwgXCLsnqzqs6BcIl0sXG4gICAgICAgICAgW1widG90YWxcIiwgXCLstJ1cIl0sXG4gICAgICAgICAgW1wiYWRtaW5cIiwgXCLqtIDrpqzsnpBcIl0sXG4gICAgICAgICAgW1wiZ3JvdXBcIiwgXCLqt7jro7lcIl0sXG4gICAgICAgICAgW1wiaXRlbVwiLCBcIuyVhOydtO2FnFwiXSxcbiAgICAgICAgICBbXCJjbnRcIiwgXCLsiJjrn4lcIl0sXG4gICAgICAgICAgW1wicHJpY2VcIiwgXCLqsIDqsqlcIl0sXG4gICAgICAgICAgW1wicHJlc2V0XCIsIFwi7ZSE66as7IWLXCJdLFxuICAgICAgICAgIFtcImFjY3RcIiwgXCLqs4TsooxcIl0sXG4gICAgICAgICAgW1widGVsXCIsIFwi7KCE7ZmU67KI7Zi4XCJdLFxuICAgICAgICAgIFtcIm5vXCIsIFwi67KI7Zi4XCJdLFxuICAgICAgICAgIFtcImJvZHlcIiwgXCLrgrTsmqlcIl0sXG4gICAgICAgICAgW1wiY29udGVudFwiLCBcIuuCtOyaqVwiXSxcbiAgICAgICAgICBbXCJvcmRlcm5vXCIsIFwi7KCV66Cs7Iic7IScXCJdLFxuICAgICAgICAgIFtcInByaW9yaXR5XCIsIFwi7Jqw7ISg7Iic7JyEXCJdLFxuICAgICAgICAgIFtcInRleHRcIiwgXCLthY3siqTtirhcIl0sXG4gICAgICAgICAgW1wia2V5XCIsIFwi7YKkXCJdLFxuICAgICAgICAgIFtcInN1bVwiLCBcIu2VqeyCsFwiXSxcbiAgICAgICAgICBbXCJleHBlY3RlZFwiLCBcIuyYiOyDgVwiXSxcbiAgICAgICAgICBbXCJhY3R1YWxcIiwgXCLsi6TsoJxcIl0sXG4gICAgICAgIF0pO1xuICAgICAgICAvLyDsoITssrQg7JeU7Yuw7YuwIOyInO2ajO2VmOupsCwg7JeU7Yuw7YuwIO2DgOydtO2LgOqzvCDtlITroa0g7ISk66qF7J2EIOy5mO2ZmCDsmqnslrTsp5Hsl5Ag7LaU6rCAXG4gICAgICAgIGZvciAoY29uc3QgZW50aXR5SWQgb2YgRW50aXR5TWFuYWdlci5nZXRBbGxJZHMoKSkge1xuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICBpZiAoKGVudGl0eS50aXRsZSA/PyBcIlwiKSAhPT0gXCJcIikge1xuICAgICAgICAgICAgZ2xvc3Nhcnkuc2V0KGluZmxlY3Rpb24udW5kZXJzY29yZShlbnRpdHkuaWQpLCBlbnRpdHkudGl0bGUpO1xuICAgICAgICAgICAgZ2xvc3Nhcnkuc2V0KFxuICAgICAgICAgICAgICBpbmZsZWN0aW9uLnVuZGVyc2NvcmUoaW5mbGVjdGlvbi5wbHVyYWxpemUoZW50aXR5LmlkKSksXG4gICAgICAgICAgICAgIGAke2VudGl0eS50aXRsZX3rpqzsiqTtirhgLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBlbnRpdHkucHJvcHMuZm9yRWFjaCgocHJvcCkgPT4ge1xuICAgICAgICAgICAgaWYgKGdsb3NzYXJ5Lmhhcyhwcm9wLm5hbWUpKSB7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwcm9wLmRlc2MpIHtcbiAgICAgICAgICAgICAgZ2xvc3Nhcnkuc2V0KHByb3AubmFtZSwgcHJvcC5kZXNjLnJlcGxhY2UoZW50aXR5LnRpdGxlID8/IFwiXCIsIFwie0VudGl0eUlEfVwiKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzdWdnZXN0ZWQgPSAoKCkgPT4ge1xuICAgICAgICAgIC8vIOuLqOyWtCDrtoTrpqwsIOqwgOuKpe2VnCDsobDtlakg7IOd7ISxXG4gICAgICAgICAgY29uc3Qgd29yZHMgPSBvcmlnaW4uc3BsaXQoXCJfXCIpO1xuICAgICAgICAgIGNvbnN0IGNvbWJpbmF0aW9ucyA9IFsuLi5yYW5nZSh3b3Jkcy5sZW5ndGgsIDAsIC0xKV0uZmxhdE1hcCgobGVuKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICAuLi5yYW5nZSgwLCB3b3Jkcy5sZW5ndGggLSBsZW4gKyAxLCAoaWR4KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgIGxlbixcbiAgICAgICAgICAgICAgICAgIHc6IHdvcmRzLnNsaWNlKGlkeCwgaWR4ICsgbGVuKS5qb2luKFwiX1wiKSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAvLyDsobDtlansnYQg7Iic7ZqM7ZWY66mwLCDsuZjtmZgg7Jqp7Ja07KeR7JeQIOyeiOuKlCDri6jslrTqsIAg7Y+s7ZWo65CcIOqyveyasCwg7LmY7ZmYIOyaqeyWtOuhnCDsuZjtmZhcbiAgICAgICAgICBjb25zdCBSRVBMQUNFRF9QUkVGSVggPSBcIiNSRVBMQUNFRC8vXCI7IC8vIOy5mO2ZmOuQnCDri6jslrTrpbwgam9pbiDsnbTtm4Tsl5Drj4Qg7Iud67OE7ZWY6riwIOychO2VtCBwcmVmaXgg7LaU6rCAXG4gICAgICAgICAgbGV0IHJlbWFpbkFycjogc3RyaW5nW10gPSBbLi4ud29yZHNdO1xuICAgICAgICAgIGZvciAoY29uc3QgY29tYiBvZiBjb21iaW5hdGlvbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlbWFpblN0ciA9IHJlbWFpbkFyci5qb2luKFwiX1wiKTtcbiAgICAgICAgICAgIGlmIChyZW1haW5TdHIuaW5jbHVkZXMoY29tYi53KSAmJiBnbG9zc2FyeS5oYXMoY29tYi53KSkge1xuICAgICAgICAgICAgICByZW1haW5BcnIgPSByZW1haW5TdHJcbiAgICAgICAgICAgICAgICAucmVwbGFjZShjb21iLncsIFJFUExBQ0VEX1BSRUZJWCArIGdsb3NzYXJ5LmdldChjb21iLncpKVxuICAgICAgICAgICAgICAgIC5zcGxpdChcIl9cIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHJlbWFpbkFyclxuICAgICAgICAgICAgLm1hcCgocikgPT4ge1xuICAgICAgICAgICAgICBpZiAoci5zdGFydHNXaXRoKFJFUExBQ0VEX1BSRUZJWCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gci5yZXBsYWNlKFJFUExBQ0VEX1BSRUZJWCwgXCJcIik7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHIudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5qb2luKFwiXCIpXG4gICAgICAgICAgICAucmVwbGFjZSgve0VudGl0eUlEfS9nLCBlbnRpdHlJZCA/IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKS50aXRsZSA6IFwiXCIpO1xuICAgICAgICB9KSgpO1xuXG4gICAgICAgIHJldHVybiB7IHN1Z2dlc3RlZCB9O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL2VudGl0eS9maW5kTWFueVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGVudGl0eUlkcyA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsSWRzKCk7XG5cbiAgICAgICAgZnVuY3Rpb24gZmxhdHRlblN1YnNldFJvd3Moc3Vic2V0Um93czogRW50aXR5U3Vic2V0Um93W10pOiBGbGF0dGVuU3Vic2V0Um93W10ge1xuICAgICAgICAgIHJldHVybiBzdWJzZXRSb3dzLmZsYXRNYXAoKHN1YnNldFJvdykgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBjaGlsZHJlbiwgLi4uc1JvdyB9ID0gc3Vic2V0Um93O1xuICAgICAgICAgICAgcmV0dXJuIFtzUm93LCAuLi5mbGF0dGVuU3Vic2V0Um93cyhjaGlsZHJlbildO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZW50aXRpZXMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICBlbnRpdHlJZHMubWFwKChlbnRpdHlJZCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgICAgY29uc3Qgc3Vic2V0Um93cyA9IGVudGl0eS5nZXRTdWJzZXRSb3dzKCk7XG5cbiAgICAgICAgICAgIC8vIHpvZCDsnbjsiqTthLTsiqTrpbwgc3ByZWFk7ZWY66m0IEpTT04uc3RyaW5naWZ56rCAIHJlZmVyZW5jZeulvCDsnbjrnbzsnbjsnLzroZwg7ZKA7Ja064K066mwIOydkeuLteydtCDsiJjrsLEgTULquYzsp4Ag67aA7ZKA7Ja0IFY4IHN0cmluZyBsaW1pdOulvCDstIjqs7ztlZzri6QuXG4gICAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICAgIHR5cGVzOiBfdHlwZXMsXG4gICAgICAgICAgICAgIGVudW1zOiBfZW51bXMsXG4gICAgICAgICAgICAgIGVudW1Db25lczogX2VudW1Db25lcyxcbiAgICAgICAgICAgICAgc3Vic2V0Q29uZXM6IF9zdWJzZXRDb25lcyxcbiAgICAgICAgICAgICAgLi4ucmVzdFxuICAgICAgICAgICAgfSA9IGVudGl0eTtcblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgLi4ucmVzdCxcbiAgICAgICAgICAgICAgZmxhdHRlblN1YnNldFJvd3M6IGZsYXR0ZW5TdWJzZXRSb3dzKHN1YnNldFJvd3MpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcblxuICAgICAgICBlbnRpdGllcy5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgICAgY29uc3QgYUlkID0gYS5wYXJlbnRJZCA/PyBhLmlkO1xuICAgICAgICAgIGNvbnN0IGJJZCA9IGIucGFyZW50SWQgPz8gYi5pZDtcbiAgICAgICAgICBpZiAoYUlkIDwgYklkKSByZXR1cm4gLTE7XG4gICAgICAgICAgaWYgKGFJZCA+IGJJZCkgcmV0dXJuIDE7XG4gICAgICAgICAgaWYgKGFJZCA9PT0gYklkKSB7XG4gICAgICAgICAgICBpZiAoYS5wYXJlbnRJZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gLTE7XG4gICAgICAgICAgICBpZiAoYi5wYXJlbnRJZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gMTtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB7IGVudGl0aWVzIH07XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldDx7XG4gICAgICAgIFF1ZXJ5c3RyaW5nOiB7XG4gICAgICAgICAgZmlsdGVyPzogXCJlbnVtc1wiIHwgXCJ0eXBlc1wiO1xuICAgICAgICAgIHJlbG9hZD86IFwiMVwiO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS90eXBlSWRzXCIsIGFzeW5jIChyZXF1ZXN0KTogUHJvbWlzZTx7IHR5cGVJZHM6IHN0cmluZ1tdIH0+ID0+IHtcbiAgICAgICAgY29uc3QgeyBmaWx0ZXIsIHJlbG9hZCB9ID0gcmVxdWVzdC5xdWVyeTtcblxuICAgICAgICBpZiAocmVsb2FkID09PSBcIjFcIikge1xuICAgICAgICAgIGF3YWl0IFNvbmFtdS5zeW5jZXIuYXV0b2xvYWRUeXBlcygpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdHlwZUlkcyA9ICgoKSA9PiB7XG4gICAgICAgICAgLy8g7ZSE66Gc7KCd7Yq47JeQ7IScIOygleydmO2VnCDtg4DsnoXrk6RcbiAgICAgICAgICBjb25zdCBwcm9qZWN0VHlwZUlkcyA9IE9iamVjdC5lbnRyaWVzKFNvbmFtdS5zeW5jZXIudHlwZXMpXG4gICAgICAgICAgICAuZmlsdGVyKChbX3R5cGVJZCwgem9kVHlwZV0pID0+ICh6b2RUeXBlLl96b2QuZGVmLnR5cGUgYXMgc3RyaW5nKSAhPT0gXCJlbnVtXCIpXG4gICAgICAgICAgICAubWFwKChbdHlwZUlkLCBfem9kVHlwZV0pID0+IHR5cGVJZCk7XG5cbiAgICAgICAgICAvLyDrgrTsnqUg7YOA7J6F65OkIChzb25hbXUg7L2U7Ja07JeQ7IScIOygnOqztSlcbiAgICAgICAgICBjb25zdCBidWlsdEluVHlwZUlkcyA9IFsuLi5CVUlMVF9JTl9UWVBFX0lEU107XG5cbiAgICAgICAgICAvLyDrqqjrk6Ag7YOA7J6FIOuzke2VqVxuICAgICAgICAgIGNvbnN0IGFsbFR5cGVJZHMgPSBbLi4uYnVpbHRJblR5cGVJZHMsIC4uLnByb2plY3RUeXBlSWRzXTtcblxuICAgICAgICAgIGlmIChmaWx0ZXIgPT09IFwidHlwZXNcIikge1xuICAgICAgICAgICAgcmV0dXJuIGFsbFR5cGVJZHM7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgZW51bUlkcyA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsSWRzKCkuZmxhdE1hcCgoZW50aXR5SWQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhlbnRpdHkuZW51bUxhYmVscyk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpZiAoZmlsdGVyID09PSBcImVudW1zXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBlbnVtSWRzO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gWy4uLmFsbFR5cGVJZHMsIC4uLmVudW1JZHNdO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkoKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHR5cGVJZHMsXG4gICAgICAgIH07XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZm9ybToge1xuICAgICAgICAgICAgaWQ6IHN0cmluZztcbiAgICAgICAgICAgIHRpdGxlOiBzdHJpbmc7XG4gICAgICAgICAgICB0YWJsZTogc3RyaW5nO1xuICAgICAgICAgICAgcGFyZW50SWQ/OiBzdHJpbmc7XG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvY3JlYXRlXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGZvcm0gfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBhd2FpdCBTb25hbXUuc3luY2VyLmNyZWF0ZUVudGl0eSh7IC4uLmZvcm0sIGVudGl0eUlkOiBmb3JtLmlkIH0pO1xuXG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L2RlbFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICAgIHJldHVybiBhd2FpdCBTb25hbXUuc3luY2VyLmRlbEVudGl0eShlbnRpdHlJZCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgbmV3VmFsdWVzOiB7XG4gICAgICAgICAgICB0aXRsZTogc3RyaW5nO1xuICAgICAgICAgICAgdGFibGU6IHN0cmluZztcbiAgICAgICAgICAgIHBhcmVudElkPzogc3RyaW5nO1xuICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L21vZGlmeUVudGl0eUJhc2VcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIG5ld1ZhbHVlcyB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICBlbnRpdHkudGl0bGUgPSBuZXdWYWx1ZXMudGl0bGU7XG4gICAgICAgICAgZW50aXR5LnRhYmxlID0gbmV3VmFsdWVzLnRhYmxlO1xuICAgICAgICAgIGVudGl0eS5wYXJlbnRJZCA9IG5ld1ZhbHVlcy5wYXJlbnRJZDtcbiAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgc3Vic2V0S2V5OiBzdHJpbmc7XG4gICAgICAgICAgZmllbGRzOiBzdHJpbmdbXTtcbiAgICAgICAgICBmaWVsZHNJbnRlcm5hbD86IHN0cmluZ1tdO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9tb2RpZnlTdWJzZXRcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIHN1YnNldEtleSwgZmllbGRzLCBmaWVsZHNJbnRlcm5hbCB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICBlbnRpdHkuc3Vic2V0c1tzdWJzZXRLZXldID0gZmllbGRzO1xuICAgICAgICAgIGlmIChmaWVsZHNJbnRlcm5hbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBpZiAoZmllbGRzSW50ZXJuYWwubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICBlbnRpdHkuc3Vic2V0c0ludGVybmFsW3N1YnNldEtleV0gPSBmaWVsZHNJbnRlcm5hbDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGRlbGV0ZSBlbnRpdHkuc3Vic2V0c0ludGVybmFsW3N1YnNldEtleV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG5cbiAgICAgICAgICByZXR1cm4geyB1cGRhdGVkOiBmaWVsZHMsIHVwZGF0ZWRJbnRlcm5hbDogZmllbGRzSW50ZXJuYWwgfTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICBzdWJzZXRLZXk6IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvZGVsU3Vic2V0XCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBzdWJzZXRLZXkgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgZGVsZXRlIGVudGl0eS5zdWJzZXRzW3N1YnNldEtleV07XG4gICAgICAgICAgZGVsZXRlIGVudGl0eS5zdWJzZXRzSW50ZXJuYWxbc3Vic2V0S2V5XTtcbiAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgbmV3UHJvcDogRW50aXR5UHJvcDtcbiAgICAgICAgICBhdD86IG51bWJlcjtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvY3JlYXRlUHJvcFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgYXQsIG5ld1Byb3AgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgYXdhaXQgZW50aXR5LmNyZWF0ZVByb3AobmV3UHJvcCwgYXQpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIG5ld1Byb3A6IEVudGl0eVByb3A7XG4gICAgICAgICAgYXQ6IG51bWJlcjtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvbW9kaWZ5UHJvcFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgYXQsIG5ld1Byb3AgfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICBlbnRpdHkubW9kaWZ5UHJvcChuZXdQcm9wLCBhdCk7XG5cbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICBhdDogbnVtYmVyO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9kZWxQcm9wXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBhdCB9ID0gcmVxdWVzdC5ib2R5O1xuXG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgIGVudGl0eS5kZWxQcm9wKGF0KTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICBhdDogbnVtYmVyO1xuICAgICAgICAgIHRvOiBudW1iZXI7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L21vdmVQcm9wXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBhdCwgdG8gfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICBlbnRpdHkubW92ZVByb3AoYXQsIHRvKTtcblxuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIGluZGV4ZXM6IEVudGl0eUluZGV4W107XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L21vZGlmeUluZGV4ZXNcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIGluZGV4ZXMgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgZW50aXR5LmluZGV4ZXMgPSBpbmRleGVzO1xuICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG5cbiAgICAgICAgICByZXR1cm4geyB1cGRhdGVkOiBpbmRleGVzIH07XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgZW51bUxhYmVsczogRW50aXR5W1wiZW51bUxhYmVsc1wiXTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvbW9kaWZ5RW51bUxhYmVsc1wiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgZW51bUxhYmVscyB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICBlbnRpdHkuZW51bUxhYmVscyA9IGVudW1MYWJlbHM7XG4gICAgICAgICAgYXdhaXQgZW50aXR5LnNhdmUoKTtcblxuICAgICAgICAgIHJldHVybiB7IHVwZGF0ZWQ6IGVudW1MYWJlbHMgfTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICBuZXdFbnVtSWQ6IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvY3JlYXRlRW51bUlkXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBuZXdFbnVtSWQgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG5cbiAgICAgICAgICBpZiAoZW50aXR5LmVudW1MYWJlbHNbbmV3RW51bUlkXSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGDsnbTrr7gg7KG07J6s7ZWY64qUIGVudW1JZOyeheuLiOuLpDogJHtuZXdFbnVtSWR9YCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZW50aXR5LmVudW1MYWJlbHNbbmV3RW51bUlkXSA9IG5ld0VudW1JZC5lbmRzV2l0aChcIlN0YXR1c1wiKVxuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgYWN0aXZlOiBcIuuFuOy2nFwiLFxuICAgICAgICAgICAgICAgIGhpZGRlbjogXCLsiKjquYBcIixcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiB7XG4gICAgICAgICAgICAgICAgXCJcIjogXCJcIixcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgZW51bUlkOiB7XG4gICAgICAgICAgICBiZWZvcmU6IHN0cmluZztcbiAgICAgICAgICAgIGFmdGVyOiBzdHJpbmc7XG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvbW9kaWZ5RW51bUlkXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBlbnVtSWQgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBjb25zdCBlbnRpdHlJZHMgPSBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpO1xuICAgICAgICAgIGNvbnN0IGlzRXhpc3RzID0gZW50aXR5SWRzLnNvbWUoKGVudGl0eUlkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0LmtleXMoZW50aXR5LmVudW1MYWJlbHMpLmluY2x1ZGVzKGVudW1JZC5hZnRlcik7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKGlzRXhpc3RzKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYOydtOuvuCDsobTsnqztlZjripQgRW51bUlk7J6F64uI64ukOiAke2VudW1JZC5hZnRlcn1gKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgZW50aXR5LmVudW1MYWJlbHNbZW51bUlkLmFmdGVyXSA9IGVudGl0eS5lbnVtTGFiZWxzW2VudW1JZC5iZWZvcmVdO1xuICAgICAgICAgIGRlbGV0ZSBlbnRpdHkuZW51bUxhYmVsc1tlbnVtSWQuYmVmb3JlXTtcblxuICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG5cbiAgICAgICAgICBmb3IgKGNvbnN0IGVudGl0eUlkIG9mIGVudGl0eUlkcykge1xuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBwcm9wIG9mIGVudGl0eS5wcm9wcykge1xuICAgICAgICAgICAgICBpZiAocHJvcC50eXBlID09PSBcImVudW1cIiAmJiBwcm9wLmlkID09PSBlbnVtSWQuYmVmb3JlKSB7XG4gICAgICAgICAgICAgICAgcHJvcC5pZCA9IGVudW1JZC5hZnRlcjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYXdhaXQgZW50aXR5LnNhdmUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgZW51bUlkOiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L2RlbGV0ZUVudW1JZFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgZW51bUlkIH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgICBjb25zdCBlbnRpdHlJZHMgPSBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpO1xuICAgICAgICAgIGNvbnN0IGlzUmVmZXJlbmNlZCA9IGVudGl0eUlkc1xuICAgICAgICAgICAgLmZsYXRNYXAoKGVudGl0eUlkKSA9PiBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCkucHJvcHMpXG4gICAgICAgICAgICAuc29tZSgocHJvcCkgPT4gcHJvcC50eXBlID09PSBcImVudW1cIiAmJiBwcm9wLmlkID09PSBlbnVtSWQpO1xuICAgICAgICAgIGlmIChpc1JlZmVyZW5jZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtlbnVtSWR966W8IOywuOyhsO2VmOuKlCDtlITroZztjbzti7DqsIAg7KG07J6s7ZWp64uI64ukLmApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICBkZWxldGUgZW50aXR5LmVudW1MYWJlbHNbZW51bUlkXTtcbiAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIHRhcmdldDogXCJlbnRpdHlcIiB8IFwicHJvcFwiIHwgXCJlbnVtXCIgfCBcInN1YnNldFwiO1xuICAgICAgICAgIHByb3BOYW1lPzogc3RyaW5nO1xuICAgICAgICAgIGVudW1JZD86IHN0cmluZztcbiAgICAgICAgICBzdWJzZXRLZXk/OiBzdHJpbmc7XG4gICAgICAgICAgY29uZTogQ29uZTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvdXBkYXRlQ29uZVwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgdGFyZ2V0LCBwcm9wTmFtZSwgZW51bUlkLCBzdWJzZXRLZXksIGNvbmUgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG5cbiAgICAgICAgICBpZiAodGFyZ2V0ID09PSBcImVudGl0eVwiKSB7XG4gICAgICAgICAgICBlbnRpdHkuY29uZSA9IGNvbmU7XG4gICAgICAgICAgfSBlbHNlIGlmICh0YXJnZXQgPT09IFwicHJvcFwiICYmIHByb3BOYW1lKSB7XG4gICAgICAgICAgICBjb25zdCBwcm9wID0gZW50aXR5LnByb3BzLmZpbmQoKHApID0+IHAubmFtZSA9PT0gcHJvcE5hbWUpO1xuICAgICAgICAgICAgaWYgKHByb3ApIHtcbiAgICAgICAgICAgICAgKHByb3AgYXMgeyBjb25lPzogQ29uZSB9KS5jb25lID0gY29uZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKHRhcmdldCA9PT0gXCJlbnVtXCIgJiYgZW51bUlkKSB7XG4gICAgICAgICAgICBlbnRpdHkuZW51bUNvbmVzW2VudW1JZF0gPSBjb25lO1xuICAgICAgICAgIH0gZWxzZSBpZiAodGFyZ2V0ID09PSBcInN1YnNldFwiICYmIHN1YnNldEtleSkge1xuICAgICAgICAgICAgZW50aXR5LnN1YnNldENvbmVzW3N1YnNldEtleV0gPSBjb25lO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgcHJlc2VydmVFeGlzdGluZz86IGJvb2xlYW47XG4gICAgICAgICAgb25seUVtcHR5PzogYm9vbGVhbjtcbiAgICAgICAgICBsb2NhbGU/OiBcImtvXCIgfCBcImVuXCIgfCBcImphXCI7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L2dlbmVyYXRlQ29uZXNcIiwgYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBwcmVzZXJ2ZUV4aXN0aW5nLCBvbmx5RW1wdHksIGxvY2FsZSB9ID0gcmVxdWVzdC5ib2R5O1xuXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIEVudGl0eSDsobTsnqwg7Jes67aAIO2ZleyduFxuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuXG4gICAgICAgICAgICAvLyBsb2NhbGUg6riw67O46rCSOiBTb25hbXUuY29uZmlnLmkxOG4uZGVmYXVsdExvY2FsZSDsgqzsmqlcbiAgICAgICAgICAgIGNvbnN0IGVmZmVjdGl2ZUxvY2FsZSA9XG4gICAgICAgICAgICAgIGxvY2FsZSA/PyAoU29uYW11LmNvbmZpZy5pMThuLmRlZmF1bHRMb2NhbGUgYXMgXCJrb1wiIHwgXCJlblwiIHwgXCJqYVwiKTtcblxuICAgICAgICAgICAgLy8gQ29uZSDsg53shLFcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGVudGl0eS5nZW5lcmF0ZUNvbmVzKHtcbiAgICAgICAgICAgICAgcHJlc2VydmVFeGlzdGluZzogcHJlc2VydmVFeGlzdGluZyA/PyB0cnVlLFxuICAgICAgICAgICAgICBvbmx5RW1wdHk6IG9ubHlFbXB0eSA/PyBmYWxzZSxcbiAgICAgICAgICAgICAgbG9jYWxlOiBlZmZlY3RpdmVMb2NhbGUsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKTtcblxuICAgICAgICAgICAgLy8gRW50aXR5IG5vdCBmb3VuZFxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5jbHVkZXMoXCLsobTsnqztlZjsp4Ag7JWK64qUIEVudGl0eVwiKSkge1xuICAgICAgICAgICAgICByZXBseS5zdGF0dXMoNDA0KTtcbiAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBlcnJvcjogYEVudGl0eSBub3QgZm91bmQ6ICR7ZW50aXR5SWR9YCxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQVBJIO2CpCDsl4bsnYxcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmluY2x1ZGVzKFwiQU5USFJPUElDX0FQSV9LRVkgbm90IGZvdW5kXCIpKSB7XG4gICAgICAgICAgICAgIHJlcGx5LnN0YXR1cyg1MDApO1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGVycm9yOiBcIkFQSSBrZXkgbm90IGNvbmZpZ3VyZWRcIixcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gUmF0ZSBsaW1pdFxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5jbHVkZXMoXCJSYXRlIGxpbWl0IGV4Y2VlZGVkXCIpKSB7XG4gICAgICAgICAgICAgIHJlcGx5LnN0YXR1cyg0MjkpO1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGVycm9yOiBcIlJhdGUgbGltaXQgZXhjZWVkZWQuIFBsZWFzZSB0cnkgYWdhaW4gbGF0ZXIuXCIsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIOq4sO2DgCDsl5Drn6xcbiAgICAgICAgICAgIHJlcGx5LnN0YXR1cyg1MDApO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgIGVycm9yOiBgQ29uZSBnZW5lcmF0aW9uIGZhaWxlZDogJHttZXNzYWdlfWAsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldDx7XG4gICAgICAgIFF1ZXJ5c3RyaW5nOiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvZ2V0VGFibGVDb2x1bW5zXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgZW50aXR5SWQgfSA9IHJlcXVlc3QucXVlcnk7XG4gICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgY29uc3QgY29sdW1ucyA9IGVudGl0eS5nZXRUYWJsZUNvbHVtbnMoKTtcbiAgICAgICAgcmV0dXJuIHsgY29sdW1ucyB9O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkczogc3RyaW5nW107XG4gICAgICAgICAgdGVtcGxhdGVLZXlzOiBzdHJpbmdbXTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9zY2FmZm9sZGluZy9nZXRTdGF0dXNcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgeyBlbnRpdHlJZHMsIHRlbXBsYXRlS2V5czogX3RlbXBsYXRlS2V5cyB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICBpZiAoKGVudGl0eUlkcyA/PyBbXSkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oU0QoXCJzb25hbXUuZXJyb3IuZW50aXR5SWRzUmVxdWlyZWRcIikpO1xuICAgICAgICB9IGVsc2UgaWYgKChfdGVtcGxhdGVLZXlzID8/IFtdKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihTRChcInNvbmFtdS5lcnJvci50ZW1wbGF0ZUtleXNSZXF1aXJlZFwiKSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBzb3J0aW5nXG4gICAgICAgIGVudGl0eUlkcy5zb3J0KChhLCBiKSA9PiAoYSA8IGIgPyAtMSA6IGEgPiBiID8gMSA6IDApKTtcbiAgICAgICAgY29uc3QgdGVtcGxhdGVLZXlzID0gVGVtcGxhdGVLZXkub3B0aW9ucy5maWx0ZXIoKHRrKSA9PiBfdGVtcGxhdGVLZXlzLmluY2x1ZGVzKHRrKSk7XG5cbiAgICAgICAgY29uc3QgY29tYmluYXRpb25zID0gZW50aXR5SWRzLmZsYXRNYXAoKGVudGl0eUlkKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHRlbXBsYXRlS2V5cy5tYXAoKHRlbXBsYXRlS2V5KSA9PiBbZW50aXR5SWQsIHRlbXBsYXRlS2V5XSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGNvbnN0IHN0YXR1c2VzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgY29tYmluYXRpb25zLm1hcChhc3luYyAoW2VudGl0eUlkLCB0ZW1wbGF0ZUtleV0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgc3ViUGF0aCwgZnVsbFBhdGgsIGlzRXhpc3RzIH0gPSBhd2FpdCBTb25hbXUuc3luY2VyLmNoZWNrRXhpc3RzR2VuQ29kZShcbiAgICAgICAgICAgICAgZW50aXR5SWQsXG4gICAgICAgICAgICAgIHRlbXBsYXRlS2V5IGFzIFRlbXBsYXRlS2V5LFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIGVudGl0eUlkLFxuICAgICAgICAgICAgICB0ZW1wbGF0ZUtleSxcbiAgICAgICAgICAgICAgc3ViUGF0aCxcbiAgICAgICAgICAgICAgZnVsbFBhdGgsXG4gICAgICAgICAgICAgIGlzRXhpc3RzLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHsgc3RhdHVzZXMgfTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgICAgdGVtcGxhdGVLZXk6IHN0cmluZztcbiAgICAgICAgICAgIGVudW1JZD86IHN0cmluZztcbiAgICAgICAgICAgIG92ZXJ3cml0ZT86IGJvb2xlYW47XG4gICAgICAgICAgfVtdO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL3NjYWZmb2xkaW5nL2dlbmVyYXRlXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgb3B0aW9ucyB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICBpZiAob3B0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihTRChcInNvbmFtdS5lcnJvci5vcHRpb25zUmVxdWlyZWRcIikpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gMS4g66qo65OgIO2FnO2UjOumv+yXkOyEnCDtlYTsmpTtlZwgZGljdCDtgqTrpbwg7IiY7KeRXG4gICAgICAgIGNvbnN0IGtleXMgPSBvcHRpb25zLmZsYXRNYXAoKHsgdGVtcGxhdGVLZXkgfSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGVNYW5hZ2VyLmdldCh0ZW1wbGF0ZUtleSk7XG4gICAgICAgICAgcmV0dXJuIHRlbXBsYXRlLmdldFJlcXVpcmVkRGljdEtleXMoKSA/PyBbXTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gMi4gdGFyZ2V067OE66GcIGVuc3VyZURpY3RLZXlzIO2YuOy2nCAo7Iic7LCoIOyymOumrClcbiAgICAgICAgYXdhaXQgc29uYW11RGljdGlvbmFyeS5lbnN1cmVEaWN0S2V5cyhbLi4ubmV3IFNldChrZXlzKV0pO1xuXG4gICAgICAgIC8vIDMuIO2FnO2UjOumvyDsg53shLEgKOuzkeugrCDsspjrpqwpXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgIG9wdGlvbnMubWFwKGFzeW5jICh7IGVudGl0eUlkLCB0ZW1wbGF0ZUtleSwgZW51bUlkLCBvdmVyd3JpdGUgfSkgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IFNvbmFtdS5zeW5jZXIuZ2VuZXJhdGVUZW1wbGF0ZShcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZUtleSBhcyBUZW1wbGF0ZUtleSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBlbnRpdHlJZCxcbiAgICAgICAgICAgICAgICAgIGVudW1JZCxcbiAgICAgICAgICAgICAgICB9IGFzIHtcbiAgICAgICAgICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgICAgICAgICBlbnVtSWQ/OiBzdHJpbmc7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBvdmVyd3JpdGUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgaWYgKGlzU29FeGNlcHRpb24oZSkgJiYgZS5zdGF0dXNDb2RlID09PSA1NDEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAocmVzdWx0LmZpbHRlcihub25OdWxsYWJsZSkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFNlcnZpY2VVbmF2YWlsYWJsZUV4Y2VwdGlvbihTRChcInNvbmFtdS5lcnJvci5hbGxGaWxlc0dlbmVyYXRlZFwiKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBvcHRpb246IHtcbiAgICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgICB0ZW1wbGF0ZUtleTogc3RyaW5nO1xuICAgICAgICAgICAgZW51bUlkPzogc3RyaW5nO1xuICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvc2NhZmZvbGRpbmcvcHJldmlld1wiLCBhc3luYyAocmVxdWVzdCk6IFByb21pc2U8eyBwYXRoQW5kQ29kZXM6IFBhdGhBbmRDb2RlW10gfT4gPT4ge1xuICAgICAgICBjb25zdCB7IG9wdGlvbiB9ID0gcmVxdWVzdC5ib2R5O1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgeyB0ZW1wbGF0ZUtleSwgLi4udGVtcGxhdGVPcHRpb25zIH0gPSBvcHRpb247XG4gICAgICAgICAgY29uc3QgcGF0aEFuZENvZGVzID0gYXdhaXQgU29uYW11LnN5bmNlci5yZW5kZXJUZW1wbGF0ZShcbiAgICAgICAgICAgIHRlbXBsYXRlS2V5IGFzIFRlbXBsYXRlS2V5LFxuICAgICAgICAgICAgdGVtcGxhdGVPcHRpb25zLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICByZXR1cm4geyBwYXRoQW5kQ29kZXMgfTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0KFwiL2FwaS9maXh0dXJlXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgc291cmNlREIsIHRhcmdldERCLCBzZWFyY2gsIGR1cGxpY2F0ZUNoZWNrIH0gPSByZXF1ZXN0LmJvZHkgYXMge1xuICAgICAgICAgIHNvdXJjZURCOiBrZXlvZiBTb25hbXVEQkNvbmZpZztcbiAgICAgICAgICB0YXJnZXREQjoga2V5b2YgU29uYW11REJDb25maWc7XG4gICAgICAgICAgc2VhcmNoOiBGaXh0dXJlU2VhcmNoT3B0aW9ucztcbiAgICAgICAgICBkdXBsaWNhdGVDaGVjaz86IER1cGxpY2F0ZUNoZWNrT3B0aW9ucztcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gRml4dHVyZU1hbmFnZXIuZ2V0Rml4dHVyZXMoc291cmNlREIsIHRhcmdldERCLCBzZWFyY2gsIGR1cGxpY2F0ZUNoZWNrKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdChcIi9hcGkvZml4dHVyZS9pbXBvcnRcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgeyBkYiwgZml4dHVyZXMgfSA9IHJlcXVlc3QuYm9keSBhcyB7XG4gICAgICAgICAgZGI6IGtleW9mIFNvbmFtdURCQ29uZmlnO1xuICAgICAgICAgIGZpeHR1cmVzOiBGaXh0dXJlUmVjb3JkW107XG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIEZpeHR1cmVNYW5hZ2VyLmluc2VydEZpeHR1cmVzKGRiLCBmaXh0dXJlcyk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3QoXCIvYXBpL2ZpeHR1cmUvYWRkRml4dHVyZUxvYWRlclwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCB7IGNvZGUgfSA9IHJlcXVlc3QuYm9keSBhcyB7IGNvZGU6IHN0cmluZyB9O1xuXG4gICAgICAgIHJldHVybiBGaXh0dXJlTWFuYWdlci5hZGRGaXh0dXJlTG9hZGVyKGNvZGUpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL2kxOG4vZGljdGlvbmFyeVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHJldHVybiBzb25hbXVEaWN0aW9uYXJ5LmdldERpY3Rpb25hcnkoKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIuZ2V0KFwiL2FwaS9pMThuL2V4cG9ydFwiLCBhc3luYyAoX3JlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgZmlsZW5hbWUsIGJ1ZmZlciB9ID0gYXdhaXQgc29uYW11RGljdGlvbmFyeS5leHBvcnRUb0V4Y2VsKCk7XG4gICAgICAgIHJlcGx5XG4gICAgICAgICAgLmhlYWRlcihcbiAgICAgICAgICAgIFwiQ29udGVudC1UeXBlXCIsXG4gICAgICAgICAgICBcImFwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC5zcHJlYWRzaGVldG1sLnNoZWV0XCIsXG4gICAgICAgICAgKVxuICAgICAgICAgIC5oZWFkZXIoXCJDb250ZW50LURpc3Bvc2l0aW9uXCIsIGBhdHRhY2htZW50OyBmaWxlbmFtZT1cIiR7ZmlsZW5hbWV9XCJgKVxuICAgICAgICAgIC5zZW5kKGJ1ZmZlcik7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3QoXCIvYXBpL2kxOG4vaW1wb3J0XCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXF1ZXN0LmZpbGUoKTtcbiAgICAgICAgaWYgKCFkYXRhKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oU0QoXCJzb25hbXUuZXJyb3IuZmlsZU5vdFVwbG9hZGVkXCIpKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBidWZmZXIgPSBhd2FpdCBkYXRhLnRvQnVmZmVyKCk7XG4gICAgICAgIHJldHVybiBzb25hbXVEaWN0aW9uYXJ5LmltcG9ydEZyb21FeGNlbChidWZmZXIpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIG9sZEtleTogc3RyaW5nO1xuICAgICAgICAgIG5ld0tleTogc3RyaW5nO1xuICAgICAgICAgIHNvdXJjZTogXCJlbnRpdHlcIiB8IFwicHJvamVjdFwiIHwgXCJzb25hbXVcIjtcbiAgICAgICAgICB2YWx1ZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvaTE4bi91cGRhdGVcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgYXdhaXQgc29uYW11RGljdGlvbmFyeS51cGRhdGVFbnRyeShyZXF1ZXN0LmJvZHkpO1xuICAgICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlIH07XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAga2V5OiBzdHJpbmc7XG4gICAgICAgICAgdmFsdWVzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2kxOG4vY3JlYXRlXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGF3YWl0IHNvbmFtdURpY3Rpb25hcnkuY3JlYXRlRW50cnkocmVxdWVzdC5ib2R5KTtcbiAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSB9O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGtleTogc3RyaW5nO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2kxOG4vZGVsZXRlXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGF3YWl0IHNvbmFtdURpY3Rpb25hcnkuZGVsZXRlRW50cnkocmVxdWVzdC5ib2R5LmtleSk7XG4gICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUgfTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7IEJvZHk6IHsga2V5czogc3RyaW5nW10gfSB9PihcIi9hcGkvaTE4bi9jaGVja1VzYWdlXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBzb25hbXVEaWN0aW9uYXJ5LmNoZWNrVXNhZ2UocmVxdWVzdC5ib2R5LmtleXMpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIFRhc2tzIEFQSVxuICAgICAgc2VydmVyLmdldChcIi9hcGkvdGFza3Mvc3RhdHVzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBTb25hbXUud29ya2Zsb3dzO1xuICAgICAgICAgIHJldHVybiB7IGFjdGl2ZTogdHJ1ZSB9O1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICByZXR1cm4geyBhY3RpdmU6IGZhbHNlIH07XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIuZ2V0KFwiL2FwaS90YXNrcy93b3JrZmxvd0RlZmluaXRpb25zXCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgZGVmaW5pdGlvbnMgPSBTb25hbXUud29ya2Zsb3dzLndvcmtmbG93RGVmaW5pdGlvbnM7XG4gICAgICAgIHJldHVybiB7IGRlZmluaXRpb25zIH07XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldDx7XG4gICAgICAgIFF1ZXJ5c3RyaW5nOiB7XG4gICAgICAgICAgbGltaXQ/OiBzdHJpbmc7XG4gICAgICAgICAgYWZ0ZXI/OiBzdHJpbmc7XG4gICAgICAgICAgYmVmb3JlPzogc3RyaW5nO1xuICAgICAgICAgIG9yZGVyPzogXCJhc2NcIiB8IFwiZGVzY1wiO1xuICAgICAgICAgIHN0YXR1cz86IHN0cmluZztcbiAgICAgICAgICB3b3JrZmxvd05hbWU/OiBzdHJpbmc7XG4gICAgICAgICAgY3JlYXRlZEFmdGVyPzogc3RyaW5nO1xuICAgICAgICAgIGNyZWF0ZWRCZWZvcmU/OiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvdGFza3Mvd29ya2Zsb3dSdW5zXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IGJhY2tlbmQgPSBTb25hbXUud29ya2Zsb3dzLmJhY2tlbmQ7XG4gICAgICAgIGNvbnN0IHsgbGltaXQsIGFmdGVyLCBiZWZvcmUsIG9yZGVyLCBzdGF0dXMsIHdvcmtmbG93TmFtZSwgY3JlYXRlZEFmdGVyLCBjcmVhdGVkQmVmb3JlIH0gPVxuICAgICAgICAgIHJlcXVlc3QucXVlcnk7XG4gICAgICAgIHJldHVybiBiYWNrZW5kLmxpc3RXb3JrZmxvd1J1bnMoe1xuICAgICAgICAgIGxpbWl0OiBsaW1pdCA/IE51bWJlci5wYXJzZUludChsaW1pdCwgMTApIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGFmdGVyLFxuICAgICAgICAgIGJlZm9yZSxcbiAgICAgICAgICBvcmRlcixcbiAgICAgICAgICBzdGF0dXM6IHN0YXR1cyA/IHN0YXR1cy5zcGxpdChcIixcIikgOiB1bmRlZmluZWQsXG4gICAgICAgICAgd29ya2Zsb3dOYW1lOiB3b3JrZmxvd05hbWUgfHwgdW5kZWZpbmVkLFxuICAgICAgICAgIGNyZWF0ZWRBZnRlcjogY3JlYXRlZEFmdGVyID8gbmV3IERhdGUoY3JlYXRlZEFmdGVyKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICBjcmVhdGVkQmVmb3JlOiBjcmVhdGVkQmVmb3JlID8gbmV3IERhdGUoY3JlYXRlZEJlZm9yZSkgOiB1bmRlZmluZWQsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQ8e1xuICAgICAgICBQYXJhbXM6IHsgaWQ6IHN0cmluZyB9O1xuICAgICAgfT4oXCIvYXBpL3Rhc2tzL3dvcmtmbG93UnVucy86aWRcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgYmFja2VuZCA9IFNvbmFtdS53b3JrZmxvd3MuYmFja2VuZDtcbiAgICAgICAgY29uc3Qgd29ya2Zsb3dSdW4gPSBhd2FpdCBiYWNrZW5kLmdldFdvcmtmbG93UnVuKHtcbiAgICAgICAgICB3b3JrZmxvd1J1bklkOiByZXF1ZXN0LnBhcmFtcy5pZCxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICghd29ya2Zsb3dSdW4pIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFdvcmtmbG93IHJ1biBub3QgZm91bmQ6ICR7cmVxdWVzdC5wYXJhbXMuaWR9YCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHdvcmtmbG93UnVuO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgUGFyYW1zOiB7IGlkOiBzdHJpbmcgfTtcbiAgICAgIH0+KFwiL2FwaS90YXNrcy93b3JrZmxvd1J1bnMvOmlkL2NhbmNlbFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCBiYWNrZW5kID0gU29uYW11LndvcmtmbG93cy5iYWNrZW5kO1xuICAgICAgICByZXR1cm4gYmFja2VuZC5jYW5jZWxXb3JrZmxvd1J1bih7XG4gICAgICAgICAgd29ya2Zsb3dSdW5JZDogcmVxdWVzdC5wYXJhbXMuaWQsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgUGFyYW1zOiB7IGlkOiBzdHJpbmcgfTtcbiAgICAgIH0+KFwiL2FwaS90YXNrcy93b3JrZmxvd1J1bnMvOmlkL3BhdXNlXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IGJhY2tlbmQgPSBTb25hbXUud29ya2Zsb3dzLmJhY2tlbmQ7XG4gICAgICAgIHJldHVybiBiYWNrZW5kLnBhdXNlV29ya2Zsb3dSdW4oe1xuICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJlcXVlc3QucGFyYW1zLmlkLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIFBhcmFtczogeyBpZDogc3RyaW5nIH07XG4gICAgICB9PihcIi9hcGkvdGFza3Mvd29ya2Zsb3dSdW5zLzppZC9yZXN1bWVcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgYmFja2VuZCA9IFNvbmFtdS53b3JrZmxvd3MuYmFja2VuZDtcbiAgICAgICAgcmV0dXJuIGJhY2tlbmQucmVzdW1lV29ya2Zsb3dSdW4oe1xuICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJlcXVlc3QucGFyYW1zLmlkLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIuZ2V0PHtcbiAgICAgICAgUGFyYW1zOiB7IGlkOiBzdHJpbmcgfTtcbiAgICAgICAgUXVlcnlzdHJpbmc6IHtcbiAgICAgICAgICBsaW1pdD86IHN0cmluZztcbiAgICAgICAgICBhZnRlcj86IHN0cmluZztcbiAgICAgICAgICBiZWZvcmU/OiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvdGFza3Mvd29ya2Zsb3dSdW5zLzppZC9zdGVwc1wiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCBiYWNrZW5kID0gU29uYW11LndvcmtmbG93cy5iYWNrZW5kO1xuICAgICAgICBjb25zdCB7IGxpbWl0LCBhZnRlciwgYmVmb3JlIH0gPSByZXF1ZXN0LnF1ZXJ5O1xuICAgICAgICByZXR1cm4gYmFja2VuZC5saXN0U3RlcEF0dGVtcHRzKHtcbiAgICAgICAgICB3b3JrZmxvd1J1bklkOiByZXF1ZXN0LnBhcmFtcy5pZCxcbiAgICAgICAgICBsaW1pdDogbGltaXQgPyBOdW1iZXIucGFyc2VJbnQobGltaXQsIDEwKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICBhZnRlcixcbiAgICAgICAgICBiZWZvcmUsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIC8qKlxuICAgICAgICogSGVhbHRoIENoZWNrIEFQSVxuICAgICAgICogTUNQIOuPhOq1rOqwgCBTb25hbXUg7ISc67KE66W8IOyekOuPmSDqsJDsp4DtlZjquLAg7JyE7ZWcIOyXlOuTnO2PrOyduO2KuFxuICAgICAgICovXG4gICAgICBzZXJ2ZXIuZ2V0KFwiL2FwaS9zb25hbXUvaGVhbHRoXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IGFkZHJlc3MgPSByZXF1ZXN0LnNlcnZlci5zZXJ2ZXIuYWRkcmVzcygpO1xuICAgICAgICBjb25zdCBwb3J0ID0gYWRkcmVzcyAmJiB0eXBlb2YgYWRkcmVzcyA9PT0gXCJvYmplY3RcIiA/IGFkZHJlc3MucG9ydCA6IDA7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBvazogdHJ1ZSxcbiAgICAgICAgICBwcm9qZWN0OiBwcm9jZXNzLmN3ZCgpLnNwbGl0KFwiL1wiKS5wb3AoKSB8fCBcInVua25vd25cIixcbiAgICAgICAgICBwb3J0LFxuICAgICAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICB9O1xuICAgICAgfSk7XG5cbiAgICAgIC8qKlxuICAgICAgICogRml4dHVyZSDsg53shLEgQVBJXG4gICAgICAgKi9cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eTogc3RyaW5nO1xuICAgICAgICAgIGNvdW50PzogbnVtYmVyO1xuICAgICAgICAgIG92ZXJyaWRlcz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgICAgICAgIHRhcmdldERiPzogXCJmaXh0dXJlXCIgfCBcInRlc3RcIjtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9zb25hbXUvZml4dHVyZS9nZW5lcmF0ZVwiLCBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgeyBlbnRpdHksIGNvdW50ID0gMSwgb3ZlcnJpZGVzLCB0YXJnZXREYiA9IFwiZml4dHVyZVwiIH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgLy8g7YOA6rKfIERCIOyEpOyglSDqsIDsoLjsmKTquLBcbiAgICAgICAgY29uc3QgZGJDb25maWcgPSB0YXJnZXREYiA9PT0gXCJmaXh0dXJlXCIgPyBTb25hbXUuZGJDb25maWcuZml4dHVyZSA6IFNvbmFtdS5kYkNvbmZpZy50ZXN0O1xuXG4gICAgICAgIC8vIEtuZXgg7J247Iqk7YS07IqkIOyDneyEsVxuICAgICAgICBjb25zdCBkYiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShkYkNvbmZpZyk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBGaXh0dXJlR2VuZXJhdG9yIOyDneyEsVxuICAgICAgICAgIGNvbnN0IGdlbmVyYXRvciA9IG5ldyBGaXh0dXJlR2VuZXJhdG9yKGRiLCBkYiwgdGFyZ2V0RGIsIEVudGl0eU1hbmFnZXIpO1xuXG4gICAgICAgICAgLy8g64uo7J28IEVudGl0eSDrsLDsuZgg7IOd7ISxXG4gICAgICAgICAgY29uc3QgZml4dHVyZXMgPSBhd2FpdCBnZW5lcmF0b3IuZ2VuZXJhdGVCYXRjaChbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGVudGl0eSxcbiAgICAgICAgICAgICAgY291bnQsXG4gICAgICAgICAgICAgIG92ZXJyaWRlczogb3ZlcnJpZGVzID8/IHt9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdKTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgZW50aXR5LFxuICAgICAgICAgICAgY291bnQ6IGZpeHR1cmVzLmxlbmd0aCxcbiAgICAgICAgICAgIGZpeHR1cmVzLFxuICAgICAgICAgICAgdGFyZ2V0RGIsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICByZXBseS5zdGF0dXMoNDAwKTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgYXdhaXQgZGIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLyoqXG4gICAgICAgKiBGaXh0dXJlIOuNsOydtO2EsCDtg5Dsg4kgQVBJXG4gICAgICAgKi9cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eTogc3RyaW5nO1xuICAgICAgICAgIHN0cmF0ZWd5OiBcInNhbXBsZVwiIHwgXCJyZWNlbnRcIiB8IFwicmFuZG9tXCIgfCBcInF1ZXJ5XCI7XG4gICAgICAgICAgbGltaXQ/OiBudW1iZXI7XG4gICAgICAgICAgd2hlcmU/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9zb25hbXUvZml4dHVyZS9leHBsb3JlXCIsIGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICBjb25zdCB7IGVudGl0eSwgc3RyYXRlZ3ksIGxpbWl0ID0gMTAsIHdoZXJlIH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgLy8gRml4dHVyZSBEQiDshKTsoJUg6rCA7KC47Jik6riwXG4gICAgICAgIGNvbnN0IGZpeHR1cmVEYkNvbmZpZyA9IFNvbmFtdS5kYkNvbmZpZy5maXh0dXJlO1xuXG4gICAgICAgIC8vIEtuZXgg7J247Iqk7YS07IqkIOyDneyEsVxuICAgICAgICBjb25zdCBmaXh0dXJlRGIgPSBjcmVhdGVLbmV4SW5zdGFuY2UoZml4dHVyZURiQ29uZmlnKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIERhdGFFeHBsb3JlciDsg53shLFcbiAgICAgICAgICBjb25zdCBleHBsb3JlciA9IG5ldyBEYXRhRXhwbG9yZXIoZml4dHVyZURiLCBFbnRpdHlNYW5hZ2VyKTtcblxuICAgICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBleHBsb3Jlci5leHBsb3JlKGVudGl0eSwge1xuICAgICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgICBsaW1pdCxcbiAgICAgICAgICAgIHdoZXJlLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICBlbnRpdHksXG4gICAgICAgICAgICBzdHJhdGVneSxcbiAgICAgICAgICAgIGNvdW50OiBkYXRhLmxlbmd0aCxcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICByZXBseS5zdGF0dXMoNDAwKTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgYXdhaXQgZml4dHVyZURiLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8qKlxuICAgICAgICogRml4dHVyZSDrjbDsnbTthLAg6rCA7KC47Jik6riwIChmZXRjaCkgQVBJXG4gICAgICAgKiBwcm9kdWN0aW9uL2RldmVsb3BtZW50IERC7JeQ7IScIOyLpOygnCDrjbDsnbTthLDrpbwgZml4dHVyZSBEQuuhnCBpbXBvcnRcbiAgICAgICAqL1xuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5OiBzdHJpbmc7XG4gICAgICAgICAgc3RyYXRlZ3k/OiBcInNhbXBsZVwiIHwgXCJyZWNlbnRcIiB8IFwicmFuZG9tXCIgfCBcInF1ZXJ5XCI7XG4gICAgICAgICAgbGltaXQ/OiBudW1iZXI7XG4gICAgICAgICAgaW5jbHVkZVJlbGF0aW9ucz86IGJvb2xlYW47XG4gICAgICAgICAgbWF4RGVwdGg/OiBudW1iZXI7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvc29uYW11L2ZpeHR1cmUvZmV0Y2hcIiwgYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IHtcbiAgICAgICAgICBlbnRpdHksXG4gICAgICAgICAgc3RyYXRlZ3kgPSBcInJlY2VudFwiLFxuICAgICAgICAgIGxpbWl0ID0gMTAsXG4gICAgICAgICAgaW5jbHVkZVJlbGF0aW9ucyA9IHRydWUsXG4gICAgICAgICAgbWF4RGVwdGggPSAyLFxuICAgICAgICB9ID0gcmVxdWVzdC5ib2R5O1xuXG4gICAgICAgIC8vIFNvdXJjZSBEQiAocHJvZHVjdGlvbi9kZXZlbG9wbWVudCkgLSDsnb3quLAg7KCE7JqpXG4gICAgICAgIGNvbnN0IHNvdXJjZURiID0gREIuZ2V0REIoXCJyXCIpO1xuXG4gICAgICAgIC8vIFRhcmdldCBEQiAoZml4dHVyZSlcbiAgICAgICAgY29uc3QgZml4dHVyZURiID0gY3JlYXRlS25leEluc3RhbmNlKFNvbmFtdS5kYkNvbmZpZy5maXh0dXJlKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIEZpeHR1cmVHZW5lcmF0b3Ig7IOd7ISxXG4gICAgICAgICAgY29uc3QgZ2VuZXJhdG9yID0gbmV3IEZpeHR1cmVHZW5lcmF0b3Ioc291cmNlRGIsIGZpeHR1cmVEYiwgXCJmaXh0dXJlXCIsIEVudGl0eU1hbmFnZXIpO1xuXG4gICAgICAgICAgLy8gcHJvZHVjdGlvbiDrjbDsnbTthLDrpbwgZml4dHVyZSBEQuuhnCBpbXBvcnRcbiAgICAgICAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgZ2VuZXJhdG9yLmltcG9ydEZyb21Tb3VyY2UoZW50aXR5LCB7XG4gICAgICAgICAgICBzdHJhdGVneSxcbiAgICAgICAgICAgIGxpbWl0LFxuICAgICAgICAgICAgaW5jbHVkZVJlbGF0aW9ucyxcbiAgICAgICAgICAgIG1heERlcHRoLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICBlbnRpdHksXG4gICAgICAgICAgICBzdHJhdGVneSxcbiAgICAgICAgICAgIGNvdW50OiByZXN1bHRzLmxlbmd0aCxcbiAgICAgICAgICAgIGltcG9ydGVkOiByZXN1bHRzLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgcmVwbHkuc3RhdHVzKDQwMCk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIC8vIHNvdXJjZURi64qUIFNvbmFtdeqwgCDqtIDrpqztlZjrr4DroZwgZGVzdHJvee2VmOyngCDslYrsnYxcbiAgICAgICAgICBhd2FpdCBmaXh0dXJlRGIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLyoqXG4gICAgICAgKiBGaXh0dXJlIOuNsOydtO2EsCDsgq3soJwgKGNsZWFuKSBBUElcbiAgICAgICAqIEZLIOyInOyEnOulvCDqs6DroKTtlZjsl6wg7JWI7KCE7ZWY6rKMIOyCreygnFxuICAgICAgICovXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdGllcz86IHN0cmluZ1tdO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL3NvbmFtdS9maXh0dXJlL2NsZWFuXCIsIGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICBjb25zdCB7IGVudGl0aWVzIH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgLy8gRml4dHVyZSBEQiDsl7DqsrBcbiAgICAgICAgY29uc3QgZml4dHVyZURiID0gY3JlYXRlS25leEluc3RhbmNlKFNvbmFtdS5kYkNvbmZpZy5maXh0dXJlKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIOyCreygnO2VoCBFbnRpdHkg66qp66GdIOqysOyglVxuICAgICAgICAgIGNvbnN0IHRhcmdldEVudGl0aWVzID1cbiAgICAgICAgICAgIGVudGl0aWVzICYmIGVudGl0aWVzLmxlbmd0aCA+IDAgPyBlbnRpdGllcyA6IEVudGl0eU1hbmFnZXIuZ2V0QWxsSWRzKCk7XG5cbiAgICAgICAgICAvLyBFbnRpdHkgSUTrpbwg7YWM7J2067iU66qF7Jy866GcIOuzgO2ZmCAoc25ha2VfY2FzZSDrs7XsiJjtmJUpXG4gICAgICAgICAgY29uc3QgdGFibGVOYW1lcyA9IHRhcmdldEVudGl0aWVzLm1hcCgoZW50aXR5SWQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgIHJldHVybiBlbnRpdHkudGFibGU7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAvLyBQb3N0Z3JlU1FMOiBUUlVOQ0FURSBDQVNDQURF66GcIEZLIOyInOyEnCDrrLTqtIDtlZjqsowg7JWI7KCE7ZWY6rKMIOyCreygnFxuICAgICAgICAgIC8vIENBU0NBREUg7Ji17IWY7Jy866GcIOydmOyhtOyEsSDsnojripQg642w7J207YSw64+EIO2VqOq7mCDsgq3soJxcbiAgICAgICAgICBhd2FpdCBmaXh0dXJlRGIucmF3KFxuICAgICAgICAgICAgYFRSVU5DQVRFIFRBQkxFICR7dGFibGVOYW1lcy5tYXAoKHQpID0+IGBcIiR7dH1cImApLmpvaW4oXCIsIFwiKX0gUkVTVEFSVCBJREVOVElUWSBDQVNDQURFYCxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICBjbGVhbmVkOiB0YWJsZU5hbWVzLFxuICAgICAgICAgICAgY291bnQ6IHRhYmxlTmFtZXMubGVuZ3RoLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgcmVwbHkuc3RhdHVzKDQwMCk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGF3YWl0IGZpeHR1cmVEYi5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvLyBDREQgQVBJXG4gICAgICBzZXJ2ZXIuZ2V0KFwiL2FwaS9jZGQvdHJlZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHJldHVybiBnZXRDZGRUcmVlKCk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8eyBCb2R5OiB7IGZpbGVQYXRoOiBzdHJpbmcgfSB9PihcIi9hcGkvY2RkL3JlYWRDb250ZW50XCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgZmlsZVBhdGggfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgcmV0dXJuIHJlYWRDb250ZW50KGZpbGVQYXRoKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7IEJvZHk6IHsgZmlsZVBhdGg6IHN0cmluZyB9IH0+KFwiL2FwaS9jZGQvZWRpdENvbnRlbnRcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgeyBmaWxlUGF0aCB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICByZXR1cm4gZWRpdENvbnRlbnQoZmlsZVBhdGgpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHsgQm9keTogeyBmaWxlUGF0aDogc3RyaW5nIH0gfT4oXCIvYXBpL2NkZC9vcGVuU291cmNlXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgZmlsZVBhdGggfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgb3BlblNvdXJjZUZpbGUoZmlsZVBhdGgpO1xuICAgICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlIH07XG4gICAgICB9KTtcblxuICAgICAgLy8gQ0REIFJ1bGVzIEFQSVxuICAgICAgc2VydmVyLmdldChcIi9hcGkvY2RkL3J1bGVzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgcmV0dXJuIGxpc3RSdWxlcygpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHsgQm9keTogeyBydWxlS2V5OiBzdHJpbmcgfSB9PihcIi9hcGkvY2RkL3JlYWRSdWxlXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgcnVsZUtleSB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICByZXR1cm4gcmVhZFJ1bGUocnVsZUtleSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8eyBCb2R5OiBDZGRBZGRSdWxlUmVxdWVzdCB9PihcIi9hcGkvY2RkL2FkZFJ1bGVcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIGFkZFJ1bGUocmVxdWVzdC5ib2R5KTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBDREQgQUMgQVBJXG4gICAgICBzZXJ2ZXIuZ2V0KFwiL2FwaS9jZGQvYWNcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgICByZXR1cm4gZ2V0QWNMaXN0KCk7XG4gICAgICB9KTtcblxuICAgICAgLy8gdWktd2ViIOu5jOuTnCDtjIzsnbwg7ISc67mZXG4gICAgICBjb25zdCB1aURpc3RQYXRoID0gcGF0aC5yZXNvbHZlKGltcG9ydC5tZXRhLmRpcm5hbWUsIFwiLi4vdWktd2ViXCIpO1xuXG4gICAgICAvLyDsoJXsoIEg7YyM7J28IOyEnOu5mTog66Oo7Yq4IO2PtOuNlCDsoITssrQgKGFzc2V0cywgc2V0dGluZy5zdmcg65OxKVxuICAgICAgc2VydmVyLnJlZ2lzdGVyKGF3YWl0IGltcG9ydChcIkBmYXN0aWZ5L3N0YXRpY1wiKSwge1xuICAgICAgICByb290OiB1aURpc3RQYXRoLFxuICAgICAgICBwcmVmaXg6IFwiL1wiLFxuICAgICAgICBkZWNvcmF0ZVJlcGx5OiBmYWxzZSxcbiAgICAgICAgd2lsZGNhcmQ6IGZhbHNlLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFNQQSBmYWxsYmFjayAtIOygleyggSDtjIzsnbzsnbQg7JeG64qUIOuqqOuToCDqsr3roZzripQgaW5kZXguaHRtbOuhnFxuICAgICAgc2VydmVyLmdldChcIipcIiwgYXN5bmMgKF9yZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICByZXBseS5oZWFkZXJzKHsgXCJDb250ZW50LXR5cGVcIjogXCJ0ZXh0L2h0bWxcIiB9KS5zZW5kKFxuICAgICAgICAgIGZzXG4gICAgICAgICAgICAucmVhZEZpbGVTeW5jKHBhdGgucmVzb2x2ZSh1aURpc3RQYXRoLCBcImluZGV4Lmh0bWxcIikpXG4gICAgICAgICAgICAudG9TdHJpbmcoKVxuICAgICAgICAgICAgLnJlcGxhY2UoXCJ7e3Byb2plY3ROYW1lfX1cIiwgU29uYW11LmNvbmZpZy5wcm9qZWN0TmFtZSA/PyBcIlVua25vd25Tb25hbXVQcm9qZWN0XCIpLFxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSxcbiAgICB7IHByZWZpeDogXCIvc29uYW11LXVpXCIgfSxcbiAgKTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFvREEsZUFBc0Isa0JBQWtCLFNBQTBCO0NBQ2hFLFFBQVEsU0FDTixPQUFPLFdBQVc7RUFFaEIsZUFBZSxvQkFBdUIsSUFBa0M7R0FDdEUsTUFBTSxjQUFjLElBQUksU0FBZSxZQUFZO0lBQ2pELE1BQU0sZ0JBQWdCO0tBQ3BCLGFBQWEsT0FBTztLQUNwQixRQUFRO0lBQ1Y7SUFFQSxNQUFNLFVBQVUsaUJBQWlCO0tBQy9CLE9BQU8sT0FBTyxhQUFhLElBQUksa0JBQWtCLE9BQU87S0FDeEQsUUFBUTtJQUNWLEdBQUcsSUFBSTtJQUVQLE9BQU8sT0FBTyxhQUFhLEtBQUssa0JBQWtCLE9BQU87R0FDM0QsQ0FBQztHQUVELE1BQU0sU0FBUyxNQUFNLEdBQUc7R0FDeEIsTUFBTTtHQUNOLE9BQU87RUFDVDtFQUVBLE1BQU0sU0FBUyxNQUFNO0VBQ3JCLE1BQU0sc0JBQXNCLE1BQU07RUFFbEMsT0FBTyxJQUFJLHNCQUFzQixZQUFZO0dBQzNDLE9BQU8sT0FBTztFQUNoQixDQUFDO0VBRUQsT0FBTyxJQU1KLHlCQUF5QixPQUFPLFlBQVk7R0FDN0MsTUFBTSxFQUFFLFVBQVUsUUFBUSxZQUFZLFFBQVE7R0EwQjlDLFNBQVMsZUF4QmlCO0lBQ3hCLElBQUksWUFBWSxRQUFRO0tBQ3RCLE1BQU0sU0FBUyxjQUFjLElBQUksUUFBUTtLQUN6QyxNQUFNLEVBQUUsVUFBVTtLQUVsQixNQUFNLEVBQUUsZ0JBQWdCO0tBQ3hCLE1BQU0sa0JBQWtCO01BQ3RCLFFBQVEsUUFBUjtPQUNFLEtBQUssU0FDSCxPQUFPLEdBQUcsTUFBTSxHQUFHO09BQ3JCLEtBQUssZUFDSCxPQUFPLEdBQUcsTUFBTSxHQUFHO09BQ3JCLEtBQUssYUFDSCxPQUFPLEdBQUcs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
748
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91aS9hcGkudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhlY0ZpbGVTeW5jLCBleGVjU3luYyB9IGZyb20gXCJjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5pbXBvcnQgeyB0eXBlIEZhc3RpZnlJbnN0YW5jZSB9IGZyb20gXCJmYXN0aWZ5XCI7XG5pbXBvcnQgaW5mbGVjdGlvbiBmcm9tIFwiaW5mbGVjdGlvblwiO1xuaW1wb3J0IHsgcmFuZ2UgfSBmcm9tIFwicmFkYXNoaVwiO1xuXG5pbXBvcnQgeyBTb25hbXUgfSBmcm9tIFwiLi4vYXBpL3NvbmFtdVwiO1xuaW1wb3J0IHsgREIgfSBmcm9tIFwiLi4vZGF0YWJhc2UvZGJcIjtcbmltcG9ydCB7IHR5cGUgU29uYW11REJDb25maWcgfSBmcm9tIFwiLi4vZGF0YWJhc2UvZGJcIjtcbmltcG9ydCB7IGNyZWF0ZUtuZXhJbnN0YW5jZSB9IGZyb20gXCIuLi9kYXRhYmFzZS9rbmV4XCI7XG5pbXBvcnQgeyBTRCB9IGZyb20gXCIuLi9kaWN0L3NkXCI7XG5pbXBvcnQgeyBzb25hbXVEaWN0aW9uYXJ5IH0gZnJvbSBcIi4uL2RpY3Qvc29uYW11LWRpY3Rpb25hcnlcIjtcbmltcG9ydCB7IHR5cGUgRW50aXR5IH0gZnJvbSBcIi4uL2VudGl0eS9lbnRpdHlcIjtcbmltcG9ydCB7IEVudGl0eU1hbmFnZXIgfSBmcm9tIFwiLi4vZW50aXR5L2VudGl0eS1tYW5hZ2VyXCI7XG5pbXBvcnQge1xuICBCYWRSZXF1ZXN0RXhjZXB0aW9uLFxuICBpc1NvRXhjZXB0aW9uLFxuICBTZXJ2aWNlVW5hdmFpbGFibGVFeGNlcHRpb24sXG59IGZyb20gXCIuLi9leGNlcHRpb25zL3NvLWV4Y2VwdGlvbnNcIjtcbmltcG9ydCB7IFRlbXBsYXRlTWFuYWdlciB9IGZyb20gXCIuLi90ZW1wbGF0ZS90ZW1wbGF0ZS1tYW5hZ2VyXCI7XG5pbXBvcnQgeyBEYXRhRXhwbG9yZXIsIHR5cGUgRGF0YUV4cGxvcmVyT3B0aW9ucyB9IGZyb20gXCIuLi90ZXN0aW5nL2RhdGEtZXhwbG9yZXJcIjtcbmltcG9ydCB7IEZpeHR1cmVHZW5lcmF0b3IsIHR5cGUgRml4dHVyZUdlbmVyYXRpb25TcGVjIH0gZnJvbSBcIi4uL3Rlc3RpbmcvZml4dHVyZS1nZW5lcmF0b3JcIjtcbmltcG9ydCB7IEZpeHR1cmVNYW5hZ2VyIH0gZnJvbSBcIi4uL3Rlc3RpbmcvZml4dHVyZS1tYW5hZ2VyXCI7XG5pbXBvcnQgeyB0eXBlIER1cGxpY2F0ZUNoZWNrT3B0aW9ucyB9IGZyb20gXCIuLi90ZXN0aW5nL2ZpeHR1cmUtbWFuYWdlclwiO1xuaW1wb3J0IHsgQlVJTFRfSU5fVFlQRV9JRFMsIFRlbXBsYXRlS2V5IH0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQge1xuICB0eXBlIENvbmUsXG4gIHR5cGUgRW50aXR5SW5kZXgsXG4gIHR5cGUgRW50aXR5UHJvcCxcbiAgdHlwZSBFbnRpdHlTdWJzZXRSb3csXG4gIHR5cGUgRml4dHVyZVJlY29yZCxcbiAgdHlwZSBGaXh0dXJlU2VhcmNoT3B0aW9ucyxcbiAgdHlwZSBGbGF0dGVuU3Vic2V0Um93LFxuICB0eXBlIFBhdGhBbmRDb2RlLFxufSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IGlzT2JqZWN0VmFsdWUgfSBmcm9tIFwiLi4vdXRpbHMvcnVudGltZS12YWx1ZVwiO1xuaW1wb3J0IHsgbm9uTnVsbGFibGUgfSBmcm9tIFwiLi4vdXRpbHMvdXRpbHNcIjtcbmltcG9ydCB7IHNldEFpQXBpIH0gZnJvbSBcIi4vYWktYXBpXCI7XG5pbXBvcnQgeyBmb3J3YXJkQXN5bmNFcnJvcnMgfSBmcm9tIFwiLi9hc3luYy1yb3V0ZVwiO1xuaW1wb3J0IHsgdHlwZSBDZGRBZGRSdWxlUmVxdWVzdCB9IGZyb20gXCIuL2NkZC1zZXJ2aWNlXCI7XG5pbXBvcnQge1xuICBhZGRSdWxlLFxuICBlZGl0Q29udGVudCxcbiAgZ2V0QWNMaXN0LFxuICBnZXRDZGRUcmVlLFxuICBsaXN0UnVsZXMsXG4gIG9wZW5Tb3VyY2VGaWxlLFxuICByZWFkQ29udGVudCxcbiAgcmVhZFJ1bGUsXG59IGZyb20gXCIuL2NkZC1zZXJ2aWNlXCI7XG5pbXBvcnQgeyByZWdpc3Rlck1pZ3JhdGlvbnNBcGkgfSBmcm9tIFwiLi9taWdyYXRpb25zLWFwaVwiO1xuXG5pbnRlcmZhY2UgRW50aXR5VGVtcGxhdGVJbnB1dCB7XG4gIGVudGl0eUlkOiBzdHJpbmc7XG4gIGVudW1JZD86IHN0cmluZztcbn1cblxuYXN5bmMgZnVuY3Rpb24gd2FpdEZvckhNUkNvbXBsZXRlZDxUPihmbjogKCkgPT4gUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICBjb25zdCB3YWl0UHJvbWlzZSA9IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgY29uc3QgaGFuZGxlciA9ICgpID0+IHtcbiAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgIHJlc29sdmUoKTtcbiAgICB9O1xuXG4gICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgU29uYW11LnN5bmNlci5ldmVudEVtaXR0ZXIub2ZmKFwib25ITVJDb21wbGV0ZWRcIiwgaGFuZGxlcik7XG4gICAgICByZXNvbHZlKCk7XG4gICAgfSwgMTUwMCk7XG5cbiAgICBTb25hbXUuc3luY2VyLmV2ZW50RW1pdHRlci5vbmNlKFwib25ITVJDb21wbGV0ZWRcIiwgaGFuZGxlcik7XG4gIH0pO1xuXG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZuKCk7XG4gIGF3YWl0IHdhaXRQcm9taXNlO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBmbGF0dGVuU3Vic2V0Um93cyhzdWJzZXRSb3dzOiBFbnRpdHlTdWJzZXRSb3dbXSk6IEZsYXR0ZW5TdWJzZXRSb3dbXSB7XG4gIHJldHVybiBzdWJzZXRSb3dzLmZsYXRNYXAoKHN1YnNldFJvdykgPT4ge1xuICAgIGNvbnN0IHsgY2hpbGRyZW4sIC4uLnNSb3cgfSA9IHN1YnNldFJvdztcbiAgICByZXR1cm4gW3NSb3csIC4uLmZsYXR0ZW5TdWJzZXRSb3dzKGNoaWxkcmVuKV07XG4gIH0pO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc29uYW11VUlBcGlQbHVnaW4oZmFzdGlmeTogRmFzdGlmeUluc3RhbmNlKSB7XG4gIGZhc3RpZnkucmVnaXN0ZXIoXG4gICAgYXN5bmMgKHNlcnZlcikgPT4ge1xuICAgICAgYXdhaXQgc2V0QWlBcGkoc2VydmVyKTtcbiAgICAgIGF3YWl0IHJlZ2lzdGVyTWlncmF0aW9uc0FwaShzZXJ2ZXIpO1xuXG4gICAgICBzZXJ2ZXIuZ2V0KFwiL2FwaS9zb25hbXUvY29uZmlnXCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgcmV0dXJuIFNvbmFtdS5jb25maWc7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldDx7XG4gICAgICAgIFF1ZXJ5c3RyaW5nOiB7XG4gICAgICAgICAgZW50aXR5SWQ/OiBzdHJpbmc7XG4gICAgICAgICAgcHJlc2V0PzogXCJ0eXBlc1wiIHwgXCJlbnRpdHkuanNvblwiIHwgXCJnZW5lcmF0ZWRcIjtcbiAgICAgICAgICBhYnNQYXRoPzogc3RyaW5nO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL3Rvb2xzL29wZW5Wc2NvZGVcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgcHJlc2V0LCBhYnNQYXRoIH0gPSByZXF1ZXN0LnF1ZXJ5O1xuXG4gICAgICAgICAgY29uc3QgdGFyZ2V0UGF0aCA9ICgoKSA9PiB7XG4gICAgICAgICAgICBpZiAoZW50aXR5SWQgJiYgcHJlc2V0KSB7XG4gICAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgICAgY29uc3QgeyBuYW1lcyB9ID0gZW50aXR5O1xuXG4gICAgICAgICAgICAgIGNvbnN0IHsgYXBpUm9vdFBhdGggfSA9IFNvbmFtdTtcbiAgICAgICAgICAgICAgY29uc3QgZmlsZW5hbWUgPSAoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHN3aXRjaCAocHJlc2V0KSB7XG4gICAgICAgICAgICAgICAgICBjYXNlIFwidHlwZXNcIjpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke25hbWVzLmZzfS50eXBlcy50c2A7XG4gICAgICAgICAgICAgICAgICBjYXNlIFwiZW50aXR5Lmpzb25cIjpcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke25hbWVzLmZzfS5lbnRpdHkuanNvbmA7XG4gICAgICAgICAgICAgICAgICBjYXNlIFwiZ2VuZXJhdGVkXCI6XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBgJHtuYW1lcy5mc30uZ2VuZXJhdGVkLnRzYDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgICAgICAgcmV0dXJuIGAke2FwaVJvb3RQYXRofS9zcmMvYXBwbGljYXRpb24vJHtlbnRpdHkubmFtZXMucGFyZW50RnN9LyR7ZmlsZW5hbWV9YDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmICghYWJzUGF0aCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLnByZXNldE9yQWJzUGF0aFJlcXVpcmVkXCIpKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gYWJzUGF0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KSgpO1xuICAgICAgICAgIGV4ZWNTeW5jKGBjb2RlICR7dGFyZ2V0UGF0aH1gKTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIuZ2V0PHtcbiAgICAgICAgUXVlcnlzdHJpbmc6IHtcbiAgICAgICAgICBlZGl0b3I6IFwidnNjb2RlXCIgfCBcImN1cnNvclwiIHwgXCJ6ZWRcIjtcbiAgICAgICAgICBhYnNQYXRoOiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvdG9vbHMvb3BlbkVkaXRvclwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCBjb21tYW5kcyA9IHtcbiAgICAgICAgICAgIHZzY29kZTogXCJjb2RlXCIsXG4gICAgICAgICAgICBjdXJzb3I6IFwiY3Vyc29yXCIsXG4gICAgICAgICAgICB6ZWQ6IFwiemVkXCIsXG4gICAgICAgICAgfSBhcyBjb25zdDtcbiAgICAgICAgICBjb25zdCBjb21tYW5kID0gY29tbWFuZHNbcmVxdWVzdC5xdWVyeS5lZGl0b3JdO1xuICAgICAgICAgIGlmIChjb21tYW5kID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwiZXJyb3IuYmFkUmVxdWVzdFwiKSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8g7IW47J2EIOqxsOy5mOyngCDslYrslYQg7YyM7J28IOqyveuhnOqwgCDrqoXroLnsnLzroZwg7ZW07ISd65CY7KeAIOyViuuPhOuhnSDtlanri4jri6QuXG4gICAgICAgICAgZXhlY0ZpbGVTeW5jKGNvbW1hbmQsIFtyZXF1ZXN0LnF1ZXJ5LmFic1BhdGhdKTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIuZ2V0PHtcbiAgICAgICAgUXVlcnlzdHJpbmc6IHtcbiAgICAgICAgICBvcmlnaW46IHN0cmluZztcbiAgICAgICAgICBlbnRpdHlJZD86IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS90b29scy9nZXRTdWdnZXN0aW9uXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgb3JpZ2luLCBlbnRpdHlJZCB9ID0gcmVxdWVzdC5xdWVyeTtcblxuICAgICAgICAgIC8vIOy5mO2ZmCDsmqnslrTsp5FcbiAgICAgICAgICBjb25zdCBnbG9zc2FyeSA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KFtcbiAgICAgICAgICAgIFtcInN0YXR1c1wiLCBcIuyDge2DnFwiXSxcbiAgICAgICAgICAgIFtcInR5cGVcIiwgXCLtg4DsnoVcIl0sXG4gICAgICAgICAgICBbXCJpbWFnZVwiLCBcIuydtOuvuOyngFwiXSxcbiAgICAgICAgICAgIFtcImltYWdlc1wiLCBcIuydtOuvuOyngOumrOyKpO2KuFwiXSxcbiAgICAgICAgICAgIFtcInVybFwiLCBcIlVSTFwiXSxcbiAgICAgICAgICAgIFtcImlkXCIsIFwiSURcIl0sXG4gICAgICAgICAgICBbXCJuYW1lXCIsIGB7RW50aXR5SUR966qFYF0sXG4gICAgICAgICAgICBbXCJ0aXRsZVwiLCBcIntFbnRpdHlJRH3rqoVcIl0sXG4gICAgICAgICAgICBbXCJwYXJlbnRcIiwgXCLsg4HsnIR7RW50aXR5SUR9XCJdLFxuICAgICAgICAgICAgW1wiZGVzY1wiLCBcIuyEpOuqhVwiXSxcbiAgICAgICAgICAgIFtcImF0XCIsIFwi7J287IucXCJdLFxuICAgICAgICAgICAgW1wiY3JlYXRlZFwiLCBcIuuTseuhnVwiXSxcbiAgICAgICAgICAgIFtcInVwZGF0ZWRcIiwgXCLsiJjsoJVcIl0sXG4gICAgICAgICAgICBbXCJkZWxldGVkXCIsIFwi7IKt7KCcXCJdLFxuICAgICAgICAgICAgW1wiYnlcIiwgXCLsnKDsoIBcIl0sXG4gICAgICAgICAgICBbXCJkYXRlXCIsIFwi7J287J6QXCJdLFxuICAgICAgICAgICAgW1widGltZVwiLCBcIuyLnOqwhFwiXSxcbiAgICAgICAgICAgIFtcImtvXCIsIFwiKO2VnOq4gClcIl0sXG4gICAgICAgICAgICBbXCJlblwiLCBcIijsmIHrrLgpXCJdLFxuICAgICAgICAgICAgW1wia3J3XCIsIFwiKOybkClcIl0sXG4gICAgICAgICAgICBbXCJ1c2RcIiwgXCIoVVNEKVwiXSxcbiAgICAgICAgICAgIFtcImNvbG9yXCIsIFwi7Lus65+sXCJdLFxuICAgICAgICAgICAgW1wiY29kZVwiLCBcIuy9lOuTnFwiXSxcbiAgICAgICAgICAgIFtcInhcIiwgXCJY7KKM7ZGcXCJdLFxuICAgICAgICAgICAgW1wieVwiLCBcIlnsooztkZxcIl0sXG4gICAgICAgICAgICBbXCJjdXJyZW50XCIsIFwi7ZiE7J6sXCJdLFxuICAgICAgICAgICAgW1wic3RvY2tcIiwgXCLsnqzqs6BcIl0sXG4gICAgICAgICAgICBbXCJ0b3RhbFwiLCBcIuy0nVwiXSxcbiAgICAgICAgICAgIFtcImFkbWluXCIsIFwi6rSA66as7J6QXCJdLFxuICAgICAgICAgICAgW1wiZ3JvdXBcIiwgXCLqt7jro7lcIl0sXG4gICAgICAgICAgICBbXCJpdGVtXCIsIFwi7JWE7J207YWcXCJdLFxuICAgICAgICAgICAgW1wiY250XCIsIFwi7IiY65+JXCJdLFxuICAgICAgICAgICAgW1wicHJpY2VcIiwgXCLqsIDqsqlcIl0sXG4gICAgICAgICAgICBbXCJwcmVzZXRcIiwgXCLtlITrpqzshYtcIl0sXG4gICAgICAgICAgICBbXCJhY2N0XCIsIFwi6rOE7KKMXCJdLFxuICAgICAgICAgICAgW1widGVsXCIsIFwi7KCE7ZmU67KI7Zi4XCJdLFxuICAgICAgICAgICAgW1wibm9cIiwgXCLrsojtmLhcIl0sXG4gICAgICAgICAgICBbXCJib2R5XCIsIFwi64K07JqpXCJdLFxuICAgICAgICAgICAgW1wiY29udGVudFwiLCBcIuuCtOyaqVwiXSxcbiAgICAgICAgICAgIFtcIm9yZGVybm9cIiwgXCLsoJXroKzsiJzshJxcIl0sXG4gICAgICAgICAgICBbXCJwcmlvcml0eVwiLCBcIuyasOyEoOyInOychFwiXSxcbiAgICAgICAgICAgIFtcInRleHRcIiwgXCLthY3siqTtirhcIl0sXG4gICAgICAgICAgICBbXCJrZXlcIiwgXCLtgqRcIl0sXG4gICAgICAgICAgICBbXCJzdW1cIiwgXCLtlansgrBcIl0sXG4gICAgICAgICAgICBbXCJleHBlY3RlZFwiLCBcIuyYiOyDgVwiXSxcbiAgICAgICAgICAgIFtcImFjdHVhbFwiLCBcIuyLpOygnFwiXSxcbiAgICAgICAgICBdKTtcbiAgICAgICAgICAvLyDsoITssrQg7JeU7Yuw7YuwIOyInO2ajO2VmOupsCwg7JeU7Yuw7YuwIO2DgOydtO2LgOqzvCDtlITroa0g7ISk66qF7J2EIOy5mO2ZmCDsmqnslrTsp5Hsl5Ag7LaU6rCAXG4gICAgICAgICAgZm9yIChjb25zdCBnbG9zc2FyeUVudGl0eUlkIG9mIEVudGl0eU1hbmFnZXIuZ2V0QWxsSWRzKCkpIHtcbiAgICAgICAgICAgIGNvbnN0IGdsb3NzYXJ5RW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZ2xvc3NhcnlFbnRpdHlJZCk7XG4gICAgICAgICAgICBpZiAoKGdsb3NzYXJ5RW50aXR5LnRpdGxlID8/IFwiXCIpICE9PSBcIlwiKSB7XG4gICAgICAgICAgICAgIGdsb3NzYXJ5LnNldChpbmZsZWN0aW9uLnVuZGVyc2NvcmUoZ2xvc3NhcnlFbnRpdHkuaWQpLCBnbG9zc2FyeUVudGl0eS50aXRsZSk7XG4gICAgICAgICAgICAgIGdsb3NzYXJ5LnNldChcbiAgICAgICAgICAgICAgICBpbmZsZWN0aW9uLnVuZGVyc2NvcmUoaW5mbGVjdGlvbi5wbHVyYWxpemUoZ2xvc3NhcnlFbnRpdHkuaWQpKSxcbiAgICAgICAgICAgICAgICBgJHtnbG9zc2FyeUVudGl0eS50aXRsZX3rpqzsiqTtirhgLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBnbG9zc2FyeUVudGl0eS5wcm9wcy5mb3JFYWNoKChwcm9wKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChnbG9zc2FyeS5oYXMocHJvcC5uYW1lKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAocHJvcC5kZXNjKSB7XG4gICAgICAgICAgICAgICAgZ2xvc3Nhcnkuc2V0KFxuICAgICAgICAgICAgICAgICAgcHJvcC5uYW1lLFxuICAgICAgICAgICAgICAgICAgcHJvcC5kZXNjLnJlcGxhY2UoZ2xvc3NhcnlFbnRpdHkudGl0bGUgPz8gXCJcIiwgXCJ7RW50aXR5SUR9XCIpLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHN1Z2dlc3RlZCA9ICgoKSA9PiB7XG4gICAgICAgICAgICAvLyDri6jslrQg67aE66asLCDqsIDriqXtlZwg7KGw7ZWpIOyDneyEsVxuICAgICAgICAgICAgY29uc3Qgd29yZHMgPSBvcmlnaW4uc3BsaXQoXCJfXCIpO1xuICAgICAgICAgICAgY29uc3QgY29tYmluYXRpb25zID0gWy4uLnJhbmdlKHdvcmRzLmxlbmd0aCwgMCwgLTEpXS5mbGF0TWFwKChsZW4pID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgICAgICAuLi5yYW5nZSgwLCB3b3Jkcy5sZW5ndGggLSBsZW4gKyAxLCAoaWR4KSA9PiB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBsZW4sXG4gICAgICAgICAgICAgICAgICAgIHc6IHdvcmRzLnNsaWNlKGlkeCwgaWR4ICsgbGVuKS5qb2luKFwiX1wiKSxcbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIF07XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8g7KGw7ZWp7J2EIOyInO2ajO2VmOupsCwg7LmY7ZmYIOyaqeyWtOynkeyXkCDsnojripQg64uo7Ja06rCAIO2PrO2VqOuQnCDqsr3smrAsIOy5mO2ZmCDsmqnslrTroZwg7LmY7ZmYXG4gICAgICAgICAgICBjb25zdCBSRVBMQUNFRF9QUkVGSVggPSBcIiNSRVBMQUNFRC8vXCI7IC8vIOy5mO2ZmOuQnCDri6jslrTrpbwgam9pbiDsnbTtm4Tsl5Drj4Qg7Iud67OE7ZWY6riwIOychO2VtCBwcmVmaXgg7LaU6rCAXG4gICAgICAgICAgICBsZXQgcmVtYWluQXJyOiBzdHJpbmdbXSA9IFsuLi53b3Jkc107XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGNvbWIgb2YgY29tYmluYXRpb25zKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHJlbWFpblN0ciA9IHJlbWFpbkFyci5qb2luKFwiX1wiKTtcbiAgICAgICAgICAgICAgaWYgKHJlbWFpblN0ci5pbmNsdWRlcyhjb21iLncpICYmIGdsb3NzYXJ5Lmhhcyhjb21iLncpKSB7XG4gICAgICAgICAgICAgICAgcmVtYWluQXJyID0gcmVtYWluU3RyXG4gICAgICAgICAgICAgICAgICAucmVwbGFjZShjb21iLncsIFJFUExBQ0VEX1BSRUZJWCArIGdsb3NzYXJ5LmdldChjb21iLncpKVxuICAgICAgICAgICAgICAgICAgLnNwbGl0KFwiX1wiKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmVtYWluQXJyXG4gICAgICAgICAgICAgIC5tYXAoKHIpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoci5zdGFydHNXaXRoKFJFUExBQ0VEX1BSRUZJWCkpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiByLnJlcGxhY2UoUkVQTEFDRURfUFJFRklYLCBcIlwiKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHIudG9VcHBlckNhc2UoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIC5qb2luKFwiXCIpXG4gICAgICAgICAgICAgIC5yZXBsYWNlKC97RW50aXR5SUR9L2csIGVudGl0eUlkID8gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpLnRpdGxlIDogXCJcIik7XG4gICAgICAgICAgfSkoKTtcblxuICAgICAgICAgIHJldHVybiB7IHN1Z2dlc3RlZCB9O1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL2VudGl0eS9maW5kTWFueVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGVudGl0eUlkcyA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsSWRzKCk7XG5cbiAgICAgICAgY29uc3QgZW50aXRpZXMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICBlbnRpdHlJZHMubWFwKChlbnRpdHlJZCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgICAgY29uc3Qgc3Vic2V0Um93cyA9IGVudGl0eS5nZXRTdWJzZXRSb3dzKCk7XG5cbiAgICAgICAgICAgIC8vIHpvZCDsnbjsiqTthLTsiqTrpbwgc3ByZWFk7ZWY66m0IEpTT04uc3RyaW5naWZ56rCAIHJlZmVyZW5jZeulvCDsnbjrnbzsnbjsnLzroZwg7ZKA7Ja064K066mwIOydkeuLteydtCDsiJjrsLEgTULquYzsp4Ag67aA7ZKA7Ja0IFY4IHN0cmluZyBsaW1pdOulvCDstIjqs7ztlZzri6QuXG4gICAgICAgICAgICBjb25zdCB7XG4gICAgICAgICAgICAgIHR5cGVzOiBfdHlwZXMsXG4gICAgICAgICAgICAgIGVudW1zOiBfZW51bXMsXG4gICAgICAgICAgICAgIGVudW1Db25lczogX2VudW1Db25lcyxcbiAgICAgICAgICAgICAgc3Vic2V0Q29uZXM6IF9zdWJzZXRDb25lcyxcbiAgICAgICAgICAgICAgLi4ucmVzdFxuICAgICAgICAgICAgfSA9IGVudGl0eTtcblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgLi4ucmVzdCxcbiAgICAgICAgICAgICAgZmxhdHRlblN1YnNldFJvd3M6IGZsYXR0ZW5TdWJzZXRSb3dzKHN1YnNldFJvd3MpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcblxuICAgICAgICBlbnRpdGllcy5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgICAgY29uc3QgYUlkID0gYS5wYXJlbnRJZCA/PyBhLmlkO1xuICAgICAgICAgIGNvbnN0IGJJZCA9IGIucGFyZW50SWQgPz8gYi5pZDtcbiAgICAgICAgICBpZiAoYUlkIDwgYklkKSByZXR1cm4gLTE7XG4gICAgICAgICAgaWYgKGFJZCA+IGJJZCkgcmV0dXJuIDE7XG4gICAgICAgICAgaWYgKGFJZCA9PT0gYklkKSB7XG4gICAgICAgICAgICBpZiAoYS5wYXJlbnRJZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gLTE7XG4gICAgICAgICAgICBpZiAoYi5wYXJlbnRJZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gMTtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB7IGVudGl0aWVzIH07XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldDx7XG4gICAgICAgIFF1ZXJ5c3RyaW5nOiB7XG4gICAgICAgICAgZmlsdGVyPzogXCJlbnVtc1wiIHwgXCJ0eXBlc1wiO1xuICAgICAgICAgIHJlbG9hZD86IFwiMVwiO1xuICAgICAgICB9O1xuICAgICAgfT4oXG4gICAgICAgIFwiL2FwaS9lbnRpdHkvdHlwZUlkc1wiLFxuICAgICAgICAocmVxdWVzdCk6IFByb21pc2U8eyB0eXBlSWRzOiBzdHJpbmdbXSB9PiA9PlxuICAgICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGZpbHRlciwgcmVsb2FkIH0gPSByZXF1ZXN0LnF1ZXJ5O1xuXG4gICAgICAgICAgICBpZiAocmVsb2FkID09PSBcIjFcIikge1xuICAgICAgICAgICAgICBhd2FpdCBTb25hbXUuc3luY2VyLmF1dG9sb2FkVHlwZXMoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdHlwZUlkcyA9ICgoKSA9PiB7XG4gICAgICAgICAgICAgIC8vIO2UhOuhnOygne2KuOyXkOyEnCDsoJXsnZjtlZwg7YOA7J6F65OkXG4gICAgICAgICAgICAgIGNvbnN0IHByb2plY3RUeXBlSWRzID0gT2JqZWN0LmVudHJpZXMoU29uYW11LnN5bmNlci50eXBlcylcbiAgICAgICAgICAgICAgICAuZmlsdGVyKChbX3R5cGVJZCwgem9kVHlwZV0pID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHsgX3pvZDogem9kTWV0YWRhdGEgfSA9IHpvZFR5cGU7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgICAgICAvKiBTQUZFVFk6IFVJIOuPhOq1rOydmCBab2Qg7J6F66ClIOyKpO2CpOuniOqwgCDsnbQg6rCS7J2YIO2DgOyeheydhCDrs7TsnqXtlZzri6QuICovICh6b2RNZXRhZGF0YVxuICAgICAgICAgICAgICAgICAgICAgIC5kZWYudHlwZSBhcyBzdHJpbmcpICE9PSBcImVudW1cIlxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5tYXAoKFt0eXBlSWQsIF96b2RUeXBlXSkgPT4gdHlwZUlkKTtcblxuICAgICAgICAgICAgICAvLyDrgrTsnqUg7YOA7J6F65OkIChzb25hbXUg7L2U7Ja07JeQ7IScIOygnOqztSlcbiAgICAgICAgICAgICAgY29uc3QgYnVpbHRJblR5cGVJZHMgPSBbLi4uQlVJTFRfSU5fVFlQRV9JRFNdO1xuXG4gICAgICAgICAgICAgIC8vIOuqqOuToCDtg4DsnoUg67OR7ZWpXG4gICAgICAgICAgICAgIGNvbnN0IGFsbFR5cGVJZHMgPSBbLi4uYnVpbHRJblR5cGVJZHMsIC4uLnByb2plY3RUeXBlSWRzXTtcblxuICAgICAgICAgICAgICBpZiAoZmlsdGVyID09PSBcInR5cGVzXCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYWxsVHlwZUlkcztcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGNvbnN0IGVudW1JZHMgPSBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpLmZsYXRNYXAoKGVudGl0eUlkKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhlbnRpdHkuZW51bUxhYmVscyk7XG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGlmIChmaWx0ZXIgPT09IFwiZW51bXNcIikge1xuICAgICAgICAgICAgICAgIHJldHVybiBlbnVtSWRzO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBbLi4uYWxsVHlwZUlkcywgLi4uZW51bUlkc107XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pKCk7XG5cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHR5cGVJZHMsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZm9ybToge1xuICAgICAgICAgICAgaWQ6IHN0cmluZztcbiAgICAgICAgICAgIHRpdGxlOiBzdHJpbmc7XG4gICAgICAgICAgICB0YWJsZTogc3RyaW5nO1xuICAgICAgICAgICAgcGFyZW50SWQ/OiBzdHJpbmc7XG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvY3JlYXRlXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgZm9ybSB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICAgICAgYXdhaXQgU29uYW11LnN5bmNlci5jcmVhdGVFbnRpdHkoeyAuLi5mb3JtLCBlbnRpdHlJZDogZm9ybS5pZCB9KTtcblxuICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvZGVsXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCBTb25hbXUuc3luY2VyLmRlbEVudGl0eShlbnRpdHlJZCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICBuZXdWYWx1ZXM6IHtcbiAgICAgICAgICAgIHRpdGxlOiBzdHJpbmc7XG4gICAgICAgICAgICB0YWJsZTogc3RyaW5nO1xuICAgICAgICAgICAgcGFyZW50SWQ/OiBzdHJpbmc7XG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvbW9kaWZ5RW50aXR5QmFzZVwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBuZXdWYWx1ZXMgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgIGVudGl0eS50aXRsZSA9IG5ld1ZhbHVlcy50aXRsZTtcbiAgICAgICAgICAgIGVudGl0eS50YWJsZSA9IG5ld1ZhbHVlcy50YWJsZTtcbiAgICAgICAgICAgIGVudGl0eS5wYXJlbnRJZCA9IG5ld1ZhbHVlcy5wYXJlbnRJZDtcbiAgICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG5cbiAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgc3Vic2V0S2V5OiBzdHJpbmc7XG4gICAgICAgICAgZmllbGRzOiBzdHJpbmdbXTtcbiAgICAgICAgICBmaWVsZHNJbnRlcm5hbD86IHN0cmluZ1tdO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9tb2RpZnlTdWJzZXRcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgc3Vic2V0S2V5LCBmaWVsZHMsIGZpZWxkc0ludGVybmFsIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgICBlbnRpdHkuc3Vic2V0c1tzdWJzZXRLZXldID0gZmllbGRzO1xuICAgICAgICAgICAgaWYgKGZpZWxkc0ludGVybmFsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgaWYgKGZpZWxkc0ludGVybmFsLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBlbnRpdHkuc3Vic2V0c0ludGVybmFsW3N1YnNldEtleV0gPSBmaWVsZHNJbnRlcm5hbDtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgZW50aXR5LnN1YnNldHNJbnRlcm5hbFtzdWJzZXRLZXldO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgICByZXR1cm4geyB1cGRhdGVkOiBmaWVsZHMsIHVwZGF0ZWRJbnRlcm5hbDogZmllbGRzSW50ZXJuYWwgfTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIHN1YnNldEtleTogc3RyaW5nO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9kZWxTdWJzZXRcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgc3Vic2V0S2V5IH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgICBkZWxldGUgZW50aXR5LnN1YnNldHNbc3Vic2V0S2V5XTtcbiAgICAgICAgICAgIGRlbGV0ZSBlbnRpdHkuc3Vic2V0c0ludGVybmFsW3N1YnNldEtleV07XG4gICAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIG5ld1Byb3A6IEVudGl0eVByb3A7XG4gICAgICAgICAgYXQ/OiBudW1iZXI7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L2NyZWF0ZVByb3BcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgYXQsIG5ld1Byb3AgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgIGF3YWl0IGVudGl0eS5jcmVhdGVQcm9wKG5ld1Byb3AsIGF0KTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgbmV3UHJvcDogRW50aXR5UHJvcDtcbiAgICAgICAgICBhdDogbnVtYmVyO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9tb2RpZnlQcm9wXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIGF0LCBuZXdQcm9wIH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgIGVudGl0eS5tb2RpZnlQcm9wKG5ld1Byb3AsIGF0KTtcblxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICBhdDogbnVtYmVyO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9kZWxQcm9wXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIGF0IH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgIGVudGl0eS5kZWxQcm9wKGF0KTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgYXQ6IG51bWJlcjtcbiAgICAgICAgICB0bzogbnVtYmVyO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9tb3ZlUHJvcFwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBhdCwgdG8gfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgICAgZW50aXR5Lm1vdmVQcm9wKGF0LCB0byk7XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgaW5kZXhlczogRW50aXR5SW5kZXhbXTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvbW9kaWZ5SW5kZXhlc1wiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBpbmRleGVzIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgICBlbnRpdHkuaW5kZXhlcyA9IGluZGV4ZXM7XG4gICAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgICByZXR1cm4geyB1cGRhdGVkOiBpbmRleGVzIH07XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICBlbnVtTGFiZWxzOiBFbnRpdHlbXCJlbnVtTGFiZWxzXCJdO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9tb2RpZnlFbnVtTGFiZWxzXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIGVudW1MYWJlbHMgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgIGVudGl0eS5lbnVtTGFiZWxzID0gZW51bUxhYmVscztcbiAgICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG5cbiAgICAgICAgICAgIHJldHVybiB7IHVwZGF0ZWQ6IGVudW1MYWJlbHMgfTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIG5ld0VudW1JZDogc3RyaW5nO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9jcmVhdGVFbnVtSWRcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgbmV3RW51bUlkIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG5cbiAgICAgICAgICAgIGlmIChlbnRpdHkuZW51bUxhYmVsc1tuZXdFbnVtSWRdKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihg7J2066+4IOyhtOyerO2VmOuKlCBlbnVtSWTsnoXri4jri6Q6ICR7bmV3RW51bUlkfWApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBlbnRpdHkuZW51bUxhYmVsc1tuZXdFbnVtSWRdID0gbmV3RW51bUlkLmVuZHNXaXRoKFwiU3RhdHVzXCIpXG4gICAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgICAgYWN0aXZlOiBcIuuFuOy2nFwiLFxuICAgICAgICAgICAgICAgICAgaGlkZGVuOiBcIuyIqOq5gFwiLFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgOiB7XG4gICAgICAgICAgICAgICAgICBcIlwiOiBcIlwiLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIGVudW1JZDoge1xuICAgICAgICAgICAgYmVmb3JlOiBzdHJpbmc7XG4gICAgICAgICAgICBhZnRlcjogc3RyaW5nO1xuICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L21vZGlmeUVudW1JZFwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBlbnVtSWQgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eUlkcyA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsSWRzKCk7XG4gICAgICAgICAgICBjb25zdCBpc0V4aXN0cyA9IGVudGl0eUlkcy5zb21lKChjYW5kaWRhdGVFbnRpdHlJZCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBjYW5kaWRhdGVFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChjYW5kaWRhdGVFbnRpdHlJZCk7XG4gICAgICAgICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhjYW5kaWRhdGVFbnRpdHkuZW51bUxhYmVscykuaW5jbHVkZXMoZW51bUlkLmFmdGVyKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKGlzRXhpc3RzKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihg7J2066+4IOyhtOyerO2VmOuKlCBFbnVtSWTsnoXri4jri6Q6ICR7ZW51bUlkLmFmdGVyfWApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgICBlbnRpdHkuZW51bUxhYmVsc1tlbnVtSWQuYWZ0ZXJdID0gZW50aXR5LmVudW1MYWJlbHNbZW51bUlkLmJlZm9yZV07XG4gICAgICAgICAgICBkZWxldGUgZW50aXR5LmVudW1MYWJlbHNbZW51bUlkLmJlZm9yZV07XG5cbiAgICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgcmVsYXRlZEVudGl0eUlkIG9mIGVudGl0eUlkcykge1xuICAgICAgICAgICAgICBjb25zdCByZWxhdGVkRW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQocmVsYXRlZEVudGl0eUlkKTtcbiAgICAgICAgICAgICAgZm9yIChjb25zdCBwcm9wIG9mIHJlbGF0ZWRFbnRpdHkucHJvcHMpIHtcbiAgICAgICAgICAgICAgICBpZiAocHJvcC50eXBlID09PSBcImVudW1cIiAmJiBwcm9wLmlkID09PSBlbnVtSWQuYmVmb3JlKSB7XG4gICAgICAgICAgICAgICAgICBwcm9wLmlkID0gZW51bUlkLmFmdGVyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBhd2FpdCByZWxhdGVkRW50aXR5LnNhdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIGVudW1JZDogc3RyaW5nO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9kZWxldGVFbnVtSWRcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgZW51bUlkIH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgICAgIGNvbnN0IGVudGl0eUlkcyA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsSWRzKCk7XG4gICAgICAgICAgICBjb25zdCBpc1JlZmVyZW5jZWQgPSBlbnRpdHlJZHNcbiAgICAgICAgICAgICAgLmZsYXRNYXAoKHJlZmVyZW5jaW5nRW50aXR5SWQpID0+IEVudGl0eU1hbmFnZXIuZ2V0KHJlZmVyZW5jaW5nRW50aXR5SWQpLnByb3BzKVxuICAgICAgICAgICAgICAuc29tZSgocHJvcCkgPT4gcHJvcC50eXBlID09PSBcImVudW1cIiAmJiBwcm9wLmlkID09PSBlbnVtSWQpO1xuICAgICAgICAgICAgaWYgKGlzUmVmZXJlbmNlZCkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZW51bUlkfeulvCDssLjsobDtlZjripQg7ZSE66Gc7Y287Yuw6rCAIOyhtOyerO2VqeuLiOuLpC5gKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgICAgZGVsZXRlIGVudGl0eS5lbnVtTGFiZWxzW2VudW1JZF07XG4gICAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgdGFyZ2V0OiBcImVudGl0eVwiIHwgXCJwcm9wXCIgfCBcImVudW1cIiB8IFwic3Vic2V0XCI7XG4gICAgICAgICAgcHJvcE5hbWU/OiBzdHJpbmc7XG4gICAgICAgICAgZW51bUlkPzogc3RyaW5nO1xuICAgICAgICAgIHN1YnNldEtleT86IHN0cmluZztcbiAgICAgICAgICBjb25lOiBDb25lO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS91cGRhdGVDb25lXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIHRhcmdldCwgcHJvcE5hbWUsIGVudW1JZCwgc3Vic2V0S2V5LCBjb25lIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG5cbiAgICAgICAgICAgIGlmICh0YXJnZXQgPT09IFwiZW50aXR5XCIpIHtcbiAgICAgICAgICAgICAgZW50aXR5LmNvbmUgPSBjb25lO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0YXJnZXQgPT09IFwicHJvcFwiICYmIHByb3BOYW1lKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHByb3AgPSBlbnRpdHkucHJvcHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBwcm9wTmFtZSk7XG4gICAgICAgICAgICAgIGlmIChwcm9wKSB7XG4gICAgICAgICAgICAgICAgLyogU0FGRVRZOiBVSSDrj4TqtazsnZggWm9kIOyeheugpSDsiqTtgqTrp4jqsIAg7J20IOqwkuydmCDtg4DsnoXsnYQg67O07J6l7ZWc64ukLiAqLyAoXG4gICAgICAgICAgICAgICAgICBwcm9wIGFzIHsgY29uZT86IENvbmUgfVxuICAgICAgICAgICAgICAgICkuY29uZSA9IGNvbmU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGFyZ2V0ID09PSBcImVudW1cIiAmJiBlbnVtSWQpIHtcbiAgICAgICAgICAgICAgZW50aXR5LmVudW1Db25lc1tlbnVtSWRdID0gY29uZTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGFyZ2V0ID09PSBcInN1YnNldFwiICYmIHN1YnNldEtleSkge1xuICAgICAgICAgICAgICBlbnRpdHkuc3Vic2V0Q29uZXNbc3Vic2V0S2V5XSA9IGNvbmU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIHByZXNlcnZlRXhpc3Rpbmc/OiBib29sZWFuO1xuICAgICAgICAgIG9ubHlFbXB0eT86IGJvb2xlYW47XG4gICAgICAgICAgbG9jYWxlPzogXCJrb1wiIHwgXCJlblwiIHwgXCJqYVwiO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9nZW5lcmF0ZUNvbmVzXCIsIGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgcHJlc2VydmVFeGlzdGluZywgb25seUVtcHR5LCBsb2NhbGUgfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBFbnRpdHkg7KG07J6sIOyXrOu2gCDtmZXsnbhcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcblxuICAgICAgICAgICAgLy8gbG9jYWxlIOq4sOuzuOqwkjogU29uYW11LmNvbmZpZy5pMThuLmRlZmF1bHRMb2NhbGUg7IKs7JqpXG4gICAgICAgICAgICAvLyBTQUZFVFk6IGkxOG4g6rWs7ISxIOyKpO2CpOuniOqwgCDsp4Dsm5AgbG9jYWxl7J2EIGtvL2VuL2ph66GcIOygnO2VnO2VnOuLpC5cbiAgICAgICAgICAgIGNvbnN0IGVmZmVjdGl2ZUxvY2FsZSA9XG4gICAgICAgICAgICAgIGxvY2FsZSA/PyAoU29uYW11LmNvbmZpZy5pMThuLmRlZmF1bHRMb2NhbGUgYXMgXCJrb1wiIHwgXCJlblwiIHwgXCJqYVwiKTtcblxuICAgICAgICAgICAgLy8gQ29uZSDsg53shLFcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGVudGl0eS5nZW5lcmF0ZUNvbmVzKHtcbiAgICAgICAgICAgICAgcHJlc2VydmVFeGlzdGluZzogcHJlc2VydmVFeGlzdGluZyA/PyB0cnVlLFxuICAgICAgICAgICAgICBvbmx5RW1wdHk6IG9ubHlFbXB0eSA/PyBmYWxzZSxcbiAgICAgICAgICAgICAgbG9jYWxlOiBlZmZlY3RpdmVMb2NhbGUsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKTtcblxuICAgICAgICAgICAgLy8gRW50aXR5IG5vdCBmb3VuZFxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5jbHVkZXMoXCLsobTsnqztlZjsp4Ag7JWK64qUIEVudGl0eVwiKSkge1xuICAgICAgICAgICAgICByZXBseS5zdGF0dXMoNDA0KTtcbiAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBlcnJvcjogYEVudGl0eSBub3QgZm91bmQ6ICR7ZW50aXR5SWR9YCxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQVBJIO2CpCDsl4bsnYxcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmluY2x1ZGVzKFwiQU5USFJPUElDX0FQSV9LRVkgbm90IGZvdW5kXCIpKSB7XG4gICAgICAgICAgICAgIHJlcGx5LnN0YXR1cyg1MDApO1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGVycm9yOiBcIkFQSSBrZXkgbm90IGNvbmZpZ3VyZWRcIixcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gUmF0ZSBsaW1pdFxuICAgICAgICAgICAgaWYgKG1lc3NhZ2UuaW5jbHVkZXMoXCJSYXRlIGxpbWl0IGV4Y2VlZGVkXCIpKSB7XG4gICAgICAgICAgICAgIHJlcGx5LnN0YXR1cyg0MjkpO1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGVycm9yOiBcIlJhdGUgbGltaXQgZXhjZWVkZWQuIFBsZWFzZSB0cnkgYWdhaW4gbGF0ZXIuXCIsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIOq4sO2DgCDsl5Drn6xcbiAgICAgICAgICAgIHJlcGx5LnN0YXR1cyg1MDApO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgIGVycm9yOiBgQ29uZSBnZW5lcmF0aW9uIGZhaWxlZDogJHttZXNzYWdlfWAsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldDx7XG4gICAgICAgIFF1ZXJ5c3RyaW5nOiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvZ2V0VGFibGVDb2x1bW5zXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQgfSA9IHJlcXVlc3QucXVlcnk7XG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgIGNvbnN0IGNvbHVtbnMgPSBlbnRpdHkuZ2V0VGFibGVDb2x1bW5zKCk7XG4gICAgICAgICAgcmV0dXJuIHsgY29sdW1ucyB9O1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkczogc3RyaW5nW107XG4gICAgICAgICAgdGVtcGxhdGVLZXlzOiBzdHJpbmdbXTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9zY2FmZm9sZGluZy9nZXRTdGF0dXNcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZHMsIHRlbXBsYXRlS2V5czogX3RlbXBsYXRlS2V5cyB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICAgIGlmICgoZW50aXR5SWRzID8/IFtdKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLmVudGl0eUlkc1JlcXVpcmVkXCIpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKChfdGVtcGxhdGVLZXlzID8/IFtdKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLnRlbXBsYXRlS2V5c1JlcXVpcmVkXCIpKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBzb3J0aW5nXG4gICAgICAgICAgZW50aXR5SWRzLnNvcnQoKGEsIGIpID0+IChhIDwgYiA/IC0xIDogYSA+IGIgPyAxIDogMCkpO1xuICAgICAgICAgIGNvbnN0IHRlbXBsYXRlS2V5cyA9IFRlbXBsYXRlS2V5Lm9wdGlvbnMuZmlsdGVyKCh0aykgPT4gX3RlbXBsYXRlS2V5cy5pbmNsdWRlcyh0aykpO1xuXG4gICAgICAgICAgY29uc3QgY29tYmluYXRpb25zID0gZW50aXR5SWRzLmZsYXRNYXAoKGVudGl0eUlkKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGVtcGxhdGVLZXlzLm1hcCgodGVtcGxhdGVLZXkpID0+IFtlbnRpdHlJZCwgdGVtcGxhdGVLZXldKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IHN0YXR1c2VzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICBjb21iaW5hdGlvbnMubWFwKGFzeW5jIChbZW50aXR5SWQsIHRlbXBsYXRlS2V5XSkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCB7IHN1YlBhdGgsIGZ1bGxQYXRoLCBpc0V4aXN0cyB9ID0gYXdhaXQgU29uYW11LnN5bmNlci5jaGVja0V4aXN0c0dlbkNvZGUoXG4gICAgICAgICAgICAgICAgZW50aXR5SWQsXG4gICAgICAgICAgICAgICAgLyogU0FGRVRZOiBVSSDrj4TqtazsnZggWm9kIOyeheugpSDsiqTtgqTrp4jqsIAg7J20IOqwkuydmCDtg4DsnoXsnYQg67O07J6l7ZWc64ukLiAqLyB0ZW1wbGF0ZUtleSBhcyBUZW1wbGF0ZUtleSxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBlbnRpdHlJZCxcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZUtleSxcbiAgICAgICAgICAgICAgICBzdWJQYXRoLFxuICAgICAgICAgICAgICAgIGZ1bGxQYXRoLFxuICAgICAgICAgICAgICAgIGlzRXhpc3RzLFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4geyBzdGF0dXNlcyB9O1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgICB0ZW1wbGF0ZUtleTogc3RyaW5nO1xuICAgICAgICAgICAgZW51bUlkPzogc3RyaW5nO1xuICAgICAgICAgICAgb3ZlcndyaXRlPzogYm9vbGVhbjtcbiAgICAgICAgICB9W107XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvc2NhZmZvbGRpbmcvZ2VuZXJhdGVcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBvcHRpb25zIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgaWYgKG9wdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihTRChcInNvbmFtdS5lcnJvci5vcHRpb25zUmVxdWlyZWRcIikpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIDEuIOuqqOuToCDthZztlIzrpr/sl5DshJwg7ZWE7JqU7ZWcIGRpY3Qg7YKk66W8IOyImOynkVxuICAgICAgICAgIGNvbnN0IGtleXMgPSBvcHRpb25zLmZsYXRNYXAoKHsgdGVtcGxhdGVLZXkgfSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZU1hbmFnZXIuZ2V0KHRlbXBsYXRlS2V5KTtcbiAgICAgICAgICAgIHJldHVybiB0ZW1wbGF0ZS5nZXRSZXF1aXJlZERpY3RLZXlzKCkgPz8gW107XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAvLyAyLiB0YXJnZXTrs4TroZwgZW5zdXJlRGljdEtleXMg7Zi47LacICjsiJzssKgg7LKY66asKVxuICAgICAgICAgIGF3YWl0IHNvbmFtdURpY3Rpb25hcnkuZW5zdXJlRGljdEtleXMoWy4uLm5ldyBTZXQoa2V5cyldKTtcblxuICAgICAgICAgIC8vIDMuIO2FnO2UjOumvyDsg53shLEgKOuzkeugrCDsspjrpqwpXG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICBvcHRpb25zLm1hcChhc3luYyAoeyBlbnRpdHlJZCwgdGVtcGxhdGVLZXksIGVudW1JZCwgb3ZlcndyaXRlIH0pID0+IHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgU29uYW11LnN5bmNlci5nZW5lcmF0ZVRlbXBsYXRlKFxuICAgICAgICAgICAgICAgICAgLyogU0FGRVRZOiBVSSDrj4TqtazsnZggWm9kIOyeheugpSDsiqTtgqTrp4jqsIAg7J20IOqwkuydmCDtg4DsnoXsnYQg67O07J6l7ZWc64ukLiAqLyB0ZW1wbGF0ZUtleSBhcyBUZW1wbGF0ZUtleSxcbiAgICAgICAgICAgICAgICAgIC8qIFNBRkVUWTogVUkg64+E6rWs7J2YIFpvZCDsnoXroKUg7Iqk7YKk66eI6rCAIEVudGl0eSDthZztlIzrpr8g7Ji17IWY7J2EIOuztOyepe2VnOuLpC4gKi8ge1xuICAgICAgICAgICAgICAgICAgICBlbnRpdHlJZCxcbiAgICAgICAgICAgICAgICAgICAgZW51bUlkLFxuICAgICAgICAgICAgICAgICAgfSBhcyBFbnRpdHlUZW1wbGF0ZUlucHV0LFxuICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBvdmVyd3JpdGUsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNTb0V4Y2VwdGlvbihlKSAmJiBlLnN0YXR1c0NvZGUgPT09IDU0MSkge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGlmIChyZXN1bHQuZmlsdGVyKG5vbk51bGxhYmxlKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBTZXJ2aWNlVW5hdmFpbGFibGVFeGNlcHRpb24oU0QoXCJzb25hbXUuZXJyb3IuYWxsRmlsZXNHZW5lcmF0ZWRcIikpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIG9wdGlvbjoge1xuICAgICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICAgIHRlbXBsYXRlS2V5OiBzdHJpbmc7XG4gICAgICAgICAgICBlbnVtSWQ/OiBzdHJpbmc7XG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFxuICAgICAgICBcIi9hcGkvc2NhZmZvbGRpbmcvcHJldmlld1wiLFxuICAgICAgICAocmVxdWVzdCk6IFByb21pc2U8eyBwYXRoQW5kQ29kZXM6IFBhdGhBbmRDb2RlW10gfT4gPT5cbiAgICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBvcHRpb24gfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgY29uc3QgeyB0ZW1wbGF0ZUtleSwgLi4udGVtcGxhdGVPcHRpb25zIH0gPSBvcHRpb247XG4gICAgICAgICAgICAgIGNvbnN0IHBhdGhBbmRDb2RlcyA9IGF3YWl0IFNvbmFtdS5zeW5jZXIucmVuZGVyVGVtcGxhdGUoXG4gICAgICAgICAgICAgICAgLyogU0FGRVRZOiBVSSDrj4TqtazsnZggWm9kIOyeheugpSDsiqTtgqTrp4jqsIAg7J20IOqwkuydmCDtg4DsnoXsnYQg67O07J6l7ZWc64ukLiAqLyB0ZW1wbGF0ZUtleSBhcyBUZW1wbGF0ZUtleSxcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZU9wdGlvbnMsXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgcmV0dXJuIHsgcGF0aEFuZENvZGVzIH07XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdChcIi9hcGkvZml4dHVyZVwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IHNvdXJjZURCLCB0YXJnZXREQiwgc2VhcmNoLCBkdXBsaWNhdGVDaGVjayB9ID1cbiAgICAgICAgICAgIC8qIFNBRkVUWTogVUkg64+E6rWs7J2YIFpvZCDsnoXroKUg7Iqk7YKk66eI6rCAIOydtCDqsJLsnZgg7YOA7J6F7J2EIOuztOyepe2VnOuLpC4gKi8gcmVxdWVzdC5ib2R5IGFzIHtcbiAgICAgICAgICAgICAgc291cmNlREI6IGtleW9mIFNvbmFtdURCQ29uZmlnO1xuICAgICAgICAgICAgICB0YXJnZXREQjoga2V5b2YgU29uYW11REJDb25maWc7XG4gICAgICAgICAgICAgIHNlYXJjaDogRml4dHVyZVNlYXJjaE9wdGlvbnM7XG4gICAgICAgICAgICAgIGR1cGxpY2F0ZUNoZWNrPzogRHVwbGljYXRlQ2hlY2tPcHRpb25zO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgIHJldHVybiBGaXh0dXJlTWFuYWdlci5nZXRGaXh0dXJlcyhzb3VyY2VEQiwgdGFyZ2V0REIsIHNlYXJjaCwgZHVwbGljYXRlQ2hlY2spO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0KFwiL2FwaS9maXh0dXJlL2ltcG9ydFwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGRiLCBmaXh0dXJlcyB9ID1cbiAgICAgICAgICAgIC8qIFNBRkVUWTogVUkg64+E6rWs7J2YIFpvZCDsnoXroKUg7Iqk7YKk66eI6rCAIOydtCDqsJLsnZgg7YOA7J6F7J2EIOuztOyepe2VnOuLpC4gKi8gcmVxdWVzdC5ib2R5IGFzIHtcbiAgICAgICAgICAgICAgZGI6IGtleW9mIFNvbmFtdURCQ29uZmlnO1xuICAgICAgICAgICAgICBmaXh0dXJlczogRml4dHVyZVJlY29yZFtdO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgIHJldHVybiBGaXh0dXJlTWFuYWdlci5pbnNlcnRGaXh0dXJlcyhkYiwgZml4dHVyZXMpO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0KFwiL2FwaS9maXh0dXJlL2FkZEZpeHR1cmVMb2FkZXJcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBjb2RlIH0gPVxuICAgICAgICAgICAgLyogU0FGRVRZOiBVSSDrj4TqtazsnZggWm9kIOyeheugpSDsiqTtgqTrp4jqsIAg7J20IOqwkuydmCDtg4DsnoXsnYQg67O07J6l7ZWc64ukLiAqLyByZXF1ZXN0LmJvZHkgYXMge1xuICAgICAgICAgICAgICBjb2RlOiBzdHJpbmc7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgcmV0dXJuIEZpeHR1cmVNYW5hZ2VyLmFkZEZpeHR1cmVMb2FkZXIoY29kZSk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLmdldChcIi9hcGkvaTE4bi9kaWN0aW9uYXJ5XCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHNvbmFtdURpY3Rpb25hcnkuZ2V0RGljdGlvbmFyeSgpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL2kxOG4vZXhwb3J0XCIsIGFzeW5jIChfcmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgeyBmaWxlbmFtZSwgYnVmZmVyIH0gPSBhd2FpdCBzb25hbXVEaWN0aW9uYXJ5LmV4cG9ydFRvRXhjZWwoKTtcbiAgICAgICAgcmVwbHlcbiAgICAgICAgICAuaGVhZGVyKFxuICAgICAgICAgICAgXCJDb250ZW50LVR5cGVcIixcbiAgICAgICAgICAgIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwuc2hlZXRcIixcbiAgICAgICAgICApXG4gICAgICAgICAgLmhlYWRlcihcIkNvbnRlbnQtRGlzcG9zaXRpb25cIiwgYGF0dGFjaG1lbnQ7IGZpbGVuYW1lPVwiJHtmaWxlbmFtZX1cImApXG4gICAgICAgICAgLnNlbmQoYnVmZmVyKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdChcIi9hcGkvaTE4bi9pbXBvcnRcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlcXVlc3QuZmlsZSgpO1xuICAgICAgICAgIGlmICghZGF0YSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oU0QoXCJzb25hbXUuZXJyb3IuZmlsZU5vdFVwbG9hZGVkXCIpKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgYnVmZmVyID0gYXdhaXQgZGF0YS50b0J1ZmZlcigpO1xuICAgICAgICAgIHJldHVybiBzb25hbXVEaWN0aW9uYXJ5LmltcG9ydEZyb21FeGNlbChidWZmZXIpO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIG9sZEtleTogc3RyaW5nO1xuICAgICAgICAgIG5ld0tleTogc3RyaW5nO1xuICAgICAgICAgIHNvdXJjZTogXCJlbnRpdHlcIiB8IFwicHJvamVjdFwiIHwgXCJzb25hbXVcIjtcbiAgICAgICAgICB2YWx1ZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvaTE4bi91cGRhdGVcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgc29uYW11RGljdGlvbmFyeS51cGRhdGVFbnRyeShyZXF1ZXN0LmJvZHkpO1xuICAgICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUgfTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBrZXk6IHN0cmluZztcbiAgICAgICAgICB2YWx1ZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvaTE4bi9jcmVhdGVcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgc29uYW11RGljdGlvbmFyeS5jcmVhdGVFbnRyeShyZXF1ZXN0LmJvZHkpO1xuICAgICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUgfTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBrZXk6IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9pMThuL2RlbGV0ZVwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBhd2FpdCBzb25hbXVEaWN0aW9uYXJ5LmRlbGV0ZUVudHJ5KHJlcXVlc3QuYm9keS5rZXkpO1xuICAgICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUgfTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7IEJvZHk6IHsga2V5czogc3RyaW5nW10gfSB9PihcIi9hcGkvaTE4bi9jaGVja1VzYWdlXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHJldHVybiBzb25hbXVEaWN0aW9uYXJ5LmNoZWNrVXNhZ2UocmVxdWVzdC5ib2R5LmtleXMpO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIC8vIFRhc2tzIEFQSVxuICAgICAgc2VydmVyLmdldChcIi9hcGkvdGFza3Mvc3RhdHVzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBTb25hbXUud29ya2Zsb3dzO1xuICAgICAgICAgIHJldHVybiB7IGFjdGl2ZTogdHJ1ZSB9O1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICByZXR1cm4geyBhY3RpdmU6IGZhbHNlIH07XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIuZ2V0KFwiL2FwaS90YXNrcy93b3JrZmxvd0RlZmluaXRpb25zXCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgZGVmaW5pdGlvbnMgPSBTb25hbXUud29ya2Zsb3dzLndvcmtmbG93RGVmaW5pdGlvbnM7XG4gICAgICAgIHJldHVybiB7IGRlZmluaXRpb25zIH07XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldDx7XG4gICAgICAgIFF1ZXJ5c3RyaW5nOiB7XG4gICAgICAgICAgbGltaXQ/OiBzdHJpbmc7XG4gICAgICAgICAgYWZ0ZXI/OiBzdHJpbmc7XG4gICAgICAgICAgYmVmb3JlPzogc3RyaW5nO1xuICAgICAgICAgIG9yZGVyPzogXCJhc2NcIiB8IFwiZGVzY1wiO1xuICAgICAgICAgIHN0YXR1cz86IHN0cmluZztcbiAgICAgICAgICB3b3JrZmxvd05hbWU/OiBzdHJpbmc7XG4gICAgICAgICAgY3JlYXRlZEFmdGVyPzogc3RyaW5nO1xuICAgICAgICAgIGNyZWF0ZWRCZWZvcmU/OiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvdGFza3Mvd29ya2Zsb3dSdW5zXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGJhY2tlbmQgPSBTb25hbXUud29ya2Zsb3dzLmJhY2tlbmQ7XG4gICAgICAgICAgY29uc3QgeyBsaW1pdCwgYWZ0ZXIsIGJlZm9yZSwgb3JkZXIsIHN0YXR1cywgd29ya2Zsb3dOYW1lLCBjcmVhdGVkQWZ0ZXIsIGNyZWF0ZWRCZWZvcmUgfSA9XG4gICAgICAgICAgICByZXF1ZXN0LnF1ZXJ5O1xuICAgICAgICAgIHJldHVybiBiYWNrZW5kLmxpc3RXb3JrZmxvd1J1bnMoe1xuICAgICAgICAgICAgbGltaXQ6IGxpbWl0ID8gTnVtYmVyLnBhcnNlSW50KGxpbWl0LCAxMCkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBhZnRlcixcbiAgICAgICAgICAgIGJlZm9yZSxcbiAgICAgICAgICAgIG9yZGVyLFxuICAgICAgICAgICAgc3RhdHVzOiBzdGF0dXMgPyBzdGF0dXMuc3BsaXQoXCIsXCIpIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgd29ya2Zsb3dOYW1lOiB3b3JrZmxvd05hbWUgfHwgdW5kZWZpbmVkLFxuICAgICAgICAgICAgY3JlYXRlZEFmdGVyOiBjcmVhdGVkQWZ0ZXIgPyBuZXcgRGF0ZShjcmVhdGVkQWZ0ZXIpIDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgY3JlYXRlZEJlZm9yZTogY3JlYXRlZEJlZm9yZSA/IG5ldyBEYXRlKGNyZWF0ZWRCZWZvcmUpIDogdW5kZWZpbmVkLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5nZXQ8e1xuICAgICAgICBQYXJhbXM6IHsgaWQ6IHN0cmluZyB9O1xuICAgICAgfT4oXCIvYXBpL3Rhc2tzL3dvcmtmbG93UnVucy86aWRcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgYmFja2VuZCA9IFNvbmFtdS53b3JrZmxvd3MuYmFja2VuZDtcbiAgICAgICAgICBjb25zdCB3b3JrZmxvd1J1biA9IGF3YWl0IGJhY2tlbmQuZ2V0V29ya2Zsb3dSdW4oe1xuICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogcmVxdWVzdC5wYXJhbXMuaWQsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgaWYgKCF3b3JrZmxvd1J1bikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBXb3JrZmxvdyBydW4gbm90IGZvdW5kOiAke3JlcXVlc3QucGFyYW1zLmlkfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gd29ya2Zsb3dSdW47XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBQYXJhbXM6IHsgaWQ6IHN0cmluZyB9O1xuICAgICAgfT4oXCIvYXBpL3Rhc2tzL3dvcmtmbG93UnVucy86aWQvY2FuY2VsXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGJhY2tlbmQgPSBTb25hbXUud29ya2Zsb3dzLmJhY2tlbmQ7XG4gICAgICAgICAgcmV0dXJuIGJhY2tlbmQuY2FuY2VsV29ya2Zsb3dSdW4oe1xuICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogcmVxdWVzdC5wYXJhbXMuaWQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBQYXJhbXM6IHsgaWQ6IHN0cmluZyB9O1xuICAgICAgfT4oXCIvYXBpL3Rhc2tzL3dvcmtmbG93UnVucy86aWQvcGF1c2VcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgYmFja2VuZCA9IFNvbmFtdS53b3JrZmxvd3MuYmFja2VuZDtcbiAgICAgICAgICByZXR1cm4gYmFja2VuZC5wYXVzZVdvcmtmbG93UnVuKHtcbiAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJlcXVlc3QucGFyYW1zLmlkLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgUGFyYW1zOiB7IGlkOiBzdHJpbmcgfTtcbiAgICAgIH0+KFwiL2FwaS90YXNrcy93b3JrZmxvd1J1bnMvOmlkL3Jlc3VtZVwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCBiYWNrZW5kID0gU29uYW11LndvcmtmbG93cy5iYWNrZW5kO1xuICAgICAgICAgIHJldHVybiBiYWNrZW5kLnJlc3VtZVdvcmtmbG93UnVuKHtcbiAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJlcXVlc3QucGFyYW1zLmlkLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHNlcnZlci5nZXQ8e1xuICAgICAgICBQYXJhbXM6IHsgaWQ6IHN0cmluZyB9O1xuICAgICAgICBRdWVyeXN0cmluZzoge1xuICAgICAgICAgIGxpbWl0Pzogc3RyaW5nO1xuICAgICAgICAgIGFmdGVyPzogc3RyaW5nO1xuICAgICAgICAgIGJlZm9yZT86IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS90YXNrcy93b3JrZmxvd1J1bnMvOmlkL3N0ZXBzXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGJhY2tlbmQgPSBTb25hbXUud29ya2Zsb3dzLmJhY2tlbmQ7XG4gICAgICAgICAgY29uc3QgeyBsaW1pdCwgYWZ0ZXIsIGJlZm9yZSB9ID0gcmVxdWVzdC5xdWVyeTtcbiAgICAgICAgICByZXR1cm4gYmFja2VuZC5saXN0U3RlcEF0dGVtcHRzKHtcbiAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJlcXVlc3QucGFyYW1zLmlkLFxuICAgICAgICAgICAgbGltaXQ6IGxpbWl0ID8gTnVtYmVyLnBhcnNlSW50KGxpbWl0LCAxMCkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBhZnRlcixcbiAgICAgICAgICAgIGJlZm9yZSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICAvKipcbiAgICAgICAqIEhlYWx0aCBDaGVjayBBUElcbiAgICAgICAqIE1DUCDrj4TqtazqsIAgU29uYW11IOyEnOuyhOulvCDsnpDrj5kg6rCQ7KeA7ZWY6riwIOychO2VnCDsl5Trk5ztj6zsnbjtirhcbiAgICAgICAqL1xuICAgICAgc2VydmVyLmdldChcIi9hcGkvc29uYW11L2hlYWx0aFwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCBhZGRyZXNzID0gcmVxdWVzdC5zZXJ2ZXIuc2VydmVyLmFkZHJlc3MoKTtcbiAgICAgICAgICBjb25zdCBwb3J0ID0gYWRkcmVzcyAmJiBpc09iamVjdFZhbHVlKGFkZHJlc3MpID8gYWRkcmVzcy5wb3J0IDogMDtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBvazogdHJ1ZSxcbiAgICAgICAgICAgIHByb2plY3Q6IHByb2Nlc3MuY3dkKCkuc3BsaXQoXCIvXCIpLnBvcCgpIHx8IFwidW5rbm93blwiLFxuICAgICAgICAgICAgcG9ydCxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICAgIH07XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgLyoqXG4gICAgICAgKiBGaXh0dXJlIOyDneyEsSBBUElcbiAgICAgICAqL1xuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5OiBzdHJpbmc7XG4gICAgICAgICAgY291bnQ/OiBudW1iZXI7XG4gICAgICAgICAgb3ZlcnJpZGVzPzogRml4dHVyZUdlbmVyYXRpb25TcGVjW1wib3ZlcnJpZGVzXCJdO1xuICAgICAgICAgIHRhcmdldERiPzogXCJmaXh0dXJlXCIgfCBcInRlc3RcIjtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9zb25hbXUvZml4dHVyZS9nZW5lcmF0ZVwiLCBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgeyBlbnRpdHksIGNvdW50ID0gMSwgb3ZlcnJpZGVzLCB0YXJnZXREYiA9IFwiZml4dHVyZVwiIH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgLy8g7YOA6rKfIERCIOyEpOyglSDqsIDsoLjsmKTquLBcbiAgICAgICAgY29uc3QgZGJDb25maWcgPSB0YXJnZXREYiA9PT0gXCJmaXh0dXJlXCIgPyBTb25hbXUuZGJDb25maWcuZml4dHVyZSA6IFNvbmFtdS5kYkNvbmZpZy50ZXN0O1xuXG4gICAgICAgIC8vIEtuZXgg7J247Iqk7YS07IqkIOyDneyEsVxuICAgICAgICBjb25zdCBkYiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShkYkNvbmZpZyk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBGaXh0dXJlR2VuZXJhdG9yIOyDneyEsVxuICAgICAgICAgIGNvbnN0IGdlbmVyYXRvciA9IG5ldyBGaXh0dXJlR2VuZXJhdG9yKGRiLCBkYiwgdGFyZ2V0RGIsIEVudGl0eU1hbmFnZXIpO1xuXG4gICAgICAgICAgLy8g64uo7J28IEVudGl0eSDrsLDsuZgg7IOd7ISxXG4gICAgICAgICAgY29uc3QgZml4dHVyZXMgPSBhd2FpdCBnZW5lcmF0b3IuZ2VuZXJhdGVCYXRjaChbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGVudGl0eSxcbiAgICAgICAgICAgICAgY291bnQsXG4gICAgICAgICAgICAgIG92ZXJyaWRlczogb3ZlcnJpZGVzID8/IHt9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdKTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgZW50aXR5LFxuICAgICAgICAgICAgY291bnQ6IGZpeHR1cmVzLmxlbmd0aCxcbiAgICAgICAgICAgIGZpeHR1cmVzLFxuICAgICAgICAgICAgdGFyZ2V0RGIsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICByZXBseS5zdGF0dXMoNDAwKTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgYXdhaXQgZGIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLyoqXG4gICAgICAgKiBGaXh0dXJlIOuNsOydtO2EsCDtg5Dsg4kgQVBJXG4gICAgICAgKi9cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eTogc3RyaW5nO1xuICAgICAgICAgIHN0cmF0ZWd5OiBcInNhbXBsZVwiIHwgXCJyZWNlbnRcIiB8IFwicmFuZG9tXCIgfCBcInF1ZXJ5XCI7XG4gICAgICAgICAgbGltaXQ/OiBudW1iZXI7XG4gICAgICAgICAgd2hlcmU/OiBEYXRhRXhwbG9yZXJPcHRpb25zW1wid2hlcmVcIl07XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvc29uYW11L2ZpeHR1cmUvZXhwbG9yZVwiLCBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgeyBlbnRpdHksIHN0cmF0ZWd5LCBsaW1pdCA9IDEwLCB3aGVyZSB9ID0gcmVxdWVzdC5ib2R5O1xuXG4gICAgICAgIC8vIEZpeHR1cmUgREIg7ISk7KCVIOqwgOyguOyYpOq4sFxuICAgICAgICBjb25zdCBmaXh0dXJlRGJDb25maWcgPSBTb25hbXUuZGJDb25maWcuZml4dHVyZTtcblxuICAgICAgICAvLyBLbmV4IOyduOyKpO2EtOyKpCDsg53shLFcbiAgICAgICAgY29uc3QgZml4dHVyZURiID0gY3JlYXRlS25leEluc3RhbmNlKGZpeHR1cmVEYkNvbmZpZyk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBEYXRhRXhwbG9yZXIg7IOd7ISxXG4gICAgICAgICAgY29uc3QgZXhwbG9yZXIgPSBuZXcgRGF0YUV4cGxvcmVyKGZpeHR1cmVEYiwgRW50aXR5TWFuYWdlcik7XG5cbiAgICAgICAgICBjb25zdCBkYXRhID0gYXdhaXQgZXhwbG9yZXIuZXhwbG9yZShlbnRpdHksIHtcbiAgICAgICAgICAgIHN0cmF0ZWd5LFxuICAgICAgICAgICAgbGltaXQsXG4gICAgICAgICAgICB3aGVyZSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgZW50aXR5LFxuICAgICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgICBjb3VudDogZGF0YS5sZW5ndGgsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgcmVwbHkuc3RhdHVzKDQwMCk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGF3YWl0IGZpeHR1cmVEYi5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvKipcbiAgICAgICAqIEZpeHR1cmUg642w7J207YSwIOqwgOyguOyYpOq4sCAoZmV0Y2gpIEFQSVxuICAgICAgICogcHJvZHVjdGlvbi9kZXZlbG9wbWVudCBEQuyXkOyEnCDsi6TsoJwg642w7J207YSw66W8IGZpeHR1cmUgRELroZwgaW1wb3J0XG4gICAgICAgKi9cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eTogc3RyaW5nO1xuICAgICAgICAgIHN0cmF0ZWd5PzogXCJzYW1wbGVcIiB8IFwicmVjZW50XCIgfCBcInJhbmRvbVwiIHwgXCJxdWVyeVwiO1xuICAgICAgICAgIGxpbWl0PzogbnVtYmVyO1xuICAgICAgICAgIGluY2x1ZGVSZWxhdGlvbnM/OiBib29sZWFuO1xuICAgICAgICAgIG1heERlcHRoPzogbnVtYmVyO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL3NvbmFtdS9maXh0dXJlL2ZldGNoXCIsIGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgZW50aXR5LFxuICAgICAgICAgIHN0cmF0ZWd5ID0gXCJyZWNlbnRcIixcbiAgICAgICAgICBsaW1pdCA9IDEwLFxuICAgICAgICAgIGluY2x1ZGVSZWxhdGlvbnMgPSB0cnVlLFxuICAgICAgICAgIG1heERlcHRoID0gMixcbiAgICAgICAgfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAvLyBTb3VyY2UgREIgKHByb2R1Y3Rpb24vZGV2ZWxvcG1lbnQpIC0g7J296riwIOyghOyaqVxuICAgICAgICBjb25zdCBzb3VyY2VEYiA9IERCLmdldERCKFwiclwiKTtcblxuICAgICAgICAvLyBUYXJnZXQgREIgKGZpeHR1cmUpXG4gICAgICAgIGNvbnN0IGZpeHR1cmVEYiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShTb25hbXUuZGJDb25maWcuZml4dHVyZSk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBGaXh0dXJlR2VuZXJhdG9yIOyDneyEsVxuICAgICAgICAgIGNvbnN0IGdlbmVyYXRvciA9IG5ldyBGaXh0dXJlR2VuZXJhdG9yKHNvdXJjZURiLCBmaXh0dXJlRGIsIFwiZml4dHVyZVwiLCBFbnRpdHlNYW5hZ2VyKTtcblxuICAgICAgICAgIC8vIHByb2R1Y3Rpb24g642w7J207YSw66W8IGZpeHR1cmUgRELroZwgaW1wb3J0XG4gICAgICAgICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IGdlbmVyYXRvci5pbXBvcnRGcm9tU291cmNlKGVudGl0eSwge1xuICAgICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgICBsaW1pdCxcbiAgICAgICAgICAgIGluY2x1ZGVSZWxhdGlvbnMsXG4gICAgICAgICAgICBtYXhEZXB0aCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgZW50aXR5LFxuICAgICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgICBjb3VudDogcmVzdWx0cy5sZW5ndGgsXG4gICAgICAgICAgICBpbXBvcnRlZDogcmVzdWx0cyxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHJlcGx5LnN0YXR1cyg0MDApO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvciksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAvLyBzb3VyY2VEYuuKlCBTb25hbXXqsIAg6rSA66as7ZWY66+A66GcIGRlc3Ryb3ntlZjsp4Ag7JWK7J2MXG4gICAgICAgICAgYXdhaXQgZml4dHVyZURiLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8qKlxuICAgICAgICogRml4dHVyZSDrjbDsnbTthLAg7IKt7KCcIChjbGVhbikgQVBJXG4gICAgICAgKiBGSyDsiJzshJzrpbwg6rOg66Ck7ZWY7JesIOyViOyghO2VmOqyjCDsgq3soJxcbiAgICAgICAqL1xuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXRpZXM/OiBzdHJpbmdbXTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9zb25hbXUvZml4dHVyZS9jbGVhblwiLCBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgeyBlbnRpdGllcyB9ID0gcmVxdWVzdC5ib2R5O1xuXG4gICAgICAgIC8vIEZpeHR1cmUgREIg7Jew6rKwXG4gICAgICAgIGNvbnN0IGZpeHR1cmVEYiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShTb25hbXUuZGJDb25maWcuZml4dHVyZSk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyDsgq3soJztlaAgRW50aXR5IOuqqeuhnSDqsrDsoJVcbiAgICAgICAgICBjb25zdCB0YXJnZXRFbnRpdGllcyA9XG4gICAgICAgICAgICBlbnRpdGllcyAmJiBlbnRpdGllcy5sZW5ndGggPiAwID8gZW50aXRpZXMgOiBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpO1xuXG4gICAgICAgICAgLy8gRW50aXR5IElE66W8IO2FjOydtOu4lOuqheycvOuhnCDrs4DtmZggKHNuYWtlX2Nhc2Ug67O17IiY7ZiVKVxuICAgICAgICAgIGNvbnN0IHRhYmxlTmFtZXMgPSB0YXJnZXRFbnRpdGllcy5tYXAoKGVudGl0eUlkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgICByZXR1cm4gZW50aXR5LnRhYmxlO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgLy8gUG9zdGdyZVNRTDogVFJVTkNBVEUgQ0FTQ0FEReuhnCBGSyDsiJzshJwg66y06rSA7ZWY6rKMIOyViOyghO2VmOqyjCDsgq3soJxcbiAgICAgICAgICAvLyBDQVNDQURFIOyYteyFmOycvOuhnCDsnZjsobTshLEg7J6I64qUIOuNsOydtO2EsOuPhCDtlajqu5gg7IKt7KCcXG4gICAgICAgICAgYXdhaXQgZml4dHVyZURiLnJhdyhcbiAgICAgICAgICAgIGBUUlVOQ0FURSBUQUJMRSAke3RhYmxlTmFtZXMubWFwKCh0KSA9PiBgXCIke3R9XCJgKS5qb2luKFwiLCBcIil9IFJFU1RBUlQgSURFTlRJVFkgQ0FTQ0FERWAsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgY2xlYW5lZDogdGFibGVOYW1lcyxcbiAgICAgICAgICAgIGNvdW50OiB0YWJsZU5hbWVzLmxlbmd0aCxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHJlcGx5LnN0YXR1cyg0MDApO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvciksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBhd2FpdCBmaXh0dXJlRGIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLy8gQ0REIEFQSVxuICAgICAgc2VydmVyLmdldChcIi9hcGkvY2RkL3RyZWVcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgICByZXR1cm4gZ2V0Q2RkVHJlZSgpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHsgQm9keTogeyBmaWxlUGF0aDogc3RyaW5nIH0gfT4oXCIvYXBpL2NkZC9yZWFkQ29udGVudFwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGZpbGVQYXRoIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgcmV0dXJuIHJlYWRDb250ZW50KGZpbGVQYXRoKTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7IEJvZHk6IHsgZmlsZVBhdGg6IHN0cmluZyB9IH0+KFwiL2FwaS9jZGQvZWRpdENvbnRlbnRcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBmaWxlUGF0aCB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICAgIHJldHVybiBlZGl0Q29udGVudChmaWxlUGF0aCk7XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLnBvc3Q8eyBCb2R5OiB7IGZpbGVQYXRoOiBzdHJpbmcgfSB9PihcIi9hcGkvY2RkL29wZW5Tb3VyY2VcIiwgKHJlcXVlc3QpID0+XG4gICAgICAgIGZvcndhcmRBc3luY0Vycm9ycyhhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBmaWxlUGF0aCB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICAgIG9wZW5Tb3VyY2VGaWxlKGZpbGVQYXRoKTtcbiAgICAgICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlIH07XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgICAgLy8gQ0REIFJ1bGVzIEFQSVxuICAgICAgc2VydmVyLmdldChcIi9hcGkvY2RkL3J1bGVzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgcmV0dXJuIGxpc3RSdWxlcygpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHsgQm9keTogeyBydWxlS2V5OiBzdHJpbmcgfSB9PihcIi9hcGkvY2RkL3JlYWRSdWxlXCIsIChyZXF1ZXN0KSA9PlxuICAgICAgICBmb3J3YXJkQXN5bmNFcnJvcnMoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgcnVsZUtleSB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICAgIHJldHVybiByZWFkUnVsZShydWxlS2V5KTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7IEJvZHk6IENkZEFkZFJ1bGVSZXF1ZXN0IH0+KFwiL2FwaS9jZGQvYWRkUnVsZVwiLCAocmVxdWVzdCkgPT5cbiAgICAgICAgZm9yd2FyZEFzeW5jRXJyb3JzKGFzeW5jICgpID0+IHtcbiAgICAgICAgICByZXR1cm4gYWRkUnVsZShyZXF1ZXN0LmJvZHkpO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIC8vIENERCBBQyBBUElcbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL2NkZC9hY1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHJldHVybiBnZXRBY0xpc3QoKTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyB1aS13ZWIg67mM65OcIO2MjOydvCDshJzruZlcbiAgICAgIGNvbnN0IHVpRGlzdFBhdGggPSBwYXRoLnJlc29sdmUoaW1wb3J0Lm1ldGEuZGlybmFtZSwgXCIuLi91aS13ZWJcIik7XG5cbiAgICAgIC8vIOygleyggSDtjIzsnbwg7ISc67mZOiDro6jtirgg7Y+0642UIOyghOyytCAoYXNzZXRzLCBzZXR0aW5nLnN2ZyDrk7EpXG4gICAgICBzZXJ2ZXIucmVnaXN0ZXIoYXdhaXQgaW1wb3J0KFwiQGZhc3RpZnkvc3RhdGljXCIpLCB7XG4gICAgICAgIHJvb3Q6IHVpRGlzdFBhdGgsXG4gICAgICAgIHByZWZpeDogXCIvXCIsXG4gICAgICAgIGRlY29yYXRlUmVwbHk6IGZhbHNlLFxuICAgICAgICB3aWxkY2FyZDogZmFsc2UsXG4gICAgICB9KTtcblxuICAgICAgLy8gU1BBIGZhbGxiYWNrIC0g7KCV7KCBIO2MjOydvOydtCDsl4bripQg66qo65OgIOqyveuhnOuKlCBpbmRleC5odG1s66GcXG4gICAgICBzZXJ2ZXIuZ2V0KFwiKlwiLCBhc3luYyAoX3JlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIHJlcGx5LmhlYWRlcnMoeyBcIkNvbnRlbnQtdHlwZVwiOiBcInRleHQvaHRtbFwiIH0pLnNlbmQoXG4gICAgICAgICAgZnNcbiAgICAgICAgICAgIC5yZWFkRmlsZVN5bmMocGF0aC5yZXNvbHZlKHVpRGlzdFBhdGgsIFwiaW5kZXguaHRtbFwiKSlcbiAgICAgICAgICAgIC50b1N0cmluZygpXG4gICAgICAgICAgICAucmVwbGFjZShcInt7cHJvamVjdE5hbWV9fVwiLCBTb25hbXUuY29uZmlnLnByb2plY3ROYW1lID8/IFwiVW5rbm93blNvbmFtdVByb2plY3RcIiksXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9LFxuICAgIHsgcHJlZml4OiBcIi9zb25hbXUtdWlcIiB9LFxuICApO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBMkRBLGVBQWUsb0JBQXVCLElBQWtDO0NBQ3RFLE1BQU0sY0FBYyxJQUFJLFNBQWUsWUFBWTtFQUNqRCxNQUFNLGdCQUFnQjtHQUNwQixhQUFhLE9BQU87R0FDcEIsUUFBUTtFQUNWO0VBRUEsTUFBTSxVQUFVLGlCQUFpQjtHQUMvQixPQUFPLE9BQU8sYUFBYSxJQUFJLGtCQUFrQixPQUFPO0dBQ3hELFFBQVE7RUFDVixHQUFHLElBQUk7RUFFUCxPQUFPLE9BQU8sYUFBYSxLQUFLLGtCQUFrQixPQUFPO0NBQzNELENBQUM7Q0FFRCxNQUFNLFNBQVMsTUFBTSxHQUFHO0NBQ3hCLE1BQU07Q0FDTixPQUFPO0FBQ1Q7QUFFQSxTQUFTLGtCQUFrQixZQUFtRDtDQUM1RSxPQUFPLFdBQVcsU0FBUyxjQUFjO0VBQ3ZDLE1BQU0sRUFBRSxVQUFVLEdBQUcsU0FBUztFQUM5QixPQUFPLENBQUMsTUFBTSxHQUFHLGtCQUFrQixRQUFRLENBQUM7Q0FDOUMsQ0FBQztBQUNIO0FBRUEsZUFBc0Isa0JBQWtCLFNBQTBCO0NBQ2hFLFFBQVEsU0FDTixPQUFPLFdBQVc7RUFDaEIsTUFBTSxTQUFTLE1BQU07RUFDckIsTUFBTSxzQkFBc0IsTUFBTTtFQUVsQyxPQUFPLElBQUksc0JBQXNCLFlBQVk7R0FDM0MsT0FBTyxPQUFPO0VBQ2hCLENBQUM7RUFFRCxPQUFPLElBTUosMEJBQTBCLFlBQzNCLG1CQUFtQixZQUFZO0dBQzdCLE1BQU0sRUFBRSxVQUFVLFFBQVEsWUFBWSxRQUFRO0dBMkI5QyxTQUFTLGVBekJpQjtJQUN4QixJQUFJLFlBQVksUUFBUTtLQUN0QixNQUFNLFNBQVMsY0FBYyxJQUFJLFFB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