sonamu 0.5.7 → 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 (529) 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 +13 -2
  39. package/dist/api/caster.d.ts.map +1 -1
  40. package/dist/api/caster.js +71 -2
  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 +258 -2
  44. package/dist/api/config.d.ts +90 -0
  45. package/dist/api/config.d.ts.map +1 -0
  46. package/dist/api/config.js +25 -0
  47. package/dist/api/context.d.ts +4 -2
  48. package/dist/api/context.d.ts.map +1 -1
  49. package/dist/api/context.js +3 -2
  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 +235 -2
  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 +9 -2
  56. package/dist/api/sonamu.d.ts +10 -24
  57. package/dist/api/sonamu.d.ts.map +1 -1
  58. package/dist/api/sonamu.js +514 -2
  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 +6 -1
  63. package/dist/bin/build-config.d.ts.map +1 -1
  64. package/dist/bin/build-config.js +15 -2
  65. package/dist/bin/cli.js +519 -2
  66. package/dist/bin/hot-hook-register.d.ts +11 -0
  67. package/dist/bin/hot-hook-register.d.ts.map +1 -0
  68. package/dist/bin/hot-hook-register.js +21 -0
  69. package/dist/bin/loader-register.d.ts +2 -0
  70. package/dist/bin/loader-register.d.ts.map +1 -0
  71. package/dist/bin/loader-register.js +34 -0
  72. package/dist/database/_batch_update.d.ts +5 -3
  73. package/dist/database/_batch_update.d.ts.map +1 -1
  74. package/dist/database/_batch_update.js +95 -2
  75. package/dist/database/base-model.d.ts +96 -10
  76. package/dist/database/base-model.d.ts.map +1 -1
  77. package/dist/database/base-model.js +390 -2
  78. package/dist/database/base-model.types.d.ts +93 -0
  79. package/dist/database/base-model.types.d.ts.map +1 -0
  80. package/dist/database/base-model.types.js +10 -0
  81. package/dist/database/code-generator.d.ts +1 -1
  82. package/dist/database/code-generator.d.ts.map +1 -1
  83. package/dist/database/code-generator.js +54 -2
  84. package/dist/database/db.d.ts +6 -21
  85. package/dist/database/db.d.ts.map +1 -1
  86. package/dist/database/db.js +129 -2
  87. package/dist/database/puri-subset.test-d.js +81 -0
  88. package/dist/database/puri-subset.types.d.ts +123 -0
  89. package/dist/database/puri-subset.types.d.ts.map +1 -0
  90. package/dist/database/puri-subset.types.js +16 -0
  91. package/dist/database/puri-wrapper.d.ts +13 -11
  92. package/dist/database/puri-wrapper.d.ts.map +1 -1
  93. package/dist/database/puri-wrapper.js +109 -2
  94. package/dist/database/puri.d.ts +41 -23
  95. package/dist/database/puri.d.ts.map +1 -1
  96. package/dist/database/puri.js +601 -2
  97. package/dist/database/puri.types.d.ts +25 -6
  98. package/dist/database/puri.types.d.ts.map +1 -1
  99. package/dist/database/puri.types.js +6 -2
  100. package/dist/database/transaction-context.d.ts +1 -1
  101. package/dist/database/transaction-context.d.ts.map +1 -1
  102. package/dist/database/transaction-context.js +14 -2
  103. package/dist/database/upsert-builder.d.ts +9 -3
  104. package/dist/database/upsert-builder.d.ts.map +1 -1
  105. package/dist/database/upsert-builder.js +365 -2
  106. package/dist/entity/entity-manager.d.ts +167 -2
  107. package/dist/entity/entity-manager.d.ts.map +1 -1
  108. package/dist/entity/entity-manager.js +130 -2
  109. package/dist/entity/entity.d.ts +5 -3
  110. package/dist/entity/entity.d.ts.map +1 -1
  111. package/dist/entity/entity.js +750 -2
  112. package/dist/exceptions/error-handler.d.ts +1 -1
  113. package/dist/exceptions/error-handler.d.ts.map +1 -1
  114. package/dist/exceptions/error-handler.js +29 -2
  115. package/dist/exceptions/so-exceptions.d.ts +1 -1
  116. package/dist/exceptions/so-exceptions.d.ts.map +1 -1
  117. package/dist/exceptions/so-exceptions.js +85 -2
  118. package/dist/file-storage/driver.d.ts +1 -1
  119. package/dist/file-storage/driver.d.ts.map +1 -1
  120. package/dist/file-storage/driver.js +79 -2
  121. package/dist/file-storage/file-storage.js +75 -2
  122. package/dist/index.d.ts +18 -9
  123. package/dist/index.d.ts.map +1 -1
  124. package/dist/index.js +34 -2
  125. package/dist/migration/code-generation.d.ts +1 -1
  126. package/dist/migration/code-generation.d.ts.map +1 -1
  127. package/dist/migration/code-generation.js +614 -2
  128. package/dist/migration/migration-set.d.ts +2 -10
  129. package/dist/migration/migration-set.d.ts.map +1 -1
  130. package/dist/migration/migration-set.js +213 -2
  131. package/dist/migration/migrator.d.ts +24 -82
  132. package/dist/migration/migrator.d.ts.map +1 -1
  133. package/dist/migration/migrator.js +330 -2
  134. package/dist/migration/postgresql-schema-reader.d.ts +51 -0
  135. package/dist/migration/postgresql-schema-reader.d.ts.map +1 -0
  136. package/dist/migration/postgresql-schema-reader.js +245 -0
  137. package/dist/migration/types.d.ts +6 -38
  138. package/dist/migration/types.d.ts.map +1 -1
  139. package/dist/migration/types.js +3 -2
  140. package/dist/naite/messaging-types.d.ts +43 -0
  141. package/dist/naite/messaging-types.d.ts.map +1 -0
  142. package/dist/naite/messaging-types.js +7 -0
  143. package/dist/naite/naite-reporter.d.ts +41 -0
  144. package/dist/naite/naite-reporter.d.ts.map +1 -0
  145. package/dist/naite/naite-reporter.js +102 -0
  146. package/dist/naite/naite.d.ts +95 -0
  147. package/dist/naite/naite.d.ts.map +1 -0
  148. package/dist/naite/naite.js +316 -0
  149. package/dist/stream/index.js +3 -2
  150. package/dist/stream/sse.d.ts +2 -2
  151. package/dist/stream/sse.d.ts.map +1 -1
  152. package/dist/stream/sse.js +38 -2
  153. package/dist/syncer/api-parser.d.ts +10 -0
  154. package/dist/syncer/api-parser.d.ts.map +1 -0
  155. package/dist/syncer/api-parser.js +240 -0
  156. package/dist/syncer/checksum.d.ts +21 -0
  157. package/dist/syncer/checksum.d.ts.map +1 -0
  158. package/dist/syncer/checksum.js +98 -0
  159. package/dist/syncer/code-generator.d.ts +20 -0
  160. package/dist/syncer/code-generator.d.ts.map +1 -0
  161. package/dist/syncer/code-generator.js +161 -0
  162. package/dist/syncer/entity-operations.d.ts +17 -0
  163. package/dist/syncer/entity-operations.d.ts.map +1 -0
  164. package/dist/syncer/entity-operations.js +59 -0
  165. package/dist/syncer/file-patterns.d.ts +29 -0
  166. package/dist/syncer/file-patterns.d.ts.map +1 -0
  167. package/dist/syncer/file-patterns.js +38 -0
  168. package/dist/syncer/index.d.ts +6 -0
  169. package/dist/syncer/index.d.ts.map +1 -1
  170. package/dist/syncer/index.js +9 -2
  171. package/dist/syncer/module-loader.d.ts +35 -0
  172. package/dist/syncer/module-loader.d.ts.map +1 -0
  173. package/dist/syncer/module-loader.js +87 -0
  174. package/dist/syncer/syncer.d.ts +98 -106
  175. package/dist/syncer/syncer.d.ts.map +1 -1
  176. package/dist/syncer/syncer.js +422 -2
  177. package/dist/template/entity-converter.d.ts +14 -0
  178. package/dist/template/entity-converter.d.ts.map +1 -0
  179. package/dist/template/entity-converter.js +108 -0
  180. package/dist/template/helpers.d.ts +23 -0
  181. package/dist/template/helpers.d.ts.map +1 -0
  182. package/dist/template/helpers.js +64 -0
  183. package/dist/{templates → template/implementations}/entity.template.d.ts +3 -3
  184. package/dist/template/implementations/entity.template.d.ts.map +1 -0
  185. package/dist/template/implementations/entity.template.js +86 -0
  186. package/dist/{templates → template/implementations}/generated.template.d.ts +3 -4
  187. package/dist/template/implementations/generated.template.d.ts.map +1 -0
  188. package/dist/template/implementations/generated.template.js +249 -0
  189. package/dist/{templates → template/implementations}/generated_http.template.d.ts +3 -4
  190. package/dist/template/implementations/generated_http.template.d.ts.map +1 -0
  191. package/dist/template/implementations/generated_http.template.js +131 -0
  192. package/dist/{templates → template/implementations}/generated_sso.template.d.ts +4 -5
  193. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -0
  194. package/dist/template/implementations/generated_sso.template.js +134 -0
  195. package/dist/{templates → template/implementations}/init_types.template.d.ts +3 -3
  196. package/dist/template/implementations/init_types.template.d.ts.map +1 -0
  197. package/dist/template/implementations/init_types.template.js +38 -0
  198. package/dist/template/implementations/model.template.d.ts +17 -0
  199. package/dist/template/implementations/model.template.d.ts.map +1 -0
  200. package/dist/template/implementations/model.template.js +181 -0
  201. package/dist/{templates → template/implementations}/model_test.template.d.ts +3 -3
  202. package/dist/template/implementations/model_test.template.d.ts.map +1 -0
  203. package/dist/template/implementations/model_test.template.js +35 -0
  204. package/dist/{templates → template/implementations}/service.template.d.ts +6 -6
  205. package/dist/template/implementations/service.template.d.ts.map +1 -0
  206. package/dist/template/implementations/service.template.js +201 -0
  207. package/dist/{templates → template/implementations}/view_enums_buttonset.template.d.ts +3 -3
  208. package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +1 -0
  209. package/dist/template/implementations/view_enums_buttonset.template.js +31 -0
  210. package/dist/{templates → template/implementations}/view_enums_dropdown.template.d.ts +3 -4
  211. package/dist/template/implementations/view_enums_dropdown.template.d.ts.map +1 -0
  212. package/dist/template/implementations/view_enums_dropdown.template.js +50 -0
  213. package/dist/{templates → template/implementations}/view_enums_select.template.d.ts +3 -3
  214. package/dist/template/implementations/view_enums_select.template.d.ts.map +1 -0
  215. package/dist/template/implementations/view_enums_select.template.js +55 -0
  216. package/dist/{templates → template/implementations}/view_form.template.d.ts +5 -5
  217. package/dist/template/implementations/view_form.template.d.ts.map +1 -0
  218. package/dist/template/implementations/view_form.template.js +337 -0
  219. package/dist/{templates → template/implementations}/view_id_all_select.template.d.ts +3 -3
  220. package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -0
  221. package/dist/template/implementations/view_id_all_select.template.js +31 -0
  222. package/dist/{templates → template/implementations}/view_id_async_select.template.d.ts +3 -3
  223. package/dist/template/implementations/view_id_async_select.template.d.ts.map +1 -0
  224. package/dist/template/implementations/view_id_async_select.template.js +105 -0
  225. package/dist/{templates → template/implementations}/view_list.template.d.ts +5 -13
  226. package/dist/template/implementations/view_list.template.d.ts.map +1 -0
  227. package/dist/template/implementations/view_list.template.js +475 -0
  228. package/dist/template/implementations/view_list_columns.template.d.ts +17 -0
  229. package/dist/template/implementations/view_list_columns.template.d.ts.map +1 -0
  230. package/dist/template/implementations/view_list_columns.template.js +49 -0
  231. package/dist/{templates → template/implementations}/view_search_input.template.d.ts +3 -3
  232. package/dist/template/implementations/view_search_input.template.d.ts.map +1 -0
  233. package/dist/template/implementations/view_search_input.template.js +64 -0
  234. package/dist/template/index.d.ts +7 -0
  235. package/dist/template/index.d.ts.map +1 -0
  236. package/dist/template/index.js +8 -0
  237. package/dist/template/template-manager.d.ts +56 -0
  238. package/dist/template/template-manager.d.ts.map +1 -0
  239. package/dist/template/template-manager.js +125 -0
  240. package/dist/template/template-types.d.ts +16 -0
  241. package/dist/template/template-types.d.ts.map +1 -0
  242. package/dist/template/template-types.js +7 -0
  243. package/dist/template/template.d.ts +49 -0
  244. package/dist/template/template.d.ts.map +1 -0
  245. package/dist/template/template.js +60 -0
  246. package/dist/template/zod-converter.d.ts +51 -0
  247. package/dist/template/zod-converter.d.ts.map +1 -0
  248. package/dist/template/zod-converter.js +449 -0
  249. package/dist/testing/_relation-graph.d.ts +1 -1
  250. package/dist/testing/_relation-graph.d.ts.map +1 -1
  251. package/dist/testing/_relation-graph.js +89 -2
  252. package/dist/testing/fixture-manager.d.ts +42 -11
  253. package/dist/testing/fixture-manager.d.ts.map +1 -1
  254. package/dist/testing/fixture-manager.js +623 -2
  255. package/dist/types/types.d.ts +747 -143
  256. package/dist/types/types.d.ts.map +1 -1
  257. package/dist/types/types.js +546 -2
  258. package/dist/typings/knex.d.js +3 -2
  259. package/dist/utils/async-utils.d.ts +7 -0
  260. package/dist/utils/async-utils.d.ts.map +1 -1
  261. package/dist/utils/async-utils.js +57 -2
  262. package/dist/utils/console-util.d.ts +2 -0
  263. package/dist/utils/console-util.d.ts.map +1 -0
  264. package/dist/utils/console-util.js +6 -0
  265. package/dist/utils/controller.d.ts +1 -0
  266. package/dist/utils/controller.d.ts.map +1 -1
  267. package/dist/utils/controller.js +29 -2
  268. package/dist/utils/esm-utils.d.ts +39 -0
  269. package/dist/utils/esm-utils.d.ts.map +1 -0
  270. package/dist/utils/esm-utils.js +49 -0
  271. package/dist/utils/formatter.d.ts +3 -0
  272. package/dist/utils/formatter.d.ts.map +1 -0
  273. package/dist/utils/formatter.js +110 -0
  274. package/dist/utils/fs-utils.d.ts +1 -1
  275. package/dist/utils/fs-utils.d.ts.map +1 -1
  276. package/dist/utils/fs-utils.js +17 -2
  277. package/dist/utils/lodash-able.d.ts.map +1 -1
  278. package/dist/utils/lodash-able.js +6 -2
  279. package/dist/utils/model.js +22 -2
  280. package/dist/utils/object-utils.d.ts +44 -0
  281. package/dist/utils/object-utils.d.ts.map +1 -0
  282. package/dist/utils/object-utils.js +191 -0
  283. package/dist/utils/path-utils.d.ts +89 -0
  284. package/dist/utils/path-utils.d.ts.map +1 -0
  285. package/dist/utils/path-utils.js +60 -0
  286. package/dist/utils/process-utils.d.ts +13 -0
  287. package/dist/utils/process-utils.d.ts.map +1 -0
  288. package/dist/utils/process-utils.js +36 -0
  289. package/dist/utils/sql-parser.d.ts +5 -1
  290. package/dist/utils/sql-parser.d.ts.map +1 -1
  291. package/dist/utils/sql-parser.js +46 -2
  292. package/dist/utils/type-utils.d.ts +23 -0
  293. package/dist/utils/type-utils.d.ts.map +1 -0
  294. package/dist/utils/type-utils.js +45 -0
  295. package/dist/utils/utils.d.ts +10 -7
  296. package/dist/utils/utils.d.ts.map +1 -1
  297. package/dist/utils/utils.js +72 -2
  298. package/dist/utils/zod-error.d.ts +1 -1
  299. package/dist/utils/zod-error.d.ts.map +1 -1
  300. package/dist/utils/zod-error.js +19 -2
  301. package/package.json +65 -27
  302. package/src/ai/agents/agent.ts +87 -0
  303. package/src/ai/agents/index.ts +2 -0
  304. package/src/ai/agents/types.ts +47 -0
  305. package/src/ai/index.ts +1 -0
  306. package/src/ai/providers/rtzr/api.ts +37 -0
  307. package/src/ai/providers/rtzr/error.ts +34 -0
  308. package/src/ai/providers/rtzr/index.ts +4 -0
  309. package/src/ai/providers/rtzr/model.ts +201 -0
  310. package/src/ai/providers/rtzr/options.ts +49 -0
  311. package/src/ai/providers/rtzr/provider.ts +91 -0
  312. package/src/ai/providers/rtzr/utils.ts +127 -0
  313. package/src/api/base-frame.ts +4 -2
  314. package/src/api/caster.ts +17 -23
  315. package/src/api/code-converters.ts +178 -535
  316. package/src/api/config.ts +125 -0
  317. package/src/api/context.ts +7 -17
  318. package/src/api/decorators.ts +176 -46
  319. package/src/api/index.ts +2 -2
  320. package/src/api/sonamu.ts +190 -167
  321. package/src/api/validator.ts +83 -0
  322. package/src/bin/build-config.ts +8 -1
  323. package/src/bin/cli.ts +258 -124
  324. package/src/bin/hot-hook-register.ts +22 -0
  325. package/src/bin/loader-register.ts +38 -0
  326. package/src/database/_batch_update.ts +46 -31
  327. package/src/database/base-model.ts +390 -182
  328. package/src/database/base-model.types.ts +155 -0
  329. package/src/database/code-generator.ts +13 -32
  330. package/src/database/db.ts +40 -96
  331. package/src/database/puri-subset.test-d.ts +471 -0
  332. package/src/database/puri-subset.types.ts +195 -0
  333. package/src/database/puri-wrapper.ts +58 -67
  334. package/src/database/puri.ts +229 -148
  335. package/src/database/puri.types.ts +76 -30
  336. package/src/database/transaction-context.ts +1 -1
  337. package/src/database/upsert-builder.ts +262 -132
  338. package/src/entity/entity-manager.ts +48 -36
  339. package/src/entity/entity.ts +330 -248
  340. package/src/exceptions/error-handler.ts +3 -3
  341. package/src/exceptions/so-exceptions.ts +11 -11
  342. package/src/file-storage/driver.ts +5 -5
  343. package/src/file-storage/file-storage.ts +2 -2
  344. package/src/index.ts +18 -10
  345. package/src/migration/code-generation.ts +185 -172
  346. package/src/migration/migration-set.ts +80 -293
  347. package/src/migration/migrator.ts +199 -571
  348. package/src/migration/mysql-schema-reader.ts.txt +272 -0
  349. package/src/migration/postgresql-schema-reader.ts +310 -0
  350. package/src/migration/types.ts +6 -39
  351. package/src/naite/messaging-types.ts +51 -0
  352. package/src/naite/naite-reporter.ts +128 -0
  353. package/src/naite/naite.ts +415 -0
  354. package/src/shared/web.shared.ts.txt +20 -24
  355. package/src/stream/sse.ts +5 -5
  356. package/src/syncer/api-parser.ts +282 -0
  357. package/src/syncer/checksum.ts +140 -0
  358. package/src/syncer/code-generator.ts +198 -0
  359. package/src/syncer/entity-operations.ts +65 -0
  360. package/src/syncer/file-patterns.ts +56 -0
  361. package/src/syncer/index.ts +6 -0
  362. package/src/syncer/module-loader.ts +128 -0
  363. package/src/syncer/syncer.ts +389 -1453
  364. package/src/template/entity-converter.ts +114 -0
  365. package/src/template/helpers.ts +81 -0
  366. package/src/{templates → template/implementations}/entity.template.ts +7 -7
  367. package/src/{templates → template/implementations}/generated.template.ts +101 -101
  368. package/src/{templates → template/implementations}/generated_http.template.ts +27 -57
  369. package/src/template/implementations/generated_sso.template.ts +151 -0
  370. package/src/{templates → template/implementations}/init_types.template.ts +5 -7
  371. package/src/{templates → template/implementations}/model.template.ts +52 -43
  372. package/src/{templates → template/implementations}/model_test.template.ts +5 -5
  373. package/src/{templates → template/implementations}/service.template.ts +66 -82
  374. package/src/{templates → template/implementations}/view_enums_buttonset.template.ts +3 -3
  375. package/src/{templates → template/implementations}/view_enums_dropdown.template.ts +4 -20
  376. package/src/{templates → template/implementations}/view_enums_select.template.ts +4 -4
  377. package/src/{templates → template/implementations}/view_form.template.ts +40 -83
  378. package/src/{templates → template/implementations}/view_id_all_select.template.ts +3 -3
  379. package/src/{templates → template/implementations}/view_id_async_select.template.ts +10 -24
  380. package/src/{templates → template/implementations}/view_list.template.ts +60 -152
  381. package/src/{templates → template/implementations}/view_list_columns.template.ts +5 -11
  382. package/src/{templates → template/implementations}/view_search_input.template.ts +3 -3
  383. package/src/template/index.ts +6 -0
  384. package/src/template/template-manager.ts +166 -0
  385. package/src/template/template-types.ts +16 -0
  386. package/src/template/template.ts +105 -0
  387. package/src/template/zod-converter.ts +525 -0
  388. package/src/testing/_relation-graph.ts +18 -11
  389. package/src/testing/fixture-manager.ts +472 -359
  390. package/src/types/types.ts +553 -308
  391. package/src/typings/knex.d.ts +7 -9
  392. package/src/utils/async-utils.ts +23 -10
  393. package/src/utils/console-util.ts +4 -0
  394. package/src/utils/controller.ts +3 -0
  395. package/src/utils/esm-utils.ts +59 -0
  396. package/src/utils/formatter.ts +109 -0
  397. package/src/utils/fs-utils.ts +1 -1
  398. package/src/utils/lodash-able.ts +1 -4
  399. package/src/utils/object-utils.ts +217 -0
  400. package/src/utils/path-utils.ts +99 -0
  401. package/src/utils/process-utils.ts +46 -0
  402. package/src/utils/sql-parser.ts +23 -5
  403. package/src/utils/type-utils.ts +83 -0
  404. package/src/utils/utils.ts +66 -43
  405. package/src/utils/zod-error.ts +3 -4
  406. package/dist/api/base-frame.js.map +0 -1
  407. package/dist/api/caster.js.map +0 -1
  408. package/dist/api/code-converters.js.map +0 -1
  409. package/dist/api/context.js.map +0 -1
  410. package/dist/api/decorators.js.map +0 -1
  411. package/dist/api/index.js.map +0 -1
  412. package/dist/api/sonamu.js.map +0 -1
  413. package/dist/bin/build-config.js.map +0 -1
  414. package/dist/bin/cli-wrapper.d.ts +0 -3
  415. package/dist/bin/cli-wrapper.d.ts.map +0 -1
  416. package/dist/bin/cli-wrapper.js +0 -3
  417. package/dist/bin/cli-wrapper.js.map +0 -1
  418. package/dist/bin/cli.js.map +0 -1
  419. package/dist/database/_batch_update.js.map +0 -1
  420. package/dist/database/base-model.js.map +0 -1
  421. package/dist/database/code-generator.js.map +0 -1
  422. package/dist/database/db.js.map +0 -1
  423. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts +0 -2
  424. package/dist/database/knex-plugins/knex-on-duplicate-update.d.ts.map +0 -1
  425. package/dist/database/knex-plugins/knex-on-duplicate-update.js +0 -2
  426. package/dist/database/knex-plugins/knex-on-duplicate-update.js.map +0 -1
  427. package/dist/database/puri-wrapper.js.map +0 -1
  428. package/dist/database/puri.js.map +0 -1
  429. package/dist/database/puri.types.js.map +0 -1
  430. package/dist/database/transaction-context.js.map +0 -1
  431. package/dist/database/upsert-builder.js.map +0 -1
  432. package/dist/entity/entity-manager.js.map +0 -1
  433. package/dist/entity/entity-utils.d.ts +0 -61
  434. package/dist/entity/entity-utils.d.ts.map +0 -1
  435. package/dist/entity/entity-utils.js +0 -2
  436. package/dist/entity/entity-utils.js.map +0 -1
  437. package/dist/entity/entity.js.map +0 -1
  438. package/dist/exceptions/error-handler.js.map +0 -1
  439. package/dist/exceptions/so-exceptions.js.map +0 -1
  440. package/dist/file-storage/driver.js.map +0 -1
  441. package/dist/file-storage/file-storage.js.map +0 -1
  442. package/dist/index.js.map +0 -1
  443. package/dist/migration/code-generation.js.map +0 -1
  444. package/dist/migration/migration-set.js.map +0 -1
  445. package/dist/migration/migrator.js.map +0 -1
  446. package/dist/migration/types.js.map +0 -1
  447. package/dist/stream/index.js.map +0 -1
  448. package/dist/stream/sse.js.map +0 -1
  449. package/dist/syncer/index.js.map +0 -1
  450. package/dist/syncer/syncer.js.map +0 -1
  451. package/dist/templates/base-template.d.ts +0 -13
  452. package/dist/templates/base-template.d.ts.map +0 -1
  453. package/dist/templates/base-template.js +0 -2
  454. package/dist/templates/base-template.js.map +0 -1
  455. package/dist/templates/entity.template.d.ts.map +0 -1
  456. package/dist/templates/entity.template.js +0 -2
  457. package/dist/templates/entity.template.js.map +0 -1
  458. package/dist/templates/generated.template.d.ts.map +0 -1
  459. package/dist/templates/generated.template.js +0 -2
  460. package/dist/templates/generated.template.js.map +0 -1
  461. package/dist/templates/generated_http.template.d.ts.map +0 -1
  462. package/dist/templates/generated_http.template.js +0 -2
  463. package/dist/templates/generated_http.template.js.map +0 -1
  464. package/dist/templates/generated_sso.template.d.ts.map +0 -1
  465. package/dist/templates/generated_sso.template.js +0 -2
  466. package/dist/templates/generated_sso.template.js.map +0 -1
  467. package/dist/templates/index.d.ts +0 -2
  468. package/dist/templates/index.d.ts.map +0 -1
  469. package/dist/templates/index.js +0 -2
  470. package/dist/templates/index.js.map +0 -1
  471. package/dist/templates/init_types.template.d.ts.map +0 -1
  472. package/dist/templates/init_types.template.js +0 -2
  473. package/dist/templates/init_types.template.js.map +0 -1
  474. package/dist/templates/model.template.d.ts +0 -17
  475. package/dist/templates/model.template.d.ts.map +0 -1
  476. package/dist/templates/model.template.js +0 -2
  477. package/dist/templates/model.template.js.map +0 -1
  478. package/dist/templates/model_test.template.d.ts.map +0 -1
  479. package/dist/templates/model_test.template.js +0 -2
  480. package/dist/templates/model_test.template.js.map +0 -1
  481. package/dist/templates/service.template.d.ts.map +0 -1
  482. package/dist/templates/service.template.js +0 -2
  483. package/dist/templates/service.template.js.map +0 -1
  484. package/dist/templates/view_enums_buttonset.template.d.ts.map +0 -1
  485. package/dist/templates/view_enums_buttonset.template.js +0 -2
  486. package/dist/templates/view_enums_buttonset.template.js.map +0 -1
  487. package/dist/templates/view_enums_dropdown.template.d.ts.map +0 -1
  488. package/dist/templates/view_enums_dropdown.template.js +0 -2
  489. package/dist/templates/view_enums_dropdown.template.js.map +0 -1
  490. package/dist/templates/view_enums_select.template.d.ts.map +0 -1
  491. package/dist/templates/view_enums_select.template.js +0 -2
  492. package/dist/templates/view_enums_select.template.js.map +0 -1
  493. package/dist/templates/view_form.template.d.ts.map +0 -1
  494. package/dist/templates/view_form.template.js +0 -2
  495. package/dist/templates/view_form.template.js.map +0 -1
  496. package/dist/templates/view_id_all_select.template.d.ts.map +0 -1
  497. package/dist/templates/view_id_all_select.template.js +0 -2
  498. package/dist/templates/view_id_all_select.template.js.map +0 -1
  499. package/dist/templates/view_id_async_select.template.d.ts.map +0 -1
  500. package/dist/templates/view_id_async_select.template.js +0 -2
  501. package/dist/templates/view_id_async_select.template.js.map +0 -1
  502. package/dist/templates/view_list.template.d.ts.map +0 -1
  503. package/dist/templates/view_list.template.js +0 -2
  504. package/dist/templates/view_list.template.js.map +0 -1
  505. package/dist/templates/view_list_columns.template.d.ts +0 -17
  506. package/dist/templates/view_list_columns.template.d.ts.map +0 -1
  507. package/dist/templates/view_list_columns.template.js +0 -2
  508. package/dist/templates/view_list_columns.template.js.map +0 -1
  509. package/dist/templates/view_search_input.template.d.ts.map +0 -1
  510. package/dist/templates/view_search_input.template.js +0 -2
  511. package/dist/templates/view_search_input.template.js.map +0 -1
  512. package/dist/testing/_relation-graph.js.map +0 -1
  513. package/dist/testing/fixture-manager.js.map +0 -1
  514. package/dist/types/types.js.map +0 -1
  515. package/dist/typings/knex.d.js.map +0 -1
  516. package/dist/utils/async-utils.js.map +0 -1
  517. package/dist/utils/controller.js.map +0 -1
  518. package/dist/utils/fs-utils.js.map +0 -1
  519. package/dist/utils/lodash-able.js.map +0 -1
  520. package/dist/utils/model.js.map +0 -1
  521. package/dist/utils/sql-parser.js.map +0 -1
  522. package/dist/utils/utils.js.map +0 -1
  523. package/dist/utils/zod-error.js.map +0 -1
  524. package/src/bin/cli-wrapper.ts +0 -75
  525. package/src/database/knex-plugins/knex-on-duplicate-update.ts +0 -45
  526. package/src/entity/entity-utils.ts +0 -291
  527. package/src/templates/base-template.ts +0 -19
  528. package/src/templates/generated_sso.template.ts +0 -138
  529. package/src/templates/index.ts +0 -1
