@nlabs/reaktor 1.4.1 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (419) hide show
  1. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/apps.d.ts +1 -2
  2. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/connections.d.ts +0 -1
  3. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/content.d.ts +0 -1
  4. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/conversations.d.ts +0 -1
  5. package/lib/Users/nitrog7/Development/reaktor/src/actions/crm.d.ts +28 -0
  6. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/crud.d.ts +0 -1
  7. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/dynamodb.d.ts +0 -1
  8. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/email.d.ts +0 -1
  9. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/files.d.ts +0 -1
  10. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/groups.d.ts +0 -1
  11. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/images.d.ts +0 -1
  12. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/index.d.ts +2 -1
  13. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/ios.d.ts +0 -1
  14. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/locations.d.ts +0 -1
  15. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/messages.d.ts +0 -1
  16. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/notifications.d.ts +0 -1
  17. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/payments.d.ts +0 -1
  18. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/personas.d.ts +1 -2
  19. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/posts.d.ts +0 -1
  20. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/query.d.ts +0 -1
  21. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/reactions.d.ts +0 -1
  22. package/lib/Users/nitrog7/Development/reaktor/src/actions/rum.d.ts +3 -0
  23. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/s3.d.ts +0 -1
  24. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/search.d.ts +0 -1
  25. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/sms.d.ts +0 -1
  26. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/statistics.d.ts +0 -1
  27. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/subscriptions.d.ts +0 -1
  28. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/tags.d.ts +0 -1
  29. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/users.d.ts +2 -3
  30. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/videos.d.ts +0 -1
  31. package/lib/{actions → Users/nitrog7/Development/reaktor/src/actions}/websockets.d.ts +0 -1
  32. package/lib/{adapters → Users/nitrog7/Development/reaktor/src/adapters}/arangoAdapter.d.ts +0 -1
  33. package/lib/{adapters → Users/nitrog7/Development/reaktor/src/adapters}/contentAdapter.d.ts +0 -1
  34. package/lib/{adapters → Users/nitrog7/Development/reaktor/src/adapters}/fileAdapter.d.ts +0 -1
  35. package/lib/{adapters → Users/nitrog7/Development/reaktor/src/adapters}/imageAdapter.d.ts +0 -1
  36. package/lib/{adapters → Users/nitrog7/Development/reaktor/src/adapters}/index.d.ts +0 -1
  37. package/lib/{adapters → Users/nitrog7/Development/reaktor/src/adapters}/messageAdapter.d.ts +0 -1
  38. package/lib/{adapters → Users/nitrog7/Development/reaktor/src/adapters}/postAdapter.d.ts +0 -1
  39. package/lib/{adapters → Users/nitrog7/Development/reaktor/src/adapters}/reaktorAdapter.d.ts +0 -1
  40. package/lib/{adapters → Users/nitrog7/Development/reaktor/src/adapters}/tagAdapter.d.ts +0 -1
  41. package/lib/{adapters → Users/nitrog7/Development/reaktor/src/adapters}/userAdapter.d.ts +0 -1
  42. package/lib/{config.d.ts → Users/nitrog7/Development/reaktor/src/config.d.ts} +0 -1
  43. package/lib/Users/nitrog7/Development/reaktor/src/constants/collections.d.ts +86 -0
  44. package/lib/{handlers → Users/nitrog7/Development/reaktor/src/handlers}/graphqlHandler.d.ts +0 -1
  45. package/lib/{index.d.ts → Users/nitrog7/Development/reaktor/src/index.d.ts} +0 -1
  46. package/lib/{lambdas → Users/nitrog7/Development/reaktor/src/lambdas}/actions/websockets.d.ts +0 -1
  47. package/lib/{lambdas → Users/nitrog7/Development/reaktor/src/lambdas}/authorizer.d.ts +0 -1
  48. package/lib/{lambdas → Users/nitrog7/Development/reaktor/src/lambdas}/connection.d.ts +4 -5
  49. package/lib/{lambdas → Users/nitrog7/Development/reaktor/src/lambdas}/utils/message.d.ts +0 -1
  50. package/lib/{lambdas → Users/nitrog7/Development/reaktor/src/lambdas}/utils/websocket.d.ts +0 -1
  51. package/lib/{mocks → Users/nitrog7/Development/reaktor/src/mocks}/conversation.d.ts +1 -2
  52. package/lib/{mocks → Users/nitrog7/Development/reaktor/src/mocks}/file.d.ts +0 -1
  53. package/lib/{mocks → Users/nitrog7/Development/reaktor/src/mocks}/group.d.ts +0 -1
  54. package/lib/{mocks → Users/nitrog7/Development/reaktor/src/mocks}/image.d.ts +0 -1
  55. package/lib/{mocks → Users/nitrog7/Development/reaktor/src/mocks}/post.d.ts +1 -2
  56. package/lib/{mocks → Users/nitrog7/Development/reaktor/src/mocks}/tag.d.ts +0 -1
  57. package/lib/{mocks → Users/nitrog7/Development/reaktor/src/mocks}/user.d.ts +0 -1
  58. package/lib/{mocks → Users/nitrog7/Development/reaktor/src/mocks}/video.d.ts +0 -1
  59. package/lib/{mutations → Users/nitrog7/Development/reaktor/src/mutations}/content/content.d.ts +0 -1
  60. package/lib/Users/nitrog7/Development/reaktor/src/mutations/crm/crm.d.ts +1 -0
  61. package/lib/{mutations → Users/nitrog7/Development/reaktor/src/mutations}/events/events.d.ts +0 -1
  62. package/lib/{mutations → Users/nitrog7/Development/reaktor/src/mutations}/groups/groups.d.ts +0 -1
  63. package/lib/{mutations → Users/nitrog7/Development/reaktor/src/mutations}/images/images.d.ts +0 -1
  64. package/lib/{mutations → Users/nitrog7/Development/reaktor/src/mutations}/index.d.ts +3 -2
  65. package/lib/{mutations → Users/nitrog7/Development/reaktor/src/mutations}/locations/locations.d.ts +0 -1
  66. package/lib/{mutations → Users/nitrog7/Development/reaktor/src/mutations}/messages/messages.d.ts +0 -1
  67. package/lib/{mutations → Users/nitrog7/Development/reaktor/src/mutations}/personas/personas.d.ts +0 -1
  68. package/lib/{mutations → Users/nitrog7/Development/reaktor/src/mutations}/posts/posts.d.ts +0 -1
  69. package/lib/{mutations → Users/nitrog7/Development/reaktor/src/mutations}/reactions/reactions.d.ts +0 -1
  70. package/lib/Users/nitrog7/Development/reaktor/src/mutations/rum/rum.d.ts +1 -0
  71. package/lib/{mutations → Users/nitrog7/Development/reaktor/src/mutations}/statistics/statistics.d.ts +0 -1
  72. package/lib/{mutations → Users/nitrog7/Development/reaktor/src/mutations}/subscriptions/subscriptions.d.ts +0 -1
  73. package/lib/{mutations → Users/nitrog7/Development/reaktor/src/mutations}/tags/tags.d.ts +0 -1
  74. package/lib/{mutations → Users/nitrog7/Development/reaktor/src/mutations}/users/users.d.ts +0 -1
  75. package/lib/{mutations → Users/nitrog7/Development/reaktor/src/mutations}/videos/videos.d.ts +0 -1
  76. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/app.d.ts +0 -1
  77. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/bankAccount.d.ts +0 -1
  78. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/connection.d.ts +0 -1
  79. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/content.d.ts +0 -1
  80. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/conversation.d.ts +0 -1
  81. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/creditCard.d.ts +0 -1
  82. package/lib/Users/nitrog7/Development/reaktor/src/objectTypes/crm.d.ts +12 -0
  83. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/document.d.ts +0 -1
  84. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/error.d.ts +0 -1
  85. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/event.d.ts +0 -1
  86. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/external.d.ts +0 -1
  87. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/file.d.ts +0 -1
  88. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/filter.d.ts +0 -1
  89. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/group.d.ts +0 -1
  90. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/iapSubscription.d.ts +0 -1
  91. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/image.d.ts +0 -1
  92. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/index.d.ts +2 -1
  93. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/location.d.ts +0 -1
  94. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/message.d.ts +0 -1
  95. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/passcode.d.ts +0 -1
  96. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/persona.d.ts +0 -1
  97. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/plan.d.ts +0 -1
  98. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/post.d.ts +0 -1
  99. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/query.d.ts +0 -1
  100. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/reaction.d.ts +0 -1
  101. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/relation.d.ts +0 -1
  102. package/lib/Users/nitrog7/Development/reaktor/src/objectTypes/rum.d.ts +3 -0
  103. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/search.d.ts +0 -1
  104. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/statistics.d.ts +0 -1
  105. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/subscription.d.ts +0 -1
  106. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/tag.d.ts +0 -1
  107. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/user.d.ts +0 -1
  108. package/lib/{objectTypes → Users/nitrog7/Development/reaktor/src/objectTypes}/video.d.ts +0 -1
  109. package/lib/{queries → Users/nitrog7/Development/reaktor/src/queries}/content/content.d.ts +0 -1
  110. package/lib/Users/nitrog7/Development/reaktor/src/queries/crm/crm.d.ts +1 -0
  111. package/lib/{queries → Users/nitrog7/Development/reaktor/src/queries}/events/events.d.ts +0 -1
  112. package/lib/{queries → Users/nitrog7/Development/reaktor/src/queries}/groups/groups.d.ts +0 -1
  113. package/lib/{queries → Users/nitrog7/Development/reaktor/src/queries}/images/images.d.ts +0 -1
  114. package/lib/{queries → Users/nitrog7/Development/reaktor/src/queries}/index.d.ts +2 -2
  115. package/lib/{queries → Users/nitrog7/Development/reaktor/src/queries}/locations/locations.d.ts +0 -1
  116. package/lib/{queries → Users/nitrog7/Development/reaktor/src/queries}/messages/messages.d.ts +0 -1
  117. package/lib/{queries → Users/nitrog7/Development/reaktor/src/queries}/personas/personas.d.ts +0 -1
  118. package/lib/{queries → Users/nitrog7/Development/reaktor/src/queries}/posts/posts.d.ts +0 -1
  119. package/lib/{queries → Users/nitrog7/Development/reaktor/src/queries}/query/query.d.ts +0 -1
  120. package/lib/{queries → Users/nitrog7/Development/reaktor/src/queries}/reactions/reactions.d.ts +0 -1
  121. package/lib/{queries → Users/nitrog7/Development/reaktor/src/queries}/statistics/statistics.d.ts +0 -1
  122. package/lib/{queries → Users/nitrog7/Development/reaktor/src/queries}/subscriptions/subscriptions.d.ts +0 -1
  123. package/lib/{queries → Users/nitrog7/Development/reaktor/src/queries}/tags/tags.d.ts +0 -1
  124. package/lib/{queries → Users/nitrog7/Development/reaktor/src/queries}/users/users.d.ts +0 -1
  125. package/lib/{queries → Users/nitrog7/Development/reaktor/src/queries}/videos/videos.d.ts +0 -1
  126. package/lib/Users/nitrog7/Development/reaktor/src/templates/email/layout.d.ts +2 -0
  127. package/lib/Users/nitrog7/Development/reaktor/src/templates/email/passwordForgot.d.ts +2 -0
  128. package/lib/Users/nitrog7/Development/reaktor/src/templates/email/passwordRecovery.d.ts +2 -0
  129. package/lib/Users/nitrog7/Development/reaktor/src/templates/email/verifyEmail.d.ts +2 -0
  130. package/lib/Users/nitrog7/Development/reaktor/src/templates/email/welcome.d.ts +2 -0
  131. package/lib/Users/nitrog7/Development/reaktor/src/templates/sms/passwordForgot.d.ts +2 -0
  132. package/lib/Users/nitrog7/Development/reaktor/src/templates/sms/passwordRecovery.d.ts +2 -0
  133. package/lib/Users/nitrog7/Development/reaktor/src/templates/sms/verifyEmail.d.ts +2 -0
  134. package/lib/Users/nitrog7/Development/reaktor/src/templates/sms/verifyPhone.d.ts +2 -0
  135. package/lib/Users/nitrog7/Development/reaktor/src/templates/sms/welcome.d.ts +2 -0
  136. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/apps.types.d.ts +0 -1
  137. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/arangodb.types.d.ts +1 -2
  138. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/auth.types.d.ts +0 -1
  139. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/connections.types.d.ts +2 -3
  140. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/content.types.d.ts +0 -1
  141. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/conversations.types.d.ts +0 -1
  142. package/lib/Users/nitrog7/Development/reaktor/src/types/crm.types.d.ts +89 -0
  143. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/email.types.d.ts +0 -1
  144. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/error.types.d.ts +0 -1
  145. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/files.types.d.ts +0 -1
  146. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/google.types.d.ts +0 -1
  147. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/groups.types.d.ts +0 -1
  148. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/images.types.d.ts +0 -1
  149. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/index.d.ts +2 -1
  150. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/locations.types.d.ts +0 -1
  151. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/messages.types.d.ts +0 -1
  152. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/notifications.types.d.ts +0 -1
  153. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/payments.types.d.ts +0 -1
  154. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/personas.types.d.ts +0 -1
  155. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/posts.types.d.ts +0 -1
  156. package/lib/Users/nitrog7/Development/reaktor/src/types/rum.types.d.ts +23 -0
  157. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/statistics.types.d.ts +0 -1
  158. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/tags.types.d.ts +0 -1
  159. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/users.types.d.ts +20 -1
  160. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/videos.types.d.ts +0 -1
  161. package/lib/{types → Users/nitrog7/Development/reaktor/src/types}/websockets.types.d.ts +0 -1
  162. package/lib/{upload.d.ts → Users/nitrog7/Development/reaktor/src/upload.d.ts} +0 -1
  163. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/adapterUtils.d.ts +0 -1
  164. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/analyticsUtils.d.ts +0 -1
  165. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/aqlHelpers.d.ts +4 -1
  166. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/arangodbUtils.d.ts +0 -1
  167. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/authUtils.d.ts +0 -1
  168. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/awsUtils.d.ts +0 -1
  169. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/collectionRegistry.d.ts +0 -1
  170. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/contextUtils.d.ts +0 -1
  171. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/dbI18n.d.ts +0 -1
  172. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/dbI18n.example.d.ts +0 -1
  173. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/googleTranslate.d.ts +0 -1
  174. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/graphqlUtils.d.ts +1 -2
  175. package/lib/Users/nitrog7/Development/reaktor/src/utils/imageUtils.d.ts +1 -0
  176. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/index.d.ts +0 -1
  177. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/languageDetection.d.ts +0 -1
  178. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/localeUtils.d.ts +0 -1
  179. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/localeUtils.example.d.ts +1 -1
  180. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/middlewareUtils.d.ts +0 -1
  181. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/queryBuilder.d.ts +0 -1
  182. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/schemaUtils.d.ts +0 -1
  183. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/sessionUtils.d.ts +0 -1
  184. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/stripeUtils.d.ts +1 -2
  185. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/templateUtils.d.ts +0 -1
  186. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/testUtils.d.ts +0 -1
  187. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/translationQueue.d.ts +0 -1
  188. package/lib/{utils → Users/nitrog7/Development/reaktor/src/utils}/translationQueue.example.d.ts +0 -1
  189. package/lib/{videoProcessing.d.ts → Users/nitrog7/Development/reaktor/src/videoProcessing.d.ts} +2 -3
  190. package/lib/actions/apps.js +2 -2
  191. package/lib/actions/content.js +1 -2
  192. package/lib/actions/crm.js +498 -0
  193. package/lib/actions/crud.js +1 -1
  194. package/lib/actions/groups.js +2 -2
  195. package/lib/actions/images.js +3 -10
  196. package/lib/actions/index.js +3 -1
  197. package/lib/actions/locations.js +1 -2
  198. package/lib/actions/posts.js +3 -3
  199. package/lib/actions/rum.js +66 -0
  200. package/lib/actions/search.js +30 -53
  201. package/lib/actions/users.js +124 -160
  202. package/lib/adapters/messageAdapter.js +7 -5
  203. package/lib/adapters/userAdapter.js +42 -2
  204. package/lib/constants/collections.js +17 -1
  205. package/lib/mocks/image.js +3 -3
  206. package/lib/mocks/video.js +3 -3
  207. package/lib/mutations/crm/crm.js +67 -0
  208. package/lib/mutations/index.js +12 -2
  209. package/lib/mutations/rum/rum.js +20 -0
  210. package/lib/objectTypes/crm.js +188 -0
  211. package/lib/objectTypes/index.js +3 -1
  212. package/lib/objectTypes/persona.js +3 -2
  213. package/lib/objectTypes/rum.js +33 -0
  214. package/lib/objectTypes/user.js +83 -2
  215. package/lib/queries/crm/crm.js +77 -0
  216. package/lib/queries/index.js +7 -2
  217. package/lib/queries/videos/videos.js +1 -1
  218. package/lib/types/apps.types.js +1 -1
  219. package/lib/types/arangodb.types.js +1 -1
  220. package/lib/types/crm.types.js +6 -0
  221. package/lib/types/index.js +3 -1
  222. package/lib/types/rum.types.js +6 -0
  223. package/lib/types/users.types.js +1 -1
  224. package/lib/utils/aqlHelpers.js +13 -2
  225. package/lib/utils/collectionRegistry.js +18 -1
  226. package/lib/utils/imageUtils.js +6 -0
  227. package/lib/utils/localeUtils.example.js +3 -4
  228. package/lib/utils/stripeUtils.js +2 -2
  229. package/package.json +53 -39
  230. package/lib/actions/apps.d.ts.map +0 -1
  231. package/lib/actions/connections.d.ts.map +0 -1
  232. package/lib/actions/content.d.ts.map +0 -1
  233. package/lib/actions/conversations.d.ts.map +0 -1
  234. package/lib/actions/crud.d.ts.map +0 -1
  235. package/lib/actions/dynamodb.d.ts.map +0 -1
  236. package/lib/actions/email.d.ts.map +0 -1
  237. package/lib/actions/files.d.ts.map +0 -1
  238. package/lib/actions/groups.d.ts.map +0 -1
  239. package/lib/actions/images.d.ts.map +0 -1
  240. package/lib/actions/index.d.ts.map +0 -1
  241. package/lib/actions/ios.d.ts.map +0 -1
  242. package/lib/actions/locations.d.ts.map +0 -1
  243. package/lib/actions/messages.d.ts.map +0 -1
  244. package/lib/actions/notifications.d.ts.map +0 -1
  245. package/lib/actions/payments.d.ts.map +0 -1
  246. package/lib/actions/personas.d.ts.map +0 -1
  247. package/lib/actions/posts.d.ts.map +0 -1
  248. package/lib/actions/query.d.ts.map +0 -1
  249. package/lib/actions/reactions.d.ts.map +0 -1
  250. package/lib/actions/s3.d.ts.map +0 -1
  251. package/lib/actions/search.d.ts.map +0 -1
  252. package/lib/actions/sms.d.ts.map +0 -1
  253. package/lib/actions/statistics.d.ts.map +0 -1
  254. package/lib/actions/subscriptions.d.ts.map +0 -1
  255. package/lib/actions/tags.d.ts.map +0 -1
  256. package/lib/actions/users.d.ts.map +0 -1
  257. package/lib/actions/videos.d.ts.map +0 -1
  258. package/lib/actions/websockets.d.ts.map +0 -1
  259. package/lib/adapters/arangoAdapter.d.ts.map +0 -1
  260. package/lib/adapters/contentAdapter.d.ts.map +0 -1
  261. package/lib/adapters/fileAdapter.d.ts.map +0 -1
  262. package/lib/adapters/imageAdapter.d.ts.map +0 -1
  263. package/lib/adapters/index.d.ts.map +0 -1
  264. package/lib/adapters/messageAdapter.d.ts.map +0 -1
  265. package/lib/adapters/postAdapter.d.ts.map +0 -1
  266. package/lib/adapters/reaktorAdapter.d.ts.map +0 -1
  267. package/lib/adapters/tagAdapter.d.ts.map +0 -1
  268. package/lib/adapters/userAdapter.d.ts.map +0 -1
  269. package/lib/config.d.ts.map +0 -1
  270. package/lib/constants/collections.d.ts +0 -71
  271. package/lib/constants/collections.d.ts.map +0 -1
  272. package/lib/handlers/graphqlHandler.d.ts.map +0 -1
  273. package/lib/index.d.ts.map +0 -1
  274. package/lib/lambdas/actions/websockets.d.ts.map +0 -1
  275. package/lib/lambdas/authorizer.d.ts.map +0 -1
  276. package/lib/lambdas/connection.d.ts.map +0 -1
  277. package/lib/lambdas/utils/message.d.ts.map +0 -1
  278. package/lib/lambdas/utils/websocket.d.ts.map +0 -1
  279. package/lib/mocks/conversation.d.ts.map +0 -1
  280. package/lib/mocks/file.d.ts.map +0 -1
  281. package/lib/mocks/group.d.ts.map +0 -1
  282. package/lib/mocks/image.d.ts.map +0 -1
  283. package/lib/mocks/post.d.ts.map +0 -1
  284. package/lib/mocks/tag.d.ts.map +0 -1
  285. package/lib/mocks/user.d.ts.map +0 -1
  286. package/lib/mocks/video.d.ts.map +0 -1
  287. package/lib/mutations/content/content.d.ts.map +0 -1
  288. package/lib/mutations/events/events.d.ts.map +0 -1
  289. package/lib/mutations/groups/groups.d.ts.map +0 -1
  290. package/lib/mutations/images/images.d.ts.map +0 -1
  291. package/lib/mutations/index.d.ts.map +0 -1
  292. package/lib/mutations/locations/locations.d.ts.map +0 -1
  293. package/lib/mutations/messages/messages.d.ts.map +0 -1
  294. package/lib/mutations/personas/personas.d.ts.map +0 -1
  295. package/lib/mutations/posts/posts.d.ts.map +0 -1
  296. package/lib/mutations/reactions/reactions.d.ts.map +0 -1
  297. package/lib/mutations/statistics/statistics.d.ts.map +0 -1
  298. package/lib/mutations/subscriptions/subscriptions.d.ts.map +0 -1
  299. package/lib/mutations/tags/tags.d.ts.map +0 -1
  300. package/lib/mutations/users/users.d.ts.map +0 -1
  301. package/lib/mutations/videos/videos.d.ts.map +0 -1
  302. package/lib/objectTypes/app.d.ts.map +0 -1
  303. package/lib/objectTypes/bankAccount.d.ts.map +0 -1
  304. package/lib/objectTypes/connection.d.ts.map +0 -1
  305. package/lib/objectTypes/content.d.ts.map +0 -1
  306. package/lib/objectTypes/conversation.d.ts.map +0 -1
  307. package/lib/objectTypes/creditCard.d.ts.map +0 -1
  308. package/lib/objectTypes/document.d.ts.map +0 -1
  309. package/lib/objectTypes/error.d.ts.map +0 -1
  310. package/lib/objectTypes/event.d.ts.map +0 -1
  311. package/lib/objectTypes/external.d.ts.map +0 -1
  312. package/lib/objectTypes/file.d.ts.map +0 -1
  313. package/lib/objectTypes/filter.d.ts.map +0 -1
  314. package/lib/objectTypes/group.d.ts.map +0 -1
  315. package/lib/objectTypes/iapSubscription.d.ts.map +0 -1
  316. package/lib/objectTypes/image.d.ts.map +0 -1
  317. package/lib/objectTypes/index.d.ts.map +0 -1
  318. package/lib/objectTypes/location.d.ts.map +0 -1
  319. package/lib/objectTypes/message.d.ts.map +0 -1
  320. package/lib/objectTypes/passcode.d.ts.map +0 -1
  321. package/lib/objectTypes/persona.d.ts.map +0 -1
  322. package/lib/objectTypes/plan.d.ts.map +0 -1
  323. package/lib/objectTypes/post.d.ts.map +0 -1
  324. package/lib/objectTypes/query.d.ts.map +0 -1
  325. package/lib/objectTypes/reaction.d.ts.map +0 -1
  326. package/lib/objectTypes/relation.d.ts.map +0 -1
  327. package/lib/objectTypes/search.d.ts.map +0 -1
  328. package/lib/objectTypes/statistics.d.ts.map +0 -1
  329. package/lib/objectTypes/subscription.d.ts.map +0 -1
  330. package/lib/objectTypes/tag.d.ts.map +0 -1
  331. package/lib/objectTypes/user.d.ts.map +0 -1
  332. package/lib/objectTypes/video.d.ts.map +0 -1
  333. package/lib/queries/content/content.d.ts.map +0 -1
  334. package/lib/queries/events/events.d.ts.map +0 -1
  335. package/lib/queries/groups/groups.d.ts.map +0 -1
  336. package/lib/queries/images/images.d.ts.map +0 -1
  337. package/lib/queries/index.d.ts.map +0 -1
  338. package/lib/queries/locations/locations.d.ts.map +0 -1
  339. package/lib/queries/messages/messages.d.ts.map +0 -1
  340. package/lib/queries/personas/personas.d.ts.map +0 -1
  341. package/lib/queries/posts/posts.d.ts.map +0 -1
  342. package/lib/queries/query/query.d.ts.map +0 -1
  343. package/lib/queries/reactions/reactions.d.ts.map +0 -1
  344. package/lib/queries/statistics/statistics.d.ts.map +0 -1
  345. package/lib/queries/subscriptions/subscriptions.d.ts.map +0 -1
  346. package/lib/queries/tags/tags.d.ts.map +0 -1
  347. package/lib/queries/users/users.d.ts.map +0 -1
  348. package/lib/queries/videos/videos.d.ts.map +0 -1
  349. package/lib/templates/email/layout.d.ts +0 -3
  350. package/lib/templates/email/layout.d.ts.map +0 -1
  351. package/lib/templates/email/passwordForgot.d.ts +0 -3
  352. package/lib/templates/email/passwordForgot.d.ts.map +0 -1
  353. package/lib/templates/email/passwordRecovery.d.ts +0 -3
  354. package/lib/templates/email/passwordRecovery.d.ts.map +0 -1
  355. package/lib/templates/email/verifyEmail.d.ts +0 -3
  356. package/lib/templates/email/verifyEmail.d.ts.map +0 -1
  357. package/lib/templates/email/welcome.d.ts +0 -3
  358. package/lib/templates/email/welcome.d.ts.map +0 -1
  359. package/lib/templates/sms/passwordForgot.d.ts +0 -3
  360. package/lib/templates/sms/passwordForgot.d.ts.map +0 -1
  361. package/lib/templates/sms/passwordRecovery.d.ts +0 -3
  362. package/lib/templates/sms/passwordRecovery.d.ts.map +0 -1
  363. package/lib/templates/sms/verifyEmail.d.ts +0 -3
  364. package/lib/templates/sms/verifyEmail.d.ts.map +0 -1
  365. package/lib/templates/sms/verifyPhone.d.ts +0 -3
  366. package/lib/templates/sms/verifyPhone.d.ts.map +0 -1
  367. package/lib/templates/sms/welcome.d.ts +0 -3
  368. package/lib/templates/sms/welcome.d.ts.map +0 -1
  369. package/lib/types/apps.types.d.ts.map +0 -1
  370. package/lib/types/arangodb.types.d.ts.map +0 -1
  371. package/lib/types/auth.types.d.ts.map +0 -1
  372. package/lib/types/connections.types.d.ts.map +0 -1
  373. package/lib/types/content.types.d.ts.map +0 -1
  374. package/lib/types/conversations.types.d.ts.map +0 -1
  375. package/lib/types/email.types.d.ts.map +0 -1
  376. package/lib/types/error.types.d.ts.map +0 -1
  377. package/lib/types/files.types.d.ts.map +0 -1
  378. package/lib/types/google.types.d.ts.map +0 -1
  379. package/lib/types/groups.types.d.ts.map +0 -1
  380. package/lib/types/images.types.d.ts.map +0 -1
  381. package/lib/types/index.d.ts.map +0 -1
  382. package/lib/types/locations.types.d.ts.map +0 -1
  383. package/lib/types/messages.types.d.ts.map +0 -1
  384. package/lib/types/notifications.types.d.ts.map +0 -1
  385. package/lib/types/payments.types.d.ts.map +0 -1
  386. package/lib/types/personas.types.d.ts.map +0 -1
  387. package/lib/types/posts.types.d.ts.map +0 -1
  388. package/lib/types/statistics.types.d.ts.map +0 -1
  389. package/lib/types/tags.types.d.ts.map +0 -1
  390. package/lib/types/users.types.d.ts.map +0 -1
  391. package/lib/types/videos.types.d.ts.map +0 -1
  392. package/lib/types/websockets.types.d.ts.map +0 -1
  393. package/lib/upload.d.ts.map +0 -1
  394. package/lib/utils/adapterUtils.d.ts.map +0 -1
  395. package/lib/utils/analyticsUtils.d.ts.map +0 -1
  396. package/lib/utils/aqlHelpers.d.ts.map +0 -1
  397. package/lib/utils/arangodbUtils.d.ts.map +0 -1
  398. package/lib/utils/authUtils.d.ts.map +0 -1
  399. package/lib/utils/awsUtils.d.ts.map +0 -1
  400. package/lib/utils/collectionRegistry.d.ts.map +0 -1
  401. package/lib/utils/contextUtils.d.ts.map +0 -1
  402. package/lib/utils/dbI18n.d.ts.map +0 -1
  403. package/lib/utils/dbI18n.example.d.ts.map +0 -1
  404. package/lib/utils/googleTranslate.d.ts.map +0 -1
  405. package/lib/utils/graphqlUtils.d.ts.map +0 -1
  406. package/lib/utils/index.d.ts.map +0 -1
  407. package/lib/utils/languageDetection.d.ts.map +0 -1
  408. package/lib/utils/localeUtils.d.ts.map +0 -1
  409. package/lib/utils/localeUtils.example.d.ts.map +0 -1
  410. package/lib/utils/middlewareUtils.d.ts.map +0 -1
  411. package/lib/utils/queryBuilder.d.ts.map +0 -1
  412. package/lib/utils/schemaUtils.d.ts.map +0 -1
  413. package/lib/utils/sessionUtils.d.ts.map +0 -1
  414. package/lib/utils/stripeUtils.d.ts.map +0 -1
  415. package/lib/utils/templateUtils.d.ts.map +0 -1
  416. package/lib/utils/testUtils.d.ts.map +0 -1
  417. package/lib/utils/translationQueue.d.ts.map +0 -1
  418. package/lib/utils/translationQueue.example.d.ts.map +0 -1
  419. package/lib/videoProcessing.d.ts.map +0 -1
