terraconstructs 0.0.11 → 0.0.13

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 (411) hide show
  1. package/.jsii +105205 -35113
  2. package/lib/aws/arn.js +1 -1
  3. package/lib/aws/aws-construct.d.ts +1 -1
  4. package/lib/aws/aws-construct.js +28 -2
  5. package/lib/aws/aws-stack.d.ts +2 -4
  6. package/lib/aws/aws-stack.js +21 -8
  7. package/lib/aws/aws-tags.d.ts +58 -0
  8. package/lib/aws/aws-tags.js +77 -0
  9. package/lib/aws/cloudwatch/actions/ec2.js +1 -1
  10. package/lib/aws/cloudwatch/actions/lambda.js +1 -1
  11. package/lib/aws/cloudwatch/alarm-base.js +1 -1
  12. package/lib/aws/cloudwatch/alarm-rule.js +1 -1
  13. package/lib/aws/cloudwatch/alarm-status-widget.js +1 -1
  14. package/lib/aws/cloudwatch/alarm.js +1 -1
  15. package/lib/aws/cloudwatch/composite-alarm.js +1 -1
  16. package/lib/aws/cloudwatch/dashboard.js +1 -1
  17. package/lib/aws/cloudwatch/data-protection-policy.js +3 -3
  18. package/lib/aws/cloudwatch/graph.js +8 -8
  19. package/lib/aws/cloudwatch/layout.js +3 -3
  20. package/lib/aws/cloudwatch/log-destinations/kinesis.js +1 -1
  21. package/lib/aws/cloudwatch/log-destinations/lambda.js +1 -1
  22. package/lib/aws/cloudwatch/log-group.js +1 -1
  23. package/lib/aws/cloudwatch/log-query.js +1 -1
  24. package/lib/aws/cloudwatch/log-stream.js +1 -1
  25. package/lib/aws/cloudwatch/metric-filter.d.ts +1 -1
  26. package/lib/aws/cloudwatch/metric-filter.js +4 -4
  27. package/lib/aws/cloudwatch/metric.js +2 -2
  28. package/lib/aws/cloudwatch/pattern.js +3 -3
  29. package/lib/aws/cloudwatch/policy.js +1 -1
  30. package/lib/aws/cloudwatch/private/env-tokens.js +5 -6
  31. package/lib/aws/cloudwatch/private/metric-util.js +4 -5
  32. package/lib/aws/cloudwatch/private/object.js +2 -3
  33. package/lib/aws/cloudwatch/private/rendering.js +3 -3
  34. package/lib/aws/cloudwatch/private/statistic.js +6 -7
  35. package/lib/aws/cloudwatch/query-definition.js +2 -2
  36. package/lib/aws/cloudwatch/stats.js +1 -1
  37. package/lib/aws/cloudwatch/subscription-filter.d.ts +1 -1
  38. package/lib/aws/cloudwatch/subscription-filter.js +4 -4
  39. package/lib/aws/cloudwatch/text.js +1 -1
  40. package/lib/aws/cloudwatch/variable.js +3 -3
  41. package/lib/aws/cloudwatch/widget.d.ts +1 -1
  42. package/lib/aws/cloudwatch/widget.js +4 -4
  43. package/lib/aws/compute/activity.js +3 -2
  44. package/lib/aws/compute/alb/application-listener-action.d.ts +334 -0
  45. package/lib/aws/compute/alb/application-listener-action.js +281 -0
  46. package/lib/aws/compute/alb/application-listener-certificate.d.ts +35 -0
  47. package/lib/aws/compute/alb/application-listener-certificate.js +35 -0
  48. package/lib/aws/compute/alb/application-listener-rule.d.ts +233 -0
  49. package/lib/aws/compute/alb/application-listener-rule.js +220 -0
  50. package/lib/aws/compute/alb/application-listener.d.ts +574 -0
  51. package/lib/aws/compute/alb/application-listener.js +538 -0
  52. package/lib/aws/compute/alb/application-load-balancer.d.ts +715 -0
  53. package/lib/aws/compute/alb/application-load-balancer.js +780 -0
  54. package/lib/aws/compute/alb/application-target-group.d.ts +339 -0
  55. package/lib/aws/compute/alb/application-target-group.js +427 -0
  56. package/lib/aws/compute/alb/conditions.d.ts +61 -0
  57. package/lib/aws/compute/alb/conditions.js +164 -0
  58. package/lib/aws/compute/alb/trust-store-revocation.d.ts +59 -0
  59. package/lib/aws/compute/alb/trust-store-revocation.js +46 -0
  60. package/lib/aws/compute/alb/trust-store.d.ts +86 -0
  61. package/lib/aws/compute/alb/trust-store.js +79 -0
  62. package/lib/aws/compute/architecture.js +1 -1
  63. package/lib/aws/compute/aspects/require-imdsv2-aspect.d.ts +75 -0
  64. package/lib/aws/compute/aspects/require-imdsv2-aspect.js +106 -0
  65. package/lib/aws/compute/bastion-host.d.ts +172 -0
  66. package/lib/aws/compute/bastion-host.js +114 -0
  67. package/lib/aws/compute/chain.js +1 -1
  68. package/lib/aws/compute/cidr-splits.d.ts +49 -0
  69. package/lib/aws/compute/cidr-splits.js +59 -0
  70. package/lib/aws/compute/client-vpn-authorization-rule.d.ts +43 -0
  71. package/lib/aws/compute/client-vpn-authorization-rule.js +30 -0
  72. package/lib/aws/compute/client-vpn-endpoint-types.d.ts +62 -0
  73. package/lib/aws/compute/client-vpn-endpoint-types.js +25 -0
  74. package/lib/aws/compute/client-vpn-endpoint.d.ts +239 -0
  75. package/lib/aws/compute/client-vpn-endpoint.js +259 -0
  76. package/lib/aws/compute/client-vpn-route.d.ts +67 -0
  77. package/lib/aws/compute/client-vpn-route.js +57 -0
  78. package/lib/aws/compute/condition.js +1 -1
  79. package/lib/aws/compute/connections.d.ts +137 -0
  80. package/lib/aws/compute/connections.js +208 -0
  81. package/lib/aws/compute/ec2-augmentations.generated.d.ts +53 -0
  82. package/lib/aws/compute/ec2-augmentations.generated.js +35 -0
  83. package/lib/aws/compute/ec2-canned-metrics.generated.d.ts +555 -0
  84. package/lib/aws/compute/ec2-canned-metrics.generated.js +681 -0
  85. package/lib/aws/compute/ec2-util-v2.d.ts +141 -0
  86. package/lib/aws/compute/ec2-util-v2.js +286 -0
  87. package/lib/aws/compute/ec2-util.d.ts +52 -0
  88. package/lib/aws/compute/ec2-util.js +138 -0
  89. package/lib/aws/compute/elasticloadbalancing-canned-metrics.generated.d.ts +176 -0
  90. package/lib/aws/compute/elasticloadbalancing-canned-metrics.generated.js +119 -0
  91. package/lib/aws/compute/elasticloadbalancingv2-canned-metrics.generated.d.ts +860 -0
  92. package/lib/aws/compute/elasticloadbalancingv2-canned-metrics.generated.js +597 -0
  93. package/lib/aws/compute/event-invoke-config.js +1 -1
  94. package/lib/aws/compute/event-source-filter.js +2 -2
  95. package/lib/aws/compute/event-source-mapping.js +1 -1
  96. package/lib/aws/compute/event-sources/s3-onfailure-destination.js +1 -1
  97. package/lib/aws/compute/event-sources/s3.js +1 -1
  98. package/lib/aws/compute/event-sources/sqs-dlq.js +1 -1
  99. package/lib/aws/compute/event-sources/sqs.js +1 -1
  100. package/lib/aws/compute/fields.js +4 -4
  101. package/lib/aws/compute/function-alias.js +1 -1
  102. package/lib/aws/compute/function-base.js +2 -2
  103. package/lib/aws/compute/function-destinations/event-bridge.js +1 -1
  104. package/lib/aws/compute/function-destinations/function.js +1 -1
  105. package/lib/aws/compute/function-destinations/sqs.js +1 -1
  106. package/lib/aws/compute/function-nodejs.js +1 -1
  107. package/lib/aws/compute/function-url.js +1 -1
  108. package/lib/aws/compute/function-vpc-config.generated.d.ts +3 -3
  109. package/lib/aws/compute/function-vpc-config.generated.js +1 -1
  110. package/lib/aws/compute/function.d.ts +1 -1
  111. package/lib/aws/compute/function.js +5 -5
  112. package/lib/aws/compute/index-alpha.d.ts +5 -0
  113. package/lib/aws/compute/index-alpha.js +22 -0
  114. package/lib/aws/compute/index.d.ts +60 -0
  115. package/lib/aws/compute/index.js +70 -2
  116. package/lib/aws/compute/instance-types.d.ts +1354 -0
  117. package/lib/aws/compute/instance-types.js +1683 -0
  118. package/lib/aws/compute/instance.d.ts +436 -0
  119. package/lib/aws/compute/instance.js +262 -0
  120. package/lib/aws/compute/ip-addresses.d.ts +249 -0
  121. package/lib/aws/compute/ip-addresses.js +248 -0
  122. package/lib/aws/compute/ipam.d.ts +309 -0
  123. package/lib/aws/compute/ipam.js +306 -0
  124. package/lib/aws/compute/key-pair.d.ts +178 -0
  125. package/lib/aws/compute/key-pair.js +194 -0
  126. package/lib/aws/compute/lambda-augmentations.generated.d.ts +65 -0
  127. package/lib/aws/compute/lambda-augmentations.generated.js +41 -0
  128. package/lib/aws/compute/lambda-canned-metrics.generated.d.ts +316 -0
  129. package/lib/aws/compute/lambda-canned-metrics.generated.js +119 -0
  130. package/lib/aws/compute/launch-template.d.ts +540 -0
  131. package/lib/aws/compute/launch-template.js +468 -0
  132. package/lib/aws/compute/lb-shared/access-logs-accounts.d.ts +7 -0
  133. package/lib/aws/compute/lb-shared/access-logs-accounts.js +46 -0
  134. package/lib/aws/compute/lb-shared/base-listener.d.ts +113 -0
  135. package/lib/aws/compute/lb-shared/base-listener.js +181 -0
  136. package/lib/aws/compute/lb-shared/base-load-balancer.d.ts +212 -0
  137. package/lib/aws/compute/lb-shared/base-load-balancer.js +290 -0
  138. package/lib/aws/compute/lb-shared/base-target-group.d.ts +382 -0
  139. package/lib/aws/compute/lb-shared/base-target-group.js +364 -0
  140. package/lib/aws/compute/lb-shared/enums.d.ts +282 -0
  141. package/lib/aws/compute/lb-shared/enums.js +301 -0
  142. package/lib/aws/compute/lb-shared/grid-lookup-types.d.ts +42 -0
  143. package/lib/aws/compute/lb-shared/grid-lookup-types.js +53 -0
  144. package/lib/aws/compute/lb-shared/imported.d.ts +24 -0
  145. package/lib/aws/compute/lb-shared/imported.js +27 -0
  146. package/lib/aws/compute/lb-shared/lb-listener-config.generated.d.ts +194 -0
  147. package/lib/aws/compute/lb-shared/lb-listener-config.generated.js +3 -0
  148. package/lib/aws/compute/lb-shared/lb-target-group-attachment-config.generated.d.ts +56 -0
  149. package/lib/aws/compute/lb-shared/lb-target-group-attachment-config.generated.js +3 -0
  150. package/lib/aws/compute/lb-shared/listener-action.d.ts +14 -0
  151. package/lib/aws/compute/lb-shared/listener-action.js +4 -0
  152. package/lib/aws/compute/lb-shared/listener-certificate.d.ts +28 -0
  153. package/lib/aws/compute/lb-shared/listener-certificate.js +29 -0
  154. package/lib/aws/compute/lb-shared/load-balancer-targets.d.ts +93 -0
  155. package/lib/aws/compute/lb-shared/load-balancer-targets.js +127 -0
  156. package/lib/aws/compute/lb-shared/util.d.ts +113 -0
  157. package/lib/aws/compute/lb-shared/util.js +264 -0
  158. package/lib/aws/compute/lb-targets/alb-target.d.ts +67 -0
  159. package/lib/aws/compute/lb-targets/alb-target.js +100 -0
  160. package/lib/aws/compute/lb-targets/index.d.ts +4 -0
  161. package/lib/aws/compute/lb-targets/index.js +22 -0
  162. package/lib/aws/compute/lb-targets/instance-target.d.ts +42 -0
  163. package/lib/aws/compute/lb-targets/instance-target.js +67 -0
  164. package/lib/aws/compute/lb-targets/ip-target.d.ts +55 -0
  165. package/lib/aws/compute/lb-targets/ip-target.js +79 -0
  166. package/lib/aws/compute/lb-targets/lambda-target.d.ts +25 -0
  167. package/lib/aws/compute/lb-targets/lambda-target.js +50 -0
  168. package/lib/aws/compute/load-balancer.d.ts +336 -0
  169. package/lib/aws/compute/load-balancer.js +287 -0
  170. package/lib/aws/compute/machine-image/amazon-linux-2022.d.ts +63 -0
  171. package/lib/aws/compute/machine-image/amazon-linux-2022.js +84 -0
  172. package/lib/aws/compute/machine-image/amazon-linux-2023.d.ts +63 -0
  173. package/lib/aws/compute/machine-image/amazon-linux-2023.js +84 -0
  174. package/lib/aws/compute/machine-image/amazon-linux2.d.ts +76 -0
  175. package/lib/aws/compute/machine-image/amazon-linux2.js +87 -0
  176. package/lib/aws/compute/machine-image/common.d.ts +181 -0
  177. package/lib/aws/compute/machine-image/common.js +122 -0
  178. package/lib/aws/compute/machine-image/index.d.ts +5 -0
  179. package/lib/aws/compute/machine-image/index.js +22 -0
  180. package/lib/aws/compute/machine-image/machine-image.d.ts +463 -0
  181. package/lib/aws/compute/machine-image/machine-image.js +566 -0
  182. package/lib/aws/compute/machine-image/utils.d.ts +2 -0
  183. package/lib/aws/compute/machine-image/utils.js +17 -0
  184. package/lib/aws/compute/nat.d.ts +325 -0
  185. package/lib/aws/compute/nat.js +455 -0
  186. package/lib/aws/compute/network-acl-types.d.ts +152 -0
  187. package/lib/aws/compute/network-acl-types.js +156 -0
  188. package/lib/aws/compute/network-acl.d.ts +285 -0
  189. package/lib/aws/compute/network-acl.js +207 -0
  190. package/lib/aws/compute/network-util.d.ts +116 -0
  191. package/lib/aws/compute/network-util.js +241 -0
  192. package/lib/aws/compute/nlb/network-listener-action.d.ts +92 -0
  193. package/lib/aws/compute/nlb/network-listener-action.js +146 -0
  194. package/lib/aws/compute/nlb/network-listener-certificate.d.ts +24 -0
  195. package/lib/aws/compute/nlb/network-listener-certificate.js +25 -0
  196. package/lib/aws/compute/nlb/network-listener.d.ts +248 -0
  197. package/lib/aws/compute/nlb/network-listener.js +217 -0
  198. package/lib/aws/compute/nlb/network-load-balancer.d.ts +315 -0
  199. package/lib/aws/compute/nlb/network-load-balancer.js +360 -0
  200. package/lib/aws/compute/nlb/network-target-group.d.ts +153 -0
  201. package/lib/aws/compute/nlb/network-target-group.js +223 -0
  202. package/lib/aws/compute/peer.d.ts +64 -0
  203. package/lib/aws/compute/peer.js +235 -0
  204. package/lib/aws/compute/placement-group.d.ts +161 -0
  205. package/lib/aws/compute/placement-group.js +133 -0
  206. package/lib/aws/compute/port.d.ts +287 -0
  207. package/lib/aws/compute/port.js +390 -0
  208. package/lib/aws/compute/prefix-list.d.ts +131 -0
  209. package/lib/aws/compute/prefix-list.js +114 -0
  210. package/lib/aws/compute/private/context-stub.d.ts +7 -0
  211. package/lib/aws/compute/private/context-stub.js +43 -0
  212. package/lib/aws/compute/private/ebs-util.d.ts +14 -0
  213. package/lib/aws/compute/private/ebs-util.js +145 -0
  214. package/lib/aws/compute/private/intrinstics.js +2 -1
  215. package/lib/aws/compute/private/json-path.js +8 -8
  216. package/lib/aws/compute/private/util.js +2 -3
  217. package/lib/aws/compute/route.d.ts +547 -0
  218. package/lib/aws/compute/route.js +469 -0
  219. package/lib/aws/compute/security-group.d.ts +414 -0
  220. package/lib/aws/compute/security-group.js +538 -0
  221. package/lib/aws/compute/state-graph.js +1 -1
  222. package/lib/aws/compute/state-machine-fragment.js +1 -1
  223. package/lib/aws/compute/state-machine.d.ts +2 -2
  224. package/lib/aws/compute/state-machine.js +14 -12
  225. package/lib/aws/compute/states/choice.js +1 -1
  226. package/lib/aws/compute/states/custom-state.js +1 -1
  227. package/lib/aws/compute/states/distributed-map/item-batcher.js +1 -1
  228. package/lib/aws/compute/states/distributed-map/item-reader.js +5 -5
  229. package/lib/aws/compute/states/distributed-map/result-writer.js +1 -1
  230. package/lib/aws/compute/states/distributed-map.js +1 -1
  231. package/lib/aws/compute/states/fail.js +1 -1
  232. package/lib/aws/compute/states/map-base.js +1 -1
  233. package/lib/aws/compute/states/map.js +1 -1
  234. package/lib/aws/compute/states/parallel.js +1 -1
  235. package/lib/aws/compute/states/pass.js +2 -2
  236. package/lib/aws/compute/states/state.js +5 -5
  237. package/lib/aws/compute/states/succeed.js +1 -1
  238. package/lib/aws/compute/states/task-base.js +2 -2
  239. package/lib/aws/compute/states/task.js +1 -1
  240. package/lib/aws/compute/states/wait.js +2 -2
  241. package/lib/aws/compute/stepfunctions-canned-metrics.generated.d.ts +83 -0
  242. package/lib/aws/compute/stepfunctions-canned-metrics.generated.js +127 -0
  243. package/lib/aws/compute/subnet-v2.d.ts +213 -0
  244. package/lib/aws/compute/subnet-v2.js +405 -0
  245. package/lib/aws/compute/subnet.d.ts +37 -0
  246. package/lib/aws/compute/subnet.js +181 -0
  247. package/lib/aws/compute/task-credentials.js +1 -1
  248. package/lib/aws/compute/task-input.js +1 -1
  249. package/lib/aws/compute/tasks/aws-sdk/call-aws-service.js +1 -1
  250. package/lib/aws/compute/tasks/eventbridge/put-events.js +1 -1
  251. package/lib/aws/compute/tasks/http/invoke.js +1 -1
  252. package/lib/aws/compute/tasks/lambda/invoke.js +1 -1
  253. package/lib/aws/compute/tasks/private/task-utils.js +3 -4
  254. package/lib/aws/compute/tasks/resource-arn-suffix.js +2 -3
  255. package/lib/aws/compute/tasks/sqs/send-message.js +1 -1
  256. package/lib/aws/compute/tasks/stepfunctions/invoke-activity.js +1 -1
  257. package/lib/aws/compute/tasks/stepfunctions/start-execution.js +1 -1
  258. package/lib/aws/compute/types.js +2 -2
  259. package/lib/aws/compute/user-data.d.ts +270 -0
  260. package/lib/aws/compute/user-data.js +487 -0
  261. package/lib/aws/compute/util.d.ts +1 -1
  262. package/lib/aws/compute/util.js +4 -5
  263. package/lib/aws/compute/volume.d.ts +480 -0
  264. package/lib/aws/compute/volume.js +426 -0
  265. package/lib/aws/compute/vpc-endpoint-service.d.ts +149 -0
  266. package/lib/aws/compute/vpc-endpoint-service.js +90 -0
  267. package/lib/aws/compute/vpc-endpoint.d.ts +742 -0
  268. package/lib/aws/compute/vpc-endpoint.js +811 -0
  269. package/lib/aws/compute/vpc-flow-logs.d.ts +551 -0
  270. package/lib/aws/compute/vpc-flow-logs.js +693 -0
  271. package/lib/aws/compute/vpc-lookup.d.ts +73 -0
  272. package/lib/aws/compute/vpc-lookup.js +3 -0
  273. package/lib/aws/compute/vpc-v2-base.d.ts +353 -0
  274. package/lib/aws/compute/vpc-v2-base.js +493 -0
  275. package/lib/aws/compute/vpc-v2.d.ts +385 -0
  276. package/lib/aws/compute/vpc-v2.js +408 -0
  277. package/lib/aws/compute/vpc.d.ts +1448 -0
  278. package/lib/aws/compute/vpc.js +1495 -0
  279. package/lib/aws/compute/vpn.d.ts +443 -0
  280. package/lib/aws/compute/vpn.js +397 -0
  281. package/lib/aws/compute/windows-versions.d.ts +418 -0
  282. package/lib/aws/compute/windows-versions.js +426 -0
  283. package/lib/aws/edge/certificate-base.d.ts +20 -0
  284. package/lib/aws/edge/certificate-base.js +28 -0
  285. package/lib/aws/edge/certificate.d.ts +23 -2
  286. package/lib/aws/edge/certificate.js +54 -4
  287. package/lib/aws/edge/distribution.js +3 -3
  288. package/lib/aws/edge/dns-alias-record-targets.js +2 -2
  289. package/lib/aws/edge/dns-record.js +16 -16
  290. package/lib/aws/edge/dns-zone.d.ts +20 -2
  291. package/lib/aws/edge/dns-zone.js +25 -10
  292. package/lib/aws/edge/function.js +2 -2
  293. package/lib/aws/edge/index.d.ts +1 -0
  294. package/lib/aws/edge/index.js +2 -1
  295. package/lib/aws/edge/key-value-store.js +4 -4
  296. package/lib/aws/edge/origin.js +7 -5
  297. package/lib/aws/edge/response-headers-policy.js +1 -1
  298. package/lib/aws/encryption/alias.js +1 -1
  299. package/lib/aws/encryption/key.js +1 -1
  300. package/lib/aws/encryption/via-service-principal.js +1 -1
  301. package/lib/aws/iam/grant.js +2 -2
  302. package/lib/aws/iam/index.d.ts +1 -0
  303. package/lib/aws/iam/index.js +2 -1
  304. package/lib/aws/iam/instance-profile.d.ts +155 -0
  305. package/lib/aws/iam/instance-profile.js +124 -0
  306. package/lib/aws/iam/managed-policy.js +1 -1
  307. package/lib/aws/iam/oidc-provider.js +1 -1
  308. package/lib/aws/iam/policy-document-config.generated.d.ts +8 -8
  309. package/lib/aws/iam/policy-document-config.generated.js +1 -1
  310. package/lib/aws/iam/policy-document.js +1 -1
  311. package/lib/aws/iam/policy-statement-props.generated.d.ts +8 -8
  312. package/lib/aws/iam/policy-statement-props.generated.js +1 -1
  313. package/lib/aws/iam/policy-statement.js +9 -9
  314. package/lib/aws/iam/policy.js +1 -1
  315. package/lib/aws/iam/principals.js +26 -26
  316. package/lib/aws/iam/private/assume-role-policy.js +2 -3
  317. package/lib/aws/iam/private/comparable-principal.js +2 -3
  318. package/lib/aws/iam/private/immutable-role.d.ts +2 -1
  319. package/lib/aws/iam/private/immutable-role.js +3 -3
  320. package/lib/aws/iam/private/imported-role.d.ts +1 -1
  321. package/lib/aws/iam/private/imported-role.js +3 -3
  322. package/lib/aws/iam/private/merge-statements.js +2 -3
  323. package/lib/aws/iam/private/util.js +4 -4
  324. package/lib/aws/iam/role.js +1 -1
  325. package/lib/aws/iam/saml-provider.d.ts +1 -1
  326. package/lib/aws/iam/saml-provider.js +6 -6
  327. package/lib/aws/iam/unknown-principal.js +1 -1
  328. package/lib/aws/iam/utils.js +2 -3
  329. package/lib/aws/index.d.ts +1 -0
  330. package/lib/aws/index.js +4 -1
  331. package/lib/aws/network/simple-ipv4-vpc.js +5 -5
  332. package/lib/aws/network/subnet-group.js +3 -3
  333. package/lib/aws/network/subnet.d.ts +1 -1
  334. package/lib/aws/network/subnet.js +7 -7
  335. package/lib/aws/notify/archive.js +3 -2
  336. package/lib/aws/notify/connection.js +5 -4
  337. package/lib/aws/notify/event-bus.js +5 -4
  338. package/lib/aws/notify/event-pattern.d.ts +26 -1
  339. package/lib/aws/notify/event-pattern.js +49 -5
  340. package/lib/aws/notify/index.js +3 -1
  341. package/lib/aws/notify/input.js +4 -3
  342. package/lib/aws/notify/kinesis-stream.js +3 -2
  343. package/lib/aws/notify/on-event-options.js +2 -1
  344. package/lib/aws/notify/queue-config.generated.d.ts +18 -11
  345. package/lib/aws/notify/queue-config.generated.js +1 -1
  346. package/lib/aws/notify/queue-policy.js +1 -1
  347. package/lib/aws/notify/queue.js +1 -1
  348. package/lib/aws/notify/resource-policy.js +1 -1
  349. package/lib/aws/notify/rule.js +3 -2
  350. package/lib/aws/notify/schedule.js +2 -2
  351. package/lib/aws/notify/sqs-augmentations.generated.d.ts +125 -0
  352. package/lib/aws/notify/sqs-augmentations.generated.js +74 -0
  353. package/lib/aws/notify/target.js +2 -1
  354. package/lib/aws/notify/targets/event-bus.js +1 -1
  355. package/lib/aws/notify/targets/function.js +1 -1
  356. package/lib/aws/notify/targets/log-group.js +2 -2
  357. package/lib/aws/notify/targets/sqs.js +1 -1
  358. package/lib/aws/notify/targets/state-machine.js +1 -1
  359. package/lib/aws/notify/targets/util.d.ts +1 -1
  360. package/lib/aws/notify/targets/util.js +10 -11
  361. package/lib/aws/notify/util.js +4 -4
  362. package/lib/aws/provider-config.generated.d.ts +33 -33
  363. package/lib/aws/provider-config.generated.js +1 -1
  364. package/lib/aws/storage/bucket-notifications.js +1 -1
  365. package/lib/aws/storage/bucket-policy.js +1 -1
  366. package/lib/aws/storage/bucket-source.js +1 -1
  367. package/lib/aws/storage/bucket.d.ts +298 -65
  368. package/lib/aws/storage/bucket.js +548 -225
  369. package/lib/aws/storage/cors-config.generated.d.ts +3 -3
  370. package/lib/aws/storage/cors-config.generated.js +1 -1
  371. package/lib/aws/storage/cors-rule-config.generated.d.ts +5 -5
  372. package/lib/aws/storage/cors-rule-config.generated.js +1 -1
  373. package/lib/aws/storage/index.d.ts +1 -0
  374. package/lib/aws/storage/index.js +2 -1
  375. package/lib/aws/storage/lifecycle-config.generated.d.ts +11 -11
  376. package/lib/aws/storage/lifecycle-config.generated.js +1 -1
  377. package/lib/aws/storage/notification-targets/function.js +6 -6
  378. package/lib/aws/storage/notification-targets/queue.js +1 -1
  379. package/lib/aws/storage/origin-access-identity.d.ts +1 -1
  380. package/lib/aws/storage/origin-access-identity.js +5 -4
  381. package/lib/aws/storage/parameter-util.d.ts +12 -0
  382. package/lib/aws/storage/parameter-util.js +65 -0
  383. package/lib/aws/storage/parameter.d.ts +526 -0
  384. package/lib/aws/storage/parameter.js +606 -0
  385. package/lib/aws/storage/s3-canned-metrics.generated.d.ts +22 -0
  386. package/lib/aws/storage/s3-canned-metrics.generated.js +23 -0
  387. package/lib/aws/storage/util.d.ts +25 -3
  388. package/lib/aws/storage/util.js +84 -17
  389. package/lib/aws/storage/website-config.generated.d.ts +5 -5
  390. package/lib/aws/storage/website-config.generated.js +1 -1
  391. package/lib/aws/util.js +2 -3
  392. package/lib/construct-base.d.ts +10 -1
  393. package/lib/construct-base.js +9 -6
  394. package/lib/duration.js +1 -1
  395. package/lib/expiration.d.ts +48 -0
  396. package/lib/expiration.js +68 -0
  397. package/lib/helpers-internal/index.d.ts +1 -0
  398. package/lib/helpers-internal/index.js +7 -0
  399. package/lib/index.d.ts +2 -0
  400. package/lib/index.js +3 -1
  401. package/lib/private/md5.d.ts +4 -0
  402. package/lib/private/md5.js +14 -0
  403. package/lib/private/unique-resource-name.js +3 -4
  404. package/lib/size.js +2 -2
  405. package/lib/stack-base.d.ts +4 -23
  406. package/lib/stack-base.js +9 -30
  407. package/lib/terra-func.d.ts +103 -0
  408. package/lib/terra-func.js +170 -0
  409. package/lib/token.js +5 -5
  410. package/package.json +15 -8
  411. package/bun.lockb +0 -0
