@nlabs/reaktor 1.18.0 → 1.20.0-reactorbox.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 (396) hide show
  1. package/README.md +290 -0
  2. package/docs/GENERATION.md +42 -16
  3. package/lib/actions/alfredFaq.js +1 -1
  4. package/lib/actions/analytics.js +1 -1
  5. package/lib/actions/apps.js +17 -2
  6. package/lib/actions/connections.js +1 -1
  7. package/lib/actions/content.js +1 -1
  8. package/lib/actions/contentGeneration.d.ts +22 -1
  9. package/lib/actions/contentGeneration.js +120 -32
  10. package/lib/actions/contentGenerationErrors.js +1 -1
  11. package/lib/actions/contentGenerationSources.d.ts +29 -0
  12. package/lib/actions/contentGenerationSources.js +103 -0
  13. package/lib/actions/conversations.js +1 -1
  14. package/lib/actions/crm.d.ts +6 -2
  15. package/lib/actions/crm.js +91 -12
  16. package/lib/actions/crmCanonicalOutcomes.d.ts +88 -0
  17. package/lib/actions/crmCanonicalOutcomes.js +398 -0
  18. package/lib/actions/crmCanonicalPolicy.d.ts +92 -0
  19. package/lib/actions/crmCanonicalPolicy.js +104 -0
  20. package/lib/actions/crmCheckoutRecovery.d.ts +72 -0
  21. package/lib/actions/crmCheckoutRecovery.js +413 -0
  22. package/lib/actions/crmCheckoutRecoveryPolicy.d.ts +38 -0
  23. package/lib/actions/crmCheckoutRecoveryPolicy.js +61 -0
  24. package/lib/actions/crmDeliveryEvents.d.ts +24 -0
  25. package/lib/actions/crmDeliveryEvents.js +207 -0
  26. package/lib/actions/crmDeliveryEvidence.d.ts +17 -0
  27. package/lib/actions/crmDeliveryEvidence.js +58 -0
  28. package/lib/actions/crmExecution.d.ts +125 -0
  29. package/lib/actions/crmExecution.js +830 -0
  30. package/lib/actions/crmFinancialEvidence.d.ts +12 -0
  31. package/lib/actions/crmFinancialEvidence.js +60 -0
  32. package/lib/actions/crmInsights.d.ts +60 -0
  33. package/lib/actions/crmInsights.js +225 -0
  34. package/lib/actions/crmLeadFollowups.d.ts +66 -0
  35. package/lib/actions/crmLeadFollowups.js +209 -0
  36. package/lib/actions/crmOutcomes.d.ts +106 -0
  37. package/lib/actions/crmOutcomes.js +289 -0
  38. package/lib/actions/crmRecoveryRetention.d.ts +13 -0
  39. package/lib/actions/crmRecoveryRetention.js +163 -0
  40. package/lib/actions/crmReminderDispatch.d.ts +10 -0
  41. package/lib/actions/crmReminderDispatch.js +65 -0
  42. package/lib/actions/crmSourceOwnership.d.ts +7 -0
  43. package/lib/actions/crmSourceOwnership.js +27 -0
  44. package/lib/actions/crmSupportInsights.d.ts +18 -0
  45. package/lib/actions/crmSupportInsights.js +47 -0
  46. package/lib/actions/crmWinback.d.ts +71 -0
  47. package/lib/actions/crmWinback.js +347 -0
  48. package/lib/actions/crmWinbackConsent.d.ts +29 -0
  49. package/lib/actions/crmWinbackConsent.js +158 -0
  50. package/lib/actions/crmWinbackPolicy.d.ts +33 -0
  51. package/lib/actions/crmWinbackPolicy.js +115 -0
  52. package/lib/actions/crmWinbackShopSource.d.ts +15 -0
  53. package/lib/actions/crmWinbackShopSource.js +63 -0
  54. package/lib/actions/crud.js +1 -1
  55. package/lib/actions/databaseAccounts.js +1 -1
  56. package/lib/actions/databaseProvisioningLease.js +1 -1
  57. package/lib/actions/dynamodb.js +1 -1
  58. package/lib/actions/email.d.ts +4 -1
  59. package/lib/actions/email.js +25 -3
  60. package/lib/actions/files.js +1 -1
  61. package/lib/actions/flags.js +1 -1
  62. package/lib/actions/geminiVideo.js +1 -1
  63. package/lib/actions/groups.js +1 -1
  64. package/lib/actions/higgsfield.js +1 -1
  65. package/lib/actions/imageGeneration.js +1 -1
  66. package/lib/actions/images.js +1 -1
  67. package/lib/actions/index.d.ts +56 -0
  68. package/lib/actions/index.js +42 -1
  69. package/lib/actions/ios.js +1 -1
  70. package/lib/actions/locations.js +1 -1
  71. package/lib/actions/merchantAccountExperiment.d.ts +50 -0
  72. package/lib/actions/merchantAccountExperiment.js +424 -0
  73. package/lib/actions/merchantAccountExperimentConfig.d.ts +7 -0
  74. package/lib/actions/merchantAccountExperimentConfig.js +32 -0
  75. package/lib/actions/merchantAccountExperimentHost.d.ts +69 -0
  76. package/lib/actions/merchantAccountExperimentHost.js +92 -0
  77. package/lib/actions/merchantAccountExperimentPolicy.d.ts +66 -0
  78. package/lib/actions/merchantAccountExperimentPolicy.js +121 -0
  79. package/lib/actions/merchantAccountExperimentRelay.d.ts +10 -0
  80. package/lib/actions/merchantAccountExperimentRelay.js +75 -0
  81. package/lib/actions/merchantCalendar.d.ts +34 -0
  82. package/lib/actions/merchantCalendar.js +119 -0
  83. package/lib/actions/merchantCalendarBookings.d.ts +17 -0
  84. package/lib/actions/merchantCalendarBookings.js +113 -0
  85. package/lib/actions/merchantCalendarDelegation.d.ts +80 -0
  86. package/lib/actions/merchantCalendarDelegation.js +353 -0
  87. package/lib/actions/merchantCalendarDiscovery.d.ts +38 -0
  88. package/lib/actions/merchantCalendarDiscovery.js +124 -0
  89. package/lib/actions/merchantCalendarEventHost.d.ts +105 -0
  90. package/lib/actions/merchantCalendarEventHost.js +16 -0
  91. package/lib/actions/merchantCalendarEventPrivacy.d.ts +7 -0
  92. package/lib/actions/merchantCalendarEventPrivacy.js +70 -0
  93. package/lib/actions/merchantCalendarEventRepository.d.ts +121 -0
  94. package/lib/actions/merchantCalendarEventRepository.js +295 -0
  95. package/lib/actions/merchantCalendarEventTransport.d.ts +65 -0
  96. package/lib/actions/merchantCalendarEventTransport.js +132 -0
  97. package/lib/actions/merchantCalendarEvents.d.ts +172 -0
  98. package/lib/actions/merchantCalendarEvents.js +365 -0
  99. package/lib/actions/merchantCalendarInvitationConsent.d.ts +28 -0
  100. package/lib/actions/merchantCalendarInvitationConsent.js +118 -0
  101. package/lib/actions/merchantCalendarManagedSource.d.ts +22 -0
  102. package/lib/actions/merchantCalendarManagedSource.js +24 -0
  103. package/lib/actions/merchantCalendarOAuth.d.ts +92 -0
  104. package/lib/actions/merchantCalendarOAuth.js +502 -0
  105. package/lib/actions/merchantCalendarOAuthConfig.d.ts +4 -0
  106. package/lib/actions/merchantCalendarOAuthConfig.js +30 -0
  107. package/lib/actions/merchantCalendarOAuthRepository.d.ts +57 -0
  108. package/lib/actions/merchantCalendarOAuthRepository.js +108 -0
  109. package/lib/actions/merchantCalendarOAuthTransport.d.ts +4 -0
  110. package/lib/actions/merchantCalendarOAuthTransport.js +25 -0
  111. package/lib/actions/merchantCalendarScopes.d.ts +4 -0
  112. package/lib/actions/merchantCalendarScopes.js +31 -0
  113. package/lib/actions/merchantFinance.d.ts +65 -0
  114. package/lib/actions/merchantFinance.js +244 -0
  115. package/lib/actions/merchantFinanceProvider.d.ts +57 -0
  116. package/lib/actions/merchantFinanceProvider.js +180 -0
  117. package/lib/actions/merchantOperations.d.ts +94 -0
  118. package/lib/actions/merchantOperations.js +489 -0
  119. package/lib/actions/messages.js +1 -1
  120. package/lib/actions/notifications.js +1 -1
  121. package/lib/actions/ollamaGeneration.js +1 -1
  122. package/lib/actions/openaiResponseSession.js +1 -1
  123. package/lib/actions/payments.js +1 -1
  124. package/lib/actions/personas.js +1 -1
  125. package/lib/actions/phoneSupport.js +1 -1
  126. package/lib/actions/posts.js +1 -1
  127. package/lib/actions/providerCredentials.d.ts +35 -0
  128. package/lib/actions/providerCredentials.js +166 -0
  129. package/lib/actions/query.js +1 -1
  130. package/lib/actions/reactions.js +1 -1
  131. package/lib/actions/rum.js +1 -1
  132. package/lib/actions/s3.d.ts +10 -7
  133. package/lib/actions/s3.js +59 -14
  134. package/lib/actions/search.js +1 -1
  135. package/lib/actions/sms.js +1 -1
  136. package/lib/actions/statistics.js +1 -1
  137. package/lib/actions/subscriptions.js +1 -1
  138. package/lib/actions/supportChannelSources.d.ts +66 -0
  139. package/lib/actions/supportChannelSources.js +183 -0
  140. package/lib/actions/supportCommerce.d.ts +62 -0
  141. package/lib/actions/supportCommerce.js +252 -0
  142. package/lib/actions/supportConnect.d.ts +39 -0
  143. package/lib/actions/supportConnect.js +224 -0
  144. package/lib/actions/supportContext.d.ts +31 -0
  145. package/lib/actions/supportContext.js +88 -0
  146. package/lib/actions/supportConversation.d.ts +102 -0
  147. package/lib/actions/supportConversation.js +100 -0
  148. package/lib/actions/supportEmailEvents.d.ts +20 -0
  149. package/lib/actions/supportEmailEvents.js +130 -0
  150. package/lib/actions/supportEmailHandoff.d.ts +114 -0
  151. package/lib/actions/supportEmailHandoff.js +356 -0
  152. package/lib/actions/supportOperations.d.ts +32 -0
  153. package/lib/actions/supportOperations.js +74 -0
  154. package/lib/actions/supportPolicy.d.ts +9 -0
  155. package/lib/actions/supportPolicy.js +44 -0
  156. package/lib/actions/supportPurposeConsent.d.ts +32 -0
  157. package/lib/actions/supportPurposeConsent.js +196 -0
  158. package/lib/actions/supportPurposePrivacy.d.ts +15 -0
  159. package/lib/actions/supportPurposePrivacy.js +181 -0
  160. package/lib/actions/supportSemanticReview.d.ts +64 -0
  161. package/lib/actions/supportSemanticReview.js +239 -0
  162. package/lib/actions/tags.js +1 -1
  163. package/lib/actions/users.js +22 -3
  164. package/lib/actions/videoGeneration.js +1 -1
  165. package/lib/actions/videos.js +1 -1
  166. package/lib/adapters/arangoAdapter.js +1 -1
  167. package/lib/adapters/contentAdapter.js +1 -1
  168. package/lib/adapters/fileAdapter.js +1 -1
  169. package/lib/adapters/geminiGenerationAdapter.js +1 -1
  170. package/lib/adapters/higgsfieldAdapter.js +1 -1
  171. package/lib/adapters/higgsfieldModelCatalog.js +1 -1
  172. package/lib/adapters/higgsfieldModels.js +1 -1
  173. package/lib/adapters/imageAdapter.js +1 -1
  174. package/lib/adapters/imageGenerationAdapter.js +1 -1
  175. package/lib/adapters/index.js +1 -1
  176. package/lib/adapters/messageAdapter.js +1 -1
  177. package/lib/adapters/postAdapter.js +1 -1
  178. package/lib/adapters/reaktorAdapter.js +1 -1
  179. package/lib/adapters/tagAdapter.js +1 -1
  180. package/lib/adapters/userAdapter.js +1 -1
  181. package/lib/assistant/core.js +1 -1
  182. package/lib/assistant/faq.js +1 -1
  183. package/lib/assistant/faqCore.js +1 -1
  184. package/lib/assistant/index.js +1 -1
  185. package/lib/assistant/service.js +1 -1
  186. package/lib/config.js +1 -1
  187. package/lib/constants/collections.d.ts +2 -1
  188. package/lib/constants/collections.js +2 -1
  189. package/lib/durableChat/conversations.js +1 -1
  190. package/lib/durableChat/errors.js +1 -1
  191. package/lib/durableChat/events.js +1 -1
  192. package/lib/durableChat/index.js +1 -1
  193. package/lib/durableChat/membership.js +1 -1
  194. package/lib/durableChat/messageTypes.js +1 -1
  195. package/lib/durableChat/messages.js +1 -1
  196. package/lib/durableChat/transaction.js +1 -1
  197. package/lib/durableChat/types.js +1 -1
  198. package/lib/handlers/graphqlHandler.js +1 -1
  199. package/lib/index.js +1 -1
  200. package/lib/lambdas/actions/websockets.js +1 -1
  201. package/lib/lambdas/authorizer.js +1 -1
  202. package/lib/lambdas/connection.js +1 -1
  203. package/lib/lambdas/utils/message.js +1 -1
  204. package/lib/lambdas/utils/websocket.js +1 -1
  205. package/lib/mocks/conversation.js +1 -1
  206. package/lib/mocks/file.js +1 -1
  207. package/lib/mocks/group.js +1 -1
  208. package/lib/mocks/image.js +1 -1
  209. package/lib/mocks/post.js +1 -1
  210. package/lib/mocks/tag.js +1 -1
  211. package/lib/mocks/user.js +1 -1
  212. package/lib/mocks/video.js +1 -1
  213. package/lib/mutations/analytics/analytics.js +1 -1
  214. package/lib/mutations/content/content.js +1 -1
  215. package/lib/mutations/crm/crm.js +395 -7
  216. package/lib/mutations/events/events.js +1 -1
  217. package/lib/mutations/flags/flags.js +1 -1
  218. package/lib/mutations/groups/groups.js +1 -1
  219. package/lib/mutations/higgsfield/higgsfield.js +1 -1
  220. package/lib/mutations/images/images.js +1 -1
  221. package/lib/mutations/index.js +1 -1
  222. package/lib/mutations/locations/locations.js +1 -1
  223. package/lib/mutations/messages/messages.js +1 -1
  224. package/lib/mutations/personas/personas.js +1 -1
  225. package/lib/mutations/posts/posts.js +1 -1
  226. package/lib/mutations/reactions/reactions.js +1 -1
  227. package/lib/mutations/rum/rum.js +1 -1
  228. package/lib/mutations/statistics/statistics.js +1 -1
  229. package/lib/mutations/subscriptions/subscriptions.js +1 -1
  230. package/lib/mutations/tags/tags.js +1 -1
  231. package/lib/mutations/users/users.js +1 -1
  232. package/lib/mutations/videos/videos.js +1 -1
  233. package/lib/nativePush/graphql.js +1 -1
  234. package/lib/nativePush/index.js +1 -1
  235. package/lib/nativePush/migrations.js +1 -1
  236. package/lib/nativePush/nativePushContract.fixture.js +1 -1
  237. package/lib/nativePush/payload.js +1 -1
  238. package/lib/nativePush/repository.js +1 -1
  239. package/lib/nativePush/service.js +1 -1
  240. package/lib/nativePush/snsProvider.js +1 -1
  241. package/lib/nativePush/types.js +1 -1
  242. package/lib/objectTypes/analytics.js +1 -1
  243. package/lib/objectTypes/app.js +1 -1
  244. package/lib/objectTypes/bankAccount.js +1 -1
  245. package/lib/objectTypes/connection.js +1 -1
  246. package/lib/objectTypes/content.js +1 -1
  247. package/lib/objectTypes/contentGeneration.js +1 -1
  248. package/lib/objectTypes/conversation.js +1 -1
  249. package/lib/objectTypes/creditCard.js +1 -1
  250. package/lib/objectTypes/crm.js +1 -1
  251. package/lib/objectTypes/document.js +1 -1
  252. package/lib/objectTypes/error.js +1 -1
  253. package/lib/objectTypes/event.js +1 -1
  254. package/lib/objectTypes/external.js +1 -1
  255. package/lib/objectTypes/file.js +1 -1
  256. package/lib/objectTypes/filter.js +1 -1
  257. package/lib/objectTypes/flag.js +1 -1
  258. package/lib/objectTypes/group.js +1 -1
  259. package/lib/objectTypes/higgsfield.js +1 -1
  260. package/lib/objectTypes/iapSubscription.js +1 -1
  261. package/lib/objectTypes/image.js +1 -1
  262. package/lib/objectTypes/imageGeneration.js +1 -1
  263. package/lib/objectTypes/index.js +1 -1
  264. package/lib/objectTypes/location.js +1 -1
  265. package/lib/objectTypes/message.js +1 -1
  266. package/lib/objectTypes/passcode.js +1 -1
  267. package/lib/objectTypes/persona.js +1 -1
  268. package/lib/objectTypes/plan.js +1 -1
  269. package/lib/objectTypes/post.js +1 -1
  270. package/lib/objectTypes/query.js +1 -1
  271. package/lib/objectTypes/reaction.js +1 -1
  272. package/lib/objectTypes/relation.js +1 -1
  273. package/lib/objectTypes/rum.js +1 -1
  274. package/lib/objectTypes/search.js +1 -1
  275. package/lib/objectTypes/statistics.js +1 -1
  276. package/lib/objectTypes/subscription.js +1 -1
  277. package/lib/objectTypes/tag.js +1 -1
  278. package/lib/objectTypes/user.js +1 -1
  279. package/lib/objectTypes/video.js +1 -1
  280. package/lib/objectTypes/videoGeneration.js +1 -1
  281. package/lib/organizations/accountLifecycle.js +1 -1
  282. package/lib/organizations/authorization.js +1 -1
  283. package/lib/organizations/billing.js +1 -1
  284. package/lib/organizations/billingProvider.js +1 -1
  285. package/lib/organizations/billingUpdates.js +1 -1
  286. package/lib/organizations/index.js +1 -1
  287. package/lib/organizations/mail.js +1 -1
  288. package/lib/organizations/memberDirectory.js +1 -1
  289. package/lib/organizations/membership.js +1 -1
  290. package/lib/organizations/passwordRecovery.js +1 -1
  291. package/lib/organizations/plans.js +1 -1
  292. package/lib/organizations/providerPagination.js +1 -1
  293. package/lib/organizations/reconciliation.js +1 -1
  294. package/lib/organizations/signup.js +1 -1
  295. package/lib/organizations/store.js +1 -1
  296. package/lib/organizations/types.js +1 -1
  297. package/lib/organizations/verification.js +1 -1
  298. package/lib/queries/analytics/analytics.js +1 -1
  299. package/lib/queries/content/content.js +1 -1
  300. package/lib/queries/crm/crm.js +251 -5
  301. package/lib/queries/events/events.js +1 -1
  302. package/lib/queries/flags/flags.js +1 -1
  303. package/lib/queries/groups/groups.js +1 -1
  304. package/lib/queries/higgsfield/higgsfield.js +1 -1
  305. package/lib/queries/images/images.js +1 -1
  306. package/lib/queries/index.js +1 -1
  307. package/lib/queries/locations/locations.js +1 -1
  308. package/lib/queries/messages/messages.js +1 -1
  309. package/lib/queries/personas/personas.js +1 -1
  310. package/lib/queries/posts/posts.js +1 -1
  311. package/lib/queries/query/query.js +1 -1
  312. package/lib/queries/reactions/reactions.js +1 -1
  313. package/lib/queries/statistics/statistics.js +1 -1
  314. package/lib/queries/subscriptions/subscriptions.js +1 -1
  315. package/lib/queries/tags/tags.js +1 -1
  316. package/lib/queries/users/users.js +1 -1
  317. package/lib/queries/videos/videos.js +1 -1
  318. package/lib/templates/email/layout.js +1 -1
  319. package/lib/templates/email/passwordForgot.js +1 -1
  320. package/lib/templates/email/passwordRecovery.js +1 -1
  321. package/lib/templates/email/verifyEmail.js +1 -1
  322. package/lib/templates/email/welcome.js +1 -1
  323. package/lib/templates/sms/passwordForgot.js +1 -1
  324. package/lib/templates/sms/passwordRecovery.js +1 -1
  325. package/lib/templates/sms/verifyEmail.js +1 -1
  326. package/lib/templates/sms/verifyPhone.js +1 -1
  327. package/lib/templates/sms/welcome.js +1 -1
  328. package/lib/types/analytics.types.js +1 -1
  329. package/lib/types/apps.types.js +1 -1
  330. package/lib/types/arangodb.types.js +1 -1
  331. package/lib/types/auth.types.d.ts +2 -0
  332. package/lib/types/auth.types.js +1 -1
  333. package/lib/types/connections.types.js +1 -1
  334. package/lib/types/content.types.js +1 -1
  335. package/lib/types/conversations.types.js +1 -1
  336. package/lib/types/crm.types.d.ts +6 -0
  337. package/lib/types/crm.types.js +1 -1
  338. package/lib/types/databaseCredentials.types.js +1 -1
  339. package/lib/types/email.types.js +1 -1
  340. package/lib/types/error.types.js +1 -1
  341. package/lib/types/files.types.js +1 -1
  342. package/lib/types/flags.types.js +1 -1
  343. package/lib/types/google.types.js +1 -1
  344. package/lib/types/groups.types.js +1 -1
  345. package/lib/types/images.types.js +1 -1
  346. package/lib/types/index.js +1 -1
  347. package/lib/types/locations.types.js +1 -1
  348. package/lib/types/messages.types.js +1 -1
  349. package/lib/types/notifications.types.js +1 -1
  350. package/lib/types/payments.types.js +1 -1
  351. package/lib/types/personas.types.js +1 -1
  352. package/lib/types/posts.types.js +1 -1
  353. package/lib/types/rum.types.js +1 -1
  354. package/lib/types/statistics.types.js +1 -1
  355. package/lib/types/tags.types.js +1 -1
  356. package/lib/types/users.types.d.ts +2 -0
  357. package/lib/types/users.types.js +1 -1
  358. package/lib/types/videos.types.js +1 -1
  359. package/lib/types/websockets.types.js +1 -1
  360. package/lib/upload.js +1 -1
  361. package/lib/utils/adapterUtils.js +1 -1
  362. package/lib/utils/analyticsUtils.js +1 -1
  363. package/lib/utils/appContext.js +1 -1
  364. package/lib/utils/aqlHelpers.js +1 -1
  365. package/lib/utils/arangodbUtils.js +1 -1
  366. package/lib/utils/authUtils.js +17 -1
  367. package/lib/utils/awsUtils.js +1 -1
  368. package/lib/utils/collectionRegistry.js +1 -1
  369. package/lib/utils/contextUtils.js +1 -1
  370. package/lib/utils/databaseCredentials.js +1 -1
  371. package/lib/utils/dbI18n.example.js +1 -1
  372. package/lib/utils/dbI18n.js +1 -1
  373. package/lib/utils/generationCallback.js +1 -1
  374. package/lib/utils/googleTranslate.js +1 -1
  375. package/lib/utils/graphqlUtils.d.ts +2 -0
  376. package/lib/utils/graphqlUtils.js +1 -1
  377. package/lib/utils/imageUtils.js +1 -1
  378. package/lib/utils/index.js +1 -1
  379. package/lib/utils/languageDetection.js +1 -1
  380. package/lib/utils/localeUtils.example.js +1 -1
  381. package/lib/utils/localeUtils.js +1 -1
  382. package/lib/utils/mediaAccess.js +1 -1
  383. package/lib/utils/middlewareUtils.js +1 -1
  384. package/lib/utils/nodeRealtime.js +1 -1
  385. package/lib/utils/opaqueToken.js +1 -1
  386. package/lib/utils/queryBuilder.js +1 -1
  387. package/lib/utils/schemaUtils.js +1 -1
  388. package/lib/utils/secretDatabase.js +1 -1
  389. package/lib/utils/sessionUtils.js +1 -1
  390. package/lib/utils/stripeUtils.js +1 -1
  391. package/lib/utils/templateUtils.js +1 -1
  392. package/lib/utils/testUtils.js +1 -1
  393. package/lib/utils/translationQueue.example.js +1 -1
  394. package/lib/utils/translationQueue.js +1 -1
  395. package/lib/videoProcessing.js +1 -1
  396. package/package.json +8 -6
