sonamu 0.8.26 → 0.9.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 (684) hide show
  1. package/bin/cli.js +60 -13
  2. package/dist/_virtual/rolldown_runtime.js +39 -0
  3. package/dist/ai/agents/agent.d.ts +3 -3
  4. package/dist/ai/agents/agent.d.ts.map +1 -1
  5. package/dist/ai/agents/agent.js +76 -73
  6. package/dist/ai/agents/index.js +3 -3
  7. package/dist/ai/agents/types.d.ts +3 -3
  8. package/dist/ai/agents/types.d.ts.map +1 -1
  9. package/dist/ai/agents/types.js +1 -3
  10. package/dist/ai/index.js +3 -2
  11. package/dist/ai/providers/rtzr/api.js +25 -25
  12. package/dist/ai/providers/rtzr/error.js +25 -26
  13. package/dist/ai/providers/rtzr/index.js +5 -5
  14. package/dist/ai/providers/rtzr/model.d.ts +1 -1
  15. package/dist/ai/providers/rtzr/model.d.ts.map +1 -1
  16. package/dist/ai/providers/rtzr/model.js +117 -133
  17. package/dist/ai/providers/rtzr/options.d.ts.map +1 -1
  18. package/dist/ai/providers/rtzr/options.js +35 -41
  19. package/dist/ai/providers/rtzr/provider.d.ts +1 -1
  20. package/dist/ai/providers/rtzr/provider.d.ts.map +1 -1
  21. package/dist/ai/providers/rtzr/provider.js +53 -51
  22. package/dist/ai/providers/rtzr/utils.d.ts.map +1 -1
  23. package/dist/ai/providers/rtzr/utils.js +84 -84
  24. package/dist/api/base-frame.d.ts +2 -2
  25. package/dist/api/base-frame.d.ts.map +1 -1
  26. package/dist/api/base-frame.js +29 -19
  27. package/dist/api/caster.d.ts +1 -1
  28. package/dist/api/caster.d.ts.map +1 -1
  29. package/dist/api/caster.js +51 -61
  30. package/dist/api/code-converters.d.ts +4 -3
  31. package/dist/api/code-converters.d.ts.map +1 -1
  32. package/dist/api/code-converters.js +226 -249
  33. package/dist/api/config.d.ts +17 -17
  34. package/dist/api/config.d.ts.map +1 -1
  35. package/dist/api/config.js +37 -30
  36. package/dist/api/context.d.ts +10 -10
  37. package/dist/api/context.d.ts.map +1 -1
  38. package/dist/api/context.js +8 -2
  39. package/dist/api/decorators.d.ts +8 -8
  40. package/dist/api/decorators.d.ts.map +1 -1
  41. package/dist/api/decorators.js +245 -268
  42. package/dist/api/index.js +39 -7
  43. package/dist/api/secret.js +22 -15
  44. package/dist/api/sonamu.d.ts +15 -15
  45. package/dist/api/sonamu.d.ts.map +1 -1
  46. package/dist/api/sonamu.js +1012 -1131
  47. package/dist/api/validator.js +88 -79
  48. package/dist/auth/auth-generator.d.ts.map +1 -1
  49. package/dist/auth/auth-generator.js +203 -200
  50. package/dist/auth/better-auth-entities.d.ts +2 -2
  51. package/dist/auth/better-auth-entities.d.ts.map +1 -1
  52. package/dist/auth/better-auth-entities.js +369 -429
  53. package/dist/auth/index.js +21 -6
  54. package/dist/auth/knex-adapter.d.ts +2 -2
  55. package/dist/auth/knex-adapter.d.ts.map +1 -1
  56. package/dist/auth/knex-adapter.js +153 -157
  57. package/dist/auth/plugins/entity-definitions/admin.d.ts +1 -1
  58. package/dist/auth/plugins/entity-definitions/admin.d.ts.map +1 -1
  59. package/dist/auth/plugins/entity-definitions/admin.js +58 -56
  60. package/dist/auth/plugins/entity-definitions/anonymous.d.ts +1 -1
  61. package/dist/auth/plugins/entity-definitions/anonymous.d.ts.map +1 -1
  62. package/dist/auth/plugins/entity-definitions/anonymous.js +20 -20
  63. package/dist/auth/plugins/entity-definitions/api-key.d.ts +1 -1
  64. package/dist/auth/plugins/entity-definitions/api-key.d.ts.map +1 -1
  65. package/dist/auth/plugins/entity-definitions/api-key.js +185 -196
  66. package/dist/auth/plugins/entity-definitions/index.d.ts +1 -1
  67. package/dist/auth/plugins/entity-definitions/index.d.ts.map +1 -1
  68. package/dist/auth/plugins/entity-definitions/index.js +26 -29
  69. package/dist/auth/plugins/entity-definitions/jwt.d.ts +1 -1
  70. package/dist/auth/plugins/entity-definitions/jwt.d.ts.map +1 -1
  71. package/dist/auth/plugins/entity-definitions/jwt.js +62 -64
  72. package/dist/auth/plugins/entity-definitions/organization.d.ts +1 -1
  73. package/dist/auth/plugins/entity-definitions/organization.d.ts.map +1 -1
  74. package/dist/auth/plugins/entity-definitions/organization.js +362 -421
  75. package/dist/auth/plugins/entity-definitions/passkey.d.ts +1 -1
  76. package/dist/auth/plugins/entity-definitions/passkey.d.ts.map +1 -1
  77. package/dist/auth/plugins/entity-definitions/passkey.js +115 -126
  78. package/dist/auth/plugins/entity-definitions/phone-number.d.ts +1 -1
  79. package/dist/auth/plugins/entity-definitions/phone-number.d.ts.map +1 -1
  80. package/dist/auth/plugins/entity-definitions/phone-number.js +31 -40
  81. package/dist/auth/plugins/entity-definitions/sso.d.ts +1 -1
  82. package/dist/auth/plugins/entity-definitions/sso.d.ts.map +1 -1
  83. package/dist/auth/plugins/entity-definitions/sso.js +94 -107
  84. package/dist/auth/plugins/entity-definitions/two-factor.d.ts +1 -1
  85. package/dist/auth/plugins/entity-definitions/two-factor.d.ts.map +1 -1
  86. package/dist/auth/plugins/entity-definitions/two-factor.js +78 -92
  87. package/dist/auth/plugins/entity-definitions/types.d.ts +1 -1
  88. package/dist/auth/plugins/entity-definitions/types.d.ts.map +1 -1
  89. package/dist/auth/plugins/entity-definitions/types.js +1 -10
  90. package/dist/auth/plugins/entity-definitions/username.d.ts +1 -1
  91. package/dist/auth/plugins/entity-definitions/username.d.ts.map +1 -1
  92. package/dist/auth/plugins/entity-definitions/username.js +31 -40
  93. package/dist/auth/plugins/index.js +12 -3
  94. package/dist/auth/plugins/wrappers/admin.d.ts +2 -2
  95. package/dist/auth/plugins/wrappers/admin.d.ts.map +1 -1
  96. package/dist/auth/plugins/wrappers/admin.js +28 -29
  97. package/dist/auth/plugins/wrappers/anonymous.d.ts +2 -1
  98. package/dist/auth/plugins/wrappers/anonymous.d.ts.map +1 -1
  99. package/dist/auth/plugins/wrappers/anonymous.js +23 -22
  100. package/dist/auth/plugins/wrappers/api-key.d.ts +2 -1
  101. package/dist/auth/plugins/wrappers/api-key.d.ts.map +1 -1
  102. package/dist/auth/plugins/wrappers/api-key.js +39 -34
  103. package/dist/auth/plugins/wrappers/index.js +11 -11
  104. package/dist/auth/plugins/wrappers/jwt.d.ts +2 -1
  105. package/dist/auth/plugins/wrappers/jwt.d.ts.map +1 -1
  106. package/dist/auth/plugins/wrappers/jwt.js +31 -26
  107. package/dist/auth/plugins/wrappers/organization.d.ts +2 -1
  108. package/dist/auth/plugins/wrappers/organization.d.ts.map +1 -1
  109. package/dist/auth/plugins/wrappers/organization.js +65 -62
  110. package/dist/auth/plugins/wrappers/passkey.d.ts +2 -1
  111. package/dist/auth/plugins/wrappers/passkey.d.ts.map +1 -1
  112. package/dist/auth/plugins/wrappers/passkey.js +33 -28
  113. package/dist/auth/plugins/wrappers/phone-number.d.ts.map +1 -1
  114. package/dist/auth/plugins/wrappers/phone-number.js +26 -23
  115. package/dist/auth/plugins/wrappers/sso.d.ts.map +1 -1
  116. package/dist/auth/plugins/wrappers/sso.js +37 -31
  117. package/dist/auth/plugins/wrappers/two-factor.d.ts.map +1 -1
  118. package/dist/auth/plugins/wrappers/two-factor.js +31 -28
  119. package/dist/auth/plugins/wrappers/username.d.ts.map +1 -1
  120. package/dist/auth/plugins/wrappers/username.js +23 -23
  121. package/dist/bin/build-config.js +31 -31
  122. package/dist/bin/cli.js +1063 -1204
  123. package/dist/bin/fixture.d.ts.map +1 -1
  124. package/dist/bin/fixture.js +266 -259
  125. package/dist/bin/hmr-hook-register.d.ts.map +1 -1
  126. package/dist/bin/hmr-hook-register.js +19 -18
  127. package/dist/bin/test-command.d.ts.map +1 -1
  128. package/dist/bin/test-command.js +180 -177
  129. package/dist/bin/ts-loader-register.js +13 -6
  130. package/dist/bin/ts-loader-registration.d.ts.map +1 -1
  131. package/dist/bin/ts-loader-registration.js +28 -38
  132. package/dist/cache/cache-manager.d.ts +1 -1
  133. package/dist/cache/cache-manager.d.ts.map +1 -1
  134. package/dist/cache/cache-manager.js +20 -15
  135. package/dist/cache/decorator.d.ts +1 -1
  136. package/dist/cache/decorator.d.ts.map +1 -1
  137. package/dist/cache/decorator.js +84 -76
  138. package/dist/cache/drivers.js +21 -34
  139. package/dist/cache/index.js +10 -7
  140. package/dist/cache/types.d.ts +2 -2
  141. package/dist/cache/types.d.ts.map +1 -1
  142. package/dist/cache/types.js +1 -6
  143. package/dist/cache-control/cache-control.d.ts +2 -2
  144. package/dist/cache-control/cache-control.d.ts.map +1 -1
  145. package/dist/cache-control/cache-control.js +106 -122
  146. package/dist/cache-control/types.d.ts +2 -2
  147. package/dist/cache-control/types.d.ts.map +1 -1
  148. package/dist/cache-control/types.js +1 -19
  149. package/dist/compress/compress.d.ts +1 -1
  150. package/dist/compress/compress.d.ts.map +1 -1
  151. package/dist/compress/compress.js +58 -56
  152. package/dist/compress/index.js +7 -2
  153. package/dist/compress/types.js +1 -11
  154. package/dist/cone/cone-generator.d.ts +1 -1
  155. package/dist/cone/cone-generator.d.ts.map +1 -1
  156. package/dist/cone/cone-generator.js +216 -219
  157. package/dist/database/_batch_update.d.ts +1 -1
  158. package/dist/database/_batch_update.d.ts.map +1 -1
  159. package/dist/database/_batch_update.js +107 -102
  160. package/dist/database/base-model.d.ts +8 -9
  161. package/dist/database/base-model.d.ts.map +1 -1
  162. package/dist/database/base-model.js +371 -392
  163. package/dist/database/base-model.types.d.ts +5 -5
  164. package/dist/database/base-model.types.d.ts.map +1 -1
  165. package/dist/database/base-model.types.js +1 -20
  166. package/dist/database/db.d.ts +5 -2
  167. package/dist/database/db.d.ts.map +1 -1
  168. package/dist/database/db.js +185 -171
  169. package/dist/database/knex.d.ts +1 -1
  170. package/dist/database/knex.d.ts.map +1 -1
  171. package/dist/database/knex.js +48 -42
  172. package/dist/database/puri-subset.types.d.ts +6 -7
  173. package/dist/database/puri-subset.types.d.ts.map +1 -1
  174. package/dist/database/puri-subset.types.js +1 -16
  175. package/dist/database/puri-wrapper.d.ts +6 -6
  176. package/dist/database/puri-wrapper.d.ts.map +1 -1
  177. package/dist/database/puri-wrapper.js +99 -101
  178. package/dist/database/puri.d.ts +4 -5
  179. package/dist/database/puri.d.ts.map +1 -1
  180. package/dist/database/puri.js +1021 -1227
  181. package/dist/database/puri.types.d.ts +6 -6
  182. package/dist/database/puri.types.d.ts.map +1 -1
  183. package/dist/database/puri.types.js +15 -6
  184. package/dist/database/transaction-context.d.ts +2 -2
  185. package/dist/database/transaction-context.d.ts.map +1 -1
  186. package/dist/database/transaction-context.js +22 -13
  187. package/dist/database/upsert-builder.d.ts +3 -3
  188. package/dist/database/upsert-builder.d.ts.map +1 -1
  189. package/dist/database/upsert-builder.js +405 -465
  190. package/dist/dict/en.js +72 -74
  191. package/dist/dict/index.js +13 -13
  192. package/dist/dict/ko.js +72 -74
  193. package/dist/dict/rc-keys.js +150 -168
  194. package/dist/dict/sd.d.ts +3 -1
  195. package/dist/dict/sd.d.ts.map +1 -1
  196. package/dist/dict/sd.js +54 -40
  197. package/dist/dict/sonamu-dictionary.d.ts +1 -1
  198. package/dist/dict/sonamu-dictionary.d.ts.map +1 -1
  199. package/dist/dict/sonamu-dictionary.js +887 -955
  200. package/dist/dict/types.js +1 -7
  201. package/dist/dict/utils.js +26 -24
  202. package/dist/entity/entity-manager.d.ts +9 -9
  203. package/dist/entity/entity-manager.d.ts.map +1 -1
  204. package/dist/entity/entity-manager.js +226 -223
  205. package/dist/entity/entity-template-cone.d.ts +1 -1
  206. package/dist/entity/entity-template-cone.d.ts.map +1 -1
  207. package/dist/entity/entity-template-cone.js +152 -151
  208. package/dist/entity/entity.d.ts.map +1 -1
  209. package/dist/entity/entity.js +952 -1089
  210. package/dist/exceptions/error-handler.d.ts +1 -1
  211. package/dist/exceptions/error-handler.d.ts.map +1 -1
  212. package/dist/exceptions/error-handler.js +32 -27
  213. package/dist/exceptions/so-exceptions.d.ts +1 -1
  214. package/dist/exceptions/so-exceptions.d.ts.map +1 -1
  215. package/dist/exceptions/so-exceptions.js +61 -68
  216. package/dist/filter/index.js +9 -3
  217. package/dist/filter/types.js +92 -88
  218. package/dist/filter/utils.d.ts +1 -1
  219. package/dist/filter/utils.d.ts.map +1 -1
  220. package/dist/filter/utils.js +147 -161
  221. package/dist/index.js +87 -40
  222. package/dist/logger/category.d.ts.map +1 -1
  223. package/dist/logger/category.js +30 -29
  224. package/dist/logger/configure.d.ts.map +1 -1
  225. package/dist/logger/configure.js +83 -107
  226. package/dist/migration/code-generation.d.ts +2 -2
  227. package/dist/migration/code-generation.d.ts.map +1 -1
  228. package/dist/migration/code-generation.js +1385 -1578
  229. package/dist/migration/migration-set.d.ts +1 -1
  230. package/dist/migration/migration-set.d.ts.map +1 -1
  231. package/dist/migration/migration-set.js +177 -227
  232. package/dist/migration/migrator.d.ts +4 -3
  233. package/dist/migration/migrator.d.ts.map +1 -1
  234. package/dist/migration/migrator.js +340 -345
  235. package/dist/migration/postgresql-schema-reader.d.ts +2 -2
  236. package/dist/migration/postgresql-schema-reader.d.ts.map +1 -1
  237. package/dist/migration/postgresql-schema-reader.js +506 -564
  238. package/dist/migration/slack-confirm.d.ts +2 -2
  239. package/dist/migration/slack-confirm.d.ts.map +1 -1
  240. package/dist/migration/slack-confirm.js +205 -193
  241. package/dist/migration/types.d.ts +2 -2
  242. package/dist/migration/types.d.ts.map +1 -1
  243. package/dist/migration/types.js +1 -3
  244. package/dist/naite/messaging-types.d.ts +1 -0
  245. package/dist/naite/messaging-types.d.ts.map +1 -1
  246. package/dist/naite/messaging-types.js +1 -7
  247. package/dist/naite/naite-reporter.d.ts +2 -2
  248. package/dist/naite/naite-reporter.d.ts.map +1 -1
  249. package/dist/naite/naite-reporter.js +127 -120
  250. package/dist/naite/naite.d.ts +3 -2
  251. package/dist/naite/naite.d.ts.map +1 -1
  252. package/dist/naite/naite.js +266 -300
  253. package/dist/ssr/index.d.ts +2 -2
  254. package/dist/ssr/index.d.ts.map +1 -1
  255. package/dist/ssr/index.js +13 -3
  256. package/dist/ssr/registry.d.ts +1 -1
  257. package/dist/ssr/registry.d.ts.map +1 -1
  258. package/dist/ssr/registry.js +45 -37
  259. package/dist/ssr/renderer.d.ts +4 -4
  260. package/dist/ssr/renderer.d.ts.map +1 -1
  261. package/dist/ssr/renderer.js +84 -91
  262. package/dist/ssr/types.d.ts +2 -2
  263. package/dist/ssr/types.d.ts.map +1 -1
  264. package/dist/ssr/types.js +1 -3
  265. package/dist/storage/base-file.js +54 -41
  266. package/dist/storage/buffered-file.d.ts +2 -2
  267. package/dist/storage/buffered-file.d.ts.map +1 -1
  268. package/dist/storage/buffered-file.js +51 -44
  269. package/dist/storage/drivers.d.ts +2 -2
  270. package/dist/storage/drivers.d.ts.map +1 -1
  271. package/dist/storage/drivers.js +12 -7
  272. package/dist/storage/index.js +14 -7
  273. package/dist/storage/s3-driver.d.ts +2 -2
  274. package/dist/storage/s3-driver.d.ts.map +1 -1
  275. package/dist/storage/s3-driver.js +52 -48
  276. package/dist/storage/storage-manager.d.ts +2 -2
  277. package/dist/storage/storage-manager.d.ts.map +1 -1
  278. package/dist/storage/storage-manager.js +33 -25
  279. package/dist/storage/types.d.ts +2 -2
  280. package/dist/storage/types.d.ts.map +1 -1
  281. package/dist/storage/types.js +1 -5
  282. package/dist/storage/uploaded-file.d.ts +1 -1
  283. package/dist/storage/uploaded-file.d.ts.map +1 -1
  284. package/dist/storage/uploaded-file.js +45 -35
  285. package/dist/stream/index.js +7 -2
  286. package/dist/stream/sse.d.ts +2 -2
  287. package/dist/stream/sse.d.ts.map +1 -1
  288. package/dist/stream/sse.js +72 -67
  289. package/dist/syncer/api-parser.d.ts +1 -1
  290. package/dist/syncer/api-parser.d.ts.map +1 -1
  291. package/dist/syncer/api-parser.js +224 -245
  292. package/dist/syncer/checksum.d.ts +1 -1
  293. package/dist/syncer/checksum.d.ts.map +1 -1
  294. package/dist/syncer/checksum.js +86 -72
  295. package/dist/syncer/code-generator.d.ts +2 -2
  296. package/dist/syncer/code-generator.d.ts.map +1 -1
  297. package/dist/syncer/code-generator.js +154 -160
  298. package/dist/syncer/entity-operations.d.ts +1 -1
  299. package/dist/syncer/entity-operations.d.ts.map +1 -1
  300. package/dist/syncer/entity-operations.js +63 -54
  301. package/dist/syncer/file-patterns.d.ts +1 -1
  302. package/dist/syncer/file-patterns.d.ts.map +1 -1
  303. package/dist/syncer/file-patterns.js +38 -38
  304. package/dist/syncer/index.js +19 -8
  305. package/dist/syncer/module-loader.d.ts +5 -5
  306. package/dist/syncer/module-loader.d.ts.map +1 -1
  307. package/dist/syncer/module-loader.js +83 -78
  308. package/dist/syncer/syncer-actions.d.ts +2 -2
  309. package/dist/syncer/syncer-actions.d.ts.map +1 -1
  310. package/dist/syncer/syncer-actions.js +76 -91
  311. package/dist/syncer/syncer.d.ts +7 -6
  312. package/dist/syncer/syncer.d.ts.map +1 -1
  313. package/dist/syncer/syncer.js +426 -492
  314. package/dist/tasks/decorator.d.ts +3 -3
  315. package/dist/tasks/decorator.d.ts.map +1 -1
  316. package/dist/tasks/decorator.js +32 -28
  317. package/dist/tasks/step-wrapper.d.ts +1 -1
  318. package/dist/tasks/step-wrapper.d.ts.map +1 -1
  319. package/dist/tasks/step-wrapper.js +42 -41
  320. package/dist/tasks/workflow-manager.d.ts +2 -2
  321. package/dist/tasks/workflow-manager.d.ts.map +1 -1
  322. package/dist/tasks/workflow-manager.js +192 -221
  323. package/dist/template/entity-converter.d.ts +1 -1
  324. package/dist/template/entity-converter.d.ts.map +1 -1
  325. package/dist/template/entity-converter.js +103 -103
  326. package/dist/template/helpers.d.ts.map +1 -1
  327. package/dist/template/helpers.js +163 -163
  328. package/dist/template/implementations/entity.template.d.ts +1 -1
  329. package/dist/template/implementations/entity.template.d.ts.map +1 -1
  330. package/dist/template/implementations/entity.template.js +76 -85
  331. package/dist/template/implementations/entry-server.template.d.ts +1 -1
  332. package/dist/template/implementations/entry-server.template.d.ts.map +1 -1
  333. package/dist/template/implementations/entry-server.template.js +32 -27
  334. package/dist/template/implementations/generated.template.d.ts +1 -1
  335. package/dist/template/implementations/generated.template.d.ts.map +1 -1
  336. package/dist/template/implementations/generated.template.js +254 -275
  337. package/dist/template/implementations/generated_http.template.d.ts +2 -2
  338. package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
  339. package/dist/template/implementations/generated_http.template.js +114 -133
  340. package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
  341. package/dist/template/implementations/generated_sso.template.js +249 -275
  342. package/dist/template/implementations/init_types.template.d.ts +1 -1
  343. package/dist/template/implementations/init_types.template.d.ts.map +1 -1
  344. package/dist/template/implementations/init_types.template.js +40 -34
  345. package/dist/template/implementations/model.template.d.ts +1 -1
  346. package/dist/template/implementations/model.template.d.ts.map +1 -1
  347. package/dist/template/implementations/model.template.js +56 -53
  348. package/dist/template/implementations/model_test.template.d.ts +1 -1
  349. package/dist/template/implementations/model_test.template.d.ts.map +1 -1
  350. package/dist/template/implementations/model_test.template.js +32 -24
  351. package/dist/template/implementations/queries.template.d.ts +1 -1
  352. package/dist/template/implementations/queries.template.d.ts.map +1 -1
  353. package/dist/template/implementations/queries.template.js +84 -89
  354. package/dist/template/implementations/sd.template.d.ts +1 -1
  355. package/dist/template/implementations/sd.template.d.ts.map +1 -1
  356. package/dist/template/implementations/sd.template.js +137 -144
  357. package/dist/template/implementations/services.template.d.ts +1 -1
  358. package/dist/template/implementations/services.template.d.ts.map +1 -1
  359. package/dist/template/implementations/services.template.js +164 -189
  360. package/dist/template/implementations/view_form.template.d.ts +1 -1
  361. package/dist/template/implementations/view_form.template.d.ts.map +1 -1
  362. package/dist/template/implementations/view_form.template.js +258 -285
  363. package/dist/template/implementations/view_id_all_select.template.d.ts +1 -1
  364. package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -1
  365. package/dist/template/implementations/view_id_all_select.template.js +31 -25
  366. package/dist/template/implementations/view_list.template.d.ts +1 -1
  367. package/dist/template/implementations/view_list.template.d.ts.map +1 -1
  368. package/dist/template/implementations/view_list.template.js +304 -355
  369. package/dist/template/implementations/view_search_input.template.d.ts +1 -1
  370. package/dist/template/implementations/view_search_input.template.d.ts.map +1 -1
  371. package/dist/template/implementations/view_search_input.template.js +31 -27
  372. package/dist/template/index.js +21 -7
  373. package/dist/template/template-manager.d.ts +1 -1
  374. package/dist/template/template-manager.d.ts.map +1 -1
  375. package/dist/template/template-manager.js +132 -123
  376. package/dist/template/template-types.js +8 -6
  377. package/dist/template/template.d.ts +2 -2
  378. package/dist/template/template.d.ts.map +1 -1
  379. package/dist/template/template.js +73 -68
  380. package/dist/template/zod-converter.d.ts.map +1 -1
  381. package/dist/template/zod-converter.js +603 -657
  382. package/dist/testing/_relation-graph.d.ts +1 -1
  383. package/dist/testing/_relation-graph.d.ts.map +1 -1
  384. package/dist/testing/_relation-graph.js +93 -88
  385. package/dist/testing/bootstrap.d.ts +22 -13
  386. package/dist/testing/bootstrap.d.ts.map +1 -1
  387. package/dist/testing/bootstrap.js +114 -114
  388. package/dist/testing/data-explorer.d.ts +3 -3
  389. package/dist/testing/data-explorer.d.ts.map +1 -1
  390. package/dist/testing/data-explorer.js +237 -265
  391. package/dist/testing/dev-test-routes.d.ts +2 -2
  392. package/dist/testing/dev-test-routes.d.ts.map +1 -1
  393. package/dist/testing/dev-test-routes.js +258 -249
  394. package/dist/testing/dev-vitest-manager.d.ts +1 -1
  395. package/dist/testing/dev-vitest-manager.d.ts.map +1 -1
  396. package/dist/testing/dev-vitest-manager.js +514 -539
  397. package/dist/testing/faker-mappings.js +422 -420
  398. package/dist/testing/fixture-generator.d.ts +3 -3
  399. package/dist/testing/fixture-generator.d.ts.map +1 -1
  400. package/dist/testing/fixture-generator.js +1216 -1346
  401. package/dist/testing/fixture-loader.js +26 -25
  402. package/dist/testing/fixture-manager.d.ts +3 -3
  403. package/dist/testing/fixture-manager.d.ts.map +1 -1
  404. package/dist/testing/fixture-manager.js +706 -776
  405. package/dist/testing/global-setup.js +53 -49
  406. package/dist/testing/index.js +19 -11
  407. package/dist/testing/naite-vitest-reporter.js +18 -13
  408. package/dist/testing/parallel-db-manager.d.ts +1 -1
  409. package/dist/testing/parallel-db-manager.d.ts.map +1 -1
  410. package/dist/testing/parallel-db-manager.js +63 -78
  411. package/dist/testing/vitest-helpers.d.ts +1 -1
  412. package/dist/testing/vitest-helpers.d.ts.map +1 -1
  413. package/dist/testing/vitest-helpers.js +37 -33
  414. package/dist/types/types.d.ts +28 -28
  415. package/dist/types/types.d.ts.map +1 -1
  416. package/dist/types/types.js +764 -890
  417. package/dist/ui/ai-api.d.ts +1 -1
  418. package/dist/ui/ai-api.d.ts.map +1 -1
  419. package/dist/ui/ai-api.js +52 -42
  420. package/dist/ui/ai-client.d.ts +1 -2
  421. package/dist/ui/ai-client.d.ts.map +1 -1
  422. package/dist/ui/ai-client.js +353 -388
  423. package/dist/ui/api.d.ts +1 -1
  424. package/dist/ui/api.d.ts.map +1 -1
  425. package/dist/ui/api.js +903 -1145
  426. package/dist/ui/cdd-service.d.ts +1 -1
  427. package/dist/ui/cdd-service.d.ts.map +1 -1
  428. package/dist/ui/cdd-service.js +406 -407
  429. package/dist/ui/cdd-types.js +1 -3
  430. package/dist/ui-web/assets/index-C-Zz-wYg.css +1 -0
  431. package/dist/ui-web/assets/index-DejDON8K.js +238 -0
  432. package/dist/ui-web/index.html +3 -3
  433. package/dist/utils/async-utils.js +57 -45
  434. package/dist/utils/console-util.d.ts.map +1 -1
  435. package/dist/utils/console-util.js +104 -87
  436. package/dist/utils/controller.js +26 -19
  437. package/dist/utils/esm-utils.js +49 -38
  438. package/dist/utils/formatter.d.ts +1 -2
  439. package/dist/utils/formatter.d.ts.map +1 -1
  440. package/dist/utils/formatter.js +89 -115
  441. package/dist/utils/fs-utils.d.ts.map +1 -1
  442. package/dist/utils/fs-utils.js +68 -65
  443. package/dist/utils/lodash-able.js +11 -4
  444. package/dist/utils/model.d.ts +1 -1
  445. package/dist/utils/model.d.ts.map +1 -1
  446. package/dist/utils/model.js +21 -19
  447. package/dist/utils/object-utils.js +148 -186
  448. package/dist/utils/path-utils.js +67 -57
  449. package/dist/utils/process-utils.d.ts.map +1 -1
  450. package/dist/utils/process-utils.js +37 -31
  451. package/dist/utils/sql-parser.d.ts +1 -1
  452. package/dist/utils/sql-parser.d.ts.map +1 -1
  453. package/dist/utils/sql-parser.js +40 -40
  454. package/dist/utils/type-utils.js +44 -43
  455. package/dist/utils/utils.d.ts +2 -3
  456. package/dist/utils/utils.d.ts.map +1 -1
  457. package/dist/utils/utils.js +81 -93
  458. package/dist/utils/zod-error.d.ts +1 -1
  459. package/dist/utils/zod-error.d.ts.map +1 -1
  460. package/dist/utils/zod-error.js +24 -17
  461. package/dist/vector/chunking.d.ts +1 -1
  462. package/dist/vector/chunking.d.ts.map +1 -1
  463. package/dist/vector/chunking.js +100 -94
  464. package/dist/vector/config.d.ts +1 -1
  465. package/dist/vector/config.d.ts.map +1 -1
  466. package/dist/vector/config.js +76 -78
  467. package/dist/vector/embedding.d.ts +1 -1
  468. package/dist/vector/embedding.d.ts.map +1 -1
  469. package/dist/vector/embedding.js +128 -125
  470. package/dist/vector/index.js +5 -5
  471. package/dist/vector/types.js +1 -5
  472. package/package.json +31 -36
  473. package/src/ai/agents/agent.ts +12 -5
  474. package/src/ai/agents/types.ts +5 -5
  475. package/src/ai/providers/rtzr/model.ts +8 -10
  476. package/src/ai/providers/rtzr/options.ts +2 -1
  477. package/src/ai/providers/rtzr/provider.ts +5 -3
  478. package/src/ai/providers/rtzr/utils.ts +2 -7
  479. package/src/api/__tests__/config.test.ts +15 -8
  480. package/src/api/base-frame.ts +5 -3
  481. package/src/api/caster.ts +7 -6
  482. package/src/api/code-converters.ts +23 -26
  483. package/src/api/config.ts +23 -17
  484. package/src/api/context.ts +18 -11
  485. package/src/api/decorators.ts +17 -18
  486. package/src/api/sonamu.ts +44 -49
  487. package/src/auth/auth-generator.ts +4 -6
  488. package/src/auth/better-auth-entities.ts +3 -2
  489. package/src/auth/knex-adapter.ts +6 -5
  490. package/src/auth/plugins/entity-definitions/admin.ts +1 -1
  491. package/src/auth/plugins/entity-definitions/anonymous.ts +1 -1
  492. package/src/auth/plugins/entity-definitions/api-key.ts +1 -1
  493. package/src/auth/plugins/entity-definitions/index.ts +1 -1
  494. package/src/auth/plugins/entity-definitions/jwt.ts +1 -1
  495. package/src/auth/plugins/entity-definitions/organization.ts +1 -1
  496. package/src/auth/plugins/entity-definitions/passkey.ts +1 -1
  497. package/src/auth/plugins/entity-definitions/phone-number.ts +1 -1
  498. package/src/auth/plugins/entity-definitions/sso.ts +1 -1
  499. package/src/auth/plugins/entity-definitions/two-factor.ts +1 -1
  500. package/src/auth/plugins/entity-definitions/types.ts +1 -1
  501. package/src/auth/plugins/entity-definitions/username.ts +1 -1
  502. package/src/auth/plugins/wrappers/admin.ts +3 -1
  503. package/src/auth/plugins/wrappers/anonymous.ts +3 -1
  504. package/src/auth/plugins/wrappers/api-key.ts +3 -1
  505. package/src/auth/plugins/wrappers/jwt.ts +3 -1
  506. package/src/auth/plugins/wrappers/organization.ts +3 -1
  507. package/src/auth/plugins/wrappers/passkey.ts +3 -1
  508. package/src/auth/plugins/wrappers/phone-number.ts +3 -1
  509. package/src/auth/plugins/wrappers/sso.ts +2 -1
  510. package/src/auth/plugins/wrappers/two-factor.ts +3 -1
  511. package/src/auth/plugins/wrappers/username.ts +3 -1
  512. package/src/bin/__tests__/ts-loader-register.test.ts +7 -12
  513. package/src/bin/build-config.ts +3 -3
  514. package/src/bin/cli.ts +27 -25
  515. package/src/bin/fixture.ts +4 -2
  516. package/src/bin/hmr-hook-register.ts +1 -0
  517. package/src/bin/test-command.ts +4 -2
  518. package/src/bin/ts-loader-registration.ts +6 -22
  519. package/src/cache/cache-manager.ts +2 -1
  520. package/src/cache/decorator.ts +2 -2
  521. package/src/cache/types.ts +3 -3
  522. package/src/cache-control/cache-control.ts +3 -2
  523. package/src/cache-control/types.ts +2 -2
  524. package/src/compress/compress.ts +1 -1
  525. package/src/cone/cone-generator.ts +5 -3
  526. package/src/database/_batch_update.ts +1 -1
  527. package/src/database/base-model.ts +20 -14
  528. package/src/database/base-model.types.ts +12 -11
  529. package/src/database/db.ts +56 -21
  530. package/src/database/knex.ts +2 -2
  531. package/src/database/puri-subset.test-d.ts +33 -32
  532. package/src/database/puri-subset.types.ts +6 -7
  533. package/src/database/puri-wrapper.ts +29 -26
  534. package/src/database/puri.ts +36 -34
  535. package/src/database/puri.types.test-d.ts +6 -5
  536. package/src/database/puri.types.ts +9 -12
  537. package/src/database/transaction-context.ts +2 -2
  538. package/src/database/upsert-builder.ts +17 -10
  539. package/src/dict/sd.ts +17 -4
  540. package/src/dict/sonamu-dictionary.ts +23 -17
  541. package/src/entity/entity-manager.ts +9 -7
  542. package/src/entity/entity-template-cone.ts +10 -3
  543. package/src/entity/entity.ts +20 -16
  544. package/src/exceptions/error-handler.ts +2 -1
  545. package/src/exceptions/so-exceptions.ts +1 -1
  546. package/src/filter/utils.ts +3 -2
  547. package/src/logger/category.ts +1 -0
  548. package/src/logger/configure.ts +5 -5
  549. package/src/migration/__tests__/code-generation.search-text.test.ts +2 -3
  550. package/src/migration/code-generation.ts +26 -25
  551. package/src/migration/migration-set.ts +16 -18
  552. package/src/migration/migrator.ts +38 -33
  553. package/src/migration/postgresql-schema-reader.ts +12 -12
  554. package/src/migration/slack-confirm.ts +5 -4
  555. package/src/migration/types.ts +2 -2
  556. package/src/naite/messaging-types.ts +1 -1
  557. package/src/naite/naite-reporter.ts +5 -3
  558. package/src/naite/naite.ts +12 -7
  559. package/src/shared/app.shared.ts.txt +2 -2
  560. package/src/shared/web.shared.ts.txt +2 -2
  561. package/src/skills/AGENTS.md +19 -18
  562. package/src/skills/commands/sonamu-skills.md +9 -9
  563. package/src/skills/sonamu/SKILL.md +111 -104
  564. package/src/skills/sonamu/ai-agents.md +27 -26
  565. package/src/skills/sonamu/api.md +81 -69
  566. package/src/skills/sonamu/auth-migration.md +13 -27
  567. package/src/skills/sonamu/auth-plugins.md +41 -31
  568. package/src/skills/sonamu/auth.md +30 -24
  569. package/src/skills/sonamu/cdd.md +26 -17
  570. package/src/skills/sonamu/cone.md +50 -50
  571. package/src/skills/sonamu/config.md +74 -51
  572. package/src/skills/sonamu/create-sonamu.md +31 -19
  573. package/src/skills/sonamu/database.md +43 -26
  574. package/src/skills/sonamu/entity-basic.md +61 -61
  575. package/src/skills/sonamu/entity-relations.md +84 -80
  576. package/src/skills/sonamu/entity-validation-checklist.md +19 -15
  577. package/src/skills/sonamu/fixture-cli.md +52 -30
  578. package/src/skills/sonamu/framework-change.md +9 -7
  579. package/src/skills/sonamu/frontend.md +64 -82
  580. package/src/skills/sonamu/i18n.md +45 -37
  581. package/src/skills/sonamu/migration.md +54 -31
  582. package/src/skills/sonamu/model.md +98 -66
  583. package/src/skills/sonamu/naite.md +34 -32
  584. package/src/skills/sonamu/project-init.md +28 -8
  585. package/src/skills/sonamu/puri.md +82 -91
  586. package/src/skills/sonamu/scaffolding.md +44 -32
  587. package/src/skills/sonamu/skill-contribution.md +50 -45
  588. package/src/skills/sonamu/subset.md +13 -13
  589. package/src/skills/sonamu/tasks.md +73 -58
  590. package/src/skills/sonamu/testing-devrunner.md +56 -36
  591. package/src/skills/sonamu/testing.md +23 -58
  592. package/src/skills/sonamu/upsert.md +32 -31
  593. package/src/skills/sonamu/vector.md +37 -36
  594. package/src/ssr/index.ts +2 -12
  595. package/src/ssr/registry.ts +1 -1
  596. package/src/ssr/renderer.ts +7 -5
  597. package/src/ssr/types.ts +2 -2
  598. package/src/storage/buffered-file.ts +4 -2
  599. package/src/storage/drivers.ts +3 -2
  600. package/src/storage/s3-driver.ts +7 -4
  601. package/src/storage/storage-manager.ts +3 -2
  602. package/src/storage/types.ts +3 -2
  603. package/src/storage/uploaded-file.ts +1 -1
  604. package/src/stream/sse.ts +2 -2
  605. package/src/syncer/api-parser.ts +8 -5
  606. package/src/syncer/checksum.ts +9 -5
  607. package/src/syncer/code-generator.ts +16 -8
  608. package/src/syncer/entity-operations.ts +5 -3
  609. package/src/syncer/file-patterns.ts +2 -1
  610. package/src/syncer/module-loader.ts +9 -6
  611. package/src/syncer/syncer-actions.ts +5 -3
  612. package/src/syncer/syncer.ts +18 -24
  613. package/src/tasks/decorator.ts +10 -8
  614. package/src/tasks/step-wrapper.ts +1 -1
  615. package/src/tasks/workflow-manager.ts +18 -15
  616. package/src/template/__tests__/generated.template.search-text.test.ts +1 -0
  617. package/src/template/entity-converter.ts +4 -2
  618. package/src/template/generated.template.test-d.ts +2 -1
  619. package/src/template/helpers.ts +5 -2
  620. package/src/template/implementations/entity.template.ts +9 -8
  621. package/src/template/implementations/entry-server.template.ts +1 -1
  622. package/src/template/implementations/generated.template.ts +21 -29
  623. package/src/template/implementations/generated_http.template.ts +9 -6
  624. package/src/template/implementations/generated_sso.template.ts +6 -4
  625. package/src/template/implementations/init_types.template.ts +3 -2
  626. package/src/template/implementations/model.template.ts +4 -2
  627. package/src/template/implementations/model_test.template.ts +3 -2
  628. package/src/template/implementations/queries.template.ts +6 -14
  629. package/src/template/implementations/sd.template.ts +4 -2
  630. package/src/template/implementations/services.template.ts +7 -11
  631. package/src/template/implementations/view_form.template.ts +5 -3
  632. package/src/template/implementations/view_id_all_select.template.ts +3 -2
  633. package/src/template/implementations/view_list.template.ts +7 -5
  634. package/src/template/implementations/view_search_input.template.ts +3 -2
  635. package/src/template/template-manager.ts +4 -3
  636. package/src/template/template.ts +4 -3
  637. package/src/template/zod-converter.ts +10 -7
  638. package/src/testing/__tests__/dev-test-routes.test.ts +3 -2
  639. package/src/testing/__tests__/dev-vitest-manager.test.ts +1 -0
  640. package/src/testing/_relation-graph.ts +2 -2
  641. package/src/testing/bootstrap.ts +55 -27
  642. package/src/testing/data-explorer.ts +5 -4
  643. package/src/testing/dev-test-routes.ts +8 -5
  644. package/src/testing/dev-vitest-manager.ts +13 -12
  645. package/src/testing/fixture-generator.ts +11 -17
  646. package/src/testing/fixture-manager.ts +21 -17
  647. package/src/testing/parallel-db-manager.ts +2 -1
  648. package/src/testing/vitest-helpers.ts +2 -1
  649. package/src/types/__tests__/entity-json-schema-search-text.test.ts +1 -0
  650. package/src/types/types.ts +8 -8
  651. package/src/typings/knex.d.ts +4 -4
  652. package/src/ui/ai-api.ts +5 -3
  653. package/src/ui/ai-client.ts +6 -5
  654. package/src/ui/api.ts +25 -23
  655. package/src/ui/cdd-service.ts +12 -11
  656. package/src/utils/console-util.ts +3 -1
  657. package/src/utils/formatter.ts +94 -102
  658. package/src/utils/fs-utils.ts +2 -1
  659. package/src/utils/model.ts +2 -2
  660. package/src/utils/object-utils.ts +3 -3
  661. package/src/utils/process-utils.ts +2 -1
  662. package/src/utils/sql-parser.ts +10 -1
  663. package/src/utils/type-utils.ts +3 -3
  664. package/src/utils/utils.ts +9 -7
  665. package/src/utils/zod-error.ts +1 -1
  666. package/src/vector/chunking.ts +1 -1
  667. package/src/vector/config.ts +1 -1
  668. package/src/vector/embedding.ts +11 -9
  669. package/tsdown.api.config.ts +50 -0
  670. package/.swcrc.project-default +0 -18
  671. package/dist/api/__tests__/config.test.js +0 -189
  672. package/dist/bin/__tests__/test-command.test.js +0 -112
  673. package/dist/bin/__tests__/ts-loader-register.test.js +0 -45
  674. package/dist/database/puri-subset.test-d.js +0 -89
  675. package/dist/database/puri.types.test-d.js +0 -129
  676. package/dist/migration/__tests__/code-generation.search-text.test.js +0 -435
  677. package/dist/template/__tests__/generated.template.search-text.test.js +0 -99
  678. package/dist/template/generated.template.test-d.js +0 -24
  679. package/dist/testing/__tests__/dev-test-routes.test.js +0 -144
  680. package/dist/testing/__tests__/dev-vitest-manager.test.js +0 -152
  681. package/dist/types/__tests__/entity-json-schema-search-text.test.js +0 -256
  682. package/dist/typings/knex.d.js +0 -3
  683. package/dist/ui-web/assets/index-CKo0Z2Iu.css +0 -1
  684. package/dist/ui-web/assets/index-DK-2aacv.js +0 -257
