@microsoft/terraform-cdk-constructs 1.2.0 → 1.3.1

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 (291) hide show
  1. package/.jsii +54630 -26185
  2. package/API.md +72091 -23784
  3. package/lib/azure-actiongroup/index.d.ts +0 -10
  4. package/lib/azure-actiongroup/index.js +1 -11
  5. package/lib/azure-actiongroup/lib/action-group.d.ts +0 -10
  6. package/lib/azure-actiongroup/lib/action-group.js +6 -32
  7. package/lib/azure-actiongroup/lib/index.d.ts +1 -4
  8. package/lib/azure-actiongroup/lib/index.js +2 -5
  9. package/lib/azure-activitylogalert/index.d.ts +0 -10
  10. package/lib/azure-activitylogalert/index.js +1 -11
  11. package/lib/azure-activitylogalert/lib/activity-log-alert.d.ts +0 -10
  12. package/lib/azure-activitylogalert/lib/activity-log-alert.js +6 -32
  13. package/lib/azure-activitylogalert/lib/index.d.ts +1 -4
  14. package/lib/azure-activitylogalert/lib/index.js +2 -5
  15. package/lib/azure-aks/index.d.ts +0 -8
  16. package/lib/azure-aks/index.js +1 -11
  17. package/lib/azure-aks/lib/aks-cluster.d.ts +4 -13
  18. package/lib/azure-aks/lib/aks-cluster.js +13 -36
  19. package/lib/azure-aks/lib/index.d.ts +1 -10
  20. package/lib/azure-aks/lib/index.js +2 -21
  21. package/lib/azure-diagnosticsettings/index.d.ts +0 -6
  22. package/lib/azure-diagnosticsettings/index.js +1 -7
  23. package/lib/azure-diagnosticsettings/lib/diagnostic-settings.d.ts +0 -10
  24. package/lib/azure-diagnosticsettings/lib/diagnostic-settings.js +6 -32
  25. package/lib/azure-diagnosticsettings/lib/index.d.ts +1 -7
  26. package/lib/azure-diagnosticsettings/lib/index.js +2 -8
  27. package/lib/azure-dnsforwardingruleset/index.d.ts +1 -0
  28. package/lib/azure-dnsforwardingruleset/index.js +18 -0
  29. package/lib/azure-dnsforwardingruleset/lib/dns-forwarding-ruleset-schemas.d.ts +24 -0
  30. package/lib/azure-dnsforwardingruleset/lib/dns-forwarding-ruleset-schemas.js +206 -0
  31. package/lib/azure-dnsforwardingruleset/lib/dns-forwarding-ruleset.d.ts +174 -0
  32. package/lib/azure-dnsforwardingruleset/lib/dns-forwarding-ruleset.js +214 -0
  33. package/lib/azure-dnsforwardingruleset/lib/forwarding-rule-schemas.d.ts +24 -0
  34. package/lib/azure-dnsforwardingruleset/lib/forwarding-rule-schemas.js +242 -0
  35. package/lib/azure-dnsforwardingruleset/lib/forwarding-rule.d.ts +193 -0
  36. package/lib/azure-dnsforwardingruleset/lib/forwarding-rule.js +193 -0
  37. package/lib/azure-dnsforwardingruleset/lib/index.d.ts +6 -0
  38. package/lib/azure-dnsforwardingruleset/lib/index.js +23 -0
  39. package/lib/azure-dnsforwardingruleset/lib/virtual-network-link-schemas.d.ts +24 -0
  40. package/lib/azure-dnsforwardingruleset/lib/virtual-network-link-schemas.js +199 -0
  41. package/lib/azure-dnsforwardingruleset/lib/virtual-network-link.d.ts +160 -0
  42. package/lib/azure-dnsforwardingruleset/lib/virtual-network-link.js +178 -0
  43. package/lib/azure-dnsforwardingruleset/test/dns-forwarding-ruleset.integ.d.ts +9 -0
  44. package/lib/azure-dnsforwardingruleset/test/dns-forwarding-ruleset.integ.js +133 -0
  45. package/lib/azure-dnsforwardingruleset/test/dns-forwarding-ruleset.spec.d.ts +9 -0
  46. package/lib/azure-dnsforwardingruleset/test/dns-forwarding-ruleset.spec.js +350 -0
  47. package/lib/azure-dnsforwardingruleset/test/forwarding-rule.spec.d.ts +9 -0
  48. package/lib/azure-dnsforwardingruleset/test/forwarding-rule.spec.js +397 -0
  49. package/lib/azure-dnsforwardingruleset/test/virtual-network-link.spec.d.ts +9 -0
  50. package/lib/azure-dnsforwardingruleset/test/virtual-network-link.spec.js +285 -0
  51. package/lib/azure-dnsresolver/index.d.ts +1 -0
  52. package/lib/azure-dnsresolver/index.js +18 -0
  53. package/lib/azure-dnsresolver/lib/dns-resolver-schemas.d.ts +24 -0
  54. package/lib/azure-dnsresolver/lib/dns-resolver-schemas.js +218 -0
  55. package/lib/azure-dnsresolver/lib/dns-resolver.d.ts +170 -0
  56. package/lib/azure-dnsresolver/lib/dns-resolver.js +236 -0
  57. package/lib/azure-dnsresolver/lib/inbound-endpoint-schemas.d.ts +24 -0
  58. package/lib/azure-dnsresolver/lib/inbound-endpoint-schemas.js +261 -0
  59. package/lib/azure-dnsresolver/lib/inbound-endpoint.d.ts +189 -0
  60. package/lib/azure-dnsresolver/lib/inbound-endpoint.js +243 -0
  61. package/lib/azure-dnsresolver/lib/index.d.ts +6 -0
  62. package/lib/azure-dnsresolver/lib/index.js +23 -0
  63. package/lib/azure-dnsresolver/lib/outbound-endpoint-schemas.d.ts +24 -0
  64. package/lib/azure-dnsresolver/lib/outbound-endpoint-schemas.js +231 -0
  65. package/lib/azure-dnsresolver/lib/outbound-endpoint.d.ts +175 -0
  66. package/lib/azure-dnsresolver/lib/outbound-endpoint.js +234 -0
  67. package/lib/azure-dnsresolver/test/dns-resolver.integ.d.ts +14 -0
  68. package/lib/azure-dnsresolver/test/dns-resolver.integ.js +117 -0
  69. package/lib/azure-dnsresolver/test/dns-resolver.spec.d.ts +9 -0
  70. package/lib/azure-dnsresolver/test/dns-resolver.spec.js +353 -0
  71. package/lib/azure-dnsresolver/test/inbound-endpoint.integ.d.ts +9 -0
  72. package/lib/azure-dnsresolver/test/inbound-endpoint.integ.js +151 -0
  73. package/lib/azure-dnsresolver/test/inbound-endpoint.spec.d.ts +9 -0
  74. package/lib/azure-dnsresolver/test/inbound-endpoint.spec.js +441 -0
  75. package/lib/azure-dnsresolver/test/outbound-endpoint.integ.d.ts +9 -0
  76. package/lib/azure-dnsresolver/test/outbound-endpoint.integ.js +149 -0
  77. package/lib/azure-dnsresolver/test/outbound-endpoint.spec.d.ts +9 -0
  78. package/lib/azure-dnsresolver/test/outbound-endpoint.spec.js +301 -0
  79. package/lib/azure-dnszone/index.d.ts +1 -0
  80. package/lib/azure-dnszone/index.js +18 -0
  81. package/lib/azure-dnszone/lib/dns-zone-schemas.d.ts +24 -0
  82. package/lib/azure-dnszone/lib/dns-zone-schemas.js +191 -0
  83. package/lib/azure-dnszone/lib/dns-zone.d.ts +182 -0
  84. package/lib/azure-dnszone/lib/dns-zone.js +228 -0
  85. package/lib/azure-dnszone/lib/index.d.ts +2 -0
  86. package/lib/azure-dnszone/lib/index.js +19 -0
  87. package/lib/azure-dnszone/test/dns-zone.integ.d.ts +9 -0
  88. package/lib/azure-dnszone/test/dns-zone.integ.js +85 -0
  89. package/lib/azure-dnszone/test/dns-zone.spec.d.ts +9 -0
  90. package/lib/azure-dnszone/test/dns-zone.spec.js +285 -0
  91. package/lib/azure-metricalert/index.d.ts +0 -10
  92. package/lib/azure-metricalert/index.js +1 -11
  93. package/lib/azure-metricalert/lib/index.d.ts +1 -4
  94. package/lib/azure-metricalert/lib/index.js +2 -5
  95. package/lib/azure-metricalert/lib/metric-alert.d.ts +0 -10
  96. package/lib/azure-metricalert/lib/metric-alert.js +6 -32
  97. package/lib/azure-networkinterface/index.d.ts +0 -3
  98. package/lib/azure-networkinterface/index.js +1 -4
  99. package/lib/azure-networkinterface/lib/index.d.ts +1 -5
  100. package/lib/azure-networkinterface/lib/index.js +2 -5
  101. package/lib/azure-networkinterface/lib/network-interface.d.ts +4 -9
  102. package/lib/azure-networkinterface/lib/network-interface.js +14 -29
  103. package/lib/azure-networkinterface/test/network-interface.integ.js +20 -6
  104. package/lib/azure-networksecuritygroup/index.d.ts +0 -5
  105. package/lib/azure-networksecuritygroup/index.js +1 -6
  106. package/lib/azure-networksecuritygroup/lib/index.d.ts +2 -5
  107. package/lib/azure-networksecuritygroup/lib/index.js +17 -14
  108. package/lib/azure-networksecuritygroup/lib/network-security-group.d.ts +4 -13
  109. package/lib/azure-networksecuritygroup/lib/network-security-group.js +14 -36
  110. package/lib/azure-policyassignment/index.d.ts +1 -0
  111. package/lib/azure-policyassignment/index.js +18 -0
  112. package/lib/azure-policyassignment/lib/index.d.ts +2 -0
  113. package/lib/azure-policyassignment/lib/index.js +19 -0
  114. package/lib/azure-policyassignment/lib/policy-assignment-schemas.d.ts +25 -0
  115. package/lib/azure-policyassignment/lib/policy-assignment-schemas.js +260 -0
  116. package/lib/azure-policyassignment/lib/policy-assignment.d.ts +349 -0
  117. package/lib/azure-policyassignment/lib/policy-assignment.js +237 -0
  118. package/lib/azure-policyassignment/test/policy-assignment.integ.d.ts +13 -0
  119. package/lib/azure-policyassignment/test/policy-assignment.integ.js +153 -0
  120. package/lib/azure-policyassignment/test/policy-assignment.spec.d.ts +9 -0
  121. package/lib/azure-policyassignment/test/policy-assignment.spec.js +651 -0
  122. package/lib/azure-policydefinition/index.d.ts +1 -0
  123. package/lib/azure-policydefinition/index.js +18 -0
  124. package/lib/azure-policydefinition/lib/index.d.ts +2 -0
  125. package/lib/azure-policydefinition/lib/index.js +19 -0
  126. package/lib/azure-policydefinition/lib/policy-definition-schemas.d.ts +25 -0
  127. package/lib/azure-policydefinition/lib/policy-definition-schemas.js +210 -0
  128. package/lib/azure-policydefinition/lib/policy-definition.d.ts +281 -0
  129. package/lib/azure-policydefinition/lib/policy-definition.js +236 -0
  130. package/lib/azure-policydefinition/test/policy-definition.integ.d.ts +9 -0
  131. package/lib/azure-policydefinition/test/policy-definition.integ.js +137 -0
  132. package/lib/azure-policydefinition/test/policy-definition.spec.d.ts +9 -0
  133. package/lib/azure-policydefinition/test/policy-definition.spec.js +806 -0
  134. package/lib/azure-privatednszone/index.d.ts +1 -0
  135. package/lib/azure-privatednszone/index.js +18 -0
  136. package/lib/azure-privatednszone/lib/index.d.ts +2 -0
  137. package/lib/azure-privatednszone/lib/index.js +19 -0
  138. package/lib/azure-privatednszone/lib/private-dns-zone-schemas.d.ts +24 -0
  139. package/lib/azure-privatednszone/lib/private-dns-zone-schemas.js +254 -0
  140. package/lib/azure-privatednszone/lib/private-dns-zone.d.ts +178 -0
  141. package/lib/azure-privatednszone/lib/private-dns-zone.js +272 -0
  142. package/lib/azure-privatednszone/test/private-dns-zone.integ.d.ts +9 -0
  143. package/lib/azure-privatednszone/test/private-dns-zone.integ.js +84 -0
  144. package/lib/azure-privatednszone/test/private-dns-zone.spec.d.ts +9 -0
  145. package/lib/azure-privatednszone/test/private-dns-zone.spec.js +341 -0
  146. package/lib/azure-privatednszonelink/index.d.ts +1 -0
  147. package/lib/azure-privatednszonelink/index.js +18 -0
  148. package/lib/azure-privatednszonelink/lib/index.d.ts +2 -0
  149. package/lib/azure-privatednszonelink/lib/index.js +19 -0
  150. package/lib/azure-privatednszonelink/lib/private-dns-zone-link-schemas.d.ts +24 -0
  151. package/lib/azure-privatednszonelink/lib/private-dns-zone-link-schemas.js +262 -0
  152. package/lib/azure-privatednszonelink/lib/private-dns-zone-link.d.ts +202 -0
  153. package/lib/azure-privatednszonelink/lib/private-dns-zone-link.js +250 -0
  154. package/lib/azure-privatednszonelink/test/private-dns-zone-link.integ.d.ts +9 -0
  155. package/lib/azure-privatednszonelink/test/private-dns-zone-link.integ.js +110 -0
  156. package/lib/azure-privatednszonelink/test/private-dns-zone-link.spec.d.ts +9 -0
  157. package/lib/azure-privatednszonelink/test/private-dns-zone-link.spec.js +465 -0
  158. package/lib/azure-publicipaddress/index.d.ts +0 -5
  159. package/lib/azure-publicipaddress/index.js +1 -6
  160. package/lib/azure-publicipaddress/lib/index.d.ts +2 -9
  161. package/lib/azure-publicipaddress/lib/index.js +17 -17
  162. package/lib/azure-publicipaddress/lib/public-ip-address.d.ts +4 -13
  163. package/lib/azure-publicipaddress/lib/public-ip-address.js +14 -36
  164. package/lib/azure-resourcegroup/index.d.ts +0 -37
  165. package/lib/azure-resourcegroup/index.js +1 -39
  166. package/lib/azure-resourcegroup/lib/index.d.ts +1 -44
  167. package/lib/azure-resourcegroup/lib/index.js +2 -43
  168. package/lib/azure-resourcegroup/lib/resource-group.d.ts +9 -23
  169. package/lib/azure-resourcegroup/lib/resource-group.js +23 -56
  170. package/lib/azure-resourcegroup/test/resource-group.spec.js +13 -19
  171. package/lib/azure-roleassignment/index.d.ts +1 -0
  172. package/lib/azure-roleassignment/index.js +18 -0
  173. package/lib/azure-roleassignment/lib/index.d.ts +2 -0
  174. package/lib/azure-roleassignment/lib/index.js +19 -0
  175. package/lib/azure-roleassignment/lib/role-assignment-schemas.d.ts +25 -0
  176. package/lib/azure-roleassignment/lib/role-assignment-schemas.js +238 -0
  177. package/lib/azure-roleassignment/lib/role-assignment.d.ts +294 -0
  178. package/lib/azure-roleassignment/lib/role-assignment.js +257 -0
  179. package/lib/azure-roleassignment/test/role-assignment.integ.d.ts +12 -0
  180. package/lib/azure-roleassignment/test/role-assignment.integ.js +101 -0
  181. package/lib/azure-roleassignment/test/role-assignment.spec.d.ts +9 -0
  182. package/lib/azure-roleassignment/test/role-assignment.spec.js +633 -0
  183. package/lib/azure-roledefinition/index.d.ts +1 -0
  184. package/lib/azure-roledefinition/index.js +18 -0
  185. package/lib/azure-roledefinition/lib/index.d.ts +2 -0
  186. package/lib/azure-roledefinition/lib/index.js +19 -0
  187. package/lib/azure-roledefinition/lib/role-definition-schemas.d.ts +25 -0
  188. package/lib/azure-roledefinition/lib/role-definition-schemas.js +195 -0
  189. package/lib/azure-roledefinition/lib/role-definition.d.ts +236 -0
  190. package/lib/azure-roledefinition/lib/role-definition.js +192 -0
  191. package/lib/azure-roledefinition/test/role-definition.integ.d.ts +12 -0
  192. package/lib/azure-roledefinition/test/role-definition.integ.js +142 -0
  193. package/lib/azure-roledefinition/test/role-definition.spec.d.ts +9 -0
  194. package/lib/azure-roledefinition/test/role-definition.spec.js +946 -0
  195. package/lib/azure-storageaccount/index.d.ts +0 -19
  196. package/lib/azure-storageaccount/index.js +1 -20
  197. package/lib/azure-storageaccount/lib/index.d.ts +1 -7
  198. package/lib/azure-storageaccount/lib/index.js +2 -8
  199. package/lib/azure-storageaccount/lib/storage-account.d.ts +4 -9
  200. package/lib/azure-storageaccount/lib/storage-account.js +15 -29
  201. package/lib/azure-subnet/index.d.ts +0 -3
  202. package/lib/azure-subnet/index.js +1 -4
  203. package/lib/azure-subnet/lib/index.d.ts +1 -4
  204. package/lib/azure-subnet/lib/index.js +2 -5
  205. package/lib/azure-subnet/lib/subnet.d.ts +3 -14
  206. package/lib/azure-subnet/lib/subnet.js +28 -47
  207. package/lib/azure-subnet/test/subnet.integ.js +19 -7
  208. package/lib/azure-subnet/test/subnet.spec.js +1 -2
  209. package/lib/azure-virtualmachine/index.d.ts +0 -6
  210. package/lib/azure-virtualmachine/index.js +1 -7
  211. package/lib/azure-virtualmachine/lib/index.d.ts +1 -10
  212. package/lib/azure-virtualmachine/lib/index.js +2 -21
  213. package/lib/azure-virtualmachine/lib/virtual-machine.d.ts +4 -13
  214. package/lib/azure-virtualmachine/lib/virtual-machine.js +15 -36
  215. package/lib/azure-virtualnetwork/index.d.ts +0 -9
  216. package/lib/azure-virtualnetwork/index.js +1 -11
  217. package/lib/azure-virtualnetwork/lib/index.d.ts +2 -9
  218. package/lib/azure-virtualnetwork/lib/index.js +17 -20
  219. package/lib/azure-virtualnetwork/lib/virtual-network.d.ts +4 -13
  220. package/lib/azure-virtualnetwork/lib/virtual-network.js +15 -36
  221. package/lib/azure-virtualnetworkmanager/index.d.ts +1 -0
  222. package/lib/azure-virtualnetworkmanager/index.js +18 -0
  223. package/lib/azure-virtualnetworkmanager/lib/connectivity-configuration-schemas.d.ts +48 -0
  224. package/lib/azure-virtualnetworkmanager/lib/connectivity-configuration-schemas.js +265 -0
  225. package/lib/azure-virtualnetworkmanager/lib/connectivity-configuration.d.ts +185 -0
  226. package/lib/azure-virtualnetworkmanager/lib/connectivity-configuration.js +206 -0
  227. package/lib/azure-virtualnetworkmanager/lib/index.d.ts +14 -0
  228. package/lib/azure-virtualnetworkmanager/lib/index.js +31 -0
  229. package/lib/azure-virtualnetworkmanager/lib/network-group-schemas.d.ts +32 -0
  230. package/lib/azure-virtualnetworkmanager/lib/network-group-schemas.js +189 -0
  231. package/lib/azure-virtualnetworkmanager/lib/network-group-static-member-schemas.d.ts +32 -0
  232. package/lib/azure-virtualnetworkmanager/lib/network-group-static-member-schemas.js +201 -0
  233. package/lib/azure-virtualnetworkmanager/lib/network-group-static-member.d.ts +135 -0
  234. package/lib/azure-virtualnetworkmanager/lib/network-group-static-member.js +163 -0
  235. package/lib/azure-virtualnetworkmanager/lib/network-group.d.ts +139 -0
  236. package/lib/azure-virtualnetworkmanager/lib/network-group.js +158 -0
  237. package/lib/azure-virtualnetworkmanager/lib/security-admin-configuration-schemas.d.ts +32 -0
  238. package/lib/azure-virtualnetworkmanager/lib/security-admin-configuration-schemas.js +182 -0
  239. package/lib/azure-virtualnetworkmanager/lib/security-admin-configuration.d.ts +144 -0
  240. package/lib/azure-virtualnetworkmanager/lib/security-admin-configuration.js +164 -0
  241. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-collection-schemas.d.ts +38 -0
  242. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-collection-schemas.js +206 -0
  243. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-collection.d.ts +142 -0
  244. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-collection.js +162 -0
  245. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-schemas.d.ts +39 -0
  246. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-schemas.js +359 -0
  247. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule.d.ts +221 -0
  248. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule.js +204 -0
  249. package/lib/azure-virtualnetworkmanager/lib/virtual-network-manager-schemas.d.ts +32 -0
  250. package/lib/azure-virtualnetworkmanager/lib/virtual-network-manager-schemas.js +236 -0
  251. package/lib/azure-virtualnetworkmanager/lib/virtual-network-manager.d.ts +337 -0
  252. package/lib/azure-virtualnetworkmanager/lib/virtual-network-manager.js +283 -0
  253. package/lib/azure-virtualnetworkmanager/test/virtual-network-manager.integ.d.ts +25 -0
  254. package/lib/azure-virtualnetworkmanager/test/virtual-network-manager.integ.js +402 -0
  255. package/lib/azure-virtualnetworkmanager/test/virtual-network-manager.spec.d.ts +9 -0
  256. package/lib/azure-virtualnetworkmanager/test/virtual-network-manager.spec.js +1652 -0
  257. package/lib/azure-vmss/index.d.ts +0 -5
  258. package/lib/azure-vmss/index.js +1 -6
  259. package/lib/azure-vmss/lib/index.d.ts +0 -7
  260. package/lib/azure-vmss/lib/index.js +1 -21
  261. package/lib/azure-vmss/lib/virtual-machine-scale-set.d.ts +5 -13
  262. package/lib/azure-vmss/lib/virtual-machine-scale-set.js +29 -53
  263. package/lib/core-azure/lib/azapi/azapi-resource-tags.spec.d.ts +10 -0
  264. package/lib/core-azure/lib/azapi/azapi-resource-tags.spec.js +218 -0
  265. package/lib/core-azure/lib/azapi/azapi-resource.d.ts +206 -26
  266. package/lib/core-azure/lib/azapi/azapi-resource.js +379 -91
  267. package/lib/core-azure/lib/azapi/azapi-resource.spec.js +2 -2
  268. package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-client-config/index.js +2 -2
  269. package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-resource/index.js +5 -5
  270. package/lib/core-azure/lib/azapi/providers-azapi/provider/index.js +5 -3
  271. package/lib/core-azure/lib/azapi/providers-azapi/resource/index.js +5 -5
  272. package/lib/core-azure/lib/azapi/providers-azapi/resource-action/index.js +3 -3
  273. package/lib/core-azure/lib/azapi/providers-azapi/update-resource/index.js +3 -3
  274. package/lib/core-azure/lib/azapi/resource-schema-validator.d.ts +118 -0
  275. package/lib/core-azure/lib/azapi/resource-schema-validator.js +236 -0
  276. package/lib/core-azure/lib/azapi/resource-version-manager.d.ts +103 -0
  277. package/lib/core-azure/lib/azapi/resource-version-manager.js +168 -0
  278. package/lib/core-azure/lib/azapi/schema-mapper/schema-mapper.js +11 -6
  279. package/lib/core-azure/lib/index.d.ts +2 -2
  280. package/lib/core-azure/lib/index.js +5 -5
  281. package/lib/core-azure/lib/version-manager/api-version-manager.js +1 -1
  282. package/lib/core-azure/lib/version-manager/interfaces/version-interfaces.js +7 -7
  283. package/lib/index.d.ts +19 -0
  284. package/lib/index.js +21 -2
  285. package/lib/testing/index.js +2 -2
  286. package/lib/testing/lib/cleanup.d.ts +1 -0
  287. package/lib/testing/lib/cleanup.js +19 -12
  288. package/lib/testing/lib/metadata.js +19 -16
  289. package/package.json +1 -1
  290. package/scripts/cleanup-test-resources.ts +22 -4
  291. package/scripts/generate-index.js +25 -8
