@nlabs/reaktor 0.10.5 → 0.10.7

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 (535) hide show
  1. package/lib/actions/apps.d.ts +1 -0
  2. package/lib/actions/apps.d.ts.map +1 -0
  3. package/lib/actions/apps.js +221 -0
  4. package/lib/actions/connections.d.ts +1 -0
  5. package/lib/actions/connections.d.ts.map +1 -0
  6. package/lib/actions/connections.js +62 -0
  7. package/lib/actions/content.d.ts +1 -0
  8. package/lib/actions/content.d.ts.map +1 -0
  9. package/lib/actions/content.js +240 -0
  10. package/lib/actions/conversations.d.ts +1 -0
  11. package/lib/actions/conversations.d.ts.map +1 -0
  12. package/lib/actions/conversations.js +335 -0
  13. package/lib/actions/dynamodb.d.ts +1 -0
  14. package/lib/actions/dynamodb.d.ts.map +1 -0
  15. package/lib/actions/dynamodb.js +119 -0
  16. package/lib/actions/email.d.ts +1 -0
  17. package/lib/actions/email.d.ts.map +1 -0
  18. package/lib/actions/email.js +56 -0
  19. package/lib/actions/files.d.ts +1 -0
  20. package/lib/actions/files.d.ts.map +1 -0
  21. package/lib/actions/files.js +226 -0
  22. package/lib/actions/groups.d.ts +1 -0
  23. package/lib/actions/groups.d.ts.map +1 -0
  24. package/lib/actions/groups.js +267 -0
  25. package/lib/actions/images.d.ts +1 -0
  26. package/lib/actions/images.d.ts.map +1 -0
  27. package/lib/actions/images.js +723 -0
  28. package/lib/actions/index.d.ts +1 -0
  29. package/lib/actions/index.d.ts.map +1 -0
  30. package/lib/actions/index.js +29 -0
  31. package/lib/actions/ios.d.ts +1 -0
  32. package/lib/actions/ios.d.ts.map +1 -0
  33. package/lib/actions/ios.js +230 -0
  34. package/lib/actions/locations.d.ts +1 -0
  35. package/lib/actions/locations.d.ts.map +1 -0
  36. package/lib/actions/locations.js +111 -0
  37. package/lib/actions/messages.d.ts +1 -0
  38. package/lib/actions/messages.d.ts.map +1 -0
  39. package/lib/actions/messages.js +167 -0
  40. package/lib/actions/notifications.d.ts +3 -2
  41. package/lib/actions/notifications.d.ts.map +1 -0
  42. package/lib/actions/notifications.js +37 -0
  43. package/lib/actions/payments.d.ts +1 -0
  44. package/lib/actions/payments.d.ts.map +1 -0
  45. package/lib/actions/payments.js +449 -0
  46. package/lib/actions/posts.d.ts +1 -0
  47. package/lib/actions/posts.d.ts.map +1 -0
  48. package/lib/actions/posts.js +608 -0
  49. package/lib/actions/profiles.d.ts +1 -0
  50. package/lib/actions/profiles.d.ts.map +1 -0
  51. package/lib/actions/profiles.js +58 -0
  52. package/lib/actions/reactions.d.ts +1 -0
  53. package/lib/actions/reactions.d.ts.map +1 -0
  54. package/lib/actions/reactions.js +286 -0
  55. package/lib/actions/s3.d.ts +1 -0
  56. package/lib/actions/s3.d.ts.map +1 -0
  57. package/lib/actions/s3.js +102 -0
  58. package/lib/actions/search.d.ts +1 -0
  59. package/lib/actions/search.d.ts.map +1 -0
  60. package/lib/actions/search.js +81 -0
  61. package/lib/actions/sms.d.ts +1 -0
  62. package/lib/actions/sms.d.ts.map +1 -0
  63. package/lib/actions/sms.js +52 -0
  64. package/lib/actions/statistics.d.ts +1 -0
  65. package/lib/actions/statistics.d.ts.map +1 -0
  66. package/lib/actions/statistics.js +43 -0
  67. package/lib/actions/subscriptions.d.ts +1 -0
  68. package/lib/actions/subscriptions.d.ts.map +1 -0
  69. package/lib/actions/subscriptions.js +202 -0
  70. package/lib/actions/tags.d.ts +1 -0
  71. package/lib/actions/tags.d.ts.map +1 -0
  72. package/lib/actions/tags.js +263 -0
  73. package/lib/actions/users.d.ts +1 -0
  74. package/lib/actions/users.d.ts.map +1 -0
  75. package/lib/actions/users.js +802 -0
  76. package/lib/actions/videos.d.ts +1 -0
  77. package/lib/actions/videos.d.ts.map +1 -0
  78. package/lib/actions/videos.js +423 -0
  79. package/lib/actions/websockets.d.ts +1 -0
  80. package/lib/actions/websockets.d.ts.map +1 -0
  81. package/lib/actions/websockets.js +164 -0
  82. package/lib/adapters/arangoAdapter.d.ts +1 -0
  83. package/lib/adapters/arangoAdapter.d.ts.map +1 -0
  84. package/lib/adapters/arangoAdapter.js +70 -0
  85. package/lib/adapters/contentAdapter.d.ts +1 -0
  86. package/lib/adapters/contentAdapter.d.ts.map +1 -0
  87. package/lib/adapters/contentAdapter.js +108 -0
  88. package/lib/adapters/fileAdapter.d.ts +1 -0
  89. package/lib/adapters/fileAdapter.d.ts.map +1 -0
  90. package/lib/adapters/fileAdapter.js +119 -0
  91. package/lib/adapters/imageAdapter.d.ts +1 -0
  92. package/lib/adapters/imageAdapter.d.ts.map +1 -0
  93. package/lib/adapters/imageAdapter.js +112 -0
  94. package/lib/adapters/index.d.ts +1 -0
  95. package/lib/adapters/index.d.ts.map +1 -0
  96. package/lib/adapters/index.js +11 -0
  97. package/lib/adapters/messageAdapter.d.ts +1 -0
  98. package/lib/adapters/messageAdapter.d.ts.map +1 -0
  99. package/lib/adapters/messageAdapter.js +82 -0
  100. package/lib/adapters/postAdapter.d.ts +1 -0
  101. package/lib/adapters/postAdapter.d.ts.map +1 -0
  102. package/lib/adapters/postAdapter.js +117 -0
  103. package/lib/adapters/reaktorAdapter.d.ts +1 -0
  104. package/lib/adapters/reaktorAdapter.d.ts.map +1 -0
  105. package/lib/adapters/reaktorAdapter.js +59 -0
  106. package/lib/adapters/tagAdapter.d.ts +1 -0
  107. package/lib/adapters/tagAdapter.d.ts.map +1 -0
  108. package/lib/adapters/tagAdapter.js +99 -0
  109. package/lib/adapters/userAdapter.d.ts +1 -0
  110. package/lib/adapters/userAdapter.d.ts.map +1 -0
  111. package/lib/adapters/userAdapter.js +264 -0
  112. package/lib/config.d.ts +1 -0
  113. package/lib/config.d.ts.map +1 -0
  114. package/lib/config.js +161 -0
  115. package/lib/handlers/graphqlHandler.d.ts +1 -0
  116. package/lib/handlers/graphqlHandler.d.ts.map +1 -0
  117. package/lib/handlers/graphqlHandler.js +118 -0
  118. package/lib/index.d.ts +1 -0
  119. package/lib/index.d.ts.map +1 -0
  120. package/lib/index.js +18 -0
  121. package/lib/lambdas/actions/websockets.d.ts +1 -0
  122. package/lib/lambdas/actions/websockets.d.ts.map +1 -0
  123. package/lib/lambdas/actions/websockets.js +105 -0
  124. package/lib/lambdas/authorizer.d.ts +1 -0
  125. package/lib/lambdas/authorizer.d.ts.map +1 -0
  126. package/lib/lambdas/authorizer.js +41 -0
  127. package/lib/lambdas/connection.d.ts +1 -0
  128. package/lib/lambdas/connection.d.ts.map +1 -0
  129. package/lib/lambdas/connection.js +85 -0
  130. package/lib/lambdas/utils/message.d.ts +1 -0
  131. package/lib/lambdas/utils/message.d.ts.map +1 -0
  132. package/lib/lambdas/utils/message.js +20 -0
  133. package/lib/lambdas/utils/websocket.d.ts +1 -0
  134. package/lib/lambdas/utils/websocket.d.ts.map +1 -0
  135. package/lib/lambdas/utils/websocket.js +78 -0
  136. package/lib/mocks/conversation.d.ts +1 -0
  137. package/lib/mocks/conversation.d.ts.map +1 -0
  138. package/lib/mocks/conversation.js +10 -0
  139. package/lib/mocks/file.d.ts +1 -0
  140. package/lib/mocks/file.d.ts.map +1 -0
  141. package/lib/mocks/file.js +13 -0
  142. package/lib/mocks/group.d.ts +1 -0
  143. package/lib/mocks/group.d.ts.map +1 -0
  144. package/lib/mocks/group.js +20 -0
  145. package/lib/mocks/image.d.ts +1 -0
  146. package/lib/mocks/image.d.ts.map +1 -0
  147. package/lib/mocks/image.js +17 -0
  148. package/lib/mocks/post.d.ts +1 -0
  149. package/lib/mocks/post.d.ts.map +1 -0
  150. package/lib/mocks/post.js +28 -0
  151. package/lib/mocks/tag.d.ts +1 -0
  152. package/lib/mocks/tag.d.ts.map +1 -0
  153. package/lib/mocks/tag.js +12 -0
  154. package/lib/mocks/user.d.ts +1 -0
  155. package/lib/mocks/user.d.ts.map +1 -0
  156. package/lib/mocks/user.js +61 -0
  157. package/lib/mocks/video.d.ts +1 -0
  158. package/lib/mocks/video.d.ts.map +1 -0
  159. package/lib/mocks/video.js +17 -0
  160. package/lib/mutations/content.d.ts +1 -0
  161. package/lib/mutations/content.d.ts.map +1 -0
  162. package/lib/mutations/content.js +27 -0
  163. package/lib/mutations/index.d.ts +1 -0
  164. package/lib/mutations/index.d.ts.map +1 -0
  165. package/lib/mutations/index.js +29 -0
  166. package/lib/mutations/locations.d.ts +1 -0
  167. package/lib/mutations/locations.d.ts.map +1 -0
  168. package/lib/mutations/locations.js +22 -0
  169. package/lib/mutations/messages.d.ts +1 -0
  170. package/lib/mutations/messages.d.ts.map +1 -0
  171. package/lib/mutations/messages.js +75 -0
  172. package/lib/mutations/posts.d.ts +1 -0
  173. package/lib/mutations/posts.d.ts.map +1 -0
  174. package/lib/mutations/posts.js +31 -0
  175. package/lib/mutations/profiles.d.ts +1 -0
  176. package/lib/mutations/profiles.d.ts.map +1 -0
  177. package/lib/mutations/profiles.js +78 -0
  178. package/lib/mutations/reactions.d.ts +1 -0
  179. package/lib/mutations/reactions.d.ts.map +1 -0
  180. package/lib/mutations/reactions.js +29 -0
  181. package/lib/mutations/statistics.d.ts +1 -0
  182. package/lib/mutations/statistics.d.ts.map +1 -0
  183. package/lib/mutations/statistics.js +17 -0
  184. package/lib/mutations/subscriptions.d.ts +1 -0
  185. package/lib/mutations/subscriptions.d.ts.map +1 -0
  186. package/lib/mutations/subscriptions.js +38 -0
  187. package/lib/mutations/tags.d.ts +1 -0
  188. package/lib/mutations/tags.d.ts.map +1 -0
  189. package/lib/mutations/tags.js +109 -0
  190. package/lib/mutations/users.d.ts +1 -0
  191. package/lib/mutations/users.d.ts.map +1 -0
  192. package/lib/mutations/users.js +129 -0
  193. package/lib/objectTypes/app.d.ts +1 -0
  194. package/lib/objectTypes/app.d.ts.map +1 -0
  195. package/lib/objectTypes/app.js +147 -0
  196. package/lib/objectTypes/bankAccount.d.ts +1 -0
  197. package/lib/objectTypes/bankAccount.d.ts.map +1 -0
  198. package/lib/objectTypes/bankAccount.js +54 -0
  199. package/lib/objectTypes/connection.d.ts +1 -0
  200. package/lib/objectTypes/connection.d.ts.map +1 -0
  201. package/lib/objectTypes/connection.js +26 -0
  202. package/lib/objectTypes/content.d.ts +1 -0
  203. package/lib/objectTypes/content.d.ts.map +1 -0
  204. package/lib/objectTypes/content.js +79 -0
  205. package/lib/objectTypes/conversation.d.ts +1 -0
  206. package/lib/objectTypes/conversation.d.ts.map +1 -0
  207. package/lib/objectTypes/conversation.js +53 -0
  208. package/lib/objectTypes/creditCard.d.ts +1 -0
  209. package/lib/objectTypes/creditCard.d.ts.map +1 -0
  210. package/lib/objectTypes/creditCard.js +64 -0
  211. package/lib/objectTypes/document.d.ts +1 -0
  212. package/lib/objectTypes/document.d.ts.map +1 -0
  213. package/lib/objectTypes/document.js +21 -0
  214. package/lib/objectTypes/error.d.ts +1 -0
  215. package/lib/objectTypes/error.d.ts.map +1 -0
  216. package/lib/objectTypes/error.js +24 -0
  217. package/lib/objectTypes/external.d.ts +1 -0
  218. package/lib/objectTypes/external.d.ts.map +1 -0
  219. package/lib/objectTypes/external.js +52 -0
  220. package/lib/objectTypes/file.d.ts +1 -0
  221. package/lib/objectTypes/file.d.ts.map +1 -0
  222. package/lib/objectTypes/file.js +76 -0
  223. package/lib/objectTypes/filter.d.ts +1 -0
  224. package/lib/objectTypes/filter.d.ts.map +1 -0
  225. package/lib/objectTypes/filter.js +21 -0
  226. package/lib/objectTypes/group.d.ts +1 -0
  227. package/lib/objectTypes/group.d.ts.map +1 -0
  228. package/lib/objectTypes/group.js +97 -0
  229. package/lib/objectTypes/iapSubscription.d.ts +1 -0
  230. package/lib/objectTypes/iapSubscription.d.ts.map +1 -0
  231. package/lib/objectTypes/iapSubscription.js +18 -0
  232. package/lib/objectTypes/image.d.ts +1 -0
  233. package/lib/objectTypes/image.d.ts.map +1 -0
  234. package/lib/objectTypes/image.js +105 -0
  235. package/lib/objectTypes/index.d.ts +1 -0
  236. package/lib/objectTypes/index.d.ts.map +1 -0
  237. package/lib/objectTypes/index.js +28 -0
  238. package/lib/objectTypes/location.d.ts +1 -0
  239. package/lib/objectTypes/location.d.ts.map +1 -0
  240. package/lib/objectTypes/location.js +85 -0
  241. package/lib/objectTypes/message.d.ts +1 -0
  242. package/lib/objectTypes/message.d.ts.map +1 -0
  243. package/lib/objectTypes/message.js +72 -0
  244. package/lib/objectTypes/passcode.d.ts +1 -0
  245. package/lib/objectTypes/passcode.d.ts.map +1 -0
  246. package/lib/objectTypes/passcode.js +20 -0
  247. package/lib/objectTypes/plan.d.ts +1 -0
  248. package/lib/objectTypes/plan.d.ts.map +1 -0
  249. package/lib/objectTypes/plan.js +71 -0
  250. package/lib/objectTypes/post.d.ts +1 -0
  251. package/lib/objectTypes/post.d.ts.map +1 -0
  252. package/lib/objectTypes/post.js +101 -0
  253. package/lib/objectTypes/profile.d.ts +1 -0
  254. package/lib/objectTypes/profile.d.ts.map +1 -0
  255. package/lib/objectTypes/profile.js +68 -0
  256. package/lib/objectTypes/reaction.d.ts +1 -0
  257. package/lib/objectTypes/reaction.d.ts.map +1 -0
  258. package/lib/objectTypes/reaction.js +37 -0
  259. package/lib/objectTypes/relation.d.ts +1 -0
  260. package/lib/objectTypes/relation.d.ts.map +1 -0
  261. package/lib/objectTypes/relation.js +27 -0
  262. package/lib/objectTypes/search.d.ts +1 -0
  263. package/lib/objectTypes/search.d.ts.map +1 -0
  264. package/lib/objectTypes/search.js +50 -0
  265. package/lib/objectTypes/statistics.d.ts +1 -0
  266. package/lib/objectTypes/statistics.d.ts.map +1 -0
  267. package/lib/objectTypes/statistics.js +17 -0
  268. package/lib/objectTypes/subscription.d.ts +1 -0
  269. package/lib/objectTypes/subscription.d.ts.map +1 -0
  270. package/lib/objectTypes/subscription.js +102 -0
  271. package/lib/objectTypes/tag.d.ts +1 -0
  272. package/lib/objectTypes/tag.d.ts.map +1 -0
  273. package/lib/objectTypes/tag.js +41 -0
  274. package/lib/objectTypes/user.d.ts +1 -0
  275. package/lib/objectTypes/user.d.ts.map +1 -0
  276. package/lib/objectTypes/user.js +111 -0
  277. package/lib/queries/content.d.ts +1 -0
  278. package/lib/queries/content.d.ts.map +1 -0
  279. package/lib/queries/content.js +50 -0
  280. package/lib/queries/index.d.ts +1 -0
  281. package/lib/queries/index.d.ts.map +1 -0
  282. package/lib/queries/index.js +27 -0
  283. package/lib/queries/locations.d.ts +1 -0
  284. package/lib/queries/locations.d.ts.map +1 -0
  285. package/lib/queries/locations.js +23 -0
  286. package/lib/queries/messages.d.ts +1 -0
  287. package/lib/queries/messages.d.ts.map +1 -0
  288. package/lib/queries/messages.js +35 -0
  289. package/lib/queries/posts.d.ts +1 -0
  290. package/lib/queries/posts.d.ts.map +1 -0
  291. package/lib/queries/posts.js +154 -0
  292. package/lib/queries/reactions.d.ts +1 -0
  293. package/lib/queries/reactions.d.ts.map +1 -0
  294. package/lib/queries/reactions.js +34 -0
  295. package/lib/queries/statistics.d.ts +1 -0
  296. package/lib/queries/statistics.d.ts.map +1 -0
  297. package/lib/queries/statistics.js +17 -0
  298. package/lib/queries/subscriptions.d.ts +1 -0
  299. package/lib/queries/subscriptions.d.ts.map +1 -0
  300. package/lib/queries/subscriptions.js +21 -0
  301. package/lib/queries/tags.d.ts +1 -0
  302. package/lib/queries/tags.d.ts.map +1 -0
  303. package/lib/queries/tags.js +56 -0
  304. package/lib/queries/users.d.ts +1 -0
  305. package/lib/queries/users.d.ts.map +1 -0
  306. package/lib/queries/users.js +39 -0
  307. package/lib/templates/email/layout.d.ts +1 -0
  308. package/lib/templates/email/layout.d.ts.map +1 -0
  309. package/lib/templates/email/layout.js +281 -0
  310. package/lib/templates/email/passwordForgot.d.ts +1 -0
  311. package/lib/templates/email/passwordForgot.d.ts.map +1 -0
  312. package/lib/templates/email/passwordForgot.js +17 -0
  313. package/lib/templates/email/passwordRecovery.d.ts +1 -0
  314. package/lib/templates/email/passwordRecovery.d.ts.map +1 -0
  315. package/lib/templates/email/passwordRecovery.js +14 -0
  316. package/lib/templates/email/verifyEmail.d.ts +1 -0
  317. package/lib/templates/email/verifyEmail.d.ts.map +1 -0
  318. package/lib/templates/email/verifyEmail.js +17 -0
  319. package/lib/templates/email/welcome.d.ts +1 -0
  320. package/lib/templates/email/welcome.d.ts.map +1 -0
  321. package/lib/templates/email/welcome.js +17 -0
  322. package/lib/templates/sms/passwordForgot.d.ts +1 -0
  323. package/lib/templates/sms/passwordForgot.d.ts.map +1 -0
  324. package/lib/templates/sms/passwordForgot.js +3 -0
  325. package/lib/templates/sms/passwordRecovery.d.ts +1 -0
  326. package/lib/templates/sms/passwordRecovery.d.ts.map +1 -0
  327. package/lib/templates/sms/passwordRecovery.js +3 -0
  328. package/lib/templates/sms/verifyEmail.d.ts +1 -0
  329. package/lib/templates/sms/verifyEmail.d.ts.map +1 -0
  330. package/lib/templates/sms/verifyEmail.js +3 -0
  331. package/lib/templates/sms/verifyPhone.d.ts +1 -0
  332. package/lib/templates/sms/verifyPhone.d.ts.map +1 -0
  333. package/lib/templates/sms/verifyPhone.js +3 -0
  334. package/lib/templates/sms/welcome.d.ts +1 -0
  335. package/lib/templates/sms/welcome.d.ts.map +1 -0
  336. package/lib/templates/sms/welcome.js +3 -0
  337. package/lib/types/apps.types.d.ts +1 -0
  338. package/lib/types/apps.types.d.ts.map +1 -0
  339. package/lib/types/apps.types.js +10 -0
  340. package/lib/types/arangodb.types.d.ts +1 -0
  341. package/lib/types/arangodb.types.d.ts.map +1 -0
  342. package/lib/types/arangodb.types.js +6 -0
  343. package/lib/types/auth.types.d.ts +1 -0
  344. package/lib/types/auth.types.d.ts.map +1 -0
  345. package/lib/types/auth.types.js +6 -0
  346. package/lib/types/connections.types.d.ts +1 -0
  347. package/lib/types/connections.types.d.ts.map +1 -0
  348. package/lib/types/connections.types.js +6 -0
  349. package/lib/types/content.types.d.ts +1 -0
  350. package/lib/types/content.types.d.ts.map +1 -0
  351. package/lib/types/content.types.js +6 -0
  352. package/lib/types/conversations.types.d.ts +1 -0
  353. package/lib/types/conversations.types.d.ts.map +1 -0
  354. package/lib/types/conversations.types.js +6 -0
  355. package/lib/types/email.types.d.ts +1 -0
  356. package/lib/types/email.types.d.ts.map +1 -0
  357. package/lib/types/email.types.js +6 -0
  358. package/lib/types/error.types.d.ts +1 -0
  359. package/lib/types/error.types.d.ts.map +1 -0
  360. package/lib/types/error.types.js +20 -0
  361. package/lib/types/files.types.d.ts +1 -0
  362. package/lib/types/files.types.d.ts.map +1 -0
  363. package/lib/types/files.types.js +6 -0
  364. package/lib/types/google.types.d.ts +1 -0
  365. package/lib/types/google.types.d.ts.map +1 -0
  366. package/lib/types/google.types.js +6 -0
  367. package/lib/types/groups.types.d.ts +1 -0
  368. package/lib/types/groups.types.d.ts.map +1 -0
  369. package/lib/types/groups.types.js +6 -0
  370. package/lib/types/images.types.d.ts +1 -0
  371. package/lib/types/images.types.d.ts.map +1 -0
  372. package/lib/types/images.types.js +6 -0
  373. package/lib/types/index.d.ts +1 -0
  374. package/lib/types/index.d.ts.map +1 -0
  375. package/lib/types/index.js +28 -0
  376. package/lib/types/locations.types.d.ts +1 -0
  377. package/lib/types/locations.types.d.ts.map +1 -0
  378. package/lib/types/locations.types.js +6 -0
  379. package/lib/types/messages.types.d.ts +1 -0
  380. package/lib/types/messages.types.d.ts.map +1 -0
  381. package/lib/types/messages.types.js +6 -0
  382. package/lib/types/notifications.types.d.ts +1 -0
  383. package/lib/types/notifications.types.d.ts.map +1 -0
  384. package/lib/types/notifications.types.js +6 -0
  385. package/lib/types/payments.types.d.ts +1 -0
  386. package/lib/types/payments.types.d.ts.map +1 -0
  387. package/lib/types/payments.types.js +6 -0
  388. package/lib/types/posts.types.d.ts +1 -0
  389. package/lib/types/posts.types.d.ts.map +1 -0
  390. package/lib/types/posts.types.js +6 -0
  391. package/lib/types/profiles.types.d.ts +1 -0
  392. package/lib/types/profiles.types.d.ts.map +1 -0
  393. package/lib/types/profiles.types.js +3 -0
  394. package/lib/types/statistics.types.d.ts +1 -0
  395. package/lib/types/statistics.types.d.ts.map +1 -0
  396. package/lib/types/statistics.types.js +3 -0
  397. package/lib/types/tags.types.d.ts +1 -0
  398. package/lib/types/tags.types.d.ts.map +1 -0
  399. package/lib/types/tags.types.js +6 -0
  400. package/lib/types/users.types.d.ts +1 -0
  401. package/lib/types/users.types.d.ts.map +1 -0
  402. package/lib/types/users.types.js +6 -0
  403. package/lib/types/videos.types.d.ts +1 -0
  404. package/lib/types/videos.types.d.ts.map +1 -0
  405. package/lib/types/videos.types.js +6 -0
  406. package/lib/types/websockets.types.d.ts +1 -0
  407. package/lib/types/websockets.types.d.ts.map +1 -0
  408. package/lib/types/websockets.types.js +6 -0
  409. package/lib/utils/adapterUtils.d.ts +1 -0
  410. package/lib/utils/adapterUtils.d.ts.map +1 -0
  411. package/lib/utils/adapterUtils.js +23 -0
  412. package/lib/utils/analyticsUtils.d.ts +1 -0
  413. package/lib/utils/analyticsUtils.d.ts.map +1 -0
  414. package/lib/utils/analyticsUtils.js +45 -0
  415. package/lib/utils/arangodbUtils.d.ts +1 -0
  416. package/lib/utils/arangodbUtils.d.ts.map +1 -0
  417. package/lib/utils/arangodbUtils.js +130 -0
  418. package/lib/utils/authUtils.d.ts +1 -0
  419. package/lib/utils/authUtils.d.ts.map +1 -0
  420. package/lib/utils/authUtils.js +54 -0
  421. package/lib/utils/contextUtils.d.ts +1 -0
  422. package/lib/utils/contextUtils.d.ts.map +1 -0
  423. package/lib/utils/contextUtils.js +10 -0
  424. package/lib/utils/dbI18n.d.ts +1 -0
  425. package/lib/utils/dbI18n.d.ts.map +1 -0
  426. package/lib/utils/dbI18n.example.d.ts +1 -0
  427. package/lib/utils/dbI18n.example.d.ts.map +1 -0
  428. package/lib/utils/dbI18n.example.js +93 -0
  429. package/lib/utils/dbI18n.js +28 -0
  430. package/lib/utils/googleTranslate.d.ts +1 -0
  431. package/lib/utils/googleTranslate.d.ts.map +1 -0
  432. package/lib/utils/googleTranslate.js +70 -0
  433. package/lib/utils/graphqlUtils.d.ts +1 -0
  434. package/lib/utils/graphqlUtils.d.ts.map +1 -0
  435. package/lib/utils/graphqlUtils.js +11 -0
  436. package/lib/utils/index.d.ts +1 -0
  437. package/lib/utils/index.d.ts.map +1 -0
  438. package/lib/utils/index.js +19 -0
  439. package/lib/utils/languageDetection.d.ts +1 -0
  440. package/lib/utils/languageDetection.d.ts.map +1 -0
  441. package/lib/utils/languageDetection.js +120 -0
  442. package/lib/utils/localeUtils.d.ts +1 -0
  443. package/lib/utils/localeUtils.d.ts.map +1 -0
  444. package/lib/utils/localeUtils.example.d.ts +1 -0
  445. package/lib/utils/localeUtils.example.d.ts.map +1 -0
  446. package/lib/utils/localeUtils.example.js +124 -0
  447. package/lib/utils/localeUtils.js +71 -0
  448. package/lib/utils/middlewareUtils.d.ts +1 -0
  449. package/lib/utils/middlewareUtils.d.ts.map +1 -0
  450. package/lib/utils/middlewareUtils.js +10 -0
  451. package/lib/utils/sessionUtils.d.ts +1 -0
  452. package/lib/utils/sessionUtils.d.ts.map +1 -0
  453. package/lib/utils/sessionUtils.js +26 -0
  454. package/lib/utils/stripeUtils.d.ts +2 -1
  455. package/lib/utils/stripeUtils.d.ts.map +1 -0
  456. package/lib/utils/stripeUtils.js +12 -0
  457. package/lib/utils/templateUtils.d.ts +1 -0
  458. package/lib/utils/templateUtils.d.ts.map +1 -0
  459. package/lib/utils/templateUtils.js +11 -0
  460. package/lib/utils/testUtils.d.ts +1 -0
  461. package/lib/utils/testUtils.d.ts.map +1 -0
  462. package/lib/utils/testUtils.js +292 -0
  463. package/lib/utils/translationQueue.d.ts +1 -0
  464. package/lib/utils/translationQueue.d.ts.map +1 -0
  465. package/lib/utils/translationQueue.example.d.ts +1 -0
  466. package/lib/utils/translationQueue.example.d.ts.map +1 -0
  467. package/lib/utils/translationQueue.example.js +340 -0
  468. package/lib/utils/translationQueue.js +113 -0
  469. package/package.json +54 -24
  470. package/.env +0 -1
  471. package/.env.example +0 -1
  472. package/DATABASE_I18N_GUIDE.md +0 -434
  473. package/TEST_UTILITIES_GUIDE.md +0 -360
  474. package/coverage/actions/groups.ts.html +0 -1039
  475. package/coverage/actions/images.ts.html +0 -2500
  476. package/coverage/actions/index.html +0 -116
  477. package/coverage/actions/notifications.ts.html +0 -223
  478. package/coverage/actions/posts.ts.html +0 -2356
  479. package/coverage/actions/tags.ts.html +0 -1000
  480. package/coverage/adapters/arangoAdapter.ts.html +0 -301
  481. package/coverage/adapters/fileAdapter.ts.html +0 -445
  482. package/coverage/adapters/index.html +0 -176
  483. package/coverage/adapters/postAdapter.ts.html +0 -436
  484. package/coverage/adapters/reaktorAdapter.ts.html +0 -310
  485. package/coverage/adapters/tagAdapter.ts.html +0 -409
  486. package/coverage/adapters/userAdapter.ts.html +0 -829
  487. package/coverage/analyticsUtils.ts.html +0 -286
  488. package/coverage/base.css +0 -224
  489. package/coverage/block-navigation.js +0 -87
  490. package/coverage/clover.xml +0 -6
  491. package/coverage/config.ts.html +0 -766
  492. package/coverage/coverage-final.json +0 -1
  493. package/coverage/favicon.png +0 -0
  494. package/coverage/index.html +0 -221
  495. package/coverage/lcov-report/base.css +0 -224
  496. package/coverage/lcov-report/block-navigation.js +0 -87
  497. package/coverage/lcov-report/favicon.png +0 -0
  498. package/coverage/lcov-report/index.html +0 -101
  499. package/coverage/lcov-report/prettify.css +0 -1
  500. package/coverage/lcov-report/prettify.js +0 -2
  501. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  502. package/coverage/lcov-report/sorter.js +0 -196
  503. package/coverage/lcov.info +0 -0
  504. package/coverage/mocks/file.ts.html +0 -118
  505. package/coverage/mocks/group.ts.html +0 -145
  506. package/coverage/mocks/image.ts.html +0 -142
  507. package/coverage/mocks/index.html +0 -176
  508. package/coverage/mocks/post.ts.html +0 -169
  509. package/coverage/mocks/tag.ts.html +0 -121
  510. package/coverage/mocks/user.ts.html +0 -271
  511. package/coverage/prettify.css +0 -1
  512. package/coverage/prettify.js +0 -2
  513. package/coverage/sort-arrow-sprite.png +0 -0
  514. package/coverage/sorter.js +0 -210
  515. package/coverage/testUtils.ts.html +0 -1309
  516. package/coverage/translationQueue.ts.html +0 -592
  517. package/coverage/types/error.ts.html +0 -145
  518. package/coverage/types/error.types.ts.html +0 -148
  519. package/coverage/types/index.html +0 -116
  520. package/coverage/utils/adapterUtils.ts.html +0 -163
  521. package/coverage/utils/analyticsUtils.ts.html +0 -286
  522. package/coverage/utils/arangodbUtils.ts.html +0 -463
  523. package/coverage/utils/authUtils.ts.html +0 -328
  524. package/coverage/utils/dbI18n.ts.html +0 -280
  525. package/coverage/utils/googleTranslate.ts.html +0 -385
  526. package/coverage/utils/index.html +0 -131
  527. package/coverage/utils/localeUtils.ts.html +0 -193
  528. package/coverage/utils/sessionUtils.ts.html +0 -211
  529. package/coverage/utils/testUtils.ts.html +0 -1309
  530. package/index.js +0 -5
  531. package/jpg:- +0 -0
  532. package/lex.config.mjs +0 -34
  533. package/tsconfig.build.json +0 -21
  534. package/tsconfig.lint.json +0 -33
  535. package/tsconfig.test.json +0 -31