@@ -0,0 +1,498 @@
1
+ /**
2
+ * Copyright (c) 2026-Present, Nitrogen Labs, Inc.
3
+ * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
4
+ */ import { createHash, parseId, parseString } from '@nlabs/utils/parsers/strings';
5
+ import { aql } from 'arangojs';
6
+ import { literal } from 'arangojs/aql';
7
+ import { COLLECTIONS, EDGES } from '../constants/collections.js';
8
+ import { useDb } from '../utils/arangodbUtils.js';
9
+ const now = ()=>Date.now();
10
+ const collection = (name)=>literal(name);
11
+ const docKey = (value = '')=>parseId(String(value));
12
+ const docId = (collectionName, key = '')=>`${collectionName}/${docKey(key)}`;
13
+ const externalKey = (prefix, id = '')=>createHash(`${prefix}-${String(id)}`, null);
14
+ const cleanString = (value, length = 640)=>parseString(String(value || ''), length);
15
+ const cleanExternalId = (value, length = 320)=>String(value || '').trim().slice(0, length);
16
+ const saveEdge = async (context, edgeCollection, edgeKey, from, to, data = {})=>{
17
+ const timestamp = now();
18
+ const edge = {
19
+ _from: from,
20
+ _key: edgeKey,
21
+ _to: to,
22
+ added: timestamp,
23
+ modified: timestamp,
24
+ ...data
25
+ };
26
+ const query = aql`
27
+ UPSERT {_key: ${edgeKey}}
28
+ INSERT ${edge}
29
+ UPDATE ${data} IN ${collection(edgeCollection)}
30
+ `;
31
+ await useDb(context.databaseName).query(query);
32
+ };
33
+ export const createMailingList = async (context, input)=>{
34
+ const timestamp = now();
35
+ const mailingListId = docKey(String(input?.mailingListId || createHash(`mailing-list-${input?.name}-${timestamp}`)));
36
+ const mailingList = {
37
+ _key: mailingListId,
38
+ added: timestamp,
39
+ createdByUserId: docKey(String(context?.session?.userId || '')),
40
+ description: cleanString(input?.description, 2000),
41
+ mailingListId,
42
+ modified: timestamp,
43
+ name: cleanString(input?.name, 160),
44
+ status: input?.status || 'active'
45
+ };
46
+ const query = aql`
47
+ UPSERT {_key: ${mailingListId}}
48
+ INSERT ${mailingList}
49
+ UPDATE ${{
50
+ description: mailingList.description,
51
+ modified: timestamp,
52
+ name: mailingList.name,
53
+ status: mailingList.status
54
+ }} IN ${collection(COLLECTIONS.MAILING_LISTS)}
55
+ RETURN NEW
56
+ `;
57
+ return useDb(context.databaseName).query(query).then((cursor)=>cursor.next());
58
+ };
59
+ export const getMailingLists = (context)=>{
60
+ const query = aql`
61
+ FOR list IN ${collection(COLLECTIONS.MAILING_LISTS)}
62
+ FILTER list.status != "archived"
63
+ SORT list.added DESC
64
+ RETURN list
65
+ `;
66
+ return useDb(context.databaseName).query(query).then((cursor)=>cursor.all());
67
+ };
68
+ export const addUserToMailingList = async (context, userId, mailingListId, source = 'manual')=>{
69
+ const userKey = docKey(userId);
70
+ const listKey = docKey(mailingListId);
71
+ const edgeKey = createHash(`hasMailingList-${userKey}-${listKey}`);
72
+ await saveEdge(context, EDGES.HAS_MAILING_LIST, edgeKey, docId(COLLECTIONS.USERS, userKey), docId(COLLECTIONS.MAILING_LISTS, listKey), {
73
+ addedByUserId: docKey(String(context?.session?.userId || '')),
74
+ source: cleanString(source, 80),
75
+ status: 'active'
76
+ });
77
+ return useDb(context.databaseName).query(aql`RETURN DOCUMENT(${docId(COLLECTIONS.MAILING_LISTS, listKey)})`).then((cursor)=>cursor.next());
78
+ };
79
+ export const removeUserFromMailingList = async (context, userId, mailingListId)=>{
80
+ const userKey = docKey(userId);
81
+ const listKey = docKey(mailingListId);
82
+ const edgeKey = createHash(`hasMailingList-${userKey}-${listKey}`);
83
+ const update = {
84
+ modified: now(),
85
+ removedAt: now(),
86
+ status: 'removed'
87
+ };
88
+ const query = aql`
89
+ UPDATE ${edgeKey} WITH ${update} IN ${collection(EDGES.HAS_MAILING_LIST)}
90
+ RETURN NEW
91
+ `;
92
+ return useDb(context.databaseName).query(query).then((cursor)=>cursor.next()).then(Boolean);
93
+ };
94
+ export const getMailingListUsers = (context, mailingListId)=>{
95
+ const listId = docId(COLLECTIONS.MAILING_LISTS, mailingListId);
96
+ const query = aql`
97
+ FOR user, edge IN 1..1 INBOUND ${listId} ${collection(EDGES.HAS_MAILING_LIST)}
98
+ FILTER edge.status == "active"
99
+ SORT user.email ASC
100
+ RETURN user
101
+ `;
102
+ return useDb(context.databaseName).query(query).then((cursor)=>cursor.all());
103
+ };
104
+ export const getUsersByPurchasedProduct = (context, productId)=>{
105
+ const productKey = externalKey('shopify-product', productId);
106
+ const query = aql`
107
+ FOR order IN 1..1 INBOUND ${docId(COLLECTIONS.SHOPIFY_PRODUCTS, productKey)} ${collection(EDGES.HAS_PURCHASED_PRODUCT)}
108
+ FOR user IN 1..1 INBOUND order._id ${collection(EDGES.HAS_CUSTOMER_ORDER)}
109
+ SORT user.email ASC
110
+ RETURN DISTINCT user
111
+ `;
112
+ return useDb(context.databaseName).query(query).then((cursor)=>cursor.all());
113
+ };
114
+ export const getEligibleMailingUsers = (context, options = {})=>{
115
+ const excludeOpenSupportTickets = options.excludeOpenSupportTickets !== false;
116
+ const query = aql`
117
+ LET baseUsers = (
118
+ FOR user IN ${collection(COLLECTIONS.USERS)}
119
+ FILTER user.marketingOptIn == true
120
+ FILTER user.email != null && user.email != ""
121
+ FILTER user.emailDeliveryStatus == null || user.emailDeliveryStatus == "valid"
122
+ ${options.mailingListId ? aql`
123
+ FILTER LENGTH(
124
+ FOR list IN 1..1 OUTBOUND user._id ${collection(EDGES.HAS_MAILING_LIST)}
125
+ FILTER list._key == ${docKey(options.mailingListId)}
126
+ RETURN list
127
+ ) > 0
128
+ ` : aql``}
129
+ ${options.productId ? aql`
130
+ FILTER LENGTH(
131
+ FOR order IN 1..1 OUTBOUND user._id ${collection(EDGES.HAS_CUSTOMER_ORDER)}
132
+ FOR product IN 1..1 OUTBOUND order._id ${collection(EDGES.HAS_PURCHASED_PRODUCT)}
133
+ FILTER product.productId == ${String(options.productId)}
134
+ RETURN product
135
+ ) > 0
136
+ ` : aql``}
137
+ ${excludeOpenSupportTickets ? aql`
138
+ FILTER LENGTH(
139
+ FOR ticket IN 1..1 OUTBOUND user._id ${collection(EDGES.HAS_SUPPORT_TICKET)}
140
+ FILTER ticket.status IN ["open", "in_progress", "waiting_on_customer", "waiting_on_internal"]
141
+ FILTER ticket.priority IN ["high", "urgent"]
142
+ RETURN ticket
143
+ ) == 0
144
+ ` : aql``}
145
+ RETURN user
146
+ )
147
+ FOR user IN baseUsers
148
+ SORT user.email ASC
149
+ RETURN DISTINCT user
150
+ `;
151
+ return useDb(context.databaseName).query(query).then((cursor)=>cursor.all());
152
+ };
153
+ export const ingestShopifyCustomerOrder = async (context, input)=>{
154
+ const timestamp = now();
155
+ const shopifyCustomerId = cleanExternalId(input.shopifyCustomerId, 160);
156
+ const shopifyOrderId = cleanExternalId(input.shopifyOrderId, 160);
157
+ const customer = input.customer || {};
158
+ const email = cleanString(customer.email, 320).toLowerCase();
159
+ const productIds = Array.from(new Set([
160
+ ...input.productIds || [],
161
+ ...(input.products || []).map((product)=>product.productId)
162
+ ].map((productId)=>cleanExternalId(productId, 320)).filter(Boolean)));
163
+ if (!shopifyCustomerId) {
164
+ throw new Error('required_shopifyCustomerId');
165
+ }
166
+ if (!shopifyOrderId) {
167
+ throw new Error('required_shopifyOrderId');
168
+ }
169
+ if (!email) {
170
+ throw new Error('required_customerEmail');
171
+ }
172
+ const userKey = externalKey('shopify-user', shopifyCustomerId);
173
+ const userInsert = {
174
+ _key: userKey,
175
+ added: timestamp,
176
+ email,
177
+ firstName: cleanString(customer.firstName, 160),
178
+ lastName: cleanString(customer.lastName, 160),
179
+ marketingConsentSource: 'shopify',
180
+ marketingOptIn: customer.marketingOptIn === true,
181
+ marketingOptInAt: customer.marketingOptIn === true ? timestamp : undefined,
182
+ modified: timestamp,
183
+ shopifyCustomerId,
184
+ userId: userKey
185
+ };
186
+ const userUpdate = {
187
+ email,
188
+ firstName: cleanString(customer.firstName, 160),
189
+ lastName: cleanString(customer.lastName, 160),
190
+ lastPurchasedAt: input.purchasedAt || timestamp,
191
+ marketingConsentSource: 'shopify',
192
+ marketingOptIn: customer.marketingOptIn === true,
193
+ modified: timestamp,
194
+ shopifyCustomerId
195
+ };
196
+ const userQuery = aql`
197
+ LET existing = FIRST(
198
+ FOR user IN ${collection(COLLECTIONS.USERS)}
199
+ FILTER user.shopifyCustomerId == ${shopifyCustomerId} || user.email == ${email}
200
+ LIMIT 1
201
+ RETURN user
202
+ )
203
+ LET userKey = existing ? existing._key : ${userKey}
204
+ UPSERT {_key: userKey}
205
+ INSERT MERGE(${userInsert}, {_key: userKey, userId: userKey})
206
+ UPDATE ${userUpdate} IN ${collection(COLLECTIONS.USERS)}
207
+ RETURN NEW
208
+ `;
209
+ const user = await useDb(context.databaseName).query(userQuery).then((cursor)=>cursor.next());
210
+ const resolvedUserKey = docKey(String(user?._key || user?.userId || userKey));
211
+ const orderKey = externalKey('shopify-order', shopifyOrderId);
212
+ const order = {
213
+ _key: orderKey,
214
+ added: timestamp,
215
+ currency: cleanString(input.currency, 3).toUpperCase(),
216
+ customerOrderId: orderKey,
217
+ modified: timestamp,
218
+ productIds,
219
+ purchasedAt: input.purchasedAt || timestamp,
220
+ shopifyCustomerId,
221
+ shopifyOrderId,
222
+ totalPrice: Number(input.totalPrice || 0),
223
+ userId: resolvedUserKey
224
+ };
225
+ const orderQuery = aql`
226
+ UPSERT {_key: ${orderKey}}
227
+ INSERT ${order}
228
+ UPDATE ${{
229
+ currency: order.currency,
230
+ modified: timestamp,
231
+ productIds,
232
+ purchasedAt: order.purchasedAt,
233
+ totalPrice: order.totalPrice,
234
+ userId: resolvedUserKey
235
+ }} IN ${collection(COLLECTIONS.CUSTOMER_ORDERS)}
236
+ RETURN NEW
237
+ `;
238
+ const savedOrder = await useDb(context.databaseName).query(orderQuery).then((cursor)=>cursor.next());
239
+ await saveEdge(context, EDGES.HAS_CUSTOMER_ORDER, createHash(`hasCustomerOrder-${resolvedUserKey}-${orderKey}`), docId(COLLECTIONS.USERS, resolvedUserKey), docId(COLLECTIONS.CUSTOMER_ORDERS, orderKey), {
240
+ purchasedAt: order.purchasedAt,
241
+ shopifyCustomerId,
242
+ shopifyOrderId
243
+ });
244
+ await Promise.all(productIds.map(async (productId)=>{
245
+ const product = (input.products || []).find((item)=>item.productId === productId) || {
246
+ productId
247
+ };
248
+ const productKey = externalKey('shopify-product', productId);
249
+ const productDoc = {
250
+ _key: productKey,
251
+ added: timestamp,
252
+ modified: timestamp,
253
+ productId,
254
+ title: cleanString(product.title, 320),
255
+ variantId: cleanExternalId(product.variantId, 160)
256
+ };
257
+ const productQuery = aql`
258
+ UPSERT {_key: ${productKey}}
259
+ INSERT ${productDoc}
260
+ UPDATE ${{
261
+ modified: timestamp,
262
+ title: productDoc.title,
263
+ variantId: productDoc.variantId
264
+ }} IN ${collection(COLLECTIONS.SHOPIFY_PRODUCTS)}
265
+ `;
266
+ await useDb(context.databaseName).query(productQuery);
267
+ await saveEdge(context, EDGES.HAS_PURCHASED_PRODUCT, createHash(`hasPurchasedProduct-${orderKey}-${productKey}`), docId(COLLECTIONS.CUSTOMER_ORDERS, orderKey), docId(COLLECTIONS.SHOPIFY_PRODUCTS, productKey), {
268
+ productId,
269
+ purchasedAt: order.purchasedAt
270
+ });
271
+ }));
272
+ await useDb(context.databaseName).query(aql`
273
+ UPDATE ${resolvedUserKey}
274
+ WITH {
275
+ lastPurchasedAt: ${order.purchasedAt},
276
+ totalOrderCount: LENGTH(
277
+ FOR order IN 1..1 OUTBOUND ${docId(COLLECTIONS.USERS, resolvedUserKey)} ${collection(EDGES.HAS_CUSTOMER_ORDER)}
278
+ RETURN order
279
+ ),
280
+ totalSpend: SUM(
281
+ FOR order IN 1..1 OUTBOUND ${docId(COLLECTIONS.USERS, resolvedUserKey)} ${collection(EDGES.HAS_CUSTOMER_ORDER)}
282
+ RETURN TO_NUMBER(order.totalPrice)
283
+ )
284
+ } IN ${collection(COLLECTIONS.USERS)}
285
+ `);
286
+ return savedOrder;
287
+ };
288
+ export const getCustomerOrdersByUser = (context, userId)=>{
289
+ const query = aql`
290
+ FOR order IN 1..1 OUTBOUND ${docId(COLLECTIONS.USERS, userId)} ${collection(EDGES.HAS_CUSTOMER_ORDER)}
291
+ SORT order.purchasedAt DESC
292
+ RETURN order
293
+ `;
294
+ return useDb(context.databaseName).query(query).then((cursor)=>cursor.all());
295
+ };
296
+ export const createSupportTicket = async (context, input)=>{
297
+ const timestamp = now();
298
+ const userKey = docKey(String(input.userId || ''));
299
+ const ticketKey = docKey(String(input.supportTicketId || createHash(`support-ticket-${userKey}-${timestamp}`)));
300
+ const ticket = {
301
+ _key: ticketKey,
302
+ added: timestamp,
303
+ assignedToUserId: docKey(String(input.assignedToUserId || '')),
304
+ description: cleanString(input.description, 4000),
305
+ modified: timestamp,
306
+ priority: input.priority || 'normal',
307
+ productId: cleanExternalId(input.productId, 320),
308
+ shopifyOrderId: cleanString(input.shopifyOrderId, 160),
309
+ status: 'open',
310
+ subject: cleanString(input.subject, 320),
311
+ supportTicketId: ticketKey,
312
+ type: input.type || 'general_support',
313
+ userId: userKey
314
+ };
315
+ const query = aql`
316
+ INSERT ${ticket} IN ${collection(COLLECTIONS.SUPPORT_TICKETS)}
317
+ RETURN NEW
318
+ `;
319
+ const savedTicket = await useDb(context.databaseName).query(query).then((cursor)=>cursor.next());
320
+ await saveEdge(context, EDGES.HAS_SUPPORT_TICKET, createHash(`hasSupportTicket-${userKey}-${ticketKey}`), docId(COLLECTIONS.USERS, userKey), docId(COLLECTIONS.SUPPORT_TICKETS, ticketKey), {
321
+ priority: ticket.priority,
322
+ status: ticket.status,
323
+ type: ticket.type
324
+ });
325
+ await addSupportTicketEvent(context, {
326
+ actorUserId: docKey(String(context?.session?.userId || userKey)),
327
+ eventType: 'created',
328
+ supportTicketId: ticketKey,
329
+ toValue: ticket.status
330
+ });
331
+ return savedTicket;
332
+ };
333
+ export const getSupportTickets = (context, filters = {})=>{
334
+ const query = aql`
335
+ FOR ticket IN ${collection(COLLECTIONS.SUPPORT_TICKETS)}
336
+ ${filters.status ? aql`FILTER ticket.status == ${filters.status}` : aql``}
337
+ ${filters.userId ? aql`FILTER ticket.userId == ${docKey(filters.userId)}` : aql``}
338
+ LET user = DOCUMENT(${COLLECTIONS.USERS}, ticket.userId)
339
+ SORT ticket.added DESC
340
+ RETURN MERGE(ticket, {user})
341
+ `;
342
+ return useDb(context.databaseName).query(query).then((cursor)=>cursor.all());
343
+ };
344
+ export const updateSupportTicketStatus = async (context, supportTicketId, status, resolutionSummary = '')=>{
345
+ const ticketKey = docKey(supportTicketId);
346
+ const timestamp = now();
347
+ const previous = await useDb(context.databaseName).query(aql`RETURN DOCUMENT(${docId(COLLECTIONS.SUPPORT_TICKETS, ticketKey)})`).then((cursor)=>cursor.next());
348
+ const update = {
349
+ ...status === 'resolved' && {
350
+ resolvedAt: timestamp,
351
+ resolutionSummary: cleanString(resolutionSummary, 4000)
352
+ },
353
+ ...status === 'closed' && {
354
+ closedAt: timestamp
355
+ },
356
+ modified: timestamp,
357
+ status
358
+ };
359
+ const query = aql`
360
+ UPDATE ${ticketKey} WITH ${update} IN ${collection(COLLECTIONS.SUPPORT_TICKETS)}
361
+ RETURN NEW
362
+ `;
363
+ const ticket = await useDb(context.databaseName).query(query).then((cursor)=>cursor.next());
364
+ await useDb(context.databaseName).query(aql`
365
+ FOR edge IN ${collection(EDGES.HAS_SUPPORT_TICKET)}
366
+ FILTER edge._to == ${docId(COLLECTIONS.SUPPORT_TICKETS, ticketKey)}
367
+ UPDATE edge WITH ${{
368
+ modified: timestamp,
369
+ resolvedAt: status === 'resolved' ? timestamp : undefined,
370
+ status
371
+ }} IN ${collection(EDGES.HAS_SUPPORT_TICKET)}
372
+ `);
373
+ await addSupportTicketEvent(context, {
374
+ actorUserId: docKey(String(context?.session?.userId || '')),
375
+ eventType: 'status_changed',
376
+ fromValue: previous?.status,
377
+ supportTicketId: ticketKey,
378
+ toValue: status
379
+ });
380
+ if (status === 'resolved') {
381
+ await createCustomerNotification(context, {
382
+ body: cleanString(resolutionSummary || 'Your support ticket has been resolved.', 4000),
383
+ status: 'queued',
384
+ subject: `Resolved: ${ticket.subject || 'Support ticket'}`,
385
+ supportTicketId: ticketKey,
386
+ type: 'support_ticket_resolved',
387
+ userId: ticket.userId
388
+ });
389
+ }
390
+ return ticket;
391
+ };
392
+ export const addSupportTicketMessage = async (context, input)=>{
393
+ const timestamp = now();
394
+ const ticketKey = docKey(String(input.supportTicketId || ''));
395
+ const messageKey = docKey(String(input.supportTicketMessageId || createHash(`support-ticket-message-${ticketKey}-${timestamp}`)));
396
+ const message = {
397
+ _key: messageKey,
398
+ added: timestamp,
399
+ authorUserId: docKey(String(input.authorUserId || context?.session?.userId || '')),
400
+ body: cleanString(input.body, 4000),
401
+ modified: timestamp,
402
+ supportTicketId: ticketKey,
403
+ supportTicketMessageId: messageKey,
404
+ visibility: input.visibility || 'customer'
405
+ };
406
+ const query = aql`
407
+ INSERT ${message} IN ${collection(COLLECTIONS.SUPPORT_TICKET_MESSAGES)}
408
+ RETURN NEW
409
+ `;
410
+ const savedMessage = await useDb(context.databaseName).query(query).then((cursor)=>cursor.next());
411
+ await saveEdge(context, EDGES.HAS_SUPPORT_TICKET_MESSAGE, createHash(`hasSupportTicketMessage-${ticketKey}-${messageKey}`), docId(COLLECTIONS.SUPPORT_TICKETS, ticketKey), docId(COLLECTIONS.SUPPORT_TICKET_MESSAGES, messageKey), {
412
+ authorUserId: message.authorUserId,
413
+ visibility: message.visibility
414
+ });
415
+ return savedMessage;
416
+ };
417
+ export const getSupportTicketMessages = (context, supportTicketId)=>{
418
+ const query = aql`
419
+ FOR message IN 1..1 OUTBOUND ${docId(COLLECTIONS.SUPPORT_TICKETS, supportTicketId)} ${collection(EDGES.HAS_SUPPORT_TICKET_MESSAGE)}
420
+ SORT message.added ASC
421
+ RETURN message
422
+ `;
423
+ return useDb(context.databaseName).query(query).then((cursor)=>cursor.all());
424
+ };
425
+ export const addSupportTicketEvent = async (context, input)=>{
426
+ const timestamp = now();
427
+ const ticketKey = docKey(String(input.supportTicketId || ''));
428
+ const eventKey = docKey(String(input.supportTicketEventId || createHash(`support-ticket-event-${ticketKey}-${timestamp}-${input.eventType}`)));
429
+ const event = {
430
+ _key: eventKey,
431
+ added: timestamp,
432
+ actorUserId: docKey(String(input.actorUserId || '')),
433
+ eventType: cleanString(input.eventType, 160),
434
+ fromValue: cleanString(input.fromValue, 320),
435
+ metadata: input.metadata || {},
436
+ modified: timestamp,
437
+ supportTicketEventId: eventKey,
438
+ supportTicketId: ticketKey,
439
+ toValue: cleanString(input.toValue, 320)
440
+ };
441
+ const query = aql`
442
+ INSERT ${event} IN ${collection(COLLECTIONS.SUPPORT_TICKET_EVENTS)}
443
+ RETURN NEW
444
+ `;
445
+ const savedEvent = await useDb(context.databaseName).query(query).then((cursor)=>cursor.next());
446
+ await saveEdge(context, EDGES.HAS_SUPPORT_TICKET_EVENT, createHash(`hasSupportTicketEvent-${ticketKey}-${eventKey}`), docId(COLLECTIONS.SUPPORT_TICKETS, ticketKey), docId(COLLECTIONS.SUPPORT_TICKET_EVENTS, eventKey), {
447
+ actorUserId: event.actorUserId,
448
+ eventType: event.eventType
449
+ });
450
+ return savedEvent;
451
+ };
452
+ export const getSupportTicketEvents = (context, supportTicketId)=>{
453
+ const query = aql`
454
+ FOR event IN 1..1 OUTBOUND ${docId(COLLECTIONS.SUPPORT_TICKETS, supportTicketId)} ${collection(EDGES.HAS_SUPPORT_TICKET_EVENT)}
455
+ SORT event.added ASC
456
+ RETURN event
457
+ `;
458
+ return useDb(context.databaseName).query(query).then((cursor)=>cursor.all());
459
+ };
460
+ export const createCustomerNotification = async (context, input)=>{
461
+ const timestamp = now();
462
+ const userKey = docKey(String(input.userId || ''));
463
+ const notificationKey = docKey(String(input.customerNotificationId || createHash(`customer-notification-${userKey}-${timestamp}`)));
464
+ const notification = {
465
+ _key: notificationKey,
466
+ added: timestamp,
467
+ body: cleanString(input.body, 4000),
468
+ customerNotificationId: notificationKey,
469
+ modified: timestamp,
470
+ sentAt: input.sentAt,
471
+ status: input.status || 'queued',
472
+ subject: cleanString(input.subject, 320),
473
+ supportTicketId: docKey(String(input.supportTicketId || '')),
474
+ type: cleanString(input.type, 160),
475
+ userId: userKey
476
+ };
477
+ const query = aql`
478
+ INSERT ${notification} IN ${collection(COLLECTIONS.CUSTOMER_NOTIFICATIONS)}
479
+ RETURN NEW
480
+ `;
481
+ const savedNotification = await useDb(context.databaseName).query(query).then((cursor)=>cursor.next());
482
+ await saveEdge(context, EDGES.HAS_CUSTOMER_NOTIFICATION, createHash(`hasCustomerNotification-${userKey}-${notificationKey}`), docId(COLLECTIONS.USERS, userKey), docId(COLLECTIONS.CUSTOMER_NOTIFICATIONS, notificationKey), {
483
+ status: notification.status,
484
+ supportTicketId: notification.supportTicketId,
485
+ type: notification.type
486
+ });
487
+ return savedNotification;
488
+ };
489
+ export const getCustomerNotificationsByUser = (context, userId)=>{
490
+ const query = aql`
491
+ FOR notification IN 1..1 OUTBOUND ${docId(COLLECTIONS.USERS, userId)} ${collection(EDGES.HAS_CUSTOMER_NOTIFICATION)}
492
+ SORT notification.added DESC
493
+ RETURN notification
494
+ `;
495
+ return useDb(context.databaseName).query(query).then((cursor)=>cursor.all());
496
+ };
497
+
498
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L3JlYWt0b3Ivc3JjL2FjdGlvbnMvY3JtLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29weXJpZ2h0IChjKSAyMDI2LVByZXNlbnQsIE5pdHJvZ2VuIExhYnMsIEluYy5cbiAqIENvcHlyaWdodHMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLiBTZWUgdGhlIGFjY29tcGFueWluZyBMSUNFTlNFIGZpbGUgZm9yIHRlcm1zLlxuICovXG5pbXBvcnQge2NyZWF0ZUhhc2gsIHBhcnNlSWQsIHBhcnNlU3RyaW5nfSBmcm9tICdAbmxhYnMvdXRpbHMvcGFyc2Vycy9zdHJpbmdzJztcbmltcG9ydCB7YXFsfSBmcm9tICdhcmFuZ29qcyc7XG5pbXBvcnQge2xpdGVyYWx9IGZyb20gJ2FyYW5nb2pzL2FxbCc7XG5cbmltcG9ydCB7Q09MTEVDVElPTlMsIEVER0VTfSBmcm9tICcuLi9jb25zdGFudHMvY29sbGVjdGlvbnMuanMnO1xuaW1wb3J0IHt1c2VEYn0gZnJvbSAnLi4vdXRpbHMvYXJhbmdvZGJVdGlscy5qcyc7XG5cbmltcG9ydCB0eXBlIHtBcWxRdWVyeX0gZnJvbSAnYXJhbmdvanMvYXFsJztcbmltcG9ydCB0eXBlIHtBcGlDb250ZXh0fSBmcm9tICcuLi90eXBlcy9hdXRoLnR5cGVzLmpzJztcbmltcG9ydCB0eXBlIHtcbiAgQ3VzdG9tZXJOb3RpZmljYXRpb25UeXBlLFxuICBDdXN0b21lck9yZGVyVHlwZSxcbiAgTWFpbGluZ0xpc3RUeXBlLFxuICBTaG9waWZ5Q3VzdG9tZXJPcmRlcklucHV0LFxuICBTdXBwb3J0VGlja2V0RXZlbnRUeXBlLFxuICBTdXBwb3J0VGlja2V0TWVzc2FnZVR5cGUsXG4gIFN1cHBvcnRUaWNrZXRTdGF0dXMsXG4gIFN1cHBvcnRUaWNrZXRUeXBlRGF0YVxufSBmcm9tICcuLi90eXBlcy9jcm0udHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1VzZXJUeXBlfSBmcm9tICcuLi90eXBlcy91c2Vycy50eXBlcy5qcyc7XG5cbmNvbnN0IG5vdyA9ICgpOiBudW1iZXIgPT4gRGF0ZS5ub3coKTtcbmNvbnN0IGNvbGxlY3Rpb24gPSAobmFtZTogc3RyaW5nKSA9PiBsaXRlcmFsKG5hbWUpO1xuY29uc3QgZG9jS2V5ID0gKHZhbHVlID0gJycpOiBzdHJpbmcgPT4gcGFyc2VJZChTdHJpbmcodmFsdWUpKTtcbmNvbnN0IGRvY0lkID0gKGNvbGxlY3Rpb25OYW1lOiBzdHJpbmcsIGtleSA9ICcnKTogc3RyaW5nID0+IGAke2NvbGxlY3Rpb25OYW1lfS8ke2RvY0tleShrZXkpfWA7XG5jb25zdCBleHRlcm5hbEtleSA9IChwcmVmaXg6IHN0cmluZywgaWQgPSAnJyk6IHN0cmluZyA9PiBjcmVhdGVIYXNoKGAke3ByZWZpeH0tJHtTdHJpbmcoaWQpfWAsIG51bGwpO1xuY29uc3QgY2xlYW5TdHJpbmcgPSAodmFsdWU6IHVua25vd24sIGxlbmd0aCA9IDY0MCk6IHN0cmluZyA9PiBwYXJzZVN0cmluZyhTdHJpbmcodmFsdWUgfHwgJycpLCBsZW5ndGgpO1xuY29uc3QgY2xlYW5FeHRlcm5hbElkID0gKHZhbHVlOiB1bmtub3duLCBsZW5ndGggPSAzMjApOiBzdHJpbmcgPT4gU3RyaW5nKHZhbHVlIHx8ICcnKS50cmltKCkuc2xpY2UoMCwgbGVuZ3RoKTtcblxuY29uc3Qgc2F2ZUVkZ2UgPSBhc3luYyAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIGVkZ2VDb2xsZWN0aW9uOiBzdHJpbmcsXG4gIGVkZ2VLZXk6IHN0cmluZyxcbiAgZnJvbTogc3RyaW5nLFxuICB0bzogc3RyaW5nLFxuICBkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9XG4pOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgY29uc3QgdGltZXN0YW1wID0gbm93KCk7XG4gIGNvbnN0IGVkZ2UgPSB7XG4gICAgX2Zyb206IGZyb20sXG4gICAgX2tleTogZWRnZUtleSxcbiAgICBfdG86IHRvLFxuICAgIGFkZGVkOiB0aW1lc3RhbXAsXG4gICAgbW9kaWZpZWQ6IHRpbWVzdGFtcCxcbiAgICAuLi5kYXRhXG4gIH07XG4gIGNvbnN0IHF1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBcbiAgICBVUFNFUlQge19rZXk6ICR7ZWRnZUtleX19XG4gICAgSU5TRVJUICR7ZWRnZX1cbiAgICBVUERBVEUgJHtkYXRhfSBJTiAke2NvbGxlY3Rpb24oZWRnZUNvbGxlY3Rpb24pfVxuICBgO1xuXG4gIGF3YWl0IHVzZURiKGNvbnRleHQuZGF0YWJhc2VOYW1lKS5xdWVyeShxdWVyeSk7XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlTWFpbGluZ0xpc3QgPSBhc3luYyAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIGlucHV0OiBQYXJ0aWFsPE1haWxpbmdMaXN0VHlwZT5cbik6IFByb21pc2U8TWFpbGluZ0xpc3RUeXBlPiA9PiB7XG4gIGNvbnN0IHRpbWVzdGFtcCA9IG5vdygpO1xuICBjb25zdCBtYWlsaW5nTGlzdElkID0gZG9jS2V5KFN0cmluZyhpbnB1dD8ubWFpbGluZ0xpc3RJZCB8fCBjcmVhdGVIYXNoKGBtYWlsaW5nLWxpc3QtJHtpbnB1dD8ubmFtZX0tJHt0aW1lc3RhbXB9YCkpKTtcbiAgY29uc3QgbWFpbGluZ0xpc3QgPSB7XG4gICAgX2tleTogbWFpbGluZ0xpc3RJZCxcbiAgICBhZGRlZDogdGltZXN0YW1wLFxuICAgIGNyZWF0ZWRCeVVzZXJJZDogZG9jS2V5KFN0cmluZyhjb250ZXh0Py5zZXNzaW9uPy51c2VySWQgfHwgJycpKSxcbiAgICBkZXNjcmlwdGlvbjogY2xlYW5TdHJpbmcoaW5wdXQ/LmRlc2NyaXB0aW9uLCAyMDAwKSxcbiAgICBtYWlsaW5nTGlzdElkLFxuICAgIG1vZGlmaWVkOiB0aW1lc3RhbXAsXG4gICAgbmFtZTogY2xlYW5TdHJpbmcoaW5wdXQ/Lm5hbWUsIDE2MCksXG4gICAgc3RhdHVzOiBpbnB1dD8uc3RhdHVzIHx8ICdhY3RpdmUnXG4gIH07XG4gIGNvbnN0IHF1ZXJ5ID0gYXFsYFxuICAgIFVQU0VSVCB7X2tleTogJHttYWlsaW5nTGlzdElkfX1cbiAgICBJTlNFUlQgJHttYWlsaW5nTGlzdH1cbiAgICBVUERBVEUgJHt7XG4gICAgICBkZXNjcmlwdGlvbjogbWFpbGluZ0xpc3QuZGVzY3JpcHRpb24sXG4gICAgICBtb2RpZmllZDogdGltZXN0YW1wLFxuICAgICAgbmFtZTogbWFpbGluZ0xpc3QubmFtZSxcbiAgICAgIHN0YXR1czogbWFpbGluZ0xpc3Quc3RhdHVzXG4gICAgfX0gSU4gJHtjb2xsZWN0aW9uKENPTExFQ1RJT05TLk1BSUxJTkdfTElTVFMpfVxuICAgIFJFVFVSTiBORVdcbiAgYDtcblxuICByZXR1cm4gdXNlRGIoY29udGV4dC5kYXRhYmFzZU5hbWUpLnF1ZXJ5KHF1ZXJ5KS50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldE1haWxpbmdMaXN0cyA9IChjb250ZXh0OiBBcGlDb250ZXh0KTogUHJvbWlzZTxNYWlsaW5nTGlzdFR5cGVbXT4gPT4ge1xuICBjb25zdCBxdWVyeSA9IGFxbGBcbiAgICBGT1IgbGlzdCBJTiAke2NvbGxlY3Rpb24oQ09MTEVDVElPTlMuTUFJTElOR19MSVNUUyl9XG4gICAgICBGSUxURVIgbGlzdC5zdGF0dXMgIT0gXCJhcmNoaXZlZFwiXG4gICAgICBTT1JUIGxpc3QuYWRkZWQgREVTQ1xuICAgICAgUkVUVVJOIGxpc3RcbiAgYDtcblxuICByZXR1cm4gdXNlRGIoY29udGV4dC5kYXRhYmFzZU5hbWUpLnF1ZXJ5KHF1ZXJ5KS50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSk7XG59O1xuXG5leHBvcnQgY29uc3QgYWRkVXNlclRvTWFpbGluZ0xpc3QgPSBhc3luYyAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHVzZXJJZDogc3RyaW5nLFxuICBtYWlsaW5nTGlzdElkOiBzdHJpbmcsXG4gIHNvdXJjZSA9ICdtYW51YWwnXG4pOiBQcm9taXNlPE1haWxpbmdMaXN0VHlwZSB8IG51bGw+ID0+IHtcbiAgY29uc3QgdXNlcktleSA9IGRvY0tleSh1c2VySWQpO1xuICBjb25zdCBsaXN0S2V5ID0gZG9jS2V5KG1haWxpbmdMaXN0SWQpO1xuICBjb25zdCBlZGdlS2V5ID0gY3JlYXRlSGFzaChgaGFzTWFpbGluZ0xpc3QtJHt1c2VyS2V5fS0ke2xpc3RLZXl9YCk7XG5cbiAgYXdhaXQgc2F2ZUVkZ2UoXG4gICAgY29udGV4dCxcbiAgICBFREdFUy5IQVNfTUFJTElOR19MSVNULFxuICAgIGVkZ2VLZXksXG4gICAgZG9jSWQoQ09MTEVDVElPTlMuVVNFUlMsIHVzZXJLZXkpLFxuICAgIGRvY0lkKENPTExFQ1RJT05TLk1BSUxJTkdfTElTVFMsIGxpc3RLZXkpLFxuICAgIHtcbiAgICAgIGFkZGVkQnlVc2VySWQ6IGRvY0tleShTdHJpbmcoY29udGV4dD8uc2Vzc2lvbj8udXNlcklkIHx8ICcnKSksXG4gICAgICBzb3VyY2U6IGNsZWFuU3RyaW5nKHNvdXJjZSwgODApLFxuICAgICAgc3RhdHVzOiAnYWN0aXZlJ1xuICAgIH1cbiAgKTtcblxuICByZXR1cm4gdXNlRGIoY29udGV4dC5kYXRhYmFzZU5hbWUpXG4gICAgLnF1ZXJ5KGFxbGBSRVRVUk4gRE9DVU1FTlQoJHtkb2NJZChDT0xMRUNUSU9OUy5NQUlMSU5HX0xJU1RTLCBsaXN0S2V5KX0pYClcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKTtcbn07XG5cbmV4cG9ydCBjb25zdCByZW1vdmVVc2VyRnJvbU1haWxpbmdMaXN0ID0gYXN5bmMgKFxuICBjb250ZXh0OiBBcGlDb250ZXh0LFxuICB1c2VySWQ6IHN0cmluZyxcbiAgbWFpbGluZ0xpc3RJZDogc3RyaW5nXG4pOiBQcm9taXNlPGJvb2xlYW4+ID0+IHtcbiAgY29uc3QgdXNlcktleSA9IGRvY0tleSh1c2VySWQpO1xuICBjb25zdCBsaXN0S2V5ID0gZG9jS2V5KG1haWxpbmdMaXN0SWQpO1xuICBjb25zdCBlZGdlS2V5ID0gY3JlYXRlSGFzaChgaGFzTWFpbGluZ0xpc3QtJHt1c2VyS2V5fS0ke2xpc3RLZXl9YCk7XG4gIGNvbnN0IHVwZGF0ZSA9IHtcbiAgICBtb2RpZmllZDogbm93KCksXG4gICAgcmVtb3ZlZEF0OiBub3coKSxcbiAgICBzdGF0dXM6ICdyZW1vdmVkJ1xuICB9O1xuICBjb25zdCBxdWVyeSA9IGFxbGBcbiAgICBVUERBVEUgJHtlZGdlS2V5fSBXSVRIICR7dXBkYXRlfSBJTiAke2NvbGxlY3Rpb24oRURHRVMuSEFTX01BSUxJTkdfTElTVCl9XG4gICAgUkVUVVJOIE5FV1xuICBgO1xuXG4gIHJldHVybiB1c2VEYihjb250ZXh0LmRhdGFiYXNlTmFtZSkucXVlcnkocXVlcnkpLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSkudGhlbihCb29sZWFuKTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRNYWlsaW5nTGlzdFVzZXJzID0gKFxuICBjb250ZXh0OiBBcGlDb250ZXh0LFxuICBtYWlsaW5nTGlzdElkOiBzdHJpbmdcbik6IFByb21pc2U8VXNlclR5cGVbXT4gPT4ge1xuICBjb25zdCBsaXN0SWQgPSBkb2NJZChDT0xMRUNUSU9OUy5NQUlMSU5HX0xJU1RTLCBtYWlsaW5nTGlzdElkKTtcbiAgY29uc3QgcXVlcnkgPSBhcWxgXG4gICAgRk9SIHVzZXIsIGVkZ2UgSU4gMS4uMSBJTkJPVU5EICR7bGlzdElkfSAke2NvbGxlY3Rpb24oRURHRVMuSEFTX01BSUxJTkdfTElTVCl9XG4gICAgICBGSUxURVIgZWRnZS5zdGF0dXMgPT0gXCJhY3RpdmVcIlxuICAgICAgU09SVCB1c2VyLmVtYWlsIEFTQ1xuICAgICAgUkVUVVJOIHVzZXJcbiAgYDtcblxuICByZXR1cm4gdXNlRGIoY29udGV4dC5kYXRhYmFzZU5hbWUpLnF1ZXJ5KHF1ZXJ5KS50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VXNlcnNCeVB1cmNoYXNlZFByb2R1Y3QgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHByb2R1Y3RJZDogc3RyaW5nXG4pOiBQcm9taXNlPFVzZXJUeXBlW10+ID0+IHtcbiAgY29uc3QgcHJvZHVjdEtleSA9IGV4dGVybmFsS2V5KCdzaG9waWZ5LXByb2R1Y3QnLCBwcm9kdWN0SWQpO1xuICBjb25zdCBxdWVyeSA9IGFxbGBcbiAgICBGT1Igb3JkZXIgSU4gMS4uMSBJTkJPVU5EICR7ZG9jSWQoQ09MTEVDVElPTlMuU0hPUElGWV9QUk9EVUNUUywgcHJvZHVjdEtleSl9ICR7Y29sbGVjdGlvbihFREdFUy5IQVNfUFVSQ0hBU0VEX1BST0RVQ1QpfVxuICAgICAgRk9SIHVzZXIgSU4gMS4uMSBJTkJPVU5EIG9yZGVyLl9pZCAke2NvbGxlY3Rpb24oRURHRVMuSEFTX0NVU1RPTUVSX09SREVSKX1cbiAgICAgICAgU09SVCB1c2VyLmVtYWlsIEFTQ1xuICAgICAgICBSRVRVUk4gRElTVElOQ1QgdXNlclxuICBgO1xuXG4gIHJldHVybiB1c2VEYihjb250ZXh0LmRhdGFiYXNlTmFtZSkucXVlcnkocXVlcnkpLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRFbGlnaWJsZU1haWxpbmdVc2VycyA9IChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgb3B0aW9uczoge3JlYWRvbmx5IG1haWxpbmdMaXN0SWQ/OiBzdHJpbmc7IHJlYWRvbmx5IHByb2R1Y3RJZD86IHN0cmluZzsgcmVhZG9ubHkgZXhjbHVkZU9wZW5TdXBwb3J0VGlja2V0cz86IGJvb2xlYW59ID0ge31cbik6IFByb21pc2U8VXNlclR5cGVbXT4gPT4ge1xuICBjb25zdCBleGNsdWRlT3BlblN1cHBvcnRUaWNrZXRzID0gb3B0aW9ucy5leGNsdWRlT3BlblN1cHBvcnRUaWNrZXRzICE9PSBmYWxzZTtcbiAgY29uc3QgcXVlcnkgPSBhcWxgXG4gICAgTEVUIGJhc2VVc2VycyA9IChcbiAgICAgIEZPUiB1c2VyIElOICR7Y29sbGVjdGlvbihDT0xMRUNUSU9OUy5VU0VSUyl9XG4gICAgICAgIEZJTFRFUiB1c2VyLm1hcmtldGluZ09wdEluID09IHRydWVcbiAgICAgICAgRklMVEVSIHVzZXIuZW1haWwgIT0gbnVsbCAmJiB1c2VyLmVtYWlsICE9IFwiXCJcbiAgICAgICAgRklMVEVSIHVzZXIuZW1haWxEZWxpdmVyeVN0YXR1cyA9PSBudWxsIHx8IHVzZXIuZW1haWxEZWxpdmVyeVN0YXR1cyA9PSBcInZhbGlkXCJcbiAgICAgICAgJHtvcHRpb25zLm1haWxpbmdMaXN0SWQgPyBhcWxgXG4gICAgICAgICAgRklMVEVSIExFTkdUSChcbiAgICAgICAgICAgIEZPUiBsaXN0IElOIDEuLjEgT1VUQk9VTkQgdXNlci5faWQgJHtjb2xsZWN0aW9uKEVER0VTLkhBU19NQUlMSU5HX0xJU1QpfVxuICAgICAgICAgICAgICBGSUxURVIgbGlzdC5fa2V5ID09ICR7ZG9jS2V5KG9wdGlvbnMubWFpbGluZ0xpc3RJZCl9XG4gICAgICAgICAgICAgIFJFVFVSTiBsaXN0XG4gICAgICAgICAgKSA+IDBcbiAgICAgICAgYCA6IGFxbGBgfVxuICAgICAgICAke29wdGlvbnMucHJvZHVjdElkID8gYXFsYFxuICAgICAgICAgIEZJTFRFUiBMRU5HVEgoXG4gICAgICAgICAgICBGT1Igb3JkZXIgSU4gMS4uMSBPVVRCT1VORCB1c2VyLl9pZCAke2NvbGxlY3Rpb24oRURHRVMuSEFTX0NVU1RPTUVSX09SREVSKX1cbiAgICAgICAgICAgICAgRk9SIHByb2R1Y3QgSU4gMS4uMSBPVVRCT1VORCBvcmRlci5faWQgJHtjb2xsZWN0aW9uKEVER0VTLkhBU19QVVJDSEFTRURfUFJPRFVDVCl9XG4gICAgICAgICAgICAgICAgRklMVEVSIHByb2R1Y3QucHJvZHVjdElkID09ICR7U3RyaW5nKG9wdGlvbnMucHJvZHVjdElkKX1cbiAgICAgICAgICAgICAgICBSRVRVUk4gcHJvZHVjdFxuICAgICAgICAgICkgPiAwXG4gICAgICAgIGAgOiBhcWxgYH1cbiAgICAgICAgJHtleGNsdWRlT3BlblN1cHBvcnRUaWNrZXRzID8gYXFsYFxuICAgICAgICAgIEZJTFRFUiBMRU5HVEgoXG4gICAgICAgICAgICBGT1IgdGlja2V0IElOIDEuLjEgT1VUQk9VTkQgdXNlci5faWQgJHtjb2xsZWN0aW9uKEVER0VTLkhBU19TVVBQT1JUX1RJQ0tFVCl9XG4gICAgICAgICAgICAgIEZJTFRFUiB0aWNrZXQuc3RhdHVzIElOIFtcIm9wZW5cIiwgXCJpbl9wcm9ncmVzc1wiLCBcIndhaXRpbmdfb25fY3VzdG9tZXJcIiwgXCJ3YWl0aW5nX29uX2ludGVybmFsXCJdXG4gICAgICAgICAgICAgIEZJTFRFUiB0aWNrZXQucHJpb3JpdHkgSU4gW1wiaGlnaFwiLCBcInVyZ2VudFwiXVxuICAgICAgICAgICAgICBSRVRVUk4gdGlja2V0XG4gICAgICAgICAgKSA9PSAwXG4gICAgICAgIGAgOiBhcWxgYH1cbiAgICAgICAgUkVUVVJOIHVzZXJcbiAgICApXG4gICAgRk9SIHVzZXIgSU4gYmFzZVVzZXJzXG4gICAgICBTT1JUIHVzZXIuZW1haWwgQVNDXG4gICAgICBSRVRVUk4gRElTVElOQ1QgdXNlclxuICBgO1xuXG4gIHJldHVybiB1c2VEYihjb250ZXh0LmRhdGFiYXNlTmFtZSkucXVlcnkocXVlcnkpLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBpbmdlc3RTaG9waWZ5Q3VzdG9tZXJPcmRlciA9IGFzeW5jIChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgaW5wdXQ6IFNob3BpZnlDdXN0b21lck9yZGVySW5wdXRcbik6IFByb21pc2U8Q3VzdG9tZXJPcmRlclR5cGU+ID0+IHtcbiAgY29uc3QgdGltZXN0YW1wID0gbm93KCk7XG4gIGNvbnN0IHNob3BpZnlDdXN0b21lcklkID0gY2xlYW5FeHRlcm5hbElkKGlucHV0LnNob3BpZnlDdXN0b21lcklkLCAxNjApO1xuICBjb25zdCBzaG9waWZ5T3JkZXJJZCA9IGNsZWFuRXh0ZXJuYWxJZChpbnB1dC5zaG9waWZ5T3JkZXJJZCwgMTYwKTtcbiAgY29uc3QgY3VzdG9tZXIgPSBpbnB1dC5jdXN0b21lciB8fCB7fTtcbiAgY29uc3QgZW1haWwgPSBjbGVhblN0cmluZyhjdXN0b21lci5lbWFpbCwgMzIwKS50b0xvd2VyQ2FzZSgpO1xuICBjb25zdCBwcm9kdWN0SWRzID0gQXJyYXkuZnJvbShuZXcgU2V0KFsuLi4oaW5wdXQucHJvZHVjdElkcyB8fCBbXSksIC4uLihpbnB1dC5wcm9kdWN0cyB8fCBbXSkubWFwKChwcm9kdWN0KSA9PiBwcm9kdWN0LnByb2R1Y3RJZCldXG4gICAgLm1hcCgocHJvZHVjdElkKSA9PiBjbGVhbkV4dGVybmFsSWQocHJvZHVjdElkLCAzMjApKVxuICAgIC5maWx0ZXIoQm9vbGVhbikpKTtcblxuICBpZighc2hvcGlmeUN1c3RvbWVySWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3JlcXVpcmVkX3Nob3BpZnlDdXN0b21lcklkJyk7XG4gIH1cbiAgaWYoIXNob3BpZnlPcmRlcklkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdyZXF1aXJlZF9zaG9waWZ5T3JkZXJJZCcpO1xuICB9XG4gIGlmKCFlbWFpbCkge1xuICAgIHRocm93IG5ldyBFcnJvcigncmVxdWlyZWRfY3VzdG9tZXJFbWFpbCcpO1xuICB9XG5cbiAgY29uc3QgdXNlcktleSA9IGV4dGVybmFsS2V5KCdzaG9waWZ5LXVzZXInLCBzaG9waWZ5Q3VzdG9tZXJJZCk7XG4gIGNvbnN0IHVzZXJJbnNlcnQgPSB7XG4gICAgX2tleTogdXNlcktleSxcbiAgICBhZGRlZDogdGltZXN0YW1wLFxuICAgIGVtYWlsLFxuICAgIGZpcnN0TmFtZTogY2xlYW5TdHJpbmcoY3VzdG9tZXIuZmlyc3ROYW1lLCAxNjApLFxuICAgIGxhc3ROYW1lOiBjbGVhblN0cmluZyhjdXN0b21lci5sYXN0TmFtZSwgMTYwKSxcbiAgICBtYXJrZXRpbmdDb25zZW50U291cmNlOiAnc2hvcGlmeScsXG4gICAgbWFya2V0aW5nT3B0SW46IGN1c3RvbWVyLm1hcmtldGluZ09wdEluID09PSB0cnVlLFxuICAgIG1hcmtldGluZ09wdEluQXQ6IGN1c3RvbWVyLm1hcmtldGluZ09wdEluID09PSB0cnVlID8gdGltZXN0YW1wIDogdW5kZWZpbmVkLFxuICAgIG1vZGlmaWVkOiB0aW1lc3RhbXAsXG4gICAgc2hvcGlmeUN1c3RvbWVySWQsXG4gICAgdXNlcklkOiB1c2VyS2V5XG4gIH07XG4gIGNvbnN0IHVzZXJVcGRhdGUgPSB7XG4gICAgZW1haWwsXG4gICAgZmlyc3ROYW1lOiBjbGVhblN0cmluZyhjdXN0b21lci5maXJzdE5hbWUsIDE2MCksXG4gICAgbGFzdE5hbWU6IGNsZWFuU3RyaW5nKGN1c3RvbWVyLmxhc3ROYW1lLCAxNjApLFxuICAgIGxhc3RQdXJjaGFzZWRBdDogaW5wdXQucHVyY2hhc2VkQXQgfHwgdGltZXN0YW1wLFxuICAgIG1hcmtldGluZ0NvbnNlbnRTb3VyY2U6ICdzaG9waWZ5JyxcbiAgICBtYXJrZXRpbmdPcHRJbjogY3VzdG9tZXIubWFya2V0aW5nT3B0SW4gPT09IHRydWUsXG4gICAgbW9kaWZpZWQ6IHRpbWVzdGFtcCxcbiAgICBzaG9waWZ5Q3VzdG9tZXJJZFxuICB9O1xuICBjb25zdCB1c2VyUXVlcnkgPSBhcWxgXG4gICAgTEVUIGV4aXN0aW5nID0gRklSU1QoXG4gICAgICBGT1IgdXNlciBJTiAke2NvbGxlY3Rpb24oQ09MTEVDVElPTlMuVVNFUlMpfVxuICAgICAgICBGSUxURVIgdXNlci5zaG9waWZ5Q3VzdG9tZXJJZCA9PSAke3Nob3BpZnlDdXN0b21lcklkfSB8fCB1c2VyLmVtYWlsID09ICR7ZW1haWx9XG4gICAgICAgIExJTUlUIDFcbiAgICAgICAgUkVUVVJOIHVzZXJcbiAgICApXG4gICAgTEVUIHVzZXJLZXkgPSBleGlzdGluZyA/IGV4aXN0aW5nLl9rZXkgOiAke3VzZXJLZXl9XG4gICAgVVBTRVJUIHtfa2V5OiB1c2VyS2V5fVxuICAgIElOU0VSVCBNRVJHRSgke3VzZXJJbnNlcnR9LCB7X2tleTogdXNlcktleSwgdXNlcklkOiB1c2VyS2V5fSlcbiAgICBVUERBVEUgJHt1c2VyVXBkYXRlfSBJTiAke2NvbGxlY3Rpb24oQ09MTEVDVElPTlMuVVNFUlMpfVxuICAgIFJFVFVSTiBORVdcbiAgYDtcbiAgY29uc3QgdXNlciA9IGF3YWl0IHVzZURiKGNvbnRleHQuZGF0YWJhc2VOYW1lKS5xdWVyeSh1c2VyUXVlcnkpLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSkgYXMgVXNlclR5cGU7XG4gIGNvbnN0IHJlc29sdmVkVXNlcktleSA9IGRvY0tleShTdHJpbmcodXNlcj8uX2tleSB8fCB1c2VyPy51c2VySWQgfHwgdXNlcktleSkpO1xuICBjb25zdCBvcmRlcktleSA9IGV4dGVybmFsS2V5KCdzaG9waWZ5LW9yZGVyJywgc2hvcGlmeU9yZGVySWQpO1xuICBjb25zdCBvcmRlciA9IHtcbiAgICBfa2V5OiBvcmRlcktleSxcbiAgICBhZGRlZDogdGltZXN0YW1wLFxuICAgIGN1cnJlbmN5OiBjbGVhblN0cmluZyhpbnB1dC5jdXJyZW5jeSwgMykudG9VcHBlckNhc2UoKSxcbiAgICBjdXN0b21lck9yZGVySWQ6IG9yZGVyS2V5LFxuICAgIG1vZGlmaWVkOiB0aW1lc3RhbXAsXG4gICAgcHJvZHVjdElkcyxcbiAgICBwdXJjaGFzZWRBdDogaW5wdXQucHVyY2hhc2VkQXQgfHwgdGltZXN0YW1wLFxuICAgIHNob3BpZnlDdXN0b21lcklkLFxuICAgIHNob3BpZnlPcmRlcklkLFxuICAgIHRvdGFsUHJpY2U6IE51bWJlcihpbnB1dC50b3RhbFByaWNlIHx8IDApLFxuICAgIHVzZXJJZDogcmVzb2x2ZWRVc2VyS2V5XG4gIH07XG4gIGNvbnN0IG9yZGVyUXVlcnkgPSBhcWxgXG4gICAgVVBTRVJUIHtfa2V5OiAke29yZGVyS2V5fX1cbiAgICBJTlNFUlQgJHtvcmRlcn1cbiAgICBVUERBVEUgJHt7XG4gICAgICBjdXJyZW5jeTogb3JkZXIuY3VycmVuY3ksXG4gICAgICBtb2RpZmllZDogdGltZXN0YW1wLFxuICAgICAgcHJvZHVjdElkcyxcbiAgICAgIHB1cmNoYXNlZEF0OiBvcmRlci5wdXJjaGFzZWRBdCxcbiAgICAgIHRvdGFsUHJpY2U6IG9yZGVyLnRvdGFsUHJpY2UsXG4gICAgICB1c2VySWQ6IHJlc29sdmVkVXNlcktleVxuICAgIH19IElOICR7Y29sbGVjdGlvbihDT0xMRUNUSU9OUy5DVVNUT01FUl9PUkRFUlMpfVxuICAgIFJFVFVSTiBORVdcbiAgYDtcbiAgY29uc3Qgc2F2ZWRPcmRlciA9IGF3YWl0IHVzZURiKGNvbnRleHQuZGF0YWJhc2VOYW1lKS5xdWVyeShvcmRlclF1ZXJ5KS50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpIGFzIEN1c3RvbWVyT3JkZXJUeXBlO1xuXG4gIGF3YWl0IHNhdmVFZGdlKFxuICAgIGNvbnRleHQsXG4gICAgRURHRVMuSEFTX0NVU1RPTUVSX09SREVSLFxuICAgIGNyZWF0ZUhhc2goYGhhc0N1c3RvbWVyT3JkZXItJHtyZXNvbHZlZFVzZXJLZXl9LSR7b3JkZXJLZXl9YCksXG4gICAgZG9jSWQoQ09MTEVDVElPTlMuVVNFUlMsIHJlc29sdmVkVXNlcktleSksXG4gICAgZG9jSWQoQ09MTEVDVElPTlMuQ1VTVE9NRVJfT1JERVJTLCBvcmRlcktleSksXG4gICAge3B1cmNoYXNlZEF0OiBvcmRlci5wdXJjaGFzZWRBdCwgc2hvcGlmeUN1c3RvbWVySWQsIHNob3BpZnlPcmRlcklkfVxuICApO1xuXG4gIGF3YWl0IFByb21pc2UuYWxsKHByb2R1Y3RJZHMubWFwKGFzeW5jIChwcm9kdWN0SWQpID0+IHtcbiAgICBjb25zdCBwcm9kdWN0ID0gKGlucHV0LnByb2R1Y3RzIHx8IFtdKS5maW5kKChpdGVtKSA9PiBpdGVtLnByb2R1Y3RJZCA9PT0gcHJvZHVjdElkKSB8fCB7cHJvZHVjdElkfTtcbiAgICBjb25zdCBwcm9kdWN0S2V5ID0gZXh0ZXJuYWxLZXkoJ3Nob3BpZnktcHJvZHVjdCcsIHByb2R1Y3RJZCk7XG4gICAgY29uc3QgcHJvZHVjdERvYyA9IHtcbiAgICAgIF9rZXk6IHByb2R1Y3RLZXksXG4gICAgICBhZGRlZDogdGltZXN0YW1wLFxuICAgICAgbW9kaWZpZWQ6IHRpbWVzdGFtcCxcbiAgICAgIHByb2R1Y3RJZCxcbiAgICAgIHRpdGxlOiBjbGVhblN0cmluZyhwcm9kdWN0LnRpdGxlLCAzMjApLFxuICAgICAgdmFyaWFudElkOiBjbGVhbkV4dGVybmFsSWQocHJvZHVjdC52YXJpYW50SWQsIDE2MClcbiAgICB9O1xuICAgIGNvbnN0IHByb2R1Y3RRdWVyeSA9IGFxbGBcbiAgICAgIFVQU0VSVCB7X2tleTogJHtwcm9kdWN0S2V5fX1cbiAgICAgIElOU0VSVCAke3Byb2R1Y3REb2N9XG4gICAgICBVUERBVEUgJHt7XG4gICAgICAgIG1vZGlmaWVkOiB0aW1lc3RhbXAsXG4gICAgICAgIHRpdGxlOiBwcm9kdWN0RG9jLnRpdGxlLFxuICAgICAgICB2YXJpYW50SWQ6IHByb2R1Y3REb2MudmFyaWFudElkXG4gICAgICB9fSBJTiAke2NvbGxlY3Rpb24oQ09MTEVDVElPTlMuU0hPUElGWV9QUk9EVUNUUyl9XG4gICAgYDtcbiAgICBhd2FpdCB1c2VEYihjb250ZXh0LmRhdGFiYXNlTmFtZSkucXVlcnkocHJvZHVjdFF1ZXJ5KTtcbiAgICBhd2FpdCBzYXZlRWRnZShcbiAgICAgIGNvbnRleHQsXG4gICAgICBFREdFUy5IQVNfUFVSQ0hBU0VEX1BST0RVQ1QsXG4gICAgICBjcmVhdGVIYXNoKGBoYXNQdXJjaGFzZWRQcm9kdWN0LSR7b3JkZXJLZXl9LSR7cHJvZHVjdEtleX1gKSxcbiAgICAgIGRvY0lkKENPTExFQ1RJT05TLkNVU1RPTUVSX09SREVSUywgb3JkZXJLZXkpLFxuICAgICAgZG9jSWQoQ09MTEVDVElPTlMuU0hPUElGWV9QUk9EVUNUUywgcHJvZHVjdEtleSksXG4gICAgICB7cHJvZHVjdElkLCBwdXJjaGFzZWRBdDogb3JkZXIucHVyY2hhc2VkQXR9XG4gICAgKTtcbiAgfSkpO1xuXG4gIGF3YWl0IHVzZURiKGNvbnRleHQuZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxgXG4gICAgVVBEQVRFICR7cmVzb2x2ZWRVc2VyS2V5fVxuICAgIFdJVEgge1xuICAgICAgbGFzdFB1cmNoYXNlZEF0OiAke29yZGVyLnB1cmNoYXNlZEF0fSxcbiAgICAgIHRvdGFsT3JkZXJDb3VudDogTEVOR1RIKFxuICAgICAgICBGT1Igb3JkZXIgSU4gMS4uMSBPVVRCT1VORCAke2RvY0lkKENPTExFQ1RJT05TLlVTRVJTLCByZXNvbHZlZFVzZXJLZXkpfSAke2NvbGxlY3Rpb24oRURHRVMuSEFTX0NVU1RPTUVSX09SREVSKX1cbiAgICAgICAgICBSRVRVUk4gb3JkZXJcbiAgICAgICksXG4gICAgICB0b3RhbFNwZW5kOiBTVU0oXG4gICAgICAgIEZPUiBvcmRlciBJTiAxLi4xIE9VVEJPVU5EICR7ZG9jSWQoQ09MTEVDVElPTlMuVVNFUlMsIHJlc29sdmVkVXNlcktleSl9ICR7Y29sbGVjdGlvbihFREdFUy5IQVNfQ1VTVE9NRVJfT1JERVIpfVxuICAgICAgICAgIFJFVFVSTiBUT19OVU1CRVIob3JkZXIudG90YWxQcmljZSlcbiAgICAgIClcbiAgICB9IElOICR7Y29sbGVjdGlvbihDT0xMRUNUSU9OUy5VU0VSUyl9XG4gIGApO1xuXG4gIHJldHVybiBzYXZlZE9yZGVyO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEN1c3RvbWVyT3JkZXJzQnlVc2VyID0gKFxuICBjb250ZXh0OiBBcGlDb250ZXh0LFxuICB1c2VySWQ6IHN0cmluZ1xuKTogUHJvbWlzZTxDdXN0b21lck9yZGVyVHlwZVtdPiA9PiB7XG4gIGNvbnN0IHF1ZXJ5ID0gYXFsYFxuICAgIEZPUiBvcmRlciBJTiAxLi4xIE9VVEJPVU5EICR7ZG9jSWQoQ09MTEVDVElPTlMuVVNFUlMsIHVzZXJJZCl9ICR7Y29sbGVjdGlvbihFREdFUy5IQVNfQ1VTVE9NRVJfT1JERVIpfVxuICAgICAgU09SVCBvcmRlci5wdXJjaGFzZWRBdCBERVNDXG4gICAgICBSRVRVUk4gb3JkZXJcbiAgYDtcblxuICByZXR1cm4gdXNlRGIoY29udGV4dC5kYXRhYmFzZU5hbWUpLnF1ZXJ5KHF1ZXJ5KS50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSk7XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlU3VwcG9ydFRpY2tldCA9IGFzeW5jIChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgaW5wdXQ6IFBhcnRpYWw8U3VwcG9ydFRpY2tldFR5cGVEYXRhPlxuKTogUHJvbWlzZTxTdXBwb3J0VGlja2V0VHlwZURhdGE+ID0+IHtcbiAgY29uc3QgdGltZXN0YW1wID0gbm93KCk7XG4gIGNvbnN0IHVzZXJLZXkgPSBkb2NLZXkoU3RyaW5nKGlucHV0LnVzZXJJZCB8fCAnJykpO1xuICBjb25zdCB0aWNrZXRLZXkgPSBkb2NLZXkoU3RyaW5nKGlucHV0LnN1cHBvcnRUaWNrZXRJZCB8fCBjcmVhdGVIYXNoKGBzdXBwb3J0LXRpY2tldC0ke3VzZXJLZXl9LSR7dGltZXN0YW1wfWApKSk7XG4gIGNvbnN0IHRpY2tldCA9IHtcbiAgICBfa2V5OiB0aWNrZXRLZXksXG4gICAgYWRkZWQ6IHRpbWVzdGFtcCxcbiAgICBhc3NpZ25lZFRvVXNlcklkOiBkb2NLZXkoU3RyaW5nKGlucHV0LmFzc2lnbmVkVG9Vc2VySWQgfHwgJycpKSxcbiAgICBkZXNjcmlwdGlvbjogY2xlYW5TdHJpbmcoaW5wdXQuZGVzY3JpcHRpb24sIDQwMDApLFxuICAgIG1vZGlmaWVkOiB0aW1lc3RhbXAsXG4gICAgcHJpb3JpdHk6IGlucHV0LnByaW9yaXR5IHx8ICdub3JtYWwnLFxuICAgIHByb2R1Y3RJZDogY2xlYW5FeHRlcm5hbElkKGlucHV0LnByb2R1Y3RJZCwgMzIwKSxcbiAgICBzaG9waWZ5T3JkZXJJZDogY2xlYW5TdHJpbmcoaW5wdXQuc2hvcGlmeU9yZGVySWQsIDE2MCksXG4gICAgc3RhdHVzOiAnb3BlbicsXG4gICAgc3ViamVjdDogY2xlYW5TdHJpbmcoaW5wdXQuc3ViamVjdCwgMzIwKSxcbiAgICBzdXBwb3J0VGlja2V0SWQ6IHRpY2tldEtleSxcbiAgICB0eXBlOiBpbnB1dC50eXBlIHx8ICdnZW5lcmFsX3N1cHBvcnQnLFxuICAgIHVzZXJJZDogdXNlcktleVxuICB9O1xuICBjb25zdCBxdWVyeSA9IGFxbGBcbiAgICBJTlNFUlQgJHt0aWNrZXR9IElOICR7Y29sbGVjdGlvbihDT0xMRUNUSU9OUy5TVVBQT1JUX1RJQ0tFVFMpfVxuICAgIFJFVFVSTiBORVdcbiAgYDtcbiAgY29uc3Qgc2F2ZWRUaWNrZXQgPSBhd2FpdCB1c2VEYihjb250ZXh0LmRhdGFiYXNlTmFtZSkucXVlcnkocXVlcnkpLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSk7XG5cbiAgYXdhaXQgc2F2ZUVkZ2UoXG4gICAgY29udGV4dCxcbiAgICBFREdFUy5IQVNfU1VQUE9SVF9USUNLRVQsXG4gICAgY3JlYXRlSGFzaChgaGFzU3VwcG9ydFRpY2tldC0ke3VzZXJLZXl9LSR7dGlja2V0S2V5fWApLFxuICAgIGRvY0lkKENPTExFQ1RJT05TLlVTRVJTLCB1c2VyS2V5KSxcbiAgICBkb2NJZChDT0xMRUNUSU9OUy5TVVBQT1JUX1RJQ0tFVFMsIHRpY2tldEtleSksXG4gICAge3ByaW9yaXR5OiB0aWNrZXQucHJpb3JpdHksIHN0YXR1czogdGlja2V0LnN0YXR1cywgdHlwZTogdGlja2V0LnR5cGV9XG4gICk7XG4gIGF3YWl0IGFkZFN1cHBvcnRUaWNrZXRFdmVudChjb250ZXh0LCB7XG4gICAgYWN0b3JVc2VySWQ6IGRvY0tleShTdHJpbmcoY29udGV4dD8uc2Vzc2lvbj8udXNlcklkIHx8IHVzZXJLZXkpKSxcbiAgICBldmVudFR5cGU6ICdjcmVhdGVkJyxcbiAgICBzdXBwb3J0VGlja2V0SWQ6IHRpY2tldEtleSxcbiAgICB0b1ZhbHVlOiB0aWNrZXQuc3RhdHVzXG4gIH0pO1xuXG4gIHJldHVybiBzYXZlZFRpY2tldDtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRTdXBwb3J0VGlja2V0cyA9IChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgZmlsdGVyczoge3JlYWRvbmx5IHN0YXR1cz86IHN0cmluZzsgcmVhZG9ubHkgdXNlcklkPzogc3RyaW5nfSA9IHt9XG4pOiBQcm9taXNlPFN1cHBvcnRUaWNrZXRUeXBlRGF0YVtdPiA9PiB7XG4gIGNvbnN0IHF1ZXJ5ID0gYXFsYFxuICAgIEZPUiB0aWNrZXQgSU4gJHtjb2xsZWN0aW9uKENPTExFQ1RJT05TLlNVUFBPUlRfVElDS0VUUyl9XG4gICAgICAke2ZpbHRlcnMuc3RhdHVzID8gYXFsYEZJTFRFUiB0aWNrZXQuc3RhdHVzID09ICR7ZmlsdGVycy5zdGF0dXN9YCA6IGFxbGBgfVxuICAgICAgJHtmaWx0ZXJzLnVzZXJJZCA/IGFxbGBGSUxURVIgdGlja2V0LnVzZXJJZCA9PSAke2RvY0tleShmaWx0ZXJzLnVzZXJJZCl9YCA6IGFxbGBgfVxuICAgICAgTEVUIHVzZXIgPSBET0NVTUVOVCgke0NPTExFQ1RJT05TLlVTRVJTfSwgdGlja2V0LnVzZXJJZClcbiAgICAgIFNPUlQgdGlja2V0LmFkZGVkIERFU0NcbiAgICAgIFJFVFVSTiBNRVJHRSh0aWNrZXQsIHt1c2VyfSlcbiAgYDtcblxuICByZXR1cm4gdXNlRGIoY29udGV4dC5kYXRhYmFzZU5hbWUpLnF1ZXJ5KHF1ZXJ5KS50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSk7XG59O1xuXG5leHBvcnQgY29uc3QgdXBkYXRlU3VwcG9ydFRpY2tldFN0YXR1cyA9IGFzeW5jIChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgc3VwcG9ydFRpY2tldElkOiBzdHJpbmcsXG4gIHN0YXR1czogU3VwcG9ydFRpY2tldFN0YXR1cyxcbiAgcmVzb2x1dGlvblN1bW1hcnkgPSAnJ1xuKTogUHJvbWlzZTxTdXBwb3J0VGlja2V0VHlwZURhdGE+ID0+IHtcbiAgY29uc3QgdGlja2V0S2V5ID0gZG9jS2V5KHN1cHBvcnRUaWNrZXRJZCk7XG4gIGNvbnN0IHRpbWVzdGFtcCA9IG5vdygpO1xuICBjb25zdCBwcmV2aW91cyA9IGF3YWl0IHVzZURiKGNvbnRleHQuZGF0YWJhc2VOYW1lKVxuICAgIC5xdWVyeShhcWxgUkVUVVJOIERPQ1VNRU5UKCR7ZG9jSWQoQ09MTEVDVElPTlMuU1VQUE9SVF9USUNLRVRTLCB0aWNrZXRLZXkpfSlgKVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpIGFzIFN1cHBvcnRUaWNrZXRUeXBlRGF0YSB8IG51bGw7XG4gIGNvbnN0IHVwZGF0ZSA9IHtcbiAgICAuLi4oc3RhdHVzID09PSAncmVzb2x2ZWQnICYmIHtyZXNvbHZlZEF0OiB0aW1lc3RhbXAsIHJlc29sdXRpb25TdW1tYXJ5OiBjbGVhblN0cmluZyhyZXNvbHV0aW9uU3VtbWFyeSwgNDAwMCl9KSxcbiAgICAuLi4oc3RhdHVzID09PSAnY2xvc2VkJyAmJiB7Y2xvc2VkQXQ6IHRpbWVzdGFtcH0pLFxuICAgIG1vZGlmaWVkOiB0aW1lc3RhbXAsXG4gICAgc3RhdHVzXG4gIH07XG4gIGNvbnN0IHF1ZXJ5ID0gYXFsYFxuICAgIFVQREFURSAke3RpY2tldEtleX0gV0lUSCAke3VwZGF0ZX0gSU4gJHtjb2xsZWN0aW9uKENPTExFQ1RJT05TLlNVUFBPUlRfVElDS0VUUyl9XG4gICAgUkVUVVJOIE5FV1xuICBgO1xuICBjb25zdCB0aWNrZXQgPSBhd2FpdCB1c2VEYihjb250ZXh0LmRhdGFiYXNlTmFtZSkucXVlcnkocXVlcnkpLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSkgYXMgU3VwcG9ydFRpY2tldFR5cGVEYXRhO1xuXG4gIGF3YWl0IHVzZURiKGNvbnRleHQuZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxgXG4gICAgRk9SIGVkZ2UgSU4gJHtjb2xsZWN0aW9uKEVER0VTLkhBU19TVVBQT1JUX1RJQ0tFVCl9XG4gICAgICBGSUxURVIgZWRnZS5fdG8gPT0gJHtkb2NJZChDT0xMRUNUSU9OUy5TVVBQT1JUX1RJQ0tFVFMsIHRpY2tldEtleSl9XG4gICAgICBVUERBVEUgZWRnZSBXSVRIICR7e1xuICAgICAgICBtb2RpZmllZDogdGltZXN0YW1wLFxuICAgICAgICByZXNvbHZlZEF0OiBzdGF0dXMgPT09ICdyZXNvbHZlZCcgPyB0aW1lc3RhbXAgOiB1bmRlZmluZWQsXG4gICAgICAgIHN0YXR1c1xuICAgICAgfX0gSU4gJHtjb2xsZWN0aW9uKEVER0VTLkhBU19TVVBQT1JUX1RJQ0tFVCl9XG4gIGApO1xuICBhd2FpdCBhZGRTdXBwb3J0VGlja2V0RXZlbnQoY29udGV4dCwge1xuICAgIGFjdG9yVXNlcklkOiBkb2NLZXkoU3RyaW5nKGNvbnRleHQ/LnNlc3Npb24/LnVzZXJJZCB8fCAnJykpLFxuICAgIGV2ZW50VHlwZTogJ3N0YXR1c19jaGFuZ2VkJyxcbiAgICBmcm9tVmFsdWU6IHByZXZpb3VzPy5zdGF0dXMsXG4gICAgc3VwcG9ydFRpY2tldElkOiB0aWNrZXRLZXksXG4gICAgdG9WYWx1ZTogc3RhdHVzXG4gIH0pO1xuXG4gIGlmKHN0YXR1cyA9PT0gJ3Jlc29sdmVkJykge1xuICAgIGF3YWl0IGNyZWF0ZUN1c3RvbWVyTm90aWZpY2F0aW9uKGNvbnRleHQsIHtcbiAgICAgIGJvZHk6IGNsZWFuU3RyaW5nKHJlc29sdXRpb25TdW1tYXJ5IHx8ICdZb3VyIHN1cHBvcnQgdGlja2V0IGhhcyBiZWVuIHJlc29sdmVkLicsIDQwMDApLFxuICAgICAgc3RhdHVzOiAncXVldWVkJyxcbiAgICAgIHN1YmplY3Q6IGBSZXNvbHZlZDogJHt0aWNrZXQuc3ViamVjdCB8fCAnU3VwcG9ydCB0aWNrZXQnfWAsXG4gICAgICBzdXBwb3J0VGlja2V0SWQ6IHRpY2tldEtleSxcbiAgICAgIHR5cGU6ICdzdXBwb3J0X3RpY2tldF9yZXNvbHZlZCcsXG4gICAgICB1c2VySWQ6IHRpY2tldC51c2VySWRcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiB0aWNrZXQ7XG59O1xuXG5leHBvcnQgY29uc3QgYWRkU3VwcG9ydFRpY2tldE1lc3NhZ2UgPSBhc3luYyAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIGlucHV0OiBQYXJ0aWFsPFN1cHBvcnRUaWNrZXRNZXNzYWdlVHlwZT5cbik6IFByb21pc2U8U3VwcG9ydFRpY2tldE1lc3NhZ2VUeXBlPiA9PiB7XG4gIGNvbnN0IHRpbWVzdGFtcCA9IG5vdygpO1xuICBjb25zdCB0aWNrZXRLZXkgPSBkb2NLZXkoU3RyaW5nKGlucHV0LnN1cHBvcnRUaWNrZXRJZCB8fCAnJykpO1xuICBjb25zdCBtZXNzYWdlS2V5ID0gZG9jS2V5KFN0cmluZyhpbnB1dC5zdXBwb3J0VGlja2V0TWVzc2FnZUlkIHx8IGNyZWF0ZUhhc2goYHN1cHBvcnQtdGlja2V0LW1lc3NhZ2UtJHt0aWNrZXRLZXl9LSR7dGltZXN0YW1wfWApKSk7XG4gIGNvbnN0IG1lc3NhZ2UgPSB7XG4gICAgX2tleTogbWVzc2FnZUtleSxcbiAgICBhZGRlZDogdGltZXN0YW1wLFxuICAgIGF1dGhvclVzZXJJZDogZG9jS2V5KFN0cmluZyhpbnB1dC5hdXRob3JVc2VySWQgfHwgY29udGV4dD8uc2Vzc2lvbj8udXNlcklkIHx8ICcnKSksXG4gICAgYm9keTogY2xlYW5TdHJpbmcoaW5wdXQuYm9keSwgNDAwMCksXG4gICAgbW9kaWZpZWQ6IHRpbWVzdGFtcCxcbiAgICBzdXBwb3J0VGlja2V0SWQ6IHRpY2tldEtleSxcbiAgICBzdXBwb3J0VGlja2V0TWVzc2FnZUlkOiBtZXNzYWdlS2V5LFxuICAgIHZpc2liaWxpdHk6IGlucHV0LnZpc2liaWxpdHkgfHwgJ2N1c3RvbWVyJ1xuICB9O1xuICBjb25zdCBxdWVyeSA9IGFxbGBcbiAgICBJTlNFUlQgJHttZXNzYWdlfSBJTiAke2NvbGxlY3Rpb24oQ09MTEVDVElPTlMuU1VQUE9SVF9USUNLRVRfTUVTU0FHRVMpfVxuICAgIFJFVFVSTiBORVdcbiAgYDtcbiAgY29uc3Qgc2F2ZWRNZXNzYWdlID0gYXdhaXQgdXNlRGIoY29udGV4dC5kYXRhYmFzZU5hbWUpLnF1ZXJ5KHF1ZXJ5KS50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpO1xuXG4gIGF3YWl0IHNhdmVFZGdlKFxuICAgIGNvbnRleHQsXG4gICAgRURHRVMuSEFTX1NVUFBPUlRfVElDS0VUX01FU1NBR0UsXG4gICAgY3JlYXRlSGFzaChgaGFzU3VwcG9ydFRpY2tldE1lc3NhZ2UtJHt0aWNrZXRLZXl9LSR7bWVzc2FnZUtleX1gKSxcbiAgICBkb2NJZChDT0xMRUNUSU9OUy5TVVBQT1JUX1RJQ0tFVFMsIHRpY2tldEtleSksXG4gICAgZG9jSWQoQ09MTEVDVElPTlMuU1VQUE9SVF9USUNLRVRfTUVTU0FHRVMsIG1lc3NhZ2VLZXkpLFxuICAgIHthdXRob3JVc2VySWQ6IG1lc3NhZ2UuYXV0aG9yVXNlcklkLCB2aXNpYmlsaXR5OiBtZXNzYWdlLnZpc2liaWxpdHl9XG4gICk7XG5cbiAgcmV0dXJuIHNhdmVkTWVzc2FnZTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRTdXBwb3J0VGlja2V0TWVzc2FnZXMgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHN1cHBvcnRUaWNrZXRJZDogc3RyaW5nXG4pOiBQcm9taXNlPFN1cHBvcnRUaWNrZXRNZXNzYWdlVHlwZVtdPiA9PiB7XG4gIGNvbnN0IHF1ZXJ5ID0gYXFsYFxuICAgIEZPUiBtZXNzYWdlIElOIDEuLjEgT1VUQk9VTkQgJHtkb2NJZChDT0xMRUNUSU9OUy5TVVBQT1JUX1RJQ0tFVFMsIHN1cHBvcnRUaWNrZXRJZCl9ICR7Y29sbGVjdGlvbihFREdFUy5IQVNfU1VQUE9SVF9USUNLRVRfTUVTU0FHRSl9XG4gICAgICBTT1JUIG1lc3NhZ2UuYWRkZWQgQVNDXG4gICAgICBSRVRVUk4gbWVzc2FnZVxuICBgO1xuXG4gIHJldHVybiB1c2VEYihjb250ZXh0LmRhdGFiYXNlTmFtZSkucXVlcnkocXVlcnkpLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpKTtcbn07XG5cbmV4cG9ydCBjb25zdCBhZGRTdXBwb3J0VGlja2V0RXZlbnQgPSBhc3luYyAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIGlucHV0OiBQYXJ0aWFsPFN1cHBvcnRUaWNrZXRFdmVudFR5cGU+XG4pOiBQcm9taXNlPFN1cHBvcnRUaWNrZXRFdmVudFR5cGU+ID0+IHtcbiAgY29uc3QgdGltZXN0YW1wID0gbm93KCk7XG4gIGNvbnN0IHRpY2tldEtleSA9IGRvY0tleShTdHJpbmcoaW5wdXQuc3VwcG9ydFRpY2tldElkIHx8ICcnKSk7XG4gIGNvbnN0IGV2ZW50S2V5ID0gZG9jS2V5KFN0cmluZyhpbnB1dC5zdXBwb3J0VGlja2V0RXZlbnRJZCB8fCBjcmVhdGVIYXNoKGBzdXBwb3J0LXRpY2tldC1ldmVudC0ke3RpY2tldEtleX0tJHt0aW1lc3RhbXB9LSR7aW5wdXQuZXZlbnRUeXBlfWApKSk7XG4gIGNvbnN0IGV2ZW50ID0ge1xuICAgIF9rZXk6IGV2ZW50S2V5LFxuICAgIGFkZGVkOiB0aW1lc3RhbXAsXG4gICAgYWN0b3JVc2VySWQ6IGRvY0tleShTdHJpbmcoaW5wdXQuYWN0b3JVc2VySWQgfHwgJycpKSxcbiAgICBldmVudFR5cGU6IGNsZWFuU3RyaW5nKGlucHV0LmV2ZW50VHlwZSwgMTYwKSxcbiAgICBmcm9tVmFsdWU6IGNsZWFuU3RyaW5nKGlucHV0LmZyb21WYWx1ZSwgMzIwKSxcbiAgICBtZXRhZGF0YTogaW5wdXQubWV0YWRhdGEgfHwge30sXG4gICAgbW9kaWZpZWQ6IHRpbWVzdGFtcCxcbiAgICBzdXBwb3J0VGlja2V0RXZlbnRJZDogZXZlbnRLZXksXG4gICAgc3VwcG9ydFRpY2tldElkOiB0aWNrZXRLZXksXG4gICAgdG9WYWx1ZTogY2xlYW5TdHJpbmcoaW5wdXQudG9WYWx1ZSwgMzIwKVxuICB9O1xuICBjb25zdCBxdWVyeSA9IGFxbGBcbiAgICBJTlNFUlQgJHtldmVudH0gSU4gJHtjb2xsZWN0aW9uKENPTExFQ1RJT05TLlNVUFBPUlRfVElDS0VUX0VWRU5UUyl9XG4gICAgUkVUVVJOIE5FV1xuICBgO1xuICBjb25zdCBzYXZlZEV2ZW50ID0gYXdhaXQgdXNlRGIoY29udGV4dC5kYXRhYmFzZU5hbWUpLnF1ZXJ5KHF1ZXJ5KS50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpO1xuXG4gIGF3YWl0IHNhdmVFZGdlKFxuICAgIGNvbnRleHQsXG4gICAgRURHRVMuSEFTX1NVUFBPUlRfVElDS0VUX0VWRU5ULFxuICAgIGNyZWF0ZUhhc2goYGhhc1N1cHBvcnRUaWNrZXRFdmVudC0ke3RpY2tldEtleX0tJHtldmVudEtleX1gKSxcbiAgICBkb2NJZChDT0xMRUNUSU9OUy5TVVBQT1JUX1RJQ0tFVFMsIHRpY2tldEtleSksXG4gICAgZG9jSWQoQ09MTEVDVElPTlMuU1VQUE9SVF9USUNLRVRfRVZFTlRTLCBldmVudEtleSksXG4gICAge2FjdG9yVXNlcklkOiBldmVudC5hY3RvclVzZXJJZCwgZXZlbnRUeXBlOiBldmVudC5ldmVudFR5cGV9XG4gICk7XG5cbiAgcmV0dXJuIHNhdmVkRXZlbnQ7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0U3VwcG9ydFRpY2tldEV2ZW50cyA9IChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgc3VwcG9ydFRpY2tldElkOiBzdHJpbmdcbik6IFByb21pc2U8U3VwcG9ydFRpY2tldEV2ZW50VHlwZVtdPiA9PiB7XG4gIGNvbnN0IHF1ZXJ5ID0gYXFsYFxuICAgIEZPUiBldmVudCBJTiAxLi4xIE9VVEJPVU5EICR7ZG9jSWQoQ09MTEVDVElPTlMuU1VQUE9SVF9USUNLRVRTLCBzdXBwb3J0VGlja2V0SWQpfSAke2NvbGxlY3Rpb24oRURHRVMuSEFTX1NVUFBPUlRfVElDS0VUX0VWRU5UKX1cbiAgICAgIFNPUlQgZXZlbnQuYWRkZWQgQVNDXG4gICAgICBSRVRVUk4gZXZlbnRcbiAgYDtcblxuICByZXR1cm4gdXNlRGIoY29udGV4dC5kYXRhYmFzZU5hbWUpLnF1ZXJ5KHF1ZXJ5KS50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSk7XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlQ3VzdG9tZXJOb3RpZmljYXRpb24gPSBhc3luYyAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIGlucHV0OiBQYXJ0aWFsPEN1c3RvbWVyTm90aWZpY2F0aW9uVHlwZT5cbik6IFByb21pc2U8Q3VzdG9tZXJOb3RpZmljYXRpb25UeXBlPiA9PiB7XG4gIGNvbnN0IHRpbWVzdGFtcCA9IG5vdygpO1xuICBjb25zdCB1c2VyS2V5ID0gZG9jS2V5KFN0cmluZyhpbnB1dC51c2VySWQgfHwgJycpKTtcbiAgY29uc3Qgbm90aWZpY2F0aW9uS2V5ID0gZG9jS2V5KFN0cmluZyhpbnB1dC5jdXN0b21lck5vdGlmaWNhdGlvbklkIHx8IGNyZWF0ZUhhc2goYGN1c3RvbWVyLW5vdGlmaWNhdGlvbi0ke3VzZXJLZXl9LSR7dGltZXN0YW1wfWApKSk7XG4gIGNvbnN0IG5vdGlmaWNhdGlvbiA9IHtcbiAgICBfa2V5OiBub3RpZmljYXRpb25LZXksXG4gICAgYWRkZWQ6IHRpbWVzdGFtcCxcbiAgICBib2R5OiBjbGVhblN0cmluZyhpbnB1dC5ib2R5LCA0MDAwKSxcbiAgICBjdXN0b21lck5vdGlmaWNhdGlvbklkOiBub3RpZmljYXRpb25LZXksXG4gICAgbW9kaWZpZWQ6IHRpbWVzdGFtcCxcbiAgICBzZW50QXQ6IGlucHV0LnNlbnRBdCxcbiAgICBzdGF0dXM6IGlucHV0LnN0YXR1cyB8fCAncXVldWVkJyxcbiAgICBzdWJqZWN0OiBjbGVhblN0cmluZyhpbnB1dC5zdWJqZWN0LCAzMjApLFxuICAgIHN1cHBvcnRUaWNrZXRJZDogZG9jS2V5KFN0cmluZyhpbnB1dC5zdXBwb3J0VGlja2V0SWQgfHwgJycpKSxcbiAgICB0eXBlOiBjbGVhblN0cmluZyhpbnB1dC50eXBlLCAxNjApLFxuICAgIHVzZXJJZDogdXNlcktleVxuICB9O1xuICBjb25zdCBxdWVyeSA9IGFxbGBcbiAgICBJTlNFUlQgJHtub3RpZmljYXRpb259IElOICR7Y29sbGVjdGlvbihDT0xMRUNUSU9OUy5DVVNUT01FUl9OT1RJRklDQVRJT05TKX1cbiAgICBSRVRVUk4gTkVXXG4gIGA7XG4gIGNvbnN0IHNhdmVkTm90aWZpY2F0aW9uID0gYXdhaXQgdXNlRGIoY29udGV4dC5kYXRhYmFzZU5hbWUpLnF1ZXJ5KHF1ZXJ5KS50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpO1xuXG4gIGF3YWl0IHNhdmVFZGdlKFxuICAgIGNvbnRleHQsXG4gICAgRURHRVMuSEFTX0NVU1RPTUVSX05PVElGSUNBVElPTixcbiAgICBjcmVhdGVIYXNoKGBoYXNDdXN0b21lck5vdGlmaWNhdGlvbi0ke3VzZXJLZXl9LSR7bm90aWZpY2F0aW9uS2V5fWApLFxuICAgIGRvY0lkKENPTExFQ1RJT05TLlVTRVJTLCB1c2VyS2V5KSxcbiAgICBkb2NJZChDT0xMRUNUSU9OUy5DVVNUT01FUl9OT1RJRklDQVRJT05TLCBub3RpZmljYXRpb25LZXkpLFxuICAgIHtcbiAgICAgIHN0YXR1czogbm90aWZpY2F0aW9uLnN0YXR1cyxcbiAgICAgIHN1cHBvcnRUaWNrZXRJZDogbm90aWZpY2F0aW9uLnN1cHBvcnRUaWNrZXRJZCxcbiAgICAgIHR5cGU6IG5vdGlmaWNhdGlvbi50eXBlXG4gICAgfVxuICApO1xuXG4gIHJldHVybiBzYXZlZE5vdGlmaWNhdGlvbjtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRDdXN0b21lck5vdGlmaWNhdGlvbnNCeVVzZXIgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHVzZXJJZDogc3RyaW5nXG4pOiBQcm9taXNlPEN1c3RvbWVyTm90aWZpY2F0aW9uVHlwZVtdPiA9PiB7XG4gIGNvbnN0IHF1ZXJ5ID0gYXFsYFxuICAgIEZPUiBub3RpZmljYXRpb24gSU4gMS4uMSBPVVRCT1VORCAke2RvY0lkKENPTExFQ1RJT05TLlVTRVJTLCB1c2VySWQpfSAke2NvbGxlY3Rpb24oRURHRVMuSEFTX0NVU1RPTUVSX05PVElGSUNBVElPTil9XG4gICAgICBTT1JUIG5vdGlmaWNhdGlvbi5hZGRlZCBERVNDXG4gICAgICBSRVRVUk4gbm90aWZpY2F0aW9uXG4gIGA7XG5cbiAgcmV0dXJuIHVzZURiKGNvbnRleHQuZGF0YWJhc2VOYW1lKS5xdWVyeShxdWVyeSkudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkpO1xufTtcbiJdLCJuYW1lcyI6WyJjcmVhdGVIYXNoIiwicGFyc2VJZCIsInBhcnNlU3RyaW5nIiwiYXFsIiwibGl0ZXJhbCIsIkNPTExFQ1RJT05TIiwiRURHRVMiLCJ1c2VEYiIsIm5vdyIsIkRhdGUiLCJjb2xsZWN0aW9uIiwibmFtZSIsImRvY0tleSIsInZhbHVlIiwiU3RyaW5nIiwiZG9jSWQiLCJjb2xsZWN0aW9uTmFtZSIsImtleSIsImV4dGVybmFsS2V5IiwicHJlZml4IiwiaWQiLCJjbGVhblN0cmluZyIsImxlbmd0aCIsImNsZWFuRXh0ZXJuYWxJZCIsInRyaW0iLCJzbGljZSIsInNhdmVFZGdlIiwiY29udGV4dCIsImVkZ2VDb2xsZWN0aW9uIiwiZWRnZUtleSIsImZyb20iLCJ0byIsImRhdGEiLCJ0aW1lc3RhbXAiLCJlZGdlIiwiX2Zyb20iLCJfa2V5IiwiX3RvIiwiYWRkZWQiLCJtb2RpZmllZCIsInF1ZXJ5IiwiZGF0YWJhc2VOYW1lIiwiY3JlYXRlTWFpbGluZ0xpc3QiLCJpbnB1dCIsIm1haWxpbmdMaXN0SWQiLCJtYWlsaW5nTGlzdCIsImNyZWF0ZWRCeVVzZXJJZCIsInNlc3Npb24iLCJ1c2VySWQiLCJkZXNjcmlwdGlvbiIsInN0YXR1cyIsIk1BSUxJTkdfTElTVFMiLCJ0aGVuIiwiY3Vyc29yIiwibmV4dCIsImdldE1haWxpbmdMaXN0cyIsImFsbCIsImFkZFVzZXJUb01haWxpbmdMaXN0Iiwic291cmNlIiwidXNlcktleSIsImxpc3RLZXkiLCJIQVNfTUFJTElOR19MSVNUIiwiVVNFUlMiLCJhZGRlZEJ5VXNlcklkIiwicmVtb3ZlVXNlckZyb21NYWlsaW5nTGlzdCIsInVwZGF0ZSIsInJlbW92ZWRBdCIsIkJvb2xlYW4iLCJnZXRNYWlsaW5nTGlzdFVzZXJzIiwibGlzdElkIiwiZ2V0VXNlcnNCeVB1cmNoYXNlZFByb2R1Y3QiLCJwcm9kdWN0SWQiLCJwcm9kdWN0S2V5IiwiU0hPUElGWV9QUk9EVUNUUyIsIkhBU19QVVJDSEFTRURfUFJPRFVDVCIsIkhBU19DVVNUT01FUl9PUkRFUiIsImdldEVsaWdpYmxlTWFpbGluZ1VzZXJzIiwib3B0aW9ucyIsImV4Y2x1ZGVPcGVuU3VwcG9ydFRpY2tldHMiLCJIQVNfU1VQUE9SVF9USUNLRVQiLCJpbmdlc3RTaG9waWZ5Q3VzdG9tZXJPcmRlciIsInNob3BpZnlDdXN0b21lcklkIiwic2hvcGlmeU9yZGVySWQiLCJjdXN0b21lciIsImVtYWlsIiwidG9Mb3dlckNhc2UiLCJwcm9kdWN0SWRzIiwiQXJyYXkiLCJTZXQiLCJwcm9kdWN0cyIsIm1hcCIsInByb2R1Y3QiLCJmaWx0ZXIiLCJFcnJvciIsInVzZXJJbnNlcnQiLCJmaXJzdE5hbWUiLCJsYXN0TmFtZSIsIm1hcmtldGluZ0NvbnNlbnRTb3VyY2UiLCJtYXJrZXRpbmdPcHRJbiIsIm1hcmtldGluZ09wdEluQXQiLCJ1bmRlZmluZWQiLCJ1c2VyVXBkYXRlIiwibGFzdFB1cmNoYXNlZEF0IiwicHVyY2hhc2VkQXQiLCJ1c2VyUXVlcnkiLCJ1c2VyIiwicmVzb2x2ZWRVc2VyS2V5Iiwib3JkZXJLZXkiLCJvcmRlciIsImN1cnJlbmN5IiwidG9VcHBlckNhc2UiLCJjdXN0b21lck9yZGVySWQiLCJ0b3RhbFByaWNlIiwiTnVtYmVyIiwib3JkZXJRdWVyeSIsIkNVU1RPTUVSX09SREVSUyIsInNhdmVkT3JkZXIiLCJQcm9taXNlIiwiZmluZCIsIml0ZW0iLCJwcm9kdWN0RG9jIiwidGl0bGUiLCJ2YXJpYW50SWQiLCJwcm9kdWN0UXVlcnkiLCJnZXRDdXN0b21lck9yZGVyc0J5VXNlciIsImNyZWF0ZVN1cHBvcnRUaWNrZXQiLCJ0aWNrZXRLZXkiLCJzdXBwb3J0VGlja2V0SWQiLCJ0aWNrZXQiLCJhc3NpZ25lZFRvVXNlcklkIiwicHJpb3JpdHkiLCJzdWJqZWN0IiwidHlwZSIsIlNVUFBPUlRfVElDS0VUUyIsInNhdmVkVGlja2V0IiwiYWRkU3VwcG9ydFRpY2tldEV2ZW50IiwiYWN0b3JVc2VySWQiLCJldmVudFR5cGUiLCJ0b1ZhbHVlIiwiZ2V0U3VwcG9ydFRpY2tldHMiLCJmaWx0ZXJzIiwidXBkYXRlU3VwcG9ydFRpY2tldFN0YXR1cyIsInJlc29sdXRpb25TdW1tYXJ5IiwicHJldmlvdXMiLCJyZXNvbHZlZEF0IiwiY2xvc2VkQXQiLCJmcm9tVmFsdWUiLCJjcmVhdGVDdXN0b21lck5vdGlmaWNhdGlvbiIsImJvZHkiLCJhZGRTdXBwb3J0VGlja2V0TWVzc2FnZSIsIm1lc3NhZ2VLZXkiLCJzdXBwb3J0VGlja2V0TWVzc2FnZUlkIiwibWVzc2FnZSIsImF1dGhvclVzZXJJZCIsInZpc2liaWxpdHkiLCJTVVBQT1JUX1RJQ0tFVF9NRVNTQUdFUyIsInNhdmVkTWVzc2FnZSIsIkhBU19TVVBQT1JUX1RJQ0tFVF9NRVNTQUdFIiwiZ2V0U3VwcG9ydFRpY2tldE1lc3NhZ2VzIiwiZXZlbnRLZXkiLCJzdXBwb3J0VGlja2V0RXZlbnRJZCIsImV2ZW50IiwibWV0YWRhdGEiLCJTVVBQT1JUX1RJQ0tFVF9FVkVOVFMiLCJzYXZlZEV2ZW50IiwiSEFTX1NVUFBPUlRfVElDS0VUX0VWRU5UIiwiZ2V0U3VwcG9ydFRpY2tldEV2ZW50cyIsIm5vdGlmaWNhdGlvbktleSIsImN1c3RvbWVyTm90aWZpY2F0aW9uSWQiLCJub3RpZmljYXRpb24iLCJzZW50QXQiLCJDVVNUT01FUl9OT1RJRklDQVRJT05TIiwic2F2ZWROb3RpZmljYXRpb24iLCJIQVNfQ1VTVE9NRVJfTk9USUZJQ0FUSU9OIiwiZ2V0Q3VzdG9tZXJOb3RpZmljYXRpb25zQnlVc2VyIl0sIm1hcHBpbmdzIjoiQUFBQTs7O0NBR0MsR0FDRCxTQUFRQSxVQUFVLEVBQUVDLE9BQU8sRUFBRUMsV0FBVyxRQUFPLCtCQUErQjtBQUM5RSxTQUFRQyxHQUFHLFFBQU8sV0FBVztBQUM3QixTQUFRQyxPQUFPLFFBQU8sZUFBZTtBQUVyQyxTQUFRQyxXQUFXLEVBQUVDLEtBQUssUUFBTyw4QkFBOEI7QUFDL0QsU0FBUUMsS0FBSyxRQUFPLDRCQUE0QjtBQWdCaEQsTUFBTUMsTUFBTSxJQUFjQyxLQUFLRCxHQUFHO0FBQ2xDLE1BQU1FLGFBQWEsQ0FBQ0Ms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