sonamu 0.9.19 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +36 -0
  2. package/dist/ai/agents/agent.js +5 -7
  3. package/dist/ai/agents/index.js +1 -2
  4. package/dist/ai/agents/types.js +1 -1
  5. package/dist/ai/index.js +1 -2
  6. package/dist/ai/providers/rtzr/api.js +2 -3
  7. package/dist/ai/providers/rtzr/error.js +14 -29
  8. package/dist/ai/providers/rtzr/index.js +1 -2
  9. package/dist/ai/providers/rtzr/model.js +13 -20
  10. package/dist/ai/providers/rtzr/options.js +2 -3
  11. package/dist/ai/providers/rtzr/provider.js +2 -3
  12. package/dist/ai/providers/rtzr/utils.js +12 -21
  13. package/dist/api/base-frame.js +4 -4
  14. package/dist/api/caster.js +21 -38
  15. package/dist/api/code-converters.js +41 -98
  16. package/dist/api/config.d.ts +1 -10
  17. package/dist/api/config.d.ts.map +1 -1
  18. package/dist/api/config.js +9 -8
  19. package/dist/api/context.js +2 -3
  20. package/dist/api/decorators.js +80 -116
  21. package/dist/api/index.js +2 -3
  22. package/dist/api/secret.js +6 -10
  23. package/dist/api/sonamu.d.ts.map +1 -1
  24. package/dist/api/sonamu.js +200 -387
  25. package/dist/api/validator.js +5 -8
  26. package/dist/api/websocket-helpers.js +21 -32
  27. package/dist/auth/audit-log/builders.js +2 -3
  28. package/dist/auth/audit-log/events.js +2 -2
  29. package/dist/auth/audit-log/plugin.js +30 -61
  30. package/dist/auth/audit-log-ingestor.js +19 -41
  31. package/dist/auth/auth-generator.js +16 -41
  32. package/dist/auth/better-auth-entities.js +3 -4
  33. package/dist/auth/index.js +2 -3
  34. package/dist/auth/knex-adapter.js +18 -45
  35. package/dist/auth/plugins/entity-definitions/admin.js +2 -2
  36. package/dist/auth/plugins/entity-definitions/anonymous.js +2 -2
  37. package/dist/auth/plugins/entity-definitions/api-key.js +2 -2
  38. package/dist/auth/plugins/entity-definitions/audit-log.js +2 -2
  39. package/dist/auth/plugins/entity-definitions/index.js +2 -3
  40. package/dist/auth/plugins/entity-definitions/jwt.js +2 -2
  41. package/dist/auth/plugins/entity-definitions/organization.js +2 -2
  42. package/dist/auth/plugins/entity-definitions/passkey.js +2 -2
  43. package/dist/auth/plugins/entity-definitions/phone-number.js +2 -2
  44. package/dist/auth/plugins/entity-definitions/sso.js +2 -2
  45. package/dist/auth/plugins/entity-definitions/two-factor.js +2 -2
  46. package/dist/auth/plugins/entity-definitions/types.js +1 -1
  47. package/dist/auth/plugins/entity-definitions/username.js +2 -2
  48. package/dist/auth/plugins/index.js +1 -2
  49. package/dist/auth/plugins/wrappers/admin.js +2 -3
  50. package/dist/auth/plugins/wrappers/anonymous.js +2 -3
  51. package/dist/auth/plugins/wrappers/api-key.js +2 -3
  52. package/dist/auth/plugins/wrappers/index.js +1 -2
  53. package/dist/auth/plugins/wrappers/jwt.js +2 -3
  54. package/dist/auth/plugins/wrappers/organization.js +2 -3
  55. package/dist/auth/plugins/wrappers/passkey.js +2 -3
  56. package/dist/auth/plugins/wrappers/phone-number.js +2 -3
  57. package/dist/auth/plugins/wrappers/sso.js +2 -3
  58. package/dist/auth/plugins/wrappers/two-factor.js +2 -3
  59. package/dist/auth/plugins/wrappers/username.js +2 -3
  60. package/dist/bin/build-config.js +2 -2
  61. package/dist/bin/cli.js +151 -258
  62. package/dist/bin/fixture.d.ts.map +1 -1
  63. package/dist/bin/fixture.js +55 -97
  64. package/dist/bin/hmr-hook-register.js +3 -3
  65. package/dist/bin/migrate-targets.d.ts +3 -0
  66. package/dist/bin/migrate-targets.d.ts.map +1 -0
  67. package/dist/bin/migrate-targets.js +11 -0
  68. package/dist/bin/test-command.js +25 -55
  69. package/dist/bin/ts-loader-register.js +5 -6
  70. package/dist/bin/ts-loader-registration.js +6 -13
  71. package/dist/cache/cache-manager.js +3 -4
  72. package/dist/cache/decorator.js +11 -21
  73. package/dist/cache/drivers.js +2 -3
  74. package/dist/cache/index.js +2 -3
  75. package/dist/cache/types.js +1 -1
  76. package/dist/cache-control/cache-control.js +21 -34
  77. package/dist/cache-control/types.js +1 -1
  78. package/dist/compress/compress.js +10 -10
  79. package/dist/compress/index.js +1 -2
  80. package/dist/compress/types.js +1 -1
  81. package/dist/cone/cone-generator.js +25 -63
  82. package/dist/database/_batch_update.js +26 -46
  83. package/dist/database/base-model.js +44 -97
  84. package/dist/database/base-model.types.js +1 -1
  85. package/dist/database/db.d.ts +8 -14
  86. package/dist/database/db.d.ts.map +1 -1
  87. package/dist/database/db.js +127 -72
  88. package/dist/database/knex.js +5 -8
  89. package/dist/database/puri-subset.types.js +1 -1
  90. package/dist/database/puri-wrapper.js +11 -15
  91. package/dist/database/puri.js +117 -234
  92. package/dist/database/puri.types.js +3 -4
  93. package/dist/database/transaction-context.js +4 -5
  94. package/dist/database/upsert-builder.js +109 -176
  95. package/dist/dict/en.d.ts +1 -0
  96. package/dist/dict/en.d.ts.map +1 -1
  97. package/dist/dict/en.js +4 -4
  98. package/dist/dict/index.js +2 -3
  99. package/dist/dict/ko.d.ts +1 -0
  100. package/dist/dict/ko.d.ts.map +1 -1
  101. package/dist/dict/ko.js +4 -4
  102. package/dist/dict/rc-keys.js +3 -4
  103. package/dist/dict/sd.js +8 -19
  104. package/dist/dict/sonamu-dictionary.js +141 -284
  105. package/dist/dict/types.js +1 -1
  106. package/dist/dict/utils.js +4 -5
  107. package/dist/entity/entity-manager.d.ts +2 -2
  108. package/dist/entity/entity-manager.js +34 -82
  109. package/dist/entity/entity-template-cone.js +33 -66
  110. package/dist/entity/entity.js +156 -310
  111. package/dist/env.d.ts +14 -0
  112. package/dist/env.d.ts.map +1 -0
  113. package/dist/env.js +75 -0
  114. package/dist/exceptions/error-handler.js +2 -3
  115. package/dist/exceptions/so-exceptions.js +7 -5
  116. package/dist/filter/index.js +1 -2
  117. package/dist/filter/types.js +3 -4
  118. package/dist/filter/utils.js +21 -54
  119. package/dist/index.js +8 -7
  120. package/dist/logger/category.js +6 -12
  121. package/dist/logger/configure.js +23 -34
  122. package/dist/migration/code-generation.js +146 -314
  123. package/dist/migration/index-where-predicate.js +52 -144
  124. package/dist/migration/migration-set.js +19 -33
  125. package/dist/migration/migrator.d.ts +2 -0
  126. package/dist/migration/migrator.d.ts.map +1 -1
  127. package/dist/migration/migrator.js +69 -53
  128. package/dist/migration/postgresql-schema-reader.js +126 -225
  129. package/dist/migration/slack-confirm.d.ts +1 -0
  130. package/dist/migration/slack-confirm.d.ts.map +1 -1
  131. package/dist/migration/slack-confirm.js +28 -38
  132. package/dist/migration/types.js +1 -1
  133. package/dist/naite/messaging-types.js +1 -1
  134. package/dist/naite/naite-reporter.js +15 -32
  135. package/dist/naite/naite.js +43 -76
  136. package/dist/ssr/index.js +6 -9
  137. package/dist/ssr/registry.js +10 -18
  138. package/dist/ssr/renderer.js +10 -21
  139. package/dist/ssr/types.js +1 -1
  140. package/dist/storage/base-file.js +5 -10
  141. package/dist/storage/buffered-file.js +3 -4
  142. package/dist/storage/drivers.js +2 -3
  143. package/dist/storage/index.js +2 -3
  144. package/dist/storage/s3-driver.js +5 -9
  145. package/dist/storage/storage-manager.js +5 -5
  146. package/dist/storage/types.js +1 -1
  147. package/dist/storage/uploaded-file.js +4 -6
  148. package/dist/stream/index.js +1 -2
  149. package/dist/stream/sse.js +8 -13
  150. package/dist/stream/ws-audience-resolver.js +5 -5
  151. package/dist/stream/ws-audience.js +3 -4
  152. package/dist/stream/ws-cluster-bus.js +3 -4
  153. package/dist/stream/ws-core.js +1 -1
  154. package/dist/stream/ws-delivery.js +11 -25
  155. package/dist/stream/ws-local-connection-store.js +9 -18
  156. package/dist/stream/ws-presence-store.js +43 -97
  157. package/dist/stream/ws-registry.js +17 -22
  158. package/dist/stream/ws-telemetry-memory.js +38 -45
  159. package/dist/stream/ws-telemetry-trace.js +4 -6
  160. package/dist/stream/ws-telemetry.js +82 -135
  161. package/dist/stream/ws.js +47 -91
  162. package/dist/syncer/api-parser.js +81 -147
  163. package/dist/syncer/checksum.js +9 -20
  164. package/dist/syncer/code-generator.js +29 -47
  165. package/dist/syncer/entity-operations.js +17 -27
  166. package/dist/syncer/event-batcher.js +8 -15
  167. package/dist/syncer/file-patterns.js +3 -4
  168. package/dist/syncer/file-tracking.js +6 -10
  169. package/dist/syncer/index.js +1 -2
  170. package/dist/syncer/module-loader.js +10 -26
  171. package/dist/syncer/syncer-actions.js +19 -37
  172. package/dist/syncer/syncer.js +46 -98
  173. package/dist/syncer/watcher.js +12 -26
  174. package/dist/tasks/decorator.js +7 -11
  175. package/dist/tasks/step-wrapper.js +7 -8
  176. package/dist/tasks/workflow-manager.js +18 -25
  177. package/dist/template/entity-converter.js +40 -64
  178. package/dist/template/helpers.js +32 -63
  179. package/dist/template/implementations/entity.template.js +7 -11
  180. package/dist/template/implementations/entry-server.template.js +2 -3
  181. package/dist/template/implementations/generated.template.js +25 -51
  182. package/dist/template/implementations/generated_http.template.js +31 -58
  183. package/dist/template/implementations/generated_sso.template.js +45 -85
  184. package/dist/template/implementations/init_types.template.js +4 -7
  185. package/dist/template/implementations/model.template.js +5 -10
  186. package/dist/template/implementations/model_test.template.js +2 -3
  187. package/dist/template/implementations/queries.template.js +4 -7
  188. package/dist/template/implementations/sd.template.js +17 -35
  189. package/dist/template/implementations/services.template.js +18 -30
  190. package/dist/template/implementations/view_form.template.js +72 -125
  191. package/dist/template/implementations/view_id_all_select.template.js +2 -3
  192. package/dist/template/implementations/view_list.template.js +86 -143
  193. package/dist/template/implementations/view_search_input.template.js +2 -3
  194. package/dist/template/index.js +5 -8
  195. package/dist/template/template-manager.js +13 -26
  196. package/dist/template/template-types.js +2 -3
  197. package/dist/template/template.js +7 -11
  198. package/dist/template/zod-converter.js +173 -348
  199. package/dist/testing/_relation-graph.js +18 -37
  200. package/dist/testing/bootstrap.js +5 -8
  201. package/dist/testing/data-explorer.js +34 -78
  202. package/dist/testing/dev-test-routes.js +54 -60
  203. package/dist/testing/dev-vitest-manager.js +33 -84
  204. package/dist/testing/faker-mappings.js +3 -4
  205. package/dist/testing/fixture-generator.d.ts +2 -1
  206. package/dist/testing/fixture-generator.d.ts.map +1 -1
  207. package/dist/testing/fixture-generator.js +159 -321
  208. package/dist/testing/fixture-loader.js +2 -2
  209. package/dist/testing/fixture-manager.d.ts.map +1 -1
  210. package/dist/testing/fixture-manager.js +124 -227
  211. package/dist/testing/global-setup.d.ts.map +1 -1
  212. package/dist/testing/global-setup.js +29 -17
  213. package/dist/testing/index.js +1 -2
  214. package/dist/testing/naite-vitest-reporter.js +2 -3
  215. package/dist/testing/parallel-db-manager.js +5 -3
  216. package/dist/testing/vitest-helpers.d.ts.map +1 -1
  217. package/dist/testing/vitest-helpers.js +15 -12
  218. package/dist/types/types.d.ts +14 -14
  219. package/dist/types/types.js +27 -50
  220. package/dist/ui/ai-api.js +6 -11
  221. package/dist/ui/ai-client.js +86 -134
  222. package/dist/ui/api.js +99 -195
  223. package/dist/ui/cdd-service.js +78 -130
  224. package/dist/ui/cdd-types.js +1 -1
  225. package/dist/ui-web/assets/{index-Df8q-fhb.js → index-DFStGyd0.js} +49 -49
  226. package/dist/ui-web/assets/index-Dx4ap5i4.css +1 -0
  227. package/dist/ui-web/index.html +2 -2
  228. package/dist/utils/async-utils.js +13 -25
  229. package/dist/utils/class-name.js +3 -4
  230. package/dist/utils/console-util.js +11 -26
  231. package/dist/utils/controller.d.ts.map +1 -1
  232. package/dist/utils/controller.js +14 -12
  233. package/dist/utils/esm-utils.js +5 -8
  234. package/dist/utils/formatter.js +10 -22
  235. package/dist/utils/fs-utils.js +14 -25
  236. package/dist/utils/lodash-able.js +3 -4
  237. package/dist/utils/model.js +7 -14
  238. package/dist/utils/object-utils.js +41 -73
  239. package/dist/utils/path-utils.js +5 -9
  240. package/dist/utils/process-utils.js +4 -7
  241. package/dist/utils/sql-parser.js +6 -13
  242. package/dist/utils/type-utils.js +16 -26
  243. package/dist/utils/utils.js +18 -40
  244. package/dist/utils/zod-error.js +9 -16
  245. package/dist/vector/chunking.js +24 -37
  246. package/dist/vector/config.js +2 -2
  247. package/dist/vector/embedding.js +8 -19
  248. package/dist/vector/index.js +1 -2
  249. package/dist/vector/types.js +1 -1
  250. package/package.json +7 -7
  251. package/src/__tests__/env.test.ts +127 -0
  252. package/src/api/__tests__/config.test.ts +10 -1
  253. package/src/api/config.ts +4 -12
  254. package/src/api/sonamu.ts +14 -4
  255. package/src/bin/__tests__/migrate-targets.test.ts +28 -0
  256. package/src/bin/__tests__/test-command.test.ts +82 -1
  257. package/src/bin/cli.ts +9 -18
  258. package/src/bin/fixture.ts +5 -4
  259. package/src/bin/migrate-targets.ts +7 -0
  260. package/src/bin/test-command.ts +2 -2
  261. package/src/database/__tests__/db.test.ts +175 -0
  262. package/src/database/db.ts +193 -71
  263. package/src/dict/en.ts +2 -0
  264. package/src/dict/ko.ts +2 -0
  265. package/src/env.ts +123 -0
  266. package/src/migration/__tests__/migrator.test.ts +149 -0
  267. package/src/migration/migrator.ts +74 -17
  268. package/src/migration/slack-confirm.ts +21 -0
  269. package/src/skills/sonamu/database.md +1 -1
  270. package/src/skills/sonamu/entity-basic.md +31 -0
  271. package/src/skills/sonamu/puri.md +22 -0
  272. package/src/skills/sonamu/testing-devrunner.md +1 -1
  273. package/src/skills/sonamu/upsert.md +53 -6
  274. package/src/stream/ws-telemetry-memory.ts +2 -2
  275. package/src/testing/fixture-generator.ts +2 -1
  276. package/src/testing/fixture-manager.ts +3 -4
  277. package/src/testing/global-setup.ts +42 -18
  278. package/src/testing/vitest-helpers.ts +14 -0
  279. package/src/utils/controller.ts +14 -7
  280. package/tsdown.api.config.ts +6 -0
  281. package/dist/_virtual/rolldown_runtime.js +0 -39
  282. package/dist/ui-web/assets/index-D4rYm-Xz.css +0 -1
package/dist/ui/ai-api.js CHANGED
@@ -1,19 +1,15 @@
1
- import { __esmMin } from "../_virtual/rolldown_runtime.js";
1
+ import { __esmMin } from "../_virtual/_rolldown/runtime.js";
2
2
  import { SD, init_sd } from "../dict/sd.js";
3
3
  import { BadRequestException, init_so_exceptions } from "../exceptions/so-exceptions.js";
4
4
  import { aiClient, init_ai_client } from "./ai-client.js";
5
5
  import { convertToModelMessages } from "ai";
6
-
7
6
  //#region src/ui/ai-api.ts
