@dyanet/nestjs-config-aws 1.2.1 → 2.0.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 (230) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +60 -43
  3. package/dist/cjs/aws-config-loader.js +57 -0
  4. package/dist/cjs/build-loaders.js +58 -0
  5. package/dist/cjs/config.module.js +138 -0
  6. package/dist/cjs/index.js +46 -0
  7. package/dist/cjs/interfaces/config-service.interface.js +11 -0
  8. package/dist/cjs/interfaces/default-schema.interface.js +63 -0
  9. package/dist/cjs/{nestjs-config-aws/src/interfaces → interfaces}/index.js +1 -1
  10. package/dist/cjs/interfaces/module-options.interface.js +3 -0
  11. package/dist/cjs/package.json +3 -0
  12. package/dist/cjs/services/config.service.js +142 -0
  13. package/dist/esm/aws-config-loader.js +54 -0
  14. package/dist/esm/build-loaders.js +55 -0
  15. package/dist/esm/config.module.js +135 -0
  16. package/dist/esm/index.js +18 -0
  17. package/dist/esm/interfaces/config-service.interface.js +7 -0
  18. package/dist/esm/interfaces/default-schema.interface.js +59 -0
  19. package/dist/esm/interfaces/index.js +8 -0
  20. package/dist/esm/interfaces/module-options.interface.js +2 -0
  21. package/dist/esm/package.json +3 -1
  22. package/dist/esm/services/config.service.js +139 -0
  23. package/dist/types/aws-config-loader.d.ts +74 -0
  24. package/dist/types/aws-config-loader.d.ts.map +1 -0
  25. package/dist/types/build-loaders.d.ts +30 -0
  26. package/dist/types/build-loaders.d.ts.map +1 -0
  27. package/dist/types/{nestjs-config-aws/src/config.module.d.ts → config.module.d.ts} +2 -8
  28. package/dist/types/config.module.d.ts.map +1 -0
  29. package/dist/types/index.d.ts +10 -0
  30. package/dist/types/index.d.ts.map +1 -0
  31. package/dist/types/interfaces/config-service.interface.d.ts.map +1 -0
  32. package/dist/types/{nestjs-config-aws/src/interfaces → interfaces}/default-schema.interface.d.ts +14 -14
  33. package/dist/types/interfaces/default-schema.interface.d.ts.map +1 -0
  34. package/dist/types/interfaces/index.d.ts.map +1 -0
  35. package/dist/types/{nestjs-config-aws/src/interfaces → interfaces}/module-options.interface.d.ts +22 -3
  36. package/dist/types/interfaces/module-options.interface.d.ts.map +1 -0
  37. package/dist/types/services/config.service.d.ts.map +1 -0
  38. package/package.json +13 -7
  39. package/dist/cjs/config-aws/src/config-manager.js +0 -366
  40. package/dist/cjs/config-aws/src/errors/index.js +0 -77
  41. package/dist/cjs/config-aws/src/index.js +0 -37
  42. package/dist/cjs/config-aws/src/interfaces/config-loader.interface.js +0 -3
  43. package/dist/cjs/config-aws/src/interfaces/config-manager.interface.js +0 -3
  44. package/dist/cjs/config-aws/src/interfaces/env-file-loader.interface.js +0 -3
  45. package/dist/cjs/config-aws/src/interfaces/environment-loader.interface.js +0 -3
  46. package/dist/cjs/config-aws/src/interfaces/s3-loader.interface.js +0 -3
  47. package/dist/cjs/config-aws/src/interfaces/secrets-manager-loader.interface.js +0 -3
  48. package/dist/cjs/config-aws/src/interfaces/ssm-parameter-store-loader.interface.js +0 -3
  49. package/dist/cjs/config-aws/src/loaders/env-file.loader.js +0 -169
  50. package/dist/cjs/config-aws/src/loaders/environment.loader.js +0 -85
  51. package/dist/cjs/config-aws/src/loaders/s3.loader.js +0 -145
  52. package/dist/cjs/config-aws/src/loaders/secrets-manager.loader.js +0 -169
  53. package/dist/cjs/config-aws/src/loaders/ssm-parameter-store.loader.js +0 -199
  54. package/dist/cjs/config-aws/src/utils/env-file-parser.util.js +0 -98
  55. package/dist/cjs/config-aws/src/utils/validation.util.js +0 -116
  56. package/dist/cjs/nestjs-config-aws/src/config.module.js +0 -175
  57. package/dist/cjs/nestjs-config-aws/src/index.js +0 -61
  58. package/dist/cjs/nestjs-config-aws/src/integration/index.js +0 -23
  59. package/dist/cjs/nestjs-config-aws/src/integration/interfaces/configuration-factory.interface.js +0 -3
  60. package/dist/cjs/nestjs-config-aws/src/integration/interfaces/configuration-source.interface.js +0 -3
  61. package/dist/cjs/nestjs-config-aws/src/integration/interfaces/index.js +0 -26
  62. package/dist/cjs/nestjs-config-aws/src/integration/interfaces/integration-options.interface.js +0 -3
  63. package/dist/cjs/nestjs-config-aws/src/integration/interfaces/integration-state.interface.js +0 -3
  64. package/dist/cjs/nestjs-config-aws/src/integration/interfaces/nestjs-config-compatibility.interface.js +0 -73
  65. package/dist/cjs/nestjs-config-aws/src/integration/interfaces/nestjs-config-integration.interface.js +0 -3
  66. package/dist/cjs/nestjs-config-aws/src/integration/interfaces/typed-configuration.interface.js +0 -4
  67. package/dist/cjs/nestjs-config-aws/src/integration/interfaces/utility-types.interface.js +0 -52
  68. package/dist/cjs/nestjs-config-aws/src/integration/nestjs-config-integration.module.js +0 -124
  69. package/dist/cjs/nestjs-config-aws/src/integration/providers/aws-configuration-loader.service.js +0 -592
  70. package/dist/cjs/nestjs-config-aws/src/integration/providers/configuration-factory.provider.js +0 -385
  71. package/dist/cjs/nestjs-config-aws/src/integration/providers/index.js +0 -20
  72. package/dist/cjs/nestjs-config-aws/src/integration/services/async-config-helper.service.js +0 -366
  73. package/dist/cjs/nestjs-config-aws/src/integration/services/error-handler.service.js +0 -267
  74. package/dist/cjs/nestjs-config-aws/src/integration/services/factory-registration.service.js +0 -517
  75. package/dist/cjs/nestjs-config-aws/src/integration/services/index.js +0 -26
  76. package/dist/cjs/nestjs-config-aws/src/integration/services/integration-state.service.js +0 -81
  77. package/dist/cjs/nestjs-config-aws/src/integration/services/namespace-handler.service.js +0 -465
  78. package/dist/cjs/nestjs-config-aws/src/integration/services/nestjs-config-integration.service.js +0 -318
  79. package/dist/cjs/nestjs-config-aws/src/integration/services/precedence-handler.service.js +0 -292
  80. package/dist/cjs/nestjs-config-aws/src/integration/services/validation-integration.service.js +0 -595
  81. package/dist/cjs/nestjs-config-aws/src/integration/utils/config-integration.util.js +0 -283
  82. package/dist/cjs/nestjs-config-aws/src/integration/utils/index.js +0 -19
  83. package/dist/cjs/nestjs-config-aws/src/interfaces/config-service.interface.js +0 -11
  84. package/dist/cjs/nestjs-config-aws/src/interfaces/default-schema.interface.js +0 -63
  85. package/dist/cjs/nestjs-config-aws/src/interfaces/module-options.interface.js +0 -3
  86. package/dist/cjs/nestjs-config-aws/src/services/config.service.js +0 -142
  87. package/dist/esm/config-aws/src/config-manager.js +0 -362
  88. package/dist/esm/config-aws/src/errors/index.js +0 -69
  89. package/dist/esm/config-aws/src/index.js +0 -21
  90. package/dist/esm/config-aws/src/interfaces/config-loader.interface.js +0 -2
  91. package/dist/esm/config-aws/src/interfaces/config-manager.interface.js +0 -2
  92. package/dist/esm/config-aws/src/interfaces/env-file-loader.interface.js +0 -2
  93. package/dist/esm/config-aws/src/interfaces/environment-loader.interface.js +0 -2
  94. package/dist/esm/config-aws/src/interfaces/s3-loader.interface.js +0 -2
  95. package/dist/esm/config-aws/src/interfaces/secrets-manager-loader.interface.js +0 -2
  96. package/dist/esm/config-aws/src/interfaces/ssm-parameter-store-loader.interface.js +0 -2
  97. package/dist/esm/config-aws/src/loaders/env-file.loader.js +0 -132
  98. package/dist/esm/config-aws/src/loaders/environment.loader.js +0 -81
  99. package/dist/esm/config-aws/src/loaders/s3.loader.js +0 -141
  100. package/dist/esm/config-aws/src/loaders/secrets-manager.loader.js +0 -165
  101. package/dist/esm/config-aws/src/loaders/ssm-parameter-store.loader.js +0 -195
  102. package/dist/esm/config-aws/src/utils/env-file-parser.util.js +0 -94
  103. package/dist/esm/config-aws/src/utils/validation.util.js +0 -112
  104. package/dist/esm/nestjs-config-aws/src/config.module.js +0 -172
  105. package/dist/esm/nestjs-config-aws/src/index.js +0 -23
  106. package/dist/esm/nestjs-config-aws/src/integration/index.js +0 -7
  107. package/dist/esm/nestjs-config-aws/src/integration/interfaces/configuration-factory.interface.js +0 -2
  108. package/dist/esm/nestjs-config-aws/src/integration/interfaces/configuration-source.interface.js +0 -2
  109. package/dist/esm/nestjs-config-aws/src/integration/interfaces/index.js +0 -10
  110. package/dist/esm/nestjs-config-aws/src/integration/interfaces/integration-options.interface.js +0 -2
  111. package/dist/esm/nestjs-config-aws/src/integration/interfaces/integration-state.interface.js +0 -2
  112. package/dist/esm/nestjs-config-aws/src/integration/interfaces/nestjs-config-compatibility.interface.js +0 -64
  113. package/dist/esm/nestjs-config-aws/src/integration/interfaces/nestjs-config-integration.interface.js +0 -2
  114. package/dist/esm/nestjs-config-aws/src/integration/interfaces/typed-configuration.interface.js +0 -3
  115. package/dist/esm/nestjs-config-aws/src/integration/interfaces/utility-types.interface.js +0 -44
  116. package/dist/esm/nestjs-config-aws/src/integration/nestjs-config-integration.module.js +0 -121
  117. package/dist/esm/nestjs-config-aws/src/integration/providers/aws-configuration-loader.service.js +0 -589
  118. package/dist/esm/nestjs-config-aws/src/integration/providers/configuration-factory.provider.js +0 -382
  119. package/dist/esm/nestjs-config-aws/src/integration/providers/index.js +0 -4
  120. package/dist/esm/nestjs-config-aws/src/integration/services/async-config-helper.service.js +0 -363
  121. package/dist/esm/nestjs-config-aws/src/integration/services/error-handler.service.js +0 -264
  122. package/dist/esm/nestjs-config-aws/src/integration/services/factory-registration.service.js +0 -514
  123. package/dist/esm/nestjs-config-aws/src/integration/services/index.js +0 -10
  124. package/dist/esm/nestjs-config-aws/src/integration/services/integration-state.service.js +0 -78
  125. package/dist/esm/nestjs-config-aws/src/integration/services/namespace-handler.service.js +0 -462
  126. package/dist/esm/nestjs-config-aws/src/integration/services/nestjs-config-integration.service.js +0 -315
  127. package/dist/esm/nestjs-config-aws/src/integration/services/precedence-handler.service.js +0 -289
  128. package/dist/esm/nestjs-config-aws/src/integration/services/validation-integration.service.js +0 -589
  129. package/dist/esm/nestjs-config-aws/src/integration/utils/config-integration.util.js +0 -240
  130. package/dist/esm/nestjs-config-aws/src/integration/utils/index.js +0 -3
  131. package/dist/esm/nestjs-config-aws/src/interfaces/config-service.interface.js +0 -7
  132. package/dist/esm/nestjs-config-aws/src/interfaces/default-schema.interface.js +0 -59
  133. package/dist/esm/nestjs-config-aws/src/interfaces/index.js +0 -8
  134. package/dist/esm/nestjs-config-aws/src/interfaces/module-options.interface.js +0 -2
  135. package/dist/esm/nestjs-config-aws/src/services/config.service.js +0 -139
  136. package/dist/types/config-aws/src/config-manager.d.ts +0 -119
  137. package/dist/types/config-aws/src/config-manager.d.ts.map +0 -1
  138. package/dist/types/config-aws/src/errors/index.d.ts +0 -43
  139. package/dist/types/config-aws/src/errors/index.d.ts.map +0 -1
  140. package/dist/types/config-aws/src/index.d.ts +0 -24
  141. package/dist/types/config-aws/src/index.d.ts.map +0 -1
  142. package/dist/types/config-aws/src/interfaces/config-loader.interface.d.ts +0 -33
  143. package/dist/types/config-aws/src/interfaces/config-loader.interface.d.ts.map +0 -1
  144. package/dist/types/config-aws/src/interfaces/config-manager.interface.d.ts +0 -86
  145. package/dist/types/config-aws/src/interfaces/config-manager.interface.d.ts.map +0 -1
  146. package/dist/types/config-aws/src/interfaces/env-file-loader.interface.d.ts +0 -12
  147. package/dist/types/config-aws/src/interfaces/env-file-loader.interface.d.ts.map +0 -1
  148. package/dist/types/config-aws/src/interfaces/environment-loader.interface.d.ts +0 -10
  149. package/dist/types/config-aws/src/interfaces/environment-loader.interface.d.ts.map +0 -1
  150. package/dist/types/config-aws/src/interfaces/s3-loader.interface.d.ts +0 -14
  151. package/dist/types/config-aws/src/interfaces/s3-loader.interface.d.ts.map +0 -1
  152. package/dist/types/config-aws/src/interfaces/secrets-manager-loader.interface.d.ts +0 -12
  153. package/dist/types/config-aws/src/interfaces/secrets-manager-loader.interface.d.ts.map +0 -1
  154. package/dist/types/config-aws/src/interfaces/ssm-parameter-store-loader.interface.d.ts +0 -14
  155. package/dist/types/config-aws/src/interfaces/ssm-parameter-store-loader.interface.d.ts.map +0 -1
  156. package/dist/types/config-aws/src/loaders/env-file.loader.d.ts +0 -69
  157. package/dist/types/config-aws/src/loaders/env-file.loader.d.ts.map +0 -1
  158. package/dist/types/config-aws/src/loaders/environment.loader.d.ts +0 -46
  159. package/dist/types/config-aws/src/loaders/environment.loader.d.ts.map +0 -1
  160. package/dist/types/config-aws/src/loaders/s3.loader.d.ts +0 -62
  161. package/dist/types/config-aws/src/loaders/s3.loader.d.ts.map +0 -1
  162. package/dist/types/config-aws/src/loaders/secrets-manager.loader.d.ts +0 -68
  163. package/dist/types/config-aws/src/loaders/secrets-manager.loader.d.ts.map +0 -1
  164. package/dist/types/config-aws/src/loaders/ssm-parameter-store.loader.d.ts +0 -78
  165. package/dist/types/config-aws/src/loaders/ssm-parameter-store.loader.d.ts.map +0 -1
  166. package/dist/types/config-aws/src/utils/env-file-parser.util.d.ts +0 -45
  167. package/dist/types/config-aws/src/utils/env-file-parser.util.d.ts.map +0 -1
  168. package/dist/types/config-aws/src/utils/validation.util.d.ts +0 -53
  169. package/dist/types/config-aws/src/utils/validation.util.d.ts.map +0 -1
  170. package/dist/types/nestjs-config-aws/src/config.module.d.ts.map +0 -1
  171. package/dist/types/nestjs-config-aws/src/index.d.ts +0 -11
  172. package/dist/types/nestjs-config-aws/src/index.d.ts.map +0 -1
  173. package/dist/types/nestjs-config-aws/src/integration/index.d.ts +0 -6
  174. package/dist/types/nestjs-config-aws/src/integration/index.d.ts.map +0 -1
  175. package/dist/types/nestjs-config-aws/src/integration/interfaces/configuration-factory.interface.d.ts +0 -71
  176. package/dist/types/nestjs-config-aws/src/integration/interfaces/configuration-factory.interface.d.ts.map +0 -1
  177. package/dist/types/nestjs-config-aws/src/integration/interfaces/configuration-source.interface.d.ts +0 -24
  178. package/dist/types/nestjs-config-aws/src/integration/interfaces/configuration-source.interface.d.ts.map +0 -1
  179. package/dist/types/nestjs-config-aws/src/integration/interfaces/index.d.ts +0 -9
  180. package/dist/types/nestjs-config-aws/src/integration/interfaces/index.d.ts.map +0 -1
  181. package/dist/types/nestjs-config-aws/src/integration/interfaces/integration-options.interface.d.ts +0 -66
  182. package/dist/types/nestjs-config-aws/src/integration/interfaces/integration-options.interface.d.ts.map +0 -1
  183. package/dist/types/nestjs-config-aws/src/integration/interfaces/integration-state.interface.d.ts +0 -17
  184. package/dist/types/nestjs-config-aws/src/integration/interfaces/integration-state.interface.d.ts.map +0 -1
  185. package/dist/types/nestjs-config-aws/src/integration/interfaces/nestjs-config-compatibility.interface.d.ts +0 -332
  186. package/dist/types/nestjs-config-aws/src/integration/interfaces/nestjs-config-compatibility.interface.d.ts.map +0 -1
  187. package/dist/types/nestjs-config-aws/src/integration/interfaces/nestjs-config-integration.interface.d.ts +0 -259
  188. package/dist/types/nestjs-config-aws/src/integration/interfaces/nestjs-config-integration.interface.d.ts.map +0 -1
  189. package/dist/types/nestjs-config-aws/src/integration/interfaces/typed-configuration.interface.d.ts +0 -209
  190. package/dist/types/nestjs-config-aws/src/integration/interfaces/typed-configuration.interface.d.ts.map +0 -1
  191. package/dist/types/nestjs-config-aws/src/integration/interfaces/utility-types.interface.d.ts +0 -249
  192. package/dist/types/nestjs-config-aws/src/integration/interfaces/utility-types.interface.d.ts.map +0 -1
  193. package/dist/types/nestjs-config-aws/src/integration/nestjs-config-integration.module.d.ts +0 -36
  194. package/dist/types/nestjs-config-aws/src/integration/nestjs-config-integration.module.d.ts.map +0 -1
  195. package/dist/types/nestjs-config-aws/src/integration/providers/aws-configuration-loader.service.d.ts +0 -134
  196. package/dist/types/nestjs-config-aws/src/integration/providers/aws-configuration-loader.service.d.ts.map +0 -1
  197. package/dist/types/nestjs-config-aws/src/integration/providers/configuration-factory.provider.d.ts +0 -119
  198. package/dist/types/nestjs-config-aws/src/integration/providers/configuration-factory.provider.d.ts.map +0 -1
  199. package/dist/types/nestjs-config-aws/src/integration/providers/index.d.ts +0 -3
  200. package/dist/types/nestjs-config-aws/src/integration/providers/index.d.ts.map +0 -1
  201. package/dist/types/nestjs-config-aws/src/integration/services/async-config-helper.service.d.ts +0 -84
  202. package/dist/types/nestjs-config-aws/src/integration/services/async-config-helper.service.d.ts.map +0 -1
  203. package/dist/types/nestjs-config-aws/src/integration/services/error-handler.service.d.ts +0 -84
  204. package/dist/types/nestjs-config-aws/src/integration/services/error-handler.service.d.ts.map +0 -1
  205. package/dist/types/nestjs-config-aws/src/integration/services/factory-registration.service.d.ts +0 -158
  206. package/dist/types/nestjs-config-aws/src/integration/services/factory-registration.service.d.ts.map +0 -1
  207. package/dist/types/nestjs-config-aws/src/integration/services/index.d.ts +0 -9
  208. package/dist/types/nestjs-config-aws/src/integration/services/index.d.ts.map +0 -1
  209. package/dist/types/nestjs-config-aws/src/integration/services/integration-state.service.d.ts +0 -41
  210. package/dist/types/nestjs-config-aws/src/integration/services/integration-state.service.d.ts.map +0 -1
  211. package/dist/types/nestjs-config-aws/src/integration/services/namespace-handler.service.d.ts +0 -192
  212. package/dist/types/nestjs-config-aws/src/integration/services/namespace-handler.service.d.ts.map +0 -1
  213. package/dist/types/nestjs-config-aws/src/integration/services/nestjs-config-integration.service.d.ts +0 -87
  214. package/dist/types/nestjs-config-aws/src/integration/services/nestjs-config-integration.service.d.ts.map +0 -1
  215. package/dist/types/nestjs-config-aws/src/integration/services/precedence-handler.service.d.ts +0 -103
  216. package/dist/types/nestjs-config-aws/src/integration/services/precedence-handler.service.d.ts.map +0 -1
  217. package/dist/types/nestjs-config-aws/src/integration/services/validation-integration.service.d.ts +0 -222
  218. package/dist/types/nestjs-config-aws/src/integration/services/validation-integration.service.d.ts.map +0 -1
  219. package/dist/types/nestjs-config-aws/src/integration/utils/config-integration.util.d.ts +0 -81
  220. package/dist/types/nestjs-config-aws/src/integration/utils/config-integration.util.d.ts.map +0 -1
  221. package/dist/types/nestjs-config-aws/src/integration/utils/index.d.ts +0 -2
  222. package/dist/types/nestjs-config-aws/src/integration/utils/index.d.ts.map +0 -1
  223. package/dist/types/nestjs-config-aws/src/interfaces/config-service.interface.d.ts.map +0 -1
  224. package/dist/types/nestjs-config-aws/src/interfaces/default-schema.interface.d.ts.map +0 -1
  225. package/dist/types/nestjs-config-aws/src/interfaces/index.d.ts.map +0 -1
  226. package/dist/types/nestjs-config-aws/src/interfaces/module-options.interface.d.ts.map +0 -1
  227. package/dist/types/nestjs-config-aws/src/services/config.service.d.ts.map +0 -1
  228. /package/dist/types/{nestjs-config-aws/src/interfaces → interfaces}/config-service.interface.d.ts +0 -0
  229. /package/dist/types/{nestjs-config-aws/src/interfaces → interfaces}/index.d.ts +0 -0
  230. /package/dist/types/{nestjs-config-aws/src/services → services}/config.service.d.ts +0 -0
