@nlabs/reaktor 1.17.0 → 1.19.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 (320) hide show
  1. package/README.md +182 -0
  2. package/docs/ASSISTANT.md +138 -0
  3. package/docs/GENERATION.md +42 -5
  4. package/docs/NATIVE_PUSH.md +56 -0
  5. package/lib/actions/alfredFaq.d.ts +80 -0
  6. package/lib/actions/alfredFaq.js +206 -0
  7. package/lib/actions/analytics.js +1 -1
  8. package/lib/actions/apps.js +1 -1
  9. package/lib/actions/connections.js +1 -1
  10. package/lib/actions/content.js +1 -1
  11. package/lib/actions/contentGeneration.d.ts +4 -0
  12. package/lib/actions/contentGeneration.js +82 -10
  13. package/lib/actions/contentGenerationErrors.js +1 -1
  14. package/lib/actions/conversations.d.ts +1 -1
  15. package/lib/actions/conversations.js +19 -9
  16. package/lib/actions/crm.js +1 -1
  17. package/lib/actions/crud.js +26 -1
  18. package/lib/actions/databaseAccounts.js +1 -1
  19. package/lib/actions/databaseProvisioningLease.js +1 -1
  20. package/lib/actions/dynamodb.js +1 -1
  21. package/lib/actions/email.js +1 -1
  22. package/lib/actions/files.js +1 -1
  23. package/lib/actions/flags.js +1 -1
  24. package/lib/actions/geminiVideo.js +1 -1
  25. package/lib/actions/groups.js +1 -1
  26. package/lib/actions/higgsfield.js +1 -1
  27. package/lib/actions/imageGeneration.js +1 -1
  28. package/lib/actions/images.js +1 -1
  29. package/lib/actions/index.d.ts +1 -0
  30. package/lib/actions/index.js +2 -1
  31. package/lib/actions/ios.js +1 -1
  32. package/lib/actions/locations.js +1 -1
  33. package/lib/actions/messages.js +23 -7
  34. package/lib/actions/notifications.js +1 -1
  35. package/lib/actions/ollamaGeneration.js +1 -1
  36. package/lib/actions/openaiResponseSession.js +1 -1
  37. package/lib/actions/payments.js +1 -1
  38. package/lib/actions/personas.js +1 -1
  39. package/lib/actions/phoneSupport.js +1 -1
  40. package/lib/actions/posts.js +1 -1
  41. package/lib/actions/query.js +1 -1
  42. package/lib/actions/reactions.js +1 -1
  43. package/lib/actions/rum.js +1 -1
  44. package/lib/actions/s3.js +1 -1
  45. package/lib/actions/search.js +1 -1
  46. package/lib/actions/sms.js +1 -1
  47. package/lib/actions/statistics.js +1 -1
  48. package/lib/actions/subscriptions.js +1 -1
  49. package/lib/actions/tags.js +1 -1
  50. package/lib/actions/users.js +57 -4
  51. package/lib/actions/videoGeneration.js +1 -1
  52. package/lib/actions/videos.js +1 -1
  53. package/lib/adapters/arangoAdapter.js +1 -1
  54. package/lib/adapters/contentAdapter.js +1 -1
  55. package/lib/adapters/fileAdapter.js +1 -1
  56. package/lib/adapters/geminiGenerationAdapter.js +1 -1
  57. package/lib/adapters/higgsfieldAdapter.js +1 -1
  58. package/lib/adapters/higgsfieldModelCatalog.js +1 -1
  59. package/lib/adapters/higgsfieldModels.js +1 -1
  60. package/lib/adapters/imageAdapter.js +1 -1
  61. package/lib/adapters/imageGenerationAdapter.js +1 -1
  62. package/lib/adapters/index.js +1 -1
  63. package/lib/adapters/messageAdapter.js +1 -1
  64. package/lib/adapters/postAdapter.js +1 -1
  65. package/lib/adapters/reaktorAdapter.js +1 -1
  66. package/lib/adapters/tagAdapter.js +1 -1
  67. package/lib/adapters/userAdapter.js +1 -1
  68. package/lib/assistant/core.d.ts +53 -0
  69. package/lib/assistant/core.js +123 -0
  70. package/lib/assistant/faq.d.ts +26 -0
  71. package/lib/assistant/faq.js +238 -0
  72. package/lib/assistant/faqCore.d.ts +23 -0
  73. package/lib/assistant/faqCore.js +20 -0
  74. package/lib/assistant/index.d.ts +7 -0
  75. package/lib/assistant/index.js +5 -0
  76. package/lib/assistant/service.d.ts +35 -0
  77. package/lib/assistant/service.js +201 -0
  78. package/lib/config.js +1 -1
  79. package/lib/constants/collections.js +1 -1
  80. package/lib/durableChat/conversations.d.ts +62 -0
  81. package/lib/durableChat/conversations.js +729 -0
  82. package/lib/durableChat/errors.d.ts +6 -0
  83. package/lib/durableChat/errors.js +11 -0
  84. package/lib/durableChat/events.d.ts +22 -0
  85. package/lib/durableChat/events.js +50 -0
  86. package/lib/durableChat/index.d.ts +8 -0
  87. package/lib/durableChat/index.js +10 -0
  88. package/lib/durableChat/membership.d.ts +24 -0
  89. package/lib/durableChat/membership.js +85 -0
  90. package/lib/durableChat/messageTypes.d.ts +76 -0
  91. package/lib/durableChat/messageTypes.js +3 -0
  92. package/lib/durableChat/messages.d.ts +16 -0
  93. package/lib/durableChat/messages.js +257 -0
  94. package/lib/durableChat/transaction.d.ts +10 -0
  95. package/lib/durableChat/transaction.js +53 -0
  96. package/lib/durableChat/types.d.ts +81 -0
  97. package/lib/durableChat/types.js +3 -0
  98. package/lib/handlers/graphqlHandler.js +1 -1
  99. package/lib/index.d.ts +4 -4
  100. package/lib/index.js +5 -3
  101. package/lib/lambdas/actions/websockets.js +4 -4
  102. package/lib/lambdas/authorizer.js +1 -1
  103. package/lib/lambdas/connection.js +1 -1
  104. package/lib/lambdas/utils/message.js +1 -1
  105. package/lib/lambdas/utils/websocket.js +1 -1
  106. package/lib/mocks/conversation.js +1 -1
  107. package/lib/mocks/file.js +1 -1
  108. package/lib/mocks/group.js +1 -1
  109. package/lib/mocks/image.js +1 -1
  110. package/lib/mocks/post.js +1 -1
  111. package/lib/mocks/tag.js +1 -1
  112. package/lib/mocks/user.js +1 -1
  113. package/lib/mocks/video.js +1 -1
  114. package/lib/mutations/analytics/analytics.js +1 -1
  115. package/lib/mutations/content/content.js +1 -1
  116. package/lib/mutations/crm/crm.js +1 -1
  117. package/lib/mutations/events/events.js +1 -1
  118. package/lib/mutations/flags/flags.js +1 -1
  119. package/lib/mutations/groups/groups.js +1 -1
  120. package/lib/mutations/higgsfield/higgsfield.js +1 -1
  121. package/lib/mutations/images/images.js +1 -1
  122. package/lib/mutations/index.js +1 -1
  123. package/lib/mutations/locations/locations.js +1 -1
  124. package/lib/mutations/messages/messages.js +1 -1
  125. package/lib/mutations/personas/personas.js +1 -1
  126. package/lib/mutations/posts/posts.js +1 -1
  127. package/lib/mutations/reactions/reactions.js +1 -1
  128. package/lib/mutations/rum/rum.js +1 -1
  129. package/lib/mutations/statistics/statistics.js +1 -1
  130. package/lib/mutations/subscriptions/subscriptions.js +1 -1
  131. package/lib/mutations/tags/tags.js +1 -1
  132. package/lib/mutations/users/users.js +1 -1
  133. package/lib/mutations/videos/videos.js +1 -1
  134. package/lib/nativePush/graphql.d.ts +14 -0
  135. package/lib/nativePush/graphql.js +105 -0
  136. package/lib/nativePush/index.d.ts +7 -0
  137. package/lib/nativePush/index.js +9 -0
  138. package/lib/nativePush/migrations.d.ts +2 -0
  139. package/lib/nativePush/migrations.js +36 -0
  140. package/lib/nativePush/nativePushContract.fixture.d.ts +22 -0
  141. package/lib/nativePush/nativePushContract.fixture.js +27 -0
  142. package/lib/nativePush/payload.d.ts +2 -0
  143. package/lib/nativePush/payload.js +106 -0
  144. package/lib/nativePush/repository.d.ts +9 -0
  145. package/lib/nativePush/repository.js +120 -0
  146. package/lib/nativePush/service.d.ts +2 -0
  147. package/lib/nativePush/service.js +110 -0
  148. package/lib/nativePush/snsProvider.d.ts +17 -0
  149. package/lib/nativePush/snsProvider.js +165 -0
  150. package/lib/nativePush/types.d.ts +89 -0
  151. package/lib/nativePush/types.js +3 -0
  152. package/lib/objectTypes/analytics.js +1 -1
  153. package/lib/objectTypes/app.js +1 -1
  154. package/lib/objectTypes/bankAccount.js +1 -1
  155. package/lib/objectTypes/connection.js +1 -1
  156. package/lib/objectTypes/content.js +1 -1
  157. package/lib/objectTypes/contentGeneration.js +1 -1
  158. package/lib/objectTypes/conversation.js +1 -1
  159. package/lib/objectTypes/creditCard.js +1 -1
  160. package/lib/objectTypes/crm.js +1 -1
  161. package/lib/objectTypes/document.js +1 -1
  162. package/lib/objectTypes/error.js +1 -1
  163. package/lib/objectTypes/event.js +1 -1
  164. package/lib/objectTypes/external.js +1 -1
  165. package/lib/objectTypes/file.js +1 -1
  166. package/lib/objectTypes/filter.js +1 -1
  167. package/lib/objectTypes/flag.js +1 -1
  168. package/lib/objectTypes/group.js +1 -1
  169. package/lib/objectTypes/higgsfield.js +1 -1
  170. package/lib/objectTypes/iapSubscription.js +1 -1
  171. package/lib/objectTypes/image.js +1 -1
  172. package/lib/objectTypes/imageGeneration.js +1 -1
  173. package/lib/objectTypes/index.js +1 -1
  174. package/lib/objectTypes/location.js +1 -1
  175. package/lib/objectTypes/message.js +1 -1
  176. package/lib/objectTypes/passcode.js +1 -1
  177. package/lib/objectTypes/persona.js +1 -1
  178. package/lib/objectTypes/plan.js +1 -1
  179. package/lib/objectTypes/post.js +1 -1
  180. package/lib/objectTypes/query.js +1 -1
  181. package/lib/objectTypes/reaction.js +1 -1
  182. package/lib/objectTypes/relation.js +1 -1
  183. package/lib/objectTypes/rum.js +1 -1
  184. package/lib/objectTypes/search.js +1 -1
  185. package/lib/objectTypes/statistics.js +1 -1
  186. package/lib/objectTypes/subscription.js +1 -1
  187. package/lib/objectTypes/tag.js +1 -1
  188. package/lib/objectTypes/user.js +1 -1
  189. package/lib/objectTypes/video.js +1 -1
  190. package/lib/objectTypes/videoGeneration.js +1 -1
  191. package/lib/organizations/accountLifecycle.d.ts +7 -0
  192. package/lib/organizations/accountLifecycle.js +106 -0
  193. package/lib/organizations/authorization.d.ts +9 -0
  194. package/lib/organizations/authorization.js +40 -0
  195. package/lib/organizations/billing.d.ts +38 -0
  196. package/lib/organizations/billing.js +277 -0
  197. package/lib/organizations/billingProvider.d.ts +4 -0
  198. package/lib/organizations/billingProvider.js +287 -0
  199. package/lib/organizations/billingUpdates.d.ts +9 -0
  200. package/lib/organizations/billingUpdates.js +388 -0
  201. package/lib/organizations/index.d.ts +10 -0
  202. package/lib/organizations/index.js +12 -0
  203. package/lib/organizations/mail.d.ts +10 -0
  204. package/lib/organizations/mail.js +60 -0
  205. package/lib/organizations/memberDirectory.d.ts +15 -0
  206. package/lib/organizations/memberDirectory.js +28 -0
  207. package/lib/organizations/membership.d.ts +19 -0
  208. package/lib/organizations/membership.js +248 -0
  209. package/lib/organizations/passwordRecovery.d.ts +9 -0
  210. package/lib/organizations/passwordRecovery.js +50 -0
  211. package/lib/organizations/plans.d.ts +6 -0
  212. package/lib/organizations/plans.js +40 -0
  213. package/lib/organizations/providerPagination.d.ts +6 -0
  214. package/lib/organizations/providerPagination.js +23 -0
  215. package/lib/organizations/reconciliation.d.ts +11 -0
  216. package/lib/organizations/reconciliation.js +400 -0
  217. package/lib/organizations/signup.d.ts +25 -0
  218. package/lib/organizations/signup.js +169 -0
  219. package/lib/organizations/store.d.ts +25 -0
  220. package/lib/organizations/store.js +167 -0
  221. package/lib/organizations/types.d.ts +138 -0
  222. package/lib/organizations/types.js +3 -0
  223. package/lib/organizations/verification.d.ts +3 -0
  224. package/lib/organizations/verification.js +51 -0
  225. package/lib/queries/analytics/analytics.js +1 -1
  226. package/lib/queries/content/content.js +1 -1
  227. package/lib/queries/crm/crm.js +1 -1
  228. package/lib/queries/events/events.js +1 -1
  229. package/lib/queries/flags/flags.js +1 -1
  230. package/lib/queries/groups/groups.js +1 -1
  231. package/lib/queries/higgsfield/higgsfield.js +1 -1
  232. package/lib/queries/images/images.js +1 -1
  233. package/lib/queries/index.js +1 -1
  234. package/lib/queries/locations/locations.js +1 -1
  235. package/lib/queries/messages/messages.js +1 -1
  236. package/lib/queries/personas/personas.js +1 -1
  237. package/lib/queries/posts/posts.js +1 -1
  238. package/lib/queries/query/query.js +1 -1
  239. package/lib/queries/reactions/reactions.js +1 -1
  240. package/lib/queries/statistics/statistics.js +1 -1
  241. package/lib/queries/subscriptions/subscriptions.js +1 -1
  242. package/lib/queries/tags/tags.js +1 -1
  243. package/lib/queries/users/users.js +1 -1
  244. package/lib/queries/videos/videos.js +1 -1
  245. package/lib/templates/email/layout.js +1 -1
  246. package/lib/templates/email/passwordForgot.js +1 -1
  247. package/lib/templates/email/passwordRecovery.js +1 -1
  248. package/lib/templates/email/verifyEmail.js +1 -1
  249. package/lib/templates/email/welcome.js +1 -1
  250. package/lib/templates/sms/passwordForgot.js +1 -1
  251. package/lib/templates/sms/passwordRecovery.js +1 -1
  252. package/lib/templates/sms/verifyEmail.js +1 -1
  253. package/lib/templates/sms/verifyPhone.js +1 -1
  254. package/lib/templates/sms/welcome.js +1 -1
  255. package/lib/types/analytics.types.js +1 -1
  256. package/lib/types/apps.types.js +1 -1
  257. package/lib/types/arangodb.types.js +1 -1
  258. package/lib/types/auth.types.js +1 -1
  259. package/lib/types/connections.types.js +1 -1
  260. package/lib/types/content.types.js +1 -1
  261. package/lib/types/conversations.types.js +1 -1
  262. package/lib/types/crm.types.js +1 -1
  263. package/lib/types/databaseCredentials.types.js +1 -1
  264. package/lib/types/email.types.js +1 -1
  265. package/lib/types/error.types.js +1 -1
  266. package/lib/types/files.types.js +1 -1
  267. package/lib/types/flags.types.js +1 -1
  268. package/lib/types/google.types.js +1 -1
  269. package/lib/types/groups.types.js +1 -1
  270. package/lib/types/images.types.js +1 -1
  271. package/lib/types/index.js +1 -1
  272. package/lib/types/locations.types.js +1 -1
  273. package/lib/types/messages.types.js +1 -1
  274. package/lib/types/notifications.types.js +1 -1
  275. package/lib/types/payments.types.js +1 -1
  276. package/lib/types/personas.types.js +1 -1
  277. package/lib/types/posts.types.js +1 -1
  278. package/lib/types/rum.types.js +1 -1
  279. package/lib/types/statistics.types.js +1 -1
  280. package/lib/types/tags.types.js +1 -1
  281. package/lib/types/users.types.js +1 -1
  282. package/lib/types/videos.types.js +1 -1
  283. package/lib/types/websockets.types.js +1 -1
  284. package/lib/upload.js +1 -1
  285. package/lib/utils/adapterUtils.js +1 -1
  286. package/lib/utils/analyticsUtils.js +1 -1
  287. package/lib/utils/appContext.js +1 -1
  288. package/lib/utils/aqlHelpers.js +1 -1
  289. package/lib/utils/arangodbUtils.js +1 -1
  290. package/lib/utils/authUtils.js +1 -1
  291. package/lib/utils/awsUtils.js +1 -1
  292. package/lib/utils/collectionRegistry.js +1 -1
  293. package/lib/utils/contextUtils.js +1 -1
  294. package/lib/utils/databaseCredentials.js +1 -1
  295. package/lib/utils/dbI18n.example.js +1 -1
  296. package/lib/utils/dbI18n.js +1 -1
  297. package/lib/utils/generationCallback.js +1 -1
  298. package/lib/utils/googleTranslate.js +1 -1
  299. package/lib/utils/graphqlUtils.js +1 -1
  300. package/lib/utils/imageUtils.js +1 -1
  301. package/lib/utils/index.js +1 -1
  302. package/lib/utils/languageDetection.js +1 -1
  303. package/lib/utils/localeUtils.example.js +1 -1
  304. package/lib/utils/localeUtils.js +1 -1
  305. package/lib/utils/mediaAccess.js +1 -1
  306. package/lib/utils/middlewareUtils.js +1 -1
  307. package/lib/utils/nodeRealtime.js +1 -1
  308. package/lib/utils/opaqueToken.js +1 -1
  309. package/lib/utils/queryBuilder.js +1 -1
  310. package/lib/utils/schemaUtils.js +1 -1
  311. package/lib/utils/secretDatabase.js +1 -1
  312. package/lib/utils/sessionUtils.js +1 -1
  313. package/lib/utils/stripeUtils.js +1 -1
  314. package/lib/utils/stripeUtils.ts.bak +1 -1
  315. package/lib/utils/templateUtils.js +1 -1
  316. package/lib/utils/testUtils.js +1 -1
  317. package/lib/utils/translationQueue.example.js +1 -1
  318. package/lib/utils/translationQueue.js +1 -1
  319. package/lib/videoProcessing.js +1 -1
  320. package/package.json +16 -3
