sonamu 0.9.19 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +36 -0
  2. package/dist/ai/agents/agent.js +5 -7
  3. package/dist/ai/agents/index.js +1 -2
  4. package/dist/ai/agents/types.js +1 -1
  5. package/dist/ai/index.js +1 -2
  6. package/dist/ai/providers/rtzr/api.js +2 -3
  7. package/dist/ai/providers/rtzr/error.js +14 -29
  8. package/dist/ai/providers/rtzr/index.js +1 -2
  9. package/dist/ai/providers/rtzr/model.js +13 -20
  10. package/dist/ai/providers/rtzr/options.js +2 -3
  11. package/dist/ai/providers/rtzr/provider.js +2 -3
  12. package/dist/ai/providers/rtzr/utils.js +12 -21
  13. package/dist/api/base-frame.js +4 -4
  14. package/dist/api/caster.js +21 -38
  15. package/dist/api/code-converters.js +41 -98
  16. package/dist/api/config.d.ts +1 -10
  17. package/dist/api/config.d.ts.map +1 -1
  18. package/dist/api/config.js +9 -8
  19. package/dist/api/context.js +2 -3
  20. package/dist/api/decorators.js +80 -116
  21. package/dist/api/index.js +2 -3
  22. package/dist/api/secret.js +6 -10
  23. package/dist/api/sonamu.d.ts.map +1 -1
  24. package/dist/api/sonamu.js +200 -387
  25. package/dist/api/validator.js +5 -8
  26. package/dist/api/websocket-helpers.js +21 -32
  27. package/dist/auth/audit-log/builders.js +2 -3
  28. package/dist/auth/audit-log/events.js +2 -2
  29. package/dist/auth/audit-log/plugin.js +30 -61
  30. package/dist/auth/audit-log-ingestor.js +19 -41
  31. package/dist/auth/auth-generator.js +16 -41
  32. package/dist/auth/better-auth-entities.js +3 -4
  33. package/dist/auth/index.js +2 -3
  34. package/dist/auth/knex-adapter.js +18 -45
  35. package/dist/auth/plugins/entity-definitions/admin.js +2 -2
  36. package/dist/auth/plugins/entity-definitions/anonymous.js +2 -2
  37. package/dist/auth/plugins/entity-definitions/api-key.js +2 -2
  38. package/dist/auth/plugins/entity-definitions/audit-log.js +2 -2
  39. package/dist/auth/plugins/entity-definitions/index.js +2 -3
  40. package/dist/auth/plugins/entity-definitions/jwt.js +2 -2
  41. package/dist/auth/plugins/entity-definitions/organization.js +2 -2
  42. package/dist/auth/plugins/entity-definitions/passkey.js +2 -2
  43. package/dist/auth/plugins/entity-definitions/phone-number.js +2 -2
  44. package/dist/auth/plugins/entity-definitions/sso.js +2 -2
  45. package/dist/auth/plugins/entity-definitions/two-factor.js +2 -2
  46. package/dist/auth/plugins/entity-definitions/types.js +1 -1
  47. package/dist/auth/plugins/entity-definitions/username.js +2 -2
  48. package/dist/auth/plugins/index.js +1 -2
  49. package/dist/auth/plugins/wrappers/admin.js +2 -3
  50. package/dist/auth/plugins/wrappers/anonymous.js +2 -3
  51. package/dist/auth/plugins/wrappers/api-key.js +2 -3
  52. package/dist/auth/plugins/wrappers/index.js +1 -2
  53. package/dist/auth/plugins/wrappers/jwt.js +2 -3
  54. package/dist/auth/plugins/wrappers/organization.js +2 -3
  55. package/dist/auth/plugins/wrappers/passkey.js +2 -3
  56. package/dist/auth/plugins/wrappers/phone-number.js +2 -3
  57. package/dist/auth/plugins/wrappers/sso.js +2 -3
  58. package/dist/auth/plugins/wrappers/two-factor.js +2 -3
  59. package/dist/auth/plugins/wrappers/username.js +2 -3
  60. package/dist/bin/build-config.js +2 -2
  61. package/dist/bin/cli.js +151 -258
  62. package/dist/bin/fixture.d.ts.map +1 -1
  63. package/dist/bin/fixture.js +55 -97
  64. package/dist/bin/hmr-hook-register.js +3 -3
  65. package/dist/bin/migrate-targets.d.ts +3 -0
  66. package/dist/bin/migrate-targets.d.ts.map +1 -0
  67. package/dist/bin/migrate-targets.js +11 -0
  68. package/dist/bin/test-command.js +25 -55
  69. package/dist/bin/ts-loader-register.js +5 -6
  70. package/dist/bin/ts-loader-registration.js +6 -13
  71. package/dist/cache/cache-manager.js +3 -4
  72. package/dist/cache/decorator.js +11 -21
  73. package/dist/cache/drivers.js +2 -3
  74. package/dist/cache/index.js +2 -3
  75. package/dist/cache/types.js +1 -1
  76. package/dist/cache-control/cache-control.js +21 -34
  77. package/dist/cache-control/types.js +1 -1
  78. package/dist/compress/compress.js +10 -10
  79. package/dist/compress/index.js +1 -2
  80. package/dist/compress/types.js +1 -1
  81. package/dist/cone/cone-generator.js +25 -63
  82. package/dist/database/_batch_update.js +26 -46
  83. package/dist/database/base-model.js +44 -97
  84. package/dist/database/base-model.types.js +1 -1
  85. package/dist/database/db.d.ts +8 -14
  86. package/dist/database/db.d.ts.map +1 -1
  87. package/dist/database/db.js +127 -72
  88. package/dist/database/knex.js +5 -8
  89. package/dist/database/puri-subset.types.js +1 -1
  90. package/dist/database/puri-wrapper.js +11 -15
  91. package/dist/database/puri.js +117 -234
  92. package/dist/database/puri.types.js +3 -4
  93. package/dist/database/transaction-context.js +4 -5
  94. package/dist/database/upsert-builder.js +109 -176
  95. package/dist/dict/en.d.ts +1 -0
  96. package/dist/dict/en.d.ts.map +1 -1
  97. package/dist/dict/en.js +4 -4
  98. package/dist/dict/index.js +2 -3
  99. package/dist/dict/ko.d.ts +1 -0
  100. package/dist/dict/ko.d.ts.map +1 -1
  101. package/dist/dict/ko.js +4 -4
  102. package/dist/dict/rc-keys.js +3 -4
  103. package/dist/dict/sd.js +8 -19
  104. package/dist/dict/sonamu-dictionary.js +141 -284
  105. package/dist/dict/types.js +1 -1
  106. package/dist/dict/utils.js +4 -5
  107. package/dist/entity/entity-manager.d.ts +2 -2
  108. package/dist/entity/entity-manager.js +34 -82
  109. package/dist/entity/entity-template-cone.js +33 -66
  110. package/dist/entity/entity.js +156 -310
  111. package/dist/env.d.ts +14 -0
  112. package/dist/env.d.ts.map +1 -0
  113. package/dist/env.js +75 -0
  114. package/dist/exceptions/error-handler.js +2 -3
  115. package/dist/exceptions/so-exceptions.js +7 -5
  116. package/dist/filter/index.js +1 -2
  117. package/dist/filter/types.js +3 -4
  118. package/dist/filter/utils.js +21 -54
  119. package/dist/index.js +8 -7
  120. package/dist/logger/category.js +6 -12
  121. package/dist/logger/configure.js +23 -34
  122. package/dist/migration/code-generation.js +146 -314
  123. package/dist/migration/index-where-predicate.js +52 -144
  124. package/dist/migration/migration-set.js +19 -33
  125. package/dist/migration/migrator.d.ts +2 -0
  126. package/dist/migration/migrator.d.ts.map +1 -1
  127. package/dist/migration/migrator.js +69 -53
  128. package/dist/migration/postgresql-schema-reader.js +126 -225
  129. package/dist/migration/slack-confirm.d.ts +1 -0
  130. package/dist/migration/slack-confirm.d.ts.map +1 -1
  131. package/dist/migration/slack-confirm.js +28 -38
  132. package/dist/migration/types.js +1 -1
  133. package/dist/naite/messaging-types.js +1 -1
  134. package/dist/naite/naite-reporter.js +15 -32
  135. package/dist/naite/naite.js +43 -76
  136. package/dist/ssr/index.js +6 -9
  137. package/dist/ssr/registry.js +10 -18
  138. package/dist/ssr/renderer.js +10 -21
  139. package/dist/ssr/types.js +1 -1
  140. package/dist/storage/base-file.js +5 -10
  141. package/dist/storage/buffered-file.js +3 -4
  142. package/dist/storage/drivers.js +2 -3
  143. package/dist/storage/index.js +2 -3
  144. package/dist/storage/s3-driver.js +5 -9
  145. package/dist/storage/storage-manager.js +5 -5
  146. package/dist/storage/types.js +1 -1
  147. package/dist/storage/uploaded-file.js +4 -6
  148. package/dist/stream/index.js +1 -2
  149. package/dist/stream/sse.js +8 -13
  150. package/dist/stream/ws-audience-resolver.js +5 -5
  151. package/dist/stream/ws-audience.js +3 -4
  152. package/dist/stream/ws-cluster-bus.js +3 -4
  153. package/dist/stream/ws-core.js +1 -1
  154. package/dist/stream/ws-delivery.js +11 -25
  155. package/dist/stream/ws-local-connection-store.js +9 -18
  156. package/dist/stream/ws-presence-store.js +43 -97
  157. package/dist/stream/ws-registry.js +17 -22
  158. package/dist/stream/ws-telemetry-memory.js +38 -45
  159. package/dist/stream/ws-telemetry-trace.js +4 -6
  160. package/dist/stream/ws-telemetry.js +82 -135
  161. package/dist/stream/ws.js +47 -91
  162. package/dist/syncer/api-parser.js +81 -147
  163. package/dist/syncer/checksum.js +9 -20
  164. package/dist/syncer/code-generator.js +29 -47
  165. package/dist/syncer/entity-operations.js +17 -27
  166. package/dist/syncer/event-batcher.js +8 -15
  167. package/dist/syncer/file-patterns.js +3 -4
  168. package/dist/syncer/file-tracking.js +6 -10
  169. package/dist/syncer/index.js +1 -2
  170. package/dist/syncer/module-loader.js +10 -26
  171. package/dist/syncer/syncer-actions.js +19 -37
  172. package/dist/syncer/syncer.js +46 -98
  173. package/dist/syncer/watcher.js +12 -26
  174. package/dist/tasks/decorator.js +7 -11
  175. package/dist/tasks/step-wrapper.js +7 -8
  176. package/dist/tasks/workflow-manager.js +18 -25
  177. package/dist/template/entity-converter.js +40 -64
  178. package/dist/template/helpers.js +32 -63
  179. package/dist/template/implementations/entity.template.js +7 -11
  180. package/dist/template/implementations/entry-server.template.js +2 -3
  181. package/dist/template/implementations/generated.template.js +25 -51
  182. package/dist/template/implementations/generated_http.template.js +31 -58
  183. package/dist/template/implementations/generated_sso.template.js +45 -85
  184. package/dist/template/implementations/init_types.template.js +4 -7
  185. package/dist/template/implementations/model.template.js +5 -10
  186. package/dist/template/implementations/model_test.template.js +2 -3
  187. package/dist/template/implementations/queries.template.js +4 -7
  188. package/dist/template/implementations/sd.template.js +17 -35
  189. package/dist/template/implementations/services.template.js +18 -30
  190. package/dist/template/implementations/view_form.template.js +72 -125
  191. package/dist/template/implementations/view_id_all_select.template.js +2 -3
  192. package/dist/template/implementations/view_list.template.js +86 -143
  193. package/dist/template/implementations/view_search_input.template.js +2 -3
  194. package/dist/template/index.js +5 -8
  195. package/dist/template/template-manager.js +13 -26
  196. package/dist/template/template-types.js +2 -3
  197. package/dist/template/template.js +7 -11
  198. package/dist/template/zod-converter.js +173 -348
  199. package/dist/testing/_relation-graph.js +18 -37
  200. package/dist/testing/bootstrap.js +5 -8
  201. package/dist/testing/data-explorer.js +34 -78
  202. package/dist/testing/dev-test-routes.js +54 -60
  203. package/dist/testing/dev-vitest-manager.js +33 -84
  204. package/dist/testing/faker-mappings.js +3 -4
  205. package/dist/testing/fixture-generator.d.ts +2 -1
  206. package/dist/testing/fixture-generator.d.ts.map +1 -1
  207. package/dist/testing/fixture-generator.js +159 -321
  208. package/dist/testing/fixture-loader.js +2 -2
  209. package/dist/testing/fixture-manager.d.ts.map +1 -1
  210. package/dist/testing/fixture-manager.js +124 -227
  211. package/dist/testing/global-setup.d.ts.map +1 -1
  212. package/dist/testing/global-setup.js +29 -17
  213. package/dist/testing/index.js +1 -2
  214. package/dist/testing/naite-vitest-reporter.js +2 -3
  215. package/dist/testing/parallel-db-manager.js +5 -3
  216. package/dist/testing/vitest-helpers.d.ts.map +1 -1
  217. package/dist/testing/vitest-helpers.js +15 -12
  218. package/dist/types/types.d.ts +14 -14
  219. package/dist/types/types.js +27 -50
  220. package/dist/ui/ai-api.js +6 -11
  221. package/dist/ui/ai-client.js +86 -134
  222. package/dist/ui/api.js +99 -195
  223. package/dist/ui/cdd-service.js +78 -130
  224. package/dist/ui/cdd-types.js +1 -1
  225. package/dist/ui-web/assets/{index-Df8q-fhb.js → index-DFStGyd0.js} +49 -49
  226. package/dist/ui-web/assets/index-Dx4ap5i4.css +1 -0
  227. package/dist/ui-web/index.html +2 -2
  228. package/dist/utils/async-utils.js +13 -25
  229. package/dist/utils/class-name.js +3 -4
  230. package/dist/utils/console-util.js +11 -26
  231. package/dist/utils/controller.d.ts.map +1 -1
  232. package/dist/utils/controller.js +14 -12
  233. package/dist/utils/esm-utils.js +5 -8
  234. package/dist/utils/formatter.js +10 -22
  235. package/dist/utils/fs-utils.js +14 -25
  236. package/dist/utils/lodash-able.js +3 -4
  237. package/dist/utils/model.js +7 -14
  238. package/dist/utils/object-utils.js +41 -73
  239. package/dist/utils/path-utils.js +5 -9
  240. package/dist/utils/process-utils.js +4 -7
  241. package/dist/utils/sql-parser.js +6 -13
  242. package/dist/utils/type-utils.js +16 -26
  243. package/dist/utils/utils.js +18 -40
  244. package/dist/utils/zod-error.js +9 -16
  245. package/dist/vector/chunking.js +24 -37
  246. package/dist/vector/config.js +2 -2
  247. package/dist/vector/embedding.js +8 -19
  248. package/dist/vector/index.js +1 -2
  249. package/dist/vector/types.js +1 -1
  250. package/package.json +7 -7
  251. package/src/__tests__/env.test.ts +127 -0
  252. package/src/api/__tests__/config.test.ts +10 -1
  253. package/src/api/config.ts +4 -12
  254. package/src/api/sonamu.ts +14 -4
  255. package/src/bin/__tests__/migrate-targets.test.ts +28 -0
  256. package/src/bin/__tests__/test-command.test.ts +82 -1
  257. package/src/bin/cli.ts +9 -18
  258. package/src/bin/fixture.ts +5 -4
  259. package/src/bin/migrate-targets.ts +7 -0
  260. package/src/bin/test-command.ts +2 -2
  261. package/src/database/__tests__/db.test.ts +175 -0
  262. package/src/database/db.ts +193 -71
  263. package/src/dict/en.ts +2 -0
  264. package/src/dict/ko.ts +2 -0
  265. package/src/env.ts +123 -0
  266. package/src/migration/__tests__/migrator.test.ts +149 -0
  267. package/src/migration/migrator.ts +74 -17
  268. package/src/migration/slack-confirm.ts +21 -0
  269. package/src/skills/sonamu/database.md +1 -1
  270. package/src/skills/sonamu/entity-basic.md +31 -0
  271. package/src/skills/sonamu/puri.md +22 -0
  272. package/src/skills/sonamu/testing-devrunner.md +1 -1
  273. package/src/skills/sonamu/upsert.md +53 -6
  274. package/src/stream/ws-telemetry-memory.ts +2 -2
  275. package/src/testing/fixture-generator.ts +2 -1
  276. package/src/testing/fixture-manager.ts +3 -4
  277. package/src/testing/global-setup.ts +42 -18
  278. package/src/testing/vitest-helpers.ts +14 -0
  279. package/src/utils/controller.ts +14 -7
  280. package/tsdown.api.config.ts +6 -0
  281. package/dist/_virtual/rolldown_runtime.js +0 -39
  282. package/dist/ui-web/assets/index-D4rYm-Xz.css +0 -1
@@ -1,4 +1,4 @@
1
- import { __esmMin } from "../_virtual/rolldown_runtime.js";
1
+ import { __esmMin } from "../_virtual/_rolldown/runtime.js";
2
2
  import { convertDomainToCategory, init_category } from "../logger/category.js";
3
3
  import { DB, init_db } from "./db.js";
4
4
  import { Sonamu, init_sonamu } from "../api/sonamu.js";
@@ -10,7 +10,6 @@ import { Puri, init_puri } from "./puri.js";
10
10
  import { PuriWrapper, init_puri_wrapper } from "./puri-wrapper.js";
11
11
  import { getLogger } from "@logtape/logtape";
12
12
  import { cloneDeep, cluster, group, isObject, omit, set } from "radashi";
13
-
14
13
  //#region src/database/base-model.ts