@@ -0,0 +1,780 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.HttpCodeTarget = exports.HttpCodeElb = exports.ApplicationLoadBalancer = exports.XffHeaderProcessingMode = void 0;
5
+ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
6
+ const cdktf_1 = require("cdktf");
7
+ const application_listener_1 = require("./application-listener");
8
+ const application_listener_action_1 = require("./application-listener-action");
9
+ const aws_construct_1 = require("../../aws-construct");
10
+ const aws_stack_1 = require("../../aws-stack");
11
+ const cloudwatch = require("../../cloudwatch");
12
+ const policy_statement_1 = require("../../iam/policy-statement");
13
+ const principals_1 = require("../../iam/principals");
14
+ const connections_1 = require("../connections");
15
+ // import {
16
+ // LoadBalancerType,
17
+ // LoadBalancerListenerProtocol,
18
+ // } from "../lb-shared/grid-lookup-types";
19
+ const elasticloadbalancingv2_canned_metrics_generated_1 = require("../elasticloadbalancingv2-canned-metrics.generated");
20
+ const base_load_balancer_1 = require("../lb-shared/base-load-balancer");
21
+ const enums_1 = require("../lb-shared/enums");
22
+ const util_1 = require("../lb-shared/util");
23
+ const security_group_1 = require("../security-group");
24
+ /**
25
+ * Processing mode of the X-Forwarded-For header in the HTTP request
26
+ * before the Application Load Balancer sends the request to the target.
27
+ */
28
+ var XffHeaderProcessingMode;
29
+ (function (XffHeaderProcessingMode) {
30
+ /**
31
+ * Application Load Balancer adds the client IP address (of the last hop) to the X-Forwarded-For header
32
+ * in the HTTP request before it sends it to targets.
33
+ */
34
+ XffHeaderProcessingMode["APPEND"] = "append";
35
+ /**
36
+ * Application Load Balancer preserves the X-Forwarded-For header in the HTTP request,
37
+ * and sends it to targets without any change.
38
+ */
39
+ XffHeaderProcessingMode["PRESERVE"] = "preserve";
40
+ /**
41
+ * Application Load Balancer removes the X-Forwarded-For header
42
+ * in the HTTP request before it sends it to targets.
43
+ */
44
+ XffHeaderProcessingMode["REMOVE"] = "remove";
45
+ })(XffHeaderProcessingMode || (exports.XffHeaderProcessingMode = XffHeaderProcessingMode = {}));
46
+ /**
47
+ * Define an Application Load Balancer
48
+ *
49
+ * @resource AWS::ElasticLoadBalancingV2::LoadBalancer
50
+ */
51
+ class ApplicationLoadBalancer extends base_load_balancer_1.BaseLoadBalancer {
52
+ // TODO: Add Grid lookup support
53
+ // /**
54
+ // * Look up an application load balancer.
55
+ // */
56
+ // public static fromLookup(
57
+ // scope: Construct,
58
+ // id: string,
59
+ // options: ApplicationLoadBalancerLookupOptions,
60
+ // ): IApplicationLoadBalancer {
61
+ // const props = BaseLoadBalancer._queryContextProvider(scope, {
62
+ // userOptions: options,
63
+ // loadBalancerType: LoadBalancerType.APPLICATION,
64
+ // });
65
+ // return new LookedUpApplicationLoadBalancer(scope, id, props);
66
+ // }
67
+ /**
68
+ * Import an existing Application Load Balancer
69
+ */
70
+ static fromApplicationLoadBalancerAttributes(scope, id, attrs) {
71
+ return new ImportedApplicationLoadBalancer(scope, id, attrs);
72
+ }
73
+ constructor(scope, id, props) {
74
+ super(scope, id, props, {
75
+ loadBalancerType: "application",
76
+ securityGroups: cdktf_1.Lazy.listValue({
77
+ produce: () => this.connections.securityGroups.map((sg) => sg.securityGroupId),
78
+ }),
79
+ ipAddressType: props.ipAddressType,
80
+ });
81
+ this.ipAddressType = props.ipAddressType ?? enums_1.IpAddressType.IPV4;
82
+ if (props.ipAddressType === enums_1.IpAddressType.DUAL_STACK_WITHOUT_PUBLIC_IPV4 &&
83
+ !props.internetFacing) {
84
+ throw new Error("dual-stack without public IPv4 address can only be used with internet-facing scheme.");
85
+ }
86
+ const securityGroups = [
87
+ props.securityGroup ||
88
+ new security_group_1.SecurityGroup(this, "SecurityGroup", {
89
+ vpc: props.vpc,
90
+ description: `Automatically created Security Group for ELB ${aws_stack_1.AwsStack.uniqueId(this)}`,
91
+ allowAllOutbound: false,
92
+ }),
93
+ ];
94
+ this.connections = new connections_1.Connections({ securityGroups });
95
+ this.listeners = [];
96
+ this.metrics = new ApplicationLoadBalancerMetrics(this, this.loadBalancerFullName);
97
+ if (props.http2Enabled !== undefined) {
98
+ this.setAttribute("routing.http2.enabled", props.http2Enabled ? "true" : "false");
99
+ }
100
+ if (props.idleTimeout !== undefined) {
101
+ this.setAttribute("idle_timeout.timeout_seconds", props.idleTimeout.toSeconds().toString());
102
+ }
103
+ if (props.dropInvalidHeaderFields) {
104
+ this.setAttribute("routing.http.drop_invalid_header_fields.enabled", "true");
105
+ }
106
+ if (props.desyncMitigationMode !== undefined) {
107
+ this.setAttribute("routing.http.desync_mitigation_mode", props.desyncMitigationMode);
108
+ }
109
+ if (props.preserveHostHeader) {
110
+ this.setAttribute("routing.http.preserve_host_header.enabled", "true");
111
+ }
112
+ if (props.xAmznTlsVersionAndCipherSuiteHeaders) {
113
+ this.setAttribute("routing.http.x_amzn_tls_version_and_cipher_suite.enabled", "true");
114
+ }
115
+ if (props.preserveXffClientPort) {
116
+ this.setAttribute("routing.http.xff_client_port.enabled", "true");
117
+ }
118
+ if (props.xffHeaderProcessingMode !== undefined) {
119
+ this.setAttribute("routing.http.xff_header_processing.mode", props.xffHeaderProcessingMode);
120
+ }
121
+ if (props.wafFailOpen) {
122
+ this.setAttribute("waf.fail_open.enabled", "true");
123
+ }
124
+ if (props.clientKeepAlive !== undefined) {
125
+ const clientKeepAliveInMillis = props.clientKeepAlive.toMilliseconds();
126
+ if (clientKeepAliveInMillis < 1000) {
127
+ throw new Error(`\'clientKeepAlive\' must be between 60 and 604800 seconds. Got: ${clientKeepAliveInMillis} milliseconds`);
128
+ }
129
+ const clientKeepAliveInSeconds = props.clientKeepAlive.toSeconds();
130
+ if (clientKeepAliveInSeconds < 60 || clientKeepAliveInSeconds > 604800) {
131
+ throw new Error(`\'clientKeepAlive\' must be between 60 and 604800 seconds. Got: ${clientKeepAliveInSeconds} seconds`);
132
+ }
133
+ this.setAttribute("client_keep_alive.seconds", clientKeepAliveInSeconds.toString());
134
+ }
135
+ if (props.crossZoneEnabled === false) {
136
+ throw new Error("crossZoneEnabled cannot be false with Application Load Balancers.");
137
+ }
138
+ }
139
+ /**
140
+ * Add a new listener to this load balancer
141
+ */
142
+ addListener(id, props) {
143
+ const listener = new application_listener_1.ApplicationListener(this, id, {
144
+ loadBalancer: this,
145
+ ...props,
146
+ });
147
+ this.listeners.push(listener);
148
+ return listener;
149
+ }
150
+ /**
151
+ * Add a redirection listener to this load balancer
152
+ */
153
+ addRedirect(props = {}) {
154
+ const sourcePort = props.sourcePort ?? 80;
155
+ const targetPort = (props.targetPort ?? 443).toString();
156
+ return this.addListener(`Redirect${sourcePort}To${targetPort}`, {
157
+ protocol: props.sourceProtocol ?? enums_1.ApplicationProtocol.HTTP,
158
+ port: sourcePort,
159
+ open: props.open ?? true,
160
+ defaultAction: application_listener_action_1.ListenerAction.redirect({
161
+ port: targetPort,
162
+ protocol: props.targetProtocol ?? enums_1.ApplicationProtocol.HTTPS,
163
+ permanent: true,
164
+ }),
165
+ });
166
+ }
167
+ /**
168
+ * Enable access logging for this load balancer.
169
+ *
170
+ * A region must be specified on the stack containing the load balancer; you cannot enable logging on
171
+ * environment-agnostic stacks. See https://docs.aws.amazon.com/cdk/latest/guide/environments.html
172
+ */
173
+ logAccessLogs(bucket, prefix) {
174
+ // TODO: Why does this override BaseLoadBalancer.putAccessLogs?
175
+ /**
176
+ * KMS key encryption is not supported on Access Log bucket for ALB, the bucket must use Amazon S3-managed keys (SSE-S3).
177
+ * See https://docs.aws.amazon.com/elasticloadbalancing/latest/application/enable-access-logging.html#bucket-permissions-troubleshooting
178
+ */
179
+ if (bucket.encryptionKey) {
180
+ throw new Error("Encryption key detected. Bucket encryption using KMS keys is unsupported");
181
+ }
182
+ // prefix = prefix; // prefix is optional in TF || "";
183
+ this.setAttribute("access_logs.s3.enabled", "true");
184
+ this.setAttribute("access_logs.s3.bucket", bucket.bucketName.toString());
185
+ this.setAttribute("access_logs.s3.prefix", prefix);
186
+ const logsDeliveryServicePrincipal = new principals_1.ServicePrincipal("delivery.logs.amazonaws.com");
187
+ bucket.addToResourcePolicy(new policy_statement_1.PolicyStatement({
188
+ actions: ["s3:PutObject"],
189
+ principals: [this.resourcePolicyPrincipal()],
190
+ resources: [
191
+ bucket.arnForObjects(`${prefix ? prefix + "/" : ""}AWSLogs/${aws_stack_1.AwsStack.ofAwsConstruct(this).account}/*`),
192
+ ],
193
+ }));
194
+ bucket.addToResourcePolicy(new policy_statement_1.PolicyStatement({
195
+ actions: ["s3:PutObject"],
196
+ principals: [logsDeliveryServicePrincipal],
197
+ resources: [
198
+ bucket.arnForObjects(`${prefix ? prefix + "/" : ""}AWSLogs/${this.env.account}/*`),
199
+ ],
200
+ condition: [
201
+ {
202
+ test: "StringEquals",
203
+ variable: "s3:x-amz-acl",
204
+ values: ["bucket-owner-full-control"],
205
+ },
206
+ ],
207
+ }));
208
+ bucket.addToResourcePolicy(new policy_statement_1.PolicyStatement({
209
+ actions: ["s3:GetBucketAcl"],
210
+ principals: [logsDeliveryServicePrincipal],
211
+ resources: [bucket.bucketArn],
212
+ }));
213
+ // make sure the bucket's policy is created before the ALB (see https://github.com/aws/aws-cdk/issues/1633)
214
+ // at the L1 level to avoid creating a circular dependency (see https://github.com/aws/aws-cdk/issues/27528
215
+ // and https://github.com/aws/aws-cdk/issues/27928)
216
+ const lb = this.node.defaultChild;
217
+ const bucketPolicy = bucket.policy?.node.defaultChild;
218
+ if (lb &&
219
+ bucketPolicy &&
220
+ cdktf_1.TerraformResource.isTerraformResource(lb) &&
221
+ cdktf_1.TerraformResource.isTerraformResource(bucketPolicy)) {
222
+ lb.node.addDependency(bucketPolicy);
223
+ }
224
+ // TODO: Should putAccessLogs be handled as part of prepareStack (in toTerraform() instead)?
225
+ // only if lb.accessLogs.internalValue !== undefined? (or based on this.attributes?)
226
+ lb?.putAccessLogs({
227
+ enabled: this.lazyBoolAttr(util_1.LoadBalancerAttribute.accessLogsS3Enabled),
228
+ bucket: this.lazyStringAttr(util_1.LoadBalancerAttribute.accessLogsS3Bucket),
229
+ prefix: this.lazyStringAttr(util_1.LoadBalancerAttribute.accessLogsS3Prefix),
230
+ });
231
+ }
232
+ /**
233
+ * Enable connection logging for this load balancer.
234
+ *
235
+ * A region must be specified on the stack containing the load balancer; you cannot enable logging on
236
+ * environment-agnostic stacks.
237
+ *
238
+ * @see https://docs.aws.amazon.com/cdk/latest/guide/environments.html
239
+ */
240
+ logConnectionLogs(bucket, prefix) {
241
+ /**
242
+ * KMS key encryption is not supported on Connection Log bucket for ALB, the bucket must use Amazon S3-managed keys (SSE-S3).
243
+ * See https://docs.aws.amazon.com/elasticloadbalancing/latest/application/enable-connection-logging.html#bucket-permissions-troubleshooting-connection
244
+ */
245
+ if (bucket.encryptionKey) {
246
+ throw new Error("Encryption key detected. Bucket encryption using KMS keys is unsupported");
247
+ }
248
+ prefix = prefix || "";
249
+ this.setAttribute("connection_logs.s3.enabled", "true");
250
+ this.setAttribute("connection_logs.s3.bucket", bucket.bucketName.toString());
251
+ this.setAttribute("connection_logs.s3.prefix", prefix);
252
+ // https://docs.aws.amazon.com/elasticloadbalancing/latest/application/enable-connection-logging.html
253
+ const logsDeliveryServicePrincipal = new principals_1.ServicePrincipal("delivery.logs.amazonaws.com");
254
+ bucket.addToResourcePolicy(new policy_statement_1.PolicyStatement({
255
+ actions: ["s3:PutObject"],
256
+ principals: [this.resourcePolicyPrincipal()],
257
+ resources: [
258
+ bucket.arnForObjects(`${prefix ? prefix + "/" : ""}AWSLogs/${aws_stack_1.AwsStack.ofAwsConstruct(this).account}/*`),
259
+ ],
260
+ }));
261
+ // We still need this policy for the bucket using the ACL
262
+ bucket.addToResourcePolicy(new policy_statement_1.PolicyStatement({
263
+ actions: ["s3:PutObject"],
264
+ principals: [logsDeliveryServicePrincipal],
265
+ resources: [
266
+ bucket.arnForObjects(`${prefix ? prefix + "/" : ""}AWSLogs/${aws_stack_1.AwsStack.ofAwsConstruct(this).account}/*`),
267
+ ],
268
+ condition: [
269
+ {
270
+ test: "StringEquals",
271
+ variable: "s3:x-amz-acl",
272
+ values: ["bucket-owner-full-control"],
273
+ },
274
+ ],
275
+ }));
276
+ bucket.addToResourcePolicy(new policy_statement_1.PolicyStatement({
277
+ actions: ["s3:GetBucketAcl"],
278
+ principals: [logsDeliveryServicePrincipal],
279
+ resources: [bucket.bucketArn],
280
+ }));
281
+ // make sure the bucket's policy is created before the ALB (see https://github.com/aws/aws-cdk/issues/1633)
282
+ // at the L1 level to avoid creating a circular dependency (see https://github.com/aws/aws-cdk/issues/27528
283
+ // and https://github.com/aws/aws-cdk/issues/27928)
284
+ const lb = this.node.defaultChild;
285
+ const bucketPolicy = bucket.policy?.node.defaultChild;
286
+ if (lb &&
287
+ bucketPolicy &&
288
+ cdktf_1.TerraformResource.isTerraformResource(lb) &&
289
+ cdktf_1.TerraformResource.isTerraformResource(bucketPolicy)) {
290
+ lb.node.addDependency(bucketPolicy);
291
+ }
292
+ // TODO: Should putConnectionLogs be handled as part of prepareStack (in toTerraform() instead)?
293
+ // only if lb.connectionLogs.internalValue !== undefined? (or based on this.attributes?)
294
+ lb?.putConnectionLogs({
295
+ enabled: this.lazyBoolAttr(util_1.LoadBalancerAttribute.connectionLogsS3Enabled),
296
+ bucket: this.lazyStringAttr(util_1.LoadBalancerAttribute.connectionLogsS3Bucket),
297
+ prefix: this.lazyStringAttr(util_1.LoadBalancerAttribute.connectionLogsS3Prefix),
298
+ });
299
+ }
300
+ /**
301
+ * Add a security group to this load balancer
302
+ */
303
+ addSecurityGroup(securityGroup) {
304
+ this.connections.addSecurityGroup(securityGroup);
305
+ }
306
+ /**
307
+ * Return the given named metric for this Application Load Balancer
308
+ *
309
+ * @default Average over 5 minutes
310
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.custom`` instead
311
+ */
312
+ metric(metricName, props) {
313
+ return this.metrics.custom(metricName, props);
314
+ }
315
+ /**
316
+ * The total number of concurrent TCP connections active from clients to the
317
+ * load balancer and from the load balancer to targets.
318
+ *
319
+ * @default Sum over 5 minutes
320
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.activeConnectionCount`` instead
321
+ */
322
+ metricActiveConnectionCount(props) {
323
+ return this.metrics.activeConnectionCount(props);
324
+ }
325
+ /**
326
+ * The number of TLS connections initiated by the client that did not
327
+ * establish a session with the load balancer. Possible causes include a
328
+ * mismatch of ciphers or protocols.
329
+ *
330
+ * @default Sum over 5 minutes
331
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.clientTlsNegotiationErrorCount`` instead
332
+ */
333
+ metricClientTlsNegotiationErrorCount(props) {
334
+ return this.metrics.clientTlsNegotiationErrorCount(props);
335
+ }
336
+ /**
337
+ * The number of load balancer capacity units (LCU) used by your load balancer.
338
+ *
339
+ * @default Sum over 5 minutes
340
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.consumedLCUs`` instead
341
+ */
342
+ metricConsumedLCUs(props) {
343
+ return this.metrics.consumedLCUs(props);
344
+ }
345
+ /**
346
+ * The number of fixed-response actions that were successful.
347
+ *
348
+ * @default Sum over 5 minutes
349
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.httpFixedResponseCount`` instead
350
+ */
351
+ metricHttpFixedResponseCount(props) {
352
+ return this.metrics.httpFixedResponseCount(props);
353
+ }
354
+ /**
355
+ * The number of redirect actions that were successful.
356
+ *
357
+ * @default Sum over 5 minutes
358
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.httpRedirectCount`` instead
359
+ */
360
+ metricHttpRedirectCount(props) {
361
+ return this.metrics.httpRedirectCount(props);
362
+ }
363
+ /**
364
+ * The number of redirect actions that couldn't be completed because the URL
365
+ * in the response location header is larger than 8K.
366
+ *
367
+ * @default Sum over 5 minutes
368
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.httpRedirectUrlLimitExceededCount`` instead
369
+ */
370
+ metricHttpRedirectUrlLimitExceededCount(props) {
371
+ return this.metrics.httpRedirectUrlLimitExceededCount(props);
372
+ }
373
+ /**
374
+ * The number of HTTP 3xx/4xx/5xx codes that originate from the load balancer.
375
+ *
376
+ * This does not include any response codes generated by the targets.
377
+ *
378
+ * @default Sum over 5 minutes
379
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.httpCodeElb`` instead
380
+ */
381
+ metricHttpCodeElb(code, props) {
382
+ return this.metrics.httpCodeElb(code, props);
383
+ }
384
+ /**
385
+ * The number of HTTP 2xx/3xx/4xx/5xx response codes generated by all targets
386
+ * in the load balancer.
387
+ *
388
+ * This does not include any response codes generated by the load balancer.
389
+ *
390
+ * @default Sum over 5 minutes
391
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.httpCodeTarget`` instead
392
+ */
393
+ metricHttpCodeTarget(code, props) {
394
+ return this.metrics.httpCodeTarget(code, props);
395
+ }
396
+ /**
397
+ * The total number of bytes processed by the load balancer over IPv6.
398
+ *
399
+ * @default Sum over 5 minutes
400
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.ipv6ProcessedBytes`` instead
401
+ */
402
+ metricIpv6ProcessedBytes(props) {
403
+ return this.metrics.ipv6ProcessedBytes(props);
404
+ }
405
+ /**
406
+ * The number of IPv6 requests received by the load balancer.
407
+ *
408
+ * @default Sum over 5 minutes
409
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.ipv6RequestCount`` instead
410
+ */
411
+ metricIpv6RequestCount(props) {
412
+ return this.metrics.ipv6RequestCount(props);
413
+ }
414
+ /**
415
+ * The total number of new TCP connections established from clients to the
416
+ * load balancer and from the load balancer to targets.
417
+ *
418
+ * @default Sum over 5 minutes
419
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.newConnectionCount`` instead
420
+ */
421
+ metricNewConnectionCount(props) {
422
+ return this.metrics.newConnectionCount(props);
423
+ }
424
+ /**
425
+ * The total number of bytes processed by the load balancer over IPv4 and IPv6.
426
+ *
427
+ * @default Sum over 5 minutes
428
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.processedBytes`` instead
429
+ */
430
+ metricProcessedBytes(props) {
431
+ return this.metrics.processedBytes(props);
432
+ }
433
+ /**
434
+ * The number of connections that were rejected because the load balancer had
435
+ * reached its maximum number of connections.
436
+ *
437
+ * @default Sum over 5 minutes
438
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.rejectedConnectionCount`` instead
439
+ */
440
+ metricRejectedConnectionCount(props) {
441
+ return this.metrics.rejectedConnectionCount(props);
442
+ }
443
+ /**
444
+ * The number of requests processed over IPv4 and IPv6.
445
+ *
446
+ * This count includes only the requests with a response generated by a target of the load balancer.
447
+ *
448
+ * @default Sum over 5 minutes
449
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.requestCount`` instead
450
+ */
451
+ metricRequestCount(props) {
452
+ return this.metrics.requestCount(props);
453
+ }
454
+ /**
455
+ * The number of rules processed by the load balancer given a request rate averaged over an hour.
456
+ *
457
+ * @default Sum over 5 minutes
458
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.ruleEvaluations`` instead
459
+ */
460
+ metricRuleEvaluations(props) {
461
+ return this.metrics.ruleEvaluations(props);
462
+ }
463
+ /**
464
+ * The number of connections that were not successfully established between the load balancer and target.
465
+ *
466
+ * @default Sum over 5 minutes
467
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.targetConnectionErrorCount`` instead
468
+ */
469
+ metricTargetConnectionErrorCount(props) {
470
+ return this.metrics.targetConnectionErrorCount(props);
471
+ }
472
+ /**
473
+ * The time elapsed, in seconds, after the request leaves the load balancer until a response from the target is received.
474
+ *
475
+ * @default Average over 5 minutes
476
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.targetResponseTime`` instead
477
+ */
478
+ metricTargetResponseTime(props) {
479
+ return this.metrics.targetResponseTime(props);
480
+ }
481
+ /**
482
+ * The number of TLS connections initiated by the load balancer that did not establish a session with the target.
483
+ *
484
+ * Possible causes include a mismatch of ciphers or protocols.
485
+ *
486
+ * @default Sum over 5 minutes
487
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.targetTLSNegotiationErrorCount`` instead
488
+ */
489
+ metricTargetTLSNegotiationErrorCount(props) {
490
+ return this.metrics.targetTLSNegotiationErrorCount(props);
491
+ }
492
+ /**
493
+ * The number of user authentications that could not be completed
494
+ *
495
+ * Because an authenticate action was misconfigured, the load balancer
496
+ * couldn't establish a connection with the IdP, or the load balancer
497
+ * couldn't complete the authentication flow due to an internal error.
498
+ *
499
+ * @default Sum over 5 minutes
500
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.elbAuthError`` instead
501
+ */
502
+ metricElbAuthError(props) {
503
+ return this.metrics.elbAuthError(props);
504
+ }
505
+ /**
506
+ * The number of user authentications that could not be completed because the
507
+ * IdP denied access to the user or an authorization code was used more than
508
+ * once.
509
+ *
510
+ * @default Sum over 5 minutes
511
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.elbAuthFailure`` instead
512
+ */
513
+ metricElbAuthFailure(props) {
514
+ return this.metrics.elbAuthFailure(props);
515
+ }
516
+ /**
517
+ * The time elapsed, in milliseconds, to query the IdP for the ID token and user info.
518
+ *
519
+ * If one or more of these operations fail, this is the time to failure.
520
+ *
521
+ * @default Average over 5 minutes
522
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.elbAuthLatency`` instead
523
+ */
524
+ metricElbAuthLatency(props) {
525
+ return this.metrics.elbAuthLatency(props);
526
+ }
527
+ /**
528
+ * The number of authenticate actions that were successful.
529
+ *
530
+ * This metric is incremented at the end of the authentication workflow,
531
+ * after the load balancer has retrieved the user claims from the IdP.
532
+ *
533
+ * @default Sum over 5 minutes
534
+ * @deprecated Use ``ApplicationLoadBalancer.metrics.elbAuthSuccess`` instead
535
+ *
536
+ */
537
+ metricElbAuthSuccess(props) {
538
+ return this.metrics.elbAuthSuccess(props);
539
+ }
540
+ }
541
+ exports.ApplicationLoadBalancer = ApplicationLoadBalancer;
542
+ _a = JSII_RTTI_SYMBOL_1;
543
+ ApplicationLoadBalancer[_a] = { fqn: "terraconstructs.aws.compute.ApplicationLoadBalancer", version: "0.0.13" };
544
+ class ApplicationLoadBalancerMetrics {
545
+ constructor(scope, loadBalancerFullName) {
546
+ this.scope = scope;
547
+ this.loadBalancerFullName = loadBalancerFullName;
548
+ }
549
+ /**
550
+ * Return the given named metric for this Application Load Balancer
551
+ *
552
+ * @default Average over 5 minutes
553
+ */
554
+ custom(metricName, props) {
555
+ return new cloudwatch.Metric({
556
+ namespace: "AWS/ApplicationELB",
557
+ metricName,
558
+ dimensionsMap: { LoadBalancer: this.loadBalancerFullName },
559
+ ...props,
560
+ });
561
+ }
562
+ activeConnectionCount(props) {
563
+ return this.cannedMetric(elasticloadbalancingv2_canned_metrics_generated_1.ApplicationELBMetrics.activeConnectionCountSum, props);
564
+ }
565
+ clientTlsNegotiationErrorCount(props) {
566
+ return this.cannedMetric(elasticloadbalancingv2_canned_metrics_generated_1.ApplicationELBMetrics.clientTlsNegotiationErrorCountSum, props);
567
+ }
568
+ consumedLCUs(props) {
569
+ return this.cannedMetric(elasticloadbalancingv2_canned_metrics_generated_1.ApplicationELBMetrics.consumedLcUsAverage, {
570
+ statistic: "sum",
571
+ ...props,
572
+ });
573
+ }
574
+ httpFixedResponseCount(props) {
575
+ return this.cannedMetric(elasticloadbalancingv2_canned_metrics_generated_1.ApplicationELBMetrics.httpFixedResponseCountSum, props);
576
+ }
577
+ httpRedirectCount(props) {
578
+ return this.cannedMetric(elasticloadbalancingv2_canned_metrics_generated_1.ApplicationELBMetrics.httpRedirectCountSum, props);
579
+ }
580
+ httpRedirectUrlLimitExceededCount(props) {
581
+ return this.cannedMetric(elasticloadbalancingv2_canned_metrics_generated_1.ApplicationELBMetrics.httpRedirectUrlLimitExceededCountSum, props);
582
+ }
583
+ httpCodeElb(code, props) {
584
+ return this.custom(code, {
585
+ statistic: "Sum",
586
+ ...props,
587
+ });
588
+ }
589
+ httpCodeTarget(code, props) {
590
+ return this.custom(code, {
591
+ statistic: "Sum",
592
+ ...props,
593
+ });
594
+ }
595
+ ipv6ProcessedBytes(props) {
596
+ return this.cannedMetric(elasticloadbalancingv2_canned_metrics_generated_1.ApplicationELBMetrics.iPv6ProcessedBytesSum, props);
597
+ }
598
+ ipv6RequestCount(props) {
599
+ return this.cannedMetric(elasticloadbalancingv2_canned_metrics_generated_1.ApplicationELBMetrics.iPv6RequestCountSum, props);
600
+ }
601
+ newConnectionCount(props) {
602
+ return this.cannedMetric(elasticloadbalancingv2_canned_metrics_generated_1.ApplicationELBMetrics.newConnectionCountSum, props);
603
+ }
604
+ processedBytes(props) {
605
+ return this.cannedMetric(elasticloadbalancingv2_canned_metrics_generated_1.ApplicationELBMetrics.processedBytesSum, props);
606
+ }
607
+ rejectedConnectionCount(props) {
608
+ return this.cannedMetric(elasticloadbalancingv2_canned_metrics_generated_1.ApplicationELBMetrics.rejectedConnectionCountSum, props);
609
+ }
610
+ requestCount(props) {
611
+ return this.cannedMetric(elasticloadbalancingv2_canned_metrics_generated_1.ApplicationELBMetrics.requestCountSum, props);
612
+ }
613
+ ruleEvaluations(props) {
614
+ return this.cannedMetric(elasticloadbalancingv2_canned_metrics_generated_1.ApplicationELBMetrics.ruleEvaluationsSum, props);
615
+ }
616
+ targetConnectionErrorCount(props) {
617
+ return this.custom("TargetConnectionErrorCount", {
618
+ statistic: "Sum",
619
+ ...props,
620
+ });
621
+ }
622
+ targetResponseTime(props) {
623
+ return this.custom("TargetResponseTime", {
624
+ statistic: "Average",
625
+ ...props,
626
+ });
627
+ }
628
+ targetTLSNegotiationErrorCount(props) {
629
+ return this.custom("TargetTLSNegotiationErrorCount", {
630
+ statistic: "Sum",
631
+ ...props,
632
+ });
633
+ }
634
+ elbAuthError(props) {
635
+ return this.custom("ELBAuthError", {
636
+ statistic: "Sum",
637
+ ...props,
638
+ });
639
+ }
640
+ elbAuthFailure(props) {
641
+ return this.custom("ELBAuthFailure", {
642
+ statistic: "Sum",
643
+ ...props,
644
+ });
645
+ }
646
+ elbAuthLatency(props) {
647
+ return this.custom("ELBAuthLatency", {
648
+ statistic: "Average",
649
+ ...props,
650
+ });
651
+ }
652
+ elbAuthSuccess(props) {
653
+ return this.custom("ELBAuthSuccess", {
654
+ statistic: "Sum",
655
+ ...props,
656
+ });
657
+ }
658
+ cannedMetric(fn, props) {
659
+ return new cloudwatch.Metric({
660
+ ...fn({ LoadBalancer: this.loadBalancerFullName }),
661
+ ...props,
662
+ }).attachTo(this.scope);
663
+ }
664
+ }
665
+ /**
666
+ * Count of HTTP status originating from the load balancer
667
+ *
668
+ * This count does not include any response codes generated by the targets.
669
+ */
670
+ var HttpCodeElb;
671
+ (function (HttpCodeElb) {
672
+ /**
673
+ * The number of HTTP 3XX redirection codes that originate from the load balancer.
674
+ */
675
+ HttpCodeElb["ELB_3XX_COUNT"] = "HTTPCode_ELB_3XX_Count";
676
+ /**
677
+ * The number of HTTP 4XX client error codes that originate from the load balancer.
678
+ *
679
+ * Client errors are generated when requests are malformed or incomplete.
680
+ * These requests have not been received by the target. This count does not
681
+ * include any response codes generated by the targets.
682
+ */
683
+ HttpCodeElb["ELB_4XX_COUNT"] = "HTTPCode_ELB_4XX_Count";
684
+ /**
685
+ * The number of HTTP 5XX server error codes that originate from the load balancer.
686
+ */
687
+ HttpCodeElb["ELB_5XX_COUNT"] = "HTTPCode_ELB_5XX_Count";
688
+ /**
689
+ * The number of HTTP 500 server error codes that originate from the load balancer.
690
+ */
691
+ HttpCodeElb["ELB_500_COUNT"] = "HTTPCode_ELB_500_Count";
692
+ /**
693
+ * The number of HTTP 502 server error codes that originate from the load balancer.
694
+ */
695
+ HttpCodeElb["ELB_502_COUNT"] = "HTTPCode_ELB_502_Count";
696
+ /**
697
+ * The number of HTTP 503 server error codes that originate from the load balancer.
698
+ */
699
+ HttpCodeElb["ELB_503_COUNT"] = "HTTPCode_ELB_503_Count";
700
+ /**
701
+ * The number of HTTP 504 server error codes that originate from the load balancer.
702
+ */
703
+ HttpCodeElb["ELB_504_COUNT"] = "HTTPCode_ELB_504_Count";
704
+ })(HttpCodeElb || (exports.HttpCodeElb = HttpCodeElb = {}));
705
+ /**
706
+ * Count of HTTP status originating from the targets
707
+ */
708
+ var HttpCodeTarget;
709
+ (function (HttpCodeTarget) {
710
+ /**
711
+ * The number of 2xx response codes from targets
712
+ */
713
+ HttpCodeTarget["TARGET_2XX_COUNT"] = "HTTPCode_Target_2XX_Count";
714
+ /**
715
+ * The number of 3xx response codes from targets
716
+ */
717
+ HttpCodeTarget["TARGET_3XX_COUNT"] = "HTTPCode_Target_3XX_Count";
718
+ /**
719
+ * The number of 4xx response codes from targets
720
+ */
721
+ HttpCodeTarget["TARGET_4XX_COUNT"] = "HTTPCode_Target_4XX_Count";
722
+ /**
723
+ * The number of 5xx response codes from targets
724
+ */
725
+ HttpCodeTarget["TARGET_5XX_COUNT"] = "HTTPCode_Target_5XX_Count";
726
+ })(HttpCodeTarget || (exports.HttpCodeTarget = HttpCodeTarget = {}));
727
+ /**
728
+ * An ApplicationLoadBalancer that has been defined elsewhere
729
+ */
730
+ class ImportedApplicationLoadBalancer extends aws_construct_1.AwsConstructBase {
731
+ get loadBalancerV2Outputs() {
732
+ return {
733
+ loadBalancerCanonicalHostedZoneId: this.loadBalancerCanonicalHostedZoneId,
734
+ loadBalancerDnsName: this.loadBalancerDnsName,
735
+ };
736
+ }
737
+ get outputs() {
738
+ return this.loadBalancerV2Outputs;
739
+ }
740
+ get listeners() {
741
+ throw Error(".listeners can only be accessed if the class was constructed as an owned, not imported, load balancer");
742
+ }
743
+ constructor(scope, id, props) {
744
+ super(scope, id, {
745
+ environmentFromArn: props.loadBalancerArn,
746
+ });
747
+ this.props = props;
748
+ this.vpc = props.vpc;
749
+ this.loadBalancerArn = props.loadBalancerArn;
750
+ this.connections = new connections_1.Connections({
751
+ securityGroups: [
752
+ security_group_1.SecurityGroup.fromSecurityGroupId(this, "SecurityGroup", props.securityGroupId, {
753
+ allowAllOutbound: props.securityGroupAllowsAllOutbound,
754
+ }),
755
+ ],
756
+ });
757
+ this.metrics = new ApplicationLoadBalancerMetrics(this, (0, util_1.parseLoadBalancerFullName)(props.loadBalancerArn));
758
+ }
759
+ addListener(id, props) {
760
+ return new application_listener_1.ApplicationListener(this, id, {
761
+ loadBalancer: this,
762
+ ...props,
763
+ });
764
+ }
765
+ get loadBalancerCanonicalHostedZoneId() {
766
+ if (this.props.loadBalancerCanonicalHostedZoneId) {
767
+ return this.props.loadBalancerCanonicalHostedZoneId;
768
+ }
769
+ // eslint-disable-next-line max-len
770
+ throw new Error(`'loadBalancerCanonicalHostedZoneId' was not provided when constructing Application Load Balancer ${this.node.path} from attributes`);
771
+ }
772
+ get loadBalancerDnsName() {
773
+ if (this.props.loadBalancerDnsName) {
774
+ return this.props.loadBalancerDnsName;
775
+ }
776
+ // eslint-disable-next-line max-len
777
+ throw new Error(`'loadBalancerDnsName' was not provided when constructing Application Load Balancer ${this.node.path} from attributes`);
778
+ }
779
+ }
780
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwbGljYXRpb24tbG9hZC1iYWxhbmNlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hd3MvY29tcHV0ZS9hbGIvYXBwbGljYXRpb24tbG9hZC1iYWxhbmNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUdBLGlDQUFnRDtBQUVoRCxpRUFHZ0M7QUFDaEMsK0VBQStEO0FBRS9ELHVEQUF1RDtBQUN2RCwrQ0FBMkM7QUFDM0MsK0NBQStDO0FBQy9DLGlFQUE2RDtBQUM3RCxxREFBd0Q7QUFFeEQsZ0RBQTJEO0FBQzNELFdBQVc7QUFDWCxzQkFBc0I7QUFDdEIsa0NBQWtDO0FBQ2xDLDJDQUEyQztBQUMzQyx3SEFBMkY7QUFDM0Ysd0VBTXlDO0FBQ3pDLDhDQUk0QjtBQUM1Qiw0Q0FHMkI7QUFDM0Isc0RBQWtFO0FBOEdsRTs7O0dBR0c7QUFDSCxJQUFZLHVCQWdCWDtBQWhCRCxXQUFZLHVCQUF1QjtJQUNqQzs7O09BR0c7SUFDSCw0Q0FBaUIsQ0FBQTtJQUNqQjs7O09BR0c7SUFDSCxnREFBcUIsQ0FBQTtJQUNyQjs7O09BR0c7SUFDSCw0Q0FBaUIsQ0FBQTtBQUNuQixDQUFDLEVBaEJXLHVCQUF1Qix1Q0FBdkIsdUJBQXVCLFFBZ0JsQztBQVFEOzs7O0dBSUc7QUFDSCxNQUFhLHVCQUNYLFNBQVEscUNBQWdCO0lBR3hCLGdDQUFnQztJQUNoQyxNQUFNO0lBQ04sMkNBQTJDO0lBQzNDLE1BQU07SUFDTiw0QkFBNEI7SUFDNUIsc0JBQXNCO0lBQ3RCLGdCQUFnQjtJQUNoQixtREFBbUQ7SUFDbkQsZ0NBQWdDO0lBQ2hDLGtFQUFrRTtJQUNsRSw0QkFBNEI7SUFDNUIsc0RBQXNEO0lBQ3RELFFBQVE7SUFFUixrRUFBa0U7SUFDbEUsSUFBSTtJQUVKOztPQUVHO0lBQ0ksTUFBTSxDQUFDLHFDQUFxQyxDQUNqRCxLQUFnQixFQUNoQixFQUFVLEVBQ1YsS0FBd0M7UUFFeEMsT0FBTyxJQUFJLCtCQUErQixDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDL0QsQ0FBQztJQU9ELFlBQ0UsS0FBZ0IsRUFDaEIsRUFBVSxFQUNWLEtBQW1DO1FBRW5DLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEtBQUssRUFBRTtZQUN0QixnQkFBZ0IsRUFBRSxhQUFhO1lBQy9CLGNBQWMsRUFBRSxZQUFJLENBQUMsU0FBUyxDQUFDO2dCQUM3QixPQUFPLEVBQUUsR0FBRyxFQUFFLENBQ1osSUFBSSxDQUFDLFdBQVcsQ0FBQyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsZUFBZSxDQUFDO2FBQ2xFLENBQUM7WUFDRixhQUFhLEVBQUUsS0FBSyxDQUFDLGFBQWE7U0FDbkMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUMsYUFBYSxJQUFJLHFCQUFhLENBQUMsSUFBSSxDQUFDO1FBRS9ELElBQ0UsS0FBSyxDQUFDLGFBQWEsS0FBSyxxQkFBYSxDQUFDLDhCQUE4QjtZQUNwRSxDQUFDLEtBQUssQ0FBQyxjQUFjLEVBQ3JCLENBQUM7WUFDRCxNQUFNLElBQUksS0FBSyxDQUNiLHNGQUFzRixDQUN2RixDQUFDO1FBQ0osQ0FBQztRQUVELE1BQU0sY0FBYyxHQUFHO1lBQ3JCLEtBQUssQ0FBQyxhQUFhO2dCQUNqQixJQUFJLDhCQUFhLENBQUMsSUFBSSxFQUFFLGVBQWUsRUFBRTtvQkFDdkMsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHO29CQUNkLFdBQVcsRUFBRSxnREFBZ0Qsb0JBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUU7b0JBQ3RGLGdCQUFnQixFQUFFLEtBQUs7aUJBQ3hCLENBQUM7U0FDTCxDQUFDO1FBQ0YsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLHlCQUFXLENBQUMsRUFBRSxjQUFjLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZELElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSw4QkFBOEIsQ0FDL0MsSUFBSSxFQUNKLElBQUksQ0FBQyxvQkFBb0IsQ0FDMUIsQ0FBQztRQUVGLElBQUksS0FBSyxDQUFDLFlBQVksS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNyQyxJQUFJLENBQUMsWUFBWSxDQUNmLHVCQUF1QixFQUN2QixLQUFLLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FDdEMsQ0FBQztRQUNKLENBQUM7UUFDRCxJQUFJLEtBQUssQ0FBQyxXQUFXLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDcEMsSUFBSSxDQUFDLFlBQVksQ0FDZiw4QkFBOEIsRUFDOUIsS0FBSyxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FDekMsQ0FBQztRQUNKLENBQUM7UUFDRCxJQUFJLEtBQUssQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1lBQ2xDLElBQUksQ0FBQyxZQUFZLENBQ2YsaURBQWlELEVBQ2pELE1BQU0sQ0FDUCxDQUFDO1FBQ0osQ0FBQztRQUNELElBQUksS0FBSyxDQUFDLG9CQUFvQixLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzdDLElBQUksQ0FBQyxZQUFZLENBQ2YscUNBQXFDLEVBQ3JDLEtBQUssQ0FBQyxvQkFBb0IsQ0FDM0IsQ0FBQztRQUNKLENBQUM7UUFDRCxJQUFJLEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxZQUFZLENBQUMsMkNBQTJDLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDekUsQ0FBQztRQUNELElBQUksS0FBSyxDQUFDLG9DQUFvQyxFQUFFLENBQUM7WUFDL0MsSUFBSSxDQUFDLFlBQVksQ0FDZiwwREFBMEQsRUFDMUQsTUFBTSxDQUNQLENBQUM7UUFDSixDQUFDO1FBQ0QsSUFBSSxLQUFLLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUNoQyxJQUFJLENBQUMsWUFBWSxDQUFDLHNDQUFzQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3BFLENBQUM7UUFDRCxJQUFJLEtBQUssQ0FBQyx1QkFBdUIsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNoRCxJQUFJLENBQUMsWUFBWSxDQUNmLHlDQUF5QyxFQUN6QyxLQUFLLENBQUMsdUJBQXVCLENBQzlCLENBQUM7UUFDSixDQUFDO1FBQ0QsSUFBSSxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDdEIsSUFBSSxDQUFDLFlBQVksQ0FBQyx1QkFBdUIsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNyRCxDQUFDO1FBQ0QsSUFBSSxLQUFLLENBQUMsZUFBZSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3hDLE1BQU0sdUJBQXVCLEdBQUcsS0FBSyxDQUFDLGVBQWUsQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN2RSxJQUFJLHVCQUF1QixHQUFHLElBQUksRUFBRSxDQUFDO2dCQUNuQyxNQUFNLElBQUksS0FBSyxDQUNiLG1FQUFtRSx1QkFBdUIsZUFBZSxDQUMxRyxDQUFDO1lBQ0osQ0FBQztZQUVELE1BQU0sd0JBQXdCLEdBQUcsS0FBSyxDQUFDLGVBQWUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNuRSxJQUFJLHdCQUF3QixHQUFHLEVBQUUsSUFBSSx3QkFBd0IsR0FBRyxNQUFNLEVBQUUsQ0FBQztnQkFDdkUsTUFBTSxJQUFJLEtBQUssQ0FDYixtRUFBbUUsd0JBQXdCLFVBQVUsQ0FDdEcsQ0FBQztZQUNKLENBQUM7WUFDRCxJQUFJLENBQUMsWUFBWSxDQUNmLDJCQUEyQixFQUMzQix3QkFBd0IsQ0FBQyxRQUFRLEVBQUUsQ0FDcEMsQ0FBQztRQUNKLENBQUM7UUFFRCxJQUFJLEtBQUssQ0FBQyxnQkFBZ0IsS0FBSyxLQUFLLEVBQUUsQ0FBQztZQUNyQyxNQUFNLElBQUksS0FBSyxDQUNiLG1FQUFtRSxDQUNwRSxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNJLFdBQVcsQ0FDaEIsRUFBVSxFQUNWLEtBQW1DO1FBRW5DLE1BQU0sUUFBUSxHQUFHLElBQUksMENBQW1CLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRTtZQUNqRCxZQUFZLEVBQUUsSUFBSTtZQUNsQixHQUFHLEtBQUs7U0FDVCxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM5QixPQUFPLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBRUQ7O09BRUc7SUFDSSxXQUFXLENBQ2hCLFFBQStDLEVBQUU7UUFFakQsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLFVBQVUsSUFBSSxFQUFFLENBQUM7UUFDMUMsTUFBTSxVQUFVLEdBQUcsQ0FBQyxLQUFLLENBQUMsVUFBVSxJQUFJLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3hELE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLFVBQVUsS0FBSyxVQUFVLEVBQUUsRUFBRTtZQUM5RCxRQUFRLEVBQUUsS0FBSyxDQUFDLGNBQWMsSUFBSSwyQkFBbUIsQ0FBQyxJQUFJO1lBQzFELElBQUksRUFBRSxVQUFVO1lBQ2hCLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSSxJQUFJLElBQUk7WUFDeEIsYUFBYSxFQUFFLDRDQUFjLENBQUMsUUFBUSxDQUFDO2dCQUNyQyxJQUFJLEVBQUUsVUFBVTtnQkFDaEIsUUFBUSxFQUFFLEtBQUssQ0FBQyxjQUFjLElBQUksMkJBQW1CLENBQUMsS0FBSztnQkFDM0QsU0FBUyxFQUFFLElBQUk7YUFDaEIsQ0FBQztTQUNILENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLGFBQWEsQ0FBQyxNQUFrQixFQUFFLE1BQWU7UUFDdEQsK0RBQStEO1FBQy9EOzs7V0FHRztRQUNILElBQUksTUFBTSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3pCLE1BQU0sSUFBSSxLQUFLLENBQ2IsMEVBQTBFLENBQzNFLENBQUM7UUFDSixDQUFDO1FBRUQsc0RBQXNEO1FBQ3RELElBQUksQ0FBQyxZQUFZLENBQUMsd0JBQXdCLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDcEQsSUFBSSxDQUFDLFlBQVksQ0FBQyx1QkFBdUIsRUFBRSxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDekUsSUFBSSxDQUFDLFlBQVksQ0FBQyx1QkFBdUIsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUVuRCxNQUFNLDRCQUE0QixHQUFHLElBQUksNkJBQWdCLENBQ3ZELDZCQUE2QixDQUM5QixDQUFDO1FBQ0YsTUFBTSxDQUFDLG1CQUFtQixDQUN4QixJQUFJLGtDQUFlLENBQUM7WUFDbEIsT0FBTyxFQUFFLENBQUMsY0FBYyxDQUFDO1lBQ3pCLFVBQVUsRUFBRSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1lBQzVDLFNBQVMsRUFBRTtnQkFDVCxNQUFNLENBQUMsYUFBYSxDQUNsQixHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLG9CQUFRLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sSUFBSSxDQUNsRjthQUNGO1NBQ0YsQ0FBQyxDQUNILENBQUM7UUFDRixNQUFNLENBQUMsbUJBQW1CLENBQ3hCLElBQUksa0NBQWUsQ0FBQztZQUNsQixPQUFPLEVBQUUsQ0FBQyxjQUFjLENBQUM7WUFDekIsVUFBVSxFQUFFLENBQUMsNEJBQTRCLENBQUM7WUFDMUMsU0FBUyxFQUFFO2dCQUNULE1BQU0sQ0FBQyxhQUFhLENBQ2xCLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLElBQUksQ0FDN0Q7YUFDRjtZQUNELFNBQVMsRUFBRTtnQkFDVDtvQkFDRSxJQUFJLEVBQUUsY0FBYztvQkFDcEIsUUFBUSxFQUFFLGNBQWM7b0JBQ3hCLE1BQU0sRUFBRSxDQUFDLDJCQUEyQixDQUFDO2lCQUN0QzthQUNGO1NBQ0YsQ0FBQyxDQUNILENBQUM7UUFDRixNQUFNLENBQUMsbUJBQW1CLENBQ3hCLElBQUksa0NBQWUsQ0FBQztZQUNsQixPQUFPLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQztZQUM1QixVQUFVLEVBQUUsQ0FBQyw0QkFBNEIsQ0FBQztZQUMxQyxTQUFTLEVBQUUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDO1NBQzlCLENBQUMsQ0FDSCxDQUFDO1FBRUYsMkdBQTJHO1FBQzNHLDJHQUEyRztRQUMzRyxtREFBbUQ7UUFDbkQsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUE2QyxDQUFDO1FBQ25FLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQztRQUN0RCxJQUNFLEVBQUU7WUFDRixZQUFZO1lBQ1oseUJBQWlCLENBQUMsbUJBQW1CLENBQUMsRUFBRSxDQUFDO1lBQ3pDLHlCQUFpQixDQUFDLG1CQUFtQixDQUFDLFlBQVksQ0FBQyxFQUNuRCxDQUFDO1lBQ0QsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDdEMsQ0FBQztRQUNELDRGQUE0RjtRQUM1RixvRkFBb0Y7UUFDcEYsRUFBRSxFQUFFLGFBQWEsQ0FBQztZQUNoQixPQUFPLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyw0QkFBUyxDQUFDLG1CQUFtQixDQUFDO1lBQ3pELE1BQU0sRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLDRCQUFTLENBQUMsa0JBQWtCLENBQUM7WUFDekQsTUFBTSxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsNEJBQVMsQ0FBQyxrQkFBa0IsQ0FBQztTQUMxRCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNJLGlCQUFpQixDQUFDLE1BQWtCLEVBQUUsTUFBZTtRQUMxRDs7O1dBR0c7UUFDSCxJQUFJLE1BQU0sQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN6QixNQUFNLElBQUksS0FBSyxDQUNiLDBFQUEwRSxDQUMzRSxDQUFDO1FBQ0osQ0FBQztRQUVELE1BQU0sR0FBRyxNQUFNLElBQUksRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxZQUFZLENBQUMsNEJBQTRCLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDeEQsSUFBSSxDQUFDLFlBQVksQ0FDZiwyQkFBMkIsRUFDM0IsTUFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsQ0FDN0IsQ0FBQztRQUNGLElBQUksQ0FBQyxZQUFZLENBQUMsMkJBQTJCLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFdkQscUdBQXFHO1FBQ3JHLE1BQU0sNEJBQTRCLEdBQUcsSUFBSSw2QkFBZ0IsQ0FDdkQsNkJBQTZCLENBQzlCLENBQUM7UUFDRixNQUFNLENBQUMsbUJBQW1CLENBQ3hCLElBQUksa0NBQWUsQ0FBQztZQUNsQixPQUFPLEVBQUUsQ0FBQyxjQUFjLENBQUM7WUFDekIsVUFBVSxFQUFFLENBQUMsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7WUFDNUMsU0FBUyxFQUFFO2dCQUNULE1BQU0sQ0FBQyxhQUFhLENBQ2xCLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsb0JBQVEsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxJQUFJLENBQ2xGO2FBQ0Y7U0FDRixDQUFDLENBQ0gsQ0FBQztRQUNGLHlEQUF5RDtRQUN6RCxNQUFNLENBQUMsbUJBQW1CLENBQ3hCLElBQUksa0NBQWUsQ0FBQztZQUNsQixPQUFPLEVBQUUsQ0FBQyxjQUFjLENBQUM7WUFDekIsVUFBVSxFQUFFLENBQUMsNEJBQTRCLENBQUM7WUFDMUMsU0FBUyxFQUFFO2dCQUNULE1BQU0sQ0FBQyxhQUFhLENBQ2xCLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsb0JBQVEsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxJQUFJLENBQ2xGO2FBQ0Y7WUFDRCxTQUFTLEVBQUU7Z0JBQ1Q7b0JBQ0UsSUFBSSxFQUFFLGNBQWM7b0JBQ3BCLFFBQVEsRUFBRSxjQUFjO29CQUN4QixNQUFNLEVBQUUsQ0FBQywyQkFBMkIsQ0FBQztpQkFDdEM7YUFDRjtTQUNGLENBQUMsQ0FDSCxDQUFDO1FBQ0YsTUFBTSxDQUFDLG1CQUFtQixDQUN4QixJQUFJLGtDQUFlLENBQUM7WUFDbEIsT0FBTyxFQUFFLENBQUMsaUJBQWlCLENBQUM7WUFDNUIsVUFBVSxFQUFFLENBQUMsNEJBQTRCLENBQUM7WUFDMUMsU0FBUyxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQztTQUM5QixDQUFDLENBQ0gsQ0FBQztRQUVGLDJHQUEyRztRQUMzRywyR0FBMkc7UUFDM0csbURBQW1EO1FBQ25ELE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBNkMsQ0FBQztRQUNuRSxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUM7UUFDdEQsSUFDRSxFQUFFO1lBQ0YsWUFBWTtZQUNaLHlCQUFpQixDQUFDLG1CQUFtQixDQUFDLEVBQUUsQ0FBQztZQUN6Qyx5QkFBaUIsQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLENBQUMsRUFDbkQsQ0FBQztZQUNELEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3RDLENBQUM7UUFDRCxnR0FBZ0c7UUFDaEcsd0ZBQXdGO1FBQ3hGLEVBQUUsRUFBRSxpQkFBaUIsQ0FBQztZQUNwQixPQUFPLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyw0QkFBUyxDQUFDLHVCQUF1QixDQUFDO1lBQzdELE1BQU0sRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDLDRCQUFTLENBQUMsc0JBQXNCLENBQUM7WUFDN0QsTUFBTSxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsNEJBQVMsQ0FBQyxzQkFBc0IsQ0FBQztTQUM5RCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxnQkFBZ0IsQ0FBQyxhQUE2QjtRQUNuRCxJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLE1BQU0sQ0FDWCxVQUFrQixFQUNsQixLQUFnQztRQUVoQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksMkJBQTJCLENBQUMsS0FBZ0M7UUFDakUsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ25ELENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0ksb0NBQW9DLENBQ3pDLEtBQWdDO1FBRWhDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyw4QkFBOEIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxrQkFBa0IsQ0FBQyxLQUFnQztRQUN4RCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLDRCQUE0QixDQUFDLEtBQWdDO1FBQ2xFLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxzQkFBc0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSx1QkFBdUIsQ0FBQyxLQUFnQztRQUM3RCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0MsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLHVDQUF1QyxDQUM1QyxLQUFnQztRQUVoQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsaUNBQWlDLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0QsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSSxpQkFBaUIsQ0FDdEIsSUFBaUIsRUFDakIsS0FBZ0M7UUFFaEMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDL0MsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0ksb0JBQW9CLENBQ3pCLElBQW9CLEVBQ3BCLEtBQWdDO1FBRWhDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLHdCQUF3QixDQUFDLEtBQWdDO1FBQzlELE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxzQkFBc0IsQ0FBQyxLQUFnQztRQUM1RCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLHdCQUF3QixDQUFDLEtBQWdDO1FBQzlELE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSSxvQkFBb0IsQ0FBQyxLQUFnQztRQUMxRCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSw2QkFBNkIsQ0FBQyxLQUFnQztRQUNuRSxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsdUJBQXVCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDckQsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSSxrQkFBa0IsQ0FBQyxLQUFnQztRQUN4RCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLHFCQUFxQixDQUFDLEtBQWdDO1FBQzNELE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ksZ0NBQWdDLENBQUMsS0FBZ0M7UUFDdEUsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLDBCQUEwQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNJLHdCQUF3QixDQUFDLEtBQWdDO1FBQzlELE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNJLG9DQUFvQyxDQUN6QyxLQUFnQztRQUVoQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsOEJBQThCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNJLGtCQUFrQixDQUFDLEtBQWdDO1FBQ3hELE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSSxvQkFBb0IsQ0FBQyxLQUFnQztRQUMxRCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0ksb0JBQW9CLENBQUMsS0FBZ0M7UUFDMUQsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0ksb0JBQW9CLENBQUMsS0FBZ0M7UUFDMUQsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM1QyxDQUFDOztBQTduQkgsMERBOG5CQzs7O0FBRUQsTUFBTSw4QkFBOEI7SUFNbEMsWUFBWSxLQUFnQixFQUFFLG9CQUE0QjtRQUN4RCxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixJQUFJLENBQUMsb0JBQW9CLEdBQUcsb0JBQW9CLENBQUM7SUFDbkQsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxNQUFNLENBQ1gsVUFBa0IsRUFDbEIsS0FBZ0M7UUFFaEMsT0FBTyxJQUFJLFVBQVUsQ0FBQyxNQUFNLENBQUM7WUFDM0IsU0FBUyxFQUFFLG9CQUFvQjtZQUMvQixVQUFVO1lBQ1YsYUFBYSxFQUFFLEVBQUUsWUFBWSxFQUFFLElBQUksQ0FBQyxvQkFBb0IsRUFBRTtZQUMxRCxHQUFHLEtBQUs7U0FDVCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU0scUJBQXFCLENBQUMsS0FBZ0M7UUFDM0QsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUN0Qix1RUFBcUIsQ0FBQyx3QkFBd0IsRUFDOUMsS0FBSyxDQUNOLENBQUM7SUFDSixDQUFDO0lBRU0sOEJBQThCLENBQUMsS0FBZ0M7UUFDcEUsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUN0Qix1RUFBcUIsQ0FBQyxpQ0FBaUMsRUFDdkQsS0FBSyxDQUNOLENBQUM7SUFDSixDQUFDO0lBRU0sWUFBWSxDQUFDLEtBQWdDO1FBQ2xELE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyx1RUFBcUIsQ0FBQyxtQkFBbUIsRUFBRTtZQUNsRSxTQUFTLEVBQUUsS0FBSztZQUNoQixHQUFHLEtBQUs7U0FDVCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU0sc0JBQXNCLENBQUMsS0FBZ0M7UUFDNUQsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUN0Qix1RUFBcUIsQ0FBQyx5QkFBeUIsRUFDL0MsS0FBSyxDQUNOLENBQUM7SUFDSixDQUFDO0lBRU0saUJBQWlCLENBQUMsS0FBZ0M7UUFDdkQsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLHVFQUFxQixDQUFDLG9CQUFvQixFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzlFLENBQUM7SUFFTSxpQ0FBaUMsQ0FBQyxLQUFnQztRQUN2RSxPQUFPLElBQUksQ0FBQyxZQUFZLENBQ3RCLHVFQUFxQixDQUFDLG9DQUFvQyxFQUMxRCxLQUFLLENBQ04sQ0FBQztJQUNKLENBQUM7SUFFTSxXQUFXLENBQUMsSUFBaUIsRUFBRSxLQUFnQztRQUNwRSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFO1lBQ3ZCLFNBQVMsRUFBRSxLQUFLO1lBQ2hCLEdBQUcsS0FBSztTQUNULENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTSxjQUFjLENBQ25CLElBQW9CLEVBQ3BCLEtBQWdDO1FBRWhDLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUU7WUFDdkIsU0FBUyxFQUFFLEtBQUs7WUFDaEIsR0FBRyxLQUFLO1NBQ1QsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVNLGtCQUFrQixDQUFDLEtBQWdDO1FBQ3hELE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FDdEIsdUVBQXFCLENBQUMscUJBQXFCLEVBQzNDLEtBQUssQ0FDTixDQUFDO0lBQ0osQ0FBQztJQUVNLGdCQUFnQixDQUFDLEtBQWdDO1FBQ3RELE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyx1RUFBcUIsQ0FBQyxtQkFBbUIsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUM3RSxDQUFDO0lBRU0sa0JBQWtCLENBQUMsS0FBZ0M7UUFDeEQsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUN0Qix1RUFBcUIsQ0FBQyxxQkFBcUIsRUFDM0MsS0FBSyxDQUNOLENBQUM7SUFDSixDQUFDO0lBRU0sY0FBYyxDQUFDLEtBQWdDO1FBQ3BELE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyx1RUFBcUIsQ0FBQyxpQkFBaUIsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUMzRSxDQUFDO0lBRU0sdUJBQXVCLENBQUMsS0FBZ0M7UUFDN0QsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUN0Qix1RUFBcUIsQ0FBQywwQkFBMEIsRUFDaEQsS0FBSyxDQUNOLENBQUM7SUFDSixDQUFDO0lBRU0sWUFBWSxDQUFDLEtBQWdDO1FBQ2xELE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyx1RUFBcUIsQ0FBQyxlQUFlLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDekUsQ0FBQztJQUVNLGVBQWUsQ0FBQyxLQUFnQztRQUNyRCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsdUVBQXFCLENBQUMsa0JBQWtCLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDNUUsQ0FBQztJQUVNLDBCQUEwQixDQUFDLEtBQWdDO1FBQ2hFLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyw0QkFBNEIsRUFBRTtZQUMvQyxTQUFTLEVBQUUsS0FBSztZQUNoQixHQUFHLEtBQUs7U0FDVCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU0sa0JBQWtCLENBQUMsS0FBZ0M7UUFDeEQsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLG9CQUFvQixFQUFFO1lBQ3ZDLFNBQVMsRUFBRSxTQUFTO1lBQ3BCLEdBQUcsS0FBSztTQUNULENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTSw4QkFBOEIsQ0FBQyxLQUFnQztRQUNwRSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsZ0NBQWdDLEVBQUU7WUFDbkQsU0FBUyxFQUFFLEtBQUs7WUFDaEIsR0FBRyxLQUFLO1NBQ1QsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVNLFlBQVksQ0FBQyxLQUFnQztRQUNsRCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFO1lBQ2pDLFNBQVMsRUFBRSxLQUFLO1lBQ2hCLEdBQUcsS0FBSztTQUNULENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTSxjQUFjLENBQUMsS0FBZ0M7UUFDcEQsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLGdCQUFnQixFQUFFO1lBQ25DLFNBQVMsRUFBRSxLQUFLO1lBQ2hCLEdBQUcsS0FBSztTQUNULENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTSxjQUFjLENBQUMsS0FBZ0M7UUFDcEQsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLGdCQUFnQixFQUFFO1lBQ25DLFNBQVMsRUFBRSxTQUFTO1lBQ3BCLEdBQUcsS0FBSztTQUNULENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTSxjQUFjLENBQUMsS0FBZ0M7UUFDcEQsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLGdCQUFnQixFQUFFO1lBQ25DLFNBQVMsRUFBRSxLQUFLO1lBQ2hCLEdBQUcsS0FBSztTQUNULENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxZQUFZLENBQ2xCLEVBQThELEVBQzlELEtBQWdDO1FBRWhDLE9BQU8sSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDO1lBQzNCLEdBQUcsRUFBRSxDQUFDLEVBQUUsWUFBWSxFQUFFLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1lBQ2xELEdBQUcsS0FBSztTQUNULENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzFCLENBQUM7Q0FDRjtBQUVEOzs7O0dBSUc7QUFDSCxJQUFZLFdBdUNYO0FBdkNELFdBQVksV0FBVztJQUNyQjs7T0FFRztJQUNILHVEQUF3QyxDQUFBO0lBRXhDOzs7Ozs7T0FNRztJQUNILHVEQUF3QyxDQUFBO0lBRXhDOztPQUVHO0lBQ0gsdURBQXdDLENBQUE7SUFFeEM7O09BRUc7SUFDSCx1REFBd0MsQ0FBQTtJQUV4Qzs7T0FFRztJQUNILHVEQUF3QyxDQUFBO0lBRXhDOztPQUVHO0lBQ0gsdURBQXdDLENBQUE7SUFFeEM7O09BRUc7SUFDSCx1REFBd0MsQ0FBQTtBQUMxQyxDQUFDLEVBdkNXLFdBQVcsMkJBQVgsV0FBVyxRQXVDdEI7QUFFRDs7R0FFRztBQUNILElBQVksY0FvQlg7QUFwQkQsV0FBWSxjQUFjO0lBQ3hCOztPQUVHO0lBQ0gsZ0VBQThDLENBQUE7SUFFOUM7O09BRUc7SUFDSCxnRUFBOEMsQ0FBQTtJQUU5Qzs7T0FFRztJQUNILGdFQUE4QyxDQUFBO0lBRTlDOztPQUVHO0lBQ0gsZ0VBQThDLENBQUE7QUFDaEQsQ0FBQyxFQXBCVyxjQUFjLDhCQUFkLGNBQWMsUUFvQnpCO0FBdVREOztHQUVHO0FBQ0gsTUFBTSwrQkFDSixTQUFRLGdDQUFnQjtJQUd4QixJQUFXLHFCQUFxQjtRQUM5QixPQUFPO1lBQ0wsaUNBQWlDLEVBQUUsSUFBSSxDQUFDLGlDQUFpQztZQUN6RSxtQkFBbUIsRUFBRSxJQUFJLENBQUMsbUJBQW1CO1NBQzlDLENBQUM7SUFDSixDQUFDO0lBQ0QsSUFBVyxPQUFPO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLHFCQUFxQixDQUFDO0lBQ3BDLENBQUM7SUFXRCxJQUFXLFNBQVM7UUFDbEIsTUFBTSxLQUFLLENBQ1QsdUdBQXVHLENBQ3hHLENBQUM7SUFDSixDQUFDO0lBVUQsWUFDRSxLQUFnQixFQUNoQixFQUFVLEVBQ08sS0FBd0M7UUFFekQsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUU7WUFDZixrQkFBa0IsRUFBRSxLQUFLLENBQUMsZUFBZTtTQUMxQyxDQUFDLENBQUM7UUFKYyxVQUFLLEdBQUwsS0FBSyxDQUFtQztRQU16RCxJQUFJLENBQUMsR0FBRyxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUM7UUFDckIsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUMsZUFBZSxDQUFDO1FBQzdDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSx5QkFBVyxDQUFDO1lBQ2pDLGNBQWMsRUFBRTtnQkFDZCw4QkFBYSxDQUFDLG1CQUFtQixDQUMvQixJQUFJLEVBQ0osZUFBZSxFQUNmLEtBQUssQ0FBQyxlQUFlLEVBQ3JCO29CQUNFLGdCQUFnQixFQUFFLEtBQUssQ0FBQyw4QkFBOEI7aUJBQ3ZELENBQ0Y7YUFDRjtTQUNGLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSw4QkFBOEIsQ0FDL0MsSUFBSSxFQUNKLElBQUEsZ0NBQXlCLEVBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUNqRCxDQUFDO0lBQ0osQ0FBQztJQUVNLFdBQVcsQ0FDaEIsRUFBVSxFQUNWLEtBQW1DO1FBRW5DLE9BQU8sSUFBSSwwQ0FBbUIsQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFO1lBQ3ZDLFlBQVksRUFBRSxJQUFJO1lBQ2xCLEdBQUcsS0FBSztTQUNULENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxJQUFXLGlDQUFpQztRQUMxQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsaUNBQWlDLEVBQUUsQ0FBQztZQUNqRCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsaUNBQWlDLENBQUM7UUFDdEQsQ0FBQztRQUNELG1DQUFtQztRQUNuQyxNQUFNLElBQUksS0FBSyxDQUNiLG9HQUFvRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksa0JBQWtCLENBQ3JJLENBQUM7SUFDSixDQUFDO0lBRUQsSUFBVyxtQkFBbUI7UUFDNUIsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDbkMsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLG1CQUFtQixDQUFDO1FBQ3hDLENBQUM7UUFDRCxtQ0FBbUM7UUFDbkMsTUFBTSxJQUFJLEtBQUssQ0FDYixzRkFBc0YsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLGtCQUFrQixDQUN2SCxDQUFDO0lBQ0osQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2Jsb2IvdjIuMTc1LjEvcGFja2FnZXMvYXdzLWNkay1saWIvYXdzLWVsYXN0aWNsb2FkYmFsYW5jaW5ndjIvbGliL2FsYi9hcHBsaWNhdGlvbi1sb2FkLWJhbGFuY2VyLnRzXG5cbmltcG9ydCB7IGxiIGFzIHRmTG9hZEJhbGFuY2VyIH0gZnJvbSBcIkBjZGt0Zi9wcm92aWRlci1hd3NcIjtcbmltcG9ydCB7IFRlcnJhZm9ybVJlc291cmNlLCBMYXp5IH0gZnJvbSBcImNka3RmXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuaW1wb3J0IHtcbiAgQXBwbGljYXRpb25MaXN0ZW5lcixcbiAgQmFzZUFwcGxpY2F0aW9uTGlzdGVuZXJQcm9wcyxcbn0gZnJvbSBcIi4vYXBwbGljYXRpb24tbGlzdGVuZXJcIjtcbmltcG9ydCB7IExpc3RlbmVyQWN0aW9uIH0gZnJvbSBcIi4vYXBwbGljYXRpb24tbGlzdGVuZXItYWN0aW9uXCI7XG5pbXBvcnQgeyBEdXJhdGlvbiB9IGZyb20gXCIuLi8uLi8uLi9kdXJhdGlvblwiO1xuaW1wb3J0IHsgQXdzQ29uc3RydWN0QmFzZSB9IGZyb20gXCIuLi8uLi9hd3MtY29uc3RydWN0XCI7XG5pbXBvcnQgeyBBd3NTdGFjayB9IGZyb20gXCIuLi8uLi9hd3Mtc3RhY2tcIjtcbmltcG9ydCAqIGFzIGNsb3Vkd2F0Y2ggZnJvbSBcIi4uLy4uL2Nsb3Vkd2F0Y2hcIjtcbmltcG9ydCB7IFBvbGljeVN0YXRlbWVudCB9IGZyb20gXCIuLi8uLi9pYW0vcG9saWN5LXN0YXRlbWVudFwiO1xuaW1wb3J0IHsgU2VydmljZVByaW5jaXBhbCB9IGZyb20gXCIuLi8uLi9pYW0vcHJpbmNpcGFsc1wiO1xuaW1wb3J0ICogYXMgczMgZnJvbSBcIi4uLy4uL3N0b3JhZ2VcIjtcbmltcG9ydCB7IENvbm5lY3Rpb25zLCBJQ29ubmVjdGFibGUgfSBmcm9tIFwiLi4vY29ubmVjdGlvbnNcIjtcbi8vIGltcG9ydCB7XG4vLyAgIExvYWRCYWxhbmNlclR5cGUsXG4vLyAgIExvYWRCYWxhbmNlckxpc3RlbmVyUHJvdG9jb2wsXG4vLyB9IGZyb20gXCIuLi9sYi1zaGFyZWQvZ3JpZC1sb29rdXAtdHlwZXNcIjtcbmltcG9ydCB7IEFwcGxpY2F0aW9uRUxCTWV0cmljcyB9IGZyb20gXCIuLi9lbGFzdGljbG9hZGJhbGFuY2luZ3YyLWNhbm5lZC1tZXRyaWNzLmdlbmVyYXRlZFwiO1xuaW1wb3J0IHtcbiAgQmFzZUxvYWRCYWxhbmNlcixcbiAgQmFzZUxvYWRCYWxhbmNlckxvb2t1cE9wdGlvbnMsXG4gIEJhc2VMb2FkQmFsYW5jZXJQcm9wcyxcbiAgSUxvYWRCYWxhbmNlclYyLFxuICBMb2FkQmFsYW5jZXJWMk91dHB1dHMsXG59IGZyb20gXCIuLi9sYi1zaGFyZWQvYmFzZS1sb2FkLWJhbGFuY2VyXCI7XG5pbXBvcnQge1xuICBJcEFkZHJlc3NUeXBlLFxuICBBcHBsaWNhdGlvblByb3RvY29sLFxuICBEZXN5bmNNaXRpZ2F0aW9uTW9kZSxcbn0gZnJvbSBcIi4uL2xiLXNoYXJlZC9lbnVtc1wiO1xuaW1wb3J0IHtcbiAgcGFyc2VMb2FkQmFsYW5jZXJGdWxsTmFtZSxcbiAgTG9hZEJhbGFuY2VyQXR0cmlidXRlIGFzIEF0dHJpYnV0ZSxcbn0gZnJvbSBcIi4uL2xiLXNoYXJlZC91dGlsXCI7XG5pbXBvcnQgeyBJU2VjdXJpdHlHcm91cCwgU2VjdXJpdHlHcm91cCB9IGZyb20gXCIuLi9zZWN1cml0eS1ncm91cFwiO1xuaW1wb3J0IHtcbiAgSVZwYyxcbiAgLy8gVnBjXG59IGZyb20gXCIuLi92cGNcIjtcblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhbiBBcHBsaWNhdGlvbiBMb2FkIEJhbGFuY2VyXG4gKlxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvbGF0ZXN0L2FwcGxpY2F0aW9uL2FwcGxpY2F0aW9uLWxvYWQtYmFsYW5jZXJzLmh0bWwjbG9hZC1iYWxhbmNlci1hdHRyaWJ1dGVzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJQcm9wcyBleHRlbmRzIEJhc2VMb2FkQmFsYW5jZXJQcm9wcyB7XG4gIC8qKlxuICAgKiBTZWN1cml0eSBncm91cCB0byBhc3NvY2lhdGUgd2l0aCB0aGlzIGxvYWQgYmFsYW5jZXJcbiAgICpcbiAgICogQGRlZmF1bHQgQSBzZWN1cml0eSBncm91cCBpcyBjcmVhdGVkXG4gICAqL1xuICByZWFkb25seSBzZWN1cml0eUdyb3VwPzogSVNlY3VyaXR5R3JvdXA7XG5cbiAgLyoqXG4gICAqIFRoZSB0eXBlIG9mIElQIGFkZHJlc3NlcyB0byB1c2VcbiAgICpcbiAgICogQGRlZmF1bHQgSXBBZGRyZXNzVHlwZS5JUFY0XG4gICAqL1xuICByZWFkb25seSBpcEFkZHJlc3NUeXBlPzogSXBBZGRyZXNzVHlwZTtcblxuICAvKipcbiAgICogSW5kaWNhdGVzIHdoZXRoZXIgSFRUUC8yIGlzIGVuYWJsZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGh0dHAyRW5hYmxlZD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSBsb2FkIGJhbGFuY2VyIGlkbGUgdGltZW91dCwgaW4gc2Vjb25kc1xuICAgKlxuICAgKiBAZGVmYXVsdCA2MFxuICAgKi9cbiAgcmVhZG9ubHkgaWRsZVRpbWVvdXQ/OiBEdXJhdGlvbjtcblxuICAvKipcbiAgICogSW5kaWNhdGVzIHdoZXRoZXIgSFRUUCBoZWFkZXJzIHdpdGggaW52YWxpZCBoZWFkZXIgZmllbGRzIGFyZSByZW1vdmVkXG4gICAqIGJ5IHRoZSBsb2FkIGJhbGFuY2VyICh0cnVlKSBvciByb3V0ZWQgdG8gdGFyZ2V0cyAoZmFsc2UpXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBkcm9wSW52YWxpZEhlYWRlckZpZWxkcz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgaG93IHRoZSBsb2FkIGJhbGFuY2VyIGhhbmRsZXMgcmVxdWVzdHMgdGhhdFxuICAgKiBtaWdodCBwb3NlIGEgc2VjdXJpdHkgcmlzayB0byB5b3VyIGFwcGxpY2F0aW9uXG4gICAqXG4gICAqIEBkZWZhdWx0IERlc3luY01pdGlnYXRpb25Nb2RlLkRFRkVOU0lWRVxuICAgKi9cbiAgcmVhZG9ubHkgZGVzeW5jTWl0aWdhdGlvbk1vZGU/OiBEZXN5bmNNaXRpZ2F0aW9uTW9kZTtcblxuICAvKipcbiAgICogVGhlIGNsaWVudCBrZWVwIGFsaXZlIGR1cmF0aW9uLiBUaGUgdmFsaWQgcmFuZ2UgaXMgNjAgdG8gNjA0ODAwIHNlY29uZHMgKDEgbWludXRlIHRvIDcgZGF5cykuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gRHVyYXRpb24uc2Vjb25kcygzNjAwKVxuICAgKi9cbiAgcmVhZG9ubHkgY2xpZW50S2VlcEFsaXZlPzogRHVyYXRpb247XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBBcHBsaWNhdGlvbiBMb2FkIEJhbGFuY2VyIHNob3VsZCBwcmVzZXJ2ZSB0aGUgaG9zdCBoZWFkZXIgaW4gdGhlIEhUVFAgcmVxdWVzdFxuICAgKiBhbmQgc2VuZCBpdCB0byB0aGUgdGFyZ2V0IHdpdGhvdXQgYW55IGNoYW5nZS5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IHByZXNlcnZlSG9zdEhlYWRlcj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSB0d28gaGVhZGVycyAoeC1hbXpuLXRscy12ZXJzaW9uIGFuZCB4LWFtem4tdGxzLWNpcGhlci1zdWl0ZSksXG4gICAqIHdoaWNoIGNvbnRhaW4gaW5mb3JtYXRpb24gYWJvdXQgdGhlIG5lZ290aWF0ZWQgVExTIHZlcnNpb24gYW5kIGNpcGhlciBzdWl0ZSxcbiAgICogYXJlIGFkZGVkIHRvIHRoZSBjbGllbnQgcmVxdWVzdCBiZWZvcmUgc2VuZGluZyBpdCB0byB0aGUgdGFyZ2V0LlxuICAgKlxuICAgKiBUaGUgeC1hbXpuLXRscy12ZXJzaW9uIGhlYWRlciBoYXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIFRMUyBwcm90b2NvbCB2ZXJzaW9uIG5lZ290aWF0ZWQgd2l0aCB0aGUgY2xpZW50LFxuICAgKiBhbmQgdGhlIHgtYW16bi10bHMtY2lwaGVyLXN1aXRlIGhlYWRlciBoYXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGNpcGhlciBzdWl0ZSBuZWdvdGlhdGVkIHdpdGggdGhlIGNsaWVudC5cbiAgICpcbiAgICogQm90aCBoZWFkZXJzIGFyZSBpbiBPcGVuU1NMIGZvcm1hdC5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IHhBbXpuVGxzVmVyc2lvbkFuZENpcGhlclN1aXRlSGVhZGVycz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBYLUZvcndhcmRlZC1Gb3IgaGVhZGVyIHNob3VsZCBwcmVzZXJ2ZSB0aGUgc291cmNlIHBvcnRcbiAgICogdGhhdCB0aGUgY2xpZW50IHVzZWQgdG8gY29ubmVjdCB0byB0aGUgbG9hZCBiYWxhbmNlci5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IHByZXNlcnZlWGZmQ2xpZW50UG9ydD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEVuYWJsZXMgeW91IHRvIG1vZGlmeSwgcHJlc2VydmUsIG9yIHJlbW92ZSB0aGUgWC1Gb3J3YXJkZWQtRm9yIGhlYWRlciBpbiB0aGUgSFRUUCByZXF1ZXN0XG4gICAqIGJlZm9yZSB0aGUgQXBwbGljYXRpb24gTG9hZCBCYWxhbmNlciBzZW5kcyB0aGUgcmVxdWVzdCB0byB0aGUgdGFyZ2V0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBYZmZIZWFkZXJQcm9jZXNzaW5nTW9kZS5BUFBFTkRcbiAgICovXG4gIHJlYWRvbmx5IHhmZkhlYWRlclByb2Nlc3NpbmdNb2RlPzogWGZmSGVhZGVyUHJvY2Vzc2luZ01vZGU7XG5cbiAgLyoqXG4gICAqIEluZGljYXRlcyB3aGV0aGVyIHRvIGFsbG93IGEgV0FGLWVuYWJsZWQgbG9hZCBiYWxhbmNlciB0byByb3V0ZSByZXF1ZXN0cyB0byB0YXJnZXRzXG4gICAqIGlmIGl0IGlzIHVuYWJsZSB0byBmb3J3YXJkIHRoZSByZXF1ZXN0IHRvIEFXUyBXQUYuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSB3YWZGYWlsT3Blbj86IGJvb2xlYW47XG59XG5cbi8qKlxuICogUHJvY2Vzc2luZyBtb2RlIG9mIHRoZSBYLUZvcndhcmRlZC1Gb3IgaGVhZGVyIGluIHRoZSBIVFRQIHJlcXVlc3RcbiAqIGJlZm9yZSB0aGUgQXBwbGljYXRpb24gTG9hZCBCYWxhbmNlciBzZW5kcyB0aGUgcmVxdWVzdCB0byB0aGUgdGFyZ2V0LlxuICovXG5leHBvcnQgZW51bSBYZmZIZWFkZXJQcm9jZXNzaW5nTW9kZSB7XG4gIC8qKlxuICAgKiBBcHBsaWNhdGlvbiBMb2FkIEJhbGFuY2VyIGFkZHMgdGhlIGNsaWVudCBJUCBhZGRyZXNzIChvZiB0aGUgbGFzdCBob3ApIHRvIHRoZSBYLUZvcndhcmRlZC1Gb3IgaGVhZGVyXG4gICAqIGluIHRoZSBIVFRQIHJlcXVlc3QgYmVmb3JlIGl0IHNlbmRzIGl0IHRvIHRhcmdldHMuXG4gICAqL1xuICBBUFBFTkQgPSBcImFwcGVuZFwiLFxuICAvKipcbiAgICogQXBwbGljYXRpb24gTG9hZCBCYWxhbmNlciBwcmVzZXJ2ZXMgdGhlIFgtRm9yd2FyZGVkLUZvciBoZWFkZXIgaW4gdGhlIEhUVFAgcmVxdWVzdCxcbiAgICogYW5kIHNlbmRzIGl0IHRvIHRhcmdldHMgd2l0aG91dCBhbnkgY2hhbmdlLlxuICAgKi9cbiAgUFJFU0VSVkUgPSBcInByZXNlcnZlXCIsXG4gIC8qKlxuICAgKiBBcHBsaWNhdGlvbiBMb2FkIEJhbGFuY2VyIHJlbW92ZXMgdGhlIFgtRm9yd2FyZGVkLUZvciBoZWFkZXJcbiAgICogaW4gdGhlIEhUVFAgcmVxdWVzdCBiZWZvcmUgaXQgc2VuZHMgaXQgdG8gdGFyZ2V0cy5cbiAgICovXG4gIFJFTU9WRSA9IFwicmVtb3ZlXCIsXG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgbG9va2luZyB1cCBhbiBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlclxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTG9va3VwT3B0aW9uc1xuICBleHRlbmRzIEJhc2VMb2FkQmFsYW5jZXJMb29rdXBPcHRpb25zIHt9XG5cbi8qKlxuICogRGVmaW5lIGFuIEFwcGxpY2F0aW9uIExvYWQgQmFsYW5jZXJcbiAqXG4gKiBAcmVzb3VyY2UgQVdTOjpFbGFzdGljTG9hZEJhbGFuY2luZ1YyOjpMb2FkQmFsYW5jZXJcbiAqL1xuZXhwb3J0IGNsYXNzIEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyXG4gIGV4dGVuZHMgQmFzZUxvYWRCYWxhbmNlclxuICBpbXBsZW1lbnRzIElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlclxue1xuICAvLyBUT0RPOiBBZGQgR3JpZCBsb29rdXAgc3VwcG9ydFxuICAvLyAvKipcbiAgLy8gICogTG9vayB1cCBhbiBhcHBsaWNhdGlvbiBsb2FkIGJhbGFuY2VyLlxuICAvLyAgKi9cbiAgLy8gcHVibGljIHN0YXRpYyBmcm9tTG9va3VwKFxuICAvLyAgIHNjb3BlOiBDb25zdHJ1Y3QsXG4gIC8vICAgaWQ6IHN0cmluZyxcbiAgLy8gICBvcHRpb25zOiBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckxvb2t1cE9wdGlvbnMsXG4gIC8vICk6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciB7XG4gIC8vICAgY29uc3QgcHJvcHMgPSBCYXNlTG9hZEJhbGFuY2VyLl9xdWVyeUNvbnRleHRQcm92aWRlcihzY29wZSwge1xuICAvLyAgICAgdXNlck9wdGlvbnM6IG9wdGlvbnMsXG4gIC8vICAgICBsb2FkQmFsYW5jZXJUeXBlOiBMb2FkQmFsYW5jZXJUeXBlLkFQUExJQ0FUSU9OLFxuICAvLyAgIH0pO1xuXG4gIC8vICAgcmV0dXJuIG5ldyBMb29rZWRVcEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyKHNjb3BlLCBpZCwgcHJvcHMpO1xuICAvLyB9XG5cbiAgLyoqXG4gICAqIEltcG9ydCBhbiBleGlzdGluZyBBcHBsaWNhdGlvbiBMb2FkIEJhbGFuY2VyXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZyb21BcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF0dHJpYnV0ZXMoXG4gICAgc2NvcGU6IENvbnN0cnVjdCxcbiAgICBpZDogc3RyaW5nLFxuICAgIGF0dHJzOiBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF0dHJpYnV0ZXMsXG4gICk6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlciB7XG4gICAgcmV0dXJuIG5ldyBJbXBvcnRlZEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyKHNjb3BlLCBpZCwgYXR0cnMpO1xuICB9XG5cbiAgcHVibGljIHJlYWRvbmx5IGNvbm5lY3Rpb25zOiBDb25uZWN0aW9ucztcbiAgcHVibGljIHJlYWRvbmx5IGlwQWRkcmVzc1R5cGU/OiBJcEFkZHJlc3NUeXBlO1xuICBwdWJsaWMgcmVhZG9ubHkgbGlzdGVuZXJzOiBBcHBsaWNhdGlvbkxpc3RlbmVyW107XG4gIHB1YmxpYyByZWFkb25seSBtZXRyaWNzOiBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHNjb3BlOiBDb25zdHJ1Y3QsXG4gICAgaWQ6IHN0cmluZyxcbiAgICBwcm9wczogQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJQcm9wcyxcbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCBwcm9wcywge1xuICAgICAgbG9hZEJhbGFuY2VyVHlwZTogXCJhcHBsaWNhdGlvblwiLFxuICAgICAgc2VjdXJpdHlHcm91cHM6IExhenkubGlzdFZhbHVlKHtcbiAgICAgICAgcHJvZHVjZTogKCkgPT5cbiAgICAgICAgICB0aGlzLmNvbm5lY3Rpb25zLnNlY3VyaXR5R3JvdXBzLm1hcCgoc2cpID0+IHNnLnNlY3VyaXR5R3JvdXBJZCksXG4gICAgICB9KSxcbiAgICAgIGlwQWRkcmVzc1R5cGU6IHByb3BzLmlwQWRkcmVzc1R5cGUsXG4gICAgfSk7XG5cbiAgICB0aGlzLmlwQWRkcmVzc1R5cGUgPSBwcm9wcy5pcEFkZHJlc3NUeXBlID8/IElwQWRkcmVzc1R5cGUuSVBWNDtcblxuICAgIGlmIChcbiAgICAgIHByb3BzLmlwQWRkcmVzc1R5cGUgPT09IElwQWRkcmVzc1R5cGUuRFVBTF9TVEFDS19XSVRIT1VUX1BVQkxJQ19JUFY0ICYmXG4gICAgICAhcHJvcHMuaW50ZXJuZXRGYWNpbmdcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJkdWFsLXN0YWNrIHdpdGhvdXQgcHVibGljIElQdjQgYWRkcmVzcyBjYW4gb25seSBiZSB1c2VkIHdpdGggaW50ZXJuZXQtZmFjaW5nIHNjaGVtZS5cIixcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2VjdXJpdHlHcm91cHMgPSBbXG4gICAgICBwcm9wcy5zZWN1cml0eUdyb3VwIHx8XG4gICAgICAgIG5ldyBTZWN1cml0eUdyb3VwKHRoaXMsIFwiU2VjdXJpdHlHcm91cFwiLCB7XG4gICAgICAgICAgdnBjOiBwcm9wcy52cGMsXG4gICAgICAgICAgZGVzY3JpcHRpb246IGBBdXRvbWF0aWNhbGx5IGNyZWF0ZWQgU2VjdXJpdHkgR3JvdXAgZm9yIEVMQiAke0F3c1N0YWNrLnVuaXF1ZUlkKHRoaXMpfWAsXG4gICAgICAgICAgYWxsb3dBbGxPdXRib3VuZDogZmFsc2UsXG4gICAgICAgIH0pLFxuICAgIF07XG4gICAgdGhpcy5jb25uZWN0aW9ucyA9IG5ldyBDb25uZWN0aW9ucyh7IHNlY3VyaXR5R3JvdXBzIH0pO1xuICAgIHRoaXMubGlzdGVuZXJzID0gW107XG4gICAgdGhpcy5tZXRyaWNzID0gbmV3IEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTWV0cmljcyhcbiAgICAgIHRoaXMsXG4gICAgICB0aGlzLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICk7XG5cbiAgICBpZiAocHJvcHMuaHR0cDJFbmFibGVkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuc2V0QXR0cmlidXRlKFxuICAgICAgICBcInJvdXRpbmcuaHR0cDIuZW5hYmxlZFwiLFxuICAgICAgICBwcm9wcy5odHRwMkVuYWJsZWQgPyBcInRydWVcIiA6IFwiZmFsc2VcIixcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChwcm9wcy5pZGxlVGltZW91dCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnNldEF0dHJpYnV0ZShcbiAgICAgICAgXCJpZGxlX3RpbWVvdXQudGltZW91dF9zZWNvbmRzXCIsXG4gICAgICAgIHByb3BzLmlkbGVUaW1lb3V0LnRvU2Vjb25kcygpLnRvU3RyaW5nKCksXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAocHJvcHMuZHJvcEludmFsaWRIZWFkZXJGaWVsZHMpIHtcbiAgICAgIHRoaXMuc2V0QXR0cmlidXRlKFxuICAgICAgICBcInJvdXRpbmcuaHR0cC5kcm9wX2ludmFsaWRfaGVhZGVyX2ZpZWxkcy5lbmFibGVkXCIsXG4gICAgICAgIFwidHJ1ZVwiLFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKHByb3BzLmRlc3luY01pdGlnYXRpb25Nb2RlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuc2V0QXR0cmlidXRlKFxuICAgICAgICBcInJvdXRpbmcuaHR0cC5kZXN5bmNfbWl0aWdhdGlvbl9tb2RlXCIsXG4gICAgICAgIHByb3BzLmRlc3luY01pdGlnYXRpb25Nb2RlLFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKHByb3BzLnByZXNlcnZlSG9zdEhlYWRlcikge1xuICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUoXCJyb3V0aW5nLmh0dHAucHJlc2VydmVfaG9zdF9oZWFkZXIuZW5hYmxlZFwiLCBcInRydWVcIik7XG4gICAgfVxuICAgIGlmIChwcm9wcy54QW16blRsc1ZlcnNpb25BbmRDaXBoZXJTdWl0ZUhlYWRlcnMpIHtcbiAgICAgIHRoaXMuc2V0QXR0cmlidXRlKFxuICAgICAgICBcInJvdXRpbmcuaHR0cC54X2Ftem5fdGxzX3ZlcnNpb25fYW5kX2NpcGhlcl9zdWl0ZS5lbmFibGVkXCIsXG4gICAgICAgIFwidHJ1ZVwiLFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKHByb3BzLnByZXNlcnZlWGZmQ2xpZW50UG9ydCkge1xuICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUoXCJyb3V0aW5nLmh0dHAueGZmX2NsaWVudF9wb3J0LmVuYWJsZWRcIiwgXCJ0cnVlXCIpO1xuICAgIH1cbiAgICBpZiAocHJvcHMueGZmSGVhZGVyUHJvY2Vzc2luZ01vZGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUoXG4gICAgICAgIFwicm91dGluZy5odHRwLnhmZl9oZWFkZXJfcHJvY2Vzc2luZy5tb2RlXCIsXG4gICAgICAgIHByb3BzLnhmZkhlYWRlclByb2Nlc3NpbmdNb2RlLFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKHByb3BzLndhZkZhaWxPcGVuKSB7XG4gICAgICB0aGlzLnNldEF0dHJpYnV0ZShcIndhZi5mYWlsX29wZW4uZW5hYmxlZFwiLCBcInRydWVcIik7XG4gICAgfVxuICAgIGlmIChwcm9wcy5jbGllbnRLZWVwQWxpdmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgY2xpZW50S2VlcEFsaXZlSW5NaWxsaXMgPSBwcm9wcy5jbGllbnRLZWVwQWxpdmUudG9NaWxsaXNlY29uZHMoKTtcbiAgICAgIGlmIChjbGllbnRLZWVwQWxpdmVJbk1pbGxpcyA8IDEwMDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBcXCdjbGllbnRLZWVwQWxpdmVcXCcgbXVzdCBiZSBiZXR3ZWVuIDYwIGFuZCA2MDQ4MDAgc2Vjb25kcy4gR290OiAke2NsaWVudEtlZXBBbGl2ZUluTWlsbGlzfSBtaWxsaXNlY29uZHNgLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjbGllbnRLZWVwQWxpdmVJblNlY29uZHMgPSBwcm9wcy5jbGllbnRLZWVwQWxpdmUudG9TZWNvbmRzKCk7XG4gICAgICBpZiAoY2xpZW50S2VlcEFsaXZlSW5TZWNvbmRzIDwgNjAgfHwgY2xpZW50S2VlcEFsaXZlSW5TZWNvbmRzID4gNjA0ODAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgXFwnY2xpZW50S2VlcEFsaXZlXFwnIG11c3QgYmUgYmV0d2VlbiA2MCBhbmQgNjA0ODAwIHNlY29uZHMuIEdvdDogJHtjbGllbnRLZWVwQWxpdmVJblNlY29uZHN9IHNlY29uZHNgLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgdGhpcy5zZXRBdHRyaWJ1dGUoXG4gICAgICAgIFwiY2xpZW50X2tlZXBfYWxpdmUuc2Vjb25kc1wiLFxuICAgICAgICBjbGllbnRLZWVwQWxpdmVJblNlY29uZHMudG9TdHJpbmcoKSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLmNyb3NzWm9uZUVuYWJsZWQgPT09IGZhbHNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwiY3Jvc3Nab25lRW5hYmxlZCBjYW5ub3QgYmUgZmFsc2Ugd2l0aCBBcHBsaWNhdGlvbiBMb2FkIEJhbGFuY2Vycy5cIixcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhIG5ldyBsaXN0ZW5lciB0byB0aGlzIGxvYWQgYmFsYW5jZXJcbiAgICovXG4gIHB1YmxpYyBhZGRMaXN0ZW5lcihcbiAgICBpZDogc3RyaW5nLFxuICAgIHByb3BzOiBCYXNlQXBwbGljYXRpb25MaXN0ZW5lclByb3BzLFxuICApOiBBcHBsaWNhdGlvbkxpc3RlbmVyIHtcbiAgICBjb25zdCBsaXN0ZW5lciA9IG5ldyBBcHBsaWNhdGlvbkxpc3RlbmVyKHRoaXMsIGlkLCB7XG4gICAgICBsb2FkQmFsYW5jZXI6IHRoaXMsXG4gICAgICAuLi5wcm9wcyxcbiAgICB9KTtcbiAgICB0aGlzLmxpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTtcbiAgICByZXR1cm4gbGlzdGVuZXI7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgcmVkaXJlY3Rpb24gbGlzdGVuZXIgdG8gdGhpcyBsb2FkIGJhbGFuY2VyXG4gICAqL1xuICBwdWJsaWMgYWRkUmVkaXJlY3QoXG4gICAgcHJvcHM6IEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyUmVkaXJlY3RDb25maWcgPSB7fSxcbiAgKTogQXBwbGljYXRpb25MaXN0ZW5lciB7XG4gICAgY29uc3Qgc291cmNlUG9ydCA9IHByb3BzLnNvdXJjZVBvcnQgPz8gODA7XG4gICAgY29uc3QgdGFyZ2V0UG9ydCA9IChwcm9wcy50YXJnZXRQb3J0ID8/IDQ0MykudG9TdHJpbmcoKTtcbiAgICByZXR1cm4gdGhpcy5hZGRMaXN0ZW5lcihgUmVkaXJlY3Qke3NvdXJjZVBvcnR9VG8ke3RhcmdldFBvcnR9YCwge1xuICAgICAgcHJvdG9jb2w6IHByb3BzLnNvdXJjZVByb3RvY29sID8/IEFwcGxpY2F0aW9uUHJvdG9jb2wuSFRUUCxcbiAgICAgIHBvcnQ6IHNvdXJjZVBvcnQsXG4gICAgICBvcGVuOiBwcm9wcy5vcGVuID8/IHRydWUsXG4gICAgICBkZWZhdWx0QWN0aW9uOiBMaXN0ZW5lckFjdGlvbi5yZWRpcmVjdCh7XG4gICAgICAgIHBvcnQ6IHRhcmdldFBvcnQsXG4gICAgICAgIHByb3RvY29sOiBwcm9wcy50YXJnZXRQcm90b2NvbCA/PyBBcHBsaWNhdGlvblByb3RvY29sLkhUVFBTLFxuICAgICAgICBwZXJtYW5lbnQ6IHRydWUsXG4gICAgICB9KSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmFibGUgYWNjZXNzIGxvZ2dpbmcgZm9yIHRoaXMgbG9hZCBiYWxhbmNlci5cbiAgICpcbiAgICogQSByZWdpb24gbXVzdCBiZSBzcGVjaWZpZWQgb24gdGhlIHN0YWNrIGNvbnRhaW5pbmcgdGhlIGxvYWQgYmFsYW5jZXI7IHlvdSBjYW5ub3QgZW5hYmxlIGxvZ2dpbmcgb25cbiAgICogZW52aXJvbm1lbnQtYWdub3N0aWMgc3RhY2tzLiBTZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Nkay9sYXRlc3QvZ3VpZGUvZW52aXJvbm1lbnRzLmh0bWxcbiAgICovXG4gIHB1YmxpYyBsb2dBY2Nlc3NMb2dzKGJ1Y2tldDogczMuSUJ1Y2tldCwgcHJlZml4Pzogc3RyaW5nKSB7XG4gICAgLy8gVE9ETzogV2h5IGRvZXMgdGhpcyBvdmVycmlkZSBCYXNlTG9hZEJhbGFuY2VyLnB1dEFjY2Vzc0xvZ3M/XG4gICAgLyoqXG4gICAgICogS01TIGtleSBlbmNyeXB0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgb24gQWNjZXNzIExvZyBidWNrZXQgZm9yIEFMQiwgdGhlIGJ1Y2tldCBtdXN0IHVzZSBBbWF6b24gUzMtbWFuYWdlZCBrZXlzIChTU0UtUzMpLlxuICAgICAqIFNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvbGF0ZXN0L2FwcGxpY2F0aW9uL2VuYWJsZS1hY2Nlc3MtbG9nZ2luZy5odG1sI2J1Y2tldC1wZXJtaXNzaW9ucy10cm91Ymxlc2hvb3RpbmdcbiAgICAgKi9cbiAgICBpZiAoYnVja2V0LmVuY3J5cHRpb25LZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJFbmNyeXB0aW9uIGtleSBkZXRlY3RlZC4gQnVja2V0IGVuY3J5cHRpb24gdXNpbmcgS01TIGtleXMgaXMgdW5zdXBwb3J0ZWRcIixcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gcHJlZml4ID0gcHJlZml4OyAvLyBwcmVmaXggaXMgb3B0aW9uYWwgaW4gVEYgfHwgXCJcIjtcbiAgICB0aGlzLnNldEF0dHJpYnV0ZShcImFjY2Vzc19sb2dzLnMzLmVuYWJsZWRcIiwgXCJ0cnVlXCIpO1xuICAgIHRoaXMuc2V0QXR0cmlidXRlKFwiYWNjZXNzX2xvZ3MuczMuYnVja2V0XCIsIGJ1Y2tldC5idWNrZXROYW1lLnRvU3RyaW5nKCkpO1xuICAgIHRoaXMuc2V0QXR0cmlidXRlKFwiYWNjZXNzX2xvZ3MuczMucHJlZml4XCIsIHByZWZpeCk7XG5cbiAgICBjb25zdCBsb2dzRGVsaXZlcnlTZXJ2aWNlUHJpbmNpcGFsID0gbmV3IFNlcnZpY2VQcmluY2lwYWwoXG4gICAgICBcImRlbGl2ZXJ5LmxvZ3MuYW1hem9uYXdzLmNvbVwiLFxuICAgICk7XG4gICAgYnVja2V0LmFkZFRvUmVzb3VyY2VQb2xpY3koXG4gICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgYWN0aW9uczogW1wiczM6UHV0T2JqZWN0XCJdLFxuICAgICAgICBwcmluY2lwYWxzOiBbdGhpcy5yZXNvdXJjZVBvbGljeVByaW5jaXBhbCgpXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgICAgYnVja2V0LmFybkZvck9iamVjdHMoXG4gICAgICAgICAgICBgJHtwcmVmaXggPyBwcmVmaXggKyBcIi9cIiA6IFwiXCJ9QVdTTG9ncy8ke0F3c1N0YWNrLm9mQXdzQ29uc3RydWN0KHRoaXMpLmFjY291bnR9LypgLFxuICAgICAgICAgICksXG4gICAgICAgIF0sXG4gICAgICB9KSxcbiAgICApO1xuICAgIGJ1Y2tldC5hZGRUb1Jlc291cmNlUG9saWN5KFxuICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGFjdGlvbnM6IFtcInMzOlB1dE9iamVjdFwiXSxcbiAgICAgICAgcHJpbmNpcGFsczogW2xvZ3NEZWxpdmVyeVNlcnZpY2VQcmluY2lwYWxdLFxuICAgICAgICByZXNvdXJjZXM6IFtcbiAgICAgICAgICBidWNrZXQuYXJuRm9yT2JqZWN0cyhcbiAgICAgICAgICAgIGAke3ByZWZpeCA/IHByZWZpeCArIFwiL1wiIDogXCJcIn1BV1NMb2dzLyR7dGhpcy5lbnYuYWNjb3VudH0vKmAsXG4gICAgICAgICAgKSxcbiAgICAgICAgXSxcbiAgICAgICAgY29uZGl0aW9uOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdGVzdDogXCJTdHJpbmdFcXVhbHNcIixcbiAgICAgICAgICAgIHZhcmlhYmxlOiBcInMzOngtYW16LWFjbFwiLFxuICAgICAgICAgICAgdmFsdWVzOiBbXCJidWNrZXQtb3duZXItZnVsbC1jb250cm9sXCJdLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KSxcbiAgICApO1xuICAgIGJ1Y2tldC5hZGRUb1Jlc291cmNlUG9saWN5KFxuICAgICAgbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICAgIGFjdGlvbnM6IFtcInMzOkdldEJ1Y2tldEFjbFwiXSxcbiAgICAgICAgcHJpbmNpcGFsczogW2xvZ3NEZWxpdmVyeVNlcnZpY2VQcmluY2lwYWxdLFxuICAgICAgICByZXNvdXJjZXM6IFtidWNrZXQuYnVja2V0QXJuXSxcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICAvLyBtYWtlIHN1cmUgdGhlIGJ1Y2tldCdzIHBvbGljeSBpcyBjcmVhdGVkIGJlZm9yZSB0aGUgQUxCIChzZWUgaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2lzc3Vlcy8xNjMzKVxuICAgIC8vIGF0IHRoZSBMMSBsZXZlbCB0byBhdm9pZCBjcmVhdGluZyBhIGNpcmN1bGFyIGRlcGVuZGVuY3kgKHNlZSBodHRwczovL2dpdGh1Yi5jb20vYXdzL2F3cy1jZGsvaXNzdWVzLzI3NTI4XG4gICAgLy8gYW5kIGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MvYXdzLWNkay9pc3N1ZXMvMjc5MjgpXG4gICAgY29uc3QgbGIgPSB0aGlzLm5vZGUuZGVmYXVsdENoaWxkIGFzIHRmTG9hZEJhbGFuY2VyLkxiIHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IGJ1Y2tldFBvbGljeSA9IGJ1Y2tldC5wb2xpY3k/Lm5vZGUuZGVmYXVsdENoaWxkO1xuICAgIGlmIChcbiAgICAgIGxiICYmXG4gICAgICBidWNrZXRQb2xpY3kgJiZcbiAgICAgIFRlcnJhZm9ybVJlc291cmNlLmlzVGVycmFmb3JtUmVzb3VyY2UobGIpICYmXG4gICAgICBUZXJyYWZvcm1SZXNvdXJjZS5pc1RlcnJhZm9ybVJlc291cmNlKGJ1Y2tldFBvbGljeSlcbiAgICApIHtcbiAgICAgIGxiLm5vZGUuYWRkRGVwZW5kZW5jeShidWNrZXRQb2xpY3kpO1xuICAgIH1cbiAgICAvLyBUT0RPOiBTaG91bGQgcHV0QWNjZXNzTG9ncyBiZSBoYW5kbGVkIGFzIHBhcnQgb2YgcHJlcGFyZVN0YWNrIChpbiB0b1RlcnJhZm9ybSgpIGluc3RlYWQpP1xuICAgIC8vIG9ubHkgaWYgbGIuYWNjZXNzTG9ncy5pbnRlcm5hbFZhbHVlICE9PSB1bmRlZmluZWQ/IChvciBiYXNlZCBvbiB0aGlzLmF0dHJpYnV0ZXM/KVxuICAgIGxiPy5wdXRBY2Nlc3NMb2dzKHtcbiAgICAgIGVuYWJsZWQ6IHRoaXMubGF6eUJvb2xBdHRyKEF0dHJpYnV0ZS5hY2Nlc3NMb2dzUzNFbmFibGVkKSxcbiAgICAgIGJ1Y2tldDogdGhpcy5sYXp5U3RyaW5nQXR0cihBdHRyaWJ1dGUuYWNjZXNzTG9nc1MzQnVja2V0KSxcbiAgICAgIHByZWZpeDogdGhpcy5sYXp5U3RyaW5nQXR0cihBdHRyaWJ1dGUuYWNjZXNzTG9nc1MzUHJlZml4KSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmFibGUgY29ubmVjdGlvbiBsb2dnaW5nIGZvciB0aGlzIGxvYWQgYmFsYW5jZXIuXG4gICAqXG4gICAqIEEgcmVnaW9uIG11c3QgYmUgc3BlY2lmaWVkIG9uIHRoZSBzdGFjayBjb250YWluaW5nIHRoZSBsb2FkIGJhbGFuY2VyOyB5b3UgY2Fubm90IGVuYWJsZSBsb2dnaW5nIG9uXG4gICAqIGVudmlyb25tZW50LWFnbm9zdGljIHN0YWNrcy5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vY2RrL2xhdGVzdC9ndWlkZS9lbnZpcm9ubWVudHMuaHRtbFxuICAgKi9cbiAgcHVibGljIGxvZ0Nvbm5lY3Rpb25Mb2dzKGJ1Y2tldDogczMuSUJ1Y2tldCwgcHJlZml4Pzogc3RyaW5nKSB7XG4gICAgLyoqXG4gICAgICogS01TIGtleSBlbmNyeXB0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgb24gQ29ubmVjdGlvbiBMb2cgYnVja2V0IGZvciBBTEIsIHRoZSBidWNrZXQgbXVzdCB1c2UgQW1hem9uIFMzLW1hbmFnZWQga2V5cyAoU1NFLVMzKS5cbiAgICAgKiBTZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nL2xhdGVzdC9hcHBsaWNhdGlvbi9lbmFibGUtY29ubmVjdGlvbi1sb2dnaW5nLmh0bWwjYnVja2V0LXBlcm1pc3Npb25zLXRyb3VibGVzaG9vdGluZy1jb25uZWN0aW9uXG4gICAgICovXG4gICAgaWYgKGJ1Y2tldC5lbmNyeXB0aW9uS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwiRW5jcnlwdGlvbiBrZXkgZGV0ZWN0ZWQuIEJ1Y2tldCBlbmNyeXB0aW9uIHVzaW5nIEtNUyBrZXlzIGlzIHVuc3VwcG9ydGVkXCIsXG4gICAgICApO1xuICAgIH1cblxuICAgIHByZWZpeCA9IHByZWZpeCB8fCBcIlwiO1xuICAgIHRoaXMuc2V0QXR0cmlidXRlKFwiY29ubmVjdGlvbl9sb2dzLnMzLmVuYWJsZWRcIiwgXCJ0cnVlXCIpO1xuICAgIHRoaXMuc2V0QXR0cmlidXRlKFxuICAgICAgXCJjb25uZWN0aW9uX2xvZ3MuczMuYnVja2V0XCIsXG4gICAgICBidWNrZXQuYnVja2V0TmFtZS50b1N0cmluZygpLFxuICAgICk7XG4gICAgdGhpcy5zZXRBdHRyaWJ1dGUoXCJjb25uZWN0aW9uX2xvZ3MuczMucHJlZml4XCIsIHByZWZpeCk7XG5cbiAgICAvLyBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvbGF0ZXN0L2FwcGxpY2F0aW9uL2VuYWJsZS1jb25uZWN0aW9uLWxvZ2dpbmcuaHRtbFxuICAgIGNvbnN0IGxvZ3NEZWxpdmVyeVNlcnZpY2VQcmluY2lwYWwgPSBuZXcgU2VydmljZVByaW5jaXBhbChcbiAgICAgIFwiZGVsaXZlcnkubG9ncy5hbWF6b25hd3MuY29tXCIsXG4gICAgKTtcbiAgICBidWNrZXQuYWRkVG9SZXNvdXJjZVBvbGljeShcbiAgICAgIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbXCJzMzpQdXRPYmplY3RcIl0sXG4gICAgICAgIHByaW5jaXBhbHM6IFt0aGlzLnJlc291cmNlUG9saWN5UHJpbmNpcGFsKCldLFxuICAgICAgICByZXNvdXJjZXM6IFtcbiAgICAgICAgICBidWNrZXQuYXJuRm9yT2JqZWN0cyhcbiAgICAgICAgICAgIGAke3ByZWZpeCA/IHByZWZpeCArIFwiL1wiIDogXCJcIn1BV1NMb2dzLyR7QXdzU3RhY2sub2ZBd3NDb25zdHJ1Y3QodGhpcykuYWNjb3VudH0vKmAsXG4gICAgICAgICAgKSxcbiAgICAgICAgXSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgLy8gV2Ugc3RpbGwgbmVlZCB0aGlzIHBvbGljeSBmb3IgdGhlIGJ1Y2tldCB1c2luZyB0aGUgQUNMXG4gICAgYnVja2V0LmFkZFRvUmVzb3VyY2VQb2xpY3koXG4gICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgYWN0aW9uczogW1wiczM6UHV0T2JqZWN0XCJdLFxuICAgICAgICBwcmluY2lwYWxzOiBbbG9nc0RlbGl2ZXJ5U2VydmljZVByaW5jaXBhbF0sXG4gICAgICAgIHJlc291cmNlczogW1xuICAgICAgICAgIGJ1Y2tldC5hcm5Gb3JPYmplY3RzKFxuICAgICAgICAgICAgYCR7cHJlZml4ID8gcHJlZml4ICsgXCIvXCIgOiBcIlwifUFXU0xvZ3MvJHtBd3NTdGFjay5vZkF3c0NvbnN0cnVjdCh0aGlzKS5hY2NvdW50fS8qYCxcbiAgICAgICAgICApLFxuICAgICAgICBdLFxuICAgICAgICBjb25kaXRpb246IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0ZXN0OiBcIlN0cmluZ0VxdWFsc1wiLFxuICAgICAgICAgICAgdmFyaWFibGU6IFwiczM6eC1hbXotYWNsXCIsXG4gICAgICAgICAgICB2YWx1ZXM6IFtcImJ1Y2tldC1vd25lci1mdWxsLWNvbnRyb2xcIl0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pLFxuICAgICk7XG4gICAgYnVja2V0LmFkZFRvUmVzb3VyY2VQb2xpY3koXG4gICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgYWN0aW9uczogW1wiczM6R2V0QnVja2V0QWNsXCJdLFxuICAgICAgICBwcmluY2lwYWxzOiBbbG9nc0RlbGl2ZXJ5U2VydmljZVByaW5jaXBhbF0sXG4gICAgICAgIHJlc291cmNlczogW2J1Y2tldC5idWNrZXRBcm5dLFxuICAgICAgfSksXG4gICAgKTtcblxuICAgIC8vIG1ha2Ugc3VyZSB0aGUgYnVja2V0J3MgcG9saWN5IGlzIGNyZWF0ZWQgYmVmb3JlIHRoZSBBTEIgKHNlZSBodHRwczovL2dpdGh1Yi5jb20vYXdzL2F3cy1jZGsvaXNzdWVzLzE2MzMpXG4gICAgLy8gYXQgdGhlIEwxIGxldmVsIHRvIGF2b2lkIGNyZWF0aW5nIGEgY2lyY3VsYXIgZGVwZW5kZW5jeSAoc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MvYXdzLWNkay9pc3N1ZXMvMjc1MjhcbiAgICAvLyBhbmQgaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2lzc3Vlcy8yNzkyOClcbiAgICBjb25zdCBsYiA9IHRoaXMubm9kZS5kZWZhdWx0Q2hpbGQgYXMgdGZMb2FkQmFsYW5jZXIuTGIgfCB1bmRlZmluZWQ7XG4gICAgY29uc3QgYnVja2V0UG9saWN5ID0gYnVja2V0LnBvbGljeT8ubm9kZS5kZWZhdWx0Q2hpbGQ7XG4gICAgaWYgKFxuICAgICAgbGIgJiZcbiAgICAgIGJ1Y2tldFBvbGljeSAmJlxuICAgICAgVGVycmFmb3JtUmVzb3VyY2UuaXNUZXJyYWZvcm1SZXNvdXJjZShsYikgJiZcbiAgICAgIFRlcnJhZm9ybVJlc291cmNlLmlzVGVycmFmb3JtUmVzb3VyY2UoYnVja2V0UG9saWN5KVxuICAgICkge1xuICAgICAgbGIubm9kZS5hZGREZXBlbmRlbmN5KGJ1Y2tldFBvbGljeSk7XG4gICAgfVxuICAgIC8vIFRPRE86IFNob3VsZCBwdXRDb25uZWN0aW9uTG9ncyBiZSBoYW5kbGVkIGFzIHBhcnQgb2YgcHJlcGFyZVN0YWNrIChpbiB0b1RlcnJhZm9ybSgpIGluc3RlYWQpP1xuICAgIC8vIG9ubHkgaWYgbGIuY29ubmVjdGlvbkxvZ3MuaW50ZXJuYWxWYWx1ZSAhPT0gdW5kZWZpbmVkPyAob3IgYmFzZWQgb24gdGhpcy5hdHRyaWJ1dGVzPylcbiAgICBsYj8ucHV0Q29ubmVjdGlvbkxvZ3Moe1xuICAgICAgZW5hYmxlZDogdGhpcy5sYXp5Qm9vbEF0dHIoQXR0cmlidXRlLmNvbm5lY3Rpb25Mb2dzUzNFbmFibGVkKSxcbiAgICAgIGJ1Y2tldDogdGhpcy5sYXp5U3RyaW5nQXR0cihBdHRyaWJ1dGUuY29ubmVjdGlvbkxvZ3NTM0J1Y2tldCksXG4gICAgICBwcmVmaXg6IHRoaXMubGF6eVN0cmluZ0F0dHIoQXR0cmlidXRlLmNvbm5lY3Rpb25Mb2dzUzNQcmVmaXgpLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhIHNlY3VyaXR5IGdyb3VwIHRvIHRoaXMgbG9hZCBiYWxhbmNlclxuICAgKi9cbiAgcHVibGljIGFkZFNlY3VyaXR5R3JvdXAoc2VjdXJpdHlHcm91cDogSVNlY3VyaXR5R3JvdXApIHtcbiAgICB0aGlzLmNvbm5lY3Rpb25zLmFkZFNlY3VyaXR5R3JvdXAoc2VjdXJpdHlHcm91cCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBnaXZlbiBuYW1lZCBtZXRyaWMgZm9yIHRoaXMgQXBwbGljYXRpb24gTG9hZCBCYWxhbmNlclxuICAgKlxuICAgKiBAZGVmYXVsdCBBdmVyYWdlIG92ZXIgNSBtaW51dGVzXG4gICAqIEBkZXByZWNhdGVkIFVzZSBgYEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyLm1ldHJpY3MuY3VzdG9tYGAgaW5zdGVhZFxuICAgKi9cbiAgcHVibGljIG1ldHJpYyhcbiAgICBtZXRyaWNOYW1lOiBzdHJpbmcsXG4gICAgcHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMsXG4gICk6IGNsb3Vkd2F0Y2guTWV0cmljIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWNzLmN1c3RvbShtZXRyaWNOYW1lLCBwcm9wcyk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHRvdGFsIG51bWJlciBvZiBjb25jdXJyZW50IFRDUCBjb25uZWN0aW9ucyBhY3RpdmUgZnJvbSBjbGllbnRzIHRvIHRoZVxuICAgKiBsb2FkIGJhbGFuY2VyIGFuZCBmcm9tIHRoZSBsb2FkIGJhbGFuY2VyIHRvIHRhcmdldHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IFN1bSBvdmVyIDUgbWludXRlc1xuICAgKiBAZGVwcmVjYXRlZCBVc2UgYGBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlci5tZXRyaWNzLmFjdGl2ZUNvbm5lY3Rpb25Db3VudGBgIGluc3RlYWRcbiAgICovXG4gIHB1YmxpYyBtZXRyaWNBY3RpdmVDb25uZWN0aW9uQ291bnQocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWNzLmFjdGl2ZUNvbm5lY3Rpb25Db3VudChwcm9wcyk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBUTFMgY29ubmVjdGlvbnMgaW5pdGlhdGVkIGJ5IHRoZSBjbGllbnQgdGhhdCBkaWQgbm90XG4gICAqIGVzdGFibGlzaCBhIHNlc3Npb24gd2l0aCB0aGUgbG9hZCBiYWxhbmNlci4gUG9zc2libGUgY2F1c2VzIGluY2x1ZGUgYVxuICAgKiBtaXNtYXRjaCBvZiBjaXBoZXJzIG9yIHByb3RvY29scy5cbiAgICpcbiAgICogQGRlZmF1bHQgU3VtIG92ZXIgNSBtaW51dGVzXG4gICAqIEBkZXByZWNhdGVkIFVzZSBgYEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyLm1ldHJpY3MuY2xpZW50VGxzTmVnb3RpYXRpb25FcnJvckNvdW50YGAgaW5zdGVhZFxuICAgKi9cbiAgcHVibGljIG1ldHJpY0NsaWVudFRsc05lZ290aWF0aW9uRXJyb3JDb3VudChcbiAgICBwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyxcbiAgKSB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljcy5jbGllbnRUbHNOZWdvdGlhdGlvbkVycm9yQ291bnQocHJvcHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgbG9hZCBiYWxhbmNlciBjYXBhY2l0eSB1bml0cyAoTENVKSB1c2VkIGJ5IHlvdXIgbG9hZCBiYWxhbmNlci5cbiAgICpcbiAgICogQGRlZmF1bHQgU3VtIG92ZXIgNSBtaW51dGVzXG4gICAqIEBkZXByZWNhdGVkIFVzZSBgYEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyLm1ldHJpY3MuY29uc3VtZWRMQ1VzYGAgaW5zdGVhZFxuICAgKi9cbiAgcHVibGljIG1ldHJpY0NvbnN1bWVkTENVcyhwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLm1ldHJpY3MuY29uc3VtZWRMQ1VzKHByb3BzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIGZpeGVkLXJlc3BvbnNlIGFjdGlvbnMgdGhhdCB3ZXJlIHN1Y2Nlc3NmdWwuXG4gICAqXG4gICAqIEBkZWZhdWx0IFN1bSBvdmVyIDUgbWludXRlc1xuICAgKiBAZGVwcmVjYXRlZCBVc2UgYGBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlci5tZXRyaWNzLmh0dHBGaXhlZFJlc3BvbnNlQ291bnRgYCBpbnN0ZWFkXG4gICAqL1xuICBwdWJsaWMgbWV0cmljSHR0cEZpeGVkUmVzcG9uc2VDb3VudChwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLm1ldHJpY3MuaHR0cEZpeGVkUmVzcG9uc2VDb3VudChwcm9wcyk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiByZWRpcmVjdCBhY3Rpb25zIHRoYXQgd2VyZSBzdWNjZXNzZnVsLlxuICAgKlxuICAgKiBAZGVmYXVsdCBTdW0gb3ZlciA1IG1pbnV0ZXNcbiAgICogQGRlcHJlY2F0ZWQgVXNlIGBgQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIubWV0cmljcy5odHRwUmVkaXJlY3RDb3VudGBgIGluc3RlYWRcbiAgICovXG4gIHB1YmxpYyBtZXRyaWNIdHRwUmVkaXJlY3RDb3VudChwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLm1ldHJpY3MuaHR0cFJlZGlyZWN0Q291bnQocHJvcHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgcmVkaXJlY3QgYWN0aW9ucyB0aGF0IGNvdWxkbid0IGJlIGNvbXBsZXRlZCBiZWNhdXNlIHRoZSBVUkxcbiAgICogaW4gdGhlIHJlc3BvbnNlIGxvY2F0aW9uIGhlYWRlciBpcyBsYXJnZXIgdGhhbiA4Sy5cbiAgICpcbiAgICogQGRlZmF1bHQgU3VtIG92ZXIgNSBtaW51dGVzXG4gICAqIEBkZXByZWNhdGVkIFVzZSBgYEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyLm1ldHJpY3MuaHR0cFJlZGlyZWN0VXJsTGltaXRFeGNlZWRlZENvdW50YGAgaW5zdGVhZFxuICAgKi9cbiAgcHVibGljIG1ldHJpY0h0dHBSZWRpcmVjdFVybExpbWl0RXhjZWVkZWRDb3VudChcbiAgICBwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyxcbiAgKSB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljcy5odHRwUmVkaXJlY3RVcmxMaW1pdEV4Y2VlZGVkQ291bnQocHJvcHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgSFRUUCAzeHgvNHh4LzV4eCBjb2RlcyB0aGF0IG9yaWdpbmF0ZSBmcm9tIHRoZSBsb2FkIGJhbGFuY2VyLlxuICAgKlxuICAgKiBUaGlzIGRvZXMgbm90IGluY2x1ZGUgYW55IHJlc3BvbnNlIGNvZGVzIGdlbmVyYXRlZCBieSB0aGUgdGFyZ2V0cy5cbiAgICpcbiAgICogQGRlZmF1bHQgU3VtIG92ZXIgNSBtaW51dGVzXG4gICAqIEBkZXByZWNhdGVkIFVzZSBgYEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyLm1ldHJpY3MuaHR0cENvZGVFbGJgYCBpbnN0ZWFkXG4gICAqL1xuICBwdWJsaWMgbWV0cmljSHR0cENvZGVFbGIoXG4gICAgY29kZTogSHR0cENvZGVFbGIsXG4gICAgcHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMsXG4gICkge1xuICAgIHJldHVybiB0aGlzLm1ldHJpY3MuaHR0cENvZGVFbGIoY29kZSwgcHJvcHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgSFRUUCAyeHgvM3h4LzR4eC81eHggcmVzcG9uc2UgY29kZXMgZ2VuZXJhdGVkIGJ5IGFsbCB0YXJnZXRzXG4gICAqIGluIHRoZSBsb2FkIGJhbGFuY2VyLlxuICAgKlxuICAgKiBUaGlzIGRvZXMgbm90IGluY2x1ZGUgYW55IHJlc3BvbnNlIGNvZGVzIGdlbmVyYXRlZCBieSB0aGUgbG9hZCBiYWxhbmNlci5cbiAgICpcbiAgICogQGRlZmF1bHQgU3VtIG92ZXIgNSBtaW51dGVzXG4gICAqIEBkZXByZWNhdGVkIFVzZSBgYEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyLm1ldHJpY3MuaHR0cENvZGVUYXJnZXRgYCBpbnN0ZWFkXG4gICAqL1xuICBwdWJsaWMgbWV0cmljSHR0cENvZGVUYXJnZXQoXG4gICAgY29kZTogSHR0cENvZGVUYXJnZXQsXG4gICAgcHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMsXG4gICkge1xuICAgIHJldHVybiB0aGlzLm1ldHJpY3MuaHR0cENvZGVUYXJnZXQoY29kZSwgcHJvcHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgcHJvY2Vzc2VkIGJ5IHRoZSBsb2FkIGJhbGFuY2VyIG92ZXIgSVB2Ni5cbiAgICpcbiAgICogQGRlZmF1bHQgU3VtIG92ZXIgNSBtaW51dGVzXG4gICAqIEBkZXByZWNhdGVkIFVzZSBgYEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyLm1ldHJpY3MuaXB2NlByb2Nlc3NlZEJ5dGVzYGAgaW5zdGVhZFxuICAgKi9cbiAgcHVibGljIG1ldHJpY0lwdjZQcm9jZXNzZWRCeXRlcyhwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLm1ldHJpY3MuaXB2NlByb2Nlc3NlZEJ5dGVzKHByb3BzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIElQdjYgcmVxdWVzdHMgcmVjZWl2ZWQgYnkgdGhlIGxvYWQgYmFsYW5jZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IFN1bSBvdmVyIDUgbWludXRlc1xuICAgKiBAZGVwcmVjYXRlZCBVc2UgYGBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlci5tZXRyaWNzLmlwdjZSZXF1ZXN0Q291bnRgYCBpbnN0ZWFkXG4gICAqL1xuICBwdWJsaWMgbWV0cmljSXB2NlJlcXVlc3RDb3VudChwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLm1ldHJpY3MuaXB2NlJlcXVlc3RDb3VudChwcm9wcyk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHRvdGFsIG51bWJlciBvZiBuZXcgVENQIGNvbm5lY3Rpb25zIGVzdGFibGlzaGVkIGZyb20gY2xpZW50cyB0byB0aGVcbiAgICogbG9hZCBiYWxhbmNlciBhbmQgZnJvbSB0aGUgbG9hZCBiYWxhbmNlciB0byB0YXJnZXRzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBTdW0gb3ZlciA1IG1pbnV0ZXNcbiAgICogQGRlcHJlY2F0ZWQgVXNlIGBgQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIubWV0cmljcy5uZXdDb25uZWN0aW9uQ291bnRgYCBpbnN0ZWFkXG4gICAqL1xuICBwdWJsaWMgbWV0cmljTmV3Q29ubmVjdGlvbkNvdW50KHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljcy5uZXdDb25uZWN0aW9uQ291bnQocHJvcHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgcHJvY2Vzc2VkIGJ5IHRoZSBsb2FkIGJhbGFuY2VyIG92ZXIgSVB2NCBhbmQgSVB2Ni5cbiAgICpcbiAgICogQGRlZmF1bHQgU3VtIG92ZXIgNSBtaW51dGVzXG4gICAqIEBkZXByZWNhdGVkIFVzZSBgYEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyLm1ldHJpY3MucHJvY2Vzc2VkQnl0ZXNgYCBpbnN0ZWFkXG4gICAqL1xuICBwdWJsaWMgbWV0cmljUHJvY2Vzc2VkQnl0ZXMocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWNzLnByb2Nlc3NlZEJ5dGVzKHByb3BzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIGNvbm5lY3Rpb25zIHRoYXQgd2VyZSByZWplY3RlZCBiZWNhdXNlIHRoZSBsb2FkIGJhbGFuY2VyIGhhZFxuICAgKiByZWFjaGVkIGl0cyBtYXhpbXVtIG51bWJlciBvZiBjb25uZWN0aW9ucy5cbiAgICpcbiAgICogQGRlZmF1bHQgU3VtIG92ZXIgNSBtaW51dGVzXG4gICAqIEBkZXByZWNhdGVkIFVzZSBgYEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyLm1ldHJpY3MucmVqZWN0ZWRDb25uZWN0aW9uQ291bnRgYCBpbnN0ZWFkXG4gICAqL1xuICBwdWJsaWMgbWV0cmljUmVqZWN0ZWRDb25uZWN0aW9uQ291bnQocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWNzLnJlamVjdGVkQ29ubmVjdGlvbkNvdW50KHByb3BzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIHJlcXVlc3RzIHByb2Nlc3NlZCBvdmVyIElQdjQgYW5kIElQdjYuXG4gICAqXG4gICAqIFRoaXMgY291bnQgaW5jbHVkZXMgb25seSB0aGUgcmVxdWVzdHMgd2l0aCBhIHJlc3BvbnNlIGdlbmVyYXRlZCBieSBhIHRhcmdldCBvZiB0aGUgbG9hZCBiYWxhbmNlci5cbiAgICpcbiAgICogQGRlZmF1bHQgU3VtIG92ZXIgNSBtaW51dGVzXG4gICAqIEBkZXByZWNhdGVkIFVzZSBgYEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyLm1ldHJpY3MucmVxdWVzdENvdW50YGAgaW5zdGVhZFxuICAgKi9cbiAgcHVibGljIG1ldHJpY1JlcXVlc3RDb3VudChwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLm1ldHJpY3MucmVxdWVzdENvdW50KHByb3BzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIHJ1bGVzIHByb2Nlc3NlZCBieSB0aGUgbG9hZCBiYWxhbmNlciBnaXZlbiBhIHJlcXVlc3QgcmF0ZSBhdmVyYWdlZCBvdmVyIGFuIGhvdXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IFN1bSBvdmVyIDUgbWludXRlc1xuICAgKiBAZGVwcmVjYXRlZCBVc2UgYGBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlci5tZXRyaWNzLnJ1bGVFdmFsdWF0aW9uc2BgIGluc3RlYWRcbiAgICovXG4gIHB1YmxpYyBtZXRyaWNSdWxlRXZhbHVhdGlvbnMocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWNzLnJ1bGVFdmFsdWF0aW9ucyhwcm9wcyk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBjb25uZWN0aW9ucyB0aGF0IHdlcmUgbm90IHN1Y2Nlc3NmdWxseSBlc3RhYmxpc2hlZCBiZXR3ZWVuIHRoZSBsb2FkIGJhbGFuY2VyIGFuZCB0YXJnZXQuXG4gICAqXG4gICAqIEBkZWZhdWx0IFN1bSBvdmVyIDUgbWludXRlc1xuICAgKiBAZGVwcmVjYXRlZCBVc2UgYGBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlci5tZXRyaWNzLnRhcmdldENvbm5lY3Rpb25FcnJvckNvdW50YGAgaW5zdGVhZFxuICAgKi9cbiAgcHVibGljIG1ldHJpY1RhcmdldENvbm5lY3Rpb25FcnJvckNvdW50KHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljcy50YXJnZXRDb25uZWN0aW9uRXJyb3JDb3VudChwcm9wcyk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHRpbWUgZWxhcHNlZCwgaW4gc2Vjb25kcywgYWZ0ZXIgdGhlIHJlcXVlc3QgbGVhdmVzIHRoZSBsb2FkIGJhbGFuY2VyIHVudGlsIGEgcmVzcG9uc2UgZnJvbSB0aGUgdGFyZ2V0IGlzIHJlY2VpdmVkLlxuICAgKlxuICAgKiBAZGVmYXVsdCBBdmVyYWdlIG92ZXIgNSBtaW51dGVzXG4gICAqIEBkZXByZWNhdGVkIFVzZSBgYEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyLm1ldHJpY3MudGFyZ2V0UmVzcG9uc2VUaW1lYGAgaW5zdGVhZFxuICAgKi9cbiAgcHVibGljIG1ldHJpY1RhcmdldFJlc3BvbnNlVGltZShwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLm1ldHJpY3MudGFyZ2V0UmVzcG9uc2VUaW1lKHByb3BzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIFRMUyBjb25uZWN0aW9ucyBpbml0aWF0ZWQgYnkgdGhlIGxvYWQgYmFsYW5jZXIgdGhhdCBkaWQgbm90IGVzdGFibGlzaCBhIHNlc3Npb24gd2l0aCB0aGUgdGFyZ2V0LlxuICAgKlxuICAgKiBQb3NzaWJsZSBjYXVzZXMgaW5jbHVkZSBhIG1pc21hdGNoIG9mIGNpcGhlcnMgb3IgcHJvdG9jb2xzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBTdW0gb3ZlciA1IG1pbnV0ZXNcbiAgICogQGRlcHJlY2F0ZWQgVXNlIGBgQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIubWV0cmljcy50YXJnZXRUTFNOZWdvdGlhdGlvbkVycm9yQ291bnRgYCBpbnN0ZWFkXG4gICAqL1xuICBwdWJsaWMgbWV0cmljVGFyZ2V0VExTTmVnb3RpYXRpb25FcnJvckNvdW50KFxuICAgIHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zLFxuICApIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWNzLnRhcmdldFRMU05lZ290aWF0aW9uRXJyb3JDb3VudChwcm9wcyk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiB1c2VyIGF1dGhlbnRpY2F0aW9ucyB0aGF0IGNvdWxkIG5vdCBiZSBjb21wbGV0ZWRcbiAgICpcbiAgICogQmVjYXVzZSBhbiBhdXRoZW50aWNhdGUgYWN0aW9uIHdhcyBtaXNjb25maWd1cmVkLCB0aGUgbG9hZCBiYWxhbmNlclxuICAgKiBjb3VsZG4ndCBlc3RhYmxpc2ggYSBjb25uZWN0aW9uIHdpdGggdGhlIElkUCwgb3IgdGhlIGxvYWQgYmFsYW5jZXJcbiAgICogY291bGRuJ3QgY29tcGxldGUgdGhlIGF1dGhlbnRpY2F0aW9uIGZsb3cgZHVlIHRvIGFuIGludGVybmFsIGVycm9yLlxuICAgKlxuICAgKiBAZGVmYXVsdCBTdW0gb3ZlciA1IG1pbnV0ZXNcbiAgICogQGRlcHJlY2F0ZWQgVXNlIGBgQXBwbGljYXRpb25Mb2FkQmFsYW5jZXIubWV0cmljcy5lbGJBdXRoRXJyb3JgYCBpbnN0ZWFkXG4gICAqL1xuICBwdWJsaWMgbWV0cmljRWxiQXV0aEVycm9yKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljcy5lbGJBdXRoRXJyb3IocHJvcHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgdXNlciBhdXRoZW50aWNhdGlvbnMgdGhhdCBjb3VsZCBub3QgYmUgY29tcGxldGVkIGJlY2F1c2UgdGhlXG4gICAqIElkUCBkZW5pZWQgYWNjZXNzIHRvIHRoZSB1c2VyIG9yIGFuIGF1dGhvcml6YXRpb24gY29kZSB3YXMgdXNlZCBtb3JlIHRoYW5cbiAgICogb25jZS5cbiAgICpcbiAgICogQGRlZmF1bHQgU3VtIG92ZXIgNSBtaW51dGVzXG4gICAqIEBkZXByZWNhdGVkIFVzZSBgYEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyLm1ldHJpY3MuZWxiQXV0aEZhaWx1cmVgYCBpbnN0ZWFkXG4gICAqL1xuICBwdWJsaWMgbWV0cmljRWxiQXV0aEZhaWx1cmUocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWNzLmVsYkF1dGhGYWlsdXJlKHByb3BzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgdGltZSBlbGFwc2VkLCBpbiBtaWxsaXNlY29uZHMsIHRvIHF1ZXJ5IHRoZSBJZFAgZm9yIHRoZSBJRCB0b2tlbiBhbmQgdXNlciBpbmZvLlxuICAgKlxuICAgKiBJZiBvbmUgb3IgbW9yZSBvZiB0aGVzZSBvcGVyYXRpb25zIGZhaWwsIHRoaXMgaXMgdGhlIHRpbWUgdG8gZmFpbHVyZS5cbiAgICpcbiAgICogQGRlZmF1bHQgQXZlcmFnZSBvdmVyIDUgbWludXRlc1xuICAgKiBAZGVwcmVjYXRlZCBVc2UgYGBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlci5tZXRyaWNzLmVsYkF1dGhMYXRlbmN5YGAgaW5zdGVhZFxuICAgKi9cbiAgcHVibGljIG1ldHJpY0VsYkF1dGhMYXRlbmN5KHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMubWV0cmljcy5lbGJBdXRoTGF0ZW5jeShwcm9wcyk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBhdXRoZW50aWNhdGUgYWN0aW9ucyB0aGF0IHdlcmUgc3VjY2Vzc2Z1bC5cbiAgICpcbiAgICogVGhpcyBtZXRyaWMgaXMgaW5jcmVtZW50ZWQgYXQgdGhlIGVuZCBvZiB0aGUgYXV0aGVudGljYXRpb24gd29ya2Zsb3csXG4gICAqIGFmdGVyIHRoZSBsb2FkIGJhbGFuY2VyIGhhcyByZXRyaWV2ZWQgdGhlIHVzZXIgY2xhaW1zIGZyb20gdGhlIElkUC5cbiAgICpcbiAgICogQGRlZmF1bHQgU3VtIG92ZXIgNSBtaW51dGVzXG4gICAqIEBkZXByZWNhdGVkIFVzZSBgYEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyLm1ldHJpY3MuZWxiQXV0aFN1Y2Nlc3NgYCBpbnN0ZWFkXG4gICAqXG4gICAqL1xuICBwdWJsaWMgbWV0cmljRWxiQXV0aFN1Y2Nlc3MocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5tZXRyaWNzLmVsYkF1dGhTdWNjZXNzKHByb3BzKTtcbiAgfVxufVxuXG5jbGFzcyBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY3NcbiAgaW1wbGVtZW50cyBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJNZXRyaWNzXG57XG4gIHByaXZhdGUgcmVhZG9ubHkgc2NvcGU6IENvbnN0cnVjdDtcbiAgcHJpdmF0ZSByZWFkb25seSBsb2FkQmFsYW5jZXJGdWxsTmFtZTogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGxvYWRCYWxhbmNlckZ1bGxOYW1lOiBzdHJpbmcpIHtcbiAgICB0aGlzLnNjb3BlID0gc2NvcGU7XG4gICAgdGhpcy5sb2FkQmFsYW5jZXJGdWxsTmFtZSA9IGxvYWRCYWxhbmNlckZ1bGxOYW1lO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgZ2l2ZW4gbmFtZWQgbWV0cmljIGZvciB0aGlzIEFwcGxpY2F0aW9uIExvYWQgQmFsYW5jZXJcbiAgICpcbiAgICogQGRlZmF1bHQgQXZlcmFnZSBvdmVyIDUgbWludXRlc1xuICAgKi9cbiAgcHVibGljIGN1c3RvbShcbiAgICBtZXRyaWNOYW1lOiBzdHJpbmcsXG4gICAgcHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMsXG4gICk6IGNsb3Vkd2F0Y2guTWV0cmljIHtcbiAgICByZXR1cm4gbmV3IGNsb3Vkd2F0Y2guTWV0cmljKHtcbiAgICAgIG5hbWVzcGFjZTogXCJBV1MvQXBwbGljYXRpb25FTEJcIixcbiAgICAgIG1ldHJpY05hbWUsXG4gICAgICBkaW1lbnNpb25zTWFwOiB7IExvYWRCYWxhbmNlcjogdGhpcy5sb2FkQmFsYW5jZXJGdWxsTmFtZSB9LFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYWN0aXZlQ29ubmVjdGlvbkNvdW50KHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FubmVkTWV0cmljKFxuICAgICAgQXBwbGljYXRpb25FTEJNZXRyaWNzLmFjdGl2ZUNvbm5lY3Rpb25Db3VudFN1bSxcbiAgICAgIHByb3BzLFxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgY2xpZW50VGxzTmVnb3RpYXRpb25FcnJvckNvdW50KHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FubmVkTWV0cmljKFxuICAgICAgQXBwbGljYXRpb25FTEJNZXRyaWNzLmNsaWVudFRsc05lZ290aWF0aW9uRXJyb3JDb3VudFN1bSxcbiAgICAgIHByb3BzLFxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgY29uc3VtZWRMQ1VzKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FubmVkTWV0cmljKEFwcGxpY2F0aW9uRUxCTWV0cmljcy5jb25zdW1lZExjVXNBdmVyYWdlLCB7XG4gICAgICBzdGF0aXN0aWM6IFwic3VtXCIsXG4gICAgICAuLi5wcm9wcyxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBodHRwRml4ZWRSZXNwb25zZUNvdW50KHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FubmVkTWV0cmljKFxuICAgICAgQXBwbGljYXRpb25FTEJNZXRyaWNzLmh0dHBGaXhlZFJlc3BvbnNlQ291bnRTdW0sXG4gICAgICBwcm9wcyxcbiAgICApO1xuICB9XG5cbiAgcHVibGljIGh0dHBSZWRpcmVjdENvdW50KHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FubmVkTWV0cmljKEFwcGxpY2F0aW9uRUxCTWV0cmljcy5odHRwUmVkaXJlY3RDb3VudFN1bSwgcHJvcHMpO1xuICB9XG5cbiAgcHVibGljIGh0dHBSZWRpcmVjdFVybExpbWl0RXhjZWVkZWRDb3VudChwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLmNhbm5lZE1ldHJpYyhcbiAgICAgIEFwcGxpY2F0aW9uRUxCTWV0cmljcy5odHRwUmVkaXJlY3RVcmxMaW1pdEV4Y2VlZGVkQ291bnRTdW0sXG4gICAgICBwcm9wcyxcbiAgICApO1xuICB9XG5cbiAgcHVibGljIGh0dHBDb2RlRWxiKGNvZGU6IEh0dHBDb2RlRWxiLCBwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLmN1c3RvbShjb2RlLCB7XG4gICAgICBzdGF0aXN0aWM6IFwiU3VtXCIsXG4gICAgICAuLi5wcm9wcyxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBodHRwQ29kZVRhcmdldChcbiAgICBjb2RlOiBIdHRwQ29kZVRhcmdldCxcbiAgICBwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyxcbiAgKSB7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tKGNvZGUsIHtcbiAgICAgIHN0YXRpc3RpYzogXCJTdW1cIixcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGlwdjZQcm9jZXNzZWRCeXRlcyhwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLmNhbm5lZE1ldHJpYyhcbiAgICAgIEFwcGxpY2F0aW9uRUxCTWV0cmljcy5pUHY2UHJvY2Vzc2VkQnl0ZXNTdW0sXG4gICAgICBwcm9wcyxcbiAgICApO1xuICB9XG5cbiAgcHVibGljIGlwdjZSZXF1ZXN0Q291bnQocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5jYW5uZWRNZXRyaWMoQXBwbGljYXRpb25FTEJNZXRyaWNzLmlQdjZSZXF1ZXN0Q291bnRTdW0sIHByb3BzKTtcbiAgfVxuXG4gIHB1YmxpYyBuZXdDb25uZWN0aW9uQ291bnQocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5jYW5uZWRNZXRyaWMoXG4gICAgICBBcHBsaWNhdGlvbkVMQk1ldHJpY3MubmV3Q29ubmVjdGlvbkNvdW50U3VtLFxuICAgICAgcHJvcHMsXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBwcm9jZXNzZWRCeXRlcyhwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLmNhbm5lZE1ldHJpYyhBcHBsaWNhdGlvbkVMQk1ldHJpY3MucHJvY2Vzc2VkQnl0ZXNTdW0sIHByb3BzKTtcbiAgfVxuXG4gIHB1YmxpYyByZWplY3RlZENvbm5lY3Rpb25Db3VudChwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucykge1xuICAgIHJldHVybiB0aGlzLmNhbm5lZE1ldHJpYyhcbiAgICAgIEFwcGxpY2F0aW9uRUxCTWV0cmljcy5yZWplY3RlZENvbm5lY3Rpb25Db3VudFN1bSxcbiAgICAgIHByb3BzLFxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgcmVxdWVzdENvdW50KHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FubmVkTWV0cmljKEFwcGxpY2F0aW9uRUxCTWV0cmljcy5yZXF1ZXN0Q291bnRTdW0sIHByb3BzKTtcbiAgfVxuXG4gIHB1YmxpYyBydWxlRXZhbHVhdGlvbnMocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5jYW5uZWRNZXRyaWMoQXBwbGljYXRpb25FTEJNZXRyaWNzLnJ1bGVFdmFsdWF0aW9uc1N1bSwgcHJvcHMpO1xuICB9XG5cbiAgcHVibGljIHRhcmdldENvbm5lY3Rpb25FcnJvckNvdW50KHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tKFwiVGFyZ2V0Q29ubmVjdGlvbkVycm9yQ291bnRcIiwge1xuICAgICAgc3RhdGlzdGljOiBcIlN1bVwiLFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgdGFyZ2V0UmVzcG9uc2VUaW1lKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tKFwiVGFyZ2V0UmVzcG9uc2VUaW1lXCIsIHtcbiAgICAgIHN0YXRpc3RpYzogXCJBdmVyYWdlXCIsXG4gICAgICAuLi5wcm9wcyxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyB0YXJnZXRUTFNOZWdvdGlhdGlvbkVycm9yQ291bnQocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5jdXN0b20oXCJUYXJnZXRUTFNOZWdvdGlhdGlvbkVycm9yQ291bnRcIiwge1xuICAgICAgc3RhdGlzdGljOiBcIlN1bVwiLFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZWxiQXV0aEVycm9yKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tKFwiRUxCQXV0aEVycm9yXCIsIHtcbiAgICAgIHN0YXRpc3RpYzogXCJTdW1cIixcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGVsYkF1dGhGYWlsdXJlKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKSB7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tKFwiRUxCQXV0aEZhaWx1cmVcIiwge1xuICAgICAgc3RhdGlzdGljOiBcIlN1bVwiLFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZWxiQXV0aExhdGVuY3kocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5jdXN0b20oXCJFTEJBdXRoTGF0ZW5jeVwiLCB7XG4gICAgICBzdGF0aXN0aWM6IFwiQXZlcmFnZVwiLFxuICAgICAgLi4ucHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZWxiQXV0aFN1Y2Nlc3MocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpIHtcbiAgICByZXR1cm4gdGhpcy5jdXN0b20oXCJFTEJBdXRoU3VjY2Vzc1wiLCB7XG4gICAgICBzdGF0aXN0aWM6IFwiU3VtXCIsXG4gICAgICAuLi5wcm9wcyxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY2FubmVkTWV0cmljKFxuICAgIGZuOiAoZGltczogeyBMb2FkQmFsYW5jZXI6IHN0cmluZyB9KSA9PiBjbG91ZHdhdGNoLk1ldHJpY1Byb3BzLFxuICAgIHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zLFxuICApOiBjbG91ZHdhdGNoLk1ldHJpYyB7XG4gICAgcmV0dXJuIG5ldyBjbG91ZHdhdGNoLk1ldHJpYyh7XG4gICAgICAuLi5mbih7IExvYWRCYWxhbmNlcjogdGhpcy5sb2FkQmFsYW5jZXJGdWxsTmFtZSB9KSxcbiAgICAgIC4uLnByb3BzLFxuICAgIH0pLmF0dGFjaFRvKHRoaXMuc2NvcGUpO1xuICB9XG59XG5cbi8qKlxuICogQ291bnQgb2YgSFRUUCBzdGF0dXMgb3JpZ2luYXRpbmcgZnJvbSB0aGUgbG9hZCBiYWxhbmNlclxuICpcbiAqIFRoaXMgY291bnQgZG9lcyBub3QgaW5jbHVkZSBhbnkgcmVzcG9uc2UgY29kZXMgZ2VuZXJhdGVkIGJ5IHRoZSB0YXJnZXRzLlxuICovXG5leHBvcnQgZW51bSBIdHRwQ29kZUVsYiB7XG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIEhUVFAgM1hYIHJlZGlyZWN0aW9uIGNvZGVzIHRoYXQgb3JpZ2luYXRlIGZyb20gdGhlIGxvYWQgYmFsYW5jZXIuXG4gICAqL1xuICBFTEJfM1hYX0NPVU5UID0gXCJIVFRQQ29kZV9FTEJfM1hYX0NvdW50XCIsXG5cbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgSFRUUCA0WFggY2xpZW50IGVycm9yIGNvZGVzIHRoYXQgb3JpZ2luYXRlIGZyb20gdGhlIGxvYWQgYmFsYW5jZXIuXG4gICAqXG4gICAqIENsaWVudCBlcnJvcnMgYXJlIGdlbmVyYXRlZCB3aGVuIHJlcXVlc3RzIGFyZSBtYWxmb3JtZWQgb3IgaW5jb21wbGV0ZS5cbiAgICogVGhlc2UgcmVxdWVzdHMgaGF2ZSBub3QgYmVlbiByZWNlaXZlZCBieSB0aGUgdGFyZ2V0LiBUaGlzIGNvdW50IGRvZXMgbm90XG4gICAqIGluY2x1ZGUgYW55IHJlc3BvbnNlIGNvZGVzIGdlbmVyYXRlZCBieSB0aGUgdGFyZ2V0cy5cbiAgICovXG4gIEVMQl80WFhfQ09VTlQgPSBcIkhUVFBDb2RlX0VMQl80WFhfQ291bnRcIixcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBIVFRQIDVYWCBzZXJ2ZXIgZXJyb3IgY29kZXMgdGhhdCBvcmlnaW5hdGUgZnJvbSB0aGUgbG9hZCBiYWxhbmNlci5cbiAgICovXG4gIEVMQl81WFhfQ09VTlQgPSBcIkhUVFBDb2RlX0VMQl81WFhfQ291bnRcIixcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBIVFRQIDUwMCBzZXJ2ZXIgZXJyb3IgY29kZXMgdGhhdCBvcmlnaW5hdGUgZnJvbSB0aGUgbG9hZCBiYWxhbmNlci5cbiAgICovXG4gIEVMQl81MDBfQ09VTlQgPSBcIkhUVFBDb2RlX0VMQl81MDBfQ291bnRcIixcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBIVFRQIDUwMiBzZXJ2ZXIgZXJyb3IgY29kZXMgdGhhdCBvcmlnaW5hdGUgZnJvbSB0aGUgbG9hZCBiYWxhbmNlci5cbiAgICovXG4gIEVMQl81MDJfQ09VTlQgPSBcIkhUVFBDb2RlX0VMQl81MDJfQ291bnRcIixcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBIVFRQIDUwMyBzZXJ2ZXIgZXJyb3IgY29kZXMgdGhhdCBvcmlnaW5hdGUgZnJvbSB0aGUgbG9hZCBiYWxhbmNlci5cbiAgICovXG4gIEVMQl81MDNfQ09VTlQgPSBcIkhUVFBDb2RlX0VMQl81MDNfQ291bnRcIixcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBIVFRQIDUwNCBzZXJ2ZXIgZXJyb3IgY29kZXMgdGhhdCBvcmlnaW5hdGUgZnJvbSB0aGUgbG9hZCBiYWxhbmNlci5cbiAgICovXG4gIEVMQl81MDRfQ09VTlQgPSBcIkhUVFBDb2RlX0VMQl81MDRfQ291bnRcIixcbn1cblxuLyoqXG4gKiBDb3VudCBvZiBIVFRQIHN0YXR1cyBvcmlnaW5hdGluZyBmcm9tIHRoZSB0YXJnZXRzXG4gKi9cbmV4cG9ydCBlbnVtIEh0dHBDb2RlVGFyZ2V0IHtcbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgMnh4IHJlc3BvbnNlIGNvZGVzIGZyb20gdGFyZ2V0c1xuICAgKi9cbiAgVEFSR0VUXzJYWF9DT1VOVCA9IFwiSFRUUENvZGVfVGFyZ2V0XzJYWF9Db3VudFwiLFxuXG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIDN4eCByZXNwb25zZSBjb2RlcyBmcm9tIHRhcmdldHNcbiAgICovXG4gIFRBUkdFVF8zWFhfQ09VTlQgPSBcIkhUVFBDb2RlX1RhcmdldF8zWFhfQ291bnRcIixcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiA0eHggcmVzcG9uc2UgY29kZXMgZnJvbSB0YXJnZXRzXG4gICAqL1xuICBUQVJHRVRfNFhYX0NPVU5UID0gXCJIVFRQQ29kZV9UYXJnZXRfNFhYX0NvdW50XCIsXG5cbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgNXh4IHJlc3BvbnNlIGNvZGVzIGZyb20gdGFyZ2V0c1xuICAgKi9cbiAgVEFSR0VUXzVYWF9DT1VOVCA9IFwiSFRUUENvZGVfVGFyZ2V0XzVYWF9Db3VudFwiLFxufVxuXG4vKipcbiAqIENvbnRhaW5zIGFsbCBtZXRyaWNzIGZvciBhbiBBcHBsaWNhdGlvbiBMb2FkIEJhbGFuY2VyLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY3Mge1xuICAvKipcbiAgICogUmV0dXJuIHRoZSBnaXZlbiBuYW1lZCBtZXRyaWMgZm9yIHRoaXMgQXBwbGljYXRpb24gTG9hZCBCYWxhbmNlclxuICAgKlxuICAgKiBAZGVmYXVsdCBBdmVyYWdlIG92ZXIgNSBtaW51dGVzXG4gICAqL1xuICBjdXN0b20oXG4gICAgbWV0cmljTmFtZTogc3RyaW5nLFxuICAgIHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zLFxuICApOiBjbG91ZHdhdGNoLk1ldHJpYztcblxuICAvKipcbiAgICogVGhlIHRvdGFsIG51bWJlciBvZiBjb25jdXJyZW50IFRDUCBjb25uZWN0aW9ucyBhY3RpdmUgZnJvbSBjbGllbnRzIHRvIHRoZVxuICAgKiBsb2FkIGJhbGFuY2VyIGFuZCBmcm9tIHRoZSBsb2FkIGJhbGFuY2VyIHRvIHRhcmdldHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IFN1bSBvdmVyIDUgbWludXRlc1xuICAgKi9cbiAgYWN0aXZlQ29ubmVjdGlvbkNvdW50KHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWM7XG5cbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgVExTIGNvbm5lY3Rpb25zIGluaXRpYXRlZCBieSB0aGUgY2xpZW50IHRoYXQgZGlkIG5vdFxuICAgKiBlc3RhYmxpc2ggYSBzZXNzaW9uIHdpdGggdGhlIGxvYWQgYmFsYW5jZXIuIFBvc3NpYmxlIGNhdXNlcyBpbmNsdWRlIGFcbiAgICogbWlzbWF0Y2ggb2YgY2lwaGVycyBvciBwcm90b2NvbHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IFN1bSBvdmVyIDUgbWludXRlc1xuICAgKi9cbiAgY2xpZW50VGxzTmVnb3RpYXRpb25FcnJvckNvdW50KFxuICAgIHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zLFxuICApOiBjbG91ZHdhdGNoLk1ldHJpYztcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBsb2FkIGJhbGFuY2VyIGNhcGFjaXR5IHVuaXRzIChMQ1UpIHVzZWQgYnkgeW91ciBsb2FkIGJhbGFuY2VyLlxuICAgKlxuICAgKiBAZGVmYXVsdCBTdW0gb3ZlciA1IG1pbnV0ZXNcbiAgICovXG4gIGNvbnN1bWVkTENVcyhwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljO1xuXG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIGZpeGVkLXJlc3BvbnNlIGFjdGlvbnMgdGhhdCB3ZXJlIHN1Y2Nlc3NmdWwuXG4gICAqXG4gICAqIEBkZWZhdWx0IFN1bSBvdmVyIDUgbWludXRlc1xuICAgKi9cbiAgaHR0cEZpeGVkUmVzcG9uc2VDb3VudChwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljO1xuXG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIHJlZGlyZWN0IGFjdGlvbnMgdGhhdCB3ZXJlIHN1Y2Nlc3NmdWwuXG4gICAqXG4gICAqIEBkZWZhdWx0IFN1bSBvdmVyIDUgbWludXRlc1xuICAgKi9cbiAgaHR0cFJlZGlyZWN0Q291bnQocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYztcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiByZWRpcmVjdCBhY3Rpb25zIHRoYXQgY291bGRuJ3QgYmUgY29tcGxldGVkIGJlY2F1c2UgdGhlIFVSTFxuICAgKiBpbiB0aGUgcmVzcG9uc2UgbG9jYXRpb24gaGVhZGVyIGlzIGxhcmdlciB0aGFuIDhLLlxuICAgKlxuICAgKiBAZGVmYXVsdCBTdW0gb3ZlciA1IG1pbnV0ZXNcbiAgICovXG4gIGh0dHBSZWRpcmVjdFVybExpbWl0RXhjZWVkZWRDb3VudChcbiAgICBwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyxcbiAgKTogY2xvdWR3YXRjaC5NZXRyaWM7XG5cbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgSFRUUCAzeHgvNHh4LzV4eCBjb2RlcyB0aGF0IG9yaWdpbmF0ZSBmcm9tIHRoZSBsb2FkIGJhbGFuY2VyLlxuICAgKlxuICAgKiBUaGlzIGRvZXMgbm90IGluY2x1ZGUgYW55IHJlc3BvbnNlIGNvZGVzIGdlbmVyYXRlZCBieSB0aGUgdGFyZ2V0cy5cbiAgICpcbiAgICogQGRlZmF1bHQgU3VtIG92ZXIgNSBtaW51dGVzXG4gICAqL1xuICBodHRwQ29kZUVsYihcbiAgICBjb2RlOiBIdHRwQ29kZUVsYixcbiAgICBwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyxcbiAgKTogY2xvdWR3YXRjaC5NZXRyaWM7XG5cbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgSFRUUCAyeHgvM3h4LzR4eC81eHggcmVzcG9uc2UgY29kZXMgZ2VuZXJhdGVkIGJ5IGFsbCB0YXJnZXRzXG4gICAqIGluIHRoZSBsb2FkIGJhbGFuY2VyLlxuICAgKlxuICAgKiBUaGlzIGRvZXMgbm90IGluY2x1ZGUgYW55IHJlc3BvbnNlIGNvZGVzIGdlbmVyYXRlZCBieSB0aGUgbG9hZCBiYWxhbmNlci5cbiAgICpcbiAgICogQGRlZmF1bHQgU3VtIG92ZXIgNSBtaW51dGVzXG4gICAqL1xuICBodHRwQ29kZVRhcmdldChcbiAgICBjb2RlOiBIdHRwQ29kZVRhcmdldCxcbiAgICBwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyxcbiAgKTogY2xvdWR3YXRjaC5NZXRyaWM7XG5cbiAgLyoqXG4gICAqIFRoZSB0b3RhbCBudW1iZXIgb2YgYnl0ZXMgcHJvY2Vzc2VkIGJ5IHRoZSBsb2FkIGJhbGFuY2VyIG92ZXIgSVB2Ni5cbiAgICpcbiAgICogQGRlZmF1bHQgU3VtIG92ZXIgNSBtaW51dGVzXG4gICAqL1xuICBpcHY2UHJvY2Vzc2VkQnl0ZXMocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYztcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBJUHY2IHJlcXVlc3RzIHJlY2VpdmVkIGJ5IHRoZSBsb2FkIGJhbGFuY2VyLlxuICAgKlxuICAgKiBAZGVmYXVsdCBTdW0gb3ZlciA1IG1pbnV0ZXNcbiAgICovXG4gIGlwdjZSZXF1ZXN0Q291bnQocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYztcblxuICAvKipcbiAgICogVGhlIHRvdGFsIG51bWJlciBvZiBuZXcgVENQIGNvbm5lY3Rpb25zIGVzdGFibGlzaGVkIGZyb20gY2xpZW50cyB0byB0aGVcbiAgICogbG9hZCBiYWxhbmNlciBhbmQgZnJvbSB0aGUgbG9hZCBiYWxhbmNlciB0byB0YXJnZXRzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBTdW0gb3ZlciA1IG1pbnV0ZXNcbiAgICovXG4gIG5ld0Nvbm5lY3Rpb25Db3VudChwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljO1xuXG4gIC8qKlxuICAgKiBUaGUgdG90YWwgbnVtYmVyIG9mIGJ5dGVzIHByb2Nlc3NlZCBieSB0aGUgbG9hZCBiYWxhbmNlciBvdmVyIElQdjQgYW5kIElQdjYuXG4gICAqXG4gICAqIEBkZWZhdWx0IFN1bSBvdmVyIDUgbWludXRlc1xuICAgKi9cbiAgcHJvY2Vzc2VkQnl0ZXMocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYztcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBjb25uZWN0aW9ucyB0aGF0IHdlcmUgcmVqZWN0ZWQgYmVjYXVzZSB0aGUgbG9hZCBiYWxhbmNlciBoYWRcbiAgICogcmVhY2hlZCBpdHMgbWF4aW11bSBudW1iZXIgb2YgY29ubmVjdGlvbnMuXG4gICAqXG4gICAqIEBkZWZhdWx0IFN1bSBvdmVyIDUgbWludXRlc1xuICAgKi9cbiAgcmVqZWN0ZWRDb25uZWN0aW9uQ291bnQocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYztcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiByZXF1ZXN0cyBwcm9jZXNzZWQgb3ZlciBJUHY0IGFuZCBJUHY2LlxuICAgKlxuICAgKiBUaGlzIGNvdW50IGluY2x1ZGVzIG9ubHkgdGhlIHJlcXVlc3RzIHdpdGggYSByZXNwb25zZSBnZW5lcmF0ZWQgYnkgYSB0YXJnZXQgb2YgdGhlIGxvYWQgYmFsYW5jZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IFN1bSBvdmVyIDUgbWludXRlc1xuICAgKi9cbiAgcmVxdWVzdENvdW50KHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWM7XG5cbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgcnVsZXMgcHJvY2Vzc2VkIGJ5IHRoZSBsb2FkIGJhbGFuY2VyIGdpdmVuIGEgcmVxdWVzdCByYXRlIGF2ZXJhZ2VkIG92ZXIgYW4gaG91ci5cbiAgICpcbiAgICogQGRlZmF1bHQgU3VtIG92ZXIgNSBtaW51dGVzXG4gICAqL1xuICBydWxlRXZhbHVhdGlvbnMocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYztcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiBjb25uZWN0aW9ucyB0aGF0IHdlcmUgbm90IHN1Y2Nlc3NmdWxseSBlc3RhYmxpc2hlZCBiZXR3ZWVuIHRoZSBsb2FkIGJhbGFuY2VyIGFuZCB0YXJnZXQuXG4gICAqXG4gICAqIEBkZWZhdWx0IFN1bSBvdmVyIDUgbWludXRlc1xuICAgKi9cbiAgdGFyZ2V0Q29ubmVjdGlvbkVycm9yQ291bnQoXG4gICAgcHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMsXG4gICk6IGNsb3Vkd2F0Y2guTWV0cmljO1xuXG4gIC8qKlxuICAgKiBUaGUgdGltZSBlbGFwc2VkLCBpbiBzZWNvbmRzLCBhZnRlciB0aGUgcmVxdWVzdCBsZWF2ZXMgdGhlIGxvYWQgYmFsYW5jZXIgdW50aWwgYSByZXNwb25zZSBmcm9tIHRoZSB0YXJnZXQgaXMgcmVjZWl2ZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IEF2ZXJhZ2Ugb3ZlciA1IG1pbnV0ZXNcbiAgICovXG4gIHRhcmdldFJlc3BvbnNlVGltZShwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljO1xuXG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIFRMUyBjb25uZWN0aW9ucyBpbml0aWF0ZWQgYnkgdGhlIGxvYWQgYmFsYW5jZXIgdGhhdCBkaWQgbm90IGVzdGFibGlzaCBhIHNlc3Npb24gd2l0aCB0aGUgdGFyZ2V0LlxuICAgKlxuICAgKiBQb3NzaWJsZSBjYXVzZXMgaW5jbHVkZSBhIG1pc21hdGNoIG9mIGNpcGhlcnMgb3IgcHJvdG9jb2xzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBTdW0gb3ZlciA1IG1pbnV0ZXNcbiAgICovXG4gIHRhcmdldFRMU05lZ290aWF0aW9uRXJyb3JDb3VudChcbiAgICBwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyxcbiAgKTogY2xvdWR3YXRjaC5NZXRyaWM7XG5cbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2YgdXNlciBhdXRoZW50aWNhdGlvbnMgdGhhdCBjb3VsZCBub3QgYmUgY29tcGxldGVkXG4gICAqXG4gICAqIEJlY2F1c2UgYW4gYXV0aGVudGljYXRlIGFjdGlvbiB3YXMgbWlzY29uZmlndXJlZCwgdGhlIGxvYWQgYmFsYW5jZXJcbiAgICogY291bGRuJ3QgZXN0YWJsaXNoIGEgY29ubmVjdGlvbiB3aXRoIHRoZSBJZFAsIG9yIHRoZSBsb2FkIGJhbGFuY2VyXG4gICAqIGNvdWxkbid0IGNvbXBsZXRlIHRoZSBhdXRoZW50aWNhdGlvbiBmbG93IGR1ZSB0byBhbiBpbnRlcm5hbCBlcnJvci5cbiAgICpcbiAgICogQGRlZmF1bHQgU3VtIG92ZXIgNSBtaW51dGVzXG4gICAqL1xuICBlbGJBdXRoRXJyb3IocHJvcHM/OiBjbG91ZHdhdGNoLk1ldHJpY09wdGlvbnMpOiBjbG91ZHdhdGNoLk1ldHJpYztcblxuICAvKipcbiAgICogVGhlIG51bWJlciBvZiB1c2VyIGF1dGhlbnRpY2F0aW9ucyB0aGF0IGNvdWxkIG5vdCBiZSBjb21wbGV0ZWQgYmVjYXVzZSB0aGVcbiAgICogSWRQIGRlbmllZCBhY2Nlc3MgdG8gdGhlIHVzZXIgb3IgYW4gYXV0aG9yaXphdGlvbiBjb2RlIHdhcyB1c2VkIG1vcmUgdGhhblxuICAgKiBvbmNlLlxuICAgKlxuICAgKiBAZGVmYXVsdCBTdW0gb3ZlciA1IG1pbnV0ZXNcbiAgICovXG4gIGVsYkF1dGhGYWlsdXJlKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWM7XG5cbiAgLyoqXG4gICAqIFRoZSB0aW1lIGVsYXBzZWQsIGluIG1pbGxpc2Vjb25kcywgdG8gcXVlcnkgdGhlIElkUCBmb3IgdGhlIElEIHRva2VuIGFuZCB1c2VyIGluZm8uXG4gICAqXG4gICAqIElmIG9uZSBvciBtb3JlIG9mIHRoZXNlIG9wZXJhdGlvbnMgZmFpbCwgdGhpcyBpcyB0aGUgdGltZSB0byBmYWlsdXJlLlxuICAgKlxuICAgKiBAZGVmYXVsdCBBdmVyYWdlIG92ZXIgNSBtaW51dGVzXG4gICAqL1xuICBlbGJBdXRoTGF0ZW5jeShwcm9wcz86IGNsb3Vkd2F0Y2guTWV0cmljT3B0aW9ucyk6IGNsb3Vkd2F0Y2guTWV0cmljO1xuXG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIGF1dGhlbnRpY2F0ZSBhY3Rpb25zIHRoYXQgd2VyZSBzdWNjZXNzZnVsLlxuICAgKlxuICAgKiBUaGlzIG1ldHJpYyBpcyBpbmNyZW1lbnRlZCBhdCB0aGUgZW5kIG9mIHRoZSBhdXRoZW50aWNhdGlvbiB3b3JrZmxvdyxcbiAgICogYWZ0ZXIgdGhlIGxvYWQgYmFsYW5jZXIgaGFzIHJldHJpZXZlZCB0aGUgdXNlciBjbGFpbXMgZnJvbSB0aGUgSWRQLlxuICAgKlxuICAgKiBAZGVmYXVsdCBTdW0gb3ZlciA1IG1pbnV0ZXNcbiAgICovXG4gIGVsYkF1dGhTdWNjZXNzKHByb3BzPzogY2xvdWR3YXRjaC5NZXRyaWNPcHRpb25zKTogY2xvdWR3YXRjaC5NZXRyaWM7XG59XG5cbi8qKlxuICogQW4gYXBwbGljYXRpb24gbG9hZCBiYWxhbmNlclxuICovXG5leHBvcnQgaW50ZXJmYWNlIElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlclxuICBleHRlbmRzIElMb2FkQmFsYW5jZXJWMixcbiAgICBJQ29ubmVjdGFibGUge1xuICAvKipcbiAgICogVGhlIEFSTiBvZiB0aGlzIGxvYWQgYmFsYW5jZXJcbiAgICovXG4gIHJlYWRvbmx5IGxvYWRCYWxhbmNlckFybjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgVlBDIHRoaXMgbG9hZCBiYWxhbmNlciBoYXMgYmVlbiBjcmVhdGVkIGluIChpZiBhdmFpbGFibGUpLlxuICAgKiBJZiB0aGlzIGludGVyZmFjZSBpcyB0aGUgcmVzdWx0IG9mIGFuIGltcG9ydCBjYWxsIHRvIGZyb21BcHBsaWNhdGlvbkxvYWRCYWxhbmNlckF0dHJpYnV0ZXMsXG4gICAqIHRoZSB2cGMgYXR0cmlidXRlIHdpbGwgYmUgdW5kZWZpbmVkIHVubGVzcyBzcGVjaWZpZWQgaW4gdGhlIG9wdGlvbmFsIHByb3BlcnRpZXMgb2YgdGhhdCBtZXRob2QuXG4gICAqL1xuICByZWFkb25seSB2cGM/OiBJVnBjO1xuXG4gIC8qKlxuICAgKiBUaGUgSVAgQWRkcmVzcyBUeXBlIGZvciB0aGlzIGxvYWQgYmFsYW5jZXJcbiAgICpcbiAgICogSWYgdGhlIGBAYXdzLWNkay9hd3MtZWxhc3RpY2xvYWRiYWxhbmNpbmdWMjphbGJEdWFsc3RhY2tXaXRob3V0UHVibGljSXB2NFNlY3VyaXR5R3JvdXBSdWxlc0RlZmF1bHRgXG4gICAqIGZlYXR1cmUgZmxhZyBpcyBzZXQgKHRoZSBkZWZhdWx0IGZvciBuZXcgcHJvamVjdHMpLCBhbmQgYGFkZExpc3RlbmVyKClgIGlzIGNhbGxlZCB3aXRoIGBvcGVuOiB0cnVlYCxcbiAgICogdGhlIGxvYWQgYmFsYW5jZXIncyBzZWN1cml0eSBncm91cCB3aWxsIGF1dG9tYXRpY2FsbHkgaW5jbHVkZSBib3RoIElQdjQgYW5kIElQdjYgaW5ncmVzcyBydWxlc1xuICAgKiB3aGVuIHVzaW5nIGBJcEFkZHJlc3NUeXBlLkRVQUxfU1RBQ0tfV0lUSE9VVF9QVUJMSUNfSVBWNGAuXG4gICAqXG4gICAqIEZvciBleGlzdGluZyBwcm9qZWN0cyB0aGF0IG9ubHkgaGF2ZSBJUHY0IHJ1bGVzLCB5b3UgY2FuIG9wdC1pbiB0byBJUHY2IGluZ3Jlc3MgcnVsZXNcbiAgICogYnkgZW5hYmxpbmcgdGhlIGZlYXR1cmUgZmxhZyBpbiB5b3VyIGNkay5qc29uIGZpbGUuIE5vdGUgdGhhdCBlbmFibGluZyB0aGlzIGZlYXR1cmUgZmxhZ1xuICAgKiB3aWxsIG1vZGlmeSBleGlzdGluZyBzZWN1cml0eSBncm91cCBydWxlcy5cbiAgICpcbiAgICogQGRlZmF1bHQgSXBBZGRyZXNzVHlwZS5JUFY0XG4gICAqL1xuICByZWFkb25seSBpcEFkZHJlc3NUeXBlPzogSXBBZGRyZXNzVHlwZTtcblxuICAvKipcbiAgICogQSBsaXN0IG9mIGxpc3RlbmVycyB0aGF0IGhhdmUgYmVlbiBhZGRlZCB0byB0aGUgbG9hZCBiYWxhbmNlci5cbiAgICogVGhpcyBsaXN0IGlzIG9ubHkgdmFsaWQgZm9yIG93bmVkIGNvbnN0cnVjdHMuXG4gICAqL1xuICByZWFkb25seSBsaXN0ZW5lcnM6IEFwcGxpY2F0aW9uTGlzdGVuZXJbXTtcblxuICAvKipcbiAgICogQWxsIG1ldHJpY3MgYXZhaWxhYmxlIGZvciB0aGlzIGxvYWQgYmFsYW5jZXJcbiAgICovXG4gIHJlYWRvbmx5IG1ldHJpY3M6IElBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY3M7XG5cbiAgLyoqXG4gICAqIEFkZCBhIG5ldyBsaXN0ZW5lciB0byB0aGlzIGxvYWQgYmFsYW5jZXJcbiAgICovXG4gIGFkZExpc3RlbmVyKFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcHJvcHM6IEJhc2VBcHBsaWNhdGlvbkxpc3RlbmVyUHJvcHMsXG4gICk6IEFwcGxpY2F0aW9uTGlzdGVuZXI7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyB0byByZWZlcmVuY2UgYW4gZXhpc3RpbmcgbG9hZCBiYWxhbmNlclxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyQXR0cmlidXRlcyB7XG4gIC8qKlxuICAgKiBBUk4gb2YgdGhlIGxvYWQgYmFsYW5jZXJcbiAgICovXG4gIHJlYWRvbmx5IGxvYWRCYWxhbmNlckFybjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBJRCBvZiB0aGUgbG9hZCBiYWxhbmNlcidzIHNlY3VyaXR5IGdyb3VwXG4gICAqL1xuICByZWFkb25seSBzZWN1cml0eUdyb3VwSWQ6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGNhbm9uaWNhbCBob3N0ZWQgem9uZSBJRCBvZiB0aGlzIGxvYWQgYmFsYW5jZXJcbiAgICpcbiAgICogQGRlZmF1bHQgLSBXaGVuIG5vdCBwcm92aWRlZCwgTEIgY2Fubm90IGJlIHVzZWQgYXMgUm91dGU1MyBBbGlhcyB0YXJnZXQuXG4gICAqL1xuICByZWFkb25seSBsb2FkQmFsYW5jZXJDYW5vbmljYWxIb3N0ZWRab25lSWQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBETlMgbmFtZSBvZiB0aGlzIGxvYWQgYmFsYW5jZXJcbiAgICpcbiAgICogQGRlZmF1bHQgLSBXaGVuIG5vdCBwcm92aWRlZCwgTEIgY2Fubm90IGJlIHVzZWQgYXMgUm91dGU1MyBBbGlhcyB0YXJnZXQuXG4gICAqL1xuICByZWFkb25seSBsb2FkQmFsYW5jZXJEbnNOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBzZWN1cml0eSBncm91cCBhbGxvd3MgYWxsIG91dGJvdW5kIHRyYWZmaWMgb3Igbm90XG4gICAqXG4gICAqIFVubGVzcyBzZXQgdG8gYGZhbHNlYCwgbm8gZWdyZXNzIHJ1bGVzIHdpbGwgYmUgYWRkZWQgdG8gdGhlIHNlY3VyaXR5IGdyb3VwLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBzZWN1cml0eUdyb3VwQWxsb3dzQWxsT3V0Ym91bmQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgVlBDIHRoaXMgbG9hZCBiYWxhbmNlciBoYXMgYmVlbiBjcmVhdGVkIGluLCBpZiBhdmFpbGFibGVcbiAgICpcbiAgICogQGRlZmF1bHQgLSBJZiB0aGUgTG9hZCBCYWxhbmNlciB3YXMgaW1wb3J0ZWQgYW5kIGEgVlBDIHdhcyBub3Qgc3BlY2lmaWVkLFxuICAgKiB0aGUgVlBDIGlzIG5vdCBhdmFpbGFibGUuXG4gICAqL1xuICByZWFkb25seSB2cGM/OiBJVnBjO1xufVxuXG4vKipcbiAqIEFuIEFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyIHRoYXQgaGFzIGJlZW4gZGVmaW5lZCBlbHNld2hlcmVcbiAqL1xuY2xhc3MgSW1wb3J0ZWRBcHBsaWNhdGlvbkxvYWRCYWxhbmNlclxuICBleHRlbmRzIEF3c0NvbnN0cnVjdEJhc2VcbiAgaW1wbGVtZW50cyBJQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJcbntcbiAgcHVibGljIGdldCBsb2FkQmFsYW5jZXJWMk91dHB1dHMoKTogTG9hZEJhbGFuY2VyVjJPdXRwdXRzIHtcbiAgICByZXR1cm4ge1xuICAgICAgbG9hZEJhbGFuY2VyQ2Fub25pY2FsSG9zdGVkWm9uZUlkOiB0aGlzLmxvYWRCYWxhbmNlckNhbm9uaWNhbEhvc3RlZFpvbmVJZCxcbiAgICAgIGxvYWRCYWxhbmNlckRuc05hbWU6IHRoaXMubG9hZEJhbGFuY2VyRG5zTmFtZSxcbiAgICB9O1xuICB9XG4gIHB1YmxpYyBnZXQgb3V0cHV0cygpOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcbiAgICByZXR1cm4gdGhpcy5sb2FkQmFsYW5jZXJWMk91dHB1dHM7XG4gIH1cbiAgLyoqXG4gICAqIE1hbmFnZSBjb25uZWN0aW9ucyBmb3IgdGhpcyBsb2FkIGJhbGFuY2VyXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgY29ubmVjdGlvbnM6IENvbm5lY3Rpb25zO1xuXG4gIC8qKlxuICAgKiBBUk4gb2YgdGhlIGxvYWQgYmFsYW5jZXJcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBsb2FkQmFsYW5jZXJBcm46IHN0cmluZztcblxuICBwdWJsaWMgZ2V0IGxpc3RlbmVycygpOiBBcHBsaWNhdGlvbkxpc3RlbmVyW10ge1xuICAgIHRocm93IEVycm9yKFxuICAgICAgXCIubGlzdGVuZXJzIGNhbiBvbmx5IGJlIGFjY2Vzc2VkIGlmIHRoZSBjbGFzcyB3YXMgY29uc3RydWN0ZWQgYXMgYW4gb3duZWQsIG5vdCBpbXBvcnRlZCwgbG9hZCBiYWxhbmNlclwiLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogVlBDIG9mIHRoZSBsb2FkIGJhbGFuY2VyXG4gICAqXG4gICAqIFVuZGVmaW5lZCBpZiBvcHRpb25hbCB2cGMgaXMgbm90IHNwZWNpZmllZC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSB2cGM/OiBJVnBjO1xuICBwdWJsaWMgcmVhZG9ubHkgbWV0cmljczogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTWV0cmljcztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBzY29wZTogQ29uc3RydWN0LFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcHJpdmF0ZSByZWFkb25seSBwcm9wczogQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJBdHRyaWJ1dGVzLFxuICApIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIGVudmlyb25tZW50RnJvbUFybjogcHJvcHMubG9hZEJhbGFuY2VyQXJuLFxuICAgIH0pO1xuXG4gICAgdGhpcy52cGMgPSBwcm9wcy52cGM7XG4gICAgdGhpcy5sb2FkQmFsYW5jZXJBcm4gPSBwcm9wcy5sb2FkQmFsYW5jZXJBcm47XG4gICAgdGhpcy5jb25uZWN0aW9ucyA9IG5ldyBDb25uZWN0aW9ucyh7XG4gICAgICBzZWN1cml0eUdyb3VwczogW1xuICAgICAgICBTZWN1cml0eUdyb3VwLmZyb21TZWN1cml0eUdyb3VwSWQoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBcIlNlY3VyaXR5R3JvdXBcIixcbiAgICAgICAgICBwcm9wcy5zZWN1cml0eUdyb3VwSWQsXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWxsb3dBbGxPdXRib3VuZDogcHJvcHMuc2VjdXJpdHlHcm91cEFsbG93c0FsbE91dGJvdW5kLFxuICAgICAgICAgIH0sXG4gICAgICAgICksXG4gICAgICBdLFxuICAgIH0pO1xuICAgIHRoaXMubWV0cmljcyA9IG5ldyBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY3MoXG4gICAgICB0aGlzLFxuICAgICAgcGFyc2VMb2FkQmFsYW5jZXJGdWxsTmFtZShwcm9wcy5sb2FkQmFsYW5jZXJBcm4pLFxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgYWRkTGlzdGVuZXIoXG4gICAgaWQ6IHN0cmluZyxcbiAgICBwcm9wczogQmFzZUFwcGxpY2F0aW9uTGlzdGVuZXJQcm9wcyxcbiAgKTogQXBwbGljYXRpb25MaXN0ZW5lciB7XG4gICAgcmV0dXJuIG5ldyBBcHBsaWNhdGlvbkxpc3RlbmVyKHRoaXMsIGlkLCB7XG4gICAgICBsb2FkQmFsYW5jZXI6IHRoaXMsXG4gICAgICAuLi5wcm9wcyxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgbG9hZEJhbGFuY2VyQ2Fub25pY2FsSG9zdGVkWm9uZUlkKCk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMucHJvcHMubG9hZEJhbGFuY2VyQ2Fub25pY2FsSG9zdGVkWm9uZUlkKSB7XG4gICAgICByZXR1cm4gdGhpcy5wcm9wcy5sb2FkQmFsYW5jZXJDYW5vbmljYWxIb3N0ZWRab25lSWQ7XG4gICAgfVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYCdsb2FkQmFsYW5jZXJDYW5vbmljYWxIb3N0ZWRab25lSWQnIHdhcyBub3QgcHJvdmlkZWQgd2hlbiBjb25zdHJ1Y3RpbmcgQXBwbGljYXRpb24gTG9hZCBCYWxhbmNlciAke3RoaXMubm9kZS5wYXRofSBmcm9tIGF0dHJpYnV0ZXNgLFxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGxvYWRCYWxhbmNlckRuc05hbWUoKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy5wcm9wcy5sb2FkQmFsYW5jZXJEbnNOYW1lKSB7XG4gICAgICByZXR1cm4gdGhpcy5wcm9wcy5sb2FkQmFsYW5jZXJEbnNOYW1lO1xuICAgIH1cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGAnbG9hZEJhbGFuY2VyRG5zTmFtZScgd2FzIG5vdCBwcm92aWRlZCB3aGVuIGNvbnN0cnVjdGluZyBBcHBsaWNhdGlvbiBMb2FkIEJhbGFuY2VyICR7dGhpcy5ub2RlLnBhdGh9IGZyb20gYXR0cmlidXRlc2AsXG4gICAgKTtcbiAgfVxufVxuLy8gVE9ETzogQWRkIEdyaWQgTG9va3VwIHN1cHBvcnRcbi8vIGNsYXNzIExvb2tlZFVwQXBwbGljYXRpb25Mb2FkQmFsYW5jZXJcbi8vICAgZXh0ZW5kcyBBd3NDb25zdHJ1Y3RCYXNlXG4vLyAgIGltcGxlbWVudHMgSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyXG4vLyB7XG4vLyAgIHB1YmxpYyByZWFkb25seSBsb2FkQmFsYW5jZXJBcm46IHN0cmluZztcbi8vICAgcHVibGljIHJlYWRvbmx5IGxvYWRCYWxhbmNlckNhbm9uaWNhbEhvc3RlZFpvbmVJZDogc3RyaW5nO1xuLy8gICBwdWJsaWMgcmVhZG9ubHkgbG9hZEJhbGFuY2VyRG5zTmFtZTogc3RyaW5nO1xuLy8gICBwdWJsaWMgcmVhZG9ubHkgaXBBZGRyZXNzVHlwZT86IElwQWRkcmVzc1R5cGU7XG4vLyAgIHB1YmxpYyByZWFkb25seSBjb25uZWN0aW9uczogQ29ubmVjdGlvbnM7XG4vLyAgIHB1YmxpYyByZWFkb25seSB2cGM/OiBJVnBjO1xuLy8gICBwdWJsaWMgcmVhZG9ubHkgbWV0cmljczogSUFwcGxpY2F0aW9uTG9hZEJhbGFuY2VyTWV0cmljcztcblxuLy8gICBwdWJsaWMgZ2V0IGxpc3RlbmVycygpOiBBcHBsaWNhdGlvbkxpc3RlbmVyW10ge1xuLy8gICAgIHRocm93IEVycm9yKFxuLy8gICAgICAgXCIubGlzdGVuZXJzIGNhbiBvbmx5IGJlIGFjY2Vzc2VkIGlmIHRoZSBjbGFzcyB3YXMgY29uc3RydWN0ZWQgYXMgYW4gb3duZWQsIG5vdCBsb29rZWQgdXAsIGxvYWQgYmFsYW5jZXJcIixcbi8vICAgICApO1xuLy8gICB9XG5cbi8vICAgY29uc3RydWN0b3IoXG4vLyAgICAgc2NvcGU6IENvbnN0cnVjdCxcbi8vICAgICBpZDogc3RyaW5nLFxuLy8gICAgIHByb3BzOiBjeGFwaS5Mb2FkQmFsYW5jZXJDb250ZXh0UmVzcG9uc2UsXG4vLyAgICkge1xuLy8gICAgIHN1cGVyKHNjb3BlLCBpZCwge1xuLy8gICAgICAgZW52aXJvbm1lbnRGcm9tQXJuOiBwcm9wcy5sb2FkQmFsYW5jZXJBcm4sXG4vLyAgICAgfSk7XG5cbi8vICAgICB0aGlzLmxvYWRCYWxhbmNlckFybiA9IHByb3BzLmxvYWRCYWxhbmNlckFybjtcbi8vICAgICB0aGlzLmxvYWRCYWxhbmNlckNhbm9uaWNhbEhvc3RlZFpvbmVJZCA9XG4vLyAgICAgICBwcm9wcy5sb2FkQmFsYW5jZXJDYW5vbmljYWxIb3N0ZWRab25lSWQ7XG4vLyAgICAgdGhpcy5sb2FkQmFsYW5jZXJEbnNOYW1lID0gcHJvcHMubG9hZEJhbGFuY2VyRG5zTmFtZTtcblxuLy8gICAgIGlmIChwcm9wcy5pcEFkZHJlc3NUeXBlID09PSBjeGFwaS5Mb2FkQmFsYW5jZXJJcEFkZHJlc3NUeXBlLklQVjQpIHtcbi8vICAgICAgIHRoaXMuaXBBZGRyZXNzVHlwZSA9IElwQWRkcmVzc1R5cGUuSVBWNDtcbi8vICAgICB9IGVsc2UgaWYgKFxuLy8gICAgICAgcHJvcHMuaXBBZGRyZXNzVHlwZSA9PT0gY3hhcGkuTG9hZEJhbGFuY2VySXBBZGRyZXNzVHlwZS5EVUFMX1NUQUNLXG4vLyAgICAgKSB7XG4vLyAgICAgICB0aGlzLmlwQWRkcmVzc1R5cGUgPSBJcEFkZHJlc3NUeXBlLkRVQUxfU1RBQ0s7XG4vLyAgICAgfSBlbHNlIGlmIChcbi8vICAgICAgIHByb3BzLmlwQWRkcmVzc1R5cGUgPT09XG4vLyAgICAgICBjeGFwaS5Mb2FkQmFsYW5jZXJJcEFkZHJlc3NUeXBlLkRVQUxfU1RBQ0tfV0lUSE9VVF9QVUJMSUNfSVBWNFxuLy8gICAgICkge1xuLy8gICAgICAgdGhpcy5pcEFkZHJlc3NUeXBlID0gSXBBZGRyZXNzVHlwZS5EVUFMX1NUQUNLX1dJVEhPVVRfUFVCTElDX0lQVjQ7XG4vLyAgICAgfVxuXG4vLyAgICAgdGhpcy52cGMgPSBWcGMuZnJvbUxvb2t1cCh0aGlzLCBcIlZwY1wiLCB7XG4vLyAgICAgICB2cGNJZDogcHJvcHMudnBjSWQsXG4vLyAgICAgfSk7XG5cbi8vICAgICB0aGlzLmNvbm5lY3Rpb25zID0gbmV3IENvbm5lY3Rpb25zKCk7XG4vLyAgICAgZm9yIChjb25zdCBzZWN1cml0eUdyb3VwSWQgb2YgcHJvcHMuc2VjdXJpdHlHcm91cElkcykge1xuLy8gICAgICAgY29uc3Qgc2VjdXJpdHlHcm91cCA9IFNlY3VyaXR5R3JvdXAuZnJvbUxvb2t1cEJ5SWQoXG4vLyAgICAgICAgIHRoaXMsXG4vLyAgICAgICAgIGBTZWN1cml0eUdyb3VwLSR7c2VjdXJpdHlHcm91cElkfWAsXG4vLyAgICAgICAgIHNlY3VyaXR5R3JvdXBJZCxcbi8vICAgICAgICk7XG4vLyAgICAgICB0aGlzLmNvbm5lY3Rpb25zLmFkZFNlY3VyaXR5R3JvdXAoc2VjdXJpdHlHcm91cCk7XG4vLyAgICAgfVxuLy8gICAgIHRoaXMubWV0cmljcyA9IG5ldyBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlck1ldHJpY3MoXG4vLyAgICAgICB0aGlzLFxuLy8gICAgICAgcGFyc2VMb2FkQmFsYW5jZXJGdWxsTmFtZSh0aGlzLmxvYWRCYWxhbmNlckFybiksXG4vLyAgICAgKTtcbi8vICAgfVxuXG4vLyAgIHB1YmxpYyBhZGRMaXN0ZW5lcihcbi8vICAgICBpZDogc3RyaW5nLFxuLy8gICAgIHByb3BzOiBCYXNlQXBwbGljYXRpb25MaXN0ZW5lclByb3BzLFxuLy8gICApOiBBcHBsaWNhdGlvbkxpc3RlbmVyIHtcbi8vICAgICByZXR1cm4gbmV3IEFwcGxpY2F0aW9uTGlzdGVuZXIodGhpcywgaWQsIHtcbi8vICAgICAgIC4uLnByb3BzLFxuLy8gICAgICAgbG9hZEJhbGFuY2VyOiB0aGlzLFxuLy8gICAgIH0pO1xuLy8gICB9XG4vLyB9XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgYSByZWRpcmVjdGlvbiBjb25maWdcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBcHBsaWNhdGlvbkxvYWRCYWxhbmNlclJlZGlyZWN0Q29uZmlnIHtcbiAgLyoqXG4gICAqIFRoZSBwcm90b2NvbCBvZiB0aGUgbGlzdGVuZXIgYmVpbmcgY3JlYXRlZFxuICAgKlxuICAgKiBAZGVmYXVsdCBIVFRQXG4gICAqL1xuICByZWFkb25seSBzb3VyY2VQcm90b2NvbD86IEFwcGxpY2F0aW9uUHJvdG9jb2w7XG5cbiAgLyoqXG4gICAqIFRoZSBwb3J0IG51bWJlciB0byBsaXN0ZW4gdG9cbiAgICpcbiAgICogQGRlZmF1bHQgODBcbiAgICovXG4gIHJlYWRvbmx5IHNvdXJjZVBvcnQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBwcm90b2NvbCBvZiB0aGUgcmVkaXJlY3Rpb24gdGFyZ2V0XG4gICAqXG4gICAqIEBkZWZhdWx0IEhUVFBTXG4gICAqL1xuICByZWFkb25seSB0YXJnZXRQcm90b2NvbD86IEFwcGxpY2F0aW9uUHJvdG9jb2w7XG5cbiAgLyoqXG4gICAqIFRoZSBwb3J0IG51bWJlciB0byByZWRpcmVjdCB0b1xuICAgKlxuICAgKiBAZGVmYXVsdCA0NDNcbiAgICovXG4gIHJlYWRvbmx5IHRhcmdldFBvcnQ/OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEFsbG93IGFueW9uZSB0byBjb25uZWN0IHRvIHRoaXMgbGlzdGVuZXJcbiAgICpcbiAgICogSWYgdGhpcyBpcyBzcGVjaWZpZWQsIHRoZSBsaXN0ZW5lciB3aWxsIGJlIG9wZW5lZCB1cCB0byBhbnlvbmUgd2hvIGNhbiByZWFjaCBpdC5cbiAgICogRm9yIGludGVybmFsIGxvYWQgYmFsYW5jZXJzIHRoaXMgaXMgYW55b25lIGluIHRoZSBzYW1lIFZQQy4gRm9yIHB1YmxpYyBsb2FkXG4gICAqIGJhbGFuY2VycywgdGhpcyBpcyBhbnlvbmUgb24gdGhlIGludGVybmV0LlxuICAgKlxuICAgKiBJZiB5b3Ugd2FudCB0byBiZSBtb3JlIHNlbGVjdGl2ZSBhYm91dCB3aG8gY2FuIGFjY2VzcyB0aGlzIGxvYWRcbiAgICogYmFsYW5jZXIsIHNldCB0aGlzIHRvIGBmYWxzZWAgYW5kIHVzZSB0aGUgbGlzdGVuZXIncyBgY29ubmVjdGlvbnNgXG4gICAqIG9iamVjdCB0byBzZWxlY3RpdmVseSBncmFudCBhY2Nlc3MgdG8gdGhlIGxpc3RlbmVyLlxuICAgKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBvcGVuPzogYm9vbGVhbjtcbn1cbiJdfQ==