8
7
  async function setAiApi(server) {
9
8
  await aiClient.init();
10
9
  server.post("/api/ai/fixture/chat", async (request, reply) => {
11
10
  const { messages, fixtureRecords } = request.body;
12
- if (!fixtureRecords || fixtureRecords.length === 0) {
13
- throw new BadRequestException(SD("sonamu.error.fixtureRecordRequired"));
14
- }
15
- const result = aiClient.handleFixture(await convertToModelMessages(messages), fixtureRecords);
16
- const response = result.toUIMessageStreamResponse();
11
+ if (!fixtureRecords || fixtureRecords.length === 0) throw new BadRequestException(SD("sonamu.error.fixtureRecordRequired"));
12
+ const response = aiClient.handleFixture(await convertToModelMessages(messages), fixtureRecords).toUIMessageStreamResponse();
17
13
  reply.raw.writeHead(response.status, Object.fromEntries(Object.entries(response.headers)));
18
14
  if (response.body) {
19
15
  const reader = response.body.getReader();
@@ -28,8 +24,7 @@ async function setAiApi(server) {
28
24
  });
29
25
  server.post("/api/ai/entity/chat", async (request, reply) => {
30
26
  const { messages } = request.body;
31
- const result = aiClient.handleEntity(await convertToModelMessages(messages));
32
- const response = result.toUIMessageStreamResponse();
27
+ const response = aiClient.handleEntity(await convertToModelMessages(messages)).toUIMessageStreamResponse();
33
28
  reply.raw.writeHead(response.status, Object.fromEntries(Object.entries(response.headers)));
34
29
  if (response.body) {
35
30
  const reader = response.body.getReader();
@@ -48,8 +43,8 @@ var init_ai_api = __esmMin((() => {
48
43
  init_so_exceptions();
49
44
  init_ai_client();
50
45
  }));
51
-
52
46
  //#endregion
53
47
  init_ai_api();
54
48
  export { init_ai_api, setAiApi };
55
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWktYXBpLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91aS9haS1hcGkudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29udmVydFRvTW9kZWxNZXNzYWdlcyB9IGZyb20gXCJhaVwiO1xuaW1wb3J0IHsgdHlwZSBVSU1lc3NhZ2UgfSBmcm9tIFwiYWlcIjtcbmltcG9ydCB7IHR5cGUgRmFzdGlmeUluc3RhbmNlIH0gZnJvbSBcImZhc3RpZnlcIjtcblxuaW1wb3J0IHsgU0QgfSBmcm9tIFwiLi4vZGljdC9zZFwiO1xuaW1wb3J0IHsgQmFkUmVxdWVzdEV4Y2VwdGlvbiB9IGZyb20gXCIuLi9leGNlcHRpb25zL3NvLWV4Y2VwdGlvbnNcIjtcbmltcG9ydCB7IHR5cGUgRml4dHVyZVJlY29yZCB9IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgYWlDbGllbnQgfSBmcm9tIFwiLi9haS1jbGllbnRcIjtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNldEFpQXBpKHNlcnZlcjogRmFzdGlmeUluc3RhbmNlKSB7XG4gIGF3YWl0IGFpQ2xpZW50LmluaXQoKTtcblxuICBzZXJ2ZXIucG9zdChcIi9hcGkvYWkvZml4dHVyZS9jaGF0XCIsIGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgIGNvbnN0IHsgbWVzc2FnZXMsIGZpeHR1cmVSZWNvcmRzIH0gPSByZXF1ZXN0LmJvZHkgYXMge1xuICAgICAgbWVzc2FnZXM6IFVJTWVzc2FnZVtdO1xuICAgICAgZml4dHVyZVJlY29yZHM/OiBGaXh0dXJlUmVjb3JkW107XG4gICAgfTtcblxuICAgIGlmICghZml4dHVyZVJlY29yZHMgfHwgZml4dHVyZVJlY29yZHMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihTRChcInNvbmFtdS5lcnJvci5maXh0dXJlUmVjb3JkUmVxdWlyZWRcIikpO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdCA9IGFpQ2xpZW50LmhhbmRsZUZpeHR1cmUoYXdhaXQgY29udmVydFRvTW9kZWxNZXNzYWdlcyhtZXNzYWdlcyksIGZpeHR1cmVSZWNvcmRzKTtcbiAgICBjb25zdCByZXNwb25zZSA9IHJlc3VsdC50b1VJTWVzc2FnZVN0cmVhbVJlc3BvbnNlKCk7XG5cbiAgICByZXBseS5yYXcud3JpdGVIZWFkKHJlc3BvbnNlLnN0YXR1cywgT2JqZWN0LmZyb21FbnRyaWVzKE9iamVjdC5lbnRyaWVzKHJlc3BvbnNlLmhlYWRlcnMpKSk7XG5cbiAgICBpZiAocmVzcG9uc2UuYm9keSkge1xuICAgICAgY29uc3QgcmVhZGVyID0gcmVzcG9uc2UuYm9keS5nZXRSZWFkZXIoKTtcbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGNvbnN0IHsgZG9uZSwgdmFsdWUgfSA9IGF3YWl0IHJlYWRlci5yZWFkKCk7XG4gICAgICAgIGlmIChkb25lKSBicmVhaztcbiAgICAgICAgcmVwbHkucmF3LndyaXRlKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXBseS5yYXcuZW5kKCk7XG4gICAgcmV0dXJuIHJlcGx5O1xuICB9KTtcblxuICAvLyBFbnRpdHkvRW51bSDsg53shLHsmqkgQUkgQ2hhdCBTdHJlYW1cbiAgc2VydmVyLnBvc3QoXCIvYXBpL2FpL2VudGl0eS9jaGF0XCIsIGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgIGNvbnN0IHsgbWVzc2FnZXMgfSA9IHJlcXVlc3QuYm9keSBhcyB7XG4gICAgICBtZXNzYWdlczogVUlNZXNzYWdlW107XG4gICAgfTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGFpQ2xpZW50LmhhbmRsZUVudGl0eShhd2FpdCBjb252ZXJ0VG9Nb2RlbE1lc3NhZ2VzKG1lc3NhZ2VzKSk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSByZXN1bHQudG9VSU1lc3NhZ2VTdHJlYW1SZXNwb25zZSgpO1xuXG4gICAgcmVwbHkucmF3LndyaXRlSGVhZChyZXNwb25zZS5zdGF0dXMsIE9iamVjdC5mcm9tRW50cmllcyhPYmplY3QuZW50cmllcyhyZXNwb25zZS5oZWFkZXJzKSkpO1xuXG4gICAgaWYgKHJlc3BvbnNlLmJvZHkpIHtcbiAgICAgIGNvbnN0IHJlYWRlciA9IHJlc3BvbnNlLmJvZHkuZ2V0UmVhZGVyKCk7XG4gICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBjb25zdCB7IGRvbmUsIHZhbHVlIH0gPSBhd2FpdCByZWFkZXIucmVhZCgpO1xuICAgICAgICBpZiAoZG9uZSkgYnJlYWs7XG4gICAgICAgIHJlcGx5LnJhdy53cml0ZSh2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmVwbHkucmF3LmVuZCgpO1xuICAgIHJldHVybiByZXBseTtcbiAgfSk7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFTQSxlQUFzQixTQUFTLFFBQXlCO0FBQ3RELE9BQU0sU0FBUyxNQUFNO0FBRXJCLFFBQU8sS0FBSyx3QkFBd0IsT0FBTyxTQUFTLFVBQVU7RUFDNUQsTUFBTSxFQUFFLFVBQVUsbUJBQW1CLFFBQVE7QUFLN0MsTUFBSSxDQUFDLGtCQUFrQixlQUFlLFdBQVcsR0FBRztBQUNsRCxTQUFNLElBQUksb0JBQW9CLEdBQUcscUNBQXFDLENBQUM7O0VBR3pFLE1BQU0sU0FBUyxTQUFTLGNBQWMsTUFBTSx1QkFBdUIsU0FBUyxFQUFFLGVBQWU7RUFDN0YsTUFBTSxXQUFXLE9BQU8sMkJBQTJCO0FBRW5ELFFBQU0sSUFBSSxVQUFVLFNBQVMsUUFBUSxPQUFPLFlBQVksT0FBTyxRQUFRLFNBQVMsUUFBUSxDQUFDLENBQUM7QUFFMUYsTUFBSSxTQUFTLE1BQU07R0FDakIsTUFBTSxTQUFTLFNBQVMsS0FBSyxXQUFXO0FBQ3hDLFVBQU8sTUFBTTtJQUNYLE1BQU0sRUFBRSxNQUFNLFVBQVUsTUFBTSxPQUFPLE1BQU07QUFDM0MsUUFBSSxLQUFNO0FBQ1YsVUFBTSxJQUFJLE1BQU0sTUFBTTs7O0FBSTFCLFFBQU0sSUFBSSxLQUFLO0FBQ2YsU0FBTztHQUNQO0FBR0YsUUFBTyxLQUFLLHVCQUF1QixPQUFPLFNBQVMsVUFBVTtFQUMzRCxNQUFNLEVBQUUsYUFBYSxRQUFRO0VBSTdCLE1BQU0sU0FBUyxTQUFTLGFBQWEsTUFBTSx1QkFBdUIsU0FBUyxDQUFDO0VBQzVFLE1BQU0sV0FBVyxPQUFPLDJCQUEyQjtBQUVuRCxRQUFNLElBQUksVUFBVSxTQUFTLFFBQVEsT0FBTyxZQUFZLE9BQU8sUUFBUSxTQUFTLFFBQVEsQ0FBQyxDQUFDO0FBRTFGLE1BQUksU0FBUyxNQUFNO0dBQ2pCLE1BQU0sU0FBUyxTQUFTLEtBQUssV0FBVztBQUN4QyxVQUFPLE1BQU07SUFDWCxNQUFNLEVBQUUsTUFBTSxVQUFVLE1BQU0sT0FBTyxNQUFNO0FBQzNDLFFBQUksS0FBTTtBQUNWLFVBQU0sSUFBSSxNQUFNLE1BQU07OztBQUkxQixRQUFNLElBQUksS0FBSztBQUNmLFNBQU87R0FDUDs7O1VBMUQ0QjtxQkFDa0M7aUJBRTNCIn0=
49
+
50
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWktYXBpLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91aS9haS1hcGkudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29udmVydFRvTW9kZWxNZXNzYWdlcyB9IGZyb20gXCJhaVwiO1xuaW1wb3J0IHsgdHlwZSBVSU1lc3NhZ2UgfSBmcm9tIFwiYWlcIjtcbmltcG9ydCB7IHR5cGUgRmFzdGlmeUluc3RhbmNlIH0gZnJvbSBcImZhc3RpZnlcIjtcblxuaW1wb3J0IHsgU0QgfSBmcm9tIFwiLi4vZGljdC9zZFwiO1xuaW1wb3J0IHsgQmFkUmVxdWVzdEV4Y2VwdGlvbiB9IGZyb20gXCIuLi9leGNlcHRpb25zL3NvLWV4Y2VwdGlvbnNcIjtcbmltcG9ydCB7IHR5cGUgRml4dHVyZVJlY29yZCB9IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgYWlDbGllbnQgfSBmcm9tIFwiLi9haS1jbGllbnRcIjtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNldEFpQXBpKHNlcnZlcjogRmFzdGlmeUluc3RhbmNlKSB7XG4gIGF3YWl0IGFpQ2xpZW50LmluaXQoKTtcblxuICBzZXJ2ZXIucG9zdChcIi9hcGkvYWkvZml4dHVyZS9jaGF0XCIsIGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgIGNvbnN0IHsgbWVzc2FnZXMsIGZpeHR1cmVSZWNvcmRzIH0gPSByZXF1ZXN0LmJvZHkgYXMge1xuICAgICAgbWVzc2FnZXM6IFVJTWVzc2FnZVtdO1xuICAgICAgZml4dHVyZVJlY29yZHM/OiBGaXh0dXJlUmVjb3JkW107XG4gICAgfTtcblxuICAgIGlmICghZml4dHVyZVJlY29yZHMgfHwgZml4dHVyZVJlY29yZHMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihTRChcInNvbmFtdS5lcnJvci5maXh0dXJlUmVjb3JkUmVxdWlyZWRcIikpO1xuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdCA9IGFpQ2xpZW50LmhhbmRsZUZpeHR1cmUoYXdhaXQgY29udmVydFRvTW9kZWxNZXNzYWdlcyhtZXNzYWdlcyksIGZpeHR1cmVSZWNvcmRzKTtcbiAgICBjb25zdCByZXNwb25zZSA9IHJlc3VsdC50b1VJTWVzc2FnZVN0cmVhbVJlc3BvbnNlKCk7XG5cbiAgICByZXBseS5yYXcud3JpdGVIZWFkKHJlc3BvbnNlLnN0YXR1cywgT2JqZWN0LmZyb21FbnRyaWVzKE9iamVjdC5lbnRyaWVzKHJlc3BvbnNlLmhlYWRlcnMpKSk7XG5cbiAgICBpZiAocmVzcG9uc2UuYm9keSkge1xuICAgICAgY29uc3QgcmVhZGVyID0gcmVzcG9uc2UuYm9keS5nZXRSZWFkZXIoKTtcbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGNvbnN0IHsgZG9uZSwgdmFsdWUgfSA9IGF3YWl0IHJlYWRlci5yZWFkKCk7XG4gICAgICAgIGlmIChkb25lKSBicmVhaztcbiAgICAgICAgcmVwbHkucmF3LndyaXRlKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXBseS5yYXcuZW5kKCk7XG4gICAgcmV0dXJuIHJlcGx5O1xuICB9KTtcblxuICAvLyBFbnRpdHkvRW51bSDsg53shLHsmqkgQUkgQ2hhdCBTdHJlYW1cbiAgc2VydmVyLnBvc3QoXCIvYXBpL2FpL2VudGl0eS9jaGF0XCIsIGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgIGNvbnN0IHsgbWVzc2FnZXMgfSA9IHJlcXVlc3QuYm9keSBhcyB7XG4gICAgICBtZXNzYWdlczogVUlNZXNzYWdlW107XG4gICAgfTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGFpQ2xpZW50LmhhbmRsZUVudGl0eShhd2FpdCBjb252ZXJ0VG9Nb2RlbE1lc3NhZ2VzKG1lc3NhZ2VzKSk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSByZXN1bHQudG9VSU1lc3NhZ2VTdHJlYW1SZXNwb25zZSgpO1xuXG4gICAgcmVwbHkucmF3LndyaXRlSGVhZChyZXNwb25zZS5zdGF0dXMsIE9iamVjdC5mcm9tRW50cmllcyhPYmplY3QuZW50cmllcyhyZXNwb25zZS5oZWFkZXJzKSkpO1xuXG4gICAgaWYgKHJlc3BvbnNlLmJvZHkpIHtcbiAgICAgIGNvbnN0IHJlYWRlciA9IHJlc3BvbnNlLmJvZHkuZ2V0UmVhZGVyKCk7XG4gICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBjb25zdCB7IGRvbmUsIHZhbHVlIH0gPSBhd2FpdCByZWFkZXIucmVhZCgpO1xuICAgICAgICBpZiAoZG9uZSkgYnJlYWs7XG4gICAgICAgIHJlcGx5LnJhdy53cml0ZSh2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmVwbHkucmF3LmVuZCgpO1xuICAgIHJldHVybiByZXBseTtcbiAgfSk7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQVNBLGVBQXNCLFNBQVMsUUFBeUI7Q0FDdEQsTUFBTSxTQUFTLEtBQUs7Q0FFcEIsT0FBTyxLQUFLLHdCQUF3QixPQUFPLFNBQVMsVUFBVTtFQUM1RCxNQUFNLEVBQUUsVUFBVSxtQkFBbUIsUUFBUTtFQUs3QyxJQUFJLENBQUMsa0JBQWtCLGVBQWUsV0FBVyxHQUMvQyxNQUFNLElBQUksb0JBQW9CLEdBQUcsb0NBQW9DLENBQUM7RUFJeEUsTUFBTSxXQURTLFNBQVMsY0FBYyxNQUFNLHVCQUF1QixRQUFRLEdBQUcsY0FDN0QsQ0FBQSxDQUFPLDBCQUEwQjtFQUVsRCxNQUFNLElBQUksVUFBVSxTQUFTLFFBQVEsT0FBTyxZQUFZLE9BQU8sUUFBUSxTQUFTLE9BQU8sQ0FBQyxDQUFDO0VBRXpGLElBQUksU0FBUyxNQUFNO0dBQ2pCLE1BQU0sU0FBUyxTQUFTLEtBQUssVUFBVTtHQUN2QyxPQUFPLE1BQU07SUFDWCxNQUFNLEVBQUUsTUFBTSxVQUFVLE1BQU0sT0FBTyxLQUFLO0lBQzFDLElBQUksTUFBTTtJQUNWLE1BQU0sSUFBSSxNQUFNLEtBQUs7R0FDdkI7RUFDRjtFQUVBLE1BQU0sSUFBSSxJQUFJO0VBQ2QsT0FBTztDQUNULENBQUM7Q0FHRCxPQUFPLEtBQUssdUJBQXVCLE9BQU8sU0FBUyxVQUFVO0VBQzNELE1BQU0sRUFBRSxhQUFhLFFBQVE7RUFLN0IsTUFBTSxXQURTLFNBQVMsYUFBYSxNQUFNLHVCQUF1QixRQUFRLENBQ3pELENBQUEsQ0FBTywwQkFBMEI7RUFFbEQsTUFBTSxJQUFJLFVBQVUsU0FBUyxRQUFRLE9BQU8sWUFBWSxPQUFPLFFBQVEsU0FBUyxPQUFPLENBQUMsQ0FBQztFQUV6RixJQUFJLFNBQVMsTUFBTTtHQUNqQixNQUFNLFNBQVMsU0FBUyxLQUFLLFVBQVU7R0FDdkMsT0FBTyxNQUFNO0lBQ1gsTUFBTSxFQUFFLE1BQU0sVUFBVSxNQUFNLE9BQU8sS0FBSztJQUMxQyxJQUFJLE1BQU07SUFDVixNQUFNLElBQUksTUFBTSxLQUFLO0dBQ3ZCO0VBQ0Y7RUFFQSxNQUFNLElBQUksSUFBSTtFQUNkLE9BQU87Q0FDVCxDQUFDO0FBQ0g7O1NBM0QrQjtvQkFDa0M7Z0JBRTNCIn0=
@@ -1,13 +1,12 @@
1
- import { __esmMin } from "../_virtual/rolldown_runtime.js";
1
+ import { __esmMin } from "../_virtual/_rolldown/runtime.js";
2
2
  import { init_utils, nonNullable } from "../utils/utils.js";
3
3
  import { Sonamu, init_sonamu } from "../api/sonamu.js";
4
4
  import { TemplateOptions, getEnumDefValues, init_types, isInternalSubsetField, normalizeSubsetField } from "../types/types.js";
5
5
  import { EntityManager, init_entity_manager } from "../entity/entity-manager.js";
6
6
  import { z as z$1 } from "zod";
7
7
  import assert from "assert";
8
- import path from "path";
9
8
  import fs from "fs";
10
-
9
+ import path from "path";
11
10
  //#region src/ui/ai-client.ts
12
11
  /**
13
12
  * Entity JSON이 entity.instructions.md의 규칙을 따르는지 검증합니다.
@@ -15,42 +14,28 @@ import fs from "fs";
15
14
  function validateEntityJson(input) {
16
15
  const errors = [];
17
16
  const { entityId, props, enums } = input;
18
- const hasIdProp = props?.some((p) => p.name === "id");
19
- if (!hasIdProp) {
20
- errors.push({
21
- field: "props",
22
- message: "id 프로퍼티가 필수입니다."
23
- });
24
- }
25
- const hasCreatedAtProp = props?.some((p) => p.name === "created_at");
26
- if (!hasCreatedAtProp) {
27
- errors.push({
28
- field: "props",
29
- message: "created_at 프로퍼티가 필수입니다."
30
- });
31
- }
17
+ if (!props?.some((p) => p.name === "id")) errors.push({
18
+ field: "props",
19
+ message: "id 프로퍼티가 필수입니다."
20
+ });
21
+ if (!props?.some((p) => p.name === "created_at")) errors.push({
22
+ field: "props",
23
+ message: "created_at 프로퍼티가 필수입니다."
24
+ });
32
25
  const orderByEnumId = `${entityId}OrderBy`;
33
26
  const searchFieldEnumId = `${entityId}SearchField`;
34
- if (!enums?.[orderByEnumId]) {
35
- errors.push({
36
- field: "enums",
37
- message: `${orderByEnumId} enum이 필수입니다. (예: { "id-desc": "ID최신순" })`
38
- });
39
- }
40
- if (!enums?.[searchFieldEnumId]) {
41
- errors.push({
42
- field: "enums",
43
- message: `${searchFieldEnumId} enum이 필수입니다. (예: { "id": "ID" })`
44
- });
45
- }
46
- for (const prop of props ?? []) {
47
- if (prop.type === "enum" && !enums?.[prop.id]) {
48
- errors.push({
49
- field: `props.${prop.name}`,
50
- message: `enum id "${prop.id}"가 enums에 정의되어 있지 않습니다.`
51
- });
52
- }
53
- }
27
+ if (!enums?.[orderByEnumId]) errors.push({
28
+ field: "enums",
29
+ message: `${orderByEnumId} enum이 필수입니다. (예: { "id-desc": "ID최신순" })`
30
+ });
31
+ if (!enums?.[searchFieldEnumId]) errors.push({
32
+ field: "enums",
33
+ message: `${searchFieldEnumId} enum이 필수입니다. (예: { "id": "ID" })`
34
+ });
35
+ for (const prop of props ?? []) if (prop.type === "enum" && !enums?.[prop.id]) errors.push({
36
+ field: `props.${prop.name}`,
37
+ message: `enum id "${prop.id}"가 enums에 정의되어 있지 않습니다.`
38
+ });
54
39
  return errors;
55
40
  }
56
41
  var AIClient, aiClient;
@@ -77,11 +62,8 @@ var init_ai_client = __esmMin((() => {
77
62
  }
78
63
  }
79
64
  handleFixture(messages, fixtureRecords) {
80
- if (!this.aiSdk || !this.model) {
81
- throw new Error("AI SDK not initialized. Call init() first.");
82
- }
83
- const usedEntityIds = [...new Set(fixtureRecords.map((r) => r.entityId))];
84
- const entityStructures = usedEntityIds.map((entityId) => {
65
+ if (!this.aiSdk || !this.model) throw new Error("AI SDK not initialized. Call init() first.");
66
+ const entityStructures = [...new Set(fixtureRecords.map((r) => r.entityId))].map((entityId) => {
85
67
  const entity = EntityManager.get(entityId);
86
68
  return {
87
69
  entityId: entity.id,
@@ -132,19 +114,16 @@ var init_ai_client = __esmMin((() => {
132
114
  updates: z$1.record(z$1.string(), z$1.unknown()).describe("컬럼명을 키로, 새 값을 값으로 하는 객체")
133
115
  })) }),
134
116
  execute: async ({ updates }) => {
135
- const updatedRecords = fixtureRecords.map((record) => {
136
- const update = updates.find((u) => u.fixtureId === record.fixtureId);
137
- if (update) {
138
- for (const [columnName, newValue] of Object.entries(update.updates)) {
139
- record.columns[columnName].value = newValue;
140
- }
141
- return record;
142
- }
143
- return record;
144
- });
145
117
  return {
146
118
  success: true,
147
- updatedRecords
119
+ updatedRecords: fixtureRecords.map((record) => {
120
+ const update = updates.find((u) => u.fixtureId === record.fixtureId);
121
+ if (update) {
122
+ for (const [columnName, newValue] of Object.entries(update.updates)) record.columns[columnName].value = newValue;
123
+ return record;
124
+ }
125
+ return record;
126
+ })
148
127
  };
149
128
  }
150
129
  }),
@@ -162,11 +141,8 @@ var init_ai_client = __esmMin((() => {
162
141
  for (const prop of entity.props) {
163
142
  if (prop.type === "virtual") continue;
164
143
  let value = fixture.columns[prop.name] ?? null;
165
- if (prop.name === "created_at") {
166
- value = new Date().toISOString();
167
- } else if (prop.type === "relation" && (prop.relationType === "HasMany" || prop.relationType === "ManyToMany")) {
168
- value = Array.isArray(value) ? value : [value].filter(nonNullable);
169
- }
144
+ if (prop.name === "created_at") value = (/* @__PURE__ */ new Date()).toISOString();
145
+ else if (prop.type === "relation" && (prop.relationType === "HasMany" || prop.relationType === "ManyToMany")) value = Array.isArray(value) ? value : [value].filter(nonNullable);
170
146
  columns[prop.name] = {
171
147
  prop,
172
148
  value
@@ -182,34 +158,28 @@ var init_ai_client = __esmMin((() => {
182
158
  override: false
183
159
  };
184
160
  });
185
- for (const newRecord of newRecords) {
186
- for (const [_colName, col] of Object.entries(newRecord.columns)) {
187
- if (col.prop.type !== "relation" || col.value === null) continue;
188
- const relatedEntityId = col.prop.with;
189
- const relatedIds = Array.isArray(col.value) ? col.value : [col.value];
190
- for (const relatedId of relatedIds) {
191
- const relatedFixtureId = `${relatedEntityId}#${relatedId}`;
192
- const relatedRecord = newRecords.find((r) => r.fixtureId === relatedFixtureId);
193
- if (relatedRecord) {
194
- const reverseCol = Object.entries(relatedRecord.columns).find(([, c]) => c.prop.type === "relation" && c.prop.with === newRecord.entityId);
195
- if (reverseCol) {
196
- const [reverseColName, reverseColValue] = reverseCol;
197
- const currentValue = reverseColValue.value;
198
- if (reverseColValue.prop.type === "relation" && (reverseColValue.prop.relationType === "HasMany" || reverseColValue.prop.relationType === "ManyToMany")) {
199
- assert(Array.isArray(currentValue), "currentValue must be an array");
200
- if (!currentValue.includes(newRecord.id)) {
201
- relatedRecord.columns[reverseColName] = {
202
- ...reverseColValue,
203
- value: [...currentValue, newRecord.id]
204
- };
205
- }
206
- } else {
207
- relatedRecord.columns[reverseColName] = {
208
- ...reverseColValue,
209
- value: newRecord.id
210
- };
211
- }
212
- }
161
+ for (const newRecord of newRecords) for (const [_colName, col] of Object.entries(newRecord.columns)) {
162
+ if (col.prop.type !== "relation" || col.value === null) continue;
163
+ const relatedEntityId = col.prop.with;
164
+ const relatedIds = Array.isArray(col.value) ? col.value : [col.value];
165
+ for (const relatedId of relatedIds) {
166
+ const relatedFixtureId = `${relatedEntityId}#${relatedId}`;
167
+ const relatedRecord = newRecords.find((r) => r.fixtureId === relatedFixtureId);
168
+ if (relatedRecord) {
169
+ const reverseCol = Object.entries(relatedRecord.columns).find(([, c]) => c.prop.type === "relation" && c.prop.with === newRecord.entityId);
170
+ if (reverseCol) {
171
+ const [reverseColName, reverseColValue] = reverseCol;
172
+ const currentValue = reverseColValue.value;
173
+ if (reverseColValue.prop.type === "relation" && (reverseColValue.prop.relationType === "HasMany" || reverseColValue.prop.relationType === "ManyToMany")) {
174
+ assert(Array.isArray(currentValue), "currentValue must be an array");
175
+ if (!currentValue.includes(newRecord.id)) relatedRecord.columns[reverseColName] = {
176
+ ...reverseColValue,
177
+ value: [...currentValue, newRecord.id]
178
+ };
179
+ } else relatedRecord.columns[reverseColName] = {
180
+ ...reverseColValue,
181
+ value: newRecord.id
182
+ };
213
183
  }
214
184
  }
215
185
  }
@@ -224,13 +194,10 @@ var init_ai_client = __esmMin((() => {
224
194
  });
225
195
  }
226
196
  handleEntity(messages) {
227
- if (!this.aiSdk || !this.model) {
228
- throw new Error("AI SDK not initialized. Call init() first.");
229
- }
197
+ if (!this.aiSdk || !this.model) throw new Error("AI SDK not initialized. Call init() first.");
230
198
  const instructionsPath = path.join(import.meta.dirname, "..", "..", "src", "ui", "entity.instructions.md");
231
199
  const instructions = fs.readFileSync(instructionsPath, "utf-8");
232
- const entityIds = EntityManager.getAllIds();
233
- const existingEntities = entityIds.map((entityId) => {
200
+ const existingEntities = EntityManager.getAllIds().map((entityId) => {
234
201
  const entity = EntityManager.get(entityId);
235
202
  return {
236
203
  id: entity.id,
@@ -322,14 +289,12 @@ updateEntity({ entityId: "Project", updates: { props: [{ name: "priority", type:
322
289
  execute: async (entity) => {
323
290
  try {
324
291
  const validationErrors = validateEntityJson(entity);
325
- if (validationErrors.length > 0) {
326
- return {
327
- success: false,
328
- entityId: entity.entityId,
329
- error: `검증 오류: ${validationErrors.map((e) => `[${e.field}] ${e.message}`).join(", ")}`,
330
- validationErrors
331
- };
332
- }
292
+ if (validationErrors.length > 0) return {
293
+ success: false,
294
+ entityId: entity.entityId,
295
+ error: `검증 오류: ${validationErrors.map((e) => `[${e.field}] ${e.message}`).join(", ")}`,
296
+ validationErrors
297
+ };
333
298
  await Sonamu.syncer.createEntity({
334
299
  subsets: { A: ["id"] },
335
300
  enums: {},
@@ -360,29 +325,19 @@ updateEntity({ entityId: "Project", updates: { props: [{ name: "priority", type:
360
325
  execute: async ({ entityId, updates, mode = "merge" }) => {
361
326
  try {
362
327
  const entity = EntityManager.get(entityId);
363
- if (updates.entityId !== undefined) entity.id = updates.entityId;
364
- if (updates.parentId !== undefined) entity.parentId = updates.parentId;
365
- if (updates.title !== undefined) entity.title = updates.title;
366
- if (updates.table !== undefined) entity.table = updates.table;
367
- if (updates.cone !== undefined) entity.cone = updates.cone;
368
- if (updates.props !== undefined) {
369
- if (mode === "replace") {
370
- entity.props = updates.props;
371
- } else {
372
- for (const newProp of updates.props) {
373
- const existingIndex = entity.props.findIndex((p) => p.name === newProp.name);
374
- if (existingIndex >= 0) {
375
- entity.props[existingIndex] = newProp;
376
- } else {
377
- entity.props.push(newProp);
378
- }
379
- }
380
- }
381
- }
382
- if (updates.indexes !== undefined) {
383
- entity.indexes = mode === "replace" ? updates.indexes : [...entity.indexes, ...updates.indexes];
328
+ if (updates.entityId !== void 0) entity.id = updates.entityId;
329
+ if (updates.parentId !== void 0) entity.parentId = updates.parentId;
330
+ if (updates.title !== void 0) entity.title = updates.title;
331
+ if (updates.table !== void 0) entity.table = updates.table;
332
+ if (updates.cone !== void 0) entity.cone = updates.cone;
333
+ if (updates.props !== void 0) if (mode === "replace") entity.props = updates.props;
334
+ else for (const newProp of updates.props) {
335
+ const existingIndex = entity.props.findIndex((p) => p.name === newProp.name);
336
+ if (existingIndex >= 0) entity.props[existingIndex] = newProp;
337
+ else entity.props.push(newProp);
384
338
  }
385
- if (updates.subsets !== undefined) {
339
+ if (updates.indexes !== void 0) entity.indexes = mode === "replace" ? updates.indexes : [...entity.indexes, ...updates.indexes];
340
+ if (updates.subsets !== void 0) {
386
341
  const normalizedSubsets = {};
387
342
  const normalizedSubsetsInternal = {};
388
343
  for (const [key, fields] of Object.entries(updates.subsets)) {
@@ -399,7 +354,7 @@ updateEntity({ entityId: "Project", updates: { props: [{ name: "priority", type:
399
354
  ...normalizedSubsetsInternal
400
355
  };
401
356
  }
402
- if (updates.enums !== undefined) {
357
+ if (updates.enums !== void 0) {
403
358
  const convertedEnums = Object.fromEntries(Object.entries(updates.enums).map(([key, enumDef]) => [key, getEnumDefValues(enumDef)]));
404
359
  entity.enumLabels = mode === "replace" ? convertedEnums : {
405
360
  ...entity.enumLabels,
@@ -411,25 +366,22 @@ updateEntity({ entityId: "Project", updates: { props: [{ name: "priority", type:
411
366
  entityId: entity.id,
412
367
  enums: entity.enumLabels
413
368
  });
414
- if (validationErrors.length > 0) {
415
- return {
416
- success: false,
417
- entityId,
418
- error: `검증 오류: ${validationErrors.map((e) => `[${e.field}] ${e.message}`).join(", ")}`,
419
- validationErrors
420
- };
421
- }
369
+ if (validationErrors.length > 0) return {
370
+ success: false,
371
+ entityId,
372
+ error: `검증 오류: ${validationErrors.map((e) => `[${e.field}] ${e.message}`).join(", ")}`,
373
+ validationErrors
374
+ };
422
375
  await entity.save();
423
376
  return {
424
377
  success: true,
425
378
  entityId
426
379
  };
427
380
  } catch (e) {
428
- const error = e instanceof Error ? e.message : "Unknown error";
429
381
  return {
430
382
  success: false,
431
383
  entityId,
432
- error
384
+ error: e instanceof Error ? e.message : "Unknown error"
433
385
  };
434
386
  }
435
387
  }
@@ -440,8 +392,8 @@ updateEntity({ entityId: "Project", updates: { props: [{ name: "priority", type:
440
392
  };
441
393
  aiClient = new AIClient();
442
394
  }));
443
-
444
395
  //#endregion
445
396
  init_ai_client();
446
397
  export { aiClient, init_ai_client };
447
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWktY2xpZW50LmpzIiwibmFtZXMiOlsiZXJyb3JzOiBWYWxpZGF0aW9uRXJyb3JbXSIsInoiLCJ1cGRhdGVkUmVjb3JkczogRml4dHVyZVJlY29yZFtdIiwibmV3UmVjb3JkczogRml4dHVyZVJlY29yZFtdIiwiY29sdW1uczogRml4dHVyZVJlY29yZFtcImNvbHVtbnNcIl0iLCJub3JtYWxpemVkU3Vic2V0czogeyBba2V5OiBzdHJpbmddOiBzdHJpbmdbXSB9Iiwibm9ybWFsaXplZFN1YnNldHNJbnRlcm5hbDogeyBba2V5OiBzdHJpbmddOiBzdHJpbmdbXSB9Il0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3VpL2FpLWNsaWVudC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXNzZXJ0IGZyb20gXCJhc3NlcnRcIjtcbmltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5cbi8qIG94bGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgKi8gLy8gQUkgU0RL7J2YIO2DgOyeheydtCDrqoXtmZXtlZjsp4Ag7JWK7JWEIGFueeulvCDtl4jsmqntlahcbmltcG9ydCB7IHR5cGUgTGFuZ3VhZ2VNb2RlbCwgdHlwZSBNb2RlbE1lc3NhZ2UsIHR5cGUgU3RyZWFtVGV4dFJlc3VsdCB9IGZyb20gXCJhaVwiO1xuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcblxuaW1wb3J0IHsgU29uYW11IH0gZnJvbSBcIi4uL2FwaS9zb25hbXVcIjtcbmltcG9ydCB7IEVudGl0eU1hbmFnZXIgfSBmcm9tIFwiLi4vZW50aXR5L2VudGl0eS1tYW5hZ2VyXCI7XG5pbXBvcnQge1xuICBnZXRFbnVtRGVmVmFsdWVzLFxuICBpc0ludGVybmFsU3Vic2V0RmllbGQsXG4gIG5vcm1hbGl6ZVN1YnNldEZpZWxkLFxuICBUZW1wbGF0ZU9wdGlvbnMsXG59IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgdHlwZSBFbnRpdHlQcm9wLCB0eXBlIEZpeHR1cmVSZWNvcmQgfSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IG5vbk51bGxhYmxlIH0gZnJvbSBcIi4uL3V0aWxzL3V0aWxzXCI7XG5cbnR5cGUgVmFsaWRhdGlvbkVycm9yID0ge1xuICBmaWVsZDogc3RyaW5nO1xuICBtZXNzYWdlOiBzdHJpbmc7XG59O1xuXG5jbGFzcyBBSUNsaWVudCB7XG4gIHByaXZhdGUgbW9kZWw6IExhbmd1YWdlTW9kZWwgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBhaVNkazpcbiAgICB8ICh0eXBlb2YgaW1wb3J0KFwiYWlcIikgJiB7XG4gICAgICAgIGFudGhyb3BpYz86IHR5cGVvZiBpbXBvcnQoXCJAYWktc2RrL2FudGhyb3BpY1wiKS5hbnRocm9waWM7XG4gICAgICB9KVxuICAgIHwgbnVsbCA9IG51bGw7XG5cbiAgYXN5bmMgaW5pdCgpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgeyBhbnRocm9waWMgfSA9IGF3YWl0IGltcG9ydChcIkBhaS1zZGsvYW50aHJvcGljXCIpO1xuICAgICAgY29uc3QgYWlNb2R1bGUgPSBhd2FpdCBpbXBvcnQoXCJhaVwiKTtcbiAgICAgIHRoaXMuYWlTZGsgPSB7IC4uLmFpTW9kdWxlLCBhbnRocm9waWMgfTtcbiAgICAgIHRoaXMubW9kZWwgPSBhbnRocm9waWMoXCJjbGF1ZGUtc29ubmV0LTQtNlwiKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBcIkFJIFNESyBwYWNrYWdlcyBub3QgaW5zdGFsbGVkLiBJbnN0YWxsIEBhaS1zZGsvYW50aHJvcGljIGFuZCBhaSB0byB1c2UgQUkgZmVhdHVyZXMuXCIsXG4gICAgICApO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlRml4dHVyZShcbiAgICBtZXNzYWdlczogTW9kZWxNZXNzYWdlW10sXG4gICAgZml4dHVyZVJlY29yZHM6IEZpeHR1cmVSZWNvcmRbXSxcbiAgKTogU3RyZWFtVGV4dFJlc3VsdDxhbnksIGFueT4ge1xuICAgIGlmICghdGhpcy5haVNkayB8fCAhdGhpcy5tb2RlbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQUkgU0RLIG5vdCBpbml0aWFsaXplZC4gQ2FsbCBpbml0KCkgZmlyc3QuXCIpO1xuICAgIH1cblxuICAgIC8vIO2YhOyerCBmaXh0dXJlUmVjb3Jkc+yXkOyEnCDsgqzsmqnrkJwg7JeU7Yuw7Yuw65Ok7J2YIOq1rOyhsCDsoJXrs7Qg7IiY7KeRXG4gICAgY29uc3QgdXNlZEVudGl0eUlkcyA9IFsuLi5uZXcgU2V0KGZpeHR1cmVSZWNvcmRzLm1hcCgocikgPT4gci5lbnRpdHlJZCkpXTtcbiAgICBjb25zdCBlbnRpdHlTdHJ1Y3R1cmVzID0gdXNlZEVudGl0eUlkcy5tYXAoKGVudGl0eUlkKSA9PiB7XG4gICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGVudGl0eUlkOiBlbnRpdHkuaWQsXG4gICAgICAgIHRhYmxlOiBlbnRpdHkudGFibGUsXG4gICAgICAgIHByb3BzOiBlbnRpdHkucHJvcHMsXG4gICAgICAgIHJlbGF0aW9uczogZW50aXR5LnJlbGF0aW9ucyxcbiAgICAgICAgZW51bUxhYmVsczogZW50aXR5LmVudW1MYWJlbHMsXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgY29uc3Qgc3lzdGVtTWVzc2FnZSA9IGBcbiAgICAgICAg64u57Iug7J2AIO2UveyKpOyzkCDroIjsvZTrk5zrpbwg7IiY7KCV7ZWY6rOgIOyDneyEse2VoCDsiJgg7J6I64qUIOuPhOyasOuvuOyeheuLiOuLpC5cblxuICAgICAgICDtmITsnqwg7ZS97Iqk7LOQIOugiOy9lOuTnDpcbiAgICAgICAgJHtKU09OLnN0cmluZ2lmeShmaXh0dXJlUmVjb3JkcywgbnVsbCwgMil9XG5cbiAgICAgICAg7JeU7Yuw7YuwIOq1rOyhsCDsoJXrs7Q6XG4gICAgICAgICR7SlNPTi5zdHJpbmdpZnkoZW50aXR5U3RydWN0dXJlcywgbnVsbCwgMil9XG5cbiAgICAgICAgIyMg7ZS97Iqk7LOQIOyImOyglVxuICAgICAgICDsgqzsmqnsnpDqsIAg7ZS97Iqk7LOQIOqwkiDsiJjsoJXsnYQg7JqU7LKt7ZWY66m0IHVwZGF0ZUZpeHR1cmVzIOuPhOq1rOulvCDsgqzsmqntlZjsl6wg67OA6rK97IKs7ZWt7J2EIOyggeyaqe2VmOyEuOyalC5cbiAgICAgICAgLSBmaXh0dXJlSWQ6IOyImOygle2VoCDtlL3siqTss5AgSUQgKO2YleyLnTogXCJFbnRpdHlJZCNpZFwiKVxuICAgICAgICAtIHVwZGF0ZXM6IOy7rOufvOuqheydhCDtgqTroZwsIOyDiCDqsJLsnYQg6rCS7Jy866GcIO2VmOuKlCDqsJ3ssrRcblxuICAgICAgICDsmIjsi5w6IFwiVXNlciMxXCIg7ZS97Iqk7LOQ7J2YIFwibmFtZVwiIOy7rOufvOydhCBcIu2Zjeq4uOuPmVwi7Jy866GcIOuzgOqyve2VmOugpOuptDpcbiAgICAgICAgdXBkYXRlRml4dHVyZXMoeyB1cGRhdGVzOiBbeyBmaXh0dXJlSWQ6IFwiVXNlciMxXCIsIHVwZGF0ZXM6IHsgbmFtZTogXCLtmY3quLjrj5lcIiB9IH1dIH0pXG5cbiAgICAgICAg67OA6rK965CgIOy7rOufvOydmCB0eXBl7J20IHJlbGF0aW9u7J24IOqyveyasCwg6rSA66CoIOyXlO2LsO2LsOyXkOuPhCDrsJjsmIHrkJjslrTslbwg7ZWgIOy7rOufvOydtCDsnojripTsp4Ag7ZmV7J247ZWY7IS47JqULlxuXG4gICAgICAgICMjIO2UveyKpOyzkCDsg53shLFcbiAgICAgICAg7IKs7Jqp7J6Q6rCAIOyDiOuhnOyatCDtlL3siqTss5Ag7IOd7ISx7J2EIOyalOyyre2VmOuptCBjcmVhdGVGaXh0dXJlcyDrj4Tqtazrpbwg7IKs7Jqp7ZWY7IS47JqULlxuICAgICAgICAtIGVudGl0eUlkOiDsg53shLHtlaAg7JeU7Yuw7YuwIElEXG4gICAgICAgIC0gaWQ6IOyDiCDroIjsvZTrk5zsnZggSUQgKOq4sOyhtCDtlL3siqTss5DsmYAg7KSR67O165CY7KeAIOyViuuKlCDsnYzsiJgg7IKs7JqpIOq2jOyepSwg7JiIOiAtMSwgLTIpXG4gICAgICAgIC0gY29sdW1uczog7Lus65+866qF7J2EIO2CpOuhnCwg6rCS7J2EIOqwkuycvOuhnCDtlZjripQg6rCd7LK0ICjsl5Tti7Dti7Ag6rWs7KGwIOywuOqzoClcblxuICAgICAgICDsmIjsi5w6IOyDiOuhnOyatCBVc2VyIO2UveyKpOyzkOulvCDsg53shLHtlZjroKTrqbQ6XG4gICAgICAgIGNyZWF0ZUZpeHR1cmVzKHsgZml4dHVyZXM6IFt7IGVudGl0eUlkOiBcIlVzZXJcIiwgaWQ6IC0xLCBjb2x1bW5zOiB7IG5hbWU6IFwi7ZmN6ri464+ZXCIsIGVtYWlsOiBcImhvbmdAZXhhbXBsZS5jb21cIiB9IH1dIH0pXG4gICAgICBgO1xuXG4gICAgY29uc3QgeyBzdHJlYW1UZXh0LCB0b29sIH0gPSB0aGlzLmFpU2RrO1xuXG4gICAgcmV0dXJuIHN0cmVhbVRleHQoe1xuICAgICAgbW9kZWw6IHRoaXMubW9kZWwsXG4gICAgICBzeXN0ZW06IHN5c3RlbU1lc3NhZ2UsXG4gICAgICBtZXNzYWdlcyxcbiAgICAgIHRvb2xzOiB7XG4gICAgICAgIHVwZGF0ZUZpeHR1cmVzOiB0b29sKHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwi7ZS97Iqk7LOQIOugiOy9lOuTnOydmCDqsJLsnYQg7IiY7KCV7ZWp64uI64ukLiDsgqzsmqnsnpDqsIAg7Yq57KCVIOy7rOufvOydtOuCmCDqsJLsnYQg67OA6rK97ZW064us65286rOgIOyalOyyre2VoCDrlYwg7IKs7Jqp7ZWY7IS47JqULlwiLFxuICAgICAgICAgIGlucHV0U2NoZW1hOiB6Lm9iamVjdCh7XG4gICAgICAgICAgICB1cGRhdGVzOiB6LmFycmF5KFxuICAgICAgICAgICAgICB6Lm9iamVjdCh7XG4gICAgICAgICAgICAgICAgZml4dHVyZUlkOiB6LnN0cmluZygpLmRlc2NyaWJlKFwi7IiY7KCV7ZWgIO2UveyKpOyzkCBJRCAo7ZiV7IudOiBFbnRpdHlJZCNpZClcIiksXG4gICAgICAgICAgICAgICAgdXBkYXRlczogelxuICAgICAgICAgICAgICAgICAgLnJlY29yZCh6LnN0cmluZygpLCB6LnVua25vd24oKSlcbiAgICAgICAgICAgICAgICAgIC5kZXNjcmliZShcIuy7rOufvOuqheydhCDtgqTroZwsIOyDiCDqsJLsnYQg6rCS7Jy866GcIO2VmOuKlCDqsJ3ssrRcIiksXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBleGVjdXRlOiBhc3luYyAoe1xuICAgICAgICAgICAgdXBkYXRlcyxcbiAgICAgICAgICB9OiB7XG4gICAgICAgICAgICB1cGRhdGVzOiBBcnJheTx7IGZpeHR1cmVJZDogc3RyaW5nOyB1cGRhdGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB9PjtcbiAgICAgICAgICB9KTogUHJvbWlzZTx7IHN1Y2Nlc3M6IGJvb2xlYW47IHVwZGF0ZWRSZWNvcmRzOiBGaXh0dXJlUmVjb3JkW10gfT4gPT4ge1xuICAgICAgICAgICAgLy8gZml4dHVyZVJlY29yZHPrpbwg67O17IKs7ZWY6rOgIOyXheuNsOydtO2KuCDsoIHsmqlcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZWRSZWNvcmRzOiBGaXh0dXJlUmVjb3JkW10gPSBmaXh0dXJlUmVjb3Jkcy5tYXAoKHJlY29yZCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCB1cGRhdGUgPSB1cGRhdGVzLmZpbmQoXG4gICAgICAgICAgICAgICAgKHU6IHsgZml4dHVyZUlkOiBzdHJpbmcgfSkgPT4gdS5maXh0dXJlSWQgPT09IHJlY29yZC5maXh0dXJlSWQsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGlmICh1cGRhdGUpIHtcbiAgICAgICAgICAgICAgICAvLyBjb2x1bW5z7J2YIHZhbHVl66W8IOyXheuNsOydtO2KuFxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2NvbHVtbk5hbWUsIG5ld1ZhbHVlXSBvZiBPYmplY3QuZW50cmllcyh1cGRhdGUudXBkYXRlcykpIHtcbiAgICAgICAgICAgICAgICAgIHJlY29yZC5jb2x1bW5zW2NvbHVtbk5hbWVdLnZhbHVlID1cbiAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWUgYXMgRml4dHVyZVJlY29yZFtcImNvbHVtbnNcIl1bc3RyaW5nXVtcInZhbHVlXCJdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVjb3JkO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgcmV0dXJuIHJlY29yZDtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCB1cGRhdGVkUmVjb3JkcyB9O1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgICBjcmVhdGVGaXh0dXJlczogdG9vbCh7XG4gICAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgICBcIuyDiOuhnOyatCDtlL3siqTss5Ag66CI7L2U65Oc66W8IOyDneyEse2VqeuLiOuLpC4g7IKs7Jqp7J6Q6rCAIOyDiOuhnOyatCDrjbDsnbTthLDrpbwg7LaU6rCA7ZW064us65286rOgIOyalOyyre2VoCDrlYwg7IKs7Jqp7ZWY7IS47JqULlwiLFxuICAgICAgICAgIGlucHV0U2NoZW1hOiB6Lm9iamVjdCh7XG4gICAgICAgICAgICBmaXh0dXJlczogei5hcnJheShcbiAgICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICAgIGVudGl0eUlkOiB6LnN0cmluZygpLmRlc2NyaWJlKFwi7IOd7ISx7ZWgIOyXlO2LsO2LsCBJRFwiKSxcbiAgICAgICAgICAgICAgICBpZDogei5udW1iZXIoKS5kZXNjcmliZShcIuyDiCDroIjsvZTrk5zsnZggSUQgKOydjOyImCDqtozsnqUsIOyYiDogLTEsIC0yKVwiKSxcbiAgICAgICAgICAgICAgICBjb2x1bW5zOiB6XG4gICAgICAgICAgICAgICAgICAucmVjb3JkKHouc3RyaW5nKCksIHoudW5rbm93bigpKVxuICAgICAgICAgICAgICAgICAgLmRlc2NyaWJlKFwi7Lus65+866qF7J2EIO2CpOuhnCwg6rCS7J2EIOqwkuycvOuhnCDtlZjripQg6rCd7LK0XCIpLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgfSksXG4gICAgICAgICAgZXhlY3V0ZTogYXN5bmMgKHtcbiAgICAgICAgICAgIGZpeHR1cmVzLFxuICAgICAgICAgIH06IHtcbiAgICAgICAgICAgIGZpeHR1cmVzOiBBcnJheTx7IGVudGl0eUlkOiBzdHJpbmc7IGlkOiBudW1iZXI7IGNvbHVtbnM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IH0+O1xuICAgICAgICAgIH0pOiBQcm9taXNlPHsgc3VjY2VzczogYm9vbGVhbjsgdXBkYXRlZFJlY29yZHM6IEZpeHR1cmVSZWNvcmRbXSB9PiA9PiB7XG4gICAgICAgICAgICBjb25zdCBuZXdSZWNvcmRzOiBGaXh0dXJlUmVjb3JkW10gPSBmaXh0dXJlcy5tYXAoXG4gICAgICAgICAgICAgIChmaXh0dXJlOiB7IGVudGl0eUlkOiBzdHJpbmc7IGlkOiBudW1iZXI7IGNvbHVtbnM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IH0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChmaXh0dXJlLmVudGl0eUlkKTtcblxuICAgICAgICAgICAgICAgIC8vIOyXlO2LsO2LsCBwcm9wc+ulvCDquLDrsJjsnLzroZwgY29sdW1ucyDqtazshLFcbiAgICAgICAgICAgICAgICBjb25zdCBjb2x1bW5zOiBGaXh0dXJlUmVjb3JkW1wiY29sdW1uc1wiXSA9IHt9O1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcHJvcCBvZiBlbnRpdHkucHJvcHMpIHtcbiAgICAgICAgICAgICAgICAgIGlmIChwcm9wLnR5cGUgPT09IFwidmlydHVhbFwiKSBjb250aW51ZTtcblxuICAgICAgICAgICAgICAgICAgbGV0IHZhbHVlID0gZml4dHVyZS5jb2x1bW5zW3Byb3AubmFtZV0gPz8gbnVsbDtcblxuICAgICAgICAgICAgICAgICAgaWYgKHByb3AubmFtZSA9PT0gXCJjcmVhdGVkX2F0XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g7ZiE7J6sIOyLnOqwhOycvOuhnCDshKTsoJVcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICAgICAgICBwcm9wLnR5cGUgPT09IFwicmVsYXRpb25cIiAmJlxuICAgICAgICAgICAgICAgICAgICAocHJvcC5yZWxhdGlvblR5cGUgPT09IFwiSGFzTWFueVwiIHx8IHByb3AucmVsYXRpb25UeXBlID09PSBcIk1hbnlUb01hbnlcIilcbiAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAvLyDrsLDsl7TroZwg67OA7ZmYXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZSA6IFt2YWx1ZV0uZmlsdGVyKG5vbk51bGxhYmxlKTtcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgY29sdW1uc1twcm9wLm5hbWVdID0ge1xuICAgICAgICAgICAgICAgICAgICBwcm9wLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWUgYXMgRml4dHVyZVJlY29yZFtcImNvbHVtbnNcIl1bc3RyaW5nXVtcInZhbHVlXCJdLFxuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgZml4dHVyZUlkOiBgJHtmaXh0dXJlLmVudGl0eUlkfSMke2ZpeHR1cmUuaWR9YCxcbiAgICAgICAgICAgICAgICAgIGVudGl0eUlkOiBmaXh0dXJlLmVudGl0eUlkLFxuICAgICAgICAgICAgICAgICAgaWQ6IGZpeHR1cmUuaWQsXG4gICAgICAgICAgICAgICAgICBjb2x1bW5zLFxuICAgICAgICAgICAgICAgICAgZmV0Y2hlZFJlY29yZHM6IFtdLFxuICAgICAgICAgICAgICAgICAgYmVsb25nc1JlY29yZHM6IFtdLFxuICAgICAgICAgICAgICAgICAgb3ZlcnJpZGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAvLyDsg4gg66CI7L2U65Oc65Ok7J2YIHJlbGF0aW9uIOy7rOufvOydhCDtmZXsnbjtlZjsl6wg6riw7KG0IOugiOy9lOuTnOuTpOydmCDsl63rsKntlqUgcmVsYXRpb24g7JeF642w7J207Yq4XG4gICAgICAgICAgICBmb3IgKGNvbnN0IG5ld1JlY29yZCBvZiBuZXdSZWNvcmRzKSB7XG4gICAgICAgICAgICAgIGZvciAoY29uc3QgW19jb2xOYW1lLCBjb2xdIG9mIE9iamVjdC5lbnRyaWVzKG5ld1JlY29yZC5jb2x1bW5zKSkge1xuICAgICAgICAgICAgICAgIGlmIChjb2wucHJvcC50eXBlICE9PSBcInJlbGF0aW9uXCIgfHwgY29sLnZhbHVlID09PSBudWxsKSBjb250aW51ZTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHJlbGF0ZWRFbnRpdHlJZCA9IGNvbC5wcm9wLndpdGg7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVsYXRlZElkcyA9IEFycmF5LmlzQXJyYXkoY29sLnZhbHVlKSA/IGNvbC52YWx1ZSA6IFtjb2wudmFsdWVdO1xuXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCByZWxhdGVkSWQgb2YgcmVsYXRlZElkcykge1xuICAgICAgICAgICAgICAgICAgY29uc3QgcmVsYXRlZEZpeHR1cmVJZCA9IGAke3JlbGF0ZWRFbnRpdHlJZH0jJHtyZWxhdGVkSWR9YDtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHJlbGF0ZWRSZWNvcmQgPSBuZXdSZWNvcmRzLmZpbmQoKHIpID0+IHIuZml4dHVyZUlkID09PSByZWxhdGVkRml4dHVyZUlkKTtcblxuICAgICAgICAgICAgICAgICAgaWYgKHJlbGF0ZWRSZWNvcmQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g7Jet67Cp7ZalIHJlbGF0aW9uIOywvuq4sFxuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXZlcnNlQ29sID0gT2JqZWN0LmVudHJpZXMocmVsYXRlZFJlY29yZC5jb2x1bW5zKS5maW5kKFxuICAgICAgICAgICAgICAgICAgICAgIChbLCBjXSkgPT4gYy5wcm9wLnR5cGUgPT09IFwicmVsYXRpb25cIiAmJiBjLnByb3Aud2l0aCA9PT0gbmV3UmVjb3JkLmVudGl0eUlkLFxuICAgICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXZlcnNlQ29sKSB7XG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgW3JldmVyc2VDb2xOYW1lLCByZXZlcnNlQ29sVmFsdWVdID0gcmV2ZXJzZUNvbDtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50VmFsdWUgPSByZXZlcnNlQ29sVmFsdWUudmFsdWU7XG5cbiAgICAgICAgICAgICAgICAgICAgICAvLyDsl63rsKntlqXsnbQg67Cw7Je07J24IOqyveyasCAoSGFzTWFueSwgTWFueVRvTWFueSlcbiAgICAgICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgICAgICByZXZlcnNlQ29sVmFsdWUucHJvcC50eXBlID09PSBcInJlbGF0aW9uXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChyZXZlcnNlQ29sVmFsdWUucHJvcC5yZWxhdGlvblR5cGUgPT09IFwiSGFzTWFueVwiIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJldmVyc2VDb2xWYWx1ZS5wcm9wLnJlbGF0aW9uVHlwZSA9PT0gXCJNYW55VG9NYW55XCIpXG4gICAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnQoQXJyYXkuaXNBcnJheShjdXJyZW50VmFsdWUpLCBcImN1cnJlbnRWYWx1ZSBtdXN0IGJlIGFuIGFycmF5XCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjdXJyZW50VmFsdWUuaW5jbHVkZXMobmV3UmVjb3JkLmlkKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZWxhdGVkUmVjb3JkLmNvbHVtbnNbcmV2ZXJzZUNvbE5hbWVdID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnJldmVyc2VDb2xWYWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogWy4uLmN1cnJlbnRWYWx1ZSwgbmV3UmVjb3JkLmlkXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8g7Jet67Cp7Zal7J20IOuLqOydvCDqsJLsnbgg6rK97JqwIChCZWxvbmdzVG9PbmUsIE9uZVRvT25lKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVsYXRlZFJlY29yZC5jb2x1bW5zW3JldmVyc2VDb2xOYW1lXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucmV2ZXJzZUNvbFZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogbmV3UmVjb3JkLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSwgdXBkYXRlZFJlY29yZHM6IG5ld1JlY29yZHMgfTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBoYW5kbGVFbnRpdHkobWVzc2FnZXM6IE1vZGVsTWVzc2FnZVtdKTogU3RyZWFtVGV4dFJlc3VsdDxhbnksIGFueT4ge1xuICAgIGlmICghdGhpcy5haVNkayB8fCAhdGhpcy5tb2RlbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQUkgU0RLIG5vdCBpbml0aWFsaXplZC4gQ2FsbCBpbml0KCkgZmlyc3QuXCIpO1xuICAgIH1cblxuICAgIC8vIGVudGl0eS5pbnN0cnVjdGlvbnMubWQg7YyM7J28IOydveq4sCAoZGlzdC91aSDrmJDripQgc3JjL3Vp7JeQ7IScIOyLpO2WieuQmOuvgOuhnCDtjKjtgqTsp4Ag66Oo7Yq4IOq4sOykgOycvOuhnCDsoJHqt7wpXG4gICAgY29uc3QgaW5zdHJ1Y3Rpb25zUGF0aCA9IHBhdGguam9pbihcbiAgICAgIGltcG9ydC5tZXRhLmRpcm5hbWUsXG4gICAgICBcIi4uXCIsXG4gICAgICBcIi4uXCIsXG4gICAgICBcInNyY1wiLFxuICAgICAgXCJ1aVwiLFxuICAgICAgXCJlbnRpdHkuaW5zdHJ1Y3Rpb25zLm1kXCIsXG4gICAgKTtcbiAgICBjb25zdCBpbnN0cnVjdGlvbnMgPSBmcy5yZWFkRmlsZVN5bmMoaW5zdHJ1Y3Rpb25zUGF0aCwgXCJ1dGYtOFwiKTtcblxuICAgIC8vIO2YhOyerCDrk7HroZ3rkJwg7JeU7Yuw7YuwIOygleuztCDsiJjsp5FcbiAgICBjb25zdCBlbnRpdHlJZHMgPSBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpO1xuICAgIGNvbnN0IGV4aXN0aW5nRW50aXRpZXMgPSBlbnRpdHlJZHMubWFwKChlbnRpdHlJZCkgPT4ge1xuICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaWQ6IGVudGl0eS5pZCxcbiAgICAgICAgdGl0bGU6IGVudGl0eS50aXRsZSxcbiAgICAgICAgdGFibGU6IGVudGl0eS50YWJsZSxcbiAgICAgICAgcHJvcHM6IGVudGl0eS5wcm9wcy5tYXAoKHApID0+ICh7XG4gICAgICAgICAgbmFtZTogcC5uYW1lLFxuICAgICAgICAgIHR5cGU6IHAudHlwZSxcbiAgICAgICAgICBkZXNjOiBwLmRlc2MsXG4gICAgICAgIH0pKSxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICBjb25zdCBzeXN0ZW1NZXNzYWdlID0gYFxu64u57Iug7J2AIFNvbmFtdSDtlITroIjsnoTsm4ztgazsl5DshJwgRW50aXR57JmAIEVudW3snYQg7IOd7ISx7ZWY64qUIOuPhOyasOuvuOyeheuLiOuLpC5cblxuJHtpbnN0cnVjdGlvbnN9XG5cbiMjIO2YhOyerCDrk7HroZ3rkJwgRW50aXR5IOuqqeuhnVxu64uk66W4IOyXlO2LsO2LsOyZgCDqtIDqs4QocmVsYXRpb24p66W8IOunuuqxsOuCmCBzdWJzZXTsl5DshJwg7LC47KGw7ZWgIOuVjCDrsJjrk5zsi5wg7JWE656YIOygleuztOulvCDtmZXsnbjtlZjshLjsmpQuXG5cbiR7SlNPTi5zdHJpbmdpZnkoZXhpc3RpbmdFbnRpdGllcywgbnVsbCwgMil9XG5cbiMjIFRvb2wg7IKs7JqpIOqwgOydtOuTnFxuXG4jIyMgRW50aXR5IOyDneyEsSAoY3JlYXRlRW50aXR5KVxu7IKs7Jqp7J6Q6rCAIOyDiOuhnOyatCBFbnRpdHkg7IOd7ISx7J2EIOyalOyyre2VmOuptCBjcmVhdGVFbnRpdHkg64+E6rWs66W8IOyCrOyaqe2VmOyEuOyalC5cbi0gZW50aXR5SWQ6IFBhc2NhbENhc2XroZwg65CcIEVudGl0eSBJRCAo7JiIOiBcIlVzZXJcIiwgXCJQcm9kdWN0Q2F0ZWdvcnlcIilcbi0gdGl0bGU6IO2VnOq4gCDsoJzrqqkgKOyYiDogXCLsgqzsmqnsnpBcIiwgXCLsg4Htkogg7Lm07YWM6rOg66asXCIpXG4tIHRhYmxlOiBzbmFrZV9jYXNl66GcIOuQnCDthYzsnbTruJTrqoUgKOyYiDogXCJ1c2Vyc1wiLCBcInByb2R1Y3RfY2F0ZWdvcmllc1wiKVxuLSBwYXJlbnRJZDog67aA66qoIEVudGl0eSBJRCAo7ISg7YOd7IKs7ZWtKVxuLSBwcm9wczogRW50aXR57J2YIO2UhOuhnO2NvO2LsCDrsLDsl7QgKOychCDrrLjshJzsnZggUHJvcGVydHkgVHlwZXMg7LC46rOgKVxuLSBpbmRleGVzOiDsnbjrjbHsiqQg67Cw7Je0XG4tIHN1YnNldHM6IOyEnOu4jOyFiyDsoJXsnZggKOq4sOuzuOqwkjogeyBBOiBbXCJpZFwiXSB9KVxuLSBlbnVtczogRW51bSDsoJXsnZhcblxuIyMjIEVudGl0eSDsiJjsoJUgKHVwZGF0ZUVudGl0eSlcbuq4sOyhtCBFbnRpdHnrpbwg7IiY7KCV7ZWgIOuVjCB1cGRhdGVFbnRpdHkg64+E6rWs66W8IOyCrOyaqe2VmOyEuOyalC4gRW51bSDstpTqsIAsIHByb3BzIOy2lOqwgC/siJjsoJUsIGluZGV4ZXMg7IiY7KCVIOuTsSDrqqjrk6Ag7IiY7KCVIOyekeyXheyXkCDsgqzsmqntlanri4jri6QuXG4tIGVudGl0eUlkOiDsiJjsoJXtlaAgRW50aXR5IElEXG4tIHVwZGF0ZXM6IOyImOygle2VoCDtlYTrk5zrk6QgKOu2gOu2hCDsl4XrjbDsnbTtirgpXG4gIC0gdGl0bGU6IOyXlO2LsO2LsCDtlZzquIAg7KCc66qpXG4gIC0gdGFibGU6IO2FjOydtOu4lOuqhVxuICAtIHByb3BzOiDstpTqsIDtlaAg7ZSE66Gc7Y287YuwIOuwsOyXtCAo6riw7KG0IHByb3Bz7JeQIOy2lOqwgCwg6rCZ7J2AIOydtOumhOydtOuptCDqtZDssrQpXG4gIC0gaW5kZXhlczog7LaU6rCA7ZWgIOyduOuNseyKpCDrsLDsl7QgKOq4sOyhtCBpbmRleGVz7JeQIOy2lOqwgClcbiAgLSBzdWJzZXRzOiDshJzruIzshYsg7KCV7J2YICjquLDsobQgc3Vic2V0c+yXkCDrs5HtlakpXG4gIC0gZW51bUxhYmVsczogRW51bSDsoJXsnZggKOq4sOyhtCBlbnVtTGFiZWxz7JeQIOuzke2VqSlcbi0gbW9kZTogXCJtZXJnZVwiKOq4sOuzuOqwkikg65iQ64qUIFwicmVwbGFjZVwiXG4gIC0gbWVyZ2U6IOq4sOyhtCDqsJLsl5Ag67OR7ZWpXG4gIC0gcmVwbGFjZTog7ZW064u5IO2VhOuTnCDsoITssrQg6rWQ7LK0XG5cbuyYiOyLnDogRW1wbG95ZWXsl5Ag7IOIIEVudW0g7LaU6rCAXG51cGRhdGVFbnRpdHkoeyBlbnRpdHlJZDogXCJFbXBsb3llZVwiLCB1cGRhdGVzOiB7IGVudW1MYWJlbHM6IHsgXCJFbXBsb3llZVJvbGVcIjogeyBcImFkbWluXCI6IFwi6rSA66as7J6QXCIsIFwidXNlclwiOiBcIuydvOuwmFwiIH0gfSB9IH0pXG5cbuyYiOyLnDogUHJvamVjdOyXkCDsg4gg7ZSE66Gc7Y287YuwIOy2lOqwgFxudXBkYXRlRW50aXR5KHsgZW50aXR5SWQ6IFwiUHJvamVjdFwiLCB1cGRhdGVzOiB7IHByb3BzOiBbeyBuYW1lOiBcInByaW9yaXR5XCIsIHR5cGU6IFwiaW50ZWdlclwiLCBkZXNjOiBcIuyasOyEoOyInOychFwiIH1dIH0gfSlcblxuIyMg7ZWE7IiYIOyCrO2VrVxuLSBFbnRpdHnsnZggcHJvcHPsl5DripQg7LWc7IaM7ZWcIGlkKGludGVnZXIsIHVuc2lnbmVkKSwgY3JlYXRlZF9hdCh0aW1lc3RhbXAp6rCAIO2PrO2VqOuQmOyWtOyVvCDtlanri4jri6QuXG4tIHJlbGF0aW9uIO2VhOuTnOuKlCBvblVwZGF0ZSwgb25EZWxldGXqsIAg7ZWE7IiY7J6F64uI64ukLiAo7JiI7Jm4OiBPbmVUb09uZeyXkOyEnCBoYXNKb2luQ29sdW1u7J20IGZhbHNl7J24IOqyveyasClcbi0gRW51bSBJROuKlCDrs7TthrUgRW50aXR5SWQgKyDsho3shLHrqoUg7ZiV7YOc7J6F64uI64ukICjsmIg6IFVzZXJTdGF0dXMsIFByb2R1Y3RUeXBlKVxuLSBzdWJzZXTsl5DshJwg64uk66W4IOyXlO2LsO2LsOydmCDtlITroZztjbzti7Drpbwg7LC47KGw7ZWgIOuVjOuKlCDrsJjrk5zsi5wg7ZW064u5IOyXlO2LsO2LsOydmCDsi6TsoJwg7ZSE66Gc7Y287Yuw66qF7J2EIOyCrOyaqe2VmOyEuOyalC5cblxuIyMg6rKA7KadIOyYpOulmCDsspjrpqxcbuuPhOq1rCDtmLjstpwg6rKw6rO866GcIOqygOymnSDsmKTrpZgodmFsaWRhdGlvbkVycm9ycynqsIAg67CY7ZmY65CY66m0OlxuMS4g7Jik66WYIOuplOyLnOyngOulvCDrtoTshJ3tlZjsl6wg66y47KCc7KCQ7J2EIO2MjOyVhe2VmOyEuOyalC5cbjIuIOyYpOulmOulvCDsiJjsoJXtlZwg642w7J207YSw66GcIGNyZWF0ZUVudGl0eeulvCDri6Tsi5wg7Zi47Lac7ZWY7IS47JqULlxuMy4g7IKs7Jqp7J6Q7JeQ6rKMIOyYpOulmOulvCDqt7jrjIDroZwg7KCE64us7ZWY7KeAIOunkOqzoCwg7IiY7KCVIO2bhCDsnqzsi5zrj4TtlZjshLjsmpQuXG5cbiMjIyDsnbzrsJjsoIHsnbgg6rKA7KadIOyYpOulmOyZgCDsiJjsoJUg67Cp67KVXG58IOyYpOulmCDrqZTsi5zsp4AgfCDsiJjsoJUg67Cp67KVIHxcbnwtLS0tLS0tLS0tLS18LS0tLS0tLS0tLXxcbnwgXCJpZCDtlITroZztjbzti7DqsIAg7ZWE7IiYXCIgfCBwcm9wc+yXkCB7IG5hbWU6IFwiaWRcIiwgdHlwZTogXCJpbnRlZ2VyXCIsIHVuc2lnbmVkOiB0cnVlIH0g7LaU6rCAIHxcbnwgXCJjcmVhdGVkX2F0IO2UhOuhnO2NvO2LsOqwgCDtlYTsiJhcIiB8IHByb3Bz7JeQIHsgbmFtZTogXCJjcmVhdGVkX2F0XCIsIHR5cGU6IFwidGltZXN0YW1wXCIsIGRiRGVmYXVsdDogXCJDVVJSRU5UX1RJTUVTVEFNUFwiIH0g7LaU6rCAIHxcbnwgXCJYeHhPcmRlckJ5IGVudW3snbQg7ZWE7IiYXCIgfCBlbnVtc+yXkCB7IFwiWHh4T3JkZXJCeVwiOiB7IFwiaWQtZGVzY1wiOiBcIklE7LWc7Iug7IicXCIgfSB9IOy2lOqwgCB8XG58IFwiWHh4U2VhcmNoRmllbGQgZW51beydtCDtlYTsiJhcIiB8IGVudW1z7JeQIHsgXCJYeHhTZWFyY2hGaWVsZFwiOiB7IFwiaWRcIjogXCJJRFwiIH0gfSDstpTqsIAgfFxufCBcInN0cmluZyDtg4DsnoXsnYAgbGVuZ3Ro6rCAIO2VhOyImFwiIHwg7ZW064u5IHByb3Dsl5AgbGVuZ3RoIOy2lOqwgCAo7JiIOiAyNTUpIHxcbnwgXCJ0ZXh0IO2DgOyeheydgCB0ZXh0VHlwZeydtCDtlYTsiJhcIiB8IO2VtOuLuSBwcm9w7JeQIHRleHRUeXBlIOy2lOqwgCAoXCJ0ZXh0XCIsIFwibWVkaXVtdGV4dFwiLCBcImxvbmd0ZXh0XCIpIHxcbnwgXCJvblVwZGF0ZeqwgCDtlYTsiJhcIiB8IO2VtOuLuSByZWxhdGlvbiBwcm9w7JeQIG9uVXBkYXRlLCBvbkRlbGV0ZSDstpTqsIAgKFwiQ0FTQ0FERVwiKSB8XG4gICAgICBgO1xuXG4gICAgY29uc3QgeyBzdHJlYW1UZXh0LCB0b29sLCBzdGVwQ291bnRJcyB9ID0gdGhpcy5haVNkaztcblxuICAgIHJldHVybiBzdHJlYW1UZXh0KHtcbiAgICAgIG1vZGVsOiB0aGlzLm1vZGVsIGFzIHVua25vd24gYXMgTGFuZ3VhZ2VNb2RlbCxcbiAgICAgIHN5c3RlbTogc3lzdGVtTWVzc2FnZSxcbiAgICAgIG1lc3NhZ2VzLFxuICAgICAgc3RvcFdoZW46IHN0ZXBDb3VudElzKDIpLFxuICAgICAgdG9vbHM6IHtcbiAgICAgICAgY3JlYXRlRW50aXR5OiB0b29sKHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwi7IOI66Gc7Jq0IEVudGl0eeulvCDsg53shLHtlanri4jri6QuIOyCrOyaqeyekOqwgCDsg4jroZzsmrQg7JeU7Yuw7Yuw64KYIO2FjOydtOu4lCDsg53shLHsnYQg7JqU7LKt7ZWgIOuVjCDsgqzsmqntlZjshLjsmpQuXCIsXG4gICAgICAgICAgaW5wdXRTY2hlbWE6IFRlbXBsYXRlT3B0aW9ucy5zaGFwZS5lbnRpdHksXG4gICAgICAgICAgZXhlY3V0ZTogYXN5bmMgKFxuICAgICAgICAgICAgZW50aXR5OiB6LmluZmVyPHR5cGVvZiBUZW1wbGF0ZU9wdGlvbnMuc2hhcGUuZW50aXR5PixcbiAgICAgICAgICApOiBQcm9taXNlPHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGJvb2xlYW47XG4gICAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgICAgZXJyb3I/OiBzdHJpbmc7XG4gICAgICAgICAgICB2YWxpZGF0aW9uRXJyb3JzPzogVmFsaWRhdGlvbkVycm9yW107XG4gICAgICAgICAgfT4gPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgLy8g7J6F66ClIOqygOymnVxuICAgICAgICAgICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGVFbnRpdHlKc29uKGVudGl0eSk7XG5cbiAgICAgICAgICAgICAgaWYgKHZhbGlkYXRpb25FcnJvcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgIGVudGl0eUlkOiBlbnRpdHkuZW50aXR5SWQsXG4gICAgICAgICAgICAgICAgICBlcnJvcjogYOqygOymnSDsmKTrpZg6ICR7dmFsaWRhdGlvbkVycm9ycy5tYXAoKGUpID0+IGBbJHtlLmZpZWxkfV0gJHtlLm1lc3NhZ2V9YCkuam9pbihcIiwgXCIpfWAsXG4gICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBhd2FpdCBTb25hbXUuc3luY2VyLmNyZWF0ZUVudGl0eSh7XG4gICAgICAgICAgICAgICAgc3Vic2V0czogeyBBOiBbXCJpZFwiXSB9LFxuICAgICAgICAgICAgICAgIGVudW1zOiB7fSxcbiAgICAgICAgICAgICAgICAuLi5lbnRpdHksXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIC8vIEVudGl0eU1hbmFnZXIg66as66Gc65OcXG4gICAgICAgICAgICAgIGF3YWl0IEVudGl0eU1hbmFnZXIucmVsb2FkKCk7XG5cbiAgICAgICAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSwgZW50aXR5SWQ6IGVudGl0eS5lbnRpdHlJZCB9O1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IGUgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFwiVW5rbm93biBlcnJvclwiO1xuICAgICAgICAgICAgICByZXR1cm4geyBzdWNjZXNzOiBmYWxzZSwgZW50aXR5SWQ6IGVudGl0eS5lbnRpdHlJZCwgZXJyb3IgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICAgdXBkYXRlRW50aXR5OiB0b29sKHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwi6riw7KG0IEVudGl0eeulvCDsiJjsoJXtlanri4jri6QuIEVudW0g7LaU6rCALCBwcm9wcyDstpTqsIAv7IiY7KCVLCBpbmRleGVzIOyImOyglSwgc3Vic2V0cyDsiJjsoJUg65OxIOuqqOuToCDsl5Tti7Dti7Ag7IiY7KCVIOyekeyXheyXkCDsgqzsmqntlZjshLjsmpQuXCIsXG4gICAgICAgICAgaW5wdXRTY2hlbWE6IHoub2JqZWN0KHtcbiAgICAgICAgICAgIGVudGl0eUlkOiB6LnN0cmluZygpLmRlc2NyaWJlKFwi7IiY7KCV7ZWgIEVudGl0eSBJRFwiKSxcbiAgICAgICAgICAgIHVwZGF0ZXM6IFRlbXBsYXRlT3B0aW9ucy5zaGFwZS5lbnRpdHkucGFydGlhbCgpLmRlc2NyaWJlKFwi7IiY7KCV7ZWgIO2VhOuTnOuTpFwiKSxcbiAgICAgICAgICAgIG1vZGU6IHpcbiAgICAgICAgICAgICAgLmVudW0oW1wibWVyZ2VcIiwgXCJyZXBsYWNlXCJdKVxuICAgICAgICAgICAgICAub3B0aW9uYWwoKVxuICAgICAgICAgICAgICAuZGVzY3JpYmUoXCLsiJjsoJUg66qo65OcOiBtZXJnZSjquLDrs7jqsJIsIOq4sOyhtCDqsJLsl5Ag67OR7ZWpKSDrmJDripQgcmVwbGFjZSjsoITssrQg6rWQ7LK0KVwiKSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBleGVjdXRlOiBhc3luYyAoe1xuICAgICAgICAgICAgZW50aXR5SWQsXG4gICAgICAgICAgICB1cGRhdGVzLFxuICAgICAgICAgICAgbW9kZSA9IFwibWVyZ2VcIixcbiAgICAgICAgICB9OiB7XG4gICAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgICAgdXBkYXRlczogUGFydGlhbDx6LmluZmVyPHR5cGVvZiBUZW1wbGF0ZU9wdGlvbnMuc2hhcGUuZW50aXR5Pj47XG4gICAgICAgICAgICBtb2RlPzogXCJtZXJnZVwiIHwgXCJyZXBsYWNlXCI7XG4gICAgICAgICAgfSk6IFByb21pc2U8e1xuICAgICAgICAgICAgc3VjY2VzczogYm9vbGVhbjtcbiAgICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgICBlcnJvcj86IHN0cmluZztcbiAgICAgICAgICAgIHZhbGlkYXRpb25FcnJvcnM/OiBWYWxpZGF0aW9uRXJyb3JbXTtcbiAgICAgICAgICB9PiA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG5cbiAgICAgICAgICAgICAgLy8gVXBkYXRlIGJhc2ljIHByb3BlcnRpZXNcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZXMuZW50aXR5SWQgIT09IHVuZGVmaW5lZCkgZW50aXR5LmlkID0gdXBkYXRlcy5lbnRpdHlJZDtcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZXMucGFyZW50SWQgIT09IHVuZGVmaW5lZCkgZW50aXR5LnBhcmVudElkID0gdXBkYXRlcy5wYXJlbnRJZDtcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZXMudGl0bGUgIT09IHVuZGVmaW5lZCkgZW50aXR5LnRpdGxlID0gdXBkYXRlcy50aXRsZTtcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZXMudGFibGUgIT09IHVuZGVmaW5lZCkgZW50aXR5LnRhYmxlID0gdXBkYXRlcy50YWJsZTtcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZXMuY29uZSAhPT0gdW5kZWZpbmVkKSBlbnRpdHkuY29uZSA9IHVwZGF0ZXMuY29uZTtcblxuICAgICAgICAgICAgICAvLyBwcm9wczogbWVyZ2Ug7IucIOydtOumhCDquLDspIAg67OR7ZWpLCByZXBsYWNlIOyLnCDqtZDssrRcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZXMucHJvcHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGlmIChtb2RlID09PSBcInJlcGxhY2VcIikge1xuICAgICAgICAgICAgICAgICAgZW50aXR5LnByb3BzID0gdXBkYXRlcy5wcm9wcyBhcyBFbnRpdHlQcm9wW107XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgbmV3UHJvcCBvZiB1cGRhdGVzLnByb3BzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nSW5kZXggPSBlbnRpdHkucHJvcHMuZmluZEluZGV4KChwKSA9PiBwLm5hbWUgPT09IG5ld1Byb3AubmFtZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChleGlzdGluZ0luZGV4ID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICBlbnRpdHkucHJvcHNbZXhpc3RpbmdJbmRleF0gPSBuZXdQcm9wIGFzIEVudGl0eVByb3A7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgZW50aXR5LnByb3BzLnB1c2gobmV3UHJvcCBhcyBFbnRpdHlQcm9wKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIGluZGV4ZXM6IG1lcmdlIOyLnCDstpTqsIAsIHJlcGxhY2Ug7IucIOq1kOyytFxuICAgICAgICAgICAgICBpZiAodXBkYXRlcy5pbmRleGVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBlbnRpdHkuaW5kZXhlcyA9XG4gICAgICAgICAgICAgICAgICBtb2RlID09PSBcInJlcGxhY2VcIiA/IHVwZGF0ZXMuaW5kZXhlcyA6IFsuLi5lbnRpdHkuaW5kZXhlcywgLi4udXBkYXRlcy5pbmRleGVzXTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIHN1YnNldHMsIHN1YnNldHNJbnRlcm5hbDogYXNzaWdu7Jy866GcIOuzke2VqSDrmJDripQg6rWQ7LK0XG4gICAgICAgICAgICAgIGlmICh1cGRhdGVzLnN1YnNldHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIC8vIE5vcm1hbGl6ZSBzdWJzZXQgZmllbGRzOiBzZXBhcmF0ZSBpbnRvIHN1YnNldHMgKG5vcm1hbCkgYW5kIHN1YnNldHNJbnRlcm5hbCAoaW50ZXJuYWwpXG4gICAgICAgICAgICAgICAgY29uc3Qgbm9ybWFsaXplZFN1YnNldHM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nW10gfSA9IHt9O1xuICAgICAgICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRTdWJzZXRzSW50ZXJuYWw6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nW10gfSA9IHt9O1xuXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBba2V5LCBmaWVsZHNdIG9mIE9iamVjdC5lbnRyaWVzKHVwZGF0ZXMuc3Vic2V0cykpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGZpZWxkQXJyYXkgPSBmaWVsZHMgYXMgc3RyaW5nW107XG4gICAgICAgICAgICAgICAgICBub3JtYWxpemVkU3Vic2V0c1trZXldID0gZmllbGRBcnJheVxuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKChmOiBzdHJpbmcpID0+ICFpc0ludGVybmFsU3Vic2V0RmllbGQoZikpXG4gICAgICAgICAgICAgICAgICAgIC5tYXAobm9ybWFsaXplU3Vic2V0RmllbGQpO1xuICAgICAgICAgICAgICAgICAgbm9ybWFsaXplZFN1YnNldHNJbnRlcm5hbFtrZXldID0gZmllbGRBcnJheVxuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKGlzSW50ZXJuYWxTdWJzZXRGaWVsZClcbiAgICAgICAgICAgICAgICAgICAgLm1hcChub3JtYWxpemVTdWJzZXRGaWVsZCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZW50aXR5LnN1YnNldHMgPVxuICAgICAgICAgICAgICAgICAgbW9kZSA9PT0gXCJyZXBsYWNlXCJcbiAgICAgICAgICAgICAgICAgICAgPyBub3JtYWxpemVkU3Vic2V0c1xuICAgICAgICAgICAgICAgICAgICA6IHsgLi4uZW50aXR5LnN1YnNldHMsIC4uLm5vcm1hbGl6ZWRTdWJzZXRzIH07XG4gICAgICAgICAgICAgICAgZW50aXR5LnN1YnNldHNJbnRlcm5hbCA9XG4gICAgICAgICAgICAgICAgICBtb2RlID09PSBcInJlcGxhY2VcIlxuICAgICAgICAgICAgICAgICAgICA/IG5vcm1hbGl6ZWRTdWJzZXRzSW50ZXJuYWxcbiAgICAgICAgICAgICAgICAgICAgOiB7IC4uLmVudGl0eS5zdWJzZXRzSW50ZXJuYWwsIC4uLm5vcm1hbGl6ZWRTdWJzZXRzSW50ZXJuYWwgfTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmICh1cGRhdGVzLmVudW1zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb252ZXJ0ZWRFbnVtcyA9IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgICAgICAgICAgICAgIE9iamVjdC5lbnRyaWVzKHVwZGF0ZXMuZW51bXMpLm1hcCgoW2tleSwgZW51bURlZl0pID0+IFtcbiAgICAgICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgICAgICBnZXRFbnVtRGVmVmFsdWVzKGVudW1EZWYpLFxuICAgICAgICAgICAgICAgICAgXSksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBlbnRpdHkuZW51bUxhYmVscyA9XG4gICAgICAgICAgICAgICAgICBtb2RlID09PSBcInJlcGxhY2VcIiA/IGNvbnZlcnRlZEVudW1zIDogeyAuLi5lbnRpdHkuZW51bUxhYmVscywgLi4uY29udmVydGVkRW51bXMgfTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIOyggOyepSDsoIQg6rKA7KadXG4gICAgICAgICAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0ZUVudGl0eUpzb24oe1xuICAgICAgICAgICAgICAgIC4uLmVudGl0eSxcbiAgICAgICAgICAgICAgICBlbnRpdHlJZDogZW50aXR5LmlkLFxuICAgICAgICAgICAgICAgIGVudW1zOiBlbnRpdHkuZW51bUxhYmVscyxcbiAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgaWYgKHZhbGlkYXRpb25FcnJvcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgIGVudGl0eUlkLFxuICAgICAgICAgICAgICAgICAgZXJyb3I6IGDqsoDspp0g7Jik66WYOiAke3ZhbGlkYXRpb25FcnJvcnMubWFwKChlKSA9PiBgWyR7ZS5maWVsZH1dICR7ZS5tZXNzYWdlfWApLmpvaW4oXCIsIFwiKX1gLFxuICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgYXdhaXQgZW50aXR5LnNhdmUoKTtcblxuICAgICAgICAgICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCBlbnRpdHlJZCB9O1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IGUgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFwiVW5rbm93biBlcnJvclwiO1xuICAgICAgICAgICAgICByZXR1cm4geyBzdWNjZXNzOiBmYWxzZSwgZW50aXR5SWQsIGVycm9yIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogRW50aXR5IEpTT07snbQgZW50aXR5Lmluc3RydWN0aW9ucy5tZOydmCDqt5zsuZnsnYQg65Sw66W064qU7KeAIOqygOymne2VqeuLiOuLpC5cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVFbnRpdHlKc29uKGlucHV0OiBUZW1wbGF0ZU9wdGlvbnNbXCJlbnRpdHlcIl0pOiBWYWxpZGF0aW9uRXJyb3JbXSB7XG4gIGNvbnN0IGVycm9yczogVmFsaWRhdGlvbkVycm9yW10gPSBbXTtcbiAgY29uc3QgeyBlbnRpdHlJZCwgcHJvcHMsIGVudW1zIH0gPSBpbnB1dDtcblxuICAvLyAxLiBpZCwgY3JlYXRlZF9hdCBwcm9wIO2VhOyImFxuICBjb25zdCBoYXNJZFByb3AgPSBwcm9wcz8uc29tZSgocCkgPT4gcC5uYW1lID09PSBcImlkXCIpO1xuICBpZiAoIWhhc0lkUHJvcCkge1xuICAgIGVycm9ycy5wdXNoKHsgZmllbGQ6IFwicHJvcHNcIiwgbWVzc2FnZTogXCJpZCDtlITroZztjbzti7DqsIAg7ZWE7IiY7J6F64uI64ukLlwiIH0pO1xuICB9XG4gIGNvbnN0IGhhc0NyZWF0ZWRBdFByb3AgPSBwcm9wcz8uc29tZSgocCkgPT4gcC5uYW1lID09PSBcImNyZWF0ZWRfYXRcIik7XG4gIGlmICghaGFzQ3JlYXRlZEF0UHJvcCkge1xuICAgIGVycm9ycy5wdXNoKHsgZmllbGQ6IFwicHJvcHNcIiwgbWVzc2FnZTogXCJjcmVhdGVkX2F0IO2UhOuhnO2NvO2LsOqwgCDtlYTsiJjsnoXri4jri6QuXCIgfSk7XG4gIH1cblxuICAvLyAyLiDtlYTsiJggZW51bSDqsoDspp06IEVudGl0eU5hbWVPcmRlckJ5LCBFbnRpdHlOYW1lU2VhcmNoRmllbGRcbiAgY29uc3Qgb3JkZXJCeUVudW1JZCA9IGAke2VudGl0eUlkfU9yZGVyQnlgO1xuICBjb25zdCBzZWFyY2hGaWVsZEVudW1JZCA9IGAke2VudGl0eUlkfVNlYXJjaEZpZWxkYDtcblxuICBpZiAoIWVudW1zPy5bb3JkZXJCeUVudW1JZF0pIHtcbiAgICBlcnJvcnMucHVzaCh7XG4gICAgICBmaWVsZDogXCJlbnVtc1wiLFxuICAgICAgbWVzc2FnZTogYCR7b3JkZXJCeUVudW1JZH0gZW51beydtCDtlYTsiJjsnoXri4jri6QuICjsmIg6IHsgXCJpZC1kZXNjXCI6IFwiSUTstZzsi6DsiJxcIiB9KWAsXG4gICAgfSk7XG4gIH1cbiAgaWYgKCFlbnVtcz8uW3NlYXJjaEZpZWxkRW51bUlkXSkge1xuICAgIGVycm9ycy5wdXNoKHtcbiAgICAgIGZpZWxkOiBcImVudW1zXCIsXG4gICAgICBtZXNzYWdlOiBgJHtzZWFyY2hGaWVsZEVudW1JZH0gZW51beydtCDtlYTsiJjsnoXri4jri6QuICjsmIg6IHsgXCJpZFwiOiBcIklEXCIgfSlgLFxuICAgIH0pO1xuICB9XG5cbiAgLy8gMy4gZW51bSBwcm9w7J2YIGlk6rCAIGVudW1z7JeQIOygleydmOuQmOyWtCDsnojripTsp4Ag7ZmV7J24IChjcm9zcy1maWVsZCDqsoDspp0pXG4gIGZvciAoY29uc3QgcHJvcCBvZiBwcm9wcyA/PyBbXSkge1xuICAgIGlmIChwcm9wLnR5cGUgPT09IFwiZW51bVwiICYmICFlbnVtcz8uW3Byb3AuaWRdKSB7XG4gICAgICBlcnJvcnMucHVzaCh7XG4gICAgICAgIGZpZWxkOiBgcHJvcHMuJHtwcm9wLm5hbWV9YCxcbiAgICAgICAgbWVzc2FnZTogYGVudW0gaWQgXCIke3Byb3AuaWR9XCLqsIAgZW51bXPsl5Ag7KCV7J2Y65CY7Ja0IOyeiOyngCDslYrsirXri4jri6QuYCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlcnJvcnM7XG59XG5cbmV4cG9ydCBjb25zdCBhaUNsaWVudCA9IG5ldyBBSUNsaWVudCgpO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQW1oQkEsU0FBUyxtQkFBbUIsT0FBcUQ7Q0FDL0UsTUFBTUEsU0FBNEIsRUFBRTtDQUNwQyxNQUFNLEVBQUUsVUFBVSxPQUFPLFVBQVU7Q0FHbkMsTUFBTSxZQUFZLE9BQU8sTUFBTSxNQUFNLEVBQUUsU0FBUyxLQUFLO0FBQ3JELEtBQUksQ0FBQyxXQUFXO0FBQ2QsU0FBTyxLQUFLO0dBQUUsT0FBTztHQUFTLFNBQVM7R0FBbUIsQ0FBQzs7Q0FFN0QsTUFBTSxtQkFBbUIsT0FBTyxNQUFNLE1BQU0sRUFBRSxTQUFTLGFBQWE7QUFDcEUsS0FBSSxDQUFDLGtCQUFrQjtBQUNyQixTQUFPLEtBQUs7R0FBRSxPQUFPO0dBQVMsU0FBUztHQUEyQixDQUFDOztDQUlyRSxNQUFNLGdCQUFnQixHQUFHLFNBQVM7Q0FDbEMsTUFBTSxvQkFBb0IsR0FBRyxTQUFTO0FBRXRDLEtBQUksQ0FBQyxRQUFRLGdCQUFnQjtBQUMzQixTQUFPLEtBQUs7R0FDVixPQUFPO0dBQ1AsU0FBUyxHQUFHLGNBQWM7R0FDM0IsQ0FBQzs7QUFFSixLQUFJLENBQUMsUUFBUSxvQkFBb0I7QUFDL0IsU0FBTyxLQUFLO0dBQ1YsT0FBTztHQUNQLFNBQVMsR0FBRyxrQkFBa0I7R0FDL0IsQ0FBQzs7QUFJSixNQUFLLE1BQU0sUUFBUSxTQUFTLEVBQUUsRUFBRTtBQUM5QixNQUFJLEtBQUssU0FBUyxVQUFVLENBQUMsUUFBUSxLQUFLLEtBQUs7QUFDN0MsVUFBTyxLQUFLO0lBQ1YsT0FBTyxTQUFTLEtBQUs7SUFDckIsU0FBUyxZQUFZLEtBQUssR0FB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
398
+
399
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWktY2xpZW50LmpzIiwibmFtZXMiOlsieiJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91aS9haS1jbGllbnQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tIFwiYXNzZXJ0XCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG4vKiBveGxpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55ICovIC8vIEFJIFNES+ydmCDtg4DsnoXsnbQg66qF7ZmV7ZWY7KeAIOyViuyVhCBhbnnrpbwg7ZeI7Jqp7ZWoXG5pbXBvcnQgeyB0eXBlIExhbmd1YWdlTW9kZWwsIHR5cGUgTW9kZWxNZXNzYWdlLCB0eXBlIFN0cmVhbVRleHRSZXN1bHQgfSBmcm9tIFwiYWlcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5cbmltcG9ydCB7IFNvbmFtdSB9IGZyb20gXCIuLi9hcGkvc29uYW11XCI7XG5pbXBvcnQgeyBFbnRpdHlNYW5hZ2VyIH0gZnJvbSBcIi4uL2VudGl0eS9lbnRpdHktbWFuYWdlclwiO1xuaW1wb3J0IHtcbiAgZ2V0RW51bURlZlZhbHVlcyxcbiAgaXNJbnRlcm5hbFN1YnNldEZpZWxkLFxuICBub3JtYWxpemVTdWJzZXRGaWVsZCxcbiAgVGVtcGxhdGVPcHRpb25zLFxufSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IHR5cGUgRW50aXR5UHJvcCwgdHlwZSBGaXh0dXJlUmVjb3JkIH0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQgeyBub25OdWxsYWJsZSB9IGZyb20gXCIuLi91dGlscy91dGlsc1wiO1xuXG50eXBlIFZhbGlkYXRpb25FcnJvciA9IHtcbiAgZmllbGQ6IHN0cmluZztcbiAgbWVzc2FnZTogc3RyaW5nO1xufTtcblxuY2xhc3MgQUlDbGllbnQge1xuICBwcml2YXRlIG1vZGVsOiBMYW5ndWFnZU1vZGVsIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgYWlTZGs6XG4gICAgfCAodHlwZW9mIGltcG9ydChcImFpXCIpICYge1xuICAgICAgICBhbnRocm9waWM/OiB0eXBlb2YgaW1wb3J0KFwiQGFpLXNkay9hbnRocm9waWNcIikuYW50aHJvcGljO1xuICAgICAgfSlcbiAgICB8IG51bGwgPSBudWxsO1xuXG4gIGFzeW5jIGluaXQoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgYW50aHJvcGljIH0gPSBhd2FpdCBpbXBvcnQoXCJAYWktc2RrL2FudGhyb3BpY1wiKTtcbiAgICAgIGNvbnN0IGFpTW9kdWxlID0gYXdhaXQgaW1wb3J0KFwiYWlcIik7XG4gICAgICB0aGlzLmFpU2RrID0geyAuLi5haU1vZHVsZSwgYW50aHJvcGljIH07XG4gICAgICB0aGlzLm1vZGVsID0gYW50aHJvcGljKFwiY2xhdWRlLXNvbm5ldC00LTZcIik7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgXCJBSSBTREsgcGFja2FnZXMgbm90IGluc3RhbGxlZC4gSW5zdGFsbCBAYWktc2RrL2FudGhyb3BpYyBhbmQgYWkgdG8gdXNlIEFJIGZlYXR1cmVzLlwiLFxuICAgICAgKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIGhhbmRsZUZpeHR1cmUoXG4gICAgbWVzc2FnZXM6IE1vZGVsTWVzc2FnZVtdLFxuICAgIGZpeHR1cmVSZWNvcmRzOiBGaXh0dXJlUmVjb3JkW10sXG4gICk6IFN0cmVhbVRleHRSZXN1bHQ8YW55LCBhbnk+IHtcbiAgICBpZiAoIXRoaXMuYWlTZGsgfHwgIXRoaXMubW9kZWwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkFJIFNESyBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdCgpIGZpcnN0LlwiKTtcbiAgICB9XG5cbiAgICAvLyDtmITsnqwgZml4dHVyZVJlY29yZHPsl5DshJwg7IKs7Jqp65CcIOyXlO2LsO2LsOuTpOydmCDqtazsobAg7KCV67O0IOyImOynkVxuICAgIGNvbnN0IHVzZWRFbnRpdHlJZHMgPSBbLi4ubmV3IFNldChmaXh0dXJlUmVjb3Jkcy5tYXAoKHIpID0+IHIuZW50aXR5SWQpKV07XG4gICAgY29uc3QgZW50aXR5U3RydWN0dXJlcyA9IHVzZWRFbnRpdHlJZHMubWFwKChlbnRpdHlJZCkgPT4ge1xuICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBlbnRpdHlJZDogZW50aXR5LmlkLFxuICAgICAgICB0YWJsZTogZW50aXR5LnRhYmxlLFxuICAgICAgICBwcm9wczogZW50aXR5LnByb3BzLFxuICAgICAgICByZWxhdGlvbnM6IGVudGl0eS5yZWxhdGlvbnMsXG4gICAgICAgIGVudW1MYWJlbHM6IGVudGl0eS5lbnVtTGFiZWxzLFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHN5c3RlbU1lc3NhZ2UgPSBgXG4gICAgICAgIOuLueyLoOydgCDtlL3siqTss5Ag66CI7L2U65Oc66W8IOyImOygle2VmOqzoCDsg53shLHtlaAg7IiYIOyeiOuKlCDrj4TsmrDrr7jsnoXri4jri6QuXG5cbiAgICAgICAg7ZiE7J6sIO2UveyKpOyzkCDroIjsvZTrk5w6XG4gICAgICAgICR7SlNPTi5zdHJpbmdpZnkoZml4dHVyZVJlY29yZHMsIG51bGwsIDIpfVxuXG4gICAgICAgIOyXlO2LsO2LsCDqtazsobAg7KCV67O0OlxuICAgICAgICAke0pTT04uc3RyaW5naWZ5KGVudGl0eVN0cnVjdHVyZXMsIG51bGwsIDIpfVxuXG4gICAgICAgICMjIO2UveyKpOyzkCDsiJjsoJVcbiAgICAgICAg7IKs7Jqp7J6Q6rCAIO2UveyKpOyzkCDqsJIg7IiY7KCV7J2EIOyalOyyre2VmOuptCB1cGRhdGVGaXh0dXJlcyDrj4Tqtazrpbwg7IKs7Jqp7ZWY7JesIOuzgOqyveyCrO2VreydhCDsoIHsmqntlZjshLjsmpQuXG4gICAgICAgIC0gZml4dHVyZUlkOiDsiJjsoJXtlaAg7ZS97Iqk7LOQIElEICjtmJXsi506IFwiRW50aXR5SWQjaWRcIilcbiAgICAgICAgLSB1cGRhdGVzOiDsu6zrn7zrqoXsnYQg7YKk66GcLCDsg4gg6rCS7J2EIOqwkuycvOuhnCDtlZjripQg6rCd7LK0XG5cbiAgICAgICAg7JiI7IucOiBcIlVzZXIjMVwiIO2UveyKpOyzkOydmCBcIm5hbWVcIiDsu6zrn7zsnYQgXCLtmY3quLjrj5lcIuycvOuhnCDrs4Dqsr3tlZjroKTrqbQ6XG4gICAgICAgIHVwZGF0ZUZpeHR1cmVzKHsgdXBkYXRlczogW3sgZml4dHVyZUlkOiBcIlVzZXIjMVwiLCB1cGRhdGVzOiB7IG5hbWU6IFwi7ZmN6ri464+ZXCIgfSB9XSB9KVxuXG4gICAgICAgIOuzgOqyveuQoCDsu6zrn7zsnZggdHlwZeydtCByZWxhdGlvbuyduCDqsr3smrAsIOq0gOugqCDsl5Tti7Dti7Dsl5Drj4Qg67CY7JiB65CY7Ja07JW8IO2VoCDsu6zrn7zsnbQg7J6I64qU7KeAIO2ZleyduO2VmOyEuOyalC5cblxuICAgICAgICAjIyDtlL3siqTss5Ag7IOd7ISxXG4gICAgICAgIOyCrOyaqeyekOqwgCDsg4jroZzsmrQg7ZS97Iqk7LOQIOyDneyEseydhCDsmpTssq3tlZjrqbQgY3JlYXRlRml4dHVyZXMg64+E6rWs66W8IOyCrOyaqe2VmOyEuOyalC5cbiAgICAgICAgLSBlbnRpdHlJZDog7IOd7ISx7ZWgIOyXlO2LsO2LsCBJRFxuICAgICAgICAtIGlkOiDsg4gg66CI7L2U65Oc7J2YIElEICjquLDsobQg7ZS97Iqk7LOQ7JmAIOykkeuzteuQmOyngCDslYrripQg7J2M7IiYIOyCrOyaqSDqtozsnqUsIOyYiDogLTEsIC0yKVxuICAgICAgICAtIGNvbHVtbnM6IOy7rOufvOuqheydhCDtgqTroZwsIOqwkuydhCDqsJLsnLzroZwg7ZWY64qUIOqwneyytCAo7JeU7Yuw7YuwIOq1rOyhsCDssLjqs6ApXG5cbiAgICAgICAg7JiI7IucOiDsg4jroZzsmrQgVXNlciDtlL3siqTss5Drpbwg7IOd7ISx7ZWY66Ck66m0OlxuICAgICAgICBjcmVhdGVGaXh0dXJlcyh7IGZpeHR1cmVzOiBbeyBlbnRpdHlJZDogXCJVc2VyXCIsIGlkOiAtMSwgY29sdW1uczogeyBuYW1lOiBcIu2Zjeq4uOuPmVwiLCBlbWFpbDogXCJob25nQGV4YW1wbGUuY29tXCIgfSB9XSB9KVxuICAgICAgYDtcblxuICAgIGNvbnN0IHsgc3RyZWFtVGV4dCwgdG9vbCB9ID0gdGhpcy5haVNkaztcblxuICAgIHJldHVybiBzdHJlYW1UZXh0KHtcbiAgICAgIG1vZGVsOiB0aGlzLm1vZGVsLFxuICAgICAgc3lzdGVtOiBzeXN0ZW1NZXNzYWdlLFxuICAgICAgbWVzc2FnZXMsXG4gICAgICB0b29sczoge1xuICAgICAgICB1cGRhdGVGaXh0dXJlczogdG9vbCh7XG4gICAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgICBcIu2UveyKpOyzkCDroIjsvZTrk5zsnZgg6rCS7J2EIOyImOygle2VqeuLiOuLpC4g7IKs7Jqp7J6Q6rCAIO2KueyglSDsu6zrn7zsnbTrgpgg6rCS7J2EIOuzgOqyve2VtOuLrOudvOqzoCDsmpTssq3tlaAg65WMIOyCrOyaqe2VmOyEuOyalC5cIixcbiAgICAgICAgICBpbnB1dFNjaGVtYTogei5vYmplY3Qoe1xuICAgICAgICAgICAgdXBkYXRlczogei5hcnJheShcbiAgICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICAgIGZpeHR1cmVJZDogei5zdHJpbmcoKS5kZXNjcmliZShcIuyImOygle2VoCDtlL3siqTss5AgSUQgKO2YleyLnTogRW50aXR5SWQjaWQpXCIpLFxuICAgICAgICAgICAgICAgIHVwZGF0ZXM6IHpcbiAgICAgICAgICAgICAgICAgIC5yZWNvcmQoei5zdHJpbmcoKSwgei51bmtub3duKCkpXG4gICAgICAgICAgICAgICAgICAuZGVzY3JpYmUoXCLsu6zrn7zrqoXsnYQg7YKk66GcLCDsg4gg6rCS7J2EIOqwkuycvOuhnCDtlZjripQg6rCd7LK0XCIpLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgfSksXG4gICAgICAgICAgZXhlY3V0ZTogYXN5bmMgKHtcbiAgICAgICAgICAgIHVwZGF0ZXMsXG4gICAgICAgICAgfToge1xuICAgICAgICAgICAgdXBkYXRlczogQXJyYXk8eyBmaXh0dXJlSWQ6IHN0cmluZzsgdXBkYXRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfT47XG4gICAgICAgICAgfSk6IFByb21pc2U8eyBzdWNjZXNzOiBib29sZWFuOyB1cGRhdGVkUmVjb3JkczogRml4dHVyZVJlY29yZFtdIH0+ID0+IHtcbiAgICAgICAgICAgIC8vIGZpeHR1cmVSZWNvcmRz66W8IOuzteyCrO2VmOqzoCDsl4XrjbDsnbTtirgg7KCB7JqpXG4gICAgICAgICAgICBjb25zdCB1cGRhdGVkUmVjb3JkczogRml4dHVyZVJlY29yZFtdID0gZml4dHVyZVJlY29yZHMubWFwKChyZWNvcmQpID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgdXBkYXRlID0gdXBkYXRlcy5maW5kKFxuICAgICAgICAgICAgICAgICh1OiB7IGZpeHR1cmVJZDogc3RyaW5nIH0pID0+IHUuZml4dHVyZUlkID09PSByZWNvcmQuZml4dHVyZUlkLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICBpZiAodXBkYXRlKSB7XG4gICAgICAgICAgICAgICAgLy8gY29sdW1uc+ydmCB2YWx1ZeulvCDsl4XrjbDsnbTtirhcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IFtjb2x1bW5OYW1lLCBuZXdWYWx1ZV0gb2YgT2JqZWN0LmVudHJpZXModXBkYXRlLnVwZGF0ZXMpKSB7XG4gICAgICAgICAgICAgICAgICByZWNvcmQuY29sdW1uc1tjb2x1bW5OYW1lXS52YWx1ZSA9XG4gICAgICAgICAgICAgICAgICAgIG5ld1ZhbHVlIGFzIEZpeHR1cmVSZWNvcmRbXCJjb2x1bW5zXCJdW3N0cmluZ11bXCJ2YWx1ZVwiXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlY29yZDtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHJldHVybiByZWNvcmQ7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSwgdXBkYXRlZFJlY29yZHMgfTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICAgY3JlYXRlRml4dHVyZXM6IHRvb2woe1xuICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgXCLsg4jroZzsmrQg7ZS97Iqk7LOQIOugiOy9lOuTnOulvCDsg53shLHtlanri4jri6QuIOyCrOyaqeyekOqwgCDsg4jroZzsmrQg642w7J207YSw66W8IOy2lOqwgO2VtOuLrOudvOqzoCDsmpTssq3tlaAg65WMIOyCrOyaqe2VmOyEuOyalC5cIixcbiAgICAgICAgICBpbnB1dFNjaGVtYTogei5vYmplY3Qoe1xuICAgICAgICAgICAgZml4dHVyZXM6IHouYXJyYXkoXG4gICAgICAgICAgICAgIHoub2JqZWN0KHtcbiAgICAgICAgICAgICAgICBlbnRpdHlJZDogei5zdHJpbmcoKS5kZXNjcmliZShcIuyDneyEse2VoCDsl5Tti7Dti7AgSURcIiksXG4gICAgICAgICAgICAgICAgaWQ6IHoubnVtYmVyKCkuZGVzY3JpYmUoXCLsg4gg66CI7L2U65Oc7J2YIElEICjsnYzsiJgg6raM7J6lLCDsmIg6IC0xLCAtMilcIiksXG4gICAgICAgICAgICAgICAgY29sdW1uczogelxuICAgICAgICAgICAgICAgICAgLnJlY29yZCh6LnN0cmluZygpLCB6LnVua25vd24oKSlcbiAgICAgICAgICAgICAgICAgIC5kZXNjcmliZShcIuy7rOufvOuqheydhCDtgqTroZwsIOqwkuydhCDqsJLsnLzroZwg7ZWY64qUIOqwneyytFwiKSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApLFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIGV4ZWN1dGU6IGFzeW5jICh7XG4gICAgICAgICAgICBmaXh0dXJlcyxcbiAgICAgICAgICB9OiB7XG4gICAgICAgICAgICBmaXh0dXJlczogQXJyYXk8eyBlbnRpdHlJZDogc3RyaW5nOyBpZDogbnVtYmVyOyBjb2x1bW5zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB9PjtcbiAgICAgICAgICB9KTogUHJvbWlzZTx7IHN1Y2Nlc3M6IGJvb2xlYW47IHVwZGF0ZWRSZWNvcmRzOiBGaXh0dXJlUmVjb3JkW10gfT4gPT4ge1xuICAgICAgICAgICAgY29uc3QgbmV3UmVjb3JkczogRml4dHVyZVJlY29yZFtdID0gZml4dHVyZXMubWFwKFxuICAgICAgICAgICAgICAoZml4dHVyZTogeyBlbnRpdHlJZDogc3RyaW5nOyBpZDogbnVtYmVyOyBjb2x1bW5zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB9KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZml4dHVyZS5lbnRpdHlJZCk7XG5cbiAgICAgICAgICAgICAgICAvLyDsl5Tti7Dti7AgcHJvcHPrpbwg6riw67CY7Jy866GcIGNvbHVtbnMg6rWs7ISxXG4gICAgICAgICAgICAgICAgY29uc3QgY29sdW1uczogRml4dHVyZVJlY29yZFtcImNvbHVtbnNcIl0gPSB7fTtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHByb3Agb2YgZW50aXR5LnByb3BzKSB7XG4gICAgICAgICAgICAgICAgICBpZiAocHJvcC50eXBlID09PSBcInZpcnR1YWxcIikgY29udGludWU7XG5cbiAgICAgICAgICAgICAgICAgIGxldCB2YWx1ZSA9IGZpeHR1cmUuY29sdW1uc1twcm9wLm5hbWVdID8/IG51bGw7XG5cbiAgICAgICAgICAgICAgICAgIGlmIChwcm9wLm5hbWUgPT09IFwiY3JlYXRlZF9hdFwiKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIO2YhOyerCDsi5zqsITsnLzroZwg7ISk7KCVXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpO1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgICAgICAgICAgcHJvcC50eXBlID09PSBcInJlbGF0aW9uXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgKHByb3AucmVsYXRpb25UeXBlID09PSBcIkhhc01hbnlcIiB8fCBwcm9wLnJlbGF0aW9uVHlwZSA9PT0gXCJNYW55VG9NYW55XCIpXG4gICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g67Cw7Je066GcIOuzgO2ZmFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUgOiBbdmFsdWVdLmZpbHRlcihub25OdWxsYWJsZSk7XG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIGNvbHVtbnNbcHJvcC5uYW1lXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgcHJvcCxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlIGFzIEZpeHR1cmVSZWNvcmRbXCJjb2x1bW5zXCJdW3N0cmluZ11bXCJ2YWx1ZVwiXSxcbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgIGZpeHR1cmVJZDogYCR7Zml4dHVyZS5lbnRpdHlJZH0jJHtmaXh0dXJlLmlkfWAsXG4gICAgICAgICAgICAgICAgICBlbnRpdHlJZDogZml4dHVyZS5lbnRpdHlJZCxcbiAgICAgICAgICAgICAgICAgIGlkOiBmaXh0dXJlLmlkLFxuICAgICAgICAgICAgICAgICAgY29sdW1ucyxcbiAgICAgICAgICAgICAgICAgIGZldGNoZWRSZWNvcmRzOiBbXSxcbiAgICAgICAgICAgICAgICAgIGJlbG9uZ3NSZWNvcmRzOiBbXSxcbiAgICAgICAgICAgICAgICAgIG92ZXJyaWRlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgLy8g7IOIIOugiOy9lOuTnOuTpOydmCByZWxhdGlvbiDsu6zrn7zsnYQg7ZmV7J247ZWY7JesIOq4sOyhtCDroIjsvZTrk5zrk6TsnZgg7Jet67Cp7ZalIHJlbGF0aW9uIOyXheuNsOydtO2KuFxuICAgICAgICAgICAgZm9yIChjb25zdCBuZXdSZWNvcmQgb2YgbmV3UmVjb3Jkcykge1xuICAgICAgICAgICAgICBmb3IgKGNvbnN0IFtfY29sTmFtZSwgY29sXSBvZiBPYmplY3QuZW50cmllcyhuZXdSZWNvcmQuY29sdW1ucykpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29sLnByb3AudHlwZSAhPT0gXCJyZWxhdGlvblwiIHx8IGNvbC52YWx1ZSA9PT0gbnVsbCkgY29udGludWU7XG5cbiAgICAgICAgICAgICAgICBjb25zdCByZWxhdGVkRW50aXR5SWQgPSBjb2wucHJvcC53aXRoO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlbGF0ZWRJZHMgPSBBcnJheS5pc0FycmF5KGNvbC52YWx1ZSkgPyBjb2wudmFsdWUgOiBbY29sLnZhbHVlXTtcblxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcmVsYXRlZElkIG9mIHJlbGF0ZWRJZHMpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHJlbGF0ZWRGaXh0dXJlSWQgPSBgJHtyZWxhdGVkRW50aXR5SWR9IyR7cmVsYXRlZElkfWA7XG4gICAgICAgICAgICAgICAgICBjb25zdCByZWxhdGVkUmVjb3JkID0gbmV3UmVjb3Jkcy5maW5kKChyKSA9PiByLmZpeHR1cmVJZCA9PT0gcmVsYXRlZEZpeHR1cmVJZCk7XG5cbiAgICAgICAgICAgICAgICAgIGlmIChyZWxhdGVkUmVjb3JkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIOyXreuwqe2WpSByZWxhdGlvbiDssL7quLBcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmV2ZXJzZUNvbCA9IE9iamVjdC5lbnRyaWVzKHJlbGF0ZWRSZWNvcmQuY29sdW1ucykuZmluZChcbiAgICAgICAgICAgICAgICAgICAgICAoWywgY10pID0+IGMucHJvcC50eXBlID09PSBcInJlbGF0aW9uXCIgJiYgYy5wcm9wLndpdGggPT09IG5ld1JlY29yZC5lbnRpdHlJZCxcbiAgICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAocmV2ZXJzZUNvbCkge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFtyZXZlcnNlQ29sTmFtZSwgcmV2ZXJzZUNvbFZhbHVlXSA9IHJldmVyc2VDb2w7XG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudFZhbHVlID0gcmV2ZXJzZUNvbFZhbHVlLnZhbHVlO1xuXG4gICAgICAgICAgICAgICAgICAgICAgLy8g7Jet67Cp7Zal7J20IOuwsOyXtOyduCDqsr3smrAgKEhhc01hbnksIE1hbnlUb01hbnkpXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgcmV2ZXJzZUNvbFZhbHVlLnByb3AudHlwZSA9PT0gXCJyZWxhdGlvblwiICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAocmV2ZXJzZUNvbFZhbHVlLnByb3AucmVsYXRpb25UeXBlID09PSBcIkhhc01hbnlcIiB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgICByZXZlcnNlQ29sVmFsdWUucHJvcC5yZWxhdGlvblR5cGUgPT09IFwiTWFueVRvTWFueVwiKVxuICAgICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXNzZXJ0KEFycmF5LmlzQXJyYXkoY3VycmVudFZhbHVlKSwgXCJjdXJyZW50VmFsdWUgbXVzdCBiZSBhbiBhcnJheVwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY3VycmVudFZhbHVlLmluY2x1ZGVzKG5ld1JlY29yZC5pZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVsYXRlZFJlY29yZC5jb2x1bW5zW3JldmVyc2VDb2xOYW1lXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5yZXZlcnNlQ29sVmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IFsuLi5jdXJyZW50VmFsdWUsIG5ld1JlY29yZC5pZF0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIOyXreuwqe2WpeydtCDri6jsnbwg6rCS7J24IOqyveyasCAoQmVsb25nc1RvT25lLCBPbmVUb09uZSlcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlbGF0ZWRSZWNvcmQuY29sdW1uc1tyZXZlcnNlQ29sTmFtZV0gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnJldmVyc2VDb2xWYWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IG5ld1JlY29yZC5pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUsIHVwZGF0ZWRSZWNvcmRzOiBuZXdSZWNvcmRzIH07XG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgaGFuZGxlRW50aXR5KG1lc3NhZ2VzOiBNb2RlbE1lc3NhZ2VbXSk6IFN0cmVhbVRleHRSZXN1bHQ8YW55LCBhbnk+IHtcbiAgICBpZiAoIXRoaXMuYWlTZGsgfHwgIXRoaXMubW9kZWwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkFJIFNESyBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdCgpIGZpcnN0LlwiKTtcbiAgICB9XG5cbiAgICAvLyBlbnRpdHkuaW5zdHJ1Y3Rpb25zLm1kIO2MjOydvCDsnb3quLAgKGRpc3QvdWkg65iQ64qUIHNyYy91aeyXkOyEnCDsi6TtlonrkJjrr4DroZwg7Yyo7YKk7KeAIOujqO2KuCDquLDspIDsnLzroZwg7KCR6re8KVxuICAgIGNvbnN0IGluc3RydWN0aW9uc1BhdGggPSBwYXRoLmpvaW4oXG4gICAgICBpbXBvcnQubWV0YS5kaXJuYW1lLFxuICAgICAgXCIuLlwiLFxuICAgICAgXCIuLlwiLFxuICAgICAgXCJzcmNcIixcbiAgICAgIFwidWlcIixcbiAgICAgIFwiZW50aXR5Lmluc3RydWN0aW9ucy5tZFwiLFxuICAgICk7XG4gICAgY29uc3QgaW5zdHJ1Y3Rpb25zID0gZnMucmVhZEZpbGVTeW5jKGluc3RydWN0aW9uc1BhdGgsIFwidXRmLThcIik7XG5cbiAgICAvLyDtmITsnqwg65Ox66Gd65CcIOyXlO2LsO2LsCDsoJXrs7Qg7IiY7KeRXG4gICAgY29uc3QgZW50aXR5SWRzID0gRW50aXR5TWFuYWdlci5nZXRBbGxJZHMoKTtcbiAgICBjb25zdCBleGlzdGluZ0VudGl0aWVzID0gZW50aXR5SWRzLm1hcCgoZW50aXR5SWQpID0+IHtcbiAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGlkOiBlbnRpdHkuaWQsXG4gICAgICAgIHRpdGxlOiBlbnRpdHkudGl0bGUsXG4gICAgICAgIHRhYmxlOiBlbnRpdHkudGFibGUsXG4gICAgICAgIHByb3BzOiBlbnRpdHkucHJvcHMubWFwKChwKSA9PiAoe1xuICAgICAgICAgIG5hbWU6IHAubmFtZSxcbiAgICAgICAgICB0eXBlOiBwLnR5cGUsXG4gICAgICAgICAgZGVzYzogcC5kZXNjLFxuICAgICAgICB9KSksXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgY29uc3Qgc3lzdGVtTWVzc2FnZSA9IGBcbuuLueyLoOydgCBTb25hbXUg7ZSE66CI7J6E7JuM7YGs7JeQ7IScIEVudGl0eeyZgCBFbnVt7J2EIOyDneyEse2VmOuKlCDrj4TsmrDrr7jsnoXri4jri6QuXG5cbiR7aW5zdHJ1Y3Rpb25zfVxuXG4jIyDtmITsnqwg65Ox66Gd65CcIEVudGl0eSDrqqnroZ1cbuuLpOuluCDsl5Tti7Dti7DsmYAg6rSA6rOEKHJlbGF0aW9uKeulvCDrp7rqsbDrgpggc3Vic2V07JeQ7IScIOywuOyhsO2VoCDrlYwg67CY65Oc7IucIOyVhOuemCDsoJXrs7Trpbwg7ZmV7J247ZWY7IS47JqULlxuXG4ke0pTT04uc3RyaW5naWZ5KGV4aXN0aW5nRW50aXRpZXMsIG51bGwsIDIpfVxuXG4jIyBUb29sIOyCrOyaqSDqsIDsnbTrk5xcblxuIyMjIEVudGl0eSDsg53shLEgKGNyZWF0ZUVudGl0eSlcbuyCrOyaqeyekOqwgCDsg4jroZzsmrQgRW50aXR5IOyDneyEseydhCDsmpTssq3tlZjrqbQgY3JlYXRlRW50aXR5IOuPhOq1rOulvCDsgqzsmqntlZjshLjsmpQuXG4tIGVudGl0eUlkOiBQYXNjYWxDYXNl66GcIOuQnCBFbnRpdHkgSUQgKOyYiDogXCJVc2VyXCIsIFwiUHJvZHVjdENhdGVnb3J5XCIpXG4tIHRpdGxlOiDtlZzquIAg7KCc66qpICjsmIg6IFwi7IKs7Jqp7J6QXCIsIFwi7IOB7ZKIIOy5tO2FjOqzoOumrFwiKVxuLSB0YWJsZTogc25ha2VfY2FzZeuhnCDrkJwg7YWM7J2067iU66qFICjsmIg6IFwidXNlcnNcIiwgXCJwcm9kdWN0X2NhdGVnb3JpZXNcIilcbi0gcGFyZW50SWQ6IOu2gOuqqCBFbnRpdHkgSUQgKOyEoO2DneyCrO2VrSlcbi0gcHJvcHM6IEVudGl0eeydmCDtlITroZztjbzti7Ag67Cw7Je0ICjsnIQg66y47ISc7J2YIFByb3BlcnR5IFR5cGVzIOywuOqzoClcbi0gaW5kZXhlczog7J24642x7IqkIOuwsOyXtFxuLSBzdWJzZXRzOiDshJzruIzshYsg7KCV7J2YICjquLDrs7jqsJI6IHsgQTogW1wiaWRcIl0gfSlcbi0gZW51bXM6IEVudW0g7KCV7J2YXG5cbiMjIyBFbnRpdHkg7IiY7KCVICh1cGRhdGVFbnRpdHkpXG7quLDsobQgRW50aXR566W8IOyImOygle2VoCDrlYwgdXBkYXRlRW50aXR5IOuPhOq1rOulvCDsgqzsmqntlZjshLjsmpQuIEVudW0g7LaU6rCALCBwcm9wcyDstpTqsIAv7IiY7KCVLCBpbmRleGVzIOyImOyglSDrk7Eg66qo65OgIOyImOyglSDsnpHsl4Xsl5Ag7IKs7Jqp7ZWp64uI64ukLlxuLSBlbnRpdHlJZDog7IiY7KCV7ZWgIEVudGl0eSBJRFxuLSB1cGRhdGVzOiDsiJjsoJXtlaAg7ZWE65Oc65OkICjrtoDrtoQg7JeF642w7J207Yq4KVxuICAtIHRpdGxlOiDsl5Tti7Dti7Ag7ZWc6riAIOygnOuqqVxuICAtIHRhYmxlOiDthYzsnbTruJTrqoVcbiAgLSBwcm9wczog7LaU6rCA7ZWgIO2UhOuhnO2NvO2LsCDrsLDsl7QgKOq4sOyhtCBwcm9wc+yXkCDstpTqsIAsIOqwmeydgCDsnbTrpoTsnbTrqbQg6rWQ7LK0KVxuICAtIGluZGV4ZXM6IOy2lOqwgO2VoCDsnbjrjbHsiqQg67Cw7Je0ICjquLDsobQgaW5kZXhlc+yXkCDstpTqsIApXG4gIC0gc3Vic2V0czog7ISc67iM7IWLIOygleydmCAo6riw7KG0IHN1YnNldHPsl5Ag67OR7ZWpKVxuICAtIGVudW1MYWJlbHM6IEVudW0g7KCV7J2YICjquLDsobQgZW51bUxhYmVsc+yXkCDrs5HtlakpXG4tIG1vZGU6IFwibWVyZ2VcIijquLDrs7jqsJIpIOuYkOuKlCBcInJlcGxhY2VcIlxuICAtIG1lcmdlOiDquLDsobQg6rCS7JeQIOuzke2VqVxuICAtIHJlcGxhY2U6IO2VtOuLuSDtlYTrk5wg7KCE7LK0IOq1kOyytFxuXG7smIjsi5w6IEVtcGxveWVl7JeQIOyDiCBFbnVtIOy2lOqwgFxudXBkYXRlRW50aXR5KHsgZW50aXR5SWQ6IFwiRW1wbG95ZWVcIiwgdXBkYXRlczogeyBlbnVtTGFiZWxzOiB7IFwiRW1wbG95ZWVSb2xlXCI6IHsgXCJhZG1pblwiOiBcIuq0gOumrOyekFwiLCBcInVzZXJcIjogXCLsnbzrsJhcIiB9IH0gfSB9KVxuXG7smIjsi5w6IFByb2plY3Tsl5Ag7IOIIO2UhOuhnO2NvO2LsCDstpTqsIBcbnVwZGF0ZUVudGl0eSh7IGVudGl0eUlkOiBcIlByb2plY3RcIiwgdXBkYXRlczogeyBwcm9wczogW3sgbmFtZTogXCJwcmlvcml0eVwiLCB0eXBlOiBcImludGVnZXJcIiwgZGVzYzogXCLsmrDshKDsiJzsnIRcIiB9XSB9IH0pXG5cbiMjIO2VhOyImCDsgqztla1cbi0gRW50aXR57J2YIHByb3Bz7JeQ64qUIOy1nOyGjO2VnCBpZChpbnRlZ2VyLCB1bnNpZ25lZCksIGNyZWF0ZWRfYXQodGltZXN0YW1wKeqwgCDtj6ztlajrkJjslrTslbwg7ZWp64uI64ukLlxuLSByZWxhdGlvbiDtlYTrk5zripQgb25VcGRhdGUsIG9uRGVsZXRl6rCAIO2VhOyImOyeheuLiOuLpC4gKOyYiOyZuDogT25lVG9PbmXsl5DshJwgaGFzSm9pbkNvbHVtbuydtCBmYWxzZeyduCDqsr3smrApXG4tIEVudW0gSUTripQg67O07Ya1IEVudGl0eUlkICsg7IaN7ISx66qFIO2Yle2DnOyeheuLiOuLpCAo7JiIOiBVc2VyU3RhdHVzLCBQcm9kdWN0VHlwZSlcbi0gc3Vic2V07JeQ7IScIOuLpOuluCDsl5Tti7Dti7DsnZgg7ZSE66Gc7Y287Yuw66W8IOywuOyhsO2VoCDrlYzripQg67CY65Oc7IucIO2VtOuLuSDsl5Tti7Dti7DsnZgg7Iuk7KCcIO2UhOuhnO2NvO2LsOuqheydhCDsgqzsmqntlZjshLjsmpQuXG5cbiMjIOqygOymnSDsmKTrpZgg7LKY66asXG7rj4Tqtawg7Zi47LacIOqysOqzvOuhnCDqsoDspp0g7Jik66WYKHZhbGlkYXRpb25FcnJvcnMp6rCAIOuwmO2ZmOuQmOuptDpcbjEuIOyYpOulmCDrqZTsi5zsp4Drpbwg67aE7ISd7ZWY7JesIOusuOygnOygkOydhCDtjIzslYXtlZjshLjsmpQuXG4yLiDsmKTrpZjrpbwg7IiY7KCV7ZWcIOuNsOydtO2EsOuhnCBjcmVhdGVFbnRpdHnrpbwg64uk7IucIO2YuOy2nO2VmOyEuOyalC5cbjMuIOyCrOyaqeyekOyXkOqyjCDsmKTrpZjrpbwg6re464yA66GcIOyghOuLrO2VmOyngCDrp5Dqs6AsIOyImOyglSDtm4Qg7J6s7Iuc64+E7ZWY7IS47JqULlxuXG4jIyMg7J2867CY7KCB7J24IOqygOymnSDsmKTrpZjsmYAg7IiY7KCVIOuwqeuylVxufCDsmKTrpZgg66mU7Iuc7KeAIHwg7IiY7KCVIOuwqeuylSB8XG58LS0tLS0tLS0tLS0tfC0tLS0tLS0tLS18XG58IFwiaWQg7ZSE66Gc7Y287Yuw6rCAIO2VhOyImFwiIHwgcHJvcHPsl5AgeyBuYW1lOiBcImlkXCIsIHR5cGU6IFwiaW50ZWdlclwiLCB1bnNpZ25lZDogdHJ1ZSB9IOy2lOqwgCB8XG58IFwiY3JlYXRlZF9hdCDtlITroZztjbzti7DqsIAg7ZWE7IiYXCIgfCBwcm9wc+yXkCB7IG5hbWU6IFwiY3JlYXRlZF9hdFwiLCB0eXBlOiBcInRpbWVzdGFtcFwiLCBkYkRlZmF1bHQ6IFwiQ1VSUkVOVF9USU1FU1RBTVBcIiB9IOy2lOqwgCB8XG58IFwiWHh4T3JkZXJCeSBlbnVt7J20IO2VhOyImFwiIHwgZW51bXPsl5AgeyBcIlh4eE9yZGVyQnlcIjogeyBcImlkLWRlc2NcIjogXCJJROy1nOyLoOyInFwiIH0gfSDstpTqsIAgfFxufCBcIlh4eFNlYXJjaEZpZWxkIGVudW3snbQg7ZWE7IiYXCIgfCBlbnVtc+yXkCB7IFwiWHh4U2VhcmNoRmllbGRcIjogeyBcImlkXCI6IFwiSURcIiB9IH0g7LaU6rCAIHxcbnwgXCJzdHJpbmcg7YOA7J6F7J2AIGxlbmd0aOqwgCDtlYTsiJhcIiB8IO2VtOuLuSBwcm9w7JeQIGxlbmd0aCDstpTqsIAgKOyYiDogMjU1KSB8XG58IFwidGV4dCDtg4DsnoXsnYAgdGV4dFR5cGXsnbQg7ZWE7IiYXCIgfCDtlbTri7kgcHJvcOyXkCB0ZXh0VHlwZSDstpTqsIAgKFwidGV4dFwiLCBcIm1lZGl1bXRleHRcIiwgXCJsb25ndGV4dFwiKSB8XG58IFwib25VcGRhdGXqsIAg7ZWE7IiYXCIgfCDtlbTri7kgcmVsYXRpb24gcHJvcOyXkCBvblVwZGF0ZSwgb25EZWxldGUg7LaU6rCAIChcIkNBU0NBREVcIikgfFxuICAgICAgYDtcblxuICAgIGNvbnN0IHsgc3RyZWFtVGV4dCwgdG9vbCwgc3RlcENvdW50SXMgfSA9IHRoaXMuYWlTZGs7XG5cbiAgICByZXR1cm4gc3RyZWFtVGV4dCh7XG4gICAgICBtb2RlbDogdGhpcy5tb2RlbCBhcyB1bmtub3duIGFzIExhbmd1YWdlTW9kZWwsXG4gICAgICBzeXN0ZW06IHN5c3RlbU1lc3NhZ2UsXG4gICAgICBtZXNzYWdlcyxcbiAgICAgIHN0b3BXaGVuOiBzdGVwQ291bnRJcygyKSxcbiAgICAgIHRvb2xzOiB7XG4gICAgICAgIGNyZWF0ZUVudGl0eTogdG9vbCh7XG4gICAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgICBcIuyDiOuhnOyatCBFbnRpdHnrpbwg7IOd7ISx7ZWp64uI64ukLiDsgqzsmqnsnpDqsIAg7IOI66Gc7Jq0IOyXlO2LsO2LsOuCmCDthYzsnbTruJQg7IOd7ISx7J2EIOyalOyyre2VoCDrlYwg7IKs7Jqp7ZWY7IS47JqULlwiLFxuICAgICAgICAgIGlucHV0U2NoZW1hOiBUZW1wbGF0ZU9wdGlvbnMuc2hhcGUuZW50aXR5LFxuICAgICAgICAgIGV4ZWN1dGU6IGFzeW5jIChcbiAgICAgICAgICAgIGVudGl0eTogei5pbmZlcjx0eXBlb2YgVGVtcGxhdGVPcHRpb25zLnNoYXBlLmVudGl0eT4sXG4gICAgICAgICAgKTogUHJvbWlzZTx7XG4gICAgICAgICAgICBzdWNjZXNzOiBib29sZWFuO1xuICAgICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICAgIGVycm9yPzogc3RyaW5nO1xuICAgICAgICAgICAgdmFsaWRhdGlvbkVycm9ycz86IFZhbGlkYXRpb25FcnJvcltdO1xuICAgICAgICAgIH0+ID0+IHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIC8vIOyeheugpSDqsoDspp1cbiAgICAgICAgICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRlRW50aXR5SnNvbihlbnRpdHkpO1xuXG4gICAgICAgICAgICAgIGlmICh2YWxpZGF0aW9uRXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgICAgICBlbnRpdHlJZDogZW50aXR5LmVudGl0eUlkLFxuICAgICAgICAgICAgICAgICAgZXJyb3I6IGDqsoDspp0g7Jik66WYOiAke3ZhbGlkYXRpb25FcnJvcnMubWFwKChlKSA9PiBgWyR7ZS5maWVsZH1dICR7ZS5tZXNzYWdlfWApLmpvaW4oXCIsIFwiKX1gLFxuICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgYXdhaXQgU29uYW11LnN5bmNlci5jcmVhdGVFbnRpdHkoe1xuICAgICAgICAgICAgICAgIHN1YnNldHM6IHsgQTogW1wiaWRcIl0gfSxcbiAgICAgICAgICAgICAgICBlbnVtczoge30sXG4gICAgICAgICAgICAgICAgLi4uZW50aXR5LFxuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAvLyBFbnRpdHlNYW5hZ2VyIOumrOuhnOuTnFxuICAgICAgICAgICAgICBhd2FpdCBFbnRpdHlNYW5hZ2VyLnJlbG9hZCgpO1xuXG4gICAgICAgICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUsIGVudGl0eUlkOiBlbnRpdHkuZW50aXR5SWQgfTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBlIGluc3RhbmNlb2YgRXJyb3IgPyBlLm1lc3NhZ2UgOiBcIlVua25vd24gZXJyb3JcIjtcbiAgICAgICAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogZmFsc2UsIGVudGl0eUlkOiBlbnRpdHkuZW50aXR5SWQsIGVycm9yIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICAgIHVwZGF0ZUVudGl0eTogdG9vbCh7XG4gICAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgICBcIuq4sOyhtCBFbnRpdHnrpbwg7IiY7KCV7ZWp64uI64ukLiBFbnVtIOy2lOqwgCwgcHJvcHMg7LaU6rCAL+yImOyglSwgaW5kZXhlcyDsiJjsoJUsIHN1YnNldHMg7IiY7KCVIOuTsSDrqqjrk6Ag7JeU7Yuw7YuwIOyImOyglSDsnpHsl4Xsl5Ag7IKs7Jqp7ZWY7IS47JqULlwiLFxuICAgICAgICAgIGlucHV0U2NoZW1hOiB6Lm9iamVjdCh7XG4gICAgICAgICAgICBlbnRpdHlJZDogei5zdHJpbmcoKS5kZXNjcmliZShcIuyImOygle2VoCBFbnRpdHkgSURcIiksXG4gICAgICAgICAgICB1cGRhdGVzOiBUZW1wbGF0ZU9wdGlvbnMuc2hhcGUuZW50aXR5LnBhcnRpYWwoKS5kZXNjcmliZShcIuyImOygle2VoCDtlYTrk5zrk6RcIiksXG4gICAgICAgICAgICBtb2RlOiB6XG4gICAgICAgICAgICAgIC5lbnVtKFtcIm1lcmdlXCIsIFwicmVwbGFjZVwiXSlcbiAgICAgICAgICAgICAgLm9wdGlvbmFsKClcbiAgICAgICAgICAgICAgLmRlc2NyaWJlKFwi7IiY7KCVIOuqqOuTnDogbWVyZ2Uo6riw67O46rCSLCDquLDsobQg6rCS7JeQIOuzke2VqSkg65iQ64qUIHJlcGxhY2Uo7KCE7LK0IOq1kOyytClcIiksXG4gICAgICAgICAgfSksXG4gICAgICAgICAgZXhlY3V0ZTogYXN5bmMgKHtcbiAgICAgICAgICAgIGVudGl0eUlkLFxuICAgICAgICAgICAgdXBkYXRlcyxcbiAgICAgICAgICAgIG1vZGUgPSBcIm1lcmdlXCIsXG4gICAgICAgICAgfToge1xuICAgICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICAgIHVwZGF0ZXM6IFBhcnRpYWw8ei5pbmZlcjx0eXBlb2YgVGVtcGxhdGVPcHRpb25zLnNoYXBlLmVudGl0eT4+O1xuICAgICAgICAgICAgbW9kZT86IFwibWVyZ2VcIiB8IFwicmVwbGFjZVwiO1xuICAgICAgICAgIH0pOiBQcm9taXNlPHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGJvb2xlYW47XG4gICAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgICAgZXJyb3I/OiBzdHJpbmc7XG4gICAgICAgICAgICB2YWxpZGF0aW9uRXJyb3JzPzogVmFsaWRhdGlvbkVycm9yW107XG4gICAgICAgICAgfT4gPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuXG4gICAgICAgICAgICAgIC8vIFVwZGF0ZSBiYXNpYyBwcm9wZXJ0aWVzXG4gICAgICAgICAgICAgIGlmICh1cGRhdGVzLmVudGl0eUlkICE9PSB1bmRlZmluZWQpIGVudGl0eS5pZCA9IHVwZGF0ZXMuZW50aXR5SWQ7XG4gICAgICAgICAgICAgIGlmICh1cGRhdGVzLnBhcmVudElkICE9PSB1bmRlZmluZWQpIGVudGl0eS5wYXJlbnRJZCA9IHVwZGF0ZXMucGFyZW50SWQ7XG4gICAgICAgICAgICAgIGlmICh1cGRhdGVzLnRpdGxlICE9PSB1bmRlZmluZWQpIGVudGl0eS50aXRsZSA9IHVwZGF0ZXMudGl0bGU7XG4gICAgICAgICAgICAgIGlmICh1cGRhdGVzLnRhYmxlICE9PSB1bmRlZmluZWQpIGVudGl0eS50YWJsZSA9IHVwZGF0ZXMudGFibGU7XG4gICAgICAgICAgICAgIGlmICh1cGRhdGVzLmNvbmUgIT09IHVuZGVmaW5lZCkgZW50aXR5LmNvbmUgPSB1cGRhdGVzLmNvbmU7XG5cbiAgICAgICAgICAgICAgLy8gcHJvcHM6IG1lcmdlIOyLnCDsnbTrpoQg6riw7KSAIOuzke2VqSwgcmVwbGFjZSDsi5wg6rWQ7LK0XG4gICAgICAgICAgICAgIGlmICh1cGRhdGVzLnByb3BzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAobW9kZSA9PT0gXCJyZXBsYWNlXCIpIHtcbiAgICAgICAgICAgICAgICAgIGVudGl0eS5wcm9wcyA9IHVwZGF0ZXMucHJvcHMgYXMgRW50aXR5UHJvcFtdO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IG5ld1Byb3Agb2YgdXBkYXRlcy5wcm9wcykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ0luZGV4ID0gZW50aXR5LnByb3BzLmZpbmRJbmRleCgocCkgPT4gcC5uYW1lID09PSBuZXdQcm9wLm5hbWUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXhpc3RpbmdJbmRleCA+PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgZW50aXR5LnByb3BzW2V4aXN0aW5nSW5kZXhdID0gbmV3UHJvcCBhcyBFbnRpdHlQcm9wO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgIGVudGl0eS5wcm9wcy5wdXNoKG5ld1Byb3AgYXMgRW50aXR5UHJvcCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyBpbmRleGVzOiBtZXJnZSDsi5wg7LaU6rCALCByZXBsYWNlIOyLnCDqtZDssrRcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZXMuaW5kZXhlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgZW50aXR5LmluZGV4ZXMgPVxuICAgICAgICAgICAgICAgICAgbW9kZSA9PT0gXCJyZXBsYWNlXCIgPyB1cGRhdGVzLmluZGV4ZXMgOiBbLi4uZW50aXR5LmluZGV4ZXMsIC4uLnVwZGF0ZXMuaW5kZXhlc107XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyBzdWJzZXRzLCBzdWJzZXRzSW50ZXJuYWw6IGFzc2lnbuycvOuhnCDrs5Htlakg65iQ64qUIOq1kOyytFxuICAgICAgICAgICAgICBpZiAodXBkYXRlcy5zdWJzZXRzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAvLyBOb3JtYWxpemUgc3Vic2V0IGZpZWxkczogc2VwYXJhdGUgaW50byBzdWJzZXRzIChub3JtYWwpIGFuZCBzdWJzZXRzSW50ZXJuYWwgKGludGVybmFsKVxuICAgICAgICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRTdWJzZXRzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZ1tdIH0gPSB7fTtcbiAgICAgICAgICAgICAgICBjb25zdCBub3JtYWxpemVkU3Vic2V0c0ludGVybmFsOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZ1tdIH0gPSB7fTtcblxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2tleSwgZmllbGRzXSBvZiBPYmplY3QuZW50cmllcyh1cGRhdGVzLnN1YnNldHMpKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBmaWVsZEFycmF5ID0gZmllbGRzIGFzIHN0cmluZ1tdO1xuICAgICAgICAgICAgICAgICAgbm9ybWFsaXplZFN1YnNldHNba2V5XSA9IGZpZWxkQXJyYXlcbiAgICAgICAgICAgICAgICAgICAgLmZpbHRlcigoZjogc3RyaW5nKSA9PiAhaXNJbnRlcm5hbFN1YnNldEZpZWxkKGYpKVxuICAgICAgICAgICAgICAgICAgICAubWFwKG5vcm1hbGl6ZVN1YnNldEZpZWxkKTtcbiAgICAgICAgICAgICAgICAgIG5vcm1hbGl6ZWRTdWJzZXRzSW50ZXJuYWxba2V5XSA9IGZpZWxkQXJyYXlcbiAgICAgICAgICAgICAgICAgICAgLmZpbHRlcihpc0ludGVybmFsU3Vic2V0RmllbGQpXG4gICAgICAgICAgICAgICAgICAgIC5tYXAobm9ybWFsaXplU3Vic2V0RmllbGQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGVudGl0eS5zdWJzZXRzID1cbiAgICAgICAgICAgICAgICAgIG1vZGUgPT09IFwicmVwbGFjZVwiXG4gICAgICAgICAgICAgICAgICAgID8gbm9ybWFsaXplZFN1YnNldHNcbiAgICAgICAgICAgICAgICAgICAgOiB7IC4uLmVudGl0eS5zdWJzZXRzLCAuLi5ub3JtYWxpemVkU3Vic2V0cyB9O1xuICAgICAgICAgICAgICAgIGVudGl0eS5zdWJzZXRzSW50ZXJuYWwgPVxuICAgICAgICAgICAgICAgICAgbW9kZSA9PT0gXCJyZXBsYWNlXCJcbiAgICAgICAgICAgICAgICAgICAgPyBub3JtYWxpemVkU3Vic2V0c0ludGVybmFsXG4gICAgICAgICAgICAgICAgICAgIDogeyAuLi5lbnRpdHkuc3Vic2V0c0ludGVybmFsLCAuLi5ub3JtYWxpemVkU3Vic2V0c0ludGVybmFsIH07XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZiAodXBkYXRlcy5lbnVtcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29udmVydGVkRW51bXMgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgICAgICAgICAgICBPYmplY3QuZW50cmllcyh1cGRhdGVzLmVudW1zKS5tYXAoKFtrZXksIGVudW1EZWZdKSA9PiBbXG4gICAgICAgICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgICAgICAgZ2V0RW51bURlZlZhbHVlcyhlbnVtRGVmKSxcbiAgICAgICAgICAgICAgICAgIF0pLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgZW50aXR5LmVudW1MYWJlbHMgPVxuICAgICAgICAgICAgICAgICAgbW9kZSA9PT0gXCJyZXBsYWNlXCIgPyBjb252ZXJ0ZWRFbnVtcyA6IHsgLi4uZW50aXR5LmVudW1MYWJlbHMsIC4uLmNvbnZlcnRlZEVudW1zIH07XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyDsoIDsnqUg7KCEIOqygOymnVxuICAgICAgICAgICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGVFbnRpdHlKc29uKHtcbiAgICAgICAgICAgICAgICAuLi5lbnRpdHksXG4gICAgICAgICAgICAgICAgZW50aXR5SWQ6IGVudGl0eS5pZCxcbiAgICAgICAgICAgICAgICBlbnVtczogZW50aXR5LmVudW1MYWJlbHMsXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGlmICh2YWxpZGF0aW9uRXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgICAgICBlbnRpdHlJZCxcbiAgICAgICAgICAgICAgICAgIGVycm9yOiBg6rKA7KadIOyYpOulmDogJHt2YWxpZGF0aW9uRXJyb3JzLm1hcCgoZSkgPT4gYFske2UuZmllbGR9XSAke2UubWVzc2FnZX1gKS5qb2luKFwiLCBcIil9YCxcbiAgICAgICAgICAgICAgICAgIHZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG5cbiAgICAgICAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSwgZW50aXR5SWQgfTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBlIGluc3RhbmNlb2YgRXJyb3IgPyBlLm1lc3NhZ2UgOiBcIlVua25vd24gZXJyb3JcIjtcbiAgICAgICAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogZmFsc2UsIGVudGl0eUlkLCBlcnJvciB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIEVudGl0eSBKU09O7J20IGVudGl0eS5pbnN0cnVjdGlvbnMubWTsnZgg6rec7LmZ7J2EIOuUsOultOuKlOyngCDqsoDspp3tlanri4jri6QuXG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlRW50aXR5SnNvbihpbnB1dDogVGVtcGxhdGVPcHRpb25zW1wiZW50aXR5XCJdKTogVmFsaWRhdGlvbkVycm9yW10ge1xuICBjb25zdCBlcnJvcnM6IFZhbGlkYXRpb25FcnJvcltdID0gW107XG4gIGNvbnN0IHsgZW50aXR5SWQsIHByb3BzLCBlbnVtcyB9ID0gaW5wdXQ7XG5cbiAgLy8gMS4gaWQsIGNyZWF0ZWRfYXQgcHJvcCDtlYTsiJhcbiAgY29uc3QgaGFzSWRQcm9wID0gcHJvcHM/LnNvbWUoKHApID0+IHAubmFtZSA9PT0gXCJpZFwiKTtcbiAgaWYgKCFoYXNJZFByb3ApIHtcbiAgICBlcnJvcnMucHVzaCh7IGZpZWxkOiBcInByb3BzXCIsIG1lc3NhZ2U6IFwiaWQg7ZSE66Gc7Y287Yuw6rCAIO2VhOyImOyeheuLiOuLpC5cIiB9KTtcbiAgfVxuICBjb25zdCBoYXNDcmVhdGVkQXRQcm9wID0gcHJvcHM/LnNvbWUoKHApID0+IHAubmFtZSA9PT0gXCJjcmVhdGVkX2F0XCIpO1xuICBpZiAoIWhhc0NyZWF0ZWRBdFByb3ApIHtcbiAgICBlcnJvcnMucHVzaCh7IGZpZWxkOiBcInByb3BzXCIsIG1lc3NhZ2U6IFwiY3JlYXRlZF9hdCDtlITroZztjbzti7DqsIAg7ZWE7IiY7J6F64uI64ukLlwiIH0pO1xuICB9XG5cbiAgLy8gMi4g7ZWE7IiYIGVudW0g6rKA7KadOiBFbnRpdHlOYW1lT3JkZXJCeSwgRW50aXR5TmFtZVNlYXJjaEZpZWxkXG4gIGNvbnN0IG9yZGVyQnlFbnVtSWQgPSBgJHtlbnRpdHlJZH1PcmRlckJ5YDtcbiAgY29uc3Qgc2VhcmNoRmllbGRFbnVtSWQgPSBgJHtlbnRpdHlJZH1TZWFyY2hGaWVsZGA7XG5cbiAgaWYgKCFlbnVtcz8uW29yZGVyQnlFbnVtSWRdKSB7XG4gICAgZXJyb3JzLnB1c2goe1xuICAgICAgZmllbGQ6IFwiZW51bXNcIixcbiAgICAgIG1lc3NhZ2U6IGAke29yZGVyQnlFbnVtSWR9IGVudW3snbQg7ZWE7IiY7J6F64uI64ukLiAo7JiIOiB7IFwiaWQtZGVzY1wiOiBcIklE7LWc7Iug7IicXCIgfSlgLFxuICAgIH0pO1xuICB9XG4gIGlmICghZW51bXM/LltzZWFyY2hGaWVsZEVudW1JZF0pIHtcbiAgICBlcnJvcnMucHVzaCh7XG4gICAgICBmaWVsZDogXCJlbnVtc1wiLFxuICAgICAgbWVzc2FnZTogYCR7c2VhcmNoRmllbGRFbnVtSWR9IGVudW3snbQg7ZWE7IiY7J6F64uI64ukLiAo7JiIOiB7IFwiaWRcIjogXCJJRFwiIH0pYCxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIDMuIGVudW0gcHJvcOydmCBpZOqwgCBlbnVtc+yXkCDsoJXsnZjrkJjslrQg7J6I64qU7KeAIO2ZleyduCAoY3Jvc3MtZmllbGQg6rKA7KadKVxuICBmb3IgKGNvbnN0IHByb3Agb2YgcHJvcHMgPz8gW10pIHtcbiAgICBpZiAocHJvcC50eXBlID09PSBcImVudW1cIiAmJiAhZW51bXM/Lltwcm9wLmlkXSkge1xuICAgICAgZXJyb3JzLnB1c2goe1xuICAgICAgICBmaWVsZDogYHByb3BzLiR7cHJvcC5uYW1lfWAsXG4gICAgICAgIG1lc3NhZ2U6IGBlbnVtIGlkIFwiJHtwcm9wLmlkfVwi6rCAIGVudW1z7JeQIOygleydmOuQmOyWtCDsnojsp4Ag7JWK7Iq164uI64ukLmAsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZXJyb3JzO1xufVxuXG5leHBvcnQgY29uc3QgYWlDbGllbnQgPSBuZXcgQUlDbGllbnQoKTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQW1oQkEsU0FBUyxtQkFBbUIs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