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