15
14
  /** biome-ignore-all lint/suspicious/noExplicitAny: Puri의 타입은 개별 모델에서 확정되므로 BaseModel에서는 any를 허용함 */
16
15
  var BaseModelClass, BaseModel;
@@ -25,6 +24,9 @@ var init_base_model = __esmMin((() => {
25
24
  init_puri_wrapper();
26
25
  init_upsert_builder();
27
26
  BaseModelClass = class {
27
+ modelName;
28
+ subsetQueries;
29
+ loaderQueries;
28
30
  logger;
29
31
  constructor(modelName = this.constructor.name, subsetQueries, loaderQueries) {
30
32
  this.modelName = modelName;
@@ -37,19 +39,14 @@ var init_base_model = __esmMin((() => {
37
39
  }
38
40
  getPuri(which) {
39
41
  const trx = DB.getTransactionContext().getTransaction(which);
40
- if (trx) {
41
- return trx;
42
- }
43
- const db = this.getDB(which);
44
- return new PuriWrapper(db, new UpsertBuilder());
42
+ if (trx) return trx;
43
+ return new PuriWrapper(this.getDB(which), new UpsertBuilder());
45
44
  }
46
45
  async destroy() {
47
46
  return DB.destroy();
48
47
  }
49
48
  async getInsertedIds(wdb, rows, tableName, unqKeyFields, chunkSize = 500) {
50
- if (!wdb) {
51
- wdb = this.getDB("w");
52
- }
49
+ if (!wdb) wdb = this.getDB("w");
53
50
  let unqKeys;
54
51
  let whereInField;
55
52
  let selectField;
@@ -76,9 +73,7 @@ var init_base_model = __esmMin((() => {
76
73
  * @returns onSubset - 특정 서브셋 전용 타입이 필요할 때 사용
77
74
  */
78
75
  getSubsetQueries(subset) {
79
- if (!this.subsetQueries) {
80
- throw new Error("subsetQueries is not defined");
81
- }
76
+ if (!this.subsetQueries) throw new Error("subsetQueries is not defined");
82
77
  const puriWrapper = new PuriWrapper(this.getDB("r"), new UpsertBuilder());
83
78
  const qb = this.subsetQueries[subset]?.(puriWrapper);
84
79
  return {
@@ -104,32 +99,24 @@ var init_base_model = __esmMin((() => {
104
99
  */
105
100
  async executeSubsetQuery(params) {
106
101
  const { subset, qb, params: queryParams, debug = false, optimizeCountQuery = false } = params;
107
- if (!this.loaderQueries) {
108
- throw new Error("loaderQueries is not defined");
109
- }
102
+ if (!this.loaderQueries) throw new Error("loaderQueries is not defined");
110
103
  if (queryParams.sonamuFilter) {
111
104
  const normalizedFilter = normalizeFilterQuery(queryParams.sonamuFilter);
112
105
  this.applySonamuFilters(qb, normalizedFilter);
113
106
  }
114
107
  const { num, page } = queryParams;
115
108
  const total = await this.executeCountQuery(qb, queryParams, debug, optimizeCountQuery);
116
- if (queryParams?.queryMode === "count") {
117
- return { total };
118
- }
109
+ if (queryParams?.queryMode === "count") return { total };
119
110
  const computedRows = await this.executeListQuery(subset, qb, queryParams, num, page, debug);
120
111
  const enhancer = params.enhancers?.[subset];
121
112
  const enhancedRows = await Promise.all(computedRows.map((row) => enhancer?.(row) ?? row));
122
- const entity = EntityManager.get(this.modelName);
123
- const internalFields = entity.subsetsInternal[subset] ?? [];
113
+ const internalFields = EntityManager.get(this.modelName).subsetsInternal[subset] ?? [];
124
114
  const rows = internalFields.length > 0 ? enhancedRows.map((row) => this.omitInternalFields(row, internalFields)) : enhancedRows;
125
- if (queryParams.queryMode === "list") {
126
- return { rows };
127
- } else {
128
- return {
129
- rows,
130
- total
131
- };
132
- }
115
+ if (queryParams.queryMode === "list") return { rows };
116
+ else return {
117
+ rows,
118
+ total
119
+ };
133
120
  }
134
121
  /**
135
122
  * 객체에서 internal 필드 제거
@@ -137,9 +124,7 @@ var init_base_model = __esmMin((() => {
137
124
  */
138
125
  omitInternalFields(row, fields) {
139
126
  const result = cloneDeep(row);
140
- for (const field of fields) {
141
- this.deleteField(result, field.split("."));
142
- }
127
+ for (const field of fields) this.deleteField(result, field.split("."));
143
128
  return result;
144
129
  }
145
130
  /**
@@ -154,15 +139,13 @@ var init_base_model = __esmMin((() => {
154
139
  validateSonamuFilters(filters, entity);
155
140
  const puri = qb;
156
141
  for (const [field, condition] of Object.entries(filters)) {
157
- if (condition === undefined || condition === null) continue;
142
+ if (condition === void 0 || condition === null) continue;
158
143
  const fullField = entity.getFullFieldName(field);
159
144
  if (typeof condition !== "object" || Array.isArray(condition)) {
160
145
  puri.where(fullField, condition);
161
146
  continue;
162
147
  }
163
- for (const [operator, value] of Object.entries(condition)) {
164
- this.applyOperator(qb, fullField, operator, value);
165
- }
148
+ for (const [operator, value] of Object.entries(condition)) this.applyOperator(qb, fullField, operator, value);
166
149
  }
167
150
  }
168
151
  /**
@@ -216,13 +199,12 @@ var init_base_model = __esmMin((() => {
216
199
  case "after":
217
200
  puri.where(field, ">", value);
218
201
  break;
219
- case "between": {
202
+ case "between":
220
203
  if (Array.isArray(value) && value.length === 2) {
221
204
  const [min, max] = value;
222
205
  puri.where(field, ">=", min).where(field, "<=", max);
223
206
  }
224
207
  break;
225
- }
226
208
  default: console.warn(`Unsupported operator: ${operator}`);
227
209
  }
228
210
  }
@@ -230,76 +212,50 @@ var init_base_model = __esmMin((() => {
230
212
  * 중첩 필드 삭제 (배열 내 객체도 처리)
231
213
  */
232
214
  deleteField(obj, parts) {
233
- if (!obj || typeof obj !== "object") {
234
- return;
235
- }
215
+ if (!obj || typeof obj !== "object") return;
236
216
  if (parts.length === 1) {
237
- if (Array.isArray(obj)) {
238
- obj.forEach((item) => {
239
- if (item && typeof item === "object") {
240
- delete item[parts[0]];
241
- }
242
- });
243
- } else {
244
- delete obj[parts[0]];
245
- }
217
+ if (Array.isArray(obj)) obj.forEach((item) => {
218
+ if (item && typeof item === "object") delete item[parts[0]];
219
+ });
220
+ else delete obj[parts[0]];
246
221
  return;
247
222
  }
248
223
  const [first, ...rest] = parts;
249
224
  const next = obj[first];
250
- if (Array.isArray(next)) {
251
- next.map((item) => this.deleteField(item, rest));
252
- } else if (next && typeof next === "object") {
253
- this.deleteField(next, rest);
254
- }
225
+ if (Array.isArray(next)) next.map((item) => this.deleteField(item, rest));
226
+ else if (next && typeof next === "object") this.deleteField(next, rest);
255
227
  }
256
228
  /**
257
229
  * COUNT 쿼리 실행 (내부 메서드)
258
230
  */
259
231
  async executeCountQuery(qb, params, debug, optimizeCountQuery) {
260
- if (params.queryMode === "list") {
261
- return 0;
262
- }
232
+ if (params.queryMode === "list") return 0;
263
233
  const countPuri = qb.clone().clear("order").clear("limit").clear("offset");
264
234
  if (optimizeCountQuery) {
265
235
  const { default: SqlParser } = await import("node-sql-parser");
266
- const parser = new SqlParser.Parser();
267
- const parsedQuery = parser.astify(countPuri.toQuery(), { database: Sonamu.config.database.database });
236
+ const parsedQuery = new SqlParser.Parser().astify(countPuri.toQuery(), { database: Sonamu.config.database.database });
268
237
  const leftJoinTables = getJoinTables(parsedQuery, ["LEFT JOIN"]);
269
238
  const whereTables = getTableNamesFromWhere(parsedQuery);
270
- const tablesToRemove = leftJoinTables.filter((j) => !whereTables.includes(j));
271
- tablesToRemove.forEach((table) => {
239
+ leftJoinTables.filter((j) => !whereTables.includes(j)).forEach((table) => {
272
240
  countPuri.clearJoin(table);
273
241
  });
274
242
  }
275
243
  const countResult = await countPuri.clear("select").select({ total: Puri.rawNumber(`COUNT(*)::integer`) }).first();
276
- if (debug) {
277
- countPuri.debug();
278
- }
244
+ if (debug) countPuri.debug();
279
245
  return countResult?.total ?? 0;
280
246
  }
281
247
  /**
282
248
  * LIST 쿼리 실행 (내부 메서드)
283
249
  */
284
250
  async executeListQuery(subset, qb, params, num, page, debug) {
285
- if (params.queryMode === "count") {
286
- return [];
287
- }
288
- const limitedQb = (() => {
289
- if (num === 0) {
290
- return qb;
291
- } else {
292
- return qb.limit(num).offset(num * (page - 1));
293
- }
251
+ if (params.queryMode === "count") return [];
252
+ let unloadedRows = await (() => {
253
+ if (num === 0) return qb;
254
+ else return qb.limit(num).offset(num * (page - 1));
294
255
  })();
295
- let unloadedRows = await limitedQb;
296
- if (debug) {
297
- qb.debug();
298
- }
256
+ if (debug) qb.debug();
299
257
  const loaders = this.loaderQueries[subset];
300
- if (loaders && Array.isArray(loaders)) {
301
- unloadedRows = await this.processLoaders(unloadedRows, loaders, debug);
302
- }
258
+ if (loaders && Array.isArray(loaders)) unloadedRows = await this.processLoaders(unloadedRows, loaders, debug);
303
259
  return this.hydrate(unloadedRows);
304
260
  }
305
261
  /**
@@ -309,13 +265,9 @@ var init_base_model = __esmMin((() => {
309
265
  for (const resolveLoader of loaders) {
310
266
  const { as, refId, qb: resolveLoaderQbFn, loaders: nestedLoaders } = resolveLoader;
311
267
  const resolveLoaderQb = resolveLoaderQbFn(new PuriWrapper(this.getDB("r"), new UpsertBuilder()), rows.map((row) => row[refId]));
312
- if (debug) {
313
- resolveLoaderQb.debug();
314
- }
268
+ if (debug) resolveLoaderQb.debug();
315
269
  let loadedRows = await resolveLoaderQb;
316
- if (nestedLoaders && nestedLoaders.length > 0) {
317
- loadedRows = await this.processLoaders(loadedRows, nestedLoaders, debug);
318
- }
270
+ if (nestedLoaders && nestedLoaders.length > 0) loadedRows = await this.processLoaders(loadedRows, nestedLoaders, debug);
319
271
  const subRowGroups = group(loadedRows, (row) => row.refId);
320
272
  rows = rows.map((row) => {
321
273
  row[as] = (subRowGroups[row[refId]] ?? []).map((r) => omit(r, ["refId"]));
@@ -337,18 +289,13 @@ var init_base_model = __esmMin((() => {
337
289
  const nullKeys = Object.entries(groups).filter(([groupKey, fields]) => {
338
290
  if (!fields || fields.length === 0) return false;
339
291
  const idField = `${groupKey}__id`;
340
- if (idField in row) {
341
- return row[idField] === null;
342
- }
292
+ if (idField in row) return row[idField] === null;
343
293
  return fields.every((field) => row[field] === null || Array.isArray(row[field]) && row[field].length === 0);
344
294
  }).map(([key]) => key);
345
295
  const hydrated = Object.keys(row).reduce((r, field) => {
346
296
  if (!field.includes("__")) {
347
- if (Array.isArray(row[field]) && isObject(row[field][0])) {
348
- r[field] = this.hydrate(row[field]);
349
- } else {
350
- r[field] = row[field];
351
- }
297
+ if (Array.isArray(row[field]) && isObject(row[field][0])) r[field] = this.hydrate(row[field]);
298
+ else r[field] = row[field];
352
299
  return r;
353
300
  }
354
301
  const parts = field.split("__");
@@ -365,8 +312,8 @@ var init_base_model = __esmMin((() => {
365
312
  };
366
313
  BaseModel = new BaseModelClass();
367
314
  }));
368
-
369
315
  //#endregion
370
316
  init_base_model();
371
317
  export { BaseModel, BaseModelClass, init_base_model };
372
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1tb2RlbC5qcyIsIm5hbWVzIjpbIm1vZGVsTmFtZTogc3RyaW5nIiwic3Vic2V0UXVlcmllcz86IFRTdWJzZXRRdWVyaWVzIiwibG9hZGVyUXVlcmllcz86IFRMb2FkZXJRdWVyaWVzIiwidW5xS2V5czogc3RyaW5nW10iLCJ3aGVyZUluRmllbGQ6IHN0cmluZyB8IEtuZXguUmF3Iiwic2VsZWN0RmllbGQ6IHN0cmluZyIsInJlc3VsdElkczogbnVtYmVyW10iLCJjb3VudFJlc3VsdDogeyB0b3RhbD86IG51bWJlciB9Il0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2RhdGFiYXNlL2Jhc2UtbW9kZWwudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqIGJpb21lLWlnbm9yZS1hbGwgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IFB1cmnsnZgg7YOA7J6F7J2AIOqwnOuzhCDrqqjrjbjsl5DshJwg7ZmV7KCV65CY66+A66GcIEJhc2VNb2RlbOyXkOyEnOuKlCBhbnnrpbwg7ZeI7Jqp7ZWoICovXG5pbXBvcnQgeyBnZXRMb2dnZXIgfSBmcm9tIFwiQGxvZ3RhcGUvbG9ndGFwZVwiO1xuaW1wb3J0IHsgdHlwZSBMb2dnZXIgfSBmcm9tIFwiQGxvZ3RhcGUvbG9ndGFwZVwiO1xuaW1wb3J0IHsgdHlwZSBLbmV4IH0gZnJvbSBcImtuZXhcIjtcbmltcG9ydCB7IGNsb25lRGVlcCwgY2x1c3RlciwgZ3JvdXAsIGlzT2JqZWN0LCBvbWl0LCBzZXQgfSBmcm9tIFwicmFkYXNoaVwiO1xuXG5pbXBvcnQgeyBTb25hbXUgfSBmcm9tIFwiLi4vYXBpL3NvbmFtdVwiO1xuaW1wb3J0IHsgRW50aXR5TWFuYWdlciB9IGZyb20gXCIuLi9lbnRpdHkvZW50aXR5LW1hbmFnZXJcIjtcbmltcG9ydCB7IHR5cGUgRmlsdGVyT3BlcmF0b3IsIHR5cGUgRmlsdGVyUXVlcnkgfSBmcm9tIFwiLi4vZmlsdGVyL3R5cGVzXCI7XG5pbXBvcnQgeyBub3JtYWxpemVGaWx0ZXJRdWVyeSwgdmFsaWRhdGVTb25hbXVGaWx0ZXJzIH0gZnJvbSBcIi4uL2ZpbHRlci91dGlsc1wiO1xuaW1wb3J0IHsgY29udmVydERvbWFpblRvQ2F0ZWdvcnkgfSBmcm9tIFwiLi4vbG9nZ2VyL2NhdGVnb3J5XCI7XG5pbXBvcnQgeyB0eXBlIERhdGFiYXNlU2NoZW1hRXh0ZW5kLCB0eXBlIFNvbmFtdVF1ZXJ5TW9kZSB9IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgdHlwZSBMaXN0UmVzdWx0IH0gZnJvbSBcIi4uL3V0aWxzL21vZGVsXCI7XG5pbXBvcnQgeyBnZXRKb2luVGFibGVzLCBnZXRUYWJsZU5hbWVzRnJvbVdoZXJlIH0gZnJvbSBcIi4uL3V0aWxzL3NxbC1wYXJzZXJcIjtcbmltcG9ydCB7IHR5cGUgRW5oYW5jZXJNYXAsIHR5cGUgUmVzb2x2ZVN1YnNldEludGVyc2VjdGlvbiB9IGZyb20gXCIuL2Jhc2UtbW9kZWwudHlwZXNcIjtcbmltcG9ydCB7IHR5cGUgREJQcmVzZXQgfSBmcm9tIFwiLi9kYlwiO1xuaW1wb3J0IHsgREIgfSBmcm9tIFwiLi9kYlwiO1xuaW1wb3J0IHsgUHVyaSB9IGZyb20gXCIuL3B1cmlcIjtcbmltcG9ydCB7XG4gIHR5cGUgSW5mZXJBbGxTdWJzZXRzLFxuICB0eXBlIFB1cmlMb2FkZXJRdWVyaWVzLFxuICB0eXBlIFB1cmlTdWJzZXRGbixcbn0gZnJvbSBcIi4vcHVyaS1zdWJzZXQudHlwZXNcIjtcbmltcG9ydCB7IFB1cmlXcmFwcGVyIH0gZnJvbSBcIi4vcHVyaS13cmFwcGVyXCI7XG5pbXBvcnQgeyB0eXBlIFVuaW9uRXh0cmFjdGVkVFRhYmxlcyB9IGZyb20gXCIuL3B1cmkudHlwZXNcIjtcbmltcG9ydCB7IFVwc2VydEJ1aWxkZXIgfSBmcm9tIFwiLi91cHNlcnQtYnVpbGRlclwiO1xuXG50eXBlIFVua25vd25EQlJlY29yZCA9IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuXG4vKipcbiAqIOuqqOuToCBNb2RlbCDtgbTrnpjsiqTsnZgg6riw67O4IO2BtOuemOyKpFxuICpcbiAqIEB0ZW1wbGF0ZSBUU3Vic2V0S2V5IC0g7ISc67iM7IWLIO2CpCDsnKDri4jsmKggKOyYiDogXCJBXCIgfCBcIlBcIiB8IFwiU1NcIilcbiAqIEB0ZW1wbGF0ZSBUU3Vic2V0TWFwcGluZyAtIOyEnOu4jOyFi+uzhCDstZzsooUg6rKw6rO8IO2DgOyehSDrp6TtlZFcbiAqIEB0ZW1wbGF0ZSBUU3Vic2V0UXVlcmllcyAtIOyEnOu4jOyFiyDsv7zrpqwg7ZWo7IiYIOqwneyytFxuICogQHRlbXBsYXRlIFRMb2FkZXJRdWVyaWVzIC0g7ISc67iM7IWL67OEIOuhnOuNlCDsv7zrpqwg67Cw7Je0IOqwneyytFxuICovXG5leHBvcnQgY2xhc3MgQmFzZU1vZGVsQ2xhc3M8XG4gIFRTdWJzZXRLZXkgZXh0ZW5kcyBzdHJpbmcgPSBuZXZlcixcbiAgVFN1YnNldE1hcHBpbmcgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gbmV2ZXIsXG4gIFRTdWJzZXRRdWVyaWVzIGV4dGVuZHMgUmVjb3JkPFRTdWJzZXRLZXksIFB1cmlTdWJzZXRGbj4gPSBuZXZlcixcbiAgVExvYWRlclF1ZXJpZXMgZXh0ZW5kcyBQdXJpTG9hZGVyUXVlcmllczxUU3Vic2V0S2V5PiA9IG5ldmVyLFxuPiB7XG4gIHByb3RlY3RlZCByZWFkb25seSBsb2dnZXI6IExvZ2dlcjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgcmVhZG9ubHkgbW9kZWxOYW1lOiBzdHJpbmcgPSB0aGlzLmNvbnN0cnVjdG9yLm5hbWUsXG4gICAgcHJvdGVjdGVkIHN1YnNldFF1ZXJpZXM/OiBUU3Vic2V0UXVlcmllcyxcbiAgICBwcm90ZWN0ZWQgbG9hZGVyUXVlcmllcz86IFRMb2FkZXJRdWVyaWVzLFxuICApIHtcbiAgICB0aGlzLmxvZ2dlciA9IGdldExvZ2dlcihjb252ZXJ0RG9tYWluVG9DYXRlZ29yeSh0aGlzLm1vZGVsTmFtZSwgXCJtb2RlbFwiKSk7XG4gIH1cblxuICBnZXREQih3aGljaDogREJQcmVzZXQpOiBLbmV4IHtcbiAgICByZXR1cm4gREIuZ2V0REIod2hpY2gpO1xuICB9XG5cbiAgZ2V0UHVyaSh3aGljaDogREJQcmVzZXQpOiBQdXJpV3JhcHBlciB7XG4gICAgLy8g7Yq4656c7J6t7IWYIOy7qO2FjeyKpO2KuOyXkOyEnCDtirjrnpzsnq3shZgg7ZqN65OdXG4gICAgY29uc3QgdHJ4ID0gREIuZ2V0VHJhbnNhY3Rpb25Db250ZXh0KCkuZ2V0VHJhbnNhY3Rpb24od2hpY2gpO1xuICAgIGlmICh0cngpIHtcbiAgICAgIHJldHVybiB0cng7XG4gICAgfVxuXG4gICAgLy8g7Yq4656c7J6t7IWY7J20IOyXhuycvOuptCDsg4jroZzsmrQgUHVyaVdyYXBwZXIg67CY7ZmYXG4gICAgY29uc3QgZGIgPSB0aGlzLmdldERCKHdoaWNoKTtcbiAgICByZXR1cm4gbmV3IFB1cmlXcmFwcGVyKGRiLCBuZXcgVXBzZXJ0QnVpbGRlcigpKTtcbiAgfVxuXG4gIGFzeW5jIGRlc3Ryb3koKSB7XG4gICAgcmV0dXJuIERCLmRlc3Ryb3koKTtcbiAgfVxuXG4gIGFzeW5jIGdldEluc2VydGVkSWRzKFxuICAgIHdkYjogS25leCxcbiAgICByb3dzOiBVbmtub3duREJSZWNvcmRbXSxcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICB1bnFLZXlGaWVsZHM6IHN0cmluZ1tdLFxuICAgIGNodW5rU2l6ZTogbnVtYmVyID0gNTAwLFxuICApIHtcbiAgICBpZiAoIXdkYikge1xuICAgICAgd2RiID0gdGhpcy5nZXREQihcIndcIik7XG4gICAgfVxuXG4gICAgbGV0IHVucUtleXM6IHN0cmluZ1tdO1xuICAgIGxldCB3aGVyZUluRmllbGQ6IHN0cmluZyB8IEtuZXguUmF3O1xuICAgIGxldCBzZWxlY3RGaWVsZDogc3RyaW5nO1xuXG4gICAgaWYgKHVucUtleUZpZWxkcy5sZW5ndGggPiAxKSB7XG4gICAgICB3aGVyZUluRmllbGQgPSB3ZGIucmF3KGBDT05DQVRfV1MoJ18nLCAnJHt1bnFLZXlGaWVsZHMuam9pbihcIixcIil9JylgKTtcbiAgICAgIHNlbGVjdEZpZWxkID0gYCR7d2hlcmVJbkZpZWxkfSBhcyB0bXBVaWRgO1xuICAgICAgdW5xS2V5cyA9IHJvd3MubWFwKChyb3cpID0+IHVucUtleUZpZWxkcy5tYXAoKGZpZWxkKSA9PiByb3dbZmllbGRdKS5qb2luKFwiX1wiKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdoZXJlSW5GaWVsZCA9IHVucUtleUZpZWxkc1swXTtcbiAgICAgIHNlbGVjdEZpZWxkID0gdW5xS2V5RmllbGRzWzBdO1xuICAgICAgdW5xS2V5cyA9IHJvd3MubWFwKChyb3cpID0+IHJvd1t1bnFLZXlGaWVsZHNbMF1dIGFzIHN0cmluZyk7XG4gICAgfVxuXG4gICAgbGV0IHJlc3VsdElkczogbnVtYmVyW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGl0ZW1zIG9mIGNsdXN0ZXIodW5xS2V5cywgY2h1bmtTaXplKSkge1xuICAgICAgY29uc3QgZGJSb3dzID0gYXdhaXQgd2RiKHRhYmxlTmFtZSlcbiAgICAgICAgLnNlbGVjdChcImlkXCIsIHdkYi5yYXcoc2VsZWN0RmllbGQpKVxuICAgICAgICAud2hlcmVJbih3aGVyZUluRmllbGQgYXMgc3RyaW5nLCBpdGVtcyk7XG4gICAgICByZXN1bHRJZHMgPSByZXN1bHRJZHMuY29uY2F0KFxuICAgICAgICBkYlJvd3MubWFwKChkYlJvdzogVW5rbm93bkRCUmVjb3JkKSA9PiBwYXJzZUludChTdHJpbmcoZGJSb3cuaWQpKSksXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHRJZHM7XG4gIH1cblxuICAvKipcbiAgICog7Yq57KCVIOyEnOu4jOyFi+yXkCDrjIDtlZwg7L+866asIOu5jOuNlCDtmo3rk51cbiAgICpcbiAgICogQHJldHVybnMgcWIgLSDsv7zrpqwg67mM642UICjsobDqsbQg7LaU6rCA7JqpKVxuICAgKiBAcmV0dXJucyBvblN1YnNldCAtIO2KueyglSDshJzruIzshYsg7KCE7JqpIO2DgOyeheydtCDtlYTsmpTtlaAg65WMIOyCrOyaqVxuICAgKi9cbiAgZ2V0U3Vic2V0UXVlcmllczxUIGV4dGVuZHMgVFN1YnNldEtleT4oc3Vic2V0OiBUKSB7XG4gICAgaWYgKCF0aGlzLnN1YnNldFF1ZXJpZXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcInN1YnNldFF1ZXJpZXMgaXMgbm90IGRlZmluZWRcIik7XG4gICAgfVxuXG4gICAgY29uc3QgcHVyaVdyYXBwZXIgPSBuZXcgUHVyaVdyYXBwZXIodGhpcy5nZXREQihcInJcIiksIG5ldyBVcHNlcnRCdWlsZGVyKCkpO1xuICAgIGNvbnN0IHFiID0gdGhpcy5zdWJzZXRRdWVyaWVzW3N1YnNldF0/LihwdXJpV3JhcHBlcik7XG5cbiAgICAvLyBOb25BbGxvd2VkQXNTaW5nbGVUYWJsZTog64uo7J28IO2FjOydtOu4lCDsu6zrn7wg7KCR6re8IOuwqeyngOyaqSDrp4jsu6RcbiAgICB0eXBlIFFCVGFibGVzID0gVW5pb25FeHRyYWN0ZWRUVGFibGVzPFRTdWJzZXRLZXksIFRTdWJzZXRRdWVyaWVzPiAmIHtcbiAgICAgIE5vbkFsbG93ZWRBc1NpbmdsZVRhYmxlOiB7IF9fZnVsbHRleHRfXzogdHJ1ZSB9O1xuICAgIH07XG5cbiAgICByZXR1cm4ge1xuICAgICAgcWI6IHFiIGFzIHVua25vd24gYXMgUHVyaTxEYXRhYmFzZVNjaGVtYUV4dGVuZCwgUUJUYWJsZXMsIHt9PixcbiAgICAgIG9uU3Vic2V0OiAoKF9zdWJzZXQ6IFRTdWJzZXRLZXkgfCByZWFkb25seSBUU3Vic2V0S2V5W10pID0+IHFiKSBhcyB7XG4gICAgICAgIC8vIOuLqOydvCDtgqRcbiAgICAgICAgPFMgZXh0ZW5kcyBUU3Vic2V0S2V5PihzdWJzZXQ6IFMpOiBSZXR1cm5UeXBlPFRTdWJzZXRRdWVyaWVzW1NdPjtcbiAgICAgICAgLy8g7YKkIOuwsOyXtCAtPiDqtZDsp5Htlakg67CY7ZmYXG4gICAgICAgIDxBcnIgZXh0ZW5kcyByZWFkb25seSBUU3Vic2V0S2V5W10+KFxuICAgICAgICAgIHN1YnNldHM6IFsuLi5BcnJdLFxuICAgICAgICApOiBSZXNvbHZlU3Vic2V0SW50ZXJzZWN0aW9uPEFyciwgVFN1YnNldFF1ZXJpZXM+O1xuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEVuaGFuY2VyIOqwneyytCDsg53shLEg7Zes7Y28XG4gICAqIO2DgOyehSDqsoDspp0g67CPIOy2lOuhoOydhCDrj4TsmYDspIxcbiAgICovXG4gIGNyZWF0ZUVuaGFuY2VyczxUIGV4dGVuZHMgVFN1YnNldEtleT4oXG4gICAgZW5oYW5jZXJzOiBFbmhhbmNlck1hcDxcbiAgICAgIFQsXG4gICAgICBJbmZlckFsbFN1YnNldHM8VFN1YnNldFF1ZXJpZXMsIFRMb2FkZXJRdWVyaWVzPixcbiAgICAgIFRTdWJzZXRNYXBwaW5nLFxuICAgICAgVFN1YnNldFF1ZXJpZXNcbiAgICA+LFxuICApIHtcbiAgICByZXR1cm4gZW5oYW5jZXJzO1xuICB9XG5cbiAgLyoqXG4gICAqIOyEnOu4jOyFiyDsv7zrpqwg7Iuk7ZaJXG4gICAqXG4gICAqIDEuIFNvbmFtdSDtlYTthLAg7KCB7JqpICjtg4DsnoUg67OA7ZmYIO2PrO2VqClcbiAgICogMi4g7L+866asIOyLpO2WiSAocGFnaW5hdGlvbiDsoIHsmqkpXG4gICAqIDMuIOuhnOuNlCDsi6TtlokgKDE6TiwgTjpNIOq0gOqzhCDrjbDsnbTthLAg66Gc65SpKVxuICAgKiA0LiBIeWRyYXRlIChmbGF0IOKGkiDspJHssqkg6rCd7LK0KVxuICAgKiA1LiBFbmhhbmNlciDsoIHsmqkgKHZpcnR1YWwg7ZWE65OcIOqzhOyCsClcbiAgICovXG4gIGFzeW5jIGV4ZWN1dGVTdWJzZXRRdWVyeTxcbiAgICBUIGV4dGVuZHMgVFN1YnNldEtleSxcbiAgICBUQ29tcHV0ZWRSZXN1bHRzIGV4dGVuZHMgSW5mZXJBbGxTdWJzZXRzPFRTdWJzZXRRdWVyaWVzLCBUTG9hZGVyUXVlcmllcz4sXG4gICAgTFAgZXh0ZW5kcyB7XG4gICAgICBudW0/OiBudW1iZXI7XG4gICAgICBwYWdlPzogbnVtYmVyO1xuICAgICAgcXVlcnlNb2RlPzogU29uYW11UXVlcnlNb2RlO1xuICAgICAgc29uYW11RmlsdGVyPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgfSxcbiAgPihcbiAgICBwYXJhbXM6IHtcbiAgICAgIHN1YnNldDogVDtcbiAgICAgIHFiOiBQdXJpPGFueSwgYW55LCBhbnk+O1xuICAgICAgcGFyYW1zOiB7XG4gICAgICAgIG51bTogbnVtYmVyO1xuICAgICAgICBwYWdlOiBudW1iZXI7XG4gICAgICAgIHF1ZXJ5TW9kZT86IFNvbmFtdVF1ZXJ5TW9kZTtcbiAgICAgICAgc29uYW11RmlsdGVyPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICB9O1xuICAgICAgZGVidWc/OiBib29sZWFuO1xuICAgICAgb3B0aW1pemVDb3VudFF1ZXJ5PzogYm9vbGVhbjtcbiAgICB9ICYgRW5oYW5jZXJQYXJhbTxUU3Vic2V0S2V5LCBUQ29tcHV0ZWRSZXN1bHRzLCBUU3Vic2V0TWFwcGluZywgVFN1YnNldFF1ZXJpZXM+LFxuICApOiBQcm9taXNlPExpc3RSZXN1bHQ8TFAsIFRTdWJzZXRNYXBwaW5nW1RdPj4ge1xuICAgIGNvbnN0IHsgc3Vic2V0LCBxYiwgcGFyYW1zOiBxdWVyeVBhcmFtcywgZGVidWcgPSBmYWxzZSwgb3B0aW1pemVDb3VudFF1ZXJ5ID0gZmFsc2UgfSA9IHBhcmFtcztcblxuICAgIGlmICghdGhpcy5sb2FkZXJRdWVyaWVzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJsb2FkZXJRdWVyaWVzIGlzIG5vdCBkZWZpbmVkXCIpO1xuICAgIH1cblxuICAgIC8vIFNvbmFtdSBGaWx0ZXIg7KCB7JqpXG4gICAgaWYgKHF1ZXJ5UGFyYW1zLnNvbmFtdUZpbHRlcikge1xuICAgICAgY29uc3Qgbm9ybWFsaXplZEZpbHRlciA9IG5vcm1hbGl6ZUZpbHRlclF1ZXJ5KHF1ZXJ5UGFyYW1zLnNvbmFtdUZpbHRlcik7XG4gICAgICB0aGlzLmFwcGx5U29uYW11RmlsdGVycyhxYiwgbm9ybWFsaXplZEZpbHRlcik7XG4gICAgfVxuXG4gICAgY29uc3QgeyBudW0sIHBhZ2UgfSA9IHF1ZXJ5UGFyYW1zO1xuXG4gICAgLy8gQ09VTlQg7L+866asIOyLpO2WiSAocXVlcnlNb2RlOiBsaXN07J28IOuVjOuKlCAwIOumrO2EtClcbiAgICBjb25zdCB0b3RhbCA9IGF3YWl0IHRoaXMuZXhlY3V0ZUNvdW50UXVlcnkocWIsIHF1ZXJ5UGFyYW1zLCBkZWJ1Zywgb3B0aW1pemVDb3VudFF1ZXJ5KTtcblxuICAgIGlmIChxdWVyeVBhcmFtcz8ucXVlcnlNb2RlID09PSBcImNvdW50XCIpIHtcbiAgICAgIHJldHVybiB7IHRvdGFsIH0gYXMgTGlzdFJlc3VsdDxMUCwgVFN1YnNldE1hcHBpbmdbVF0+O1xuICAgIH1cblxuICAgIC8vIExJU1Qg7L+866asIOyLpO2WiVxuICAgIGNvbnN0IGNvbXB1dGVkUm93cyA9IGF3YWl0IHRoaXMuZXhlY3V0ZUxpc3RRdWVyeShzdWJzZXQsIHFiLCBxdWVyeVBhcmFtcywgbnVtLCBwYWdlLCBkZWJ1Zyk7XG5cbiAgICAvLyBFbmhhbmNlciDsoIHsmqlcbiAgICBjb25zdCBlbmhhbmNlciA9IChwYXJhbXMgYXMgYW55KS5lbmhhbmNlcnM/LltzdWJzZXRdO1xuICAgIGNvbnN0IGVuaGFuY2VkUm93cyA9IChhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGNvbXB1dGVkUm93cy5tYXAoKHJvdykgPT4gZW5oYW5jZXI/Lihyb3cpID8/IHJvdyksXG4gICAgKSkgYXMgVFN1YnNldE1hcHBpbmdbVF1bXTtcblxuICAgIC8vIEludGVybmFsIO2VhOuTnCDsoJzqsbBcbiAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldCh0aGlzLm1vZGVsTmFtZSk7XG4gICAgY29uc3QgaW50ZXJuYWxGaWVsZHMgPSBlbnRpdHkuc3Vic2V0c0ludGVybmFsW3N1YnNldF0gPz8gW107XG4gICAgY29uc3Qgcm93cyA9XG4gICAgICBpbnRlcm5hbEZpZWxkcy5sZW5ndGggPiAwXG4gICAgICAgID8gZW5oYW5jZWRSb3dzLm1hcCgocm93KSA9PiB0aGlzLm9taXRJbnRlcm5hbEZpZWxkcyhyb3csIGludGVybmFsRmllbGRzKSlcbiAgICAgICAgOiBlbmhhbmNlZFJvd3M7XG5cbiAgICBpZiAocXVlcnlQYXJhbXMucXVlcnlNb2RlID09PSBcImxpc3RcIikge1xuICAgICAgLy8g66as7Iqk7Yq466eMIOumrO2EtFxuICAgICAgcmV0dXJuIHsgcm93cyB9IGFzIExpc3RSZXN1bHQ8TFAsIFRTdWJzZXRNYXBwaW5nW1RdPjtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8g65GY64ukIOumrO2EtFxuICAgICAgcmV0dXJuIHsgcm93cywgdG90YWwgfSBhcyBMaXN0UmVzdWx0PExQLCBUU3Vic2V0TWFwcGluZ1tUXT47XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOqwneyytOyXkOyEnCBpbnRlcm5hbCDtlYTrk5wg7KCc6rGwXG4gICAqIOykkeyyqSDtlYTrk5wo7JiIOiBcInVzZXIuZW1haWxcIikg67CPIOuwsOyXtCjsmIg6IFwiZW1wbG95ZWVzLnNhbGFyeVwiKeuPhCDsspjrpqxcbiAgICovXG4gIG9taXRJbnRlcm5hbEZpZWxkczxUIGV4dGVuZHMgb2JqZWN0Pihyb3c6IFQsIGZpZWxkczogc3RyaW5nW10pOiBUIHtcbiAgICBjb25zdCByZXN1bHQgPSBjbG9uZURlZXAocm93KTtcbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIGZpZWxkcykge1xuICAgICAgdGhpcy5kZWxldGVGaWVsZChyZXN1bHQsIGZpZWxkLnNwbGl0KFwiLlwiKSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVyUXVlcnnrpbwgUHVyaSBRdWVyeUJ1aWxkZXLsl5Ag7KCB7JqpXG4gICAqXG4gICAqIEBwYXJhbSBxYiBQdXJpIFF1ZXJ5QnVpbGRlciDsnbjsiqTthLTsiqRcbiAgICogQHBhcmFtIGZpbHRlcnMgRmlsdGVyUXVlcnkg6rCd7LK0XG4gICAqL1xuICBwcm90ZWN0ZWQgYXBwbHlTb25hbXVGaWx0ZXJzPFRFbnRpdHkgPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oXG4gICAgcWI6IFB1cmk8YW55LCBhbnksIGFueT4sXG4gICAgZmlsdGVycz86IEZpbHRlclF1ZXJ5PFRFbnRpdHk+LFxuICApOiB2b2lkIHtcbiAgICBpZiAoIWZpbHRlcnMpIHJldHVybjtcblxuICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KHRoaXMubW9kZWxOYW1lKTtcblxuICAgIC8vIDEuIO2VhO2EsCDqsoDspp0gKEVudGl0eSDquLDrsJgpXG4gICAgdmFsaWRhdGVTb25hbXVGaWx0ZXJzKGZpbHRlcnMsIGVudGl0eSk7XG5cbiAgICAvLyAyLiDqsoDspp3rkJwg7ZWE7YSwIOyggeyaqVxuICAgIGNvbnN0IHB1cmkgPSBxYiBhcyBhbnk7XG5cbiAgICBmb3IgKGNvbnN0IFtmaWVsZCwgY29uZGl0aW9uXSBvZiBPYmplY3QuZW50cmllcyhmaWx0ZXJzKSkge1xuICAgICAgaWYgKGNvbmRpdGlvbiA9PT0gdW5kZWZpbmVkIHx8IGNvbmRpdGlvbiA9PT0gbnVsbCkgY29udGludWU7XG5cbiAgICAgIC8vIO2FjOydtOu4lOuqhS7tlYTrk5zrqoUg7ZiV7Iud7Jy866GcIOuzgO2ZmFxuICAgICAgY29uc3QgZnVsbEZpZWxkID0gZW50aXR5LmdldEZ1bGxGaWVsZE5hbWUoZmllbGQpO1xuXG4gICAgICAvLyDsp4HsoJEg6rCSIChlceyZgCDrj5nsnbwpXG4gICAgICBpZiAodHlwZW9mIGNvbmRpdGlvbiAhPT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KGNvbmRpdGlvbikpIHtcbiAgICAgICAgcHVyaS53aGVyZShmdWxsRmllbGQsIGNvbmRpdGlvbik7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyDsl7DsgrDsnpAg6rCd7LK0XG4gICAgICBmb3IgKGNvbnN0IFtvcGVyYXRvciwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGNvbmRpdGlvbikpIHtcbiAgICAgICAgdGhpcy5hcHBseU9wZXJhdG9yKHFiLCBmdWxsRmllbGQsIG9wZXJhdG9yIGFzIEZpbHRlck9wZXJhdG9yLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOuLqOydvCDsl7DsgrDsnpDrpbwgUXVlcnlCdWlsZGVy7JeQIOyggeyaqVxuICAgKi9cbiAgcHJpdmF0ZSBhcHBseU9wZXJhdG9yKFxuICAgIHFiOiBQdXJpPGFueSwgYW55LCBhbnk+LFxuICAgIGZpZWxkOiBzdHJpbmcsXG4gICAgb3BlcmF0b3I6IEZpbHRlck9wZXJhdG9yLFxuICAgIHZhbHVlOiB1bmtub3duLFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBwdXJpID0gcWIgYXMgYW55O1xuXG4gICAgc3dpdGNoIChvcGVyYXRvcikge1xuICAgICAgY2FzZSBcImVxXCI6XG4gICAgICAgIHB1cmkud2hlcmUoZmllbGQsIHZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgXCJuZVwiOlxuICAgICAgICBwdXJpLndoZXJlKGZpZWxkLCBcIiE9XCIsIHZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgXCJndFwiOlxuICAgICAgICBwdXJpLndoZXJlKGZpZWxkLCBcIj5cIiwgdmFsdWUpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcImd0ZVwiOlxuICAgICAgICBwdXJpLndoZXJlKGZpZWxkLCBcIj49XCIsIHZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgXCJsdFwiOlxuICAgICAgICBwdXJpLndoZXJlKGZpZWxkLCBcIjxcIiwgdmFsdWUpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcImx0ZVwiOlxuICAgICAgICBwdXJpLndoZXJlKGZpZWxkLCBcIjw9XCIsIHZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgXCJpblwiOlxuICAgICAgICBwdXJpLndoZXJlSW4oZmllbGQsIHZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgXCJub3RJblwiOlxuICAgICAgICBwdXJpLndoZXJlTm90SW4oZmllbGQsIHZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgXCJjb250YWluc1wiOlxuICAgICAgICBwdXJpLndoZXJlKGZpZWxkLCBcImxpa2VcIiwgYCUke3ZhbHVlfSVgKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgXCJzdGFydHNXaXRoXCI6XG4gICAgICAgIHB1cmkud2hlcmUoZmllbGQsIFwibGlrZVwiLCBgJHt2YWx1ZX0lYCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIFwiZW5kc1dpdGhcIjpcbiAgICAgICAgcHVyaS53aGVyZShmaWVsZCwgXCJsaWtlXCIsIGAlJHt2YWx1ZX1gKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgXCJpc051bGxcIjpcbiAgICAgICAgcHVyaS53aGVyZShmaWVsZCwgbnVsbCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIFwiaXNOb3ROdWxsXCI6XG4gICAgICAgIHB1cmkud2hlcmUoZmllbGQsIFwiIT1cIiwgbnVsbCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIFwiYmVmb3JlXCI6XG4gICAgICAgIHB1cmkud2hlcmUoZmllbGQsIFwiPFwiLCB2YWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIFwiYWZ0ZXJcIjpcbiAgICAgICAgcHVyaS53aGVyZShmaWVsZCwgXCI+XCIsIHZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgXCJiZXR3ZWVuXCI6IHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpICYmIHZhbHVlLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgIGNvbnN0IFttaW4sIG1heF0gPSB2YWx1ZTtcbiAgICAgICAgICBwdXJpLndoZXJlKGZpZWxkLCBcIj49XCIsIG1pbikud2hlcmUoZmllbGQsIFwiPD1cIiwgbWF4KTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgY29uc29sZS53YXJuKGBVbnN1cHBvcnRlZCBvcGVyYXRvcjogJHtvcGVyYXRvcn1gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog7KSR7LKpIO2VhOuTnCDsgq3soJwgKOuwsOyXtCDrgrQg6rCd7LK064+EIOyymOumrClcbiAgICovXG4gIGRlbGV0ZUZpZWxkKG9iajogYW55LCBwYXJ0czogc3RyaW5nW10pOiB2b2lkIHtcbiAgICBpZiAoIW9iaiB8fCB0eXBlb2Ygb2JqICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgICAgICBvYmouZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgICAgIGlmIChpdGVtICYmIHR5cGVvZiBpdGVtID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICBkZWxldGUgaXRlbVtwYXJ0c1swXV07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlbGV0ZSBvYmpbcGFydHNbMF1dO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IFtmaXJzdCwgLi4ucmVzdF0gPSBwYXJ0cztcbiAgICBjb25zdCBuZXh0ID0gb2JqW2ZpcnN0XTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KG5leHQpKSB7XG4gICAgICBuZXh0Lm1hcCgoaXRlbSkgPT4gdGhpcy5kZWxldGVGaWVsZChpdGVtLCByZXN0KSk7XG4gICAgfSBlbHNlIGlmIChuZXh0ICYmIHR5cGVvZiBuZXh0ID09PSBcIm9iamVjdFwiKSB7XG4gICAgICB0aGlzLmRlbGV0ZUZpZWxkKG5leHQsIHJlc3QpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDT1VOVCDsv7zrpqwg7Iuk7ZaJICjrgrTrtoAg66mU7ISc65OcKVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBleGVjdXRlQ291bnRRdWVyeShcbiAgICBxYjogUHVyaTxhbnksIGFueSwgYW55PixcbiAgICBwYXJhbXM6IHsgcXVlcnlNb2RlPzogXCJsaXN0XCIgfCBcImNvdW50XCIgfCBcImJvdGhcIiB9LFxuICAgIGRlYnVnOiBib29sZWFuLFxuICAgIG9wdGltaXplQ291bnRRdWVyeTogYm9vbGVhbixcbiAgKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBpZiAocGFyYW1zLnF1ZXJ5TW9kZSA9PT0gXCJsaXN0XCIpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cblxuICAgIGNvbnN0IGNvdW50UHVyaSA9IHFiLmNsb25lKCkuY2xlYXIoXCJvcmRlclwiKS5jbGVhcihcImxpbWl0XCIpLmNsZWFyKFwib2Zmc2V0XCIpO1xuXG4gICAgaWYgKG9wdGltaXplQ291bnRRdWVyeSkge1xuICAgICAgY29uc3QgeyBkZWZhdWx0OiBTcWxQYXJzZXIgfSA9IGF3YWl0IGltcG9ydChcIm5vZGUtc3FsLXBhcnNlclwiKTtcbiAgICAgIGNvbnN0IHBhcnNlciA9IG5ldyBTcWxQYXJzZXIuUGFyc2VyKCk7XG4gICAgICBjb25zdCBwYXJzZWRRdWVyeSA9IHBhcnNlci5hc3RpZnkoY291bnRQdXJpLnRvUXVlcnkoKSwge1xuICAgICAgICBkYXRhYmFzZTogU29uYW11LmNvbmZpZy5kYXRhYmFzZS5kYXRhYmFzZSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBsZWZ0Sm9pblRhYmxlcyA9IGdldEpvaW5UYWJsZXMocGFyc2VkUXVlcnksIFtcIkxFRlQgSk9JTlwiXSk7XG4gICAgICBjb25zdCB3aGVyZVRhYmxlcyA9IGdldFRhYmxlTmFtZXNGcm9tV2hlcmUocGFyc2VkUXVlcnkpO1xuXG4gICAgICBjb25zdCB0YWJsZXNUb1JlbW92ZSA9IGxlZnRKb2luVGFibGVzLmZpbHRlcigoaikgPT4gIXdoZXJlVGFibGVzLmluY2x1ZGVzKGopKTtcbiAgICAgIHRhYmxlc1RvUmVtb3ZlLmZvckVhY2goKHRhYmxlKSA9PiB7XG4gICAgICAgIGNvdW50UHVyaS5jbGVhckpvaW4odGFibGUpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gQ09VTlQoKinroZwg7KCE7LK0IOugiOy9lOuTnCDsiJjrpbwg6rOE7IKwXG4gICAgLy8gVE9ETzogcWLsnZggRElTVElOQ1TqsIAg7J6I64qUIOqyveyasCDsspjrpqztlbTslbwg7ZWoXG4gICAgY29uc3QgY291bnRSZXN1bHQ6IHsgdG90YWw/OiBudW1iZXIgfSA9IGF3YWl0IGNvdW50UHVyaVxuICAgICAgLmNsZWFyKFwic2VsZWN0XCIpXG4gICAgICAuc2VsZWN0KHsgdG90YWw6IFB1cmkucmF3TnVtYmVyKGBDT1VOVCgqKTo6aW50ZWdlcmApIH0pXG4gICAgICAuZmlyc3QoKTtcblxuICAgIGlmIChkZWJ1Zykge1xuICAgICAgY291bnRQdXJpLmRlYnVnKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvdW50UmVzdWx0Py50b3RhbCA/PyAwO1xuICB9XG5cbiAgLyoqXG4gICAqIExJU1Qg7L+866asIOyLpO2WiSAo64K067aAIOuplOyEnOuTnClcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZXhlY3V0ZUxpc3RRdWVyeTxUIGV4dGVuZHMgVFN1YnNldEtleT4oXG4gICAgc3Vic2V0OiBULFxuICAgIHFiOiBQdXJpPGFueSwgYW55LCBhbnk+LFxuICAgIHBhcmFtczogeyBxdWVyeU1vZGU/OiBcImxpc3RcIiB8IFwiY291bnRcIiB8IFwiYm90aFwiIH0sXG4gICAgbnVtOiBudW1iZXIsXG4gICAgcGFnZTogbnVtYmVyLFxuICAgIGRlYnVnOiBib29sZWFuLFxuICApOiBQcm9taXNlPGFueVtdPiB7XG4gICAgaWYgKHBhcmFtcy5xdWVyeU1vZGUgPT09IFwiY291bnRcIikge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGNvbnN0IGxpbWl0ZWRRYiA9ICgoKSA9PiB7XG4gICAgICBpZiAobnVtID09PSAwKSB7XG4gICAgICAgIHJldHVybiBxYjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBxYi5saW1pdChudW0pLm9mZnNldChudW0gKiAocGFnZSAtIDEpKTtcbiAgICAgIH1cbiAgICB9KSgpO1xuICAgIGxldCB1bmxvYWRlZFJvd3MgPSBhd2FpdCBsaW1pdGVkUWI7XG5cbiAgICBpZiAoZGVidWcpIHtcbiAgICAgIHFiLmRlYnVnKCk7XG4gICAgfVxuXG4gICAgLy8g66Gc642UIOyymOumrFxuICAgIGNvbnN0IGxvYWRlcnMgPSAodGhpcy5sb2FkZXJRdWVyaWVzIGFzIGFueSlbc3Vic2V0XTtcbiAgICBpZiAobG9hZGVycyAmJiBBcnJheS5pc0FycmF5KGxvYWRlcnMpKSB7XG4gICAgICB1bmxvYWRlZFJvd3MgPSBhd2FpdCB0aGlzLnByb2Nlc3NMb2FkZXJzKHVubG9hZGVkUm93cywgbG9hZGVycywgZGVidWcpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmh5ZHJhdGUodW5sb2FkZWRSb3dzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDsnqzqt4DsoIEg66Gc642UIOyymOumrFxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwcm9jZXNzTG9hZGVycyhyb3dzOiBhbnlbXSwgbG9hZGVyczogYW55W10sIGRlYnVnOiBib29sZWFuKTogUHJvbWlzZTxhbnlbXT4ge1xuICAgIGZvciAoY29uc3QgcmVzb2x2ZUxvYWRlciBvZiBsb2FkZXJzKSB7XG4gICAgICBjb25zdCB7IGFzLCByZWZJZCwgcWI6IHJlc29sdmVMb2FkZXJRYkZuLCBsb2FkZXJzOiBuZXN0ZWRMb2FkZXJzIH0gPSByZXNvbHZlTG9hZGVyO1xuXG4gICAgICBjb25zdCByZXNvbHZlTG9hZGVyUWIgPSByZXNvbHZlTG9hZGVyUWJGbihcbiAgICAgICAgbmV3IFB1cmlXcmFwcGVyKHRoaXMuZ2V0REIoXCJyXCIpLCBuZXcgVXBzZXJ0QnVpbGRlcigpKSxcbiAgICAgICAgcm93cy5tYXAoKHJvdykgPT4gcm93W3JlZklkXSksXG4gICAgICApO1xuXG4gICAgICBpZiAoZGVidWcpIHtcbiAgICAgICAgcmVzb2x2ZUxvYWRlclFiLmRlYnVnKCk7XG4gICAgICB9XG5cbiAgICAgIGxldCBsb2FkZWRSb3dzID0gKGF3YWl0IHJlc29sdmVMb2FkZXJRYikgYXMgYW55W107XG5cbiAgICAgIC8vIOykkeyyqSBsb2FkZXJz6rCAIOyeiOycvOuptCDsnqzqt4Ag7LKY66asXG4gICAgICBpZiAobmVzdGVkTG9hZGVycyAmJiBuZXN0ZWRMb2FkZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbG9hZGVkUm93cyA9IGF3YWl0IHRoaXMucHJvY2Vzc0xvYWRlcnMobG9hZGVkUm93cywgbmVzdGVkTG9hZGVycywgZGVidWcpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzdWJSb3dHcm91cHMgPSBncm91cChsb2FkZWRSb3dzLCAocm93KSA9PiByb3cucmVmSWQpO1xuXG4gICAgICByb3dzID0gcm93cy5tYXAoKHJvdykgPT4ge1xuICAgICAgICByb3dbYXNdID0gKHN1YlJvd0dyb3Vwc1tyb3dbcmVmSWRdXSA/PyBbXSkubWFwKChyKSA9PiBvbWl0KHIsIFtcInJlZklkXCJdKSk7XG4gICAgICAgIHJldHVybiByb3c7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcm93cztcbiAgfVxuXG4gIC8qKlxuICAgKiBGbGF0IOugiOy9lOuTnOulvCDspJHssqkg6rCd7LK066GcIOuzgO2ZmFxuICAgKlxuICAgKiAtIGB1c2VyX19uYW1lYCDihpIgYHsgdXNlcjogeyBuYW1lIH0gfWBcbiAgICogLSBudWxsYWJsZSByZWxhdGlvbuydmCDqsr3smrAgaWQg7ZWE65Oc6rCAIG51bGzsnbTrqbQg6rCd7LK0IOyekOyytOulvCBudWxs66GcXG4gICAqL1xuICBoeWRyYXRlPFQgZXh0ZW5kcyBVbmtub3duREJSZWNvcmQ+KHJvd3M6IFRbXSk6IFRbXSB7XG4gICAgcmV0dXJuIHJvd3MubWFwKChyb3c6IFQpID0+IHtcbiAgICAgIC8vIG51bGxhYmxlIHJlbGF0aW9uIOyymOumrDog6re466O57J2YIGlkIO2VhOuTnOqwgCBudWxs7J2066m0IOqwneyytCDsoITssrTrpbwgbnVsbOuhnFxuICAgICAgY29uc3QgbmVzdGVkS2V5cyA9IE9iamVjdC5rZXlzKHJvdykuZmlsdGVyKChrZXkpID0+IGtleS5pbmNsdWRlcyhcIl9fXCIpKTtcbiAgICAgIGNvbnN0IGdyb3VwcyA9IE9iamVjdC5ncm91cEJ5KG5lc3RlZEtleXMsIChrZXkpID0+IGtleS5zcGxpdChcIl9fXCIpWzBdKTtcblxuICAgICAgLy8gaWQg7ZWE65Oc6rCAIG51bGzsnbgg6re466O5IOywvuq4sCAo7JiIOiBwYXJlbnRfX2lk6rCAIG51bGzsnbTrqbQgcGFyZW50IOq3uOujuSDsoITssrTqsIAgbnVsbClcbiAgICAgIGNvbnN0IG51bGxLZXlzID0gT2JqZWN0LmVudHJpZXMoZ3JvdXBzKVxuICAgICAgICAuZmlsdGVyKChbZ3JvdXBLZXksIGZpZWxkc10pID0+IHtcbiAgICAgICAgICBpZiAoIWZpZWxkcyB8fCBmaWVsZHMubGVuZ3RoID09PSAwKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgICAvLyDqt7jro7nsnZggaWQg7ZWE65OcIOywvuq4sCAo7JiIOiBcInBhcmVudF9faWRcIilcbiAgICAgICAgICBjb25zdCBpZEZpZWxkID0gYCR7Z3JvdXBLZXl9X19pZGA7XG4gICAgICAgICAgaWYgKGlkRmllbGQgaW4gcm93KSB7XG4gICAgICAgICAgICAvLyBpZCDtlYTrk5zqsIAgbnVsbOydtOuptCDqsJ3ssrQg7KCE7LK06rCAIG51bGxcbiAgICAgICAgICAgIHJldHVybiByb3dbaWRGaWVsZF0gPT09IG51bGw7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gaWQg7ZWE65Oc6rCAIOyXhuycvOuptCDquLDsobQg66Gc7KeBOiDrqqjrk6Ag7ZWE65Oc6rCAIG51bGzsnbjsp4Ag7ZmV7J24XG4gICAgICAgICAgcmV0dXJuIGZpZWxkcy5ldmVyeShcbiAgICAgICAgICAgIChmaWVsZCkgPT5cbiAgICAgICAgICAgICAgcm93W2ZpZWxkXSA9PT0gbnVsbCB8fCAoQXJyYXkuaXNBcnJheShyb3dbZmllbGRdKSAmJiByb3dbZmllbGRdLmxlbmd0aCA9PT0gMCksXG4gICAgICAgICAgKTtcbiAgICAgICAgfSlcbiAgICAgICAgLm1hcCgoW2tleV0pID0+IGtleSk7XG5cbiAgICAgIGNvbnN0IGh5ZHJhdGVkID0gT2JqZWN0LmtleXMocm93KS5yZWR1Y2UoKHIsIGZpZWxkKSA9PiB7XG4gICAgICAgIGlmICghZmllbGQuaW5jbHVkZXMoXCJfX1wiKSkge1xuICAgICAgICAgIC8vIOydvOuwmCDtlYTrk5w6IOuwsOyXtCDrgrQg6rCd7LK066m0IOyerOq3gCBoeWRyYXRlXG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocm93W2ZpZWxkXSkgJiYgaXNPYmplY3Qocm93W2ZpZWxkXVswXSkpIHtcbiAgICAgICAgICAgIHJbZmllbGRdID0gdGhpcy5oeWRyYXRlKHJvd1tmaWVsZF0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByW2ZpZWxkXSA9IHJvd1tmaWVsZF07XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiByO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8g7KSR7LKpIO2VhOuTnCDsspjrpqw6IHVzZXJfX25hbWUg4oaSIHVzZXJbbmFtZV1cbiAgICAgICAgY29uc3QgcGFydHMgPSBmaWVsZC5zcGxpdChcIl9fXCIpO1xuICAgICAgICBjb25zdCBvYmpQYXRoID1cbiAgICAgICAgICBwYXJ0c1swXSArXG4gICAgICAgICAgcGFydHNcbiAgICAgICAgICAgIC5zbGljZSgxKVxuICAgICAgICAgICAgLm1hcCgocGFydCkgPT4gYFske3BhcnR9XWApXG4gICAgICAgICAgICAuam9pbihcIlwiKTtcblxuICAgICAgICByID0gc2V0KFxuICAgICAgICAgIHIsXG4gICAgICAgICAgb2JqUGF0aCxcbiAgICAgICAgICByb3dbZmllbGRdICYmIEFycmF5LmlzQXJyYXkocm93W2ZpZWxkXSkgJiYgaXNPYmplY3Qocm93W2ZpZWxkXVswXSlcbiAgICAgICAgICAgID8gdGhpcy5oeWRyYXRlKHJvd1tmaWVsZF0pXG4gICAgICAgICAgICA6IHJvd1tmaWVsZF0sXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIHI7XG4gICAgICB9LCB7fSBhcyBVbmtub3duREJSZWNvcmQpO1xuXG4gICAgICAvLyBudWxsIHJlbGF0aW9uIOyymOumrFxuICAgICAgbnVsbEtleXMuZm9yRWFjaCgobnVsbEtleSkgPT4ge1xuICAgICAgICBoeWRyYXRlZFtudWxsS2V5XSA9IG51bGw7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGh5ZHJhdGVkO1xuICAgIH0pIGFzIFRbXTtcbiAgfVxufVxuXG4vKipcbiAqIEVuaGFuY2VyIO2MjOudvOuvuO2EsCDsobDqsbTrtoAg7YOA7J6FXG4gKiBSZXF1aXJlZEVuaGFuY2VyS2V5c+qwgCDsl4bsnLzrqbQgZW5oYW5jZXJzIOyEoO2DneyggSwg7J6I7Jy866m0IO2VhOyImFxuICovXG50eXBlIEVuaGFuY2VyUGFyYW08XG4gIFRTdWJzZXRLZXkgZXh0ZW5kcyBzdHJpbmcsXG4gIFRDb21wdXRlZFJlc3VsdHMgZXh0ZW5kcyBSZWNvcmQ8VFN1YnNldEtleSwgYW55PixcbiAgVFN1YnNldE1hcHBpbmcgZXh0ZW5kcyBSZWNvcmQ8VFN1YnNldEtleSwgYW55PixcbiAgVFN1YnNldFF1ZXJpZXMgZXh0ZW5kcyBSZWNvcmQ8VFN1YnNldEtleSwgUHVyaVN1YnNldEZuPixcbj4gPSBbUmVxdWlyZWRFbmhhbmNlcktleXM8VFN1YnNldEtleSwgVENvbXB1dGVkUmVzdWx0cywgVFN1YnNldE1hcHBpbmc+XSBleHRlbmRzIFtuZXZlcl1cbiAgPyB7IGVuaGFuY2Vycz86IEVuaGFuY2VyTWFwPFRTdWJzZXRLZXksIFRDb21wdXRlZFJlc3VsdHMsIFRTdWJzZXRNYXBwaW5nLCBUU3Vic2V0UXVlcmllcz4gfVxuICA6IHsgZW5oYW5jZXJzOiBFbmhhbmNlck1hcDxUU3Vic2V0S2V5LCBUQ29tcHV0ZWRSZXN1bHRzLCBUU3Vic2V0TWFwcGluZywgVFN1YnNldFF1ZXJpZXM+IH07XG5cbnR5cGUgUmVxdWlyZWRFbmhhbmNlcktleXM8XG4gIFRTdWJzZXRLZXkgZXh0ZW5kcyBzdHJpbmcsXG4gIFRDb21wdXRlZFJlc3VsdHMgZXh0ZW5kcyBSZWNvcmQ8VFN1YnNldEtleSwgYW55PixcbiAgVFN1YnNldE1hcHBpbmcgZXh0ZW5kcyBSZWNvcmQ8VFN1YnNldEtleSwgYW55Pixcbj4gPSB7XG4gIFtLIGluIFRTdWJzZXRLZXldOiBUQ29tcHV0ZWRSZXN1bHRzW0tdIGV4dGVuZHMgVFN1YnNldE1hcHBpbmdbS10gPyBuZXZlciA6IEs7XG59W1RTdWJzZXRLZXldO1xuXG5leHBvcnQgY29uc3QgQmFzZU1vZGVsID0gbmV3IEJhc2VNb2RlbENsYXNzKCk7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7O2NBTXVDO3NCQUNrQjthQUVxQjtnQkFDakI7a0JBR2U7VUFHbEQ7WUFDSTtvQkFNZTtzQkFFSTtDQVlwQyxpQkFBYixNQUtFO0VBQ0EsQUFBbUI7RUFFbkIsWUFDRSxBQUFnQkEsWUFBb0IsS0FBSyxZQUFZLE1BQ3JELEFBQVVDLGVBQ1YsQUFBVUMsZUFDVjtHQUhnQjtHQUNOO0dBQ0E7QUFFVixRQUFLLFNBQVMsVUFBVSx3QkFBd0IsS0FBSyxXQUFXLFFBQVEsQ0FBQzs7RUFHM0UsTUFBTSxPQUF1QjtBQUMzQixVQUFPLEdBQUcsTUFBTSxNQUFNOztFQUd4QixRQUFRLE9BQThCO0dBRXBDLE1BQU0sTUFBTSxHQUFHLHVCQUF1QixDQUFDLGVBQWUsTUFBTTtBQUM1RCxPQUFJLEtBQUs7QUFDUCxXQUFPOztHQUlULE1BQU0sS0FBSyxLQUFLLE1BQU0sTUFBTTtBQUM1QixVQUFPLElBQUksWUFBWSxJQUFJLElBQUksZUFBZSxDQUFDOztFQUdqRCxNQUFNLFVBQVU7QUFD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
318
+
319
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1tb2RlbC5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi9zcmMvZGF0YWJhc2UvYmFzZS1tb2RlbC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiogYmlvbWUtaWdub3JlLWFsbCBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogUHVyaeydmCDtg4DsnoXsnYAg6rCc67OEIOuqqOuNuOyXkOyEnCDtmZXsoJXrkJjrr4DroZwgQmFzZU1vZGVs7JeQ7ISc64qUIGFueeulvCDtl4jsmqntlaggKi9cbmltcG9ydCB7IGdldExvZ2dlciB9IGZyb20gXCJAbG9ndGFwZS9sb2d0YXBlXCI7XG5pbXBvcnQgeyB0eXBlIExvZ2dlciB9IGZyb20gXCJAbG9ndGFwZS9sb2d0YXBlXCI7XG5pbXBvcnQgeyB0eXBlIEtuZXggfSBmcm9tIFwia25leFwiO1xuaW1wb3J0IHsgY2xvbmVEZWVwLCBjbHVzdGVyLCBncm91cCwgaXNPYmplY3QsIG9taXQsIHNldCB9IGZyb20gXCJyYWRhc2hpXCI7XG5cbmltcG9ydCB7IFNvbmFtdSB9IGZyb20gXCIuLi9hcGkvc29uYW11XCI7XG5pbXBvcnQgeyBFbnRpdHlNYW5hZ2VyIH0gZnJvbSBcIi4uL2VudGl0eS9lbnRpdHktbWFuYWdlclwiO1xuaW1wb3J0IHsgdHlwZSBGaWx0ZXJPcGVyYXRvciwgdHlwZSBGaWx0ZXJRdWVyeSB9IGZyb20gXCIuLi9maWx0ZXIvdHlwZXNcIjtcbmltcG9ydCB7IG5vcm1hbGl6ZUZpbHRlclF1ZXJ5LCB2YWxpZGF0ZVNvbmFtdUZpbHRlcnMgfSBmcm9tIFwiLi4vZmlsdGVyL3V0aWxzXCI7XG5pbXBvcnQgeyBjb252ZXJ0RG9tYWluVG9DYXRlZ29yeSB9IGZyb20gXCIuLi9sb2dnZXIvY2F0ZWdvcnlcIjtcbmltcG9ydCB7IHR5cGUgRGF0YWJhc2VTY2hlbWFFeHRlbmQsIHR5cGUgU29uYW11UXVlcnlNb2RlIH0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQgeyB0eXBlIExpc3RSZXN1bHQgfSBmcm9tIFwiLi4vdXRpbHMvbW9kZWxcIjtcbmltcG9ydCB7IGdldEpvaW5UYWJsZXMsIGdldFRhYmxlTmFtZXNGcm9tV2hlcmUgfSBmcm9tIFwiLi4vdXRpbHMvc3FsLXBhcnNlclwiO1xuaW1wb3J0IHsgdHlwZSBFbmhhbmNlck1hcCwgdHlwZSBSZXNvbHZlU3Vic2V0SW50ZXJzZWN0aW9uIH0gZnJvbSBcIi4vYmFzZS1tb2RlbC50eXBlc1wiO1xuaW1wb3J0IHsgdHlwZSBEQlByZXNldCB9IGZyb20gXCIuL2RiXCI7XG5pbXBvcnQgeyBEQiB9IGZyb20gXCIuL2RiXCI7XG5pbXBvcnQgeyBQdXJpIH0gZnJvbSBcIi4vcHVyaVwiO1xuaW1wb3J0IHtcbiAgdHlwZSBJbmZlckFsbFN1YnNldHMsXG4gIHR5cGUgUHVyaUxvYWRlclF1ZXJpZXMsXG4gIHR5cGUgUHVyaVN1YnNldEZuLFxufSBmcm9tIFwiLi9wdXJpLXN1YnNldC50eXBlc1wiO1xuaW1wb3J0IHsgUHVyaVdyYXBwZXIgfSBmcm9tIFwiLi9wdXJpLXdyYXBwZXJcIjtcbmltcG9ydCB7IHR5cGUgVW5pb25FeHRyYWN0ZWRUVGFibGVzIH0gZnJvbSBcIi4vcHVyaS50eXBlc1wiO1xuaW1wb3J0IHsgVXBzZXJ0QnVpbGRlciB9IGZyb20gXCIuL3Vwc2VydC1idWlsZGVyXCI7XG5cbnR5cGUgVW5rbm93bkRCUmVjb3JkID0gUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG5cbi8qKlxuICog66qo65OgIE1vZGVsIO2BtOuemOyKpOydmCDquLDrs7gg7YG0656Y7IqkXG4gKlxuICogQHRlbXBsYXRlIFRTdWJzZXRLZXkgLSDshJzruIzshYsg7YKkIOycoOuLiOyYqCAo7JiIOiBcIkFcIiB8IFwiUFwiIHwgXCJTU1wiKVxuICogQHRlbXBsYXRlIFRTdWJzZXRNYXBwaW5nIC0g7ISc67iM7IWL67OEIOy1nOyihSDqsrDqs7wg7YOA7J6FIOunpO2VkVxuICogQHRlbXBsYXRlIFRTdWJzZXRRdWVyaWVzIC0g7ISc67iM7IWLIOy/vOumrCDtlajsiJgg6rCd7LK0XG4gKiBAdGVtcGxhdGUgVExvYWRlclF1ZXJpZXMgLSDshJzruIzshYvrs4Qg66Gc642UIOy/vOumrCDrsLDsl7Qg6rCd7LK0XG4gKi9cbmV4cG9ydCBjbGFzcyBCYXNlTW9kZWxDbGFzczxcbiAgVFN1YnNldEtleSBleHRlbmRzIHN0cmluZyA9IG5ldmVyLFxuICBUU3Vic2V0TWFwcGluZyBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4gPSBuZXZlcixcbiAgVFN1YnNldFF1ZXJpZXMgZXh0ZW5kcyBSZWNvcmQ8VFN1YnNldEtleSwgUHVyaVN1YnNldEZuPiA9IG5ldmVyLFxuICBUTG9hZGVyUXVlcmllcyBleHRlbmRzIFB1cmlMb2FkZXJRdWVyaWVzPFRTdWJzZXRLZXk+ID0gbmV2ZXIsXG4+IHtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGxvZ2dlcjogTG9nZ2VyO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyByZWFkb25seSBtb2RlbE5hbWU6IHN0cmluZyA9IHRoaXMuY29uc3RydWN0b3IubmFtZSxcbiAgICBwcm90ZWN0ZWQgc3Vic2V0UXVlcmllcz86IFRTdWJzZXRRdWVyaWVzLFxuICAgIHByb3RlY3RlZCBsb2FkZXJRdWVyaWVzPzogVExvYWRlclF1ZXJpZXMsXG4gICkge1xuICAgIHRoaXMubG9nZ2VyID0gZ2V0TG9nZ2VyKGNvbnZlcnREb21haW5Ub0NhdGVnb3J5KHRoaXMubW9kZWxOYW1lLCBcIm1vZGVsXCIpKTtcbiAgfVxuXG4gIGdldERCKHdoaWNoOiBEQlByZXNldCk6IEtuZXgge1xuICAgIHJldHVybiBEQi5nZXREQih3aGljaCk7XG4gIH1cblxuICBnZXRQdXJpKHdoaWNoOiBEQlByZXNldCk6IFB1cmlXcmFwcGVyIHtcbiAgICAvLyDtirjrnpzsnq3shZgg7Luo7YWN7Iqk7Yq47JeQ7IScIO2KuOuenOyereyFmCDtmo3rk51cbiAgICBjb25zdCB0cnggPSBEQi5nZXRUcmFuc2FjdGlvbkNvbnRleHQoKS5nZXRUcmFuc2FjdGlvbih3aGljaCk7XG4gICAgaWYgKHRyeCkge1xuICAgICAgcmV0dXJuIHRyeDtcbiAgICB9XG5cbiAgICAvLyDtirjrnpzsnq3shZjsnbQg7JeG7Jy866m0IOyDiOuhnOyatCBQdXJpV3JhcHBlciDrsJjtmZhcbiAgICBjb25zdCBkYiA9IHRoaXMuZ2V0REIod2hpY2gpO1xuICAgIHJldHVybiBuZXcgUHVyaVdyYXBwZXIoZGIsIG5ldyBVcHNlcnRCdWlsZGVyKCkpO1xuICB9XG5cbiAgYXN5bmMgZGVzdHJveSgpIHtcbiAgICByZXR1cm4gREIuZGVzdHJveSgpO1xuICB9XG5cbiAgYXN5bmMgZ2V0SW5zZXJ0ZWRJZHMoXG4gICAgd2RiOiBLbmV4LFxuICAgIHJvd3M6IFVua25vd25EQlJlY29yZFtdLFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIHVucUtleUZpZWxkczogc3RyaW5nW10sXG4gICAgY2h1bmtTaXplOiBudW1iZXIgPSA1MDAsXG4gICkge1xuICAgIGlmICghd2RiKSB7XG4gICAgICB3ZGIgPSB0aGlzLmdldERCKFwid1wiKTtcbiAgICB9XG5cbiAgICBsZXQgdW5xS2V5czogc3RyaW5nW107XG4gICAgbGV0IHdoZXJlSW5GaWVsZDogc3RyaW5nIHwgS25leC5SYXc7XG4gICAgbGV0IHNlbGVjdEZpZWxkOiBzdHJpbmc7XG5cbiAgICBpZiAodW5xS2V5RmllbGRzLmxlbmd0aCA+IDEpIHtcbiAgICAgIHdoZXJlSW5GaWVsZCA9IHdkYi5yYXcoYENPTkNBVF9XUygnXycsICcke3VucUtleUZpZWxkcy5qb2luKFwiLFwiKX0nKWApO1xuICAgICAgc2VsZWN0RmllbGQgPSBgJHt3aGVyZUluRmllbGR9IGFzIHRtcFVpZGA7XG4gICAgICB1bnFLZXlzID0gcm93cy5tYXAoKHJvdykgPT4gdW5xS2V5RmllbGRzLm1hcCgoZmllbGQpID0+IHJvd1tmaWVsZF0pLmpvaW4oXCJfXCIpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgd2hlcmVJbkZpZWxkID0gdW5xS2V5RmllbGRzWzBdO1xuICAgICAgc2VsZWN0RmllbGQgPSB1bnFLZXlGaWVsZHNbMF07XG4gICAgICB1bnFLZXlzID0gcm93cy5tYXAoKHJvdykgPT4gcm93W3VucUtleUZpZWxkc1swXV0gYXMgc3RyaW5nKTtcbiAgICB9XG5cbiAgICBsZXQgcmVzdWx0SWRzOiBudW1iZXJbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgaXRlbXMgb2YgY2x1c3Rlcih1bnFLZXlzLCBjaHVua1NpemUpKSB7XG4gICAgICBjb25zdCBkYlJvd3MgPSBhd2FpdCB3ZGIodGFibGVOYW1lKVxuICAgICAgICAuc2VsZWN0KFwiaWRcIiwgd2RiLnJhdyhzZWxlY3RGaWVsZCkpXG4gICAgICAgIC53aGVyZUluKHdoZXJlSW5GaWVsZCBhcyBzdHJpbmcsIGl0ZW1zKTtcbiAgICAgIHJlc3VsdElkcyA9IHJlc3VsdElkcy5jb25jYXQoXG4gICAgICAgIGRiUm93cy5tYXAoKGRiUm93OiBVbmtub3duREJSZWNvcmQpID0+IHBhcnNlSW50KFN0cmluZyhkYlJvdy5pZCkpKSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdElkcztcbiAgfVxuXG4gIC8qKlxuICAgKiDtirnsoJUg7ISc67iM7IWL7JeQIOuMgO2VnCDsv7zrpqwg67mM642UIO2ajeuTnVxuICAgKlxuICAgKiBAcmV0dXJucyBxYiAtIOy/vOumrCDruYzrjZQgKOyhsOqxtCDstpTqsIDsmqkpXG4gICAqIEByZXR1cm5zIG9uU3Vic2V0IC0g7Yq57KCVIOyEnOu4jOyFiyDsoITsmqkg7YOA7J6F7J20IO2VhOyalO2VoCDrlYwg7IKs7JqpXG4gICAqL1xuICBnZXRTdWJzZXRRdWVyaWVzPFQgZXh0ZW5kcyBUU3Vic2V0S2V5PihzdWJzZXQ6IFQpIHtcbiAgICBpZiAoIXRoaXMuc3Vic2V0UXVlcmllcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwic3Vic2V0UXVlcmllcyBpcyBub3QgZGVmaW5lZFwiKTtcbiAgICB9XG5cbiAgICBjb25zdCBwdXJpV3JhcHBlciA9IG5ldyBQdXJpV3JhcHBlcih0aGlzLmdldERCKFwiclwiKSwgbmV3IFVwc2VydEJ1aWxkZXIoKSk7XG4gICAgY29uc3QgcWIgPSB0aGlzLnN1YnNldFF1ZXJpZXNbc3Vic2V0XT8uKHB1cmlXcmFwcGVyKTtcblxuICAgIC8vIE5vbkFsbG93ZWRBc1NpbmdsZVRhYmxlOiDri6jsnbwg7YWM7J2067iUIOy7rOufvCDsoJHqt7wg67Cp7KeA7JqpIOuniOy7pFxuICAgIHR5cGUgUUJUYWJsZXMgPSBVbmlvbkV4dHJhY3RlZFRUYWJsZXM8VFN1YnNldEtleSwgVFN1YnNldFF1ZXJpZXM+ICYge1xuICAgICAgTm9uQWxsb3dlZEFzU2luZ2xlVGFibGU6IHsgX19mdWxsdGV4dF9fOiB0cnVlIH07XG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICBxYjogcWIgYXMgdW5rbm93biBhcyBQdXJpPERhdGFiYXNlU2NoZW1hRXh0ZW5kLCBRQlRhYmxlcywge30+LFxuICAgICAgb25TdWJzZXQ6ICgoX3N1YnNldDogVFN1YnNldEtleSB8IHJlYWRvbmx5IFRTdWJzZXRLZXlbXSkgPT4gcWIpIGFzIHtcbiAgICAgICAgLy8g64uo7J28IO2CpFxuICAgICAgICA8UyBleHRlbmRzIFRTdWJzZXRLZXk+KHN1YnNldDogUyk6IFJldHVyblR5cGU8VFN1YnNldFF1ZXJpZXNbU10+O1xuICAgICAgICAvLyDtgqQg67Cw7Je0IC0+IOq1kOynke2VqSDrsJjtmZhcbiAgICAgICAgPEFyciBleHRlbmRzIHJlYWRvbmx5IFRTdWJzZXRLZXlbXT4oXG4gICAgICAgICAgc3Vic2V0czogWy4uLkFycl0sXG4gICAgICAgICk6IFJlc29sdmVTdWJzZXRJbnRlcnNlY3Rpb248QXJyLCBUU3Vic2V0UXVlcmllcz47XG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogRW5oYW5jZXIg6rCd7LK0IOyDneyEsSDtl6ztjbxcbiAgICog7YOA7J6FIOqygOymnSDrsI8g7LaU66Gg7J2EIOuPhOyZgOykjFxuICAgKi9cbiAgY3JlYXRlRW5oYW5jZXJzPFQgZXh0ZW5kcyBUU3Vic2V0S2V5PihcbiAgICBlbmhhbmNlcnM6IEVuaGFuY2VyTWFwPFxuICAgICAgVCxcbiAgICAgIEluZmVyQWxsU3Vic2V0czxUU3Vic2V0UXVlcmllcywgVExvYWRlclF1ZXJpZXM+LFxuICAgICAgVFN1YnNldE1hcHBpbmcsXG4gICAgICBUU3Vic2V0UXVlcmllc1xuICAgID4sXG4gICkge1xuICAgIHJldHVybiBlbmhhbmNlcnM7XG4gIH1cblxuICAvKipcbiAgICog7ISc67iM7IWLIOy/vOumrCDsi6TtlolcbiAgICpcbiAgICogMS4gU29uYW11IO2VhO2EsCDsoIHsmqkgKO2DgOyehSDrs4DtmZgg7Y+s7ZWoKVxuICAgKiAyLiDsv7zrpqwg7Iuk7ZaJIChwYWdpbmF0aW9uIOyggeyaqSlcbiAgICogMy4g66Gc642UIOyLpO2WiSAoMTpOLCBOOk0g6rSA6rOEIOuNsOydtO2EsCDroZzrlKkpXG4gICAqIDQuIEh5ZHJhdGUgKGZsYXQg4oaSIOykkeyyqSDqsJ3ssrQpXG4gICAqIDUuIEVuaGFuY2VyIOyggeyaqSAodmlydHVhbCDtlYTrk5wg6rOE7IKwKVxuICAgKi9cbiAgYXN5bmMgZXhlY3V0ZVN1YnNldFF1ZXJ5PFxuICAgIFQgZXh0ZW5kcyBUU3Vic2V0S2V5LFxuICAgIFRDb21wdXRlZFJlc3VsdHMgZXh0ZW5kcyBJbmZlckFsbFN1YnNldHM8VFN1YnNldFF1ZXJpZXMsIFRMb2FkZXJRdWVyaWVzPixcbiAgICBMUCBleHRlbmRzIHtcbiAgICAgIG51bT86IG51bWJlcjtcbiAgICAgIHBhZ2U/OiBudW1iZXI7XG4gICAgICBxdWVyeU1vZGU/OiBTb25hbXVRdWVyeU1vZGU7XG4gICAgICBzb25hbXVGaWx0ZXI/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICB9LFxuICA+KFxuICAgIHBhcmFtczoge1xuICAgICAgc3Vic2V0OiBUO1xuICAgICAgcWI6IFB1cmk8YW55LCBhbnksIGFueT47XG4gICAgICBwYXJhbXM6IHtcbiAgICAgICAgbnVtOiBudW1iZXI7XG4gICAgICAgIHBhZ2U6IG51bWJlcjtcbiAgICAgICAgcXVlcnlNb2RlPzogU29uYW11UXVlcnlNb2RlO1xuICAgICAgICBzb25hbXVGaWx0ZXI/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgIH07XG4gICAgICBkZWJ1Zz86IGJvb2xlYW47XG4gICAgICBvcHRpbWl6ZUNvdW50UXVlcnk/OiBib29sZWFuO1xuICAgIH0gJiBFbmhhbmNlclBhcmFtPFRTdWJzZXRLZXksIFRDb21wdXRlZFJlc3VsdHMsIFRTdWJzZXRNYXBwaW5nLCBUU3Vic2V0UXVlcmllcz4sXG4gICk6IFByb21pc2U8TGlzdFJlc3VsdDxMUCwgVFN1YnNldE1hcHBpbmdbVF0+PiB7XG4gICAgY29uc3QgeyBzdWJzZXQsIHFiLCBwYXJhbXM6IHF1ZXJ5UGFyYW1zLCBkZWJ1ZyA9IGZhbHNlLCBvcHRpbWl6ZUNvdW50UXVlcnkgPSBmYWxzZSB9ID0gcGFyYW1zO1xuXG4gICAgaWYgKCF0aGlzLmxvYWRlclF1ZXJpZXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImxvYWRlclF1ZXJpZXMgaXMgbm90IGRlZmluZWRcIik7XG4gICAgfVxuXG4gICAgLy8gU29uYW11IEZpbHRlciDsoIHsmqlcbiAgICBpZiAocXVlcnlQYXJhbXMuc29uYW11RmlsdGVyKSB7XG4gICAgICBjb25zdCBub3JtYWxpemVkRmlsdGVyID0gbm9ybWFsaXplRmlsdGVyUXVlcnkocXVlcnlQYXJhbXMuc29uYW11RmlsdGVyKTtcbiAgICAgIHRoaXMuYXBwbHlTb25hbXVGaWx0ZXJzKHFiLCBub3JtYWxpemVkRmlsdGVyKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IG51bSwgcGFnZSB9ID0gcXVlcnlQYXJhbXM7XG5cbiAgICAvLyBDT1VOVCDsv7zrpqwg7Iuk7ZaJIChxdWVyeU1vZGU6IGxpc3Tsnbwg65WM64qUIDAg66as7YS0KVxuICAgIGNvbnN0IHRvdGFsID0gYXdhaXQgdGhpcy5leGVjdXRlQ291bnRRdWVyeShxYiwgcXVlcnlQYXJhbXMsIGRlYnVnLCBvcHRpbWl6ZUNvdW50UXVlcnkpO1xuXG4gICAgaWYgKHF1ZXJ5UGFyYW1zPy5xdWVyeU1vZGUgPT09IFwiY291bnRcIikge1xuICAgICAgcmV0dXJuIHsgdG90YWwgfSBhcyBMaXN0UmVzdWx0PExQLCBUU3Vic2V0TWFwcGluZ1tUXT47XG4gICAgfVxuXG4gICAgLy8gTElTVCDsv7zrpqwg7Iuk7ZaJXG4gICAgY29uc3QgY29tcHV0ZWRSb3dzID0gYXdhaXQgdGhpcy5leGVjdXRlTGlzdFF1ZXJ5KHN1YnNldCwgcWIsIHF1ZXJ5UGFyYW1zLCBudW0sIHBhZ2UsIGRlYnVnKTtcblxuICAgIC8vIEVuaGFuY2VyIOyggeyaqVxuICAgIGNvbnN0IGVuaGFuY2VyID0gKHBhcmFtcyBhcyBhbnkpLmVuaGFuY2Vycz8uW3N1YnNldF07XG4gICAgY29uc3QgZW5oYW5jZWRSb3dzID0gKGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgY29tcHV0ZWRSb3dzLm1hcCgocm93KSA9PiBlbmhhbmNlcj8uKHJvdykgPz8gcm93KSxcbiAgICApKSBhcyBUU3Vic2V0TWFwcGluZ1tUXVtdO1xuXG4gICAgLy8gSW50ZXJuYWwg7ZWE65OcIOygnOqxsFxuICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KHRoaXMubW9kZWxOYW1lKTtcbiAgICBjb25zdCBpbnRlcm5hbEZpZWxkcyA9IGVudGl0eS5zdWJzZXRzSW50ZXJuYWxbc3Vic2V0XSA/PyBbXTtcbiAgICBjb25zdCByb3dzID1cbiAgICAgIGludGVybmFsRmllbGRzLmxlbmd0aCA+IDBcbiAgICAgICAgPyBlbmhhbmNlZFJvd3MubWFwKChyb3cpID0+IHRoaXMub21pdEludGVybmFsRmllbGRzKHJvdywgaW50ZXJuYWxGaWVsZHMpKVxuICAgICAgICA6IGVuaGFuY2VkUm93cztcblxuICAgIGlmIChxdWVyeVBhcmFtcy5xdWVyeU1vZGUgPT09IFwibGlzdFwiKSB7XG4gICAgICAvLyDrpqzsiqTtirjrp4wg66as7YS0XG4gICAgICByZXR1cm4geyByb3dzIH0gYXMgTGlzdFJlc3VsdDxMUCwgVFN1YnNldE1hcHBpbmdbVF0+O1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyDrkZjri6Qg66as7YS0XG4gICAgICByZXR1cm4geyByb3dzLCB0b3RhbCB9IGFzIExpc3RSZXN1bHQ8TFAsIFRTdWJzZXRNYXBwaW5nW1RdPjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog6rCd7LK07JeQ7IScIGludGVybmFsIO2VhOuTnCDsoJzqsbBcbiAgICog7KSR7LKpIO2VhOuTnCjsmIg6IFwidXNlci5lbWFpbFwiKSDrsI8g67Cw7Je0KOyYiDogXCJlbXBsb3llZXMuc2FsYXJ5XCIp64+EIOyymOumrFxuICAgKi9cbiAgb21pdEludGVybmFsRmllbGRzPFQgZXh0ZW5kcyBvYmplY3Q+KHJvdzogVCwgZmllbGRzOiBzdHJpbmdbXSk6IFQge1xuICAgIGNvbnN0IHJlc3VsdCA9IGNsb25lRGVlcChyb3cpO1xuICAgIGZvciAoY29uc3QgZmllbGQgb2YgZmllbGRzKSB7XG4gICAgICB0aGlzLmRlbGV0ZUZpZWxkKHJlc3VsdCwgZmllbGQuc3BsaXQoXCIuXCIpKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXJRdWVyeeulvCBQdXJpIFF1ZXJ5QnVpbGRlcuyXkCDsoIHsmqlcbiAgICpcbiAgICogQHBhcmFtIHFiIFB1cmkgUXVlcnlCdWlsZGVyIOyduOyKpO2EtOyKpFxuICAgKiBAcGFyYW0gZmlsdGVycyBGaWx0ZXJRdWVyeSDqsJ3ssrRcbiAgICovXG4gIHByb3RlY3RlZCBhcHBseVNvbmFtdUZpbHRlcnM8VEVudGl0eSA9IFJlY29yZDxzdHJpbmcsIHVua25vd24+PihcbiAgICBxYjogUHVyaTxhbnksIGFueSwgYW55PixcbiAgICBmaWx0ZXJzPzogRmlsdGVyUXVlcnk8VEVudGl0eT4sXG4gICk6IHZvaWQge1xuICAgIGlmICghZmlsdGVycykgcmV0dXJuO1xuXG4gICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQodGhpcy5tb2RlbE5hbWUpO1xuXG4gICAgLy8gMS4g7ZWE7YSwIOqygOymnSAoRW50aXR5IOq4sOuwmClcbiAgICB2YWxpZGF0ZVNvbmFtdUZpbHRlcnMoZmlsdGVycywgZW50aXR5KTtcblxuICAgIC8vIDIuIOqygOymneuQnCDtlYTthLAg7KCB7JqpXG4gICAgY29uc3QgcHVyaSA9IHFiIGFzIGFueTtcblxuICAgIGZvciAoY29uc3QgW2ZpZWxkLCBjb25kaXRpb25dIG9mIE9iamVjdC5lbnRyaWVzKGZpbHRlcnMpKSB7XG4gICAgICBpZiAoY29uZGl0aW9uID09PSB1bmRlZmluZWQgfHwgY29uZGl0aW9uID09PSBudWxsKSBjb250aW51ZTtcblxuICAgICAgLy8g7YWM7J2067iU66qFLu2VhOuTnOuqhSDtmJXsi53snLzroZwg67OA7ZmYXG4gICAgICBjb25zdCBmdWxsRmllbGQgPSBlbnRpdHkuZ2V0RnVsbEZpZWxkTmFtZShmaWVsZCk7XG5cbiAgICAgIC8vIOyngeygkSDqsJIgKGVx7JmAIOuPmeydvClcbiAgICAgIGlmICh0eXBlb2YgY29uZGl0aW9uICE9PSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkoY29uZGl0aW9uKSkge1xuICAgICAgICBwdXJpLndoZXJlKGZ1bGxGaWVsZCwgY29uZGl0aW9uKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIOyXsOyCsOyekCDqsJ3ssrRcbiAgICAgIGZvciAoY29uc3QgW29wZXJhdG9yLCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoY29uZGl0aW9uKSkge1xuICAgICAgICB0aGlzLmFwcGx5T3BlcmF0b3IocWIsIGZ1bGxGaWVsZCwgb3BlcmF0b3IgYXMgRmlsdGVyT3BlcmF0b3IsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog64uo7J28IOyXsOyCsOyekOulvCBRdWVyeUJ1aWxkZXLsl5Ag7KCB7JqpXG4gICAqL1xuICBwcml2YXRlIGFwcGx5T3BlcmF0b3IoXG4gICAgcWI6IFB1cmk8YW55LCBhbnksIGFueT4sXG4gICAgZmllbGQ6IHN0cmluZyxcbiAgICBvcGVyYXRvcjogRmlsdGVyT3BlcmF0b3IsXG4gICAgdmFsdWU6IHVua25vd24sXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHB1cmkgPSBxYiBhcyBhbnk7XG5cbiAgICBzd2l0Y2ggKG9wZXJhdG9yKSB7XG4gICAgICBjYXNlIFwiZXFcIjpcbiAgICAgICAgcHVyaS53aGVyZShmaWVsZCwgdmFsdWUpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcIm5lXCI6XG4gICAgICAgIHB1cmkud2hlcmUoZmllbGQsIFwiIT1cIiwgdmFsdWUpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcImd0XCI6XG4gICAgICAgIHB1cmkud2hlcmUoZmllbGQsIFwiPlwiLCB2YWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIFwiZ3RlXCI6XG4gICAgICAgIHB1cmkud2hlcmUoZmllbGQsIFwiPj1cIiwgdmFsdWUpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcImx0XCI6XG4gICAgICAgIHB1cmkud2hlcmUoZmllbGQsIFwiPFwiLCB2YWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlIFwibHRlXCI6XG4gICAgICAgIHB1cmkud2hlcmUoZmllbGQsIFwiPD1cIiwgdmFsdWUpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcImluXCI6XG4gICAgICAgIHB1cmkud2hlcmVJbihmaWVsZCwgdmFsdWUpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcIm5vdEluXCI6XG4gICAgICAgIHB1cmkud2hlcmVOb3RJbihmaWVsZCwgdmFsdWUpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcImNvbnRhaW5zXCI6XG4gICAgICAgIHB1cmkud2hlcmUoZmllbGQsIFwibGlrZVwiLCBgJSR7dmFsdWV9JWApO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcInN0YXJ0c1dpdGhcIjpcbiAgICAgICAgcHVyaS53aGVyZShmaWVsZCwgXCJsaWtlXCIsIGAke3ZhbHVlfSVgKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgXCJlbmRzV2l0aFwiOlxuICAgICAgICBwdXJpLndoZXJlKGZpZWxkLCBcImxpa2VcIiwgYCUke3ZhbHVlfWApO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcImlzTnVsbFwiOlxuICAgICAgICBwdXJpLndoZXJlKGZpZWxkLCBudWxsKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgXCJpc05vdE51bGxcIjpcbiAgICAgICAgcHVyaS53aGVyZShmaWVsZCwgXCIhPVwiLCBudWxsKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgXCJiZWZvcmVcIjpcbiAgICAgICAgcHVyaS53aGVyZShmaWVsZCwgXCI8XCIsIHZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgXCJhZnRlclwiOlxuICAgICAgICBwdXJpLndoZXJlKGZpZWxkLCBcIj5cIiwgdmFsdWUpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBcImJldHdlZW5cIjoge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgY29uc3QgW21pbiwgbWF4XSA9IHZhbHVlO1xuICAgICAgICAgIHB1cmkud2hlcmUoZmllbGQsIFwiPj1cIiwgbWluKS53aGVyZShmaWVsZCwgXCI8PVwiLCBtYXgpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBjb25zb2xlLndhcm4oYFVuc3VwcG9ydGVkIG9wZXJhdG9yOiAke29wZXJhdG9yfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDspJHssqkg7ZWE65OcIOyCreygnCAo67Cw7Je0IOuCtCDqsJ3ssrTrj4Qg7LKY66asKVxuICAgKi9cbiAgZGVsZXRlRmllbGQob2JqOiBhbnksIHBhcnRzOiBzdHJpbmdbXSk6IHZvaWQge1xuICAgIGlmICghb2JqIHx8IHR5cGVvZiBvYmogIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocGFydHMubGVuZ3RoID09PSAxKSB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgICAgIG9iai5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICAgICAgaWYgKGl0ZW0gJiYgdHlwZW9mIGl0ZW0gPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgIGRlbGV0ZSBpdGVtW3BhcnRzWzBdXTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVsZXRlIG9ialtwYXJ0c1swXV07XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgW2ZpcnN0LCAuLi5yZXN0XSA9IHBhcnRzO1xuICAgIGNvbnN0IG5leHQgPSBvYmpbZmlyc3RdO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkobmV4dCkpIHtcbiAgICAgIG5leHQubWFwKChpdGVtKSA9PiB0aGlzLmRlbGV0ZUZpZWxkKGl0ZW0sIHJlc3QpKTtcbiAgICB9IGVsc2UgaWYgKG5leHQgJiYgdHlwZW9mIG5leHQgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRoaXMuZGVsZXRlRmllbGQobmV4dCwgcmVzdCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENPVU5UIOy/vOumrCDsi6TtlokgKOuCtOu2gCDrqZTshJzrk5wpXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGV4ZWN1dGVDb3VudFF1ZXJ5KFxuICAgIHFiOiBQdXJpPGFueSwgYW55LCBhbnk+LFxuICAgIHBhcmFtczogeyBxdWVyeU1vZGU/OiBcImxpc3RcIiB8IFwiY291bnRcIiB8IFwiYm90aFwiIH0sXG4gICAgZGVidWc6IGJvb2xlYW4sXG4gICAgb3B0aW1pemVDb3VudFF1ZXJ5OiBib29sZWFuLFxuICApOiBQcm9taXNlPG51bWJlcj4ge1xuICAgIGlmIChwYXJhbXMucXVlcnlNb2RlID09PSBcImxpc3RcIikge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgY29uc3QgY291bnRQdXJpID0gcWIuY2xvbmUoKS5jbGVhcihcIm9yZGVyXCIpLmNsZWFyKFwibGltaXRcIikuY2xlYXIoXCJvZmZzZXRcIik7XG5cbiAgICBpZiAob3B0aW1pemVDb3VudFF1ZXJ5KSB7XG4gICAgICBjb25zdCB7IGRlZmF1bHQ6IFNxbFBhcnNlciB9ID0gYXdhaXQgaW1wb3J0KFwibm9kZS1zcWwtcGFyc2VyXCIpO1xuICAgICAgY29uc3QgcGFyc2VyID0gbmV3IFNxbFBhcnNlci5QYXJzZXIoKTtcbiAgICAgIGNvbnN0IHBhcnNlZFF1ZXJ5ID0gcGFyc2VyLmFzdGlmeShjb3VudFB1cmkudG9RdWVyeSgpLCB7XG4gICAgICAgIGRhdGFiYXNlOiBTb25hbXUuY29uZmlnLmRhdGFiYXNlLmRhdGFiYXNlLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGxlZnRKb2luVGFibGVzID0gZ2V0Sm9pblRhYmxlcyhwYXJzZWRRdWVyeSwgW1wiTEVGVCBKT0lOXCJdKTtcbiAgICAgIGNvbnN0IHdoZXJlVGFibGVzID0gZ2V0VGFibGVOYW1lc0Zyb21XaGVyZShwYXJzZWRRdWVyeSk7XG5cbiAgICAgIGNvbnN0IHRhYmxlc1RvUmVtb3ZlID0gbGVmdEpvaW5UYWJsZXMuZmlsdGVyKChqKSA9PiAhd2hlcmVUYWJsZXMuaW5jbHVkZXMoaikpO1xuICAgICAgdGFibGVzVG9SZW1vdmUuZm9yRWFjaCgodGFibGUpID0+IHtcbiAgICAgICAgY291bnRQdXJpLmNsZWFySm9pbih0YWJsZSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBDT1VOVCgqKeuhnCDsoITssrQg66CI7L2U65OcIOyImOulvCDqs4TsgrBcbiAgICAvLyBUT0RPOiBxYuydmCBESVNUSU5DVOqwgCDsnojripQg6rK97JqwIOyymOumrO2VtOyVvCDtlahcbiAgICBjb25zdCBjb3VudFJlc3VsdDogeyB0b3RhbD86IG51bWJlciB9ID0gYXdhaXQgY291bnRQdXJpXG4gICAgICAuY2xlYXIoXCJzZWxlY3RcIilcbiAgICAgIC5zZWxlY3QoeyB0b3RhbDogUHVyaS5yYXdOdW1iZXIoYENPVU5UKCopOjppbnRlZ2VyYCkgfSlcbiAgICAgIC5maXJzdCgpO1xuXG4gICAgaWYgKGRlYnVnKSB7XG4gICAgICBjb3VudFB1cmkuZGVidWcoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY291bnRSZXN1bHQ/LnRvdGFsID8/IDA7XG4gIH1cblxuICAvKipcbiAgICogTElTVCDsv7zrpqwg7Iuk7ZaJICjrgrTrtoAg66mU7ISc65OcKVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBleGVjdXRlTGlzdFF1ZXJ5PFQgZXh0ZW5kcyBUU3Vic2V0S2V5PihcbiAgICBzdWJzZXQ6IFQsXG4gICAgcWI6IFB1cmk8YW55LCBhbnksIGFueT4sXG4gICAgcGFyYW1zOiB7IHF1ZXJ5TW9kZT86IFwibGlzdFwiIHwgXCJjb3VudFwiIHwgXCJib3RoXCIgfSxcbiAgICBudW06IG51bWJlcixcbiAgICBwYWdlOiBudW1iZXIsXG4gICAgZGVidWc6IGJvb2xlYW4sXG4gICk6IFByb21pc2U8YW55W10+IHtcbiAgICBpZiAocGFyYW1zLnF1ZXJ5TW9kZSA9PT0gXCJjb3VudFwiKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgY29uc3QgbGltaXRlZFFiID0gKCgpID0+IHtcbiAgICAgIGlmIChudW0gPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHFiO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHFiLmxpbWl0KG51bSkub2Zmc2V0KG51bSAqIChwYWdlIC0gMSkpO1xuICAgICAgfVxuICAgIH0pKCk7XG4gICAgbGV0IHVubG9hZGVkUm93cyA9IGF3YWl0IGxpbWl0ZWRRYjtcblxuICAgIGlmIChkZWJ1Zykge1xuICAgICAgcWIuZGVidWcoKTtcbiAgICB9XG5cbiAgICAvLyDroZzrjZQg7LKY66asXG4gICAgY29uc3QgbG9hZGVycyA9ICh0aGlzLmxvYWRlclF1ZXJpZXMgYXMgYW55KVtzdWJzZXRdO1xuICAgIGlmIChsb2FkZXJzICYmIEFycmF5LmlzQXJyYXkobG9hZGVycykpIHtcbiAgICAgIHVubG9hZGVkUm93cyA9IGF3YWl0IHRoaXMucHJvY2Vzc0xvYWRlcnModW5sb2FkZWRSb3dzLCBsb2FkZXJzLCBkZWJ1Zyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuaHlkcmF0ZSh1bmxvYWRlZFJvd3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIOyerOq3gOyggSDroZzrjZQg7LKY66asXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHByb2Nlc3NMb2FkZXJzKHJvd3M6IGFueVtdLCBsb2FkZXJzOiBhbnlbXSwgZGVidWc6IGJvb2xlYW4pOiBQcm9taXNlPGFueVtdPiB7XG4gICAgZm9yIChjb25zdCByZXNvbHZlTG9hZGVyIG9mIGxvYWRlcnMpIHtcbiAgICAgIGNvbnN0IHsgYXMsIHJlZklkLCBxYjogcmVzb2x2ZUxvYWRlclFiRm4sIGxvYWRlcnM6IG5lc3RlZExvYWRlcnMgfSA9IHJlc29sdmVMb2FkZXI7XG5cbiAgICAgIGNvbnN0IHJlc29sdmVMb2FkZXJRYiA9IHJlc29sdmVMb2FkZXJRYkZuKFxuICAgICAgICBuZXcgUHVyaVdyYXBwZXIodGhpcy5nZXREQihcInJcIiksIG5ldyBVcHNlcnRCdWlsZGVyKCkpLFxuICAgICAgICByb3dzLm1hcCgocm93KSA9PiByb3dbcmVmSWRdKSxcbiAgICAgICk7XG5cbiAgICAgIGlmIChkZWJ1Zykge1xuICAgICAgICByZXNvbHZlTG9hZGVyUWIuZGVidWcoKTtcbiAgICAgIH1cblxuICAgICAgbGV0IGxvYWRlZFJvd3MgPSAoYXdhaXQgcmVzb2x2ZUxvYWRlclFiKSBhcyBhbnlbXTtcblxuICAgICAgLy8g7KSR7LKpIGxvYWRlcnPqsIAg7J6I7Jy866m0IOyerOq3gCDsspjrpqxcbiAgICAgIGlmIChuZXN0ZWRMb2FkZXJzICYmIG5lc3RlZExvYWRlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICBsb2FkZWRSb3dzID0gYXdhaXQgdGhpcy5wcm9jZXNzTG9hZGVycyhsb2FkZWRSb3dzLCBuZXN0ZWRMb2FkZXJzLCBkZWJ1Zyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHN1YlJvd0dyb3VwcyA9IGdyb3VwKGxvYWRlZFJvd3MsIChyb3cpID0+IHJvdy5yZWZJZCk7XG5cbiAgICAgIHJvd3MgPSByb3dzLm1hcCgocm93KSA9PiB7XG4gICAgICAgIHJvd1thc10gPSAoc3ViUm93R3JvdXBzW3Jvd1tyZWZJZF1dID8/IFtdKS5tYXAoKHIpID0+IG9taXQociwgW1wicmVmSWRcIl0pKTtcbiAgICAgICAgcmV0dXJuIHJvdztcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiByb3dzO1xuICB9XG5cbiAgLyoqXG4gICAqIEZsYXQg66CI7L2U65Oc66W8IOykkeyyqSDqsJ3ssrTroZwg67OA7ZmYXG4gICAqXG4gICAqIC0gYHVzZXJfX25hbWVgIOKGkiBgeyB1c2VyOiB7IG5hbWUgfSB9YFxuICAgKiAtIG51bGxhYmxlIHJlbGF0aW9u7J2YIOqyveyasCBpZCDtlYTrk5zqsIAgbnVsbOydtOuptCDqsJ3ssrQg7J6Q7LK066W8IG51bGzroZxcbiAgICovXG4gIGh5ZHJhdGU8VCBleHRlbmRzIFVua25vd25EQlJlY29yZD4ocm93czogVFtdKTogVFtdIHtcbiAgICByZXR1cm4gcm93cy5tYXAoKHJvdzogVCkgPT4ge1xuICAgICAgLy8gbnVsbGFibGUgcmVsYXRpb24g7LKY66asOiDqt7jro7nsnZggaWQg7ZWE65Oc6rCAIG51bGzsnbTrqbQg6rCd7LK0IOyghOyytOulvCBudWxs66GcXG4gICAgICBjb25zdCBuZXN0ZWRLZXlzID0gT2JqZWN0LmtleXMocm93KS5maWx0ZXIoKGtleSkgPT4ga2V5LmluY2x1ZGVzKFwiX19cIikpO1xuICAgICAgY29uc3QgZ3JvdXBzID0gT2JqZWN0Lmdyb3VwQnkobmVzdGVkS2V5cywgKGtleSkgPT4ga2V5LnNwbGl0KFwiX19cIilbMF0pO1xuXG4gICAgICAvLyBpZCDtlYTrk5zqsIAgbnVsbOyduCDqt7jro7kg7LC+6riwICjsmIg6IHBhcmVudF9faWTqsIAgbnVsbOydtOuptCBwYXJlbnQg6re466O5IOyghOyytOqwgCBudWxsKVxuICAgICAgY29uc3QgbnVsbEtleXMgPSBPYmplY3QuZW50cmllcyhncm91cHMpXG4gICAgICAgIC5maWx0ZXIoKFtncm91cEtleSwgZmllbGRzXSkgPT4ge1xuICAgICAgICAgIGlmICghZmllbGRzIHx8IGZpZWxkcy5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcblxuICAgICAgICAgIC8vIOq3uOujueydmCBpZCDtlYTrk5wg7LC+6riwICjsmIg6IFwicGFyZW50X19pZFwiKVxuICAgICAgICAgIGNvbnN0IGlkRmllbGQgPSBgJHtncm91cEtleX1fX2lkYDtcbiAgICAgICAgICBpZiAoaWRGaWVsZCBpbiByb3cpIHtcbiAgICAgICAgICAgIC8vIGlkIO2VhOuTnOqwgCBudWxs7J2066m0IOqwneyytCDsoITssrTqsIAgbnVsbFxuICAgICAgICAgICAgcmV0dXJuIHJvd1tpZEZpZWxkXSA9PT0gbnVsbDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBpZCDtlYTrk5zqsIAg7JeG7Jy866m0IOq4sOyhtCDroZzsp4E6IOuqqOuToCDtlYTrk5zqsIAgbnVsbOyduOyngCDtmZXsnbhcbiAgICAgICAgICByZXR1cm4gZmllbGRzLmV2ZXJ5KFxuICAgICAgICAgICAgKGZpZWxkKSA9PlxuICAgICAgICAgICAgICByb3dbZmllbGRdID09PSBudWxsIHx8IChBcnJheS5pc0FycmF5KHJvd1tmaWVsZF0pICYmIHJvd1tmaWVsZF0ubGVuZ3RoID09PSAwKSxcbiAgICAgICAgICApO1xuICAgICAgICB9KVxuICAgICAgICAubWFwKChba2V5XSkgPT4ga2V5KTtcblxuICAgICAgY29uc3QgaHlkcmF0ZWQgPSBPYmplY3Qua2V5cyhyb3cpLnJlZHVjZSgociwgZmllbGQpID0+IHtcbiAgICAgICAgaWYgKCFmaWVsZC5pbmNsdWRlcyhcIl9fXCIpKSB7XG4gICAgICAgICAgLy8g7J2867CYIO2VhOuTnDog67Cw7Je0IOuCtCDqsJ3ssrTrqbQg7J6s6reAIGh5ZHJhdGVcbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShyb3dbZmllbGRdKSAmJiBpc09iamVjdChyb3dbZmllbGRdWzBdKSkge1xuICAgICAgICAgICAgcltmaWVsZF0gPSB0aGlzLmh5ZHJhdGUocm93W2ZpZWxkXSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJbZmllbGRdID0gcm93W2ZpZWxkXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHI7XG4gICAgICAgIH1cblxuICAgICAgICAvLyDspJHssqkg7ZWE65OcIOyymOumrDogdXNlcl9fbmFtZSDihpIgdXNlcltuYW1lXVxuICAgICAgICBjb25zdCBwYXJ0cyA9IGZpZWxkLnNwbGl0KFwiX19cIik7XG4gICAgICAgIGNvbnN0IG9ialBhdGggPVxuICAgICAgICAgIHBhcnRzWzBdICtcbiAgICAgICAgICBwYXJ0c1xuICAgICAgICAgICAgLnNsaWNlKDEpXG4gICAgICAgICAgICAubWFwKChwYXJ0KSA9PiBgWyR7cGFydH1dYClcbiAgICAgICAgICAgIC5qb2luKFwiXCIpO1xuXG4gICAgICAgIHIgPSBzZXQoXG4gICAgICAgICAgcixcbiAgICAgICAgICBvYmpQYXRoLFxuICAgICAgICAgIHJvd1tmaWVsZF0gJiYgQXJyYXkuaXNBcnJheShyb3dbZmllbGRdKSAmJiBpc09iamVjdChyb3dbZmllbGRdWzBdKVxuICAgICAgICAgICAgPyB0aGlzLmh5ZHJhdGUocm93W2ZpZWxkXSlcbiAgICAgICAgICAgIDogcm93W2ZpZWxkXSxcbiAgICAgICAgKTtcblxuICAgICAgICByZXR1cm4gcjtcbiAgICAgIH0sIHt9IGFzIFVua25vd25EQlJlY29yZCk7XG5cbiAgICAgIC8vIG51bGwgcmVsYXRpb24g7LKY66asXG4gICAgICBudWxsS2V5cy5mb3JFYWNoKChudWxsS2V5KSA9PiB7XG4gICAgICAgIGh5ZHJhdGVkW251bGxLZXldID0gbnVsbDtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gaHlkcmF0ZWQ7XG4gICAgfSkgYXMgVFtdO1xuICB9XG59XG5cbi8qKlxuICogRW5oYW5jZXIg7YyM652866+47YSwIOyhsOqxtOu2gCDtg4DsnoVcbiAqIFJlcXVpcmVkRW5oYW5jZXJLZXlz6rCAIOyXhuycvOuptCBlbmhhbmNlcnMg7ISg7YOd7KCBLCDsnojsnLzrqbQg7ZWE7IiYXG4gKi9cbnR5cGUgRW5oYW5jZXJQYXJhbTxcbiAgVFN1YnNldEtleSBleHRlbmRzIHN0cmluZyxcbiAgVENvbXB1dGVkUmVzdWx0cyBleHRlbmRzIFJlY29yZDxUU3Vic2V0S2V5LCBhbnk+LFxuICBUU3Vic2V0TWFwcGluZyBleHRlbmRzIFJlY29yZDxUU3Vic2V0S2V5LCBhbnk+LFxuICBUU3Vic2V0UXVlcmllcyBleHRlbmRzIFJlY29yZDxUU3Vic2V0S2V5LCBQdXJpU3Vic2V0Rm4+LFxuPiA9IFtSZXF1aXJlZEVuaGFuY2VyS2V5czxUU3Vic2V0S2V5LCBUQ29tcHV0ZWRSZXN1bHRzLCBUU3Vic2V0TWFwcGluZz5dIGV4dGVuZHMgW25ldmVyXVxuICA/IHsgZW5oYW5jZXJzPzogRW5oYW5jZXJNYXA8VFN1YnNldEtleSwgVENvbXB1dGVkUmVzdWx0cywgVFN1YnNldE1hcHBpbmcsIFRTdWJzZXRRdWVyaWVzPiB9XG4gIDogeyBlbmhhbmNlcnM6IEVuaGFuY2VyTWFwPFRTdWJzZXRLZXksIFRDb21wdXRlZFJlc3VsdHMsIFRTdWJzZXRNYXBwaW5nLCBUU3Vic2V0UXVlcmllcz4gfTtcblxudHlwZSBSZXF1aXJlZEVuaGFuY2VyS2V5czxcbiAgVFN1YnNldEtleSBleHRlbmRzIHN0cmluZyxcbiAgVENvbXB1dGVkUmVzdWx0cyBleHRlbmRzIFJlY29yZDxUU3Vic2V0S2V5LCBhbnk+LFxuICBUU3Vic2V0TWFwcGluZyBleHRlbmRzIFJlY29yZDxUU3Vic2V0S2V5LCBhbnk+LFxuPiA9IHtcbiAgW0sgaW4gVFN1YnNldEtleV06IFRDb21wdXRlZFJlc3VsdHNbS10gZXh0ZW5kcyBUU3Vic2V0TWFwcGluZ1tLXSA/IG5ldmVyIDogSztcbn1bVFN1YnNldEtleV07XG5cbmV4cG9ydCBjb25zdCBCYXNlTW9kZWwgPSBuZXcgQmFzZU1vZGVsQ2xhc3MoKTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OzthQU1zQztxQkFDa0I7WUFFcUI7ZUFDakI7aUJBR2U7U0FHbEQ7V0FDSTttQkFNZTtxQkFFSTtDQVluQyxpQkFBYixNQUtFO0VBSWtCO0VBQ047RUFDQTtFQUxaO0VBRUEsWUFDRSxZQUFvQyxLQUFLLFlBQVksTUFDckQsZUFDQSxlQUNBO0dBSGdCLEtBQUEsWUFBQTtHQUNOLEtBQUEsZ0JBQUE7R0FDQSxLQUFBLGdCQUFBO0dBRVYsS0FBSyxTQUFTLFVBQVUsd0JBQXdCLEtBQUssV0FBVyxPQUFPLENBQUM7RUFDMUU7RUFFQSxNQUFNLE9BQXVCO0dBQzNCLE9BQU8sR0FBRyxNQUFNLEtBQUs7RUFDdkI7RUFFQSxRQUFRLE9BQThCO0dBRXBDLE1BQU0sTUFBTSxHQUFHLHNCQUFzQixDQUFDLENBQUMsZUFBZSxLQUFLO0dBQzNELElBQUksS0FDRixPQUFPO0dBS1QsT0FBTyxJQUFJLFlBREEsS0FBSyxNQUFNLEtBQ0MsR0FBSSxJQUFJLGNBQWMsQ0FBQztFQUNoRDtFQUVBLE1BQU0sVUFBVTtHQUNkLE9BQU8sR0FBRyxRQUFRO0VBQ3BCO0VBRUEsTUFBTSxlQUNKLEtBQ0EsTUFDQSxXQUNBLGNBQ0EsWUFBb0IsS0FDcEI7R0FDQSxJQUFJLENBQUMsS0FDSCxNQUFNLEtBQUssTUFBTSxHQUFHO0dBR3RCLElBQUk7R0FDSixJQUFJO0dBQ0osSUFBSTtHQUVKLElBQUksYUFBYSxTQUFTLEdBQUc7SUFDM0IsZUFBZSxJQUFJLElBQUksbUJBQW1CLGFBQWEsS0FB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
@@ -1 +1 @@
1
- export { };
1
+ export {};
@@ -1,19 +1,17 @@
1
1
  import { AsyncLocalStorage } from "async_hooks";
2
2
  import { type Knex } from "knex";
3
3
  import { type SonamuConfig } from "../api/config";
4
+ import { type EnvironmentSnapshots, type SonamuEnvironment } from "../env";
4
5
  import { TransactionContext } from "./transaction-context";
5
- export type DBPreset = "w" | "r";
6
- export type SonamuDBConfig = {
7
- development_master: Knex.Config;
8
- development_slave: Knex.Config;
9
- production_master: Knex.Config;
10
- production_slave: Knex.Config;
11
- fixture: Knex.Config;
12
- test: Knex.Config;
13
- };
6
+ export type SonamuMainDBPreset = "test" | "fixture" | SonamuEnvironment;
7
+ export type SonamuReadonlyDBPreset = "test_readonly" | "development_readonly" | "staging_readonly" | "production_readonly";
8
+ export type SonamuDBPreset = SonamuMainDBPreset | SonamuReadonlyDBPreset;
9
+ export type DBPreset = "w" | "r" | SonamuDBPreset;
10
+ export type SonamuDBConfig = Record<SonamuDBPreset, Knex.Config>;
14
11
  export declare class DBClass {
15
12
  private wdb?;
16
13
  private rdb?;
14
+ private presetDBs;
17
15
  private workerDBs;
18
16
  private currentConfig;
19
17
  transactionStorage: AsyncLocalStorage<TransactionContext>;
@@ -22,14 +20,10 @@ export declare class DBClass {
22
20
  private getCurrentConfig;
23
21
  getTransactionContext(): TransactionContext;
24
22
  getDB(which: DBPreset): Knex;
25
- /**
26
- * 병렬 테스트에서 worker별 DB 인스턴스를 반환합니다.
27
- * VITEST_POOL_ID 환경변수로 worker를 식별하여 해당 DB에 연결합니다.
28
- */
29
23
  private getWorkerDB;
30
24
  getDBConfig(which: DBPreset): Knex.Config;
31
25
  destroy(): Promise<void>;
32
- generateDBConfig(config: SonamuConfig["database"]): SonamuDBConfig;
26
+ generateDBConfig(config: SonamuConfig["database"], projectName?: string, snapshots?: EnvironmentSnapshots): SonamuDBConfig;
33
27
  testTransaction: Knex.Transaction | null;
34
28
  createTestTransaction(): Promise<Knex.Transaction>;
35
29
  clearTestTransaction(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/database/db.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,MAAM,CAAC;AAEjC,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAEvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAuC3D,MAAM,MAAM,QAAQ,GAAG,GAAG,GAAG,GAAG,CAAC;AAEjC,MAAM,MAAM,cAAc,GAAG;IAC3B,kBAAkB,EAAE,IAAI,CAAC,MAAM,CAAC;IAChC,iBAAiB,EAAE,IAAI,CAAC,MAAM,CAAC;IAC/B,iBAAiB,EAAE,IAAI,CAAC,MAAM,CAAC;IAC/B,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC;IAC9B,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC;IACrB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;CACnB,CAAC;AAEF,qBAAa,OAAO;IAClB,OAAO,CAAC,GAAG,CAAC,CAAO;IACnB,OAAO,CAAC,GAAG,CAAC,CAAO;IACnB,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,aAAa,CAA+B;IAE7C,kBAAkB,wCAA+C;IAEjE,kBAAkB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAIpE,SAAS,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IAIzC,OAAO,CAAC,gBAAgB;IAQjB,qBAAqB,IAAI,kBAAkB;IAIlD,KAAK,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAsC5B;;;OAGG;IACH,OAAO,CAAC,WAAW;IA+BnB,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC,MAAM;IA2BnC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBvB,gBAAgB,CAAC,MAAM,EAAE,YAAY,CAAC,UAAU,CAAC,GAAG,cAAc;IA+ClE,eAAe,EAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAQ;IACjD,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC;IAKlD,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrC,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;CAIzC;AACD,eAAO,MAAM,EAAE,SAAgB,CAAC"}
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/database/db.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,MAAM,CAAC;AAEjC,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAwB,KAAK,oBAAoB,EAAE,KAAK,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAEjG,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAmC3D,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,SAAS,GAAG,iBAAiB,CAAC;AACxE,MAAM,MAAM,sBAAsB,GAC9B,eAAe,GACf,sBAAsB,GACtB,kBAAkB,GAClB,qBAAqB,CAAC;AAC1B,MAAM,MAAM,cAAc,GAAG,kBAAkB,GAAG,sBAAsB,CAAC;AACzE,MAAM,MAAM,QAAQ,GAAG,GAAG,GAAG,GAAG,GAAG,cAAc,CAAC;AAElD,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;AAgGjE,qBAAa,OAAO;IAClB,OAAO,CAAC,GAAG,CAAC,CAAO;IACnB,OAAO,CAAC,GAAG,CAAC,CAAO;IACnB,OAAO,CAAC,SAAS,CAAwC;IACzD,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,aAAa,CAA+B;IAE7C,kBAAkB,wCAA+C;IAEjE,kBAAkB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAIpE,SAAS,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IAIzC,OAAO,CAAC,gBAAgB;IAQjB,qBAAqB,IAAI,kBAAkB;IAIlD,KAAK,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IA4C5B,OAAO,CAAC,WAAW;IA6BnB,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC,MAAM;IAsBnC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBvB,gBAAgB,CACrB,MAAM,EAAE,YAAY,CAAC,UAAU,CAAC,EAChC,WAAW,CAAC,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,oBAAoB,GAC/B,cAAc;IA2EV,eAAe,EAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAQ;IACjD,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC;IAKlD,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrC,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;CAIzC;AACD,eAAO,MAAM,EAAE,SAAgB,CAAC"}