sonamu 0.6.0 → 0.7.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 (406) hide show
  1. package/.swcrc.project-default +18 -0
  2. package/bin/cli.js +24 -0
  3. package/dist/ai/agents/agent.d.ts +11 -0
  4. package/dist/ai/agents/agent.d.ts.map +1 -0
  5. package/dist/ai/agents/agent.js +65 -0
  6. package/dist/ai/agents/index.d.ts +3 -0
  7. package/dist/ai/agents/index.d.ts.map +1 -0
  8. package/dist/ai/agents/index.js +4 -0
  9. package/dist/ai/agents/types.d.ts +43 -0
  10. package/dist/ai/agents/types.d.ts.map +1 -0
  11. package/dist/ai/agents/types.js +3 -0
  12. package/dist/ai/index.d.ts +2 -0
  13. package/dist/ai/index.d.ts.map +1 -0
  14. package/dist/ai/index.js +3 -0
  15. package/dist/ai/providers/rtzr/api.d.ts +22 -0
  16. package/dist/ai/providers/rtzr/api.d.ts.map +1 -0
  17. package/dist/ai/providers/rtzr/api.js +28 -0
  18. package/dist/ai/providers/rtzr/error.d.ts +18 -0
  19. package/dist/ai/providers/rtzr/error.d.ts.map +1 -0
  20. package/dist/ai/providers/rtzr/error.js +29 -0
  21. package/dist/ai/providers/rtzr/index.d.ts +5 -0
  22. package/dist/ai/providers/rtzr/index.d.ts.map +1 -0
  23. package/dist/ai/providers/rtzr/index.js +6 -0
  24. package/dist/ai/providers/rtzr/model.d.ts +52 -0
  25. package/dist/ai/providers/rtzr/model.d.ts.map +1 -0
  26. package/dist/ai/providers/rtzr/model.js +137 -0
  27. package/dist/ai/providers/rtzr/options.d.ts +7 -0
  28. package/dist/ai/providers/rtzr/options.d.ts.map +1 -0
  29. package/dist/ai/providers/rtzr/options.js +47 -0
  30. package/dist/ai/providers/rtzr/provider.d.ts +18 -0
  31. package/dist/ai/providers/rtzr/provider.d.ts.map +1 -0
  32. package/dist/ai/providers/rtzr/provider.js +54 -0
  33. package/dist/ai/providers/rtzr/utils.d.ts +19 -0
  34. package/dist/ai/providers/rtzr/utils.d.ts.map +1 -0
  35. package/dist/ai/providers/rtzr/utils.js +88 -0
  36. package/dist/api/base-frame.d.ts +2 -2
  37. package/dist/api/base-frame.d.ts.map +1 -1
  38. package/dist/api/base-frame.js +2 -1
  39. package/dist/api/caster.d.ts.map +1 -1
  40. package/dist/api/caster.js +6 -1
  41. package/dist/api/code-converters.d.ts +58 -14
  42. package/dist/api/code-converters.d.ts.map +1 -1
  43. package/dist/api/code-converters.js +178 -409
  44. package/dist/api/config.d.ts +27 -13
  45. package/dist/api/config.d.ts.map +1 -1
  46. package/dist/api/config.js +19 -26
  47. package/dist/api/context.d.ts +4 -3
  48. package/dist/api/context.d.ts.map +1 -1
  49. package/dist/api/context.js +1 -1
  50. package/dist/api/decorators.d.ts +20 -6
  51. package/dist/api/decorators.d.ts.map +1 -1
  52. package/dist/api/decorators.js +111 -18
  53. package/dist/api/index.d.ts +2 -2
  54. package/dist/api/index.d.ts.map +1 -1
  55. package/dist/api/index.js +3 -3
  56. package/dist/api/sonamu.d.ts +7 -7
  57. package/dist/api/sonamu.d.ts.map +1 -1
  58. package/dist/api/sonamu.js +83 -51
  59. package/dist/api/validator.d.ts +6 -0
  60. package/dist/api/validator.d.ts.map +1 -0
  61. package/dist/api/validator.js +81 -0
  62. package/dist/bin/build-config.d.ts +5 -1
  63. package/dist/bin/build-config.d.ts.map +1 -1
  64. package/dist/bin/build-config.js +5 -2
  65. package/dist/bin/cli.js +165 -64
  66. package/dist/bin/loader-register.d.ts +2 -0
  67. package/dist/bin/loader-register.d.ts.map +1 -0
  68. package/dist/bin/loader-register.js +34 -0
  69. package/dist/database/_batch_update.d.ts +5 -3
  70. package/dist/database/_batch_update.d.ts.map +1 -1
  71. package/dist/database/_batch_update.js +30 -13
  72. package/dist/database/base-model.d.ts +96 -10
  73. package/dist/database/base-model.d.ts.map +1 -1
  74. package/dist/database/base-model.js +232 -89
  75. package/dist/database/base-model.types.d.ts +93 -0
  76. package/dist/database/base-model.types.d.ts.map +1 -0
  77. package/dist/database/base-model.types.js +10 -0
  78. package/dist/database/code-generator.d.ts +1 -1
  79. package/dist/database/code-generator.d.ts.map +1 -1
  80. package/dist/database/code-generator.js +11 -10
  81. package/dist/database/db.d.ts +5 -6
  82. package/dist/database/db.d.ts.map +1 -1
  83. package/dist/database/db.js +22 -25
  84. package/dist/database/puri-subset.test-d.js +81 -0
  85. package/dist/database/puri-subset.types.d.ts +123 -0
  86. package/dist/database/puri-subset.types.d.ts.map +1 -0
  87. package/dist/database/puri-subset.types.js +16 -0
  88. package/dist/database/puri-wrapper.d.ts +13 -11
  89. package/dist/database/puri-wrapper.d.ts.map +1 -1
  90. package/dist/database/puri-wrapper.js +2 -2
  91. package/dist/database/puri.d.ts +25 -14
  92. package/dist/database/puri.d.ts.map +1 -1
  93. package/dist/database/puri.js +83 -21
  94. package/dist/database/puri.types.d.ts +21 -7
  95. package/dist/database/puri.types.d.ts.map +1 -1
  96. package/dist/database/puri.types.js +4 -1
  97. package/dist/database/transaction-context.d.ts +1 -1
  98. package/dist/database/transaction-context.d.ts.map +1 -1
  99. package/dist/database/transaction-context.js +1 -1
  100. package/dist/database/upsert-builder.d.ts +9 -3
  101. package/dist/database/upsert-builder.d.ts.map +1 -1
  102. package/dist/database/upsert-builder.js +228 -78
  103. package/dist/entity/entity-manager.d.ts +165 -2
  104. package/dist/entity/entity-manager.d.ts.map +1 -1
  105. package/dist/entity/entity-manager.js +26 -10
  106. package/dist/entity/entity.d.ts +5 -3
  107. package/dist/entity/entity.d.ts.map +1 -1
  108. package/dist/entity/entity.js +153 -54
  109. package/dist/exceptions/error-handler.d.ts +1 -1
  110. package/dist/exceptions/error-handler.d.ts.map +1 -1
  111. package/dist/exceptions/error-handler.js +1 -1
  112. package/dist/exceptions/so-exceptions.d.ts +1 -1
  113. package/dist/exceptions/so-exceptions.d.ts.map +1 -1
  114. package/dist/exceptions/so-exceptions.js +1 -1
  115. package/dist/file-storage/driver.d.ts +1 -1
  116. package/dist/file-storage/driver.d.ts.map +1 -1
  117. package/dist/file-storage/driver.js +1 -1
  118. package/dist/file-storage/file-storage.js +2 -2
  119. package/dist/index.d.ts +18 -11
  120. package/dist/index.d.ts.map +1 -1
  121. package/dist/index.js +19 -13
  122. package/dist/migration/code-generation.d.ts +1 -1
  123. package/dist/migration/code-generation.d.ts.map +1 -1
  124. package/dist/migration/code-generation.js +123 -67
  125. package/dist/migration/migration-set.d.ts +2 -10
  126. package/dist/migration/migration-set.d.ts.map +1 -1
  127. package/dist/migration/migration-set.js +67 -218
  128. package/dist/migration/migrator.d.ts +24 -73
  129. package/dist/migration/migrator.d.ts.map +1 -1
  130. package/dist/migration/migrator.js +121 -301
  131. package/dist/migration/postgresql-schema-reader.d.ts +51 -0
  132. package/dist/migration/postgresql-schema-reader.d.ts.map +1 -0
  133. package/dist/migration/postgresql-schema-reader.js +245 -0
  134. package/dist/migration/types.d.ts +6 -38
  135. package/dist/migration/types.d.ts.map +1 -1
  136. package/dist/migration/types.js +1 -1
  137. package/dist/naite/messaging-types.d.ts +43 -0
  138. package/dist/naite/messaging-types.d.ts.map +1 -0
  139. package/dist/naite/messaging-types.js +7 -0
  140. package/dist/naite/naite-reporter.d.ts +41 -0
  141. package/dist/naite/naite-reporter.d.ts.map +1 -0
  142. package/dist/naite/naite-reporter.js +102 -0
  143. package/dist/naite/naite.d.ts +91 -8
  144. package/dist/naite/naite.d.ts.map +1 -1
  145. package/dist/naite/naite.js +285 -41
  146. package/dist/stream/sse.d.ts +2 -2
  147. package/dist/stream/sse.d.ts.map +1 -1
  148. package/dist/stream/sse.js +1 -1
  149. package/dist/syncer/api-parser.d.ts +3 -13
  150. package/dist/syncer/api-parser.d.ts.map +1 -1
  151. package/dist/syncer/api-parser.js +67 -56
  152. package/dist/syncer/checksum.d.ts +2 -2
  153. package/dist/syncer/checksum.d.ts.map +1 -1
  154. package/dist/syncer/checksum.js +11 -11
  155. package/dist/syncer/code-generator.d.ts +3 -3
  156. package/dist/syncer/code-generator.d.ts.map +1 -1
  157. package/dist/syncer/code-generator.js +37 -17
  158. package/dist/syncer/entity-operations.d.ts +2 -2
  159. package/dist/syncer/entity-operations.d.ts.map +1 -1
  160. package/dist/syncer/entity-operations.js +9 -8
  161. package/dist/syncer/file-patterns.d.ts +1 -1
  162. package/dist/syncer/file-patterns.d.ts.map +1 -1
  163. package/dist/syncer/file-patterns.js +1 -1
  164. package/dist/syncer/index.d.ts +4 -4
  165. package/dist/syncer/index.d.ts.map +1 -1
  166. package/dist/syncer/index.js +5 -5
  167. package/dist/syncer/module-loader.d.ts +4 -4
  168. package/dist/syncer/module-loader.d.ts.map +1 -1
  169. package/dist/syncer/module-loader.js +17 -12
  170. package/dist/syncer/syncer.d.ts +31 -24
  171. package/dist/syncer/syncer.d.ts.map +1 -1
  172. package/dist/syncer/syncer.js +92 -45
  173. package/dist/template/entity-converter.d.ts +1 -1
  174. package/dist/template/entity-converter.d.ts.map +1 -1
  175. package/dist/template/entity-converter.js +15 -8
  176. package/dist/template/helpers.d.ts +2 -2
  177. package/dist/template/helpers.d.ts.map +1 -1
  178. package/dist/template/helpers.js +3 -3
  179. package/dist/template/implementations/entity.template.d.ts +2 -2
  180. package/dist/template/implementations/entity.template.d.ts.map +1 -1
  181. package/dist/template/implementations/entity.template.js +4 -5
  182. package/dist/template/implementations/generated.template.d.ts +2 -3
  183. package/dist/template/implementations/generated.template.d.ts.map +1 -1
  184. package/dist/template/implementations/generated.template.js +46 -29
  185. package/dist/template/implementations/generated_http.template.d.ts +2 -3
  186. package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
  187. package/dist/template/implementations/generated_http.template.js +9 -9
  188. package/dist/template/implementations/generated_sso.template.d.ts +3 -4
  189. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
  190. package/dist/template/implementations/generated_sso.template.js +54 -25
  191. package/dist/template/implementations/init_types.template.d.ts +2 -2
  192. package/dist/template/implementations/init_types.template.d.ts.map +1 -1
  193. package/dist/template/implementations/init_types.template.js +2 -2
  194. package/dist/template/implementations/model.template.d.ts +2 -2
  195. package/dist/template/implementations/model.template.d.ts.map +1 -1
  196. package/dist/template/implementations/model.template.js +47 -37
  197. package/dist/template/implementations/model_test.template.d.ts +2 -2
  198. package/dist/template/implementations/model_test.template.d.ts.map +1 -1
  199. package/dist/template/implementations/model_test.template.js +2 -2
  200. package/dist/template/implementations/service.template.d.ts +4 -4
  201. package/dist/template/implementations/service.template.d.ts.map +1 -1
  202. package/dist/template/implementations/service.template.js +24 -16
  203. package/dist/template/implementations/view_enums_buttonset.template.d.ts +2 -2
  204. package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +1 -1
  205. package/dist/template/implementations/view_enums_buttonset.template.js +1 -1
  206. package/dist/template/implementations/view_enums_dropdown.template.d.ts +2 -2
  207. package/dist/template/implementations/view_enums_dropdown.template.d.ts.map +1 -1
  208. package/dist/template/implementations/view_enums_dropdown.template.js +2 -2
  209. package/dist/template/implementations/view_enums_select.template.d.ts +2 -2
  210. package/dist/template/implementations/view_enums_select.template.d.ts.map +1 -1
  211. package/dist/template/implementations/view_enums_select.template.js +2 -2
  212. package/dist/template/implementations/view_form.template.d.ts +2 -2
  213. package/dist/template/implementations/view_form.template.d.ts.map +1 -1
  214. package/dist/template/implementations/view_form.template.js +4 -4
  215. package/dist/template/implementations/view_id_all_select.template.d.ts +2 -2
  216. package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -1
  217. package/dist/template/implementations/view_id_all_select.template.js +1 -1
  218. package/dist/template/implementations/view_id_async_select.template.d.ts +2 -2
  219. package/dist/template/implementations/view_id_async_select.template.d.ts.map +1 -1
  220. package/dist/template/implementations/view_id_async_select.template.js +1 -1
  221. package/dist/template/implementations/view_list.template.d.ts +2 -2
  222. package/dist/template/implementations/view_list.template.d.ts.map +1 -1
  223. package/dist/template/implementations/view_list.template.js +29 -19
  224. package/dist/template/implementations/view_list_columns.template.d.ts +3 -3
  225. package/dist/template/implementations/view_list_columns.template.d.ts.map +1 -1
  226. package/dist/template/implementations/view_list_columns.template.js +1 -1
  227. package/dist/template/implementations/view_search_input.template.d.ts +2 -2
  228. package/dist/template/implementations/view_search_input.template.d.ts.map +1 -1
  229. package/dist/template/implementations/view_search_input.template.js +1 -1
  230. package/dist/template/index.d.ts +4 -2
  231. package/dist/template/index.d.ts.map +1 -1
  232. package/dist/template/index.js +5 -3
  233. package/dist/template/template-manager.d.ts +56 -0
  234. package/dist/template/template-manager.d.ts.map +1 -0
  235. package/dist/template/template-manager.js +125 -0
  236. package/dist/template/template-types.d.ts +16 -0
  237. package/dist/template/template-types.d.ts.map +1 -0
  238. package/dist/template/template-types.js +7 -0
  239. package/dist/template/template.d.ts +12 -2
  240. package/dist/template/template.d.ts.map +1 -1
  241. package/dist/template/template.js +19 -6
  242. package/dist/template/zod-converter.d.ts +40 -7
  243. package/dist/template/zod-converter.d.ts.map +1 -1
  244. package/dist/template/zod-converter.js +341 -58
  245. package/dist/testing/_relation-graph.d.ts +1 -1
  246. package/dist/testing/_relation-graph.d.ts.map +1 -1
  247. package/dist/testing/_relation-graph.js +12 -3
  248. package/dist/testing/fixture-manager.d.ts +42 -11
  249. package/dist/testing/fixture-manager.d.ts.map +1 -1
  250. package/dist/testing/fixture-manager.js +338 -236
  251. package/dist/types/types.d.ts +709 -104
  252. package/dist/types/types.d.ts.map +1 -1
  253. package/dist/types/types.js +309 -52
  254. package/dist/typings/knex.d.js +2 -2
  255. package/dist/utils/async-utils.d.ts.map +1 -1
  256. package/dist/utils/async-utils.js +3 -3
  257. package/dist/utils/console-util.js +1 -1
  258. package/dist/utils/controller.d.ts +1 -0
  259. package/dist/utils/controller.d.ts.map +1 -1
  260. package/dist/utils/controller.js +4 -1
  261. package/dist/utils/esm-utils.d.ts +0 -6
  262. package/dist/utils/esm-utils.d.ts.map +1 -1
  263. package/dist/utils/esm-utils.js +2 -9
  264. package/dist/utils/formatter.d.ts +3 -0
  265. package/dist/utils/formatter.d.ts.map +1 -0
  266. package/dist/utils/formatter.js +110 -0
  267. package/dist/utils/fs-utils.d.ts +1 -1
  268. package/dist/utils/fs-utils.d.ts.map +1 -1
  269. package/dist/utils/fs-utils.js +1 -1
  270. package/dist/utils/lodash-able.d.ts.map +1 -1
  271. package/dist/utils/lodash-able.js +1 -1
  272. package/dist/utils/object-utils.d.ts +44 -0
  273. package/dist/utils/object-utils.d.ts.map +1 -0
  274. package/dist/utils/object-utils.js +191 -0
  275. package/dist/utils/path-utils.d.ts +1 -1
  276. package/dist/utils/path-utils.d.ts.map +1 -1
  277. package/dist/utils/path-utils.js +3 -3
  278. package/dist/utils/process-utils.js +1 -1
  279. package/dist/utils/sql-parser.d.ts +5 -1
  280. package/dist/utils/sql-parser.d.ts.map +1 -1
  281. package/dist/utils/sql-parser.js +14 -3
  282. package/dist/utils/type-utils.d.ts +23 -0
  283. package/dist/utils/type-utils.d.ts.map +1 -0
  284. package/dist/utils/type-utils.js +45 -0
  285. package/dist/utils/utils.d.ts +7 -1
  286. package/dist/utils/utils.d.ts.map +1 -1
  287. package/dist/utils/utils.js +44 -5
  288. package/dist/utils/zod-error.d.ts +1 -1
  289. package/dist/utils/zod-error.d.ts.map +1 -1
  290. package/dist/utils/zod-error.js +1 -1
  291. package/package.json +54 -29
  292. package/src/ai/agents/agent.ts +87 -0
  293. package/src/ai/agents/index.ts +2 -0
  294. package/src/ai/agents/types.ts +47 -0
  295. package/src/ai/index.ts +1 -0
  296. package/src/ai/providers/rtzr/api.ts +37 -0
  297. package/src/ai/providers/rtzr/error.ts +34 -0
  298. package/src/ai/providers/rtzr/index.ts +4 -0
  299. package/src/ai/providers/rtzr/model.ts +201 -0
  300. package/src/ai/providers/rtzr/options.ts +49 -0
  301. package/src/ai/providers/rtzr/provider.ts +91 -0
  302. package/src/ai/providers/rtzr/utils.ts +127 -0
  303. package/src/api/base-frame.ts +4 -2
  304. package/src/api/caster.ts +17 -23
  305. package/src/api/code-converters.ts +176 -533
  306. package/src/api/config.ts +39 -56
  307. package/src/api/context.ts +7 -18
  308. package/src/api/decorators.ts +175 -46
  309. package/src/api/index.ts +2 -2
  310. package/src/api/sonamu.ts +133 -124
  311. package/src/api/validator.ts +83 -0
  312. package/src/bin/build-config.ts +7 -1
  313. package/src/bin/cli.ts +192 -110
  314. package/src/bin/loader-register.ts +38 -0
  315. package/src/database/_batch_update.ts +46 -31
  316. package/src/database/base-model.ts +390 -182
  317. package/src/database/base-model.types.ts +155 -0
  318. package/src/database/code-generator.ts +13 -32
  319. package/src/database/db.ts +36 -50
  320. package/src/database/puri-subset.test-d.ts +471 -0
  321. package/src/database/puri-subset.types.ts +195 -0
  322. package/src/database/puri-wrapper.ts +58 -67
  323. package/src/database/puri.ts +182 -126
  324. package/src/database/puri.types.ts +64 -31
  325. package/src/database/transaction-context.ts +1 -1
  326. package/src/database/upsert-builder.ts +262 -132
  327. package/src/entity/entity-manager.ts +36 -28
  328. package/src/entity/entity.ts +330 -249
  329. package/src/exceptions/error-handler.ts +3 -3
  330. package/src/exceptions/so-exceptions.ts +11 -11
  331. package/src/file-storage/driver.ts +5 -5
  332. package/src/file-storage/file-storage.ts +2 -2
  333. package/src/index.ts +18 -12
  334. package/src/migration/code-generation.ts +185 -172
  335. package/src/migration/migration-set.ts +80 -293
  336. package/src/migration/migrator.ts +182 -425
  337. package/src/migration/mysql-schema-reader.ts.txt +272 -0
  338. package/src/migration/postgresql-schema-reader.ts +310 -0
  339. package/src/migration/types.ts +6 -39
  340. package/src/naite/messaging-types.ts +51 -0
  341. package/src/naite/naite-reporter.ts +128 -0
  342. package/src/naite/naite.ts +378 -33
  343. package/src/shared/web.shared.ts.txt +20 -24
  344. package/src/stream/sse.ts +5 -5
  345. package/src/syncer/api-parser.ts +52 -69
  346. package/src/syncer/checksum.ts +25 -37
  347. package/src/syncer/code-generator.ts +58 -62
  348. package/src/syncer/entity-operations.ts +12 -15
  349. package/src/syncer/file-patterns.ts +2 -2
  350. package/src/syncer/index.ts +4 -4
  351. package/src/syncer/module-loader.ts +28 -25
  352. package/src/syncer/syncer.ts +155 -162
  353. package/src/template/entity-converter.ts +18 -27
  354. package/src/template/helpers.ts +8 -11
  355. package/src/template/implementations/entity.template.ts +6 -6
  356. package/src/template/implementations/generated.template.ts +99 -99
  357. package/src/template/implementations/generated_http.template.ts +21 -54
  358. package/src/template/implementations/generated_sso.template.ts +78 -65
  359. package/src/template/implementations/init_types.template.ts +4 -6
  360. package/src/template/implementations/model.template.ts +47 -38
  361. package/src/template/implementations/model_test.template.ts +3 -3
  362. package/src/template/implementations/service.template.ts +56 -80
  363. package/src/template/implementations/view_enums_buttonset.template.ts +2 -2
  364. package/src/template/implementations/view_enums_dropdown.template.ts +4 -4
  365. package/src/template/implementations/view_enums_select.template.ts +3 -3
  366. package/src/template/implementations/view_form.template.ts +34 -75
  367. package/src/template/implementations/view_id_all_select.template.ts +2 -2
  368. package/src/template/implementations/view_id_async_select.template.ts +9 -23
  369. package/src/template/implementations/view_list.template.ts +54 -95
  370. package/src/template/implementations/view_list_columns.template.ts +4 -10
  371. package/src/template/implementations/view_search_input.template.ts +2 -2
  372. package/src/template/index.ts +4 -2
  373. package/src/template/template-manager.ts +166 -0
  374. package/src/template/template-types.ts +16 -0
  375. package/src/template/template.ts +29 -10
  376. package/src/template/zod-converter.ts +407 -101
  377. package/src/testing/_relation-graph.ts +18 -11
  378. package/src/testing/fixture-manager.ts +468 -362
  379. package/src/types/types.ts +516 -248
  380. package/src/typings/knex.d.ts +7 -9
  381. package/src/utils/async-utils.ts +8 -12
  382. package/src/utils/console-util.ts +1 -1
  383. package/src/utils/controller.ts +3 -0
  384. package/src/utils/esm-utils.ts +8 -18
  385. package/src/utils/formatter.ts +109 -0
  386. package/src/utils/fs-utils.ts +1 -1
  387. package/src/utils/lodash-able.ts +1 -4
  388. package/src/utils/object-utils.ts +217 -0
  389. package/src/utils/path-utils.ts +3 -6
  390. package/src/utils/process-utils.ts +1 -1
  391. package/src/utils/sql-parser.ts +23 -5
  392. package/src/utils/type-utils.ts +83 -0
  393. package/src/utils/utils.ts +58 -9
  394. package/src/utils/zod-error.ts +3 -3
  395. package/dist/bin/cli-wrapper.d.ts +0 -3
  396. package/dist/bin/cli-wrapper.d.ts.map +0 -1
  397. package/dist/bin/cli-wrapper.js +0 -72
  398. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts +0 -2
  399. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts.map +0 -1
  400. package/dist/database/knex-plugins/knex-on-duplicate-update.js +0 -39
  401. package/dist/entity/entity-utils.d.ts +0 -61
  402. package/dist/entity/entity-utils.d.ts.map +0 -1
  403. package/dist/entity/entity-utils.js +0 -210
  404. package/src/bin/cli-wrapper.ts +0 -82
  405. package/src/database/knex-plugins/knex-on-duplicate-update.ts +0 -45
  406. package/src/entity/entity-utils.ts +0 -291
