@nlabs/reaktor 0.10.2 → 0.10.6
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/coverage/block-navigation.js +1 -1
- package/coverage/index.html +23 -23
- package/coverage/sorter.js +21 -7
- package/lib/actions/apps.d.ts +1 -0
- package/lib/actions/apps.d.ts.map +1 -0
- package/lib/actions/apps.js +218 -17
- package/lib/actions/connections.d.ts +1 -0
- package/lib/actions/connections.d.ts.map +1 -0
- package/lib/actions/connections.js +61 -6
- package/lib/actions/content.d.ts +1 -0
- package/lib/actions/content.d.ts.map +1 -0
- package/lib/actions/content.js +232 -9
- package/lib/actions/conversations.d.ts +1 -0
- package/lib/actions/conversations.d.ts.map +1 -0
- package/lib/actions/conversations.js +321 -19
- package/lib/actions/dynamodb.d.ts +1 -0
- package/lib/actions/dynamodb.d.ts.map +1 -0
- package/lib/actions/dynamodb.js +119 -2
- package/lib/actions/email.d.ts +1 -0
- package/lib/actions/email.d.ts.map +1 -0
- package/lib/actions/email.js +56 -2
- package/lib/actions/files.d.ts +1 -0
- package/lib/actions/files.d.ts.map +1 -0
- package/lib/actions/files.js +226 -5
- package/lib/actions/groups.d.ts +1 -0
- package/lib/actions/groups.d.ts.map +1 -0
- package/lib/actions/groups.js +234 -19
- package/lib/actions/images.d.ts +1 -0
- package/lib/actions/images.d.ts.map +1 -0
- package/lib/actions/images.js +688 -31
- package/lib/actions/index.d.ts +2 -0
- package/lib/actions/index.d.ts.map +1 -0
- package/lib/actions/index.js +29 -2
- package/lib/actions/ios.d.ts +1 -0
- package/lib/actions/ios.d.ts.map +1 -0
- package/lib/actions/ios.js +228 -9
- package/lib/actions/locations.d.ts +1 -0
- package/lib/actions/locations.d.ts.map +1 -0
- package/lib/actions/locations.js +111 -7
- package/lib/actions/messages.d.ts +1 -0
- package/lib/actions/messages.d.ts.map +1 -0
- package/lib/actions/messages.js +155 -21
- package/lib/actions/notifications.d.ts +1 -0
- package/lib/actions/notifications.d.ts.map +1 -0
- package/lib/actions/notifications.js +37 -2
- package/lib/actions/payments.d.ts +1 -0
- package/lib/actions/payments.d.ts.map +1 -0
- package/lib/actions/payments.js +428 -11
- package/lib/actions/posts.d.ts +1 -0
- package/lib/actions/posts.d.ts.map +1 -0
- package/lib/actions/posts.js +540 -75
- package/lib/actions/profiles.d.ts +1 -0
- package/lib/actions/profiles.d.ts.map +1 -0
- package/lib/actions/profiles.js +58 -8
- package/lib/actions/reactions.d.ts +1 -0
- package/lib/actions/reactions.d.ts.map +1 -0
- package/lib/actions/reactions.js +276 -25
- package/lib/actions/s3.d.ts +1 -0
- package/lib/actions/s3.d.ts.map +1 -0
- package/lib/actions/s3.js +102 -2
- package/lib/actions/search.d.ts +1 -0
- package/lib/actions/search.d.ts.map +1 -0
- package/lib/actions/search.js +81 -5
- package/lib/actions/sms.d.ts +1 -0
- package/lib/actions/sms.d.ts.map +1 -0
- package/lib/actions/sms.js +52 -2
- package/lib/actions/statistics.d.ts +1 -0
- package/lib/actions/statistics.d.ts.map +1 -0
- package/lib/actions/statistics.js +41 -6
- package/lib/actions/subscriptions.d.ts +1 -0
- package/lib/actions/subscriptions.d.ts.map +1 -0
- package/lib/actions/subscriptions.js +196 -6
- package/lib/actions/tags.d.ts +1 -0
- package/lib/actions/tags.d.ts.map +1 -0
- package/lib/actions/tags.js +258 -19
- package/lib/actions/users.d.ts +1 -0
- package/lib/actions/users.d.ts.map +1 -0
- package/lib/actions/users.js +781 -66
- package/lib/actions/videos.d.ts +26 -0
- package/lib/actions/videos.d.ts.map +1 -0
- package/lib/actions/videos.js +423 -0
- package/lib/actions/websockets.d.ts +1 -0
- package/lib/actions/websockets.d.ts.map +1 -0
- package/lib/actions/websockets.js +148 -14
- package/lib/adapters/arangoAdapter.d.ts +1 -0
- package/lib/adapters/arangoAdapter.d.ts.map +1 -0
- package/lib/adapters/arangoAdapter.js +70 -2
- package/lib/adapters/contentAdapter.d.ts +1 -0
- package/lib/adapters/contentAdapter.d.ts.map +1 -0
- package/lib/adapters/contentAdapter.js +108 -2
- package/lib/adapters/fileAdapter.d.ts +1 -0
- package/lib/adapters/fileAdapter.d.ts.map +1 -0
- package/lib/adapters/fileAdapter.js +119 -2
- package/lib/adapters/imageAdapter.d.ts +1 -0
- package/lib/adapters/imageAdapter.d.ts.map +1 -0
- package/lib/adapters/imageAdapter.js +112 -2
- package/lib/adapters/index.d.ts +1 -0
- package/lib/adapters/index.d.ts.map +1 -0
- package/lib/adapters/index.js +11 -2
- package/lib/adapters/messageAdapter.d.ts +1 -0
- package/lib/adapters/messageAdapter.d.ts.map +1 -0
- package/lib/adapters/messageAdapter.js +82 -2
- package/lib/adapters/postAdapter.d.ts +1 -0
- package/lib/adapters/postAdapter.d.ts.map +1 -0
- package/lib/adapters/postAdapter.js +117 -2
- package/lib/adapters/reaktorAdapter.d.ts +1 -0
- package/lib/adapters/reaktorAdapter.d.ts.map +1 -0
- package/lib/adapters/reaktorAdapter.js +59 -2
- package/lib/adapters/tagAdapter.d.ts +1 -0
- package/lib/adapters/tagAdapter.d.ts.map +1 -0
- package/lib/adapters/tagAdapter.js +99 -2
- package/lib/adapters/userAdapter.d.ts +1 -0
- package/lib/adapters/userAdapter.d.ts.map +1 -0
- package/lib/adapters/userAdapter.js +264 -2
- package/lib/config.d.ts +1 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +161 -2
- package/lib/handlers/graphqlHandler.d.ts +1 -0
- package/lib/handlers/graphqlHandler.d.ts.map +1 -0
- package/lib/handlers/graphqlHandler.js +118 -2
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +18 -2
- package/lib/lambdas/actions/websockets.d.ts +1 -0
- package/lib/lambdas/actions/websockets.d.ts.map +1 -0
- package/lib/lambdas/actions/websockets.js +89 -14
- package/lib/lambdas/authorizer.d.ts +1 -0
- package/lib/lambdas/authorizer.d.ts.map +1 -0
- package/lib/lambdas/authorizer.js +41 -2
- package/lib/lambdas/connection.d.ts +1 -0
- package/lib/lambdas/connection.d.ts.map +1 -0
- package/lib/lambdas/connection.js +85 -2
- package/lib/lambdas/utils/message.d.ts +1 -0
- package/lib/lambdas/utils/message.d.ts.map +1 -0
- package/lib/lambdas/utils/message.js +20 -2
- package/lib/lambdas/utils/websocket.d.ts +1 -0
- package/lib/lambdas/utils/websocket.d.ts.map +1 -0
- package/lib/lambdas/utils/websocket.js +78 -2
- package/lib/mocks/conversation.d.ts +1 -0
- package/lib/mocks/conversation.d.ts.map +1 -0
- package/lib/mocks/conversation.js +10 -2
- package/lib/mocks/file.d.ts +1 -0
- package/lib/mocks/file.d.ts.map +1 -0
- package/lib/mocks/file.js +13 -2
- package/lib/mocks/group.d.ts +1 -0
- package/lib/mocks/group.d.ts.map +1 -0
- package/lib/mocks/group.js +20 -2
- package/lib/mocks/image.d.ts +1 -0
- package/lib/mocks/image.d.ts.map +1 -0
- package/lib/mocks/image.js +17 -2
- package/lib/mocks/post.d.ts +1 -0
- package/lib/mocks/post.d.ts.map +1 -0
- package/lib/mocks/post.js +28 -2
- package/lib/mocks/tag.d.ts +1 -0
- package/lib/mocks/tag.d.ts.map +1 -0
- package/lib/mocks/tag.js +12 -2
- package/lib/mocks/user.d.ts +1 -0
- package/lib/mocks/user.d.ts.map +1 -0
- package/lib/mocks/user.js +61 -2
- package/lib/mocks/video.d.ts +4 -0
- package/lib/mocks/video.d.ts.map +1 -0
- package/lib/mocks/video.js +17 -0
- package/lib/mutations/content.d.ts +1 -0
- package/lib/mutations/content.d.ts.map +1 -0
- package/lib/mutations/content.js +27 -2
- package/lib/mutations/index.d.ts +1 -0
- package/lib/mutations/index.d.ts.map +1 -0
- package/lib/mutations/index.js +29 -2
- package/lib/mutations/locations.d.ts +1 -0
- package/lib/mutations/locations.d.ts.map +1 -0
- package/lib/mutations/locations.js +22 -2
- package/lib/mutations/messages.d.ts +1 -0
- package/lib/mutations/messages.d.ts.map +1 -0
- package/lib/mutations/messages.js +75 -2
- package/lib/mutations/posts.d.ts +1 -0
- package/lib/mutations/posts.d.ts.map +1 -0
- package/lib/mutations/posts.js +31 -2
- package/lib/mutations/profiles.d.ts +1 -0
- package/lib/mutations/profiles.d.ts.map +1 -0
- package/lib/mutations/profiles.js +78 -2
- package/lib/mutations/reactions.d.ts +1 -0
- package/lib/mutations/reactions.d.ts.map +1 -0
- package/lib/mutations/reactions.js +29 -2
- package/lib/mutations/statistics.d.ts +1 -0
- package/lib/mutations/statistics.d.ts.map +1 -0
- package/lib/mutations/statistics.js +17 -2
- package/lib/mutations/subscriptions.d.ts +1 -0
- package/lib/mutations/subscriptions.d.ts.map +1 -0
- package/lib/mutations/subscriptions.js +38 -2
- package/lib/mutations/tags.d.ts +1 -0
- package/lib/mutations/tags.d.ts.map +1 -0
- package/lib/mutations/tags.js +109 -2
- package/lib/mutations/users.d.ts +1 -0
- package/lib/mutations/users.d.ts.map +1 -0
- package/lib/mutations/users.js +129 -2
- package/lib/objectTypes/app.d.ts +1 -0
- package/lib/objectTypes/app.d.ts.map +1 -0
- package/lib/objectTypes/app.js +147 -2
- package/lib/objectTypes/bankAccount.d.ts +1 -0
- package/lib/objectTypes/bankAccount.d.ts.map +1 -0
- package/lib/objectTypes/bankAccount.js +54 -2
- package/lib/objectTypes/connection.d.ts +1 -0
- package/lib/objectTypes/connection.d.ts.map +1 -0
- package/lib/objectTypes/connection.js +26 -2
- package/lib/objectTypes/content.d.ts +1 -0
- package/lib/objectTypes/content.d.ts.map +1 -0
- package/lib/objectTypes/content.js +79 -2
- package/lib/objectTypes/conversation.d.ts +1 -0
- package/lib/objectTypes/conversation.d.ts.map +1 -0
- package/lib/objectTypes/conversation.js +53 -2
- package/lib/objectTypes/creditCard.d.ts +1 -0
- package/lib/objectTypes/creditCard.d.ts.map +1 -0
- package/lib/objectTypes/creditCard.js +64 -2
- package/lib/objectTypes/document.d.ts +1 -0
- package/lib/objectTypes/document.d.ts.map +1 -0
- package/lib/objectTypes/document.js +21 -2
- package/lib/objectTypes/error.d.ts +1 -0
- package/lib/objectTypes/error.d.ts.map +1 -0
- package/lib/objectTypes/error.js +24 -2
- package/lib/objectTypes/external.d.ts +1 -0
- package/lib/objectTypes/external.d.ts.map +1 -0
- package/lib/objectTypes/external.js +52 -2
- package/lib/objectTypes/file.d.ts +1 -0
- package/lib/objectTypes/file.d.ts.map +1 -0
- package/lib/objectTypes/file.js +76 -2
- package/lib/objectTypes/filter.d.ts +1 -0
- package/lib/objectTypes/filter.d.ts.map +1 -0
- package/lib/objectTypes/filter.js +21 -2
- package/lib/objectTypes/group.d.ts +1 -0
- package/lib/objectTypes/group.d.ts.map +1 -0
- package/lib/objectTypes/group.js +97 -2
- package/lib/objectTypes/iapSubscription.d.ts +1 -0
- package/lib/objectTypes/iapSubscription.d.ts.map +1 -0
- package/lib/objectTypes/iapSubscription.js +18 -2
- package/lib/objectTypes/image.d.ts +1 -0
- package/lib/objectTypes/image.d.ts.map +1 -0
- package/lib/objectTypes/image.js +105 -2
- package/lib/objectTypes/index.d.ts +1 -0
- package/lib/objectTypes/index.d.ts.map +1 -0
- package/lib/objectTypes/index.js +28 -2
- package/lib/objectTypes/location.d.ts +1 -0
- package/lib/objectTypes/location.d.ts.map +1 -0
- package/lib/objectTypes/location.js +85 -2
- package/lib/objectTypes/message.d.ts +1 -0
- package/lib/objectTypes/message.d.ts.map +1 -0
- package/lib/objectTypes/message.js +72 -2
- package/lib/objectTypes/passcode.d.ts +1 -0
- package/lib/objectTypes/passcode.d.ts.map +1 -0
- package/lib/objectTypes/passcode.js +20 -2
- package/lib/objectTypes/plan.d.ts +1 -0
- package/lib/objectTypes/plan.d.ts.map +1 -0
- package/lib/objectTypes/plan.js +71 -2
- package/lib/objectTypes/post.d.ts +1 -0
- package/lib/objectTypes/post.d.ts.map +1 -0
- package/lib/objectTypes/post.js +101 -2
- package/lib/objectTypes/profile.d.ts +1 -0
- package/lib/objectTypes/profile.d.ts.map +1 -0
- package/lib/objectTypes/profile.js +68 -2
- package/lib/objectTypes/reaction.d.ts +1 -0
- package/lib/objectTypes/reaction.d.ts.map +1 -0
- package/lib/objectTypes/reaction.js +37 -2
- package/lib/objectTypes/relation.d.ts +1 -0
- package/lib/objectTypes/relation.d.ts.map +1 -0
- package/lib/objectTypes/relation.js +27 -2
- package/lib/objectTypes/search.d.ts +1 -0
- package/lib/objectTypes/search.d.ts.map +1 -0
- package/lib/objectTypes/search.js +50 -2
- package/lib/objectTypes/statistics.d.ts +1 -0
- package/lib/objectTypes/statistics.d.ts.map +1 -0
- package/lib/objectTypes/statistics.js +17 -2
- package/lib/objectTypes/subscription.d.ts +1 -0
- package/lib/objectTypes/subscription.d.ts.map +1 -0
- package/lib/objectTypes/subscription.js +102 -2
- package/lib/objectTypes/tag.d.ts +1 -0
- package/lib/objectTypes/tag.d.ts.map +1 -0
- package/lib/objectTypes/tag.js +41 -2
- package/lib/objectTypes/user.d.ts +1 -0
- package/lib/objectTypes/user.d.ts.map +1 -0
- package/lib/objectTypes/user.js +111 -2
- package/lib/queries/content.d.ts +1 -0
- package/lib/queries/content.d.ts.map +1 -0
- package/lib/queries/content.js +50 -2
- package/lib/queries/index.d.ts +1 -0
- package/lib/queries/index.d.ts.map +1 -0
- package/lib/queries/index.js +27 -2
- package/lib/queries/locations.d.ts +1 -0
- package/lib/queries/locations.d.ts.map +1 -0
- package/lib/queries/locations.js +23 -2
- package/lib/queries/messages.d.ts +1 -0
- package/lib/queries/messages.d.ts.map +1 -0
- package/lib/queries/messages.js +35 -2
- package/lib/queries/posts.d.ts +1 -0
- package/lib/queries/posts.d.ts.map +1 -0
- package/lib/queries/posts.js +154 -2
- package/lib/queries/reactions.d.ts +1 -0
- package/lib/queries/reactions.d.ts.map +1 -0
- package/lib/queries/reactions.js +34 -2
- package/lib/queries/statistics.d.ts +1 -0
- package/lib/queries/statistics.d.ts.map +1 -0
- package/lib/queries/statistics.js +17 -2
- package/lib/queries/subscriptions.d.ts +1 -0
- package/lib/queries/subscriptions.d.ts.map +1 -0
- package/lib/queries/subscriptions.js +21 -2
- package/lib/queries/tags.d.ts +1 -0
- package/lib/queries/tags.d.ts.map +1 -0
- package/lib/queries/tags.js +56 -2
- package/lib/queries/users.d.ts +1 -0
- package/lib/queries/users.d.ts.map +1 -0
- package/lib/queries/users.js +39 -2
- package/lib/templates/email/layout.d.ts +1 -0
- package/lib/templates/email/layout.d.ts.map +1 -0
- package/lib/templates/email/layout.js +4 -3
- package/lib/templates/email/passwordForgot.d.ts +1 -0
- package/lib/templates/email/passwordForgot.d.ts.map +1 -0
- package/lib/templates/email/passwordForgot.js +4 -3
- package/lib/templates/email/passwordRecovery.d.ts +1 -0
- package/lib/templates/email/passwordRecovery.d.ts.map +1 -0
- package/lib/templates/email/passwordRecovery.js +4 -3
- package/lib/templates/email/verifyEmail.d.ts +1 -0
- package/lib/templates/email/verifyEmail.d.ts.map +1 -0
- package/lib/templates/email/verifyEmail.js +4 -3
- package/lib/templates/email/welcome.d.ts +1 -0
- package/lib/templates/email/welcome.d.ts.map +1 -0
- package/lib/templates/email/welcome.js +4 -3
- package/lib/templates/sms/passwordForgot.d.ts +1 -0
- package/lib/templates/sms/passwordForgot.d.ts.map +1 -0
- package/lib/templates/sms/passwordForgot.js +3 -2
- package/lib/templates/sms/passwordRecovery.d.ts +1 -0
- package/lib/templates/sms/passwordRecovery.d.ts.map +1 -0
- package/lib/templates/sms/passwordRecovery.js +3 -2
- package/lib/templates/sms/verifyEmail.d.ts +1 -0
- package/lib/templates/sms/verifyEmail.d.ts.map +1 -0
- package/lib/templates/sms/verifyEmail.js +3 -2
- package/lib/templates/sms/verifyPhone.d.ts +1 -0
- package/lib/templates/sms/verifyPhone.d.ts.map +1 -0
- package/lib/templates/sms/verifyPhone.js +3 -2
- package/lib/templates/sms/welcome.d.ts +1 -0
- package/lib/templates/sms/welcome.d.ts.map +1 -0
- package/lib/templates/sms/welcome.js +3 -2
- package/lib/types/apps.types.d.ts +1 -0
- package/lib/types/apps.types.d.ts.map +1 -0
- package/lib/types/apps.types.js +10 -2
- package/lib/types/arangodb.types.d.ts +2 -1
- package/lib/types/arangodb.types.d.ts.map +1 -0
- package/lib/types/arangodb.types.js +6 -1
- package/lib/types/auth.types.d.ts +1 -0
- package/lib/types/auth.types.d.ts.map +1 -0
- package/lib/types/auth.types.js +6 -1
- package/lib/types/connections.types.d.ts +1 -0
- package/lib/types/connections.types.d.ts.map +1 -0
- package/lib/types/connections.types.js +6 -1
- package/lib/types/content.types.d.ts +1 -0
- package/lib/types/content.types.d.ts.map +1 -0
- package/lib/types/content.types.js +6 -1
- package/lib/types/conversations.types.d.ts +1 -0
- package/lib/types/conversations.types.d.ts.map +1 -0
- package/lib/types/conversations.types.js +6 -1
- package/lib/types/email.types.d.ts +1 -0
- package/lib/types/email.types.d.ts.map +1 -0
- package/lib/types/email.types.js +6 -1
- package/lib/types/error.types.d.ts +1 -0
- package/lib/types/error.types.d.ts.map +1 -0
- package/lib/types/error.types.js +20 -2
- package/lib/types/files.types.d.ts +1 -0
- package/lib/types/files.types.d.ts.map +1 -0
- package/lib/types/files.types.js +6 -1
- package/lib/types/google.types.d.ts +1 -0
- package/lib/types/google.types.d.ts.map +1 -0
- package/lib/types/google.types.js +6 -1
- package/lib/types/groups.types.d.ts +1 -0
- package/lib/types/groups.types.d.ts.map +1 -0
- package/lib/types/groups.types.js +6 -1
- package/lib/types/images.types.d.ts +1 -0
- package/lib/types/images.types.d.ts.map +1 -0
- package/lib/types/images.types.js +6 -1
- package/lib/types/index.d.ts +2 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +28 -2
- package/lib/types/locations.types.d.ts +1 -0
- package/lib/types/locations.types.d.ts.map +1 -0
- package/lib/types/locations.types.js +6 -1
- package/lib/types/messages.types.d.ts +1 -0
- package/lib/types/messages.types.d.ts.map +1 -0
- package/lib/types/messages.types.js +6 -1
- package/lib/types/notifications.types.d.ts +1 -0
- package/lib/types/notifications.types.d.ts.map +1 -0
- package/lib/types/notifications.types.js +6 -1
- package/lib/types/payments.types.d.ts +1 -0
- package/lib/types/payments.types.d.ts.map +1 -0
- package/lib/types/payments.types.js +6 -1
- package/lib/types/posts.types.d.ts +1 -0
- package/lib/types/posts.types.d.ts.map +1 -0
- package/lib/types/posts.types.js +6 -1
- package/lib/types/profiles.types.d.ts +1 -0
- package/lib/types/profiles.types.d.ts.map +1 -0
- package/lib/types/profiles.types.js +3 -1
- package/lib/types/statistics.types.d.ts +1 -0
- package/lib/types/statistics.types.d.ts.map +1 -0
- package/lib/types/statistics.types.js +3 -1
- package/lib/types/tags.types.d.ts +1 -0
- package/lib/types/tags.types.d.ts.map +1 -0
- package/lib/types/tags.types.js +6 -1
- package/lib/types/users.types.d.ts +1 -0
- package/lib/types/users.types.d.ts.map +1 -0
- package/lib/types/users.types.js +6 -1
- package/lib/types/videos.types.d.ts +47 -0
- package/lib/types/videos.types.d.ts.map +1 -0
- package/lib/types/videos.types.js +6 -0
- package/lib/types/websockets.types.d.ts +1 -0
- package/lib/types/websockets.types.d.ts.map +1 -0
- package/lib/types/websockets.types.js +6 -1
- package/lib/utils/adapterUtils.d.ts +1 -0
- package/lib/utils/adapterUtils.d.ts.map +1 -0
- package/lib/utils/adapterUtils.js +23 -2
- package/lib/utils/analyticsUtils.d.ts +1 -0
- package/lib/utils/analyticsUtils.d.ts.map +1 -0
- package/lib/utils/analyticsUtils.js +45 -2
- package/lib/utils/arangodbUtils.d.ts +1 -0
- package/lib/utils/arangodbUtils.d.ts.map +1 -0
- package/lib/utils/arangodbUtils.js +128 -5
- package/lib/utils/authUtils.d.ts +1 -0
- package/lib/utils/authUtils.d.ts.map +1 -0
- package/lib/utils/authUtils.js +54 -2
- package/lib/utils/contextUtils.d.ts +1 -0
- package/lib/utils/contextUtils.d.ts.map +1 -0
- package/lib/utils/contextUtils.js +10 -2
- package/lib/utils/dbI18n.d.ts +1 -0
- package/lib/utils/dbI18n.d.ts.map +1 -0
- package/lib/utils/dbI18n.example.d.ts +1 -0
- package/lib/utils/dbI18n.example.d.ts.map +1 -0
- package/lib/utils/dbI18n.example.js +92 -5
- package/lib/utils/dbI18n.js +28 -2
- package/lib/utils/googleTranslate.d.ts +1 -0
- package/lib/utils/googleTranslate.d.ts.map +1 -0
- package/lib/utils/googleTranslate.js +70 -2
- package/lib/utils/graphqlUtils.d.ts +1 -0
- package/lib/utils/graphqlUtils.d.ts.map +1 -0
- package/lib/utils/graphqlUtils.js +11 -2
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.d.ts.map +1 -0
- package/lib/utils/index.js +19 -2
- package/lib/utils/languageDetection.d.ts +1 -0
- package/lib/utils/languageDetection.d.ts.map +1 -0
- package/lib/utils/languageDetection.js +120 -2
- package/lib/utils/localeUtils.d.ts +1 -0
- package/lib/utils/localeUtils.d.ts.map +1 -0
- package/lib/utils/localeUtils.example.d.ts +1 -0
- package/lib/utils/localeUtils.example.d.ts.map +1 -0
- package/lib/utils/localeUtils.example.js +124 -2
- package/lib/utils/localeUtils.js +71 -2
- package/lib/utils/middlewareUtils.d.ts +1 -0
- package/lib/utils/middlewareUtils.d.ts.map +1 -0
- package/lib/utils/middlewareUtils.js +10 -2
- package/lib/utils/sessionUtils.d.ts +1 -0
- package/lib/utils/sessionUtils.d.ts.map +1 -0
- package/lib/utils/sessionUtils.js +26 -2
- package/lib/utils/stripeUtils.d.ts +2 -1
- package/lib/utils/stripeUtils.d.ts.map +1 -0
- package/lib/utils/stripeUtils.js +12 -2
- package/lib/utils/templateUtils.d.ts +1 -0
- package/lib/utils/templateUtils.d.ts.map +1 -0
- package/lib/utils/templateUtils.js +11 -2
- package/lib/utils/testUtils.d.ts +1 -0
- package/lib/utils/testUtils.d.ts.map +1 -0
- package/lib/utils/testUtils.js +292 -2
- package/lib/utils/translationQueue.d.ts +1 -0
- package/lib/utils/translationQueue.d.ts.map +1 -0
- package/lib/utils/translationQueue.example.d.ts +1 -0
- package/lib/utils/translationQueue.example.d.ts.map +1 -0
- package/lib/utils/translationQueue.example.js +340 -2
- package/lib/utils/translationQueue.js +113 -2
- package/package.json +47 -29
package/lib/actions/users.js
CHANGED
|
@@ -1,87 +1,802 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2019-Present, Nitrogen Labs, Inc.
|
|
3
|
+
* Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
|
|
4
|
+
*/ import { parseNum } from '@nlabs/utils/parsers/numbers';
|
|
5
|
+
import { createHash, createPassword, parseArangoId, parseChar, parseEmail, parsePassword, parsePhone, parseUsername } from '@nlabs/utils/parsers/strings';
|
|
6
|
+
import { aql } from 'arangojs';
|
|
7
|
+
import { DateTime } from 'luxon';
|
|
8
|
+
import Stripe from 'stripe';
|
|
9
|
+
import { parseUser } from '../adapters/userAdapter.js';
|
|
10
|
+
import { Config } from '../config.js';
|
|
11
|
+
import { ErrorTypes } from '../types/error.types.js';
|
|
12
|
+
import { logError, logException } from '../utils/analyticsUtils.js';
|
|
13
|
+
import { getDocId, getLimit, selectReactionCountByType, useDb } from '../utils/arangodbUtils.js';
|
|
14
|
+
import { detectLanguage } from '../utils/languageDetection.js';
|
|
15
|
+
import { getSession, setSession } from '../utils/sessionUtils.js';
|
|
16
|
+
import { sendEmail } from './email.js';
|
|
17
|
+
import { sendSms } from './sms.js';
|
|
18
|
+
const eventCategory = 'users';
|
|
19
|
+
const STRIPE_API_VERSION = '2025-12-15.clover';
|
|
20
|
+
export var UserAccess = /*#__PURE__*/ function(UserAccess) {
|
|
21
|
+
UserAccess[UserAccess["DEACTIVATED"] = 0] = "DEACTIVATED";
|
|
22
|
+
UserAccess[UserAccess["ACTIVE"] = 1] = "ACTIVE";
|
|
23
|
+
UserAccess[UserAccess["PREMIUM"] = 2] = "PREMIUM";
|
|
24
|
+
UserAccess[UserAccess["CONTENT_ADMIN"] = 3] = "CONTENT_ADMIN";
|
|
25
|
+
UserAccess[UserAccess["ADMIN"] = 4] = "ADMIN";
|
|
26
|
+
return UserAccess;
|
|
27
|
+
}({});
|
|
28
|
+
export const createToken = (userId, username = '', userAccess = 0, expiresInMinutes = 15)=>{
|
|
29
|
+
const now = DateTime.local();
|
|
30
|
+
const sessionExpires = now.plus({
|
|
31
|
+
minutes: expiresInMinutes
|
|
32
|
+
});
|
|
33
|
+
const iat = Math.floor(now.toSeconds());
|
|
34
|
+
const exp = Math.floor(sessionExpires.toSeconds());
|
|
35
|
+
const token = setSession({
|
|
36
|
+
exp,
|
|
37
|
+
iat,
|
|
38
|
+
userAccess,
|
|
39
|
+
userId,
|
|
40
|
+
username
|
|
41
|
+
});
|
|
42
|
+
return {
|
|
43
|
+
expires: sessionExpires.toMillis(),
|
|
44
|
+
issued: now.toMillis(),
|
|
45
|
+
token,
|
|
46
|
+
userId,
|
|
47
|
+
username
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
export const getUserOptional = (fields = [])=>fields.reduce((selects, field)=>{
|
|
51
|
+
if (field.includes('Count')) {
|
|
52
|
+
return selectReactionCountByType('users', 'u', field, selects);
|
|
53
|
+
}
|
|
54
|
+
return selects;
|
|
55
|
+
}, {
|
|
56
|
+
objects: [],
|
|
57
|
+
queries: []
|
|
58
|
+
});
|
|
59
|
+
export const parseUserOptions = (options = {})=>{
|
|
60
|
+
const { from = 0, to = 30 } = options;
|
|
61
|
+
const limit = getLimit(from, to);
|
|
62
|
+
return {
|
|
63
|
+
...options,
|
|
64
|
+
limit
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
export const addUser = async (context, user)=>{
|
|
68
|
+
const action = 'addUser';
|
|
69
|
+
const { databaseName, languageContext } = context;
|
|
70
|
+
const { confirm: _confirm, ...newUser } = user;
|
|
71
|
+
const { email, password, phone, username, userId, _key, _id, ...insertUser } = parseUser(newUser);
|
|
72
|
+
const hasPassword = !!password;
|
|
73
|
+
const hasUsername = !!username || !!phone || !!email;
|
|
74
|
+
if (!hasPassword || !hasUsername) {
|
|
75
|
+
logException({
|
|
76
|
+
action,
|
|
77
|
+
category: eventCategory,
|
|
78
|
+
params: {
|
|
79
|
+
username
|
|
80
|
+
},
|
|
81
|
+
value: ErrorTypes.INVALID_ARGUMENTS
|
|
82
|
+
}, context);
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
const hashId = username || phone || email;
|
|
86
|
+
const salt = createHash(`${hashId}${password}`, '');
|
|
87
|
+
const encryptedPassword = createPassword(password, salt);
|
|
88
|
+
const filters = [];
|
|
89
|
+
if (username) {
|
|
90
|
+
filters.push(`u.username == "${username}"`);
|
|
91
|
+
}
|
|
92
|
+
if (email) {
|
|
93
|
+
filters.push(`u.email == "${email}"`);
|
|
94
|
+
}
|
|
95
|
+
if (phone) {
|
|
96
|
+
filters.push(`u.phone == ${phone}`);
|
|
97
|
+
}
|
|
98
|
+
const checkQuery = `FOR u IN users
|
|
99
|
+
FILTER ${filters.join(' || ')}
|
|
3
100
|
LIMIT 1
|
|
4
|
-
RETURN u`;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
101
|
+
RETURN u`;
|
|
102
|
+
try {
|
|
103
|
+
const existingUsers = await useDb(databaseName).query(checkQuery).then((cursor)=>cursor.all());
|
|
104
|
+
if (existingUsers.length) {
|
|
105
|
+
throw logException({
|
|
106
|
+
action,
|
|
107
|
+
category: eventCategory,
|
|
108
|
+
params: {
|
|
109
|
+
email,
|
|
110
|
+
phone,
|
|
111
|
+
username
|
|
112
|
+
},
|
|
113
|
+
value: ErrorTypes.EXISTING_ITEM
|
|
114
|
+
}, context);
|
|
115
|
+
}
|
|
116
|
+
} catch (error) {
|
|
117
|
+
throw logError({
|
|
118
|
+
action,
|
|
119
|
+
category: eventCategory,
|
|
120
|
+
params: {
|
|
121
|
+
email,
|
|
122
|
+
phone,
|
|
123
|
+
username
|
|
124
|
+
},
|
|
125
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
126
|
+
}, error, context);
|
|
127
|
+
}
|
|
128
|
+
const phoneCountryCode = phone?.replace(/\D/g, '').substring(0, 3);
|
|
129
|
+
const locale = detectLanguage({
|
|
130
|
+
...languageContext,
|
|
131
|
+
phoneCountryCode: phoneCountryCode || '',
|
|
132
|
+
userPreference: insertUser.locale || 'en'
|
|
133
|
+
});
|
|
134
|
+
const verifiedEmailCode = Math.floor(100000 + Math.random() * 900000);
|
|
135
|
+
const verifiedSmsCode = Math.floor(100000 + Math.random() * 900000);
|
|
136
|
+
const insert = {
|
|
137
|
+
...insertUser,
|
|
138
|
+
_key: createHash(username),
|
|
139
|
+
added: Date.now(),
|
|
140
|
+
email,
|
|
141
|
+
locale,
|
|
142
|
+
modified: Date.now(),
|
|
143
|
+
password: encryptedPassword,
|
|
144
|
+
phone,
|
|
145
|
+
salt,
|
|
146
|
+
userAccess: 1,
|
|
147
|
+
username,
|
|
148
|
+
verifiedEmail: false,
|
|
149
|
+
verifiedEmailCode,
|
|
150
|
+
verifiedPhone: false,
|
|
151
|
+
verifiedSmsCode
|
|
152
|
+
};
|
|
153
|
+
const insertQuery = aql`INSERT ${insert} IN users RETURN NEW`;
|
|
154
|
+
return await useDb(databaseName).query(insertQuery).then((cursor)=>cursor.next()).catch((error)=>{
|
|
155
|
+
throw logError({
|
|
156
|
+
action,
|
|
157
|
+
category: eventCategory,
|
|
158
|
+
params: {
|
|
159
|
+
username
|
|
160
|
+
},
|
|
161
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
162
|
+
}, error, context);
|
|
163
|
+
});
|
|
164
|
+
};
|
|
165
|
+
export const updateUser = async (context, user)=>{
|
|
166
|
+
const action = 'updateUser';
|
|
167
|
+
const { databaseName } = context;
|
|
168
|
+
const updatedUser = parseUser(user);
|
|
169
|
+
const { _key, _id, tags = [], ...update } = updatedUser;
|
|
170
|
+
const { id } = updatedUser;
|
|
171
|
+
const userQuery = aql`LET u = DOCUMENT(${id})
|
|
172
|
+
UPDATE u WITH ${update} IN users
|
|
173
|
+
RETURN NEW`;
|
|
174
|
+
try {
|
|
175
|
+
const database = useDb(databaseName);
|
|
176
|
+
const updatedUser = await database.query(userQuery).then((cursor)=>cursor.next());
|
|
177
|
+
const tagCollection = database.collection('isTagged');
|
|
178
|
+
await Promise.all(tags.map(({ id: tagDocId, name })=>{
|
|
179
|
+
const tagQuery = aql`FOR it IN isTagged
|
|
180
|
+
FILTER it._from == ${tagDocId} && it._to == ${id} && it.name == ${name}
|
|
8
181
|
LIMIT 1
|
|
9
|
-
RETURN it`;
|
|
10
|
-
|
|
182
|
+
RETURN it`;
|
|
183
|
+
return database.query(tagQuery).then((cursor)=>cursor.next()).then((tagEdge)=>{
|
|
184
|
+
if (!!tagEdge) {
|
|
185
|
+
return tagEdge;
|
|
186
|
+
}
|
|
187
|
+
const edge = {
|
|
188
|
+
_from: tagDocId,
|
|
189
|
+
_key: createHash(`isTagged-${tagDocId}-${id}`),
|
|
190
|
+
_to: id,
|
|
191
|
+
added: Date.now(),
|
|
192
|
+
name
|
|
193
|
+
};
|
|
194
|
+
return tagCollection.save(edge, {
|
|
195
|
+
returnNew: true
|
|
196
|
+
}).then(()=>edge);
|
|
197
|
+
});
|
|
198
|
+
}));
|
|
199
|
+
return updatedUser;
|
|
200
|
+
} catch (error) {
|
|
201
|
+
throw logError({
|
|
202
|
+
action,
|
|
203
|
+
category: eventCategory,
|
|
204
|
+
params: {
|
|
205
|
+
user
|
|
206
|
+
},
|
|
207
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
208
|
+
}, error, context);
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
export const forgotPassword = async (context, { email, phone, username })=>{
|
|
212
|
+
const action = 'forgotPassword';
|
|
213
|
+
const { databaseName } = context;
|
|
214
|
+
const aqlQuery = aql`FOR u IN users
|
|
215
|
+
FILTER u.email == ${email} || u.phone == ${phone} || u.username == ${username}
|
|
11
216
|
LIMIT 1
|
|
12
|
-
RETURN u`;
|
|
13
|
-
|
|
217
|
+
RETURN u`;
|
|
218
|
+
try {
|
|
219
|
+
return await useDb(databaseName).query(aqlQuery).then(async (cursor)=>{
|
|
220
|
+
const user = cursor.next();
|
|
221
|
+
if (user) {
|
|
222
|
+
const { email, phone, verifiedEmail, verifiedPhone } = user;
|
|
223
|
+
const codeExpires = 1000 * 60 * 15; // 15 minutes
|
|
224
|
+
const code = Math.floor(100000 + Math.random() * 900000);
|
|
225
|
+
const userDocId = getDocId('users', user);
|
|
226
|
+
let update;
|
|
227
|
+
if (email && verifiedEmail) {
|
|
228
|
+
sendEmail({
|
|
229
|
+
context,
|
|
230
|
+
text: `Your code is ${code}`
|
|
231
|
+
});
|
|
232
|
+
update = {
|
|
233
|
+
verifiedEmailCode: code,
|
|
234
|
+
verifiedEmailExpires: codeExpires
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
if (phone && verifiedPhone) {
|
|
238
|
+
sendSms({
|
|
239
|
+
context,
|
|
240
|
+
text: `Your code is ${code}`
|
|
241
|
+
});
|
|
242
|
+
update = {
|
|
243
|
+
verifiedPhoneExpires: codeExpires,
|
|
244
|
+
verifiedSmsCode: code
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
if (update.verifiedEmailCode || update.verifiedSmsCode) {
|
|
248
|
+
const updateQuery = aql`UPDATE ${userDocId} WITH ${update} IN users`;
|
|
249
|
+
await useDb(databaseName).query(updateQuery);
|
|
250
|
+
return true;
|
|
251
|
+
}
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
return false;
|
|
255
|
+
});
|
|
256
|
+
} catch (error) {
|
|
257
|
+
logError({
|
|
258
|
+
action,
|
|
259
|
+
category: eventCategory,
|
|
260
|
+
params: {
|
|
261
|
+
email,
|
|
262
|
+
phone,
|
|
263
|
+
username
|
|
264
|
+
},
|
|
265
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
266
|
+
}, error, context);
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
export const resetPassword = async (context, { code, password, type, username })=>{
|
|
271
|
+
const action = 'resetPassword';
|
|
272
|
+
const { databaseName } = context;
|
|
273
|
+
const formatPassword = parsePassword(password);
|
|
274
|
+
const aqlQuery = aql`FOR u IN users
|
|
275
|
+
FILTER u.username == ${username}
|
|
14
276
|
LIMIT 1
|
|
15
|
-
RETURN u`;
|
|
16
|
-
|
|
277
|
+
RETURN u`;
|
|
278
|
+
try {
|
|
279
|
+
return await useDb(databaseName).query(aqlQuery).then(async (cursor)=>{
|
|
280
|
+
const user = cursor.next();
|
|
281
|
+
if (user) {
|
|
282
|
+
const { _id: userDocId, salt, verifiedEmailCode, verifiedEmailExpires = 0, verifiedSmsCode, verifiedPhoneExpires = 0 } = user;
|
|
283
|
+
const now = Date.now();
|
|
284
|
+
let update;
|
|
285
|
+
switch(type){
|
|
286
|
+
case 'email':
|
|
287
|
+
if (code === verifiedEmailCode && verifiedEmailExpires > now) {
|
|
288
|
+
const password = createPassword(formatPassword, salt);
|
|
289
|
+
update = {
|
|
290
|
+
password
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
break;
|
|
294
|
+
case 'phone':
|
|
295
|
+
if (code === verifiedSmsCode && verifiedPhoneExpires > now) {
|
|
296
|
+
const password = createPassword(formatPassword, salt);
|
|
297
|
+
update = {
|
|
298
|
+
password
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
break;
|
|
302
|
+
default:
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
if (update) {
|
|
306
|
+
const updateQuery = aql`UPDATE ${userDocId} WITH ${update} IN users`;
|
|
307
|
+
await useDb(databaseName).query(updateQuery);
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return false;
|
|
312
|
+
});
|
|
313
|
+
} catch (error) {
|
|
314
|
+
logError({
|
|
315
|
+
action,
|
|
316
|
+
category: eventCategory,
|
|
317
|
+
params: {
|
|
318
|
+
username
|
|
319
|
+
},
|
|
320
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
321
|
+
}, error, context);
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
export const confirmCode = async (context, { code, type, value })=>{
|
|
326
|
+
const action = 'confirmCode';
|
|
327
|
+
const { databaseName } = context;
|
|
328
|
+
const isSms = type === 'sms';
|
|
329
|
+
const formattedValue = isSms ? parsePhone(value) : parseEmail(value);
|
|
330
|
+
const filterByType = isSms ? `FILTER u.phone == "${formattedValue}" && u.verifiedSmsCode == ${code}` : `FILTER u.email == "${formattedValue}" && u.verifiedEmailCode == ${code}`;
|
|
331
|
+
const aqlQuery = `FOR u IN users
|
|
332
|
+
${filterByType}
|
|
17
333
|
LIMIT 1
|
|
18
|
-
RETURN u`;
|
|
334
|
+
RETURN u`;
|
|
335
|
+
try {
|
|
336
|
+
return await useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.next()).then((user)=>{
|
|
337
|
+
if (user) {
|
|
338
|
+
const updatedUser = isSms ? {
|
|
339
|
+
verifiedPhone: true,
|
|
340
|
+
verifiedSmsCode: 0
|
|
341
|
+
} : {
|
|
342
|
+
verifiedEmail: true,
|
|
343
|
+
verifiedEmailCode: 0
|
|
344
|
+
};
|
|
345
|
+
const aqlQuery = aql`UPDATE ${user._key} WITH ${updatedUser} IN users`;
|
|
346
|
+
return useDb(databaseName).query(aqlQuery).then(()=>true).catch((error)=>{
|
|
347
|
+
logError({
|
|
348
|
+
action,
|
|
349
|
+
category: eventCategory,
|
|
350
|
+
params: {
|
|
351
|
+
code,
|
|
352
|
+
type,
|
|
353
|
+
value: formattedValue
|
|
354
|
+
},
|
|
355
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
356
|
+
}, error, context);
|
|
357
|
+
return false;
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
return false;
|
|
361
|
+
});
|
|
362
|
+
} catch (error) {
|
|
363
|
+
logError({
|
|
364
|
+
action,
|
|
365
|
+
category: eventCategory,
|
|
366
|
+
params: {
|
|
367
|
+
code,
|
|
368
|
+
type,
|
|
369
|
+
value: formattedValue
|
|
370
|
+
},
|
|
371
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
372
|
+
}, error, context);
|
|
373
|
+
return false;
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
export const deleteUser = (context, user)=>{
|
|
377
|
+
const action = 'deleteUser';
|
|
378
|
+
const { databaseName } = context;
|
|
379
|
+
const { id } = parseUser(user);
|
|
380
|
+
const aqlQuery = aql`LET u = DOCUMENT(${id})
|
|
19
381
|
REMOVE u IN users
|
|
20
|
-
RETURN OLD
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
382
|
+
RETURN OLD`;
|
|
383
|
+
const stripeClient = new Stripe(Config.get('stripe.token'), {
|
|
384
|
+
apiVersion: STRIPE_API_VERSION,
|
|
385
|
+
typescript: true
|
|
386
|
+
});
|
|
387
|
+
return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.next()).then((deletedUser)=>stripeClient.customers.del(deletedUser?.stripeCustomerId).then(()=>stripeClient.accounts.del(deletedUser?.stripeAccountId)).then(()=>deletedUser)).catch((error)=>logError({
|
|
388
|
+
action,
|
|
389
|
+
category: eventCategory,
|
|
390
|
+
params: {
|
|
391
|
+
id
|
|
392
|
+
},
|
|
393
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
394
|
+
}, error, context));
|
|
395
|
+
};
|
|
396
|
+
export const deactivateUser = (context, user)=>{
|
|
397
|
+
const action = 'delete';
|
|
398
|
+
const { databaseName } = context;
|
|
399
|
+
const { id } = parseUser(user);
|
|
400
|
+
const updated = {
|
|
401
|
+
userAccess: 0
|
|
402
|
+
};
|
|
403
|
+
const aqlQuery = aql`UPDATE ${id} WITH ${updated} IN users LIMIT 1 RETURN NEW`;
|
|
404
|
+
return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.next()).catch((error)=>{
|
|
405
|
+
throw logError({
|
|
406
|
+
action,
|
|
407
|
+
category: eventCategory,
|
|
408
|
+
params: {
|
|
409
|
+
id
|
|
410
|
+
},
|
|
411
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
412
|
+
}, error, context);
|
|
413
|
+
});
|
|
414
|
+
};
|
|
415
|
+
export const getDisplayName = (user)=>{
|
|
416
|
+
const { first, last, name = '', username = '' } = user;
|
|
417
|
+
const fullname = [
|
|
418
|
+
first,
|
|
419
|
+
last
|
|
420
|
+
].join(' ').trim();
|
|
421
|
+
if (name) {
|
|
422
|
+
return name;
|
|
423
|
+
} else if (fullname !== '') {
|
|
424
|
+
return fullname;
|
|
425
|
+
} else if (username) {
|
|
426
|
+
return username;
|
|
427
|
+
}
|
|
428
|
+
return 'Unknown';
|
|
429
|
+
};
|
|
430
|
+
export const getSessionUser = (context)=>{
|
|
431
|
+
const action = 'getSessionUser';
|
|
432
|
+
const { databaseName, fields, session: { userId: sessionId, username } = {} } = context;
|
|
433
|
+
const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
|
|
434
|
+
const formatSessionId = parseArangoId(`users/${sessionId}`);
|
|
435
|
+
const aqlQuery = `LET u = DOCUMENT("${formatSessionId}")
|
|
436
|
+
${selectQueries.join('\n')}
|
|
437
|
+
RETURN MERGE(u, {${selectObjects.join(', ')}})`;
|
|
438
|
+
return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.next()).catch((error)=>{
|
|
439
|
+
throw logError({
|
|
440
|
+
action,
|
|
441
|
+
category: eventCategory,
|
|
442
|
+
params: {
|
|
443
|
+
userId: sessionId,
|
|
444
|
+
username
|
|
445
|
+
},
|
|
446
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
447
|
+
}, error, context);
|
|
448
|
+
});
|
|
449
|
+
};
|
|
450
|
+
export const getUser = (context, user)=>{
|
|
451
|
+
const action = 'getUser';
|
|
452
|
+
const { email, id, phone, userId, username } = parseUser(user);
|
|
453
|
+
const { databaseName, fields } = context;
|
|
454
|
+
const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
|
|
455
|
+
let aqlQuery = '';
|
|
456
|
+
if (id) {
|
|
457
|
+
aqlQuery = `LET u = DOCUMENT("${id}")
|
|
458
|
+
${selectQueries.join('\n')}
|
|
26
459
|
FILTER u.userAccess > 0
|
|
27
|
-
RETURN MERGE(u, {${
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
`
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
${
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
FILTER
|
|
41
|
-
${
|
|
42
|
-
|
|
43
|
-
|
|
460
|
+
RETURN MERGE(u, {${selectObjects.join(', ')}})`;
|
|
461
|
+
} else if (username) {
|
|
462
|
+
aqlQuery = `FOR u IN users
|
|
463
|
+
FILTER u.username == "${username}"
|
|
464
|
+
${selectQueries.join('\n')}
|
|
465
|
+
RETURN MERGE(u, {${selectObjects.join(', ')}})`;
|
|
466
|
+
} else if (email) {
|
|
467
|
+
aqlQuery = `FOR u IN users
|
|
468
|
+
FILTER u.email == "${email}"
|
|
469
|
+
${selectQueries.join('\n')}
|
|
470
|
+
RETURN MERGE(u, {${selectObjects.join(', ')}})`;
|
|
471
|
+
} else if (phone) {
|
|
472
|
+
aqlQuery = `FOR u IN users
|
|
473
|
+
FILTER u.phone == "${phone}"
|
|
474
|
+
${selectQueries.join('\n')}
|
|
475
|
+
RETURN MERGE(u, {${selectObjects.join(', ')}})`;
|
|
476
|
+
}
|
|
477
|
+
return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.next()).then((user)=>user).catch((error)=>logError({
|
|
478
|
+
action,
|
|
479
|
+
category: eventCategory,
|
|
480
|
+
params: {
|
|
481
|
+
id,
|
|
482
|
+
userId,
|
|
483
|
+
username
|
|
484
|
+
},
|
|
485
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
486
|
+
}, error, context));
|
|
487
|
+
};
|
|
488
|
+
export const getUsers = (context, options)=>{
|
|
489
|
+
const action = 'getUserList';
|
|
490
|
+
const { databaseName, fields } = context;
|
|
491
|
+
const { limit, username } = parseUserOptions(options);
|
|
492
|
+
const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
|
|
493
|
+
const filterBy = [
|
|
494
|
+
'u.userAccess > 0'
|
|
495
|
+
];
|
|
496
|
+
if (username) {
|
|
497
|
+
filterBy.push(`CONTAINS(u.username, "${parseUsername(username)}")`);
|
|
498
|
+
}
|
|
499
|
+
const aqlQuery = `FOR u IN users
|
|
500
|
+
FILTER ${filterBy.join(' && ')}
|
|
501
|
+
${selectQueries.join('\n')}
|
|
502
|
+
${limit.aql}
|
|
44
503
|
SORT u.username
|
|
45
|
-
RETURN MERGE(u, {${
|
|
504
|
+
RETURN MERGE(u, {${selectObjects.join(', ')}})`;
|
|
505
|
+
return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.all()).catch((error)=>{
|
|
506
|
+
logError({
|
|
507
|
+
action,
|
|
508
|
+
category: eventCategory,
|
|
509
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
510
|
+
}, error, context);
|
|
511
|
+
return [];
|
|
512
|
+
});
|
|
513
|
+
};
|
|
514
|
+
export const getUsersByReactions = (context, { reactions = [], username }, options)=>{
|
|
515
|
+
const action = 'getUsersByReactions';
|
|
516
|
+
const { databaseName, fields, session: { userId: sessionId } = {} } = context;
|
|
517
|
+
const formatReactions = reactions.map((reactionName)=>parseChar(reactionName, 32).toLowerCase());
|
|
518
|
+
const { limit } = parseUserOptions(options);
|
|
519
|
+
const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
|
|
520
|
+
const formatSessionId = `users/${sessionId}`;
|
|
521
|
+
const formatUsername = parseUsername(username);
|
|
522
|
+
const filterBy = [
|
|
523
|
+
'u.userAccess > 0',
|
|
524
|
+
`POSITION(${JSON.stringify(formatReactions)}, LOWER(r.name))`
|
|
525
|
+
];
|
|
526
|
+
if (username) {
|
|
527
|
+
filterBy.push(`CONTAINS(u.username, "${formatUsername}")`);
|
|
528
|
+
}
|
|
529
|
+
const aqlQuery = `FOR u, r IN OUTBOUND "${formatSessionId}" hasReaction
|
|
46
530
|
OPTIONS {vertexCollections: "users"}
|
|
47
|
-
${
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
${
|
|
51
|
-
|
|
52
|
-
|
|
531
|
+
${selectQueries.join('\n')}
|
|
532
|
+
FILTER ${filterBy.join(' && ')}
|
|
533
|
+
${limit.aql}
|
|
534
|
+
RETURN MERGE(u, {${selectObjects.join(', ')}})`;
|
|
535
|
+
return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.all()).catch((error)=>{
|
|
536
|
+
logError({
|
|
537
|
+
action,
|
|
538
|
+
category: eventCategory,
|
|
539
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
540
|
+
}, error, context);
|
|
541
|
+
return [];
|
|
542
|
+
});
|
|
543
|
+
};
|
|
544
|
+
export const getUsersByTags = (context, { tags, username }, options)=>{
|
|
545
|
+
const action = 'getUsersByTags';
|
|
546
|
+
const { databaseName, fields, session: { userId: sessionId } = {} } = context;
|
|
547
|
+
const formatTags = tags?.reduce((list, tagName)=>{
|
|
548
|
+
if (tagName) {
|
|
549
|
+
list.push(parseChar(tagName, 32).toLowerCase());
|
|
550
|
+
}
|
|
551
|
+
return list;
|
|
552
|
+
}, []);
|
|
553
|
+
const { limit } = parseUserOptions(options);
|
|
554
|
+
const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
|
|
555
|
+
const formatUsername = parseUsername(username);
|
|
556
|
+
const filterBy = [
|
|
557
|
+
`u._key != "${sessionId}"`,
|
|
558
|
+
'u.userAccess > 0'
|
|
559
|
+
];
|
|
560
|
+
if (username) {
|
|
561
|
+
filterBy.push(`CONTAINS(u.username, "${formatUsername}")`);
|
|
562
|
+
}
|
|
563
|
+
const aqlQuery = `FOR t IN tags
|
|
564
|
+
FILTER POSITION(${JSON.stringify(formatTags)}, LOWER(t.name))
|
|
53
565
|
FOR u, it IN OUTBOUND t isTagged
|
|
54
566
|
OPTIONS {bfs: true, uniqueVertices: "global", vertexCollections: "users"}
|
|
55
|
-
${
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
${
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
567
|
+
${selectQueries.join('\n')}
|
|
568
|
+
FILTER ${filterBy.join(' && ')}
|
|
569
|
+
${limit.aql}
|
|
570
|
+
RETURN DISTINCT MERGE(u, {${selectObjects.join(', ')}})`;
|
|
571
|
+
return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.all()).catch((error)=>{
|
|
572
|
+
logError({
|
|
573
|
+
action,
|
|
574
|
+
category: eventCategory,
|
|
575
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
576
|
+
}, error, context);
|
|
577
|
+
return [];
|
|
578
|
+
});
|
|
579
|
+
};
|
|
580
|
+
export const getUsersByLatest = (context, { username }, options)=>{
|
|
581
|
+
const action = 'getUsersByLatest';
|
|
582
|
+
const { databaseName, fields, session: { userId } = {} } = context;
|
|
583
|
+
const { limit } = parseUserOptions(options);
|
|
584
|
+
const filter = [
|
|
585
|
+
'u._id != session._id',
|
|
586
|
+
'u.userAccess > 0'
|
|
587
|
+
];
|
|
588
|
+
const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
|
|
589
|
+
if (username) {
|
|
590
|
+
filter.push(`CONTAINS(u.username, "${parseUsername(username)}")`);
|
|
591
|
+
}
|
|
592
|
+
// Get data from database
|
|
593
|
+
const aqlQuery = `FOR u IN users
|
|
594
|
+
LET session = DOCUMENT("users/${userId}")
|
|
595
|
+
FILTER ${filter.join(' && ')}
|
|
596
|
+
${selectQueries.join('\n')}
|
|
64
597
|
LET distance = DISTANCE(u.latitude || 0, u.longitude || 0, session.latitude || 0, session.longitude || 0)
|
|
65
|
-
${
|
|
598
|
+
${limit.aql}
|
|
66
599
|
SORT distance ASC, u.added DESC
|
|
67
|
-
RETURN MERGE(u, {${
|
|
68
|
-
|
|
600
|
+
RETURN MERGE(u, {${selectObjects.join(', ')}})`;
|
|
601
|
+
return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.all()).catch((error)=>{
|
|
602
|
+
logError({
|
|
603
|
+
action,
|
|
604
|
+
category: eventCategory,
|
|
605
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
606
|
+
}, error, context);
|
|
607
|
+
return [];
|
|
608
|
+
});
|
|
609
|
+
};
|
|
610
|
+
export const getUsersByConnection = (context, { userId }, options)=>{
|
|
611
|
+
const action = 'getUsersByConnection';
|
|
612
|
+
const { databaseName, fields } = context;
|
|
613
|
+
const { limit, username } = parseUserOptions(options);
|
|
614
|
+
const { objects: selectObjects, queries: selectQueries } = getUserOptional(fields);
|
|
615
|
+
const formatUserId = parseArangoId(`users/${userId}`);
|
|
616
|
+
const filterBy = [
|
|
617
|
+
'u.userAccess > 0'
|
|
618
|
+
];
|
|
619
|
+
if (username) {
|
|
620
|
+
filterBy.push(`CONTAINS(u.username, "${parseUsername(username)}")`);
|
|
621
|
+
}
|
|
622
|
+
const aqlQuery = `FOR cu IN users
|
|
623
|
+
LET session = DOCUMENT("${formatUserId}")
|
|
69
624
|
FOR u, connection IN OUTBOUND cu hasConnection
|
|
70
625
|
OPTIONS {bfs: true, uniqueVertices: "global", vertexCollections: "users"}
|
|
71
|
-
${
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
${
|
|
75
|
-
|
|
76
|
-
|
|
626
|
+
${selectQueries.join('\n')}
|
|
627
|
+
FILTER ${filterBy.join(' && ')}
|
|
628
|
+
${limit.aql}
|
|
629
|
+
RETURN DISTINCT MERGE(u, {${selectObjects.join(', ')}})`;
|
|
630
|
+
return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.all()).catch((error)=>{
|
|
631
|
+
logError({
|
|
632
|
+
action,
|
|
633
|
+
category: eventCategory,
|
|
634
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
635
|
+
}, error, context);
|
|
636
|
+
return [];
|
|
637
|
+
});
|
|
638
|
+
};
|
|
639
|
+
export const refreshSession = ({ expires, token })=>{
|
|
640
|
+
try {
|
|
641
|
+
const { userId, username, userAccess } = getSession(token);
|
|
642
|
+
return createToken(userId, username, userAccess, expires);
|
|
643
|
+
} catch (error) {
|
|
644
|
+
throw error; // Re-throw the error from getSession
|
|
645
|
+
}
|
|
646
|
+
};
|
|
647
|
+
export const signIn = async (context, args)=>{
|
|
648
|
+
const action = 'signIn';
|
|
649
|
+
const { databaseName } = context;
|
|
650
|
+
const { email, expires, password, phone, username } = args;
|
|
651
|
+
const formatEmail = parseEmail(email);
|
|
652
|
+
const formatUsername = parseUsername(username);
|
|
653
|
+
const formatPassword = parsePassword(password);
|
|
654
|
+
const formatPhone = parsePhone(phone);
|
|
655
|
+
const formatExpires = parseNum(expires) || 15;
|
|
656
|
+
if (!formatUsername && !formatEmail && !formatPhone || !formatPassword) {
|
|
657
|
+
throw logException({
|
|
658
|
+
action,
|
|
659
|
+
category: eventCategory,
|
|
660
|
+
params: {
|
|
661
|
+
username
|
|
662
|
+
},
|
|
663
|
+
value: ErrorTypes.INVALID_ARGUMENTS
|
|
664
|
+
}, context);
|
|
665
|
+
}
|
|
666
|
+
const filters = [];
|
|
667
|
+
if (formatEmail) {
|
|
668
|
+
filters.push(`u.email == "${formatEmail}"`);
|
|
669
|
+
}
|
|
670
|
+
if (formatPhone) {
|
|
671
|
+
filters.push(`u.phone == ${formatPhone}`);
|
|
672
|
+
}
|
|
673
|
+
if (formatUsername) {
|
|
674
|
+
filters.push(`u.username == "${formatUsername}"`);
|
|
675
|
+
}
|
|
676
|
+
const checkQuery = `FOR u IN users
|
|
677
|
+
FILTER ${filters.join(' || ')}
|
|
77
678
|
LIMIT 1
|
|
78
|
-
RETURN u`;
|
|
79
|
-
|
|
679
|
+
RETURN u`;
|
|
680
|
+
let checkUser;
|
|
681
|
+
try {
|
|
682
|
+
checkUser = await useDb(databaseName).query(checkQuery).then((cursor)=>cursor.next());
|
|
683
|
+
} catch (error) {
|
|
684
|
+
throw logError({
|
|
685
|
+
action,
|
|
686
|
+
category: eventCategory,
|
|
687
|
+
params: {
|
|
688
|
+
username: formatUsername
|
|
689
|
+
},
|
|
690
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
691
|
+
}, error, context);
|
|
692
|
+
}
|
|
693
|
+
if (!checkUser) {
|
|
694
|
+
throw logException({
|
|
695
|
+
action,
|
|
696
|
+
category: eventCategory,
|
|
697
|
+
params: {
|
|
698
|
+
username
|
|
699
|
+
},
|
|
700
|
+
value: ErrorTypes.INVALID_AUTHENTICATION
|
|
701
|
+
}, context);
|
|
702
|
+
}
|
|
703
|
+
const { _key: userId, password: validPassword, salt, userAccess } = checkUser;
|
|
704
|
+
const authPassword = createPassword(formatPassword, salt);
|
|
705
|
+
console.log({
|
|
706
|
+
createPassword,
|
|
707
|
+
authPassword,
|
|
708
|
+
validPassword,
|
|
709
|
+
formatPassword,
|
|
710
|
+
salt
|
|
711
|
+
});
|
|
712
|
+
if (validPassword !== authPassword) {
|
|
713
|
+
throw logException({
|
|
714
|
+
action,
|
|
715
|
+
category: eventCategory,
|
|
716
|
+
params: {
|
|
717
|
+
userAccess,
|
|
718
|
+
userId,
|
|
719
|
+
username
|
|
720
|
+
},
|
|
721
|
+
value: ErrorTypes.INVALID_AUTHENTICATION
|
|
722
|
+
}, context);
|
|
723
|
+
}
|
|
724
|
+
try {
|
|
725
|
+
const token = createToken(userId || '', username || '', userAccess, formatExpires);
|
|
726
|
+
return token;
|
|
727
|
+
} catch (error) {
|
|
728
|
+
throw logError({
|
|
729
|
+
action,
|
|
730
|
+
category: eventCategory,
|
|
731
|
+
params: {
|
|
732
|
+
userId,
|
|
733
|
+
username
|
|
734
|
+
},
|
|
735
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
736
|
+
}, error, context);
|
|
737
|
+
}
|
|
738
|
+
};
|
|
739
|
+
export const signOut = async (context)=>{
|
|
740
|
+
const action = 'signOut';
|
|
741
|
+
const { databaseName, session: { userId: sessionId, username } = {} } = context;
|
|
742
|
+
const userDocId = `users/${sessionId}`;
|
|
743
|
+
const update = {
|
|
744
|
+
lastOnline: Date.now(),
|
|
745
|
+
sessionId: null
|
|
746
|
+
};
|
|
747
|
+
const sessionQuery = aql`LET u = DOCUMENT(${userDocId})
|
|
748
|
+
UPDATE u WITH ${update} IN users
|
|
80
749
|
LIMIT 1
|
|
81
|
-
RETURN NEW`;
|
|
750
|
+
RETURN NEW`;
|
|
751
|
+
try {
|
|
752
|
+
await useDb(databaseName).query(sessionQuery).then((cursor)=>cursor.next());
|
|
753
|
+
} catch (error) {
|
|
754
|
+
logError({
|
|
755
|
+
action,
|
|
756
|
+
category: eventCategory,
|
|
757
|
+
params: {
|
|
758
|
+
userId: sessionId,
|
|
759
|
+
username
|
|
760
|
+
},
|
|
761
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
762
|
+
}, error, context);
|
|
763
|
+
return false;
|
|
764
|
+
}
|
|
765
|
+
return true;
|
|
766
|
+
};
|
|
767
|
+
export const getActiveUserCount = (context)=>{
|
|
768
|
+
const action = 'getActiveUserCount';
|
|
769
|
+
const { databaseName } = context;
|
|
770
|
+
const countQuery = aql`LET docs = (
|
|
82
771
|
FOR u IN users
|
|
83
772
|
FILTER u.active == true
|
|
84
773
|
RETURN u
|
|
85
774
|
)
|
|
86
|
-
RETURN LENGTH(docs)`;
|
|
87
|
-
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FjdGlvbnMvdXNlcnMudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQ29weXJpZ2h0IChjKSAyMDE5LVByZXNlbnQsIE5pdHJvZ2VuIExhYnMsIEluYy5cbiAqIENvcHlyaWdodHMgbGljZW5zZWQgdW5kZXIgdGhlIE1JVCBMaWNlbnNlLiBTZWUgdGhlIGFjY29tcGFueWluZyBMSUNFTlNFIGZpbGUgZm9yIHRlcm1zLlxuICovXG5pbXBvcnQge3BhcnNlTnVtfSBmcm9tICdAbmxhYnMvdXRpbHMvcGFyc2Vycy9udW1iZXJzJztcbmltcG9ydCB7XG4gIGNyZWF0ZUhhc2gsXG4gIGNyZWF0ZVBhc3N3b3JkLFxuICBwYXJzZUFyYW5nb0lkLFxuICBwYXJzZUNoYXIsXG4gIHBhcnNlRW1haWwsXG4gIHBhcnNlUGFzc3dvcmQsXG4gIHBhcnNlUGhvbmUsXG4gIHBhcnNlVXNlcm5hbWVcbn0gZnJvbSAnQG5sYWJzL3V0aWxzL3BhcnNlcnMvc3RyaW5ncyc7XG5pbXBvcnQge2FxbH0gZnJvbSAnYXJhbmdvanMnO1xuaW1wb3J0IHtEYXRlVGltZX0gZnJvbSAnbHV4b24nO1xuaW1wb3J0IFN0cmlwZSBmcm9tICdzdHJpcGUnO1xuXG5pbXBvcnQge3BhcnNlVXNlcn0gZnJvbSAnLi4vYWRhcHRlcnMvdXNlckFkYXB0ZXIuanMnO1xuaW1wb3J0IHtDb25maWd9IGZyb20gJy4uL2NvbmZpZy5qcyc7XG5pbXBvcnQge0Vycm9yVHlwZXMsIHR5cGUgU2Vzc2lvbkVycm9yfSBmcm9tICcuLi90eXBlcy9lcnJvci50eXBlcy5qcyc7XG5pbXBvcnQge2xvZ0Vycm9yLCBsb2dFeGNlcHRpb259IGZyb20gJy4uL3V0aWxzL2FuYWx5dGljc1V0aWxzLmpzJztcbmltcG9ydCB7Z2V0RG9jSWQsIGdldExpbWl0LCBzZWxlY3RSZWFjdGlvbkNvdW50QnlUeXBlLCB1c2VEYn0gZnJvbSAnLi4vdXRpbHMvYXJhbmdvZGJVdGlscy5qcyc7XG5pbXBvcnQge2RldGVjdExhbmd1YWdlfSBmcm9tICcuLi91dGlscy9sYW5ndWFnZURldGVjdGlvbi5qcyc7XG5pbXBvcnQge2dldFNlc3Npb24sIHNldFNlc3Npb24sIHR5cGUgU2Vzc2lvblRva2VufSBmcm9tICcuLi91dGlscy9zZXNzaW9uVXRpbHMuanMnO1xuaW1wb3J0IHtzZW5kRW1haWx9IGZyb20gJy4vZW1haWwuanMnO1xuaW1wb3J0IHtzZW5kU21zfSBmcm9tICcuL3Ntcy5qcyc7XG5cbmltcG9ydCB0eXBlIHtBcWxRdWVyeX0gZnJvbSAnYXJhbmdvanMvYXFsJztcbmltcG9ydCB0eXBlIHtFZGdlQ29sbGVjdGlvbn0gZnJvbSAnYXJhbmdvanMvY29sbGVjdGlvbnMnO1xuaW1wb3J0IHR5cGUge0FwaUNvbnRleHR9IGZyb20gJy4uL3R5cGVzL2F1dGgudHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1VzZXJJbnB1dCwgVXNlclR5cGV9IGZyb20gJy4uL3R5cGVzL3VzZXJzLnR5cGVzLmpzJztcblxuY29uc3QgZXZlbnRDYXRlZ29yeSA9ICd1c2Vycyc7XG5jb25zdCBTVFJJUEVfQVBJX1ZFUlNJT04gPSAnMjAyNS0wNy0zMC5iYXNpbCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXNlck9wdGlvbnMge1xuICByZWFkb25seSBmcm9tPzogbnVtYmVyO1xuICByZWFkb25seSB0bz86IG51bWJlcjtcbiAgcmVhZG9ubHkgdXNlcm5hbWU/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBlbnVtIFVzZXJBY2Nlc3Mge1xuICBERUFDVElWQVRFRCA9IDAsXG4gIEFDVElWRSA9IDEsXG4gIFBSRU1JVU0gPSAyLFxuICBDT05URU5UX0FETUlOID0gMyxcbiAgQURNSU4gPSA0XG59XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVUb2tlbiA9IChcbiAgdXNlcklkOiBzdHJpbmcsXG4gIHVzZXJuYW1lOiBzdHJpbmcgPSAnJyxcbiAgdXNlckFjY2VzczogbnVtYmVyID0gMCxcbiAgZXhwaXJlc0luTWludXRlczogbnVtYmVyID0gMTVcbik6IFNlc3Npb25Ub2tlbiA9PiB7XG4gIGNvbnN0IG5vdzogRGF0ZVRpbWUgPSBEYXRlVGltZS5sb2NhbCgpO1xuICBjb25zdCBzZXNzaW9uRXhwaXJlczogRGF0ZVRpbWUgPSBub3cucGx1cyh7bWludXRlczogZXhwaXJlc0luTWludXRlc30pO1xuICBjb25zdCBpYXQ6IG51bWJlciA9IE1hdGguZmxvb3Iobm93LnRvU2Vjb25kcygpKTtcbiAgY29uc3QgZXhwOiBudW1iZXIgPSBNYXRoLmZsb29yKHNlc3Npb25FeHBpcmVzLnRvU2Vjb25kcygpKTtcbiAgY29uc3QgdG9rZW4gPSBzZXRTZXNzaW9uKHtcbiAgICBleHAsXG4gICAgaWF0LFxuICAgIHVzZXJBY2Nlc3MsXG4gICAgdXNlcklkLFxuICAgIHVzZXJuYW1lXG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgZXhwaXJlczogc2Vzc2lvbkV4cGlyZXMudG9NaWxsaXMoKSxcbiAgICBpc3N1ZWQ6IG5vdy50b01pbGxpcygpLFxuICAgIHRva2VuLFxuICAgIHVzZXJJZCxcbiAgICB1c2VybmFtZVxuICB9O1xufTtcblxuaW50ZXJmYWNlIFNlbGVjdEFjY3VtdWxhdG9yIHtcbiAgb2JqZWN0czogc3RyaW5nW107XG4gIHF1ZXJpZXM6IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgY29uc3QgZ2V0VXNlck9wdGlvbmFsID0gKGZpZWxkczogc3RyaW5nW10gPSBbXSk6IFNlbGVjdEFjY3VtdWxhdG9yID0+XG4gIGZpZWxkcy5yZWR1Y2UoKHNlbGVjdHM6IFNlbGVjdEFjY3VtdWxhdG9yLCBmaWVsZDogc3RyaW5nKSA9PiB7XG4gICAgaWYoZmllbGQuaW5jbHVkZXMoJ0NvdW50JykpIHtcbiAgICAgIHJldHVybiBzZWxlY3RSZWFjdGlvbkNvdW50QnlUeXBlKCd1c2VycycsICd1JywgZmllbGQsIHNlbGVjdHMpO1xuICAgIH1cblxuICAgIHJldHVybiBzZWxlY3RzO1xuICB9LCB7b2JqZWN0czogW10sIHF1ZXJpZXM6IFtdfSk7XG5cbmV4cG9ydCBjb25zdCBwYXJzZVVzZXJPcHRpb25zID0gKG9wdGlvbnM6IFVzZXJPcHRpb25zID0ge30pID0+IHtcbiAgY29uc3Qge1xuICAgIGZyb20gPSAwLFxuICAgIHRvID0gMzBcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGxpbWl0ID0gZ2V0TGltaXQoZnJvbSwgdG8pO1xuXG4gIHJldHVybiB7XG4gICAgLi4ub3B0aW9ucyxcbiAgICBsaW1pdFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGFkZFVzZXIgPSBhc3luYyAoY29udGV4dDogQXBpQ29udGV4dCwgdXNlcjogVXNlcklucHV0KTogUHJvbWlzZTxVc2VyVHlwZSB8IG51bGw+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2FkZFVzZXInO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBsYW5ndWFnZUNvbnRleHR9ID0gY29udGV4dDtcbiAgY29uc3Qge2NvbmZpcm06IF9jb25maXJtLCAuLi5uZXdVc2VyfSA9IHVzZXI7XG4gIGNvbnN0IHtlbWFpbCwgcGFzc3dvcmQsIHBob25lLCB1c2VybmFtZSwgdXNlcklkLCBfa2V5LCBfaWQsIC4uLmluc2VydFVzZXJ9ID0gcGFyc2VVc2VyKG5ld1VzZXIpO1xuICBjb25zdCBoYXNQYXNzd29yZCA9ICEhcGFzc3dvcmQ7XG4gIGNvbnN0IGhhc1VzZXJuYW1lID0gISF1c2VybmFtZSB8fCAhIXBob25lIHx8ICEhZW1haWw7XG5cbiAgaWYoIWhhc1Bhc3N3b3JkIHx8ICFoYXNVc2VybmFtZSkge1xuICAgIGxvZ0V4Y2VwdGlvbih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge3VzZXJuYW1lfSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLklOVkFMSURfQVJHVU1FTlRTXG4gICAgfSwgY29udGV4dCk7XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGhhc2hJZCA9IHVzZXJuYW1lIHx8IHBob25lIHx8IGVtYWlsO1xuICBjb25zdCBzYWx0OiBzdHJpbmcgPSBjcmVhdGVIYXNoKGAke2hhc2hJZH0ke3Bhc3N3b3JkfWAsICcnKTtcbiAgY29uc3QgZW5jcnlwdGVkUGFzc3dvcmQgPSBjcmVhdGVQYXNzd29yZChwYXNzd29yZCwgc2FsdCk7XG4gIGNvbnN0IGZpbHRlcnM6IHN0cmluZ1tdID0gW107XG5cbiAgaWYodXNlcm5hbWUpIHtcbiAgICBmaWx0ZXJzLnB1c2goYHUudXNlcm5hbWUgPT0gXCIke3VzZXJuYW1lfVwiYCk7XG4gIH1cblxuICBpZihlbWFpbCkge1xuICAgIGZpbHRlcnMucHVzaChgdS5lbWFpbCA9PSBcIiR7ZW1haWx9XCJgKTtcbiAgfVxuXG4gIGlmKHBob25lKSB7XG4gICAgZmlsdGVycy5wdXNoKGB1LnBob25lID09ICR7cGhvbmV9YCk7XG4gIH1cblxuICBjb25zdCBjaGVja1F1ZXJ5OiBzdHJpbmcgPSBgRk9SIHUgSU4gdXNlcnNcbiAgICBGSUxURVIgJHtmaWx0ZXJzLmpvaW4oJyB8fCAnKX1cbiAgICBMSU1JVCAxXG4gICAgUkVUVVJOIHVgO1xuXG4gIHRyeSB7XG4gICAgY29uc3QgZXhpc3RpbmdVc2VycyA9IGF3YWl0IHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoY2hlY2tRdWVyeSkudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkpO1xuXG4gICAgaWYoZXhpc3RpbmdVc2Vycy5sZW5ndGgpIHtcbiAgICAgIHRocm93IGxvZ0V4Y2VwdGlvbih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIHBhcmFtczoge1xuICAgICAgICAgIGVtYWlsLFxuICAgICAgICAgIHBob25lLFxuICAgICAgICAgIHVzZXJuYW1lXG4gICAgICAgIH0sXG4gICAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkVYSVNUSU5HX0lURU1cbiAgICAgIH0sIGNvbnRleHQpO1xuICAgIH1cbiAgfSBjYXRjaChlcnJvcikge1xuICAgIHRocm93IGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7ZW1haWwsIHBob25lLCB1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgfVxuXG4gIGNvbnN0IHBob25lQ291bnRyeUNvZGUgPSBwaG9uZT8ucmVwbGFjZSgvXFxEL2csICcnKS5zdWJzdHJpbmcoMCwgMyk7XG4gIGNvbnN0IGxvY2FsZSA9IGRldGVjdExhbmd1YWdlKHtcbiAgICAuLi5sYW5ndWFnZUNvbnRleHQsXG4gICAgcGhvbmVDb3VudHJ5Q29kZTogcGhvbmVDb3VudHJ5Q29kZSB8fCAnJyxcbiAgICB1c2VyUHJlZmVyZW5jZTogaW5zZXJ0VXNlci5sb2NhbGUgfHwgJ2VuJ1xuICB9KTtcbiAgY29uc3QgdmVyaWZpZWRFbWFpbENvZGU6IG51bWJlciA9IE1hdGguZmxvb3IoMTAwMDAwICsgKE1hdGgucmFuZG9tKCkgKiA5MDAwMDApKTtcbiAgY29uc3QgdmVyaWZpZWRTbXNDb2RlOiBudW1iZXIgPSBNYXRoLmZsb29yKDEwMDAwMCArIChNYXRoLnJhbmRvbSgpICogOTAwMDAwKSk7XG5cbiAgY29uc3QgaW5zZXJ0OiBVc2VyVHlwZSA9IHtcbiAgICAuLi5pbnNlcnRVc2VyLFxuICAgIF9rZXk6IGNyZWF0ZUhhc2godXNlcm5hbWUpLFxuICAgIGFkZGVkOiBEYXRlLm5vdygpLFxuICAgIGVtYWlsLFxuICAgIGxvY2FsZSxcbiAgICBtb2RpZmllZDogRGF0ZS5ub3coKSxcbiAgICBwYXNzd29yZDogZW5jcnlwdGVkUGFzc3dvcmQsXG4gICAgcGhvbmUsXG4gICAgc2FsdCxcbiAgICB1c2VyQWNjZXNzOiAxLFxuICAgIHVzZXJuYW1lLFxuICAgIHZlcmlmaWVkRW1haWw6IGZhbHNlLFxuICAgIHZlcmlmaWVkRW1haWxDb2RlLFxuICAgIHZlcmlmaWVkUGhvbmU6IGZhbHNlLFxuICAgIHZlcmlmaWVkU21zQ29kZVxuICB9O1xuXG4gIGNvbnN0IGluc2VydFF1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBJTlNFUlQgJHtpbnNlcnR9IElOIHVzZXJzIFJFVFVSTiBORVdgO1xuXG4gIHJldHVybiBhd2FpdCB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGluc2VydFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgdGhyb3cgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICBwYXJhbXM6IHt1c2VybmFtZX0sXG4gICAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgICB9LCBlcnJvciwgY29udGV4dCk7XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgdXBkYXRlVXNlciA9IGFzeW5jIChjb250ZXh0OiBBcGlDb250ZXh0LCB1c2VyOiBVc2VyVHlwZSk6IFByb21pc2U8VXNlclR5cGU+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ3VwZGF0ZVVzZXInO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHVwZGF0ZWRVc2VyID0gcGFyc2VVc2VyKHVzZXIpO1xuICBjb25zdCB7X2tleSwgX2lkLCB0YWdzID0gW10sIC4uLnVwZGF0ZX0gPSB1cGRhdGVkVXNlcjtcbiAgY29uc3Qge2lkfSA9IHVwZGF0ZWRVc2VyO1xuXG4gIGNvbnN0IHVzZXJRdWVyeTogQXFsUXVlcnkgPSBhcWxgTEVUIHUgPSBET0NVTUVOVCgke2lkfSlcbiAgICBVUERBVEUgdSBXSVRIICR7dXBkYXRlfSBJTiB1c2Vyc1xuICAgIFJFVFVSTiBORVdgO1xuICB0cnkge1xuICAgIGNvbnN0IGRhdGFiYXNlID0gdXNlRGIoZGF0YWJhc2VOYW1lKTtcbiAgICBjb25zdCB1cGRhdGVkVXNlciA9IGF3YWl0IGRhdGFiYXNlLnF1ZXJ5KHVzZXJRdWVyeSkudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKTtcbiAgICBjb25zdCB0YWdDb2xsZWN0aW9uOiBFZGdlQ29sbGVjdGlvbiA9IGRhdGFiYXNlLmNvbGxlY3Rpb24oJ2lzVGFnZ2VkJyk7XG5cbiAgICBhd2FpdCBQcm9taXNlLmFsbCh0YWdzLm1hcCgoe2lkOiB0YWdEb2NJZCwgbmFtZX0pID0+IHtcbiAgICAgIGNvbnN0IHRhZ1F1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBGT1IgaXQgSU4gaXNUYWdnZWRcbiAgICAgICAgRklMVEVSIGl0Ll9mcm9tID09ICR7dGFnRG9jSWR9ICYmIGl0Ll90byA9PSAke2lkfSAmJiBpdC5uYW1lID09ICR7bmFtZX1cbiAgICAgICAgTElNSVQgMVxuICAgICAgICBSRVRVUk4gaXRgO1xuXG4gICAgICByZXR1cm4gZGF0YWJhc2UucXVlcnkodGFnUXVlcnkpXG4gICAgICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgICAgIC50aGVuKCh0YWdFZGdlKSA9PiB7XG4gICAgICAgICAgaWYoISF0YWdFZGdlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGFnRWRnZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBlZGdlID0ge1xuICAgICAgICAgICAgX2Zyb206IHRhZ0RvY0lkLFxuICAgICAgICAgICAgX2tleTogY3JlYXRlSGFzaChgaXNUYWdnZWQtJHt0YWdEb2NJZH0tJHtpZH1gKSxcbiAgICAgICAgICAgIF90bzogaWQsXG4gICAgICAgICAgICBhZGRlZDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgIG5hbWVcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgcmV0dXJuIHRhZ0NvbGxlY3Rpb24uc2F2ZShlZGdlLCB7cmV0dXJuTmV3OiB0cnVlfSkudGhlbigoKSA9PiBlZGdlKTtcbiAgICAgICAgfSk7XG4gICAgfSkpO1xuXG4gICAgcmV0dXJuIHVwZGF0ZWRVc2VyO1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgdGhyb3cgbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHt1c2VyfSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgZm9yZ290UGFzc3dvcmQgPSBhc3luYyAoY29udGV4dDogQXBpQ29udGV4dCwge2VtYWlsLCBwaG9uZSwgdXNlcm5hbWV9KTogUHJvbWlzZTxib29sZWFuPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdmb3Jnb3RQYXNzd29yZCc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWV9ID0gY29udGV4dDtcbiAgY29uc3QgYXFsUXVlcnk6IEFxbFF1ZXJ5ID0gYXFsYEZPUiB1IElOIHVzZXJzXG4gICAgRklMVEVSIHUuZW1haWwgPT0gJHtlbWFpbH0gfHwgdS5waG9uZSA9PSAke3Bob25lfSB8fCB1LnVzZXJuYW1lID09ICR7dXNlcm5hbWV9XG4gICAgTElNSVQgMVxuICAgIFJFVFVSTiB1YDtcblxuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgICAgLnRoZW4oYXN5bmMgKGN1cnNvcikgPT4ge1xuICAgICAgICBjb25zdCB1c2VyID0gY3Vyc29yLm5leHQoKTtcblxuICAgICAgICBpZih1c2VyKSB7XG4gICAgICAgICAgY29uc3Qge2VtYWlsLCBwaG9uZSwgdmVyaWZpZWRFbWFpbCwgdmVyaWZpZWRQaG9uZX0gPSB1c2VyIGFzIFVzZXJUeXBlO1xuICAgICAgICAgIGNvbnN0IGNvZGVFeHBpcmVzID0gMTAwMCAqIDYwICogMTU7IC8vIDE1IG1pbnV0ZXNcbiAgICAgICAgICBjb25zdCBjb2RlID0gTWF0aC5mbG9vcigxMDAwMDAgKyAoTWF0aC5yYW5kb20oKSAqIDkwMDAwMCkpO1xuICAgICAgICAgIGNvbnN0IHVzZXJEb2NJZCA9IGdldERvY0lkKCd1c2VycycsIHVzZXIpO1xuICAgICAgICAgIGxldCB1cGRhdGU7XG5cbiAgICAgICAgICBpZihlbWFpbCAmJiB2ZXJpZmllZEVtYWlsKSB7XG4gICAgICAgICAgICBzZW5kRW1haWwoe1xuICAgICAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgICAgICB0ZXh0OiBgWW91ciBjb2RlIGlzICR7Y29kZX1gXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHVwZGF0ZSA9IHt2ZXJpZmllZEVtYWlsQ29kZTogY29kZSwgdmVyaWZpZWRFbWFpbEV4cGlyZXM6IGNvZGVFeHBpcmVzfTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZihwaG9uZSAmJiB2ZXJpZmllZFBob25lKSB7XG4gICAgICAgICAgICBzZW5kU21zKHtcbiAgICAgICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICAgICAgdGV4dDogYFlvdXIgY29kZSBpcyAke2NvZGV9YFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB1cGRhdGUgPSB7dmVyaWZpZWRQaG9uZUV4cGlyZXM6IGNvZGVFeHBpcmVzLCB2ZXJpZmllZFNtc0NvZGU6IGNvZGV9O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmKHVwZGF0ZS52ZXJpZmllZEVtYWlsQ29kZSB8fCB1cGRhdGUudmVyaWZpZWRTbXNDb2RlKSB7XG4gICAgICAgICAgICBjb25zdCB1cGRhdGVRdWVyeTogQXFsUXVlcnkgPSBhcWxgVVBEQVRFICR7dXNlckRvY0lkfSBXSVRIICR7dXBkYXRlfSBJTiB1c2Vyc2A7XG5cbiAgICAgICAgICAgIGF3YWl0IHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkodXBkYXRlUXVlcnkpO1xuXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9KTtcbiAgfSBjYXRjaChlcnJvcikge1xuICAgIGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7ZW1haWwsIHBob25lLCB1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHJlc2V0UGFzc3dvcmQgPSBhc3luYyAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHtcbiAgICBjb2RlLFxuICAgIHBhc3N3b3JkLFxuICAgIHR5cGUsXG4gICAgdXNlcm5hbWVcbiAgfToge1xuICAgIGNvZGU6IG51bWJlcjtcbiAgICBwYXNzd29yZDogc3RyaW5nO1xuICAgIHR5cGU6ICdwaG9uZScgfCAnZW1haWwnO1xuICAgIHVzZXJuYW1lOiBzdHJpbmc7XG4gIH1cbik6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAncmVzZXRQYXNzd29yZCc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWV9ID0gY29udGV4dDtcbiAgY29uc3QgZm9ybWF0UGFzc3dvcmQ6IHN0cmluZyA9IHBhcnNlUGFzc3dvcmQocGFzc3dvcmQpO1xuICBjb25zdCBhcWxRdWVyeTogQXFsUXVlcnkgPSBhcWxgRk9SIHUgSU4gdXNlcnNcbiAgICBGSUxURVIgdS51c2VybmFtZSA9PSAke3VzZXJuYW1lfVxuICAgIExJTUlUIDFcbiAgICBSRVRVUk4gdWA7XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRdWVyeSlcbiAgICAgIC50aGVuKGFzeW5jIChjdXJzb3IpID0+IHtcbiAgICAgICAgY29uc3QgdXNlciA9IGN1cnNvci5uZXh0KCk7XG5cbiAgICAgICAgaWYodXNlcikge1xuICAgICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgIF9pZDogdXNlckRvY0lkLFxuICAgICAgICAgICAgc2FsdCxcbiAgICAgICAgICAgIHZlcmlmaWVkRW1haWxDb2RlLFxuICAgICAgICAgICAgdmVyaWZpZWRFbWFpbEV4cGlyZXMgPSAwLFxuICAgICAgICAgICAgdmVyaWZpZWRTbXNDb2RlLFxuICAgICAgICAgICAgdmVyaWZpZWRQaG9uZUV4cGlyZXMgPSAwXG4gICAgICAgICAgfSA9IHVzZXIgYXMgVXNlclR5cGU7XG4gICAgICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICBsZXQgdXBkYXRlO1xuXG4gICAgICAgICAgc3dpdGNoKHR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ2VtYWlsJzpcbiAgICAgICAgICAgICAgaWYoY29kZSA9PT0gdmVyaWZpZWRFbWFpbENvZGUgJiYgdmVyaWZpZWRFbWFpbEV4cGlyZXMgPiBub3cpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXNzd29yZDogc3RyaW5nID0gY3JlYXRlUGFzc3dvcmQoZm9ybWF0UGFzc3dvcmQsIHNhbHQpO1xuICAgICAgICAgICAgICAgIHVwZGF0ZSA9IHtwYXNzd29yZH07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdwaG9uZSc6XG4gICAgICAgICAgICAgIGlmKGNvZGUgPT09IHZlcmlmaWVkU21zQ29kZSAmJiB2ZXJpZmllZFBob25lRXhwaXJlcyA+IG5vdykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhc3N3b3JkOiBzdHJpbmcgPSBjcmVhdGVQYXNzd29yZChmb3JtYXRQYXNzd29yZCwgc2FsdCk7XG4gICAgICAgICAgICAgICAgdXBkYXRlID0ge3Bhc3N3b3JkfTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZih1cGRhdGUpIHtcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZVF1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBVUERBVEUgJHt1c2VyRG9jSWR9IFdJVEggJHt1cGRhdGV9IElOIHVzZXJzYDtcblxuICAgICAgICAgICAgYXdhaXQgdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeSh1cGRhdGVRdWVyeSk7XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0pO1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHt1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGNvbmZpcm1Db2RlID0gYXN5bmMgKFxuICBjb250ZXh0OiBBcGlDb250ZXh0LFxuICB7XG4gICAgY29kZSxcbiAgICB0eXBlLFxuICAgIHZhbHVlXG4gIH06IHtcbiAgICBjb2RlOiBudW1iZXI7XG4gICAgdHlwZTogJ3NtcycgfCAnZW1haWwnO1xuICAgIHZhbHVlOiBzdHJpbmc7XG4gIH1cbik6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnY29uZmlybUNvZGUnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lfSA9IGNvbnRleHQ7XG4gIGNvbnN0IGlzU21zID0gdHlwZSA9PT0gJ3Ntcyc7XG4gIGNvbnN0IGZvcm1hdHRlZFZhbHVlID0gaXNTbXMgPyBwYXJzZVBob25lKHZhbHVlKSA6IHBhcnNlRW1haWwodmFsdWUpO1xuICBjb25zdCBmaWx0ZXJCeVR5cGUgPSBpc1Ntc1xuICAgID8gYEZJTFRFUiB1LnBob25lID09IFwiJHtmb3JtYXR0ZWRWYWx1ZX1cIiAmJiB1LnZlcmlmaWVkU21zQ29kZSA9PSAke2NvZGV9YFxuICAgIDogYEZJTFRFUiB1LmVtYWlsID09IFwiJHtmb3JtYXR0ZWRWYWx1ZX1cIiAmJiB1LnZlcmlmaWVkRW1haWxDb2RlID09ICR7Y29kZX1gO1xuICBjb25zdCBhcWxRdWVyeTogc3RyaW5nID0gYEZPUiB1IElOIHVzZXJzXG4gICAgJHtmaWx0ZXJCeVR5cGV9XG4gICAgTElNSVQgMVxuICAgIFJFVFVSTiB1YDtcblxuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAgIC50aGVuKCh1c2VyKSA9PiB7XG4gICAgICAgIGlmKHVzZXIpIHtcbiAgICAgICAgICBjb25zdCB1cGRhdGVkVXNlciA9IGlzU21zXG4gICAgICAgICAgICA/IHt2ZXJpZmllZFBob25lOiB0cnVlLCB2ZXJpZmllZFNtc0NvZGU6IDB9XG4gICAgICAgICAgICA6IHt2ZXJpZmllZEVtYWlsOiB0cnVlLCB2ZXJpZmllZEVtYWlsQ29kZTogMH07XG4gICAgICAgICAgY29uc3QgYXFsUXVlcnk6IEFxbFF1ZXJ5ID0gYXFsYFVQREFURSAke3VzZXIuX2tleX0gV0lUSCAke3VwZGF0ZWRVc2VyfSBJTiB1c2Vyc2A7XG5cbiAgICAgICAgICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRdWVyeSlcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHRydWUpXG4gICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICBsb2dFcnJvcih7XG4gICAgICAgICAgICAgICAgYWN0aW9uLFxuICAgICAgICAgICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICAgICAgICAgIHBhcmFtczoge2NvZGUsIHR5cGUsIHZhbHVlOiBmb3JtYXR0ZWRWYWx1ZX0sXG4gICAgICAgICAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgICAgICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuXG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge2NvZGUsIHR5cGUsIHZhbHVlOiBmb3JtYXR0ZWRWYWx1ZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGRlbGV0ZVVzZXIgPSAoY29udGV4dDogQXBpQ29udGV4dCwgdXNlcjogVXNlclR5cGUpOiBQcm9taXNlPFVzZXJUeXBlPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdkZWxldGVVc2VyJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZX0gPSBjb250ZXh0O1xuICBjb25zdCB7aWR9ID0gcGFyc2VVc2VyKHVzZXIpO1xuXG4gIGNvbnN0IGFxbFF1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBMRVQgdSA9IERPQ1VNRU5UKCR7aWR9KVxuICAgIFJFTU9WRSB1IElOIHVzZXJzXG4gICAgUkVUVVJOIE9MRGA7XG5cbiAgY29uc3Qgc3RyaXBlQ2xpZW50ID0gbmV3IFN0cmlwZShDb25maWcuZ2V0KCdzdHJpcGUudG9rZW4nKSwge2FwaVZlcnNpb246IFNUUklQRV9BUElfVkVSU0lPTiwgdHlwZXNjcmlwdDogdHJ1ZX0pO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgLnRoZW4oKGRlbGV0ZWRVc2VyKSA9PiBzdHJpcGVDbGllbnQuY3VzdG9tZXJzLmRlbChkZWxldGVkVXNlcj8uc3RyaXBlQ3VzdG9tZXJJZClcbiAgICAgIC50aGVuKCgpID0+IHN0cmlwZUNsaWVudC5hY2NvdW50cy5kZWwoZGVsZXRlZFVzZXI/LnN0cmlwZUFjY291bnRJZCkpXG4gICAgICAudGhlbigoKSA9PiBkZWxldGVkVXNlcikpXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7aWR9LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICB9LCBlcnJvciwgY29udGV4dCkpO1xufTtcblxuZXhwb3J0IGNvbnN0IGRlYWN0aXZhdGVVc2VyID0gKGNvbnRleHQ6IEFwaUNvbnRleHQsIHVzZXI6IFVzZXJUeXBlKTogUHJvbWlzZTxVc2VyVHlwZT4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnZGVsZXRlJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZX0gPSBjb250ZXh0O1xuICBjb25zdCB7aWR9ID0gcGFyc2VVc2VyKHVzZXIpO1xuICBjb25zdCB1cGRhdGVkOiBVc2VyVHlwZSA9IHtcbiAgICB1c2VyQWNjZXNzOiAwXG4gIH07XG4gIGNvbnN0IGFxbFF1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBVUERBVEUgJHtpZH0gV0lUSCAke3VwZGF0ZWR9IElOIHVzZXJzIExJTUlUIDEgUkVUVVJOIE5FV2A7XG5cbiAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoYXFsUXVlcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgdGhyb3cgbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHtpZH0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0RGlzcGxheU5hbWUgPSAodXNlcjogVXNlclR5cGUpOiBzdHJpbmcgPT4ge1xuICBjb25zdCB7Zmlyc3QsIGxhc3QsIG5hbWUgPSAnJywgdXNlcm5hbWUgPSAnJ30gPSB1c2VyO1xuICBjb25zdCBmdWxsbmFtZSA9IChbZmlyc3QsIGxhc3RdKS5qb2luKCcgJykudHJpbSgpO1xuXG4gIGlmKG5hbWUpIHtcbiAgICByZXR1cm4gbmFtZTtcbiAgfSBlbHNlIGlmKGZ1bGxuYW1lICE9PSAnJykge1xuICAgIHJldHVybiBmdWxsbmFtZTtcbiAgfSBlbHNlIGlmKHVzZXJuYW1lKSB7XG4gICAgcmV0dXJuIHVzZXJuYW1lO1xuICB9XG5cbiAgcmV0dXJuICdVbmtub3duJztcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRTZXNzaW9uVXNlciA9IChjb250ZXh0OiBBcGlDb250ZXh0KTogUHJvbWlzZTxVc2VyVHlwZT4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnZ2V0U2Vzc2lvblVzZXInO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHMsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZCwgdXNlcm5hbWV9ID0ge319ID0gY29udGV4dDtcbiAgY29uc3Qge29iamVjdHM6IHNlbGVjdE9iamVjdHMsIHF1ZXJpZXM6IHNlbGVjdFF1ZXJpZXN9ID0gZ2V0VXNlck9wdGlvbmFsKGZpZWxkcyk7XG4gIGNvbnN0IGZvcm1hdFNlc3Npb25JZCA9IHBhcnNlQXJhbmdvSWQoYHVzZXJzLyR7c2Vzc2lvbklkfWApO1xuXG4gIGNvbnN0IGFxbFF1ZXJ5OiBzdHJpbmcgPSBgTEVUIHUgPSBET0NVTUVOVChcIiR7Zm9ybWF0U2Vzc2lvbklkfVwiKVxuICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gIFJFVFVSTiBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkgYXMgdW5rbm93biBhcyBVc2VyVHlwZSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgdGhyb3cgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICBwYXJhbXM6IHt1c2VySWQ6IHNlc3Npb25JZCwgdXNlcm5hbWV9LFxuICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICAgIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFVzZXIgPSAoY29udGV4dDogQXBpQ29udGV4dCwgdXNlcjogVXNlclR5cGUpOiBQcm9taXNlPFVzZXJUeXBlPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdnZXRVc2VyJztcbiAgY29uc3Qge2VtYWlsLCBpZCwgcGhvbmUsIHVzZXJJZCwgdXNlcm5hbWV9ID0gcGFyc2VVc2VyKHVzZXIpO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHN9ID0gY29udGV4dDtcbiAgY29uc3Qge29iamVjdHM6IHNlbGVjdE9iamVjdHMsIHF1ZXJpZXM6IHNlbGVjdFF1ZXJpZXN9ID0gZ2V0VXNlck9wdGlvbmFsKGZpZWxkcyk7XG4gIGxldCBhcWxRdWVyeTogc3RyaW5nID0gJyc7XG5cbiAgaWYoaWQpIHtcbiAgICBhcWxRdWVyeSA9IGBMRVQgdSA9IERPQ1VNRU5UKFwiJHtpZH1cIilcbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgRklMVEVSIHUudXNlckFjY2VzcyA+IDBcbiAgICBSRVRVUk4gTUVSR0UodSwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcbiAgfSBlbHNlIGlmKHVzZXJuYW1lKSB7XG4gICAgYXFsUXVlcnkgPSBgRk9SIHUgSU4gdXNlcnNcbiAgICBGSUxURVIgdS51c2VybmFtZSA9PSBcIiR7dXNlcm5hbWV9XCJcbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgUkVUVVJOIE1FUkdFKHUsIHske3NlbGVjdE9iamVjdHMuam9pbignLCAnKX19KWA7XG4gIH0gZWxzZSBpZihlbWFpbCkge1xuICAgIGFxbFF1ZXJ5ID0gYEZPUiB1IElOIHVzZXJzXG4gICAgRklMVEVSIHUuZW1haWwgPT0gXCIke2VtYWlsfVwiXG4gICAgJHtzZWxlY3RRdWVyaWVzLmpvaW4oJ1xcbicpfVxuICAgIFJFVFVSTiBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuICB9IGVsc2UgaWYocGhvbmUpIHtcbiAgICBhcWxRdWVyeSA9IGBGT1IgdSBJTiB1c2Vyc1xuICAgIEZJTFRFUiB1LnBob25lID09IFwiJHtwaG9uZX1cIlxuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICBSRVRVUk4gTUVSR0UodSwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcbiAgfVxuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpXG4gICAgLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgLnRoZW4oKHVzZXIpID0+IHVzZXIpXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7aWQsIHVzZXJJZCwgdXNlcm5hbWV9LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICB9LCBlcnJvciwgY29udGV4dCkpO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFVzZXJzID0gKGNvbnRleHQ6IEFwaUNvbnRleHQsIG9wdGlvbnM/OiBVc2VyT3B0aW9ucyk6IFByb21pc2U8VXNlclR5cGVbXT4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnZ2V0VXNlckxpc3QnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHN9ID0gY29udGV4dDtcbiAgY29uc3Qge2xpbWl0LCB1c2VybmFtZX0gPSBwYXJzZVVzZXJPcHRpb25zKG9wdGlvbnMpO1xuICBjb25zdCB7b2JqZWN0czogc2VsZWN0T2JqZWN0cywgcXVlcmllczogc2VsZWN0UXVlcmllc30gPSBnZXRVc2VyT3B0aW9uYWwoZmllbGRzKTtcbiAgY29uc3QgZmlsdGVyQnk6IHN0cmluZ1tdID0gWyd1LnVzZXJBY2Nlc3MgPiAwJ107XG5cbiAgaWYodXNlcm5hbWUpIHtcbiAgICBmaWx0ZXJCeS5wdXNoKGBDT05UQUlOUyh1LnVzZXJuYW1lLCBcIiR7cGFyc2VVc2VybmFtZSh1c2VybmFtZSl9XCIpYCk7XG4gIH1cblxuICBjb25zdCBhcWxRdWVyeTogc3RyaW5nID0gYEZPUiB1IElOIHVzZXJzXG4gICAgRklMVEVSICR7ZmlsdGVyQnkuam9pbignICYmICcpfVxuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICAke2xpbWl0LmFxbH1cbiAgICBTT1JUIHUudXNlcm5hbWVcbiAgICBSRVRVUk4gTUVSR0UodSwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcblxuICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRdWVyeSlcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkgYXMgdW5rbm93biBhcyBVc2VyVHlwZVtdKVxuICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICBsb2dFcnJvcih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgICB9LCBlcnJvciwgY29udGV4dCk7XG5cbiAgICAgIHJldHVybiBbXSBhcyBVc2VyVHlwZVtdO1xuICAgIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFVzZXJzQnlSZWFjdGlvbnMgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHtyZWFjdGlvbnMgPSBbXSwgdXNlcm5hbWV9OiB7cmVhY3Rpb25zPzogc3RyaW5nW107IHVzZXJuYW1lPzogc3RyaW5nfSxcbiAgb3B0aW9ucz86IFVzZXJPcHRpb25zXG4pOiBQcm9taXNlPFVzZXJUeXBlW10+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2dldFVzZXJzQnlSZWFjdGlvbnMnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHMsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZH0gPSB7fX0gPSBjb250ZXh0O1xuICBjb25zdCBmb3JtYXRSZWFjdGlvbnM6IHN0cmluZ1tdID0gcmVhY3Rpb25zLm1hcCgocmVhY3Rpb25OYW1lOiBzdHJpbmcpID0+IHBhcnNlQ2hhcihyZWFjdGlvbk5hbWUsIDMyKS50b0xvd2VyQ2FzZSgpKTtcbiAgY29uc3Qge2xpbWl0fSA9IHBhcnNlVXNlck9wdGlvbnMob3B0aW9ucyk7XG4gIGNvbnN0IHtvYmplY3RzOiBzZWxlY3RPYmplY3RzLCBxdWVyaWVzOiBzZWxlY3RRdWVyaWVzfSA9IGdldFVzZXJPcHRpb25hbChmaWVsZHMpO1xuICBjb25zdCBmb3JtYXRTZXNzaW9uSWQ6IHN0cmluZyA9IGB1c2Vycy8ke3Nlc3Npb25JZH1gO1xuICBjb25zdCBmb3JtYXRVc2VybmFtZTogc3RyaW5nID0gcGFyc2VVc2VybmFtZSh1c2VybmFtZSk7XG4gIGNvbnN0IGZpbHRlckJ5OiBzdHJpbmdbXSA9IFtcbiAgICAndS51c2VyQWNjZXNzID4gMCcsXG4gICAgYFBPU0lUSU9OKCR7SlNPTi5zdHJpbmdpZnkoZm9ybWF0UmVhY3Rpb25zKX0sIExPV0VSKHIubmFtZSkpYFxuICBdO1xuXG4gIGlmKHVzZXJuYW1lKSB7XG4gICAgZmlsdGVyQnkucHVzaChgQ09OVEFJTlModS51c2VybmFtZSwgXCIke2Zvcm1hdFVzZXJuYW1lfVwiKWApO1xuICB9XG5cbiAgY29uc3QgYXFsUXVlcnk6IHN0cmluZyA9IGBGT1IgdSwgciBJTiBPVVRCT1VORCBcIiR7Zm9ybWF0U2Vzc2lvbklkfVwiIGhhc1JlYWN0aW9uXG4gICAgT1BUSU9OUyB7dmVydGV4Q29sbGVjdGlvbnM6IFwidXNlcnNcIn1cbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgRklMVEVSICR7ZmlsdGVyQnkuam9pbignICYmICcpfVxuICAgICR7bGltaXQuYXFsfVxuICAgIFJFVFVSTiBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSBhcyB1bmtub3duIGFzIFVzZXJUeXBlW10pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgICAgcmV0dXJuIFtdIGFzIFVzZXJUeXBlW107XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VXNlcnNCeVRhZ3MgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHt0YWdzLCB1c2VybmFtZX0sXG4gIG9wdGlvbnM/OiBVc2VyT3B0aW9uc1xuKTogUHJvbWlzZTxVc2VyVHlwZVtdPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdnZXRVc2Vyc0J5VGFncyc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWUsIGZpZWxkcywgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkfSA9IHt9fSA9IGNvbnRleHQ7XG4gIGNvbnN0IGZvcm1hdFRhZ3M6IHN0cmluZ1tdID0gdGFncz8ucmVkdWNlKChsaXN0OiBzdHJpbmdbXSwgdGFnTmFtZTogc3RyaW5nKSA9PiB7XG4gICAgaWYodGFnTmFtZSkge1xuICAgICAgbGlzdC5wdXNoKHBhcnNlQ2hhcih0YWdOYW1lLCAzMikudG9Mb3dlckNhc2UoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxpc3Q7XG4gIH0sIFtdKTtcbiAgY29uc3Qge2xpbWl0fSA9IHBhcnNlVXNlck9wdGlvbnMob3B0aW9ucyk7XG4gIGNvbnN0IHtvYmplY3RzOiBzZWxlY3RPYmplY3RzLCBxdWVyaWVzOiBzZWxlY3RRdWVyaWVzfSA9IGdldFVzZXJPcHRpb25hbChmaWVsZHMpO1xuICBjb25zdCBmb3JtYXRVc2VybmFtZTogc3RyaW5nID0gcGFyc2VVc2VybmFtZSh1c2VybmFtZSk7XG4gIGNvbnN0IGZpbHRlckJ5OiBzdHJpbmdbXSA9IFtcbiAgICBgdS5fa2V5ICE9IFwiJHtzZXNzaW9uSWR9XCJgLFxuICAgICd1LnVzZXJBY2Nlc3MgPiAwJ1xuICBdO1xuXG4gIGlmKHVzZXJuYW1lKSB7XG4gICAgZmlsdGVyQnkucHVzaChgQ09OVEFJTlModS51c2VybmFtZSwgXCIke2Zvcm1hdFVzZXJuYW1lfVwiKWApO1xuICB9XG5cbiAgY29uc3QgYXFsUXVlcnk6IHN0cmluZyA9IGBGT1IgdCBJTiB0YWdzXG4gICAgRklMVEVSIFBPU0lUSU9OKCR7SlNPTi5zdHJpbmdpZnkoZm9ybWF0VGFncyl9LCBMT1dFUih0Lm5hbWUpKVxuICAgIEZPUiB1LCBpdCBJTiBPVVRCT1VORCB0IGlzVGFnZ2VkXG4gICAgT1BUSU9OUyB7YmZzOiB0cnVlLCB1bmlxdWVWZXJ0aWNlczogXCJnbG9iYWxcIiwgdmVydGV4Q29sbGVjdGlvbnM6IFwidXNlcnNcIn1cbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgRklMVEVSICR7ZmlsdGVyQnkuam9pbignICYmICcpfVxuICAgICR7bGltaXQuYXFsfVxuICAgIFJFVFVSTiBESVNUSU5DVCBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSBhcyB1bmtub3duIGFzIFVzZXJUeXBlW10pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgICAgcmV0dXJuIFtdIGFzIFVzZXJUeXBlW107XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VXNlcnNCeUxhdGVzdCA9IChjb250ZXh0OiBBcGlDb250ZXh0LCB7dXNlcm5hbWV9LCBvcHRpb25zPzogVXNlck9wdGlvbnMpOiBQcm9taXNlPFVzZXJUeXBlW10+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2dldFVzZXJzQnlMYXRlc3QnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHMsIHNlc3Npb246IHt1c2VySWR9ID0ge319ID0gY29udGV4dDtcbiAgY29uc3Qge2xpbWl0fSA9IHBhcnNlVXNlck9wdGlvbnMob3B0aW9ucyk7XG4gIGNvbnN0IGZpbHRlciA9IFtcbiAgICAndS5faWQgIT0gc2Vzc2lvbi5faWQnLFxuICAgICd1LnVzZXJBY2Nlc3MgPiAwJ1xuICBdO1xuICBjb25zdCB7b2JqZWN0czogc2VsZWN0T2JqZWN0cywgcXVlcmllczogc2VsZWN0UXVlcmllc30gPSBnZXRVc2VyT3B0aW9uYWwoZmllbGRzKTtcblxuICBpZih1c2VybmFtZSkge1xuICAgIGZpbHRlci5wdXNoKGBDT05UQUlOUyh1LnVzZXJuYW1lLCBcIiR7cGFyc2VVc2VybmFtZSh1c2VybmFtZSl9XCIpYCk7XG4gIH1cblxuICAvLyBHZXQgZGF0YSBmcm9tIGRhdGFiYXNlXG4gIGNvbnN0IGFxbFF1ZXJ5OiBzdHJpbmcgPSBgRk9SIHUgSU4gdXNlcnNcbiAgICBMRVQgc2Vzc2lvbiA9IERPQ1VNRU5UKFwidXNlcnMvJHt1c2VySWR9XCIpXG4gICAgRklMVEVSICR7ZmlsdGVyLmpvaW4oJyAmJiAnKX1cbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgTEVUIGRpc3RhbmNlID0gRElTVEFOQ0UodS5sYXRpdHVkZSB8fCAwLCB1LmxvbmdpdHVkZSB8fCAwLCBzZXNzaW9uLmxhdGl0dWRlIHx8IDAsIHNlc3Npb24ubG9uZ2l0dWRlIHx8IDApXG4gICAgJHtsaW1pdC5hcWx9XG4gICAgU09SVCBkaXN0YW5jZSBBU0MsIHUuYWRkZWQgREVTQ1xuICAgIFJFVFVSTiBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSBhcyB1bmtub3duIGFzIFVzZXJUeXBlW10pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgICAgcmV0dXJuIFtdIGFzIFVzZXJUeXBlW107XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VXNlcnNCeUNvbm5lY3Rpb24gPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHt1c2VySWR9OiBVc2VyVHlwZSxcbiAgb3B0aW9ucz86IFVzZXJPcHRpb25zXG4pOiBQcm9taXNlPFVzZXJUeXBlW10+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2dldFVzZXJzQnlDb25uZWN0aW9uJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZSwgZmllbGRzfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtsaW1pdCwgdXNlcm5hbWV9ID0gcGFyc2VVc2VyT3B0aW9ucyhvcHRpb25zKTtcbiAgY29uc3Qge29iamVjdHM6IHNlbGVjdE9iamVjdHMsIHF1ZXJpZXM6IHNlbGVjdFF1ZXJpZXN9ID0gZ2V0VXNlck9wdGlvbmFsKGZpZWxkcyk7XG4gIGNvbnN0IGZvcm1hdFVzZXJJZDogc3RyaW5nID0gcGFyc2VBcmFuZ29JZChgdXNlcnMvJHt1c2VySWR9YCk7XG4gIGNvbnN0IGZpbHRlckJ5OiBzdHJpbmdbXSA9IFtcbiAgICAndS51c2VyQWNjZXNzID4gMCdcbiAgXTtcblxuICBpZih1c2VybmFtZSkge1xuICAgIGZpbHRlckJ5LnB1c2goYENPTlRBSU5TKHUudXNlcm5hbWUsIFwiJHtwYXJzZVVzZXJuYW1lKHVzZXJuYW1lKX1cIilgKTtcbiAgfVxuXG4gIGNvbnN0IGFxbFF1ZXJ5OiBzdHJpbmcgPSBgRk9SIGN1IElOIHVzZXJzXG4gICAgTEVUIHNlc3Npb24gPSBET0NVTUVOVChcIiR7Zm9ybWF0VXNlcklkfVwiKVxuICAgIEZPUiB1LCBjb25uZWN0aW9uIElOIE9VVEJPVU5EIGN1IGhhc0Nvbm5lY3Rpb25cbiAgICBPUFRJT05TIHtiZnM6IHRydWUsIHVuaXF1ZVZlcnRpY2VzOiBcImdsb2JhbFwiLCB2ZXJ0ZXhDb2xsZWN0aW9uczogXCJ1c2Vyc1wifVxuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICBGSUxURVIgJHtmaWx0ZXJCeS5qb2luKCcgJiYgJyl9XG4gICAgJHtsaW1pdC5hcWx9XG4gICAgUkVUVVJOIERJU1RJTkNUIE1FUkdFKHUsIHske3NlbGVjdE9iamVjdHMuam9pbignLCAnKX19KWA7XG5cbiAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoYXFsUXVlcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpIGFzIHVua25vd24gYXMgVXNlclR5cGVbXSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuXG4gICAgICByZXR1cm4gW10gYXMgVXNlclR5cGVbXTtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWZyZXNoU2Vzc2lvbiA9ICh7ZXhwaXJlcywgdG9rZW59KTogU2Vzc2lvblRva2VuIHwgU2Vzc2lvbkVycm9yID0+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCB7dXNlcklkLCB1c2VybmFtZSwgdXNlckFjY2Vzc30gPSBnZXRTZXNzaW9uKHRva2VuKTtcbiAgICByZXR1cm4gY3JlYXRlVG9rZW4odXNlcklkLCB1c2VybmFtZSwgdXNlckFjY2VzcywgZXhwaXJlcyk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICB0aHJvdyBlcnJvcjsgLy8gUmUtdGhyb3cgdGhlIGVycm9yIGZyb20gZ2V0U2Vzc2lvblxuICB9XG59O1xuXG5leHBvcnQgY29uc3Qgc2lnbkluID0gYXN5bmMgKGNvbnRleHQ6IEFwaUNvbnRleHQsIGFyZ3MpOiBQcm9taXNlPFNlc3Npb25Ub2tlbiB8IG51bGw+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ3NpZ25Jbic7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWV9ID0gY29udGV4dDtcbiAgY29uc3Qge2VtYWlsLCBleHBpcmVzLCBwYXNzd29yZCwgcGhvbmUsIHVzZXJuYW1lfSA9IGFyZ3M7XG4gIGNvbnN0IGZvcm1hdEVtYWlsOiBzdHJpbmcgPSBwYXJzZUVtYWlsKGVtYWlsKTtcbiAgY29uc3QgZm9ybWF0VXNlcm5hbWU6IHN0cmluZyA9IHBhcnNlVXNlcm5hbWUodXNlcm5hbWUpO1xuICBjb25zdCBmb3JtYXRQYXNzd29yZDogc3RyaW5nID0gcGFyc2VQYXNzd29yZChwYXNzd29yZCk7XG4gIGNvbnN0IGZvcm1hdFBob25lOiBzdHJpbmcgPSBwYXJzZVBob25lKHBob25lKTtcbiAgY29uc3QgZm9ybWF0RXhwaXJlczogbnVtYmVyID0gcGFyc2VOdW0oZXhwaXJlcykgfHwgMTU7XG5cbiAgaWYoKCFmb3JtYXRVc2VybmFtZSAmJiAhZm9ybWF0RW1haWwgJiYgIWZvcm1hdFBob25lKSB8fCAhZm9ybWF0UGFzc3dvcmQpIHtcbiAgICB0aHJvdyBsb2dFeGNlcHRpb24oe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHt1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5JTlZBTElEX0FSR1VNRU5UU1xuICAgIH0sIGNvbnRleHQpO1xuICB9XG5cbiAgY29uc3QgZmlsdGVyczogc3RyaW5nW10gPSBbXTtcblxuICBpZihmb3JtYXRFbWFpbCkge1xuICAgIGZpbHRlcnMucHVzaChgdS5lbWFpbCA9PSBcIiR7Zm9ybWF0RW1haWx9XCJgKTtcbiAgfVxuXG4gIGlmKGZvcm1hdFBob25lKSB7XG4gICAgZmlsdGVycy5wdXNoKGB1LnBob25lID09ICR7Zm9ybWF0UGhvbmV9YCk7XG4gIH1cblxuICBpZihmb3JtYXRVc2VybmFtZSkge1xuICAgIGZpbHRlcnMucHVzaChgdS51c2VybmFtZSA9PSBcIiR7Zm9ybWF0VXNlcm5hbWV9XCJgKTtcbiAgfVxuXG4gIGNvbnN0IGNoZWNrUXVlcnk6IHN0cmluZyA9IGBGT1IgdSBJTiB1c2Vyc1xuICAgIEZJTFRFUiAke2ZpbHRlcnMuam9pbignIHx8ICcpfVxuICAgIExJTUlUIDFcbiAgICBSRVRVUk4gdWA7XG5cbiAgbGV0IGNoZWNrVXNlcjogVXNlclR5cGU7XG5cbiAgdHJ5IHtcbiAgICBjaGVja1VzZXIgPSBhd2FpdCB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGNoZWNrUXVlcnkpLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICB0aHJvdyBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge3VzZXJuYW1lOiBmb3JtYXRVc2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgfVxuXG4gIGlmKCFjaGVja1VzZXIpIHtcbiAgICB0aHJvdyBsb2dFeGNlcHRpb24oe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHt1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5JTlZBTElEX0FVVEhFTlRJQ0FUSU9OXG4gICAgfSwgY29udGV4dCk7XG4gIH1cblxuICBjb25zdCB7X2tleTogdXNlcklkLCBwYXNzd29yZDogdmFsaWRQYXNzd29yZCwgc2FsdCwgdXNlckFjY2Vzc30gPSBjaGVja1VzZXIgYXMgVXNlclR5cGU7XG4gIGNvbnN0IGF1dGhQYXNzd29yZDogc3RyaW5nID0gY3JlYXRlUGFzc3dvcmQoZm9ybWF0UGFzc3dvcmQsIHNhbHQpO1xuXG4gIGNvbnNvbGUubG9nKHtcbiAgICBjcmVhdGVQYXNzd29yZCxcbiAgICBhdXRoUGFzc3dvcmQsXG4gICAgdmFsaWRQYXNzd29yZCxcbiAgICBmb3JtYXRQYXNzd29yZCxcbiAgICBzYWx0XG4gIH0pO1xuXG4gIGlmKHZhbGlkUGFzc3dvcmQgIT09IGF1dGhQYXNzd29yZCkge1xuICAgIHRocm93IGxvZ0V4Y2VwdGlvbih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge3VzZXJBY2Nlc3MsIHVzZXJJZCwgdXNlcm5hbWV9LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuSU5WQUxJRF9BVVRIRU5USUNBVElPTlxuICAgIH0sIGNvbnRleHQpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCB0b2tlbiA9IGNyZWF0ZVRva2VuKHVzZXJJZCB8fCAnJywgdXNlcm5hbWUgfHwgJycsIHVzZXJBY2Nlc3MsIGZvcm1hdEV4cGlyZXMpO1xuXG4gICAgcmV0dXJuIHRva2VuO1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgdGhyb3cgbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHt1c2VySWQsIHVzZXJuYW1lfSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3Qgc2lnbk91dCA9IGFzeW5jIChjb250ZXh0OiBBcGlDb250ZXh0KTogUHJvbWlzZTxib29sZWFuPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdzaWduT3V0JztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZSwgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkLCB1c2VybmFtZX0gPSB7fX0gPSBjb250ZXh0O1xuICBjb25zdCB1c2VyRG9jSWQ6IHN0cmluZyA9IGB1c2Vycy8ke3Nlc3Npb25JZH1gO1xuXG4gIGNvbnN0IHVwZGF0ZSA9IHtcbiAgICBsYXN0T25saW5lOiBEYXRlLm5vdygpLFxuICAgIHNlc3Npb25JZDogbnVsbFxuICB9O1xuICBjb25zdCBzZXNzaW9uUXVlcnk6IEFxbFF1ZXJ5ID0gYXFsYExFVCB1ID0gRE9DVU1FTlQoJHt1c2VyRG9jSWR9KVxuICAgIFVQREFURSB1IFdJVEggJHt1cGRhdGV9IElOIHVzZXJzXG4gICAgTElNSVQgMVxuICAgIFJFVFVSTiBORVdgO1xuXG4gIHRyeSB7XG4gICAgYXdhaXQgdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShzZXNzaW9uUXVlcnkpLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge3VzZXJJZDogc2Vzc2lvbklkLCB1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEFjdGl2ZVVzZXJDb3VudCA9IChjb250ZXh0OiBBcGlDb250ZXh0KTogUHJvbWlzZTxudW1iZXI+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2dldEFjdGl2ZVVzZXJDb3VudCc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWV9ID0gY29udGV4dDtcbiAgY29uc3QgY291bnRRdWVyeTogQXFsUXVlcnkgPSBhcWxgTEVUIGRvY3MgPSAoXG4gICAgRk9SIHUgSU4gdXNlcnNcbiAgICBGSUxURVIgdS5hY3RpdmUgPT0gdHJ1ZVxuICAgIFJFVFVSTiB1XG4gIClcbiAgUkVUVVJOIExFTkdUSChkb2NzKWA7XG5cbiAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoY291bnRRdWVyeSlcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKVxuICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgIHRocm93IGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRVc2VyQnlUb2tlbiA9IChjb250ZXh0OiBBcGlDb250ZXh0LCB0b2tlbjogc3RyaW5nKTogUHJvbWlzZTxVc2VyVHlwZT4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnZ2V0VXNlckJ5VG9rZW4nO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHt1c2VySWR9ID0gZ2V0U2Vzc2lvbih0b2tlbik7XG4gIGNvbnN0IHVzZXJEb2NJZCA9IHBhcnNlQXJhbmdvSWQoYHVzZXJzLyR7dXNlcklkfWApO1xuICBjb25zdCBhcWxRdWVyeTogQXFsUXVlcnkgPSBhcWxgTEVUIHUgPSBET0NVTUVOVChcIiR7dXNlckRvY0lkfVwiKSBSRVRVUk4gdWA7XG5cbiAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSlcbiAgICAucXVlcnkoYXFsUXVlcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgdGhyb3cgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICBwYXJhbXM6IHt1c2VySWR9LFxuICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICAgIH0pO1xufTsiXSwKICAibWFwcGluZ3MiOiAiQUFJQSxPQUFRLFlBQUFBLE1BQWUsK0JBQ3ZCLE9BQ0UsY0FBQUMsRUFDQSxrQkFBQUMsRUFDQSxpQkFBQUMsRUFDQSxhQUFBQyxFQUNBLGNBQUFDLEVBQ0EsaUJBQUFDLEVBQ0EsY0FBQUMsRUFDQSxpQkFBQUMsTUFDSywrQkFDUCxPQUFRLE9BQUFDLE1BQVUsV0FDbEIsT0FBUSxZQUFBQyxNQUFlLFFBQ3ZCLE9BQU9DLE1BQVksU0FFbkIsT0FBUSxhQUFBQyxNQUFnQiw2QkFDeEIsT0FBUSxVQUFBQyxNQUFhLGVBQ3JCLE9BQVEsY0FBQUMsTUFBb0MsMEJBQzVDLE9BQVEs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SWQiLCAicGFyc2VDaGFyIiwgInBhcnNlRW1haWwiLCAicGFyc2VQYXNzd29yZCIsICJwYXJzZVBob25lIiwgInBhcnNlVXNlcm5hbWUiLCAiYXFsIiwgIkRhdGVUaW1lIiwgIlN0cmlwZSIsICJwYXJzZVVzZXIiLCAiQ29uZmlnIiwgIkVycm9yVHlwZXMiLCAibG9nRXJyb3IiLCAibG9nRXhjZXB0aW9uIiwgImdldERvY0lkIiwgImdldExpbWl0IiwgInNlbGVjdFJlYWN0aW9uQ291bnRCeVR5cGUiLCAidXNlRGIiLCAiZGV0ZWN0TGFuZ3VhZ2UiLCAiZ2V0U2Vzc2lvbiIsICJzZXRTZXNzaW9uIiwgInNlbmRFbWFpbCIsICJzZW5kU21zIiwgImV2ZW50Q2F0ZWdvcnkiLCAiU1RSSVBFX0FQSV9WRVJTSU9OIiwgIlVzZXJBY2Nlc3MiLCAiY3JlYXRlVG9rZW4iLCAidXNlcklkIiwgInVzZXJuYW1lIiwgInVzZXJBY2Nlc3MiLCAiZXhwaXJlc0luTWludXRlcyIsICJub3ciLCAic2Vzc2lvbkV4cGlyZXMiLCAiaWF0IiwgImV4cCIsICJ0b2tlbiIsICJnZXRVc2VyT3B0aW9uYWwiLCAiZmllbGRzIiwgInNlbGVjdHMiLCAiZmllbGQiLCAicGFyc2VVc2VyT3B0aW9ucyIsICJvcHRpb25zIiwgImZyb20iLCAidG8iLCAibGltaXQiLCAiYWRkVXNlciIsICJjb250ZXh0IiwgInVzZXIiLCAiYWN0aW9uIiwgImRhdGFiYXNlTmFtZSIsICJsYW5ndWFnZUNvbnRleHQiLCAiX2NvbmZpcm0iLCAibmV3VXNlciIsICJlbWFpbCIsICJwYXNzd29yZCIsICJwaG9uZSIsICJfa2V5IiwgIl9pZCIsICJpbnNlcnRVc2VyIiwgInNhbHQiLCAiZW5jcnlwdGVkUGFzc3dvcmQiLCAiZmlsdGVycyIsICJjaGVja1F1ZXJ5IiwgImN1cnNvciIsICJlcnJvciIsICJwaG9uZUNvdW50cnlDb2RlIiwgImxvY2FsZSIsICJ2ZXJpZmllZEVtYWlsQ29kZSIsICJ2ZXJpZmllZFNtc0NvZGUiLCAiaW5zZXJ0IiwgImluc2VydFF1ZXJ5IiwgInVwZGF0ZVVzZXIiLCAidXBkYXRlZFVzZXIiLCAidGFncyIsICJ1cGRhdGUiLCAiaWQiLCAidXNlclF1ZXJ5IiwgImRhdGFiYXNlIiwgInRhZ0NvbGxlY3Rpb24iLCAidGFnRG9jSWQiLCAibmFtZSIsICJ0YWdRdWVyeSIsICJ0YWdFZGdlIiwgImVkZ2UiLCAiZm9yZ290UGFzc3dvcmQiLCAiYXFsUXVlcnkiLCAidmVyaWZpZWRFbWFpbCIsICJ2ZXJpZmllZFBob25lIiwgImNvZGVFeHBpcmVzIiwgImNvZGUiLCAidXNlckRvY0lkIiwgInVwZGF0ZVF1ZXJ5IiwgInJlc2V0UGFzc3dvcmQiLCAidHlwZSIsICJmb3JtYXRQYXNzd29yZCIsICJ2ZXJpZmllZEVtYWlsRXhwaXJlcyIsICJ2ZXJpZmllZFBob25lRXhwaXJlcyIsICJjb25maXJtQ29kZSIsICJ2YWx1ZSIsICJpc1NtcyIsICJmb3JtYXR0ZWRWYWx1ZSIsICJkZWxldGVVc2VyIiwgInN0cmlwZUNsaWVudCIsICJkZWxldGVkVXNlciIsICJkZWFjdGl2YXRlVXNlciIsICJnZXREaXNwbGF5TmFtZSIsICJmaXJzdCIsICJsYXN0IiwgImZ1bGxuYW1lIiwgImdldFNlc3Npb25Vc2VyIiwgInNlc3Npb25JZCIsICJzZWxlY3RPYmplY3RzIiwgInNlbGVjdFF1ZXJpZXMiLCAiZ2V0VXNlciIsICJnZXRVc2VycyIsICJmaWx0ZXJCeSIsICJnZXRVc2Vyc0J5UmVhY3Rpb25zIiwgInJlYWN0aW9ucyIsICJmb3JtYXRSZWFjdGlvbnMiLCAicmVhY3Rpb25OYW1lIiwgImZvcm1hdFNlc3Npb25JZCIsICJmb3JtYXRVc2VybmFtZSIsICJnZXRVc2Vyc0J5VGFncyIsICJmb3JtYXRUYWdzIiwgImxpc3QiLCAidGFnTmFtZSIsICJnZXRVc2Vyc0J5TGF0ZXN0IiwgImZpbHRlciIsICJnZXRVc2Vyc0J5Q29ubmVjdGlvbiIsICJmb3JtYXRVc2VySWQiLCAicmVmcmVzaFNlc3Npb24iLCAiZXhwaXJlcyIsICJzaWduSW4iLCAiYXJncyIsICJmb3JtYXRFbWFpbCIsICJmb3JtYXRQaG9uZSIsICJmb3JtYXRFeHBpcmVzIiwgImNoZWNrVXNlciIsICJ2YWxpZFBhc3N3b3JkIiwgImF1dGhQYXNzd29yZCIsICJzaWduT3V0IiwgInNlc3Npb25RdWVyeSIsICJnZXRBY3RpdmVVc2VyQ291bnQiLCAiY291bnRRdWVyeSIsICJnZXRVc2VyQnlUb2tlbiJdCn0K
|
|
775
|
+
RETURN LENGTH(docs)`;
|
|
776
|
+
return useDb(databaseName).query(countQuery).then((cursor)=>cursor.next()).catch((error)=>{
|
|
777
|
+
throw logError({
|
|
778
|
+
action,
|
|
779
|
+
category: eventCategory,
|
|
780
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
781
|
+
}, error, context);
|
|
782
|
+
});
|
|
783
|
+
};
|
|
784
|
+
export const getUserByToken = (context, token)=>{
|
|
785
|
+
const action = 'getUserByToken';
|
|
786
|
+
const { databaseName } = context;
|
|
787
|
+
const { userId } = getSession(token);
|
|
788
|
+
const userDocId = parseArangoId(`users/${userId}`);
|
|
789
|
+
const aqlQuery = aql`LET u = DOCUMENT("${userDocId}") RETURN u`;
|
|
790
|
+
return useDb(databaseName).query(aqlQuery).then((cursor)=>cursor.next()).catch((error)=>{
|
|
791
|
+
throw logError({
|
|
792
|
+
action,
|
|
793
|
+
category: eventCategory,
|
|
794
|
+
params: {
|
|
795
|
+
userId
|
|
796
|
+
},
|
|
797
|
+
value: ErrorTypes.DATABASE_ERROR
|
|
798
|
+
}, error, context);
|
|
799
|
+
});
|
|
800
|
+
};
|
|
801
|
+
|
|
802
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L3JlYWt0b3Ivc3JjL2FjdGlvbnMvdXNlcnMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTktUHJlc2VudCwgTml0cm9nZW4gTGFicywgSW5jLlxuICogQ29weXJpZ2h0cyBsaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSB0aGUgYWNjb21wYW55aW5nIExJQ0VOU0UgZmlsZSBmb3IgdGVybXMuXG4gKi9cbmltcG9ydCB7cGFyc2VOdW19IGZyb20gJ0BubGFicy91dGlscy9wYXJzZXJzL251bWJlcnMnO1xuaW1wb3J0IHtcbiAgY3JlYXRlSGFzaCxcbiAgY3JlYXRlUGFzc3dvcmQsXG4gIHBhcnNlQXJhbmdvSWQsXG4gIHBhcnNlQ2hhcixcbiAgcGFyc2VFbWFpbCxcbiAgcGFyc2VQYXNzd29yZCxcbiAgcGFyc2VQaG9uZSxcbiAgcGFyc2VVc2VybmFtZVxufSBmcm9tICdAbmxhYnMvdXRpbHMvcGFyc2Vycy9zdHJpbmdzJztcbmltcG9ydCB7YXFsfSBmcm9tICdhcmFuZ29qcyc7XG5pbXBvcnQge0RhdGVUaW1lfSBmcm9tICdsdXhvbic7XG5pbXBvcnQgU3RyaXBlIGZyb20gJ3N0cmlwZSc7XG5cbmltcG9ydCB7cGFyc2VVc2VyfSBmcm9tICcuLi9hZGFwdGVycy91c2VyQWRhcHRlci5qcyc7XG5pbXBvcnQge0NvbmZpZ30gZnJvbSAnLi4vY29uZmlnLmpzJztcbmltcG9ydCB7RXJyb3JUeXBlcywgdHlwZSBTZXNzaW9uRXJyb3J9IGZyb20gJy4uL3R5cGVzL2Vycm9yLnR5cGVzLmpzJztcbmltcG9ydCB7bG9nRXJyb3IsIGxvZ0V4Y2VwdGlvbn0gZnJvbSAnLi4vdXRpbHMvYW5hbHl0aWNzVXRpbHMuanMnO1xuaW1wb3J0IHtnZXREb2NJZCwgZ2V0TGltaXQsIHNlbGVjdFJlYWN0aW9uQ291bnRCeVR5cGUsIHVzZURifSBmcm9tICcuLi91dGlscy9hcmFuZ29kYlV0aWxzLmpzJztcbmltcG9ydCB7ZGV0ZWN0TGFuZ3VhZ2V9IGZyb20gJy4uL3V0aWxzL2xhbmd1YWdlRGV0ZWN0aW9uLmpzJztcbmltcG9ydCB7Z2V0U2Vzc2lvbiwgc2V0U2Vzc2lvbiwgdHlwZSBTZXNzaW9uVG9rZW59IGZyb20gJy4uL3V0aWxzL3Nlc3Npb25VdGlscy5qcyc7XG5pbXBvcnQge3NlbmRFbWFpbH0gZnJvbSAnLi9lbWFpbC5qcyc7XG5pbXBvcnQge3NlbmRTbXN9IGZyb20gJy4vc21zLmpzJztcblxuaW1wb3J0IHR5cGUge0FxbFF1ZXJ5fSBmcm9tICdhcmFuZ29qcy9hcWwnO1xuaW1wb3J0IHR5cGUge0VkZ2VDb2xsZWN0aW9ufSBmcm9tICdhcmFuZ29qcy9jb2xsZWN0aW9ucyc7XG5pbXBvcnQgdHlwZSB7QXBpQ29udGV4dH0gZnJvbSAnLi4vdHlwZXMvYXV0aC50eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7VXNlcklucHV0LCBVc2VyVHlwZX0gZnJvbSAnLi4vdHlwZXMvdXNlcnMudHlwZXMuanMnO1xuXG5jb25zdCBldmVudENhdGVnb3J5ID0gJ3VzZXJzJztcbmNvbnN0IFNUUklQRV9BUElfVkVSU0lPTiA9ICcyMDI1LTEyLTE1LmNsb3Zlcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXNlck9wdGlvbnMge1xuICByZWFkb25seSBmcm9tPzogbnVtYmVyO1xuICByZWFkb25seSB0bz86IG51bWJlcjtcbiAgcmVhZG9ubHkgdXNlcm5hbWU/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBlbnVtIFVzZXJBY2Nlc3Mge1xuICBERUFDVElWQVRFRCA9IDAsXG4gIEFDVElWRSA9IDEsXG4gIFBSRU1JVU0gPSAyLFxuICBDT05URU5UX0FETUlOID0gMyxcbiAgQURNSU4gPSA0XG59XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVUb2tlbiA9IChcbiAgdXNlcklkOiBzdHJpbmcsXG4gIHVzZXJuYW1lOiBzdHJpbmcgPSAnJyxcbiAgdXNlckFjY2VzczogbnVtYmVyID0gMCxcbiAgZXhwaXJlc0luTWludXRlczogbnVtYmVyID0gMTVcbik6IFNlc3Npb25Ub2tlbiA9PiB7XG4gIGNvbnN0IG5vdzogRGF0ZVRpbWUgPSBEYXRlVGltZS5sb2NhbCgpO1xuICBjb25zdCBzZXNzaW9uRXhwaXJlczogRGF0ZVRpbWUgPSBub3cucGx1cyh7bWludXRlczogZXhwaXJlc0luTWludXRlc30pO1xuICBjb25zdCBpYXQ6IG51bWJlciA9IE1hdGguZmxvb3Iobm93LnRvU2Vjb25kcygpKTtcbiAgY29uc3QgZXhwOiBudW1iZXIgPSBNYXRoLmZsb29yKHNlc3Npb25FeHBpcmVzLnRvU2Vjb25kcygpKTtcbiAgY29uc3QgdG9rZW4gPSBzZXRTZXNzaW9uKHtcbiAgICBleHAsXG4gICAgaWF0LFxuICAgIHVzZXJBY2Nlc3MsXG4gICAgdXNlcklkLFxuICAgIHVzZXJuYW1lXG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgZXhwaXJlczogc2Vzc2lvbkV4cGlyZXMudG9NaWxsaXMoKSxcbiAgICBpc3N1ZWQ6IG5vdy50b01pbGxpcygpLFxuICAgIHRva2VuLFxuICAgIHVzZXJJZCxcbiAgICB1c2VybmFtZVxuICB9O1xufTtcblxuaW50ZXJmYWNlIFNlbGVjdEFjY3VtdWxhdG9yIHtcbiAgb2JqZWN0czogc3RyaW5nW107XG4gIHF1ZXJpZXM6IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgY29uc3QgZ2V0VXNlck9wdGlvbmFsID0gKGZpZWxkczogc3RyaW5nW10gPSBbXSk6IFNlbGVjdEFjY3VtdWxhdG9yID0+XG4gIGZpZWxkcy5yZWR1Y2UoKHNlbGVjdHM6IFNlbGVjdEFjY3VtdWxhdG9yLCBmaWVsZDogc3RyaW5nKSA9PiB7XG4gICAgaWYoZmllbGQuaW5jbHVkZXMoJ0NvdW50JykpIHtcbiAgICAgIHJldHVybiBzZWxlY3RSZWFjdGlvbkNvdW50QnlUeXBlKCd1c2VycycsICd1JywgZmllbGQsIHNlbGVjdHMpO1xuICAgIH1cblxuICAgIHJldHVybiBzZWxlY3RzO1xuICB9LCB7b2JqZWN0czogW10sIHF1ZXJpZXM6IFtdfSk7XG5cbmV4cG9ydCBjb25zdCBwYXJzZVVzZXJPcHRpb25zID0gKG9wdGlvbnM6IFVzZXJPcHRpb25zID0ge30pID0+IHtcbiAgY29uc3Qge1xuICAgIGZyb20gPSAwLFxuICAgIHRvID0gMzBcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGxpbWl0ID0gZ2V0TGltaXQoZnJvbSwgdG8pO1xuXG4gIHJldHVybiB7XG4gICAgLi4ub3B0aW9ucyxcbiAgICBsaW1pdFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGFkZFVzZXIgPSBhc3luYyAoY29udGV4dDogQXBpQ29udGV4dCwgdXNlcjogVXNlcklucHV0KTogUHJvbWlzZTxVc2VyVHlwZSB8IG51bGw+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2FkZFVzZXInO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBsYW5ndWFnZUNvbnRleHR9ID0gY29udGV4dDtcbiAgY29uc3Qge2NvbmZpcm06IF9jb25maXJtLCAuLi5uZXdVc2VyfSA9IHVzZXI7XG4gIGNvbnN0IHtlbWFpbCwgcGFzc3dvcmQsIHBob25lLCB1c2VybmFtZSwgdXNlcklkLCBfa2V5LCBfaWQsIC4uLmluc2VydFVzZXJ9ID0gcGFyc2VVc2VyKG5ld1VzZXIpO1xuICBjb25zdCBoYXNQYXNzd29yZCA9ICEhcGFzc3dvcmQ7XG4gIGNvbnN0IGhhc1VzZXJuYW1lID0gISF1c2VybmFtZSB8fCAhIXBob25lIHx8ICEhZW1haWw7XG5cbiAgaWYoIWhhc1Bhc3N3b3JkIHx8ICFoYXNVc2VybmFtZSkge1xuICAgIGxvZ0V4Y2VwdGlvbih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge3VzZXJuYW1lfSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLklOVkFMSURfQVJHVU1FTlRTXG4gICAgfSwgY29udGV4dCk7XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGhhc2hJZCA9IHVzZXJuYW1lIHx8IHBob25lIHx8IGVtYWlsO1xuICBjb25zdCBzYWx0OiBzdHJpbmcgPSBjcmVhdGVIYXNoKGAke2hhc2hJZH0ke3Bhc3N3b3JkfWAsICcnKTtcbiAgY29uc3QgZW5jcnlwdGVkUGFzc3dvcmQgPSBjcmVhdGVQYXNzd29yZChwYXNzd29yZCwgc2FsdCk7XG4gIGNvbnN0IGZpbHRlcnM6IHN0cmluZ1tdID0gW107XG5cbiAgaWYodXNlcm5hbWUpIHtcbiAgICBmaWx0ZXJzLnB1c2goYHUudXNlcm5hbWUgPT0gXCIke3VzZXJuYW1lfVwiYCk7XG4gIH1cblxuICBpZihlbWFpbCkge1xuICAgIGZpbHRlcnMucHVzaChgdS5lbWFpbCA9PSBcIiR7ZW1haWx9XCJgKTtcbiAgfVxuXG4gIGlmKHBob25lKSB7XG4gICAgZmlsdGVycy5wdXNoKGB1LnBob25lID09ICR7cGhvbmV9YCk7XG4gIH1cblxuICBjb25zdCBjaGVja1F1ZXJ5OiBzdHJpbmcgPSBgRk9SIHUgSU4gdXNlcnNcbiAgICBGSUxURVIgJHtmaWx0ZXJzLmpvaW4oJyB8fCAnKX1cbiAgICBMSU1JVCAxXG4gICAgUkVUVVJOIHVgO1xuXG4gIHRyeSB7XG4gICAgY29uc3QgZXhpc3RpbmdVc2VycyA9IGF3YWl0IHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoY2hlY2tRdWVyeSkudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkpO1xuXG4gICAgaWYoZXhpc3RpbmdVc2Vycy5sZW5ndGgpIHtcbiAgICAgIHRocm93IGxvZ0V4Y2VwdGlvbih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIHBhcmFtczoge1xuICAgICAgICAgIGVtYWlsLFxuICAgICAgICAgIHBob25lLFxuICAgICAgICAgIHVzZXJuYW1lXG4gICAgICAgIH0sXG4gICAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkVYSVNUSU5HX0lURU1cbiAgICAgIH0sIGNvbnRleHQpO1xuICAgIH1cbiAgfSBjYXRjaChlcnJvcikge1xuICAgIHRocm93IGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7ZW1haWwsIHBob25lLCB1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgfVxuXG4gIGNvbnN0IHBob25lQ291bnRyeUNvZGUgPSBwaG9uZT8ucmVwbGFjZSgvXFxEL2csICcnKS5zdWJzdHJpbmcoMCwgMyk7XG4gIGNvbnN0IGxvY2FsZSA9IGRldGVjdExhbmd1YWdlKHtcbiAgICAuLi5sYW5ndWFnZUNvbnRleHQsXG4gICAgcGhvbmVDb3VudHJ5Q29kZTogcGhvbmVDb3VudHJ5Q29kZSB8fCAnJyxcbiAgICB1c2VyUHJlZmVyZW5jZTogaW5zZXJ0VXNlci5sb2NhbGUgfHwgJ2VuJ1xuICB9KTtcbiAgY29uc3QgdmVyaWZpZWRFbWFpbENvZGU6IG51bWJlciA9IE1hdGguZmxvb3IoMTAwMDAwICsgKE1hdGgucmFuZG9tKCkgKiA5MDAwMDApKTtcbiAgY29uc3QgdmVyaWZpZWRTbXNDb2RlOiBudW1iZXIgPSBNYXRoLmZsb29yKDEwMDAwMCArIChNYXRoLnJhbmRvbSgpICogOTAwMDAwKSk7XG5cbiAgY29uc3QgaW5zZXJ0OiBVc2VyVHlwZSA9IHtcbiAgICAuLi5pbnNlcnRVc2VyLFxuICAgIF9rZXk6IGNyZWF0ZUhhc2godXNlcm5hbWUpLFxuICAgIGFkZGVkOiBEYXRlLm5vdygpLFxuICAgIGVtYWlsLFxuICAgIGxvY2FsZSxcbiAgICBtb2RpZmllZDogRGF0ZS5ub3coKSxcbiAgICBwYXNzd29yZDogZW5jcnlwdGVkUGFzc3dvcmQsXG4gICAgcGhvbmUsXG4gICAgc2FsdCxcbiAgICB1c2VyQWNjZXNzOiAxLFxuICAgIHVzZXJuYW1lLFxuICAgIHZlcmlmaWVkRW1haWw6IGZhbHNlLFxuICAgIHZlcmlmaWVkRW1haWxDb2RlLFxuICAgIHZlcmlmaWVkUGhvbmU6IGZhbHNlLFxuICAgIHZlcmlmaWVkU21zQ29kZVxuICB9O1xuXG4gIGNvbnN0IGluc2VydFF1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBJTlNFUlQgJHtpbnNlcnR9IElOIHVzZXJzIFJFVFVSTiBORVdgO1xuXG4gIHJldHVybiBhd2FpdCB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGluc2VydFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgdGhyb3cgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICBwYXJhbXM6IHt1c2VybmFtZX0sXG4gICAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgICB9LCBlcnJvciwgY29udGV4dCk7XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgdXBkYXRlVXNlciA9IGFzeW5jIChjb250ZXh0OiBBcGlDb250ZXh0LCB1c2VyOiBVc2VyVHlwZSk6IFByb21pc2U8VXNlclR5cGU+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ3VwZGF0ZVVzZXInO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHVwZGF0ZWRVc2VyID0gcGFyc2VVc2VyKHVzZXIpO1xuICBjb25zdCB7X2tleSwgX2lkLCB0YWdzID0gW10sIC4uLnVwZGF0ZX0gPSB1cGRhdGVkVXNlcjtcbiAgY29uc3Qge2lkfSA9IHVwZGF0ZWRVc2VyO1xuXG4gIGNvbnN0IHVzZXJRdWVyeTogQXFsUXVlcnkgPSBhcWxgTEVUIHUgPSBET0NVTUVOVCgke2lkfSlcbiAgICBVUERBVEUgdSBXSVRIICR7dXBkYXRlfSBJTiB1c2Vyc1xuICAgIFJFVFVSTiBORVdgO1xuICB0cnkge1xuICAgIGNvbnN0IGRhdGFiYXNlID0gdXNlRGIoZGF0YWJhc2VOYW1lKTtcbiAgICBjb25zdCB1cGRhdGVkVXNlciA9IGF3YWl0IGRhdGFiYXNlLnF1ZXJ5KHVzZXJRdWVyeSkudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKTtcbiAgICBjb25zdCB0YWdDb2xsZWN0aW9uOiBFZGdlQ29sbGVjdGlvbiA9IGRhdGFiYXNlLmNvbGxlY3Rpb24oJ2lzVGFnZ2VkJyk7XG5cbiAgICBhd2FpdCBQcm9taXNlLmFsbCh0YWdzLm1hcCgoe2lkOiB0YWdEb2NJZCwgbmFtZX0pID0+IHtcbiAgICAgIGNvbnN0IHRhZ1F1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBGT1IgaXQgSU4gaXNUYWdnZWRcbiAgICAgICAgRklMVEVSIGl0Ll9mcm9tID09ICR7dGFnRG9jSWR9ICYmIGl0Ll90byA9PSAke2lkfSAmJiBpdC5uYW1lID09ICR7bmFtZX1cbiAgICAgICAgTElNSVQgMVxuICAgICAgICBSRVRVUk4gaXRgO1xuXG4gICAgICByZXR1cm4gZGF0YWJhc2UucXVlcnkodGFnUXVlcnkpXG4gICAgICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgICAgIC50aGVuKCh0YWdFZGdlKSA9PiB7XG4gICAgICAgICAgaWYoISF0YWdFZGdlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGFnRWRnZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBlZGdlID0ge1xuICAgICAgICAgICAgX2Zyb206IHRhZ0RvY0lkLFxuICAgICAgICAgICAgX2tleTogY3JlYXRlSGFzaChgaXNUYWdnZWQtJHt0YWdEb2NJZH0tJHtpZH1gKSxcbiAgICAgICAgICAgIF90bzogaWQsXG4gICAgICAgICAgICBhZGRlZDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgIG5hbWVcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgcmV0dXJuIHRhZ0NvbGxlY3Rpb24uc2F2ZShlZGdlLCB7cmV0dXJuTmV3OiB0cnVlfSkudGhlbigoKSA9PiBlZGdlKTtcbiAgICAgICAgfSk7XG4gICAgfSkpO1xuXG4gICAgcmV0dXJuIHVwZGF0ZWRVc2VyO1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgdGhyb3cgbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHt1c2VyfSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgZm9yZ290UGFzc3dvcmQgPSBhc3luYyAoY29udGV4dDogQXBpQ29udGV4dCwge2VtYWlsLCBwaG9uZSwgdXNlcm5hbWV9KTogUHJvbWlzZTxib29sZWFuPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdmb3Jnb3RQYXNzd29yZCc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWV9ID0gY29udGV4dDtcbiAgY29uc3QgYXFsUXVlcnk6IEFxbFF1ZXJ5ID0gYXFsYEZPUiB1IElOIHVzZXJzXG4gICAgRklMVEVSIHUuZW1haWwgPT0gJHtlbWFpbH0gfHwgdS5waG9uZSA9PSAke3Bob25lfSB8fCB1LnVzZXJuYW1lID09ICR7dXNlcm5hbWV9XG4gICAgTElNSVQgMVxuICAgIFJFVFVSTiB1YDtcblxuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgICAgLnRoZW4oYXN5bmMgKGN1cnNvcikgPT4ge1xuICAgICAgICBjb25zdCB1c2VyID0gY3Vyc29yLm5leHQoKTtcblxuICAgICAgICBpZih1c2VyKSB7XG4gICAgICAgICAgY29uc3Qge2VtYWlsLCBwaG9uZSwgdmVyaWZpZWRFbWFpbCwgdmVyaWZpZWRQaG9uZX0gPSB1c2VyIGFzIFVzZXJUeXBlO1xuICAgICAgICAgIGNvbnN0IGNvZGVFeHBpcmVzID0gMTAwMCAqIDYwICogMTU7IC8vIDE1IG1pbnV0ZXNcbiAgICAgICAgICBjb25zdCBjb2RlID0gTWF0aC5mbG9vcigxMDAwMDAgKyAoTWF0aC5yYW5kb20oKSAqIDkwMDAwMCkpO1xuICAgICAgICAgIGNvbnN0IHVzZXJEb2NJZCA9IGdldERvY0lkKCd1c2VycycsIHVzZXIpO1xuICAgICAgICAgIGxldCB1cGRhdGU7XG5cbiAgICAgICAgICBpZihlbWFpbCAmJiB2ZXJpZmllZEVtYWlsKSB7XG4gICAgICAgICAgICBzZW5kRW1haWwoe1xuICAgICAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgICAgICB0ZXh0OiBgWW91ciBjb2RlIGlzICR7Y29kZX1gXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHVwZGF0ZSA9IHt2ZXJpZmllZEVtYWlsQ29kZTogY29kZSwgdmVyaWZpZWRFbWFpbEV4cGlyZXM6IGNvZGVFeHBpcmVzfTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZihwaG9uZSAmJiB2ZXJpZmllZFBob25lKSB7XG4gICAgICAgICAgICBzZW5kU21zKHtcbiAgICAgICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICAgICAgdGV4dDogYFlvdXIgY29kZSBpcyAke2NvZGV9YFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB1cGRhdGUgPSB7dmVyaWZpZWRQaG9uZUV4cGlyZXM6IGNvZGVFeHBpcmVzLCB2ZXJpZmllZFNtc0NvZGU6IGNvZGV9O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmKHVwZGF0ZS52ZXJpZmllZEVtYWlsQ29kZSB8fCB1cGRhdGUudmVyaWZpZWRTbXNDb2RlKSB7XG4gICAgICAgICAgICBjb25zdCB1cGRhdGVRdWVyeTogQXFsUXVlcnkgPSBhcWxgVVBEQVRFICR7dXNlckRvY0lkfSBXSVRIICR7dXBkYXRlfSBJTiB1c2Vyc2A7XG5cbiAgICAgICAgICAgIGF3YWl0IHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkodXBkYXRlUXVlcnkpO1xuXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9KTtcbiAgfSBjYXRjaChlcnJvcikge1xuICAgIGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7ZW1haWwsIHBob25lLCB1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IHJlc2V0UGFzc3dvcmQgPSBhc3luYyAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHtcbiAgICBjb2RlLFxuICAgIHBhc3N3b3JkLFxuICAgIHR5cGUsXG4gICAgdXNlcm5hbWVcbiAgfToge1xuICAgIGNvZGU6IG51bWJlcjtcbiAgICBwYXNzd29yZDogc3RyaW5nO1xuICAgIHR5cGU6ICdwaG9uZScgfCAnZW1haWwnO1xuICAgIHVzZXJuYW1lOiBzdHJpbmc7XG4gIH1cbik6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAncmVzZXRQYXNzd29yZCc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWV9ID0gY29udGV4dDtcbiAgY29uc3QgZm9ybWF0UGFzc3dvcmQ6IHN0cmluZyA9IHBhcnNlUGFzc3dvcmQocGFzc3dvcmQpO1xuICBjb25zdCBhcWxRdWVyeTogQXFsUXVlcnkgPSBhcWxgRk9SIHUgSU4gdXNlcnNcbiAgICBGSUxURVIgdS51c2VybmFtZSA9PSAke3VzZXJuYW1lfVxuICAgIExJTUlUIDFcbiAgICBSRVRVUk4gdWA7XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gYXdhaXQgdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRdWVyeSlcbiAgICAgIC50aGVuKGFzeW5jIChjdXJzb3IpID0+IHtcbiAgICAgICAgY29uc3QgdXNlciA9IGN1cnNvci5uZXh0KCk7XG5cbiAgICAgICAgaWYodXNlcikge1xuICAgICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgIF9pZDogdXNlckRvY0lkLFxuICAgICAgICAgICAgc2FsdCxcbiAgICAgICAgICAgIHZlcmlmaWVkRW1haWxDb2RlLFxuICAgICAgICAgICAgdmVyaWZpZWRFbWFpbEV4cGlyZXMgPSAwLFxuICAgICAgICAgICAgdmVyaWZpZWRTbXNDb2RlLFxuICAgICAgICAgICAgdmVyaWZpZWRQaG9uZUV4cGlyZXMgPSAwXG4gICAgICAgICAgfSA9IHVzZXIgYXMgVXNlclR5cGU7XG4gICAgICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgICBsZXQgdXBkYXRlO1xuXG4gICAgICAgICAgc3dpdGNoKHR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgJ2VtYWlsJzpcbiAgICAgICAgICAgICAgaWYoY29kZSA9PT0gdmVyaWZpZWRFbWFpbENvZGUgJiYgdmVyaWZpZWRFbWFpbEV4cGlyZXMgPiBub3cpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXNzd29yZDogc3RyaW5nID0gY3JlYXRlUGFzc3dvcmQoZm9ybWF0UGFzc3dvcmQsIHNhbHQpO1xuICAgICAgICAgICAgICAgIHVwZGF0ZSA9IHtwYXNzd29yZH07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdwaG9uZSc6XG4gICAgICAgICAgICAgIGlmKGNvZGUgPT09IHZlcmlmaWVkU21zQ29kZSAmJiB2ZXJpZmllZFBob25lRXhwaXJlcyA+IG5vdykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhc3N3b3JkOiBzdHJpbmcgPSBjcmVhdGVQYXNzd29yZChmb3JtYXRQYXNzd29yZCwgc2FsdCk7XG4gICAgICAgICAgICAgICAgdXBkYXRlID0ge3Bhc3N3b3JkfTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZih1cGRhdGUpIHtcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZVF1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBVUERBVEUgJHt1c2VyRG9jSWR9IFdJVEggJHt1cGRhdGV9IElOIHVzZXJzYDtcblxuICAgICAgICAgICAgYXdhaXQgdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeSh1cGRhdGVRdWVyeSk7XG5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0pO1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHt1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGNvbmZpcm1Db2RlID0gYXN5bmMgKFxuICBjb250ZXh0OiBBcGlDb250ZXh0LFxuICB7XG4gICAgY29kZSxcbiAgICB0eXBlLFxuICAgIHZhbHVlXG4gIH06IHtcbiAgICBjb2RlOiBudW1iZXI7XG4gICAgdHlwZTogJ3NtcycgfCAnZW1haWwnO1xuICAgIHZhbHVlOiBzdHJpbmc7XG4gIH1cbik6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnY29uZmlybUNvZGUnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lfSA9IGNvbnRleHQ7XG4gIGNvbnN0IGlzU21zID0gdHlwZSA9PT0gJ3Ntcyc7XG4gIGNvbnN0IGZvcm1hdHRlZFZhbHVlID0gaXNTbXMgPyBwYXJzZVBob25lKHZhbHVlKSA6IHBhcnNlRW1haWwodmFsdWUpO1xuICBjb25zdCBmaWx0ZXJCeVR5cGUgPSBpc1Ntc1xuICAgID8gYEZJTFRFUiB1LnBob25lID09IFwiJHtmb3JtYXR0ZWRWYWx1ZX1cIiAmJiB1LnZlcmlmaWVkU21zQ29kZSA9PSAke2NvZGV9YFxuICAgIDogYEZJTFRFUiB1LmVtYWlsID09IFwiJHtmb3JtYXR0ZWRWYWx1ZX1cIiAmJiB1LnZlcmlmaWVkRW1haWxDb2RlID09ICR7Y29kZX1gO1xuICBjb25zdCBhcWxRdWVyeTogc3RyaW5nID0gYEZPUiB1IElOIHVzZXJzXG4gICAgJHtmaWx0ZXJCeVR5cGV9XG4gICAgTElNSVQgMVxuICAgIFJFVFVSTiB1YDtcblxuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAgIC50aGVuKCh1c2VyKSA9PiB7XG4gICAgICAgIGlmKHVzZXIpIHtcbiAgICAgICAgICBjb25zdCB1cGRhdGVkVXNlciA9IGlzU21zXG4gICAgICAgICAgICA/IHt2ZXJpZmllZFBob25lOiB0cnVlLCB2ZXJpZmllZFNtc0NvZGU6IDB9XG4gICAgICAgICAgICA6IHt2ZXJpZmllZEVtYWlsOiB0cnVlLCB2ZXJpZmllZEVtYWlsQ29kZTogMH07XG4gICAgICAgICAgY29uc3QgYXFsUXVlcnk6IEFxbFF1ZXJ5ID0gYXFsYFVQREFURSAke3VzZXIuX2tleX0gV0lUSCAke3VwZGF0ZWRVc2VyfSBJTiB1c2Vyc2A7XG5cbiAgICAgICAgICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRdWVyeSlcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHRydWUpXG4gICAgICAgICAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICBsb2dFcnJvcih7XG4gICAgICAgICAgICAgICAgYWN0aW9uLFxuICAgICAgICAgICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICAgICAgICAgIHBhcmFtczoge2NvZGUsIHR5cGUsIHZhbHVlOiBmb3JtYXR0ZWRWYWx1ZX0sXG4gICAgICAgICAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgICAgICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuXG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge2NvZGUsIHR5cGUsIHZhbHVlOiBmb3JtYXR0ZWRWYWx1ZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuZXhwb3J0IGNvbnN0IGRlbGV0ZVVzZXIgPSAoY29udGV4dDogQXBpQ29udGV4dCwgdXNlcjogVXNlclR5cGUpOiBQcm9taXNlPFVzZXJUeXBlPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdkZWxldGVVc2VyJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZX0gPSBjb250ZXh0O1xuICBjb25zdCB7aWR9ID0gcGFyc2VVc2VyKHVzZXIpO1xuXG4gIGNvbnN0IGFxbFF1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBMRVQgdSA9IERPQ1VNRU5UKCR7aWR9KVxuICAgIFJFTU9WRSB1IElOIHVzZXJzXG4gICAgUkVUVVJOIE9MRGA7XG5cbiAgY29uc3Qgc3RyaXBlQ2xpZW50ID0gbmV3IFN0cmlwZShDb25maWcuZ2V0KCdzdHJpcGUudG9rZW4nKSwge2FwaVZlcnNpb246IFNUUklQRV9BUElfVkVSU0lPTiwgdHlwZXNjcmlwdDogdHJ1ZX0pO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgLnRoZW4oKGRlbGV0ZWRVc2VyKSA9PiBzdHJpcGVDbGllbnQuY3VzdG9tZXJzLmRlbChkZWxldGVkVXNlcj8uc3RyaXBlQ3VzdG9tZXJJZClcbiAgICAgIC50aGVuKCgpID0+IHN0cmlwZUNsaWVudC5hY2NvdW50cy5kZWwoZGVsZXRlZFVzZXI/LnN0cmlwZUFjY291bnRJZCkpXG4gICAgICAudGhlbigoKSA9PiBkZWxldGVkVXNlcikpXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7aWR9LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICB9LCBlcnJvciwgY29udGV4dCkpO1xufTtcblxuZXhwb3J0IGNvbnN0IGRlYWN0aXZhdGVVc2VyID0gKGNvbnRleHQ6IEFwaUNvbnRleHQsIHVzZXI6IFVzZXJUeXBlKTogUHJvbWlzZTxVc2VyVHlwZT4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnZGVsZXRlJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZX0gPSBjb250ZXh0O1xuICBjb25zdCB7aWR9ID0gcGFyc2VVc2VyKHVzZXIpO1xuICBjb25zdCB1cGRhdGVkOiBVc2VyVHlwZSA9IHtcbiAgICB1c2VyQWNjZXNzOiAwXG4gIH07XG4gIGNvbnN0IGFxbFF1ZXJ5OiBBcWxRdWVyeSA9IGFxbGBVUERBVEUgJHtpZH0gV0lUSCAke3VwZGF0ZWR9IElOIHVzZXJzIExJTUlUIDEgUkVUVVJOIE5FV2A7XG5cbiAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoYXFsUXVlcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgdGhyb3cgbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHtpZH0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0RGlzcGxheU5hbWUgPSAodXNlcjogVXNlclR5cGUpOiBzdHJpbmcgPT4ge1xuICBjb25zdCB7Zmlyc3QsIGxhc3QsIG5hbWUgPSAnJywgdXNlcm5hbWUgPSAnJ30gPSB1c2VyO1xuICBjb25zdCBmdWxsbmFtZSA9IChbZmlyc3QsIGxhc3RdKS5qb2luKCcgJykudHJpbSgpO1xuXG4gIGlmKG5hbWUpIHtcbiAgICByZXR1cm4gbmFtZTtcbiAgfSBlbHNlIGlmKGZ1bGxuYW1lICE9PSAnJykge1xuICAgIHJldHVybiBmdWxsbmFtZTtcbiAgfSBlbHNlIGlmKHVzZXJuYW1lKSB7XG4gICAgcmV0dXJuIHVzZXJuYW1lO1xuICB9XG5cbiAgcmV0dXJuICdVbmtub3duJztcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRTZXNzaW9uVXNlciA9IChjb250ZXh0OiBBcGlDb250ZXh0KTogUHJvbWlzZTxVc2VyVHlwZT4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnZ2V0U2Vzc2lvblVzZXInO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHMsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZCwgdXNlcm5hbWV9ID0ge319ID0gY29udGV4dDtcbiAgY29uc3Qge29iamVjdHM6IHNlbGVjdE9iamVjdHMsIHF1ZXJpZXM6IHNlbGVjdFF1ZXJpZXN9ID0gZ2V0VXNlck9wdGlvbmFsKGZpZWxkcyk7XG4gIGNvbnN0IGZvcm1hdFNlc3Npb25JZCA9IHBhcnNlQXJhbmdvSWQoYHVzZXJzLyR7c2Vzc2lvbklkfWApO1xuXG4gIGNvbnN0IGFxbFF1ZXJ5OiBzdHJpbmcgPSBgTEVUIHUgPSBET0NVTUVOVChcIiR7Zm9ybWF0U2Vzc2lvbklkfVwiKVxuICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gIFJFVFVSTiBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkgYXMgdW5rbm93biBhcyBVc2VyVHlwZSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgdGhyb3cgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICBwYXJhbXM6IHt1c2VySWQ6IHNlc3Npb25JZCwgdXNlcm5hbWV9LFxuICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICAgIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFVzZXIgPSAoY29udGV4dDogQXBpQ29udGV4dCwgdXNlcjogVXNlclR5cGUpOiBQcm9taXNlPFVzZXJUeXBlPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdnZXRVc2VyJztcbiAgY29uc3Qge2VtYWlsLCBpZCwgcGhvbmUsIHVzZXJJZCwgdXNlcm5hbWV9ID0gcGFyc2VVc2VyKHVzZXIpO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHN9ID0gY29udGV4dDtcbiAgY29uc3Qge29iamVjdHM6IHNlbGVjdE9iamVjdHMsIHF1ZXJpZXM6IHNlbGVjdFF1ZXJpZXN9ID0gZ2V0VXNlck9wdGlvbmFsKGZpZWxkcyk7XG4gIGxldCBhcWxRdWVyeTogc3RyaW5nID0gJyc7XG5cbiAgaWYoaWQpIHtcbiAgICBhcWxRdWVyeSA9IGBMRVQgdSA9IERPQ1VNRU5UKFwiJHtpZH1cIilcbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgRklMVEVSIHUudXNlckFjY2VzcyA+IDBcbiAgICBSRVRVUk4gTUVSR0UodSwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcbiAgfSBlbHNlIGlmKHVzZXJuYW1lKSB7XG4gICAgYXFsUXVlcnkgPSBgRk9SIHUgSU4gdXNlcnNcbiAgICBGSUxURVIgdS51c2VybmFtZSA9PSBcIiR7dXNlcm5hbWV9XCJcbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgUkVUVVJOIE1FUkdFKHUsIHske3NlbGVjdE9iamVjdHMuam9pbignLCAnKX19KWA7XG4gIH0gZWxzZSBpZihlbWFpbCkge1xuICAgIGFxbFF1ZXJ5ID0gYEZPUiB1IElOIHVzZXJzXG4gICAgRklMVEVSIHUuZW1haWwgPT0gXCIke2VtYWlsfVwiXG4gICAgJHtzZWxlY3RRdWVyaWVzLmpvaW4oJ1xcbicpfVxuICAgIFJFVFVSTiBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuICB9IGVsc2UgaWYocGhvbmUpIHtcbiAgICBhcWxRdWVyeSA9IGBGT1IgdSBJTiB1c2Vyc1xuICAgIEZJTFRFUiB1LnBob25lID09IFwiJHtwaG9uZX1cIlxuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICBSRVRVUk4gTUVSR0UodSwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcbiAgfVxuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpXG4gICAgLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5uZXh0KCkpXG4gICAgLnRoZW4oKHVzZXIpID0+IHVzZXIpXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IGxvZ0Vycm9yKHtcbiAgICAgIGFjdGlvbixcbiAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgcGFyYW1zOiB7aWQsIHVzZXJJZCwgdXNlcm5hbWV9LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICB9LCBlcnJvciwgY29udGV4dCkpO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFVzZXJzID0gKGNvbnRleHQ6IEFwaUNvbnRleHQsIG9wdGlvbnM/OiBVc2VyT3B0aW9ucyk6IFByb21pc2U8VXNlclR5cGVbXT4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnZ2V0VXNlckxpc3QnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHN9ID0gY29udGV4dDtcbiAgY29uc3Qge2xpbWl0LCB1c2VybmFtZX0gPSBwYXJzZVVzZXJPcHRpb25zKG9wdGlvbnMpO1xuICBjb25zdCB7b2JqZWN0czogc2VsZWN0T2JqZWN0cywgcXVlcmllczogc2VsZWN0UXVlcmllc30gPSBnZXRVc2VyT3B0aW9uYWwoZmllbGRzKTtcbiAgY29uc3QgZmlsdGVyQnk6IHN0cmluZ1tdID0gWyd1LnVzZXJBY2Nlc3MgPiAwJ107XG5cbiAgaWYodXNlcm5hbWUpIHtcbiAgICBmaWx0ZXJCeS5wdXNoKGBDT05UQUlOUyh1LnVzZXJuYW1lLCBcIiR7cGFyc2VVc2VybmFtZSh1c2VybmFtZSl9XCIpYCk7XG4gIH1cblxuICBjb25zdCBhcWxRdWVyeTogc3RyaW5nID0gYEZPUiB1IElOIHVzZXJzXG4gICAgRklMVEVSICR7ZmlsdGVyQnkuam9pbignICYmICcpfVxuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICAke2xpbWl0LmFxbH1cbiAgICBTT1JUIHUudXNlcm5hbWVcbiAgICBSRVRVUk4gTUVSR0UodSwgeyR7c2VsZWN0T2JqZWN0cy5qb2luKCcsICcpfX0pYDtcblxuICByZXR1cm4gdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShhcWxRdWVyeSlcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IuYWxsKCkgYXMgdW5rbm93biBhcyBVc2VyVHlwZVtdKVxuICAgIC5jYXRjaCgoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICBsb2dFcnJvcih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgICB9LCBlcnJvciwgY29udGV4dCk7XG5cbiAgICAgIHJldHVybiBbXSBhcyBVc2VyVHlwZVtdO1xuICAgIH0pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldFVzZXJzQnlSZWFjdGlvbnMgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHtyZWFjdGlvbnMgPSBbXSwgdXNlcm5hbWV9OiB7cmVhY3Rpb25zPzogc3RyaW5nW107IHVzZXJuYW1lPzogc3RyaW5nfSxcbiAgb3B0aW9ucz86IFVzZXJPcHRpb25zXG4pOiBQcm9taXNlPFVzZXJUeXBlW10+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2dldFVzZXJzQnlSZWFjdGlvbnMnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHMsIHNlc3Npb246IHt1c2VySWQ6IHNlc3Npb25JZH0gPSB7fX0gPSBjb250ZXh0O1xuICBjb25zdCBmb3JtYXRSZWFjdGlvbnM6IHN0cmluZ1tdID0gcmVhY3Rpb25zLm1hcCgocmVhY3Rpb25OYW1lOiBzdHJpbmcpID0+IHBhcnNlQ2hhcihyZWFjdGlvbk5hbWUsIDMyKS50b0xvd2VyQ2FzZSgpKTtcbiAgY29uc3Qge2xpbWl0fSA9IHBhcnNlVXNlck9wdGlvbnMob3B0aW9ucyk7XG4gIGNvbnN0IHtvYmplY3RzOiBzZWxlY3RPYmplY3RzLCBxdWVyaWVzOiBzZWxlY3RRdWVyaWVzfSA9IGdldFVzZXJPcHRpb25hbChmaWVsZHMpO1xuICBjb25zdCBmb3JtYXRTZXNzaW9uSWQ6IHN0cmluZyA9IGB1c2Vycy8ke3Nlc3Npb25JZH1gO1xuICBjb25zdCBmb3JtYXRVc2VybmFtZTogc3RyaW5nID0gcGFyc2VVc2VybmFtZSh1c2VybmFtZSk7XG4gIGNvbnN0IGZpbHRlckJ5OiBzdHJpbmdbXSA9IFtcbiAgICAndS51c2VyQWNjZXNzID4gMCcsXG4gICAgYFBPU0lUSU9OKCR7SlNPTi5zdHJpbmdpZnkoZm9ybWF0UmVhY3Rpb25zKX0sIExPV0VSKHIubmFtZSkpYFxuICBdO1xuXG4gIGlmKHVzZXJuYW1lKSB7XG4gICAgZmlsdGVyQnkucHVzaChgQ09OVEFJTlModS51c2VybmFtZSwgXCIke2Zvcm1hdFVzZXJuYW1lfVwiKWApO1xuICB9XG5cbiAgY29uc3QgYXFsUXVlcnk6IHN0cmluZyA9IGBGT1IgdSwgciBJTiBPVVRCT1VORCBcIiR7Zm9ybWF0U2Vzc2lvbklkfVwiIGhhc1JlYWN0aW9uXG4gICAgT1BUSU9OUyB7dmVydGV4Q29sbGVjdGlvbnM6IFwidXNlcnNcIn1cbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgRklMVEVSICR7ZmlsdGVyQnkuam9pbignICYmICcpfVxuICAgICR7bGltaXQuYXFsfVxuICAgIFJFVFVSTiBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSBhcyB1bmtub3duIGFzIFVzZXJUeXBlW10pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgICAgcmV0dXJuIFtdIGFzIFVzZXJUeXBlW107XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VXNlcnNCeVRhZ3MgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHt0YWdzLCB1c2VybmFtZX0sXG4gIG9wdGlvbnM/OiBVc2VyT3B0aW9uc1xuKTogUHJvbWlzZTxVc2VyVHlwZVtdPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdnZXRVc2Vyc0J5VGFncyc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWUsIGZpZWxkcywgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkfSA9IHt9fSA9IGNvbnRleHQ7XG4gIGNvbnN0IGZvcm1hdFRhZ3M6IHN0cmluZ1tdID0gdGFncz8ucmVkdWNlKChsaXN0OiBzdHJpbmdbXSwgdGFnTmFtZTogc3RyaW5nKSA9PiB7XG4gICAgaWYodGFnTmFtZSkge1xuICAgICAgbGlzdC5wdXNoKHBhcnNlQ2hhcih0YWdOYW1lLCAzMikudG9Mb3dlckNhc2UoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxpc3Q7XG4gIH0sIFtdKTtcbiAgY29uc3Qge2xpbWl0fSA9IHBhcnNlVXNlck9wdGlvbnMob3B0aW9ucyk7XG4gIGNvbnN0IHtvYmplY3RzOiBzZWxlY3RPYmplY3RzLCBxdWVyaWVzOiBzZWxlY3RRdWVyaWVzfSA9IGdldFVzZXJPcHRpb25hbChmaWVsZHMpO1xuICBjb25zdCBmb3JtYXRVc2VybmFtZTogc3RyaW5nID0gcGFyc2VVc2VybmFtZSh1c2VybmFtZSk7XG4gIGNvbnN0IGZpbHRlckJ5OiBzdHJpbmdbXSA9IFtcbiAgICBgdS5fa2V5ICE9IFwiJHtzZXNzaW9uSWR9XCJgLFxuICAgICd1LnVzZXJBY2Nlc3MgPiAwJ1xuICBdO1xuXG4gIGlmKHVzZXJuYW1lKSB7XG4gICAgZmlsdGVyQnkucHVzaChgQ09OVEFJTlModS51c2VybmFtZSwgXCIke2Zvcm1hdFVzZXJuYW1lfVwiKWApO1xuICB9XG5cbiAgY29uc3QgYXFsUXVlcnk6IHN0cmluZyA9IGBGT1IgdCBJTiB0YWdzXG4gICAgRklMVEVSIFBPU0lUSU9OKCR7SlNPTi5zdHJpbmdpZnkoZm9ybWF0VGFncyl9LCBMT1dFUih0Lm5hbWUpKVxuICAgIEZPUiB1LCBpdCBJTiBPVVRCT1VORCB0IGlzVGFnZ2VkXG4gICAgT1BUSU9OUyB7YmZzOiB0cnVlLCB1bmlxdWVWZXJ0aWNlczogXCJnbG9iYWxcIiwgdmVydGV4Q29sbGVjdGlvbnM6IFwidXNlcnNcIn1cbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgRklMVEVSICR7ZmlsdGVyQnkuam9pbignICYmICcpfVxuICAgICR7bGltaXQuYXFsfVxuICAgIFJFVFVSTiBESVNUSU5DVCBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSBhcyB1bmtub3duIGFzIFVzZXJUeXBlW10pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgICAgcmV0dXJuIFtdIGFzIFVzZXJUeXBlW107XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VXNlcnNCeUxhdGVzdCA9IChjb250ZXh0OiBBcGlDb250ZXh0LCB7dXNlcm5hbWV9LCBvcHRpb25zPzogVXNlck9wdGlvbnMpOiBQcm9taXNlPFVzZXJUeXBlW10+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2dldFVzZXJzQnlMYXRlc3QnO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lLCBmaWVsZHMsIHNlc3Npb246IHt1c2VySWR9ID0ge319ID0gY29udGV4dDtcbiAgY29uc3Qge2xpbWl0fSA9IHBhcnNlVXNlck9wdGlvbnMob3B0aW9ucyk7XG4gIGNvbnN0IGZpbHRlciA9IFtcbiAgICAndS5faWQgIT0gc2Vzc2lvbi5faWQnLFxuICAgICd1LnVzZXJBY2Nlc3MgPiAwJ1xuICBdO1xuICBjb25zdCB7b2JqZWN0czogc2VsZWN0T2JqZWN0cywgcXVlcmllczogc2VsZWN0UXVlcmllc30gPSBnZXRVc2VyT3B0aW9uYWwoZmllbGRzKTtcblxuICBpZih1c2VybmFtZSkge1xuICAgIGZpbHRlci5wdXNoKGBDT05UQUlOUyh1LnVzZXJuYW1lLCBcIiR7cGFyc2VVc2VybmFtZSh1c2VybmFtZSl9XCIpYCk7XG4gIH1cblxuICAvLyBHZXQgZGF0YSBmcm9tIGRhdGFiYXNlXG4gIGNvbnN0IGFxbFF1ZXJ5OiBzdHJpbmcgPSBgRk9SIHUgSU4gdXNlcnNcbiAgICBMRVQgc2Vzc2lvbiA9IERPQ1VNRU5UKFwidXNlcnMvJHt1c2VySWR9XCIpXG4gICAgRklMVEVSICR7ZmlsdGVyLmpvaW4oJyAmJiAnKX1cbiAgICAke3NlbGVjdFF1ZXJpZXMuam9pbignXFxuJyl9XG4gICAgTEVUIGRpc3RhbmNlID0gRElTVEFOQ0UodS5sYXRpdHVkZSB8fCAwLCB1LmxvbmdpdHVkZSB8fCAwLCBzZXNzaW9uLmxhdGl0dWRlIHx8IDAsIHNlc3Npb24ubG9uZ2l0dWRlIHx8IDApXG4gICAgJHtsaW1pdC5hcWx9XG4gICAgU09SVCBkaXN0YW5jZSBBU0MsIHUuYWRkZWQgREVTQ1xuICAgIFJFVFVSTiBNRVJHRSh1LCB7JHtzZWxlY3RPYmplY3RzLmpvaW4oJywgJyl9fSlgO1xuXG4gIHJldHVybiB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGFxbFF1ZXJ5KVxuICAgIC50aGVuKChjdXJzb3IpID0+IGN1cnNvci5hbGwoKSBhcyB1bmtub3duIGFzIFVzZXJUeXBlW10pXG4gICAgLmNhdGNoKChlcnJvcjogRXJyb3IpID0+IHtcbiAgICAgIGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgICAgcmV0dXJuIFtdIGFzIFVzZXJUeXBlW107XG4gICAgfSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0VXNlcnNCeUNvbm5lY3Rpb24gPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsXG4gIHt1c2VySWR9OiBVc2VyVHlwZSxcbiAgb3B0aW9ucz86IFVzZXJPcHRpb25zXG4pOiBQcm9taXNlPFVzZXJUeXBlW10+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2dldFVzZXJzQnlDb25uZWN0aW9uJztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZSwgZmllbGRzfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHtsaW1pdCwgdXNlcm5hbWV9ID0gcGFyc2VVc2VyT3B0aW9ucyhvcHRpb25zKTtcbiAgY29uc3Qge29iamVjdHM6IHNlbGVjdE9iamVjdHMsIHF1ZXJpZXM6IHNlbGVjdFF1ZXJpZXN9ID0gZ2V0VXNlck9wdGlvbmFsKGZpZWxkcyk7XG4gIGNvbnN0IGZvcm1hdFVzZXJJZDogc3RyaW5nID0gcGFyc2VBcmFuZ29JZChgdXNlcnMvJHt1c2VySWR9YCk7XG4gIGNvbnN0IGZpbHRlckJ5OiBzdHJpbmdbXSA9IFtcbiAgICAndS51c2VyQWNjZXNzID4gMCdcbiAgXTtcblxuICBpZih1c2VybmFtZSkge1xuICAgIGZpbHRlckJ5LnB1c2goYENPTlRBSU5TKHUudXNlcm5hbWUsIFwiJHtwYXJzZVVzZXJuYW1lKHVzZXJuYW1lKX1cIilgKTtcbiAgfVxuXG4gIGNvbnN0IGFxbFF1ZXJ5OiBzdHJpbmcgPSBgRk9SIGN1IElOIHVzZXJzXG4gICAgTEVUIHNlc3Npb24gPSBET0NVTUVOVChcIiR7Zm9ybWF0VXNlcklkfVwiKVxuICAgIEZPUiB1LCBjb25uZWN0aW9uIElOIE9VVEJPVU5EIGN1IGhhc0Nvbm5lY3Rpb25cbiAgICBPUFRJT05TIHtiZnM6IHRydWUsIHVuaXF1ZVZlcnRpY2VzOiBcImdsb2JhbFwiLCB2ZXJ0ZXhDb2xsZWN0aW9uczogXCJ1c2Vyc1wifVxuICAgICR7c2VsZWN0UXVlcmllcy5qb2luKCdcXG4nKX1cbiAgICBGSUxURVIgJHtmaWx0ZXJCeS5qb2luKCcgJiYgJyl9XG4gICAgJHtsaW1pdC5hcWx9XG4gICAgUkVUVVJOIERJU1RJTkNUIE1FUkdFKHUsIHske3NlbGVjdE9iamVjdHMuam9pbignLCAnKX19KWA7XG5cbiAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoYXFsUXVlcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLmFsbCgpIGFzIHVua25vd24gYXMgVXNlclR5cGVbXSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuXG4gICAgICByZXR1cm4gW10gYXMgVXNlclR5cGVbXTtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCByZWZyZXNoU2Vzc2lvbiA9ICh7ZXhwaXJlcywgdG9rZW59KTogU2Vzc2lvblRva2VuIHwgU2Vzc2lvbkVycm9yID0+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCB7dXNlcklkLCB1c2VybmFtZSwgdXNlckFjY2Vzc30gPSBnZXRTZXNzaW9uKHRva2VuKTtcbiAgICByZXR1cm4gY3JlYXRlVG9rZW4odXNlcklkLCB1c2VybmFtZSwgdXNlckFjY2VzcywgZXhwaXJlcyk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICB0aHJvdyBlcnJvcjsgLy8gUmUtdGhyb3cgdGhlIGVycm9yIGZyb20gZ2V0U2Vzc2lvblxuICB9XG59O1xuXG5leHBvcnQgY29uc3Qgc2lnbkluID0gYXN5bmMgKGNvbnRleHQ6IEFwaUNvbnRleHQsIGFyZ3MpOiBQcm9taXNlPFNlc3Npb25Ub2tlbiB8IG51bGw+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ3NpZ25Jbic7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWV9ID0gY29udGV4dDtcbiAgY29uc3Qge2VtYWlsLCBleHBpcmVzLCBwYXNzd29yZCwgcGhvbmUsIHVzZXJuYW1lfSA9IGFyZ3M7XG4gIGNvbnN0IGZvcm1hdEVtYWlsOiBzdHJpbmcgPSBwYXJzZUVtYWlsKGVtYWlsKTtcbiAgY29uc3QgZm9ybWF0VXNlcm5hbWU6IHN0cmluZyA9IHBhcnNlVXNlcm5hbWUodXNlcm5hbWUpO1xuICBjb25zdCBmb3JtYXRQYXNzd29yZDogc3RyaW5nID0gcGFyc2VQYXNzd29yZChwYXNzd29yZCk7XG4gIGNvbnN0IGZvcm1hdFBob25lOiBzdHJpbmcgPSBwYXJzZVBob25lKHBob25lKTtcbiAgY29uc3QgZm9ybWF0RXhwaXJlczogbnVtYmVyID0gcGFyc2VOdW0oZXhwaXJlcykgfHwgMTU7XG5cbiAgaWYoKCFmb3JtYXRVc2VybmFtZSAmJiAhZm9ybWF0RW1haWwgJiYgIWZvcm1hdFBob25lKSB8fCAhZm9ybWF0UGFzc3dvcmQpIHtcbiAgICB0aHJvdyBsb2dFeGNlcHRpb24oe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHt1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5JTlZBTElEX0FSR1VNRU5UU1xuICAgIH0sIGNvbnRleHQpO1xuICB9XG5cbiAgY29uc3QgZmlsdGVyczogc3RyaW5nW10gPSBbXTtcblxuICBpZihmb3JtYXRFbWFpbCkge1xuICAgIGZpbHRlcnMucHVzaChgdS5lbWFpbCA9PSBcIiR7Zm9ybWF0RW1haWx9XCJgKTtcbiAgfVxuXG4gIGlmKGZvcm1hdFBob25lKSB7XG4gICAgZmlsdGVycy5wdXNoKGB1LnBob25lID09ICR7Zm9ybWF0UGhvbmV9YCk7XG4gIH1cblxuICBpZihmb3JtYXRVc2VybmFtZSkge1xuICAgIGZpbHRlcnMucHVzaChgdS51c2VybmFtZSA9PSBcIiR7Zm9ybWF0VXNlcm5hbWV9XCJgKTtcbiAgfVxuXG4gIGNvbnN0IGNoZWNrUXVlcnk6IHN0cmluZyA9IGBGT1IgdSBJTiB1c2Vyc1xuICAgIEZJTFRFUiAke2ZpbHRlcnMuam9pbignIHx8ICcpfVxuICAgIExJTUlUIDFcbiAgICBSRVRVUk4gdWA7XG5cbiAgbGV0IGNoZWNrVXNlcjogVXNlclR5cGU7XG5cbiAgdHJ5IHtcbiAgICBjaGVja1VzZXIgPSBhd2FpdCB1c2VEYihkYXRhYmFzZU5hbWUpLnF1ZXJ5KGNoZWNrUXVlcnkpLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICB0aHJvdyBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge3VzZXJuYW1lOiBmb3JtYXRVc2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgfVxuXG4gIGlmKCFjaGVja1VzZXIpIHtcbiAgICB0aHJvdyBsb2dFeGNlcHRpb24oe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHt1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5JTlZBTElEX0FVVEhFTlRJQ0FUSU9OXG4gICAgfSwgY29udGV4dCk7XG4gIH1cblxuICBjb25zdCB7X2tleTogdXNlcklkLCBwYXNzd29yZDogdmFsaWRQYXNzd29yZCwgc2FsdCwgdXNlckFjY2Vzc30gPSBjaGVja1VzZXIgYXMgVXNlclR5cGU7XG4gIGNvbnN0IGF1dGhQYXNzd29yZDogc3RyaW5nID0gY3JlYXRlUGFzc3dvcmQoZm9ybWF0UGFzc3dvcmQsIHNhbHQpO1xuXG4gIGNvbnNvbGUubG9nKHtcbiAgICBjcmVhdGVQYXNzd29yZCxcbiAgICBhdXRoUGFzc3dvcmQsXG4gICAgdmFsaWRQYXNzd29yZCxcbiAgICBmb3JtYXRQYXNzd29yZCxcbiAgICBzYWx0XG4gIH0pO1xuXG4gIGlmKHZhbGlkUGFzc3dvcmQgIT09IGF1dGhQYXNzd29yZCkge1xuICAgIHRocm93IGxvZ0V4Y2VwdGlvbih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge3VzZXJBY2Nlc3MsIHVzZXJJZCwgdXNlcm5hbWV9LFxuICAgICAgdmFsdWU6IEVycm9yVHlwZXMuSU5WQUxJRF9BVVRIRU5USUNBVElPTlxuICAgIH0sIGNvbnRleHQpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBjb25zdCB0b2tlbiA9IGNyZWF0ZVRva2VuKHVzZXJJZCB8fCAnJywgdXNlcm5hbWUgfHwgJycsIHVzZXJBY2Nlc3MsIGZvcm1hdEV4cGlyZXMpO1xuXG4gICAgcmV0dXJuIHRva2VuO1xuICB9IGNhdGNoKGVycm9yKSB7XG4gICAgdGhyb3cgbG9nRXJyb3Ioe1xuICAgICAgYWN0aW9uLFxuICAgICAgY2F0ZWdvcnk6IGV2ZW50Q2F0ZWdvcnksXG4gICAgICBwYXJhbXM6IHt1c2VySWQsIHVzZXJuYW1lfSxcbiAgICAgIHZhbHVlOiBFcnJvclR5cGVzLkRBVEFCQVNFX0VSUk9SXG4gICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3Qgc2lnbk91dCA9IGFzeW5jIChjb250ZXh0OiBBcGlDb250ZXh0KTogUHJvbWlzZTxib29sZWFuPiA9PiB7XG4gIGNvbnN0IGFjdGlvbiA9ICdzaWduT3V0JztcbiAgY29uc3Qge2RhdGFiYXNlTmFtZSwgc2Vzc2lvbjoge3VzZXJJZDogc2Vzc2lvbklkLCB1c2VybmFtZX0gPSB7fX0gPSBjb250ZXh0O1xuICBjb25zdCB1c2VyRG9jSWQ6IHN0cmluZyA9IGB1c2Vycy8ke3Nlc3Npb25JZH1gO1xuXG4gIGNvbnN0IHVwZGF0ZSA9IHtcbiAgICBsYXN0T25saW5lOiBEYXRlLm5vdygpLFxuICAgIHNlc3Npb25JZDogbnVsbFxuICB9O1xuICBjb25zdCBzZXNzaW9uUXVlcnk6IEFxbFF1ZXJ5ID0gYXFsYExFVCB1ID0gRE9DVU1FTlQoJHt1c2VyRG9jSWR9KVxuICAgIFVQREFURSB1IFdJVEggJHt1cGRhdGV9IElOIHVzZXJzXG4gICAgTElNSVQgMVxuICAgIFJFVFVSTiBORVdgO1xuXG4gIHRyeSB7XG4gICAgYXdhaXQgdXNlRGIoZGF0YWJhc2VOYW1lKS5xdWVyeShzZXNzaW9uUXVlcnkpLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSk7XG4gIH0gY2F0Y2goZXJyb3IpIHtcbiAgICBsb2dFcnJvcih7XG4gICAgICBhY3Rpb24sXG4gICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgIHBhcmFtczoge3VzZXJJZDogc2Vzc2lvbklkLCB1c2VybmFtZX0sXG4gICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgIH0sIGVycm9yLCBjb250ZXh0KTtcblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEFjdGl2ZVVzZXJDb3VudCA9IChjb250ZXh0OiBBcGlDb250ZXh0KTogUHJvbWlzZTxudW1iZXI+ID0+IHtcbiAgY29uc3QgYWN0aW9uID0gJ2dldEFjdGl2ZVVzZXJDb3VudCc7XG4gIGNvbnN0IHtkYXRhYmFzZU5hbWV9ID0gY29udGV4dDtcbiAgY29uc3QgY291bnRRdWVyeTogQXFsUXVlcnkgPSBhcWxgTEVUIGRvY3MgPSAoXG4gICAgRk9SIHUgSU4gdXNlcnNcbiAgICBGSUxURVIgdS5hY3RpdmUgPT0gdHJ1ZVxuICAgIFJFVFVSTiB1XG4gIClcbiAgUkVUVVJOIExFTkdUSChkb2NzKWA7XG5cbiAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSkucXVlcnkoY291bnRRdWVyeSlcbiAgICAudGhlbigoY3Vyc29yKSA9PiBjdXJzb3IubmV4dCgpKVxuICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgIHRocm93IGxvZ0Vycm9yKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBjYXRlZ29yeTogZXZlbnRDYXRlZ29yeSxcbiAgICAgICAgdmFsdWU6IEVycm9yVHlwZXMuREFUQUJBU0VfRVJST1JcbiAgICAgIH0sIGVycm9yLCBjb250ZXh0KTtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRVc2VyQnlUb2tlbiA9IChjb250ZXh0OiBBcGlDb250ZXh0LCB0b2tlbjogc3RyaW5nKTogUHJvbWlzZTxVc2VyVHlwZT4gPT4ge1xuICBjb25zdCBhY3Rpb24gPSAnZ2V0VXNlckJ5VG9rZW4nO1xuICBjb25zdCB7ZGF0YWJhc2VOYW1lfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHt1c2VySWR9ID0gZ2V0U2Vzc2lvbih0b2tlbik7XG4gIGNvbnN0IHVzZXJEb2NJZCA9IHBhcnNlQXJhbmdvSWQoYHVzZXJzLyR7dXNlcklkfWApO1xuICBjb25zdCBhcWxRdWVyeTogQXFsUXVlcnkgPSBhcWxgTEVUIHUgPSBET0NVTUVOVChcIiR7dXNlckRvY0lkfVwiKSBSRVRVUk4gdWA7XG5cbiAgcmV0dXJuIHVzZURiKGRhdGFiYXNlTmFtZSlcbiAgICAucXVlcnkoYXFsUXVlcnkpXG4gICAgLnRoZW4oKGN1cnNvcikgPT4gY3Vyc29yLm5leHQoKSlcbiAgICAuY2F0Y2goKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgdGhyb3cgbG9nRXJyb3Ioe1xuICAgICAgICBhY3Rpb24sXG4gICAgICAgIGNhdGVnb3J5OiBldmVudENhdGVnb3J5LFxuICAgICAgICBwYXJhbXM6IHt1c2VySWR9LFxuICAgICAgICB2YWx1ZTogRXJyb3JUeXBlcy5EQVRBQkFTRV9FUlJPUlxuICAgICAgfSwgZXJyb3IsIGNvbnRleHQpO1xuICAgIH0pO1xufTsiXSwibmFtZXMiOlsicGFyc2VOdW0iLCJjcmVhdGVIYXNoIiwiY3JlYXRlUGFzc3dvcmQiLCJwYXJzZUFyYW5nb0lkIiwicGFyc2VDaGFyIiwicGFyc2VFbWFpbCIsInBhcnNlUGFzc3dvcmQiLCJwYXJzZVBob25lIiwicGFyc2VVc2VybmFtZSIsImFxbCIsIkRhdGVUaW1lIiwiU3RyaXBlIiwicGFyc2VVc2VyIiwiQ29uZmlnIiwiRXJyb3JUeXBlcyIsImxvZ0Vycm9yIiwibG9nRXhjZXB0aW9uIiwiZ2V0RG9jSWQiLCJnZXRMaW1pdCIsInNlbGVjdFJlYWN0aW9uQ291bnRCeVR5cGUiLCJ1c2VEYiIsImRldGVjdExhbmd1YWdlIiwiZ2V0U2Vzc2lvbiIsInNldFNlc3Npb24iLCJzZW5kRW1haWwiLCJzZW5kU21zIiwiZXZlbnRDYXRlZ29yeSIsIlNUUklQRV9BUElfVkVSU0lPTiIsIlVzZXJBY2Nlc3MiLCJjcmVhdGVUb2tlbiIsInVzZXJJZCIsInVzZXJuYW1lIiwidXNlckFjY2VzcyIsImV4cGlyZXNJbk1pbnV0ZXMiLCJub3ciLCJsb2NhbCIsInNlc3Npb25FeHBpcmVzIiwicGx1cyIsIm1pbnV0ZXMiLCJpYXQiLCJNYXRoIiwiZmxvb3IiLCJ0b1NlY29uZHMiLCJleHAiLCJ0b2tlbiIsImV4cGlyZXMiLCJ0b01pbGxpcyIsImlzc3VlZCIsImdldFVzZXJPcHRpb25hbCIsImZpZWxkcyIsInJlZHVjZSIsInNlbGVjdHMiLCJmaWVsZCIsImluY2x1ZGVzIiwib2JqZWN0cyIsInF1ZXJpZXMiLCJwYXJzZVVzZXJPcHRpb25zIiwib3B0aW9ucyIsImZyb20iLCJ0byIsImxpbWl0IiwiYWRkVXNlciIsImNvbnRleHQiLCJ1c2VyIiwiYWN0aW9uIiwiZGF0YWJhc2VOYW1lIiwibGFuZ3VhZ2VDb250ZXh0IiwiY29uZmlybSIsIl9jb25maXJtIiwibmV3VXNlciIsImVtYWlsIiwicGFzc3dvcmQiLCJwaG9uZSIsIl9rZXkiLCJfaWQiLCJpbnNlcnRVc2VyIiwiaGFzUGFzc3dvcmQiLCJoYXNVc2VybmFtZSIsImNhdGVnb3J5IiwicGFyYW1zIiwidmFsdWUiLCJJTlZBTElEX0FSR1VNRU5UUyIsImhhc2hJZCIsInNhbHQiLCJlbmNyeXB0ZWRQYXNzd29yZCIsImZpbHRlcnMiLCJwdXNoIiwiY2hlY2tRdWVyeSIsImpvaW4iLCJleGlzdGluZ1VzZXJzIiwicXVlcnkiLCJ0aGVuIiwiY3Vyc29yIiwiYWxsIiwibGVuZ3RoIiwiRVhJU1RJTkdfSVRFTSIsImVycm9yIiwiREFUQUJBU0VfRVJST1IiLCJwaG9uZUNvdW50cnlDb2RlIiwicmVwbGFjZSIsInN1YnN0cmluZyIsImxvY2FsZSIsInVzZXJQcmVmZXJlbmNlIiwidmVyaWZpZWRFbWFpbENvZGUiLCJyYW5kb20iLCJ2ZXJpZmllZFNtc0NvZGUiLCJpbnNlcnQiLCJhZGRlZCIsIkRhdGUiLCJtb2RpZmllZCIsInZlcmlmaWVkRW1haWwiLCJ2ZXJpZmllZFBob25lIiwiaW5zZXJ0UXVlcnkiLCJuZXh0IiwiY2F0Y2giLCJ1cGRhdGVVc2VyIiwidXBkYXRlZFVzZXIiLCJ0YWdzIiwidXBkYXRlIiwiaWQiLCJ1c2VyUXVlcnkiLCJkYXRhYmFzZSIsInRhZ0NvbGxlY3Rpb24iLCJjb2xsZWN0aW9uIiwiUHJvbWlzZSIsIm1hcCIsInRhZ0RvY0lkIiwibmFtZSIsInRhZ1F1ZXJ5IiwidGFnRWRnZSIsImVkZ2UiLCJfZnJvbSIsIl90byIsInNhdmUiLCJyZXR1cm5OZXciLCJmb3Jnb3RQYXNzd29yZCIsImFxbFF1ZXJ5IiwiY29kZUV4cGlyZXMiLCJjb2RlIiwidXNlckRvY0lkIiwidGV4dCIsInZlcmlmaWVkRW1haWxFeHBpcmVzIiwidmVyaWZpZWRQaG9uZUV4cGlyZXMiLCJ1cGRhdGVRdWVyeSIsInJlc2V0UGFzc3dvcmQiLCJ0eXBlIiwiZm9ybWF0UGFzc3dvcmQiLCJjb25maXJtQ29kZSIsImlzU21zIiwiZm9ybWF0dGVkVmFsdWUiLCJmaWx0ZXJCeVR5cGUiLCJkZWxldGVVc2VyIiwic3RyaXBlQ2xpZW50IiwiZ2V0IiwiYXBpVmVyc2lvbiIsInR5cGVzY3JpcHQiLCJkZWxldGVkVXNlciIsImN1c3RvbWVycyIsImRlbCIsInN0cmlwZUN1c3RvbWVySWQiLCJhY2NvdW50cyIsInN0cmlwZUFjY291bnRJZCIsImRlYWN0aXZhdGVVc2VyIiwidXBkYXRlZCIsImdldERpc3BsYXlOYW1lIiwiZmlyc3QiLCJsYXN0IiwiZnVsbG5hbWUiLCJ0cmltIiwiZ2V0U2Vzc2lvblVzZXIiLCJzZXNzaW9uIiwic2Vzc2lvbklkIiwic2VsZWN0T2JqZWN0cyIsInNlbGVjdFF1ZXJpZXMiLCJmb3JtYXRTZXNzaW9uSWQiLCJnZXRVc2VyIiwiZ2V0VXNlcnMiLCJmaWx0ZXJCeSIsImdldFVzZXJzQnlSZWFjdGlvbnMiLCJyZWFjdGlvbnMiLCJmb3JtYXRSZWFjdGlvbnMiLCJyZWFjdGlvbk5hbWUiLCJ0b0xvd2VyQ2FzZSIsImZvcm1hdFVzZXJuYW1lIiwiSlNPTiIsInN0cmluZ2lmeSIsImdldFVzZXJzQnlUYWdzIiwiZm9ybWF0VGFncyIsImxpc3QiLCJ0YWdOYW1lIiwiZ2V0VXNlcnNCeUxhdGVzdCIsImZpbHRlciIsImdldFVzZXJzQnlDb25uZWN0aW9uIiwiZm9ybWF0VXNlcklkIiwicmVmcmVzaFNlc3Npb24iLCJzaWduSW4iLCJhcmdzIiwiZm9ybWF0RW1haWwiLCJmb3JtYXRQaG9uZSIsImZvcm1hdEV4cGlyZXMiLCJjaGVja1VzZXIiLCJJTlZBTElEX0FVVEhFTlRJQ0FUSU9OIiwidmFsaWRQYXNzd29yZCIsImF1dGhQYXNzd29yZCIsImNvbnNvbGUiLCJsb2ciLCJzaWduT3V0IiwibGFzdE9ubGluZSIsInNlc3Npb25RdWVyeSIsImdldEFjdGl2ZVVzZXJDb3VudCIsImNvdW50UXVlcnkiLCJnZXRVc2VyQnlUb2tlbiJdLCJtYXBwaW5ncyI6IkFBQUE7OztDQUdDLEdBQ0QsU0FBUUEsUUFBUSxRQUFPLCtCQUErQjtBQUN0RCxTQUNFQyxVQUFVLEVBQ1ZDLGNBQWMsRUFDZEMsYUFBYSxFQUNiQyxTQUFTLEVBQ1RDLFVBQVUsRUFDVkMsYUFBYSxFQUNiQyxVQUFVLEVBQ1ZDLGFBQWEsUUFDUiwrQkFBK0I7QUFDdEMsU0FBUUMsR0FBRyxRQUFPLFdBQVc7QUFDN0IsU0FBUUMsUUFBUSxRQUFPLFFBQVE7QUFDL0IsT0FBT0MsWUFBWSxTQUFTO0FBRTVCLFNBQVFDLFNBQVMsUUFBTyw2QkFBNkI7QUFDckQsU0FBUUMsTUFBTSxRQUFPLGVBQWU7QUFDcEMsU0FBUUMsVUFBVSxRQUEwQiwwQkFBMEI7QUFDdEUsU0FBUUMsUUFBUSxFQUFFQyxZQUFZLFFBQU8sNkJBQTZCO0FBQ2xFLFNBQVFDLFFBQVEsRUFBRUMsUUFBUSxFQUFFQyx5QkFBeUIs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
|