@@ -0,0 +1,388 @@
1
+ /* Financial writes are ordered and fenced; metadata receipts survive provider idempotency expiry. */ /* eslint-disable no-await-in-loop */ import { getOrganizationPlan } from './plans.js';
2
+ import { listAllProviderRecords } from './providerPagination.js';
3
+ import { organizationKey } from './store.js';
4
+ const publishedPlan = (value)=>getOrganizationPlan(value).key;
5
+ const safeQuantity = (value)=>{
6
+ if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0) {
7
+ throw new Error('invalid_billing_job');
8
+ }
9
+ return value;
10
+ };
11
+ const adjustmentReceipt = (item)=>({
12
+ amountCents: item.amount,
13
+ periodEnd: Number(item.metadata.periodEnd),
14
+ periodStart: Number(item.metadata.periodStart),
15
+ providerId: item.id
16
+ });
17
+ export const createOrganizationBillingUpdater = (stripe, prices)=>async (subscription, job, fence)=>{
18
+ await fence();
19
+ if (job.priceVersion !== '2026-10-v1') {
20
+ throw new Error('billing_rate_version_unavailable');
21
+ }
22
+ if (!Number.isSafeInteger(job.effectiveAt) || job.effectiveAt < 0) {
23
+ throw new Error('invalid_billing_job');
24
+ }
25
+ const raw = await stripe.subscriptions.retrieve(subscription.id);
26
+ const customer = typeof raw.customer === 'string' ? raw.customer : raw.customer.id;
27
+ const base = raw.items.data.find((item)=>[
28
+ prices.pro,
29
+ prices.starter
30
+ ].includes(item.price.id));
31
+ const seat = raw.items.data.find((item)=>item.price.id === prices.seat);
32
+ if (raw.livemode || customer !== subscription.customerId || !base || raw.items.has_more) {
33
+ throw new Error('billing_subscription_mismatch');
34
+ }
35
+ const existing = await listAllProviderRecords((startingAfter)=>stripe.invoiceItems.list({
36
+ customer,
37
+ limit: 100,
38
+ starting_after: startingAfter
39
+ }));
40
+ const adjustments = existing.filter((item)=>item.metadata.organizationBillingJob === job.jobId).map(adjustmentReceipt);
41
+ if (raw.metadata.organizationBillingJob === job.jobId) {
42
+ return {
43
+ adjustments
44
+ };
45
+ }
46
+ if (job.kind === 'seats' && job.effectiveAt < raw.start_date * 1000) {
47
+ return {
48
+ adjustments
49
+ };
50
+ }
51
+ const scheduleId = typeof raw.schedule === 'string' ? raw.schedule : raw.schedule?.id;
52
+ const schedule = scheduleId ? await stripe.subscriptionSchedules.retrieve(scheduleId) : null;
53
+ const boundaryChange = job.kind === 'cancel' || job.kind === 'plan' && job.desired.changeAt === 'period_end';
54
+ const targetPeriodEnd = Number(job.desired.targetPeriodEnd);
55
+ const scheduleBoundary = boundaryChange ? targetPeriodEnd : Number(raw.metadata.organizationPendingBoundary);
56
+ const key = (operation)=>organizationKey('billing-job', job.jobId, operation);
57
+ const metadata = (pendingPlan = '')=>({
58
+ organizationBillingJob: job.jobId,
59
+ organizationPendingBoundary: pendingPlan ? String(scheduleBoundary) : '',
60
+ organizationPendingPlan: pendingPlan
61
+ });
62
+ let closed = raw.status === 'canceled';
63
+ if (boundaryChange && (!Number.isSafeInteger(targetPeriodEnd) || targetPeriodEnd <= job.effectiveAt || job.desired.subscriptionId !== raw.id)) {
64
+ throw new Error('billing_change_boundary_required');
65
+ }
66
+ const lateBoundary = boundaryChange && targetPeriodEnd <= Date.now();
67
+ if (job.kind === 'cancel' && !closed) {
68
+ if (scheduleId) {
69
+ await fence();
70
+ await stripe.subscriptionSchedules.release(scheduleId, {}, {
71
+ idempotencyKey: key('release')
72
+ });
73
+ }
74
+ if (!lateBoundary) {
75
+ await fence();
76
+ await stripe.subscriptions.update(raw.id, {
77
+ cancel_at: targetPeriodEnd / 1000,
78
+ metadata: {
79
+ ...metadata(),
80
+ organizationCancelBoundary: String(targetPeriodEnd)
81
+ },
82
+ proration_behavior: 'none'
83
+ }, {
84
+ idempotencyKey: key('cancel')
85
+ });
86
+ return {
87
+ adjustments
88
+ };
89
+ }
90
+ await fence();
91
+ await stripe.subscriptions.update(raw.id, {
92
+ metadata: {
93
+ organizationCancelBoundary: String(targetPeriodEnd)
94
+ }
95
+ }, {
96
+ idempotencyKey: key('cancel-intent')
97
+ });
98
+ await fence();
99
+ await stripe.subscriptions.cancel(raw.id, {
100
+ invoice_now: false,
101
+ prorate: false
102
+ }, {
103
+ idempotencyKey: key('cancel')
104
+ });
105
+ closed = true;
106
+ }
107
+ if (![
108
+ 'cancel',
109
+ 'plan',
110
+ 'seats'
111
+ ].includes(job.kind)) {
112
+ throw new Error('invalid_billing_job');
113
+ }
114
+ const currentPlan = base.price.id === prices.pro ? 'pro' : 'starter';
115
+ const plan = job.kind === 'plan' ? publishedPlan(job.desired.plan) : currentPlan;
116
+ const seats = job.kind === 'seats' ? safeQuantity(job.desired.extraSeats) : seat?.quantity || 0;
117
+ let pendingPlan = null;
118
+ if (job.kind === 'plan' && job.desired.changeAt === 'period_end' && !lateBoundary) {
119
+ pendingPlan = plan;
120
+ } else if (!lateBoundary && raw.metadata.organizationPendingPlan === 'starter' && currentPlan !== 'starter') {
121
+ pendingPlan = 'starter';
122
+ }
123
+ if (pendingPlan && (!Number.isSafeInteger(scheduleBoundary) || scheduleBoundary <= Date.now())) {
124
+ throw new Error('billing_change_boundary_required');
125
+ }
126
+ const phaseItems = (phasePlan)=>[
127
+ {
128
+ price: prices[phasePlan],
129
+ quantity: 1
130
+ },
131
+ ...seats ? [
132
+ {
133
+ price: prices.seat,
134
+ quantity: seats
135
+ }
136
+ ] : []
137
+ ];
138
+ const applySchedule = async ()=>{
139
+ await fence();
140
+ const id = scheduleId || (await stripe.subscriptionSchedules.create({
141
+ from_subscription: raw.id
142
+ }, {
143
+ idempotencyKey: key('schedule-create')
144
+ })).id;
145
+ await fence();
146
+ await stripe.subscriptionSchedules.update(id, {
147
+ end_behavior: 'release',
148
+ metadata: metadata(pendingPlan),
149
+ phases: [
150
+ {
151
+ end_date: scheduleBoundary / 1000,
152
+ items: phaseItems(currentPlan),
153
+ proration_behavior: 'none',
154
+ start_date: base.current_period_start
155
+ },
156
+ {
157
+ duration: {
158
+ interval: 'month',
159
+ interval_count: 1
160
+ },
161
+ items: phaseItems(pendingPlan),
162
+ proration_behavior: 'none',
163
+ start_date: scheduleBoundary / 1000
164
+ }
165
+ ],
166
+ proration_behavior: 'none'
167
+ }, {
168
+ idempotencyKey: key('schedule-update')
169
+ });
170
+ };
171
+ const markApplied = async ()=>{
172
+ await fence();
173
+ await stripe.subscriptions.update(raw.id, {
174
+ metadata: metadata(pendingPlan || '')
175
+ }, {
176
+ idempotencyKey: key('marker')
177
+ });
178
+ };
179
+ if (schedule?.metadata.organizationBillingJob === job.jobId) {
180
+ await markApplied();
181
+ return {
182
+ adjustments
183
+ };
184
+ }
185
+ if (job.kind === 'plan' && job.desired.changeAt === 'period_end' && !lateBoundary) {
186
+ await applySchedule();
187
+ await markApplied();
188
+ return {
189
+ adjustments
190
+ };
191
+ }
192
+ const currentRate = getOrganizationPlan(currentPlan).baseCents + seats * 800;
193
+ let rateDelta = -currentRate;
194
+ if (job.kind !== 'cancel') {
195
+ rateDelta = job.kind === 'seats' ? (seats - safeQuantity(job.desired.previousExtraSeats)) * 800 : getOrganizationPlan(plan).baseCents - getOrganizationPlan(publishedPlan(job.desired.previousPlan)).baseCents;
196
+ }
197
+ if (job.kind === 'plan' && (!lateBoundary && (job.desired.changeAt !== 'immediate' || rateDelta <= 0) || lateBoundary && rateDelta >= 0 || raw.status !== 'active')) {
198
+ throw new Error('invalid_billing_job');
199
+ }
200
+ if (!Number.isSafeInteger(rateDelta)) {
201
+ throw new Error('invalid_billing_job');
202
+ }
203
+ const invoices = await listAllProviderRecords((startingAfter)=>stripe.invoices.list({
204
+ customer,
205
+ limit: 100,
206
+ starting_after: startingAfter,
207
+ subscription: raw.id
208
+ }));
209
+ if (invoices.some((invoice)=>invoice.metadata?.organizationBillingJob === job.jobId && (!Number.isSafeInteger(Number(invoice.metadata.periodStart)) || !Number.isSafeInteger(Number(invoice.metadata.periodEnd)) || Number(invoice.metadata.periodEnd) <= Number(invoice.metadata.periodStart)))) {
210
+ throw new Error('billing_settlement_conflict');
211
+ }
212
+ const periods = new Map();
213
+ const renewalRates = new Map();
214
+ for (const invoice of invoices){
215
+ if (invoice.lines.has_more) {
216
+ throw new Error('billing_lookup_incomplete');
217
+ }
218
+ const invoiceRates = new Map();
219
+ for (const line of invoice.lines.data){
220
+ const price = line.pricing?.price_details?.price;
221
+ const priceId = typeof price === 'string' ? price : price?.id;
222
+ if ([
223
+ prices.pro,
224
+ prices.starter,
225
+ prices.seat
226
+ ].includes(priceId || '') && !line.parent?.subscription_item_details?.proration) {
227
+ const period = {
228
+ end: line.period.end * 1000,
229
+ start: line.period.start * 1000
230
+ };
231
+ const periodKey = `${period.start}-${period.end}`;
232
+ if (priceId !== prices.seat) {
233
+ periods.set(periodKey, period);
234
+ }
235
+ const rate = priceId === prices.seat ? 800 * safeQuantity(line.quantity) : getOrganizationPlan(priceId === prices.pro ? 'pro' : 'starter').baseCents;
236
+ invoiceRates.set(periodKey, (invoiceRates.get(periodKey) || 0) + rate);
237
+ }
238
+ }
239
+ for (const [periodKey, rate] of invoiceRates){
240
+ if (renewalRates.has(periodKey) && renewalRates.get(periodKey) !== rate) {
241
+ throw new Error('billing_period_history_required');
242
+ }
243
+ renewalRates.set(periodKey, rate);
244
+ }
245
+ }
246
+ // Canceled subscriptions may truncate item dates. Licensed renewal invoices retain the full charged period.
247
+ const currentStart = base.current_period_start * 1000;
248
+ const currentPeriod = {
249
+ end: Math.max(base.current_period_end * 1000, ...[
250
+ ...periods.values()
251
+ ].filter((period)=>period.start === currentStart).map((period)=>period.end)),
252
+ start: currentStart
253
+ };
254
+ periods.set(`${currentPeriod.start}-${currentPeriod.end}`, currentPeriod);
255
+ const effectiveAt = Math.floor((boundaryChange ? targetPeriodEnd : job.effectiveAt) / 1000) * 1000;
256
+ const canceledBoundary = Number(raw.metadata.organizationCancelBoundary);
257
+ const chargeThrough = closed && Number.isSafeInteger(canceledBoundary) && canceledBoundary > 0 && job.kind !== 'cancel' ? Math.min(currentPeriod.end, canceledBoundary) : currentPeriod.end;
258
+ const applicable = [
259
+ ...periods.values()
260
+ ].filter((period)=>period.end > effectiveAt && period.start <= currentPeriod.start).sort((a, b)=>a.start - b.start);
261
+ let coveredThrough = effectiveAt;
262
+ for (const period of applicable){
263
+ if (!Number.isSafeInteger(period.start) || !Number.isSafeInteger(period.end) || period.end <= period.start || period.start > coveredThrough) {
264
+ throw new Error('billing_period_history_required');
265
+ }
266
+ coveredThrough = Math.max(coveredThrough, period.end);
267
+ }
268
+ if (coveredThrough < chargeThrough) {
269
+ throw new Error('billing_period_history_required');
270
+ }
271
+ // Fixed, published USD rates. Apply original-time adjustments before disabling automatic provider proration.
272
+ for (const period of applicable){
273
+ const periodRate = job.kind === 'cancel' ? -(renewalRates.get(`${period.start}-${period.end}`) ?? -rateDelta) : rateDelta;
274
+ const amountCents = Math.round(periodRate * Math.max(0, Math.min(period.end, chargeThrough) - Math.max(effectiveAt, period.start)) / (period.end - period.start));
275
+ if (!amountCents) {
276
+ continue;
277
+ }
278
+ if (!Number.isSafeInteger(amountCents)) {
279
+ throw new Error('invalid_billing_job');
280
+ }
281
+ const receipt = existing.find((item)=>item.metadata.organizationBillingJob === job.jobId && Number(item.metadata.periodStart) === period.start && Number(item.metadata.periodEnd) === period.end);
282
+ const invoiceId = typeof receipt?.invoice === 'string' ? receipt.invoice : receipt?.invoice?.id;
283
+ let settlement = invoiceId ? await stripe.invoices.retrieve(invoiceId) : invoices.find((invoice)=>invoice.metadata?.organizationBillingJob === job.jobId && Number(invoice.metadata.periodStart) === period.start && Number(invoice.metadata.periodEnd) === period.end);
284
+ if (receipt && (!invoiceId || receipt.amount !== amountCents)) {
285
+ throw new Error('billing_settlement_conflict');
286
+ }
287
+ if (!settlement) {
288
+ await fence();
289
+ settlement = await stripe.invoices.create({
290
+ auto_advance: false,
291
+ customer,
292
+ metadata: {
293
+ organizationBillingJob: job.jobId,
294
+ periodEnd: String(period.end),
295
+ periodStart: String(period.start),
296
+ subscriptionId: raw.id
297
+ },
298
+ pending_invoice_items_behavior: 'exclude',
299
+ ...closed ? {} : {
300
+ subscription: raw.id
301
+ }
302
+ }, {
303
+ idempotencyKey: key(`settlement-${period.start}-${period.end}`)
304
+ });
305
+ }
306
+ if (!receipt) {
307
+ if (settlement.status !== 'draft') {
308
+ throw new Error('billing_settlement_conflict');
309
+ }
310
+ await fence();
311
+ const item = await stripe.invoiceItems.create({
312
+ amount: amountCents,
313
+ currency: 'usd',
314
+ customer,
315
+ description: `Reaktor ${job.kind === 'seats' ? 'active-member' : 'plan'} proration (${job.priceVersion})`,
316
+ discountable: false,
317
+ invoice: settlement.id,
318
+ metadata: {
319
+ organizationBillingJob: job.jobId,
320
+ periodEnd: String(period.end),
321
+ periodStart: String(period.start),
322
+ priceVersion: job.priceVersion
323
+ },
324
+ period: {
325
+ end: period.end / 1000,
326
+ start: Math.max(effectiveAt, period.start) / 1000
327
+ }
328
+ }, {
329
+ idempotencyKey: key(`adjustment-${period.start}-${period.end}`)
330
+ });
331
+ adjustments.push(adjustmentReceipt(item));
332
+ }
333
+ if (settlement?.status === 'draft') {
334
+ await fence();
335
+ await stripe.invoices.finalizeInvoice(settlement.id, {
336
+ auto_advance: true
337
+ }, {
338
+ idempotencyKey: key(`settlement-finalize-${period.start}-${period.end}`)
339
+ });
340
+ }
341
+ }
342
+ if (job.kind === 'plan' && lateBoundary && scheduleId) {
343
+ await fence();
344
+ await stripe.subscriptionSchedules.release(scheduleId, {}, {
345
+ idempotencyKey: key('release')
346
+ });
347
+ }
348
+ if (closed) {
349
+ await markApplied();
350
+ } else if (pendingPlan) {
351
+ await applySchedule();
352
+ await markApplied();
353
+ } else {
354
+ const seatItems = seats ? [
355
+ {
356
+ price: prices.seat,
357
+ quantity: seats
358
+ }
359
+ ] : [];
360
+ const items = [
361
+ {
362
+ id: base.id,
363
+ price: prices[plan],
364
+ quantity: 1
365
+ },
366
+ ...seat ? [
367
+ {
368
+ id: seat.id,
369
+ price: prices.seat,
370
+ quantity: seats
371
+ }
372
+ ] : seatItems
373
+ ];
374
+ await fence();
375
+ await stripe.subscriptions.update(raw.id, {
376
+ items,
377
+ metadata: metadata(),
378
+ proration_behavior: 'none'
379
+ }, {
380
+ idempotencyKey: key('apply')
381
+ });
382
+ }
383
+ return {
384
+ adjustments
385
+ };
386
+ };
387
+
388
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9wcml2YXRlL3RtcC92YXVsdC1yZWFrdG9yLWNvbXBsZXRpb24vcGFja2FnZXMvcmVha3Rvci9zcmMvb3JnYW5pemF0aW9ucy9iaWxsaW5nVXBkYXRlcy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiBGaW5hbmNpYWwgd3JpdGVzIGFyZSBvcmRlcmVkIGFuZCBmZW5jZWQ7IG1ldGFkYXRhIHJlY2VpcHRzIHN1cnZpdmUgcHJvdmlkZXIgaWRlbXBvdGVuY3kgZXhwaXJ5LiAqL1xuLyogZXNsaW50LWRpc2FibGUgbm8tYXdhaXQtaW4tbG9vcCAqL1xuaW1wb3J0IHtnZXRPcmdhbml6YXRpb25QbGFufSBmcm9tICcuL3BsYW5zLmpzJztcbmltcG9ydCB7bGlzdEFsbFByb3ZpZGVyUmVjb3Jkc30gZnJvbSAnLi9wcm92aWRlclBhZ2luYXRpb24uanMnO1xuaW1wb3J0IHtvcmdhbml6YXRpb25LZXl9IGZyb20gJy4vc3RvcmUuanMnO1xuXG5pbXBvcnQgdHlwZSBTdHJpcGUgZnJvbSAnc3RyaXBlJztcbmltcG9ydCB0eXBlIHtCaWxsaW5nQWRqdXN0bWVudCwgQmlsbGluZ1Byb3ZpZGVyLCBQbGFuS2V5fSBmcm9tICcuL3R5cGVzLmpzJztcblxudHlwZSBQcmljZXMgPSBSZWFkb25seTx7cHJvOiBzdHJpbmc7IHNlYXQ6IHN0cmluZzsgc3RhcnRlcjogc3RyaW5nfT47XG50eXBlIFBlcmlvZCA9IFJlYWRvbmx5PHtlbmQ6IG51bWJlcjsgc3RhcnQ6IG51bWJlcn0+O1xuY29uc3QgcHVibGlzaGVkUGxhbiA9ICh2YWx1ZTogdW5rbm93bik6IFBsYW5LZXkgPT4gZ2V0T3JnYW5pemF0aW9uUGxhbih2YWx1ZSBhcyBQbGFuS2V5KS5rZXk7XG5jb25zdCBzYWZlUXVhbnRpdHkgPSAodmFsdWU6IHVua25vd24pOiBudW1iZXIgPT4ge1xuICBpZih0eXBlb2YgdmFsdWUgIT09ICdudW1iZXInIHx8ICFOdW1iZXIuaXNTYWZlSW50ZWdlcih2YWx1ZSkgfHwgdmFsdWUgPCAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkX2JpbGxpbmdfam9iJyk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufTtcbmNvbnN0IGFkanVzdG1lbnRSZWNlaXB0ID0gKGl0ZW06IFN0cmlwZS5JbnZvaWNlSXRlbSk6IEJpbGxpbmdBZGp1c3RtZW50ID0+ICh7XG4gIGFtb3VudENlbnRzOiBpdGVtLmFtb3VudCxcbiAgcGVyaW9kRW5kOiBOdW1iZXIoaXRlbS5tZXRhZGF0YS5wZXJpb2RFbmQpLFxuICBwZXJpb2RTdGFydDogTnVtYmVyKGl0ZW0ubWV0YWRhdGEucGVyaW9kU3RhcnQpLFxuICBwcm92aWRlcklkOiBpdGVtLmlkXG59KTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZU9yZ2FuaXphdGlvbkJpbGxpbmdVcGRhdGVyID1cbiAgKHN0cmlwZTogU3RyaXBlLCBwcmljZXM6IFByaWNlcyk6IEJpbGxpbmdQcm92aWRlclsndXBkYXRlJ10gPT5cbiAgICBhc3luYyAoc3Vic2NyaXB0aW9uLCBqb2IsIGZlbmNlKSA9PiB7XG4gICAgICBhd2FpdCBmZW5jZSgpO1xuICAgICAgaWYoam9iLnByaWNlVmVyc2lvbiAhPT0gJzIwMjYtMTAtdjEnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignYmlsbGluZ19yYXRlX3ZlcnNpb25fdW5hdmFpbGFibGUnKTtcbiAgICAgIH1cbiAgICAgIGlmKCFOdW1iZXIuaXNTYWZlSW50ZWdlcihqb2IuZWZmZWN0aXZlQXQpIHx8IGpvYi5lZmZlY3RpdmVBdCA8IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkX2JpbGxpbmdfam9iJyk7XG4gICAgICB9XG4gICAgICBjb25zdCByYXcgPSBhd2FpdCBzdHJpcGUuc3Vic2NyaXB0aW9ucy5yZXRyaWV2ZShzdWJzY3JpcHRpb24uaWQpO1xuICAgICAgY29uc3QgY3VzdG9tZXIgPSB0eXBlb2YgcmF3LmN1c3RvbWVyID09PSAnc3RyaW5nJyA/IHJhdy5jdXN0b21lciA6IHJhdy5jdXN0b21lci5pZDtcbiAgICAgIGNvbnN0IGJhc2UgPSByYXcuaXRlbXMuZGF0YS5maW5kKChpdGVtKSA9PiBbcHJpY2VzLnBybywgcHJpY2VzLnN0YXJ0ZXJdLmluY2x1ZGVzKGl0ZW0ucHJpY2UuaWQpKTtcbiAgICAgIGNvbnN0IHNlYXQgPSByYXcuaXRlbXMuZGF0YS5maW5kKChpdGVtKSA9PiBpdGVtLnByaWNlLmlkID09PSBwcmljZXMuc2VhdCk7XG4gICAgICBpZihyYXcubGl2ZW1vZGUgfHwgY3VzdG9tZXIgIT09IHN1YnNjcmlwdGlvbi5jdXN0b21lcklkIHx8ICFiYXNlIHx8IHJhdy5pdGVtcy5oYXNfbW9yZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2JpbGxpbmdfc3Vic2NyaXB0aW9uX21pc21hdGNoJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IGxpc3RBbGxQcm92aWRlclJlY29yZHMoKHN0YXJ0aW5nQWZ0ZXIpID0+XG4gICAgICAgIHN0cmlwZS5pbnZvaWNlSXRlbXMubGlzdCh7Y3VzdG9tZXIsIGxpbWl0OiAxMDAsIHN0YXJ0aW5nX2FmdGVyOiBzdGFydGluZ0FmdGVyfSlcbiAgICAgICk7XG4gICAgICBjb25zdCBhZGp1c3RtZW50cyA9IGV4aXN0aW5nXG4gICAgICAgIC5maWx0ZXIoKGl0ZW0pID0+IGl0ZW0ubWV0YWRhdGEub3JnYW5pemF0aW9uQmlsbGluZ0pvYiA9PT0gam9iLmpvYklkKVxuICAgICAgICAubWFwKGFkanVzdG1lbnRSZWNlaXB0KTtcbiAgICAgIGlmKHJhdy5tZXRhZGF0YS5vcmdhbml6YXRpb25CaWxsaW5nSm9iID09PSBqb2Iuam9iSWQpIHtcbiAgICAgICAgcmV0dXJuIHthZGp1c3RtZW50c307XG4gICAgICB9XG4gICAgICBpZihqb2Iua2luZCA9PT0gJ3NlYXRzJyAmJiBqb2IuZWZmZWN0aXZlQXQgPCByYXcuc3RhcnRfZGF0ZSAqIDEwMDApIHtcbiAgICAgICAgcmV0dXJuIHthZGp1c3RtZW50c307XG4gICAgICB9XG4gICAgICBjb25zdCBzY2hlZHVsZUlkID0gdHlwZW9mIHJhdy5zY2hlZHVsZSA9PT0gJ3N0cmluZycgPyByYXcuc2NoZWR1bGUgOiByYXcuc2NoZWR1bGU/LmlkO1xuICAgICAgY29uc3Qgc2NoZWR1bGUgPSBzY2hlZHVsZUlkID8gYXdhaXQgc3RyaXBlLnN1YnNjcmlwdGlvblNjaGVkdWxlcy5yZXRyaWV2ZShzY2hlZHVsZUlkKSA6IG51bGw7XG4gICAgICBjb25zdCBib3VuZGFyeUNoYW5nZSA9IGpvYi5raW5kID09PSAnY2FuY2VsJyB8fCAoam9iLmtpbmQgPT09ICdwbGFuJyAmJiBqb2IuZGVzaXJlZC5jaGFuZ2VBdCA9PT0gJ3BlcmlvZF9lbmQnKTtcbiAgICAgIGNvbnN0IHRhcmdldFBlcmlvZEVuZCA9IE51bWJlcihqb2IuZGVzaXJlZC50YXJnZXRQZXJpb2RFbmQpO1xuICAgICAgY29uc3Qgc2NoZWR1bGVCb3VuZGFyeSA9IGJvdW5kYXJ5Q2hhbmdlID8gdGFyZ2V0UGVyaW9kRW5kIDogTnVtYmVyKHJhdy5tZXRhZGF0YS5vcmdhbml6YXRpb25QZW5kaW5nQm91bmRhcnkpO1xuICAgICAgY29uc3Qga2V5ID0gKG9wZXJhdGlvbjogc3RyaW5nKTogc3RyaW5nID0+IG9yZ2FuaXphdGlvbktleSgnYmlsbGluZy1qb2InLCBqb2Iuam9iSWQsIG9wZXJhdGlvbik7XG4gICAgICBjb25zdCBtZXRhZGF0YSA9IChwZW5kaW5nUGxhbiA9ICcnKSA9PiAoe1xuICAgICAgICBvcmdhbml6YXRpb25CaWxsaW5nSm9iOiBqb2Iuam9iSWQsXG4gICAgICAgIG9yZ2FuaXphdGlvblBlbmRpbmdCb3VuZGFyeTogcGVuZGluZ1BsYW4gPyBTdHJpbmcoc2NoZWR1bGVCb3VuZGFyeSkgOiAnJyxcbiAgICAgICAgb3JnYW5pemF0aW9uUGVuZGluZ1BsYW46IHBlbmRpbmdQbGFuXG4gICAgICB9KTtcbiAgICAgIGxldCBjbG9zZWQgPSByYXcuc3RhdHVzID09PSAnY2FuY2VsZWQnO1xuICAgICAgaWYoYm91bmRhcnlDaGFuZ2UgJiYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcih0YXJnZXRQZXJpb2RFbmQpIHx8IHRhcmdldFBlcmlvZEVuZCA8PSBqb2IuZWZmZWN0aXZlQXRcbiAgICAgICAgfHwgam9iLmRlc2lyZWQuc3Vic2NyaXB0aW9uSWQgIT09IHJhdy5pZCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdiaWxsaW5nX2NoYW5nZV9ib3VuZGFyeV9yZXF1aXJlZCcpO1xuICAgICAgfVxuICAgICAgY29uc3QgbGF0ZUJvdW5kYXJ5ID0gYm91bmRhcnlDaGFuZ2UgJiYgdGFyZ2V0UGVyaW9kRW5kIDw9IERhdGUubm93KCk7XG5cbiAgICAgIGlmKGpvYi5raW5kID09PSAnY2FuY2VsJyAmJiAhY2xvc2VkKSB7XG4gICAgICAgIGlmKHNjaGVkdWxlSWQpIHtcbiAgICAgICAgICBhd2FpdCBmZW5jZSgpO1xuICAgICAgICAgIGF3YWl0IHN0cmlwZS5zdWJzY3JpcHRpb25TY2hlZHVsZXMucmVsZWFzZShzY2hlZHVsZUlkLCB7fSwge2lkZW1wb3RlbmN5S2V5OiBrZXkoJ3JlbGVhc2UnKX0pO1xuICAgICAgICB9XG4gICAgICAgIGlmKCFsYXRlQm91bmRhcnkpIHtcbiAgICAgICAgICBhd2FpdCBmZW5jZSgpO1xuICAgICAgICAgIGF3YWl0IHN0cmlwZS5zdWJzY3JpcHRpb25zLnVwZGF0ZShyYXcuaWQsIHtjYW5jZWxfYXQ6IHRhcmdldFBlcmlvZEVuZCAvIDEwMDAsIG1ldGFkYXRhOiB7Li4ubWV0YWRhdGEoKSwgb3JnYW5pemF0aW9uQ2FuY2VsQm91bmRhcnk6IFN0cmluZyh0YXJnZXRQZXJpb2RFbmQpfSwgcHJvcmF0aW9uX2JlaGF2aW9yOiAnbm9uZSd9LCB7aWRlbXBvdGVuY3lLZXk6IGtleSgnY2FuY2VsJyl9KTtcbiAgICAgICAgICByZXR1cm4ge2FkanVzdG1lbnRzfTtcbiAgICAgICAgfVxuICAgICAgICBhd2FpdCBmZW5jZSgpO1xuICAgICAgICBhd2FpdCBzdHJpcGUuc3Vic2NyaXB0aW9ucy51cGRhdGUocmF3LmlkLCB7bWV0YWRhdGE6IHtvcmdhbml6YXRpb25DYW5jZWxCb3VuZGFyeTogU3RyaW5nKHRhcmdldFBlcmlvZEVuZCl9fSwge2lkZW1wb3RlbmN5S2V5OiBrZXkoJ2NhbmNlbC1pbnRlbnQnKX0pO1xuICAgICAgICBhd2FpdCBmZW5jZSgpO1xuICAgICAgICBhd2FpdCBzdHJpcGUuc3Vic2NyaXB0aW9ucy5jYW5jZWwocmF3LmlkLCB7aW52b2ljZV9ub3c6IGZhbHNlLCBwcm9yYXRlOiBmYWxzZX0sIHtpZGVtcG90ZW5jeUtleToga2V5KCdjYW5jZWwnKX0pO1xuICAgICAgICBjbG9zZWQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYoIVsnY2FuY2VsJywgJ3BsYW4nLCAnc2VhdHMnXS5pbmNsdWRlcyhqb2Iua2luZCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkX2JpbGxpbmdfam9iJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBjdXJyZW50UGxhbiA9IGJhc2UucHJpY2UuaWQgPT09IHByaWNlcy5wcm8gPyAncHJvJyA6ICdzdGFydGVyJztcbiAgICAgIGNvbnN0IHBsYW4gPSBqb2Iua2luZCA9PT0gJ3BsYW4nID8gcHVibGlzaGVkUGxhbihqb2IuZGVzaXJlZC5wbGFuKSA6IGN1cnJlbnRQbGFuO1xuICAgICAgY29uc3Qgc2VhdHMgPSBqb2Iua2luZCA9PT0gJ3NlYXRzJyA/IHNhZmVRdWFudGl0eShqb2IuZGVzaXJlZC5leHRyYVNlYXRzKSA6IHNlYXQ/LnF1YW50aXR5IHx8IDA7XG4gICAgICBsZXQgcGVuZGluZ1BsYW46IFBsYW5LZXkgfCBudWxsID0gbnVsbDtcbiAgICAgIGlmKGpvYi5raW5kID09PSAncGxhbicgJiYgam9iLmRlc2lyZWQuY2hhbmdlQXQgPT09ICdwZXJpb2RfZW5kJyAmJiAhbGF0ZUJvdW5kYXJ5KSB7XG4gICAgICAgIHBlbmRpbmdQbGFuID0gcGxhbjtcbiAgICAgIH0gZWxzZSBpZighbGF0ZUJvdW5kYXJ5ICYmIHJhdy5tZXRhZGF0YS5vcmdhbml6YXRpb25QZW5kaW5nUGxhbiA9PT0gJ3N0YXJ0ZXInICYmIGN1cnJlbnRQbGFuICE9PSAnc3RhcnRlcicpIHtcbiAgICAgICAgcGVuZGluZ1BsYW4gPSAnc3RhcnRlcic7XG4gICAgICB9XG4gICAgICBpZihwZW5kaW5nUGxhbiAmJiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKHNjaGVkdWxlQm91bmRhcnkpIHx8IHNjaGVkdWxlQm91bmRhcnkgPD0gRGF0ZS5ub3coKSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdiaWxsaW5nX2NoYW5nZV9ib3VuZGFyeV9yZXF1aXJlZCcpO1xuICAgICAgfVxuICAgICAgY29uc3QgcGhhc2VJdGVtcyA9IChwaGFzZVBsYW46IFBsYW5LZXkpID0+IFtcbiAgICAgICAge3ByaWNlOiBwcmljZXNbcGhhc2VQbGFuXSwgcXVhbnRpdHk6IDF9LFxuICAgICAgICAuLi4oc2VhdHMgPyBbe3ByaWNlOiBwcmljZXMuc2VhdCwgcXVhbnRpdHk6IHNlYXRzfV0gOiBbXSlcbiAgICAgIF07XG4gICAgICBjb25zdCBhcHBseVNjaGVkdWxlID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICBhd2FpdCBmZW5jZSgpO1xuICAgICAgICBjb25zdCBpZCA9XG4gICAgICAgICAgc2NoZWR1bGVJZCB8fFxuICAgICAgICAoXG4gICAgICAgICAgYXdhaXQgc3RyaXBlLnN1YnNjcmlwdGlvblNjaGVkdWxlcy5jcmVhdGUoXG4gICAgICAgICAgICB7ZnJvbV9zdWJzY3JpcHRpb246IHJhdy5pZH0sXG4gICAgICAgICAgICB7aWRlbXBvdGVuY3lLZXk6IGtleSgnc2NoZWR1bGUtY3JlYXRlJyl9XG4gICAgICAgICAgKVxuICAgICAgICApLmlkO1xuICAgICAgICBhd2FpdCBmZW5jZSgpO1xuICAgICAgICBhd2FpdCBzdHJpcGUuc3Vic2NyaXB0aW9uU2NoZWR1bGVzLnVwZGF0ZShcbiAgICAgICAgICBpZCxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBlbmRfYmVoYXZpb3I6ICdyZWxlYXNlJyxcbiAgICAgICAgICAgIG1ldGFkYXRhOiBtZXRhZGF0YShwZW5kaW5nUGxhbiEpLFxuICAgICAgICAgICAgcGhhc2VzOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBlbmRfZGF0ZTogc2NoZWR1bGVCb3VuZGFyeSAvIDEwMDAsXG4gICAgICAgICAgICAgICAgaXRlbXM6IHBoYXNlSXRlbXMoY3VycmVudFBsYW4pLFxuICAgICAgICAgICAgICAgIHByb3JhdGlvbl9iZWhhdmlvcjogJ25vbmUnLFxuICAgICAgICAgICAgICAgIHN0YXJ0X2RhdGU6IGJhc2UuY3VycmVudF9wZXJpb2Rfc3RhcnRcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGR1cmF0aW9uOiB7aW50ZXJ2YWw6ICdtb250aCcsIGludGVydmFsX2NvdW50OiAxfSxcbiAgICAgICAgICAgICAgICBpdGVtczogcGhhc2VJdGVtcyhwZW5kaW5nUGxhbiEpLFxuICAgICAgICAgICAgICAgIHByb3JhdGlvbl9iZWhhdmlvcjogJ25vbmUnLFxuICAgICAgICAgICAgICAgIHN0YXJ0X2RhdGU6IHNjaGVkdWxlQm91bmRhcnkgLyAxMDAwXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBwcm9yYXRpb25fYmVoYXZpb3I6ICdub25lJ1xuICAgICAgICAgIH0sXG4gICAgICAgICAge2lkZW1wb3RlbmN5S2V5OiBrZXkoJ3NjaGVkdWxlLXVwZGF0ZScpfVxuICAgICAgICApO1xuICAgICAgfTtcbiAgICAgIGNvbnN0IG1hcmtBcHBsaWVkID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICBhd2FpdCBmZW5jZSgpO1xuICAgICAgICBhd2FpdCBzdHJpcGUuc3Vic2NyaXB0aW9ucy51cGRhdGUoXG4gICAgICAgICAgcmF3LmlkLFxuICAgICAgICAgIHttZXRhZGF0YTogbWV0YWRhdGEocGVuZGluZ1BsYW4gfHwgJycpfSxcbiAgICAgICAgICB7aWRlbXBvdGVuY3lLZXk6IGtleSgnbWFya2VyJyl9XG4gICAgICAgICk7XG4gICAgICB9O1xuICAgICAgaWYoc2NoZWR1bGU/Lm1ldGFkYXRhLm9yZ2FuaXphdGlvbkJpbGxpbmdKb2IgPT09IGpvYi5qb2JJZCkge1xuICAgICAgICBhd2FpdCBtYXJrQXBwbGllZCgpO1xuICAgICAgICByZXR1cm4ge2FkanVzdG1lbnRzfTtcbiAgICAgIH1cbiAgICAgIGlmKGpvYi5raW5kID09PSAncGxhbicgJiYgam9iLmRlc2lyZWQuY2hhbmdlQXQgPT09ICdwZXJpb2RfZW5kJyAmJiAhbGF0ZUJvdW5kYXJ5KSB7XG4gICAgICAgIGF3YWl0IGFwcGx5U2NoZWR1bGUoKTtcbiAgICAgICAgYXdhaXQgbWFya0FwcGxpZWQoKTtcbiAgICAgICAgcmV0dXJuIHthZGp1c3RtZW50c307XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGN1cnJlbnRSYXRlID0gZ2V0T3JnYW5pemF0aW9uUGxhbihjdXJyZW50UGxhbikuYmFzZUNlbnRzICsgKHNlYXRzICogODAwKTtcbiAgICAgIGxldCByYXRlRGVsdGEgPSAtY3VycmVudFJhdGU7XG4gICAgICBpZihqb2Iua2luZCAhPT0gJ2NhbmNlbCcpIHtcbiAgICAgICAgcmF0ZURlbHRhID0gam9iLmtpbmQgPT09ICdzZWF0cydcbiAgICAgICAgICA/IChzZWF0cyAtIHNhZmVRdWFudGl0eShqb2IuZGVzaXJlZC5wcmV2aW91c0V4dHJhU2VhdHMpKSAqIDgwMFxuICAgICAgICAgIDogZ2V0T3JnYW5pemF0aW9uUGxhbihwbGFuKS5iYXNlQ2VudHMgLVxuICAgICAgICAgIGdldE9yZ2FuaXphdGlvblBsYW4ocHVibGlzaGVkUGxhbihqb2IuZGVzaXJlZC5wcmV2aW91c1BsYW4pKS5iYXNlQ2VudHM7XG4gICAgICB9XG4gICAgICBpZihcbiAgICAgICAgam9iLmtpbmQgPT09ICdwbGFuJyAmJlxuICAgICAgKCghbGF0ZUJvdW5kYXJ5ICYmIChqb2IuZGVzaXJlZC5jaGFuZ2VBdCAhPT0gJ2ltbWVkaWF0ZScgfHwgcmF0ZURlbHRhIDw9IDApKSB8fCAobGF0ZUJvdW5kYXJ5ICYmIHJhdGVEZWx0YSA+PSAwKSB8fCByYXcuc3RhdHVzICE9PSAnYWN0aXZlJylcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWRfYmlsbGluZ19qb2InKTtcbiAgICAgIH1cbiAgICAgIGlmKCFOdW1iZXIuaXNTYWZlSW50ZWdlcihyYXRlRGVsdGEpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZF9iaWxsaW5nX2pvYicpO1xuICAgICAgfVxuICAgICAgY29uc3QgaW52b2ljZXMgPSBhd2FpdCBsaXN0QWxsUHJvdmlkZXJSZWNvcmRzKChzdGFydGluZ0FmdGVyKSA9PlxuICAgICAgICBzdHJpcGUuaW52b2ljZXMubGlzdCh7Y3VzdG9tZXIsIGxpbWl0OiAxMDAsIHN0YXJ0aW5nX2FmdGVyOiBzdGFydGluZ0FmdGVyLCBzdWJzY3JpcHRpb246IHJhdy5pZH0pXG4gICAgICApO1xuICAgICAgaWYoaW52b2ljZXMuc29tZSgoaW52b2ljZSkgPT4gaW52b2ljZS5tZXRhZGF0YT8ub3JnYW5pemF0aW9uQmlsbGluZ0pvYiA9PT0gam9iLmpvYklkXG4gICAgICAgICYmICghTnVtYmVyLmlzU2FmZUludGVnZXIoTnVtYmVyKGludm9pY2UubWV0YWRhdGEucGVyaW9kU3RhcnQpKVxuICAgICAgICAgIHx8ICFOdW1iZXIuaXNTYWZlSW50ZWdlcihOdW1iZXIoaW52b2ljZS5tZXRhZGF0YS5wZXJpb2RFbmQpKVxuICAgICAgICAgIHx8IE51bWJlcihpbnZvaWNlLm1ldGFkYXRhLnBlcmlvZEVuZCkgPD0gTnVtYmVyKGludm9pY2UubWV0YWRhdGEucGVyaW9kU3RhcnQpKSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdiaWxsaW5nX3NldHRsZW1lbnRfY29uZmxpY3QnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBlcmlvZHMgPSBuZXcgTWFwPHN0cmluZywgUGVyaW9kPigpO1xuICAgICAgY29uc3QgcmVuZXdhbFJhdGVzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgICAgIGZvcihjb25zdCBpbnZvaWNlIG9mIGludm9pY2VzKSB7XG4gICAgICAgIGlmKGludm9pY2UubGluZXMuaGFzX21vcmUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2JpbGxpbmdfbG9va3VwX2luY29tcGxldGUnKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpbnZvaWNlUmF0ZXMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICAgICAgICBmb3IoY29uc3QgbGluZSBvZiBpbnZvaWNlLmxpbmVzLmRhdGEpIHtcbiAgICAgICAgICBjb25zdCBwcmljZSA9IGxpbmUucHJpY2luZz8ucHJpY2VfZGV0YWlscz8ucHJpY2U7XG4gICAgICAgICAgY29uc3QgcHJpY2VJZCA9IHR5cGVvZiBwcmljZSA9PT0gJ3N0cmluZycgPyBwcmljZSA6IHByaWNlPy5pZDtcbiAgICAgICAgICBpZihcbiAgICAgICAgICAgIFtwcmljZXMucHJvLCBwcmljZXMuc3RhcnRlciwgcHJpY2VzLnNlYXRdLmluY2x1ZGVzKHByaWNlSWQgfHwgJycpICYmXG4gICAgICAgICAgIWxpbmUucGFyZW50Py5zdWJzY3JpcHRpb25faXRlbV9kZXRhaWxzPy5wcm9yYXRpb25cbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnN0IHBlcmlvZCA9IHtlbmQ6IGxpbmUucGVyaW9kLmVuZCAqIDEwMDAsIHN0YXJ0OiBsaW5lLnBlcmlvZC5zdGFydCAqIDEwMDB9O1xuICAgICAgICAgICAgY29uc3QgcGVyaW9kS2V5ID0gYCR7cGVyaW9kLnN0YXJ0fS0ke3BlcmlvZC5lbmR9YDtcbiAgICAgICAgICAgIGlmKHByaWNlSWQgIT09IHByaWNlcy5zZWF0KSB7XG4gICAgICAgICAgICAgIHBlcmlvZHMuc2V0KHBlcmlvZEtleSwgcGVyaW9kKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJhdGUgPSBwcmljZUlkID09PSBwcmljZXMuc2VhdCA/IDgwMCAqIHNhZmVRdWFudGl0eShsaW5lLnF1YW50aXR5KSA6IGdldE9yZ2FuaXphdGlvblBsYW4ocHJpY2VJZCA9PT0gcHJpY2VzLnBybyA/ICdwcm8nIDogJ3N0YXJ0ZXInKS5iYXNlQ2VudHM7XG4gICAgICAgICAgICBpbnZvaWNlUmF0ZXMuc2V0KHBlcmlvZEtleSwgKGludm9pY2VSYXRlcy5nZXQocGVyaW9kS2V5KSB8fCAwKSArIHJhdGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IoY29uc3QgW3BlcmlvZEtleSwgcmF0ZV0gb2YgaW52b2ljZVJhdGVzKSB7XG4gICAgICAgICAgaWYocmVuZXdhbFJhdGVzLmhhcyhwZXJpb2RLZXkpICYmIHJlbmV3YWxSYXRlcy5nZXQocGVyaW9kS2V5KSAhPT0gcmF0ZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdiaWxsaW5nX3BlcmlvZF9oaXN0b3J5X3JlcXVpcmVkJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlbmV3YWxSYXRlcy5zZXQocGVyaW9kS2V5LCByYXRlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gQ2FuY2VsZWQgc3Vic2NyaXB0aW9ucyBtYXkgdHJ1bmNhdGUgaXRlbSBkYXRlcy4gTGljZW5zZWQgcmVuZXdhbCBpbnZvaWNlcyByZXRhaW4gdGhlIGZ1bGwgY2hhcmdlZCBwZXJpb2QuXG4gICAgICBjb25zdCBjdXJyZW50U3RhcnQgPSBiYXNlLmN1cnJlbnRfcGVyaW9kX3N0YXJ0ICogMTAwMDtcbiAgICAgIGNvbnN0IGN1cnJlbnRQZXJpb2QgPSB7XG4gICAgICAgIGVuZDogTWF0aC5tYXgoYmFzZS5jdXJyZW50X3BlcmlvZF9lbmQgKiAxMDAwLCAuLi5bLi4ucGVyaW9kcy52YWx1ZXMoKV1cbiAgICAgICAgICAuZmlsdGVyKChwZXJpb2QpID0+IHBlcmlvZC5zdGFydCA9PT0gY3VycmVudFN0YXJ0KS5tYXAoKHBlcmlvZCkgPT4gcGVyaW9kLmVuZCkpLFxuICAgICAgICBzdGFydDogY3VycmVudFN0YXJ0XG4gICAgICB9O1xuICAgICAgcGVyaW9kcy5zZXQoYCR7Y3VycmVudFBlcmlvZC5zdGFydH0tJHtjdXJyZW50UGVyaW9kLmVuZH1gLCBjdXJyZW50UGVyaW9kKTtcbiAgICAgIGNvbnN0IGVmZmVjdGl2ZUF0ID0gTWF0aC5mbG9vcigoYm91bmRhcnlDaGFuZ2UgPyB0YXJnZXRQZXJpb2RFbmQgOiBqb2IuZWZmZWN0aXZlQXQpIC8gMTAwMCkgKiAxMDAwO1xuICAgICAgY29uc3QgY2FuY2VsZWRCb3VuZGFyeSA9IE51bWJlcihyYXcubWV0YWRhdGEub3JnYW5pemF0aW9uQ2FuY2VsQm91bmRhcnkpO1xuICAgICAgY29uc3QgY2hhcmdlVGhyb3VnaCA9IGNsb3NlZCAmJiBOdW1iZXIuaXNTYWZlSW50ZWdlcihjYW5jZWxlZEJvdW5kYXJ5KSAmJiBjYW5jZWxlZEJvdW5kYXJ5ID4gMCAmJiBqb2Iua2luZCAhPT0gJ2NhbmNlbCdcbiAgICAgICAgPyBNYXRoLm1pbihjdXJyZW50UGVyaW9kLmVuZCwgY2FuY2VsZWRCb3VuZGFyeSkgOiBjdXJyZW50UGVyaW9kLmVuZDtcbiAgICAgIGNvbnN0IGFwcGxpY2FibGUgPSBbLi4ucGVyaW9kcy52YWx1ZXMoKV1cbiAgICAgICAgLmZpbHRlcigocGVyaW9kKSA9PiBwZXJpb2QuZW5kID4gZWZmZWN0aXZlQXQgJiYgcGVyaW9kLnN0YXJ0IDw9IGN1cnJlbnRQZXJpb2Quc3RhcnQpXG4gICAgICAgIC5zb3J0KChhLCBiKSA9PiBhLnN0YXJ0IC0gYi5zdGFydCk7XG4gICAgICBsZXQgY292ZXJlZFRocm91Z2ggPSBlZmZlY3RpdmVBdDtcbiAgICAgIGZvcihjb25zdCBwZXJpb2Qgb2YgYXBwbGljYWJsZSkge1xuICAgICAgICBpZihcbiAgICAgICAgICAhTnVtYmVyLmlzU2FmZUludGVnZXIocGVyaW9kLnN0YXJ0KSB8fFxuICAgICAgICAhTnVtYmVyLmlzU2FmZUludGVnZXIocGVyaW9kLmVuZCkgfHxcbiAgICAgICAgcGVyaW9kLmVuZCA8PSBwZXJpb2Quc3RhcnQgfHxcbiAgICAgICAgcGVyaW9kLnN0YXJ0ID4gY292ZXJlZFRocm91Z2hcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdiaWxsaW5nX3BlcmlvZF9oaXN0b3J5X3JlcXVpcmVkJyk7XG4gICAgICAgIH1cbiAgICAgICAgY292ZXJlZFRocm91Z2ggPSBNYXRoLm1heChjb3ZlcmVkVGhyb3VnaCwgcGVyaW9kLmVuZCk7XG4gICAgICB9XG4gICAgICBpZihjb3ZlcmVkVGhyb3VnaCA8IGNoYXJnZVRocm91Z2gpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdiaWxsaW5nX3BlcmlvZF9oaXN0b3J5X3JlcXVpcmVkJyk7XG4gICAgICB9XG4gICAgICAvLyBGaXhlZCwgcHVibGlzaGVkIFVTRCByYXRlcy4gQXBwbHkgb3JpZ2luYWwtdGltZSBhZGp1c3RtZW50cyBiZWZvcmUgZGlzYWJsaW5nIGF1dG9tYXRpYyBwcm92aWRlciBwcm9yYXRpb24uXG4gICAgICBmb3IoY29uc3QgcGVyaW9kIG9mIGFwcGxpY2FibGUpIHtcbiAgICAgICAgY29uc3QgcGVyaW9kUmF0ZSA9IGpvYi5raW5kID09PSAnY2FuY2VsJyA/IC0ocmVuZXdhbFJhdGVzLmdldChgJHtwZXJpb2Quc3RhcnR9LSR7cGVyaW9kLmVuZH1gKSA/PyAtcmF0ZURlbHRhKSA6IHJhdGVEZWx0YTtcbiAgICAgICAgY29uc3QgYW1vdW50Q2VudHMgPSBNYXRoLnJvdW5kKFxuICAgICAgICAgIChwZXJpb2RSYXRlICogTWF0aC5tYXgoMCwgTWF0aC5taW4ocGVyaW9kLmVuZCwgY2hhcmdlVGhyb3VnaCkgLSBNYXRoLm1heChlZmZlY3RpdmVBdCwgcGVyaW9kLnN0YXJ0KSkpXG4gICAgICAgICAgLyAocGVyaW9kLmVuZCAtIHBlcmlvZC5zdGFydClcbiAgICAgICAgKTtcbiAgICAgICAgaWYoIWFtb3VudENlbnRzKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYoIU51bWJlci5pc1NhZmVJbnRlZ2VyKGFtb3VudENlbnRzKSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignaW52YWxpZF9iaWxsaW5nX2pvYicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlY2VpcHQgPSBleGlzdGluZy5maW5kKChpdGVtKSA9PiBpdGVtLm1ldGFkYXRhLm9yZ2FuaXphdGlvbkJpbGxpbmdKb2IgPT09IGpvYi5qb2JJZFxuICAgICAgICAgICYmIE51bWJlcihpdGVtLm1ldGFkYXRhLnBlcmlvZFN0YXJ0KSA9PT0gcGVyaW9kLnN0YXJ0ICYmIE51bWJlcihpdGVtLm1ldGFkYXRhLnBlcmlvZEVuZCkgPT09IHBlcmlvZC5lbmQpO1xuICAgICAgICBjb25zdCBpbnZvaWNlSWQgPSB0eXBlb2YgcmVjZWlwdD8uaW52b2ljZSA9PT0gJ3N0cmluZycgPyByZWNlaXB0Lmludm9pY2UgOiByZWNlaXB0Py5pbnZvaWNlPy5pZDtcbiAgICAgICAgbGV0IHNldHRsZW1lbnQgPSBpbnZvaWNlSWQgPyBhd2FpdCBzdHJpcGUuaW52b2ljZXMucmV0cmlldmUoaW52b2ljZUlkKSA6IGludm9pY2VzLmZpbmQoKGludm9pY2UpID0+XG4gICAgICAgICAgaW52b2ljZS5tZXRhZGF0YT8ub3JnYW5pemF0aW9uQmlsbGluZ0pvYiA9PT0gam9iLmpvYklkXG4gICAgICAgICAgJiYgTnVtYmVyKGludm9pY2UubWV0YWRhdGEucGVyaW9kU3RhcnQpID09PSBwZXJpb2Quc3RhcnRcbiAgICAgICAgICAmJiBOdW1iZXIoaW52b2ljZS5tZXRhZGF0YS5wZXJpb2RFbmQpID09PSBwZXJpb2QuZW5kKTtcbiAgICAgICAgaWYocmVjZWlwdCAmJiAoIWludm9pY2VJZCB8fCByZWNlaXB0LmFtb3VudCAhPT0gYW1vdW50Q2VudHMpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdiaWxsaW5nX3NldHRsZW1lbnRfY29uZmxpY3QnKTtcbiAgICAgICAgfVxuICAgICAgICBpZighc2V0dGxlbWVudCkge1xuICAgICAgICAgIGF3YWl0IGZlbmNlKCk7XG4gICAgICAgICAgc2V0dGxlbWVudCA9IGF3YWl0IHN0cmlwZS5pbnZvaWNlcy5jcmVhdGUoe2F1dG9fYWR2YW5jZTogZmFsc2UsIGN1c3RvbWVyLFxuICAgICAgICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgICAgICAgb3JnYW5pemF0aW9uQmlsbGluZ0pvYjogam9iLmpvYklkLFxuICAgICAgICAgICAgICBwZXJpb2RFbmQ6IFN0cmluZyhwZXJpb2QuZW5kKSxcbiAgICAgICAgICAgICAgcGVyaW9kU3RhcnQ6IFN0cmluZyhwZXJpb2Quc3RhcnQpLFxuICAgICAgICAgICAgICBzdWJzY3JpcHRpb25JZDogcmF3LmlkXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcGVuZGluZ19pbnZvaWNlX2l0ZW1zX2JlaGF2aW9yOiAnZXhjbHVkZScsIC4uLihjbG9zZWQgPyB7fSA6IHtzdWJzY3JpcHRpb246IHJhdy5pZH0pXG4gICAgICAgICAgfSwge2lkZW1wb3RlbmN5S2V5OiBrZXkoYHNldHRsZW1lbnQtJHtwZXJpb2Quc3RhcnR9LSR7cGVyaW9kLmVuZH1gKX0pO1xuICAgICAgICB9XG4gICAgICAgIGlmKCFyZWNlaXB0KSB7XG4gICAgICAgICAgaWYoc2V0dGxlbWVudC5zdGF0dXMgIT09ICdkcmFmdCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignYmlsbGluZ19zZXR0bGVtZW50X2NvbmZsaWN0Jyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGF3YWl0IGZlbmNlKCk7XG4gICAgICAgICAgY29uc3QgaXRlbSA9IGF3YWl0IHN0cmlwZS5pbnZvaWNlSXRlbXMuY3JlYXRlKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBhbW91bnQ6IGFtb3VudENlbnRzLFxuICAgICAgICAgICAgICBjdXJyZW5jeTogJ3VzZCcsXG4gICAgICAgICAgICAgIGN1c3RvbWVyLFxuICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogYFJlYWt0b3IgJHtqb2Iua2luZCA9PT0gJ3NlYXRzJyA/ICdhY3RpdmUtbWVtYmVyJyA6ICdwbGFuJ30gcHJvcmF0aW9uICgke2pvYi5wcmljZVZlcnNpb259KWAsXG4gICAgICAgICAgICAgIGRpc2NvdW50YWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgIGludm9pY2U6IHNldHRsZW1lbnQuaWQsXG4gICAgICAgICAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICAgICAgICAgb3JnYW5pemF0aW9uQmlsbGluZ0pvYjogam9iLmpvYklkLFxuICAgICAgICAgICAgICAgIHBlcmlvZEVuZDogU3RyaW5nKHBlcmlvZC5lbmQpLFxuICAgICAgICAgICAgICAgIHBlcmlvZFN0YXJ0OiBTdHJpbmcocGVyaW9kLnN0YXJ0KSxcbiAgICAgICAgICAgICAgICBwcmljZVZlcnNpb246IGpvYi5wcmljZVZlcnNpb25cbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgcGVyaW9kOiB7ZW5kOiBwZXJpb2QuZW5kIC8gMTAwMCwgc3RhcnQ6IE1hdGgubWF4KGVmZmVjdGl2ZUF0LCBwZXJpb2Quc3RhcnQpIC8gMTAwMH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7aWRlbXBvdGVuY3lLZXk6IGtleShgYWRqdXN0bWVudC0ke3BlcmlvZC5zdGFydH0tJHtwZXJpb2QuZW5kfWApfVxuICAgICAgICAgICk7XG4gICAgICAgICAgYWRqdXN0bWVudHMucHVzaChhZGp1c3RtZW50UmVjZWlwdChpdGVtKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYoc2V0dGxlbWVudD8uc3RhdHVzID09PSAnZHJhZnQnKSB7XG4gICAgICAgICAgYXdhaXQgZmVuY2UoKTtcbiAgICAgICAgICBhd2FpdCBzdHJpcGUuaW52b2ljZXMuZmluYWxpemVJbnZvaWNlKFxuICAgICAgICAgICAgc2V0dGxlbWVudC5pZCxcbiAgICAgICAgICAgIHthdXRvX2FkdmFuY2U6IHRydWV9LFxuICAgICAgICAgICAge2lkZW1wb3RlbmN5S2V5OiBrZXkoYHNldHRsZW1lbnQtZmluYWxpemUtJHtwZXJpb2Quc3RhcnR9LSR7cGVyaW9kLmVuZH1gKX1cbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZihqb2Iua2luZCA9PT0gJ3BsYW4nICYmIGxhdGVCb3VuZGFyeSAmJiBzY2hlZHVsZUlkKSB7XG4gICAgICAgIGF3YWl0IGZlbmNlKCk7XG4gICAgICAgIGF3YWl0IHN0cmlwZS5zdWJzY3JpcHRpb25TY2hlZHVsZXMucmVsZWFzZShzY2hlZHVsZUlkLCB7fSwge2lkZW1wb3RlbmN5S2V5OiBrZXkoJ3JlbGVhc2UnKX0pO1xuICAgICAgfVxuICAgICAgaWYoY2xvc2VkKSB7XG4gICAgICAgIGF3YWl0IG1hcmtBcHBsaWVkKCk7XG4gICAgICB9IGVsc2UgaWYocGVuZGluZ1BsYW4pIHtcbiAgICAgICAgYXdhaXQgYXBwbHlTY2hlZHVsZSgpO1xuICAgICAgICBhd2FpdCBtYXJrQXBwbGllZCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qgc2VhdEl0ZW1zID0gc2VhdHMgPyBbe3ByaWNlOiBwcmljZXMuc2VhdCwgcXVhbnRpdHk6IHNlYXRzfV0gOiBbXTtcbiAgICAgICAgY29uc3QgaXRlbXM6IFN0cmlwZS5TdWJzY3JpcHRpb25VcGRhdGVQYXJhbXMuSXRlbVtdID0gW1xuICAgICAgICAgIHtpZDogYmFzZS5pZCwgcHJpY2U6IHByaWNlc1twbGFuXSwgcXVhbnRpdHk6IDF9LFxuICAgICAgICAgIC4uLihzZWF0XG4gICAgICAgICAgICA/IFt7aWQ6IHNlYXQuaWQsIHByaWNlOiBwcmljZXMuc2VhdCwgcXVhbnRpdHk6IHNlYXRzfV1cbiAgICAgICAgICAgIDogc2VhdEl0ZW1zKVxuICAgICAgICBdO1xuICAgICAgICBhd2FpdCBmZW5jZSgpO1xuICAgICAgICBhd2FpdCBzdHJpcGUuc3Vic2NyaXB0aW9ucy51cGRhdGUoXG4gICAgICAgICAgcmF3LmlkLFxuICAgICAgICAgIHtpdGVtcywgbWV0YWRhdGE6IG1ldGFkYXRhKCksIHByb3JhdGlvbl9iZWhhdmlvcjogJ25vbmUnfSxcbiAgICAgICAgICB7aWRlbXBvdGVuY3lLZXk6IGtleSgnYXBwbHknKX1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7YWRqdXN0bWVudHN9O1xuICAgIH07XG4iXSwibmFtZXMiOlsiZ2V0T3JnYW5pemF0aW9uUGxhbiIsImxpc3RBbGxQcm92aWRlclJlY29yZHMiLCJvcmdhbml6YXRpb25LZXkiLCJwdWJsaXNoZWRQbGFuIiwidmFsdWUiLCJrZXkiLCJzYWZlUXVhbnRpdHkiLCJOdW1iZXIiLCJpc1NhZmVJbnRlZ2VyIiwiRXJyb3IiLCJhZGp1c3RtZW50UmVjZWlwdCIsIml0ZW0iLCJhbW91bnRDZW50cyIsImFtb3VudCIsInBlcmlvZEVuZCIsIm1ldGFkYXRhIiwicGVyaW9kU3RhcnQiLCJwcm92aWRlcklkIiwiaWQiLCJjcmVhdGVPcmdhbml6YXRpb25CaWxsaW5nVXBkYXRlciIsInN0cmlwZSIsInByaWNlcyIsInN1YnNjcmlwdGlvbiIsImpvYiIsImZlbmNlIiwicHJpY2VWZXJzaW9uIiwiZWZmZWN0aXZlQXQiLCJyYXciLCJzdWJzY3JpcHRpb25zIiwicmV0cmlldmUiLCJjdXN0b21lciIsImJhc2UiLCJpdGVtcyIsImRhdGEiLCJmaW5kIiwicHJvIiwic3RhcnRlciIsImluY2x1ZGVzIiwicHJpY2UiLCJzZWF0IiwibGl2ZW1vZGUiLCJjdXN0b21lcklkIiwiaGFzX21vcmUiLCJleGlzdGluZyIsInN0YXJ0aW5nQWZ0ZXIiLCJpbnZvaWNlSXRlbXMiLCJsaXN0IiwibGltaXQiLCJzdGFydGluZ19hZnRlciIsImFkanVzdG1lbnRzIiwiZmlsdGVyIiwib3JnYW5pemF0aW9uQmlsbGluZ0pvYiIsImpvYklkIiwibWFwIiwia2luZCIsInN0YXJ0X2RhdGUiLCJzY2hlZHVsZUlkIiwic2NoZWR1bGUiLCJzdWJzY3JpcHRpb25TY2hlZHVsZXMiLCJib3VuZGFyeUNoYW5nZSIsImRlc2lyZWQiLCJjaGFuZ2VBdCIsInRhcmdldFBlcmlvZEVuZCIsInNjaGVkdWxlQm91bmRhcnkiLCJvcmdhbml6YXRpb25QZW5kaW5nQm91bmRhcnkiLCJvcGVyYXRpb24iLCJwZW5kaW5nUGxhbiIsIlN0cmluZyIsIm9yZ2FuaXphdGlvblBlbmRpbmdQbGFuIiwiY2xvc2VkIiwic3RhdHVzIiwic3Vic2NyaXB0aW9uSWQiLCJsYXRlQm91bmRhcnkiLCJEYXRlIiwibm93IiwicmVsZWFzZSIsImlkZW1wb3RlbmN5S2V5IiwidXBkYXRlIiwiY2FuY2VsX2F0Iiwib3JnYW5pemF0aW9uQ2FuY2VsQm91bmRhcnkiLCJwcm9yYXRpb25fYmVoYXZpb3IiLCJjYW5jZWwiLCJpbnZvaWNlX25vdyIsInByb3JhdGUiLCJjdXJyZW50UGxhbiIsInBsYW4iLCJzZWF0cyIsImV4dHJhU2VhdHMiLCJxdWFudGl0eSIsInBoYXNlSXRlbXMiLCJwaGFzZVBsYW4iLCJhcHBseVNjaGVkdWxlIiwiY3JlYXRlIiwiZnJvbV9zdWJzY3JpcHRpb24iLCJlbmRfYmVoYXZpb3IiLCJwaGFzZXMiLCJlbmRfZGF0ZSIsImN1cnJlbnRfcGVyaW9kX3N0YXJ0IiwiZHVyYXRpb24iLCJpbnRlcnZhbCIsImludGVydmFsX2NvdW50IiwibWFya0FwcGxpZWQiLCJjdXJyZW50UmF0ZSIsImJhc2VDZW50cyIsInJhdGVEZWx0YSIsInByZXZpb3VzRXh0cmFTZWF0cyIsInByZXZpb3VzUGxhbiIsImludm9pY2VzIiwic29tZSIsImludm9pY2UiLCJwZXJpb2RzIiwiTWFwIiwicmVuZXdhbFJhdGVzIiwibGluZXMiLCJpbnZvaWNlUmF0ZXMiLCJsaW5lIiwicHJpY2luZyIsInByaWNlX2RldGFpbHMiLCJwcmljZUlkIiwicGFyZW50Iiwic3Vic2NyaXB0aW9uX2l0ZW1fZGV0YWlscyIsInByb3JhdGlvbiIsInBlcmlvZCIsImVuZCIsInN0YXJ0IiwicGVyaW9kS2V5Iiwic2V0IiwicmF0ZSIsImdldCIsImhhcyIsImN1cnJlbnRTdGFydCIsImN1cnJlbnRQZXJpb2QiLCJNYXRoIiwibWF4IiwiY3VycmVudF9wZXJpb2RfZW5kIiwidmFsdWVzIiwiZmxvb3IiLCJjYW5jZWxlZEJvdW5kYXJ5IiwiY2hhcmdlVGhyb3VnaCIsIm1pbiIsImFwcGxpY2FibGUiLCJzb3J0IiwiYSIsImIiLCJjb3ZlcmVkVGhyb3VnaCIsInBlcmlvZFJhdGUiLCJyb3VuZCIsInJlY2VpcHQiLCJpbnZvaWNlSWQiLCJzZXR0bGVtZW50IiwiYXV0b19hZHZhbmNlIiwicGVuZGluZ19pbnZvaWNlX2l0ZW1zX2JlaGF2aW9yIiwiY3VycmVuY3kiLCJkZXNjcmlwdGlvbiIsImRpc2NvdW50YWJsZSIsInB1c2giLCJmaW5hbGl6ZUludm9pY2UiLCJzZWF0SXRlbXMiXSwibWFwcGluZ3MiOiJBQUFBLG1HQUFtRyxHQUNuRyxtQ0FBbUMsR0FDbkMsU0FBUUEsbUJBQW1CLFFBQU8sYUFBYTtBQUMvQyxTQUFRQyxzQkFBc0IsUUFBTywwQkFBMEI7QUFDL0QsU0FBUUMsZUFBZSxRQUFPLGFBQWE7QUFPM0MsTUFBTUMsZ0JBQWdCLENBQUNDLFFBQTRCSixvQkFBb0JJLE9BQWtCQyxHQUFHO0FBQzVGLE1BQU1DLGVBQWUsQ0FBQ0Y7SUFDcEIsSUFBRyxPQUFPQSxVQUFVLFlBQVksQ0FBQ0csT0FBT0MsYUFBYSxDQUFDSixVQUFVQSxRQUFRLEdBQUc7UUFDekUsTUFBTSxJQUFJSyxNQUFNO0lBQ2xCO0lBQ0EsT0FBT0w7QUFDVDtBQUNBLE1BQU1NLG9CQUFvQixDQUFDQyxPQUFpRCxDQUFBO1FBQzFFQyxhQUFhRCxLQUFLRSxNQUFNO1FBQ3hCQyxXQUFXUCxPQUFPSSxLQUFLSSxRQUFRLENBQUNELFNBQVM7UUFDekNFLGFBQWFULE9BQU9JLEtBQUtJLFFBQVEsQ0FBQ0MsV0FBVztRQUM3Q0MsWUFBWU4sS0FBS08sRUFBRTtJQUNyQixDQUFBO0FBRUEsT0FBTyxNQUFNQyxtQ0FDWCxDQUFDQyxRQUFn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
@@ -0,0 +1,10 @@
1
+ export * from './plans.js';
2
+ export * from './types.js';
3
+ export * from './authorization.js';
4
+ export * from './billing.js';
5
+ export * from './billingProvider.js';
6
+ export * from './membership.js';
7
+ export * from './memberDirectory.js';
8
+ export * from './reconciliation.js';
9
+ export * from './signup.js';
10
+ export * from './verification.js';
@@ -0,0 +1,12 @@
1
+ export * from './plans.js';
2
+ export * from './types.js';
3
+ export * from './authorization.js';
4
+ export * from './billing.js';
5
+ export * from './billingProvider.js';
6
+ export * from './membership.js';
7
+ export * from './memberDirectory.js';
8
+ export * from './reconciliation.js';
9
+ export * from './signup.js';
10
+ export * from './verification.js';
11
+
12
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9wcml2YXRlL3RtcC92YXVsdC1yZWFrdG9yLWNvbXBsZXRpb24vcGFja2FnZXMvcmVha3Rvci9zcmMvb3JnYW5pemF0aW9ucy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL3BsYW5zLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vdHlwZXMuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9hdXRob3JpemF0aW9uLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vYmlsbGluZy5qcyc7XG5leHBvcnQgKiBmcm9tICcuL2JpbGxpbmdQcm92aWRlci5qcyc7XG5leHBvcnQgKiBmcm9tICcuL21lbWJlcnNoaXAuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9tZW1iZXJEaXJlY3RvcnkuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9yZWNvbmNpbGlhdGlvbi5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3NpZ251cC5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3ZlcmlmaWNhdGlvbi5qcyc7XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxhQUFhO0FBQzNCLGNBQWMsYUFBYTtBQUMzQixjQUFjLHFCQUFxQjtBQUNuQyxjQUFjLGVBQWU7QUFDN0IsY0FBYyx1QkFBdUI7QUFDckMsY0FBYyxrQkFBa0I7QUFDaEMsY0FBYyx1QkFBdUI7QUFDckMsY0FBYyxzQkFBc0I7QUFDcEMsY0FBYyxjQUFjO0FBQzVCLGNBQWMsb0JBQW9CIn0=
@@ -0,0 +1,10 @@
1
+ type OrganizationMail = {
2
+ email: string;
3
+ registrationId: string;
4
+ token: string;
5
+ };
6
+ export declare const organizationMailKey: () => Buffer;
7
+ export declare const encodeOrganizationMail: (payload: OrganizationMail) => string;
8
+ export declare const decodeOrganizationMail: (ciphertext: string) => OrganizationMail;
9
+ export declare const sendOrganizationMail: (ciphertext: string) => Promise<void>;
10
+ export {};
@@ -0,0 +1,60 @@
1
+ import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';
2
+ import { sesSend } from '../actions/email.js';
3
+ export const organizationMailKey = ()=>{
4
+ const key = process.env.ORGANIZATION_MAIL_KEY || '';
5
+ if (!/^[a-f0-9]{64}$/i.test(key)) {
6
+ throw new Error('organization_mail_not_configured');
7
+ }
8
+ return Buffer.from(key, 'hex');
9
+ };
10
+ export const encodeOrganizationMail = (payload)=>{
11
+ const iv = randomBytes(12);
12
+ const cipher = createCipheriv('aes-256-gcm', organizationMailKey(), iv);
13
+ const ciphertext = Buffer.concat([
14
+ cipher.update(JSON.stringify(payload), 'utf8'),
15
+ cipher.final()
16
+ ]);
17
+ return Buffer.concat([
18
+ iv,
19
+ cipher.getAuthTag(),
20
+ ciphertext
21
+ ]).toString('base64url');
22
+ };
23
+ export const decodeOrganizationMail = (ciphertext)=>{
24
+ const data = Buffer.from(ciphertext, 'base64url');
25
+ const decipher = createDecipheriv('aes-256-gcm', organizationMailKey(), data.subarray(0, 12));
26
+ decipher.setAuthTag(data.subarray(12, 28));
27
+ return JSON.parse(Buffer.concat([
28
+ decipher.update(data.subarray(28)),
29
+ decipher.final()
30
+ ]).toString('utf8'));
31
+ };
32
+ export const sendOrganizationMail = async (ciphertext)=>{
33
+ const payload = decodeOrganizationMail(ciphertext);
34
+ const origin = process.env.ORGANIZATION_SITE_ORIGIN || '';
35
+ const from = process.env.ORGANIZATION_EMAIL_FROM || '';
36
+ if (!/^https:\/\/[^/?#]+$/.test(origin) || !from.includes('@')) {
37
+ throw new Error('organization_mail_not_configured');
38
+ }
39
+ const url = `${origin}/verify-email#registration=${encodeURIComponent(payload.registrationId)}&token=${encodeURIComponent(payload.token)}`;
40
+ await sesSend({
41
+ Destination: {
42
+ ToAddresses: [
43
+ payload.email
44
+ ]
45
+ },
46
+ Message: {
47
+ Body: {
48
+ Text: {
49
+ Data: `Verify your Reaktor account: ${url}\nThis link expires in 24 hours.`
50
+ }
51
+ },
52
+ Subject: {
53
+ Data: 'Verify your Reaktor account'
54
+ }
55
+ },
56
+ Source: from
57
+ });
58
+ };
59
+
60
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9wcml2YXRlL3RtcC92YXVsdC1yZWFrdG9yLWNvbXBsZXRpb24vcGFja2FnZXMvcmVha3Rvci9zcmMvb3JnYW5pemF0aW9ucy9tYWlsLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Y3JlYXRlQ2lwaGVyaXYsIGNyZWF0ZURlY2lwaGVyaXYsIHJhbmRvbUJ5dGVzfSBmcm9tICdub2RlOmNyeXB0byc7XG5cbmltcG9ydCB7c2VzU2VuZH0gZnJvbSAnLi4vYWN0aW9ucy9lbWFpbC5qcyc7XG5cbnR5cGUgT3JnYW5pemF0aW9uTWFpbCA9IHtlbWFpbDogc3RyaW5nOyByZWdpc3RyYXRpb25JZDogc3RyaW5nOyB0b2tlbjogc3RyaW5nfTtcbmV4cG9ydCBjb25zdCBvcmdhbml6YXRpb25NYWlsS2V5ID0gKCk6IEJ1ZmZlciA9PiB7XG4gIGNvbnN0IGtleSA9IHByb2Nlc3MuZW52Lk9SR0FOSVpBVElPTl9NQUlMX0tFWSB8fCAnJztcbiAgaWYoIS9eW2EtZjAtOV17NjR9JC9pLnRlc3Qoa2V5KSkge1xuICAgIHRocm93IG5ldyBFcnJvcignb3JnYW5pemF0aW9uX21haWxfbm90X2NvbmZpZ3VyZWQnKTtcbiAgfVxuICByZXR1cm4gQnVmZmVyLmZyb20oa2V5LCAnaGV4Jyk7XG59O1xuZXhwb3J0IGNvbnN0IGVuY29kZU9yZ2FuaXphdGlvbk1haWwgPSAocGF5bG9hZDogT3JnYW5pemF0aW9uTWFpbCk6IHN0cmluZyA9PiB7XG4gIGNvbnN0IGl2ID0gcmFuZG9tQnl0ZXMoMTIpO1xuICBjb25zdCBjaXBoZXIgPSBjcmVhdGVDaXBoZXJpdignYWVzLTI1Ni1nY20nLCBvcmdhbml6YXRpb25NYWlsS2V5KCksIGl2KTtcbiAgY29uc3QgY2lwaGVydGV4dCA9IEJ1ZmZlci5jb25jYXQoW2NpcGhlci51cGRhdGUoSlNPTi5zdHJpbmdpZnkocGF5bG9hZCksICd1dGY4JyksIGNpcGhlci5maW5hbCgpXSk7XG4gIHJldHVybiBCdWZmZXIuY29uY2F0KFtpdiwgY2lwaGVyLmdldEF1dGhUYWcoKSwgY2lwaGVydGV4dF0pLnRvU3RyaW5nKCdiYXNlNjR1cmwnKTtcbn07XG5leHBvcnQgY29uc3QgZGVjb2RlT3JnYW5pemF0aW9uTWFpbCA9IChjaXBoZXJ0ZXh0OiBzdHJpbmcpOiBPcmdhbml6YXRpb25NYWlsID0+IHtcbiAgY29uc3QgZGF0YSA9IEJ1ZmZlci5mcm9tKGNpcGhlcnRleHQsICdiYXNlNjR1cmwnKTtcbiAgY29uc3QgZGVjaXBoZXIgPSBjcmVhdGVEZWNpcGhlcml2KCdhZXMtMjU2LWdjbScsIG9yZ2FuaXphdGlvbk1haWxLZXkoKSwgZGF0YS5zdWJhcnJheSgwLCAxMikpO1xuICBkZWNpcGhlci5zZXRBdXRoVGFnKGRhdGEuc3ViYXJyYXkoMTIsIDI4KSk7XG4gIHJldHVybiBKU09OLnBhcnNlKFxuICAgIEJ1ZmZlci5jb25jYXQoW2RlY2lwaGVyLnVwZGF0ZShkYXRhLnN1YmFycmF5KDI4KSksIGRlY2lwaGVyLmZpbmFsKCldKS50b1N0cmluZygndXRmOCcpXG4gICkgYXMgT3JnYW5pemF0aW9uTWFpbDtcbn07XG5leHBvcnQgY29uc3Qgc2VuZE9yZ2FuaXphdGlvbk1haWwgPSBhc3luYyAoY2lwaGVydGV4dDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gIGNvbnN0IHBheWxvYWQgPSBkZWNvZGVPcmdhbml6YXRpb25NYWlsKGNpcGhlcnRleHQpO1xuICBjb25zdCBvcmlnaW4gPSBwcm9jZXNzLmVudi5PUkdBTklaQVRJT05fU0lURV9PUklHSU4gfHwgJyc7XG4gIGNvbnN0IGZyb20gPSBwcm9jZXNzLmVudi5PUkdBTklaQVRJT05fRU1BSUxfRlJPTSB8fCAnJztcbiAgaWYoIS9eaHR0cHM6XFwvXFwvW14vPyNdKyQvLnRlc3Qob3JpZ2luKSB8fCAhZnJvbS5pbmNsdWRlcygnQCcpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdvcmdhbml6YXRpb25fbWFpbF9ub3RfY29uZmlndXJlZCcpO1xuICB9XG4gIGNvbnN0IHVybCA9IGAke29yaWdpbn0vdmVyaWZ5LWVtYWlsI3JlZ2lzdHJhdGlvbj0ke2VuY29kZVVSSUNvbXBvbmVudChwYXlsb2FkLnJlZ2lzdHJhdGlvbklkKX0mdG9rZW49JHtlbmNvZGVVUklDb21wb25lbnQocGF5bG9hZC50b2tlbil9YDtcbiAgYXdhaXQgc2VzU2VuZCh7XG4gICAgRGVzdGluYXRpb246IHtUb0FkZHJlc3NlczogW3BheWxvYWQuZW1haWxdfSxcbiAgICBNZXNzYWdlOiB7XG4gICAgICBCb2R5OiB7VGV4dDoge0RhdGE6IGBWZXJpZnkgeW91ciBSZWFrdG9yIGFjY291bnQ6ICR7dXJsfVxcblRoaXMgbGluayBleHBpcmVzIGluIDI0IGhvdXJzLmB9fSxcbiAgICAgIFN1YmplY3Q6IHtEYXRhOiAnVmVyaWZ5IHlvdXIgUmVha3RvciBhY2NvdW50J31cbiAgICB9LFxuICAgIFNvdXJjZTogZnJvbVxuICB9KTtcbn07XG4iXSwibmFtZXMiOlsiY3JlYXRlQ2lwaGVyaXYiLCJjcmVhdGVEZWNpcGhlcml2IiwicmFuZG9tQnl0ZXMiLCJzZXNTZW5kIiwib3JnYW5pemF0aW9uTWFpbEtleSIsImtleSIsInByb2Nlc3MiLCJlbnYiLCJPUkdBTklaQVRJT05fTUFJTF9LRVkiLCJ0ZXN0IiwiRXJyb3IiLCJCdWZmZXIiLCJmcm9tIiwiZW5jb2RlT3JnYW5pemF0aW9uTWFpbCIsInBheWxvYWQiLCJpdiIsImNpcGhlciIsImNpcGhlcnRleHQiLCJjb25jYXQiLCJ1cGRhdGUiLCJKU09OIiwic3RyaW5naWZ5IiwiZmluYWwiLCJnZXRBdXRoVGFnIiwidG9TdHJpbmciLCJkZWNvZGVPcmdhbml6YXRpb25NYWlsIiwiZGF0YSIsImRlY2lwaGVyIiwic3ViYXJyYXkiLCJzZXRBdXRoVGFnIiwicGFyc2UiLCJzZW5kT3JnYW5pemF0aW9uTWFpbCIsIm9yaWdpbiIsIk9SR0FOSVpBVElPTl9TSVRFX09SSUdJTiIsIk9SR0FOSVpBVElPTl9FTUFJTF9GUk9NIiwiaW5jbHVkZXMiLCJ1cmwiLCJlbmNvZGVVUklDb21wb25lbnQiLCJyZWdpc3RyYXRpb25JZCIsInRva2VuIiwiRGVzdGluYXRpb24iLCJUb0FkZHJlc3NlcyIsImVtYWlsIiwiTWVzc2FnZSIsIkJvZHkiLCJUZXh0IiwiRGF0YSIsIlN1YmplY3QiLCJTb3VyY2UiXSwibWFwcGluZ3MiOiJBQUFBLFNBQVFBLGNBQWMsRUFBRUMsZ0JBQWdCLEVBQUVDLFdBQVcsUUFBTyxjQUFjO0FBRTFFLFNBQVFDLE9BQU8sUUFBTyxzQkFBc0I7QUFHNUMsT0FBTyxNQUFNQyxzQkFBc0I7SUFDakMsTUFBTUMsTUFBTUMsUUFBUUMsR0FBRyxDQUFDQyxxQkFBcUIsSUFBSTtJQUNqRCxJQUFHLENBQUMsa0JBQWtCQyxJQUFJLENBQUNKLE1BQU07UUFDL0IsTUFBTSxJQUFJSyxNQUFNO0lBQ2xCO0lBQ0EsT0FBT0MsT0FBT0MsSUFBSSxDQUFDUCxLQUFLO0FBQzFCLEVBQUU7QUFDRixPQUFPLE1BQU1RLHlCQUF5QixDQUFDQztJQUNyQyxNQUFNQyxLQUFLYixZQUFZO0lBQ3ZCLE1BQU1jLFNBQVNoQixlQUFlLGVBQWVJLHVCQUF1Qlc7SUFDcEUsTUFBTUUsYUFBYU4sT0FBT08sTUFBTSxDQUFDO1FBQUNGLE9BQU9HLE1BQU0sQ0FBQ0MsS0FBS0MsU0FBUyxDQUFDUCxVQUFVO1FBQVNFLE9BQU9NLEtBQUs7S0FBRztJQUNqRyxPQUFPWCxPQUFPTyxNQUFNLENBQUM7UUFBQ0g7UUFBSUMsT0FBT08sVUFBVTtRQUFJTjtLQUFXLEVBQUVPLFFBQVEsQ0FBQztBQUN2RSxFQUFFO0FBQ0YsT0FBTyxNQUFNQyx5QkFBeUIsQ0FBQ1I7SUFDckMsTUFBTVMsT0FBT2YsT0FBT0MsSUFBSSxDQUFDSyxZQUFZO0lBQ3JDLE1BQU1VLFdBQVcxQixpQkFBaUIsZUFBZUcsdUJBQXVCc0IsS0FBS0UsUUFBUSxDQUFDLEdBQUc7SUFDekZELFNBQVNFLFVBQVUsQ0FBQ0gsS0FBS0UsUUFBUSxDQUFDLElBQUk7SUFDdEMsT0FBT1IsS0FBS1UsS0FBSyxDQUNmbkIsT0FBT08sTUFBTSxDQUFDO1FBQUNTLFNBQVNSLE1BQU0sQ0FBQ08sS0FBS0UsUUFBUSxDQUFDO1FBQU1ELFNBQVNMLEtBQUs7S0FBRyxFQUFFRSxRQUFRLENBQUM7QUFFbkYsRUFBRTtBQUNGLE9BQU8sTUFBTU8sdUJBQXVCLE9BQU9kO0lBQ3pDLE1BQU1ILFVBQVVXLHVCQUF1QlI7SUFDdkMsTUFBTWUsU0FBUzFCLFFBQVFDLEdBQUcsQ0FBQzBCLHdCQUF3QixJQUFJO0lBQ3ZELE1BQU1yQixPQUFPTixRQUFRQyxHQUFHLENBQUMyQix1QkFBdUIsSUFBSTtJQUNwRCxJQUFHLENBQUMsc0JBQXNCekIsSUFBSSxDQUFDdUIsV0FBVyxDQUFDcEIsS0FBS3VCLFFBQVEsQ0FBQyxNQUFNO1FBQzdELE1BQU0sSUFBSXpCLE1BQU07SUFDbEI7SUFDQSxNQUFNMEIsTUFBTSxHQUFHSixPQUFPLDJCQUEyQixFQUFFSyxtQkFBbUJ2QixRQUFRd0IsY0FBYyxFQUFFLE9BQU8sRUFBRUQsbUJBQW1CdkIsUUFBUXlCLEtBQUssR0FBRztJQUMxSSxNQUFNcEMsUUFBUTtRQUNacUMsYUFBYTtZQUFDQyxhQUFhO2dCQUFDM0IsUUFBUTRCLEtBQUs7YUFBQztRQUFBO1FBQzFDQyxTQUFTO1lBQ1BDLE1BQU07Z0JBQUNDLE1BQU07b0JBQUNDLE1BQU0sQ0FBQyw2QkFBNkIsRUFBRVYsSUFBSSxnQ0FBZ0MsQ0FBQztnQkFBQTtZQUFDO1lBQzFGVyxTQUFTO2dCQUFDRCxNQUFNO1lBQTZCO1FBQy9DO1FBQ0FFLFFBQVFwQztJQUNWO0FBQ0YsRUFBRSJ9
@@ -0,0 +1,15 @@
1
+ import type { ApiContext } from '../types/auth.types.js';
2
+ export type PendingOrganizationInvitation = Readonly<{
3
+ email: string;
4
+ expiresAt: number;
5
+ invitationId: string;
6
+ organizationId: string;
7
+ }>;
8
+ export type PendingOrganizationTransfer = Readonly<{
9
+ expiresAt: number;
10
+ organizationId: string;
11
+ recipientUserId: string;
12
+ transferId: string;
13
+ }>;
14
+ export declare const listOrganizationInvitations: (context: ApiContext, organizationId: string) => Promise<PendingOrganizationInvitation[]>;
15
+ export declare const listOrganizationTransfers: (context: ApiContext, organizationId: string) => Promise<PendingOrganizationTransfer[]>;
@@ -0,0 +1,28 @@
1
+ /* ArangoDB document keys are reserved metadata. */ /* eslint no-underscore-dangle: ["warn", {"allow": ["_key"]}] */ import { organizationAccessInTransaction } from './authorization.js';
2
+ import { organizationStoreFor } from './store.js';
3
+ export const listOrganizationInvitations = (context, organizationId)=>organizationStoreFor(context).transaction(async (tx)=>{
4
+ await organizationAccessInTransaction(tx, context, organizationId, 'admin');
5
+ const invitations = await tx.find('organizationInvitations', {
6
+ organizationId
7
+ });
8
+ return invitations.filter((item)=>!item.used && !item.revoked && item.expiresAt > Date.now()).map((item)=>({
9
+ email: item.email,
10
+ expiresAt: item.expiresAt,
11
+ invitationId: item._key,
12
+ organizationId
13
+ }));
14
+ });
15
+ export const listOrganizationTransfers = (context, organizationId)=>organizationStoreFor(context).transaction(async (tx)=>{
16
+ const { organization, userId } = await organizationAccessInTransaction(tx, context, organizationId, 'member');
17
+ const transfers = await tx.find('organizationOwnerTransfers', {
18
+ organizationId
19
+ });
20
+ return transfers.filter((item)=>!item.used && item.expiresAt > Date.now() && item.revision === organization.revision && item.ownerUserId === organization.ownerUserId && (userId === organization.ownerUserId || userId === item.recipientUserId)).map((item)=>({
21
+ expiresAt: item.expiresAt,
22
+ organizationId,
23
+ recipientUserId: item.recipientUserId,
24
+ transferId: item._key
25
+ }));
26
+ });
27
+
28
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9wcml2YXRlL3RtcC92YXVsdC1yZWFrdG9yLWNvbXBsZXRpb24vcGFja2FnZXMvcmVha3Rvci9zcmMvb3JnYW5pemF0aW9ucy9tZW1iZXJEaXJlY3RvcnkudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyogQXJhbmdvREIgZG9jdW1lbnQga2V5cyBhcmUgcmVzZXJ2ZWQgbWV0YWRhdGEuICovXG4vKiBlc2xpbnQgbm8tdW5kZXJzY29yZS1kYW5nbGU6IFtcIndhcm5cIiwge1wiYWxsb3dcIjogW1wiX2tleVwiXX1dICovXG5pbXBvcnQge29yZ2FuaXphdGlvbkFjY2Vzc0luVHJhbnNhY3Rpb259IGZyb20gJy4vYXV0aG9yaXphdGlvbi5qcyc7XG5pbXBvcnQge29yZ2FuaXphdGlvblN0b3JlRm9yfSBmcm9tICcuL3N0b3JlLmpzJztcblxuaW1wb3J0IHR5cGUge0FwaUNvbnRleHR9IGZyb20gJy4uL3R5cGVzL2F1dGgudHlwZXMuanMnO1xuXG5leHBvcnQgdHlwZSBQZW5kaW5nT3JnYW5pemF0aW9uSW52aXRhdGlvbiA9IFJlYWRvbmx5PHtcbiAgZW1haWw6IHN0cmluZztcbiAgZXhwaXJlc0F0OiBudW1iZXI7XG4gIGludml0YXRpb25JZDogc3RyaW5nO1xuICBvcmdhbml6YXRpb25JZDogc3RyaW5nO1xufT47XG5leHBvcnQgdHlwZSBQZW5kaW5nT3JnYW5pemF0aW9uVHJhbnNmZXIgPSBSZWFkb25seTx7XG4gIGV4cGlyZXNBdDogbnVtYmVyO1xuICBvcmdhbml6YXRpb25JZDogc3RyaW5nO1xuICByZWNpcGllbnRVc2VySWQ6IHN0cmluZztcbiAgdHJhbnNmZXJJZDogc3RyaW5nO1xufT47XG50eXBlIEludml0YXRpb24gPSBPbWl0PFBlbmRpbmdPcmdhbml6YXRpb25JbnZpdGF0aW9uLCAnaW52aXRhdGlvbklkJz4gJiB7cmV2b2tlZDogYm9vbGVhbjsgdXNlZDogYm9vbGVhbn07XG50eXBlIFRyYW5zZmVyID0gT21pdDxQZW5kaW5nT3JnYW5pemF0aW9uVHJhbnNmZXIsICd0cmFuc2ZlcklkJz4gJiB7XG4gIG93bmVyVXNlcklkOiBzdHJpbmc7XG4gIHJldmlzaW9uOiBudW1iZXI7XG4gIHVzZWQ6IGJvb2xlYW47XG59O1xuXG5leHBvcnQgY29uc3QgbGlzdE9yZ2FuaXphdGlvbkludml0YXRpb25zID0gKFxuICBjb250ZXh0OiBBcGlDb250ZXh0LFxuICBvcmdhbml6YXRpb25JZDogc3RyaW5nXG4pOiBQcm9taXNlPFBlbmRpbmdPcmdhbml6YXRpb25JbnZpdGF0aW9uW10+ID0+IG9yZ2FuaXphdGlvblN0b3JlRm9yKGNvbnRleHQpLnRyYW5zYWN0aW9uKGFzeW5jICh0eCkgPT4ge1xuICBhd2FpdCBvcmdhbml6YXRpb25BY2Nlc3NJblRyYW5zYWN0aW9uKHR4LCBjb250ZXh0LCBvcmdhbml6YXRpb25JZCwgJ2FkbWluJyk7XG4gIGNvbnN0IGludml0YXRpb25zID0gYXdhaXQgdHguZmluZDxJbnZpdGF0aW9uPignb3JnYW5pemF0aW9uSW52aXRhdGlvbnMnLCB7b3JnYW5pemF0aW9uSWR9KTtcbiAgcmV0dXJuIGludml0YXRpb25zLmZpbHRlcigoaXRlbSkgPT4gIWl0ZW0udXNlZCAmJiAhaXRlbS5yZXZva2VkICYmIGl0ZW0uZXhwaXJlc0F0ID4gRGF0ZS5ub3coKSlcbiAgICAubWFwKChpdGVtKSA9PiAoe2VtYWlsOiBpdGVtLmVtYWlsLCBleHBpcmVzQXQ6IGl0ZW0uZXhwaXJlc0F0LCBpbnZpdGF0aW9uSWQ6IGl0ZW0uX2tleSwgb3JnYW5pemF0aW9uSWR9KSk7XG59KTtcblxuZXhwb3J0IGNvbnN0IGxpc3RPcmdhbml6YXRpb25UcmFuc2ZlcnMgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIG9yZ2FuaXphdGlvbklkOiBzdHJpbmdcbik6IFByb21pc2U8UGVuZGluZ09yZ2FuaXphdGlvblRyYW5zZmVyW10+ID0+IG9yZ2FuaXphdGlvblN0b3JlRm9yKGNvbnRleHQpLnRyYW5zYWN0aW9uKGFzeW5jICh0eCkgPT4ge1xuICBjb25zdCB7b3JnYW5pemF0aW9uLCB1c2VySWR9ID0gYXdhaXQgb3JnYW5pemF0aW9uQWNjZXNzSW5UcmFuc2FjdGlvbih0eCwgY29udGV4dCwgb3JnYW5pemF0aW9uSWQsICdtZW1iZXInKTtcbiAgY29uc3QgdHJhbnNmZXJzID0gYXdhaXQgdHguZmluZDxUcmFuc2Zlcj4oJ29yZ2FuaXphdGlvbk93bmVyVHJhbnNmZXJzJywge29yZ2FuaXphdGlvbklkfSk7XG4gIHJldHVybiB0cmFuc2ZlcnMuZmlsdGVyKChpdGVtKSA9PiAhaXRlbS51c2VkICYmIGl0ZW0uZXhwaXJlc0F0ID4gRGF0ZS5ub3coKVxuICAgICYmIGl0ZW0ucmV2aXNpb24gPT09IG9yZ2FuaXphdGlvbi5yZXZpc2lvbiAmJiBpdGVtLm93bmVyVXNlcklkID09PSBvcmdhbml6YXRpb24ub3duZXJVc2VySWRcbiAgICAmJiAodXNlcklkID09PSBvcmdhbml6YXRpb24ub3duZXJVc2VySWQgfHwgdXNlcklkID09PSBpdGVtLnJlY2lwaWVudFVzZXJJZCkpXG4gICAgLm1hcCgoaXRlbSkgPT4gKHtcbiAgICAgIGV4cGlyZXNBdDogaXRlbS5leHBpcmVzQXQsIG9yZ2FuaXphdGlvbklkLCByZWNpcGllbnRVc2VySWQ6IGl0ZW0ucmVjaXBpZW50VXNlcklkLCB0cmFuc2ZlcklkOiBpdGVtLl9rZXlcbiAgICB9KSk7XG59KTtcbiJdLCJuYW1lcyI6WyJvcmdhbml6YXRpb25BY2Nlc3NJblRyYW5zYWN0aW9uIiwib3JnYW5pemF0aW9uU3RvcmVGb3IiLCJsaXN0T3JnYW5pemF0aW9uSW52aXRhdGlvbnMiLCJjb250ZXh0Iiwib3JnYW5pemF0aW9uSWQiLCJ0cmFuc2FjdGlvbiIsInR4IiwiaW52aXRhdGlvbnMiLCJmaW5kIiwiZmlsdGVyIiwiaXRlbSIsInVzZWQiLCJyZXZva2VkIiwiZXhwaXJlc0F0IiwiRGF0ZSIsIm5vdyIsIm1hcCIsImVtYWlsIiwiaW52aXRhdGlvbklkIiwiX2tleSIsImxpc3RPcmdhbml6YXRpb25UcmFuc2ZlcnMiLCJvcmdhbml6YXRpb24iLCJ1c2VySWQiLCJ0cmFuc2ZlcnMiLCJyZXZpc2lvbiIsIm93bmVyVXNlcklkIiwicmVjaXBpZW50VXNlcklkIiwidHJhbnNmZXJJZCJdLCJtYXBwaW5ncyI6IkFBQUEsaURBQWlELEdBQ2pELDhEQUE4RCxHQUM5RCxTQUFRQSwrQkFBK0IsUUFBTyxxQkFBcUI7QUFDbkUsU0FBUUMsb0JBQW9CLFFBQU8sYUFBYTtBQXVCaEQsT0FBTyxNQUFNQyw4QkFBOEIsQ0FDekNDLFNBQ0FDLGlCQUM2Q0gscUJBQXFCRSxTQUFTRSxXQUFXLENBQUMsT0FBT0M7UUFDOUYsTUFBTU4sZ0NBQWdDTSxJQUFJSCxTQUFTQyxnQkFBZ0I7UUFDbkUsTUFBTUcsY0FBYyxNQUFNRCxHQUFHRSxJQUFJLENBQWEsMkJBQTJCO1lBQUNKO1FBQWM7UUFDeEYsT0FBT0csWUFBWUUsTUFBTSxDQUFDLENBQUNDLE9BQVMsQ0FBQ0EsS0FBS0MsSUFBSSxJQUFJLENBQUNELEtBQUtFLE9BQU8sSUFBSUYsS0FBS0csU0FBUyxHQUFHQyxLQUFLQyxHQUFHLElBQ3pGQyxHQUFHLENBQUMsQ0FBQ04sT0FBVSxDQUFBO2dCQUFDTyxPQUFPUCxLQUFLTyxLQUFLO2dCQUFFSixXQUFXSCxLQUFLRyxTQUFTO2dCQUFFSyxjQUFjUixLQUFLUyxJQUFJO2dCQUFFZjtZQUFjLENBQUE7SUFDMUcsR0FBRztBQUVILE9BQU8sTUFBTWdCLDRCQUE0QixDQUN2Q2pCLFNBQ0FDLGlCQUMyQ0gscUJBQXFCRSxTQUFTRSxXQUFXLENBQUMsT0FBT0M7UUFDNUYsTUFBTSxFQUFDZSxZQUFZLEVBQUVDLE1BQU0sRUFBQyxHQUFHLE1BQU10QixnQ0FBZ0NNLElBQUlILFNBQVNDLGdCQUFnQjtRQUNsRyxNQUFNbUIsWUFBWSxNQUFNakIsR0FBR0UsSUFBSSxDQUFXLDhCQUE4QjtZQUFDSjtRQUFjO1FBQ3ZGLE9BQU9tQixVQUFVZCxNQUFNLENBQUMsQ0FBQ0MsT0FBUyxDQUFDQSxLQUFLQyxJQUFJLElBQUlELEtBQUtHLFNBQVMsR0FBR0MsS0FBS0MsR0FBRyxNQUNwRUwsS0FBS2MsUUFBUSxLQUFLSCxhQUFhRyxRQUFRLElBQUlkLEtBQUtlLFdBQVcsS0FBS0osYUFBYUksV0FBVyxJQUN2RkgsQ0FBQUEsV0FBV0QsYUFBYUksV0FBVyxJQUFJSCxXQUFXWixLQUFLZ0IsZUFBZSxBQUFELEdBQ3hFVixHQUFHLENBQUMsQ0FBQ04sT0FBVSxDQUFBO2dCQUNkRyxXQUFXSCxLQUFLRyxTQUFTO2dCQUFFVDtnQkFBZ0JzQixpQkFBaUJoQixLQUFLZ0IsZUFBZTtnQkFBRUMsWUFBWWpCLEtBQUtTLElBQUk7WUFDekcsQ0FBQTtJQUNKLEdBQUcifQ==