package/README.md CHANGED
@@ -1702,3 +1702,293 @@ Each operation takes `input: JSONObject!` and returns JSON at `data.assistant.<o
1702
1702
  Support requires user confirmation, valid contact details and a stable `web-UUID` request ID. Queued acceptance means durable storage for retry, not confirmed email delivery. Read GraphQL `errors` even for HTTP 200 responses. The server selects approved knowledge, origins, database and delivery configuration; caller metadata cannot grant access.
1703
1703
 
1704
1704
  The backend factories are exported from the server-only `@nlabs/reaktor/assistant` subpath in the release containing the extraction. See [assistant endpoint, configuration and rollout](docs/ASSISTANT.md) for complete requests/responses, validation, limits, adapters and publication/deployment status.
1705
+
1706
+ ## Minimized CRM and Support aggregate reads (source extension)
1707
+
1708
+ `crm.merchantInsights(appId: ID!, from: String!, to: String!, productId: ID)` returns `crm_merchant_insights_v1` JSON for a timezone-qualified window of at most 90 days. It reads bounded source contact/marketing-opt-in and Support type/status counters. Counts below five are withheld; source windows exceeding 10,000 records are marked truncated. No identities, ticket text, emails, customer values, campaign attribution or lead pipeline are returned. Product-scoped reads do not imply product-related contact acquisition.
1709
+
1710
+ Administrators issue an explicit scoped key with `crm.createInsightsReadKey(appId: ID!, scopes: [String!]!, expiresAt: String!)`; allowed scopes are `crm:aggregates` and `support:aggregates`. The host must provide its existing authorized application database resolver. The API returns the secret once and stores only its SHA256 hash, exact app/database scope, administrator owner and expiry in the owner API database. Expiry must be future and at most 365 days. `crm.revokeInsightsReadKey(appId: ID!, id: ID!)` revokes that credential. No customer records or graph edges change.
1711
+
1712
+ Send the opaque key as `Authorization: Bearer <readKey>` only to the verified owner GraphQL endpoint. It is isolated from ordinary session authentication; it grants no other CRM/Support/user actions. Reads check scope, hash, expiry and revocation before and after aggregation. Public package helpers are `createCrmInsightsReadKey`, `getCrmMerchantInsights` and `revokeCrmInsightsReadKey`. Keep keys server-side; rotate/revoke through the owner API and clear consumer caches when grants or projects are removed.
1713
+
1714
+ This extension needs a reviewed compatible package build adopted by the owner host and deployment of those fields before a consumer can connect. It does not establish a live service merely because a local source checkout exports it. Existing email campaigns, private ticket messages, appointments and merchant invoices need their separate consent, source, frozen-action and execution/reconciliation contracts.
1715
+
1716
+
1717
+ ## Account-scoped multipart S3 primitives
1718
+
1719
+ `s3Head`, `s3Delete`, `s3CreateMultipartUpload`, `s3CompleteMultipartUpload`, and `s3AbortMultipartUpload` accept an optional second `S3Client` argument. `s3ListParts(params, client?)` returns exactly one raw SDK page, including truncation, markers, ordering and checksums. All propagate original errors; none retry, paginate or translate missing/denied errors.
1720
+
1721
+ Explicit truthy buckets with an injected client never read global configuration/credentials. Empty/missing buckets fall back to `aws.s3.Bucket || aws.s3.bucket`. Injected branches copy caller inputs. Existing no-client helpers retain their legacy bucket mutations; new ListParts copies in both branches.
1722
+
1723
+ `s3GetUploadPartSignedUrl(params, client?, signingOptions?)` exports `S3UploadPartSigningOptions` derived from the presigner options excluding `expiresIn`. Options are forwarded; `params.Expires || 3600` is applied last and cannot be overridden. Legacy calls delete Expires and fill Bucket on caller input; injected calls modify only a copy. Account expiry/part sizing/checksum validation and reconciliation remain application policy.
1724
+
1725
+ ```ts
1726
+ await s3GetUploadPartSignedUrl({Bucket: bucket, ChecksumSHA256: checksum,
1727
+ ContentLength: bytes, Expires: 900, Key: key, PartNumber: part, UploadId: uploadId},
1728
+ client, {unhoistableHeaders: new Set(['x-amz-checksum-sha256'])});
1729
+ ```
1730
+
1731
+ These additions require a verified compatible release before registry adoption. Local compatible archives preserve the installed baseline manifest/dependencies and replace only the S3 module/declarations; source checkout version alone is not a release guarantee.
1732
+
1733
+ ## Scoped merchant lead follow-up and Support operations
1734
+
1735
+ `generateCrmLeadFollowupCandidates` and GraphQL `crm.leadFollowupCandidates(input:JSON!)` read bounded native new/qualified lead opportunities from current consented campaign associations. Administrator-issued `crm:lead_followup` requires separate `crm:outreach` and exact organization/project/campaign bounds. Candidates expire within 15 minutes and source/grant/consent expiry. Existing exact execution previews accept a frozen candidate/revision binding; native source validation and once-only opportunity claims prevent concurrent or different-request-key duplicate sending. Unknown submission stays held. Generation alone sends nothing; these are current source opportunities, not fabricated historical events or inactivity cohorts.
1736
+
1737
+ `readSupportInbox` and GraphQL `crm.supportInbox(input:JSON!)` require native `support:read` and return bounded ticket status/priority/type/revision and eligible operator identifiers, with truncation and expiry. `support:manage` separately authorizes reviewed assignment, priority and internal escalation through the existing preview/decision/execution ledger with source and operator revisions. Escalation updates native ticket metadata without external notifications. `summarizeCampaignSupport` uses existing consented campaign associations for suppressed operational topic/status/resolution counters; it exposes no ticket text or customer testimonials. New pure public policy helpers include `supportPriorities`, `validSupportManagement` and `supportOperatorRevision`. Portable consumer adoption still requires compatible owner deployment and real granted source configuration.
1738
+
1739
+ ## Trusted native SES delivery relay
1740
+
1741
+ `ingestCrmDeliveryEvent(context,input)` and GraphQL mutation `crm.ingestDeliveryEvent(input:JSON!)`
1742
+ require a separately administrator-issued `crm:delivery_events` execution key. Keep that key on an
1743
+ explicitly trusted server relay; it is not an ordinary Ads customer-execution scope and does not grant
1744
+ outreach or target access. The relay must establish authentic AWS/provider event provenance before
1745
+ calling the owner operation. This operation does not verify raw SNS signatures, subscriptions or
1746
+ anonymous browser claims. Bridge deployment and SES event-destination configuration remain separate.
1747
+
1748
+ The exact normalized input is `{appId,eventId,receiptId,providerMessageId,kind,occurredAt,bounceType?}`.
1749
+ `kind` is `delivered`, `bounce` or `complaint`; bounce classification must be exactly `Permanent`,
1750
+ `Transient` or `Undetermined` when kind is bounce. No email, recipient/body, SNS envelope or additional
1751
+ properties are accepted. `receiptId` identifies the actual native execution receipt returned by the
1752
+ sending workflow, and `providerMessageId` must match its accepted SES MessageId. Native sends now
1753
+ persist `providerAcceptedAt`. Legacy records lacking that timestamp and submitting/unknown sends
1754
+ remain held; delivery claims cannot repair uncertain submission or trigger retry.
1755
+
1756
+ Events are bounded to thirty days, no more than one minute ahead of the owner clock or before recorded
1757
+ provider acceptance, and no more than thirty days after acceptance. Each receipt accepts at most 32
1758
+ unique events. Same app/event-ID payload replay is idempotent across key rotation; conflicting reuse is
1759
+ rejected. Minimized event metadata and receipt/user graph edges commit atomically with suppression.
1760
+ An exact current recipient is required; changed/deleted recipients hold. Bounce of any classification
1761
+ sets a delivery hold without claiming permanent rejection; complaint is monotonic over later bounces.
1762
+ Delivered events and replays never clear existing delivery holds or marketing opt-out. The returned
1763
+ `suppressed` value reflects the current delivery hold, not marketing permission. No sends or retries
1764
+ occur. Relay authority is rechecked before writes and immediately before transaction commit; native
1765
+ app writes use an exclusive transaction while the platform grant registry remains its existing separate
1766
+ authority boundary. Compatible owner deployment and real source relay acceptance remain outstanding.
1767
+
1768
+ Native administrator action `eraseCrmDeliveryEvidence(context,appId,userId)` and GraphQL mutation
1769
+ `crm.eraseDeliveryEvidence(appId:ID!,userId:ID!)` atomically remove that user's delivery event records and
1770
+ both event edges in the current owned app database. They preserve a hash-only tombstone and original
1771
+ send receipts; previously accepted messages cannot be reingested across relay key rotation. A genuinely
1772
+ new accepted send after erasure may start new evidence. This action does not clear suppression or consent,
1773
+ remove users, resend or change unknown submissions. Call it only from a configured authorized native
1774
+ privacy workflow; it is not granted by a relay key or exposed through ordinary Ads execution sources.
1775
+
1776
+
1777
+ Ordinary receipt inspection now includes optional minimized `deliveryEvidence` only for actual applied
1778
+ SES receipts. Its exact shape is `{schemaVersion:'crm_delivery_evidence_v1',status,generatedAt,validUntil,
1779
+ negativeHold,events:[{kind,occurredAt,bounceType?}]}`. Status is `available`, `unavailable` or `erased`;
1780
+ only available evidence supplies a boolean current native delivery hold. Other statuses supply null and
1781
+ an empty timeline. Reports contain no event IDs, relay key, recipient, message body or raw provider data.
1782
+ The snapshot expires within fifteen minutes and no later than ordinary receipt authority expiry.
1783
+ Inspection rechecks the same current grant after reading the native ledger. Missing, corrupt, erased or
1784
+ changed-recipient evidence does not imply delivery success or permission. Available delivered reports
1785
+ do not clear suppression or consent; transient bounce remains a hold rather than proven permanent rejection.
1786
+
1787
+ Ads accepts this strict projection through its existing ordinary receipt-read path, rejects nested private
1788
+ fields before persistence, clears cached evidence on failed or revoked refresh, and withholds the timeline
1789
+ after its deadline or source withdrawal. No relay-write scope is exposed through Ads and no retry follows
1790
+ a delivery report. A configured source bridge, compatible native deployment, provider event-destination
1791
+ configuration and administrator privacy-workflow adoption remain separate live acceptance requirements.
1792
+
1793
+ ### Canonical CRM lifecycle and verified settlement source
1794
+
1795
+ Public actions `createCrmCanonicalReadKey`, `getCrmCanonicalOutcomes`,
1796
+ `correctCrmCanonicalObservation`, and `registerCrmCanonicalFinanceBinding` are exposed through
1797
+ `crm.canonicalOutcomes(input: JSON!)` and the corresponding CRM administrator mutations.
1798
+ `crm:canonical_outcomes` is a distinct read scope bound to app, organization, project and campaigns.
1799
+ `crm:canonical_finance` additionally requires exact existing owned issuer IDs. Keys remain actor bound and expiring.
1800
+
1801
+ A campaign association must separately record `canonicalConsent` with purpose `canonical_campaign_outcomes`,
1802
+ explicit evidence reference and expiry no later than its campaign association consent. New native stage records
1803
+ contain actual occurrence time, immutable event ID and version. Legacy unversioned or truncated histories are
1804
+ explicitly incomplete; this API never invents an occurrence or silently deletes prior history from such a read.
1805
+ Corrections target an actual existing observation and retain its occurrence time under source/event/association CAS.
1806
+ A completed read emits versioned tombstones for consent/source withdrawal. Source snapshot metadata is bounded
1807
+ at 1,000 events and has a 30-day TTL; it contains minimized references, not form or ticket text.
1808
+
1809
+ Financial registration only binds existing native invoice, payment evidence, customer order, user and native
1810
+ payment documents under exact source revisions. It does not issue invoices or establish settlement authenticity.
1811
+ A financial read verifies the actual existing Stripe charge, bound customer and complete refund evidence using
1812
+ GET operations only, requires captured paid live settlement and matching immutable legal amounts/currency,
1813
+ and rechecks current native evidence and grant bounds after transport. Failed/uncertain verification is held.
1814
+ Stripe evidence alone does not prove a Shopify order namespace: financial observations remain
1815
+ `verified_settlement_namespace_unproven` until a consumer independently reads the current owned Shopify
1816
+ order and matches its exact provider payment/refund identities. Never sum these rows with Shopify revenue
1817
+ without that proof. No charge, refund, invoice issuance or external send is performed by this contract.
1818
+
1819
+ ### Advisory external calendar busy reads
1820
+
1821
+ `readMerchantCalendarBusy(context,{appId,from,resourceId,sourceId,to})` and
1822
+ `crm.merchantCalendarBusy(input: JSON!)` provide a separate Scheduling-owned Google Calendar busy-time
1823
+ read. Require an actual current `scheduling:read` grant, exact current native resource and explicit
1824
+ server-only `MERCHANT_CALENDAR_SOURCES` configuration (`appId,calendarId,expiresAt,id,resourceId,scopes,token`).
1825
+ Configure the actual obtained Google free/busy or read scope and finite token expiry; source rotation
1826
+ and native resource/grant changes invalidate an in-flight read. No native provider credential creation,
1827
+ OAuth refresh controller or token persistence API is implied by this configuration.
1828
+
1829
+ Only at most seven days within the next ninety days are read, with at most500 busy ranges and one
1830
+ configured calendar. Return minimized UTC intervals, resource timezone, revision and at most five-minute
1831
+ freshness. Group expansion, partial provider errors, absent calendars and mismatched time ranges hold
1832
+ evidence. Empty busy ranges mean no busy intervals were returned for this source/window; they do not
1833
+ establish complete availability. No event names, participant/email/calendar identities or keys are returned.
1834
+ This advisory read never creates an external event or native reservation, sends invitations or changes
1835
+ booking execution. Combining external availability with native reservation needs a separately validated
1836
+ collision and provider-race contract. Official operation:
1837
+ https://developers.google.com/workspace/calendar/api/v3/reference/freebusy/query
1838
+
1839
+ ### Native consented checkout recovery
1840
+
1841
+ `generateCrmCheckoutRecoveryCandidates` reads only registered, current Shopify abandoned checkout identities. It requires
1842
+ independent `crm:checkout_recovery` plus `crm:outreach` authority and exact `recoveryBounds` (organization, project,
1843
+ campaigns, source IDs, 24–720 hour recipient cooldown). Lead follow-up authority cannot enumerate recovery candidates.
1844
+ `recordCrmCheckoutRecoveryConsent` accepts only the authenticated native customer's own revision and explicit independent
1845
+ `checkout_recovery` purpose (at most 30 days); administrators cannot register consent on somebody else's behalf.
1846
+ `registerCrmCheckoutRecoveryBinding` is administrator-only and binds an existing consented campaign association, current
1847
+ native recipient and independently read current Shopify customer/checkout. Registration sends nothing.
1848
+
1849
+ Owner-only `CRM_CHECKOUT_RECOVERY_SOURCES` configuration contains exact app/organization/project/source ID, shop domain,
1850
+ server-held Shopify token, token expiry and explicit protected orders/customers access approval. Reads target fixed Shopify
1851
+ Admin API 2026-10, verify actual shop and current installed `read_orders`/`read_customers` scopes, and query the exact
1852
+ checkout with `status:open recovery_state:not_recovered email_state:not_sent`. Completed, absent, ambiguous, recovered,
1853
+ externally emailed, unsubscribed, suppressed, expired, changed or unavailable evidence is held. Candidate data is bounded
1854
+ and expires within 15 minutes; registration metadata and graph edges have at most the customer's 30-day consent lifetime.
1855
+
1856
+ Existing `previewCrmExecution` accepts independent `recovery: {candidateId, revision}` for `crm_outreach`. The native preview
1857
+ freezes one recipient and exact plain-text body with unsubscribe capability; exact approval remains a separate operation.
1858
+ Execution repeats provider completion/consent/source token and native recipient/association checks, atomically claims the
1859
+ stable shop/checkout/customer/campaign opportunity, and uses the existing durable SES ledger. Actual recent provider
1860
+ acceptance and every unknown/submitting marketing receipt enforce recipient cadence. Unknown submission outcomes remain
1861
+ claimed and cannot be retried automatically or bypassed by rotating grants. No paid operations, bookings, financial
1862
+ movements, implicit consent, automatic recovery sends, inferred inactivity or unsupported win-back eligibility are added.
1863
+
1864
+ GraphQL exposes `crm.checkoutRecoveryCandidates(input: JSON!)`, `crm.checkoutRecoveryConsent(input: JSON!)` and
1865
+ `crm.registerCheckoutRecoveryBinding(input: JSON!)`; the existing exact preview/approval/execution fields remain in use.
1866
+
1867
+ ### Permitted native Support order/product context
1868
+
1869
+ `readSupportContext(context, {appId, ticketId, ticketRevision})` and GraphQL `crm.supportContext(input: JSON!)` require a separately issued `support:context` execution-key scope plus `support:read`. The owner checks current app/database authorization, exact actionable ticket revision, explicit app-stamped native customer identity, and exact order/product references. Missing, ambiguous, deleted, legacy-unscoped and cross-customer references are held. Source and grant revisions are checked again before returning minimized IDs/revisions, native product title, recorded currency/date, held/reference status and a snapshot lasting at most 15 minutes. Contact details, amounts and ticket/conversation content are excluded. Provenance is `native_recorded_unverified_shop`: it does not verify a Shopify shop/customer namespace, live order/delivery state or settlement, and grants no reply/refund/payment authority.
1870
+
1871
+ For genuine newly owned source records, `ingestShopifyCustomerOrder(context, input, {appId})` and `createSupportTicket(context, input, {appId})` reauthorize administrator/app scope inside the owner helper. Their existing GraphQL mutations pass explicit `appId` to this supported path. New order/product/customer keys are app-scoped; customer lookup uses exact app and source customer ID rather than email matching. New records receive immutable app labels. Existing conflicting/deleted/unscoped labels are rejected; legacy records are not retroactively stamped or joined. Product ingestion is bounded to 50 referenced products. Scope-less legacy helper calls preserve their prior behavior, but those unscoped records are ineligible for this context read. Customer/order/product relationships remain native graph edges; this path is source registration, not proof of financial settlement. Deployed owner adoption and genuinely authorized source ingestion are required before real context exists.
1872
+
1873
+ ### Explicit verified recovery links and content retention
1874
+
1875
+ Recovery candidates can expose `recoveryLinkHash`, never the checkout capability URL.
1876
+ The source proof reads Shopify's `abandonedCheckoutUrl` plus actual shop identity and primary domain;
1877
+ only exact bounded HTTPS provider-owned URLs are supported. `includeVerifiedRecoveryLink: true`
1878
+ in a recovery preview explicitly appends that exact current URL before the native unsubscribe capability.
1879
+ The reviewed body has a hard 5000-character bound; an unsupported URL or changed source is held.
1880
+ Ordinary previews and older candidates without a link hash keep their existing behavior.
1881
+
1882
+ Recovery receipts carry `contentStatus: current | redacted`. Redacted receipts omit `body`, `subject`,
1883
+ and `recipient.email`; absence never represents an unchanged approved message. Reads recheck the
1884
+ current source, purpose consent, suppression and expiry before retaining content. Rejection, expiry,
1885
+ and grant revocation remove capability-bearing content without deleting source hashes, unsubscribe
1886
+ verification, exact receipt revision, provider acceptance or durable opportunity claims. Unknown outcomes
1887
+ remain unknown and cannot retry. Redacted content cannot be approved or submitted.
1888
+
1889
+ Native hosts can call administrator-only `retainCrmCheckoutRecoveryContent(context, appId)`
1890
+ (or `crm.retainCheckoutRecoveryContent`) for bounded 100-row expired/rejected content cleanup.
1891
+ A host maintenance worker should continue until it returns fewer than 100. The public receipt never
1892
+ exports the private payload/grant/unsubscribe hashes. Existing unsubscribe verification keeps working
1893
+ after content redaction or sending-grant expiry/revocation. Non-recovery content is unchanged.
1894
+
1895
+ ### Bounded Amazon Connect Support metadata (unreleased)
1896
+
1897
+ `configureSupportConnectSource`, `bindSupportConnectConversation` and
1898
+ `eraseSupportConnectEvidence` require ordinary native administrator authority. Configure an exact
1899
+ app database, Connect instance ARN, path-free IAM relay role and expiry. Binding requires a current,
1900
+ explicitly app-owned ticket and native user revision; legacy unscoped records are held. Contact IDs
1901
+ remain private. Erasure preserves opaque replay tombstones and does not send or retry anything.
1902
+
1903
+ `ingestSupportConnectMetadata` is a private host adapter API, requiring a current native
1904
+ `support:channel_ingest` grant and the AWS gateway-owned IAM principal. It performs one bounded
1905
+ `DescribeContact` call, verifies the exact contact ARN and VOICE channel, and records only actual
1906
+ initiation/disconnect timestamps. Claimed milestones, identity matching, transcripts and reply
1907
+ operations are unsupported. The relay scope is deliberately excluded from ordinary Ads credentials.
1908
+
1909
+ `readSupportConnectEvidence` / `crm.supportChannelEvidence` require current `support:read` authority.
1910
+ The minimized result contains source/ticket revision, channel, observed/ended timestamps, provenance,
1911
+ generation time and validity deadline; no contact/customer IDs, bodies, amounts or relay credentials.
1912
+ Validity is clamped to current read, source, contributing binding and relay authority expiries, at most
1913
+ 15 minutes. Current source/binding/grant/ticket changes hold old evidence. Completion is not resolution,
1914
+ message delivery, consent, settlement or a sale.
1915
+
1916
+ Core source/binding/event/grant checks and replay insertion share one native transaction. Tickets and
1917
+ users reside in the app database: their revisions are checked before the provider read, after it,
1918
+ immediately before core commit, and independently during inspection. Those checks do not lock the
1919
+ app database across the core transaction. A residual cross-database read-to-commit race remains;
1920
+ this metadata-only API must not be used as an atomic customer-action authorization proof.
1921
+
1922
+ Authenticated reads perform bounded retention cleanup (100 expired bindings and 200 events per read;
1923
+ events retain at most 30 days). Dormant sources require an owner-operated cleanup schedule; no live
1924
+ schedule or deployment is installed here. Tombstones retain only opaque hashes required to prevent
1925
+ re-ingestion after privacy erasure.
1926
+
1927
+ The host route is `POST /crm/support/channels/connect`, requiring AWS_IAM and exact qualified-Lambda
1928
+ invoke permissions. `apps/api/config/support-connect-route.yaml` is a review-only CloudFormation
1929
+ plan, not an automatic deployment. It separates the relay's exact execute-api route from the runtime's
1930
+ exact instance/contact `connect:DescribeContact` resource and documented `connect:Channel=VOICE`
1931
+ condition. Existing broader invocation policies must be reviewed separately. Local trusted-gateway
1932
+ fixtures do not implement or certify live SigV4 verification. Installed provisioning descriptors lack
1933
+ HTTP API IAM-route planning; deployment and cloud acceptance remain required before enabling intake.
1934
+
1935
+ ### Private scheduled recovery/win-back content expiry (unreleased)
1936
+
1937
+ `processCrmRecoveryRetention({databaseName, environment}, limit)` is a server maintenance entry,
1938
+ not a public GraphQL action or execution-key scope. The database comes only from private host
1939
+ configuration. No session or administrator is synthesized. It uses current explicit active `apps`
1940
+ registry entries and the public deterministic app/database mapping; legacy inferred names, duplicate
1941
+ namespaces, changed revisions, unsupported environments and the control database itself are held.
1942
+
1943
+ A domain checkpoint and sixty-second lease serialize workers and rotate discovery beyond the first
1944
+ page. One invocation checks at most ten apps and redacts at most one hundred due receipts per app.
1945
+ Only `crm_outreach` receipts with an explicit recovery or win-back object and expired/rejected content
1946
+ qualify. A single app-database query clears body, subject, unsubscribe token and recipient email,
1947
+ with revision conflict checks. It preserves the current document's review/source/purpose proof,
1948
+ provider acceptance, unsubscribe hash, unknown/submitting state and opportunity claim edges.
1949
+ Ordinary outreach, Support messages, financial records and unexpired content remain unchanged.
1950
+ A database/revision failure holds that app; cleanup is idempotent and never sends or retries customers.
1951
+
1952
+ `crmRecoveryRetentionWorker.ts` is a private scheduled host entry. The SAM configuration defines a
1953
+ fifteen-minute schedule, disabled by default, concurrency one and no public API event or provider/send
1954
+ IAM policy. Enable it only after reviewing the actual control registry, per-app database permissions
1955
+ and cloud transaction acceptance. At-rest scheduled expiry happens only after deployment and opt-in;
1956
+ large receipt/app backlogs need successive bounded passes. Local tests do not certify deployed IAM.
1957
+ Registry fencing and app receipt mutation span separate databases; the final registry read does not
1958
+ lock the registry across the app transaction. Receipt redaction itself is atomic with revision guards;
1959
+ this residual namespace read-to-mutation window cannot authorize customer operations.
1960
+
1961
+ ### Conditional verified-purchase win-back
1962
+
1963
+ `createCrmExecutionKey` accepts a separate `crm:winback` scope only with `crm:outreach` and strict
1964
+ `winbackBounds`: exact organization/project/campaign/source IDs, current app-owned issuer IDs,
1965
+ `quietDays` 30–365 and cross-outreach `cooldownHours` 24–720. These do not reuse lead-followup or
1966
+ checkout-recovery authority. Server-only `CRM_WINBACK_SOURCES` entries require explicit current
1967
+ orders/customer/all-orders access approvals and an expiring protected Shopify token. Default 60-day
1968
+ order coverage is insufficient.
1969
+
1970
+ A customer calls `getOwnCrmWinbackConsent` / `recordCrmWinbackConsent` under their own native session,
1971
+ with exact user and independent purpose-document revisions. Merchant administrator intent cannot
1972
+ substitute for this consent. The purpose document leaves the user's financial-evidence revision unchanged.
1973
+ An administrator can associate it with an existing current canonical financial binding using
1974
+ `registerCrmWinbackBinding`; registration never asserts settlement. Actual issued/native evidence,
1975
+ current Stripe customer/charge/refunds, positive remaining settlement and exact current Shopify
1976
+ shop/customer/order/payment namespace must independently agree. Unsupported gateways, namespace,
1977
+ protected access, refunds, suppression or uncertain evidence remain held.
1978
+
1979
+ `getCrmWinbackCandidates` / GraphQL `crm.winbackCandidates(input:JSON!)` enumerate at most 25 current
1980
+ review candidates from exact registered purchase associations. `complete` and `truncated` describe
1981
+ this bounded enumeration, not a customer's global history. Eligibility only proves no recent order
1982
+ updates in the verified shop using protected all-order access and its maximum updated order; it never
1983
+ claims global inactivity or invents a lifecycle event. Cached candidates contain no provider charge,
1984
+ financial binding, source token or recovery URL. A preview uses `winback:{candidateId,revision}`, freezes
1985
+ one exact recipient/body/unsubscribe capability and requires separate approval and execution.
1986
+
1987
+ All action boundaries recheck purpose, protected source, native financial CAS, actual settlement,
1988
+ current recipient/suppression and cadence. The once-only purchase opportunity namespace is actual
1989
+ app/shop/customer/charge/purpose, independent of grant, token, campaign and binding aliases. Unknown
1990
+ submissions keep their durable claim and cannot retry; CRM's default SES transport explicitly permits
1991
+ one SDK attempt. Expired/rejected/withdrawn candidate content is redacted while state, receipt revision,
1992
+ provider acceptance and once-only accounting remain. The separate host retention worker covers
1993
+ explicit recovery/win-back outreach receipts; deployment/credentials and real provider acceptance
1994
+ remain unexercised by the mocked verification suite.
@@ -127,9 +127,11 @@ const memories = JSON.parse(result.text); // Validate application-specific data
127
127
  `responseFormat` supports `{type: 'text'}`, `{type: 'json_object'}`, or
128
128
  `{type: 'json_schema', name, schema, strict?, description?}`. `reasoningEffort` accepts
129
129
  `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, or `max`; model support is checked by the
