@nlabs/reaktor 0.10.2 → 0.10.6

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 (472) hide show
  1. package/coverage/block-navigation.js +1 -1
  2. package/coverage/index.html +23 -23
  3. package/coverage/sorter.js +21 -7
  4. package/lib/actions/apps.d.ts +1 -0
  5. package/lib/actions/apps.d.ts.map +1 -0
  6. package/lib/actions/apps.js +218 -17
  7. package/lib/actions/connections.d.ts +1 -0
  8. package/lib/actions/connections.d.ts.map +1 -0
  9. package/lib/actions/connections.js +61 -6
  10. package/lib/actions/content.d.ts +1 -0
  11. package/lib/actions/content.d.ts.map +1 -0
  12. package/lib/actions/content.js +232 -9
  13. package/lib/actions/conversations.d.ts +1 -0
  14. package/lib/actions/conversations.d.ts.map +1 -0
  15. package/lib/actions/conversations.js +321 -19
  16. package/lib/actions/dynamodb.d.ts +1 -0
  17. package/lib/actions/dynamodb.d.ts.map +1 -0
  18. package/lib/actions/dynamodb.js +119 -2
  19. package/lib/actions/email.d.ts +1 -0
  20. package/lib/actions/email.d.ts.map +1 -0
  21. package/lib/actions/email.js +56 -2
  22. package/lib/actions/files.d.ts +1 -0
  23. package/lib/actions/files.d.ts.map +1 -0
  24. package/lib/actions/files.js +226 -5
  25. package/lib/actions/groups.d.ts +1 -0
  26. package/lib/actions/groups.d.ts.map +1 -0
  27. package/lib/actions/groups.js +234 -19
  28. package/lib/actions/images.d.ts +1 -0
  29. package/lib/actions/images.d.ts.map +1 -0
  30. package/lib/actions/images.js +688 -31
  31. package/lib/actions/index.d.ts +2 -0
  32. package/lib/actions/index.d.ts.map +1 -0
  33. package/lib/actions/index.js +29 -2
  34. package/lib/actions/ios.d.ts +1 -0
  35. package/lib/actions/ios.d.ts.map +1 -0
  36. package/lib/actions/ios.js +228 -9
  37. package/lib/actions/locations.d.ts +1 -0
  38. package/lib/actions/locations.d.ts.map +1 -0
  39. package/lib/actions/locations.js +111 -7
  40. package/lib/actions/messages.d.ts +1 -0
  41. package/lib/actions/messages.d.ts.map +1 -0
  42. package/lib/actions/messages.js +155 -21
  43. package/lib/actions/notifications.d.ts +1 -0
  44. package/lib/actions/notifications.d.ts.map +1 -0
  45. package/lib/actions/notifications.js +37 -2
  46. package/lib/actions/payments.d.ts +1 -0
  47. package/lib/actions/payments.d.ts.map +1 -0
  48. package/lib/actions/payments.js +428 -11
  49. package/lib/actions/posts.d.ts +1 -0
  50. package/lib/actions/posts.d.ts.map +1 -0
  51. package/lib/actions/posts.js +540 -75
  52. package/lib/actions/profiles.d.ts +1 -0
  53. package/lib/actions/profiles.d.ts.map +1 -0
  54. package/lib/actions/profiles.js +58 -8
  55. package/lib/actions/reactions.d.ts +1 -0
  56. package/lib/actions/reactions.d.ts.map +1 -0
  57. package/lib/actions/reactions.js +276 -25
  58. package/lib/actions/s3.d.ts +1 -0
  59. package/lib/actions/s3.d.ts.map +1 -0
  60. package/lib/actions/s3.js +102 -2
  61. package/lib/actions/search.d.ts +1 -0
  62. package/lib/actions/search.d.ts.map +1 -0
  63. package/lib/actions/search.js +81 -5
  64. package/lib/actions/sms.d.ts +1 -0
  65. package/lib/actions/sms.d.ts.map +1 -0
  66. package/lib/actions/sms.js +52 -2
  67. package/lib/actions/statistics.d.ts +1 -0
  68. package/lib/actions/statistics.d.ts.map +1 -0
  69. package/lib/actions/statistics.js +41 -6
  70. package/lib/actions/subscriptions.d.ts +1 -0
  71. package/lib/actions/subscriptions.d.ts.map +1 -0
  72. package/lib/actions/subscriptions.js +196 -6
  73. package/lib/actions/tags.d.ts +1 -0
  74. package/lib/actions/tags.d.ts.map +1 -0
  75. package/lib/actions/tags.js +258 -19
  76. package/lib/actions/users.d.ts +1 -0
  77. package/lib/actions/users.d.ts.map +1 -0
  78. package/lib/actions/users.js +781 -66
  79. package/lib/actions/videos.d.ts +26 -0
  80. package/lib/actions/videos.d.ts.map +1 -0
  81. package/lib/actions/videos.js +423 -0
  82. package/lib/actions/websockets.d.ts +1 -0
  83. package/lib/actions/websockets.d.ts.map +1 -0
  84. package/lib/actions/websockets.js +148 -14
  85. package/lib/adapters/arangoAdapter.d.ts +1 -0
  86. package/lib/adapters/arangoAdapter.d.ts.map +1 -0
  87. package/lib/adapters/arangoAdapter.js +70 -2
  88. package/lib/adapters/contentAdapter.d.ts +1 -0
  89. package/lib/adapters/contentAdapter.d.ts.map +1 -0
  90. package/lib/adapters/contentAdapter.js +108 -2
  91. package/lib/adapters/fileAdapter.d.ts +1 -0
  92. package/lib/adapters/fileAdapter.d.ts.map +1 -0
  93. package/lib/adapters/fileAdapter.js +119 -2
  94. package/lib/adapters/imageAdapter.d.ts +1 -0
  95. package/lib/adapters/imageAdapter.d.ts.map +1 -0
  96. package/lib/adapters/imageAdapter.js +112 -2
  97. package/lib/adapters/index.d.ts +1 -0
  98. package/lib/adapters/index.d.ts.map +1 -0
  99. package/lib/adapters/index.js +11 -2
  100. package/lib/adapters/messageAdapter.d.ts +1 -0
  101. package/lib/adapters/messageAdapter.d.ts.map +1 -0
  102. package/lib/adapters/messageAdapter.js +82 -2
  103. package/lib/adapters/postAdapter.d.ts +1 -0
  104. package/lib/adapters/postAdapter.d.ts.map +1 -0
  105. package/lib/adapters/postAdapter.js +117 -2
  106. package/lib/adapters/reaktorAdapter.d.ts +1 -0
  107. package/lib/adapters/reaktorAdapter.d.ts.map +1 -0
  108. package/lib/adapters/reaktorAdapter.js +59 -2
  109. package/lib/adapters/tagAdapter.d.ts +1 -0
  110. package/lib/adapters/tagAdapter.d.ts.map +1 -0
  111. package/lib/adapters/tagAdapter.js +99 -2
  112. package/lib/adapters/userAdapter.d.ts +1 -0
  113. package/lib/adapters/userAdapter.d.ts.map +1 -0
  114. package/lib/adapters/userAdapter.js +264 -2
  115. package/lib/config.d.ts +1 -0
  116. package/lib/config.d.ts.map +1 -0
  117. package/lib/config.js +161 -2
  118. package/lib/handlers/graphqlHandler.d.ts +1 -0
  119. package/lib/handlers/graphqlHandler.d.ts.map +1 -0
  120. package/lib/handlers/graphqlHandler.js +118 -2
  121. package/lib/index.d.ts +1 -0
  122. package/lib/index.d.ts.map +1 -0
  123. package/lib/index.js +18 -2
  124. package/lib/lambdas/actions/websockets.d.ts +1 -0
  125. package/lib/lambdas/actions/websockets.d.ts.map +1 -0
  126. package/lib/lambdas/actions/websockets.js +89 -14
  127. package/lib/lambdas/authorizer.d.ts +1 -0
  128. package/lib/lambdas/authorizer.d.ts.map +1 -0
  129. package/lib/lambdas/authorizer.js +41 -2
  130. package/lib/lambdas/connection.d.ts +1 -0
  131. package/lib/lambdas/connection.d.ts.map +1 -0
  132. package/lib/lambdas/connection.js +85 -2
  133. package/lib/lambdas/utils/message.d.ts +1 -0
  134. package/lib/lambdas/utils/message.d.ts.map +1 -0
  135. package/lib/lambdas/utils/message.js +20 -2
  136. package/lib/lambdas/utils/websocket.d.ts +1 -0
  137. package/lib/lambdas/utils/websocket.d.ts.map +1 -0
  138. package/lib/lambdas/utils/websocket.js +78 -2
  139. package/lib/mocks/conversation.d.ts +1 -0
  140. package/lib/mocks/conversation.d.ts.map +1 -0
  141. package/lib/mocks/conversation.js +10 -2
  142. package/lib/mocks/file.d.ts +1 -0
  143. package/lib/mocks/file.d.ts.map +1 -0
  144. package/lib/mocks/file.js +13 -2
  145. package/lib/mocks/group.d.ts +1 -0
  146. package/lib/mocks/group.d.ts.map +1 -0
  147. package/lib/mocks/group.js +20 -2
  148. package/lib/mocks/image.d.ts +1 -0
  149. package/lib/mocks/image.d.ts.map +1 -0
  150. package/lib/mocks/image.js +17 -2
  151. package/lib/mocks/post.d.ts +1 -0
  152. package/lib/mocks/post.d.ts.map +1 -0
  153. package/lib/mocks/post.js +28 -2
  154. package/lib/mocks/tag.d.ts +1 -0
  155. package/lib/mocks/tag.d.ts.map +1 -0
  156. package/lib/mocks/tag.js +12 -2
  157. package/lib/mocks/user.d.ts +1 -0
  158. package/lib/mocks/user.d.ts.map +1 -0
  159. package/lib/mocks/user.js +61 -2
  160. package/lib/mocks/video.d.ts +4 -0
  161. package/lib/mocks/video.d.ts.map +1 -0
  162. package/lib/mocks/video.js +17 -0
  163. package/lib/mutations/content.d.ts +1 -0
  164. package/lib/mutations/content.d.ts.map +1 -0
  165. package/lib/mutations/content.js +27 -2
  166. package/lib/mutations/index.d.ts +1 -0
  167. package/lib/mutations/index.d.ts.map +1 -0
  168. package/lib/mutations/index.js +29 -2
  169. package/lib/mutations/locations.d.ts +1 -0
  170. package/lib/mutations/locations.d.ts.map +1 -0
  171. package/lib/mutations/locations.js +22 -2
  172. package/lib/mutations/messages.d.ts +1 -0
  173. package/lib/mutations/messages.d.ts.map +1 -0
  174. package/lib/mutations/messages.js +75 -2
  175. package/lib/mutations/posts.d.ts +1 -0
  176. package/lib/mutations/posts.d.ts.map +1 -0
  177. package/lib/mutations/posts.js +31 -2
  178. package/lib/mutations/profiles.d.ts +1 -0
  179. package/lib/mutations/profiles.d.ts.map +1 -0
  180. package/lib/mutations/profiles.js +78 -2
  181. package/lib/mutations/reactions.d.ts +1 -0
  182. package/lib/mutations/reactions.d.ts.map +1 -0
  183. package/lib/mutations/reactions.js +29 -2
  184. package/lib/mutations/statistics.d.ts +1 -0
  185. package/lib/mutations/statistics.d.ts.map +1 -0
  186. package/lib/mutations/statistics.js +17 -2
  187. package/lib/mutations/subscriptions.d.ts +1 -0
  188. package/lib/mutations/subscriptions.d.ts.map +1 -0
  189. package/lib/mutations/subscriptions.js +38 -2
  190. package/lib/mutations/tags.d.ts +1 -0
  191. package/lib/mutations/tags.d.ts.map +1 -0
  192. package/lib/mutations/tags.js +109 -2
  193. package/lib/mutations/users.d.ts +1 -0
  194. package/lib/mutations/users.d.ts.map +1 -0
  195. package/lib/mutations/users.js +129 -2
  196. package/lib/objectTypes/app.d.ts +1 -0
  197. package/lib/objectTypes/app.d.ts.map +1 -0
  198. package/lib/objectTypes/app.js +147 -2
  199. package/lib/objectTypes/bankAccount.d.ts +1 -0
  200. package/lib/objectTypes/bankAccount.d.ts.map +1 -0
  201. package/lib/objectTypes/bankAccount.js +54 -2
  202. package/lib/objectTypes/connection.d.ts +1 -0
  203. package/lib/objectTypes/connection.d.ts.map +1 -0
  204. package/lib/objectTypes/connection.js +26 -2
  205. package/lib/objectTypes/content.d.ts +1 -0
  206. package/lib/objectTypes/content.d.ts.map +1 -0
  207. package/lib/objectTypes/content.js +79 -2
  208. package/lib/objectTypes/conversation.d.ts +1 -0
  209. package/lib/objectTypes/conversation.d.ts.map +1 -0
  210. package/lib/objectTypes/conversation.js +53 -2
  211. package/lib/objectTypes/creditCard.d.ts +1 -0
  212. package/lib/objectTypes/creditCard.d.ts.map +1 -0
  213. package/lib/objectTypes/creditCard.js +64 -2
  214. package/lib/objectTypes/document.d.ts +1 -0
  215. package/lib/objectTypes/document.d.ts.map +1 -0
  216. package/lib/objectTypes/document.js +21 -2
  217. package/lib/objectTypes/error.d.ts +1 -0
  218. package/lib/objectTypes/error.d.ts.map +1 -0
  219. package/lib/objectTypes/error.js +24 -2
  220. package/lib/objectTypes/external.d.ts +1 -0
  221. package/lib/objectTypes/external.d.ts.map +1 -0
  222. package/lib/objectTypes/external.js +52 -2
  223. package/lib/objectTypes/file.d.ts +1 -0
  224. package/lib/objectTypes/file.d.ts.map +1 -0
  225. package/lib/objectTypes/file.js +76 -2
  226. package/lib/objectTypes/filter.d.ts +1 -0
  227. package/lib/objectTypes/filter.d.ts.map +1 -0
  228. package/lib/objectTypes/filter.js +21 -2
  229. package/lib/objectTypes/group.d.ts +1 -0
  230. package/lib/objectTypes/group.d.ts.map +1 -0
  231. package/lib/objectTypes/group.js +97 -2
  232. package/lib/objectTypes/iapSubscription.d.ts +1 -0
  233. package/lib/objectTypes/iapSubscription.d.ts.map +1 -0
  234. package/lib/objectTypes/iapSubscription.js +18 -2
  235. package/lib/objectTypes/image.d.ts +1 -0
  236. package/lib/objectTypes/image.d.ts.map +1 -0
  237. package/lib/objectTypes/image.js +105 -2
  238. package/lib/objectTypes/index.d.ts +1 -0
  239. package/lib/objectTypes/index.d.ts.map +1 -0
  240. package/lib/objectTypes/index.js +28 -2
  241. package/lib/objectTypes/location.d.ts +1 -0
  242. package/lib/objectTypes/location.d.ts.map +1 -0
  243. package/lib/objectTypes/location.js +85 -2
  244. package/lib/objectTypes/message.d.ts +1 -0
  245. package/lib/objectTypes/message.d.ts.map +1 -0
  246. package/lib/objectTypes/message.js +72 -2
  247. package/lib/objectTypes/passcode.d.ts +1 -0
  248. package/lib/objectTypes/passcode.d.ts.map +1 -0
  249. package/lib/objectTypes/passcode.js +20 -2
  250. package/lib/objectTypes/plan.d.ts +1 -0
  251. package/lib/objectTypes/plan.d.ts.map +1 -0
  252. package/lib/objectTypes/plan.js +71 -2
  253. package/lib/objectTypes/post.d.ts +1 -0
  254. package/lib/objectTypes/post.d.ts.map +1 -0
  255. package/lib/objectTypes/post.js +101 -2
  256. package/lib/objectTypes/profile.d.ts +1 -0
  257. package/lib/objectTypes/profile.d.ts.map +1 -0
  258. package/lib/objectTypes/profile.js +68 -2
  259. package/lib/objectTypes/reaction.d.ts +1 -0
  260. package/lib/objectTypes/reaction.d.ts.map +1 -0
  261. package/lib/objectTypes/reaction.js +37 -2
  262. package/lib/objectTypes/relation.d.ts +1 -0
  263. package/lib/objectTypes/relation.d.ts.map +1 -0
  264. package/lib/objectTypes/relation.js +27 -2
  265. package/lib/objectTypes/search.d.ts +1 -0
  266. package/lib/objectTypes/search.d.ts.map +1 -0
  267. package/lib/objectTypes/search.js +50 -2
  268. package/lib/objectTypes/statistics.d.ts +1 -0
  269. package/lib/objectTypes/statistics.d.ts.map +1 -0
  270. package/lib/objectTypes/statistics.js +17 -2
  271. package/lib/objectTypes/subscription.d.ts +1 -0
  272. package/lib/objectTypes/subscription.d.ts.map +1 -0
  273. package/lib/objectTypes/subscription.js +102 -2
  274. package/lib/objectTypes/tag.d.ts +1 -0
  275. package/lib/objectTypes/tag.d.ts.map +1 -0
  276. package/lib/objectTypes/tag.js +41 -2
  277. package/lib/objectTypes/user.d.ts +1 -0
  278. package/lib/objectTypes/user.d.ts.map +1 -0
  279. package/lib/objectTypes/user.js +111 -2
  280. package/lib/queries/content.d.ts +1 -0
  281. package/lib/queries/content.d.ts.map +1 -0
  282. package/lib/queries/content.js +50 -2
  283. package/lib/queries/index.d.ts +1 -0
  284. package/lib/queries/index.d.ts.map +1 -0
  285. package/lib/queries/index.js +27 -2
  286. package/lib/queries/locations.d.ts +1 -0
  287. package/lib/queries/locations.d.ts.map +1 -0
  288. package/lib/queries/locations.js +23 -2
  289. package/lib/queries/messages.d.ts +1 -0
  290. package/lib/queries/messages.d.ts.map +1 -0
  291. package/lib/queries/messages.js +35 -2
  292. package/lib/queries/posts.d.ts +1 -0
  293. package/lib/queries/posts.d.ts.map +1 -0
  294. package/lib/queries/posts.js +154 -2
  295. package/lib/queries/reactions.d.ts +1 -0
  296. package/lib/queries/reactions.d.ts.map +1 -0
  297. package/lib/queries/reactions.js +34 -2
  298. package/lib/queries/statistics.d.ts +1 -0
  299. package/lib/queries/statistics.d.ts.map +1 -0
  300. package/lib/queries/statistics.js +17 -2
  301. package/lib/queries/subscriptions.d.ts +1 -0
  302. package/lib/queries/subscriptions.d.ts.map +1 -0
  303. package/lib/queries/subscriptions.js +21 -2
  304. package/lib/queries/tags.d.ts +1 -0
  305. package/lib/queries/tags.d.ts.map +1 -0
  306. package/lib/queries/tags.js +56 -2
  307. package/lib/queries/users.d.ts +1 -0
  308. package/lib/queries/users.d.ts.map +1 -0
  309. package/lib/queries/users.js +39 -2
  310. package/lib/templates/email/layout.d.ts +1 -0
  311. package/lib/templates/email/layout.d.ts.map +1 -0
  312. package/lib/templates/email/layout.js +4 -3
  313. package/lib/templates/email/passwordForgot.d.ts +1 -0
  314. package/lib/templates/email/passwordForgot.d.ts.map +1 -0
  315. package/lib/templates/email/passwordForgot.js +4 -3
  316. package/lib/templates/email/passwordRecovery.d.ts +1 -0
  317. package/lib/templates/email/passwordRecovery.d.ts.map +1 -0
  318. package/lib/templates/email/passwordRecovery.js +4 -3
  319. package/lib/templates/email/verifyEmail.d.ts +1 -0
  320. package/lib/templates/email/verifyEmail.d.ts.map +1 -0
  321. package/lib/templates/email/verifyEmail.js +4 -3
  322. package/lib/templates/email/welcome.d.ts +1 -0
  323. package/lib/templates/email/welcome.d.ts.map +1 -0
  324. package/lib/templates/email/welcome.js +4 -3
  325. package/lib/templates/sms/passwordForgot.d.ts +1 -0
  326. package/lib/templates/sms/passwordForgot.d.ts.map +1 -0
  327. package/lib/templates/sms/passwordForgot.js +3 -2
  328. package/lib/templates/sms/passwordRecovery.d.ts +1 -0
  329. package/lib/templates/sms/passwordRecovery.d.ts.map +1 -0
  330. package/lib/templates/sms/passwordRecovery.js +3 -2
  331. package/lib/templates/sms/verifyEmail.d.ts +1 -0
  332. package/lib/templates/sms/verifyEmail.d.ts.map +1 -0
  333. package/lib/templates/sms/verifyEmail.js +3 -2
  334. package/lib/templates/sms/verifyPhone.d.ts +1 -0
  335. package/lib/templates/sms/verifyPhone.d.ts.map +1 -0
  336. package/lib/templates/sms/verifyPhone.js +3 -2
  337. package/lib/templates/sms/welcome.d.ts +1 -0
  338. package/lib/templates/sms/welcome.d.ts.map +1 -0
  339. package/lib/templates/sms/welcome.js +3 -2
  340. package/lib/types/apps.types.d.ts +1 -0
  341. package/lib/types/apps.types.d.ts.map +1 -0
  342. package/lib/types/apps.types.js +10 -2
  343. package/lib/types/arangodb.types.d.ts +2 -1
  344. package/lib/types/arangodb.types.d.ts.map +1 -0
  345. package/lib/types/arangodb.types.js +6 -1
  346. package/lib/types/auth.types.d.ts +1 -0
  347. package/lib/types/auth.types.d.ts.map +1 -0
  348. package/lib/types/auth.types.js +6 -1
  349. package/lib/types/connections.types.d.ts +1 -0
  350. package/lib/types/connections.types.d.ts.map +1 -0
  351. package/lib/types/connections.types.js +6 -1
  352. package/lib/types/content.types.d.ts +1 -0
  353. package/lib/types/content.types.d.ts.map +1 -0
  354. package/lib/types/content.types.js +6 -1
  355. package/lib/types/conversations.types.d.ts +1 -0
  356. package/lib/types/conversations.types.d.ts.map +1 -0
  357. package/lib/types/conversations.types.js +6 -1
  358. package/lib/types/email.types.d.ts +1 -0
  359. package/lib/types/email.types.d.ts.map +1 -0
  360. package/lib/types/email.types.js +6 -1
  361. package/lib/types/error.types.d.ts +1 -0
  362. package/lib/types/error.types.d.ts.map +1 -0
  363. package/lib/types/error.types.js +20 -2
  364. package/lib/types/files.types.d.ts +1 -0
  365. package/lib/types/files.types.d.ts.map +1 -0
  366. package/lib/types/files.types.js +6 -1
  367. package/lib/types/google.types.d.ts +1 -0
  368. package/lib/types/google.types.d.ts.map +1 -0
  369. package/lib/types/google.types.js +6 -1
  370. package/lib/types/groups.types.d.ts +1 -0
  371. package/lib/types/groups.types.d.ts.map +1 -0
  372. package/lib/types/groups.types.js +6 -1
  373. package/lib/types/images.types.d.ts +1 -0
  374. package/lib/types/images.types.d.ts.map +1 -0
  375. package/lib/types/images.types.js +6 -1
  376. package/lib/types/index.d.ts +2 -0
  377. package/lib/types/index.d.ts.map +1 -0
  378. package/lib/types/index.js +28 -2
  379. package/lib/types/locations.types.d.ts +1 -0
  380. package/lib/types/locations.types.d.ts.map +1 -0
  381. package/lib/types/locations.types.js +6 -1
  382. package/lib/types/messages.types.d.ts +1 -0
  383. package/lib/types/messages.types.d.ts.map +1 -0
  384. package/lib/types/messages.types.js +6 -1
  385. package/lib/types/notifications.types.d.ts +1 -0
  386. package/lib/types/notifications.types.d.ts.map +1 -0
  387. package/lib/types/notifications.types.js +6 -1
  388. package/lib/types/payments.types.d.ts +1 -0
  389. package/lib/types/payments.types.d.ts.map +1 -0
  390. package/lib/types/payments.types.js +6 -1
  391. package/lib/types/posts.types.d.ts +1 -0
  392. package/lib/types/posts.types.d.ts.map +1 -0
  393. package/lib/types/posts.types.js +6 -1
  394. package/lib/types/profiles.types.d.ts +1 -0
  395. package/lib/types/profiles.types.d.ts.map +1 -0
  396. package/lib/types/profiles.types.js +3 -1
  397. package/lib/types/statistics.types.d.ts +1 -0
  398. package/lib/types/statistics.types.d.ts.map +1 -0
  399. package/lib/types/statistics.types.js +3 -1
  400. package/lib/types/tags.types.d.ts +1 -0
  401. package/lib/types/tags.types.d.ts.map +1 -0
  402. package/lib/types/tags.types.js +6 -1
  403. package/lib/types/users.types.d.ts +1 -0
  404. package/lib/types/users.types.d.ts.map +1 -0
  405. package/lib/types/users.types.js +6 -1
  406. package/lib/types/videos.types.d.ts +47 -0
  407. package/lib/types/videos.types.d.ts.map +1 -0
  408. package/lib/types/videos.types.js +6 -0
  409. package/lib/types/websockets.types.d.ts +1 -0
  410. package/lib/types/websockets.types.d.ts.map +1 -0
  411. package/lib/types/websockets.types.js +6 -1
  412. package/lib/utils/adapterUtils.d.ts +1 -0
  413. package/lib/utils/adapterUtils.d.ts.map +1 -0
  414. package/lib/utils/adapterUtils.js +23 -2
  415. package/lib/utils/analyticsUtils.d.ts +1 -0
  416. package/lib/utils/analyticsUtils.d.ts.map +1 -0
  417. package/lib/utils/analyticsUtils.js +45 -2
  418. package/lib/utils/arangodbUtils.d.ts +1 -0
  419. package/lib/utils/arangodbUtils.d.ts.map +1 -0
  420. package/lib/utils/arangodbUtils.js +128 -5
  421. package/lib/utils/authUtils.d.ts +1 -0
  422. package/lib/utils/authUtils.d.ts.map +1 -0
  423. package/lib/utils/authUtils.js +54 -2
  424. package/lib/utils/contextUtils.d.ts +1 -0
  425. package/lib/utils/contextUtils.d.ts.map +1 -0
  426. package/lib/utils/contextUtils.js +10 -2
  427. package/lib/utils/dbI18n.d.ts +1 -0
  428. package/lib/utils/dbI18n.d.ts.map +1 -0
  429. package/lib/utils/dbI18n.example.d.ts +1 -0
  430. package/lib/utils/dbI18n.example.d.ts.map +1 -0
  431. package/lib/utils/dbI18n.example.js +92 -5
  432. package/lib/utils/dbI18n.js +28 -2
  433. package/lib/utils/googleTranslate.d.ts +1 -0
  434. package/lib/utils/googleTranslate.d.ts.map +1 -0
  435. package/lib/utils/googleTranslate.js +70 -2
  436. package/lib/utils/graphqlUtils.d.ts +1 -0
  437. package/lib/utils/graphqlUtils.d.ts.map +1 -0
  438. package/lib/utils/graphqlUtils.js +11 -2
  439. package/lib/utils/index.d.ts +1 -0
  440. package/lib/utils/index.d.ts.map +1 -0
  441. package/lib/utils/index.js +19 -2
  442. package/lib/utils/languageDetection.d.ts +1 -0
  443. package/lib/utils/languageDetection.d.ts.map +1 -0
  444. package/lib/utils/languageDetection.js +120 -2
  445. package/lib/utils/localeUtils.d.ts +1 -0
  446. package/lib/utils/localeUtils.d.ts.map +1 -0
  447. package/lib/utils/localeUtils.example.d.ts +1 -0
  448. package/lib/utils/localeUtils.example.d.ts.map +1 -0
  449. package/lib/utils/localeUtils.example.js +124 -2
  450. package/lib/utils/localeUtils.js +71 -2
  451. package/lib/utils/middlewareUtils.d.ts +1 -0
  452. package/lib/utils/middlewareUtils.d.ts.map +1 -0
  453. package/lib/utils/middlewareUtils.js +10 -2
  454. package/lib/utils/sessionUtils.d.ts +1 -0
  455. package/lib/utils/sessionUtils.d.ts.map +1 -0
  456. package/lib/utils/sessionUtils.js +26 -2
  457. package/lib/utils/stripeUtils.d.ts +2 -1
  458. package/lib/utils/stripeUtils.d.ts.map +1 -0
  459. package/lib/utils/stripeUtils.js +12 -2
  460. package/lib/utils/templateUtils.d.ts +1 -0
  461. package/lib/utils/templateUtils.d.ts.map +1 -0
  462. package/lib/utils/templateUtils.js +11 -2
  463. package/lib/utils/testUtils.d.ts +1 -0
  464. package/lib/utils/testUtils.d.ts.map +1 -0
  465. package/lib/utils/testUtils.js +292 -2
  466. package/lib/utils/translationQueue.d.ts +1 -0
  467. package/lib/utils/translationQueue.d.ts.map +1 -0
  468. package/lib/utils/translationQueue.example.d.ts +1 -0
  469. package/lib/utils/translationQueue.example.d.ts.map +1 -0
  470. package/lib/utils/translationQueue.example.js +340 -2
  471. package/lib/utils/translationQueue.js +113 -2
  472. package/package.json +47 -29