@@ -1 +1 @@
1
- {"version":3,"file":"sonamu.d.ts","sourceRoot":"","sources":["../../src/api/sonamu.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sonamu.d.ts","sourceRoot":"","sources":["../../src/api/sonamu.ts"],"names":[],"mappings":"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"}
@@ -1,29 +1,7 @@
1
+ import assert from "assert";
1
2
  import { AsyncLocalStorage } from "async_hooks";
2
- import chalk from "chalk";
3
- import fastify from "fastify";
4
- import { readFile } from "node:fs/promises";
5
3
  import path from "path";
6
- import { exists } from "../utils/fs-utils.js";
7
- import chokidar from "chokidar";
8
- import { formatInTimeZone } from "date-fns-tz";
9
- import { ZodError } from "zod";
10
- import { DB } from "../database/db.js";
11
- import { attachOnDuplicateUpdate } from "../database/knex-plugins/knex-on-duplicate-update.js";
12
- import { BadRequestException, NotFoundException } from "../exceptions/so-exceptions.js";
13
- import { createSSEFactory } from "../stream/sse.js";
14
- import { ApiParamType } from "../types/types.js";
15
- import { isLocal, isTest } from "../utils/controller.js";
16
- import { findApiRootPath } from "../utils/utils.js";
17
- import { humanizeZodError } from "../utils/zod-error.js";
18
- import { fastifyCaster } from "./caster.js";
19
- import { getZodObjectFromApi } from "./code-converters.js";
20
- import fastifyPassport from "@fastify/passport";
21
- import { loadConfig } from "./config.js";
22
- import { isHotReloadServer } from "../utils/esm-utils.js";
23
- import { Template } from "../template/index.js";
24
- import assert from "assert";
25
- import { centerText } from "../utils/console-util.js";
26
- import { BaseModel } from "../database/base-model.js";
4
+ import { Naite } from "../naite/naite.js";
27
5
  class SonamuClass {
28
6
  isInitialized = false;
29
7
  asyncLocalStorage = new AsyncLocalStorage();
@@ -40,6 +18,7 @@ class SonamuClass {
40
18
  reply: null,
41
19
  headers: {},
42
20
  createSSE: ()=>{},
21
+ // biome-ignore lint/suspicious/noExplicitAny: 테스팅 환경에서 컨텍스트가 주입되지 않은 경우 빈 컨텍스트 리턴
43
22
  naiteStore: new Map()
44
23
  };
45
24
  } else {
@@ -122,18 +101,29 @@ class SonamuClass {
122
101
  if (this.isInitialized) {
123
102
  return;
124
103
  }
125
- !doSilent && console.time(chalk.cyan(`Sonamu.init${forTesting ? " for testing" : ""}`));
104
+ if (!doSilent) {
105
+ const chalk = (await import("chalk")).default;
106
+ console.time(chalk.cyan(`Sonamu.init${forTesting ? " for testing" : ""}`));
107
+ }
126
108
  // API 루트 패스
109
+ const { findApiRootPath } = await import("../utils/utils.js");
127
110
  this.apiRootPath = apiRootPath ?? findApiRootPath();
111
+ const { loadConfig } = await import("./config.js");
128
112
  this.config = await loadConfig(this.apiRootPath);
129
- const secretsPath = path.join(this.apiRootPath, "sonamu.secrets.json");
130
- if (await exists(secretsPath)) {
131
- this.secrets = JSON.parse((await readFile(secretsPath)).toString());
113
+ // sonamu.config.ts 기본값 설정
114
+ this.config.database.database = this.config.database.database ?? "postgresql";
115
+ if (process.env.ANTHROPIC_API_KEY) {
116
+ this.secrets = {
117
+ anthropic_api_key: process.env.ANTHROPIC_API_KEY
118
+ };
132
119
  }
133
120
  // DB 로드
121
+ const { DB } = await import("../database/db.js");
134
122
  this.dbConfig = DB.generateDBConfig(this.config.database);
135
- !doSilent && console.log(chalk.green("DB Config Loaded!"));
136
- attachOnDuplicateUpdate();
123
+ if (!doSilent) {
124
+ const chalk = (await import("chalk")).default;
125
+ console.log(chalk.green("DB Config Loaded!"));
126
+ }
137
127
  // 테스팅인 경우 엔티티 로드 & 싱크 없이 중단
138
128
  if (forTesting) {
139
129
  this.isInitialized = true;
@@ -149,20 +139,31 @@ class SonamuClass {
149
139
  await this.syncer.autoloadTypes();
150
140
  await this.syncer.autoloadModels();
151
141
  await this.syncer.autoloadApis();
152
- await Template.autoload();
142
+ const { TemplateManager } = await import("../template/index.js");
143
+ await TemplateManager.autoload();
144
+ const { isLocal, isTest } = await import("../utils/controller.js");
145
+ if (isLocal()) {
146
+ // 로컬에서는 코드 생성을 위해 Biome 셋업이 필요함 (현재 apiRootPath 전달하여 실행)
147
+ (await import("../utils/formatter.js")).setupBiome(this.apiRootPath);
148
+ }
149
+ const { isHotReloadServer } = await import("../utils/controller.js");
153
150
  if (isLocal() && !isTest() && isHotReloadServer() && enableSync) {
154
151
  await this.syncer.sync();
155
- this.startWatcher();
152
+ await this.startWatcher();
156
153
  this.syncer.syncUI();
157
154
  }
158
155
  this.isInitialized = true;
159
- !doSilent && console.timeEnd(chalk.cyan("Sonamu.init"));
156
+ if (!doSilent) {
157
+ const chalk = (await import("chalk")).default;
158
+ console.timeEnd(chalk.cyan("Sonamu.init"));
159
+ }
160
160
  }
161
161
  async createServer(initOptions) {
162
162
  if (this.isInitialized === false) {
163
163
  await this.init(initOptions?.doSilent, initOptions?.enableSync);
164
164
  }
165
165
  const options = this.config.server;
166
+ const fastify = (await import("fastify")).default;
166
167
  const server = fastify(options.fastify);
167
168
  this.server = server;
168
169
  // Storage 설정 저장
@@ -171,13 +172,13 @@ class SonamuClass {
171
172
  }
172
173
  // 플러그인 등록
173
174
  if (options.plugins) {
174
- this.registerPlugins(server, options.plugins);
175
+ await this.registerPlugins(server, options.plugins);
175
176
  }
176
177
  if (options.auth) {
177
178
  if (!options.plugins?.session) {
178
179
  throw new Error("Auth requires session plugin. Please add plugins.session configuration.");
179
180
  }
180
- this.registerAuth(server, options.auth);
181
+ await this.registerAuth(server, options.auth);
181
182
  }
182
183
  // API 라우팅 설정
183
184
  await this.withFastify(server, options.apiConfig, {
@@ -196,9 +197,16 @@ class SonamuClass {
196
197
  // timezone 설정
197
198
  const timezone = this.config.api.timezone;
198
199
  if (timezone) {
199
- const DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssXXX";
200
+ // 타임존에 맞게 응답 날짜 스트링을 변환해주어야 합니다.
201
+ // 가령 timezone이 "Asia/Seoul" 이면
202
+ // "2025-11-21T00:00:00.000Z" 를 "2025-11-21T09:00:00+09:00" 으로 변환해주어야 합니다.
203
+ const { formatInTimeZone } = await import("date-fns-tz");
200
204
  // ISO 8601 날짜 형식 정규식 (예: 2024-01-15T09:30:00.000Z)
201
205
  const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/;
206
+ // T를 둘러싼 작은따옴표가 없다면 "2025-11-19176354618900018:56:29+09:00"와 같은 결과가 나옵니다.
207
+ // 이는 date-fns 특입니다.
208
+ // 이렇게 해도 괜찮습니다. "2025-11-19T18:56:29+09:00" 모양으로 잘 나옵니다.
209
+ const DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssXXX";
202
210
  server.setReplySerializer((payload)=>{
203
211
  return JSON.stringify(payload, (_key, value)=>{
204
212
  if (typeof value === "string" && ISO_DATE_REGEX.test(value)) {
@@ -207,7 +215,10 @@ class SonamuClass {
207
215
  return value;
208
216
  });
209
217
  });
210
- !options?.doSilent && console.log(chalk.green(`Timezone set to ${timezone}`));
218
+ if (!options?.doSilent) {
219
+ const chalk = (await import("chalk")).default;
220
+ console.log(chalk.green(`Timezone set to ${timezone}`));
221
+ }
211
222
  }
212
223
  // 전체 라우팅 리스트
213
224
  server.get(`${this.config.api.route.prefix}/routes`, async (_request, _reply)=>{
@@ -218,42 +229,49 @@ class SonamuClass {
218
229
  return "ok";
219
230
  });
220
231
  // API 라우팅 (로컬HMR 상태와 구분)
232
+ const { isLocal } = await import("../utils/controller.js");
221
233
  if (isLocal()) {
222
- server.all("*", (request, reply)=>{
234
+ server.all("*", async (request, reply)=>{
223
235
  const found = this.syncer.apis.find((api)=>this.config.api.route.prefix + api.path === request.url.split("?")[0] && (api.options.httpMethod ?? "GET") === request.method.toUpperCase());
224
236
  if (found) {
225
237
  return this.getApiHandler(found, config)(request, reply);
226
238
  }
239
+ const { NotFoundException } = await import("../exceptions/so-exceptions.js");
227
240
  throw new NotFoundException("존재하지 않는 API 접근입니다.");
228
241
  });
229
242
  } else {
230
- this.syncer.apis.map((api)=>{
243
+ for (const api of this.syncer.apis){
231
244
  // model
232
245
  if (this.syncer.models[api.modelName] === undefined) {
233
246
  throw new Error(`정의되지 않은 모델에 접근 ${api.modelName}`);
234
247
  }
235
248
  // route
236
249
  server.route({
237
- method: api.options.httpMethod,
250
+ method: api.options.httpMethod ?? "GET",
238
251
  url: this.config.api.route.prefix + api.path,
239
252
  handler: this.getApiHandler(api, config)
240
253
  }); // END server.route
241
- });
254
+ }
242
255
  }
243
256
  }
244
257
  getApiHandler(api, config) {
245
258
  return async (request, reply)=>{
246
259
  (api.options.guards ?? []).every((guard)=>config.guardHandler(guard, request, api));
247
260
  // 파라미터 정보로 zod 스키마 빌드
261
+ const { getZodObjectFromApi } = await import("./code-converters.js");
248
262
  const ReqType = getZodObjectFromApi(api, this.syncer.types);
249
263
  // request 파싱
250
264
  const which = api.options.httpMethod === "GET" ? "query" : "body";
251
265
  let reqBody;
252
266
  try {
267
+ const { fastifyCaster } = await import("./caster.js");
253
268
  reqBody = fastifyCaster(ReqType).parse(request[which] ?? {});
254
269
  } catch (e) {
270
+ const { ZodError } = await import("zod");
255
271
  if (e instanceof ZodError) {
272
+ const { humanizeZodError } = await import("../utils/zod-error.js");
256
273
  const messages = humanizeZodError(e).map((issue)=>issue.message).join(" ");
274
+ const { BadRequestException } = await import("../exceptions/so-exceptions.js");
257
275
  throw new BadRequestException(messages, {
258
276
  zodError: e
259
277
  });
@@ -299,6 +317,7 @@ class SonamuClass {
299
317
  return cachedData;
300
318
  }
301
319
  // createSSEFactory 함수에 미리 request의 socket과 reply를 바인딩.
320
+ const { createSSEFactory } = await import("../stream/sse.js");
302
321
  const createSSE = ((_request, _reply, _events)=>createSSEFactory(_request.socket, _reply, _events)).bind(null, request, reply);
303
322
  const context = {
304
323
  ...await Promise.resolve(config.contextProvider({
@@ -306,7 +325,7 @@ class SonamuClass {
306
325
  reply,
307
326
  headers: request.headers,
308
327
  createSSE,
309
- naiteStore: new Map(),
328
+ naiteStore: Naite.createStore(),
310
329
  // auth
311
330
  user: request.user ?? null,
312
331
  passport: {
@@ -319,6 +338,8 @@ class SonamuClass {
319
338
  return this.asyncLocalStorage.run({
320
339
  context
321
340
  }, async ()=>{
341
+ const { ApiParamType } = await import("../types/types.js");
342
+ // biome-ignore lint/suspicious/noExplicitAny: model은 모델 인스턴스이므로 메서드 호출 가능
322
343
  const result = await model[api.methodName].apply(model, api.parameters.map((param)=>{
323
344
  // Context 인젝션
324
345
  if (ApiParamType.isContext(param.type)) {
@@ -336,11 +357,12 @@ class SonamuClass {
336
357
  });
337
358
  };
338
359
  }
339
- startWatcher() {
360
+ async startWatcher() {
340
361
  const watchPath = [
341
362
  path.join(this.apiRootPath, "src"),
342
363
  path.join(this.apiRootPath, "sonamu.config.ts")
343
364
  ];
365
+ const chokidar = (await import("chokidar")).default;
344
366
  this.watcher = chokidar.watch(watchPath, {
345
367
  ignored: (path, stats)=>!!stats?.isFile() && !path.endsWith(".ts") && !path.endsWith(".json"),
346
368
  persistent: true,
@@ -357,6 +379,7 @@ class SonamuClass {
357
379
  const isConfigTs = filePath === path.join(this.apiRootPath, "sonamu.config.ts");
358
380
  if (isConfigTs) {
359
381
  const relativePath = filePath.replace(this.apiRootPath, "api");
382
+ const chalk = (await import("chalk")).default;
360
383
  console.log(chalk.bold(`Detected(${event}): ${chalk.blue(relativePath)} - Restarting...`));
361
384
  process.kill(process.pid, "SIGUSR2");
362
385
  return;
@@ -377,7 +400,7 @@ class SonamuClass {
377
400
  await this.destroy();
378
401
  }
379
402
  }
380
- registerPlugins(server, plugins) {
403
+ async registerPlugins(server, plugins) {
381
404
  if (!plugins) {
382
405
  return;
383
406
  }
@@ -390,23 +413,25 @@ class SonamuClass {
390
413
  static: "@fastify/static",
391
414
  session: "@fastify/secure-session"
392
415
  };
393
- const registerPlugin = (key, pluginName)=>{
416
+ const registerPlugin = async (key, pluginName)=>{
394
417
  const option = plugins[key];
395
418
  if (!option) return;
396
419
  if (option === true) {
397
- server.register(import(pluginName));
420
+ server.register((await import(pluginName)).default);
398
421
  } else {
399
- server.register(import(pluginName), option);
422
+ server.register((await import(pluginName)).default, option);
400
423
  }
401
424
  };
402
- Object.entries(pluginsModules).forEach(([key, pluginName])=>{
403
- registerPlugin(key, pluginName);
404
- });
425
+ for (const [key, pluginName] of Object.entries(pluginsModules)){
426
+ await registerPlugin(key, pluginName);
427
+ }
405
428
  if (plugins.custom) {
406
429
  plugins.custom(server);
407
430
  }
408
431
  }
409
432
  async registerAuth(server, options) {
433
+ // await import("fastify");
434
+ const fastifyPassport = (await import("@fastify/passport")).default;
410
435
  server.register(fastifyPassport.initialize());
411
436
  server.register(fastifyPassport.secureSession());
412
437
  if (typeof options === "boolean") {
@@ -444,6 +469,7 @@ class SonamuClass {
444
469
  }).then(async ()=>{
445
470
  await options.lifecycle?.onStart?.(server);
446
471
  }).catch(async (err)=>{
472
+ const chalk = (await import("chalk")).default;
447
473
  console.error(chalk.red("Failed to start server:", err));
448
474
  await shutdown();
449
475
  });
@@ -455,6 +481,7 @@ class SonamuClass {
455
481
  }
456
482
  this.pendingFiles.push(filePath);
457
483
  const relativePath = path.relative(this.apiRootPath, filePath);
484
+ const chalk = (await import("chalk")).default;
458
485
  console.log(chalk.bold(`Detected(${event}): ${chalk.blue(relativePath)}`));
459
486
  await this.syncer.syncFromWatcher(event, filePath);
460
487
  // 처리 완료된 파일을 대기 목록에서 제거
@@ -468,10 +495,15 @@ class SonamuClass {
468
495
  await this.syncer.renewChecksums();
469
496
  const endTime = Date.now();
470
497
  const totalTime = endTime - this.hmrStartTime;
498
+ const [chalk, { centerText }] = await Promise.all([
499
+ (await import("chalk")).default,
500
+ import("../utils/console-util.js")
501
+ ]);
471
502
  const msg = `HMR Done! ${chalk.bold.white(`${totalTime}ms`)}`;
472
503
  console.log(chalk.black.bgGreen(centerText(msg)));
473
504
  }
474
505
  async destroy() {
506
+ const { BaseModel } = await import("../database/base-model.js");
475
507
  await BaseModel.destroy();
476
508
  await this.watcher?.close();
477
509
  this.storage?.destroy();
@@ -479,4 +511,4 @@ class SonamuClass {
479
511
  }
480
512
  export const Sonamu = new SonamuClass();
481
513
 
482
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvc29uYW11LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFzeW5jTG9jYWxTdG9yYWdlIH0gZnJvbSBcImFzeW5jX2hvb2tzXCI7XG5pbXBvcnQgY2hhbGsgZnJvbSBcImNoYWxrXCI7XG5pbXBvcnQgZmFzdGlmeSBmcm9tIFwiZmFzdGlmeVwiO1xuaW1wb3J0IHsgcmVhZEZpbGUgfSBmcm9tIFwiZnMvcHJvbWlzZXNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBleGlzdHMgfSBmcm9tIFwiLi4vdXRpbHMvZnMtdXRpbHNcIjtcbmltcG9ydCBjaG9raWRhciwgeyB0eXBlIEZTV2F0Y2hlciB9IGZyb20gXCJjaG9raWRhclwiO1xuaW1wb3J0IHsgZm9ybWF0SW5UaW1lWm9uZSB9IGZyb20gXCJkYXRlLWZucy10elwiO1xuaW1wb3J0IHR5cGUgeyBGYXN0aWZ5SW5zdGFuY2UsIEZhc3RpZnlSZXBseSwgRmFzdGlmeVJlcXVlc3QgfSBmcm9tIFwiZmFzdGlmeVwiO1xuaW1wb3J0IHR5cGUgeyBJbmNvbWluZ01lc3NhZ2UsIFNlcnZlciwgU2VydmVyUmVzcG9uc2UgfSBmcm9tIFwiaHR0cFwiO1xuaW1wb3J0IHsgWm9kRXJyb3IsIFpvZE9iamVjdCB9IGZyb20gXCJ6b2RcIjtcbmltcG9ydCB7IERCLCBTb25hbXVEQkNvbmZpZyB9IGZyb20gXCIuLi9kYXRhYmFzZS9kYlwiO1xuaW1wb3J0IHsgYXR0YWNoT25EdXBsaWNhdGVVcGRhdGUgfSBmcm9tIFwiLi4vZGF0YWJhc2Uva25leC1wbHVnaW5zL2tuZXgtb24tZHVwbGljYXRlLXVwZGF0ZVwiO1xuaW1wb3J0IHtcbiAgQmFkUmVxdWVzdEV4Y2VwdGlvbixcbiAgTm90Rm91bmRFeGNlcHRpb24sXG59IGZyb20gXCIuLi9leGNlcHRpb25zL3NvLWV4Y2VwdGlvbnNcIjtcbmltcG9ydCB0eXBlIHsgRHJpdmVyIH0gZnJvbSBcIi4uL2ZpbGUtc3RvcmFnZS9kcml2ZXJcIjtcbmltcG9ydCB7IGNyZWF0ZVNTRUZhY3RvcnkgfSBmcm9tIFwiLi4vc3RyZWFtL3NzZVwiO1xuaW1wb3J0IHR5cGUgeyBTeW5jZXIgfSBmcm9tIFwiLi4vc3luY2VyL3N5bmNlclwiO1xuaW1wb3J0IHsgQXBpUGFyYW1UeXBlLCBTb25hbXVGYXN0aWZ5Q29uZmlnIH0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQgeyBpc0xvY2FsLCBpc1Rlc3QgfSBmcm9tIFwiLi4vdXRpbHMvY29udHJvbGxlclwiO1xuaW1wb3J0IHsgZmluZEFwaVJvb3RQYXRoIH0gZnJvbSBcIi4uL3V0aWxzL3V0aWxzXCI7XG5pbXBvcnQgeyBodW1hbml6ZVpvZEVycm9yIH0gZnJvbSBcIi4uL3V0aWxzL3pvZC1lcnJvclwiO1xuaW1wb3J0IHsgZmFzdGlmeUNhc3RlciB9IGZyb20gXCIuL2Nhc3RlclwiO1xuaW1wb3J0IHsgZ2V0Wm9kT2JqZWN0RnJvbUFwaSB9IGZyb20gXCIuL2NvZGUtY29udmVydGVyc1wiO1xuaW1wb3J0IHR5cGUgeyBBdXRoQ29udGV4dCwgQ29udGV4dCwgVXBsb2FkQ29udGV4dCB9IGZyb20gXCIuL2NvbnRleHRcIjtcbmltcG9ydCB0eXBlIHsgRXh0ZW5kZWRBcGkgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgZmFzdGlmeVBhc3Nwb3J0IGZyb20gXCJAZmFzdGlmeS9wYXNzcG9ydFwiO1xuaW1wb3J0IHsgbG9hZENvbmZpZywgU29uYW11Q29uZmlnLCBTb25hbXVTZXJ2ZXJPcHRpb25zIH0gZnJvbSBcIi4vY29uZmlnXCI7XG5pbXBvcnQgeyBBYnNvbHV0ZVBhdGggfSBmcm9tIFwiLi4vdXRpbHMvcGF0aC11dGlsc1wiO1xuaW1wb3J0IHsgaXNIb3RSZWxvYWRTZXJ2ZXIgfSBmcm9tIFwiLi4vdXRpbHMvZXNtLXV0aWxzXCI7XG5pbXBvcnQgeyBUZW1wbGF0ZSB9IGZyb20gXCIuLi90ZW1wbGF0ZVwiO1xuaW1wb3J0IGFzc2VydCBmcm9tIFwiYXNzZXJ0XCI7XG5pbXBvcnQgeyBjZW50ZXJUZXh0IH0gZnJvbSBcIi4uL3V0aWxzL2NvbnNvbGUtdXRpbFwiO1xuaW1wb3J0IHsgQmFzZU1vZGVsIH0gZnJvbSBcIi4uL2RhdGFiYXNlL2Jhc2UtbW9kZWxcIjtcblxuZXhwb3J0IHR5cGUgU29uYW11U2VjcmV0cyA9IHtcbiAgW2tleTogc3RyaW5nXTogc3RyaW5nO1xufTtcbmNsYXNzIFNvbmFtdUNsYXNzIHtcbiAgcHVibGljIGlzSW5pdGlhbGl6ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHVibGljIGFzeW5jTG9jYWxTdG9yYWdlOiBBc3luY0xvY2FsU3RvcmFnZTx7XG4gICAgY29udGV4dDogQ29udGV4dDtcbiAgfT4gPSBuZXcgQXN5bmNMb2NhbFN0b3JhZ2UoKTtcblxuICBwdWJsaWMgdXBsb2FkU3RvcmFnZTogQXN5bmNMb2NhbFN0b3JhZ2U8e1xuICAgIHVwbG9hZENvbnRleHQ6IFVwbG9hZENvbnRleHQ7XG4gIH0+ID0gbmV3IEFzeW5jTG9jYWxTdG9yYWdlKCk7XG5cbiAgcHVibGljIGdldENvbnRleHQoKTogQ29udGV4dCB7XG4gICAgY29uc3Qgc3RvcmUgPSB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLmdldFN0b3JlKCk7XG4gICAgaWYgKHN0b3JlPy5jb250ZXh0KSB7XG4gICAgICByZXR1cm4gc3RvcmUuY29udGV4dDtcbiAgICB9XG5cbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwidGVzdFwiKSB7XG4gICAgICAvLyDthYzsiqTtjIUg7ZmY6rK97JeQ7IScIOy7qO2FjeyKpO2KuOqwgCDso7zsnoXrkJjsp4Ag7JWK7J2AIOqyveyasCDruYgg7Luo7YWN7Iqk7Yq4IOumrO2EtFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcmVxdWVzdDogbnVsbCxcbiAgICAgICAgcmVwbHk6IG51bGwsXG4gICAgICAgIGhlYWRlcnM6IHt9LFxuICAgICAgICBjcmVhdGVTU0U6ICgpID0+IHt9LFxuICAgICAgICBuYWl0ZVN0b3JlOiBuZXcgTWFwPHN0cmluZywgYW55PigpLFxuICAgICAgfSBhcyB1bmtub3duIGFzIENvbnRleHQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNvbmFtdSBjYW5ub3QgZmluZCBjb250ZXh0XCIpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBnZXRVcGxvYWRDb250ZXh0KCk6IFVwbG9hZENvbnRleHQge1xuICAgIGNvbnN0IHN0b3JlID0gdGhpcy51cGxvYWRTdG9yYWdlLmdldFN0b3JlKCk7XG4gICAgaWYgKHN0b3JlPy51cGxvYWRDb250ZXh0KSB7XG4gICAgICByZXR1cm4gc3RvcmUudXBsb2FkQ29udGV4dDtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgXCJTb25hbXUgY2Fubm90IGZpbmQgdXBsb2FkIGNvbnRleHQuIERpZCB5b3UgdXNlIEB1cGxvYWQgZGVjb3JhdG9yP1wiXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgX2FwaVJvb3RQYXRoOiBBYnNvbHV0ZVBhdGggfCBudWxsID0gbnVsbDtcbiAgc2V0IGFwaVJvb3RQYXRoKGFwaVJvb3RQYXRoOiBBYnNvbHV0ZVBhdGgpIHtcbiAgICB0aGlzLl9hcGlSb290UGF0aCA9IGFwaVJvb3RQYXRoO1xuICB9XG4gIGdldCBhcGlSb290UGF0aCgpOiBBYnNvbHV0ZVBhdGgge1xuICAgIGlmICh0aGlzLl9hcGlSb290UGF0aCA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2FwaVJvb3RQYXRoITtcbiAgfVxuICBnZXQgYXBwUm9vdFBhdGgoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5hcGlSb290UGF0aC5zcGxpdChwYXRoLnNlcCkuc2xpY2UoMCwgLTEpLmpvaW4ocGF0aC5zZXApO1xuICB9XG5cbiAgcHJpdmF0ZSBfZGJDb25maWc6IFNvbmFtdURCQ29uZmlnIHwgbnVsbCA9IG51bGw7XG4gIHNldCBkYkNvbmZpZyhkYkNvbmZpZzogU29uYW11REJDb25maWcpIHtcbiAgICB0aGlzLl9kYkNvbmZpZyA9IGRiQ29uZmlnO1xuICB9XG4gIGdldCBkYkNvbmZpZygpOiBTb25hbXVEQkNvbmZpZyB7XG4gICAgaWYgKHRoaXMuX2RiQ29uZmlnID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTb25hbXUgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fZGJDb25maWchO1xuICB9XG5cbiAgcHJpdmF0ZSBfc3luY2VyOiBTeW5jZXIgfCBudWxsID0gbnVsbDtcbiAgc2V0IHN5bmNlcihzeW5jZXI6IFN5bmNlcikge1xuICAgIHRoaXMuX3N5bmNlciA9IHN5bmNlcjtcbiAgfVxuICBnZXQgc3luY2VyKCk6IFN5bmNlciB7XG4gICAgaWYgKHRoaXMuX3N5bmNlciA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3N5bmNlciE7XG4gIH1cblxuICBwcml2YXRlIF9jb25maWc6IFNvbmFtdUNvbmZpZyB8IG51bGwgPSBudWxsO1xuICBzZXQgY29uZmlnKGNvbmZpZzogU29uYW11Q29uZmlnKSB7XG4gICAgdGhpcy5fY29uZmlnID0gY29uZmlnO1xuICB9XG4gIGdldCBjb25maWcoKTogU29uYW11Q29uZmlnIHtcbiAgICBpZiAodGhpcy5fY29uZmlnID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTb25hbXUgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY29uZmlnO1xuICB9XG5cbiAgcHJpdmF0ZSBfc2VjcmV0czogU29uYW11U2VjcmV0cyB8IG51bGwgPSBudWxsO1xuICBzZXQgc2VjcmV0cyhzZWNyZXRzOiBTb25hbXVTZWNyZXRzKSB7XG4gICAgdGhpcy5fc2VjcmV0cyA9IHNlY3JldHM7XG4gIH1cbiAgZ2V0IHNlY3JldHMoKTogU29uYW11U2VjcmV0cyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9zZWNyZXRzO1xuICB9XG5cbiAgcHJpdmF0ZSBfc3RvcmFnZTogRHJpdmVyIHwgbnVsbCA9IG51bGw7XG4gIHNldCBzdG9yYWdlKHN0b3JhZ2U6IERyaXZlcikge1xuICAgIHRoaXMuX3N0b3JhZ2UgPSBzdG9yYWdlO1xuICB9XG4gIGdldCBzdG9yYWdlKCk6IERyaXZlciB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9zdG9yYWdlO1xuICB9XG5cbiAgLy8gSE1SIOyymOumrFxuICBwdWJsaWMgd2F0Y2hlcjogRlNXYXRjaGVyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcGVuZGluZ0ZpbGVzOiBzdHJpbmdbXSA9IFtdO1xuICBwcml2YXRlIGhtclN0YXJ0VGltZTogbnVtYmVyID0gMDtcblxuICBwdWJsaWMgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2UgfCBudWxsID0gbnVsbDtcblxuICBhc3luYyBpbml0Rm9yVGVzdGluZygpIHtcbiAgICBhd2FpdCB0aGlzLmluaXQodHJ1ZSwgZmFsc2UsIHVuZGVmaW5lZCwgdHJ1ZSk7XG4gIH1cblxuICBhc3luYyBpbml0KFxuICAgIGRvU2lsZW50OiBib29sZWFuID0gZmFsc2UsXG4gICAgZW5hYmxlU3luYzogYm9vbGVhbiA9IHRydWUsXG4gICAgYXBpUm9vdFBhdGg/OiBBYnNvbHV0ZVBhdGgsXG4gICAgZm9yVGVzdGluZzogYm9vbGVhbiA9IGZhbHNlXG4gICkge1xuICAgIGlmICh0aGlzLmlzSW5pdGlhbGl6ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgIWRvU2lsZW50ICYmXG4gICAgICBjb25zb2xlLnRpbWUoXG4gICAgICAgIGNoYWxrLmN5YW4oYFNvbmFtdS5pbml0JHtmb3JUZXN0aW5nID8gXCIgZm9yIHRlc3RpbmdcIiA6IFwiXCJ9YClcbiAgICAgICk7XG5cbiAgICAvLyBBUEkg66Oo7Yq4IO2MqOyKpFxuICAgIHRoaXMuYXBpUm9vdFBhdGggPSBhcGlSb290UGF0aCA/PyBmaW5kQXBpUm9vdFBhdGgoKTtcbiAgICB0aGlzLmNvbmZpZyA9IGF3YWl0IGxvYWRDb25maWcodGhpcy5hcGlSb290UGF0aCk7XG4gICAgY29uc3Qgc2VjcmV0c1BhdGggPSBwYXRoLmpvaW4odGhpcy5hcGlSb290UGF0aCwgXCJzb25hbXUuc2VjcmV0cy5qc29uXCIpO1xuICAgIGlmIChhd2FpdCBleGlzdHMoc2VjcmV0c1BhdGgpKSB7XG4gICAgICB0aGlzLnNlY3JldHMgPSBKU09OLnBhcnNlKFxuICAgICAgICAoYXdhaXQgcmVhZEZpbGUoc2VjcmV0c1BhdGgpKS50b1N0cmluZygpXG4gICAgICApIGFzIFNvbmFtdVNlY3JldHM7XG4gICAgfVxuXG4gICAgLy8gREIg66Gc65OcXG4gICAgdGhpcy5kYkNvbmZpZyA9IERCLmdlbmVyYXRlREJDb25maWcodGhpcy5jb25maWcuZGF0YWJhc2UpO1xuICAgICFkb1NpbGVudCAmJiBjb25zb2xlLmxvZyhjaGFsay5ncmVlbihcIkRCIENvbmZpZyBMb2FkZWQhXCIpKTtcbiAgICBhdHRhY2hPbkR1cGxpY2F0ZVVwZGF0ZSgpO1xuXG4gICAgLy8g7YWM7Iqk7YyF7J24IOqyveyasCDsl5Tti7Dti7Ag66Gc65OcICYg7Iux7YGsIOyXhuydtCDspJHri6hcbiAgICBpZiAoZm9yVGVzdGluZykge1xuICAgICAgdGhpcy5pc0luaXRpYWxpemVkID0gdHJ1ZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBFbnRpdHkg66Gc65OcXG4gICAgY29uc3QgeyBFbnRpdHlNYW5hZ2VyIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9lbnRpdHkvZW50aXR5LW1hbmFnZXJcIik7XG4gICAgYXdhaXQgRW50aXR5TWFuYWdlci5hdXRvbG9hZChkb1NpbGVudCk7XG5cbiAgICAvLyBTeW5jZXJcbiAgICBjb25zdCB7IFN5bmNlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vc3luY2VyL3N5bmNlclwiKTtcbiAgICB0aGlzLnN5bmNlciA9IG5ldyBTeW5jZXIoKTtcblxuICAgIC8vIEF1dG9sb2FkOiBNb2RlbHMgLyBUeXBlcyAvIEFQSXNcbiAgICBhd2FpdCB0aGlzLnN5bmNlci5hdXRvbG9hZFR5cGVzKCk7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuYXV0b2xvYWRNb2RlbHMoKTtcbiAgICBhd2FpdCB0aGlzLnN5bmNlci5hdXRvbG9hZEFwaXMoKTtcblxuICAgIGF3YWl0IFRlbXBsYXRlLmF1dG9sb2FkKCk7XG5cbiAgICBpZiAoaXNMb2NhbCgpICYmICFpc1Rlc3QoKSAmJiBpc0hvdFJlbG9hZFNlcnZlcigpICYmIGVuYWJsZVN5bmMpIHtcbiAgICAgIGF3YWl0IHRoaXMuc3luY2VyLnN5bmMoKTtcblxuICAgICAgdGhpcy5zdGFydFdhdGNoZXIoKTtcblxuICAgICAgdGhpcy5zeW5jZXIuc3luY1VJKCk7XG4gICAgfVxuXG4gICAgdGhpcy5pc0luaXRpYWxpemVkID0gdHJ1ZTtcbiAgICAhZG9TaWxlbnQgJiYgY29uc29sZS50aW1lRW5kKGNoYWxrLmN5YW4oXCJTb25hbXUuaW5pdFwiKSk7XG4gIH1cblxuICBhc3luYyBjcmVhdGVTZXJ2ZXIoaW5pdE9wdGlvbnM/OiB7XG4gICAgZW5hYmxlU3luYz86IGJvb2xlYW47XG4gICAgZG9TaWxlbnQ/OiBib29sZWFuO1xuICB9KSB7XG4gICAgaWYgKHRoaXMuaXNJbml0aWFsaXplZCA9PT0gZmFsc2UpIHtcbiAgICAgIGF3YWl0IHRoaXMuaW5pdChpbml0T3B0aW9ucz8uZG9TaWxlbnQsIGluaXRPcHRpb25zPy5lbmFibGVTeW5jKTtcbiAgICB9XG5cbiAgICBjb25zdCBvcHRpb25zID0gdGhpcy5jb25maWcuc2VydmVyO1xuICAgIGNvbnN0IHNlcnZlciA9IGZhc3RpZnkob3B0aW9ucy5mYXN0aWZ5KTtcbiAgICB0aGlzLnNlcnZlciA9IHNlcnZlcjtcblxuICAgIC8vIFN0b3JhZ2Ug7ISk7KCVIOyggOyepVxuICAgIGlmIChvcHRpb25zLnN0b3JhZ2UpIHtcbiAgICAgIHRoaXMuc3RvcmFnZSA9IG9wdGlvbnMuc3RvcmFnZTtcbiAgICB9XG5cbiAgICAvLyDtlIzrn6zqt7jsnbgg65Ox66GdXG4gICAgaWYgKG9wdGlvbnMucGx1Z2lucykge1xuICAgICAgdGhpcy5yZWdpc3RlclBsdWdpbnMoc2VydmVyLCBvcHRpb25zLnBsdWdpbnMpO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmF1dGgpIHtcbiAgICAgIGlmICghb3B0aW9ucy5wbHVnaW5zPy5zZXNzaW9uKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBcIkF1dGggcmVxdWlyZXMgc2Vzc2lvbiBwbHVnaW4uIFBsZWFzZSBhZGQgcGx1Z2lucy5zZXNzaW9uIGNvbmZpZ3VyYXRpb24uXCJcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5yZWdpc3RlckF1dGgoc2VydmVyLCBvcHRpb25zLmF1dGgpO1xuICAgIH1cblxuICAgIC8vIEFQSSDrnbzsmrDtjIUg7ISk7KCVXG4gICAgYXdhaXQgdGhpcy53aXRoRmFzdGlmeShzZXJ2ZXIsIG9wdGlvbnMuYXBpQ29uZmlnLCB7XG4gICAgICBlbmFibGVTeW5jOiBpbml0T3B0aW9ucz8uZW5hYmxlU3luYyxcbiAgICAgIGRvU2lsZW50OiBpbml0T3B0aW9ucz8uZG9TaWxlbnQsXG4gICAgfSk7XG5cbiAgICAvLyDshJzrsoQg7Iuc7J6RXG4gICAgYXdhaXQgdGhpcy5ib290KHNlcnZlciwgb3B0aW9ucyk7XG5cbiAgICByZXR1cm4gc2VydmVyO1xuICB9XG5cbiAgYXN5bmMgd2l0aEZhc3RpZnkoXG4gICAgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2U8U2VydmVyLCBJbmNvbWluZ01lc3NhZ2UsIFNlcnZlclJlc3BvbnNlPixcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICAgb3B0aW9ucz86IHtcbiAgICAgIGVuYWJsZVN5bmM/OiBib29sZWFuO1xuICAgICAgZG9TaWxlbnQ/OiBib29sZWFuO1xuICAgIH1cbiAgKSB7XG4gICAgaWYgKHRoaXMuaXNJbml0aWFsaXplZCA9PT0gZmFsc2UpIHtcbiAgICAgIGF3YWl0IHRoaXMuaW5pdChvcHRpb25zPy5kb1NpbGVudCwgb3B0aW9ucz8uZW5hYmxlU3luYyk7XG4gICAgfVxuXG4gICAgdGhpcy5zZXJ2ZXIgPSBzZXJ2ZXI7XG5cbiAgICAvLyB0aW1lem9uZSDshKTsoJVcbiAgICBjb25zdCB0aW1lem9uZSA9IHRoaXMuY29uZmlnLmFwaS50aW1lem9uZTtcbiAgICBpZiAodGltZXpvbmUpIHtcbiAgICAgIGNvbnN0IERBVEVfRk9STUFUID0gXCJ5eXl5LU1NLWRkJ1QnSEg6bW06c3NYWFhcIjtcbiAgICAgIC8vIElTTyA4NjAxIOuCoOynnCDtmJXsi50g7KCV6rec7IudICjsmIg6IDIwMjQtMDEtMTVUMDk6MzA6MDAuMDAwWilcbiAgICAgIGNvbnN0IElTT19EQVRFX1JFR0VYID0gL15cXGR7NH0tXFxkezJ9LVxcZHsyfVRcXGR7Mn06XFxkezJ9OlxcZHsyfShcXC5cXGR7M30pP1okLztcblxuICAgICAgc2VydmVyLnNldFJlcGx5U2VyaWFsaXplcigocGF5bG9hZCkgPT4ge1xuICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkocGF5bG9hZCwgKF9rZXksIHZhbHVlKSA9PiB7XG4gICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiBJU09fREFURV9SRUdFWC50ZXN0KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZvcm1hdEluVGltZVpvbmUobmV3IERhdGUodmFsdWUpLCB0aW1lem9uZSwgREFURV9GT1JNQVQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgICAhb3B0aW9ucz8uZG9TaWxlbnQgJiZcbiAgICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYFRpbWV6b25lIHNldCB0byAke3RpbWV6b25lfWApKTtcbiAgICB9XG5cbiAgICAvLyDsoITssrQg65287Jqw7YyFIOumrOyKpO2KuFxuICAgIHNlcnZlci5nZXQoXG4gICAgICBgJHt0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4fS9yb3V0ZXNgLFxuICAgICAgYXN5bmMgKF9yZXF1ZXN0LCBfcmVwbHkpOiBQcm9taXNlPGFueT4gPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5zeW5jZXIuYXBpcztcbiAgICAgIH1cbiAgICApO1xuXG4gICAgLy8gSGVhbHRoY2hlY2sgQVBJXG4gICAgc2VydmVyLmdldChcbiAgICAgIGAke3RoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXh9L2hlYWx0aGNoZWNrYCxcbiAgICAgIGFzeW5jIChfcmVxdWVzdCwgX3JlcGx5KTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgICAgICAgcmV0dXJuIFwib2tcIjtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgLy8gQVBJIOudvOyasO2MhSAo66Gc7LusSE1SIOyDge2DnOyZgCDqtazrtoQpXG4gICAgaWYgKGlzTG9jYWwoKSkge1xuICAgICAgc2VydmVyLmFsbChcIipcIiwgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IGZvdW5kID0gdGhpcy5zeW5jZXIuYXBpcy5maW5kKFxuICAgICAgICAgIChhcGkpID0+XG4gICAgICAgICAgICB0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4ICsgYXBpLnBhdGggPT09XG4gICAgICAgICAgICAgIHJlcXVlc3QudXJsLnNwbGl0KFwiP1wiKVswXSAmJlxuICAgICAgICAgICAgKGFwaS5vcHRpb25zLmh0dHBNZXRob2QgPz8gXCJHRVRcIikgPT09IHJlcXVlc3QubWV0aG9kLnRvVXBwZXJDYXNlKClcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGZvdW5kKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXBpSGFuZGxlcihmb3VuZCwgY29uZmlnKShyZXF1ZXN0LCByZXBseSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IE5vdEZvdW5kRXhjZXB0aW9uKFwi7KG07J6s7ZWY7KeAIOyViuuKlCBBUEkg7KCR6re87J6F64uI64ukLlwiKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN5bmNlci5hcGlzLm1hcCgoYXBpKSA9PiB7XG4gICAgICAgIC8vIG1vZGVsXG4gICAgICAgIGlmICh0aGlzLnN5bmNlci5tb2RlbHNbYXBpLm1vZGVsTmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihg7KCV7J2Y65CY7KeAIOyViuydgCDrqqjrjbjsl5Ag7KCR6re8ICR7YXBpLm1vZGVsTmFtZX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHJvdXRlXG4gICAgICAgIHNlcnZlci5yb3V0ZSh7XG4gICAgICAgICAgbWV0aG9kOiBhcGkub3B0aW9ucy5odHRwTWV0aG9kISxcbiAgICAgICAgICB1cmw6IHRoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXggKyBhcGkucGF0aCxcbiAgICAgICAgICBoYW5kbGVyOiB0aGlzLmdldEFwaUhhbmRsZXIoYXBpLCBjb25maWcpLFxuICAgICAgICB9KTsgLy8gRU5EIHNlcnZlci5yb3V0ZVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0QXBpSGFuZGxlcihhcGk6IEV4dGVuZGVkQXBpLCBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcpIHtcbiAgICByZXR1cm4gYXN5bmMgKFxuICAgICAgcmVxdWVzdDogRmFzdGlmeVJlcXVlc3QsXG4gICAgICByZXBseTogRmFzdGlmeVJlcGx5XG4gICAgKTogUHJvbWlzZTx1bmtub3duPiA9PiB7XG4gICAgICAoYXBpLm9wdGlvbnMuZ3VhcmRzID8/IFtdKS5ldmVyeSgoZ3VhcmQpID0+XG4gICAgICAgIGNvbmZpZy5ndWFyZEhhbmRsZXIoZ3VhcmQsIHJlcXVlc3QsIGFwaSlcbiAgICAgICk7XG5cbiAgICAgIC8vIO2MjOudvOuvuO2EsCDsoJXrs7TroZwgem9kIOyKpO2CpOuniCDruYzrk5xcbiAgICAgIGNvbnN0IFJlcVR5cGUgPSBnZXRab2RPYmplY3RGcm9tQXBpKGFwaSwgdGhpcy5zeW5jZXIudHlwZXMpO1xuXG4gICAgICAvLyByZXF1ZXN0IO2MjOyLsVxuICAgICAgY29uc3Qgd2hpY2ggPSBhcGkub3B0aW9ucy5odHRwTWV0aG9kID09PSBcIkdFVFwiID8gXCJxdWVyeVwiIDogXCJib2R5XCI7XG4gICAgICBsZXQgcmVxQm9keToge1xuICAgICAgICBba2V5OiBzdHJpbmddOiB1bmtub3duO1xuICAgICAgfTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJlcUJvZHkgPSBmYXN0aWZ5Q2FzdGVyKFJlcVR5cGUpLnBhcnNlKHJlcXVlc3Rbd2hpY2hdID8/IHt9KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBab2RFcnJvcikge1xuICAgICAgICAgIGNvbnN0IG1lc3NhZ2VzID0gaHVtYW5pemVab2RFcnJvcihlKVxuICAgICAgICAgICAgLm1hcCgoaXNzdWUpID0+IGlzc3VlLm1lc3NhZ2UpXG4gICAgICAgICAgICAuam9pbihcIiBcIik7XG4gICAgICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24obWVzc2FnZXMsIHtcbiAgICAgICAgICAgIHpvZEVycm9yOiBlLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gQ29udGVudC1UeXBlXG4gICAgICByZXBseS50eXBlKGFwaS5vcHRpb25zLmNvbnRlbnRUeXBlID8/IFwiYXBwbGljYXRpb24vanNvblwiKTtcblxuICAgICAgLy8g7LqQ7IucXG4gICAgICBjb25zdCB7IGNhY2hlS2V5LCBjYWNoZVR0bCwgY2FjaGVkRGF0YSB9ID0gYXdhaXQgKGFzeW5jICgpID0+IHtcbiAgICAgICAgaWYgKGNvbmZpZy5jYWNoZSkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBjYWNoZUtleVJlcyA9IGNvbmZpZy5jYWNoZS5yZXNvbHZlS2V5KGFwaS5wYXRoLCByZXFCb2R5KTtcbiAgICAgICAgICAgIGlmIChjYWNoZUtleVJlcy5jYWNoZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHsgY2FjaGVLZXk6IG51bGwsIGNhY2hlZERhdGE6IG51bGwgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgY2FjaGVLZXkgPSBjYWNoZUtleVJlcy5rZXk7XG4gICAgICAgICAgICBjb25zdCBjYWNoZVR0bCA9IGNhY2hlS2V5UmVzLnR0bDtcbiAgICAgICAgICAgIGNvbnN0IGNhY2hlZERhdGEgPSBhd2FpdCBjb25maWcuY2FjaGUuZ2V0KGNhY2hlS2V5KTtcbiAgICAgICAgICAgIHJldHVybiB7IGNhY2hlS2V5LCBjYWNoZVR0bCwgY2FjaGVkRGF0YSB9O1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB7IGNhY2hlS2V5OiBudWxsLCBjYWNoZWREYXRhOiBudWxsIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgY2FjaGVLZXk6IG51bGwsIGNhY2hlZERhdGE6IG51bGwgfTtcbiAgICAgIH0pKCk7XG4gICAgICBpZiAoY2FjaGVkRGF0YSAhPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gY2FjaGVkRGF0YTtcbiAgICAgIH1cblxuICAgICAgLy8gY3JlYXRlU1NFRmFjdG9yeSDtlajsiJjsl5Ag66+466asIHJlcXVlc3TsnZggc29ja2V06rO8IHJlcGx566W8IOuwlOyduOuUqS5cbiAgICAgIGNvbnN0IGNyZWF0ZVNTRSA9ICg8VCBleHRlbmRzIFpvZE9iamVjdD4oXG4gICAgICAgIF9yZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCxcbiAgICAgICAgX3JlcGx5OiBGYXN0aWZ5UmVwbHksXG4gICAgICAgIF9ldmVudHM6IFRcbiAgICAgICkgPT4gY3JlYXRlU1NFRmFjdG9yeShfcmVxdWVzdC5zb2NrZXQsIF9yZXBseSwgX2V2ZW50cykpLmJpbmQoXG4gICAgICAgIG51bGwsXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIHJlcGx5XG4gICAgICApO1xuXG4gICAgICBjb25zdCBjb250ZXh0OiBDb250ZXh0ID0ge1xuICAgICAgICAuLi4oYXdhaXQgUHJvbWlzZS5yZXNvbHZlKFxuICAgICAgICAgIGNvbmZpZy5jb250ZXh0UHJvdmlkZXIoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICAgIHJlcGx5LFxuICAgICAgICAgICAgICBoZWFkZXJzOiByZXF1ZXN0LmhlYWRlcnMsXG4gICAgICAgICAgICAgIGNyZWF0ZVNTRSxcbiAgICAgICAgICAgICAgbmFpdGVTdG9yZTogbmV3IE1hcDxzdHJpbmcsIGFueT4oKSxcbiAgICAgICAgICAgICAgLy8gYXV0aFxuICAgICAgICAgICAgICB1c2VyOiByZXF1ZXN0LnVzZXIgPz8gbnVsbCxcbiAgICAgICAgICAgICAgcGFzc3BvcnQ6IHtcbiAgICAgICAgICAgICAgICBsb2dpbjogcmVxdWVzdC5sb2dpbi5iaW5kKFxuICAgICAgICAgICAgICAgICAgcmVxdWVzdFxuICAgICAgICAgICAgICAgICkgYXMgQXV0aENvbnRleHRbXCJwYXNzcG9ydFwiXVtcImxvZ2luXCJdLFxuICAgICAgICAgICAgICAgIGxvZ291dDogcmVxdWVzdC5sb2dvdXQuYmluZChcbiAgICAgICAgICAgICAgICAgIHJlcXVlc3RcbiAgICAgICAgICAgICAgICApIGFzIEF1dGhDb250ZXh0W1wicGFzc3BvcnRcIl1bXCJsb2dvdXRcIl0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIHJlcGx5XG4gICAgICAgICAgKVxuICAgICAgICApKSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1vZGVsID0gdGhpcy5zeW5jZXIubW9kZWxzW2FwaS5tb2RlbE5hbWVdO1xuICAgICAgcmV0dXJuIHRoaXMuYXN5bmNMb2NhbFN0b3JhZ2UucnVuKHsgY29udGV4dCB9LCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IChtb2RlbCBhcyBhbnkpW2FwaS5tZXRob2ROYW1lXS5hcHBseShcbiAgICAgICAgICBtb2RlbCxcbiAgICAgICAgICBhcGkucGFyYW1ldGVycy5tYXAoKHBhcmFtKSA9PiB7XG4gICAgICAgICAgICAvLyBDb250ZXh0IOyduOygneyFmFxuICAgICAgICAgICAgaWYgKEFwaVBhcmFtVHlwZS5pc0NvbnRleHQocGFyYW0udHlwZSkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gcmVxQm9keVtwYXJhbS5uYW1lXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgICByZXBseS50eXBlKGFwaS5vcHRpb25zLmNvbnRlbnRUeXBlID8/IFwiYXBwbGljYXRpb24vanNvblwiKTtcblxuICAgICAgICAvLyDsupDsi5wg7YKkIOyeiOuKlCDqsr3smrAg6rCx7IugIO2bhCDsoIDsnqVcbiAgICAgICAgaWYgKGNvbmZpZy5jYWNoZSAmJiBjYWNoZUtleSkge1xuICAgICAgICAgIGF3YWl0IGNvbmZpZy5jYWNoZS5wdXQoY2FjaGVLZXksIHJlc3VsdCwgY2FjaGVUdGwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICB9O1xuICB9XG5cbiAgc3RhcnRXYXRjaGVyKCk6IHZvaWQge1xuICAgIGNvbnN0IHdhdGNoUGF0aCA9IFtcbiAgICAgIHBhdGguam9pbih0aGlzLmFwaVJvb3RQYXRoLCBcInNyY1wiKSxcbiAgICAgIHBhdGguam9pbih0aGlzLmFwaVJvb3RQYXRoLCBcInNvbmFtdS5jb25maWcudHNcIiksXG4gICAgXTtcblxuICAgIHRoaXMud2F0Y2hlciA9IGNob2tpZGFyLndhdGNoKHdhdGNoUGF0aCwge1xuICAgICAgaWdub3JlZDogKHBhdGgsIHN0YXRzKSA9PlxuICAgICAgICAhIXN0YXRzPy5pc0ZpbGUoKSAmJiAhcGF0aC5lbmRzV2l0aChcIi50c1wiKSAmJiAhcGF0aC5lbmRzV2l0aChcIi5qc29uXCIpLFxuICAgICAgcGVyc2lzdGVudDogdHJ1ZSxcbiAgICAgIGlnbm9yZUluaXRpYWw6IHRydWUsXG4gICAgfSk7XG5cbiAgICB0aGlzLndhdGNoZXIub24oXCJhbGxcIiwgYXN5bmMgKGV2ZW50OiBzdHJpbmcsIGZpbGVQYXRoOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IGFic29sdXRlUGF0aCA9IGZpbGVQYXRoIGFzIEFic29sdXRlUGF0aDtcbiAgICAgIGFzc2VydChcbiAgICAgICAgYWJzb2x1dGVQYXRoLnN0YXJ0c1dpdGgodGhpcy5hcGlSb290UGF0aCksXG4gICAgICAgIFwiRmlsZSBwYXRoIGlzIG5vdCB3aXRoaW4gdGhlIEFQSSByb290IHBhdGhcIlxuICAgICAgKTtcblxuICAgICAgaWYgKGV2ZW50ICE9PSBcImNoYW5nZVwiICYmIGV2ZW50ICE9PSBcImFkZFwiKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gc29uYW11LmNvbmZpZy50cyDrs4Dqsr0g7IucIOyerOyLnOyekVxuICAgICAgICBjb25zdCBpc0NvbmZpZ1RzID1cbiAgICAgICAgICBmaWxlUGF0aCA9PT0gcGF0aC5qb2luKHRoaXMuYXBpUm9vdFBhdGgsIFwic29uYW11LmNvbmZpZy50c1wiKTtcblxuICAgICAgICBpZiAoaXNDb25maWdUcykge1xuICAgICAgICAgIGNvbnN0IHJlbGF0aXZlUGF0aCA9IGZpbGVQYXRoLnJlcGxhY2UodGhpcy5hcGlSb290UGF0aCwgXCJhcGlcIik7XG4gICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICBjaGFsay5ib2xkKFxuICAgICAgICAgICAgICBgRGV0ZWN0ZWQoJHtldmVudH0pOiAke2NoYWxrLmJsdWUocmVsYXRpdmVQYXRoKX0gLSBSZXN0YXJ0aW5nLi4uYFxuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgICAgcHJvY2Vzcy5raWxsKHByb2Nlc3MucGlkLCBcIlNJR1VTUjJcIik7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgdGhpcy5oYW5kbGVGaWxlQ2hhbmdlKGV2ZW50LCBhYnNvbHV0ZVBhdGgpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLypcbiAgICAgQSBmdW5jdGlvbiB0aGF0IGF1dG9tYXRpY2FsbHkgaGFuZGxlcyBpbml0IGFuZCBkZXN0cm95IHdoZW4gdXNpbmcgU29uYW11IHZpYSBzY3JpcHRzLiAgICBcbiAgKi9cbiAgYXN5bmMgcnVuU2NyaXB0KGZuOiAoKSA9PiBQcm9taXNlPHZvaWQ+KSB7XG4gICAgYXdhaXQgdGhpcy5pbml0KHRydWUsIGZhbHNlLCB1bmRlZmluZWQsIGZhbHNlKTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgZm4oKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgdGhpcy5kZXN0cm95KCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWdpc3RlclBsdWdpbnMoXG4gICAgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2UsXG4gICAgcGx1Z2luczogU29uYW11U2VydmVyT3B0aW9uc1tcInBsdWdpbnNcIl1cbiAgKSB7XG4gICAgaWYgKCFwbHVnaW5zKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcGx1Z2luc01vZHVsZXMgPSB7XG4gICAgICBjb3JzOiBcIkBmYXN0aWZ5L2NvcnNcIixcbiAgICAgIGZvcm1ib2R5OiBcIkBmYXN0aWZ5L2Zvcm1ib2R5XCIsXG4gICAgICBtdWx0aXBhcnQ6IFwiQGZhc3RpZnkvbXVsdGlwYXJ0XCIsXG4gICAgICBxczogXCJmYXN0aWZ5LXFzXCIsXG4gICAgICBzc2U6IFwiZmFzdGlmeS1zc2UtdjJcIixcbiAgICAgIHN0YXRpYzogXCJAZmFzdGlmeS9zdGF0aWNcIixcbiAgICAgIHNlc3Npb246IFwiQGZhc3RpZnkvc2VjdXJlLXNlc3Npb25cIixcbiAgICB9IGFzIGNvbnN0O1xuXG4gICAgY29uc3QgcmVnaXN0ZXJQbHVnaW4gPSA8SyBleHRlbmRzIGtleW9mIE5vbk51bGxhYmxlPHR5cGVvZiBwbHVnaW5zPj4oXG4gICAgICBrZXk6IEssXG4gICAgICBwbHVnaW5OYW1lOiBzdHJpbmdcbiAgICApID0+IHtcbiAgICAgIGNvbnN0IG9wdGlvbiA9IHBsdWdpbnNba2V5XTtcbiAgICAgIGlmICghb3B0aW9uKSByZXR1cm47XG5cbiAgICAgIGlmIChvcHRpb24gPT09IHRydWUpIHtcbiAgICAgICAgc2VydmVyLnJlZ2lzdGVyKGltcG9ydChwbHVnaW5OYW1lKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXJ2ZXIucmVnaXN0ZXIoaW1wb3J0KHBsdWdpbk5hbWUpLCBvcHRpb24pO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBPYmplY3QuZW50cmllcyhwbHVnaW5zTW9kdWxlcykuZm9yRWFjaCgoW2tleSwgcGx1Z2luTmFtZV0pID0+IHtcbiAgICAgIHJlZ2lzdGVyUGx1Z2luKGtleSBhcyBrZXlvZiB0eXBlb2YgcGx1Z2lucywgcGx1Z2luTmFtZSk7XG4gICAgfSk7XG5cbiAgICBpZiAocGx1Z2lucy5jdXN0b20pIHtcbiAgICAgIHBsdWdpbnMuY3VzdG9tKHNlcnZlcik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyByZWdpc3RlckF1dGgoXG4gICAgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2UsXG4gICAgb3B0aW9uczogTm9uTnVsbGFibGU8U29uYW11U2VydmVyT3B0aW9uc1tcImF1dGhcIl0+XG4gICkge1xuICAgIHNlcnZlci5yZWdpc3RlcihmYXN0aWZ5UGFzc3BvcnQuaW5pdGlhbGl6ZSgpKTtcbiAgICBzZXJ2ZXIucmVnaXN0ZXIoZmFzdGlmeVBhc3Nwb3J0LnNlY3VyZVNlc3Npb24oKSk7XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09IFwiYm9vbGVhblwiKSB7XG4gICAgICBmYXN0aWZ5UGFzc3BvcnQucmVnaXN0ZXJVc2VyU2VyaWFsaXplcihhc3luYyAodXNlciwgX3JlcXVlc3QpID0+IHVzZXIpO1xuICAgICAgZmFzdGlmeVBhc3Nwb3J0LnJlZ2lzdGVyVXNlckRlc2VyaWFsaXplcihcbiAgICAgICAgYXN5bmMgKHNlcmlhbGl6ZWQsIF9yZXF1ZXN0KSA9PiBzZXJpYWxpemVkXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBmYXN0aWZ5UGFzc3BvcnQucmVnaXN0ZXJVc2VyU2VyaWFsaXplcihvcHRpb25zLnVzZXJTZXJpYWxpemVyKTtcbiAgICAgIGZhc3RpZnlQYXNzcG9ydC5yZWdpc3RlclVzZXJEZXNlcmlhbGl6ZXIob3B0aW9ucy51c2VyRGVzZXJpYWxpemVyKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGJvb3Qoc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2UsIG9wdGlvbnM6IFNvbmFtdVNlcnZlck9wdGlvbnMpIHtcbiAgICBjb25zdCBwb3J0ID0gb3B0aW9ucy5saXN0ZW4/LnBvcnQgPz8gMzAwMDtcbiAgICBjb25zdCBob3N0ID0gb3B0aW9ucy5saXN0ZW4/Lmhvc3QgPz8gXCJsb2NhbGhvc3RcIjtcblxuICAgIHNlcnZlci5hZGRIb29rKFwib25DbG9zZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBvcHRpb25zLmxpZmVjeWNsZT8ub25TaHV0ZG93bj8uKHNlcnZlcik7XG4gICAgICBhd2FpdCB0aGlzLmRlc3Ryb3koKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHNodXRkb3duID0gYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc2VydmVyLmNsb3NlKCk7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3IgZHVyaW5nIHNodXRkb3duOlwiLCBlcnIpO1xuICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHByb2Nlc3Mub24oXCJTSUdJTlRcIiwgc2h1dGRvd24pO1xuICAgIHByb2Nlc3Mub24oXCJTSUdURVJNXCIsIHNodXRkb3duKTtcblxuICAgIGlmIChvcHRpb25zLmxpZmVjeWNsZT8ub25FcnJvcikge1xuICAgICAgc2VydmVyLnNldEVycm9ySGFuZGxlcihvcHRpb25zLmxpZmVjeWNsZT8ub25FcnJvcik7XG4gICAgfVxuXG4gICAgc2VydmVyXG4gICAgICAubGlzdGVuKHsgcG9ydCwgaG9zdCB9KVxuICAgICAgLnRoZW4oYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCBvcHRpb25zLmxpZmVjeWNsZT8ub25TdGFydD8uKHNlcnZlcik7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGFzeW5jIChlcnIpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcihjaGFsay5yZWQoXCJGYWlsZWQgdG8gc3RhcnQgc2VydmVyOlwiLCBlcnIpKTtcbiAgICAgICAgYXdhaXQgc2h1dGRvd24oKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBoYW5kbGVGaWxlQ2hhbmdlKFxuICAgIGV2ZW50OiBzdHJpbmcsXG4gICAgZmlsZVBhdGg6IEFic29sdXRlUGF0aFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyDssqsg67KI7Ke4IO2MjOydvOydtOuptCBITVIg7Iuc7J6RIOyLnOqwhCDquLDroZ1cbiAgICBpZiAodGhpcy5wZW5kaW5nRmlsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLmhtclN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgfVxuICAgIHRoaXMucGVuZGluZ0ZpbGVzLnB1c2goZmlsZVBhdGgpO1xuXG4gICAgY29uc3QgcmVsYXRpdmVQYXRoID0gcGF0aC5yZWxhdGl2ZSh0aGlzLmFwaVJvb3RQYXRoLCBmaWxlUGF0aCk7XG4gICAgY29uc29sZS5sb2coY2hhbGsuYm9sZChgRGV0ZWN0ZWQoJHtldmVudH0pOiAke2NoYWxrLmJsdWUocmVsYXRpdmVQYXRoKX1gKSk7XG5cbiAgICBhd2FpdCB0aGlzLnN5bmNlci5zeW5jRnJvbVdhdGNoZXIoZXZlbnQsIGZpbGVQYXRoKTtcblxuICAgIC8vIOyymOumrCDsmYTro4zrkJwg7YyM7J287J2EIOuMgOq4sCDrqqnroZ3sl5DshJwg7KCc6rGwXG4gICAgdGhpcy5wZW5kaW5nRmlsZXMgPSB0aGlzLnBlbmRpbmdGaWxlcy5zbGljZSgxKTtcblxuICAgIC8vIOuqqOuToCDtjIzsnbwg7LKY66as6rCAIOyZhOujjOuQmOuptCDstZzsooUg66mU7Iuc7KeAIOy2nOugpVxuICAgIGlmICh0aGlzLnBlbmRpbmdGaWxlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGF3YWl0IHRoaXMuZmluaXNoSE1SKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBmaW5pc2hITVIoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIucmVuZXdDaGVja3N1bXMoKTtcblxuICAgIGNvbnN0IGVuZFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IHRvdGFsVGltZSA9IGVuZFRpbWUgLSB0aGlzLmhtclN0YXJ0VGltZTtcbiAgICBjb25zdCBtc2cgPSBgSE1SIERvbmUhICR7Y2hhbGsuYm9sZC53aGl0ZShgJHt0b3RhbFRpbWV9bXNgKX1gO1xuXG4gICAgY29uc29sZS5sb2coY2hhbGsuYmxhY2suYmdHcmVlbihjZW50ZXJUZXh0KG1zZykpKTtcbiAgfVxuXG4gIGFzeW5jIGRlc3Ryb3koKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgQmFzZU1vZGVsLmRlc3Ryb3koKTtcbiAgICBhd2FpdCB0aGlzLndhdGNoZXI/LmNsb3NlKCk7XG4gICAgdGhpcy5zdG9yYWdlPy5kZXN0cm95KCk7XG4gIH1cbn1cbmV4cG9ydCBjb25zdCBTb25hbXUgPSBuZXcgU29uYW11Q2xhc3MoKTtcbiJdLCJuYW1lcyI6WyJBc3luY0xvY2FsU3RvcmFnZSIsImNoYWxrIiwiZmFzdGlmeSIsInJlYWRGaWxlIiwicGF0aCIsImV4aXN0cyIsImNob2tpZGFyIiwiZm9ybWF0SW5UaW1lWm9uZSIsIlpvZEVycm9yIiwiREIiLCJhdHRhY2hPbkR1cGxpY2F0ZVVwZGF0ZSIsIkJhZFJlcXVlc3RFeGNlcHRpb24iLCJOb3RGb3VuZEV4Y2VwdGlvbiIsImNyZWF0ZVNTRUZhY3RvcnkiLCJBcGlQYXJhbVR5cGUiLCJpc0xvY2FsIiwiaXNUZXN0IiwiZmluZEFwaVJvb3RQYXRoIiwiaHVtYW5pemVab2RFcnJvciIsImZhc3RpZnlDYXN0ZXIiLCJnZXRab2RPYmplY3RGcm9tQXBpIiwiZmFzdGlmeVBhc3Nwb3J0IiwibG9hZENvbmZpZyIsImlzSG90UmVsb2FkU2VydmVyIiwiVGVtcGxhdGUiLCJhc3NlcnQiLCJjZW50ZXJUZXh0IiwiQmFzZU1vZGVsIiwiU29uYW11Q2xhc3MiLCJpc0luaXRpYWxpemVkIiwiYXN5bmNMb2NhbFN0b3JhZ2UiLCJ1cGxvYWRTdG9yYWdlIiwiZ2V0Q29udGV4dCIsInN0b3JlIiwiZ2V0U3RvcmUiLCJjb250ZXh0IiwicHJvY2VzcyIsImVudiIsIk5PREVfRU5WIiwicmVxdWVzdCIsInJlcGx5IiwiaGVhZGVycyIsImNyZWF0ZVNTRSIsIm5haXRlU3RvcmUiLCJNYXAiLCJFcnJvciIsImdldFVwbG9hZENvbnRleHQiLCJ1cGxvYWRDb250ZXh0IiwiX2FwaVJvb3RQYXRoIiwiYXBpUm9vdFBhdGgiLCJhcHBSb290UGF0aCIsInNwbGl0Iiwic2VwIiwic2xpY2UiLCJqb2luIiwiX2RiQ29uZmlnIiwiZGJDb25maWciLCJfc3luY2VyIiwic3luY2VyIiwiX2NvbmZpZyIsImNvbmZpZyIsIl9zZWNyZXRzIiwic2VjcmV0cyIsIl9zdG9yYWdlIiwic3RvcmFnZSIsIndhdGNoZXIiLCJwZW5kaW5nRmlsZXMiLCJobXJTdGFydFRpbWUiLCJzZXJ2ZXIiLCJpbml0Rm9yVGVzdGluZyIsImluaXQiLCJ1bmRlZmluZWQiLCJkb1NpbGVudCIsImVuYWJsZVN5bmMiLCJmb3JUZXN0aW5nIiwiY29uc29sZSIsInRpbWUiLCJjeWFuIiwic2VjcmV0c1BhdGgiLCJKU09OIiwicGFyc2UiLCJ0b1N0cmluZyIsImdlbmVyYXRlREJDb25maWciLCJkYXRhYmFzZSIsImxvZyIsImdyZWVuIiwiRW50aXR5TWFuYWdlciIsImF1dG9sb2FkIiwiU3luY2VyIiwiYXV0b2xvYWRUeXBlcyIsImF1dG9sb2FkTW9kZWxzIiwiYXV0b2xvYWRBcGlzIiwic3luYyIsInN0YXJ0V2F0Y2hlciIsInN5bmNVSSIsInRpbWVFbmQiLCJjcmVhdGVTZXJ2ZXIiLCJpbml0T3B0aW9ucyIsIm9wdGlvbnMiLCJwbHVnaW5zIiwicmVnaXN0ZXJQbHVnaW5zIiwiYXV0aCIsInNlc3Npb24iLCJyZWdpc3RlckF1dGgiLCJ3aXRoRmFzdGlmeSIsImFwaUNvbmZpZyIsImJvb3QiLCJ0aW1lem9uZSIsImFwaSIsIkRBVEVfRk9STUFUIiwiSVNPX0RBVEVfUkVHRVgiLCJzZXRSZXBseVNlcmlhbGl6ZXIiLCJwYXlsb2FkIiwic3RyaW5naWZ5IiwiX2tleSIsInZhbHVlIiwidGVzdCIsIkRhdGUiLCJnZXQiLCJyb3V0ZSIsInByZWZpeCIsIl9yZXF1ZXN0IiwiX3JlcGx5IiwiYXBpcyIsImFsbCIsImZvdW5kIiwiZmluZCIsInVybCIsImh0dHBNZXRob2QiLCJtZXRob2QiLCJ0b1VwcGVyQ2FzZSIsImdldEFwaUhhbmRsZXIiLCJtYXAiLCJtb2RlbHMiLCJtb2RlbE5hbWUiLCJoYW5kbGVyIiwiZ3VhcmRzIiwiZXZlcnkiLCJndWFyZCIsImd1YXJkSGFuZGxlciIsIlJlcVR5cGUiLCJ0eXBlcyIsIndoaWNoIiwicmVxQm9keSIsImUiLCJtZXNzYWdlcyIsImlzc3VlIiwibWVzc2FnZSIsInpvZEVycm9yIiwidHlwZSIsImNvbnRlbnRUeXBlIiwiY2FjaGVLZXkiLCJjYWNoZVR0bCIsImNhY2hlZERhdGEiLCJjYWNoZSIsImNhY2hlS2V5UmVzIiwicmVzb2x2ZUtleSIsImtleSIsInR0bCIsImVycm9yIiwiX2V2ZW50cyIsInNvY2tldCIsImJpbmQiLCJQcm9taXNlIiwicmVzb2x2ZSIsImNvbnRleHRQcm92aWRlciIsInVzZXIiLCJwYXNzcG9ydCIsImxvZ2luIiwibG9nb3V0IiwibW9kZWwiLCJydW4iLCJyZXN1bHQiLCJtZXRob2ROYW1lIiwiYXBwbHkiLCJwYXJhbWV0ZXJzIiwicGFyYW0iLCJpc0NvbnRleHQiLCJuYW1lIiwicHV0Iiwid2F0Y2hQYXRoIiwid2F0Y2giLCJpZ25vcmVkIiwic3RhdHMiLCJpc0ZpbGUiLCJlbmRzV2l0aCIsInBlcnNpc3RlbnQiLCJpZ25vcmVJbml0aWFsIiwib24iLCJldmVudCIsImZpbGVQYXRoIiwiYWJzb2x1dGVQYXRoIiwic3RhcnRzV2l0aCIsImlzQ29uZmlnVHMiLCJyZWxhdGl2ZVBhdGgiLCJyZXBsYWNlIiwiYm9sZCIsImJsdWUiLCJraWxsIiwicGlkIiwiaGFuZGxlRmlsZUNoYW5nZSIsInJ1blNjcmlwdCIsImZuIiwiZGVzdHJveSIsInBsdWdpbnNNb2R1bGVzIiwiY29ycyIsImZvcm1ib2R5IiwibXVsdGlwYXJ0IiwicXMiLCJzc2UiLCJzdGF0aWMiLCJyZWdpc3RlclBsdWdpbiIsInBsdWdpbk5hbWUiLCJvcHRpb24iLCJyZWdpc3RlciIsIk9iamVjdCIsImVudHJpZXMiLCJmb3JFYWNoIiwiY3VzdG9tIiwiaW5pdGlhbGl6ZSIsInNlY3VyZVNlc3Npb24iLCJyZWdpc3RlclVzZXJTZXJpYWxpemVyIiwicmVnaXN0ZXJVc2VyRGVzZXJpYWxpemVyIiwic2VyaWFsaXplZCIsInVzZXJTZXJpYWxpemVyIiwidXNlckRlc2VyaWFsaXplciIsInBvcnQiLCJsaXN0ZW4iLCJob3N0IiwiYWRkSG9vayIsImxpZmVjeWNsZSIsIm9uU2h1dGRvd24iLCJzaHV0ZG93biIsImNsb3NlIiwiZXhpdCIsImVyciIsIm9uRXJyb3IiLCJzZXRFcnJvckhhbmRsZXIiLCJ0aGVuIiwib25TdGFydCIsImNhdGNoIiwicmVkIiwibGVuZ3RoIiwibm93IiwicHVzaCIsInJlbGF0aXZlIiwic3luY0Zyb21XYXRjaGVyIiwiZmluaXNoSE1SIiwicmVuZXdDaGVja3N1bXMiLCJlbmRUaW1lIiwidG90YWxUaW1lIiwibXNnIiwid2hpdGUiLCJibGFjayIsImJnR3JlZW4iLCJTb25hbXUiXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLGlCQUFpQixRQUFRLGNBQWM7QUFDaEQsT0FBT0MsV0FBVyxRQUFRO0FBQzFCLE9BQU9DLGFBQWEsVUFBVTtBQUM5QixTQUFTQyxRQUFRLFFBQVEsbUJBQWM7QUFDdkMsT0FBT0MsVUFBVSxPQUFPO0FBQ3hCLFNBQVNDLE1BQU0sUUFBUSx1QkFBb0I7QUFDM0MsT0FBT0MsY0FBa0MsV0FBVztBQUNwRCxTQUFTQyxnQkFBZ0IsUUFBUSxjQUFjO0FBRy9DLFNBQVNDLFFBQVEsUUFBbUIsTUFBTTtBQUMxQyxTQUFTQyxFQUFFLFFBQXdCLG9CQUFpQjtBQUNwRCxTQUFTQyx1QkFBdUIsUUFBUSx1REFBb0Q7QUFDNUYsU0FDRUMsbUJBQW1CLEVBQ25CQyxpQkFBaUIsUUFDWixpQ0FBOEI7QUFFckMsU0FBU0MsZ0JBQWdCLFFBQVEsbUJBQWdCO0FBRWpELFNBQVNDLFlBQVksUUFBNkIsb0JBQWlCO0FBQ25FLFNBQVNDLE9BQU8sRUFBRUMsTUFBTSxRQUFRLHlCQUFzQjtBQUN0RCxTQUFTQyxlQUFlLFFBQVEsb0JBQWlCO0FBQ2pELFNBQVNDLGdCQUFnQixRQUFRLHdCQUFxQjtBQUN0RCxTQUFTQyxhQUFhLFFBQVEsY0FBVztBQUN6QyxTQUFTQyxtQkFBbUIsUUFBUSx1QkFBb0I7QUFHeEQsT0FBT0MscUJBQXFCLG9CQUFvQjtBQUNoRCxTQUFTQyxVQUFVLFFBQTJDLGNBQVc7QUFFekUsU0FBU0MsaUJBQWlCLFFBQVEsd0JBQXFCO0FBQ3ZELFNBQVNDLFFBQVEsUUFBUSx1QkFBYztBQUN2QyxPQUFPQyxZQUFZLFNBQVM7QUFDNUIsU0FBU0MsVUFBVSxRQUFRLDJCQUF3QjtBQUNuRCxTQUFTQyxTQUFTLFFBQVEsNEJBQXlCO0FBS25ELE1BQU1DO0lBQ0dDLGdCQUF5QixNQUFNO0lBQy9CQyxvQkFFRixJQUFJOUIsb0JBQW9CO0lBRXRCK0IsZ0JBRUYsSUFBSS9CLG9CQUFvQjtJQUV0QmdDLGFBQXNCO1FBQzNCLE1BQU1DLFFBQVEsSUFBSSxDQUFDSCxpQkFBaUIsQ0FBQ0ksUUFBUTtRQUM3QyxJQUFJRCxPQUFPRSxTQUFTO1lBQ2xCLE9BQU9GLE1BQU1FLE9BQU87UUFDdEI7UUFFQSxJQUFJQyxRQUFRQyxHQUFHLENBQUNDLFFBQVEsS0FBSyxRQUFRO1lBQ25DLHNDQUFzQztZQUN0QyxPQUFPO2dCQUNMQyxTQUFTO2dCQUNUQyxPQUFPO2dCQUNQQyxTQUFTLENBQUM7Z0JBQ1ZDLFdBQVcsS0FBTztnQkFDbEJDLFlBQVksSUFBSUM7WUFDbEI7UUFDRixPQUFPO1lBQ0wsTUFBTSxJQUFJQyxNQUFNO1FBQ2xCO0lBQ0Y7SUFFT0MsbUJBQWtDO1FBQ3ZDLE1BQU1iLFFBQVEsSUFBSSxDQUFDRixhQUFhLENBQUNHLFFBQVE7UUFDekMsSUFBSUQsT0FBT2MsZUFBZTtZQUN4QixPQUFPZCxNQUFNYyxhQUFhO1FBQzVCO1FBQ0EsTUFBTSxJQUFJRixNQUNSO0lBRUo7SUFFUUcsZUFBb0MsS0FBSztJQUNqRCxJQUFJQyxZQUFZQSxXQUF5QixFQUFFO1FBQ3pDLElBQUksQ0FBQ0QsWUFBWSxHQUFHQztJQUN0QjtJQUNBLElBQUlBLGNBQTRCO1FBQzlCLElBQUksSUFBSSxDQUFDRCxZQUFZLEtBQUssTUFBTTtZQUM5QixNQUFNLElBQUlILE1BQU07UUFDbEI7UUFDQSxPQUFPLElBQUksQ0FBQ0csWUFBWTtJQUMxQjtJQUNBLElBQUlFLGNBQXNCO1FBQ3hCLE9BQU8sSUFBSSxDQUFDRCxXQUFXLENBQUNFLEtBQUssQ0FBQy9DLEtBQUtnRCxHQUFHLEVBQUVDLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBR0MsSUFBSSxDQUFDbEQsS0FBS2dELEdBQUc7SUFDcEU7SUFFUUcsWUFBbUMsS0FBSztJQUNoRCxJQUFJQyxTQUFTQSxRQUF3QixFQUFFO1FBQ3JDLElBQUksQ0FBQ0QsU0FBUyxHQUFHQztJQUNuQjtJQUNBLElBQUlBLFdBQTJCO1FBQzdCLElBQUksSUFBSSxDQUFDRCxTQUFTLEtBQUssTUFBTTtZQUMzQixNQUFNLElBQUlWLE1BQU07UUFDbEI7UUFDQSxPQUFPLElBQUksQ0FBQ1UsU0FBUztJQUN2QjtJQUVRRSxVQUF5QixLQUFLO0lBQ3RDLElBQUlDLE9BQU9BLE1BQWMsRUFBRTtRQUN6QixJQUFJLENBQUNELE9BQU8sR0FBR0M7SUFDakI7SUFDQSxJQUFJQSxTQUFpQjtRQUNuQixJQUFJLElBQUksQ0FBQ0QsT0FBTyxLQUFLLE1BQU07WUFDekIsTUFBTSxJQUFJWixNQUFNO1FBQ2xCO1FBQ0EsT0FBTyxJQUFJLENBQUNZLE9BQU87SUFDckI7SUFFUUUsVUFBK0IsS0FBSztJQUM1QyxJQUFJQyxPQUFPQSxNQUFvQixFQUFFO1FBQy9CLElBQUksQ0FBQ0QsT0FBTyxHQUFHQztJQUNqQjtJQUNBLElBQUlBLFNBQXVCO1FBQ3pCLElBQUksSUFBSSxDQUFDRCxPQUFPLEtBQUssTUFBTTtZQUN6QixNQUFNLElBQUlkLE1BQU07UUFDbEI7UUFDQSxPQUFPLElBQUksQ0FBQ2MsT0FBTztJQUNyQjtJQUVRRSxXQUFpQyxLQUFLO0lBQzlDLElBQUlDLFFBQVFBLE9BQXNCLEVBQUU7UUFDbEMsSUFBSSxDQUFDRCxRQUFRLEdBQUdDO0lBQ2xCO0lBQ0EsSUFBSUEsVUFBZ0M7UUFDbEMsT0FBTyxJQUFJLENBQUNELFFBQVE7SUFDdEI7SUFFUUUsV0FBMEIsS0FBSztJQUN2QyxJQUFJQyxRQUFRQSxPQUFlLEVBQUU7UUFDM0IsSUFBSSxDQUFDRCxRQUFRLEdBQUdDO0lBQ2xCO0lBQ0EsSUFBSUEsVUFBeUI7UUFDM0IsT0FBTyxJQUFJLENBQUNELFFBQVE7SUFDdEI7SUFFQSxTQUFTO0lBQ0ZFLFVBQTRCLEtBQUs7SUFDaENDLGVBQXlCLEVBQUUsQ0FBQztJQUM1QkMsZUFBdUIsRUFBRTtJQUUxQkMsU0FBaUMsS0FBSztJQUU3QyxNQUFNQyxpQkFBaUI7UUFDckIsTUFBTSxJQUFJLENBQUNDLElBQUksQ0FBQyxNQUFNLE9BQU9DLFdBQVc7SUFDMUM7SUFFQSxNQUFNRCxLQUNKRSxXQUFvQixLQUFLLEVBQ3pCQyxhQUFzQixJQUFJLEVBQzFCeEIsV0FBMEIsRUFDMUJ5QixhQUFzQixLQUFLLEVBQzNCO1FBQ0EsSUFBSSxJQUFJLENBQUM3QyxhQUFhLEVBQUU7WUFDdEI7UUFDRjtRQUNBLENBQUMyQyxZQUNDRyxRQUFRQyxJQUFJLENBQ1YzRSxNQUFNNEUsSUFBSSxDQUFDLENBQUMsV0FBVyxFQUFFSCxhQUFhLGlCQUFpQixJQUFJO1FBRy9ELFlBQVk7UUFDWixJQUFJLENBQUN6QixXQUFXLEdBQUdBLGVBQWVoQztRQUNsQyxJQUFJLENBQUMyQyxNQUFNLEdBQUcsTUFBTXRDLFdBQVcsSUFBSSxDQUFDMkIsV0FBVztRQUMvQyxNQUFNNkIsY0FBYzFFLEtBQUtrRCxJQUFJLENBQUMsSUFBSSxDQUFDTCxXQUFXLEVBQUU7UUFDaEQsSUFBSSxNQUFNNUMsT0FBT3lFLGNBQWM7WUFDN0IsSUFBSSxDQUFDaEIsT0FBTyxHQUFHaUIsS0FBS0MsS0FBSyxDQUN2QixBQUFDLENBQUEsTUFBTTdFLFNBQVMyRSxZQUFXLEVBQUdHLFFBQVE7UUFFMUM7UUFFQSxRQUFRO1FBQ1IsSUFBSSxDQUFDekIsUUFBUSxHQUFHL0MsR0FBR3lFLGdCQUFnQixDQUFDLElBQUksQ0FBQ3RCLE1BQU0sQ0FBQ3VCLFFBQVE7UUFDeEQsQ0FBQ1gsWUFBWUcsUUFBUVMsR0FBRyxDQUFDbkYsTUFBTW9GLEtBQUssQ0FBQztRQUNyQzNFO1FBRUEsNEJBQTRCO1FBQzVCLElBQUlnRSxZQUFZO1lBQ2QsSUFBSSxDQUFDN0MsYUFBYSxHQUFHO1lBQ3JCO1FBQ0Y7UUFFQSxZQUFZO1FBQ1osTUFBTSxFQUFFeUQsYUFBYSxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUM7UUFDdkMsTUFBTUEsY0FBY0MsUUFBUSxDQUFDZjtRQUU3QixTQUFTO1FBQ1QsTUFBTSxFQUFFZ0IsTUFBTSxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUM7UUFDaEMsSUFBSSxDQUFDOUIsTUFBTSxHQUFHLElBQUk4QjtRQUVsQixrQ0FBa0M7UUFDbEMsTUFBTSxJQUFJLENBQUM5QixNQUFNLENBQUMrQixhQUFhO1FBQy9CLE1BQU0sSUFBSSxDQUFDL0IsTUFBTSxDQUFDZ0MsY0FBYztRQUNoQyxNQUFNLElBQUksQ0FBQ2hDLE1BQU0sQ0FBQ2lDLFlBQVk7UUFFOUIsTUFBTW5FLFNBQVMrRCxRQUFRO1FBRXZCLElBQUl4RSxhQUFhLENBQUNDLFlBQVlPLHVCQUF1QmtELFlBQVk7WUFDL0QsTUFBTSxJQUFJLENBQUNmLE1BQU0sQ0FBQ2tDLElBQUk7WUFFdEIsSUFBSSxDQUFDQyxZQUFZO1lBRWpCLElBQUksQ0FBQ25DLE1BQU0sQ0FBQ29DLE1BQU07UUFDcEI7UUFFQSxJQUFJLENBQUNqRSxhQUFhLEdBQUc7UUFDckIsQ0FBQzJDLFlBQVlHLFFBQVFvQixPQUFPLENBQUM5RixNQUFNNEUsSUFBSSxDQUFDO0lBQzFDO0lBRUEsTUFBTW1CLGFBQWFDLFdBR2xCLEVBQUU7UUFDRCxJQUFJLElBQUksQ0FBQ3BFLGFBQWEsS0FBSyxPQUFPO1lBQ2hDLE1BQU0sSUFBSSxDQUFDeUMsSUFBSSxDQUFDMkIsYUFBYXpCLFVBQVV5QixhQUFheEI7UUFDdEQ7UUFFQSxNQUFNeUIsVUFBVSxJQUFJLENBQUN0QyxNQUFNLENBQUNRLE1BQU07UUFDbEMsTUFBTUEsU0FBU2xFLFFBQVFnRyxRQUFRaEcsT0FBTztRQUN0QyxJQUFJLENBQUNrRSxNQUFNLEdBQUdBO1FBRWQsZ0JBQWdCO1FBQ2hCLElBQUk4QixRQUFRbEMsT0FBTyxFQUFFO1lBQ25CLElBQUksQ0FBQ0EsT0FBTyxHQUFHa0MsUUFBUWxDLE9BQU87UUFDaEM7UUFFQSxVQUFVO1FBQ1YsSUFBSWtDLFFBQVFDLE9BQU8sRUFBRTtZQUNuQixJQUFJLENBQUNDLGVBQWUsQ0FBQ2hDLFFBQVE4QixRQUFRQyxPQUFPO1FBQzlDO1FBRUEsSUFBSUQsUUFBUUcsSUFBSSxFQUFFO1lBQ2hCLElBQUksQ0FBQ0gsUUFBUUMsT0FBTyxFQUFFRyxTQUFTO2dCQUM3QixNQUFNLElBQUl6RCxNQUNSO1lBRUo7WUFFQSxJQUFJLENBQUMwRCxZQUFZLENBQUNuQyxRQUFROEIsUUFBUUcsSUFBSTtRQUN4QztRQUVBLGFBQWE7UUFDYixNQUFNLElBQUksQ0FBQ0csV0FBVyxDQUFDcEMsUUFBUThCLFFBQVFPLFNBQVMsRUFBRTtZQUNoRGhDLFlBQVl3QixhQUFheEI7WUFDekJELFVBQVV5QixhQUFhekI7UUFDekI7UUFFQSxRQUFRO1FBQ1IsTUFBTSxJQUFJLENBQUNrQyxJQUFJLENBQUN0QyxRQUFROEI7UUFFeEIsT0FBTzlCO0lBQ1Q7SUFFQSxNQUFNb0MsWUFDSnBDLE1BQWdFLEVBQ2hFUixNQUEyQixFQUMzQnNDLE9BR0MsRUFDRDtRQUNBLElBQUksSUFBSSxDQUFDckUsYUFBYSxLQUFLLE9BQU87WUFDaEMsTUFBTSxJQUFJLENBQUN5QyxJQUFJLENBQUM0QixTQUFTMUIsVUFBVTBCLFNBQVN6QjtRQUM5QztRQUVBLElBQUksQ0FBQ0wsTUFBTSxHQUFHQTtRQUVkLGNBQWM7UUFDZCxNQUFNdUMsV0FBVyxJQUFJLENBQUMvQyxNQUFNLENBQUNnRCxHQUFHLENBQUNELFFBQVE7UUFDekMsSUFBSUEsVUFBVTtZQUNaLE1BQU1FLGNBQWM7WUFDcEIsbURBQW1EO1lBQ25ELE1BQU1DLGlCQUFpQjtZQUV2QjFDLE9BQU8yQyxrQkFBa0IsQ0FBQyxDQUFDQztnQkFDekIsT0FBT2pDLEtBQUtrQyxTQUFTLENBQUNELFNBQVMsQ0FBQ0UsTUFBTUM7b0JBQ3BDLElBQUksT0FBT0EsVUFBVSxZQUFZTCxlQUFlTSxJQUFJLENBQUNELFFBQVE7d0JBQzNELE9BQU81RyxpQkFBaUIsSUFBSThHLEtBQUtGLFFBQVFSLFVBQVVFO29CQUNyRDtvQkFDQSxPQUFPTTtnQkFDVDtZQUNGO1lBQ0EsQ0FBQ2pCLFNBQVMxQixZQUNSRyxRQUFRUyxHQUFHLENBQUNuRixNQUFNb0YsS0FBSyxDQUFDLENBQUMsZ0JBQWdCLEVBQUVzQixVQUFVO1FBQ3pEO1FBRUEsYUFBYTtRQUNidkMsT0FBT2tELEdBQUcsQ0FDUixHQUFHLElBQUksQ0FBQzFELE1BQU0sQ0FBQ2dELEdBQUcsQ0FBQ1csS0FBSyxDQUFDQyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQ3hDLE9BQU9DLFVBQVVDO1lBQ2YsT0FBTyxJQUFJLENBQUNoRSxNQUFNLENBQUNpRSxJQUFJO1FBQ3pCO1FBR0Ysa0JBQWtCO1FBQ2xCdkQsT0FBT2tELEdBQUcsQ0FDUixHQUFHLElBQUksQ0FBQzFELE1BQU0sQ0FBQ2dELEdBQUcsQ0FBQ1csS0FBSyxDQUFDQyxNQUFNLENBQUMsWUFBWSxDQUFDLEVBQzdDLE9BQU9DLFVBQVVDO1lBQ2YsT0FBTztRQUNUO1FBR0YseUJBQXlCO1FBQ3pCLElBQUkzRyxXQUFXO1lBQ2JxRCxPQUFPd0QsR0FBRyxDQUFDLEtBQUssQ0FBQ3JGLFNBQVNDO2dCQUN4QixNQUFNcUYsUUFBUSxJQUFJLENBQUNuRSxNQUFNLENBQUNpRSxJQUFJLENBQUNHLElBQUksQ0FDakMsQ0FBQ2xCLE1BQ0MsSUFBSSxDQUFDaEQsTUFBTSxDQUFDZ0QsR0FBRyxDQUFDVyxLQUFLLENBQUNDLE1BQU0sR0FBR1osSUFBSXhHLElBQUksS0FDckNtQyxRQUFRd0YsR0FBRyxDQUFDNUUsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQzNCLEFBQUN5RCxDQUFBQSxJQUFJVixPQUFPLENBQUM4QixVQUFVLElBQUksS0FBSSxNQUFPekYsUUFBUTBGLE1BQU0sQ0FBQ0MsV0FBVztnQkFFcEUsSUFBSUwsT0FBTztvQkFDVCxPQUFPLElBQUksQ0FBQ00sYUFBYSxDQUFDTixPQUFPakUsUUFBUXJCLFNBQVNDO2dCQUNwRDtnQkFDQSxNQUFNLElBQUk1QixrQkFBa0I7WUFDOUI7UUFDRixPQUFPO1lBQ0wsSUFBSSxDQUFDOEMsTUFBTSxDQUFDaUUsSUFBSSxDQUFDUyxHQUFHLENBQUMsQ0FBQ3hCO2dCQUNwQixRQUFRO2dCQUNSLElBQUksSUFBSSxDQUFDbEQsTUFBTSxDQUFDMkUsTUFBTSxDQUFDekIsSUFBSTBCLFNBQVMsQ0FBQyxLQUFLL0QsV0FBVztvQkFDbkQsTUFBTSxJQUFJMUIsTUFBTSxDQUFDLGVBQWUsRUFBRStELElBQUkwQixTQUFTLEVBQUU7Z0JBQ25EO2dCQUVBLFFBQVE7Z0JBQ1JsRSxPQUFPbUQsS0FBSyxDQUFDO29CQUNYVSxRQUFRckIsSUFBSVYsT0FBTyxDQUFDOEIsVUFBVTtvQkFDOUJELEtBQUssSUFBSSxDQUFDbkUsTUFBTSxDQUFDZ0QsR0FBRyxDQUFDVyxLQUFLLENBQUNDLE1BQU0sR0FBR1osSUFBSXhHLElBQUk7b0JBQzVDbUksU0FBUyxJQUFJLENBQUNKLGFBQWEsQ0FBQ3ZCLEtBQUtoRDtnQkFDbkMsSUFBSSxtQkFBbUI7WUFDekI7UUFDRjtJQUNGO0lBRUF1RSxjQUFjdkIsR0FBZ0IsRUFBRWhELE1BQTJCLEVBQUU7UUFDM0QsT0FBTyxPQUNMckIsU0FDQUM7WUFFQ29FLENBQUFBLElBQUlWLE9BQU8sQ0FBQ3NDLE1BQU0sSUFBSSxFQUFFLEFBQUQsRUFBR0MsS0FBSyxDQUFDLENBQUNDLFFBQ2hDOUUsT0FBTytFLFlBQVksQ0FBQ0QsT0FBT25HLFNBQVNxRTtZQUd0QyxzQkFBc0I7WUFDdEIsTUFBTWdDLFVBQVV4SCxvQkFBb0J3RixLQUFLLElBQUksQ0FBQ2xELE1BQU0sQ0FBQ21GLEtBQUs7WUFFMUQsYUFBYTtZQUNiLE1BQU1DLFFBQVFsQyxJQUFJVixPQUFPLENBQUM4QixVQUFVLEtBQUssUUFBUSxVQUFVO1lBQzNELElBQUllO1lBR0osSUFBSTtnQkFDRkEsVUFBVTVILGNBQWN5SCxTQUFTNUQsS0FBSyxDQUFDekMsT0FBTyxDQUFDdUcsTUFBTSxJQUFJLENBQUM7WUFDNUQsRUFBRSxPQUFPRSxHQUFHO2dCQUNWLElBQUlBLGFBQWF4SSxVQUFVO29CQUN6QixNQUFNeUksV0FBVy9ILGlCQUFpQjhILEdBQy9CWixHQUFHLENBQUMsQ0FBQ2MsUUFBVUEsTUFBTUMsT0FBTyxFQUM1QjdGLElBQUksQ0FBQztvQkFDUixNQUFNLElBQUkzQyxvQkFBb0JzSSxVQUFVO3dCQUN0Q0csVUFBVUo7b0JBQ1o7Z0JBQ0YsT0FBTztvQkFDTCxNQUFNQTtnQkFDUjtZQUNGO1lBRUEsZUFBZTtZQUNmeEcsTUFBTTZHLElBQUksQ0FBQ3pDLElBQUlWLE9BQU8sQ0FBQ29ELFdBQVcsSUFBSTtZQUV0QyxLQUFLO1lBQ0wsTUFBTSxFQUFFQyxRQUFRLEVBQUVDLFFBQVEsRUFBRUMsVUFBVSxFQUFFLEdBQUcsTUFBTSxBQUFDLENBQUE7Z0JBQ2hELElBQUk3RixPQUFPOEYsS0FBSyxFQUFFO29CQUNoQixJQUFJO3dCQUNGLE1BQU1DLGNBQWMvRixPQUFPOEYsS0FBSyxDQUFDRSxVQUFVLENBQUNoRCxJQUFJeEcsSUFBSSxFQUFFMkk7d0JBQ3RELElBQUlZLFlBQVlELEtBQUssS0FBSyxPQUFPOzRCQUMvQixPQUFPO2dDQUFFSCxVQUFVO2dDQUFNRSxZQUFZOzRCQUFLO3dCQUM1Qzt3QkFFQSxNQUFNRixXQUFXSSxZQUFZRSxHQUFHO3dCQUNoQyxNQUFNTCxXQUFXRyxZQUFZRyxHQUFHO3dCQUNoQyxNQUFNTCxhQUFhLE1BQU03RixPQUFPOEYsS0FBSyxDQUFDcEMsR0FBRyxDQUFDaUM7d0JBQzFDLE9BQU87NEJBQUVBOzRCQUFVQzs0QkFBVUM7d0JBQVc7b0JBQzFDLEVBQUUsT0FBT1QsR0FBRzt3QkFDVnJFLFFBQVFvRixLQUFLLENBQUNmO29CQUNoQjtvQkFDQSxPQUFPO3dCQUFFTyxVQUFVO3dCQUFNRSxZQUFZO29CQUFLO2dCQUM1QztnQkFDQSxPQUFPO29CQUFFRixVQUFVO29CQUFNRSxZQUFZO2dCQUFLO1lBQzVDLENBQUE7WUFDQSxJQUFJQSxlQUFlLE1BQU07Z0JBQ3ZCLE9BQU9BO1lBQ1Q7WUFFQSx1REFBdUQ7WUFDdkQsTUFBTS9HLFlBQVksQUFBQyxDQUFBLENBQ2pCK0UsVUFDQUMsUUFDQXNDLFVBQ0duSixpQkFBaUI0RyxTQUFTd0MsTUFBTSxFQUFFdkMsUUFBUXNDLFFBQU8sRUFBR0UsSUFBSSxDQUMzRCxNQUNBM0gsU0FDQUM7WUFHRixNQUFNTCxVQUFtQjtnQkFDdkIsR0FBSSxNQUFNZ0ksUUFBUUMsT0FBTyxDQUN2QnhHLE9BQU95RyxlQUFlLENBQ3BCO29CQUNFOUg7b0JBQ0FDO29CQUNBQyxTQUFTRixRQUFRRSxPQUFPO29CQUN4QkM7b0JBQ0FDLFlBQVksSUFBSUM7b0JBQ2hCLE9BQU87b0JBQ1AwSCxNQUFNL0gsUUFBUStILElBQUksSUFBSTtvQkFDdEJDLFVBQVU7d0JBQ1JDLE9BQU9qSSxRQUFRaUksS0FBSyxDQUFDTixJQUFJLENBQ3ZCM0g7d0JBRUZrSSxRQUFRbEksUUFBUWtJLE1BQU0sQ0FBQ1AsSUFBSSxDQUN6QjNIO29CQUVKO2dCQUNGLEdBQ0FBLFNBQ0FDLE9BRUg7WUFDSDtZQUVBLE1BQU1rSSxRQUFRLElBQUksQ0FBQ2hILE1BQU0sQ0FBQzJFLE1BQU0sQ0FBQ3pCLElBQUkwQixTQUFTLENBQUM7WUFDL0MsT0FBTyxJQUFJLENBQUN4RyxpQkFBaUIsQ0FBQzZJLEdBQUcsQ0FBQztnQkFBRXhJO1lBQVEsR0FBRztnQkFDN0MsTUFBTXlJLFNBQVMsTUFBTSxBQUFDRixLQUFhLENBQUM5RCxJQUFJaUUsVUFBVSxDQUFDLENBQUNDLEtBQUssQ0FDdkRKLE9BQ0E5RCxJQUFJbUUsVUFBVSxDQUFDM0MsR0FBRyxDQUFDLENBQUM0QztvQkFDbEIsY0FBYztvQkFDZCxJQUFJbEssYUFBYW1LLFNBQVMsQ0FBQ0QsTUFBTTNCLElBQUksR0FBRzt3QkFDdEMsT0FBT2xIO29CQUNULE9BQU87d0JBQ0wsT0FBTzRHLE9BQU8sQ0FBQ2lDLE1BQU1FLElBQUksQ0FBQztvQkFDNUI7Z0JBQ0Y7Z0JBRUYxSSxNQUFNNkcsSUFBSSxDQUFDekMsSUFBSVYsT0FBTyxDQUFDb0QsV0FBVyxJQUFJO2dCQUV0QyxxQkFBcUI7Z0JBQ3JCLElBQUkxRixPQUFPOEYsS0FBSyxJQUFJSCxVQUFVO29CQUM1QixNQUFNM0YsT0FBTzhGLEtBQUssQ0FBQ3lCLEdBQUcsQ0FBQzVCLFVBQVVxQixRQUFRcEI7Z0JBQzNDO2dCQUNBLE9BQU9vQjtZQUNUO1FBQ0Y7SUFDRjtJQUVBL0UsZUFBcUI7UUFDbkIsTUFBTXVGLFlBQVk7WUFDaEJoTCxLQUFLa0QsSUFBSSxDQUFDLElBQUksQ0FBQ0wsV0FBVyxFQUFFO1lBQzVCN0MsS0FBS2tELElBQUksQ0FBQyxJQUFJLENBQUNMLFdBQVcsRUFBRTtTQUM3QjtRQUVELElBQUksQ0FBQ2dCLE9BQU8sR0FBRzNELFNBQVMrSyxLQUFLLENBQUNELFdBQVc7WUFDdkNFLFNBQVMsQ0FBQ2xMLE1BQU1tTCxRQUNkLENBQUMsQ0FBQ0EsT0FBT0MsWUFBWSxDQUFDcEwsS0FBS3FMLFFBQVEsQ0FBQyxVQUFVLENBQUNyTCxLQUFLcUwsUUFBUSxDQUFDO1lBQy9EQyxZQUFZO1lBQ1pDLGVBQWU7UUFDakI7UUFFQSxJQUFJLENBQUMxSCxPQUFPLENBQUMySCxFQUFFLENBQUMsT0FBTyxPQUFPQyxPQUFlQztZQUMzQyxNQUFNQyxlQUFlRDtZQUNyQnJLLE9BQ0VzSyxhQUFhQyxVQUFVLENBQUMsSUFBSSxDQUFDL0ksV0FBVyxHQUN4QztZQUdGLElBQUk0SSxVQUFVLFlBQVlBLFVBQVUsT0FBTztnQkFDekM7WUFDRjtZQUVBLElBQUk7Z0JBQ0YsNEJBQTRCO2dCQUM1QixNQUFNSSxhQUNKSCxhQUFhMUwsS0FBS2tELElBQUksQ0FBQyxJQUFJLENBQUNMLFdBQVcsRUFBRTtnQkFFM0MsSUFBSWdKLFlBQVk7b0JBQ2QsTUFBTUMsZUFBZUosU0FBU0ssT0FBTyxDQUFDLElBQUksQ0FBQ2xKLFdBQVcsRUFBRTtvQkFDeEQwQixRQUFRUyxHQUFHLENBQ1RuRixNQUFNbU0sSUFBSSxDQUNSLENBQUMsU0FBUyxFQUFFUCxNQUFNLEdBQUcsRUFBRTVMLE1BQU1vTSxJQUFJLENBQUNILGNBQWMsZ0JBQWdCLENBQUM7b0JBR3JFOUosUUFBUWtLLElBQUksQ0FBQ2xLLFFBQVFtSyxHQUFHLEVBQUU7b0JBQzFCO2dCQUNGO2dCQUVBLE1BQU0sSUFBSSxDQUFDQyxnQkFBZ0IsQ0FBQ1gsT0FBT0U7WUFDckMsRUFBRSxPQUFPL0MsR0FBRztnQkFDVnJFLFFBQVFvRixLQUFLLENBQUNmO1lBQ2hCO1FBQ0Y7SUFDRjtJQUVBOztFQUVBLEdBQ0EsTUFBTXlELFVBQVVDLEVBQXVCLEVBQUU7UUFDdkMsTUFBTSxJQUFJLENBQUNwSSxJQUFJLENBQUMsTUFBTSxPQUFPQyxXQUFXO1FBQ3hDLElBQUk7WUFDRixNQUFNbUk7UUFDUixTQUFVO1lBQ1IsTUFBTSxJQUFJLENBQUNDLE9BQU87UUFDcEI7SUFDRjtJQUVRdkcsZ0JBQ05oQyxNQUF1QixFQUN2QitCLE9BQXVDLEVBQ3ZDO1FBQ0EsSUFBSSxDQUFDQSxTQUFTO1lBQ1o7UUFDRjtRQUVBLE1BQU15RyxpQkFBaUI7WUFDckJDLE1BQU07WUFDTkMsVUFBVTtZQUNWQyxXQUFXO1lBQ1hDLElBQUk7WUFDSkMsS0FBSztZQUNMQyxRQUFRO1lBQ1I1RyxTQUFTO1FBQ1g7UUFFQSxNQUFNNkcsaUJBQWlCLENBQ3JCdEQsS0FDQXVEO1lBRUEsTUFBTUMsU0FBU2xILE9BQU8sQ0FBQzBELElBQUk7WUFDM0IsSUFBSSxDQUFDd0QsUUFBUTtZQUViLElBQUlBLFdBQVcsTUFBTTtnQkFDbkJqSixPQUFPa0osUUFBUSxDQUFDLE1BQU0sQ0FBQ0Y7WUFDekIsT0FBTztnQkFDTGhKLE9BQU9rSixRQUFRLENBQUMsTUFBTSxDQUFDRixhQUFhQztZQUN0QztRQUNGO1FBRUFFLE9BQU9DLE9BQU8sQ0FBQ1osZ0JBQWdCYSxPQUFPLENBQUMsQ0FBQyxDQUFDNUQsS0FBS3VELFdBQVc7WUFDdkRELGVBQWV0RCxLQUE2QnVEO1FBQzlDO1FBRUEsSUFBSWpILFFBQVF1SCxNQUFNLEVBQUU7WUFDbEJ2SCxRQUFRdUgsTUFBTSxDQUFDdEo7UUFDakI7SUFDRjtJQUVBLE1BQWNtQyxhQUNabkMsTUFBdUIsRUFDdkI4QixPQUFpRCxFQUNqRDtRQUNBOUIsT0FBT2tKLFFBQVEsQ0FBQ2pNLGdCQUFnQnNNLFVBQVU7UUFDMUN2SixPQUFPa0osUUFBUSxDQUFDak0sZ0JBQWdCdU0sYUFBYTtRQUU3QyxJQUFJLE9BQU8xSCxZQUFZLFdBQVc7WUFDaEM3RSxnQkFBZ0J3TSxzQkFBc0IsQ0FBQyxPQUFPdkQsTUFBTTdDLFdBQWE2QztZQUNqRWpKLGdCQUFnQnlNLHdCQUF3QixDQUN0QyxPQUFPQyxZQUFZdEcsV0FBYXNHO1FBRXBDLE9BQU87WUFDTDFNLGdCQUFnQndNLHNCQUFzQixDQUFDM0gsUUFBUThILGNBQWM7WUFDN0QzTSxnQkFBZ0J5TSx3QkFBd0IsQ0FBQzVILFFBQVErSCxnQkFBZ0I7UUFDbkU7SUFDRjtJQUVBLE1BQWN2SCxLQUFLdEMsTUFBdUIsRUFBRThCLE9BQTRCLEVBQUU7UUFDeEUsTUFBTWdJLE9BQU9oSSxRQUFRaUksTUFBTSxFQUFFRCxRQUFRO1FBQ3JDLE1BQU1FLE9BQU9sSSxRQUFRaUksTUFBTSxFQUFFQyxRQUFRO1FBRXJDaEssT0FBT2lLLE9BQU8sQ0FBQyxXQUFXO1lBQ3hCLE1BQU1uSSxRQUFRb0ksU0FBUyxFQUFFQyxhQUFhbks7WUFDdEMsTUFBTSxJQUFJLENBQUN1SSxPQUFPO1FBQ3BCO1FBRUEsTUFBTTZCLFdBQVc7WUFDZixJQUFJO2dCQUNGLE1BQU1wSyxPQUFPcUssS0FBSztnQkFDbEJyTSxRQUFRc00sSUFBSSxDQUFDO1lBQ2YsRUFBRSxPQUFPQyxLQUFLO2dCQUNaaEssUUFBUW9GLEtBQUssQ0FBQywwQkFBMEI0RTtnQkFDeEN2TSxRQUFRc00sSUFBSSxDQUFDO1lBQ2Y7UUFDRjtRQUVBdE0sUUFBUXdKLEVBQUUsQ0FBQyxVQUFVNEM7UUFDckJwTSxRQUFRd0osRUFBRSxDQUFDLFdBQVc0QztRQUV0QixJQUFJdEksUUFBUW9JLFNBQVMsRUFBRU0sU0FBUztZQUM5QnhLLE9BQU95SyxlQUFlLENBQUMzSSxRQUFRb0ksU0FBUyxFQUFFTTtRQUM1QztRQUVBeEssT0FDRytKLE1BQU0sQ0FBQztZQUFFRDtZQUFNRTtRQUFLLEdBQ3BCVSxJQUFJLENBQUM7WUFDSixNQUFNNUksUUFBUW9JLFNBQVMsRUFBRVMsVUFBVTNLO1FBQ3JDLEdBQ0M0SyxLQUFLLENBQUMsT0FBT0w7WUFDWmhLLFFBQVFvRixLQUFLLENBQUM5SixNQUFNZ1AsR0FBRyxDQUFDLDJCQUEyQk47WUFDbkQsTUFBTUg7UUFDUjtJQUNKO0lBRUEsTUFBY2hDLGlCQUNaWCxLQUFhLEVBQ2JDLFFBQXNCLEVBQ1A7UUFDZix5QkFBeUI7UUFDekIsSUFBSSxJQUFJLENBQUM1SCxZQUFZLENBQUNnTCxNQUFNLEtBQUssR0FBRztZQUNsQyxJQUFJLENBQUMvSyxZQUFZLEdBQUdrRCxLQUFLOEgsR0FBRztRQUM5QjtRQUNBLElBQUksQ0FBQ2pMLFlBQVksQ0FBQ2tMLElBQUksQ0FBQ3REO1FBRXZCLE1BQU1JLGVBQWU5TCxLQUFLaVAsUUFBUSxDQUFDLElBQUksQ0FBQ3BNLFdBQVcsRUFBRTZJO1FBQ3JEbkgsUUFBUVMsR0FBRyxDQUFDbkYsTUFBTW1NLElBQUksQ0FBQyxDQUFDLFNBQVMsRUFBRVAsTUFBTSxHQUFHLEVBQUU1TCxNQUFNb00sSUFBSSxDQUFDSCxlQUFlO1FBRXhFLE1BQU0sSUFBSSxDQUFDeEksTUFBTSxDQUFDNEwsZUFBZSxDQUFDekQsT0FBT0M7UUFFekMsd0JBQXdCO1FBQ3hCLElBQUksQ0FBQzVILFlBQVksR0FBRyxJQUFJLENBQUNBLFlBQVksQ0FBQ2IsS0FBSyxDQUFDO1FBRTVDLDJCQUEyQjtRQUMzQixJQUFJLElBQUksQ0FBQ2EsWUFBWSxDQUFDZ0wsTUFBTSxLQUFLLEdBQUc7WUFDbEMsTUFBTSxJQUFJLENBQUNLLFNBQVM7UUFDdEI7SUFDRjtJQUVBLE1BQWNBLFlBQTJCO1FBQ3ZDLE1BQU0sSUFBSSxDQUFDN0wsTUFBTSxDQUFDOEwsY0FBYztRQUVoQyxNQUFNQyxVQUFVcEksS0FBSzhILEdBQUc7UUFDeEIsTUFBTU8sWUFBWUQsVUFBVSxJQUFJLENBQUN0TCxZQUFZO1FBQzdDLE1BQU13TCxNQUFNLENBQUMsVUFBVSxFQUFFMVAsTUFBTW1NLElBQUksQ0FBQ3dELEtBQUssQ0FBQyxHQUFHRixVQUFVLEVBQUUsQ0FBQyxHQUFHO1FBRTdEL0ssUUFBUVMsR0FBRyxDQUFDbkYsTUFBTTRQLEtBQUssQ0FBQ0MsT0FBTyxDQUFDcE8sV0FBV2lPO0lBQzdDO0lBRUEsTUFBTWhELFVBQXlCO1FBQzdCLE1BQU1oTCxVQUFVZ0wsT0FBTztRQUN2QixNQUFNLElBQUksQ0FBQzFJLE9BQU8sRUFBRXdLO1FBQ3BCLElBQUksQ0FBQ3pLLE9BQU8sRUFBRTJJO0lBQ2hCO0FBQ0Y7QUFDQSxPQUFPLE1BQU1vRCxTQUFTLElBQUluTyxjQUFjIn0=
514
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvc29uYW11LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhc3NlcnQgZnJvbSBcImFzc2VydFwiO1xuaW1wb3J0IHsgQXN5bmNMb2NhbFN0b3JhZ2UgfSBmcm9tIFwiYXN5bmNfaG9va3NcIjtcbmltcG9ydCB0eXBlIHsgRlNXYXRjaGVyIH0gZnJvbSBcImNob2tpZGFyXCI7XG5pbXBvcnQgdHlwZSB7IEZhc3RpZnlJbnN0YW5jZSwgRmFzdGlmeVJlcGx5LCBGYXN0aWZ5UmVxdWVzdCB9IGZyb20gXCJmYXN0aWZ5XCI7XG5pbXBvcnQgdHlwZSB7IEluY29taW5nTWVzc2FnZSwgU2VydmVyLCBTZXJ2ZXJSZXNwb25zZSB9IGZyb20gXCJodHRwXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHR5cGUgeyBab2RPYmplY3QgfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQgdHlwZSB7IFNvbmFtdURCQ29uZmlnIH0gZnJvbSBcIi4uL2RhdGFiYXNlL2RiXCI7XG5pbXBvcnQgdHlwZSB7IERyaXZlciB9IGZyb20gXCIuLi9maWxlLXN0b3JhZ2UvZHJpdmVyXCI7XG5pbXBvcnQgeyBOYWl0ZSB9IGZyb20gXCIuLi9uYWl0ZS9uYWl0ZVwiO1xuaW1wb3J0IHR5cGUgeyBTeW5jZXIgfSBmcm9tIFwiLi4vc3luY2VyL3N5bmNlclwiO1xuaW1wb3J0IHR5cGUgeyBTb25hbXVGYXN0aWZ5Q29uZmlnIH0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQgdHlwZSB7IEFic29sdXRlUGF0aCB9IGZyb20gXCIuLi91dGlscy9wYXRoLXV0aWxzXCI7XG5pbXBvcnQgdHlwZSB7IFNvbmFtdUNvbmZpZywgU29uYW11U2VydmVyT3B0aW9ucyB9IGZyb20gXCIuL2NvbmZpZ1wiO1xuaW1wb3J0IHR5cGUgeyBBdXRoQ29udGV4dCwgQ29udGV4dCwgVXBsb2FkQ29udGV4dCB9IGZyb20gXCIuL2NvbnRleHRcIjtcbmltcG9ydCB0eXBlIHsgRXh0ZW5kZWRBcGkgfSBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5cbmV4cG9ydCB0eXBlIFNvbmFtdVNlY3JldHMgPSB7XG4gIGFudGhyb3BpY19hcGlfa2V5Pzogc3RyaW5nO1xufTtcbmNsYXNzIFNvbmFtdUNsYXNzIHtcbiAgcHVibGljIGlzSW5pdGlhbGl6ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHVibGljIGFzeW5jTG9jYWxTdG9yYWdlOiBBc3luY0xvY2FsU3RvcmFnZTx7XG4gICAgY29udGV4dDogQ29udGV4dDtcbiAgfT4gPSBuZXcgQXN5bmNMb2NhbFN0b3JhZ2UoKTtcblxuICBwdWJsaWMgdXBsb2FkU3RvcmFnZTogQXN5bmNMb2NhbFN0b3JhZ2U8e1xuICAgIHVwbG9hZENvbnRleHQ6IFVwbG9hZENvbnRleHQ7XG4gIH0+ID0gbmV3IEFzeW5jTG9jYWxTdG9yYWdlKCk7XG5cbiAgcHVibGljIGdldENvbnRleHQoKTogQ29udGV4dCB7XG4gICAgY29uc3Qgc3RvcmUgPSB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLmdldFN0b3JlKCk7XG4gICAgaWYgKHN0b3JlPy5jb250ZXh0KSB7XG4gICAgICByZXR1cm4gc3RvcmUuY29udGV4dDtcbiAgICB9XG5cbiAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwidGVzdFwiKSB7XG4gICAgICAvLyDthYzsiqTtjIUg7ZmY6rK97JeQ7IScIOy7qO2FjeyKpO2KuOqwgCDso7zsnoXrkJjsp4Ag7JWK7J2AIOqyveyasCDruYgg7Luo7YWN7Iqk7Yq4IOumrO2EtFxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcmVxdWVzdDogbnVsbCxcbiAgICAgICAgcmVwbHk6IG51bGwsXG4gICAgICAgIGhlYWRlcnM6IHt9LFxuICAgICAgICBjcmVhdGVTU0U6ICgpID0+IHt9LFxuICAgICAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IO2FjOyKpO2MhSDtmZjqsr3sl5DshJwg7Luo7YWN7Iqk7Yq46rCAIOyjvOyeheuQmOyngCDslYrsnYAg6rK97JqwIOu5iCDsu6jthY3siqTtirgg66as7YS0XG4gICAgICAgIG5haXRlU3RvcmU6IG5ldyBNYXA8c3RyaW5nLCBhbnk+KCksXG4gICAgICB9IGFzIHVua25vd24gYXMgQ29udGV4dDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGNhbm5vdCBmaW5kIGNvbnRleHRcIik7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGdldFVwbG9hZENvbnRleHQoKTogVXBsb2FkQ29udGV4dCB7XG4gICAgY29uc3Qgc3RvcmUgPSB0aGlzLnVwbG9hZFN0b3JhZ2UuZ2V0U3RvcmUoKTtcbiAgICBpZiAoc3RvcmU/LnVwbG9hZENvbnRleHQpIHtcbiAgICAgIHJldHVybiBzdG9yZS51cGxvYWRDb250ZXh0O1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJTb25hbXUgY2Fubm90IGZpbmQgdXBsb2FkIGNvbnRleHQuIERpZCB5b3UgdXNlIEB1cGxvYWQgZGVjb3JhdG9yP1wiKTtcbiAgfVxuXG4gIHByaXZhdGUgX2FwaVJvb3RQYXRoOiBBYnNvbHV0ZVBhdGggfCBudWxsID0gbnVsbDtcbiAgc2V0IGFwaVJvb3RQYXRoKGFwaVJvb3RQYXRoOiBBYnNvbHV0ZVBhdGgpIHtcbiAgICB0aGlzLl9hcGlSb290UGF0aCA9IGFwaVJvb3RQYXRoO1xuICB9XG4gIGdldCBhcGlSb290UGF0aCgpOiBBYnNvbHV0ZVBhdGgge1xuICAgIGlmICh0aGlzLl9hcGlSb290UGF0aCA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU29uYW11IGhhcyBub3QgYmVlbiBpbml0aWFsaXplZFwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2FwaVJvb3RQYXRoO1xuICB9XG4gIGdldCBhcHBSb290UGF0aCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmFwaVJvb3RQYXRoLnNwbGl0KHBhdGguc2VwKS5zbGljZSgwLCAtMSkuam9pbihwYXRoLnNlcCk7XG4gIH1cblxuICBwcml2YXRlIF9kYkNvbmZpZzogU29uYW11REJDb25maWcgfCBudWxsID0gbnVsbDtcbiAgc2V0IGRiQ29uZmlnKGRiQ29uZmlnOiBTb25hbXVEQkNvbmZpZykge1xuICAgIHRoaXMuX2RiQ29uZmlnID0gZGJDb25maWc7XG4gIH1cbiAgZ2V0IGRiQ29uZmlnKCk6IFNvbmFtdURCQ29uZmlnIHtcbiAgICBpZiAodGhpcy5fZGJDb25maWcgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNvbmFtdSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRcIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9kYkNvbmZpZztcbiAgfVxuXG4gIHByaXZhdGUgX3N5bmNlcjogU3luY2VyIHwgbnVsbCA9IG51bGw7XG4gIHNldCBzeW5jZXIoc3luY2VyOiBTeW5jZXIpIHtcbiAgICB0aGlzLl9zeW5jZXIgPSBzeW5jZXI7XG4gIH1cbiAgZ2V0IHN5bmNlcigpOiBTeW5jZXIge1xuICAgIGlmICh0aGlzLl9zeW5jZXIgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNvbmFtdSBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWRcIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9zeW5jZXI7XG4gIH1cblxuICBwcml2YXRlIF9jb25maWc6IFNvbmFtdUNvbmZpZyB8IG51bGwgPSBudWxsO1xuICBzZXQgY29uZmlnKGNvbmZpZzogU29uYW11Q29uZmlnKSB7XG4gICAgdGhpcy5fY29uZmlnID0gY29uZmlnO1xuICB9XG4gIGdldCBjb25maWcoKTogU29uYW11Q29uZmlnIHtcbiAgICBpZiAodGhpcy5fY29uZmlnID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTb25hbXUgaGFzIG5vdCBiZWVuIGluaXRpYWxpemVkXCIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY29uZmlnO1xuICB9XG5cbiAgcHJpdmF0ZSBfc2VjcmV0czogU29uYW11U2VjcmV0cyB8IG51bGwgPSBudWxsO1xuICBzZXQgc2VjcmV0cyhzZWNyZXRzOiBTb25hbXVTZWNyZXRzKSB7XG4gICAgdGhpcy5fc2VjcmV0cyA9IHNlY3JldHM7XG4gIH1cbiAgZ2V0IHNlY3JldHMoKTogU29uYW11U2VjcmV0cyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9zZWNyZXRzO1xuICB9XG5cbiAgcHJpdmF0ZSBfc3RvcmFnZTogRHJpdmVyIHwgbnVsbCA9IG51bGw7XG4gIHNldCBzdG9yYWdlKHN0b3JhZ2U6IERyaXZlcikge1xuICAgIHRoaXMuX3N0b3JhZ2UgPSBzdG9yYWdlO1xuICB9XG4gIGdldCBzdG9yYWdlKCk6IERyaXZlciB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLl9zdG9yYWdlO1xuICB9XG5cbiAgLy8gSE1SIOyymOumrFxuICBwdWJsaWMgd2F0Y2hlcjogRlNXYXRjaGVyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcGVuZGluZ0ZpbGVzOiBzdHJpbmdbXSA9IFtdO1xuICBwcml2YXRlIGhtclN0YXJ0VGltZTogbnVtYmVyID0gMDtcblxuICBwdWJsaWMgc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2UgfCBudWxsID0gbnVsbDtcblxuICBhc3luYyBpbml0Rm9yVGVzdGluZygpIHtcbiAgICBhd2FpdCB0aGlzLmluaXQodHJ1ZSwgZmFsc2UsIHVuZGVmaW5lZCwgdHJ1ZSk7XG4gIH1cblxuICBhc3luYyBpbml0KFxuICAgIGRvU2lsZW50OiBib29sZWFuID0gZmFsc2UsXG4gICAgZW5hYmxlU3luYzogYm9vbGVhbiA9IHRydWUsXG4gICAgYXBpUm9vdFBhdGg/OiBBYnNvbHV0ZVBhdGgsXG4gICAgZm9yVGVzdGluZzogYm9vbGVhbiA9IGZhbHNlLFxuICApIHtcbiAgICBpZiAodGhpcy5pc0luaXRpYWxpemVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFkb1NpbGVudCkge1xuICAgICAgY29uc3QgY2hhbGsgPSAoYXdhaXQgaW1wb3J0KFwiY2hhbGtcIikpLmRlZmF1bHQ7XG4gICAgICBjb25zb2xlLnRpbWUoY2hhbGsuY3lhbihgU29uYW11LmluaXQke2ZvclRlc3RpbmcgPyBcIiBmb3IgdGVzdGluZ1wiIDogXCJcIn1gKSk7XG4gICAgfVxuXG4gICAgLy8gQVBJIOujqO2KuCDtjKjsiqRcbiAgICBjb25zdCB7IGZpbmRBcGlSb290UGF0aCB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvdXRpbHNcIik7XG4gICAgdGhpcy5hcGlSb290UGF0aCA9IGFwaVJvb3RQYXRoID8/IGZpbmRBcGlSb290UGF0aCgpO1xuXG4gICAgY29uc3QgeyBsb2FkQ29uZmlnIH0gPSBhd2FpdCBpbXBvcnQoXCIuL2NvbmZpZ1wiKTtcbiAgICB0aGlzLmNvbmZpZyA9IGF3YWl0IGxvYWRDb25maWcodGhpcy5hcGlSb290UGF0aCk7XG4gICAgLy8gc29uYW11LmNvbmZpZy50cyDquLDrs7jqsJIg7ISk7KCVXG4gICAgdGhpcy5jb25maWcuZGF0YWJhc2UuZGF0YWJhc2UgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS5kYXRhYmFzZSA/PyBcInBvc3RncmVzcWxcIjtcblxuICAgIGlmIChwcm9jZXNzLmVudi5BTlRIUk9QSUNfQVBJX0tFWSkge1xuICAgICAgdGhpcy5zZWNyZXRzID0ge1xuICAgICAgICBhbnRocm9waWNfYXBpX2tleTogcHJvY2Vzcy5lbnYuQU5USFJPUElDX0FQSV9LRVksXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIERCIOuhnOuTnFxuICAgIGNvbnN0IHsgREIgfSA9IGF3YWl0IGltcG9ydChcIi4uL2RhdGFiYXNlL2RiXCIpO1xuICAgIHRoaXMuZGJDb25maWcgPSBEQi5nZW5lcmF0ZURCQ29uZmlnKHRoaXMuY29uZmlnLmRhdGFiYXNlKTtcbiAgICBpZiAoIWRvU2lsZW50KSB7XG4gICAgICBjb25zdCBjaGFsayA9IChhd2FpdCBpbXBvcnQoXCJjaGFsa1wiKSkuZGVmYXVsdDtcbiAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmdyZWVuKFwiREIgQ29uZmlnIExvYWRlZCFcIikpO1xuICAgIH1cblxuICAgIC8vIO2FjOyKpO2MheyduCDqsr3smrAg7JeU7Yuw7YuwIOuhnOuTnCAmIOyLse2BrCDsl4bsnbQg7KSR64uoXG4gICAgaWYgKGZvclRlc3RpbmcpIHtcbiAgICAgIHRoaXMuaXNJbml0aWFsaXplZCA9IHRydWU7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gRW50aXR5IOuhnOuTnFxuICAgIGNvbnN0IHsgRW50aXR5TWFuYWdlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vZW50aXR5L2VudGl0eS1tYW5hZ2VyXCIpO1xuICAgIGF3YWl0IEVudGl0eU1hbmFnZXIuYXV0b2xvYWQoZG9TaWxlbnQpO1xuXG4gICAgLy8gU3luY2VyXG4gICAgY29uc3QgeyBTeW5jZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL3N5bmNlci9zeW5jZXJcIik7XG4gICAgdGhpcy5zeW5jZXIgPSBuZXcgU3luY2VyKCk7XG5cbiAgICAvLyBBdXRvbG9hZDogTW9kZWxzIC8gVHlwZXMgLyBBUElzXG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuYXV0b2xvYWRUeXBlcygpO1xuICAgIGF3YWl0IHRoaXMuc3luY2VyLmF1dG9sb2FkTW9kZWxzKCk7XG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuYXV0b2xvYWRBcGlzKCk7XG5cbiAgICBjb25zdCB7IFRlbXBsYXRlTWFuYWdlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdGVtcGxhdGVcIik7XG4gICAgYXdhaXQgVGVtcGxhdGVNYW5hZ2VyLmF1dG9sb2FkKCk7XG5cbiAgICBjb25zdCB7IGlzTG9jYWwsIGlzVGVzdCB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvY29udHJvbGxlclwiKTtcbiAgICBpZiAoaXNMb2NhbCgpKSB7XG4gICAgICAvLyDroZzsu6zsl5DshJzripQg7L2U65OcIOyDneyEseydhCDsnITtlbQgQmlvbWUg7IWL7JeF7J20IO2VhOyalO2VqCAo7ZiE7J6sIGFwaVJvb3RQYXRoIOyghOuLrO2VmOyXrCDsi6TtlokpXG4gICAgICAoYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvZm9ybWF0dGVyXCIpKS5zZXR1cEJpb21lKHRoaXMuYXBpUm9vdFBhdGgpO1xuICAgIH1cblxuICAgIGNvbnN0IHsgaXNIb3RSZWxvYWRTZXJ2ZXIgfSA9IGF3YWl0IGltcG9ydChcIi4uL3V0aWxzL2NvbnRyb2xsZXJcIik7XG4gICAgaWYgKGlzTG9jYWwoKSAmJiAhaXNUZXN0KCkgJiYgaXNIb3RSZWxvYWRTZXJ2ZXIoKSAmJiBlbmFibGVTeW5jKSB7XG4gICAgICBhd2FpdCB0aGlzLnN5bmNlci5zeW5jKCk7XG5cbiAgICAgIGF3YWl0IHRoaXMuc3RhcnRXYXRjaGVyKCk7XG5cbiAgICAgIHRoaXMuc3luY2VyLnN5bmNVSSgpO1xuICAgIH1cblxuICAgIHRoaXMuaXNJbml0aWFsaXplZCA9IHRydWU7XG4gICAgaWYgKCFkb1NpbGVudCkge1xuICAgICAgY29uc3QgY2hhbGsgPSAoYXdhaXQgaW1wb3J0KFwiY2hhbGtcIikpLmRlZmF1bHQ7XG4gICAgICBjb25zb2xlLnRpbWVFbmQoY2hhbGsuY3lhbihcIlNvbmFtdS5pbml0XCIpKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBjcmVhdGVTZXJ2ZXIoaW5pdE9wdGlvbnM/OiB7IGVuYWJsZVN5bmM/OiBib29sZWFuOyBkb1NpbGVudD86IGJvb2xlYW4gfSkge1xuICAgIGlmICh0aGlzLmlzSW5pdGlhbGl6ZWQgPT09IGZhbHNlKSB7XG4gICAgICBhd2FpdCB0aGlzLmluaXQoaW5pdE9wdGlvbnM/LmRvU2lsZW50LCBpbml0T3B0aW9ucz8uZW5hYmxlU3luYyk7XG4gICAgfVxuXG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuY29uZmlnLnNlcnZlcjtcbiAgICBjb25zdCBmYXN0aWZ5ID0gKGF3YWl0IGltcG9ydChcImZhc3RpZnlcIikpLmRlZmF1bHQ7XG4gICAgY29uc3Qgc2VydmVyID0gZmFzdGlmeShvcHRpb25zLmZhc3RpZnkpO1xuICAgIHRoaXMuc2VydmVyID0gc2VydmVyO1xuXG4gICAgLy8gU3RvcmFnZSDshKTsoJUg7KCA7J6lXG4gICAgaWYgKG9wdGlvbnMuc3RvcmFnZSkge1xuICAgICAgdGhpcy5zdG9yYWdlID0gb3B0aW9ucy5zdG9yYWdlO1xuICAgIH1cblxuICAgIC8vIO2UjOufrOq3uOyduCDrk7HroZ1cbiAgICBpZiAob3B0aW9ucy5wbHVnaW5zKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlZ2lzdGVyUGx1Z2lucyhzZXJ2ZXIsIG9wdGlvbnMucGx1Z2lucyk7XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMuYXV0aCkge1xuICAgICAgaWYgKCFvcHRpb25zLnBsdWdpbnM/LnNlc3Npb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQXV0aCByZXF1aXJlcyBzZXNzaW9uIHBsdWdpbi4gUGxlYXNlIGFkZCBwbHVnaW5zLnNlc3Npb24gY29uZmlndXJhdGlvbi5cIik7XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJBdXRoKHNlcnZlciwgb3B0aW9ucy5hdXRoKTtcbiAgICB9XG5cbiAgICAvLyBBUEkg65287Jqw7YyFIOyEpOyglVxuICAgIGF3YWl0IHRoaXMud2l0aEZhc3RpZnkoc2VydmVyLCBvcHRpb25zLmFwaUNvbmZpZywge1xuICAgICAgZW5hYmxlU3luYzogaW5pdE9wdGlvbnM/LmVuYWJsZVN5bmMsXG4gICAgICBkb1NpbGVudDogaW5pdE9wdGlvbnM/LmRvU2lsZW50LFxuICAgIH0pO1xuXG4gICAgLy8g7ISc67KEIOyLnOyekVxuICAgIGF3YWl0IHRoaXMuYm9vdChzZXJ2ZXIsIG9wdGlvbnMpO1xuXG4gICAgcmV0dXJuIHNlcnZlcjtcbiAgfVxuXG4gIGFzeW5jIHdpdGhGYXN0aWZ5KFxuICAgIHNlcnZlcjogRmFzdGlmeUluc3RhbmNlPFNlcnZlciwgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZT4sXG4gICAgY29uZmlnOiBTb25hbXVGYXN0aWZ5Q29uZmlnLFxuICAgIG9wdGlvbnM/OiB7XG4gICAgICBlbmFibGVTeW5jPzogYm9vbGVhbjtcbiAgICAgIGRvU2lsZW50PzogYm9vbGVhbjtcbiAgICB9LFxuICApIHtcbiAgICBpZiAodGhpcy5pc0luaXRpYWxpemVkID09PSBmYWxzZSkge1xuICAgICAgYXdhaXQgdGhpcy5pbml0KG9wdGlvbnM/LmRvU2lsZW50LCBvcHRpb25zPy5lbmFibGVTeW5jKTtcbiAgICB9XG5cbiAgICB0aGlzLnNlcnZlciA9IHNlcnZlcjtcblxuICAgIC8vIHRpbWV6b25lIOyEpOyglVxuICAgIGNvbnN0IHRpbWV6b25lID0gdGhpcy5jb25maWcuYXBpLnRpbWV6b25lO1xuICAgIGlmICh0aW1lem9uZSkge1xuICAgICAgLy8g7YOA7J6E7KG07JeQIOunnuqyjCDsnZHri7Ug64Kg7KecIOyKpO2KuOungeydhCDrs4DtmZjtlbTso7zslrTslbwg7ZWp64uI64ukLlxuICAgICAgLy8g6rCA66C5IHRpbWV6b25l7J20IFwiQXNpYS9TZW91bFwiIOydtOuptFxuICAgICAgLy8gXCIyMDI1LTExLTIxVDAwOjAwOjAwLjAwMFpcIiDrpbwgXCIyMDI1LTExLTIxVDA5OjAwOjAwKzA5OjAwXCIg7Jy866GcIOuzgO2ZmO2VtOyjvOyWtOyVvCDtlanri4jri6QuXG4gICAgICBjb25zdCB7IGZvcm1hdEluVGltZVpvbmUgfSA9IGF3YWl0IGltcG9ydChcImRhdGUtZm5zLXR6XCIpO1xuXG4gICAgICAvLyBJU08gODYwMSDrgqDsp5wg7ZiV7IudIOygleq3nOyLnSAo7JiIOiAyMDI0LTAxLTE1VDA5OjMwOjAwLjAwMFopXG4gICAgICBjb25zdCBJU09fREFURV9SRUdFWCA9IC9eXFxkezR9LVxcZHsyfS1cXGR7Mn1UXFxkezJ9OlxcZHsyfTpcXGR7Mn0oXFwuXFxkezN9KT9aJC87XG5cbiAgICAgIC8vIFTrpbwg65GY65+s7Iu8IOyekeydgOuUsOyYtO2RnOqwgCDsl4bri6TrqbQgXCIyMDI1LTExLTE5MTc2MzU0NjE4OTAwMDE4OjU2OjI5KzA5OjAwXCLsmYAg6rCZ7J2AIOqysOqzvOqwgCDrgpjsmLXri4jri6QuXG4gICAgICAvLyDsnbTripQgZGF0ZS1mbnMg7Yq57J6F64uI64ukLlxuICAgICAgLy8g7J2066CH6rKMIO2VtOuPhCDqtJzssK7sirXri4jri6QuIFwiMjAyNS0xMS0xOVQxODo1NjoyOSswOTowMFwiIOuqqOyWkeycvOuhnCDsnpgg64KY7Ji164uI64ukLlxuICAgICAgY29uc3QgREFURV9GT1JNQVQgPSBcInl5eXktTU0tZGQnVCdISDptbTpzc1hYWFwiO1xuXG4gICAgICBzZXJ2ZXIuc2V0UmVwbHlTZXJpYWxpemVyKChwYXlsb2FkKSA9PiB7XG4gICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeShwYXlsb2FkLCAoX2tleSwgdmFsdWUpID0+IHtcbiAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmIElTT19EQVRFX1JFR0VYLnRlc3QodmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gZm9ybWF0SW5UaW1lWm9uZShcbiAgICAgICAgICAgICAgbmV3IERhdGUodmFsdWUpLFxuICAgICAgICAgICAgICB0aW1lem9uZSBhcyBgJHtzdHJpbmd9LyR7c3RyaW5nfWAsXG4gICAgICAgICAgICAgIERBVEVfRk9STUFULFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgaWYgKCFvcHRpb25zPy5kb1NpbGVudCkge1xuICAgICAgICBjb25zdCBjaGFsayA9IChhd2FpdCBpbXBvcnQoXCJjaGFsa1wiKSkuZGVmYXVsdDtcbiAgICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYFRpbWV6b25lIHNldCB0byAke3RpbWV6b25lfWApKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyDsoITssrQg65287Jqw7YyFIOumrOyKpO2KuFxuICAgIHNlcnZlci5nZXQoXG4gICAgICBgJHt0aGlzLmNvbmZpZy5hcGkucm91dGUucHJlZml4fS9yb3V0ZXNgLFxuICAgICAgYXN5bmMgKF9yZXF1ZXN0LCBfcmVwbHkpOiBQcm9taXNlPHR5cGVvZiB0aGlzLnN5bmNlci5hcGlzPiA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnN5bmNlci5hcGlzO1xuICAgICAgfSxcbiAgICApO1xuXG4gICAgLy8gSGVhbHRoY2hlY2sgQVBJXG4gICAgc2VydmVyLmdldChcbiAgICAgIGAke3RoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXh9L2hlYWx0aGNoZWNrYCxcbiAgICAgIGFzeW5jIChfcmVxdWVzdCwgX3JlcGx5KTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgICAgICAgcmV0dXJuIFwib2tcIjtcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIC8vIEFQSSDrnbzsmrDtjIUgKOuhnOy7rEhNUiDsg4Htg5zsmYAg6rWs67aEKVxuICAgIGNvbnN0IHsgaXNMb2NhbCB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdXRpbHMvY29udHJvbGxlclwiKTtcbiAgICBpZiAoaXNMb2NhbCgpKSB7XG4gICAgICBzZXJ2ZXIuYWxsKFwiKlwiLCBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgZm91bmQgPSB0aGlzLnN5bmNlci5hcGlzLmZpbmQoXG4gICAgICAgICAgKGFwaSkgPT5cbiAgICAgICAgICAgIHRoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXggKyBhcGkucGF0aCA9PT0gcmVxdWVzdC51cmwuc3BsaXQoXCI/XCIpWzBdICYmXG4gICAgICAgICAgICAoYXBpLm9wdGlvbnMuaHR0cE1ldGhvZCA/PyBcIkdFVFwiKSA9PT0gcmVxdWVzdC5tZXRob2QudG9VcHBlckNhc2UoKSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGZvdW5kKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXBpSGFuZGxlcihmb3VuZCwgY29uZmlnKShyZXF1ZXN0LCByZXBseSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyBOb3RGb3VuZEV4Y2VwdGlvbiB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vZXhjZXB0aW9ucy9zby1leGNlcHRpb25zXCIpO1xuICAgICAgICB0aHJvdyBuZXcgTm90Rm91bmRFeGNlcHRpb24oXCLsobTsnqztlZjsp4Ag7JWK64qUIEFQSSDsoJHqt7zsnoXri4jri6QuXCIpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAoY29uc3QgYXBpIG9mIHRoaXMuc3luY2VyLmFwaXMpIHtcbiAgICAgICAgLy8gbW9kZWxcbiAgICAgICAgaWYgKHRoaXMuc3luY2VyLm1vZGVsc1thcGkubW9kZWxOYW1lXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGDsoJXsnZjrkJjsp4Ag7JWK7J2AIOuqqOuNuOyXkCDsoJHqt7wgJHthcGkubW9kZWxOYW1lfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcm91dGVcbiAgICAgICAgc2VydmVyLnJvdXRlKHtcbiAgICAgICAgICBtZXRob2Q6IGFwaS5vcHRpb25zLmh0dHBNZXRob2QgPz8gXCJHRVRcIixcbiAgICAgICAgICB1cmw6IHRoaXMuY29uZmlnLmFwaS5yb3V0ZS5wcmVmaXggKyBhcGkucGF0aCxcbiAgICAgICAgICBoYW5kbGVyOiB0aGlzLmdldEFwaUhhbmRsZXIoYXBpLCBjb25maWcpLFxuICAgICAgICB9KTsgLy8gRU5EIHNlcnZlci5yb3V0ZVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGdldEFwaUhhbmRsZXIoXG4gICAgYXBpOiBFeHRlbmRlZEFwaSxcbiAgICBjb25maWc6IFNvbmFtdUZhc3RpZnlDb25maWcsXG4gICk6IChyZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCwgcmVwbHk6IEZhc3RpZnlSZXBseSkgPT4gUHJvbWlzZTx1bmtub3duPiB7XG4gICAgcmV0dXJuIGFzeW5jIChyZXF1ZXN0OiBGYXN0aWZ5UmVxdWVzdCwgcmVwbHk6IEZhc3RpZnlSZXBseSk6IFByb21pc2U8dW5rbm93bj4gPT4ge1xuICAgICAgKGFwaS5vcHRpb25zLmd1YXJkcyA/PyBbXSkuZXZlcnkoKGd1YXJkKSA9PiBjb25maWcuZ3VhcmRIYW5kbGVyKGd1YXJkLCByZXF1ZXN0LCBhcGkpKTtcblxuICAgICAgLy8g7YyM652866+47YSwIOygleuztOuhnCB6b2Qg7Iqk7YKk66eIIOu5jOuTnFxuICAgICAgY29uc3QgeyBnZXRab2RPYmplY3RGcm9tQXBpIH0gPSBhd2FpdCBpbXBvcnQoXCIuL2NvZGUtY29udmVydGVyc1wiKTtcbiAgICAgIGNvbnN0IFJlcVR5cGUgPSBnZXRab2RPYmplY3RGcm9tQXBpKGFwaSwgdGhpcy5zeW5jZXIudHlwZXMpO1xuXG4gICAgICAvLyByZXF1ZXN0IO2MjOyLsVxuICAgICAgY29uc3Qgd2hpY2ggPSBhcGkub3B0aW9ucy5odHRwTWV0aG9kID09PSBcIkdFVFwiID8gXCJxdWVyeVwiIDogXCJib2R5XCI7XG4gICAgICBsZXQgcmVxQm9keToge1xuICAgICAgICBba2V5OiBzdHJpbmddOiB1bmtub3duO1xuICAgICAgfTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgZmFzdGlmeUNhc3RlciB9ID0gYXdhaXQgaW1wb3J0KFwiLi9jYXN0ZXJcIik7XG4gICAgICAgIHJlcUJvZHkgPSBmYXN0aWZ5Q2FzdGVyKFJlcVR5cGUpLnBhcnNlKHJlcXVlc3Rbd2hpY2hdID8/IHt9KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc3QgeyBab2RFcnJvciB9ID0gYXdhaXQgaW1wb3J0KFwiem9kXCIpO1xuICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFpvZEVycm9yKSB7XG4gICAgICAgICAgY29uc3QgeyBodW1hbml6ZVpvZEVycm9yIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi91dGlscy96b2QtZXJyb3JcIik7XG4gICAgICAgICAgY29uc3QgbWVzc2FnZXMgPSBodW1hbml6ZVpvZEVycm9yKGUpXG4gICAgICAgICAgICAubWFwKChpc3N1ZSkgPT4gaXNzdWUubWVzc2FnZSlcbiAgICAgICAgICAgIC5qb2luKFwiIFwiKTtcbiAgICAgICAgICBjb25zdCB7IEJhZFJlcXVlc3RFeGNlcHRpb24gfSA9IGF3YWl0IGltcG9ydChcIi4uL2V4Y2VwdGlvbnMvc28tZXhjZXB0aW9uc1wiKTtcbiAgICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihtZXNzYWdlcywge1xuICAgICAgICAgICAgem9kRXJyb3I6IGUsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBDb250ZW50LVR5cGVcbiAgICAgIHJlcGx5LnR5cGUoYXBpLm9wdGlvbnMuY29udGVudFR5cGUgPz8gXCJhcHBsaWNhdGlvbi9qc29uXCIpO1xuXG4gICAgICAvLyDsupDsi5xcbiAgICAgIGNvbnN0IHsgY2FjaGVLZXksIGNhY2hlVHRsLCBjYWNoZWREYXRhIH0gPSBhd2FpdCAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBpZiAoY29uZmlnLmNhY2hlKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGNhY2hlS2V5UmVzID0gY29uZmlnLmNhY2hlLnJlc29sdmVLZXkoYXBpLnBhdGgsIHJlcUJvZHkpO1xuICAgICAgICAgICAgaWYgKGNhY2hlS2V5UmVzLmNhY2hlID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICByZXR1cm4geyBjYWNoZUtleTogbnVsbCwgY2FjaGVkRGF0YTogbnVsbCB9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBjYWNoZUtleSA9IGNhY2hlS2V5UmVzLmtleTtcbiAgICAgICAgICAgIGNvbnN0IGNhY2hlVHRsID0gY2FjaGVLZXlSZXMudHRsO1xuICAgICAgICAgICAgY29uc3QgY2FjaGVkRGF0YSA9IGF3YWl0IGNvbmZpZy5jYWNoZS5nZXQoY2FjaGVLZXkpO1xuICAgICAgICAgICAgcmV0dXJuIHsgY2FjaGVLZXksIGNhY2hlVHRsLCBjYWNoZWREYXRhIH07XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHsgY2FjaGVLZXk6IG51bGwsIGNhY2hlZERhdGE6IG51bGwgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBjYWNoZUtleTogbnVsbCwgY2FjaGVkRGF0YTogbnVsbCB9O1xuICAgICAgfSkoKTtcbiAgICAgIGlmIChjYWNoZWREYXRhICE9PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBjYWNoZWREYXRhO1xuICAgICAgfVxuXG4gICAgICAvLyBjcmVhdGVTU0VGYWN0b3J5IO2VqOyImOyXkCDrr7jrpqwgcmVxdWVzdOydmCBzb2NrZXTqs7wgcmVwbHnrpbwg67CU7J2465SpLlxuICAgICAgY29uc3QgeyBjcmVhdGVTU0VGYWN0b3J5IH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9zdHJlYW0vc3NlXCIpO1xuICAgICAgY29uc3QgY3JlYXRlU1NFID0gKDxUIGV4dGVuZHMgWm9kT2JqZWN0PihcbiAgICAgICAgX3JlcXVlc3Q6IEZhc3RpZnlSZXF1ZXN0LFxuICAgICAgICBfcmVwbHk6IEZhc3RpZnlSZXBseSxcbiAgICAgICAgX2V2ZW50czogVCxcbiAgICAgICkgPT4gY3JlYXRlU1NFRmFjdG9yeShfcmVxdWVzdC5zb2NrZXQsIF9yZXBseSwgX2V2ZW50cykpLmJpbmQobnVsbCwgcmVxdWVzdCwgcmVwbHkpO1xuXG4gICAgICBjb25zdCBjb250ZXh0OiBDb250ZXh0ID0ge1xuICAgICAgICAuLi4oYXdhaXQgUHJvbWlzZS5yZXNvbHZlKFxuICAgICAgICAgIGNvbmZpZy5jb250ZXh0UHJvdmlkZXIoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgICAgIHJlcGx5LFxuICAgICAgICAgICAgICBoZWFkZXJzOiByZXF1ZXN0LmhlYWRlcnMsXG4gICAgICAgICAgICAgIGNyZWF0ZVNTRSxcbiAgICAgICAgICAgICAgbmFpdGVTdG9yZTogTmFpdGUuY3JlYXRlU3RvcmUoKSxcbiAgICAgICAgICAgICAgLy8gYXV0aFxuICAgICAgICAgICAgICB1c2VyOiByZXF1ZXN0LnVzZXIgPz8gbnVsbCxcbiAgICAgICAgICAgICAgcGFzc3BvcnQ6IHtcbiAgICAgICAgICAgICAgICBsb2dpbjogcmVxdWVzdC5sb2dpbi5iaW5kKHJlcXVlc3QpIGFzIEF1dGhDb250ZXh0W1wicGFzc3BvcnRcIl1bXCJsb2dpblwiXSxcbiAgICAgICAgICAgICAgICBsb2dvdXQ6IHJlcXVlc3QubG9nb3V0LmJpbmQocmVxdWVzdCkgYXMgQXV0aENvbnRleHRbXCJwYXNzcG9ydFwiXVtcImxvZ291dFwiXSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgICAgcmVwbHksXG4gICAgICAgICAgKSxcbiAgICAgICAgKSksXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtb2RlbCA9IHRoaXMuc3luY2VyLm1vZGVsc1thcGkubW9kZWxOYW1lXTtcbiAgICAgIHJldHVybiB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLnJ1bih7IGNvbnRleHQgfSwgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB7IEFwaVBhcmFtVHlwZSB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vdHlwZXMvdHlwZXNcIik7XG4gICAgICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogbW9kZWzsnYAg66qo6424IOyduOyKpO2EtOyKpOydtOuvgOuhnCDrqZTshJzrk5wg7Zi47LacIOqwgOuKpVxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCAobW9kZWwgYXMgYW55KVthcGkubWV0aG9kTmFtZV0uYXBwbHkoXG4gICAgICAgICAgbW9kZWwsXG4gICAgICAgICAgYXBpLnBhcmFtZXRlcnMubWFwKChwYXJhbSkgPT4ge1xuICAgICAgICAgICAgLy8gQ29udGV4dCDsnbjsoJ3shZhcbiAgICAgICAgICAgIGlmIChBcGlQYXJhbVR5cGUuaXNDb250ZXh0KHBhcmFtLnR5cGUpKSB7XG4gICAgICAgICAgICAgIHJldHVybiBjb250ZXh0O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlcUJvZHlbcGFyYW0ubmFtZV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICAgIHJlcGx5LnR5cGUoYXBpLm9wdGlvbnMuY29udGVudFR5cGUgPz8gXCJhcHBsaWNhdGlvbi9qc29uXCIpO1xuXG4gICAgICAgIC8vIOy6kOyLnCDtgqQg7J6I64qUIOqyveyasCDqsLHsi6Ag7ZuEIOyggOyepVxuICAgICAgICBpZiAoY29uZmlnLmNhY2hlICYmIGNhY2hlS2V5KSB7XG4gICAgICAgICAgYXdhaXQgY29uZmlnLmNhY2hlLnB1dChjYWNoZUtleSwgcmVzdWx0LCBjYWNoZVR0bCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuICAgIH07XG4gIH1cblxuICBhc3luYyBzdGFydFdhdGNoZXIoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgd2F0Y2hQYXRoID0gW1xuICAgICAgcGF0aC5qb2luKHRoaXMuYXBpUm9vdFBhdGgsIFwic3JjXCIpLFxuICAgICAgcGF0aC5qb2luKHRoaXMuYXBpUm9vdFBhdGgsIFwic29uYW11LmNvbmZpZy50c1wiKSxcbiAgICBdO1xuXG4gICAgY29uc3QgY2hva2lkYXIgPSAoYXdhaXQgaW1wb3J0KFwiY2hva2lkYXJcIikpLmRlZmF1bHQ7XG4gICAgdGhpcy53YXRjaGVyID0gY2hva2lkYXIud2F0Y2god2F0Y2hQYXRoLCB7XG4gICAgICBpZ25vcmVkOiAocGF0aCwgc3RhdHMpID0+XG4gICAgICAgICEhc3RhdHM/LmlzRmlsZSgpICYmICFwYXRoLmVuZHNXaXRoKFwiLnRzXCIpICYmICFwYXRoLmVuZHNXaXRoKFwiLmpzb25cIiksXG4gICAgICBwZXJzaXN0ZW50OiB0cnVlLFxuICAgICAgaWdub3JlSW5pdGlhbDogdHJ1ZSxcbiAgICB9KTtcblxuICAgIHRoaXMud2F0Y2hlci5vbihcImFsbFwiLCBhc3luYyAoZXZlbnQ6IHN0cmluZywgZmlsZVBhdGg6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgYWJzb2x1dGVQYXRoID0gZmlsZVBhdGggYXMgQWJzb2x1dGVQYXRoO1xuICAgICAgYXNzZXJ0KFxuICAgICAgICBhYnNvbHV0ZVBhdGguc3RhcnRzV2l0aCh0aGlzLmFwaVJvb3RQYXRoKSxcbiAgICAgICAgXCJGaWxlIHBhdGggaXMgbm90IHdpdGhpbiB0aGUgQVBJIHJvb3QgcGF0aFwiLFxuICAgICAgKTtcblxuICAgICAgaWYgKGV2ZW50ICE9PSBcImNoYW5nZVwiICYmIGV2ZW50ICE9PSBcImFkZFwiKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8gc29uYW11LmNvbmZpZy50cyDrs4Dqsr0g7IucIOyerOyLnOyekVxuICAgICAgICBjb25zdCBpc0NvbmZpZ1RzID0gZmlsZVBhdGggPT09IHBhdGguam9pbih0aGlzLmFwaVJvb3RQYXRoLCBcInNvbmFtdS5jb25maWcudHNcIik7XG5cbiAgICAgICAgaWYgKGlzQ29uZmlnVHMpIHtcbiAgICAgICAgICBjb25zdCByZWxhdGl2ZVBhdGggPSBmaWxlUGF0aC5yZXBsYWNlKHRoaXMuYXBpUm9vdFBhdGgsIFwiYXBpXCIpO1xuICAgICAgICAgIGNvbnN0IGNoYWxrID0gKGF3YWl0IGltcG9ydChcImNoYWxrXCIpKS5kZWZhdWx0O1xuICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgY2hhbGsuYm9sZChgRGV0ZWN0ZWQoJHtldmVudH0pOiAke2NoYWxrLmJsdWUocmVsYXRpdmVQYXRoKX0gLSBSZXN0YXJ0aW5nLi4uYCksXG4gICAgICAgICAgKTtcbiAgICAgICAgICBwcm9jZXNzLmtpbGwocHJvY2Vzcy5waWQsIFwiU0lHVVNSMlwiKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB0aGlzLmhhbmRsZUZpbGVDaGFuZ2UoZXZlbnQsIGFic29sdXRlUGF0aCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKlxuICAgICBBIGZ1bmN0aW9uIHRoYXQgYXV0b21hdGljYWxseSBoYW5kbGVzIGluaXQgYW5kIGRlc3Ryb3kgd2hlbiB1c2luZyBTb25hbXUgdmlhIHNjcmlwdHMuICAgIFxuICAqL1xuICBhc3luYyBydW5TY3JpcHQoZm46ICgpID0+IFByb21pc2U8dm9pZD4pIHtcbiAgICBhd2FpdCB0aGlzLmluaXQodHJ1ZSwgZmFsc2UsIHVuZGVmaW5lZCwgZmFsc2UpO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBmbigpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCB0aGlzLmRlc3Ryb3koKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlZ2lzdGVyUGx1Z2lucyhzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZSwgcGx1Z2luczogU29uYW11U2VydmVyT3B0aW9uc1tcInBsdWdpbnNcIl0pIHtcbiAgICBpZiAoIXBsdWdpbnMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwbHVnaW5zTW9kdWxlcyA9IHtcbiAgICAgIGNvcnM6IFwiQGZhc3RpZnkvY29yc1wiLFxuICAgICAgZm9ybWJvZHk6IFwiQGZhc3RpZnkvZm9ybWJvZHlcIixcbiAgICAgIG11bHRpcGFydDogXCJAZmFzdGlmeS9tdWx0aXBhcnRcIixcbiAgICAgIHFzOiBcImZhc3RpZnktcXNcIixcbiAgICAgIHNzZTogXCJmYXN0aWZ5LXNzZS12MlwiLFxuICAgICAgc3RhdGljOiBcIkBmYXN0aWZ5L3N0YXRpY1wiLFxuICAgICAgc2Vzc2lvbjogXCJAZmFzdGlmeS9zZWN1cmUtc2Vzc2lvblwiLFxuICAgIH0gYXMgY29uc3Q7XG5cbiAgICBjb25zdCByZWdpc3RlclBsdWdpbiA9IGFzeW5jIDxLIGV4dGVuZHMga2V5b2YgTm9uTnVsbGFibGU8dHlwZW9mIHBsdWdpbnM+PihcbiAgICAgIGtleTogSyxcbiAgICAgIHBsdWdpbk5hbWU6IHN0cmluZyxcbiAgICApID0+IHtcbiAgICAgIGNvbnN0IG9wdGlvbiA9IHBsdWdpbnNba2V5XTtcbiAgICAgIGlmICghb3B0aW9uKSByZXR1cm47XG5cbiAgICAgIGlmIChvcHRpb24gPT09IHRydWUpIHtcbiAgICAgICAgc2VydmVyLnJlZ2lzdGVyKChhd2FpdCBpbXBvcnQocGx1Z2luTmFtZSkpLmRlZmF1bHQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2VydmVyLnJlZ2lzdGVyKChhd2FpdCBpbXBvcnQocGx1Z2luTmFtZSkpLmRlZmF1bHQsIG9wdGlvbik7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGZvciAoY29uc3QgW2tleSwgcGx1Z2luTmFtZV0gb2YgT2JqZWN0LmVudHJpZXMocGx1Z2luc01vZHVsZXMpKSB7XG4gICAgICBhd2FpdCByZWdpc3RlclBsdWdpbihrZXkgYXMga2V5b2YgdHlwZW9mIHBsdWdpbnMsIHBsdWdpbk5hbWUpO1xuICAgIH1cblxuICAgIGlmIChwbHVnaW5zLmN1c3RvbSkge1xuICAgICAgcGx1Z2lucy5jdXN0b20oc2VydmVyKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlZ2lzdGVyQXV0aChcbiAgICBzZXJ2ZXI6IEZhc3RpZnlJbnN0YW5jZSxcbiAgICBvcHRpb25zOiBOb25OdWxsYWJsZTxTb25hbXVTZXJ2ZXJPcHRpb25zW1wiYXV0aFwiXT4sXG4gICkge1xuICAgIC8vIGF3YWl0IGltcG9ydChcImZhc3RpZnlcIik7XG4gICAgY29uc3QgZmFzdGlmeVBhc3Nwb3J0ID0gKGF3YWl0IGltcG9ydChcIkBmYXN0aWZ5L3Bhc3Nwb3J0XCIpKS5kZWZhdWx0O1xuICAgIHNlcnZlci5yZWdpc3RlcihmYXN0aWZ5UGFzc3BvcnQuaW5pdGlhbGl6ZSgpKTtcbiAgICBzZXJ2ZXIucmVnaXN0ZXIoZmFzdGlmeVBhc3Nwb3J0LnNlY3VyZVNlc3Npb24oKSk7XG5cbiAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09IFwiYm9vbGVhblwiKSB7XG4gICAgICBmYXN0aWZ5UGFzc3BvcnQucmVnaXN0ZXJVc2VyU2VyaWFsaXplcihhc3luYyAodXNlciwgX3JlcXVlc3QpID0+IHVzZXIpO1xuICAgICAgZmFzdGlmeVBhc3Nwb3J0LnJlZ2lzdGVyVXNlckRlc2VyaWFsaXplcihhc3luYyAoc2VyaWFsaXplZCwgX3JlcXVlc3QpID0+IHNlcmlhbGl6ZWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmYXN0aWZ5UGFzc3BvcnQucmVnaXN0ZXJVc2VyU2VyaWFsaXplcihvcHRpb25zLnVzZXJTZXJpYWxpemVyKTtcbiAgICAgIGZhc3RpZnlQYXNzcG9ydC5yZWdpc3RlclVzZXJEZXNlcmlhbGl6ZXIob3B0aW9ucy51c2VyRGVzZXJpYWxpemVyKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGJvb3Qoc2VydmVyOiBGYXN0aWZ5SW5zdGFuY2UsIG9wdGlvbnM6IFNvbmFtdVNlcnZlck9wdGlvbnMpIHtcbiAgICBjb25zdCBwb3J0ID0gb3B0aW9ucy5saXN0ZW4/LnBvcnQgPz8gMzAwMDtcbiAgICBjb25zdCBob3N0ID0gb3B0aW9ucy5saXN0ZW4/Lmhvc3QgPz8gXCJsb2NhbGhvc3RcIjtcblxuICAgIHNlcnZlci5hZGRIb29rKFwib25DbG9zZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCBvcHRpb25zLmxpZmVjeWNsZT8ub25TaHV0ZG93bj8uKHNlcnZlcik7XG4gICAgICBhd2FpdCB0aGlzLmRlc3Ryb3koKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IHNodXRkb3duID0gYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc2VydmVyLmNsb3NlKCk7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3IgZHVyaW5nIHNodXRkb3duOlwiLCBlcnIpO1xuICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHByb2Nlc3Mub24oXCJTSUdJTlRcIiwgc2h1dGRvd24pO1xuICAgIHByb2Nlc3Mub24oXCJTSUdURVJNXCIsIHNodXRkb3duKTtcblxuICAgIGlmIChvcHRpb25zLmxpZmVjeWNsZT8ub25FcnJvcikge1xuICAgICAgc2VydmVyLnNldEVycm9ySGFuZGxlcihvcHRpb25zLmxpZmVjeWNsZT8ub25FcnJvcik7XG4gICAgfVxuXG4gICAgc2VydmVyXG4gICAgICAubGlzdGVuKHsgcG9ydCwgaG9zdCB9KVxuICAgICAgLnRoZW4oYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCBvcHRpb25zLmxpZmVjeWNsZT8ub25TdGFydD8uKHNlcnZlcik7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGFzeW5jIChlcnIpID0+IHtcbiAgICAgICAgY29uc3QgY2hhbGsgPSAoYXdhaXQgaW1wb3J0KFwiY2hhbGtcIikpLmRlZmF1bHQ7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoY2hhbGsucmVkKFwiRmFpbGVkIHRvIHN0YXJ0IHNlcnZlcjpcIiwgZXJyKSk7XG4gICAgICAgIGF3YWl0IHNodXRkb3duKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlRmlsZUNoYW5nZShldmVudDogc3RyaW5nLCBmaWxlUGF0aDogQWJzb2x1dGVQYXRoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8g7LKrIOuyiOynuCDtjIzsnbzsnbTrqbQgSE1SIOyLnOyekSDsi5zqsIQg6riw66GdXG4gICAgaWYgKHRoaXMucGVuZGluZ0ZpbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5obXJTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIH1cbiAgICB0aGlzLnBlbmRpbmdGaWxlcy5wdXNoKGZpbGVQYXRoKTtcblxuICAgIGNvbnN0IHJlbGF0aXZlUGF0aCA9IHBhdGgucmVsYXRpdmUodGhpcy5hcGlSb290UGF0aCwgZmlsZVBhdGgpO1xuICAgIGNvbnN0IGNoYWxrID0gKGF3YWl0IGltcG9ydChcImNoYWxrXCIpKS5kZWZhdWx0O1xuICAgIGNvbnNvbGUubG9nKGNoYWxrLmJvbGQoYERldGVjdGVkKCR7ZXZlbnR9KTogJHtjaGFsay5ibHVlKHJlbGF0aXZlUGF0aCl9YCkpO1xuXG4gICAgYXdhaXQgdGhpcy5zeW5jZXIuc3luY0Zyb21XYXRjaGVyKGV2ZW50LCBmaWxlUGF0aCk7XG5cbiAgICAvLyDsspjrpqwg7JmE66OM65CcIO2MjOydvOydhCDrjIDquLAg66qp66Gd7JeQ7IScIOygnOqxsFxuICAgIHRoaXMucGVuZGluZ0ZpbGVzID0gdGhpcy5wZW5kaW5nRmlsZXMuc2xpY2UoMSk7XG5cbiAgICAvLyDrqqjrk6Ag7YyM7J28IOyymOumrOqwgCDsmYTro4zrkJjrqbQg7LWc7KKFIOuplOyLnOyngCDstpzroKVcbiAgICBpZiAodGhpcy5wZW5kaW5nRmlsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICBhd2FpdCB0aGlzLmZpbmlzaEhNUigpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZmluaXNoSE1SKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuc3luY2VyLnJlbmV3Q2hlY2tzdW1zKCk7XG5cbiAgICBjb25zdCBlbmRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCB0b3RhbFRpbWUgPSBlbmRUaW1lIC0gdGhpcy5obXJTdGFydFRpbWU7XG4gICAgY29uc3QgW2NoYWxrLCB7IGNlbnRlclRleHQgfV0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAoYXdhaXQgaW1wb3J0KFwiY2hhbGtcIikpLmRlZmF1bHQsXG4gICAgICBpbXBvcnQoXCIuLi91dGlscy9jb25zb2xlLXV0aWxcIiksXG4gICAgXSk7XG4gICAgY29uc3QgbXNnID0gYEhNUiBEb25lISAke2NoYWxrLmJvbGQud2hpdGUoYCR7dG90YWxUaW1lfW1zYCl9YDtcblxuICAgIGNvbnNvbGUubG9nKGNoYWxrLmJsYWNrLmJnR3JlZW4oY2VudGVyVGV4dChtc2cpKSk7XG4gIH1cblxuICBhc3luYyBkZXN0cm95KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsgQmFzZU1vZGVsIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9kYXRhYmFzZS9iYXNlLW1vZGVsXCIpO1xuICAgIGF3YWl0IEJhc2VNb2RlbC5kZXN0cm95KCk7XG4gICAgYXdhaXQgdGhpcy53YXRjaGVyPy5jbG9zZSgpO1xuICAgIHRoaXMuc3RvcmFnZT8uZGVzdHJveSgpO1xuICB9XG59XG5leHBvcnQgY29uc3QgU29uYW11ID0gbmV3IFNvbmFtdUNsYXNzKCk7XG4iXSwibmFtZXMiOlsiYXNzZXJ0IiwiQXN5bmNMb2NhbFN0b3JhZ2UiLCJwYXRoIiwiTmFpdGUiLCJTb25hbXVDbGFzcyIsImlzSW5pdGlhbGl6ZWQiLCJhc3luY0xvY2FsU3RvcmFnZSIsInVwbG9hZFN0b3JhZ2UiLCJnZXRDb250ZXh0Iiwic3RvcmUiLCJnZXRTdG9yZSIsImNvbnRleHQiLCJwcm9jZXNzIiwiZW52IiwiTk9ERV9FTlYiLCJyZXF1ZXN0IiwicmVwbHkiLCJoZWFkZXJzIiwiY3JlYXRlU1NFIiwibmFpdGVTdG9yZSIsIk1hcCIsIkVycm9yIiwiZ2V0VXBsb2FkQ29udGV4dCIsInVwbG9hZENvbnRleHQiLCJfYXBpUm9vdFBhdGgiLCJhcGlSb290UGF0aCIsImFwcFJvb3RQYXRoIiwic3BsaXQiLCJzZXAiLCJzbGljZSIsImpvaW4iLCJfZGJDb25maWciLCJkYkNvbmZpZyIsIl9zeW5jZXIiLCJzeW5jZXIiLCJfY29uZmlnIiwiY29uZmlnIiwiX3NlY3JldHMiLCJzZWNyZXRzIiwiX3N0b3JhZ2UiLCJzdG9yYWdlIiwid2F0Y2hlciIsInBlbmRpbmdGaWxlcyIsImhtclN0YXJ0VGltZSIsInNlcnZlciIsImluaXRGb3JUZXN0aW5nIiwiaW5pdCIsInVuZGVmaW5lZCIsImRvU2lsZW50IiwiZW5hYmxlU3luYyIsImZvclRlc3RpbmciLCJjaGFsayIsImRlZmF1bHQiLCJjb25zb2xlIiwidGltZSIsImN5YW4iLCJmaW5kQXBpUm9vdFBhdGgiLCJsb2FkQ29uZmlnIiwiZGF0YWJhc2UiLCJBTlRIUk9QSUNfQVBJX0tFWSIsImFudGhyb3BpY19hcGlfa2V5IiwiREIiLCJnZW5lcmF0ZURCQ29uZmlnIiwibG9nIiwiZ3JlZW4iLCJFbnRpdHlNYW5hZ2VyIiwiYXV0b2xvYWQiLCJTeW5jZXIiLCJhdXRvbG9hZFR5cGVzIiwiYXV0b2xvYWRNb2RlbHMiLCJhdXRvbG9hZEFwaXMiLCJUZW1wbGF0ZU1hbmFnZXIiLCJpc0xvY2FsIiwiaXNUZXN0Iiwic2V0dXBCaW9tZSIsImlzSG90UmVsb2FkU2VydmVyIiwic3luYyIsInN0YXJ0V2F0Y2hlciIsInN5bmNVSSIsInRpbWVFbmQiLCJjcmVhdGVTZXJ2ZXIiLCJpbml0T3B0aW9ucyIsIm9wdGlvbnMiLCJmYXN0aWZ5IiwicGx1Z2lucyIsInJlZ2lzdGVyUGx1Z2lucyIsImF1dGgiLCJzZXNzaW9uIiwicmVnaXN0ZXJBdXRoIiwid2l0aEZhc3RpZnkiLCJhcGlDb25maWciLCJib290IiwidGltZXpvbmUiLCJhcGkiLCJmb3JtYXRJblRpbWVab25lIiwiSVNPX0RBVEVfUkVHRVgiLCJEQVRFX0ZPUk1BVCIsInNldFJlcGx5U2VyaWFsaXplciIsInBheWxvYWQiLCJKU09OIiwic3RyaW5naWZ5IiwiX2tleSIsInZhbHVlIiwidGVzdCIsIkRhdGUiLCJnZXQiLCJyb3V0ZSIsInByZWZpeCIsIl9yZXF1ZXN0IiwiX3JlcGx5IiwiYXBpcyIsImFsbCIsImZvdW5kIiwiZmluZCIsInVybCIsImh0dHBNZXRob2QiLCJtZXRob2QiLCJ0b1VwcGVyQ2FzZSIsImdldEFwaUhhbmRsZXIiLCJOb3RGb3VuZEV4Y2VwdGlvbiIsIm1vZGVscyIsIm1vZGVsTmFtZSIsImhhbmRsZXIiLCJndWFyZHMiLCJldmVyeSIsImd1YXJkIiwiZ3VhcmRIYW5kbGVyIiwiZ2V0Wm9kT2JqZWN0RnJvbUFwaSIsIlJlcVR5cGUiLCJ0eXBlcyIsIndoaWNoIiwicmVxQm9keSIsImZhc3RpZnlDYXN0ZXIiLCJwYXJzZSIsImUiLCJab2RFcnJvciIsImh1bWFuaXplWm9kRXJyb3IiLCJtZXNzYWdlcyIsIm1hcCIsImlzc3VlIiwibWVzc2FnZSIsIkJhZFJlcXVlc3RFeGNlcHRpb24iLCJ6b2RFcnJvciIsInR5cGUiLCJjb250ZW50VHlwZSIsImNhY2hlS2V5IiwiY2FjaGVUdGwiLCJjYWNoZWREYXRhIiwiY2FjaGUiLCJjYWNoZUtleVJlcyIsInJlc29sdmVLZXkiLCJrZXkiLCJ0dGwiLCJlcnJvciIsImNyZWF0ZVNTRUZhY3RvcnkiLCJfZXZlbnRzIiwic29ja2V0IiwiYmluZCIsIlByb21pc2UiLCJyZXNvbHZlIiwiY29udGV4dFByb3ZpZGVyIiwiY3JlYXRlU3RvcmUiLCJ1c2VyIiwicGFzc3BvcnQiLCJsb2dpbiIsImxvZ291dCIsIm1vZGVsIiwicnVuIiwiQXBpUGFyYW1UeXBlIiwicmVzdWx0IiwibWV0aG9kTmFtZSIsImFwcGx5IiwicGFyYW1ldGVycyIsInBhcmFtIiwiaXNDb250ZXh0IiwibmFtZSIsInB1dCIsIndhdGNoUGF0aCIsImNob2tpZGFyIiwid2F0Y2giLCJpZ25vcmVkIiwic3RhdHMiLCJpc0ZpbGUiLCJlbmRzV2l0aCIsInBlcnNpc3RlbnQiLCJpZ25vcmVJbml0aWFsIiwib24iLCJldmVudCIsImZpbGVQYXRoIiwiYWJzb2x1dGVQYXRoIiwic3RhcnRzV2l0aCIsImlzQ29uZmlnVHMiLCJyZWxhdGl2ZVBhdGgiLCJyZXBsYWNlIiwiYm9sZCIsImJsdWUiLCJraWxsIiwicGlkIiwiaGFuZGxlRmlsZUNoYW5nZSIsInJ1blNjcmlwdCIsImZuIiwiZGVzdHJveSIsInBsdWdpbnNNb2R1bGVzIiwiY29ycyIsImZvcm1ib2R5IiwibXVsdGlwYXJ0IiwicXMiLCJzc2UiLCJzdGF0aWMiLCJyZWdpc3RlclBsdWdpbiIsInBsdWdpbk5hbWUiLCJvcHRpb24iLCJyZWdpc3RlciIsIk9iamVjdCIsImVudHJpZXMiLCJjdXN0b20iLCJmYXN0aWZ5UGFzc3BvcnQiLCJpbml0aWFsaXplIiwic2VjdXJlU2Vzc2lvbiIsInJlZ2lzdGVyVXNlclNlcmlhbGl6ZXIiLCJyZWdpc3RlclVzZXJEZXNlcmlhbGl6ZXIiLCJzZXJpYWxpemVkIiwidXNlclNlcmlhbGl6ZXIiLCJ1c2VyRGVzZXJpYWxpemVyIiwicG9ydCIsImxpc3RlbiIsImhvc3QiLCJhZGRIb29rIiwibGlmZWN5Y2xlIiwib25TaHV0ZG93biIsInNodXRkb3duIiwiY2xvc2UiLCJleGl0IiwiZXJyIiwib25FcnJvciIsInNldEVycm9ySGFuZGxlciIsInRoZW4iLCJvblN0YXJ0IiwiY2F0Y2giLCJyZWQiLCJsZW5ndGgiLCJub3ciLCJwdXNoIiwicmVsYXRpdmUiLCJzeW5jRnJvbVdhdGNoZXIiLCJmaW5pc2hITVIiLCJyZW5ld0NoZWNrc3VtcyIsImVuZFRpbWUiLCJ0b3RhbFRpbWUiLCJjZW50ZXJUZXh0IiwibXNnIiwid2hpdGUiLCJibGFjayIsImJnR3JlZW4iLCJCYXNlTW9kZWwiLCJTb25hbXUiXSwibWFwcGluZ3MiOiJBQUFBLE9BQU9BLFlBQVksU0FBUztBQUM1QixTQUFTQyxpQkFBaUIsUUFBUSxjQUFjO0FBSWhELE9BQU9DLFVBQVUsT0FBTztBQUl4QixTQUFTQyxLQUFLLFFBQVEsb0JBQWlCO0FBV3ZDLE1BQU1DO0lBQ0dDLGdCQUF5QixNQUFNO0lBQy9CQyxvQkFFRixJQUFJTCxvQkFBb0I7SUFFdEJNLGdCQUVGLElBQUlOLG9CQUFvQjtJQUV0Qk8sYUFBc0I7UUFDM0IsTUFBTUMsUUFBUSxJQUFJLENBQUNILGlCQUFpQixDQUFDSSxRQUFRO1FBQzdDLElBQUlELE9BQU9FLFNBQVM7WUFDbEIsT0FBT0YsTUFBTUUsT0FBTztRQUN0QjtRQUVBLElBQUlDLFFBQVFDLEdBQUcsQ0FBQ0MsUUFBUSxL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
@@ -0,0 +1,6 @@
1
+ export declare const RESERVED_KEYWORDS: Set<string>;
2
+ export declare class ApiValidationError extends Error {
3
+ constructor(message: string);
4
+ }
5
+ export declare function validateMethodName(methodName: string): void;
6
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/api/validator.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,aAmE5B,CAAC;AAEH,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,QAMpD"}