130
- provider. These fields and `messages` are currently OpenAI-only; other providers reject
131
- them before submitting instead of silently dropping them. Image messages and tools are not
132
- supported by this text action. Gemini's existing `images` input remains available.
130
+ provider. `reasoningEffort` is OpenAI-only. OpenAI and Gemini support text-only
131
+ `messages`; Gemini supports text and JSON-object response formats, while JSON-schema
132
+ response formats remain OpenAI-only. Unsupported combinations reject before submission.
133
+ Image messages and tools are not supported by this text action. Gemini's existing
134
+ `images` input remains available with prompt input, separately from `messages`.
133
135
 
134
136
  `timeoutMs` applies to all providers and defaults to 120000. It must be a positive
135
137
  32-bit integer. A timeout does not prove the provider stopped working or did not charge.
@@ -211,8 +213,9 @@ callers own model-specific defaults. Existing prompt/system handling, token budg
211
213
  timeouts, and completion validation are unchanged. Requests still use one submission.
212
214
 
213
215
  Gemini JSON schemas, image-generation output controls, and temperature on other
214
- providers are rejected before submission, rather than silently discarded. Messages
215
- and reasoning effort remain OpenAI-only. This addition is generic provider transport;
216
+ providers are rejected before submission, rather than silently discarded. Reasoning
217
+ effort remains OpenAI-only; Gemini text conversations are described in the 1.19
218
+ section below. This addition is generic provider transport;
216
219
  it contains no application prompts, reviewer choices, or writing policies.
