@nlabs/metropolisjs 0.1.2 → 0.2.0

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 (329) hide show
  1. package/.github/copilot-instructions.md +167 -0
  2. package/AGENTS.md +13 -0
  3. package/CHANGELOG.md +112 -0
  4. package/GRAPHQL_VALIDATION_RESULTS.md +158 -0
  5. package/PERMISSION_GRAPHQL_INTEGRATION.md +293 -0
  6. package/PERMISSION_IMPLEMENTATION_SUMMARY.md +243 -0
  7. package/README.md +1123 -112
  8. package/SIGNIN_GRAPHQL_VALIDATION.md +125 -0
  9. package/VAULT_GRAPHQL_API_FINDINGS.md +312 -0
  10. package/docs/ACTIONS.md +63 -0
  11. package/docs/COLLECTIONS.md +1038 -0
  12. package/docs/CONNECTIONS.md +1367 -0
  13. package/docs/CRUD_INTEGRATION.md +702 -0
  14. package/examples/connections-usage.tsx +909 -0
  15. package/examples/content-actions-usage.ts +144 -0
  16. package/examples/crud-usage.tsx +847 -0
  17. package/examples/extensibility-usage.tsx +889 -0
  18. package/examples/i18n-import-examples.ts +86 -0
  19. package/examples/i18n-namespace-usage.ts +118 -0
  20. package/examples/i18next-singleton-demo.ts +187 -0
  21. package/examples/permission-system-usage.tsx +415 -0
  22. package/examples/project-details.tsx +397 -0
  23. package/examples/shared-i18n-usage.tsx +203 -0
  24. package/examples/signup-error-handling.ts +100 -0
  25. package/examples/translation-types.ts +86 -0
  26. package/examples/translation-usage.tsx +336 -0
  27. package/index.js +1 -0
  28. package/jest.config.mjs +28 -0
  29. package/lex.config.mjs +11 -2
  30. package/lib/__tests__/e2e/helpers/testGraphQLServer.d.ts +22 -0
  31. package/lib/__tests__/e2e/helpers/testGraphQLServer.d.ts.map +1 -0
  32. package/lib/__tests__/e2e/helpers/testGraphQLServer.js +197 -0
  33. package/lib/__tests__/e2e/helpers/testGraphQLServerSimple.d.ts +3 -0
  34. package/lib/__tests__/e2e/helpers/testGraphQLServerSimple.d.ts.map +1 -0
  35. package/lib/__tests__/e2e/helpers/testGraphQLServerSimple.js +52 -0
  36. package/lib/actions/appActions/appActions.d.ts +29 -0
  37. package/lib/actions/appActions/appActions.d.ts.map +1 -0
  38. package/lib/actions/appActions/appActions.js +159 -0
  39. package/lib/actions/connectionActions/connectionActions.d.ts +19 -0
  40. package/lib/actions/connectionActions/connectionActions.d.ts.map +1 -0
  41. package/lib/actions/connectionActions/connectionActions.js +131 -0
  42. package/lib/actions/contentActions/contentActions.d.ts +34 -0
  43. package/lib/actions/contentActions/contentActions.d.ts.map +1 -0
  44. package/lib/actions/contentActions/contentActions.js +314 -0
  45. package/lib/actions/conversationActions/conversationActions.d.ts +30 -0
  46. package/lib/actions/conversationActions/conversationActions.d.ts.map +1 -0
  47. package/lib/actions/conversationActions/conversationActions.js +225 -0
  48. package/lib/actions/eventActions/eventActions.d.ts +27 -7
  49. package/lib/actions/eventActions/eventActions.d.ts.map +1 -0
  50. package/lib/actions/eventActions/eventActions.js +436 -2
  51. package/lib/actions/groupActions/groupActions.d.ts +30 -0
  52. package/lib/actions/groupActions/groupActions.d.ts.map +1 -0
  53. package/lib/actions/groupActions/groupActions.js +229 -0
  54. package/lib/actions/imageActions/imageActions.d.ts +16 -10
  55. package/lib/actions/imageActions/imageActions.d.ts.map +1 -0
  56. package/lib/actions/imageActions/imageActions.js +593 -2
  57. package/lib/actions/index.d.ts +21 -9
  58. package/lib/actions/index.d.ts.map +1 -0
  59. package/lib/actions/index.js +22 -2
  60. package/lib/actions/locationActions/locationActions.d.ts +11 -9
  61. package/lib/actions/locationActions/locationActions.d.ts.map +1 -0
  62. package/lib/actions/locationActions/locationActions.js +388 -2
  63. package/lib/actions/messageActions/messageActions.d.ts +16 -32
  64. package/lib/actions/messageActions/messageActions.d.ts.map +1 -0
  65. package/lib/actions/messageActions/messageActions.js +235 -2
  66. package/lib/actions/permissionActions/permissionActions.d.ts +34 -0
  67. package/lib/actions/permissionActions/permissionActions.d.ts.map +1 -0
  68. package/lib/actions/permissionActions/permissionActions.js +330 -0
  69. package/lib/actions/personaActions/personaActions.d.ts +65 -0
  70. package/lib/actions/personaActions/personaActions.d.ts.map +1 -0
  71. package/lib/actions/personaActions/personaActions.js +572 -0
  72. package/lib/actions/postActions/postActions.d.ts +12 -32
  73. package/lib/actions/postActions/postActions.d.ts.map +1 -0
  74. package/lib/actions/postActions/postActions.js +447 -2
  75. package/lib/actions/reactionActions/reactionActions.d.ts +13 -27
  76. package/lib/actions/reactionActions/reactionActions.d.ts.map +1 -0
  77. package/lib/actions/reactionActions/reactionActions.js +413 -2
  78. package/lib/actions/sseActions/sseActions.d.ts +1 -0
  79. package/lib/actions/sseActions/sseActions.d.ts.map +1 -0
  80. package/lib/actions/sseActions/sseActions.js +148 -2
  81. package/lib/actions/subscriptionActions/subscriptionActions.d.ts +24 -0
  82. package/lib/actions/subscriptionActions/subscriptionActions.d.ts.map +1 -0
  83. package/lib/actions/subscriptionActions/subscriptionActions.js +329 -0
  84. package/lib/actions/tagActions/tagActions.d.ts +13 -31
  85. package/lib/actions/tagActions/tagActions.d.ts.map +1 -0
  86. package/lib/actions/tagActions/tagActions.js +347 -2
  87. package/lib/actions/translationActions/translationActions.d.ts +38 -0
  88. package/lib/actions/translationActions/translationActions.d.ts.map +1 -0
  89. package/lib/actions/translationActions/translationActions.js +189 -0
  90. package/lib/actions/userActions/userActions.d.ts +42 -95
  91. package/lib/actions/userActions/userActions.d.ts.map +1 -0
  92. package/lib/actions/userActions/userActions.js +844 -2
  93. package/lib/actions/videoActions/videoActions.d.ts +41 -0
  94. package/lib/actions/videoActions/videoActions.d.ts.map +1 -0
  95. package/lib/actions/videoActions/videoActions.js +532 -0
  96. package/lib/actions/websocketActions/websocketActions.d.ts +20 -21
  97. package/lib/actions/websocketActions/websocketActions.d.ts.map +1 -0
  98. package/lib/actions/websocketActions/websocketActions.js +377 -2
  99. package/lib/adapters/appAdapter/appAdapter.d.ts +8 -0
  100. package/lib/adapters/appAdapter/appAdapter.d.ts.map +1 -0
  101. package/lib/adapters/appAdapter/appAdapter.js +90 -0
  102. package/lib/adapters/arangoAdapter/arangoAdapter.d.ts +3 -2
  103. package/lib/adapters/arangoAdapter/arangoAdapter.d.ts.map +1 -0
  104. package/lib/adapters/arangoAdapter/arangoAdapter.js +75 -2
  105. package/lib/adapters/contentAdapter/contentAdapter.d.ts +3 -2
  106. package/lib/adapters/contentAdapter/contentAdapter.d.ts.map +1 -0
  107. package/lib/adapters/contentAdapter/contentAdapter.js +107 -2
  108. package/lib/adapters/conversationAdapter/conversationAdapter.d.ts +3 -2
  109. package/lib/adapters/conversationAdapter/conversationAdapter.d.ts.map +1 -0
  110. package/lib/adapters/conversationAdapter/conversationAdapter.js +75 -2
  111. package/lib/adapters/eventAdapter/eventAdapter.d.ts +5 -2
  112. package/lib/adapters/eventAdapter/eventAdapter.d.ts.map +1 -0
  113. package/lib/adapters/eventAdapter/eventAdapter.js +162 -2
  114. package/lib/adapters/fileAdapter/fileAdapter.d.ts +3 -2
  115. package/lib/adapters/fileAdapter/fileAdapter.d.ts.map +1 -0
  116. package/lib/adapters/fileAdapter/fileAdapter.js +118 -2
  117. package/lib/adapters/groupAdapter/groupAdapter.d.ts +28 -0
  118. package/lib/adapters/groupAdapter/groupAdapter.d.ts.map +1 -0
  119. package/lib/adapters/groupAdapter/groupAdapter.js +66 -0
  120. package/lib/adapters/imageAdapter/imageAdapter.d.ts +9 -2
  121. package/lib/adapters/imageAdapter/imageAdapter.d.ts.map +1 -0
  122. package/lib/adapters/imageAdapter/imageAdapter.js +134 -2
  123. package/lib/adapters/index.d.ts +34 -16
  124. package/lib/adapters/index.d.ts.map +1 -0
  125. package/lib/adapters/index.js +19 -2
  126. package/lib/adapters/locationAdapter/locationAdapter.d.ts +3 -2
  127. package/lib/adapters/locationAdapter/locationAdapter.d.ts.map +1 -0
  128. package/lib/adapters/locationAdapter/locationAdapter.js +95 -2
  129. package/lib/adapters/messageAdapter/messageAdapter.d.ts +23 -19
  130. package/lib/adapters/messageAdapter/messageAdapter.d.ts.map +1 -0
  131. package/lib/adapters/messageAdapter/messageAdapter.js +82 -2
  132. package/lib/adapters/permissionAdapter/permissionAdapter.d.ts +41 -0
  133. package/lib/adapters/permissionAdapter/permissionAdapter.d.ts.map +1 -0
  134. package/lib/adapters/permissionAdapter/permissionAdapter.js +120 -0
  135. package/lib/adapters/personaAdapter/personaAdapter.d.ts +28 -2
  136. package/lib/adapters/personaAdapter/personaAdapter.d.ts.map +1 -0
  137. package/lib/adapters/personaAdapter/personaAdapter.js +161 -2
  138. package/lib/adapters/postAdapter/postAdapter.d.ts +3 -2
  139. package/lib/adapters/postAdapter/postAdapter.d.ts.map +1 -0
  140. package/lib/adapters/postAdapter/postAdapter.js +115 -2
  141. package/lib/adapters/reactionAdapter/reactionAdapter.d.ts +5 -2
  142. package/lib/adapters/reactionAdapter/reactionAdapter.d.ts.map +1 -0
  143. package/lib/adapters/reactionAdapter/reactionAdapter.js +81 -2
  144. package/lib/adapters/reaktorAdapter/reaktorAdapter.d.ts +3 -2
  145. package/lib/adapters/reaktorAdapter/reaktorAdapter.d.ts.map +1 -0
  146. package/lib/adapters/reaktorAdapter/reaktorAdapter.js +58 -2
  147. package/lib/adapters/sessionAdapter/sessionAdapter.d.ts +3 -2
  148. package/lib/adapters/sessionAdapter/sessionAdapter.d.ts.map +1 -0
  149. package/lib/adapters/sessionAdapter/sessionAdapter.js +80 -2
  150. package/lib/adapters/tagAdapter/tagAdapter.d.ts +3 -2
  151. package/lib/adapters/tagAdapter/tagAdapter.d.ts.map +1 -0
  152. package/lib/adapters/tagAdapter/tagAdapter.js +98 -2
  153. package/lib/adapters/translationAdapter/translationAdapter.d.ts +21 -0
  154. package/lib/adapters/translationAdapter/translationAdapter.d.ts.map +1 -0
  155. package/lib/adapters/translationAdapter/translationAdapter.js +55 -0
  156. package/lib/adapters/userAdapter/userAdapter.d.ts +18 -6
  157. package/lib/adapters/userAdapter/userAdapter.d.ts.map +1 -0
  158. package/lib/adapters/userAdapter/userAdapter.js +302 -2
  159. package/lib/adapters/videoAdapter/videoAdapter.d.ts +8 -0
  160. package/lib/adapters/videoAdapter/videoAdapter.d.ts.map +1 -0
  161. package/lib/adapters/videoAdapter/videoAdapter.js +194 -0
  162. package/lib/config/index.d.ts +19 -6
  163. package/lib/config/index.d.ts.map +1 -0
  164. package/lib/config/index.js +97 -2
  165. package/lib/constants/Collections.d.ts +44 -0
  166. package/lib/constants/Collections.d.ts.map +1 -0
  167. package/lib/constants/Collections.js +40 -0
  168. package/lib/constants/MetropolisConstants.d.ts +1 -0
  169. package/lib/constants/MetropolisConstants.d.ts.map +1 -0
  170. package/lib/constants/MetropolisConstants.js +15 -2
  171. package/lib/graphql/message.d.ts +1 -0
  172. package/lib/graphql/message.d.ts.map +1 -0
  173. package/lib/graphql/message.js +6 -4
  174. package/lib/graphql/notification.d.ts +1 -0
  175. package/lib/graphql/notification.d.ts.map +1 -0
  176. package/lib/graphql/notification.js +6 -4
  177. package/lib/graphql/session.d.ts +1 -0
  178. package/lib/graphql/session.d.ts.map +1 -0
  179. package/lib/graphql/session.js +4 -3
  180. package/lib/index.d.ts +45 -22
  181. package/lib/index.d.ts.map +1 -0
  182. package/lib/index.js +248 -2
  183. package/lib/stores/appStore.d.ts +1 -0
  184. package/lib/stores/appStore.d.ts.map +1 -0
  185. package/lib/stores/appStore.js +23 -2
  186. package/lib/stores/contentStore.d.ts +36 -0
  187. package/lib/stores/contentStore.d.ts.map +1 -0
  188. package/lib/stores/contentStore.js +139 -0
  189. package/lib/stores/conversationStore.d.ts +38 -0
  190. package/lib/stores/conversationStore.d.ts.map +1 -0
  191. package/lib/stores/conversationStore.js +117 -0
  192. package/lib/stores/eventStore.d.ts +4 -1
  193. package/lib/stores/eventStore.d.ts.map +1 -0
  194. package/lib/stores/eventStore.js +47 -2
  195. package/lib/stores/groupStore.d.ts +37 -0
  196. package/lib/stores/groupStore.d.ts.map +1 -0
  197. package/lib/stores/groupStore.js +68 -0
  198. package/lib/stores/imageStore.d.ts +6 -1
  199. package/lib/stores/imageStore.d.ts.map +1 -0
  200. package/lib/stores/imageStore.js +53 -2
  201. package/lib/stores/index.d.ts +20 -11
  202. package/lib/stores/index.d.ts.map +1 -0
  203. package/lib/stores/index.js +24 -2
  204. package/lib/stores/locationStore.d.ts +2 -1
  205. package/lib/stores/locationStore.d.ts.map +1 -0
  206. package/lib/stores/locationStore.js +42 -2
  207. package/lib/stores/messageStore.d.ts +19 -4
  208. package/lib/stores/messageStore.d.ts.map +1 -0
  209. package/lib/stores/messageStore.js +137 -2
  210. package/lib/stores/notificationStore.d.ts +33 -0
  211. package/lib/stores/notificationStore.d.ts.map +1 -0
  212. package/lib/stores/notificationStore.js +55 -0
  213. package/lib/stores/permissionStore.d.ts +37 -0
  214. package/lib/stores/permissionStore.d.ts.map +1 -0
  215. package/lib/stores/permissionStore.js +117 -0
  216. package/lib/stores/personaStore.d.ts +26 -0
  217. package/lib/stores/personaStore.d.ts.map +1 -0
  218. package/lib/stores/personaStore.js +118 -0
  219. package/lib/stores/postStore.d.ts +2 -1
  220. package/lib/stores/postStore.d.ts.map +1 -0
  221. package/lib/stores/postStore.js +53 -2
  222. package/lib/stores/reactionStore.d.ts +1 -0
  223. package/lib/stores/reactionStore.d.ts.map +1 -0
  224. package/lib/stores/reactionStore.js +28 -2
  225. package/lib/stores/subscriptionStore.d.ts +41 -0
  226. package/lib/stores/subscriptionStore.d.ts.map +1 -0
  227. package/lib/stores/subscriptionStore.js +85 -0
  228. package/lib/stores/tagStore.d.ts +8 -5
  229. package/lib/stores/tagStore.d.ts.map +1 -0
  230. package/lib/stores/tagStore.js +87 -2
  231. package/lib/stores/translationStore.d.ts +42 -0
  232. package/lib/stores/translationStore.d.ts.map +1 -0
  233. package/lib/stores/translationStore.js +122 -0
  234. package/lib/stores/userStore.d.ts +5 -4
  235. package/lib/stores/userStore.d.ts.map +1 -0
  236. package/lib/stores/userStore.js +319 -2
  237. package/lib/stores/videoStore.d.ts +39 -0
  238. package/lib/stores/videoStore.d.ts.map +1 -0
  239. package/lib/stores/videoStore.js +132 -0
  240. package/lib/stores/websocketStore.d.ts +1 -0
  241. package/lib/stores/websocketStore.d.ts.map +1 -0
  242. package/lib/stores/websocketStore.js +51 -2
  243. package/lib/types/apps.types.d.ts +17 -0
  244. package/lib/types/apps.types.d.ts.map +1 -0
  245. package/lib/types/apps.types.js +6 -0
  246. package/lib/types/common.types.d.ts +31 -0
  247. package/lib/types/common.types.d.ts.map +1 -0
  248. package/lib/types/common.types.js +6 -0
  249. package/lib/types/conversations.types.d.ts +17 -0
  250. package/lib/types/conversations.types.d.ts.map +1 -0
  251. package/lib/types/conversations.types.js +6 -0
  252. package/lib/types/edges.types.d.ts +38 -0
  253. package/lib/types/edges.types.d.ts.map +1 -0
  254. package/lib/types/edges.types.js +6 -0
  255. package/lib/types/groups.types.d.ts +19 -0
  256. package/lib/types/groups.types.d.ts.map +1 -0
  257. package/lib/types/groups.types.js +6 -0
  258. package/lib/types/index.d.ts +12 -0
  259. package/lib/types/index.d.ts.map +1 -0
  260. package/lib/types/index.js +12 -0
  261. package/lib/types/subscriptions.types.d.ts +32 -0
  262. package/lib/types/subscriptions.types.d.ts.map +1 -0
  263. package/lib/types/subscriptions.types.js +6 -0
  264. package/lib/types/videos.types.d.ts +61 -0
  265. package/lib/types/videos.types.d.ts.map +1 -0
  266. package/lib/types/videos.types.js +6 -0
  267. package/lib/utils/MetropolisProvider.d.ts +39 -15
  268. package/lib/utils/MetropolisProvider.d.ts.map +1 -0
  269. package/lib/utils/MetropolisProvider.js +31 -2
  270. package/lib/utils/actionFactory.d.ts +21 -19
  271. package/lib/utils/actionFactory.d.ts.map +1 -0
  272. package/lib/utils/actionFactory.js +95 -2
  273. package/lib/utils/api.d.ts +5 -4
  274. package/lib/utils/api.d.ts.map +1 -0
  275. package/lib/utils/api.js +252 -6
  276. package/lib/utils/app.d.ts +1 -0
  277. package/lib/utils/app.d.ts.map +1 -0
  278. package/lib/utils/app.js +15 -2
  279. package/lib/utils/baseActionFactory.d.ts +5 -23
  280. package/lib/utils/baseActionFactory.d.ts.map +1 -0
  281. package/lib/utils/baseActionFactory.js +72 -2
  282. package/lib/utils/configUtils.d.ts +11 -0
  283. package/lib/utils/configUtils.d.ts.map +1 -0
  284. package/lib/utils/configUtils.js +20 -0
  285. package/lib/utils/dateUtils.d.ts +1 -0
  286. package/lib/utils/dateUtils.d.ts.map +1 -0
  287. package/lib/utils/dateUtils.js +11 -2
  288. package/lib/utils/file.d.ts +3 -1
  289. package/lib/utils/file.d.ts.map +1 -0
  290. package/lib/utils/file.js +156 -2
  291. package/lib/utils/i18n.d.ts +7 -0
  292. package/lib/utils/i18n.d.ts.map +1 -0
  293. package/lib/utils/i18n.js +96 -0
  294. package/lib/utils/index.d.ts +20 -0
  295. package/lib/utils/index.d.ts.map +1 -0
  296. package/lib/utils/index.js +26 -0
  297. package/lib/utils/location.d.ts +4 -3
  298. package/lib/utils/location.d.ts.map +1 -0
  299. package/lib/utils/location.js +82 -2
  300. package/lib/utils/permissionUtils.d.ts +22 -0
  301. package/lib/utils/permissionUtils.d.ts.map +1 -0
  302. package/lib/utils/permissionUtils.js +72 -0
  303. package/lib/utils/requestCache.d.ts +8 -0
  304. package/lib/utils/requestCache.d.ts.map +1 -0
  305. package/lib/utils/requestCache.js +53 -0
  306. package/lib/utils/session.d.ts +14 -0
  307. package/lib/utils/session.d.ts.map +1 -0
  308. package/lib/utils/session.js +107 -0
  309. package/lib/utils/useConversationTyping.d.ts +26 -0
  310. package/lib/utils/useConversationTyping.d.ts.map +1 -0
  311. package/lib/utils/useConversationTyping.js +117 -0
  312. package/lib/utils/useMetropolis.d.ts +67 -12
  313. package/lib/utils/useMetropolis.d.ts.map +1 -0
  314. package/lib/utils/useMetropolis.js +311 -2
  315. package/lib/utils/useTranslations.d.ts +16 -0
  316. package/lib/utils/useTranslations.d.ts.map +1 -0
  317. package/lib/utils/useTranslations.js +105 -0
  318. package/lib/utils/validatorFactory.d.ts +3 -2
  319. package/lib/utils/validatorFactory.d.ts.map +1 -0
  320. package/lib/utils/validatorFactory.js +95 -2
  321. package/package.json +58 -17
  322. package/temp_signin.ts +73 -0
  323. package/lib/actions/profileActions/profileActions.d.ts +0 -50
  324. package/lib/actions/profileActions/profileActions.js +0 -2
  325. package/lib/adapters/profileAdapter/profileAdapter.d.ts +0 -32
  326. package/lib/adapters/profileAdapter/profileAdapter.js +0 -2
  327. package/lib/stores/profileStore.d.ts +0 -24
  328. package/lib/stores/profileStore.js +0 -2
  329. /package/{FACTORY_PATTERN_GUIDE.md → factoryPatternGuide.md} +0 -0