@@ -1,308 +1,274 @@
1
- /** biome-ignore-all lint/suspicious/noExplicitAny: Naite는 expect와 호응하도록 any를 허용함 */ import { getLogger } from "@logtape/logtape";
1
+ import { __esmMin } from "../_virtual/rolldown_runtime.js";
2
+ import { convertNaiteKeyToCategory, init_category } from "../logger/category.js";
3
+ import { Sonamu, init_sonamu } from "../api/sonamu.js";
4
+ import { init_object_utils, isSerializable } from "../utils/object-utils.js";
5
+ import { getLogger } from "@logtape/logtape";
2
6
  import { get } from "radashi";
3
- import { Sonamu } from "../api/sonamu.js";
4
- import { convertNaiteKeyToCategory } from "../logger/category.js";
5
- import { isSerializable } from "../utils/object-utils.js";
6
- /**
7
- * 콜스택을 파싱하여 StackFrame 배열로 반환
8
- * - extractCallStack 자신과 Naite.t는 제외
9
- * - runWithContext/runWithMockContext 발견 시 거기서 종료
10
- * - node: 내부 경로는 포함하되, lineNumber는 path에 : 포함 시 붙이지 않음
11
- */ function extractCallStack() {
12
- const stack = new Error().stack;
13
- if (!stack) return [];
14
- const lines = stack.split("\n");
15
- // 콜스택 구조:
16
- // [0]: "Error"
17
- // [1]: "at extractCallStack"
18
- // [2]: "at Naite.t"
19
- // [3]: 실제 호출 위치부터 시작
20
- const frames = lines.slice(3).map(parseStackFrame).filter((frame)=>frame !== null);
21
- // runWithContext 계열 함수 발견 시 거기서 자르기
22
- const contextIndex = frames.findIndex((f)=>f.functionName?.includes("runWithContext") || f.functionName?.includes("runWithMockContext"));
23
- return contextIndex >= 0 ? frames.slice(0, contextIndex + 1) : frames;
24
- }
7
+
8
+ //#region src/naite/naite.ts
25
9
  /**
26
- * 콜스택 줄을 파싱
27
- * 형식1: "at FunctionName (filePath:lineNumber:columnNumber)"
28
- * 형식2: "at filePath:lineNumber:columnNumber" (익명 함수/모듈 레벨)
29
- */ function parseStackFrame(line) {
30
- // 패턴1: "at FunctionName (filePath:lineNumber:columnNumber)"
31
- const matchWithFunc = line.match(/at\s+(.+?)\s+\((.+?):(\d+):\d+\)/);
32
- if (matchWithFunc) {
33
- const functionName = matchWithFunc[1];
34
- const filePath = matchWithFunc[2];
35
- const lineNumberStr = matchWithFunc[3];
36
- // filePath에 이미 :가 포함되어 있으면 (예: "node:internal/...")
37
- if (filePath.includes(":")) {
38
- return {
39
- functionName,
40
- filePath,
41
- lineNumber: 0
42
- };
43
- }
44
- return {
45
- functionName,
46
- filePath,
47
- lineNumber: Number.parseInt(lineNumberStr, 10)
48
- };
49
- }
50
- // 패턴2: "at filePath:lineNumber:columnNumber" (함수명 없음)
51
- const matchNoFunc = line.match(/at\s+(.+?):(\d+):\d+$/);
52
- if (matchNoFunc) {
53
- const filePath = matchNoFunc[1];
54
- const lineNumberStr = matchNoFunc[2];
55
- return {
56
- functionName: null,
57
- filePath,
58
- lineNumber: Number.parseInt(lineNumberStr, 10)
59
- };
60
- }
61
- return null;
10
+ * 콜스택을 파싱하여 StackFrame 배열로 반환
11
+ * - extractCallStack 자신과 Naite.t는 제외
12
+ * - runWithContext/runWithMockContext 발견 거기서 종료
13
+ * - node: 내부 경로는 포함하되, lineNumber는 path에 : 포함 시 붙이지 않음
14
+ */
15
+ function extractCallStack() {
16
+ const stack = new Error().stack;
17
+ if (!stack) return [];
18
+ const lines = stack.split("\n");
19
+ const frames = lines.slice(3).map(parseStackFrame).filter((frame) => frame !== null);
20
+ const contextIndex = frames.findIndex((f) => f.functionName?.includes("runWithContext") || f.functionName?.includes("runWithMockContext"));
21
+ return contextIndex >= 0 ? frames.slice(0, contextIndex + 1) : frames;
62
22
  }
63
23
  /**
64
- * wildcard 패턴 매칭
65
- * 예시:
66
- * - "syncer:*" → "syncer:a", "syncer:a:b" 모두 매칭
67
- * - "syncer:*:user" → "syncer:renderTemplate:user" 매칭
68
- * - "syncer:renderTemplate:*" → "syncer:renderTemplate:service" 매칭
69
- */ function matchesPattern(key, pattern) {
70
- const keyParts = key.split(":");
71
- const patternParts = pattern.split(":");
72
- // 마지막이 * → prefix 매칭 (길이 무관)
73
- // 예: "syncer:*"는 "syncer:a", "syncer:a:b" 모두 매칭
74
- if (patternParts[patternParts.length - 1] === "*") {
75
- const prefixParts = patternParts.slice(0, -1);
76
- // prefix가 모두 일치하는지 확인
77
- return prefixParts.every((part, i)=>part === keyParts[i]);
78
- }
79
- // 길이가 같아야 함
80
- if (patternParts.length !== keyParts.length) {
81
- return false;
82
- }
83
- // 각 파트가 * 또는 정확히 일치
84
- return patternParts.every((part, i)=>part === "*" || part === keyParts[i]);
24
+ * 콜스택 줄을 파싱
25
+ * 형식1: "at FunctionName (filePath:lineNumber:columnNumber)"
26
+ * 형식2: "at filePath:lineNumber:columnNumber" (익명 함수/모듈 레벨)
27
+ */
28
+ function parseStackFrame(line) {
29
+ const matchWithFunc = line.match(/at\s+(.+?)\s+\((.+?):(\d+):\d+\)/);
30
+ if (matchWithFunc) {
31
+ const functionName = matchWithFunc[1];
32
+ const filePath = matchWithFunc[2];
33
+ const lineNumberStr = matchWithFunc[3];
34
+ if (filePath.includes(":")) {
35
+ return {
36
+ functionName,
37
+ filePath,
38
+ lineNumber: 0
39
+ };
40
+ }
41
+ return {
42
+ functionName,
43
+ filePath,
44
+ lineNumber: Number.parseInt(lineNumberStr, 10)
45
+ };
46
+ }
47
+ const matchNoFunc = line.match(/at\s+(.+?):(\d+):\d+$/);
48
+ if (matchNoFunc) {
49
+ const filePath = matchNoFunc[1];
50
+ const lineNumberStr = matchNoFunc[2];
51
+ return {
52
+ functionName: null,
53
+ filePath,
54
+ lineNumber: Number.parseInt(lineNumberStr, 10)
55
+ };
56
+ }
57
+ return null;
85
58
  }
86
59
  /**
87
- * NaiteQuery 클래스
88
- * 체이닝을 통한 trace 필터링 및 조회
89
- */ export class NaiteQuery {
90
- traces;
91
- constructor(traces){
92
- this.traces = traces;
93
- }
94
- /**
95
- * 파일명으로 필터링
96
- * @param fileName 파일명 (예: "syncer.test.ts")
97
- */ fromFile(fileName) {
98
- const filtered = this.traces.filter((t)=>t.stack.some((frame)=>frame.filePath.endsWith(`/${fileName}`)));
99
- return new NaiteQuery(filtered);
100
- }
101
- /**
102
- * 함수명으로 필터링
103
- * @param funcName 함수명 (includes 체크)
104
- * @param options.from 'direct' = 직접 호출만, 'indirect' = 간접 호출만, 'both' = 모두
105
- */ fromFunction(funcName, options = {
106
- from: "both"
107
- }) {
108
- const filtered = this.traces.filter((t)=>{
109
- if (options.from === "direct") {
110
- // stack[0]만 확인 (직접 호출)
111
- return t.stack[0]?.functionName?.includes(funcName);
112
- }
113
- if (options.from === "indirect") {
114
- // stack[1+]에서 확인 (간접 호출)
115
- return t.stack.slice(1).some((f)=>f.functionName?.includes(funcName));
116
- }
117
- // 전체 스택에서 확인
118
- return t.stack.some((f)=>f.functionName?.includes(funcName));
119
- });
120
- return new NaiteQuery(filtered);
121
- }
122
- /**
123
- * 데이터 경로 기반 필터링
124
- * @param path radash get 경로 (예: "data.userId")
125
- * @param operator 비교 연산자
126
- * @param value 비교값
127
- */ where(path, operator, value) {
128
- const filtered = this.traces.filter((trace)=>{
129
- const actual = get(trace, path);
130
- switch(operator){
131
- case ">":
132
- return actual > value;
133
- case "<":
134
- return actual < value;
135
- case ">=":
136
- return actual >= value;
137
- case "<=":
138
- return actual <= value;
139
- case "=":
140
- return actual === value;
141
- case "!=":
142
- return actual !== value;
143
- case "includes":
144
- return typeof actual === "string" && actual.includes(value);
145
- default:
146
- return false;
147
- }
148
- });
149
- return new NaiteQuery(filtered);
150
- }
151
- /**
152
- * 전체 데이터 배열 반환
153
- */ result() {
154
- return this.traces.map((t)=>t.data);
155
- }
156
- /**
157
- * 첫 번째 데이터 반환
158
- */ first() {
159
- return this.traces[0]?.data;
160
- }
161
- /**
162
- * 마지막 데이터 반환
163
- */ last() {
164
- return this.traces[this.traces.length - 1]?.data;
165
- }
166
- /**
167
- * n번째 데이터 반환
168
- */ at(index) {
169
- return this.traces[index]?.data;
170
- }
171
- /**
172
- * 원본 trace 배열 반환 (디버깅/NaiteViewer용)
173
- */ getTraces() {
174
- return this.traces;
175
- }
176
- }
177
- // Naite 싱글턴 객체 (추후 logger 연결 등의 상태 관리 필요성 고려)
178
- export class NaiteClass {
179
- // 테스트 로그 기록
180
- t(name, value/*이렇게 받은 값이 NaiteTrace로 저장되어 있다가 추후에 vitest에게 meta를 통해 넘겨져 프로세스간 통신을 통해 직렬화되어야 하는 점을 고려하였을 때 여기에 Serializable을 써서 제한을 둘 수도 있지만, 사용상의 편의를 생각하여 any로 받습니다.*/ ) {
181
- // 이 t 함수는 테스트 환경에서만 작동해야 합니다.
182
- // 그리고 테스트 환경 판단에 왜 isTest() 함수를 사용하지 않았냐면요,,
183
- // 이렇게 하는게 유틸 함수 불러와서 사용하는 것보다 조금이나마 빠를 것 같았기 때문입니다.
184
- if (process.env.NODE_ENV !== "test") {
185
- return;
186
- }
187
- try {
188
- const context = Sonamu.getContext();
189
- const store = context?.naiteStore;
190
- if (!store) {
191
- return;
192
- }
193
- // 콜스택 수집
194
- const stack = extractCallStack();
195
- const trace = {
196
- key: name,
197
- data: value,
198
- stack,
199
- at: new Date()
200
- };
201
- // 항상 배열로 관리
202
- const existing = store.get(name) ?? [];
203
- getLogger([
204
- "naite",
205
- ...convertNaiteKeyToCategory(name)
206
- ]).debug(`naite: {name} ${existing.length === 0 ? "is empty state" : `already existing with ${existing.length} entries`}, appending new entry`, {
207
- name,
208
- value
209
- });
210
- store.set(name, [
211
- ...existing,
212
- trace
213
- ]);
214
- } catch {
215
- // Context 없는 상황에서 Naite.t 호출
216
- }
217
- }
218
- /**
219
- * key 또는 wildcard 패턴으로 trace 조회
220
- * 항상 NaiteQuery 반환하여 체이닝 가능
221
- */ get(keyPattern) {
222
- const context = Sonamu.getContext();
223
- const store = context?.naiteStore;
224
- if (!store) {
225
- return new NaiteQuery([]);
226
- }
227
- // wildcard 없으면 exact match
228
- if (!keyPattern.includes("*")) {
229
- const traces = store.get(keyPattern) ?? [];
230
- return new NaiteQuery(traces);
231
- }
232
- // wildcard 패턴 매칭
233
- const allTraces = [];
234
- for (const [key, traces] of store.entries()){
235
- if (matchesPattern(key, keyPattern)) {
236
- allTraces.push(...traces);
237
- }
238
- }
239
- return new NaiteQuery(allTraces);
240
- }
241
- // 전체 리스트 가져오기
242
- getAll() {
243
- const context = Sonamu.getContext();
244
- if (!context?.naiteStore) {
245
- return {};
246
- }
247
- // NaiteTrace 배열을 data만 추출하여 반환
248
- const result = {};
249
- for (const [key, traces] of context.naiteStore.entries()){
250
- if (key.startsWith("mock:")) {
251
- // Mock 설정은 그대로 반환
252
- result[key] = traces;
253
- } else {
254
- // NaiteTrace 배열은 data만 추출
255
- result[key] = traces.map((t)=>t.data);
256
- }
257
- }
258
- return result;
259
- }
260
- /**
261
- * 스토어에 들어있던 트레이스를 고대로 꺼내옵니다.
262
- * 이때 값들은 모두 직렬화 가능한 상태로 나가게 됩니다.
263
- * 테스트 정보와 함께 extensions에 보낼 용도로 만들었습니다.
264
- * @returns
265
- */ getAllTraces() {
266
- const context = Sonamu.getContext();
267
- if (!context?.naiteStore) {
268
- return [];
269
- }
270
- const traces = Array.from(context.naiteStore.values()).flat();
271
- // 직렬화 불가능한 값이 존재한다면 이를 대문짝만하게 알려줍니다! 그치만 알리기만 하고 그냥 지나갑니다 ㅎㅎ
272
- // 왜 직렬화가 중요한가? 이(getAllTraces) 호출의 결과는 외부로 나가게 되는데,
273
- // 이때 주 용도가 vitest의 task.meta 필드를 통해 afterEach에서 Sonamu extension으로 전달하는 것입니다.
274
- // 여기서 meta 필드에 담긴 내용은 프로세스간 통신(process.send) 또는 스레드간 통신(message port)을 통해 전달되어야 하는데,
275
- // 이로 인해 "직렬화 가능한 값들만 허용"하는 제약이 생깁니다.
276
- //
277
- // 이 제약을 의식하여 Naite.t에 직렬화 가능한 값만 넘기게 할 수도 있었지만, 그렇게 하면 불편해질 것 같아서 하지 않았습니다.
278
- // 따라서 현재 Naite.t는 모든 값을 받을 수 있게 되어 있습니다.
279
- // 대신 이렇게(getAllTraces) 그 값들을 빼낼 때 JSON.stringify를 사용하여 강제로 직렬화 가능하게 만들었습니다,,
280
- for (const trace of traces){
281
- const check = isSerializable(trace.data);
282
- if (!check.valid) {
283
- console.warn("\n" + "╔════════════════════════════════════════════════════════════════╗\n" + "║ [Naite] Non-serializable value detected! ║\n" + "╠════════════════════════════════════════════════════════════════╣\n" + `║ Key: ${trace.key.padEnd(57)}║\n` + `║ Reason: ${(check.reason ?? "unknown").slice(0, 54).padEnd(54)}║\n` + `║ Location: ${(trace.stack[0]?.filePath ?? "unknown").slice(-51).padEnd(52)}║\n` + `║ Line: ${String(trace.stack[0]?.lineNumber ?? 0).padEnd(56)}║\n` + "╠════════════════════════════════════════════════════════════════╣\n" + "║ Naite.t() accepts any type of value. However, values will ║\n" + "║ be serialized to JSON when exported via Naite.getAllTraces(). ║\n" + "╚════════════════════════════════════════════════════════════════╝\n");
284
- }
285
- }
286
- return traces.map((trace)=>({
287
- key: trace.key,
288
- value: JSON.parse(JSON.stringify(trace.data ?? "")),
289
- filePath: trace.stack[0]?.filePath ?? "",
290
- lineNumber: trace.stack[0]?.lineNumber ?? 0,
291
- at: trace.at.toISOString()
292
- }));
293
- }
294
- // 특정 키 삭제하기
295
- del(key) {
296
- const context = Sonamu.getContext();
297
- if (!context?.naiteStore) {
298
- return;
299
- }
300
- context.naiteStore.delete(key);
301
- }
302
- createStore() {
303
- return new Map();
304
- }
60
+ * wildcard 패턴 매칭
61
+ * 예시:
62
+ * - "syncer:*" "syncer:a", "syncer:a:b" 모두 매칭
63
+ * - "syncer:*:user" → "syncer:renderTemplate:user" 매칭
64
+ * - "syncer:renderTemplate:*" → "syncer:renderTemplate:service" 매칭
65
+ */
66
+ function matchesPattern(key, pattern) {
67
+ const keyParts = key.split(":");
68
+ const patternParts = pattern.split(":");
69
+ if (patternParts[patternParts.length - 1] === "*") {
70
+ const prefixParts = patternParts.slice(0, -1);
71
+ return prefixParts.every((part, i) => part === keyParts[i]);
72
+ }
73
+ if (patternParts.length !== keyParts.length) {
74
+ return false;
75
+ }
76
+ return patternParts.every((part, i) => part === "*" || part === keyParts[i]);
305
77
  }
306
- export const Naite = new NaiteClass();
78
+ var NaiteQuery, NaiteClass, Naite;
79
+ var init_naite = __esmMin((() => {
80
+ init_sonamu();
81
+ init_category();
82
+ init_object_utils();
83
+ NaiteQuery = class NaiteQuery {
84
+ constructor(traces) {
85
+ this.traces = traces;
86
+ }
87
+ isComparableValue(value) {
88
+ return typeof value === "number" || typeof value === "string";
89
+ }
90
+ /**
91
+ * 파일명으로 필터링
92
+ * @param fileName 파일명 (예: "syncer.test.ts")
93
+ */
94
+ fromFile(fileName) {
95
+ const filtered = this.traces.filter((t) => t.stack.some((frame) => frame.filePath.endsWith(`/${fileName}`)));
96
+ return new NaiteQuery(filtered);
97
+ }
98
+ /**
99
+ * 함수명으로 필터링
100
+ * @param funcName 함수명 (includes 체크)
101
+ * @param options.from 'direct' = 직접 호출만, 'indirect' = 간접 호출만, 'both' = 모두
102
+ */
103
+ fromFunction(funcName, options = { from: "both" }) {
104
+ const filtered = this.traces.filter((t) => {
105
+ if (options.from === "direct") {
106
+ return t.stack[0]?.functionName?.includes(funcName);
107
+ }
108
+ if (options.from === "indirect") {
109
+ return t.stack.slice(1).some((f) => f.functionName?.includes(funcName));
110
+ }
111
+ return t.stack.some((f) => f.functionName?.includes(funcName));
112
+ });
113
+ return new NaiteQuery(filtered);
114
+ }
115
+ /**
116
+ * 데이터 경로 기반 필터링
117
+ * @param path radash get 경로 (예: "data.userId")
118
+ * @param operator 비교 연산자
119
+ * @param value 비교값
120
+ */
121
+ where(path, operator, value) {
122
+ const filtered = this.traces.filter((trace) => {
123
+ const actual = get(trace, path);
124
+ switch (operator) {
125
+ case ">": return this.isComparableValue(actual) && this.isComparableValue(value) && actual > value;
126
+ case "<": return this.isComparableValue(actual) && this.isComparableValue(value) && actual < value;
127
+ case ">=": return this.isComparableValue(actual) && this.isComparableValue(value) && actual >= value;
128
+ case "<=": return this.isComparableValue(actual) && this.isComparableValue(value) && actual <= value;
129
+ case "=": return actual === value;
130
+ case "!=": return actual !== value;
131
+ case "includes": return typeof actual === "string" && actual.includes(value);
132
+ default: return false;
133
+ }
134
+ });
135
+ return new NaiteQuery(filtered);
136
+ }
137
+ /**
138
+ * 전체 데이터 배열 반환
139
+ */
140
+ result() {
141
+ return this.traces.map((t) => t.data);
142
+ }
143
+ /**
144
+ * 첫 번째 데이터 반환
145
+ */
146
+ first() {
147
+ return this.traces[0]?.data;
148
+ }
149
+ /**
150
+ * 마지막 데이터 반환
151
+ */
152
+ last() {
153
+ return this.traces[this.traces.length - 1]?.data;
154
+ }
155
+ /**
156
+ * n번째 데이터 반환
157
+ */
158
+ at(index) {
159
+ return this.traces[index]?.data;
160
+ }
161
+ /**
162
+ * 원본 trace 배열 반환 (디버깅/NaiteViewer용)
163
+ */
164
+ getTraces() {
165
+ return this.traces;
166
+ }
167
+ };
168
+ NaiteClass = class {
169
+ t(name, value) {
170
+ if (process.env.NODE_ENV !== "test") {
171
+ return;
172
+ }
173
+ try {
174
+ const context = Sonamu.getContext();
175
+ const store = context?.naiteStore;
176
+ if (!store) {
177
+ return;
178
+ }
179
+ const stack = extractCallStack();
180
+ const trace = {
181
+ key: name,
182
+ data: value,
183
+ stack,
184
+ at: new Date()
185
+ };
186
+ const existing = store.get(name) ?? [];
187
+ getLogger(["naite", ...convertNaiteKeyToCategory(name)]).debug(`naite: {name} ${existing.length === 0 ? "is empty state" : `already existing with ${existing.length} entries`}, appending new entry`, {
188
+ name,
189
+ value
190
+ });
191
+ store.set(name, [...existing, trace]);
192
+ } catch {}
193
+ }
194
+ /**
195
+ * key 또는 wildcard 패턴으로 trace 조회
196
+ * 항상 NaiteQuery 반환하여 체이닝 가능
197
+ */
198
+ get(keyPattern) {
199
+ const context = Sonamu.getContext();
200
+ const store = context?.naiteStore;
201
+ if (!store) {
202
+ return new NaiteQuery([]);
203
+ }
204
+ if (!keyPattern.includes("*")) {
205
+ const traces = store.get(keyPattern) ?? [];
206
+ return new NaiteQuery(traces);
207
+ }
208
+ const allTraces = [];
209
+ for (const [key, traces] of store.entries()) {
210
+ if (matchesPattern(key, keyPattern)) {
211
+ allTraces.push(...traces);
212
+ }
213
+ }
214
+ return new NaiteQuery(allTraces);
215
+ }
216
+ getAll() {
217
+ const context = Sonamu.getContext();
218
+ if (!context?.naiteStore) {
219
+ return {};
220
+ }
221
+ const result = {};
222
+ for (const [key, traces] of context.naiteStore.entries()) {
223
+ if (key.startsWith("mock:")) {
224
+ result[key] = traces;
225
+ } else {
226
+ result[key] = traces.map((t) => t.data);
227
+ }
228
+ }
229
+ return result;
230
+ }
231
+ /**
232
+ * 스토어에 들어있던 트레이스를 고대로 꺼내옵니다.
233
+ * 이때 값들은 모두 직렬화 가능한 상태로 나가게 됩니다.
234
+ * 테스트 정보와 함께 extensions에 보낼 용도로 만들었습니다.
235
+ * @returns
236
+ */
237
+ getAllTraces() {
238
+ const context = Sonamu.getContext();
239
+ if (!context?.naiteStore) {
240
+ return [];
241
+ }
242
+ const traces = Array.from(context.naiteStore.values()).flat();
243
+ for (const trace of traces) {
244
+ const check = isSerializable(trace.data);
245
+ if (!check.valid) {
246
+ console.warn("\n" + "╔════════════════════════════════════════════════════════════════╗\n" + "║ [Naite] Non-serializable value detected! ║\n" + "╠════════════════════════════════════════════════════════════════╣\n" + `║ Key: ${trace.key.padEnd(57)}║\n` + `║ Reason: ${(check.reason ?? "unknown").slice(0, 54).padEnd(54)}║\n` + `║ Location: ${(trace.stack[0]?.filePath ?? "unknown").slice(-51).padEnd(52)}║\n` + `║ Line: ${String(trace.stack[0]?.lineNumber ?? 0).padEnd(56)}║\n` + "╠════════════════════════════════════════════════════════════════╣\n" + "║ Naite.t() accepts any type of value. However, values will ║\n" + "║ be serialized to JSON when exported via Naite.getAllTraces(). ║\n" + "╚════════════════════════════════════════════════════════════════╝\n");
247
+ }
248
+ }
249
+ return traces.map((trace) => ({
250
+ key: trace.key,
251
+ value: JSON.parse(JSON.stringify(trace.data ?? "")),
252
+ filePath: trace.stack[0]?.filePath ?? "",
253
+ lineNumber: trace.stack[0]?.lineNumber ?? 0,
254
+ at: trace.at.toISOString()
255
+ }));
256
+ }
257
+ del(key) {
258
+ const context = Sonamu.getContext();
259
+ if (!context?.naiteStore) {
260
+ return;
261
+ }
262
+ context.naiteStore.delete(key);
263
+ }
264
+ createStore() {
265
+ return new Map();
266
+ }
267
+ };
268
+ Naite = new NaiteClass();
269
+ }));
307
270
 
308
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9uYWl0ZS9uYWl0ZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiogYmlvbWUtaWdub3JlLWFsbCBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogTmFpdGXripQgZXhwZWN07JmAIO2YuOydke2VmOuPhOuhnSBhbnnrpbwg7ZeI7Jqp7ZWoICovXG5cbmltcG9ydCB7IGdldExvZ2dlciB9IGZyb20gXCJAbG9ndGFwZS9sb2d0YXBlXCI7XG5pbXBvcnQgeyBnZXQgfSBmcm9tIFwicmFkYXNoaVwiO1xuaW1wb3J0IHsgU29uYW11IH0gZnJvbSBcIi4uL2FwaS9zb25hbXVcIjtcbmltcG9ydCB0eXBlIHsgQ29tcGFyaXNvbk9wZXJhdG9yIH0gZnJvbSBcIi4uL2RhdGFiYXNlL3B1cmkudHlwZXNcIjtcbmltcG9ydCB7IGNvbnZlcnROYWl0ZUtleVRvQ2F0ZWdvcnkgfSBmcm9tIFwiLi4vbG9nZ2VyL2NhdGVnb3J5XCI7XG5pbXBvcnQgeyBpc1NlcmlhbGl6YWJsZSB9IGZyb20gXCIuLi91dGlscy9vYmplY3QtdXRpbHNcIjtcblxuLy8gU3RhY2tGcmFtZSDtg4DsnoVcbmludGVyZmFjZSBTdGFja0ZyYW1lIHtcbiAgZnVuY3Rpb25OYW1lOiBzdHJpbmcgfCBudWxsO1xuICBmaWxlUGF0aDogc3RyaW5nOyAvLyBcIi9Vc2Vycy8uLi4vc3luY2VyLnRzXCIg65iQ64qUIFwibm9kZTppbnRlcm5hbC8uLi5cIlxuICBsaW5lTnVtYmVyOiBudW1iZXI7IC8vIFRTIO2MjOydvCDquLDspIAg65287J24IOuyiO2YuFxufVxuXG4vLyBOYWl0ZVRyYWNlIO2DgOyehVxuaW50ZXJmYWNlIE5haXRlVHJhY2Uge1xuICBrZXk6IHN0cmluZztcbiAgZGF0YTogYW55O1xuICBzdGFjazogU3RhY2tGcmFtZVtdOyAvLyDsvZzsiqTtg50g7KCV67O0XG4gIGF0OiBEYXRlO1xufVxuXG4vLyBOYWl0ZS506rCAIOyggOyepeuQmOuKlCDtg4DsnoUgKO2VreyDgSDrsLDsl7TroZwg7Ya17J28KVxuZXhwb3J0IHR5cGUgTmFpdGVTdG9yZSA9IE1hcDxzdHJpbmcsIE5haXRlVHJhY2VbXT47XG5cbi8vIGdldEFsbFRyYWNlcygp6rCAIOuwmO2ZmO2VmOuKlCDsp4HroKztmZTrkJwgdHJhY2Ug7YOA7J6FXG4vLyBib290c3RyYXAudHPsnZggVGFza01ldGEgYXVnbWVudGF0aW9uLCBkZXYtdml0ZXN0LW1hbmFnZXIudHPsl5DshJzrj4Qg7J20IO2DgOyeheydhCDqs7XsnKDtlanri4jri6QuXG5leHBvcnQgdHlwZSBTZXJpYWxpemVkVHJhY2UgPSB7XG4gIGtleTogc3RyaW5nO1xuICB2YWx1ZTogYW55O1xuICBmaWxlUGF0aDogc3RyaW5nO1xuICBsaW5lTnVtYmVyOiBudW1iZXI7XG4gIGF0OiBzdHJpbmc7XG59O1xuXG4vKipcbiAqIOy9nOyKpO2DneydhCDtjIzsi7HtlZjsl6wgU3RhY2tGcmFtZSDrsLDsl7TroZwg67CY7ZmYXG4gKiAtIGV4dHJhY3RDYWxsU3RhY2sg7J6Q7Iug6rO8IE5haXRlLnTripQg7KCc7Jm4XG4gKiAtIHJ1bldpdGhDb250ZXh0L3J1bldpdGhNb2NrQ29udGV4dCDrsJzqsqwg7IucIOqxsOq4sOyEnCDsooXro4xcbiAqIC0gbm9kZTog64K067aAIOqyveuhnOuKlCDtj6ztlajtlZjrkJgsIGxpbmVOdW1iZXLripQgcGF0aOyXkCA6IO2PrO2VqCDsi5wg67aZ7J207KeAIOyViuydjFxuICovXG5mdW5jdGlvbiBleHRyYWN0Q2FsbFN0YWNrKCk6IFN0YWNrRnJhbWVbXSB7XG4gIGNvbnN0IHN0YWNrID0gbmV3IEVycm9yKCkuc3RhY2s7XG4gIGlmICghc3RhY2spIHJldHVybiBbXTtcblxuICBjb25zdCBsaW5lcyA9IHN0YWNrLnNwbGl0KFwiXFxuXCIpO1xuXG4gIC8vIOy9nOyKpO2DnSDqtazsobA6XG4gIC8vIFswXTogXCJFcnJvclwiXG4gIC8vIFsxXTogXCJhdCBleHRyYWN0Q2FsbFN0YWNrXCJcbiAgLy8gWzJdOiBcImF0IE5haXRlLnRcIlxuICAvLyBbM106IOyLpOygnCDtmLjstpwg7JyE7LmY67aA7YSwIOyLnOyekVxuICBjb25zdCBmcmFtZXMgPSBsaW5lc1xuICAgIC5zbGljZSgzKVxuICAgIC5tYXAocGFyc2VTdGFja0ZyYW1lKVxuICAgIC5maWx0ZXIoKGZyYW1lKTogZnJhbWUgaXMgU3RhY2tGcmFtZSA9PiBmcmFtZSAhPT0gbnVsbCk7XG5cbiAgLy8gcnVuV2l0aENvbnRleHQg6rOE7Je0IO2VqOyImCDrsJzqsqwg7IucIOqxsOq4sOyEnCDsnpDrpbTquLBcbiAgY29uc3QgY29udGV4dEluZGV4ID0gZnJhbWVzLmZpbmRJbmRleChcbiAgICAoZikgPT5cbiAgICAgIGYuZnVuY3Rpb25OYW1lPy5pbmNsdWRlcyhcInJ1bldpdGhDb250ZXh0XCIpIHx8IGYuZnVuY3Rpb25OYW1lPy5pbmNsdWRlcyhcInJ1bldpdGhNb2NrQ29udGV4dFwiKSxcbiAgKTtcblxuICByZXR1cm4gY29udGV4dEluZGV4ID49IDAgPyBmcmFtZXMuc2xpY2UoMCwgY29udGV4dEluZGV4ICsgMSkgOiBmcmFtZXM7XG59XG5cbi8qKlxuICog7L2c7Iqk7YOdIO2VnCDspITsnYQg7YyM7IuxXG4gKiDtmJXsi50xOiBcImF0IEZ1bmN0aW9uTmFtZSAoZmlsZVBhdGg6bGluZU51bWJlcjpjb2x1bW5OdW1iZXIpXCJcbiAqIO2YleyLnTI6IFwiYXQgZmlsZVBhdGg6bGluZU51bWJlcjpjb2x1bW5OdW1iZXJcIiAo7J2166qFIO2VqOyImC/rqqjrk4gg66CI67KoKVxuICovXG5mdW5jdGlvbiBwYXJzZVN0YWNrRnJhbWUobGluZTogc3RyaW5nKTogU3RhY2tGcmFtZSB8IG51bGwge1xuICAvLyDtjKjthLQxOiBcImF0IEZ1bmN0aW9uTmFtZSAoZmlsZVBhdGg6bGluZU51bWJlcjpjb2x1bW5OdW1iZXIpXCJcbiAgY29uc3QgbWF0Y2hXaXRoRnVuYyA9IGxpbmUubWF0Y2goL2F0XFxzKyguKz8pXFxzK1xcKCguKz8pOihcXGQrKTpcXGQrXFwpLyk7XG4gIGlmIChtYXRjaFdpdGhGdW5jKSB7XG4gICAgY29uc3QgZnVuY3Rpb25OYW1lID0gbWF0Y2hXaXRoRnVuY1sxXTtcbiAgICBjb25zdCBmaWxlUGF0aCA9IG1hdGNoV2l0aEZ1bmNbMl07XG4gICAgY29uc3QgbGluZU51bWJlclN0ciA9IG1hdGNoV2l0aEZ1bmNbM107XG5cbiAgICAvLyBmaWxlUGF0aOyXkCDsnbTrr7ggOuqwgCDtj6ztlajrkJjslrQg7J6I7Jy866m0ICjsmIg6IFwibm9kZTppbnRlcm5hbC8uLi5cIilcbiAgICBpZiAoZmlsZVBhdGguaW5jbHVkZXMoXCI6XCIpKSB7XG4gICAgICByZXR1cm4geyBmdW5jdGlvbk5hbWUsIGZpbGVQYXRoLCBsaW5lTnVtYmVyOiAwIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGZ1bmN0aW9uTmFtZSxcbiAgICAgIGZpbGVQYXRoLFxuICAgICAgbGluZU51bWJlcjogTnVtYmVyLnBhcnNlSW50KGxpbmVOdW1iZXJTdHIsIDEwKSxcbiAgICB9O1xuICB9XG5cbiAgLy8g7Yyo7YS0MjogXCJhdCBmaWxlUGF0aDpsaW5lTnVtYmVyOmNvbHVtbk51bWJlclwiICjtlajsiJjrqoUg7JeG7J2MKVxuICBjb25zdCBtYXRjaE5vRnVuYyA9IGxpbmUubWF0Y2goL2F0XFxzKyguKz8pOihcXGQrKTpcXGQrJC8pO1xuICBpZiAobWF0Y2hOb0Z1bmMpIHtcbiAgICBjb25zdCBmaWxlUGF0aCA9IG1hdGNoTm9GdW5jWzFdO1xuICAgIGNvbnN0IGxpbmVOdW1iZXJTdHIgPSBtYXRjaE5vRnVuY1syXTtcblxuICAgIHJldHVybiB7XG4gICAgICBmdW5jdGlvbk5hbWU6IG51bGwsXG4gICAgICBmaWxlUGF0aCxcbiAgICAgIGxpbmVOdW1iZXI6IE51bWJlci5wYXJzZUludChsaW5lTnVtYmVyU3RyLCAxMCksXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIHdpbGRjYXJkIO2MqO2EtCDrp6Tsua1cbiAqIOyYiOyLnDpcbiAqIC0gXCJzeW5jZXI6KlwiIOKGkiBcInN5bmNlcjphXCIsIFwic3luY2VyOmE6YlwiIOuqqOuRkCDrp6Tsua1cbiAqIC0gXCJzeW5jZXI6Kjp1c2VyXCIg4oaSIFwic3luY2VyOnJlbmRlclRlbXBsYXRlOnVzZXJcIiDrp6Tsua1cbiAqIC0gXCJzeW5jZXI6cmVuZGVyVGVtcGxhdGU6KlwiIOKGkiBcInN5bmNlcjpyZW5kZXJUZW1wbGF0ZTpzZXJ2aWNlXCIg66ek7LmtXG4gKi9cbmZ1bmN0aW9uIG1hdGNoZXNQYXR0ZXJuKGtleTogc3RyaW5nLCBwYXR0ZXJuOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3Qga2V5UGFydHMgPSBrZXkuc3BsaXQoXCI6XCIpO1xuICBjb25zdCBwYXR0ZXJuUGFydHMgPSBwYXR0ZXJuLnNwbGl0KFwiOlwiKTtcblxuICAvLyDrp4jsp4Drp4nsnbQgKiDihpIgcHJlZml4IOunpOy5rSAo6ri47J20IOustOq0gClcbiAgLy8g7JiIOiBcInN5bmNlcjoqXCLripQgXCJzeW5jZXI6YVwiLCBcInN5bmNlcjphOmJcIiDrqqjrkZAg66ek7LmtXG4gIGlmIChwYXR0ZXJuUGFydHNbcGF0dGVyblBhcnRzLmxlbmd0aCAtIDFdID09PSBcIipcIikge1xuICAgIGNvbnN0IHByZWZpeFBhcnRzID0gcGF0dGVyblBhcnRzLnNsaWNlKDAsIC0xKTtcbiAgICAvLyBwcmVmaXjqsIAg66qo65GQIOydvOy5mO2VmOuKlOyngCDtmZXsnbhcbiAgICByZXR1cm4gcHJlZml4UGFydHMuZXZlcnkoKHBhcnQsIGkpID0+IHBhcnQgPT09IGtleVBhcnRzW2ldKTtcbiAgfVxuXG4gIC8vIOq4uOydtOqwgCDqsJnslYTslbwg7ZWoXG4gIGlmIChwYXR0ZXJuUGFydHMubGVuZ3RoICE9PSBrZXlQYXJ0cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyDqsIEg7YyM7Yq46rCAICog65iQ64qUIOygle2Zle2eiCDsnbzsuZhcbiAgcmV0dXJuIHBhdHRlcm5QYXJ0cy5ldmVyeSgocGFydCwgaSkgPT4gcGFydCA9PT0gXCIqXCIgfHwgcGFydCA9PT0ga2V5UGFydHNbaV0pO1xufVxuXG4vKipcbiAqIE5haXRlUXVlcnkg7YG0656Y7IqkXG4gKiDssrTsnbTri53snYQg7Ya17ZWcIHRyYWNlIO2VhO2EsOungSDrsI8g7KGw7ZqMXG4gKi9cbmV4cG9ydCBjbGFzcyBOYWl0ZVF1ZXJ5IHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSB0cmFjZXM6IE5haXRlVHJhY2VbXSkge31cblxuICAvKipcbiAgICog7YyM7J2866qF7Jy866GcIO2VhO2EsOungVxuICAgKiBAcGFyYW0gZmlsZU5hbWUg7YyM7J2866qFICjsmIg6IFwic3luY2VyLnRlc3QudHNcIilcbiAgICovXG4gIGZyb21GaWxlKGZpbGVOYW1lOiBzdHJpbmcpOiBOYWl0ZVF1ZXJ5IHtcbiAgICBjb25zdCBmaWx0ZXJlZCA9IHRoaXMudHJhY2VzLmZpbHRlcigodCkgPT5cbiAgICAgIHQuc3RhY2suc29tZSgoZnJhbWUpID0+IGZyYW1lLmZpbGVQYXRoLmVuZHNXaXRoKGAvJHtmaWxlTmFtZX1gKSksXG4gICAgKTtcbiAgICByZXR1cm4gbmV3IE5haXRlUXVlcnkoZmlsdGVyZWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VqOyImOuqheycvOuhnCDtlYTthLDrp4FcbiAgICogQHBhcmFtIGZ1bmNOYW1lIO2VqOyImOuqhSAoaW5jbHVkZXMg7LK07YGsKVxuICAgKiBAcGFyYW0gb3B0aW9ucy5mcm9tICdkaXJlY3QnID0g7KeB7KCRIO2YuOy2nOunjCwgJ2luZGlyZWN0JyA9IOqwhOygkSDtmLjstpzrp4wsICdib3RoJyA9IOuqqOuRkFxuICAgKi9cbiAgZnJvbUZ1bmN0aW9uKFxuICAgIGZ1bmNOYW1lOiBzdHJpbmcsXG4gICAgb3B0aW9uczogeyBmcm9tOiBcImRpcmVjdFwiIHwgXCJpbmRpcmVjdFwiIHwgXCJib3RoXCIgfSA9IHsgZnJvbTogXCJib3RoXCIgfSxcbiAgKTogTmFpdGVRdWVyeSB7XG4gICAgY29uc3QgZmlsdGVyZWQgPSB0aGlzLnRyYWNlcy5maWx0ZXIoKHQpID0+IHtcbiAgICAgIGlmIChvcHRpb25zLmZyb20gPT09IFwiZGlyZWN0XCIpIHtcbiAgICAgICAgLy8gc3RhY2tbMF3rp4wg7ZmV7J24ICjsp4HsoJEg7Zi47LacKVxuICAgICAgICByZXR1cm4gdC5zdGFja1swXT8uZnVuY3Rpb25OYW1lPy5pbmNsdWRlcyhmdW5jTmFtZSk7XG4gICAgICB9XG4gICAgICBpZiAob3B0aW9ucy5mcm9tID09PSBcImluZGlyZWN0XCIpIHtcbiAgICAgICAgLy8gc3RhY2tbMStd7JeQ7IScIO2ZleyduCAo6rCE7KCRIO2YuOy2nClcbiAgICAgICAgcmV0dXJuIHQuc3RhY2suc2xpY2UoMSkuc29tZSgoZikgPT4gZi5mdW5jdGlvbk5hbWU/LmluY2x1ZGVzKGZ1bmNOYW1lKSk7XG4gICAgICB9XG4gICAgICAvLyDsoITssrQg7Iqk7YOd7JeQ7IScIO2ZleyduFxuICAgICAgcmV0dXJuIHQuc3RhY2suc29tZSgoZikgPT4gZi5mdW5jdGlvbk5hbWU/LmluY2x1ZGVzKGZ1bmNOYW1lKSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIG5ldyBOYWl0ZVF1ZXJ5KGZpbHRlcmVkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDrjbDsnbTthLAg6rK966GcIOq4sOuwmCDtlYTthLDrp4FcbiAgICogQHBhcmFtIHBhdGggcmFkYXNoIGdldCDqsr3roZwgKOyYiDogXCJkYXRhLnVzZXJJZFwiKVxuICAgKiBAcGFyYW0gb3BlcmF0b3Ig67mE6rWQIOyXsOyCsOyekFxuICAgKiBAcGFyYW0gdmFsdWUg67mE6rWQ6rCSXG4gICAqL1xuICB3aGVyZShwYXRoOiBzdHJpbmcsIG9wZXJhdG9yOiBDb21wYXJpc29uT3BlcmF0b3IgfCBcImluY2x1ZGVzXCIsIHZhbHVlOiBhbnkpOiBOYWl0ZVF1ZXJ5IHtcbiAgICBjb25zdCBmaWx0ZXJlZCA9IHRoaXMudHJhY2VzLmZpbHRlcigodHJhY2UpID0+IHtcbiAgICAgIGNvbnN0IGFjdHVhbCA9IGdldCh0cmFjZSwgcGF0aCkgYXMgYW55O1xuXG4gICAgICBzd2l0Y2ggKG9wZXJhdG9yKSB7XG4gICAgICAgIGNhc2UgXCI+XCI6XG4gICAgICAgICAgcmV0dXJuIGFjdHVhbCA+IHZhbHVlO1xuICAgICAgICBjYXNlIFwiPFwiOlxuICAgICAgICAgIHJldHVybiBhY3R1YWwgPCB2YWx1ZTtcbiAgICAgICAgY2FzZSBcIj49XCI6XG4gICAgICAgICAgcmV0dXJuIGFjdHVhbCA+PSB2YWx1ZTtcbiAgICAgICAgY2FzZSBcIjw9XCI6XG4gICAgICAgICAgcmV0dXJuIGFjdHVhbCA8PSB2YWx1ZTtcbiAgICAgICAgY2FzZSBcIj1cIjpcbiAgICAgICAgICByZXR1cm4gYWN0dWFsID09PSB2YWx1ZTtcbiAgICAgICAgY2FzZSBcIiE9XCI6XG4gICAgICAgICAgcmV0dXJuIGFjdHVhbCAhPT0gdmFsdWU7XG4gICAgICAgIGNhc2UgXCJpbmNsdWRlc1wiOlxuICAgICAgICAgIHJldHVybiB0eXBlb2YgYWN0dWFsID09PSBcInN0cmluZ1wiICYmIGFjdHVhbC5pbmNsdWRlcyh2YWx1ZSk7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBuZXcgTmFpdGVRdWVyeShmaWx0ZXJlZCk7XG4gIH1cblxuICAvKipcbiAgICog7KCE7LK0IOuNsOydtO2EsCDrsLDsl7Qg67CY7ZmYXG4gICAqL1xuICByZXN1bHQoKTogYW55W10ge1xuICAgIHJldHVybiB0aGlzLnRyYWNlcy5tYXAoKHQpID0+IHQuZGF0YSk7XG4gIH1cblxuICAvKipcbiAgICog7LKrIOuyiOynuCDrjbDsnbTthLAg67CY7ZmYXG4gICAqL1xuICBmaXJzdCgpOiBhbnkgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnRyYWNlc1swXT8uZGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiDrp4jsp4Drp4kg642w7J207YSwIOuwmO2ZmFxuICAgKi9cbiAgbGFzdCgpOiBhbnkgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnRyYWNlc1t0aGlzLnRyYWNlcy5sZW5ndGggLSAxXT8uZGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiBu67KI7Ke4IOuNsOydtO2EsCDrsJjtmZhcbiAgICovXG4gIGF0KGluZGV4OiBudW1iZXIpOiBhbnkgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnRyYWNlc1tpbmRleF0/LmRhdGE7XG4gIH1cblxuICAvKipcbiAgICog7JuQ67O4IHRyYWNlIOuwsOyXtCDrsJjtmZggKOuUlOuyhOq5hS9OYWl0ZVZpZXdlcuyaqSlcbiAgICovXG4gIGdldFRyYWNlcygpOiBOYWl0ZVRyYWNlW10ge1xuICAgIHJldHVybiB0aGlzLnRyYWNlcztcbiAgfVxufVxuXG4vLyBOYWl0ZSDsi7HquIDthLQg6rCd7LK0ICjstpTtm4QgbG9nZ2VyIOyXsOqysCDrk7HsnZgg7IOB7YOcIOq0gOumrCDtlYTsmpTshLEg6rOg66CkKVxuZXhwb3J0IGNsYXNzIE5haXRlQ2xhc3Mge1xuICAvLyDthYzsiqTtirgg66Gc6re4IOq4sOuhnVxuICB0KFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICB2YWx1ZTogYW55IC8q7J2066CH6rKMIOuwm+ydgCDqsJLsnbQgTmFpdGVUcmFjZeuhnCDsoIDsnqXrkJjslrQg7J6I64uk6rCAIOy2lO2bhOyXkCB2aXRlc3Tsl5DqsowgbWV0YeulvCDthrXtlbQg64SY6rKo7KC4IO2UhOuhnOyEuOyKpOqwhCDthrXsi6DsnYQg7Ya17ZW0IOyngeugrO2ZlOuQmOyWtOyVvCDtlZjripQg7KCQ7J2EIOqzoOugpO2VmOyYgOydhCDrlYwg7Jes6riw7JeQIFNlcmlhbGl6YWJsZeydhCDsjajshJwg7KCc7ZWc7J2EIOuRmCDsiJjrj4Qg7J6I7KeA66eMLCDsgqzsmqnsg4HsnZgg7Y647J2Y66W8IOyDneqwge2VmOyXrCBhbnnroZwg67Cb7Iq164uI64ukLiovLFxuICApIHtcbiAgICAvLyDsnbQgdCDtlajsiJjripQg7YWM7Iqk7Yq4IO2ZmOqyveyXkOyEnOunjCDsnpHrj5ntlbTslbwg7ZWp64uI64ukLlxuICAgIC8vIOq3uOumrOqzoCDthYzsiqTtirgg7ZmY6rK9IO2MkOuLqOyXkCDsmZwgaXNUZXN0KCkg7ZWo7IiY66W8IOyCrOyaqe2VmOyngCDslYrslZjrg5DrqbTsmpQsLFxuICAgIC8vIOydtOugh+qyjCDtlZjripTqsowg7Jyg7Yu4IO2VqOyImCDrtojrn6zsmYDshJwg7IKs7Jqp7ZWY64qUIOqyg+uztOuLpCDsobDquIjsnbTrgpjrp4gg67mg66W8IOqygyDqsJnslZjquLAg65WM66y47J6F64uI64ukLlxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJ0ZXN0XCIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgY29udGV4dCA9IFNvbmFtdS5nZXRDb250ZXh0KCk7XG4gICAgICBjb25zdCBzdG9yZSA9IGNvbnRleHQ/Lm5haXRlU3RvcmU7XG5cbiAgICAgIGlmICghc3RvcmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyDsvZzsiqTtg50g7IiY7KeRXG4gICAgICBjb25zdCBzdGFjayA9IGV4dHJhY3RDYWxsU3RhY2soKTtcblxuICAgICAgY29uc3QgdHJhY2U6IE5haXRlVHJhY2UgPSB7XG4gICAgICAgIGtleTogbmFtZSxcbiAgICAgICAgZGF0YTogdmFsdWUsXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBhdDogbmV3IERhdGUoKSxcbiAgICAgIH07XG5cbiAgICAgIC8vIO2VreyDgSDrsLDsl7TroZwg6rSA66asXG4gICAgICBjb25zdCBleGlzdGluZyA9IHN0b3JlLmdldChuYW1lKSA/PyBbXTtcbiAgICAgIGdldExvZ2dlcihbXCJuYWl0ZVwiLCAuLi5jb252ZXJ0TmFpdGVLZXlUb0NhdGVnb3J5KG5hbWUpXSkuZGVidWcoXG4gICAgICAgIGBuYWl0ZToge25hbWV9ICR7ZXhpc3RpbmcubGVuZ3RoID09PSAwID8gXCJpcyBlbXB0eSBzdGF0ZVwiIDogYGFscmVhZHkgZXhpc3Rpbmcgd2l0aCAke2V4aXN0aW5nLmxlbmd0aH0gZW50cmllc2B9LCBhcHBlbmRpbmcgbmV3IGVudHJ5YCxcbiAgICAgICAge1xuICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgdmFsdWUsXG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICBzdG9yZS5zZXQobmFtZSwgWy4uLmV4aXN0aW5nLCB0cmFjZV0pO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gQ29udGV4dCDsl4bripQg7IOB7Zmp7JeQ7IScIE5haXRlLnQg7Zi47LacXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIGtleSDrmJDripQgd2lsZGNhcmQg7Yyo7YS07Jy866GcIHRyYWNlIOyhsO2ajFxuICAgKiDtla3sg4EgTmFpdGVRdWVyeSDrsJjtmZjtlZjsl6wg7LK07J2064udIOqwgOuKpVxuICAgKi9cbiAgZ2V0KGtleVBhdHRlcm46IHN0cmluZyk6IE5haXRlUXVlcnkge1xuICAgIGNvbnN0IGNvbnRleHQgPSBTb25hbXUuZ2V0Q29udGV4dCgpO1xuICAgIGNvbnN0IHN0b3JlID0gY29udGV4dD8ubmFpdGVTdG9yZTtcblxuICAgIGlmICghc3RvcmUpIHtcbiAgICAgIHJldHVybiBuZXcgTmFpdGVRdWVyeShbXSk7XG4gICAgfVxuXG4gICAgLy8gd2lsZGNhcmQg7JeG7Jy866m0IGV4YWN0IG1hdGNoXG4gICAgaWYgKCFrZXlQYXR0ZXJuLmluY2x1ZGVzKFwiKlwiKSkge1xuICAgICAgY29uc3QgdHJhY2VzID0gc3RvcmUuZ2V0KGtleVBhdHRlcm4pID8/IFtdO1xuICAgICAgcmV0dXJuIG5ldyBOYWl0ZVF1ZXJ5KHRyYWNlcyk7XG4gICAgfVxuXG4gICAgLy8gd2lsZGNhcmQg7Yyo7YS0IOunpOy5rVxuICAgIGNvbnN0IGFsbFRyYWNlczogTmFpdGVUcmFjZVtdID0gW107XG4gICAgZm9yIChjb25zdCBba2V5LCB0cmFjZXNdIG9mIHN0b3JlLmVudHJpZXMoKSkge1xuICAgICAgaWYgKG1hdGNoZXNQYXR0ZXJuKGtleSwga2V5UGF0dGVybikpIHtcbiAgICAgICAgYWxsVHJhY2VzLnB1c2goLi4udHJhY2VzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IE5haXRlUXVlcnkoYWxsVHJhY2VzKTtcbiAgfVxuXG4gIC8vIOyghOyytCDrpqzsiqTtirgg6rCA7KC47Jik6riwXG4gIGdldEFsbCgpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9IHtcbiAgICBjb25zdCBjb250ZXh0ID0gU29uYW11LmdldENvbnRleHQoKTtcbiAgICBpZiAoIWNvbnRleHQ/Lm5haXRlU3RvcmUpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgLy8gTmFpdGVUcmFjZSDrsLDsl7TsnYQgZGF0YeunjCDstpTstpztlZjsl6wg67CY7ZmYXG4gICAgY29uc3QgcmVzdWx0OiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0ge307XG4gICAgZm9yIChjb25zdCBba2V5LCB0cmFjZXNdIG9mIGNvbnRleHQubmFpdGVTdG9yZS5lbnRyaWVzKCkpIHtcbiAgICAgIGlmIChrZXkuc3RhcnRzV2l0aChcIm1vY2s6XCIpKSB7XG4gICAgICAgIC8vIE1vY2sg7ISk7KCV7J2AIOq3uOuMgOuhnCDrsJjtmZhcbiAgICAgICAgcmVzdWx0W2tleV0gPSB0cmFjZXM7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBOYWl0ZVRyYWNlIOuwsOyXtOydgCBkYXRh66eMIOy2lOy2nFxuICAgICAgICByZXN1bHRba2V5XSA9IHRyYWNlcy5tYXAoKHQ6IE5haXRlVHJhY2UpID0+IHQuZGF0YSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICog7Iqk7Yag7Ja07JeQIOuTpOyWtOyeiOuNmCDtirjroIjsnbTsiqTrpbwg6rOg64yA66GcIOq6vOuCtOyYteuLiOuLpC5cbiAgICog7J2065WMIOqwkuuTpOydgCDrqqjrkZAg7KeB66Cs7ZmUIOqwgOuKpe2VnCDsg4Htg5zroZwg64KY6rCA6rKMIOuQqeuLiOuLpC5cbiAgICog7YWM7Iqk7Yq4IOygleuztOyZgCDtlajqu5ggZXh0ZW5zaW9uc+yXkCDrs7Trgrwg7Jqp64+E66GcIOunjOuTpOyXiOyKteuLiOuLpC5cbiAgICogQHJldHVybnNcbiAgICovXG4gIGdldEFsbFRyYWNlcygpOiBTZXJpYWxpemVkVHJhY2VbXSB7XG4gICAgY29uc3QgY29udGV4dCA9IFNvbmFtdS5nZXRDb250ZXh0KCk7XG4gICAgaWYgKCFjb250ZXh0Py5uYWl0ZVN0b3JlKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgY29uc3QgdHJhY2VzID0gQXJyYXkuZnJvbShjb250ZXh0Lm5haXRlU3RvcmUudmFsdWVzKCkpLmZsYXQoKTtcblxuICAgIC8vIOyngeugrO2ZlCDrtojqsIDriqXtlZwg6rCS7J20IOyhtOyerO2VnOuLpOuptCDsnbTrpbwg64yA66y47Ked66eM7ZWY6rKMIOyVjOugpOykjeuLiOuLpCEg6re47LmY66eMIOyVjOumrOq4sOunjCDtlZjqs6Ag6re464OlIOyngOuCmOqwkeuLiOuLpCDjhY7jhY5cbiAgICAvLyDsmZwg7KeB66Cs7ZmU6rCAIOykkeyalO2VnOqwgD8g7J20KGdldEFsbFRyYWNlcykg7Zi47Lac7J2YIOqysOqzvOuKlCDsmbjrtoDroZwg64KY6rCA6rKMIOuQmOuKlOuNsCxcbiAgICAvLyDsnbTrlYwg7KO8IOyaqeuPhOqwgCB2aXRlc3TsnZggdGFzay5tZXRhIO2VhOuTnOulvCDthrXtlbQgYWZ0ZXJFYWNo7JeQ7IScIFNvbmFtdSBleHRlbnNpb27snLzroZwg7KCE64us7ZWY64qUIOqyg+yeheuLiOuLpC5cbiAgICAvLyDsl6zquLDshJwgbWV0YSDtlYTrk5zsl5Ag64u06ri0IOuCtOyaqeydgCDtlITroZzshLjsiqTqsIQg7Ya17IugKHByb2Nlc3Muc2VuZCkg65iQ64qUIOyKpOugiOuTnOqwhCDthrXsi6AobWVzc2FnZSBwb3J0KeydhCDthrXtlbQg7KCE64us65CY7Ja07JW8IO2VmOuKlOuNsCxcbiAgICAvLyDsnbTroZwg7J247ZW0IFwi7KeB66Cs7ZmUIOqwgOuKpe2VnCDqsJLrk6Trp4wg7ZeI7JqpXCLtlZjripQg7KCc7JW97J20IOyDneq5geuLiOuLpC5cbiAgICAvL1xuICAgIC8vIOydtCDsoJzslb3snYQg7J2Y7Iud7ZWY7JesIE5haXRlLnTsl5Ag7KeB66Cs7ZmUIOqwgOuKpe2VnCDqsJLrp4wg64SY6riw6rKMIO2VoCDsiJjrj4Qg7J6I7JeI7KeA66eMLCDqt7jroIfqsowg7ZWY66m0IOu2iO2OuO2VtOyniCDqsoMg6rCZ7JWE7IScIO2VmOyngCDslYrslZjsirXri4jri6QuXG4gICAgLy8g65Sw65287IScIO2YhOyerCBOYWl0ZS5064qUIOuqqOuToCDqsJLsnYQg67Cb7J2EIOyImCDsnojqsowg65CY7Ja0IOyeiOyKteuLiOuLpC5cbiAgICAvLyDrjIDsi6Ag7J2066CH6rKMKGdldEFsbFRyYWNlcykg6re4IOqwkuuTpOydhCDrubzrgrwg65WMIEpTT04uc3RyaW5naWZ566W8IOyCrOyaqe2VmOyXrCDqsJXsoJzroZwg7KeB66Cs7ZmUIOqwgOuKpe2VmOqyjCDrp4zrk6Tsl4jsirXri4jri6QsLFxuICAgIGZvciAoY29uc3QgdHJhY2Ugb2YgdHJhY2VzKSB7XG4gICAgICBjb25zdCBjaGVjayA9IGlzU2VyaWFsaXphYmxlKHRyYWNlLmRhdGEpO1xuICAgICAgaWYgKCFjaGVjay52YWxpZCkge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgXCJcXG5cIiArXG4gICAgICAgICAgICBcIuKVlOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVl1xcblwiICtcbiAgICAgICAgICAgIFwi4pWRICBbTmFpdGVdIE5vbi1zZXJpYWxpemFibGUgdmFsdWUgZGV0ZWN0ZWQhICAgICAgICAgICAgICAgICAgICAgIOKVkVxcblwiICtcbiAgICAgICAgICAgIFwi4pWg4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWjXFxuXCIgK1xuICAgICAgICAgICAgYOKVkSAgS2V5OiAke3RyYWNlLmtleS5wYWRFbmQoNTcpfeKVkVxcbmAgK1xuICAgICAgICAgICAgYOKVkSAgUmVhc29uOiAkeyhjaGVjay5yZWFzb24gPz8gXCJ1bmtub3duXCIpLnNsaWNlKDAsIDU0KS5wYWRFbmQoNTQpfeKVkVxcbmAgK1xuICAgICAgICAgICAgYOKVkSAgTG9jYXRpb246ICR7KHRyYWNlLnN0YWNrWzBdPy5maWxlUGF0aCA/PyBcInVua25vd25cIikuc2xpY2UoLTUxKS5wYWRFbmQoNTIpfeKVkVxcbmAgK1xuICAgICAgICAgICAgYOKVkSAgTGluZTogJHtTdHJpbmcodHJhY2Uuc3RhY2tbMF0/LmxpbmVOdW1iZXIgPz8gMCkucGFkRW5kKDU2KX3ilZFcXG5gICtcbiAgICAgICAgICAgIFwi4pWg4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWjXFxuXCIgK1xuICAgICAgICAgICAgXCLilZEgIE5haXRlLnQoKSBhY2NlcHRzIGFueSB0eXBlIG9mIHZhbHVlLiBIb3dldmVyLCB2YWx1ZXMgd2lsbCAgICAg4pWRXFxuXCIgK1xuICAgICAgICAgICAgXCLilZEgIGJlIHNlcmlhbGl6ZWQgdG8gSlNPTiB3aGVuIGV4cG9ydGVkIHZpYSBOYWl0ZS5nZXRBbGxUcmFjZXMoKS4g4pWRXFxuXCIgK1xuICAgICAgICAgICAgXCLilZrilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZ1cXG5cIixcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJhY2VzLm1hcCgodHJhY2UpID0+ICh7XG4gICAgICBrZXk6IHRyYWNlLmtleSxcbiAgICAgIHZhbHVlOiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRyYWNlLmRhdGEgPz8gXCJcIikpLCAvLyDsp4HroKztmZQg6rCA64ql7ZWcIOqyg+unjCDrgqjquLDroKTripQg64iI66y86rKo7Jq0IOuFuOugpSwsIOyViOq3uOufrOuptCB0YXNrLm1ldGHsl5Ag65Ok7Ja06rCA7IScIO2UhOuhnOyEuOyKpOqwhCDthrXsi6Ag7ZWgIOuVjCDrrLjsoJwg7IOd6riw6rGw65Og7JqULCxcbiAgICAgIGZpbGVQYXRoOiB0cmFjZS5zdGFja1swXT8uZmlsZVBhdGggPz8gXCJcIixcbiAgICAgIGxpbmVOdW1iZXI6IHRyYWNlLnN0YWNrWzBdPy5saW5lTnVtYmVyID8/IDAsXG4gICAgICBhdDogdHJhY2UuYXQudG9JU09TdHJpbmcoKSxcbiAgICB9KSk7XG4gIH1cblxuICAvLyDtirnsoJUg7YKkIOyCreygnO2VmOq4sFxuICBkZWwoa2V5OiBzdHJpbmcpIHtcbiAgICBjb25zdCBjb250ZXh0ID0gU29uYW11LmdldENvbnRleHQoKTtcbiAgICBpZiAoIWNvbnRleHQ/Lm5haXRlU3RvcmUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29udGV4dC5uYWl0ZVN0b3JlLmRlbGV0ZShrZXkpO1xuICB9XG5cbiAgY3JlYXRlU3RvcmUoKTogTmFpdGVTdG9yZSB7XG4gICAgcmV0dXJuIG5ldyBNYXA8c3RyaW5nLCBOYWl0ZVRyYWNlW10+KCk7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IE5haXRlID0gbmV3IE5haXRlQ2xhc3MoKTtcbiJdLCJuYW1lcyI6WyJnZXRMb2dnZXIiLCJnZXQiLCJTb25hbXUiLCJjb252ZXJ0TmFpdGVLZXlUb0NhdGVnb3J5IiwiaXNTZXJpYWxpemFibGUiLCJleHRyYWN0Q2FsbFN0YWNrIiwic3RhY2siLCJFcnJvciIsImxpbmVzIiwic3BsaXQiLCJmcmFtZXMiLCJzbGljZSIsIm1hcCIsInBhcnNlU3RhY2tGcmFtZSIsImZpbHRlciIsImZyYW1lIiwiY29udGV4dEluZGV4IiwiZmluZEluZGV4IiwiZiIsImZ1bmN0aW9uTmFtZSIsImluY2x1ZGVzIiwibGluZSIsIm1hdGNoV2l0aEZ1bmMiLCJtYXRjaCIsImZpbGVQYXRoIiwibGluZU51bWJlclN0ciIsImxpbmVOdW1iZXIiLCJOdW1iZXIiLCJwYXJzZUludCIsIm1hdGNoTm9GdW5jIiwibWF0Y2hlc1BhdHRlcm4iLCJrZXkiLCJwYXR0ZXJuIiwia2V5UGFydHMiLCJwYXR0ZXJuUGFydHMiLCJsZW5ndGgiLCJwcmVmaXhQYXJ0cyIsImV2ZXJ5IiwicGFydCIsImkiLCJOYWl0ZVF1ZXJ5IiwidHJhY2VzIiwiZnJvbUZpbGUiLCJmaWxlTmFtZSIsImZpbHRlcmVkIiwidCIsInNvbWUiLCJlbmRzV2l0aCIsImZyb21GdW5jdGlvbiIsImZ1bmNOYW1lIiwib3B0aW9ucyIsImZyb20iLCJ3aGVyZSIsInBhdGgiLCJvcGVyYXRvciIsInZhbHVlIiwidHJhY2UiLCJhY3R1YWwiLCJyZXN1bHQiLCJkYXRhIiwiZmlyc3QiLCJsYXN0IiwiYXQiLCJpbmRleCIsImdldFRyYWNlcyIsIk5haXRlQ2xhc3MiLCJuYW1lIiwicHJvY2VzcyIsImVudiIsIk5PREVfRU5WIiwiY29udGV4dCIsImdldENvbnRleHQiLCJzdG9yZSIsIm5haXRlU3RvcmUiLCJEYXRlIiwiZXhpc3RpbmciLCJkZWJ1ZyIsInNldCIsImtleVBhdHRlcm4iLCJhbGxUcmFjZXMiLCJlbnRyaWVzIiwicHVzaCIsImdldEFsbCIsInN0YXJ0c1dpdGgiLCJnZXRBbGxUcmFjZXMiLCJBcnJheSIsInZhbHVlcyIsImZsYXQiLCJjaGVjayIsInZhbGlkIiwiY29uc29sZSIsIndhcm4iLCJwYWRFbmQiLCJyZWFzb24iLCJTdHJpbmciLCJKU09OIiwicGFyc2UiLCJzdHJpbmdpZnkiLCJ0b0lTT1N0cmluZyIsImRlbCIsImRlbGV0ZSIsImNyZWF0ZVN0b3JlIiwiTWFwIiwiTmFpdGUiXSwibWFwcGluZ3MiOiJBQUFBLGtGQUFrRixHQUVsRixTQUFTQSxTQUFTLFFBQVEsbUJBQW1CO0FBQzdDLFNBQVNDLEdBQUcsUUFBUSxVQUFVO0FBQzlCLFNBQVNDLE1BQU0sUUFBUSxtQkFBZ0I7QUFFdkMsU0FBU0MseUJBQXlCLFFBQVEsd0JBQXFCO0FBQy9ELFNBQVNDLGNBQWMsUUFBUSwyQkFBd0I7QUE4QnZEOzs7OztDQUtDLEdBQ0QsU0FBU0M7SUFDUCxNQUFNQyxRQUFRLElBQUlDLFFBQVFELEtBQUs7SUFDL0IsSUFBSSxDQUFDQSxPQUFPLE9BQU8sRUFBRTtJQUVyQixNQUFNRSxRQUFRRixNQUFNRyxLQUFLLENBQUM7SUFFMUIsVUFBVTtJQUNWLGVBQWU7SUFDZiw2QkFBNkI7SUFDN0Isb0JBQW9CO0lBQ3BCLHFCQUFxQjtJQUNyQixNQUFNQyxTQUFTRixNQUNaRyxLQUFLLENBQUMsR0FDTkMsR0FBRyxDQUFDQyxpQkFDSkMsTUFBTSxDQUFDLENBQUNDLFFBQStCQSxVQUFVO0lBRXBELG9DQUFvQztJQUNwQyxNQUFNQyxlQUFlTixPQUFPTyxT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
271
+ //#endregion
272
+ init_naite();
273
+ export { Naite, NaiteClass, NaiteQuery, init_naite };
274
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFpdGUuanMiLCJuYW1lcyI6WyJ0cmFjZXM6IE5haXRlVHJhY2VbXSIsInRyYWNlOiBOYWl0ZVRyYWNlIiwiYWxsVHJhY2VzOiBOYWl0ZVRyYWNlW10iLCJyZXN1bHQ6IHsgW2tleTogc3RyaW5nXTogYW55IH0iXSwic291cmNlcyI6WyIuLi8uLi9zcmMvbmFpdGUvbmFpdGUudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyogb3hsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSAqLyAvLyBOYWl0ZeuKlCBleHBlY3TsmYAg7Zi47J2R7ZWY64+E66GdIGFueeulvCDtl4jsmqntlahcblxuaW1wb3J0IHsgZ2V0TG9nZ2VyIH0gZnJvbSBcIkBsb2d0YXBlL2xvZ3RhcGVcIjtcbmltcG9ydCB7IGdldCB9IGZyb20gXCJyYWRhc2hpXCI7XG5cbmltcG9ydCB7IFNvbmFtdSB9IGZyb20gXCIuLi9hcGkvc29uYW11XCI7XG5pbXBvcnQgeyB0eXBlIENvbXBhcmlzb25PcGVyYXRvciB9IGZyb20gXCIuLi9kYXRhYmFzZS9wdXJpLnR5cGVzXCI7XG5pbXBvcnQgeyBjb252ZXJ0TmFpdGVLZXlUb0NhdGVnb3J5IH0gZnJvbSBcIi4uL2xvZ2dlci9jYXRlZ29yeVwiO1xuaW1wb3J0IHsgaXNTZXJpYWxpemFibGUgfSBmcm9tIFwiLi4vdXRpbHMvb2JqZWN0LXV0aWxzXCI7XG5cbi8vIFN0YWNrRnJhbWUg7YOA7J6FXG5pbnRlcmZhY2UgU3RhY2tGcmFtZSB7XG4gIGZ1bmN0aW9uTmFtZTogc3RyaW5nIHwgbnVsbDtcbiAgZmlsZVBhdGg6IHN0cmluZzsgLy8gXCIvVXNlcnMvLi4uL3N5bmNlci50c1wiIOuYkOuKlCBcIm5vZGU6aW50ZXJuYWwvLi4uXCJcbiAgbGluZU51bWJlcjogbnVtYmVyOyAvLyBUUyDtjIzsnbwg6riw7KSAIOudvOyduCDrsojtmLhcbn1cblxuLy8gTmFpdGVUcmFjZSDtg4DsnoVcbmludGVyZmFjZSBOYWl0ZVRyYWNlIHtcbiAga2V5OiBzdHJpbmc7XG4gIGRhdGE6IGFueTtcbiAgc3RhY2s6IFN0YWNrRnJhbWVbXTsgLy8g7L2c7Iqk7YOdIOygleuztFxuICBhdDogRGF0ZTtcbn1cblxuLy8gTmFpdGUudOqwgCDsoIDsnqXrkJjripQg7YOA7J6FICjtla3sg4Eg67Cw7Je066GcIO2GteydvClcbmV4cG9ydCB0eXBlIE5haXRlU3RvcmUgPSBNYXA8c3RyaW5nLCBOYWl0ZVRyYWNlW10+O1xuXG4vLyBnZXRBbGxUcmFjZXMoKeqwgCDrsJjtmZjtlZjripQg7KeB66Cs7ZmU65CcIHRyYWNlIO2DgOyehVxuLy8gYm9vdHN0cmFwLnRz7J2YIFRhc2tNZXRhIGF1Z21lbnRhdGlvbiwgZGV2LXZpdGVzdC1tYW5hZ2VyLnRz7JeQ7ISc64+EIOydtCDtg4DsnoXsnYQg6rO17Jyg7ZWp64uI64ukLlxuZXhwb3J0IHR5cGUgU2VyaWFsaXplZFRyYWNlID0ge1xuICBrZXk6IHN0cmluZztcbiAgdmFsdWU6IGFueTtcbiAgZmlsZVBhdGg6IHN0cmluZztcbiAgbGluZU51bWJlcjogbnVtYmVyO1xuICBhdDogc3RyaW5nO1xufTtcblxuLyoqXG4gKiDsvZzsiqTtg53snYQg7YyM7Iux7ZWY7JesIFN0YWNrRnJhbWUg67Cw7Je066GcIOuwmO2ZmFxuICogLSBleHRyYWN0Q2FsbFN0YWNrIOyekOyLoOqzvCBOYWl0ZS5064qUIOygnOyZuFxuICogLSBydW5XaXRoQ29udGV4dC9ydW5XaXRoTW9ja0NvbnRleHQg67Cc6rKsIOyLnCDqsbDquLDshJwg7KKF66OMXG4gKiAtIG5vZGU6IOuCtOu2gCDqsr3roZzripQg7Y+s7ZWo7ZWY65CYLCBsaW5lTnVtYmVy64qUIHBhdGjsl5AgOiDtj6ztlagg7IucIOu2meydtOyngCDslYrsnYxcbiAqL1xuZnVuY3Rpb24gZXh0cmFjdENhbGxTdGFjaygpOiBTdGFja0ZyYW1lW10ge1xuICBjb25zdCBzdGFjayA9IG5ldyBFcnJvcigpLnN0YWNrO1xuICBpZiAoIXN0YWNrKSByZXR1cm4gW107XG5cbiAgY29uc3QgbGluZXMgPSBzdGFjay5zcGxpdChcIlxcblwiKTtcblxuICAvLyDsvZzsiqTtg50g6rWs7KGwOlxuICAvLyBbMF06IFwiRXJyb3JcIlxuICAvLyBbMV06IFwiYXQgZXh0cmFjdENhbGxTdGFja1wiXG4gIC8vIFsyXTogXCJhdCBOYWl0ZS50XCJcbiAgLy8gWzNdOiDsi6TsoJwg7Zi47LacIOychOy5mOu2gO2EsCDsi5zsnpFcbiAgY29uc3QgZnJhbWVzID0gbGluZXNcbiAgICAuc2xpY2UoMylcbiAgICAubWFwKHBhcnNlU3RhY2tGcmFtZSlcbiAgICAuZmlsdGVyKChmcmFtZSk6IGZyYW1lIGlzIFN0YWNrRnJhbWUgPT4gZnJhbWUgIT09IG51bGwpO1xuXG4gIC8vIHJ1bldpdGhDb250ZXh0IOqzhOyXtCDtlajsiJgg67Cc6rKsIOyLnCDqsbDquLDshJwg7J6Q66W06riwXG4gIGNvbnN0IGNvbnRleHRJbmRleCA9IGZyYW1lcy5maW5kSW5kZXgoXG4gICAgKGYpID0+XG4gICAgICBmLmZ1bmN0aW9uTmFtZT8uaW5jbHVkZXMoXCJydW5XaXRoQ29udGV4dFwiKSB8fCBmLmZ1bmN0aW9uTmFtZT8uaW5jbHVkZXMoXCJydW5XaXRoTW9ja0NvbnRleHRcIiksXG4gICk7XG5cbiAgcmV0dXJuIGNvbnRleHRJbmRleCA+PSAwID8gZnJhbWVzLnNsaWNlKDAsIGNvbnRleHRJbmRleCArIDEpIDogZnJhbWVzO1xufVxuXG4vKipcbiAqIOy9nOyKpO2DnSDtlZwg7KSE7J2EIO2MjOyLsVxuICog7ZiV7IudMTogXCJhdCBGdW5jdGlvbk5hbWUgKGZpbGVQYXRoOmxpbmVOdW1iZXI6Y29sdW1uTnVtYmVyKVwiXG4gKiDtmJXsi50yOiBcImF0IGZpbGVQYXRoOmxpbmVOdW1iZXI6Y29sdW1uTnVtYmVyXCIgKOydteuqhSDtlajsiJgv66qo65OIIOugiOuyqClcbiAqL1xuZnVuY3Rpb24gcGFyc2VTdGFja0ZyYW1lKGxpbmU6IHN0cmluZyk6IFN0YWNrRnJhbWUgfCBudWxsIHtcbiAgLy8g7Yyo7YS0MTogXCJhdCBGdW5jdGlvbk5hbWUgKGZpbGVQYXRoOmxpbmVOdW1iZXI6Y29sdW1uTnVtYmVyKVwiXG4gIGNvbnN0IG1hdGNoV2l0aEZ1bmMgPSBsaW5lLm1hdGNoKC9hdFxccysoLis/KVxccytcXCgoLis/KTooXFxkKyk6XFxkK1xcKS8pO1xuICBpZiAobWF0Y2hXaXRoRnVuYykge1xuICAgIGNvbnN0IGZ1bmN0aW9uTmFtZSA9IG1hdGNoV2l0aEZ1bmNbMV07XG4gICAgY29uc3QgZmlsZVBhdGggPSBtYXRjaFdpdGhGdW5jWzJdO1xuICAgIGNvbnN0IGxpbmVOdW1iZXJTdHIgPSBtYXRjaFdpdGhGdW5jWzNdO1xuXG4gICAgLy8gZmlsZVBhdGjsl5Ag7J2066+4IDrqsIAg7Y+s7ZWo65CY7Ja0IOyeiOycvOuptCAo7JiIOiBcIm5vZGU6aW50ZXJuYWwvLi4uXCIpXG4gICAgaWYgKGZpbGVQYXRoLmluY2x1ZGVzKFwiOlwiKSkge1xuICAgICAgcmV0dXJuIHsgZnVuY3Rpb25OYW1lLCBmaWxlUGF0aCwgbGluZU51bWJlcjogMCB9O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBmdW5jdGlvbk5hbWUsXG4gICAgICBmaWxlUGF0aCxcbiAgICAgIGxpbmVOdW1iZXI6IE51bWJlci5wYXJzZUludChsaW5lTnVtYmVyU3RyLCAxMCksXG4gICAgfTtcbiAgfVxuXG4gIC8vIO2MqO2EtDI6IFwiYXQgZmlsZVBhdGg6bGluZU51bWJlcjpjb2x1bW5OdW1iZXJcIiAo7ZWo7IiY66qFIOyXhuydjClcbiAgY29uc3QgbWF0Y2hOb0Z1bmMgPSBsaW5lLm1hdGNoKC9hdFxccysoLis/KTooXFxkKyk6XFxkKyQvKTtcbiAgaWYgKG1hdGNoTm9GdW5jKSB7XG4gICAgY29uc3QgZmlsZVBhdGggPSBtYXRjaE5vRnVuY1sxXTtcbiAgICBjb25zdCBsaW5lTnVtYmVyU3RyID0gbWF0Y2hOb0Z1bmNbMl07XG5cbiAgICByZXR1cm4ge1xuICAgICAgZnVuY3Rpb25OYW1lOiBudWxsLFxuICAgICAgZmlsZVBhdGgsXG4gICAgICBsaW5lTnVtYmVyOiBOdW1iZXIucGFyc2VJbnQobGluZU51bWJlclN0ciwgMTApLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiB3aWxkY2FyZCDtjKjthLQg66ek7LmtXG4gKiDsmIjsi5w6XG4gKiAtIFwic3luY2VyOipcIiDihpIgXCJzeW5jZXI6YVwiLCBcInN5bmNlcjphOmJcIiDrqqjrkZAg66ek7LmtXG4gKiAtIFwic3luY2VyOio6dXNlclwiIOKGkiBcInN5bmNlcjpyZW5kZXJUZW1wbGF0ZTp1c2VyXCIg66ek7LmtXG4gKiAtIFwic3luY2VyOnJlbmRlclRlbXBsYXRlOipcIiDihpIgXCJzeW5jZXI6cmVuZGVyVGVtcGxhdGU6c2VydmljZVwiIOunpOy5rVxuICovXG5mdW5jdGlvbiBtYXRjaGVzUGF0dGVybihrZXk6IHN0cmluZywgcGF0dGVybjogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IGtleVBhcnRzID0ga2V5LnNwbGl0KFwiOlwiKTtcbiAgY29uc3QgcGF0dGVyblBhcnRzID0gcGF0dGVybi5zcGxpdChcIjpcIik7XG5cbiAgLy8g66eI7KeA66eJ7J20ICog4oaSIHByZWZpeCDrp6Tsua0gKOq4uOydtCDrrLTqtIApXG4gIC8vIOyYiDogXCJzeW5jZXI6Klwi64qUIFwic3luY2VyOmFcIiwgXCJzeW5jZXI6YTpiXCIg66qo65GQIOunpOy5rVxuICBpZiAocGF0dGVyblBhcnRzW3BhdHRlcm5QYXJ0cy5sZW5ndGggLSAxXSA9PT0gXCIqXCIpIHtcbiAgICBjb25zdCBwcmVmaXhQYXJ0cyA9IHBhdHRlcm5QYXJ0cy5zbGljZSgwLCAtMSk7XG4gICAgLy8gcHJlZml46rCAIOuqqOuRkCDsnbzsuZjtlZjripTsp4Ag7ZmV7J24XG4gICAgcmV0dXJuIHByZWZpeFBhcnRzLmV2ZXJ5KChwYXJ0LCBpKSA9PiBwYXJ0ID09PSBrZXlQYXJ0c1tpXSk7XG4gIH1cblxuICAvLyDquLjsnbTqsIAg6rCZ7JWE7JW8IO2VqFxuICBpZiAocGF0dGVyblBhcnRzLmxlbmd0aCAhPT0ga2V5UGFydHMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8g6rCBIO2MjO2KuOqwgCAqIOuYkOuKlCDsoJXtmZXtnogg7J287LmYXG4gIHJldHVybiBwYXR0ZXJuUGFydHMuZXZlcnkoKHBhcnQsIGkpID0+IHBhcnQgPT09IFwiKlwiIHx8IHBhcnQgPT09IGtleVBhcnRzW2ldKTtcbn1cblxuLyoqXG4gKiBOYWl0ZVF1ZXJ5IO2BtOuemOyKpFxuICog7LK07J2064ud7J2EIO2Gte2VnCB0cmFjZSDtlYTthLDrp4Eg67CPIOyhsO2ajFxuICovXG5leHBvcnQgY2xhc3MgTmFpdGVRdWVyeSB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgdHJhY2VzOiBOYWl0ZVRyYWNlW10pIHt9XG5cbiAgcHJpdmF0ZSBpc0NvbXBhcmFibGVWYWx1ZSh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIG51bWJlciB8IHN0cmluZyB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIiB8fCB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCI7XG4gIH1cblxuICAvKipcbiAgICog7YyM7J2866qF7Jy866GcIO2VhO2EsOungVxuICAgKiBAcGFyYW0gZmlsZU5hbWUg7YyM7J2866qFICjsmIg6IFwic3luY2VyLnRlc3QudHNcIilcbiAgICovXG4gIGZyb21GaWxlKGZpbGVOYW1lOiBzdHJpbmcpOiBOYWl0ZVF1ZXJ5IHtcbiAgICBjb25zdCBmaWx0ZXJlZCA9IHRoaXMudHJhY2VzLmZpbHRlcigodCkgPT5cbiAgICAgIHQuc3RhY2suc29tZSgoZnJhbWUpID0+IGZyYW1lLmZpbGVQYXRoLmVuZHNXaXRoKGAvJHtmaWxlTmFtZX1gKSksXG4gICAgKTtcbiAgICByZXR1cm4gbmV3IE5haXRlUXVlcnkoZmlsdGVyZWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VqOyImOuqheycvOuhnCDtlYTthLDrp4FcbiAgICogQHBhcmFtIGZ1bmNOYW1lIO2VqOyImOuqhSAoaW5jbHVkZXMg7LK07YGsKVxuICAgKiBAcGFyYW0gb3B0aW9ucy5mcm9tICdkaXJlY3QnID0g7KeB7KCRIO2YuOy2nOunjCwgJ2luZGlyZWN0JyA9IOqwhOygkSDtmLjstpzrp4wsICdib3RoJyA9IOuqqOuRkFxuICAgKi9cbiAgZnJvbUZ1bmN0aW9uKFxuICAgIGZ1bmNOYW1lOiBzdHJpbmcsXG4gICAgb3B0aW9uczogeyBmcm9tOiBcImRpcmVjdFwiIHwgXCJpbmRpcmVjdFwiIHwgXCJib3RoXCIgfSA9IHsgZnJvbTogXCJib3RoXCIgfSxcbiAgKTogTmFpdGVRdWVyeSB7XG4gICAgY29uc3QgZmlsdGVyZWQgPSB0aGlzLnRyYWNlcy5maWx0ZXIoKHQpID0+IHtcbiAgICAgIGlmIChvcHRpb25zLmZyb20gPT09IFwiZGlyZWN0XCIpIHtcbiAgICAgICAgLy8gc3RhY2tbMF3rp4wg7ZmV7J24ICjsp4HsoJEg7Zi47LacKVxuICAgICAgICByZXR1cm4gdC5zdGFja1swXT8uZnVuY3Rpb25OYW1lPy5pbmNsdWRlcyhmdW5jTmFtZSk7XG4gICAgICB9XG4gICAgICBpZiAob3B0aW9ucy5mcm9tID09PSBcImluZGlyZWN0XCIpIHtcbiAgICAgICAgLy8gc3RhY2tbMStd7JeQ7IScIO2ZleyduCAo6rCE7KCRIO2YuOy2nClcbiAgICAgICAgcmV0dXJuIHQuc3RhY2suc2xpY2UoMSkuc29tZSgoZikgPT4gZi5mdW5jdGlvbk5hbWU/LmluY2x1ZGVzKGZ1bmNOYW1lKSk7XG4gICAgICB9XG4gICAgICAvLyDsoITssrQg7Iqk7YOd7JeQ7IScIO2ZleyduFxuICAgICAgcmV0dXJuIHQuc3RhY2suc29tZSgoZikgPT4gZi5mdW5jdGlvbk5hbWU/LmluY2x1ZGVzKGZ1bmNOYW1lKSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIG5ldyBOYWl0ZVF1ZXJ5KGZpbHRlcmVkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDrjbDsnbTthLAg6rK966GcIOq4sOuwmCDtlYTthLDrp4FcbiAgICogQHBhcmFtIHBhdGggcmFkYXNoIGdldCDqsr3roZwgKOyYiDogXCJkYXRhLnVzZXJJZFwiKVxuICAgKiBAcGFyYW0gb3BlcmF0b3Ig67mE6rWQIOyXsOyCsOyekFxuICAgKiBAcGFyYW0gdmFsdWUg67mE6rWQ6rCSXG4gICAqL1xuICB3aGVyZShwYXRoOiBzdHJpbmcsIG9wZXJhdG9yOiBDb21wYXJpc29uT3BlcmF0b3IgfCBcImluY2x1ZGVzXCIsIHZhbHVlOiBhbnkpOiBOYWl0ZVF1ZXJ5IHtcbiAgICBjb25zdCBmaWx0ZXJlZCA9IHRoaXMudHJhY2VzLmZpbHRlcigodHJhY2UpID0+IHtcbiAgICAgIGNvbnN0IGFjdHVhbCA9IGdldCh0cmFjZSwgcGF0aCk7XG5cbiAgICAgIHN3aXRjaCAob3BlcmF0b3IpIHtcbiAgICAgICAgY2FzZSBcIj5cIjpcbiAgICAgICAgICByZXR1cm4gdGhpcy5pc0NvbXBhcmFibGVWYWx1ZShhY3R1YWwpICYmIHRoaXMuaXNDb21wYXJhYmxlVmFsdWUodmFsdWUpICYmIGFjdHVhbCA+IHZhbHVlO1xuICAgICAgICBjYXNlIFwiPFwiOlxuICAgICAgICAgIHJldHVybiB0aGlzLmlzQ29tcGFyYWJsZVZhbHVlKGFjdHVhbCkgJiYgdGhpcy5pc0NvbXBhcmFibGVWYWx1ZSh2YWx1ZSkgJiYgYWN0dWFsIDwgdmFsdWU7XG4gICAgICAgIGNhc2UgXCI+PVwiOlxuICAgICAgICAgIHJldHVybiB0aGlzLmlzQ29tcGFyYWJsZVZhbHVlKGFjdHVhbCkgJiYgdGhpcy5pc0NvbXBhcmFibGVWYWx1ZSh2YWx1ZSkgJiYgYWN0dWFsID49IHZhbHVlO1xuICAgICAgICBjYXNlIFwiPD1cIjpcbiAgICAgICAgICByZXR1cm4gdGhpcy5pc0NvbXBhcmFibGVWYWx1ZShhY3R1YWwpICYmIHRoaXMuaXNDb21wYXJhYmxlVmFsdWUodmFsdWUpICYmIGFjdHVhbCA8PSB2YWx1ZTtcbiAgICAgICAgY2FzZSBcIj1cIjpcbiAgICAgICAgICByZXR1cm4gYWN0dWFsID09PSB2YWx1ZTtcbiAgICAgICAgY2FzZSBcIiE9XCI6XG4gICAgICAgICAgcmV0dXJuIGFjdHVhbCAhPT0gdmFsdWU7XG4gICAgICAgIGNhc2UgXCJpbmNsdWRlc1wiOlxuICAgICAgICAgIHJldHVybiB0eXBlb2YgYWN0dWFsID09PSBcInN0cmluZ1wiICYmIGFjdHVhbC5pbmNsdWRlcyh2YWx1ZSk7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBuZXcgTmFpdGVRdWVyeShmaWx0ZXJlZCk7XG4gIH1cblxuICAvKipcbiAgICog7KCE7LK0IOuNsOydtO2EsCDrsLDsl7Qg67CY7ZmYXG4gICAqL1xuICByZXN1bHQoKTogYW55W10ge1xuICAgIHJldHVybiB0aGlzLnRyYWNlcy5tYXAoKHQpID0+IHQuZGF0YSk7XG4gIH1cblxuICAvKipcbiAgICog7LKrIOuyiOynuCDrjbDsnbTthLAg67CY7ZmYXG4gICAqL1xuICBmaXJzdCgpOiBhbnkgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnRyYWNlc1swXT8uZGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiDrp4jsp4Drp4kg642w7J207YSwIOuwmO2ZmFxuICAgKi9cbiAgbGFzdCgpOiBhbnkgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnRyYWNlc1t0aGlzLnRyYWNlcy5sZW5ndGggLSAxXT8uZGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiBu67KI7Ke4IOuNsOydtO2EsCDrsJjtmZhcbiAgICovXG4gIGF0KGluZGV4OiBudW1iZXIpOiBhbnkgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnRyYWNlc1tpbmRleF0/LmRhdGE7XG4gIH1cblxuICAvKipcbiAgICog7JuQ67O4IHRyYWNlIOuwsOyXtCDrsJjtmZggKOuUlOuyhOq5hS9OYWl0ZVZpZXdlcuyaqSlcbiAgICovXG4gIGdldFRyYWNlcygpOiBOYWl0ZVRyYWNlW10ge1xuICAgIHJldHVybiB0aGlzLnRyYWNlcztcbiAgfVxufVxuXG4vLyBOYWl0ZSDsi7HquIDthLQg6rCd7LK0ICjstpTtm4QgbG9nZ2VyIOyXsOqysCDrk7HsnZgg7IOB7YOcIOq0gOumrCDtlYTsmpTshLEg6rOg66CkKVxuZXhwb3J0IGNsYXNzIE5haXRlQ2xhc3Mge1xuICAvLyDthYzsiqTtirgg66Gc6re4IOq4sOuhnVxuICB0KFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICB2YWx1ZTogYW55IC8q7J2066CH6rKMIOuwm+ydgCDqsJLsnbQgTmFpdGVUcmFjZeuhnCDsoIDsnqXrkJjslrQg7J6I64uk6rCAIOy2lO2bhOyXkCB2aXRlc3Tsl5DqsowgbWV0YeulvCDthrXtlbQg64SY6rKo7KC4IO2UhOuhnOyEuOyKpOqwhCDthrXsi6DsnYQg7Ya17ZW0IOyngeugrO2ZlOuQmOyWtOyVvCDtlZjripQg7KCQ7J2EIOqzoOugpO2VmOyYgOydhCDrlYwg7Jes6riw7JeQIFNlcmlhbGl6YWJsZeydhCDsjajshJwg7KCc7ZWc7J2EIOuRmCDsiJjrj4Qg7J6I7KeA66eMLCDsgqzsmqnsg4HsnZgg7Y647J2Y66W8IOyDneqwge2VmOyXrCBhbnnroZwg67Cb7Iq164uI64ukLiovLFxuICApIHtcbiAgICAvLyDsnbQgdCDtlajsiJjripQg7YWM7Iqk7Yq4IO2ZmOqyveyXkOyEnOunjCDsnpHrj5ntlbTslbwg7ZWp64uI64ukLlxuICAgIC8vIOq3uOumrOqzoCDthYzsiqTtirgg7ZmY6rK9IO2MkOuLqOyXkCDsmZwgaXNUZXN0KCkg7ZWo7IiY66W8IOyCrOyaqe2VmOyngCDslYrslZjrg5DrqbTsmpQsLFxuICAgIC8vIOydtOugh+qyjCDtlZjripTqsowg7Jyg7Yu4IO2VqOyImCDrtojrn6zsmYDshJwg7IKs7Jqp7ZWY64qUIOqyg+uztOuLpCDsobDquIjsnbTrgpjrp4gg67mg66W8IOqygyDqsJnslZjquLAg65WM66y47J6F64uI64ukLlxuICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gXCJ0ZXN0XCIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgY29udGV4dCA9IFNvbmFtdS5nZXRDb250ZXh0KCk7XG4gICAgICBjb25zdCBzdG9yZSA9IGNvbnRleHQ/Lm5haXRlU3RvcmU7XG5cbiAgICAgIGlmICghc3RvcmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyDsvZzsiqTtg50g7IiY7KeRXG4gICAgICBjb25zdCBzdGFjayA9IGV4dHJhY3RDYWxsU3RhY2soKTtcblxuICAgICAgY29uc3QgdHJhY2U6IE5haXRlVHJhY2UgPSB7XG4gICAgICAgIGtleTogbmFtZSxcbiAgICAgICAgZGF0YTogdmFsdWUsXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBhdDogbmV3IERhdGUoKSxcbiAgICAgIH07XG5cbiAgICAgIC8vIO2VreyDgSDrsLDsl7TroZwg6rSA66asXG4gICAgICBjb25zdCBleGlzdGluZyA9IHN0b3JlLmdldChuYW1lKSA/PyBbXTtcbiAgICAgIGdldExvZ2dlcihbXCJuYWl0ZVwiLCAuLi5jb252ZXJ0TmFpdGVLZXlUb0NhdGVnb3J5KG5hbWUpXSkuZGVidWcoXG4gICAgICAgIGBuYWl0ZToge25hbWV9ICR7ZXhpc3RpbmcubGVuZ3RoID09PSAwID8gXCJpcyBlbXB0eSBzdGF0ZVwiIDogYGFscmVhZHkgZXhpc3Rpbmcgd2l0aCAke2V4aXN0aW5nLmxlbmd0aH0gZW50cmllc2B9LCBhcHBlbmRpbmcgbmV3IGVudHJ5YCxcbiAgICAgICAge1xuICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgdmFsdWUsXG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICBzdG9yZS5zZXQobmFtZSwgWy4uLmV4aXN0aW5nLCB0cmFjZV0pO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gQ29udGV4dCDsl4bripQg7IOB7Zmp7JeQ7IScIE5haXRlLnQg7Zi47LacXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIGtleSDrmJDripQgd2lsZGNhcmQg7Yyo7YS07Jy866GcIHRyYWNlIOyhsO2ajFxuICAgKiDtla3sg4EgTmFpdGVRdWVyeSDrsJjtmZjtlZjsl6wg7LK07J2064udIOqwgOuKpVxuICAgKi9cbiAgZ2V0KGtleVBhdHRlcm46IHN0cmluZyk6IE5haXRlUXVlcnkge1xuICAgIGNvbnN0IGNvbnRleHQgPSBTb25hbXUuZ2V0Q29udGV4dCgpO1xuICAgIGNvbnN0IHN0b3JlID0gY29udGV4dD8ubmFpdGVTdG9yZTtcblxuICAgIGlmICghc3RvcmUpIHtcbiAgICAgIHJldHVybiBuZXcgTmFpdGVRdWVyeShbXSk7XG4gICAgfVxuXG4gICAgLy8gd2lsZGNhcmQg7JeG7Jy866m0IGV4YWN0IG1hdGNoXG4gICAgaWYgKCFrZXlQYXR0ZXJuLmluY2x1ZGVzKFwiKlwiKSkge1xuICAgICAgY29uc3QgdHJhY2VzID0gc3RvcmUuZ2V0KGtleVBhdHRlcm4pID8/IFtdO1xuICAgICAgcmV0dXJuIG5ldyBOYWl0ZVF1ZXJ5KHRyYWNlcyk7XG4gICAgfVxuXG4gICAgLy8gd2lsZGNhcmQg7Yyo7YS0IOunpOy5rVxuICAgIGNvbnN0IGFsbFRyYWNlczogTmFpdGVUcmFjZVtdID0gW107XG4gICAgZm9yIChjb25zdCBba2V5LCB0cmFjZXNdIG9mIHN0b3JlLmVudHJpZXMoKSkge1xuICAgICAgaWYgKG1hdGNoZXNQYXR0ZXJuKGtleSwga2V5UGF0dGVybikpIHtcbiAgICAgICAgYWxsVHJhY2VzLnB1c2goLi4udHJhY2VzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IE5haXRlUXVlcnkoYWxsVHJhY2VzKTtcbiAgfVxuXG4gIC8vIOyghOyytCDrpqzsiqTtirgg6rCA7KC47Jik6riwXG4gIGdldEFsbCgpOiB7IFtrZXk6IHN0cmluZ106IGFueSB9IHtcbiAgICBjb25zdCBjb250ZXh0ID0gU29uYW11LmdldENvbnRleHQoKTtcbiAgICBpZiAoIWNvbnRleHQ/Lm5haXRlU3RvcmUpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgLy8gTmFpdGVUcmFjZSDrsLDsl7TsnYQgZGF0YeunjCDstpTstpztlZjsl6wg67CY7ZmYXG4gICAgY29uc3QgcmVzdWx0OiB7IFtrZXk6IHN0cmluZ106IGFueSB9ID0ge307XG4gICAgZm9yIChjb25zdCBba2V5LCB0cmFjZXNdIG9mIGNvbnRleHQubmFpdGVTdG9yZS5lbnRyaWVzKCkpIHtcbiAgICAgIGlmIChrZXkuc3RhcnRzV2l0aChcIm1vY2s6XCIpKSB7XG4gICAgICAgIC8vIE1vY2sg7ISk7KCV7J2AIOq3uOuMgOuhnCDrsJjtmZhcbiAgICAgICAgcmVzdWx0W2tleV0gPSB0cmFjZXM7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBOYWl0ZVRyYWNlIOuwsOyXtOydgCBkYXRh66eMIOy2lOy2nFxuICAgICAgICByZXN1bHRba2V5XSA9IHRyYWNlcy5tYXAoKHQ6IE5haXRlVHJhY2UpID0+IHQuZGF0YSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICog7Iqk7Yag7Ja07JeQIOuTpOyWtOyeiOuNmCDtirjroIjsnbTsiqTrpbwg6rOg64yA66GcIOq6vOuCtOyYteuLiOuLpC5cbiAgICog7J2065WMIOqwkuuTpOydgCDrqqjrkZAg7KeB66Cs7ZmUIOqwgOuKpe2VnCDsg4Htg5zroZwg64KY6rCA6rKMIOuQqeuLiOuLpC5cbiAgICog7YWM7Iqk7Yq4IOygleuztOyZgCDtlajqu5ggZXh0ZW5zaW9uc+yXkCDrs7Trgrwg7Jqp64+E66GcIOunjOuTpOyXiOyKteuLiOuLpC5cbiAgICogQHJldHVybnNcbiAgICovXG4gIGdldEFsbFRyYWNlcygpOiBTZXJpYWxpemVkVHJhY2VbXSB7XG4gICAgY29uc3QgY29udGV4dCA9IFNvbmFtdS5nZXRDb250ZXh0KCk7XG4gICAgaWYgKCFjb250ZXh0Py5uYWl0ZVN0b3JlKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgY29uc3QgdHJhY2VzID0gQXJyYXkuZnJvbShjb250ZXh0Lm5haXRlU3RvcmUudmFsdWVzKCkpLmZsYXQoKTtcblxuICAgIC8vIOyngeugrO2ZlCDrtojqsIDriqXtlZwg6rCS7J20IOyhtOyerO2VnOuLpOuptCDsnbTrpbwg64yA66y47Ked66eM7ZWY6rKMIOyVjOugpOykjeuLiOuLpCEg6re47LmY66eMIOyVjOumrOq4sOunjCDtlZjqs6Ag6re464OlIOyngOuCmOqwkeuLiOuLpCDjhY7jhY5cbiAgICAvLyDsmZwg7KeB66Cs7ZmU6rCAIOykkeyalO2VnOqwgD8g7J20KGdldEFsbFRyYWNlcykg7Zi47Lac7J2YIOqysOqzvOuKlCDsmbjrtoDroZwg64KY6rCA6rKMIOuQmOuKlOuNsCxcbiAgICAvLyDsnbTrlYwg7KO8IOyaqeuPhOqwgCB2aXRlc3TsnZggdGFzay5tZXRhIO2VhOuTnOulvCDthrXtlbQgYWZ0ZXJFYWNo7JeQ7IScIFNvbmFtdSBleHRlbnNpb27snLzroZwg7KCE64us7ZWY64qUIOqyg+yeheuLiOuLpC5cbiAgICAvLyDsl6zquLDshJwgbWV0YSDtlYTrk5zsl5Ag64u06ri0IOuCtOyaqeydgCDtlITroZzshLjsiqTqsIQg7Ya17IugKHByb2Nlc3Muc2VuZCkg65iQ64qUIOyKpOugiOuTnOqwhCDthrXsi6AobWVzc2FnZSBwb3J0KeydhCDthrXtlbQg7KCE64us65CY7Ja07JW8IO2VmOuKlOuNsCxcbiAgICAvLyDsnbTroZwg7J247ZW0IFwi7KeB66Cs7ZmUIOqwgOuKpe2VnCDqsJLrk6Trp4wg7ZeI7JqpXCLtlZjripQg7KCc7JW97J20IOyDneq5geuLiOuLpC5cbiAgICAvL1xuICAgIC8vIOydtCDsoJzslb3snYQg7J2Y7Iud7ZWY7JesIE5haXRlLnTsl5Ag7KeB66Cs7ZmUIOqwgOuKpe2VnCDqsJLrp4wg64SY6riw6rKMIO2VoCDsiJjrj4Qg7J6I7JeI7KeA66eMLCDqt7jroIfqsowg7ZWY66m0IOu2iO2OuO2VtOyniCDqsoMg6rCZ7JWE7IScIO2VmOyngCDslYrslZjsirXri4jri6QuXG4gICAgLy8g65Sw65287IScIO2YhOyerCBOYWl0ZS5064qUIOuqqOuToCDqsJLsnYQg67Cb7J2EIOyImCDsnojqsowg65CY7Ja0IOyeiOyKteuLiOuLpC5cbiAgICAvLyDrjIDsi6Ag7J2066CH6rKMKGdldEFsbFRyYWNlcykg6re4IOqwkuuTpOydhCDrubzrgrwg65WMIEpTT04uc3RyaW5naWZ566W8IOyCrOyaqe2VmOyXrCDqsJXsoJzroZwg7KeB66Cs7ZmUIOqwgOuKpe2VmOqyjCDrp4zrk6Tsl4jsirXri4jri6QsLFxuICAgIGZvciAoY29uc3QgdHJhY2Ugb2YgdHJhY2VzKSB7XG4gICAgICBjb25zdCBjaGVjayA9IGlzU2VyaWFsaXphYmxlKHRyYWNlLmRhdGEpO1xuICAgICAgaWYgKCFjaGVjay52YWxpZCkge1xuICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgXCJcXG5cIiArXG4gICAgICAgICAgICBcIuKVlOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVl1xcblwiICtcbiAgICAgICAgICAgIFwi4pWRICBbTmFpdGVdIE5vbi1zZXJpYWxpemFibGUgdmFsdWUgZGV0ZWN0ZWQhICAgICAgICAgICAgICAgICAgICAgIOKVkVxcblwiICtcbiAgICAgICAgICAgIFwi4pWg4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWjXFxuXCIgK1xuICAgICAgICAgICAgYOKVkSAgS2V5OiAke3RyYWNlLmtleS5wYWRFbmQoNTcpfeKVkVxcbmAgK1xuICAgICAgICAgICAgYOKVkSAgUmVhc29uOiAkeyhjaGVjay5yZWFzb24gPz8gXCJ1bmtub3duXCIpLnNsaWNlKDAsIDU0KS5wYWRFbmQoNTQpfeKVkVxcbmAgK1xuICAgICAgICAgICAgYOKVkSAgTG9jYXRpb246ICR7KHRyYWNlLnN0YWNrWzBdPy5maWxlUGF0aCA/PyBcInVua25vd25cIikuc2xpY2UoLTUxKS5wYWRFbmQoNTIpfeKVkVxcbmAgK1xuICAgICAgICAgICAgYOKVkSAgTGluZTogJHtTdHJpbmcodHJhY2Uuc3RhY2tbMF0/LmxpbmVOdW1iZXIgPz8gMCkucGFkRW5kKDU2KX3ilZFcXG5gICtcbiAgICAgICAgICAgIFwi4pWg4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWjXFxuXCIgK1xuICAgICAgICAgICAgXCLilZEgIE5haXRlLnQoKSBhY2NlcHRzIGFueSB0eXBlIG9mIHZhbHVlLiBIb3dldmVyLCB2YWx1ZXMgd2lsbCAgICAg4pWRXFxuXCIgK1xuICAgICAgICAgICAgXCLilZEgIGJlIHNlcmlhbGl6ZWQgdG8gSlNPTiB3aGVuIGV4cG9ydGVkIHZpYSBOYWl0ZS5nZXRBbGxUcmFjZXMoKS4g4pWRXFxuXCIgK1xuICAgICAgICAgICAgXCLilZrilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZ1cXG5cIixcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJhY2VzLm1hcCgodHJhY2UpID0+ICh7XG4gICAgICBrZXk6IHRyYWNlLmtleSxcbiAgICAgIHZhbHVlOiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRyYWNlLmRhdGEgPz8gXCJcIikpLCAvLyDsp4HroKztmZQg6rCA64ql7ZWcIOqyg+unjCDrgqjquLDroKTripQg64iI66y86rKo7Jq0IOuFuOugpSwsIOyViOq3uOufrOuptCB0YXNrLm1ldGHsl5Ag65Ok7Ja06rCA7IScIO2UhOuhnOyEuOyKpOqwhCDthrXsi6Ag7ZWgIOuVjCDrrLjsoJwg7IOd6riw6rGw65Og7JqULCxcbiAgICAgIGZpbGVQYXRoOiB0cmFjZS5zdGFja1swXT8uZmlsZVBhdGggPz8gXCJcIixcbiAgICAgIGxpbmVOdW1iZXI6IHRyYWNlLnN0YWNrWzBdPy5saW5lTnVtYmVyID8/IDAsXG4gICAgICBhdDogdHJhY2UuYXQudG9JU09TdHJpbmcoKSxcbiAgICB9KSk7XG4gIH1cblxuICAvLyDtirnsoJUg7YKkIOyCreygnO2VmOq4sFxuICBkZWwoa2V5OiBzdHJpbmcpIHtcbiAgICBjb25zdCBjb250ZXh0ID0gU29uYW11LmdldENvbnRleHQoKTtcbiAgICBpZiAoIWNvbnRleHQ/Lm5haXRlU3RvcmUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29udGV4dC5uYWl0ZVN0b3JlLmRlbGV0ZShrZXkpO1xuICB9XG5cbiAgY3JlYXRlU3RvcmUoKTogTmFpdGVTdG9yZSB7XG4gICAgcmV0dXJuIG5ldyBNYXA8c3RyaW5nLCBOYWl0ZVRyYWNlW10+KCk7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IE5haXRlID0gbmV3IE5haXRlQ2xhc3MoKTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUE0Q0EsU0FBUyxtQkFBaUM7Q0FDeEMsTUFBTSxRQUFRLElBQUksT0FBTyxDQUFDO0FBQzFC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