@@ -1,589 +0,0 @@
1
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
6
- };
7
- var __metadata = (this && this.__metadata) || function (k, v) {
8
- if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
- };
10
- var __param = (this && this.__param) || function (paramIndex, decorator) {
11
- return function (target, key) { decorator(target, key, paramIndex); }
12
- };
13
- var AwsConfigurationLoaderService_1;
14
- import { Injectable, Logger, Inject, Optional } from '@nestjs/common';
15
- import { SecretsManagerLoader, SSMParameterStoreLoader, EnvironmentLoader, } from '@dyanet/config-aws';
16
- import { ErrorHandlerService } from '../services/error-handler.service';
17
- /**
18
- * Service for loading configuration from AWS sources for integration with @nestjs/config.
19
- * Uses existing AWS loaders to fetch configuration and provides namespace-aware loading capabilities.
20
- */
21
- let AwsConfigurationLoaderService = AwsConfigurationLoaderService_1 = class AwsConfigurationLoaderService {
22
- logger = new Logger(AwsConfigurationLoaderService_1.name);
23
- loaders;
24
- options;
25
- errorHandler;
26
- constructor(options) {
27
- this.options = options || {};
28
- this.errorHandler = new ErrorHandlerService(this.options);
29
- this.loaders = this.createLoaders();
30
- }
31
- /**
32
- * Load configuration from AWS sources.
33
- * @returns Promise resolving to configuration data
34
- */
35
- async loadConfiguration() {
36
- const mergedConfig = {};
37
- const sources = [];
38
- for (const loader of this.loaders) {
39
- try {
40
- // Check if loader is available in current environment with timeout
41
- const isAvailable = await this.checkAvailabilityWithTimeout(loader);
42
- if (!isAvailable) {
43
- if (this.options.enableLogging) {
44
- this.logger.debug(`Skipping ${loader.getName()} - not available in current environment`);
45
- }
46
- continue;
47
- }
48
- if (this.options.enableLogging) {
49
- this.logger.debug(`Loading configuration from ${loader.getName()}`);
50
- }
51
- // Load configuration from this source with retry logic for AWS services
52
- const loaderConfig = loader instanceof EnvironmentLoader
53
- ? await loader.load()
54
- : await this.loadWithRetry(loader);
55
- // Create configuration source metadata
56
- const source = {
57
- name: loader.getName(),
58
- type: this.getSourceType(loader),
59
- priority: this.getSourcePriority(loader),
60
- data: loaderConfig,
61
- loadedAt: new Date(),
62
- };
63
- sources.push(source);
64
- // Merge with existing configuration based on precedence
65
- Object.assign(mergedConfig, loaderConfig);
66
- if (this.options.enableLogging) {
67
- const keyCount = Object.keys(loaderConfig).length;
68
- this.logger.debug(`Loaded ${keyCount} configuration values from ${loader.getName()}`);
69
- }
70
- }
71
- catch (error) {
72
- const loaderError = error instanceof Error ? error : new Error(String(error));
73
- // Log detailed error information for troubleshooting
74
- this.errorHandler.logDetailedError(`loadConfiguration - ${loader.getName()}`, loaderError, {
75
- loaderName: loader.getName(),
76
- loaderType: this.getSourceType(loader),
77
- });
78
- // Handle specific error types
79
- if (this.isAwsServiceError(loaderError)) {
80
- const shouldContinue = this.handleAwsSpecificError(loader, loaderError);
81
- if (!shouldContinue) {
82
- throw loaderError;
83
- }
84
- }
85
- else {
86
- // Handle general configuration errors
87
- const shouldContinue = this.errorHandler.handleConfigurationError(loader.getName(), loaderError);
88
- if (!shouldContinue) {
89
- throw loaderError;
90
- }
91
- }
92
- // Add error to source metadata
93
- const errorSource = {
94
- name: loader.getName(),
95
- type: this.getSourceType(loader),
96
- priority: this.getSourcePriority(loader),
97
- data: {},
98
- loadedAt: new Date(),
99
- errors: [loaderError.message],
100
- };
101
- sources.push(errorSource);
102
- }
103
- }
104
- return mergedConfig;
105
- }
106
- /**
107
- * Load configuration for specific namespaces from AWS sources.
108
- * @param namespaces - Array of namespace names to load
109
- * @returns Promise resolving to namespaced configuration data
110
- */
111
- async loadNamespacedConfiguration(namespaces) {
112
- const result = {};
113
- // Initialize all namespaces
114
- for (const namespace of namespaces) {
115
- result[namespace] = {};
116
- }
117
- for (const loader of this.loaders) {
118
- try {
119
- // Check if loader is available in current environment with timeout
120
- const isAvailable = await this.checkAvailabilityWithTimeout(loader);
121
- if (!isAvailable) {
122
- if (this.options.enableLogging) {
123
- this.logger.debug(`Skipping ${loader.getName()} for namespace loading - not available`);
124
- }
125
- continue;
126
- }
127
- if (this.options.enableLogging) {
128
- this.logger.debug(`Loading namespaced configuration from ${loader.getName()}`);
129
- }
130
- // Load configuration from this source with retry logic for AWS services
131
- const loaderConfig = loader instanceof EnvironmentLoader
132
- ? await loader.load()
133
- : await this.loadWithRetry(loader);
134
- // Distribute configuration to namespaces based on key prefixes or patterns
135
- for (const namespace of namespaces) {
136
- const namespacedConfig = this.extractNamespaceConfig(loaderConfig, namespace);
137
- if (Object.keys(namespacedConfig).length > 0) {
138
- Object.assign(result[namespace], namespacedConfig);
139
- if (this.options.enableLogging) {
140
- const keyCount = Object.keys(namespacedConfig).length;
141
- this.logger.debug(`Loaded ${keyCount} values for namespace '${namespace}' from ${loader.getName()}`);
142
- }
143
- }
144
- }
145
- }
146
- catch (error) {
147
- const loaderError = error instanceof Error ? error : new Error(String(error));
148
- // Log detailed error information for troubleshooting
149
- this.errorHandler.logDetailedError(`loadNamespacedConfiguration - ${loader.getName()}`, loaderError, {
150
- loaderName: loader.getName(),
151
- loaderType: this.getSourceType(loader),
152
- namespaces,
153
- });
154
- // Handle specific error types
155
- if (this.isAwsServiceError(loaderError)) {
156
- const shouldContinue = this.handleAwsSpecificError(loader, loaderError);
157
- if (!shouldContinue) {
158
- throw loaderError;
159
- }
160
- }
161
- else {
162
- // Handle general configuration errors
163
- const shouldContinue = this.errorHandler.handleConfigurationError(loader.getName(), loaderError);
164
- if (!shouldContinue) {
165
- throw loaderError;
166
- }
167
- }
168
- // Create fallback configuration for each namespace
169
- if (this.options.fallbackToLocal) {
170
- for (const namespace of namespaces) {
171
- const fallbackConfig = this.errorHandler.createFallbackConfiguration(namespace);
172
- Object.assign(result[namespace], fallbackConfig);
173
- }
174
- }
175
- }
176
- }
177
- return result;
178
- }
179
- /**
180
- * Check if AWS services are available.
181
- * @returns Promise resolving to availability status
182
- */
183
- async isAvailable() {
184
- try {
185
- // Check if at least one AWS loader is available
186
- const availabilityChecks = this.loaders
187
- .filter(loader => !(loader instanceof EnvironmentLoader)) // Skip environment loader
188
- .map(loader => this.checkAvailabilityWithTimeout(loader));
189
- if (availabilityChecks.length === 0) {
190
- // No AWS loaders configured
191
- return false;
192
- }
193
- // Wait for all availability checks to complete
194
- const results = await Promise.allSettled(availabilityChecks);
195
- // Return true if at least one AWS service is available
196
- return results.some(result => result.status === 'fulfilled' && result.value === true);
197
- }
198
- catch (error) {
199
- const availabilityError = error instanceof Error ? error : new Error(String(error));
200
- this.errorHandler.logDetailedError('isAvailable', availabilityError);
201
- // Handle as AWS unavailable
202
- this.errorHandler.handleAwsUnavailable('AWS Services', availabilityError);
203
- return false;
204
- }
205
- }
206
- /**
207
- * Get all available configuration sources with their metadata.
208
- * @returns Promise resolving to array of configuration sources
209
- */
210
- async getAvailableSources() {
211
- const sources = [];
212
- for (const loader of this.loaders) {
213
- try {
214
- const isAvailable = await loader.isAvailable();
215
- if (isAvailable) {
216
- const loaderConfig = await loader.load();
217
- const source = {
218
- name: loader.getName(),
219
- type: this.getSourceType(loader),
220
- priority: this.getSourcePriority(loader),
221
- data: loaderConfig,
222
- loadedAt: new Date(),
223
- };
224
- sources.push(source);
225
- }
226
- }
227
- catch (error) {
228
- // Add source with error information
229
- const source = {
230
- name: loader.getName(),
231
- type: this.getSourceType(loader),
232
- priority: this.getSourcePriority(loader),
233
- data: {},
234
- loadedAt: new Date(),
235
- errors: [error instanceof Error ? error.message : String(error)],
236
- };
237
- sources.push(source);
238
- }
239
- }
240
- return sources;
241
- }
242
- /**
243
- * Create configuration loaders based on integration options.
244
- * @returns Array of configuration loaders
245
- */
246
- createLoaders() {
247
- const loaders = [];
248
- // Always include environment loader
249
- loaders.push(new EnvironmentLoader({ prefix: this.options.envPrefix }));
250
- // Add AWS Secrets Manager loader if configured
251
- if (this.options.secretsManagerConfig?.enabled !== false) {
252
- const secretsConfig = {
253
- region: this.options.secretsManagerConfig?.region,
254
- // Convert paths to secretName format expected by SecretsManagerLoader
255
- secretName: this.getSecretsManagerPath(),
256
- };
257
- loaders.push(new SecretsManagerLoader(secretsConfig));
258
- }
259
- // Add SSM Parameter Store loader if configured
260
- if (this.options.ssmConfig?.enabled !== false) {
261
- const ssmConfig = {
262
- region: this.options.ssmConfig?.region,
263
- // Convert paths to parameterPath format expected by SSMParameterStoreLoader
264
- parameterPath: this.getSSMParameterPath(),
265
- withDecryption: this.options.ssmConfig?.decrypt ?? true,
266
- };
267
- loaders.push(new SSMParameterStoreLoader(ssmConfig));
268
- }
269
- return loaders;
270
- }
271
- /**
272
- * Get the source type for a given loader.
273
- * @param loader - The configuration loader
274
- * @returns The configuration source type
275
- */
276
- getSourceType(loader) {
277
- if (loader instanceof EnvironmentLoader) {
278
- return 'environment';
279
- }
280
- else if (loader instanceof SecretsManagerLoader) {
281
- return 'secrets-manager';
282
- }
283
- else if (loader instanceof SSMParameterStoreLoader) {
284
- return 'ssm';
285
- }
286
- else {
287
- return 'local-file';
288
- }
289
- }
290
- /**
291
- * Get the priority for a given loader based on precedence rules.
292
- * @param loader - The configuration loader
293
- * @returns The priority number (higher = higher priority)
294
- */
295
- getSourcePriority(loader) {
296
- const precedence = this.options.precedence || 'aws-first';
297
- if (precedence === 'local-first') {
298
- // Environment variables have highest priority
299
- if (loader instanceof EnvironmentLoader)
300
- return 100;
301
- if (loader instanceof SecretsManagerLoader)
302
- return 50;
303
- if (loader instanceof SSMParameterStoreLoader)
304
- return 40;
305
- }
306
- else if (precedence === 'aws-first') {
307
- // AWS sources have higher priority
308
- if (loader instanceof SecretsManagerLoader)
309
- return 100;
310
- if (loader instanceof SSMParameterStoreLoader)
311
- return 90;
312
- if (loader instanceof EnvironmentLoader)
313
- return 50;
314
- }
315
- else {
316
- // merge - equal priority, order matters
317
- return 50;
318
- }
319
- return 50;
320
- }
321
- /**
322
- * Extract configuration for a specific namespace from loaded configuration.
323
- * @param config - The loaded configuration
324
- * @param namespace - The namespace to extract
325
- * @returns Configuration values for the namespace
326
- */
327
- extractNamespaceConfig(config, namespace) {
328
- const namespaceConfig = {};
329
- const namespacePrefix = namespace.toUpperCase();
330
- // Strategy 1: Look for direct namespace key (e.g., config.database)
331
- if (config[namespace]) {
332
- Object.assign(namespaceConfig, config[namespace]);
333
- }
334
- // Strategy 2: Look for keys that start with the namespace prefix (e.g., DATABASE_HOST)
335
- for (const [key, value] of Object.entries(config)) {
336
- const upperKey = key.toUpperCase();
337
- // Check if key starts with namespace prefix followed by underscore
338
- if (upperKey.startsWith(`${namespacePrefix}_`)) {
339
- // Remove namespace prefix and underscore, convert to camelCase
340
- const namespacedKey = key.substring(namespace.length + 1);
341
- const camelCaseKey = this.toCamelCase(namespacedKey);
342
- if (camelCaseKey) {
343
- namespaceConfig[camelCaseKey] = value;
344
- }
345
- }
346
- }
347
- // Strategy 3: Look for nested namespace paths (e.g., /app/database/host)
348
- const nestedConfig = this.extractNestedNamespaceConfig(config, namespace);
349
- Object.assign(namespaceConfig, nestedConfig);
350
- return namespaceConfig;
351
- }
352
- /**
353
- * Extract nested namespace configuration from hierarchical keys.
354
- * @param config - The loaded configuration
355
- * @param namespace - The namespace to extract
356
- * @returns Configuration values for the namespace
357
- */
358
- extractNestedNamespaceConfig(config, namespace) {
359
- const namespaceConfig = {};
360
- const namespacePath = `/${namespace}/`;
361
- for (const [key, value] of Object.entries(config)) {
362
- // Check if key contains namespace path
363
- if (key.includes(namespacePath)) {
364
- // Extract the part after the namespace path
365
- const pathIndex = key.indexOf(namespacePath);
366
- const afterNamespace = key.substring(pathIndex + namespacePath.length);
367
- if (afterNamespace) {
368
- // Convert path segments to nested object structure
369
- const nestedKey = this.pathToNestedKey(afterNamespace);
370
- this.setNestedValue(namespaceConfig, nestedKey, value);
371
- }
372
- }
373
- }
374
- return namespaceConfig;
375
- }
376
- /**
377
- * Convert snake_case or kebab-case to camelCase.
378
- * @param str - String to convert
379
- * @returns camelCase string
380
- */
381
- toCamelCase(str) {
382
- return str
383
- .toLowerCase()
384
- .replace(/[_-](.)/g, (_, char) => char.toUpperCase());
385
- }
386
- /**
387
- * Convert path segments to nested key structure.
388
- * @param path - Path string (e.g., "host/port")
389
- * @returns Nested key structure
390
- */
391
- pathToNestedKey(path) {
392
- return path
393
- .split('/')
394
- .map(segment => this.toCamelCase(segment))
395
- .join('.');
396
- }
397
- /**
398
- * Set a nested value in an object using dot notation.
399
- * @param obj - Target object
400
- * @param path - Dot notation path
401
- * @param value - Value to set
402
- */
403
- setNestedValue(obj, path, value) {
404
- const keys = path.split('.');
405
- let current = obj;
406
- for (let i = 0; i < keys.length - 1; i++) {
407
- const key = keys[i];
408
- if (key && (!(key in current) || typeof current[key] !== 'object')) {
409
- current[key] = {};
410
- }
411
- if (key) {
412
- current = current[key];
413
- }
414
- }
415
- const lastKey = keys[keys.length - 1];
416
- if (lastKey) {
417
- current[lastKey] = value;
418
- }
419
- }
420
- /**
421
- * Get the Secrets Manager path based on configuration.
422
- * @returns The secrets manager path
423
- */
424
- getSecretsManagerPath() {
425
- const paths = this.options.secretsManagerConfig?.paths;
426
- if (!paths) {
427
- return '/nestjs-config-aws';
428
- }
429
- // Use the first available path or default
430
- return paths.production || paths.development || paths.test || '/nestjs-config-aws';
431
- }
432
- /**
433
- * Get the SSM Parameter Store path based on configuration.
434
- * @returns The SSM parameter path
435
- */
436
- getSSMParameterPath() {
437
- const paths = this.options.ssmConfig?.paths;
438
- if (!paths) {
439
- return '/nestjs-config-aws';
440
- }
441
- // Use the first available path or default
442
- return paths.production || paths.development || paths.test || '/nestjs-config-aws';
443
- }
444
- /**
445
- * Check if an error is an AWS service error.
446
- * @param error - The error to check
447
- * @returns Whether the error is from an AWS service
448
- */
449
- isAwsServiceError(error) {
450
- // AWS SDK errors typically have specific names
451
- const awsErrorNames = [
452
- 'AccessDeniedException',
453
- 'ResourceNotFoundException',
454
- 'InvalidRequestException',
455
- 'ThrottlingException',
456
- 'ServiceUnavailableException',
457
- 'NetworkingError',
458
- 'TimeoutError',
459
- 'CredentialsError',
460
- 'UnknownEndpoint',
461
- ];
462
- return awsErrorNames.includes(error.name) || error.message.includes('AWS');
463
- }
464
- /**
465
- * Handle AWS-specific errors with appropriate strategies.
466
- * @param loader - The loader that encountered the error
467
- * @param error - The AWS error
468
- * @returns Whether to continue processing
469
- */
470
- handleAwsSpecificError(loader, error) {
471
- const serviceName = this.getServiceName(loader);
472
- switch (error.name) {
473
- case 'AccessDeniedException':
474
- return this.errorHandler.handlePermissionError(serviceName, this.getResourceName(loader), error);
475
- case 'ResourceNotFoundException':
476
- return this.errorHandler.handleResourceNotFound(serviceName, this.getResourceName(loader), error);
477
- case 'NetworkingError':
478
- case 'TimeoutError':
479
- const networkResult = this.errorHandler.handleNetworkError(serviceName, error);
480
- return networkResult.shouldContinue;
481
- case 'ThrottlingException':
482
- case 'TooManyRequestsException':
483
- this.logger.warn(`Rate limiting encountered for ${serviceName}, continuing with other sources`);
484
- return true;
485
- case 'ServiceUnavailableException':
486
- return this.errorHandler.handleAwsUnavailable(serviceName, error);
487
- case 'CredentialsError':
488
- this.logger.error(`AWS credentials error for ${serviceName}: ${error.message}`);
489
- this.logger.error('Please check AWS credentials configuration');
490
- return this.errorHandler.handleAwsUnavailable(serviceName, error);
491
- default:
492
- // Handle as general configuration error
493
- return this.errorHandler.handleConfigurationError(serviceName, error);
494
- }
495
- }
496
- /**
497
- * Get the service name for a loader.
498
- * @param loader - The configuration loader
499
- * @returns The service name
500
- */
501
- getServiceName(loader) {
502
- if (loader instanceof SecretsManagerLoader) {
503
- return 'AWS Secrets Manager';
504
- }
505
- else if (loader instanceof SSMParameterStoreLoader) {
506
- return 'AWS Systems Manager Parameter Store';
507
- }
508
- else if (loader instanceof EnvironmentLoader) {
509
- return 'Environment Variables';
510
- }
511
- else {
512
- return 'Unknown Service';
513
- }
514
- }
515
- /**
516
- * Get the resource name for a loader.
517
- * @param loader - The configuration loader
518
- * @returns The resource name
519
- */
520
- getResourceName(loader) {
521
- if (loader instanceof SecretsManagerLoader) {
522
- return this.getSecretsManagerPath();
523
- }
524
- else if (loader instanceof SSMParameterStoreLoader) {
525
- return this.getSSMParameterPath();
526
- }
527
- else {
528
- return 'configuration';
529
- }
530
- }
531
- /**
532
- * Load configuration with retry logic for retryable errors.
533
- * @param loader - The configuration loader
534
- * @param maxRetries - Maximum number of retries
535
- * @returns Promise resolving to configuration data
536
- */
537
- async loadWithRetry(loader, maxRetries = 3) {
538
- let lastError = null;
539
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
540
- try {
541
- return await loader.load();
542
- }
543
- catch (error) {
544
- const loaderError = error instanceof Error ? error : new Error(String(error));
545
- lastError = loaderError;
546
- // Check if error is retryable
547
- if (!this.errorHandler.isRetryableError(loaderError) || attempt === maxRetries) {
548
- throw loaderError;
549
- }
550
- // Wait before retrying
551
- const delay = this.errorHandler.getRetryDelay(attempt);
552
- this.logger.warn(`Retrying ${loader.getName()} in ${delay}ms (attempt ${attempt}/${maxRetries})`);
553
- await new Promise(resolve => setTimeout(resolve, delay));
554
- }
555
- }
556
- // This should never be reached, but just in case
557
- throw lastError || new Error('Unknown error during retry');
558
- }
559
- /**
560
- * Check availability with timeout and error handling.
561
- * @param loader - The configuration loader
562
- * @param timeoutMs - Timeout in milliseconds
563
- * @returns Promise resolving to availability status
564
- */
565
- async checkAvailabilityWithTimeout(loader, timeoutMs = 5000) {
566
- try {
567
- const timeoutPromise = new Promise((_, reject) => {
568
- setTimeout(() => reject(new Error('Availability check timeout')), timeoutMs);
569
- });
570
- const availabilityPromise = loader.isAvailable();
571
- return await Promise.race([availabilityPromise, timeoutPromise]);
572
- }
573
- catch (error) {
574
- const loaderError = error instanceof Error ? error : new Error(String(error));
575
- if (this.options.enableLogging) {
576
- this.logger.debug(`Availability check failed for ${loader.getName()}: ${loaderError.message}`);
577
- }
578
- return false;
579
- }
580
- }
581
- };
582
- AwsConfigurationLoaderService = AwsConfigurationLoaderService_1 = __decorate([
583
- Injectable(),
584
- __param(0, Optional()),
585
- __param(0, Inject('INTEGRATION_OPTIONS')),
586
- __metadata("design:paramtypes", [Object])
587
- ], AwsConfigurationLoaderService);
588
- export { AwsConfigurationLoaderService };
589
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzLWNvbmZpZ3VyYXRpb24tbG9hZGVyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvaW50ZWdyYXRpb24vcHJvdmlkZXJzL2F3cy1jb25maWd1cmF0aW9uLWxvYWRlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEUsT0FBTyxFQUVMLG9CQUFvQixFQUNwQix1QkFBdUIsRUFDdkIsaUJBQWlCLEdBQ2xCLE1BQU0sb0JBQW9CLENBQUM7QUFJNUIsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFFeEU7OztHQUdHO0FBRUksSUFBTSw2QkFBNkIscUNBQW5DLE1BQU0sNkJBQTZCO0lBQ3ZCLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQywrQkFBNkIsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN4RCxPQUFPLENBQWlCO0lBQ3hCLE9BQU8sQ0FBcUI7SUFDNUIsWUFBWSxDQUFzQjtJQUVuRCxZQUM2QyxPQUE0QjtRQUV2RSxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sSUFBSSxFQUFFLENBQUM7UUFDN0IsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLG1CQUFtQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMxRCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUN0QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsS0FBSyxDQUFDLGlCQUFpQjtRQUNyQixNQUFNLFlBQVksR0FBd0IsRUFBRSxDQUFDO1FBQzdDLE1BQU0sT0FBTyxHQUEwQixFQUFFLENBQUM7UUFFMUMsS0FBSyxNQUFNLE1BQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDbEMs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QUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDL0UsQ0FBQyxDQUFDLENBQUM7WUFFSCxNQUFNLG1CQUFtQixHQUFHLE1BQU0sQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUVqRCxPQUFPLE1BQU0sT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLG1CQUFtQixFQUFFLGNBQWMsQ0FBQyxDQUFDLENBQUM7UUFDbkUsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLFdBQVcsR0FBRyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBRTlFLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQztnQkFDL0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsaUNBQWlDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsS0FBSyxXQUFXLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUNqRyxDQUFDO1lBRUQsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO0lBQ0gsQ0FBQztDQUNGLENBQUE7QUEvbkJZLDZCQUE2QjtJQUR6QyxVQUFVLEVBQUU7SUFRUixXQUFBLFFBQVEsRUFBRSxDQUFBO0lBQUUsV0FBQSxNQUFNLENBQUMscUJBQXFCLENBQUMsQ0FBQTs7R0FQakMsNkJBQTZCLENBK25CekMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBMb2dnZXIsIEluamVjdCwgT3B0aW9uYWwgfSBmcm9tICdAbmVzdGpzL2NvbW1vbic7XHJcbmltcG9ydCB7XHJcbiAgQ29uZmlnTG9hZGVyLFxyXG4gIFNlY3JldHNNYW5hZ2VyTG9hZGVyLFxyXG4gIFNTTVBhcmFtZXRlclN0b3JlTG9hZGVyLFxyXG4gIEVudmlyb25tZW50TG9hZGVyLFxyXG59IGZyb20gJ0BkeWFuZXQvY29uZmlnLWF3cyc7XHJcbmltcG9ydCB7IEludGVncmF0aW9uT3B0aW9ucyB9IGZyb20gJy4uL2ludGVyZmFjZXMvaW50ZWdyYXRpb24tb3B0aW9ucy5pbnRlcmZhY2UnO1xyXG5pbXBvcnQgeyBDb25maWd1cmF0aW9uU291cmNlLCBDb25maWd1cmF0aW9uU291cmNlVHlwZSB9IGZyb20gJy4uL2ludGVyZmFjZXMvY29uZmlndXJhdGlvbi1zb3VyY2UuaW50ZXJmYWNlJztcclxuXHJcbmltcG9ydCB7IEVycm9ySGFuZGxlclNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9lcnJvci1oYW5kbGVyLnNlcnZpY2UnO1xyXG5cclxuLyoqXHJcbiAqIFNlcnZpY2UgZm9yIGxvYWRpbmcgY29uZmlndXJhdGlvbiBmcm9tIEFXUyBzb3VyY2VzIGZvciBpbnRlZ3JhdGlvbiB3aXRoIEBuZXN0anMvY29uZmlnLlxyXG4gKiBVc2VzIGV4aXN0aW5nIEFXUyBsb2FkZXJzIHRvIGZldGNoIGNvbmZpZ3VyYXRpb24gYW5kIHByb3ZpZGVzIG5hbWVzcGFjZS1hd2FyZSBsb2FkaW5nIGNhcGFiaWxpdGllcy5cclxuICovXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIEF3c0NvbmZpZ3VyYXRpb25Mb2FkZXJTZXJ2aWNlIHtcclxuICBwcml2YXRlIHJlYWRvbmx5IGxvZ2dlciA9IG5ldyBMb2dnZXIoQXdzQ29uZmlndXJhdGlvbkxvYWRlclNlcnZpY2UubmFtZSk7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBsb2FkZXJzOiBDb25maWdMb2FkZXJbXTtcclxuICBwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM6IEludGVncmF0aW9uT3B0aW9ucztcclxuICBwcml2YXRlIHJlYWRvbmx5IGVycm9ySGFuZGxlcjogRXJyb3JIYW5kbGVyU2VydmljZTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KCdJTlRFR1JBVElPTl9PUFRJT05TJykgb3B0aW9ucz86IEludGVncmF0aW9uT3B0aW9uc1xyXG4gICkge1xyXG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcclxuICAgIHRoaXMuZXJyb3JIYW5kbGVyID0gbmV3IEVycm9ySGFuZGxlclNlcnZpY2UodGhpcy5vcHRpb25zKTtcclxuICAgIHRoaXMubG9hZGVycyA9IHRoaXMuY3JlYXRlTG9hZGVycygpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9hZCBjb25maWd1cmF0aW9uIGZyb20gQVdTIHNvdXJjZXMuXHJcbiAgICogQHJldHVybnMgUHJvbWlzZSByZXNvbHZpbmcgdG8gY29uZmlndXJhdGlvbiBkYXRhXHJcbiAgICovXHJcbiAgYXN5bmMgbG9hZENvbmZpZ3VyYXRpb24oKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PiB7XHJcbiAgICBjb25zdCBtZXJnZWRDb25maWc6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcclxuICAgIGNvbnN0IHNvdXJjZXM6IENvbmZpZ3VyYXRpb25Tb3VyY2VbXSA9IFtdO1xyXG5cclxuICAgIGZvciAoY29uc3QgbG9hZGVyIG9mIHRoaXMubG9hZGVycykge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIC8vIENoZWNrIGlmIGxvYWRlciBpcyBhdmFpbGFibGUgaW4gY3VycmVudCBlbnZpcm9ubWVudCB3aXRoIHRpbWVvdXRcclxuICAgICAgICBjb25zdCBpc0F2YWlsYWJsZSA9IGF3YWl0IHRoaXMuY2hlY2tBdmFpbGFiaWxpdHlXaXRoVGltZW91dChsb2FkZXIpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGlmICghaXNBdmFpbGFibGUpIHtcclxuICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuZW5hYmxlTG9nZ2luZykge1xyXG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgU2tpcHBpbmcgJHtsb2FkZXIuZ2V0TmFtZSgpfSAtIG5vdCBhdmFpbGFibGUgaW4gY3VycmVudCBlbnZpcm9ubWVudGApO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgY29udGludWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmVuYWJsZUxvZ2dpbmcpIHtcclxuICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBMb2FkaW5nIGNvbmZpZ3VyYXRpb24gZnJvbSAke2xvYWRlci5nZXROYW1lKCl9YCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBMb2FkIGNvbmZpZ3VyYXRpb24gZnJvbSB0aGlzIHNvdXJjZSB3aXRoIHJldHJ5IGxvZ2ljIGZvciBBV1Mgc2VydmljZXNcclxuICAgICAgICBjb25zdCBsb2FkZXJDb25maWcgPSBsb2FkZXIgaW5zdGFuY2VvZiBFbnZpcm9ubWVudExvYWRlciBcclxuICAgICAgICAgID8gYXdhaXQgbG9hZGVyLmxvYWQoKSBcclxuICAgICAgICAgIDogYXdhaXQgdGhpcy5sb2FkV2l0aFJldHJ5KGxvYWRlcik7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gQ3JlYXRlIGNvbmZpZ3VyYXRpb24gc291cmNlIG1ldGFkYXRhXHJcbiAgICAgICAgY29uc3Qgc291cmNlOiBDb25maWd1cmF0aW9uU291cmNlID0ge1xyXG4gICAgICAgICAgbmFtZTogbG9hZGVyLmdldE5hbWUoKSxcclxuICAgICAgICAgIHR5cGU6IHRoaXMuZ2V0U291cmNlVHlwZShsb2FkZXIpLFxyXG4gICAgICAgICAgcHJpb3JpdHk6IHRoaXMuZ2V0U291cmNlUHJpb3JpdHkobG9hZGVyKSxcclxuICAgICAgICAgIGRhdGE6IGxvYWRlckNvbmZpZyxcclxuICAgICAgICAgIGxvYWRlZEF0OiBuZXcgRGF0ZSgpLFxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHNvdXJjZXMucHVzaChzb3VyY2UpO1xyXG5cclxuICAgICAgICAvLyBNZXJnZSB3aXRoIGV4aXN0aW5nIGNvbmZpZ3VyYXRpb24gYmFzZWQgb24gcHJlY2VkZW5jZVxyXG4gICAgICAgIE9iamVjdC5hc3NpZ24obWVyZ2VkQ29uZmlnLCBsb2FkZXJDb25maWcpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuZW5hYmxlTG9nZ2luZykge1xyXG4gICAgICAgICAgY29uc3Qga2V5Q291bnQgPSBPYmplY3Qua2V5cyhsb2FkZXJDb25maWcpLmxlbmd0aDtcclxuICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBMb2FkZWQgJHtrZXlDb3VudH0gY29uZmlndXJhdGlvbiB2YWx1ZXMgZnJvbSAke2xvYWRlci5nZXROYW1lKCl9YCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgIGNvbnN0IGxvYWRlckVycm9yID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIExvZyBkZXRhaWxlZCBlcnJvciBpbmZvcm1hdGlvbiBmb3IgdHJvdWJsZXNob290aW5nXHJcbiAgICAgICAgdGhpcy5lcnJvckhhbmRsZXIubG9nRGV0YWlsZWRFcnJvcihgbG9hZENvbmZpZ3VyYXRpb24gLSAke2xvYWRlci5nZXROYW1lKCl9YCwgbG9hZGVyRXJyb3IsIHtcclxuICAgICAgICAgIGxvYWRlck5hbWU6IGxvYWRlci5nZXROYW1lKCksXHJcbiAgICAgICAgICBsb2FkZXJUeXBlOiB0aGlzLmdldFNvdXJjZVR5cGUobG9hZGVyKSxcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgLy8gSGFuZGxlIHNwZWNpZmljIGVycm9yIHR5cGVzXHJcbiAgICAgICAgaWYgKHRoaXMuaXNBd3NTZXJ2aWNlRXJyb3IobG9hZGVyRXJyb3IpKSB7XHJcbiAgICAgICAgICBjb25zdCBzaG91bGRDb250aW51ZSA9IHRoaXMuaGFuZGxlQXdzU3BlY2lmaWNFcnJvcihsb2FkZXIsIGxvYWRlckVycm9yKTtcclxuICAgICAgICAgIGlmICghc2hvdWxkQ29udGludWUpIHtcclxuICAgICAgICAgICAgdGhyb3cgbG9hZGVyRXJyb3I7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIC8vIEhhbmRsZSBnZW5lcmFsIGNvbmZpZ3VyYXRpb24gZXJyb3JzXHJcbiAgICAgICAgICBjb25zdCBzaG91bGRDb250aW51ZSA9IHRoaXMuZXJyb3JIYW5kbGVyLmhhbmRsZUNvbmZpZ3VyYXRpb25FcnJvcihsb2FkZXIuZ2V0TmFtZSgpLCBsb2FkZXJFcnJvcik7XHJcbiAgICAgICAgICBpZiAoIXNob3VsZENvbnRpbnVlKSB7XHJcbiAgICAgICAgICAgIHRocm93IGxvYWRlckVycm9yO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQWRkIGVycm9yIHRvIHNvdXJjZSBtZXRhZGF0YVxyXG4gICAgICAgIGNvbnN0IGVycm9yU291cmNlOiBDb25maWd1cmF0aW9uU291cmNlID0ge1xyXG4gICAgICAgICAgbmFtZTogbG9hZGVyLmdldE5hbWUoKSxcclxuICAgICAgICAgIHR5cGU6IHRoaXMuZ2V0U291cmNlVHlwZShsb2FkZXIpLFxyXG4gICAgICAgICAgcHJpb3JpdHk6IHRoaXMuZ2V0U291cmNlUHJpb3JpdHkobG9hZGVyKSxcclxuICAgICAgICAgIGRhdGE6IHt9LFxyXG4gICAgICAgICAgbG9hZGVkQXQ6IG5ldyBEYXRlKCksXHJcbiAgICAgICAgICBlcnJvcnM6IFtsb2FkZXJFcnJvci5tZXNzYWdlXSxcclxuICAgICAgICB9O1xyXG4gICAgICAgIHNvdXJjZXMucHVzaChlcnJvclNvdXJjZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbWVyZ2VkQ29uZmlnO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9hZCBjb25maWd1cmF0aW9uIGZvciBzcGVjaWZpYyBuYW1lc3BhY2VzIGZyb20gQVdTIHNvdXJjZXMuXHJcbiAgICogQHBhcmFtIG5hbWVzcGFjZXMgLSBBcnJheSBvZiBuYW1lc3BhY2UgbmFtZXMgdG8gbG9hZFxyXG4gICAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIG5hbWVzcGFjZWQgY29uZmlndXJhdGlvbiBkYXRhXHJcbiAgICovXHJcbiAgYXN5bmMgbG9hZE5hbWVzcGFjZWRDb25maWd1cmF0aW9uKG5hbWVzcGFjZXM6IHN0cmluZ1tdKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBhbnk+Pj4ge1xyXG4gICAgY29uc3QgcmVzdWx0OiBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBhbnk+PiA9IHt9O1xyXG4gICAgXHJcbiAgICAvLyBJbml0aWFsaXplIGFsbCBuYW1lc3BhY2VzXHJcbiAgICBmb3IgKGNvbnN0IG5hbWVzcGFjZSBvZiBuYW1lc3BhY2VzKSB7XHJcbiAgICAgIHJlc3VsdFtuYW1lc3BhY2VdID0ge307XHJcbiAgICB9XHJcblxyXG4gICAgZm9yIChjb25zdCBsb2FkZXIgb2YgdGhpcy5sb2FkZXJzKSB7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgLy8gQ2hlY2sgaWYgbG9hZGVyIGlzIGF2YWlsYWJsZSBpbiBjdXJyZW50IGVudmlyb25tZW50IHdpdGggdGltZW91dFxyXG4gICAgICAgIGNvbnN0IGlzQXZhaWxhYmxlID0gYXdhaXQgdGhpcy5jaGVja0F2YWlsYWJpbGl0eVdpdGhUaW1lb3V0KGxvYWRlcik7XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKCFpc0F2YWlsYWJsZSkge1xyXG4gICAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5lbmFibGVMb2dnaW5nKSB7XHJcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBTa2lwcGluZyAke2xvYWRlci5nZXROYW1lKCl9IGZvciBuYW1lc3BhY2UgbG9hZGluZyAtIG5vdCBhdmFpbGFibGVgKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5lbmFibGVMb2dnaW5nKSB7XHJcbiAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgTG9hZGluZyBuYW1lc3BhY2VkIGNvbmZpZ3VyYXRpb24gZnJvbSAke2xvYWRlci5nZXROYW1lKCl9YCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBMb2FkIGNvbmZpZ3VyYXRpb24gZnJvbSB0aGlzIHNvdXJjZSB3aXRoIHJldHJ5IGxvZ2ljIGZvciBBV1Mgc2VydmljZXNcclxuICAgICAgICBjb25zdCBsb2FkZXJDb25maWcgPSBsb2FkZXIgaW5zdGFuY2VvZiBFbnZpcm9ubWVudExvYWRlciBcclxuICAgICAgICAgID8gYXdhaXQgbG9hZGVyLmxvYWQoKSBcclxuICAgICAgICAgIDogYXdhaXQgdGhpcy5sb2FkV2l0aFJldHJ5KGxvYWRlcik7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gRGlzdHJpYnV0ZSBjb25maWd1cmF0aW9uIHRvIG5hbWVzcGFjZXMgYmFzZWQgb24ga2V5IHByZWZpeGVzIG9yIHBhdHRlcm5zXHJcbiAgICAgICAgZm9yIChjb25zdCBuYW1lc3BhY2Ugb2YgbmFtZXNwYWNlcykge1xyXG4gICAgICAgICAgY29uc3QgbmFtZXNwYWNlZENvbmZpZyA9IHRoaXMuZXh0cmFjdE5hbWVzcGFjZUNvbmZpZyhsb2FkZXJDb25maWcsIG5hbWVzcGFjZSk7XHJcbiAgICAgICAgICBcclxuICAgICAgICAgIGlmIChPYmplY3Qua2V5cyhuYW1lc3BhY2VkQ29uZmlnKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24ocmVzdWx0W25hbWVzcGFjZV0hLCBuYW1lc3BhY2VkQ29uZmlnKTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGlmICh0aGlzLm9wdGlvbnMuZW5hYmxlTG9nZ2luZykge1xyXG4gICAgICAgICAgICAgIGNvbnN0IGtleUNvdW50ID0gT2JqZWN0LmtleXMobmFtZXNwYWNlZENvbmZpZykubGVuZ3RoO1xyXG4gICAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBMb2FkZWQgJHtrZXlDb3VudH0gdmFsdWVzIGZvciBuYW1lc3BhY2UgJyR7bmFtZXNwYWNlfScgZnJvbSAke2xvYWRlci5nZXROYW1lKCl9YCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgY29uc3QgbG9hZGVyRXJyb3IgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoU3RyaW5nKGVycm9yKSk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gTG9nIGRldGFpbGVkIGVycm9yIGluZm9ybWF0aW9uIGZvciB0cm91Ymxlc2hvb3RpbmdcclxuICAgICAgICB0aGlzLmVycm9ySGFuZGxlci5sb2dEZXRhaWxlZEVycm9yKGBsb2FkTmFtZXNwYWNlZENvbmZpZ3VyYXRpb24gLSAke2xvYWRlci5nZXROYW1lKCl9YCwgbG9hZGVyRXJyb3IsIHtcclxuICAgICAgICAgIGxvYWRlck5hbWU6IGxvYWRlci5nZXROYW1lKCksXHJcbiAgICAgICAgICBsb2FkZXJUeXBlOiB0aGlzLmdldFNvdXJjZVR5cGUobG9hZGVyKSxcclxuICAgICAgICAgIG5hbWVzcGFjZXMsXHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIC8vIEhhbmRsZSBzcGVjaWZpYyBlcnJvciB0eXBlc1xyXG4gICAgICAgIGlmICh0aGlzLmlzQXdzU2VydmljZUVycm9yKGxvYWRlckVycm9yKSkge1xyXG4gICAgICAgICAgY29uc3Qgc2hvdWxkQ29udGludWUgPSB0aGlzLmhhbmRsZUF3c1NwZWNpZmljRXJyb3IobG9hZGVyLCBsb2FkZXJFcnJvcik7XHJcbiAgICAgICAgICBpZiAoIXNob3VsZENvbnRpbnVlKSB7XHJcbiAgICAgICAgICAgIHRocm93IGxvYWRlckVycm9yO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAvLyBIYW5kbGUgZ2VuZXJhbCBjb25maWd1cmF0aW9uIGVycm9yc1xyXG4gICAgICAgICAgY29uc3Qgc2hvdWxkQ29udGludWUgPSB0aGlzLmVycm9ySGFuZGxlci5oYW5kbGVDb25maWd1cmF0aW9uRXJyb3IobG9hZGVyLmdldE5hbWUoKSwgbG9hZGVyRXJyb3IpO1xyXG4gICAgICAgICAgaWYgKCFzaG91bGRDb250aW51ZSkge1xyXG4gICAgICAgICAgICB0aHJvdyBsb2FkZXJFcnJvcjtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIENyZWF0ZSBmYWxsYmFjayBjb25maWd1cmF0aW9uIGZvciBlYWNoIG5hbWVzcGFjZVxyXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuZmFsbGJhY2tUb0xvY2FsKSB7XHJcbiAgICAgICAgICBmb3IgKGNvbnN0IG5hbWVzcGFjZSBvZiBuYW1lc3BhY2VzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGZhbGxiYWNrQ29uZmlnID0gdGhpcy5lcnJvckhhbmRsZXIuY3JlYXRlRmFsbGJhY2tDb25maWd1cmF0aW9uKG5hbWVzcGFjZSk7XHJcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24ocmVzdWx0W25hbWVzcGFjZV0hLCBmYWxsYmFja0NvbmZpZyk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrIGlmIEFXUyBzZXJ2aWNlcyBhcmUgYXZhaWxhYmxlLlxyXG4gICAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIGF2YWlsYWJpbGl0eSBzdGF0dXNcclxuICAgKi9cclxuICBhc3luYyBpc0F2YWlsYWJsZSgpOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuICAgIHRyeSB7XHJcbiAgICAgIC8vIENoZWNrIGlmIGF0IGxlYXN0IG9uZSBBV1MgbG9hZGVyIGlzIGF2YWlsYWJsZVxyXG4gICAgICBjb25zdCBhdmFpbGFiaWxpdHlDaGVja3MgPSB0aGlzLmxvYWRlcnNcclxuICAgICAgICAuZmlsdGVyKGxvYWRlciA9PiAhKGxvYWRlciBpbnN0YW5jZW9mIEVudmlyb25tZW50TG9hZGVyKSkgLy8gU2tpcCBlbnZpcm9ubWVudCBsb2FkZXJcclxuICAgICAgICAubWFwKGxvYWRlciA9PiB0aGlzLmNoZWNrQXZhaWxhYmlsaXR5V2l0aFRpbWVvdXQobG9hZGVyKSk7XHJcblxyXG4gICAgICBpZiAoYXZhaWxhYmlsaXR5Q2hlY2tzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgIC8vIE5vIEFXUyBsb2FkZXJzIGNvbmZpZ3VyZWRcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIFdhaXQgZm9yIGFsbCBhdmFpbGFiaWxpdHkgY2hlY2tzIHRvIGNvbXBsZXRlXHJcbiAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoYXZhaWxhYmlsaXR5Q2hlY2tzKTtcclxuICAgICAgXHJcbiAgICAgIC8vIFJldHVybiB0cnVlIGlmIGF0IGxlYXN0IG9uZSBBV1Mgc2VydmljZSBpcyBhdmFpbGFibGVcclxuICAgICAgcmV0dXJuIHJlc3VsdHMuc29tZShyZXN1bHQgPT4gcmVzdWx0LnN0YXR1cyA9PT0gJ2Z1bGZpbGxlZCcgJiYgcmVzdWx0LnZhbHVlID09PSB0cnVlKTtcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIGNvbnN0IGF2YWlsYWJpbGl0eUVycm9yID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpO1xyXG4gICAgICBcclxuICAgICAgdGhpcy5lcnJvckhhbmRsZXIubG9nRGV0YWlsZWRFcnJvcignaXNBdmFpbGFibGUnLCBhdmFpbGFiaWxpdHlFcnJvcik7XHJcbiAgICAgIFxyXG4gICAgICAvLyBIYW5kbGUgYXMgQVdTIHVuYXZhaWxhYmxlXHJcbiAgICAgIHRoaXMuZXJyb3JIYW5kbGVyLmhhbmRsZUF3c1VuYXZhaWxhYmxlKCdBV1MgU2VydmljZXMnLCBhdmFpbGFiaWxpdHlFcnJvcik7XHJcbiAgICAgIFxyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgYWxsIGF2YWlsYWJsZSBjb25maWd1cmF0aW9uIHNvdXJjZXMgd2l0aCB0aGVpciBtZXRhZGF0YS5cclxuICAgKiBAcmV0dXJucyBQcm9taXNlIHJlc29sdmluZyB0byBhcnJheSBvZiBjb25maWd1cmF0aW9uIHNvdXJjZXNcclxuICAgKi9cclxuICBhc3luYyBnZXRBdmFpbGFibGVTb3VyY2VzKCk6IFByb21pc2U8Q29uZmlndXJhdGlvblNvdXJjZVtdPiB7XHJcbiAgICBjb25zdCBzb3VyY2VzOiBDb25maWd1cmF0aW9uU291cmNlW10gPSBbXTtcclxuXHJcbiAgICBmb3IgKGNvbnN0IGxvYWRlciBvZiB0aGlzLmxvYWRlcnMpIHtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBjb25zdCBpc0F2YWlsYWJsZSA9IGF3YWl0IGxvYWRlci5pc0F2YWlsYWJsZSgpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGlmIChpc0F2YWlsYWJsZSkge1xyXG4gICAgICAgICAgY29uc3QgbG9hZGVyQ29uZmlnID0gYXdhaXQgbG9hZGVyLmxvYWQoKTtcclxuICAgICAgICAgIFxyXG4gICAgICAgICAgY29uc3Qgc291cmNlOiBDb25maWd1cmF0aW9uU291cmNlID0ge1xyXG4gICAgICAgICAgICBuYW1lOiBsb2FkZXIuZ2V0TmFtZSgpLFxyXG4gICAgICAgICAgICB0eXBlOiB0aGlzLmdldFNvdXJjZVR5cGUobG9hZGVyKSxcclxuICAgICAgICAgICAgcHJpb3JpdHk6IHRoaXMuZ2V0U291cmNlUHJpb3JpdHkobG9hZGVyKSxcclxuICAgICAgICAgICAgZGF0YTogbG9hZGVyQ29uZmlnLFxyXG4gICAgICAgICAgICBsb2FkZWRBdDogbmV3IERhdGUoKSxcclxuICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgc291cmNlcy5wdXNoKHNvdXJjZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgIC8vIEFkZCBzb3VyY2Ugd2l0aCBlcnJvciBpbmZvcm1hdGlvblxyXG4gICAgICAgIGNvbnN0IHNvdXJjZTogQ29uZmlndXJhdGlvblNvdXJjZSA9IHtcclxuICAgICAgICAgIG5hbWU6IGxvYWRlci5nZXROYW1lKCksXHJcbiAgICAgICAgICB0eXBlOiB0aGlzLmdldFNvdXJjZVR5cGUobG9hZGVyKSxcclxuICAgICAgICAgIHByaW9yaXR5OiB0aGlzLmdldFNvdXJjZVByaW9yaXR5KGxvYWRlciksXHJcbiAgICAgICAgICBkYXRhOiB7fSxcclxuICAgICAgICAgIGxvYWRlZEF0OiBuZXcgRGF0ZSgpLFxyXG4gICAgICAgICAgZXJyb3JzOiBbZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpXSxcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICBzb3VyY2VzLnB1c2goc291cmNlKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBzb3VyY2VzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ3JlYXRlIGNvbmZpZ3VyYXRpb24gbG9hZGVycyBiYXNlZCBvbiBpbnRlZ3JhdGlvbiBvcHRpb25zLlxyXG4gICAqIEByZXR1cm5zIEFycmF5IG9mIGNvbmZpZ3VyYXRpb24gbG9hZGVyc1xyXG4gICAqL1xyXG4gIHByaXZhdGUgY3JlYXRlTG9hZGVycygpOiBDb25maWdMb2FkZXJbXSB7XHJcbiAgICBjb25zdCBsb2FkZXJzOiBDb25maWdMb2FkZXJbXSA9IFtdO1xyXG5cclxuICAgIC8vIEFsd2F5cyBpbmNsdWRlIGVudmlyb25tZW50IGxvYWRlclxyXG4gICAgbG9hZGVycy5wdXNoKG5ldyBFbnZpcm9ubWVudExvYWRlcih7IHByZWZpeDogdGhpcy5vcHRpb25zLmVudlByZWZpeCB9KSk7XHJcblxyXG4gICAgLy8gQWRkIEFXUyBTZWNyZXRzIE1hbmFnZXIgbG9hZGVyIGlmIGNvbmZpZ3VyZWRcclxuICAgIGlmICh0aGlzLm9wdGlvbnMuc2VjcmV0c01hbmFnZXJDb25maWc/LmVuYWJsZWQgIT09IGZhbHNlKSB7XHJcbiAgICAgIGNvbnN0IHNlY3JldHNDb25maWcgPSB7XHJcbiAgICAgICAgcmVnaW9uOiB0aGlzLm9wdGlvbnMuc2VjcmV0c01hbmFnZXJDb25maWc/LnJlZ2lvbixcclxuICAgICAgICAvLyBDb252ZXJ0IHBhdGhzIHRvIHNlY3JldE5hbWUgZm9ybWF0IGV4cGVjdGVkIGJ5IFNlY3JldHNNYW5hZ2VyTG9hZGVyXHJcbiAgICAgICAgc2VjcmV0TmFtZTogdGhpcy5nZXRTZWNyZXRzTWFuYWdlclBhdGgoKSxcclxuICAgICAgfTtcclxuICAgICAgbG9hZGVycy5wdXNoKG5ldyBTZWNyZXRzTWFuYWdlckxvYWRlcihzZWNyZXRzQ29uZmlnKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQWRkIFNTTSBQYXJhbWV0ZXIgU3RvcmUgbG9hZGVyIGlmIGNvbmZpZ3VyZWRcclxuICAgIGlmICh0aGlzLm9wdGlvbnMuc3NtQ29uZmlnPy5lbmFibGVkICE9PSBmYWxzZSkge1xyXG4gICAgICBjb25zdCBzc21Db25maWcgPSB7XHJcbiAgICAgICAgcmVnaW9uOiB0aGlzLm9wdGlvbnMuc3NtQ29uZmlnPy5yZWdpb24sXHJcbiAgICAgICAgLy8gQ29udmVydCBwYXRocyB0byBwYXJhbWV0ZXJQYXRoIGZvcm1hdCBleHBlY3RlZCBieSBTU01QYXJhbWV0ZXJTdG9yZUxvYWRlclxyXG4gICAgICAgIHBhcmFtZXRlclBhdGg6IHRoaXMuZ2V0U1NNUGFyYW1ldGVyUGF0aCgpLFxyXG4gICAgICAgIHdpdGhEZWNyeXB0aW9uOiB0aGlzLm9wdGlvbnMuc3NtQ29uZmlnPy5kZWNyeXB0ID8/IHRydWUsXHJcbiAgICAgIH07XHJcbiAgICAgIGxvYWRlcnMucHVzaChuZXcgU1NNUGFyYW1ldGVyU3RvcmVMb2FkZXIoc3NtQ29uZmlnKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGxvYWRlcnM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgdGhlIHNvdXJjZSB0eXBlIGZvciBhIGdpdmVuIGxvYWRlci5cclxuICAgKiBAcGFyYW0gbG9hZGVyIC0gVGhlIGNvbmZpZ3VyYXRpb24gbG9hZGVyXHJcbiAgICogQHJldHVybnMgVGhlIGNvbmZpZ3VyYXRpb24gc291cmNlIHR5cGVcclxuICAgKi9cclxuICBwcml2YXRlIGdldFNvdXJjZVR5cGUobG9hZGVyOiBDb25maWdMb2FkZXIpOiBDb25maWd1cmF0aW9uU291cmNlVHlwZSB7XHJcbiAgICBpZiAobG9hZGVyIGluc3RhbmNlb2YgRW52aXJvbm1lbnRMb2FkZXIpIHtcclxuICAgICAgcmV0dXJuICdlbnZpcm9ubWVudCc7XHJcbiAgICB9IGVsc2UgaWYgKGxvYWRlciBpbnN0YW5jZW9mIFNlY3JldHNNYW5hZ2VyTG9hZGVyKSB7XHJcbiAgICAgIHJldHVybiAnc2VjcmV0cy1tYW5hZ2VyJztcclxuICAgIH0gZWxzZSBpZiAobG9hZGVyIGluc3RhbmNlb2YgU1NNUGFyYW1ldGVyU3RvcmVMb2FkZXIpIHtcclxuICAgICAgcmV0dXJuICdzc20nO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuICdsb2NhbC1maWxlJztcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCB0aGUgcHJpb3JpdHkgZm9yIGEgZ2l2ZW4gbG9hZGVyIGJhc2VkIG9uIHByZWNlZGVuY2UgcnVsZXMuXHJcbiAgICogQHBhcmFtIGxvYWRlciAtIFRoZSBjb25maWd1cmF0aW9uIGxvYWRlclxyXG4gICAqIEByZXR1cm5zIFRoZSBwcmlvcml0eSBudW1iZXIgKGhpZ2hlciA9IGhpZ2hlciBwcmlvcml0eSlcclxuICAgKi9cclxuICBwcml2YXRlIGdldFNvdXJjZVByaW9yaXR5KGxvYWRlcjogQ29uZmlnTG9hZGVyKTogbnVtYmVyIHtcclxuICAgIGNvbnN0IHByZWNlZGVuY2UgPSB0aGlzLm9wdGlvbnMucHJlY2VkZW5jZSB8fCAnYXdzLWZpcnN0JztcclxuICAgIFxyXG4gICAgaWYgKHByZWNlZGVuY2UgPT09ICdsb2NhbC1maXJzdCcpIHtcclxuICAgICAgLy8gRW52aXJvbm1lbnQgdmFyaWFibGVzIGhhdmUgaGlnaGVzdCBwcmlvcml0eVxyXG4gICAgICBpZiAobG9hZGVyIGluc3RhbmNlb2YgRW52aXJvbm1lbnRMb2FkZXIpIHJldHVybiAxMDA7XHJcbiAgICAgIGlmIChsb2FkZXIgaW5zdGFuY2VvZiBTZWNyZXRzTWFuYWdlckxvYWRlcikgcmV0dXJuIDUwO1xyXG4gICAgICBpZiAobG9hZGVyIGluc3RhbmNlb2YgU1NNUGFyYW1ldGVyU3RvcmVMb2FkZXIpIHJldHVybiA0MDtcclxuICAgIH0gZWxzZSBpZiAocHJlY2VkZW5jZSA9PT0gJ2F3cy1maXJzdCcpIHtcclxuICAgICAgLy8gQVdTIHNvdXJjZXMgaGF2ZSBoaWdoZXIgcHJpb3JpdHlcclxuICAgICAgaWYgKGxvYWRlciBpbnN0YW5jZW9mIFNlY3JldHNNYW5hZ2VyTG9hZGVyKSByZXR1cm4gMTAwO1xyXG4gICAgICBpZiAobG9hZGVyIGluc3RhbmNlb2YgU1NNUGFyYW1ldGVyU3RvcmVMb2FkZXIpIHJldHVybiA5MDtcclxuICAgICAgaWYgKGxvYWRlciBpbnN0YW5jZW9mIEVudmlyb25tZW50TG9hZGVyKSByZXR1cm4gNTA7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyBtZXJnZSAtIGVxdWFsIHByaW9yaXR5LCBvcmRlciBtYXR0ZXJzXHJcbiAgICAgIHJldHVybiA1MDtcclxuICAgIH1cclxuICAgIFxyXG4gICAgcmV0dXJuIDUwO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRXh0cmFjdCBjb25maWd1cmF0aW9uIGZvciBhIHNwZWNpZmljIG5hbWVzcGFjZSBmcm9tIGxvYWRlZCBjb25maWd1cmF0aW9uLlxyXG4gICAqIEBwYXJhbSBjb25maWcgLSBUaGUgbG9hZGVkIGNvbmZpZ3VyYXRpb25cclxuICAgKiBAcGFyYW0gbmFtZXNwYWNlIC0gVGhlIG5hbWVzcGFjZSB0byBleHRyYWN0XHJcbiAgICogQHJldHVybnMgQ29uZmlndXJhdGlvbiB2YWx1ZXMgZm9yIHRoZSBuYW1lc3BhY2VcclxuICAgKi9cclxuICBwcml2YXRlIGV4dHJhY3ROYW1lc3BhY2VDb25maWcoY29uZmlnOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBuYW1lc3BhY2U6IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIGFueT4ge1xyXG4gICAgY29uc3QgbmFtZXNwYWNlQ29uZmlnOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XHJcbiAgICBjb25zdCBuYW1lc3BhY2VQcmVmaXggPSBuYW1lc3BhY2UudG9VcHBlckNhc2UoKTtcclxuXHJcbiAgICAvLyBTdHJhdGVneSAxOiBMb29rIGZvciBkaXJlY3QgbmFtZXNwYWNlIGtleSAoZS5nLiwgY29uZmlnLmRhdGFiYXNlKVxyXG4gICAgaWYgKGNvbmZpZ1tuYW1lc3BhY2VdKSB7XHJcbiAgICAgIE9iamVjdC5hc3NpZ24obmFtZXNwYWNlQ29uZmlnLCBjb25maWdbbmFtZXNwYWNlXSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gU3RyYXRlZ3kgMjogTG9vayBmb3Iga2V5cyB0aGF0IHN0YXJ0IHdpdGggdGhlIG5hbWVzcGFjZSBwcmVmaXggKGUuZy4sIERBVEFCQVNFX0hPU1QpXHJcbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhjb25maWcpKSB7XHJcbiAgICAgIGNvbnN0IHVwcGVyS2V5ID0ga2V5LnRvVXBwZXJDYXNlKCk7XHJcbiAgICAgIFxyXG4gICAgICAvLyBDaGVjayBpZiBrZXkgc3RhcnRzIHdpdGggbmFtZXNwYWNlIHByZWZpeCBmb2xsb3dlZCBieSB1bmRlcnNjb3JlXHJcbiAgICAgIGlmICh1cHBlcktleS5zdGFydHNXaXRoKGAke25hbWVzcGFjZVByZWZpeH1fYCkpIHtcclxuICAgICAgICAvLyBSZW1vdmUgbmFtZXNwYWNlIHByZWZpeCBhbmQgdW5kZXJzY29yZSwgY29udmVydCB0byBjYW1lbENhc2VcclxuICAgICAgICBjb25zdCBuYW1lc3BhY2VkS2V5ID0ga2V5LnN1YnN0cmluZyhuYW1lc3BhY2UubGVuZ3RoICsgMSk7XHJcbiAgICAgICAgY29uc3QgY2FtZWxDYXNlS2V5ID0gdGhpcy50b0NhbWVsQ2FzZShuYW1lc3BhY2VkS2V5KTtcclxuICAgICAgICBcclxuICAgICAgICBpZiAoY2FtZWxDYXNlS2V5KSB7XHJcbiAgICAgICAgICBuYW1lc3BhY2VDb25maWdbY2FtZWxDYXNlS2V5XSA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIFN0cmF0ZWd5IDM6IExvb2sgZm9yIG5lc3RlZCBuYW1lc3BhY2UgcGF0aHMgKGUuZy4sIC9hcHAvZGF0YWJhc2UvaG9zdClcclxuICAgIGNvbnN0IG5lc3RlZENvbmZpZyA9IHRoaXMuZXh0cmFjdE5lc3RlZE5hbWVzcGFjZUNvbmZpZyhjb25maWcsIG5hbWVzcGFjZSk7XHJcbiAgICBPYmplY3QuYXNzaWduKG5hbWVzcGFjZUNvbmZpZywgbmVzdGVkQ29uZmlnKTtcclxuXHJcbiAgICByZXR1cm4gbmFtZXNwYWNlQ29uZmlnO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRXh0cmFjdCBuZXN0ZWQgbmFtZXNwYWNlIGNvbmZpZ3VyYXRpb24gZnJvbSBoaWVyYXJjaGljYWwga2V5cy5cclxuICAgKiBAcGFyYW0gY29uZmlnIC0gVGhlIGxvYWRlZCBjb25maWd1cmF0aW9uXHJcbiAgICogQHBhcmFtIG5hbWVzcGFjZSAtIFRoZSBuYW1lc3BhY2UgdG8gZXh0cmFjdFxyXG4gICAqIEByZXR1cm5zIENvbmZpZ3VyYXRpb24gdmFsdWVzIGZvciB0aGUgbmFtZXNwYWNlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBleHRyYWN0TmVzdGVkTmFtZXNwYWNlQ29uZmlnKGNvbmZpZzogUmVjb3JkPHN0cmluZywgYW55PiwgbmFtZXNwYWNlOiBzdHJpbmcpOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcclxuICAgIGNvbnN0IG5hbWVzcGFjZUNvbmZpZzogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xyXG4gICAgY29uc3QgbmFtZXNwYWNlUGF0aCA9IGAvJHtuYW1lc3BhY2V9L2A7XHJcblxyXG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoY29uZmlnKSkge1xyXG4gICAgICAvLyBDaGVjayBpZiBrZXkgY29udGFpbnMgbmFtZXNwYWNlIHBhdGhcclxuICAgICAgaWYgKGtleS5pbmNsdWRlcyhuYW1lc3BhY2VQYXRoKSkge1xyXG4gICAgICAgIC8vIEV4dHJhY3QgdGhlIHBhcnQgYWZ0ZXIgdGhlIG5hbWVzcGFjZSBwYXRoXHJcbiAgICAgICAgY29uc3QgcGF0aEluZGV4ID0ga2V5LmluZGV4T2YobmFtZXNwYWNlUGF0aCk7XHJcbiAgICAgICAgY29uc3QgYWZ0ZXJOYW1lc3BhY2UgPSBrZXkuc3Vic3RyaW5nKHBhdGhJbmRleCArIG5hbWVzcGFjZVBhdGgubGVuZ3RoKTtcclxuICAgICAgICBcclxuICAgICAgICBpZiAoYWZ0ZXJOYW1lc3BhY2UpIHtcclxuICAgICAgICAgIC8vIENvbnZlcnQgcGF0aCBzZWdtZW50cyB0byBuZXN0ZWQgb2JqZWN0IHN0cnVjdHVyZVxyXG4gICAgICAgICAgY29uc3QgbmVzdGVkS2V5ID0gdGhpcy5wYXRoVG9OZXN0ZWRLZXkoYWZ0ZXJOYW1lc3BhY2UpO1xyXG4gICAgICAgICAgdGhpcy5zZXROZXN0ZWRWYWx1ZShuYW1lc3BhY2VDb25maWcsIG5lc3RlZEtleSwgdmFsdWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBuYW1lc3BhY2VDb25maWc7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDb252ZXJ0IHNuYWtlX2Nhc2Ugb3Iga2ViYWItY2FzZSB0byBjYW1lbENhc2UuXHJcbiAgICogQHBhcmFtIHN0ciAtIFN0cmluZyB0byBjb252ZXJ0XHJcbiAgICogQHJldHVybnMgY2FtZWxDYXNlIHN0cmluZ1xyXG4gICAqL1xyXG4gIHByaXZhdGUgdG9DYW1lbENhc2Uoc3RyOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHN0clxyXG4gICAgICAudG9Mb3dlckNhc2UoKVxyXG4gICAgICAucmVwbGFjZSgvW18tXSguKS9nLCAoXywgY2hhcikgPT4gY2hhci50b1VwcGVyQ2FzZSgpKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENvbnZlcnQgcGF0aCBzZWdtZW50cyB0byBuZXN0ZWQga2V5IHN0cnVjdHVyZS5cclxuICAgKiBAcGFyYW0gcGF0aCAtIFBhdGggc3RyaW5nIChlLmcuLCBcImhvc3QvcG9ydFwiKVxyXG4gICAqIEByZXR1cm5zIE5lc3RlZCBrZXkgc3RydWN0dXJlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBwYXRoVG9OZXN0ZWRLZXkocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgIHJldHVybiBwYXRoXHJcbiAgICAgIC5zcGxpdCgnLycpXHJcbiAgICAgIC5tYXAoc2VnbWVudCA9PiB0aGlzLnRvQ2FtZWxDYXNlKHNlZ21lbnQpKVxyXG4gICAgICAuam9pbignLicpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2V0IGEgbmVzdGVkIHZhbHVlIGluIGFuIG9iamVjdCB1c2luZyBkb3Qgbm90YXRpb24uXHJcbiAgICogQHBhcmFtIG9iaiAtIFRhcmdldCBvYmplY3RcclxuICAgKiBAcGFyYW0gcGF0aCAtIERvdCBub3RhdGlvbiBwYXRoXHJcbiAgICogQHBhcmFtIHZhbHVlIC0gVmFsdWUgdG8gc2V0XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBzZXROZXN0ZWRWYWx1ZShvYmo6IFJlY29yZDxzdHJpbmcsIGFueT4sIHBhdGg6IHN0cmluZywgdmFsdWU6IGFueSk6IHZvaWQge1xyXG4gICAgY29uc3Qga2V5cyA9IHBhdGguc3BsaXQoJy4nKTtcclxuICAgIGxldCBjdXJyZW50ID0gb2JqO1xyXG5cclxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGggLSAxOyBpKyspIHtcclxuICAgICAgY29uc3Qga2V5ID0ga2V5c1tpXTtcclxuICAgICAgaWYgKGtleSAmJiAoIShrZXkgaW4gY3VycmVudCkgfHwgdHlwZW9mIGN1cnJlbnRba2V5XSAhPT0gJ29iamVjdCcpKSB7XHJcbiAgICAgICAgY3VycmVudFtrZXldID0ge307XHJcbiAgICAgIH1cclxuICAgICAgaWYgKGtleSkge1xyXG4gICAgICAgIGN1cnJlbnQgPSBjdXJyZW50W2tleV07XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBsYXN0S2V5ID0ga2V5c1trZXlzLmxlbmd0aCAtIDFdO1xyXG4gICAgaWYgKGxhc3RLZXkpIHtcclxuICAgICAgY3VycmVudFtsYXN0S2V5XSA9IHZhbHVlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHRoZSBTZWNyZXRzIE1hbmFnZXIgcGF0aCBiYXNlZCBvbiBjb25maWd1cmF0aW9uLlxyXG4gICAqIEByZXR1cm5zIFRoZSBzZWNyZXRzIG1hbmFnZXIgcGF0aFxyXG4gICAqL1xyXG4gIHByaXZhdGUgZ2V0U2VjcmV0c01hbmFnZXJQYXRoKCk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBwYXRocyA9IHRoaXMub3B0aW9ucy5zZWNyZXRzTWFuYWdlckNvbmZpZz8ucGF0aHM7XHJcbiAgICBpZiAoIXBhdGhzKSB7XHJcbiAgICAgIHJldHVybiAnL25lc3Rqcy1jb25maWctYXdzJztcclxuICAgIH1cclxuXHJcbiAgICAvLyBVc2UgdGhlIGZpcnN0IGF2YWlsYWJsZSBwYXRoIG9yIGRlZmF1bHRcclxuICAgIHJldHVybiBwYXRocy5wcm9kdWN0aW9uIHx8IHBhdGhzLmRldmVsb3BtZW50IHx8IHBhdGhzLnRlc3QgfHwgJy9uZXN0anMtY29uZmlnLWF3cyc7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgdGhlIFNTTSBQYXJhbWV0ZXIgU3RvcmUgcGF0aCBiYXNlZCBvbiBjb25maWd1cmF0aW9uLlxyXG4gICAqIEByZXR1cm5zIFRoZSBTU00gcGFyYW1ldGVyIHBhdGhcclxuICAgKi9cclxuICBwcml2YXRlIGdldFNTTVBhcmFtZXRlclBhdGgoKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IHBhdGhzID0gdGhpcy5vcHRpb25zLnNzbUNvbmZpZz8ucGF0aHM7XHJcbiAgICBpZiAoIXBhdGhzKSB7XHJcbiAgICAgIHJldHVybiAnL25lc3Rqcy1jb25maWctYXdzJztcclxuICAgIH1cclxuXHJcbiAgICAvLyBVc2UgdGhlIGZpcnN0IGF2YWlsYWJsZSBwYXRoIG9yIGRlZmF1bHRcclxuICAgIHJldHVybiBwYXRocy5wcm9kdWN0aW9uIHx8IHBhdGhzLmRldmVsb3BtZW50IHx8IHBhdGhzLnRlc3QgfHwgJy9uZXN0anMtY29uZmlnLWF3cyc7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDaGVjayBpZiBhbiBlcnJvciBpcyBhbiBBV1Mgc2VydmljZSBlcnJvci5cclxuICAgKiBAcGFyYW0gZXJyb3IgLSBUaGUgZXJyb3IgdG8gY2hlY2tcclxuICAgKiBAcmV0dXJucyBXaGV0aGVyIHRoZSBlcnJvciBpcyBmcm9tIGFuIEFXUyBzZXJ2aWNlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBpc0F3c1NlcnZpY2VFcnJvcihlcnJvcjogRXJyb3IpOiBib29sZWFuIHtcclxuICAgIC8vIEFXUyBTREsgZXJyb3JzIHR5cGljYWxseSBoYXZlIHNwZWNpZmljIG5hbWVzXHJcbiAgICBjb25zdCBhd3NFcnJvck5hbWVzID0gW1xyXG4gICAgICAnQWNjZXNzRGVuaWVkRXhjZXB0aW9uJyxcclxuICAgICAgJ1Jlc291cmNlTm90Rm91bmRFeGNlcHRpb24nLFxyXG4gICAgICAnSW52YWxpZFJlcXVlc3RFeGNlcHRpb24nLFxyXG4gICAgICAnVGhyb3R0bGluZ0V4Y2VwdGlvbicsXHJcbiAgICAgICdTZXJ2aWNlVW5hdmFpbGFibGVFeGNlcHRpb24nLFxyXG4gICAgICAnTmV0d29ya2luZ0Vycm9yJyxcclxuICAgICAgJ1RpbWVvdXRFcnJvcicsXHJcbiAgICAgICdDcmVkZW50aWFsc0Vycm9yJyxcclxuICAgICAgJ1Vua25vd25FbmRwb2ludCcsXHJcbiAgICBdO1xyXG5cclxuICAgIHJldHVybiBhd3NFcnJvck5hbWVzLmluY2x1ZGVzKGVycm9yLm5hbWUpIHx8IGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoJ0FXUycpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGFuZGxlIEFXUy1zcGVjaWZpYyBlcnJvcnMgd2l0aCBhcHByb3ByaWF0ZSBzdHJhdGVnaWVzLlxyXG4gICAqIEBwYXJhbSBsb2FkZXIgLSBUaGUgbG9hZGVyIHRoYXQgZW5jb3VudGVyZWQgdGhlIGVycm9yXHJcbiAgICogQHBhcmFtIGVycm9yIC0gVGhlIEFXUyBlcnJvclxyXG4gICAqIEByZXR1cm5zIFdoZXRoZXIgdG8gY29udGludWUgcHJvY2Vzc2luZ1xyXG4gICAqL1xyXG4gIHByaXZhdGUgaGFuZGxlQXdzU3BlY2lmaWNFcnJvcihsb2FkZXI6IENvbmZpZ0xvYWRlciwgZXJyb3I6IEVycm9yKTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBzZXJ2aWNlTmFtZSA9IHRoaXMuZ2V0U2VydmljZU5hbWUobG9hZGVyKTtcclxuXHJcbiAgICBzd2l0Y2ggKGVycm9yLm5hbWUpIHtcclxuICAgICAgY2FzZSAnQWNjZXNzRGVuaWVkRXhjZXB0aW9uJzpcclxuICAgICAgICByZXR1cm4gdGhpcy5lcnJvckhhbmRsZXIuaGFuZGxlUGVybWlzc2lvbkVycm9yKFxyXG4gICAgICAgICAgc2VydmljZU5hbWUsXHJcbiAgICAgICAgICB0aGlzLmdldFJlc291cmNlTmFtZShsb2FkZXIpLFxyXG4gICAgICAgICAgZXJyb3JcclxuICAgICAgICApO1xyXG5cclxuICAgICAgY2FzZSAnUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbic6XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZXJyb3JIYW5kbGVyLmhhbmRsZVJlc291cmNlTm90Rm91bmQoXHJcbiAgICAgICAgICBzZXJ2aWNlTmFtZSxcclxuICAgICAgICAgIHRoaXMuZ2V0UmVzb3VyY2VOYW1lKGxvYWRlciksXHJcbiAgICAgICAgICBlcnJvclxyXG4gICAgICAgICk7XHJcblxyXG4gICAgICBjYXNlICdOZXR3b3JraW5nRXJyb3InOlxyXG4gICAgICBjYXNlICdUaW1lb3V0RXJyb3InOlxyXG4gICAgICAgIGNvbnN0IG5ldHdvcmtSZXN1bHQgPSB0aGlzLmVycm9ySGFuZGxlci5oYW5kbGVOZXR3b3JrRXJyb3Ioc2VydmljZU5hbWUsIGVycm9yKTtcclxuICAgICAgICByZXR1cm4gbmV0d29ya1Jlc3VsdC5zaG91bGRDb250aW51ZTtcclxuXHJcbiAgICAgIGNhc2UgJ1Rocm90dGxpbmdFeGNlcHRpb24nOlxyXG4gICAgICBjYXNlICdUb29NYW55UmVxdWVzdHNFeGNlcHRpb24nOlxyXG4gICAgICAgIHRoaXMubG9nZ2VyLndhcm4oYFJhdGUgbGltaXRpbmcgZW5jb3VudGVyZWQgZm9yICR7c2VydmljZU5hbWV9LCBjb250aW51aW5nIHdpdGggb3RoZXIgc291cmNlc2ApO1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG5cclxuICAgICAgY2FzZSAnU2VydmljZVVuYXZhaWxhYmxlRXhjZXB0aW9uJzpcclxuICAgICAgICByZXR1cm4gdGhpcy5lcnJvckhhbmRsZXIuaGFuZGxlQXdzVW5hdmFpbGFibGUoc2VydmljZU5hbWUsIGVycm9yKTtcclxuXHJcbiAgICAgIGNhc2UgJ0NyZWRlbnRpYWxzRXJyb3InOlxyXG4gICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKGBBV1MgY3JlZGVudGlhbHMgZXJyb3IgZm9yICR7c2VydmljZU5hbWV9OiAke2Vycm9yLm1lc3NhZ2V9YCk7XHJcbiAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoJ1BsZWFzZSBjaGVjayBBV1MgY3JlZGVudGlhbHMgY29uZmlndXJhdGlvbicpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLmVycm9ySGFuZGxlci5oYW5kbGVBd3NVbmF2YWlsYWJsZShzZXJ2aWNlTmFtZSwgZXJyb3IpO1xyXG5cclxuICAgICAgZGVmYXVsdDpcclxuICAgICAgICAvLyBIYW5kbGUgYXMgZ2VuZXJhbCBjb25maWd1cmF0aW9uIGVycm9yXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZXJyb3JIYW5kbGVyLmhhbmRsZUNvbmZpZ3VyYXRpb25FcnJvcihzZXJ2aWNlTmFtZSwgZXJyb3IpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHRoZSBzZXJ2aWNlIG5hbWUgZm9yIGEgbG9hZGVyLlxyXG4gICAqIEBwYXJhbSBsb2FkZXIgLSBUaGUgY29uZmlndXJhdGlvbiBsb2FkZXJcclxuICAgKiBAcmV0dXJucyBUaGUgc2VydmljZSBuYW1lXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRTZXJ2aWNlTmFtZShsb2FkZXI6IENvbmZpZ0xvYWRlcik6IHN0cmluZyB7XHJcbiAgICBpZiAobG9hZGVyIGluc3RhbmNlb2YgU2VjcmV0c01hbmFnZXJMb2FkZXIpIHtcclxuICAgICAgcmV0dXJuICdBV1MgU2VjcmV0cyBNYW5hZ2VyJztcclxuICAgIH0gZWxzZSBpZiAobG9hZGVyIGluc3RhbmNlb2YgU1NNUGFyYW1ldGVyU3RvcmVMb2FkZXIpIHtcclxuICAgICAgcmV0dXJuICdBV1MgU3lzdGVtcyBNYW5hZ2VyIFBhcmFtZXRlciBTdG9yZSc7XHJcbiAgICB9IGVsc2UgaWYgKGxvYWRlciBpbnN0YW5jZW9mIEVudmlyb25tZW50TG9hZGVyKSB7XHJcbiAgICAgIHJldHVybiAnRW52aXJvbm1lbnQgVmFyaWFibGVzJztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiAnVW5rbm93biBTZXJ2aWNlJztcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCB0aGUgcmVzb3VyY2UgbmFtZSBmb3IgYSBsb2FkZXIuXHJcbiAgICogQHBhcmFtIGxvYWRlciAtIFRoZSBjb25maWd1cmF0aW9uIGxvYWRlclxyXG4gICAqIEByZXR1cm5zIFRoZSByZXNvdXJjZSBuYW1lXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRSZXNvdXJjZU5hbWUobG9hZGVyOiBDb25maWdMb2FkZXIpOiBzdHJpbmcge1xyXG4gICAgaWYgKGxvYWRlciBpbnN0YW5jZW9mIFNlY3JldHNNYW5hZ2VyTG9hZGVyKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmdldFNlY3JldHNNYW5hZ2VyUGF0aCgpO1xyXG4gICAgfSBlbHNlIGlmIChsb2FkZXIgaW5zdGFuY2VvZiBTU01QYXJhbWV0ZXJTdG9yZUxvYWRlcikge1xyXG4gICAgICByZXR1cm4gdGhpcy5nZXRTU01QYXJhbWV0ZXJQYXRoKCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gJ2NvbmZpZ3VyYXRpb24nO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9hZCBjb25maWd1cmF0aW9uIHdpdGggcmV0cnkgbG9naWMgZm9yIHJldHJ5YWJsZSBlcnJvcnMuXHJcbiAgICogQHBhcmFtIGxvYWRlciAtIFRoZSBjb25maWd1cmF0aW9uIGxvYWRlclxyXG4gICAqIEBwYXJhbSBtYXhSZXRyaWVzIC0gTWF4aW11bSBudW1iZXIgb2YgcmV0cmllc1xyXG4gICAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIGNvbmZpZ3VyYXRpb24gZGF0YVxyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgbG9hZFdpdGhSZXRyeShsb2FkZXI6IENvbmZpZ0xvYWRlciwgbWF4UmV0cmllczogbnVtYmVyID0gMyk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj4ge1xyXG4gICAgbGV0IGxhc3RFcnJvcjogRXJyb3IgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgICBmb3IgKGxldCBhdHRlbXB0ID0gMTsgYXR0ZW1wdCA8PSBtYXhSZXRyaWVzOyBhdHRlbXB0KyspIHtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICByZXR1cm4gYXdhaXQgbG9hZGVyLmxvYWQoKTtcclxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICBjb25zdCBsb2FkZXJFcnJvciA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKTtcclxuICAgICAgICBsYXN0RXJyb3IgPSBsb2FkZXJFcnJvcjtcclxuXHJcbiAgICAgICAgLy8gQ2hlY2sgaWYgZXJyb3IgaXMgcmV0cnlhYmxlXHJcbiAgICAgICAgaWYgKCF0aGlzLmVycm9ySGFuZGxlci5pc1JldHJ5YWJsZUVycm9yKGxvYWRlckVycm9yKSB8fCBhdHRlbXB0ID09PSBtYXhSZXRyaWVzKSB7XHJcbiAgICAgICAgICB0aHJvdyBsb2FkZXJFcnJvcjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFdhaXQgYmVmb3JlIHJldHJ5aW5nXHJcbiAgICAgICAgY29uc3QgZGVsYXkgPSB0aGlzLmVycm9ySGFuZGxlci5nZXRSZXRyeURlbGF5KGF0dGVtcHQpO1xyXG4gICAgICAgIHRoaXMubG9nZ2VyLndhcm4oYFJldHJ5aW5nICR7bG9hZGVyLmdldE5hbWUoKX0gaW4gJHtkZWxheX1tcyAoYXR0ZW1wdCAke2F0dGVtcHR9LyR7bWF4UmV0cmllc30pYCk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KHJlc29sdmUsIGRlbGF5KSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBUaGlzIHNob3VsZCBuZXZlciBiZSByZWFjaGVkLCBidXQganVzdCBpbiBjYXNlXHJcbiAgICB0aHJvdyBsYXN0RXJyb3IgfHwgbmV3IEVycm9yKCdVbmtub3duIGVycm9yIGR1cmluZyByZXRyeScpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2sgYXZhaWxhYmlsaXR5IHdpdGggdGltZW91dCBhbmQgZXJyb3IgaGFuZGxpbmcuXHJcbiAgICogQHBhcmFtIGxvYWRlciAtIFRoZSBjb25maWd1cmF0aW9uIGxvYWRlclxyXG4gICAqIEBwYXJhbSB0aW1lb3V0TXMgLSBUaW1lb3V0IGluIG1pbGxpc2Vjb25kc1xyXG4gICAqIEByZXR1cm5zIFByb21pc2UgcmVzb2x2aW5nIHRvIGF2YWlsYWJpbGl0eSBzdGF0dXNcclxuICAgKi9cclxuICBwcml2YXRlIGFzeW5jIGNoZWNrQXZhaWxhYmlsaXR5V2l0aFRpbWVvdXQobG9hZGVyOiBDb25maWdMb2FkZXIsIHRpbWVvdXRNczogbnVtYmVyID0gNTAwMCk6IFByb21pc2U8Ym9vbGVhbj4ge1xyXG4gICAgdHJ5IHtcclxuICAgICAgY29uc3QgdGltZW91dFByb21pc2UgPSBuZXcgUHJvbWlzZTxib29sZWFuPigoXywgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiByZWplY3QobmV3IEVycm9yKCdBdmFpbGFiaWxpdHkgY2hlY2sgdGltZW91dCcpKSwgdGltZW91dE1zKTtcclxuICAgICAgfSk7XHJcblxyXG4gICAgICBjb25zdCBhdmFpbGFiaWxpdHlQcm9taXNlID0gbG9hZGVyLmlzQXZhaWxhYmxlKCk7XHJcblxyXG4gICAgICByZXR1cm4gYXdhaXQgUHJvbWlzZS5yYWNlKFthdmFpbGFiaWxpdHlQcm9taXNlLCB0aW1lb3V0UHJvbWlzZV0pO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgY29uc3QgbG9hZGVyRXJyb3IgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoU3RyaW5nKGVycm9yKSk7XHJcbiAgICAgIFxyXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmVuYWJsZUxvZ2dpbmcpIHtcclxuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgQXZhaWxhYmlsaXR5IGNoZWNrIGZhaWxlZCBmb3IgJHtsb2FkZXIuZ2V0TmFtZSgpfTogJHtsb2FkZXJFcnJvci5tZXNzYWdlfWApO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG59Il19