@@ -0,0 +1,802 @@
1
+ /**
2
+ * Copyright (c) 2019-Present, Nitrogen Labs, Inc.
3
+ * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
4
+ */ import { parseNum } from '@nlabs/utils/parsers/numbers';
5
+ import { createHash, createPassword, parseArangoId, parseChar, parseEmail, parsePassword, parsePhone, parseUsername } from '@nlabs/utils/parsers/strings';
6
+ import { aql } from 'arangojs';
7
+ import { DateTime } from 'luxon';
8
+ import Stripe from 'stripe';
9
+ import { parseUser } from '../adapters/userAdapter.js';
10
+ import { Config } from '../config.js';
11
+ import { ErrorTypes } from '../types/error.types.js';
12
+ import { logError, logException } from '../utils/analyticsUtils.js';
13
+ import { getDocId, getLimit, selectReactionCountByType, useDb } from '../utils/arangodbUtils.js';
14
+ import { detectLanguage } from '../utils/languageDetection.js';
15
+ import { getSession, setSession } from '../utils/sessionUtils.js';
16
+ import { sendEmail } from './email.js';
17
+ import { sendSms } from './sms.js';
18
+ const eventCategory = 'users';
19
+ const STRIPE_API_VERSION = '2025-12-15.clover';
20
+ export var UserAccess = /*#__PURE__*/ function(UserAccess) {
21
+ UserAccess[UserAccess["DEACTIVATED"] = 0] = "DEACTIVATED";
22
+ UserAccess[UserAccess["ACTIVE"] = 1] = "ACTIVE";
23
+ UserAccess[UserAccess["PREMIUM"] = 2] = "PREMIUM";
24
+ UserAccess[UserAccess["CONTENT_ADMIN"] = 3] = "CONTENT_ADMIN";
25
+ UserAccess[UserAccess["ADMIN"] = 4] = "ADMIN";
26
+ return UserAccess;
27
+ }({});
28
+ export const createToken = (userId, username = '', userAccess = 0, expiresInMinutes = 15)=>{
29
+ const now = DateTime.local();
30
+ const sessionExpires = now.plus({
31
+ minutes: expiresInMinutes
32
+ });
33
+ const iat = Math.floor(now.toSeconds());
34
+ const exp = Math.floor(sessionExpires.toSeconds());
35
+ const token = setSession({
36
+ exp,
37
+ iat,
38
+ userAccess,
39
+ userId,
40
+ username
41
+ });
42
+ return {
43
+ expires: sessionExpires.toMillis(),
44
+ issued: now.toMillis(),
45
+ token,
46
+ userId,
47
+ username
48
+ };
49
+ };
50
+ export const getUserOptional = (fields = [])=>fields.reduce((selects, field)=>{
51
+ if (field.includes('Count')) {
52
+ return selectReactionCountByType('users', 'u', field, selects);
53
+ }
54
+ return selects;
55
+ }, {
56
+ objects: [],
57
+ queries: []
58
+ });
59
+ export const parseUserOptions = (options = {})=>{
60
+ const { from = 0, to = 30 } = options;
61
+ const limit = getLimit(from, to);
62
+ return {
63
+ ...options,
64
+ limit
65
+ };
66
+ };
67
+ export const addUser = async (context, user)=>{
68
+ const action = 'addUser';
69
+ const { databaseName, languageContext } = context;
70
+ const { confirm: _confirm, ...newUser } = user;
71
+ const { email, password, phone, username, userId, _key, _id, ...insertUser } = parseUser(newUser);
72
+ const hasPassword = !!password;
73
+ const hasUsername = !!username || !!phone || !!email;
74
+ if (!hasPassword || !hasUsername) {
75
+ logException({
76
+ action,
77
+ category: eventCategory,
78
+ params: {
79
+ username
80
+ },
81
+ value: ErrorTypes.INVALID_ARGUMENTS
82
+ }, context);
83
+ return null;
84
+ }
85
+ const hashId = username || phone || email;
86
+ const salt = createHash(`${hashId}${password}`, '');
87
+ const encryptedPassword = createPassword(password, salt);
88
+ const filters = [];
89
+ if (username) {
90
+ filters.push(`u.username == "${username}"`);
91
+ }
92
+ if (email) {
93
+ filters.push(`u.email == "${email}"`);
94
+ }
95
+ if (phone) {
96
+ filters.push(`u.phone == ${phone}`);
97
+ }
98
+ const checkQuery = `FOR u IN users
99
+ FILTER ${filters.join(' || ')}
100
+ LIMIT 1
101
+ RETURN u`;
102
+ try {
103
+ const existingUsers = await useDb(databaseName).query(checkQuery).then((cursor)=>cursor.all());
104
+ if (existingUsers.length) {
105
+ throw logException({
106
+ action,
107
+ category: eventCategory,
108
+ params: {
109
+ email,
110
+ phone,
111
+ username
112
+ },
113
+ value: ErrorTypes.EXISTING_ITEM
114
+ }, context);
115
+ }
116
+ } catch (error) {
117
+ throw logError({
118
+ action,
119
+ category: eventCategory,
120
+ params: {
121
+ email,
122
+ phone,
123
+ username
124
+ },
125
+ value: ErrorTypes.DATABASE_ERROR
126
+ }, error, context);
127
+ }
128
+ const phoneCountryCode = phone?.replace(/\D/g, '').substring(0, 3);
129
+ const locale = detectLanguage({
130
+ ...languageContext,
131
+ phoneCountryCode: phoneCountryCode || '',
132
+ userPreference: insertUser.locale || 'en'
133
+ });
134
+ const verifiedEmailCode = Math.floor(100000 + Math.random() * 900000);
135
+ const verifiedSmsCode = Math.floor(100000 + Math.random() * 900000);
136
+ const insert = {
137
+ ...insertUser,
138
+ _key: createHash(username),
139
+ added: Date.now(),
140
+ email,
141
+ locale,
142
+ modified: Date.now(),
143
+ password: encryptedPassword,
144
+ phone,
145
+ salt,
146
+ userAccess: 1,
147
+ username,
148
+ verifiedEmail: false,
149
+ verifiedEmailCode,
150
+ verifiedPhone: false,
151
+ verifiedSmsCode
152
+ };
153
+ const insertQuery = aql`INSERT ${insert} IN users RETURN NEW`;
154
+ return await useDb(databaseName).query(insertQuery).then((cursor)=>cursor.next()).catch((error)=>{
155
+ throw logError({
156
+ action,
157
+ category: eventCategory,
158
+ params: {
159
+ username
160
+ },
161
+ value: ErrorTypes.DATABASE_ERROR
162
+ }, error, context);
163
+ });
164
+ };
165
+ export const updateUser = async (context, user)=>{
166
+ const action = 'updateUser';
167
+ const { databaseName } = context;
168
+ const updatedUser = parseUser(user);
169
+ const { _key, _id, tags = [], ...update } = updatedUser;
170
+ const { id } = updatedUser;
171
+ const userQuery = aql`LET u = DOCUMENT(${id})
172
+ UPDATE u WITH ${update} IN users
173
+ RETURN NEW`;
174
+ try {
175
+ const database = useDb(databaseName);
176
+ const updatedUser = await database.query(userQuery).then((cursor)=>cursor.next());
177
+ const tagCollection = database.collection('isTagged');
178
+ await Promise.all(tags.map(({ id: tagDocId, name })=>{
179
+ const tagQuery = aql`FOR it IN isTagged
180
+ FILTER it._from == ${tagDocId} && it._to == ${id} && it.name == ${name}
181
+ LIMIT 1
182
+ RETURN it`;
183
+ return database.query(tagQuery).then((cursor)=>cursor.next()).then((tagEdge)=>{
184
+ if (!!tagEdge) {
185
+ return tagEdge;
186
+ }
187
+ const edge = {
188
+ _from: tagDocId,
189
+ _key: createHash(`isTagged-${tagDocId}-${id}`),
190
+ _to: id,
191
+ added: Date.now(),
192
+ name
193
+ };
194
+ return tagCollection.save(edge, {
195
+ returnNew: true
196
+ }).then(()=>edge);
197
+ });
198
+ }));
199
+ return updatedUser;
200
+ } catch (error) {
201
+ throw logError({
202
+ action,
203
+ category: eventCategory,
204
+ params: {
205
+ user
206
+ },
207
+ value: ErrorTypes.DATABASE_ERROR
208
+ }, error, context);
209
+ }
210
+ };
211
+ export const forgotPassword = async (context, { email, phone, username })=>{
212
+ const action = 'forgotPassword';
213
+ const { databaseName } = context;
214
+ const aqlQuery = aql`FOR u IN users
215
+ FILTER u.email == ${email} || u.phone == ${phone} || u.username == ${username}
216
+ LIMIT 1
217
+ RETURN u`;
218
+ try {
219
+ return await useDb(databaseName).query(aqlQuery).then(async (cursor)=>{
220
+ const user = cursor.next();
221
+ if (user) {
222
+ const { email, phone, verifiedEmail, verifiedPhone } = user;
223
+ const codeExpires = 1000 * 60 * 15; // 15 minutes
224
+ const code = Math.floor(100000 + Math.random() * 900000);
225
+ const userDocId = getDocId('users', user);
226
+ let update;
227
+ if (email && verifiedEmail) {
228
+ sendEmail({
229
+ context,
230
+ text: `Your code is ${code}`
231
+ });
232
+ update = {
233
+ verifiedEmailCode: code,
234
+ verifiedEmailExpires: codeExpires
235
+ };
236
+ }
237
+ if (phone && verifiedPhone) {
238
+ sendSms({
239
+ context,
240
+ text: `Your code is ${code}`
241
+ });
242
+ update = {
243
+ verifiedPhoneExpires: codeExpires,
244
+ verifiedSmsCode: code
245
+ };
246
+ }
247
+ if (update.verifiedEmailCode || update.verifiedSmsCode) {
248
+ const updateQuery = aql`UPDATE ${userDocId} WITH ${update} IN users`;
249
+ await useDb(databaseName).query(updateQuery);
250
+ return true;
251
+ }
252
+ return false;
253
+ }
254
+ return false;
255
+ });
256
+ } catch (error) {
257
+ logError({
258
+ action,
259
+ category: eventCategory,
260
+ params: {
261
+ email,
262
+ phone,
263
+ username
264
+ },
265
+ value: ErrorTypes.DATABASE_ERROR
266
+ }, error, context);
267
+ return false;
268
+ }
269
+ };
270
+ export const resetPassword = async (context, { code, password, type, username })=>{
271
+ const action = 'resetPassword';
272
+ const { databaseName } = context;
273
+ const formatPassword = parsePassword(password);
274
+ const aqlQuery = aql`FOR u IN users
275
+ FILTER u.username == ${username}
276
+ LIMIT 1
277
+ RETURN u`;
278
+ try {
279
+ return await useDb(databaseName).query(aqlQuery).then(async (cursor)=>{
280
+ const user = cursor.next();
281
+ if (user) {
282
+ const { _id: userDocId, salt, verifiedEmailCode, verifiedEmailExpires = 0, verifiedSmsCode, verifiedPhoneExpires = 0 } = user;
283
+ const now = Date.now();
284
+ let update;
285
+ switch(type){
286
+ case 'email':
287
+ if (code === verifiedEmailCode && verifiedEmailExpires > now) {
288
+ const password = createPassword(formatPassword, salt);
289
+ update = {
290
+ password
291
+ };
292
+ }
293
+ break;
294
+ case 'phone':
295
+ if (code === verifiedSmsCode && verifiedPhoneExpires > now) {
296
+ const password = createPassword(formatPassword, salt);
297
+ update = {
298
+ password
299
+ };
300
+ }
301
+ break;
302
+ default:
303
+ return false;
304
+ }
305
+ if (update) {
306
+ const updateQuery = aql`UPDATE ${userDocId} WITH ${update} IN users`;
307
+ await useDb(databaseName).query(updateQuery);
308
+ return true;
309
+ }
310
+ }
311
+ return false;
312
+ });
313
+ } catch (error) {
314
+ logError({
315
+ action,
316
+ category: eventCategory,
317
+ params: {
318
+ username
319
+ },
320
+ value: ErrorTypes.DATABASE_ERROR
321
+ }, error, context);
322
+ return false;
323
+ }
324
+ };
325
+ export const confirmCode = async (context, { code, type, value })=>{
326
+ const action = 'confirmCode';
327
+ const { databaseName } = context;
328
+ const isSms = type === 'sms';
329
+ const formattedValue = isSms ? parsePhone(value) : parseEmail(value);
330
+ const filterByType = isSms ? `FILTER u.phone == "${formattedValue}" && u.verifiedSmsCode == ${code}` : `FILTER u.email == "${formattedValue}" && u.verifiedEmailCode == ${code}`;
331
+ const aqlQuery = `FOR u IN users
332
+ ${filterByType}
333
+ LIMIT 1
334
+ RETURN u`;
335
+ try {
336
+ return await useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.next()).then((user)=>{
337
+ if (user) {
338
+ const updatedUser = isSms ? {
339
+ verifiedPhone: true,
340
+ verifiedSmsCode: 0
341
+ } : {
342
+ verifiedEmail: true,
343
+ verifiedEmailCode: 0
344
+ };
345
+ const aqlQuery = aql`UPDATE ${user._key} WITH ${updatedUser} IN users`;
346
+ return useDb(databaseName).query(aqlQuery).then(()=>true).catch((error)=>{
347
+ logError({
348
+ action,
349
+ category: eventCategory,
350
+ params: {
351
+ code,
352
+ type,
353
+ value: formattedValue
354
+ },
355
+ value: ErrorTypes.DATABASE_ERROR
356
+ }, error, context);
357
+ return false;
358
+ });
359
+ }
360
+ return false;
361
+ });
362
+ } catch (error) {
363
+ logError({
364
+ action,
365
+ category: eventCategory,
366
+ params: {
367
+ code,
368
+ type,
369
+ value: formattedValue
370
+ },
371
+ value: ErrorTypes.DATABASE_ERROR
372
+ }, error, context);
373
+ return false;
374
+ }
375
+ };
376
+ export const deleteUser = (context, user)=>{
377
+ const action = 'deleteUser';
378
+ const { databaseName } = context;
379
+ const { id } = parseUser(user);
380
+ const aqlQuery = aql`LET u = DOCUMENT(${id})
381
+ REMOVE u IN users
382
+ RETURN OLD`;
383
+ const stripeClient = new Stripe(Config.get('stripe.token'), {
384
+ apiVersion: STRIPE_API_VERSION,
385
+ typescript: true
386
+ });
387
+ return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.next()).then((deletedUser)=>stripeClient.customers.del(deletedUser?.stripeCustomerId).then(()=>stripeClient.accounts.del(deletedUser?.stripeAccountId)).then(()=>deletedUser)).catch((error)=>logError({
388
+ action,
389
+ category: eventCategory,
390
+ params: {
391
+ id
392
+ },
393
+ value: ErrorTypes.DATABASE_ERROR
394
+ }, error, context));
395
+ };
396
+ export const deactivateUser = (context, user)=>{
397
+ const action = 'delete';
398
+ const { databaseName } = context;
399
+ const { id } = parseUser(user);
400
+ const updated = {
401
+ userAccess: 0
402
+ };
403
+ const aqlQuery = aql`UPDATE ${id} WITH ${updated} IN users LIMIT 1 RETURN NEW`;
404
+ return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.next()).catch((error)=>{
405
+ throw logError({
406
+ action,
407
+ category: eventCategory,
408
+ params: {
409
+ id
410
+ },
411
+ value: ErrorTypes.DATABASE_ERROR
412
+ }, error, context);
413
+ });
414
+ };
415
+ export const getDisplayName = (user)=>{
416
+ const { first, last, name = '', username = '' } = user;
417
+ const fullname = [
418
+ first,
419
+ last
420
+ ].join(' ').trim();
421
+ if (name) {
422
+ return name;
423
+ } else if (fullname !== '') {
424
+ return fullname;
425
+ } else if (username) {
426
+ return username;
427
+ }
428
+ return 'Unknown';
429
+ };
430
+ export const getSessionUser = (context)=>{
431
+ const action = 'getSessionUser';
432
+ const { databaseName, fields, session: { userId: sessionId, username } = {} } = context;
433
+ const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
434
+ const formatSessionId = parseArangoId(`users/${sessionId}`);
435
+ const aqlQuery = `LET u = DOCUMENT("${formatSessionId}")
436
+ ${selectQueries.join('\n')}
437
+ RETURN MERGE(u, {${selectObjects.join(', ')}})`;
438
+ return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.next()).catch((error)=>{
439
+ throw logError({
440
+ action,
441
+ category: eventCategory,
442
+ params: {
443
+ userId: sessionId,
444
+ username
445
+ },
446
+ value: ErrorTypes.DATABASE_ERROR
447
+ }, error, context);
448
+ });
449
+ };
450
+ export const getUser = (context, user)=>{
451
+ const action = 'getUser';
452
+ const { email, id, phone, userId, username } = parseUser(user);
453
+ const { databaseName, fields } = context;
454
+ const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
455
+ let aqlQuery = '';
456
+ if (id) {
457
+ aqlQuery = `LET u = DOCUMENT("${id}")
458
+ ${selectQueries.join('\n')}
459
+ FILTER u.userAccess > 0
460
+ RETURN MERGE(u, {${selectObjects.join(', ')}})`;
461
+ } else if (username) {
462
+ aqlQuery = `FOR u IN users
463
+ FILTER u.username == "${username}"
464
+ ${selectQueries.join('\n')}
465
+ RETURN MERGE(u, {${selectObjects.join(', ')}})`;
466
+ } else if (email) {
467
+ aqlQuery = `FOR u IN users
468
+ FILTER u.email == "${email}"
469
+ ${selectQueries.join('\n')}
470
+ RETURN MERGE(u, {${selectObjects.join(', ')}})`;
471
+ } else if (phone) {
472
+ aqlQuery = `FOR u IN users
473
+ FILTER u.phone == "${phone}"
474
+ ${selectQueries.join('\n')}
475
+ RETURN MERGE(u, {${selectObjects.join(', ')}})`;
476
+ }
477
+ return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.next()).then((user)=>user).catch((error)=>logError({
478
+ action,
479
+ category: eventCategory,
480
+ params: {
481
+ id,
482
+ userId,
483
+ username
484
+ },
485
+ value: ErrorTypes.DATABASE_ERROR
486
+ }, error, context));
487
+ };
488
+ export const getUsers = (context, options)=>{
489
+ const action = 'getUserList';
490
+ const { databaseName, fields } = context;
491
+ const { limit, username } = parseUserOptions(options);
492
+ const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
493
+ const filterBy = [
494
+ 'u.userAccess > 0'
495
+ ];
496
+ if (username) {
497
+ filterBy.push(`CONTAINS(u.username, "${parseUsername(username)}")`);
498
+ }
499
+ const aqlQuery = `FOR u IN users
500
+ FILTER ${filterBy.join(' && ')}
501
+ ${selectQueries.join('\n')}
502
+ ${limit.aql}
503
+ SORT u.username
504
+ RETURN MERGE(u, {${selectObjects.join(', ')}})`;
505
+ return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.all()).catch((error)=>{
506
+ logError({
507
+ action,
508
+ category: eventCategory,
509
+ value: ErrorTypes.DATABASE_ERROR
510
+ }, error, context);
511
+ return [];
512
+ });
513
+ };
514
+ export const getUsersByReactions = (context, { reactions = [], username }, options)=>{
515
+ const action = 'getUsersByReactions';
516
+ const { databaseName, fields, session: { userId: sessionId } = {} } = context;
517
+ const formatReactions = reactions.map((reactionName)=>parseChar(reactionName, 32).toLowerCase());
518
+ const { limit } = parseUserOptions(options);
519
+ const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
520
+ const formatSessionId = `users/${sessionId}`;
521
+ const formatUsername = parseUsername(username);
522
+ const filterBy = [
523
+ 'u.userAccess > 0',
524
+ `POSITION(${JSON.stringify(formatReactions)}, LOWER(r.name))`
525
+ ];
526
+ if (username) {
527
+ filterBy.push(`CONTAINS(u.username, "${formatUsername}")`);
528
+ }
529
+ const aqlQuery = `FOR u, r IN OUTBOUND "${formatSessionId}" hasReaction
530
+ OPTIONS {vertexCollections: "users"}
531
+ ${selectQueries.join('\n')}
532
+ FILTER ${filterBy.join(' && ')}
533
+ ${limit.aql}
534
+ RETURN MERGE(u, {${selectObjects.join(', ')}})`;
535
+ return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.all()).catch((error)=>{
536
+ logError({
537
+ action,
538
+ category: eventCategory,
539
+ value: ErrorTypes.DATABASE_ERROR
540
+ }, error, context);
541
+ return [];
542
+ });
543
+ };
544
+ export const getUsersByTags = (context, { tags, username }, options)=>{
545
+ const action = 'getUsersByTags';
546
+ const { databaseName, fields, session: { userId: sessionId } = {} } = context;
547
+ const formatTags = tags?.reduce((list, tagName)=>{
548
+ if (tagName) {
549
+ list.push(parseChar(tagName, 32).toLowerCase());
550
+ }
551
+ return list;
552
+ }, []);
553
+ const { limit } = parseUserOptions(options);
554
+ const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
555
+ const formatUsername = parseUsername(username);
556
+ const filterBy = [
557
+ `u._key != "${sessionId}"`,
558
+ 'u.userAccess > 0'
559
+ ];
560
+ if (username) {
561
+ filterBy.push(`CONTAINS(u.username, "${formatUsername}")`);
562
+ }
563
+ const aqlQuery = `FOR t IN tags
564
+ FILTER POSITION(${JSON.stringify(formatTags)}, LOWER(t.name))
565
+ FOR u, it IN OUTBOUND t isTagged
566
+ OPTIONS {bfs: true, uniqueVertices: "global", vertexCollections: "users"}
567
+ ${selectQueries.join('\n')}
568
+ FILTER ${filterBy.join(' && ')}
569
+ ${limit.aql}
570
+ RETURN DISTINCT MERGE(u, {${selectObjects.join(', ')}})`;
571
+ return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.all()).catch((error)=>{
572
+ logError({
573
+ action,
574
+ category: eventCategory,
575
+ value: ErrorTypes.DATABASE_ERROR
576
+ }, error, context);
577
+ return [];
578
+ });
579
+ };
580
+ export const getUsersByLatest = (context, { username }, options)=>{
581
+ const action = 'getUsersByLatest';
582
+ const { databaseName, fields, session: { userId } = {} } = context;
583
+ const { limit } = parseUserOptions(options);
584
+ const filter = [
585
+ 'u._id != session._id',
586
+ 'u.userAccess > 0'
587
+ ];
588
+ const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
589
+ if (username) {
590
+ filter.push(`CONTAINS(u.username, "${parseUsername(username)}")`);
591
+ }
592
+ // Get data from database
593
+ const aqlQuery = `FOR u IN users
594
+ LET session = DOCUMENT("users/${userId}")
595
+ FILTER ${filter.join(' && ')}
596
+ ${selectQueries.join('\n')}
597
+ LET distance = DISTANCE(u.latitude || 0, u.longitude || 0, session.latitude || 0, session.longitude || 0)
598
+ ${limit.aql}
599
+ SORT distance ASC, u.added DESC
600
+ RETURN MERGE(u, {${selectObjects.join(', ')}})`;
601
+ return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.all()).catch((error)=>{
602
+ logError({
603
+ action,
604
+ category: eventCategory,
605
+ value: ErrorTypes.DATABASE_ERROR
606
+ }, error, context);
607
+ return [];
608
+ });
609
+ };
610
+ export const getUsersByConnection = (context, { userId }, options)=>{
611
+ const action = 'getUsersByConnection';
612
+ const { databaseName, fields } = context;
613
+ const { limit, username } = parseUserOptions(options);
614
+ const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
615
+ const formatUserId = parseArangoId(`users/${userId}`);
616
+ const filterBy = [
617
+ 'u.userAccess > 0'
618
+ ];
619
+ if (username) {
620
+ filterBy.push(`CONTAINS(u.username, "${parseUsername(username)}")`);
621
+ }
622
+ const aqlQuery = `FOR cu IN users
623
+ LET session = DOCUMENT("${formatUserId}")
624
+ FOR u, connection IN OUTBOUND cu hasConnection
625
+ OPTIONS {bfs: true, uniqueVertices: "global", vertexCollections: "users"}
626
+ ${selectQueries.join('\n')}
627
+ FILTER ${filterBy.join(' && ')}
628
+ ${limit.aql}
629
+ RETURN DISTINCT MERGE(u, {${selectObjects.join(', ')}})`;
630
+ return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.all()).catch((error)=>{
631
+ logError({
632
+ action,
633
+ category: eventCategory,
634
+ value: ErrorTypes.DATABASE_ERROR
635
+ }, error, context);
636
+ return [];
637
+ });
638
+ };
639
+ export const refreshSession = ({ expires, token })=>{
640
+ try {
641
+ const { userId, username, userAccess } = getSession(token);
642
+ return createToken(userId, username, userAccess, expires);
643
+ } catch (error) {
644
+ throw error; // Re-throw the error from getSession
645
+ }
646
+ };
647
+ export const signIn = async (context, args)=>{
648
+ const action = 'signIn';
649
+ const { databaseName } = context;
650
+ const { email, expires, password, phone, username } = args;
651
+ const formatEmail = parseEmail(email);
652
+ const formatUsername = parseUsername(username);
653
+ const formatPassword = parsePassword(password);
654
+ const formatPhone = parsePhone(phone);
655
+ const formatExpires = parseNum(expires) || 15;
656
+ if (!formatUsername && !formatEmail && !formatPhone || !formatPassword) {
657
+ throw logException({
658
+ action,
659
+ category: eventCategory,
660
+ params: {
661
+ username
662
+ },
663
+ value: ErrorTypes.INVALID_ARGUMENTS
664
+ }, context);
665
+ }
666
+ const filters = [];
667
+ if (formatEmail) {
668
+ filters.push(`u.email == "${formatEmail}"`);
669
+ }
670
+ if (formatPhone) {
671
+ filters.push(`u.phone == ${formatPhone}`);
672
+ }
673
+ if (formatUsername) {
674
+ filters.push(`u.username == "${formatUsername}"`);
675
+ }
676
+ const checkQuery = `FOR u IN users
677
+ FILTER ${filters.join(' || ')}
678
+ LIMIT 1
679
+ RETURN u`;
680
+ let checkUser;
681
+ try {
682
+ checkUser = await useDb(databaseName).query(checkQuery).then((cursor)=>cursor.next());
683
+ } catch (error) {
684
+ throw logError({
685
+ action,
686
+ category: eventCategory,
687
+ params: {
688
+ username: formatUsername
689
+ },
690
+ value: ErrorTypes.DATABASE_ERROR
691
+ }, error, context);
692
+ }
693
+ if (!checkUser) {
694
+ throw logException({
695
+ action,
696
+ category: eventCategory,
697
+ params: {
698
+ username
699
+ },
700
+ value: ErrorTypes.INVALID_AUTHENTICATION
701
+ }, context);
702
+ }
703
+ const { _key: userId, password: validPassword, salt, userAccess } = checkUser;
704
+ const authPassword = createPassword(formatPassword, salt);
705
+ console.log({
706
+ createPassword,
707
+ authPassword,
708
+ validPassword,
709
+ formatPassword,
710
+ salt
711
+ });
712
+ if (validPassword !== authPassword) {
713
+ throw logException({
714
+ action,
715
+ category: eventCategory,
716
+ params: {
717
+ userAccess,
718
+ userId,
719
+ username
720
+ },
721
+ value: ErrorTypes.INVALID_AUTHENTICATION
722
+ }, context);
723
+ }
724
+ try {
725
+ const token = createToken(userId || '', username || '', userAccess, formatExpires);
726
+ return token;
727
+ } catch (error) {
728
+ throw logError({
729
+ action,
730
+ category: eventCategory,
731
+ params: {
732
+ userId,
733
+ username
734
+ },
735
+ value: ErrorTypes.DATABASE_ERROR
736
+ }, error, context);
737
+ }
738
+ };
739
+ export const signOut = async (context)=>{
740
+ const action = 'signOut';
741
+ const { databaseName, session: { userId: sessionId, username } = {} } = context;
742
+ const userDocId = `users/${sessionId}`;
743
+ const update = {
744
+ lastOnline: Date.now(),
745
+ sessionId: null
746
+ };
747
+ const sessionQuery = aql`LET u = DOCUMENT(${userDocId})
748
+ UPDATE u WITH ${update} IN users
749
+ LIMIT 1
750
+ RETURN NEW`;
751
+ try {
752
+ await useDb(databaseName).query(sessionQuery).then((cursor)=>cursor.next());
753
+ } catch (error) {
754
+ logError({
755
+ action,
756
+ category: eventCategory,
757
+ params: {
758
+ userId: sessionId,
759
+ username
760
+ },
761
+ value: ErrorTypes.DATABASE_ERROR
762
+ }, error, context);
763
+ return false;
764
+ }
765
+ return true;
766
+ };
767
+ export const getActiveUserCount = (context)=>{
768
+ const action = 'getActiveUserCount';
769
+ const { databaseName } = context;
770
+ const countQuery = aql`LET docs = (
771
+ FOR u IN users
772
+ FILTER u.active == true
773
+ RETURN u
774
+ )
775
+ RETURN LENGTH(docs)`;
776
+ return useDb(databaseName).query(countQuery).then((cursor)=>cursor.next()).catch((error)=>{
777
+ throw logError({
778
+ action,
779
+ category: eventCategory,
780
+ value: ErrorTypes.DATABASE_ERROR
781
+ }, error, context);
782
+ });
783
+ };
784
+ export const getUserByToken = (context, token)=>{
785
+ const action = 'getUserByToken';
786
+ const { databaseName } = context;
787
+ const { userId } = getSession(token);
788
+ const userDocId = parseArangoId(`users/${userId}`);
789
+ const aqlQuery = aql`LET u = DOCUMENT("${userDocId}") RETURN u`;
790
+ return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.next()).catch((error)=>{
791
+ throw logError({
792
+ action,
793
+ category: eventCategory,
794
+ params: {
795
+ userId
796
+ },
797
+ value: ErrorTypes.DATABASE_ERROR
798
+ }, error, context);
799
+ });
800
+ };
801
+
802
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L3JlYWt0b3Ivc3JjL2FjdGlvbnMvdXNlcnMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTktUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCB7cGFyc2VOdW19IGZyb20gJ0BubGFicy91dGlscy9wYXJzZXJzL251bWJlcnMnO1xuaW1wb3J0IHtcbiAgY3JlYXRlSGFzaCxcbiAgY3JlYXRlUGFzc3dvcmQsXG4gIHBhcnNlQXJhbmdvSWQsXG4gIHBhcnNlQ2hhcixcbiAgcGFyc2VFbWFpbCxcbiAgcGFyc2VQYXNzd29yZCxcbiAgcGFyc2VQaG9uZSxcbiAgcGFyc2VVc2VybmFtZVxufSBmcm9tICdAbmxhYnMvdXRpbHMvcGFyc2Vycy9zdHJpbmdzJztcbmltcG9ydCB7YXFsfSBmcm9tICdhcmFuZ29qcyc7XG5pbXBvcnQge0RhdGVUaW1lfSBmcm9tICdsdXhvbic7XG5pbXBvcnQgU3RyaXBlIGZyb20gJ3N0cmlwZSc7XG5cbmltcG9ydCB7cGFyc2VVc2VyfSBmcm9tICcuLi9hZGFwdGVycy91c2VyQWRhcHRlci5qcyc7XG5pbXBvcnQge0NvbmZpZ30gZnJvbSAnLi4vY29uZmlnLmpzJztcbmltcG9ydCB7RXJyb3JUeXBlcywgdHlwZSBTZXNzaW9uRXJyb3J9IGZyb20gJy4uL3R5cGVzL2Vycm9yLnR5cGVzLmpzJztcbmltcG9ydCB7bG9nRXJyb3IsIGxvZ0V4Y2VwdGlvbn0gZnJvbSAnLi4vdXRpbHMvYW5hbHl0aWNzVXRpbHMuanMnO1xuaW1wb3J0IHtnZXREb2NJZCwgZ2V0TGltaXQsIHNlbGVjdFJlYWN0aW9uQ291bnRCeVR5cGUsIHVzZURifSBmcm9tICcuLi91dGlscy9hcmFuZ29kYlV0aWxzLmpzJztcbmltcG9ydCB7ZGV0ZWN0TGFuZ3VhZ2V9IGZyb20gJy4uL3V0aWxzL2xhbmd1YWdlRGV0ZWN0aW9uLmpzJztcbmltcG9ydCB7Z2V0U2Vzc2lvbiwgc2V0U2Vzc2lvbiwgdHlwZSBTZXNzaW9uVG9rZW59IGZyb20gJy4uL3V0aWxzL3Nlc3Npb25VdGlscy5qcyc7XG5pbXBvcnQge3NlbmRFbWFpbH0gZnJvbSAnLi9lbWFpbC5qcyc7XG5pbXBvcnQge3NlbmRTbXN9IGZyb20gJy4vc21zLmpzJztcblxuaW1wb3J0IHR5cGUge0FxbFF1ZXJ5fSBmcm9tICdhcmFuZ29qcy9hcWwnO1xuaW1wb3J0IHR5cGUge0VkZ2VDb2xsZWN0aW9ufSBmcm9tICdhcmFuZ29qcy9jb2xsZWN0aW9ucyc7XG5pbXBvcnQgdHlwZSB7QXBpQ29udGV4dH0gZnJvbSAnLi4vdHlwZXMvYXV0aC50eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7VXNlcklucHV0LCBVc2VyVHlwZX0gZnJvbSAnLi4vdHlwZXMvdXNlcnMudHlwZXMuanMnO1xuXG5jb25zdCBldmVudENhdGVnb3J5ID0gJ3VzZXJzJztcbmNvbnN0IFNUUklQRV9BUElfVkVSU0lPTiA9ICcyMDI1LTEyLTE1LmNsb3Zlcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXNlck9wdGlvbnMge1xuICByZWFkb25seSBmcm9tPzogbnVtYmVyO1xuICByZWFkb25seSB0bz86IG51bWJlcjtcbiAgcmVhZG9ubHkgdXNlcm5hbWU/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBlbnVtIFVzZXJBY2Nlc3Mge1xuICBERUFDVElWQVRFRCA9IDAsXG4gIEFDVElWRSA9IDEsXG4gIFBSRU1JVU0gPSAyLFxuICBDT05URU5UX0FETUlOID0gMyxcbiAgQURNSU4gPSA0XG59XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVUb2tlbiA9IChcbiAgdXNlcklkOiBzdHJpbmcsXG4gIHVzZXJuYW1lOiBzdHJpbmcgPSAnJyxcbiAgdXNlckFjY2VzczogbnVtYmVyID0gMCxcbiAgZXhwaXJlc0luTWludXRlczogbnVtYmVyID0gMTVcbik6IFNlc3Npb25Ub2tlbiA9PiB7XG4gIGNvbnN0IG5vdzogRGF0ZVRpbWUgPSBEYXRlVGltZS5sb2NhbCgpO1xuICBjb25zdCBzZXNzaW9uRXhwaXJlczogRGF0ZVRpbWUgPSBub3cucGx1cyh7bWludXRlczogZXhwaXJlc0luTWludXRlc30pO1xuICBjb25zdCBpYXQ6IG51bWJlciA9IE1hdGguZmxvb3Iobm93LnRvU2Vjb25kcygpKTtcbiAgY29uc3QgZXhwOiBudW1iZXIgPSBNYXRoLmZsb29yKHNlc3Npb25FeHBpcmVzLnRvU2Vjb25kcygpKTtcbiAgY29uc3QgdG9rZW4gPSBzZXRTZXNzaW9uKHtcbiAgICBleHAsXG4gICAgaWF0LFxuICAgIHVzZXJBY2Nlc3MsXG4gICAgdXNlcklkLFxuICAgIHVzZXJuYW1lXG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgZXhwaXJlczogc2Vzc2lvbkV4cGlyZXMudG9NaWxsaXMoKSxcbiAgICBpc3N1ZWQ6IG5vdy50b01pbGxpcygpLFxuICAgIHRva2VuLFxuICAgIHVzZXJJZCxcbiAgICB1c2VybmFtZVxuICB9O1xufTtcblxuaW50ZXJmYWNlIFNlbGVjdEFjY3VtdWxhdG9yIHtcbiAgb2JqZWN0czogc3RyaW5nW107XG4gIHF1ZXJpZXM6IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgY29uc3QgZ2V0VXNlck9wdGlvbmFsID0gKGZpZWxkczogc3RyaW5nW10gPSBbXSk6IFNlbGVjdEFjY3VtdWxhdG9yID0+XG4gIGZpZWxkcy5yZWR1Y2UoKHNlbGVjdHM6IFNlbGVjdEFjY3VtdWxhdG9yLCBmaWVsZDogc3RyaW5nKSA9PiB7XG4gICAgaWYoZmllbGQuaW5jbHVkZXMoJ0NvdW50JykpIHtcbiAgICAgIHJldHVybiBzZWxlY3RSZWFjdGlvbkNvdW50QnlUeXBlKCd1c2VycycsICd1JywgZmllbGQsIHNlbGVjdHMpO1xuICAgIH1cblxuICAgIHJldHVybiBzZWxlY3RzO1xuICB9LCB7b2JqZWN0czogW10sIHF1ZXJpZXM6IFtdfSk7XG5cbmV4cG9ydCBjb25zdCBwYXJzZVVzZXJPcHRpb25zID0gKG9wdGlvbnM6IFVzZXJPcHRpb25zID0ge30pID0+IHtcbiAgY29uc3Qge1xuICAgIGZyb20gPSAwLFxuICAgIHRvID0gMzBcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGxpbWl0ID0gZ2V0TGltaXQoZnJvbSwgdG8pO1xuXG4gIHJldHVybiB7XG4gICAgLi4ub3B0aW9ucyxcbiAgICBsaW1pdFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGFkZFVzZXIgPSBhc3luYyAoY29udGV4dDogQXBpQ29udGV4dCwgdXNlcjogVXNlcklucHV0KTogUHJvbWlzZTxVc2VyVHlwZSB8IG51bGw+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2FkZFVzZXInO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBsYW5ndWFnZUNvbnRleHR9ID0gY29udGV4dDtcbiAgY29uc3Qge2NvbmZpcm06IF9jb25maXJtLCAuLi5uZXdVc2VyfSA9IHVzZXI7XG4gIGNvbnN0IHtlbWFpbCwgcGFzc3dvcmQsIHBob25lLCB1c2VybmFtZSwgdXNlcklkLCBfa2V5LCBfaWQsIC4uLmluc2VydFVzZXJ9ID0gcGFyc2VVc2VyKG5ld1VzZXIpO1xuICBjb25zdCBoYXNQYXNzd29yZCA9ICEhcGFzc3dvcmQ7XG4gIGNvbnN0IGhhc1VzZXJuYW1lID0gISF1c2VybmFtZSB8fCAhIXBob25lIHx8ICEhZW1haWw7XG5cbiAgaWYoIWhhc1Bhc3N3b3JkIHx8ICFoYXNVc2VybmFtZSkge1xuICAgIGxvZ0V4Y2VwdGlvbih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge3VzZXJuYW1lfSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLklOVkFMSURfQVJHVU1FTlRTXG4gICAgfSwgY29udGV4dCk7XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGhhc2hJZCA9IHVzZXJuYW1lIHx8IHBob25lIHx8IGVtYWlsO1xuICBjb25zdCBzYWx0OiBzdHJpbmcgPSBjcmVhdGVIYXNoKGAke2hhc2hJZH0ke3Bhc3N3b3JkfWAsICcnKTtcbiAgY29uc3QgZW5jcnlwdGVkUGFzc3dvcmQgPSBjcmVhdGVQYXNzd29yZChwYXNzd29yZCwgc2FsdCk7XG4gIGNvbnN0IGZpbHRlcnM6IHN0cmluZ1tdID0gW107XG5cbiAgaWYodXNlcm5hbWUpIHtcbiAgICBmaWx0ZXJzLnB1c2goYHUudXNlcm5hbWUgPT0gXCIke3VzZXJuYW1lfVwiYCk7XG4gIH1cblxuICBpZihlbWFpbCkge1xuICAgIGZpbHRlcnMucHVzaChgdS5lbWFpbCA9PSBcIiR7ZW1haWx9XCJgKTtcbiAgfVxuXG4gIGlmKHBob25lKSB7XG4gICAgZmlsdGVycy5wdXNoKGB1LnBob25lID09ICR7cGhvbmV9YCk7XG4gIH1cblxuICBjb25zdCBjaGVja1F1ZXJ5OiBzdHJpbmcgPSBgRk9SIHUgSU4gdXNlcnNcbiAgICBGSUxURVIgJHtmaWx0ZXJzLmpvaW4oJyB8fCAnKX1cbiAgICBMSU1JVCAxXG4gICAgUkVUVVJOIHVgO1xuXG4gIHRyeSB7XG4gICAgY29uc3QgZXhpc3RpbmdVc2VycyA9IGF3YWl0IHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoY2hlY2tRdWVyeSkudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkpO1xuXG4gICAgaWYoZXhpc3RpbmdVc2Vycy5sZW5ndGgpIHtcbiAgICAgIHRocm93IGxvZ0V4Y2VwdGlvbih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIHBhcmFtczoge1xuICAgICAgICAgIGVtYWlsLFxuICAgICAgICAgIHBob25lLFxuICAgICAgICAgIHVzZXJuYW1lXG4gICAgICAgIH0sXG4gICAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkVYSVNUSU5HX0lURU1cbiAgICAgIH0sIGNvbnRleHQpO1xuICAgIH1cbiAgfSBjYXRjaChlcnJvcikge1xuICAgIHRocm93IGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7ZW1haWwsIHBob25lLCB1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgfVxuXG4gIGNvbnN0IHBob25lQ291bnRyeUNvZGUgPSBwaG9uZT8ucmVwbGFjZSgvXFxEL2csICcnKS5zdWJzdHJpbmcoMCwgMyk7XG4gIGNvbnN0IGxvY2FsZSA9IGRldGVjdExhbmd1YWdlKHtcbiAgICAuLi5sYW5ndWFnZUNvbnRleHQsXG4gICAgcGhvbmVDb3VudHJ5Q29kZTogcGhvbmVDb3VudHJ5Q29kZSB8fCAnJyxcbiAgICB1c2VyUHJlZmVyZW5jZTogaW5zZXJ0VXNlci5sb2NhbGUgfHwgJ2VuJ1xuICB9KTtcbiAgY29uc3QgdmVyaWZpZWRFbWFpbENvZGU6IG51bWJlciA9IE1hdGguZmxvb3IoMTAwMDAwICsgKE1hdGgucmFuZG9tKCkgKiA5MDAwMDApKTtcbiAgY29uc3QgdmVyaWZpZWRTbXNDb2RlOiBudW1iZXIgPSBNYXRoLmZsb29yKDEwMDAwMCArIChNYXRoLnJhbmRvbSgpICogOTAwMDAwKSk7XG5cbiAgY29uc3QgaW5zZXJ0OiBVc2VyVHlwZSA9IHtcbiAgICAuLi5pbnNlcnRVc2VyLFxuICAgIF9rZXk6IGNyZWF0ZUhhc2godXNlcm5hbWUpLFxuICAgIGFkZGVkOiBEYXRlLm5vdygpLFxuICAgIGVtYWlsLFxuICAgIGxvY2FsZSxcbiAgICBtb2RpZmllZDogRGF0ZS5ub3coKSxcbiAgICBwYXNzd29yZDogZW5jcnlwdGVkUGFzc3dvcmQsXG4gICAgcGhvbmUsXG4gICAgc2FsdCxcbiAgICB1c2VyQWNjZXNzOiAxLFxuICAgIHVzZXJuYW1lLFxuICAgIHZlcmlmaWVkRW1haWw6IGZhbHNlLFxuICAgIHZlcmlmaWVkRW1haWxDb2RlLFxuICAgIHZlcmlmaWVkUGhvbmU6IGZhbHNlLFxuICAgIHZlcmlmaWVkU21zQ29kZVxuICB9O1xuXG4gIGNvbnN0IGluc2VydFF1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBJTlNFUlQgJHtpbnNlcnR9IElOIHVzZXJzIFJFVFVSTiBORVdgO1xuXG4gIHJldHVybiBhd2FpdCB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGluc2VydFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgdGhyb3cgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICBwYXJhbXM6IHt1c2VybmFtZX0sXG4gICAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgICB9LCBlcnJvciwgY29udGV4dCk7XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgdXBkYXRlVXNlciA9IGFzeW5jIChjb250ZXh0OiBBcGlDb250ZXh0LCB1c2VyOiBVc2VyVHlwZSk6IFByb21pc2U8VXNlclR5cGU+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ3VwZGF0ZVVzZXInO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHVwZGF0ZWRVc2VyID0gcGFyc2VVc2VyKHVzZXIpO1xuICBjb25zdCB7X2tleSwgX2lkLCB0YWdzID0gW10sIC4uLnVwZGF0ZX0gPSB1cGRhdGVkVXNlcjtcbiAgY29uc3Qge2lkfSA9IHVwZGF0ZWRVc2VyO1xuXG4gIGNvbnN0IHVzZXJRdWVyeTogQXFsUXVlcnkgPSBhcWxgTEVUIHUgPSBET0NVTUVOVCgke2lkfSlcbiAgICBVUERBVEUgdSBXSVRIICR7dXBkYXRlfSBJTiB1c2Vyc1xuICAgIFJFVFVSTiBORVdgO1xuICB0cnkge1xuICAgIGNvbnN0IGRhdGFiYXNlID0gdXNlRGIoZGF0YWJhc2VOYW1lKTtcbiAgICBjb25zdCB1cGRhdGVkVXNlciA9IGF3YWl0IGRhdGFiYXNlLnF1ZXJ5KHVzZXJRdWVyeSkudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKTtcbiAgICBjb25zdCB0YWdDb2xsZWN0aW9uOiBFZGdlQ29sbGVjdGlvbiA9IGRhdGFiYXNlLmNvbGxlY3Rpb24oJ2lzVGFnZ2VkJyk7XG5cbiAgICBhd2FpdCBQcm9taXNlLmFsbCh0YWdzLm1hcCgoe2lkOiB0YWdEb2NJZCwgbmFtZX0pID0+IHtcbiAgICAgIGNvbnN0IHRhZ1F1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBGT1IgaXQgSU4gaXNUYWdnZWRcbiAgICAgICAgRklMVEVSIGl0Ll9mcm9tID09ICR7dGFnRG9jSWR9ICYmIGl0Ll90byA9PSAke2lkfSAmJiBpdC5uYW1lID09ICR7bmFtZX1cbiAgICAgICAgTElNSVQgMVxuICAgICAgICBSRVRVUk4gaXRgO1xuXG4gICAgICByZXR1cm4gZGF0YWJhc2UucXVlcnkodGFnUXVlcnkpXG4gICAgICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgICAgIC50aGVuKCh0YWdFZGdlKSA9PiB7XG4gICAgICAgICAgaWYoISF0YWdFZGdlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGFnRWRnZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBlZGdlID0ge1xuICAgICAgICAgICAgX2Zyb206IHRhZ0RvY0lkLFxuICAgICAgICAgICAgX2tleTogY3JlYXRlSGFzaChgaXNUYWdnZWQtJHt0YWdEb2NJZH0tJHtpZH1gKSxcbiAgICAgICAgICAgIF90bzogaWQsXG4gICAgICAgICAgICBhZGRlZDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgIG5hbWVcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgcmV0dXJuIHRhZ0NvbGxlY3Rpb24uc2F2ZShlZGdlLCB7cmV0dXJuTmV3OiB0cnVlfSkudGhlbigoKSA9PiBlZGdlKTtcbiAgICAgICAgfSk7XG4gICAgfSkpO1xuXG4gICAgcmV0dXJuIHVwZGF0ZWRVc2VyO1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgdGhyb3cgbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHt1c2VyfSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgZm9yZ290UGFzc3dvcmQgPSBhc3luYyAoY29udGV4dDogQXBpQ29udGV4dCwge2VtYWlsLCBwaG9uZSwgdXNlcm5hbWV9KTogUHJvbWlzZTxib29sZWFuPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdmb3Jnb3RQYXNzd29yZCc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWV9ID0gY29udGV4dDtcbiAgY29uc3QgYXFsUXVlcnk6IEFxbFF1ZXJ5ID0gYXFsYEZPUiB1IElOIHVzZXJzXG4gICAgRklMVEVSIHUuZW1haWwgPT0gJHtlbWFpbH0gfHwgdS5waG9uZSA9PSAke3Bob25lfSB8fCB1LnVzZXJuYW1lID09ICR7dXNlcm5hbWV9XG4gICAgTElNSVQgMVxuICAgIFJFVFVSTiB1YDtcblxuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgICAgLnRoZW4oYXN5bmMgKGN1cnNvcikgPT4ge1xuICAgICAgICBjb25zdCB1c2VyID0gY3Vyc29yLm5leHQoKTtcblxuICAgICAgICBpZih1c2VyKSB7XG4gICAgICAgICAgY29uc3Qge2VtYWlsLCBwaG9uZSwgdmVyaWZpZWRFbWFpbCwgdmVyaWZpZWRQaG9uZX0gPSB1c2VyIGFzIFVzZXJUeXBlO1xuICAgICAgICAgIGNvbnN0IGNvZGVFeHBpcmVzID0gMTAwMCAqIDYwICogMTU7IC8vIDE1IG1pbnV0ZXNcbiAgICAgICAgICBjb25zdCBjb2RlID0gTWF0aC5mbG9vcigxMDAwMDAgKyAoTWF0aC5yYW5kb20oKSAqIDkwMDAwMCkpO1xuICAgICAgICAgIGNvbnN0IHVzZXJEb2NJZCA9IGdldERvY0lkKCd1c2VycycsIHVzZXIpO1xuICAgICAgICAgIGxldCB1cGRhdGU7XG5cbiAgICAgICAgICBpZihlbWFpbCAmJiB2ZXJpZmllZEVtYWlsKSB7XG4gICAgICAgICAgICBzZW5kRW1haWwoe1xuICAgICAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgICAgICB0ZXh0OiBgWW91ciBjb2RlIGlzICR7Y29kZX1gXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHVwZGF0ZSA9IHt2ZXJpZmllZEVtYWlsQ29kZTogY29kZSwgdmVyaWZpZWRFbWFpbEV4cGlyZXM6IGNvZGVFeHBpcmVzfTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZihwaG9uZSAmJiB2ZXJpZmllZFBob25lKSB7XG4gICAgICAgICAgICBzZW5kU21zKHtcbiAgICAgICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICAgICAgdGV4dDogYFlvdXIgY29kZSBpcyAke2NvZGV9YFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB1cGRhdGUgPSB7dmVyaWZpZWRQaG9uZUV4cGlyZXM6IGNvZGVFeHBpcmVzLCB2ZXJpZmllZFNtc0NvZGU6IGNvZGV9O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmKHVwZGF0ZS52ZXJpZmllZEVtYWlsQ29kZSB8fCB1cGRhdGUudmVyaWZpZWRTbXNDb2RlKSB7XG4gICAgICAgICAgICBjb25zdCB1cGRhdGVRdWVyeTogQXFsUXVlcnkgPSBhcWxgVVBEQVRFICR7dXNlckRvY0lkfSBXSVRIICR7dXBkYXRlfSBJTiB1c2Vyc2A7XG5cbiAgICAgICAgICAgIGF3YWl0IHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkodXBkYXRlUXVlcnkpO1xuXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9KTtcbiAgfSBjYXRjaChlcnJvcikge1xuICAgIGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7ZW1haWwsIHBob25lLCB1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHJlc2V0UGFzc3dvcmQgPSBhc3luYyAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHtcbiAgICBjb2RlLFxuICAgIHBhc3N3b3JkLFxuICAgIHR5cGUsXG4gICAgdXNlcm5hbWVcbiAgfToge1xuICAgIGNvZGU6IG51bWJlcjtcbiAgICBwYXNzd29yZDogc3RyaW5nO1xuICAgIHR5cGU6ICdwaG9uZScgfCAnZW1haWwnO1xuICAgIHVzZXJuYW1lOiBzdHJpbmc7XG4gIH1cbik6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAncmVzZXRQYXNzd29yZCc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWV9ID0gY29udGV4dDtcbiAgY29uc3QgZm9ybWF0UGFzc3dvcmQ6IHN0cmluZyA9IHBhcnNlUGFzc3dvcmQocGFzc3dvcmQpO1xuICBjb25zdCBhcWxRdWVyeTogQXFsUXVlcnkgPSBhcWxgRk9SIHUgSU4gdXNlcnNcbiAgICBGSUxURVIgdS51c2VybmFtZSA9PSAke3VzZXJuYW1lfVxuICAgIExJTUlUIDFcbiAgICBSRVRVUk4gdWA7XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRdWVyeSlcbiAgICAgIC50aGVuKGFzeW5jIChjdXJzb3IpID0+IHtcbiAgICAgICAgY29uc3QgdXNlciA9IGN1cnNvci5uZXh0KCk7XG5cbiAgICAgICAgaWYodXNlcikge1xuICAgICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgIF9pZDogdXNlckRvY0lkLFxuICAgICAgICAgICAgc2FsdCxcbiAgICAgICAgICAgIHZlcmlmaWVkRW1haWxDb2RlLFxuICAgICAgICAgICAgdmVyaWZpZWRFbWFpbEV4cGlyZXMgPSAwLFxuICAgICAgICAgICAgdmVyaWZpZWRTbXNDb2RlLFxuICAgICAgICAgICAgdmVyaWZpZWRQaG9uZUV4cGlyZXMgPSAwXG4gICAgICAgICAgfSA9IHVzZXIgYXMgVXNlclR5cGU7XG4gICAgICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICBsZXQgdXBkYXRlO1xuXG4gICAgICAgICAgc3dpdGNoKHR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ2VtYWlsJzpcbiAgICAgICAgICAgICAgaWYoY29kZSA9PT0gdmVyaWZpZWRFbWFpbENvZGUgJiYgdmVyaWZpZWRFbWFpbEV4cGlyZXMgPiBub3cpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXNzd29yZDogc3RyaW5nID0gY3JlYXRlUGFzc3dvcmQoZm9ybWF0UGFzc3dvcmQsIHNhbHQpO1xuICAgICAgICAgICAgICAgIHVwZGF0ZSA9IHtwYXNzd29yZH07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdwaG9uZSc6XG4gICAgICAgICAgICAgIGlmKGNvZGUgPT09IHZlcmlmaWVkU21zQ29kZSAmJiB2ZXJpZmllZFBob25lRXhwaXJlcyA+IG5vdykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhc3N3b3JkOiBzdHJpbmcgPSBjcmVhdGVQYXNzd29yZChmb3JtYXRQYXNzd29yZCwgc2FsdCk7XG4gICAgICAgICAgICAgICAgdXBkYXRlID0ge3Bhc3N3b3JkfTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZih1cGRhdGUpIHtcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZVF1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBVUERBVEUgJHt1c2VyRG9jSWR9IFdJVEggJHt1cGRhdGV9IElOIHVzZXJzYDtcblxuICAgICAgICAgICAgYXdhaXQgdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeSh1cGRhdGVRdWVyeSk7XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0pO1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHt1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGNvbmZpcm1Db2RlID0gYXN5bmMgKFxuICBjb250ZXh0OiBBcGlDb250ZXh0LFxuICB7XG4gICAgY29kZSxcbiAgICB0eXBlLFxuICAgIHZhbHVlXG4gIH06IHtcbiAgICBjb2RlOiBudW1iZXI7XG4gICAgdHlwZTogJ3NtcycgfCAnZW1haWwnO1xuICAgIHZhbHVlOiBzdHJpbmc7XG4gIH1cbik6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnY29uZmlybUNvZGUnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lfSA9IGNvbnRleHQ7XG4gIGNvbnN0IGlzU21zID0gdHlwZSA9PT0gJ3Ntcyc7XG4gIGNvbnN0IGZvcm1hdHRlZFZhbHVlID0gaXNTbXMgPyBwYXJzZVBob25lKHZhbHVlKSA6IHBhcnNlRW1haWwodmFsdWUpO1xuICBjb25zdCBmaWx0ZXJCeVR5cGUgPSBpc1Ntc1xuICAgID8gYEZJTFRFUiB1LnBob25lID09IFwiJHtmb3JtYXR0ZWRWYWx1ZX1cIiAmJiB1LnZlcmlmaWVkU21zQ29kZSA9PSAke2NvZGV9YFxuICAgIDogYEZJTFRFUiB1LmVtYWlsID09IFwiJHtmb3JtYXR0ZWRWYWx1ZX1cIiAmJiB1LnZlcmlmaWVkRW1haWxDb2RlID09ICR7Y29kZX1gO1xuICBjb25zdCBhcWxRdWVyeTogc3RyaW5nID0gYEZPUiB1IElOIHVzZXJzXG4gICAgJHtmaWx0ZXJCeVR5cGV9XG4gICAgTElNSVQgMVxuICAgIFJFVFVSTiB1YDtcblxuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAgIC50aGVuKCh1c2VyKSA9PiB7XG4gICAgICAgIGlmKHVzZXIpIHtcbiAgICAgICAgICBjb25zdCB1cGRhdGVkVXNlciA9IGlzU21zXG4gICAgICAgICAgICA/IHt2ZXJpZmllZFBob25lOiB0cnVlLCB2ZXJpZmllZFNtc0NvZGU6IDB9XG4gICAgICAgICAgICA6IHt2ZXJpZmllZEVtYWlsOiB0cnVlLCB2ZXJpZmllZEVtYWlsQ29kZTogMH07XG4gICAgICAgICAgY29uc3QgYXFsUXVlcnk6IEFxbFF1ZXJ5ID0gYXFsYFVQREFURSAke3VzZXIuX2tleX0gV0lUSCAke3VwZGF0ZWRVc2VyfSBJTiB1c2Vyc2A7XG5cbiAgICAgICAgICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRdWVyeSlcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHRydWUpXG4gICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICBsb2dFcnJvcih7XG4gICAgICAgICAgICAgICAgYWN0aW9uLFxuICAgICAgICAgICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICAgICAgICAgIHBhcmFtczoge2NvZGUsIHR5cGUsIHZhbHVlOiBmb3JtYXR0ZWRWYWx1ZX0sXG4gICAgICAgICAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgICAgICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuXG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge2NvZGUsIHR5cGUsIHZhbHVlOiBmb3JtYXR0ZWRWYWx1ZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGRlbGV0ZVVzZXIgPSAoY29udGV4dDogQXBpQ29udGV4dCwgdXNlcjogVXNlclR5cGUpOiBQcm9taXNlPFVzZXJUeXBlPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdkZWxldGVVc2VyJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZX0gPSBjb250ZXh0O1xuICBjb25zdCB7aWR9ID0gcGFyc2VVc2VyKHVzZXIpO1xuXG4gIGNvbnN0IGFxbFF1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBMRVQgdSA9IERPQ1VNRU5UKCR7aWR9KVxuICAgIFJFTU9WRSB1IElOIHVzZXJzXG4gICAgUkVUVVJOIE9MRGA7XG5cbiAgY29uc3Qgc3RyaXBlQ2xpZW50ID0gbmV3IFN0cmlwZShDb25maWcuZ2V0KCdzdHJpcGUudG9rZW4nKSwge2FwaVZlcnNpb246IFNUUklQRV9BUElfVkVSU0lPTiwgdHlwZXNjcmlwdDogdHJ1ZX0pO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgLnRoZW4oKGRlbGV0ZWRVc2VyKSA9PiBzdHJpcGVDbGllbnQuY3VzdG9tZXJzLmRlbChkZWxldGVkVXNlcj8uc3RyaXBlQ3VzdG9tZXJJZClcbiAgICAgIC50aGVuKCgpID0+IHN0cmlwZUNsaWVudC5hY2NvdW50cy5kZWwoZGVsZXRlZFVzZXI/LnN0cmlwZUFjY291bnRJZCkpXG4gICAgICAudGhlbigoKSA9PiBkZWxldGVkVXNlcikpXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7aWR9LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICB9LCBlcnJvciwgY29udGV4dCkpO1xufTtcblxuZXhwb3J0IGNvbnN0IGRlYWN0aXZhdGVVc2VyID0gKGNvbnRleHQ6IEFwaUNvbnRleHQsIHVzZXI6IFVzZXJUeXBlKTogUHJvbWlzZTxVc2VyVHlwZT4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnZGVsZXRlJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZX0gPSBjb250ZXh0O1xuICBjb25zdCB7aWR9ID0gcGFyc2VVc2VyKHVzZXIpO1xuICBjb25zdCB1cGRhdGVkOiBVc2VyVHlwZSA9IHtcbiAgICB1c2VyQWNjZXNzOiAwXG4gIH07XG4gIGNvbnN0IGFxbFF1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBVUERBVEUgJHtpZH0gV0lUSCAke3VwZGF0ZWR9IElOIHVzZXJzIExJTUlUIDEgUkVUVVJOIE5FV2A7XG5cbiAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoYXFsUXVlcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgdGhyb3cgbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHtpZH0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0RGlzcGxheU5hbWUgPSAodXNlcjogVXNlclR5cGUpOiBzdHJpbmcgPT4ge1xuICBjb25zdCB7Zmlyc3QsIGxhc3QsIG5hbWUgPSAnJywgdXNlcm5hbWUgPSAnJ30gPSB1c2VyO1xuICBjb25zdCBmdWxsbmFtZSA9IChbZmlyc3QsIGxhc3RdKS5qb2luKCcgJykudHJpbSgpO1xuXG4gIGlmKG5hbWUpIHtcbiAgICByZXR1cm4gbmFtZTtcbiAgfSBlbHNlIGlmKGZ1bGxuYW1lICE9PSAnJykge1xuICAgIHJldHVybiBmdWxsbmFtZTtcbiAgfSBlbHNlIGlmKHVzZXJuYW1lKSB7XG4gICAgcmV0dXJuIHVzZXJuYW1lO1xuICB9XG5cbiAgcmV0dXJuICdVbmtub3duJztcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRTZXNzaW9uVXNlciA9IChjb250ZXh0OiBBcGlDb250ZXh0KTogUHJvbWlzZTxVc2VyVHlwZT4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnZ2V0U2Vzc2lvblVzZXInO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHMsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZCwgdXNlcm5hbWV9ID0ge319ID0gY29udGV4dDtcbiAgY29uc3Qge29iamVjdHM6IHNlbGVjdE9iamVjdHMsIHF1ZXJpZXM6IHNlbGVjdFF1ZXJpZXN9ID0gZ2V0VXNlck9wdGlvbmFsKGZpZWxkcyk7XG4gIGNvbnN0IGZvcm1hdFNlc3Npb25JZCA9IHBhcnNlQXJhbmdvSWQoYHVzZXJzLyR7c2Vzc2lvbklkfWApO1xuXG4gIGNvbnN0IGFxbFF1ZXJ5OiBzdHJpbmcgPSBgTEVUIHUgPSBET0NVTUVOVChcIiR7Zm9ybWF0U2Vzc2lvbklkfVwiKVxuICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gIFJFVFVSTiBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkgYXMgdW5rbm93biBhcyBVc2VyVHlwZSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgdGhyb3cgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICBwYXJhbXM6IHt1c2VySWQ6IHNlc3Npb25JZCwgdXNlcm5hbWV9LFxuICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICAgIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFVzZXIgPSAoY29udGV4dDogQXBpQ29udGV4dCwgdXNlcjogVXNlclR5cGUpOiBQcm9taXNlPFVzZXJUeXBlPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdnZXRVc2VyJztcbiAgY29uc3Qge2VtYWlsLCBpZCwgcGhvbmUsIHVzZXJJZCwgdXNlcm5hbWV9ID0gcGFyc2VVc2VyKHVzZXIpO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHN9ID0gY29udGV4dDtcbiAgY29uc3Qge29iamVjdHM6IHNlbGVjdE9iamVjdHMsIHF1ZXJpZXM6IHNlbGVjdFF1ZXJpZXN9ID0gZ2V0VXNlck9wdGlvbmFsKGZpZWxkcyk7XG4gIGxldCBhcWxRdWVyeTogc3RyaW5nID0gJyc7XG5cbiAgaWYoaWQpIHtcbiAgICBhcWxRdWVyeSA9IGBMRVQgdSA9IERPQ1VNRU5UKFwiJHtpZH1cIilcbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgRklMVEVSIHUudXNlckFjY2VzcyA+IDBcbiAgICBSRVRVUk4gTUVSR0UodSwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcbiAgfSBlbHNlIGlmKHVzZXJuYW1lKSB7XG4gICAgYXFsUXVlcnkgPSBgRk9SIHUgSU4gdXNlcnNcbiAgICBGSUxURVIgdS51c2VybmFtZSA9PSBcIiR7dXNlcm5hbWV9XCJcbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgUkVUVVJOIE1FUkdFKHUsIHske3NlbGVjdE9iamVjdHMuam9pbignLCAnKX19KWA7XG4gIH0gZWxzZSBpZihlbWFpbCkge1xuICAgIGFxbFF1ZXJ5ID0gYEZPUiB1IElOIHVzZXJzXG4gICAgRklMVEVSIHUuZW1haWwgPT0gXCIke2VtYWlsfVwiXG4gICAgJHtzZWxlY3RRdWVyaWVzLmpvaW4oJ1xcbicpfVxuICAgIFJFVFVSTiBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuICB9IGVsc2UgaWYocGhvbmUpIHtcbiAgICBhcWxRdWVyeSA9IGBGT1IgdSBJTiB1c2Vyc1xuICAgIEZJTFRFUiB1LnBob25lID09IFwiJHtwaG9uZX1cIlxuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICBSRVRVUk4gTUVSR0UodSwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcbiAgfVxuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpXG4gICAgLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgLnRoZW4oKHVzZXIpID0+IHVzZXIpXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7aWQsIHVzZXJJZCwgdXNlcm5hbWV9LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICB9LCBlcnJvciwgY29udGV4dCkpO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFVzZXJzID0gKGNvbnRleHQ6IEFwaUNvbnRleHQsIG9wdGlvbnM/OiBVc2VyT3B0aW9ucyk6IFByb21pc2U8VXNlclR5cGVbXT4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnZ2V0VXNlckxpc3QnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHN9ID0gY29udGV4dDtcbiAgY29uc3Qge2xpbWl0LCB1c2VybmFtZX0gPSBwYXJzZVVzZXJPcHRpb25zKG9wdGlvbnMpO1xuICBjb25zdCB7b2JqZWN0czogc2VsZWN0T2JqZWN0cywgcXVlcmllczogc2VsZWN0UXVlcmllc30gPSBnZXRVc2VyT3B0aW9uYWwoZmllbGRzKTtcbiAgY29uc3QgZmlsdGVyQnk6IHN0cmluZ1tdID0gWyd1LnVzZXJBY2Nlc3MgPiAwJ107XG5cbiAgaWYodXNlcm5hbWUpIHtcbiAgICBmaWx0ZXJCeS5wdXNoKGBDT05UQUlOUyh1LnVzZXJuYW1lLCBcIiR7cGFyc2VVc2VybmFtZSh1c2VybmFtZSl9XCIpYCk7XG4gIH1cblxuICBjb25zdCBhcWxRdWVyeTogc3RyaW5nID0gYEZPUiB1IElOIHVzZXJzXG4gICAgRklMVEVSICR7ZmlsdGVyQnkuam9pbignICYmICcpfVxuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICAke2xpbWl0LmFxbH1cbiAgICBTT1JUIHUudXNlcm5hbWVcbiAgICBSRVRVUk4gTUVSR0UodSwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcblxuICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRdWVyeSlcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkgYXMgdW5rbm93biBhcyBVc2VyVHlwZVtdKVxuICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICBsb2dFcnJvcih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgICB9LCBlcnJvciwgY29udGV4dCk7XG5cbiAgICAgIHJldHVybiBbXSBhcyBVc2VyVHlwZVtdO1xuICAgIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFVzZXJzQnlSZWFjdGlvbnMgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHtyZWFjdGlvbnMgPSBbXSwgdXNlcm5hbWV9OiB7cmVhY3Rpb25zPzogc3RyaW5nW107IHVzZXJuYW1lPzogc3RyaW5nfSxcbiAgb3B0aW9ucz86IFVzZXJPcHRpb25zXG4pOiBQcm9taXNlPFVzZXJUeXBlW10+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2dldFVzZXJzQnlSZWFjdGlvbnMnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHMsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZH0gPSB7fX0gPSBjb250ZXh0O1xuICBjb25zdCBmb3JtYXRSZWFjdGlvbnM6IHN0cmluZ1tdID0gcmVhY3Rpb25zLm1hcCgocmVhY3Rpb25OYW1lOiBzdHJpbmcpID0+IHBhcnNlQ2hhcihyZWFjdGlvbk5hbWUsIDMyKS50b0xvd2VyQ2FzZSgpKTtcbiAgY29uc3Qge2xpbWl0fSA9IHBhcnNlVXNlck9wdGlvbnMob3B0aW9ucyk7XG4gIGNvbnN0IHtvYmplY3RzOiBzZWxlY3RPYmplY3RzLCBxdWVyaWVzOiBzZWxlY3RRdWVyaWVzfSA9IGdldFVzZXJPcHRpb25hbChmaWVsZHMpO1xuICBjb25zdCBmb3JtYXRTZXNzaW9uSWQ6IHN0cmluZyA9IGB1c2Vycy8ke3Nlc3Npb25JZH1gO1xuICBjb25zdCBmb3JtYXRVc2VybmFtZTogc3RyaW5nID0gcGFyc2VVc2VybmFtZSh1c2VybmFtZSk7XG4gIGNvbnN0IGZpbHRlckJ5OiBzdHJpbmdbXSA9IFtcbiAgICAndS51c2VyQWNjZXNzID4gMCcsXG4gICAgYFBPU0lUSU9OKCR7SlNPTi5zdHJpbmdpZnkoZm9ybWF0UmVhY3Rpb25zKX0sIExPV0VSKHIubmFtZSkpYFxuICBdO1xuXG4gIGlmKHVzZXJuYW1lKSB7XG4gICAgZmlsdGVyQnkucHVzaChgQ09OVEFJTlModS51c2VybmFtZSwgXCIke2Zvcm1hdFVzZXJuYW1lfVwiKWApO1xuICB9XG5cbiAgY29uc3QgYXFsUXVlcnk6IHN0cmluZyA9IGBGT1IgdSwgciBJTiBPVVRCT1VORCBcIiR7Zm9ybWF0U2Vzc2lvbklkfVwiIGhhc1JlYWN0aW9uXG4gICAgT1BUSU9OUyB7dmVydGV4Q29sbGVjdGlvbnM6IFwidXNlcnNcIn1cbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgRklMVEVSICR7ZmlsdGVyQnkuam9pbignICYmICcpfVxuICAgICR7bGltaXQuYXFsfVxuICAgIFJFVFVSTiBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSBhcyB1bmtub3duIGFzIFVzZXJUeXBlW10pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgICAgcmV0dXJuIFtdIGFzIFVzZXJUeXBlW107XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VXNlcnNCeVRhZ3MgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHt0YWdzLCB1c2VybmFtZX0sXG4gIG9wdGlvbnM/OiBVc2VyT3B0aW9uc1xuKTogUHJvbWlzZTxVc2VyVHlwZVtdPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdnZXRVc2Vyc0J5VGFncyc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWUsIGZpZWxkcywgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkfSA9IHt9fSA9IGNvbnRleHQ7XG4gIGNvbnN0IGZvcm1hdFRhZ3M6IHN0cmluZ1tdID0gdGFncz8ucmVkdWNlKChsaXN0OiBzdHJpbmdbXSwgdGFnTmFtZTogc3RyaW5nKSA9PiB7XG4gICAgaWYodGFnTmFtZSkge1xuICAgICAgbGlzdC5wdXNoKHBhcnNlQ2hhcih0YWdOYW1lLCAzMikudG9Mb3dlckNhc2UoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxpc3Q7XG4gIH0sIFtdKTtcbiAgY29uc3Qge2xpbWl0fSA9IHBhcnNlVXNlck9wdGlvbnMob3B0aW9ucyk7XG4gIGNvbnN0IHtvYmplY3RzOiBzZWxlY3RPYmplY3RzLCBxdWVyaWVzOiBzZWxlY3RRdWVyaWVzfSA9IGdldFVzZXJPcHRpb25hbChmaWVsZHMpO1xuICBjb25zdCBmb3JtYXRVc2VybmFtZTogc3RyaW5nID0gcGFyc2VVc2VybmFtZSh1c2VybmFtZSk7XG4gIGNvbnN0IGZpbHRlckJ5OiBzdHJpbmdbXSA9IFtcbiAgICBgdS5fa2V5ICE9IFwiJHtzZXNzaW9uSWR9XCJgLFxuICAgICd1LnVzZXJBY2Nlc3MgPiAwJ1xuICBdO1xuXG4gIGlmKHVzZXJuYW1lKSB7XG4gICAgZmlsdGVyQnkucHVzaChgQ09OVEFJTlModS51c2VybmFtZSwgXCIke2Zvcm1hdFVzZXJuYW1lfVwiKWApO1xuICB9XG5cbiAgY29uc3QgYXFsUXVlcnk6IHN0cmluZyA9IGBGT1IgdCBJTiB0YWdzXG4gICAgRklMVEVSIFBPU0lUSU9OKCR7SlNPTi5zdHJpbmdpZnkoZm9ybWF0VGFncyl9LCBMT1dFUih0Lm5hbWUpKVxuICAgIEZPUiB1LCBpdCBJTiBPVVRCT1VORCB0IGlzVGFnZ2VkXG4gICAgT1BUSU9OUyB7YmZzOiB0cnVlLCB1bmlxdWVWZXJ0aWNlczogXCJnbG9iYWxcIiwgdmVydGV4Q29sbGVjdGlvbnM6IFwidXNlcnNcIn1cbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgRklMVEVSICR7ZmlsdGVyQnkuam9pbignICYmICcpfVxuICAgICR7bGltaXQuYXFsfVxuICAgIFJFVFVSTiBESVNUSU5DVCBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSBhcyB1bmtub3duIGFzIFVzZXJUeXBlW10pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgICAgcmV0dXJuIFtdIGFzIFVzZXJUeXBlW107XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VXNlcnNCeUxhdGVzdCA9IChjb250ZXh0OiBBcGlDb250ZXh0LCB7dXNlcm5hbWV9LCBvcHRpb25zPzogVXNlck9wdGlvbnMpOiBQcm9taXNlPFVzZXJUeXBlW10+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2dldFVzZXJzQnlMYXRlc3QnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHMsIHNlc3Npb246IHt1c2VySWR9ID0ge319ID0gY29udGV4dDtcbiAgY29uc3Qge2xpbWl0fSA9IHBhcnNlVXNlck9wdGlvbnMob3B0aW9ucyk7XG4gIGNvbnN0IGZpbHRlciA9IFtcbiAgICAndS5faWQgIT0gc2Vzc2lvbi5faWQnLFxuICAgICd1LnVzZXJBY2Nlc3MgPiAwJ1xuICBdO1xuICBjb25zdCB7b2JqZWN0czogc2VsZWN0T2JqZWN0cywgcXVlcmllczogc2VsZWN0UXVlcmllc30gPSBnZXRVc2VyT3B0aW9uYWwoZmllbGRzKTtcblxuICBpZih1c2VybmFtZSkge1xuICAgIGZpbHRlci5wdXNoKGBDT05UQUlOUyh1LnVzZXJuYW1lLCBcIiR7cGFyc2VVc2VybmFtZSh1c2VybmFtZSl9XCIpYCk7XG4gIH1cblxuICAvLyBHZXQgZGF0YSBmcm9tIGRhdGFiYXNlXG4gIGNvbnN0IGFxbFF1ZXJ5OiBzdHJpbmcgPSBgRk9SIHUgSU4gdXNlcnNcbiAgICBMRVQgc2Vzc2lvbiA9IERPQ1VNRU5UKFwidXNlcnMvJHt1c2VySWR9XCIpXG4gICAgRklMVEVSICR7ZmlsdGVyLmpvaW4oJyAmJiAnKX1cbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgTEVUIGRpc3RhbmNlID0gRElTVEFOQ0UodS5sYXRpdHVkZSB8fCAwLCB1LmxvbmdpdHVkZSB8fCAwLCBzZXNzaW9uLmxhdGl0dWRlIHx8IDAsIHNlc3Npb24ubG9uZ2l0dWRlIHx8IDApXG4gICAgJHtsaW1pdC5hcWx9XG4gICAgU09SVCBkaXN0YW5jZSBBU0MsIHUuYWRkZWQgREVTQ1xuICAgIFJFVFVSTiBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSBhcyB1bmtub3duIGFzIFVzZXJUeXBlW10pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgICAgcmV0dXJuIFtdIGFzIFVzZXJUeXBlW107XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VXNlcnNCeUNvbm5lY3Rpb24gPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHt1c2VySWR9OiBVc2VyVHlwZSxcbiAgb3B0aW9ucz86IFVzZXJPcHRpb25zXG4pOiBQcm9taXNlPFVzZXJUeXBlW10+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2dldFVzZXJzQnlDb25uZWN0aW9uJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZSwgZmllbGRzfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtsaW1pdCwgdXNlcm5hbWV9ID0gcGFyc2VVc2VyT3B0aW9ucyhvcHRpb25zKTtcbiAgY29uc3Qge29iamVjdHM6IHNlbGVjdE9iamVjdHMsIHF1ZXJpZXM6IHNlbGVjdFF1ZXJpZXN9ID0gZ2V0VXNlck9wdGlvbmFsKGZpZWxkcyk7XG4gIGNvbnN0IGZvcm1hdFVzZXJJZDogc3RyaW5nID0gcGFyc2VBcmFuZ29JZChgdXNlcnMvJHt1c2VySWR9YCk7XG4gIGNvbnN0IGZpbHRlckJ5OiBzdHJpbmdbXSA9IFtcbiAgICAndS51c2VyQWNjZXNzID4gMCdcbiAgXTtcblxuICBpZih1c2VybmFtZSkge1xuICAgIGZpbHRlckJ5LnB1c2goYENPTlRBSU5TKHUudXNlcm5hbWUsIFwiJHtwYXJzZVVzZXJuYW1lKHVzZXJuYW1lKX1cIilgKTtcbiAgfVxuXG4gIGNvbnN0IGFxbFF1ZXJ5OiBzdHJpbmcgPSBgRk9SIGN1IElOIHVzZXJzXG4gICAgTEVUIHNlc3Npb24gPSBET0NVTUVOVChcIiR7Zm9ybWF0VXNlcklkfVwiKVxuICAgIEZPUiB1LCBjb25uZWN0aW9uIElOIE9VVEJPVU5EIGN1IGhhc0Nvbm5lY3Rpb25cbiAgICBPUFRJT05TIHtiZnM6IHRydWUsIHVuaXF1ZVZlcnRpY2VzOiBcImdsb2JhbFwiLCB2ZXJ0ZXhDb2xsZWN0aW9uczogXCJ1c2Vyc1wifVxuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICBGSUxURVIgJHtmaWx0ZXJCeS5qb2luKCcgJiYgJyl9XG4gICAgJHtsaW1pdC5hcWx9XG4gICAgUkVUVVJOIERJU1RJTkNUIE1FUkdFKHUsIHske3NlbGVjdE9iamVjdHMuam9pbignLCAnKX19KWA7XG5cbiAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoYXFsUXVlcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpIGFzIHVua25vd24gYXMgVXNlclR5cGVbXSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuXG4gICAgICByZXR1cm4gW10gYXMgVXNlclR5cGVbXTtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWZyZXNoU2Vzc2lvbiA9ICh7ZXhwaXJlcywgdG9rZW59KTogU2Vzc2lvblRva2VuIHwgU2Vzc2lvbkVycm9yID0+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCB7dXNlcklkLCB1c2VybmFtZSwgdXNlckFjY2Vzc30gPSBnZXRTZXNzaW9uKHRva2VuKTtcbiAgICByZXR1cm4gY3JlYXRlVG9rZW4odXNlcklkLCB1c2VybmFtZSwgdXNlckFjY2VzcywgZXhwaXJlcyk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICB0aHJvdyBlcnJvcjsgLy8gUmUtdGhyb3cgdGhlIGVycm9yIGZyb20gZ2V0U2Vzc2lvblxuICB9XG59O1xuXG5leHBvcnQgY29uc3Qgc2lnbkluID0gYXN5bmMgKGNvbnRleHQ6IEFwaUNvbnRleHQsIGFyZ3MpOiBQcm9taXNlPFNlc3Npb25Ub2tlbiB8IG51bGw+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ3NpZ25Jbic7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWV9ID0gY29udGV4dDtcbiAgY29uc3Qge2VtYWlsLCBleHBpcmVzLCBwYXNzd29yZCwgcGhvbmUsIHVzZXJuYW1lfSA9IGFyZ3M7XG4gIGNvbnN0IGZvcm1hdEVtYWlsOiBzdHJpbmcgPSBwYXJzZUVtYWlsKGVtYWlsKTtcbiAgY29uc3QgZm9ybWF0VXNlcm5hbWU6IHN0cmluZyA9IHBhcnNlVXNlcm5hbWUodXNlcm5hbWUpO1xuICBjb25zdCBmb3JtYXRQYXNzd29yZDogc3RyaW5nID0gcGFyc2VQYXNzd29yZChwYXNzd29yZCk7XG4gIGNvbnN0IGZvcm1hdFBob25lOiBzdHJpbmcgPSBwYXJzZVBob25lKHBob25lKTtcbiAgY29uc3QgZm9ybWF0RXhwaXJlczogbnVtYmVyID0gcGFyc2VOdW0oZXhwaXJlcykgfHwgMTU7XG5cbiAgaWYoKCFmb3JtYXRVc2VybmFtZSAmJiAhZm9ybWF0RW1haWwgJiYgIWZvcm1hdFBob25lKSB8fCAhZm9ybWF0UGFzc3dvcmQpIHtcbiAgICB0aHJvdyBsb2dFeGNlcHRpb24oe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHt1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5JTlZBTElEX0FSR1VNRU5UU1xuICAgIH0sIGNvbnRleHQpO1xuICB9XG5cbiAgY29uc3QgZmlsdGVyczogc3RyaW5nW10gPSBbXTtcblxuICBpZihmb3JtYXRFbWFpbCkge1xuICAgIGZpbHRlcnMucHVzaChgdS5lbWFpbCA9PSBcIiR7Zm9ybWF0RW1haWx9XCJgKTtcbiAgfVxuXG4gIGlmKGZvcm1hdFBob25lKSB7XG4gICAgZmlsdGVycy5wdXNoKGB1LnBob25lID09ICR7Zm9ybWF0UGhvbmV9YCk7XG4gIH1cblxuICBpZihmb3JtYXRVc2VybmFtZSkge1xuICAgIGZpbHRlcnMucHVzaChgdS51c2VybmFtZSA9PSBcIiR7Zm9ybWF0VXNlcm5hbWV9XCJgKTtcbiAgfVxuXG4gIGNvbnN0IGNoZWNrUXVlcnk6IHN0cmluZyA9IGBGT1IgdSBJTiB1c2Vyc1xuICAgIEZJTFRFUiAke2ZpbHRlcnMuam9pbignIHx8ICcpfVxuICAgIExJTUlUIDFcbiAgICBSRVRVUk4gdWA7XG5cbiAgbGV0IGNoZWNrVXNlcjogVXNlclR5cGU7XG5cbiAgdHJ5IHtcbiAgICBjaGVja1VzZXIgPSBhd2FpdCB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGNoZWNrUXVlcnkpLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICB0aHJvdyBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge3VzZXJuYW1lOiBmb3JtYXRVc2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgfVxuXG4gIGlmKCFjaGVja1VzZXIpIHtcbiAgICB0aHJvdyBsb2dFeGNlcHRpb24oe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHt1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5JTlZBTElEX0FVVEhFTlRJQ0FUSU9OXG4gICAgfSwgY29udGV4dCk7XG4gIH1cblxuICBjb25zdCB7X2tleTogdXNlcklkLCBwYXNzd29yZDogdmFsaWRQYXNzd29yZCwgc2FsdCwgdXNlckFjY2Vzc30gPSBjaGVja1VzZXIgYXMgVXNlclR5cGU7XG4gIGNvbnN0IGF1dGhQYXNzd29yZDogc3RyaW5nID0gY3JlYXRlUGFzc3dvcmQoZm9ybWF0UGFzc3dvcmQsIHNhbHQpO1xuXG4gIGNvbnNvbGUubG9nKHtcbiAgICBjcmVhdGVQYXNzd29yZCxcbiAgICBhdXRoUGFzc3dvcmQsXG4gICAgdmFsaWRQYXNzd29yZCxcbiAgICBmb3JtYXRQYXNzd29yZCxcbiAgICBzYWx0XG4gIH0pO1xuXG4gIGlmKHZhbGlkUGFzc3dvcmQgIT09IGF1dGhQYXNzd29yZCkge1xuICAgIHRocm93IGxvZ0V4Y2VwdGlvbih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge3VzZXJBY2Nlc3MsIHVzZXJJZCwgdXNlcm5hbWV9LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuSU5WQUxJRF9BVVRIRU5USUNBVElPTlxuICAgIH0sIGNvbnRleHQpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCB0b2tlbiA9IGNyZWF0ZVRva2VuKHVzZXJJZCB8fCAnJywgdXNlcm5hbWUgfHwgJycsIHVzZXJBY2Nlc3MsIGZvcm1hdEV4cGlyZXMpO1xuXG4gICAgcmV0dXJuIHRva2VuO1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgdGhyb3cgbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHt1c2VySWQsIHVzZXJuYW1lfSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3Qgc2lnbk91dCA9IGFzeW5jIChjb250ZXh0OiBBcGlDb250ZXh0KTogUHJvbWlzZTxib29sZWFuPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdzaWduT3V0JztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZSwgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkLCB1c2VybmFtZX0gPSB7fX0gPSBjb250ZXh0O1xuICBjb25zdCB1c2VyRG9jSWQ6IHN0cmluZyA9IGB1c2Vycy8ke3Nlc3Npb25JZH1gO1xuXG4gIGNvbnN0IHVwZGF0ZSA9IHtcbiAgICBsYXN0T25saW5lOiBEYXRlLm5vdygpLFxuICAgIHNlc3Npb25JZDogbnVsbFxuICB9O1xuICBjb25zdCBzZXNzaW9uUXVlcnk6IEFxbFF1ZXJ5ID0gYXFsYExFVCB1ID0gRE9DVU1FTlQoJHt1c2VyRG9jSWR9KVxuICAgIFVQREFURSB1IFdJVEggJHt1cGRhdGV9IElOIHVzZXJzXG4gICAgTElNSVQgMVxuICAgIFJFVFVSTiBORVdgO1xuXG4gIHRyeSB7XG4gICAgYXdhaXQgdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShzZXNzaW9uUXVlcnkpLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge3VzZXJJZDogc2Vzc2lvbklkLCB1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEFjdGl2ZVVzZXJDb3VudCA9IChjb250ZXh0OiBBcGlDb250ZXh0KTogUHJvbWlzZTxudW1iZXI+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2dldEFjdGl2ZVVzZXJDb3VudCc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWV9ID0gY29udGV4dDtcbiAgY29uc3QgY291bnRRdWVyeTogQXFsUXVlcnkgPSBhcWxgTEVUIGRvY3MgPSAoXG4gICAgRk9SIHUgSU4gdXNlcnNcbiAgICBGSUxURVIgdS5hY3RpdmUgPT0gdHJ1ZVxuICAgIFJFVFVSTiB1XG4gIClcbiAgUkVUVVJOIExFTkdUSChkb2NzKWA7XG5cbiAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoY291bnRRdWVyeSlcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKVxuICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgIHRocm93IGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRVc2VyQnlUb2tlbiA9IChjb250ZXh0OiBBcGlDb250ZXh0LCB0b2tlbjogc3RyaW5nKTogUHJvbWlzZTxVc2VyVHlwZT4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnZ2V0VXNlckJ5VG9rZW4nO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHt1c2VySWR9ID0gZ2V0U2Vzc2lvbih0b2tlbik7XG4gIGNvbnN0IHVzZXJEb2NJZCA9IHBhcnNlQXJhbmdvSWQoYHVzZXJzLyR7dXNlcklkfWApO1xuICBjb25zdCBhcWxRdWVyeTogQXFsUXVlcnkgPSBhcWxgTEVUIHUgPSBET0NVTUVOVChcIiR7dXNlckRvY0lkfVwiKSBSRVRVUk4gdWA7XG5cbiAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSlcbiAgICAucXVlcnkoYXFsUXVlcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgdGhyb3cgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICBwYXJhbXM6IHt1c2VySWR9LFxuICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICAgIH0pO1xufTsiXSwibmFtZXMiOlsicGFyc2VOdW0iLCJjcmVhdGVIYXNoIiwiY3JlYXRlUGFzc3dvcmQiLCJwYXJzZUFyYW5nb0lkIiwicGFyc2VDaGFyIiwicGFyc2VFbWFpbCIsInBhcnNlUGFzc3dvcmQiLCJwYXJzZVBob25lIiwicGFyc2VVc2VybmFtZSIsImFxbCIsIkRhdGVUaW1lIiwiU3RyaXBlIiwicGFyc2VVc2VyIiwiQ29uZmlnIiwiRXJyb3JUeXBlcyIsImxvZ0Vycm9yIiwibG9nRXhjZXB0aW9uIiwiZ2V0RG9jSWQiLCJnZXRMaW1pdCIsInNlbGVjdFJlYWN0aW9uQ291bnRCeVR5cGUiLCJ1c2VEYiIsImRldGVjdExhbmd1YWdlIiwiZ2V0U2Vzc2lvbiIsInNldFNlc3Npb24iLCJzZW5kRW1haWwiLCJzZW5kU21zIiwiZXZlbnRDYXRlZ29yeSIsIlNUUklQRV9BUElfVkVSU0lPTiIsIlVzZXJBY2Nlc3MiLCJjcmVhdGVUb2tlbiIsInVzZXJJZCIsInVzZXJuYW1lIiwidXNlckFjY2VzcyIsImV4cGlyZXNJbk1pbnV0ZXMiLCJub3ciLCJsb2NhbCIsInNlc3Npb25FeHBpcmVzIiwicGx1cyIsIm1pbnV0ZXMiLCJpYXQiLCJNYXRoIiwiZmxvb3IiLCJ0b1NlY29uZHMiLCJleHAiLCJ0b2tlbiIsImV4cGlyZXMiLCJ0b01pbGxpcyIsImlzc3VlZCIsImdldFVzZXJPcHRpb25hbCIsImZpZWxkcyIsInJlZHVjZSIsInNlbGVjdHMiLCJmaWVsZCIsImluY2x1ZGVzIiwib2JqZWN0cyIsInF1ZXJpZXMiLCJwYXJzZVVzZXJPcHRpb25zIiwib3B0aW9ucyIsImZyb20iLCJ0byIsImxpbWl0IiwiYWRkVXNlciIsImNvbnRleHQiLCJ1c2VyIiwiYWN0aW9uIiwiZGF0YWJhc2VOYW1lIiwibGFuZ3VhZ2VDb250ZXh0IiwiY29uZmlybSIsIl9jb25maXJtIiwibmV3VXNlciIsImVtYWlsIiwicGFzc3dvcmQiLCJwaG9uZSIsIl9rZXkiLCJfaWQiLCJpbnNlcnRVc2VyIiwiaGFzUGFzc3dvcmQiLCJoYXNVc2VybmFtZSIsImNhdGVnb3J5IiwicGFyYW1zIiwidmFsdWUiLCJJTlZBTElEX0FSR1VNRU5UUyIsImhhc2hJZCIsInNhbHQiLCJlbmNyeXB0ZWRQYXNzd29yZCIsImZpbHRlcnMiLCJwdXNoIiwiY2hlY2tRdWVyeSIsImpvaW4iLCJleGlzdGluZ1VzZXJzIiwicXVlcnkiLCJ0aGVuIiwiY3Vyc29yIiwiYWxsIiwibGVuZ3RoIiwiRVhJU1RJTkdfSVRFTSIsImVycm9yIiwiREFUQUJBU0VfRVJST1IiLCJwaG9uZUNvdW50cnlDb2RlIiwicmVwbGFjZSIsInN1YnN0cmluZyIsImxvY2FsZSIsInVzZXJQcmVmZXJlbmNlIiwidmVyaWZpZWRFbWFpbENvZGUiLCJyYW5kb20iLCJ2ZXJpZmllZFNtc0NvZGUiLCJpbnNlcnQiLCJhZGRlZCIsIkRhdGUiLCJtb2RpZmllZCIsInZlcmlmaWVkRW1haWwiLCJ2ZXJpZmllZFBob25lIiwiaW5zZXJ0UXVlcnkiLCJuZXh0IiwiY2F0Y2giLCJ1cGRhdGVVc2VyIiwidXBkYXRlZFVzZXIiLCJ0YWdzIiwidXBkYXRlIiwiaWQiLCJ1c2VyUXVlcnkiLCJkYXRhYmFzZSIsInRhZ0NvbGxlY3Rpb24iLCJjb2xsZWN0aW9uIiwiUHJvbWlzZSIsIm1hcCIsInRhZ0RvY0lkIiwibmFtZSIsInRhZ1F1ZXJ5IiwidGFnRWRnZSIsImVkZ2UiLCJfZnJvbSIsIl90byIsInNhdmUiLCJyZXR1cm5OZXciLCJmb3Jnb3RQYXNzd29yZCIsImFxbFF1ZXJ5IiwiY29kZUV4cGlyZXMiLCJjb2RlIiwidXNlckRvY0lkIiwidGV4dCIsInZlcmlmaWVkRW1haWxFeHBpcmVzIiwidmVyaWZpZWRQaG9uZUV4cGlyZXMiLCJ1cGRhdGVRdWVyeSIsInJlc2V0UGFzc3dvcmQiLCJ0eXBlIiwiZm9ybWF0UGFzc3dvcmQiLCJjb25maXJtQ29kZSIsImlzU21zIiwiZm9ybWF0dGVkVmFsdWUiLCJmaWx0ZXJCeVR5cGUiLCJkZWxldGVVc2VyIiwic3RyaXBlQ2xpZW50IiwiZ2V0IiwiYXBpVmVyc2lvbiIsInR5cGVzY3JpcHQiLCJkZWxldGVkVXNlciIsImN1c3RvbWVycyIsImRlbCIsInN0cmlwZUN1c3RvbWVySWQiLCJhY2NvdW50cyIsInN0cmlwZUFjY291bnRJZCIsImRlYWN0aXZhdGVVc2VyIiwidXBkYXRlZCIsImdldERpc3BsYXlOYW1lIiwiZmlyc3QiLCJsYXN0IiwiZnVsbG5hbWUiLCJ0cmltIiwiZ2V0U2Vzc2lvblVzZXIiLCJzZXNzaW9uIiwic2Vzc2lvbklkIiwic2VsZWN0T2JqZWN0cyIsInNlbGVjdFF1ZXJpZXMiLCJmb3JtYXRTZXNzaW9uSWQiLCJnZXRVc2VyIiwiZ2V0VXNlcnMiLCJmaWx0ZXJCeSIsImdldFVzZXJzQnlSZWFjdGlvbnMiLCJyZWFjdGlvbnMiLCJmb3JtYXRSZWFjdGlvbnMiLCJyZWFjdGlvbk5hbWUiLCJ0b0xvd2VyQ2FzZSIsImZvcm1hdFVzZXJuYW1lIiwiSlNPTiIsInN0cmluZ2lmeSIsImdldFVzZXJzQnlUYWdzIiwiZm9ybWF0VGFncyIsImxpc3QiLCJ0YWdOYW1lIiwiZ2V0VXNlcnNCeUxhdGVzdCIsImZpbHRlciIsImdldFVzZXJzQnlDb25uZWN0aW9uIiwiZm9ybWF0VXNlcklkIiwicmVmcmVzaFNlc3Npb24iLCJzaWduSW4iLCJhcmdzIiwiZm9ybWF0RW1haWwiLCJmb3JtYXRQaG9uZSIsImZvcm1hdEV4cGlyZXMiLCJjaGVja1VzZXIiLCJJTlZBTElEX0FVVEhFTlRJQ0FUSU9OIiwidmFsaWRQYXNzd29yZCIsImF1dGhQYXNzd29yZCIsImNvbnNvbGUiLCJsb2ciLCJzaWduT3V0IiwibGFzdE9ubGluZSIsInNlc3Npb25RdWVyeSIsImdldEFjdGl2ZVVzZXJDb3VudCIsImNvdW50UXVlcnkiLCJnZXRVc2VyQnlUb2tlbiJdLCJtYXBwaW5ncyI6IkFBQUE7OztDQUdDLEdBQ0QsU0FBUUEsUUFBUSxRQUFPLCtCQUErQjtBQUN0RCxTQUNFQyxVQUFVLEVBQ1ZDLGNBQWMsRUFDZEMsYUFBYSxFQUNiQyxTQUFTLEVBQ1RDLFVBQVUsRUFDVkMsYUFBYSxFQUNiQyxVQUFVLEVBQ1ZDLGFBQWEsUUFDUiwrQkFBK0I7QUFDdEMsU0FBUUMsR0FBRyxRQUFPLFdBQVc7QUFDN0IsU0FBUUMsUUFBUSxRQUFPLFFBQVE7QUFDL0IsT0FBT0MsWUFBWSxTQUFTO0FBRTVCLFNBQVFDLFNBQVMsUUFBTyw2QkFBNkI7QUFDckQsU0FBUUMsTUFBTSxRQUFPLGVBQWU7QUFDcEMsU0FBUUMsVUFBVSxRQUEwQiwwQkFBMEI7QUFDdEUsU0FBUUMsUUFBUSxFQUFFQyxZQUFZLFFBQU8sNkJBQTZCO0FBQ2xFLFNBQVFDLFFBQVEsRUFBRUMsUUFBUSxFQUFFQyx5QkFBeUIsRUFBRUMsS0FBSyxRQUFPLDRCQUE0QjtBQUMvRixTQUFRQyxjQUFjLFFBQU8sZ0NBQWdDO0FBQzdELFNBQVFDLFVBQVUsRUFBRUMsVUFBVSxRQUEwQiwyQkFBMkI7QUFDbkYsU0FBUUMsU0FBUyxRQUFPLGFBQWE7QUFDckMsU0FBUUMsT0FBTyxRQUFPLFdBQVc7QUFPakMsTUFBTUMsZ0JBQWdCO0FBQ3RCLE1BQU1DLHFCQUFxQjtBQVEzQixPQUFPLElBQUEsQUFBS0Msb0NBQUFBOzs7Ozs7V0FBQUE7TUFNWDtBQUVELE9BQU8sTUFBTUMsY0FBYyxDQUN6QkMsUUFDQUMsV0FBbUIsRUFBRSxFQUNyQkMsYUFBcUIsQ0FBQyxFQUN0QkMsbUJBQTJCLEVBQUU7SUFFN0IsTUFBTUMsTUFBZ0J4QixTQUFTeUIsS0FBSztJQUNwQyxNQUFNQyxpQkFBMkJGLElBQUlHLElBQUksQ0FBQztRQUFDQyxTQUFTTDtJQUFnQjtJQUNwRSxNQUFNTSxNQUFjQyxLQUFLQyxLQUFLLENBQUNQLElBQUlRLFNBQVM7SUFDNUMsTUFBTUMsTUFBY0gsS0FBS0MsS0FBSyxDQUFDTCxlQUFlTSxTQUFTO0lBQ3ZELE1BQU1FLFFBQVFyQixXQUFXO1FBQ3ZCb0I7UUFDQUo7UUFDQVA7UUFDQUY7UUFDQUM7SUFDRjtJQUVBLE9BQU87UUFDTGMsU0FBU1QsZUFBZVUsUUFBUTtRQUNoQ0MsUUFBUWIsSUFBSVksUUFBUTtRQUNwQkY7UUFDQWQ7UUFDQUM7SUFDRjtBQUNGLEVBQUU7QUFPRixPQUFPLE1BQU1pQixrQkFBa0IsQ0FBQ0MsU0FBbUIsRUFBRSxHQUNuREEsT0FBT0MsTUFBTSxDQUFDLENBQUNDLFNBQTRCQztRQUN6QyxJQUFHQSxNQUFNQyxRQUFRLENBQUMsVUFBVTtZQUMxQixPQUFPbEMsMEJBQTBCLFNBQVMsS0FBS2lDLE9BQU9EO1FBQ3hEO1FBRUEsT0FBT0E7SUFDVCxHQUFHO1FBQUNHLFNBQVMsRUFBRTtRQUFFQyxTQUFTLEVBQUU7SUFBQSxHQUFHO0FBRWpDLE9BQU8sTUFBTUMsbUJBQW1CLENBQUNDLFVBQXVCLENBQUMsQ0FBQztJQUN4RCxNQUFNLEVBQ0pDLE9BQU8sQ0FBQyxFQUNSQyxLQUFLLEVBQUUsRUFDUixHQUFHRjtJQUNKLE1BQU1HLFFBQVExQyxTQUFTd0MsTUFBTUM7SUFFN0IsT0FBTztRQUNMLEdBQUdGLE9BQU87UUFDVkc7SUFDRjtBQUNGLEVBQUU7QUFFRixPQUFPLE1BQU1DLFVBQVUsT0FBT0MsU0FBcUJDO0lBQ2pELE1BQU1DLFNBQVM7SUFDZixNQUFNLEVBQUNDLFlBQVksRUFBRUMsZUFBZSxFQUFDLEdBQUdKO0lBQ3hDLE1BQU0sRUFBQ0ssU0FBU0MsUUFBUSxFQUFFLEdBQUdDLFNBQVEsR0FBR047SUFDeEMsTUFBTSxFQUFDTyxLQUFLLEVBQUVDLFFBQVEsRUFBRUMsS0FBSyxFQUFFekMsUUFBUSxFQUFFRCxNQUFNLEVBQUUyQyxJQUFJLEVBQUVDLEdBQUcsRUFBRSxHQUFHQyxZQUFXLEdBQUcvRCxVQUFVeUQ7SUFDdkYsTUFBTU8sY0FBYyxDQUFDLENBQUNMO0lBQ3RCLE1BQU1NLGNBQWMsQ0FBQyxDQUFDOUMsWUFBWSxDQUFDLENBQUN5QyxTQUFTLENBQUMsQ0FBQ0Y7SUFFL0MsSUFBRyxDQUFDTSxlQUFlLENBQUNDLGFBQWE7UUFDL0I3RCxhQUFhO1lBQ1hnRDtZQUNBYyxVQUFVcEQ7WUFDVnFELFFBQVE7Z0JBQUNoRDtZQUFRO1lBQ2pCaUQsT0FBT2xFLFdBQVdtRSxpQkFBaUI7UUFDckMsR0FBR25CO1FBRUgsT0FBTztJQUNUO0lBRUEsTUFBTW9CLFNBQVNuRCxZQUFZeUMsU0FBU0Y7SUFDcEMsTUFBTWEsT0FBZWxGLFdBQVcsR0FBR2lGLFNBQVNYLFVBQVUsRUFBRTtJQUN4RCxNQUFNYSxvQkFBb0JsRixlQUFlcUUsVUFBVVk7SUFDbkQsTUFBTUUsVUFBb0IsRUFBRTtJQUU1QixJQUFHdEQsVUFBVTtRQUNYc0QsUUFBUUMsSUFBSSxDQUFDLENBQUMsZUFBZSxFQUFFdkQsU0FBUyxDQUFDLENBQUM7SUFDNUM7SUFFQSxJQUFHdUMsT0FBTztRQUNSZSxRQUFRQyxJQUFJLENBQUMsQ0FBQyxZQUFZLEVBQUVoQixNQUFNLENBQUMsQ0FBQztJQUN0QztJQUVBLElBQUdFLE9BQU87UUFDUmEsUUFBUUMsSUFBSSxDQUFDLENBQUMsV0FBVyxFQUFFZCxPQUFPO0lBQ3BDO0lBRUEsTUFBTWUsYUFBcUIsQ0FBQztXQUNuQixFQUFFRixRQUFRRyxJQUFJLENBQUMsUUFBUTs7WUFFdEIsQ0FBQztJQUVYLElBQUk7UUFDRixNQUFNQyxnQkFBZ0IsTUFBTXJFLE1BQU02QyxjQUFjeUIsS0FBSyxDQUFDSCxZQUFZSSxJQUFJLENBQUMsQ0FBQ0MsU0FBV0EsT0FBT0MsR0FBRztRQUU3RixJQUFHSixjQUFjSyxNQUFNLEVBQUU7WUFDdkIsTUFBTTlFLGFBQWE7Z0JBQ2pCZ0Q7Z0JBQ0FjLFVBQVVwRDtnQkFDVnFELFFBQVE7b0JBQ05UO29CQUNBRTtvQkFDQXpDO2dCQUNGO2dCQUNBaUQsT0FBT2xFLFdBQVdpRixhQUFhO1lBQ2pDLEdBQUdqQztRQUNMO0lBQ0YsRUFBRSxPQUFNa0MsT0FBTztRQUNiLE1BQU1qRixTQUFTO1lBQ2JpRDtZQUNBYyxVQUFVcEQ7WUFDVnFELFFBQVE7Z0JBQUNUO2dCQUFPRTtnQkFBT3pDO1lBQVE7WUFDL0JpRCxPQUFPbEUsV0FBV21GLGNBQWM7UUFDbEMsR0FBR0QsT0FBT2xDO0lBQ1o7SUFFQSxNQUFNb0MsbUJBQW1CMUIsT0FBTzJCLFFBQVEsT0FBTyxJQUFJQyxVQUFVLEdBQUc7SUFDaEUsTUFBTUMsU0FBU2hGLGVBQWU7UUFDNUIsR0FBRzZDLGVBQWU7UUFDbEJnQyxrQkFBa0JBLG9CQUFvQjtRQUN0Q0ksZ0JBQWdCM0IsV0FBVzBCLE1BQU0sSUFBSTtJQUN2QztJQUNBLE1BQU1FLG9CQUE0Qi9ELEtBQUtDLEtBQUssQ0FBQyxTQUFVRCxLQUFLZ0UsTUFBTSxLQUFLO0lBQ3ZFLE1BQU1DLGtCQUEwQmpFLEtBQUtDLEtBQUssQ0FBQyxTQUFVRCxLQUFLZ0UsTUFBTSxLQUFLO0lBRXJFLE1BQU1FLFNBQW1CO1FBQ3ZCLEdBQUcvQixVQUFVO1FBQ2JGLE1BQU14RSxXQUFXOEI7UUFDakI0RSxPQUFPQyxLQUFLMUUsR0FBRztRQUNmb0M7UUFDQStCO1FBQ0FRLFVBQVVELEtBQUsxRSxHQUFHO1FBQ2xCcUMsVUFBVWE7UUFDVlo7UUFDQVc7UUFDQW5ELFlBQVk7UUFDWkQ7UUFDQStFLGVBQWU7UUFDZlA7UUFDQVEsZUFBZTtRQUNmTjtJQUNGO0lBRUEsTUFBTU8sY0FBd0J2RyxHQUFHLENBQUMsT0FBTyxFQUFFaUcsT0FBTyxvQkFBb0IsQ0FBQztJQUV2RSxPQUFPLE1BQU10RixNQUFNNkMsY0FBY3lCLEtBQUssQ0FBQ3NCLGFBQ3BDckIsSUFBSSxDQUFDLENBQUNDLFNBQVdBLE9BQU9xQixJQUFJLElBQzVCQyxLQUFLLENBQUMsQ0FBQ2xCO1FBQ04sTUFBTWpGLFNBQVM7WUFDYmlEO1lBQ0FjLFVBQVVwRDtZQUNWcUQsUUFBUTtnQkFBQ2hEO1lBQVE7WUFDakJpRCxPQUFPbEUsV0FBV21GLGNBQWM7UUFDbEMsR0FBR0QsT0FBT2xDO0lBQ1o7QUFDSixFQUFFO0FBRUYsT0FBTyxNQUFNcUQsYUFBYSxPQUFPckQsU0FBcUJDO0lBQ3BELE1BQU1DLFNBQVM7SUFDZixNQUFNLEVBQUNDLFlBQVksRUFBQyxHQUFHSDtJQUN2QixNQUFNc0QsY0FBY3hHLFVBQVVtRDtJQUM5QixNQUFNLEVBQUNVLElBQUksRUFBRUMsR0FBRyxFQUFFMkMsT0FBTyxFQUFFLEVBQUUsR0FBR0MsUUFBTyxHQUFHRjtJQUMxQyxNQUFNLEVBQUNHLEVBQUUsRUFBQyxHQUFHSDtJQUViLE1BQU1JLFlBQXNCL0csR0FBRyxDQUFDLGlCQUFpQixFQUFFOEcsR0FBRztrQkFDdEMsRUFBRUQsT0FBTztjQUNiLENBQUM7SUFDYixJQUFJO1FBQ0YsTUFBTUcsV0FBV3JHLE1BQU02QztRQUN2QixNQUFNbUQsY0FBYyxNQUFNSyxTQUFTL0IsS0FBSyxDQUFDOEIsV0FBVzdCLElBQUksQ0FBQyxDQUFDQyxTQUFXQSxPQUFPcUIsSUFBSTtRQUNoRixNQUFNUyxnQkFBZ0NELFNBQVNFLFVBQVUsQ0FBQztRQUUxRCxNQUFNQyxRQUFRL0IsR0FBRyxDQUFDd0IsS0FBS1EsR0FBRyxDQUFDLENBQUMsRUFBQ04sSUFBSU8sUUFBUSxFQUFFQyxJQUFJLEVBQUM7WUFDOUMsTUFBTUMsV0FBcUJ2SCxHQUFHLENBQUM7MkJBQ1YsRUFBRXFILFNBQVMsY0FBYyxFQUFFUCxHQUFHLGVBQWUsRUFBRVEsS0FBSzs7aUJBRTlELENBQUM7WUFFWixPQUFPTixTQUFTL0IsS0FBSyxDQUFDc0MsVUFDbkJyQyxJQUFJLENBQUMsQ0FBQ0MsU0FBV0EsT0FBT3FCLElBQUksSUFDNUJ0QixJQUFJLENBQUMsQ0FBQ3NDO2dCQUNMLElBQUcsQ0FBQyxDQUFDQSxTQUFTO29CQUNaLE9BQU9BO2dCQUNUO2dCQUVBLE1BQU1DLE9BQU87b0JBQ1hDLE9BQU9MO29CQUNQckQsTUFBTXhFLFdBQVcsQ0FBQyxTQUFTLEVBQUU2SCxTQUFTLENBQUMsRUFBRVAsSUFBSTtvQkFDN0NhLEtBQUtiO29CQUNMWixPQUFPQyxLQUFLMUUsR0FBRztvQkFDZjZGO2dCQUNGO2dCQUVBLE9BQU9MLGNBQWNXLElBQUksQ0FBQ0gsTUFBTTtvQkFBQ0ksV0FBVztnQkFBSSxHQUFHM0MsSUFBSSxDQUFDLElBQU11QztZQUNoRTtRQUNKO1FBRUEsT0FBT2Q7SUFDVCxFQUFFLE9BQU1wQixPQUFPO1FBQ2IsTUFBTWpGLFNBQVM7WUFDYmlEO1lBQ0FjLFVBQVVwRDtZQUNWcUQsUUFBUTtnQkFBQ2hCO1lBQUk7WUFDYmlCLE9BQU9sRSxXQUFXbUYsY0FBYztRQUNsQyxHQUFHRCxPQUFPbEM7SUFDWjtBQUNGLEVBQUU7QUFFRixPQUFPLE1BQU15RSxpQkFBaUIsT0FBT3pFLFNBQXFCLEVBQUNRLEtBQUssRUFBRUUsS0FBSyxFQUFFekMsUUFBUSxFQUFDO0lBQ2hGLE1BQU1pQyxTQUFTO0lBQ2YsTUFBTSxFQUFDQyxZQUFZLEVBQUMsR0FBR0g7SUFDdkIsTUFBTTBFLFdBQXFCL0gsR0FBRyxDQUFDO3NCQUNYLEVBQUU2RCxNQUFNLGVBQWUsRUFBRUUsTUFBTSxrQkFBa0IsRUFBRXpDLFNBQVM7O1lBRXRFLENBQUM7SUFFWCxJQUFJO1FBQ0YsT0FBTyxNQUFNWCxNQUFNNkMsY0FBY3lCLEtBQUssQ0FBQzhDLFVBQ3BDN0MsSUFBSSxDQUFDLE9BQU9DO1lBQ1gsTUFBTTdCLE9BQU82QixPQUFPcUIsSUFBSTtZQUV4QixJQUFHbEQsTUFBTTtnQkFDUCxNQUFNLEVBQUNPLEtBQUssRUFBRUUsS0FBSyxFQUFFc0MsYUFBYSxFQUFFQyxhQUFhLEVBQUMsR0FBR2hEO2dCQUNyRCxNQUFNMEUsY0FBYyxPQUFPLEtBQUssSUFBSSxhQUFhO2dCQUNqRCxNQUFNQyxPQUFPbEcsS0FBS0MsS0FBSyxDQUFDLFNBQVVELEtBQUtnRSxNQUFNLEtBQUs7Z0JBQ2xELE1BQU1tQyxZQUFZMUgsU0FBUyxTQUFTOEM7Z0JBQ3BDLElBQUl1RDtnQkFFSixJQUFHaEQsU0FBU3dDLGVBQWU7b0JBQ3pCdEYsVUFBVTt3QkFDUnNDO3dCQUNBOEUsTUFBTSxDQUFDLGFBQWEsRUFBRUYsTUFBTTtvQkFDOUI7b0JBQ0FwQixTQUFTO3dCQUFDZixtQkFBbUJtQzt3QkFBTUcsc0JBQXNCSjtvQkFBVztnQkFDdEU7Z0JBRUEsSUFBR2pFLFNBQVN1QyxlQUFlO29CQUN6QnRGLFFBQVE7d0JBQ05xQzt3QkFDQThFLE1BQU0sQ0FBQyxhQUFhLEVBQUVGLE1BQU07b0JBQzlCO29CQUNBcEIsU0FBUzt3QkFBQ3dCLHNCQUFzQkw7d0JBQWFoQyxpQkFBaUJpQztvQkFBSTtnQkFDcEU7Z0JBRUEsSUFBR3BCLE9BQU9mLGlCQUFpQixJQUFJZSxPQUFPYixlQUFlLEVBQUU7b0JBQ3JELE1BQU1zQyxjQUF3QnRJLEdBQUcsQ0FBQyxPQUFPLEVBQUVrSSxVQUFVLE1BQU0sRUFBRXJCLE9BQU8sU0FBUyxDQUFDO29CQUU5RSxNQUFNbEcsTUFBTTZDLGNBQWN5QixLQUFLLENBQUNxRDtvQkFFaEMsT0FBTztnQkFDVDtnQkFFQSxPQUFPO1lBQ1Q7WUFFQSxPQUFPO1FBQ1Q7SUFDSixFQUFFLE9BQU0vQyxPQUFPO1FBQ2JqRixTQUFTO1lBQ1BpRDtZQUNBYyxVQUFVcEQ7WUFDVnFELFFBQVE7Z0JBQUNUO2dCQUFPRTtnQkFBT3pDO1lBQVE7WUFDL0JpRCxPQUFPbEUsV0FBV21GLGNBQWM7UUFDbEMsR0FBR0QsT0FBT2xDO1FBRVYsT0FBTztJQUNUO0FBQ0YsRUFBRTtBQUVGLE9BQU8sTUFBTWtGLGdCQUFnQixPQUMzQmxGLFNBQ0EsRUFDRTRFLElBQUksRUFDSm5FLFFBQVEsRUFDUjBFLElBQUksRUFDSmxILFFBQVEsRUFNVDtJQUVELE1BQU1pQyxTQUFTO0lBQ2YsTUFBTSxFQUFDQyxZQUFZLEVBQUMsR0FBR0g7SUFDdkIsTUFBTW9GLGlCQUF5QjVJLGNBQWNpRTtJQUM3QyxNQUFNaUUsV0FBcUIvSCxHQUFHLENBQUM7eUJBQ1IsRUFBRXNCLFNBQVM7O1lBRXhCLENBQUM7SUFFWCxJQUFJO1FBQ0YsT0FBTyxNQUFNWCxNQUFNNkMsY0FBY3lCLEtBQUssQ0FBQzhDLFVBQ3BDN0MsSUFBSSxDQUFDLE9BQU9DO1lBQ1gsTUFBTTdCLE9BQU82QixPQUFPcUIsSUFBSTtZQUV4QixJQUFHbEQsTUFBTTtnQkFDUCxNQUFNLEVBQ0pXLEtBQUtpRSxTQUFTLEVBQ2R4RCxJQUFJLEVBQ0pvQixpQkFBaUIsRUFDakJzQyx1QkFBdUIsQ0FBQyxFQUN4QnBDLGVBQWUsRUFDZnFDLHVCQUF1QixDQUFDLEVBQ3pCLEdBQUcvRTtnQkFDSixNQUFNN0IsTUFBTTBFLEtBQUsxRSxHQUFHO2dCQUNwQixJQUFJb0Y7Z0JBRUosT0FBTzJCO29CQUNMLEtBQUs7d0JBQ0gsSUFBR1AsU0FBU25DLHFCQUFxQnNDLHVCQUF1QjNHLEtBQUs7NEJBQzNELE1BQU1xQyxXQUFtQnJFLGVBQWVnSixnQkFBZ0IvRDs0QkFDeERtQyxTQUFTO2dDQUFDL0M7NEJBQVE7d0JBQ3BCO3dCQUNBO29CQUNGLEtBQUs7d0JBQ0gsSUFBR21FLFNBQVNqQyxtQkFBbUJxQyx1QkFBdUI1RyxLQUFLOzRCQUN6RCxNQUFNcUMsV0FBbUJyRSxlQUFlZ0osZ0JBQWdCL0Q7NEJBQ3hEbUMsU0FBUztnQ0FBQy9DOzRCQUFRO3dCQUNwQjt3QkFDQTtvQkFDRjt3QkFDRSxPQUFPO2dCQUNYO2dCQUVBLElBQUcrQyxRQUFRO29CQUNULE1BQU15QixjQUF3QnRJLEdBQUcsQ0FBQyxPQUFPLEVBQUVrSSxVQUFVLE1BQU0sRUFBRXJCLE9BQU8sU0FBUyxDQUFDO29CQUU5RSxNQUFNbEcsTUFBTTZDLGNBQWN5QixLQUFLLENBQUNxRDtvQkFFaEMsT0FBTztnQkFDVDtZQUNGO1lBRUEsT0FBTztRQUNUO0lBQ0osRUFBRSxPQUFNL0MsT0FBTztRQUNiakYsU0FBUztZQUNQaUQ7WUFDQWMsVUFBVXBEO1lBQ1ZxRCxRQUFRO2dCQUFDaEQ7WUFBUTtZQUNqQmlELE9BQU9sRSxXQUFXbUYsY0FBYztRQUNsQyxHQUFHRCxPQUFPbEM7UUFFVixPQUFPO0lBQ1Q7QUFDRixFQUFFO0FBRUYsT0FBTyxNQUFNcUYsY0FBYyxPQUN6QnJGLFNBQ0EsRUFDRTRFLElBQUksRUFDSk8sSUFBSSxFQUNKakUsS0FBSyxFQUtOO0lBRUQsTUFBTWhCLFNBQVM7SUFDZixNQUFNLEVBQUNDLFlBQVksRUFBQyxHQUFHSDtJQUN2QixNQUFNc0YsUUFBUUgsU0FBUztJQUN2QixNQUFNSSxpQkFBaUJELFFBQVE3SSxXQUFXeUUsU0FBUzNFLFdBQVcyRTtJQUM5RCxNQUFNc0UsZUFBZUYsUUFDakIsQ0FBQyxtQkFBbUIsRUFBRUMsZUFBZSwwQkFBMEIsRUFBRVgsTUFBTSxHQUN2RSxDQUFDLG1CQUFtQixFQUFFVyxlQUFlLDRCQUE0QixFQUFFWCxNQUFNO0lBQzdFLE1BQU1GLFdBQW1CLENBQUM7SUFDeEIsRUFBRWMsYUFBYTs7WUFFUCxDQUFDO0lBRVgsSUFBSTtRQUNGLE9BQU8sTUFBTWxJLE1BQU02QyxjQUFjeUIsS0FBSyxDQUFDOEMsVUFDcEM3QyxJQUFJLENBQUMsQ0FBQ0MsU0FBV0EsT0FBT3FCLElBQUksSUFDNUJ0QixJQUFJLENBQUMsQ0FBQzVCO1lBQ0wsSUFBR0EsTUFBTTtnQkFDUCxNQUFNcUQsY0FBY2dDLFFBQ2hCO29CQUFDckMsZUFBZTtvQkFBTU4saUJBQWlCO2dCQUFDLElBQ3hDO29CQUFDSyxlQUFlO29CQUFNUCxtQkFBbUI7Z0JBQUM7Z0JBQzlDLE1BQU1pQyxXQUFxQi9ILEdBQUcsQ0FBQyxPQUFPLEVBQUVzRCxLQUFLVSxJQUFJLENBQUMsTUFBTSxFQUFFMkMsWUFBWSxTQUFTLENBQUM7Z0JBRWhGLE9BQU9oRyxNQUFNNkMsY0FBY3lCLEtBQUssQ0FBQzhDLFVBQzlCN0MsSUFBSSxDQUFDLElBQU0sTUFDWHVCLEtBQUssQ0FBQyxDQUFDbEI7b0JBQ05qRixTQUFTO3dCQUNQaUQ7d0JBQ0FjLFVBQVVwRDt3QkFDVnFELFFBQVE7NEJBQUMyRDs0QkFBTU87NEJBQU1qRSxPQUFPcUU7d0JBQWM7d0JBQzFDckUsT0FBT2xFLFdBQVdtRixjQUFjO29CQUNsQyxHQUFHRCxPQUFPbEM7b0JBRVYsT0FBTztnQkFDVDtZQUNKO1lBRUEsT0FBTztRQUNUO0lBQ0osRUFBRSxPQUFNa0MsT0FBTztRQUNiakYsU0FBUztZQUNQaUQ7WUFDQWMsVUFBVXBEO1lBQ1ZxRCxRQUFRO2dCQUFDMkQ7Z0JBQU1PO2dCQUFNakUsT0FBT3FFO1lBQWM7WUFDMUNyRSxPQUFPbEUsV0FBV21GLGNBQWM7UUFDbEMsR0FBR0QsT0FBT2xDO1FBRVYsT0FBTztJQUNUO0FBQ0YsRUFBRTtBQUVGLE9BQU8sTUFBTXlGLGFBQWEsQ0FBQ3pGLFNBQXFCQztJQUM5QyxNQUFNQyxTQUFTO0lBQ2YsTUFBTSxFQUFDQyxZQUFZLEVBQUMsR0FBR0g7SUFDdkIsTUFBTSxFQUFDeUQsRUFBRSxFQUFDLEdBQUczRyxVQUFVbUQ7SUFFdkIsTUFBTXlFLFdBQXFCL0gsR0FBRyxDQUFDLGlCQUFpQixFQUFFOEcsR0FBRzs7Y0FFekMsQ0FBQztJQUViLE1BQU1pQyxlQUFlLElBQUk3SSxPQUFPRSxPQUFPNEksR0FBRyxDQUFDLGlCQUFpQjtRQUFDQyxZQUFZL0g7UUFBb0JnSSxZQUFZO0lBQUk7SUFFN0csT0FBT3ZJLE1BQU02QyxjQUFjeUIsS0FBSyxDQUFDOEMsVUFDOUI3QyxJQUFJLENBQUMsQ0FBQ0MsU0FBV0EsT0FBT3FCLElBQUksSUFDNUJ0QixJQUFJLENBQUMsQ0FBQ2lFLGNBQWdCSixhQUFhSyxTQUFTLENBQUNDLEdBQUcsQ0FBQ0YsYUFBYUcsa0JBQzVEcEUsSUFBSSxDQUFDLElBQU02RCxhQUFhUSxRQUFRLENBQUNGLEdBQUcsQ0FBQ0YsYUFBYUssa0JBQ2xEdEUsSUFBSSxDQUFDLElBQU1pRSxjQUNiMUMsS0FBSyxDQUFDLENBQUNsQixRQUFpQmpGLFNBQVM7WUFDaENpRDtZQUNBYyxVQUFVcEQ7WUFDVnFELFFBQVE7Z0JBQUN3QztZQUFFO1lBQ1h2QyxPQUFPbEUsV0FBV21GLGNBQWM7UUFDbEMsR0FBR0QsT0FBT2xDO0FBQ2QsRUFBRTtBQUVGLE9BQU8sTUFBTW9HLGlCQUFpQixDQUFDcEcsU0FBcUJDO0lBQ2xELE1BQU1DLFNBQVM7SUFDZixNQUFNLEVBQUNDLFlBQVksRUFBQyxHQUFHSDtJQUN2QixNQUFNLEVBQUN5RCxFQUFFLEVBQUMsR0FBRzNHLFVBQVVtRDtJQUN2QixNQUFNb0csVUFBb0I7UUFDeEJuSSxZQUFZO0lBQ2Q7SUFDQSxNQUFNd0csV0FBcUIvSCxHQUFHLENBQUMsT0FBTyxFQUFFOEcsR0FBRyxNQUFNLEVBQUU0QyxRQUFRLDRCQUE0QixDQUFDO0lBRXhGLE9BQU8vSSxNQUFNNkMsY0FBY3lCLEtBQUssQ0FBQzhDLFVBQzlCN0MsSUFBSSxDQUFDLENBQUNDLFNBQVdBLE9BQU9xQixJQUFJLElBQzVCQyxLQUFLLENBQUMsQ0FBQ2xCO1FBQ04sTUFBTWpGLFNBQVM7WUFDZmlEO1lBQ0FjLFVBQVVwRDtZQUNWcUQsUUFBUTtnQkFBQ3dDO1lBQUU7WUFDWHZDLE9BQU9sRSxXQUFXbUYsY0FBYztRQUNsQyxHQUFHRCxPQUFPbEM7SUFDWjtBQUNGLEVBQUU7QUFFRixPQUFPLE1BQU1zRyxpQkFBaUIsQ0FBQ3JHO0lBQzdCLE1BQU0sRUFBQ3NHLEtBQUssRUFBRUMsSUFBSSxFQUFFdkMsT0FBTyxFQUFFLEVBQUVoRyxXQUFXLEVBQUUsRUFBQyxHQUFHZ0M7SUFDaEQsTUFBTXdHLFdBQVcsQUFBQztRQUFDRjtRQUFPQztLQUFLLENBQUU5RSxJQUFJLENBQUMsS0FBS2dGLElBQUk7SUFFL0MsSUFBR3pDLE1BQU07UUFDUCxPQUFPQTtJQUNULE9BQU8sSUFBR3dDLGFBQWEsSUFBSTtRQUN6QixPQUFPQTtJQUNULE9BQU8sSUFBR3hJLFVBQVU7UUFDbEIsT0FBT0E7SUFDVDtJQUVBLE9BQU87QUFDVCxFQUFFO0FBRUYsT0FBTyxNQUFNMEksaUJBQWlCLENBQUMzRztJQUM3QixNQUFNRSxTQUFTO0lBQ2YsTUFBTSxFQUFDQyxZQUFZLEVBQUVoQixNQUFNLEVBQUV5SCxTQUFTLEVBQUM1SSxRQUFRNkksU0FBUyxFQUFFNUksUUFBUSxFQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUMsR0FBRytCO0lBQzVFLE1BQU0sRUFBQ1IsU0FBU3NILGFBQWEsRUFBRXJILFNBQVNzSCxhQUFhLEVBQUMsR0FBRzdILGdCQUFnQkM7SUFDekUsTUFBTTZILGtCQUFrQjNLLGNBQWMsQ0FBQyxNQUFNLEVBQUV3SyxXQUFXO0lBRTFELE1BQU1uQyxXQUFtQixDQUFDLGtCQUFrQixFQUFFc0MsZ0JBQWdCO0VBQzlELEVBQUVELGNBQWNyRixJQUFJLENBQUMsTUFBTTttQkFDVixFQUFFb0YsY0FBY3BGLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUUvQyxPQUFPcEUsTUFBTTZDLGNBQWN5QixLQUFLLENBQUM4QyxVQUM5QjdDLElBQUksQ0FBQyxDQUFDQyxTQUFXQSxPQUFPcUIsSUFBSSxJQUM1QkMsS0FBSyxDQUFDLENBQUNsQjtRQUNOLE1BQU1qRixTQUFTO1lBQ2JpRDtZQUNBYyxVQUFVcEQ7WUFDVnFELFFBQVE7Z0JBQUNqRCxRQUFRNkk7Z0JBQVc1STtZQUFRO1lBQ3BDaUQsT0FBT2xFLFdBQVdtRixjQUFjO1FBQ2xDLEdBQUdELE9BQU9sQztJQUNaO0FBQ0osRUFBRTtBQUVGLE9BQU8sTUFBTWlILFVBQVUsQ0FBQ2pILFNBQXFCQztJQUMzQyxNQUFNQyxTQUFTO0lBQ2YsTUFBTSxFQUFDTSxLQUFLLEVBQUVpRCxFQUFFLEVBQUUvQyxLQUFLLEVBQUUxQyxNQUFNLEVBQUVDLFFBQVEsRUFBQyxHQUFHbkIsVUFBVW1EO0lBQ3ZELE1BQU0sRUFBQ0UsWUFBWSxFQUFFaEIsTUFBTSxFQUFDLEdBQUdhO0lBQy9CLE1BQU0sRUFBQ1IsU0FBU3NILGFBQWEsRUFBRXJILFNBQVNzSCxhQUFhLEVBQUMsR0FBRzdILGdCQUFnQkM7SUFDekUsSUFBSXVGLFdBQW1CO0lBRXZCLElBQUdqQixJQUFJO1FBQ0xpQixXQUFXLENBQUMsa0JBQWtCLEVBQUVqQixHQUFHO0lBQ25DLEVBQUVzRCxjQUFjckYsSUFBSSxDQUFDLE1BQU07O3FCQUVWLEVBQUVvRixjQUFjcEYsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ2pELE9BQU8sSUFBR3pELFVBQVU7UUFDbEJ5RyxXQUFXLENBQUM7MEJBQ1UsRUFBRXpHLFNBQVM7SUFDakMsRUFBRThJLGNBQWNyRixJQUFJLENBQUMsTUFBTTtxQkFDVixFQUFFb0YsY0FBY3BGLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNqRCxPQUFPLElBQUdsQixPQUFPO1FBQ2ZrRSxXQUFXLENBQUM7dUJBQ08sRUFBRWxFLE1BQU07SUFDM0IsRUFBRXVHLGNBQWNyRixJQUFJLENBQUMsTUFBTTtxQkFDVixFQUFFb0YsY0FBY3BGLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNqRCxPQUFPLElBQUdoQixPQUFPO1FBQ2ZnRSxXQUFXLENBQUM7dUJBQ08sRUFBRWhFLE1BQU07SUFDM0IsRUFBRXFHLGNBQWNyRixJQUFJLENBQUMsTUFBTTtxQkFDVixFQUFFb0YsY0FBY3BGLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNqRDtJQUVBLE9BQU9wRSxNQUFNNkMsY0FDVnlCLEtBQUssQ0FBQzhDLFVBQ043QyxJQUFJLENBQUMsQ0FBQ0MsU0FBV0EsT0FBT3FCLElBQUksSUFDNUJ0QixJQUFJLENBQUMsQ0FBQzVCLE9BQVNBLE1BQ2ZtRCxLQUFLLENBQUMsQ0FBQ2xCLFFBQWlCakYsU0FBUztZQUNoQ2lEO1lBQ0FjLFVBQVVwRDtZQUNWcUQsUUFBUTtnQkFBQ3dDO2dCQUFJekY7Z0JBQVFDO1lBQVE7WUFDN0JpRCxPQUFPbEUsV0FBV21GLGNBQWM7UUFDbEMsR0FBR0QsT0FBT2xDO0FBQ2QsRUFBRTtBQUVGLE9BQU8sTUFBTWtILFdBQVcsQ0FBQ2xILFNBQXFCTDtJQUM1QyxNQUFNTyxTQUFTO0lBQ2YsTUFBTSxFQUFDQyxZQUFZLEVBQUVoQixNQUFNLEVBQUMsR0FBR2E7SUFDL0IsTUFBTSxFQUFDRixLQUFLLEVBQUU3QixRQUFRLEVBQUMsR0FBR3lCLGlCQUFpQkM7SUFDM0MsTUFBTSxFQUFDSCxTQUFTc0gsYUFBYSxFQUFFckgsU0FBU3NILGFBQWEsRUFBQyxHQUFHN0gsZ0JBQWdCQztJQUN6RSxNQUFNZ0ksV0FBcUI7UUFBQztLQUFtQjtJQUUvQyxJQUFHbEosVUFBVTtRQUNYa0osU0FBUzNGLElBQUksQ0FBQyxDQUFDLHNCQUFzQixFQUFFOUUsY0FBY3VCLFVBQVUsRUFBRSxDQUFDO0lBQ3BFO0lBRUEsTUFBTXlHLFdBQW1CLENBQUM7V0FDakIsRUFBRXlDLFNBQVN6RixJQUFJLENBQUMsUUFBUTtJQUMvQixFQUFFcUYsY0FBY3JGLElBQUksQ0FBQyxNQUFNO0lBQzNCLEVBQUU1QixNQUFNbkQsR0FBRyxDQUFDOztxQkFFSyxFQUFFbUssY0FBY3BGLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUVqRCxPQUFPcEUsTUFBTTZDLGNBQWN5QixLQUFLLENBQUM4QyxVQUM5QjdDLElBQUksQ0FBQyxDQUFDQyxTQUFXQSxPQUFPQyxHQUFHLElBQzNCcUIsS0FBSyxDQUFDLENBQUNsQjtRQUNOakYsU0FBUztZQUNQaUQ7WUFDQWMsVUFBVXBEO1lBQ1ZzRCxPQUFPbEUsV0FBV21GLGNBQWM7UUFDbEMsR0FBR0QsT0FBT2xDO1FBRVYsT0FBTyxFQUFFO0lBQ1g7QUFDSixFQUFFO0FBRUYsT0FBTyxNQUFNb0gsc0JBQXNCLENBQ2pDcEgsU0FDQSxFQUFDcUgsWUFBWSxFQUFFLEVBQUVwSixRQUFRLEVBQTRDLEVBQ3JFMEI7SUFFQSxNQUFNTyxTQUFTO0lBQ2YsTUFBTSxFQUFDQyxZQUFZLEVBQUVoQixNQUFNLEVBQUV5SCxTQUFTLEVBQUM1SSxRQUFRNkksU0FBUyxFQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUMsR0FBRzdHO0lBQ2xFLE1BQU1zSCxrQkFBNEJELFVBQVV0RCxHQUFHLENBQUMsQ0FBQ3dELGVBQXlCakwsVUFBVWlMLGNBQWMsSUFBSUMsV0FBVztJQUNqSCxNQUFNLEVBQUMxSCxLQUFLLEVBQUMsR0FBR0osaUJBQWlCQztJQUNqQyxNQUFNLEVBQUNILFNBQVNzSCxhQUFhLEVBQUVySCxTQUFTc0gsYUFBYSxFQUFDLEdBQUc3SCxnQkFBZ0JDO0lBQ3pFLE1BQU02SCxrQkFBMEIsQ0FBQyxNQUFNLEVBQUVILFdBQVc7SUFDcEQsTUFBTVksaUJBQXlCL0ssY0FBY3VCO0lBQzdDLE1BQU1rSixXQUFxQjtRQUN6QjtRQUNBLENBQUMsU0FBUyxFQUFFTyxLQUFLQyxTQUFTLENBQUNMLGlCQUFpQixnQkFBZ0IsQ0FBQztLQUM5RDtJQUVELElBQUdySixVQUFVO1FBQ1hrSixTQUFTM0YsSUFBSSxDQUFDLENBQUMsc0JBQXNCLEVBQUVpRyxlQUFlLEVBQUUsQ0FBQztJQUMzRDtJQUVBLE1BQU0vQyxXQUFtQixDQUFDLHNCQUFzQixFQUFFc0MsZ0JBQWdCOztJQUVoRSxFQUFFRCxjQUFjckYsSUFBSSxDQUFDLE1BQU07V0FDcEIsRUFBRXlGLFNBQVN6RixJQUFJLENBQUMsUUFBUTtJQUMvQixFQUFFNUIsTUFBTW5ELEdBQUcsQ0FBQztxQkFDSyxFQUFFbUssY0FBY3BGLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUVqRCxPQUFPcEUsTUFBTTZDLGNBQWN5QixLQUFLLENBQUM4QyxVQUM5QjdDLElBQUksQ0FBQyxDQUFDQyxTQUFXQSxPQUFPQyxHQUFHLElBQzNCcUIsS0FBSyxDQUFDLENBQUNsQjtRQUNOakYsU0FBUztZQUNQaUQ7WUFDQWMsVUFBVXBEO1lBQ1ZzRCxPQUFPbEUsV0FBV21GLGNBQWM7UUFDbEMsR0FBR0QsT0FBT2xDO1FBRVYsT0FBTyxFQUFFO0lBQ1g7QUFDSixFQUFFO0FBRUYsT0FBTyxNQUFNNEgsaUJBQWlCLENBQzVCNUgsU0FDQSxFQUFDdUQsSUFBSSxFQUFFdEYsUUFBUSxFQUFDLEVBQ2hCMEI7SUFFQSxNQUFNTyxTQUFTO0lBQ2YsTUFBTSxFQUFDQyxZQUFZLEVBQUVoQixNQUFNLEVBQUV5SCxTQUFTLEVBQUM1SSxRQUFRNkksU0FBUyxFQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUMsR0FBRzdHO0lBQ2xFLE1BQU02SCxhQUF1QnRFLE1BQU1uRSxPQUFPLENBQUMwSSxNQUFnQkM7UUFDekQsSUFBR0EsU0FBUztZQUNWRCxLQUFLdEcsSUFBSSxDQUFDbEYsVUFBVXlMLFNBQVMsSUFBSVAsV0FBVztRQUM5QztRQUVBLE9BQU9NO0lBQ1QsR0FBRyxFQUFFO0lBQ0wsTUFBTSxFQUFDaEksS0FBSyxFQUFDLEdBQUdKLGlCQUFpQkM7SUFDakMsTUFBTSxFQUFDSCxTQUFTc0gsYUFBYSxFQUFFckgsU0FBU3NILGFBQWEsRUFBQyxHQUFHN0gsZ0JBQWdCQztJQUN6RSxNQUFNc0ksaUJBQXlCL0ssY0FBY3VCO0lBQzdDLE1BQU1rSixXQUFxQjtRQUN6QixDQUFDLFdBQVcsRUFBRU4sVUFBVSxDQUFDLENBQUM7UUFDMUI7S0FDRDtJQUVELElBQUc1SSxVQUFVO1FBQ1hrSixTQUFTM0YsSUFBSSxDQUFDLENBQUMsc0JBQXNCLEVBQUVpRyxlQUFlLEVBQUUsQ0FBQztJQUMzRDtJQUVBLE1BQU0vQyxXQUFtQixDQUFDO29CQUNSLEVBQUVnRCxLQUFLQyxTQUFTLENBQUNFLFlBQVk7OztJQUc3QyxFQUFFZCxjQUFjckYsSUFBSSxDQUFDLE1BQU07V0FDcEIsRUFBRXlGLFNBQVN6RixJQUFJLENBQUMsUUFBUTtJQUMvQixFQUFFNUIsTUFBTW5ELEdBQUcsQ0FBQzs4QkFDYyxFQUFFbUssY0FBY3BGLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUUxRCxPQUFPcEUsTUFBTTZDLGNBQWN5QixLQUFLLENBQUM4QyxVQUM5QjdDLElBQUksQ0FBQyxDQUFDQyxTQUFXQSxPQUFPQyxHQUFHLElBQzNCcUIsS0FBSyxDQUFDLENBQUNsQjtRQUNOakYsU0FBUztZQUNQaUQ7WUFDQWMsVUFBVXBEO1lBQ1ZzRCxPQUFPbEUsV0FBV21GLGNBQWM7UUFDbEMsR0FBR0QsT0FBT2xDO1FBRVYsT0FBTyxFQUFFO0lBQ1g7QUFDSixFQUFFO0FBRUYsT0FBTyxNQUFNZ0ksbUJBQW1CLENBQUNoSSxTQUFxQixFQUFDL0IsUUFBUSxFQUFDLEVBQUUwQjtJQUNoRSxNQUFNTyxTQUFTO0lBQ2YsTUFBTSxFQUFDQyxZQUFZLEVBQUVoQixNQUFNLEVBQUV5SCxTQUFTLEVBQUM1SSxNQUFNLEVBQUMsR0FBRyxDQUFDLENBQUMsRUFBQyxHQUFHZ0M7SUFDdkQsTUFBTSxFQUFDRixLQUFLLEVBQUMsR0FBR0osaUJBQWlCQztJQUNqQyxNQUFNc0ksU0FBUztRQUNiO1FBQ0E7S0FDRDtJQUNELE1BQU0sRUFBQ3pJLFNBQVNzSCxhQUFhLEVBQUVySCxTQUFTc0gsYUFBYSxFQUFDLEdBQUc3SCxnQkFBZ0JDO0lBRXpFLElBQUdsQixVQUFVO1FBQ1hnSyxPQUFPekcsSUFBSSxDQUFDLENBQUMsc0JBQXNCLEVBQUU5RSxjQUFjdUIsVUFBVSxFQUFFLENBQUM7SUFDbEU7SUFFQSx5QkFBeUI7SUFDekIsTUFBTXlHLFdBQW1CLENBQUM7a0NBQ00sRUFBRTFHLE9BQU87V0FDaEMsRUFBRWlLLE9BQU92RyxJQUFJLENBQUMsUUFBUTtJQUM3QixFQUFFcUYsY0FBY3JGLElBQUksQ0FBQyxNQUFNOztJQUUzQixFQUFFNUIsTUFBTW5ELEdBQUcsQ0FBQzs7cUJBRUssRUFBRW1LLGNBQWNwRixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7SUFFakQsT0FBT3BFLE1BQU02QyxjQUFjeUIsS0FBSyxDQUFDOEMsVUFDOUI3QyxJQUFJLENBQUMsQ0FBQ0MsU0FBV0EsT0FBT0MsR0FBRyxJQUMzQnFCLEtBQUssQ0FBQyxDQUFDbEI7UUFDTmpGLFNBQVM7WUFDUGlEO1lBQ0FjLFVBQVVwRDtZQUNWc0QsT0FBT2xFLFdBQVdtRixjQUFjO1FBQ2xDLEdBQUdELE9BQU9sQztRQUVWLE9BQU8sRUFBRTtJQUNYO0FBQ0osRUFBRTtBQUVGLE9BQU8sTUFBTWtJLHVCQUF1QixDQUNsQ2xJLFNBQ0EsRUFBQ2hDLE1BQU0sRUFBVyxFQUNsQjJCO0lBRUEsTUFBTU8sU0FBUztJQUNmLE1BQU0sRUFBQ0MsWUFBWSxFQUFFaEIsTUFBTSxFQUFDLEdBQUdhO0lBQy9CLE1BQU0sRUFBQ0YsS0FBSyxFQUFFN0IsUUFBUSxFQUFDLEdBQUd5QixpQkFBaUJDO0lBQzNDLE1BQU0sRUFBQ0gsU0FBU3NILGFBQWEsRUFBRXJILFNBQVNzSCxhQUFhLEVBQUMsR0FBRzdILGdCQUFnQkM7SUFDekUsTUFBTWdKLGVBQXVCOUwsY0FBYyxDQUFDLE1BQU0sRUFBRTJCLFFBQVE7SUFDNUQsTUFBTW1KLFdBQXFCO1FBQ3pCO0tBQ0Q7SUFFRCxJQUFHbEosVUFBVTtRQUNYa0osU0FBUzNGLElBQUksQ0FBQyxDQUFDLHNCQUFzQixFQUFFOUUsY0FBY3VCLFVBQVUsRUFBRSxDQUFDO0lBQ3BFO0lBRUEsTUFBTXlHLFdBQW1CLENBQUM7NEJBQ0EsRUFBRXlELGFBQWE7OztJQUd2QyxFQUFFcEIsY0FBY3JGLElBQUksQ0FBQyxNQUFNO1dBQ3BCLEVBQUV5RixTQUFTekYsSUFBSSxDQUFDLFFBQVE7SUFDL0IsRUFBRTVCLE1BQU1uRCxHQUFHLENBQUM7OEJBQ2MsRUFBRW1LLGNBQWNwRixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7SUFFMUQsT0FBT3BFLE1BQU02QyxjQUFjeUIsS0FBSyxDQUFDOEMsVUFDOUI3QyxJQUFJLENBQUMsQ0FBQ0MsU0FBV0EsT0FBT0MsR0FBRyxJQUMzQnFCLEtBQUssQ0FBQyxDQUFDbEI7UUFDTmpGLFNBQVM7WUFDUGlEO1lBQ0FjLFVBQVVwRDtZQUNWc0QsT0FBT2xFLFdBQVdtRixjQUFjO1FBQ2xDLEdBQUdELE9BQU9sQztRQUVWLE9BQU8sRUFBRTtJQUNYO0FBQ0osRUFBRTtBQUVGLE9BQU8sTUFBTW9JLGlCQUFpQixDQUFDLEVBQUNySixPQUFPLEVBQUVELEtBQUssRUFBQztJQUM3QyxJQUFJO1FBQ0YsTUFBTSxFQUFDZCxNQUFNLEVBQUVDLFFBQVEsRUFBRUMsVUFBVSxFQUFDLEdBQUdWLFdBQVdzQjtRQUNsRCxPQUFPZixZQUFZQyxRQUFRQyxVQUFVQyxZQUFZYTtJQUNuRCxFQUFFLE9BQU1tRCxPQUFPO1FBQ2IsTUFBTUEsT0FBTyxxQ0FBcUM7SUFDcEQ7QUFDRixFQUFFO0FBRUYsT0FBTyxNQUFNbUcsU0FBUyxPQUFPckksU0FBcUJzSTtJQUNoRCxNQUFNcEksU0FBUztJQUNmLE1BQU0sRUFBQ0MsWUFBWSxFQUFDLEdBQUdIO0lBQ3ZCLE1BQU0sRUFBQ1EsS0FBSyxFQUFFekIsT0FBTyxFQUFFMEIsUUFBUSxFQUFFQyxLQUFLLEVBQUV6QyxRQUFRLEVBQUMsR0FBR3FLO0lBQ3BELE1BQU1DLGNBQXNCaE0sV0FBV2lFO0lBQ3ZDLE1BQU1pSCxpQkFBeUIvSyxjQUFjdUI7SUFDN0MsTUFBTW1ILGlCQUF5QjVJLGNBQWNpRTtJQUM3QyxNQUFNK0gsY0FBc0IvTCxXQUFXaUU7SUFDdkMsTUFBTStILGdCQUF3QnZNLFNBQVM2QyxZQUFZO0lBRW5ELElBQUcsQUFBQyxDQUFDMEksa0JBQWtCLENBQUNjLGVBQWUsQ0FBQ0MsZUFBZ0IsQ0FBQ3BELGdCQUFnQjtRQUN2RSxNQUFNbEksYUFBYTtZQUNqQmdEO1lBQ0FjLFVBQVVwRDtZQUNWcUQsUUFBUTtnQkFBQ2hEO1lBQVE7WUFDakJpRCxPQUFPbEUsV0FBV21FLGlCQUFpQjtRQUNyQyxHQUFHbkI7SUFDTDtJQUVBLE1BQU11QixVQUFvQixFQUFFO0lBRTVCLElBQUdnSCxhQUFhO1FBQ2RoSCxRQUFRQyxJQUFJLENBQUMsQ0FBQyxZQUFZLEVBQUUrRyxZQUFZLENBQUMsQ0FBQztJQUM1QztJQUVBLElBQUdDLGFBQWE7UUFDZGpILFFBQVFDLElBQUksQ0FBQyxDQUFDLFdBQVcsRUFBRWdILGFBQWE7SUFDMUM7SUFFQSxJQUFHZixnQkFBZ0I7UUFDakJsRyxRQUFRQyxJQUFJLENBQUMsQ0FBQyxlQUFlLEVBQUVpRyxlQUFlLENBQUMsQ0FBQztJQUNsRDtJQUVBLE1BQU1oRyxhQUFxQixDQUFDO1dBQ25CLEVBQUVGLFFBQVFHLElBQUksQ0FBQyxRQUFROztZQUV0QixDQUFDO0lBRVgsSUFBSWdIO0lBRUosSUFBSTtRQUNGQSxZQUFZLE1BQU1wTCxNQUFNNkMsY0FBY3lCLEtBQUssQ0FBQ0gsWUFBWUksSUFBSSxDQUFDLENBQUNDLFNBQVdBLE9BQU9xQixJQUFJO0lBQ3RGLEVBQUUsT0FBTWpCLE9BQU87UUFDYixNQUFNakYsU0FBUztZQUNiaUQ7WUFDQWMsVUFBVXBEO1lBQ1ZxRCxRQUFRO2dCQUFDaEQsVUFBVXdKO1lBQWM7WUFDakN2RyxPQUFPbEUsV0FBV21GLGNBQWM7UUFDbEMsR0FBR0QsT0FBT2xDO0lBQ1o7SUFFQSxJQUFHLENBQUMwSSxXQUFXO1FBQ2IsTUFBTXhMLGFBQWE7WUFDakJnRDtZQUNBYyxVQUFVcEQ7WUFDVnFELFFBQVE7Z0JBQUNoRDtZQUFRO1lBQ2pCaUQsT0FBT2xFLFdBQVcyTCxzQkFBc0I7UUFDMUMsR0FBRzNJO0lBQ0w7SUFFQSxNQUFNLEVBQUNXLE1BQU0zQyxNQUFNLEVBQUV5QyxVQUFVbUksYUFBYSxFQUFFdkgsSUFBSSxFQUFFbkQsVUFBVSxFQUFDLEdBQUd3SztJQUNsRSxNQUFNRyxlQUF1QnpNLGVBQWVnSixnQkFBZ0IvRDtJQUU1RHlILFFBQVFDLEdBQUcsQ0FBQztRQUNWM007UUFDQXlNO1FBQ0FEO1FBQ0F4RDtRQUNBL0Q7SUFDRjtJQUVBLElBQUd1SCxrQkFBa0JDLGNBQWM7UUFDakMsTUFBTTNMLGFBQWE7WUFDakJnRDtZQUNBYyxVQUFVcEQ7WUFDVnFELFFBQVE7Z0JBQUMvQztnQkFBWUY7Z0JBQVFDO1lBQVE7WUFDckNpRCxPQUFPbEUsV0FBVzJMLHNCQUFzQjtRQUMxQyxHQUFHM0k7SUFDTDtJQUVBLElBQUk7UUFDRixNQUFNbEIsUUFBUWYsWUFBWUMsVUFBVSxJQUFJQyxZQUFZLElBQUlDLFlBQVl1SztRQUVwRSxPQUFPM0o7SUFDVCxFQUFFLE9BQU1vRCxPQUFPO1FBQ2IsTUFBTWpGLFNBQVM7WUFDYmlEO1lBQ0FjLFVBQVVwRDtZQUNWcUQsUUFBUTtnQkFBQ2pEO2dCQUFRQztZQUFRO1lBQ3pCaUQsT0FBT2xFLFdBQVdtRixjQUFjO1FBQ2xDLEdBQUdELE9BQU9sQztJQUNaO0FBQ0YsRUFBRTtBQUVGLE9BQU8sTUFBTWdKLFVBQVUsT0FBT2hKO0lBQzVCLE1BQU1FLFNBQVM7SUFDZixNQUFNLEVBQUNDLFlBQVksRUFBRXlHLFNBQVMsRUFBQzVJLFFBQVE2SSxTQUFTLEVBQUU1SSxRQUFRLEVBQUMsR0FBRyxDQUFDLENBQUMsRUFBQyxHQUFHK0I7SUFDcEUsTUFBTTZFLFlBQW9CLENBQUMsTUFBTSxFQUFFZ0MsV0FBVztJQUU5QyxNQUFNckQsU0FBUztRQUNieUYsWUFBWW5HLEtBQUsxRSxHQUFHO1FBQ3BCeUksV0FBVztJQUNiO0lBQ0EsTUFBTXFDLGVBQXlCdk0sR0FBRyxDQUFDLGlCQUFpQixFQUFFa0ksVUFBVTtrQkFDaEQsRUFBRXJCLE9BQU87O2NBRWIsQ0FBQztJQUViLElBQUk7UUFDRixNQUFNbEcsTUFBTTZDLGNBQWN5QixLQUFLLENBQUNzSCxjQUFjckgsSUFBSSxDQUFDLENBQUNDLFNBQVdBLE9BQU9xQixJQUFJO0lBQzVFLEVBQUUsT0FBTWpCLE9BQU87UUFDYmpGLFNBQVM7WUFDUGlEO1lBQ0FjLFVBQVVwRDtZQUNWcUQsUUFBUTtnQkFBQ2pELFFBQVE2STtnQkFBVzVJO1lBQVE7WUFDcENpRCxPQUFPbEUsV0FBV21GLGNBQWM7UUFDbEMsR0FBR0QsT0FBT2xDO1FBRVYsT0FBTztJQUNUO0lBRUEsT0FBTztBQUNULEVBQUU7QUFFRixPQUFPLE1BQU1tSixxQkFBcUIsQ0FBQ25KO0lBQ2pDLE1BQU1FLFNBQVM7SUFDZixNQUFNLEVBQUNDLFlBQVksRUFBQyxHQUFHSDtJQUN2QixNQUFNb0osYUFBdUJ6TSxHQUFHLENBQUM7Ozs7O3FCQUtkLENBQUM7SUFFcEIsT0FBT1csTUFBTTZDLGNBQWN5QixLQUFLLENBQUN3SCxZQUM5QnZILElBQUksQ0FBQyxDQUFDQyxTQUFXQSxPQUFPcUIsSUFBSSxJQUM1QkMsS0FBSyxDQUFDLENBQUNsQjtRQUNOLE1BQU1qRixTQUFTO1lBQ2JpRDtZQUNBYyxVQUFVcEQ7WUFDVnNELE9BQU9sRSxXQUFXbUYsY0FBYztRQUNsQyxHQUFHRCxPQUFPbEM7SUFDWjtBQUNKLEVBQUU7QUFFRixPQUFPLE1BQU1xSixpQkFBaUIsQ0FBQ3JKLFNBQXFCbEI7SUFDbEQsTUFBTW9CLFNBQVM7SUFDZixNQUFNLEVBQUNDLFlBQVksRUFBQyxHQUFHSDtJQUN2QixNQUFNLEVBQUNoQyxNQUFNLEVBQUMsR0FBR1IsV0FBV3NCO0lBQzVCLE1BQU0rRixZQUFZeEksY0FBYyxDQUFDLE1BQU0sRUFBRTJCLFFBQVE7SUFDakQsTUFBTTBHLFdBQXFCL0gsR0FBRyxDQUFDLGtCQUFrQixFQUFFa0ksVUFBVSxXQUFXLENBQUM7SUFFekUsT0FBT3ZILE1BQU02QyxjQUNWeUIsS0FBSyxDQUFDOEMsVUFDTjdDLElBQUksQ0FBQyxDQUFDQyxTQUFXQSxPQUFPcUIsSUFBSSxJQUM1QkMsS0FBSyxDQUFDLENBQUNsQjtRQUNOLE1BQU1qRixTQUFTO1lBQ2JpRDtZQUNBYyxVQUFVcEQ7WUFDVnFELFFBQVE7Z0JBQUNqRDtZQUFNO1lBQ2ZrRCxPQUFPbEUsV0FBV21GLGNBQWM7UUFDbEMsR0FBR0QsT0FBT2xDO0lBQ1o7QUFDSixFQUFFIn0=