@@ -0,0 +1,572 @@
1
+ /**
2
+ * Copyright (c) 2023-Present, Nitrogen Labs, Inc.
3
+ * Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
4
+ */ import { parseId } from '@nlabs/utils';
5
+ import { validatePersonaInput } from '../../adapters/personaAdapter/personaAdapter.js';
6
+ import { PERSONA_CONSTANTS } from '../../stores/personaStore.js';
7
+ import { USER_CONSTANTS } from '../../stores/userStore.js';
8
+ import { appMutation, appQuery } from '../../utils/api.js';
9
+ import { createBaseActions } from '../../utils/baseActionFactory.js';
10
+ import { clearCachedRequest, getCachedRequest, setCachedRequest } from '../../utils/requestCache.js';
11
+ // Define the collection name for personas
12
+ const DATA_TYPE = 'personas';
13
+ const PERSONA_TAG_SESSION_FIELDS = [
14
+ 'personaId',
15
+ 'tags {name, tagId}'
16
+ ];
17
+ const DEFAULT_PERSONA_PROPS = [
18
+ 'imageId',
19
+ 'imageUrl',
20
+ 'name',
21
+ 'personaId',
22
+ 'tags {name, tagId}',
23
+ 'thumbUrl',
24
+ 'userId'
25
+ ];
26
+ // Default validation function
27
+ const defaultPersonaValidator = (input, options)=>validatePersonaInput(input);
28
+ export const syncPersonaToSession = (flux, persona = {})=>{
29
+ const currentSession = flux.getState('user.session', {}) || {};
30
+ const sessionPersonaId = parseId(String(currentSession?.personaId || ''));
31
+ const fetchedPersonaId = parseId(String(persona?.personaId || ''));
32
+ const sessionUserId = parseId(String(currentSession?.userId || ''));
33
+ const fetchedUserId = parseId(String(persona?.userId || ''));
34
+ if (!fetchedPersonaId) {
35
+ return;
36
+ }
37
+ if (sessionPersonaId && sessionPersonaId !== fetchedPersonaId) {
38
+ return;
39
+ }
40
+ if (sessionUserId && fetchedUserId && sessionUserId !== fetchedUserId) {
41
+ return;
42
+ }
43
+ const nextSession = {
44
+ ...currentSession,
45
+ ...persona,
46
+ ...Array.isArray(persona?.tags) ? {
47
+ tags: persona.tags
48
+ } : {}
49
+ };
50
+ void flux.setState('user.session', nextSession);
51
+ flux.dispatch({
52
+ type: USER_CONSTANTS.UPDATE_SESSION_SUCCESS,
53
+ user: persona
54
+ });
55
+ };
56
+ export const syncPersonaTagsToSession = async (flux, personaId = '')=>{
57
+ const normalizedPersonaId = parseId(String(personaId || ''));
58
+ if (!normalizedPersonaId) {
59
+ return flux.getState('user.session', {}) || {};
60
+ }
61
+ const queryVariables = {
62
+ personaId: {
63
+ type: 'ID!',
64
+ value: normalizedPersonaId
65
+ }
66
+ };
67
+ try {
68
+ const data = await appQuery(flux, 'getPersonaById', DATA_TYPE, queryVariables, PERSONA_TAG_SESSION_FIELDS);
69
+ const persona = data?.personas?.getPersonaById || {};
70
+ syncPersonaToSession(flux, {
71
+ ...persona?.personaId ? {
72
+ personaId: persona.personaId
73
+ } : {
74
+ personaId: normalizedPersonaId
75
+ },
76
+ ...Array.isArray(persona?.tags) ? {
77
+ tags: persona.tags
78
+ } : {}
79
+ });
80
+ return flux.getState('user.session', {}) || {};
81
+ } catch (error) {
82
+ return flux.getState('user.session', {}) || {};
83
+ }
84
+ };
85
+ /**
86
+ * Factory function to create PersonaActions with enhanced adapter injection capabilities.
87
+ * Custom adapters are merged with default behavior, allowing partial overrides.
88
+ *
89
+ * @example
90
+ * // Basic usage with default adapters
91
+ * const personaActions = createPersonaActions(flux);
92
+ *
93
+ * @example
94
+ * // Custom adapter that extends default behavior
95
+ * const customPersonaAdapter = (input: unknown, options?: PersonaAdapterOptions) => {
96
+ * // input is already validated by default adapter
97
+ * return input;
98
+ * };
99
+ *
100
+ * const personaActions = createPersonaActions(flux, {
101
+ * personaAdapter: customPersonaAdapter
102
+ * });
103
+ */ export const createPersonaActions = (flux, options)=>{
104
+ const personaBase = createBaseActions(flux, defaultPersonaValidator, {
105
+ ...options?.personaAdapter && {
106
+ adapter: options.personaAdapter
107
+ },
108
+ ...options?.personaAdapterOptions && {
109
+ adapterOptions: options.personaAdapterOptions
110
+ }
111
+ });
112
+ const getActivePersonaId = ()=>parseId(String(flux.getState('user.session.personaId') || ''));
113
+ const clearPersonaRelationshipCache = async (personaId)=>{
114
+ await clearCachedRequest(flux, `persona.getPersonaById:${personaId}`);
115
+ await clearCachedRequest(flux, `persona.getPersonaById:${getActivePersonaId()}`);
116
+ await clearCachedRequest(flux, 'persona.getPersonaListByIds');
117
+ await clearCachedRequest(flux, 'persona.listByRelation');
118
+ await clearCachedRequest(flux, 'persona.listByTags');
119
+ };
120
+ // Action implementations
121
+ const addPersona = async (personaData, personaProps = [], requestOptions = {})=>{
122
+ try {
123
+ const queryVariables = {
124
+ persona: {
125
+ type: 'PersonaInput!',
126
+ value: personaBase.validator(personaData)
127
+ }
128
+ };
129
+ const onSuccess = async (data)=>{
130
+ const addPersona = data?.personas?.addPersona || {};
131
+ return flux.dispatch({
132
+ persona: addPersona,
133
+ type: PERSONA_CONSTANTS.ADD_ITEM_SUCCESS
134
+ });
135
+ };
136
+ return await appMutation(flux, 'addPersona', DATA_TYPE, queryVariables, [
137
+ ...DEFAULT_PERSONA_PROPS,
138
+ ...personaProps
139
+ ], {
140
+ onSuccess
141
+ });
142
+ } catch (error) {
143
+ flux.dispatch({
144
+ error,
145
+ type: PERSONA_CONSTANTS.ADD_ITEM_ERROR
146
+ });
147
+ throw error;
148
+ } finally{
149
+ await clearCachedRequest(flux, 'persona.getPersonaListByIds');
150
+ await clearCachedRequest(flux, 'persona.listByRelation');
151
+ await clearCachedRequest(flux, 'persona.listByTags');
152
+ }
153
+ };
154
+ const getPersonaById = async (personaId, personaProps = [], requestOptions = {})=>{
155
+ try {
156
+ const cachedResult = getCachedRequest(flux, `persona.getPersonaById:${personaId}`, {
157
+ personaId,
158
+ personaProps
159
+ }, requestOptions);
160
+ if (cachedResult !== undefined) {
161
+ return cachedResult;
162
+ }
163
+ const queryVariables = {
164
+ personaId: {
165
+ type: 'ID!',
166
+ value: parseId(personaId)
167
+ }
168
+ };
169
+ const onSuccess = (data)=>{
170
+ const persona = data?.personas?.getPersonaById || {};
171
+ syncPersonaToSession(flux, persona);
172
+ return flux.dispatch({
173
+ persona,
174
+ type: PERSONA_CONSTANTS.GET_ITEM_SUCCESS
175
+ });
176
+ };
177
+ const result = await appQuery(flux, 'getPersonaById', DATA_TYPE, queryVariables, [
178
+ ...DEFAULT_PERSONA_PROPS,
179
+ ...personaProps
180
+ ], {
181
+ onSuccess
182
+ });
183
+ return await setCachedRequest(flux, `persona.getPersonaById:${personaId}`, {
184
+ personaId,
185
+ personaProps
186
+ }, result, requestOptions);
187
+ } catch (error) {
188
+ flux.dispatch({
189
+ error,
190
+ type: PERSONA_CONSTANTS.GET_ITEM_ERROR
191
+ });
192
+ throw error;
193
+ }
194
+ };
195
+ const getPersonaListByIds = async (personaIds, personaProps = [], requestOptions = {})=>{
196
+ try {
197
+ const cachedResult = getCachedRequest(flux, 'persona.getPersonaListByIds', {
198
+ personaIds,
199
+ personaProps
200
+ }, requestOptions);
201
+ if (cachedResult !== undefined) {
202
+ return cachedResult;
203
+ }
204
+ const queryVariables = {
205
+ personaIds: {
206
+ type: '[ID!]!',
207
+ value: personaIds.map(parseId)
208
+ }
209
+ };
210
+ const onSuccess = (data)=>{
211
+ const personas = data?.personas?.getPersonaListByIds || [];
212
+ return flux.dispatch({
213
+ personas,
214
+ type: PERSONA_CONSTANTS.GET_LIST_SUCCESS
215
+ });
216
+ };
217
+ const result = await appQuery(flux, 'getPersonaListByIds', DATA_TYPE, queryVariables, [
218
+ ...DEFAULT_PERSONA_PROPS,
219
+ ...personaProps
220
+ ], {
221
+ onSuccess
222
+ });
223
+ return await setCachedRequest(flux, 'persona.getPersonaListByIds', {
224
+ personaIds,
225
+ personaProps
226
+ }, result, requestOptions);
227
+ } catch (error) {
228
+ flux.dispatch({
229
+ error,
230
+ type: PERSONA_CONSTANTS.GET_LIST_ERROR
231
+ });
232
+ throw error;
233
+ }
234
+ };
235
+ const listByTags = async (username, tags, from = 0, to = 10, personaProps = [], filters = {}, requestOptions = {})=>{
236
+ try {
237
+ const cachedResult = getCachedRequest(flux, 'persona.listByTags', {
238
+ username,
239
+ tags,
240
+ from,
241
+ to,
242
+ personaProps,
243
+ filters
244
+ }, requestOptions);
245
+ if (cachedResult !== undefined) {
246
+ return cachedResult;
247
+ }
248
+ const queryVariables = {
249
+ filters: {
250
+ type: 'PersonaListFiltersInput',
251
+ value: filters
252
+ },
253
+ from: {
254
+ type: 'Int',
255
+ value: from
256
+ },
257
+ tags: {
258
+ type: '[String!]',
259
+ value: Array.isArray(tags) ? tags : []
260
+ },
261
+ to: {
262
+ type: 'Int',
263
+ value: to
264
+ },
265
+ username: {
266
+ type: 'String',
267
+ value: username
268
+ }
269
+ };
270
+ const onSuccess = (data)=>{
271
+ const personas = data?.personas?.listByTags || [];
272
+ return flux.dispatch({
273
+ personas,
274
+ type: PERSONA_CONSTANTS.GET_LIST_SUCCESS
275
+ });
276
+ };
277
+ const result = await appQuery(flux, 'listByTags', DATA_TYPE, queryVariables, [
278
+ ...DEFAULT_PERSONA_PROPS,
279
+ ...personaProps
280
+ ], {
281
+ onSuccess
282
+ });
283
+ return await setCachedRequest(flux, 'persona.listByTags', {
284
+ username,
285
+ tags,
286
+ from,
287
+ to,
288
+ personaProps,
289
+ filters
290
+ }, result, requestOptions);
291
+ } catch (error) {
292
+ flux.dispatch({
293
+ error,
294
+ type: PERSONA_CONSTANTS.GET_LIST_ERROR
295
+ });
296
+ throw error;
297
+ }
298
+ };
299
+ const listByRelation = async (relation, personaId = '', from = 0, to = 24, personaProps = [], requestOptions = {})=>{
300
+ const normalizedRelation = relation === 'followers' || relation === 'friends' ? relation : 'following';
301
+ try {
302
+ const normalizedPersonaId = parseId(personaId) || getActivePersonaId();
303
+ const cachedResult = getCachedRequest(flux, 'persona.listByRelation', {
304
+ relation: normalizedRelation,
305
+ personaId: normalizedPersonaId,
306
+ from,
307
+ to,
308
+ personaProps
309
+ }, requestOptions);
310
+ if (cachedResult !== undefined) {
311
+ await flux.dispatch({
312
+ personas: cachedResult,
313
+ relation: normalizedRelation,
314
+ type: PERSONA_CONSTANTS.GET_LIST_SUCCESS
315
+ });
316
+ return cachedResult;
317
+ }
318
+ const queryVariables = {
319
+ from: {
320
+ type: 'Int',
321
+ value: from
322
+ },
323
+ personaId: {
324
+ type: 'ID',
325
+ value: normalizedPersonaId
326
+ },
327
+ relation: {
328
+ type: 'String',
329
+ value: normalizedRelation
330
+ },
331
+ to: {
332
+ type: 'Int',
333
+ value: to
334
+ }
335
+ };
336
+ const onSuccess = (data)=>{
337
+ const personas = data?.personas?.listByRelation || [];
338
+ return flux.dispatch({
339
+ personas,
340
+ relation: normalizedRelation,
341
+ type: PERSONA_CONSTANTS.GET_LIST_SUCCESS
342
+ });
343
+ };
344
+ const result = await appQuery(flux, 'listByRelation', DATA_TYPE, queryVariables, [
345
+ ...DEFAULT_PERSONA_PROPS,
346
+ ...personaProps
347
+ ], {
348
+ onSuccess
349
+ });
350
+ return await setCachedRequest(flux, 'persona.listByRelation', {
351
+ relation: normalizedRelation,
352
+ personaId: normalizedPersonaId,
353
+ from,
354
+ to,
355
+ personaProps
356
+ }, result, requestOptions);
357
+ } catch (error) {
358
+ flux.dispatch({
359
+ error,
360
+ relation: normalizedRelation,
361
+ type: PERSONA_CONSTANTS.GET_LIST_ERROR
362
+ });
363
+ throw error;
364
+ }
365
+ };
366
+ const deletePersona = async (personaId, personaProps = [], requestOptions = {})=>{
367
+ try {
368
+ const queryVariables = {
369
+ personaId: {
370
+ type: 'ID!',
371
+ value: parseId(personaId)
372
+ }
373
+ };
374
+ const onSuccess = (data)=>{
375
+ const persona = data?.personas?.deletePersona || {};
376
+ return flux.dispatch({
377
+ persona,
378
+ type: PERSONA_CONSTANTS.DELETE_ITEM_SUCCESS
379
+ });
380
+ };
381
+ return await appMutation(flux, 'deletePersona', DATA_TYPE, queryVariables, [
382
+ 'personaId',
383
+ ...personaProps
384
+ ], {
385
+ onSuccess
386
+ });
387
+ } catch (error) {
388
+ flux.dispatch({
389
+ error,
390
+ type: PERSONA_CONSTANTS.DELETE_ITEM_ERROR
391
+ });
392
+ throw error;
393
+ } finally{
394
+ await clearCachedRequest(flux, `persona.getPersonaById:${personaId}`);
395
+ await clearCachedRequest(flux, 'persona.getPersonaListByIds');
396
+ await clearCachedRequest(flux, 'persona.listByRelation');
397
+ await clearCachedRequest(flux, 'persona.listByTags');
398
+ }
399
+ };
400
+ const updatePersona = async (persona, personaProps = [], requestOptions = {})=>{
401
+ try {
402
+ const queryVariables = {
403
+ persona: {
404
+ type: 'PersonaInput!',
405
+ value: personaBase.validator(persona)
406
+ }
407
+ };
408
+ const onSuccess = async (data)=>{
409
+ const persona = data?.personas?.updatePersona || {};
410
+ syncPersonaToSession(flux, persona);
411
+ return flux.dispatch({
412
+ persona,
413
+ type: PERSONA_CONSTANTS.UPDATE_ITEM_SUCCESS
414
+ });
415
+ };
416
+ return await appMutation(flux, 'updatePersona', DATA_TYPE, queryVariables, [
417
+ ...DEFAULT_PERSONA_PROPS,
418
+ ...personaProps
419
+ ], {
420
+ onSuccess
421
+ });
422
+ } catch (error) {
423
+ flux.dispatch({
424
+ error,
425
+ type: PERSONA_CONSTANTS.UPDATE_ITEM_ERROR
426
+ });
427
+ throw error;
428
+ } finally{
429
+ await clearCachedRequest(flux, `persona.getPersonaById:${String(persona?.personaId || '')}`);
430
+ await clearCachedRequest(flux, 'persona.getPersonaListByIds');
431
+ await clearCachedRequest(flux, 'persona.listByRelation');
432
+ await clearCachedRequest(flux, 'persona.listByTags');
433
+ }
434
+ };
435
+ const followPersona = async (targetPersonaId)=>{
436
+ const personaId = getActivePersonaId();
437
+ if (!personaId) {
438
+ throw new Error('A current persona is required before following.');
439
+ }
440
+ try {
441
+ const queryVariables = {
442
+ itemId: {
443
+ type: 'ID!',
444
+ value: parseId(targetPersonaId)
445
+ },
446
+ itemType: {
447
+ type: 'String!',
448
+ value: DATA_TYPE
449
+ },
450
+ personaId: {
451
+ type: 'ID!',
452
+ value: personaId
453
+ },
454
+ type: {
455
+ type: 'String',
456
+ value: 'follow'
457
+ }
458
+ };
459
+ const result = await appMutation(flux, 'addConnection', DATA_TYPE, queryVariables, [], {});
460
+ return Boolean(result?.personas?.addConnection ?? result);
461
+ } finally{
462
+ await clearPersonaRelationshipCache(parseId(targetPersonaId));
463
+ }
464
+ };
465
+ const unfollowPersona = async (targetPersonaId)=>{
466
+ const personaId = getActivePersonaId();
467
+ if (!personaId) {
468
+ throw new Error('A current persona is required before unfollowing.');
469
+ }
470
+ try {
471
+ const queryVariables = {
472
+ itemId: {
473
+ type: 'ID!',
474
+ value: parseId(targetPersonaId)
475
+ },
476
+ itemType: {
477
+ type: 'String!',
478
+ value: DATA_TYPE
479
+ },
480
+ personaId: {
481
+ type: 'ID!',
482
+ value: personaId
483
+ },
484
+ type: {
485
+ type: 'String',
486
+ value: 'follow'
487
+ }
488
+ };
489
+ const result = await appMutation(flux, 'deleteConnection', DATA_TYPE, queryVariables, [], {});
490
+ return Boolean(result?.personas?.deleteConnection ?? result);
491
+ } finally{
492
+ await clearPersonaRelationshipCache(parseId(targetPersonaId));
493
+ }
494
+ };
495
+ const blockPersona = async (targetPersonaId)=>{
496
+ const personaId = getActivePersonaId();
497
+ if (!personaId) {
498
+ throw new Error('A current persona is required before blocking.');
499
+ }
500
+ try {
501
+ const queryVariables = {
502
+ itemId: {
503
+ type: 'ID!',
504
+ value: parseId(targetPersonaId)
505
+ },
506
+ itemType: {
507
+ type: 'String!',
508
+ value: DATA_TYPE
509
+ },
510
+ personaId: {
511
+ type: 'ID!',
512
+ value: personaId
513
+ },
514
+ type: {
515
+ type: 'String',
516
+ value: 'block'
517
+ }
518
+ };
519
+ const result = await appMutation(flux, 'addConnection', DATA_TYPE, queryVariables, [], {});
520
+ return Boolean(result?.personas?.addConnection ?? result);
521
+ } finally{
522
+ await clearPersonaRelationshipCache(parseId(targetPersonaId));
523
+ }
524
+ };
525
+ const unblockPersona = async (targetPersonaId)=>{
526
+ const personaId = getActivePersonaId();
527
+ if (!personaId) {
528
+ throw new Error('A current persona is required before unblocking.');
529
+ }
530
+ try {
531
+ const queryVariables = {
532
+ itemId: {
533
+ type: 'ID!',
534
+ value: parseId(targetPersonaId)
535
+ },
536
+ itemType: {
537
+ type: 'String!',
538
+ value: DATA_TYPE
539
+ },
540
+ personaId: {
541
+ type: 'ID!',
542
+ value: personaId
543
+ },
544
+ type: {
545
+ type: 'String',
546
+ value: 'block'
547
+ }
548
+ };
549
+ const result = await appMutation(flux, 'deleteConnection', DATA_TYPE, queryVariables, [], {});
550
+ return Boolean(result?.personas?.deleteConnection ?? result);
551
+ } finally{
552
+ await clearPersonaRelationshipCache(parseId(targetPersonaId));
553
+ }
554
+ };
555
+ return {
556
+ blockPersona,
557
+ followPersona,
558
+ addPersona,
559
+ getPersonaById,
560
+ getPersonaListByIds,
561
+ listByRelation,
562
+ listByTags,
563
+ unfollowPersona,
564
+ unblockPersona,
565
+ deletePersona,
566
+ updatePersona,
567
+ updatePersonaAdapter: personaBase.updateAdapter,
568
+ updatePersonaAdapterOptions: personaBase.updateOptions
569
+ };
570
+ };
571
+
572
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L21ldHJvcG9saXNqcy9zcmMvYWN0aW9ucy9wZXJzb25hQWN0aW9ucy9wZXJzb25hQWN0aW9ucy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvcHlyaWdodCAoYykgMjAyMy1QcmVzZW50LCBOaXRyb2dlbiBMYWJzLCBJbmMuXG4gKiBDb3B5cmlnaHRzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIHRoZSBhY2NvbXBhbnlpbmcgTElDRU5TRSBmaWxlIGZvciB0ZXJtcy5cbiAqL1xuaW1wb3J0IHsgcGFyc2VJZCB9IGZyb20gJ0BubGFicy91dGlscyc7XG5cbmltcG9ydCB7IHZhbGlkYXRlUGVyc29uYUlucHV0IH0gZnJvbSAnLi4vLi4vYWRhcHRlcnMvcGVyc29uYUFkYXB0ZXIvcGVyc29uYUFkYXB0ZXIuanMnO1xuaW1wb3J0IHsgUEVSU09OQV9DT05TVEFOVFMgfSBmcm9tICcuLi8uLi9zdG9yZXMvcGVyc29uYVN0b3JlLmpzJztcbmltcG9ydCB7IFVTRVJfQ09OU1RBTlRTIH0gZnJvbSAnLi4vLi4vc3RvcmVzL3VzZXJTdG9yZS5qcyc7XG5pbXBvcnQgeyBhcHBNdXRhdGlvbiwgYXBwUXVlcnkgfSBmcm9tICcuLi8uLi91dGlscy9hcGkuanMnO1xuaW1wb3J0IHsgY3JlYXRlQmFzZUFjdGlvbnMgfSBmcm9tICcuLi8uLi91dGlscy9iYXNlQWN0aW9uRmFjdG9yeS5qcyc7XG5pbXBvcnQge2NsZWFyQ2FjaGVkUmVxdWVzdCwgZ2V0Q2FjaGVkUmVxdWVzdCwgc2V0Q2FjaGVkUmVxdWVzdH0gZnJvbSAnLi4vLi4vdXRpbHMvcmVxdWVzdENhY2hlLmpzJztcblxuaW1wb3J0IHR5cGUgeyBGbHV4RnJhbWV3b3JrIH0gZnJvbSAnQG5sYWJzL2Fya2hhbWpzJztcbmltcG9ydCB0eXBlIHsgUGVyc29uYVR5cGUgfSBmcm9tICcuLi8uLi9hZGFwdGVycy9wZXJzb25hQWRhcHRlci9wZXJzb25hQWRhcHRlci5qcyc7XG5pbXBvcnQgdHlwZSB7IEFjdGlvblJlcXVlc3RPcHRpb25zIH0gZnJvbSAnLi4vLi4vdXRpbHMvcmVxdWVzdENhY2hlLmpzJztcblxuLy8gRGVmaW5lIHRoZSBjb2xsZWN0aW9uIG5hbWUgZm9yIHBlcnNvbmFzXG5jb25zdCBEQVRBX1RZUEUgPSAncGVyc29uYXMnO1xuY29uc3QgUEVSU09OQV9UQUdfU0VTU0lPTl9GSUVMRFMgPSBbJ3BlcnNvbmFJZCcsICd0YWdzIHtuYW1lLCB0YWdJZH0nXTtcbmNvbnN0IERFRkFVTFRfUEVSU09OQV9QUk9QUyA9IFtcbiAgJ2ltYWdlSWQnLFxuICAnaW1hZ2VVcmwnLFxuICAnbmFtZScsXG4gICdwZXJzb25hSWQnLFxuICAndGFncyB7bmFtZSwgdGFnSWR9JyxcbiAgJ3RodW1iVXJsJyxcbiAgJ3VzZXJJZCdcbl07XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGVyc29uYUFkYXB0ZXJPcHRpb25zIHtcbiAgcmVhZG9ubHkgc3RyaWN0PzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgYWxsb3dQYXJ0aWFsPzogYm9vbGVhbjtcbiAgcmVhZG9ubHkgZW52aXJvbm1lbnQ/OiAnZGV2ZWxvcG1lbnQnIHwgJ3Byb2R1Y3Rpb24nIHwgJ3Rlc3QnO1xuICByZWFkb25seSBjdXN0b21WYWxpZGF0aW9uPzogKGlucHV0OiB1bmtub3duKSA9PiB1bmtub3duO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBlcnNvbmFBY3Rpb25zT3B0aW9ucyB7XG4gIHJlYWRvbmx5IHBlcnNvbmFBZGFwdGVyPzogKGlucHV0OiB1bmtub3duLCBvcHRpb25zPzogUGVyc29uYUFkYXB0ZXJPcHRpb25zKSA9PiBhbnk7XG4gIHJlYWRvbmx5IHBlcnNvbmFBZGFwdGVyT3B0aW9ucz86IFBlcnNvbmFBZGFwdGVyT3B0aW9ucztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQZXJzb25hQXBpUmVzdWx0c1R5cGUge1xuICByZWFkb25seSBwZXJzb25hczoge1xuICAgIHJlYWRvbmx5IGFkZENvbm5lY3Rpb24/OiBib29sZWFuO1xuICAgIHJlYWRvbmx5IGFkZFBlcnNvbmE/OiBQZXJzb25hVHlwZTtcbiAgICByZWFkb25seSBkZWxldGVDb25uZWN0aW9uPzogYm9vbGVhbjtcbiAgICByZWFkb25seSBkZWxldGVQZXJzb25hPzogUGVyc29uYVR5cGU7XG4gICAgcmVhZG9ubHkgZ2V0UGVyc29uYUJ5SWQ/OiBQZXJzb25hVHlwZTtcbiAgICByZWFkb25seSBnZXRQZXJzb25hTGlzdEJ5SWRzPzogUGVyc29uYVR5cGVbXTtcbiAgICByZWFkb25seSBsaXN0QnlSZWxhdGlvbj86IFBlcnNvbmFUeXBlW107XG4gICAgcmVhZG9ubHkgbGlzdEJ5VGFncz86IFBlcnNvbmFUeXBlW107XG4gICAgcmVhZG9ubHkgdXBkYXRlUGVyc29uYT86IFBlcnNvbmFUeXBlO1xuICB9O1xufVxuXG5leHBvcnQgdHlwZSBQZXJzb25hUmVsYXRpb25GaWx0ZXIgPSAnZm9sbG93ZXJzJyB8ICdmb2xsb3dpbmcnIHwgJ2ZyaWVuZHMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFBlcnNvbmFBY3Rpb25zIHtcbiAgcmVhZG9ubHkgYmxvY2tQZXJzb25hOiAodGFyZ2V0UGVyc29uYUlkOiBzdHJpbmcpID0+IFByb21pc2U8Ym9vbGVhbj47XG4gIHJlYWRvbmx5IGZvbGxvd1BlcnNvbmE6ICh0YXJnZXRQZXJzb25hSWQ6IHN0cmluZykgPT4gUHJvbWlzZTxib29sZWFuPjtcbiAgcmVhZG9ubHkgYWRkUGVyc29uYTogKHBlcnNvbmFEYXRhOiBQYXJ0aWFsPFBlcnNvbmFUeXBlPiwgcGVyc29uYVByb3BzPzogc3RyaW5nW10sIHJlcXVlc3RPcHRpb25zPzogQWN0aW9uUmVxdWVzdE9wdGlvbnMpID0+IFByb21pc2U8UGVyc29uYVR5cGU+O1xuICByZWFkb25seSBnZXRQZXJzb25hQnlJZDogKHBlcnNvbmFJZDogc3RyaW5nLCBwZXJzb25hUHJvcHM/OiBzdHJpbmdbXSwgcmVxdWVzdE9wdGlvbnM/OiBBY3Rpb25SZXF1ZXN0T3B0aW9ucykgPT4gUHJvbWlzZTxQZXJzb25hVHlwZT47XG4gIHJlYWRvbmx5IGdldFBlcnNvbmFMaXN0QnlJZHM6IChwZXJzb25hSWRzOiBzdHJpbmdbXSwgcGVyc29uYVByb3BzPzogc3RyaW5nW10sIHJlcXVlc3RPcHRpb25zPzogQWN0aW9uUmVxdWVzdE9wdGlvbnMpID0+IFByb21pc2U8UGVyc29uYVR5cGVbXT47XG4gIHJlYWRvbmx5IGxpc3RCeVJlbGF0aW9uOiAoXG4gICAgcmVsYXRpb246IFBlcnNvbmFSZWxhdGlvbkZpbHRlcixcbiAgICBwZXJzb25hSWQ/OiBzdHJpbmcsXG4gICAgZnJvbT86IG51bWJlcixcbiAgICB0bz86IG51bWJlcixcbiAgICBwZXJzb25hUHJvcHM/OiBzdHJpbmdbXSxcbiAgICByZXF1ZXN0T3B0aW9ucz86IEFjdGlvblJlcXVlc3RPcHRpb25zXG4gICkgPT4gUHJvbWlzZTxQZXJzb25hVHlwZVtdPjtcbiAgcmVhZG9ubHkgbGlzdEJ5VGFnczogKFxuICAgIHVzZXJuYW1lOiBzdHJpbmcsXG4gICAgdGFnczogc3RyaW5nW10sXG4gICAgZnJvbT86IG51bWJlcixcbiAgICB0bz86IG51bWJlcixcbiAgICBwZXJzb25hUHJvcHM/OiBzdHJpbmdbXSxcbiAgICBmaWx0ZXJzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gICAgcmVxdWVzdE9wdGlvbnM/OiBBY3Rpb25SZXF1ZXN0T3B0aW9uc1xuICApID0+IFByb21pc2U8UGVyc29uYVR5cGVbXT47XG4gIHJlYWRvbmx5IHVuZm9sbG93UGVyc29uYTogKHRhcmdldFBlcnNvbmFJZDogc3RyaW5nKSA9PiBQcm9taXNlPGJvb2xlYW4+O1xuICByZWFkb25seSB1bmJsb2NrUGVyc29uYTogKHRhcmdldFBlcnNvbmFJZDogc3RyaW5nKSA9PiBQcm9taXNlPGJvb2xlYW4+O1xuICByZWFkb25seSBkZWxldGVQZXJzb25hOiAocGVyc29uYUlkOiBzdHJpbmcsIHBlcnNvbmFQcm9wcz86IHN0cmluZ1tdLCByZXF1ZXN0T3B0aW9ucz86IEFjdGlvblJlcXVlc3RPcHRpb25zKSA9PiBQcm9taXNlPFBlcnNvbmFUeXBlPjtcbiAgcmVhZG9ubHkgdXBkYXRlUGVyc29uYTogKHBlcnNvbmE6IFBhcnRpYWw8UGVyc29uYVR5cGU+LCBwZXJzb25hUHJvcHM/OiBzdHJpbmdbXSwgcmVxdWVzdE9wdGlvbnM/OiBBY3Rpb25SZXF1ZXN0T3B0aW9ucykgPT4gUHJvbWlzZTxQZXJzb25hVHlwZT47XG4gIHJlYWRvbmx5IHVwZGF0ZVBlcnNvbmFBZGFwdGVyOiAoYWRhcHRlcjogKGlucHV0OiB1bmtub3duLCBvcHRpb25zPzogUGVyc29uYUFkYXB0ZXJPcHRpb25zKSA9PiBhbnkpID0+IHZvaWQ7XG4gIHJlYWRvbmx5IHVwZGF0ZVBlcnNvbmFBZGFwdGVyT3B0aW9uczogKG9wdGlvbnM6IFBlcnNvbmFBZGFwdGVyT3B0aW9ucykgPT4gdm9pZDtcbn1cblxuLy8gRGVmYXVsdCB2YWxpZGF0aW9uIGZ1bmN0aW9uXG5jb25zdCBkZWZhdWx0UGVyc29uYVZhbGlkYXRvciA9IChpbnB1dDogdW5rbm93biwgb3B0aW9ucz86IFBlcnNvbmFBZGFwdGVyT3B0aW9ucykgPT4gdmFsaWRhdGVQZXJzb25hSW5wdXQoaW5wdXQpO1xuXG5leHBvcnQgY29uc3Qgc3luY1BlcnNvbmFUb1Nlc3Npb24gPSAoZmx1eDogRmx1eEZyYW1ld29yaywgcGVyc29uYTogUGFydGlhbDxQZXJzb25hVHlwZT4gPSB7fSkgPT4ge1xuICBjb25zdCBjdXJyZW50U2Vzc2lvbiA9IChmbHV4LmdldFN0YXRlKCd1c2VyLnNlc3Npb24nLCB7fSkgfHwge30pIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBjb25zdCBzZXNzaW9uUGVyc29uYUlkID0gcGFyc2VJZChTdHJpbmcoY3VycmVudFNlc3Npb24/LnBlcnNvbmFJZCB8fCAnJykpO1xuICBjb25zdCBmZXRjaGVkUGVyc29uYUlkID0gcGFyc2VJZChTdHJpbmcocGVyc29uYT8ucGVyc29uYUlkIHx8ICcnKSk7XG4gIGNvbnN0IHNlc3Npb25Vc2VySWQgPSBwYXJzZUlkKFN0cmluZyhjdXJyZW50U2Vzc2lvbj8udXNlcklkIHx8ICcnKSk7XG4gIGNvbnN0IGZldGNoZWRVc2VySWQgPSBwYXJzZUlkKFN0cmluZyhwZXJzb25hPy51c2VySWQgfHwgJycpKTtcblxuICBpZighZmV0Y2hlZFBlcnNvbmFJZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmKHNlc3Npb25QZXJzb25hSWQgJiYgc2Vzc2lvblBlcnNvbmFJZCAhPT0gZmV0Y2hlZFBlcnNvbmFJZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmKHNlc3Npb25Vc2VySWQgJiYgZmV0Y2hlZFVzZXJJZCAmJiBzZXNzaW9uVXNlcklkICE9PSBmZXRjaGVkVXNlcklkKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgbmV4dFNlc3Npb24gPSB7XG4gICAgLi4uY3VycmVudFNlc3Npb24sXG4gICAgLi4ucGVyc29uYSxcbiAgICAuLi4oQXJyYXkuaXNBcnJheShwZXJzb25hPy50YWdzKSA/IHt0YWdzOiBwZXJzb25hLnRhZ3N9IDoge30pXG4gIH07XG5cbiAgdm9pZCBmbHV4LnNldFN0YXRlKCd1c2VyLnNlc3Npb24nLCBuZXh0U2Vzc2lvbik7XG4gIGZsdXguZGlzcGF0Y2goe3R5cGU6IFVTRVJfQ09OU1RBTlRTLlVQREFURV9TRVNTSU9OX1NVQ0NFU1MsIHVzZXI6IHBlcnNvbmEgYXMgYW55fSk7XG59O1xuXG5leHBvcnQgY29uc3Qgc3luY1BlcnNvbmFUYWdzVG9TZXNzaW9uID0gYXN5bmMgKFxuICBmbHV4OiBGbHV4RnJhbWV3b3JrLFxuICBwZXJzb25hSWQ6IHN0cmluZyA9ICcnXG4pOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIHVua25vd24+PiA9PiB7XG4gIGNvbnN0IG5vcm1hbGl6ZWRQZXJzb25hSWQgPSBwYXJzZUlkKFN0cmluZyhwZXJzb25hSWQgfHwgJycpKTtcblxuICBpZighbm9ybWFsaXplZFBlcnNvbmFJZCkge1xuICAgIHJldHVybiAoZmx1eC5nZXRTdGF0ZSgndXNlci5zZXNzaW9uJywge30pIHx8IHt9KSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgfVxuXG4gIGNvbnN0IHF1ZXJ5VmFyaWFibGVzID0ge1xuICAgIHBlcnNvbmFJZDoge1xuICAgICAgdHlwZTogJ0lEIScsXG4gICAgICB2YWx1ZTogbm9ybWFsaXplZFBlcnNvbmFJZFxuICAgIH1cbiAgfTtcblxuICB0cnkge1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBhcHBRdWVyeShcbiAgICAgIGZsdXgsXG4gICAgICAnZ2V0UGVyc29uYUJ5SWQnLFxuICAgICAgREFUQV9UWVBFLFxuICAgICAgcXVlcnlWYXJpYWJsZXMsXG4gICAgICBQRVJTT05BX1RBR19TRVNTSU9OX0ZJRUxEU1xuICAgICkgYXMgdW5rbm93biBhcyB7XG4gICAgICBwZXJzb25hcz86IHtnZXRQZXJzb25hQnlJZD86IFBhcnRpYWw8UGVyc29uYVR5cGU+fTtcbiAgICB9O1xuICAgIGNvbnN0IHBlcnNvbmEgPSBkYXRhPy5wZXJzb25hcz8uZ2V0UGVyc29uYUJ5SWQgfHwge307XG5cbiAgICBzeW5jUGVyc29uYVRvU2Vzc2lvbihmbHV4LCB7XG4gICAgICAuLi4ocGVyc29uYT8ucGVyc29uYUlkID8ge3BlcnNvbmFJZDogcGVyc29uYS5wZXJzb25hSWR9IDoge3BlcnNvbmFJZDogbm9ybWFsaXplZFBlcnNvbmFJZH0pLFxuICAgICAgLi4uKEFycmF5LmlzQXJyYXkocGVyc29uYT8udGFncykgPyB7dGFnczogcGVyc29uYS50YWdzfSA6IHt9KVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIChmbHV4LmdldFN0YXRlKCd1c2VyLnNlc3Npb24nLCB7fSkgfHwge30pIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgcmV0dXJuIChmbHV4LmdldFN0YXRlKCd1c2VyLnNlc3Npb24nLCB7fSkgfHwge30pIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICB9XG59O1xuXG4vKipcbiAqIEZhY3RvcnkgZnVuY3Rpb24gdG8gY3JlYXRlIFBlcnNvbmFBY3Rpb25zIHdpdGggZW5oYW5jZWQgYWRhcHRlciBpbmplY3Rpb24gY2FwYWJpbGl0aWVzLlxuICogQ3VzdG9tIGFkYXB0ZXJzIGFyZSBtZXJnZWQgd2l0aCBkZWZhdWx0IGJlaGF2aW9yLCBhbGxvd2luZyBwYXJ0aWFsIG92ZXJyaWRlcy5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQmFzaWMgdXNhZ2Ugd2l0aCBkZWZhdWx0IGFkYXB0ZXJzXG4gKiBjb25zdCBwZXJzb25hQWN0aW9ucyA9IGNyZWF0ZVBlcnNvbmFBY3Rpb25zKGZsdXgpO1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBDdXN0b20gYWRhcHRlciB0aGF0IGV4dGVuZHMgZGVmYXVsdCBiZWhhdmlvclxuICogY29uc3QgY3VzdG9tUGVyc29uYUFkYXB0ZXIgPSAoaW5wdXQ6IHVua25vd24sIG9wdGlvbnM/OiBQZXJzb25hQWRhcHRlck9wdGlvbnMpID0+IHtcbiAqICAgLy8gaW5wdXQgaXMgYWxyZWFkeSB2YWxpZGF0ZWQgYnkgZGVmYXVsdCBhZGFwdGVyXG4gKiAgIHJldHVybiBpbnB1dDtcbiAqIH07XG4gKlxuICogY29uc3QgcGVyc29uYUFjdGlvbnMgPSBjcmVhdGVQZXJzb25hQWN0aW9ucyhmbHV4LCB7XG4gKiAgIHBlcnNvbmFBZGFwdGVyOiBjdXN0b21QZXJzb25hQWRhcHRlclxuICogfSk7XG4gKi9cbmV4cG9ydCBjb25zdCBjcmVhdGVQZXJzb25hQWN0aW9ucyA9IChcbiAgZmx1eDogRmx1eEZyYW1ld29yayxcbiAgb3B0aW9ucz86IFBlcnNvbmFBY3Rpb25zT3B0aW9uc1xuKTogUGVyc29uYUFjdGlvbnMgPT4ge1xuICBjb25zdCBwZXJzb25hQmFzZSA9IGNyZWF0ZUJhc2VBY3Rpb25zKGZsdXgsIGRlZmF1bHRQZXJzb25hVmFsaWRhdG9yLCB7XG4gICAgLi4uKG9wdGlvbnM/LnBlcnNvbmFBZGFwdGVyICYmIHthZGFwdGVyOiBvcHRpb25zLnBlcnNvbmFBZGFwdGVyfSksXG4gICAgLi4uKG9wdGlvbnM/LnBlcnNvbmFBZGFwdGVyT3B0aW9ucyAmJiB7YWRhcHRlck9wdGlvbnM6IG9wdGlvbnMucGVyc29uYUFkYXB0ZXJPcHRpb25zfSlcbiAgfSk7XG5cbiAgY29uc3QgZ2V0QWN0aXZlUGVyc29uYUlkID0gKCk6IHN0cmluZyA9PiBwYXJzZUlkKFN0cmluZyhmbHV4LmdldFN0YXRlKCd1c2VyLnNlc3Npb24ucGVyc29uYUlkJykgfHwgJycpKTtcblxuICBjb25zdCBjbGVhclBlcnNvbmFSZWxhdGlvbnNoaXBDYWNoZSA9IGFzeW5jIChwZXJzb25hSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGF3YWl0IGNsZWFyQ2FjaGVkUmVxdWVzdChmbHV4LCBgcGVyc29uYS5nZXRQZXJzb25hQnlJZDoke3BlcnNvbmFJZH1gKTtcbiAgICBhd2FpdCBjbGVhckNhY2hlZFJlcXVlc3QoZmx1eCwgYHBlcnNvbmEuZ2V0UGVyc29uYUJ5SWQ6JHtnZXRBY3RpdmVQZXJzb25hSWQoKX1gKTtcbiAgICBhd2FpdCBjbGVhckNhY2hlZFJlcXVlc3QoZmx1eCwgJ3BlcnNvbmEuZ2V0UGVyc29uYUxpc3RCeUlkcycpO1xuICAgIGF3YWl0IGNsZWFyQ2FjaGVkUmVxdWVzdChmbHV4LCAncGVyc29uYS5saXN0QnlSZWxhdGlvbicpO1xuICAgIGF3YWl0IGNsZWFyQ2FjaGVkUmVxdWVzdChmbHV4LCAncGVyc29uYS5saXN0QnlUYWdzJyk7XG4gIH07XG5cbiAgLy8gQWN0aW9uIGltcGxlbWVudGF0aW9uc1xuICBjb25zdCBhZGRQZXJzb25hID0gYXN5bmMgKHBlcnNvbmFEYXRhOiBQYXJ0aWFsPFBlcnNvbmFUeXBlPiwgcGVyc29uYVByb3BzOiBzdHJpbmdbXSA9IFtdLCByZXF1ZXN0T3B0aW9uczogQWN0aW9uUmVxdWVzdE9wdGlvbnMgPSB7fSk6IFByb21pc2U8UGVyc29uYVR5cGU+ID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcXVlcnlWYXJpYWJsZXMgPSB7XG4gICAgICAgIHBlcnNvbmE6IHtcbiAgICAgICAgICB0eXBlOiAnUGVyc29uYUlucHV0IScsXG4gICAgICAgICAgdmFsdWU6IHBlcnNvbmFCYXNlLnZhbGlkYXRvcihwZXJzb25hRGF0YSlcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgY29uc3Qgb25TdWNjZXNzID0gYXN5bmMgKGRhdGE6IFBlcnNvbmFBcGlSZXN1bHRzVHlwZSkgPT4ge1xuICAgICAgICBjb25zdCBhZGRQZXJzb25hID0gZGF0YT8ucGVyc29uYXM/LmFkZFBlcnNvbmEgfHwge307XG4gICAgICAgIHJldHVybiBmbHV4LmRpc3BhdGNoKHtwZXJzb25hOiBhZGRQZXJzb25hLCB0eXBlOiBQRVJTT05BX0NPTlNUQU5UUy5BRERfSVRFTV9TVUNDRVNTfSk7XG4gICAgICB9O1xuXG4gICAgICByZXR1cm4gYXdhaXQgYXBwTXV0YXRpb248UGVyc29uYVR5cGU+KFxuICAgICAgICBmbHV4LFxuICAgICAgICAnYWRkUGVyc29uYScsXG4gICAgICAgIERBVEFfVFlQRSxcbiAgICAgICAgcXVlcnlWYXJpYWJsZXMsXG4gICAgICAgIFsuLi5ERUZBVUxUX1BFUlNPTkFfUFJPUFMsIC4uLnBlcnNvbmFQcm9wc10sXG4gICAgICAgIHtvblN1Y2Nlc3N9XG4gICAgICApO1xuICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgIGZsdXguZGlzcGF0Y2goe2Vycm9yLCB0eXBlOiBQRVJTT05BX0NPTlNUQU5UUy5BRERfSVRFTV9FUlJPUn0pO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IGNsZWFyQ2FjaGVkUmVxdWVzdChmbHV4LCAncGVyc29uYS5nZXRQZXJzb25hTGlzdEJ5SWRzJyk7XG4gICAgICBhd2FpdCBjbGVhckNhY2hlZFJlcXVlc3QoZmx1eCwgJ3BlcnNvbmEubGlzdEJ5UmVsYXRpb24nKTtcbiAgICAgIGF3YWl0IGNsZWFyQ2FjaGVkUmVxdWVzdChmbHV4LCAncGVyc29uYS5saXN0QnlUYWdzJyk7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGdldFBlcnNvbmFCeUlkID0gYXN5bmMgKHBlcnNvbmFJZDogc3RyaW5nLCBwZXJzb25hUHJvcHM6IHN0cmluZ1tdID0gW10sIHJlcXVlc3RPcHRpb25zOiBBY3Rpb25SZXF1ZXN0T3B0aW9ucyA9IHt9KTogUHJvbWlzZTxQZXJzb25hVHlwZT4gPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjYWNoZWRSZXN1bHQgPSBnZXRDYWNoZWRSZXF1ZXN0PFBlcnNvbmFUeXBlPihmbHV4LCBgcGVyc29uYS5nZXRQZXJzb25hQnlJZDoke3BlcnNvbmFJZH1gLCB7cGVyc29uYUlkLCBwZXJzb25hUHJvcHN9LCByZXF1ZXN0T3B0aW9ucyk7XG5cbiAgICAgIGlmKGNhY2hlZFJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBjYWNoZWRSZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHF1ZXJ5VmFyaWFibGVzID0ge1xuICAgICAgICBwZXJzb25hSWQ6IHtcbiAgICAgICAgICB0eXBlOiAnSUQhJyxcbiAgICAgICAgICB2YWx1ZTogcGFyc2VJZChwZXJzb25hSWQpXG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG9uU3VjY2VzcyA9IChkYXRhOiBQZXJzb25hQXBpUmVzdWx0c1R5cGUpID0+IHtcbiAgICAgICAgY29uc3QgcGVyc29uYSA9IGRhdGE/LnBlcnNvbmFzPy5nZXRQZXJzb25hQnlJZCB8fCB7fTtcbiAgICAgICAgc3luY1BlcnNvbmFUb1Nlc3Npb24oZmx1eCwgcGVyc29uYSk7XG4gICAgICAgIHJldHVybiBmbHV4LmRpc3BhdGNoKHtwZXJzb25hLCB0eXBlOiBQRVJTT05BX0NPTlNUQU5UUy5HRVRfSVRFTV9TVUNDRVNTfSk7XG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhcHBRdWVyeTxQZXJzb25hVHlwZT4oXG4gICAgICAgIGZsdXgsXG4gICAgICAgICdnZXRQZXJzb25hQnlJZCcsXG4gICAgICAgIERBVEFfVFlQRSxcbiAgICAgICAgcXVlcnlWYXJpYWJsZXMsXG4gICAgICAgIFsuLi5ERUZBVUxUX1BFUlNPTkFfUFJPUFMsIC4uLnBlcnNvbmFQcm9wc10sXG4gICAgICAgIHtvblN1Y2Nlc3N9XG4gICAgICApO1xuICAgICAgcmV0dXJuIGF3YWl0IHNldENhY2hlZFJlcXVlc3QoZmx1eCwgYHBlcnNvbmEuZ2V0UGVyc29uYUJ5SWQ6JHtwZXJzb25hSWR9YCwge3BlcnNvbmFJZCwgcGVyc29uYVByb3BzfSwgcmVzdWx0LCByZXF1ZXN0T3B0aW9ucyk7XG4gICAgfSBjYXRjaChlcnJvcikge1xuICAgICAgZmx1eC5kaXNwYXRjaCh7ZXJyb3IsIHR5cGU6IFBFUlNPTkFfQ09OU1RBTlRTLkdFVF9JVEVNX0VSUk9SfSk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgZ2V0UGVyc29uYUxpc3RCeUlkcyA9IGFzeW5jIChwZXJzb25hSWRzOiBzdHJpbmdbXSwgcGVyc29uYVByb3BzOiBzdHJpbmdbXSA9IFtdLCByZXF1ZXN0T3B0aW9uczogQWN0aW9uUmVxdWVzdE9wdGlvbnMgPSB7fSk6IFByb21pc2U8UGVyc29uYVR5cGVbXT4gPT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjYWNoZWRSZXN1bHQgPSBnZXRDYWNoZWRSZXF1ZXN0PFBlcnNvbmFUeXBlW10+KGZsdXgsICdwZXJzb25hLmdldFBlcnNvbmFMaXN0QnlJZHMnLCB7cGVyc29uYUlkcywgcGVyc29uYVByb3BzfSwgcmVxdWVzdE9wdGlvbnMpO1xuXG4gICAgICBpZihjYWNoZWRSZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gY2FjaGVkUmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBxdWVyeVZhcmlhYmxlcyA9IHtcbiAgICAgICAgcGVyc29uYUlkczoge1xuICAgICAgICAgIHR5cGU6ICdbSUQhXSEnLFxuICAgICAgICAgIHZhbHVlOiBwZXJzb25hSWRzLm1hcChwYXJzZUlkKVxuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBjb25zdCBvblN1Y2Nlc3MgPSAoZGF0YTogUGVyc29uYUFwaVJlc3VsdHNUeXBlKSA9PiB7XG4gICAgICAgIGNvbnN0IHBlcnNvbmFzID0gZGF0YT8ucGVyc29uYXM/LmdldFBlcnNvbmFMaXN0QnlJZHMgfHwgW107XG4gICAgICAgIHJldHVybiBmbHV4LmRpc3BhdGNoKHtwZXJzb25hcywgdHlwZTogUEVSU09OQV9DT05TVEFOVFMuR0VUX0xJU1RfU1VDQ0VTU30pO1xuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYXBwUXVlcnk8UGVyc29uYVR5cGVbXT4oXG4gICAgICAgIGZsdXgsXG4gICAgICAgICdnZXRQZXJzb25hTGlzdEJ5SWRzJyxcbiAgICAgICAgREFUQV9UWVBFLFxuICAgICAgICBxdWVyeVZhcmlhYmxlcyxcbiAgICAgICAgWy4uLkRFRkFVTFRfUEVSU09OQV9QUk9QUywgLi4ucGVyc29uYVByb3BzXSxcbiAgICAgICAge29uU3VjY2Vzc31cbiAgICAgICk7XG4gICAgICByZXR1cm4gYXdhaXQgc2V0Q2FjaGVkUmVxdWVzdChmbHV4LCAncGVyc29uYS5nZXRQZXJzb25hTGlzdEJ5SWRzJywge3BlcnNvbmFJZHMsIHBlcnNvbmFQcm9wc30sIHJlc3VsdCwgcmVxdWVzdE9wdGlvbnMpO1xuICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgIGZsdXguZGlzcGF0Y2goe2Vycm9yLCB0eXBlOiBQRVJTT05BX0NPTlNUQU5UUy5HRVRfTElTVF9FUlJPUn0pO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGxpc3RCeVRhZ3MgPSBhc3luYyAoXG4gICAgdXNlcm5hbWU6IHN0cmluZyxcbiAgICB0YWdzOiBzdHJpbmdbXSxcbiAgICBmcm9tOiBudW1iZXIgPSAwLFxuICAgIHRvOiBudW1iZXIgPSAxMCxcbiAgICBwZXJzb25hUHJvcHM6IHN0cmluZ1tdID0gW10sXG4gICAgZmlsdGVyczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fSxcbiAgICByZXF1ZXN0T3B0aW9uczogQWN0aW9uUmVxdWVzdE9wdGlvbnMgPSB7fVxuICApOiBQcm9taXNlPFBlcnNvbmFUeXBlW10+ID0+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgY2FjaGVkUmVzdWx0ID0gZ2V0Q2FjaGVkUmVxdWVzdDxQZXJzb25hVHlwZVtdPihcbiAgICAgICAgZmx1eCxcbiAgICAgICAgJ3BlcnNvbmEubGlzdEJ5VGFncycsXG4gICAgICAgIHt1c2VybmFtZSwgdGFncywgZnJvbSwgdG8sIHBlcnNvbmFQcm9wcywgZmlsdGVyc30sXG4gICAgICAgIHJlcXVlc3RPcHRpb25zXG4gICAgICApO1xuXG4gICAgICBpZihjYWNoZWRSZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gY2FjaGVkUmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBxdWVyeVZhcmlhYmxlcyA9IHtcbiAgICAgICAgZmlsdGVyczoge1xuICAgICAgICAgIHR5cGU6ICdQZXJzb25hTGlzdEZpbHRlcnNJbnB1dCcsXG4gICAgICAgICAgdmFsdWU6IGZpbHRlcnNcbiAgICAgICAgfSxcbiAgICAgICAgZnJvbToge1xuICAgICAgICAgIHR5cGU6ICdJbnQnLFxuICAgICAgICAgIHZhbHVlOiBmcm9tXG4gICAgICAgIH0sXG4gICAgICAgIHRhZ3M6IHtcbiAgICAgICAgICB0eXBlOiAnW1N0cmluZyFdJyxcbiAgICAgICAgICB2YWx1ZTogQXJyYXkuaXNBcnJheSh0YWdzKSA/IHRhZ3MgOiBbXVxuICAgICAgICB9LFxuICAgICAgICB0bzoge1xuICAgICAgICAgIHR5cGU6ICdJbnQnLFxuICAgICAgICAgIHZhbHVlOiB0b1xuICAgICAgICB9LFxuICAgICAgICB1c2VybmFtZToge1xuICAgICAgICAgIHR5cGU6ICdTdHJpbmcnLFxuICAgICAgICAgIHZhbHVlOiB1c2VybmFtZVxuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBjb25zdCBvblN1Y2Nlc3MgPSAoZGF0YTogUGVyc29uYUFwaVJlc3VsdHNUeXBlKSA9PiB7XG4gICAgICAgIGNvbnN0IHBlcnNvbmFzID0gZGF0YT8ucGVyc29uYXM/Lmxpc3RCeVRhZ3MgfHwgW107XG4gICAgICAgIHJldHVybiBmbHV4LmRpc3BhdGNoKHtwZXJzb25hcywgdHlwZTogUEVSU09OQV9DT05TVEFOVFMuR0VUX0xJU1RfU1VDQ0VTU30pO1xuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYXBwUXVlcnk8UGVyc29uYVR5cGVbXT4oXG4gICAgICAgIGZsdXgsXG4gICAgICAgICdsaXN0QnlUYWdzJyxcbiAgICAgICAgREFUQV9UWVBFLFxuICAgICAgICBxdWVyeVZhcmlhYmxlcyxcbiAgICAgICAgWy4uLkRFRkFVTFRfUEVSU09OQV9QUk9QUywgLi4ucGVyc29uYVByb3BzXSxcbiAgICAgICAge29uU3VjY2Vzc31cbiAgICAgICk7XG4gICAgICByZXR1cm4gYXdhaXQgc2V0Q2FjaGVkUmVxdWVzdChmbHV4LCAncGVyc29uYS5saXN0QnlUYWdzJywge3VzZXJuYW1lLCB0YWdzLCBmcm9tLCB0bywgcGVyc29uYVByb3BzLCBmaWx0ZXJzfSwgcmVzdWx0LCByZXF1ZXN0T3B0aW9ucyk7XG4gICAgfSBjYXRjaChlcnJvcikge1xuICAgICAgZmx1eC5kaXNwYXRjaCh7ZXJyb3IsIHR5cGU6IFBFUlNPTkFfQ09OU1RBTlRTLkdFVF9MSVNUX0VSUk9SfSk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgbGlzdEJ5UmVsYXRpb24gPSBhc3luYyAoXG4gICAgcmVsYXRpb246IFBlcnNvbmFSZWxhdGlvbkZpbHRlcixcbiAgICBwZXJzb25hSWQ6IHN0cmluZyA9ICcnLFxuICAgIGZyb206IG51bWJlciA9IDAsXG4gICAgdG86IG51bWJlciA9IDI0LFxuICAgIHBlcnNvbmFQcm9wczogc3RyaW5nW10gPSBbXSxcbiAgICByZXF1ZXN0T3B0aW9uczogQWN0aW9uUmVxdWVzdE9wdGlvbnMgPSB7fVxuICApOiBQcm9taXNlPFBlcnNvbmFUeXBlW10+ID0+IHtcbiAgICBjb25zdCBub3JtYWxpemVkUmVsYXRpb24gPSByZWxhdGlvbiA9PT0gJ2ZvbGxvd2VycycgfHwgcmVsYXRpb24gPT09ICdmcmllbmRzJyA/IHJlbGF0aW9uIDogJ2ZvbGxvd2luZyc7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3Qgbm9ybWFsaXplZFBlcnNvbmFJZCA9IHBhcnNlSWQocGVyc29uYUlkKSB8fCBnZXRBY3RpdmVQZXJzb25hSWQoKTtcbiAgICAgIGNvbnN0IGNhY2hlZFJlc3VsdCA9IGdldENhY2hlZFJlcXVlc3Q8UGVyc29uYVR5cGVbXT4oXG4gICAgICAgIGZsdXgsXG4gICAgICAgICdwZXJzb25hLmxpc3RCeVJlbGF0aW9uJyxcbiAgICAgICAge3JlbGF0aW9uOiBub3JtYWxpemVkUmVsYXRpb24sIHBlcnNvbmFJZDogbm9ybWFsaXplZFBlcnNvbmFJZCwgZnJvbSwgdG8sIHBlcnNvbmFQcm9wc30sXG4gICAgICAgIHJlcXVlc3RPcHRpb25zXG4gICAgICApO1xuXG4gICAgICBpZihjYWNoZWRSZXN1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBhd2FpdCBmbHV4LmRpc3BhdGNoKHtwZXJzb25hczogY2FjaGVkUmVzdWx0LCByZWxhdGlvbjogbm9ybWFsaXplZFJlbGF0aW9uLCB0eXBlOiBQRVJTT05BX0NPTlNUQU5UUy5HRVRfTElTVF9TVUNDRVNTfSk7XG4gICAgICAgIHJldHVybiBjYWNoZWRSZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHF1ZXJ5VmFyaWFibGVzID0ge1xuICAgICAgICBmcm9tOiB7XG4gICAgICAgICAgdHlwZTogJ0ludCcsXG4gICAgICAgICAgdmFsdWU6IGZyb21cbiAgICAgICAgfSxcbiAgICAgICAgcGVyc29uYUlkOiB7XG4gICAgICAgICAgdHlwZTogJ0lEJyxcbiAgICAgICAgICB2YWx1ZTogbm9ybWFsaXplZFBlcnNvbmFJZFxuICAgICAgICB9LFxuICAgICAgICByZWxhdGlvbjoge1xuICAgICAgICAgIHR5cGU6ICdTdHJpbmcnLFxuICAgICAgICAgIHZhbHVlOiBub3JtYWxpemVkUmVsYXRpb25cbiAgICAgICAgfSxcbiAgICAgICAgdG86IHtcbiAgICAgICAgICB0eXBlOiAnSW50JyxcbiAgICAgICAgICB2YWx1ZTogdG9cbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgY29uc3Qgb25TdWNjZXNzID0gKGRhdGE6IFBlcnNvbmFBcGlSZXN1bHRzVHlwZSkgPT4ge1xuICAgICAgICBjb25zdCBwZXJzb25hcyA9IGRhdGE/LnBlcnNvbmFzPy5saXN0QnlSZWxhdGlvbiB8fCBbXTtcbiAgICAgICAgcmV0dXJuIGZsdXguZGlzcGF0Y2goe3BlcnNvbmFzLCByZWxhdGlvbjogbm9ybWFsaXplZFJlbGF0aW9uLCB0eXBlOiBQRVJTT05BX0NPTlNUQU5UUy5HRVRfTElTVF9TVUNDRVNTfSk7XG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhcHBRdWVyeTxQZXJzb25hVHlwZVtdPihcbiAgICAgICAgZmx1eCxcbiAgICAgICAgJ2xpc3RCeVJlbGF0aW9uJyxcbiAgICAgICAgREFUQV9UWVBFLFxuICAgICAgICBxdWVyeVZhcmlhYmxlcyxcbiAgICAgICAgWy4uLkRFRkFVTFRfUEVSU09OQV9QUk9QUywgLi4ucGVyc29uYVByb3BzXSxcbiAgICAgICAge29uU3VjY2Vzc31cbiAgICAgICk7XG5cbiAgICAgIHJldHVybiBhd2FpdCBzZXRDYWNoZWRSZXF1ZXN0KFxuICAgICAgICBmbHV4LFxuICAgICAgICAncGVyc29uYS5saXN0QnlSZWxhdGlvbicsXG4gICAgICAgIHtyZWxhdGlvbjogbm9ybWFsaXplZFJlbGF0aW9uLCBwZXJzb25hSWQ6IG5vcm1hbGl6ZWRQZXJzb25hSWQsIGZyb20sIHRvLCBwZXJzb25hUHJvcHN9LFxuICAgICAgICByZXN1bHQsXG4gICAgICAgIHJlcXVlc3RPcHRpb25zXG4gICAgICApO1xuICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgIGZsdXguZGlzcGF0Y2goe2Vycm9yLCByZWxhdGlvbjogbm9ybWFsaXplZFJlbGF0aW9uLCB0eXBlOiBQRVJTT05BX0NPTlNUQU5UUy5HRVRfTElTVF9FUlJPUn0pO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGRlbGV0ZVBlcnNvbmEgPSBhc3luYyAocGVyc29uYUlkOiBzdHJpbmcsIHBlcnNvbmFQcm9wczogc3RyaW5nW10gPSBbXSwgcmVxdWVzdE9wdGlvbnM6IEFjdGlvblJlcXVlc3RPcHRpb25zID0ge30pOiBQcm9taXNlPFBlcnNvbmFUeXBlPiA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHF1ZXJ5VmFyaWFibGVzID0ge1xuICAgICAgICBwZXJzb25hSWQ6IHtcbiAgICAgICAgICB0eXBlOiAnSUQhJyxcbiAgICAgICAgICB2YWx1ZTogcGFyc2VJZChwZXJzb25hSWQpXG4gICAgICAgIH1cbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IG9uU3VjY2VzcyA9IChkYXRhOiBQZXJzb25hQXBpUmVzdWx0c1R5cGUpID0+IHtcbiAgICAgICAgY29uc3QgcGVyc29uYSA9IGRhdGE/LnBlcnNvbmFzPy5kZWxldGVQZXJzb25hIHx8IHt9O1xuICAgICAgICByZXR1cm4gZmx1eC5kaXNwYXRjaCh7cGVyc29uYSwgdHlwZTogUEVSU09OQV9DT05TVEFOVFMuREVMRVRFX0lURU1fU1VDQ0VTU30pO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuIGF3YWl0IGFwcE11dGF0aW9uPFBlcnNvbmFUeXBlPihmbHV4LCAnZGVsZXRlUGVyc29uYScsIERBVEFfVFlQRSwgcXVlcnlWYXJpYWJsZXMsIFsncGVyc29uYUlkJywgLi4ucGVyc29uYVByb3BzXSwge29uU3VjY2Vzc30pO1xuICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgIGZsdXguZGlzcGF0Y2goe2Vycm9yLCB0eXBlOiBQRVJTT05BX0NPTlNUQU5UUy5ERUxFVEVfSVRFTV9FUlJPUn0pO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IGNsZWFyQ2FjaGVkUmVxdWVzdChmbHV4LCBgcGVyc29uYS5nZXRQZXJzb25hQnlJZDoke3BlcnNvbmFJZH1gKTtcbiAgICAgIGF3YWl0IGNsZWFyQ2FjaGVkUmVxdWVzdChmbHV4LCAncGVyc29uYS5nZXRQZXJzb25hTGlzdEJ5SWRzJyk7XG4gICAgICBhd2FpdCBjbGVhckNhY2hlZFJlcXVlc3QoZmx1eCwgJ3BlcnNvbmEubGlzdEJ5UmVsYXRpb24nKTtcbiAgICAgIGF3YWl0IGNsZWFyQ2FjaGVkUmVxdWVzdChmbHV4LCAncGVyc29uYS5saXN0QnlUYWdzJyk7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IHVwZGF0ZVBlcnNvbmEgPSBhc3luYyAocGVyc29uYTogUGFydGlhbDxQZXJzb25hVHlwZT4sIHBlcnNvbmFQcm9wczogc3RyaW5nW10gPSBbXSwgcmVxdWVzdE9wdGlvbnM6IEFjdGlvblJlcXVlc3RPcHRpb25zID0ge30pOiBQcm9taXNlPFBlcnNvbmFUeXBlPiA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHF1ZXJ5VmFyaWFibGVzID0ge1xuICAgICAgICBwZXJzb25hOiB7XG4gICAgICAgICAgdHlwZTogJ1BlcnNvbmFJbnB1dCEnLFxuICAgICAgICAgIHZhbHVlOiBwZXJzb25hQmFzZS52YWxpZGF0b3IocGVyc29uYSlcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgY29uc3Qgb25TdWNjZXNzID0gYXN5bmMgKGRhdGE6IFBlcnNvbmFBcGlSZXN1bHRzVHlwZSkgPT4ge1xuICAgICAgICBjb25zdCBwZXJzb25hID0gZGF0YT8ucGVyc29uYXM/LnVwZGF0ZVBlcnNvbmEgfHwge307XG4gICAgICAgIHN5bmNQZXJzb25hVG9TZXNzaW9uKGZsdXgsIHBlcnNvbmEpO1xuICAgICAgICByZXR1cm4gZmx1eC5kaXNwYXRjaCh7cGVyc29uYSwgdHlwZTogUEVSU09OQV9DT05TVEFOVFMuVVBEQVRFX0lURU1fU1VDQ0VTU30pO1xuICAgICAgfTtcblxuICAgICAgcmV0dXJuIGF3YWl0IGFwcE11dGF0aW9uPFBlcnNvbmFUeXBlPihcbiAgICAgICAgZmx1eCxcbiAgICAgICAgJ3VwZGF0ZVBlcnNvbmEnLFxuICAgICAgICBEQVRBX1RZUEUsXG4gICAgICAgIHF1ZXJ5VmFyaWFibGVzLFxuICAgICAgICBbLi4uREVGQVVMVF9QRVJTT05BX1BST1BTLCAuLi5wZXJzb25hUHJvcHNdLFxuICAgICAgICB7b25TdWNjZXNzfVxuICAgICAgKTtcbiAgICB9IGNhdGNoKGVycm9yKSB7XG4gICAgICBmbHV4LmRpc3BhdGNoKHtlcnJvciwgdHlwZTogUEVSU09OQV9DT05TVEFOVFMuVVBEQVRFX0lURU1fRVJST1J9KTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBjbGVhckNhY2hlZFJlcXVlc3QoZmx1eCwgYHBlcnNvbmEuZ2V0UGVyc29uYUJ5SWQ6JHtTdHJpbmcocGVyc29uYT8ucGVyc29uYUlkIHx8ICcnKX1gKTtcbiAgICAgIGF3YWl0IGNsZWFyQ2FjaGVkUmVxdWVzdChmbHV4LCAncGVyc29uYS5nZXRQZXJzb25hTGlzdEJ5SWRzJyk7XG4gICAgICBhd2FpdCBjbGVhckNhY2hlZFJlcXVlc3QoZmx1eCwgJ3BlcnNvbmEubGlzdEJ5UmVsYXRpb24nKTtcbiAgICAgIGF3YWl0IGNsZWFyQ2FjaGVkUmVxdWVzdChmbHV4LCAncGVyc29uYS5saXN0QnlUYWdzJyk7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGZvbGxvd1BlcnNvbmEgPSBhc3luYyAodGFyZ2V0UGVyc29uYUlkOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+ID0+IHtcbiAgICBjb25zdCBwZXJzb25hSWQgPSBnZXRBY3RpdmVQZXJzb25hSWQoKTtcblxuICAgIGlmKCFwZXJzb25hSWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQSBjdXJyZW50IHBlcnNvbmEgaXMgcmVxdWlyZWQgYmVmb3JlIGZvbGxvd2luZy4nKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcXVlcnlWYXJpYWJsZXMgPSB7XG4gICAgICAgIGl0ZW1JZDoge1xuICAgICAgICAgIHR5cGU6ICdJRCEnLFxuICAgICAgICAgIHZhbHVlOiBwYXJzZUlkKHRhcmdldFBlcnNvbmFJZClcbiAgICAgICAgfSxcbiAgICAgICAgaXRlbVR5cGU6IHtcbiAgICAgICAgICB0eXBlOiAnU3RyaW5nIScsXG4gICAgICAgICAgdmFsdWU6IERBVEFfVFlQRVxuICAgICAgICB9LFxuICAgICAgICBwZXJzb25hSWQ6IHtcbiAgICAgICAgICB0eXBlOiAnSUQhJyxcbiAgICAgICAgICB2YWx1ZTogcGVyc29uYUlkXG4gICAgICAgIH0sXG4gICAgICAgIHR5cGU6IHtcbiAgICAgICAgICB0eXBlOiAnU3RyaW5nJyxcbiAgICAgICAgICB2YWx1ZTogJ2ZvbGxvdydcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYXBwTXV0YXRpb248Ym9vbGVhbj4oXG4gICAgICAgIGZsdXgsXG4gICAgICAgICdhZGRDb25uZWN0aW9uJyxcbiAgICAgICAgREFUQV9UWVBFLFxuICAgICAgICBxdWVyeVZhcmlhYmxlcyxcbiAgICAgICAgW10sXG4gICAgICAgIHt9XG4gICAgICApO1xuXG4gICAgICByZXR1cm4gQm9vbGVhbigocmVzdWx0IGFzIHVua25vd24gYXMgUGVyc29uYUFwaVJlc3VsdHNUeXBlKT8ucGVyc29uYXM/LmFkZENvbm5lY3Rpb24gPz8gcmVzdWx0KTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgY2xlYXJQZXJzb25hUmVsYXRpb25zaGlwQ2FjaGUocGFyc2VJZCh0YXJnZXRQZXJzb25hSWQpKTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgdW5mb2xsb3dQZXJzb25hID0gYXN5bmMgKHRhcmdldFBlcnNvbmFJZDogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiA9PiB7XG4gICAgY29uc3QgcGVyc29uYUlkID0gZ2V0QWN0aXZlUGVyc29uYUlkKCk7XG5cbiAgICBpZighcGVyc29uYUlkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgY3VycmVudCBwZXJzb25hIGlzIHJlcXVpcmVkIGJlZm9yZSB1bmZvbGxvd2luZy4nKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcXVlcnlWYXJpYWJsZXMgPSB7XG4gICAgICAgIGl0ZW1JZDoge1xuICAgICAgICAgIHR5cGU6ICdJRCEnLFxuICAgICAgICAgIHZhbHVlOiBwYXJzZUlkKHRhcmdldFBlcnNvbmFJZClcbiAgICAgICAgfSxcbiAgICAgICAgaXRlbVR5cGU6IHtcbiAgICAgICAgICB0eXBlOiAnU3RyaW5nIScsXG4gICAgICAgICAgdmFsdWU6IERBVEFfVFlQRVxuICAgICAgICB9LFxuICAgICAgICBwZXJzb25hSWQ6IHtcbiAgICAgICAgICB0eXBlOiAnSUQhJyxcbiAgICAgICAgICB2YWx1ZTogcGVyc29uYUlkXG4gICAgICAgIH0sXG4gICAgICAgIHR5cGU6IHtcbiAgICAgICAgICB0eXBlOiAnU3RyaW5nJyxcbiAgICAgICAgICB2YWx1ZTogJ2ZvbGxvdydcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYXBwTXV0YXRpb248Ym9vbGVhbj4oXG4gICAgICAgIGZsdXgsXG4gICAgICAgICdkZWxldGVDb25uZWN0aW9uJyxcbiAgICAgICAgREFUQV9UWVBFLFxuICAgICAgICBxdWVyeVZhcmlhYmxlcyxcbiAgICAgICAgW10sXG4gICAgICAgIHt9XG4gICAgICApO1xuXG4gICAgICByZXR1cm4gQm9vbGVhbigocmVzdWx0IGFzIHVua25vd24gYXMgUGVyc29uYUFwaVJlc3VsdHNUeXBlKT8ucGVyc29uYXM/LmRlbGV0ZUNvbm5lY3Rpb24gPz8gcmVzdWx0KTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgYXdhaXQgY2xlYXJQZXJzb25hUmVsYXRpb25zaGlwQ2FjaGUocGFyc2VJZCh0YXJnZXRQZXJzb25hSWQpKTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgYmxvY2tQZXJzb25hID0gYXN5bmMgKHRhcmdldFBlcnNvbmFJZDogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiA9PiB7XG4gICAgY29uc3QgcGVyc29uYUlkID0gZ2V0QWN0aXZlUGVyc29uYUlkKCk7XG5cbiAgICBpZighcGVyc29uYUlkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgY3VycmVudCBwZXJzb25hIGlzIHJlcXVpcmVkIGJlZm9yZSBibG9ja2luZy4nKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcXVlcnlWYXJpYWJsZXMgPSB7XG4gICAgICAgIGl0ZW1JZDoge1xuICAgICAgICAgIHR5cGU6ICdJRCEnLFxuICAgICAgICAgIHZhbHVlOiBwYXJzZUlkKHRhcmdldFBlcnNvbmFJZClcbiAgICAgICAgfSxcbiAgICAgICAgaXRlbVR5cGU6IHtcbiAgICAgICAgICB0eXBlOiAnU3RyaW5nIScsXG4gICAgICAgICAgdmFsdWU6IERBVEFfVFlQRVxuICAgICAgICB9LFxuICAgICAgICBwZXJzb25hSWQ6IHtcbiAgICAgICAgICB0eXBlOiAnSUQhJyxcbiAgICAgICAgICB2YWx1ZTogcGVyc29uYUlkXG4gICAgICAgIH0sXG4gICAgICAgIHR5cGU6IHtcbiAgICAgICAgICB0eXBlOiAnU3RyaW5nJyxcbiAgICAgICAgICB2YWx1ZTogJ2Jsb2NrJ1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhcHBNdXRhdGlvbjxib29sZWFuPihcbiAgICAgICAgZmx1eCxcbiAgICAgICAgJ2FkZENvbm5lY3Rpb24nLFxuICAgICAgICBEQVRBX1RZUEUsXG4gICAgICAgIHF1ZXJ5VmFyaWFibGVzLFxuICAgICAgICBbXSxcbiAgICAgICAge31cbiAgICAgICk7XG5cbiAgICAgIHJldHVybiBCb29sZWFuKChyZXN1bHQgYXMgdW5rbm93biBhcyBQZXJzb25hQXBpUmVzdWx0c1R5cGUpPy5wZXJzb25hcz8uYWRkQ29ubmVjdGlvbiA/PyByZXN1bHQpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBjbGVhclBlcnNvbmFSZWxhdGlvbnNoaXBDYWNoZShwYXJzZUlkKHRhcmdldFBlcnNvbmFJZCkpO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCB1bmJsb2NrUGVyc29uYSA9IGFzeW5jICh0YXJnZXRQZXJzb25hSWQ6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICAgIGNvbnN0IHBlcnNvbmFJZCA9IGdldEFjdGl2ZVBlcnNvbmFJZCgpO1xuXG4gICAgaWYoIXBlcnNvbmFJZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIGN1cnJlbnQgcGVyc29uYSBpcyByZXF1aXJlZCBiZWZvcmUgdW5ibG9ja2luZy4nKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcXVlcnlWYXJpYWJsZXMgPSB7XG4gICAgICAgIGl0ZW1JZDoge1xuICAgICAgICAgIHR5cGU6ICdJRCEnLFxuICAgICAgICAgIHZhbHVlOiBwYXJzZUlkKHRhcmdldFBlcnNvbmFJZClcbiAgICAgICAgfSxcbiAgICAgICAgaXRlbVR5cGU6IHtcbiAgICAgICAgICB0eXBlOiAnU3RyaW5nIScsXG4gICAgICAgICAgdmFsdWU6IERBVEFfVFlQRVxuICAgICAgICB9LFxuICAgICAgICBwZXJzb25hSWQ6IHtcbiAgICAgICAgICB0eXBlOiAnSUQhJyxcbiAgICAgICAgICB2YWx1ZTogcGVyc29uYUlkXG4gICAgICAgIH0sXG4gICAgICAgIHR5cGU6IHtcbiAgICAgICAgICB0eXBlOiAnU3RyaW5nJyxcbiAgICAgICAgICB2YWx1ZTogJ2Jsb2NrJ1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhcHBNdXRhdGlvbjxib29sZWFuPihcbiAgICAgICAgZmx1eCxcbiAgICAgICAgJ2RlbGV0ZUNvbm5lY3Rpb24nLFxuICAgICAgICBEQVRBX1RZUEUsXG4gICAgICAgIHF1ZXJ5VmFyaWFibGVzLFxuICAgICAgICBbXSxcbiAgICAgICAge31cbiAgICAgICk7XG5cbiAgICAgIHJldHVybiBCb29sZWFuKChyZXN1bHQgYXMgdW5rbm93biBhcyBQZXJzb25hQXBpUmVzdWx0c1R5cGUpPy5wZXJzb25hcz8uZGVsZXRlQ29ubmVjdGlvbiA/PyByZXN1bHQpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBjbGVhclBlcnNvbmFSZWxhdGlvbnNoaXBDYWNoZShwYXJzZUlkKHRhcmdldFBlcnNvbmFJZCkpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4ge1xuICAgIGJsb2NrUGVyc29uYSxcbiAgICBmb2xsb3dQZXJzb25hLFxuICAgIGFkZFBlcnNvbmEsXG4gICAgZ2V0UGVyc29uYUJ5SWQsXG4gICAgZ2V0UGVyc29uYUxpc3RCeUlkcyxcbiAgICBsaXN0QnlSZWxhdGlvbixcbiAgICBsaXN0QnlUYWdzLFxuICAgIHVuZm9sbG93UGVyc29uYSxcbiAgICB1bmJsb2NrUGVyc29uYSxcbiAgICBkZWxldGVQZXJzb25hLFxuICAgIHVwZGF0ZVBlcnNvbmEsXG4gICAgdXBkYXRlUGVyc29uYUFkYXB0ZXI6IHBlcnNvbmFCYXNlLnVwZGF0ZUFkYXB0ZXIsXG4gICAgdXBkYXRlUGVyc29uYUFkYXB0ZXJPcHRpb25zOiBwZXJzb25hQmFzZS51cGRhdGVPcHRpb25zXG4gIH07XG59O1xuIl0sIm5hbWVzIjpbInBhcnNlSWQiLCJ2YWxpZGF0ZVBlcnNvbmFJbnB1dCIsIlBFUlNPTkFfQ09OU1RBTlRTIiwiVVNFUl9DT05TVEFOVFMiLCJhcHBNdXRhdGlvbiIsImFwcFF1ZXJ5IiwiY3JlYXRlQmFzZUFjdGlvbnMiLCJjbGVhckNhY2hlZFJlcXVlc3QiLCJnZXRDYWNoZWRSZXF1ZXN0Iiwic2V0Q2FjaGVkUmVxdWVzdCIsIkRBVEFfVFlQRSIsIlBFUlNPTkFfVEFHX1NFU1NJT05fRklFTERTIiwiREVGQVVMVF9QRVJTT05BX1BST1BTIiwiZGVmYXVsdFBlcnNvbmFWYWxpZGF0b3IiLCJpbnB1dCIsIm9wdGlvbnMiLCJzeW5jUGVyc29uYVRvU2Vzc2lvbiIsImZsdXgiLCJwZXJzb25hIiwiY3VycmVudFNlc3Npb24iLCJnZXRTdGF0ZSIsInNlc3Npb25QZXJzb25hSWQiLCJTdHJpbmciLCJwZXJzb25hSWQiLCJmZXRjaGVkUGVyc29uYUlkIiwic2Vzc2lvblVzZXJJZCIsInVzZXJJZCIsImZldGNoZWRVc2VySWQiLCJuZXh0U2Vzc2lvbiIsIkFycmF5IiwiaXNBcnJheSIsInRhZ3MiLCJzZXRTdGF0ZSIsImRpc3BhdGNoIiwidHlwZSIsIlVQREFURV9TRVNTSU9OX1NVQ0NFU1MiLCJ1c2VyIiwic3luY1BlcnNvbmFUYWdzVG9TZXNzaW9uIiwibm9ybWFsaXplZFBlcnNvbmFJZCIsInF1ZXJ5VmFyaWFibGVzIiwidmFsdWUiLCJkYXRhIiwicGVyc29uYXMiLCJnZXRQZXJzb25hQnlJZCIsImVycm9yIiwiY3JlYXRlUGVyc29uYUFjdGlvbnMiLCJwZXJzb25hQmFzZSIsInBlcnNvbmFBZGFwdGVyIiwiYWRhcHRlciIsInBlcnNvbmFBZGFwdGVyT3B0aW9ucyIsImFkYXB0ZXJPcHRpb25zIiwiZ2V0QWN0aXZlUGVyc29uYUlkIiwiY2xlYXJQZXJzb25hUmVsYXRpb25zaGlwQ2FjaGUiLCJhZGRQZXJzb25hIiwicGVyc29uYURhdGEiLCJwZXJzb25hUHJvcHMiLCJyZXF1ZXN0T3B0aW9ucyIsInZhbGlkYXRvciIsIm9uU3VjY2VzcyIsIkFERF9JVEVNX1NVQ0NFU1MiLCJBRERfSVRFTV9FUlJPUiIsImNhY2hlZFJlc3VsdCIsInVuZGVmaW5lZCIsIkdFVF9JVEVNX1NVQ0NFU1MiLCJyZXN1bHQiLCJHRVRfSVRFTV9FUlJPUiIsImdldFBlcnNvbmFMaXN0QnlJZHMiLCJwZXJzb25hSWRzIiwibWFwIiwiR0VUX0xJU1RfU1VDQ0VTUyIsIkdFVF9MSVNUX0VSUk9SIiwibGlzdEJ5VGFncyIsInVzZXJuYW1lIiwiZnJvbSIsInRvIiwiZmlsdGVycyIsImxpc3RCeVJlbGF0aW9uIiwicmVsYXRpb24iLCJub3JtYWxpemVkUmVsYXRpb24iLCJkZWxldGVQZXJzb25hIiwiREVMRVRFX0lURU1fU1VDQ0VTUyIsIkRFTEVURV9JVEVNX0VSUk9SIiwidXBkYXRlUGVyc29uYSIsIlVQREFURV9JVEVNX1NVQ0NFU1MiLCJVUERBVEVfSVRFTV9FUlJPUiIsImZvbGxvd1BlcnNvbmEiLCJ0YXJnZXRQZXJzb25hSWQiLCJFcnJvciIsIml0ZW1JZCIsIml0ZW1UeXBlIiwiQm9vbGVhbiIsImFkZENvbm5lY3Rpb24iLCJ1bmZvbGxvd1BlcnNvbmEiLCJkZWxldGVDb25uZWN0aW9uIiwiYmxvY2tQZXJzb25hIiwidW5ibG9ja1BlcnNvbmEiLCJ1cGRhdGVQZXJzb25hQWRhcHRlciIsInVwZGF0ZUFkYXB0ZXIiLCJ1cGRhdGVQZXJzb25hQWRhcHRlck9wdGlvbnMiLCJ1cGRhdGVPcHRpb25zIl0sIm1hcHBpbmdzIjoiQUFBQTs7O0NBR0MsR0FDRCxTQUFTQSxPQUFPLFFBQVEsZUFBZTtBQUV2QyxTQUFTQyxvQkFBb0IsUUFBUSxrREFBa0Q7QUFDdkYsU0FBU0MsaUJBQWlCLFFBQVEsK0JBQStCO0FBQ2pFLFNBQVNDLGNBQWMsUUFBUSw0QkFBNEI7QUFDM0QsU0FBU0MsV0FBVyxFQUFFQyxRQUFRLFFBQVEscUJBQXFCO0FBQzNELFNBQVNDLGlCQUFpQixRQUFRLG1DQUFtQztBQUNyRSxTQUFRQyxrQkFBa0IsRUFBRUMsZ0JBQWdCLEVBQUVDLGdCQUFnQixRQUFPLDhCQUE4QjtBQU1uRywwQ0FBMEM7QUFDMUMsTUFBTUMsWUFBWTtBQUNsQixNQUFNQyw2QkFBNkI7SUFBQztJQUFhO0NBQXFCO0FBQ3RFLE1BQU1DLHdCQUF3QjtJQUM1QjtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDQTtDQUNEO0FBNkRELDhCQUE4QjtBQUM5QixN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