217
220
 
218
221
  Reference: [Gemini generation configuration](https://ai.google.dev/api/generate-content#v1beta.GenerationConfig).
@@ -308,14 +311,37 @@ policy belongs to callers; Reaktor adds no defaults or application prompts.
308
311
  ## Output whitespace
309
312
 
310
313
  The server-side `generateContent` action accepts `outputTextMode: 'preserve'`
311
- for Claude Messages and OpenAI/Grok Responses calls. Preserve mode concatenates
312
- text blocks exactly, adding no separators and keeping surrounding whitespace.
313
- Claude thinking/redacted-thinking blocks are excluded; unsupported blocks or
314
- malformed text are rejected in preserve mode. A normally completed, nonblank
315
- text response is still required.
316
-
317
- Omit the option or use `'trim'` to keep existing behavior: OpenAI/Grok trim their
318
- concatenated text; Claude inserts newlines between text blocks before trimming.
319
- Other providers reject the option before submission. It is local output policy
320
- and is never sent to a provider; GraphQL input does not expose it. The option does
321
- not enable or select Claude thinking settings or alter provider request bodies.
314
+ for Claude Messages, Gemini text, and OpenAI/Grok Responses calls. Preserve mode
315
+ concatenates text blocks exactly by default, retaining surrounding whitespace.
316
+ Claude thinking/redacted-thinking blocks and Gemini thought parts are excluded;
317
+ unsupported or malformed exact output rejects. Normally completed, nonblank
318
+ text remains required.
319
+
320
+ Omit the option or use trim to keep prior behavior: OpenAI/Grok trim concatenated
321
+ text; Claude/Gemini insert newlines between text blocks before trimming. Ollama
322
+ and image requests reject this option. It is local output policy, never sent to
323
+ providers, and GraphQL input does not expose it. Separate explicit thinking controls
324
+ are described below; output preservation does not select them.
325
+
326
+ ### Exact text parts and Gemini conversations (1.19.0)
327
+
328
+ `generateContent` accepts `outputTextMode: 'preserve'` for Claude, Gemini,
329
+ OpenAI and Grok text output. Defaults retain existing trimming. For Claude/Gemini
330
+ preserve mode, `outputTextSeparator: '' | '\n'` selects text-block concatenation
331
+ (the default is empty), and `outputTextFilter: 'nonblank'` omits blank blocks
332
+ without trimming retained strings. These controls are never provider request fields.
333
+ Unsupported, incomplete or blank exact output rejects; callers own durable claims
334
+ and must not automatically replay an uncertain submission.
335
+
336
+ Gemini also accepts text-only `messages` with user/assistant roles. String content
337
+ becomes one text part; arrays of `{type: 'text', text}` preserve text part boundaries.
338
+ Assistant maps to the provider's model role. Supply either prompt or messages;
339
+ `system` remains a separate instruction. Image content and system/developer message
340
+ roles are rejected for this conversation profile. `thinkingLevel` can explicitly
341
+ select minimal, low, medium or high on Gemini text requests; no level is injected
342
+ by default. Model-specific capability/account availability is caller-owned.
343
+ See [Google's thinking controls](https://ai.google.dev/gemini-api/docs/thinking).
344
+
345
+ ## Explicit URL evidence (1.20.0)
346
+
347
+ Gemini 2.5 Flash text requests with prompt input accept bounded explicit `urlContext` URLs, optionally combined with search. The action exposes verified `grounding` and URL retrieval metadata plus validated provider `usage` counts. Missing or malformed counts remain absent. URL context with `messages` rejects before submission; URLs must never be silently ignored. Output preservation options remain supported. Callers own authorization, durable paid-operation claims, source interpretation and uncertain-outcome reconciliation.
@@ -203,4 +203,4 @@ export const faqAction = async (context, operation, value = {})=>{
203
203
  }
204
204
  };
205
205
 
206
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L3JlYWt0b3IvcGFja2FnZXMvcmVha3Rvci9zcmMvYWN0aW9ucy9hbGZyZWRGYXEudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtjcmVhdGVIYXNofSBmcm9tICdub2RlOmNyeXB0byc7XG5pbXBvcnQge2FxbH0gZnJvbSAnYXJhbmdvanMnO1xuaW1wb3J0IHt1c2VEYn0gZnJvbSAnLi4vdXRpbHMvYXJhbmdvZGJVdGlscy5qcyc7XG5pbXBvcnQgdHlwZSB7QXBpQ29udGV4dH0gZnJvbSAnLi4vdHlwZXMvYXV0aC50eXBlcy5qcyc7XG5cbmludGVyZmFjZSBGYXFTb3VyY2Uge3RpdGxlOiBzdHJpbmc7IHVybDogc3RyaW5nfVxuaW50ZXJmYWNlIFRvcGljIHsgX2tleTogc3RyaW5nOyBhbnN3ZXI/OiBzdHJpbmc7IGFuc3dlckV4cGlyZXM/OiBudW1iZXI7IGFwcElkOiBzdHJpbmc7IGVtYmVkZGluZz86IG51bWJlcltdOyBraW5kOiBzdHJpbmc7IGxhc3RBc2tlZDogbnVtYmVyOyBwcm9kdWN0Pzogc3RyaW5nOyBxdWVzdGlvbjogc3RyaW5nOyBzb3VyY2VzPzogRmFxU291cmNlW107IHdlaWdodDogbnVtYmVyfVxuaW50ZXJmYWNlIEZhcUlucHV0IHtjaGFubmVsOiAnd2Vic2l0ZScgfCAncGhvbmUnOyBlbWJlZGRpbmc6IG51bWJlcltdOyBldmVudElkOiBzdHJpbmc7IHByb2R1Y3Q6IHN0cmluZzsgcXVlc3Rpb246IHN0cmluZzsgcmV2aXNpb246IG51bWJlcjsgdG9waWNJZDogc3RyaW5nfVxuY29uc3QgaGFzaCA9ICh2YWx1ZTogc3RyaW5nKTogc3RyaW5nID0+IGNyZWF0ZUhhc2goJ3NoYTI1NicpLnVwZGF0ZSh2YWx1ZSkuZGlnZXN0KCdoZXgnKTtcbmNvbnN0IHByb2R1Y3RzID0gbmV3IFNldChbJ2FsZnJlZCcsICduaXRyb2dlbicsICduaXRyb2dlbi1sYWJzJywgJ25pdHJvZ2VuLXN0dWRpb3MnLCAncmVha3RvcicsICdnb3RoYW11aScsICdsYW50ZXJudWknLCAnbWV0cm9wb2xpc2pzJywgJ2Fya2hhbWpzJywgJ2xleCcsICd0b3JjaG9uZScsICdwdWxzaWZ5JywgJ3BoYW50YXplJywgJ3JlYWN0b3Jib3gnXSk7XG5jb25zdCBzYWZlVGV4dCA9ICh2YWx1ZTogdW5rbm93biwgbWF4OiBudW1iZXIpOiB2YWx1ZSBpcyBzdHJpbmcgPT4gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiB2YWx1ZS50cmltKCkubGVuZ3RoID49IDggJiYgdmFsdWUubGVuZ3RoIDw9IG1heCAmJiAhL1tAPD5dfFxcYig/OnNrX3xBS0lBKXwoPzpcXGRbXFxzKCktXSopezd9L2kudGVzdCh2YWx1ZSk7XG5jb25zdCB2ZWN0b3JWYWxpZCA9ICh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIG51bWJlcltdID0+IEFycmF5LmlzQXJyYXkodmFsdWUpICYmIHZhbHVlLmxlbmd0aCA9PT0gMjU2ICYmIHZhbHVlLmV2ZXJ5KChuKSA9PiB0eXBlb2YgbiA9PT0gJ251bWJlcicgJiYgTnVtYmVyLmlzRmluaXRlKG4pKSAmJiB2YWx1ZS5zb21lKChuKSA9PiBuICE9PSAwKTtcbmNvbnN0IHNvdXJjZVZhbGlkID0gKHNvdXJjZTogRmFxU291cmNlKTogYm9vbGVhbiA9PiB7XG4gIHRyeSB7Y29uc3QgdXJsID0gbmV3IFVSTChzb3VyY2UudXJsKTsgcmV0dXJuIHR5cGVvZiBzb3VyY2UudGl0bGUgPT09ICdzdHJpbmcnICYmIHNvdXJjZS50aXRsZS5sZW5ndGggPD0gMjAwICYmIHVybC5wcm90b2NvbCA9PT0gJ2h0dHBzOicgJiYgIXVybC51c2VybmFtZSAmJiAhdXJsLnBhc3N3b3JkICYmICF1cmwuc2VhcmNoICYmIFsnbml0cm9nZW54LmNvJywgJ3d3dy5uaXRyb2dlbnguY28nLCAncmVha3Rvci5pbycsICd0b3JjaC5vbmUnLCAncHVsc2lmeS5jb20nLCAncGhhbnRhemUuY29tJywgJ3JlYWN0b3Jib3guY29tJywgLi4uWydhbGZyZWQnLCAncmVha3RvcicsICdnb3RoYW11aScsICdsYW50ZXJudWknLCAnbWV0cm9wb2xpc2pzJywgJ2Fya2hhbWpzJywgJ2xleCddLm1hcCgobmFtZSkgPT4gYCR7bmFtZX0ubml0cm9nZW54LmNvYCldLmluY2x1ZGVzKHVybC5ob3N0bmFtZSk7fSBjYXRjaCB7cmV0dXJuIGZhbHNlO31cbn07XG5leHBvcnQgY29uc3QgdmFsaWRhdGVGYXFJbnB1dCA9ICh2YWx1ZTogdW5rbm93bik6IEZhcUlucHV0ID0+IHtcbiAgY29uc3QgdiA9IHZhbHVlIGFzIEZhcUlucHV0O1xuICBpZighdiB8fCAhc2FmZVRleHQodi5xdWVzdGlvbiwgNTAwKSB8fCAhcHJvZHVjdHMuaGFzKHYucHJvZHVjdCkgfHwgIVsnd2Vic2l0ZScsICdwaG9uZSddLmluY2x1ZGVzKHYuY2hhbm5lbCkgfHwgIS9eW2EtZjAtOV17NjR9JC8udGVzdCh2LmV2ZW50SWQpIHx8ICF2ZWN0b3JWYWxpZCh2LmVtYmVkZGluZykgfHwgIU51bWJlci5pc1NhZmVJbnRlZ2VyKHYucmV2aXNpb24pIHx8IHYucmV2aXNpb24gPCAwIHx8IHR5cGVvZiB2LnRvcGljSWQgIT09ICdzdHJpbmcnIHx8ICh2LnRvcGljSWQgJiYgIS9edG9waWMtW2EtZjAtOV17NjR9JC8udGVzdCh2LnRvcGljSWQpKSkgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkX2ZhcV9pbnB1dCcpO1xuICByZXR1cm4ge2NoYW5uZWw6IHYuY2hhbm5lbCwgZW1iZWRkaW5nOiB2LmVtYmVkZGluZywgZXZlbnRJZDogdi5ldmVudElkLCBwcm9kdWN0OiB2LnByb2R1Y3QsIHF1ZXN0aW9uOiB2LnF1ZXN0aW9uLnRyaW0oKSwgcmV2aXNpb246IHYucmV2aXNpb24sIHRvcGljSWQ6IHYudG9waWNJZH07XG59O1xuZXhwb3J0IGNvbnN0IHB1YmxpY0ZhcSA9ICh0b3BpY3M6IFRvcGljW10sIG5vdzogbnVtYmVyKSA9PiB0b3BpY3MuZmlsdGVyKCh0b3BpYykgPT4gdG9waWMuYXBwSWQgPT09ICduaXRyb2dlbngnICYmIHRvcGljLmtpbmQgPT09ICd0b3BpYycgJiYgdG9waWMud2VpZ2h0ID49IDMgJiYgc2FmZVRleHQodG9waWMuYW5zd2VyLCAyNTAwKSAmJiAodG9waWMuYW5zd2VyRXhwaXJlcyB8fCAwKSA+IG5vdyAmJiB0b3BpYy5zb3VyY2VzPy5sZW5ndGggJiYgdG9waWMuc291cmNlcy5ldmVyeShzb3VyY2VWYWxpZCkpLnNvcnQoKGEsIGIpID0+IGIud2VpZ2h0IC0gYS53ZWlnaHQgfHwgYi5sYXN0QXNrZWQgLSBhLmxhc3RBc2tlZCB8fCBhLl9rZXkubG9jYWxlQ29tcGFyZShiLl9rZXkpKS5zbGljZSgwLCAxNSkubWFwKCh7X2tleSwgYW5zd2VyLCBxdWVzdGlvbiwgc291cmNlc30pID0+ICh7YW5zd2VyLCBpZDogX2tleSwgcXVlc3Rpb24sIHNvdXJjZXN9KSk7XG5jb25zdCBjb3NpbmUgPSAoYTogbnVtYmVyW10sIGI6IG51bWJlcltdKTogbnVtYmVyID0+IHtcbiAgaWYoIXZlY3RvclZhbGlkKGIpKSByZXR1cm4gLTE7XG4gIHJldHVybiBhLnJlZHVjZSgoc3VtLCBuLCBpKSA9PiBzdW0gKyBuICogYltpXSwgMCkgLyBNYXRoLnNxcnQoYS5yZWR1Y2UoKHN1bSwgbikgPT4gc3VtICsgbiAqIG4sIDApICogYi5yZWR1Y2UoKHN1bSwgbikgPT4gc3VtICsgbiAqIG4sIDApKTtcbn07XG5leHBvcnQgY29uc3QgZmFxQWN0aW9uID0gYXN5bmMgKGNvbnRleHQ6IEFwaUNvbnRleHQsIG9wZXJhdGlvbjogc3RyaW5nLCB2YWx1ZTogdW5rbm93biA9IHt9KSA9PiB7XG4gIGNvbnN0IGRiID0gdXNlRGIoY29udGV4dC5kYXRhYmFzZU5hbWUpO1xuICBjb25zdCBjb2xsZWN0aW9uID0gZGIuY29sbGVjdGlvbignYWxmcmVkRmFxJyk7XG4gIGlmKCFhd2FpdCBjb2xsZWN0aW9uLmV4aXN0cygpKSB7dHJ5IHthd2FpdCBjb2xsZWN0aW9uLmNyZWF0ZSgpO30gY2F0Y2goZXJyb3IpIHtpZighYXdhaXQgY29sbGVjdGlvbi5leGlzdHMoKSkgdGhyb3cgZXJyb3I7fX1cbiAgYXdhaXQgY29sbGVjdGlvbi5lbnN1cmVJbmRleCh7ZmllbGRzOiBbJ2FwcElkJywgJ2tpbmQnLCAncHJvZHVjdCddLCB0eXBlOiAncGVyc2lzdGVudCd9KTtcbiAgY29uc3QgaW5wdXQgPSB2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgaWYob3BlcmF0aW9uID09PSAnbGlzdCcgfHwgb3BlcmF0aW9uID09PSAncmVmcmVzaC1saXN0Jykge1xuICAgIGNvbnN0IHRvcGljcyA9IGF3YWl0IGRiLnF1ZXJ5KGFxbGBGT1IgdCBJTiBhbGZyZWRGYXEgRklMVEVSIHQuYXBwSWQgPT0gJ25pdHJvZ2VueCcgQU5EIHQua2luZCA9PSAndG9waWMnIEFORCB0LndlaWdodCA+PSAzIFNPUlQgdC53ZWlnaHQgREVTQywgdC5sYXN0QXNrZWQgREVTQywgdC5fa2V5IEFTQyBSRVRVUk4gdGApLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpKSBhcyBUb3BpY1tdO1xuICAgIHJldHVybiBvcGVyYXRpb24gPT09ICdsaXN0JyA/IHtpdGVtczogcHVibGljRmFxKHRvcGljcy5maWx0ZXIoKHRvcGljKSA9PiAodG9waWMgYXMgVG9waWMgJiB7c291cmNlUmV2aXNpb24/OiBzdHJpbmd9KS5zb3VyY2VSZXZpc2lvbiA9PT0gaW5wdXQuc291cmNlUmV2aXNpb24pLCBEYXRlLm5vdygpKX0gOiB7aXRlbXM6IHRvcGljc307XG4gIH1cbiAgaWYob3BlcmF0aW9uID09PSAncmVmcmVzaCcpIHtcbiAgICBpZih0eXBlb2YgaW5wdXQudG9waWNJZCAhPT0gJ3N0cmluZycgfHwgIS9edG9waWMtW2EtZjAtOV17NjR9JC8udGVzdChpbnB1dC50b3BpY0lkKSkgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkX2ZhcV9pbnB1dCcpO1xuICAgIGNvbnN0IHZhbGlkID0gc2FmZVRleHQoaW5wdXQuYW5zd2VyLCAyNTAwKSAmJiBBcnJheS5pc0FycmF5KGlucHV0LnNvdXJjZXMpICYmIGlucHV0LnNvdXJjZXMubGVuZ3RoID4gMCAmJiBpbnB1dC5zb3VyY2VzLmxlbmd0aCA8PSAzICYmIGlucHV0LnNvdXJjZXMuZXZlcnkoc291cmNlVmFsaWQpICYmIHR5cGVvZiBpbnB1dC5hbnN3ZXJFeHBpcmVzID09PSAnbnVtYmVyJyAmJiBpbnB1dC5hbnN3ZXJFeHBpcmVzID4gRGF0ZS5ub3coKSAmJiBpbnB1dC5hbnN3ZXJFeHBpcmVzIDw9IERhdGUubm93KCkgKyAxNCAqIDg2NDAwMDAwO1xuICAgIGF3YWl0IGRiLnF1ZXJ5KGFxbGBGT1IgdCBJTiBhbGZyZWRGYXEgRklMVEVSIHQuX2tleSA9PSAke2lucHV0LnRvcGljSWR9IEFORCB0LmFwcElkID09ICduaXRyb2dlbngnIEFORCB0LmtpbmQgPT0gJ3RvcGljJyBVUERBVEUgdCBXSVRIICR7dmFsaWQgPyB7YW5zd2VyOiBpbnB1dC5hbnN3ZXIsIGFuc3dlckV4cGlyZXM6IGlucHV0LmFuc3dlckV4cGlyZXMsIHJlZnJlc2hBZnRlcjogRGF0ZS5ub3coKSArIDEyICogMzYwMDAwMCwgc291cmNlUmV2aXNpb246IGlucHV0LnNvdXJjZVJldmlzaW9uLCBzb3VyY2VzOiBpbnB1dC5zb3VyY2VzfSA6IHthbnN3ZXI6IG51bGwsIGFuc3dlckV4cGlyZXM6IDAsIHJlZnJlc2hBZnRlcjogRGF0ZS5ub3coKSArIDEyICogMzYwMDAwMCwgc291cmNlUmV2aXNpb246IGlucHV0LnNvdXJjZVJldmlzaW9uLCBzb3VyY2VzOiBbXX19IElOIGFsZnJlZEZhcWApO1xuICAgIHJldHVybiB7b2s6IHRydWV9O1xuICB9XG4gIGlmKG9wZXJhdGlvbiAhPT0gJ3JlY29yZCcgJiYgb3BlcmF0aW9uICE9PSAnY2FuZGlkYXRlcycpIHRocm93IG5ldyBFcnJvcignaW52YWxpZF9mYXFfaW5wdXQnKTtcbiAgY29uc3QgZXZlbnQgPSB2YWxpZGF0ZUZhcUlucHV0KHZhbHVlKTtcbiAgY29uc3QgbWV0YUtleSA9IGBjYXRhbG9nLSR7ZXZlbnQucHJvZHVjdH1gO1xuICBjb25zdCB0eCA9IGF3YWl0IGRiLmJlZ2luVHJhbnNhY3Rpb24oe2V4Y2x1c2l2ZTogWydhbGZyZWRGYXEnXX0sIHtsb2NrVGltZW91dDogMTB9KTtcbiAgY29uc3QgbmV4dCA9IGFzeW5jIChxdWVyeTogUmV0dXJuVHlwZTx0eXBlb2YgYXFsPikgPT4gdHguc3RlcCgoKSA9PiBkYi5xdWVyeShxdWVyeSkpLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSBhcyBQcm9taXNlPHthcHBJZD86IHN0cmluZzsga2luZD86IHN0cmluZzsgcHJvZHVjdD86IHN0cmluZzsgcmV2aXNpb24/OiBudW1iZXI7IHRvcGljSWQ/OiBzdHJpbmd9IHwgbnVsbD4pO1xuICB0cnkge1xuICAgIGlmKG9wZXJhdGlvbiA9PT0gJ2NhbmRpZGF0ZXMnKSB7XG4gICAgICBjb25zdCBtZXRhID0gYXdhaXQgbmV4dChhcWxgUkVUVVJOIERPQ1VNRU5UKCdhbGZyZWRGYXEnLCAke21ldGFLZXl9KWApO1xuICAgICAgY29uc3QgdG9waWNzID0gYXdhaXQgdHguc3RlcCgoKSA9PiBkYi5xdWVyeShhcWxgRk9SIHQgSU4gYWxmcmVkRmFxIEZJTFRFUiB0LmFwcElkID09ICduaXRyb2dlbngnIEFORCB0LmtpbmQgPT0gJ3RvcGljJyBBTkQgdC5wcm9kdWN0ID09ICR7ZXZlbnQucHJvZHVjdH0gUkVUVVJOIHRgKSkudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkpIGFzIFRvcGljW107XG4gICAgICBhd2FpdCB0eC5jb21taXQoKTtcbiAgICAgIHJldHVybiB7Y2FuZGlkYXRlczogdG9waWNzLm1hcCgodG9waWMpID0+ICh7aWQ6IHRvcGljLl9rZXksIHF1ZXN0aW9uOiB0b3BpYy5xdWVzdGlvbiwgc2NvcmU6IGNvc2luZShldmVudC5lbWJlZGRpbmcsIHRvcGljLmVtYmVkZGluZyB8fCBbXSl9KSkuZmlsdGVyKCh0b3BpYykgPT4gdG9waWMuc2NvcmUgPj0gMC41NSkuc29ydCgoYSwgYikgPT4gYi5zY29yZSAtIGEuc2NvcmUpLnNsaWNlKDAsIDgpLCByZXZpc2lvbjogbWV0YT8ucmV2aXNpb24gfHwgMH07XG4gICAgfVxuICAgIGNvbnN0IGtleSA9IGBxdWVzdGlvbi0ke2V2ZW50LmV2ZW50SWR9YDtcbiAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IG5leHQoYXFsYFJFVFVSTiBET0NVTUVOVCgnYWxmcmVkRmFxJywgJHtrZXl9KWApO1xuICAgIGlmKGV4aXN0aW5nKSB7YXdhaXQgdHguY29tbWl0KCk7IHJldHVybiB7ZHVwbGljYXRlOiB0cnVlLCB0b3BpY0lkOiBleGlzdGluZy50b3BpY0lkfTt9XG4gICAgY29uc3QgbWV0YSA9IGF3YWl0IG5leHQoYXFsYFJFVFVSTiBET0NVTUVOVCgnYWxmcmVkRmFxJywgJHttZXRhS2V5fSlgKTtcbiAgICBpZigobWV0YT8ucmV2aXNpb24gfHwgMCkgIT09IGV2ZW50LnJldmlzaW9uKSB0aHJvdyBuZXcgRXJyb3IoJ2ZhcV9yZXZpc2lvbl9jb25mbGljdCcpO1xuICAgIGNvbnN0IHRvcGljSWQgPSBldmVudC50b3BpY0lkIHx8IGB0b3BpYy0ke2hhc2goYCR7ZXZlbnQucHJvZHVjdH06JHtldmVudC5xdWVzdGlvbi50b0xvd2VyQ2FzZSgpfWApfWA7XG4gICAgY29uc3QgdGltZXN0YW1wID0gRGF0ZS5ub3coKTtcbiAgICBpZihldmVudC50b3BpY0lkKSB7XG4gICAgICBjb25zdCB0b3BpYyA9IGF3YWl0IG5leHQoYXFsYFJFVFVSTiBET0NVTUVOVCgnYWxmcmVkRmFxJywgJHt0b3BpY0lkfSlgKTtcbiAgICAgIGlmKCF0b3BpYyB8fCB0b3BpYy5hcHBJZCAhPT0gJ25pdHJvZ2VueCcgfHwgdG9waWMucHJvZHVjdCAhPT0gZXZlbnQucHJvZHVjdCB8fCB0b3BpYy5raW5kICE9PSAndG9waWMnKSB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWRfZmFxX2lucHV0Jyk7XG4gICAgfVxuICAgIGF3YWl0IG5leHQoYXFsYFVQU0VSVCB7X2tleTogJHt0b3BpY0lkfX0gSU5TRVJUICR7e19rZXk6IHRvcGljSWQsIGFuc3dlckV4cGlyZXM6IDAsIGFwcElkOiAnbml0cm9nZW54JywgZW1iZWRkaW5nOiBldmVudC5lbWJlZGRpbmcsIGVtYmVkZGluZ01vZGVsOiAnYW1hem9uLnRpdGFuLWVtYmVkLXRleHQtdjI6MC8yNTYnLCBmaXJzdEFza2VkOiB0aW1lc3RhbXAsIGtpbmQ6ICd0b3BpYycsIGxhc3RBc2tlZDogdGltZXN0YW1wLCBwaG9uZUNvdW50OiBldmVudC5jaGFubmVsID09PSAncGhvbmUnID8gMSA6IDAsIHByb2R1Y3Q6IGV2ZW50LnByb2R1Y3QsIHF1ZXN0aW9uOiBldmVudC5xdWVzdGlvbiwgd2Vic2l0ZUNvdW50OiBldmVudC5jaGFubmVsID09PSAnd2Vic2l0ZScgPyAxIDogMCwgd2VpZ2h0OiAxfX0gVVBEQVRFIHtsYXN0QXNrZWQ6ICR7dGltZXN0YW1wfSwgd2VpZ2h0OiBPTEQud2VpZ2h0ICsgMSwgcGhvbmVDb3VudDogT0xELnBob25lQ291bnQgKyAke2V2ZW50LmNoYW5uZWwgPT09ICdwaG9uZScgPyAxIDogMH0sIHdlYnNpdGVDb3VudDogT0xELndlYnNpdGVDb3VudCArICR7ZXZlbnQuY2hhbm5lbCA9PT0gJ3dlYnNpdGUnID8gMSA6IDB9fSBJTiBhbGZyZWRGYXFgKTtcbiAgICBhd2FpdCBuZXh0KGFxbGBJTlNFUlQgJHt7X2tleToga2V5LCBhcHBJZDogJ25pdHJvZ2VueCcsIGNoYW5uZWw6IGV2ZW50LmNoYW5uZWwsIGNsYXNzaWZpZXJWZXJzaW9uOiAxLCBjcmVhdGVkOiB0aW1lc3RhbXAsIGtpbmQ6ICdxdWVzdGlvbicsIHByb2R1Y3Q6IGV2ZW50LnByb2R1Y3QsIHF1ZXN0aW9uOiBldmVudC5xdWVzdGlvbiwgdG9waWNJZH19IElOIGFsZnJlZEZhcWApO1xuICAgIGF3YWl0IG5leHQoYXFsYFVQU0VSVCB7X2tleTogJHttZXRhS2V5fX0gSU5TRVJUICR7e19rZXk6IG1ldGFLZXksIGFwcElkOiAnbml0cm9nZW54Jywga2luZDogJ2NhdGFsb2cnLCByZXZpc2lvbjogZXZlbnQucmV2aXNpb24gKyAxfX0gVVBEQVRFIHtyZXZpc2lvbjogJHtldmVudC5yZXZpc2lvbiArIDF9fSBJTiBhbGZyZWRGYXFgKTtcbiAgICBhd2FpdCB0eC5jb21taXQoKTtcbiAgICByZXR1cm4ge2R1cGxpY2F0ZTogZmFsc2UsIHRvcGljSWR9O1xuICB9IGNhdGNoKGVycm9yKSB7YXdhaXQgdHguYWJvcnQoKTsgdGhyb3cgZXJyb3I7fVxufTtcbiJdLCJuYW1lcyI6WyJjcmVhdGVIYXNoIiwiYXFsIiwidXNlRGIiLCJoYXNoIiwidmFsdWUiLCJ1cGRhdGUiLCJkaWdlc3QiLCJwcm9kdWN0cyIsIlNldCIsInNhZmVUZXh0IiwibWF4IiwidHJpbSIsImxlbmd0aCIsInRlc3QiLCJ2ZWN0b3JWYWxpZCIsIkFycmF5IiwiaXNBcnJheSIsImV2ZXJ5IiwibiIsIk51bWJlciIsImlzRmluaXRlIiwic29tZSIsInNvdXJjZVZhbGlkIiwic291cmNlIiwidXJsIiwiVVJMIiwidGl0bGUiLCJwcm90b2NvbCIsInVzZXJuYW1lIiwicGFzc3dvcmQiLCJzZWFyY2giLCJtYXAiLCJuYW1lIiwiaW5jbHVkZXMiLCJob3N0bmFtZSIsInZhbGlkYXRlRmFxSW5wdXQiLCJ2IiwicXVlc3Rpb24iLCJoYXMiLCJwcm9kdWN0IiwiY2hhbm5lbCIsImV2ZW50SWQiLCJlbWJlZGRpbmciLCJpc1NhZmVJbnRlZ2VyIiwicmV2aXNpb24iLCJ0b3BpY0lkIiwiRXJyb3IiLCJwdWJsaWNGYXEiLCJ0b3BpY3MiLCJub3ciLCJmaWx0ZXIiLCJ0b3BpYyIsImFwcElkIiwia2luZCIsIndlaWdodCIsImFuc3dlciIsImFuc3dlckV4cGlyZXMiLCJzb3VyY2VzIiwic29ydCIsImEiLCJiIiwibGFzdEFza2VkIiwiX2tleSIsImxvY2FsZUNvbXBhcmUiLCJzbGljZSIsImlkIiwiY29zaW5lIiwicmVkdWNlIiwic3VtIiwiaSIsIk1hdGgiLCJzcXJ0IiwiZmFxQWN0aW9uIiwiY29udGV4dCIsIm9wZXJhdGlvbiIsImRiIiwiZGF0YWJhc2VOYW1lIiwiY29sbGVjdGlvbiIsImV4aXN0cyIsImNyZWF0ZSIsImVycm9yIiwiZW5zdXJlSW5kZXgiLCJmaWVsZHMiLCJ0eXBlIiwiaW5wdXQiLCJxdWVyeSIsInRoZW4iLCJjdXJzb3IiLCJhbGwiLCJpdGVtcyIsInNvdXJjZVJldmlzaW9uIiwiRGF0ZSIsInZhbGlkIiwicmVmcmVzaEFmdGVyIiwib2siLCJldmVudCIsIm1ldGFLZXkiLCJ0eCIsImJlZ2luVHJhbnNhY3Rpb24iLCJleGNsdXNpdmUiLCJsb2NrVGltZW91dCIsIm5leHQiLCJzdGVwIiwibWV0YSIsImNvbW1pdCIsImNhbmRpZGF0ZXMiLCJzY29yZSIsImtleSIsImV4aXN0aW5nIiwiZHVwbGljYXRlIiwidG9Mb3dlckNhc2UiLCJ0aW1lc3RhbXAiLCJlbWJlZGRpbmdNb2RlbCIsImZpcnN0QXNrZWQiLCJwaG9uZUNvdW50Iiwid2Vic2l0ZUNvdW50IiwiY2xhc3NpZmllclZlcnNpb24iLCJjcmVhdGVkIiwiYWJvcnQiXSwibWFwcGluZ3MiOiJBQUFBLFNBQVFBLFVBQVUsUUFBTyxjQUFjO0FBQ3ZDLFNBQVFDLEdBQUcsUUFBTyxXQUFXO0FBQzdCLFNBQVFDLEtBQUssUUFBTyw0QkFBNEI7QUFNaEQsTUFBTUMsT0FBTyxDQUFDQyxRQUEwQkosV0FBVyxVQUFVSyxNQUFNLENBQUNELE9BQU9FLE1BQU0sQ0FBQztBQUNsRixNQUFNQyxXQUFXLElBQUlDLElBQUk7SUFBQztJQUFVO0lBQVk7SUFBaUI7SUFBb0I7SUFBVztJQUFZO0lBQWE7SUFBZ0I7SUFBWTtJQUFPO0lBQVk7SUFBVztJQUFZO0NBQWE7QUFDNU0sTUFBTUMsV0FBVyxDQUFDTCxPQUFnQk0sTUFBaUMsT0FBT04sVUFBVSxZQUFZQSxNQUFNTyxJQUFJLEdBQUdDLE1BQU0sSUFBSSxLQUFLUixNQUFNUSxNQUFNLElBQUlGLE9BQU8sQ0FBQywwQ0FBMENHLElBQUksQ0FBQ1Q7QUFDbk0sTUFBTVUsY0FBYyxDQUFDVixR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
206
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9wcml2YXRlL3RtcC92YXVsdC1yZWFrdG9yLWNvbXBsZXRpb24vcGFja2FnZXMvcmVha3Rvci9zcmMvYWN0aW9ucy9hbGZyZWRGYXEudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtjcmVhdGVIYXNofSBmcm9tICdub2RlOmNyeXB0byc7XG5pbXBvcnQge2FxbH0gZnJvbSAnYXJhbmdvanMnO1xuaW1wb3J0IHt1c2VEYn0gZnJvbSAnLi4vdXRpbHMvYXJhbmdvZGJVdGlscy5qcyc7XG5pbXBvcnQgdHlwZSB7QXBpQ29udGV4dH0gZnJvbSAnLi4vdHlwZXMvYXV0aC50eXBlcy5qcyc7XG5cbmludGVyZmFjZSBGYXFTb3VyY2Uge3RpdGxlOiBzdHJpbmc7IHVybDogc3RyaW5nfVxuaW50ZXJmYWNlIFRvcGljIHsgX2tleTogc3RyaW5nOyBhbnN3ZXI/OiBzdHJpbmc7IGFuc3dlckV4cGlyZXM/OiBudW1iZXI7IGFwcElkOiBzdHJpbmc7IGVtYmVkZGluZz86IG51bWJlcltdOyBraW5kOiBzdHJpbmc7IGxhc3RBc2tlZDogbnVtYmVyOyBwcm9kdWN0Pzogc3RyaW5nOyBxdWVzdGlvbjogc3RyaW5nOyBzb3VyY2VzPzogRmFxU291cmNlW107IHdlaWdodDogbnVtYmVyfVxuaW50ZXJmYWNlIEZhcUlucHV0IHtjaGFubmVsOiAnd2Vic2l0ZScgfCAncGhvbmUnOyBlbWJlZGRpbmc6IG51bWJlcltdOyBldmVudElkOiBzdHJpbmc7IHByb2R1Y3Q6IHN0cmluZzsgcXVlc3Rpb246IHN0cmluZzsgcmV2aXNpb246IG51bWJlcjsgdG9waWNJZDogc3RyaW5nfVxuY29uc3QgaGFzaCA9ICh2YWx1ZTogc3RyaW5nKTogc3RyaW5nID0+IGNyZWF0ZUhhc2goJ3NoYTI1NicpLnVwZGF0ZSh2YWx1ZSkuZGlnZXN0KCdoZXgnKTtcbmNvbnN0IHByb2R1Y3RzID0gbmV3IFNldChbJ2FsZnJlZCcsICduaXRyb2dlbicsICduaXRyb2dlbi1sYWJzJywgJ25pdHJvZ2VuLXN0dWRpb3MnLCAncmVha3RvcicsICdnb3RoYW11aScsICdsYW50ZXJudWknLCAnbWV0cm9wb2xpc2pzJywgJ2Fya2hhbWpzJywgJ2xleCcsICd0b3JjaG9uZScsICdwdWxzaWZ5JywgJ3BoYW50YXplJywgJ3JlYWN0b3Jib3gnXSk7XG5jb25zdCBzYWZlVGV4dCA9ICh2YWx1ZTogdW5rbm93biwgbWF4OiBudW1iZXIpOiB2YWx1ZSBpcyBzdHJpbmcgPT4gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyAmJiB2YWx1ZS50cmltKCkubGVuZ3RoID49IDggJiYgdmFsdWUubGVuZ3RoIDw9IG1heCAmJiAhL1tAPD5dfFxcYig/OnNrX3xBS0lBKXwoPzpcXGRbXFxzKCktXSopezd9L2kudGVzdCh2YWx1ZSk7XG5jb25zdCB2ZWN0b3JWYWxpZCA9ICh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIG51bWJlcltdID0+IEFycmF5LmlzQXJyYXkodmFsdWUpICYmIHZhbHVlLmxlbmd0aCA9PT0gMjU2ICYmIHZhbHVlLmV2ZXJ5KChuKSA9PiB0eXBlb2YgbiA9PT0gJ251bWJlcicgJiYgTnVtYmVyLmlzRmluaXRlKG4pKSAmJiB2YWx1ZS5zb21lKChuKSA9PiBuICE9PSAwKTtcbmNvbnN0IHNvdXJjZVZhbGlkID0gKHNvdXJjZTogRmFxU291cmNlKTogYm9vbGVhbiA9PiB7XG4gIHRyeSB7Y29uc3QgdXJsID0gbmV3IFVSTChzb3VyY2UudXJsKTsgcmV0dXJuIHR5cGVvZiBzb3VyY2UudGl0bGUgPT09ICdzdHJpbmcnICYmIHNvdXJjZS50aXRsZS5sZW5ndGggPD0gMjAwICYmIHVybC5wcm90b2NvbCA9PT0gJ2h0dHBzOicgJiYgIXVybC51c2VybmFtZSAmJiAhdXJsLnBhc3N3b3JkICYmICF1cmwuc2VhcmNoICYmIFsnbml0cm9nZW54LmNvJywgJ3d3dy5uaXRyb2dlbnguY28nLCAncmVha3Rvci5pbycsICd0b3JjaC5vbmUnLCAncHVsc2lmeS5jb20nLCAncGhhbnRhemUuY29tJywgJ3JlYWN0b3Jib3guY29tJywgLi4uWydhbGZyZWQnLCAncmVha3RvcicsICdnb3RoYW11aScsICdsYW50ZXJudWknLCAnbWV0cm9wb2xpc2pzJywgJ2Fya2hhbWpzJywgJ2xleCddLm1hcCgobmFtZSkgPT4gYCR7bmFtZX0ubml0cm9nZW54LmNvYCldLmluY2x1ZGVzKHVybC5ob3N0bmFtZSk7fSBjYXRjaCB7cmV0dXJuIGZhbHNlO31cbn07XG5leHBvcnQgY29uc3QgdmFsaWRhdGVGYXFJbnB1dCA9ICh2YWx1ZTogdW5rbm93bik6IEZhcUlucHV0ID0+IHtcbiAgY29uc3QgdiA9IHZhbHVlIGFzIEZhcUlucHV0O1xuICBpZighdiB8fCAhc2FmZVRleHQodi5xdWVzdGlvbiwgNTAwKSB8fCAhcHJvZHVjdHMuaGFzKHYucHJvZHVjdCkgfHwgIVsnd2Vic2l0ZScsICdwaG9uZSddLmluY2x1ZGVzKHYuY2hhbm5lbCkgfHwgIS9eW2EtZjAtOV17NjR9JC8udGVzdCh2LmV2ZW50SWQpIHx8ICF2ZWN0b3JWYWxpZCh2LmVtYmVkZGluZykgfHwgIU51bWJlci5pc1NhZmVJbnRlZ2VyKHYucmV2aXNpb24pIHx8IHYucmV2aXNpb24gPCAwIHx8IHR5cGVvZiB2LnRvcGljSWQgIT09ICdzdHJpbmcnIHx8ICh2LnRvcGljSWQgJiYgIS9edG9waWMtW2EtZjAtOV17NjR9JC8udGVzdCh2LnRvcGljSWQpKSkgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkX2ZhcV9pbnB1dCcpO1xuICByZXR1cm4ge2NoYW5uZWw6IHYuY2hhbm5lbCwgZW1iZWRkaW5nOiB2LmVtYmVkZGluZywgZXZlbnRJZDogdi5ldmVudElkLCBwcm9kdWN0OiB2LnByb2R1Y3QsIHF1ZXN0aW9uOiB2LnF1ZXN0aW9uLnRyaW0oKSwgcmV2aXNpb246IHYucmV2aXNpb24sIHRvcGljSWQ6IHYudG9waWNJZH07XG59O1xuZXhwb3J0IGNvbnN0IHB1YmxpY0ZhcSA9ICh0b3BpY3M6IFRvcGljW10sIG5vdzogbnVtYmVyKSA9PiB0b3BpY3MuZmlsdGVyKCh0b3BpYykgPT4gdG9waWMuYXBwSWQgPT09ICduaXRyb2dlbngnICYmIHRvcGljLmtpbmQgPT09ICd0b3BpYycgJiYgdG9waWMud2VpZ2h0ID49IDMgJiYgc2FmZVRleHQodG9waWMuYW5zd2VyLCAyNTAwKSAmJiAodG9waWMuYW5zd2VyRXhwaXJlcyB8fCAwKSA+IG5vdyAmJiB0b3BpYy5zb3VyY2VzPy5sZW5ndGggJiYgdG9waWMuc291cmNlcy5ldmVyeShzb3VyY2VWYWxpZCkpLnNvcnQoKGEsIGIpID0+IGIud2VpZ2h0IC0gYS53ZWlnaHQgfHwgYi5sYXN0QXNrZWQgLSBhLmxhc3RBc2tlZCB8fCBhLl9rZXkubG9jYWxlQ29tcGFyZShiLl9rZXkpKS5zbGljZSgwLCAxNSkubWFwKCh7X2tleSwgYW5zd2VyLCBxdWVzdGlvbiwgc291cmNlc30pID0+ICh7YW5zd2VyLCBpZDogX2tleSwgcXVlc3Rpb24sIHNvdXJjZXN9KSk7XG5jb25zdCBjb3NpbmUgPSAoYTogbnVtYmVyW10sIGI6IG51bWJlcltdKTogbnVtYmVyID0+IHtcbiAgaWYoIXZlY3RvclZhbGlkKGIpKSByZXR1cm4gLTE7XG4gIHJldHVybiBhLnJlZHVjZSgoc3VtLCBuLCBpKSA9PiBzdW0gKyBuICogYltpXSwgMCkgLyBNYXRoLnNxcnQoYS5yZWR1Y2UoKHN1bSwgbikgPT4gc3VtICsgbiAqIG4sIDApICogYi5yZWR1Y2UoKHN1bSwgbikgPT4gc3VtICsgbiAqIG4sIDApKTtcbn07XG5leHBvcnQgY29uc3QgZmFxQWN0aW9uID0gYXN5bmMgKGNvbnRleHQ6IEFwaUNvbnRleHQsIG9wZXJhdGlvbjogc3RyaW5nLCB2YWx1ZTogdW5rbm93biA9IHt9KSA9PiB7XG4gIGNvbnN0IGRiID0gdXNlRGIoY29udGV4dC5kYXRhYmFzZU5hbWUpO1xuICBjb25zdCBjb2xsZWN0aW9uID0gZGIuY29sbGVjdGlvbignYWxmcmVkRmFxJyk7XG4gIGlmKCFhd2FpdCBjb2xsZWN0aW9uLmV4aXN0cygpKSB7dHJ5IHthd2FpdCBjb2xsZWN0aW9uLmNyZWF0ZSgpO30gY2F0Y2goZXJyb3IpIHtpZighYXdhaXQgY29sbGVjdGlvbi5leGlzdHMoKSkgdGhyb3cgZXJyb3I7fX1cbiAgYXdhaXQgY29sbGVjdGlvbi5lbnN1cmVJbmRleCh7ZmllbGRzOiBbJ2FwcElkJywgJ2tpbmQnLCAncHJvZHVjdCddLCB0eXBlOiAncGVyc2lzdGVudCd9KTtcbiAgY29uc3QgaW5wdXQgPSB2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgaWYob3BlcmF0aW9uID09PSAnbGlzdCcgfHwgb3BlcmF0aW9uID09PSAncmVmcmVzaC1saXN0Jykge1xuICAgIGNvbnN0IHRvcGljcyA9IGF3YWl0IGRiLnF1ZXJ5KGFxbGBGT1IgdCBJTiBhbGZyZWRGYXEgRklMVEVSIHQuYXBwSWQgPT0gJ25pdHJvZ2VueCcgQU5EIHQua2luZCA9PSAndG9waWMnIEFORCB0LndlaWdodCA+PSAzIFNPUlQgdC53ZWlnaHQgREVTQywgdC5sYXN0QXNrZWQgREVTQywgdC5fa2V5IEFTQyBSRVRVUk4gdGApLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpKSBhcyBUb3BpY1tdO1xuICAgIHJldHVybiBvcGVyYXRpb24gPT09ICdsaXN0JyA/IHtpdGVtczogcHVibGljRmFxKHRvcGljcy5maWx0ZXIoKHRvcGljKSA9PiAodG9waWMgYXMgVG9waWMgJiB7c291cmNlUmV2aXNpb24/OiBzdHJpbmd9KS5zb3VyY2VSZXZpc2lvbiA9PT0gaW5wdXQuc291cmNlUmV2aXNpb24pLCBEYXRlLm5vdygpKX0gOiB7aXRlbXM6IHRvcGljc307XG4gIH1cbiAgaWYob3BlcmF0aW9uID09PSAncmVmcmVzaCcpIHtcbiAgICBpZih0eXBlb2YgaW5wdXQudG9waWNJZCAhPT0gJ3N0cmluZycgfHwgIS9edG9waWMtW2EtZjAtOV17NjR9JC8udGVzdChpbnB1dC50b3BpY0lkKSkgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkX2ZhcV9pbnB1dCcpO1xuICAgIGNvbnN0IHZhbGlkID0gc2FmZVRleHQoaW5wdXQuYW5zd2VyLCAyNTAwKSAmJiBBcnJheS5pc0FycmF5KGlucHV0LnNvdXJjZXMpICYmIGlucHV0LnNvdXJjZXMubGVuZ3RoID4gMCAmJiBpbnB1dC5zb3VyY2VzLmxlbmd0aCA8PSAzICYmIGlucHV0LnNvdXJjZXMuZXZlcnkoc291cmNlVmFsaWQpICYmIHR5cGVvZiBpbnB1dC5hbnN3ZXJFeHBpcmVzID09PSAnbnVtYmVyJyAmJiBpbnB1dC5hbnN3ZXJFeHBpcmVzID4gRGF0ZS5ub3coKSAmJiBpbnB1dC5hbnN3ZXJFeHBpcmVzIDw9IERhdGUubm93KCkgKyAxNCAqIDg2NDAwMDAwO1xuICAgIGF3YWl0IGRiLnF1ZXJ5KGFxbGBGT1IgdCBJTiBhbGZyZWRGYXEgRklMVEVSIHQuX2tleSA9PSAke2lucHV0LnRvcGljSWR9IEFORCB0LmFwcElkID09ICduaXRyb2dlbngnIEFORCB0LmtpbmQgPT0gJ3RvcGljJyBVUERBVEUgdCBXSVRIICR7dmFsaWQgPyB7YW5zd2VyOiBpbnB1dC5hbnN3ZXIsIGFuc3dlckV4cGlyZXM6IGlucHV0LmFuc3dlckV4cGlyZXMsIHJlZnJlc2hBZnRlcjogRGF0ZS5ub3coKSArIDEyICogMzYwMDAwMCwgc291cmNlUmV2aXNpb246IGlucHV0LnNvdXJjZVJldmlzaW9uLCBzb3VyY2VzOiBpbnB1dC5zb3VyY2VzfSA6IHthbnN3ZXI6IG51bGwsIGFuc3dlckV4cGlyZXM6IDAsIHJlZnJlc2hBZnRlcjogRGF0ZS5ub3coKSArIDEyICogMzYwMDAwMCwgc291cmNlUmV2aXNpb246IGlucHV0LnNvdXJjZVJldmlzaW9uLCBzb3VyY2VzOiBbXX19IElOIGFsZnJlZEZhcWApO1xuICAgIHJldHVybiB7b2s6IHRydWV9O1xuICB9XG4gIGlmKG9wZXJhdGlvbiAhPT0gJ3JlY29yZCcgJiYgb3BlcmF0aW9uICE9PSAnY2FuZGlkYXRlcycpIHRocm93IG5ldyBFcnJvcignaW52YWxpZF9mYXFfaW5wdXQnKTtcbiAgY29uc3QgZXZlbnQgPSB2YWxpZGF0ZUZhcUlucHV0KHZhbHVlKTtcbiAgY29uc3QgbWV0YUtleSA9IGBjYXRhbG9nLSR7ZXZlbnQucHJvZHVjdH1gO1xuICBjb25zdCB0eCA9IGF3YWl0IGRiLmJlZ2luVHJhbnNhY3Rpb24oe2V4Y2x1c2l2ZTogWydhbGZyZWRGYXEnXX0sIHtsb2NrVGltZW91dDogMTB9KTtcbiAgY29uc3QgbmV4dCA9IGFzeW5jIChxdWVyeTogUmV0dXJuVHlwZTx0eXBlb2YgYXFsPikgPT4gdHguc3RlcCgoKSA9PiBkYi5xdWVyeShxdWVyeSkpLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSBhcyBQcm9taXNlPHthcHBJZD86IHN0cmluZzsga2luZD86IHN0cmluZzsgcHJvZHVjdD86IHN0cmluZzsgcmV2aXNpb24/OiBudW1iZXI7IHRvcGljSWQ/OiBzdHJpbmd9IHwgbnVsbD4pO1xuICB0cnkge1xuICAgIGlmKG9wZXJhdGlvbiA9PT0gJ2NhbmRpZGF0ZXMnKSB7XG4gICAgICBjb25zdCBtZXRhID0gYXdhaXQgbmV4dChhcWxgUkVUVVJOIERPQ1VNRU5UKCdhbGZyZWRGYXEnLCAke21ldGFLZXl9KWApO1xuICAgICAgY29uc3QgdG9waWNzID0gYXdhaXQgdHguc3RlcCgoKSA9PiBkYi5xdWVyeShhcWxgRk9SIHQgSU4gYWxmcmVkRmFxIEZJTFRFUiB0LmFwcElkID09ICduaXRyb2dlbngnIEFORCB0LmtpbmQgPT0gJ3RvcGljJyBBTkQgdC5wcm9kdWN0ID09ICR7ZXZlbnQucHJvZHVjdH0gUkVUVVJOIHRgKSkudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkpIGFzIFRvcGljW107XG4gICAgICBhd2FpdCB0eC5jb21taXQoKTtcbiAgICAgIHJldHVybiB7Y2FuZGlkYXRlczogdG9waWNzLm1hcCgodG9waWMpID0+ICh7aWQ6IHRvcGljLl9rZXksIHF1ZXN0aW9uOiB0b3BpYy5xdWVzdGlvbiwgc2NvcmU6IGNvc2luZShldmVudC5lbWJlZGRpbmcsIHRvcGljLmVtYmVkZGluZyB8fCBbXSl9KSkuZmlsdGVyKCh0b3BpYykgPT4gdG9waWMuc2NvcmUgPj0gMC41NSkuc29ydCgoYSwgYikgPT4gYi5zY29yZSAtIGEuc2NvcmUpLnNsaWNlKDAsIDgpLCByZXZpc2lvbjogbWV0YT8ucmV2aXNpb24gfHwgMH07XG4gICAgfVxuICAgIGNvbnN0IGtleSA9IGBxdWVzdGlvbi0ke2V2ZW50LmV2ZW50SWR9YDtcbiAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IG5leHQoYXFsYFJFVFVSTiBET0NVTUVOVCgnYWxmcmVkRmFxJywgJHtrZXl9KWApO1xuICAgIGlmKGV4aXN0aW5nKSB7YXdhaXQgdHguY29tbWl0KCk7IHJldHVybiB7ZHVwbGljYXRlOiB0cnVlLCB0b3BpY0lkOiBleGlzdGluZy50b3BpY0lkfTt9XG4gICAgY29uc3QgbWV0YSA9IGF3YWl0IG5leHQoYXFsYFJFVFVSTiBET0NVTUVOVCgnYWxmcmVkRmFxJywgJHttZXRhS2V5fSlgKTtcbiAgICBpZigobWV0YT8ucmV2aXNpb24gfHwgMCkgIT09IGV2ZW50LnJldmlzaW9uKSB0aHJvdyBuZXcgRXJyb3IoJ2ZhcV9yZXZpc2lvbl9jb25mbGljdCcpO1xuICAgIGNvbnN0IHRvcGljSWQgPSBldmVudC50b3BpY0lkIHx8IGB0b3BpYy0ke2hhc2goYCR7ZXZlbnQucHJvZHVjdH06JHtldmVudC5xdWVzdGlvbi50b0xvd2VyQ2FzZSgpfWApfWA7XG4gICAgY29uc3QgdGltZXN0YW1wID0gRGF0ZS5ub3coKTtcbiAgICBpZihldmVudC50b3BpY0lkKSB7XG4gICAgICBjb25zdCB0b3BpYyA9IGF3YWl0IG5leHQoYXFsYFJFVFVSTiBET0NVTUVOVCgnYWxmcmVkRmFxJywgJHt0b3BpY0lkfSlgKTtcbiAgICAgIGlmKCF0b3BpYyB8fCB0b3BpYy5hcHBJZCAhPT0gJ25pdHJvZ2VueCcgfHwgdG9waWMucHJvZHVjdCAhPT0gZXZlbnQucHJvZHVjdCB8fCB0b3BpYy5raW5kICE9PSAndG9waWMnKSB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWRfZmFxX2lucHV0Jyk7XG4gICAgfVxuICAgIGF3YWl0IG5leHQoYXFsYFVQU0VSVCB7X2tleTogJHt0b3BpY0lkfX0gSU5TRVJUICR7e19rZXk6IHRvcGljSWQsIGFuc3dlckV4cGlyZXM6IDAsIGFwcElkOiAnbml0cm9nZW54JywgZW1iZWRkaW5nOiBldmVudC5lbWJlZGRpbmcsIGVtYmVkZGluZ01vZGVsOiAnYW1hem9uLnRpdGFuLWVtYmVkLXRleHQtdjI6MC8yNTYnLCBmaXJzdEFza2VkOiB0aW1lc3RhbXAsIGtpbmQ6ICd0b3BpYycsIGxhc3RBc2tlZDogdGltZXN0YW1wLCBwaG9uZUNvdW50OiBldmVudC5jaGFubmVsID09PSAncGhvbmUnID8gMSA6IDAsIHByb2R1Y3Q6IGV2ZW50LnByb2R1Y3QsIHF1ZXN0aW9uOiBldmVudC5xdWVzdGlvbiwgd2Vic2l0ZUNvdW50OiBldmVudC5jaGFubmVsID09PSAnd2Vic2l0ZScgPyAxIDogMCwgd2VpZ2h0OiAxfX0gVVBEQVRFIHtsYXN0QXNrZWQ6ICR7dGltZXN0YW1wfSwgd2VpZ2h0OiBPTEQud2VpZ2h0ICsgMSwgcGhvbmVDb3VudDogT0xELnBob25lQ291bnQgKyAke2V2ZW50LmNoYW5uZWwgPT09ICdwaG9uZScgPyAxIDogMH0sIHdlYnNpdGVDb3VudDogT0xELndlYnNpdGVDb3VudCArICR7ZXZlbnQuY2hhbm5lbCA9PT0gJ3dlYnNpdGUnID8gMSA6IDB9fSBJTiBhbGZyZWRGYXFgKTtcbiAgICBhd2FpdCBuZXh0KGFxbGBJTlNFUlQgJHt7X2tleToga2V5LCBhcHBJZDogJ25pdHJvZ2VueCcsIGNoYW5uZWw6IGV2ZW50LmNoYW5uZWwsIGNsYXNzaWZpZXJWZXJzaW9uOiAxLCBjcmVhdGVkOiB0aW1lc3RhbXAsIGtpbmQ6ICdxdWVzdGlvbicsIHByb2R1Y3Q6IGV2ZW50LnByb2R1Y3QsIHF1ZXN0aW9uOiBldmVudC5xdWVzdGlvbiwgdG9waWNJZH19IElOIGFsZnJlZEZhcWApO1xuICAgIGF3YWl0IG5leHQoYXFsYFVQU0VSVCB7X2tleTogJHttZXRhS2V5fX0gSU5TRVJUICR7e19rZXk6IG1ldGFLZXksIGFwcElkOiAnbml0cm9nZW54Jywga2luZDogJ2NhdGFsb2cnLCByZXZpc2lvbjogZXZlbnQucmV2aXNpb24gKyAxfX0gVVBEQVRFIHtyZXZpc2lvbjogJHtldmVudC5yZXZpc2lvbiArIDF9fSBJTiBhbGZyZWRGYXFgKTtcbiAgICBhd2FpdCB0eC5jb21taXQoKTtcbiAgICByZXR1cm4ge2R1cGxpY2F0ZTogZmFsc2UsIHRvcGljSWR9O1xuICB9IGNhdGNoKGVycm9yKSB7YXdhaXQgdHguYWJvcnQoKTsgdGhyb3cgZXJyb3I7fVxufTtcbiJdLCJuYW1lcyI6WyJjcmVhdGVIYXNoIiwiYXFsIiwidXNlRGIiLCJoYXNoIiwidmFsdWUiLCJ1cGRhdGUiLCJkaWdlc3QiLCJwcm9kdWN0cyIsIlNldCIsInNhZmVUZXh0IiwibWF4IiwidHJpbSIsImxlbmd0aCIsInRlc3QiLCJ2ZWN0b3JWYWxpZCIsIkFycmF5IiwiaXNBcnJheSIsImV2ZXJ5IiwibiIsIk51bWJlciIsImlzRmluaXRlIiwic29tZSIsInNvdXJjZVZhbGlkIiwic291cmNlIiwidXJsIiwiVVJMIiwidGl0bGUiLCJwcm90b2NvbCIsInVzZXJuYW1lIiwicGFzc3dvcmQiLCJzZWFyY2giLCJtYXAiLCJuYW1lIiwiaW5jbHVkZXMiLCJob3N0bmFtZSIsInZhbGlkYXRlRmFxSW5wdXQiLCJ2IiwicXVlc3Rpb24iLCJoYXMiLCJwcm9kdWN0IiwiY2hhbm5lbCIsImV2ZW50SWQiLCJlbWJlZGRpbmciLCJpc1NhZmVJbnRlZ2VyIiwicmV2aXNpb24iLCJ0b3BpY0lkIiwiRXJyb3IiLCJwdWJsaWNGYXEiLCJ0b3BpY3MiLCJub3ciLCJmaWx0ZXIiLCJ0b3BpYyIsImFwcElkIiwia2luZCIsIndlaWdodCIsImFuc3dlciIsImFuc3dlckV4cGlyZXMiLCJzb3VyY2VzIiwic29ydCIsImEiLCJiIiwibGFzdEFza2VkIiwiX2tleSIsImxvY2FsZUNvbXBhcmUiLCJzbGljZSIsImlkIiwiY29zaW5lIiwicmVkdWNlIiwic3VtIiwiaSIsIk1hdGgiLCJzcXJ0IiwiZmFxQWN0aW9uIiwiY29udGV4dCIsIm9wZXJhdGlvbiIsImRiIiwiZGF0YWJhc2VOYW1lIiwiY29sbGVjdGlvbiIsImV4aXN0cyIsImNyZWF0ZSIsImVycm9yIiwiZW5zdXJlSW5kZXgiLCJmaWVsZHMiLCJ0eXBlIiwiaW5wdXQiLCJxdWVyeSIsInRoZW4iLCJjdXJzb3IiLCJhbGwiLCJpdGVtcyIsInNvdXJjZVJldmlzaW9uIiwiRGF0ZSIsInZhbGlkIiwicmVmcmVzaEFmdGVyIiwib2siLCJldmVudCIsIm1ldGFLZXkiLCJ0eCIsImJlZ2luVHJhbnNhY3Rpb24iLCJleGNsdXNpdmUiLCJsb2NrVGltZW91dCIsIm5leHQiLCJzdGVwIiwibWV0YSIsImNvbW1pdCIsImNhbmRpZGF0ZXMiLCJzY29yZSIsImtleSIsImV4aXN0aW5nIiwiZHVwbGljYXRlIiwidG9Mb3dlckNhc2UiLCJ0aW1lc3RhbXAiLCJlbWJlZGRpbmdNb2RlbCIsImZpcnN0QXNrZWQiLCJwaG9uZUNvdW50Iiwid2Vic2l0ZUNvdW50IiwiY2xhc3NpZmllclZlcnNpb24iLCJjcmVhdGVkIiwiYWJvcnQiXSwibWFwcGluZ3MiOiJBQUFBLFNBQVFBLFVBQVUsUUFBTyxjQUFjO0FBQ3ZDLFNBQVFDLEdBQUcsUUFBTyxXQUFXO0FBQzdCLFNBQVFDLEtBQUssUUFBTyw0QkFBNEI7QUFNaEQsTUFBTUMsT0FBTyxDQUFDQyxRQUEwQkosV0FBVyxVQUFVSyxNQUFNLENBQUNELE9BQU9FLE1BQU0sQ0FBQztBQUNsRixNQUFNQyxXQUFXLElBQUlDLElBQUk7SUFBQztJQUFVO0lBQVk7SUFBaUI7SUFBb0I7SUFBVztJQUFZO0lBQWE7SUFBZ0I7SUFBWTtJQUFPO0lBQVk7SUFBVztJQUFZO0NBQWE7QUFDNU0sTUFBTUMsV0FBVyxDQUFDTCxPQUFnQk0sTUFBaUMsT0FBT04sVUFBVSxZQUFZQSxNQUFNTyxJQUFJLEdBQUdDLE1BQU0sSUFBSSxLQUFLUixNQUFNUSxNQUFNLElBQUlGLE9BQU8sQ0FBQywwQ0FBMENHLElBQUksQ0FBQ1Q7QUFDbk0sTUFBTVUsY0FBYyxDQUFD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