@@ -1,2 +1,422 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"Syncer",{enumerable:true,get:function(){return Syncer}});var _path=/*#__PURE__*/_interop_require_wildcard(require("path"));var _utils=require("../utils/utils");var _fs=require("fs");var _promises=require("fs/promises");var _fsutils=require("../utils/fs-utils");var _crypto=/*#__PURE__*/_interop_require_default(require("crypto"));var _fastdeepequal=/*#__PURE__*/_interop_require_default(require("fast-deep-equal"));var _lodash=/*#__PURE__*/_interop_require_wildcard(require("lodash"));var _inflection=/*#__PURE__*/_interop_require_default(require("inflection"));var _entitymanager=require("../entity/entity-manager");var _typescript=/*#__PURE__*/_interop_require_default(require("typescript"));var _types=require("../types/types");var _decorators=require("../api/decorators");var _zod=require("zod");var _chalk=/*#__PURE__*/_interop_require_default(require("chalk"));var _soexceptions=require("../exceptions/so-exceptions");var _lodashable=require("../utils/lodash-able");var _codeconverters=require("../api/code-converters");var _generatedtemplate=require("../templates/generated.template");var _init_typestemplate=require("../templates/init_types.template");var _entitytemplate=require("../templates/entity.template");var _modeltemplate=require("../templates/model.template");var _model_testtemplate=require("../templates/model_test.template");var _servicetemplate=require("../templates/service.template");var _view_formtemplate=require("../templates/view_form.template");var _view_listtemplate=require("../templates/view_list.template");var _prettier=/*#__PURE__*/_interop_require_default(require("prettier"));var _view_id_all_selecttemplate=require("../templates/view_id_all_select.template");var _view_id_async_selecttemplate=require("../templates/view_id_async_select.template");var _view_enums_dropdowntemplate=require("../templates/view_enums_dropdown.template");var _view_enums_selecttemplate=require("../templates/view_enums_select.template");var _view_enums_buttonsettemplate=require("../templates/view_enums_buttonset.template");var _view_search_inputtemplate=require("../templates/view_search_input.template");var _view_list_columnstemplate=require("../templates/view_list_columns.template");var _generated_httptemplate=require("../templates/generated_http.template");var _sonamu=require("../api/sonamu");var _generated_ssotemplate=require("../templates/generated_sso.template");var _promises1=require("timers/promises");var _assert=/*#__PURE__*/_interop_require_default(require("assert"));var _core=/*#__PURE__*/_interop_require_wildcard(require("@swc/core"));var _minimatch=require("minimatch");var _asyncutils=require("../utils/async-utils");function _array_like_to_array(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i<len;i++)arr2[i]=arr[i];return arr2}function _array_with_holes(arr){if(Array.isArray(arr))return arr}function _array_without_holes(arr){if(Array.isArray(arr))return _array_like_to_array(arr)}function _async_iterator(iterable){var method,async,sync,retry=2;for("undefined"!=typeof Symbol&&(async=Symbol.asyncIterator,sync=Symbol.iterator);retry--;){if(async&&null!=(method=iterable[async]))return method.call(iterable);if(sync&&null!=(method=iterable[sync]))return new AsyncFromSyncIterator(method.call(iterable));async="@@asyncIterator",sync="@@iterator"}throw new TypeError("Object is not async iterable")}function AsyncFromSyncIterator(s){function AsyncFromSyncIteratorContinuation(r){if(Object(r)!==r)return Promise.reject(new TypeError(r+" is not an object."));var done=r.done;return Promise.resolve(r.value).then(function(value){return{value:value,done:done}})}return AsyncFromSyncIterator=function(s){this.s=s,this.n=s.next},AsyncFromSyncIterator.prototype={s:null,n:null,next:function(){return AsyncFromSyncIteratorContinuation(this.n.apply(this.s,arguments))},return:function(value){var ret=this.s.return;return void 0===ret?Promise.resolve({value:value,done:!0}):AsyncFromSyncIteratorContinuation(ret.apply(this.s,arguments))},throw:function(value){var thr=this.s.return;return void 0===thr?Promise.reject(value):AsyncFromSyncIteratorContinuation(thr.apply(this.s,arguments))}},new AsyncFromSyncIterator(s)}function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{Promise.resolve(value).then(_next,_throw)}}function _async_to_generator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value)}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err)}_next(undefined)})}}function _class_call_check(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor)}}function _create_class(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor}function _define_property(obj,key,value){if(key in obj){Object.defineProperty(obj,key,{value:value,enumerable:true,configurable:true,writable:true})}else{obj[key]=value}return obj}function _instanceof(left,right){if(right!=null&&typeof Symbol!=="undefined"&&right[Symbol.hasInstance]){return!!right[Symbol.hasInstance](left)}else{return left instanceof right}}function _interop_require_default(obj){return obj&&obj.__esModule?obj:{default:obj}}function _getRequireWildcardCache(nodeInterop){if(typeof WeakMap!=="function")return null;var cacheBabelInterop=new WeakMap;var cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}function _interop_require_wildcard(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule){return obj}if(obj===null||typeof obj!=="object"&&typeof obj!=="function"){return{default:obj}}var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj)){return cache.get(obj)}var newObj={__proto__:null};var hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj){if(key!=="default"&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;if(desc&&(desc.get||desc.set)){Object.defineProperty(newObj,key,desc)}else{newObj[key]=obj[key]}}}newObj.default=obj;if(cache){cache.set(obj,newObj)}return newObj}function _iterable_to_array(iter){if(typeof Symbol!=="undefined"&&iter[Symbol.iterator]!=null||iter["@@iterator"]!=null)return Array.from(iter)}function _iterable_to_array_limit(arr,i){var _i=arr==null?null:typeof Symbol!=="undefined"&&arr[Symbol.iterator]||arr["@@iterator"];if(_i==null)return;var _arr=[];var _n=true;var _d=false;var _s,_e;try{for(_i=_i.call(arr);!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"]!=null)_i["return"]()}finally{if(_d)throw _e}}return _arr}function _non_iterable_rest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _non_iterable_spread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _object_spread(target){for(var i=1;i<arguments.length;i++){var source=arguments[i]!=null?arguments[i]:{};var ownKeys=Object.keys(source);if(typeof Object.getOwnPropertySymbols==="function"){ownKeys=ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym){return Object.getOwnPropertyDescriptor(source,sym).enumerable}))}ownKeys.forEach(function(key){_define_property(target,key,source[key])})}return target}function ownKeys(object,enumerableOnly){var keys=Object.keys(object);if(Object.getOwnPropertySymbols){var symbols=Object.getOwnPropertySymbols(object);if(enumerableOnly){symbols=symbols.filter(function(sym){return Object.getOwnPropertyDescriptor(object,sym).enumerable})}keys.push.apply(keys,symbols)}return keys}function _object_spread_props(target,source){source=source!=null?source:{};if(Object.getOwnPropertyDescriptors){Object.defineProperties(target,Object.getOwnPropertyDescriptors(source))}else{ownKeys(Object(source)).forEach(function(key){Object.defineProperty(target,key,Object.getOwnPropertyDescriptor(source,key))})}return target}function _sliced_to_array(arr,i){return _array_with_holes(arr)||_iterable_to_array_limit(arr,i)||_unsupported_iterable_to_array(arr,i)||_non_iterable_rest()}function _to_consumable_array(arr){return _array_without_holes(arr)||_iterable_to_array(arr)||_unsupported_iterable_to_array(arr)||_non_iterable_spread()}function _unsupported_iterable_to_array(o,minLen){if(!o)return;if(typeof o==="string")return _array_like_to_array(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(n);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _array_like_to_array(o,minLen)}function _ts_generator(thisArg,body){var f,y,t,_={label:0,sent:function(){if(t[0]&1)throw t[1];return t[1]},trys:[],ops:[]},g=Object.create((typeof Iterator==="function"?Iterator:Object).prototype);return g.next=verb(0),g["throw"]=verb(1),g["return"]=verb(2),typeof Symbol==="function"&&(g[Symbol.iterator]=function(){return this}),g;function verb(n){return function(v){return step([n,v])}}function step(op){if(f)throw new TypeError("Generator is already executing.");while(g&&(g=0,op[0]&&(_=0)),_)try{if(f=1,y&&(t=op[0]&2?y["return"]:op[0]?y["throw"]||((t=y["return"])&&t.call(y),0):y.next)&&!(t=t.call(y,op[1])).done)return t;if(y=0,t)op=[op[0]&2,t.value];switch(op[0]){case 0:case 1:t=op;break;case 4:_.label++;return{value:op[1],done:false};case 5:_.label++;y=op[1];op=[0];continue;case 7:op=_.ops.pop();_.trys.pop();continue;default:if(!(t=_.trys,t=t.length>0&&t[t.length-1])&&(op[0]===6||op[0]===2)){_=0;continue}if(op[0]===3&&(!t||op[1]>t[0]&&op[1]<t[3])){_.label=op[1];break}if(op[0]===6&&_.label<t[1]){_.label=t[1];t=op;break}if(t&&_.label<t[2]){_.label=t[2];_.ops.push(op);break}if(t[2])_.ops.pop();_.trys.pop();continue}op=body.call(thisArg,_)}catch(e){op=[6,e];y=0}finally{f=t=0}if(op[0]&5)throw op[1];return{value:op[0]?op[1]:void 0,done:true}}}var Syncer=/*#__PURE__*/function(){"use strict";function Syncer(){var _this=this;_class_call_check(this,Syncer);_define_property(this,"apis",[]);_define_property(this,"types",{});_define_property(this,"models",{});_define_property(this,"isSyncing",false);_define_property(this,"checksumPatternGroup",{entity:_sonamu.Sonamu.apiRootPath+"/src/application/**/*.entity.json",types:_sonamu.Sonamu.apiRootPath+"/src/application/**/*.types.ts",generated:_sonamu.Sonamu.apiRootPath+"/src/application/sonamu.generated.ts",functions:_sonamu.Sonamu.apiRootPath+"/src/application/**/*.functions.ts",model:_sonamu.Sonamu.apiRootPath+"/dist/application/**/*.model.js",frame:_sonamu.Sonamu.apiRootPath+"/dist/application/**/*.frame.js"});_define_property(this,"resolveParamDec",function(paramDec){var index=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0;var name=paramDec.name;var type=_this.resolveTypeNode(paramDec.type);if(name===undefined){console.debug({name:name,type:type,paramDec:paramDec})}var result={name:name.escapedText?name.escapedText.toString():"nonameAt".concat(index),type:type,optional:paramDec.optional===true,defaultDef:paramDec===null||paramDec===void 0?void 0:paramDec.defaultDef};if(_typescript.default.isObjectBindingPattern(name)&&_typescript.default.isTypeReferenceNode(paramDec.type)&&_typescript.default.isIdentifier(paramDec.type.typeName)){result.name=_inflection.default.camelize(paramDec.type.typeName.text,true)}return result})}_create_class(Syncer,[{key:"checksumsPath",get:function get(){return _path.default.join(_sonamu.Sonamu.apiRootPath,"/sonamu.lock")}},{key:"sync",value:function sync(){return _async_to_generator(function(){var _this,targets,currentDirname,currentChecksums,previousChecksums,isSame,msg,margin,abc,onSIGUSR2,diff,diffFiles,changedChecksums;return _ts_generator(this,function(_state){switch(_state.label){case 0:_this=this;targets=_sonamu.Sonamu.config.sync.targets;currentDirname=__dirname.endsWith("/syncer")?__dirname:_path.default.join(__dirname,"./syncer");return[4,Promise.all(targets.map(function(target){return _async_to_generator(function(){var _this,srcCodePath,dstCodePath,srcChecksum,dstChecksum,_tmp;return _ts_generator(this,function(_state){switch(_state.label){case 0:_this=this;srcCodePath=_path.default.join(currentDirname,"../shared/".concat(target,".shared.ts.txt")).replace("/dist/","/src/");return[4,(0,_fsutils.exists)(srcCodePath)];case 1:if(!_state.sent()){return[2]}dstCodePath=_path.default.join(_sonamu.Sonamu.appRootPath,target,"src/services/sonamu.shared.ts");return[4,this.getChecksumOfFile(srcCodePath)];case 2:srcChecksum=_state.sent();return[4,function(){return _async_to_generator(function(){return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,(0,_fsutils.exists)(dstCodePath)];case 1:if(!_state.sent()){return[2,""]}return[2,this.getChecksumOfFile(dstCodePath)]}})}).call(_this)}()];case 3:dstChecksum=_state.sent();if(srcChecksum===dstChecksum){return[2]}_tmp=[dstCodePath];return[4,(0,_promises.readFile)(srcCodePath)];case 4:return[4,_promises.writeFile.apply(void 0,_tmp.concat([_state.sent()]))];case 5:_state.sent();console.log(_chalk.default.blue("shared.ts is synced"));return[2]}})}).call(_this)}))];case 1:_state.sent();return[4,this.getCurrentChecksums()];case 2:currentChecksums=_state.sent();return[4,this.getPreviousChecksums()];case 3:previousChecksums=_state.sent();isSame=(0,_fastdeepequal.default)(currentChecksums,previousChecksums);if(isSame){msg="All files are synced!";margin=(process.stdout.columns-msg.length)/2;console.log(_chalk.default.black.bgGreen(" ".repeat(margin)+msg+" ".repeat(margin)));return[2]}abc=new AbortController;this.isSyncing=true;onSIGUSR2=function(){return _async_to_generator(function(){var e;return _ts_generator(this,function(_state){switch(_state.label){case 0:if(this.isSyncing===false){process.exit(0)}console.log(_chalk.default.magentaBright("wait for syncing done...."));_state.label=1;case 1:_state.trys.push([1,3,,4]);return[4,(0,_promises1.setTimeout)(2e4,"waiting-sync",{signal:abc.signal})];case 2:_state.sent();return[3,4];case 3:e=_state.sent();return[3,4];case 4:console.log(_chalk.default.magentaBright("Syncing DONE!"));process.exit(0);return[2]}})}).call(_this)};process.on("SIGUSR2",onSIGUSR2);diff=_lodash.default.differenceWith(currentChecksums,previousChecksums,_lodash.default.isEqual);diffFiles=diff.map(function(r){return r.path});console.log("Changed Files: ",diffFiles);return[4,this.doSyncActions(diffFiles,currentChecksums)];case 4:changedChecksums=_state.sent().changedChecksums;currentChecksums=changedChecksums!==null&&changedChecksums!==void 0?changedChecksums:currentChecksums;return[4,this.saveChecksums(currentChecksums)];case 5:_state.sent();this.isSyncing=false;abc.abort();process.off("SIGUSR2",onSIGUSR2);return[2]}})}).call(this)}},{key:"doSyncActions",value:function doSyncActions(diffFiles,currentChecksums){return _async_to_generator(function(){var _this,diffGroups,diffTypes,_diffGroups_entity,entityId,entity,typeFilePath,_tmp,_diffGroups_generated,_diffGroups_types,_diffGroups_functions,_diffGroups_generated1,tsPaths,_diffGroups_model,_diffGroups_frame,mergedGroup,params;return _ts_generator(this,function(_state){switch(_state.label){case 0:_this=this;diffGroups=_lodash.default.groupBy(diffFiles,function(r){var matched=r.match(/\.(model|types|functions|entity|generated|frame)\.[tj]s/);var _matched_;return(_matched_=matched===null||matched===void 0?void 0:matched[1])!==null&&_matched_!==void 0?_matched_:"unknown"});diffTypes=Object.keys(diffGroups);if(!(diffTypes.includes("entity")||diffTypes.includes("types")))return[3,8];return[4,_entitymanager.EntityManager.reload()];case 1:_state.sent();return[4,this.actionGenerateSchemas()];case 2:_state.sent();entityId=this.getEntityIdFromPath(_to_consumable_array((_diffGroups_entity=diffGroups["entity"])!==null&&_diffGroups_entity!==void 0?_diffGroups_entity:[]))[0];if(!entityId)return[3,6];entity=_entitymanager.EntityManager.get(entityId);typeFilePath=_path.default.join(_sonamu.Sonamu.apiRootPath,"src/application/".concat(entity.names.fs,"/").concat(entity.names.fs,".types.ts"));_tmp=entity.parentId===undefined;if(!_tmp)return[3,4];return[4,(0,_fsutils.exists)(typeFilePath)];case 3:_tmp=!_state.sent();_state.label=4;case 4:if(!_tmp)return[3,6];return[4,this.generateTemplate("init_types",{entityId:entityId})];case 5:_state.sent();_state.label=6;case 6:diffGroups["generated"]=_lodash.default.uniq(_to_consumable_array((_diffGroups_generated=diffGroups["generated"])!==null&&_diffGroups_generated!==void 0?_diffGroups_generated:[]).concat(["/src/application/sonamu.generated.ts"]));diffTypes.push("generated");if(!currentChecksums)return[3,8];return[4,this.getCurrentChecksums()];case 7:currentChecksums=_state.sent();_state.label=8;case 8:if(!(diffTypes.includes("types")||diffTypes.includes("functions")||diffTypes.includes("generated")))return[3,10];tsPaths=_lodash.default.uniq(_to_consumable_array((_diffGroups_types=diffGroups["types"])!==null&&_diffGroups_types!==void 0?_diffGroups_types:[]).concat(_to_consumable_array((_diffGroups_functions=diffGroups["functions"])!==null&&_diffGroups_functions!==void 0?_diffGroups_functions:[]),_to_consumable_array((_diffGroups_generated1=diffGroups["generated"])!==null&&_diffGroups_generated1!==void 0?_diffGroups_generated1:[])).map(function(p){return p.replace("/dist/","/src/").replace(".js",".ts")}));return[4,this.actionSyncFilesToTargets(tsPaths)];case 9:_state.sent();_state.label=10;case 10:if(!(diffTypes.includes("model")||diffTypes.includes("frame")))return[3,15];mergedGroup=_to_consumable_array((_diffGroups_model=diffGroups["model"])!==null&&_diffGroups_model!==void 0?_diffGroups_model:[]).concat(_to_consumable_array((_diffGroups_frame=diffGroups["frame"])!==null&&_diffGroups_frame!==void 0?_diffGroups_frame:[]));return[4,this.autoloadModels()];case 11:_state.sent();return[4,this.autoloadApis()];case 12:_state.sent();params=mergedGroup.map(function(modelPath){if(modelPath.endsWith(".model.js")){var entityId=_this.getEntityIdFromPath([modelPath])[0];(0,_assert.default)(entityId);return{namesRecord:_entitymanager.EntityManager.getNamesFromId(entityId),modelTsPath:_path.default.join(_sonamu.Sonamu.apiRootPath,modelPath.replace("/dist/","/src/").replace(".model.js",".model.ts"))}}if(modelPath.endsWith("frame.js")){var _modelPath_match;var _ref=_sliced_to_array((_modelPath_match=modelPath.match(/.+\/(.+)\.frame.js$/))!==null&&_modelPath_match!==void 0?_modelPath_match:[],2),frameName=_ref[1];(0,_assert.default)(frameName);return{namesRecord:_entitymanager.EntityManager.getNamesFromId(frameName),modelTsPath:_path.default.join(_sonamu.Sonamu.apiRootPath,modelPath.replace("/dist/","/src/").replace(".frame.js",".frame.ts"))}}throw new Error("not reachable")});return[4,this.actionGenerateServices(params)];case 13:_state.sent();return[4,this.actionGenerateHttps()];case 14:_state.sent();_state.label=15;case 15:return[2,{diffTypes:diffTypes,changedChecksums:currentChecksums}]}})}).call(this)}},{key:"syncFromWatcher",value:function syncFromWatcher(diffFiles){return _async_to_generator(function(){var _this,tsFiles,jsonFiles,chunks,transpiledFilePaths,_iteratorNormalCompletion,_didIteratorError,_iteratorError,_iterator,_step,_$chunk,_transpiledFilePaths,_transpiledFilePaths1,err,allFilePaths,targetFilePaths;function clearModuleAndDependents(filePath){var resolved=require.resolve(filePath);var toDelete=new Set([resolved]);Object.keys(require.cache).forEach(function(key){var _mod_children;var mod=require.cache[key];if(mod===null||mod===void 0?void 0:(_mod_children=mod.children)===null||_mod_children===void 0?void 0:_mod_children.some(function(child){return child.id===resolved})){toDelete.add(key)}});toDelete.forEach(function(key){if(key.includes("dist/index.js")){process.kill(process.pid,"SIGUSR2")}delete require.cache[key]})}return _ts_generator(this,function(_state){switch(_state.label){case 0:_this=this;tsFiles=diffFiles.filter(function(file){return file.endsWith(".ts")});jsonFiles=diffFiles.filter(function(file){return file.endsWith(".json")});chunks=(0,_lodash.chunk)(tsFiles,5);transpiledFilePaths=[];_iteratorNormalCompletion=true,_didIteratorError=false,_iteratorError=undefined;_state.label=1;case 1:_state.trys.push([1,6,7,8]);_iterator=chunks[Symbol.iterator]();_state.label=2;case 2:if(!!(_iteratorNormalCompletion=(_step=_iterator.next()).done))return[3,5];_$chunk=_step.value;return[4,Promise.all(_$chunk.map(function(diffFile){return _async_to_generator(function(){var _ref,code,map,jsPath,mapPath,sourceMapComment;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,_core.transformFile(diffFile,{module:{type:"commonjs"},jsc:{parser:{syntax:"typescript",decorators:true},target:"es5"},sourceMaps:true})];case 1:_ref=_state.sent(),code=_ref.code,map=_ref.map;jsPath=diffFile.replace("/src/","/dist/").replace(".ts",".js");return[4,(0,_promises.mkdir)(_path.default.dirname(jsPath),{recursive:true})];case 2:_state.sent();return[4,(0,_promises.writeFile)(jsPath,code)];case 3:_state.sent();if(!map)return[3,7];mapPath=jsPath+".map";return[4,(0,_promises.mkdir)(_path.default.dirname(mapPath),{recursive:true})];case 4:_state.sent();return[4,(0,_promises.writeFile)(mapPath,map)];case 5:_state.sent();sourceMapComment="\n//# sourceMappingURL="+_path.default.basename(mapPath);return[4,(0,_promises.writeFile)(jsPath,sourceMapComment,{flag:"a"})];case 6:_state.sent();_state.label=7;case 7:console.log(_chalk.default.bold("Transpiled: ")+_chalk.default.blue("".concat(jsPath.replace(_sonamu.Sonamu.apiRootPath,"api"))));return[2,jsPath]}})})()}))];case 3:_transpiledFilePaths1=_state.sent();(_transpiledFilePaths=transpiledFilePaths).push.apply(_transpiledFilePaths,_to_consumable_array(_transpiledFilePaths1));_state.label=4;case 4:_iteratorNormalCompletion=true;return[3,2];case 5:return[3,8];case 6:err=_state.sent();_didIteratorError=true;_iteratorError=err;return[3,8];case 7:try{if(!_iteratorNormalCompletion&&_iterator.return!=null){_iterator.return()}}finally{if(_didIteratorError){throw _iteratorError}}return[7];case 8:transpiledFilePaths.map(function(filePath){clearModuleAndDependents(filePath)});allFilePaths=_to_consumable_array(tsFiles).concat(_to_consumable_array(transpiledFilePaths),_to_consumable_array(jsonFiles));targetFilePaths=allFilePaths.filter(function(filePath){return Object.values(_this.checksumPatternGroup).some(function(pattern){return(0,_minimatch.minimatch)(filePath,pattern)})}).map(function(filePath){return"/"+_path.default.relative(_sonamu.Sonamu.apiRootPath,filePath)});return[4,this.doSyncActions(targetFilePaths)];case 9:_state.sent();this.apis=[];this.types={};this.models={};return[4,this.autoloadTypes()];case 10:_state.sent();return[4,this.autoloadModels()];case 11:_state.sent();return[4,this.autoloadApis()];case 12:_state.sent();this.syncUI();return[2]}})}).call(this)}},{key:"getEntityIdFromPath",value:function getEntityIdFromPath(filePaths){return _lodash.default.uniq(filePaths.map(function(p){var matched=p.match(/application\/(.+)\//);(0,_assert.default)(matched&&matched[1]);return _inflection.default.camelize(matched[1].replace(/\-/g,"_"))}))}},{key:"actionGenerateSchemas",value:function actionGenerateSchemas(){return _async_to_generator(function(){return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,Promise.all([this.generateTemplate("generated_sso",{},{overwrite:true}),this.generateTemplate("generated",{},{overwrite:true})])];case 1:return[2,_state.sent().flat().flat()]}})}).call(this)}},{key:"actionGenerateServices",value:function actionGenerateServices(paramsArray){return _async_to_generator(function(){var _this;return _ts_generator(this,function(_state){switch(_state.label){case 0:_this=this;return[4,Promise.all(paramsArray.map(function(params){return _async_to_generator(function(){return _ts_generator(this,function(_state){return[2,this.generateTemplate("service",params,{overwrite:true})]})}).call(_this)}))];case 1:return[2,_state.sent().flat().flat()]}})}).call(this)}},{key:"actionGenerateHttps",value:function actionGenerateHttps(){return _async_to_generator(function(){var _ref,res;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,this.generateTemplate("generated_http",{},{overwrite:true})];case 1:_ref=_sliced_to_array.apply(void 0,[_state.sent(),1]),res=_ref[0];(0,_assert.default)(res);return[2,res]}})}).call(this)}},{key:"copyFileWithReplaceCoreToShared",value:function copyFileWithReplaceCoreToShared(fromPath,toPath){return _async_to_generator(function(){var oldFileContent,newFileContent;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,(0,_fsutils.exists)(fromPath)];case 1:if(!_state.sent()){return[2]}return[4,(0,_promises.readFile)(fromPath)];case 2:oldFileContent=_state.sent().toString();newFileContent=function(){var nfc=oldFileContent.replace(/from "sonamu"/g,'from "src/services/sonamu.shared"');if(toPath.includes("/web/")){return nfc.replace(/from "lodash";/g,'from "lodash-es";')}else{return nfc}}();return[2,(0,_promises.writeFile)(toPath,newFileContent)]}})})()}},{key:"actionSyncFilesToTargets",value:function actionSyncFilesToTargets(tsPaths){return _async_to_generator(function(){var _this,targets,_Sonamu_config_api,apiDir;return _ts_generator(this,function(_state){switch(_state.label){case 0:_this=this;targets=_sonamu.Sonamu.config.sync.targets;_Sonamu_config_api=_sonamu.Sonamu.config.api,apiDir=_Sonamu_config_api.dir;return[4,Promise.all(targets.map(function(target){return _async_to_generator(function(){var _this;return _ts_generator(this,function(_state){_this=this;return[2,Promise.all(tsPaths.map(function(src){return _async_to_generator(function(){var realSrc,dst,dir;return _ts_generator(this,function(_state){switch(_state.label){case 0:realSrc=_sonamu.Sonamu.apiRootPath+src;dst=realSrc.replace("/".concat(apiDir,"/"),"/".concat(target,"/")).replace("/application/","/services/");dir=(0,_path.dirname)(dst);return[4,(0,_fsutils.exists)(dir)];case 1:if(!!_state.sent())return[3,3];return[4,(0,_promises.mkdir)(dir,{recursive:true})];case 2:_state.sent();_state.label=3;case 3:console.log(_chalk.default.bold("Copied: ")+_chalk.default.blue("Copied: ".concat(dst.replace(_sonamu.Sonamu.appRootPath+"/",""))));return[4,this.copyFileWithReplaceCoreToShared(realSrc,dst)];case 4:_state.sent();return[2,dst]}})}).call(_this)}))]})}).call(_this)}))];case 1:return[2,_state.sent().flat()]}})}).call(this)}},{key:"getCurrentChecksums",value:function getCurrentChecksums(){return _async_to_generator(function(){var _this,filePaths,fileChecksums;return _ts_generator(this,function(_state){switch(_state.label){case 0:_this=this;return[4,Promise.all(Object.entries(this.checksumPatternGroup).map(function(param){var _param=_sliced_to_array(param,2),_fileType=_param[0],pattern=_param[1];return _async_to_generator(function(){return _ts_generator(this,function(_state){return[2,(0,_utils.globAsync)(pattern)]})})()}))];case 1:filePaths=_state.sent().flat().sort();return[4,Promise.all(filePaths.map(function(filePath){return _async_to_generator(function(){var _tmp;return _ts_generator(this,function(_state){switch(_state.label){case 0:_tmp={path:filePath.substring(_sonamu.Sonamu.apiRootPath.length)};return[4,this.getChecksumOfFile(filePath)];case 1:return[2,(_tmp.checksum=_state.sent(),_tmp)]}})}).call(_this)}))];case 2:fileChecksums=_state.sent();return[2,fileChecksums]}})}).call(this)}},{key:"getPreviousChecksums",value:function getPreviousChecksums(){return _async_to_generator(function(){var previousChecksums,_;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,(0,_fsutils.exists)(this.checksumsPath)];case 1:if(!_state.sent()){return[2,[]]}_=JSON.parse;return[4,(0,_promises.readFile)(this.checksumsPath,"utf-8")];case 2:previousChecksums=_.apply(JSON,[_state.sent()]);return[2,previousChecksums]}})}).call(this)}},{key:"saveChecksums",value:function saveChecksums(checksums){return _async_to_generator(function(){return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,(0,_promises.writeFile)(this.checksumsPath,JSON.stringify(checksums,null,2),"utf-8")];case 1:_state.sent();console.log("checksum saved",this.checksumsPath);return[2]}})}).call(this)}},{key:"getChecksumOfFile",value:function getChecksumOfFile(filePath){return _async_to_generator(function(){return _ts_generator(this,function(_state){return[2,new Promise(function(resolve,reject){var hash=_crypto.default.createHash("sha1");var input=(0,_fs.createReadStream)(filePath);input.on("error",reject);input.on("data",function(chunk){hash.update(chunk)});input.on("close",function(){resolve(hash.digest("hex"))})})]})})()}},{key:"readApisFromFile",value:function readApisFromFile(filePath){return _async_to_generator(function(){var _this,sourceFile,_,_tmp,methods,modelName,methodName,visitor,currentModelApis,extendedApis;return _ts_generator(this,function(_state){switch(_state.label){case 0:_this=this;_=_typescript.default.createSourceFile;_tmp=[filePath];return[4,(0,_promises.readFile)(filePath)];case 1:sourceFile=_.apply(_typescript.default,_tmp.concat([_state.sent().toString(),_typescript.default.ScriptTarget.Latest]));methods=[];modelName="UnknownModel";methodName="unknownMethod";visitor=function(node){if(_typescript.default.isClassDeclaration(node)){if(node.name&&_typescript.default.isIdentifier(node.name)){modelName=node.name.escapedText.toString().replace(/Class$/,"")}}if(_typescript.default.isMethodDeclaration(node)){if(_typescript.default.isIdentifier(node.name)){methodName=node.name.escapedText.toString()}var _node_typeParameters;var typeParameters=((_node_typeParameters=node.typeParameters)!==null&&_node_typeParameters!==void 0?_node_typeParameters:[]).map(function(typeParam){var tp=typeParam;return{t:"type-param",id:tp.name.escapedText.toString(),constraint:tp.constraint?_this.resolveTypeNode(tp.constraint):undefined}});var parameters=node.parameters.map(function(paramDec,index){var defaultDef=_this.printNode(paramDec.initializer,sourceFile);return _this.resolveParamDec({name:paramDec.name,type:paramDec.type,optional:paramDec.questionToken!==undefined||paramDec.initializer!==undefined,defaultDef:defaultDef},index)});if(node.type===undefined){throw new Error("리턴 타입이 기재되지 않은 메소드 ".concat(modelName,".").concat(methodName))}var returnType=_this.resolveTypeNode(node.type);methods.push({modelName:modelName,methodName:methodName,typeParameters:typeParameters,parameters:parameters,returnType:returnType})}_typescript.default.forEachChild(node,visitor)};visitor(sourceFile);if(methods.length===0){return[2,[]]}currentModelApis=_decorators.registeredApis.filter(function(api){return methods.find(function(method){return method.modelName===api.modelName&&method.methodName===api.methodName})});if(currentModelApis.length===0){throw new Error("현재 파일에 사전 등록된 API가 없습니다. ".concat(filePath))}extendedApis=currentModelApis.map(function(api){var foundMethod=methods.find(function(method){return method.modelName===api.modelName&&method.methodName===api.methodName});return _object_spread_props(_object_spread({},api),{typeParameters:foundMethod.typeParameters,parameters:foundMethod.parameters,returnType:foundMethod.returnType})});return[2,extendedApis]}})}).call(this)}},{key:"resolveTypeNode",value:function resolveTypeNode(typeNode){var _this=this;switch(typeNode===null||typeNode===void 0?void 0:typeNode.kind){case _typescript.default.SyntaxKind.AnyKeyword:return"any";case _typescript.default.SyntaxKind.UnknownKeyword:return"unknown";case _typescript.default.SyntaxKind.StringKeyword:return"string";case _typescript.default.SyntaxKind.NumberKeyword:return"number";case _typescript.default.SyntaxKind.BooleanKeyword:return"boolean";case _typescript.default.SyntaxKind.UndefinedKeyword:return"undefined";case _typescript.default.SyntaxKind.NullKeyword:return"null";case _typescript.default.SyntaxKind.VoidKeyword:return"void";case _typescript.default.SyntaxKind.LiteralType:var literal=typeNode.literal;if(_typescript.default.isStringLiteral(literal)){return{t:"string-literal",value:literal.text}}else if(_typescript.default.isNumericLiteral(literal)){return{t:"numeric-literal",value:Number(literal.text)}}else{if(literal.kind===_typescript.default.SyntaxKind.NullKeyword){return"null"}else if(literal.kind===_typescript.default.SyntaxKind.UndefinedKeyword){return"undefined"}else if(literal.kind===_typescript.default.SyntaxKind.TrueKeyword){return"true"}else if(literal.kind===_typescript.default.SyntaxKind.FalseKeyword){return"false"}throw new Error("알 수 없는 리터럴")}case _typescript.default.SyntaxKind.ArrayType:var arrNode=typeNode;return{t:"array",elementsType:this.resolveTypeNode(arrNode.elementType)};case _typescript.default.SyntaxKind.TypeLiteral:var literalNode=typeNode;return{t:"object",props:literalNode.members.map(function(member){if(_typescript.default.isIndexSignatureDeclaration(member)){(0,_assert.default)(member.parameters[0]);var res=_this.resolveParamDec({name:member.parameters[0].name,type:member.parameters[0].type});return _this.resolveParamDec({name:{escapedText:"[".concat(res.name).concat(res.optional?"?":"",": ").concat(res.type,"]")},type:member.type})}else{return _this.resolveParamDec({name:member.name,type:member.type,optional:member.questionToken!==undefined})}})};case _typescript.default.SyntaxKind.TypeReference:var _typeNode_typeArguments;return{t:"ref",id:typeNode.typeName.escapedText.toString(),args:(_typeNode_typeArguments=typeNode.typeArguments)===null||_typeNode_typeArguments===void 0?void 0:_typeNode_typeArguments.map(function(typeArg){return _this.resolveTypeNode(typeArg)})};case _typescript.default.SyntaxKind.UnionType:return{t:"union",types:typeNode.types.map(function(type){return _this.resolveTypeNode(type)})};case _typescript.default.SyntaxKind.IntersectionType:return{t:"intersection",types:typeNode.types.map(function(type){return _this.resolveTypeNode(type)})};case _typescript.default.SyntaxKind.IndexedAccessType:return{t:"indexed-access",object:this.resolveTypeNode(typeNode.objectType),index:this.resolveTypeNode(typeNode.indexType)};case _typescript.default.SyntaxKind.TupleType:if(_typescript.default.isTupleTypeNode(typeNode)){return{t:"tuple-type",elements:typeNode.elements.map(function(elem){return _this.resolveTypeNode(elem)})}}break;case undefined:throw new Error("typeNode undefined")}console.debug(typeNode);throw new Error("알 수 없는 SyntaxKind ".concat(typeNode.kind))}},{key:"printNode",value:function printNode(node,sourceFile){if(node===undefined){return undefined}var printer=_typescript.default.createPrinter({newLine:_typescript.default.NewLineKind.LineFeed});return printer.printNode(_typescript.default.EmitHint.Unspecified,node,sourceFile)}},{key:"autoloadApis",value:function autoloadApis(){return _async_to_generator(function(){var _this,pathPattern,filePaths,result;return _ts_generator(this,function(_state){switch(_state.label){case 0:_this=this;pathPattern=_path.default.join(_sonamu.Sonamu.apiRootPath,"/src/application/**/*.{model,frame}.ts");return[4,(0,_utils.globAsync)(pathPattern)];case 1:filePaths=_state.sent();return[4,Promise.all(filePaths.map(function(filePath){return _this.readApisFromFile(filePath)}))];case 2:result=_state.sent();this.apis=result.flat();return[2,this.apis]}})}).call(this)}},{key:"autoloadModels",value:function autoloadModels(){return _async_to_generator(function(){var pathPattern,filePaths,modules,functions;return _ts_generator(this,function(_state){switch(_state.label){case 0:pathPattern=_path.default.join(_sonamu.Sonamu.apiRootPath,"dist/application/**/*.{model,frame}.js");return[4,(0,_utils.globAsync)(pathPattern)];case 1:return[4,_asyncutils.filterAsync.apply(void 0,[_state.sent(),function(path){return _async_to_generator(function(){var srcPath;return _ts_generator(this,function(_state){switch(_state.label){case 0:srcPath=path.replace("/dist/","/src/").replace(".js",".ts");return[4,(0,_fsutils.exists)(srcPath)];case 1:return[2,_state.sent()]}})})()}])];case 2:filePaths=_state.sent();return[4,(0,_utils.importMultiple)(filePaths)];case 3:modules=_state.sent();functions=modules.map(function(param){var imported=param.imported;return Object.entries(imported)}).flat();this.models=Object.fromEntries(functions.filter(function(param){var _param=_sliced_to_array(param,1),name=_param[0];return name.endsWith("Model")||name.endsWith("Frame")}));return[2,this.models]}})}).call(this)}},{key:"autoloadTypes",value:function autoloadTypes(){var doRefresh=arguments.length>0&&arguments[0]!==void 0?arguments[0]:false;return _async_to_generator(function(){var pathPatterns,filePaths,modules,functions;return _ts_generator(this,function(_state){switch(_state.label){case 0:if(!doRefresh&&Object.keys(this.types).length>0){return[2,this.types]}pathPatterns=[_path.default.join(_sonamu.Sonamu.apiRootPath,"/dist/application/**/*.types.js"),_path.default.join(_sonamu.Sonamu.apiRootPath,"/dist/application/**/*.generated.js")];return[4,(0,_asyncutils.mapAsync)(pathPatterns,_utils.globAsync)];case 1:return[4,_asyncutils.filterAsync.apply(void 0,[_state.sent().flat(),function(path){return _async_to_generator(function(){var srcPath;return _ts_generator(this,function(_state){switch(_state.label){case 0:srcPath=path.replace("/dist/","/src/").replace(".js",".ts");return[4,(0,_fsutils.exists)(srcPath)];case 1:return[2,_state.sent()]}})})()}])];case 2:filePaths=_state.sent();return[4,(0,_utils.importMultiple)(filePaths,doRefresh)];case 3:modules=_state.sent();functions=modules.map(function(param){var imported=param.imported;return Object.entries(imported)}).flat();this.types=Object.fromEntries(functions.filter(function(param){var _param=_sliced_to_array(param,2),f=_param[1];return _instanceof(f,_zod.z.ZodType)}));return[2,this.types]}})}).call(this)}},{key:"getTemplate",value:function getTemplate(key){if(key==="entity"){return new _entitytemplate.Template__entity}else if(key==="init_types"){return new _init_typestemplate.Template__init_types}else if(key==="generated"){return new _generatedtemplate.Template__generated}else if(key==="generated_sso"){return new _generated_ssotemplate.Template__generated_sso}else if(key==="generated_http"){return new _generated_httptemplate.Template__generated_http}else if(key==="model"){return new _modeltemplate.Template__model}else if(key==="model_test"){return new _model_testtemplate.Template__model_test}else if(key==="service"){return new _servicetemplate.Template__service}else if(key==="view_list"){return new _view_listtemplate.Template__view_list}else if(key==="view_list_columns"){return new _view_list_columnstemplate.Template__view_list_columns}else if(key==="view_search_input"){return new _view_search_inputtemplate.Template__view_search_input}else if(key==="view_form"){return new _view_formtemplate.Template__view_form}else if(key==="view_id_all_select"){return new _view_id_all_selecttemplate.Template__view_id_all_select}else if(key==="view_id_async_select"){return new _view_id_async_selecttemplate.Template__view_id_async_select}else if(key==="view_enums_select"){return new _view_enums_selecttemplate.Template__view_enums_select}else if(key==="view_enums_dropdown"){return new _view_enums_dropdowntemplate.Template__view_enums_dropdown}else if(key==="view_enums_buttonset"){return new _view_enums_buttonsettemplate.Template__view_enums_buttonset}else{throw new _soexceptions.BadRequestException("잘못된 템플릿 키 ".concat(key))}}},{key:"renderTemplate",value:function renderTemplate(key,options){return _async_to_generator(function(){var _this,_template,template,extra,modelTsPath,entityId,columnsNode,listParamsZodType,listParamsNode,saveParamsZodType,saveParamsNode,rendered,resolved,preTemplateResolved;return _ts_generator(this,function(_state){switch(_state.label){case 0:_this=this;template=this.getTemplate(key);extra=[];if(!(key==="service"))return[3,2];modelTsPath=options.modelTsPath;return[4,this.readApisFromFile(modelTsPath)];case 1:extra=[_state.sent()];return[3,7];case 2:if(!["model","view_list","view_form"].includes(key))return[3,7];entityId=options.entityId;if(!(key==="view_list"||key==="model"))return[3,5];return[4,this.getColumnsNode(entityId,"A")];case 3:columnsNode=_state.sent();return[4,this.getZodTypeById("".concat(entityId,"ListParams"))];case 4:listParamsZodType=_state.sent();listParamsNode=this.zodTypeToRenderingNode(listParamsZodType);extra=[columnsNode,listParamsNode];return[3,7];case 5:if(!(key==="view_form"))return[3,7];return[4,this.getZodTypeById("".concat(entityId,"SaveParams"))];case 6:saveParamsZodType=_state.sent();saveParamsNode=this.zodTypeToRenderingNode(saveParamsZodType);extra=[saveParamsNode];_state.label=7;case 7:return[4,(_template=template).render.apply(_template,[options].concat(_to_consumable_array(extra)))];case 8:rendered=_state.sent();return[4,this.resolveRenderedTemplate(key,rendered)];case 9:resolved=_state.sent();preTemplateResolved=[];if(!rendered.preTemplates)return[3,11];return[4,Promise.all(rendered.preTemplates.map(function(param){var _$key=param.key,_$options=param.options;return _this.renderTemplate(_$key,_$options)}))];case 10:preTemplateResolved=_state.sent().flat();_state.label=11;case 11:return[2,[resolved].concat(_to_consumable_array(preTemplateResolved))]}})}).call(this)}},{key:"resolveRenderedTemplate",value:function resolveRenderedTemplate(key,result){return _async_to_generator(function(){var target,filePath,body,importKeys,customHeaders,importDefs,header,formatted;return _ts_generator(this,function(_state){switch(_state.label){case 0:target=result.target,filePath=result.path,body=result.body,importKeys=result.importKeys,customHeaders=result.customHeaders;importDefs=importKeys.reduce(function(r,importKey){var modulePath=_entitymanager.EntityManager.getModulePath(importKey);var importPath=modulePath;if(modulePath.includes("/")||modulePath.includes(".")){importPath=(0,_lodashable.wrapIf)(_path.default.relative(_path.default.dirname(filePath),modulePath),function(p){return[p.startsWith(".")===false,"./"+p]})}var existsOne=r.find(function(importDef){return importDef.from===importPath});if(existsOne){existsOne.keys=_lodash.default.uniq(existsOne.keys.concat(importKey))}else{r.push({keys:[importKey],from:importPath})}return r},[]).filter(function(importDef){return filePath.endsWith(importDef.from.replace("./","")+".ts")===false});header=_to_consumable_array(customHeaders!==null&&customHeaders!==void 0?customHeaders:[]).concat(_to_consumable_array(importDefs.map(function(importDef){return"import { ".concat(importDef.keys.join(", ")," } from '").concat(importDef.from,"'")}))).join("\n");return[4,function(){return _async_to_generator(function(){return _ts_generator(this,function(_state){if(key==="generated_http"){return[2,[header,body].join("\n\n")]}else{return[2,_prettier.default.format([header,body].join("\n\n"),{parser:key==="entity"?"json":"typescript"})]}return[2]})})()}()];case 1:formatted=_state.sent();return[2,{path:target+"/"+filePath,code:formatted}]}})})()}},{key:"writeCodeToPath",value:function writeCodeToPath(pathAndCode){return _async_to_generator(function(){var targets,appRootPath,filePath,dstFilePaths;return _ts_generator(this,function(_state){switch(_state.label){case 0:targets=_sonamu.Sonamu.config.sync.targets;appRootPath=_sonamu.Sonamu.appRootPath;filePath="".concat(_sonamu.Sonamu.appRootPath,"/").concat(pathAndCode.path);dstFilePaths=_lodash.default.uniq(targets.map(function(target){return filePath.replace("/:target/","/".concat(target,"/"))}));return[4,Promise.all(dstFilePaths.map(function(dstFilePath){return _async_to_generator(function(){var dir;return _ts_generator(this,function(_state){switch(_state.label){case 0:dir=_path.default.dirname(dstFilePath);return[4,(0,_fsutils.exists)(dir)];case 1:if(!!_state.sent())return[3,3];return[4,(0,_promises.mkdir)(dir,{recursive:true})];case 2:_state.sent();_state.label=3;case 3:return[4,(0,_promises.writeFile)(dstFilePath,pathAndCode.code)];case 4:_state.sent();console.log(_chalk.default.bold("Generated: ")+_chalk.default.blue("".concat(dstFilePath.replace(appRootPath+"/",""))));return[2,dstFilePath]}})})()}))];case 1:return[2,_state.sent()]}})})()}},{key:"generateTemplate",value:function generateTemplate(key,templateOptions,_generateOptions){return _async_to_generator(function(){var _this,generateOptions,keys,pathAndCodes,filteredPathAndCodes;return _ts_generator(this,function(_state){switch(_state.label){case 0:_this=this;generateOptions=_object_spread({overwrite:false},_generateOptions);keys=[key];return[4,Promise.all(keys.map(function(key){return _async_to_generator(function(){return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,this.renderTemplate(key,templateOptions)];case 1:return[2,_state.sent()]}})}).call(_this)}))];case 1:pathAndCodes=_state.sent().flat();return[4,function(){return _async_to_generator(function(){return _ts_generator(this,function(_state){switch(_state.label){case 0:if(!(generateOptions.overwrite===true))return[3,1];return[2,pathAndCodes];case 1:return[4,(0,_asyncutils.filterAsync)(pathAndCodes,function(pathAndCode){return _async_to_generator(function(){var targets,filePath,dstFilePaths;return _ts_generator(this,function(_state){switch(_state.label){case 0:targets=_sonamu.Sonamu.config.sync.targets;filePath="".concat(_sonamu.Sonamu.appRootPath,"/").concat(pathAndCode.path);dstFilePaths=targets.map(function(target){return filePath.replace("/:target/","/".concat(target,"/"))});return[4,(0,_asyncutils.everyAsync)(dstFilePaths,function(dstPath){return _async_to_generator(function(){return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,(0,_fsutils.exists)(dstPath)];case 1:return[2,!_state.sent()]}})})()})];case 1:return[2,_state.sent()]}})})()})];case 2:return[2,_state.sent()];case 3:return[2]}})})()}()];case 2:filteredPathAndCodes=_state.sent();if(filteredPathAndCodes.length===0){throw new _soexceptions.AlreadyProcessedException("이미 경로에 모든 파일이 존재합니다.")}return[2,Promise.all(filteredPathAndCodes.map(function(pathAndCode){return _this.writeCodeToPath(pathAndCode)}))]}})}).call(this)}},{key:"checkExistsGenCode",value:function checkExistsGenCode(entityId,templateKey,enumId){return _async_to_generator(function(){var _this_getTemplate_getTargetAndPath,target,genPath,fullPath,subPath,_tmp;return _ts_generator(this,function(_state){switch(_state.label){case 0:_this_getTemplate_getTargetAndPath=this.getTemplate(templateKey).getTargetAndPath(_entitymanager.EntityManager.getNamesFromId(entityId),enumId),target=_this_getTemplate_getTargetAndPath.target,genPath=_this_getTemplate_getTargetAndPath.path;fullPath=_path.default.join(_sonamu.Sonamu.appRootPath,target,genPath);subPath=_path.default.join(target,genPath);_tmp={subPath:subPath,fullPath:fullPath};return[4,(0,_fsutils.exists)(fullPath)];case 1:return[2,(_tmp.isExists=_state.sent(),_tmp)]}})}).call(this)}},{key:"checkExists",value:function checkExists(entityId,enums){return _async_to_generator(function(){var _this,keys,names,enumsKeys;return _ts_generator(this,function(_state){switch(_state.label){case 0:_this=this;keys=_types.TemplateKey.options;names=_entitymanager.EntityManager.getNamesFromId(entityId);enumsKeys=Object.keys(enums).filter(function(name){return name!==names.constant});return[4,(0,_asyncutils.reduceAsync)(keys,function(result,key){return _async_to_generator(function(){var tpl,_tpl_getTargetAndPath,target,p,targets;return _ts_generator(this,function(_state){switch(_state.label){case 0:tpl=this.getTemplate(key);if(!key.startsWith("view_enums"))return[3,2];return[4,(0,_asyncutils.mapAsync)(enumsKeys,function(componentId){return _async_to_generator(function(){var _tpl_getTargetAndPath,target,p,_;return _ts_generator(this,function(_state){switch(_state.label){case 0:_tpl_getTargetAndPath=tpl.getTargetAndPath(names,componentId),target=_tpl_getTargetAndPath.target,p=_tpl_getTargetAndPath.path;_="".concat(key,"__").concat(componentId);return[4,(0,_fsutils.exists)(_path.default.join(_sonamu.Sonamu.appRootPath,target,p))];case 1:result[_]=_state.sent();return[2]}})})()})];case 1:_state.sent();return[2,result];case 2:_tpl_getTargetAndPath=tpl.getTargetAndPath(names),target=_tpl_getTargetAndPath.target,p=_tpl_getTargetAndPath.path;targets=_sonamu.Sonamu.config.sync.targets;if(!target.includes(":target"))return[3,4];return[4,(0,_asyncutils.mapAsync)(targets,function(t){return _async_to_generator(function(){var _;return _ts_generator(this,function(_state){switch(_state.label){case 0:_="".concat(key,"__").concat(t);return[4,(0,_fsutils.exists)(_path.default.join(_sonamu.Sonamu.appRootPath,target.replace(":target",t),p))];case 1:result[_]=_state.sent();return[2]}})})()})];case 3:_state.sent();return[3,6];case 4:return[4,(0,_fsutils.exists)(_path.default.join(_sonamu.Sonamu.appRootPath,target,p))];case 5:result[key]=_state.sent();_state.label=6;case 6:return[2,result]}})}).call(_this)},{})];case 1:return[2,_state.sent()]}})}).call(this)}},{key:"getZodTypeById",value:function getZodTypeById(zodTypeId){return _async_to_generator(function(){var modulePath,moduleAbsPath,importPath,imported;return _ts_generator(this,function(_state){switch(_state.label){case 0:modulePath=_entitymanager.EntityManager.getModulePath(zodTypeId);moduleAbsPath=_path.default.join(_sonamu.Sonamu.apiRootPath,"dist","application",modulePath+".js");importPath="./"+_path.default.relative(__dirname,moduleAbsPath);return[4,Promise.resolve(importPath).then(function(p){return /*#__PURE__*/_interop_require_wildcard(require(p))})];case 1:imported=_state.sent();if(!imported[zodTypeId]){throw new Error("존재하지 않는 zodTypeId ".concat(zodTypeId))}return[2,imported[zodTypeId].describe(zodTypeId)]}})})()}},{key:"propNodeToZodType",value:function propNodeToZodType(propNode){return _async_to_generator(function(){var _this,innerType,_propNode_prop,obj;return _ts_generator(this,function(_state){switch(_state.label){case 0:_this=this;if(!(propNode.nodeType==="plain"))return[3,1];return[2,this.propToZodType(propNode.prop)];case 1:if(!(propNode.nodeType==="array"))return[3,7];if(!(propNode.prop===undefined))return[3,2];throw new Error;case 2:if(!(propNode.children.length>0))return[3,4];return[4,this.propNodeToZodType(_object_spread_props(_object_spread({},propNode),{nodeType:"object"}))];case 3:return[2,_state.sent().array()];case 4:return[4,this.propToZodType(propNode.prop)];case 5:innerType=_state.sent();if(propNode.prop.nullable===true){return[2,_zod.z.array(innerType).nullable()]}else{return[2,_zod.z.array(innerType)]}_state.label=6;case 6:return[3,10];case 7:if(!(propNode.nodeType==="object"))return[3,9];return[4,propNode.children.reduce(function(promise,childPropNode){return _async_to_generator(function(){var result,_;return _ts_generator(this,function(_state){switch(_state.label){case 0:return[4,promise];case 1:result=_state.sent();_=childPropNode.prop.name;return[4,this.propNodeToZodType(childPropNode)];case 2:result[_]=_state.sent();return[2,result]}})}).call(_this)},{})];case 8:obj=_state.sent();if(((_propNode_prop=propNode.prop)===null||_propNode_prop===void 0?void 0:_propNode_prop.nullable)===true){return[2,_zod.z.object(obj).nullable()]}else{return[2,_zod.z.object(obj)]}return[3,10];case 9:throw Error;case 10:return[2]}})}).call(this)}},{key:"propToZodType",value:function propToZodType(prop){return _async_to_generator(function(){var zodType;return _ts_generator(this,function(_state){switch(_state.label){case 0:zodType=_zod.z.unknown();if(!(0,_types.isIntegerProp)(prop))return[3,1];zodType=_zod.z.number().int();return[3,19];case 1:if(!(0,_types.isBigIntegerProp)(prop))return[3,2];zodType=_zod.z.bigint();return[3,19];case 2:if(!(0,_types.isTextProp)(prop))return[3,3];zodType=_zod.z.string().max((0,_codeconverters.getTextTypeLength)(prop.textType));return[3,19];case 3:if(!(0,_types.isEnumProp)(prop))return[3,5];return[4,this.getZodTypeById(prop.id)];case 4:zodType=_state.sent();return[3,19];case 5:if(!(0,_types.isStringProp)(prop))return[3,6];zodType=_zod.z.string().max(prop.length);return[3,19];case 6:if(!((0,_types.isFloatProp)(prop)||(0,_types.isDoubleProp)(prop)))return[3,7];zodType=_zod.z.number();return[3,19];case 7:if(!(0,_types.isDecimalProp)(prop))return[3,8];zodType=_zod.z.string();return[3,19];case 8:if(!(0,_types.isBooleanProp)(prop))return[3,9];zodType=_zod.z.boolean();return[3,19];case 9:if(!(0,_types.isDateProp)(prop))return[3,10];zodType=_zod.z.string().length(10);return[3,19];case 10:if(!(0,_types.isTimeProp)(prop))return[3,11];zodType=_zod.z.string().length(8);return[3,19];case 11:if(!(0,_types.isDateTimeProp)(prop))return[3,12];zodType=_zod.z.date();return[3,19];case 12:if(!(0,_types.isTimestampProp)(prop))return[3,13];zodType=_zod.z.date();return[3,19];case 13:if(!(0,_types.isJsonProp)(prop))return[3,15];return[4,this.getZodTypeById(prop.id)];case 14:zodType=_state.sent();return[3,19];case 15:if(!(0,_types.isUuidProp)(prop))return[3,16];zodType=_zod.z.uuid();return[3,19];case 16:if(!(0,_types.isVirtualProp)(prop))return[3,18];return[4,this.getZodTypeById(prop.id)];case 17:zodType=_state.sent();return[3,19];case 18:if((0,_types.isRelationProp)(prop)){if((0,_types.isBelongsToOneRelationProp)(prop)||(0,_types.isOneToOneRelationProp)(prop)&&prop.hasJoinColumn){zodType=_zod.z.number().int()}}else{throw new Error("prop을 zodType으로 변환하는데 실패 ".concat(prop,"}"))}_state.label=19;case 19:if(prop.unsigned){zodType=zodType.nonnegative()}if(prop.nullable){zodType=zodType.nullable()}return[2,zodType]}})}).call(this)}},{key:"resolveRenderType",value:function resolveRenderType(key,zodType){if(_instanceof(zodType,_zod.z.ZodDate)){return"datetime"}else if(_instanceof(zodType,_zod.z.ZodString)){if(key.includes("img")||key.includes("image")){return"string-image"}else if(zodType.description==="SQLDateTimeString"){return"string-datetime"}else if(key.endsWith("date")){return"string-date"}else{return"string-plain"}}else if(_instanceof(zodType,_zod.z.ZodNumber)){if(key==="id"){return"number-id"}else if(key.endsWith("_id")){return"number-fk_id"}else{return"number-plain"}}else if(_instanceof(zodType,_zod.z.ZodBoolean)){return"boolean"}else if(_instanceof(zodType,_zod.z.ZodEnum)){return"enums"}else if(_instanceof(zodType,_zod.z.ZodRecord)){return"record"}else if(_instanceof(zodType,_zod.z.ZodAny)||_instanceof(zodType,_zod.z.ZodUnknown)){return"string-plain"}else if(_instanceof(zodType,_zod.z.ZodUnion)){return"string-plain"}else if(_instanceof(zodType,_zod.z.ZodLiteral)){return"string-plain"}else{throw new Error("타입 파싱 불가 ".concat(key," ").concat(zodType.def.type))}}},{key:"zodTypeToRenderingNode",value:function zodTypeToRenderingNode(zodType){var _this=this;var baseKey=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"root";var def={name:baseKey,label:_inflection.default.camelize(baseKey,false),zodType:zodType};if(_instanceof(zodType,_zod.z.ZodObject)){var columnKeys=Object.keys(zodType.shape);var children=columnKeys.map(function(key){var innerType=zodType.shape[key];return _this.zodTypeToRenderingNode(innerType,key)});return _object_spread_props(_object_spread({},def),{renderType:"object",children:children})}else if(_instanceof(zodType,_zod.z.ZodArray)){var innerType=zodType.def.element;if(_instanceof(innerType,_zod.z.ZodString)&&baseKey.includes("images")){return _object_spread_props(_object_spread({},def),{renderType:"array-images"})}return _object_spread_props(_object_spread({},def),{renderType:"array",element:this.zodTypeToRenderingNode(innerType,baseKey)})}else if(_instanceof(zodType,_zod.z.ZodUnion)){var optionNodes=zodType.def.options.map(function(opt){return _this.zodTypeToRenderingNode(opt,baseKey)});return optionNodes[0]}else if(_instanceof(zodType,_zod.z.ZodOptional)){return _object_spread_props(_object_spread({},this.zodTypeToRenderingNode(zodType.def.innerType,baseKey)),{optional:true})}else if(_instanceof(zodType,_zod.z.ZodNullable)){return _object_spread_props(_object_spread({},this.zodTypeToRenderingNode(zodType.def.innerType,baseKey)),{nullable:true})}else{return _object_spread_props(_object_spread({},def),{renderType:this.resolveRenderType(baseKey,zodType)})}}},{key:"getColumnsNode",value:function getColumnsNode(entityId,subsetKey){return _async_to_generator(function(){var entity,subsetA,propNodes,rootPropNode,columnsZodType,columnsNode;return _ts_generator(this,function(_state){switch(_state.label){case 0:entity=_entitymanager.EntityManager.get(entityId);subsetA=entity.subsets[subsetKey];if(subsetA===undefined){throw new _soexceptions.ServiceUnavailableException("SubsetA 가 없습니다.")}propNodes=entity.fieldExprsToPropNodes(subsetA);rootPropNode={nodeType:"object",children:propNodes};return[4,this.propNodeToZodType(rootPropNode)];case 1:columnsZodType=_state.sent();columnsNode=this.zodTypeToRenderingNode(columnsZodType);columnsNode.children=columnsNode.children.map(function(child){if(child.renderType==="object"){var pickedCol=child.children.find(function(cc){return["title","name"].includes(cc.name)});if(pickedCol){return _object_spread_props(_object_spread({},child),{renderType:"object-pick",config:{picked:pickedCol.name}})}else{return child}}else if(child.renderType==="array"&&child.element&&child.element.renderType==="object"){var pickedCol1=child.element.children.find(function(cc){return["title","name"].includes(cc.name)});if(pickedCol1){return _object_spread_props(_object_spread({},child),{element:_object_spread_props(_object_spread({},child.element),{renderType:"object-pick",config:{picked:pickedCol1.name}})})}else{return child}}return child});return[2,columnsNode]}})}).call(this)}},{key:"createEntity",value:function createEntity(form){return _async_to_generator(function(){return _ts_generator(this,function(_state){switch(_state.label){case 0:if(!/^[A-Z][a-zA-Z0-9]*$/.test(form.entityId)){throw new _soexceptions.BadRequestException("entityId는 CamelCase 형식이어야 합니다.")}return[4,this.generateTemplate("entity",form)];case 1:_state.sent();return[4,_entitymanager.EntityManager.reload()];case 2:_state.sent();return[2]}})}).call(this)}},{key:"delEntity",value:function delEntity(entityId){return _async_to_generator(function(){var entity,delPaths,_iteratorAbruptCompletion,_didIteratorError,_iteratorError,_iterator,_step,_value,delPath,err;return _ts_generator(this,function(_state){switch(_state.label){case 0:entity=_entitymanager.EntityManager.get(entityId);delPaths=function(){if(entity.parentId){return["".concat(_sonamu.Sonamu.apiRootPath,"/src/application/").concat(entity.names.parentFs,"/").concat(entity.names.fs,".entity.json")]}else{return["".concat(_sonamu.Sonamu.apiRootPath,"/src/application/").concat(entity.names.fs),"".concat(_sonamu.Sonamu.apiRootPath,"/dist/application/").concat(entity.names.fs)].concat(_to_consumable_array(_sonamu.Sonamu.config.sync.targets.map(function(target){return["".concat(_sonamu.Sonamu.appRootPath,"/").concat(target,"/src/services/").concat(entity.names.fs)]}).flat()))}}();_iteratorAbruptCompletion=false,_didIteratorError=false;_state.label=1;case 1:_state.trys.push([1,9,10,15]);_iterator=_async_iterator(delPaths);_state.label=2;case 2:return[4,_iterator.next()];case 3:if(!(_iteratorAbruptCompletion=!(_step=_state.sent()).done))return[3,8];_value=_step.value;delPath=_value;return[4,(0,_fsutils.exists)(delPath)];case 4:if(!_state.sent())return[3,6];console.log(_chalk.default.red("DELETE ".concat(delPath)));return[4,(0,_promises.rm)(delPath,{recursive:true,force:true})];case 5:_state.sent();return[3,7];case 6:console.log(_chalk.default.yellow("NOT_EXISTS ".concat(delPath)));_state.label=7;case 7:_iteratorAbruptCompletion=false;return[3,2];case 8:return[3,15];case 9:err=_state.sent();_didIteratorError=true;_iteratorError=err;return[3,15];case 10:_state.trys.push([10,,13,14]);if(!(_iteratorAbruptCompletion&&_iterator.return!=null))return[3,12];return[4,_iterator.return()];case 11:_state.sent();_state.label=12;case 12:return[3,14];case 13:if(_didIteratorError){throw _iteratorError}return[7];case 14:return[7];case 15:return[4,_entitymanager.EntityManager.reload()];case 16:_state.sent();return[2,{delPaths:delPaths}]}})})()}},{key:"syncUI",value:function syncUI(){var _Sonamu_config_ui;var _Sonamu_config_ui_port;var uiPort=(_Sonamu_config_ui_port=(_Sonamu_config_ui=_sonamu.Sonamu.config.ui)===null||_Sonamu_config_ui===void 0?void 0:_Sonamu_config_ui.port)!==null&&_Sonamu_config_ui_port!==void 0?_Sonamu_config_ui_port:57e3;fetch("http://127.0.0.1:".concat(uiPort,"/api/reload"),{method:"GET"}).catch(function(e){return console.log(_chalk.default.dim("Failed to reload Sonamu UI: ".concat(e.message)))})}}]);return Syncer}();
2
- //# sourceMappingURL=syncer.js.map
1
+ import { hot } from "@sonamu-kit/hot-hook";
2
+ import assert from "assert";
3
+ import chalk from "chalk";
4
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
5
+ import { minimatch } from "minimatch";
6
+ import path, { dirname } from "path";
7
+ import { group, unique } from "radashi";
8
+ import { registeredApis } from "../api/decorators.js";
9
+ import { Sonamu } from "../api/sonamu.js";
10
+ import { EntityManager } from "../entity/entity-manager.js";
11
+ import { Naite } from "../naite/naite.js";
12
+ import { TemplateManager } from "../template/template-manager.js";
13
+ import { TemplateKey } from "../types/types.js";
14
+ import { mapAsync, reduceAsync } from "../utils/async-utils.js";
15
+ import { centerText } from "../utils/console-util.js";
16
+ import { isTest } from "../utils/controller.js";
17
+ import { exists } from "../utils/fs-utils.js";
18
+ import { runWithGracefulShutdown } from "../utils/process-utils.js";
19
+ import { areFilesSame, findChangedFilesUsingChecksums, renewChecksums } from "./checksum.js";
20
+ import { generateTemplate, renderTemplate } from "./code-generator.js";
21
+ import { createEntity, delEntity } from "./entity-operations.js";
22
+ import { getChecksumPatternGroupInAbsolutePath } from "./file-patterns.js";
23
+ import { loadApis, loadModels, loadTypes } from "./module-loader.js";
24
+ export class Syncer {
25
+ apis = [];
26
+ types = {};
27
+ models = {};
28
+ isSyncing = false;
29
+ /**
30
+ * 체크섬이 변경된 부분에 대해 싱크를 진행합니다.
31
+ * 다만 sonamu.shared.ts는 체크섬 비교 없이 무조건 싱크(복사)합니다.
32
+ * @returns
33
+ */ async sync() {
34
+ const { targets } = Sonamu.config.sync;
35
+ // sonamu.shared.ts는 무조건 싱크(복사)합니다.
36
+ await this.copySharedToTargets(targets);
37
+ // 그 다음부터는 변경된 파일을 찾아서 동기화 작업을 실행합니다.
38
+ const changedFiles = await findChangedFilesUsingChecksums();
39
+ if (changedFiles.length === 0) {
40
+ console.log(chalk.black.bgGreen(centerText("All files are synced!")));
41
+ return;
42
+ }
43
+ // 만약 싱크 중에 프로세스가 죽으면 꼬여버리기 때문에,
44
+ // 시그널에도 잠시 버틸 수 있는 환경 속에서 싱크를 실행합니다.
45
+ await runWithGracefulShutdown(async ()=>{
46
+ // 얘가 싱크 작업 수행하는 본체입니다.
47
+ await this.doSyncActions(changedFiles);
48
+ // 싱크 액션이 끝나면 항상 체크섬을 다시 갱신합니다.
49
+ await renewChecksums();
50
+ }, {
51
+ whenThisHappens: "SIGUSR2",
52
+ waitForUpTo: 20000
53
+ });
54
+ }
55
+ /**
56
+ * Watcher가 감지한 파일 변경 사항에 대해 싱크를 진행합니다.
57
+ * 주어진 변경 파일들 중 체크섬 관리 대상인 것들만 가져다가 싱크를 진행합니다.
58
+ * 체크섬 파일 업데이트는 여기에서 하지 않습니다. 호출자가 합니다.
59
+ * @param diffFilePath - 변경 파일들. 프로젝트 루트부터 "src/" 또는 "dist/"로 시작하는 상대 경로입니다. 예시: "src/application/user/user.model.ts"
60
+ */ async syncFromWatcher(event, diffFilePath) {
61
+ if (event !== "change" && event !== "add" && event !== "unlink") {
62
+ return;
63
+ }
64
+ // 일단 변경된 파일과 dependent 파일들을 invalidate 합니다.
65
+ // 한 번 이상 import된 친구들에 대해서만 실제 작업이 일어납니다.
66
+ // 그러니 안심하고 invalidate 해도 됩니다.
67
+ // 테스트 환경에서는 hot.invalidateFile시 초기 에러가 발생하기 때문에 invalidate 하지 않습니다.
68
+ if (!isTest()) {
69
+ const invalidatedPaths = await hot.invalidateFile(diffFilePath, event);
70
+ if (invalidatedPaths.length > 0) {
71
+ console.log(chalk.bold(`🔄 Invalidated:`));
72
+ for (const invalidatedPath of invalidatedPaths){
73
+ // 만약 model.ts 파일이 변경(invalidate)되었다? 그러면 registeredApis 중에서 이 모델에 해당하는 api들은 지워줘요.
74
+ // registeredApis는 통으로 다 날려버릴 수 없습니다. registeredApis에 올라오는 친구들은 초기 로드시 또는 HMR시에만 등록되기 때문입니다.
75
+ // 따라서 model.ts 파일의 변경으로 다음번 새로운 eval이 예상되는 이 시점에서만, 이 모델에서 나온 registeredApis들을 지워줄 수 있습니다.
76
+ const removedApis = this.removeInvalidatedRegisteredApis(invalidatedPath);
77
+ if (removedApis.length > 0) {
78
+ console.log(chalk.blue(`- ${path.relative(Sonamu.apiRootPath, invalidatedPath)}`), chalk.gray(`(with ${removedApis.length} APIs)`));
79
+ } else {
80
+ console.log(chalk.blue(`- ${path.relative(Sonamu.apiRootPath, invalidatedPath)}`));
81
+ }
82
+ }
83
+ }
84
+ }
85
+ const isInCheckPatternGroup = Object.values(getChecksumPatternGroupInAbsolutePath()).some((pattern)=>minimatch(diffFilePath, pattern));
86
+ // 할 일(sync)이 있으면 합니다.
87
+ if (isInCheckPatternGroup) {
88
+ await this.doSyncActions([
89
+ diffFilePath
90
+ ]);
91
+ }
92
+ // 싱크 작업이 끝나면 모든 모듈을 로드합니다.
93
+ // hot-hook에 의해 invalidate된 부분들이 아니라면 캐시 그대로 유지합니다.
94
+ await this.autoloadTypes();
95
+ await this.autoloadModels();
96
+ await this.autoloadApis();
97
+ this.syncUI();
98
+ }
99
+ removeInvalidatedRegisteredApis(invalidatedPath) {
100
+ if (!invalidatedPath.endsWith(".model.ts" /*소스 코드를 다루는 상황이니 .ts 경로로 봅니다.*/ )) {
101
+ return [];
102
+ }
103
+ const entityId = EntityManager.getEntityIdFromPath(invalidatedPath);
104
+ const toRemove = registeredApis.filter((api)=>api.modelName === `${entityId}Model`);
105
+ for (const api of toRemove){
106
+ registeredApis.splice(registeredApis.indexOf(api), 1);
107
+ }
108
+ return toRemove;
109
+ }
110
+ async copySharedToTargets(targets) {
111
+ for (const target of targets){
112
+ // 지금 가져가려는 이 파일은 Sonamu 코드베이스의 일부입니다.
113
+ // 그런데 dist 속 빌드된 소스 코드 파일이 필요한 것이 아니고, src에만 있는 텍스트 파일이 필요합니다.
114
+ // 따라서 /src/에서 찾습니다.
115
+ const srcPath = path.join(import.meta.dirname.replace("/dist/", "/src/"), `../shared/${target}.shared.ts.txt`);
116
+ if (!await exists(srcPath)) {
117
+ return;
118
+ }
119
+ if (!await exists(path.join(Sonamu.appRootPath, target))) {
120
+ throw new Error(`Tried to copy sonamu.shared.ts to target '${target}' but the target directory does not exist. Please check your project directory structure.`);
121
+ }
122
+ // 이건 프로젝트에 .ts 소스 코드 파일을 생성하는 것이므로 src의 .ts 경로로 갑니다.
123
+ const destPath = path.join(Sonamu.appRootPath, target, "./sonamu.shared.ts");
124
+ // 정말 혹시나지만 target 디렉토리는 있어도 src/services 디렉토리는 없을 수 있으므로 미리 생성해줍니다.
125
+ if (!await exists(path.dirname(destPath))) {
126
+ await mkdir(path.dirname(destPath), {
127
+ recursive: true
128
+ });
129
+ console.warn(`Created directory '${path.dirname(destPath)}' because it did not exist.`);
130
+ }
131
+ if (await areFilesSame(srcPath, destPath)) {
132
+ return;
133
+ }
134
+ await writeFile(destPath, await readFile(srcPath));
135
+ !isTest() && console.log(chalk.bold("Copied: ") + chalk.blue(path.relative(Sonamu.appRootPath, destPath)));
136
+ }
137
+ }
138
+ async autoloadTypes() {
139
+ this.types = await loadTypes();
140
+ }
141
+ async autoloadModels() {
142
+ this.models = await loadModels();
143
+ }
144
+ async autoloadApis() {
145
+ this.apis = await loadApis();
146
+ }
147
+ /**
148
+ * 실제 싱크를 수행하는 본체입니다.
149
+ * 변경된 파일들을 타입별로 분류하고 각 타입에 맞는 액션을 실행합니다.
150
+ * @param diffFilePaths - 변경된 파일들의 절대 경로 목록
151
+ * @returns diffTypes - 변경된 파일의 타입 목록 (entity, types, model 등)
152
+ */ async doSyncActions(diffFilePaths) {
153
+ const diffGroups = this.calculateDiffGroups(diffFilePaths);
154
+ const diffTypes = Object.keys(diffGroups);
155
+ // 트리거: entity, types
156
+ // 액션: 스키마 생성
157
+ if (diffTypes.includes("entity")) {
158
+ await this.handleEntityChange(diffGroups, diffTypes);
159
+ }
160
+ // 트리거: types, enums, generated 변경시
161
+ // 액션: 파일 싱크 types, enums, generated
162
+ if (diffTypes.includes("types") || diffTypes.includes("functions") || diffTypes.includes("generated")) {
163
+ await this.handleTypesOrFunctionsOrGeneratedChange(diffGroups);
164
+ }
165
+ // 트리거: model
166
+ if (diffTypes.includes("model") || diffTypes.includes("frame")) {
167
+ await this.handleModelOrFrameChange(diffGroups);
168
+ }
169
+ // 트리거: config
170
+ if (diffTypes.includes("config")) {
171
+ await this.actionSyncConfig();
172
+ }
173
+ return {
174
+ diffTypes
175
+ };
176
+ }
177
+ calculateDiffGroups(diffFiles) {
178
+ return group(diffFiles, (r)=>{
179
+ const matched = r.match(/\.(model|types|functions|entity|generated|frame|config)\.[tj]s/);
180
+ return matched?.[1] ?? "unknown";
181
+ });
182
+ }
183
+ async handleEntityChange(diffGroups, diffTypes) {
184
+ Naite.t("handleEntityChange", {
185
+ diffGroups,
186
+ diffTypes
187
+ });
188
+ await EntityManager.reload();
189
+ // types 생성(entity 새로 추가된 경우)
190
+ // parentId가 없고, types가 없는 경우에만 생성
191
+ const entityId = EntityManager.getEntityIdFromPath(diffGroups.entity?.[0]);
192
+ if (entityId) {
193
+ const entity = EntityManager.get(entityId);
194
+ // 프로젝트에 생성되어야 하는 .ts 파일의 경로입니다.
195
+ const typeFilePath = path.join(Sonamu.apiRootPath, `src/application/${entity.names.fs}/${entity.names.fs}.types.ts`);
196
+ if (entity.parentId === undefined && !await exists(typeFilePath)) {
197
+ await generateTemplate("init_types", {
198
+ entityId
199
+ });
200
+ }
201
+ }
202
+ await this.actionGenerateSchemas();
203
+ diffGroups.generated = unique([
204
+ ...diffGroups.generated ?? [],
205
+ path.join(Sonamu.apiRootPath, "src/application/sonamu.generated.ts")
206
+ ]);
207
+ diffTypes.push("generated");
208
+ }
209
+ async handleTypesOrFunctionsOrGeneratedChange(diffGroups) {
210
+ const tsPaths = unique([
211
+ ...diffGroups.types ?? [],
212
+ ...diffGroups.functions ?? [],
213
+ ...diffGroups.generated ?? []
214
+ ]);
215
+ Naite.t("handleTypesOrFunctionsOrGeneratedChange", {
216
+ diffGroups
217
+ });
218
+ // console.log(
219
+ // chalk.gray(
220
+ // `[Processing] Handling types/functions/generated changes: ${tsPaths.map((p) => path.relative(Sonamu.apiRootPath, p)).join(", ")}`
221
+ // )
222
+ // );
223
+ await this.actionSyncFilesToTargets(tsPaths);
224
+ return [];
225
+ }
226
+ async handleModelOrFrameChange(diffGroups) {
227
+ Naite.t("handleModelOrFrameChange", {
228
+ diffGroups
229
+ });
230
+ const mergedGroup = [
231
+ ...diffGroups.model ?? [],
232
+ ...diffGroups.frame ?? []
233
+ ];
234
+ // console.log(
235
+ // chalk.gray(
236
+ // `[Processing] Handling model/frame changes: ${mergedGroup.map((p) => path.relative(Sonamu.apiRootPath, p)).join(", ")}`
237
+ // )
238
+ // );
239
+ // generated_http.template.ts에서 syncer.types를 씁니다.
240
+ // service.template.ts에서 syncer.apis를 씁니다.
241
+ await this.autoloadModels();
242
+ await this.autoloadTypes();
243
+ await this.autoloadApis();
244
+ const params = mergedGroup.map((modelPath)=>{
245
+ if (modelPath.endsWith(".model.ts")) {
246
+ const entityId = EntityManager.getEntityIdFromPath(modelPath);
247
+ assert(entityId);
248
+ return {
249
+ namesRecord: EntityManager.getNamesFromId(entityId)
250
+ };
251
+ }
252
+ if (modelPath.endsWith("frame.ts")) {
253
+ const [, frameName] = modelPath.match(/.+\/(.+)\.frame.js$/) ?? [];
254
+ assert(frameName);
255
+ return {
256
+ namesRecord: EntityManager.getNamesFromId(frameName)
257
+ };
258
+ }
259
+ throw new Error("not reachable");
260
+ });
261
+ await this.actionGenerateServices(params);
262
+ await this.actionGenerateHttps();
263
+ }
264
+ // web/.sonamu.env 에 현재 설정값 저장
265
+ async actionSyncConfig() {
266
+ const { host, port } = Sonamu.config.server.listen ?? {};
267
+ const content = `API_HOST=${host ?? "localhost"}\nAPI_PORT=${port ?? 3000}`;
268
+ Naite.t("actionSyncConfig", {
269
+ content
270
+ });
271
+ await Promise.all(Sonamu.config.sync.targets.map(async (target)=>{
272
+ await writeFile(path.join(Sonamu.appRootPath, target, ".sonamu.env"), content);
273
+ }));
274
+ }
275
+ /**
276
+ * sonamu.generated.ts와 sonamu.generated.sso.ts를 생성합니다.
277
+ * @returns 생성된 파일 경로 배열.
278
+ */ async actionGenerateSchemas() {
279
+ return (await Promise.all([
280
+ generateTemplate("generated_sso", {}, {
281
+ overwrite: true
282
+ }),
283
+ generateTemplate("generated", {}, {
284
+ overwrite: true
285
+ })
286
+ ])).flat().flat();
287
+ }
288
+ /**
289
+ * *.service.ts를 생성합니다.
290
+ * @param paramsArray
291
+ * @returns 생성된 파일 경로 배열.
292
+ */ async actionGenerateServices(paramsArray) {
293
+ Naite.t("actionGenerateServices", paramsArray);
294
+ return (await Promise.all(paramsArray.map(async (params)=>generateTemplate("service", params, {
295
+ overwrite: true
296
+ })))).flat().flat();
297
+ }
298
+ /**
299
+ * sonamu.generated.http를 생성합니다.
300
+ * @returns 생성된 파일 경로.
301
+ */ async actionGenerateHttps() {
302
+ const [res] = await generateTemplate("generated_http", {
303
+ entityId: "dummy"
304
+ }, {
305
+ overwrite: true
306
+ });
307
+ assert(res);
308
+ return res;
309
+ }
310
+ /**
311
+ * *.types.ts, *.functions.ts, *.generated.ts를 타겟 디렉토리에 복사합니다.
312
+ * @param tsPaths
313
+ * @returns 복사된 파일 경로 배열.
314
+ */ async actionSyncFilesToTargets(tsPaths) {
315
+ const { targets } = Sonamu.config.sync;
316
+ const { dir: apiDir } = Sonamu.config.api;
317
+ return (await Promise.all(targets.map(async (target)=>Promise.all(tsPaths.map(async (realSrc)=>{
318
+ const dst = realSrc.replace(`/${apiDir}/`, `/${target}/`).replace("/application/", "/services/");
319
+ const dir = dirname(dst);
320
+ if (!await exists(dir)) {
321
+ await mkdir(dir, {
322
+ recursive: true
323
+ });
324
+ }
325
+ !isTest() && console.log(chalk.bold("Copied: ") + chalk.blue(dst.replace(`${Sonamu.appRootPath}/`, "")));
326
+ await this.copyFileWithReplaceCoreToShared(realSrc, dst);
327
+ return dst;
328
+ }))))).flat();
329
+ }
330
+ async copyFileWithReplaceCoreToShared(fromPath, toPath) {
331
+ if (!await exists(fromPath)) {
332
+ return;
333
+ }
334
+ const oldFileContent = (await readFile(fromPath)).toString();
335
+ const newFileContent = (()=>{
336
+ const nfc = oldFileContent.replace(/from "sonamu"/g, `from "./sonamu.shared"`);
337
+ return nfc;
338
+ })();
339
+ return writeFile(toPath, newFileContent);
340
+ }
341
+ /**
342
+ * 주어진 엔티티와 템플릿 키에 대해, 생성된 코드가 존재하는지 확인합니다.
343
+ * @param entityId 엔티티 ID
344
+ * @param templateKey 템플릿 키
345
+ * @param enumId 열거형 ID
346
+ * @returns 생성된 코드가 존재하는지 여부
347
+ */ async checkExistsGenCode(entityId, templateKey, enumId) {
348
+ const { target, path: genPath } = TemplateManager.get(templateKey).getTargetAndPath(EntityManager.getNamesFromId(entityId), enumId);
349
+ const subPath = path.join(target, genPath);
350
+ const fullPath = path.join(Sonamu.appRootPath, subPath);
351
+ return {
352
+ subPath,
353
+ fullPath,
354
+ isExists: await exists(fullPath)
355
+ };
356
+ }
357
+ /**
358
+ * 주어진 엔티티와 열거형에 대해, 생성된 코드가 존재하는지 확인합니다.
359
+ * @param entityId 엔티티 ID
360
+ * @param enums 열거형 레이블
361
+ * @returns 생성된 코드가 존재하는지 여부
362
+ */ async checkExists(entityId, enums) {
363
+ const keys = TemplateKey.options;
364
+ const names = EntityManager.getNamesFromId(entityId);
365
+ const enumsKeys = Object.keys(enums).filter((name)=>name !== names.constant);
366
+ return await reduceAsync(keys, async (result, key)=>{
367
+ const tpl = TemplateManager.get(key);
368
+ if (key.startsWith("view_enums")) {
369
+ await mapAsync(enumsKeys, async (componentId)=>{
370
+ const { target, path: p } = tpl.getTargetAndPath(names, componentId);
371
+ result[`${key}__${componentId}`] = await exists(path.join(Sonamu.appRootPath, target, p));
372
+ });
373
+ return result;
374
+ }
375
+ const { target, path: p } = tpl.getTargetAndPath(names);
376
+ const { targets } = Sonamu.config.sync;
377
+ if (target.includes(":target")) {
378
+ await mapAsync(targets, async (t)=>{
379
+ result[`${key}__${t}`] = await exists(path.join(Sonamu.appRootPath, target.replace(":target", t), p));
380
+ });
381
+ } else {
382
+ result[key] = await exists(path.join(Sonamu.appRootPath, target, p));
383
+ }
384
+ return result;
385
+ }, {});
386
+ }
387
+ syncUI() {
388
+ const uiPort = Sonamu.config.ui?.port ?? 57000;
389
+ if (!isTest()) {
390
+ fetch(`http://127.0.0.1:${uiPort}/api/reload`, {
391
+ method: "GET"
392
+ }).catch((e)=>console.log(chalk.dim(`Failed to reload Sonamu UI: ${e.message}`)));
393
+ }
394
+ }
395
+ /**
396
+ * 하위호환용 프록시 메소드입니다.
397
+ */ async createEntity(form) {
398
+ return await createEntity(form);
399
+ }
400
+ /**
401
+ * 하위호환용 프록시 메소드입니다.
402
+ */ async delEntity(entityId) {
403
+ return await delEntity(entityId);
404
+ }
405
+ /**
406
+ * 하위호환용 프록시 메소드입니다.
407
+ */ async generateTemplate(key, templateOptions, _generateOptions) {
408
+ return await generateTemplate(key, templateOptions, _generateOptions);
409
+ }
410
+ /**
411
+ * 하위호환용 프록시 메소드입니다.
412
+ */ async renderTemplate(key, templateOptions) {
413
+ return await renderTemplate(key, templateOptions);
414
+ }
415
+ /**
416
+ * 하위호환용 프록시 메소드입니다.
417
+ */ async renewChecksums() {
418
+ return await renewChecksums();
419
+ }
420
+ }
421
+
422
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zeW5jZXIvc3luY2VyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGhvdCB9IGZyb20gXCJAc29uYW11LWtpdC9ob3QtaG9va1wiO1xuaW1wb3J0IGFzc2VydCBmcm9tIFwiYXNzZXJ0XCI7XG5pbXBvcnQgY2hhbGsgZnJvbSBcImNoYWxrXCI7XG5pbXBvcnQgeyBta2RpciwgcmVhZEZpbGUsIHdyaXRlRmlsZSB9IGZyb20gXCJmcy9wcm9taXNlc1wiO1xuaW1wb3J0IHsgbWluaW1hdGNoIH0gZnJvbSBcIm1pbmltYXRjaFwiO1xuaW1wb3J0IHBhdGgsIHsgZGlybmFtZSB9IGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBncm91cCwgdW5pcXVlIH0gZnJvbSBcInJhZGFzaGlcIjtcbmltcG9ydCB0eXBlIHsgeiB9IGZyb20gXCJ6b2RcIjtcbmltcG9ydCB7IHJlZ2lzdGVyZWRBcGlzIH0gZnJvbSBcIi4uL2FwaS9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBTb25hbXUgfSBmcm9tIFwiLi4vYXBpL3NvbmFtdVwiO1xuaW1wb3J0IHsgRW50aXR5TWFuYWdlciwgdHlwZSBFbnRpdHlOYW1lc1JlY29yZCB9IGZyb20gXCIuLi9lbnRpdHkvZW50aXR5LW1hbmFnZXJcIjtcbmltcG9ydCB7IE5haXRlIH0gZnJvbSBcIi4uL25haXRlL25haXRlXCI7XG5pbXBvcnQgeyBUZW1wbGF0ZU1hbmFnZXIgfSBmcm9tIFwiLi4vdGVtcGxhdGUvdGVtcGxhdGUtbWFuYWdlclwiO1xuaW1wb3J0IHR5cGUgeyBHZW5lcmF0ZU9wdGlvbnMsIFBhdGhBbmRDb2RlIH0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQgeyBUZW1wbGF0ZUtleSwgdHlwZSBUZW1wbGF0ZU9wdGlvbnMgfSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IG1hcEFzeW5jLCByZWR1Y2VBc3luYyB9IGZyb20gXCIuLi91dGlscy9hc3luYy11dGlsc1wiO1xuaW1wb3J0IHsgY2VudGVyVGV4dCB9IGZyb20gXCIuLi91dGlscy9jb25zb2xlLXV0aWxcIjtcbmltcG9ydCB7IGlzVGVzdCB9IGZyb20gXCIuLi91dGlscy9jb250cm9sbGVyXCI7XG5pbXBvcnQgeyBleGlzdHMgfSBmcm9tIFwiLi4vdXRpbHMvZnMtdXRpbHNcIjtcbmltcG9ydCB0eXBlIHsgQWJzb2x1dGVQYXRoIH0gZnJvbSBcIi4uL3V0aWxzL3BhdGgtdXRpbHNcIjtcbmltcG9ydCB7IHJ1bldpdGhHcmFjZWZ1bFNodXRkb3duIH0gZnJvbSBcIi4uL3V0aWxzL3Byb2Nlc3MtdXRpbHNcIjtcbmltcG9ydCB7IGFyZUZpbGVzU2FtZSwgZmluZENoYW5nZWRGaWxlc1VzaW5nQ2hlY2tzdW1zLCByZW5ld0NoZWNrc3VtcyB9IGZyb20gXCIuL2NoZWNrc3VtXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZVRlbXBsYXRlLCByZW5kZXJUZW1wbGF0ZSB9IGZyb20gXCIuL2NvZGUtZ2VuZXJhdG9yXCI7XG5pbXBvcnQgeyBjcmVhdGVFbnRpdHksIGRlbEVudGl0eSB9IGZyb20gXCIuL2VudGl0eS1vcGVyYXRpb25zXCI7XG5pbXBvcnQgeyB0eXBlIEZpbGVUeXBlLCBnZXRDaGVja3N1bVBhdHRlcm5Hcm91cEluQWJzb2x1dGVQYXRoIH0gZnJvbSBcIi4vZmlsZS1wYXR0ZXJuc1wiO1xuaW1wb3J0IHtcbiAgdHlwZSBMb2FkZWRBcGlzLFxuICB0eXBlIExvYWRlZE1vZGVscyxcbiAgdHlwZSBMb2FkZWRUeXBlcyxcbiAgbG9hZEFwaXMsXG4gIGxvYWRNb2RlbHMsXG4gIGxvYWRUeXBlcyxcbn0gZnJvbSBcIi4vbW9kdWxlLWxvYWRlclwiO1xuXG50eXBlIERpZmZHcm91cHMgPSB7XG4gIFtrZXkgaW4gRmlsZVR5cGVdOiBBYnNvbHV0ZVBhdGhbXTtcbn07XG5cbmV4cG9ydCBjbGFzcyBTeW5jZXIge1xuICBhcGlzOiBMb2FkZWRBcGlzID0gW107XG4gIHR5cGVzOiBMb2FkZWRUeXBlcyA9IHt9O1xuICBtb2RlbHM6IExvYWRlZE1vZGVscyA9IHt9O1xuICBpc1N5bmNpbmc6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvKipcbiAgICog7LK07YGs7ISs7J20IOuzgOqyveuQnCDrtoDrtoTsl5Ag64yA7ZW0IOyLse2BrOulvCDsp4Ttlontlanri4jri6QuXG4gICAqIOuLpOunjCBzb25hbXUuc2hhcmVkLnRz64qUIOyytO2BrOyErCDruYTqtZAg7JeG7J20IOustOyhsOqxtCDsi7Htgawo67O17IKsKe2VqeuLiOuLpC5cbiAgICogQHJldHVybnNcbiAgICovXG4gIGFzeW5jIHN5bmMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyB0YXJnZXRzIH0gPSBTb25hbXUuY29uZmlnLnN5bmM7XG5cbiAgICAvLyBzb25hbXUuc2hhcmVkLnRz64qUIOustOyhsOqxtCDsi7Htgawo67O17IKsKe2VqeuLiOuLpC5cbiAgICBhd2FpdCB0aGlzLmNvcHlTaGFyZWRUb1RhcmdldHModGFyZ2V0cyk7XG5cbiAgICAvLyDqt7gg64uk7J2M67aA7YSw64qUIOuzgOqyveuQnCDtjIzsnbzsnYQg7LC+7JWE7IScIOuPmeq4sO2ZlCDsnpHsl4XsnYQg7Iuk7ZaJ7ZWp64uI64ukLlxuICAgIGNvbnN0IGNoYW5nZWRGaWxlcyA9IGF3YWl0IGZpbmRDaGFuZ2VkRmlsZXNVc2luZ0NoZWNrc3VtcygpO1xuICAgIGlmIChjaGFuZ2VkRmlsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICBjb25zb2xlLmxvZyhjaGFsay5ibGFjay5iZ0dyZWVuKGNlbnRlclRleHQoXCJBbGwgZmlsZXMgYXJlIHN5bmNlZCFcIikpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyDrp4zslb0g7Iux7YGsIOykkeyXkCDtlITroZzshLjsiqTqsIAg7KO97Jy866m0IOq8rOyXrOuyhOumrOq4sCDrlYzrrLjsl5AsXG4gICAgLy8g7Iuc6re464SQ7JeQ64+EIOyeoOyLnCDrsoTti7gg7IiYIOyeiOuKlCDtmZjqsr0g7IaN7JeQ7IScIOyLse2BrOulvCDsi6Ttlontlanri4jri6QuXG4gICAgYXdhaXQgcnVuV2l0aEdyYWNlZnVsU2h1dGRvd24oXG4gICAgICBhc3luYyAoKSA9PiB7XG4gICAgICAgIC8vIOyWmOqwgCDsi7Htgawg7J6R7JeFIOyImO2Wie2VmOuKlCDrs7jssrTsnoXri4jri6QuXG4gICAgICAgIGF3YWl0IHRoaXMuZG9TeW5jQWN0aW9ucyhjaGFuZ2VkRmlsZXMpO1xuXG4gICAgICAgIC8vIOyLse2BrCDslaHshZjsnbQg64Gd64KY66m0IO2VreyDgSDssrTtgazshKzsnYQg64uk7IucIOqwseyLoO2VqeuLiOuLpC5cbiAgICAgICAgYXdhaXQgcmVuZXdDaGVja3N1bXMoKTtcbiAgICAgIH0sXG4gICAgICB7IHdoZW5UaGlzSGFwcGVuczogXCJTSUdVU1IyXCIsIHdhaXRGb3JVcFRvOiAyMDAwMCB9LFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogV2F0Y2hlcuqwgCDqsJDsp4DtlZwg7YyM7J28IOuzgOqyvSDsgqztla3sl5Ag64yA7ZW0IOyLse2BrOulvCDsp4Ttlontlanri4jri6QuXG4gICAqIOyjvOyWtOynhCDrs4Dqsr0g7YyM7J2865OkIOykkSDssrTtgazshKwg6rSA66asIOuMgOyDgeyduCDqsoPrk6Trp4wg6rCA7KC464uk6rCAIOyLse2BrOulvCDsp4Ttlontlanri4jri6QuXG4gICAqIOyytO2BrOyErCDtjIzsnbwg7JeF642w7J207Yq464qUIOyXrOq4sOyXkOyEnCDtlZjsp4Ag7JWK7Iq164uI64ukLiDtmLjstpzsnpDqsIAg7ZWp64uI64ukLlxuICAgKiBAcGFyYW0gZGlmZkZpbGVQYXRoIC0g67OA6rK9IO2MjOydvOuTpC4g7ZSE66Gc7KCd7Yq4IOujqO2KuOu2gO2EsCBcInNyYy9cIiDrmJDripQgXCJkaXN0L1wi66GcIOyLnOyeke2VmOuKlCDsg4HrjIAg6rK966Gc7J6F64uI64ukLiDsmIjsi5w6IFwic3JjL2FwcGxpY2F0aW9uL3VzZXIvdXNlci5tb2RlbC50c1wiXG4gICAqL1xuICBhc3luYyBzeW5jRnJvbVdhdGNoZXIoZXZlbnQ6IHN0cmluZywgZGlmZkZpbGVQYXRoOiBBYnNvbHV0ZVBhdGgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoZXZlbnQgIT09IFwiY2hhbmdlXCIgJiYgZXZlbnQgIT09IFwiYWRkXCIgJiYgZXZlbnQgIT09IFwidW5saW5rXCIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyDsnbzri6gg67OA6rK965CcIO2MjOydvOqzvCBkZXBlbmRlbnQg7YyM7J2865Ok7J2EIGludmFsaWRhdGUg7ZWp64uI64ukLlxuICAgIC8vIO2VnCDrsogg7J207IOBIGltcG9ydOuQnCDsuZzqtazrk6Tsl5Ag64yA7ZW07ISc66eMIOyLpOygnCDsnpHsl4XsnbQg7J287Ja064Kp64uI64ukLlxuICAgIC8vIOq3uOufrOuLiCDslYjsi6ztlZjqs6AgaW52YWxpZGF0ZSDtlbTrj4Qg65Cp64uI64ukLlxuICAgIC8vIO2FjOyKpO2KuCDtmZjqsr3sl5DshJzripQgaG90LmludmFsaWRhdGVGaWxl7IucIOy0iOq4sCDsl5Drn6zqsIAg67Cc7IOd7ZWY6riwIOuVjOusuOyXkCBpbnZhbGlkYXRlIO2VmOyngCDslYrsirXri4jri6QuXG4gICAgaWYgKCFpc1Rlc3QoKSkge1xuICAgICAgY29uc3QgaW52YWxpZGF0ZWRQYXRocyA9IChhd2FpdCBob3QuaW52YWxpZGF0ZUZpbGUoZGlmZkZpbGVQYXRoLCBldmVudCkpIGFzIEFic29sdXRlUGF0aFtdO1xuXG4gICAgICBpZiAoaW52YWxpZGF0ZWRQYXRocy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmJvbGQoYPCflIQgSW52YWxpZGF0ZWQ6YCkpO1xuXG4gICAgICAgIGZvciAoY29uc3QgaW52YWxpZGF0ZWRQYXRoIG9mIGludmFsaWRhdGVkUGF0aHMpIHtcbiAgICAgICAgICAvLyDrp4zslb0gbW9kZWwudHMg7YyM7J287J20IOuzgOqyvShpbnZhbGlkYXRlKeuQmOyXiOuLpD8g6re465+s66m0IHJlZ2lzdGVyZWRBcGlzIOykkeyXkOyEnCDsnbQg66qo64247JeQIO2VtOuLue2VmOuKlCBhcGnrk6TsnYAg7KeA7JuM7KSY7JqULlxuICAgICAgICAgIC8vIHJlZ2lzdGVyZWRBcGlz64qUIO2GteycvOuhnCDri6Qg64Kg66Ck67KE66a0IOyImCDsl4bsirXri4jri6QuIHJlZ2lzdGVyZWRBcGlz7JeQIOyYrOudvOyYpOuKlCDsuZzqtazrk6TsnYAg7LSI6riwIOuhnOuTnOyLnCDrmJDripQgSE1S7Iuc7JeQ66eMIOuTseuhneuQmOq4sCDrlYzrrLjsnoXri4jri6QuXG4gICAgICAgICAgLy8g65Sw65287IScIG1vZGVsLnRzIO2MjOydvOydmCDrs4Dqsr3snLzroZwg64uk7J2M67KIIOyDiOuhnOyatCBldmFs7J20IOyYiOyDgeuQmOuKlCDsnbQg7Iuc7KCQ7JeQ7ISc66eMLCDsnbQg66qo64247JeQ7IScIOuCmOyYqCByZWdpc3RlcmVkQXBpc+uTpOydhCDsp4Dsm4zspIQg7IiYIOyeiOyKteuLiOuLpC5cbiAgICAgICAgICBjb25zdCByZW1vdmVkQXBpcyA9IHRoaXMucmVtb3ZlSW52YWxpZGF0ZWRSZWdpc3RlcmVkQXBpcyhpbnZhbGlkYXRlZFBhdGgpO1xuICAgICAgICAgIGlmIChyZW1vdmVkQXBpcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgY2hhbGsuYmx1ZShgLSAke3BhdGgucmVsYXRpdmUoU29uYW11LmFwaVJvb3RQYXRoLCBpbnZhbGlkYXRlZFBhdGgpfWApLFxuICAgICAgICAgICAgICBjaGFsay5ncmF5KGAod2l0aCAke3JlbW92ZWRBcGlzLmxlbmd0aH0gQVBJcylgKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmJsdWUoYC0gJHtwYXRoLnJlbGF0aXZlKFNvbmFtdS5hcGlSb290UGF0aCwgaW52YWxpZGF0ZWRQYXRoKX1gKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgaXNJbkNoZWNrUGF0dGVybkdyb3VwID0gT2JqZWN0LnZhbHVlcyhnZXRDaGVja3N1bVBhdHRlcm5Hcm91cEluQWJzb2x1dGVQYXRoKCkpLnNvbWUoXG4gICAgICAocGF0dGVybikgPT4gbWluaW1hdGNoKGRpZmZGaWxlUGF0aCwgcGF0dGVybiksXG4gICAgKTtcblxuICAgIC8vIO2VoCDsnbwoc3luYynsnbQg7J6I7Jy866m0IO2VqeuLiOuLpC5cbiAgICBpZiAoaXNJbkNoZWNrUGF0dGVybkdyb3VwKSB7XG4gICAgICBhd2FpdCB0aGlzLmRvU3luY0FjdGlvbnMoW2RpZmZGaWxlUGF0aF0pO1xuICAgIH1cblxuICAgIC8vIOyLse2BrCDsnpHsl4XsnbQg64Gd64KY66m0IOuqqOuToCDrqqjrk4jsnYQg66Gc65Oc7ZWp64uI64ukLlxuICAgIC8vIGhvdC1ob29r7JeQIOydmO2VtCBpbnZhbGlkYXRl65CcIOu2gOu2hOuTpOydtCDslYTri4jrnbzrqbQg7LqQ7IucIOq3uOuMgOuhnCDsnKDsp4Dtlanri4jri6QuXG4gICAgYXdhaXQgdGhpcy5hdXRvbG9hZFR5cGVzKCk7XG4gICAgYXdhaXQgdGhpcy5hdXRvbG9hZE1vZGVscygpO1xuICAgIGF3YWl0IHRoaXMuYXV0b2xvYWRBcGlzKCk7XG5cbiAgICB0aGlzLnN5bmNVSSgpO1xuICB9XG5cbiAgcmVtb3ZlSW52YWxpZGF0ZWRSZWdpc3RlcmVkQXBpcyhcbiAgICBpbnZhbGlkYXRlZFBhdGg6IEFic29sdXRlUGF0aCxcbiAgKTogKHR5cGVvZiByZWdpc3RlcmVkQXBpcylbbnVtYmVyXVtdIHtcbiAgICBpZiAoIWludmFsaWRhdGVkUGF0aC5lbmRzV2l0aChcIi5tb2RlbC50c1wiIC8q7IaM7IqkIOy9lOuTnOulvCDri6Tro6jripQg7IOB7Zmp7J2064uIIC50cyDqsr3roZzroZwg67SF64uI64ukLiovKSkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGNvbnN0IGVudGl0eUlkID0gRW50aXR5TWFuYWdlci5nZXRFbnRpdHlJZEZyb21QYXRoKGludmFsaWRhdGVkUGF0aCk7XG4gICAgY29uc3QgdG9SZW1vdmUgPSByZWdpc3RlcmVkQXBpcy5maWx0ZXIoKGFwaSkgPT4gYXBpLm1vZGVsTmFtZSA9PT0gYCR7ZW50aXR5SWR9TW9kZWxgKTtcbiAgICBmb3IgKGNvbnN0IGFwaSBvZiB0b1JlbW92ZSkge1xuICAgICAgcmVnaXN0ZXJlZEFwaXMuc3BsaWNlKHJlZ2lzdGVyZWRBcGlzLmluZGV4T2YoYXBpKSwgMSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRvUmVtb3ZlO1xuICB9XG5cbiAgYXN5bmMgY29weVNoYXJlZFRvVGFyZ2V0cyh0YXJnZXRzOiBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGZvciAoY29uc3QgdGFyZ2V0IG9mIHRhcmdldHMpIHtcbiAgICAgIC8vIOyngOq4iCDqsIDsoLjqsIDroKTripQg7J20IO2MjOydvOydgCBTb25hbXUg7L2U65Oc67Kg7J207Iqk7J2YIOydvOu2gOyeheuLiOuLpC5cbiAgICAgIC8vIOq3uOufsOuNsCBkaXN0IOyGjSDruYzrk5zrkJwg7IaM7IqkIOy9lOuTnCDtjIzsnbzsnbQg7ZWE7JqU7ZWcIOqyg+ydtCDslYTri4jqs6AsIHNyY+yXkOunjCDsnojripQg7YWN7Iqk7Yq4IO2MjOydvOydtCDtlYTsmpTtlanri4jri6QuXG4gICAgICAvLyDrlLDrnbzshJwgL3NyYy/sl5DshJwg7LC+7Iq164uI64ukLlxuICAgICAgY29uc3Qgc3JjUGF0aCA9IHBhdGguam9pbihcbiAgICAgICAgaW1wb3J0Lm1ldGEuZGlybmFtZS5yZXBsYWNlKFwiL2Rpc3QvXCIsIFwiL3NyYy9cIiksXG4gICAgICAgIGAuLi9zaGFyZWQvJHt0YXJnZXR9LnNoYXJlZC50cy50eHRgLFxuICAgICAgKTtcbiAgICAgIGlmICghKGF3YWl0IGV4aXN0cyhzcmNQYXRoKSkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKCEoYXdhaXQgZXhpc3RzKHBhdGguam9pbihTb25hbXUuYXBwUm9vdFBhdGgsIHRhcmdldCkpKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYFRyaWVkIHRvIGNvcHkgc29uYW11LnNoYXJlZC50cyB0byB0YXJnZXQgJyR7dGFyZ2V0fScgYnV0IHRoZSB0YXJnZXQgZGlyZWN0b3J5IGRvZXMgbm90IGV4aXN0LiBQbGVhc2UgY2hlY2sgeW91ciBwcm9qZWN0IGRpcmVjdG9yeSBzdHJ1Y3R1cmUuYCxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8g7J206rG0IO2UhOuhnOygne2KuOyXkCAudHMg7IaM7IqkIOy9lOuTnCDtjIzsnbzsnYQg7IOd7ISx7ZWY64qUIOqyg+ydtOuvgOuhnCBzcmPsnZggLnRzIOqyveuhnOuhnCDqsJHri4jri6QuXG4gICAgICBjb25zdCBkZXN0UGF0aCA9IHBhdGguam9pbihTb25hbXUuYXBwUm9vdFBhdGgsIHRhcmdldCwgXCIuL3NvbmFtdS5zaGFyZWQudHNcIik7XG5cbiAgICAgIC8vIOygleunkCDtmLnsi5zrgpjsp4Drp4wgdGFyZ2V0IOuUlOugie2GoOumrOuKlCDsnojslrTrj4Qgc3JjL3NlcnZpY2VzIOuUlOugie2GoOumrOuKlCDsl4bsnYQg7IiYIOyeiOycvOuvgOuhnCDrr7jrpqwg7IOd7ISx7ZW07KSN64uI64ukLlxuICAgICAgaWYgKCEoYXdhaXQgZXhpc3RzKHBhdGguZGlybmFtZShkZXN0UGF0aCkpKSkge1xuICAgICAgICBhd2FpdCBta2RpcihwYXRoLmRpcm5hbWUoZGVzdFBhdGgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgICAgY29uc29sZS53YXJuKGBDcmVhdGVkIGRpcmVjdG9yeSAnJHtwYXRoLmRpcm5hbWUoZGVzdFBhdGgpfScgYmVjYXVzZSBpdCBkaWQgbm90IGV4aXN0LmApO1xuICAgICAgfVxuXG4gICAgICBpZiAoYXdhaXQgYXJlRmlsZXNTYW1lKHNyY1BhdGgsIGRlc3RQYXRoKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHdyaXRlRmlsZShkZXN0UGF0aCwgYXdhaXQgcmVhZEZpbGUoc3JjUGF0aCkpO1xuXG4gICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgY2hhbGsuYm9sZChcIkNvcGllZDogXCIpICsgY2hhbGsuYmx1ZShwYXRoLnJlbGF0aXZlKFNvbmFtdS5hcHBSb290UGF0aCwgZGVzdFBhdGgpKSxcbiAgICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBhdXRvbG9hZFR5cGVzKCkge1xuICAgIHRoaXMudHlwZXMgPSBhd2FpdCBsb2FkVHlwZXMoKTtcbiAgfVxuXG4gIGFzeW5jIGF1dG9sb2FkTW9kZWxzKCkge1xuICAgIHRoaXMubW9kZWxzID0gYXdhaXQgbG9hZE1vZGVscygpO1xuICB9XG5cbiAgYXN5bmMgYXV0b2xvYWRBcGlzKCkge1xuICAgIHRoaXMuYXBpcyA9IGF3YWl0IGxvYWRBcGlzKCk7XG4gIH1cblxuICAvKipcbiAgICog7Iuk7KCcIOyLse2BrOulvCDsiJjtlontlZjripQg67O47LK07J6F64uI64ukLlxuICAgKiDrs4Dqsr3rkJwg7YyM7J2865Ok7J2EIO2DgOyeheuzhOuhnCDrtoTrpZjtlZjqs6Ag6rCBIO2DgOyeheyXkCDrp57ripQg7JWh7IWY7J2EIOyLpO2Wie2VqeuLiOuLpC5cbiAgICogQHBhcmFtIGRpZmZGaWxlUGF0aHMgLSDrs4Dqsr3rkJwg7YyM7J2865Ok7J2YIOygiOuMgCDqsr3roZwg66qp66GdXG4gICAqIEByZXR1cm5zIGRpZmZUeXBlcyAtIOuzgOqyveuQnCDtjIzsnbzsnZgg7YOA7J6FIOuqqeuhnSAoZW50aXR5LCB0eXBlcywgbW9kZWwg65OxKVxuICAgKi9cbiAgYXN5bmMgZG9TeW5jQWN0aW9ucyhkaWZmRmlsZVBhdGhzOiBBYnNvbHV0ZVBhdGhbXSk6IFByb21pc2U8eyBkaWZmVHlwZXM6IHN0cmluZ1tdIH0+IHtcbiAgICBjb25zdCBkaWZmR3JvdXBzID0gdGhpcy5jYWxjdWxhdGVEaWZmR3JvdXBzKGRpZmZGaWxlUGF0aHMpO1xuICAgIGNvbnN0IGRpZmZUeXBlcyA9IE9iamVjdC5rZXlzKGRpZmZHcm91cHMpO1xuXG4gICAgLy8g7Yq466as6rGwOiBlbnRpdHksIHR5cGVzXG4gICAgLy8g7JWh7IWYOiDsiqTtgqTrp4gg7IOd7ISxXG4gICAgaWYgKGRpZmZUeXBlcy5pbmNsdWRlcyhcImVudGl0eVwiKSkge1xuICAgICAgYXdhaXQgdGhpcy5oYW5kbGVFbnRpdHlDaGFuZ2UoZGlmZkdyb3VwcywgZGlmZlR5cGVzKTtcbiAgICB9XG5cbiAgICAvLyDtirjrpqzqsbA6IHR5cGVzLCBlbnVtcywgZ2VuZXJhdGVkIOuzgOqyveyLnFxuICAgIC8vIOyVoeyFmDog7YyM7J28IOyLse2BrCB0eXBlcywgZW51bXMsIGdlbmVyYXRlZFxuICAgIGlmIChcbiAgICAgIGRpZmZUeXBlcy5pbmNsdWRlcyhcInR5cGVzXCIpIHx8XG4gICAgICBkaWZmVHlwZXMuaW5jbHVkZXMoXCJmdW5jdGlvbnNcIikgfHxcbiAgICAgIGRpZmZUeXBlcy5pbmNsdWRlcyhcImdlbmVyYXRlZFwiKVxuICAgICkge1xuICAgICAgYXdhaXQgdGhpcy5oYW5kbGVUeXBlc09yRnVuY3Rpb25zT3JHZW5lcmF0ZWRDaGFuZ2UoZGlmZkdyb3Vwcyk7XG4gICAgfVxuXG4gICAgLy8g7Yq466as6rGwOiBtb2RlbFxuICAgIGlmIChkaWZmVHlwZXMuaW5jbHVkZXMoXCJtb2RlbFwiKSB8fCBkaWZmVHlwZXMuaW5jbHVkZXMoXCJmcmFtZVwiKSkge1xuICAgICAgYXdhaXQgdGhpcy5oYW5kbGVNb2RlbE9yRnJhbWVDaGFuZ2UoZGlmZkdyb3Vwcyk7XG4gICAgfVxuXG4gICAgLy8g7Yq466as6rGwOiBjb25maWdcbiAgICBpZiAoZGlmZlR5cGVzLmluY2x1ZGVzKFwiY29uZmlnXCIpKSB7XG4gICAgICBhd2FpdCB0aGlzLmFjdGlvblN5bmNDb25maWcoKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGlmZlR5cGVzLFxuICAgIH07XG4gIH1cblxuICBjYWxjdWxhdGVEaWZmR3JvdXBzKGRpZmZGaWxlczogQWJzb2x1dGVQYXRoW10pOiBEaWZmR3JvdXBzIHtcbiAgICByZXR1cm4gZ3JvdXAoZGlmZkZpbGVzLCAocikgPT4ge1xuICAgICAgY29uc3QgbWF0Y2hlZCA9IHIubWF0Y2goL1xcLihtb2RlbHx0eXBlc3xmdW5jdGlvbnN8ZW50aXR5fGdlbmVyYXRlZHxmcmFtZXxjb25maWcpXFwuW3RqXXMvKTtcbiAgICAgIHJldHVybiBtYXRjaGVkPy5bMV0gPz8gXCJ1bmtub3duXCI7XG4gICAgfSkgYXMgdW5rbm93biBhcyBEaWZmR3JvdXBzO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlRW50aXR5Q2hhbmdlKGRpZmZHcm91cHM6IERpZmZHcm91cHMsIGRpZmZUeXBlczogc3RyaW5nW10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBOYWl0ZS50KFwiaGFuZGxlRW50aXR5Q2hhbmdlXCIsIHsgZGlmZkdyb3VwcywgZGlmZlR5cGVzIH0pO1xuXG4gICAgYXdhaXQgRW50aXR5TWFuYWdlci5yZWxvYWQoKTtcblxuICAgIC8vIHR5cGVzIOyDneyEsShlbnRpdHkg7IOI66GcIOy2lOqwgOuQnCDqsr3smrApXG4gICAgLy8gcGFyZW50SWTqsIAg7JeG6rOgLCB0eXBlc+qwgCDsl4bripQg6rK97Jqw7JeQ66eMIOyDneyEsVxuICAgIGNvbnN0IGVudGl0eUlkID0gRW50aXR5TWFuYWdlci5nZXRFbnRpdHlJZEZyb21QYXRoKGRpZmZHcm91cHMuZW50aXR5Py5bMF0pO1xuXG4gICAgaWYgKGVudGl0eUlkKSB7XG4gICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAvLyDtlITroZzsoJ3tirjsl5Ag7IOd7ISx65CY7Ja07JW8IO2VmOuKlCAudHMg7YyM7J287J2YIOqyveuhnOyeheuLiOuLpC5cbiAgICAgIGNvbnN0IHR5cGVGaWxlUGF0aCA9IHBhdGguam9pbihcbiAgICAgICAgU29uYW11LmFwaVJvb3RQYXRoLFxuICAgICAgICBgc3JjL2FwcGxpY2F0aW9uLyR7ZW50aXR5Lm5hbWVzLmZzfS8ke2VudGl0eS5uYW1lcy5mc30udHlwZXMudHNgLFxuICAgICAgKTtcbiAgICAgIGlmIChlbnRpdHkucGFyZW50SWQgPT09IHVuZGVmaW5lZCAmJiAhKGF3YWl0IGV4aXN0cyh0eXBlRmlsZVBhdGgpKSkge1xuICAgICAgICBhd2FpdCBnZW5lcmF0ZVRlbXBsYXRlKFwiaW5pdF90eXBlc1wiLCB7IGVudGl0eUlkIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuYWN0aW9uR2VuZXJhdGVTY2hlbWFzKCk7XG5cbiAgICBkaWZmR3JvdXBzLmdlbmVyYXRlZCA9IHVuaXF1ZShbXG4gICAgICAuLi4oZGlmZkdyb3Vwcy5nZW5lcmF0ZWQgPz8gW10pLFxuICAgICAgcGF0aC5qb2luKFNvbmFtdS5hcGlSb290UGF0aCwgXCJzcmMvYXBwbGljYXRpb24vc29uYW11LmdlbmVyYXRlZC50c1wiKSBhcyBBYnNvbHV0ZVBhdGgsXG4gICAgXSk7XG4gICAgZGlmZlR5cGVzLnB1c2goXCJnZW5lcmF0ZWRcIik7XG4gIH1cblxuICBhc3luYyBoYW5kbGVUeXBlc09yRnVuY3Rpb25zT3JHZW5lcmF0ZWRDaGFuZ2UoZGlmZkdyb3VwczogRGlmZkdyb3Vwcyk6IFByb21pc2U8RmlsZVR5cGVbXT4ge1xuICAgIGNvbnN0IHRzUGF0aHMgPSB1bmlxdWUoW1xuICAgICAgLi4uKGRpZmZHcm91cHMudHlwZXMgPz8gW10pLFxuICAgICAgLi4uKGRpZmZHcm91cHMuZnVuY3Rpb25zID8/IFtdKSxcbiAgICAgIC4uLihkaWZmR3JvdXBzLmdlbmVyYXRlZCA/PyBbXSksXG4gICAgXSk7XG4gICAgTmFpdGUudChcImhhbmRsZVR5cGVzT3JGdW5jdGlvbnNPckdlbmVyYXRlZENoYW5nZVwiLCB7IGRpZmZHcm91cHMgfSk7XG5cbiAgICAvLyBjb25zb2xlLmxvZyhcbiAgICAvLyAgIGNoYWxrLmdyYXkoXG4gICAgLy8gICAgIGBbUHJvY2Vzc2luZ10gSGFuZGxpbmcgdHlwZXMvZnVuY3Rpb25zL2dlbmVyYXRlZCBjaGFuZ2VzOiAke3RzUGF0aHMubWFwKChwKSA9PiBwYXRoLnJlbGF0aXZlKFNvbmFtdS5hcGlSb290UGF0aCwgcCkpLmpvaW4oXCIsIFwiKX1gXG4gICAgLy8gICApXG4gICAgLy8gKTtcblxuICAgIGF3YWl0IHRoaXMuYWN0aW9uU3luY0ZpbGVzVG9UYXJnZXRzKHRzUGF0aHMpO1xuXG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlTW9kZWxPckZyYW1lQ2hhbmdlKGRpZmZHcm91cHM6IERpZmZHcm91cHMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBOYWl0ZS50KFwiaGFuZGxlTW9kZWxPckZyYW1lQ2hhbmdlXCIsIHsgZGlmZkdyb3VwcyB9KTtcbiAgICBjb25zdCBtZXJnZWRHcm91cCA9IFsuLi4oZGlmZkdyb3Vwcy5tb2RlbCA/PyBbXSksIC4uLihkaWZmR3JvdXBzLmZyYW1lID8/IFtdKV07XG5cbiAgICAvLyBjb25zb2xlLmxvZyhcbiAgICAvLyAgIGNoYWxrLmdyYXkoXG4gICAgLy8gICAgIGBbUHJvY2Vzc2luZ10gSGFuZGxpbmcgbW9kZWwvZnJhbWUgY2hhbmdlczogJHttZXJnZWRHcm91cC5tYXAoKHApID0+IHBhdGgucmVsYXRpdmUoU29uYW11LmFwaVJvb3RQYXRoLCBwKSkuam9pbihcIiwgXCIpfWBcbiAgICAvLyAgIClcbiAgICAvLyApO1xuXG4gICAgLy8gZ2VuZXJhdGVkX2h0dHAudGVtcGxhdGUudHPsl5DshJwgc3luY2VyLnR5cGVz66W8IOyUgeuLiOuLpC5cbiAgICAvLyBzZXJ2aWNlLnRlbXBsYXRlLnRz7JeQ7IScIHN5bmNlci5hcGlz66W8IOyUgeuLiOuLpC5cbiAgICBhd2FpdCB0aGlzLmF1dG9sb2FkTW9kZWxzKCk7XG4gICAgYXdhaXQgdGhpcy5hdXRvbG9hZFR5cGVzKCk7XG4gICAgYXdhaXQgdGhpcy5hdXRvbG9hZEFwaXMoKTtcblxuICAgIGNvbnN0IHBhcmFtczoge1xuICAgICAgbmFtZXNSZWNvcmQ6IEVudGl0eU5hbWVzUmVjb3JkO1xuICAgIH1bXSA9IG1lcmdlZEdyb3VwLm1hcCgobW9kZWxQYXRoKSA9PiB7XG4gICAgICBpZiAobW9kZWxQYXRoLmVuZHNXaXRoKFwiLm1vZGVsLnRzXCIpKSB7XG4gICAgICAgIGNvbnN0IGVudGl0eUlkID0gRW50aXR5TWFuYWdlci5nZXRFbnRpdHlJZEZyb21QYXRoKG1vZGVsUGF0aCk7XG4gICAgICAgIGFzc2VydChlbnRpdHlJZCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgbmFtZXNSZWNvcmQ6IEVudGl0eU1hbmFnZXIuZ2V0TmFtZXNGcm9tSWQoZW50aXR5SWQpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgaWYgKG1vZGVsUGF0aC5lbmRzV2l0aChcImZyYW1lLnRzXCIpKSB7XG4gICAgICAgIGNvbnN0IFssIGZyYW1lTmFtZV0gPSBtb2RlbFBhdGgubWF0Y2goLy4rXFwvKC4rKVxcLmZyYW1lLmpzJC8pID8/IFtdO1xuICAgICAgICBhc3NlcnQoZnJhbWVOYW1lKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBuYW1lc1JlY29yZDogRW50aXR5TWFuYWdlci5nZXROYW1lc0Zyb21JZChmcmFtZU5hbWUpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwibm90IHJlYWNoYWJsZVwiKTtcbiAgICB9KTtcblxuICAgIGF3YWl0IHRoaXMuYWN0aW9uR2VuZXJhdGVTZXJ2aWNlcyhwYXJhbXMpO1xuICAgIGF3YWl0IHRoaXMuYWN0aW9uR2VuZXJhdGVIdHRwcygpO1xuICB9XG5cbiAgLy8gd2ViLy5zb25hbXUuZW52IOyXkCDtmITsnqwg7ISk7KCV6rCSIOyggOyepVxuICBhc3luYyBhY3Rpb25TeW5jQ29uZmlnKCkge1xuICAgIGNvbnN0IHsgaG9zdCwgcG9ydCB9ID0gU29uYW11LmNvbmZpZy5zZXJ2ZXIubGlzdGVuID8/IHt9O1xuICAgIGNvbnN0IGNvbnRlbnQgPSBgQVBJX0hPU1Q9JHtob3N0ID8/IFwibG9jYWxob3N0XCJ9XFxuQVBJX1BPUlQ9JHtwb3J0ID8/IDMwMDB9YDtcblxuICAgIE5haXRlLnQoXCJhY3Rpb25TeW5jQ29uZmlnXCIsIHsgY29udGVudCB9KTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIFNvbmFtdS5jb25maWcuc3luYy50YXJnZXRzLm1hcChhc3luYyAodGFyZ2V0KSA9PiB7XG4gICAgICAgIGF3YWl0IHdyaXRlRmlsZShwYXRoLmpvaW4oU29uYW11LmFwcFJvb3RQYXRoLCB0YXJnZXQsIFwiLnNvbmFtdS5lbnZcIiksIGNvbnRlbnQpO1xuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBzb25hbXUuZ2VuZXJhdGVkLnRz7JmAIHNvbmFtdS5nZW5lcmF0ZWQuc3NvLnRz66W8IOyDneyEse2VqeuLiOuLpC5cbiAgICogQHJldHVybnMg7IOd7ISx65CcIO2MjOydvCDqsr3roZwg67Cw7Je0LlxuICAgKi9cbiAgYXN5bmMgYWN0aW9uR2VuZXJhdGVTY2hlbWFzKCk6IFByb21pc2U8QWJzb2x1dGVQYXRoW10+IHtcbiAgICByZXR1cm4gKFxuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBnZW5lcmF0ZVRlbXBsYXRlKFwiZ2VuZXJhdGVkX3Nzb1wiLCB7fSwgeyBvdmVyd3JpdGU6IHRydWUgfSksXG4gICAgICAgIGdlbmVyYXRlVGVtcGxhdGUoXCJnZW5lcmF0ZWRcIiwge30sIHsgb3ZlcndyaXRlOiB0cnVlIH0pLFxuICAgICAgXSlcbiAgICApXG4gICAgICAuZmxhdCgpXG4gICAgICAuZmxhdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqICouc2VydmljZS50c+ulvCDsg53shLHtlanri4jri6QuXG4gICAqIEBwYXJhbSBwYXJhbXNBcnJheVxuICAgKiBAcmV0dXJucyDsg53shLHrkJwg7YyM7J28IOqyveuhnCDrsLDsl7QuXG4gICAqL1xuICBhc3luYyBhY3Rpb25HZW5lcmF0ZVNlcnZpY2VzKFxuICAgIHBhcmFtc0FycmF5OiB7XG4gICAgICBuYW1lc1JlY29yZDogRW50aXR5TmFtZXNSZWNvcmQ7XG4gICAgfVtdLFxuICApOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgTmFpdGUudChcImFjdGlvbkdlbmVyYXRlU2VydmljZXNcIiwgcGFyYW1zQXJyYXkpO1xuICAgIHJldHVybiAoXG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgcGFyYW1zQXJyYXkubWFwKGFzeW5jIChwYXJhbXMpID0+XG4gICAgICAgICAgZ2VuZXJhdGVUZW1wbGF0ZShcInNlcnZpY2VcIiwgcGFyYW1zIGFzIFRlbXBsYXRlT3B0aW9uc1tcInNlcnZpY2VcIl0sIHtcbiAgICAgICAgICAgIG92ZXJ3cml0ZTogdHJ1ZSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKSxcbiAgICAgIClcbiAgICApXG4gICAgICAuZmxhdCgpXG4gICAgICAuZmxhdCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIHNvbmFtdS5nZW5lcmF0ZWQuaHR0cOulvCDsg53shLHtlanri4jri6QuXG4gICAqIEByZXR1cm5zIOyDneyEseuQnCDtjIzsnbwg6rK966GcLlxuICAgKi9cbiAgYXN5bmMgYWN0aW9uR2VuZXJhdGVIdHRwcygpOiBQcm9taXNlPEFic29sdXRlUGF0aD4ge1xuICAgIGNvbnN0IFtyZXNdID0gYXdhaXQgZ2VuZXJhdGVUZW1wbGF0ZShcbiAgICAgIFwiZ2VuZXJhdGVkX2h0dHBcIixcbiAgICAgIHsgZW50aXR5SWQ6IFwiZHVtbXlcIiB9LFxuICAgICAgeyBvdmVyd3JpdGU6IHRydWUgfSxcbiAgICApO1xuICAgIGFzc2VydChyZXMpO1xuICAgIHJldHVybiByZXM7XG4gIH1cblxuICAvKipcbiAgICogKi50eXBlcy50cywgKi5mdW5jdGlvbnMudHMsICouZ2VuZXJhdGVkLnRz66W8IO2DgOqynyDrlJTroInthqDrpqzsl5Ag67O17IKs7ZWp64uI64ukLlxuICAgKiBAcGFyYW0gdHNQYXRoc1xuICAgKiBAcmV0dXJucyDrs7XsgqzrkJwg7YyM7J28IOqyveuhnCDrsLDsl7QuXG4gICAqL1xuICBhc3luYyBhY3Rpb25TeW5jRmlsZXNUb1RhcmdldHModHNQYXRoczogQWJzb2x1dGVQYXRoW10pOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gICAgY29uc3QgeyB0YXJnZXRzIH0gPSBTb25hbXUuY29uZmlnLnN5bmM7XG4gICAgY29uc3QgeyBkaXI6IGFwaURpciB9ID0gU29uYW11LmNvbmZpZy5hcGk7XG5cbiAgICByZXR1cm4gKFxuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgIHRhcmdldHMubWFwKGFzeW5jICh0YXJnZXQpID0+XG4gICAgICAgICAgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICB0c1BhdGhzLm1hcChhc3luYyAocmVhbFNyYykgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBkc3QgPSByZWFsU3JjXG4gICAgICAgICAgICAgICAgLnJlcGxhY2UoYC8ke2FwaURpcn0vYCwgYC8ke3RhcmdldH0vYClcbiAgICAgICAgICAgICAgICAucmVwbGFjZShcIi9hcHBsaWNhdGlvbi9cIiwgXCIvc2VydmljZXMvXCIpO1xuICAgICAgICAgICAgICBjb25zdCBkaXIgPSBkaXJuYW1lKGRzdCk7XG4gICAgICAgICAgICAgIGlmICghKGF3YWl0IGV4aXN0cyhkaXIpKSkge1xuICAgICAgICAgICAgICAgIGF3YWl0IG1rZGlyKGRpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAgICAgICBjaGFsay5ib2xkKFwiQ29waWVkOiBcIikgKyBjaGFsay5ibHVlKGRzdC5yZXBsYWNlKGAke1NvbmFtdS5hcHBSb290UGF0aH0vYCwgXCJcIikpLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGF3YWl0IHRoaXMuY29weUZpbGVXaXRoUmVwbGFjZUNvcmVUb1NoYXJlZChyZWFsU3JjLCBkc3QpO1xuICAgICAgICAgICAgICByZXR1cm4gZHN0O1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKSxcbiAgICAgICAgKSxcbiAgICAgIClcbiAgICApLmZsYXQoKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY29weUZpbGVXaXRoUmVwbGFjZUNvcmVUb1NoYXJlZChmcm9tUGF0aDogc3RyaW5nLCB0b1BhdGg6IHN0cmluZykge1xuICAgIGlmICghKGF3YWl0IGV4aXN0cyhmcm9tUGF0aCkpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgb2xkRmlsZUNvbnRlbnQgPSAoYXdhaXQgcmVhZEZpbGUoZnJvbVBhdGgpKS50b1N0cmluZygpO1xuXG4gICAgY29uc3QgbmV3RmlsZUNvbnRlbnQgPSAoKCkgPT4ge1xuICAgICAgY29uc3QgbmZjID0gb2xkRmlsZUNvbnRlbnQucmVwbGFjZSgvZnJvbSBcInNvbmFtdVwiL2csIGBmcm9tIFwiLi9zb25hbXUuc2hhcmVkXCJgKTtcbiAgICAgIHJldHVybiBuZmM7XG4gICAgfSkoKTtcbiAgICByZXR1cm4gd3JpdGVGaWxlKHRvUGF0aCwgbmV3RmlsZUNvbnRlbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIOyjvOyWtOynhCDsl5Tti7Dti7DsmYAg7YWc7ZSM66a/IO2CpOyXkCDrjIDtlbQsIOyDneyEseuQnCDsvZTrk5zqsIAg7KG07J6s7ZWY64qU7KeAIO2ZleyduO2VqeuLiOuLpC5cbiAgICogQHBhcmFtIGVudGl0eUlkIOyXlO2LsO2LsCBJRFxuICAgKiBAcGFyYW0gdGVtcGxhdGVLZXkg7YWc7ZSM66a/IO2CpFxuICAgKiBAcGFyYW0gZW51bUlkIOyXtOqxsO2YlSBJRFxuICAgKiBAcmV0dXJucyDsg53shLHrkJwg7L2U65Oc6rCAIOyhtOyerO2VmOuKlOyngCDsl6zrtoBcbiAgICovXG4gIGFzeW5jIGNoZWNrRXhpc3RzR2VuQ29kZShcbiAgICBlbnRpdHlJZDogc3RyaW5nLFxuICAgIHRlbXBsYXRlS2V5OiBUZW1wbGF0ZUtleSxcbiAgICBlbnVtSWQ/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8eyBzdWJQYXRoOiBzdHJpbmc7IGZ1bGxQYXRoOiBzdHJpbmc7IGlzRXhpc3RzOiBib29sZWFuIH0+IHtcbiAgICBjb25zdCB7IHRhcmdldCwgcGF0aDogZ2VuUGF0aCB9ID0gVGVtcGxhdGVNYW5hZ2VyLmdldCh0ZW1wbGF0ZUtleSkuZ2V0VGFyZ2V0QW5kUGF0aChcbiAgICAgIEVudGl0eU1hbmFnZXIuZ2V0TmFtZXNGcm9tSWQoZW50aXR5SWQpLFxuICAgICAgZW51bUlkLFxuICAgICk7XG5cbiAgICBjb25zdCBzdWJQYXRoID0gcGF0aC5qb2luKHRhcmdldCwgZ2VuUGF0aCk7XG4gICAgY29uc3QgZnVsbFBhdGggPSBwYXRoLmpvaW4oU29uYW11LmFwcFJvb3RQYXRoLCBzdWJQYXRoKTtcbiAgICByZXR1cm4ge1xuICAgICAgc3ViUGF0aCxcbiAgICAgIGZ1bGxQYXRoLFxuICAgICAgaXNFeGlzdHM6IGF3YWl0IGV4aXN0cyhmdWxsUGF0aCksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDso7zslrTsp4Qg7JeU7Yuw7Yuw7JmAIOyXtOqxsO2YleyXkCDrjIDtlbQsIOyDneyEseuQnCDsvZTrk5zqsIAg7KG07J6s7ZWY64qU7KeAIO2ZleyduO2VqeuLiOuLpC5cbiAgICogQHBhcmFtIGVudGl0eUlkIOyXlO2LsO2LsCBJRFxuICAgKiBAcGFyYW0gZW51bXMg7Je06rGw7ZiVIOugiOydtOu4lFxuICAgKiBAcmV0dXJucyDsg53shLHrkJwg7L2U65Oc6rCAIOyhtOyerO2VmOuKlOyngCDsl6zrtoBcbiAgICovXG4gIGFzeW5jIGNoZWNrRXhpc3RzKFxuICAgIGVudGl0eUlkOiBzdHJpbmcsXG4gICAgZW51bXM6IHtcbiAgICAgIFtuYW1lOiBzdHJpbmddOiB6LlpvZEVudW08UmVhZG9ubHk8UmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVtYmVyPj4+O1xuICAgIH0sXG4gICk6IFByb21pc2U8UmVjb3JkPGAke1RlbXBsYXRlS2V5fSR7c3RyaW5nfWAsIGJvb2xlYW4+PiB7XG4gICAgY29uc3Qga2V5czogVGVtcGxhdGVLZXlbXSA9IFRlbXBsYXRlS2V5Lm9wdGlvbnM7XG4gICAgY29uc3QgbmFtZXMgPSBFbnRpdHlNYW5hZ2VyLmdldE5hbWVzRnJvbUlkKGVudGl0eUlkKTtcbiAgICBjb25zdCBlbnVtc0tleXMgPSBPYmplY3Qua2V5cyhlbnVtcykuZmlsdGVyKChuYW1lKSA9PiBuYW1lICE9PSBuYW1lcy5jb25zdGFudCk7XG5cbiAgICByZXR1cm4gYXdhaXQgcmVkdWNlQXN5bmMoXG4gICAgICBrZXlzLFxuICAgICAgYXN5bmMgKHJlc3VsdCwga2V5KSA9PiB7XG4gICAgICAgIGNvbnN0IHRwbCA9IFRlbXBsYXRlTWFuYWdlci5nZXQoa2V5KTtcbiAgICAgICAgaWYgKGtleS5zdGFydHNXaXRoKFwidmlld19lbnVtc1wiKSkge1xuICAgICAgICAgIGF3YWl0IG1hcEFzeW5jKGVudW1zS2V5cywgYXN5bmMgKGNvbXBvbmVudElkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB7IHRhcmdldCwgcGF0aDogcCB9ID0gdHBsLmdldFRhcmdldEFuZFBhdGgobmFtZXMsIGNvbXBvbmVudElkKTtcbiAgICAgICAgICAgIHJlc3VsdFtgJHtrZXl9X18ke2NvbXBvbmVudElkfWBdID0gYXdhaXQgZXhpc3RzKFxuICAgICAgICAgICAgICBwYXRoLmpvaW4oU29uYW11LmFwcFJvb3RQYXRoLCB0YXJnZXQsIHApLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgeyB0YXJnZXQsIHBhdGg6IHAgfSA9IHRwbC5nZXRUYXJnZXRBbmRQYXRoKG5hbWVzKTtcbiAgICAgICAgY29uc3QgeyB0YXJnZXRzIH0gPSBTb25hbXUuY29uZmlnLnN5bmM7XG4gICAgICAgIGlmICh0YXJnZXQuaW5jbHVkZXMoXCI6dGFyZ2V0XCIpKSB7XG4gICAgICAgICAgYXdhaXQgbWFwQXN5bmModGFyZ2V0cywgYXN5bmMgKHQpID0+IHtcbiAgICAgICAgICAgIHJlc3VsdFtgJHtrZXl9X18ke3R9YF0gPSBhd2FpdCBleGlzdHMoXG4gICAgICAgICAgICAgIHBhdGguam9pbihTb25hbXUuYXBwUm9vdFBhdGgsIHRhcmdldC5yZXBsYWNlKFwiOnRhcmdldFwiLCB0KSwgcCksXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc3VsdFtrZXldID0gYXdhaXQgZXhpc3RzKHBhdGguam9pbihTb25hbXUuYXBwUm9vdFBhdGgsIHRhcmdldCwgcCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0sXG4gICAgICB7fSBhcyBSZWNvcmQ8YCR7VGVtcGxhdGVLZXl9JHtzdHJpbmd9YCwgYm9vbGVhbj4sXG4gICAgKTtcbiAgfVxuXG4gIHN5bmNVSSgpIHtcbiAgICBjb25zdCB1aVBvcnQgPSBTb25hbXUuY29uZmlnLnVpPy5wb3J0ID8/IDU3MDAwO1xuXG4gICAgaWYgKCFpc1Rlc3QoKSkge1xuICAgICAgZmV0Y2goYGh0dHA6Ly8xMjcuMC4wLjE6JHt1aVBvcnR9L2FwaS9yZWxvYWRgLCB7XG4gICAgICAgIG1ldGhvZDogXCJHRVRcIixcbiAgICAgIH0pLmNhdGNoKChlKSA9PiBjb25zb2xlLmxvZyhjaGFsay5kaW0oYEZhaWxlZCB0byByZWxvYWQgU29uYW11IFVJOiAke2UubWVzc2FnZX1gKSkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDtlZjsnITtmLjtmZjsmqkg7ZSE66Gd7IucIOuplOyGjOuTnOyeheuLiOuLpC5cbiAgICovXG4gIGFzeW5jIGNyZWF0ZUVudGl0eShmb3JtOiBUZW1wbGF0ZU9wdGlvbnNbXCJlbnRpdHlcIl0pIHtcbiAgICByZXR1cm4gYXdhaXQgY3JlYXRlRW50aXR5KGZvcm0pO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VmOychO2YuO2ZmOyaqSDtlITroZ3si5wg66mU7IaM65Oc7J6F64uI64ukLlxuICAgKi9cbiAgYXN5bmMgZGVsRW50aXR5KGVudGl0eUlkOiBzdHJpbmcpOiBQcm9taXNlPHsgZGVsUGF0aHM6IHN0cmluZ1tdIH0+IHtcbiAgICByZXR1cm4gYXdhaXQgZGVsRW50aXR5KGVudGl0eUlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDtlZjsnITtmLjtmZjsmqkg7ZSE66Gd7IucIOuplOyGjOuTnOyeheuLiOuLpC5cbiAgICovXG4gIGFzeW5jIGdlbmVyYXRlVGVtcGxhdGU8VCBleHRlbmRzIFRlbXBsYXRlS2V5PihcbiAgICBrZXk6IFQsXG4gICAgdGVtcGxhdGVPcHRpb25zOiBUZW1wbGF0ZU9wdGlvbnNbVF0sXG4gICAgX2dlbmVyYXRlT3B0aW9ucz86IEdlbmVyYXRlT3B0aW9ucyxcbiAgKTogUHJvbWlzZTxBYnNvbHV0ZVBhdGhbXT4ge1xuICAgIHJldHVybiBhd2FpdCBnZW5lcmF0ZVRlbXBsYXRlKGtleSwgdGVtcGxhdGVPcHRpb25zLCBfZ2VuZXJhdGVPcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDtlZjsnITtmLjtmZjsmqkg7ZSE66Gd7IucIOuplOyGjOuTnOyeheuLiOuLpC5cbiAgICovXG4gIGFzeW5jIHJlbmRlclRlbXBsYXRlPFQgZXh0ZW5kcyBrZXlvZiBUZW1wbGF0ZU9wdGlvbnM+KFxuICAgIGtleTogVCxcbiAgICB0ZW1wbGF0ZU9wdGlvbnM6IFRlbXBsYXRlT3B0aW9uc1tUXSxcbiAgKTogUHJvbWlzZTxQYXRoQW5kQ29kZVtdPiB7XG4gICAgcmV0dXJuIGF3YWl0IHJlbmRlclRlbXBsYXRlKGtleSwgdGVtcGxhdGVPcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDtlZjsnITtmLjtmZjsmqkg7ZSE66Gd7IucIOuplOyGjOuTnOyeheuLiOuLpC5cbiAgICovXG4gIGFzeW5jIHJlbmV3Q2hlY2tzdW1zKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBhd2FpdCByZW5ld0NoZWNrc3VtcygpO1xuICB9XG59XG4iXSwibmFtZXMiOlsiaG90IiwiYXNzZXJ0IiwiY2hhbGsiLCJta2RpciIsInJlYWRGaWxlIiwid3JpdGVGaWxlIiwibWluaW1hdGNoIiwicGF0aCIsImRpcm5hbWUiLCJncm91cCIsInVuaXF1ZSIsInJlZ2lzdGVyZWRBcGlzIiwiU29uYW11IiwiRW50aXR5TWFuYWdlciIsIk5haXRlIiwiVGVtcGxhdGVNYW5hZ2VyIiwiVGVtcGxhdGVLZXkiLCJtYXBBc3luYyIsInJlZHVjZUFzeW5jIiwiY2VudGVyVGV4dCIsImlzVGVzdCIsImV4aXN0cyIsInJ1bldpdGhHcmFjZWZ1bFNodXRkb3duIiwiYXJlRmlsZXNTYW1lIiwiZmluZENoYW5nZWRGaWxlc1VzaW5nQ2hlY2tzdW1zIiwicmVuZXdDaGVja3N1bXMiLCJnZW5lcmF0ZVRlbXBsYXRlIiwicmVuZGVyVGVtcGxhdGUiLCJjcmVhdGVFbnRpdHkiLCJkZWxFbnRpdHkiLCJnZXRDaGVja3N1bVBhdHRlcm5Hcm91cEluQWJzb2x1dGVQYXRoIiwibG9hZEFwaXMiLCJsb2FkTW9kZWxzIiwibG9hZFR5cGVzIiwiU3luY2VyIiwiYXBpcyIsInR5cGVzIiwibW9kZWxzIiwiaXNTeW5jaW5nIiwic3luYyIsInRhcmdldHMiLCJjb25maWciLCJjb3B5U2hhcmVkVG9UYXJnZXRzIiwiY2hhbmdlZEZpbGVzIiwibGVuZ3RoIiwiY29uc29sZSIsImxvZyIsImJsYWNrIiwiYmdHcmVlbiIsImRvU3luY0FjdGlvbnMiLCJ3aGVuVGhpc0hhcHBlbnMiLCJ3YWl0Rm9yVXBUbyIsInN5bmNGcm9tV2F0Y2hlciIsImV2ZW50IiwiZGlmZkZpbGVQYXRoIiwiaW52YWxpZGF0ZWRQYXRocyIsImludmFsaWRhdGVGaWxlIiwiYm9sZCIsImludmFsaWRhdGVkUGF0aCIsInJlbW92ZWRBcGlzIiwicmVtb3ZlSW52YWxpZGF0ZWRSZWdpc3RlcmVkQXBpcyIsImJsdWUiLCJyZWxhdGl2ZSIsImFwaVJvb3RQYXRoIiwiZ3JheSIsImlzSW5DaGVja1BhdHRlcm5Hcm91cCIsIk9iamVjdCIsInZhbHVlcyIsInNvbWUiLCJwYXR0ZXJuIiwiYXV0b2xvYWRUeXBlcyIsImF1dG9sb2FkTW9kZWxzIiwiYXV0b2xvYWRBcGlzIiwic3luY1VJIiwiZW5kc1dpdGgiLCJlbnRpdHlJZCIsImdldEVudGl0eUlkRnJvbVBhdGgiLCJ0b1JlbW92ZSIsImZpbHRlciIsImFwaSIsIm1vZGVsTmFtZSIsInNwbGljZSIsImluZGV4T2YiLCJ0YXJnZXQiLCJzcmNQYXRoIiwiam9pbiIsInJlcGxhY2UiLCJhcHBSb290UGF0aCIsIkVycm9yIiwiZGVzdFBhdGgiLCJyZWN1cnNpdmUiLCJ3YXJuIiwiZGlmZkZpbGVQYXRocyIsImRpZmZHcm91cHMiLCJjYWxjdWxhdGVEaWZmR3JvdXBzIiwiZGlmZlR5cGVzIiwia2V5cyIsImluY2x1ZGVzIiwiaGFuZGxlRW50aXR5Q2hhbmdlIiwiaGFuZGxlVHlwZXNPckZ1bmN0aW9uc09yR2VuZXJhdGVkQ2hhbmdlIiwiaGFuZGxlTW9kZWxPckZyYW1lQ2hhbmdlIiwiYWN0aW9uU3luY0NvbmZpZyIsImRpZmZGaWxlcyIsInIiLCJtYXRjaGVkIiwibWF0Y2giLCJ0IiwicmVsb2FkIiwiZW50aXR5IiwiZ2V0IiwidHlwZUZpbGVQYXRoIiwibmFtZXMiLCJmcyIsInBhcmVudElkIiwidW5kZWZpbmVkIiwiYWN0aW9uR2VuZXJhdGVTY2hlbWFzIiwiZ2VuZXJhdGVkIiwicHVzaCIsInRzUGF0aHMiLCJmdW5jdGlvbnMiLCJhY3Rpb25TeW5jRmlsZXNUb1RhcmdldHMiLCJtZXJnZWRHcm91cCIsIm1vZGVsIiwiZnJhbWUiLCJwYXJhbXMiLCJtYXAiLCJtb2RlbFBhdGgiLCJuYW1lc1JlY29yZCIsImdldE5hbWVzRnJvbUlkIiwiZnJhbWVOYW1lIiwiYWN0aW9uR2VuZXJhdGVTZXJ2aWNlcyIsImFjdGlvbkdlbmVyYXRlSHR0cHMiLCJob3N0IiwicG9ydCIsInNlcnZlciIsImxpc3RlbiIsImNvbnRlbnQiLCJQcm9taXNlIiwiYWxsIiwib3ZlcndyaXRlIiwiZmxhdCIsInBhcmFtc0FycmF5IiwicmVzIiwiZGlyIiwiYXBpRGlyIiwicmVhbFNyYyIsImRzdCIsImNvcHlGaWxlV2l0aFJlcGxhY2VDb3JlVG9TaGFyZWQiLCJmcm9tUGF0aCIsInRvUGF0aCIsIm9sZEZpbGVDb250ZW50IiwidG9TdHJpbmciLCJuZXdGaWxlQ29udGVudCIsIm5mYyIsImNoZWNrRXhpc3RzR2VuQ29kZSIsInRlbXBsYXRlS2V5IiwiZW51bUlkIiwiZ2VuUGF0aCIsImdldFRhcmdldEFuZFBhdGgiLCJzdWJQYXRoIiwiZnVsbFBhdGgiLCJpc0V4aXN0cyIsImNoZWNrRXhpc3RzIiwiZW51bXMiLCJvcHRpb25zIiwiZW51bXNLZXlzIiwibmFtZSIsImNvbnN0YW50IiwicmVzdWx0Iiwia2V5IiwidHBsIiwic3RhcnRzV2l0aCIsImNvbXBvbmVudElkIiwicCIsInVpUG9ydCIsInVpIiwiZmV0Y2giLCJtZXRob2QiLCJjYXRjaCIsImUiLCJkaW0iLCJtZXNzYWdlIiwiZm9ybSIsInRlbXBsYXRlT3B0aW9ucyIsIl9nZW5lcmF0ZU9wdGlvbnMiXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLEdBQUcsUUFBUSx1QkFBdUI7QUFDM0MsT0FBT0MsWUFBWSxTQUFTO0FBQzVCLE9BQU9DLFdBQVcsUUFBUTtBQUMxQixTQUFTQyxLQUFLLEVBQUVDLFFBQVEsRUFBRUMsU0FBUyxRQUFRLG1CQUFjO0FBQ3pELFNBQVNDLFNBQVMsUUFBUSxZQUFZO0FBQ3RDLE9BQU9DLFFBQVFDLE9BQU8sUUFBUSxPQUFPO0FBQ3JDLFNBQVNDLEtBQUssRUFBRUMsTUFBTSxRQUFRLFVBQVU7QUFFeEMsU0FBU0MsY0FBYyxRQUFRLHVCQUFvQjtBQUNuRCxTQUFTQyxNQUFNLFFBQVEsbUJBQWdCO0FBQ3ZDLFNBQVNDLGFBQWEsUUFBZ0MsOEJBQTJCO0FBQ2pGLFNBQVNDLEtBQUssUUFBUSxvQkFBaUI7QUFDdkMsU0FB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