@@ -0,0 +1,1652 @@
1
+ "use strict";
2
+ /**
3
+ * Comprehensive tests for the Virtual Network Manager implementation
4
+ *
5
+ * This test suite validates the VirtualNetworkManager class and all child resource
6
+ * constructs using the AzapiResource framework. Tests cover automatic version resolution,
7
+ * explicit version pinning, schema validation, property transformation, resource creation,
8
+ * and parent-child relationships.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ const cdktf_1 = require("cdktf");
12
+ const cdktf = require("cdktf");
13
+ const connectivity_configuration_1 = require("../lib/connectivity-configuration");
14
+ const network_group_1 = require("../lib/network-group");
15
+ const network_group_static_member_1 = require("../lib/network-group-static-member");
16
+ const security_admin_configuration_1 = require("../lib/security-admin-configuration");
17
+ const security_admin_rule_1 = require("../lib/security-admin-rule");
18
+ const security_admin_rule_collection_1 = require("../lib/security-admin-rule-collection");
19
+ const virtual_network_manager_1 = require("../lib/virtual-network-manager");
20
+ describe("VirtualNetworkManager", () => {
21
+ let app;
22
+ let stack;
23
+ beforeEach(() => {
24
+ app = cdktf_1.Testing.app();
25
+ stack = new cdktf.TerraformStack(app, "test-stack");
26
+ });
27
+ describe("Basic Instantiation Tests", () => {
28
+ it("should create a Virtual Network Manager with minimum required properties", () => {
29
+ const props = {
30
+ name: "test-network-manager",
31
+ location: "eastus",
32
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
33
+ networkManagerScopes: {
34
+ subscriptions: [
35
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
36
+ ],
37
+ },
38
+ networkManagerScopeAccesses: ["Connectivity", "SecurityAdmin"],
39
+ };
40
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
41
+ expect(manager).toBeInstanceOf(virtual_network_manager_1.VirtualNetworkManager);
42
+ expect(manager.props).toBe(props);
43
+ expect(manager.resourceName).toBeDefined();
44
+ const synthesized = cdktf_1.Testing.synth(stack);
45
+ expect(synthesized).toContain("Microsoft.Network/networkManagers");
46
+ });
47
+ it("should create a Virtual Network Manager with all properties", () => {
48
+ const props = {
49
+ name: "test-network-manager-full",
50
+ location: "westus",
51
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
52
+ networkManagerScopes: {
53
+ subscriptions: [
54
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
55
+ ],
56
+ managementGroups: [
57
+ "/providers/Microsoft.Management/managementGroups/mg1",
58
+ ],
59
+ },
60
+ networkManagerScopeAccesses: ["Connectivity", "SecurityAdmin"],
61
+ description: "Test network manager with all properties",
62
+ tags: {
63
+ environment: "test",
64
+ project: "cdktf-constructs",
65
+ },
66
+ };
67
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
68
+ expect(manager.props).toBe(props);
69
+ expect(manager.props.description).toBe("Test network manager with all properties");
70
+ expect(manager.props.tags).toEqual({
71
+ environment: "test",
72
+ project: "cdktf-constructs",
73
+ });
74
+ expect(manager.tags).toEqual(props.tags);
75
+ });
76
+ });
77
+ describe("Framework Integration Tests", () => {
78
+ it("should use default API version when none specified", () => {
79
+ const props = {
80
+ name: "test-network-manager",
81
+ location: "eastus",
82
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
83
+ networkManagerScopes: {
84
+ subscriptions: [
85
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
86
+ ],
87
+ },
88
+ networkManagerScopeAccesses: ["Connectivity"],
89
+ };
90
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
91
+ expect(manager.resolvedApiVersion).toBe("2024-05-01");
92
+ });
93
+ it("should use specified API version when provided", () => {
94
+ const props = {
95
+ name: "test-network-manager",
96
+ location: "eastus",
97
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
98
+ apiVersion: "2023-11-01",
99
+ networkManagerScopes: {
100
+ subscriptions: [
101
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
102
+ ],
103
+ },
104
+ networkManagerScopeAccesses: ["SecurityAdmin"],
105
+ };
106
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
107
+ expect(manager.resolvedApiVersion).toBe("2023-11-01");
108
+ const synthesized = cdktf_1.Testing.synth(stack);
109
+ expect(synthesized).toContain("@2023-11-01");
110
+ });
111
+ it("should register schemas on first instantiation", () => {
112
+ const props = {
113
+ name: "test-network-manager",
114
+ location: "eastus",
115
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
116
+ networkManagerScopes: {
117
+ subscriptions: [
118
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
119
+ ],
120
+ },
121
+ networkManagerScopeAccesses: ["Connectivity"],
122
+ };
123
+ // First instantiation should register schemas
124
+ const manager1 = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager1", props);
125
+ expect(manager1).toBeInstanceOf(virtual_network_manager_1.VirtualNetworkManager);
126
+ // Second instantiation should not re-register
127
+ const manager2 = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager2", {
128
+ ...props,
129
+ name: "test-network-manager-2",
130
+ });
131
+ expect(manager2).toBeInstanceOf(virtual_network_manager_1.VirtualNetworkManager);
132
+ });
133
+ });
134
+ describe("Property Validation Tests", () => {
135
+ it("should properly format networkManagerScopes with subscriptions", () => {
136
+ const props = {
137
+ name: "test-network-manager",
138
+ location: "eastus",
139
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
140
+ networkManagerScopes: {
141
+ subscriptions: [
142
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
143
+ "/subscriptions/11111111-1111-1111-1111-111111111111",
144
+ ],
145
+ },
146
+ networkManagerScopeAccesses: ["Connectivity"],
147
+ };
148
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
149
+ expect(manager.props.networkManagerScopes.subscriptions).toHaveLength(2);
150
+ expect(manager.props.networkManagerScopes.subscriptions).toContain("/subscriptions/00000000-0000-0000-0000-000000000000");
151
+ const synthesized = cdktf_1.Testing.synth(stack);
152
+ const stackConfig = JSON.parse(synthesized);
153
+ expect(stackConfig.resource).toBeDefined();
154
+ });
155
+ it("should properly format networkManagerScopes with management groups", () => {
156
+ const props = {
157
+ name: "test-network-manager",
158
+ location: "eastus",
159
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
160
+ networkManagerScopes: {
161
+ managementGroups: [
162
+ "/providers/Microsoft.Management/managementGroups/mg1",
163
+ "/providers/Microsoft.Management/managementGroups/mg2",
164
+ ],
165
+ },
166
+ networkManagerScopeAccesses: ["SecurityAdmin"],
167
+ };
168
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
169
+ expect(manager.props.networkManagerScopes.managementGroups).toHaveLength(2);
170
+ expect(manager.props.networkManagerScopes.managementGroups).toContain("/providers/Microsoft.Management/managementGroups/mg1");
171
+ const synthesized = cdktf_1.Testing.synth(stack);
172
+ const stackConfig = JSON.parse(synthesized);
173
+ expect(stackConfig.resource).toBeDefined();
174
+ });
175
+ it("should properly format networkManagerScopeAccesses with Connectivity and SecurityAdmin", () => {
176
+ const props = {
177
+ name: "test-network-manager",
178
+ location: "eastus",
179
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
180
+ networkManagerScopes: {
181
+ subscriptions: [
182
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
183
+ ],
184
+ },
185
+ networkManagerScopeAccesses: ["Connectivity", "SecurityAdmin"],
186
+ };
187
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
188
+ expect(manager.props.networkManagerScopeAccesses).toHaveLength(2);
189
+ expect(manager.props.networkManagerScopeAccesses).toContain("Connectivity");
190
+ expect(manager.props.networkManagerScopeAccesses).toContain("SecurityAdmin");
191
+ });
192
+ it("should properly format networkManagerScopeAccesses with Routing", () => {
193
+ const props = {
194
+ name: "test-network-manager",
195
+ location: "eastus",
196
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
197
+ networkManagerScopes: {
198
+ subscriptions: [
199
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
200
+ ],
201
+ },
202
+ networkManagerScopeAccesses: ["Routing"],
203
+ };
204
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
205
+ expect(manager.props.networkManagerScopeAccesses).toHaveLength(1);
206
+ expect(manager.props.networkManagerScopeAccesses).toContain("Routing");
207
+ });
208
+ });
209
+ describe("Tag Management Tests", () => {
210
+ it("should add tags using addTag method", () => {
211
+ const props = {
212
+ name: "test-network-manager",
213
+ location: "eastus",
214
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
215
+ networkManagerScopes: {
216
+ subscriptions: [
217
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
218
+ ],
219
+ },
220
+ networkManagerScopeAccesses: ["Connectivity"],
221
+ tags: {
222
+ environment: "test",
223
+ },
224
+ };
225
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
226
+ manager.addTag("project", "network-infrastructure");
227
+ expect(manager.props.tags.project).toBe("network-infrastructure");
228
+ expect(manager.props.tags.environment).toBe("test");
229
+ const synthesized = cdktf_1.Testing.synth(stack);
230
+ expect(synthesized).toContain("network-infrastructure");
231
+ });
232
+ it("should remove tags using removeTag method", () => {
233
+ const props = {
234
+ name: "test-network-manager",
235
+ location: "eastus",
236
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
237
+ networkManagerScopes: {
238
+ subscriptions: [
239
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
240
+ ],
241
+ },
242
+ networkManagerScopeAccesses: ["Connectivity"],
243
+ tags: {
244
+ environment: "test",
245
+ temporary: "true",
246
+ },
247
+ };
248
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
249
+ manager.removeTag("temporary");
250
+ expect(manager.props.tags.temporary).toBeUndefined();
251
+ expect(manager.props.tags.environment).toBe("test");
252
+ });
253
+ it("should add tags when no initial tags exist", () => {
254
+ const props = {
255
+ name: "test-network-manager",
256
+ location: "eastus",
257
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
258
+ networkManagerScopes: {
259
+ subscriptions: [
260
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
261
+ ],
262
+ },
263
+ networkManagerScopeAccesses: ["Connectivity"],
264
+ };
265
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
266
+ manager.addTag("firstTag", "firstValue");
267
+ expect(manager.props.tags.firstTag).toBe("firstValue");
268
+ });
269
+ });
270
+ describe("Terraform Output Tests", () => {
271
+ it("should create proper Terraform outputs", () => {
272
+ const props = {
273
+ name: "test-network-manager",
274
+ location: "eastus",
275
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
276
+ networkManagerScopes: {
277
+ subscriptions: [
278
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
279
+ ],
280
+ },
281
+ networkManagerScopeAccesses: ["Connectivity"],
282
+ };
283
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
284
+ expect(manager.idOutput).toBeInstanceOf(cdktf.TerraformOutput);
285
+ expect(manager.nameOutput).toBeInstanceOf(cdktf.TerraformOutput);
286
+ expect(manager.locationOutput).toBeInstanceOf(cdktf.TerraformOutput);
287
+ expect(manager.tagsOutput).toBeInstanceOf(cdktf.TerraformOutput);
288
+ expect(manager.scopeOutput).toBeInstanceOf(cdktf.TerraformOutput);
289
+ expect(manager.scopeAccessesOutput).toBeInstanceOf(cdktf.TerraformOutput);
290
+ });
291
+ it("should have proper resource references in outputs", () => {
292
+ const props = {
293
+ name: "test-network-manager",
294
+ location: "eastus",
295
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
296
+ networkManagerScopes: {
297
+ subscriptions: [
298
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
299
+ ],
300
+ },
301
+ networkManagerScopeAccesses: ["Connectivity"],
302
+ };
303
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
304
+ expect(manager.id).toMatch(/^\$\{.*\.id\}$/);
305
+ expect(manager.resourceName).toMatch(/^\$\{.*\.name\}$/);
306
+ });
307
+ });
308
+ describe("Lifecycle Management Tests", () => {
309
+ it("should apply ignore_changes when specified", () => {
310
+ const props = {
311
+ name: "test-network-manager",
312
+ location: "eastus",
313
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
314
+ networkManagerScopes: {
315
+ subscriptions: [
316
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
317
+ ],
318
+ },
319
+ networkManagerScopeAccesses: ["Connectivity"],
320
+ ignoreChanges: ["tags"],
321
+ };
322
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
323
+ expect(manager.props.ignoreChanges).toEqual(["tags"]);
324
+ const synthesized = cdktf_1.Testing.synth(stack);
325
+ const stackConfig = JSON.parse(synthesized);
326
+ expect(stackConfig.resource).toBeDefined();
327
+ });
328
+ it("should handle multiple ignore_changes properties", () => {
329
+ const props = {
330
+ name: "test-network-manager",
331
+ location: "eastus",
332
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
333
+ networkManagerScopes: {
334
+ subscriptions: [
335
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
336
+ ],
337
+ },
338
+ networkManagerScopeAccesses: ["Connectivity"],
339
+ ignoreChanges: ["tags", "description"],
340
+ };
341
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
342
+ expect(manager.props.ignoreChanges).toHaveLength(2);
343
+ expect(manager.props.ignoreChanges).toContain("tags");
344
+ expect(manager.props.ignoreChanges).toContain("description");
345
+ });
346
+ });
347
+ describe("CDK Synthesis Tests", () => {
348
+ it("should synthesize valid Terraform configuration", () => {
349
+ const props = {
350
+ name: "test-network-manager",
351
+ location: "eastus",
352
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
353
+ networkManagerScopes: {
354
+ subscriptions: [
355
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
356
+ ],
357
+ },
358
+ networkManagerScopeAccesses: ["Connectivity", "SecurityAdmin"],
359
+ description: "Test network manager",
360
+ tags: {
361
+ environment: "test",
362
+ },
363
+ };
364
+ new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
365
+ const synthesized = cdktf_1.Testing.synth(stack);
366
+ expect(synthesized).toBeDefined();
367
+ const stackConfig = JSON.parse(synthesized);
368
+ expect(stackConfig.resource).toBeDefined();
369
+ });
370
+ it("should handle multiple Virtual Network Managers in the same stack", () => {
371
+ const props1 = {
372
+ name: "test-network-manager-1",
373
+ location: "eastus",
374
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
375
+ networkManagerScopes: {
376
+ subscriptions: [
377
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
378
+ ],
379
+ },
380
+ networkManagerScopeAccesses: ["Connectivity"],
381
+ };
382
+ const props2 = {
383
+ name: "test-network-manager-2",
384
+ location: "westus",
385
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
386
+ apiVersion: "2023-11-01",
387
+ networkManagerScopes: {
388
+ subscriptions: [
389
+ "/subscriptions/11111111-1111-1111-1111-111111111111",
390
+ ],
391
+ },
392
+ networkManagerScopeAccesses: ["SecurityAdmin"],
393
+ };
394
+ const manager1 = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager1", props1);
395
+ const manager2 = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager2", props2);
396
+ expect(manager1.resolvedApiVersion).toBe("2024-05-01");
397
+ expect(manager2.resolvedApiVersion).toBe("2023-11-01");
398
+ const synthesized = cdktf_1.Testing.synth(stack);
399
+ expect(synthesized).toBeDefined();
400
+ });
401
+ it("should verify Terraform output structure", () => {
402
+ const props = {
403
+ name: "test-network-manager",
404
+ location: "eastus",
405
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
406
+ networkManagerScopes: {
407
+ subscriptions: [
408
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
409
+ ],
410
+ },
411
+ networkManagerScopeAccesses: ["Connectivity"],
412
+ };
413
+ new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
414
+ const synthesized = cdktf_1.Testing.synth(stack);
415
+ const stackConfig = JSON.parse(synthesized);
416
+ expect(stackConfig.resource).toBeDefined();
417
+ expect(stackConfig.output).toBeDefined();
418
+ expect(stackConfig.output.id).toBeDefined();
419
+ expect(stackConfig.output.name).toBeDefined();
420
+ expect(stackConfig.output.location).toBeDefined();
421
+ expect(stackConfig.output.tags).toBeDefined();
422
+ expect(stackConfig.output.scope).toBeDefined();
423
+ expect(stackConfig.output.scopeAccesses).toBeDefined();
424
+ });
425
+ });
426
+ describe("Resource Type and Version Tests", () => {
427
+ it("should have correct resource type", () => {
428
+ const props = {
429
+ name: "test-network-manager",
430
+ location: "eastus",
431
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
432
+ networkManagerScopes: {
433
+ subscriptions: [
434
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
435
+ ],
436
+ },
437
+ networkManagerScopeAccesses: ["Connectivity"],
438
+ };
439
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
440
+ expect(manager).toBeInstanceOf(virtual_network_manager_1.VirtualNetworkManager);
441
+ });
442
+ it("should support all registered API versions", () => {
443
+ const versions = ["2023-11-01", "2024-05-01"];
444
+ versions.forEach((version) => {
445
+ const testStack = new cdktf.TerraformStack(app, `Stack-${version}`);
446
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(testStack, `Manager-${version}`, {
447
+ name: `manager-${version}`,
448
+ location: "eastus",
449
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
450
+ apiVersion: version,
451
+ networkManagerScopes: {
452
+ subscriptions: [
453
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
454
+ ],
455
+ },
456
+ networkManagerScopeAccesses: ["Connectivity"],
457
+ });
458
+ expect(manager.resolvedApiVersion).toBe(version);
459
+ });
460
+ });
461
+ it("should use latest version as default", () => {
462
+ const props = {
463
+ name: "test-network-manager",
464
+ location: "eastus",
465
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
466
+ networkManagerScopes: {
467
+ subscriptions: [
468
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
469
+ ],
470
+ },
471
+ networkManagerScopeAccesses: ["Connectivity"],
472
+ };
473
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
474
+ expect(manager.resolvedApiVersion).toBe("2024-05-01");
475
+ });
476
+ });
477
+ describe("Description Property Tests", () => {
478
+ it("should create Virtual Network Manager with description", () => {
479
+ const props = {
480
+ name: "test-network-manager",
481
+ location: "eastus",
482
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
483
+ networkManagerScopes: {
484
+ subscriptions: [
485
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
486
+ ],
487
+ },
488
+ networkManagerScopeAccesses: ["Connectivity"],
489
+ description: "Central network management for production workloads",
490
+ };
491
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
492
+ expect(manager.props.description).toBe("Central network management for production workloads");
493
+ });
494
+ it("should create Virtual Network Manager without description", () => {
495
+ const props = {
496
+ name: "test-network-manager",
497
+ location: "eastus",
498
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
499
+ networkManagerScopes: {
500
+ subscriptions: [
501
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
502
+ ],
503
+ },
504
+ networkManagerScopeAccesses: ["Connectivity"],
505
+ };
506
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
507
+ expect(manager.props.description).toBeUndefined();
508
+ });
509
+ });
510
+ describe("Mixed Scope Configuration Tests", () => {
511
+ it("should support both subscriptions and management groups in scope", () => {
512
+ const props = {
513
+ name: "test-network-manager",
514
+ location: "eastus",
515
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
516
+ networkManagerScopes: {
517
+ subscriptions: [
518
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
519
+ ],
520
+ managementGroups: [
521
+ "/providers/Microsoft.Management/managementGroups/mg1",
522
+ ],
523
+ },
524
+ networkManagerScopeAccesses: ["Connectivity", "SecurityAdmin"],
525
+ };
526
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
527
+ expect(manager.props.networkManagerScopes.subscriptions).toHaveLength(1);
528
+ expect(manager.props.networkManagerScopes.managementGroups).toHaveLength(1);
529
+ });
530
+ it("should support all three scope access types", () => {
531
+ const props = {
532
+ name: "test-network-manager",
533
+ location: "eastus",
534
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
535
+ networkManagerScopes: {
536
+ subscriptions: [
537
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
538
+ ],
539
+ },
540
+ networkManagerScopeAccesses: [
541
+ "Connectivity",
542
+ "SecurityAdmin",
543
+ "Routing",
544
+ ],
545
+ };
546
+ const manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", props);
547
+ expect(manager.props.networkManagerScopeAccesses).toHaveLength(3);
548
+ expect(manager.props.networkManagerScopeAccesses).toContain("Connectivity");
549
+ expect(manager.props.networkManagerScopeAccesses).toContain("SecurityAdmin");
550
+ expect(manager.props.networkManagerScopeAccesses).toContain("Routing");
551
+ });
552
+ });
553
+ describe("Convenience Methods for Child Resources", () => {
554
+ let manager;
555
+ beforeEach(() => {
556
+ manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", {
557
+ name: "test-manager",
558
+ location: "eastus",
559
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
560
+ networkManagerScopes: {
561
+ subscriptions: [
562
+ "/subscriptions/00000000-0000-0000-0000-000000000000",
563
+ ],
564
+ },
565
+ networkManagerScopeAccesses: ["Connectivity", "SecurityAdmin"],
566
+ });
567
+ });
568
+ it("should create NetworkGroup using convenience method", () => {
569
+ const networkGroup = manager.addNetworkGroup("prod-group", {
570
+ name: "production-vnets",
571
+ description: "Production virtual networks",
572
+ memberType: "VirtualNetwork",
573
+ });
574
+ expect(networkGroup).toBeInstanceOf(network_group_1.NetworkGroup);
575
+ expect(networkGroup.props.networkManagerId).toBe(manager.id);
576
+ expect(networkGroup.props.name).toBe("production-vnets");
577
+ expect(networkGroup.props.description).toBe("Production virtual networks");
578
+ });
579
+ it("should create ConnectivityConfiguration using convenience method", () => {
580
+ const networkGroup = manager.addNetworkGroup("prod-group", {
581
+ name: "production-vnets",
582
+ });
583
+ const connectivityConfig = manager.addConnectivityConfiguration("hub-spoke", {
584
+ name: "production-hub-spoke",
585
+ connectivityTopology: "HubAndSpoke",
586
+ appliesToGroups: [
587
+ {
588
+ networkGroupId: networkGroup.id,
589
+ groupConnectivity: "None",
590
+ useHubGateway: true,
591
+ },
592
+ ],
593
+ hubs: [
594
+ {
595
+ resourceId: "/subscriptions/test/virtualNetworks/hub",
596
+ resourceType: "Microsoft.Network/virtualNetworks",
597
+ },
598
+ ],
599
+ });
600
+ expect(connectivityConfig).toBeInstanceOf(connectivity_configuration_1.ConnectivityConfiguration);
601
+ expect(connectivityConfig.props.networkManagerId).toBe(manager.id);
602
+ expect(connectivityConfig.props.connectivityTopology).toBe("HubAndSpoke");
603
+ });
604
+ it("should create SecurityAdminConfiguration using convenience method", () => {
605
+ const securityConfig = manager.addSecurityAdminConfiguration("security", {
606
+ name: "production-security",
607
+ description: "High-priority security rules",
608
+ });
609
+ expect(securityConfig).toBeInstanceOf(security_admin_configuration_1.SecurityAdminConfiguration);
610
+ expect(securityConfig.props.networkManagerId).toBe(manager.id);
611
+ expect(securityConfig.props.name).toBe("production-security");
612
+ });
613
+ });
614
+ });
615
+ describe("NetworkGroup", () => {
616
+ let app;
617
+ let stack;
618
+ let manager;
619
+ beforeEach(() => {
620
+ app = cdktf_1.Testing.app();
621
+ stack = new cdktf.TerraformStack(app, "test-stack");
622
+ manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", {
623
+ name: "test-manager",
624
+ location: "eastus",
625
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
626
+ networkManagerScopes: {
627
+ subscriptions: ["/subscriptions/00000000-0000-0000-0000-000000000000"],
628
+ },
629
+ networkManagerScopeAccesses: ["Connectivity"],
630
+ });
631
+ });
632
+ describe("Basic Instantiation", () => {
633
+ it("should create NetworkGroup with minimum required properties", () => {
634
+ const props = {
635
+ name: "test-group",
636
+ networkManagerId: manager.id,
637
+ };
638
+ const networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", props);
639
+ expect(networkGroup).toBeInstanceOf(network_group_1.NetworkGroup);
640
+ expect(networkGroup.props).toBe(props);
641
+ expect(networkGroup.resourceName).toBeDefined();
642
+ expect(networkGroup.id).toBeDefined();
643
+ });
644
+ it("should create NetworkGroup with all properties", () => {
645
+ const props = {
646
+ name: "production-vnets",
647
+ networkManagerId: manager.id,
648
+ description: "Production virtual networks for East US",
649
+ memberType: "VirtualNetwork",
650
+ };
651
+ const networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", props);
652
+ expect(networkGroup.props.description).toBe("Production virtual networks for East US");
653
+ expect(networkGroup.props.memberType).toBe("VirtualNetwork");
654
+ });
655
+ it("should create NetworkGroup with Subnet member type", () => {
656
+ const props = {
657
+ name: "subnet-group",
658
+ networkManagerId: manager.id,
659
+ memberType: "Subnet",
660
+ description: "Subnet-level network group",
661
+ };
662
+ const networkGroup = new network_group_1.NetworkGroup(stack, "SubnetGroup", props);
663
+ expect(networkGroup.props.memberType).toBe("Subnet");
664
+ });
665
+ });
666
+ describe("API Version Handling", () => {
667
+ it("should use default API version when none specified", () => {
668
+ const networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", {
669
+ name: "test-group",
670
+ networkManagerId: manager.id,
671
+ });
672
+ expect(networkGroup.resolvedApiVersion).toBe("2024-05-01");
673
+ });
674
+ it("should use specified API version when provided", () => {
675
+ const networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", {
676
+ name: "test-group",
677
+ networkManagerId: manager.id,
678
+ apiVersion: "2023-11-01",
679
+ });
680
+ expect(networkGroup.resolvedApiVersion).toBe("2023-11-01");
681
+ });
682
+ });
683
+ describe("Terraform Outputs", () => {
684
+ it("should create proper Terraform outputs", () => {
685
+ const networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", {
686
+ name: "test-group",
687
+ networkManagerId: manager.id,
688
+ });
689
+ expect(networkGroup.idOutput).toBeInstanceOf(cdktf.TerraformOutput);
690
+ expect(networkGroup.nameOutput).toBeInstanceOf(cdktf.TerraformOutput);
691
+ expect(networkGroup.provisioningStateOutput).toBeInstanceOf(cdktf.TerraformOutput);
692
+ });
693
+ it("should have proper resource references", () => {
694
+ const networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", {
695
+ name: "test-group",
696
+ networkManagerId: manager.id,
697
+ });
698
+ expect(networkGroup.id).toMatch(/^\$\{.*\.id\}$/);
699
+ expect(networkGroup.resourceName).toMatch(/^\$\{.*\.name\}$/);
700
+ expect(networkGroup.provisioningState).toMatch(/^\$\{.*\.output\.properties\.provisioningState\}$/);
701
+ });
702
+ });
703
+ describe("Lifecycle Management", () => {
704
+ it("should apply ignore_changes when specified", () => {
705
+ const networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", {
706
+ name: "test-group",
707
+ networkManagerId: manager.id,
708
+ ignoreChanges: ["description"],
709
+ });
710
+ expect(networkGroup.props.ignoreChanges).toEqual(["description"]);
711
+ });
712
+ });
713
+ describe("CDK Synthesis", () => {
714
+ it("should synthesize valid Terraform configuration", () => {
715
+ new network_group_1.NetworkGroup(stack, "TestGroup", {
716
+ name: "test-group",
717
+ networkManagerId: manager.id,
718
+ description: "Test network group",
719
+ });
720
+ const synthesized = cdktf_1.Testing.synth(stack);
721
+ expect(synthesized).toBeDefined();
722
+ const stackConfig = JSON.parse(synthesized);
723
+ expect(stackConfig.resource).toBeDefined();
724
+ });
725
+ });
726
+ });
727
+ describe("NetworkGroupStaticMember", () => {
728
+ let app;
729
+ let stack;
730
+ let manager;
731
+ let networkGroup;
732
+ beforeEach(() => {
733
+ app = cdktf_1.Testing.app();
734
+ stack = new cdktf.TerraformStack(app, "test-stack");
735
+ manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", {
736
+ name: "test-manager",
737
+ location: "eastus",
738
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
739
+ networkManagerScopes: {
740
+ subscriptions: ["/subscriptions/00000000-0000-0000-0000-000000000000"],
741
+ },
742
+ networkManagerScopeAccesses: ["Connectivity"],
743
+ });
744
+ networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", {
745
+ name: "test-group",
746
+ networkManagerId: manager.id,
747
+ });
748
+ });
749
+ describe("Basic Instantiation", () => {
750
+ it("should create StaticMember for VNet", () => {
751
+ const props = {
752
+ name: "vnet-member",
753
+ networkGroupId: networkGroup.id,
754
+ resourceId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet",
755
+ };
756
+ const member = new network_group_static_member_1.NetworkGroupStaticMember(stack, "VnetMember", props);
757
+ expect(member).toBeInstanceOf(network_group_static_member_1.NetworkGroupStaticMember);
758
+ expect(member.props).toBe(props);
759
+ expect(member.props.resourceId).toContain("virtualNetworks");
760
+ });
761
+ it("should create StaticMember for Subnet", () => {
762
+ const props = {
763
+ name: "subnet-member",
764
+ networkGroupId: networkGroup.id,
765
+ resourceId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg/providers/Microsoft.Network/virtualNetworks/test-vnet/subnets/test-subnet",
766
+ };
767
+ const member = new network_group_static_member_1.NetworkGroupStaticMember(stack, "SubnetMember", props);
768
+ expect(member).toBeInstanceOf(network_group_static_member_1.NetworkGroupStaticMember);
769
+ expect(member.props.resourceId).toContain("subnets");
770
+ });
771
+ });
772
+ describe("API Version Handling", () => {
773
+ it("should use default API version when none specified", () => {
774
+ const member = new network_group_static_member_1.NetworkGroupStaticMember(stack, "TestMember", {
775
+ name: "test-member",
776
+ networkGroupId: networkGroup.id,
777
+ resourceId: "/subscriptions/test/virtualNetworks/vnet1",
778
+ });
779
+ expect(member.resolvedApiVersion).toBe("2024-05-01");
780
+ });
781
+ it("should use specified API version when provided", () => {
782
+ const member = new network_group_static_member_1.NetworkGroupStaticMember(stack, "TestMember", {
783
+ name: "test-member",
784
+ networkGroupId: networkGroup.id,
785
+ resourceId: "/subscriptions/test/virtualNetworks/vnet1",
786
+ apiVersion: "2023-11-01",
787
+ });
788
+ expect(member.resolvedApiVersion).toBe("2023-11-01");
789
+ });
790
+ });
791
+ describe("Terraform Outputs", () => {
792
+ it("should create proper Terraform outputs", () => {
793
+ const member = new network_group_static_member_1.NetworkGroupStaticMember(stack, "TestMember", {
794
+ name: "test-member",
795
+ networkGroupId: networkGroup.id,
796
+ resourceId: "/subscriptions/test/virtualNetworks/vnet1",
797
+ });
798
+ expect(member.idOutput).toBeInstanceOf(cdktf.TerraformOutput);
799
+ expect(member.nameOutput).toBeInstanceOf(cdktf.TerraformOutput);
800
+ expect(member.resourceIdOutput).toBeInstanceOf(cdktf.TerraformOutput);
801
+ });
802
+ it("should have proper resource references", () => {
803
+ const member = new network_group_static_member_1.NetworkGroupStaticMember(stack, "TestMember", {
804
+ name: "test-member",
805
+ networkGroupId: networkGroup.id,
806
+ resourceId: "/subscriptions/test/virtualNetworks/vnet1",
807
+ });
808
+ expect(member.id).toMatch(/^\$\{.*\.id\}$/);
809
+ expect(member.resourceName).toMatch(/^\$\{.*\.name\}$/);
810
+ // memberResourceId returns the input resourceId since Azure API doesn't return it
811
+ expect(member.memberResourceId).toBe("/subscriptions/test/virtualNetworks/vnet1");
812
+ expect(member.region).toMatch(/^\$\{.*\.output\.properties\.region\}$/);
813
+ });
814
+ });
815
+ describe("Parent-Child Relationship", () => {
816
+ it("should correctly reference parent network group", () => {
817
+ const member = new network_group_static_member_1.NetworkGroupStaticMember(stack, "TestMember", {
818
+ name: "test-member",
819
+ networkGroupId: networkGroup.id,
820
+ resourceId: "/subscriptions/test/virtualNetworks/vnet1",
821
+ });
822
+ expect(member.props.networkGroupId).toBe(networkGroup.id);
823
+ });
824
+ });
825
+ describe("CDK Synthesis", () => {
826
+ it("should synthesize valid Terraform configuration", () => {
827
+ new network_group_static_member_1.NetworkGroupStaticMember(stack, "TestMember", {
828
+ name: "test-member",
829
+ networkGroupId: networkGroup.id,
830
+ resourceId: "/subscriptions/test/virtualNetworks/vnet1",
831
+ });
832
+ const synthesized = cdktf_1.Testing.synth(stack);
833
+ expect(synthesized).toBeDefined();
834
+ const stackConfig = JSON.parse(synthesized);
835
+ expect(stackConfig.resource).toBeDefined();
836
+ });
837
+ });
838
+ });
839
+ describe("ConnectivityConfiguration", () => {
840
+ let app;
841
+ let stack;
842
+ let manager;
843
+ let networkGroup;
844
+ beforeEach(() => {
845
+ app = cdktf_1.Testing.app();
846
+ stack = new cdktf.TerraformStack(app, "test-stack");
847
+ manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", {
848
+ name: "test-manager",
849
+ location: "eastus",
850
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
851
+ networkManagerScopes: {
852
+ subscriptions: ["/subscriptions/00000000-0000-0000-0000-000000000000"],
853
+ },
854
+ networkManagerScopeAccesses: ["Connectivity"],
855
+ });
856
+ networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", {
857
+ name: "test-group",
858
+ networkManagerId: manager.id,
859
+ });
860
+ });
861
+ describe("Basic Instantiation - Mesh Topology", () => {
862
+ it("should create Mesh connectivity configuration", () => {
863
+ const props = {
864
+ name: "mesh-config",
865
+ networkManagerId: manager.id,
866
+ connectivityTopology: "Mesh",
867
+ appliesToGroups: [
868
+ {
869
+ networkGroupId: networkGroup.id,
870
+ groupConnectivity: "DirectlyConnected",
871
+ isGlobal: false,
872
+ },
873
+ ],
874
+ };
875
+ const config = new connectivity_configuration_1.ConnectivityConfiguration(stack, "MeshConfig", props);
876
+ expect(config).toBeInstanceOf(connectivity_configuration_1.ConnectivityConfiguration);
877
+ expect(config.topology).toBe("Mesh");
878
+ expect(config.props.appliesToGroups).toHaveLength(1);
879
+ });
880
+ it("should create global Mesh connectivity configuration", () => {
881
+ const props = {
882
+ name: "global-mesh",
883
+ networkManagerId: manager.id,
884
+ connectivityTopology: "Mesh",
885
+ appliesToGroups: [
886
+ {
887
+ networkGroupId: networkGroup.id,
888
+ groupConnectivity: "DirectlyConnected",
889
+ isGlobal: true,
890
+ },
891
+ ],
892
+ isGlobal: true,
893
+ };
894
+ const config = new connectivity_configuration_1.ConnectivityConfiguration(stack, "GlobalMesh", props);
895
+ expect(config.props.isGlobal).toBe(true);
896
+ });
897
+ });
898
+ describe("Basic Instantiation - Hub-and-Spoke Topology", () => {
899
+ it("should create Hub-and-Spoke connectivity configuration", () => {
900
+ const props = {
901
+ name: "hub-spoke-config",
902
+ networkManagerId: manager.id,
903
+ connectivityTopology: "HubAndSpoke",
904
+ appliesToGroups: [
905
+ {
906
+ networkGroupId: networkGroup.id,
907
+ groupConnectivity: "None",
908
+ useHubGateway: true,
909
+ },
910
+ ],
911
+ hubs: [
912
+ {
913
+ resourceId: "/subscriptions/test/virtualNetworks/hub-vnet",
914
+ resourceType: "Microsoft.Network/virtualNetworks",
915
+ },
916
+ ],
917
+ };
918
+ const config = new connectivity_configuration_1.ConnectivityConfiguration(stack, "HubSpokeConfig", props);
919
+ expect(config.topology).toBe("HubAndSpoke");
920
+ expect(config.props.hubs).toHaveLength(1);
921
+ expect(config.props.appliesToGroups[0].useHubGateway).toBe(true);
922
+ });
923
+ it("should create Hub-and-Spoke with multiple hubs", () => {
924
+ const props = {
925
+ name: "multi-hub-config",
926
+ networkManagerId: manager.id,
927
+ connectivityTopology: "HubAndSpoke",
928
+ appliesToGroups: [
929
+ {
930
+ networkGroupId: networkGroup.id,
931
+ groupConnectivity: "None",
932
+ },
933
+ ],
934
+ hubs: [
935
+ {
936
+ resourceId: "/subscriptions/test/virtualNetworks/hub-vnet-1",
937
+ resourceType: "Microsoft.Network/virtualNetworks",
938
+ },
939
+ {
940
+ resourceId: "/subscriptions/test/virtualNetworks/hub-vnet-2",
941
+ resourceType: "Microsoft.Network/virtualNetworks",
942
+ },
943
+ ],
944
+ };
945
+ const config = new connectivity_configuration_1.ConnectivityConfiguration(stack, "MultiHubConfig", props);
946
+ expect(config.props.hubs).toHaveLength(2);
947
+ });
948
+ });
949
+ describe("Property Validation", () => {
950
+ it("should handle description property", () => {
951
+ const config = new connectivity_configuration_1.ConnectivityConfiguration(stack, "TestConfig", {
952
+ name: "test-config",
953
+ networkManagerId: manager.id,
954
+ description: "Hub-and-spoke topology for production workloads",
955
+ connectivityTopology: "HubAndSpoke",
956
+ appliesToGroups: [{ networkGroupId: networkGroup.id }],
957
+ hubs: [
958
+ {
959
+ resourceId: "/subscriptions/test/virtualNetworks/hub",
960
+ resourceType: "Microsoft.Network/virtualNetworks",
961
+ },
962
+ ],
963
+ });
964
+ expect(config.props.description).toBe("Hub-and-spoke topology for production workloads");
965
+ });
966
+ it("should handle deleteExistingPeering property", () => {
967
+ const config = new connectivity_configuration_1.ConnectivityConfiguration(stack, "TestConfig", {
968
+ name: "test-config",
969
+ networkManagerId: manager.id,
970
+ connectivityTopology: "Mesh",
971
+ appliesToGroups: [{ networkGroupId: networkGroup.id }],
972
+ deleteExistingPeering: true,
973
+ });
974
+ expect(config.props.deleteExistingPeering).toBe(true);
975
+ });
976
+ });
977
+ describe("API Version Handling", () => {
978
+ it("should use default API version when none specified", () => {
979
+ const config = new connectivity_configuration_1.ConnectivityConfiguration(stack, "TestConfig", {
980
+ name: "test-config",
981
+ networkManagerId: manager.id,
982
+ connectivityTopology: "Mesh",
983
+ appliesToGroups: [{ networkGroupId: networkGroup.id }],
984
+ });
985
+ expect(config.resolvedApiVersion).toBe("2024-05-01");
986
+ });
987
+ it("should use specified API version when provided", () => {
988
+ const config = new connectivity_configuration_1.ConnectivityConfiguration(stack, "TestConfig", {
989
+ name: "test-config",
990
+ networkManagerId: manager.id,
991
+ apiVersion: "2023-11-01",
992
+ connectivityTopology: "Mesh",
993
+ appliesToGroups: [{ networkGroupId: networkGroup.id }],
994
+ });
995
+ expect(config.resolvedApiVersion).toBe("2023-11-01");
996
+ });
997
+ });
998
+ describe("Terraform Outputs", () => {
999
+ it("should create proper Terraform outputs", () => {
1000
+ const config = new connectivity_configuration_1.ConnectivityConfiguration(stack, "TestConfig", {
1001
+ name: "test-config",
1002
+ networkManagerId: manager.id,
1003
+ connectivityTopology: "Mesh",
1004
+ appliesToGroups: [{ networkGroupId: networkGroup.id }],
1005
+ });
1006
+ expect(config.idOutput).toBeInstanceOf(cdktf.TerraformOutput);
1007
+ expect(config.nameOutput).toBeInstanceOf(cdktf.TerraformOutput);
1008
+ expect(config.provisioningStateOutput).toBeInstanceOf(cdktf.TerraformOutput);
1009
+ });
1010
+ });
1011
+ describe("CDK Synthesis", () => {
1012
+ it("should synthesize valid Terraform configuration", () => {
1013
+ new connectivity_configuration_1.ConnectivityConfiguration(stack, "TestConfig", {
1014
+ name: "test-config",
1015
+ networkManagerId: manager.id,
1016
+ connectivityTopology: "Mesh",
1017
+ appliesToGroups: [{ networkGroupId: networkGroup.id }],
1018
+ });
1019
+ const synthesized = cdktf_1.Testing.synth(stack);
1020
+ expect(synthesized).toBeDefined();
1021
+ const stackConfig = JSON.parse(synthesized);
1022
+ expect(stackConfig.resource).toBeDefined();
1023
+ });
1024
+ });
1025
+ });
1026
+ describe("SecurityAdminConfiguration", () => {
1027
+ let app;
1028
+ let stack;
1029
+ let manager;
1030
+ beforeEach(() => {
1031
+ app = cdktf_1.Testing.app();
1032
+ stack = new cdktf.TerraformStack(app, "test-stack");
1033
+ manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", {
1034
+ name: "test-manager",
1035
+ location: "eastus",
1036
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
1037
+ networkManagerScopes: {
1038
+ subscriptions: ["/subscriptions/00000000-0000-0000-0000-000000000000"],
1039
+ },
1040
+ networkManagerScopeAccesses: ["SecurityAdmin"],
1041
+ });
1042
+ });
1043
+ describe("Basic Instantiation", () => {
1044
+ it("should create SecurityAdminConfiguration with minimum properties", () => {
1045
+ const props = {
1046
+ name: "security-config",
1047
+ networkManagerId: manager.id,
1048
+ };
1049
+ const config = new security_admin_configuration_1.SecurityAdminConfiguration(stack, "SecurityConfig", props);
1050
+ expect(config).toBeInstanceOf(security_admin_configuration_1.SecurityAdminConfiguration);
1051
+ expect(config.props).toBe(props);
1052
+ });
1053
+ it("should create SecurityAdminConfiguration with all properties", () => {
1054
+ const props = {
1055
+ name: "security-config",
1056
+ networkManagerId: manager.id,
1057
+ description: "Organization-wide security rules",
1058
+ applyOnNetworkIntentPolicyBasedServices: ["None"],
1059
+ };
1060
+ const config = new security_admin_configuration_1.SecurityAdminConfiguration(stack, "SecurityConfig", props);
1061
+ expect(config.props.description).toBe("Organization-wide security rules");
1062
+ expect(config.props.applyOnNetworkIntentPolicyBasedServices).toEqual([
1063
+ "None",
1064
+ ]);
1065
+ });
1066
+ });
1067
+ describe("API Version Handling", () => {
1068
+ it("should use default API version when none specified", () => {
1069
+ const config = new security_admin_configuration_1.SecurityAdminConfiguration(stack, "SecurityConfig", {
1070
+ name: "security-config",
1071
+ networkManagerId: manager.id,
1072
+ });
1073
+ expect(config.resolvedApiVersion).toBe("2024-05-01");
1074
+ });
1075
+ it("should use specified API version when provided", () => {
1076
+ const config = new security_admin_configuration_1.SecurityAdminConfiguration(stack, "SecurityConfig", {
1077
+ name: "security-config",
1078
+ networkManagerId: manager.id,
1079
+ apiVersion: "2023-11-01",
1080
+ });
1081
+ expect(config.resolvedApiVersion).toBe("2023-11-01");
1082
+ });
1083
+ });
1084
+ describe("Terraform Outputs", () => {
1085
+ it("should create proper Terraform outputs", () => {
1086
+ const config = new security_admin_configuration_1.SecurityAdminConfiguration(stack, "SecurityConfig", {
1087
+ name: "security-config",
1088
+ networkManagerId: manager.id,
1089
+ });
1090
+ expect(config.idOutput).toBeInstanceOf(cdktf.TerraformOutput);
1091
+ expect(config.nameOutput).toBeInstanceOf(cdktf.TerraformOutput);
1092
+ expect(config.provisioningStateOutput).toBeInstanceOf(cdktf.TerraformOutput);
1093
+ });
1094
+ it("should have proper resource references", () => {
1095
+ const config = new security_admin_configuration_1.SecurityAdminConfiguration(stack, "SecurityConfig", {
1096
+ name: "security-config",
1097
+ networkManagerId: manager.id,
1098
+ });
1099
+ expect(config.id).toMatch(/^\$\{.*\.id\}$/);
1100
+ expect(config.resourceName).toMatch(/^\$\{.*\.name\}$/);
1101
+ expect(config.provisioningState).toMatch(/^\$\{.*\.output\.properties\.provisioningState\}$/);
1102
+ });
1103
+ });
1104
+ describe("CDK Synthesis", () => {
1105
+ it("should synthesize valid Terraform configuration", () => {
1106
+ new security_admin_configuration_1.SecurityAdminConfiguration(stack, "SecurityConfig", {
1107
+ name: "security-config",
1108
+ networkManagerId: manager.id,
1109
+ description: "Test security configuration",
1110
+ });
1111
+ const synthesized = cdktf_1.Testing.synth(stack);
1112
+ expect(synthesized).toBeDefined();
1113
+ const stackConfig = JSON.parse(synthesized);
1114
+ expect(stackConfig.resource).toBeDefined();
1115
+ });
1116
+ });
1117
+ });
1118
+ describe("SecurityAdminRuleCollection", () => {
1119
+ let app;
1120
+ let stack;
1121
+ let manager;
1122
+ let securityConfig;
1123
+ let networkGroup;
1124
+ beforeEach(() => {
1125
+ app = cdktf_1.Testing.app();
1126
+ stack = new cdktf.TerraformStack(app, "test-stack");
1127
+ manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", {
1128
+ name: "test-manager",
1129
+ location: "eastus",
1130
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
1131
+ networkManagerScopes: {
1132
+ subscriptions: ["/subscriptions/00000000-0000-0000-0000-000000000000"],
1133
+ },
1134
+ networkManagerScopeAccesses: ["SecurityAdmin"],
1135
+ });
1136
+ securityConfig = new security_admin_configuration_1.SecurityAdminConfiguration(stack, "SecurityConfig", {
1137
+ name: "security-config",
1138
+ networkManagerId: manager.id,
1139
+ });
1140
+ networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", {
1141
+ name: "test-group",
1142
+ networkManagerId: manager.id,
1143
+ });
1144
+ });
1145
+ describe("Basic Instantiation", () => {
1146
+ it("should create RuleCollection with minimum properties", () => {
1147
+ const props = {
1148
+ name: "rule-collection",
1149
+ securityAdminConfigurationId: securityConfig.id,
1150
+ appliesToGroups: [{ networkGroupId: networkGroup.id }],
1151
+ };
1152
+ const collection = new security_admin_rule_collection_1.SecurityAdminRuleCollection(stack, "RuleCollection", props);
1153
+ expect(collection).toBeInstanceOf(security_admin_rule_collection_1.SecurityAdminRuleCollection);
1154
+ expect(collection.props.appliesToGroups).toHaveLength(1);
1155
+ });
1156
+ it("should create RuleCollection with description", () => {
1157
+ const props = {
1158
+ name: "block-high-risk-ports",
1159
+ securityAdminConfigurationId: securityConfig.id,
1160
+ description: "Rules to block high-risk ports",
1161
+ appliesToGroups: [{ networkGroupId: networkGroup.id }],
1162
+ };
1163
+ const collection = new security_admin_rule_collection_1.SecurityAdminRuleCollection(stack, "RuleCollection", props);
1164
+ expect(collection.props.description).toBe("Rules to block high-risk ports");
1165
+ });
1166
+ it("should create RuleCollection applied to multiple groups", () => {
1167
+ const group2 = new network_group_1.NetworkGroup(stack, "TestGroup2", {
1168
+ name: "test-group-2",
1169
+ networkManagerId: manager.id,
1170
+ });
1171
+ const props = {
1172
+ name: "multi-group-collection",
1173
+ securityAdminConfigurationId: securityConfig.id,
1174
+ appliesToGroups: [
1175
+ { networkGroupId: networkGroup.id },
1176
+ { networkGroupId: group2.id },
1177
+ ],
1178
+ };
1179
+ const collection = new security_admin_rule_collection_1.SecurityAdminRuleCollection(stack, "RuleCollection", props);
1180
+ expect(collection.props.appliesToGroups).toHaveLength(2);
1181
+ });
1182
+ });
1183
+ describe("API Version Handling", () => {
1184
+ it("should use default API version when none specified", () => {
1185
+ const collection = new security_admin_rule_collection_1.SecurityAdminRuleCollection(stack, "RuleCollection", {
1186
+ name: "rule-collection",
1187
+ securityAdminConfigurationId: securityConfig.id,
1188
+ appliesToGroups: [{ networkGroupId: networkGroup.id }],
1189
+ });
1190
+ expect(collection.resolvedApiVersion).toBe("2024-05-01");
1191
+ });
1192
+ it("should use specified API version when provided", () => {
1193
+ const collection = new security_admin_rule_collection_1.SecurityAdminRuleCollection(stack, "RuleCollection", {
1194
+ name: "rule-collection",
1195
+ securityAdminConfigurationId: securityConfig.id,
1196
+ apiVersion: "2023-11-01",
1197
+ appliesToGroups: [{ networkGroupId: networkGroup.id }],
1198
+ });
1199
+ expect(collection.resolvedApiVersion).toBe("2023-11-01");
1200
+ });
1201
+ });
1202
+ describe("Terraform Outputs", () => {
1203
+ it("should create proper Terraform outputs", () => {
1204
+ const collection = new security_admin_rule_collection_1.SecurityAdminRuleCollection(stack, "RuleCollection", {
1205
+ name: "rule-collection",
1206
+ securityAdminConfigurationId: securityConfig.id,
1207
+ appliesToGroups: [{ networkGroupId: networkGroup.id }],
1208
+ });
1209
+ expect(collection.idOutput).toBeInstanceOf(cdktf.TerraformOutput);
1210
+ expect(collection.nameOutput).toBeInstanceOf(cdktf.TerraformOutput);
1211
+ expect(collection.provisioningStateOutput).toBeInstanceOf(cdktf.TerraformOutput);
1212
+ });
1213
+ });
1214
+ describe("Parent-Child Relationship", () => {
1215
+ it("should correctly reference parent security admin configuration", () => {
1216
+ const collection = new security_admin_rule_collection_1.SecurityAdminRuleCollection(stack, "RuleCollection", {
1217
+ name: "rule-collection",
1218
+ securityAdminConfigurationId: securityConfig.id,
1219
+ appliesToGroups: [{ networkGroupId: networkGroup.id }],
1220
+ });
1221
+ expect(collection.props.securityAdminConfigurationId).toBe(securityConfig.id);
1222
+ });
1223
+ });
1224
+ describe("CDK Synthesis", () => {
1225
+ it("should synthesize valid Terraform configuration", () => {
1226
+ new security_admin_rule_collection_1.SecurityAdminRuleCollection(stack, "RuleCollection", {
1227
+ name: "rule-collection",
1228
+ securityAdminConfigurationId: securityConfig.id,
1229
+ appliesToGroups: [{ networkGroupId: networkGroup.id }],
1230
+ });
1231
+ const synthesized = cdktf_1.Testing.synth(stack);
1232
+ expect(synthesized).toBeDefined();
1233
+ const stackConfig = JSON.parse(synthesized);
1234
+ expect(stackConfig.resource).toBeDefined();
1235
+ });
1236
+ });
1237
+ });
1238
+ describe("SecurityAdminRule", () => {
1239
+ let app;
1240
+ let stack;
1241
+ let manager;
1242
+ let securityConfig;
1243
+ let networkGroup;
1244
+ let ruleCollection;
1245
+ beforeEach(() => {
1246
+ app = cdktf_1.Testing.app();
1247
+ stack = new cdktf.TerraformStack(app, "test-stack");
1248
+ manager = new virtual_network_manager_1.VirtualNetworkManager(stack, "TestManager", {
1249
+ name: "test-manager",
1250
+ location: "eastus",
1251
+ resourceGroupId: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/test-rg",
1252
+ networkManagerScopes: {
1253
+ subscriptions: ["/subscriptions/00000000-0000-0000-0000-000000000000"],
1254
+ },
1255
+ networkManagerScopeAccesses: ["SecurityAdmin"],
1256
+ });
1257
+ securityConfig = new security_admin_configuration_1.SecurityAdminConfiguration(stack, "SecurityConfig", {
1258
+ name: "security-config",
1259
+ networkManagerId: manager.id,
1260
+ });
1261
+ networkGroup = new network_group_1.NetworkGroup(stack, "TestGroup", {
1262
+ name: "test-group",
1263
+ networkManagerId: manager.id,
1264
+ });
1265
+ ruleCollection = new security_admin_rule_collection_1.SecurityAdminRuleCollection(stack, "RuleCollection", {
1266
+ name: "rule-collection",
1267
+ securityAdminConfigurationId: securityConfig.id,
1268
+ appliesToGroups: [{ networkGroupId: networkGroup.id }],
1269
+ });
1270
+ });
1271
+ describe("Basic Instantiation - Deny Rules", () => {
1272
+ it("should create Deny rule blocking SSH", () => {
1273
+ const props = {
1274
+ name: "block-ssh",
1275
+ ruleCollectionId: ruleCollection.id,
1276
+ description: "Block SSH access from internet",
1277
+ priority: 100,
1278
+ action: "Deny",
1279
+ direction: "Inbound",
1280
+ protocol: "Tcp",
1281
+ destinationPortRanges: ["22"],
1282
+ sources: [
1283
+ { addressPrefix: "Internet", addressPrefixType: "ServiceTag" },
1284
+ ],
1285
+ destinations: [{ addressPrefix: "*", addressPrefixType: "IPPrefix" }],
1286
+ };
1287
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "BlockSSH", props);
1288
+ expect(rule).toBeInstanceOf(security_admin_rule_1.SecurityAdminRule);
1289
+ expect(rule.ruleAction).toBe("Deny");
1290
+ expect(rule.rulePriority).toBe(100);
1291
+ expect(rule.props.protocol).toBe("Tcp");
1292
+ expect(rule.props.destinationPortRanges).toEqual(["22"]);
1293
+ });
1294
+ it("should create Deny rule blocking RDP", () => {
1295
+ const props = {
1296
+ name: "block-rdp",
1297
+ ruleCollectionId: ruleCollection.id,
1298
+ priority: 101,
1299
+ action: "Deny",
1300
+ direction: "Inbound",
1301
+ protocol: "Tcp",
1302
+ destinationPortRanges: ["3389"],
1303
+ sources: [
1304
+ { addressPrefix: "Internet", addressPrefixType: "ServiceTag" },
1305
+ ],
1306
+ destinations: [{ addressPrefix: "*", addressPrefixType: "IPPrefix" }],
1307
+ };
1308
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "BlockRDP", props);
1309
+ expect(rule.props.destinationPortRanges).toEqual(["3389"]);
1310
+ });
1311
+ });
1312
+ describe("Basic Instantiation - Allow Rules", () => {
1313
+ it("should create Allow rule", () => {
1314
+ const props = {
1315
+ name: "allow-https",
1316
+ ruleCollectionId: ruleCollection.id,
1317
+ priority: 200,
1318
+ action: "Allow",
1319
+ direction: "Inbound",
1320
+ protocol: "Tcp",
1321
+ destinationPortRanges: ["443"],
1322
+ };
1323
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "AllowHTTPS", props);
1324
+ expect(rule.ruleAction).toBe("Allow");
1325
+ });
1326
+ });
1327
+ describe("Basic Instantiation - AlwaysAllow Rules", () => {
1328
+ it("should create AlwaysAllow rule for monitoring", () => {
1329
+ const props = {
1330
+ name: "always-allow-monitoring",
1331
+ ruleCollectionId: ruleCollection.id,
1332
+ description: "Always allow traffic from monitoring systems",
1333
+ priority: 50,
1334
+ action: "AlwaysAllow",
1335
+ direction: "Inbound",
1336
+ protocol: "Any",
1337
+ sources: [
1338
+ { addressPrefix: "10.0.0.0/24", addressPrefixType: "IPPrefix" },
1339
+ ],
1340
+ destinations: [{ addressPrefix: "*", addressPrefixType: "IPPrefix" }],
1341
+ };
1342
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "AllowMonitoring", props);
1343
+ expect(rule.ruleAction).toBe("AlwaysAllow");
1344
+ expect(rule.rulePriority).toBe(50);
1345
+ });
1346
+ });
1347
+ describe("Protocol Handling", () => {
1348
+ it("should support Tcp protocol", () => {
1349
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "TcpRule", {
1350
+ name: "tcp-rule",
1351
+ ruleCollectionId: ruleCollection.id,
1352
+ priority: 100,
1353
+ action: "Deny",
1354
+ direction: "Inbound",
1355
+ protocol: "Tcp",
1356
+ });
1357
+ expect(rule.props.protocol).toBe("Tcp");
1358
+ });
1359
+ it("should support Udp protocol", () => {
1360
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "UdpRule", {
1361
+ name: "udp-rule",
1362
+ ruleCollectionId: ruleCollection.id,
1363
+ priority: 100,
1364
+ action: "Deny",
1365
+ direction: "Inbound",
1366
+ protocol: "Udp",
1367
+ });
1368
+ expect(rule.props.protocol).toBe("Udp");
1369
+ });
1370
+ it("should support Icmp protocol", () => {
1371
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "IcmpRule", {
1372
+ name: "icmp-rule",
1373
+ ruleCollectionId: ruleCollection.id,
1374
+ priority: 100,
1375
+ action: "Deny",
1376
+ direction: "Inbound",
1377
+ protocol: "Icmp",
1378
+ });
1379
+ expect(rule.props.protocol).toBe("Icmp");
1380
+ });
1381
+ it("should support Any protocol", () => {
1382
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "AnyRule", {
1383
+ name: "any-rule",
1384
+ ruleCollectionId: ruleCollection.id,
1385
+ priority: 100,
1386
+ action: "Allow",
1387
+ direction: "Inbound",
1388
+ protocol: "Any",
1389
+ });
1390
+ expect(rule.props.protocol).toBe("Any");
1391
+ });
1392
+ });
1393
+ describe("Direction Handling", () => {
1394
+ it("should support Inbound direction", () => {
1395
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "InboundRule", {
1396
+ name: "inbound-rule",
1397
+ ruleCollectionId: ruleCollection.id,
1398
+ priority: 100,
1399
+ action: "Deny",
1400
+ direction: "Inbound",
1401
+ protocol: "Tcp",
1402
+ });
1403
+ expect(rule.props.direction).toBe("Inbound");
1404
+ });
1405
+ it("should support Outbound direction", () => {
1406
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "OutboundRule", {
1407
+ name: "outbound-rule",
1408
+ ruleCollectionId: ruleCollection.id,
1409
+ priority: 100,
1410
+ action: "Deny",
1411
+ direction: "Outbound",
1412
+ protocol: "Tcp",
1413
+ });
1414
+ expect(rule.props.direction).toBe("Outbound");
1415
+ });
1416
+ });
1417
+ describe("Port Range Handling", () => {
1418
+ it("should handle single source port", () => {
1419
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "SinglePort", {
1420
+ name: "single-port",
1421
+ ruleCollectionId: ruleCollection.id,
1422
+ priority: 100,
1423
+ action: "Deny",
1424
+ direction: "Inbound",
1425
+ protocol: "Tcp",
1426
+ sourcePortRanges: ["80"],
1427
+ });
1428
+ expect(rule.props.sourcePortRanges).toEqual(["80"]);
1429
+ });
1430
+ it("should handle multiple destination ports", () => {
1431
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "MultiplePorts", {
1432
+ name: "multiple-ports",
1433
+ ruleCollectionId: ruleCollection.id,
1434
+ priority: 100,
1435
+ action: "Deny",
1436
+ direction: "Inbound",
1437
+ protocol: "Tcp",
1438
+ destinationPortRanges: ["80", "443", "8080"],
1439
+ });
1440
+ expect(rule.props.destinationPortRanges).toEqual(["80", "443", "8080"]);
1441
+ });
1442
+ it("should handle port ranges", () => {
1443
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "PortRange", {
1444
+ name: "port-range",
1445
+ ruleCollectionId: ruleCollection.id,
1446
+ priority: 100,
1447
+ action: "Deny",
1448
+ direction: "Inbound",
1449
+ protocol: "Tcp",
1450
+ destinationPortRanges: ["8000-8999"],
1451
+ });
1452
+ expect(rule.props.destinationPortRanges).toEqual(["8000-8999"]);
1453
+ });
1454
+ it("should default to wildcard when ports not specified", () => {
1455
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "DefaultPorts", {
1456
+ name: "default-ports",
1457
+ ruleCollectionId: ruleCollection.id,
1458
+ priority: 100,
1459
+ action: "Deny",
1460
+ direction: "Inbound",
1461
+ protocol: "Any",
1462
+ });
1463
+ expect(rule.props.sourcePortRanges).toBeUndefined();
1464
+ expect(rule.props.destinationPortRanges).toBeUndefined();
1465
+ });
1466
+ });
1467
+ describe("Address Prefix Handling", () => {
1468
+ it("should handle IP prefix sources", () => {
1469
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "IPPrefix", {
1470
+ name: "ip-prefix",
1471
+ ruleCollectionId: ruleCollection.id,
1472
+ priority: 100,
1473
+ action: "Deny",
1474
+ direction: "Inbound",
1475
+ protocol: "Tcp",
1476
+ sources: [
1477
+ { addressPrefix: "10.0.0.0/8", addressPrefixType: "IPPrefix" },
1478
+ ],
1479
+ });
1480
+ expect(rule.props.sources).toEqual([
1481
+ { addressPrefix: "10.0.0.0/8", addressPrefixType: "IPPrefix" },
1482
+ ]);
1483
+ });
1484
+ it("should handle ServiceTag sources", () => {
1485
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "ServiceTag", {
1486
+ name: "service-tag",
1487
+ ruleCollectionId: ruleCollection.id,
1488
+ priority: 100,
1489
+ action: "Deny",
1490
+ direction: "Inbound",
1491
+ protocol: "Tcp",
1492
+ sources: [
1493
+ { addressPrefix: "Internet", addressPrefixType: "ServiceTag" },
1494
+ ],
1495
+ });
1496
+ expect(rule.props.sources).toEqual([
1497
+ { addressPrefix: "Internet", addressPrefixType: "ServiceTag" },
1498
+ ]);
1499
+ });
1500
+ it("should handle multiple source addresses", () => {
1501
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "MultipleSources", {
1502
+ name: "multiple-sources",
1503
+ ruleCollectionId: ruleCollection.id,
1504
+ priority: 100,
1505
+ action: "Deny",
1506
+ direction: "Inbound",
1507
+ protocol: "Tcp",
1508
+ sources: [
1509
+ { addressPrefix: "10.0.0.0/8", addressPrefixType: "IPPrefix" },
1510
+ { addressPrefix: "192.168.0.0/16", addressPrefixType: "IPPrefix" },
1511
+ ],
1512
+ });
1513
+ expect(rule.props.sources).toHaveLength(2);
1514
+ });
1515
+ });
1516
+ describe("Priority Handling", () => {
1517
+ it("should accept low priority number (high priority)", () => {
1518
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "HighPriority", {
1519
+ name: "high-priority",
1520
+ ruleCollectionId: ruleCollection.id,
1521
+ priority: 1,
1522
+ action: "AlwaysAllow",
1523
+ direction: "Inbound",
1524
+ protocol: "Any",
1525
+ });
1526
+ expect(rule.rulePriority).toBe(1);
1527
+ });
1528
+ it("should accept high priority number (low priority)", () => {
1529
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "LowPriority", {
1530
+ name: "low-priority",
1531
+ ruleCollectionId: ruleCollection.id,
1532
+ priority: 4096,
1533
+ action: "Allow",
1534
+ direction: "Inbound",
1535
+ protocol: "Any",
1536
+ });
1537
+ expect(rule.rulePriority).toBe(4096);
1538
+ });
1539
+ });
1540
+ describe("API Version Handling", () => {
1541
+ it("should use default API version when none specified", () => {
1542
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "TestRule", {
1543
+ name: "test-rule",
1544
+ ruleCollectionId: ruleCollection.id,
1545
+ priority: 100,
1546
+ action: "Deny",
1547
+ direction: "Inbound",
1548
+ protocol: "Tcp",
1549
+ });
1550
+ expect(rule.resolvedApiVersion).toBe("2024-05-01");
1551
+ });
1552
+ it("should use specified API version when provided", () => {
1553
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "TestRule", {
1554
+ name: "test-rule",
1555
+ ruleCollectionId: ruleCollection.id,
1556
+ apiVersion: "2023-11-01",
1557
+ priority: 100,
1558
+ action: "Deny",
1559
+ direction: "Inbound",
1560
+ protocol: "Tcp",
1561
+ });
1562
+ expect(rule.resolvedApiVersion).toBe("2023-11-01");
1563
+ });
1564
+ });
1565
+ describe("Terraform Outputs", () => {
1566
+ it("should create proper Terraform outputs", () => {
1567
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "TestRule", {
1568
+ name: "test-rule",
1569
+ ruleCollectionId: ruleCollection.id,
1570
+ priority: 100,
1571
+ action: "Deny",
1572
+ direction: "Inbound",
1573
+ protocol: "Tcp",
1574
+ });
1575
+ expect(rule.idOutput).toBeInstanceOf(cdktf.TerraformOutput);
1576
+ expect(rule.nameOutput).toBeInstanceOf(cdktf.TerraformOutput);
1577
+ expect(rule.provisioningStateOutput).toBeInstanceOf(cdktf.TerraformOutput);
1578
+ });
1579
+ it("should have proper resource references", () => {
1580
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "TestRule", {
1581
+ name: "test-rule",
1582
+ ruleCollectionId: ruleCollection.id,
1583
+ priority: 100,
1584
+ action: "Deny",
1585
+ direction: "Inbound",
1586
+ protocol: "Tcp",
1587
+ });
1588
+ expect(rule.id).toMatch(/^\$\{.*\.id\}$/);
1589
+ expect(rule.resourceName).toMatch(/^\$\{.*\.name\}$/);
1590
+ expect(rule.provisioningState).toMatch(/^\$\{.*\.output\.properties\.provisioningState\}$/);
1591
+ });
1592
+ });
1593
+ describe("Parent-Child Relationship", () => {
1594
+ it("should correctly reference parent rule collection", () => {
1595
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "TestRule", {
1596
+ name: "test-rule",
1597
+ ruleCollectionId: ruleCollection.id,
1598
+ priority: 100,
1599
+ action: "Deny",
1600
+ direction: "Inbound",
1601
+ protocol: "Tcp",
1602
+ });
1603
+ expect(rule.props.ruleCollectionId).toBe(ruleCollection.id);
1604
+ });
1605
+ });
1606
+ describe("CDK Synthesis", () => {
1607
+ it("should synthesize valid Terraform configuration", () => {
1608
+ new security_admin_rule_1.SecurityAdminRule(stack, "TestRule", {
1609
+ name: "test-rule",
1610
+ ruleCollectionId: ruleCollection.id,
1611
+ description: "Test security rule",
1612
+ priority: 100,
1613
+ action: "Deny",
1614
+ direction: "Inbound",
1615
+ protocol: "Tcp",
1616
+ destinationPortRanges: ["22"],
1617
+ });
1618
+ const synthesized = cdktf_1.Testing.synth(stack);
1619
+ expect(synthesized).toBeDefined();
1620
+ const stackConfig = JSON.parse(synthesized);
1621
+ expect(stackConfig.resource).toBeDefined();
1622
+ });
1623
+ });
1624
+ describe("Complex Rule Scenarios", () => {
1625
+ it("should handle rule with all properties specified", () => {
1626
+ const rule = new security_admin_rule_1.SecurityAdminRule(stack, "ComplexRule", {
1627
+ name: "complex-rule",
1628
+ ruleCollectionId: ruleCollection.id,
1629
+ description: "Complex security rule with all properties",
1630
+ priority: 150,
1631
+ action: "Deny",
1632
+ direction: "Inbound",
1633
+ protocol: "Tcp",
1634
+ sourcePortRanges: ["1024-65535"],
1635
+ destinationPortRanges: ["22", "3389"],
1636
+ sources: [
1637
+ { addressPrefix: "Internet", addressPrefixType: "ServiceTag" },
1638
+ { addressPrefix: "192.168.0.0/16", addressPrefixType: "IPPrefix" },
1639
+ ],
1640
+ destinations: [
1641
+ { addressPrefix: "10.0.0.0/8", addressPrefixType: "IPPrefix" },
1642
+ ],
1643
+ });
1644
+ expect(rule.props.priority).toBe(150);
1645
+ expect(rule.props.sourcePortRanges).toEqual(["1024-65535"]);
1646
+ expect(rule.props.destinationPortRanges).toEqual(["22", "3389"]);
1647
+ expect(rule.props.sources).toHaveLength(2);
1648
+ expect(rule.props.destinations).toHaveLength(1);
1649
+ });
1650
+ });
1651
+ });
1652
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlydHVhbC1uZXR3b3JrLW1hbmFnZXIuc3BlYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9henVyZS12aXJ0dWFsbmV0d29ya21hbmFnZXIvdGVzdC92aXJ0dWFsLW5ldHdvcmstbWFuYWdlci5zcGVjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7OztHQU9HOztBQUVILGlDQUFnQztBQUNoQywrQkFBK0I7QUFDL0Isa0ZBRzJDO0FBQzNDLHdEQUF1RTtBQUN2RSxvRkFHNEM7QUFDNUMsc0ZBRzZDO0FBQzdDLG9FQUdvQztBQUNwQywwRkFHK0M7QUFDL0MsNEVBR3dDO0FBRXhDLFFBQVEsQ0FBQyx1QkFBdUIsRUFBRSxHQUFHLEVBQUU7SUFDckMsSUFBSSxHQUFjLENBQUM7SUFDbkIsSUFBSSxLQUEyQixDQUFDO0lBRWhDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7UUFDZCxHQUFHLEdBQUcsZUFBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ3BCLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxjQUFjLENBQUMsR0FBRyxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQ3RELENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLDJCQUEyQixFQUFFLEdBQUcsRUFBRTtRQUN6QyxFQUFFLENBQUMsMEVBQTBFLEVBQUUsR0FBRyxFQUFFO1lBQ2xGLE1BQU0sS0FBSyxHQUErQjtnQkFDeEMsSUFBSSxFQUFFLHNCQUFzQjtnQkFDNUIsUUFBUSxFQUFFLFFBQVE7Z0JBQ2xCLGVBQWUsRUFDYiw0RUFBNEU7Z0JBQzlFLG9CQUFvQixFQUFFO29CQUNwQixhQUFhLEVBQUU7d0JBQ2IscURBQXFEO3FCQUN0RDtpQkFDRjtnQkFDRCwyQkFBMkIsRUFBRSxDQUFDLGNBQWMsRUFBRSxlQUFlLENBQUM7YUFDL0QsQ0FBQztZQUVGLE1BQU0sT0FBTyxHQUFHLElBQUksK0NBQXFCLENBQUMsS0FBSyxFQUFFLGFBQWEsRUFBRSxLQUFLLENB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QUUsWUFBWSxFQUFFLGlCQUFpQixFQUFFLFVBQVUsRUFBRTtpQkFDL0Q7YUFDRixDQUFDLENBQUM7WUFFSCxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDdEMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDO1lBQzVELE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDakUsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzNDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsRCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbXByZWhlbnNpdmUgdGVzdHMgZm9yIHRoZSBWaXJ0dWFsIE5ldHdvcmsgTWFuYWdlciBpbXBsZW1lbnRhdGlvblxuICpcbiAqIFRoaXMgdGVzdCBzdWl0ZSB2YWxpZGF0ZXMgdGhlIFZpcnR1YWxOZXR3b3JrTWFuYWdlciBjbGFzcyBhbmQgYWxsIGNoaWxkIHJlc291cmNlXG4gKiBjb25zdHJ1Y3RzIHVzaW5nIHRoZSBBemFwaVJlc291cmNlIGZyYW1ld29yay4gVGVzdHMgY292ZXIgYXV0b21hdGljIHZlcnNpb24gcmVzb2x1dGlvbixcbiAqIGV4cGxpY2l0IHZlcnNpb24gcGlubmluZywgc2NoZW1hIHZhbGlkYXRpb24sIHByb3BlcnR5IHRyYW5zZm9ybWF0aW9uLCByZXNvdXJjZSBjcmVhdGlvbixcbiAqIGFuZCBwYXJlbnQtY2hpbGQgcmVsYXRpb25zaGlwcy5cbiAqL1xuXG5pbXBvcnQgeyBUZXN0aW5nIH0gZnJvbSBcImNka3RmXCI7XG5pbXBvcnQgKiBhcyBjZGt0ZiBmcm9tIFwiY2RrdGZcIjtcbmltcG9ydCB7XG4gIENvbm5lY3Rpdml0eUNvbmZpZ3VyYXRpb24sXG4gIENvbm5lY3Rpdml0eUNvbmZpZ3VyYXRpb25Qcm9wcyxcbn0gZnJvbSBcIi4uL2xpYi9jb25uZWN0aXZpdHktY29uZmlndXJhdGlvblwiO1xuaW1wb3J0IHsgTmV0d29ya0dyb3VwLCBOZXR3b3JrR3JvdXBQcm9wcyB9IGZyb20gXCIuLi9saWIvbmV0d29yay1ncm91cFwiO1xuaW1wb3J0IHtcbiAgTmV0d29ya0dyb3VwU3RhdGljTWVtYmVyLFxuICBOZXR3b3JrR3JvdXBTdGF0aWNNZW1iZXJQcm9wcyxcbn0gZnJvbSBcIi4uL2xpYi9uZXR3b3JrLWdyb3VwLXN0YXRpYy1tZW1iZXJcIjtcbmltcG9ydCB7XG4gIFNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uLFxuICBTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvblByb3BzLFxufSBmcm9tIFwiLi4vbGliL3NlY3VyaXR5LWFkbWluLWNvbmZpZ3VyYXRpb25cIjtcbmltcG9ydCB7XG4gIFNlY3VyaXR5QWRtaW5SdWxlLFxuICBTZWN1cml0eUFkbWluUnVsZVByb3BzLFxufSBmcm9tIFwiLi4vbGliL3NlY3VyaXR5LWFkbWluLXJ1bGVcIjtcbmltcG9ydCB7XG4gIFNlY3VyaXR5QWRtaW5SdWxlQ29sbGVjdGlvbixcbiAgU2VjdXJpdHlBZG1pblJ1bGVDb2xsZWN0aW9uUHJvcHMsXG59IGZyb20gXCIuLi9saWIvc2VjdXJpdHktYWRtaW4tcnVsZS1jb2xsZWN0aW9uXCI7XG5pbXBvcnQge1xuICBWaXJ0dWFsTmV0d29ya01hbmFnZXIsXG4gIFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzLFxufSBmcm9tIFwiLi4vbGliL3ZpcnR1YWwtbmV0d29yay1tYW5hZ2VyXCI7XG5cbmRlc2NyaWJlKFwiVmlydHVhbE5ldHdvcmtNYW5hZ2VyXCIsICgpID0+IHtcbiAgbGV0IGFwcDogY2RrdGYuQXBwO1xuICBsZXQgc3RhY2s6IGNka3RmLlRlcnJhZm9ybVN0YWNrO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIGFwcCA9IFRlc3RpbmcuYXBwKCk7XG4gICAgc3RhY2sgPSBuZXcgY2RrdGYuVGVycmFmb3JtU3RhY2soYXBwLCBcInRlc3Qtc3RhY2tcIik7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiQmFzaWMgSW5zdGFudGlhdGlvbiBUZXN0c1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIGEgVmlydHVhbCBOZXR3b3JrIE1hbmFnZXIgd2l0aCBtaW5pbXVtIHJlcXVpcmVkIHByb3BlcnRpZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIiwgXCJTZWN1cml0eUFkbWluXCJdLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QobWFuYWdlcikudG9CZUluc3RhbmNlT2YoVmlydHVhbE5ldHdvcmtNYW5hZ2VyKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzKS50b0JlKHByb3BzKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyLnJlc291cmNlTmFtZSkudG9CZURlZmluZWQoKTtcblxuICAgICAgY29uc3Qgc3ludGhlc2l6ZWQgPSBUZXN0aW5nLnN5bnRoKHN0YWNrKTtcbiAgICAgIGV4cGVjdChzeW50aGVzaXplZCkudG9Db250YWluKFwiTWljcm9zb2Z0Lk5ldHdvcmsvbmV0d29ya01hbmFnZXJzXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIGEgVmlydHVhbCBOZXR3b3JrIE1hbmFnZXIgd2l0aCBhbGwgcHJvcGVydGllc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogVmlydHVhbE5ldHdvcmtNYW5hZ2VyUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1uZXR3b3JrLW1hbmFnZXItZnVsbFwiLFxuICAgICAgICBsb2NhdGlvbjogXCJ3ZXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgICBzdWJzY3JpcHRpb25zOiBbXG4gICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiLFxuICAgICAgICAgIF0sXG4gICAgICAgICAgbWFuYWdlbWVudEdyb3VwczogW1xuICAgICAgICAgICAgXCIvcHJvdmlkZXJzL01pY3Jvc29mdC5NYW5hZ2VtZW50L21hbmFnZW1lbnRHcm91cHMvbWcxXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIiwgXCJTZWN1cml0eUFkbWluXCJdLFxuICAgICAgICBkZXNjcmlwdGlvbjogXCJUZXN0IG5ldHdvcmsgbWFuYWdlciB3aXRoIGFsbCBwcm9wZXJ0aWVzXCIsXG4gICAgICAgIHRhZ3M6IHtcbiAgICAgICAgICBlbnZpcm9ubWVudDogXCJ0ZXN0XCIsXG4gICAgICAgICAgcHJvamVjdDogXCJjZGt0Zi1jb25zdHJ1Y3RzXCIsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtYW5hZ2VyID0gbmV3IFZpcnR1YWxOZXR3b3JrTWFuYWdlcihzdGFjaywgXCJUZXN0TWFuYWdlclwiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzKS50b0JlKHByb3BzKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLmRlc2NyaXB0aW9uKS50b0JlKFxuICAgICAgICBcIlRlc3QgbmV0d29yayBtYW5hZ2VyIHdpdGggYWxsIHByb3BlcnRpZXNcIixcbiAgICAgICk7XG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy50YWdzKS50b0VxdWFsKHtcbiAgICAgICAgZW52aXJvbm1lbnQ6IFwidGVzdFwiLFxuICAgICAgICBwcm9qZWN0OiBcImNka3RmLWNvbnN0cnVjdHNcIixcbiAgICAgIH0pO1xuICAgICAgZXhwZWN0KG1hbmFnZXIudGFncykudG9FcXVhbChwcm9wcy50YWdzKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJGcmFtZXdvcmsgSW50ZWdyYXRpb24gVGVzdHNcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIHVzZSBkZWZhdWx0IEFQSSB2ZXJzaW9uIHdoZW4gbm9uZSBzcGVjaWZpZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIl0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtYW5hZ2VyID0gbmV3IFZpcnR1YWxOZXR3b3JrTWFuYWdlcihzdGFjaywgXCJUZXN0TWFuYWdlclwiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdChtYW5hZ2VyLnJlc29sdmVkQXBpVmVyc2lvbikudG9CZShcIjIwMjQtMDUtMDFcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCB1c2Ugc3BlY2lmaWVkIEFQSSB2ZXJzaW9uIHdoZW4gcHJvdmlkZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBhcGlWZXJzaW9uOiBcIjIwMjMtMTEtMDFcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgICBzdWJzY3JpcHRpb25zOiBbXG4gICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiU2VjdXJpdHlBZG1pblwiXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hbmFnZXIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHByb3BzKTtcblxuICAgICAgZXhwZWN0KG1hbmFnZXIucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyMy0xMS0wMVwiKTtcblxuICAgICAgY29uc3Qgc3ludGhlc2l6ZWQgPSBUZXN0aW5nLnN5bnRoKHN0YWNrKTtcbiAgICAgIGV4cGVjdChzeW50aGVzaXplZCkudG9Db250YWluKFwiQDIwMjMtMTEtMDFcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCByZWdpc3RlciBzY2hlbWFzIG9uIGZpcnN0IGluc3RhbnRpYXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIl0sXG4gICAgICB9O1xuXG4gICAgICAvLyBGaXJzdCBpbnN0YW50aWF0aW9uIHNob3VsZCByZWdpc3RlciBzY2hlbWFzXG4gICAgICBjb25zdCBtYW5hZ2VyMSA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXIxXCIsIHByb3BzKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyMSkudG9CZUluc3RhbmNlT2YoVmlydHVhbE5ldHdvcmtNYW5hZ2VyKTtcblxuICAgICAgLy8gU2Vjb25kIGluc3RhbnRpYXRpb24gc2hvdWxkIG5vdCByZS1yZWdpc3RlclxuICAgICAgY29uc3QgbWFuYWdlcjIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyMlwiLCB7XG4gICAgICAgIC4uLnByb3BzLFxuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyLTJcIixcbiAgICAgIH0pO1xuICAgICAgZXhwZWN0KG1hbmFnZXIyKS50b0JlSW5zdGFuY2VPZihWaXJ0dWFsTmV0d29ya01hbmFnZXIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlByb3BlcnR5IFZhbGlkYXRpb24gVGVzdHNcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIHByb3Blcmx5IGZvcm1hdCBuZXR3b3JrTWFuYWdlclNjb3BlcyB3aXRoIHN1YnNjcmlwdGlvbnNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzExMTExMTExLTExMTEtMTExMS0xMTExLTExMTExMTExMTExMVwiLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCJdLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy5uZXR3b3JrTWFuYWdlclNjb3Blcy5zdWJzY3JpcHRpb25zKS50b0hhdmVMZW5ndGgoMik7XG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy5uZXR3b3JrTWFuYWdlclNjb3Blcy5zdWJzY3JpcHRpb25zKS50b0NvbnRhaW4oXG4gICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBzeW50aGVzaXplZCA9IFRlc3Rpbmcuc3ludGgoc3RhY2spO1xuICAgICAgY29uc3Qgc3RhY2tDb25maWcgPSBKU09OLnBhcnNlKHN5bnRoZXNpemVkKTtcbiAgICAgIGV4cGVjdChzdGFja0NvbmZpZy5yZXNvdXJjZSkudG9CZURlZmluZWQoKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHByb3Blcmx5IGZvcm1hdCBuZXR3b3JrTWFuYWdlclNjb3BlcyB3aXRoIG1hbmFnZW1lbnQgZ3JvdXBzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBWaXJ0dWFsTmV0d29ya01hbmFnZXJQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LW5ldHdvcmstbWFuYWdlclwiLFxuICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgICBtYW5hZ2VtZW50R3JvdXBzOiBbXG4gICAgICAgICAgICBcIi9wcm92aWRlcnMvTWljcm9zb2Z0Lk1hbmFnZW1lbnQvbWFuYWdlbWVudEdyb3Vwcy9tZzFcIixcbiAgICAgICAgICAgIFwiL3Byb3ZpZGVycy9NaWNyb3NvZnQuTWFuYWdlbWVudC9tYW5hZ2VtZW50R3JvdXBzL21nMlwiLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiU2VjdXJpdHlBZG1pblwiXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hbmFnZXIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHByb3BzKTtcblxuICAgICAgZXhwZWN0KG1hbmFnZXIucHJvcHMubmV0d29ya01hbmFnZXJTY29wZXMubWFuYWdlbWVudEdyb3VwcykudG9IYXZlTGVuZ3RoKFxuICAgICAgICAyLFxuICAgICAgKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLm5ldHdvcmtNYW5hZ2VyU2NvcGVzLm1hbmFnZW1lbnRHcm91cHMpLnRvQ29udGFpbihcbiAgICAgICAgXCIvcHJvdmlkZXJzL01pY3Jvc29mdC5NYW5hZ2VtZW50L21hbmFnZW1lbnRHcm91cHMvbWcxXCIsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBzeW50aGVzaXplZCA9IFRlc3Rpbmcuc3ludGgoc3RhY2spO1xuICAgICAgY29uc3Qgc3RhY2tDb25maWcgPSBKU09OLnBhcnNlKHN5bnRoZXNpemVkKTtcbiAgICAgIGV4cGVjdChzdGFja0NvbmZpZy5yZXNvdXJjZSkudG9CZURlZmluZWQoKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHByb3Blcmx5IGZvcm1hdCBuZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXMgd2l0aCBDb25uZWN0aXZpdHkgYW5kIFNlY3VyaXR5QWRtaW5cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIiwgXCJTZWN1cml0eUFkbWluXCJdLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy5uZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXMpLnRvSGF2ZUxlbmd0aCgyKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLm5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlcykudG9Db250YWluKFxuICAgICAgICBcIkNvbm5lY3Rpdml0eVwiLFxuICAgICAgKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLm5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlcykudG9Db250YWluKFxuICAgICAgICBcIlNlY3VyaXR5QWRtaW5cIixcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBwcm9wZXJseSBmb3JtYXQgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzIHdpdGggUm91dGluZ1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogVmlydHVhbE5ldHdvcmtNYW5hZ2VyUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1uZXR3b3JrLW1hbmFnZXJcIixcbiAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgIHJlc291cmNlR3JvdXBJZDpcbiAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVzOiB7XG4gICAgICAgICAgc3Vic2NyaXB0aW9uczogW1xuICAgICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDBcIixcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXM6IFtcIlJvdXRpbmdcIl0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtYW5hZ2VyID0gbmV3IFZpcnR1YWxOZXR3b3JrTWFuYWdlcihzdGFjaywgXCJUZXN0TWFuYWdlclwiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLm5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlcykudG9IYXZlTGVuZ3RoKDEpO1xuICAgICAgZXhwZWN0KG1hbmFnZXIucHJvcHMubmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzKS50b0NvbnRhaW4oXCJSb3V0aW5nXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlRhZyBNYW5hZ2VtZW50IFRlc3RzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBhZGQgdGFncyB1c2luZyBhZGRUYWcgbWV0aG9kXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBWaXJ0dWFsTmV0d29ya01hbmFnZXJQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LW5ldHdvcmstbWFuYWdlclwiLFxuICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgICBzdWJzY3JpcHRpb25zOiBbXG4gICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCJdLFxuICAgICAgICB0YWdzOiB7XG4gICAgICAgICAgZW52aXJvbm1lbnQ6IFwidGVzdFwiLFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwgcHJvcHMpO1xuXG4gICAgICBtYW5hZ2VyLmFkZFRhZyhcInByb2plY3RcIiwgXCJuZXR3b3JrLWluZnJhc3RydWN0dXJlXCIpO1xuXG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy50YWdzIS5wcm9qZWN0KS50b0JlKFwibmV0d29yay1pbmZyYXN0cnVjdHVyZVwiKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLnRhZ3MhLmVudmlyb25tZW50KS50b0JlKFwidGVzdFwiKTtcblxuICAgICAgY29uc3Qgc3ludGhlc2l6ZWQgPSBUZXN0aW5nLnN5bnRoKHN0YWNrKTtcbiAgICAgIGV4cGVjdChzeW50aGVzaXplZCkudG9Db250YWluKFwibmV0d29yay1pbmZyYXN0cnVjdHVyZVwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHJlbW92ZSB0YWdzIHVzaW5nIHJlbW92ZVRhZyBtZXRob2RcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIl0sXG4gICAgICAgIHRhZ3M6IHtcbiAgICAgICAgICBlbnZpcm9ubWVudDogXCJ0ZXN0XCIsXG4gICAgICAgICAgdGVtcG9yYXJ5OiBcInRydWVcIixcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hbmFnZXIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHByb3BzKTtcblxuICAgICAgbWFuYWdlci5yZW1vdmVUYWcoXCJ0ZW1wb3JhcnlcIik7XG5cbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLnRhZ3MhLnRlbXBvcmFyeSkudG9CZVVuZGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KG1hbmFnZXIucHJvcHMudGFncyEuZW52aXJvbm1lbnQpLnRvQmUoXCJ0ZXN0XCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgYWRkIHRhZ3Mgd2hlbiBubyBpbml0aWFsIHRhZ3MgZXhpc3RcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIl0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtYW5hZ2VyID0gbmV3IFZpcnR1YWxOZXR3b3JrTWFuYWdlcihzdGFjaywgXCJUZXN0TWFuYWdlclwiLCBwcm9wcyk7XG5cbiAgICAgIG1hbmFnZXIuYWRkVGFnKFwiZmlyc3RUYWdcIiwgXCJmaXJzdFZhbHVlXCIpO1xuXG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy50YWdzIS5maXJzdFRhZykudG9CZShcImZpcnN0VmFsdWVcIik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiVGVycmFmb3JtIE91dHB1dCBUZXN0c1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIHByb3BlciBUZXJyYWZvcm0gb3V0cHV0c1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogVmlydHVhbE5ldHdvcmtNYW5hZ2VyUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1uZXR3b3JrLW1hbmFnZXJcIixcbiAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgIHJlc291cmNlR3JvdXBJZDpcbiAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVzOiB7XG4gICAgICAgICAgc3Vic2NyaXB0aW9uczogW1xuICAgICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDBcIixcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXM6IFtcIkNvbm5lY3Rpdml0eVwiXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hbmFnZXIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHByb3BzKTtcblxuICAgICAgZXhwZWN0KG1hbmFnZXIuaWRPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QobWFuYWdlci5uYW1lT3V0cHV0KS50b0JlSW5zdGFuY2VPZihjZGt0Zi5UZXJyYWZvcm1PdXRwdXQpO1xuICAgICAgZXhwZWN0KG1hbmFnZXIubG9jYXRpb25PdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QobWFuYWdlci50YWdzT3V0cHV0KS50b0JlSW5zdGFuY2VPZihjZGt0Zi5UZXJyYWZvcm1PdXRwdXQpO1xuICAgICAgZXhwZWN0KG1hbmFnZXIuc2NvcGVPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QobWFuYWdlci5zY29wZUFjY2Vzc2VzT3V0cHV0KS50b0JlSW5zdGFuY2VPZihjZGt0Zi5UZXJyYWZvcm1PdXRwdXQpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaGF2ZSBwcm9wZXIgcmVzb3VyY2UgcmVmZXJlbmNlcyBpbiBvdXRwdXRzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBWaXJ0dWFsTmV0d29ya01hbmFnZXJQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LW5ldHdvcmstbWFuYWdlclwiLFxuICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgICBzdWJzY3JpcHRpb25zOiBbXG4gICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCJdLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QobWFuYWdlci5pZCkudG9NYXRjaCgvXlxcJFxcey4qXFwuaWRcXH0kLyk7XG4gICAgICBleHBlY3QobWFuYWdlci5yZXNvdXJjZU5hbWUpLnRvTWF0Y2goL15cXCRcXHsuKlxcLm5hbWVcXH0kLyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiTGlmZWN5Y2xlIE1hbmFnZW1lbnQgVGVzdHNcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGFwcGx5IGlnbm9yZV9jaGFuZ2VzIHdoZW4gc3BlY2lmaWVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBWaXJ0dWFsTmV0d29ya01hbmFnZXJQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LW5ldHdvcmstbWFuYWdlclwiLFxuICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgICBzdWJzY3JpcHRpb25zOiBbXG4gICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCJdLFxuICAgICAgICBpZ25vcmVDaGFuZ2VzOiBbXCJ0YWdzXCJdLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy5pZ25vcmVDaGFuZ2VzKS50b0VxdWFsKFtcInRhZ3NcIl0pO1xuXG4gICAgICBjb25zdCBzeW50aGVzaXplZCA9IFRlc3Rpbmcuc3ludGgoc3RhY2spO1xuICAgICAgY29uc3Qgc3RhY2tDb25maWcgPSBKU09OLnBhcnNlKHN5bnRoZXNpemVkKTtcbiAgICAgIGV4cGVjdChzdGFja0NvbmZpZy5yZXNvdXJjZSkudG9CZURlZmluZWQoKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhbmRsZSBtdWx0aXBsZSBpZ25vcmVfY2hhbmdlcyBwcm9wZXJ0aWVzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBWaXJ0dWFsTmV0d29ya01hbmFnZXJQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LW5ldHdvcmstbWFuYWdlclwiLFxuICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgICBzdWJzY3JpcHRpb25zOiBbXG4gICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCJdLFxuICAgICAgICBpZ25vcmVDaGFuZ2VzOiBbXCJ0YWdzXCIsIFwiZGVzY3JpcHRpb25cIl0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtYW5hZ2VyID0gbmV3IFZpcnR1YWxOZXR3b3JrTWFuYWdlcihzdGFjaywgXCJUZXN0TWFuYWdlclwiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLmlnbm9yZUNoYW5nZXMpLnRvSGF2ZUxlbmd0aCgyKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLmlnbm9yZUNoYW5nZXMpLnRvQ29udGFpbihcInRhZ3NcIik7XG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy5pZ25vcmVDaGFuZ2VzKS50b0NvbnRhaW4oXCJkZXNjcmlwdGlvblwiKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJDREsgU3ludGhlc2lzIFRlc3RzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBzeW50aGVzaXplIHZhbGlkIFRlcnJhZm9ybSBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBWaXJ0dWFsTmV0d29ya01hbmFnZXJQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LW5ldHdvcmstbWFuYWdlclwiLFxuICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgICBzdWJzY3JpcHRpb25zOiBbXG4gICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCIsIFwiU2VjdXJpdHlBZG1pblwiXSxcbiAgICAgICAgZGVzY3JpcHRpb246IFwiVGVzdCBuZXR3b3JrIG1hbmFnZXJcIixcbiAgICAgICAgdGFnczoge1xuICAgICAgICAgIGVudmlyb25tZW50OiBcInRlc3RcIixcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwgcHJvcHMpO1xuXG4gICAgICBjb25zdCBzeW50aGVzaXplZCA9IFRlc3Rpbmcuc3ludGgoc3RhY2spO1xuICAgICAgZXhwZWN0KHN5bnRoZXNpemVkKS50b0JlRGVmaW5lZCgpO1xuXG4gICAgICBjb25zdCBzdGFja0NvbmZpZyA9IEpTT04ucGFyc2Uoc3ludGhlc2l6ZWQpO1xuICAgICAgZXhwZWN0KHN0YWNrQ29uZmlnLnJlc291cmNlKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaGFuZGxlIG11bHRpcGxlIFZpcnR1YWwgTmV0d29yayBNYW5hZ2VycyBpbiB0aGUgc2FtZSBzdGFja1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczE6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyLTFcIixcbiAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgIHJlc291cmNlR3JvdXBJZDpcbiAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVzOiB7XG4gICAgICAgICAgc3Vic2NyaXB0aW9uczogW1xuICAgICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDBcIixcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXM6IFtcIkNvbm5lY3Rpdml0eVwiXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHByb3BzMjogVmlydHVhbE5ldHdvcmtNYW5hZ2VyUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1uZXR3b3JrLW1hbmFnZXItMlwiLFxuICAgICAgICBsb2NhdGlvbjogXCJ3ZXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgYXBpVmVyc2lvbjogXCIyMDIzLTExLTAxXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVzOiB7XG4gICAgICAgICAgc3Vic2NyaXB0aW9uczogW1xuICAgICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8xMTExMTExMS0xMTExLTExMTEtMTExMS0xMTExMTExMTExMTFcIixcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXM6IFtcIlNlY3VyaXR5QWRtaW5cIl0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtYW5hZ2VyMSA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXIxXCIsIHByb3BzMSk7XG4gICAgICBjb25zdCBtYW5hZ2VyMiA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXIyXCIsIHByb3BzMik7XG5cbiAgICAgIGV4cGVjdChtYW5hZ2VyMS5yZXNvbHZlZEFwaVZlcnNpb24pLnRvQmUoXCIyMDI0LTA1LTAxXCIpO1xuICAgICAgZXhwZWN0KG1hbmFnZXIyLnJlc29sdmVkQXBpVmVyc2lvbikudG9CZShcIjIwMjMtMTEtMDFcIik7XG5cbiAgICAgIGNvbnN0IHN5bnRoZXNpemVkID0gVGVzdGluZy5zeW50aChzdGFjayk7XG4gICAgICBleHBlY3Qoc3ludGhlc2l6ZWQpLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCB2ZXJpZnkgVGVycmFmb3JtIG91dHB1dCBzdHJ1Y3R1cmVcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIl0sXG4gICAgICB9O1xuXG4gICAgICBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHByb3BzKTtcblxuICAgICAgY29uc3Qgc3ludGhlc2l6ZWQgPSBUZXN0aW5nLnN5bnRoKHN0YWNrKTtcbiAgICAgIGNvbnN0IHN0YWNrQ29uZmlnID0gSlNPTi5wYXJzZShzeW50aGVzaXplZCk7XG5cbiAgICAgIGV4cGVjdChzdGFja0NvbmZpZy5yZXNvdXJjZSkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChzdGFja0NvbmZpZy5vdXRwdXQpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3Qoc3RhY2tDb25maWcub3V0cHV0LmlkKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KHN0YWNrQ29uZmlnLm91dHB1dC5uYW1lKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KHN0YWNrQ29uZmlnLm91dHB1dC5sb2NhdGlvbikudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChzdGFja0NvbmZpZy5vdXRwdXQudGFncykudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChzdGFja0NvbmZpZy5vdXRwdXQuc2NvcGUpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3Qoc3RhY2tDb25maWcub3V0cHV0LnNjb3BlQWNjZXNzZXMpLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiUmVzb3VyY2UgVHlwZSBhbmQgVmVyc2lvbiBUZXN0c1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgaGF2ZSBjb3JyZWN0IHJlc291cmNlIHR5cGVcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIl0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtYW5hZ2VyID0gbmV3IFZpcnR1YWxOZXR3b3JrTWFuYWdlcihzdGFjaywgXCJUZXN0TWFuYWdlclwiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdChtYW5hZ2VyKS50b0JlSW5zdGFuY2VPZihWaXJ0dWFsTmV0d29ya01hbmFnZXIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgc3VwcG9ydCBhbGwgcmVnaXN0ZXJlZCBBUEkgdmVyc2lvbnNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgdmVyc2lvbnMgPSBbXCIyMDIzLTExLTAxXCIsIFwiMjAyNC0wNS0wMVwiXTtcblxuICAgICAgdmVyc2lvbnMuZm9yRWFjaCgodmVyc2lvbikgPT4ge1xuICAgICAgICBjb25zdCB0ZXN0U3RhY2sgPSBuZXcgY2RrdGYuVGVycmFmb3JtU3RhY2soYXBwLCBgU3RhY2stJHt2ZXJzaW9ufWApO1xuICAgICAgICBjb25zdCBtYW5hZ2VyID0gbmV3IFZpcnR1YWxOZXR3b3JrTWFuYWdlcihcbiAgICAgICAgICB0ZXN0U3RhY2ssXG4gICAgICAgICAgYE1hbmFnZXItJHt2ZXJzaW9ufWAsXG4gICAgICAgICAge1xuICAgICAgICAgICAgbmFtZTogYG1hbmFnZXItJHt2ZXJzaW9ufWAsXG4gICAgICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgICAgIHJlc291cmNlR3JvdXBJZDpcbiAgICAgICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICAgICAgYXBpVmVyc2lvbjogdmVyc2lvbixcbiAgICAgICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVzOiB7XG4gICAgICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiLFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCJdLFxuICAgICAgICAgIH0sXG4gICAgICAgICk7XG5cbiAgICAgICAgZXhwZWN0KG1hbmFnZXIucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKHZlcnNpb24pO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCB1c2UgbGF0ZXN0IHZlcnNpb24gYXMgZGVmYXVsdFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogVmlydHVhbE5ldHdvcmtNYW5hZ2VyUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1uZXR3b3JrLW1hbmFnZXJcIixcbiAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgIHJlc291cmNlR3JvdXBJZDpcbiAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVzOiB7XG4gICAgICAgICAgc3Vic2NyaXB0aW9uczogW1xuICAgICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDBcIixcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXM6IFtcIkNvbm5lY3Rpdml0eVwiXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hbmFnZXIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHByb3BzKTtcblxuICAgICAgZXhwZWN0KG1hbmFnZXIucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyNC0wNS0wMVwiKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJEZXNjcmlwdGlvbiBQcm9wZXJ0eSBUZXN0c1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIFZpcnR1YWwgTmV0d29yayBNYW5hZ2VyIHdpdGggZGVzY3JpcHRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJDb25uZWN0aXZpdHlcIl0sXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIkNlbnRyYWwgbmV0d29yayBtYW5hZ2VtZW50IGZvciBwcm9kdWN0aW9uIHdvcmtsb2Fkc1wiLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy5kZXNjcmlwdGlvbikudG9CZShcbiAgICAgICAgXCJDZW50cmFsIG5ldHdvcmsgbWFuYWdlbWVudCBmb3IgcHJvZHVjdGlvbiB3b3JrbG9hZHNcIixcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgVmlydHVhbCBOZXR3b3JrIE1hbmFnZXIgd2l0aG91dCBkZXNjcmlwdGlvblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogVmlydHVhbE5ldHdvcmtNYW5hZ2VyUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1uZXR3b3JrLW1hbmFnZXJcIixcbiAgICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICAgIHJlc291cmNlR3JvdXBJZDpcbiAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVzOiB7XG4gICAgICAgICAgc3Vic2NyaXB0aW9uczogW1xuICAgICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDBcIixcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXM6IFtcIkNvbm5lY3Rpdml0eVwiXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hbmFnZXIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHByb3BzKTtcblxuICAgICAgZXhwZWN0KG1hbmFnZXIucHJvcHMuZGVzY3JpcHRpb24pLnRvQmVVbmRlZmluZWQoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJNaXhlZCBTY29wZSBDb25maWd1cmF0aW9uIFRlc3RzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBzdXBwb3J0IGJvdGggc3Vic2NyaXB0aW9ucyBhbmQgbWFuYWdlbWVudCBncm91cHMgaW4gc2NvcGVcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgICBtYW5hZ2VtZW50R3JvdXBzOiBbXG4gICAgICAgICAgICBcIi9wcm92aWRlcnMvTWljcm9zb2Z0Lk1hbmFnZW1lbnQvbWFuYWdlbWVudEdyb3Vwcy9tZzFcIixcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXM6IFtcIkNvbm5lY3Rpdml0eVwiLCBcIlNlY3VyaXR5QWRtaW5cIl0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtYW5hZ2VyID0gbmV3IFZpcnR1YWxOZXR3b3JrTWFuYWdlcihzdGFjaywgXCJUZXN0TWFuYWdlclwiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLm5ldHdvcmtNYW5hZ2VyU2NvcGVzLnN1YnNjcmlwdGlvbnMpLnRvSGF2ZUxlbmd0aCgxKTtcbiAgICAgIGV4cGVjdChtYW5hZ2VyLnByb3BzLm5ldHdvcmtNYW5hZ2VyU2NvcGVzLm1hbmFnZW1lbnRHcm91cHMpLnRvSGF2ZUxlbmd0aChcbiAgICAgICAgMSxcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBzdXBwb3J0IGFsbCB0aHJlZSBzY29wZSBhY2Nlc3MgdHlwZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFZpcnR1YWxOZXR3b3JrTWFuYWdlclByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtbmV0d29yay1tYW5hZ2VyXCIsXG4gICAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcbiAgICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCIsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXG4gICAgICAgICAgXCJDb25uZWN0aXZpdHlcIixcbiAgICAgICAgICBcIlNlY3VyaXR5QWRtaW5cIixcbiAgICAgICAgICBcIlJvdXRpbmdcIixcbiAgICAgICAgXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG1hbmFnZXIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHByb3BzKTtcblxuICAgICAgZXhwZWN0KG1hbmFnZXIucHJvcHMubmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzKS50b0hhdmVMZW5ndGgoMyk7XG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy5uZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXMpLnRvQ29udGFpbihcbiAgICAgICAgXCJDb25uZWN0aXZpdHlcIixcbiAgICAgICk7XG4gICAgICBleHBlY3QobWFuYWdlci5wcm9wcy5uZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXMpLnRvQ29udGFpbihcbiAgICAgICAgXCJTZWN1cml0eUFkbWluXCIsXG4gICAgICApO1xuICAgICAgZXhwZWN0KG1hbmFnZXIucHJvcHMubmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzKS50b0NvbnRhaW4oXCJSb3V0aW5nXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkNvbnZlbmllbmNlIE1ldGhvZHMgZm9yIENoaWxkIFJlc291cmNlc1wiLCAoKSA9PiB7XG4gICAgbGV0IG1hbmFnZXI6IFZpcnR1YWxOZXR3b3JrTWFuYWdlcjtcblxuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtbWFuYWdlclwiLFxuICAgICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgICBzdWJzY3JpcHRpb25zOiBbXG4gICAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiLFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCIsIFwiU2VjdXJpdHlBZG1pblwiXSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIE5ldHdvcmtHcm91cCB1c2luZyBjb252ZW5pZW5jZSBtZXRob2RcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgbmV0d29ya0dyb3VwID0gbWFuYWdlci5hZGROZXR3b3JrR3JvdXAoXCJwcm9kLWdyb3VwXCIsIHtcbiAgICAgICAgbmFtZTogXCJwcm9kdWN0aW9uLXZuZXRzXCIsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIlByb2R1Y3Rpb24gdmlydHVhbCBuZXR3b3Jrc1wiLFxuICAgICAgICBtZW1iZXJUeXBlOiBcIlZpcnR1YWxOZXR3b3JrXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KG5ldHdvcmtHcm91cCkudG9CZUluc3RhbmNlT2YoTmV0d29ya0dyb3VwKTtcbiAgICAgIGV4cGVjdChuZXR3b3JrR3JvdXAucHJvcHMubmV0d29ya01hbmFnZXJJZCkudG9CZShtYW5hZ2VyLmlkKTtcbiAgICAgIGV4cGVjdChuZXR3b3JrR3JvdXAucHJvcHMubmFtZSkudG9CZShcInByb2R1Y3Rpb24tdm5ldHNcIik7XG4gICAgICBleHBlY3QobmV0d29ya0dyb3VwLnByb3BzLmRlc2NyaXB0aW9uKS50b0JlKFxuICAgICAgICBcIlByb2R1Y3Rpb24gdmlydHVhbCBuZXR3b3Jrc1wiLFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBDb25uZWN0aXZpdHlDb25maWd1cmF0aW9uIHVzaW5nIGNvbnZlbmllbmNlIG1ldGhvZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBuZXR3b3JrR3JvdXAgPSBtYW5hZ2VyLmFkZE5ldHdvcmtHcm91cChcInByb2QtZ3JvdXBcIiwge1xuICAgICAgICBuYW1lOiBcInByb2R1Y3Rpb24tdm5ldHNcIixcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBjb25uZWN0aXZpdHlDb25maWcgPSBtYW5hZ2VyLmFkZENvbm5lY3Rpdml0eUNvbmZpZ3VyYXRpb24oXG4gICAgICAgIFwiaHViLXNwb2tlXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInByb2R1Y3Rpb24taHViLXNwb2tlXCIsXG4gICAgICAgICAgY29ubmVjdGl2aXR5VG9wb2xvZ3k6IFwiSHViQW5kU3Bva2VcIixcbiAgICAgICAgICBhcHBsaWVzVG9Hcm91cHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCxcbiAgICAgICAgICAgICAgZ3JvdXBDb25uZWN0aXZpdHk6IFwiTm9uZVwiLFxuICAgICAgICAgICAgICB1c2VIdWJHYXRld2F5OiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICAgIGh1YnM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgcmVzb3VyY2VJZDogXCIvc3Vic2NyaXB0aW9ucy90ZXN0L3ZpcnR1YWxOZXR3b3Jrcy9odWJcIixcbiAgICAgICAgICAgICAgcmVzb3VyY2VUeXBlOiBcIk1pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3Jrc1wiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbm5lY3Rpdml0eUNvbmZpZykudG9CZUluc3RhbmNlT2YoQ29ubmVjdGl2aXR5Q29uZmlndXJhdGlvbik7XG4gICAgICBleHBlY3QoY29ubmVjdGl2aXR5Q29uZmlnLnByb3BzLm5ldHdvcmtNYW5hZ2VySWQpLnRvQmUobWFuYWdlci5pZCk7XG4gICAgICBleHBlY3QoY29ubmVjdGl2aXR5Q29uZmlnLnByb3BzLmNvbm5lY3Rpdml0eVRvcG9sb2d5KS50b0JlKFwiSHViQW5kU3Bva2VcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgU2VjdXJpdHlBZG1pbkNvbmZpZ3VyYXRpb24gdXNpbmcgY29udmVuaWVuY2UgbWV0aG9kXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHNlY3VyaXR5Q29uZmlnID0gbWFuYWdlci5hZGRTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbihcInNlY3VyaXR5XCIsIHtcbiAgICAgICAgbmFtZTogXCJwcm9kdWN0aW9uLXNlY3VyaXR5XCIsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIkhpZ2gtcHJpb3JpdHkgc2VjdXJpdHkgcnVsZXNcIixcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3Qoc2VjdXJpdHlDb25maWcpLnRvQmVJbnN0YW5jZU9mKFNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uKTtcbiAgICAgIGV4cGVjdChzZWN1cml0eUNvbmZpZy5wcm9wcy5uZXR3b3JrTWFuYWdlcklkKS50b0JlKG1hbmFnZXIuaWQpO1xuICAgICAgZXhwZWN0KHNlY3VyaXR5Q29uZmlnLnByb3BzLm5hbWUpLnRvQmUoXCJwcm9kdWN0aW9uLXNlY3VyaXR5XCIpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcIk5ldHdvcmtHcm91cFwiLCAoKSA9PiB7XG4gIGxldCBhcHA6IGNka3RmLkFwcDtcbiAgbGV0IHN0YWNrOiBjZGt0Zi5UZXJyYWZvcm1TdGFjaztcbiAgbGV0IG1hbmFnZXI6IFZpcnR1YWxOZXR3b3JrTWFuYWdlcjtcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICBhcHAgPSBUZXN0aW5nLmFwcCgpO1xuICAgIHN0YWNrID0gbmV3IGNka3RmLlRlcnJhZm9ybVN0YWNrKGFwcCwgXCJ0ZXN0LXN0YWNrXCIpO1xuICAgIG1hbmFnZXIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHtcbiAgICAgIG5hbWU6IFwidGVzdC1tYW5hZ2VyXCIsXG4gICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgIHJlc291cmNlR3JvdXBJZDpcbiAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgc3Vic2NyaXB0aW9uczogW1wiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCJdLFxuICAgICAgfSxcbiAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCJdLFxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkJhc2ljIEluc3RhbnRpYXRpb25cIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBOZXR3b3JrR3JvdXAgd2l0aCBtaW5pbXVtIHJlcXVpcmVkIHByb3BlcnRpZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IE5ldHdvcmtHcm91cFByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtZ3JvdXBcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG5ldHdvcmtHcm91cCA9IG5ldyBOZXR3b3JrR3JvdXAoc3RhY2ssIFwiVGVzdEdyb3VwXCIsIHByb3BzKTtcblxuICAgICAgZXhwZWN0KG5ldHdvcmtHcm91cCkudG9CZUluc3RhbmNlT2YoTmV0d29ya0dyb3VwKTtcbiAgICAgIGV4cGVjdChuZXR3b3JrR3JvdXAucHJvcHMpLnRvQmUocHJvcHMpO1xuICAgICAgZXhwZWN0KG5ldHdvcmtHcm91cC5yZXNvdXJjZU5hbWUpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QobmV0d29ya0dyb3VwLmlkKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIE5ldHdvcmtHcm91cCB3aXRoIGFsbCBwcm9wZXJ0aWVzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBOZXR3b3JrR3JvdXBQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJwcm9kdWN0aW9uLXZuZXRzXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIlByb2R1Y3Rpb24gdmlydHVhbCBuZXR3b3JrcyBmb3IgRWFzdCBVU1wiLFxuICAgICAgICBtZW1iZXJUeXBlOiBcIlZpcnR1YWxOZXR3b3JrXCIsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBuZXR3b3JrR3JvdXAgPSBuZXcgTmV0d29ya0dyb3VwKHN0YWNrLCBcIlRlc3RHcm91cFwiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdChuZXR3b3JrR3JvdXAucHJvcHMuZGVzY3JpcHRpb24pLnRvQmUoXG4gICAgICAgIFwiUHJvZHVjdGlvbiB2aXJ0dWFsIG5ldHdvcmtzIGZvciBFYXN0IFVTXCIsXG4gICAgICApO1xuICAgICAgZXhwZWN0KG5ldHdvcmtHcm91cC5wcm9wcy5tZW1iZXJUeXBlKS50b0JlKFwiVmlydHVhbE5ldHdvcmtcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgTmV0d29ya0dyb3VwIHdpdGggU3VibmV0IG1lbWJlciB0eXBlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBOZXR3b3JrR3JvdXBQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJzdWJuZXQtZ3JvdXBcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICAgICAgbWVtYmVyVHlwZTogXCJTdWJuZXRcIixcbiAgICAgICAgZGVzY3JpcHRpb246IFwiU3VibmV0LWxldmVsIG5ldHdvcmsgZ3JvdXBcIixcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG5ldHdvcmtHcm91cCA9IG5ldyBOZXR3b3JrR3JvdXAoc3RhY2ssIFwiU3VibmV0R3JvdXBcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QobmV0d29ya0dyb3VwLnByb3BzLm1lbWJlclR5cGUpLnRvQmUoXCJTdWJuZXRcIik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiQVBJIFZlcnNpb24gSGFuZGxpbmdcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIHVzZSBkZWZhdWx0IEFQSSB2ZXJzaW9uIHdoZW4gbm9uZSBzcGVjaWZpZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgbmV0d29ya0dyb3VwID0gbmV3IE5ldHdvcmtHcm91cChzdGFjaywgXCJUZXN0R3JvdXBcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtZ3JvdXBcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QobmV0d29ya0dyb3VwLnJlc29sdmVkQXBpVmVyc2lvbikudG9CZShcIjIwMjQtMDUtMDFcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCB1c2Ugc3BlY2lmaWVkIEFQSSB2ZXJzaW9uIHdoZW4gcHJvdmlkZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgbmV0d29ya0dyb3VwID0gbmV3IE5ldHdvcmtHcm91cChzdGFjaywgXCJUZXN0R3JvdXBcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtZ3JvdXBcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICAgICAgYXBpVmVyc2lvbjogXCIyMDIzLTExLTAxXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KG5ldHdvcmtHcm91cC5yZXNvbHZlZEFwaVZlcnNpb24pLnRvQmUoXCIyMDIzLTExLTAxXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlRlcnJhZm9ybSBPdXRwdXRzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjcmVhdGUgcHJvcGVyIFRlcnJhZm9ybSBvdXRwdXRzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IG5ldHdvcmtHcm91cCA9IG5ldyBOZXR3b3JrR3JvdXAoc3RhY2ssIFwiVGVzdEdyb3VwXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWdyb3VwXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KG5ldHdvcmtHcm91cC5pZE91dHB1dCkudG9CZUluc3RhbmNlT2YoY2RrdGYuVGVycmFmb3JtT3V0cHV0KTtcbiAgICAgIGV4cGVjdChuZXR3b3JrR3JvdXAubmFtZU91dHB1dCkudG9CZUluc3RhbmNlT2YoY2RrdGYuVGVycmFmb3JtT3V0cHV0KTtcbiAgICAgIGV4cGVjdChuZXR3b3JrR3JvdXAucHJvdmlzaW9uaW5nU3RhdGVPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKFxuICAgICAgICBjZGt0Zi5UZXJyYWZvcm1PdXRwdXQsXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaGF2ZSBwcm9wZXIgcmVzb3VyY2UgcmVmZXJlbmNlc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBuZXR3b3JrR3JvdXAgPSBuZXcgTmV0d29ya0dyb3VwKHN0YWNrLCBcIlRlc3RHcm91cFwiLCB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1ncm91cFwiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChuZXR3b3JrR3JvdXAuaWQpLnRvTWF0Y2goL15cXCRcXHsuKlxcLmlkXFx9JC8pO1xuICAgICAgZXhwZWN0KG5ldHdvcmtHcm91cC5yZXNvdXJjZU5hbWUpLnRvTWF0Y2goL15cXCRcXHsuKlxcLm5hbWVcXH0kLyk7XG4gICAgICBleHBlY3QobmV0d29ya0dyb3VwLnByb3Zpc2lvbmluZ1N0YXRlKS50b01hdGNoKFxuICAgICAgICAvXlxcJFxcey4qXFwub3V0cHV0XFwucHJvcGVydGllc1xcLnByb3Zpc2lvbmluZ1N0YXRlXFx9JC8sXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkxpZmVjeWNsZSBNYW5hZ2VtZW50XCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBhcHBseSBpZ25vcmVfY2hhbmdlcyB3aGVuIHNwZWNpZmllZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBuZXR3b3JrR3JvdXAgPSBuZXcgTmV0d29ya0dyb3VwKHN0YWNrLCBcIlRlc3RHcm91cFwiLCB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1ncm91cFwiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgICAgICBpZ25vcmVDaGFuZ2VzOiBbXCJkZXNjcmlwdGlvblwiXSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QobmV0d29ya0dyb3VwLnByb3BzLmlnbm9yZUNoYW5nZXMpLnRvRXF1YWwoW1wiZGVzY3JpcHRpb25cIl0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkNESyBTeW50aGVzaXNcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIHN5bnRoZXNpemUgdmFsaWQgVGVycmFmb3JtIGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgbmV3IE5ldHdvcmtHcm91cChzdGFjaywgXCJUZXN0R3JvdXBcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtZ3JvdXBcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICAgICAgZGVzY3JpcHRpb246IFwiVGVzdCBuZXR3b3JrIGdyb3VwXCIsXG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgc3ludGhlc2l6ZWQgPSBUZXN0aW5nLnN5bnRoKHN0YWNrKTtcbiAgICAgIGV4cGVjdChzeW50aGVzaXplZCkudG9CZURlZmluZWQoKTtcbiAgICAgIGNvbnN0IHN0YWNrQ29uZmlnID0gSlNPTi5wYXJzZShzeW50aGVzaXplZCk7XG4gICAgICBleHBlY3Qoc3RhY2tDb25maWcucmVzb3VyY2UpLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKFwiTmV0d29ya0dyb3VwU3RhdGljTWVtYmVyXCIsICgpID0+IHtcbiAgbGV0IGFwcDogY2RrdGYuQXBwO1xuICBsZXQgc3RhY2s6IGNka3RmLlRlcnJhZm9ybVN0YWNrO1xuICBsZXQgbWFuYWdlcjogVmlydHVhbE5ldHdvcmtNYW5hZ2VyO1xuICBsZXQgbmV0d29ya0dyb3VwOiBOZXR3b3JrR3JvdXA7XG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgYXBwID0gVGVzdGluZy5hcHAoKTtcbiAgICBzdGFjayA9IG5ldyBjZGt0Zi5UZXJyYWZvcm1TdGFjayhhcHAsIFwidGVzdC1zdGFja1wiKTtcbiAgICBtYW5hZ2VyID0gbmV3IFZpcnR1YWxOZXR3b3JrTWFuYWdlcihzdGFjaywgXCJUZXN0TWFuYWdlclwiLCB7XG4gICAgICBuYW1lOiBcInRlc3QtbWFuYWdlclwiLFxuICAgICAgbG9jYXRpb246IFwiZWFzdHVzXCIsXG4gICAgICByZXNvdXJjZUdyb3VwSWQ6XG4gICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmdcIixcbiAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVzOiB7XG4gICAgICAgIHN1YnNjcmlwdGlvbnM6IFtcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiXSxcbiAgICAgIH0sXG4gICAgICBuZXR3b3JrTWFuYWdlclNjb3BlQWNjZXNzZXM6IFtcIkNvbm5lY3Rpdml0eVwiXSxcbiAgICB9KTtcbiAgICBuZXR3b3JrR3JvdXAgPSBuZXcgTmV0d29ya0dyb3VwKHN0YWNrLCBcIlRlc3RHcm91cFwiLCB7XG4gICAgICBuYW1lOiBcInRlc3QtZ3JvdXBcIixcbiAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiQmFzaWMgSW5zdGFudGlhdGlvblwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIFN0YXRpY01lbWJlciBmb3IgVk5ldFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogTmV0d29ya0dyb3VwU3RhdGljTWVtYmVyUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwidm5ldC1tZW1iZXJcIixcbiAgICAgICAgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCxcbiAgICAgICAgcmVzb3VyY2VJZDpcbiAgICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnL3Byb3ZpZGVycy9NaWNyb3NvZnQuTmV0d29yay92aXJ0dWFsTmV0d29ya3MvdGVzdC12bmV0XCIsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBtZW1iZXIgPSBuZXcgTmV0d29ya0dyb3VwU3RhdGljTWVtYmVyKHN0YWNrLCBcIlZuZXRNZW1iZXJcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QobWVtYmVyKS50b0JlSW5zdGFuY2VPZihOZXR3b3JrR3JvdXBTdGF0aWNNZW1iZXIpO1xuICAgICAgZXhwZWN0KG1lbWJlci5wcm9wcykudG9CZShwcm9wcyk7XG4gICAgICBleHBlY3QobWVtYmVyLnByb3BzLnJlc291cmNlSWQpLnRvQ29udGFpbihcInZpcnR1YWxOZXR3b3Jrc1wiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBTdGF0aWNNZW1iZXIgZm9yIFN1Ym5ldFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogTmV0d29ya0dyb3VwU3RhdGljTWVtYmVyUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwic3VibmV0LW1lbWJlclwiLFxuICAgICAgICBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkLFxuICAgICAgICByZXNvdXJjZUlkOlxuICAgICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwL3Jlc291cmNlR3JvdXBzL3Rlc3QtcmcvcHJvdmlkZXJzL01pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3Jrcy90ZXN0LXZuZXQvc3VibmV0cy90ZXN0LXN1Ym5ldFwiLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgbWVtYmVyID0gbmV3IE5ldHdvcmtHcm91cFN0YXRpY01lbWJlcihzdGFjaywgXCJTdWJuZXRNZW1iZXJcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QobWVtYmVyKS50b0JlSW5zdGFuY2VPZihOZXR3b3JrR3JvdXBTdGF0aWNNZW1iZXIpO1xuICAgICAgZXhwZWN0KG1lbWJlci5wcm9wcy5yZXNvdXJjZUlkKS50b0NvbnRhaW4oXCJzdWJuZXRzXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkFQSSBWZXJzaW9uIEhhbmRsaW5nXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCB1c2UgZGVmYXVsdCBBUEkgdmVyc2lvbiB3aGVuIG5vbmUgc3BlY2lmaWVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IG1lbWJlciA9IG5ldyBOZXR3b3JrR3JvdXBTdGF0aWNNZW1iZXIoc3RhY2ssIFwiVGVzdE1lbWJlclwiLCB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1tZW1iZXJcIixcbiAgICAgICAgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCxcbiAgICAgICAgcmVzb3VyY2VJZDogXCIvc3Vic2NyaXB0aW9ucy90ZXN0L3ZpcnR1YWxOZXR3b3Jrcy92bmV0MVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChtZW1iZXIucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyNC0wNS0wMVwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHVzZSBzcGVjaWZpZWQgQVBJIHZlcnNpb24gd2hlbiBwcm92aWRlZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBtZW1iZXIgPSBuZXcgTmV0d29ya0dyb3VwU3RhdGljTWVtYmVyKHN0YWNrLCBcIlRlc3RNZW1iZXJcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtbWVtYmVyXCIsXG4gICAgICAgIG5ldHdvcmtHcm91cElkOiBuZXR3b3JrR3JvdXAuaWQsXG4gICAgICAgIHJlc291cmNlSWQ6IFwiL3N1YnNjcmlwdGlvbnMvdGVzdC92aXJ0dWFsTmV0d29ya3Mvdm5ldDFcIixcbiAgICAgICAgYXBpVmVyc2lvbjogXCIyMDIzLTExLTAxXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KG1lbWJlci5yZXNvbHZlZEFwaVZlcnNpb24pLnRvQmUoXCIyMDIzLTExLTAxXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlRlcnJhZm9ybSBPdXRwdXRzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjcmVhdGUgcHJvcGVyIFRlcnJhZm9ybSBvdXRwdXRzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IG1lbWJlciA9IG5ldyBOZXR3b3JrR3JvdXBTdGF0aWNNZW1iZXIoc3RhY2ssIFwiVGVzdE1lbWJlclwiLCB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1tZW1iZXJcIixcbiAgICAgICAgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCxcbiAgICAgICAgcmVzb3VyY2VJZDogXCIvc3Vic2NyaXB0aW9ucy90ZXN0L3ZpcnR1YWxOZXR3b3Jrcy92bmV0MVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChtZW1iZXIuaWRPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QobWVtYmVyLm5hbWVPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QobWVtYmVyLnJlc291cmNlSWRPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBoYXZlIHByb3BlciByZXNvdXJjZSByZWZlcmVuY2VzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IG1lbWJlciA9IG5ldyBOZXR3b3JrR3JvdXBTdGF0aWNNZW1iZXIoc3RhY2ssIFwiVGVzdE1lbWJlclwiLCB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1tZW1iZXJcIixcbiAgICAgICAgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCxcbiAgICAgICAgcmVzb3VyY2VJZDogXCIvc3Vic2NyaXB0aW9ucy90ZXN0L3ZpcnR1YWxOZXR3b3Jrcy92bmV0MVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChtZW1iZXIuaWQpLnRvTWF0Y2goL15cXCRcXHsuKlxcLmlkXFx9JC8pO1xuICAgICAgZXhwZWN0KG1lbWJlci5yZXNvdXJjZU5hbWUpLnRvTWF0Y2goL15cXCRcXHsuKlxcLm5hbWVcXH0kLyk7XG4gICAgICAvLyBtZW1iZXJSZXNvdXJjZUlkIHJldHVybnMgdGhlIGlucHV0IHJlc291cmNlSWQgc2luY2UgQXp1cmUgQVBJIGRvZXNuJ3QgcmV0dXJuIGl0XG4gICAgICBleHBlY3QobWVtYmVyLm1lbWJlclJlc291cmNlSWQpLnRvQmUoXG4gICAgICAgIFwiL3N1YnNjcmlwdGlvbnMvdGVzdC92aXJ0dWFsTmV0d29ya3Mvdm5ldDFcIixcbiAgICAgICk7XG4gICAgICBleHBlY3QobWVtYmVyLnJlZ2lvbikudG9NYXRjaCgvXlxcJFxcey4qXFwub3V0cHV0XFwucHJvcGVydGllc1xcLnJlZ2lvblxcfSQvKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJQYXJlbnQtQ2hpbGQgUmVsYXRpb25zaGlwXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjb3JyZWN0bHkgcmVmZXJlbmNlIHBhcmVudCBuZXR3b3JrIGdyb3VwXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IG1lbWJlciA9IG5ldyBOZXR3b3JrR3JvdXBTdGF0aWNNZW1iZXIoc3RhY2ssIFwiVGVzdE1lbWJlclwiLCB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1tZW1iZXJcIixcbiAgICAgICAgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCxcbiAgICAgICAgcmVzb3VyY2VJZDogXCIvc3Vic2NyaXB0aW9ucy90ZXN0L3ZpcnR1YWxOZXR3b3Jrcy92bmV0MVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChtZW1iZXIucHJvcHMubmV0d29ya0dyb3VwSWQpLnRvQmUobmV0d29ya0dyb3VwLmlkKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJDREsgU3ludGhlc2lzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBzeW50aGVzaXplIHZhbGlkIFRlcnJhZm9ybSBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICAgIG5ldyBOZXR3b3JrR3JvdXBTdGF0aWNNZW1iZXIoc3RhY2ssIFwiVGVzdE1lbWJlclwiLCB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1tZW1iZXJcIixcbiAgICAgICAgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCxcbiAgICAgICAgcmVzb3VyY2VJZDogXCIvc3Vic2NyaXB0aW9ucy90ZXN0L3ZpcnR1YWxOZXR3b3Jrcy92bmV0MVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHN5bnRoZXNpemVkID0gVGVzdGluZy5zeW50aChzdGFjayk7XG4gICAgICBleHBlY3Qoc3ludGhlc2l6ZWQpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBjb25zdCBzdGFja0NvbmZpZyA9IEpTT04ucGFyc2Uoc3ludGhlc2l6ZWQpO1xuICAgICAgZXhwZWN0KHN0YWNrQ29uZmlnLnJlc291cmNlKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcIkNvbm5lY3Rpdml0eUNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICBsZXQgYXBwOiBjZGt0Zi5BcHA7XG4gIGxldCBzdGFjazogY2RrdGYuVGVycmFmb3JtU3RhY2s7XG4gIGxldCBtYW5hZ2VyOiBWaXJ0dWFsTmV0d29ya01hbmFnZXI7XG4gIGxldCBuZXR3b3JrR3JvdXA6IE5ldHdvcmtHcm91cDtcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICBhcHAgPSBUZXN0aW5nLmFwcCgpO1xuICAgIHN0YWNrID0gbmV3IGNka3RmLlRlcnJhZm9ybVN0YWNrKGFwcCwgXCJ0ZXN0LXN0YWNrXCIpO1xuICAgIG1hbmFnZXIgPSBuZXcgVmlydHVhbE5ldHdvcmtNYW5hZ2VyKHN0YWNrLCBcIlRlc3RNYW5hZ2VyXCIsIHtcbiAgICAgIG5hbWU6IFwidGVzdC1tYW5hZ2VyXCIsXG4gICAgICBsb2NhdGlvbjogXCJlYXN0dXNcIixcbiAgICAgIHJlc291cmNlR3JvdXBJZDpcbiAgICAgICAgXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAvcmVzb3VyY2VHcm91cHMvdGVzdC1yZ1wiLFxuICAgICAgbmV0d29ya01hbmFnZXJTY29wZXM6IHtcbiAgICAgICAgc3Vic2NyaXB0aW9uczogW1wiL3N1YnNjcmlwdGlvbnMvMDAwMDAwMDAtMDAwMC0wMDAwLTAwMDAtMDAwMDAwMDAwMDAwXCJdLFxuICAgICAgfSxcbiAgICAgIG5ldHdvcmtNYW5hZ2VyU2NvcGVBY2Nlc3NlczogW1wiQ29ubmVjdGl2aXR5XCJdLFxuICAgIH0pO1xuICAgIG5ldHdvcmtHcm91cCA9IG5ldyBOZXR3b3JrR3JvdXAoc3RhY2ssIFwiVGVzdEdyb3VwXCIsIHtcbiAgICAgIG5hbWU6IFwidGVzdC1ncm91cFwiLFxuICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJCYXNpYyBJbnN0YW50aWF0aW9uIC0gTWVzaCBUb3BvbG9neVwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIE1lc2ggY29ubmVjdGl2aXR5IGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IENvbm5lY3Rpdml0eUNvbmZpZ3VyYXRpb25Qcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJtZXNoLWNvbmZpZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgICAgICBjb25uZWN0aXZpdHlUb3BvbG9neTogXCJNZXNoXCIsXG4gICAgICAgIGFwcGxpZXNUb0dyb3VwczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5ldHdvcmtHcm91cElkOiBuZXR3b3JrR3JvdXAuaWQsXG4gICAgICAgICAgICBncm91cENvbm5lY3Rpdml0eTogXCJEaXJlY3RseUNvbm5lY3RlZFwiLFxuICAgICAgICAgICAgaXNHbG9iYWw6IGZhbHNlLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBjb25maWcgPSBuZXcgQ29ubmVjdGl2aXR5Q29uZmlndXJhdGlvbihzdGFjaywgXCJNZXNoQ29uZmlnXCIsIHByb3BzKTtcblxuICAgICAgZXhwZWN0KGNvbmZpZykudG9CZUluc3RhbmNlT2YoQ29ubmVjdGl2aXR5Q29uZmlndXJhdGlvbik7XG4gICAgICBleHBlY3QoY29uZmlnLnRvcG9sb2d5KS50b0JlKFwiTWVzaFwiKTtcbiAgICAgIGV4cGVjdChjb25maWcucHJvcHMuYXBwbGllc1RvR3JvdXBzKS50b0hhdmVMZW5ndGgoMSk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgZ2xvYmFsIE1lc2ggY29ubmVjdGl2aXR5IGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IENvbm5lY3Rpdml0eUNvbmZpZ3VyYXRpb25Qcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJnbG9iYWwtbWVzaFwiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgICAgICBjb25uZWN0aXZpdHlUb3BvbG9neTogXCJNZXNoXCIsXG4gICAgICAgIGFwcGxpZXNUb0dyb3VwczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5ldHdvcmtHcm91cElkOiBuZXR3b3JrR3JvdXAuaWQsXG4gICAgICAgICAgICBncm91cENvbm5lY3Rpdml0eTogXCJEaXJlY3RseUNvbm5lY3RlZFwiLFxuICAgICAgICAgICAgaXNHbG9iYWw6IHRydWUsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgaXNHbG9iYWw6IHRydWUsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBjb25maWcgPSBuZXcgQ29ubmVjdGl2aXR5Q29uZmlndXJhdGlvbihzdGFjaywgXCJHbG9iYWxNZXNoXCIsIHByb3BzKTtcblxuICAgICAgZXhwZWN0KGNvbmZpZy5wcm9wcy5pc0dsb2JhbCkudG9CZSh0cnVlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJCYXNpYyBJbnN0YW50aWF0aW9uIC0gSHViLWFuZC1TcG9rZSBUb3BvbG9neVwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIEh1Yi1hbmQtU3Bva2UgY29ubmVjdGl2aXR5IGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IENvbm5lY3Rpdml0eUNvbmZpZ3VyYXRpb25Qcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJodWItc3Bva2UtY29uZmlnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICAgIGNvbm5lY3Rpdml0eVRvcG9sb2d5OiBcIkh1YkFuZFNwb2tlXCIsXG4gICAgICAgIGFwcGxpZXNUb0dyb3VwczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5ldHdvcmtHcm91cElkOiBuZXR3b3JrR3JvdXAuaWQsXG4gICAgICAgICAgICBncm91cENvbm5lY3Rpdml0eTogXCJOb25lXCIsXG4gICAgICAgICAgICB1c2VIdWJHYXRld2F5OiB0cnVlLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGh1YnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXNvdXJjZUlkOiBcIi9zdWJzY3JpcHRpb25zL3Rlc3QvdmlydHVhbE5ldHdvcmtzL2h1Yi12bmV0XCIsXG4gICAgICAgICAgICByZXNvdXJjZVR5cGU6IFwiTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtzXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBDb25uZWN0aXZpdHlDb25maWd1cmF0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJIdWJTcG9rZUNvbmZpZ1wiLFxuICAgICAgICBwcm9wcyxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChjb25maWcudG9wb2xvZ3kpLnRvQmUoXCJIdWJBbmRTcG9rZVwiKTtcbiAgICAgIGV4cGVjdChjb25maWcucHJvcHMuaHVicykudG9IYXZlTGVuZ3RoKDEpO1xuICAgICAgZXhwZWN0KGNvbmZpZy5wcm9wcy5hcHBsaWVzVG9Hcm91cHNbMF0udXNlSHViR2F0ZXdheSkudG9CZSh0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBIdWItYW5kLVNwb2tlIHdpdGggbXVsdGlwbGUgaHVic1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogQ29ubmVjdGl2aXR5Q29uZmlndXJhdGlvblByb3BzID0ge1xuICAgICAgICBuYW1lOiBcIm11bHRpLWh1Yi1jb25maWdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICAgICAgY29ubmVjdGl2aXR5VG9wb2xvZ3k6IFwiSHViQW5kU3Bva2VcIixcbiAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCxcbiAgICAgICAgICAgIGdyb3VwQ29ubmVjdGl2aXR5OiBcIk5vbmVcIixcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBodWJzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgcmVzb3VyY2VJZDogXCIvc3Vic2NyaXB0aW9ucy90ZXN0L3ZpcnR1YWxOZXR3b3Jrcy9odWItdm5ldC0xXCIsXG4gICAgICAgICAgICByZXNvdXJjZVR5cGU6IFwiTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtzXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICByZXNvdXJjZUlkOiBcIi9zdWJzY3JpcHRpb25zL3Rlc3QvdmlydHVhbE5ldHdvcmtzL2h1Yi12bmV0LTJcIixcbiAgICAgICAgICAgIHJlc291cmNlVHlwZTogXCJNaWNyb3NvZnQuTmV0d29yay92aXJ0dWFsTmV0d29ya3NcIixcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgY29uZmlnID0gbmV3IENvbm5lY3Rpdml0eUNvbmZpZ3VyYXRpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIk11bHRpSHViQ29uZmlnXCIsXG4gICAgICAgIHByb3BzLFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbmZpZy5wcm9wcy5odWJzKS50b0hhdmVMZW5ndGgoMik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiUHJvcGVydHkgVmFsaWRhdGlvblwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgaGFuZGxlIGRlc2NyaXB0aW9uIHByb3BlcnR5XCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBDb25uZWN0aXZpdHlDb25maWd1cmF0aW9uKHN0YWNrLCBcIlRlc3RDb25maWdcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY29uZmlnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIkh1Yi1hbmQtc3Bva2UgdG9wb2xvZ3kgZm9yIHByb2R1Y3Rpb24gd29ya2xvYWRzXCIsXG4gICAgICAgIGNvbm5lY3Rpdml0eVRvcG9sb2d5OiBcIkh1YkFuZFNwb2tlXCIsXG4gICAgICAgIGFwcGxpZXNUb0dyb3VwczogW3sgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCB9XSxcbiAgICAgICAgaHViczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHJlc291cmNlSWQ6IFwiL3N1YnNjcmlwdGlvbnMvdGVzdC92aXJ0dWFsTmV0d29ya3MvaHViXCIsXG4gICAgICAgICAgICByZXNvdXJjZVR5cGU6IFwiTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtzXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QoY29uZmlnLnByb3BzLmRlc2NyaXB0aW9uKS50b0JlKFxuICAgICAgICBcIkh1Yi1hbmQtc3Bva2UgdG9wb2xvZ3kgZm9yIHByb2R1Y3Rpb24gd29ya2xvYWRzXCIsXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaGFuZGxlIGRlbGV0ZUV4aXN0aW5nUGVlcmluZyBwcm9wZXJ0eVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb25maWcgPSBuZXcgQ29ubmVjdGl2aXR5Q29uZmlndXJhdGlvbihzdGFjaywgXCJUZXN0Q29uZmlnXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWNvbmZpZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgICAgICBjb25uZWN0aXZpdHlUb3BvbG9neTogXCJNZXNoXCIsXG4gICAgICAgIGFwcGxpZXNUb0dyb3VwczogW3sgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCB9XSxcbiAgICAgICAgZGVsZXRlRXhpc3RpbmdQZWVyaW5nOiB0cnVlLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChjb25maWcucHJvcHMuZGVsZXRlRXhpc3RpbmdQZWVyaW5nKS50b0JlKHRydWUpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkFQSSBWZXJzaW9uIEhhbmRsaW5nXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCB1c2UgZGVmYXVsdCBBUEkgdmVyc2lvbiB3aGVuIG5vbmUgc3BlY2lmaWVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBDb25uZWN0aXZpdHlDb25maWd1cmF0aW9uKHN0YWNrLCBcIlRlc3RDb25maWdcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY29uZmlnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICAgIGNvbm5lY3Rpdml0eVRvcG9sb2d5OiBcIk1lc2hcIixcbiAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH1dLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChjb25maWcucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyNC0wNS0wMVwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHVzZSBzcGVjaWZpZWQgQVBJIHZlcnNpb24gd2hlbiBwcm92aWRlZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb25maWcgPSBuZXcgQ29ubmVjdGl2aXR5Q29uZmlndXJhdGlvbihzdGFjaywgXCJUZXN0Q29uZmlnXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWNvbmZpZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgICAgICBhcGlWZXJzaW9uOiBcIjIwMjMtMTEtMDFcIixcbiAgICAgICAgY29ubmVjdGl2aXR5VG9wb2xvZ3k6IFwiTWVzaFwiLFxuICAgICAgICBhcHBsaWVzVG9Hcm91cHM6IFt7IG5ldHdvcmtHcm91cElkOiBuZXR3b3JrR3JvdXAuaWQgfV0sXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KGNvbmZpZy5yZXNvbHZlZEFwaVZlcnNpb24pLnRvQmUoXCIyMDIzLTExLTAxXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlRlcnJhZm9ybSBPdXRwdXRzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjcmVhdGUgcHJvcGVyIFRlcnJhZm9ybSBvdXRwdXRzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBDb25uZWN0aXZpdHlDb25maWd1cmF0aW9uKHN0YWNrLCBcIlRlc3RDb25maWdcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY29uZmlnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICAgIGNvbm5lY3Rpdml0eVRvcG9sb2d5OiBcIk1lc2hcIixcbiAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH1dLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChjb25maWcuaWRPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QoY29uZmlnLm5hbWVPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QoY29uZmlnLnByb3Zpc2lvbmluZ1N0YXRlT3V0cHV0KS50b0JlSW5zdGFuY2VPZihcbiAgICAgICAgY2RrdGYuVGVycmFmb3JtT3V0cHV0LFxuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJDREsgU3ludGhlc2lzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBzeW50aGVzaXplIHZhbGlkIFRlcnJhZm9ybSBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICAgIG5ldyBDb25uZWN0aXZpdHlDb25maWd1cmF0aW9uKHN0YWNrLCBcIlRlc3RDb25maWdcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtY29uZmlnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICAgIGNvbm5lY3Rpdml0eVRvcG9sb2d5OiBcIk1lc2hcIixcbiAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH1dLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHN5bnRoZXNpemVkID0gVGVzdGluZy5zeW50aChzdGFjayk7XG4gICAgICBleHBlY3Qoc3ludGhlc2l6ZWQpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBjb25zdCBzdGFja0NvbmZpZyA9IEpTT04ucGFyc2Uoc3ludGhlc2l6ZWQpO1xuICAgICAgZXhwZWN0KHN0YWNrQ29uZmlnLnJlc291cmNlKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcIlNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgbGV0IGFwcDogY2RrdGYuQXBwO1xuICBsZXQgc3RhY2s6IGNka3RmLlRlcnJhZm9ybVN0YWNrO1xuICBsZXQgbWFuYWdlcjogVmlydHVhbE5ldHdvcmtNYW5hZ2VyO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIGFwcCA9IFRlc3RpbmcuYXBwKCk7XG4gICAgc3RhY2sgPSBuZXcgY2RrdGYuVGVycmFmb3JtU3RhY2soYXBwLCBcInRlc3Qtc3RhY2tcIik7XG4gICAgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwge1xuICAgICAgbmFtZTogXCJ0ZXN0LW1hbmFnZXJcIixcbiAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICBzdWJzY3JpcHRpb25zOiBbXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDBcIl0sXG4gICAgICB9LFxuICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJTZWN1cml0eUFkbWluXCJdLFxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkJhc2ljIEluc3RhbnRpYXRpb25cIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbiB3aXRoIG1pbmltdW0gcHJvcGVydGllc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogU2VjdXJpdHlBZG1pbkNvbmZpZ3VyYXRpb25Qcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJzZWN1cml0eS1jb25maWdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiU2VjdXJpdHlDb25maWdcIixcbiAgICAgICAgcHJvcHMsXG4gICAgICApO1xuXG4gICAgICBleHBlY3QoY29uZmlnKS50b0JlSW5zdGFuY2VPZihTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbik7XG4gICAgICBleHBlY3QoY29uZmlnLnByb3BzKS50b0JlKHByb3BzKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbiB3aXRoIGFsbCBwcm9wZXJ0aWVzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvblByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInNlY3VyaXR5LWNvbmZpZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgICAgICBkZXNjcmlwdGlvbjogXCJPcmdhbml6YXRpb24td2lkZSBzZWN1cml0eSBydWxlc1wiLFxuICAgICAgICBhcHBseU9uTmV0d29ya0ludGVudFBvbGljeUJhc2VkU2VydmljZXM6IFtcIk5vbmVcIl0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBjb25maWcgPSBuZXcgU2VjdXJpdHlBZG1pbkNvbmZpZ3VyYXRpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlNlY3VyaXR5Q29uZmlnXCIsXG4gICAgICAgIHByb3BzLFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbmZpZy5wcm9wcy5kZXNjcmlwdGlvbikudG9CZShcIk9yZ2FuaXphdGlvbi13aWRlIHNlY3VyaXR5IHJ1bGVzXCIpO1xuICAgICAgZXhwZWN0KGNvbmZpZy5wcm9wcy5hcHBseU9uTmV0d29ya0ludGVudFBvbGljeUJhc2VkU2VydmljZXMpLnRvRXF1YWwoW1xuICAgICAgICBcIk5vbmVcIixcbiAgICAgIF0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkFQSSBWZXJzaW9uIEhhbmRsaW5nXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCB1c2UgZGVmYXVsdCBBUEkgdmVyc2lvbiB3aGVuIG5vbmUgc3BlY2lmaWVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbihzdGFjaywgXCJTZWN1cml0eUNvbmZpZ1wiLCB7XG4gICAgICAgIG5hbWU6IFwic2VjdXJpdHktY29uZmlnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KGNvbmZpZy5yZXNvbHZlZEFwaVZlcnNpb24pLnRvQmUoXCIyMDI0LTA1LTAxXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgdXNlIHNwZWNpZmllZCBBUEkgdmVyc2lvbiB3aGVuIHByb3ZpZGVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbihzdGFjaywgXCJTZWN1cml0eUNvbmZpZ1wiLCB7XG4gICAgICAgIG5hbWU6IFwic2VjdXJpdHktY29uZmlnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICAgIGFwaVZlcnNpb246IFwiMjAyMy0xMS0wMVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChjb25maWcucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyMy0xMS0wMVwiKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJUZXJyYWZvcm0gT3V0cHV0c1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIHByb3BlciBUZXJyYWZvcm0gb3V0cHV0c1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb25maWcgPSBuZXcgU2VjdXJpdHlBZG1pbkNvbmZpZ3VyYXRpb24oc3RhY2ssIFwiU2VjdXJpdHlDb25maWdcIiwge1xuICAgICAgICBuYW1lOiBcInNlY3VyaXR5LWNvbmZpZ1wiLFxuICAgICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChjb25maWcuaWRPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QoY29uZmlnLm5hbWVPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QoY29uZmlnLnByb3Zpc2lvbmluZ1N0YXRlT3V0cHV0KS50b0JlSW5zdGFuY2VPZihcbiAgICAgICAgY2RrdGYuVGVycmFmb3JtT3V0cHV0LFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhdmUgcHJvcGVyIHJlc291cmNlIHJlZmVyZW5jZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgY29uZmlnID0gbmV3IFNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uKHN0YWNrLCBcIlNlY3VyaXR5Q29uZmlnXCIsIHtcbiAgICAgICAgbmFtZTogXCJzZWN1cml0eS1jb25maWdcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QoY29uZmlnLmlkKS50b01hdGNoKC9eXFwkXFx7LipcXC5pZFxcfSQvKTtcbiAgICAgIGV4cGVjdChjb25maWcucmVzb3VyY2VOYW1lKS50b01hdGNoKC9eXFwkXFx7LipcXC5uYW1lXFx9JC8pO1xuICAgICAgZXhwZWN0KGNvbmZpZy5wcm92aXNpb25pbmdTdGF0ZSkudG9NYXRjaChcbiAgICAgICAgL15cXCRcXHsuKlxcLm91dHB1dFxcLnByb3BlcnRpZXNcXC5wcm92aXNpb25pbmdTdGF0ZVxcfSQvLFxuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJDREsgU3ludGhlc2lzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBzeW50aGVzaXplIHZhbGlkIFRlcnJhZm9ybSBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICAgIG5ldyBTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbihzdGFjaywgXCJTZWN1cml0eUNvbmZpZ1wiLCB7XG4gICAgICAgIG5hbWU6IFwic2VjdXJpdHktY29uZmlnXCIsXG4gICAgICAgIG5ldHdvcmtNYW5hZ2VySWQ6IG1hbmFnZXIuaWQsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIlRlc3Qgc2VjdXJpdHkgY29uZmlndXJhdGlvblwiLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHN5bnRoZXNpemVkID0gVGVzdGluZy5zeW50aChzdGFjayk7XG4gICAgICBleHBlY3Qoc3ludGhlc2l6ZWQpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBjb25zdCBzdGFja0NvbmZpZyA9IEpTT04ucGFyc2Uoc3ludGhlc2l6ZWQpO1xuICAgICAgZXhwZWN0KHN0YWNrQ29uZmlnLnJlc291cmNlKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcIlNlY3VyaXR5QWRtaW5SdWxlQ29sbGVjdGlvblwiLCAoKSA9PiB7XG4gIGxldCBhcHA6IGNka3RmLkFwcDtcbiAgbGV0IHN0YWNrOiBjZGt0Zi5UZXJyYWZvcm1TdGFjaztcbiAgbGV0IG1hbmFnZXI6IFZpcnR1YWxOZXR3b3JrTWFuYWdlcjtcbiAgbGV0IHNlY3VyaXR5Q29uZmlnOiBTZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbjtcbiAgbGV0IG5ldHdvcmtHcm91cDogTmV0d29ya0dyb3VwO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIGFwcCA9IFRlc3RpbmcuYXBwKCk7XG4gICAgc3RhY2sgPSBuZXcgY2RrdGYuVGVycmFmb3JtU3RhY2soYXBwLCBcInRlc3Qtc3RhY2tcIik7XG4gICAgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwge1xuICAgICAgbmFtZTogXCJ0ZXN0LW1hbmFnZXJcIixcbiAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICBzdWJzY3JpcHRpb25zOiBbXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDBcIl0sXG4gICAgICB9LFxuICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJTZWN1cml0eUFkbWluXCJdLFxuICAgIH0pO1xuICAgIHNlY3VyaXR5Q29uZmlnID0gbmV3IFNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uKHN0YWNrLCBcIlNlY3VyaXR5Q29uZmlnXCIsIHtcbiAgICAgIG5hbWU6IFwic2VjdXJpdHktY29uZmlnXCIsXG4gICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgIH0pO1xuICAgIG5ldHdvcmtHcm91cCA9IG5ldyBOZXR3b3JrR3JvdXAoc3RhY2ssIFwiVGVzdEdyb3VwXCIsIHtcbiAgICAgIG5hbWU6IFwidGVzdC1ncm91cFwiLFxuICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJCYXNpYyBJbnN0YW50aWF0aW9uXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjcmVhdGUgUnVsZUNvbGxlY3Rpb24gd2l0aCBtaW5pbXVtIHByb3BlcnRpZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFNlY3VyaXR5QWRtaW5SdWxlQ29sbGVjdGlvblByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInJ1bGUtY29sbGVjdGlvblwiLFxuICAgICAgICBzZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbklkOiBzZWN1cml0eUNvbmZpZy5pZCxcbiAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH1dLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgY29sbGVjdGlvbiA9IG5ldyBTZWN1cml0eUFkbWluUnVsZUNvbGxlY3Rpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlJ1bGVDb2xsZWN0aW9uXCIsXG4gICAgICAgIHByb3BzLFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbGxlY3Rpb24pLnRvQmVJbnN0YW5jZU9mKFNlY3VyaXR5QWRtaW5SdWxlQ29sbGVjdGlvbik7XG4gICAgICBleHBlY3QoY29sbGVjdGlvbi5wcm9wcy5hcHBsaWVzVG9Hcm91cHMpLnRvSGF2ZUxlbmd0aCgxKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBSdWxlQ29sbGVjdGlvbiB3aXRoIGRlc2NyaXB0aW9uXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBTZWN1cml0eUFkbWluUnVsZUNvbGxlY3Rpb25Qcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJibG9jay1oaWdoLXJpc2stcG9ydHNcIixcbiAgICAgICAgc2VjdXJpdHlBZG1pbkNvbmZpZ3VyYXRpb25JZDogc2VjdXJpdHlDb25maWcuaWQsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIlJ1bGVzIHRvIGJsb2NrIGhpZ2gtcmlzayBwb3J0c1wiLFxuICAgICAgICBhcHBsaWVzVG9Hcm91cHM6IFt7IG5ldHdvcmtHcm91cElkOiBuZXR3b3JrR3JvdXAuaWQgfV0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBjb2xsZWN0aW9uID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlQ29sbGVjdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiUnVsZUNvbGxlY3Rpb25cIixcbiAgICAgICAgcHJvcHMsXG4gICAgICApO1xuXG4gICAgICBleHBlY3QoY29sbGVjdGlvbi5wcm9wcy5kZXNjcmlwdGlvbikudG9CZShcbiAgICAgICAgXCJSdWxlcyB0byBibG9jayBoaWdoLXJpc2sgcG9ydHNcIixcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgUnVsZUNvbGxlY3Rpb24gYXBwbGllZCB0byBtdWx0aXBsZSBncm91cHNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgZ3JvdXAyID0gbmV3IE5ldHdvcmtHcm91cChzdGFjaywgXCJUZXN0R3JvdXAyXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LWdyb3VwLTJcIixcbiAgICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBwcm9wczogU2VjdXJpdHlBZG1pblJ1bGVDb2xsZWN0aW9uUHJvcHMgPSB7XG4gICAgICAgIG5hbWU6IFwibXVsdGktZ3JvdXAtY29sbGVjdGlvblwiLFxuICAgICAgICBzZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbklkOiBzZWN1cml0eUNvbmZpZy5pZCxcbiAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbXG4gICAgICAgICAgeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH0sXG4gICAgICAgICAgeyBuZXR3b3JrR3JvdXBJZDogZ3JvdXAyLmlkIH0sXG4gICAgICAgIF0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBjb2xsZWN0aW9uID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlQ29sbGVjdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiUnVsZUNvbGxlY3Rpb25cIixcbiAgICAgICAgcHJvcHMsXG4gICAgICApO1xuXG4gICAgICBleHBlY3QoY29sbGVjdGlvbi5wcm9wcy5hcHBsaWVzVG9Hcm91cHMpLnRvSGF2ZUxlbmd0aCgyKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJBUEkgVmVyc2lvbiBIYW5kbGluZ1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgdXNlIGRlZmF1bHQgQVBJIHZlcnNpb24gd2hlbiBub25lIHNwZWNpZmllZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb2xsZWN0aW9uID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlQ29sbGVjdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiUnVsZUNvbGxlY3Rpb25cIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwicnVsZS1jb2xsZWN0aW9uXCIsXG4gICAgICAgICAgc2VjdXJpdHlBZG1pbkNvbmZpZ3VyYXRpb25JZDogc2VjdXJpdHlDb25maWcuaWQsXG4gICAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH1dLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbGxlY3Rpb24ucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyNC0wNS0wMVwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHVzZSBzcGVjaWZpZWQgQVBJIHZlcnNpb24gd2hlbiBwcm92aWRlZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb2xsZWN0aW9uID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlQ29sbGVjdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiUnVsZUNvbGxlY3Rpb25cIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwicnVsZS1jb2xsZWN0aW9uXCIsXG4gICAgICAgICAgc2VjdXJpdHlBZG1pbkNvbmZpZ3VyYXRpb25JZDogc2VjdXJpdHlDb25maWcuaWQsXG4gICAgICAgICAgYXBpVmVyc2lvbjogXCIyMDIzLTExLTAxXCIsXG4gICAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH1dLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbGxlY3Rpb24ucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyMy0xMS0wMVwiKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJUZXJyYWZvcm0gT3V0cHV0c1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIHByb3BlciBUZXJyYWZvcm0gb3V0cHV0c1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb2xsZWN0aW9uID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlQ29sbGVjdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiUnVsZUNvbGxlY3Rpb25cIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwicnVsZS1jb2xsZWN0aW9uXCIsXG4gICAgICAgICAgc2VjdXJpdHlBZG1pbkNvbmZpZ3VyYXRpb25JZDogc2VjdXJpdHlDb25maWcuaWQsXG4gICAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH1dLFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KGNvbGxlY3Rpb24uaWRPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QoY29sbGVjdGlvbi5uYW1lT3V0cHV0KS50b0JlSW5zdGFuY2VPZihjZGt0Zi5UZXJyYWZvcm1PdXRwdXQpO1xuICAgICAgZXhwZWN0KGNvbGxlY3Rpb24ucHJvdmlzaW9uaW5nU3RhdGVPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKFxuICAgICAgICBjZGt0Zi5UZXJyYWZvcm1PdXRwdXQsXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlBhcmVudC1DaGlsZCBSZWxhdGlvbnNoaXBcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNvcnJlY3RseSByZWZlcmVuY2UgcGFyZW50IHNlY3VyaXR5IGFkbWluIGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgY29sbGVjdGlvbiA9IG5ldyBTZWN1cml0eUFkbWluUnVsZUNvbGxlY3Rpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlJ1bGVDb2xsZWN0aW9uXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInJ1bGUtY29sbGVjdGlvblwiLFxuICAgICAgICAgIHNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uSWQ6IHNlY3VyaXR5Q29uZmlnLmlkLFxuICAgICAgICAgIGFwcGxpZXNUb0dyb3VwczogW3sgbmV0d29ya0dyb3VwSWQ6IG5ldHdvcmtHcm91cC5pZCB9XSxcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChjb2xsZWN0aW9uLnByb3BzLnNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uSWQpLnRvQmUoXG4gICAgICAgIHNlY3VyaXR5Q29uZmlnLmlkLFxuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJDREsgU3ludGhlc2lzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBzeW50aGVzaXplIHZhbGlkIFRlcnJhZm9ybSBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICAgIG5ldyBTZWN1cml0eUFkbWluUnVsZUNvbGxlY3Rpb24oc3RhY2ssIFwiUnVsZUNvbGxlY3Rpb25cIiwge1xuICAgICAgICBuYW1lOiBcInJ1bGUtY29sbGVjdGlvblwiLFxuICAgICAgICBzZWN1cml0eUFkbWluQ29uZmlndXJhdGlvbklkOiBzZWN1cml0eUNvbmZpZy5pZCxcbiAgICAgICAgYXBwbGllc1RvR3JvdXBzOiBbeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH1dLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHN5bnRoZXNpemVkID0gVGVzdGluZy5zeW50aChzdGFjayk7XG4gICAgICBleHBlY3Qoc3ludGhlc2l6ZWQpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBjb25zdCBzdGFja0NvbmZpZyA9IEpTT04ucGFyc2Uoc3ludGhlc2l6ZWQpO1xuICAgICAgZXhwZWN0KHN0YWNrQ29uZmlnLnJlc291cmNlKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZShcIlNlY3VyaXR5QWRtaW5SdWxlXCIsICgpID0+IHtcbiAgbGV0IGFwcDogY2RrdGYuQXBwO1xuICBsZXQgc3RhY2s6IGNka3RmLlRlcnJhZm9ybVN0YWNrO1xuICBsZXQgbWFuYWdlcjogVmlydHVhbE5ldHdvcmtNYW5hZ2VyO1xuICBsZXQgc2VjdXJpdHlDb25maWc6IFNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uO1xuICBsZXQgbmV0d29ya0dyb3VwOiBOZXR3b3JrR3JvdXA7XG4gIGxldCBydWxlQ29sbGVjdGlvbjogU2VjdXJpdHlBZG1pblJ1bGVDb2xsZWN0aW9uO1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIGFwcCA9IFRlc3RpbmcuYXBwKCk7XG4gICAgc3RhY2sgPSBuZXcgY2RrdGYuVGVycmFmb3JtU3RhY2soYXBwLCBcInRlc3Qtc3RhY2tcIik7XG4gICAgbWFuYWdlciA9IG5ldyBWaXJ0dWFsTmV0d29ya01hbmFnZXIoc3RhY2ssIFwiVGVzdE1hbmFnZXJcIiwge1xuICAgICAgbmFtZTogXCJ0ZXN0LW1hbmFnZXJcIixcbiAgICAgIGxvY2F0aW9uOiBcImVhc3R1c1wiLFxuICAgICAgcmVzb3VyY2VHcm91cElkOlxuICAgICAgICBcIi9zdWJzY3JpcHRpb25zLzAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMC9yZXNvdXJjZUdyb3Vwcy90ZXN0LXJnXCIsXG4gICAgICBuZXR3b3JrTWFuYWdlclNjb3Blczoge1xuICAgICAgICBzdWJzY3JpcHRpb25zOiBbXCIvc3Vic2NyaXB0aW9ucy8wMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDBcIl0sXG4gICAgICB9LFxuICAgICAgbmV0d29ya01hbmFnZXJTY29wZUFjY2Vzc2VzOiBbXCJTZWN1cml0eUFkbWluXCJdLFxuICAgIH0pO1xuICAgIHNlY3VyaXR5Q29uZmlnID0gbmV3IFNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uKHN0YWNrLCBcIlNlY3VyaXR5Q29uZmlnXCIsIHtcbiAgICAgIG5hbWU6IFwic2VjdXJpdHktY29uZmlnXCIsXG4gICAgICBuZXR3b3JrTWFuYWdlcklkOiBtYW5hZ2VyLmlkLFxuICAgIH0pO1xuICAgIG5ldHdvcmtHcm91cCA9IG5ldyBOZXR3b3JrR3JvdXAoc3RhY2ssIFwiVGVzdEdyb3VwXCIsIHtcbiAgICAgIG5hbWU6IFwidGVzdC1ncm91cFwiLFxuICAgICAgbmV0d29ya01hbmFnZXJJZDogbWFuYWdlci5pZCxcbiAgICB9KTtcbiAgICBydWxlQ29sbGVjdGlvbiA9IG5ldyBTZWN1cml0eUFkbWluUnVsZUNvbGxlY3Rpb24oc3RhY2ssIFwiUnVsZUNvbGxlY3Rpb25cIiwge1xuICAgICAgbmFtZTogXCJydWxlLWNvbGxlY3Rpb25cIixcbiAgICAgIHNlY3VyaXR5QWRtaW5Db25maWd1cmF0aW9uSWQ6IHNlY3VyaXR5Q29uZmlnLmlkLFxuICAgICAgYXBwbGllc1RvR3JvdXBzOiBbeyBuZXR3b3JrR3JvdXBJZDogbmV0d29ya0dyb3VwLmlkIH1dLFxuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkJhc2ljIEluc3RhbnRpYXRpb24gLSBEZW55IFJ1bGVzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjcmVhdGUgRGVueSBydWxlIGJsb2NraW5nIFNTSFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogU2VjdXJpdHlBZG1pblJ1bGVQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJibG9jay1zc2hcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIkJsb2NrIFNTSCBhY2Nlc3MgZnJvbSBpbnRlcm5ldFwiLFxuICAgICAgICBwcmlvcml0eTogMTAwLFxuICAgICAgICBhY3Rpb246IFwiRGVueVwiLFxuICAgICAgICBkaXJlY3Rpb246IFwiSW5ib3VuZFwiLFxuICAgICAgICBwcm90b2NvbDogXCJUY3BcIixcbiAgICAgICAgZGVzdGluYXRpb25Qb3J0UmFuZ2VzOiBbXCIyMlwiXSxcbiAgICAgICAgc291cmNlczogW1xuICAgICAgICAgIHsgYWRkcmVzc1ByZWZpeDogXCJJbnRlcm5ldFwiLCBhZGRyZXNzUHJlZml4VHlwZTogXCJTZXJ2aWNlVGFnXCIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZGVzdGluYXRpb25zOiBbeyBhZGRyZXNzUHJlZml4OiBcIipcIiwgYWRkcmVzc1ByZWZpeFR5cGU6IFwiSVBQcmVmaXhcIiB9XSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiQmxvY2tTU0hcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QocnVsZSkudG9CZUluc3RhbmNlT2YoU2VjdXJpdHlBZG1pblJ1bGUpO1xuICAgICAgZXhwZWN0KHJ1bGUucnVsZUFjdGlvbikudG9CZShcIkRlbnlcIik7XG4gICAgICBleHBlY3QocnVsZS5ydWxlUHJpb3JpdHkpLnRvQmUoMTAwKTtcbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnByb3RvY29sKS50b0JlKFwiVGNwXCIpO1xuICAgICAgZXhwZWN0KHJ1bGUucHJvcHMuZGVzdGluYXRpb25Qb3J0UmFuZ2VzKS50b0VxdWFsKFtcIjIyXCJdKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBEZW55IHJ1bGUgYmxvY2tpbmcgUkRQXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBTZWN1cml0eUFkbWluUnVsZVByb3BzID0ge1xuICAgICAgICBuYW1lOiBcImJsb2NrLXJkcFwiLFxuICAgICAgICBydWxlQ29sbGVjdGlvbklkOiBydWxlQ29sbGVjdGlvbi5pZCxcbiAgICAgICAgcHJpb3JpdHk6IDEwMSxcbiAgICAgICAgYWN0aW9uOiBcIkRlbnlcIixcbiAgICAgICAgZGlyZWN0aW9uOiBcIkluYm91bmRcIixcbiAgICAgICAgcHJvdG9jb2w6IFwiVGNwXCIsXG4gICAgICAgIGRlc3RpbmF0aW9uUG9ydFJhbmdlczogW1wiMzM4OVwiXSxcbiAgICAgICAgc291cmNlczogW1xuICAgICAgICAgIHsgYWRkcmVzc1ByZWZpeDogXCJJbnRlcm5ldFwiLCBhZGRyZXNzUHJlZml4VHlwZTogXCJTZXJ2aWNlVGFnXCIgfSxcbiAgICAgICAgXSxcbiAgICAgICAgZGVzdGluYXRpb25zOiBbeyBhZGRyZXNzUHJlZml4OiBcIipcIiwgYWRkcmVzc1ByZWZpeFR5cGU6IFwiSVBQcmVmaXhcIiB9XSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiQmxvY2tSRFBcIiwgcHJvcHMpO1xuXG4gICAgICBleHBlY3QocnVsZS5wcm9wcy5kZXN0aW5hdGlvblBvcnRSYW5nZXMpLnRvRXF1YWwoW1wiMzM4OVwiXSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiQmFzaWMgSW5zdGFudGlhdGlvbiAtIEFsbG93IFJ1bGVzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjcmVhdGUgQWxsb3cgcnVsZVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogU2VjdXJpdHlBZG1pblJ1bGVQcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJhbGxvdy1odHRwc1wiLFxuICAgICAgICBydWxlQ29sbGVjdGlvbklkOiBydWxlQ29sbGVjdGlvbi5pZCxcbiAgICAgICAgcHJpb3JpdHk6IDIwMCxcbiAgICAgICAgYWN0aW9uOiBcIkFsbG93XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIlRjcFwiLFxuICAgICAgICBkZXN0aW5hdGlvblBvcnRSYW5nZXM6IFtcIjQ0M1wiXSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiQWxsb3dIVFRQU1wiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdChydWxlLnJ1bGVBY3Rpb24pLnRvQmUoXCJBbGxvd1wiKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJCYXNpYyBJbnN0YW50aWF0aW9uIC0gQWx3YXlzQWxsb3cgUnVsZXNcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBBbHdheXNBbGxvdyBydWxlIGZvciBtb25pdG9yaW5nXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHByb3BzOiBTZWN1cml0eUFkbWluUnVsZVByb3BzID0ge1xuICAgICAgICBuYW1lOiBcImFsd2F5cy1hbGxvdy1tb25pdG9yaW5nXCIsXG4gICAgICAgIHJ1bGVDb2xsZWN0aW9uSWQ6IHJ1bGVDb2xsZWN0aW9uLmlkLFxuICAgICAgICBkZXNjcmlwdGlvbjogXCJBbHdheXMgYWxsb3cgdHJhZmZpYyBmcm9tIG1vbml0b3Jpbmcgc3lzdGVtc1wiLFxuICAgICAgICBwcmlvcml0eTogNTAsXG4gICAgICAgIGFjdGlvbjogXCJBbHdheXNBbGxvd1wiLFxuICAgICAgICBkaXJlY3Rpb246IFwiSW5ib3VuZFwiLFxuICAgICAgICBwcm90b2NvbDogXCJBbnlcIixcbiAgICAgICAgc291cmNlczogW1xuICAgICAgICAgIHsgYWRkcmVzc1ByZWZpeDogXCIxMC4wLjAuMC8yNFwiLCBhZGRyZXNzUHJlZml4VHlwZTogXCJJUFByZWZpeFwiIH0sXG4gICAgICAgIF0sXG4gICAgICAgIGRlc3RpbmF0aW9uczogW3sgYWRkcmVzc1ByZWZpeDogXCIqXCIsIGFkZHJlc3NQcmVmaXhUeXBlOiBcIklQUHJlZml4XCIgfV0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBydWxlID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIkFsbG93TW9uaXRvcmluZ1wiLCBwcm9wcyk7XG5cbiAgICAgIGV4cGVjdChydWxlLnJ1bGVBY3Rpb24pLnRvQmUoXCJBbHdheXNBbGxvd1wiKTtcbiAgICAgIGV4cGVjdChydWxlLnJ1bGVQcmlvcml0eSkudG9CZSg1MCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiUHJvdG9jb2wgSGFuZGxpbmdcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIHN1cHBvcnQgVGNwIHByb3RvY29sXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiVGNwUnVsZVwiLCB7XG4gICAgICAgIG5hbWU6IFwidGNwLXJ1bGVcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIHByaW9yaXR5OiAxMDAsXG4gICAgICAgIGFjdGlvbjogXCJEZW55XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIlRjcFwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnByb3RvY29sKS50b0JlKFwiVGNwXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgc3VwcG9ydCBVZHAgcHJvdG9jb2xcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcnVsZSA9IG5ldyBTZWN1cml0eUFkbWluUnVsZShzdGFjaywgXCJVZHBSdWxlXCIsIHtcbiAgICAgICAgbmFtZTogXCJ1ZHAtcnVsZVwiLFxuICAgICAgICBydWxlQ29sbGVjdGlvbklkOiBydWxlQ29sbGVjdGlvbi5pZCxcbiAgICAgICAgcHJpb3JpdHk6IDEwMCxcbiAgICAgICAgYWN0aW9uOiBcIkRlbnlcIixcbiAgICAgICAgZGlyZWN0aW9uOiBcIkluYm91bmRcIixcbiAgICAgICAgcHJvdG9jb2w6IFwiVWRwXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHJ1bGUucHJvcHMucHJvdG9jb2wpLnRvQmUoXCJVZHBcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBzdXBwb3J0IEljbXAgcHJvdG9jb2xcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcnVsZSA9IG5ldyBTZWN1cml0eUFkbWluUnVsZShzdGFjaywgXCJJY21wUnVsZVwiLCB7XG4gICAgICAgIG5hbWU6IFwiaWNtcC1ydWxlXCIsXG4gICAgICAgIHJ1bGVDb2xsZWN0aW9uSWQ6IHJ1bGVDb2xsZWN0aW9uLmlkLFxuICAgICAgICBwcmlvcml0eTogMTAwLFxuICAgICAgICBhY3Rpb246IFwiRGVueVwiLFxuICAgICAgICBkaXJlY3Rpb246IFwiSW5ib3VuZFwiLFxuICAgICAgICBwcm90b2NvbDogXCJJY21wXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHJ1bGUucHJvcHMucHJvdG9jb2wpLnRvQmUoXCJJY21wXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgc3VwcG9ydCBBbnkgcHJvdG9jb2xcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcnVsZSA9IG5ldyBTZWN1cml0eUFkbWluUnVsZShzdGFjaywgXCJBbnlSdWxlXCIsIHtcbiAgICAgICAgbmFtZTogXCJhbnktcnVsZVwiLFxuICAgICAgICBydWxlQ29sbGVjdGlvbklkOiBydWxlQ29sbGVjdGlvbi5pZCxcbiAgICAgICAgcHJpb3JpdHk6IDEwMCxcbiAgICAgICAgYWN0aW9uOiBcIkFsbG93XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIkFueVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnByb3RvY29sKS50b0JlKFwiQW55XCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkRpcmVjdGlvbiBIYW5kbGluZ1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgc3VwcG9ydCBJbmJvdW5kIGRpcmVjdGlvblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBydWxlID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIkluYm91bmRSdWxlXCIsIHtcbiAgICAgICAgbmFtZTogXCJpbmJvdW5kLXJ1bGVcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIHByaW9yaXR5OiAxMDAsXG4gICAgICAgIGFjdGlvbjogXCJEZW55XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIlRjcFwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLmRpcmVjdGlvbikudG9CZShcIkluYm91bmRcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBzdXBwb3J0IE91dGJvdW5kIGRpcmVjdGlvblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBydWxlID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIk91dGJvdW5kUnVsZVwiLCB7XG4gICAgICAgIG5hbWU6IFwib3V0Ym91bmQtcnVsZVwiLFxuICAgICAgICBydWxlQ29sbGVjdGlvbklkOiBydWxlQ29sbGVjdGlvbi5pZCxcbiAgICAgICAgcHJpb3JpdHk6IDEwMCxcbiAgICAgICAgYWN0aW9uOiBcIkRlbnlcIixcbiAgICAgICAgZGlyZWN0aW9uOiBcIk91dGJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIlRjcFwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLmRpcmVjdGlvbikudG9CZShcIk91dGJvdW5kXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlBvcnQgUmFuZ2UgSGFuZGxpbmdcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGhhbmRsZSBzaW5nbGUgc291cmNlIHBvcnRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcnVsZSA9IG5ldyBTZWN1cml0eUFkbWluUnVsZShzdGFjaywgXCJTaW5nbGVQb3J0XCIsIHtcbiAgICAgICAgbmFtZTogXCJzaW5nbGUtcG9ydFwiLFxuICAgICAgICBydWxlQ29sbGVjdGlvbklkOiBydWxlQ29sbGVjdGlvbi5pZCxcbiAgICAgICAgcHJpb3JpdHk6IDEwMCxcbiAgICAgICAgYWN0aW9uOiBcIkRlbnlcIixcbiAgICAgICAgZGlyZWN0aW9uOiBcIkluYm91bmRcIixcbiAgICAgICAgcHJvdG9jb2w6IFwiVGNwXCIsXG4gICAgICAgIHNvdXJjZVBvcnRSYW5nZXM6IFtcIjgwXCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnNvdXJjZVBvcnRSYW5nZXMpLnRvRXF1YWwoW1wiODBcIl0pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaGFuZGxlIG11bHRpcGxlIGRlc3RpbmF0aW9uIHBvcnRzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiTXVsdGlwbGVQb3J0c1wiLCB7XG4gICAgICAgIG5hbWU6IFwibXVsdGlwbGUtcG9ydHNcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIHByaW9yaXR5OiAxMDAsXG4gICAgICAgIGFjdGlvbjogXCJEZW55XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIlRjcFwiLFxuICAgICAgICBkZXN0aW5hdGlvblBvcnRSYW5nZXM6IFtcIjgwXCIsIFwiNDQzXCIsIFwiODA4MFwiXSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QocnVsZS5wcm9wcy5kZXN0aW5hdGlvblBvcnRSYW5nZXMpLnRvRXF1YWwoW1wiODBcIiwgXCI0NDNcIiwgXCI4MDgwXCJdKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhbmRsZSBwb3J0IHJhbmdlc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBydWxlID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIlBvcnRSYW5nZVwiLCB7XG4gICAgICAgIG5hbWU6IFwicG9ydC1yYW5nZVwiLFxuICAgICAgICBydWxlQ29sbGVjdGlvbklkOiBydWxlQ29sbGVjdGlvbi5pZCxcbiAgICAgICAgcHJpb3JpdHk6IDEwMCxcbiAgICAgICAgYWN0aW9uOiBcIkRlbnlcIixcbiAgICAgICAgZGlyZWN0aW9uOiBcIkluYm91bmRcIixcbiAgICAgICAgcHJvdG9jb2w6IFwiVGNwXCIsXG4gICAgICAgIGRlc3RpbmF0aW9uUG9ydFJhbmdlczogW1wiODAwMC04OTk5XCJdLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLmRlc3RpbmF0aW9uUG9ydFJhbmdlcykudG9FcXVhbChbXCI4MDAwLTg5OTlcIl0pO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgZGVmYXVsdCB0byB3aWxkY2FyZCB3aGVuIHBvcnRzIG5vdCBzcGVjaWZpZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcnVsZSA9IG5ldyBTZWN1cml0eUFkbWluUnVsZShzdGFjaywgXCJEZWZhdWx0UG9ydHNcIiwge1xuICAgICAgICBuYW1lOiBcImRlZmF1bHQtcG9ydHNcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIHByaW9yaXR5OiAxMDAsXG4gICAgICAgIGFjdGlvbjogXCJEZW55XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIkFueVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnNvdXJjZVBvcnRSYW5nZXMpLnRvQmVVbmRlZmluZWQoKTtcbiAgICAgIGV4cGVjdChydWxlLnByb3BzLmRlc3RpbmF0aW9uUG9ydFJhbmdlcykudG9CZVVuZGVmaW5lZCgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkFkZHJlc3MgUHJlZml4IEhhbmRsaW5nXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBoYW5kbGUgSVAgcHJlZml4IHNvdXJjZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcnVsZSA9IG5ldyBTZWN1cml0eUFkbWluUnVsZShzdGFjaywgXCJJUFByZWZpeFwiLCB7XG4gICAgICAgIG5hbWU6IFwiaXAtcHJlZml4XCIsXG4gICAgICAgIHJ1bGVDb2xsZWN0aW9uSWQ6IHJ1bGVDb2xsZWN0aW9uLmlkLFxuICAgICAgICBwcmlvcml0eTogMTAwLFxuICAgICAgICBhY3Rpb246IFwiRGVueVwiLFxuICAgICAgICBkaXJlY3Rpb246IFwiSW5ib3VuZFwiLFxuICAgICAgICBwcm90b2NvbDogXCJUY3BcIixcbiAgICAgICAgc291cmNlczogW1xuICAgICAgICAgIHsgYWRkcmVzc1ByZWZpeDogXCIxMC4wLjAuMC84XCIsIGFkZHJlc3NQcmVmaXhUeXBlOiBcIklQUHJlZml4XCIgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QocnVsZS5wcm9wcy5zb3VyY2VzKS50b0VxdWFsKFtcbiAgICAgICAgeyBhZGRyZXNzUHJlZml4OiBcIjEwLjAuMC4wLzhcIiwgYWRkcmVzc1ByZWZpeFR5cGU6IFwiSVBQcmVmaXhcIiB9LFxuICAgICAgXSk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBoYW5kbGUgU2VydmljZVRhZyBzb3VyY2VzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiU2VydmljZVRhZ1wiLCB7XG4gICAgICAgIG5hbWU6IFwic2VydmljZS10YWdcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIHByaW9yaXR5OiAxMDAsXG4gICAgICAgIGFjdGlvbjogXCJEZW55XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIlRjcFwiLFxuICAgICAgICBzb3VyY2VzOiBbXG4gICAgICAgICAgeyBhZGRyZXNzUHJlZml4OiBcIkludGVybmV0XCIsIGFkZHJlc3NQcmVmaXhUeXBlOiBcIlNlcnZpY2VUYWdcIiB9LFxuICAgICAgICBdLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnNvdXJjZXMpLnRvRXF1YWwoW1xuICAgICAgICB7IGFkZHJlc3NQcmVmaXg6IFwiSW50ZXJuZXRcIiwgYWRkcmVzc1ByZWZpeFR5cGU6IFwiU2VydmljZVRhZ1wiIH0sXG4gICAgICBdKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhbmRsZSBtdWx0aXBsZSBzb3VyY2UgYWRkcmVzc2VzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiTXVsdGlwbGVTb3VyY2VzXCIsIHtcbiAgICAgICAgbmFtZTogXCJtdWx0aXBsZS1zb3VyY2VzXCIsXG4gICAgICAgIHJ1bGVDb2xsZWN0aW9uSWQ6IHJ1bGVDb2xsZWN0aW9uLmlkLFxuICAgICAgICBwcmlvcml0eTogMTAwLFxuICAgICAgICBhY3Rpb246IFwiRGVueVwiLFxuICAgICAgICBkaXJlY3Rpb246IFwiSW5ib3VuZFwiLFxuICAgICAgICBwcm90b2NvbDogXCJUY3BcIixcbiAgICAgICAgc291cmNlczogW1xuICAgICAgICAgIHsgYWRkcmVzc1ByZWZpeDogXCIxMC4wLjAuMC84XCIsIGFkZHJlc3NQcmVmaXhUeXBlOiBcIklQUHJlZml4XCIgfSxcbiAgICAgICAgICB7IGFkZHJlc3NQcmVmaXg6IFwiMTkyLjE2OC4wLjAvMTZcIiwgYWRkcmVzc1ByZWZpeFR5cGU6IFwiSVBQcmVmaXhcIiB9LFxuICAgICAgICBdLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnNvdXJjZXMpLnRvSGF2ZUxlbmd0aCgyKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJQcmlvcml0eSBIYW5kbGluZ1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgYWNjZXB0IGxvdyBwcmlvcml0eSBudW1iZXIgKGhpZ2ggcHJpb3JpdHkpXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiSGlnaFByaW9yaXR5XCIsIHtcbiAgICAgICAgbmFtZTogXCJoaWdoLXByaW9yaXR5XCIsXG4gICAgICAgIHJ1bGVDb2xsZWN0aW9uSWQ6IHJ1bGVDb2xsZWN0aW9uLmlkLFxuICAgICAgICBwcmlvcml0eTogMSxcbiAgICAgICAgYWN0aW9uOiBcIkFsd2F5c0FsbG93XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIkFueVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnJ1bGVQcmlvcml0eSkudG9CZSgxKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGFjY2VwdCBoaWdoIHByaW9yaXR5IG51bWJlciAobG93IHByaW9yaXR5KVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBydWxlID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIkxvd1ByaW9yaXR5XCIsIHtcbiAgICAgICAgbmFtZTogXCJsb3ctcHJpb3JpdHlcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIHByaW9yaXR5OiA0MDk2LFxuICAgICAgICBhY3Rpb246IFwiQWxsb3dcIixcbiAgICAgICAgZGlyZWN0aW9uOiBcIkluYm91bmRcIixcbiAgICAgICAgcHJvdG9jb2w6IFwiQW55XCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHJ1bGUucnVsZVByaW9yaXR5KS50b0JlKDQwOTYpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkFQSSBWZXJzaW9uIEhhbmRsaW5nXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCB1c2UgZGVmYXVsdCBBUEkgdmVyc2lvbiB3aGVuIG5vbmUgc3BlY2lmaWVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiVGVzdFJ1bGVcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtcnVsZVwiLFxuICAgICAgICBydWxlQ29sbGVjdGlvbklkOiBydWxlQ29sbGVjdGlvbi5pZCxcbiAgICAgICAgcHJpb3JpdHk6IDEwMCxcbiAgICAgICAgYWN0aW9uOiBcIkRlbnlcIixcbiAgICAgICAgZGlyZWN0aW9uOiBcIkluYm91bmRcIixcbiAgICAgICAgcHJvdG9jb2w6IFwiVGNwXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHJ1bGUucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyNC0wNS0wMVwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHVzZSBzcGVjaWZpZWQgQVBJIHZlcnNpb24gd2hlbiBwcm92aWRlZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBydWxlID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIlRlc3RSdWxlXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LXJ1bGVcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIGFwaVZlcnNpb246IFwiMjAyMy0xMS0wMVwiLFxuICAgICAgICBwcmlvcml0eTogMTAwLFxuICAgICAgICBhY3Rpb246IFwiRGVueVwiLFxuICAgICAgICBkaXJlY3Rpb246IFwiSW5ib3VuZFwiLFxuICAgICAgICBwcm90b2NvbDogXCJUY3BcIixcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QocnVsZS5yZXNvbHZlZEFwaVZlcnNpb24pLnRvQmUoXCIyMDIzLTExLTAxXCIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlRlcnJhZm9ybSBPdXRwdXRzXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBjcmVhdGUgcHJvcGVyIFRlcnJhZm9ybSBvdXRwdXRzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHJ1bGUgPSBuZXcgU2VjdXJpdHlBZG1pblJ1bGUoc3RhY2ssIFwiVGVzdFJ1bGVcIiwge1xuICAgICAgICBuYW1lOiBcInRlc3QtcnVsZVwiLFxuICAgICAgICBydWxlQ29sbGVjdGlvbklkOiBydWxlQ29sbGVjdGlvbi5pZCxcbiAgICAgICAgcHJpb3JpdHk6IDEwMCxcbiAgICAgICAgYWN0aW9uOiBcIkRlbnlcIixcbiAgICAgICAgZGlyZWN0aW9uOiBcIkluYm91bmRcIixcbiAgICAgICAgcHJvdG9jb2w6IFwiVGNwXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHJ1bGUuaWRPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKGNka3RmLlRlcnJhZm9ybU91dHB1dCk7XG4gICAgICBleHBlY3QocnVsZS5uYW1lT3V0cHV0KS50b0JlSW5zdGFuY2VPZihjZGt0Zi5UZXJyYWZvcm1PdXRwdXQpO1xuICAgICAgZXhwZWN0KHJ1bGUucHJvdmlzaW9uaW5nU3RhdGVPdXRwdXQpLnRvQmVJbnN0YW5jZU9mKFxuICAgICAgICBjZGt0Zi5UZXJyYWZvcm1PdXRwdXQsXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgaGF2ZSBwcm9wZXIgcmVzb3VyY2UgcmVmZXJlbmNlc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBydWxlID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIlRlc3RSdWxlXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LXJ1bGVcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIHByaW9yaXR5OiAxMDAsXG4gICAgICAgIGFjdGlvbjogXCJEZW55XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIlRjcFwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLmlkKS50b01hdGNoKC9eXFwkXFx7LipcXC5pZFxcfSQvKTtcbiAgICAgIGV4cGVjdChydWxlLnJlc291cmNlTmFtZSkudG9NYXRjaCgvXlxcJFxcey4qXFwubmFtZVxcfSQvKTtcbiAgICAgIGV4cGVjdChydWxlLnByb3Zpc2lvbmluZ1N0YXRlKS50b01hdGNoKFxuICAgICAgICAvXlxcJFxcey4qXFwub3V0cHV0XFwucHJvcGVydGllc1xcLnByb3Zpc2lvbmluZ1N0YXRlXFx9JC8sXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIlBhcmVudC1DaGlsZCBSZWxhdGlvbnNoaXBcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNvcnJlY3RseSByZWZlcmVuY2UgcGFyZW50IHJ1bGUgY29sbGVjdGlvblwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBydWxlID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIlRlc3RSdWxlXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LXJ1bGVcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIHByaW9yaXR5OiAxMDAsXG4gICAgICAgIGFjdGlvbjogXCJEZW55XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIlRjcFwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnJ1bGVDb2xsZWN0aW9uSWQpLnRvQmUocnVsZUNvbGxlY3Rpb24uaWQpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkNESyBTeW50aGVzaXNcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIHN5bnRoZXNpemUgdmFsaWQgVGVycmFmb3JtIGNvbmZpZ3VyYXRpb25cIiwgKCkgPT4ge1xuICAgICAgbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIlRlc3RSdWxlXCIsIHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LXJ1bGVcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIlRlc3Qgc2VjdXJpdHkgcnVsZVwiLFxuICAgICAgICBwcmlvcml0eTogMTAwLFxuICAgICAgICBhY3Rpb246IFwiRGVueVwiLFxuICAgICAgICBkaXJlY3Rpb246IFwiSW5ib3VuZFwiLFxuICAgICAgICBwcm90b2NvbDogXCJUY3BcIixcbiAgICAgICAgZGVzdGluYXRpb25Qb3J0UmFuZ2VzOiBbXCIyMlwiXSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBzeW50aGVzaXplZCA9IFRlc3Rpbmcuc3ludGgoc3RhY2spO1xuICAgICAgZXhwZWN0KHN5bnRoZXNpemVkKS50b0JlRGVmaW5lZCgpO1xuICAgICAgY29uc3Qgc3RhY2tDb25maWcgPSBKU09OLnBhcnNlKHN5bnRoZXNpemVkKTtcbiAgICAgIGV4cGVjdChzdGFja0NvbmZpZy5yZXNvdXJjZSkudG9CZURlZmluZWQoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJDb21wbGV4IFJ1bGUgU2NlbmFyaW9zXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBoYW5kbGUgcnVsZSB3aXRoIGFsbCBwcm9wZXJ0aWVzIHNwZWNpZmllZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBydWxlID0gbmV3IFNlY3VyaXR5QWRtaW5SdWxlKHN0YWNrLCBcIkNvbXBsZXhSdWxlXCIsIHtcbiAgICAgICAgbmFtZTogXCJjb21wbGV4LXJ1bGVcIixcbiAgICAgICAgcnVsZUNvbGxlY3Rpb25JZDogcnVsZUNvbGxlY3Rpb24uaWQsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIkNvbXBsZXggc2VjdXJpdHkgcnVsZSB3aXRoIGFsbCBwcm9wZXJ0aWVzXCIsXG4gICAgICAgIHByaW9yaXR5OiAxNTAsXG4gICAgICAgIGFjdGlvbjogXCJEZW55XCIsXG4gICAgICAgIGRpcmVjdGlvbjogXCJJbmJvdW5kXCIsXG4gICAgICAgIHByb3RvY29sOiBcIlRjcFwiLFxuICAgICAgICBzb3VyY2VQb3J0UmFuZ2VzOiBbXCIxMDI0LTY1NTM1XCJdLFxuICAgICAgICBkZXN0aW5hdGlvblBvcnRSYW5nZXM6IFtcIjIyXCIsIFwiMzM4OVwiXSxcbiAgICAgICAgc291cmNlczogW1xuICAgICAgICAgIHsgYWRkcmVzc1ByZWZpeDogXCJJbnRlcm5ldFwiLCBhZGRyZXNzUHJlZml4VHlwZTogXCJTZXJ2aWNlVGFnXCIgfSxcbiAgICAgICAgICB7IGFkZHJlc3NQcmVmaXg6IFwiMTkyLjE2OC4wLjAvMTZcIiwgYWRkcmVzc1ByZWZpeFR5cGU6IFwiSVBQcmVmaXhcIiB9LFxuICAgICAgICBdLFxuICAgICAgICBkZXN0aW5hdGlvbnM6IFtcbiAgICAgICAgICB7IGFkZHJlc3NQcmVmaXg6IFwiMTAuMC4wLjAvOFwiLCBhZGRyZXNzUHJlZml4VHlwZTogXCJJUFByZWZpeFwiIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHJ1bGUucHJvcHMucHJpb3JpdHkpLnRvQmUoMTUwKTtcbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnNvdXJjZVBvcnRSYW5nZXMpLnRvRXF1YWwoW1wiMTAyNC02NTUzNVwiXSk7XG4gICAgICBleHBlY3QocnVsZS5wcm9wcy5kZXN0aW5hdGlvblBvcnRSYW5nZXMpLnRvRXF1YWwoW1wiMjJcIiwgXCIzMzg5XCJdKTtcbiAgICAgIGV4cGVjdChydWxlLnByb3BzLnNvdXJjZXMpLnRvSGF2ZUxlbmd0aCgyKTtcbiAgICAgIGV4cGVjdChydWxlLnByb3BzLmRlc3RpbmF0aW9ucykudG9IYXZlTGVuZ3RoKDEpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19