@@ -1,112 +1,386 @@
1
- import{parseNum as L}from"@nlabs/utils/parsers/numbers";import{createHash as v,parseArangoId as S,parseChar as _,parseId as D,parseString as q,parseVarChar as x}from"@nlabs/utils/parsers/strings";import{aql as A}from"arangojs";import{parsePost as H}from"../adapters/postAdapter.js";import{ErrorTypes as m}from"../types/error.types.js";import{logError as f,logException as w}from"../utils/analyticsUtils.js";import{getLimit as V,useDb as E}from"../utils/arangodbUtils.js";import{extractTags as B,getTagsByName as U,updateTagsInItem as Q}from"./tags.js";const W=1e5,O="posts",$=(t={})=>{const{from:r=0,latitude:e=0,longitude:o=0,to:i=30,type:n="post"}=t;return{latitude:L(e,32),limit:V(r,i),longitude:L(o,32),type:_(n,32)}},C=(t=[],r="")=>(t||[]).reduce((e,o)=>{switch(o){case"hasRsvp":return e.queries.push(`LET hasRsvp = TO_BOOL(FIRST(
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, parseArangoId, parseChar, parseId, parseString, parseVarChar } from '@nlabs/utils/parsers/strings';
6
+ import { aql } from 'arangojs';
7
+ import { parsePost } from '../adapters/postAdapter.js';
8
+ import { ErrorTypes } from '../types/error.types.js';
9
+ import { logError, logException } from '../utils/analyticsUtils.js';
10
+ import { getLimit, useDb } from '../utils/arangodbUtils.js';
11
+ import { extractTags, getTagsByName, updateTagsInItem } from './tags.js';
12
+ const MAX_CONTENT_LENGTH = 100000;
13
+ const eventCategory = 'posts';
14
+ export const parsePostOptions = (options = {})=>{
15
+ const { from = 0, latitude = 0, longitude = 0, to = 30, type = 'post' } = options;
16
+ return {
17
+ latitude: parseNum(latitude, 32),
18
+ limit: getLimit(from, to),
19
+ longitude: parseNum(longitude, 32),
20
+ type: parseChar(type, 32)
21
+ };
22
+ };
23
+ export const getPostOptional = (fields = [], sessionId = '')=>(fields || []).reduce((selects, field)=>{
24
+ switch(field){
25
+ case 'hasRsvp':
26
+ {
27
+ selects.queries.push(`LET hasRsvp = TO_BOOL(FIRST(
2
28
  FOR post, r IN INBOUND p._id hasReaction
3
- FILTER r.name == "rsvp" && r.type == "posts" && r._from == "users/${r}"
29
+ FILTER r.name == "rsvp" && r.type == "posts" && r._from == "users/${sessionId}"
4
30
  COLLECT WITH COUNT INTO count
5
31
  RETURN count
6
- ))`),e.objects.push("hasRsvp:hasRsvp"),e;case"isSaved":return e.queries.push(`LET isSaved = TO_BOOL(FIRST(
32
+ ))`);
33
+ selects.objects.push('hasRsvp:hasRsvp');
34
+ return selects;
35
+ }
36
+ case 'isSaved':
37
+ {
38
+ selects.queries.push(`LET isSaved = TO_BOOL(FIRST(
7
39
  FOR post, r IN INBOUND p._id hasReaction
8
- FILTER r.name == "pin" && r.type == "posts" && r._from == "users/${r}"
40
+ FILTER r.name == "pin" && r.type == "posts" && r._from == "users/${sessionId}"
9
41
  COLLECT WITH COUNT INTO count
10
42
  RETURN count
11
- ))`),e.objects.push("isSaved:isSaved"),e;case"reactions":return e.queries.push(`LET reactions = (
43
+ ))`);
44
+ selects.objects.push('isSaved:isSaved');
45
+ return selects;
46
+ }
47
+ case 'reactions':
48
+ {
49
+ selects.queries.push(`LET reactions = (
12
50
  FOR post, r IN INBOUND p._id hasReaction
13
51
  COLLECT reactionName = r.value INTO reactionItems
14
52
  RETURN {name: reactionName, count: LENGTH(reactionItems[*].r.value)}
15
- )`),e.objects.push("reactions:reactions"),e;case"rsvpCount":return e.queries.push(`LET rsvpCount = FIRST(
53
+ )`);
54
+ selects.objects.push('reactions:reactions');
55
+ return selects;
56
+ }
57
+ case 'rsvpCount':
58
+ {
59
+ selects.queries.push(`LET rsvpCount = FIRST(
16
60
  FOR post, r IN INBOUND p._id hasReaction
17
61
  FILTER r.name == "rsvp" && r.type == "posts"
18
62
  COLLECT WITH COUNT INTO count
19
63
  RETURN count
20
- )`),e.objects.push("rsvpCount:rsvpCount"),e;case"viewCount":return e.queries.push(`LET viewCount = FIRST(
64
+ )`);
65
+ selects.objects.push('rsvpCount:rsvpCount');
66
+ return selects;
67
+ }
68
+ case 'viewCount':
69
+ {
70
+ selects.queries.push(`LET viewCount = FIRST(
21
71
  FOR post, r IN INBOUND p._id hasReaction
22
72
  FILTER r.name == "view" && r.type == "posts"
23
73
  COLLECT WITH COUNT INTO count
24
74
  RETURN count
25
- )`),e.objects.push("viewCount:viewCount"),e;default:return e}},{objects:[],queries:[]}),st=async(t,r,e)=>{const o="getPost",{databaseName:i,fields:n,session:{userId:p}={}}=t,R=D(r),{type:c}=$(e),s=E(i),{objects:a,queries:u}=C(n,p),d=A`FOR p IN posts
26
- FILTER p._key == ${R} && p.type == ${c}
75
+ )`);
76
+ selects.objects.push('viewCount:viewCount');
77
+ return selects;
78
+ }
79
+ default:
80
+ {
81
+ return selects;
82
+ }
83
+ }
84
+ }, {
85
+ objects: [],
86
+ queries: []
87
+ });
88
+ export const getPost = async (context, postId, options)=>{
89
+ const action = 'getPost';
90
+ const { databaseName, fields, session: { userId: sessionId } = {} } = context;
91
+ const formatItemId = parseId(postId);
92
+ const { type } = parsePostOptions(options);
93
+ const database = useDb(databaseName);
94
+ const { objects: selectObjects, queries: selectQueries } = getPostOptional(fields, sessionId);
95
+ const aqlQry = aql`FOR p IN posts
96
+ FILTER p._key == ${formatItemId} && p.type == ${type}
27
97
  LIMIT 1
28
- RETURN p`;return s.query(d).then(I=>I.next()).then(I=>{const{_id:g,userId:T,groupId:h,privacy:N="default"}=I;let y;return T===p?I:(h&&N==="group"?y=`LET p = DOCUMENT("${g}")
29
- ${u.join(`
30
- `)}
98
+ RETURN p`;
99
+ return database.query(aqlQry).then((cursor)=>cursor.next()).then((post)=>{
100
+ const { _id: postDocId, userId, groupId, privacy = 'default' } = post;
101
+ let privacyAqlQry;
102
+ if (userId === sessionId) {
103
+ return post;
104
+ }
105
+ if (groupId && privacy === 'group') {
106
+ privacyAqlQry = `LET p = DOCUMENT("${postDocId}")
107
+ ${selectQueries.join('\n')}
31
108
  FOR group IN groups
32
109
  FILTER group._key == p.groupId
33
110
  FOR u, e IN OUTBOUND group._id hasConnection
34
- FILTER u._key == "${p}"
111
+ FILTER u._key == "${sessionId}"
35
112
  LIMIT 1
36
- RETURN MERGE(p, {${a.join(", ")}})`:N==="public"&&(y=`LET p = DOCUMENT("${g}")
37
- ${u.join(`
38
- `)}
113
+ RETURN MERGE(p, {${selectObjects.join(', ')}})`;
114
+ } else if (privacy === 'public') {
115
+ privacyAqlQry = `LET p = DOCUMENT("${postDocId}")
116
+ ${selectQueries.join('\n')}
39
117
  LIMIT 1
40
- RETURN MERGE(p, {${a.join(", ")}})`),y?s.query(y).then(l=>l.next()).catch(l=>f({action:o,category:O,label:m.DATABASE_ERROR},l,t)):{})}).catch(I=>f({action:o,category:O,label:m.DATABASE_ERROR},I,t))},ot=(t,r,e,o)=>{const i="getPostsByArea",{databaseName:n,fields:p,session:{userId:R}={}}=t,{limit:c,type:s}=$(o),a=L(r),u=L(e),{objects:d,queries:I}=C(p,R);I.push(`LET distance = DISTANCE(
41
- ${a},
42
- ${u},
118
+ RETURN MERGE(p, {${selectObjects.join(', ')}})`;
119
+ }
120
+ if (privacyAqlQry) {
121
+ return database.query(privacyAqlQry).then((cursor)=>cursor.next()).catch((error)=>logError({
122
+ action,
123
+ category: eventCategory,
124
+ label: ErrorTypes.DATABASE_ERROR
125
+ }, error, context));
126
+ }
127
+ return {};
128
+ }).catch((error)=>logError({
129
+ action,
130
+ category: eventCategory,
131
+ label: ErrorTypes.DATABASE_ERROR
132
+ }, error, context));
133
+ };
134
+ // export const getPostList = (context: ApiContext, options?: PostOptions): Promise<PostType[]> => {
135
+ // // const action: string = 'getListByApp';
136
+ // const {database, fields, session: {userId: sessionId}} = context;
137
+ // const {limit, type} = parsePostOptions(options);
138
+ // const {objects: selectObjects, queries: selectQueries} = getPostOptional(fields, sessionId);
139
+ // const aqlQry: string = `FOR p IN posts
140
+ // FILTER p.type == "${type}" && p.privacy == "public" && p.parent == null
141
+ // ${selectQueries.join('\n')}
142
+ // ${limit.aql}
143
+ // SORT p.added
144
+ // RETURN DISTINCT MERGE(p, {${selectObjects.join(', ')}})`;
145
+ // return database.query(aqlQry)
146
+ // .then((cursor) => cursor.all())
147
+ // .catch((error: Error) => {
148
+ // throw error;
149
+ // });
150
+ // };
151
+ export const getPostsByArea = (context, latitude, longitude, options)=>{
152
+ const action = 'getPostsByArea';
153
+ const { databaseName, fields, session: { userId: sessionId } = {} } = context;
154
+ const { limit, type } = parsePostOptions(options);
155
+ const formatLatitude = parseNum(latitude);
156
+ const formatLongitude = parseNum(longitude);
157
+ const { objects: selectObjects, queries: selectQueries } = getPostOptional(fields, sessionId);
158
+ selectQueries.push(`LET distance = DISTANCE(
159
+ ${formatLatitude},
160
+ ${formatLongitude},
43
161
  NOT_NULL(p.latitude, 0),
44
162
  NOT_NULL(p.longitude, 0))
45
- `),d.push("distance:distance");const g=`FOR p IN posts
46
- ${I.join(`
47
- `)}
48
- FILTER p.type == "${s}" && p.privacy == "public" && p.parentId == null
49
- ${c.aql}
163
+ `);
164
+ selectObjects.push('distance:distance');
165
+ const aqlQry = `FOR p IN posts
166
+ ${selectQueries.join('\n')}
167
+ FILTER p.type == "${type}" && p.privacy == "public" && p.parentId == null
168
+ ${limit.aql}
50
169
  SORT distance, p.added
51
- RETURN DISTINCT MERGE(p, {${d.join(", ")}})`;return E(n).query(g).then(T=>T.all()).catch(T=>(f({action:i,category:O,label:m.DATABASE_ERROR},T,t),[]))},rt=(t,r)=>{const{databaseName:e,fields:o,session:{userId:i}={}}=t,{limit:n,type:p}=$(r),{objects:R,queries:c}=C(o,i),s=`FOR p IN posts
52
- FILTER p.type == "${p}" && p.privacy == "public" && p.parent == null
53
- ${c.join(`
54
- `)}
55
- ${n.aql}
170
+ RETURN DISTINCT MERGE(p, {${selectObjects.join(', ')}})`;
171
+ return useDb(databaseName).query(aqlQry).then((cursor)=>cursor.all()).catch((error)=>{
172
+ logError({
173
+ action,
174
+ category: eventCategory,
175
+ label: ErrorTypes.DATABASE_ERROR
176
+ }, error, context);
177
+ return [];
178
+ });
179
+ };
180
+ // export const getPostsByGroup = (
181
+ // context: ApiContext,
182
+ // groupId: string,
183
+ // options?: PostOptions
184
+ // ): Promise<PostType[]> => {
185
+ // // const action: string = 'getListByGroup';
186
+ // const {database, fields, session: {userId: sessionId}} = context;
187
+ // const {objects: selectObjects, queries: selectQueries} = getPostOptional(fields, sessionId);
188
+ // // Group id
189
+ // const formatGroupId: string = parseId(groupId);
190
+ // const db = database;
191
+ // const aqlQry: string = `FOR u, g IN INBOUND ${formatGroupId} hasGroup
192
+ // FILTER u._key == ${sessionId}
193
+ // RETURN g`;
194
+ // return db.query(aqlQry)
195
+ // .then((cursor) => cursor.all())
196
+ // .then((groups: GroupType[] = []) => {
197
+ // if(groups.length) {
198
+ // const {limit, type} = parsePostOptions(options);
199
+ // const postAqlQry: string = `FOR p IN posts
200
+ // FILTER p.type == "${type}" && p.groupId == "${formatGroupId}" && p.parent == null
201
+ // ${selectQueries.join('\n')}
202
+ // ${limit.aql}
203
+ // SORT p.added
204
+ // RETURN DISTINCT MERGE(p, {${selectObjects.join(', ')}})`;
205
+ // return db.query(postAqlQry)
206
+ // .then((cursor) => cursor.all())
207
+ // .catch((error: Error) => {
208
+ // throw error;
209
+ // });
210
+ // }
211
+ // return [];
212
+ // })
213
+ // .catch((error: Error) => {
214
+ // throw error;
215
+ // });
216
+ // };
217
+ export const getPostsByLatest = (context, options)=>{
218
+ // const action: string = 'getListByLatest';
219
+ const { databaseName, fields, session: { userId: sessionId } = {} } = context;
220
+ const { limit, type } = parsePostOptions(options);
221
+ const { objects: selectObjects, queries: selectQueries } = getPostOptional(fields, sessionId);
222
+ const aqlQry = `FOR p IN posts
223
+ FILTER p.type == "${type}" && p.privacy == "public" && p.parent == null
224
+ ${selectQueries.join('\n')}
225
+ ${limit.aql}
56
226
  SORT p.added DESC
57
- RETURN DISTINCT MERGE(p, {${R.join(", ")}})`;return E(e).query(s).then(a=>a.all()).catch(a=>{throw a})},nt=(t,r=[],e)=>{const o="getPostsByReactions",{databaseName:i,fields:n,session:{userId:p}={}}=t,{latitude:R,limit:c,longitude:s,type:a}=$(e),{objects:u,queries:d}=C(n,p),I=`users/${p}`,g=JSON.stringify(r.map(P=>_(P,32).toLowerCase())),T=[],h=[`p.type == "${a}"`,'p.privacy == "public"'],N=L(R),y=L(s);N&&y&&(d.push(`LET distance = DISTANCE(
58
- ${N},
59
- ${y},
227
+ RETURN DISTINCT MERGE(p, {${selectObjects.join(', ')}})`;
228
+ return useDb(databaseName).query(aqlQry).then((cursor)=>cursor.all()).catch((error)=>{
229
+ throw error;
230
+ });
231
+ };
232
+ export const getPostsByReactions = (context, reactions = [], options)=>{
233
+ const action = 'getPostsByReactions';
234
+ const { databaseName, fields, session: { userId: sessionId } = {} } = context;
235
+ const { latitude, limit, longitude, type } = parsePostOptions(options);
236
+ const { objects: selectObjects, queries: selectQueries } = getPostOptional(fields, sessionId);
237
+ const formatSessionId = `users/${sessionId}`;
238
+ const formatReactions = JSON.stringify(reactions.map((reaction)=>parseChar(reaction, 32).toLowerCase()));
239
+ const sortBy = [];
240
+ const filters = [
241
+ `p.type == "${type}"`,
242
+ 'p.privacy == "public"'
243
+ ];
244
+ const formatLatitude = parseNum(latitude);
245
+ const formatLongitude = parseNum(longitude);
246
+ if (formatLatitude && formatLongitude) {
247
+ selectQueries.push(`LET distance = DISTANCE(
248
+ ${formatLatitude},
249
+ ${formatLongitude},
60
250
  NOT_NULL(p.latitude, 0),
61
251
  NOT_NULL(p.longitude, 0))
62
- `),u.push("distance:distance"),T.push("distance")),r.length&&(T.push("matchedTags DESC"),d.push(`LET matchedReactions = LENGTH(
252
+ `);
253
+ selectObjects.push('distance:distance');
254
+ sortBy.push('distance');
255
+ }
256
+ if (reactions.length) {
257
+ sortBy.push('matchedTags DESC');
258
+ selectQueries.push(`LET matchedReactions = LENGTH(
63
259
  FOR mr IN reactions
64
260
  FILTER mr.matched == true
65
261
  RETURN mr
66
- )`),u.push("matchedReactions:matchedReactions"),h.push("matchedReactions > 0")),T.push("p.added DESC"),u.push("reactions:reactions");const l=`FOR p, r IN OUTBOUND "${I}" hasReaction
262
+ )`);
263
+ selectObjects.push('matchedReactions:matchedReactions');
264
+ filters.push('matchedReactions > 0');
265
+ }
266
+ sortBy.push('p.added DESC');
267
+ selectObjects.push('reactions:reactions');
268
+ // Get data from database
269
+ const aqlQry = `FOR p, r IN OUTBOUND "${formatSessionId}" hasReaction
67
270
  LET reactions = (
68
271
  FOR reaction, hr IN 1..1 INBOUND p isTagged
69
- LET matched = LENGTH(${g}) > 0 && POSITION(${g}, reaction.name)
272
+ LET matched = LENGTH(${formatReactions}) > 0 && POSITION(${formatReactions}, reaction.name)
70
273
  SORT reaction.name
71
274
  RETURN MERGE(reaction, {matched:matched})
72
275
  )
73
- ${d.join(`
74
- `)}
75
- FILTER ${h.join(" && ")}
76
- ${c.aql}
77
- RETURN DISTINCT MERGE(p, {${u.join(", ")}})`;return E(i).query(l).then(P=>P.all()).catch(P=>(f({action:o,category:O,label:m.DATABASE_ERROR},P,t),[]))},at=(t,r=[],e)=>{const o="getPostsByTags",{databaseName:i,fields:n,session:{userId:p}={}}=t,{latitude:R,limit:c,longitude:s,type:a}=$(e),{objects:u,queries:d}=C(n,p),I=JSON.stringify(r.map(l=>_(l,32).toLowerCase())),g=[],T=[`p.type == "${a}"`,'p.privacy == "public"'],h=L(R),N=L(s);h&&N&&(d.push(`LET distance = DISTANCE(
78
- ${h},
79
- ${N},
276
+ ${selectQueries.join('\n')}
277
+ FILTER ${filters.join(' && ')}
278
+ ${limit.aql}
279
+ RETURN DISTINCT MERGE(p, {${selectObjects.join(', ')}})`;
280
+ return useDb(databaseName).query(aqlQry).then((cursor)=>cursor.all()).catch((error)=>{
281
+ logError({
282
+ action,
283
+ category: eventCategory,
284
+ label: ErrorTypes.DATABASE_ERROR
285
+ }, error, context);
286
+ return [];
287
+ });
288
+ };
289
+ export const getPostsByTags = (context, tags = [], options)=>{
290
+ const action = 'getPostsByTags';
291
+ const { databaseName, fields, session: { userId: sessionId } = {} } = context;
292
+ const { latitude, limit, longitude, type } = parsePostOptions(options);
293
+ const { objects: selectObjects, queries: selectQueries } = getPostOptional(fields, sessionId);
294
+ const formatTagNames = JSON.stringify(tags.map((tag)=>parseChar(tag, 32).toLowerCase()));
295
+ const sortBy = [];
296
+ const filters = [
297
+ `p.type == "${type}"`,
298
+ 'p.privacy == "public"'
299
+ ];
300
+ const formatLatitude = parseNum(latitude);
301
+ const formatLongitude = parseNum(longitude);
302
+ if (formatLatitude && formatLongitude) {
303
+ selectQueries.push(`LET distance = DISTANCE(
304
+ ${formatLatitude},
305
+ ${formatLongitude},
80
306
  NOT_NULL(p.latitude, 0),
81
307
  NOT_NULL(p.longitude, 0))
82
- `),u.push("distance:distance"),g.push("distance")),r.length&&(g.push("matchedTags DESC"),d.push(`LET matchedTags = LENGTH(
308
+ `);
309
+ selectObjects.push('distance:distance');
310
+ sortBy.push('distance');
311
+ }
312
+ if (tags.length) {
313
+ sortBy.push('matchedTags DESC');
314
+ selectQueries.push(`LET matchedTags = LENGTH(
83
315
  FOR t IN tags
84
316
  FILTER t.matched == true
85
317
  RETURN t
86
- )`),u.push("matchedTags:matchedTags"),T.push("matchedTags > 0")),g.push("p.added DESC"),u.push("tags:tags");const y=`FOR p IN posts
318
+ )`);
319
+ selectObjects.push('matchedTags:matchedTags');
320
+ filters.push('matchedTags > 0');
321
+ }
322
+ sortBy.push('p.added DESC');
323
+ selectObjects.push('tags:tags');
324
+ const aqlQry = `FOR p IN posts
87
325
  LET tags = (
88
326
  FOR tag, it IN 1..1 INBOUND p isTagged
89
- LET matched = LENGTH(${I}) > 0 && POSITION(${I}, tag.name)
327
+ LET matched = LENGTH(${formatTagNames}) > 0 && POSITION(${formatTagNames}, tag.name)
90
328
  SORT tag.name
91
329
  RETURN MERGE(tag, {matched:matched})
92
330
  )
93
- ${d.join(`
94
- `)}
95
- FILTER ${T.join(" && ")}
96
- ${c.aql}
97
- SORT ${g.join(", ")}
98
- RETURN DISTINCT MERGE(p, {${u.join(", ")}})`;return E(i).query(y).then(l=>l.all()).catch(l=>(f({action:o,category:O,label:m.DATABASE_ERROR},l,t),[]))},it=(t,r,e)=>{const o="getPostsByUser",{databaseName:i,fields:n,session:{userId:p}={}}=t,{limit:R,type:c}=$(e),s=D(r),{objects:a,queries:u}=C(n,p),d=`FOR p IN posts
99
- FILTER p.userId == "${s}" && p.type == "${c}" && p.privacy == "public" && p.parent == null
100
- ${u.join(`
101
- `)}
102
- ${R.aql}
331
+ ${selectQueries.join('\n')}
332
+ FILTER ${filters.join(' && ')}
333
+ ${limit.aql}
334
+ SORT ${sortBy.join(', ')}
335
+ RETURN DISTINCT MERGE(p, {${selectObjects.join(', ')}})`;
336
+ return useDb(databaseName).query(aqlQry).then((cursor)=>cursor.all()).catch((error)=>{
337
+ logError({
338
+ action,
339
+ category: eventCategory,
340
+ label: ErrorTypes.DATABASE_ERROR
341
+ }, error, context);
342
+ return [];
343
+ });
344
+ };
345
+ export const getPostsByUser = (context, userId, options)=>{
346
+ const action = 'getPostsByUser';
347
+ const { databaseName, fields, session: { userId: sessionId } = {} } = context;
348
+ const { limit, type } = parsePostOptions(options);
349
+ const formatUserId = parseId(userId);
350
+ const { objects: selectObjects, queries: selectQueries } = getPostOptional(fields, sessionId);
351
+ const aqlQry = `FOR p IN posts
352
+ FILTER p.userId == "${formatUserId}" && p.type == "${type}" && p.privacy == "public" && p.parent == null
353
+ ${selectQueries.join('\n')}
354
+ ${limit.aql}
103
355
  SORT p.added
104
- RETURN DISTINCT MERGE(p, {${a.join(", ")}})`;return E(i).query(d).then(I=>I.all()).catch(I=>(f({action:o,category:O,label:m.DATABASE_ERROR},I,t),[]))},pt=(t,r,e)=>{const o="getPostComments",{databaseName:i,session:{userId:n}={}}=t,{limit:p,type:R}=$(e),c=D(r),s=A`FOR p IN posts
105
- FILTER p.type == ${R} && p._key == ${c}
356
+ RETURN DISTINCT MERGE(p, {${selectObjects.join(', ')}})`;
357
+ return useDb(databaseName).query(aqlQry).then((cursor)=>cursor.all()).catch((error)=>{
358
+ logError({
359
+ action,
360
+ category: eventCategory,
361
+ label: ErrorTypes.DATABASE_ERROR
362
+ }, error, context);
363
+ return [];
364
+ });
365
+ };
366
+ export const getPostComments = (context, postId, options)=>{
367
+ const action = 'getPostComments';
368
+ const { databaseName, session: { userId: sessionId } = {} } = context;
369
+ const { limit, type } = parsePostOptions(options);
370
+ const formatItemId = parseId(postId);
371
+ // Get the parent post to get restrictions
372
+ const aqlQry = aql`FOR p IN posts
373
+ FILTER p.type == ${type} && p._key == ${formatItemId}
106
374
  LIMIT 1
107
- RETURN p`;return E(i).query(s).then(a=>a.next()).then(a=>{const{_key:u,groupId:d,privacy:I="default"}=a;let g;return d&&I==="group"?g=`FOR p IN posts
375
+ RETURN p`;
376
+ return useDb(databaseName).query(aqlQry).then((cursor)=>cursor.next()).then((post)=>{
377
+ const { _key, groupId, privacy = 'default' } = post;
378
+ // Query based on privacy level
379
+ let privacyAqlQry;
380
+ if (groupId && privacy === 'group') {
381
+ privacyAqlQry = `FOR p IN posts
108
382
  FOR user IN users
109
- FILTER p.parent == "${u}" && user._key == p.userId
383
+ FILTER p.parent == "${_key}" && user._key == p.userId
110
384
  LET reactions = (
111
385
  FOR post, r IN INBOUND p._id reactions
112
386
  COLLECT reactionName = r.value INTO reactionItems
@@ -115,29 +389,220 @@ import{parseNum as L}from"@nlabs/utils/parsers/numbers";import{createHash as v,p
115
389
  FOR group IN groups
116
390
  FILTER group._key == p.groupId
117
391
  FOR u, e IN OUTBOUND group._id hasConnection
118
- FILTER u._key == "${n}"
392
+ FILTER u._key == "${sessionId}"
119
393
  SORT p.added
120
- ${p.aql}
121
- RETURN MERGE(p, {user: user, reactions: reactions})`:I==="public"&&(g=`FOR p IN posts
394
+ ${limit.aql}
395
+ RETURN MERGE(p, {user: user, reactions: reactions})`;
396
+ } else if (privacy === 'public') {
397
+ privacyAqlQry = `FOR p IN posts
122
398
  FOR user IN users
123
- FILTER p.parent == "${u}" && user._key == p.userId
399
+ FILTER p.parent == "${_key}" && user._key == p.userId
124
400
  LET reactions = (
125
401
  FOR post, r IN INBOUND p._id reactions
126
402
  COLLECT reactionName = r.value INTO reactionItems
127
403
  RETURN {name: reactionName, count: LENGTH(reactionItems[*].r.value)}
128
404
  )
129
405
  SORT p.added
130
- ${p.aql}
131
- RETURN MERGE(p, {user: user, reactions: reactions})`),g?E(i).query(g).then(T=>T.all()).catch(T=>(f({action:o,category:O,label:m.DATABASE_ERROR},T,t),[])):[]}).catch(a=>(f({action:o,category:O,label:m.DATABASE_ERROR},a,t),[]))},ct=async(t,{content:r="",endDate:e,groupId:o="",location:i,latitude:n,longitude:p,name:R="",parentId:c="",privacy:s="public",tags:a=[],startDate:u,type:d="default"})=>{const I="addPost",{databaseName:g,session:{userId:T}={}}=t,h=Date.now(),N=v(`post-${T}`),y={_id:`posts/${N}`,_key:N,added:h,content:q(r,W)||"",endDate:e?L(e,13):void 0,groupId:o?D(o):void 0,latitude:n!==void 0?L(n):void 0,location:i?q(i,160):void 0,longitude:p!==void 0?L(p):void 0,modified:h,name:q(R,160),parentId:c?D(c):void 0,privacy:x(s,16),startDate:u?L(u,13):void 0,type:_(d,32),userId:T},l=A`INSERT ${y} IN posts RETURN NEW`;try{const P=await E(g).query(l).then(b=>b.next()).catch(b=>f({action:I,category:O,label:m.DATABASE_ERROR},b,t)),{_id:M}=P,j=await B(y.content||"");if(a.length||j.length){const b=(await U(t,a.map(({name:F})=>F||""))).map(F=>({...F,tagBy:T})),G=(await U(t,j||[])).map(F=>({...F,tagBy:"extract"})),k=await Q(t,{itemDocId:M,tags:[...G,...b]});return{...P,tags:k}}return P}catch(P){throw P}},ut=async(t,r)=>{const e="updatePost",{databaseName:o,session:{userId:i}={}}=t,n=Date.now(),p=H(r),{postId:R,tags:c=[]}=p,s={...p,modified:n};if(!R)throw w({action:e,category:O,value:m.INVALID_ID},t);const a={...s,_key:R,added:n,userId:i},u=A`UPSERT {_key: ${R}, userId: ${i}}
132
- INSERT ${a}
133
- UPDATE ${s}
134
- IN posts RETURN NEW`;try{const d=await E(o).query(u).then(T=>T.next()).catch(T=>f({action:e,category:O,value:m.DATABASE_ERROR},T,{})),{_id:I}=d,g=await B(a.content||"");if(c?.length||g?.length){const T=c?.length?(await U(t,c.map(({name:y})=>y||""))).map(y=>({...y,tagBy:i})):[],h=g?.length?(await U(t,g||[])).map(y=>({...y,tagBy:"extract"})):[],N=await Q(t,{itemDocId:I,tags:[...h,...T]});return{...d,tags:N}}return d}catch(d){throw d}},dt=async(t,r)=>{const e="deletePost",{databaseName:o,session:{userId:i}={}}=t,n=S(r);if(!n)throw w({action:e,category:O,value:m.INVALID_ID},t);const p=A`FOR t IN isTagged
135
- FILTER t._to == ${n}
136
- REMOVE t IN isTagged`;await E(o).query(p).catch(s=>{throw s});const R=A`FOR f IN hasFile
137
- FILTER f._to == ${n}
138
- REMOVE f IN hasFile`;await E(o).query(R).catch(s=>{throw s});const c=A`FOR p IN posts
139
- FILTER p._id == ${n} && p.userId == ${i}
406
+ ${limit.aql}
407
+ RETURN MERGE(p, {user: user, reactions: reactions})`;
408
+ }
409
+ if (privacyAqlQry) {
410
+ return useDb(databaseName).query(privacyAqlQry).then((cursor)=>cursor.all()).catch((error)=>{
411
+ logError({
412
+ action,
413
+ category: eventCategory,
414
+ label: ErrorTypes.DATABASE_ERROR
415
+ }, error, context);
416
+ return [];
417
+ });
418
+ }
419
+ return [];
420
+ }).catch((error)=>{
421
+ logError({
422
+ action,
423
+ category: eventCategory,
424
+ label: ErrorTypes.DATABASE_ERROR
425
+ }, error, context);
426
+ return [];
427
+ });
428
+ };
429
+ export const addPost = async (context, { content = '', endDate, groupId = '', location, latitude, longitude, name = '', parentId = '', privacy = 'public', tags = [], startDate, type = 'default' })=>{
430
+ const action = 'addPost';
431
+ const { databaseName, session: { userId: sessionId } = {} } = context;
432
+ const now = Date.now();
433
+ const postId = createHash(`post-${sessionId}`);
434
+ const insert = {
435
+ _id: `posts/${postId}`,
436
+ _key: postId,
437
+ added: now,
438
+ content: parseString(content, MAX_CONTENT_LENGTH) || '',
439
+ endDate: endDate ? parseNum(endDate, 13) : undefined,
440
+ groupId: groupId ? parseId(groupId) : undefined,
441
+ latitude: latitude !== undefined ? parseNum(latitude) : undefined,
442
+ location: location ? parseString(location, 160) : undefined,
443
+ longitude: longitude !== undefined ? parseNum(longitude) : undefined,
444
+ modified: now,
445
+ name: parseString(name, 160),
446
+ parentId: parentId ? parseId(parentId) : undefined,
447
+ privacy: parseVarChar(privacy, 16),
448
+ startDate: startDate ? parseNum(startDate, 13) : undefined,
449
+ type: parseChar(type, 32),
450
+ userId: sessionId
451
+ };
452
+ const aqlQry = aql`INSERT ${insert} IN posts RETURN NEW`;
453
+ try {
454
+ const savedPost = await useDb(databaseName).query(aqlQry).then((cursor)=>cursor.next()).catch((error)=>logError({
455
+ action,
456
+ category: eventCategory,
457
+ label: ErrorTypes.DATABASE_ERROR
458
+ }, error, context));
459
+ const { _id: postDocId } = savedPost;
460
+ const contentTagNames = await extractTags(insert.content || '');
461
+ if (tags.length || contentTagNames.length) {
462
+ const userTags = (await getTagsByName(context, tags.map(({ name })=>name || ''))).map((tag)=>({
463
+ ...tag,
464
+ tagBy: sessionId
465
+ }));
466
+ const contentTags = (await getTagsByName(context, contentTagNames || [])).map((tag)=>({
467
+ ...tag,
468
+ tagBy: 'extract'
469
+ }));
470
+ const updatedTags = await updateTagsInItem(context, {
471
+ itemDocId: postDocId,
472
+ tags: [
473
+ ...contentTags,
474
+ ...userTags
475
+ ]
476
+ });
477
+ return {
478
+ ...savedPost,
479
+ tags: updatedTags
480
+ };
481
+ }
482
+ return savedPost;
483
+ } catch (error) {
484
+ throw error;
485
+ }
486
+ };
487
+ export const updatePost = async (context, post)=>{
488
+ const action = 'updatePost';
489
+ const { databaseName, session: { userId: sessionId } = {} } = context;
490
+ const now = Date.now();
491
+ const parsedPost = parsePost(post);
492
+ const { postId, tags = [] } = parsedPost;
493
+ const update = {
494
+ ...parsedPost,
495
+ modified: now
496
+ };
497
+ if (!postId) {
498
+ throw logException({
499
+ action,
500
+ category: eventCategory,
501
+ value: ErrorTypes.INVALID_ID
502
+ }, context);
503
+ }
504
+ const insert = {
505
+ ...update,
506
+ _key: postId,
507
+ added: now,
508
+ userId: sessionId
509
+ };
510
+ const aqlQry = aql`UPSERT {_key: ${postId}, userId: ${sessionId}}
511
+ INSERT ${insert}
512
+ UPDATE ${update}
513
+ IN posts RETURN NEW`;
514
+ try {
515
+ const updatedPost = await useDb(databaseName).query(aqlQry).then((cursor)=>cursor.next()).catch((error)=>logError({
516
+ action,
517
+ category: eventCategory,
518
+ value: ErrorTypes.DATABASE_ERROR
519
+ }, error, {}));
520
+ const { _id: updatedPostId } = updatedPost;
521
+ const contentTagNames = await extractTags(insert.content || '');
522
+ if (tags?.length || contentTagNames?.length) {
523
+ const userTags = tags?.length ? (await getTagsByName(context, tags.map(({ name })=>name || ''))).map((tag)=>({
524
+ ...tag,
525
+ tagBy: sessionId
526
+ })) : [];
527
+ const contentTags = contentTagNames?.length ? (await getTagsByName(context, contentTagNames || [])).map((tag)=>({
528
+ ...tag,
529
+ tagBy: 'extract'
530
+ })) : [];
531
+ const updatedTags = await updateTagsInItem(context, {
532
+ itemDocId: updatedPostId,
533
+ tags: [
534
+ ...contentTags,
535
+ ...userTags
536
+ ]
537
+ });
538
+ return {
539
+ ...updatedPost,
540
+ tags: updatedTags
541
+ };
542
+ }
543
+ return updatedPost;
544
+ } catch (error) {
545
+ throw error;
546
+ }
547
+ };
548
+ export const deletePost = async (context, postDocId)=>{
549
+ const action = 'deletePost';
550
+ const { databaseName, session: { userId: sessionId } = {} } = context;
551
+ const formatPostId = parseArangoId(postDocId);
552
+ if (!formatPostId) {
553
+ throw logException({
554
+ action,
555
+ category: eventCategory,
556
+ value: ErrorTypes.INVALID_ID
557
+ }, context);
558
+ }
559
+ const edgeAqlQry = aql`FOR t IN isTagged
560
+ FILTER t._to == ${formatPostId}
561
+ REMOVE t IN isTagged`;
562
+ await useDb(databaseName).query(edgeAqlQry).catch((error)=>{
563
+ throw error;
564
+ });
565
+ const fileAqlQry = aql`FOR f IN hasFile
566
+ FILTER f._to == ${formatPostId}
567
+ REMOVE f IN hasFile`;
568
+ await useDb(databaseName).query(fileAqlQry).catch((error)=>{
569
+ throw error;
570
+ });
571
+ const aqlQry = aql`FOR p IN posts
572
+ FILTER p._id == ${formatPostId} && p.userId == ${sessionId}
140
573
  LIMIT 1
141
574
  REMOVE p IN posts
142
- RETURN OLD`;return E(o).query(c).then(s=>s.next()).catch(s=>{throw s})},Tt=(t,r,e,o="isPosted",i={})=>{const n="createPostEdge",{databaseName:p}=t,R=E(p).collection(o),c=S(r),s=S(e);if(!s||!c)throw new Error(m.INVALID_ID);const a=v(`postEdge-${c}-${s}`),u={_from:c,_key:a,_to:s,added:Date.now(),...i};return R.save(u,{returnNew:!0}).catch(d=>{throw f({action:n,category:O,value:m.DATABASE_ERROR},d,t)})};export{ct as addPost,Tt as createPostEdge,dt as deletePost,st as getPost,pt as getPostComments,C as getPostOptional,ot as getPostsByArea,rt as getPostsByLatest,nt as getPostsByReactions,at as getPostsByTags,it as getPostsByUser,$ as parsePostOptions,ut as updatePost};
143
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FjdGlvbnMvcG9zdHMudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQ29weXJpZ2h0IChjKSAyMDE5LVByZXNlbnQsIE5pdHJvZ2VuIExhYnMsIEluYy5cbiAqIENvcHlyaWdodHMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLiBTZWUgdGhlIGFjY29tcGFueWluZyBMSUNFTlNFIGZpbGUgZm9yIHRlcm1zLlxuICovXG5pbXBvcnQgeyBwYXJzZU51bSB9IGZyb20gJ0BubGFicy91dGlscy9wYXJzZXJzL251bWJlcnMnO1xuaW1wb3J0IHtcbiAgICBjcmVhdGVIYXNoLCBwYXJzZUFyYW5nb0lkLCBwYXJzZUNoYXIsIHBhcnNlSWQsIHBhcnNlU3RyaW5nLCBwYXJzZVZhckNoYXJcbn0gZnJvbSAnQG5sYWJzL3V0aWxzL3BhcnNlcnMvc3RyaW5ncyc7XG5pbXBvcnQgeyBhcWwgfSBmcm9tICdhcmFuZ29qcyc7XG5pbXBvcnQgeyBBcWxRdWVyeSB9IGZyb20gJ2FyYW5nb2pzL2FxbCc7XG5cbmltcG9ydCB7IHBhcnNlUG9zdCB9IGZyb20gJy4uL2FkYXB0ZXJzL3Bvc3RBZGFwdGVyLmpzJztcbmltcG9ydCB7IEVycm9yVHlwZXMgfSBmcm9tICcuLi90eXBlcy9lcnJvci50eXBlcy5qcyc7XG5pbXBvcnQgeyBsb2dFcnJvciwgbG9nRXhjZXB0aW9uIH0gZnJvbSAnLi4vdXRpbHMvYW5hbHl0aWNzVXRpbHMuanMnO1xuaW1wb3J0IHsgZ2V0TGltaXQsIHVzZURiIH0gZnJvbSAnLi4vdXRpbHMvYXJhbmdvZGJVdGlscy5qcyc7XG5pbXBvcnQgeyBleHRyYWN0VGFncywgZ2V0VGFnc0J5TmFtZSwgdXBkYXRlVGFnc0luSXRlbSB9IGZyb20gJy4vdGFncy5qcyc7XG5cbmltcG9ydCB0eXBlIHsgRWRnZUNvbGxlY3Rpb24gfSBmcm9tICdhcmFuZ29qcy9jb2xsZWN0aW9ucyc7XG5pbXBvcnQgdHlwZSB7IEFyYW5nb0RiTGltaXQgfSBmcm9tICcuLi90eXBlcy9hcmFuZ29kYi50eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7IEFwaUNvbnRleHQgfSBmcm9tICcuLi90eXBlcy9hdXRoLnR5cGVzLmpzJztcbmltcG9ydCB0eXBlIHsgRmlsZVR5cGUgfSBmcm9tICcuLi90eXBlcy9maWxlcy50eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7IFBvc3RJbnB1dFR5cGUsIFBvc3RPcHRpb25zLCBQb3N0VHlwZSB9IGZyb20gJy4uL3R5cGVzL3Bvc3RzLnR5cGVzLmpzJztcbmltcG9ydCB0eXBlIHsgVGFnVHlwZSB9IGZyb20gJy4uL3R5cGVzL3RhZ3MudHlwZXMuanMnO1xuXG5jb25zdCBNQVhfQ09OVEVOVF9MRU5HVEg6IG51bWJlciA9IDEwMDAwMDtcbmNvbnN0IGV2ZW50Q2F0ZWdvcnk6IHN0cmluZyA9ICdwb3N0cyc7XG5cbmV4cG9ydCBjb25zdCBwYXJzZVBvc3RPcHRpb25zID0gKG9wdGlvbnM6IFBvc3RPcHRpb25zID0ge30pID0+IHtcbiAgY29uc3Qge1xuICAgIGZyb20gPSAwLFxuICAgIGxhdGl0dWRlID0gMCxcbiAgICBsb25naXR1ZGUgPSAwLFxuICAgIHRvID0gMzAsXG4gICAgdHlwZSA9ICdwb3N0J1xuICB9ID0gb3B0aW9ucztcblxuICByZXR1cm4ge1xuICAgIGxhdGl0dWRlOiBwYXJzZU51bShsYXRpdHVkZSwgMzIpLFxuICAgIGxpbWl0OiBnZXRMaW1pdChmcm9tLCB0bykgYXMgQXJhbmdvRGJMaW1pdCxcbiAgICBsb25naXR1ZGU6IHBhcnNlTnVtKGxvbmdpdHVkZSwgMzIpLFxuICAgIHR5cGU6IHBhcnNlQ2hhcih0eXBlLCAzMilcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRQb3N0T3B0aW9uYWwgPSAoZmllbGRzOiBzdHJpbmdbXSA9IFtdLCBzZXNzaW9uSWQ6IHN0cmluZyA9ICcnKSA9PlxuICAoZmllbGRzIHx8IFtdKS5yZWR1Y2UoKHNlbGVjdHM6IHtvYmplY3RzOiBzdHJpbmdbXSwgcXVlcmllczogc3RyaW5nW119LCBmaWVsZDogc3RyaW5nKSA9PiB7XG4gICAgc3dpdGNoKGZpZWxkKSB7XG4gICAgICBjYXNlICdoYXNSc3ZwJzoge1xuICAgICAgICBzZWxlY3RzLnF1ZXJpZXMucHVzaChgTEVUIGhhc1JzdnAgPSBUT19CT09MKEZJUlNUKFxuICAgICAgICAgIEZPUiBwb3N0LCByIElOIElOQk9VTkQgcC5faWQgaGFzUmVhY3Rpb25cbiAgICAgICAgICBGSUxURVIgci5uYW1lID09IFwicnN2cFwiICYmIHIudHlwZSA9PSBcInBvc3RzXCIgJiYgci5fZnJvbSA9PSBcInVzZXJzLyR7c2Vzc2lvbklkfVwiXG4gICAgICAgICAgQ09MTEVDVCBXSVRIIENPVU5UIElOVE8gY291bnRcbiAgICAgICAgICBSRVRVUk4gY291bnRcbiAgICAgICAgKSlgKTtcbiAgICAgICAgc2VsZWN0cy5vYmplY3RzLnB1c2goJ2hhc1JzdnA6aGFzUnN2cCcpO1xuICAgICAgICByZXR1cm4gc2VsZWN0cztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2lzU2F2ZWQnOiB7XG4gICAgICAgIHNlbGVjdHMucXVlcmllcy5wdXNoKGBMRVQgaXNTYXZlZCA9IFRPX0JPT0woRklSU1QoXG4gICAgICAgICAgRk9SIHBvc3QsIHIgSU4gSU5CT1VORCBwLl9pZCBoYXNSZWFjdGlvblxuICAgICAgICAgIEZJTFRFUiByLm5hbWUgPT0gXCJwaW5cIiAmJiByLnR5cGUgPT0gXCJwb3N0c1wiICYmIHIuX2Zyb20gPT0gXCJ1c2Vycy8ke3Nlc3Npb25JZH1cIlxuICAgICAgICAgIENPTExFQ1QgV0lUSCBDT1VOVCBJTlRPIGNvdW50XG4gICAgICAgICAgUkVUVVJOIGNvdW50XG4gICAgICAgICkpYCk7XG4gICAgICAgIHNlbGVjdHMub2JqZWN0cy5wdXNoKCdpc1NhdmVkOmlzU2F2ZWQnKTtcbiAgICAgICAgcmV0dXJuIHNlbGVjdHM7XG4gICAgICB9XG4gICAgICBjYXNlICdyZWFjdGlvbnMnOiB7XG4gICAgICAgIHNlbGVjdHMucXVlcmllcy5wdXNoKGBMRVQgcmVhY3Rpb25zID0gKFxuICAgICAgICAgIEZPUiBwb3N0LCByIElOIElOQk9VTkQgcC5faWQgaGFzUmVhY3Rpb25cbiAgICAgICAgICBDT0xMRUNUIHJlYWN0aW9uTmFtZSA9IHIudmFsdWUgSU5UTyByZWFjdGlvbkl0ZW1zXG4gICAgICAgICAgUkVUVVJOIHtuYW1lOiByZWFjdGlvbk5hbWUsIGNvdW50OiBMRU5HVEgocmVhY3Rpb25JdGVtc1sqXS5yLnZhbHVlKX1cbiAgICAgICAgKWApO1xuICAgICAgICBzZWxlY3RzLm9iamVjdHMucHVzaCgncmVhY3Rpb25zOnJlYWN0aW9ucycpO1xuICAgICAgICByZXR1cm4gc2VsZWN0cztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ3JzdnBDb3VudCc6IHtcbiAgICAgICAgc2VsZWN0cy5xdWVyaWVzLnB1c2goYExFVCByc3ZwQ291bnQgPSBGSVJTVChcbiAgICAgICAgICBGT1IgcG9zdCwgciBJTiBJTkJPVU5EIHAuX2lkIGhhc1JlYWN0aW9uXG4gICAgICAgICAgRklMVEVSIHIubmFtZSA9PSBcInJzdnBcIiAmJiByLnR5cGUgPT0gXCJwb3N0c1wiXG4gICAgICAgICAgQ09MTEVDVCBXSVRIIENPVU5UIElOVE8gY291bnRcbiAgICAgICAgICBSRVRVUk4gY291bnRcbiAgICAgICAgKWApO1xuICAgICAgICBzZWxlY3RzLm9iamVjdHMucHVzaCgncnN2cENvdW50OnJzdnBDb3VudCcpO1xuICAgICAgICByZXR1cm4gc2VsZWN0cztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ3ZpZXdDb3VudCc6IHtcbiAgICAgICAgc2VsZWN0cy5xdWVyaWVzLnB1c2goYExFVCB2aWV3Q291bnQgPSBGSVJTVChcbiAgICAgICAgICBGT1IgcG9zdCwgciBJTiBJTkJPVU5EIHAuX2lkIGhhc1JlYWN0aW9uXG4gICAgICAgICAgRklMVEVSIHIubmFtZSA9PSBcInZpZXdcIiAmJiByLnR5cGUgPT0gXCJwb3N0c1wiXG4gICAgICAgICAgQ09MTEVDVCBXSVRIIENPVU5UIElOVE8gY291bnRcbiAgICAgICAgICBSRVRVUk4gY291bnRcbiAgICAgICAgKWApO1xuICAgICAgICBzZWxlY3RzLm9iamVjdHMucHVzaCgndmlld0NvdW50OnZpZXdDb3VudCcpO1xuICAgICAgICByZXR1cm4gc2VsZWN0cztcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgcmV0dXJuIHNlbGVjdHM7XG4gICAgICB9XG4gICAgfVxuICB9LCB7b2JqZWN0czogW10sIHF1ZXJpZXM6IFtdfSk7XG5cbmV4cG9ydCBjb25zdCBnZXRQb3N0ID0gYXN5bmMgKFxuICBjb250ZXh0OiBBcGlDb250ZXh0LFxuICBwb3N0SWQ6IHN0cmluZyxcbiAgb3B0aW9ucz86IFBvc3RPcHRpb25zXG4pOiBQcm9taXNlPFBvc3RUeXBlPiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2dldFBvc3QnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHMsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZH0gPSB7fX0gPSBjb250ZXh0O1xuICBjb25zdCBmb3JtYXRJdGVtSWQ6IHN0cmluZyA9IHBhcnNlSWQocG9zdElkKTtcbiAgY29uc3Qge3R5cGV9ID0gcGFyc2VQb3N0T3B0aW9ucyhvcHRpb25zKTtcbiAgY29uc3QgZGF0YWJhc2UgPSB1c2VEYihkYXRhYmFzZU5hbWUpO1xuICBjb25zdCB7b2JqZWN0czogc2VsZWN0T2JqZWN0cywgcXVlcmllczogc2VsZWN0UXVlcmllc30gPSBnZXRQb3N0T3B0aW9uYWwoZmllbGRzLCBzZXNzaW9uSWQpO1xuICBjb25zdCBhcWxRcnk6IEFxbFF1ZXJ5ID0gYXFsYEZPUiBwIElOIHBvc3RzXG4gICAgRklMVEVSIHAuX2tleSA9PSAke2Zvcm1hdEl0ZW1JZH0gJiYgcC50eXBlID09ICR7dHlwZX1cbiAgICBMSU1JVCAxXG4gICAgUkVUVVJOIHBgO1xuXG4gIHJldHVybiBkYXRhYmFzZS5xdWVyeShhcWxRcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAudGhlbigocG9zdDogUG9zdFR5cGUpID0+IHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgX2lkOiBwb3N0RG9jSWQsXG4gICAgICAgIHVzZXJJZCxcbiAgICAgICAgZ3JvdXBJZCxcbiAgICAgICAgcHJpdmFjeSA9ICdkZWZhdWx0J1xuICAgICAgfTogUG9zdFR5cGUgPSBwb3N0O1xuXG4gICAgICBsZXQgcHJpdmFjeUFxbFFyeTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgICBpZih1c2VySWQgPT09IHNlc3Npb25JZCkge1xuICAgICAgICByZXR1cm4gcG9zdDtcbiAgICAgIH1cblxuICAgICAgaWYoZ3JvdXBJZCAmJiBwcml2YWN5ID09PSAnZ3JvdXAnKSB7XG4gICAgICAgIHByaXZhY3lBcWxRcnkgPSBgTEVUIHAgPSBET0NVTUVOVChcIiR7cG9zdERvY0lkfVwiKVxuICAgICAgICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICAgICAgICBGT1IgZ3JvdXAgSU4gZ3JvdXBzXG4gICAgICAgICAgRklMVEVSIGdyb3VwLl9rZXkgPT0gcC5ncm91cElkXG4gICAgICAgICAgRk9SIHUsIGUgSU4gT1VUQk9VTkQgZ3JvdXAuX2lkIGhhc0Nvbm5lY3Rpb25cbiAgICAgICAgICBGSUxURVIgdS5fa2V5ID09IFwiJHtzZXNzaW9uSWR9XCJcbiAgICAgICAgICBMSU1JVCAxXG4gICAgICAgICAgUkVUVVJOIE1FUkdFKHAsIHske3NlbGVjdE9iamVjdHMuam9pbignLCAnKX19KWA7XG4gICAgICB9IGVsc2UgaWYocHJpdmFjeSA9PT0gJ3B1YmxpYycpIHtcbiAgICAgICAgcHJpdmFjeUFxbFFyeSA9IGBMRVQgcCA9IERPQ1VNRU5UKFwiJHtwb3N0RG9jSWR9XCIpXG4gICAgICAgICAgJHtzZWxlY3RRdWVyaWVzLmpvaW4oJ1xcbicpfVxuICAgICAgICAgIExJTUlUIDFcbiAgICAgICAgICBSRVRVUk4gTUVSR0UocCwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcbiAgICAgIH1cblxuICAgICAgaWYocHJpdmFjeUFxbFFyeSkge1xuICAgICAgICByZXR1cm4gZGF0YWJhc2UucXVlcnkocHJpdmFjeUFxbFFyeSlcbiAgICAgICAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKVxuICAgICAgICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiBsb2dFcnJvcih7XG4gICAgICAgICAgICBhY3Rpb24sXG4gICAgICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgICAgIGxhYmVsOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgICAgICAgfSwgZXJyb3IsIGNvbnRleHQpKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHt9O1xuICAgIH0pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgbGFiZWw6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICB9LCBlcnJvciwgY29udGV4dCkpO1xufTtcblxuXG4vLyBleHBvcnQgY29uc3QgZ2V0UG9zdExpc3QgPSAoY29udGV4dDogQXBpQ29udGV4dCwgb3B0aW9ucz86IFBvc3RPcHRpb25zKTogUHJvbWlzZTxQb3N0VHlwZVtdPiA9PiB7XG4vLyAgIC8vIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2dldExpc3RCeUFwcCc7XG4vLyAgIGNvbnN0IHtkYXRhYmFzZSwgZmllbGRzLCBzZXNzaW9uOiB7dXNlcklkOiBzZXNzaW9uSWR9fSA9IGNvbnRleHQ7XG4vLyAgIGNvbnN0IHtsaW1pdCwgdHlwZX0gPSBwYXJzZVBvc3RPcHRpb25zKG9wdGlvbnMpO1xuLy8gICBjb25zdCB7b2JqZWN0czogc2VsZWN0T2JqZWN0cywgcXVlcmllczogc2VsZWN0UXVlcmllc30gPSBnZXRQb3N0T3B0aW9uYWwoZmllbGRzLCBzZXNzaW9uSWQpO1xuLy8gICBjb25zdCBhcWxRcnk6IHN0cmluZyA9IGBGT1IgcCBJTiBwb3N0c1xuLy8gICAgIEZJTFRFUiBwLnR5cGUgPT0gXCIke3R5cGV9XCIgJiYgcC5wcml2YWN5ID09IFwicHVibGljXCIgJiYgcC5wYXJlbnQgPT0gbnVsbFxuLy8gICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbi8vICAgICAke2xpbWl0LmFxbH1cbi8vICAgICBTT1JUIHAuYWRkZWRcbi8vICAgICBSRVRVUk4gRElTVElOQ1QgTUVSR0UocCwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcblxuLy8gICByZXR1cm4gZGF0YWJhc2UucXVlcnkoYXFsUXJ5KVxuLy8gICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSlcbi8vICAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuLy8gICAgICAgdGhyb3cgZXJyb3I7XG4vLyAgICAgfSk7XG4vLyB9O1xuXG5leHBvcnQgY29uc3QgZ2V0UG9zdHNCeUFyZWEgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIGxhdGl0dWRlOiBudW1iZXIsXG4gIGxvbmdpdHVkZTogbnVtYmVyLFxuICBvcHRpb25zPzogUG9zdE9wdGlvbnNcbik6IFByb21pc2U8UG9zdFR5cGVbXT4gPT4ge1xuICBjb25zdCBhY3Rpb246IHN0cmluZyA9ICdnZXRQb3N0c0J5QXJlYSc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWUsIGZpZWxkcywgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkfSA9IHt9fSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtsaW1pdCwgdHlwZX0gPSBwYXJzZVBvc3RPcHRpb25zKG9wdGlvbnMpO1xuICBjb25zdCBmb3JtYXRMYXRpdHVkZTogbnVtYmVyID0gcGFyc2VOdW0obGF0aXR1ZGUpO1xuICBjb25zdCBmb3JtYXRMb25naXR1ZGU6IG51bWJlciA9IHBhcnNlTnVtKGxvbmdpdHVkZSk7XG4gIGNvbnN0IHtvYmplY3RzOiBzZWxlY3RPYmplY3RzLCBxdWVyaWVzOiBzZWxlY3RRdWVyaWVzfSA9IGdldFBvc3RPcHRpb25hbChmaWVsZHMsIHNlc3Npb25JZCk7XG4gIHNlbGVjdFF1ZXJpZXMucHVzaChgTEVUIGRpc3RhbmNlID0gRElTVEFOQ0UoXG4gICAgJHtmb3JtYXRMYXRpdHVkZX0sXG4gICAgJHtmb3JtYXRMb25naXR1ZGV9LFxuICAgIE5PVF9OVUxMKHAubGF0aXR1ZGUsIDApLFxuICAgIE5PVF9OVUxMKHAubG9uZ2l0dWRlLCAwKSlcbiAgYCk7XG4gIHNlbGVjdE9iamVjdHMucHVzaCgnZGlzdGFuY2U6ZGlzdGFuY2UnKTtcblxuICBjb25zdCBhcWxRcnk6IHN0cmluZyA9IGBGT1IgcCBJTiBwb3N0c1xuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICBGSUxURVIgcC50eXBlID09IFwiJHt0eXBlfVwiICYmIHAucHJpdmFjeSA9PSBcInB1YmxpY1wiICYmIHAucGFyZW50SWQgPT0gbnVsbFxuICAgICR7bGltaXQuYXFsfVxuICAgIFNPUlQgZGlzdGFuY2UsIHAuYWRkZWRcbiAgICBSRVRVUk4gRElTVElOQ1QgTUVSR0UocCwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcblxuICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpIGFzIHVua25vd24gYXMgUG9zdFR5cGVbXSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICBsYWJlbDogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuXG4gICAgICByZXR1cm4gW10gYXMgUG9zdFR5cGVbXTtcbiAgICB9KTtcbn07XG5cbi8vIGV4cG9ydCBjb25zdCBnZXRQb3N0c0J5R3JvdXAgPSAoXG4vLyAgIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4vLyAgIGdyb3VwSWQ6IHN0cmluZyxcbi8vICAgb3B0aW9ucz86IFBvc3RPcHRpb25zXG4vLyApOiBQcm9taXNlPFBvc3RUeXBlW10+ID0+IHtcbi8vICAgLy8gY29uc3QgYWN0aW9uOiBzdHJpbmcgPSAnZ2V0TGlzdEJ5R3JvdXAnO1xuLy8gICBjb25zdCB7ZGF0YWJhc2UsIGZpZWxkcywgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkfX0gPSBjb250ZXh0O1xuLy8gICBjb25zdCB7b2JqZWN0czogc2VsZWN0T2JqZWN0cywgcXVlcmllczogc2VsZWN0UXVlcmllc30gPSBnZXRQb3N0T3B0aW9uYWwoZmllbGRzLCBzZXNzaW9uSWQpO1xuXG4vLyAgIC8vIEdyb3VwIGlkXG4vLyAgIGNvbnN0IGZvcm1hdEdyb3VwSWQ6IHN0cmluZyA9IHBhcnNlSWQoZ3JvdXBJZCk7XG4vLyAgIGNvbnN0IGRiID0gZGF0YWJhc2U7XG4vLyAgIGNvbnN0IGFxbFFyeTogc3RyaW5nID0gYEZPUiB1LCBnIElOIElOQk9VTkQgJHtmb3JtYXRHcm91cElkfSBoYXNHcm91cFxuLy8gICAgICAgRklMVEVSIHUuX2tleSA9PSAke3Nlc3Npb25JZH1cbi8vICAgICAgIFJFVFVSTiBnYDtcblxuLy8gICByZXR1cm4gZGIucXVlcnkoYXFsUXJ5KVxuLy8gICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSlcbi8vICAgICAudGhlbigoZ3JvdXBzOiBHcm91cFR5cGVbXSA9IFtdKSA9PiB7XG4vLyAgICAgICBpZihncm91cHMubGVuZ3RoKSB7XG4vLyAgICAgICAgIGNvbnN0IHtsaW1pdCwgdHlwZX0gPSBwYXJzZVBvc3RPcHRpb25zKG9wdGlvbnMpO1xuLy8gICAgICAgICBjb25zdCBwb3N0QXFsUXJ5OiBzdHJpbmcgPSBgRk9SIHAgSU4gcG9zdHNcbi8vICAgICAgICAgICBGSUxURVIgcC50eXBlID09IFwiJHt0eXBlfVwiICYmIHAuZ3JvdXBJZCA9PSBcIiR7Zm9ybWF0R3JvdXBJZH1cIiAmJiBwLnBhcmVudCA9PSBudWxsXG4vLyAgICAgICAgICAgJHtzZWxlY3RRdWVyaWVzLmpvaW4oJ1xcbicpfVxuLy8gICAgICAgICAgICR7bGltaXQuYXFsfVxuLy8gICAgICAgICAgIFNPUlQgcC5hZGRlZFxuLy8gICAgICAgICAgIFJFVFVSTiBESVNUSU5DVCBNRVJHRShwLCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4vLyAgICAgICAgIHJldHVybiBkYi5xdWVyeShwb3N0QXFsUXJ5KVxuLy8gICAgICAgICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSlcbi8vICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuLy8gICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4vLyAgICAgICAgICAgfSk7XG4vLyAgICAgICB9XG5cbi8vICAgICAgIHJldHVybiBbXTtcbi8vICAgICB9KVxuLy8gICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiB7XG4vLyAgICAgICB0aHJvdyBlcnJvcjtcbi8vICAgICB9KTtcbi8vIH07XG5cbmV4cG9ydCBjb25zdCBnZXRQb3N0c0J5TGF0ZXN0ID0gKGNvbnRleHQ6IEFwaUNvbnRleHQsIG9wdGlvbnM/OiBQb3N0T3B0aW9ucyk6IFByb21pc2U8UG9zdFR5cGVbXT4gPT4ge1xuICAvLyBjb25zdCBhY3Rpb246IHN0cmluZyA9ICdnZXRMaXN0QnlMYXRlc3QnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHMsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZH0gPSB7fX0gPSBjb250ZXh0O1xuICBjb25zdCB7bGltaXQsIHR5cGV9ID0gcGFyc2VQb3N0T3B0aW9ucyhvcHRpb25zKTtcbiAgY29uc3Qge29iamVjdHM6IHNlbGVjdE9iamVjdHMsIHF1ZXJpZXM6IHNlbGVjdFF1ZXJpZXN9ID0gZ2V0UG9zdE9wdGlvbmFsKGZpZWxkcywgc2Vzc2lvbklkKTtcbiAgY29uc3QgYXFsUXJ5OiBzdHJpbmcgPSBgRk9SIHAgSU4gcG9zdHNcbiAgICBGSUxURVIgcC50eXBlID09IFwiJHt0eXBlfVwiICYmIHAucHJpdmFjeSA9PSBcInB1YmxpY1wiICYmIHAucGFyZW50ID09IG51bGxcbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgJHtsaW1pdC5hcWx9XG4gICAgU09SVCBwLmFkZGVkIERFU0NcbiAgICBSRVRVUk4gRElTVElOQ1QgTUVSR0UocCwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcblxuICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpKVxuICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRQb3N0c0J5UmVhY3Rpb25zID0gKFxuICBjb250ZXh0OiBBcGlDb250ZXh0LFxuICByZWFjdGlvbnM6IHN0cmluZ1tdID0gW10sXG4gIG9wdGlvbnM/OiBQb3N0T3B0aW9uc1xuKTogUHJvbWlzZTxQb3N0VHlwZVtdPiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2dldFBvc3RzQnlSZWFjdGlvbnMnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHMsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZH0gPSB7fX0gPSBjb250ZXh0O1xuICBjb25zdCB7bGF0aXR1ZGUsIGxpbWl0LCBsb25naXR1ZGUsIHR5cGV9ID0gcGFyc2VQb3N0T3B0aW9ucyhvcHRpb25zKTtcbiAgY29uc3Qge29iamVjdHM6IHNlbGVjdE9iamVjdHMsIHF1ZXJpZXM6IHNlbGVjdFF1ZXJpZXN9ID0gZ2V0UG9zdE9wdGlvbmFsKGZpZWxkcywgc2Vzc2lvbklkKTtcbiAgY29uc3QgZm9ybWF0U2Vzc2lvbklkOiBzdHJpbmcgPSBgdXNlcnMvJHtzZXNzaW9uSWR9YDtcbiAgY29uc3QgZm9ybWF0UmVhY3Rpb25zOiBzdHJpbmcgPSBKU09OLnN0cmluZ2lmeShyZWFjdGlvbnMubWFwKChyZWFjdGlvbikgPT4gcGFyc2VDaGFyKHJlYWN0aW9uLCAzMikudG9Mb3dlckNhc2UoKSkpO1xuICBjb25zdCBzb3J0Qnk6IHN0cmluZ1tdID0gW107XG4gIGNvbnN0IGZpbHRlcnM6IHN0cmluZ1tdID0gW2BwLnR5cGUgPT0gXCIke3R5cGV9XCJgLCAncC5wcml2YWN5ID09IFwicHVibGljXCInXTtcbiAgY29uc3QgZm9ybWF0TGF0aXR1ZGU6IG51bWJlciA9IHBhcnNlTnVtKGxhdGl0dWRlKTtcbiAgY29uc3QgZm9ybWF0TG9uZ2l0dWRlOiBudW1iZXIgPSBwYXJzZU51bShsb25naXR1ZGUpO1xuXG4gIGlmKGZvcm1hdExhdGl0dWRlICYmIGZvcm1hdExvbmdpdHVkZSkge1xuICAgIHNlbGVjdFF1ZXJpZXMucHVzaChgTEVUIGRpc3RhbmNlID0gRElTVEFOQ0UoXG4gICAgICAke2Zvcm1hdExhdGl0dWRlfSxcbiAgICAgICR7Zm9ybWF0TG9uZ2l0dWRlfSxcbiAgICAgIE5PVF9OVUxMKHAubGF0aXR1ZGUsIDApLFxuICAgICAgTk9UX05VTEwocC5sb25naXR1ZGUsIDApKVxuICAgIGApO1xuICAgIHNlbGVjdE9iamVjdHMucHVzaCgnZGlzdGFuY2U6ZGlzdGFuY2UnKTtcbiAgICBzb3J0QnkucHVzaCgnZGlzdGFuY2UnKTtcbiAgfVxuXG4gIGlmKHJlYWN0aW9ucy5sZW5ndGgpIHtcbiAgICBzb3J0QnkucHVzaCgnbWF0Y2hlZFRhZ3MgREVTQycpO1xuICAgIHNlbGVjdFF1ZXJpZXMucHVzaChgTEVUIG1hdGNoZWRSZWFjdGlvbnMgPSBMRU5HVEgoXG4gICAgICBGT1IgbXIgSU4gcmVhY3Rpb25zXG4gICAgICBGSUxURVIgbXIubWF0Y2hlZCA9PSB0cnVlXG4gICAgICBSRVRVUk4gbXJcbiAgICApYCk7XG4gICAgc2VsZWN0T2JqZWN0cy5wdXNoKCdtYXRjaGVkUmVhY3Rpb25zOm1hdGNoZWRSZWFjdGlvbnMnKTtcbiAgICBmaWx0ZXJzLnB1c2goJ21hdGNoZWRSZWFjdGlvbnMgPiAwJyk7XG4gIH1cblxuICBzb3J0QnkucHVzaCgncC5hZGRlZCBERVNDJyk7XG4gIHNlbGVjdE9iamVjdHMucHVzaCgncmVhY3Rpb25zOnJlYWN0aW9ucycpO1xuXG4gIC8vIEdldCBkYXRhIGZyb20gZGF0YWJhc2VcbiAgY29uc3QgYXFsUXJ5OiBzdHJpbmcgPSBgRk9SIHAsIHIgSU4gT1VUQk9VTkQgXCIke2Zvcm1hdFNlc3Npb25JZH1cIiBoYXNSZWFjdGlvblxuICAgIExFVCByZWFjdGlvbnMgPSAoXG4gICAgICBGT1IgcmVhY3Rpb24sIGhyIElOIDEuLjEgSU5CT1VORCBwIGlzVGFnZ2VkXG4gICAgICBMRVQgbWF0Y2hlZCA9IExFTkdUSCgke2Zvcm1hdFJlYWN0aW9uc30pID4gMCAmJiBQT1NJVElPTigke2Zvcm1hdFJlYWN0aW9uc30sIHJlYWN0aW9uLm5hbWUpXG4gICAgICBTT1JUIHJlYWN0aW9uLm5hbWVcbiAgICAgIFJFVFVSTiBNRVJHRShyZWFjdGlvbiwge21hdGNoZWQ6bWF0Y2hlZH0pXG4gICAgKVxuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICBGSUxURVIgJHtmaWx0ZXJzLmpvaW4oJyAmJiAnKX1cbiAgICAke2xpbWl0LmFxbH1cbiAgICBSRVRVUk4gRElTVElOQ1QgTUVSR0UocCwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcblxuICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpIGFzIHVua25vd24gYXMgUG9zdFR5cGVbXSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICBsYWJlbDogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuXG4gICAgICByZXR1cm4gW10gYXMgUG9zdFR5cGVbXTtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRQb3N0c0J5VGFncyA9IChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgdGFnczogc3RyaW5nW10gPSBbXSxcbiAgb3B0aW9ucz86IFBvc3RPcHRpb25zXG4pOiBQcm9taXNlPFBvc3RUeXBlW10+ID0+IHtcbiAgY29uc3QgYWN0aW9uOiBzdHJpbmcgPSAnZ2V0UG9zdHNCeVRhZ3MnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHMsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZH0gPSB7fX0gPSBjb250ZXh0O1xuICBjb25zdCB7bGF0aXR1ZGUsIGxpbWl0LCBsb25naXR1ZGUsIHR5cGV9ID0gcGFyc2VQb3N0T3B0aW9ucyhvcHRpb25zKTtcbiAgY29uc3Qge29iamVjdHM6IHNlbGVjdE9iamVjdHMsIHF1ZXJpZXM6IHNlbGVjdFF1ZXJpZXN9ID0gZ2V0UG9zdE9wdGlvbmFsKGZpZWxkcywgc2Vzc2lvbklkKTtcbiAgY29uc3QgZm9ybWF0VGFnTmFtZXM6IHN0cmluZyA9IEpTT04uc3RyaW5naWZ5KHRhZ3MubWFwKCh0YWcpID0+IHBhcnNlQ2hhcih0YWcsIDMyKS50b0xvd2VyQ2FzZSgpKSk7XG4gIGNvbnN0IHNvcnRCeTogc3RyaW5nW10gPSBbXTtcbiAgY29uc3QgZmlsdGVyczogc3RyaW5nW10gPSBbYHAudHlwZSA9PSBcIiR7dHlwZX1cImAsICdwLnByaXZhY3kgPT0gXCJwdWJsaWNcIiddO1xuICBjb25zdCBmb3JtYXRMYXRpdHVkZTogbnVtYmVyID0gcGFyc2VOdW0obGF0aXR1ZGUpO1xuICBjb25zdCBmb3JtYXRMb25naXR1ZGU6IG51bWJlciA9IHBhcnNlTnVtKGxvbmdpdHVkZSk7XG5cbiAgaWYoZm9ybWF0TGF0aXR1ZGUgJiYgZm9ybWF0TG9uZ2l0dWRlKSB7XG4gICAgc2VsZWN0UXVlcmllcy5wdXNoKGBMRVQgZGlzdGFuY2UgPSBESVNUQU5DRShcbiAgICAgICR7Zm9ybWF0TGF0aXR1ZGV9LFxuICAgICAgJHtmb3JtYXRMb25naXR1ZGV9LFxuICAgICAgTk9UX05VTEwocC5sYXRpdHVkZSwgMCksXG4gICAgICBOT1RfTlVMTChwLmxvbmdpdHVkZSwgMCkpXG4gICAgYCk7XG4gICAgc2VsZWN0T2JqZWN0cy5wdXNoKCdkaXN0YW5jZTpkaXN0YW5jZScpO1xuICAgIHNvcnRCeS5wdXNoKCdkaXN0YW5jZScpO1xuICB9XG5cbiAgaWYodGFncy5sZW5ndGgpIHtcbiAgICBzb3J0QnkucHVzaCgnbWF0Y2hlZFRhZ3MgREVTQycpO1xuICAgIHNlbGVjdFF1ZXJpZXMucHVzaChgTEVUIG1hdGNoZWRUYWdzID0gTEVOR1RIKFxuICAgICAgRk9SIHQgSU4gdGFnc1xuICAgICAgRklMVEVSIHQubWF0Y2hlZCA9PSB0cnVlXG4gICAgICBSRVRVUk4gdFxuICAgIClgKTtcbiAgICBzZWxlY3RPYmplY3RzLnB1c2goJ21hdGNoZWRUYWdzOm1hdGNoZWRUYWdzJyk7XG4gICAgZmlsdGVycy5wdXNoKCdtYXRjaGVkVGFncyA+IDAnKTtcbiAgfVxuXG4gIHNvcnRCeS5wdXNoKCdwLmFkZGVkIERFU0MnKTtcbiAgc2VsZWN0T2JqZWN0cy5wdXNoKCd0YWdzOnRhZ3MnKTtcblxuICBjb25zdCBhcWxRcnk6IHN0cmluZyA9IGBGT1IgcCBJTiBwb3N0c1xuICAgIExFVCB0YWdzID0gKFxuICAgICAgRk9SIHRhZywgaXQgSU4gMS4uMSBJTkJPVU5EIHAgaXNUYWdnZWRcbiAgICAgIExFVCBtYXRjaGVkID0gTEVOR1RIKCR7Zm9ybWF0VGFnTmFtZXN9KSA+IDAgJiYgUE9TSVRJT04oJHtmb3JtYXRUYWdOYW1lc30sIHRhZy5uYW1lKVxuICAgICAgU09SVCB0YWcubmFtZVxuICAgICAgUkVUVVJOIE1FUkdFKHRhZywge21hdGNoZWQ6bWF0Y2hlZH0pXG4gICAgKVxuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICBGSUxURVIgJHtmaWx0ZXJzLmpvaW4oJyAmJiAnKX1cbiAgICAke2xpbWl0LmFxbH1cbiAgICBTT1JUICR7c29ydEJ5LmpvaW4oJywgJyl9XG4gICAgUkVUVVJOIERJU1RJTkNUIE1FUkdFKHAsIHske3NlbGVjdE9iamVjdHMuam9pbignLCAnKX19KWA7XG5cbiAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoYXFsUXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSBhcyB1bmtub3duIGFzIFBvc3RUeXBlW10pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgbGFiZWw6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgICAgcmV0dXJuIFtdIGFzIFBvc3RUeXBlW107XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0UG9zdHNCeVVzZXIgPSAoY29udGV4dDogQXBpQ29udGV4dCwgdXNlcklkOiBzdHJpbmcsIG9wdGlvbnM/OiBQb3N0T3B0aW9ucyk6IFByb21pc2U8UG9zdFR5cGVbXT4gPT4ge1xuICBjb25zdCBhY3Rpb246IHN0cmluZyA9ICdnZXRQb3N0c0J5VXNlcic7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWUsIGZpZWxkcywgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkfSA9IHt9fSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtsaW1pdCwgdHlwZX0gPSBwYXJzZVBvc3RPcHRpb25zKG9wdGlvbnMpO1xuICBjb25zdCBmb3JtYXRVc2VySWQ6IHN0cmluZyA9IHBhcnNlSWQodXNlcklkKTtcbiAgY29uc3Qge29iamVjdHM6IHNlbGVjdE9iamVjdHMsIHF1ZXJpZXM6IHNlbGVjdFF1ZXJpZXN9ID0gZ2V0UG9zdE9wdGlvbmFsKGZpZWxkcywgc2Vzc2lvbklkKTtcbiAgY29uc3QgYXFsUXJ5OiBzdHJpbmcgPSBgRk9SIHAgSU4gcG9zdHNcbiAgICBGSUxURVIgcC51c2VySWQgPT0gXCIke2Zvcm1hdFVzZXJJZH1cIiAmJiBwLnR5cGUgPT0gXCIke3R5cGV9XCIgJiYgcC5wcml2YWN5ID09IFwicHVibGljXCIgJiYgcC5wYXJlbnQgPT0gbnVsbFxuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICAke2xpbWl0LmFxbH1cbiAgICBTT1JUIHAuYWRkZWRcbiAgICBSRVRVUk4gRElTVElOQ1QgTUVSR0UocCwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcblxuICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpIGFzIHVua25vd24gYXMgUG9zdFR5cGVbXSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICBsYWJlbDogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuXG4gICAgICByZXR1cm4gW10gYXMgUG9zdFR5cGVbXTtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRQb3N0Q29tbWVudHMgPSAoY29udGV4dDogQXBpQ29udGV4dCwgcG9zdElkOiBzdHJpbmcsIG9wdGlvbnM/OiBQb3N0T3B0aW9ucyk6IFByb21pc2U8UG9zdFR5cGVbXT4gPT4ge1xuICBjb25zdCBhY3Rpb246IHN0cmluZyA9ICdnZXRQb3N0Q29tbWVudHMnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBzZXNzaW9uOiB7dXNlcklkOiBzZXNzaW9uSWR9ID0ge319ID0gY29udGV4dDtcbiAgY29uc3Qge2xpbWl0LCB0eXBlfSA9IHBhcnNlUG9zdE9wdGlvbnMob3B0aW9ucyk7XG4gIGNvbnN0IGZvcm1hdEl0ZW1JZDogc3RyaW5nID0gcGFyc2VJZChwb3N0SWQpO1xuXG4gIC8vIEdldCB0aGUgcGFyZW50IHBvc3QgdG8gZ2V0IHJlc3RyaWN0aW9uc1xuICBjb25zdCBhcWxRcnk6IEFxbFF1ZXJ5ID0gYXFsYEZPUiBwIElOIHBvc3RzXG4gICAgRklMVEVSIHAudHlwZSA9PSAke3R5cGV9ICYmIHAuX2tleSA9PSAke2Zvcm1hdEl0ZW1JZH1cbiAgICBMSU1JVCAxXG4gICAgUkVUVVJOIHBgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFFyeSlcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKVxuICAgIC50aGVuKChwb3N0OiBQb3N0VHlwZSkgPT4ge1xuICAgICAgY29uc3Qge1xuICAgICAgICBfa2V5LFxuICAgICAgICBncm91cElkLFxuICAgICAgICBwcml2YWN5ID0gJ2RlZmF1bHQnXG4gICAgICB9OiBQb3N0VHlwZSA9IHBvc3Q7XG5cbiAgICAgIC8vIFF1ZXJ5IGJhc2VkIG9uIHByaXZhY3kgbGV2ZWxcbiAgICAgIGxldCBwcml2YWN5QXFsUXJ5OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAgIGlmKGdyb3VwSWQgJiYgcHJpdmFjeSA9PT0gJ2dyb3VwJykge1xuICAgICAgICBwcml2YWN5QXFsUXJ5ID0gYEZPUiBwIElOIHBvc3RzXG4gICAgICAgICAgRk9SIHVzZXIgSU4gdXNlcnNcbiAgICAgICAgICBGSUxURVIgcC5wYXJlbnQgPT0gXCIke19rZXl9XCIgJiYgdXNlci5fa2V5ID09IHAudXNlcklkXG4gICAgICAgICAgTEVUIHJlYWN0aW9ucyA9IChcbiAgICAgICAgICAgIEZPUiBwb3N0LCByIElOIElOQk9VTkQgcC5faWQgcmVhY3Rpb25zXG4gICAgICAgICAgICBDT0xMRUNUIHJlYWN0aW9uTmFtZSA9IHIudmFsdWUgSU5UTyByZWFjdGlvbkl0ZW1zXG4gICAgICAgICAgICBSRVRVUk4ge25hbWU6IHJlYWN0aW9uTmFtZSwgY291bnQ6IExFTkdUSChyZWFjdGlvbkl0ZW1zWypdLnIudmFsdWUpfVxuICAgICAgICAgIClcbiAgICAgICAgICBGT1IgZ3JvdXAgSU4gZ3JvdXBzXG4gICAgICAgICAgRklMVEVSIGdyb3VwLl9rZXkgPT0gcC5ncm91cElkXG4gICAgICAgICAgRk9SIHUsIGUgSU4gT1VUQk9VTkQgZ3JvdXAuX2lkIGhhc0Nvbm5lY3Rpb25cbiAgICAgICAgICBGSUxURVIgdS5fa2V5ID09IFwiJHtzZXNzaW9uSWR9XCJcbiAgICAgICAgICBTT1JUIHAuYWRkZWRcbiAgICAgICAgICAke2xpbWl0LmFxbH1cbiAgICAgICAgICBSRVRVUk4gTUVSR0UocCwge3VzZXI6IHVzZXIsIHJlYWN0aW9uczogcmVhY3Rpb25zfSlgO1xuICAgICAgfSBlbHNlIGlmKHByaXZhY3kgPT09ICdwdWJsaWMnKSB7XG4gICAgICAgIHByaXZhY3lBcWxRcnkgPSBgRk9SIHAgSU4gcG9zdHNcbiAgICAgICAgICBGT1IgdXNlciBJTiB1c2Vyc1xuICAgICAgICAgIEZJTFRFUiBwLnBhcmVudCA9PSBcIiR7X2tleX1cIiAmJiB1c2VyLl9rZXkgPT0gcC51c2VySWRcbiAgICAgICAgICBMRVQgcmVhY3Rpb25zID0gKFxuICAgICAgICAgICAgRk9SIHBvc3QsIHIgSU4gSU5CT1VORCBwLl9pZCByZWFjdGlvbnNcbiAgICAgICAgICAgIENPTExFQ1QgcmVhY3Rpb25OYW1lID0gci52YWx1ZSBJTlRPIHJlYWN0aW9uSXRlbXNcbiAgICAgICAgICAgIFJFVFVSTiB7bmFtZTogcmVhY3Rpb25OYW1lLCBjb3VudDogTEVOR1RIKHJlYWN0aW9uSXRlbXNbKl0uci52YWx1ZSl9XG4gICAgICAgICAgKVxuICAgICAgICAgIFNPUlQgcC5hZGRlZFxuICAgICAgICAgICR7bGltaXQuYXFsfVxuICAgICAgICAgIFJFVFVSTiBNRVJHRShwLCB7dXNlcjogdXNlciwgcmVhY3Rpb25zOiByZWFjdGlvbnN9KWA7XG4gICAgICB9XG5cbiAgICAgIGlmKHByaXZhY3lBcWxRcnkpIHtcbiAgICAgICAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkocHJpdmFjeUFxbFFyeSlcbiAgICAgICAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkgYXMgdW5rbm93biBhcyBQb3N0VHlwZVtdKVxuICAgICAgICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICAgICAgICBsb2dFcnJvcih7XG4gICAgICAgICAgICAgIGFjdGlvbixcbiAgICAgICAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgICAgICAgIGxhYmVsOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgICAgICAgICB9LCBlcnJvciwgY29udGV4dCk7XG5cbiAgICAgICAgICAgIHJldHVybiBbXSBhcyBQb3N0VHlwZVtdO1xuICAgICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gW10gYXMgUG9zdFR5cGVbXTtcbiAgICB9KVxuICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICBsb2dFcnJvcih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIGxhYmVsOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgICB9LCBlcnJvciwgY29udGV4dCk7XG5cbiAgICAgIHJldHVybiBbXSBhcyBQb3N0VHlwZVtdO1xuICAgIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGFkZFBvc3QgPSBhc3luYyAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHtcbiAgICBjb250ZW50ID0gJycsXG4gICAgZW5kRGF0ZSxcbiAgICBncm91cElkID0gJycsXG4gICAgbG9jYXRpb24sXG4gICAgbGF0aXR1ZGUsXG4gICAgbG9uZ2l0dWRlLFxuICAgIG5hbWUgPSAnJyxcbiAgICBwYXJlbnRJZCA9ICcnLFxuICAgIHByaXZhY3kgPSAncHVibGljJyxcbiAgICB0YWdzID0gW10sXG4gICAgc3RhcnREYXRlLFxuICAgIHR5cGUgPSAnZGVmYXVsdCdcbiAgfTogUG9zdElucHV0VHlwZVxuKTogUHJvbWlzZTxQb3N0VHlwZT4gPT4ge1xuICBjb25zdCBhY3Rpb246IHN0cmluZyA9ICdhZGRQb3N0JztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZSwgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkfSA9IHt9fSA9IGNvbnRleHQ7XG4gIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gIGNvbnN0IHBvc3RJZCA9IGNyZWF0ZUhhc2goYHBvc3QtJHtzZXNzaW9uSWR9YCk7XG4gIGNvbnN0IGluc2VydDogUG9zdFR5cGUgPSB7XG4gICAgX2lkOiBgcG9zdHMvJHtwb3N0SWR9YCxcbiAgICBfa2V5OiBwb3N0SWQsXG4gICAgYWRkZWQ6IG5vdyxcbiAgICBjb250ZW50OiBwYXJzZVN0cmluZyhjb250ZW50LCBNQVhfQ09OVEVOVF9MRU5HVEgpIHx8ICcnLFxuICAgIGVuZERhdGU6IGVuZERhdGUgPyBwYXJzZU51bShlbmREYXRlLCAxMykgOiB1bmRlZmluZWQsXG4gICAgZ3JvdXBJZDogZ3JvdXBJZCA/IHBhcnNlSWQoZ3JvdXBJZCkgOiB1bmRlZmluZWQsXG4gICAgbGF0aXR1ZGU6IGxhdGl0dWRlICE9PSB1bmRlZmluZWQgPyBwYXJzZU51bShsYXRpdHVkZSkgOiB1bmRlZmluZWQsXG4gICAgbG9jYXRpb246IGxvY2F0aW9uID8gcGFyc2VTdHJpbmcobG9jYXRpb24sIDE2MCkgOiB1bmRlZmluZWQsXG4gICAgbG9uZ2l0dWRlOiBsb25naXR1ZGUgIT09IHVuZGVmaW5lZCA/IHBhcnNlTnVtKGxvbmdpdHVkZSkgOiB1bmRlZmluZWQsXG4gICAgbW9kaWZpZWQ6IG5vdyxcbiAgICBuYW1lOiBwYXJzZVN0cmluZyhuYW1lLCAxNjApLFxuICAgIHBhcmVudElkOiBwYXJlbnRJZCA/IHBhcnNlSWQocGFyZW50SWQpIDogdW5kZWZpbmVkLFxuICAgIHByaXZhY3k6IHBhcnNlVmFyQ2hhcihwcml2YWN5LCAxNiksXG4gICAgc3RhcnREYXRlOiBzdGFydERhdGUgPyBwYXJzZU51bShzdGFydERhdGUsIDEzKSA6IHVuZGVmaW5lZCxcbiAgICB0eXBlOiBwYXJzZUNoYXIodHlwZSwgMzIpLFxuICAgIHVzZXJJZDogc2Vzc2lvbklkXG4gIH07XG4gIGNvbnN0IGFxbFFyeTogQXFsUXVlcnkgPSBhcWxgSU5TRVJUICR7aW5zZXJ0fSBJTiBwb3N0cyBSRVRVUk4gTkVXYDtcblxuICB0cnkge1xuICAgIGNvbnN0IHNhdmVkUG9zdDogUG9zdFR5cGUgPSBhd2FpdCB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFFyeSlcbiAgICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4gbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICBsYWJlbDogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpKTtcbiAgICBjb25zdCB7X2lkOiBwb3N0RG9jSWR9ID0gc2F2ZWRQb3N0O1xuICAgIGNvbnN0IGNvbnRlbnRUYWdOYW1lcyA9IGF3YWl0IGV4dHJhY3RUYWdzKGluc2VydC5jb250ZW50IHx8ICcnKTtcblxuICAgIGlmKHRhZ3MubGVuZ3RoIHx8IGNvbnRlbnRUYWdOYW1lcy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHVzZXJUYWdzID0gKGF3YWl0IGdldFRhZ3NCeU5hbWUoY29udGV4dCwgdGFncy5tYXAoKHtuYW1lfSkgPT4gbmFtZSB8fCAnJykpKVxuICAgICAgICAubWFwKCh0YWcpID0+ICh7Li4udGFnLCB0YWdCeTogc2Vzc2lvbklkfSkpO1xuICAgICAgY29uc3QgY29udGVudFRhZ3MgPSAoYXdhaXQgZ2V0VGFnc0J5TmFtZShjb250ZXh0LCBjb250ZW50VGFnTmFtZXMgfHwgW10pKVxuICAgICAgICAubWFwKCh0YWcpID0+ICh7Li4udGFnLCB0YWdCeTogJ2V4dHJhY3QnfSkpO1xuICAgICAgY29uc3QgdXBkYXRlZFRhZ3M6IFRhZ1R5cGVbXSA9IGF3YWl0IHVwZGF0ZVRhZ3NJbkl0ZW0oXG4gICAgICAgIGNvbnRleHQsXG4gICAgICAgIHtcbiAgICAgICAgICBpdGVtRG9jSWQ6IHBvc3REb2NJZCxcbiAgICAgICAgICB0YWdzOiBbLi4uY29udGVudFRhZ3MsIC4uLnVzZXJUYWdzXVxuICAgICAgICB9XG4gICAgICApO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5zYXZlZFBvc3QsXG4gICAgICAgIHRhZ3M6IHVwZGF0ZWRUYWdzXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBzYXZlZFBvc3Q7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHVwZGF0ZVBvc3QgPSBhc3luYyAoY29udGV4dDogQXBpQ29udGV4dCwgcG9zdDogUG9zdElucHV0VHlwZSk6IFByb21pc2U8UG9zdFR5cGU+ID0+IHtcbiAgY29uc3QgYWN0aW9uOiBzdHJpbmcgPSAndXBkYXRlUG9zdCc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWUsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZH0gPSB7fX0gPSBjb250ZXh0O1xuICBjb25zdCBub3c6IG51bWJlciA9IERhdGUubm93KCk7XG4gIGNvbnN0IHBhcnNlZFBvc3QgPSBwYXJzZVBvc3QocG9zdCk7XG4gIGNvbnN0IHtcbiAgICBwb3N0SWQsXG4gICAgdGFncyA9IFtdXG4gIH0gPSBwYXJzZWRQb3N0O1xuXG4gIGNvbnN0IHVwZGF0ZTogUG9zdFR5cGUgPSB7XG4gICAgLi4ucGFyc2VkUG9zdCxcbiAgICBtb2RpZmllZDogbm93XG4gIH07XG5cbiAgaWYoIXBvc3RJZCkge1xuICAgIHRocm93IGxvZ0V4Y2VwdGlvbih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLklOVkFMSURfSURcbiAgICB9LCBjb250ZXh0KTtcbiAgfVxuXG4gIGNvbnN0IGluc2VydCA9IHtcbiAgICAuLi51cGRhdGUsXG4gICAgX2tleTogcG9zdElkLFxuICAgIGFkZGVkOiBub3csXG4gICAgdXNlcklkOiBzZXNzaW9uSWRcbiAgfTtcbiAgY29uc3QgYXFsUXJ5OiBBcWxRdWVyeSA9IGFxbGBVUFNFUlQge19rZXk6ICR7cG9zdElkfSwgdXNlcklkOiAke3Nlc3Npb25JZH19XG4gICAgSU5TRVJUICR7aW5zZXJ0fVxuICAgIFVQREFURSAke3VwZGF0ZX1cbiAgICBJTiBwb3N0cyBSRVRVUk4gTkVXYDtcblxuICB0cnkge1xuICAgIGNvbnN0IHVwZGF0ZWRQb3N0OiBQb3N0VHlwZSA9IGF3YWl0IHVzZURiKGRhdGFiYXNlTmFtZSlcbiAgICAgIC5xdWVyeShhcWxRcnkpXG4gICAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKVxuICAgICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCB7fSkpO1xuICAgIGNvbnN0IHtfaWQ6IHVwZGF0ZWRQb3N0SWR9ID0gdXBkYXRlZFBvc3Q7XG4gICAgY29uc3QgY29udGVudFRhZ05hbWVzID0gYXdhaXQgZXh0cmFjdFRhZ3MoaW5zZXJ0LmNvbnRlbnQgfHwgJycpO1xuXG4gICAgaWYodGFncz8ubGVuZ3RoIHx8IGNvbnRlbnRUYWdOYW1lcz8ubGVuZ3RoKSB7XG4gICAgICBjb25zdCB1c2VyVGFncyA9IHRhZ3M/Lmxlbmd0aCA/IChhd2FpdCBnZXRUYWdzQnlOYW1lKGNvbnRleHQsIHRhZ3MubWFwKCh7bmFtZX0pID0+IG5hbWUgfHwgJycpKSlcbiAgICAgICAgLm1hcCgodGFnKSA9PiAoey4uLnRhZywgdGFnQnk6IHNlc3Npb25JZH0pKSA6IFtdO1xuICAgICAgY29uc3QgY29udGVudFRhZ3MgPSBjb250ZW50VGFnTmFtZXM/Lmxlbmd0aCA/IChhd2FpdCBnZXRUYWdzQnlOYW1lKGNvbnRleHQsIGNvbnRlbnRUYWdOYW1lcyB8fCBbXSkpXG4gICAgICAgIC5tYXAoKHRhZykgPT4gKHsuLi50YWcsIHRhZ0J5OiAnZXh0cmFjdCd9KSkgOiBbXTtcbiAgICAgIGNvbnN0IHVwZGF0ZWRUYWdzOiBUYWdUeXBlW10gPSBhd2FpdCB1cGRhdGVUYWdzSW5JdGVtKFxuICAgICAgICBjb250ZXh0LFxuICAgICAgICB7XG4gICAgICAgICAgaXRlbURvY0lkOiB1cGRhdGVkUG9zdElkLFxuICAgICAgICAgIHRhZ3M6IFsuLi5jb250ZW50VGFncywgLi4udXNlclRhZ3NdXG4gICAgICAgIH1cbiAgICAgICk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLnVwZGF0ZWRQb3N0LFxuICAgICAgICB0YWdzOiB1cGRhdGVkVGFnc1xuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gdXBkYXRlZFBvc3Q7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGRlbGV0ZVBvc3QgPSBhc3luYyAoY29udGV4dDogQXBpQ29udGV4dCwgcG9zdERvY0lkOiBzdHJpbmcpOiBQcm9taXNlPFBvc3RUeXBlPiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2RlbGV0ZVBvc3QnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBzZXNzaW9uOiB7dXNlcklkOiBzZXNzaW9uSWR9ID0ge319ID0gY29udGV4dDtcbiAgY29uc3QgZm9ybWF0UG9zdElkOiBzdHJpbmcgPSBwYXJzZUFyYW5nb0lkKHBvc3REb2NJZCk7XG5cbiAgaWYoIWZvcm1hdFBvc3RJZCkge1xuICAgIHRocm93IGxvZ0V4Y2VwdGlvbih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLklOVkFMSURfSURcbiAgICB9LCBjb250ZXh0KTtcbiAgfVxuXG4gIGNvbnN0IGVkZ2VBcWxRcnk6IEFxbFF1ZXJ5ID0gYXFsYEZPUiB0IElOIGlzVGFnZ2VkXG4gIEZJTFRFUiB0Ll90byA9PSAke2Zvcm1hdFBvc3RJZH1cbiAgUkVNT1ZFIHQgSU4gaXNUYWdnZWRgO1xuXG4gIGF3YWl0IHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoZWRnZUFxbFFyeSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSk7XG5cbiAgY29uc3QgZmlsZUFxbFFyeTogQXFsUXVlcnkgPSBhcWxgRk9SIGYgSU4gaGFzRmlsZVxuICAgIEZJTFRFUiBmLl90byA9PSAke2Zvcm1hdFBvc3RJZH1cbiAgICBSRU1PVkUgZiBJTiBoYXNGaWxlYDtcblxuICBhd2FpdCB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGZpbGVBcWxRcnkpXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH0pO1xuXG4gIGNvbnN0IGFxbFFyeSA9IGFxbGBGT1IgcCBJTiBwb3N0c1xuICAgICAgRklMVEVSIHAuX2lkID09ICR7Zm9ybWF0UG9zdElkfSAmJiBwLnVzZXJJZCA9PSAke3Nlc3Npb25JZH1cbiAgICAgIExJTUlUIDFcbiAgICAgIFJFTU9WRSBwIElOIHBvc3RzXG4gICAgICBSRVRVUk4gT0xEYDtcblxuICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlUG9zdEVkZ2UgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHBvc3REb2NJZDogc3RyaW5nLFxuICBpdGVtRG9jSWQ6IHN0cmluZyxcbiAgZWRnZVR5cGU6IHN0cmluZyA9ICdpc1Bvc3RlZCcsXG4gIHByb3BzID0ge31cbik6IFByb21pc2U8RmlsZVR5cGU+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2NyZWF0ZVBvc3RFZGdlJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZX0gPSBjb250ZXh0O1xuICBjb25zdCBlZGdlQ29sbGVjdGlvbjogRWRnZUNvbGxlY3Rpb24gPSB1c2VEYihkYXRhYmFzZU5hbWUpLmNvbGxlY3Rpb24oZWRnZVR5cGUpO1xuICBjb25zdCBmb3JtYXRQb3N0SWQ6IHN0cmluZyA9IHBhcnNlQXJhbmdvSWQocG9zdERvY0lkKTtcbiAgY29uc3QgZm9ybWF0RG9jSWQ6IHN0cmluZyA9IHBhcnNlQXJhbmdvSWQoaXRlbURvY0lkKTtcblxuICBpZighZm9ybWF0RG9jSWQgfHwgIWZvcm1hdFBvc3RJZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihFcnJvclR5cGVzLklOVkFMSURfSUQpO1xuICB9XG5cbiAgY29uc3QgZWRnZUlkOiBzdHJpbmcgPSBjcmVhdGVIYXNoKGBwb3N0RWRnZS0ke2Zvcm1hdFBvc3RJZH0tJHtmb3JtYXREb2NJZH1gKTtcbiAgY29uc3QgZWRnZSA9IHtcbiAgICBfZnJvbTogZm9ybWF0UG9zdElkLFxuICAgIF9rZXk6IGVkZ2VJZCxcbiAgICBfdG86IGZvcm1hdERvY0lkLFxuICAgIGFkZGVkOiBEYXRlLm5vdygpLFxuICAgIC4uLnByb3BzXG4gIH07XG5cbiAgcmV0dXJuIGVkZ2VDb2xsZWN0aW9uLnNhdmUoZWRnZSwge3JldHVybk5ldzogdHJ1ZX0pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIHRocm93IGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgICB9KTtcbn07XG4iXSwKICAibWFwcGluZ3MiOiAiQUFJQSxPQUFTLFlBQUFBLE1BQWdCLCtCQUN6QixPQUNJLGNBQUFDLEVBQVksaUJBQUFDLEVBQWUsYUFBQUMsRUFBVyxXQUFBQyxFQUFTLGVBQUFDLEVBQWEsZ0JBQUFDLE1BQ3pELCtCQUNQLE9BQVMsT0FBQUMsTUFBVyxXQUdwQixPQUFTLGFBQUFDLE1BQWlCLDZCQUMxQixPQUFTLGNBQUFDLE1BQWtCLDBCQUMzQixPQUFTLFlBQUFDLEVBQVUsZ0JBQUFDLE1BQW9CLDZCQUN2QyxPQUFTLFlBQUFDLEVBQVUsU0FBQUMsTUFBYSw0QkFDaEMsT0FBUyxlQUFBQyxFQUFhLGlCQUFBQyxFQUFlLG9CQUFBQyxNQUF3QixZQVM3RCxNQUFNQyxFQUE2QixJQUM3QkMsRUFBd0IsUUFFakJDLEVBQW1CLENBQUNDLEVBQXVCLENBQUMsSUFBTSxDQUM3RCxLQUFNLENBQ0osS0FBQUMsRUFBTyxFQUNQLFNBQUFDLEVBQVcsRUFDWCxVQUFBQyxFQUFZLEVBQ1osR0FBQUMsRUFBSyxHQUNMLEtBQUFDLEVBQU8sTUFDVCxFQUFJTCxFQUVKLE1BQU8sQ0FDTCxTQUFVcEIsRUFBU3NCLEVBQVUsRUFBRSxFQUMvQixNQUFPVixFQUFTUyxFQUFNRyxDQUFFLEVBQ3hCLFVBQVd4QixFQUFTdUIsRUFBVyxFQUFFLEVBQ2pDLEtBQU1wQixFQUFVc0IsRUFBTSxFQUFFLENBQzFCLENBQ0YsRUFFYUMsRUFBa0IsQ0FBQ0MsRUFBbUIsQ0FBQyxFQUFHQyxFQUFvQixNQUN4RUQsR0FBVSxDQUFDLEdBQUcsT0FBTyxDQUFDRSxFQUFpREMsSUFBa0IsQ0FDeEYsT0FBT0EsRUFBTyxDQUNaLElBQUssVUFDSCxPQUFBRCxFQUFRLFFBQVEsS0FBSztBQUFBO0FBQUEsOEVBRWlERCxDQUFTO0FBQUE7QUFBQTtBQUFBLFdBRzVFLEVBQ0hD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QixFQUNBLFNBQVVoQixFQUNWLE1BQU9ULEVBQVcsY0FDcEIsRUFBR3VDLEVBQU9oQixDQUFPLENBQ25CLENBQUMsQ0FDTCIsCiAgIm5hbWVzIjogWyJwYXJzZU51bSIsICJjcmVhdGVIYXNoIiwgInBhcnNlQXJhbmdvSWQiLCAicGFyc2VDaGFyIiwgInBhcnNlSWQiLCAicGFyc2VTdHJpbmciLCAicGFyc2VWYXJDaGFyIiwgImFxbCIsICJwYXJzZVBvc3QiLCAiRXJyb3JUeXBlcyIsICJsb2dFcnJvciIsICJsb2dFeGNlcHRpb24iLCAiZ2V0TGltaXQiLCAidXNlRGIiLCAiZXh0cmFjdFRhZ3MiLCAiZ2V0VGFnc0J5TmFtZSIsICJ1cGRhdGVUYWdzSW5JdGVtIiwgIk1BWF9DT05URU5UX0xFTkdUSCIsICJldmVudENhdGVnb3J5IiwgInBhcnNlUG9zdE9wdGlvbnMiLCAib3B0aW9ucyIsICJmcm9tIiwgImxhdGl0dWRlIiwgImxvbmdpdHVkZSIsICJ0byIsICJ0eXBlIiwgImdldFBvc3RPcHRpb25hbCIsICJmaWVsZHMiLCAic2Vzc2lvbklkIiwgInNlbGVjdHMiLCAiZmllbGQiLCAiZ2V0UG9zdCIsICJjb250ZXh0IiwgInBvc3RJZCIsICJhY3Rpb24iLCAiZGF0YWJhc2VOYW1lIiwgImZvcm1hdEl0ZW1JZCIsICJkYXRhYmFzZSIsICJzZWxlY3RPYmplY3RzIiwgInNlbGVjdFF1ZXJpZXMiLCAiYXFsUXJ5IiwgImN1cnNvciIsICJwb3N0IiwgInBvc3REb2NJZCIsICJ1c2VySWQiLCAiZ3JvdXBJZCIsICJwcml2YWN5IiwgInByaXZhY3lBcWxRcnkiLCAiZXJyb3IiLCAiZ2V0UG9zdHNCeUFyZWEiLCAibGltaXQiLCAiZm9ybWF0TGF0aXR1ZGUiLCAiZm9ybWF0TG9uZ2l0dWRlIiwgImdldFBvc3RzQnlMYXRlc3QiLCAiZ2V0UG9zdHNCeVJlYWN0aW9ucyIsICJyZWFjdGlvbnMiLCAiZm9ybWF0U2Vzc2lvbklkIiwgImZvcm1hdFJlYWN0aW9ucyIsICJyZWFjdGlvbiIsICJzb3J0QnkiLCAiZmlsdGVycyIsICJnZXRQb3N0c0J5VGFncyIsICJ0YWdzIiwgImZvcm1hdFRhZ05hbWVzIiwgInRhZyIsICJnZXRQb3N0c0J5VXNlciIsICJmb3JtYXRVc2VySWQiLCAiZ2V0UG9zdENvbW1lbnRzIiwgIl9rZXkiLCAiYWRkUG9zdCIsICJjb250ZW50IiwgImVuZERhdGUiLCAibG9jYXRpb24iLCAibmFtZSIsICJwYXJlbnRJZCIsICJzdGFydERhdGUiLCAibm93IiwgImluc2VydCIsICJzYXZlZFBvc3QiLCAiY29udGVudFRhZ05hbWVzIiwgInVzZXJUYWdzIiwgImNvbnRlbnRUYWdzIiwgInVwZGF0ZWRUYWdzIiwgInVwZGF0ZVBvc3QiLCAicGFyc2VkUG9zdCIsICJ1cGRhdGUiLCAidXBkYXRlZFBvc3QiLCAidXBkYXRlZFBvc3RJZCIsICJkZWxldGVQb3N0IiwgImZvcm1hdFBvc3RJZCIsICJlZGdlQXFsUXJ5IiwgImZpbGVBcWxRcnkiLCAiY3JlYXRlUG9zdEVkZ2UiLCAiaXRlbURvY0lkIiwgImVkZ2VUeXBlIiwgInByb3BzIiwgImVkZ2VDb2xsZWN0aW9uIiwgImZvcm1hdERvY0lkIiwgImVkZ2VJZCIsICJlZGdlIl0KfQo=
575
+ RETURN OLD`;
576
+ return useDb(databaseName).query(aqlQry).then((cursor)=>cursor.next()).catch((error)=>{
577
+ throw error;
578
+ });
579
+ };
580
+ export const createPostEdge = (context, postDocId, itemDocId, edgeType = 'isPosted', props = {})=>{
581
+ const action = 'createPostEdge';
582
+ const { databaseName } = context;
583
+ const edgeCollection = useDb(databaseName).collection(edgeType);
584
+ const formatPostId = parseArangoId(postDocId);
585
+ const formatDocId = parseArangoId(itemDocId);
586
+ if (!formatDocId || !formatPostId) {
587
+ throw new Error(ErrorTypes.INVALID_ID);
588
+ }
589
+ const edgeId = createHash(`postEdge-${formatPostId}-${formatDocId}`);
590
+ const edge = {
591
+ _from: formatPostId,
592
+ _key: edgeId,
593
+ _to: formatDocId,
594
+ added: Date.now(),
595
+ ...props
596
+ };
597
+ return edgeCollection.save(edge, {
598
+ returnNew: true
599
+ }).catch((error)=>{
600
+ throw logError({
601
+ action,
602
+ category: eventCategory,
603
+ value: ErrorTypes.DATABASE_ERROR
604
+ }, error, context);
605
+ });
606
+ };
607
+
608
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L3JlYWt0b3Ivc3JjL2FjdGlvbnMvcG9zdHMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTktUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCB7IHBhcnNlTnVtIH0gZnJvbSAnQG5sYWJzL3V0aWxzL3BhcnNlcnMvbnVtYmVycyc7XG5pbXBvcnQge1xuICAgIGNyZWF0ZUhhc2gsIHBhcnNlQXJhbmdvSWQsIHBhcnNlQ2hhciwgcGFyc2VJZCwgcGFyc2VTdHJpbmcsIHBhcnNlVmFyQ2hhclxufSBmcm9tICdAbmxhYnMvdXRpbHMvcGFyc2Vycy9zdHJpbmdzJztcbmltcG9ydCB7IGFxbCB9IGZyb20gJ2FyYW5nb2pzJztcbmltcG9ydCB7IEFxbFF1ZXJ5IH0gZnJvbSAnYXJhbmdvanMvYXFsJztcblxuaW1wb3J0IHsgcGFyc2VQb3N0IH0gZnJvbSAnLi4vYWRhcHRlcnMvcG9zdEFkYXB0ZXIuanMnO1xuaW1wb3J0IHsgRXJyb3JUeXBlcyB9IGZyb20gJy4uL3R5cGVzL2Vycm9yLnR5cGVzLmpzJztcbmltcG9ydCB7IGxvZ0Vycm9yLCBsb2dFeGNlcHRpb24gfSBmcm9tICcuLi91dGlscy9hbmFseXRpY3NVdGlscy5qcyc7XG5pbXBvcnQgeyBnZXRMaW1pdCwgdXNlRGIgfSBmcm9tICcuLi91dGlscy9hcmFuZ29kYlV0aWxzLmpzJztcbmltcG9ydCB7IGV4dHJhY3RUYWdzLCBnZXRUYWdzQnlOYW1lLCB1cGRhdGVUYWdzSW5JdGVtIH0gZnJvbSAnLi90YWdzLmpzJztcblxuaW1wb3J0IHR5cGUgeyBFZGdlQ29sbGVjdGlvbiB9IGZyb20gJ2FyYW5nb2pzL2NvbGxlY3Rpb25zJztcbmltcG9ydCB0eXBlIHsgQXJhbmdvRGJMaW1pdCB9IGZyb20gJy4uL3R5cGVzL2FyYW5nb2RiLnR5cGVzLmpzJztcbmltcG9ydCB0eXBlIHsgQXBpQ29udGV4dCB9IGZyb20gJy4uL3R5cGVzL2F1dGgudHlwZXMuanMnO1xuaW1wb3J0IHR5cGUgeyBGaWxlVHlwZSB9IGZyb20gJy4uL3R5cGVzL2ZpbGVzLnR5cGVzLmpzJztcbmltcG9ydCB0eXBlIHsgUG9zdElucHV0VHlwZSwgUG9zdE9wdGlvbnMsIFBvc3RUeXBlIH0gZnJvbSAnLi4vdHlwZXMvcG9zdHMudHlwZXMuanMnO1xuaW1wb3J0IHR5cGUgeyBUYWdUeXBlIH0gZnJvbSAnLi4vdHlwZXMvdGFncy50eXBlcy5qcyc7XG5cbmNvbnN0IE1BWF9DT05URU5UX0xFTkdUSDogbnVtYmVyID0gMTAwMDAwO1xuY29uc3QgZXZlbnRDYXRlZ29yeTogc3RyaW5nID0gJ3Bvc3RzJztcblxuZXhwb3J0IGNvbnN0IHBhcnNlUG9zdE9wdGlvbnMgPSAob3B0aW9uczogUG9zdE9wdGlvbnMgPSB7fSkgPT4ge1xuICBjb25zdCB7XG4gICAgZnJvbSA9IDAsXG4gICAgbGF0aXR1ZGUgPSAwLFxuICAgIGxvbmdpdHVkZSA9IDAsXG4gICAgdG8gPSAzMCxcbiAgICB0eXBlID0gJ3Bvc3QnXG4gIH0gPSBvcHRpb25zO1xuXG4gIHJldHVybiB7XG4gICAgbGF0aXR1ZGU6IHBhcnNlTnVtKGxhdGl0dWRlLCAzMiksXG4gICAgbGltaXQ6IGdldExpbWl0KGZyb20sIHRvKSBhcyBBcmFuZ29EYkxpbWl0LFxuICAgIGxvbmdpdHVkZTogcGFyc2VOdW0obG9uZ2l0dWRlLCAzMiksXG4gICAgdHlwZTogcGFyc2VDaGFyKHR5cGUsIDMyKVxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFBvc3RPcHRpb25hbCA9IChmaWVsZHM6IHN0cmluZ1tdID0gW10sIHNlc3Npb25JZDogc3RyaW5nID0gJycpID0+XG4gIChmaWVsZHMgfHwgW10pLnJlZHVjZSgoc2VsZWN0czoge29iamVjdHM6IHN0cmluZ1tdLCBxdWVyaWVzOiBzdHJpbmdbXX0sIGZpZWxkOiBzdHJpbmcpID0+IHtcbiAgICBzd2l0Y2goZmllbGQpIHtcbiAgICAgIGNhc2UgJ2hhc1JzdnAnOiB7XG4gICAgICAgIHNlbGVjdHMucXVlcmllcy5wdXNoKGBMRVQgaGFzUnN2cCA9IFRPX0JPT0woRklSU1QoXG4gICAgICAgICAgRk9SIHBvc3QsIHIgSU4gSU5CT1VORCBwLl9pZCBoYXNSZWFjdGlvblxuICAgICAgICAgIEZJTFRFUiByLm5hbWUgPT0gXCJyc3ZwXCIgJiYgci50eXBlID09IFwicG9zdHNcIiAmJiByLl9mcm9tID09IFwidXNlcnMvJHtzZXNzaW9uSWR9XCJcbiAgICAgICAgICBDT0xMRUNUIFdJVEggQ09VTlQgSU5UTyBjb3VudFxuICAgICAgICAgIFJFVFVSTiBjb3VudFxuICAgICAgICApKWApO1xuICAgICAgICBzZWxlY3RzLm9iamVjdHMucHVzaCgnaGFzUnN2cDpoYXNSc3ZwJyk7XG4gICAgICAgIHJldHVybiBzZWxlY3RzO1xuICAgICAgfVxuICAgICAgY2FzZSAnaXNTYXZlZCc6IHtcbiAgICAgICAgc2VsZWN0cy5xdWVyaWVzLnB1c2goYExFVCBpc1NhdmVkID0gVE9fQk9PTChGSVJTVChcbiAgICAgICAgICBGT1IgcG9zdCwgciBJTiBJTkJPVU5EIHAuX2lkIGhhc1JlYWN0aW9uXG4gICAgICAgICAgRklMVEVSIHIubmFtZSA9PSBcInBpblwiICYmIHIudHlwZSA9PSBcInBvc3RzXCIgJiYgci5fZnJvbSA9PSBcInVzZXJzLyR7c2Vzc2lvbklkfVwiXG4gICAgICAgICAgQ09MTEVDVCBXSVRIIENPVU5UIElOVE8gY291bnRcbiAgICAgICAgICBSRVRVUk4gY291bnRcbiAgICAgICAgKSlgKTtcbiAgICAgICAgc2VsZWN0cy5vYmplY3RzLnB1c2goJ2lzU2F2ZWQ6aXNTYXZlZCcpO1xuICAgICAgICByZXR1cm4gc2VsZWN0cztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ3JlYWN0aW9ucyc6IHtcbiAgICAgICAgc2VsZWN0cy5xdWVyaWVzLnB1c2goYExFVCByZWFjdGlvbnMgPSAoXG4gICAgICAgICAgRk9SIHBvc3QsIHIgSU4gSU5CT1VORCBwLl9pZCBoYXNSZWFjdGlvblxuICAgICAgICAgIENPTExFQ1QgcmVhY3Rpb25OYW1lID0gci52YWx1ZSBJTlRPIHJlYWN0aW9uSXRlbXNcbiAgICAgICAgICBSRVRVUk4ge25hbWU6IHJlYWN0aW9uTmFtZSwgY291bnQ6IExFTkdUSChyZWFjdGlvbkl0ZW1zWypdLnIudmFsdWUpfVxuICAgICAgICApYCk7XG4gICAgICAgIHNlbGVjdHMub2JqZWN0cy5wdXNoKCdyZWFjdGlvbnM6cmVhY3Rpb25zJyk7XG4gICAgICAgIHJldHVybiBzZWxlY3RzO1xuICAgICAgfVxuICAgICAgY2FzZSAncnN2cENvdW50Jzoge1xuICAgICAgICBzZWxlY3RzLnF1ZXJpZXMucHVzaChgTEVUIHJzdnBDb3VudCA9IEZJUlNUKFxuICAgICAgICAgIEZPUiBwb3N0LCByIElOIElOQk9VTkQgcC5faWQgaGFzUmVhY3Rpb25cbiAgICAgICAgICBGSUxURVIgci5uYW1lID09IFwicnN2cFwiICYmIHIudHlwZSA9PSBcInBvc3RzXCJcbiAgICAgICAgICBDT0xMRUNUIFdJVEggQ09VTlQgSU5UTyBjb3VudFxuICAgICAgICAgIFJFVFVSTiBjb3VudFxuICAgICAgICApYCk7XG4gICAgICAgIHNlbGVjdHMub2JqZWN0cy5wdXNoKCdyc3ZwQ291bnQ6cnN2cENvdW50Jyk7XG4gICAgICAgIHJldHVybiBzZWxlY3RzO1xuICAgICAgfVxuICAgICAgY2FzZSAndmlld0NvdW50Jzoge1xuICAgICAgICBzZWxlY3RzLnF1ZXJpZXMucHVzaChgTEVUIHZpZXdDb3VudCA9IEZJUlNUKFxuICAgICAgICAgIEZPUiBwb3N0LCByIElOIElOQk9VTkQgcC5faWQgaGFzUmVhY3Rpb25cbiAgICAgICAgICBGSUxURVIgci5uYW1lID09IFwidmlld1wiICYmIHIudHlwZSA9PSBcInBvc3RzXCJcbiAgICAgICAgICBDT0xMRUNUIFdJVEggQ09VTlQgSU5UTyBjb3VudFxuICAgICAgICAgIFJFVFVSTiBjb3VudFxuICAgICAgICApYCk7XG4gICAgICAgIHNlbGVjdHMub2JqZWN0cy5wdXNoKCd2aWV3Q291bnQ6dmlld0NvdW50Jyk7XG4gICAgICAgIHJldHVybiBzZWxlY3RzO1xuICAgICAgfVxuICAgICAgZGVmYXVsdDoge1xuICAgICAgICByZXR1cm4gc2VsZWN0cztcbiAgICAgIH1cbiAgICB9XG4gIH0sIHtvYmplY3RzOiBbXSwgcXVlcmllczogW119KTtcblxuZXhwb3J0IGNvbnN0IGdldFBvc3QgPSBhc3luYyAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHBvc3RJZDogc3RyaW5nLFxuICBvcHRpb25zPzogUG9zdE9wdGlvbnNcbik6IFByb21pc2U8UG9zdFR5cGU+ID0+IHtcbiAgY29uc3QgYWN0aW9uOiBzdHJpbmcgPSAnZ2V0UG9zdCc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWUsIGZpZWxkcywgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkfSA9IHt9fSA9IGNvbnRleHQ7XG4gIGNvbnN0IGZvcm1hdEl0ZW1JZDogc3RyaW5nID0gcGFyc2VJZChwb3N0SWQpO1xuICBjb25zdCB7dHlwZX0gPSBwYXJzZVBvc3RPcHRpb25zKG9wdGlvbnMpO1xuICBjb25zdCBkYXRhYmFzZSA9IHVzZURiKGRhdGFiYXNlTmFtZSk7XG4gIGNvbnN0IHtvYmplY3RzOiBzZWxlY3RPYmplY3RzLCBxdWVyaWVzOiBzZWxlY3RRdWVyaWVzfSA9IGdldFBvc3RPcHRpb25hbChmaWVsZHMsIHNlc3Npb25JZCk7XG4gIGNvbnN0IGFxbFFyeTogQXFsUXVlcnkgPSBhcWxgRk9SIHAgSU4gcG9zdHNcbiAgICBGSUxURVIgcC5fa2V5ID09ICR7Zm9ybWF0SXRlbUlkfSAmJiBwLnR5cGUgPT0gJHt0eXBlfVxuICAgIExJTUlUIDFcbiAgICBSRVRVUk4gcGA7XG5cbiAgcmV0dXJuIGRhdGFiYXNlLnF1ZXJ5KGFxbFFyeSlcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKVxuICAgIC50aGVuKChwb3N0OiBQb3N0VHlwZSkgPT4ge1xuICAgICAgY29uc3Qge1xuICAgICAgICBfaWQ6IHBvc3REb2NJZCxcbiAgICAgICAgdXNlcklkLFxuICAgICAgICBncm91cElkLFxuICAgICAgICBwcml2YWN5ID0gJ2RlZmF1bHQnXG4gICAgICB9OiBQb3N0VHlwZSA9IHBvc3Q7XG5cbiAgICAgIGxldCBwcml2YWN5QXFsUXJ5OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICAgIGlmKHVzZXJJZCA9PT0gc2Vzc2lvbklkKSB7XG4gICAgICAgIHJldHVybiBwb3N0O1xuICAgICAgfVxuXG4gICAgICBpZihncm91cElkICYmIHByaXZhY3kgPT09ICdncm91cCcpIHtcbiAgICAgICAgcHJpdmFjeUFxbFFyeSA9IGBMRVQgcCA9IERPQ1VNRU5UKFwiJHtwb3N0RG9jSWR9XCIpXG4gICAgICAgICAgJHtzZWxlY3RRdWVyaWVzLmpvaW4oJ1xcbicpfVxuICAgICAgICAgIEZPUiBncm91cCBJTiBncm91cHNcbiAgICAgICAgICBGSUxURVIgZ3JvdXAuX2tleSA9PSBwLmdyb3VwSWRcbiAgICAgICAgICBGT1IgdSwgZSBJTiBPVVRCT1VORCBncm91cC5faWQgaGFzQ29ubmVjdGlvblxuICAgICAgICAgIEZJTFRFUiB1Ll9rZXkgPT0gXCIke3Nlc3Npb25JZH1cIlxuICAgICAgICAgIExJTUlUIDFcbiAgICAgICAgICBSRVRVUk4gTUVSR0UocCwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcbiAgICAgIH0gZWxzZSBpZihwcml2YWN5ID09PSAncHVibGljJykge1xuICAgICAgICBwcml2YWN5QXFsUXJ5ID0gYExFVCBwID0gRE9DVU1FTlQoXCIke3Bvc3REb2NJZH1cIilcbiAgICAgICAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgICAgICAgTElNSVQgMVxuICAgICAgICAgIFJFVFVSTiBNRVJHRShwLCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuICAgICAgfVxuXG4gICAgICBpZihwcml2YWN5QXFsUXJ5KSB7XG4gICAgICAgIHJldHVybiBkYXRhYmFzZS5xdWVyeShwcml2YWN5QXFsUXJ5KVxuICAgICAgICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgICAgICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IGxvZ0Vycm9yKHtcbiAgICAgICAgICAgIGFjdGlvbixcbiAgICAgICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICAgICAgbGFiZWw6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgICAgICB9LCBlcnJvciwgY29udGV4dCkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge307XG4gICAgfSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4gbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBsYWJlbDogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KSk7XG59O1xuXG5cbi8vIGV4cG9ydCBjb25zdCBnZXRQb3N0TGlzdCA9IChjb250ZXh0OiBBcGlDb250ZXh0LCBvcHRpb25zPzogUG9zdE9wdGlvbnMpOiBQcm9taXNlPFBvc3RUeXBlW10+ID0+IHtcbi8vICAgLy8gY29uc3QgYWN0aW9uOiBzdHJpbmcgPSAnZ2V0TGlzdEJ5QXBwJztcbi8vICAgY29uc3Qge2RhdGFiYXNlLCBmaWVsZHMsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZH19ID0gY29udGV4dDtcbi8vICAgY29uc3Qge2xpbWl0LCB0eXBlfSA9IHBhcnNlUG9zdE9wdGlvbnMob3B0aW9ucyk7XG4vLyAgIGNvbnN0IHtvYmplY3RzOiBzZWxlY3RPYmplY3RzLCBxdWVyaWVzOiBzZWxlY3RRdWVyaWVzfSA9IGdldFBvc3RPcHRpb25hbChmaWVsZHMsIHNlc3Npb25JZCk7XG4vLyAgIGNvbnN0IGFxbFFyeTogc3RyaW5nID0gYEZPUiBwIElOIHBvc3RzXG4vLyAgICAgRklMVEVSIHAudHlwZSA9PSBcIiR7dHlwZX1cIiAmJiBwLnByaXZhY3kgPT0gXCJwdWJsaWNcIiAmJiBwLnBhcmVudCA9PSBudWxsXG4vLyAgICAgJHtzZWxlY3RRdWVyaWVzLmpvaW4oJ1xcbicpfVxuLy8gICAgICR7bGltaXQuYXFsfVxuLy8gICAgIFNPUlQgcC5hZGRlZFxuLy8gICAgIFJFVFVSTiBESVNUSU5DVCBNRVJHRShwLCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4vLyAgIHJldHVybiBkYXRhYmFzZS5xdWVyeShhcWxRcnkpXG4vLyAgICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpKVxuLy8gICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiB7XG4vLyAgICAgICB0aHJvdyBlcnJvcjtcbi8vICAgICB9KTtcbi8vIH07XG5cbmV4cG9ydCBjb25zdCBnZXRQb3N0c0J5QXJlYSA9IChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgbGF0aXR1ZGU6IG51bWJlcixcbiAgbG9uZ2l0dWRlOiBudW1iZXIsXG4gIG9wdGlvbnM/OiBQb3N0T3B0aW9uc1xuKTogUHJvbWlzZTxQb3N0VHlwZVtdPiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2dldFBvc3RzQnlBcmVhJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZSwgZmllbGRzLCBzZXNzaW9uOiB7dXNlcklkOiBzZXNzaW9uSWR9ID0ge319ID0gY29udGV4dDtcbiAgY29uc3Qge2xpbWl0LCB0eXBlfSA9IHBhcnNlUG9zdE9wdGlvbnMob3B0aW9ucyk7XG4gIGNvbnN0IGZvcm1hdExhdGl0dWRlOiBudW1iZXIgPSBwYXJzZU51bShsYXRpdHVkZSk7XG4gIGNvbnN0IGZvcm1hdExvbmdpdHVkZTogbnVtYmVyID0gcGFyc2VOdW0obG9uZ2l0dWRlKTtcbiAgY29uc3Qge29iamVjdHM6IHNlbGVjdE9iamVjdHMsIHF1ZXJpZXM6IHNlbGVjdFF1ZXJpZXN9ID0gZ2V0UG9zdE9wdGlvbmFsKGZpZWxkcywgc2Vzc2lvbklkKTtcbiAgc2VsZWN0UXVlcmllcy5wdXNoKGBMRVQgZGlzdGFuY2UgPSBESVNUQU5DRShcbiAgICAke2Zvcm1hdExhdGl0dWRlfSxcbiAgICAke2Zvcm1hdExvbmdpdHVkZX0sXG4gICAgTk9UX05VTEwocC5sYXRpdHVkZSwgMCksXG4gICAgTk9UX05VTEwocC5sb25naXR1ZGUsIDApKVxuICBgKTtcbiAgc2VsZWN0T2JqZWN0cy5wdXNoKCdkaXN0YW5jZTpkaXN0YW5jZScpO1xuXG4gIGNvbnN0IGFxbFFyeTogc3RyaW5nID0gYEZPUiBwIElOIHBvc3RzXG4gICAgJHtzZWxlY3RRdWVyaWVzLmpvaW4oJ1xcbicpfVxuICAgIEZJTFRFUiBwLnR5cGUgPT0gXCIke3R5cGV9XCIgJiYgcC5wcml2YWN5ID09IFwicHVibGljXCIgJiYgcC5wYXJlbnRJZCA9PSBudWxsXG4gICAgJHtsaW1pdC5hcWx9XG4gICAgU09SVCBkaXN0YW5jZSwgcC5hZGRlZFxuICAgIFJFVFVSTiBESVNUSU5DVCBNRVJHRShwLCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFFyeSlcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkgYXMgdW5rbm93biBhcyBQb3N0VHlwZVtdKVxuICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICBsb2dFcnJvcih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIGxhYmVsOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgICB9LCBlcnJvciwgY29udGV4dCk7XG5cbiAgICAgIHJldHVybiBbXSBhcyBQb3N0VHlwZVtdO1xuICAgIH0pO1xufTtcblxuLy8gZXhwb3J0IGNvbnN0IGdldFBvc3RzQnlHcm91cCA9IChcbi8vICAgY29udGV4dDogQXBpQ29udGV4dCxcbi8vICAgZ3JvdXBJZDogc3RyaW5nLFxuLy8gICBvcHRpb25zPzogUG9zdE9wdGlvbnNcbi8vICk6IFByb21pc2U8UG9zdFR5cGVbXT4gPT4ge1xuLy8gICAvLyBjb25zdCBhY3Rpb246IHN0cmluZyA9ICdnZXRMaXN0QnlHcm91cCc7XG4vLyAgIGNvbnN0IHtkYXRhYmFzZSwgZmllbGRzLCBzZXNzaW9uOiB7dXNlcklkOiBzZXNzaW9uSWR9fSA9IGNvbnRleHQ7XG4vLyAgIGNvbnN0IHtvYmplY3RzOiBzZWxlY3RPYmplY3RzLCBxdWVyaWVzOiBzZWxlY3RRdWVyaWVzfSA9IGdldFBvc3RPcHRpb25hbChmaWVsZHMsIHNlc3Npb25JZCk7XG5cbi8vICAgLy8gR3JvdXAgaWRcbi8vICAgY29uc3QgZm9ybWF0R3JvdXBJZDogc3RyaW5nID0gcGFyc2VJZChncm91cElkKTtcbi8vICAgY29uc3QgZGIgPSBkYXRhYmFzZTtcbi8vICAgY29uc3QgYXFsUXJ5OiBzdHJpbmcgPSBgRk9SIHUsIGcgSU4gSU5CT1VORCAke2Zvcm1hdEdyb3VwSWR9IGhhc0dyb3VwXG4vLyAgICAgICBGSUxURVIgdS5fa2V5ID09ICR7c2Vzc2lvbklkfVxuLy8gICAgICAgUkVUVVJOIGdgO1xuXG4vLyAgIHJldHVybiBkYi5xdWVyeShhcWxRcnkpXG4vLyAgICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpKVxuLy8gICAgIC50aGVuKChncm91cHM6IEdyb3VwVHlwZVtdID0gW10pID0+IHtcbi8vICAgICAgIGlmKGdyb3Vwcy5sZW5ndGgpIHtcbi8vICAgICAgICAgY29uc3Qge2xpbWl0LCB0eXBlfSA9IHBhcnNlUG9zdE9wdGlvbnMob3B0aW9ucyk7XG4vLyAgICAgICAgIGNvbnN0IHBvc3RBcWxRcnk6IHN0cmluZyA9IGBGT1IgcCBJTiBwb3N0c1xuLy8gICAgICAgICAgIEZJTFRFUiBwLnR5cGUgPT0gXCIke3R5cGV9XCIgJiYgcC5ncm91cElkID09IFwiJHtmb3JtYXRHcm91cElkfVwiICYmIHAucGFyZW50ID09IG51bGxcbi8vICAgICAgICAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4vLyAgICAgICAgICAgJHtsaW1pdC5hcWx9XG4vLyAgICAgICAgICAgU09SVCBwLmFkZGVkXG4vLyAgICAgICAgICAgUkVUVVJOIERJU1RJTkNUIE1FUkdFKHAsIHske3NlbGVjdE9iamVjdHMuam9pbignLCAnKX19KWA7XG5cbi8vICAgICAgICAgcmV0dXJuIGRiLnF1ZXJ5KHBvc3RBcWxRcnkpXG4vLyAgICAgICAgICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpKVxuLy8gICAgICAgICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiB7XG4vLyAgICAgICAgICAgICB0aHJvdyBlcnJvcjtcbi8vICAgICAgICAgICB9KTtcbi8vICAgICAgIH1cblxuLy8gICAgICAgcmV0dXJuIFtdO1xuLy8gICAgIH0pXG4vLyAgICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbi8vICAgICAgIHRocm93IGVycm9yO1xuLy8gICAgIH0pO1xuLy8gfTtcblxuZXhwb3J0IGNvbnN0IGdldFBvc3RzQnlMYXRlc3QgPSAoY29udGV4dDogQXBpQ29udGV4dCwgb3B0aW9ucz86IFBvc3RPcHRpb25zKTogUHJvbWlzZTxQb3N0VHlwZVtdPiA9PiB7XG4gIC8vIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2dldExpc3RCeUxhdGVzdCc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWUsIGZpZWxkcywgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkfSA9IHt9fSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtsaW1pdCwgdHlwZX0gPSBwYXJzZVBvc3RPcHRpb25zKG9wdGlvbnMpO1xuICBjb25zdCB7b2JqZWN0czogc2VsZWN0T2JqZWN0cywgcXVlcmllczogc2VsZWN0UXVlcmllc30gPSBnZXRQb3N0T3B0aW9uYWwoZmllbGRzLCBzZXNzaW9uSWQpO1xuICBjb25zdCBhcWxRcnk6IHN0cmluZyA9IGBGT1IgcCBJTiBwb3N0c1xuICAgIEZJTFRFUiBwLnR5cGUgPT0gXCIke3R5cGV9XCIgJiYgcC5wcml2YWN5ID09IFwicHVibGljXCIgJiYgcC5wYXJlbnQgPT0gbnVsbFxuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICAke2xpbWl0LmFxbH1cbiAgICBTT1JUIHAuYWRkZWQgREVTQ1xuICAgIFJFVFVSTiBESVNUSU5DVCBNRVJHRShwLCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFFyeSlcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkpXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFBvc3RzQnlSZWFjdGlvbnMgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHJlYWN0aW9uczogc3RyaW5nW10gPSBbXSxcbiAgb3B0aW9ucz86IFBvc3RPcHRpb25zXG4pOiBQcm9taXNlPFBvc3RUeXBlW10+ID0+IHtcbiAgY29uc3QgYWN0aW9uOiBzdHJpbmcgPSAnZ2V0UG9zdHNCeVJlYWN0aW9ucyc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWUsIGZpZWxkcywgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkfSA9IHt9fSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtsYXRpdHVkZSwgbGltaXQsIGxvbmdpdHVkZSwgdHlwZX0gPSBwYXJzZVBvc3RPcHRpb25zKG9wdGlvbnMpO1xuICBjb25zdCB7b2JqZWN0czogc2VsZWN0T2JqZWN0cywgcXVlcmllczogc2VsZWN0UXVlcmllc30gPSBnZXRQb3N0T3B0aW9uYWwoZmllbGRzLCBzZXNzaW9uSWQpO1xuICBjb25zdCBmb3JtYXRTZXNzaW9uSWQ6IHN0cmluZyA9IGB1c2Vycy8ke3Nlc3Npb25JZH1gO1xuICBjb25zdCBmb3JtYXRSZWFjdGlvbnM6IHN0cmluZyA9IEpTT04uc3RyaW5naWZ5KHJlYWN0aW9ucy5tYXAoKHJlYWN0aW9uKSA9PiBwYXJzZUNoYXIocmVhY3Rpb24sIDMyKS50b0xvd2VyQ2FzZSgpKSk7XG4gIGNvbnN0IHNvcnRCeTogc3RyaW5nW10gPSBbXTtcbiAgY29uc3QgZmlsdGVyczogc3RyaW5nW10gPSBbYHAudHlwZSA9PSBcIiR7dHlwZX1cImAsICdwLnByaXZhY3kgPT0gXCJwdWJsaWNcIiddO1xuICBjb25zdCBmb3JtYXRMYXRpdHVkZTogbnVtYmVyID0gcGFyc2VOdW0obGF0aXR1ZGUpO1xuICBjb25zdCBmb3JtYXRMb25naXR1ZGU6IG51bWJlciA9IHBhcnNlTnVtKGxvbmdpdHVkZSk7XG5cbiAgaWYoZm9ybWF0TGF0aXR1ZGUgJiYgZm9ybWF0TG9uZ2l0dWRlKSB7XG4gICAgc2VsZWN0UXVlcmllcy5wdXNoKGBMRVQgZGlzdGFuY2UgPSBESVNUQU5DRShcbiAgICAgICR7Zm9ybWF0TGF0aXR1ZGV9LFxuICAgICAgJHtmb3JtYXRMb25naXR1ZGV9LFxuICAgICAgTk9UX05VTEwocC5sYXRpdHVkZSwgMCksXG4gICAgICBOT1RfTlVMTChwLmxvbmdpdHVkZSwgMCkpXG4gICAgYCk7XG4gICAgc2VsZWN0T2JqZWN0cy5wdXNoKCdkaXN0YW5jZTpkaXN0YW5jZScpO1xuICAgIHNvcnRCeS5wdXNoKCdkaXN0YW5jZScpO1xuICB9XG5cbiAgaWYocmVhY3Rpb25zLmxlbmd0aCkge1xuICAgIHNvcnRCeS5wdXNoKCdtYXRjaGVkVGFncyBERVNDJyk7XG4gICAgc2VsZWN0UXVlcmllcy5wdXNoKGBMRVQgbWF0Y2hlZFJlYWN0aW9ucyA9IExFTkdUSChcbiAgICAgIEZPUiBtciBJTiByZWFjdGlvbnNcbiAgICAgIEZJTFRFUiBtci5tYXRjaGVkID09IHRydWVcbiAgICAgIFJFVFVSTiBtclxuICAgIClgKTtcbiAgICBzZWxlY3RPYmplY3RzLnB1c2goJ21hdGNoZWRSZWFjdGlvbnM6bWF0Y2hlZFJlYWN0aW9ucycpO1xuICAgIGZpbHRlcnMucHVzaCgnbWF0Y2hlZFJlYWN0aW9ucyA+IDAnKTtcbiAgfVxuXG4gIHNvcnRCeS5wdXNoKCdwLmFkZGVkIERFU0MnKTtcbiAgc2VsZWN0T2JqZWN0cy5wdXNoKCdyZWFjdGlvbnM6cmVhY3Rpb25zJyk7XG5cbiAgLy8gR2V0IGRhdGEgZnJvbSBkYXRhYmFzZVxuICBjb25zdCBhcWxRcnk6IHN0cmluZyA9IGBGT1IgcCwgciBJTiBPVVRCT1VORCBcIiR7Zm9ybWF0U2Vzc2lvbklkfVwiIGhhc1JlYWN0aW9uXG4gICAgTEVUIHJlYWN0aW9ucyA9IChcbiAgICAgIEZPUiByZWFjdGlvbiwgaHIgSU4gMS4uMSBJTkJPVU5EIHAgaXNUYWdnZWRcbiAgICAgIExFVCBtYXRjaGVkID0gTEVOR1RIKCR7Zm9ybWF0UmVhY3Rpb25zfSkgPiAwICYmIFBPU0lUSU9OKCR7Zm9ybWF0UmVhY3Rpb25zfSwgcmVhY3Rpb24ubmFtZSlcbiAgICAgIFNPUlQgcmVhY3Rpb24ubmFtZVxuICAgICAgUkVUVVJOIE1FUkdFKHJlYWN0aW9uLCB7bWF0Y2hlZDptYXRjaGVkfSlcbiAgICApXG4gICAgJHtzZWxlY3RRdWVyaWVzLmpvaW4oJ1xcbicpfVxuICAgIEZJTFRFUiAke2ZpbHRlcnMuam9pbignICYmICcpfVxuICAgICR7bGltaXQuYXFsfVxuICAgIFJFVFVSTiBESVNUSU5DVCBNRVJHRShwLCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFFyeSlcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkgYXMgdW5rbm93biBhcyBQb3N0VHlwZVtdKVxuICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICBsb2dFcnJvcih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIGxhYmVsOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgICB9LCBlcnJvciwgY29udGV4dCk7XG5cbiAgICAgIHJldHVybiBbXSBhcyBQb3N0VHlwZVtdO1xuICAgIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFBvc3RzQnlUYWdzID0gKFxuICBjb250ZXh0OiBBcGlDb250ZXh0LFxuICB0YWdzOiBzdHJpbmdbXSA9IFtdLFxuICBvcHRpb25zPzogUG9zdE9wdGlvbnNcbik6IFByb21pc2U8UG9zdFR5cGVbXT4gPT4ge1xuICBjb25zdCBhY3Rpb246IHN0cmluZyA9ICdnZXRQb3N0c0J5VGFncyc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWUsIGZpZWxkcywgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkfSA9IHt9fSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtsYXRpdHVkZSwgbGltaXQsIGxvbmdpdHVkZSwgdHlwZX0gPSBwYXJzZVBvc3RPcHRpb25zKG9wdGlvbnMpO1xuICBjb25zdCB7b2JqZWN0czogc2VsZWN0T2JqZWN0cywgcXVlcmllczogc2VsZWN0UXVlcmllc30gPSBnZXRQb3N0T3B0aW9uYWwoZmllbGRzLCBzZXNzaW9uSWQpO1xuICBjb25zdCBmb3JtYXRUYWdOYW1lczogc3RyaW5nID0gSlNPTi5zdHJpbmdpZnkodGFncy5tYXAoKHRhZykgPT4gcGFyc2VDaGFyKHRhZywgMzIpLnRvTG93ZXJDYXNlKCkpKTtcbiAgY29uc3Qgc29ydEJ5OiBzdHJpbmdbXSA9IFtdO1xuICBjb25zdCBmaWx0ZXJzOiBzdHJpbmdbXSA9IFtgcC50eXBlID09IFwiJHt0eXBlfVwiYCwgJ3AucHJpdmFjeSA9PSBcInB1YmxpY1wiJ107XG4gIGNvbnN0IGZvcm1hdExhdGl0dWRlOiBudW1iZXIgPSBwYXJzZU51bShsYXRpdHVkZSk7XG4gIGNvbnN0IGZvcm1hdExvbmdpdHVkZTogbnVtYmVyID0gcGFyc2VOdW0obG9uZ2l0dWRlKTtcblxuICBpZihmb3JtYXRMYXRpdHVkZSAmJiBmb3JtYXRMb25naXR1ZGUpIHtcbiAgICBzZWxlY3RRdWVyaWVzLnB1c2goYExFVCBkaXN0YW5jZSA9IERJU1RBTkNFKFxuICAgICAgJHtmb3JtYXRMYXRpdHVkZX0sXG4gICAgICAke2Zvcm1hdExvbmdpdHVkZX0sXG4gICAgICBOT1RfTlVMTChwLmxhdGl0dWRlLCAwKSxcbiAgICAgIE5PVF9OVUxMKHAubG9uZ2l0dWRlLCAwKSlcbiAgICBgKTtcbiAgICBzZWxlY3RPYmplY3RzLnB1c2goJ2Rpc3RhbmNlOmRpc3RhbmNlJyk7XG4gICAgc29ydEJ5LnB1c2goJ2Rpc3RhbmNlJyk7XG4gIH1cblxuICBpZih0YWdzLmxlbmd0aCkge1xuICAgIHNvcnRCeS5wdXNoKCdtYXRjaGVkVGFncyBERVNDJyk7XG4gICAgc2VsZWN0UXVlcmllcy5wdXNoKGBMRVQgbWF0Y2hlZFRhZ3MgPSBMRU5HVEgoXG4gICAgICBGT1IgdCBJTiB0YWdzXG4gICAgICBGSUxURVIgdC5tYXRjaGVkID09IHRydWVcbiAgICAgIFJFVFVSTiB0XG4gICAgKWApO1xuICAgIHNlbGVjdE9iamVjdHMucHVzaCgnbWF0Y2hlZFRhZ3M6bWF0Y2hlZFRhZ3MnKTtcbiAgICBmaWx0ZXJzLnB1c2goJ21hdGNoZWRUYWdzID4gMCcpO1xuICB9XG5cbiAgc29ydEJ5LnB1c2goJ3AuYWRkZWQgREVTQycpO1xuICBzZWxlY3RPYmplY3RzLnB1c2goJ3RhZ3M6dGFncycpO1xuXG4gIGNvbnN0IGFxbFFyeTogc3RyaW5nID0gYEZPUiBwIElOIHBvc3RzXG4gICAgTEVUIHRhZ3MgPSAoXG4gICAgICBGT1IgdGFnLCBpdCBJTiAxLi4xIElOQk9VTkQgcCBpc1RhZ2dlZFxuICAgICAgTEVUIG1hdGNoZWQgPSBMRU5HVEgoJHtmb3JtYXRUYWdOYW1lc30pID4gMCAmJiBQT1NJVElPTigke2Zvcm1hdFRhZ05hbWVzfSwgdGFnLm5hbWUpXG4gICAgICBTT1JUIHRhZy5uYW1lXG4gICAgICBSRVRVUk4gTUVSR0UodGFnLCB7bWF0Y2hlZDptYXRjaGVkfSlcbiAgICApXG4gICAgJHtzZWxlY3RRdWVyaWVzLmpvaW4oJ1xcbicpfVxuICAgIEZJTFRFUiAke2ZpbHRlcnMuam9pbignICYmICcpfVxuICAgICR7bGltaXQuYXFsfVxuICAgIFNPUlQgJHtzb3J0Qnkuam9pbignLCAnKX1cbiAgICBSRVRVUk4gRElTVElOQ1QgTUVSR0UocCwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcblxuICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpIGFzIHVua25vd24gYXMgUG9zdFR5cGVbXSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICBsYWJlbDogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuXG4gICAgICByZXR1cm4gW10gYXMgUG9zdFR5cGVbXTtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRQb3N0c0J5VXNlciA9IChjb250ZXh0OiBBcGlDb250ZXh0LCB1c2VySWQ6IHN0cmluZywgb3B0aW9ucz86IFBvc3RPcHRpb25zKTogUHJvbWlzZTxQb3N0VHlwZVtdPiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2dldFBvc3RzQnlVc2VyJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZSwgZmllbGRzLCBzZXNzaW9uOiB7dXNlcklkOiBzZXNzaW9uSWR9ID0ge319ID0gY29udGV4dDtcbiAgY29uc3Qge2xpbWl0LCB0eXBlfSA9IHBhcnNlUG9zdE9wdGlvbnMob3B0aW9ucyk7XG4gIGNvbnN0IGZvcm1hdFVzZXJJZDogc3RyaW5nID0gcGFyc2VJZCh1c2VySWQpO1xuICBjb25zdCB7b2JqZWN0czogc2VsZWN0T2JqZWN0cywgcXVlcmllczogc2VsZWN0UXVlcmllc30gPSBnZXRQb3N0T3B0aW9uYWwoZmllbGRzLCBzZXNzaW9uSWQpO1xuICBjb25zdCBhcWxRcnk6IHN0cmluZyA9IGBGT1IgcCBJTiBwb3N0c1xuICAgIEZJTFRFUiBwLnVzZXJJZCA9PSBcIiR7Zm9ybWF0VXNlcklkfVwiICYmIHAudHlwZSA9PSBcIiR7dHlwZX1cIiAmJiBwLnByaXZhY3kgPT0gXCJwdWJsaWNcIiAmJiBwLnBhcmVudCA9PSBudWxsXG4gICAgJHtzZWxlY3RRdWVyaWVzLmpvaW4oJ1xcbicpfVxuICAgICR7bGltaXQuYXFsfVxuICAgIFNPUlQgcC5hZGRlZFxuICAgIFJFVFVSTiBESVNUSU5DVCBNRVJHRShwLCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFFyeSlcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkgYXMgdW5rbm93biBhcyBQb3N0VHlwZVtdKVxuICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICBsb2dFcnJvcih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIGxhYmVsOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgICB9LCBlcnJvciwgY29udGV4dCk7XG5cbiAgICAgIHJldHVybiBbXSBhcyBQb3N0VHlwZVtdO1xuICAgIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFBvc3RDb21tZW50cyA9IChjb250ZXh0OiBBcGlDb250ZXh0LCBwb3N0SWQ6IHN0cmluZywgb3B0aW9ucz86IFBvc3RPcHRpb25zKTogUHJvbWlzZTxQb3N0VHlwZVtdPiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2dldFBvc3RDb21tZW50cyc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWUsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZH0gPSB7fX0gPSBjb250ZXh0O1xuICBjb25zdCB7bGltaXQsIHR5cGV9ID0gcGFyc2VQb3N0T3B0aW9ucyhvcHRpb25zKTtcbiAgY29uc3QgZm9ybWF0SXRlbUlkOiBzdHJpbmcgPSBwYXJzZUlkKHBvc3RJZCk7XG5cbiAgLy8gR2V0IHRoZSBwYXJlbnQgcG9zdCB0byBnZXQgcmVzdHJpY3Rpb25zXG4gIGNvbnN0IGFxbFFyeTogQXFsUXVlcnkgPSBhcWxgRk9SIHAgSU4gcG9zdHNcbiAgICBGSUxURVIgcC50eXBlID09ICR7dHlwZX0gJiYgcC5fa2V5ID09ICR7Zm9ybWF0SXRlbUlkfVxuICAgIExJTUlUIDFcbiAgICBSRVRVUk4gcGA7XG5cbiAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoYXFsUXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgLnRoZW4oKHBvc3Q6IFBvc3RUeXBlKSA9PiB7XG4gICAgICBjb25zdCB7XG4gICAgICAgIF9rZXksXG4gICAgICAgIGdyb3VwSWQsXG4gICAgICAgIHByaXZhY3kgPSAnZGVmYXVsdCdcbiAgICAgIH06IFBvc3RUeXBlID0gcG9zdDtcblxuICAgICAgLy8gUXVlcnkgYmFzZWQgb24gcHJpdmFjeSBsZXZlbFxuICAgICAgbGV0IHByaXZhY3lBcWxRcnk6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgICAgaWYoZ3JvdXBJZCAmJiBwcml2YWN5ID09PSAnZ3JvdXAnKSB7XG4gICAgICAgIHByaXZhY3lBcWxRcnkgPSBgRk9SIHAgSU4gcG9zdHNcbiAgICAgICAgICBGT1IgdXNlciBJTiB1c2Vyc1xuICAgICAgICAgIEZJTFRFUiBwLnBhcmVudCA9PSBcIiR7X2tleX1cIiAmJiB1c2VyLl9rZXkgPT0gcC51c2VySWRcbiAgICAgICAgICBMRVQgcmVhY3Rpb25zID0gKFxuICAgICAgICAgICAgRk9SIHBvc3QsIHIgSU4gSU5CT1VORCBwLl9pZCByZWFjdGlvbnNcbiAgICAgICAgICAgIENPTExFQ1QgcmVhY3Rpb25OYW1lID0gci52YWx1ZSBJTlRPIHJlYWN0aW9uSXRlbXNcbiAgICAgICAgICAgIFJFVFVSTiB7bmFtZTogcmVhY3Rpb25OYW1lLCBjb3VudDogTEVOR1RIKHJlYWN0aW9uSXRlbXNbKl0uci52YWx1ZSl9XG4gICAgICAgICAgKVxuICAgICAgICAgIEZPUiBncm91cCBJTiBncm91cHNcbiAgICAgICAgICBGSUxURVIgZ3JvdXAuX2tleSA9PSBwLmdyb3VwSWRcbiAgICAgICAgICBGT1IgdSwgZSBJTiBPVVRCT1VORCBncm91cC5faWQgaGFzQ29ubmVjdGlvblxuICAgICAgICAgIEZJTFRFUiB1Ll9rZXkgPT0gXCIke3Nlc3Npb25JZH1cIlxuICAgICAgICAgIFNPUlQgcC5hZGRlZFxuICAgICAgICAgICR7bGltaXQuYXFsfVxuICAgICAgICAgIFJFVFVSTiBNRVJHRShwLCB7dXNlcjogdXNlciwgcmVhY3Rpb25zOiByZWFjdGlvbnN9KWA7XG4gICAgICB9IGVsc2UgaWYocHJpdmFjeSA9PT0gJ3B1YmxpYycpIHtcbiAgICAgICAgcHJpdmFjeUFxbFFyeSA9IGBGT1IgcCBJTiBwb3N0c1xuICAgICAgICAgIEZPUiB1c2VyIElOIHVzZXJzXG4gICAgICAgICAgRklMVEVSIHAucGFyZW50ID09IFwiJHtfa2V5fVwiICYmIHVzZXIuX2tleSA9PSBwLnVzZXJJZFxuICAgICAgICAgIExFVCByZWFjdGlvbnMgPSAoXG4gICAgICAgICAgICBGT1IgcG9zdCwgciBJTiBJTkJPVU5EIHAuX2lkIHJlYWN0aW9uc1xuICAgICAgICAgICAgQ09MTEVDVCByZWFjdGlvbk5hbWUgPSByLnZhbHVlIElOVE8gcmVhY3Rpb25JdGVtc1xuICAgICAgICAgICAgUkVUVVJOIHtuYW1lOiByZWFjdGlvbk5hbWUsIGNvdW50OiBMRU5HVEgocmVhY3Rpb25JdGVtc1sqXS5yLnZhbHVlKX1cbiAgICAgICAgICApXG4gICAgICAgICAgU09SVCBwLmFkZGVkXG4gICAgICAgICAgJHtsaW1pdC5hcWx9XG4gICAgICAgICAgUkVUVVJOIE1FUkdFKHAsIHt1c2VyOiB1c2VyLCByZWFjdGlvbnM6IHJlYWN0aW9uc30pYDtcbiAgICAgIH1cblxuICAgICAgaWYocHJpdmFjeUFxbFFyeSkge1xuICAgICAgICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShwcml2YWN5QXFsUXJ5KVxuICAgICAgICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSBhcyB1bmtub3duIGFzIFBvc3RUeXBlW10pXG4gICAgICAgICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgICAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgICAgICAgYWN0aW9uLFxuICAgICAgICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgICAgICAgbGFiZWw6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgICAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgICAgICAgICAgcmV0dXJuIFtdIGFzIFBvc3RUeXBlW107XG4gICAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBbXSBhcyBQb3N0VHlwZVtdO1xuICAgIH0pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgbGFiZWw6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgICAgcmV0dXJuIFtdIGFzIFBvc3RUeXBlW107XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgYWRkUG9zdCA9IGFzeW5jIChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAge1xuICAgIGNvbnRlbnQgPSAnJyxcbiAgICBlbmREYXRlLFxuICAgIGdyb3VwSWQgPSAnJyxcbiAgICBsb2NhdGlvbixcbiAgICBsYXRpdHVkZSxcbiAgICBsb25naXR1ZGUsXG4gICAgbmFtZSA9ICcnLFxuICAgIHBhcmVudElkID0gJycsXG4gICAgcHJpdmFjeSA9ICdwdWJsaWMnLFxuICAgIHRhZ3MgPSBbXSxcbiAgICBzdGFydERhdGUsXG4gICAgdHlwZSA9ICdkZWZhdWx0J1xuICB9OiBQb3N0SW5wdXRUeXBlXG4pOiBQcm9taXNlPFBvc3RUeXBlPiA9PiB7XG4gIGNvbnN0IGFjdGlvbjogc3RyaW5nID0gJ2FkZFBvc3QnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBzZXNzaW9uOiB7dXNlcklkOiBzZXNzaW9uSWR9ID0ge319ID0gY29udGV4dDtcbiAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgY29uc3QgcG9zdElkID0gY3JlYXRlSGFzaChgcG9zdC0ke3Nlc3Npb25JZH1gKTtcbiAgY29uc3QgaW5zZXJ0OiBQb3N0VHlwZSA9IHtcbiAgICBfaWQ6IGBwb3N0cy8ke3Bvc3RJZH1gLFxuICAgIF9rZXk6IHBvc3RJZCxcbiAgICBhZGRlZDogbm93LFxuICAgIGNvbnRlbnQ6IHBhcnNlU3RyaW5nKGNvbnRlbnQsIE1BWF9DT05URU5UX0xFTkdUSCkgfHwgJycsXG4gICAgZW5kRGF0ZTogZW5kRGF0ZSA/IHBhcnNlTnVtKGVuZERhdGUsIDEzKSA6IHVuZGVmaW5lZCxcbiAgICBncm91cElkOiBncm91cElkID8gcGFyc2VJZChncm91cElkKSA6IHVuZGVmaW5lZCxcbiAgICBsYXRpdHVkZTogbGF0aXR1ZGUgIT09IHVuZGVmaW5lZCA/IHBhcnNlTnVtKGxhdGl0dWRlKSA6IHVuZGVmaW5lZCxcbiAgICBsb2NhdGlvbjogbG9jYXRpb24gPyBwYXJzZVN0cmluZyhsb2NhdGlvbiwgMTYwKSA6IHVuZGVmaW5lZCxcbiAgICBsb25naXR1ZGU6IGxvbmdpdHVkZSAhPT0gdW5kZWZpbmVkID8gcGFyc2VOdW0obG9uZ2l0dWRlKSA6IHVuZGVmaW5lZCxcbiAgICBtb2RpZmllZDogbm93LFxuICAgIG5hbWU6IHBhcnNlU3RyaW5nKG5hbWUsIDE2MCksXG4gICAgcGFyZW50SWQ6IHBhcmVudElkID8gcGFyc2VJZChwYXJlbnRJZCkgOiB1bmRlZmluZWQsXG4gICAgcHJpdmFjeTogcGFyc2VWYXJDaGFyKHByaXZhY3ksIDE2KSxcbiAgICBzdGFydERhdGU6IHN0YXJ0RGF0ZSA/IHBhcnNlTnVtKHN0YXJ0RGF0ZSwgMTMpIDogdW5kZWZpbmVkLFxuICAgIHR5cGU6IHBhcnNlQ2hhcih0eXBlLCAzMiksXG4gICAgdXNlcklkOiBzZXNzaW9uSWRcbiAgfTtcbiAgY29uc3QgYXFsUXJ5OiBBcWxRdWVyeSA9IGFxbGBJTlNFUlQgJHtpbnNlcnR9IElOIHBvc3RzIFJFVFVSTiBORVdgO1xuXG4gIHRyeSB7XG4gICAgY29uc3Qgc2F2ZWRQb3N0OiBQb3N0VHlwZSA9IGF3YWl0IHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoYXFsUXJ5KVxuICAgICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiBsb2dFcnJvcih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIGxhYmVsOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgICB9LCBlcnJvciwgY29udGV4dCkpO1xuICAgIGNvbnN0IHtfaWQ6IHBvc3REb2NJZH0gPSBzYXZlZFBvc3Q7XG4gICAgY29uc3QgY29udGVudFRhZ05hbWVzID0gYXdhaXQgZXh0cmFjdFRhZ3MoaW5zZXJ0LmNvbnRlbnQgfHwgJycpO1xuXG4gICAgaWYodGFncy5sZW5ndGggfHwgY29udGVudFRhZ05hbWVzLmxlbmd0aCkge1xuICAgICAgY29uc3QgdXNlclRhZ3MgPSAoYXdhaXQgZ2V0VGFnc0J5TmFtZShjb250ZXh0LCB0YWdzLm1hcCgoe25hbWV9KSA9PiBuYW1lIHx8ICcnKSkpXG4gICAgICAgIC5tYXAoKHRhZykgPT4gKHsuLi50YWcsIHRhZ0J5OiBzZXNzaW9uSWR9KSk7XG4gICAgICBjb25zdCBjb250ZW50VGFncyA9IChhd2FpdCBnZXRUYWdzQnlOYW1lKGNvbnRleHQsIGNvbnRlbnRUYWdOYW1lcyB8fCBbXSkpXG4gICAgICAgIC5tYXAoKHRhZykgPT4gKHsuLi50YWcsIHRhZ0J5OiAnZXh0cmFjdCd9KSk7XG4gICAgICBjb25zdCB1cGRhdGVkVGFnczogVGFnVHlwZVtdID0gYXdhaXQgdXBkYXRlVGFnc0luSXRlbShcbiAgICAgICAgY29udGV4dCxcbiAgICAgICAge1xuICAgICAgICAgIGl0ZW1Eb2NJZDogcG9zdERvY0lkLFxuICAgICAgICAgIHRhZ3M6IFsuLi5jb250ZW50VGFncywgLi4udXNlclRhZ3NdXG4gICAgICAgIH1cbiAgICAgICk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLnNhdmVkUG9zdCxcbiAgICAgICAgdGFnczogdXBkYXRlZFRhZ3NcbiAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHNhdmVkUG9zdDtcbiAgfSBjYXRjaChlcnJvcikge1xuICAgIHRocm93IGVycm9yO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgdXBkYXRlUG9zdCA9IGFzeW5jIChjb250ZXh0OiBBcGlDb250ZXh0LCBwb3N0OiBQb3N0SW5wdXRUeXBlKTogUHJvbWlzZTxQb3N0VHlwZT4gPT4ge1xuICBjb25zdCBhY3Rpb246IHN0cmluZyA9ICd1cGRhdGVQb3N0JztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZSwgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkfSA9IHt9fSA9IGNvbnRleHQ7XG4gIGNvbnN0IG5vdzogbnVtYmVyID0gRGF0ZS5ub3coKTtcbiAgY29uc3QgcGFyc2VkUG9zdCA9IHBhcnNlUG9zdChwb3N0KTtcbiAgY29uc3Qge1xuICAgIHBvc3RJZCxcbiAgICB0YWdzID0gW11cbiAgfSA9IHBhcnNlZFBvc3Q7XG5cbiAgY29uc3QgdXBkYXRlOiBQb3N0VHlwZSA9IHtcbiAgICAuLi5wYXJzZWRQb3N0LFxuICAgIG1vZGlmaWVkOiBub3dcbiAgfTtcblxuICBpZighcG9zdElkKSB7XG4gICAgdGhyb3cgbG9nRXhjZXB0aW9uKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuSU5WQUxJRF9JRFxuICAgIH0sIGNvbnRleHQpO1xuICB9XG5cbiAgY29uc3QgaW5zZXJ0ID0ge1xuICAgIC4uLnVwZGF0ZSxcbiAgICBfa2V5OiBwb3N0SWQsXG4gICAgYWRkZWQ6IG5vdyxcbiAgICB1c2VySWQ6IHNlc3Npb25JZFxuICB9O1xuICBjb25zdCBhcWxRcnk6IEFxbFF1ZXJ5ID0gYXFsYFVQU0VSVCB7X2tleTogJHtwb3N0SWR9LCB1c2VySWQ6ICR7c2Vzc2lvbklkfX1cbiAgICBJTlNFUlQgJHtpbnNlcnR9XG4gICAgVVBEQVRFICR7dXBkYXRlfVxuICAgIElOIHBvc3RzIFJFVFVSTiBORVdgO1xuXG4gIHRyeSB7XG4gICAgY29uc3QgdXBkYXRlZFBvc3Q6IFBvc3RUeXBlID0gYXdhaXQgdXNlRGIoZGF0YWJhc2VOYW1lKVxuICAgICAgLnF1ZXJ5KGFxbFFyeSlcbiAgICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4gbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIHt9KSk7XG4gICAgY29uc3Qge19pZDogdXBkYXRlZFBvc3RJZH0gPSB1cGRhdGVkUG9zdDtcbiAgICBjb25zdCBjb250ZW50VGFnTmFtZXMgPSBhd2FpdCBleHRyYWN0VGFncyhpbnNlcnQuY29udGVudCB8fCAnJyk7XG5cbiAgICBpZih0YWdzPy5sZW5ndGggfHwgY29udGVudFRhZ05hbWVzPy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHVzZXJUYWdzID0gdGFncz8ubGVuZ3RoID8gKGF3YWl0IGdldFRhZ3NCeU5hbWUoY29udGV4dCwgdGFncy5tYXAoKHtuYW1lfSkgPT4gbmFtZSB8fCAnJykpKVxuICAgICAgICAubWFwKCh0YWcpID0+ICh7Li4udGFnLCB0YWdCeTogc2Vzc2lvbklkfSkpIDogW107XG4gICAgICBjb25zdCBjb250ZW50VGFncyA9IGNvbnRlbnRUYWdOYW1lcz8ubGVuZ3RoID8gKGF3YWl0IGdldFRhZ3NCeU5hbWUoY29udGV4dCwgY29udGVudFRhZ05hbWVzIHx8IFtdKSlcbiAgICAgICAgLm1hcCgodGFnKSA9PiAoey4uLnRhZywgdGFnQnk6ICdleHRyYWN0J30pKSA6IFtdO1xuICAgICAgY29uc3QgdXBkYXRlZFRhZ3M6IFRhZ1R5cGVbXSA9IGF3YWl0IHVwZGF0ZVRhZ3NJbkl0ZW0oXG4gICAgICAgIGNvbnRleHQsXG4gICAgICAgIHtcbiAgICAgICAgICBpdGVtRG9jSWQ6IHVwZGF0ZWRQb3N0SWQsXG4gICAgICAgICAgdGFnczogWy4uLmNvbnRlbnRUYWdzLCAuLi51c2VyVGFnc11cbiAgICAgICAgfVxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4udXBkYXRlZFBvc3QsXG4gICAgICAgIHRhZ3M6IHVwZGF0ZWRUYWdzXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiB1cGRhdGVkUG9zdDtcbiAgfSBjYXRjaChlcnJvcikge1xuICAgIHRocm93IGVycm9yO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgZGVsZXRlUG9zdCA9IGFzeW5jIChjb250ZXh0OiBBcGlDb250ZXh0LCBwb3N0RG9jSWQ6IHN0cmluZyk6IFByb21pc2U8UG9zdFR5cGU+ID0+IHtcbiAgY29uc3QgYWN0aW9uOiBzdHJpbmcgPSAnZGVsZXRlUG9zdCc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWUsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZH0gPSB7fX0gPSBjb250ZXh0O1xuICBjb25zdCBmb3JtYXRQb3N0SWQ6IHN0cmluZyA9IHBhcnNlQXJhbmdvSWQocG9zdERvY0lkKTtcblxuICBpZighZm9ybWF0UG9zdElkKSB7XG4gICAgdGhyb3cgbG9nRXhjZXB0aW9uKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuSU5WQUxJRF9JRFxuICAgIH0sIGNvbnRleHQpO1xuICB9XG5cbiAgY29uc3QgZWRnZUFxbFFyeTogQXFsUXVlcnkgPSBhcWxgRk9SIHQgSU4gaXNUYWdnZWRcbiAgRklMVEVSIHQuX3RvID09ICR7Zm9ybWF0UG9zdElkfVxuICBSRU1PVkUgdCBJTiBpc1RhZ2dlZGA7XG5cbiAgYXdhaXQgdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShlZGdlQXFsUXJ5KVxuICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9KTtcblxuICBjb25zdCBmaWxlQXFsUXJ5OiBBcWxRdWVyeSA9IGFxbGBGT1IgZiBJTiBoYXNGaWxlXG4gICAgRklMVEVSIGYuX3RvID09ICR7Zm9ybWF0UG9zdElkfVxuICAgIFJFTU9WRSBmIElOIGhhc0ZpbGVgO1xuXG4gIGF3YWl0IHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoZmlsZUFxbFFyeSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSk7XG5cbiAgY29uc3QgYXFsUXJ5ID0gYXFsYEZPUiBwIElOIHBvc3RzXG4gICAgICBGSUxURVIgcC5faWQgPT0gJHtmb3JtYXRQb3N0SWR9ICYmIHAudXNlcklkID09ICR7c2Vzc2lvbklkfVxuICAgICAgTElNSVQgMVxuICAgICAgUkVNT1ZFIHAgSU4gcG9zdHNcbiAgICAgIFJFVFVSTiBPTERgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFFyeSlcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKVxuICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVQb3N0RWRnZSA9IChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgcG9zdERvY0lkOiBzdHJpbmcsXG4gIGl0ZW1Eb2NJZDogc3RyaW5nLFxuICBlZGdlVHlwZTogc3RyaW5nID0gJ2lzUG9zdGVkJyxcbiAgcHJvcHMgPSB7fVxuKTogUHJvbWlzZTxGaWxlVHlwZT4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnY3JlYXRlUG9zdEVkZ2UnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lfSA9IGNvbnRleHQ7XG4gIGNvbnN0IGVkZ2VDb2xsZWN0aW9uOiBFZGdlQ29sbGVjdGlvbiA9IHVzZURiKGRhdGFiYXNlTmFtZSkuY29sbGVjdGlvbihlZGdlVHlwZSk7XG4gIGNvbnN0IGZvcm1hdFBvc3RJZDogc3RyaW5nID0gcGFyc2VBcmFuZ29JZChwb3N0RG9jSWQpO1xuICBjb25zdCBmb3JtYXREb2NJZDogc3RyaW5nID0gcGFyc2VBcmFuZ29JZChpdGVtRG9jSWQpO1xuXG4gIGlmKCFmb3JtYXREb2NJZCB8fCAhZm9ybWF0UG9zdElkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKEVycm9yVHlwZXMuSU5WQUxJRF9JRCk7XG4gIH1cblxuICBjb25zdCBlZGdlSWQ6IHN0cmluZyA9IGNyZWF0ZUhhc2goYHBvc3RFZGdlLSR7Zm9ybWF0UG9zdElkfS0ke2Zvcm1hdERvY0lkfWApO1xuICBjb25zdCBlZGdlID0ge1xuICAgIF9mcm9tOiBmb3JtYXRQb3N0SWQsXG4gICAgX2tleTogZWRnZUlkLFxuICAgIF90bzogZm9ybWF0RG9jSWQsXG4gICAgYWRkZWQ6IERhdGUubm93KCksXG4gICAgLi4ucHJvcHNcbiAgfTtcblxuICByZXR1cm4gZWRnZUNvbGxlY3Rpb24uc2F2ZShlZGdlLCB7cmV0dXJuTmV3OiB0cnVlfSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgdGhyb3cgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICAgIH0pO1xufTtcbiJdLCJuYW1lcyI6WyJwYXJzZU51bSIsImNyZWF0ZUhhc2giLCJwYXJzZUFyYW5nb0lkIiwicGFyc2VDaGFyIiwicGFyc2VJZCIsInBhcnNlU3RyaW5nIiwicGFyc2VWYXJDaGFyIiwiYXFsIiwicGFyc2VQb3N0IiwiRXJyb3JUeXBlcyIsImxvZ0Vycm9yIiwibG9nRXhjZXB0aW9uIiwiZ2V0TGltaXQiLCJ1c2VEYiIsImV4dHJhY3RUYWdzIiwiZ2V0VGFnc0J5TmFtZSIsInVwZGF0ZVRhZ3NJbkl0ZW0iLCJNQVhfQ09OVEVOVF9MRU5HVEgiLCJldmVudENhdGVnb3J5IiwicGFyc2VQb3N0T3B0aW9ucyIsIm9wdGlvbnMiLCJmcm9tIiwibGF0aXR1ZGUiLCJsb25naXR1ZGUiLCJ0byIsInR5cGUiLCJsaW1pdCIsImdldFBvc3RPcHRpb25hbCIsImZpZWxkcyIsInNlc3Npb25JZCIsInJlZHVjZSIsInNlbGVjdHMiLCJmaWVsZCIsInF1ZXJpZXMiLCJwdXNoIiwib2JqZWN0cyIsImdldFBvc3QiLCJjb250ZXh0IiwicG9zdElkIiwiYWN0aW9uIiwiZGF0YWJhc2VOYW1lIiwic2Vzc2lvbiIsInVzZXJJZCIsImZvcm1hdEl0ZW1JZCIsImRhdGFiYXNlIiwic2VsZWN0T2JqZWN0cyIsInNlbGVjdFF1ZXJpZXMiLCJhcWxRcnkiLCJxdWVyeSIsInRoZW4iLCJjdXJzb3IiLCJuZXh0IiwicG9zdCIsIl9pZCIsInBvc3REb2NJZCIsImdyb3VwSWQiLCJwcml2YWN5IiwicHJpdmFjeUFxbFFyeSIsImpvaW4iLCJjYXRjaCIsImVycm9yIiwiY2F0ZWdvcnkiLCJsYWJlbCIsIkRBVEFCQVNFX0VSUk9SIiwiZ2V0UG9zdHNCeUFyZWEiLCJmb3JtYXRMYXRpdHVkZSIsImZvcm1hdExvbmdpdHVkZSIsImFsbCIsImdldFBvc3RzQnlMYXRlc3QiLCJnZXRQb3N0c0J5UmVhY3Rpb25zIiwicmVhY3Rpb25zIiwiZm9ybWF0U2Vzc2lvbklkIiwiZm9ybWF0UmVhY3Rpb25zIiwiSlNPTiIsInN0cmluZ2lmeSIsIm1hcCIsInJlYWN0aW9uIiwidG9Mb3dlckNhc2UiLCJzb3J0QnkiLCJmaWx0ZXJzIiwibGVuZ3RoIiwiZ2V0UG9zdHNCeVRhZ3MiLCJ0YWdzIiwiZm9ybWF0VGFnTmFtZXMiLCJ0YWciLCJnZXRQb3N0c0J5VXNlciIsImZvcm1hdFVzZXJJZCIsImdldFBvc3RDb21tZW50cyIsIl9rZXkiLCJhZGRQb3N0IiwiY29udGVudCIsImVuZERhdGUiLCJsb2NhdGlvbiIsIm5hbWUiLCJwYXJlbnRJZCIsInN0YXJ0RGF0ZSIsIm5vdyIsIkRhdGUiLCJpbnNlcnQiLCJhZGRlZCIsInVuZGVmaW5lZCIsIm1vZGlmaWVkIiwic2F2ZWRQb3N0IiwiY29udGVudFRhZ05hbWVzIiwidXNlclRhZ3MiLCJ0YWdCeSIsImNvbnRlbnRUYWdzIiwidXBkYXRlZFRhZ3MiLCJpdGVtRG9jSWQiLCJ1cGRhdGVQb3N0IiwicGFyc2VkUG9zdCIsInVwZGF0ZSIsInZhbHVlIiwiSU5WQUxJRF9JRCIsInVwZGF0ZWRQb3N0IiwidXBkYXRlZFBvc3RJZCIsImRlbGV0ZVBvc3QiLCJmb3JtYXRQb3N0SWQiLCJlZGdlQXFsUXJ5IiwiZmlsZUFxbFFyeSIsImNyZWF0ZVBvc3RFZGdlIiwiZWRnZVR5cGUiLCJwcm9wcyIsImVkZ2VDb2xsZWN0aW9uIiwiY29sbGVjdGlvbiIsImZvcm1hdERvY0lkIiwiRXJyb3IiLCJlZGdlSWQiLCJlZGdlIiwiX2Zyb20iLCJfdG8iLCJzYXZlIiwicmV0dXJuTmV3Il0sIm1hcHBpbmdzIjoiQUFBQTs7O0NBR0MsR0FDRCxTQUFTQSxRQUFRLFFBQVEsK0JBQStCO0FBQ3hELFNBQ0lDLFVBQVUsRUFBRUMsYUFBYSxFQUFFQyxTQUFTLEVBQUVDLE9BQU8sRUFBRUMsV0FBVyxFQUFFQyxZQUFZLFFBQ3JFLCtCQUErQjtBQUN0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