From 476774101b547b09d0786998b8f4e85f70fb34b0 Mon Sep 17 00:00:00 2001 From: Jason Posthuma Date: Wed, 10 Feb 2021 15:28:08 +0100 Subject: [PATCH 1/6] Added support for `req.userFromJwt` in login sequence --- src/Routers/UsersRouter.js | 39 +++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/Routers/UsersRouter.js b/src/Routers/UsersRouter.js index 7843cf4674..43f24ebdf2 100644 --- a/src/Routers/UsersRouter.js +++ b/src/Routers/UsersRouter.js @@ -139,6 +139,32 @@ export class UsersRouter extends ClassesRouter { }); } + /** + * Validates JWT bearer token and looks up user `req.userFromJwt`. CRITICALLY IMPORTANT that the JWT has already been validated by this point (eg: express middleware, AWS API Gateway Authorizer) + * @param {Object} req The request + * @returns {Object} User object + */ + _authenticateUserFromRequestWithJwt(req) { + return new Promise((resolve, reject) => { + if (!req.userFromJwt) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid credentials.'); + } + + const query = { objectId: req.userFromJwt.objectId }; + return req.config.database + .find('_User', query) + .then(results => { + if (!results.length) + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid credentials.'); + const user = results[0]; + resolve(user); + }) + .catch(error => { + return reject(error); + }); + }); + } + handleMe(req) { if (!req.info || !req.info.sessionToken) { throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); @@ -171,10 +197,17 @@ export class UsersRouter extends ClassesRouter { } async handleLogIn(req) { - const user = await this._authenticateUserFromRequest(req); + let userFromJwt; + if (req.userFromJwt) { + // Could be just used `req.userFromJwt`, but the forced lookup + // Ensures the user hasn't been deleted since the the JWT was granted + userFromJwt = await this._authenticateUserFromRequestWithJwt(req); + } + + const user = userFromJwt || (await this._authenticateUserFromRequest(req)); - // handle password expiry policy - if (req.config.passwordPolicy && req.config.passwordPolicy.maxPasswordAge) { + // handle password expiry policy - ignore if user is managed in SSO (provided by JWT) + if (!userFromJwt && req.config.passwordPolicy && req.config.passwordPolicy.maxPasswordAge) { let changedAt = user._password_changed_at; if (!changedAt) { From 55c995ef31896f648ea43b6e0238822e20930a8d Mon Sep 17 00:00:00 2001 From: Jason Posthuma Date: Wed, 10 Feb 2021 15:51:50 +0100 Subject: [PATCH 2/6] Fixed casing issue --- src/Routers/UsersRouter.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Routers/UsersRouter.js b/src/Routers/UsersRouter.js index 43f24ebdf2..fd7d244c74 100644 --- a/src/Routers/UsersRouter.js +++ b/src/Routers/UsersRouter.js @@ -140,17 +140,17 @@ export class UsersRouter extends ClassesRouter { } /** - * Validates JWT bearer token and looks up user `req.userFromJwt`. CRITICALLY IMPORTANT that the JWT has already been validated by this point (eg: express middleware, AWS API Gateway Authorizer) + * Validates JWT bearer token and looks up user `req.userFromJWT`. CRITICALLY IMPORTANT that the JWT has already been validated by this point (eg: express middleware, AWS API Gateway Authorizer) * @param {Object} req The request * @returns {Object} User object */ _authenticateUserFromRequestWithJwt(req) { return new Promise((resolve, reject) => { - if (!req.userFromJwt) { + if (!req.userFromJWT) { throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid credentials.'); } - const query = { objectId: req.userFromJwt.objectId }; + const query = { objectId: req.userFromJWT.objectId }; return req.config.database .find('_User', query) .then(results => { @@ -197,17 +197,17 @@ export class UsersRouter extends ClassesRouter { } async handleLogIn(req) { - let userFromJwt; - if (req.userFromJwt) { - // Could be just used `req.userFromJwt`, but the forced lookup + let userFromJWT; + if (req.userFromJWT) { + // Could be just used `req.userFromJWT`, but the forced lookup // Ensures the user hasn't been deleted since the the JWT was granted - userFromJwt = await this._authenticateUserFromRequestWithJwt(req); + userFromJWT = await this._authenticateUserFromRequestWithJwt(req); } - const user = userFromJwt || (await this._authenticateUserFromRequest(req)); + const user = userFromJWT || (await this._authenticateUserFromRequest(req)); // handle password expiry policy - ignore if user is managed in SSO (provided by JWT) - if (!userFromJwt && req.config.passwordPolicy && req.config.passwordPolicy.maxPasswordAge) { + if (!userFromJWT && req.config.passwordPolicy && req.config.passwordPolicy.maxPasswordAge) { let changedAt = user._password_changed_at; if (!changedAt) { From 94d31e781efe0ec7d872d28f9c85ad23b2afccfc Mon Sep 17 00:00:00 2001 From: Jason Posthuma Date: Wed, 10 Feb 2021 15:58:33 +0100 Subject: [PATCH 3/6] Fixed Id lookup on user --- src/Routers/UsersRouter.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Routers/UsersRouter.js b/src/Routers/UsersRouter.js index fd7d244c74..6c0347f501 100644 --- a/src/Routers/UsersRouter.js +++ b/src/Routers/UsersRouter.js @@ -150,7 +150,9 @@ export class UsersRouter extends ClassesRouter { throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid credentials.'); } - const query = { objectId: req.userFromJWT.objectId }; + const query = { + objectId: req.userFromJWT.id, + }; return req.config.database .find('_User', query) .then(results => { From b49eb69e9c2af7e1b7698340976dece0ab9a1448 Mon Sep 17 00:00:00 2001 From: Jason Posthuma Date: Thu, 11 Feb 2021 14:56:48 +0100 Subject: [PATCH 4/6] Added built version --- .gitignore | 2 +- lib/AccountLockout.js | 193 ++ lib/Adapters/AdapterLoader.js | 63 + lib/Adapters/Analytics/AnalyticsAdapter.js | 41 + lib/Adapters/Auth/AuthAdapter.js | 34 + lib/Adapters/Auth/OAuth1Client.js | 227 ++ lib/Adapters/Auth/apple.js | 105 + lib/Adapters/Auth/facebook.js | 62 + lib/Adapters/Auth/gcenter.js | 126 + lib/Adapters/Auth/github.js | 40 + lib/Adapters/Auth/google.js | 167 ++ lib/Adapters/Auth/gpgames.js | 35 + lib/Adapters/Auth/httpsRequest.js | 47 + lib/Adapters/Auth/index.js | 173 ++ lib/Adapters/Auth/instagram.js | 31 + lib/Adapters/Auth/janraincapture.js | 46 + lib/Adapters/Auth/janrainengage.js | 52 + lib/Adapters/Auth/keycloak.js | 125 + lib/Adapters/Auth/ldap.js | 105 + lib/Adapters/Auth/line.js | 41 + lib/Adapters/Auth/linkedin.js | 46 + lib/Adapters/Auth/meetup.js | 39 + lib/Adapters/Auth/microsoft.js | 39 + lib/Adapters/Auth/oauth2.js | 142 + lib/Adapters/Auth/phantauth.js | 47 + lib/Adapters/Auth/qq.js | 48 + lib/Adapters/Auth/spotify.js | 51 + lib/Adapters/Auth/twitter.js | 60 + lib/Adapters/Auth/vkontakte.js | 54 + lib/Adapters/Auth/wechat.js | 33 + lib/Adapters/Auth/weibo.js | 47 + lib/Adapters/Cache/CacheAdapter.js | 50 + lib/Adapters/Cache/InMemoryCache.js | 76 + lib/Adapters/Cache/InMemoryCacheAdapter.js | 45 + lib/Adapters/Cache/LRUCache.js | 46 + lib/Adapters/Cache/NullCacheAdapter.js | 34 + .../RedisCacheAdapter/KeyPromiseQueue.js | 59 + lib/Adapters/Cache/RedisCacheAdapter/index.js | 130 + lib/Adapters/Email/MailAdapter.js | 40 + lib/Adapters/Files/FilesAdapter.js | 136 + lib/Adapters/Files/GridFSBucketAdapter.js | 273 ++ lib/Adapters/Files/GridStoreAdapter.js | 182 ++ lib/Adapters/Logger/LoggerAdapter.js | 39 + lib/Adapters/Logger/WinstonLogger.js | 137 + lib/Adapters/Logger/WinstonLoggerAdapter.js | 75 + lib/Adapters/MessageQueue/EventEmitterMQ.js | 73 + lib/Adapters/PubSub/EventEmitterPubSub.js | 69 + lib/Adapters/PubSub/PubSubAdapter.js | 39 + lib/Adapters/PubSub/RedisPubSub.js | 33 + lib/Adapters/Push/PushAdapter.js | 50 + lib/Adapters/Storage/Mongo/MongoCollection.js | 229 ++ .../Storage/Mongo/MongoSchemaCollection.js | 365 +++ .../Storage/Mongo/MongoStorageAdapter.js | 957 +++++++ lib/Adapters/Storage/Mongo/MongoTransform.js | 1795 ++++++++++++ .../Storage/Postgres/PostgresClient.js | 40 + .../Storage/Postgres/PostgresConfigParser.js | 95 + .../Postgres/PostgresStorageAdapter.js | 2494 +++++++++++++++++ .../Storage/Postgres/sql/array/add-unique.sql | 11 + .../Storage/Postgres/sql/array/add.sql | 11 + .../Postgres/sql/array/contains-all-regex.sql | 14 + .../Postgres/sql/array/contains-all.sql | 14 + .../Storage/Postgres/sql/array/contains.sql | 11 + .../Storage/Postgres/sql/array/remove.sql | 11 + lib/Adapters/Storage/Postgres/sql/index.js | 35 + .../sql/misc/json-object-set-keys.sql | 19 + lib/Adapters/Storage/StorageAdapter.js | 2 + lib/Adapters/WebSocketServer/WSAdapter.js | 45 + lib/Adapters/WebSocketServer/WSSAdapter.js | 74 + lib/Auth.js | 373 +++ lib/ClientSDK.js | 47 + lib/Config.js | 471 ++++ lib/Controllers/AdaptableController.js | 88 + lib/Controllers/AnalyticsController.js | 52 + lib/Controllers/CacheController.js | 92 + lib/Controllers/DatabaseController.js | 1568 +++++++++++ lib/Controllers/FilesController.js | 136 + lib/Controllers/HooksController.js | 302 ++ lib/Controllers/LiveQueryController.js | 78 + lib/Controllers/LoggerController.js | 265 ++ lib/Controllers/ParseGraphQLController.js | 358 +++ lib/Controllers/PushController.js | 257 ++ lib/Controllers/SchemaCache.js | 75 + lib/Controllers/SchemaController.js | 1670 +++++++++++ lib/Controllers/UserController.js | 375 +++ lib/Controllers/index.js | 312 +++ lib/Controllers/types.js | 2 + lib/GraphQL/ParseGraphQLSchema.js | 446 +++ lib/GraphQL/ParseGraphQLServer.js | 140 + lib/GraphQL/helpers/objectsMutations.js | 40 + lib/GraphQL/helpers/objectsQueries.js | 309 ++ .../loaders/defaultGraphQLMutations.js | 28 + lib/GraphQL/loaders/defaultGraphQLQueries.js | 29 + lib/GraphQL/loaders/defaultGraphQLTypes.js | 1271 +++++++++ lib/GraphQL/loaders/defaultRelaySchema.js | 71 + lib/GraphQL/loaders/filesMutations.js | 103 + lib/GraphQL/loaders/functionsMutations.js | 90 + lib/GraphQL/loaders/parseClassMutations.js | 288 ++ lib/GraphQL/loaders/parseClassQueries.js | 150 + lib/GraphQL/loaders/parseClassTypes.js | 531 ++++ lib/GraphQL/loaders/schemaDirectives.js | 72 + lib/GraphQL/loaders/schemaMutations.js | 179 ++ lib/GraphQL/loaders/schemaQueries.js | 93 + lib/GraphQL/loaders/schemaTypes.js | 376 +++ lib/GraphQL/loaders/usersMutations.js | 332 +++ lib/GraphQL/loaders/usersQueries.js | 111 + lib/GraphQL/parseGraphQLUtils.js | 69 + lib/GraphQL/transformers/className.js | 17 + lib/GraphQL/transformers/constraintType.js | 73 + lib/GraphQL/transformers/inputType.js | 71 + lib/GraphQL/transformers/mutation.js | 275 ++ lib/GraphQL/transformers/outputType.js | 71 + lib/GraphQL/transformers/query.js | 273 ++ lib/GraphQL/transformers/schemaFields.js | 128 + lib/LiveQuery/Client.js | 114 + lib/LiveQuery/Id.js | 26 + lib/LiveQuery/ParseCloudCodePublisher.js | 50 + lib/LiveQuery/ParseLiveQueryServer.js | 848 ++++++ lib/LiveQuery/ParsePubSub.js | 49 + lib/LiveQuery/ParseWebSocketServer.js | 80 + lib/LiveQuery/QueryTools.js | 452 +++ lib/LiveQuery/RequestSchema.js | 146 + lib/LiveQuery/SessionTokenCache.js | 67 + lib/LiveQuery/Subscription.js | 61 + lib/LiveQuery/equalObjects.js | 62 + lib/Options/Definitions.js | 715 +++++ lib/Options/docs.js | 178 ++ lib/Options/index.js | 18 + lib/Options/parsers.js | 90 + lib/Page.js | 53 + lib/ParseMessageQueue.js | 34 + lib/ParseServer.js | 499 ++++ lib/ParseServerRESTController.js | 184 ++ lib/PromiseRouter.js | 255 ++ lib/Push/PushQueue.js | 79 + lib/Push/PushWorker.js | 130 + lib/Push/utils.js | 159 ++ lib/RestQuery.js | 979 +++++++ lib/RestWrite.js | 1485 ++++++++++ lib/Routers/AggregateRouter.js | 153 + lib/Routers/AnalyticsRouter.js | 32 + lib/Routers/AudiencesRouter.js | 70 + lib/Routers/ClassesRouter.js | 231 ++ lib/Routers/CloudCodeRouter.js | 105 + lib/Routers/FeaturesRouter.js | 79 + lib/Routers/FilesRouter.js | 280 ++ lib/Routers/FunctionsRouter.js | 181 ++ lib/Routers/GlobalConfigRouter.js | 95 + lib/Routers/GraphQLRouter.js | 55 + lib/Routers/HooksRouter.js | 144 + lib/Routers/IAPValidationRouter.js | 136 + lib/Routers/InstallationsRouter.js | 57 + lib/Routers/LogsRouter.js | 71 + lib/Routers/PagesRouter.js | 693 +++++ lib/Routers/PublicAPIRouter.js | 322 +++ lib/Routers/PurgeRouter.js | 60 + lib/Routers/PushRouter.js | 92 + lib/Routers/RolesRouter.js | 40 + lib/Routers/SchemasRouter.js | 120 + lib/Routers/SessionsRouter.js | 107 + lib/Routers/UsersRouter.js | 470 ++++ lib/StatusHandler.js | 386 +++ lib/TestUtils.js | 31 + lib/Utils.js | 139 + lib/batch.js | 135 + lib/cache.js | 16 + .../definitions/parse-live-query-server.js | 12 + lib/cli/definitions/parse-server.js | 12 + lib/cli/parse-live-query-server.js | 19 + lib/cli/parse-server.js | 111 + lib/cli/utils/commander.js | 163 ++ lib/cli/utils/runner.js | 65 + lib/cloud-code/HTTPResponse.js | 73 + lib/cloud-code/Parse.Cloud.js | 719 +++++ lib/cloud-code/httpRequest.js | 192 ++ lib/cryptoUtils.js | 62 + lib/defaults.js | 60 + lib/deprecated.js | 13 + lib/index.js | 107 + lib/logger.js | 47 + lib/middlewares.js | 492 ++++ lib/password.js | 38 + lib/request.js | 4 + lib/requiredParameter.js | 13 + lib/rest.js | 208 ++ lib/triggers.js | 1032 +++++++ lib/vendor/README.md | 8 + lib/vendor/mongodbUrl.js | 1064 +++++++ 187 files changed, 37912 insertions(+), 1 deletion(-) create mode 100644 lib/AccountLockout.js create mode 100644 lib/Adapters/AdapterLoader.js create mode 100644 lib/Adapters/Analytics/AnalyticsAdapter.js create mode 100644 lib/Adapters/Auth/AuthAdapter.js create mode 100644 lib/Adapters/Auth/OAuth1Client.js create mode 100644 lib/Adapters/Auth/apple.js create mode 100644 lib/Adapters/Auth/facebook.js create mode 100644 lib/Adapters/Auth/gcenter.js create mode 100644 lib/Adapters/Auth/github.js create mode 100644 lib/Adapters/Auth/google.js create mode 100644 lib/Adapters/Auth/gpgames.js create mode 100644 lib/Adapters/Auth/httpsRequest.js create mode 100755 lib/Adapters/Auth/index.js create mode 100644 lib/Adapters/Auth/instagram.js create mode 100644 lib/Adapters/Auth/janraincapture.js create mode 100644 lib/Adapters/Auth/janrainengage.js create mode 100644 lib/Adapters/Auth/keycloak.js create mode 100644 lib/Adapters/Auth/ldap.js create mode 100644 lib/Adapters/Auth/line.js create mode 100644 lib/Adapters/Auth/linkedin.js create mode 100644 lib/Adapters/Auth/meetup.js create mode 100644 lib/Adapters/Auth/microsoft.js create mode 100644 lib/Adapters/Auth/oauth2.js create mode 100644 lib/Adapters/Auth/phantauth.js create mode 100644 lib/Adapters/Auth/qq.js create mode 100644 lib/Adapters/Auth/spotify.js create mode 100644 lib/Adapters/Auth/twitter.js create mode 100644 lib/Adapters/Auth/vkontakte.js create mode 100644 lib/Adapters/Auth/wechat.js create mode 100644 lib/Adapters/Auth/weibo.js create mode 100644 lib/Adapters/Cache/CacheAdapter.js create mode 100644 lib/Adapters/Cache/InMemoryCache.js create mode 100644 lib/Adapters/Cache/InMemoryCacheAdapter.js create mode 100644 lib/Adapters/Cache/LRUCache.js create mode 100644 lib/Adapters/Cache/NullCacheAdapter.js create mode 100644 lib/Adapters/Cache/RedisCacheAdapter/KeyPromiseQueue.js create mode 100644 lib/Adapters/Cache/RedisCacheAdapter/index.js create mode 100644 lib/Adapters/Email/MailAdapter.js create mode 100644 lib/Adapters/Files/FilesAdapter.js create mode 100644 lib/Adapters/Files/GridFSBucketAdapter.js create mode 100644 lib/Adapters/Files/GridStoreAdapter.js create mode 100644 lib/Adapters/Logger/LoggerAdapter.js create mode 100644 lib/Adapters/Logger/WinstonLogger.js create mode 100644 lib/Adapters/Logger/WinstonLoggerAdapter.js create mode 100644 lib/Adapters/MessageQueue/EventEmitterMQ.js create mode 100644 lib/Adapters/PubSub/EventEmitterPubSub.js create mode 100644 lib/Adapters/PubSub/PubSubAdapter.js create mode 100644 lib/Adapters/PubSub/RedisPubSub.js create mode 100644 lib/Adapters/Push/PushAdapter.js create mode 100644 lib/Adapters/Storage/Mongo/MongoCollection.js create mode 100644 lib/Adapters/Storage/Mongo/MongoSchemaCollection.js create mode 100644 lib/Adapters/Storage/Mongo/MongoStorageAdapter.js create mode 100644 lib/Adapters/Storage/Mongo/MongoTransform.js create mode 100644 lib/Adapters/Storage/Postgres/PostgresClient.js create mode 100644 lib/Adapters/Storage/Postgres/PostgresConfigParser.js create mode 100644 lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js create mode 100644 lib/Adapters/Storage/Postgres/sql/array/add-unique.sql create mode 100644 lib/Adapters/Storage/Postgres/sql/array/add.sql create mode 100644 lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql create mode 100644 lib/Adapters/Storage/Postgres/sql/array/contains-all.sql create mode 100644 lib/Adapters/Storage/Postgres/sql/array/contains.sql create mode 100644 lib/Adapters/Storage/Postgres/sql/array/remove.sql create mode 100644 lib/Adapters/Storage/Postgres/sql/index.js create mode 100644 lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql create mode 100644 lib/Adapters/Storage/StorageAdapter.js create mode 100644 lib/Adapters/WebSocketServer/WSAdapter.js create mode 100644 lib/Adapters/WebSocketServer/WSSAdapter.js create mode 100644 lib/Auth.js create mode 100644 lib/ClientSDK.js create mode 100644 lib/Config.js create mode 100644 lib/Controllers/AdaptableController.js create mode 100644 lib/Controllers/AnalyticsController.js create mode 100644 lib/Controllers/CacheController.js create mode 100644 lib/Controllers/DatabaseController.js create mode 100644 lib/Controllers/FilesController.js create mode 100644 lib/Controllers/HooksController.js create mode 100644 lib/Controllers/LiveQueryController.js create mode 100644 lib/Controllers/LoggerController.js create mode 100644 lib/Controllers/ParseGraphQLController.js create mode 100644 lib/Controllers/PushController.js create mode 100644 lib/Controllers/SchemaCache.js create mode 100644 lib/Controllers/SchemaController.js create mode 100644 lib/Controllers/UserController.js create mode 100644 lib/Controllers/index.js create mode 100644 lib/Controllers/types.js create mode 100644 lib/GraphQL/ParseGraphQLSchema.js create mode 100644 lib/GraphQL/ParseGraphQLServer.js create mode 100644 lib/GraphQL/helpers/objectsMutations.js create mode 100644 lib/GraphQL/helpers/objectsQueries.js create mode 100644 lib/GraphQL/loaders/defaultGraphQLMutations.js create mode 100644 lib/GraphQL/loaders/defaultGraphQLQueries.js create mode 100644 lib/GraphQL/loaders/defaultGraphQLTypes.js create mode 100644 lib/GraphQL/loaders/defaultRelaySchema.js create mode 100644 lib/GraphQL/loaders/filesMutations.js create mode 100644 lib/GraphQL/loaders/functionsMutations.js create mode 100644 lib/GraphQL/loaders/parseClassMutations.js create mode 100644 lib/GraphQL/loaders/parseClassQueries.js create mode 100644 lib/GraphQL/loaders/parseClassTypes.js create mode 100644 lib/GraphQL/loaders/schemaDirectives.js create mode 100644 lib/GraphQL/loaders/schemaMutations.js create mode 100644 lib/GraphQL/loaders/schemaQueries.js create mode 100644 lib/GraphQL/loaders/schemaTypes.js create mode 100644 lib/GraphQL/loaders/usersMutations.js create mode 100644 lib/GraphQL/loaders/usersQueries.js create mode 100644 lib/GraphQL/parseGraphQLUtils.js create mode 100644 lib/GraphQL/transformers/className.js create mode 100644 lib/GraphQL/transformers/constraintType.js create mode 100644 lib/GraphQL/transformers/inputType.js create mode 100644 lib/GraphQL/transformers/mutation.js create mode 100644 lib/GraphQL/transformers/outputType.js create mode 100644 lib/GraphQL/transformers/query.js create mode 100644 lib/GraphQL/transformers/schemaFields.js create mode 100644 lib/LiveQuery/Client.js create mode 100644 lib/LiveQuery/Id.js create mode 100644 lib/LiveQuery/ParseCloudCodePublisher.js create mode 100644 lib/LiveQuery/ParseLiveQueryServer.js create mode 100644 lib/LiveQuery/ParsePubSub.js create mode 100644 lib/LiveQuery/ParseWebSocketServer.js create mode 100644 lib/LiveQuery/QueryTools.js create mode 100644 lib/LiveQuery/RequestSchema.js create mode 100644 lib/LiveQuery/SessionTokenCache.js create mode 100644 lib/LiveQuery/Subscription.js create mode 100644 lib/LiveQuery/equalObjects.js create mode 100644 lib/Options/Definitions.js create mode 100644 lib/Options/docs.js create mode 100644 lib/Options/index.js create mode 100644 lib/Options/parsers.js create mode 100644 lib/Page.js create mode 100644 lib/ParseMessageQueue.js create mode 100644 lib/ParseServer.js create mode 100644 lib/ParseServerRESTController.js create mode 100644 lib/PromiseRouter.js create mode 100644 lib/Push/PushQueue.js create mode 100644 lib/Push/PushWorker.js create mode 100644 lib/Push/utils.js create mode 100644 lib/RestQuery.js create mode 100644 lib/RestWrite.js create mode 100644 lib/Routers/AggregateRouter.js create mode 100644 lib/Routers/AnalyticsRouter.js create mode 100644 lib/Routers/AudiencesRouter.js create mode 100644 lib/Routers/ClassesRouter.js create mode 100644 lib/Routers/CloudCodeRouter.js create mode 100644 lib/Routers/FeaturesRouter.js create mode 100644 lib/Routers/FilesRouter.js create mode 100644 lib/Routers/FunctionsRouter.js create mode 100644 lib/Routers/GlobalConfigRouter.js create mode 100644 lib/Routers/GraphQLRouter.js create mode 100644 lib/Routers/HooksRouter.js create mode 100644 lib/Routers/IAPValidationRouter.js create mode 100644 lib/Routers/InstallationsRouter.js create mode 100644 lib/Routers/LogsRouter.js create mode 100644 lib/Routers/PagesRouter.js create mode 100644 lib/Routers/PublicAPIRouter.js create mode 100644 lib/Routers/PurgeRouter.js create mode 100644 lib/Routers/PushRouter.js create mode 100644 lib/Routers/RolesRouter.js create mode 100644 lib/Routers/SchemasRouter.js create mode 100644 lib/Routers/SessionsRouter.js create mode 100644 lib/Routers/UsersRouter.js create mode 100644 lib/StatusHandler.js create mode 100644 lib/TestUtils.js create mode 100644 lib/Utils.js create mode 100644 lib/batch.js create mode 100644 lib/cache.js create mode 100644 lib/cli/definitions/parse-live-query-server.js create mode 100644 lib/cli/definitions/parse-server.js create mode 100644 lib/cli/parse-live-query-server.js create mode 100755 lib/cli/parse-server.js create mode 100644 lib/cli/utils/commander.js create mode 100644 lib/cli/utils/runner.js create mode 100644 lib/cloud-code/HTTPResponse.js create mode 100644 lib/cloud-code/Parse.Cloud.js create mode 100644 lib/cloud-code/httpRequest.js create mode 100644 lib/cryptoUtils.js create mode 100644 lib/defaults.js create mode 100644 lib/deprecated.js create mode 100644 lib/index.js create mode 100644 lib/logger.js create mode 100644 lib/middlewares.js create mode 100644 lib/password.js create mode 100644 lib/request.js create mode 100644 lib/requiredParameter.js create mode 100644 lib/rest.js create mode 100644 lib/triggers.js create mode 100644 lib/vendor/README.md create mode 100644 lib/vendor/mongodbUrl.js diff --git a/.gitignore b/.gitignore index e4e19156c2..60fbcf9a3d 100644 --- a/.gitignore +++ b/.gitignore @@ -45,7 +45,7 @@ node_modules .vscode # Babel.js -lib/ +# lib/ - Inlcuded built version # cache folder .cache diff --git a/lib/AccountLockout.js b/lib/AccountLockout.js new file mode 100644 index 0000000000..34087024bb --- /dev/null +++ b/lib/AccountLockout.js @@ -0,0 +1,193 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.AccountLockout = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// This class handles the Account Lockout Policy settings. +class AccountLockout { + constructor(user, config) { + this._user = user; + this._config = config; + } + /** + * set _failed_login_count to value + */ + + + _setFailedLoginCount(value) { + const query = { + username: this._user.username + }; + const updateFields = { + _failed_login_count: value + }; + return this._config.database.update('_User', query, updateFields); + } + /** + * check if the _failed_login_count field has been set + */ + + + _isFailedLoginCountSet() { + const query = { + username: this._user.username, + _failed_login_count: { + $exists: true + } + }; + return this._config.database.find('_User', query).then(users => { + if (Array.isArray(users) && users.length > 0) { + return true; + } else { + return false; + } + }); + } + /** + * if _failed_login_count is NOT set then set it to 0 + * else do nothing + */ + + + _initFailedLoginCount() { + return this._isFailedLoginCountSet().then(failedLoginCountIsSet => { + if (!failedLoginCountIsSet) { + return this._setFailedLoginCount(0); + } + }); + } + /** + * increment _failed_login_count by 1 + */ + + + _incrementFailedLoginCount() { + const query = { + username: this._user.username + }; + const updateFields = { + _failed_login_count: { + __op: 'Increment', + amount: 1 + } + }; + return this._config.database.update('_User', query, updateFields); + } + /** + * if the failed login count is greater than the threshold + * then sets lockout expiration to 'currenttime + accountPolicy.duration', i.e., account is locked out for the next 'accountPolicy.duration' minutes + * else do nothing + */ + + + _setLockoutExpiration() { + const query = { + username: this._user.username, + _failed_login_count: { + $gte: this._config.accountLockout.threshold + } + }; + const now = new Date(); + const updateFields = { + _account_lockout_expires_at: _node.default._encode(new Date(now.getTime() + this._config.accountLockout.duration * 60 * 1000)) + }; + return this._config.database.update('_User', query, updateFields).catch(err => { + if (err && err.code && err.message && err.code === 101 && err.message === 'Object not found.') { + return; // nothing to update so we are good + } else { + throw err; // unknown error + } + }); + } + /** + * if _account_lockout_expires_at > current_time and _failed_login_count > threshold + * reject with account locked error + * else + * resolve + */ + + + _notLocked() { + const query = { + username: this._user.username, + _account_lockout_expires_at: { + $gt: _node.default._encode(new Date()) + }, + _failed_login_count: { + $gte: this._config.accountLockout.threshold + } + }; + return this._config.database.find('_User', query).then(users => { + if (Array.isArray(users) && users.length > 0) { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Your account is locked due to multiple failed login attempts. Please try again after ' + this._config.accountLockout.duration + ' minute(s)'); + } + }); + } + /** + * set and/or increment _failed_login_count + * if _failed_login_count > threshold + * set the _account_lockout_expires_at to current_time + accountPolicy.duration + * else + * do nothing + */ + + + _handleFailedLoginAttempt() { + return this._initFailedLoginCount().then(() => { + return this._incrementFailedLoginCount(); + }).then(() => { + return this._setLockoutExpiration(); + }); + } + /** + * handle login attempt if the Account Lockout Policy is enabled + */ + + + handleLoginAttempt(loginSuccessful) { + if (!this._config.accountLockout) { + return Promise.resolve(); + } + + return this._notLocked().then(() => { + if (loginSuccessful) { + return this._setFailedLoginCount(0); + } else { + return this._handleFailedLoginAttempt(); + } + }); + } + /** + * Removes the account lockout. + */ + + + unlockAccount() { + if (!this._config.accountLockout || !this._config.accountLockout.unlockOnPasswordReset) { + return Promise.resolve(); + } + + return this._config.database.update('_User', { + username: this._user.username + }, { + _failed_login_count: { + __op: 'Delete' + }, + _account_lockout_expires_at: { + __op: 'Delete' + } + }); + } + +} + +exports.AccountLockout = AccountLockout; +var _default = AccountLockout; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9BY2NvdW50TG9ja291dC5qcyJdLCJuYW1lcyI6WyJBY2NvdW50TG9ja291dCIsImNvbnN0cnVjdG9yIiwidXNlciIsImNvbmZpZyIsIl91c2VyIiwiX2NvbmZpZyIsIl9zZXRGYWlsZWRMb2dpbkNvdW50IiwidmFsdWUiLCJxdWVyeSIsInVzZXJuYW1lIiwidXBkYXRlRmllbGRzIiwiX2ZhaWxlZF9sb2dpbl9jb3VudCIsImRhdGFiYXNlIiwidXBkYXRlIiwiX2lzRmFpbGVkTG9naW5Db3VudFNldCIsIiRleGlzdHMiLCJmaW5kIiwidGhlbiIsInVzZXJzIiwiQXJyYXkiLCJpc0FycmF5IiwibGVuZ3RoIiwiX2luaXRGYWlsZWRMb2dpbkNvdW50IiwiZmFpbGVkTG9naW5Db3VudElzU2V0IiwiX2luY3JlbWVudEZhaWxlZExvZ2luQ291bnQiLCJfX29wIiwiYW1vdW50IiwiX3NldExvY2tvdXRFeHBpcmF0aW9uIiwiJGd0ZSIsImFjY291bnRMb2Nrb3V0IiwidGhyZXNob2xkIiwibm93IiwiRGF0ZSIsIl9hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCIsIlBhcnNlIiwiX2VuY29kZSIsImdldFRpbWUiLCJkdXJhdGlvbiIsImNhdGNoIiwiZXJyIiwiY29kZSIsIm1lc3NhZ2UiLCJfbm90TG9ja2VkIiwiJGd0IiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiX2hhbmRsZUZhaWxlZExvZ2luQXR0ZW1wdCIsImhhbmRsZUxvZ2luQXR0ZW1wdCIsImxvZ2luU3VjY2Vzc2Z1bCIsIlByb21pc2UiLCJyZXNvbHZlIiwidW5sb2NrQWNjb3VudCIsInVubG9ja09uUGFzc3dvcmRSZXNldCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUNBOzs7O0FBREE7QUFHTyxNQUFNQSxjQUFOLENBQXFCO0FBQzFCQyxFQUFBQSxXQUFXLENBQUNDLElBQUQsRUFBT0MsTUFBUCxFQUFlO0FBQ3hCLFNBQUtDLEtBQUwsR0FBYUYsSUFBYjtBQUNBLFNBQUtHLE9BQUws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ZW50IjpbIi8vIFRoaXMgY2xhc3MgaGFuZGxlcyB0aGUgQWNjb3VudCBMb2Nrb3V0IFBvbGljeSBzZXR0aW5ncy5cbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcblxuZXhwb3J0IGNsYXNzIEFjY291bnRMb2Nrb3V0IHtcbiAgY29uc3RydWN0b3IodXNlciwgY29uZmlnKSB7XG4gICAgdGhpcy5fdXNlciA9IHVzZXI7XG4gICAgdGhpcy5fY29uZmlnID0gY29uZmlnO1xuICB9XG5cbiAgLyoqXG4gICAqIHNldCBfZmFpbGVkX2xvZ2luX2NvdW50IHRvIHZhbHVlXG4gICAqL1xuICBfc2V0RmFpbGVkTG9naW5Db3VudCh2YWx1ZSkge1xuICAgIGNvbnN0IHF1ZXJ5ID0ge1xuICAgICAgdXNlcm5hbWU6IHRoaXMuX3VzZXIudXNlcm5hbWUsXG4gICAgfTtcblxuICAgIGNvbnN0IHVwZGF0ZUZpZWxkcyA9IHtcbiAgICAgIF9mYWlsZWRfbG9naW5fY291bnQ6IHZhbHVlLFxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy5fY29uZmlnLmRhdGFiYXNlLnVwZGF0ZSgnX1VzZXInLCBxdWVyeSwgdXBkYXRlRmllbGRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBjaGVjayBpZiB0aGUgX2ZhaWxlZF9sb2dpbl9jb3VudCBmaWVsZCBoYXMgYmVlbiBzZXRcbiAgICovXG4gIF9pc0ZhaWxlZExvZ2luQ291bnRTZXQoKSB7XG4gICAgY29uc3QgcXVlcnkgPSB7XG4gICAgICB1c2VybmFtZTogdGhpcy5fdXNlci51c2VybmFtZSxcbiAgICAgIF9mYWlsZWRfbG9naW5fY291bnQ6IHsgJGV4aXN0czogdHJ1ZSB9LFxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy5fY29uZmlnLmRhdGFiYXNlLmZpbmQoJ19Vc2VyJywgcXVlcnkpLnRoZW4odXNlcnMgPT4ge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodXNlcnMpICYmIHVzZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogaWYgX2ZhaWxlZF9sb2dpbl9jb3VudCBpcyBOT1Qgc2V0IHRoZW4gc2V0IGl0IHRvIDBcbiAgICogZWxzZSBkbyBub3RoaW5nXG4gICAqL1xuICBfaW5pdEZhaWxlZExvZ2luQ291bnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2lzRmFpbGVkTG9naW5Db3VudFNldCgpLnRoZW4oZmFpbGVkTG9naW5Db3VudElzU2V0ID0+IHtcbiAgICAgIGlmICghZmFpbGVkTG9naW5Db3VudElzU2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zZXRGYWlsZWRMb2dpbkNvdW50KDApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIGluY3JlbWVudCBfZmFpbGVkX2xvZ2luX2NvdW50IGJ5IDFcbiAgICovXG4gIF9pbmNyZW1lbnRGYWlsZWRMb2dpbkNvdW50KCkge1xuICAgIGNvbnN0IHF1ZXJ5ID0ge1xuICAgICAgdXNlcm5hbWU6IHRoaXMuX3VzZXIudXNlcm5hbWUsXG4gICAgfTtcblxuICAgIGNvbnN0IHVwZGF0ZUZpZWxkcyA9IHtcbiAgICAgIF9mYWlsZWRfbG9naW5fY291bnQ6IHsgX19vcDogJ0luY3JlbWVudCcsIGFtb3VudDogMSB9LFxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy5fY29uZmlnLmRhdGFiYXNlLnVwZGF0ZSgnX1VzZXInLCBxdWVyeSwgdXBkYXRlRmllbGRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBpZiB0aGUgZmFpbGVkIGxvZ2luIGNvdW50IGlzIGdyZWF0ZXIgdGhhbiB0aGUgdGhyZXNob2xkXG4gICAqIHRoZW4gc2V0cyBsb2Nrb3V0IGV4cGlyYXRpb24gdG8gJ2N1cnJlbnR0aW1lICsgYWNjb3VudFBvbGljeS5kdXJhdGlvbicsIGkuZS4sIGFjY291bnQgaXMgbG9ja2VkIG91dCBmb3IgdGhlIG5leHQgJ2FjY291bnRQb2xpY3kuZHVyYXRpb24nIG1pbnV0ZXNcbiAgICogZWxzZSBkbyBub3RoaW5nXG4gICAqL1xuICBfc2V0TG9ja291dEV4cGlyYXRpb24oKSB7XG4gICAgY29uc3QgcXVlcnkgPSB7XG4gICAgICB1c2VybmFtZTogdGhpcy5fdXNlci51c2VybmFtZSxcbiAgICAgIF9mYWlsZWRfbG9naW5fY291bnQ6IHsgJGd0ZTogdGhpcy5fY29uZmlnLmFjY291bnRMb2Nrb3V0LnRocmVzaG9sZCB9LFxuICAgIH07XG5cbiAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuXG4gICAgY29uc3QgdXBkYXRlRmllbGRzID0ge1xuICAgICAgX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0OiBQYXJzZS5fZW5jb2RlKFxuICAgICAgICBuZXcgRGF0ZShub3cuZ2V0VGltZSgpICsgdGhpcy5fY29uZmlnLmFjY291bnRMb2Nrb3V0LmR1cmF0aW9uICogNjAgKiAxMDAwKVxuICAgICAgKSxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHRoaXMuX2NvbmZpZy5kYXRhYmFzZS51cGRhdGUoJ19Vc2VyJywgcXVlcnksIHVwZGF0ZUZpZWxkcykuY2F0Y2goZXJyID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgZXJyICYmXG4gICAgICAgIGVyci5jb2RlICYmXG4gICAgICAgIGVyci5tZXNzYWdlICYmXG4gICAgICAgIGVyci5jb2RlID09PSAxMDEgJiZcbiAgICAgICAgZXJyLm1lc3NhZ2UgPT09ICdPYmplY3Qgbm90IGZvdW5kLidcbiAgICAgICkge1xuICAgICAgICByZXR1cm47IC8vIG5vdGhpbmcgdG8gdXBkYXRlIHNvIHdlIGFyZSBnb29kXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlcnI7IC8vIHVua25vd24gZXJyb3JcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBpZiBfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQgPiBjdXJyZW50X3RpbWUgYW5kIF9mYWlsZWRfbG9naW5fY291bnQgPiB0aHJlc2hvbGRcbiAgICogICByZWplY3Qgd2l0aCBhY2NvdW50IGxvY2tlZCBlcnJvclxuICAgKiBlbHNlXG4gICAqICAgcmVzb2x2ZVxuICAgKi9cbiAgX25vdExvY2tlZCgpIHtcbiAgICBjb25zdCBxdWVyeSA9IHtcbiAgICAgIHVzZXJuYW1lOiB0aGlzLl91c2VyLnVzZXJuYW1lLFxuICAgICAgX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0OiB7ICRndDogUGFyc2UuX2VuY29kZShuZXcgRGF0ZSgpKSB9LFxuICAgICAgX2ZhaWxlZF9sb2dpbl9jb3VudDogeyAkZ3RlOiB0aGlzLl9jb25maWcuYWNjb3VudExvY2tvdXQudGhyZXNob2xkIH0sXG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLl9jb25maWcuZGF0YWJhc2UuZmluZCgnX1VzZXInLCBxdWVyeSkudGhlbih1c2VycyA9PiB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheSh1c2VycykgJiYgdXNlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICAgICAnWW91ciBhY2NvdW50IGlzIGxvY2tlZCBkdWUgdG8gbXVsdGlwbGUgZmFpbGVkIGxvZ2luIGF0dGVtcHRzLiBQbGVhc2UgdHJ5IGFnYWluIGFmdGVyICcgK1xuICAgICAgICAgICAgdGhpcy5fY29uZmlnLmFjY291bnRMb2Nrb3V0LmR1cmF0aW9uICtcbiAgICAgICAgICAgICcgbWludXRlKHMpJ1xuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIHNldCBhbmQvb3IgaW5jcmVtZW50IF9mYWlsZWRfbG9naW5fY291bnRcbiAgICogaWYgX2ZhaWxlZF9sb2dpbl9jb3VudCA+IHRocmVzaG9sZFxuICAgKiAgIHNldCB0aGUgX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0IHRvIGN1cnJlbnRfdGltZSArIGFjY291bnRQb2xpY3kuZHVyYXRpb25cbiAgICogZWxzZVxuICAgKiAgIGRvIG5vdGhpbmdcbiAgICovXG4gIF9oYW5kbGVGYWlsZWRMb2dpbkF0dGVtcHQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2luaXRGYWlsZWRMb2dpbkNvdW50KClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2luY3JlbWVudEZhaWxlZExvZ2luQ291bnQoKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zZXRMb2Nrb3V0RXhwaXJhdGlvbigpO1xuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogaGFuZGxlIGxvZ2luIGF0dGVtcHQgaWYgdGhlIEFjY291bnQgTG9ja291dCBQb2xpY3kgaXMgZW5hYmxlZFxuICAgKi9cbiAgaGFuZGxlTG9naW5BdHRlbXB0KGxvZ2luU3VjY2Vzc2Z1bCkge1xuICAgIGlmICghdGhpcy5fY29uZmlnLmFjY291bnRMb2Nrb3V0KSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9ub3RMb2NrZWQoKS50aGVuKCgpID0+IHtcbiAgICAgIGlmIChsb2dpblN1Y2Nlc3NmdWwpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldEZhaWxlZExvZ2luQ291bnQoMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcy5faGFuZGxlRmFpbGVkTG9naW5BdHRlbXB0KCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyB0aGUgYWNjb3VudCBsb2Nrb3V0LlxuICAgKi9cbiAgdW5sb2NrQWNjb3VudCgpIHtcbiAgICBpZiAoIXRoaXMuX2NvbmZpZy5hY2NvdW50TG9ja291dCB8fCAhdGhpcy5fY29uZmlnLmFjY291bnRMb2Nrb3V0LnVubG9ja09uUGFzc3dvcmRSZXNldCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY29uZmlnLmRhdGFiYXNlLnVwZGF0ZShcbiAgICAgICdfVXNlcicsXG4gICAgICB7IHVzZXJuYW1lOiB0aGlzLl91c2VyLnVzZXJuYW1lIH0sXG4gICAgICB7XG4gICAgICAgIF9mYWlsZWRfbG9naW5fY291bnQ6IHsgX19vcDogJ0RlbGV0ZScgfSxcbiAgICAgICAgX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0OiB7IF9fb3A6ICdEZWxldGUnIH0sXG4gICAgICB9XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBBY2NvdW50TG9ja291dDtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/AdapterLoader.js b/lib/Adapters/AdapterLoader.js new file mode 100644 index 0000000000..f295afe333 --- /dev/null +++ b/lib/Adapters/AdapterLoader.js @@ -0,0 +1,63 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.loadAdapter = loadAdapter; +exports.default = void 0; + +/** + * @module AdapterLoader + */ + +/** + * @static + * Attempt to load an adapter or fallback to the default. + * @param {Adapter} adapter an adapter + * @param {Adapter} defaultAdapter the default adapter to load + * @param {any} options options to pass to the contstructor + * @returns {Object} the loaded adapter + */ +function loadAdapter(adapter, defaultAdapter, options) { + if (!adapter) { + if (!defaultAdapter) { + return options; + } // Load from the default adapter when no adapter is set + + + return loadAdapter(defaultAdapter, undefined, options); + } else if (typeof adapter === 'function') { + try { + return adapter(options); + } catch (e) { + if (e.name === 'TypeError') { + var Adapter = adapter; + return new Adapter(options); + } else { + throw e; + } + } + } else if (typeof adapter === 'string') { + /* eslint-disable */ + adapter = require(adapter); // If it's define as a module, get the default + + if (adapter.default) { + adapter = adapter.default; + } + + return loadAdapter(adapter, undefined, options); + } else if (adapter.module) { + return loadAdapter(adapter.module, undefined, adapter.options); + } else if (adapter.class) { + return loadAdapter(adapter.class, undefined, adapter.options); + } else if (adapter.adapter) { + return loadAdapter(adapter.adapter, undefined, adapter.options); + } // return the adapter as provided + + + return adapter; +} + +var _default = loadAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9BZGFwdGVycy9BZGFwdGVyTG9hZGVyLmpzIl0sIm5hbWVzIjpbImxvYWRBZGFwdGVyIiwiYWRhcHRlciIsImRlZmF1bHRBZGFwdGVyIiwib3B0aW9ucyIsInVuZGVmaW5lZCIsImUiLCJuYW1lIiwiQWRhcHRlciIsInJlcXVpcmUiLCJkZWZhdWx0IiwibW9kdWxlIiwiY2xhc3MiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQSxXQUFULENBQXdCQyxPQUF4QixFQUFpQ0MsY0FBakMsRUFBaURDLE9BQWpELEVBQTZEO0FBQ2xFLE1BQUksQ0FBQ0YsT0FBTCxFQUFjO0FBQ1osUUFBSSxDQUFDQyxjQUFMLEVBQXFCO0FBQ25CLGFBQU9DLE9BQVA7QUFDRCxLQUhXLENBSVo7OztBQUNBLFdBQU9ILFdBQVcsQ0FBQ0UsY0FBRCxFQUFpQkUsU0FBakIsRUFBNEJELE9BQTVCLENBQWxCO0FBQ0QsR0FORCxNQU1PLElBQUksT0FBT0YsT0FBUCxLQUFtQixVQUF2QixFQUFtQztBQUN4QyxRQUFJO0FBQ0YsYUFBT0EsT0FBTyxDQUFDRSxPQUFELENBQWQ7QUFDRCxLQUZELENBRUUsT0FBT0UsQ0FBUCxFQUFVO0FBQ1YsVUFBSUEsQ0FBQyxDQUFDQyxJQUFGLEtBQVcsV0FBZixFQUE0QjtBQUMxQixZQUFJQyxPQUFPLEdBQUdOLE9BQWQ7QUFDQSxlQUFPLElBQUlNLE9BQUosQ0FBWUosT0FBWixDQUFQO0FBQ0QsT0FIRCxNQUdPO0FBQ0wsY0FBTUUsQ0FBTjtBQUNEO0FBQ0Y7QUFDRixHQVhNLE1BV0EsSUFBSSxPQUFPSixPQUFQLEtBQW1CLFFBQXZCLEVBQWlDO0FBQ3RDO0FBQ0FBLElBQUFBLE9BQU8sR0FBR08sT0FBTyxDQUFDUCxPQUFELENBQWpCLENBRnNDLENBR3RDOztBQUNBLFFBQUlBLE9BQU8sQ0FBQ1EsT0FBWixFQUFxQjtBQUNuQlIsTUFBQUEsT0FBTyxHQUFHQSxPQUFPLENBQUNRLE9BQWxCO0FBQ0Q7O0FBQ0QsV0FBT1QsV0FBVyxDQUFDQyxPQUFELEVBQVVHLFNBQVYsRUFBcUJELE9BQXJCLENBQWxCO0FBQ0QsR0FSTSxNQVFBLElBQUlGLE9BQU8sQ0FBQ1MsTUFBWixFQUFvQjtBQUN6QixXQUFPVixXQUFXLENBQUNDLE9BQU8sQ0FBQ1MsTUFBVCxFQUFpQk4sU0FBakIsRUFBNEJILE9BQU8sQ0FBQ0UsT0FBcEMsQ0FBbEI7QUFDRCxHQUZNLE1BRUEsSUFBSUYsT0FBTyxDQUFDVSxLQUFaLEVBQW1CO0FBQ3hCLFdBQU9YLFdBQVcsQ0FBQ0MsT0FBTyxDQUFDVSxLQUFULEVBQWdCUCxTQUFoQixFQUEyQkgsT0FBTyxDQUFDRSxPQUFuQyxDQUFsQjtBQUNELEdBRk0sTUFFQSxJQUFJRixPQUFPLENBQUNBLE9BQVosRUFBcUI7QUFDMUIsV0FBT0QsV0FBVyxDQUFDQyxPQUFPLENBQUNBLE9BQVQsRUFBa0JHLFNBQWxCLEVBQTZCSCxPQUFPLENBQUNFLE9BQXJDLENBQWxCO0FBQ0QsR0FoQ2lFLENBaUNsRTs7O0FBQ0EsU0FBT0YsT0FBUDtBQUNEOztlQUVjRCxXIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbW9kdWxlIEFkYXB0ZXJMb2FkZXJcbiAqL1xuLyoqXG4gKiBAc3RhdGljXG4gKiBBdHRlbXB0IHRvIGxvYWQgYW4gYWRhcHRlciBvciBmYWxsYmFjayB0byB0aGUgZGVmYXVsdC5cbiAqIEBwYXJhbSB7QWRhcHRlcn0gYWRhcHRlciBhbiBhZGFwdGVyXG4gKiBAcGFyYW0ge0FkYXB0ZXJ9IGRlZmF1bHRBZGFwdGVyIHRoZSBkZWZhdWx0IGFkYXB0ZXIgdG8gbG9hZFxuICogQHBhcmFtIHthbnl9IG9wdGlvbnMgb3B0aW9ucyB0byBwYXNzIHRvIHRoZSBjb250c3RydWN0b3JcbiAqIEByZXR1cm5zIHtPYmplY3R9IHRoZSBsb2FkZWQgYWRhcHRlclxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9hZEFkYXB0ZXI8VD4oYWRhcHRlciwgZGVmYXVsdEFkYXB0ZXIsIG9wdGlvbnMpOiBUIHtcbiAgaWYgKCFhZGFwdGVyKSB7XG4gICAgaWYgKCFkZWZhdWx0QWRhcHRlcikge1xuICAgICAgcmV0dXJuIG9wdGlvbnM7XG4gICAgfVxuICAgIC8vIExvYWQgZnJvbSB0aGUgZGVmYXVsdCBhZGFwdGVyIHdoZW4gbm8gYWRhcHRlciBpcyBzZXRcbiAgICByZXR1cm4gbG9hZEFkYXB0ZXIoZGVmYXVsdEFkYXB0ZXIsIHVuZGVmaW5lZCwgb3B0aW9ucyk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGFkYXB0ZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGFkYXB0ZXIob3B0aW9ucyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKGUubmFtZSA9PT0gJ1R5cGVFcnJvcicpIHtcbiAgICAgICAgdmFyIEFkYXB0ZXIgPSBhZGFwdGVyO1xuICAgICAgICByZXR1cm4gbmV3IEFkYXB0ZXIob3B0aW9ucyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgYWRhcHRlciA9PT0gJ3N0cmluZycpIHtcbiAgICAvKiBlc2xpbnQtZGlzYWJsZSAqL1xuICAgIGFkYXB0ZXIgPSByZXF1aXJlKGFkYXB0ZXIpO1xuICAgIC8vIElmIGl0J3MgZGVmaW5lIGFzIGEgbW9kdWxlLCBnZXQgdGhlIGRlZmF1bHRcbiAgICBpZiAoYWRhcHRlci5kZWZhdWx0KSB7XG4gICAgICBhZGFwdGVyID0gYWRhcHRlci5kZWZhdWx0O1xuICAgIH1cbiAgICByZXR1cm4gbG9hZEFkYXB0ZXIoYWRhcHRlciwgdW5kZWZpbmVkLCBvcHRpb25zKTtcbiAgfSBlbHNlIGlmIChhZGFwdGVyLm1vZHVsZSkge1xuICAgIHJldHVybiBsb2FkQWRhcHRlcihhZGFwdGVyLm1vZHVsZSwgdW5kZWZpbmVkLCBhZGFwdGVyLm9wdGlvbnMpO1xuICB9IGVsc2UgaWYgKGFkYXB0ZXIuY2xhc3MpIHtcbiAgICByZXR1cm4gbG9hZEFkYXB0ZXIoYWRhcHRlci5jbGFzcywgdW5kZWZpbmVkLCBhZGFwdGVyLm9wdGlvbnMpO1xuICB9IGVsc2UgaWYgKGFkYXB0ZXIuYWRhcHRlcikge1xuICAgIHJldHVybiBsb2FkQWRhcHRlcihhZGFwdGVyLmFkYXB0ZXIsIHVuZGVmaW5lZCwgYWRhcHRlci5vcHRpb25zKTtcbiAgfVxuICAvLyByZXR1cm4gdGhlIGFkYXB0ZXIgYXMgcHJvdmlkZWRcbiAgcmV0dXJuIGFkYXB0ZXI7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGxvYWRBZGFwdGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Analytics/AnalyticsAdapter.js b/lib/Adapters/Analytics/AnalyticsAdapter.js new file mode 100644 index 0000000000..32559338b1 --- /dev/null +++ b/lib/Adapters/Analytics/AnalyticsAdapter.js @@ -0,0 +1,41 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.AnalyticsAdapter = void 0; + +/*eslint no-unused-vars: "off"*/ + +/** + * @module Adapters + */ + +/** + * @interface AnalyticsAdapter + */ +class AnalyticsAdapter { + /** + @param {any} parameters: the analytics request body, analytics info will be in the dimensions property + @param {Request} req: the original http request + */ + appOpened(parameters, req) { + return Promise.resolve({}); + } + /** + @param {String} eventName: the name of the custom eventName + @param {any} parameters: the analytics request body, analytics info will be in the dimensions property + @param {Request} req: the original http request + */ + + + trackEvent(eventName, parameters, req) { + return Promise.resolve({}); + } + +} + +exports.AnalyticsAdapter = AnalyticsAdapter; +var _default = AnalyticsAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BbmFseXRpY3MvQW5hbHl0aWNzQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJBbmFseXRpY3NBZGFwdGVyIiwiYXBwT3BlbmVkIiwicGFyYW1ldGVycyIsInJlcSIsIlByb21pc2UiLCJyZXNvbHZlIiwidHJhY2tFdmVudCIsImV2ZW50TmFtZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBO0FBQ0E7QUFDQTs7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNQSxnQkFBTixDQUF1QjtBQUM1QjtBQUNGO0FBQ0E7QUFDQTtBQUNFQyxFQUFBQSxTQUFTLENBQUNDLFVBQUQsRUFBYUMsR0FBYixFQUFrQjtBQUN6QixXQUFPQyxPQUFPLENBQUNDLE9BQVIsQ0FBZ0IsRUFBaEIsQ0FBUDtBQUNEO0FBRUQ7QUFDRjtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0VDLEVBQUFBLFVBQVUsQ0FBQ0MsU0FBRCxFQUFZTCxVQUFaLEVBQXdCQyxHQUF4QixFQUE2QjtBQUNyQyxXQUFPQyxPQUFPLENBQUNDLE9BQVIsQ0FBZ0IsRUFBaEIsQ0FBUDtBQUNEOztBQWhCMkI7OztlQW1CZkwsZ0IiLCJzb3VyY2VzQ29udGVudCI6WyIvKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG4vKipcbiAqIEBtb2R1bGUgQWRhcHRlcnNcbiAqL1xuLyoqXG4gKiBAaW50ZXJmYWNlIEFuYWx5dGljc0FkYXB0ZXJcbiAqL1xuZXhwb3J0IGNsYXNzIEFuYWx5dGljc0FkYXB0ZXIge1xuICAvKipcbiAgQHBhcmFtIHthbnl9IHBhcmFtZXRlcnM6IHRoZSBhbmFseXRpY3MgcmVxdWVzdCBib2R5LCBhbmFseXRpY3MgaW5mbyB3aWxsIGJlIGluIHRoZSBkaW1lbnNpb25zIHByb3BlcnR5XG4gIEBwYXJhbSB7UmVxdWVzdH0gcmVxOiB0aGUgb3JpZ2luYWwgaHR0cCByZXF1ZXN0XG4gICAqL1xuICBhcHBPcGVuZWQocGFyYW1ldGVycywgcmVxKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gIH1cblxuICAvKipcbiAgQHBhcmFtIHtTdHJpbmd9IGV2ZW50TmFtZTogdGhlIG5hbWUgb2YgdGhlIGN1c3RvbSBldmVudE5hbWVcbiAgQHBhcmFtIHthbnl9IHBhcmFtZXRlcnM6IHRoZSBhbmFseXRpY3MgcmVxdWVzdCBib2R5LCBhbmFseXRpY3MgaW5mbyB3aWxsIGJlIGluIHRoZSBkaW1lbnNpb25zIHByb3BlcnR5XG4gIEBwYXJhbSB7UmVxdWVzdH0gcmVxOiB0aGUgb3JpZ2luYWwgaHR0cCByZXF1ZXN0XG4gICAqL1xuICB0cmFja0V2ZW50KGV2ZW50TmFtZSwgcGFyYW1ldGVycywgcmVxKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQW5hbHl0aWNzQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/AuthAdapter.js b/lib/Adapters/Auth/AuthAdapter.js new file mode 100644 index 0000000000..5a5c4d8d52 --- /dev/null +++ b/lib/Adapters/Auth/AuthAdapter.js @@ -0,0 +1,34 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.AuthAdapter = void 0; + +/*eslint no-unused-vars: "off"*/ +class AuthAdapter { + /* + @param appIds: the specified app ids in the configuration + @param authData: the client provided authData + @param options: additional options + @returns a promise that resolves if the applicationId is valid + */ + validateAppId(appIds, authData, options) { + return Promise.resolve({}); + } + /* + @param authData: the client provided authData + @param options: additional options + */ + + + validateAuthData(authData, options) { + return Promise.resolve({}); + } + +} + +exports.AuthAdapter = AuthAdapter; +var _default = AuthAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL0F1dGhBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIkF1dGhBZGFwdGVyIiwidmFsaWRhdGVBcHBJZCIsImFwcElkcyIsImF1dGhEYXRhIiwib3B0aW9ucyIsIlByb21pc2UiLCJyZXNvbHZlIiwidmFsaWRhdGVBdXRoRGF0YSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBO0FBQ08sTUFBTUEsV0FBTixDQUFrQjtBQUN2QjtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDRUMsRUFBQUEsYUFBYSxDQUFDQyxNQUFELEVBQVNDLFFBQVQsRUFBbUJDLE9BQW5CLEVBQTRCO0FBQ3ZDLFdBQU9DLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQixFQUFoQixDQUFQO0FBQ0Q7QUFFRDtBQUNGO0FBQ0E7QUFDQTs7O0FBQ0VDLEVBQUFBLGdCQUFnQixDQUFDSixRQUFELEVBQVdDLE9BQVgsRUFBb0I7QUFDbEMsV0FBT0MsT0FBTyxDQUFDQyxPQUFSLENBQWdCLEVBQWhCLENBQVA7QUFDRDs7QUFqQnNCOzs7ZUFvQlZOLFciLCJzb3VyY2VzQ29udGVudCI6WyIvKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG5leHBvcnQgY2xhc3MgQXV0aEFkYXB0ZXIge1xuICAvKlxuICBAcGFyYW0gYXBwSWRzOiB0aGUgc3BlY2lmaWVkIGFwcCBpZHMgaW4gdGhlIGNvbmZpZ3VyYXRpb25cbiAgQHBhcmFtIGF1dGhEYXRhOiB0aGUgY2xpZW50IHByb3ZpZGVkIGF1dGhEYXRhXG4gIEBwYXJhbSBvcHRpb25zOiBhZGRpdGlvbmFsIG9wdGlvbnNcbiAgQHJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgaWYgdGhlIGFwcGxpY2F0aW9uSWQgaXMgdmFsaWRcbiAgICovXG4gIHZhbGlkYXRlQXBwSWQoYXBwSWRzLCBhdXRoRGF0YSwgb3B0aW9ucykge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe30pO1xuICB9XG5cbiAgLypcbiAgQHBhcmFtIGF1dGhEYXRhOiB0aGUgY2xpZW50IHByb3ZpZGVkIGF1dGhEYXRhXG4gIEBwYXJhbSBvcHRpb25zOiBhZGRpdGlvbmFsIG9wdGlvbnNcbiAgICovXG4gIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBBdXRoQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/OAuth1Client.js b/lib/Adapters/Auth/OAuth1Client.js new file mode 100644 index 0000000000..a3350db5d2 --- /dev/null +++ b/lib/Adapters/Auth/OAuth1Client.js @@ -0,0 +1,227 @@ +"use strict"; + +var https = require('https'), + crypto = require('crypto'); + +var Parse = require('parse/node').Parse; + +var OAuth = function (options) { + if (!options) { + throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'No options passed to OAuth'); + } + + this.consumer_key = options.consumer_key; + this.consumer_secret = options.consumer_secret; + this.auth_token = options.auth_token; + this.auth_token_secret = options.auth_token_secret; + this.host = options.host; + this.oauth_params = options.oauth_params || {}; +}; + +OAuth.prototype.send = function (method, path, params, body) { + var request = this.buildRequest(method, path, params, body); // Encode the body properly, the current Parse Implementation don't do it properly + + return new Promise(function (resolve, reject) { + var httpRequest = https.request(request, function (res) { + var data = ''; + res.on('data', function (chunk) { + data += chunk; + }); + res.on('end', function () { + data = JSON.parse(data); + resolve(data); + }); + }).on('error', function () { + reject('Failed to make an OAuth request'); + }); + + if (request.body) { + httpRequest.write(request.body); + } + + httpRequest.end(); + }); +}; + +OAuth.prototype.buildRequest = function (method, path, params, body) { + if (path.indexOf('/') != 0) { + path = '/' + path; + } + + if (params && Object.keys(params).length > 0) { + path += '?' + OAuth.buildParameterString(params); + } + + var request = { + host: this.host, + path: path, + method: method.toUpperCase() + }; + var oauth_params = this.oauth_params || {}; + oauth_params.oauth_consumer_key = this.consumer_key; + + if (this.auth_token) { + oauth_params['oauth_token'] = this.auth_token; + } + + request = OAuth.signRequest(request, oauth_params, this.consumer_secret, this.auth_token_secret); + + if (body && Object.keys(body).length > 0) { + request.body = OAuth.buildParameterString(body); + } + + return request; +}; + +OAuth.prototype.get = function (path, params) { + return this.send('GET', path, params); +}; + +OAuth.prototype.post = function (path, params, body) { + return this.send('POST', path, params, body); +}; +/* + Proper string %escape encoding +*/ + + +OAuth.encode = function (str) { + // discuss at: http://phpjs.org/functions/rawurlencode/ + // original by: Brett Zamir (http://brett-zamir.me) + // input by: travc + // input by: Brett Zamir (http://brett-zamir.me) + // input by: Michael Grier + // input by: Ratheous + // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // bugfixed by: Brett Zamir (http://brett-zamir.me) + // bugfixed by: Joris + // reimplemented by: Brett Zamir (http://brett-zamir.me) + // reimplemented by: Brett Zamir (http://brett-zamir.me) + // note: This reflects PHP 5.3/6.0+ behavior + // note: Please be aware that this function expects to encode into UTF-8 encoded strings, as found on + // note: pages served as UTF-8 + // example 1: rawurlencode('Kevin van Zonneveld!'); + // returns 1: 'Kevin%20van%20Zonneveld%21' + // example 2: rawurlencode('http://kevin.vanzonneveld.net/'); + // returns 2: 'http%3A%2F%2Fkevin.vanzonneveld.net%2F' + // example 3: rawurlencode('http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a'); + // returns 3: 'http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a' + str = (str + '').toString(); // Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current + // PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following. + + return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A'); +}; + +OAuth.signatureMethod = 'HMAC-SHA1'; +OAuth.version = '1.0'; +/* + Generate a nonce +*/ + +OAuth.nonce = function () { + var text = ''; + var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + + for (var i = 0; i < 30; i++) text += possible.charAt(Math.floor(Math.random() * possible.length)); + + return text; +}; + +OAuth.buildParameterString = function (obj) { + // Sort keys and encode values + if (obj) { + var keys = Object.keys(obj).sort(); // Map key=value, join them by & + + return keys.map(function (key) { + return key + '=' + OAuth.encode(obj[key]); + }).join('&'); + } + + return ''; +}; +/* + Build the signature string from the object +*/ + + +OAuth.buildSignatureString = function (method, url, parameters) { + return [method.toUpperCase(), OAuth.encode(url), OAuth.encode(parameters)].join('&'); +}; +/* + Retuns encoded HMAC-SHA1 from key and text +*/ + + +OAuth.signature = function (text, key) { + crypto = require('crypto'); + return OAuth.encode(crypto.createHmac('sha1', key).update(text).digest('base64')); +}; + +OAuth.signRequest = function (request, oauth_parameters, consumer_secret, auth_token_secret) { + oauth_parameters = oauth_parameters || {}; // Set default values + + if (!oauth_parameters.oauth_nonce) { + oauth_parameters.oauth_nonce = OAuth.nonce(); + } + + if (!oauth_parameters.oauth_timestamp) { + oauth_parameters.oauth_timestamp = Math.floor(new Date().getTime() / 1000); + } + + if (!oauth_parameters.oauth_signature_method) { + oauth_parameters.oauth_signature_method = OAuth.signatureMethod; + } + + if (!oauth_parameters.oauth_version) { + oauth_parameters.oauth_version = OAuth.version; + } + + if (!auth_token_secret) { + auth_token_secret = ''; + } // Force GET method if unset + + + if (!request.method) { + request.method = 'GET'; + } // Collect all the parameters in one signatureParameters object + + + var signatureParams = {}; + var parametersToMerge = [request.params, request.body, oauth_parameters]; + + for (var i in parametersToMerge) { + var parameters = parametersToMerge[i]; + + for (var k in parameters) { + signatureParams[k] = parameters[k]; + } + } // Create a string based on the parameters + + + var parameterString = OAuth.buildParameterString(signatureParams); // Build the signature string + + var url = 'https://' + request.host + '' + request.path; + var signatureString = OAuth.buildSignatureString(request.method, url, parameterString); // Hash the signature string + + var signatureKey = [OAuth.encode(consumer_secret), OAuth.encode(auth_token_secret)].join('&'); + var signature = OAuth.signature(signatureString, signatureKey); // Set the signature in the params + + oauth_parameters.oauth_signature = signature; + + if (!request.headers) { + request.headers = {}; + } // Set the authorization header + + + var authHeader = Object.keys(oauth_parameters).sort().map(function (key) { + var value = oauth_parameters[key]; + return key + '="' + value + '"'; + }).join(', '); + request.headers.Authorization = 'OAuth ' + authHeader; // Set the content type header + + request.headers['Content-Type'] = 'application/x-www-form-urlencoded'; + return request; +}; + +module.exports = OAuth; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL09BdXRoMUNsaWVudC5qcyJdLCJuYW1lcyI6WyJodHRwcyIsInJlcXVpcmUiLCJjcnlwdG8iLCJQYXJzZSIsIk9BdXRoIiwib3B0aW9ucyIsIkVycm9yIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiY29uc3VtZXJfa2V5IiwiY29uc3VtZXJfc2VjcmV0IiwiYXV0aF90b2tlbiIsImF1dGhfdG9rZW5fc2VjcmV0IiwiaG9zdCIsIm9hdXRoX3BhcmFtcyIsInByb3RvdHlwZSIsInNlbmQiLCJtZXRob2QiLCJwYXRoIiwicGFyYW1zIiwiYm9keSIsInJlcXVlc3QiLCJidWlsZFJlcXVlc3QiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsImh0dHBSZXF1ZXN0IiwicmVzIiwiZGF0YSIsIm9uIiwiY2h1bmsiLCJKU09OIiwicGFyc2UiLCJ3cml0ZSIsImVuZCIsImluZGV4T2YiLCJPYmplY3QiLCJrZXlzIiwibGVuZ3RoIiwiYnVpbGRQYXJhbWV0ZXJTdHJpbmciLCJ0b1VwcGVyQ2FzZSIsIm9hdXRoX2NvbnN1bWVyX2tleSIsInNpZ25SZXF1ZXN0IiwiZ2V0IiwicG9zdCIsImVuY29kZSIsInN0ciIsInRvU3RyaW5nIiwiZW5jb2RlVVJJQ29tcG9uZW50IiwicmVwbGFjZSIsInNpZ25hdHVyZU1ldGhvZCIsInZlcnNpb24iLCJub25jZSIsInRleHQiLCJwb3NzaWJsZSIsImkiLCJjaGFyQXQiLCJNYXRoIiwiZmxvb3IiLCJyYW5kb20iLCJvYmoiLCJzb3J0IiwibWFwIiwia2V5Iiwiam9pbiIsImJ1aWxkU2lnbmF0dXJlU3RyaW5nIiwidXJsIiwicGFyYW1ldGVycyIsInNpZ25hdHVyZSIsImNyZWF0ZUhtYWMiLCJ1cGRhdGUiLCJkaWdlc3QiLCJvYXV0aF9wYXJhbWV0ZXJzIiwib2F1dGhfbm9uY2UiLCJvYXV0aF90aW1lc3RhbXAiLCJEYXRlIiwiZ2V0VGltZSIsIm9hdXRoX3NpZ25hdHVyZV9tZXRob2QiLCJvYXV0aF92ZXJzaW9uIiwic2lnbmF0dXJlUGFyYW1zIiwicGFyYW1ldGVyc1RvTWVyZ2UiLCJrIiwicGFyYW1ldGVyU3RyaW5nIiwic2lnbmF0dXJlU3RyaW5nIiwic2lnbmF0dXJlS2V5Iiwib2F1dGhfc2lnbmF0dXJlIiwiaGVhZGVycyIsImF1dGhIZWFkZXIiLCJ2YWx1ZSIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLE9BQUQsQ0FBbkI7QUFBQSxJQUNFQyxNQUFNLEdBQUdELE9BQU8sQ0FBQyxRQUFELENBRGxCOztBQUVBLElBQUlFLEtBQUssR0FBR0YsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkUsS0FBbEM7O0FBRUEsSUFBSUMsS0FBSyxHQUFHLFVBQVVDLE9BQVYsRUFBbUI7QUFDN0IsTUFBSSxDQUFDQSxPQUFMLEVBQWM7QUFDWixVQUFNLElBQUlGLEtBQUssQ0FBQ0csS0FBVixDQUFnQkgsS0FBSyxDQUFDRyxLQUFOLENBQVlDLHFCQUE1QixFQUFtRCw0QkFBbkQsQ0FBTjtBQUNEOztBQUNELE9BQUtDLFlBQUwsR0FBb0JILE9BQU8sQ0FBQ0csWUFBNUI7QUFDQSxPQUFLQyxlQUFMLEdBQXVCSixPQUFPLENBQUNJLGVBQS9CO0FBQ0EsT0FBS0MsVUFBTCxHQUFrQkwsT0FBTyxDQUFDSyxVQUExQjtBQUNBLE9BQUtDLGlCQUFMLEdBQXlCTixPQUFPLENBQUNNLGlCQUFqQztBQUNBLE9BQUtDLElBQUwsR0FBWVAsT0FBTyxDQUFDTyxJQUFwQjtBQUNBLE9BQUtDLFlBQUwsR0FBb0JSLE9BQU8sQ0FBQ1EsWUFBUixJQUF3QixFQUE1QztBQUNELENBVkQ7O0FBWUFULEtBQUssQ0FBQ1UsU0FBTixDQUFnQkMsSUFBaEIsR0FBdUIsVUFBVUMsTUFBVixFQUFrQkMsSUFBbEIsRUFBd0JDLE1BQXhCLEVBQWdDQyxJQUFoQyxFQUFzQztBQUMzRCxNQUFJQyxPQUFPLEdBQUcsS0FBS0Ms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LGVBQWpCLEdBQW1DakIsU0FBbkM7O0FBQ0EsTUFBSSxDQUFDL0MsT0FBTyxDQUFDaUUsT0FBYixFQUFzQjtBQUNwQmpFLElBQUFBLE9BQU8sQ0FBQ2lFLE9BQVIsR0FBa0IsRUFBbEI7QUFDRCxHQW5EMEYsQ0FxRDNGOzs7QUFDQSxNQUFJQyxVQUFVLEdBQUduRCxNQUFNLENBQUNDLElBQVAsQ0FBWW1DLGdCQUFaLEVBQ2RYLElBRGMsR0FFZEMsR0FGYyxDQUVWLFVBQVVDLEdBQVYsRUFBZTtBQUNsQixRQUFJeUIsS0FBSyxHQUFHaEIsZ0JBQWdCLENBQUNULEdBQUQsQ0FBNUI7QUFDQSxXQUFPQSxHQUFHLEdBQUcsSUFBTixHQUFheUIsS0FBYixHQUFxQixHQUE1QjtBQUNELEdBTGMsRUFNZHhCLElBTmMsQ0FNVCxJQU5TLENBQWpCO0FBUUEzQyxFQUFBQSxPQUFPLENBQUNpRSxPQUFSLENBQWdCRyxhQUFoQixHQUFnQyxXQUFXRixVQUEzQyxDQTlEMkYsQ0FnRTNGOztBQUNBbEUsRUFBQUEsT0FBTyxDQUFDaUUsT0FBUixDQUFnQixjQUFoQixJQUFrQyxtQ0FBbEM7QUFDQSxTQUFPakUsT0FBUDtBQUNELENBbkVEOztBQXFFQXFFLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQnRGLEtBQWpCIiwic291cmNlc0NvbnRlbnQiOlsidmFyIGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKSxcbiAgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbnZhciBPQXV0aCA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucykge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsICdObyBvcHRpb25zIHBhc3NlZCB0byBPQXV0aCcpO1xuICB9XG4gIHRoaXMuY29uc3VtZXJfa2V5ID0gb3B0aW9ucy5jb25zdW1lcl9rZXk7XG4gIHRoaXMuY29uc3VtZXJfc2VjcmV0ID0gb3B0aW9ucy5jb25zdW1lcl9zZWNyZXQ7XG4gIHRoaXMuYXV0aF90b2tlbiA9IG9wdGlvbnMuYXV0aF90b2tlbjtcbiAgdGhpcy5hdXRoX3Rva2VuX3NlY3JldCA9IG9wdGlvbnMuYXV0aF90b2tlbl9zZWNyZXQ7XG4gIHRoaXMuaG9zdCA9IG9wdGlvbnMuaG9zdDtcbiAgdGhpcy5vYXV0aF9wYXJhbXMgPSBvcHRpb25zLm9hdXRoX3BhcmFtcyB8fCB7fTtcbn07XG5cbk9BdXRoLnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24gKG1ldGhvZCwgcGF0aCwgcGFyYW1zLCBib2R5KSB7XG4gIHZhciByZXF1ZXN0ID0gdGhpcy5idWlsZFJlcXVlc3QobWV0aG9kLCBwYXRoLCBwYXJhbXMsIGJvZHkpO1xuICAvLyBFbmNvZGUgdGhlIGJvZHkgcHJvcGVybHksIHRoZSBjdXJyZW50IFBhcnNlIEltcGxlbWVudGF0aW9uIGRvbid0IGRvIGl0IHByb3Blcmx5XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgdmFyIGh0dHBSZXF1ZXN0ID0gaHR0cHNcbiAgICAgIC5yZXF1ZXN0KHJlcXVlc3QsIGZ1bmN0aW9uIChyZXMpIHtcbiAgICAgICAgdmFyIGRhdGEgPSAnJztcbiAgICAgICAgcmVzLm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgICAgICAgZGF0YSArPSBjaHVuaztcbiAgICAgICAgfSk7XG4gICAgICAgIHJlcy5vbignZW5kJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGRhdGEgPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgICAgICAgIHJlc29sdmUoZGF0YSk7XG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC5vbignZXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJlamVjdCgnRmFpbGVkIHRvIG1ha2UgYW4gT0F1dGggcmVxdWVzdCcpO1xuICAgICAgfSk7XG4gICAgaWYgKHJlcXVlc3QuYm9keSkge1xuICAgICAgaHR0cFJlcXVlc3Qud3JpdGUocmVxdWVzdC5ib2R5KTtcbiAgICB9XG4gICAgaHR0cFJlcXVlc3QuZW5kKCk7XG4gIH0pO1xufTtcblxuT0F1dGgucHJvdG90eXBlLmJ1aWxkUmVxdWVzdCA9IGZ1bmN0aW9uIChtZXRob2QsIHBhdGgsIHBhcmFtcywgYm9keSkge1xuICBpZiAocGF0aC5pbmRleE9mKCcvJykgIT0gMCkge1xuICAgIHBhdGggPSAnLycgKyBwYXRoO1xuICB9XG4gIGlmIChwYXJhbXMgJiYgT2JqZWN0LmtleXMocGFyYW1zKS5sZW5ndGggPiAwKSB7XG4gICAgcGF0aCArPSAnPycgKyBPQXV0aC5idWlsZFBhcmFtZXRlclN0cmluZyhwYXJhbXMpO1xuICB9XG5cbiAgdmFyIHJlcXVlc3QgPSB7XG4gICAgaG9zdDogdGhpcy5ob3N0LFxuICAgIHBhdGg6IHBhdGgsXG4gICAgbWV0aG9kOiBtZXRob2QudG9VcHBlckNhc2UoKSxcbiAgfTtcblxuICB2YXIgb2F1dGhfcGFyYW1zID0gdGhpcy5vYXV0aF9wYXJhbXMgfHwge307XG4gIG9hdXRoX3BhcmFtcy5vYXV0aF9jb25zdW1lcl9rZXkgPSB0aGlzLmNvbnN1bWVyX2tleTtcbiAgaWYgKHRoaXMuYXV0aF90b2tlbikge1xuICAgIG9hdXRoX3BhcmFtc1snb2F1dGhfdG9rZW4nXSA9IHRoaXMuYXV0aF90b2tlbjtcbiAgfVxuXG4gIHJlcXVlc3QgPSBPQXV0aC5zaWduUmVxdWVzdChyZXF1ZXN0LCBvYXV0aF9wYXJhbXMsIHRoaXMuY29uc3VtZXJfc2VjcmV0LCB0aGlzLmF1dGhfdG9rZW5fc2VjcmV0KTtcblxuICBpZiAoYm9keSAmJiBPYmplY3Qua2V5cyhib2R5KS5sZW5ndGggPiAwKSB7XG4gICAgcmVxdWVzdC5ib2R5ID0gT0F1dGguYnVpbGRQYXJhbWV0ZXJTdHJpbmcoYm9keSk7XG4gIH1cbiAgcmV0dXJuIHJlcXVlc3Q7XG59O1xuXG5PQXV0aC5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKHBhdGgsIHBhcmFtcykge1xuICByZXR1cm4gdGhpcy5zZW5kKCdHRVQnLCBwYXRoLCBwYXJhbXMpO1xufTtcblxuT0F1dGgucHJvdG90eXBlLnBvc3QgPSBmdW5jdGlvbiAocGF0aCwgcGFyYW1zLCBib2R5KSB7XG4gIHJldHVybiB0aGlzLnNlbmQoJ1BPU1QnLCBwYXRoLCBwYXJhbXMsIGJvZHkpO1xufTtcblxuLypcblx0UHJvcGVyIHN0cmluZyAlZXNjYXBlIGVuY29kaW5nXG4qL1xuT0F1dGguZW5jb2RlID0gZnVuY3Rpb24gKHN0cikge1xuICAvLyAgICAgICBkaXNjdXNzIGF0OiBodHRwOi8vcGhwanMub3JnL2Z1bmN0aW9ucy9yYXd1cmxlbmNvZGUvXG4gIC8vICAgICAgb3JpZ2luYWwgYnk6IEJyZXR0IFphbWlyIChodHRwOi8vYnJldHQtemFtaXIubWUpXG4gIC8vICAgICAgICAgaW5wdXQgYnk6IHRyYXZjXG4gIC8vICAgICAgICAgaW5wdXQgYnk6IEJyZXR0IFphbWlyIChodHRwOi8vYnJldHQtemFtaXIubWUpXG4gIC8vICAgICAgICAgaW5wdXQgYnk6IE1pY2hhZWwgR3JpZXJcbiAgLy8gICAgICAgICBpbnB1dCBieTogUmF0aGVvdXNcbiAgLy8gICAgICBidWdmaXhlZCBieTogS2V2aW4gdmFuIFpvbm5ldmVsZCAoaHR0cDovL2tldmluLnZhbnpvbm5ldmVsZC5uZXQpXG4gIC8vICAgICAgYnVnZml4ZWQgYnk6IEJyZXR0IFphbWlyIChodHRwOi8vYnJldHQtemFtaXIubWUpXG4gIC8vICAgICAgYnVnZml4ZWQgYnk6IEpvcmlzXG4gIC8vIHJlaW1wbGVtZW50ZWQgYnk6IEJyZXR0IFphbWlyIChodHRwOi8vYnJldHQtemFtaXIubWUpXG4gIC8vIHJlaW1wbGVtZW50ZWQgYnk6IEJyZXR0IFphbWlyIChodHRwOi8vYnJldHQtemFtaXIubWUpXG4gIC8vICAgICAgICAgICAgIG5vdGU6IFRoaXMgcmVmbGVjdHMgUEhQIDUuMy82LjArIGJlaGF2aW9yXG4gIC8vICAgICAgICAgICAgIG5vdGU6IFBsZWFzZSBiZSBhd2FyZSB0aGF0IHRoaXMgZnVuY3Rpb24gZXhwZWN0cyB0byBlbmNvZGUgaW50byBVVEYtOCBlbmNvZGVkIHN0cmluZ3MsIGFzIGZvdW5kIG9uXG4gIC8vICAgICAgICAgICAgIG5vdGU6IHBhZ2VzIHNlcnZlZCBhcyBVVEYtOFxuICAvLyAgICAgICAgZXhhbXBsZSAxOiByYXd1cmxlbmNvZGUoJ0tldmluIHZhbiBab25uZXZlbGQhJyk7XG4gIC8vICAgICAgICByZXR1cm5zIDE6ICdLZXZpbiUyMHZhbiUyMFpvbm5ldmVsZCUyMSdcbiAgLy8gICAgICAgIGV4YW1wbGUgMjogcmF3dXJsZW5jb2RlKCdodHRwOi8va2V2aW4udmFuem9ubmV2ZWxkLm5ldC8nKTtcbiAgLy8gICAgICAgIHJldHVybnMgMjogJ2h0dHAlM0ElMkYlMkZrZXZpbi52YW56b25uZXZlbGQubmV0JTJGJ1xuICAvLyAgICAgICAgZXhhbXBsZSAzOiByYXd1cmxlbmNvZGUoJ2h0dHA6Ly93d3cuZ29vZ2xlLm5sL3NlYXJjaD9xPXBocC5qcyZpZT11dGYtOCZvZT11dGYtOCZhcT10JnJscz1jb20udWJ1bnR1OmVuLVVTOnVub2ZmaWNpYWwmY2xpZW50PWZpcmVmb3gtYScpO1xuICAvLyAgICAgICAgcmV0dXJucyAzOiAnaHR0cCUzQSUyRiUyRnd3dy5nb29nbGUubmwlMkZzZWFyY2glM0ZxJTNEcGhwLmpzJTI2aWUlM0R1dGYtOCUyNm9lJTNEdXRmLTglMjZhcSUzRHQlMjZybHMlM0Rjb20udWJ1bnR1JTNBZW4tVVMlM0F1bm9mZmljaWFsJTI2Y2xpZW50JTNEZmlyZWZveC1hJ1xuXG4gIHN0ciA9IChzdHIgKyAnJykudG9TdHJpbmcoKTtcblxuICAvLyBUaWxkZSBzaG91bGQgYmUgYWxsb3dlZCB1bmVzY2FwZWQgaW4gZnV0dXJlIHZlcnNpb25zIG9mIFBIUCAoYXMgcmVmbGVjdGVkIGJlbG93KSwgYnV0IGlmIHlvdSB3YW50IHRvIHJlZmxlY3QgY3VycmVudFxuICAvLyBQSFAgYmVoYXZpb3IsIHlvdSB3b3VsZCBuZWVkIHRvIGFkZCBcIi5yZXBsYWNlKC9+L2csICclN0UnKTtcIiB0byB0aGUgZm9sbG93aW5nLlxuICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KHN0cilcbiAgICAucmVwbGFjZSgvIS9nLCAnJTIxJylcbiAgICAucmVwbGFjZSgvJy9nLCAnJTI3JylcbiAgICAucmVwbGFjZSgvXFwoL2csICclMjgnKVxuICAgIC5yZXBsYWNlKC9cXCkvZywgJyUyOScpXG4gICAgLnJlcGxhY2UoL1xcKi9nLCAnJTJBJyk7XG59O1xuXG5PQXV0aC5zaWduYXR1cmVNZXRob2QgPSAnSE1BQy1TSEExJztcbk9BdXRoLnZlcnNpb24gPSAnMS4wJztcblxuLypcblx0R2VuZXJhdGUgYSBub25jZVxuKi9cbk9BdXRoLm5vbmNlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdGV4dCA9ICcnO1xuICB2YXIgcG9zc2libGUgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODknO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMzA7IGkrKykgdGV4dCArPSBwb3NzaWJsZS5jaGFyQXQoTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogcG9zc2libGUubGVuZ3RoKSk7XG5cbiAgcmV0dXJuIHRleHQ7XG59O1xuXG5PQXV0aC5idWlsZFBhcmFtZXRlclN0cmluZyA9IGZ1bmN0aW9uIChvYmopIHtcbiAgLy8gU29ydCBrZXlzIGFuZCBlbmNvZGUgdmFsdWVzXG4gIGlmIChvYmopIHtcbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iaikuc29ydCgpO1xuXG4gICAgLy8gTWFwIGtleT12YWx1ZSwgam9pbiB0aGVtIGJ5ICZcbiAgICByZXR1cm4ga2V5c1xuICAgICAgLm1hcChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIHJldHVybiBrZXkgKyAnPScgKyBPQXV0aC5lbmNvZGUob2JqW2tleV0pO1xuICAgICAgfSlcbiAgICAgIC5qb2luKCcmJyk7XG4gIH1cblxuICByZXR1cm4gJyc7XG59O1xuXG4vKlxuXHRCdWlsZCB0aGUgc2lnbmF0dXJlIHN0cmluZyBmcm9tIHRoZSBvYmplY3RcbiovXG5cbk9BdXRoLmJ1aWxkU2lnbmF0dXJlU3RyaW5nID0gZnVuY3Rpb24gKG1ldGhvZCwgdXJsLCBwYXJhbWV0ZXJzKSB7XG4gIHJldHVybiBbbWV0aG9kLnRvVXBwZXJDYXNlKCksIE9BdXRoLmVuY29kZSh1cmwpLCBPQXV0aC5lbmNvZGUocGFyYW1ldGVycyldLmpvaW4oJyYnKTtcbn07XG5cbi8qXG5cdFJldHVucyBlbmNvZGVkIEhNQUMtU0hBMSBmcm9tIGtleSBhbmQgdGV4dFxuKi9cbk9BdXRoLnNpZ25hdHVyZSA9IGZ1bmN0aW9uICh0ZXh0LCBrZXkpIHtcbiAgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG4gIHJldHVybiBPQXV0aC5lbmNvZGUoY3J5cHRvLmNyZWF0ZUhtYWMoJ3NoYTEnLCBrZXkpLnVwZGF0ZSh0ZXh0KS5kaWdlc3QoJ2Jhc2U2NCcpKTtcbn07XG5cbk9BdXRoLnNpZ25SZXF1ZXN0ID0gZnVuY3Rpb24gKHJlcXVlc3QsIG9hdXRoX3BhcmFtZXRlcnMsIGNvbnN1bWVyX3NlY3JldCwgYXV0aF90b2tlbl9zZWNyZXQpIHtcbiAgb2F1dGhfcGFyYW1ldGVycyA9IG9hdXRoX3BhcmFtZXRlcnMgfHwge307XG5cbiAgLy8gU2V0IGRlZmF1bHQgdmFsdWVzXG4gIGlmICghb2F1dGhfcGFyYW1ldGVycy5vYXV0aF9ub25jZSkge1xuICAgIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfbm9uY2UgPSBPQXV0aC5ub25jZSgpO1xuICB9XG4gIGlmICghb2F1dGhfcGFyYW1ldGVycy5vYXV0aF90aW1lc3RhbXApIHtcbiAgICBvYXV0aF9wYXJhbWV0ZXJzLm9hdXRoX3RpbWVzdGFtcCA9IE1hdGguZmxvb3IobmV3IERhdGUoKS5nZXRUaW1lKCkgLyAxMDAwKTtcbiAgfVxuICBpZiAoIW9hdXRoX3BhcmFtZXRlcnMub2F1dGhfc2lnbmF0dXJlX21ldGhvZCkge1xuICAgIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfc2lnbmF0dXJlX21ldGhvZCA9IE9BdXRoLnNpZ25hdHVyZU1ldGhvZDtcbiAgfVxuICBpZiAoIW9hdXRoX3BhcmFtZXRlcnMub2F1dGhfdmVyc2lvbikge1xuICAgIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfdmVyc2lvbiA9IE9BdXRoLnZlcnNpb247XG4gIH1cblxuICBpZiAoIWF1dGhfdG9rZW5fc2VjcmV0KSB7XG4gICAgYXV0aF90b2tlbl9zZWNyZXQgPSAnJztcbiAgfVxuICAvLyBGb3JjZSBHRVQgbWV0aG9kIGlmIHVuc2V0XG4gIGlmICghcmVxdWVzdC5tZXRob2QpIHtcbiAgICByZXF1ZXN0Lm1ldGhvZCA9ICdHRVQnO1xuICB9XG5cbiAgLy8gQ29sbGVjdCAgYWxsIHRoZSBwYXJhbWV0ZXJzIGluIG9uZSBzaWduYXR1cmVQYXJhbWV0ZXJzIG9iamVjdFxuICB2YXIgc2lnbmF0dXJlUGFyYW1zID0ge307XG4gIHZhciBwYXJhbWV0ZXJzVG9NZXJnZSA9IFtyZXF1ZXN0LnBhcmFtcywgcmVxdWVzdC5ib2R5LCBvYXV0aF9wYXJhbWV0ZXJzXTtcbiAgZm9yICh2YXIgaSBpbiBwYXJhbWV0ZXJzVG9NZXJnZSkge1xuICAgIHZhciBwYXJhbWV0ZXJzID0gcGFyYW1ldGVyc1RvTWVyZ2VbaV07XG4gICAgZm9yICh2YXIgayBpbiBwYXJhbWV0ZXJzKSB7XG4gICAgICBzaWduYXR1cmVQYXJhbXNba10gPSBwYXJhbWV0ZXJzW2tdO1xuICAgIH1cbiAgfVxuXG4gIC8vIENyZWF0ZSBhIHN0cmluZyBiYXNlZCBvbiB0aGUgcGFyYW1ldGVyc1xuICB2YXIgcGFyYW1ldGVyU3RyaW5nID0gT0F1dGguYnVpbGRQYXJhbWV0ZXJTdHJpbmcoc2lnbmF0dXJlUGFyYW1zKTtcblxuICAvLyBCdWlsZCB0aGUgc2lnbmF0dXJlIHN0cmluZ1xuICB2YXIgdXJsID0gJ2h0dHBzOi8vJyArIHJlcXVlc3QuaG9zdCArICcnICsgcmVxdWVzdC5wYXRoO1xuXG4gIHZhciBzaWduYXR1cmVTdHJpbmcgPSBPQXV0aC5idWlsZFNpZ25hdHVyZVN0cmluZyhyZXF1ZXN0Lm1ldGhvZCwgdXJsLCBwYXJhbWV0ZXJTdHJpbmcpO1xuICAvLyBIYXNoIHRoZSBzaWduYXR1cmUgc3RyaW5nXG4gIHZhciBzaWduYXR1cmVLZXkgPSBbT0F1dGguZW5jb2RlKGNvbnN1bWVyX3NlY3JldCksIE9BdXRoLmVuY29kZShhdXRoX3Rva2VuX3NlY3JldCldLmpvaW4oJyYnKTtcblxuICB2YXIgc2lnbmF0dXJlID0gT0F1dGguc2lnbmF0dXJlKHNpZ25hdHVyZVN0cmluZywgc2lnbmF0dXJlS2V5KTtcblxuICAvLyBTZXQgdGhlIHNpZ25hdHVyZSBpbiB0aGUgcGFyYW1zXG4gIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfc2lnbmF0dXJlID0gc2lnbmF0dXJlO1xuICBpZiAoIXJlcXVlc3QuaGVhZGVycykge1xuICAgIHJlcXVlc3QuaGVhZGVycyA9IHt9O1xuICB9XG5cbiAgLy8gU2V0IHRoZSBhdXRob3JpemF0aW9uIGhlYWRlclxuICB2YXIgYXV0aEhlYWRlciA9IE9iamVjdC5rZXlzKG9hdXRoX3BhcmFtZXRlcnMpXG4gICAgLnNvcnQoKVxuICAgIC5tYXAoZnVuY3Rpb24gKGtleSkge1xuICAgICAgdmFyIHZhbHVlID0gb2F1dGhfcGFyYW1ldGVyc1trZXldO1xuICAgICAgcmV0dXJuIGtleSArICc9XCInICsgdmFsdWUgKyAnXCInO1xuICAgIH0pXG4gICAgLmpvaW4oJywgJyk7XG5cbiAgcmVxdWVzdC5oZWFkZXJzLkF1dGhvcml6YXRpb24gPSAnT0F1dGggJyArIGF1dGhIZWFkZXI7XG5cbiAgLy8gU2V0IHRoZSBjb250ZW50IHR5cGUgaGVhZGVyXG4gIHJlcXVlc3QuaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJztcbiAgcmV0dXJuIHJlcXVlc3Q7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE9BdXRoO1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/apple.js b/lib/Adapters/Auth/apple.js new file mode 100644 index 0000000000..86ed2e216e --- /dev/null +++ b/lib/Adapters/Auth/apple.js @@ -0,0 +1,105 @@ +"use strict"; + +// Apple SignIn Auth +// https://developer.apple.com/documentation/signinwithapplerestapi +const Parse = require('parse/node').Parse; + +const jwksClient = require('jwks-rsa'); + +const util = require('util'); + +const jwt = require('jsonwebtoken'); + +const TOKEN_ISSUER = 'https://appleid.apple.com'; + +const getAppleKeyByKeyId = async (keyId, cacheMaxEntries, cacheMaxAge) => { + const client = jwksClient({ + jwksUri: `${TOKEN_ISSUER}/auth/keys`, + cache: true, + cacheMaxEntries, + cacheMaxAge + }); + const asyncGetSigningKeyFunction = util.promisify(client.getSigningKey); + let key; + + try { + key = await asyncGetSigningKeyFunction(keyId); + } catch (error) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Unable to find matching key for Key ID: ${keyId}`); + } + + return key; +}; + +const getHeaderFromToken = token => { + const decodedToken = jwt.decode(token, { + complete: true + }); + + if (!decodedToken) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `provided token does not decode as JWT`); + } + + return decodedToken.header; +}; + +const verifyIdToken = async ({ + token, + id +}, { + clientId, + cacheMaxEntries, + cacheMaxAge +}) => { + if (!token) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token is invalid for this user.`); + } + + const { + kid: keyId, + alg: algorithm + } = getHeaderFromToken(token); + const ONE_HOUR_IN_MS = 3600000; + let jwtClaims; + cacheMaxAge = cacheMaxAge || ONE_HOUR_IN_MS; + cacheMaxEntries = cacheMaxEntries || 5; + const appleKey = await getAppleKeyByKeyId(keyId, cacheMaxEntries, cacheMaxAge); + const signingKey = appleKey.publicKey || appleKey.rsaPublicKey; + + try { + jwtClaims = jwt.verify(token, signingKey, { + algorithms: algorithm, + // the audience can be checked against a string, a regular expression or a list of strings and/or regular expressions. + audience: clientId + }); + } catch (exception) { + const message = exception.message; + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `${message}`); + } + + if (jwtClaims.iss !== TOKEN_ISSUER) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token not issued by correct OpenID provider - expected: ${TOKEN_ISSUER} | from: ${jwtClaims.iss}`); + } + + if (jwtClaims.sub !== id) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `auth data is invalid for this user.`); + } + + return jwtClaims; +}; // Returns a promise that fulfills if this id token is valid + + +function validateAuthData(authData, options = {}) { + return verifyIdToken(authData, options); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} + +module.exports = { + validateAppId, + validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2FwcGxlLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsImp3a3NDbGllbnQiLCJ1dGlsIiwiand0IiwiVE9LRU5fSVNTVUVSIiwiZ2V0QXBwbGVLZXlCeUtleUlkIiwia2V5SWQiLCJjYWNoZU1heEVudHJpZXMiLCJjYWNoZU1heEFnZSIsImNsaWVudCIsImp3a3NVcmkiLCJjYWNoZSIsImFzeW5jR2V0U2lnbmluZ0tleUZ1bmN0aW9uIiwicHJvbWlzaWZ5IiwiZ2V0U2lnbmluZ0tleSIsImtleSIsImVycm9yIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiZ2V0SGVhZGVyRnJvbVRva2VuIiwidG9rZW4iLCJkZWNvZGVkVG9rZW4iLCJkZWNvZGUiLCJjb21wbGV0ZSIsImhlYWRlciIsInZlcmlmeUlkVG9rZW4iLCJpZCIsImNsaWVudElkIiwia2lkIiwiYWxnIiwiYWxnb3JpdGhtIiwiT05FX0hPVVJfSU5fTVMiLCJqd3RDbGFpbXMiLCJhcHBsZUtleSIsInNpZ25pbmdLZXkiLCJwdWJsaWNLZXkiLCJyc2FQdWJsaWNLZXkiLCJ2ZXJpZnkiLCJhbGdvcml0aG1zIiwiYXVkaWVuY2UiLCJleGNlcHRpb24iLCJtZXNzYWdlIiwiaXNzIiwic3ViIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUVBLE1BQU1BLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBcEM7O0FBQ0EsTUFBTUUsVUFBVSxHQUFHRCxPQUFPLENBQUMsVUFBRCxDQUExQjs7QUFDQSxNQUFNRSxJQUFJLEdBQUdGLE9BQU8sQ0FBQyxNQUFELENBQXBCOztBQUNBLE1BQU1HLEdBQUcsR0FBR0gsT0FBTyxDQUFDLGNBQUQsQ0FBbkI7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QXpELENBQU47QUFDRDs7QUFFRCxNQUFJVCxTQUFTLENBQUNVLEdBQVYsS0FBa0J0QyxZQUF0QixFQUFvQztBQUNsQyxVQUFNLElBQUlMLEtBQUssQ0FBQ2tCLEtBQVYsQ0FDSmxCLEtBQUssQ0FBQ2tCLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSCw4REFBNkRkLFlBQWEsWUFBVzRCLFNBQVMsQ0FBQ1UsR0FBSSxFQUZoRyxDQUFOO0FBSUQ7O0FBRUQsTUFBSVYsU0FBUyxDQUFDVyxHQUFWLEtBQWtCakIsRUFBdEIsRUFBMEI7QUFDeEIsVUFBTSxJQUFJM0IsS0FBSyxDQUFDa0IsS0FBVixDQUFnQmxCLEtBQUssQ0FBQ2tCLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQStDLHFDQUEvQyxDQUFOO0FBQ0Q7O0FBQ0QsU0FBT2MsU0FBUDtBQUNELENBdENELEMsQ0F3Q0E7OztBQUNBLFNBQVNZLGdCQUFULENBQTBCQyxRQUExQixFQUFvQ0MsT0FBTyxHQUFHLEVBQTlDLEVBQWtEO0FBQ2hELFNBQU9yQixhQUFhLENBQUNvQixRQUFELEVBQVdDLE9BQVgsQ0FBcEI7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNDLGFBQVQsR0FBeUI7QUFDdkIsU0FBT0MsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFREMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZKLEVBQUFBLGFBRGU7QUFFZkgsRUFBQUE7QUFGZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEFwcGxlIFNpZ25JbiBBdXRoXG4vLyBodHRwczovL2RldmVsb3Blci5hcHBsZS5jb20vZG9jdW1lbnRhdGlvbi9zaWduaW53aXRoYXBwbGVyZXN0YXBpXG5cbmNvbnN0IFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuY29uc3Qgandrc0NsaWVudCA9IHJlcXVpcmUoJ2p3a3MtcnNhJyk7XG5jb25zdCB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuY29uc3Qgand0ID0gcmVxdWlyZSgnanNvbndlYnRva2VuJyk7XG5cbmNvbnN0IFRPS0VOX0lTU1VFUiA9ICdodHRwczovL2FwcGxlaWQuYXBwbGUuY29tJztcblxuY29uc3QgZ2V0QXBwbGVLZXlCeUtleUlkID0gYXN5bmMgKGtleUlkLCBjYWNoZU1heEVudHJpZXMsIGNhY2hlTWF4QWdlKSA9PiB7XG4gIGNvbnN0IGNsaWVudCA9IGp3a3NDbGllbnQoe1xuICAgIGp3a3NVcmk6IGAke1RPS0VOX0lTU1VFUn0vYXV0aC9rZXlzYCxcbiAgICBjYWNoZTogdHJ1ZSxcbiAgICBjYWNoZU1heEVudHJpZXMsXG4gICAgY2FjaGVNYXhBZ2UsXG4gIH0pO1xuXG4gIGNvbnN0IGFzeW5jR2V0U2lnbmluZ0tleUZ1bmN0aW9uID0gdXRpbC5wcm9taXNpZnkoY2xpZW50LmdldFNpZ25pbmdLZXkpO1xuXG4gIGxldCBrZXk7XG4gIHRyeSB7XG4gICAga2V5ID0gYXdhaXQgYXN5bmNHZXRTaWduaW5nS2V5RnVuY3Rpb24oa2V5SWQpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICBgVW5hYmxlIHRvIGZpbmQgbWF0Y2hpbmcga2V5IGZvciBLZXkgSUQ6ICR7a2V5SWR9YFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIGtleTtcbn07XG5cbmNvbnN0IGdldEhlYWRlckZyb21Ub2tlbiA9IHRva2VuID0+IHtcbiAgY29uc3QgZGVjb2RlZFRva2VuID0gand0LmRlY29kZSh0b2tlbiwgeyBjb21wbGV0ZTogdHJ1ZSB9KTtcbiAgaWYgKCFkZWNvZGVkVG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgYHByb3ZpZGVkIHRva2VuIGRvZXMgbm90IGRlY29kZSBhcyBKV1RgKTtcbiAgfVxuXG4gIHJldHVybiBkZWNvZGVkVG9rZW4uaGVhZGVyO1xufTtcblxuY29uc3QgdmVyaWZ5SWRUb2tlbiA9IGFzeW5jICh7IHRva2VuLCBpZCB9LCB7IGNsaWVudElkLCBjYWNoZU1heEVudHJpZXMsIGNhY2hlTWF4QWdlIH0pID0+IHtcbiAgaWYgKCF0b2tlbikge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBgaWQgdG9rZW4gaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLmApO1xuICB9XG5cbiAgY29uc3QgeyBraWQ6IGtleUlkLCBhbGc6IGFsZ29yaXRobSB9ID0gZ2V0SGVhZGVyRnJvbVRva2VuKHRva2VuKTtcbiAgY29uc3QgT05FX0hPVVJfSU5fTVMgPSAzNjAwMDAwO1xuICBsZXQgand0Q2xhaW1zO1xuXG4gIGNhY2hlTWF4QWdlID0gY2FjaGVNYXhBZ2UgfHwgT05FX0hPVVJfSU5fTVM7XG4gIGNhY2hlTWF4RW50cmllcyA9IGNhY2hlTWF4RW50cmllcyB8fCA1O1xuXG4gIGNvbnN0IGFwcGxlS2V5ID0gYXdhaXQgZ2V0QXBwbGVLZXlCeUtleUlkKGtleUlkLCBjYWNoZU1heEVudHJpZXMsIGNhY2hlTWF4QWdlKTtcbiAgY29uc3Qgc2lnbmluZ0tleSA9IGFwcGxlS2V5LnB1YmxpY0tleSB8fCBhcHBsZUtleS5yc2FQdWJsaWNLZXk7XG5cbiAgdHJ5IHtcbiAgICBqd3RDbGFpbXMgPSBqd3QudmVyaWZ5KHRva2VuLCBzaWduaW5nS2V5LCB7XG4gICAgICBhbGdvcml0aG1zOiBhbGdvcml0aG0sXG4gICAgICAvLyB0aGUgYXVkaWVuY2UgY2FuIGJlIGNoZWNrZWQgYWdhaW5zdCBhIHN0cmluZywgYSByZWd1bGFyIGV4cHJlc3Npb24gb3IgYSBsaXN0IG9mIHN0cmluZ3MgYW5kL29yIHJlZ3VsYXIgZXhwcmVzc2lvbnMuXG4gICAgICBhdWRpZW5jZTogY2xpZW50SWQsXG4gICAgfSk7XG4gIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBleGNlcHRpb24ubWVzc2FnZTtcblxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBgJHttZXNzYWdlfWApO1xuICB9XG5cbiAgaWYgKGp3dENsYWltcy5pc3MgIT09IFRPS0VOX0lTU1VFUikge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICBgaWQgdG9rZW4gbm90IGlzc3VlZCBieSBjb3JyZWN0IE9wZW5JRCBwcm92aWRlciAtIGV4cGVjdGVkOiAke1RPS0VOX0lTU1VFUn0gfCBmcm9tOiAke2p3dENsYWltcy5pc3N9YFxuICAgICk7XG4gIH1cblxuICBpZiAoand0Q2xhaW1zLnN1YiAhPT0gaWQpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgYGF1dGggZGF0YSBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuYCk7XG4gIH1cbiAgcmV0dXJuIGp3dENsYWltcztcbn07XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyBpZCB0b2tlbiBpcyB2YWxpZFxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSwgb3B0aW9ucyA9IHt9KSB7XG4gIHJldHVybiB2ZXJpZnlJZFRva2VuKGF1dGhEYXRhLCBvcHRpb25zKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/facebook.js b/lib/Adapters/Auth/facebook.js new file mode 100644 index 0000000000..63ba4005ad --- /dev/null +++ b/lib/Adapters/Auth/facebook.js @@ -0,0 +1,62 @@ +"use strict"; + +// Helper functions for accessing the Facebook Graph API. +const httpsRequest = require('./httpsRequest'); + +var Parse = require('parse/node').Parse; + +const crypto = require('crypto'); + +function getAppSecretPath(authData, options = {}) { + const appSecret = options.appSecret; + + if (!appSecret) { + return ''; + } + + const appsecret_proof = crypto.createHmac('sha256', appSecret).update(authData.access_token).digest('hex'); + return `&appsecret_proof=${appsecret_proof}`; +} // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData, options) { + return graphRequest('me?fields=id&access_token=' + authData.access_token + getAppSecretPath(authData, options)).then(data => { + if (data && data.id == authData.id || process.env.TESTING && authData.id === 'test') { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is invalid for this user.'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId(appIds, authData, options) { + var access_token = authData.access_token; + + if (process.env.TESTING && access_token === 'test') { + return Promise.resolve(); + } + + if (!appIds.length) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is not configured.'); + } + + return graphRequest('app?access_token=' + access_token + getAppSecretPath(authData, options)).then(data => { + if (data && appIds.indexOf(data.id) != -1) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is invalid for this user.'); + }); +} // A promisey wrapper for FB graph requests. + + +function graphRequest(path) { + return httpsRequest.get('https://graph.facebook.com/' + path); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2ZhY2Vib29rLmpzIl0sIm5hbWVzIjpbImh0dHBzUmVxdWVzdCIsInJlcXVpcmUiLCJQYXJzZSIsImNyeXB0byIsImdldEFwcFNlY3JldFBhdGgiLCJhdXRoRGF0YSIsIm9wdGlvbnMiLCJhcHBTZWNyZXQiLCJhcHBzZWNyZXRfcHJvb2YiLCJjcmVhdGVIbWFjIiwidXBkYXRlIiwiYWNjZXNzX3Rva2VuIiwiZGlnZXN0IiwidmFsaWRhdGVBdXRoRGF0YSIsImdyYXBoUmVxdWVzdCIsInRoZW4iLCJkYXRhIiwiaWQiLCJwcm9jZXNzIiwiZW52IiwiVEVTVElORyIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJhcHBJZHMiLCJQcm9taXNlIiwicmVzb2x2ZSIsImxlbmd0aCIsImluZGV4T2YiLCJwYXRoIiwiZ2V0IiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBLE1BQU1BLFlBQVksR0FBR0MsT0FBTyxDQUFDLGdCQUFELENBQTVCOztBQUNBLElBQUlDLEtBQUssR0FBR0QsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkMsS0FBbEM7O0FBQ0EsTUFBTUMsTUFBTSxHQUFHRixPQUFPLENBQUMsUUFBRCxDQUF0Qjs7QUFFQSxTQUFTRyxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0NDLE9BQU8sR0FBRyxFQUE5QyxFQUFrRDtBQUNoRCxRQUFNQyxTQUFTLEdBQUdELE9BQU8sQ0FBQ0MsU0FBMUI7O0FBQ0EsTUFBSSxDQUFDQSxTQUFMLEVBQWdCO0FBQ2QsV0FBTyxFQUFQO0FBQ0Q7O0FBQ0QsUUFBTUMsZUFBZSxHQUFHTCxNQUFNLENBQzNCTSxVQURxQixDQUNWLFFBRFUsRUFDQUYsU0FEQSxFQUVyQkcsTUFGcUIsQ0FFZEwsUUFBUSxDQUFDTSxZQUZLLEVBR3JCQyxNQUhxQixDQUdkLEtBSGMsQ0FBeEI7QUFLQSxTQUFRLG9CQUFtQkosZUFBZ0IsRUFBM0M7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNLLGdCQUFULENBQTBCUixRQUExQixFQUFvQ0MsT0FBcEMsRUFBNkM7QUFDM0MsU0FBT1EsWUFBWSxDQUNqQiwrQkFBK0JULFFBQVEsQ0FBQ00sWUFBeEMsR0FBdURQLGdCQUFnQixDQUFDQyxRQUFELEVBQVdDLE9BQVgsQ0FEdEQsQ0FBWixDQUVMUyxJQUZLLENBRUFDLElBQUksSUFBSTtBQUNiLFFBQUtBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxFQUFMLElBQVdaLFFBQVEsQ0FBQ1ksRUFBN0IsSUFBcUNDLE9BQU8sQ0FBQ0MsR0FBUixDQUFZQyxPQUFaLElBQXVCZixRQUFRLENBQUNZLEVBQVQsS0FBZ0IsTUFBaEYsRUFBeUY7QUFDdkY7QUFDRDs7QUFDRCxVQUFNLElBQUlmLEtBQUssQ0FBQ21CLEtBQVYsQ0FBZ0JuQixLQUFLLENBQUNtQixLQUFOLENBQVlDLGdCQUE1QixFQUE4Qyx5Q0FBOUMsQ0FBTjtBQUNELEdBUE0sQ0FBUDtBQVFELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxDQUF1QkMsTUFBdkIsRUFBK0JuQixRQUEvQixFQUF5Q0MsT0FBekMsRUFBa0Q7QUFDaEQsTUFBSUssWUFBWSxHQUFHTixRQUFRLENBQUNNLFlBQTVCOztBQUNBLE1BQUlPLE9BQU8sQ0FBQ0MsR0FBUixDQUFZQyxPQUFaLElBQXVCVCxZQUFZLEtBQUssTUFBNUMsRUFBb0Q7QUFDbEQsV0FBT2MsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFDRCxNQUFJLENBQUNGLE1BQU0sQ0FBQ0csTUFBWixFQUFvQjtBQUNsQixVQUFNLElBQUl6QixLQUFLLENBQUNtQixLQUFWLENBQWdCbkIsS0FBSyxDQUFDbUIsS0FBTixDQUFZQyxnQkFBNUIsRUFBOEMsa0NBQTlDLENBQU47QUFDRDs7QUFDRCxTQUFPUixZQUFZLENBQ2pCLHNCQUFzQkgsWUFBdEIsR0FBcUNQLGdCQUFnQixDQUFDQyxRQUFELEVBQVdDLE9BQVgsQ0FEcEMsQ0FBWixDQUVMUyxJQUZLLENBRUFDLElBQUksSUFBSTtBQUNiLFFBQUlBLElBQUksSUFBSVEsTUFBTSxDQUFDSSxPQUFQLENBQWVaLElBQUksQ0FBQ0MsRUFBcEIsS0FBMkIsQ0FBQyxDQUF4QyxFQUEyQztBQUN6QztBQUNEOztBQUNELFVBQU0sSUFBSWYsS0FBSyxDQUFDbUIsS0FBVixDQUFnQm5CLEtBQUssQ0FBQ21CLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLHlDQUE5QyxDQUFOO0FBQ0QsR0FQTSxDQUFQO0FBUUQsQyxDQUVEOzs7QUFDQSxTQUFTUixZQUFULENBQXNCZSxJQUF0QixFQUE0QjtBQUMxQixTQUFPN0IsWUFBWSxDQUFDOEIsR0FBYixDQUFpQixnQ0FBZ0NELElBQWpELENBQVA7QUFDRDs7QUFFREUsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZULEVBQUFBLGFBQWEsRUFBRUEsYUFEQTtBQUVmVixFQUFBQSxnQkFBZ0IsRUFBRUE7QUFGSCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgRmFjZWJvb2sgR3JhcGggQVBJLlxuY29uc3QgaHR0cHNSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwc1JlcXVlc3QnKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xuXG5mdW5jdGlvbiBnZXRBcHBTZWNyZXRQYXRoKGF1dGhEYXRhLCBvcHRpb25zID0ge30pIHtcbiAgY29uc3QgYXBwU2VjcmV0ID0gb3B0aW9ucy5hcHBTZWNyZXQ7XG4gIGlmICghYXBwU2VjcmV0KSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG4gIGNvbnN0IGFwcHNlY3JldF9wcm9vZiA9IGNyeXB0b1xuICAgIC5jcmVhdGVIbWFjKCdzaGEyNTYnLCBhcHBTZWNyZXQpXG4gICAgLnVwZGF0ZShhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pXG4gICAgLmRpZ2VzdCgnaGV4Jyk7XG5cbiAgcmV0dXJuIGAmYXBwc2VjcmV0X3Byb29mPSR7YXBwc2VjcmV0X3Byb29mfWA7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIGdyYXBoUmVxdWVzdChcbiAgICAnbWU/ZmllbGRzPWlkJmFjY2Vzc190b2tlbj0nICsgYXV0aERhdGEuYWNjZXNzX3Rva2VuICsgZ2V0QXBwU2VjcmV0UGF0aChhdXRoRGF0YSwgb3B0aW9ucylcbiAgKS50aGVuKGRhdGEgPT4ge1xuICAgIGlmICgoZGF0YSAmJiBkYXRhLmlkID09IGF1dGhEYXRhLmlkKSB8fCAocHJvY2Vzcy5lbnYuVEVTVElORyAmJiBhdXRoRGF0YS5pZCA9PT0gJ3Rlc3QnKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0ZhY2Vib29rIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLicpO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKGFwcElkcywgYXV0aERhdGEsIG9wdGlvbnMpIHtcbiAgdmFyIGFjY2Vzc190b2tlbiA9IGF1dGhEYXRhLmFjY2Vzc190b2tlbjtcbiAgaWYgKHByb2Nlc3MuZW52LlRFU1RJTkcgJiYgYWNjZXNzX3Rva2VuID09PSAndGVzdCcpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbiAgaWYgKCFhcHBJZHMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdGYWNlYm9vayBhdXRoIGlzIG5vdCBjb25maWd1cmVkLicpO1xuICB9XG4gIHJldHVybiBncmFwaFJlcXVlc3QoXG4gICAgJ2FwcD9hY2Nlc3NfdG9rZW49JyArIGFjY2Vzc190b2tlbiArIGdldEFwcFNlY3JldFBhdGgoYXV0aERhdGEsIG9wdGlvbnMpXG4gICkudGhlbihkYXRhID0+IHtcbiAgICBpZiAoZGF0YSAmJiBhcHBJZHMuaW5kZXhPZihkYXRhLmlkKSAhPSAtMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0ZhY2Vib29rIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLicpO1xuICB9KTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBGQiBncmFwaCByZXF1ZXN0cy5cbmZ1bmN0aW9uIGdyYXBoUmVxdWVzdChwYXRoKSB7XG4gIHJldHVybiBodHRwc1JlcXVlc3QuZ2V0KCdodHRwczovL2dyYXBoLmZhY2Vib29rLmNvbS8nICsgcGF0aCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/gcenter.js b/lib/Adapters/Auth/gcenter.js new file mode 100644 index 0000000000..bc44150cef --- /dev/null +++ b/lib/Adapters/Auth/gcenter.js @@ -0,0 +1,126 @@ +"use strict"; + +/* Apple Game Center Auth +https://developer.apple.com/documentation/gamekit/gklocalplayer/1515407-generateidentityverificationsign#discussion + +const authData = { + publicKeyUrl: 'https://valid.apple.com/public/timeout.cer', + timestamp: 1460981421303, + signature: 'PoDwf39DCN464B49jJCU0d9Y0J', + salt: 'saltST==', + bundleId: 'com.valid.app' + id: 'playerId', +}; +*/ +const { + Parse +} = require('parse/node'); + +const crypto = require('crypto'); + +const https = require('https'); + +const url = require('url'); + +const cache = {}; // (publicKey -> cert) cache + +function verifyPublicKeyUrl(publicKeyUrl) { + const parsedUrl = url.parse(publicKeyUrl); + + if (parsedUrl.protocol !== 'https:') { + return false; + } + + const hostnameParts = parsedUrl.hostname.split('.'); + const length = hostnameParts.length; + const domainParts = hostnameParts.slice(length - 2, length); + const domain = domainParts.join('.'); + return domain === 'apple.com'; +} + +function convertX509CertToPEM(X509Cert) { + const pemPreFix = '-----BEGIN CERTIFICATE-----\n'; + const pemPostFix = '-----END CERTIFICATE-----'; + const base64 = X509Cert; + const certBody = base64.match(new RegExp('.{0,64}', 'g')).join('\n'); + return pemPreFix + certBody + pemPostFix; +} + +function getAppleCertificate(publicKeyUrl) { + if (!verifyPublicKeyUrl(publicKeyUrl)) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Apple Game Center - invalid publicKeyUrl: ${publicKeyUrl}`); + } + + if (cache[publicKeyUrl]) { + return cache[publicKeyUrl]; + } + + return new Promise((resolve, reject) => { + https.get(publicKeyUrl, res => { + let data = ''; + res.on('data', chunk => { + data += chunk.toString('base64'); + }); + res.on('end', () => { + const cert = convertX509CertToPEM(data); + + if (res.headers['cache-control']) { + var expire = res.headers['cache-control'].match(/max-age=([0-9]+)/); + + if (expire) { + cache[publicKeyUrl] = cert; // we'll expire the cache entry later, as per max-age + + setTimeout(() => { + delete cache[publicKeyUrl]; + }, parseInt(expire[1], 10) * 1000); + } + } + + resolve(cert); + }); + }).on('error', reject); + }); +} + +function convertTimestampToBigEndian(timestamp) { + const buffer = Buffer.alloc(8); + const high = ~~(timestamp / 0xffffffff); + const low = timestamp % (0xffffffff + 0x1); + buffer.writeUInt32BE(parseInt(high, 10), 0); + buffer.writeUInt32BE(parseInt(low, 10), 4); + return buffer; +} + +function verifySignature(publicKey, authData) { + const verifier = crypto.createVerify('sha256'); + verifier.update(authData.playerId, 'utf8'); + verifier.update(authData.bundleId, 'utf8'); + verifier.update(convertTimestampToBigEndian(authData.timestamp)); + verifier.update(authData.salt, 'base64'); + + if (!verifier.verify(publicKey, authData.signature, 'base64')) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Apple Game Center - invalid signature'); + } +} // Returns a promise that fulfills if this user id is valid. + + +async function validateAuthData(authData) { + if (!authData.id) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Apple Game Center - authData id missing'); + } + + authData.playerId = authData.id; + const publicKey = await getAppleCertificate(authData.publicKeyUrl); + return verifySignature(publicKey, authData); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} + +module.exports = { + validateAppId, + validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2djZW50ZXIuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwiY3J5cHRvIiwiaHR0cHMiLCJ1cmwiLCJjYWNoZSIsInZlcmlmeVB1YmxpY0tleVVybCIsInB1YmxpY0tleVVybCIsInBhcnNlZFVybCIsInBhcnNlIiwicHJvdG9jb2wiLCJob3N0bmFtZVBhcnRzIiwiaG9zdG5hbWUiLCJzcGxpdCIsImxlbmd0aCIsImRvbWFpblBhcnRzIiwic2xpY2UiLCJkb21haW4iLCJqb2luIiwiY29udmVydFg1MDlDZXJ0VG9QRU0iLCJYNTA5Q2VydCIsInBlbVByZUZpeCIsInBlbVBvc3RGaXgiLCJiYXNlNjQiLCJjZXJ0Qm9keSIsIm1hdGNoIiwiUmVnRXhwIiwiZ2V0QXBwbGVDZXJ0aWZpY2F0ZSIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiZ2V0IiwicmVzIiwiZGF0YSIsIm9uIiwiY2h1bmsiLCJ0b1N0cmluZyIsImNlcnQiLCJoZWFkZXJzIiwiZXhwaXJlIiwic2V0VGltZW91dCIsInBhcnNlSW50IiwiY29udmVydFRpbWVzdGFtcFRvQmlnRW5kaWFuIiwidGltZXN0YW1wIiwiYnVmZmVyIiwiQnVmZmVyIiwiYWxsb2MiLCJoaWdoIiwibG93Iiwid3JpdGVVSW50MzJCRSIsInZlcmlmeVNpZ25hdHVyZSIsInB1YmxpY0tleSIsImF1dGhEYXRhIiwidmVyaWZpZXIiLCJjcmVhdGVWZXJpZnkiLCJ1cGRhdGUiLCJwbGF5ZXJJZCIsImJ1bmRsZUlkIiwic2FsdCIsInZlcmlmeSIsInNpZ25hdHVyZSIsInZhbGlkYXRlQXV0aERhdGEiLCJpZCIsInZhbGlkYXRlQXBwSWQiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVB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Q1QsU0FBVixDQUEzQztBQUNBVSxFQUFBQSxRQUFRLENBQUNFLE1BQVQsQ0FBZ0JILFFBQVEsQ0FBQ00sSUFBekIsRUFBK0IsUUFBL0I7O0FBRUEsTUFBSSxDQUFDTCxRQUFRLENBQUNNLE1BQVQsQ0FBZ0JSLFNBQWhCLEVBQTJCQyxRQUFRLENBQUNRLFNBQXBDLEVBQStDLFFBQS9DLENBQUwsRUFBK0Q7QUFDN0QsVUFBTSxJQUFJOUQsS0FBSyxDQUFDNEIsS0FBVixDQUFnQjVCLEtBQUssQ0FBQzRCLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLHVDQUE5QyxDQUFOO0FBQ0Q7QUFDRixDLENBRUQ7OztBQUNBLGVBQWVrQyxnQkFBZixDQUFnQ1QsUUFBaEMsRUFBMEM7QUFDeEMsTUFBSSxDQUFDQSxRQUFRLENBQUNVLEVBQWQsRUFBa0I7QUFDaEIsVUFBTSxJQUFJaEUsS0FBSyxDQUFDNEIsS0FBVixDQUFnQjVCLEtBQUssQ0FBQzRCLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLHlDQUE5QyxDQUFOO0FBQ0Q7O0FBQ0R5QixFQUFBQSxRQUFRLENBQUNJLFFBQVQsR0FBb0JKLFFBQVEsQ0FBQ1UsRUFBN0I7QUFDQSxRQUFNWCxTQUFTLEdBQUcsTUFBTTFCLG1CQUFtQixDQUFDMkIsUUFBUSxDQUFDL0MsWUFBVixDQUEzQztBQUNBLFNBQU82QyxlQUFlLENBQUNDLFNBQUQsRUFBWUMsUUFBWixDQUF0QjtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU1csYUFBVCxHQUF5QjtBQUN2QixTQUFPbkMsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFRG1DLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmRixFQUFBQSxhQURlO0FBRWZGLEVBQUFBO0FBRmUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBBcHBsZSBHYW1lIENlbnRlciBBdXRoXG5odHRwczovL2RldmVsb3Blci5hcHBsZS5jb20vZG9jdW1lbnRhdGlvbi9nYW1la2l0L2drbG9jYWxwbGF5ZXIvMTUxNTQwNy1nZW5lcmF0ZWlkZW50aXR5dmVyaWZpY2F0aW9uc2lnbiNkaXNjdXNzaW9uXG5cbmNvbnN0IGF1dGhEYXRhID0ge1xuICBwdWJsaWNLZXlVcmw6ICdodHRwczovL3ZhbGlkLmFwcGxlLmNvbS9wdWJsaWMvdGltZW91dC5jZXInLFxuICB0aW1lc3RhbXA6IDE0NjA5ODE0MjEzMDMsXG4gIHNpZ25hdHVyZTogJ1BvRHdmMzlEQ040NjRCNDlqSkNVMGQ5WTBKJyxcbiAgc2FsdDogJ3NhbHRTVD09JyxcbiAgYnVuZGxlSWQ6ICdjb20udmFsaWQuYXBwJ1xuICBpZDogJ3BsYXllcklkJyxcbn07XG4qL1xuXG5jb25zdCB7IFBhcnNlIH0gPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5jb25zdCBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcbmNvbnN0IGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKTtcbmNvbnN0IHVybCA9IHJlcXVpcmUoJ3VybCcpO1xuXG5jb25zdCBjYWNoZSA9IHt9OyAvLyAocHVibGljS2V5IC0+IGNlcnQpIGNhY2hlXG5cbmZ1bmN0aW9uIHZlcmlmeVB1YmxpY0tleVVybChwdWJsaWNLZXlVcmwpIHtcbiAgY29uc3QgcGFyc2VkVXJsID0gdXJsLnBhcnNlKHB1YmxpY0tleVVybCk7XG4gIGlmIChwYXJzZWRVcmwucHJvdG9jb2wgIT09ICdodHRwczonKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGNvbnN0IGhvc3RuYW1lUGFydHMgPSBwYXJzZWRVcmwuaG9zdG5hbWUuc3BsaXQoJy4nKTtcbiAgY29uc3QgbGVuZ3RoID0gaG9zdG5hbWVQYXJ0cy5sZW5ndGg7XG4gIGNvbnN0IGRvbWFpblBhcnRzID0gaG9zdG5hbWVQYXJ0cy5zbGljZShsZW5ndGggLSAyLCBsZW5ndGgpO1xuICBjb25zdCBkb21haW4gPSBkb21haW5QYXJ0cy5qb2luKCcuJyk7XG4gIHJldHVybiBkb21haW4gPT09ICdhcHBsZS5jb20nO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0WDUwOUNlcnRUb1BFTShYNTA5Q2VydCkge1xuICBjb25zdCBwZW1QcmVGaXggPSAnLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXFxuJztcbiAgY29uc3QgcGVtUG9zdEZpeCA9ICctLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tJztcblxuICBjb25zdCBiYXNlNjQgPSBYNTA5Q2VydDtcbiAgY29uc3QgY2VydEJvZHkgPSBiYXNlNjQubWF0Y2gobmV3IFJlZ0V4cCgnLnswLDY0fScsICdnJykpLmpvaW4oJ1xcbicpO1xuXG4gIHJldHVybiBwZW1QcmVGaXggKyBjZXJ0Qm9keSArIHBlbVBvc3RGaXg7XG59XG5cbmZ1bmN0aW9uIGdldEFwcGxlQ2VydGlmaWNhdGUocHVibGljS2V5VXJsKSB7XG4gIGlmICghdmVyaWZ5UHVibGljS2V5VXJsKHB1YmxpY0tleVVybCkpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgYEFwcGxlIEdhbWUgQ2VudGVyIC0gaW52YWxpZCBwdWJsaWNLZXlVcmw6ICR7cHVibGljS2V5VXJsfWBcbiAgICApO1xuICB9XG4gIGlmIChjYWNoZVtwdWJsaWNLZXlVcmxdKSB7XG4gICAgcmV0dXJuIGNhY2hlW3B1YmxpY0tleVVybF07XG4gIH1cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBodHRwc1xuICAgICAgLmdldChwdWJsaWNLZXlVcmwsIHJlcyA9PiB7XG4gICAgICAgIGxldCBkYXRhID0gJyc7XG4gICAgICAgIHJlcy5vbignZGF0YScsIGNodW5rID0+IHtcbiAgICAgICAgICBkYXRhICs9IGNodW5rLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJlcy5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNlcnQgPSBjb252ZXJ0WDUwOUNlcnRUb1BFTShkYXRhKTtcbiAgICAgICAgICBpZiAocmVzLmhlYWRlcnNbJ2NhY2hlLWNvbnRyb2wnXSkge1xuICAgICAgICAgICAgdmFyIGV4cGlyZSA9IHJlcy5oZWFkZXJzWydjYWNoZS1jb250cm9sJ10ubWF0Y2goL21heC1hZ2U9KFswLTldKykvKTtcbiAgICAgICAgICAgIGlmIChleHBpcmUpIHtcbiAgICAgICAgICAgICAgY2FjaGVbcHVibGljS2V5VXJsXSA9IGNlcnQ7XG4gICAgICAgICAgICAgIC8vIHdlJ2xsIGV4cGlyZSB0aGUgY2FjaGUgZW50cnkgbGF0ZXIsIGFzIHBlciBtYXgtYWdlXG4gICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBjYWNoZVtwdWJsaWNLZXlVcmxdO1xuICAgICAgICAgICAgICB9LCBwYXJzZUludChleHBpcmVbMV0sIDEwKSAqIDEwMDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXNvbHZlKGNlcnQpO1xuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRUaW1lc3RhbXBUb0JpZ0VuZGlhbih0aW1lc3RhbXApIHtcbiAgY29uc3QgYnVmZmVyID0gQnVmZmVyLmFsbG9jKDgpO1xuXG4gIGNvbnN0IGhpZ2ggPSB+fih0aW1lc3RhbXAgLyAweGZmZmZmZmZmKTtcbiAgY29uc3QgbG93ID0gdGltZXN0YW1wICUgKDB4ZmZmZmZmZmYgKyAweDEpO1xuXG4gIGJ1ZmZlci53cml0ZVVJbnQzMkJFKHBhcnNlSW50KGhpZ2gsIDEwKSwgMCk7XG4gIGJ1ZmZlci53cml0ZVVJbnQzMkJFKHBhcnNlSW50KGxvdywgMTApLCA0KTtcblxuICByZXR1cm4gYnVmZmVyO1xufVxuXG5mdW5jdGlvbiB2ZXJpZnlTaWduYXR1cmUocHVibGljS2V5LCBhdXRoRGF0YSkge1xuICBjb25zdCB2ZXJpZmllciA9IGNyeXB0by5jcmVhdGVWZXJpZnkoJ3NoYTI1NicpO1xuICB2ZXJpZmllci51cGRhdGUoYXV0aERhdGEucGxheWVySWQsICd1dGY4Jyk7XG4gIHZlcmlmaWVyLnVwZGF0ZShhdXRoRGF0YS5idW5kbGVJZCwgJ3V0ZjgnKTtcbiAgdmVyaWZpZXIudXBkYXRlKGNvbnZlcnRUaW1lc3RhbXBUb0JpZ0VuZGlhbihhdXRoRGF0YS50aW1lc3RhbXApKTtcbiAgdmVyaWZpZXIudXBkYXRlKGF1dGhEYXRhLnNhbHQsICdiYXNlNjQnKTtcblxuICBpZiAoIXZlcmlmaWVyLnZlcmlmeShwdWJsaWNLZXksIGF1dGhEYXRhLnNpZ25hdHVyZSwgJ2Jhc2U2NCcpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdBcHBsZSBHYW1lIENlbnRlciAtIGludmFsaWQgc2lnbmF0dXJlJyk7XG4gIH1cbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5hc3luYyBmdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG4gIGlmICghYXV0aERhdGEuaWQpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0FwcGxlIEdhbWUgQ2VudGVyIC0gYXV0aERhdGEgaWQgbWlzc2luZycpO1xuICB9XG4gIGF1dGhEYXRhLnBsYXllcklkID0gYXV0aERhdGEuaWQ7XG4gIGNvbnN0IHB1YmxpY0tleSA9IGF3YWl0IGdldEFwcGxlQ2VydGlmaWNhdGUoYXV0aERhdGEucHVibGljS2V5VXJsKTtcbiAgcmV0dXJuIHZlcmlmeVNpZ25hdHVyZShwdWJsaWNLZXksIGF1dGhEYXRhKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/github.js b/lib/Adapters/Auth/github.js new file mode 100644 index 0000000000..42601db410 --- /dev/null +++ b/lib/Adapters/Auth/github.js @@ -0,0 +1,40 @@ +"use strict"; + +// Helper functions for accessing the github API. +var Parse = require('parse/node').Parse; + +const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData) { + return request('user', authData.access_token).then(data => { + if (data && data.id == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Github auth is invalid for this user.'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for api requests + + +function request(path, access_token) { + return httpsRequest.get({ + host: 'api.github.com', + path: '/' + path, + headers: { + Authorization: 'bearer ' + access_token, + 'User-Agent': 'parse-server' + } + }); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2dpdGh1Yi5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJyZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsImRhdGEiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJnZXQiLCJob3N0IiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFDQSxNQUFNRSxZQUFZLEdBQUdELE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNFLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsTUFBRCxFQUFTRCxRQUFRLENBQUNFLFlBQWxCLENBQVAsQ0FBdUNDLElBQXZDLENBQTRDQyxJQUFJLElBQUk7QUFDekQsUUFBSUEsSUFBSSxJQUFJQSxJQUFJLENBQUNDLEVBQUwsSUFBV0wsUUFBUSxDQUFDSyxFQUFoQyxFQUFvQztBQUNsQztBQUNEOztBQUNELFVBQU0sSUFBSVQsS0FBSyxDQUFDVSxLQUFWLENBQWdCVixLQUFLLENBQUNVLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLHVDQUE5QyxDQUFOO0FBQ0QsR0FMTSxDQUFQO0FBTUQsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTVCxPQUFULENBQWlCVSxJQUFqQixFQUF1QlQsWUFBdkIsRUFBcUM7QUFDbkMsU0FBT0osWUFBWSxDQUFDYyxHQUFiLENBQWlCO0FBQ3RCQyxJQUFBQSxJQUFJLEVBQUUsZ0JBRGdCO0FBRXRCRixJQUFBQSxJQUFJLEVBQUUsTUFBTUEsSUFGVTtBQUd0QkcsSUFBQUEsT0FBTyxFQUFFO0FBQ1BDLE1BQUFBLGFBQWEsRUFBRSxZQUFZYixZQURwQjtBQUVQLG9CQUFjO0FBRlA7QUFIYSxHQUFqQixDQUFQO0FBUUQ7O0FBRURjLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVCxFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlQsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIGdpdGh1YiBBUEkuXG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG4gIHJldHVybiByZXF1ZXN0KCd1c2VyJywgYXV0aERhdGEuYWNjZXNzX3Rva2VuKS50aGVuKGRhdGEgPT4ge1xuICAgIGlmIChkYXRhICYmIGRhdGEuaWQgPT0gYXV0aERhdGEuaWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdHaXRodWIgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBhcGkgcmVxdWVzdHNcbmZ1bmN0aW9uIHJlcXVlc3QocGF0aCwgYWNjZXNzX3Rva2VuKSB7XG4gIHJldHVybiBodHRwc1JlcXVlc3QuZ2V0KHtcbiAgICBob3N0OiAnYXBpLmdpdGh1Yi5jb20nLFxuICAgIHBhdGg6ICcvJyArIHBhdGgsXG4gICAgaGVhZGVyczoge1xuICAgICAgQXV0aG9yaXphdGlvbjogJ2JlYXJlciAnICsgYWNjZXNzX3Rva2VuLFxuICAgICAgJ1VzZXItQWdlbnQnOiAncGFyc2Utc2VydmVyJyxcbiAgICB9LFxuICB9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQ6IHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGE6IHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/google.js b/lib/Adapters/Auth/google.js new file mode 100644 index 0000000000..5d02b17870 --- /dev/null +++ b/lib/Adapters/Auth/google.js @@ -0,0 +1,167 @@ +'use strict'; // Helper functions for accessing the google API. + +var Parse = require('parse/node').Parse; + +const https = require('https'); + +const jwt = require('jsonwebtoken'); + +const TOKEN_ISSUER = 'accounts.google.com'; +const HTTPS_TOKEN_ISSUER = 'https://accounts.google.com'; +let cache = {}; // Retrieve Google Signin Keys (with cache control) + +function getGoogleKeyByKeyId(keyId) { + if (cache[keyId] && cache.expiresAt > new Date()) { + return cache[keyId]; + } + + return new Promise((resolve, reject) => { + https.get(`https://www.googleapis.com/oauth2/v3/certs`, res => { + let data = ''; + res.on('data', chunk => { + data += chunk.toString('utf8'); + }); + res.on('end', () => { + const { + keys + } = JSON.parse(data); + const pems = keys.reduce((pems, { + n: modulus, + e: exposant, + kid + }) => Object.assign(pems, { + [kid]: rsaPublicKeyToPEM(modulus, exposant) + }), {}); + + if (res.headers['cache-control']) { + var expire = res.headers['cache-control'].match(/max-age=([0-9]+)/); + + if (expire) { + cache = Object.assign({}, pems, { + expiresAt: new Date(new Date().getTime() + Number(expire[1]) * 1000) + }); + } + } + + resolve(pems[keyId]); + }); + }).on('error', reject); + }); +} + +function getHeaderFromToken(token) { + const decodedToken = jwt.decode(token, { + complete: true + }); + + if (!decodedToken) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `provided token does not decode as JWT`); + } + + return decodedToken.header; +} + +async function verifyIdToken({ + id_token: token, + id +}, { + clientId +}) { + if (!token) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token is invalid for this user.`); + } + + const { + kid: keyId, + alg: algorithm + } = getHeaderFromToken(token); + let jwtClaims; + const googleKey = await getGoogleKeyByKeyId(keyId); + + try { + jwtClaims = jwt.verify(token, googleKey, { + algorithms: algorithm, + audience: clientId + }); + } catch (exception) { + const message = exception.message; + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `${message}`); + } + + if (jwtClaims.iss !== TOKEN_ISSUER && jwtClaims.iss !== HTTPS_TOKEN_ISSUER) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token not issued by correct provider - expected: ${TOKEN_ISSUER} or ${HTTPS_TOKEN_ISSUER} | from: ${jwtClaims.iss}`); + } + + if (jwtClaims.sub !== id) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `auth data is invalid for this user.`); + } + + if (clientId && jwtClaims.aud !== clientId) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token not authorized for this clientId.`); + } + + return jwtClaims; +} // Returns a promise that fulfills if this user id is valid. + + +function validateAuthData(authData, options = {}) { + return verifyIdToken(authData, options); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; // Helpers functions to convert the RSA certs to PEM (from jwks-rsa) + +function rsaPublicKeyToPEM(modulusB64, exponentB64) { + const modulus = new Buffer(modulusB64, 'base64'); + const exponent = new Buffer(exponentB64, 'base64'); + const modulusHex = prepadSigned(modulus.toString('hex')); + const exponentHex = prepadSigned(exponent.toString('hex')); + const modlen = modulusHex.length / 2; + const explen = exponentHex.length / 2; + const encodedModlen = encodeLengthHex(modlen); + const encodedExplen = encodeLengthHex(explen); + const encodedPubkey = '30' + encodeLengthHex(modlen + explen + encodedModlen.length / 2 + encodedExplen.length / 2 + 2) + '02' + encodedModlen + modulusHex + '02' + encodedExplen + exponentHex; + const der = new Buffer(encodedPubkey, 'hex').toString('base64'); + let pem = '-----BEGIN RSA PUBLIC KEY-----\n'; + pem += `${der.match(/.{1,64}/g).join('\n')}`; + pem += '\n-----END RSA PUBLIC KEY-----\n'; + return pem; +} + +function prepadSigned(hexStr) { + const msb = hexStr[0]; + + if (msb < '0' || msb > '7') { + return `00${hexStr}`; + } + + return hexStr; +} + +function toHex(number) { + const nstr = number.toString(16); + + if (nstr.length % 2) { + return `0${nstr}`; + } + + return nstr; +} + +function encodeLengthHex(n) { + if (n <= 127) { + return toHex(n); + } + + const nHex = toHex(n); + const lengthOfLengthByte = 128 + nHex.length / 2; + return toHex(lengthOfLengthByte) + nHex; +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2dvb2dsZS5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwcyIsImp3dCIsIlRPS0VOX0lTU1VFUiIsIkhUVFBTX1RPS0VOX0lTU1VFUiIsImNhY2hlIiwiZ2V0R29vZ2xlS2V5QnlLZXlJZCIsImtleUlkIiwiZXhwaXJlc0F0IiwiRGF0ZSIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiZ2V0IiwicmVzIiwiZGF0YSIsIm9uIiwiY2h1bmsiLCJ0b1N0cmluZyIsImtleXMiLCJKU09OIiwicGFyc2UiLCJwZW1zIiwicmVkdWNlIiwibiIsIm1vZHVsdXMiLCJlIiwiZXhwb3NhbnQiLCJraWQiLCJPYmplY3QiLCJhc3NpZ24iLCJyc2FQdWJsaWNLZXlUb1BFTSIsImhlYWRlcnMiLCJleHBpcmUiLCJtYXRjaCIsImdldFRpbWUiLCJOdW1iZXIiLCJnZXRIZWFkZXJGcm9tVG9rZW4iLCJ0b2tlbiIsImRlY29kZWRUb2tlbiIsImRlY29kZSIsImNvbXBsZXRlIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiaGVhZGVyIiwidmVyaWZ5SWRUb2tlbiIsImlkX3Rva2VuIiwiaWQiLCJjbGllbnRJZCIsImFsZyIsImFsZ29yaXRobSIsImp3dENsYWltcyIsImdvb2dsZUtleSIsInZlcmlmeSIsImFsZ29yaXRobXMiLCJhdWRpZW5jZSIsImV4Y2VwdGlvbiIsIm1lc3NhZ2UiLCJpc3MiLCJzdWIiLCJhdWQiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJvcHRpb25zIiwidmFsaWRhdGVBcHBJZCIsIm1vZHVsZSIsImV4cG9ydHMiLCJtb2R1bHVzQjY0IiwiZXhwb25lbnRCNjQiLCJCdWZmZXIiLCJleHBvbmVudCIsIm1vZHVsdXNIZXgiLCJwcmVwYWRTaWduZWQiLCJleHBvbmVudEhleCIsIm1vZGxlbiIsImxlbmd0aCIsImV4cGxlbiIsImVuY29kZWRNb2RsZW4iLCJlbmNvZGVMZW5ndGhIZXgiLCJlbmNvZGVkRXhwbGVuIiwiZW5jb2RlZFB1YmtleSIsImRlciIsInBlbSIsImpvaW4iLCJoZXhTdHIiLCJtc2IiLCJ0b0hleCIsIm51bWJlciIsIm5zdHIiLCJuSGV4IiwibGVuZ3RoT2ZMZW5ndGhCeXRlIl0sIm1hcHBpbmdzIjoiQUFBQSxhLENBRUE7O0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFFQSxNQUFNRSxLQUFLLEdBQUdELE9BQU8sQ0FBQyxPQUFELENBQXJCOztBQUNBLE1BQU1FLEdBQUcsR0FBR0YsT0FBTyxDQUFDLGNBQUQsQ0FBbkI7O0FBRUEsTUFBTUcsWUFBWSxHQUFHLHFCQUFyQjtBQUNBLE1BQU1DLGtCQUFrQixHQUFHLDZCQUEzQjtBQUVBLElBQUlDLEtBQUssR0FBRyxFQUFaLEMsQ0FFQTs7QUFDQSxTQUFTQyxtQkFBVCxDQUE2QkMsS0FBN0IsRUFBb0M7QUFDbEMsTUFBSUYsS0FBSyxDQUFDRSxLQUFELENBQUwsSUFBZ0JGLEtBQUssQ0FBQ0csU0FBTixHQUFrQixJQUFJQyxJQUFKLEVBQXRDLEVBQWtEO0FBQ2hELFdBQU9KLEtBQUssQ0FBQ0UsS0FBRCxDQUFaO0FBQ0Q7O0FBRUQsU0FBTyxJQUFJRyxPQUFKLENBQVksQ0FBQ0MsT0FBRCxFQUFVQyxNQUFWLEtBQXFCO0FBQ3RDWCxJQUFBQSxLQUFLLENBQ0ZZLEdBREgsQ0FDUSw0Q0FEUixFQUNxREMsR0FBRyxJQUFJO0FBQ3hELFVBQUlDLElBQUksR0FBRyxFQUFYO0FBQ0FELE1BQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLE1BQVAsRUFBZUMsS0FBSyxJQUFJO0FBQ3RCRixRQUFBQSxJQUFJLElBQUlFLEtBQUssQ0FBQ0MsUUFBTixDQUFlLE1BQWYsQ0FBUjtBQUNELE9BRkQ7QUFHQUosTUFBQUEsR0FBRyxDQUFDRSxFQUFKLENBQU8sS0FBUCxFQUFjLE1BQU07QUFDbEIsY0FBTTtBQUFFRyxVQUFBQTtBQUFGLFlBQVdDLElBQUksQ0FBQ0Ms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O0FBQ0EsU0FBT0EsR0FBUDtBQUNEOztBQUVELFNBQVNWLFlBQVQsQ0FBc0JZLE1BQXRCLEVBQThCO0FBQzVCLFFBQU1DLEdBQUcsR0FBR0QsTUFBTSxDQUFDLENBQUQsQ0FBbEI7O0FBQ0EsTUFBSUMsR0FBRyxHQUFHLEdBQU4sSUFBYUEsR0FBRyxHQUFHLEdBQXZCLEVBQTRCO0FBQzFCLFdBQVEsS0FBSUQsTUFBTyxFQUFuQjtBQUNEOztBQUNELFNBQU9BLE1BQVA7QUFDRDs7QUFFRCxTQUFTRSxLQUFULENBQWVDLE1BQWYsRUFBdUI7QUFDckIsUUFBTUMsSUFBSSxHQUFHRCxNQUFNLENBQUNyRSxRQUFQLENBQWdCLEVBQWhCLENBQWI7O0FBQ0EsTUFBSXNFLElBQUksQ0FBQ2IsTUFBTCxHQUFjLENBQWxCLEVBQXFCO0FBQ25CLFdBQVEsSUFBR2EsSUFBSyxFQUFoQjtBQUNEOztBQUNELFNBQU9BLElBQVA7QUFDRDs7QUFFRCxTQUFTVixlQUFULENBQXlCdEQsQ0FBekIsRUFBNEI7QUFDMUIsTUFBSUEsQ0FBQyxJQUFJLEdBQVQsRUFBYztBQUNaLFdBQU84RCxLQUFLLENBQUM5RCxDQUFELENBQVo7QUFDRDs7QUFDRCxRQUFNaUUsSUFBSSxHQUFHSCxLQUFLLENBQUM5RCxDQUFELENBQWxCO0FBQ0EsUUFBTWtFLGtCQUFrQixHQUFHLE1BQU1ELElBQUksQ0FBQ2QsTUFBTCxHQUFjLENBQS9DO0FBQ0EsU0FBT1csS0FBSyxDQUFDSSxrQkFBRCxDQUFMLEdBQTRCRCxJQUFuQztBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIGdvb2dsZSBBUEkuXG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbmNvbnN0IGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKTtcbmNvbnN0IGp3dCA9IHJlcXVpcmUoJ2pzb253ZWJ0b2tlbicpO1xuXG5jb25zdCBUT0tFTl9JU1NVRVIgPSAnYWNjb3VudHMuZ29vZ2xlLmNvbSc7XG5jb25zdCBIVFRQU19UT0tFTl9JU1NVRVIgPSAnaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tJztcblxubGV0IGNhY2hlID0ge307XG5cbi8vIFJldHJpZXZlIEdvb2dsZSBTaWduaW4gS2V5cyAod2l0aCBjYWNoZSBjb250cm9sKVxuZnVuY3Rpb24gZ2V0R29vZ2xlS2V5QnlLZXlJZChrZXlJZCkge1xuICBpZiAoY2FjaGVba2V5SWRdICYmIGNhY2hlLmV4cGlyZXNBdCA+IG5ldyBEYXRlKCkpIHtcbiAgICByZXR1cm4gY2FjaGVba2V5SWRdO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBodHRwc1xuICAgICAgLmdldChgaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vb2F1dGgyL3YzL2NlcnRzYCwgcmVzID0+IHtcbiAgICAgICAgbGV0IGRhdGEgPSAnJztcbiAgICAgICAgcmVzLm9uKCdkYXRhJywgY2h1bmsgPT4ge1xuICAgICAgICAgIGRhdGEgKz0gY2h1bmsudG9TdHJpbmcoJ3V0ZjgnKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJlcy5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsga2V5cyB9ID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgICAgICBjb25zdCBwZW1zID0ga2V5cy5yZWR1Y2UoXG4gICAgICAgICAgICAocGVtcywgeyBuOiBtb2R1bHVzLCBlOiBleHBvc2FudCwga2lkIH0pID0+XG4gICAgICAgICAgICAgIE9iamVjdC5hc3NpZ24ocGVtcywge1xuICAgICAgICAgICAgICAgIFtraWRdOiByc2FQdWJsaWNLZXlUb1BFTShtb2R1bHVzLCBleHBvc2FudCksXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAge31cbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKHJlcy5oZWFkZXJzWydjYWNoZS1jb250cm9sJ10pIHtcbiAgICAgICAgICAgIHZhciBleHBpcmUgPSByZXMuaGVhZGVyc1snY2FjaGUtY29udHJvbCddLm1hdGNoKC9tYXgtYWdlPShbMC05XSspLyk7XG5cbiAgICAgICAgICAgIGlmIChleHBpcmUpIHtcbiAgICAgICAgICAgICAgY2FjaGUgPSBPYmplY3QuYXNzaWduKHt9LCBwZW1zLCB7XG4gICAgICAgICAgICAgICAgZXhwaXJlc0F0OiBuZXcgRGF0ZShuZXcgRGF0ZSgpLmdldFRpbWUoKSArIE51bWJlcihleHBpcmVbMV0pICogMTAwMCksXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJlc29sdmUocGVtc1trZXlJZF0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldEhlYWRlckZyb21Ub2tlbih0b2tlbikge1xuICBjb25zdCBkZWNvZGVkVG9rZW4gPSBqd3QuZGVjb2RlKHRva2VuLCB7IGNvbXBsZXRlOiB0cnVlIH0pO1xuXG4gIGlmICghZGVjb2RlZFRva2VuKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsIGBwcm92aWRlZCB0b2tlbiBkb2VzIG5vdCBkZWNvZGUgYXMgSldUYCk7XG4gIH1cblxuICByZXR1cm4gZGVjb2RlZFRva2VuLmhlYWRlcjtcbn1cblxuYXN5bmMgZnVuY3Rpb24gdmVyaWZ5SWRUb2tlbih7IGlkX3Rva2VuOiB0b2tlbiwgaWQgfSwgeyBjbGllbnRJZCB9KSB7XG4gIGlmICghdG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgYGlkIHRva2VuIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci5gKTtcbiAgfVxuXG4gIGNvbnN0IHsga2lkOiBrZXlJZCwgYWxnOiBhbGdvcml0aG0gfSA9IGdldEhlYWRlckZyb21Ub2tlbih0b2tlbik7XG4gIGxldCBqd3RDbGFpbXM7XG4gIGNvbnN0IGdvb2dsZUtleSA9IGF3YWl0IGdldEdvb2dsZUtleUJ5S2V5SWQoa2V5SWQpO1xuXG4gIHRyeSB7XG4gICAgand0Q2xhaW1zID0gand0LnZlcmlmeSh0b2tlbiwgZ29vZ2xlS2V5LCB7XG4gICAgICBhbGdvcml0aG1zOiBhbGdvcml0aG0sXG4gICAgICBhdWRpZW5jZTogY2xpZW50SWQsXG4gICAgfSk7XG4gIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBleGNlcHRpb24ubWVzc2FnZTtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgYCR7bWVzc2FnZX1gKTtcbiAgfVxuXG4gIGlmIChqd3RDbGFpbXMuaXNzICE9PSBUT0tFTl9JU1NVRVIgJiYgand0Q2xhaW1zLmlzcyAhPT0gSFRUUFNfVE9LRU5fSVNTVUVSKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgIGBpZCB0b2tlbiBub3QgaXNzdWVkIGJ5IGNvcnJlY3QgcHJvdmlkZXIgLSBleHBlY3RlZDogJHtUT0tFTl9JU1NVRVJ9IG9yICR7SFRUUFNfVE9LRU5fSVNTVUVSfSB8IGZyb206ICR7and0Q2xhaW1zLmlzc31gXG4gICAgKTtcbiAgfVxuXG4gIGlmIChqd3RDbGFpbXMuc3ViICE9PSBpZCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBgYXV0aCBkYXRhIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci5gKTtcbiAgfVxuXG4gIGlmIChjbGllbnRJZCAmJiBqd3RDbGFpbXMuYXVkICE9PSBjbGllbnRJZCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICBgaWQgdG9rZW4gbm90IGF1dGhvcml6ZWQgZm9yIHRoaXMgY2xpZW50SWQuYFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gand0Q2xhaW1zO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIG9wdGlvbnMgPSB7fSkge1xuICByZXR1cm4gdmVyaWZ5SWRUb2tlbihhdXRoRGF0YSwgb3B0aW9ucyk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcblxuLy8gSGVscGVycyBmdW5jdGlvbnMgdG8gY29udmVydCB0aGUgUlNBIGNlcnRzIHRvIFBFTSAoZnJvbSBqd2tzLXJzYSlcbmZ1bmN0aW9uIHJzYVB1YmxpY0tleVRvUEVNKG1vZHVsdXNCNjQsIGV4cG9uZW50QjY0KSB7XG4gIGNvbnN0IG1vZHVsdXMgPSBuZXcgQnVmZmVyKG1vZHVsdXNCNjQsICdiYXNlNjQnKTtcbiAgY29uc3QgZXhwb25lbnQgPSBuZXcgQnVmZmVyKGV4cG9uZW50QjY0LCAnYmFzZTY0Jyk7XG4gIGNvbnN0IG1vZHVsdXNIZXggPSBwcmVwYWRTaWduZWQobW9kdWx1cy50b1N0cmluZygnaGV4JykpO1xuICBjb25zdCBleHBvbmVudEhleCA9IHByZXBhZFNpZ25lZChleHBvbmVudC50b1N0cmluZygnaGV4JykpO1xuICBjb25zdCBtb2RsZW4gPSBtb2R1bHVzSGV4Lmxlbmd0aCAvIDI7XG4gIGNvbnN0IGV4cGxlbiA9IGV4cG9uZW50SGV4Lmxlbmd0aCAvIDI7XG5cbiAgY29uc3QgZW5jb2RlZE1vZGxlbiA9IGVuY29kZUxlbmd0aEhleChtb2RsZW4pO1xuICBjb25zdCBlbmNvZGVkRXhwbGVuID0gZW5jb2RlTGVuZ3RoSGV4KGV4cGxlbik7XG4gIGNvbnN0IGVuY29kZWRQdWJrZXkgPVxuICAgICczMCcgK1xuICAgIGVuY29kZUxlbmd0aEhleChtb2RsZW4gKyBleHBsZW4gKyBlbmNvZGVkTW9kbGVuLmxlbmd0aCAvIDIgKyBlbmNvZGVkRXhwbGVuLmxlbmd0aCAvIDIgKyAyKSArXG4gICAgJzAyJyArXG4gICAgZW5jb2RlZE1vZGxlbiArXG4gICAgbW9kdWx1c0hleCArXG4gICAgJzAyJyArXG4gICAgZW5jb2RlZEV4cGxlbiArXG4gICAgZXhwb25lbnRIZXg7XG5cbiAgY29uc3QgZGVyID0gbmV3IEJ1ZmZlcihlbmNvZGVkUHVia2V5LCAnaGV4JykudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuXG4gIGxldCBwZW0gPSAnLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tXFxuJztcbiAgcGVtICs9IGAke2Rlci5tYXRjaCgvLnsxLDY0fS9nKS5qb2luKCdcXG4nKX1gO1xuICBwZW0gKz0gJ1xcbi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS1cXG4nO1xuICByZXR1cm4gcGVtO1xufVxuXG5mdW5jdGlvbiBwcmVwYWRTaWduZWQoaGV4U3RyKSB7XG4gIGNvbnN0IG1zYiA9IGhleFN0clswXTtcbiAgaWYgKG1zYiA8ICcwJyB8fCBtc2IgPiAnNycpIHtcbiAgICByZXR1cm4gYDAwJHtoZXhTdHJ9YDtcbiAgfVxuICByZXR1cm4gaGV4U3RyO1xufVxuXG5mdW5jdGlvbiB0b0hleChudW1iZXIpIHtcbiAgY29uc3QgbnN0ciA9IG51bWJlci50b1N0cmluZygxNik7XG4gIGlmIChuc3RyLmxlbmd0aCAlIDIpIHtcbiAgICByZXR1cm4gYDAke25zdHJ9YDtcbiAgfVxuICByZXR1cm4gbnN0cjtcbn1cblxuZnVuY3Rpb24gZW5jb2RlTGVuZ3RoSGV4KG4pIHtcbiAgaWYgKG4gPD0gMTI3KSB7XG4gICAgcmV0dXJuIHRvSGV4KG4pO1xuICB9XG4gIGNvbnN0IG5IZXggPSB0b0hleChuKTtcbiAgY29uc3QgbGVuZ3RoT2ZMZW5ndGhCeXRlID0gMTI4ICsgbkhleC5sZW5ndGggLyAyO1xuICByZXR1cm4gdG9IZXgobGVuZ3RoT2ZMZW5ndGhCeXRlKSArIG5IZXg7XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/gpgames.js b/lib/Adapters/Auth/gpgames.js new file mode 100644 index 0000000000..9030748d39 --- /dev/null +++ b/lib/Adapters/Auth/gpgames.js @@ -0,0 +1,35 @@ +"use strict"; + +/* Google Play Game Services +https://developers.google.com/games/services/web/api/players/get + +const authData = { + id: 'playerId', + access_token: 'token', +}; +*/ +const { + Parse +} = require('parse/node'); + +const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills if this user id is valid. + + +async function validateAuthData(authData) { + const response = await httpsRequest.get(`https://www.googleapis.com/games/v1/players/${authData.id}?access_token=${authData.access_token}`); + + if (!(response && response.playerId === authData.id)) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Google Play Games Services - authData is invalid for this user.'); + } +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} + +module.exports = { + validateAppId, + validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2dwZ2FtZXMuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwiaHR0cHNSZXF1ZXN0IiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwicmVzcG9uc2UiLCJnZXQiLCJpZCIsImFjY2Vzc190b2tlbiIsInBsYXllcklkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsIlByb21pc2UiLCJyZXNvbHZlIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUFFQSxFQUFBQTtBQUFGLElBQVlDLE9BQU8sQ0FBQyxZQUFELENBQXpCOztBQUNBLE1BQU1DLFlBQVksR0FBR0QsT0FBTyxDQUFDLGdCQUFELENBQTVCLEMsQ0FFQTs7O0FBQ0EsZUFBZUUsZ0JBQWYsQ0FBZ0NDLFFBQWhDLEVBQTBDO0FBQ3hDLFFBQU1DLFFBQVEsR0FBRyxNQUFNSCxZQUFZLENBQUNJLEdBQWIsQ0FDcEIsK0NBQThDRixRQUFRLENBQUNHLEVBQUcsaUJBQWdCSCxRQUFRLENBQUNJLFlBQWEsRUFENUUsQ0FBdkI7O0FBR0EsTUFBSSxFQUFFSCxRQUFRLElBQUlBLFFBQVEsQ0FBQ0ksUUFBVCxLQUFzQkwsUUFBUSxDQUFDRyxFQUE3QyxDQUFKLEVBQXNEO0FBQ3BELFVBQU0sSUFBSVAsS0FBSyxDQUFDVSxLQUFWLENBQ0pWLEtBQUssQ0FBQ1UsS0FBTixDQUFZQyxnQkFEUixFQUVKLGlFQUZJLENBQU47QUFJRDtBQUNGLEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVEQyxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZkosRUFBQUEsYUFEZTtBQUVmVCxFQUFBQTtBQUZlLENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLyogR29vZ2xlIFBsYXkgR2FtZSBTZXJ2aWNlc1xuaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vZ2FtZXMvc2VydmljZXMvd2ViL2FwaS9wbGF5ZXJzL2dldFxuXG5jb25zdCBhdXRoRGF0YSA9IHtcbiAgaWQ6ICdwbGF5ZXJJZCcsXG4gIGFjY2Vzc190b2tlbjogJ3Rva2VuJyxcbn07XG4qL1xuY29uc3QgeyBQYXJzZSB9ID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpO1xuY29uc3QgaHR0cHNSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwc1JlcXVlc3QnKTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5hc3luYyBmdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgaHR0cHNSZXF1ZXN0LmdldChcbiAgICBgaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZ2FtZXMvdjEvcGxheWVycy8ke2F1dGhEYXRhLmlkfT9hY2Nlc3NfdG9rZW49JHthdXRoRGF0YS5hY2Nlc3NfdG9rZW59YFxuICApO1xuICBpZiAoIShyZXNwb25zZSAmJiByZXNwb25zZS5wbGF5ZXJJZCA9PT0gYXV0aERhdGEuaWQpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICdHb29nbGUgUGxheSBHYW1lcyBTZXJ2aWNlcyAtIGF1dGhEYXRhIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nXG4gICAgKTtcbiAgfVxufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/httpsRequest.js b/lib/Adapters/Auth/httpsRequest.js new file mode 100644 index 0000000000..d6dd47a969 --- /dev/null +++ b/lib/Adapters/Auth/httpsRequest.js @@ -0,0 +1,47 @@ +"use strict"; + +const https = require('https'); + +function makeCallback(resolve, reject, noJSON) { + return function (res) { + let data = ''; + res.on('data', chunk => { + data += chunk; + }); + res.on('end', () => { + if (noJSON) { + return resolve(data); + } + + try { + data = JSON.parse(data); + } catch (e) { + return reject(e); + } + + resolve(data); + }); + res.on('error', reject); + }; +} + +function get(options, noJSON = false) { + return new Promise((resolve, reject) => { + https.get(options, makeCallback(resolve, reject, noJSON)).on('error', reject); + }); +} + +function request(options, postData) { + return new Promise((resolve, reject) => { + const req = https.request(options, makeCallback(resolve, reject)); + req.on('error', reject); + req.write(postData); + req.end(); + }); +} + +module.exports = { + get, + request +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2h0dHBzUmVxdWVzdC5qcyJdLCJuYW1lcyI6WyJodHRwcyIsInJlcXVpcmUiLCJtYWtlQ2FsbGJhY2siLCJyZXNvbHZlIiwicmVqZWN0Iiwibm9KU09OIiwicmVzIiwiZGF0YSIsIm9uIiwiY2h1bmsiLCJKU09OIiwicGFyc2UiLCJlIiwiZ2V0Iiwib3B0aW9ucyIsIlByb21pc2UiLCJyZXF1ZXN0IiwicG9zdERhdGEiLCJyZXEiLCJ3cml0ZSIsImVuZCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUEsTUFBTUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsT0FBRCxDQUFyQjs7QUFFQSxTQUFTQyxZQUFULENBQXNCQyxPQUF0QixFQUErQkMsTUFBL0IsRUFBdUNDLE1BQXZDLEVBQStDO0FBQzdDLFNBQU8sVUFBVUMsR0FBVixFQUFlO0FBQ3BCLFFBQUlDLElBQUksR0FBRyxFQUFYO0FBQ0FELElBQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLE1BQVAsRUFBZUMsS0FBSyxJQUFJO0FBQ3RCRixNQUFBQSxJQUFJLElBQUlFLEtBQVI7QUFDRCxLQUZEO0FBR0FILElBQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLEtBQVAsRUFBYyxNQUFNO0FBQ2xCLFVBQUlILE1BQUosRUFBWTtBQUNWLGVBQU9GLE9BQU8sQ0FBQ0ksSUFBRCxDQUFkO0FBQ0Q7O0FBQ0QsVUFBSTtBQUNGQSxRQUFBQSxJQUFJLEdBQUdHLElBQUksQ0FBQ0MsS0FBTCxDQUFXSixJQUFYLENBQVA7QUFDRCxPQUZELENBRUUsT0FBT0ssQ0FBUCxFQUFVO0FBQ1YsZUFBT1IsTUFBTSxDQUFDUSxDQUFELENBQWI7QUFDRDs7QUFDRFQsTUFBQUEsT0FBTyxDQUFDSSxJQUFELENBQVA7QUFDRCxLQVZEO0FBV0FELElBQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLE9BQVAsRUFBZ0JKLE1BQWhCO0FBQ0QsR0FqQkQ7QUFrQkQ7O0FBRUQsU0FBU1MsR0FBVCxDQUFhQyxPQUFiLEVBQXNCVCxNQUFNLEdBQUcsS0FBL0IsRUFBc0M7QUFDcEMsU0FBTyxJQUFJVSxPQUFKLENBQVksQ0FBQ1osT0FBRCxFQUFVQyxNQUFWLEtBQXFCO0FBQ3RDSixJQUFBQSxLQUFLLENBQUNhLEdBQU4sQ0FBVUMsT0FBVixFQUFtQlosWUFBWSxDQUFDQyxPQUFELEVBQVVDLE1BQVYsRUFBa0JDLE1BQWxCLENBQS9CLEVBQTBERyxFQUExRCxDQUE2RCxPQUE3RCxFQUFzRUosTUFBdEU7QUFDRCxHQUZNLENBQVA7QUFHRDs7QUFFRCxTQUFTWSxPQUFULENBQWlCRixPQUFqQixFQUEwQkcsUUFBMUIsRUFBb0M7QUFDbEMsU0FBTyxJQUFJRixPQUFKLENBQVksQ0FBQ1osT0FBRCxFQUFVQyxNQUFWLEtBQXFCO0FBQ3RDLFVBQU1jLEdBQUcsR0FBR2xCLEtBQUssQ0FBQ2dCLE9BQU4sQ0FBY0YsT0FBZCxFQUF1QlosWUFBWSxDQUFDQyxPQUFELEVBQVVDLE1BQVYsQ0FBbkMsQ0FBWjtBQUNBYyxJQUFBQSxHQUFHLENBQUNWLEVBQUosQ0FBTyxPQUFQLEVBQWdCSixNQUFoQjtBQUNBYyxJQUFBQSxHQUFHLENBQUNDLEtBQUosQ0FBVUYsUUFBVjtBQUNBQyxJQUFBQSxHQUFHLENBQUNFLEdBQUo7QUFDRCxHQUxNLENBQVA7QUFNRDs7QUFFREMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQUVULEVBQUFBLEdBQUY7QUFBT0csRUFBQUE7QUFBUCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKTtcblxuZnVuY3Rpb24gbWFrZUNhbGxiYWNrKHJlc29sdmUsIHJlamVjdCwgbm9KU09OKSB7XG4gIHJldHVybiBmdW5jdGlvbiAocmVzKSB7XG4gICAgbGV0IGRhdGEgPSAnJztcbiAgICByZXMub24oJ2RhdGEnLCBjaHVuayA9PiB7XG4gICAgICBkYXRhICs9IGNodW5rO1xuICAgIH0pO1xuICAgIHJlcy5vbignZW5kJywgKCkgPT4ge1xuICAgICAgaWYgKG5vSlNPTikge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZShkYXRhKTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIGRhdGEgPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gcmVqZWN0KGUpO1xuICAgICAgfVxuICAgICAgcmVzb2x2ZShkYXRhKTtcbiAgICB9KTtcbiAgICByZXMub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0KG9wdGlvbnMsIG5vSlNPTiA9IGZhbHNlKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgaHR0cHMuZ2V0KG9wdGlvbnMsIG1ha2VDYWxsYmFjayhyZXNvbHZlLCByZWplY3QsIG5vSlNPTikpLm9uKCdlcnJvcicsIHJlamVjdCk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiByZXF1ZXN0KG9wdGlvbnMsIHBvc3REYXRhKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgcmVxID0gaHR0cHMucmVxdWVzdChvcHRpb25zLCBtYWtlQ2FsbGJhY2socmVzb2x2ZSwgcmVqZWN0KSk7XG4gICAgcmVxLm9uKCdlcnJvcicsIHJlamVjdCk7XG4gICAgcmVxLndyaXRlKHBvc3REYXRhKTtcbiAgICByZXEuZW5kKCk7XG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHsgZ2V0LCByZXF1ZXN0IH07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/index.js b/lib/Adapters/Auth/index.js new file mode 100755 index 0000000000..a2ab7b7442 --- /dev/null +++ b/lib/Adapters/Auth/index.js @@ -0,0 +1,173 @@ +"use strict"; + +var _AdapterLoader = _interopRequireDefault(require("../AdapterLoader")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const apple = require('./apple'); + +const gcenter = require('./gcenter'); + +const gpgames = require('./gpgames'); + +const facebook = require('./facebook'); + +const instagram = require('./instagram'); + +const linkedin = require('./linkedin'); + +const meetup = require('./meetup'); + +const google = require('./google'); + +const github = require('./github'); + +const twitter = require('./twitter'); + +const spotify = require('./spotify'); + +const digits = require('./twitter'); // digits tokens are validated by twitter + + +const janrainengage = require('./janrainengage'); + +const janraincapture = require('./janraincapture'); + +const line = require('./line'); + +const vkontakte = require('./vkontakte'); + +const qq = require('./qq'); + +const wechat = require('./wechat'); + +const weibo = require('./weibo'); + +const oauth2 = require('./oauth2'); + +const phantauth = require('./phantauth'); + +const microsoft = require('./microsoft'); + +const keycloak = require('./keycloak'); + +const ldap = require('./ldap'); + +const anonymous = { + validateAuthData: () => { + return Promise.resolve(); + }, + validateAppId: () => { + return Promise.resolve(); + } +}; +const providers = { + apple, + gcenter, + gpgames, + facebook, + instagram, + linkedin, + meetup, + google, + github, + twitter, + spotify, + anonymous, + digits, + janrainengage, + janraincapture, + line, + vkontakte, + qq, + wechat, + weibo, + phantauth, + microsoft, + keycloak, + ldap +}; + +function authDataValidator(adapter, appIds, options) { + return function (authData) { + return adapter.validateAuthData(authData, options).then(() => { + if (appIds) { + return adapter.validateAppId(appIds, authData, options); + } + + return Promise.resolve(); + }); + }; +} + +function loadAuthAdapter(provider, authOptions) { + let defaultAdapter = providers[provider]; + const providerOptions = authOptions[provider]; + + if (providerOptions && Object.prototype.hasOwnProperty.call(providerOptions, 'oauth2') && providerOptions['oauth2'] === true) { + defaultAdapter = oauth2; + } + + if (!defaultAdapter && !providerOptions) { + return; + } + + const adapter = Object.assign({}, defaultAdapter); + const appIds = providerOptions ? providerOptions.appIds : undefined; // Try the configuration methods + + if (providerOptions) { + const optionalAdapter = (0, _AdapterLoader.default)(providerOptions, undefined, providerOptions); + + if (optionalAdapter) { + ['validateAuthData', 'validateAppId'].forEach(key => { + if (optionalAdapter[key]) { + adapter[key] = optionalAdapter[key]; + } + }); + } + } // TODO: create a new module from validateAdapter() in + // src/Controllers/AdaptableController.js so we can use it here for adapter + // validation based on the src/Adapters/Auth/AuthAdapter.js expected class + // signature. + + + if (!adapter.validateAuthData || !adapter.validateAppId) { + return; + } + + return { + adapter, + appIds, + providerOptions + }; +} + +module.exports = function (authOptions = {}, enableAnonymousUsers = true) { + let _enableAnonymousUsers = enableAnonymousUsers; + + const setEnableAnonymousUsers = function (enable) { + _enableAnonymousUsers = enable; + }; // To handle the test cases on configuration + + + const getValidatorForProvider = function (provider) { + if (provider === 'anonymous' && !_enableAnonymousUsers) { + return; + } + + const { + adapter, + appIds, + providerOptions + } = loadAuthAdapter(provider, authOptions); + return authDataValidator(adapter, appIds, providerOptions); + }; + + return Object.freeze({ + getValidatorForProvider, + setEnableAnonymousUsers + }); +}; + +module.exports.loadAuthAdapter = loadAuthAdapter; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2luZGV4LmpzIl0sIm5hbWVzIjpbImFwcGxlIiwicmVxdWlyZSIsImdjZW50ZXIiLCJncGdhbWVzIiwiZmFjZWJvb2siLCJpbnN0YWdyYW0iLCJsaW5rZWRpbiIsIm1lZXR1cCIsImdvb2dsZSIsImdpdGh1YiIsInR3aXR0ZXIiLCJzcG90aWZ5IiwiZGlnaXRzIiwiamFucmFpbmVuZ2FnZSIsImphbnJhaW5jYXB0dXJlIiwibGluZSIsInZrb250YWt0ZSIsInFxIiwid2VjaGF0Iiwid2VpYm8iLCJvYXV0aDIiLCJwaGFudGF1dGgiLCJtaWNyb3NvZnQiLCJrZXljbG9hayIsImxkYXAiLCJhbm9ueW1vdXMiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ2YWxpZGF0ZUFwcElkIiwicHJvdmlkZXJzIiwiYXV0aERhdGFWYWxpZGF0b3IiLCJhZGFwdGVyIiwiYXBwSWRzIiwib3B0aW9ucyIsImF1dGhEYXRhIiwidGhlbiIsImxvYWRBdXRoQWRhcHRlciIsInByb3ZpZGVyIiwiYXV0aE9wdGlvbnMiLCJkZWZhdWx0QWRhcHRlciIsInByb3ZpZGVyT3B0aW9ucyIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImFzc2lnbiIsInVuZGVmaW5lZCIsIm9wdGlvbmFsQWRhcHRlciIsImZvckVhY2giLCJrZXkiLCJtb2R1bGUiLCJleHBvcnRzIiwiZW5hYmxlQW5vbnltb3VzVXNlcnMiLCJfZW5hYmxlQW5vbnltb3VzVXNlcnMiLCJzZXRFbmFibGVBbm9ueW1vdXNVc2VycyIsImVuYWJsZSIsImdldFZhbGlkYXRvckZvclByb3ZpZGVyIiwiZnJlZXplIl0sIm1hcHBpbmdzIjoiOztBQUFBOzs7O0FBRUEsTUFBTUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsU0FBRCxDQUFyQjs7QUFDQSxNQUFNQyxPQUFPLEdBQUdELE9BQU8sQ0FBQyxXQUFELENBQXZCOztBQUNBLE1BQU1FLE9BQU8sR0FBR0YsT0FBTyxDQUFDLFdBQUQsQ0FBdkI7O0FBQ0EsTUFBTUcsUUFBUSxHQUFHSCxPQUFPLENBQUMsWUFBRCxDQUF4Qjs7QUFDQSxNQUFNSSxTQUFTLEdBQUdKLE9BQU8sQ0FBQyxhQUFELENBQXpCOztBQUNBLE1BQU1LLFFBQVEsR0FBR0wsT0FBTyxDQUFDLFlBQUQsQ0FBeEI7O0FBQ0EsTUFBTU0sTUFBTSxHQUFHTixPQUFPLENBQUMsVUFBRCxDQUF0Qjs7QUFDQSxNQUFNTyxNQUFNLEdBQUdQLE9BQU8sQ0FBQyxVQUFELENBQXRCOztBQUNBLE1BQU1RLE1BQU0sR0FBR1IsT0FBTyxDQUFDLFVBQUQsQ0FBdEI7O0FBQ0EsTUFBTVMsT0FBTyxHQUFHVCxPQUFPLENBQUMsV0FBRCxDQUF2Qjs7QUFDQSxNQUFNVSxPQUFPLEdBQUdWLE9BQU8sQ0FBQyxXQUFELENBQXZCOztBQUNBLE1BQU1XLE1BQU0sR0FBR1gsT0FBTyxDQUFDLFdBQUQsQ0FBdEIsQyxDQUFxQzs7O0FBQ3JDLE1BQU1ZLGFBQWEsR0FBR1osT0FBTyxDQUFDLGlCQUFELENBQTdCOztBQUNBLE1BQU1hLGNBQWMsR0FBR2IsT0FBTyxDQUFDLGtCQUFELENBQTlCOztBQUNBLE1BQU1jLElBQUksR0FBR2QsT0FBTyxDQUFDLFFBQUQsQ0FBcEI7O0FBQ0EsTUFBTWUsU0FBUyxHQUFHZixPQUFPLENBQUMsYUFBRCxDQUF6Qjs7QUFDQSxNQUFNZ0IsRUFBRSxHQUFHaEIsT0FBTyxDQUFDLE1BQUQsQ0FBbEI7O0FBQ0EsTUFBTWlCLE1BQU0sR0FBR2pCLE9BQU8sQ0FBQyxVQUFELENBQXRCOztBQUNBLE1BQU1rQixLQUFLLEdBQUdsQixPQUFPLENBQUMsU0FBRCxDQUFyQjs7QUFDQSxNQUFNbUIsTUFBTSxHQUFHbkIsT0FBTyxDQUFDLFVBQUQsQ0FBdEI7O0FBQ0EsTUFBTW9CLFNBQVMsR0FBR3BCLE9BQU8sQ0FBQyxhQUFELENBQXpCOztBQUNBLE1BQU1xQixTQUFTLEdBQUdyQixPQUFPLENBQUMsYUFBRCxDQUF6Qjs7QUFDQSxNQUFNc0IsUUFBUSxHQUFHdEIsT0FBTyxDQUFDLFlBQUQsQ0FBeEI7O0FBQ0EsTUFBTXVCLElBQUksR0FBR3ZCLE9BQU8sQ0FBQyxRQUFELENBQXBCOztBQUVBLE1BQU13QixTQUFTLEdBQUc7QUFDaEJDLEVBQUFBLGdCQUFnQixFQUFFLE1BQU07QUFDdEIsV0FBT0MsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxHQUhlO0FBSWhCQyxFQUFBQSxhQUFhLEVBQUUsTUFBTTtBQUNuQixXQUFPRixPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEO0FBTmUsQ0FBbEI7QUFTQSxNQUFNRSxTQUFTLEdBQUc7QUFDaEI5QixFQUFBQSxLQURnQjtBQUVoQkUsRUFBQUEsT0FGZ0I7QUFHaEJDLEVBQUFBLE9BSGdCO0FBSWhCQyxFQUFBQSxRQUpnQjtBQUtoQkMsRUFBQUEsU0FMZ0I7QUFNaEJDLEVBQUFBLFFBTmdCO0FBT2hCQyxFQUFBQSxNQVBnQjtBQVFoQkMsRUFBQUEsTUFSZ0I7QUFTaEJDLEVBQUFBLE1BVGdCO0FBVWhCQyxFQUFBQSxPQVZnQjtBQVdoQkMsRUFBQUEsT0FYZ0I7QUFZaEJjLEVBQUFBLFNBWmdCO0FBYWhCYixFQUFBQSxNQWJnQjtBQWNoQkMsRUFBQUEsYUFkZ0I7QUFlaEJDLEVBQUFBLGNBZmdCO0FBZ0JoQkMsRUFBQUEsSUFoQmdCO0FBaUJoQkMsRUFBQUEsU0FqQmdCO0FBa0JoQkMsRUFBQUEsRUFsQmdCO0FBbUJoQkMsRUFBQUEsTUFuQmdCO0FBb0JoQkMsRUFBQUEsS0FwQmdCO0FBcUJoQkUsRUFBQUEsU0FyQmdCO0FBc0JoQkMsRUFBQUEsU0F0QmdCO0FBdUJoQkMsRUFBQUEsUUF2QmdCO0FBd0JoQkMsRUFBQUE7QUF4QmdCLENBQWxCOztBQTJCQSxTQUFTTyxpQkFBVCxDQUEyQkMsT0FBM0IsRUFBb0NDLE1BQXBDLEVBQTRDQyxPQUE1QyxFQUFxRDtBQUNuRCxTQUFPLFVBQVVDLFFBQVYsRUFBb0I7QUFDekIsV0FBT0gsT0FBTyxDQUFDTixnQkFBUixDQUF5QlMsUUFBekIsRUFBbUNELE9BQW5DLEVBQTRDRSxJQUE1QyxDQUFpRCxNQUFNO0FBQzVELFVBQUlILE1BQUosRUFBWTtBQUNWLGVBQU9ELE9BQU8sQ0FBQ0gsYUFBUixDQUFzQkksTUFBdEIsRUFBOEJFLFFBQTlCLEVBQXdDRCxPQUF4QyxDQUFQO0FBQ0Q7O0FBQ0QsYUFBT1AsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxLQUxNLENBQVA7QUFNRCxHQVBEO0FBUUQ7O0FBRUQsU0FBU1MsZUFBVCxDQUF5QkMsUUFBekIsRUFBbUNDLFdBQW5DLEVBQWdEO0FBQzlDLE1BQUlDLGNBQWMsR0FBR1YsU0FBUyxDQUFDUSxRQUFELENBQTlCO0FBQ0EsUUFBTUcsZUFBZSxHQUFHRixXQUFXLENBQUNELFFBQUQsQ0FBbkM7O0FBQ0EsTUFDRUcsZUFBZSxJQUNmQyxNQUFNLENBQUNDLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUFxQ0osZUFBckMsRUFBc0QsUUFBdEQsQ0FEQSxJQUVBQSxlQUFlLENBQUMsUUFBRCxDQUFmLEtBQThCLElBSGhDLEVBSUU7QUFDQUQsSUFBQUEsY0FBYyxHQUFHcEIsTUFBakI7QUFDRDs7QUFFRCxNQUFJLENBQUNvQixjQUFELElBQW1CLENBQUNDLGVBQXhCLEVBQXlDO0FBQ3ZDO0FBQ0Q7O0FBRUQsUUFBTVQsT0FBTyxHQUFHVSxNQUFNLENBQUNJLE1BQVAsQ0FBYyxFQUFkLEVBQWtCTixjQUFsQixDQUFoQjtBQUNBLFFBQU1QLE1BQU0sR0FBR1EsZUFBZSxHQUFHQSxlQUFlLENBQUNSLE1BQW5CLEdBQTRCYyxTQUExRCxDQWhCOEMsQ0FrQjlDOztBQUNBLE1BQUlOLGVBQUosRUFBcUI7QUFDbkIsVUFBTU8sZUFBZSxHQUFHLDRCQUFZUCxlQUFaLEVBQTZCTSxTQUE3QixFQUF3Q04sZUFBeEMsQ0FBeEI7O0FBQ0EsUUFBSU8sZUFBSixFQUFxQjtBQUNuQixPQUFDLGtCQUFELEVBQXFCLGVBQXJCLEVBQXNDQyxPQUF0QyxDQUE4Q0MsR0FBRyxJQUFJO0FBQ25ELFlBQUlGLGVBQWUsQ0FBQ0UsR0FBRCxDQUFuQixFQUEwQjtBQUN4QmxCLFVBQUFBLE9BQU8sQ0FBQ2tCLEdBQUQsQ0FBUCxHQUFlRixlQUFlLENBQUNFLEdBQUQsQ0FBOUI7QUFDRDtBQUNGLE9BSkQ7QUFLRDtBQUNGLEdBNUI2QyxDQThCOUM7QUFDQTtBQUNBO0FBQ0E7OztBQUNBLE1BQUksQ0FBQ2xCLE9BQU8sQ0FBQ04sZ0JBQVQsSUFBNkIsQ0FBQ00sT0FBTyxDQUFDSCxhQUExQyxFQUF5RDtBQUN2RDtBQUNEOztBQUVELFNBQU87QUFBRUcsSUFBQUEsT0FBRjtBQUFXQyxJQUFBQSxNQUFYO0FBQW1CUSxJQUFBQTtBQUFuQixHQUFQO0FBQ0Q7O0FBRURVLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQixVQUFVYixXQUFXLEdBQUcsRUFBeEIsRUFBNEJjLG9CQUFvQixHQUFHLElBQW5ELEVBQXlEO0FBQ3hFLE1BQUlDLHFCQUFxQixHQUFHRCxvQkFBNUI7O0FBQ0EsUUFBTUUsdUJBQXVCLEdBQUcsVUFBVUMsTUFBVixFQUFrQjtBQUNoREYsSUFBQUEscUJBQXFCLEdBQUdFLE1BQXhCO0FBQ0QsR0FGRCxDQUZ3RSxDQUt4RTs7O0FBQ0EsUUFBTUMsdUJBQXVCLEdBQUcsVUFBVW5CLFFBQVYsRUFBb0I7QUFDbEQsUUFBSUEsUUFBUSxLQUFLLFdBQWIsSUFBNEIsQ0FBQ2dCLHFCQUFqQyxFQUF3RDtBQUN0RDtBQUNEOztBQUVELFVBQU07QUFBRXRCLE1BQUFBLE9BQUY7QUFBV0MsTUFBQUEsTUFBWDtBQUFtQlEsTUFBQUE7QUFBbkIsUUFBdUNKLGVBQWUsQ0FBQ0MsUUFBRCxFQUFXQyxXQUFYLENBQTVEO0FBRUEsV0FBT1IsaUJBQWlCLENBQUNDLE9BQUQsRUFBVUMsTUFBVixFQUFrQlEsZUFBbEIsQ0FBeEI7QUFDRCxHQVJEOztBQVVBLFNBQU9DLE1BQU0sQ0FBQ2dCLE1BQVAsQ0FBYztBQUNuQkQsSUFBQUEsdUJBRG1CO0FBRW5CRixJQUFBQTtBQUZtQixHQUFkLENBQVA7QUFJRCxDQXBCRDs7QUFzQkFKLE1BQU0sQ0FBQ0MsT0FBUCxDQUFlZixlQUFmLEdBQWlDQSxlQUFqQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBsb2FkQWRhcHRlciBmcm9tICcuLi9BZGFwdGVyTG9hZGVyJztcblxuY29uc3QgYXBwbGUgPSByZXF1aXJlKCcuL2FwcGxlJyk7XG5jb25zdCBnY2VudGVyID0gcmVxdWlyZSgnLi9nY2VudGVyJyk7XG5jb25zdCBncGdhbWVzID0gcmVxdWlyZSgnLi9ncGdhbWVzJyk7XG5jb25zdCBmYWNlYm9vayA9IHJlcXVpcmUoJy4vZmFjZWJvb2snKTtcbmNvbnN0IGluc3RhZ3JhbSA9IHJlcXVpcmUoJy4vaW5zdGFncmFtJyk7XG5jb25zdCBsaW5rZWRpbiA9IHJlcXVpcmUoJy4vbGlua2VkaW4nKTtcbmNvbnN0IG1lZXR1cCA9IHJlcXVpcmUoJy4vbWVldHVwJyk7XG5jb25zdCBnb29nbGUgPSByZXF1aXJlKCcuL2dvb2dsZScpO1xuY29uc3QgZ2l0aHViID0gcmVxdWlyZSgnLi9naXRodWInKTtcbmNvbnN0IHR3aXR0ZXIgPSByZXF1aXJlKCcuL3R3aXR0ZXInKTtcbmNvbnN0IHNwb3RpZnkgPSByZXF1aXJlKCcuL3Nwb3RpZnknKTtcbmNvbnN0IGRpZ2l0cyA9IHJlcXVpcmUoJy4vdHdpdHRlcicpOyAvLyBkaWdpdHMgdG9rZW5zIGFyZSB2YWxpZGF0ZWQgYnkgdHdpdHRlclxuY29uc3QgamFucmFpbmVuZ2FnZSA9IHJlcXVpcmUoJy4vamFucmFpbmVuZ2FnZScpO1xuY29uc3QgamFucmFpbmNhcHR1cmUgPSByZXF1aXJlKCcuL2phbnJhaW5jYXB0dXJlJyk7XG5jb25zdCBsaW5lID0gcmVxdWlyZSgnLi9saW5lJyk7XG5jb25zdCB2a29udGFrdGUgPSByZXF1aXJlKCcuL3Zrb250YWt0ZScpO1xuY29uc3QgcXEgPSByZXF1aXJlKCcuL3FxJyk7XG5jb25zdCB3ZWNoYXQgPSByZXF1aXJlKCcuL3dlY2hhdCcpO1xuY29uc3Qgd2VpYm8gPSByZXF1aXJlKCcuL3dlaWJvJyk7XG5jb25zdCBvYXV0aDIgPSByZXF1aXJlKCcuL29hdXRoMicpO1xuY29uc3QgcGhhbnRhdXRoID0gcmVxdWlyZSgnLi9waGFudGF1dGgnKTtcbmNvbnN0IG1pY3Jvc29mdCA9IHJlcXVpcmUoJy4vbWljcm9zb2Z0Jyk7XG5jb25zdCBrZXljbG9hayA9IHJlcXVpcmUoJy4va2V5Y2xvYWsnKTtcbmNvbnN0IGxkYXAgPSByZXF1aXJlKCcuL2xkYXAnKTtcblxuY29uc3QgYW5vbnltb3VzID0ge1xuICB2YWxpZGF0ZUF1dGhEYXRhOiAoKSA9PiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9LFxuICB2YWxpZGF0ZUFwcElkOiAoKSA9PiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9LFxufTtcblxuY29uc3QgcHJvdmlkZXJzID0ge1xuICBhcHBsZSxcbiAgZ2NlbnRlcixcbiAgZ3BnYW1lcyxcbiAgZmFjZWJvb2ssXG4gIGluc3RhZ3JhbSxcbiAgbGlua2VkaW4sXG4gIG1lZXR1cCxcbiAgZ29vZ2xlLFxuICBnaXRodWIsXG4gIHR3aXR0ZXIsXG4gIHNwb3RpZnksXG4gIGFub255bW91cyxcbiAgZGlnaXRzLFxuICBqYW5yYWluZW5nYWdlLFxuICBqYW5yYWluY2FwdHVyZSxcbiAgbGluZSxcbiAgdmtvbnRha3RlLFxuICBxcSxcbiAgd2VjaGF0LFxuICB3ZWlibyxcbiAgcGhhbnRhdXRoLFxuICBtaWNyb3NvZnQsXG4gIGtleWNsb2FrLFxuICBsZGFwLFxufTtcblxuZnVuY3Rpb24gYXV0aERhdGFWYWxpZGF0b3IoYWRhcHRlciwgYXBwSWRzLCBvcHRpb25zKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoYXV0aERhdGEpIHtcbiAgICByZXR1cm4gYWRhcHRlci52YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhLCBvcHRpb25zKS50aGVuKCgpID0+IHtcbiAgICAgIGlmIChhcHBJZHMpIHtcbiAgICAgICAgcmV0dXJuIGFkYXB0ZXIudmFsaWRhdGVBcHBJZChhcHBJZHMsIGF1dGhEYXRhLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9KTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gbG9hZEF1dGhBZGFwdGVyKHByb3ZpZGVyLCBhdXRoT3B0aW9ucykge1xuICBsZXQgZGVmYXVsdEFkYXB0ZXIgPSBwcm92aWRlcnNbcHJvdmlkZXJdO1xuICBjb25zdCBwcm92aWRlck9wdGlvbnMgPSBhdXRoT3B0aW9uc1twcm92aWRlcl07XG4gIGlmIChcbiAgICBwcm92aWRlck9wdGlvbnMgJiZcbiAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocHJvdmlkZXJPcHRpb25zLCAnb2F1dGgyJykgJiZcbiAgICBwcm92aWRlck9wdGlvbnNbJ29hdXRoMiddID09PSB0cnVlXG4gICkge1xuICAgIGRlZmF1bHRBZGFwdGVyID0gb2F1dGgyO1xuICB9XG5cbiAgaWYgKCFkZWZhdWx0QWRhcHRlciAmJiAhcHJvdmlkZXJPcHRpb25zKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgYWRhcHRlciA9IE9iamVjdC5hc3NpZ24oe30sIGRlZmF1bHRBZGFwdGVyKTtcbiAgY29uc3QgYXBwSWRzID0gcHJvdmlkZXJPcHRpb25zID8gcHJvdmlkZXJPcHRpb25zLmFwcElkcyA6IHVuZGVmaW5lZDtcblxuICAvLyBUcnkgdGhlIGNvbmZpZ3VyYXRpb24gbWV0aG9kc1xuICBpZiAocHJvdmlkZXJPcHRpb25zKSB7XG4gICAgY29uc3Qgb3B0aW9uYWxBZGFwdGVyID0gbG9hZEFkYXB0ZXIocHJvdmlkZXJPcHRpb25zLCB1bmRlZmluZWQsIHByb3ZpZGVyT3B0aW9ucyk7XG4gICAgaWYgKG9wdGlvbmFsQWRhcHRlcikge1xuICAgICAgWyd2YWxpZGF0ZUF1dGhEYXRhJywgJ3ZhbGlkYXRlQXBwSWQnXS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgIGlmIChvcHRpb25hbEFkYXB0ZXJba2V5XSkge1xuICAgICAgICAgIGFkYXB0ZXJba2V5XSA9IG9wdGlvbmFsQWRhcHRlcltrZXldO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvLyBUT0RPOiBjcmVhdGUgYSBuZXcgbW9kdWxlIGZyb20gdmFsaWRhdGVBZGFwdGVyKCkgaW5cbiAgLy8gc3JjL0NvbnRyb2xsZXJzL0FkYXB0YWJsZUNvbnRyb2xsZXIuanMgc28gd2UgY2FuIHVzZSBpdCBoZXJlIGZvciBhZGFwdGVyXG4gIC8vIHZhbGlkYXRpb24gYmFzZWQgb24gdGhlIHNyYy9BZGFwdGVycy9BdXRoL0F1dGhBZGFwdGVyLmpzIGV4cGVjdGVkIGNsYXNzXG4gIC8vIHNpZ25hdHVyZS5cbiAgaWYgKCFhZGFwdGVyLnZhbGlkYXRlQXV0aERhdGEgfHwgIWFkYXB0ZXIudmFsaWRhdGVBcHBJZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHJldHVybiB7IGFkYXB0ZXIsIGFwcElkcywgcHJvdmlkZXJPcHRpb25zIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGF1dGhPcHRpb25zID0ge30sIGVuYWJsZUFub255bW91c1VzZXJzID0gdHJ1ZSkge1xuICBsZXQgX2VuYWJsZUFub255bW91c1VzZXJzID0gZW5hYmxlQW5vbnltb3VzVXNlcnM7XG4gIGNvbnN0IHNldEVuYWJsZUFub255bW91c1VzZXJzID0gZnVuY3Rpb24gKGVuYWJsZSkge1xuICAgIF9lbmFibGVBbm9ueW1vdXNVc2VycyA9IGVuYWJsZTtcbiAgfTtcbiAgLy8gVG8gaGFuZGxlIHRoZSB0ZXN0IGNhc2VzIG9uIGNvbmZpZ3VyYXRpb25cbiAgY29uc3QgZ2V0VmFsaWRhdG9yRm9yUHJvdmlkZXIgPSBmdW5jdGlvbiAocHJvdmlkZXIpIHtcbiAgICBpZiAocHJvdmlkZXIgPT09ICdhbm9ueW1vdXMnICYmICFfZW5hYmxlQW5vbnltb3VzVXNlcnMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB7IGFkYXB0ZXIsIGFwcElkcywgcHJvdmlkZXJPcHRpb25zIH0gPSBsb2FkQXV0aEFkYXB0ZXIocHJvdmlkZXIsIGF1dGhPcHRpb25zKTtcblxuICAgIHJldHVybiBhdXRoRGF0YVZhbGlkYXRvcihhZGFwdGVyLCBhcHBJZHMsIHByb3ZpZGVyT3B0aW9ucyk7XG4gIH07XG5cbiAgcmV0dXJuIE9iamVjdC5mcmVlemUoe1xuICAgIGdldFZhbGlkYXRvckZvclByb3ZpZGVyLFxuICAgIHNldEVuYWJsZUFub255bW91c1VzZXJzLFxuICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzLmxvYWRBdXRoQWRhcHRlciA9IGxvYWRBdXRoQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/instagram.js b/lib/Adapters/Auth/instagram.js new file mode 100644 index 0000000000..a6a888efb5 --- /dev/null +++ b/lib/Adapters/Auth/instagram.js @@ -0,0 +1,31 @@ +"use strict"; + +// Helper functions for accessing the instagram API. +var Parse = require('parse/node').Parse; + +const httpsRequest = require('./httpsRequest'); + +const defaultURL = 'https://graph.instagram.com/'; // Returns a promise that fulfills if this user id is valid. + +function validateAuthData(authData) { + const apiURL = authData.apiURL || defaultURL; + const path = `${apiURL}me?fields=id&access_token=${authData.access_token}`; + return httpsRequest.get(path).then(response => { + if (response && response.data && response.data.id == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Instagram auth is invalid for this user.'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} + +module.exports = { + validateAppId, + validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2luc3RhZ3JhbS5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJkZWZhdWx0VVJMIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwiYXBpVVJMIiwicGF0aCIsImFjY2Vzc190b2tlbiIsImdldCIsInRoZW4iLCJyZXNwb25zZSIsImRhdGEiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQSxJQUFJQSxLQUFLLEdBQUdDLE9BQU8sQ0FBQyxZQUFELENBQVAsQ0FBc0JELEtBQWxDOztBQUNBLE1BQU1FLFlBQVksR0FBR0QsT0FBTyxDQUFDLGdCQUFELENBQTVCOztBQUNBLE1BQU1FLFVBQVUsR0FBRyw4QkFBbkIsQyxDQUVBOztBQUNBLFNBQVNDLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxRQUFNQyxNQUFNLEdBQUdELFFBQVEsQ0FBQ0MsTUFBVCxJQUFtQkgsVUFBbEM7QUFDQSxRQUFNSSxJQUFJLEdBQUksR0FBRUQsTUFBTyw2QkFBNEJELFFBQVEsQ0FBQ0csWUFBYSxFQUF6RTtBQUNBLFNBQU9OLFlBQVksQ0FBQ08sR0FBYixDQUFpQkYsSUFBakIsRUFBdUJHLElBQXZCLENBQTRCQyxRQUFRLElBQUk7QUFDN0MsUUFBSUEsUUFBUSxJQUFJQSxRQUFRLENBQUNDLElBQXJCLElBQTZCRCxRQUFRLENBQUNDLElBQVQsQ0FBY0MsRUFBZCxJQUFvQlIsUUFBUSxDQUFDUSxFQUE5RCxFQUFrRTtBQUNoRTtBQUNEOztBQUNELFVBQU0sSUFBSWIsS0FBSyxDQUFDYyxLQUFWLENBQWdCZCxLQUFLLENBQUNjLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLDBDQUE5QyxDQUFOO0FBQ0QsR0FMTSxDQUFQO0FBTUQsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0Q7O0FBRURDLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmSixFQUFBQSxhQURlO0FBRWZaLEVBQUFBO0FBRmUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIGluc3RhZ3JhbSBBUEkuXG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuY29uc3QgZGVmYXVsdFVSTCA9ICdodHRwczovL2dyYXBoLmluc3RhZ3JhbS5jb20vJztcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG4gIGNvbnN0IGFwaVVSTCA9IGF1dGhEYXRhLmFwaVVSTCB8fCBkZWZhdWx0VVJMO1xuICBjb25zdCBwYXRoID0gYCR7YXBpVVJMfW1lP2ZpZWxkcz1pZCZhY2Nlc3NfdG9rZW49JHthdXRoRGF0YS5hY2Nlc3NfdG9rZW59YDtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQocGF0aCkudGhlbihyZXNwb25zZSA9PiB7XG4gICAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLmRhdGEgJiYgcmVzcG9uc2UuZGF0YS5pZCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0luc3RhZ3JhbSBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nKTtcbiAgfSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/janraincapture.js b/lib/Adapters/Auth/janraincapture.js new file mode 100644 index 0000000000..7ac024882f --- /dev/null +++ b/lib/Adapters/Auth/janraincapture.js @@ -0,0 +1,46 @@ +"use strict"; + +// Helper functions for accessing the Janrain Capture API. +var Parse = require('parse/node').Parse; + +var querystring = require('querystring'); + +const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData, options) { + return request(options.janrain_capture_host, authData.access_token).then(data => { + //successful response will have a "stat" (status) of 'ok' and a result node that stores the uuid, because that's all we asked for + //see: https://docs.janrain.com/api/registration/entity/#entity + if (data && data.stat == 'ok' && data.result == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Janrain capture auth is invalid for this user.'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId() { + //no-op + return Promise.resolve(); +} // A promisey wrapper for api requests + + +function request(host, access_token) { + var query_string_data = querystring.stringify({ + access_token: access_token, + attribute_name: 'uuid' // we only need to pull the uuid for this access token to make sure it matches + + }); + return httpsRequest.get({ + host: host, + path: '/entity?' + query_string_data + }); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2phbnJhaW5jYXB0dXJlLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsInF1ZXJ5c3RyaW5nIiwiaHR0cHNSZXF1ZXN0IiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsInJlcXVlc3QiLCJqYW5yYWluX2NhcHR1cmVfaG9zdCIsImFjY2Vzc190b2tlbiIsInRoZW4iLCJkYXRhIiwic3RhdCIsInJlc3VsdCIsImlkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsIlByb21pc2UiLCJyZXNvbHZlIiwiaG9zdCIsInF1ZXJ5X3N0cmluZ19kYXRhIiwic3RyaW5naWZ5IiwiYXR0cmlidXRlX25hbWUiLCJnZXQiLCJwYXRoIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBbEM7O0FBQ0EsSUFBSUUsV0FBVyxHQUFHRCxPQUFPLENBQUMsYUFBRCxDQUF6Qjs7QUFDQSxNQUFNRSxZQUFZLEdBQUdGLE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNHLGdCQUFULENBQTBCQyxRQUExQixFQUFvQ0MsT0FBcEMsRUFBNkM7QUFDM0MsU0FBT0MsT0FBTyxDQUFDRCxPQUFPLENBQUNFLG9CQUFULEVBQStCSCxRQUFRLENBQUNJLFlBQXhDLENBQVAsQ0FBNkRDLElBQTdELENBQWtFQyxJQUFJLElBQUk7QUFDL0U7QUFDQTtBQUNBLFFBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxJQUFMLElBQWEsSUFBckIsSUFBNkJELElBQUksQ0FBQ0UsTUFBTCxJQUFlUixRQUFRLENBQUNTLEVBQXpELEVBQTZEO0FBQzNEO0FBQ0Q7O0FBQ0QsVUFBTSxJQUFJZCxLQUFLLENBQUNlLEtBQVYsQ0FDSmYsS0FBSyxDQUFDZSxLQUFOLENBQVlDLGdCQURSLEVBRUosZ0RBRkksQ0FBTjtBQUlELEdBVk0sQ0FBUDtBQVdELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QjtBQUNBLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTWixPQUFULENBQWlCYSxJQUFqQixFQUF1QlgsWUFBdkIsRUFBcUM7QUFDbkMsTUFBSVksaUJBQWlCLEdBQUduQixXQUFXLENBQUNvQixTQUFaLENBQXNCO0FBQzVDYixJQUFBQSxZQUFZLEVBQUVBLFlBRDhCO0FBRTVDYyxJQUFBQSxjQUFjLEVBQUUsTUFGNEIsQ0FFcEI7O0FBRm9CLEdBQXRCLENBQXhCO0FBS0EsU0FBT3BCLFlBQVksQ0FBQ3FCLEdBQWIsQ0FBaUI7QUFBRUosSUFBQUEsSUFBSSxFQUFFQSxJQUFSO0FBQWNLLElBQUFBLElBQUksRUFBRSxhQUFhSjtBQUFqQyxHQUFqQixDQUFQO0FBQ0Q7O0FBRURLLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVixFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZmIsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIEphbnJhaW4gQ2FwdHVyZSBBUEkuXG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG52YXIgcXVlcnlzdHJpbmcgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpO1xuY29uc3QgaHR0cHNSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwc1JlcXVlc3QnKTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyB1c2VyIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSwgb3B0aW9ucykge1xuICByZXR1cm4gcmVxdWVzdChvcHRpb25zLmphbnJhaW5fY2FwdHVyZV9ob3N0LCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oZGF0YSA9PiB7XG4gICAgLy9zdWNjZXNzZnVsIHJlc3BvbnNlIHdpbGwgaGF2ZSBhIFwic3RhdFwiIChzdGF0dXMpIG9mICdvaycgYW5kIGEgcmVzdWx0IG5vZGUgdGhhdCBzdG9yZXMgdGhlIHV1aWQsIGJlY2F1c2UgdGhhdCdzIGFsbCB3ZSBhc2tlZCBmb3JcbiAgICAvL3NlZTogaHR0cHM6Ly9kb2NzLmphbnJhaW4uY29tL2FwaS9yZWdpc3RyYXRpb24vZW50aXR5LyNlbnRpdHlcbiAgICBpZiAoZGF0YSAmJiBkYXRhLnN0YXQgPT0gJ29rJyAmJiBkYXRhLnJlc3VsdCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ0phbnJhaW4gY2FwdHVyZSBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nXG4gICAgKTtcbiAgfSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgLy9uby1vcFxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbi8vIEEgcHJvbWlzZXkgd3JhcHBlciBmb3IgYXBpIHJlcXVlc3RzXG5mdW5jdGlvbiByZXF1ZXN0KGhvc3QsIGFjY2Vzc190b2tlbikge1xuICB2YXIgcXVlcnlfc3RyaW5nX2RhdGEgPSBxdWVyeXN0cmluZy5zdHJpbmdpZnkoe1xuICAgIGFjY2Vzc190b2tlbjogYWNjZXNzX3Rva2VuLFxuICAgIGF0dHJpYnV0ZV9uYW1lOiAndXVpZCcsIC8vIHdlIG9ubHkgbmVlZCB0byBwdWxsIHRoZSB1dWlkIGZvciB0aGlzIGFjY2VzcyB0b2tlbiB0byBtYWtlIHN1cmUgaXQgbWF0Y2hlc1xuICB9KTtcblxuICByZXR1cm4gaHR0cHNSZXF1ZXN0LmdldCh7IGhvc3Q6IGhvc3QsIHBhdGg6ICcvZW50aXR5PycgKyBxdWVyeV9zdHJpbmdfZGF0YSB9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQ6IHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGE6IHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/janrainengage.js b/lib/Adapters/Auth/janrainengage.js new file mode 100644 index 0000000000..d7c4774377 --- /dev/null +++ b/lib/Adapters/Auth/janrainengage.js @@ -0,0 +1,52 @@ +"use strict"; + +// Helper functions for accessing the Janrain Engage API. +var httpsRequest = require('./httpsRequest'); + +var Parse = require('parse/node').Parse; + +var querystring = require('querystring'); // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData, options) { + return apiRequest(options.api_key, authData.auth_token).then(data => { + //successful response will have a "stat" (status) of 'ok' and a profile node with an identifier + //see: http://developers.janrain.com/overview/social-login/identity-providers/user-profile-data/#normalized-user-profile-data + if (data && data.stat == 'ok' && data.profile.identifier == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Janrain engage auth is invalid for this user.'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId() { + //no-op + return Promise.resolve(); +} // A promisey wrapper for api requests + + +function apiRequest(api_key, auth_token) { + var post_data = querystring.stringify({ + token: auth_token, + apiKey: api_key, + format: 'json' + }); + var post_options = { + host: 'rpxnow.com', + path: '/api/v2/auth_info', + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Content-Length': post_data.length + } + }; + return httpsRequest.request(post_options, post_data); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2phbnJhaW5lbmdhZ2UuanMiXSwibmFtZXMiOlsiaHR0cHNSZXF1ZXN0IiwicmVxdWlyZSIsIlBhcnNlIiwicXVlcnlzdHJpbmciLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJvcHRpb25zIiwiYXBpUmVxdWVzdCIsImFwaV9rZXkiLCJhdXRoX3Rva2VuIiwidGhlbiIsImRhdGEiLCJzdGF0IiwicHJvZmlsZSIsImlkZW50aWZpZXIiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBvc3RfZGF0YSIsInN0cmluZ2lmeSIsInRva2VuIiwiYXBpS2V5IiwiZm9ybWF0IiwicG9zdF9vcHRpb25zIiwiaG9zdCIsInBhdGgiLCJtZXRob2QiLCJoZWFkZXJzIiwibGVuZ3RoIiwicmVxdWVzdCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQSxJQUFJQSxZQUFZLEdBQUdDLE9BQU8sQ0FBQyxnQkFBRCxDQUExQjs7QUFDQSxJQUFJQyxLQUFLLEdBQUdELE9BQU8sQ0FBQyxZQUFELENBQVAsQ0FBc0JDLEtBQWxDOztBQUNBLElBQUlDLFdBQVcsR0FBR0YsT0FBTyxDQUFDLGFBQUQsQ0FBekIsQyxDQUVBOzs7QUFDQSxTQUFTRyxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0NDLE9BQXBDLEVBQTZDO0FBQzNDLFNBQU9DLFVBQVUsQ0FBQ0QsT0FBTyxDQUFDRSxPQUFULEVBQWtCSCxRQUFRLENBQUNJLFVBQTNCLENBQVYsQ0FBaURDLElBQWpELENBQXNEQyxJQUFJLElBQUk7QUFDbkU7QUFDQTtBQUNBLFFBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxJQUFMLElBQWEsSUFBckIsSUFBNkJELElBQUksQ0FBQ0UsT0FBTCxDQUFhQyxVQUFiLElBQTJCVCxRQUFRLENBQUNVLEVBQXJFLEVBQXlFO0FBQ3ZFO0FBQ0Q7O0FBQ0QsVUFBTSxJQUFJYixLQUFLLENBQUNjLEtBQVYsQ0FDSmQsS0FBSyxDQUFDYyxLQUFOLENBQVlDLGdCQURSLEVBRUosK0NBRkksQ0FBTjtBQUlELEdBVk0sQ0FBUDtBQVdELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QjtBQUNBLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTYixVQUFULENBQW9CQyxPQUFwQixFQUE2QkMsVUFBN0IsRUFBeUM7QUFDdkMsTUFBSVksU0FBUyxHQUFHbEIsV0FBVyxDQUFDbUIsU0FBWixDQUFzQjtBQUNwQ0MsSUFBQUEsS0FBSyxFQUFFZCxVQUQ2QjtBQUVwQ2UsSUFBQUEsTUFBTSxFQUFFaEIsT0FGNEI7QUFHcENpQixJQUFBQSxNQUFNLEVBQUU7QUFINEIsR0FBdEIsQ0FBaEI7QUFNQSxNQUFJQyxZQUFZLEdBQUc7QUFDakJDLElBQUFBLElBQUksRUFBRSxZQURXO0FBRWpCQyxJQUFBQSxJQUFJLEVBQUUsbUJBRlc7QUFHakJDLElBQUFBLE1BQU0sRUFBRSxNQUhTO0FBSWpCQyxJQUFBQSxPQUFPLEVBQUU7QUFDUCxzQkFBZ0IsbUNBRFQ7QUFFUCx3QkFBa0JULFNBQVMsQ0FBQ1U7QUFGckI7QUFKUSxHQUFuQjtBQVVBLFNBQU8vQixZQUFZLENBQUNnQyxPQUFiLENBQXFCTixZQUFyQixFQUFtQ0wsU0FBbkMsQ0FBUDtBQUNEOztBQUVEWSxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZmhCLEVBQUFBLGFBQWEsRUFBRUEsYUFEQTtBQUVmZCxFQUFBQSxnQkFBZ0IsRUFBRUE7QUFGSCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgSmFucmFpbiBFbmdhZ2UgQVBJLlxudmFyIGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG52YXIgcXVlcnlzdHJpbmcgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhLCBvcHRpb25zKSB7XG4gIHJldHVybiBhcGlSZXF1ZXN0KG9wdGlvbnMuYXBpX2tleSwgYXV0aERhdGEuYXV0aF90b2tlbikudGhlbihkYXRhID0+IHtcbiAgICAvL3N1Y2Nlc3NmdWwgcmVzcG9uc2Ugd2lsbCBoYXZlIGEgXCJzdGF0XCIgKHN0YXR1cykgb2YgJ29rJyBhbmQgYSBwcm9maWxlIG5vZGUgd2l0aCBhbiBpZGVudGlmaWVyXG4gICAgLy9zZWU6IGh0dHA6Ly9kZXZlbG9wZXJzLmphbnJhaW4uY29tL292ZXJ2aWV3L3NvY2lhbC1sb2dpbi9pZGVudGl0eS1wcm92aWRlcnMvdXNlci1wcm9maWxlLWRhdGEvI25vcm1hbGl6ZWQtdXNlci1wcm9maWxlLWRhdGFcbiAgICBpZiAoZGF0YSAmJiBkYXRhLnN0YXQgPT0gJ29rJyAmJiBkYXRhLnByb2ZpbGUuaWRlbnRpZmllciA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ0phbnJhaW4gZW5nYWdlIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICApO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICAvL25vLW9wXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBhcGkgcmVxdWVzdHNcbmZ1bmN0aW9uIGFwaVJlcXVlc3QoYXBpX2tleSwgYXV0aF90b2tlbikge1xuICB2YXIgcG9zdF9kYXRhID0gcXVlcnlzdHJpbmcuc3RyaW5naWZ5KHtcbiAgICB0b2tlbjogYXV0aF90b2tlbixcbiAgICBhcGlLZXk6IGFwaV9rZXksXG4gICAgZm9ybWF0OiAnanNvbicsXG4gIH0pO1xuXG4gIHZhciBwb3N0X29wdGlvbnMgPSB7XG4gICAgaG9zdDogJ3JweG5vdy5jb20nLFxuICAgIHBhdGg6ICcvYXBpL3YyL2F1dGhfaW5mbycsXG4gICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgaGVhZGVyczoge1xuICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAgICAgJ0NvbnRlbnQtTGVuZ3RoJzogcG9zdF9kYXRhLmxlbmd0aCxcbiAgICB9LFxuICB9O1xuXG4gIHJldHVybiBodHRwc1JlcXVlc3QucmVxdWVzdChwb3N0X29wdGlvbnMsIHBvc3RfZGF0YSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/keycloak.js b/lib/Adapters/Auth/keycloak.js new file mode 100644 index 0000000000..6f022c8e9c --- /dev/null +++ b/lib/Adapters/Auth/keycloak.js @@ -0,0 +1,125 @@ +"use strict"; + +/* + # Parse Server Keycloak Authentication + + ## Keycloak `authData` + + ``` + { + "keycloak": { + "access_token": "access token you got from keycloak JS client authentication", + "id": "the id retrieved from client authentication in Keycloak", + "roles": ["the roles retrieved from client authentication in Keycloak"], + "groups": ["the groups retrieved from client authentication in Keycloak"] + } + } + ``` + + The authentication module will test if the authData is the same as the + userinfo oauth call, comparing the attributes + + Copy the JSON config file generated on Keycloak (https://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter) + and paste it inside of a folder (Ex.: `auth/keycloak.json`) in your server. + + The options passed to Parse server: + + ``` + { + auth: { + keycloak: { + config: require(`./auth/keycloak.json`) + } + } + } + ``` +*/ +const { + Parse +} = require('parse/node'); + +const httpsRequest = require('./httpsRequest'); + +const arraysEqual = (_arr1, _arr2) => { + if (!Array.isArray(_arr1) || !Array.isArray(_arr2) || _arr1.length !== _arr2.length) return false; + + var arr1 = _arr1.concat().sort(); + + var arr2 = _arr2.concat().sort(); + + for (var i = 0; i < arr1.length; i++) { + if (arr1[i] !== arr2[i]) return false; + } + + return true; +}; + +const handleAuth = async ({ + access_token, + id, + roles, + groups +} = {}, { + config +} = {}) => { + if (!(access_token && id)) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Missing access token and/or User id'); + } + + if (!config || !(config['auth-server-url'] && config['realm'])) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Missing keycloak configuration'); + } + + try { + const response = await httpsRequest.get({ + host: config['auth-server-url'], + path: `/realms/${config['realm']}/protocol/openid-connect/userinfo`, + headers: { + Authorization: 'Bearer ' + access_token + } + }); + + if (response && response.data && response.data.sub == id && arraysEqual(response.data.roles, roles) && arraysEqual(response.data.groups, groups)) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid authentication'); + } catch (e) { + if (e instanceof Parse.Error) { + throw e; + } + + const error = JSON.parse(e.text); + + if (error.error_description) { + throw new Parse.Error(Parse.Error.HOSTING_ERROR, error.error_description); + } else { + throw new Parse.Error(Parse.Error.HOSTING_ERROR, 'Could not connect to the authentication server'); + } + } +}; +/* + @param {Object} authData: the client provided authData + @param {string} authData.access_token: the access_token retrieved from client authentication in Keycloak + @param {string} authData.id: the id retrieved from client authentication in Keycloak + @param {Array} authData.roles: the roles retrieved from client authentication in Keycloak + @param {Array} authData.groups: the groups retrieved from client authentication in Keycloak + @param {Object} options: additional options + @param {Object} options.config: the config object passed during Parse Server instantiation +*/ + + +function validateAuthData(authData, options = {}) { + return handleAuth(authData, options); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} + +module.exports = { + validateAppId, + validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2tleWNsb2FrLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsImh0dHBzUmVxdWVzdCIsImFycmF5c0VxdWFsIiwiX2FycjEiLCJfYXJyMiIsIkFycmF5IiwiaXNBcnJheSIsImxlbmd0aCIsImFycjEiLCJjb25jYXQiLCJzb3J0IiwiYXJyMiIsImkiLCJoYW5kbGVBdXRoIiwiYWNjZXNzX3Rva2VuIiwiaWQiLCJyb2xlcyIsImdyb3VwcyIsImNvbmZpZyIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInJlc3BvbnNlIiwiZ2V0IiwiaG9zdCIsInBhdGgiLCJoZWFkZXJzIiwiQXV0aG9yaXphdGlvbiIsImRhdGEiLCJzdWIiLCJlIiwiZXJyb3IiLCJKU09OIiwicGFyc2UiLCJ0ZXh0IiwiZXJyb3JfZGVzY3JpcHRpb24iLCJIT1NUSU5HX0VSUk9SIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQSxNQUFNO0FBQUVBLEVBQUFBO0FBQUYsSUFBWUMsT0FBTyxDQUFDLFlBQUQsQ0FBekI7O0FBQ0EsTUFBTUMsWUFBWSxHQUFHRCxPQUFPLENBQUMsZ0JBQUQsQ0FBNUI7O0FBRUEsTUFBTUUsV0FBVyxHQUFHLENBQUNDLEtBQUQsRUFBUUMsS0FBUixLQUFrQjtBQUNwQyxNQUFJLENBQUNDLEtBQUssQ0FBQ0MsT0FBTixDQUFjSCxLQUFkLENB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QUssQ0FBQ29CLEtBQVYsQ0FDSnBCLEtBQUssQ0FBQ29CLEtBQU4sQ0FBWWdCLGFBRFIsRUFFSixnREFGSSxDQUFOO0FBSUQ7QUFDRjtBQUNGLENBdkNEO0FBeUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0EsU0FBU0MsZ0JBQVQsQ0FBMEJDLFFBQTFCLEVBQW9DQyxPQUFPLEdBQUcsRUFBOUMsRUFBa0Q7QUFDaEQsU0FBT3pCLFVBQVUsQ0FBQ3dCLFFBQUQsRUFBV0MsT0FBWCxDQUFqQjtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVEQyxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZkosRUFBQUEsYUFEZTtBQUVmSCxFQUFBQTtBQUZlLENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAgIyBQYXJzZSBTZXJ2ZXIgS2V5Y2xvYWsgQXV0aGVudGljYXRpb25cblxuICAjIyBLZXljbG9hayBgYXV0aERhdGFgXG5cbiAgYGBgXG4gICAge1xuICAgICAgXCJrZXljbG9ha1wiOiB7XG4gICAgICAgIFwiYWNjZXNzX3Rva2VuXCI6IFwiYWNjZXNzIHRva2VuIHlvdSBnb3QgZnJvbSBrZXljbG9hayBKUyBjbGllbnQgYXV0aGVudGljYXRpb25cIixcbiAgICAgICAgXCJpZFwiOiBcInRoZSBpZCByZXRyaWV2ZWQgZnJvbSBjbGllbnQgYXV0aGVudGljYXRpb24gaW4gS2V5Y2xvYWtcIixcbiAgICAgICAgXCJyb2xlc1wiOiBbXCJ0aGUgcm9sZXMgcmV0cmlldmVkIGZyb20gY2xpZW50IGF1dGhlbnRpY2F0aW9uIGluIEtleWNsb2FrXCJdLFxuICAgICAgICBcImdyb3Vwc1wiOiBbXCJ0aGUgZ3JvdXBzIHJldHJpZXZlZCBmcm9tIGNsaWVudCBhdXRoZW50aWNhdGlvbiBpbiBLZXljbG9ha1wiXVxuICAgICAgfVxuICAgIH1cbiAgYGBgXG5cbiAgVGhlIGF1dGhlbnRpY2F0aW9uIG1vZHVsZSB3aWxsIHRlc3QgaWYgdGhlIGF1dGhEYXRhIGlzIHRoZSBzYW1lIGFzIHRoZVxuICB1c2VyaW5mbyBvYXV0aCBjYWxsLCBjb21wYXJpbmcgdGhlIGF0dHJpYnV0ZXNcblxuICBDb3B5IHRoZSBKU09OIGNvbmZpZyBmaWxlIGdlbmVyYXRlZCBvbiBLZXljbG9hayAoaHR0cHM6Ly93d3cua2V5Y2xvYWsub3JnL2RvY3MvbGF0ZXN0L3NlY3VyaW5nX2FwcHMvaW5kZXguaHRtbCNfamF2YXNjcmlwdF9hZGFwdGVyKVxuICBhbmQgcGFzdGUgaXQgaW5zaWRlIG9mIGEgZm9sZGVyIChFeC46IGBhdXRoL2tleWNsb2FrLmpzb25gKSBpbiB5b3VyIHNlcnZlci5cblxuICBUaGUgb3B0aW9ucyBwYXNzZWQgdG8gUGFyc2Ugc2VydmVyOlxuXG4gIGBgYFxuICAgIHtcbiAgICAgIGF1dGg6IHtcbiAgICAgICAga2V5Y2xvYWs6IHtcbiAgICAgICAgICBjb25maWc6IHJlcXVpcmUoYC4vYXV0aC9rZXljbG9hay5qc29uYClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgYGBgXG4qL1xuXG5jb25zdCB7IFBhcnNlIH0gPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG5jb25zdCBhcnJheXNFcXVhbCA9IChfYXJyMSwgX2FycjIpID0+IHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KF9hcnIxKSB8fCAhQXJyYXkuaXNBcnJheShfYXJyMikgfHwgX2FycjEubGVuZ3RoICE9PSBfYXJyMi5sZW5ndGgpIHJldHVybiBmYWxzZTtcblxuICB2YXIgYXJyMSA9IF9hcnIxLmNvbmNhdCgpLnNvcnQoKTtcbiAgdmFyIGFycjIgPSBfYXJyMi5jb25jYXQoKS5zb3J0KCk7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIxLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGFycjFbaV0gIT09IGFycjJbaV0pIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuY29uc3QgaGFuZGxlQXV0aCA9IGFzeW5jICh7IGFjY2Vzc190b2tlbiwgaWQsIHJvbGVzLCBncm91cHMgfSA9IHt9LCB7IGNvbmZpZyB9ID0ge30pID0+IHtcbiAgaWYgKCEoYWNjZXNzX3Rva2VuICYmIGlkKSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnTWlzc2luZyBhY2Nlc3MgdG9rZW4gYW5kL29yIFVzZXIgaWQnKTtcbiAgfVxuICBpZiAoIWNvbmZpZyB8fCAhKGNvbmZpZ1snYXV0aC1zZXJ2ZXItdXJsJ10gJiYgY29uZmlnWydyZWFsbSddKSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnTWlzc2luZyBrZXljbG9hayBjb25maWd1cmF0aW9uJyk7XG4gIH1cbiAgdHJ5IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGh0dHBzUmVxdWVzdC5nZXQoe1xuICAgICAgaG9zdDogY29uZmlnWydhdXRoLXNlcnZlci11cmwnXSxcbiAgICAgIHBhdGg6IGAvcmVhbG1zLyR7Y29uZmlnWydyZWFsbSddfS9wcm90b2NvbC9vcGVuaWQtY29ubmVjdC91c2VyaW5mb2AsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgIEF1dGhvcml6YXRpb246ICdCZWFyZXIgJyArIGFjY2Vzc190b2tlbixcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgaWYgKFxuICAgICAgcmVzcG9uc2UgJiZcbiAgICAgIHJlc3BvbnNlLmRhdGEgJiZcbiAgICAgIHJlc3BvbnNlLmRhdGEuc3ViID09IGlkICYmXG4gICAgICBhcnJheXNFcXVhbChyZXNwb25zZS5kYXRhLnJvbGVzLCByb2xlcykgJiZcbiAgICAgIGFycmF5c0VxdWFsKHJlc3BvbnNlLmRhdGEuZ3JvdXBzLCBncm91cHMpXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnSW52YWxpZCBhdXRoZW50aWNhdGlvbicpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKGUgaW5zdGFuY2VvZiBQYXJzZS5FcnJvcikge1xuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gICAgY29uc3QgZXJyb3IgPSBKU09OLnBhcnNlKGUudGV4dCk7XG4gICAgaWYgKGVycm9yLmVycm9yX2Rlc2NyaXB0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSE9TVElOR19FUlJPUiwgZXJyb3IuZXJyb3JfZGVzY3JpcHRpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLkhPU1RJTkdfRVJST1IsXG4gICAgICAgICdDb3VsZCBub3QgY29ubmVjdCB0byB0aGUgYXV0aGVudGljYXRpb24gc2VydmVyJ1xuICAgICAgKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qXG4gIEBwYXJhbSB7T2JqZWN0fSBhdXRoRGF0YTogdGhlIGNsaWVudCBwcm92aWRlZCBhdXRoRGF0YVxuICBAcGFyYW0ge3N0cmluZ30gYXV0aERhdGEuYWNjZXNzX3Rva2VuOiB0aGUgYWNjZXNzX3Rva2VuIHJldHJpZXZlZCBmcm9tIGNsaWVudCBhdXRoZW50aWNhdGlvbiBpbiBLZXljbG9ha1xuICBAcGFyYW0ge3N0cmluZ30gYXV0aERhdGEuaWQ6IHRoZSBpZCByZXRyaWV2ZWQgZnJvbSBjbGllbnQgYXV0aGVudGljYXRpb24gaW4gS2V5Y2xvYWtcbiAgQHBhcmFtIHtBcnJheX0gIGF1dGhEYXRhLnJvbGVzOiB0aGUgcm9sZXMgcmV0cmlldmVkIGZyb20gY2xpZW50IGF1dGhlbnRpY2F0aW9uIGluIEtleWNsb2FrXG4gIEBwYXJhbSB7QXJyYXl9ICBhdXRoRGF0YS5ncm91cHM6IHRoZSBncm91cHMgcmV0cmlldmVkIGZyb20gY2xpZW50IGF1dGhlbnRpY2F0aW9uIGluIEtleWNsb2FrXG4gIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zOiBhZGRpdGlvbmFsIG9wdGlvbnNcbiAgQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMuY29uZmlnOiB0aGUgY29uZmlnIG9iamVjdCBwYXNzZWQgZHVyaW5nIFBhcnNlIFNlcnZlciBpbnN0YW50aWF0aW9uXG4qL1xuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSwgb3B0aW9ucyA9IHt9KSB7XG4gIHJldHVybiBoYW5kbGVBdXRoKGF1dGhEYXRhLCBvcHRpb25zKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/ldap.js b/lib/Adapters/Auth/ldap.js new file mode 100644 index 0000000000..ac2f99257d --- /dev/null +++ b/lib/Adapters/Auth/ldap.js @@ -0,0 +1,105 @@ +"use strict"; + +const ldapjs = require('ldapjs'); + +const Parse = require('parse/node').Parse; + +function validateAuthData(authData, options) { + if (!optionsAreValid(options)) { + return new Promise((_, reject) => { + reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP auth configuration missing')); + }); + } + + const clientOptions = options.url.startsWith('ldaps://') ? { + url: options.url, + tlsOptions: options.tlsOptions + } : { + url: options.url + }; + const client = ldapjs.createClient(clientOptions); + const userCn = typeof options.dn === 'string' ? options.dn.replace('{{id}}', authData.id) : `uid=${authData.id},${options.suffix}`; + return new Promise((resolve, reject) => { + client.bind(userCn, authData.password, ldapError => { + delete authData.password; + + if (ldapError) { + let error; + + switch (ldapError.code) { + case 49: + error = new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'LDAP: Wrong username or password'); + break; + + case 'DEPTH_ZERO_SELF_SIGNED_CERT': + error = new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'LDAPS: Certificate mismatch'); + break; + + default: + error = new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'LDAP: Somthing went wrong (' + ldapError.code + ')'); + } + + reject(error); + client.destroy(ldapError); + return; + } + + if (typeof options.groupCn === 'string' && typeof options.groupFilter === 'string') { + searchForGroup(client, options, authData.id, resolve, reject); + } else { + client.unbind(); + client.destroy(); + resolve(); + } + }); + }); +} + +function optionsAreValid(options) { + return typeof options === 'object' && typeof options.suffix === 'string' && typeof options.url === 'string' && (options.url.startsWith('ldap://') || options.url.startsWith('ldaps://') && typeof options.tlsOptions === 'object'); +} + +function searchForGroup(client, options, id, resolve, reject) { + const filter = options.groupFilter.replace(/{{id}}/gi, id); + const opts = { + scope: 'sub', + filter: filter + }; + let found = false; + client.search(options.suffix, opts, (searchError, res) => { + if (searchError) { + client.unbind(); + client.destroy(); + return reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP group search failed')); + } + + res.on('searchEntry', entry => { + if (entry.object.cn === options.groupCn) { + found = true; + client.unbind(); + client.destroy(); + return resolve(); + } + }); + res.on('end', () => { + if (!found) { + client.unbind(); + client.destroy(); + return reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP: User not in group')); + } + }); + res.on('error', () => { + return reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP group search failed')); + }); + }); +} + +function validateAppId() { + return Promise.resolve(); +} + +module.exports = { + validateAppId, + validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2xkYXAuanMiXSwibmFtZXMiOlsibGRhcGpzIiwicmVxdWlyZSIsIlBhcnNlIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsIm9wdGlvbnNBcmVWYWxpZCIsIlByb21pc2UiLCJfIiwicmVqZWN0IiwiRXJyb3IiLCJJTlRFUk5BTF9TRVJWRVJfRVJST1IiLCJjbGllbnRPcHRpb25zIiwidXJsIiwic3RhcnRzV2l0aCIsInRsc09wdGlvbnMiLCJjbGllbnQiLCJjcmVhdGVDbGllbnQiLCJ1c2VyQ24iLCJkbiIsInJlcGxhY2UiLCJpZCIsInN1ZmZpeCIsInJlc29sdmUiLCJiaW5kIiwicGFzc3dvcmQiLCJsZGFwRXJyb3IiLCJlcnJvciIsImNvZGUiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiZGVzdHJveSIsImdyb3VwQ24iLCJncm91cEZpbHRlciIsInNlYXJjaEZvckdyb3VwIiwidW5iaW5kIiwiZmlsdGVyIiwib3B0cyIsInNjb3BlIiwiZm91bmQiLCJzZWFyY2giLCJzZWFyY2hFcnJvciIsInJlcyIsIm9uIiwiZW50cnkiLCJvYmplY3QiLCJjbiIsInZhbGlkYXRlQXBwSWQiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLE1BQU1BLE1BQU0sR0FBR0MsT0FBTyxDQUFDLFFBQUQsQ0FBdEI7O0FBQ0EsTUFBTUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCQyxLQUFwQzs7QUFFQSxTQUFTQyxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0NDLE9BQXBDLEVBQTZDO0FBQzNDLE1BQUksQ0FBQ0MsZUFBZSxDQUFDRCxPQUFELENBQXBCLEVBQStCO0FBQzdCLFdBQU8sSUFBSUUsT0FBSixDQUFZLENBQUNDLENBQUQsRUFBSUMsTUFBSixLQUFlO0FBQ2hDQSxNQUFBQSxNQUFNLENBQUMsSUFBSVAsS0FBSyxDQUFDUSxLQUFWLENBQWdCUixLQUFLLENB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TTtBQUNsQixVQUFJLENBQUNKLEtBQUwsRUFBWTtBQUNWdEIsUUFBQUEsTUFBTSxDQUFDa0IsTUFBUDtBQUNBbEIsUUFBQUEsTUFBTSxDQUFDYyxPQUFQO0FBQ0EsZUFBT3JCLE1BQU0sQ0FDWCxJQUFJUCxLQUFLLENBQUNRLEtBQVYsQ0FBZ0JSLEtBQUssQ0FBQ1EsS0FBTixDQUFZQyxxQkFBNUIsRUFBbUQseUJBQW5ELENBRFcsQ0FBYjtBQUdEO0FBQ0YsS0FSRDtBQVNBOEIsSUFBQUEsR0FBRyxDQUFDQyxFQUFKLENBQU8sT0FBUCxFQUFnQixNQUFNO0FBQ3BCLGFBQU9qQyxNQUFNLENBQUMsSUFBSVAsS0FBSyxDQUFDUSxLQUFWLENBQWdCUixLQUFLLENBQUNRLEtBQU4sQ0FBWUMscUJBQTVCLEVBQW1ELDBCQUFuRCxDQUFELENBQWI7QUFDRCxLQUZEO0FBR0QsR0ExQkQ7QUEyQkQ7O0FBRUQsU0FBU21DLGFBQVQsR0FBeUI7QUFDdkIsU0FBT3ZDLE9BQU8sQ0FBQ2dCLE9BQVIsRUFBUDtBQUNEOztBQUVEd0IsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZGLEVBQUFBLGFBRGU7QUFFZjNDLEVBQUFBO0FBRmUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBsZGFwanMgPSByZXF1aXJlKCdsZGFwanMnKTtcbmNvbnN0IFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhLCBvcHRpb25zKSB7XG4gIGlmICghb3B0aW9uc0FyZVZhbGlkKG9wdGlvbnMpKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChfLCByZWplY3QpID0+IHtcbiAgICAgIHJlamVjdChuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLCAnTERBUCBhdXRoIGNvbmZpZ3VyYXRpb24gbWlzc2luZycpKTtcbiAgICB9KTtcbiAgfVxuICBjb25zdCBjbGllbnRPcHRpb25zID0gb3B0aW9ucy51cmwuc3RhcnRzV2l0aCgnbGRhcHM6Ly8nKVxuICAgID8geyB1cmw6IG9wdGlvbnMudXJsLCB0bHNPcHRpb25zOiBvcHRpb25zLnRsc09wdGlvbnMgfVxuICAgIDogeyB1cmw6IG9wdGlvbnMudXJsIH07XG5cbiAgY29uc3QgY2xpZW50ID0gbGRhcGpzLmNyZWF0ZUNsaWVudChjbGllbnRPcHRpb25zKTtcbiAgY29uc3QgdXNlckNuID1cbiAgICB0eXBlb2Ygb3B0aW9ucy5kbiA9PT0gJ3N0cmluZydcbiAgICAgID8gb3B0aW9ucy5kbi5yZXBsYWNlKCd7e2lkfX0nLCBhdXRoRGF0YS5pZClcbiAgICAgIDogYHVpZD0ke2F1dGhEYXRhLmlkfSwke29wdGlvbnMuc3VmZml4fWA7XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjbGllbnQuYmluZCh1c2VyQ24sIGF1dGhEYXRhLnBhc3N3b3JkLCBsZGFwRXJyb3IgPT4ge1xuICAgICAgZGVsZXRlIGF1dGhEYXRhLnBhc3N3b3JkO1xuICAgICAgaWYgKGxkYXBFcnJvcikge1xuICAgICAgICBsZXQgZXJyb3I7XG4gICAgICAgIHN3aXRjaCAobGRhcEVycm9yLmNvZGUpIHtcbiAgICAgICAgICBjYXNlIDQ5OlxuICAgICAgICAgICAgZXJyb3IgPSBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICAgICAgICdMREFQOiBXcm9uZyB1c2VybmFtZSBvciBwYXNzd29yZCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdERVBUSF9aRVJPX1NFTEZfU0lHTkVEX0NFUlQnOlxuICAgICAgICAgICAgZXJyb3IgPSBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0xEQVBTOiBDZXJ0aWZpY2F0ZSBtaXNtYXRjaCcpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGVycm9yID0gbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgICAgICAgICAnTERBUDogU29tdGhpbmcgd2VudCB3cm9uZyAoJyArIGxkYXBFcnJvci5jb2RlICsgJyknXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIGNsaWVudC5kZXN0cm95KGxkYXBFcnJvcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLmdyb3VwQ24gPT09ICdzdHJpbmcnICYmIHR5cGVvZiBvcHRpb25zLmdyb3VwRmlsdGVyID09PSAnc3RyaW5nJykge1xuICAgICAgICBzZWFyY2hGb3JHcm91cChjbGllbnQsIG9wdGlvbnMsIGF1dGhEYXRhLmlkLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2xpZW50LnVuYmluZCgpO1xuICAgICAgICBjbGllbnQuZGVzdHJveSgpO1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBvcHRpb25zQXJlVmFsaWQob3B0aW9ucykge1xuICByZXR1cm4gKFxuICAgIHR5cGVvZiBvcHRpb25zID09PSAnb2JqZWN0JyAmJlxuICAgIHR5cGVvZiBvcHRpb25zLnN1ZmZpeCA9PT0gJ3N0cmluZycgJiZcbiAgICB0eXBlb2Ygb3B0aW9ucy51cmwgPT09ICdzdHJpbmcnICYmXG4gICAgKG9wdGlvbnMudXJsLnN0YXJ0c1dpdGgoJ2xkYXA6Ly8nKSB8fFxuICAgICAgKG9wdGlvbnMudXJsLnN0YXJ0c1dpdGgoJ2xkYXBzOi8vJykgJiYgdHlwZW9mIG9wdGlvbnMudGxzT3B0aW9ucyA9PT0gJ29iamVjdCcpKVxuICApO1xufVxuXG5mdW5jdGlvbiBzZWFyY2hGb3JHcm91cChjbGllbnQsIG9wdGlvbnMsIGlkLCByZXNvbHZlLCByZWplY3QpIHtcbiAgY29uc3QgZmlsdGVyID0gb3B0aW9ucy5ncm91cEZpbHRlci5yZXBsYWNlKC97e2lkfX0vZ2ksIGlkKTtcbiAgY29uc3Qgb3B0cyA9IHtcbiAgICBzY29wZTogJ3N1YicsXG4gICAgZmlsdGVyOiBmaWx0ZXIsXG4gIH07XG4gIGxldCBmb3VuZCA9IGZhbHNlO1xuICBjbGllbnQuc2VhcmNoKG9wdGlvbnMuc3VmZml4LCBvcHRzLCAoc2VhcmNoRXJyb3IsIHJlcykgPT4ge1xuICAgIGlmIChzZWFyY2hFcnJvcikge1xuICAgICAgY2xpZW50LnVuYmluZCgpO1xuICAgICAgY2xpZW50LmRlc3Ryb3koKTtcbiAgICAgIHJldHVybiByZWplY3QobmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUiwgJ0xEQVAgZ3JvdXAgc2VhcmNoIGZhaWxlZCcpKTtcbiAgICB9XG4gICAgcmVzLm9uKCdzZWFyY2hFbnRyeScsIGVudHJ5ID0+IHtcbiAgICAgIGlmIChlbnRyeS5vYmplY3QuY24gPT09IG9wdGlvbnMuZ3JvdXBDbikge1xuICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgIGNsaWVudC51bmJpbmQoKTtcbiAgICAgICAgY2xpZW50LmRlc3Ryb3koKTtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXMub24oJ2VuZCcsICgpID0+IHtcbiAgICAgIGlmICghZm91bmQpIHtcbiAgICAgICAgY2xpZW50LnVuYmluZCgpO1xuICAgICAgICBjbGllbnQuZGVzdHJveSgpO1xuICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgIG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsICdMREFQOiBVc2VyIG5vdCBpbiBncm91cCcpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmVzLm9uKCdlcnJvcicsICgpID0+IHtcbiAgICAgIHJldHVybiByZWplY3QobmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUiwgJ0xEQVAgZ3JvdXAgc2VhcmNoIGZhaWxlZCcpKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/line.js b/lib/Adapters/Auth/line.js new file mode 100644 index 0000000000..7d346a0bcf --- /dev/null +++ b/lib/Adapters/Auth/line.js @@ -0,0 +1,41 @@ +"use strict"; + +// Helper functions for accessing the line API. +var Parse = require('parse/node').Parse; + +const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills if this user id is valid. + + +function validateAuthData(authData) { + return request('profile', authData.access_token).then(response => { + if (response && response.userId && response.userId === authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Line auth is invalid for this user.'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for api requests + + +function request(path, access_token) { + var options = { + host: 'api.line.me', + path: '/v2/' + path, + method: 'GET', + headers: { + Authorization: 'Bearer ' + access_token + } + }; + return httpsRequest.get(options); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2xpbmUuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwiaHR0cHNSZXF1ZXN0IiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwicmVxdWVzdCIsImFjY2Vzc190b2tlbiIsInRoZW4iLCJyZXNwb25zZSIsInVzZXJJZCIsImlkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsIlByb21pc2UiLCJyZXNvbHZlIiwicGF0aCIsIm9wdGlvbnMiLCJob3N0IiwibWV0aG9kIiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJnZXQiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFDQSxNQUFNRSxZQUFZLEdBQUdELE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNFLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsU0FBRCxFQUFZRCxRQUFRLENBQUNFLFlBQXJCLENBQVAsQ0FBMENDLElBQTFDLENBQStDQyxRQUFRLElBQUk7QUFDaEUsUUFBSUEsUUFBUSxJQUFJQSxRQUFRLENBQUNDLE1BQXJCLElBQStCRCxRQUFRLENBQUNDLE1BQVQsS0FBb0JMLFFBQVEsQ0FBQ00sRUFBaEUsRUFBb0U7QUFDbEU7QUFDRDs7QUFDRCxVQUFNLElBQUlWLEtBQUssQ0FBQ1csS0FBVixDQUFnQlgsS0FBSyxDQUFDVyxLQUFOLENBQVlDLGdCQUE1QixFQUE4QyxxQ0FBOUMsQ0FBTjtBQUNELEdBTE0sQ0FBUDtBQU1ELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU1YsT0FBVCxDQUFpQlcsSUFBakIsRUFBdUJWLFlBQXZCLEVBQXFDO0FBQ25DLE1BQUlXLE9BQU8sR0FBRztBQUNaQyxJQUFBQSxJQUFJLEVBQUUsYUFETTtBQUVaRixJQUFBQSxJQUFJLEVBQUUsU0FBU0EsSUFGSDtBQUdaRyxJQUFBQSxNQUFNLEVBQUUsS0FISTtBQUlaQyxJQUFBQSxPQUFPLEVBQUU7QUFDUEMsTUFBQUEsYUFBYSxFQUFFLFlBQVlmO0FBRHBCO0FBSkcsR0FBZDtBQVFBLFNBQU9KLFlBQVksQ0FBQ29CLEdBQWIsQ0FBaUJMLE9BQWpCLENBQVA7QUFDRDs7QUFFRE0sTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZYLEVBQUFBLGFBQWEsRUFBRUEsYUFEQTtBQUVmVixFQUFBQSxnQkFBZ0IsRUFBRUE7QUFGSCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgbGluZSBBUEkuXG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIHJlcXVlc3QoJ3Byb2ZpbGUnLCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgIGlmIChyZXNwb25zZSAmJiByZXNwb25zZS51c2VySWQgJiYgcmVzcG9uc2UudXNlcklkID09PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0xpbmUgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBhcGkgcmVxdWVzdHNcbmZ1bmN0aW9uIHJlcXVlc3QocGF0aCwgYWNjZXNzX3Rva2VuKSB7XG4gIHZhciBvcHRpb25zID0ge1xuICAgIGhvc3Q6ICdhcGkubGluZS5tZScsXG4gICAgcGF0aDogJy92Mi8nICsgcGF0aCxcbiAgICBtZXRob2Q6ICdHRVQnLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgIEF1dGhvcml6YXRpb246ICdCZWFyZXIgJyArIGFjY2Vzc190b2tlbixcbiAgICB9LFxuICB9O1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LmdldChvcHRpb25zKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQ6IHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGE6IHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/linkedin.js b/lib/Adapters/Auth/linkedin.js new file mode 100644 index 0000000000..6876cb4b0c --- /dev/null +++ b/lib/Adapters/Auth/linkedin.js @@ -0,0 +1,46 @@ +"use strict"; + +// Helper functions for accessing the linkedin API. +var Parse = require('parse/node').Parse; + +const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData) { + return request('me', authData.access_token, authData.is_mobile_sdk).then(data => { + if (data && data.id == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Linkedin auth is invalid for this user.'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for api requests + + +function request(path, access_token, is_mobile_sdk) { + var headers = { + Authorization: 'Bearer ' + access_token, + 'x-li-format': 'json' + }; + + if (is_mobile_sdk) { + headers['x-li-src'] = 'msdk'; + } + + return httpsRequest.get({ + host: 'api.linkedin.com', + path: '/v2/' + path, + headers: headers + }); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2xpbmtlZGluLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsImh0dHBzUmVxdWVzdCIsInZhbGlkYXRlQXV0aERhdGEiLCJhdXRoRGF0YSIsInJlcXVlc3QiLCJhY2Nlc3NfdG9rZW4iLCJpc19tb2JpbGVfc2RrIiwidGhlbiIsImRhdGEiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJoZWFkZXJzIiwiQXV0aG9yaXphdGlvbiIsImdldCIsImhvc3QiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFDQSxNQUFNRSxZQUFZLEdBQUdELE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNFLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsSUFBRCxFQUFPRCxRQUFRLENBQUNFLFlBQWhCLEVBQThCRixRQUFRLENBQUNHLGFBQXZDLENBQVAsQ0FBNkRDLElBQTdELENBQWtFQyxJQUFJLElBQUk7QUFDL0UsUUFBSUEsSUFBSSxJQUFJQSxJQUFJLENBQUNDLEVBQUwsSUFBV04sUUFBUSxDQUFDTSxFQUFoQyxFQUFvQztBQUNsQztBQUNEOztBQUNELFVBQU0sSUFBSVYsS0FBSyxDQUFDVyxLQUFWLENBQWdCWCxLQUFLLENBQUNXLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLHlDQUE5QyxDQUFOO0FBQ0QsR0FMTSxDQUFQO0FBTUQsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTVixPQUFULENBQWlCVyxJQUFqQixFQUF1QlYsWUFBdkIsRUFBcUNDLGFBQXJDLEVBQW9EO0FBQ2xELE1BQUlVLE9BQU8sR0FBRztBQUNaQyxJQUFBQSxhQUFhLEVBQUUsWUFBWVosWUFEZjtBQUVaLG1CQUFlO0FBRkgsR0FBZDs7QUFLQSxNQUFJQyxhQUFKLEVBQW1CO0FBQ2pCVSxJQUFBQSxPQUFPLENBQUMsVUFBRCxDQUFQLEdBQXNCLE1BQXRCO0FBQ0Q7O0FBQ0QsU0FBT2YsWUFBWSxDQUFDaUIsR0FBYixDQUFpQjtBQUN0QkMsSUFBQUEsSUFBSSxFQUFFLGtCQURnQjtBQUV0QkosSUFBQUEsSUFBSSxFQUFFLFNBQVNBLElBRk87QUFHdEJDLElBQUFBLE9BQU8sRUFBRUE7QUFIYSxHQUFqQixDQUFQO0FBS0Q7O0FBRURJLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVCxFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlYsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIGxpbmtlZGluIEFQSS5cbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIHJlcXVlc3QoJ21lJywgYXV0aERhdGEuYWNjZXNzX3Rva2VuLCBhdXRoRGF0YS5pc19tb2JpbGVfc2RrKS50aGVuKGRhdGEgPT4ge1xuICAgIGlmIChkYXRhICYmIGRhdGEuaWQgPT0gYXV0aERhdGEuaWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdMaW5rZWRpbiBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nKTtcbiAgfSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIGFwaSByZXF1ZXN0c1xuZnVuY3Rpb24gcmVxdWVzdChwYXRoLCBhY2Nlc3NfdG9rZW4sIGlzX21vYmlsZV9zZGspIHtcbiAgdmFyIGhlYWRlcnMgPSB7XG4gICAgQXV0aG9yaXphdGlvbjogJ0JlYXJlciAnICsgYWNjZXNzX3Rva2VuLFxuICAgICd4LWxpLWZvcm1hdCc6ICdqc29uJyxcbiAgfTtcblxuICBpZiAoaXNfbW9iaWxlX3Nkaykge1xuICAgIGhlYWRlcnNbJ3gtbGktc3JjJ10gPSAnbXNkayc7XG4gIH1cbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoe1xuICAgIGhvc3Q6ICdhcGkubGlua2VkaW4uY29tJyxcbiAgICBwYXRoOiAnL3YyLycgKyBwYXRoLFxuICAgIGhlYWRlcnM6IGhlYWRlcnMsXG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZDogdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YTogdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/meetup.js b/lib/Adapters/Auth/meetup.js new file mode 100644 index 0000000000..18eb5e0b20 --- /dev/null +++ b/lib/Adapters/Auth/meetup.js @@ -0,0 +1,39 @@ +"use strict"; + +// Helper functions for accessing the meetup API. +var Parse = require('parse/node').Parse; + +const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData) { + return request('member/self', authData.access_token).then(data => { + if (data && data.id == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Meetup auth is invalid for this user.'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for api requests + + +function request(path, access_token) { + return httpsRequest.get({ + host: 'api.meetup.com', + path: '/2/' + path, + headers: { + Authorization: 'bearer ' + access_token + } + }); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL21lZXR1cC5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJyZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsImRhdGEiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJnZXQiLCJob3N0IiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFDQSxNQUFNRSxZQUFZLEdBQUdELE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNFLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsYUFBRCxFQUFnQkQsUUFBUSxDQUFDRSxZQUF6QixDQUFQLENBQThDQyxJQUE5QyxDQUFtREMsSUFBSSxJQUFJO0FBQ2hFLFFBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxFQUFMLElBQVdMLFFBQVEsQ0FBQ0ssRUFBaEMsRUFBb0M7QUFDbEM7QUFDRDs7QUFDRCxVQUFNLElBQUlULEtBQUssQ0FBQ1UsS0FBVixDQUFnQlYsS0FBSyxDQUFDVSxLQUFOLENBQVlDLGdCQUE1QixFQUE4Qyx1Q0FBOUMsQ0FBTjtBQUNELEdBTE0sQ0FBUDtBQU1ELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU1QsT0FBVCxDQUFpQlUsSUFBakIsRUFBdUJULFlBQXZCLEVBQXFDO0FBQ25DLFNBQU9KLFlBQVksQ0FBQ2MsR0FBYixDQUFpQjtBQUN0QkMsSUFBQUEsSUFBSSxFQUFFLGdCQURnQjtBQUV0QkYsSUFBQUEsSUFBSSxFQUFFLFFBQVFBLElBRlE7QUFHdEJHLElBQUFBLE9BQU8sRUFBRTtBQUNQQyxNQUFBQSxhQUFhLEVBQUUsWUFBWWI7QUFEcEI7QUFIYSxHQUFqQixDQUFQO0FBT0Q7O0FBRURjLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVCxFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlQsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIG1lZXR1cCBBUEkuXG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG4gIHJldHVybiByZXF1ZXN0KCdtZW1iZXIvc2VsZicsIGF1dGhEYXRhLmFjY2Vzc190b2tlbikudGhlbihkYXRhID0+IHtcbiAgICBpZiAoZGF0YSAmJiBkYXRhLmlkID09IGF1dGhEYXRhLmlkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnTWVldHVwIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLicpO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbi8vIEEgcHJvbWlzZXkgd3JhcHBlciBmb3IgYXBpIHJlcXVlc3RzXG5mdW5jdGlvbiByZXF1ZXN0KHBhdGgsIGFjY2Vzc190b2tlbikge1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LmdldCh7XG4gICAgaG9zdDogJ2FwaS5tZWV0dXAuY29tJyxcbiAgICBwYXRoOiAnLzIvJyArIHBhdGgsXG4gICAgaGVhZGVyczoge1xuICAgICAgQXV0aG9yaXphdGlvbjogJ2JlYXJlciAnICsgYWNjZXNzX3Rva2VuLFxuICAgIH0sXG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZDogdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YTogdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/microsoft.js b/lib/Adapters/Auth/microsoft.js new file mode 100644 index 0000000000..47a79ffe2c --- /dev/null +++ b/lib/Adapters/Auth/microsoft.js @@ -0,0 +1,39 @@ +"use strict"; + +// Helper functions for accessing the microsoft graph API. +var Parse = require('parse/node').Parse; + +const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills if this user mail is valid. + + +function validateAuthData(authData) { + return request('me', authData.access_token).then(response => { + if (response && response.id && response.id == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Microsoft Graph auth is invalid for this user.'); + }); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for api requests + + +function request(path, access_token) { + return httpsRequest.get({ + host: 'graph.microsoft.com', + path: '/v1.0/' + path, + headers: { + Authorization: 'Bearer ' + access_token + } + }); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL21pY3Jvc29mdC5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJyZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsInJlc3BvbnNlIiwiaWQiLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ2YWxpZGF0ZUFwcElkIiwiUHJvbWlzZSIsInJlc29sdmUiLCJwYXRoIiwiZ2V0IiwiaG9zdCIsImhlYWRlcnMiLCJBdXRob3JpemF0aW9uIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBbEM7O0FBQ0EsTUFBTUUsWUFBWSxHQUFHRCxPQUFPLENBQUMsZ0JBQUQsQ0FBNUIsQyxDQUVBOzs7QUFDQSxTQUFTRSxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0M7QUFDbEMsU0FBT0MsT0FBTyxDQUFDLElBQUQsRUFBT0QsUUFBUSxDQUFDRSxZQUFoQixDQUFQLENBQXFDQyxJQUFyQyxDQUEwQ0MsUUFBUSxJQUFJO0FBQzNELFFBQUlBLFFBQVEsSUFBSUEsUUFBUSxDQUFDQyxFQUFyQixJQUEyQkQsUUFBUSxDQUFDQyxFQUFULElBQWVMLFFBQVEsQ0FBQ0ssRUFBdkQsRUFBMkQ7QUFDekQ7QUFDRDs7QUFDRCxVQUFNLElBQUlULEtBQUssQ0FBQ1UsS0FBVixDQUNKVixLQUFLLENBQUNVLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSixnREFGSSxDQUFOO0FBSUQsR0FSTSxDQUFQO0FBU0QsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTVCxPQUFULENBQWlCVSxJQUFqQixFQUF1QlQsWUFBdkIsRUFBcUM7QUFDbkMsU0FBT0osWUFBWSxDQUFDYyxHQUFiLENBQWlCO0FBQ3RCQyxJQUFBQSxJQUFJLEVBQUUscUJBRGdCO0FBRXRCRixJQUFBQSxJQUFJLEVBQUUsV0FBV0EsSUFGSztBQUd0QkcsSUFBQUEsT0FBTyxFQUFFO0FBQ1BDLE1BQUFBLGFBQWEsRUFBRSxZQUFZYjtBQURwQjtBQUhhLEdBQWpCLENBQVA7QUFPRDs7QUFFRGMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZULEVBQUFBLGFBQWEsRUFBRUEsYUFEQTtBQUVmVCxFQUFBQSxnQkFBZ0IsRUFBRUE7QUFGSCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgbWljcm9zb2Z0IGdyYXBoIEFQSS5cbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyB1c2VyIG1haWwgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG4gIHJldHVybiByZXF1ZXN0KCdtZScsIGF1dGhEYXRhLmFjY2Vzc190b2tlbikudGhlbihyZXNwb25zZSA9PiB7XG4gICAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLmlkICYmIHJlc3BvbnNlLmlkID09IGF1dGhEYXRhLmlkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAnTWljcm9zb2Z0IEdyYXBoIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICApO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBhcGkgcmVxdWVzdHNcbmZ1bmN0aW9uIHJlcXVlc3QocGF0aCwgYWNjZXNzX3Rva2VuKSB7XG4gIHJldHVybiBodHRwc1JlcXVlc3QuZ2V0KHtcbiAgICBob3N0OiAnZ3JhcGgubWljcm9zb2Z0LmNvbScsXG4gICAgcGF0aDogJy92MS4wLycgKyBwYXRoLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgIEF1dGhvcml6YXRpb246ICdCZWFyZXIgJyArIGFjY2Vzc190b2tlbixcbiAgICB9LFxuICB9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQ6IHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGE6IHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/oauth2.js b/lib/Adapters/Auth/oauth2.js new file mode 100644 index 0000000000..b830be60ff --- /dev/null +++ b/lib/Adapters/Auth/oauth2.js @@ -0,0 +1,142 @@ +"use strict"; + +/* + * This auth adapter is based on the OAuth 2.0 Token Introspection specification. + * See RFC 7662 for details (https://tools.ietf.org/html/rfc7662). + * It's purpose is to validate OAuth2 access tokens using the OAuth2 provider's + * token introspection endpoint (if implemented by the provider). + * + * The adapter accepts the following config parameters: + * + * 1. "tokenIntrospectionEndpointUrl" (string, required) + * The URL of the token introspection endpoint of the OAuth2 provider that + * issued the access token to the client that is to be validated. + * + * 2. "useridField" (string, optional) + * The name of the field in the token introspection response that contains + * the userid. If specified, it will be used to verify the value of the "id" + * field in the "authData" JSON that is coming from the client. + * This can be the "aud" (i.e. audience), the "sub" (i.e. subject) or the + * "username" field in the introspection response, but since only the + * "active" field is required and all other reponse fields are optional + * in the RFC, it has to be optional in this adapter as well. + * Default: - (undefined) + * + * 3. "appidField" (string, optional) + * The name of the field in the token introspection response that contains + * the appId of the client. If specified, it will be used to verify it's + * value against the set of appIds in the adapter config. The concept of + * appIds comes from the two major social login providers + * (Google and Facebook). They have not yet implemented the token + * introspection endpoint, but the concept can be valid for any OAuth2 + * provider. + * Default: - (undefined) + * + * 4. "appIds" (array of strings, required if appidField is defined) + * A set of appIds that are used to restrict accepted access tokens based + * on a specific field's value in the token introspection response. + * Default: - (undefined) + * + * 5. "authorizationHeader" (string, optional) + * The value of the "Authorization" HTTP header in requests sent to the + * introspection endpoint. It must contain the raw value. + * Thus if HTTP Basic authorization is to be used, it must contain the + * "Basic" string, followed by whitespace, then by the base64 encoded + * version of the concatenated + ":" + string. + * Eg. "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" + * + * The adapter expects requests with the following authData JSON: + * + * { + * "someadapter": { + * "id": "user's OAuth2 provider-specific id as a string", + * "access_token": "an authorized OAuth2 access token for the user", + * } + * } + */ +const Parse = require('parse/node').Parse; + +const url = require('url'); + +const querystring = require('querystring'); + +const httpsRequest = require('./httpsRequest'); + +const INVALID_ACCESS = 'OAuth2 access token is invalid for this user.'; +const INVALID_ACCESS_APPID = "OAuth2: the access_token's appID is empty or is not in the list of permitted appIDs in the auth configuration."; +const MISSING_APPIDS = 'OAuth2 configuration is missing the client app IDs ("appIds" config parameter).'; +const MISSING_URL = 'OAuth2 token introspection endpoint URL is missing from configuration!'; // Returns a promise that fulfills if this user id is valid. + +function validateAuthData(authData, options) { + return requestTokenInfo(options, authData.access_token).then(response => { + if (!response || !response.active || options.useridField && authData.id !== response[options.useridField]) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, INVALID_ACCESS); + } + }); +} + +function validateAppId(appIds, authData, options) { + if (!options || !options.appidField) { + return Promise.resolve(); + } + + if (!appIds || appIds.length === 0) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, MISSING_APPIDS); + } + + return requestTokenInfo(options, authData.access_token).then(response => { + if (!response || !response.active) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, INVALID_ACCESS); + } + + const appidField = options.appidField; + + if (!response[appidField]) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, INVALID_ACCESS_APPID); + } + + const responseValue = response[appidField]; + + if (!Array.isArray(responseValue) && appIds.includes(responseValue)) { + return; + } else if (Array.isArray(responseValue) && responseValue.some(appId => appIds.includes(appId))) { + return; + } else { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, INVALID_ACCESS_APPID); + } + }); +} // A promise wrapper for requests to the OAuth2 token introspection endpoint. + + +function requestTokenInfo(options, access_token) { + if (!options || !options.tokenIntrospectionEndpointUrl) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, MISSING_URL); + } + + const parsedUrl = url.parse(options.tokenIntrospectionEndpointUrl); + const postData = querystring.stringify({ + token: access_token + }); + const headers = { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Content-Length': Buffer.byteLength(postData) + }; + + if (options.authorizationHeader) { + headers['Authorization'] = options.authorizationHeader; + } + + const postOptions = { + hostname: parsedUrl.hostname, + path: parsedUrl.pathname, + method: 'POST', + headers: headers + }; + return httpsRequest.request(postOptions, postData); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL29hdXRoMi5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJ1cmwiLCJxdWVyeXN0cmluZyIsImh0dHBzUmVxdWVzdCIsIklOVkFMSURfQUNDRVNTIiwiSU5WQUxJRF9BQ0NFU1NfQVBQSUQiLCJNSVNTSU5HX0FQUElEUyIsIk1JU1NJTkdfVVJMIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsInJlcXVlc3RUb2tlbkluZm8iLCJhY2Nlc3NfdG9rZW4iLCJ0aGVuIiwicmVzcG9uc2UiLCJhY3RpdmUiLCJ1c2VyaWRGaWVsZCIsImlkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsImFwcElkcyIsImFwcGlkRmllbGQiLCJQcm9taXNlIiwicmVzb2x2ZSIsImxlbmd0aCIsInJlc3BvbnNlVmFsdWUiLCJBcnJheSIsImlzQXJyYXkiLCJpbmNsdWRlcyIsInNvbWUiLCJhcHBJZCIsInRva2VuSW50cm9zcGVjdGlvbkVuZHBvaW50VXJsIiwicGFyc2VkVXJsIiwicGFyc2UiLCJwb3N0RGF0YSIsInN0cmluZ2lmeSIsInRva2VuIiwiaGVhZGVycyIsIkJ1ZmZlciIsImJ5dGVMZW5ndGgiLCJhdXRob3JpemF0aW9uSGVhZGVyIiwicG9zdE9wdGlvbnMiLCJob3N0bmFtZSIsInBhdGgiLCJwYXRobmFtZSIsIm1ldGhvZCIsInJlcXVlc3QiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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QUFxQkwsV0FBckIsRUFBa0NQLFFBQWxDLENBQVA7QUFDRDs7QUFFRGEsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2Y3QixFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlosRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogVGhpcyBhdXRoIGFkYXB0ZXIgaXMgYmFzZWQgb24gdGhlIE9BdXRoIDIuMCBUb2tlbiBJbnRyb3NwZWN0aW9uIHNwZWNpZmljYXRpb24uXG4gKiBTZWUgUkZDIDc2NjIgZm9yIGRldGFpbHMgKGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM3NjYyKS5cbiAqIEl0J3MgcHVycG9zZSBpcyB0byB2YWxpZGF0ZSBPQXV0aDIgYWNjZXNzIHRva2VucyB1c2luZyB0aGUgT0F1dGgyIHByb3ZpZGVyJ3NcbiAqIHRva2VuIGludHJvc3BlY3Rpb24gZW5kcG9pbnQgKGlmIGltcGxlbWVudGVkIGJ5IHRoZSBwcm92aWRlcikuXG4gKlxuICogVGhlIGFkYXB0ZXIgYWNjZXB0cyB0aGUgZm9sbG93aW5nIGNvbmZpZyBwYXJhbWV0ZXJzOlxuICpcbiAqIDEuIFwidG9rZW5JbnRyb3NwZWN0aW9uRW5kcG9pbnRVcmxcIiAoc3RyaW5nLCByZXF1aXJlZClcbiAqICAgICAgVGhlIFVSTCBvZiB0aGUgdG9rZW4gaW50cm9zcGVjdGlvbiBlbmRwb2ludCBvZiB0aGUgT0F1dGgyIHByb3ZpZGVyIHRoYXRcbiAqICAgICAgaXNzdWVkIHRoZSBhY2Nlc3MgdG9rZW4gdG8gdGhlIGNsaWVudCB0aGF0IGlzIHRvIGJlIHZhbGlkYXRlZC5cbiAqXG4gKiAyLiBcInVzZXJpZEZpZWxkXCIgKHN0cmluZywgb3B0aW9uYWwpXG4gKiAgICAgIFRoZSBuYW1lIG9mIHRoZSBmaWVsZCBpbiB0aGUgdG9rZW4gaW50cm9zcGVjdGlvbiByZXNwb25zZSB0aGF0IGNvbnRhaW5zXG4gKiAgICAgIHRoZSB1c2VyaWQuIElmIHNwZWNpZmllZCwgaXQgd2lsbCBiZSB1c2VkIHRvIHZlcmlmeSB0aGUgdmFsdWUgb2YgdGhlIFwiaWRcIlxuICogICAgICBmaWVsZCBpbiB0aGUgXCJhdXRoRGF0YVwiIEpTT04gdGhhdCBpcyBjb21pbmcgZnJvbSB0aGUgY2xpZW50LlxuICogICAgICBUaGlzIGNhbiBiZSB0aGUgXCJhdWRcIiAoaS5lLiBhdWRpZW5jZSksIHRoZSBcInN1YlwiIChpLmUuIHN1YmplY3QpIG9yIHRoZVxuICogICAgICBcInVzZXJuYW1lXCIgZmllbGQgaW4gdGhlIGludHJvc3BlY3Rpb24gcmVzcG9uc2UsIGJ1dCBzaW5jZSBvbmx5IHRoZVxuICogICAgICBcImFjdGl2ZVwiIGZpZWxkIGlzIHJlcXVpcmVkIGFuZCBhbGwgb3RoZXIgcmVwb25zZSBmaWVsZHMgYXJlIG9wdGlvbmFsXG4gKiAgICAgIGluIHRoZSBSRkMsIGl0IGhhcyB0byBiZSBvcHRpb25hbCBpbiB0aGlzIGFkYXB0ZXIgYXMgd2VsbC5cbiAqICAgICAgRGVmYXVsdDogLSAodW5kZWZpbmVkKVxuICpcbiAqIDMuIFwiYXBwaWRGaWVsZFwiIChzdHJpbmcsIG9wdGlvbmFsKVxuICogICAgICBUaGUgbmFtZSBvZiB0aGUgZmllbGQgaW4gdGhlIHRva2VuIGludHJvc3BlY3Rpb24gcmVzcG9uc2UgdGhhdCBjb250YWluc1xuICogICAgICB0aGUgYXBwSWQgb2YgdGhlIGNsaWVudC4gSWYgc3BlY2lmaWVkLCBpdCB3aWxsIGJlIHVzZWQgdG8gdmVyaWZ5IGl0J3NcbiAqICAgICAgdmFsdWUgYWdhaW5zdCB0aGUgc2V0IG9mIGFwcElkcyBpbiB0aGUgYWRhcHRlciBjb25maWcuIFRoZSBjb25jZXB0IG9mXG4gKiAgICAgIGFwcElkcyBjb21lcyBmcm9tIHRoZSB0d28gbWFqb3Igc29jaWFsIGxvZ2luIHByb3ZpZGVyc1xuICogICAgICAoR29vZ2xlIGFuZCBGYWNlYm9vaykuIFRoZXkgaGF2ZSBub3QgeWV0IGltcGxlbWVudGVkIHRoZSB0b2tlblxuICogICAgICBpbnRyb3NwZWN0aW9uIGVuZHBvaW50LCBidXQgdGhlIGNvbmNlcHQgY2FuIGJlIHZhbGlkIGZvciBhbnkgT0F1dGgyXG4gKiAgICAgIHByb3ZpZGVyLlxuICogICAgICBEZWZhdWx0OiAtICh1bmRlZmluZWQpXG4gKlxuICogNC4gXCJhcHBJZHNcIiAoYXJyYXkgb2Ygc3RyaW5ncywgcmVxdWlyZWQgaWYgYXBwaWRGaWVsZCBpcyBkZWZpbmVkKVxuICogICAgICBBIHNldCBvZiBhcHBJZHMgdGhhdCBhcmUgdXNlZCB0byByZXN0cmljdCBhY2NlcHRlZCBhY2Nlc3MgdG9rZW5zIGJhc2VkXG4gKiAgICAgIG9uIGEgc3BlY2lmaWMgZmllbGQncyB2YWx1ZSBpbiB0aGUgdG9rZW4gaW50cm9zcGVjdGlvbiByZXNwb25zZS5cbiAqICAgICAgRGVmYXVsdDogLSAodW5kZWZpbmVkKVxuICpcbiAqIDUuIFwiYXV0aG9yaXphdGlvbkhlYWRlclwiIChzdHJpbmcsIG9wdGlvbmFsKVxuICogICAgICBUaGUgdmFsdWUgb2YgdGhlIFwiQXV0aG9yaXphdGlvblwiIEhUVFAgaGVhZGVyIGluIHJlcXVlc3RzIHNlbnQgdG8gdGhlXG4gKiAgICAgIGludHJvc3BlY3Rpb24gZW5kcG9pbnQuIEl0IG11c3QgY29udGFpbiB0aGUgcmF3IHZhbHVlLlxuICogICAgICBUaHVzIGlmIEhUVFAgQmFzaWMgYXV0aG9yaXphdGlvbiBpcyB0byBiZSB1c2VkLCBpdCBtdXN0IGNvbnRhaW4gdGhlXG4gKiAgICAgIFwiQmFzaWNcIiBzdHJpbmcsIGZvbGxvd2VkIGJ5IHdoaXRlc3BhY2UsIHRoZW4gYnkgdGhlIGJhc2U2NCBlbmNvZGVkXG4gKiAgICAgIHZlcnNpb24gb2YgdGhlIGNvbmNhdGVuYXRlZCA8dXNlcm5hbWU+ICsgXCI6XCIgKyA8cGFzc3dvcmQ+IHN0cmluZy5cbiAqICAgICAgRWcuIFwiQmFzaWMgZFhObGNtNWhiV1U2Y0dGemMzZHZjbVE9XCJcbiAqXG4gKiBUaGUgYWRhcHRlciBleHBlY3RzIHJlcXVlc3RzIHdpdGggdGhlIGZvbGxvd2luZyBhdXRoRGF0YSBKU09OOlxuICpcbiAqIHtcbiAqICAgXCJzb21lYWRhcHRlclwiOiB7XG4gKiAgICAgXCJpZFwiOiBcInVzZXIncyBPQXV0aDIgcHJvdmlkZXItc3BlY2lmaWMgaWQgYXMgYSBzdHJpbmdcIixcbiAqICAgICBcImFjY2Vzc190b2tlblwiOiBcImFuIGF1dGhvcml6ZWQgT0F1dGgyIGFjY2VzcyB0b2tlbiBmb3IgdGhlIHVzZXJcIixcbiAqICAgfVxuICogfVxuICovXG5cbmNvbnN0IFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuY29uc3QgdXJsID0gcmVxdWlyZSgndXJsJyk7XG5jb25zdCBxdWVyeXN0cmluZyA9IHJlcXVpcmUoJ3F1ZXJ5c3RyaW5nJyk7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG5jb25zdCBJTlZBTElEX0FDQ0VTUyA9ICdPQXV0aDIgYWNjZXNzIHRva2VuIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nO1xuY29uc3QgSU5WQUxJRF9BQ0NFU1NfQVBQSUQgPVxuICBcIk9BdXRoMjogdGhlIGFjY2Vzc190b2tlbidzIGFwcElEIGlzIGVtcHR5IG9yIGlzIG5vdCBpbiB0aGUgbGlzdCBvZiBwZXJtaXR0ZWQgYXBwSURzIGluIHRoZSBhdXRoIGNvbmZpZ3VyYXRpb24uXCI7XG5jb25zdCBNSVNTSU5HX0FQUElEUyA9XG4gICdPQXV0aDIgY29uZmlndXJhdGlvbiBpcyBtaXNzaW5nIHRoZSBjbGllbnQgYXBwIElEcyAoXCJhcHBJZHNcIiBjb25maWcgcGFyYW1ldGVyKS4nO1xuY29uc3QgTUlTU0lOR19VUkwgPSAnT0F1dGgyIHRva2VuIGludHJvc3BlY3Rpb24gZW5kcG9pbnQgVVJMIGlzIG1pc3NpbmcgZnJvbSBjb25maWd1cmF0aW9uISc7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyB1c2VyIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSwgb3B0aW9ucykge1xuICByZXR1cm4gcmVxdWVzdFRva2VuSW5mbyhvcHRpb25zLCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgIGlmIChcbiAgICAgICFyZXNwb25zZSB8fFxuICAgICAgIXJlc3BvbnNlLmFjdGl2ZSB8fFxuICAgICAgKG9wdGlvbnMudXNlcmlkRmllbGQgJiYgYXV0aERhdGEuaWQgIT09IHJlc3BvbnNlW29wdGlvbnMudXNlcmlkRmllbGRdKVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsIElOVkFMSURfQUNDRVNTKTtcbiAgICB9XG4gIH0pO1xufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKGFwcElkcywgYXV0aERhdGEsIG9wdGlvbnMpIHtcbiAgaWYgKCFvcHRpb25zIHx8ICFvcHRpb25zLmFwcGlkRmllbGQpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbiAgaWYgKCFhcHBJZHMgfHwgYXBwSWRzLmxlbmd0aCA9PT0gMCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBNSVNTSU5HX0FQUElEUyk7XG4gIH1cbiAgcmV0dXJuIHJlcXVlc3RUb2tlbkluZm8ob3B0aW9ucywgYXV0aERhdGEuYWNjZXNzX3Rva2VuKS50aGVuKHJlc3BvbnNlID0+IHtcbiAgICBpZiAoIXJlc3BvbnNlIHx8ICFyZXNwb25zZS5hY3RpdmUpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBJTlZBTElEX0FDQ0VTUyk7XG4gICAgfVxuICAgIGNvbnN0IGFwcGlkRmllbGQgPSBvcHRpb25zLmFwcGlkRmllbGQ7XG4gICAgaWYgKCFyZXNwb25zZVthcHBpZEZpZWxkXSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsIElOVkFMSURfQUNDRVNTX0FQUElEKTtcbiAgICB9XG4gICAgY29uc3QgcmVzcG9uc2VWYWx1ZSA9IHJlc3BvbnNlW2FwcGlkRmllbGRdO1xuICAgIGlmICghQXJyYXkuaXNBcnJheShyZXNwb25zZVZhbHVlKSAmJiBhcHBJZHMuaW5jbHVkZXMocmVzcG9uc2VWYWx1ZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgQXJyYXkuaXNBcnJheShyZXNwb25zZVZhbHVlKSAmJlxuICAgICAgcmVzcG9uc2VWYWx1ZS5zb21lKGFwcElkID0+IGFwcElkcy5pbmNsdWRlcyhhcHBJZCkpXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBJTlZBTElEX0FDQ0VTU19BUFBJRCk7XG4gICAgfVxuICB9KTtcbn1cblxuLy8gQSBwcm9taXNlIHdyYXBwZXIgZm9yIHJlcXVlc3RzIHRvIHRoZSBPQXV0aDIgdG9rZW4gaW50cm9zcGVjdGlvbiBlbmRwb2ludC5cbmZ1bmN0aW9uIHJlcXVlc3RUb2tlbkluZm8ob3B0aW9ucywgYWNjZXNzX3Rva2VuKSB7XG4gIGlmICghb3B0aW9ucyB8fCAhb3B0aW9ucy50b2tlbkludHJvc3BlY3Rpb25FbmRwb2ludFVybCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBNSVNTSU5HX1VSTCk7XG4gIH1cbiAgY29uc3QgcGFyc2VkVXJsID0gdXJsLnBhcnNlKG9wdGlvbnMudG9rZW5JbnRyb3NwZWN0aW9uRW5kcG9pbnRVcmwpO1xuICBjb25zdCBwb3N0RGF0YSA9IHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeSh7XG4gICAgdG9rZW46IGFjY2Vzc190b2tlbixcbiAgfSk7XG4gIGNvbnN0IGhlYWRlcnMgPSB7XG4gICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAgICdDb250ZW50LUxlbmd0aCc6IEJ1ZmZlci5ieXRlTGVuZ3RoKHBvc3REYXRhKSxcbiAgfTtcbiAgaWYgKG9wdGlvbnMuYXV0aG9yaXphdGlvbkhlYWRlcikge1xuICAgIGhlYWRlcnNbJ0F1dGhvcml6YXRpb24nXSA9IG9wdGlvbnMuYXV0aG9yaXphdGlvbkhlYWRlcjtcbiAgfVxuICBjb25zdCBwb3N0T3B0aW9ucyA9IHtcbiAgICBob3N0bmFtZTogcGFyc2VkVXJsLmhvc3RuYW1lLFxuICAgIHBhdGg6IHBhcnNlZFVybC5wYXRobmFtZSxcbiAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICBoZWFkZXJzOiBoZWFkZXJzLFxuICB9O1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LnJlcXVlc3QocG9zdE9wdGlvbnMsIHBvc3REYXRhKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQ6IHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGE6IHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/phantauth.js b/lib/Adapters/Auth/phantauth.js new file mode 100644 index 0000000000..5c8774bbd7 --- /dev/null +++ b/lib/Adapters/Auth/phantauth.js @@ -0,0 +1,47 @@ +"use strict"; + +/* + * PhantAuth was designed to simplify testing for applications using OpenID Connect + * authentication by making use of random generated users. + * + * To learn more, please go to: https://www.phantauth.net + */ +const { + Parse +} = require('parse/node'); + +const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills if this user id is valid. + + +function validateAuthData(authData) { + return request('auth/userinfo', authData.access_token).then(data => { + if (data && data.sub == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'PhantAuth auth is invalid for this user.'); + }); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for api requests + + +function request(path, access_token) { + return httpsRequest.get({ + host: 'phantauth.net', + path: '/' + path, + headers: { + Authorization: 'bearer ' + access_token, + 'User-Agent': 'parse-server' + } + }); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3BoYW50YXV0aC5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJyZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsImRhdGEiLCJzdWIiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJnZXQiLCJob3N0IiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBLE1BQU07QUFBRUEsRUFBQUE7QUFBRixJQUFZQyxPQUFPLENBQUMsWUFBRCxDQUF6Qjs7QUFDQSxNQUFNQyxZQUFZLEdBQUdELE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNFLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsZUFBRCxFQUFrQkQsUUFBUSxDQUFDRSxZQUEzQixDQUFQLENBQWdEQyxJQUFoRCxDQUFxREMsSUFBSSxJQUFJO0FBQ2xFLFFBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxHQUFMLElBQVlMLFFBQVEsQ0FBQ00sRUFBakMsRUFBcUM7QUFDbkM7QUFDRDs7QUFDRCxVQUFNLElBQUlWLEtBQUssQ0FBQ1csS0FBVixDQUFnQlgsS0FBSyxDQUFDVyxLQUFOLENBQVlDLGdCQUE1QixFQUE4QywwQ0FBOUMsQ0FBTjtBQUNELEdBTE0sQ0FBUDtBQU1ELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU1YsT0FBVCxDQUFpQlcsSUFBakIsRUFBdUJWLFlBQXZCLEVBQXFDO0FBQ25DLFNBQU9KLFlBQVksQ0FBQ2UsR0FBYixDQUFpQjtBQUN0QkMsSUFBQUEsSUFBSSxFQUFFLGVBRGdCO0FBRXRCRixJQUFBQSxJQUFJLEVBQUUsTUFBTUEsSUFGVTtBQUd0QkcsSUFBQUEsT0FBTyxFQUFFO0FBQ1BDLE1BQUFBLGFBQWEsRUFBRSxZQUFZZCxZQURwQjtBQUVQLG9CQUFjO0FBRlA7QUFIYSxHQUFqQixDQUFQO0FBUUQ7O0FBRURlLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVCxFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlYsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogUGhhbnRBdXRoIHdhcyBkZXNpZ25lZCB0byBzaW1wbGlmeSB0ZXN0aW5nIGZvciBhcHBsaWNhdGlvbnMgdXNpbmcgT3BlbklEIENvbm5lY3RcbiAqIGF1dGhlbnRpY2F0aW9uIGJ5IG1ha2luZyB1c2Ugb2YgcmFuZG9tIGdlbmVyYXRlZCB1c2Vycy5cbiAqXG4gKiBUbyBsZWFybiBtb3JlLCBwbGVhc2UgZ28gdG86IGh0dHBzOi8vd3d3LnBoYW50YXV0aC5uZXRcbiAqL1xuXG5jb25zdCB7IFBhcnNlIH0gPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIHJlcXVlc3QoJ2F1dGgvdXNlcmluZm8nLCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oZGF0YSA9PiB7XG4gICAgaWYgKGRhdGEgJiYgZGF0YS5zdWIgPT0gYXV0aERhdGEuaWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdQaGFudEF1dGggYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIGFwaSByZXF1ZXN0c1xuZnVuY3Rpb24gcmVxdWVzdChwYXRoLCBhY2Nlc3NfdG9rZW4pIHtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoe1xuICAgIGhvc3Q6ICdwaGFudGF1dGgubmV0JyxcbiAgICBwYXRoOiAnLycgKyBwYXRoLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgIEF1dGhvcml6YXRpb246ICdiZWFyZXIgJyArIGFjY2Vzc190b2tlbixcbiAgICAgICdVc2VyLUFnZW50JzogJ3BhcnNlLXNlcnZlcicsXG4gICAgfSxcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/qq.js b/lib/Adapters/Auth/qq.js new file mode 100644 index 0000000000..9191ef36da --- /dev/null +++ b/lib/Adapters/Auth/qq.js @@ -0,0 +1,48 @@ +"use strict"; + +// Helper functions for accessing the qq Graph API. +const httpsRequest = require('./httpsRequest'); + +var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData) { + return graphRequest('me?access_token=' + authData.access_token).then(function (data) { + if (data && data.openid == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'qq auth is invalid for this user.'); + }); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for qq graph requests. + + +function graphRequest(path) { + return httpsRequest.get('https://graph.qq.com/oauth2.0/' + path, true).then(data => { + return parseResponseData(data); + }); +} + +function parseResponseData(data) { + const starPos = data.indexOf('('); + const endPos = data.indexOf(')'); + + if (starPos == -1 || endPos == -1) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'qq auth is invalid for this user.'); + } + + data = data.substring(starPos + 1, endPos - 1); + return JSON.parse(data); +} + +module.exports = { + validateAppId, + validateAuthData, + parseResponseData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3FxLmpzIl0sIm5hbWVzIjpbImh0dHBzUmVxdWVzdCIsInJlcXVpcmUiLCJQYXJzZSIsInZhbGlkYXRlQXV0aERhdGEiLCJhdXRoRGF0YSIsImdyYXBoUmVxdWVzdCIsImFjY2Vzc190b2tlbiIsInRoZW4iLCJkYXRhIiwib3BlbmlkIiwiaWQiLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ2YWxpZGF0ZUFwcElkIiwiUHJvbWlzZSIsInJlc29sdmUiLCJwYXRoIiwiZ2V0IiwicGFyc2VSZXNwb25zZURhdGEiLCJzdGFyUG9zIiwiaW5kZXhPZiIsImVuZFBvcyIsInN1YnN0cmluZyIsIkpTT04iLCJwYXJzZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQSxNQUFNQSxZQUFZLEdBQUdDLE9BQU8sQ0FBQyxnQkFBRCxDQUE1Qjs7QUFDQSxJQUFJQyxLQUFLLEdBQUdELE9BQU8sQ0FBQyxZQUFELENBQVAsQ0FBc0JDLEtBQWxDLEMsQ0FFQTs7O0FBQ0EsU0FBU0MsZ0JBQVQsQ0FBMEJDLFFBQTFCLEVBQW9DO0FBQ2xDLFNBQU9DLFlBQVksQ0FBQyxxQkFBcUJELFFBQVEsQ0FBQ0UsWUFBL0IsQ0FBWixDQUF5REMsSUFBekQsQ0FBOEQsVUFBVUMsSUFBVixFQUFnQjtBQUNuRixRQUFJQSxJQUFJLElBQUlBLElBQUksQ0FBQ0MsTUFBTCxJQUFlTCxRQUFRLENBQUNNLEVBQXBDLEVBQXdDO0FBQ3RDO0FBQ0Q7O0FBQ0QsVUFBTSxJQUFJUixLQUFLLENBQUNTLEtBQVYsQ0FBZ0JULEtBQUssQ0FBQ1MsS0FBTixDQUFZQyxnQkFBNUIsRUFBOEMsbUNBQTlDLENBQU47QUFDRCxHQUxNLENBQVA7QUFNRCxDLENBRUQ7OztBQUNBLFNBQVNDLGFBQVQsR0FBeUI7QUFDdkIsU0FBT0MsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNWLFlBQVQsQ0FBc0JXLElBQXRCLEVBQTRCO0FBQzFCLFNBQU9oQixZQUFZLENBQUNpQixHQUFiLENBQWlCLG1DQUFtQ0QsSUFBcEQsRUFBMEQsSUFBMUQsRUFBZ0VULElBQWhFLENBQXFFQyxJQUFJLElBQUk7QUFDbEYsV0FBT1UsaUJBQWlCLENBQUNWLElBQUQsQ0FBeEI7QUFDRCxHQUZNLENBQVA7QUFHRDs7QUFFRCxTQUFTVSxpQkFBVCxDQUEyQlYsSUFBM0IsRUFBaUM7QUFDL0IsUUFBTVcsT0FBTyxHQUFHWCxJQUFJLENBQUNZLE9BQUwsQ0FBYSxHQUFiLENBQWhCO0FBQ0EsUUFBTUMsTUFBTSxHQUFHYixJQUFJLENBQUNZLE9BQUwsQ0FBYSxHQUFiLENBQWY7O0FBQ0EsTUFBSUQsT0FBTyxJQUFJLENBQUMsQ0FBWixJQUFpQkUsTUFBTSxJQUFJLENBQUMsQ0FBaEMsRUFBbUM7QUFDakMsVUFBTSxJQUFJbkIsS0FBSyxDQUFDUyxLQUFWLENBQWdCVCxLQUFLLENBQUNTLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLG1DQUE5QyxDQUFOO0FBQ0Q7O0FBQ0RKLEVBQUFBLElBQUksR0FBR0EsSUFBSSxDQUFDYyxTQUFMLENBQWVILE9BQU8sR0FBRyxDQUF6QixFQUE0QkUsTUFBTSxHQUFHLENBQXJDLENBQVA7QUFDQSxTQUFPRSxJQUFJLENBQUNDLEtBQUwsQ0FBV2hCLElBQVgsQ0FBUDtBQUNEOztBQUVEaUIsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZiLEVBQUFBLGFBRGU7QUFFZlYsRUFBQUEsZ0JBRmU7QUFHZmUsRUFBQUE7QUFIZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgcXEgR3JhcGggQVBJLlxuY29uc3QgaHR0cHNSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwc1JlcXVlc3QnKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyB1c2VyIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSkge1xuICByZXR1cm4gZ3JhcGhSZXF1ZXN0KCdtZT9hY2Nlc3NfdG9rZW49JyArIGF1dGhEYXRhLmFjY2Vzc190b2tlbikudGhlbihmdW5jdGlvbiAoZGF0YSkge1xuICAgIGlmIChkYXRhICYmIGRhdGEub3BlbmlkID09IGF1dGhEYXRhLmlkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAncXEgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIHFxIGdyYXBoIHJlcXVlc3RzLlxuZnVuY3Rpb24gZ3JhcGhSZXF1ZXN0KHBhdGgpIHtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoJ2h0dHBzOi8vZ3JhcGgucXEuY29tL29hdXRoMi4wLycgKyBwYXRoLCB0cnVlKS50aGVuKGRhdGEgPT4ge1xuICAgIHJldHVybiBwYXJzZVJlc3BvbnNlRGF0YShkYXRhKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlUmVzcG9uc2VEYXRhKGRhdGEpIHtcbiAgY29uc3Qgc3RhclBvcyA9IGRhdGEuaW5kZXhPZignKCcpO1xuICBjb25zdCBlbmRQb3MgPSBkYXRhLmluZGV4T2YoJyknKTtcbiAgaWYgKHN0YXJQb3MgPT0gLTEgfHwgZW5kUG9zID09IC0xKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdxcSBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nKTtcbiAgfVxuICBkYXRhID0gZGF0YS5zdWJzdHJpbmcoc3RhclBvcyArIDEsIGVuZFBvcyAtIDEpO1xuICByZXR1cm4gSlNPTi5wYXJzZShkYXRhKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGEsXG4gIHBhcnNlUmVzcG9uc2VEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/spotify.js b/lib/Adapters/Auth/spotify.js new file mode 100644 index 0000000000..154d3ad6d6 --- /dev/null +++ b/lib/Adapters/Auth/spotify.js @@ -0,0 +1,51 @@ +"use strict"; + +// Helper functions for accessing the Spotify API. +const httpsRequest = require('./httpsRequest'); + +var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData) { + return request('me', authData.access_token).then(data => { + if (data && data.id == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify auth is invalid for this user.'); + }); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId(appIds, authData) { + var access_token = authData.access_token; + + if (!appIds.length) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify auth is not configured.'); + } + + return request('me', access_token).then(data => { + if (data && appIds.indexOf(data.id) != -1) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify auth is invalid for this user.'); + }); +} // A promisey wrapper for Spotify API requests. + + +function request(path, access_token) { + return httpsRequest.get({ + host: 'api.spotify.com', + path: '/v1/' + path, + headers: { + Authorization: 'Bearer ' + access_token + } + }); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3Nwb3RpZnkuanMiXSwibmFtZXMiOlsiaHR0cHNSZXF1ZXN0IiwicmVxdWlyZSIsIlBhcnNlIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwicmVxdWVzdCIsImFjY2Vzc190b2tlbiIsInRoZW4iLCJkYXRhIiwiaWQiLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ2YWxpZGF0ZUFwcElkIiwiYXBwSWRzIiwibGVuZ3RoIiwiaW5kZXhPZiIsInBhdGgiLCJnZXQiLCJob3N0IiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsTUFBTUEsWUFBWSxHQUFHQyxPQUFPLENBQUMsZ0JBQUQsQ0FBNUI7O0FBQ0EsSUFBSUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCQyxLQUFsQyxDLENBRUE7OztBQUNBLFNBQVNDLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsSUFBRCxFQUFPRCxRQUFRLENBQUNFLFlBQWhCLENBQVAsQ0FBcUNDLElBQXJDLENBQTBDQyxJQUFJLElBQUk7QUFDdkQsUUFBSUEsSUFBSSxJQUFJQSxJQUFJLENBQUNDLEVBQUwsSUFBV0wsUUFBUSxDQUFDSyxFQUFoQyxFQUFvQztBQUNsQztBQUNEOztBQUNELFVBQU0sSUFBSVAsS0FBSyxDQUFDUSxLQUFWLENBQWdCUixLQUFLLENBQUNRLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLHdDQUE5QyxDQUFOO0FBQ0QsR0FMTSxDQUFQO0FBTUQsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULENBQXVCQyxNQUF2QixFQUErQlQsUUFBL0IsRUFBeUM7QUFDdkMsTUFBSUUsWUFBWSxHQUFHRixRQUFRLENBQUNFLFlBQTVCOztBQUNBLE1BQUksQ0FBQ08sTUFBTSxDQUFDQyxNQUFaLEVBQW9CO0FBQ2xCLFVBQU0sSUFBSVosS0FBSyxDQUFDUSxLQUFWLENBQWdCUixLQUFLLENBQUNRLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLGlDQUE5QyxDQUFOO0FBQ0Q7O0FBQ0QsU0FBT04sT0FBTyxDQUFDLElBQUQsRUFBT0MsWUFBUCxDQUFQLENBQTRCQyxJQUE1QixDQUFpQ0MsSUFBSSxJQUFJO0FBQzlDLFFBQUlBLElBQUksSUFBSUssTUFBTSxDQUFDRSxPQUFQLENBQWVQLElBQUksQ0FBQ0MsRUFBcEIsS0FBMkIsQ0FBQyxDQUF4QyxFQUEyQztBQUN6QztBQUNEOztBQUNELFVBQU0sSUFBSVAsS0FBSyxDQUFDUSxLQUFWLENBQWdCUixLQUFLLENBQUNRLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLHdDQUE5QyxDQUFOO0FBQ0QsR0FMTSxDQUFQO0FBTUQsQyxDQUVEOzs7QUFDQSxTQUFTTixPQUFULENBQWlCVyxJQUFqQixFQUF1QlYsWUFBdkIsRUFBcUM7QUFDbkMsU0FBT04sWUFBWSxDQUFDaUIsR0FBYixDQUFpQjtBQUN0QkMsSUFBQUEsSUFBSSxFQUFFLGlCQURnQjtBQUV0QkYsSUFBQUEsSUFBSSxFQUFFLFNBQVNBLElBRk87QUFHdEJHLElBQUFBLE9BQU8sRUFBRTtBQUNQQyxNQUFBQSxhQUFhLEVBQUUsWUFBWWQ7QUFEcEI7QUFIYSxHQUFqQixDQUFQO0FBT0Q7O0FBRURlLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVixFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlQsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIFNwb3RpZnkgQVBJLlxuY29uc3QgaHR0cHNSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwc1JlcXVlc3QnKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyB1c2VyIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSkge1xuICByZXR1cm4gcmVxdWVzdCgnbWUnLCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oZGF0YSA9PiB7XG4gICAgaWYgKGRhdGEgJiYgZGF0YS5pZCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ1Nwb3RpZnkgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZChhcHBJZHMsIGF1dGhEYXRhKSB7XG4gIHZhciBhY2Nlc3NfdG9rZW4gPSBhdXRoRGF0YS5hY2Nlc3NfdG9rZW47XG4gIGlmICghYXBwSWRzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnU3BvdGlmeSBhdXRoIGlzIG5vdCBjb25maWd1cmVkLicpO1xuICB9XG4gIHJldHVybiByZXF1ZXN0KCdtZScsIGFjY2Vzc190b2tlbikudGhlbihkYXRhID0+IHtcbiAgICBpZiAoZGF0YSAmJiBhcHBJZHMuaW5kZXhPZihkYXRhLmlkKSAhPSAtMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ1Nwb3RpZnkgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gIH0pO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIFNwb3RpZnkgQVBJIHJlcXVlc3RzLlxuZnVuY3Rpb24gcmVxdWVzdChwYXRoLCBhY2Nlc3NfdG9rZW4pIHtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoe1xuICAgIGhvc3Q6ICdhcGkuc3BvdGlmeS5jb20nLFxuICAgIHBhdGg6ICcvdjEvJyArIHBhdGgsXG4gICAgaGVhZGVyczoge1xuICAgICAgQXV0aG9yaXphdGlvbjogJ0JlYXJlciAnICsgYWNjZXNzX3Rva2VuLFxuICAgIH0sXG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZDogdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YTogdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/twitter.js b/lib/Adapters/Auth/twitter.js new file mode 100644 index 0000000000..ce9cd4666b --- /dev/null +++ b/lib/Adapters/Auth/twitter.js @@ -0,0 +1,60 @@ +"use strict"; + +// Helper functions for accessing the twitter API. +var OAuth = require('./OAuth1Client'); + +var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData, options) { + if (!options) { + throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Twitter auth configuration missing'); + } + + options = handleMultipleConfigurations(authData, options); + var client = new OAuth(options); + client.host = 'api.twitter.com'; + client.auth_token = authData.auth_token; + client.auth_token_secret = authData.auth_token_secret; + return client.get('/1.1/account/verify_credentials.json').then(data => { + if (data && data.id_str == '' + authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} + +function handleMultipleConfigurations(authData, options) { + if (Array.isArray(options)) { + const consumer_key = authData.consumer_key; + + if (!consumer_key) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.'); + } + + options = options.filter(option => { + return option.consumer_key == consumer_key; + }); + + if (options.length == 0) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.'); + } + + options = options[0]; + } + + return options; +} + +module.exports = { + validateAppId, + validateAuthData, + handleMultipleConfigurations +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3R3aXR0ZXIuanMiXSwibmFtZXMiOlsiT0F1dGgiLCJyZXF1aXJlIiwiUGFyc2UiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJvcHRpb25zIiwiRXJyb3IiLCJJTlRFUk5BTF9TRVJWRVJfRVJST1IiLCJoYW5kbGVNdWx0aXBsZUNvbmZpZ3VyYXRpb25zIiwiY2xpZW50IiwiaG9zdCIsImF1dGhfdG9rZW4iLCJhdXRoX3Rva2VuX3NlY3JldCIsImdldCIsInRoZW4iLCJkYXRhIiwiaWRfc3RyIiwiaWQiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsIlByb21pc2UiLCJyZXNvbHZlIiwiQXJyYXkiLCJpc0FycmF5IiwiY29uc3VtZXJfa2V5IiwiZmlsdGVyIiwib3B0aW9uIiwibGVuZ3RoIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLGdCQUFELENBQW5COztBQUNBLElBQUlDLEtBQUssR0FBR0QsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkMsS0FBbEMsQyxDQUVBOzs7QUFDQSxTQUFTQyxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0NDLE9BQXBDLEVBQTZDO0FBQzNDLE1BQUksQ0FBQ0EsT0FBTCxFQUFjO0FBQ1osVUFBTSxJQUFJSCxLQUFLLENBQUNJLEtBQVYsQ0FBZ0JKLEtBQUssQ0FBQ0ksS0FBTixDQUFZQyxxQkFBNUIsRUFBbUQsb0NBQW5ELENBQU47QUFDRDs7QUFDREYsRUFBQUEsT0FBTyxHQUFHRyw0QkFBNEIsQ0FBQ0osUUFBRCxFQUFXQyxPQUFYLENBQXRDO0FBQ0EsTUFBSUksTUFBTSxHQUFHLElBQUlULEtBQUosQ0FBVUssT0FBVixDQUFiO0FBQ0FJLEVBQUFBLE1BQU0sQ0FBQ0MsSUFBUCxHQUFjLGlCQUFkO0FBQ0FELEVBQUFBLE1BQU0sQ0FBQ0UsVUFBUCxHQUFvQlAsUUFBUSxDQUFDTyxVQUE3QjtBQUNBRixFQUFBQSxNQUFNLENBQUNHLGlCQUFQLEdBQTJCUixRQUFRLENBQUNRLGlCQUFwQztBQUVBLFNBQU9ILE1BQU0sQ0FBQ0ksR0FBUCxDQUFXLHNDQUFYLEVBQW1EQyxJQUFuRCxDQUF3REMsSUFBSSxJQUFJO0FBQ3JFLFFBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxNQUFMLElBQWUsS0FBS1osUUFBUSxDQUFDYSxFQUF6QyxFQUE2QztBQUMzQztBQUNEOztBQUNELFVBQU0sSUFBSWYsS0FBSyxDQUFDSSxLQUFWLENBQWdCSixLQUFLLENBQUNJLEtBQU4sQ0FBWVksZ0JBQTVCLEVBQThDLHdDQUE5QyxDQUFOO0FBQ0QsR0FMTSxDQUFQO0FBTUQsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0Q7O0FBRUQsU0FBU2IsNEJBQVQsQ0FBc0NKLFFBQXRDLEVBQWdEQyxPQUFoRCxFQUF5RDtBQUN2RCxNQUFJaUIsS0FBSyxDQUFDQyxPQUFOLENBQWNsQixPQUFkLENBQUosRUFBNEI7QUFDMUIsVUFBTW1CLFlBQVksR0FBR3BCLFFBQVEsQ0FBQ29CLFlBQTlCOztBQUNBLFFBQUksQ0FBQ0EsWUFBTCxFQUFtQjtBQUNqQixZQUFNLElBQUl0QixLQUFLLENBQUNJLEtBQVYsQ0FBZ0JKLEtBQUssQ0FBQ0ksS0FBTixDQUFZWSxnQkFBNUIsRUFBOEMsd0NBQTlDLENBQU47QUFDRDs7QUFDRGIsSUFBQUEsT0FBTyxHQUFHQSxPQUFPLENBQUNvQixNQUFSLENBQWVDLE1BQU0sSUFBSTtBQUNqQyxhQUFPQSxNQUFNLENBQUNGLFlBQVAsSUFBdUJBLFlBQTlCO0FBQ0QsS0FGUyxDQUFWOztBQUlBLFFBQUluQixPQUFPLENBQUNzQixNQUFSLElBQWtCLENBQXRCLEVBQXlCO0FBQ3ZCLFlBQU0sSUFBSXpCLEtBQUssQ0FBQ0ksS0FBVixDQUFnQkosS0FBSyxDQUFDSSxLQUFOLENBQVlZLGdCQUE1QixFQUE4Qyx3Q0FBOUMsQ0FBTjtBQUNEOztBQUNEYixJQUFBQSxPQUFPLEdBQUdBLE9BQU8sQ0FBQyxDQUFELENBQWpCO0FBQ0Q7O0FBQ0QsU0FBT0EsT0FBUDtBQUNEOztBQUVEdUIsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZWLEVBQUFBLGFBRGU7QUFFZmhCLEVBQUFBLGdCQUZlO0FBR2ZLLEVBQUFBO0FBSGUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIHR3aXR0ZXIgQVBJLlxudmFyIE9BdXRoID0gcmVxdWlyZSgnLi9PQXV0aDFDbGllbnQnKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyB1c2VyIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSwgb3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLCAnVHdpdHRlciBhdXRoIGNvbmZpZ3VyYXRpb24gbWlzc2luZycpO1xuICB9XG4gIG9wdGlvbnMgPSBoYW5kbGVNdWx0aXBsZUNvbmZpZ3VyYXRpb25zKGF1dGhEYXRhLCBvcHRpb25zKTtcbiAgdmFyIGNsaWVudCA9IG5ldyBPQXV0aChvcHRpb25zKTtcbiAgY2xpZW50Lmhvc3QgPSAnYXBpLnR3aXR0ZXIuY29tJztcbiAgY2xpZW50LmF1dGhfdG9rZW4gPSBhdXRoRGF0YS5hdXRoX3Rva2VuO1xuICBjbGllbnQuYXV0aF90b2tlbl9zZWNyZXQgPSBhdXRoRGF0YS5hdXRoX3Rva2VuX3NlY3JldDtcblxuICByZXR1cm4gY2xpZW50LmdldCgnLzEuMS9hY2NvdW50L3ZlcmlmeV9jcmVkZW50aWFscy5qc29uJykudGhlbihkYXRhID0+IHtcbiAgICBpZiAoZGF0YSAmJiBkYXRhLmlkX3N0ciA9PSAnJyArIGF1dGhEYXRhLmlkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnVHdpdHRlciBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nKTtcbiAgfSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG5mdW5jdGlvbiBoYW5kbGVNdWx0aXBsZUNvbmZpZ3VyYXRpb25zKGF1dGhEYXRhLCBvcHRpb25zKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KG9wdGlvbnMpKSB7XG4gICAgY29uc3QgY29uc3VtZXJfa2V5ID0gYXV0aERhdGEuY29uc3VtZXJfa2V5O1xuICAgIGlmICghY29uc3VtZXJfa2V5KSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ1R3aXR0ZXIgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gICAgfVxuICAgIG9wdGlvbnMgPSBvcHRpb25zLmZpbHRlcihvcHRpb24gPT4ge1xuICAgICAgcmV0dXJuIG9wdGlvbi5jb25zdW1lcl9rZXkgPT0gY29uc3VtZXJfa2V5O1xuICAgIH0pO1xuXG4gICAgaWYgKG9wdGlvbnMubGVuZ3RoID09IDApIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnVHdpdHRlciBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nKTtcbiAgICB9XG4gICAgb3B0aW9ucyA9IG9wdGlvbnNbMF07XG4gIH1cbiAgcmV0dXJuIG9wdGlvbnM7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhLFxuICBoYW5kbGVNdWx0aXBsZUNvbmZpZ3VyYXRpb25zLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/vkontakte.js b/lib/Adapters/Auth/vkontakte.js new file mode 100644 index 0000000000..1e952c1d3d --- /dev/null +++ b/lib/Adapters/Auth/vkontakte.js @@ -0,0 +1,54 @@ +'use strict'; // Helper functions for accessing the vkontakte API. + +const httpsRequest = require('./httpsRequest'); + +var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData, params) { + return vkOAuth2Request(params).then(function (response) { + if (response && response.access_token) { + return request('api.vk.com', 'method/users.get?access_token=' + authData.access_token + '&v=' + params.apiVersion).then(function (response) { + if (response && response.response && response.response.length && response.response[0].id == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Vk auth is invalid for this user.'); + }); + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Vk appIds or appSecret is incorrect.'); + }); +} + +function vkOAuth2Request(params) { + return new Promise(function (resolve) { + if (!params || !params.appIds || !params.appIds.length || !params.appSecret || !params.appSecret.length) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Vk auth is not configured. Missing appIds or appSecret.'); + } + + if (!params.apiVersion) { + params.apiVersion = '5.124'; + } + + resolve(); + }).then(function () { + return request('oauth.vk.com', 'access_token?client_id=' + params.appIds + '&client_secret=' + params.appSecret + '&v=' + params.apiVersion + '&grant_type=client_credentials'); + }); +} // Returns a promise that fulfills iff this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for api requests + + +function request(host, path) { + return httpsRequest.get('https://' + host + '/' + path); +} + +module.exports = { + validateAppId: validateAppId, + validateAuthData: validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3Zrb250YWt0ZS5qcyJdLCJuYW1lcyI6WyJodHRwc1JlcXVlc3QiLCJyZXF1aXJlIiwiUGFyc2UiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJwYXJhbXMiLCJ2a09BdXRoMlJlcXVlc3QiLCJ0aGVuIiwicmVzcG9uc2UiLCJhY2Nlc3NfdG9rZW4iLCJyZXF1ZXN0IiwiYXBpVmVyc2lvbiIsImxlbmd0aCIsImlkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiUHJvbWlzZSIsInJlc29sdmUiLCJhcHBJZHMiLCJhcHBTZWNyZXQiLCJ2YWxpZGF0ZUFwcElkIiwiaG9zdCIsInBhdGgiLCJnZXQiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiQUFBQSxhLENBRUE7O0FBRUEsTUFBTUEsWUFBWSxHQUFHQyxPQUFPLENBQUMsZ0JBQUQsQ0FBNUI7O0FBQ0EsSUFBSUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCQyxLQUFsQyxDLENBRUE7OztBQUNBLFNBQVNDLGdCQUFULENBQTBCQyxRQUExQixFQUFvQ0MsTUFBcEMsRUFBNEM7QUFDMUMsU0FBT0MsZUFBZSxDQUFDRCxNQUFELENBQWYsQ0FBd0JFLElBQXhCLENBQTZCLFVBQVVDLFFBQVYsRUFBb0I7QUFDdEQsUUFBSUEsUUFBUSxJQUFJQSxRQUFRLENBQUNDLFlBQXpCLEVBQXVDO0FBQ3JDLGFBQU9DLE9BQU8sQ0FDWixZQURZLEVBRVosbUNBQW1DTixRQUFRLENBQUNLLFlBQTVDLEdBQTJELEtBQTNELEdBQW1FSixNQUFNLENBQUNNLFVBRjlELENBQVAsQ0FHTEosSUFISyxDQUdBLFVBQVVDLFFBQVYsRUFBb0I7QUFDekIsWUFDRUEsUUFBUSxJQUNSQSxRQUFRLENBQUNBLFFBRFQsSUFFQUEsUUFBUSxDQUFDQSxRQUFULENBQWtCSSxNQUZsQixJQUdBSixRQUFRLENBQUNBLFFBQVQsQ0FBa0IsQ0FBbEIsRUFBcUJLLEVBQXJCLElBQTJCVCxRQUFRLENBQUNTLEVBSnRDLEVBS0U7QUFDQTtBQUNEOztBQUNELGNBQU0sSUFBSVgsS0FBSyxDQUFDWSxLQUFWLENBQWdCWixLQUFLLENBQUNZLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLG1DQUE5QyxDQUFOO0FBQ0QsT0FiTSxDQUFQO0FBY0Q7O0FBQ0QsVUFBTSxJQUFJYixLQUFLLENBQUNZLEtBQVYsQ0FBZ0JaLEtBQUssQ0FBQ1ksS0FBTixDQUFZQyxnQkFBNUIsRUFBOEMsc0NBQTlDLENBQU47QUFDRCxHQWxCTSxDQUFQO0FBbUJEOztBQUVELFNBQVNULGVBQVQsQ0FBeUJELE1BQXpCLEVBQWlDO0FBQy9CLFNBQU8sSUFBSVcsT0FBSixDQUFZLFVBQVVDLE9BQVYsRUFBbUI7QUFDcEMsUUFDRSxDQUFDWixNQUFELElBQ0EsQ0FBQ0EsTUFBTSxDQUFDYSxNQURSLElBRUEsQ0FBQ2IsTUFBTSxDQUFDYSxNQUFQLENBQWNOLE1BRmYsSUFHQSxDQUFDUCxNQUFNLENBQUNjLFNBSFIsSUFJQSxDQUFDZCxNQUFNLENBQUNjLFNBQVAsQ0FBaUJQLE1BTHBCLEVBTUU7QUFDQSxZQUFNLElBQUlWLEtBQUssQ0FBQ1ksS0FBVixDQUNKWixLQUFLLENBQUNZLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSix5REFGSSxDQUFOO0FBSUQ7O0FBQ0QsUUFBSSxDQUFDVixNQUFNLENBQUNNLFVBQVosRUFBd0I7QUFDdEJOLE1BQUFBLE1BQU0sQ0FBQ00sVUFBUCxHQUFvQixPQUFwQjtBQUNEOztBQUNETSxJQUFBQSxPQUFPO0FBQ1IsR0FqQk0sRUFpQkpWLElBakJJLENBaUJDLFlBQVk7QUFDbEIsV0FBT0csT0FBTyxDQUNaLGNBRFksRUFFWiw0QkFDRUwsTUFBTSxDQUFDYSxNQURULEdBRUUsaUJBRkYsR0FHRWIsTUFBTSxDQUFDYyxTQUhULEdBSUUsS0FKRixHQUtFZCxNQUFNLENBQUNNLFVBTFQsR0FNRSxnQ0FSVSxDQUFkO0FBVUQsR0E1Qk0sQ0FBUDtBQTZCRCxDLENBRUQ7OztBQUNBLFNBQVNTLGFBQVQsR0FBeUI7QUFDdkIsU0FBT0osT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNQLE9BQVQsQ0FBaUJXLElBQWpCLEVBQXVCQyxJQUF2QixFQUE2QjtBQUMzQixTQUFPdEIsWUFBWSxDQUFDdUIsR0FBYixDQUFpQixhQUFhRixJQUFiLEdBQW9CLEdBQXBCLEdBQTBCQyxJQUEzQyxDQUFQO0FBQ0Q7O0FBRURFLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmTCxFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZmpCLEVBQUFBLGdCQUFnQixFQUFFQTtBQUZILENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIHZrb250YWt0ZSBBUEkuXG5cbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIHBhcmFtcykge1xuICByZXR1cm4gdmtPQXV0aDJSZXF1ZXN0KHBhcmFtcykudGhlbihmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICBpZiAocmVzcG9uc2UgJiYgcmVzcG9uc2UuYWNjZXNzX3Rva2VuKSB7XG4gICAgICByZXR1cm4gcmVxdWVzdChcbiAgICAgICAgJ2FwaS52ay5jb20nLFxuICAgICAgICAnbWV0aG9kL3VzZXJzLmdldD9hY2Nlc3NfdG9rZW49JyArIGF1dGhEYXRhLmFjY2Vzc190b2tlbiArICcmdj0nICsgcGFyYW1zLmFwaVZlcnNpb25cbiAgICAgICkudGhlbihmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHJlc3BvbnNlICYmXG4gICAgICAgICAgcmVzcG9uc2UucmVzcG9uc2UgJiZcbiAgICAgICAgICByZXNwb25zZS5yZXNwb25zZS5sZW5ndGggJiZcbiAgICAgICAgICByZXNwb25zZS5yZXNwb25zZVswXS5pZCA9PSBhdXRoRGF0YS5pZFxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdWayBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ1ZrIGFwcElkcyBvciBhcHBTZWNyZXQgaXMgaW5jb3JyZWN0LicpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gdmtPQXV0aDJSZXF1ZXN0KHBhcmFtcykge1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICBpZiAoXG4gICAgICAhcGFyYW1zIHx8XG4gICAgICAhcGFyYW1zLmFwcElkcyB8fFxuICAgICAgIXBhcmFtcy5hcHBJZHMubGVuZ3RoIHx8XG4gICAgICAhcGFyYW1zLmFwcFNlY3JldCB8fFxuICAgICAgIXBhcmFtcy5hcHBTZWNyZXQubGVuZ3RoXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICdWayBhdXRoIGlzIG5vdCBjb25maWd1cmVkLiBNaXNzaW5nIGFwcElkcyBvciBhcHBTZWNyZXQuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKCFwYXJhbXMuYXBpVmVyc2lvbikge1xuICAgICAgcGFyYW1zLmFwaVZlcnNpb24gPSAnNS4xMjQnO1xuICAgIH1cbiAgICByZXNvbHZlKCk7XG4gIH0pLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiByZXF1ZXN0KFxuICAgICAgJ29hdXRoLnZrLmNvbScsXG4gICAgICAnYWNjZXNzX3Rva2VuP2NsaWVudF9pZD0nICtcbiAgICAgICAgcGFyYW1zLmFwcElkcyArXG4gICAgICAgICcmY2xpZW50X3NlY3JldD0nICtcbiAgICAgICAgcGFyYW1zLmFwcFNlY3JldCArXG4gICAgICAgICcmdj0nICtcbiAgICAgICAgcGFyYW1zLmFwaVZlcnNpb24gK1xuICAgICAgICAnJmdyYW50X3R5cGU9Y2xpZW50X2NyZWRlbnRpYWxzJ1xuICAgICk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBhcGkgcmVxdWVzdHNcbmZ1bmN0aW9uIHJlcXVlc3QoaG9zdCwgcGF0aCkge1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LmdldCgnaHR0cHM6Ly8nICsgaG9zdCArICcvJyArIHBhdGgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZDogdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YTogdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/wechat.js b/lib/Adapters/Auth/wechat.js new file mode 100644 index 0000000000..7ac39e029c --- /dev/null +++ b/lib/Adapters/Auth/wechat.js @@ -0,0 +1,33 @@ +"use strict"; + +// Helper functions for accessing the WeChat Graph API. +const httpsRequest = require('./httpsRequest'); + +var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData) { + return graphRequest('auth?access_token=' + authData.access_token + '&openid=' + authData.id).then(function (data) { + if (data.errcode == 0) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'wechat auth is invalid for this user.'); + }); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for WeChat graph requests. + + +function graphRequest(path) { + return httpsRequest.get('https://api.weixin.qq.com/sns/' + path); +} + +module.exports = { + validateAppId, + validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3dlY2hhdC5qcyJdLCJuYW1lcyI6WyJodHRwc1JlcXVlc3QiLCJyZXF1aXJlIiwiUGFyc2UiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJncmFwaFJlcXVlc3QiLCJhY2Nlc3NfdG9rZW4iLCJpZCIsInRoZW4iLCJkYXRhIiwiZXJyY29kZSIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJnZXQiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsTUFBTUEsWUFBWSxHQUFHQyxPQUFPLENBQUMsZ0JBQUQsQ0FBNUI7O0FBQ0EsSUFBSUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCQyxLQUFsQyxDLENBRUE7OztBQUNBLFNBQVNDLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxZQUFZLENBQUMsdUJBQXVCRCxRQUFRLENBQUNFLFlBQWhDLEdBQStDLFVBQS9DLEdBQTRERixRQUFRLENBQUNHLEVBQXRFLENBQVosQ0FBc0ZDLElBQXRGLENBQ0wsVUFBVUMsSUFBVixFQUFnQjtBQUNkLFFBQUlBLElBQUksQ0FBQ0MsT0FBTCxJQUFnQixDQUFwQixFQUF1QjtBQUNyQjtBQUNEOztBQUNELFVBQU0sSUFBSVIsS0FBSyxDQUFDUyxLQUFWLENBQWdCVCxLQUFLLENBQUNTLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLHVDQUE5QyxDQUFOO0FBQ0QsR0FOSSxDQUFQO0FBUUQsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTVixZQUFULENBQXNCVyxJQUF0QixFQUE0QjtBQUMxQixTQUFPaEIsWUFBWSxDQUFDaUIsR0FBYixDQUFpQixtQ0FBbUNELElBQXBELENBQVA7QUFDRDs7QUFFREUsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZOLEVBQUFBLGFBRGU7QUFFZlYsRUFBQUE7QUFGZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgV2VDaGF0IEdyYXBoIEFQSS5cbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIGdyYXBoUmVxdWVzdCgnYXV0aD9hY2Nlc3NfdG9rZW49JyArIGF1dGhEYXRhLmFjY2Vzc190b2tlbiArICcmb3BlbmlkPScgKyBhdXRoRGF0YS5pZCkudGhlbihcbiAgICBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgaWYgKGRhdGEuZXJyY29kZSA9PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnd2VjaGF0IGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLicpO1xuICAgIH1cbiAgKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBXZUNoYXQgZ3JhcGggcmVxdWVzdHMuXG5mdW5jdGlvbiBncmFwaFJlcXVlc3QocGF0aCkge1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LmdldCgnaHR0cHM6Ly9hcGkud2VpeGluLnFxLmNvbS9zbnMvJyArIHBhdGgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/weibo.js b/lib/Adapters/Auth/weibo.js new file mode 100644 index 0000000000..4e02a25ade --- /dev/null +++ b/lib/Adapters/Auth/weibo.js @@ -0,0 +1,47 @@ +"use strict"; + +// Helper functions for accessing the weibo Graph API. +var httpsRequest = require('./httpsRequest'); + +var Parse = require('parse/node').Parse; + +var querystring = require('querystring'); // Returns a promise that fulfills iff this user id is valid. + + +function validateAuthData(authData) { + return graphRequest(authData.access_token).then(function (data) { + if (data && data.uid == authData.id) { + return; + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'weibo auth is invalid for this user.'); + }); +} // Returns a promise that fulfills if this app id is valid. + + +function validateAppId() { + return Promise.resolve(); +} // A promisey wrapper for weibo graph requests. + + +function graphRequest(access_token) { + var postData = querystring.stringify({ + access_token: access_token + }); + var options = { + hostname: 'api.weibo.com', + path: '/oauth2/get_token_info', + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Content-Length': Buffer.byteLength(postData) + } + }; + return httpsRequest.request(options, postData); +} + +module.exports = { + validateAppId, + validateAuthData +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3dlaWJvLmpzIl0sIm5hbWVzIjpbImh0dHBzUmVxdWVzdCIsInJlcXVpcmUiLCJQYXJzZSIsInF1ZXJ5c3RyaW5nIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwiZ3JhcGhSZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsImRhdGEiLCJ1aWQiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBvc3REYXRhIiwic3RyaW5naWZ5Iiwib3B0aW9ucyIsImhvc3RuYW1lIiwicGF0aCIsIm1ldGhvZCIsImhlYWRlcnMiLCJCdWZmZXIiLCJieXRlTGVuZ3RoIiwicmVxdWVzdCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQSxJQUFJQSxZQUFZLEdBQUdDLE9BQU8sQ0FBQyxnQkFBRCxDQUExQjs7QUFDQSxJQUFJQyxLQUFLLEdBQUdELE9BQU8sQ0FBQyxZQUFELENBQVAsQ0FBc0JDLEtBQWxDOztBQUNBLElBQUlDLFdBQVcsR0FBR0YsT0FBTyxDQUFDLGFBQUQsQ0FBekIsQyxDQUVBOzs7QUFDQSxTQUFTRyxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0M7QUFDbEMsU0FBT0MsWUFBWSxDQUFDRCxRQUFRLENBQUNFLFlBQVYsQ0FBWixDQUFvQ0MsSUFBcEMsQ0FBeUMsVUFBVUMsSUFBVixFQUFnQjtBQUM5RCxRQUFJQSxJQUFJLElBQUlBLElBQUksQ0FBQ0MsR0FBTCxJQUFZTCxRQUFRLENBQUNNLEVBQWpDLEVBQXFDO0FBQ25DO0FBQ0Q7O0FBQ0QsVUFBTSxJQUFJVCxLQUFLLENBQUNVLEtBQVYsQ0FBZ0JWLEtBQUssQ0FBQ1UsS0FBTixDQUFZQyxnQkFBNUIsRUFBOEMsc0NBQTlDLENBQU47QUFDRCxHQUxNLENBQVA7QUFNRCxDLENBRUQ7OztBQUNBLFNBQVNDLGFBQVQsR0FBeUI7QUFDdkIsU0FBT0MsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNWLFlBQVQsQ0FBc0JDLFlBQXRCLEVBQW9DO0FBQ2xDLE1BQUlVLFFBQVEsR0FBR2QsV0FBVyxDQUFDZSxTQUFaLENBQXNCO0FBQ25DWCxJQUFBQSxZQUFZLEVBQUVBO0FBRHFCLEdBQXRCLENBQWY7QUFHQSxNQUFJWSxPQUFPLEdBQUc7QUFDWkMsSUFBQUEsUUFBUSxFQUFFLGVBREU7QUFFWkMsSUFBQUEsSUFBSSxFQUFFLHdCQUZNO0FBR1pDLElBQUFBLE1BQU0sRUFBRSxNQUhJO0FBSVpDLElBQUFBLE9BQU8sRUFBRTtBQUNQLHNCQUFnQixtQ0FEVDtBQUVQLHdCQUFrQkMsTUFBTSxDQUFDQyxVQUFQLENBQWtCUixRQUFsQjtBQUZYO0FBSkcsR0FBZDtBQVNBLFNBQU9qQixZQUFZLENBQUMwQixPQUFiLENBQXFCUCxPQUFyQixFQUE4QkYsUUFBOUIsQ0FBUDtBQUNEOztBQUVEVSxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZmQsRUFBQUEsYUFEZTtBQUVmVixFQUFBQTtBQUZlLENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgYWNjZXNzaW5nIHRoZSB3ZWlibyBHcmFwaCBBUEkuXG52YXIgaHR0cHNSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwc1JlcXVlc3QnKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbnZhciBxdWVyeXN0cmluZyA9IHJlcXVpcmUoJ3F1ZXJ5c3RyaW5nJyk7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIGdyYXBoUmVxdWVzdChhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHtcbiAgICBpZiAoZGF0YSAmJiBkYXRhLnVpZCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ3dlaWJvIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLicpO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciB3ZWlibyBncmFwaCByZXF1ZXN0cy5cbmZ1bmN0aW9uIGdyYXBoUmVxdWVzdChhY2Nlc3NfdG9rZW4pIHtcbiAgdmFyIHBvc3REYXRhID0gcXVlcnlzdHJpbmcuc3RyaW5naWZ5KHtcbiAgICBhY2Nlc3NfdG9rZW46IGFjY2Vzc190b2tlbixcbiAgfSk7XG4gIHZhciBvcHRpb25zID0ge1xuICAgIGhvc3RuYW1lOiAnYXBpLndlaWJvLmNvbScsXG4gICAgcGF0aDogJy9vYXV0aDIvZ2V0X3Rva2VuX2luZm8nLFxuICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyxcbiAgICAgICdDb250ZW50LUxlbmd0aCc6IEJ1ZmZlci5ieXRlTGVuZ3RoKHBvc3REYXRhKSxcbiAgICB9LFxuICB9O1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LnJlcXVlc3Qob3B0aW9ucywgcG9zdERhdGEpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Cache/CacheAdapter.js b/lib/Adapters/Cache/CacheAdapter.js new file mode 100644 index 0000000000..90a616c493 --- /dev/null +++ b/lib/Adapters/Cache/CacheAdapter.js @@ -0,0 +1,50 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.CacheAdapter = void 0; + +/*eslint no-unused-vars: "off"*/ + +/** + * @module Adapters + */ + +/** + * @interface CacheAdapter + */ +class CacheAdapter { + /** + * Get a value in the cache + * @param {String} key Cache key to get + * @return {Promise} that will eventually resolve to the value in the cache. + */ + get(key) {} + /** + * Set a value in the cache + * @param {String} key Cache key to set + * @param {String} value Value to set the key + * @param {String} ttl Optional TTL + */ + + + put(key, value, ttl) {} + /** + * Remove a value from the cache. + * @param {String} key Cache key to remove + */ + + + del(key) {} + /** + * Empty a cache + */ + + + clear() {} + +} + +exports.CacheAdapter = CacheAdapter; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9DYWNoZUFkYXB0ZXIuanMiXSwibmFtZXMiOlsiQ2FjaGVBZGFwdGVyIiwiZ2V0Iiwia2V5IiwicHV0IiwidmFsdWUiLCJ0dGwiLCJkZWwiLCJjbGVhciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBO0FBQ0E7QUFDQTs7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNQSxZQUFOLENBQW1CO0FBQ3hCO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDRUMsRUFBQUEsR0FBRyxDQUFDQyxHQUFELEVBQU0sQ0FBRTtBQUVYO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0VDLEVBQUFBLEdBQUcsQ0FBQ0QsR0FBRCxFQUFNRSxLQUFOLEVBQWFDLEdBQWIsRUFBa0IsQ0FBRTtBQUV2QjtBQUNGO0FBQ0E7QUFDQTs7O0FBQ0VDLEVBQUFBLEdBQUcsQ0FBQ0osR0FBRCxFQUFNLENBQUU7QUFFWDtBQUNGO0FBQ0E7OztBQUNFSyxFQUFBQSxLQUFLLEdBQUcsQ0FBRTs7QUF6QmMiLCJzb3VyY2VzQ29udGVudCI6WyIvKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG4vKipcbiAqIEBtb2R1bGUgQWRhcHRlcnNcbiAqL1xuLyoqXG4gKiBAaW50ZXJmYWNlIENhY2hlQWRhcHRlclxuICovXG5leHBvcnQgY2xhc3MgQ2FjaGVBZGFwdGVyIHtcbiAgLyoqXG4gICAqIEdldCBhIHZhbHVlIGluIHRoZSBjYWNoZVxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5IENhY2hlIGtleSB0byBnZXRcbiAgICogQHJldHVybiB7UHJvbWlzZX0gdGhhdCB3aWxsIGV2ZW50dWFsbHkgcmVzb2x2ZSB0byB0aGUgdmFsdWUgaW4gdGhlIGNhY2hlLlxuICAgKi9cbiAgZ2V0KGtleSkge31cblxuICAvKipcbiAgICogU2V0IGEgdmFsdWUgaW4gdGhlIGNhY2hlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgQ2FjaGUga2V5IHRvIHNldFxuICAgKiBAcGFyYW0ge1N0cmluZ30gdmFsdWUgVmFsdWUgdG8gc2V0IHRoZSBrZXlcbiAgICogQHBhcmFtIHtTdHJpbmd9IHR0bCBPcHRpb25hbCBUVExcbiAgICovXG4gIHB1dChrZXksIHZhbHVlLCB0dGwpIHt9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBhIHZhbHVlIGZyb20gdGhlIGNhY2hlLlxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5IENhY2hlIGtleSB0byByZW1vdmVcbiAgICovXG4gIGRlbChrZXkpIHt9XG5cbiAgLyoqXG4gICAqIEVtcHR5IGEgY2FjaGVcbiAgICovXG4gIGNsZWFyKCkge31cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Cache/InMemoryCache.js b/lib/Adapters/Cache/InMemoryCache.js new file mode 100644 index 0000000000..b9a6543504 --- /dev/null +++ b/lib/Adapters/Cache/InMemoryCache.js @@ -0,0 +1,76 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.InMemoryCache = void 0; +const DEFAULT_CACHE_TTL = 5 * 1000; + +class InMemoryCache { + constructor({ + ttl = DEFAULT_CACHE_TTL + }) { + this.ttl = ttl; + this.cache = Object.create(null); + } + + get(key) { + const record = this.cache[key]; + + if (record == null) { + return null; + } // Has Record and isnt expired + + + if (isNaN(record.expire) || record.expire >= Date.now()) { + return record.value; + } // Record has expired + + + delete this.cache[key]; + return null; + } + + put(key, value, ttl = this.ttl) { + if (ttl < 0 || isNaN(ttl)) { + ttl = NaN; + } + + var record = { + value: value, + expire: ttl + Date.now() + }; + + if (!isNaN(record.expire)) { + record.timeout = setTimeout(() => { + this.del(key); + }, ttl); + } + + this.cache[key] = record; + } + + del(key) { + var record = this.cache[key]; + + if (record == null) { + return; + } + + if (record.timeout) { + clearTimeout(record.timeout); + } + + delete this.cache[key]; + } + + clear() { + this.cache = Object.create(null); + } + +} + +exports.InMemoryCache = InMemoryCache; +var _default = InMemoryCache; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9Jbk1lbW9yeUNhY2hlLmpzIl0sIm5hbWVzIjpbIkRFRkFVTFRfQ0FDSEVfVFRMIiwiSW5NZW1vcnlDYWNoZSIsImNvbnN0cnVjdG9yIiwidHRsIiwiY2FjaGUiLCJPYmplY3QiLCJjcmVhdGUiLCJnZXQiLCJrZXkiLCJyZWNvcmQiLCJpc05hTiIsImV4cGlyZSIsIkRhdGUiLCJub3ciLCJ2YWx1ZSIsInB1dCIsIk5hTiIsInRpbWVvdXQiLCJzZXRUaW1lb3V0IiwiZGVsIiwiY2xlYXJUaW1lb3V0IiwiY2xlYXIiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLE1BQU1BLGlCQUFpQixHQUFHLElBQUksSUFBOUI7O0FBRU8sTUFBTUMsYUFBTixDQUFvQjtBQUN6QkMsRUFBQUEsV0FBVyxDQUFDO0FBQUVDLElBQUFBLEdBQUcsR0FBR0g7QUFBUixHQUFELEVBQThCO0FBQ3ZDLFNBQUtHLEdBQUwsR0FBV0EsR0FBWDtBQUNBLFNBQUtDLEtBQUwsR0FBYUMsTUFBTSxDQUFDQyxNQUFQLENBQWMsSUFBZCxDQUFiO0FBQ0Q7O0FBRURDLEVBQUFBLEdBQUcsQ0FBQ0MsR0FBRCxFQUFNO0FBQ1AsVUFBTUMsTUFBTSxHQUFHLEtBQUtMLEtBQUwsQ0FBV0ksR0FBWCxDQUFmOztBQUNBLFFBQUlDLE1BQU0sSUFBSSxJQUFkLEVBQW9CO0FBQ2xCLGFBQU8sSUFBUDtBQUNELEtBSk0sQ0FNUDs7O0FBQ0EsUUFBSUMsS0FBSyxDQUFDRCxNQUFNLENBQUNFLE1BQVIsQ0FBTCxJQUF3QkYsTUFBTSxDQUFDRSxNQUFQLElBQWlCQyxJQUFJLENBQUNDLEdBQUwsRUFBN0MsRUFBeUQ7QUFDdkQsYUFBT0osTUFBTSxDQUFDSyxLQUFkO0FBQ0QsS0FUTSxDQVdQOzs7QUFDQSxXQUFPLEtBQUtWLEtBQUwsQ0FBV0ksR0FBWCxDQUFQO0FBQ0EsV0FBTyxJQUFQO0FBQ0Q7O0FBRURPLEVBQUFBLEdBQUcsQ0FBQ1AsR0FBRCxFQUFNTSxLQUFOLEVBQWFYLEdBQUcsR0FBRyxLQUFLQSxHQUF4QixFQUE2QjtBQUM5QixRQUFJQSxHQUFHLEdBQUcsQ0FBTixJQUFXTyxLQUFLLENBQUNQLEdBQUQsQ0FBcEIsRUFBMkI7QUFDekJBLE1BQUFBLEdBQUcsR0FBR2EsR0FBTjtBQUNEOztBQUVELFFBQUlQLE1BQU0sR0FBRztBQUNYSyxNQUFBQSxLQUFLLEVBQUVBLEtBREk7QUFFWEgsTUFBQUEsTUFBTSxFQUFFUixHQUFHLEdBQUdTLElBQUksQ0FBQ0MsR0FBTDtBQUZILEtBQWI7O0FBS0EsUUFBSSxDQUFDSCxLQUFLLENBQUNELE1BQU0sQ0FBQ0UsTUFBUixDQUFWLEVBQTJCO0FBQ3pCRixNQUFBQSxNQUFNLENBQUNRLE9BQVAsR0FBaUJDLFVBQVUsQ0FBQyxNQUFNO0FBQ2hDLGFBQUtDLEdBQUwsQ0FBU1gsR0FBVDtBQUNELE9BRjBCLEVBRXhCTCxHQUZ3QixDQUEzQjtBQUdEOztBQUVELFNBQUtDLEtBQUwsQ0FBV0ksR0FBWCxJQUFrQkMsTUFBbEI7QUFDRDs7QUFFRFUsRUFBQUEsR0FBRyxDQUFDWCxHQUFELEVBQU07QUFDUCxRQUFJQyxNQUFNLEdBQUcsS0FBS0wsS0FBTCxDQUFXSSxHQUFYLENBQWI7O0FBQ0EsUUFBSUMsTUFBTSxJQUFJLElBQWQsRUFBb0I7QUFDbEI7QUFDRDs7QUFFRCxRQUFJQSxNQUFNLENBQUNRLE9BQVgsRUFBb0I7QUFDbEJHLE1BQUFBLFlBQVksQ0FBQ1gsTUFBTSxDQUFDUSxPQUFSLENBQVo7QUFDRDs7QUFDRCxXQUFPLEtBQUtiLEtBQUwsQ0FBV0ksR0FBWCxDQUFQO0FBQ0Q7O0FBRURhLEVBQUFBLEtBQUssR0FBRztBQUNOLFNBQUtqQixLQUFMLEdBQWFDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjLElBQWQsQ0FBYjtBQUNEOztBQXZEd0I7OztlQTBEWkwsYSIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IERFRkFVTFRfQ0FDSEVfVFRMID0gNSAqIDEwMDA7XG5cbmV4cG9ydCBjbGFzcyBJbk1lbW9yeUNhY2hlIHtcbiAgY29uc3RydWN0b3IoeyB0dGwgPSBERUZBVUxUX0NBQ0hFX1RUTCB9KSB7XG4gICAgdGhpcy50dGwgPSB0dGw7XG4gICAgdGhpcy5jYWNoZSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gIH1cblxuICBnZXQoa2V5KSB7XG4gICAgY29uc3QgcmVjb3JkID0gdGhpcy5jYWNoZVtrZXldO1xuICAgIGlmIChyZWNvcmQgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gSGFzIFJlY29yZCBhbmQgaXNudCBleHBpcmVkXG4gICAgaWYgKGlzTmFOKHJlY29yZC5leHBpcmUpIHx8IHJlY29yZC5leHBpcmUgPj0gRGF0ZS5ub3coKSkge1xuICAgICAgcmV0dXJuIHJlY29yZC52YWx1ZTtcbiAgICB9XG5cbiAgICAvLyBSZWNvcmQgaGFzIGV4cGlyZWRcbiAgICBkZWxldGUgdGhpcy5jYWNoZVtrZXldO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHV0KGtleSwgdmFsdWUsIHR0bCA9IHRoaXMudHRsKSB7XG4gICAgaWYgKHR0bCA8IDAgfHwgaXNOYU4odHRsKSkge1xuICAgICAgdHRsID0gTmFOO1xuICAgIH1cblxuICAgIHZhciByZWNvcmQgPSB7XG4gICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICBleHBpcmU6IHR0bCArIERhdGUubm93KCksXG4gICAgfTtcblxuICAgIGlmICghaXNOYU4ocmVjb3JkLmV4cGlyZSkpIHtcbiAgICAgIHJlY29yZC50aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuZGVsKGtleSk7XG4gICAgICB9LCB0dGwpO1xuICAgIH1cblxuICAgIHRoaXMuY2FjaGVba2V5XSA9IHJlY29yZDtcbiAgfVxuXG4gIGRlbChrZXkpIHtcbiAgICB2YXIgcmVjb3JkID0gdGhpcy5jYWNoZVtrZXldO1xuICAgIGlmIChyZWNvcmQgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChyZWNvcmQudGltZW91dCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHJlY29yZC50aW1lb3V0KTtcbiAgICB9XG4gICAgZGVsZXRlIHRoaXMuY2FjaGVba2V5XTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIHRoaXMuY2FjaGUgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEluTWVtb3J5Q2FjaGU7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Cache/InMemoryCacheAdapter.js b/lib/Adapters/Cache/InMemoryCacheAdapter.js new file mode 100644 index 0000000000..ffc38ce5ec --- /dev/null +++ b/lib/Adapters/Cache/InMemoryCacheAdapter.js @@ -0,0 +1,45 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.InMemoryCacheAdapter = void 0; + +var _LRUCache = require("./LRUCache"); + +class InMemoryCacheAdapter { + constructor(ctx) { + this.cache = new _LRUCache.LRUCache(ctx); + } + + get(key) { + const record = this.cache.get(key); + + if (record === null) { + return Promise.resolve(null); + } + + return Promise.resolve(record); + } + + put(key, value, ttl) { + this.cache.put(key, value, ttl); + return Promise.resolve(); + } + + del(key) { + this.cache.del(key); + return Promise.resolve(); + } + + clear() { + this.cache.clear(); + return Promise.resolve(); + } + +} + +exports.InMemoryCacheAdapter = InMemoryCacheAdapter; +var _default = InMemoryCacheAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9Jbk1lbW9yeUNhY2hlQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJJbk1lbW9yeUNhY2hlQWRhcHRlciIsImNvbnN0cnVjdG9yIiwiY3R4IiwiY2FjaGUiLCJMUlVDYWNoZSIsImdldCIsImtleSIsInJlY29yZCIsIlByb21pc2UiLCJyZXNvbHZlIiwicHV0IiwidmFsdWUiLCJ0dGwiLCJkZWwiLCJjbGVhciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUVPLE1BQU1BLG9CQUFOLENBQTJCO0FBQ2hDQyxFQUFBQSxXQUFXLENBQUNDLEdBQUQsRUFBTTtBQUNmLFNBQUtDLEtBQUwsR0FBYSxJQUFJQyxrQkFBSixDQUFhRixHQUFiLENBQWI7QUFDRDs7QUFFREcsRUFBQUEsR0FBRyxDQUFDQyxHQUFELEVBQU07QUFDUCxVQUFNQyxNQUFNLEdBQUcsS0FBS0osS0FBTCxDQUFXRSxHQUFYLENBQWVDLEdBQWYsQ0FBZjs7QUFDQSxRQUFJQyxNQUFNLEtBQUssSUFBZixFQUFxQjtBQUNuQixhQUFPQyxPQUFPLENBQUNDLE9BQVIsQ0FBZ0IsSUFBaEIsQ0FBUDtBQUNEOztBQUNELFdBQU9ELE9BQU8sQ0FBQ0MsT0FBUixDQUFnQkYsTUFBaEIsQ0FBUDtBQUNEOztBQUVERyxFQUFBQSxHQUFHLENBQUNKLEdBQUQsRUFBTUssS0FBTixFQUFhQyxHQUFiLEVBQWtCO0FBQ25CLFNBQUtULEtBQUwsQ0FBV08sR0FBWCxDQUFlSixHQUFmLEVBQW9CSyxLQUFwQixFQUEyQkMsR0FBM0I7QUFDQSxXQUFPSixPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVESSxFQUFBQSxHQUFHLENBQUNQLEdBQUQsRUFBTTtBQUNQLFNBQUtILEtBQUwsQ0FBV1UsR0FBWCxDQUFlUCxHQUFmO0FBQ0EsV0FBT0UsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFREssRUFBQUEsS0FBSyxHQUFHO0FBQ04sU0FBS1gsS0FBTCxDQUFXVyxLQUFYO0FBQ0EsV0FBT04sT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUExQitCOzs7ZUE2Qm5CVCxvQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExSVUNhY2hlIH0gZnJvbSAnLi9MUlVDYWNoZSc7XG5cbmV4cG9ydCBjbGFzcyBJbk1lbW9yeUNhY2hlQWRhcHRlciB7XG4gIGNvbnN0cnVjdG9yKGN0eCkge1xuICAgIHRoaXMuY2FjaGUgPSBuZXcgTFJVQ2FjaGUoY3R4KTtcbiAgfVxuXG4gIGdldChrZXkpIHtcbiAgICBjb25zdCByZWNvcmQgPSB0aGlzLmNhY2hlLmdldChrZXkpO1xuICAgIGlmIChyZWNvcmQgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobnVsbCk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVjb3JkKTtcbiAgfVxuXG4gIHB1dChrZXksIHZhbHVlLCB0dGwpIHtcbiAgICB0aGlzLmNhY2hlLnB1dChrZXksIHZhbHVlLCB0dGwpO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGRlbChrZXkpIHtcbiAgICB0aGlzLmNhY2hlLmRlbChrZXkpO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIHRoaXMuY2FjaGUuY2xlYXIoKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSW5NZW1vcnlDYWNoZUFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Cache/LRUCache.js b/lib/Adapters/Cache/LRUCache.js new file mode 100644 index 0000000000..9781621ecf --- /dev/null +++ b/lib/Adapters/Cache/LRUCache.js @@ -0,0 +1,46 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.LRUCache = void 0; + +var _lruCache = _interopRequireDefault(require("lru-cache")); + +var _defaults = _interopRequireDefault(require("../../defaults")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class LRUCache { + constructor({ + ttl = _defaults.default.cacheTTL, + maxSize = _defaults.default.cacheMaxSize + }) { + this.cache = new _lruCache.default({ + max: maxSize, + maxAge: ttl + }); + } + + get(key) { + return this.cache.get(key) || null; + } + + put(key, value, ttl = this.ttl) { + this.cache.set(key, value, ttl); + } + + del(key) { + this.cache.del(key); + } + + clear() { + this.cache.reset(); + } + +} + +exports.LRUCache = LRUCache; +var _default = LRUCache; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9MUlVDYWNoZS5qcyJdLCJuYW1lcyI6WyJMUlVDYWNoZSIsImNvbnN0cnVjdG9yIiwidHRsIiwiZGVmYXVsdHMiLCJjYWNoZVRUTCIsIm1heFNpemUiLCJjYWNoZU1heFNpemUiLCJjYWNoZSIsIkxSVSIsIm1heCIsIm1heEFnZSIsImdldCIsImtleSIsInB1dCIsInZhbHVlIiwic2V0IiwiZGVsIiwiY2xlYXIiLCJyZXNldCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7O0FBRU8sTUFBTUEsUUFBTixDQUFlO0FBQ3BCQyxFQUFBQSxXQUFXLENBQUM7QUFBRUMsSUFBQUEsR0FBRyxHQUFHQyxrQkFBU0MsUUFBakI7QUFBMkJDLElBQUFBLE9BQU8sR0FBR0Ysa0JBQVNHO0FBQTlDLEdBQUQsRUFBK0Q7QUFDeEUsU0FBS0MsS0FBTCxHQUFhLElBQUlDLGlCQUFKLENBQVE7QUFDbkJDLE1BQUFBLEdBQUcsRUFBRUosT0FEYztBQUVuQkssTUFBQUEsTUFBTSxFQUFFUjtBQUZXLEtBQVIsQ0FBYjtBQUlEOztBQUVEUyxFQUFBQSxHQUFHLENBQUNDLEdBQUQsRUFBTTtBQUNQLFdBQU8sS0FBS0wsS0FBTCxDQUFXSSxHQUFYLENBQWVDLEdBQWYsS0FBdUIsSUFBOUI7QUFDRDs7QUFFREMsRUFBQUEsR0FBRyxDQUFDRCxHQUFELEVBQU1FLEtBQU4sRUFBYVosR0FBRyxHQUFHLEtBQUtBLEdBQXhCLEVBQTZCO0FBQzlCLFNBQUtLLEtBQUwsQ0FBV1EsR0FBWCxDQUFlSCxHQUFmLEVBQW9CRSxLQUFwQixFQUEyQlosR0FBM0I7QUFDRDs7QUFFRGMsRUFBQUEsR0FBRyxDQUFDSixHQUFELEVBQU07QUFDUCxTQUFLTCxLQUFMLENBQVdTLEdBQVgsQ0FBZUosR0FBZjtBQUNEOztBQUVESyxFQUFBQSxLQUFLLEdBQUc7QUFDTixTQUFLVixLQUFMLENBQVdXLEtBQVg7QUFDRDs7QUF0Qm1COzs7ZUF5QlBsQixRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IExSVSBmcm9tICdscnUtY2FjaGUnO1xuaW1wb3J0IGRlZmF1bHRzIGZyb20gJy4uLy4uL2RlZmF1bHRzJztcblxuZXhwb3J0IGNsYXNzIExSVUNhY2hlIHtcbiAgY29uc3RydWN0b3IoeyB0dGwgPSBkZWZhdWx0cy5jYWNoZVRUTCwgbWF4U2l6ZSA9IGRlZmF1bHRzLmNhY2hlTWF4U2l6ZSB9KSB7XG4gICAgdGhpcy5jYWNoZSA9IG5ldyBMUlUoe1xuICAgICAgbWF4OiBtYXhTaXplLFxuICAgICAgbWF4QWdlOiB0dGwsXG4gICAgfSk7XG4gIH1cblxuICBnZXQoa2V5KSB7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0KGtleSkgfHwgbnVsbDtcbiAgfVxuXG4gIHB1dChrZXksIHZhbHVlLCB0dGwgPSB0aGlzLnR0bCkge1xuICAgIHRoaXMuY2FjaGUuc2V0KGtleSwgdmFsdWUsIHR0bCk7XG4gIH1cblxuICBkZWwoa2V5KSB7XG4gICAgdGhpcy5jYWNoZS5kZWwoa2V5KTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIHRoaXMuY2FjaGUucmVzZXQoKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBMUlVDYWNoZTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Cache/NullCacheAdapter.js b/lib/Adapters/Cache/NullCacheAdapter.js new file mode 100644 index 0000000000..639c544c94 --- /dev/null +++ b/lib/Adapters/Cache/NullCacheAdapter.js @@ -0,0 +1,34 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.NullCacheAdapter = void 0; + +class NullCacheAdapter { + constructor() {} + + get() { + return new Promise(resolve => { + return resolve(null); + }); + } + + put() { + return Promise.resolve(); + } + + del() { + return Promise.resolve(); + } + + clear() { + return Promise.resolve(); + } + +} + +exports.NullCacheAdapter = NullCacheAdapter; +var _default = NullCacheAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9OdWxsQ2FjaGVBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIk51bGxDYWNoZUFkYXB0ZXIiLCJjb25zdHJ1Y3RvciIsImdldCIsIlByb21pc2UiLCJyZXNvbHZlIiwicHV0IiwiZGVsIiwiY2xlYXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBTyxNQUFNQSxnQkFBTixDQUF1QjtBQUM1QkMsRUFBQUEsV0FBVyxHQUFHLENBQUU7O0FBRWhCQyxFQUFBQSxHQUFHLEdBQUc7QUFDSixXQUFPLElBQUlDLE9BQUosQ0FBWUMsT0FBTyxJQUFJO0FBQzVCLGFBQU9BLE9BQU8sQ0FBQyxJQUFELENBQWQ7QUFDRCxLQUZNLENBQVA7QUFHRDs7QUFFREMsRUFBQUEsR0FBRyxHQUFHO0FBQ0osV0FBT0YsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFREUsRUFBQUEsR0FBRyxHQUFHO0FBQ0osV0FBT0gsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFREcsRUFBQUEsS0FBSyxHQUFHO0FBQ04sV0FBT0osT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFuQjJCOzs7ZUFzQmZKLGdCIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNsYXNzIE51bGxDYWNoZUFkYXB0ZXIge1xuICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgZ2V0KCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgIH0pO1xuICB9XG5cbiAgcHV0KCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGRlbCgpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTnVsbENhY2hlQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Cache/RedisCacheAdapter/KeyPromiseQueue.js b/lib/Adapters/Cache/RedisCacheAdapter/KeyPromiseQueue.js new file mode 100644 index 0000000000..d4303d8803 --- /dev/null +++ b/lib/Adapters/Cache/RedisCacheAdapter/KeyPromiseQueue.js @@ -0,0 +1,59 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.KeyPromiseQueue = void 0; + +// KeyPromiseQueue is a simple promise queue +// used to queue operations per key basis. +// Once the tail promise in the key-queue fulfills, +// the chain on that key will be cleared. +class KeyPromiseQueue { + constructor() { + this.queue = {}; + } + + enqueue(key, operation) { + const tuple = this.beforeOp(key); + const toAwait = tuple[1]; + const nextOperation = toAwait.then(operation); + const wrappedOperation = nextOperation.then(result => { + this.afterOp(key); + return result; + }); + tuple[1] = wrappedOperation; + return wrappedOperation; + } + + beforeOp(key) { + let tuple = this.queue[key]; + + if (!tuple) { + tuple = [0, Promise.resolve()]; + this.queue[key] = tuple; + } + + tuple[0]++; + return tuple; + } + + afterOp(key) { + const tuple = this.queue[key]; + + if (!tuple) { + return; + } + + tuple[0]--; + + if (tuple[0] <= 0) { + delete this.queue[key]; + return; + } + } + +} + +exports.KeyPromiseQueue = KeyPromiseQueue; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9SZWRpc0NhY2hlQWRhcHRlci9LZXlQcm9taXNlUXVldWUuanMiXSwibmFtZXMiOlsiS2V5UHJvbWlzZVF1ZXVlIiwiY29uc3RydWN0b3IiLCJxdWV1ZSIsImVucXVldWUiLCJrZXkiLCJvcGVyYXRpb24iLCJ0dXBsZSIsImJlZm9yZU9wIiwidG9Bd2FpdCIsIm5leHRPcGVyYXRpb24iLCJ0aGVuIiwid3JhcHBlZE9wZXJhdGlvbiIsInJlc3VsdCIsImFmdGVyT3AiLCJQcm9taXNlIiwicmVzb2x2ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTUEsZUFBTixDQUFzQjtBQUMzQkMsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxHQUFhLEVBQWI7QUFDRDs7QUFFREMsRUFBQUEsT0FBTyxDQUFDQyxHQUFELEVBQU1DLFNBQU4sRUFBaUI7QUFDdEIsVUFBTUMsS0FBSyxHQUFHLEtBQUtDLFFBQUwsQ0FBY0gsR0FBZCxDQUFkO0FBQ0EsVUFBTUksT0FBTyxHQUFHRixLQUFLLENBQUMsQ0FBRCxDQUFyQjtBQUNBLFVBQU1HLGFBQWEsR0FBR0QsT0FBTyxDQUFDRSxJQUFSLENBQWFMLFNBQWIsQ0FBdEI7QUFDQSxVQUFNTSxnQkFBZ0IsR0FBR0YsYUFBYSxDQUFDQyxJQUFkLENBQW1CRSxNQUFNLElBQUk7QUFDcEQsV0FBS0MsT0FBTCxDQUFhVCxHQUFiO0FBQ0EsYUFBT1EsTUFBUDtBQUNELEtBSHdCLENBQXpCO0FBSUFOLElBQUFBLEtBQUssQ0FBQyxDQUFELENBQUwsR0FBV0ssZ0JBQVg7QUFDQSxXQUFPQSxnQkFBUDtBQUNEOztBQUVESixFQUFBQSxRQUFRLENBQUNILEdBQUQsRUFBTTtBQUNaLFFBQUlFLEtBQUssR0FBRyxLQUFLSixLQUFMLENBQVdFLEdBQVgsQ0FBWjs7QUFDQSxRQUFJLENBQUNFLEtBQUwsRUFBWTtBQUNWQSxNQUFBQSxLQUFLLEdBQUcsQ0FBQyxDQUFELEVBQUlRLE9BQU8sQ0FBQ0MsT0FBUixFQUFKLENBQVI7QUFDQSxXQUFLYixLQUFMLENBQVdFLEdBQVgsSUFBa0JFLEtBQWxCO0FBQ0Q7O0FBQ0RBLElBQUFBLEtBQUssQ0FBQyxDQUFELENBQUw7QUFDQSxXQUFPQSxLQUFQO0FBQ0Q7O0FBRURPLEVBQUFBLE9BQU8sQ0FBQ1QsR0FBRCxFQUFNO0FBQ1gsVUFBTUUsS0FBSyxHQUFHLEtBQUtKLEtBQUwsQ0FBV0UsR0FBWCxDQUFkOztBQUNBLFFBQUksQ0FBQ0UsS0FBTCxFQUFZO0FBQ1Y7QUFDRDs7QUFDREEsSUFBQUEsS0FBSyxDQUFDLENBQUQsQ0FBTDs7QUFDQSxRQUFJQSxLQUFLLENBQUMsQ0FBRCxDQUFMLElBQVksQ0FBaEIsRUFBbUI7QUFDakIsYUFBTyxLQUFLSixLQUFMLENBQVdFLEdBQVgsQ0FBUDtBQUNBO0FBQ0Q7QUFDRjs7QUFyQzBCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gS2V5UHJvbWlzZVF1ZXVlIGlzIGEgc2ltcGxlIHByb21pc2UgcXVldWVcbi8vIHVzZWQgdG8gcXVldWUgb3BlcmF0aW9ucyBwZXIga2V5IGJhc2lzLlxuLy8gT25jZSB0aGUgdGFpbCBwcm9taXNlIGluIHRoZSBrZXktcXVldWUgZnVsZmlsbHMsXG4vLyB0aGUgY2hhaW4gb24gdGhhdCBrZXkgd2lsbCBiZSBjbGVhcmVkLlxuZXhwb3J0IGNsYXNzIEtleVByb21pc2VRdWV1ZSB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMucXVldWUgPSB7fTtcbiAgfVxuXG4gIGVucXVldWUoa2V5LCBvcGVyYXRpb24pIHtcbiAgICBjb25zdCB0dXBsZSA9IHRoaXMuYmVmb3JlT3Aoa2V5KTtcbiAgICBjb25zdCB0b0F3YWl0ID0gdHVwbGVbMV07XG4gICAgY29uc3QgbmV4dE9wZXJhdGlvbiA9IHRvQXdhaXQudGhlbihvcGVyYXRpb24pO1xuICAgIGNvbnN0IHdyYXBwZWRPcGVyYXRpb24gPSBuZXh0T3BlcmF0aW9uLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgIHRoaXMuYWZ0ZXJPcChrZXkpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KTtcbiAgICB0dXBsZVsxXSA9IHdyYXBwZWRPcGVyYXRpb247XG4gICAgcmV0dXJuIHdyYXBwZWRPcGVyYXRpb247XG4gIH1cblxuICBiZWZvcmVPcChrZXkpIHtcbiAgICBsZXQgdHVwbGUgPSB0aGlzLnF1ZXVlW2tleV07XG4gICAgaWYgKCF0dXBsZSkge1xuICAgICAgdHVwbGUgPSBbMCwgUHJvbWlzZS5yZXNvbHZlKCldO1xuICAgICAgdGhpcy5xdWV1ZVtrZXldID0gdHVwbGU7XG4gICAgfVxuICAgIHR1cGxlWzBdKys7XG4gICAgcmV0dXJuIHR1cGxlO1xuICB9XG5cbiAgYWZ0ZXJPcChrZXkpIHtcbiAgICBjb25zdCB0dXBsZSA9IHRoaXMucXVldWVba2V5XTtcbiAgICBpZiAoIXR1cGxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHR1cGxlWzBdLS07XG4gICAgaWYgKHR1cGxlWzBdIDw9IDApIHtcbiAgICAgIGRlbGV0ZSB0aGlzLnF1ZXVlW2tleV07XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Cache/RedisCacheAdapter/index.js b/lib/Adapters/Cache/RedisCacheAdapter/index.js new file mode 100644 index 0000000000..7cf7f4e3e1 --- /dev/null +++ b/lib/Adapters/Cache/RedisCacheAdapter/index.js @@ -0,0 +1,130 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.RedisCacheAdapter = void 0; + +var _redis = _interopRequireDefault(require("redis")); + +var _logger = _interopRequireDefault(require("../../../logger")); + +var _KeyPromiseQueue = require("./KeyPromiseQueue"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const DEFAULT_REDIS_TTL = 30 * 1000; // 30 seconds in milliseconds + +const FLUSH_DB_KEY = '__flush_db__'; + +function debug() { + _logger.default.debug.apply(_logger.default, ['RedisCacheAdapter', ...arguments]); +} + +const isValidTTL = ttl => typeof ttl === 'number' && ttl > 0; + +class RedisCacheAdapter { + constructor(redisCtx, ttl = DEFAULT_REDIS_TTL) { + this.ttl = isValidTTL(ttl) ? ttl : DEFAULT_REDIS_TTL; + this.client = _redis.default.createClient(redisCtx); + this.queue = new _KeyPromiseQueue.KeyPromiseQueue(); + } + + handleShutdown() { + if (!this.client) { + return Promise.resolve(); + } + + return new Promise(resolve => { + this.client.quit(err => { + if (err) { + _logger.default.error('RedisCacheAdapter error on shutdown', { + error: err + }); + } + + resolve(); + }); + }); + } + + get(key) { + debug('get', key); + return this.queue.enqueue(key, () => new Promise(resolve => { + this.client.get(key, function (err, res) { + debug('-> get', key, res); + + if (!res) { + return resolve(null); + } + + resolve(JSON.parse(res)); + }); + })); + } + + put(key, value, ttl = this.ttl) { + value = JSON.stringify(value); + debug('put', key, value, ttl); + + if (ttl === 0) { + // ttl of zero is a logical no-op, but redis cannot set expire time of zero + return this.queue.enqueue(key, () => Promise.resolve()); + } + + if (ttl === Infinity) { + return this.queue.enqueue(key, () => new Promise(resolve => { + this.client.set(key, value, function () { + resolve(); + }); + })); + } + + if (!isValidTTL(ttl)) { + ttl = this.ttl; + } + + return this.queue.enqueue(key, () => new Promise(resolve => { + this.client.psetex(key, ttl, value, function () { + resolve(); + }); + })); + } + + del(key) { + debug('del', key); + return this.queue.enqueue(key, () => new Promise(resolve => { + this.client.del(key, function () { + resolve(); + }); + })); + } + + clear() { + debug('clear'); + return this.queue.enqueue(FLUSH_DB_KEY, () => new Promise(resolve => { + this.client.flushdb(function () { + resolve(); + }); + })); + } // Used for testing + + + async getAllKeys() { + return new Promise((resolve, reject) => { + this.client.keys('*', (err, keys) => { + if (err) { + reject(err); + } else { + resolve(keys); + } + }); + }); + } + +} + +exports.RedisCacheAdapter = RedisCacheAdapter; +var _default = RedisCacheAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9SZWRpc0NhY2hlQWRhcHRlci9pbmRleC5qcyJdLCJuYW1lcyI6WyJERUZBVUxUX1JFRElTX1RUTCIsIkZMVVNIX0RCX0tFWSIsImRlYnVnIiwibG9nZ2VyIiwiYXBwbHkiLCJhcmd1bWVudHMiLCJpc1ZhbGlkVFRMIiwidHRsIiwiUmVkaXNDYWNoZUFkYXB0ZXIiLCJjb25zdHJ1Y3RvciIsInJlZGlzQ3R4IiwiY2xpZW50IiwicmVkaXMiLCJjcmVhdGVDbGllbnQiLCJxdWV1ZSIsIktleVByb21pc2VRdWV1ZSIsImhhbmRsZVNodXRkb3duIiwiUHJvbWlzZSIsInJlc29sdmUiLCJxdWl0IiwiZXJyIiwiZXJyb3IiLCJnZXQiLCJrZXkiLCJlbnF1ZXVlIiwicmVzIiwiSlNPTiIsInBhcnNlIiwicHV0IiwidmFsdWUiLCJzdHJpbmdpZnkiLCJJbmZpbml0eSIsInNldCIsInBzZXRleCIsImRlbCIsImNsZWFyIiwiZmx1c2hkYiIsImdldEFsbEtleXMiLCJyZWplY3QiLCJrZXlzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxNQUFNQSxpQkFBaUIsR0FBRyxLQUFLLElBQS9CLEMsQ0FBcUM7O0FBQ3JDLE1BQU1DLFlBQVksR0FBRyxjQUFyQjs7QUFFQSxTQUFTQyxLQUFULEdBQWlCO0FBQ2ZDLGtCQUFPRCxLQUFQLENBQWFFLEtBQWIsQ0FBbUJELGVBQW5CLEVBQTJCLENBQUMsbUJBQUQsRUFBc0IsR0FBR0UsU0FBekIsQ0FBM0I7QUFDRDs7QUFFRCxNQUFNQyxVQUFVLEdBQUdDLEdBQUcsSUFBSSxPQUFPQSxHQUFQLEtBQWUsUUFBZixJQUEyQkEsR0FBRyxHQUFHLENBQTNEOztBQUVPLE1BQU1DLGlCQUFOLENBQXdCO0FBQzdCQyxFQUFBQSxXQUFXLENBQUNDLFFBQUQsRUFBV0gsR0FBRyxHQUFHUCxpQkFBakIsRUFBb0M7QUFDN0MsU0FBS08sR0FBTCxHQUFXRCxV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Q1gsR0FBRCxFQUFNO0FBQ1ByQixJQUFBQSxLQUFLLENBQUMsS0FBRCxFQUFRcUIsR0FBUixDQUFMO0FBQ0EsV0FBTyxLQUFLVCxLQUFMLENBQVdVLE9BQVgsQ0FDTEQsR0FESyxFQUVMLE1BQ0UsSUFBSU4sT0FBSixDQUFZQyxPQUFPLElBQUk7QUFDckIsV0FBS1AsTUFBTCxDQUFZdUIsR0FBWixDQUFnQlgsR0FBaEIsRUFBcUIsWUFBWTtBQUMvQkwsUUFBQUEsT0FBTztBQUNSLE9BRkQ7QUFHRCxLQUpELENBSEcsQ0FBUDtBQVNEOztBQUVEaUIsRUFBQUEsS0FBSyxHQUFHO0FBQ05qQyxJQUFBQSxLQUFLLENBQUMsT0FBRCxDQUFMO0FBQ0EsV0FBTyxLQUFLWSxLQUFMLENBQVdVLE9BQVgsQ0FDTHZCLFlBREssRUFFTCxNQUNFLElBQUlnQixPQUFKLENBQVlDLE9BQU8sSUFBSTtBQUNyQixXQUFLUCxNQUFMLENBQVl5QixPQUFaLENBQW9CLFlBQVk7QUFDOUJsQixRQUFBQSxPQUFPO0FBQ1IsT0FGRDtBQUdELEtBSkQsQ0FIRyxDQUFQO0FBU0QsR0FsRzRCLENBb0c3Qjs7O0FBQ0EsUUFBTW1CLFVBQU4sR0FBbUI7QUFDakIsV0FBTyxJQUFJcEIsT0FBSixDQUFZLENBQUNDLE9BQUQsRUFBVW9CLE1BQVYsS0FBcUI7QUFDdEMsV0FBSzNCLE1BQUwsQ0FBWTRCLElBQVosQ0FBaUIsR0FBakIsRUFBc0IsQ0FBQ25CLEdBQUQsRUFBTW1CLElBQU4sS0FBZTtBQUNuQyxZQUFJbkIsR0FBSixFQUFTO0FBQ1BrQixVQUFBQSxNQUFNLENBQUNsQixHQUFELENBQU47QUFDRCxTQUZELE1BRU87QUFDTEYsVUFBQUEsT0FBTyxDQUFDcUIsSUFBRCxDQUFQO0FBQ0Q7QUFDRixPQU5EO0FBT0QsS0FSTSxDQUFQO0FBU0Q7O0FBL0c0Qjs7O2VBa0hoQi9CLGlCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHJlZGlzIGZyb20gJ3JlZGlzJztcbmltcG9ydCBsb2dnZXIgZnJvbSAnLi4vLi4vLi4vbG9nZ2VyJztcbmltcG9ydCB7IEtleVByb21pc2VRdWV1ZSB9IGZyb20gJy4vS2V5UHJvbWlzZVF1ZXVlJztcblxuY29uc3QgREVGQVVMVF9SRURJU19UVEwgPSAzMCAqIDEwMDA7IC8vIDMwIHNlY29uZHMgaW4gbWlsbGlzZWNvbmRzXG5jb25zdCBGTFVTSF9EQl9LRVkgPSAnX19mbHVzaF9kYl9fJztcblxuZnVuY3Rpb24gZGVidWcoKSB7XG4gIGxvZ2dlci5kZWJ1Zy5hcHBseShsb2dnZXIsIFsnUmVkaXNDYWNoZUFkYXB0ZXInLCAuLi5hcmd1bWVudHNdKTtcbn1cblxuY29uc3QgaXNWYWxpZFRUTCA9IHR0bCA9PiB0eXBlb2YgdHRsID09PSAnbnVtYmVyJyAmJiB0dGwgPiAwO1xuXG5leHBvcnQgY2xhc3MgUmVkaXNDYWNoZUFkYXB0ZXIge1xuICBjb25zdHJ1Y3RvcihyZWRpc0N0eCwgdHRsID0gREVGQVVMVF9SRURJU19UVEwpIHtcbiAgICB0aGlzLnR0bCA9IGlzVmFsaWRUVEwodHRsKSA/IHR0bCA6IERFRkFVTFRfUkVESVNfVFRMO1xuICAgIHRoaXMuY2xpZW50ID0gcmVkaXMuY3JlYXRlQ2xpZW50KHJlZGlzQ3R4KTtcbiAgICB0aGlzLnF1ZXVlID0gbmV3IEtleVByb21pc2VRdWV1ZSgpO1xuICB9XG5cbiAgaGFuZGxlU2h1dGRvd24oKSB7XG4gICAgaWYgKCF0aGlzLmNsaWVudCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICB0aGlzLmNsaWVudC5xdWl0KGVyciA9PiB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoJ1JlZGlzQ2FjaGVBZGFwdGVyIGVycm9yIG9uIHNodXRkb3duJywgeyBlcnJvcjogZXJyIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0KGtleSkge1xuICAgIGRlYnVnKCdnZXQnLCBrZXkpO1xuICAgIHJldHVybiB0aGlzLnF1ZXVlLmVucXVldWUoXG4gICAgICBrZXksXG4gICAgICAoKSA9PlxuICAgICAgICBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgICAgICB0aGlzLmNsaWVudC5nZXQoa2V5LCBmdW5jdGlvbiAoZXJyLCByZXMpIHtcbiAgICAgICAgICAgIGRlYnVnKCctPiBnZXQnLCBrZXksIHJlcyk7XG4gICAgICAgICAgICBpZiAoIXJlcykge1xuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShudWxsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc29sdmUoSlNPTi5wYXJzZShyZXMpKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgcHV0KGtleSwgdmFsdWUsIHR0bCA9IHRoaXMudHRsKSB7XG4gICAgdmFsdWUgPSBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG4gICAgZGVidWcoJ3B1dCcsIGtleSwgdmFsdWUsIHR0bCk7XG5cbiAgICBpZiAodHRsID09PSAwKSB7XG4gICAgICAvLyB0dGwgb2YgemVybyBpcyBhIGxvZ2ljYWwgbm8tb3AsIGJ1dCByZWRpcyBjYW5ub3Qgc2V0IGV4cGlyZSB0aW1lIG9mIHplcm9cbiAgICAgIHJldHVybiB0aGlzLnF1ZXVlLmVucXVldWUoa2V5LCAoKSA9PiBQcm9taXNlLnJlc29sdmUoKSk7XG4gICAgfVxuXG4gICAgaWYgKHR0bCA9PT0gSW5maW5pdHkpIHtcbiAgICAgIHJldHVybiB0aGlzLnF1ZXVlLmVucXVldWUoXG4gICAgICAgIGtleSxcbiAgICAgICAgKCkgPT5cbiAgICAgICAgICBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2xpZW50LnNldChrZXksIHZhbHVlLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghaXNWYWxpZFRUTCh0dGwpKSB7XG4gICAgICB0dGwgPSB0aGlzLnR0bDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5xdWV1ZS5lbnF1ZXVlKFxuICAgICAga2V5LFxuICAgICAgKCkgPT5cbiAgICAgICAgbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgdGhpcy5jbGllbnQucHNldGV4KGtleSwgdHRsLCB2YWx1ZSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cblxuICBkZWwoa2V5KSB7XG4gICAgZGVidWcoJ2RlbCcsIGtleSk7XG4gICAgcmV0dXJuIHRoaXMucXVldWUuZW5xdWV1ZShcbiAgICAgIGtleSxcbiAgICAgICgpID0+XG4gICAgICAgIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICAgIHRoaXMuY2xpZW50LmRlbChrZXksIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgY2xlYXIoKSB7XG4gICAgZGVidWcoJ2NsZWFyJyk7XG4gICAgcmV0dXJuIHRoaXMucXVldWUuZW5xdWV1ZShcbiAgICAgIEZMVVNIX0RCX0tFWSxcbiAgICAgICgpID0+XG4gICAgICAgIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICAgIHRoaXMuY2xpZW50LmZsdXNoZGIoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvLyBVc2VkIGZvciB0ZXN0aW5nXG4gIGFzeW5jIGdldEFsbEtleXMoKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50LmtleXMoJyonLCAoZXJyLCBrZXlzKSA9PiB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNvbHZlKGtleXMpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBSZWRpc0NhY2hlQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Email/MailAdapter.js b/lib/Adapters/Email/MailAdapter.js new file mode 100644 index 0000000000..a1b3044451 --- /dev/null +++ b/lib/Adapters/Email/MailAdapter.js @@ -0,0 +1,40 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.MailAdapter = void 0; + +/*eslint no-unused-vars: "off"*/ + +/** + * @module Adapters + */ + +/** + * @interface MailAdapter + * Mail Adapter prototype + * A MailAdapter should implement at least sendMail() + */ +class MailAdapter { + /** + * A method for sending mail + * @param options would have the parameters + * - to: the recipient + * - text: the raw text of the message + * - subject: the subject of the email + */ + sendMail(options) {} + /* You can implement those methods if you want + * to provide HTML templates etc... + */ + // sendVerificationEmail({ link, appName, user }) {} + // sendPasswordResetEmail({ link, appName, user }) {} + + +} + +exports.MailAdapter = MailAdapter; +var _default = MailAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9FbWFpbC9NYWlsQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJNYWlsQWRhcHRlciIsInNlbmRNYWlsIiwib3B0aW9ucyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBO0FBQ0E7QUFDQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTUEsV0FBTixDQUFrQjtBQUN2QjtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNFQyxFQUFBQSxRQUFRLENBQUNDLE9BQUQsRUFBVSxDQUFFO0FBRXBCO0FBQ0Y7QUFDQTtBQUNFO0FBQ0E7OztBQWR1Qjs7O2VBaUJWRixXIiwic291cmNlc0NvbnRlbnQiOlsiLyplc2xpbnQgbm8tdW51c2VkLXZhcnM6IFwib2ZmXCIqL1xuLyoqXG4gKiBAbW9kdWxlIEFkYXB0ZXJzXG4gKi9cbi8qKlxuICogQGludGVyZmFjZSBNYWlsQWRhcHRlclxuICogTWFpbCBBZGFwdGVyIHByb3RvdHlwZVxuICogQSBNYWlsQWRhcHRlciBzaG91bGQgaW1wbGVtZW50IGF0IGxlYXN0IHNlbmRNYWlsKClcbiAqL1xuZXhwb3J0IGNsYXNzIE1haWxBZGFwdGVyIHtcbiAgLyoqXG4gICAqIEEgbWV0aG9kIGZvciBzZW5kaW5nIG1haWxcbiAgICogQHBhcmFtIG9wdGlvbnMgd291bGQgaGF2ZSB0aGUgcGFyYW1ldGVyc1xuICAgKiAtIHRvOiB0aGUgcmVjaXBpZW50XG4gICAqIC0gdGV4dDogdGhlIHJhdyB0ZXh0IG9mIHRoZSBtZXNzYWdlXG4gICAqIC0gc3ViamVjdDogdGhlIHN1YmplY3Qgb2YgdGhlIGVtYWlsXG4gICAqL1xuICBzZW5kTWFpbChvcHRpb25zKSB7fVxuXG4gIC8qIFlvdSBjYW4gaW1wbGVtZW50IHRob3NlIG1ldGhvZHMgaWYgeW91IHdhbnRcbiAgICogdG8gcHJvdmlkZSBIVE1MIHRlbXBsYXRlcyBldGMuLi5cbiAgICovXG4gIC8vIHNlbmRWZXJpZmljYXRpb25FbWFpbCh7IGxpbmssIGFwcE5hbWUsIHVzZXIgfSkge31cbiAgLy8gc2VuZFBhc3N3b3JkUmVzZXRFbWFpbCh7IGxpbmssIGFwcE5hbWUsIHVzZXIgfSkge31cbn1cblxuZXhwb3J0IGRlZmF1bHQgTWFpbEFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Files/FilesAdapter.js b/lib/Adapters/Files/FilesAdapter.js new file mode 100644 index 0000000000..112ca8202e --- /dev/null +++ b/lib/Adapters/Files/FilesAdapter.js @@ -0,0 +1,136 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.validateFilename = validateFilename; +exports.default = exports.FilesAdapter = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/*eslint no-unused-vars: "off"*/ +// Files Adapter +// +// Allows you to change the file storage mechanism. +// +// Adapter classes must implement the following functions: +// * createFile(filename, data, contentType) +// * deleteFile(filename) +// * getFileData(filename) +// * getFileLocation(config, filename) +// Adapter classes should implement the following functions: +// * validateFilename(filename) +// * handleFileStream(filename, req, res, contentType) +// +// Default is GridFSBucketAdapter, which requires mongo +// and for the API server to be using the DatabaseController with Mongo +// database adapter. + +/** + * @module Adapters + */ + +/** + * @interface FilesAdapter + */ +class FilesAdapter { + /** Responsible for storing the file in order to be retrieved later by its filename + * + * @param {string} filename - the filename to save + * @param {*} data - the buffer of data from the file + * @param {string} contentType - the supposed contentType + * @discussion the contentType can be undefined if the controller was not able to determine it + * @param {object} options - (Optional) options to be passed to file adapter (S3 File Adapter Only) + * - tags: object containing key value pairs that will be stored with file + * - metadata: object containing key value pairs that will be sotred with file (https://docs.aws.amazon.com/AmazonS3/latest/user-guide/add-object-metadata.html) + * @discussion options are not supported by all file adapters. Check the your adapter's documentation for compatibility + * + * @return {Promise} a promise that should fail if the storage didn't succeed + */ + createFile(filename, data, contentType, options) {} + /** Responsible for deleting the specified file + * + * @param {string} filename - the filename to delete + * + * @return {Promise} a promise that should fail if the deletion didn't succeed + */ + + + deleteFile(filename) {} + /** Responsible for retrieving the data of the specified file + * + * @param {string} filename - the name of file to retrieve + * + * @return {Promise} a promise that should pass with the file data or fail on error + */ + + + getFileData(filename) {} + /** Returns an absolute URL where the file can be accessed + * + * @param {Config} config - server configuration + * @param {string} filename + * + * @return {string} Absolute URL + */ + + + getFileLocation(config, filename) {} + /** Validate a filename for this adapter type + * + * @param {string} filename + * + * @returns {null|Parse.Error} null if there are no errors + */ + // validateFilename(filename: string): ?Parse.Error {} + + /** Handles Byte-Range Requests for Streaming + * + * @param {string} filename + * @param {object} req + * @param {object} res + * @param {string} contentType + * + * @returns {Promise} Data for byte range + */ + // handleFileStream(filename: string, res: any, req: any, contentType: string): Promise + + /** Responsible for retrieving metadata and tags + * + * @param {string} filename - the filename to retrieve metadata + * + * @return {Promise} a promise that should pass with metadata + */ + // getMetadata(filename: string): Promise {} + + +} +/** + * Simple filename validation + * + * @param filename + * @returns {null|Parse.Error} + */ + + +exports.FilesAdapter = FilesAdapter; + +function validateFilename(filename) { + if (filename.length > 128) { + return new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename too long.'); + } + + const regx = /^[_a-zA-Z0-9][a-zA-Z0-9@. ~_-]*$/; + + if (!filename.match(regx)) { + return new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename contains invalid characters.'); + } + + return null; +} + +var _default = FilesAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9GaWxlcy9GaWxlc0FkYXB0ZXIuanMiXSwibmFtZXMiOlsiRmlsZXNBZGFwdGVyIiwiY3JlYXRlRmlsZSIsImZpbGVuYW1lIiwiZGF0YSIsImNvbnRlbnRUeXBlIiwib3B0aW9ucyIsImRlbGV0ZUZpbGUiLCJnZXRGaWxlRGF0YSIsImdldEZpbGVMb2NhdGlvbiIsImNvbmZpZyIsInZhbGlkYXRlRmlsZW5hbWUiLCJsZW5ndGgiLCJQYXJzZSIsIkVycm9yIiwiSU5WQUxJRF9GSUxFX05BTUUiLCJyZWd4IiwibWF0Y2giXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBbUJBOzs7O0FBbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBSUE7QUFDQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU1BLFlBQU4sQ0FBbUI7QUFDeEI7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDRUMsRUFBQUEsVUFBVSxDQUFDQyxRQUFELEVBQW1CQyxJQUFuQixFQUF5QkMsV0FBekIsRUFBOENDLE9BQTlDLEVBQXdFLENBQUU7QUFFcEY7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDRUMsRUFBQUEsVUFBVSxDQUFDSixRQUFELEVBQTRCLENBQUU7QUFFeEM7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDRUssRUFBQUEsV0FBVyxDQUFDTCxRQUFELEVBQWlDLENBQUU7QUFFOUM7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNFTSxFQUFBQSxlQUFlLENBQUNDLE1BQUQsRUFBaUJQLFFBQWpCLEVBQTJDLENBQUU7QUFFNUQ7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0U7O0FBRUE7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0U7O0FBRUE7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0U7OztBQWxFd0I7QUFxRTFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFDTyxTQUFTUSxnQkFBVCxDQUEwQlIsUUFBMUIsRUFBa0Q7QUFDdkQsTUFBSUEsUUFBUSxDQUFDUyxNQUFULEdBQWtCLEdBQXRCLEVBQTJCO0FBQ3pCLFdBQU8sSUFBSUMsY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZQyxpQkFBNUIsRUFBK0Msb0JBQS9DLENBQVA7QUFDRDs7QUFFRCxRQUFNQyxJQUFJLEdBQUcsa0NBQWI7O0FBQ0EsTUFBSSxDQUFDYixRQUFRLENBQUNjLEtBQVQsQ0FBZUQsSUFBZixDQUFMLEVBQTJCO0FBQ3pCLFdBQU8sSUFBSUgsY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZQyxpQkFBNUIsRUFBK0MsdUNBQS9DLENBQVA7QUFDRDs7QUFDRCxTQUFPLElBQVA7QUFDRDs7ZUFFY2QsWSIsInNvdXJjZXNDb250ZW50IjpbIi8qZXNsaW50IG5vLXVudXNlZC12YXJzOiBcIm9mZlwiKi9cbi8vIEZpbGVzIEFkYXB0ZXJcbi8vXG4vLyBBbGxvd3MgeW91IHRvIGNoYW5nZSB0aGUgZmlsZSBzdG9yYWdlIG1lY2hhbmlzbS5cbi8vXG4vLyBBZGFwdGVyIGNsYXNzZXMgbXVzdCBpbXBsZW1lbnQgdGhlIGZvbGxvd2luZyBmdW5jdGlvbnM6XG4vLyAqIGNyZWF0ZUZpbGUoZmlsZW5hbWUsIGRhdGEsIGNvbnRlbnRUeXBlKVxuLy8gKiBkZWxldGVGaWxlKGZpbGVuYW1lKVxuLy8gKiBnZXRGaWxlRGF0YShmaWxlbmFtZSlcbi8vICogZ2V0RmlsZUxvY2F0aW9uKGNvbmZpZywgZmlsZW5hbWUpXG4vLyBBZGFwdGVyIGNsYXNzZXMgc2hvdWxkIGltcGxlbWVudCB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uczpcbi8vICogdmFsaWRhdGVGaWxlbmFtZShmaWxlbmFtZSlcbi8vICogaGFuZGxlRmlsZVN0cmVhbShmaWxlbmFtZSwgcmVxLCByZXMsIGNvbnRlbnRUeXBlKVxuLy9cbi8vIERlZmF1bHQgaXMgR3JpZEZTQnVja2V0QWRhcHRlciwgd2hpY2ggcmVxdWlyZXMgbW9uZ29cbi8vIGFuZCBmb3IgdGhlIEFQSSBzZXJ2ZXIgdG8gYmUgdXNpbmcgdGhlIERhdGFiYXNlQ29udHJvbGxlciB3aXRoIE1vbmdvXG4vLyBkYXRhYmFzZSBhZGFwdGVyLlxuXG5pbXBvcnQgdHlwZSB7IENvbmZpZyB9IGZyb20gJy4uLy4uL0NvbmZpZyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG4vKipcbiAqIEBtb2R1bGUgQWRhcHRlcnNcbiAqL1xuLyoqXG4gKiBAaW50ZXJmYWNlIEZpbGVzQWRhcHRlclxuICovXG5leHBvcnQgY2xhc3MgRmlsZXNBZGFwdGVyIHtcbiAgLyoqIFJlc3BvbnNpYmxlIGZvciBzdG9yaW5nIHRoZSBmaWxlIGluIG9yZGVyIHRvIGJlIHJldHJpZXZlZCBsYXRlciBieSBpdHMgZmlsZW5hbWVcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gdGhlIGZpbGVuYW1lIHRvIHNhdmVcbiAgICogQHBhcmFtIHsqfSBkYXRhIC0gdGhlIGJ1ZmZlciBvZiBkYXRhIGZyb20gdGhlIGZpbGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNvbnRlbnRUeXBlIC0gdGhlIHN1cHBvc2VkIGNvbnRlbnRUeXBlXG4gICAqIEBkaXNjdXNzaW9uIHRoZSBjb250ZW50VHlwZSBjYW4gYmUgdW5kZWZpbmVkIGlmIHRoZSBjb250cm9sbGVyIHdhcyBub3QgYWJsZSB0byBkZXRlcm1pbmUgaXRcbiAgICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnMgLSAoT3B0aW9uYWwpIG9wdGlvbnMgdG8gYmUgcGFzc2VkIHRvIGZpbGUgYWRhcHRlciAoUzMgRmlsZSBBZGFwdGVyIE9ubHkpXG4gICAqIC0gdGFnczogb2JqZWN0IGNvbnRhaW5pbmcga2V5IHZhbHVlIHBhaXJzIHRoYXQgd2lsbCBiZSBzdG9yZWQgd2l0aCBmaWxlXG4gICAqIC0gbWV0YWRhdGE6IG9iamVjdCBjb250YWluaW5nIGtleSB2YWx1ZSBwYWlycyB0aGF0IHdpbGwgYmUgc290cmVkIHdpdGggZmlsZSAoaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvblMzL2xhdGVzdC91c2VyLWd1aWRlL2FkZC1vYmplY3QtbWV0YWRhdGEuaHRtbClcbiAgICogQGRpc2N1c3Npb24gb3B0aW9ucyBhcmUgbm90IHN1cHBvcnRlZCBieSBhbGwgZmlsZSBhZGFwdGVycy4gQ2hlY2sgdGhlIHlvdXIgYWRhcHRlcidzIGRvY3VtZW50YXRpb24gZm9yIGNvbXBhdGliaWxpdHlcbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZX0gYSBwcm9taXNlIHRoYXQgc2hvdWxkIGZhaWwgaWYgdGhlIHN0b3JhZ2UgZGlkbid0IHN1Y2NlZWRcbiAgICovXG4gIGNyZWF0ZUZpbGUoZmlsZW5hbWU6IHN0cmluZywgZGF0YSwgY29udGVudFR5cGU6IHN0cmluZywgb3B0aW9uczogT2JqZWN0KTogUHJvbWlzZSB7fVxuXG4gIC8qKiBSZXNwb25zaWJsZSBmb3IgZGVsZXRpbmcgdGhlIHNwZWNpZmllZCBmaWxlXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIHRoZSBmaWxlbmFtZSB0byBkZWxldGVcbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZX0gYSBwcm9taXNlIHRoYXQgc2hvdWxkIGZhaWwgaWYgdGhlIGRlbGV0aW9uIGRpZG4ndCBzdWNjZWVkXG4gICAqL1xuICBkZWxldGVGaWxlKGZpbGVuYW1lOiBzdHJpbmcpOiBQcm9taXNlIHt9XG5cbiAgLyoqIFJlc3BvbnNpYmxlIGZvciByZXRyaWV2aW5nIHRoZSBkYXRhIG9mIHRoZSBzcGVjaWZpZWQgZmlsZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSB0aGUgbmFtZSBvZiBmaWxlIHRvIHJldHJpZXZlXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IGEgcHJvbWlzZSB0aGF0IHNob3VsZCBwYXNzIHdpdGggdGhlIGZpbGUgZGF0YSBvciBmYWlsIG9uIGVycm9yXG4gICAqL1xuICBnZXRGaWxlRGF0YShmaWxlbmFtZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHt9XG5cbiAgLyoqIFJldHVybnMgYW4gYWJzb2x1dGUgVVJMIHdoZXJlIHRoZSBmaWxlIGNhbiBiZSBhY2Nlc3NlZFxuICAgKlxuICAgKiBAcGFyYW0ge0NvbmZpZ30gY29uZmlnIC0gc2VydmVyIGNvbmZpZ3VyYXRpb25cbiAgICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZ30gQWJzb2x1dGUgVVJMXG4gICAqL1xuICBnZXRGaWxlTG9jYXRpb24oY29uZmlnOiBDb25maWcsIGZpbGVuYW1lOiBzdHJpbmcpOiBzdHJpbmcge31cblxuICAvKiogVmFsaWRhdGUgYSBmaWxlbmFtZSBmb3IgdGhpcyBhZGFwdGVyIHR5cGVcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lXG4gICAqXG4gICAqIEByZXR1cm5zIHtudWxsfFBhcnNlLkVycm9yfSBudWxsIGlmIHRoZXJlIGFyZSBubyBlcnJvcnNcbiAgICovXG4gIC8vIHZhbGlkYXRlRmlsZW5hbWUoZmlsZW5hbWU6IHN0cmluZyk6ID9QYXJzZS5FcnJvciB7fVxuXG4gIC8qKiBIYW5kbGVzIEJ5dGUtUmFuZ2UgUmVxdWVzdHMgZm9yIFN0cmVhbWluZ1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWVcbiAgICogQHBhcmFtIHtvYmplY3R9IHJlcVxuICAgKiBAcGFyYW0ge29iamVjdH0gcmVzXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZW50VHlwZVxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gRGF0YSBmb3IgYnl0ZSByYW5nZVxuICAgKi9cbiAgLy8gaGFuZGxlRmlsZVN0cmVhbShmaWxlbmFtZTogc3RyaW5nLCByZXM6IGFueSwgcmVxOiBhbnksIGNvbnRlbnRUeXBlOiBzdHJpbmcpOiBQcm9taXNlXG5cbiAgLyoqIFJlc3BvbnNpYmxlIGZvciByZXRyaWV2aW5nIG1ldGFkYXRhIGFuZCB0YWdzXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIHRoZSBmaWxlbmFtZSB0byByZXRyaWV2ZSBtZXRhZGF0YVxuICAgKlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBhIHByb21pc2UgdGhhdCBzaG91bGQgcGFzcyB3aXRoIG1ldGFkYXRhXG4gICAqL1xuICAvLyBnZXRNZXRhZGF0YShmaWxlbmFtZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHt9XG59XG5cbi8qKlxuICogU2ltcGxlIGZpbGVuYW1lIHZhbGlkYXRpb25cbiAqXG4gKiBAcGFyYW0gZmlsZW5hbWVcbiAqIEByZXR1cm5zIHtudWxsfFBhcnNlLkVycm9yfVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVGaWxlbmFtZShmaWxlbmFtZSk6ID9QYXJzZS5FcnJvciB7XG4gIGlmIChmaWxlbmFtZS5sZW5ndGggPiAxMjgpIHtcbiAgICByZXR1cm4gbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfRklMRV9OQU1FLCAnRmlsZW5hbWUgdG9vIGxvbmcuJyk7XG4gIH1cblxuICBjb25zdCByZWd4ID0gL15bX2EtekEtWjAtOV1bYS16QS1aMC05QC4gfl8tXSokLztcbiAgaWYgKCFmaWxlbmFtZS5tYXRjaChyZWd4KSkge1xuICAgIHJldHVybiBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9GSUxFX05BTUUsICdGaWxlbmFtZSBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcnMuJyk7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbmV4cG9ydCBkZWZhdWx0IEZpbGVzQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Files/GridFSBucketAdapter.js b/lib/Adapters/Files/GridFSBucketAdapter.js new file mode 100644 index 0000000000..352922c2e0 --- /dev/null +++ b/lib/Adapters/Files/GridFSBucketAdapter.js @@ -0,0 +1,273 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.GridFSBucketAdapter = void 0; + +var _mongodb = require("mongodb"); + +var _FilesAdapter = require("./FilesAdapter"); + +var _defaults = _interopRequireDefault(require("../../defaults")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + GridFSBucketAdapter + Stores files in Mongo using GridStore + Requires the database adapter to be based on mongoclient + + + */ +// -disable-next +const crypto = require('crypto'); + +class GridFSBucketAdapter extends _FilesAdapter.FilesAdapter { + constructor(mongoDatabaseURI = _defaults.default.DefaultMongoURI, mongoOptions = {}, encryptionKey = undefined) { + super(); + this._databaseURI = mongoDatabaseURI; + this._algorithm = 'aes-256-gcm'; + this._encryptionKey = encryptionKey !== undefined ? crypto.createHash('sha256').update(String(encryptionKey)).digest('base64').substr(0, 32) : null; + const defaultMongoOptions = { + useNewUrlParser: true, + useUnifiedTopology: true + }; + this._mongoOptions = Object.assign(defaultMongoOptions, mongoOptions); + } + + _connect() { + if (!this._connectionPromise) { + this._connectionPromise = _mongodb.MongoClient.connect(this._databaseURI, this._mongoOptions).then(client => { + this._client = client; + return client.db(client.s.options.dbName); + }); + } + + return this._connectionPromise; + } + + _getBucket() { + return this._connect().then(database => new _mongodb.GridFSBucket(database)); + } // For a given config object, filename, and data, store a file + // Returns a promise + + + async createFile(filename, data, contentType, options = {}) { + const bucket = await this._getBucket(); + const stream = await bucket.openUploadStream(filename, { + metadata: options.metadata + }); + + if (this._encryptionKey !== null) { + try { + const iv = crypto.randomBytes(16); + const cipher = crypto.createCipheriv(this._algorithm, this._encryptionKey, iv); + const encryptedResult = Buffer.concat([cipher.update(data), cipher.final(), iv, cipher.getAuthTag()]); + await stream.write(encryptedResult); + } catch (err) { + return new Promise((resolve, reject) => { + return reject(err); + }); + } + } else { + await stream.write(data); + } + + stream.end(); + return new Promise((resolve, reject) => { + stream.on('finish', resolve); + stream.on('error', reject); + }); + } + + async deleteFile(filename) { + const bucket = await this._getBucket(); + const documents = await bucket.find({ + filename + }).toArray(); + + if (documents.length === 0) { + throw new Error('FileNotFound'); + } + + return Promise.all(documents.map(doc => { + return bucket.delete(doc._id); + })); + } + + async getFileData(filename) { + const bucket = await this._getBucket(); + const stream = bucket.openDownloadStreamByName(filename); + stream.read(); + return new Promise((resolve, reject) => { + const chunks = []; + stream.on('data', data => { + chunks.push(data); + }); + stream.on('end', () => { + const data = Buffer.concat(chunks); + + if (this._encryptionKey !== null) { + try { + const authTagLocation = data.length - 16; + const ivLocation = data.length - 32; + const authTag = data.slice(authTagLocation); + const iv = data.slice(ivLocation, authTagLocation); + const encrypted = data.slice(0, ivLocation); + const decipher = crypto.createDecipheriv(this._algorithm, this._encryptionKey, iv); + decipher.setAuthTag(authTag); + const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]); + return resolve(decrypted); + } catch (err) { + return reject(err); + } + } + + resolve(data); + }); + stream.on('error', err => { + reject(err); + }); + }); + } + + async rotateEncryptionKey(options = {}) { + var fileNames = []; + var oldKeyFileAdapter = {}; + const bucket = await this._getBucket(); + + if (options.oldKey !== undefined) { + oldKeyFileAdapter = new GridFSBucketAdapter(this._databaseURI, this._mongoOptions, options.oldKey); + } else { + oldKeyFileAdapter = new GridFSBucketAdapter(this._databaseURI, this._mongoOptions); + } + + if (options.fileNames !== undefined) { + fileNames = options.fileNames; + } else { + const fileNamesIterator = await bucket.find().toArray(); + fileNamesIterator.forEach(file => { + fileNames.push(file.filename); + }); + } + + return new Promise(resolve => { + var fileNamesNotRotated = fileNames; + var fileNamesRotated = []; + var fileNameTotal = fileNames.length; + var fileNameIndex = 0; + fileNames.forEach(fileName => { + oldKeyFileAdapter.getFileData(fileName).then(plainTextData => { + //Overwrite file with data encrypted with new key + this.createFile(fileName, plainTextData).then(() => { + fileNamesRotated.push(fileName); + fileNamesNotRotated = fileNamesNotRotated.filter(function (value) { + return value !== fileName; + }); + fileNameIndex += 1; + + if (fileNameIndex == fileNameTotal) { + resolve({ + rotated: fileNamesRotated, + notRotated: fileNamesNotRotated + }); + } + }).catch(() => { + fileNameIndex += 1; + + if (fileNameIndex == fileNameTotal) { + resolve({ + rotated: fileNamesRotated, + notRotated: fileNamesNotRotated + }); + } + }); + }).catch(() => { + fileNameIndex += 1; + + if (fileNameIndex == fileNameTotal) { + resolve({ + rotated: fileNamesRotated, + notRotated: fileNamesNotRotated + }); + } + }); + }); + }); + } + + getFileLocation(config, filename) { + return config.mount + '/files/' + config.applicationId + '/' + encodeURIComponent(filename); + } + + async getMetadata(filename) { + const bucket = await this._getBucket(); + const files = await bucket.find({ + filename + }).toArray(); + + if (files.length === 0) { + return {}; + } + + const { + metadata + } = files[0]; + return { + metadata + }; + } + + async handleFileStream(filename, req, res, contentType) { + const bucket = await this._getBucket(); + const files = await bucket.find({ + filename + }).toArray(); + + if (files.length === 0) { + throw new Error('FileNotFound'); + } + + const parts = req.get('Range').replace(/bytes=/, '').split('-'); + const partialstart = parts[0]; + const partialend = parts[1]; + const start = parseInt(partialstart, 10); + const end = partialend ? parseInt(partialend, 10) : files[0].length - 1; + res.writeHead(206, { + 'Accept-Ranges': 'bytes', + 'Content-Length': end - start + 1, + 'Content-Range': 'bytes ' + start + '-' + end + '/' + files[0].length, + 'Content-Type': contentType + }); + const stream = bucket.openDownloadStreamByName(filename); + stream.start(start); + stream.on('data', chunk => { + res.write(chunk); + }); + stream.on('error', () => { + res.sendStatus(404); + }); + stream.on('end', () => { + res.end(); + }); + } + + handleShutdown() { + if (!this._client) { + return Promise.resolve(); + } + + return this._client.close(false); + } + + validateFilename(filename) { + return (0, _FilesAdapter.validateFilename)(filename); + } + +} + +exports.GridFSBucketAdapter = GridFSBucketAdapter; +var _default = GridFSBucketAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9GaWxlcy9HcmlkRlNCdWNrZXRBZGFwdGVyLmpzIl0sIm5hbWVzIjpbImNyeXB0byIsInJlcXVpcmUiLCJHcmlkRlNCdWNrZXRBZGFwdGVyIiwiRmlsZXNBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJtb25nb0RhdGFiYXNlVVJJIiwiZGVmYXVsdHMiLCJEZWZhdWx0TW9uZ29VUkkiLCJtb25nb09wdGlvbnMiLCJlbmNyeXB0aW9uS2V5IiwidW5kZWZpbmVkIiwiX2RhdGFiYXNlVVJJIiwiX2FsZ29yaXRobSIsIl9lbmNyeXB0aW9uS2V5IiwiY3JlYXRlSGFzaCIsInVwZGF0ZSIsIlN0cmluZyIsImRpZ2VzdCIsInN1YnN0ciIsImRlZmF1bHRNb25nb09wdGlvbnMiLCJ1c2VOZXdVcmxQYXJzZXIiLCJ1c2VVbmlmaWVkVG9wb2xvZ3kiLCJfbW9uZ29PcHRpb25zIiwiT2JqZWN0IiwiYXNzaWduIiwiX2Nvbm5lY3QiLCJfY29ubmVjdGlvblByb21pc2UiLCJNb25nb0NsaWVudCIsImNvbm5lY3QiLCJ0aGVuIiwiY2xpZW50IiwiX2NsaWVudCIsImRiIiwicyIsIm9wdGlvbnMiLCJkYk5hbWUiLCJfZ2V0QnVja2V0IiwiZGF0YWJhc2UiLCJHcmlkRlNCdWNrZXQiLCJjcmVhdGVGaWxlIiwiZmlsZW5hbWUiLCJkYXRhIiwiY29udGVudFR5cGUiLCJidWNrZXQiLCJzdHJlYW0iLCJvcGVuVXBsb2FkU3RyZWFtIiwibWV0YWRhdGEiLCJpdiIsInJhbmRvbUJ5dGVzIiwiY2lwaGVyIiwiY3JlYXRlQ2lwaGVyaXYiLCJlbmNyeXB0ZWRSZXN1bHQiLCJCdWZmZXIiLCJjb25jYXQiLCJmaW5hbCIsImdldEF1dGhUYWciLCJ3cml0ZSIsImVyciIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiZW5kIiwib24iLCJkZWxldGVGaWxlIiwiZG9jdW1lbnRzIiwiZmluZCIsInRvQXJyYXkiLCJsZW5ndGgiLCJFcnJvciIsImFsbCIsIm1hcCIsImRvYyIsImRlbGV0ZSIsIl9pZCIsImdldEZpbGVEYXRhIiwib3BlbkRvd25sb2FkU3RyZWFtQnlOYW1lIiwicmVhZCIsImNodW5rcyIsInB1c2giLCJhdXRoVGFnTG9jYXRpb24iLCJpdkxvY2F0aW9uIiwiYXV0aFRhZyIsInNsaWNlIiwiZW5jcnlwdGVkIiwiZGVjaXBoZXIiLCJjcmVhdGVEZWNpcGhlcml2Iiwic2V0QXV0aFRhZyIsImRlY3J5cHRlZCIsInJvdGF0ZUVuY3J5cHRpb25LZXkiLCJmaWxlTmFtZXMiLCJvbGRLZXlGaWxlQWRhcHRlciIsIm9sZEtleSIsImZpbGVOYW1lc0l0ZXJhdG9yIiwiZm9yRWFjaCIsImZpbGUiLCJmaWxlTmFtZXNOb3RSb3RhdGVkIiwiZmlsZU5hbWVzUm90YXRlZCIsImZpbGVOYW1lVG90YWwiLCJmaWxlTmFtZUluZGV4IiwiZmlsZU5hbWUiLCJwbGFpblRleHREYXRhIiwiZmlsdGVyIiwidmFsdWUiLCJyb3RhdGVkIiwibm90Um90YXRlZCIsImNhdGNoIiwiZ2V0RmlsZUxvY2F0aW9uIiwiY29uZmlnIiwibW91bnQiLCJhcHBsaWNhdGlvbklkIiwiZW5jb2RlVVJJQ29tcG9uZW50IiwiZ2V0TWV0YWRhdGEiLCJmaWxlcyIsImhhbmRsZUZpbGVTdHJlYW0iLCJyZXEiLCJyZXMiLCJwYXJ0cyIsImdldCIsInJlcGxhY2UiLCJzcGxpdCIsInBhcnRpYWxzdGFydCIsInBhcnRpYWxlbmQiLCJzdGFydCIsInBhcnNlSW50Iiwid3JpdGVIZWFkIiwiY2h1bmsiLCJzZW5kU3RhdHVzIiwiaGFuZGxlU2h1dGRvd24iLCJjbG9zZSIsInZhbGlkYXRlRmlsZW5hbWUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFTQTs7QUFDQTs7QUFDQTs7OztBQVhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFJQSxNQUFNQSxNQUFNLEdBQUdDLE9BQU8sQ0FBQyxRQUFELENBQXRCOztBQUVPLE1BQU1DLG1CQUFOLFNBQWtDQywwQkFBbEMsQ0FBK0M7QUFN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QUk7QUFDekJWLE1BQUFBLEdBQUcsQ0FBQzNELEtBQUosQ0FBVXFFLEtBQVY7QUFDRCxLQUZEO0FBR0FqRixJQUFBQSxNQUFNLENBQUNrQixFQUFQLENBQVUsT0FBVixFQUFtQixNQUFNO0FBQ3ZCcUQsTUFBQUEsR0FBRyxDQUFDVyxVQUFKLENBQWUsR0FBZjtBQUNELEtBRkQ7QUFHQWxGLElBQUFBLE1BQU0sQ0FBQ2tCLEVBQVAsQ0FBVSxLQUFWLEVBQWlCLE1BQU07QUFDckJxRCxNQUFBQSxHQUFHLENBQUN0RCxHQUFKO0FBQ0QsS0FGRDtBQUdEOztBQUVEa0UsRUFBQUEsY0FBYyxHQUFHO0FBQ2YsUUFBSSxDQUFDLEtBQUtoRyxPQUFWLEVBQW1CO0FBQ2pCLGFBQU8yQixPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUNELFdBQU8sS0FBSzVCLE9BQUwsQ0FBYWlHLEtBQWIsQ0FBbUIsS0FBbkIsQ0FBUDtBQUNEOztBQUVEQyxFQUFBQSxnQkFBZ0IsQ0FBQ3pGLFFBQUQsRUFBVztBQUN6QixXQUFPLG9DQUFpQkEsUUFBakIsQ0FBUDtBQUNEOztBQXZQbUQ7OztlQTBQdkN0QyxtQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuIEdyaWRGU0J1Y2tldEFkYXB0ZXJcbiBTdG9yZXMgZmlsZXMgaW4gTW9uZ28gdXNpbmcgR3JpZFN0b3JlXG4gUmVxdWlyZXMgdGhlIGRhdGFiYXNlIGFkYXB0ZXIgdG8gYmUgYmFzZWQgb24gbW9uZ29jbGllbnRcblxuIEBmbG93IHdlYWtcbiAqL1xuXG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCB7IE1vbmdvQ2xpZW50LCBHcmlkRlNCdWNrZXQsIERiIH0gZnJvbSAnbW9uZ29kYic7XG5pbXBvcnQgeyBGaWxlc0FkYXB0ZXIsIHZhbGlkYXRlRmlsZW5hbWUgfSBmcm9tICcuL0ZpbGVzQWRhcHRlcic7XG5pbXBvcnQgZGVmYXVsdHMgZnJvbSAnLi4vLi4vZGVmYXVsdHMnO1xuY29uc3QgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG5cbmV4cG9ydCBjbGFzcyBHcmlkRlNCdWNrZXRBZGFwdGVyIGV4dGVuZHMgRmlsZXNBZGFwdGVyIHtcbiAgX2RhdGFiYXNlVVJJOiBzdHJpbmc7XG4gIF9jb25uZWN0aW9uUHJvbWlzZTogUHJvbWlzZTxEYj47XG4gIF9tb25nb09wdGlvbnM6IE9iamVjdDtcbiAgX2FsZ29yaXRobTogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIG1vbmdvRGF0YWJhc2VVUkkgPSBkZWZhdWx0cy5EZWZhdWx0TW9uZ29VUkksXG4gICAgbW9uZ29PcHRpb25zID0ge30sXG4gICAgZW5jcnlwdGlvbktleSA9IHVuZGVmaW5lZFxuICApIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX2RhdGFiYXNlVVJJID0gbW9uZ29EYXRhYmFzZVVSSTtcbiAgICB0aGlzLl9hbGdvcml0aG0gPSAnYWVzLTI1Ni1nY20nO1xuICAgIHRoaXMuX2VuY3J5cHRpb25LZXkgPVxuICAgICAgZW5jcnlwdGlvbktleSAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8gY3J5cHRvLmNyZWF0ZUhhc2goJ3NoYTI1NicpLnVwZGF0ZShTdHJpbmcoZW5jcnlwdGlvbktleSkpLmRpZ2VzdCgnYmFzZTY0Jykuc3Vic3RyKDAsIDMyKVxuICAgICAgICA6IG51bGw7XG4gICAgY29uc3QgZGVmYXVsdE1vbmdvT3B0aW9ucyA9IHtcbiAgICAgIHVzZU5ld1VybFBhcnNlcjogdHJ1ZSxcbiAgICAgIHVzZVVuaWZpZWRUb3BvbG9neTogdHJ1ZSxcbiAgICB9O1xuICAgIHRoaXMuX21vbmdvT3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oZGVmYXVsdE1vbmdvT3B0aW9ucywgbW9uZ29PcHRpb25zKTtcbiAgfVxuXG4gIF9jb25uZWN0KCkge1xuICAgIGlmICghdGhpcy5fY29ubmVjdGlvblByb21pc2UpIHtcbiAgICAgIHRoaXMuX2Nvbm5lY3Rpb25Qcm9taXNlID0gTW9uZ29DbGllbnQuY29ubmVjdCh0aGlzLl9kYXRhYmFzZVVSSSwgdGhpcy5fbW9uZ29PcHRpb25zKS50aGVuKFxuICAgICAgICBjbGllbnQgPT4ge1xuICAgICAgICAgIHRoaXMuX2NsaWVudCA9IGNsaWVudDtcbiAgICAgICAgICByZXR1cm4gY2xpZW50LmRiKGNsaWVudC5zLm9wdGlvbnMuZGJOYW1lKTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2Nvbm5lY3Rpb25Qcm9taXNlO1xuICB9XG5cbiAgX2dldEJ1Y2tldCgpIHtcbiAgICByZXR1cm4gdGhpcy5fY29ubmVjdCgpLnRoZW4oZGF0YWJhc2UgPT4gbmV3IEdyaWRGU0J1Y2tldChkYXRhYmFzZSkpO1xuICB9XG5cbiAgLy8gRm9yIGEgZ2l2ZW4gY29uZmlnIG9iamVjdCwgZmlsZW5hbWUsIGFuZCBkYXRhLCBzdG9yZSBhIGZpbGVcbiAgLy8gUmV0dXJucyBhIHByb21pc2VcbiAgYXN5bmMgY3JlYXRlRmlsZShmaWxlbmFtZTogc3RyaW5nLCBkYXRhLCBjb250ZW50VHlwZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgYnVja2V0ID0gYXdhaXQgdGhpcy5fZ2V0QnVja2V0KCk7XG4gICAgY29uc3Qgc3RyZWFtID0gYXdhaXQgYnVja2V0Lm9wZW5VcGxvYWRTdHJlYW0oZmlsZW5hbWUsIHtcbiAgICAgIG1ldGFkYXRhOiBvcHRpb25zLm1ldGFkYXRhLFxuICAgIH0pO1xuICAgIGlmICh0aGlzLl9lbmNyeXB0aW9uS2V5ICE9PSBudWxsKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBpdiA9IGNyeXB0by5yYW5kb21CeXRlcygxNik7XG4gICAgICAgIGNvbnN0IGNpcGhlciA9IGNyeXB0by5jcmVhdGVDaXBoZXJpdih0aGlzLl9hbGdvcml0aG0sIHRoaXMuX2VuY3J5cHRpb25LZXksIGl2KTtcbiAgICAgICAgY29uc3QgZW5jcnlwdGVkUmVzdWx0ID0gQnVmZmVyLmNvbmNhdChbXG4gICAgICAgICAgY2lwaGVyLnVwZGF0ZShkYXRhKSxcbiAgICAgICAgICBjaXBoZXIuZmluYWwoKSxcbiAgICAgICAgICBpdixcbiAgICAgICAgICBjaXBoZXIuZ2V0QXV0aFRhZygpLFxuICAgICAgICBdKTtcbiAgICAgICAgYXdhaXQgc3RyZWFtLndyaXRlKGVuY3J5cHRlZFJlc3VsdCk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBhd2FpdCBzdHJlYW0ud3JpdGUoZGF0YSk7XG4gICAgfVxuICAgIHN0cmVhbS5lbmQoKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgc3RyZWFtLm9uKCdmaW5pc2gnLCByZXNvbHZlKTtcbiAgICAgIHN0cmVhbS5vbignZXJyb3InLCByZWplY3QpO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgZGVsZXRlRmlsZShmaWxlbmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3QgYnVja2V0ID0gYXdhaXQgdGhpcy5fZ2V0QnVja2V0KCk7XG4gICAgY29uc3QgZG9jdW1lbnRzID0gYXdhaXQgYnVja2V0LmZpbmQoeyBmaWxlbmFtZSB9KS50b0FycmF5KCk7XG4gICAgaWYgKGRvY3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRmlsZU5vdEZvdW5kJyk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLmFsbChcbiAgICAgIGRvY3VtZW50cy5tYXAoZG9jID0+IHtcbiAgICAgICAgcmV0dXJuIGJ1Y2tldC5kZWxldGUoZG9jLl9pZCk7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBhc3luYyBnZXRGaWxlRGF0YShmaWxlbmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3QgYnVja2V0ID0gYXdhaXQgdGhpcy5fZ2V0QnVja2V0KCk7XG4gICAgY29uc3Qgc3RyZWFtID0gYnVja2V0Lm9wZW5Eb3dubG9hZFN0cmVhbUJ5TmFtZShmaWxlbmFtZSk7XG4gICAgc3RyZWFtLnJlYWQoKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgY2h1bmtzID0gW107XG4gICAgICBzdHJlYW0ub24oJ2RhdGEnLCBkYXRhID0+IHtcbiAgICAgICAgY2h1bmtzLnB1c2goZGF0YSk7XG4gICAgICB9KTtcbiAgICAgIHN0cmVhbS5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBkYXRhID0gQnVmZmVyLmNvbmNhdChjaHVua3MpO1xuICAgICAgICBpZiAodGhpcy5fZW5jcnlwdGlvbktleSAhPT0gbnVsbCkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBhdXRoVGFnTG9jYXRpb24gPSBkYXRhLmxlbmd0aCAtIDE2O1xuICAgICAgICAgICAgY29uc3QgaXZMb2NhdGlvbiA9IGRhdGEubGVuZ3RoIC0gMzI7XG4gICAgICAgICAgICBjb25zdCBhdXRoVGFnID0gZGF0YS5zbGljZShhdXRoVGFnTG9jYXRpb24pO1xuICAgICAgICAgICAgY29uc3QgaXYgPSBkYXRhLnNsaWNlKGl2TG9jYXRpb24sIGF1dGhUYWdMb2NhdGlvbik7XG4gICAgICAgICAgICBjb25zdCBlbmNyeXB0ZWQgPSBkYXRhLnNsaWNlKDAsIGl2TG9jYXRpb24pO1xuICAgICAgICAgICAgY29uc3QgZGVjaXBoZXIgPSBjcnlwdG8uY3JlYXRlRGVjaXBoZXJpdih0aGlzLl9hbGdvcml0aG0sIHRoaXMuX2VuY3J5cHRpb25LZXksIGl2KTtcbiAgICAgICAgICAgIGRlY2lwaGVyLnNldEF1dGhUYWcoYXV0aFRhZyk7XG4gICAgICAgICAgICBjb25zdCBkZWNyeXB0ZWQgPSBCdWZmZXIuY29uY2F0KFtkZWNpcGhlci51cGRhdGUoZW5jcnlwdGVkKSwgZGVjaXBoZXIuZmluYWwoKV0pO1xuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoZGVjcnlwdGVkKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmVzb2x2ZShkYXRhKTtcbiAgICAgIH0pO1xuICAgICAgc3RyZWFtLm9uKCdlcnJvcicsIGVyciA9PiB7XG4gICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyByb3RhdGVFbmNyeXB0aW9uS2V5KG9wdGlvbnMgPSB7fSkge1xuICAgIHZhciBmaWxlTmFtZXMgPSBbXTtcbiAgICB2YXIgb2xkS2V5RmlsZUFkYXB0ZXIgPSB7fTtcbiAgICBjb25zdCBidWNrZXQgPSBhd2FpdCB0aGlzLl9nZXRCdWNrZXQoKTtcbiAgICBpZiAob3B0aW9ucy5vbGRLZXkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgb2xkS2V5RmlsZUFkYXB0ZXIgPSBuZXcgR3JpZEZTQnVja2V0QWRhcHRlcihcbiAgICAgICAgdGhpcy5fZGF0YWJhc2VVUkksXG4gICAgICAgIHRoaXMuX21vbmdvT3B0aW9ucyxcbiAgICAgICAgb3B0aW9ucy5vbGRLZXlcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9sZEtleUZpbGVBZGFwdGVyID0gbmV3IEdyaWRGU0J1Y2tldEFkYXB0ZXIodGhpcy5fZGF0YWJhc2VVUkksIHRoaXMuX21vbmdvT3B0aW9ucyk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmZpbGVOYW1lcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBmaWxlTmFtZXMgPSBvcHRpb25zLmZpbGVOYW1lcztcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgZmlsZU5hbWVzSXRlcmF0b3IgPSBhd2FpdCBidWNrZXQuZmluZCgpLnRvQXJyYXkoKTtcbiAgICAgIGZpbGVOYW1lc0l0ZXJhdG9yLmZvckVhY2goZmlsZSA9PiB7XG4gICAgICAgIGZpbGVOYW1lcy5wdXNoKGZpbGUuZmlsZW5hbWUpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgIHZhciBmaWxlTmFtZXNOb3RSb3RhdGVkID0gZmlsZU5hbWVzO1xuICAgICAgdmFyIGZpbGVOYW1lc1JvdGF0ZWQgPSBbXTtcbiAgICAgIHZhciBmaWxlTmFtZVRvdGFsID0gZmlsZU5hbWVzLmxlbmd0aDtcbiAgICAgIHZhciBmaWxlTmFtZUluZGV4ID0gMDtcbiAgICAgIGZpbGVOYW1lcy5mb3JFYWNoKGZpbGVOYW1lID0+IHtcbiAgICAgICAgb2xkS2V5RmlsZUFkYXB0ZXJcbiAgICAgICAgICAuZ2V0RmlsZURhdGEoZmlsZU5hbWUpXG4gICAgICAgICAgLnRoZW4ocGxhaW5UZXh0RGF0YSA9PiB7XG4gICAgICAgICAgICAvL092ZXJ3cml0ZSBmaWxlIHdpdGggZGF0YSBlbmNyeXB0ZWQgd2l0aCBuZXcga2V5XG4gICAgICAgICAgICB0aGlzLmNyZWF0ZUZpbGUoZmlsZU5hbWUsIHBsYWluVGV4dERhdGEpXG4gICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBmaWxlTmFtZXNSb3RhdGVkLnB1c2goZmlsZU5hbWUpO1xuICAgICAgICAgICAgICAgIGZpbGVOYW1lc05vdFJvdGF0ZWQgPSBmaWxlTmFtZXNOb3RSb3RhdGVkLmZpbHRlcihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZSAhPT0gZmlsZU5hbWU7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgZmlsZU5hbWVJbmRleCArPSAxO1xuICAgICAgICAgICAgICAgIGlmIChmaWxlTmFtZUluZGV4ID09IGZpbGVOYW1lVG90YWwpIHtcbiAgICAgICAgICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgICAgICAgICByb3RhdGVkOiBmaWxlTmFtZXNSb3RhdGVkLFxuICAgICAgICAgICAgICAgICAgICBub3RSb3RhdGVkOiBmaWxlTmFtZXNOb3RSb3RhdGVkLFxuICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgICAgIGZpbGVOYW1lSW5kZXggKz0gMTtcbiAgICAgICAgICAgICAgICBpZiAoZmlsZU5hbWVJbmRleCA9PSBmaWxlTmFtZVRvdGFsKSB7XG4gICAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgcm90YXRlZDogZmlsZU5hbWVzUm90YXRlZCxcbiAgICAgICAgICAgICAgICAgICAgbm90Um90YXRlZDogZmlsZU5hbWVzTm90Um90YXRlZCxcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgZmlsZU5hbWVJbmRleCArPSAxO1xuICAgICAgICAgICAgaWYgKGZpbGVOYW1lSW5kZXggPT0gZmlsZU5hbWVUb3RhbCkge1xuICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICByb3RhdGVkOiBmaWxlTmFtZXNSb3RhdGVkLFxuICAgICAgICAgICAgICAgIG5vdFJvdGF0ZWQ6IGZpbGVOYW1lc05vdFJvdGF0ZWQsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBnZXRGaWxlTG9jYXRpb24oY29uZmlnLCBmaWxlbmFtZSkge1xuICAgIHJldHVybiBjb25maWcubW91bnQgKyAnL2ZpbGVzLycgKyBjb25maWcuYXBwbGljYXRpb25JZCArICcvJyArIGVuY29kZVVSSUNvbXBvbmVudChmaWxlbmFtZSk7XG4gIH1cblxuICBhc3luYyBnZXRNZXRhZGF0YShmaWxlbmFtZSkge1xuICAgIGNvbnN0IGJ1Y2tldCA9IGF3YWl0IHRoaXMuX2dldEJ1Y2tldCgpO1xuICAgIGNvbnN0IGZpbGVzID0gYXdhaXQgYnVja2V0LmZpbmQoeyBmaWxlbmFtZSB9KS50b0FycmF5KCk7XG4gICAgaWYgKGZpbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjb25zdCB7IG1ldGFkYXRhIH0gPSBmaWxlc1swXTtcbiAgICByZXR1cm4geyBtZXRhZGF0YSB9O1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlRmlsZVN0cmVhbShmaWxlbmFtZTogc3RyaW5nLCByZXEsIHJlcywgY29udGVudFR5cGUpIHtcbiAgICBjb25zdCBidWNrZXQgPSBhd2FpdCB0aGlzLl9nZXRCdWNrZXQoKTtcbiAgICBjb25zdCBmaWxlcyA9IGF3YWl0IGJ1Y2tldC5maW5kKHsgZmlsZW5hbWUgfSkudG9BcnJheSgpO1xuICAgIGlmIChmaWxlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRmlsZU5vdEZvdW5kJyk7XG4gICAgfVxuICAgIGNvbnN0IHBhcnRzID0gcmVxXG4gICAgICAuZ2V0KCdSYW5nZScpXG4gICAgICAucmVwbGFjZSgvYnl0ZXM9LywgJycpXG4gICAgICAuc3BsaXQoJy0nKTtcbiAgICBjb25zdCBwYXJ0aWFsc3RhcnQgPSBwYXJ0c1swXTtcbiAgICBjb25zdCBwYXJ0aWFsZW5kID0gcGFydHNbMV07XG5cbiAgICBjb25zdCBzdGFydCA9IHBhcnNlSW50KHBhcnRpYWxzdGFydCwgMTApO1xuICAgIGNvbnN0IGVuZCA9IHBhcnRpYWxlbmQgPyBwYXJzZUludChwYXJ0aWFsZW5kLCAxMCkgOiBmaWxlc1swXS5sZW5ndGggLSAxO1xuXG4gICAgcmVzLndyaXRlSGVhZCgyMDYsIHtcbiAgICAgICdBY2NlcHQtUmFuZ2VzJzogJ2J5dGVzJyxcbiAgICAgICdDb250ZW50LUxlbmd0aCc6IGVuZCAtIHN0YXJ0ICsgMSxcbiAgICAgICdDb250ZW50LVJhbmdlJzogJ2J5dGVzICcgKyBzdGFydCArICctJyArIGVuZCArICcvJyArIGZpbGVzWzBdLmxlbmd0aCxcbiAgICAgICdDb250ZW50LVR5cGUnOiBjb250ZW50VHlwZSxcbiAgICB9KTtcbiAgICBjb25zdCBzdHJlYW0gPSBidWNrZXQub3BlbkRvd25sb2FkU3RyZWFtQnlOYW1lKGZpbGVuYW1lKTtcbiAgICBzdHJlYW0uc3RhcnQoc3RhcnQpO1xuICAgIHN0cmVhbS5vbignZGF0YScsIGNodW5rID0+IHtcbiAgICAgIHJlcy53cml0ZShjaHVuayk7XG4gICAgfSk7XG4gICAgc3RyZWFtLm9uKCdlcnJvcicsICgpID0+IHtcbiAgICAgIHJlcy5zZW5kU3RhdHVzKDQwNCk7XG4gICAgfSk7XG4gICAgc3RyZWFtLm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICByZXMuZW5kKCk7XG4gICAgfSk7XG4gIH1cblxuICBoYW5kbGVTaHV0ZG93bigpIHtcbiAgICBpZiAoIXRoaXMuX2NsaWVudCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY2xpZW50LmNsb3NlKGZhbHNlKTtcbiAgfVxuXG4gIHZhbGlkYXRlRmlsZW5hbWUoZmlsZW5hbWUpIHtcbiAgICByZXR1cm4gdmFsaWRhdGVGaWxlbmFtZShmaWxlbmFtZSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgR3JpZEZTQnVja2V0QWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Files/GridStoreAdapter.js b/lib/Adapters/Files/GridStoreAdapter.js new file mode 100644 index 0000000000..b3286a27e5 --- /dev/null +++ b/lib/Adapters/Files/GridStoreAdapter.js @@ -0,0 +1,182 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.GridStoreAdapter = void 0; + +var _mongodb = require("mongodb"); + +var _FilesAdapter = require("./FilesAdapter"); + +var _defaults = _interopRequireDefault(require("../../defaults")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + GridStoreAdapter + Stores files in Mongo using GridStore + Requires the database adapter to be based on mongoclient + (GridStore is deprecated, Please use GridFSBucket instead) + + + */ +// -disable-next +class GridStoreAdapter extends _FilesAdapter.FilesAdapter { + constructor(mongoDatabaseURI = _defaults.default.DefaultMongoURI, mongoOptions = {}) { + super(); + this._databaseURI = mongoDatabaseURI; + const defaultMongoOptions = { + useNewUrlParser: true, + useUnifiedTopology: true + }; + this._mongoOptions = Object.assign(defaultMongoOptions, mongoOptions); + } + + _connect() { + if (!this._connectionPromise) { + this._connectionPromise = _mongodb.MongoClient.connect(this._databaseURI, this._mongoOptions).then(client => { + this._client = client; + return client.db(client.s.options.dbName); + }); + } + + return this._connectionPromise; + } // For a given config object, filename, and data, store a file + // Returns a promise + + + createFile(filename, data) { + return this._connect().then(database => { + const gridStore = new _mongodb.GridStore(database, filename, 'w'); + return gridStore.open(); + }).then(gridStore => { + return gridStore.write(data); + }).then(gridStore => { + return gridStore.close(); + }); + } + + deleteFile(filename) { + return this._connect().then(database => { + const gridStore = new _mongodb.GridStore(database, filename, 'r'); + return gridStore.open(); + }).then(gridStore => { + return gridStore.unlink(); + }).then(gridStore => { + return gridStore.close(); + }); + } + + getFileData(filename) { + return this._connect().then(database => { + return _mongodb.GridStore.exist(database, filename).then(() => { + const gridStore = new _mongodb.GridStore(database, filename, 'r'); + return gridStore.open(); + }); + }).then(gridStore => { + return gridStore.read(); + }); + } + + getFileLocation(config, filename) { + return config.mount + '/files/' + config.applicationId + '/' + encodeURIComponent(filename); + } + + async handleFileStream(filename, req, res, contentType) { + const stream = await this._connect().then(database => { + return _mongodb.GridStore.exist(database, filename).then(() => { + const gridStore = new _mongodb.GridStore(database, filename, 'r'); + return gridStore.open(); + }); + }); + handleRangeRequest(stream, req, res, contentType); + } + + handleShutdown() { + if (!this._client) { + return Promise.resolve(); + } + + return this._client.close(false); + } + + validateFilename(filename) { + return (0, _FilesAdapter.validateFilename)(filename); + } + +} // handleRangeRequest is licensed under Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0/). +// Author: LEROIB at weightingformypizza (https://weightingformypizza.wordpress.com/2015/06/24/stream-html5-media-content-like-video-audio-from-mongodb-using-express-and-gridstore/). + + +exports.GridStoreAdapter = GridStoreAdapter; + +function handleRangeRequest(stream, req, res, contentType) { + const buffer_size = 1024 * 1024; //1024Kb + // Range request, partial stream the file + + const parts = req.get('Range').replace(/bytes=/, '').split('-'); + let [start, end] = parts; + const notEnded = !end && end !== 0; + const notStarted = !start && start !== 0; // No end provided, we want all bytes + + if (notEnded) { + end = stream.length - 1; + } // No start provided, we're reading backwards + + + if (notStarted) { + start = stream.length - end; + end = start + end - 1; + } // Data exceeds the buffer_size, cap + + + if (end - start >= buffer_size) { + end = start + buffer_size - 1; + } + + const contentLength = end - start + 1; + res.writeHead(206, { + 'Content-Range': 'bytes ' + start + '-' + end + '/' + stream.length, + 'Accept-Ranges': 'bytes', + 'Content-Length': contentLength, + 'Content-Type': contentType + }); + stream.seek(start, function () { + // Get gridFile stream + const gridFileStream = stream.stream(true); + let bufferAvail = 0; + let remainingBytesToWrite = contentLength; + let totalBytesWritten = 0; // Write to response + + gridFileStream.on('data', function (data) { + bufferAvail += data.length; + + if (bufferAvail > 0) { + // slice returns the same buffer if overflowing + // safe to call in any case + const buffer = data.slice(0, remainingBytesToWrite); // Write the buffer + + res.write(buffer); // Increment total + + totalBytesWritten += buffer.length; // Decrement remaining + + remainingBytesToWrite -= data.length; // Decrement the available buffer + + bufferAvail -= buffer.length; + } // In case of small slices, all values will be good at that point + // we've written enough, end... + + + if (totalBytesWritten >= contentLength) { + stream.close(); + res.end(); + this.destroy(); + } + }); + }); +} + +var _default = GridStoreAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9GaWxlcy9HcmlkU3RvcmVBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIkdyaWRTdG9yZUFkYXB0ZXIiLCJGaWxlc0FkYXB0ZXIiLCJjb25zdHJ1Y3RvciIsIm1vbmdvRGF0YWJhc2VVUkkiLCJkZWZhdWx0cyIsIkRlZmF1bHRNb25nb1VSSSIsIm1vbmdvT3B0aW9ucyIsIl9kYXRhYmFzZVVSSSIsImRlZmF1bHRNb25nb09wdGlvbnMiLCJ1c2VOZXdVcmxQYXJzZXIiLCJ1c2VVbmlmaWVkVG9wb2xvZ3kiLCJfbW9uZ29PcHRpb25zIiwiT2JqZWN0IiwiYXNzaWduIiwiX2Nvbm5lY3QiLCJfY29ubmVjdGlvblByb21pc2UiLCJNb25nb0NsaWVudCIsImNvbm5lY3QiLCJ0aGVuIiwiY2xpZW50IiwiX2NsaWVudCIsImRiIiwicyIsIm9wdGlvbnMiLCJkYk5hbWUiLCJjcmVhdGVGaWxlIiwiZmlsZW5hbWUiLCJkYXRhIiwiZGF0YWJhc2UiLCJncmlkU3RvcmUiLCJHcmlkU3RvcmUiLCJvcGVuIiwid3JpdGUiLCJjbG9zZSIsImRlbGV0ZUZpbGUiLCJ1bmxpbmsiLCJnZXRGaWxlRGF0YSIsImV4aXN0IiwicmVhZCIsImdldEZpbGVMb2NhdGlvbiIsImNvbmZpZyIsIm1vdW50IiwiYXBwbGljYXRpb25JZCIsImVuY29kZVVSSUNvbXBvbmVudCIsImhhbmRsZUZpbGVTdHJlYW0iLCJyZXEiLCJyZXMiLCJjb250ZW50VHlwZSIsInN0cmVhbSIsImhhbmRsZVJhbmdlUmVxdWVzdCIsImhhbmRsZVNodXRkb3duIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ2YWxpZGF0ZUZpbGVuYW1lIiwiYnVmZmVyX3NpemUiLCJwYXJ0cyIsImdldCIsInJlcGxhY2UiLCJzcGxpdCIsInN0YXJ0IiwiZW5kIiwibm90RW5kZWQiLCJub3RTdGFydGVkIiwibGVuZ3RoIiwiY29udGVudExlbmd0aCIsIndyaXRlSGVhZCIsInNlZWsiLCJncmlkRmlsZVN0cmVhbSIsImJ1ZmZlckF2YWlsIiwicmVtYWluaW5nQnl0ZXNUb1dyaXRlIiwidG90YWxCeXRlc1dyaXR0ZW4iLCJvbiIsImJ1ZmZlciIsInNsaWNlIiwiZGVzdHJveSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQVVBOztBQUNBOztBQUNBOzs7O0FBWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBS08sTUFBTUEsZ0JBQU4sU0FBK0JDLDBCQUEvQixDQUE0QztBQUtqREMsRUFBQUEsV0FBVyxDQUFDQyxnQkFBZ0IsR0FBR0Msa0JBQVNDLGVBQTdCLEVBQThDQyxZQUFZLEdBQUcsRUFBN0QsRUFBaUU7QUFDMUU7QUFDQSxTQUFLQyxZQUFMLEdBQW9CSixnQkFBcEI7QUFFQSxVQUFNSyxtQkFBbUIsR0FBRztBQUMxQkMsTUFBQUEsZUFBZSxFQUFFLElBRFM7QUFFMUJDLE1BQUFBLGtCQUFrQixFQUFFO0FBRk0sS0FBNUI7QUFJQSxTQUFLQyxhQUFMLEdBQXFCQyxNQUFNLENBQUNDLE1BQVAsQ0FBY0wsbUJBQWQsRUFBbUNGLFlBQW5DLENBQXJCO0FBQ0Q7O0FBRURRLEVBQUFBLFFBQVEsR0FBRztBQUNULFFBQUksQ0FBQyxLQUFLQyxrQkFBVixFQUE4QjtBQUM1QixXQUFLQSxrQkFBTCxHQUEwQkMscUJBQVlDLE9BQVosQ0FBb0IsS0FBS1YsWUFBekIsRUFBdUMsS0FBS0ksYUFBNUMsRUFBMkRPLElBQTNELENBQ3hCQyxNQUFNLElBQUk7QUFDUixhQUFLQyxPQUFMLEdBQWVELE1BQWY7QUFDQSxlQUFPQSxNQUFNLENBQUNFLEVBQVAsQ0FBVUYsTUFBTSxDQUFDRyxDQUFQLENBQVNDLE9BQVQsQ0FBaUJDLE1BQTNCLENBQVA7QUFDRCxPQUp1QixDQUExQjtBQU1EOztBQUNELFdBQU8sS0FBS1Qsa0JBQVo7QUFDRCxHQTFCZ0QsQ0E0QmpEO0FBQ0E7OztBQUNBVSxFQUFBQSxVQUFVLENBQUNDLFFBQUQsRUFBbUJDLElBQW5CLEVBQXlCO0FBQ2pDLFdBQU8sS0FBS2IsUUFBTCxHQUNK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UUFBQUEsR0FBRyxDQUFDYyxHQUFKO0FBQ0EsYUFBS2MsT0FBTDtBQUNEO0FBQ0YsS0F0QkQ7QUF1QkQsR0E5QkQ7QUErQkQ7O2VBRWMxRSxnQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuIEdyaWRTdG9yZUFkYXB0ZXJcbiBTdG9yZXMgZmlsZXMgaW4gTW9uZ28gdXNpbmcgR3JpZFN0b3JlXG4gUmVxdWlyZXMgdGhlIGRhdGFiYXNlIGFkYXB0ZXIgdG8gYmUgYmFzZWQgb24gbW9uZ29jbGllbnRcbiAoR3JpZFN0b3JlIGlzIGRlcHJlY2F0ZWQsIFBsZWFzZSB1c2UgR3JpZEZTQnVja2V0IGluc3RlYWQpXG5cbiBAZmxvdyB3ZWFrXG4gKi9cblxuLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG5pbXBvcnQgeyBNb25nb0NsaWVudCwgR3JpZFN0b3JlLCBEYiB9IGZyb20gJ21vbmdvZGInO1xuaW1wb3J0IHsgRmlsZXNBZGFwdGVyLCB2YWxpZGF0ZUZpbGVuYW1lIH0gZnJvbSAnLi9GaWxlc0FkYXB0ZXInO1xuaW1wb3J0IGRlZmF1bHRzIGZyb20gJy4uLy4uL2RlZmF1bHRzJztcblxuZXhwb3J0IGNsYXNzIEdyaWRTdG9yZUFkYXB0ZXIgZXh0ZW5kcyBGaWxlc0FkYXB0ZXIge1xuICBfZGF0YWJhc2VVUkk6IHN0cmluZztcbiAgX2Nvbm5lY3Rpb25Qcm9taXNlOiBQcm9taXNlPERiPjtcbiAgX21vbmdvT3B0aW9uczogT2JqZWN0O1xuXG4gIGNvbnN0cnVjdG9yKG1vbmdvRGF0YWJhc2VVUkkgPSBkZWZhdWx0cy5EZWZhdWx0TW9uZ29VUkksIG1vbmdvT3B0aW9ucyA9IHt9KSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLl9kYXRhYmFzZVVSSSA9IG1vbmdvRGF0YWJhc2VVUkk7XG5cbiAgICBjb25zdCBkZWZhdWx0TW9uZ29PcHRpb25zID0ge1xuICAgICAgdXNlTmV3VXJsUGFyc2VyOiB0cnVlLFxuICAgICAgdXNlVW5pZmllZFRvcG9sb2d5OiB0cnVlLFxuICAgIH07XG4gICAgdGhpcy5fbW9uZ29PcHRpb25zID0gT2JqZWN0LmFzc2lnbihkZWZhdWx0TW9uZ29PcHRpb25zLCBtb25nb09wdGlvbnMpO1xuICB9XG5cbiAgX2Nvbm5lY3QoKSB7XG4gICAgaWYgKCF0aGlzLl9jb25uZWN0aW9uUHJvbWlzZSkge1xuICAgICAgdGhpcy5fY29ubmVjdGlvblByb21pc2UgPSBNb25nb0NsaWVudC5jb25uZWN0KHRoaXMuX2RhdGFiYXNlVVJJLCB0aGlzLl9tb25nb09wdGlvbnMpLnRoZW4oXG4gICAgICAgIGNsaWVudCA9PiB7XG4gICAgICAgICAgdGhpcy5fY2xpZW50ID0gY2xpZW50O1xuICAgICAgICAgIHJldHVybiBjbGllbnQuZGIoY2xpZW50LnMub3B0aW9ucy5kYk5hbWUpO1xuICAgICAgICB9XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY29ubmVjdGlvblByb21pc2U7XG4gIH1cblxuICAvLyBGb3IgYSBnaXZlbiBjb25maWcgb2JqZWN0LCBmaWxlbmFtZSwgYW5kIGRhdGEsIHN0b3JlIGEgZmlsZVxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZVxuICBjcmVhdGVGaWxlKGZpbGVuYW1lOiBzdHJpbmcsIGRhdGEpIHtcbiAgICByZXR1cm4gdGhpcy5fY29ubmVjdCgpXG4gICAgICAudGhlbihkYXRhYmFzZSA9PiB7XG4gICAgICAgIGNvbnN0IGdyaWRTdG9yZSA9IG5ldyBHcmlkU3RvcmUoZGF0YWJhc2UsIGZpbGVuYW1lLCAndycpO1xuICAgICAgICByZXR1cm4gZ3JpZFN0b3JlLm9wZW4oKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihncmlkU3RvcmUgPT4ge1xuICAgICAgICByZXR1cm4gZ3JpZFN0b3JlLndyaXRlKGRhdGEpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKGdyaWRTdG9yZSA9PiB7XG4gICAgICAgIHJldHVybiBncmlkU3RvcmUuY2xvc2UoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgZGVsZXRlRmlsZShmaWxlbmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuX2Nvbm5lY3QoKVxuICAgICAgLnRoZW4oZGF0YWJhc2UgPT4ge1xuICAgICAgICBjb25zdCBncmlkU3RvcmUgPSBuZXcgR3JpZFN0b3JlKGRhdGFiYXNlLCBmaWxlbmFtZSwgJ3InKTtcbiAgICAgICAgcmV0dXJuIGdyaWRTdG9yZS5vcGVuKCk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oZ3JpZFN0b3JlID0+IHtcbiAgICAgICAgcmV0dXJuIGdyaWRTdG9yZS51bmxpbmsoKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihncmlkU3RvcmUgPT4ge1xuICAgICAgICByZXR1cm4gZ3JpZFN0b3JlLmNsb3NlKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIGdldEZpbGVEYXRhKGZpbGVuYW1lOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5fY29ubmVjdCgpXG4gICAgICAudGhlbihkYXRhYmFzZSA9PiB7XG4gICAgICAgIHJldHVybiBHcmlkU3RvcmUuZXhpc3QoZGF0YWJhc2UsIGZpbGVuYW1lKS50aGVuKCgpID0+IHtcbiAgICAgICAgICBjb25zdCBncmlkU3RvcmUgPSBuZXcgR3JpZFN0b3JlKGRhdGFiYXNlLCBmaWxlbmFtZSwgJ3InKTtcbiAgICAgICAgICByZXR1cm4gZ3JpZFN0b3JlLm9wZW4oKTtcbiAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oZ3JpZFN0b3JlID0+IHtcbiAgICAgICAgcmV0dXJuIGdyaWRTdG9yZS5yZWFkKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIGdldEZpbGVMb2NhdGlvbihjb25maWcsIGZpbGVuYW1lKSB7XG4gICAgcmV0dXJuIGNvbmZpZy5tb3VudCArICcvZmlsZXMvJyArIGNvbmZpZy5hcHBsaWNhdGlvbklkICsgJy8nICsgZW5jb2RlVVJJQ29tcG9uZW50KGZpbGVuYW1lKTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUZpbGVTdHJlYW0oZmlsZW5hbWU6IHN0cmluZywgcmVxLCByZXMsIGNvbnRlbnRUeXBlKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gYXdhaXQgdGhpcy5fY29ubmVjdCgpLnRoZW4oZGF0YWJhc2UgPT4ge1xuICAgICAgcmV0dXJuIEdyaWRTdG9yZS5leGlzdChkYXRhYmFzZSwgZmlsZW5hbWUpLnRoZW4oKCkgPT4ge1xuICAgICAgICBjb25zdCBncmlkU3RvcmUgPSBuZXcgR3JpZFN0b3JlKGRhdGFiYXNlLCBmaWxlbmFtZSwgJ3InKTtcbiAgICAgICAgcmV0dXJuIGdyaWRTdG9yZS5vcGVuKCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBoYW5kbGVSYW5nZVJlcXVlc3Qoc3RyZWFtLCByZXEsIHJlcywgY29udGVudFR5cGUpO1xuICB9XG5cbiAgaGFuZGxlU2h1dGRvd24oKSB7XG4gICAgaWYgKCF0aGlzLl9jbGllbnQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudC5jbG9zZShmYWxzZSk7XG4gIH1cblxuICB2YWxpZGF0ZUZpbGVuYW1lKGZpbGVuYW1lKSB7XG4gICAgcmV0dXJuIHZhbGlkYXRlRmlsZW5hbWUoZmlsZW5hbWUpO1xuICB9XG59XG5cbi8vIGhhbmRsZVJhbmdlUmVxdWVzdCBpcyBsaWNlbnNlZCB1bmRlciBDcmVhdGl2ZSBDb21tb25zIEF0dHJpYnV0aW9uIDQuMCBJbnRlcm5hdGlvbmFsIExpY2Vuc2UgKGh0dHBzOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9ieS80LjAvKS5cbi8vIEF1dGhvcjogTEVST0lCIGF0IHdlaWdodGluZ2Zvcm15cGl6emEgKGh0dHBzOi8vd2VpZ2h0aW5nZm9ybXlwaXp6YS53b3JkcHJlc3MuY29tLzIwMTUvMDYvMjQvc3RyZWFtLWh0bWw1LW1lZGlhLWNvbnRlbnQtbGlrZS12aWRlby1hdWRpby1mcm9tLW1vbmdvZGItdXNpbmctZXhwcmVzcy1hbmQtZ3JpZHN0b3JlLykuXG5mdW5jdGlvbiBoYW5kbGVSYW5nZVJlcXVlc3Qoc3RyZWFtLCByZXEsIHJlcywgY29udGVudFR5cGUpIHtcbiAgY29uc3QgYnVmZmVyX3NpemUgPSAxMDI0ICogMTAyNDsgLy8xMDI0S2JcbiAgLy8gUmFuZ2UgcmVxdWVzdCwgcGFydGlhbCBzdHJlYW0gdGhlIGZpbGVcbiAgY29uc3QgcGFydHMgPSByZXFcbiAgICAuZ2V0KCdSYW5nZScpXG4gICAgLnJlcGxhY2UoL2J5dGVzPS8sICcnKVxuICAgIC5zcGxpdCgnLScpO1xuICBsZXQgW3N0YXJ0LCBlbmRdID0gcGFydHM7XG4gIGNvbnN0IG5vdEVuZGVkID0gIWVuZCAmJiBlbmQgIT09IDA7XG4gIGNvbnN0IG5vdFN0YXJ0ZWQgPSAhc3RhcnQgJiYgc3RhcnQgIT09IDA7XG4gIC8vIE5vIGVuZCBwcm92aWRlZCwgd2Ugd2FudCBhbGwgYnl0ZXNcbiAgaWYgKG5vdEVuZGVkKSB7XG4gICAgZW5kID0gc3RyZWFtLmxlbmd0aCAtIDE7XG4gIH1cbiAgLy8gTm8gc3RhcnQgcHJvdmlkZWQsIHdlJ3JlIHJlYWRpbmcgYmFja3dhcmRzXG4gIGlmIChub3RTdGFydGVkKSB7XG4gICAgc3RhcnQgPSBzdHJlYW0ubGVuZ3RoIC0gZW5kO1xuICAgIGVuZCA9IHN0YXJ0ICsgZW5kIC0gMTtcbiAgfVxuXG4gIC8vIERhdGEgZXhjZWVkcyB0aGUgYnVmZmVyX3NpemUsIGNhcFxuICBpZiAoZW5kIC0gc3RhcnQgPj0gYnVmZmVyX3NpemUpIHtcbiAgICBlbmQgPSBzdGFydCArIGJ1ZmZlcl9zaXplIC0gMTtcbiAgfVxuXG4gIGNvbnN0IGNvbnRlbnRMZW5ndGggPSBlbmQgLSBzdGFydCArIDE7XG5cbiAgcmVzLndyaXRlSGVhZCgyMDYsIHtcbiAgICAnQ29udGVudC1SYW5nZSc6ICdieXRlcyAnICsgc3RhcnQgKyAnLScgKyBlbmQgKyAnLycgKyBzdHJlYW0ubGVuZ3RoLFxuICAgICdBY2NlcHQtUmFuZ2VzJzogJ2J5dGVzJyxcbiAgICAnQ29udGVudC1MZW5ndGgnOiBjb250ZW50TGVuZ3RoLFxuICAgICdDb250ZW50LVR5cGUnOiBjb250ZW50VHlwZSxcbiAgfSk7XG5cbiAgc3RyZWFtLnNlZWsoc3RhcnQsIGZ1bmN0aW9uICgpIHtcbiAgICAvLyBHZXQgZ3JpZEZpbGUgc3RyZWFtXG4gICAgY29uc3QgZ3JpZEZpbGVTdHJlYW0gPSBzdHJlYW0uc3RyZWFtKHRydWUpO1xuICAgIGxldCBidWZmZXJBdmFpbCA9IDA7XG4gICAgbGV0IHJlbWFpbmluZ0J5dGVzVG9Xcml0ZSA9IGNvbnRlbnRMZW5ndGg7XG4gICAgbGV0IHRvdGFsQnl0ZXNXcml0dGVuID0gMDtcbiAgICAvLyBXcml0ZSB0byByZXNwb25zZVxuICAgIGdyaWRGaWxlU3RyZWFtLm9uKCdkYXRhJywgZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgIGJ1ZmZlckF2YWlsICs9IGRhdGEubGVuZ3RoO1xuICAgICAgaWYgKGJ1ZmZlckF2YWlsID4gMCkge1xuICAgICAgICAvLyBzbGljZSByZXR1cm5zIHRoZSBzYW1lIGJ1ZmZlciBpZiBvdmVyZmxvd2luZ1xuICAgICAgICAvLyBzYWZlIHRvIGNhbGwgaW4gYW55IGNhc2VcbiAgICAgICAgY29uc3QgYnVmZmVyID0gZGF0YS5zbGljZSgwLCByZW1haW5pbmdCeXRlc1RvV3JpdGUpO1xuICAgICAgICAvLyBXcml0ZSB0aGUgYnVmZmVyXG4gICAgICAgIHJlcy53cml0ZShidWZmZXIpO1xuICAgICAgICAvLyBJbmNyZW1lbnQgdG90YWxcbiAgICAgICAgdG90YWxCeXRlc1dyaXR0ZW4gKz0gYnVmZmVyLmxlbmd0aDtcbiAgICAgICAgLy8gRGVjcmVtZW50IHJlbWFpbmluZ1xuICAgICAgICByZW1haW5pbmdCeXRlc1RvV3JpdGUgLT0gZGF0YS5sZW5ndGg7XG4gICAgICAgIC8vIERlY3JlbWVudCB0aGUgYXZhaWxhYmxlIGJ1ZmZlclxuICAgICAgICBidWZmZXJBdmFpbCAtPSBidWZmZXIubGVuZ3RoO1xuICAgICAgfVxuICAgICAgLy8gSW4gY2FzZSBvZiBzbWFsbCBzbGljZXMsIGFsbCB2YWx1ZXMgd2lsbCBiZSBnb29kIGF0IHRoYXQgcG9pbnRcbiAgICAgIC8vIHdlJ3ZlIHdyaXR0ZW4gZW5vdWdoLCBlbmQuLi5cbiAgICAgIGlmICh0b3RhbEJ5dGVzV3JpdHRlbiA+PSBjb250ZW50TGVuZ3RoKSB7XG4gICAgICAgIHN0cmVhbS5jbG9zZSgpO1xuICAgICAgICByZXMuZW5kKCk7XG4gICAgICAgIHRoaXMuZGVzdHJveSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgR3JpZFN0b3JlQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Logger/LoggerAdapter.js b/lib/Adapters/Logger/LoggerAdapter.js new file mode 100644 index 0000000000..5d3d26d1a1 --- /dev/null +++ b/lib/Adapters/Logger/LoggerAdapter.js @@ -0,0 +1,39 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.LoggerAdapter = void 0; + +/*eslint no-unused-vars: "off"*/ + +/** + * @module Adapters + */ + +/** + * @interface LoggerAdapter + * Logger Adapter + * Allows you to change the logger mechanism + * Default is WinstonLoggerAdapter.js + */ +class LoggerAdapter { + constructor(options) {} + /** + * log + * @param {String} level + * @param {String} message + * @param {Object} metadata + */ + + + log(level, message + /* meta */ + ) {} + +} + +exports.LoggerAdapter = LoggerAdapter; +var _default = LoggerAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9Mb2dnZXIvTG9nZ2VyQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJMb2dnZXJBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJvcHRpb25zIiwibG9nIiwibGV2ZWwiLCJtZXNzYWdlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7QUFDQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU1BLGFBQU4sQ0FBb0I7QUFDekJDLEVBQUFBLFdBQVcsQ0FBQ0MsT0FBRCxFQUFVLENBQUU7QUFDdkI7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDRUMsRUFBQUEsR0FBRyxDQUFDQyxLQUFELEVBQVFDO0FBQVE7QUFBaEIsSUFBNEIsQ0FBRTs7QUFSUjs7O2VBV1pMLGEiLCJzb3VyY2VzQ29udGVudCI6WyIvKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG4vKipcbiAqIEBtb2R1bGUgQWRhcHRlcnNcbiAqL1xuLyoqXG4gKiBAaW50ZXJmYWNlIExvZ2dlckFkYXB0ZXJcbiAqIExvZ2dlciBBZGFwdGVyXG4gKiBBbGxvd3MgeW91IHRvIGNoYW5nZSB0aGUgbG9nZ2VyIG1lY2hhbmlzbVxuICogRGVmYXVsdCBpcyBXaW5zdG9uTG9nZ2VyQWRhcHRlci5qc1xuICovXG5leHBvcnQgY2xhc3MgTG9nZ2VyQWRhcHRlciB7XG4gIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHt9XG4gIC8qKlxuICAgKiBsb2dcbiAgICogQHBhcmFtIHtTdHJpbmd9IGxldmVsXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBtZXRhZGF0YVxuICAgKi9cbiAgbG9nKGxldmVsLCBtZXNzYWdlIC8qIG1ldGEgKi8pIHt9XG59XG5cbmV4cG9ydCBkZWZhdWx0IExvZ2dlckFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Logger/WinstonLogger.js b/lib/Adapters/Logger/WinstonLogger.js new file mode 100644 index 0000000000..9980d08868 --- /dev/null +++ b/lib/Adapters/Logger/WinstonLogger.js @@ -0,0 +1,137 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.configureLogger = configureLogger; +exports.addTransport = addTransport; +exports.removeTransport = removeTransport; +exports.default = exports.logger = void 0; + +var _winston = _interopRequireWildcard(require("winston")); + +var _fs = _interopRequireDefault(require("fs")); + +var _path = _interopRequireDefault(require("path")); + +var _winstonDailyRotateFile = _interopRequireDefault(require("winston-daily-rotate-file")); + +var _lodash = _interopRequireDefault(require("lodash")); + +var _defaults = _interopRequireDefault(require("../../defaults")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +const logger = _winston.default.createLogger(); + +exports.logger = logger; + +function configureTransports(options) { + const transports = []; + + if (options) { + const silent = options.silent; + delete options.silent; + + try { + if (!_lodash.default.isNil(options.dirname)) { + const parseServer = new _winstonDailyRotateFile.default(Object.assign({ + filename: 'parse-server.info', + json: true, + format: _winston.format.combine(_winston.format.timestamp(), _winston.format.splat(), _winston.format.json()) + }, options)); + parseServer.name = 'parse-server'; + transports.push(parseServer); + const parseServerError = new _winstonDailyRotateFile.default(Object.assign({ + filename: 'parse-server.err', + json: true, + format: _winston.format.combine(_winston.format.timestamp(), _winston.format.splat(), _winston.format.json()) + }, options, { + level: 'error' + })); + parseServerError.name = 'parse-server-error'; + transports.push(parseServerError); + } + } catch (e) { + /* */ + } + + const consoleFormat = options.json ? _winston.format.json() : _winston.format.simple(); + const consoleOptions = Object.assign({ + colorize: true, + name: 'console', + silent, + format: _winston.format.combine(_winston.format.splat(), consoleFormat) + }, options); + transports.push(new _winston.default.transports.Console(consoleOptions)); + } + + logger.configure({ + transports + }); +} + +function configureLogger({ + logsFolder = _defaults.default.logsFolder, + jsonLogs = _defaults.default.jsonLogs, + logLevel = _winston.default.level, + verbose = _defaults.default.verbose, + silent = _defaults.default.silent, + maxLogFiles +} = {}) { + if (verbose) { + logLevel = 'verbose'; + } + + _winston.default.level = logLevel; + const options = {}; + + if (logsFolder) { + if (!_path.default.isAbsolute(logsFolder)) { + logsFolder = _path.default.resolve(process.cwd(), logsFolder); + } + + try { + _fs.default.mkdirSync(logsFolder); + } catch (e) { + /* */ + } + } + + options.dirname = logsFolder; + options.level = logLevel; + options.silent = silent; + options.maxFiles = maxLogFiles; + + if (jsonLogs) { + options.json = true; + options.stringify = true; + } + + configureTransports(options); +} + +function addTransport(transport) { + // we will remove the existing transport + // before replacing it with a new one + removeTransport(transport.name); + logger.add(transport); +} + +function removeTransport(transport) { + const matchingTransport = logger.transports.find(t1 => { + return typeof transport === 'string' ? t1.name === transport : t1 === transport; + }); + + if (matchingTransport) { + logger.remove(matchingTransport); + } +} + +var _default = logger; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9Mb2dnZXIvV2luc3RvbkxvZ2dlci5qcyJdLCJuYW1lcyI6WyJsb2dnZXIiLCJ3aW5zdG9uIiwiY3JlYXRlTG9nZ2VyIiwiY29uZmlndXJlVHJhbnNwb3J0cyIsIm9wdGlvbnMiLCJ0cmFuc3BvcnRzIiwic2lsZW50IiwiXyIsImlzTmlsIiwiZGlybmFtZSIsInBhcnNlU2VydmVyIiwiRGFpbHlSb3RhdGVGaWxlIiwiT2JqZWN0IiwiYXNzaWduIiwiZmlsZW5hbWUiLCJqc29uIiwiZm9ybWF0IiwiY29tYmluZSIsInRpbWVzdGFtcCIsInNwbGF0IiwibmFtZSIsInB1c2giLCJwYXJzZVNlcnZlckVycm9yIiwibGV2ZWwiLCJlIiwiY29uc29sZUZvcm1hdCIsInNpbXBsZSIsImNvbnNvbGVPcHRpb25zIiwiY29sb3JpemUiLCJDb25zb2xlIiwiY29uZmlndXJlIiwiY29uZmlndXJlTG9nZ2VyIiwibG9nc0ZvbGRlciIsImRlZmF1bHRzIiwianNvbkxvZ3MiLCJsb2dMZXZlbCIsInZlcmJvc2UiLCJtYXhMb2dGaWxlcyIsInBhdGgiLCJpc0Fic29sdXRlIiwicmVzb2x2ZSIsInByb2Nlc3MiLCJjd2QiLCJmcyIsIm1rZGlyU3luYyIsIm1heEZpbGVzIiwic3RyaW5naWZ5IiwiYWRkVHJhbnNwb3J0IiwidHJhbnNwb3J0IiwicmVtb3ZlVHJhbnNwb3J0IiwiYWRkIiwibWF0Y2hpbmdUcmFuc3BvcnQiLCJmaW5kIiwidDEiLCJyZW1vdmUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFQSxNQUFNQSxNQUFNLEdBQUdDLGlCQUFRQyxZQUFSLEVBQWY7Ozs7QUFFQSxTQUFTQyxtQkFBVCxDQUE2QkMsT0FBN0IsRUFBc0M7QUFDcEMsUUFBTUMsVUFBVSxHQUFHLEVBQW5COztBQUNBLE1BQUlELE9BQUosRUFBYTtBQUNYLFVBQU1FLE1BQU0sR0FBR0Ys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aUJBQWQ7QUFDRDtBQUNGOztlQUdjbkQsTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB3aW5zdG9uLCB7IGZvcm1hdCB9IGZyb20gJ3dpbnN0b24nO1xuaW1wb3J0IGZzIGZyb20gJ2ZzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IERhaWx5Um90YXRlRmlsZSBmcm9tICd3aW5zdG9uLWRhaWx5LXJvdGF0ZS1maWxlJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgZGVmYXVsdHMgZnJvbSAnLi4vLi4vZGVmYXVsdHMnO1xuXG5jb25zdCBsb2dnZXIgPSB3aW5zdG9uLmNyZWF0ZUxvZ2dlcigpO1xuXG5mdW5jdGlvbiBjb25maWd1cmVUcmFuc3BvcnRzKG9wdGlvbnMpIHtcbiAgY29uc3QgdHJhbnNwb3J0cyA9IFtdO1xuICBpZiAob3B0aW9ucykge1xuICAgIGNvbnN0IHNpbGVudCA9IG9wdGlvbnMuc2lsZW50O1xuICAgIGRlbGV0ZSBvcHRpb25zLnNpbGVudDtcblxuICAgIHRyeSB7XG4gICAgICBpZiAoIV8uaXNOaWwob3B0aW9ucy5kaXJuYW1lKSkge1xuICAgICAgICBjb25zdCBwYXJzZVNlcnZlciA9IG5ldyBEYWlseVJvdGF0ZUZpbGUoXG4gICAgICAgICAgT2JqZWN0LmFzc2lnbihcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZmlsZW5hbWU6ICdwYXJzZS1zZXJ2ZXIuaW5mbycsXG4gICAgICAgICAgICAgIGpzb246IHRydWUsXG4gICAgICAgICAgICAgIGZvcm1hdDogZm9ybWF0LmNvbWJpbmUoZm9ybWF0LnRpbWVzdGFtcCgpLCBmb3JtYXQuc3BsYXQoKSwgZm9ybWF0Lmpzb24oKSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3B0aW9uc1xuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgICAgcGFyc2VTZXJ2ZXIubmFtZSA9ICdwYXJzZS1zZXJ2ZXInO1xuICAgICAgICB0cmFuc3BvcnRzLnB1c2gocGFyc2VTZXJ2ZXIpO1xuXG4gICAgICAgIGNvbnN0IHBhcnNlU2VydmVyRXJyb3IgPSBuZXcgRGFpbHlSb3RhdGVGaWxlKFxuICAgICAgICAgIE9iamVjdC5hc3NpZ24oXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGZpbGVuYW1lOiAncGFyc2Utc2VydmVyLmVycicsXG4gICAgICAgICAgICAgIGpzb246IHRydWUsXG4gICAgICAgICAgICAgIGZvcm1hdDogZm9ybWF0LmNvbWJpbmUoZm9ybWF0LnRpbWVzdGFtcCgpLCBmb3JtYXQuc3BsYXQoKSwgZm9ybWF0Lmpzb24oKSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICAgIHsgbGV2ZWw6ICdlcnJvcicgfVxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgICAgcGFyc2VTZXJ2ZXJFcnJvci5uYW1lID0gJ3BhcnNlLXNlcnZlci1lcnJvcic7XG4gICAgICAgIHRyYW5zcG9ydHMucHVzaChwYXJzZVNlcnZlckVycm9yKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvKiAqL1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnNvbGVGb3JtYXQgPSBvcHRpb25zLmpzb24gPyBmb3JtYXQuanNvbigpIDogZm9ybWF0LnNpbXBsZSgpO1xuICAgIGNvbnN0IGNvbnNvbGVPcHRpb25zID0gT2JqZWN0LmFzc2lnbihcbiAgICAgIHtcbiAgICAgICAgY29sb3JpemU6IHRydWUsXG4gICAgICAgIG5hbWU6ICdjb25zb2xlJyxcbiAgICAgICAgc2lsZW50LFxuICAgICAgICBmb3JtYXQ6IGZvcm1hdC5jb21iaW5lKGZvcm1hdC5zcGxhdCgpLCBjb25zb2xlRm9ybWF0KSxcbiAgICAgIH0sXG4gICAgICBvcHRpb25zXG4gICAgKTtcblxuICAgIHRyYW5zcG9ydHMucHVzaChuZXcgd2luc3Rvbi50cmFuc3BvcnRzLkNvbnNvbGUoY29uc29sZU9wdGlvbnMpKTtcbiAgfVxuXG4gIGxvZ2dlci5jb25maWd1cmUoe1xuICAgIHRyYW5zcG9ydHMsXG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29uZmlndXJlTG9nZ2VyKHtcbiAgbG9nc0ZvbGRlciA9IGRlZmF1bHRzLmxvZ3NGb2xkZXIsXG4gIGpzb25Mb2dzID0gZGVmYXVsdHMuanNvbkxvZ3MsXG4gIGxvZ0xldmVsID0gd2luc3Rvbi5sZXZlbCxcbiAgdmVyYm9zZSA9IGRlZmF1bHRzLnZlcmJvc2UsXG4gIHNpbGVudCA9IGRlZmF1bHRzLnNpbGVudCxcbiAgbWF4TG9nRmlsZXMsXG59ID0ge30pIHtcbiAgaWYgKHZlcmJvc2UpIHtcbiAgICBsb2dMZXZlbCA9ICd2ZXJib3NlJztcbiAgfVxuXG4gIHdpbnN0b24ubGV2ZWwgPSBsb2dMZXZlbDtcbiAgY29uc3Qgb3B0aW9ucyA9IHt9O1xuXG4gIGlmIChsb2dzRm9sZGVyKSB7XG4gICAgaWYgKCFwYXRoLmlzQWJzb2x1dGUobG9nc0ZvbGRlcikpIHtcbiAgICAgIGxvZ3NGb2xkZXIgPSBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSwgbG9nc0ZvbGRlcik7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBmcy5ta2RpclN5bmMobG9nc0ZvbGRlcik7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLyogKi9cbiAgICB9XG4gIH1cbiAgb3B0aW9ucy5kaXJuYW1lID0gbG9nc0ZvbGRlcjtcbiAgb3B0aW9ucy5sZXZlbCA9IGxvZ0xldmVsO1xuICBvcHRpb25zLnNpbGVudCA9IHNpbGVudDtcbiAgb3B0aW9ucy5tYXhGaWxlcyA9IG1heExvZ0ZpbGVzO1xuXG4gIGlmIChqc29uTG9ncykge1xuICAgIG9wdGlvbnMuanNvbiA9IHRydWU7XG4gICAgb3B0aW9ucy5zdHJpbmdpZnkgPSB0cnVlO1xuICB9XG4gIGNvbmZpZ3VyZVRyYW5zcG9ydHMob3B0aW9ucyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRUcmFuc3BvcnQodHJhbnNwb3J0KSB7XG4gIC8vIHdlIHdpbGwgcmVtb3ZlIHRoZSBleGlzdGluZyB0cmFuc3BvcnRcbiAgLy8gYmVmb3JlIHJlcGxhY2luZyBpdCB3aXRoIGEgbmV3IG9uZVxuICByZW1vdmVUcmFuc3BvcnQodHJhbnNwb3J0Lm5hbWUpO1xuXG4gIGxvZ2dlci5hZGQodHJhbnNwb3J0KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZVRyYW5zcG9ydCh0cmFuc3BvcnQpIHtcbiAgY29uc3QgbWF0Y2hpbmdUcmFuc3BvcnQgPSBsb2dnZXIudHJhbnNwb3J0cy5maW5kKHQxID0+IHtcbiAgICByZXR1cm4gdHlwZW9mIHRyYW5zcG9ydCA9PT0gJ3N0cmluZycgPyB0MS5uYW1lID09PSB0cmFuc3BvcnQgOiB0MSA9PT0gdHJhbnNwb3J0O1xuICB9KTtcblxuICBpZiAobWF0Y2hpbmdUcmFuc3BvcnQpIHtcbiAgICBsb2dnZXIucmVtb3ZlKG1hdGNoaW5nVHJhbnNwb3J0KTtcbiAgfVxufVxuXG5leHBvcnQgeyBsb2dnZXIgfTtcbmV4cG9ydCBkZWZhdWx0IGxvZ2dlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Logger/WinstonLoggerAdapter.js b/lib/Adapters/Logger/WinstonLoggerAdapter.js new file mode 100644 index 0000000000..d953c2865e --- /dev/null +++ b/lib/Adapters/Logger/WinstonLoggerAdapter.js @@ -0,0 +1,75 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.WinstonLoggerAdapter = void 0; + +var _LoggerAdapter = require("./LoggerAdapter"); + +var _WinstonLogger = require("./WinstonLogger"); + +const MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000; + +class WinstonLoggerAdapter extends _LoggerAdapter.LoggerAdapter { + constructor(options) { + super(); + + if (options) { + (0, _WinstonLogger.configureLogger)(options); + } + } + + log() { + return _WinstonLogger.logger.log.apply(_WinstonLogger.logger, arguments); + } + + addTransport(transport) { + // Note that this is calling addTransport + // from logger. See import - confusing. + // but this is not recursive. + (0, _WinstonLogger.addTransport)(transport); + } // custom query as winston is currently limited + + + query(options, callback = () => {}) { + if (!options) { + options = {}; + } // defaults to 7 days prior + + + const from = options.from || new Date(Date.now() - 7 * MILLISECONDS_IN_A_DAY); + const until = options.until || new Date(); + const limit = options.size || 10; + const order = options.order || 'desc'; + const level = options.level || 'info'; + const queryOptions = { + from, + until, + limit, + order + }; + return new Promise((resolve, reject) => { + _WinstonLogger.logger.query(queryOptions, (err, res) => { + if (err) { + callback(err); + return reject(err); + } + + if (level === 'error') { + callback(res['parse-server-error']); + resolve(res['parse-server-error']); + } else { + callback(res['parse-server']); + resolve(res['parse-server']); + } + }); + }); + } + +} + +exports.WinstonLoggerAdapter = WinstonLoggerAdapter; +var _default = WinstonLoggerAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9Mb2dnZXIvV2luc3RvbkxvZ2dlckFkYXB0ZXIuanMiXSwibmFtZXMiOlsiTUlMTElTRUNPTkRTX0lOX0FfREFZIiwiV2luc3RvbkxvZ2dlckFkYXB0ZXIiLCJMb2dnZXJBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJvcHRpb25zIiwibG9nIiwibG9nZ2VyIiwiYXBwbHkiLCJhcmd1bWVudHMiLCJhZGRUcmFuc3BvcnQiLCJ0cmFuc3BvcnQiLCJxdWVyeSIsImNhbGxiYWNrIiwiZnJvbSIsIkRhdGUiLCJub3ciLCJ1bnRpbCIsImxpbWl0Iiwic2l6ZSIsIm9yZGVyIiwibGV2ZWwiLCJxdWVyeU9wdGlvbnMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsImVyciIsInJlcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUVBLE1BQU1BLHFCQUFxQixHQUFHLEtBQUssRUFBTCxHQUFVLEVBQVYsR0FBZSxJQUE3Qzs7QUFFTyxNQUFNQyxvQkFBTixTQUFtQ0MsNEJBQW5DLENBQWlEO0FBQ3REQyxFQUFBQSxXQUFXLENBQUNDLE9BQUQsRUFBVTtBQUNuQjs7QUFDQSxRQUFJQSxPQUFKLEVBQWE7QUFDWCwwQ0FBZ0JBLE9BQWhCO0FBQ0Q7QUFDRjs7QUFFREMsRUFBQUEsR0FBRyxHQUFHO0FBQ0osV0FBT0Msc0JBQU9ELEdBQVAsQ0FBV0UsS0FBWCxDQUFpQkQscUJBQWpCLEVBQXlCRSxTQUF6QixDQUFQO0FBQ0Q7O0FBRURDLEVBQUFBLFlBQVksQ0FBQ0MsU0FBRCxFQUFZO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBLHFDQUFhQSxTQUFiO0FBQ0QsR0FqQnFELENBbUJ0RDs7O0FBQ0FDLEVBQUFBLEtBQUssQ0FBQ1AsT0FBRCxFQUFVUSxRQUFRLEdBQUcsTUFBTSxDQUFFLENBQTdCLEVBQStCO0FBQ2xDLFFBQUksQ0FBQ1IsT0FBTCxFQUFjO0FBQ1pBLE1BQUFBLE9BQU8sR0FBRyxFQUFWO0FBQ0QsS0FIaUMsQ0FJbEM7OztBQUNBLFVBQU1TLElBQUksR0FBR1QsT0FBTyxDQUFDUyxJQUFSLElBQWdCLElBQUlDLElBQUosQ0FBU0EsSUFBSSxDQUFDQyxHQUFMLEtBQWEsSUFBSWYscUJBQTFCLENBQTdCO0FBQ0EsVUFBTWdCLEtBQUssR0FBR1osT0FBTyxDQUFDWSxLQUFSLElBQWlCLElBQUlGLElBQUosRUFBL0I7QUFDQSxVQUFNRyxLQUFLLEdBQUdiLE9BQU8sQ0FBQ2MsSUFBUixJQUFnQixFQUE5QjtBQUNBLFVBQU1DLEtBQUssR0FBR2YsT0FBTyxDQUFDZSxLQUFSLElBQWlCLE1BQS9CO0FBQ0EsVUFBTUMsS0FBSyxHQUFHaEIsT0FBTyxDQUFDZ0IsS0FBUixJQUFpQixNQUEvQjtBQUVBLFVBQU1DLFlBQVksR0FBRztBQUNuQlIsTUFBQUEsSUFEbUI7QUFFbkJHLE1BQUFBLEtBRm1CO0FBR25CQyxNQUFBQSxLQUhtQjtBQUluQkUsTUFBQUE7QUFKbUIsS0FBckI7QUFPQSxXQUFPLElBQUlHLE9BQUosQ0FBWSxDQUFDQyxPQUFELEVBQVVDLE1BQVYsS0FBcUI7QUFDdENsQiw0QkFBT0ssS0FBUCxDQUFhVSxZQUFiLEVBQTJCLENBQUNJLEdBQUQsRUFBTUMsR0FBTixLQUFjO0FBQ3ZDLFlBQUlELEdBQUosRUFBUztBQUNQYixVQUFBQSxRQUFRLENBQUNhLEdBQUQsQ0FBUjtBQUNBLGlCQUFPRCxNQUFNLENBQUNDLEdBQUQsQ0FBYjtBQUNEOztBQUVELFlBQUlMLEtBQUssS0FBSyxPQUFkLEVBQXVCO0FBQ3JCUixVQUFBQSxRQUFRLENBQUNjLEdBQUcsQ0FBQyxvQkFBRCxDQUFKLENBQVI7QUFDQUgsVUFBQUEsT0FBTyxDQUFDRyxHQUFHLENBQUMsb0JBQUQsQ0FBSixDQUFQO0FBQ0QsU0FIRCxNQUdPO0FBQ0xkLFVBQUFBLFFBQVEsQ0FBQ2MsR0FBRyxDQUFDLGNBQUQsQ0FBSixDQUFSO0FBQ0FILFVBQUFBLE9BQU8sQ0FBQ0csR0FBRyxDQUFDLGNBQUQsQ0FBSixDQUFQO0FBQ0Q7QUFDRixPQWJEO0FBY0QsS0FmTSxDQUFQO0FBZ0JEOztBQXREcUQ7OztlQXlEekN6QixvQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExvZ2dlckFkYXB0ZXIgfSBmcm9tICcuL0xvZ2dlckFkYXB0ZXInO1xuaW1wb3J0IHsgbG9nZ2VyLCBhZGRUcmFuc3BvcnQsIGNvbmZpZ3VyZUxvZ2dlciB9IGZyb20gJy4vV2luc3RvbkxvZ2dlcic7XG5cbmNvbnN0IE1JTExJU0VDT05EU19JTl9BX0RBWSA9IDI0ICogNjAgKiA2MCAqIDEwMDA7XG5cbmV4cG9ydCBjbGFzcyBXaW5zdG9uTG9nZ2VyQWRhcHRlciBleHRlbmRzIExvZ2dlckFkYXB0ZXIge1xuICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgc3VwZXIoKTtcbiAgICBpZiAob3B0aW9ucykge1xuICAgICAgY29uZmlndXJlTG9nZ2VyKG9wdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIGxvZygpIHtcbiAgICByZXR1cm4gbG9nZ2VyLmxvZy5hcHBseShsb2dnZXIsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBhZGRUcmFuc3BvcnQodHJhbnNwb3J0KSB7XG4gICAgLy8gTm90ZSB0aGF0IHRoaXMgaXMgY2FsbGluZyBhZGRUcmFuc3BvcnRcbiAgICAvLyBmcm9tIGxvZ2dlci4gIFNlZSBpbXBvcnQgLSBjb25mdXNpbmcuXG4gICAgLy8gYnV0IHRoaXMgaXMgbm90IHJlY3Vyc2l2ZS5cbiAgICBhZGRUcmFuc3BvcnQodHJhbnNwb3J0KTtcbiAgfVxuXG4gIC8vIGN1c3RvbSBxdWVyeSBhcyB3aW5zdG9uIGlzIGN1cnJlbnRseSBsaW1pdGVkXG4gIHF1ZXJ5KG9wdGlvbnMsIGNhbGxiYWNrID0gKCkgPT4ge30pIHtcbiAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICB9XG4gICAgLy8gZGVmYXVsdHMgdG8gNyBkYXlzIHByaW9yXG4gICAgY29uc3QgZnJvbSA9IG9wdGlvbnMuZnJvbSB8fCBuZXcgRGF0ZShEYXRlLm5vdygpIC0gNyAqIE1JTExJU0VDT05EU19JTl9BX0RBWSk7XG4gICAgY29uc3QgdW50aWwgPSBvcHRpb25zLnVudGlsIHx8IG5ldyBEYXRlKCk7XG4gICAgY29uc3QgbGltaXQgPSBvcHRpb25zLnNpemUgfHwgMTA7XG4gICAgY29uc3Qgb3JkZXIgPSBvcHRpb25zLm9yZGVyIHx8ICdkZXNjJztcbiAgICBjb25zdCBsZXZlbCA9IG9wdGlvbnMubGV2ZWwgfHwgJ2luZm8nO1xuXG4gICAgY29uc3QgcXVlcnlPcHRpb25zID0ge1xuICAgICAgZnJvbSxcbiAgICAgIHVudGlsLFxuICAgICAgbGltaXQsXG4gICAgICBvcmRlcixcbiAgICB9O1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGxvZ2dlci5xdWVyeShxdWVyeU9wdGlvbnMsIChlcnIsIHJlcykgPT4ge1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgY2FsbGJhY2soZXJyKTtcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobGV2ZWwgPT09ICdlcnJvcicpIHtcbiAgICAgICAgICBjYWxsYmFjayhyZXNbJ3BhcnNlLXNlcnZlci1lcnJvciddKTtcbiAgICAgICAgICByZXNvbHZlKHJlc1sncGFyc2Utc2VydmVyLWVycm9yJ10pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNhbGxiYWNrKHJlc1sncGFyc2Utc2VydmVyJ10pO1xuICAgICAgICAgIHJlc29sdmUocmVzWydwYXJzZS1zZXJ2ZXInXSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFdpbnN0b25Mb2dnZXJBZGFwdGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/MessageQueue/EventEmitterMQ.js b/lib/Adapters/MessageQueue/EventEmitterMQ.js new file mode 100644 index 0000000000..ddf372cd6d --- /dev/null +++ b/lib/Adapters/MessageQueue/EventEmitterMQ.js @@ -0,0 +1,73 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.EventEmitterMQ = void 0; + +var _events = _interopRequireDefault(require("events")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const emitter = new _events.default.EventEmitter(); +const subscriptions = new Map(); + +function unsubscribe(channel) { + if (!subscriptions.has(channel)) { + //console.log('No channel to unsub from'); + return; + } //console.log('unsub ', channel); + + + emitter.removeListener(channel, subscriptions.get(channel)); + subscriptions.delete(channel); +} + +class Publisher { + constructor(emitter) { + this.emitter = emitter; + } + + publish(channel, message) { + this.emitter.emit(channel, message); + } + +} + +class Consumer extends _events.default.EventEmitter { + constructor(emitter) { + super(); + this.emitter = emitter; + } + + subscribe(channel) { + unsubscribe(channel); + + const handler = message => { + this.emit('message', channel, message); + }; + + subscriptions.set(channel, handler); + this.emitter.on(channel, handler); + } + + unsubscribe(channel) { + unsubscribe(channel); + } + +} + +function createPublisher() { + return new Publisher(emitter); +} + +function createSubscriber() { + return new Consumer(emitter); +} + +const EventEmitterMQ = { + createPublisher, + createSubscriber +}; +exports.EventEmitterMQ = EventEmitterMQ; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9NZXNzYWdlUXVldWUvRXZlbnRFbWl0dGVyTVEuanMiXSwibmFtZXMiOlsiZW1pdHRlciIsImV2ZW50cyIsIkV2ZW50RW1pdHRlciIsInN1YnNjcmlwdGlvbnMiLCJNYXAiLCJ1bnN1YnNjcmliZSIsImNoYW5uZWwiLCJoYXMiLCJyZW1vdmVMaXN0ZW5lciIsImdldCIsImRlbGV0ZSIsIlB1Ymxpc2hlciIsImNvbnN0cnVjdG9yIiwicHVibGlzaCIsIm1lc3NhZ2UiLCJlbWl0IiwiQ29uc3VtZXIiLCJzdWJzY3JpYmUiLCJoYW5kbGVyIiwic2V0Iiwib24iLCJjcmVhdGVQdWJsaXNoZXIiLCJjcmVhdGVTdWJzY3JpYmVyIiwiRXZlbnRFbWl0dGVyTVEiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7OztBQUVBLE1BQU1BLE9BQU8sR0FBRyxJQUFJQyxnQkFBT0MsWUFBWCxFQUFoQjtBQUNBLE1BQU1DLGFBQWEsR0FBRyxJQUFJQyxHQUFKLEVBQXRCOztBQUVBLFNBQVNDLFdBQVQsQ0FBcUJDLE9BQXJCLEVBQXNDO0FBQ3BDLE1BQUksQ0FBQ0gsYUFBYSxDQUFDSSxHQUFkLENBQWtCRCxPQUFsQixDQUFMLEVBQWlDO0FBQy9CO0FBQ0E7QUFDRCxHQUptQyxDQUtwQzs7O0FBQ0FOLEVBQUFBLE9BQU8sQ0FBQ1EsY0FBUixDQUF1QkYsT0FBdkIsRUFBZ0NILGFBQWEsQ0FBQ00sR0FBZCxDQUFrQkgsT0FBbEIsQ0FBaEM7QUFDQUgsRUFBQUEsYUFBYSxDQUFDTyxNQUFkLENBQXFCSixPQUFyQjtBQUNEOztBQUVELE1BQU1LLFNBQU4sQ0FBZ0I7QUFHZEMsRUFBQUEsV0FBVyxDQUFDWixPQUFELEVBQWU7QUFDeEIsU0FBS0EsT0FBTCxHQUFlQSxPQUFmO0FBQ0Q7O0FBRURhLEVBQUFBLE9BQU8sQ0FBQ1AsT0FBRCxFQUFrQlEsT0FBbEIsRUFBeUM7QUFDOUMsU0FBS2QsT0FBTCxDQUFhZSxJQUFiLENBQWtCVCxPQUFsQixFQUEyQlEsT0FBM0I7QUFDRDs7QUFUYTs7QUFZaEIsTUFBTUUsUUFBTixTQUF1QmYsZ0JBQU9DLFlBQTlCLENBQTJDO0FBR3pDVSxFQUFBQSxXQUFXLENBQUNaLE9BQUQsRUFBZTtBQUN4QjtBQUNBLFNBQUtBLE9BQUwsR0FBZUEsT0FBZjtBQUNEOztBQUVEaUIsRUFBQUEsU0FBUyxDQUFDWCxPQUFELEVBQXdCO0FBQy9CRCxJQUFBQSxXQUFXLENBQUNDLE9BQUQsQ0FBWDs7QUFDQSxVQUFNWSxPQUFPLEdBQUdKLE9BQU8sSUFBSTtBQUN6QixXQUFLQyxJQUFMLENBQVUsU0FBVixFQUFxQlQsT0FBckIsRUFBOEJRLE9BQTlCO0FBQ0QsS0FGRDs7QUFHQVgsSUFBQUEsYUFBYSxDQUFDZ0IsR0FBZCxDQUFrQmIsT0FBbEIsRUFBMkJZLE9BQTNCO0FBQ0EsU0FBS2xCLE9BQUwsQ0FBYW9CLEVBQWIsQ0FBZ0JkLE9BQWhCLEVBQXlCWSxPQUF6QjtBQUNEOztBQUVEYixFQUFBQSxXQUFXLENBQUNDLE9BQUQsRUFBd0I7QUFDakNELElBQUFBLFdBQVcsQ0FBQ0MsT0FBRCxDQUFYO0FBQ0Q7O0FBbkJ3Qzs7QUFzQjNDLFNBQVNlLGVBQVQsR0FBZ0M7QUFDOUIsU0FBTyxJQUFJVixTQUFKLENBQWNYLE9BQWQsQ0FBUDtBQUNEOztBQUVELFNBQVNzQixnQkFBVCxHQUFpQztBQUMvQixTQUFPLElBQUlOLFFBQUosQ0FBYWhCLE9BQWIsQ0FBUDtBQUNEOztBQUVELE1BQU11QixjQUFjLEdBQUc7QUFDckJGLEVBQUFBLGVBRHFCO0FBRXJCQyxFQUFBQTtBQUZxQixDQUF2QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBldmVudHMgZnJvbSAnZXZlbnRzJztcblxuY29uc3QgZW1pdHRlciA9IG5ldyBldmVudHMuRXZlbnRFbWl0dGVyKCk7XG5jb25zdCBzdWJzY3JpcHRpb25zID0gbmV3IE1hcCgpO1xuXG5mdW5jdGlvbiB1bnN1YnNjcmliZShjaGFubmVsOiBzdHJpbmcpIHtcbiAgaWYgKCFzdWJzY3JpcHRpb25zLmhhcyhjaGFubmVsKSkge1xuICAgIC8vY29uc29sZS5sb2coJ05vIGNoYW5uZWwgdG8gdW5zdWIgZnJvbScpO1xuICAgIHJldHVybjtcbiAgfVxuICAvL2NvbnNvbGUubG9nKCd1bnN1YiAnLCBjaGFubmVsKTtcbiAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihjaGFubmVsLCBzdWJzY3JpcHRpb25zLmdldChjaGFubmVsKSk7XG4gIHN1YnNjcmlwdGlvbnMuZGVsZXRlKGNoYW5uZWwpO1xufVxuXG5jbGFzcyBQdWJsaXNoZXIge1xuICBlbWl0dGVyOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoZW1pdHRlcjogYW55KSB7XG4gICAgdGhpcy5lbWl0dGVyID0gZW1pdHRlcjtcbiAgfVxuXG4gIHB1Ymxpc2goY2hhbm5lbDogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmVtaXR0ZXIuZW1pdChjaGFubmVsLCBtZXNzYWdlKTtcbiAgfVxufVxuXG5jbGFzcyBDb25zdW1lciBleHRlbmRzIGV2ZW50cy5FdmVudEVtaXR0ZXIge1xuICBlbWl0dGVyOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoZW1pdHRlcjogYW55KSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmVtaXR0ZXIgPSBlbWl0dGVyO1xuICB9XG5cbiAgc3Vic2NyaWJlKGNoYW5uZWw6IHN0cmluZyk6IHZvaWQge1xuICAgIHVuc3Vic2NyaWJlKGNoYW5uZWwpO1xuICAgIGNvbnN0IGhhbmRsZXIgPSBtZXNzYWdlID0+IHtcbiAgICAgIHRoaXMuZW1pdCgnbWVzc2FnZScsIGNoYW5uZWwsIG1lc3NhZ2UpO1xuICAgIH07XG4gICAgc3Vic2NyaXB0aW9ucy5zZXQoY2hhbm5lbCwgaGFuZGxlcik7XG4gICAgdGhpcy5lbWl0dGVyLm9uKGNoYW5uZWwsIGhhbmRsZXIpO1xuICB9XG5cbiAgdW5zdWJzY3JpYmUoY2hhbm5lbDogc3RyaW5nKTogdm9pZCB7XG4gICAgdW5zdWJzY3JpYmUoY2hhbm5lbCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlUHVibGlzaGVyKCk6IGFueSB7XG4gIHJldHVybiBuZXcgUHVibGlzaGVyKGVtaXR0ZXIpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVTdWJzY3JpYmVyKCk6IGFueSB7XG4gIHJldHVybiBuZXcgQ29uc3VtZXIoZW1pdHRlcik7XG59XG5cbmNvbnN0IEV2ZW50RW1pdHRlck1RID0ge1xuICBjcmVhdGVQdWJsaXNoZXIsXG4gIGNyZWF0ZVN1YnNjcmliZXIsXG59O1xuXG5leHBvcnQgeyBFdmVudEVtaXR0ZXJNUSB9O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/PubSub/EventEmitterPubSub.js b/lib/Adapters/PubSub/EventEmitterPubSub.js new file mode 100644 index 0000000000..8c3c66ff90 --- /dev/null +++ b/lib/Adapters/PubSub/EventEmitterPubSub.js @@ -0,0 +1,69 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.EventEmitterPubSub = void 0; + +var _events = _interopRequireDefault(require("events")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const emitter = new _events.default.EventEmitter(); + +class Publisher { + constructor(emitter) { + this.emitter = emitter; + } + + publish(channel, message) { + this.emitter.emit(channel, message); + } + +} + +class Subscriber extends _events.default.EventEmitter { + constructor(emitter) { + super(); + this.emitter = emitter; + this.subscriptions = new Map(); + } + + subscribe(channel) { + const handler = message => { + this.emit('message', channel, message); + }; + + this.subscriptions.set(channel, handler); + this.emitter.on(channel, handler); + } + + unsubscribe(channel) { + if (!this.subscriptions.has(channel)) { + return; + } + + this.emitter.removeListener(channel, this.subscriptions.get(channel)); + this.subscriptions.delete(channel); + } + +} + +function createPublisher() { + return new Publisher(emitter); +} + +function createSubscriber() { + // createSubscriber is called once at live query server start + // to avoid max listeners warning, we should clean up the event emitter + // each time this function is called + emitter.removeAllListeners(); + return new Subscriber(emitter); +} + +const EventEmitterPubSub = { + createPublisher, + createSubscriber +}; +exports.EventEmitterPubSub = EventEmitterPubSub; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9QdWJTdWIvRXZlbnRFbWl0dGVyUHViU3ViLmpzIl0sIm5hbWVzIjpbImVtaXR0ZXIiLCJldmVudHMiLCJFdmVudEVtaXR0ZXIiLCJQdWJsaXNoZXIiLCJjb25zdHJ1Y3RvciIsInB1Ymxpc2giLCJjaGFubmVsIiwibWVzc2FnZSIsImVtaXQiLCJTdWJzY3JpYmVyIiwic3Vic2NyaXB0aW9ucyIsIk1hcCIsInN1YnNjcmliZSIsImhhbmRsZXIiLCJzZXQiLCJvbiIsInVuc3Vic2NyaWJlIiwiaGFzIiwicmVtb3ZlTGlzdGVuZXIiLCJnZXQiLCJkZWxldGUiLCJjcmVhdGVQdWJsaXNoZXIiLCJjcmVhdGVTdWJzY3JpYmVyIiwicmVtb3ZlQWxsTGlzdGVuZXJzIiwiRXZlbnRFbWl0dGVyUHViU3ViIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7Ozs7QUFFQSxNQUFNQSxPQUFPLEdBQUcsSUFBSUMsZ0JBQU9DLFlBQVgsRUFBaEI7O0FBRUEsTUFBTUMsU0FBTixDQUFnQjtBQUdkQyxFQUFBQSxXQUFXLENBQUNKLE9BQUQsRUFBZTtBQUN4QixTQUFLQSxPQUFMLEdBQWVBLE9BQWY7QUFDRDs7QUFFREssRUFBQUEsT0FBTyxDQUFDQyxPQUFELEVBQWtCQyxPQUFsQixFQUF5QztBQUM5QyxTQUFLUCxPQUFMLENBQWFRLElBQWIsQ0FBa0JGLE9BQWxCLEVBQTJCQyxPQUEzQjtBQUNEOztBQVRhOztBQVloQixNQUFNRSxVQUFOLFNBQXlCUixnQkFBT0MsWUFBaEMsQ0FBNkM7QUFJM0NFLEVBQUFBLFdBQVcsQ0FBQ0osT0FBRCxFQUFlO0FBQ3hCO0FBQ0EsU0FBS0EsT0FBTCxHQUFlQSxPQUFmO0FBQ0EsU0FBS1UsYUFBTCxHQUFxQixJQUFJQyxHQUFKLEVBQXJCO0FBQ0Q7O0FBRURDLEVBQUFBLFNBQVMsQ0FBQ04sT0FBRCxFQUF3QjtBQUMvQixVQUFNTyxPQUFPLEdBQUdOLE9BQU8sSUFBSTtBQUN6QixXQUFLQyxJQUFMLENBQVUsU0FBVixFQUFxQkYsT0FBckIsRUFBOEJDLE9BQTlCO0FBQ0QsS0FGRDs7QUFHQSxTQUFLRyxhQUFMLENBQW1CSSxHQUFuQixDQUF1QlIsT0FBdkIsRUFBZ0NPLE9BQWhDO0FBQ0EsU0FBS2IsT0FBTCxDQUFhZSxFQUFiLENBQWdCVCxPQUFoQixFQUF5Qk8sT0FBekI7QUFDRDs7QUFFREcsRUFBQUEsV0FBVyxDQUFDVixPQUFELEVBQXdCO0FBQ2pDLFFBQUksQ0FBQyxLQUFLSSxhQUFMLENBQW1CTyxHQUFuQixDQUF1QlgsT0FBdkIsQ0FBTCxFQUFzQztBQUNwQztBQUNEOztBQUNELFNBQUtOLE9BQUwsQ0FBYWtCLGNBQWIsQ0FBNEJaLE9BQTVCLEVBQXFDLEtBQUtJLGFBQUwsQ0FBbUJTLEdBQW5CLENBQXVCYixPQUF2QixDQUFyQztBQUNBLFNBQUtJLGFBQUwsQ0FBbUJVLE1BQW5CLENBQTBCZCxPQUExQjtBQUNEOztBQXhCMEM7O0FBMkI3QyxTQUFTZSxlQUFULEdBQWdDO0FBQzlCLFNBQU8sSUFBSWxCLFNBQUosQ0FBY0gsT0FBZCxDQUFQO0FBQ0Q7O0FBRUQsU0FBU3NCLGdCQUFULEdBQWlDO0FBQy9CO0FBQ0E7QUFDQTtBQUNBdEIsRUFBQUEsT0FBTyxDQUFDdUIsa0JBQVI7QUFDQSxTQUFPLElBQUlkLFVBQUosQ0FBZVQsT0FBZixDQUFQO0FBQ0Q7O0FBRUQsTUFBTXdCLGtCQUFrQixHQUFHO0FBQ3pCSCxFQUFBQSxlQUR5QjtBQUV6QkMsRUFBQUE7QUFGeUIsQ0FBM0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZXZlbnRzIGZyb20gJ2V2ZW50cyc7XG5cbmNvbnN0IGVtaXR0ZXIgPSBuZXcgZXZlbnRzLkV2ZW50RW1pdHRlcigpO1xuXG5jbGFzcyBQdWJsaXNoZXIge1xuICBlbWl0dGVyOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoZW1pdHRlcjogYW55KSB7XG4gICAgdGhpcy5lbWl0dGVyID0gZW1pdHRlcjtcbiAgfVxuXG4gIHB1Ymxpc2goY2hhbm5lbDogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmVtaXR0ZXIuZW1pdChjaGFubmVsLCBtZXNzYWdlKTtcbiAgfVxufVxuXG5jbGFzcyBTdWJzY3JpYmVyIGV4dGVuZHMgZXZlbnRzLkV2ZW50RW1pdHRlciB7XG4gIGVtaXR0ZXI6IGFueTtcbiAgc3Vic2NyaXB0aW9uczogYW55O1xuXG4gIGNvbnN0cnVjdG9yKGVtaXR0ZXI6IGFueSkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5lbWl0dGVyID0gZW1pdHRlcjtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMgPSBuZXcgTWFwKCk7XG4gIH1cblxuICBzdWJzY3JpYmUoY2hhbm5lbDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgaGFuZGxlciA9IG1lc3NhZ2UgPT4ge1xuICAgICAgdGhpcy5lbWl0KCdtZXNzYWdlJywgY2hhbm5lbCwgbWVzc2FnZSk7XG4gICAgfTtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuc2V0KGNoYW5uZWwsIGhhbmRsZXIpO1xuICAgIHRoaXMuZW1pdHRlci5vbihjaGFubmVsLCBoYW5kbGVyKTtcbiAgfVxuXG4gIHVuc3Vic2NyaWJlKGNoYW5uZWw6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghdGhpcy5zdWJzY3JpcHRpb25zLmhhcyhjaGFubmVsKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmVtaXR0ZXIucmVtb3ZlTGlzdGVuZXIoY2hhbm5lbCwgdGhpcy5zdWJzY3JpcHRpb25zLmdldChjaGFubmVsKSk7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmRlbGV0ZShjaGFubmVsKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVQdWJsaXNoZXIoKTogYW55IHtcbiAgcmV0dXJuIG5ldyBQdWJsaXNoZXIoZW1pdHRlcik7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVN1YnNjcmliZXIoKTogYW55IHtcbiAgLy8gY3JlYXRlU3Vic2NyaWJlciBpcyBjYWxsZWQgb25jZSBhdCBsaXZlIHF1ZXJ5IHNlcnZlciBzdGFydFxuICAvLyB0byBhdm9pZCBtYXggbGlzdGVuZXJzIHdhcm5pbmcsIHdlIHNob3VsZCBjbGVhbiB1cCB0aGUgZXZlbnQgZW1pdHRlclxuICAvLyBlYWNoIHRpbWUgdGhpcyBmdW5jdGlvbiBpcyBjYWxsZWRcbiAgZW1pdHRlci5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcbiAgcmV0dXJuIG5ldyBTdWJzY3JpYmVyKGVtaXR0ZXIpO1xufVxuXG5jb25zdCBFdmVudEVtaXR0ZXJQdWJTdWIgPSB7XG4gIGNyZWF0ZVB1Ymxpc2hlcixcbiAgY3JlYXRlU3Vic2NyaWJlcixcbn07XG5cbmV4cG9ydCB7IEV2ZW50RW1pdHRlclB1YlN1YiB9O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/PubSub/PubSubAdapter.js b/lib/Adapters/PubSub/PubSubAdapter.js new file mode 100644 index 0000000000..13ad87a701 --- /dev/null +++ b/lib/Adapters/PubSub/PubSubAdapter.js @@ -0,0 +1,39 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.PubSubAdapter = void 0; + +/*eslint no-unused-vars: "off"*/ + +/** + * @module Adapters + */ + +/** + * @interface PubSubAdapter + */ +class PubSubAdapter { + /** + * @returns {PubSubAdapter.Publisher} + */ + static createPublisher() {} + /** + * @returns {PubSubAdapter.Subscriber} + */ + + + static createSubscriber() {} + +} +/** + * @interface Publisher + * @memberof PubSubAdapter + */ + + +exports.PubSubAdapter = PubSubAdapter; +var _default = PubSubAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9QdWJTdWIvUHViU3ViQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJQdWJTdWJBZGFwdGVyIiwiY3JlYXRlUHVibGlzaGVyIiwiY3JlYXRlU3Vic2NyaWJlciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBO0FBQ0E7QUFDQTs7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNQSxhQUFOLENBQW9CO0FBQ3pCO0FBQ0Y7QUFDQTtBQUNFLFNBQU9DLGVBQVAsR0FBeUIsQ0FBRTtBQUMzQjtBQUNGO0FBQ0E7OztBQUNFLFNBQU9DLGdCQUFQLEdBQTBCLENBQUU7O0FBUkg7QUFXM0I7QUFDQTtBQUNBO0FBQ0E7Ozs7ZUEyQmVGLGEiLCJzb3VyY2VzQ29udGVudCI6WyIvKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG4vKipcbiAqIEBtb2R1bGUgQWRhcHRlcnNcbiAqL1xuLyoqXG4gKiBAaW50ZXJmYWNlIFB1YlN1YkFkYXB0ZXJcbiAqL1xuZXhwb3J0IGNsYXNzIFB1YlN1YkFkYXB0ZXIge1xuICAvKipcbiAgICogQHJldHVybnMge1B1YlN1YkFkYXB0ZXIuUHVibGlzaGVyfVxuICAgKi9cbiAgc3RhdGljIGNyZWF0ZVB1Ymxpc2hlcigpIHt9XG4gIC8qKlxuICAgKiBAcmV0dXJucyB7UHViU3ViQWRhcHRlci5TdWJzY3JpYmVyfVxuICAgKi9cbiAgc3RhdGljIGNyZWF0ZVN1YnNjcmliZXIoKSB7fVxufVxuXG4vKipcbiAqIEBpbnRlcmZhY2UgUHVibGlzaGVyXG4gKiBAbWVtYmVyb2YgUHViU3ViQWRhcHRlclxuICovXG5pbnRlcmZhY2UgUHVibGlzaGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBjaGFubmVsIHRoZSBjaGFubmVsIGluIHdoaWNoIHRvIHB1Ymxpc2hcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgdGhlIG1lc3NhZ2UgdG8gcHVibGlzaFxuICAgKi9cbiAgcHVibGlzaChjaGFubmVsOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQ7XG59XG5cbi8qKlxuICogQGludGVyZmFjZSBTdWJzY3JpYmVyXG4gKiBAbWVtYmVyb2YgUHViU3ViQWRhcHRlclxuICovXG5pbnRlcmZhY2UgU3Vic2NyaWJlciB7XG4gIC8qKlxuICAgKiBjYWxsZWQgd2hlbiBhIG5ldyBzdWJzY3JpcHRpb24gdGhlIGNoYW5uZWwgaXMgcmVxdWlyZWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IGNoYW5uZWwgdGhlIGNoYW5uZWwgdG8gc3Vic2NyaWJlXG4gICAqL1xuICBzdWJzY3JpYmUoY2hhbm5lbDogc3RyaW5nKTogdm9pZDtcblxuICAvKipcbiAgICogY2FsbGVkIHdoZW4gdGhlIHN1YnNjcmlwdGlvbiBmcm9tIHRoZSBjaGFubmVsIHNob3VsZCBiZSBzdG9wcGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBjaGFubmVsXG4gICAqL1xuICB1bnN1YnNjcmliZShjaGFubmVsOiBzdHJpbmcpOiB2b2lkO1xufVxuXG5leHBvcnQgZGVmYXVsdCBQdWJTdWJBZGFwdGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/PubSub/RedisPubSub.js b/lib/Adapters/PubSub/RedisPubSub.js new file mode 100644 index 0000000000..cb4a03c10a --- /dev/null +++ b/lib/Adapters/PubSub/RedisPubSub.js @@ -0,0 +1,33 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.RedisPubSub = void 0; + +var _redis = _interopRequireDefault(require("redis")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function createPublisher({ + redisURL, + redisOptions = {} +}) { + redisOptions.no_ready_check = true; + return _redis.default.createClient(redisURL, redisOptions); +} + +function createSubscriber({ + redisURL, + redisOptions = {} +}) { + redisOptions.no_ready_check = true; + return _redis.default.createClient(redisURL, redisOptions); +} + +const RedisPubSub = { + createPublisher, + createSubscriber +}; +exports.RedisPubSub = RedisPubSub; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9QdWJTdWIvUmVkaXNQdWJTdWIuanMiXSwibmFtZXMiOlsiY3JlYXRlUHVibGlzaGVyIiwicmVkaXNVUkwiLCJyZWRpc09wdGlvbnMiLCJub19yZWFkeV9jaGVjayIsInJlZGlzIiwiY3JlYXRlQ2xpZW50IiwiY3JlYXRlU3Vic2NyaWJlciIsIlJlZGlzUHViU3ViIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7Ozs7QUFFQSxTQUFTQSxlQUFULENBQXlCO0FBQUVDLEVBQUFBLFFBQUY7QUFBWUMsRUFBQUEsWUFBWSxHQUFHO0FBQTNCLENBQXpCLEVBQStEO0FBQzdEQSxFQUFBQSxZQUFZLENBQUNDLGNBQWIsR0FBOEIsSUFBOUI7QUFDQSxTQUFPQyxlQUFNQyxZQUFOLENBQW1CSixRQUFuQixFQUE2QkMsWUFBN0IsQ0FBUDtBQUNEOztBQUVELFNBQVNJLGdCQUFULENBQTBCO0FBQUVMLEVBQUFBLFFBQUY7QUFBWUMsRUFBQUEsWUFBWSxHQUFHO0FBQTNCLENBQTFCLEVBQWdFO0FBQzlEQSxFQUFBQSxZQUFZLENBQUNDLGNBQWIsR0FBOEIsSUFBOUI7QUFDQSxTQUFPQyxlQUFNQyxZQUFOLENBQW1CSixRQUFuQixFQUE2QkMsWUFBN0IsQ0FBUDtBQUNEOztBQUVELE1BQU1LLFdBQVcsR0FBRztBQUNsQlAsRUFBQUEsZUFEa0I7QUFFbEJNLEVBQUFBO0FBRmtCLENBQXBCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHJlZGlzIGZyb20gJ3JlZGlzJztcblxuZnVuY3Rpb24gY3JlYXRlUHVibGlzaGVyKHsgcmVkaXNVUkwsIHJlZGlzT3B0aW9ucyA9IHt9IH0pOiBhbnkge1xuICByZWRpc09wdGlvbnMubm9fcmVhZHlfY2hlY2sgPSB0cnVlO1xuICByZXR1cm4gcmVkaXMuY3JlYXRlQ2xpZW50KHJlZGlzVVJMLCByZWRpc09wdGlvbnMpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVTdWJzY3JpYmVyKHsgcmVkaXNVUkwsIHJlZGlzT3B0aW9ucyA9IHt9IH0pOiBhbnkge1xuICByZWRpc09wdGlvbnMubm9fcmVhZHlfY2hlY2sgPSB0cnVlO1xuICByZXR1cm4gcmVkaXMuY3JlYXRlQ2xpZW50KHJlZGlzVVJMLCByZWRpc09wdGlvbnMpO1xufVxuXG5jb25zdCBSZWRpc1B1YlN1YiA9IHtcbiAgY3JlYXRlUHVibGlzaGVyLFxuICBjcmVhdGVTdWJzY3JpYmVyLFxufTtcblxuZXhwb3J0IHsgUmVkaXNQdWJTdWIgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Push/PushAdapter.js b/lib/Adapters/Push/PushAdapter.js new file mode 100644 index 0000000000..72fd17e1bf --- /dev/null +++ b/lib/Adapters/Push/PushAdapter.js @@ -0,0 +1,50 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.PushAdapter = void 0; + +/*eslint no-unused-vars: "off"*/ +// Push Adapter +// +// Allows you to change the push notification mechanism. +// +// Adapter classes must implement the following functions: +// * getValidPushTypes() +// * send(devices, installations, pushStatus) +// +// Default is ParsePushAdapter, which uses GCM for +// android push and APNS for ios push. + +/** + * @module Adapters + */ + +/** + * @interface PushAdapter + */ +class PushAdapter { + /** + * @param {any} body + * @param {Parse.Installation[]} installations + * @param {any} pushStatus + * @returns {Promise} + */ + send(body, installations, pushStatus) {} + /** + * Get an array of valid push types. + * @returns {Array} An array of valid push types + */ + + + getValidPushTypes() { + return []; + } + +} + +exports.PushAdapter = PushAdapter; +var _default = PushAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9QdXNoL1B1c2hBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIlB1c2hBZGFwdGVyIiwic2VuZCIsImJvZHkiLCJpbnN0YWxsYXRpb25zIiwicHVzaFN0YXR1cyIsImdldFZhbGlkUHVzaFR5cGVzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTUEsV0FBTixDQUFrQjtBQUN2QjtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDRUMsRUFBQUEsSUFBSSxDQUFDQyxJQUFELEVBQVlDLGFBQVosRUFBa0NDLFVBQWxDLEVBQWdFLENBQUU7QUFFdEU7QUFDRjtBQUNBO0FBQ0E7OztBQUNFQyxFQUFBQSxpQkFBaUIsR0FBYTtBQUM1QixXQUFPLEVBQVA7QUFDRDs7QUFmc0I7OztlQWtCVkwsVyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG4vKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG4vLyBQdXNoIEFkYXB0ZXJcbi8vXG4vLyBBbGxvd3MgeW91IHRvIGNoYW5nZSB0aGUgcHVzaCBub3RpZmljYXRpb24gbWVjaGFuaXNtLlxuLy9cbi8vIEFkYXB0ZXIgY2xhc3NlcyBtdXN0IGltcGxlbWVudCB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uczpcbi8vICogZ2V0VmFsaWRQdXNoVHlwZXMoKVxuLy8gKiBzZW5kKGRldmljZXMsIGluc3RhbGxhdGlvbnMsIHB1c2hTdGF0dXMpXG4vL1xuLy8gRGVmYXVsdCBpcyBQYXJzZVB1c2hBZGFwdGVyLCB3aGljaCB1c2VzIEdDTSBmb3Jcbi8vIGFuZHJvaWQgcHVzaCBhbmQgQVBOUyBmb3IgaW9zIHB1c2guXG5cbi8qKlxuICogQG1vZHVsZSBBZGFwdGVyc1xuICovXG4vKipcbiAqIEBpbnRlcmZhY2UgUHVzaEFkYXB0ZXJcbiAqL1xuZXhwb3J0IGNsYXNzIFB1c2hBZGFwdGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7YW55fSBib2R5XG4gICAqIEBwYXJhbSB7UGFyc2UuSW5zdGFsbGF0aW9uW119IGluc3RhbGxhdGlvbnNcbiAgICogQHBhcmFtIHthbnl9IHB1c2hTdGF0dXNcbiAgICogQHJldHVybnMge1Byb21pc2V9XG4gICAqL1xuICBzZW5kKGJvZHk6IGFueSwgaW5zdGFsbGF0aW9uczogYW55W10sIHB1c2hTdGF0dXM6IGFueSk6ID9Qcm9taXNlPCo+IHt9XG5cbiAgLyoqXG4gICAqIEdldCBhbiBhcnJheSBvZiB2YWxpZCBwdXNoIHR5cGVzLlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IEFuIGFycmF5IG9mIHZhbGlkIHB1c2ggdHlwZXNcbiAgICovXG4gIGdldFZhbGlkUHVzaFR5cGVzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gW107XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUHVzaEFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Storage/Mongo/MongoCollection.js b/lib/Adapters/Storage/Mongo/MongoCollection.js new file mode 100644 index 0000000000..3845114bc5 --- /dev/null +++ b/lib/Adapters/Storage/Mongo/MongoCollection.js @@ -0,0 +1,229 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +const mongodb = require('mongodb'); + +const Collection = mongodb.Collection; + +class MongoCollection { + constructor(mongoCollection) { + this._mongoCollection = mongoCollection; + } // Does a find with "smart indexing". + // Currently this just means, if it needs a geoindex and there is + // none, then build the geoindex. + // This could be improved a lot but it's not clear if that's a good + // idea. Or even if this behavior is a good idea. + + + find(query, { + skip, + limit, + sort, + keys, + maxTimeMS, + readPreference, + hint, + caseInsensitive, + explain + } = {}) { + // Support for Full Text Search - $text + if (keys && keys.$score) { + delete keys.$score; + keys.score = { + $meta: 'textScore' + }; + } + + return this._rawFind(query, { + skip, + limit, + sort, + keys, + maxTimeMS, + readPreference, + hint, + caseInsensitive, + explain + }).catch(error => { + // Check for "no geoindex" error + if (error.code != 17007 && !error.message.match(/unable to find index for .geoNear/)) { + throw error; + } // Figure out what key needs an index + + + const key = error.message.match(/field=([A-Za-z_0-9]+) /)[1]; + + if (!key) { + throw error; + } + + var index = {}; + index[key] = '2d'; + return this._mongoCollection.createIndex(index) // Retry, but just once. + .then(() => this._rawFind(query, { + skip, + limit, + sort, + keys, + maxTimeMS, + readPreference, + hint, + caseInsensitive, + explain + })); + }); + } + /** + * Collation to support case insensitive queries + */ + + + static caseInsensitiveCollation() { + return { + locale: 'en_US', + strength: 2 + }; + } + + _rawFind(query, { + skip, + limit, + sort, + keys, + maxTimeMS, + readPreference, + hint, + caseInsensitive, + explain + } = {}) { + let findOperation = this._mongoCollection.find(query, { + skip, + limit, + sort, + readPreference, + hint + }); + + if (keys) { + findOperation = findOperation.project(keys); + } + + if (caseInsensitive) { + findOperation = findOperation.collation(MongoCollection.caseInsensitiveCollation()); + } + + if (maxTimeMS) { + findOperation = findOperation.maxTimeMS(maxTimeMS); + } + + return explain ? findOperation.explain(explain) : findOperation.toArray(); + } + + count(query, { + skip, + limit, + sort, + maxTimeMS, + readPreference, + hint + } = {}) { + // If query is empty, then use estimatedDocumentCount instead. + // This is due to countDocuments performing a scan, + // which greatly increases execution time when being run on large collections. + // See https://github.com/Automattic/mongoose/issues/6713 for more info regarding this problem. + if (typeof query !== 'object' || !Object.keys(query).length) { + return this._mongoCollection.estimatedDocumentCount({ + maxTimeMS + }); + } + + const countOperation = this._mongoCollection.countDocuments(query, { + skip, + limit, + sort, + maxTimeMS, + readPreference, + hint + }); + + return countOperation; + } + + distinct(field, query) { + return this._mongoCollection.distinct(field, query); + } + + aggregate(pipeline, { + maxTimeMS, + readPreference, + hint, + explain + } = {}) { + return this._mongoCollection.aggregate(pipeline, { + maxTimeMS, + readPreference, + hint, + explain + }).toArray(); + } + + insertOne(object, session) { + return this._mongoCollection.insertOne(object, { + session + }); + } // Atomically updates data in the database for a single (first) object that matched the query + // If there is nothing that matches the query - does insert + // Postgres Note: `INSERT ... ON CONFLICT UPDATE` that is available since 9.5. + + + upsertOne(query, update, session) { + return this._mongoCollection.updateOne(query, update, { + upsert: true, + session + }); + } + + updateOne(query, update) { + return this._mongoCollection.updateOne(query, update); + } + + updateMany(query, update, session) { + return this._mongoCollection.updateMany(query, update, { + session + }); + } + + deleteMany(query, session) { + return this._mongoCollection.deleteMany(query, { + session + }); + } + + _ensureSparseUniqueIndexInBackground(indexRequest) { + return new Promise((resolve, reject) => { + this._mongoCollection.createIndex(indexRequest, { + unique: true, + background: true, + sparse: true + }, error => { + if (error) { + reject(error); + } else { + resolve(); + } + }); + }); + } + + drop() { + return this._mongoCollection.drop(); + } + +} + +exports.default = MongoCollection; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvQ29sbGVjdGlvbi5qcyJdLCJuYW1lcyI6WyJtb25nb2RiIiwicmVxdWlyZSIsIkNvbGxlY3Rpb24iLCJNb25nb0NvbGxlY3Rpb24iLCJjb25zdHJ1Y3RvciIsIm1vbmdvQ29sbGVjdGlvbiIsIl9tb25nb0NvbGxlY3Rpb24iLCJmaW5kIiwicXVlcnkiLCJza2lwIiwibGltaXQiLCJzb3J0Iiwia2V5cyIsIm1heFRpbWVNUyIsInJlYWRQcmVmZXJlbmNlIiwiaGludCIsImNhc2VJbnNlbnNpdGl2ZSIsImV4cGxhaW4iLCIkc2NvcmUiLCJzY29yZSIsIiRtZXRhIiwiX3Jhd0ZpbmQiLCJjYXRjaCIsImVycm9yIiwiY29kZSIsIm1lc3NhZ2UiLCJtYXRjaCIsImtleSIsImluZGV4IiwiY3JlYXRlSW5kZXgiLCJ0aGVuIiwiY2FzZUluc2Vuc2l0aXZlQ29sbGF0aW9uIiwibG9jYWxlIiwic3RyZW5ndGgiLCJmaW5kT3BlcmF0aW9uIiwicHJvamVjdCIsImNvbGxhdGlvbiIsInRvQXJyYXkiLCJjb3VudCIsIk9iamVjdCIsImxlbmd0aCIsImVzdGltYXRlZERvY3VtZW50Q291bnQiLCJjb3VudE9wZXJhdGlvbiIsImNvdW50RG9jdW1lbnRzIiwiZGlzdGluY3QiLCJmaWVsZCIsImFnZ3JlZ2F0ZSIsInBpcGVsaW5lIiwiaW5zZXJ0T25lIiwib2JqZWN0Iiwic2Vzc2lvbiIsInVwc2VydE9uZSIsInVwZGF0ZSIsInVwZGF0ZU9uZSIsInVwc2VydCIsInVwZGF0ZU1hbnkiLCJkZWxldGVNYW55IiwiX2Vuc3VyZVNwYXJzZVVuaXF1ZUluZGV4SW5CYWNrZ3JvdW5kIiwiaW5kZXhSZXF1ZXN0IiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJ1bmlxdWUiLCJiYWNrZ3JvdW5kIiwic3BhcnNlIiwiZHJvcCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBLE1BQU1BLE9BQU8sR0FBR0Ms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LEtBQUszRCxnQkFBTCxDQUFzQjJELElBQXRCLEVBQVA7QUFDRDs7QUFoTGtDIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgbW9uZ29kYiA9IHJlcXVpcmUoJ21vbmdvZGInKTtcbmNvbnN0IENvbGxlY3Rpb24gPSBtb25nb2RiLkNvbGxlY3Rpb247XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1vbmdvQ29sbGVjdGlvbiB7XG4gIF9tb25nb0NvbGxlY3Rpb246IENvbGxlY3Rpb247XG5cbiAgY29uc3RydWN0b3IobW9uZ29Db2xsZWN0aW9uOiBDb2xsZWN0aW9uKSB7XG4gICAgdGhpcy5fbW9uZ29Db2xsZWN0aW9uID0gbW9uZ29Db2xsZWN0aW9uO1xuICB9XG5cbiAgLy8gRG9lcyBhIGZpbmQgd2l0aCBcInNtYXJ0IGluZGV4aW5nXCIuXG4gIC8vIEN1cnJlbnRseSB0aGlzIGp1c3QgbWVhbnMsIGlmIGl0IG5lZWRzIGEgZ2VvaW5kZXggYW5kIHRoZXJlIGlzXG4gIC8vIG5vbmUsIHRoZW4gYnVpbGQgdGhlIGdlb2luZGV4LlxuICAvLyBUaGlzIGNvdWxkIGJlIGltcHJvdmVkIGEgbG90IGJ1dCBpdCdzIG5vdCBjbGVhciBpZiB0aGF0J3MgYSBnb29kXG4gIC8vIGlkZWEuIE9yIGV2ZW4gaWYgdGhpcyBiZWhhdmlvciBpcyBhIGdvb2QgaWRlYS5cbiAgZmluZChcbiAgICBxdWVyeSxcbiAgICB7IHNraXAsIGxpbWl0LCBzb3J0LCBrZXlzLCBtYXhUaW1lTVMsIHJlYWRQcmVmZXJlbmNlLCBoaW50LCBjYXNlSW5zZW5zaXRpdmUsIGV4cGxhaW4gfSA9IHt9XG4gICkge1xuICAgIC8vIFN1cHBvcnQgZm9yIEZ1bGwgVGV4dCBTZWFyY2ggLSAkdGV4dFxuICAgIGlmIChrZXlzICYmIGtleXMuJHNjb3JlKSB7XG4gICAgICBkZWxldGUga2V5cy4kc2NvcmU7XG4gICAgICBrZXlzLnNjb3JlID0geyAkbWV0YTogJ3RleHRTY29yZScgfTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3Jhd0ZpbmQocXVlcnksIHtcbiAgICAgIHNraXAsXG4gICAgICBsaW1pdCxcbiAgICAgIHNvcnQsXG4gICAgICBrZXlzLFxuICAgICAgbWF4VGltZU1TLFxuICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICBoaW50LFxuICAgICAgY2FzZUluc2Vuc2l0aXZlLFxuICAgICAgZXhwbGFpbixcbiAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAvLyBDaGVjayBmb3IgXCJubyBnZW9pbmRleFwiIGVycm9yXG4gICAgICBpZiAoZXJyb3IuY29kZSAhPSAxNzAwNyAmJiAhZXJyb3IubWVzc2FnZS5tYXRjaCgvdW5hYmxlIHRvIGZpbmQgaW5kZXggZm9yIC5nZW9OZWFyLykpIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgICAvLyBGaWd1cmUgb3V0IHdoYXQga2V5IG5lZWRzIGFuIGluZGV4XG4gICAgICBjb25zdCBrZXkgPSBlcnJvci5tZXNzYWdlLm1hdGNoKC9maWVsZD0oW0EtWmEtel8wLTldKykgLylbMV07XG4gICAgICBpZiAoIWtleSkge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cblxuICAgICAgdmFyIGluZGV4ID0ge307XG4gICAgICBpbmRleFtrZXldID0gJzJkJztcbiAgICAgIHJldHVybiAoXG4gICAgICAgIHRoaXMuX21vbmdvQ29sbGVjdGlvblxuICAgICAgICAgIC5jcmVhdGVJbmRleChpbmRleClcbiAgICAgICAgICAvLyBSZXRyeSwgYnV0IGp1c3Qgb25jZS5cbiAgICAgICAgICAudGhlbigoKSA9PlxuICAgICAgICAgICAgdGhpcy5fcmF3RmluZChxdWVyeSwge1xuICAgICAgICAgICAgICBza2lwLFxuICAgICAgICAgICAgICBsaW1pdCxcbiAgICAgICAgICAgICAgc29ydCxcbiAgICAgICAgICAgICAga2V5cyxcbiAgICAgICAgICAgICAgbWF4VGltZU1TLFxuICAgICAgICAgICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICAgICAgaGludCxcbiAgICAgICAgICAgICAgY2FzZUluc2Vuc2l0aXZlLFxuICAgICAgICAgICAgICBleHBsYWluLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICApXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbGxhdGlvbiB0byBzdXBwb3J0IGNhc2UgaW5zZW5zaXRpdmUgcXVlcmllc1xuICAgKi9cbiAgc3RhdGljIGNhc2VJbnNlbnNpdGl2ZUNvbGxhdGlvbigpIHtcbiAgICByZXR1cm4geyBsb2NhbGU6ICdlbl9VUycsIHN0cmVuZ3RoOiAyIH07XG4gIH1cblxuICBfcmF3RmluZChcbiAgICBxdWVyeSxcbiAgICB7IHNraXAsIGxpbWl0LCBzb3J0LCBrZXlzLCBtYXhUaW1lTVMsIHJlYWRQcmVmZXJlbmNlLCBoaW50LCBjYXNlSW5zZW5zaXRpdmUsIGV4cGxhaW4gfSA9IHt9XG4gICkge1xuICAgIGxldCBmaW5kT3BlcmF0aW9uID0gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLmZpbmQocXVlcnksIHtcbiAgICAgIHNraXAsXG4gICAgICBsaW1pdCxcbiAgICAgIHNvcnQsXG4gICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgIGhpbnQsXG4gICAgfSk7XG5cbiAgICBpZiAoa2V5cykge1xuICAgICAgZmluZE9wZXJhdGlvbiA9IGZpbmRPcGVyYXRpb24ucHJvamVjdChrZXlzKTtcbiAgICB9XG5cbiAgICBpZiAoY2FzZUluc2Vuc2l0aXZlKSB7XG4gICAgICBmaW5kT3BlcmF0aW9uID0gZmluZE9wZXJhdGlvbi5jb2xsYXRpb24oTW9uZ29Db2xsZWN0aW9uLmNhc2VJbnNlbnNpdGl2ZUNvbGxhdGlvbigpKTtcbiAgICB9XG5cbiAgICBpZiAobWF4VGltZU1TKSB7XG4gICAgICBmaW5kT3BlcmF0aW9uID0gZmluZE9wZXJhdGlvbi5tYXhUaW1lTVMobWF4VGltZU1TKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXhwbGFpbiA/IGZpbmRPcGVyYXRpb24uZXhwbGFpbihleHBsYWluKSA6IGZpbmRPcGVyYXRpb24udG9BcnJheSgpO1xuICB9XG5cbiAgY291bnQocXVlcnksIHsgc2tpcCwgbGltaXQsIHNvcnQsIG1heFRpbWVNUywgcmVhZFByZWZlcmVuY2UsIGhpbnQgfSA9IHt9KSB7XG4gICAgLy8gSWYgcXVlcnkgaXMgZW1wdHksIHRoZW4gdXNlIGVzdGltYXRlZERvY3VtZW50Q291bnQgaW5zdGVhZC5cbiAgICAvLyBUaGlzIGlzIGR1ZSB0byBjb3VudERvY3VtZW50cyBwZXJmb3JtaW5nIGEgc2NhbixcbiAgICAvLyB3aGljaCBncmVhdGx5IGluY3JlYXNlcyBleGVjdXRpb24gdGltZSB3aGVuIGJlaW5nIHJ1biBvbiBsYXJnZSBjb2xsZWN0aW9ucy5cbiAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL0F1dG9tYXR0aWMvbW9uZ29vc2UvaXNzdWVzLzY3MTMgZm9yIG1vcmUgaW5mbyByZWdhcmRpbmcgdGhpcyBwcm9ibGVtLlxuICAgIGlmICh0eXBlb2YgcXVlcnkgIT09ICdvYmplY3QnIHx8ICFPYmplY3Qua2V5cyhxdWVyeSkubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLmVzdGltYXRlZERvY3VtZW50Q291bnQoe1xuICAgICAgICBtYXhUaW1lTVMsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBjb3VudE9wZXJhdGlvbiA9IHRoaXMuX21vbmdvQ29sbGVjdGlvbi5jb3VudERvY3VtZW50cyhxdWVyeSwge1xuICAgICAgc2tpcCxcbiAgICAgIGxpbWl0LFxuICAgICAgc29ydCxcbiAgICAgIG1heFRpbWVNUyxcbiAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgaGludCxcbiAgICB9KTtcblxuICAgIHJldHVybiBjb3VudE9wZXJhdGlvbjtcbiAgfVxuXG4gIGRpc3RpbmN0KGZpZWxkLCBxdWVyeSkge1xuICAgIHJldHVybiB0aGlzLl9tb25nb0NvbGxlY3Rpb24uZGlzdGluY3QoZmllbGQsIHF1ZXJ5KTtcbiAgfVxuXG4gIGFnZ3JlZ2F0ZShwaXBlbGluZSwgeyBtYXhUaW1lTVMsIHJlYWRQcmVmZXJlbmNlLCBoaW50LCBleHBsYWluIH0gPSB7fSkge1xuICAgIHJldHVybiB0aGlzLl9tb25nb0NvbGxlY3Rpb25cbiAgICAgIC5hZ2dyZWdhdGUocGlwZWxpbmUsIHsgbWF4VGltZU1TLCByZWFkUHJlZmVyZW5jZSwgaGludCwgZXhwbGFpbiB9KVxuICAgICAgLnRvQXJyYXkoKTtcbiAgfVxuXG4gIGluc2VydE9uZShvYmplY3QsIHNlc3Npb24pIHtcbiAgICByZXR1cm4gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLmluc2VydE9uZShvYmplY3QsIHsgc2Vzc2lvbiB9KTtcbiAgfVxuXG4gIC8vIEF0b21pY2FsbHkgdXBkYXRlcyBkYXRhIGluIHRoZSBkYXRhYmFzZSBmb3IgYSBzaW5nbGUgKGZpcnN0KSBvYmplY3QgdGhhdCBtYXRjaGVkIHRoZSBxdWVyeVxuICAvLyBJZiB0aGVyZSBpcyBub3RoaW5nIHRoYXQgbWF0Y2hlcyB0aGUgcXVlcnkgLSBkb2VzIGluc2VydFxuICAvLyBQb3N0Z3JlcyBOb3RlOiBgSU5TRVJUIC4uLiBPTiBDT05GTElDVCBVUERBVEVgIHRoYXQgaXMgYXZhaWxhYmxlIHNpbmNlIDkuNS5cbiAgdXBzZXJ0T25lKHF1ZXJ5LCB1cGRhdGUsIHNlc3Npb24pIHtcbiAgICByZXR1cm4gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLnVwZGF0ZU9uZShxdWVyeSwgdXBkYXRlLCB7XG4gICAgICB1cHNlcnQ6IHRydWUsXG4gICAgICBzZXNzaW9uLFxuICAgIH0pO1xuICB9XG5cbiAgdXBkYXRlT25lKHF1ZXJ5LCB1cGRhdGUpIHtcbiAgICByZXR1cm4gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLnVwZGF0ZU9uZShxdWVyeSwgdXBkYXRlKTtcbiAgfVxuXG4gIHVwZGF0ZU1hbnkocXVlcnksIHVwZGF0ZSwgc2Vzc2lvbikge1xuICAgIHJldHVybiB0aGlzLl9tb25nb0NvbGxlY3Rpb24udXBkYXRlTWFueShxdWVyeSwgdXBkYXRlLCB7IHNlc3Npb24gfSk7XG4gIH1cblxuICBkZWxldGVNYW55KHF1ZXJ5LCBzZXNzaW9uKSB7XG4gICAgcmV0dXJuIHRoaXMuX21vbmdvQ29sbGVjdGlvbi5kZWxldGVNYW55KHF1ZXJ5LCB7IHNlc3Npb24gfSk7XG4gIH1cblxuICBfZW5zdXJlU3BhcnNlVW5pcXVlSW5kZXhJbkJhY2tncm91bmQoaW5kZXhSZXF1ZXN0KSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuX21vbmdvQ29sbGVjdGlvbi5jcmVhdGVJbmRleChcbiAgICAgICAgaW5kZXhSZXF1ZXN0LFxuICAgICAgICB7IHVuaXF1ZTogdHJ1ZSwgYmFja2dyb3VuZDogdHJ1ZSwgc3BhcnNlOiB0cnVlIH0sXG4gICAgICAgIGVycm9yID0+IHtcbiAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBkcm9wKCkge1xuICAgIHJldHVybiB0aGlzLl9tb25nb0NvbGxlY3Rpb24uZHJvcCgpO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js b/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js new file mode 100644 index 0000000000..15075a09ed --- /dev/null +++ b/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js @@ -0,0 +1,365 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _MongoCollection = _interopRequireDefault(require("./MongoCollection")); + +var _node = _interopRequireDefault(require("parse/node")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } + +function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function mongoFieldToParseSchemaField(type) { + if (type[0] === '*') { + return { + type: 'Pointer', + targetClass: type.slice(1) + }; + } + + if (type.startsWith('relation<')) { + return { + type: 'Relation', + targetClass: type.slice('relation<'.length, type.length - 1) + }; + } + + switch (type) { + case 'number': + return { + type: 'Number' + }; + + case 'string': + return { + type: 'String' + }; + + case 'boolean': + return { + type: 'Boolean' + }; + + case 'date': + return { + type: 'Date' + }; + + case 'map': + case 'object': + return { + type: 'Object' + }; + + case 'array': + return { + type: 'Array' + }; + + case 'geopoint': + return { + type: 'GeoPoint' + }; + + case 'file': + return { + type: 'File' + }; + + case 'bytes': + return { + type: 'Bytes' + }; + + case 'polygon': + return { + type: 'Polygon' + }; + } +} + +const nonFieldSchemaKeys = ['_id', '_metadata', '_client_permissions']; + +function mongoSchemaFieldsToParseSchemaFields(schema) { + var fieldNames = Object.keys(schema).filter(key => nonFieldSchemaKeys.indexOf(key) === -1); + var response = fieldNames.reduce((obj, fieldName) => { + obj[fieldName] = mongoFieldToParseSchemaField(schema[fieldName]); + + if (schema._metadata && schema._metadata.fields_options && schema._metadata.fields_options[fieldName]) { + obj[fieldName] = Object.assign({}, obj[fieldName], schema._metadata.fields_options[fieldName]); + } + + return obj; + }, {}); + response.ACL = { + type: 'ACL' + }; + response.createdAt = { + type: 'Date' + }; + response.updatedAt = { + type: 'Date' + }; + response.objectId = { + type: 'String' + }; + return response; +} + +const emptyCLPS = Object.freeze({ + find: {}, + count: {}, + get: {}, + create: {}, + update: {}, + delete: {}, + addField: {}, + protectedFields: {} +}); +const defaultCLPS = Object.freeze({ + find: { + '*': true + }, + count: { + '*': true + }, + get: { + '*': true + }, + create: { + '*': true + }, + update: { + '*': true + }, + delete: { + '*': true + }, + addField: { + '*': true + }, + protectedFields: { + '*': [] + } +}); + +function mongoSchemaToParseSchema(mongoSchema) { + let clps = defaultCLPS; + let indexes = {}; + + if (mongoSchema._metadata) { + if (mongoSchema._metadata.class_permissions) { + clps = _objectSpread(_objectSpread({}, emptyCLPS), mongoSchema._metadata.class_permissions); + } + + if (mongoSchema._metadata.indexes) { + indexes = _objectSpread({}, mongoSchema._metadata.indexes); + } + } + + return { + className: mongoSchema._id, + fields: mongoSchemaFieldsToParseSchemaFields(mongoSchema), + classLevelPermissions: clps, + indexes: indexes + }; +} + +function _mongoSchemaQueryFromNameQuery(name, query) { + const object = { + _id: name + }; + + if (query) { + Object.keys(query).forEach(key => { + object[key] = query[key]; + }); + } + + return object; +} // Returns a type suitable for inserting into mongo _SCHEMA collection. +// Does no validation. That is expected to be done in Parse Server. + + +function parseFieldTypeToMongoFieldType({ + type, + targetClass +}) { + switch (type) { + case 'Pointer': + return `*${targetClass}`; + + case 'Relation': + return `relation<${targetClass}>`; + + case 'Number': + return 'number'; + + case 'String': + return 'string'; + + case 'Boolean': + return 'boolean'; + + case 'Date': + return 'date'; + + case 'Object': + return 'object'; + + case 'Array': + return 'array'; + + case 'GeoPoint': + return 'geopoint'; + + case 'File': + return 'file'; + + case 'Bytes': + return 'bytes'; + + case 'Polygon': + return 'polygon'; + } +} + +class MongoSchemaCollection { + constructor(collection) { + this._collection = collection; + } + + _fetchAllSchemasFrom_SCHEMA() { + return this._collection._rawFind({}).then(schemas => schemas.map(mongoSchemaToParseSchema)); + } + + _fetchOneSchemaFrom_SCHEMA(name) { + return this._collection._rawFind(_mongoSchemaQueryFromNameQuery(name), { + limit: 1 + }).then(results => { + if (results.length === 1) { + return mongoSchemaToParseSchema(results[0]); + } else { + throw undefined; + } + }); + } // Atomically find and delete an object based on query. + + + findAndDeleteSchema(name) { + return this._collection._mongoCollection.findOneAndDelete(_mongoSchemaQueryFromNameQuery(name)); + } + + insertSchema(schema) { + return this._collection.insertOne(schema).then(result => mongoSchemaToParseSchema(result.ops[0])).catch(error => { + if (error.code === 11000) { + //Mongo's duplicate key error + throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'Class already exists.'); + } else { + throw error; + } + }); + } + + updateSchema(name, update) { + return this._collection.updateOne(_mongoSchemaQueryFromNameQuery(name), update); + } + + upsertSchema(name, query, update) { + return this._collection.upsertOne(_mongoSchemaQueryFromNameQuery(name, query), update); + } // Add a field to the schema. If database does not support the field + // type (e.g. mongo doesn't support more than one GeoPoint in a class) reject with an "Incorrect Type" + // Parse error with a desciptive message. If the field already exists, this function must + // not modify the schema, and must reject with DUPLICATE_VALUE error. + // If this is called for a class that doesn't exist, this function must create that class. + // TODO: throw an error if an unsupported field type is passed. Deciding whether a type is supported + // should be the job of the adapter. Some adapters may not support GeoPoint at all. Others may + // Support additional types that Mongo doesn't, like Money, or something. + // TODO: don't spend an extra query on finding the schema if the type we are trying to add isn't a GeoPoint. + + + addFieldIfNotExists(className, fieldName, fieldType) { + return this._fetchOneSchemaFrom_SCHEMA(className).then(schema => { + // If a field with this name already exists, it will be handled elsewhere. + if (schema.fields[fieldName] != undefined) { + return; + } // The schema exists. Check for existing GeoPoints. + + + if (fieldType.type === 'GeoPoint') { + // Make sure there are not other geopoint fields + if (Object.keys(schema.fields).some(existingField => schema.fields[existingField].type === 'GeoPoint')) { + throw new _node.default.Error(_node.default.Error.INCORRECT_TYPE, 'MongoDB only supports one GeoPoint field in a class.'); + } + } + + return; + }, error => { + // If error is undefined, the schema doesn't exist, and we can create the schema with the field. + // If some other error, reject with it. + if (error === undefined) { + return; + } + + throw error; + }).then(() => { + const { + type, + targetClass + } = fieldType, + fieldOptions = _objectWithoutProperties(fieldType, ["type", "targetClass"]); // We use $exists and $set to avoid overwriting the field type if it + // already exists. (it could have added inbetween the last query and the update) + + + if (fieldOptions && Object.keys(fieldOptions).length > 0) { + return this.upsertSchema(className, { + [fieldName]: { + $exists: false + } + }, { + $set: { + [fieldName]: parseFieldTypeToMongoFieldType({ + type, + targetClass + }), + [`_metadata.fields_options.${fieldName}`]: fieldOptions + } + }); + } else { + return this.upsertSchema(className, { + [fieldName]: { + $exists: false + } + }, { + $set: { + [fieldName]: parseFieldTypeToMongoFieldType({ + type, + targetClass + }) + } + }); + } + }); + } + +} // Exported for testing reasons and because we haven't moved all mongo schema format +// related logic into the database adapter yet. + + +MongoSchemaCollection._TESTmongoSchemaToParseSchema = mongoSchemaToParseSchema; +MongoSchemaCollection.parseFieldTypeToMongoFieldType = parseFieldTypeToMongoFieldType; +var _default = MongoSchemaCollection; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvU2NoZW1hQ29sbGVjdGlvbi5qcyJdLCJuYW1lcyI6WyJtb25nb0ZpZWxkVG9QYXJzZVNjaGVtYUZpZWxkIiwidHlwZSIsInRhcmdldENsYXNzIiwic2xpY2UiLCJzdGFydHNXaXRoIiwibGVuZ3RoIiwibm9uRmllbGRTY2hlbWFLZXlzIiwibW9uZ29TY2hlbWFGaWVsZHNUb1BhcnNlU2NoZW1hRmllbGRzIiwic2NoZW1hIiwiZmllbGROYW1lcyIsIk9iamVjdCIsImtleXMiLCJmaWx0ZXIiLCJrZXkiLCJpbmRleE9mIiwicmVzcG9uc2UiLCJyZWR1Y2UiLCJvYmoiLCJmaWVsZE5hbWUiLCJfbWV0YWRhdGEiLCJmaWVsZHNfb3B0aW9ucyIsImFzc2lnbiIsIkFDTCIsImNyZWF0ZWRBdCIsInVwZGF0ZWRBdCIsIm9iamVjdElkIiwiZW1wdHlDTFBTIiwiZnJlZXplIiwiZmluZCIsImNvdW50IiwiZ2V0IiwiY3JlYXRlIiwidXBkYXRlIiwiZGVsZXRlIiwiYWRkRmllbGQiLCJwcm90ZWN0ZWRGaWVsZHMiLCJkZWZhdWx0Q0xQUyIsIm1vbmdvU2NoZW1hVG9QYXJzZVNjaGVtYSIsIm1vbmdvU2NoZW1hIiwiY2xwcyIsImluZGV4ZXMiLCJjbGFzc19wZXJtaXNzaW9ucyIsImNsYXNzTmFtZSIsIl9pZCIsImZpZWxkcyIsImNsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsIl9tb25nb1NjaGVtYVF1ZXJ5RnJvbU5hbWVRdWVyeSIsIm5hbWUiLCJxdWVyeSIsIm9iamVjdCIsImZvckVhY2giLCJwYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUiLCJNb25nb1NjaGVtYUNvbGxlY3Rpb24iLCJjb25zdHJ1Y3RvciIsImNvbGxlY3Rpb24iLCJfY29sbGVjdGlvbiIsIl9mZXRjaEFsbFNjaGVtYXNGcm9tX1NDSEVNQSIsIl9yYXdGaW5kIiwidGhlbiIsInNjaGVtYXMiLCJtYXAiLCJfZmV0Y2hPbmVTY2hlbWFGcm9tX1NDSEVNQSIsImxpbWl0IiwicmVzdWx0cyIsInVuZGVmaW5lZCIsImZpbmRBbmREZWxldGVTY2hlbWEiLCJfbW9uZ29Db2xsZWN0aW9uIiwiZmluZE9uZUFuZERlbGV0ZSIsImluc2VydFNjaGVtYSIsImluc2VydE9uZSIsInJlc3VsdCIsIm9wcyIsImNhdGNoIiwiZXJyb3IiLCJjb2RlIiwiUGFyc2UiLCJFcnJvciIsIkRVUExJQ0FURV9WQUxVRSIsInVwZGF0ZVNjaGVtYSIsInVwZGF0ZU9uZSIsInVwc2VydFNjaGVtYSIsInVwc2VydE9uZSIsImFkZEZpZWxkSWZOb3RFeGlzdHMiLCJmaWVsZFR5cGUiLCJzb21lIiwiZXhpc3RpbmdGaWVsZCIsIklOQ09SUkVDVF9UWVBFIiwiZmllbGRPcHRpb25zIiwiJGV4aXN0cyIsIiRzZXQiLCJfVEVTVG1vbmdvU2NoZW1hVG9QYXJzZVNjaGVtYSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7Ozs7Ozs7Ozs7OztBQUVBLFNBQVNBLDRCQUFULENBQXNDQyxJQUF0QyxFQUE0QztBQUMxQyxNQUFJQSxJQUFJLENBQUMsQ0FBRCxDQUFKLEtBQVksR0FBaEIsRUFBcUI7QUFDbkIsV0FBTztBQUNMQSxNQUFBQSxJQUFJLEVBQUUsU0FERDtBQUVMQyxNQUFBQSxXQUFXLEVBQUVELElBQUksQ0FBQ0UsS0FBTCxDQUFXLENBQVg7QUFGUixLQUFQO0FBSUQ7O0FBQ0QsTUFBSUYsSUFBSSxDQUFDRyxVQUFMLENBQWdCLFdBQWhCLENBQUosRUFBa0M7QUFDaEMsV0FBTztBQUNMSCxNQUFBQSxJQUFJLEVBQUUsVUFERDtBQUVMQyxNQUFBQSxXQUFXLEVBQUVELElBQUksQ0FBQ0UsS0FBTCxDQUFXLFlBQVlFLE1BQXZCLEVBQStCSixJQUFJLENBQUNJLE1BQUwsR0FBYyxDQUE3QztBQUZSLEtBQVA7QUFJRDs7QUFDRCxVQUFRSixJQUFSO0FBQ0UsU0FBSyxRQUFMO0FBQ0UsYUFBTztBQUFFQSxRQUFBQSxJQUFJLEVBQUU7QUFBUixPQUFQ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Q3ZFLFNBQUQsR0FBYWlDLDhCQUE4QixDQUFDO0FBQzFDbEQsY0FBQUEsSUFEMEM7QUFFMUNDLGNBQUFBO0FBRjBDLGFBQUQ7QUFEdkM7QUFEUixTQUhLLENBQVA7QUFZRDtBQUNGLEtBaEVJLENBQVA7QUFpRUQ7O0FBL0h5QixDLENBa0k1QjtBQUNBOzs7QUFDQWtELHFCQUFxQixDQUFDc0MsNkJBQXRCLEdBQXNEckQsd0JBQXREO0FBQ0FlLHFCQUFxQixDQUFDRCw4QkFBdEIsR0FBdURBLDhCQUF2RDtlQUVlQyxxQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBNb25nb0NvbGxlY3Rpb24gZnJvbSAnLi9Nb25nb0NvbGxlY3Rpb24nO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuXG5mdW5jdGlvbiBtb25nb0ZpZWxkVG9QYXJzZVNjaGVtYUZpZWxkKHR5cGUpIHtcbiAgaWYgKHR5cGVbMF0gPT09ICcqJykge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiAnUG9pbnRlcicsXG4gICAgICB0YXJnZXRDbGFzczogdHlwZS5zbGljZSgxKSxcbiAgICB9O1xuICB9XG4gIGlmICh0eXBlLnN0YXJ0c1dpdGgoJ3JlbGF0aW9uPCcpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdSZWxhdGlvbicsXG4gICAgICB0YXJnZXRDbGFzczogdHlwZS5zbGljZSgncmVsYXRpb248Jy5sZW5ndGgsIHR5cGUubGVuZ3RoIC0gMSksXG4gICAgfTtcbiAgfVxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdudW1iZXInOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ051bWJlcicgfTtcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ1N0cmluZycgfTtcbiAgICBjYXNlICdib29sZWFuJzpcbiAgICAgIHJldHVybiB7IHR5cGU6ICdCb29sZWFuJyB9O1xuICAgIGNhc2UgJ2RhdGUnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ0RhdGUnIH07XG4gICAgY2FzZSAnbWFwJzpcbiAgICBjYXNlICdvYmplY3QnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ09iamVjdCcgfTtcbiAgICBjYXNlICdhcnJheSc6XG4gICAgICByZXR1cm4geyB0eXBlOiAnQXJyYXknIH07XG4gICAgY2FzZSAnZ2VvcG9pbnQnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ0dlb1BvaW50JyB9O1xuICAgIGNhc2UgJ2ZpbGUnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ0ZpbGUnIH07XG4gICAgY2FzZSAnYnl0ZXMnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ0J5dGVzJyB9O1xuICAgIGNhc2UgJ3BvbHlnb24nOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ1BvbHlnb24nIH07XG4gIH1cbn1cblxuY29uc3Qgbm9uRmllbGRTY2hlbWFLZXlzID0gWydfaWQnLCAnX21ldGFkYXRhJywgJ19jbGllbnRfcGVybWlzc2lvbnMnXTtcbmZ1bmN0aW9uIG1vbmdvU2NoZW1hRmllbGRzVG9QYXJzZVNjaGVtYUZpZWxkcyhzY2hlbWEpIHtcbiAgdmFyIGZpZWxkTmFtZXMgPSBPYmplY3Qua2V5cyhzY2hlbWEpLmZpbHRlcihrZXkgPT4gbm9uRmllbGRTY2hlbWFLZXlzLmluZGV4T2Yoa2V5KSA9PT0gLTEpO1xuICB2YXIgcmVzcG9uc2UgPSBmaWVsZE5hbWVzLnJlZHVjZSgob2JqLCBmaWVsZE5hbWUpID0+IHtcbiAgICBvYmpbZmllbGROYW1lXSA9IG1vbmdvRmllbGRUb1BhcnNlU2NoZW1hRmllbGQoc2NoZW1hW2ZpZWxkTmFtZV0pO1xuICAgIGlmIChcbiAgICAgIHNjaGVtYS5fbWV0YWRhdGEgJiZcbiAgICAgIHNjaGVtYS5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnMgJiZcbiAgICAgIHNjaGVtYS5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnNbZmllbGROYW1lXVxuICAgICkge1xuICAgICAgb2JqW2ZpZWxkTmFtZV0gPSBPYmplY3QuYXNzaWduKFxuICAgICAgICB7fSxcbiAgICAgICAgb2JqW2ZpZWxkTmFtZV0sXG4gICAgICAgIHNjaGVtYS5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnNbZmllbGROYW1lXVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIG9iajtcbiAgfSwge30pO1xuICByZXNwb25zZS5BQ0wgPSB7IHR5cGU6ICdBQ0wnIH07XG4gIHJlc3BvbnNlLmNyZWF0ZWRBdCA9IHsgdHlwZTogJ0RhdGUnIH07XG4gIHJlc3BvbnNlLnVwZGF0ZWRBdCA9IHsgdHlwZTogJ0RhdGUnIH07XG4gIHJlc3BvbnNlLm9iamVjdElkID0geyB0eXBlOiAnU3RyaW5nJyB9O1xuICByZXR1cm4gcmVzcG9uc2U7XG59XG5cbmNvbnN0IGVtcHR5Q0xQUyA9IE9iamVjdC5mcmVlemUoe1xuICBmaW5kOiB7fSxcbiAgY291bnQ6IHt9LFxuICBnZXQ6IHt9LFxuICBjcmVhdGU6IHt9LFxuICB1cGRhdGU6IHt9LFxuICBkZWxldGU6IHt9LFxuICBhZGRGaWVsZDoge30sXG4gIHByb3RlY3RlZEZpZWxkczoge30sXG59KTtcblxuY29uc3QgZGVmYXVsdENMUFMgPSBPYmplY3QuZnJlZXplKHtcbiAgZmluZDogeyAnKic6IHRydWUgfSxcbiAgY291bnQ6IHsgJyonOiB0cnVlIH0sXG4gIGdldDogeyAnKic6IHRydWUgfSxcbiAgY3JlYXRlOiB7ICcqJzogdHJ1ZSB9LFxuICB1cGRhdGU6IHsgJyonOiB0cnVlIH0sXG4gIGRlbGV0ZTogeyAnKic6IHRydWUgfSxcbiAgYWRkRmllbGQ6IHsgJyonOiB0cnVlIH0sXG4gIHByb3RlY3RlZEZpZWxkczogeyAnKic6IFtdIH0sXG59KTtcblxuZnVuY3Rpb24gbW9uZ29TY2hlbWFUb1BhcnNlU2NoZW1hKG1vbmdvU2NoZW1hKSB7XG4gIGxldCBjbHBzID0gZGVmYXVsdENMUFM7XG4gIGxldCBpbmRleGVzID0ge307XG4gIGlmIChtb25nb1NjaGVtYS5fbWV0YWRhdGEpIHtcbiAgICBpZiAobW9uZ29TY2hlbWEuX21ldGFkYXRhLmNsYXNzX3Blcm1pc3Npb25zKSB7XG4gICAgICBjbHBzID0geyAuLi5lbXB0eUNMUFMsIC4uLm1vbmdvU2NoZW1hLl9tZXRhZGF0YS5jbGFzc19wZXJtaXNzaW9ucyB9O1xuICAgIH1cbiAgICBpZiAobW9uZ29TY2hlbWEuX21ldGFkYXRhLmluZGV4ZXMpIHtcbiAgICAgIGluZGV4ZXMgPSB7IC4uLm1vbmdvU2NoZW1hLl9tZXRhZGF0YS5pbmRleGVzIH07XG4gICAgfVxuICB9XG4gIHJldHVybiB7XG4gICAgY2xhc3NOYW1lOiBtb25nb1NjaGVtYS5faWQsXG4gICAgZmllbGRzOiBtb25nb1NjaGVtYUZpZWxkc1RvUGFyc2VTY2hlbWFGaWVsZHMobW9uZ29TY2hlbWEpLFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogY2xwcyxcbiAgICBpbmRleGVzOiBpbmRleGVzLFxuICB9O1xufVxuXG5mdW5jdGlvbiBfbW9uZ29TY2hlbWFRdWVyeUZyb21OYW1lUXVlcnkobmFtZTogc3RyaW5nLCBxdWVyeSkge1xuICBjb25zdCBvYmplY3QgPSB7IF9pZDogbmFtZSB9O1xuICBpZiAocXVlcnkpIHtcbiAgICBPYmplY3Qua2V5cyhxdWVyeSkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgb2JqZWN0W2tleV0gPSBxdWVyeVtrZXldO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBvYmplY3Q7XG59XG5cbi8vIFJldHVybnMgYSB0eXBlIHN1aXRhYmxlIGZvciBpbnNlcnRpbmcgaW50byBtb25nbyBfU0NIRU1BIGNvbGxlY3Rpb24uXG4vLyBEb2VzIG5vIHZhbGlkYXRpb24uIFRoYXQgaXMgZXhwZWN0ZWQgdG8gYmUgZG9uZSBpbiBQYXJzZSBTZXJ2ZXIuXG5mdW5jdGlvbiBwYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUoeyB0eXBlLCB0YXJnZXRDbGFzcyB9KSB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ1BvaW50ZXInOlxuICAgICAgcmV0dXJuIGAqJHt0YXJnZXRDbGFzc31gO1xuICAgIGNhc2UgJ1JlbGF0aW9uJzpcbiAgICAgIHJldHVybiBgcmVsYXRpb248JHt0YXJnZXRDbGFzc30+YDtcbiAgICBjYXNlICdOdW1iZXInOlxuICAgICAgcmV0dXJuICdudW1iZXInO1xuICAgIGNhc2UgJ1N0cmluZyc6XG4gICAgICByZXR1cm4gJ3N0cmluZyc7XG4gICAgY2FzZSAnQm9vbGVhbic6XG4gICAgICByZXR1cm4gJ2Jvb2xlYW4nO1xuICAgIGNhc2UgJ0RhdGUnOlxuICAgICAgcmV0dXJuICdkYXRlJztcbiAgICBjYXNlICdPYmplY3QnOlxuICAgICAgcmV0dXJuICdvYmplY3QnO1xuICAgIGNhc2UgJ0FycmF5JzpcbiAgICAgIHJldHVybiAnYXJyYXknO1xuICAgIGNhc2UgJ0dlb1BvaW50JzpcbiAgICAgIHJldHVybiAnZ2VvcG9pbnQnO1xuICAgIGNhc2UgJ0ZpbGUnOlxuICAgICAgcmV0dXJuICdmaWxlJztcbiAgICBjYXNlICdCeXRlcyc6XG4gICAgICByZXR1cm4gJ2J5dGVzJztcbiAgICBjYXNlICdQb2x5Z29uJzpcbiAgICAgIHJldHVybiAncG9seWdvbic7XG4gIH1cbn1cblxuY2xhc3MgTW9uZ29TY2hlbWFDb2xsZWN0aW9uIHtcbiAgX2NvbGxlY3Rpb246IE1vbmdvQ29sbGVjdGlvbjtcblxuICBjb25zdHJ1Y3Rvcihjb2xsZWN0aW9uOiBNb25nb0NvbGxlY3Rpb24pIHtcbiAgICB0aGlzLl9jb2xsZWN0aW9uID0gY29sbGVjdGlvbjtcbiAgfVxuXG4gIF9mZXRjaEFsbFNjaGVtYXNGcm9tX1NDSEVNQSgpIHtcbiAgICByZXR1cm4gdGhpcy5fY29sbGVjdGlvbi5fcmF3RmluZCh7fSkudGhlbihzY2hlbWFzID0+IHNjaGVtYXMubWFwKG1vbmdvU2NoZW1hVG9QYXJzZVNjaGVtYSkpO1xuICB9XG5cbiAgX2ZldGNoT25lU2NoZW1hRnJvbV9TQ0hFTUEobmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbGxlY3Rpb25cbiAgICAgIC5fcmF3RmluZChfbW9uZ29TY2hlbWFRdWVyeUZyb21OYW1lUXVlcnkobmFtZSksIHsgbGltaXQ6IDEgfSlcbiAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICByZXR1cm4gbW9uZ29TY2hlbWFUb1BhcnNlU2NoZW1hKHJlc3VsdHNbMF0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICAvLyBBdG9taWNhbGx5IGZpbmQgYW5kIGRlbGV0ZSBhbiBvYmplY3QgYmFzZWQgb24gcXVlcnkuXG4gIGZpbmRBbmREZWxldGVTY2hlbWEobmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbGxlY3Rpb24uX21vbmdvQ29sbGVjdGlvbi5maW5kT25lQW5kRGVsZXRlKF9tb25nb1NjaGVtYVF1ZXJ5RnJvbU5hbWVRdWVyeShuYW1lKSk7XG4gIH1cblxuICBpbnNlcnRTY2hlbWEoc2NoZW1hOiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5fY29sbGVjdGlvblxuICAgICAgLmluc2VydE9uZShzY2hlbWEpXG4gICAgICAudGhlbihyZXN1bHQgPT4gbW9uZ29TY2hlbWFUb1BhcnNlU2NoZW1hKHJlc3VsdC5vcHNbMF0pKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDExMDAwKSB7XG4gICAgICAgICAgLy9Nb25nbydzIGR1cGxpY2F0ZSBrZXkgZXJyb3JcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFLCAnQ2xhc3MgYWxyZWFkeSBleGlzdHMuJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgdXBkYXRlU2NoZW1hKG5hbWU6IHN0cmluZywgdXBkYXRlKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbGxlY3Rpb24udXBkYXRlT25lKF9tb25nb1NjaGVtYVF1ZXJ5RnJvbU5hbWVRdWVyeShuYW1lKSwgdXBkYXRlKTtcbiAgfVxuXG4gIHVwc2VydFNjaGVtYShuYW1lOiBzdHJpbmcsIHF1ZXJ5OiBzdHJpbmcsIHVwZGF0ZSkge1xuICAgIHJldHVybiB0aGlzLl9jb2xsZWN0aW9uLnVwc2VydE9uZShfbW9uZ29TY2hlbWFRdWVyeUZyb21OYW1lUXVlcnkobmFtZSwgcXVlcnkpLCB1cGRhdGUpO1xuICB9XG5cbiAgLy8gQWRkIGEgZmllbGQgdG8gdGhlIHNjaGVtYS4gSWYgZGF0YWJhc2UgZG9lcyBub3Qgc3VwcG9ydCB0aGUgZmllbGRcbiAgLy8gdHlwZSAoZS5nLiBtb25nbyBkb2Vzbid0IHN1cHBvcnQgbW9yZSB0aGFuIG9uZSBHZW9Qb2ludCBpbiBhIGNsYXNzKSByZWplY3Qgd2l0aCBhbiBcIkluY29ycmVjdCBUeXBlXCJcbiAgLy8gUGFyc2UgZXJyb3Igd2l0aCBhIGRlc2NpcHRpdmUgbWVzc2FnZS4gSWYgdGhlIGZpZWxkIGFscmVhZHkgZXhpc3RzLCB0aGlzIGZ1bmN0aW9uIG11c3RcbiAgLy8gbm90IG1vZGlmeSB0aGUgc2NoZW1hLCBhbmQgbXVzdCByZWplY3Qgd2l0aCBEVVBMSUNBVEVfVkFMVUUgZXJyb3IuXG4gIC8vIElmIHRoaXMgaXMgY2FsbGVkIGZvciBhIGNsYXNzIHRoYXQgZG9lc24ndCBleGlzdCwgdGhpcyBmdW5jdGlvbiBtdXN0IGNyZWF0ZSB0aGF0IGNsYXNzLlxuXG4gIC8vIFRPRE86IHRocm93IGFuIGVycm9yIGlmIGFuIHVuc3VwcG9ydGVkIGZpZWxkIHR5cGUgaXMgcGFzc2VkLiBEZWNpZGluZyB3aGV0aGVyIGEgdHlwZSBpcyBzdXBwb3J0ZWRcbiAgLy8gc2hvdWxkIGJlIHRoZSBqb2Igb2YgdGhlIGFkYXB0ZXIuIFNvbWUgYWRhcHRlcnMgbWF5IG5vdCBzdXBwb3J0IEdlb1BvaW50IGF0IGFsbC4gT3RoZXJzIG1heVxuICAvLyBTdXBwb3J0IGFkZGl0aW9uYWwgdHlwZXMgdGhhdCBNb25nbyBkb2Vzbid0LCBsaWtlIE1vbmV5LCBvciBzb21ldGhpbmcuXG5cbiAgLy8gVE9ETzogZG9uJ3Qgc3BlbmQgYW4gZXh0cmEgcXVlcnkgb24gZmluZGluZyB0aGUgc2NoZW1hIGlmIHRoZSB0eXBlIHdlIGFyZSB0cnlpbmcgdG8gYWRkIGlzbid0IGEgR2VvUG9pbnQuXG4gIGFkZEZpZWxkSWZOb3RFeGlzdHMoY2xhc3NOYW1lOiBzdHJpbmcsIGZpZWxkTmFtZTogc3RyaW5nLCBmaWVsZFR5cGU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLl9mZXRjaE9uZVNjaGVtYUZyb21fU0NIRU1BKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKFxuICAgICAgICBzY2hlbWEgPT4ge1xuICAgICAgICAgIC8vIElmIGEgZmllbGQgd2l0aCB0aGlzIG5hbWUgYWxyZWFkeSBleGlzdHMsIGl0IHdpbGwgYmUgaGFuZGxlZCBlbHNld2hlcmUuXG4gICAgICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gVGhlIHNjaGVtYSBleGlzdHMuIENoZWNrIGZvciBleGlzdGluZyBHZW9Qb2ludHMuXG4gICAgICAgICAgaWYgKGZpZWxkVHlwZS50eXBlID09PSAnR2VvUG9pbnQnKSB7XG4gICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhlcmUgYXJlIG5vdCBvdGhlciBnZW9wb2ludCBmaWVsZHNcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgT2JqZWN0LmtleXMoc2NoZW1hLmZpZWxkcykuc29tZShcbiAgICAgICAgICAgICAgICBleGlzdGluZ0ZpZWxkID0+IHNjaGVtYS5maWVsZHNbZXhpc3RpbmdGaWVsZF0udHlwZSA9PT0gJ0dlb1BvaW50J1xuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLFxuICAgICAgICAgICAgICAgICdNb25nb0RCIG9ubHkgc3VwcG9ydHMgb25lIEdlb1BvaW50IGZpZWxkIGluIGEgY2xhc3MuJ1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yID0+IHtcbiAgICAgICAgICAvLyBJZiBlcnJvciBpcyB1bmRlZmluZWQsIHRoZSBzY2hlbWEgZG9lc24ndCBleGlzdCwgYW5kIHdlIGNhbiBjcmVhdGUgdGhlIHNjaGVtYSB3aXRoIHRoZSBmaWVsZC5cbiAgICAgICAgICAvLyBJZiBzb21lIG90aGVyIGVycm9yLCByZWplY3Qgd2l0aCBpdC5cbiAgICAgICAgICBpZiAoZXJyb3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBjb25zdCB7IHR5cGUsIHRhcmdldENsYXNzLCAuLi5maWVsZE9wdGlvbnMgfSA9IGZpZWxkVHlwZTtcbiAgICAgICAgLy8gV2UgdXNlICRleGlzdHMgYW5kICRzZXQgdG8gYXZvaWQgb3ZlcndyaXRpbmcgdGhlIGZpZWxkIHR5cGUgaWYgaXRcbiAgICAgICAgLy8gYWxyZWFkeSBleGlzdHMuIChpdCBjb3VsZCBoYXZlIGFkZGVkIGluYmV0d2VlbiB0aGUgbGFzdCBxdWVyeSBhbmQgdGhlIHVwZGF0ZSlcbiAgICAgICAgaWYgKGZpZWxkT3B0aW9ucyAmJiBPYmplY3Qua2V5cyhmaWVsZE9wdGlvbnMpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy51cHNlcnRTY2hlbWEoXG4gICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICB7IFtmaWVsZE5hbWVdOiB7ICRleGlzdHM6IGZhbHNlIH0gfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgJHNldDoge1xuICAgICAgICAgICAgICAgIFtmaWVsZE5hbWVdOiBwYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUoe1xuICAgICAgICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgICAgICAgIHRhcmdldENsYXNzLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIFtgX21ldGFkYXRhLmZpZWxkc19vcHRpb25zLiR7ZmllbGROYW1lfWBdOiBmaWVsZE9wdGlvbnMsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy51cHNlcnRTY2hlbWEoXG4gICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICB7IFtmaWVsZE5hbWVdOiB7ICRleGlzdHM6IGZhbHNlIH0gfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgJHNldDoge1xuICAgICAgICAgICAgICAgIFtmaWVsZE5hbWVdOiBwYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUoe1xuICAgICAgICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgICAgICAgIHRhcmdldENsYXNzLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG59XG5cbi8vIEV4cG9ydGVkIGZvciB0ZXN0aW5nIHJlYXNvbnMgYW5kIGJlY2F1c2Ugd2UgaGF2ZW4ndCBtb3ZlZCBhbGwgbW9uZ28gc2NoZW1hIGZvcm1hdFxuLy8gcmVsYXRlZCBsb2dpYyBpbnRvIHRoZSBkYXRhYmFzZSBhZGFwdGVyIHlldC5cbk1vbmdvU2NoZW1hQ29sbGVjdGlvbi5fVEVTVG1vbmdvU2NoZW1hVG9QYXJzZVNjaGVtYSA9IG1vbmdvU2NoZW1hVG9QYXJzZVNjaGVtYTtcbk1vbmdvU2NoZW1hQ29sbGVjdGlvbi5wYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUgPSBwYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGU7XG5cbmV4cG9ydCBkZWZhdWx0IE1vbmdvU2NoZW1hQ29sbGVjdGlvbjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js b/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js new file mode 100644 index 0000000000..79bb74789f --- /dev/null +++ b/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -0,0 +1,957 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.MongoStorageAdapter = void 0; + +var _MongoCollection = _interopRequireDefault(require("./MongoCollection")); + +var _MongoSchemaCollection = _interopRequireDefault(require("./MongoSchemaCollection")); + +var _StorageAdapter = require("../StorageAdapter"); + +var _mongodbUrl = require("../../../vendor/mongodbUrl"); + +var _MongoTransform = require("./MongoTransform"); + +var _node = _interopRequireDefault(require("parse/node")); + +var _lodash = _interopRequireDefault(require("lodash")); + +var _defaults = _interopRequireDefault(require("../../../defaults")); + +var _logger = _interopRequireDefault(require("../../../logger")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } + +function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } + +function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } + +// -disable-next +const mongodb = require('mongodb'); + +const MongoClient = mongodb.MongoClient; +const ReadPreference = mongodb.ReadPreference; +const MongoSchemaCollectionName = '_SCHEMA'; + +const storageAdapterAllCollections = mongoAdapter => { + return mongoAdapter.connect().then(() => mongoAdapter.database.collections()).then(collections => { + return collections.filter(collection => { + if (collection.namespace.match(/\.system\./)) { + return false; + } // TODO: If you have one app with a collection prefix that happens to be a prefix of another + // apps prefix, this will go very very badly. We should fix that somehow. + + + return collection.collectionName.indexOf(mongoAdapter._collectionPrefix) == 0; + }); + }); +}; + +const convertParseSchemaToMongoSchema = (_ref) => { + let schema = _extends({}, _ref); + + delete schema.fields._rperm; + delete schema.fields._wperm; + + if (schema.className === '_User') { + // Legacy mongo adapter knows about the difference between password and _hashed_password. + // Future database adapters will only know about _hashed_password. + // Note: Parse Server will bring back password with injectDefaultSchema, so we don't need + // to add _hashed_password back ever. + delete schema.fields._hashed_password; + } + + return schema; +}; // Returns { code, error } if invalid, or { result }, an object +// suitable for inserting into _SCHEMA collection, otherwise. + + +const mongoSchemaFromFieldsAndClassNameAndCLP = (fields, className, classLevelPermissions, indexes) => { + const mongoObject = { + _id: className, + objectId: 'string', + updatedAt: 'string', + createdAt: 'string', + _metadata: undefined + }; + + for (const fieldName in fields) { + const _fields$fieldName = fields[fieldName], + { + type, + targetClass + } = _fields$fieldName, + fieldOptions = _objectWithoutProperties(_fields$fieldName, ["type", "targetClass"]); + + mongoObject[fieldName] = _MongoSchemaCollection.default.parseFieldTypeToMongoFieldType({ + type, + targetClass + }); + + if (fieldOptions && Object.keys(fieldOptions).length > 0) { + mongoObject._metadata = mongoObject._metadata || {}; + mongoObject._metadata.fields_options = mongoObject._metadata.fields_options || {}; + mongoObject._metadata.fields_options[fieldName] = fieldOptions; + } + } + + if (typeof classLevelPermissions !== 'undefined') { + mongoObject._metadata = mongoObject._metadata || {}; + + if (!classLevelPermissions) { + delete mongoObject._metadata.class_permissions; + } else { + mongoObject._metadata.class_permissions = classLevelPermissions; + } + } + + if (indexes && typeof indexes === 'object' && Object.keys(indexes).length > 0) { + mongoObject._metadata = mongoObject._metadata || {}; + mongoObject._metadata.indexes = indexes; + } + + if (!mongoObject._metadata) { + // cleanup the unused _metadata + delete mongoObject._metadata; + } + + return mongoObject; +}; + +class MongoStorageAdapter { + // Private + // Public + constructor({ + uri = _defaults.default.DefaultMongoURI, + collectionPrefix = '', + mongoOptions = {} + }) { + this._uri = uri; + this._collectionPrefix = collectionPrefix; + this._mongoOptions = mongoOptions; + this._mongoOptions.useNewUrlParser = true; + this._mongoOptions.useUnifiedTopology = true; // MaxTimeMS is not a global MongoDB client option, it is applied per operation. + + this._maxTimeMS = mongoOptions.maxTimeMS; + this.canSortOnJoinTables = true; + delete mongoOptions.maxTimeMS; + } + + connect() { + if (this.connectionPromise) { + return this.connectionPromise; + } // parsing and re-formatting causes the auth value (if there) to get URI + // encoded + + + const encodedUri = (0, _mongodbUrl.format)((0, _mongodbUrl.parse)(this._uri)); + this.connectionPromise = MongoClient.connect(encodedUri, this._mongoOptions).then(client => { + // Starting mongoDB 3.0, the MongoClient.connect don't return a DB anymore but a client + // Fortunately, we can get back the options and use them to select the proper DB. + // https://github.com/mongodb/node-mongodb-native/blob/2c35d76f08574225b8db02d7bef687123e6bb018/lib/mongo_client.js#L885 + const options = client.s.options; + const database = client.db(options.dbName); + + if (!database) { + delete this.connectionPromise; + return; + } + + database.on('error', () => { + delete this.connectionPromise; + }); + database.on('close', () => { + delete this.connectionPromise; + }); + this.client = client; + this.database = database; + }).catch(err => { + delete this.connectionPromise; + return Promise.reject(err); + }); + return this.connectionPromise; + } + + handleError(error) { + if (error && error.code === 13) { + // Unauthorized error + delete this.client; + delete this.database; + delete this.connectionPromise; + + _logger.default.error('Received unauthorized error', { + error: error + }); + } + + throw error; + } + + handleShutdown() { + if (!this.client) { + return Promise.resolve(); + } + + return this.client.close(false); + } + + _adaptiveCollection(name) { + return this.connect().then(() => this.database.collection(this._collectionPrefix + name)).then(rawCollection => new _MongoCollection.default(rawCollection)).catch(err => this.handleError(err)); + } + + _schemaCollection() { + return this.connect().then(() => this._adaptiveCollection(MongoSchemaCollectionName)).then(collection => new _MongoSchemaCollection.default(collection)); + } + + classExists(name) { + return this.connect().then(() => { + return this.database.listCollections({ + name: this._collectionPrefix + name + }).toArray(); + }).then(collections => { + return collections.length > 0; + }).catch(err => this.handleError(err)); + } + + setClassLevelPermissions(className, CLPs) { + return this._schemaCollection().then(schemaCollection => schemaCollection.updateSchema(className, { + $set: { + '_metadata.class_permissions': CLPs + } + })).catch(err => this.handleError(err)); + } + + setIndexesWithSchemaFormat(className, submittedIndexes, existingIndexes = {}, fields) { + if (submittedIndexes === undefined) { + return Promise.resolve(); + } + + if (Object.keys(existingIndexes).length === 0) { + existingIndexes = { + _id_: { + _id: 1 + } + }; + } + + const deletePromises = []; + const insertedIndexes = []; + Object.keys(submittedIndexes).forEach(name => { + const field = submittedIndexes[name]; + + if (existingIndexes[name] && field.__op !== 'Delete') { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Index ${name} exists, cannot update.`); + } + + if (!existingIndexes[name] && field.__op === 'Delete') { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Index ${name} does not exist, cannot delete.`); + } + + if (field.__op === 'Delete') { + const promise = this.dropIndex(className, name); + deletePromises.push(promise); + delete existingIndexes[name]; + } else { + Object.keys(field).forEach(key => { + if (!Object.prototype.hasOwnProperty.call(fields, key.indexOf('_p_') === 0 ? key.replace('_p_', '') : key)) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Field ${key} does not exist, cannot add index.`); + } + }); + existingIndexes[name] = field; + insertedIndexes.push({ + key: field, + name + }); + } + }); + let insertPromise = Promise.resolve(); + + if (insertedIndexes.length > 0) { + insertPromise = this.createIndexes(className, insertedIndexes); + } + + return Promise.all(deletePromises).then(() => insertPromise).then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.updateSchema(className, { + $set: { + '_metadata.indexes': existingIndexes + } + })).catch(err => this.handleError(err)); + } + + setIndexesFromMongo(className) { + return this.getIndexes(className).then(indexes => { + indexes = indexes.reduce((obj, index) => { + if (index.key._fts) { + delete index.key._fts; + delete index.key._ftsx; + + for (const field in index.weights) { + index.key[field] = 'text'; + } + } + + obj[index.name] = index.key; + return obj; + }, {}); + return this._schemaCollection().then(schemaCollection => schemaCollection.updateSchema(className, { + $set: { + '_metadata.indexes': indexes + } + })); + }).catch(err => this.handleError(err)).catch(() => { + // Ignore if collection not found + return Promise.resolve(); + }); + } + + createClass(className, schema) { + schema = convertParseSchemaToMongoSchema(schema); + const mongoObject = mongoSchemaFromFieldsAndClassNameAndCLP(schema.fields, className, schema.classLevelPermissions, schema.indexes); + mongoObject._id = className; + return this.setIndexesWithSchemaFormat(className, schema.indexes, {}, schema.fields).then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.insertSchema(mongoObject)).catch(err => this.handleError(err)); + } + + addFieldIfNotExists(className, fieldName, type) { + return this._schemaCollection().then(schemaCollection => schemaCollection.addFieldIfNotExists(className, fieldName, type)).then(() => this.createIndexesIfNeeded(className, fieldName, type)).catch(err => this.handleError(err)); + } // Drops a collection. Resolves with true if it was a Parse Schema (eg. _User, Custom, etc.) + // and resolves with false if it wasn't (eg. a join table). Rejects if deletion was impossible. + + + deleteClass(className) { + return this._adaptiveCollection(className).then(collection => collection.drop()).catch(error => { + // 'ns not found' means collection was already gone. Ignore deletion attempt. + if (error.message == 'ns not found') { + return; + } + + throw error; + }) // We've dropped the collection, now remove the _SCHEMA document + .then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.findAndDeleteSchema(className)).catch(err => this.handleError(err)); + } + + deleteAllClasses(fast) { + return storageAdapterAllCollections(this).then(collections => Promise.all(collections.map(collection => fast ? collection.deleteMany({}) : collection.drop()))); + } // Remove the column and all the data. For Relations, the _Join collection is handled + // specially, this function does not delete _Join columns. It should, however, indicate + // that the relation fields does not exist anymore. In mongo, this means removing it from + // the _SCHEMA collection. There should be no actual data in the collection under the same name + // as the relation column, so it's fine to attempt to delete it. If the fields listed to be + // deleted do not exist, this function should return successfully anyways. Checking for + // attempts to delete non-existent fields is the responsibility of Parse Server. + // Pointer field names are passed for legacy reasons: the original mongo + // format stored pointer field names differently in the database, and therefore + // needed to know the type of the field before it could delete it. Future database + // adapters should ignore the pointerFieldNames argument. All the field names are in + // fieldNames, they show up additionally in the pointerFieldNames database for use + // by the mongo adapter, which deals with the legacy mongo format. + // This function is not obligated to delete fields atomically. It is given the field + // names in a list so that databases that are capable of deleting fields atomically + // may do so. + // Returns a Promise. + + + deleteFields(className, schema, fieldNames) { + const mongoFormatNames = fieldNames.map(fieldName => { + if (schema.fields[fieldName].type === 'Pointer') { + return `_p_${fieldName}`; + } else { + return fieldName; + } + }); + const collectionUpdate = { + $unset: {} + }; + mongoFormatNames.forEach(name => { + collectionUpdate['$unset'][name] = null; + }); + const collectionFilter = { + $or: [] + }; + mongoFormatNames.forEach(name => { + collectionFilter['$or'].push({ + [name]: { + $exists: true + } + }); + }); + const schemaUpdate = { + $unset: {} + }; + fieldNames.forEach(name => { + schemaUpdate['$unset'][name] = null; + schemaUpdate['$unset'][`_metadata.fields_options.${name}`] = null; + }); + return this._adaptiveCollection(className).then(collection => collection.updateMany(collectionFilter, collectionUpdate)).then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.updateSchema(className, schemaUpdate)).catch(err => this.handleError(err)); + } // Return a promise for all schemas known to this adapter, in Parse format. In case the + // schemas cannot be retrieved, returns a promise that rejects. Requirements for the + // rejection reason are TBD. + + + getAllClasses() { + return this._schemaCollection().then(schemasCollection => schemasCollection._fetchAllSchemasFrom_SCHEMA()).catch(err => this.handleError(err)); + } // Return a promise for the schema with the given name, in Parse format. If + // this adapter doesn't know about the schema, return a promise that rejects with + // undefined as the reason. + + + getClass(className) { + return this._schemaCollection().then(schemasCollection => schemasCollection._fetchOneSchemaFrom_SCHEMA(className)).catch(err => this.handleError(err)); + } // TODO: As yet not particularly well specified. Creates an object. Maybe shouldn't even need the schema, + // and should infer from the type. Or maybe does need the schema for validations. Or maybe needs + // the schema only for the legacy mongo format. We'll figure that out later. + + + createObject(className, schema, object, transactionalSession) { + schema = convertParseSchemaToMongoSchema(schema); + const mongoObject = (0, _MongoTransform.parseObjectToMongoObjectForCreate)(className, object, schema); + return this._adaptiveCollection(className).then(collection => collection.insertOne(mongoObject, transactionalSession)).catch(error => { + if (error.code === 11000) { + // Duplicate value + const err = new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); + err.underlyingError = error; + + if (error.message) { + const matches = error.message.match(/index:[\sa-zA-Z0-9_\-\.]+\$?([a-zA-Z_-]+)_1/); + + if (matches && Array.isArray(matches)) { + err.userInfo = { + duplicated_field: matches[1] + }; + } + } + + throw err; + } + + throw error; + }).catch(err => this.handleError(err)); + } // Remove all objects that match the given Parse Query. + // If no objects match, reject with OBJECT_NOT_FOUND. If objects are found and deleted, resolve with undefined. + // If there is some other error, reject with INTERNAL_SERVER_ERROR. + + + deleteObjectsByQuery(className, schema, query, transactionalSession) { + schema = convertParseSchemaToMongoSchema(schema); + return this._adaptiveCollection(className).then(collection => { + const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); + return collection.deleteMany(mongoWhere, transactionalSession); + }).catch(err => this.handleError(err)).then(({ + result + }) => { + if (result.n === 0) { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } + + return Promise.resolve(); + }, () => { + throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'Database adapter error'); + }); + } // Apply the update to all objects that match the given Parse Query. + + + updateObjectsByQuery(className, schema, query, update, transactionalSession) { + schema = convertParseSchemaToMongoSchema(schema); + const mongoUpdate = (0, _MongoTransform.transformUpdate)(className, update, schema); + const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); + return this._adaptiveCollection(className).then(collection => collection.updateMany(mongoWhere, mongoUpdate, transactionalSession)).catch(err => this.handleError(err)); + } // Atomically finds and updates an object based on query. + // Return value not currently well specified. + + + findOneAndUpdate(className, schema, query, update, transactionalSession) { + schema = convertParseSchemaToMongoSchema(schema); + const mongoUpdate = (0, _MongoTransform.transformUpdate)(className, update, schema); + const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); + return this._adaptiveCollection(className).then(collection => collection._mongoCollection.findOneAndUpdate(mongoWhere, mongoUpdate, { + returnOriginal: false, + session: transactionalSession || undefined + })).then(result => (0, _MongoTransform.mongoObjectToParseObject)(className, result.value, schema)).catch(error => { + if (error.code === 11000) { + throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); + } + + throw error; + }).catch(err => this.handleError(err)); + } // Hopefully we can get rid of this. It's only used for config and hooks. + + + upsertOneObject(className, schema, query, update, transactionalSession) { + schema = convertParseSchemaToMongoSchema(schema); + const mongoUpdate = (0, _MongoTransform.transformUpdate)(className, update, schema); + const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); + return this._adaptiveCollection(className).then(collection => collection.upsertOne(mongoWhere, mongoUpdate, transactionalSession)).catch(err => this.handleError(err)); + } // Executes a find. Accepts: className, query in Parse format, and { skip, limit, sort }. + + + find(className, schema, query, { + skip, + limit, + sort, + keys, + readPreference, + hint, + caseInsensitive, + explain + }) { + schema = convertParseSchemaToMongoSchema(schema); + const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); + + const mongoSort = _lodash.default.mapKeys(sort, (value, fieldName) => (0, _MongoTransform.transformKey)(className, fieldName, schema)); + + const mongoKeys = _lodash.default.reduce(keys, (memo, key) => { + if (key === 'ACL') { + memo['_rperm'] = 1; + memo['_wperm'] = 1; + } else { + memo[(0, _MongoTransform.transformKey)(className, key, schema)] = 1; + } + + return memo; + }, {}); // If we aren't requesting the `_id` field, we need to explicitly opt out + // of it. Doing so in parse-server is unusual, but it can allow us to + // optimize some queries with covering indexes. + + + if (keys && !mongoKeys._id) { + mongoKeys._id = 0; + } + + readPreference = this._parseReadPreference(readPreference); + return this.createTextIndexesIfNeeded(className, query, schema).then(() => this._adaptiveCollection(className)).then(collection => collection.find(mongoWhere, { + skip, + limit, + sort: mongoSort, + keys: mongoKeys, + maxTimeMS: this._maxTimeMS, + readPreference, + hint, + caseInsensitive, + explain + })).then(objects => { + if (explain) { + return objects; + } + + return objects.map(object => (0, _MongoTransform.mongoObjectToParseObject)(className, object, schema)); + }).catch(err => this.handleError(err)); + } + + ensureIndex(className, schema, fieldNames, indexName, caseInsensitive = false, options = {}) { + schema = convertParseSchemaToMongoSchema(schema); + const indexCreationRequest = {}; + const mongoFieldNames = fieldNames.map(fieldName => (0, _MongoTransform.transformKey)(className, fieldName, schema)); + mongoFieldNames.forEach(fieldName => { + indexCreationRequest[fieldName] = options.indexType !== undefined ? options.indexType : 1; + }); + const defaultOptions = { + background: true, + sparse: true + }; + const indexNameOptions = indexName ? { + name: indexName + } : {}; + const ttlOptions = options.ttl !== undefined ? { + expireAfterSeconds: options.ttl + } : {}; + const caseInsensitiveOptions = caseInsensitive ? { + collation: _MongoCollection.default.caseInsensitiveCollation() + } : {}; + + const indexOptions = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, defaultOptions), caseInsensitiveOptions), indexNameOptions), ttlOptions); + + return this._adaptiveCollection(className).then(collection => new Promise((resolve, reject) => collection._mongoCollection.createIndex(indexCreationRequest, indexOptions, error => error ? reject(error) : resolve()))).catch(err => this.handleError(err)); + } // Create a unique index. Unique indexes on nullable fields are not allowed. Since we don't + // currently know which fields are nullable and which aren't, we ignore that criteria. + // As such, we shouldn't expose this function to users of parse until we have an out-of-band + // Way of determining if a field is nullable. Undefined doesn't count against uniqueness, + // which is why we use sparse indexes. + + + ensureUniqueness(className, schema, fieldNames) { + schema = convertParseSchemaToMongoSchema(schema); + const indexCreationRequest = {}; + const mongoFieldNames = fieldNames.map(fieldName => (0, _MongoTransform.transformKey)(className, fieldName, schema)); + mongoFieldNames.forEach(fieldName => { + indexCreationRequest[fieldName] = 1; + }); + return this._adaptiveCollection(className).then(collection => collection._ensureSparseUniqueIndexInBackground(indexCreationRequest)).catch(error => { + if (error.code === 11000) { + throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'Tried to ensure field uniqueness for a class that already has duplicates.'); + } + + throw error; + }).catch(err => this.handleError(err)); + } // Used in tests + + + _rawFind(className, query) { + return this._adaptiveCollection(className).then(collection => collection.find(query, { + maxTimeMS: this._maxTimeMS + })).catch(err => this.handleError(err)); + } // Executes a count. + + + count(className, schema, query, readPreference, hint) { + schema = convertParseSchemaToMongoSchema(schema); + readPreference = this._parseReadPreference(readPreference); + return this._adaptiveCollection(className).then(collection => collection.count((0, _MongoTransform.transformWhere)(className, query, schema, true), { + maxTimeMS: this._maxTimeMS, + readPreference, + hint + })).catch(err => this.handleError(err)); + } + + distinct(className, schema, query, fieldName) { + schema = convertParseSchemaToMongoSchema(schema); + const isPointerField = schema.fields[fieldName] && schema.fields[fieldName].type === 'Pointer'; + const transformField = (0, _MongoTransform.transformKey)(className, fieldName, schema); + return this._adaptiveCollection(className).then(collection => collection.distinct(transformField, (0, _MongoTransform.transformWhere)(className, query, schema))).then(objects => { + objects = objects.filter(obj => obj != null); + return objects.map(object => { + if (isPointerField) { + return (0, _MongoTransform.transformPointerString)(schema, fieldName, object); + } + + return (0, _MongoTransform.mongoObjectToParseObject)(className, object, schema); + }); + }).catch(err => this.handleError(err)); + } + + aggregate(className, schema, pipeline, readPreference, hint, explain) { + let isPointerField = false; + pipeline = pipeline.map(stage => { + if (stage.$group) { + stage.$group = this._parseAggregateGroupArgs(schema, stage.$group); + + if (stage.$group._id && typeof stage.$group._id === 'string' && stage.$group._id.indexOf('$_p_') >= 0) { + isPointerField = true; + } + } + + if (stage.$match) { + stage.$match = this._parseAggregateArgs(schema, stage.$match); + } + + if (stage.$project) { + stage.$project = this._parseAggregateProjectArgs(schema, stage.$project); + } + + if (stage.$geoNear && stage.$geoNear.query) { + stage.$geoNear.query = this._parseAggregateArgs(schema, stage.$geoNear.query); + } + + return stage; + }); + readPreference = this._parseReadPreference(readPreference); + return this._adaptiveCollection(className).then(collection => collection.aggregate(pipeline, { + readPreference, + maxTimeMS: this._maxTimeMS, + hint, + explain + })).then(results => { + results.forEach(result => { + if (Object.prototype.hasOwnProperty.call(result, '_id')) { + if (isPointerField && result._id) { + result._id = result._id.split('$')[1]; + } + + if (result._id == null || result._id == undefined || ['object', 'string'].includes(typeof result._id) && _lodash.default.isEmpty(result._id)) { + result._id = null; + } + + result.objectId = result._id; + delete result._id; + } + }); + return results; + }).then(objects => objects.map(object => (0, _MongoTransform.mongoObjectToParseObject)(className, object, schema))).catch(err => this.handleError(err)); + } // This function will recursively traverse the pipeline and convert any Pointer or Date columns. + // If we detect a pointer column we will rename the column being queried for to match the column + // in the database. We also modify the value to what we expect the value to be in the database + // as well. + // For dates, the driver expects a Date object, but we have a string coming in. So we'll convert + // the string to a Date so the driver can perform the necessary comparison. + // + // The goal of this method is to look for the "leaves" of the pipeline and determine if it needs + // to be converted. The pipeline can have a few different forms. For more details, see: + // https://docs.mongodb.com/manual/reference/operator/aggregation/ + // + // If the pipeline is an array, it means we are probably parsing an '$and' or '$or' operator. In + // that case we need to loop through all of it's children to find the columns being operated on. + // If the pipeline is an object, then we'll loop through the keys checking to see if the key name + // matches one of the schema columns. If it does match a column and the column is a Pointer or + // a Date, then we'll convert the value as described above. + // + // As much as I hate recursion...this seemed like a good fit for it. We're essentially traversing + // down a tree to find a "leaf node" and checking to see if it needs to be converted. + + + _parseAggregateArgs(schema, pipeline) { + if (pipeline === null) { + return null; + } else if (Array.isArray(pipeline)) { + return pipeline.map(value => this._parseAggregateArgs(schema, value)); + } else if (typeof pipeline === 'object') { + const returnValue = {}; + + for (const field in pipeline) { + if (schema.fields[field] && schema.fields[field].type === 'Pointer') { + if (typeof pipeline[field] === 'object') { + // Pass objects down to MongoDB...this is more than likely an $exists operator. + returnValue[`_p_${field}`] = pipeline[field]; + } else { + returnValue[`_p_${field}`] = `${schema.fields[field].targetClass}$${pipeline[field]}`; + } + } else if (schema.fields[field] && schema.fields[field].type === 'Date') { + returnValue[field] = this._convertToDate(pipeline[field]); + } else { + returnValue[field] = this._parseAggregateArgs(schema, pipeline[field]); + } + + if (field === 'objectId') { + returnValue['_id'] = returnValue[field]; + delete returnValue[field]; + } else if (field === 'createdAt') { + returnValue['_created_at'] = returnValue[field]; + delete returnValue[field]; + } else if (field === 'updatedAt') { + returnValue['_updated_at'] = returnValue[field]; + delete returnValue[field]; + } + } + + return returnValue; + } + + return pipeline; + } // This function is slightly different than the one above. Rather than trying to combine these + // two functions and making the code even harder to understand, I decided to split it up. The + // difference with this function is we are not transforming the values, only the keys of the + // pipeline. + + + _parseAggregateProjectArgs(schema, pipeline) { + const returnValue = {}; + + for (const field in pipeline) { + if (schema.fields[field] && schema.fields[field].type === 'Pointer') { + returnValue[`_p_${field}`] = pipeline[field]; + } else { + returnValue[field] = this._parseAggregateArgs(schema, pipeline[field]); + } + + if (field === 'objectId') { + returnValue['_id'] = returnValue[field]; + delete returnValue[field]; + } else if (field === 'createdAt') { + returnValue['_created_at'] = returnValue[field]; + delete returnValue[field]; + } else if (field === 'updatedAt') { + returnValue['_updated_at'] = returnValue[field]; + delete returnValue[field]; + } + } + + return returnValue; + } // This function is slightly different than the two above. MongoDB $group aggregate looks like: + // { $group: { _id: , : { : }, ... } } + // The could be a column name, prefixed with the '$' character. We'll look for + // these and check to see if it is a 'Pointer' or if it's one of createdAt, + // updatedAt or objectId and change it accordingly. + + + _parseAggregateGroupArgs(schema, pipeline) { + if (Array.isArray(pipeline)) { + return pipeline.map(value => this._parseAggregateGroupArgs(schema, value)); + } else if (typeof pipeline === 'object') { + const returnValue = {}; + + for (const field in pipeline) { + returnValue[field] = this._parseAggregateGroupArgs(schema, pipeline[field]); + } + + return returnValue; + } else if (typeof pipeline === 'string') { + const field = pipeline.substring(1); + + if (schema.fields[field] && schema.fields[field].type === 'Pointer') { + return `$_p_${field}`; + } else if (field == 'createdAt') { + return '$_created_at'; + } else if (field == 'updatedAt') { + return '$_updated_at'; + } + } + + return pipeline; + } // This function will attempt to convert the provided value to a Date object. Since this is part + // of an aggregation pipeline, the value can either be a string or it can be another object with + // an operator in it (like $gt, $lt, etc). Because of this I felt it was easier to make this a + // recursive method to traverse down to the "leaf node" which is going to be the string. + + + _convertToDate(value) { + if (typeof value === 'string') { + return new Date(value); + } + + const returnValue = {}; + + for (const field in value) { + returnValue[field] = this._convertToDate(value[field]); + } + + return returnValue; + } + + _parseReadPreference(readPreference) { + if (readPreference) { + readPreference = readPreference.toUpperCase(); + } + + switch (readPreference) { + case 'PRIMARY': + readPreference = ReadPreference.PRIMARY; + break; + + case 'PRIMARY_PREFERRED': + readPreference = ReadPreference.PRIMARY_PREFERRED; + break; + + case 'SECONDARY': + readPreference = ReadPreference.SECONDARY; + break; + + case 'SECONDARY_PREFERRED': + readPreference = ReadPreference.SECONDARY_PREFERRED; + break; + + case 'NEAREST': + readPreference = ReadPreference.NEAREST; + break; + + case undefined: + case null: + case '': + break; + + default: + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Not supported read preference.'); + } + + return readPreference; + } + + performInitialization() { + return Promise.resolve(); + } + + createIndex(className, index) { + return this._adaptiveCollection(className).then(collection => collection._mongoCollection.createIndex(index)).catch(err => this.handleError(err)); + } + + createIndexes(className, indexes) { + return this._adaptiveCollection(className).then(collection => collection._mongoCollection.createIndexes(indexes)).catch(err => this.handleError(err)); + } + + createIndexesIfNeeded(className, fieldName, type) { + if (type && type.type === 'Polygon') { + const index = { + [fieldName]: '2dsphere' + }; + return this.createIndex(className, index); + } + + return Promise.resolve(); + } + + createTextIndexesIfNeeded(className, query, schema) { + for (const fieldName in query) { + if (!query[fieldName] || !query[fieldName].$text) { + continue; + } + + const existingIndexes = schema.indexes; + + for (const key in existingIndexes) { + const index = existingIndexes[key]; + + if (Object.prototype.hasOwnProperty.call(index, fieldName)) { + return Promise.resolve(); + } + } + + const indexName = `${fieldName}_text`; + const textIndex = { + [indexName]: { + [fieldName]: 'text' + } + }; + return this.setIndexesWithSchemaFormat(className, textIndex, existingIndexes, schema.fields).catch(error => { + if (error.code === 85) { + // Index exist with different options + return this.setIndexesFromMongo(className); + } + + throw error; + }); + } + + return Promise.resolve(); + } + + getIndexes(className) { + return this._adaptiveCollection(className).then(collection => collection._mongoCollection.indexes()).catch(err => this.handleError(err)); + } + + dropIndex(className, index) { + return this._adaptiveCollection(className).then(collection => collection._mongoCollection.dropIndex(index)).catch(err => this.handleError(err)); + } + + dropAllIndexes(className) { + return this._adaptiveCollection(className).then(collection => collection._mongoCollection.dropIndexes()).catch(err => this.handleError(err)); + } + + updateSchemaWithIndexes() { + return this.getAllClasses().then(classes => { + const promises = classes.map(schema => { + return this.setIndexesFromMongo(schema.className); + }); + return Promise.all(promises); + }).catch(err => this.handleError(err)); + } + + createTransactionalSession() { + const transactionalSection = this.client.startSession(); + transactionalSection.startTransaction(); + return Promise.resolve(transactionalSection); + } + + commitTransactionalSession(transactionalSection) { + return transactionalSection.commitTransaction().then(() => { + transactionalSection.endSession(); + }); + } + + abortTransactionalSession(transactionalSection) { + return transactionalSection.abortTransaction().then(() => { + transactionalSection.endSession(); + }); + } + +} + +exports.MongoStorageAdapter = MongoStorageAdapter; +var _default = MongoStorageAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvU3RvcmFnZUFkYXB0ZXIuanMiXSwibmFtZXMiOlsibW9uZ29kYiIsInJlcXVpcmUiLCJNb25nb0NsaWVudCIsIlJlYWRQcmVmZXJlbmNlIiwiTW9uZ29TY2hlbWFDb2xsZWN0aW9uTmFtZSIsInN0b3JhZ2VBZGFwdGVyQWxsQ29sbGVjdGlvbnMiLCJtb25nb0FkYXB0ZXIiLCJjb25uZWN0IiwidGhlbiIsImRhdGFiYXNlIiwiY29sbGVjdGlvbnMiLCJmaWx0ZXIiLCJjb2xsZWN0aW9uIiwibmFtZXNwYWNlIiwibWF0Y2giLCJjb2xsZWN0aW9uTmFtZSIsImluZGV4T2YiLCJfY29sbGVjdGlvblByZWZpeCIsImNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEiLCJzY2hlbWEiLCJmaWVsZHMiLCJfcnBlcm0iLCJfd3Blcm0iLCJjbGFzc05hbWUiLCJfaGFzaGVkX3Bhc3N3b3JkIiwibW9uZ29TY2hlbWFGcm9tRmllbGRzQW5kQ2xhc3NOYW1lQW5kQ0xQIiwiY2xhc3NMZXZlbFBlcm1pc3Npb25zIiwiaW5kZXhlcyIsIm1vbmdvT2JqZWN0IiwiX2lkIiwib2JqZWN0SWQiLCJ1cGRhdGVkQXQiLCJjcmVhdGVkQXQiLCJfbWV0YWRhdGEiLCJ1bmRlZmluZWQiLCJmaWVsZE5hbWUiLCJ0eXBlIiwidGFyZ2V0Q2xhc3MiLCJmaWVsZE9wdGlvbnMiLCJNb25nb1NjaGVtYUNvbGxlY3Rpb24iLCJwYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUiLCJPYmplY3QiLCJrZXlzIiwibGVuZ3RoIiwiZmllbGRzX29wdGlvbnMiLCJjbGFzc19wZXJtaXNzaW9ucyIsIk1vbmdvU3RvcmFnZUFkYXB0ZXIiLCJjb25zdHJ1Y3RvciIsInVyaSIsImRlZmF1bHRzIiwiRGVmYXVsdE1vbmdvVVJJIiwiY29sbGVjdGlvblByZWZpeCIsIm1vbmdvT3B0aW9ucyIsIl91cmkiLCJfbW9uZ29PcHRpb25zIiwidXNlTmV3VXJsUGFyc2VyIiwidXNlVW5pZmllZFRvcG9sb2d5IiwiX21heFRpbWVNUyIsIm1heFRpbWVNUyIsImNhblNvcnRPbkpvaW5UYWJsZXMiLCJjb25uZWN0aW9uUHJvbWlzZSIsImVuY29kZWRVcmkiLCJjbGllbnQiLCJvcHRpb25zIiwicyIsImRiIiwiZGJOYW1lIiwib24iLCJjYXRjaCIsImVyciIsIlByb21pc2UiLCJyZWplY3QiLCJoYW5kbGVFcnJvciIsImVycm9yIiwiY29kZSIsImxvZ2dlciIsImhhbmRsZVNodXRkb3duIiwicmVzb2x2ZSIsImNsb3NlIiwiX2FkYXB0aXZlQ29sbGVjdGlvbiIsIm5hbWUiLCJyYXdDb2xsZWN0aW9uIiwiTW9uZ29Db2xsZWN0aW9uIiwiX3NjaGVtYUNvbGxlY3Rpb24iLCJjbGFzc0V4aXN0cyIsImxpc3RDb2xsZWN0aW9ucyIsInRvQXJyYXkiLCJzZXRDbGFzc0xldmVsUGVybWlzc2lvbnMiLCJDTFBzIiwic2NoZW1hQ29sbGVjdGlvbiIsInVwZGF0ZVNjaGVtYSIsIiRzZXQiLCJzZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdCIsInN1Ym1pdHRlZEluZGV4ZXMiLCJleGlzdGluZ0luZGV4ZXMiLCJfaWRfIiwiZGVsZXRlUHJvbWlzZXMiLCJpbnNlcnRlZEluZGV4ZXMiLCJmb3JFYWNoIiwiZmllbGQiLCJfX29wIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfUVVFUlkiLCJwcm9taXNlIiwiZHJvcEluZGV4IiwicHVzaCIsImtleSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInJlcGxhY2UiLCJpbnNlcnRQcm9taXNlIiwiY3JlYXRlSW5kZXhlcyIsImFsbCIsInNldEluZGV4ZXNGcm9tTW9uZ28iLCJnZXRJbmRleGVzIiwicmVkdWNlIiwib2JqIiwiaW5kZXgiLCJfZnRzIiwiX2Z0c3giLCJ3ZWlnaHRzIiwiY3JlYXRlQ2xhc3MiLCJpbnNlcnRTY2hlbWEiLCJhZGRGaWVsZElmTm90RXhpc3RzIiwiY3JlYXRlSW5kZXhlc0lmTmVlZGVkIiwiZGVsZXRlQ2xhc3MiLCJkcm9wIiwibWVzc2FnZSIsImZpbmRBbmREZWxldGVTY2hlbWEiLCJkZWxldGVBbGxDbGFzc2VzIiwiZmFzdCIsIm1hcCIsImRlbGV0ZU1hbnkiLCJkZWxldGVGaWVsZHMiLCJmaWVsZE5hbWVzIiwibW9uZ29Gb3JtYXROYW1lcyIsImNvbGxlY3Rpb25VcGRhdGUiLCIkdW5zZXQiLCJjb2xsZWN0aW9uRmlsdGVyIiwiJG9yIiwiJGV4aXN0cyIsInNjaGVtYVVwZGF0ZSIsInVwZGF0ZU1hbnkiLCJnZXRBbGxDbGFzc2VzIiwic2NoZW1hc0NvbGxlY3Rpb24iLCJfZmV0Y2hBbGxTY2hlbWFzRnJvbV9TQ0hFTUEiLCJnZXRDbGFzcyIsIl9mZXRjaE9uZVNjaGVtYUZyb21fU0NIRU1BIiwiY3JlYXRlT2JqZWN0Iiwib2JqZWN0IiwidHJhbnNhY3Rpb25hbFNlc3Npb24iLCJpbnNlcnRPbmUiLCJEVVBMSUNBVEVfVkFMVUUiLCJ1bmRlcmx5aW5nRXJyb3IiLCJtYXRjaGVzIiwiQXJyYXkiLCJpc0FycmF5IiwidXNlckluZm8iLCJkdXBsaWNhdGVkX2ZpZWxkIiwiZGVsZXRlT2JqZWN0c0J5UXVlcnkiLCJxdWVyeSIsIm1vbmdvV2hlcmUiLCJyZXN1bHQiLCJuIiwiT0JKRUNUX05PVF9GT1VORCIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsInVwZGF0ZU9iamVjdHNCeVF1ZXJ5IiwidXBkYXRlIiwibW9uZ29VcGRhdGUiLCJmaW5kT25lQW5kVXBkYXRlIiwiX21vbmdvQ29sbGVjdGlvbiIsInJldHVybk9yaWdpbmFsIiwic2Vzc2lvbiIsInZhbHVlIiwidXBzZXJ0T25lT2JqZWN0IiwidXBzZXJ0T25lIiwiZmluZCIsInNraXAiLCJsaW1pdCIsInNvcnQiLCJyZWFkUHJlZmVyZW5jZSIsImhpbnQiLCJjYXNlSW5zZW5zaXRpdmUiLCJleHBsYWluIiwibW9uZ29Tb3J0IiwiXyIsIm1hcEtleXMiLCJtb25nb0tleXMiLCJtZW1vIiwiX3BhcnNlUmVhZFByZWZlcmVuY2UiLCJjcmVhdGVUZXh0SW5kZXhlc0lmTmVlZGVkIiwib2JqZWN0cyIsImVuc3VyZUluZGV4IiwiaW5kZXhOYW1lIiwiaW5kZXhDcmVhdGlvblJlcXVlc3QiLCJtb25nb0ZpZWxkTmFtZXMiLCJpbmRleFR5cGUiLCJkZWZhdWx0T3B0aW9ucyIsImJhY2tncm91bmQiLCJzcGFyc2UiLCJpbmRleE5hbWVPcHRpb25zIiwidHRsT3B0aW9ucyIsInR0bCIsImV4cGlyZUFmdGVyU2Vjb25kcyIsImNhc2VJbnNlbnNpdGl2ZU9wdGlvbnMiLCJjb2xsYXRpb24iLCJjYXNlSW5zZW5zaXRpdmVDb2xsYXRpb24iLCJpbmRleE9wdGlvbnMiLCJjcmVhdGVJbmRleCIsImVuc3VyZVVuaXF1ZW5lc3MiLCJfZW5zdXJlU3BhcnNlVW5pcXVlSW5kZXhJbkJhY2tncm91bmQiLCJfcmF3RmluZCIsImNvdW50IiwiZGlzdGluY3QiLCJpc1BvaW50ZXJGaWVsZCIsInRyYW5zZm9ybUZpZWxkIiwiYWdncmVnYXRlIiwicGlwZWxpbmUiLCJzdGFnZSIsIiRncm91cCIsIl9wYXJzZUFnZ3JlZ2F0ZUdyb3VwQXJncyIsIiRtYXRjaCIsIl9wYXJzZUFnZ3JlZ2F0ZUFyZ3MiLCIkcHJvamVjdCIsIl9wYXJzZUFnZ3JlZ2F0ZVByb2plY3RBcmdzIiwiJGdlb05lYXIiLCJyZXN1bHRzIiwic3BsaXQiLCJpbmNsdWRlcyIsImlzRW1wdHkiLCJyZXR1cm5WYWx1ZSIsIl9jb252ZXJ0VG9EYXRlIiwic3Vic3RyaW5nIiwiRGF0ZSIsInRvVXBwZXJDYXNlIiwiUFJJTUFSWSIsIlBSSU1BUllfUFJFRkVSUkVEIiwiU0VDT05EQVJZIiwiU0VDT05EQVJZX1BSRUZFUlJFRCIsIk5FQVJFU1QiLCJwZXJmb3JtSW5pdGlhbGl6YXRpb24iLCIkdGV4dCIsInRleHRJbmRleCIsImRyb3BBbGxJbmRleGVzIiwiZHJvcEluZGV4ZXMiLCJ1cGRhdGVTY2hlbWFXaXRoSW5kZXhlcyIsImNsYXNzZXMiLCJwcm9taXNlcyIsImNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uIiwidHJhbnNhY3Rpb25hbFNlY3Rpb24iLCJzdGFydFNlc3Npb24iLCJzdGFydFRyYW5zYWN0aW9uIiwiY29tbWl0VHJhbnNhY3Rpb25hbFNlc3Npb24iLCJjb21taXRUcmFuc2FjdGlvbiIsImVuZFNlc3Npb24iLCJhYm9ydFRyYW5zYWN0aW9uYWxTZXNzaW9uIiwiYWJvcnRUcmFuc2FjdGlvbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUNBOztBQUNBOztBQUNBOztBQUVBOztBQUNBOztBQVNBOztBQUVBOztBQUNBOztBQUNBOzs7Ozs7Ozs7Ozs7Ozs7O0FBRUE7QUFDQSxNQUFNQSxPQUFPLEdBQUdDLE9BQU8sQ0FBQyxTQUFELENBQXZCOztBQUNBLE1BQU1DLFdBQVcsR0FBR0YsT0FBTyxDQUFDRSxXQUE1QjtBQUNBLE1BQU1DLGNBQWMsR0FBR0gsT0FBTyxDQUFDRyxjQUEvQjtBQUVBLE1BQU1DLHlCQUF5QixHQUFHLFNBQWxDOztBQUVBLE1BQU1DLDRCQUE0QixHQUFHQyxZQUFZLElBQUk7QUFDbkQsU0FBT0EsWUFBWSxDQUNoQkMsT0FESSxHQUVKQyxJQUZJLENBRUMsTUFBTUYsWUFBWSxDQUFDRyxRQUFiLENBQXNCQyxXQUF0QixFQUZQLEVBR0pGLElBSEksQ0FHQ0UsV0FBVyxJQUFJO0FBQ25CLFdBQU9BLFdBQVcsQ0FBQ0MsTUFBWixDQUFtQkMsVUFBVSxJQUFJO0FBQ3RDLFVBQUlBLFVBQVUsQ0FBQ0MsU0FBWCxDQUFxQkMsS0FBckIsQ0FBMkIsWUFBM0IsQ0FBSixFQUE4QztBQUM1QyxlQUFPLEtBQVA7QUFDRCxPQUhxQyxDQUl0QztBQUNBOzs7QUFDQSxhQUFPRixVQUFVLENBQUNHLGNBQVgsQ0FBMEJDLE9BQTFCLENBQWtDVixZQUFZLENBQUNXLGlCQUEvQyxLQUFxRSxDQUE1RTtBQUNELEtBUE0sQ0FBUDtBQVFELEdBWkksQ0FBUDtBQWFELENBZEQ7O0FBZ0JBLE1BQU1DLCtCQUErQixHQUFHLFVBQW1CO0FBQUEsTUFBYkMsTUFBYTs7QUFDekQsU0FBT0EsTUFBTSxDQUFDQyxNQUFQLENBQWNDLE1BQXJCO0FBQ0EsU0FBT0YsTUFBTSxDQUFDQyxNQUFQLENBQWNFLE1BQXJCOztBQUVBLE1BQUlILE1BQU0sQ0FBQ0ksU0FBUCxLQUFxQixPQUF6QixFQUFrQztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQU9KLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjSSxnQkFBckI7QUFDRDs7QUFFRCxTQUFPTCxNQUFQO0FBQ0QsQ0FiRCxDLENBZUE7QUFDQTs7O0FBQ0EsTUFBTU0sdUNBQXVDLEdBQUcsQ0FDOUNMLE1BRDhDLEVBRTlDRyxTQUY4QyxFQUc5Q0cscUJBSDhDLEVBSTlDQyxPQUo4QyxLQUszQztBQUNILFFBQU1DLFdBQVcsR0FBRztBQUNsQkMsSUFBQUEsR0FBRyxFQUFFTixTQURhO0FBRWxCTyxJQUFBQSxRQUFRLEVBQUUsUUFGUTtBQUdsQkMsSUFBQUEsU0FBUyxFQUFFLFFBSE87QUFJbEJDLElBQUFBLFNBQVMsRUFBRSxRQUpPO0FBS2xCQyxJQUFBQSxTQUFTLEVBQUVDO0FBTE8sR0FBcEI7O0FBUUEsT0FBSyxNQUFNQyxTQUFYLElBQXdCZixNQUF4QixFQUFnQztBQUM5Qiw4QkFBK0NBLE1BQU0sQ0FBQ2UsU0FBRCxDQUFyRDtBQUFBLFVBQU07QUFBRUMsTUFBQUEsSUFBRjtBQUFRQyxNQUFBQTtBQUFSLEtBQU47QUFBQSxVQUE4QkMsWUFBOUI7O0FBQ0FWLElBQUFBLFdBQVcsQ0FBQ08sU0FBRCxDQUFYLEdBQXlCSSwrQkFBc0JDLDhCQUF0QixDQUFxRDtBQUM1RUosTUFBQUEsSUFENEU7QUFFNUVDLE1BQUFBO0FBRjRFLEtBQXJELENBQXpCOztBQUlBLFFBQUlDLFlBQVksSUFBSUcsTUFBTSxDQUFDQyxJQUFQLENBQVlKLFlBQVosRUFBMEJLLE1BQTFCLEdBQW1DLENBQXZELEVBQTBEO0FBQ3hEZixNQUFBQSxXQUFXLENBQUNLLFNBQVosR0FBd0JMLFdBQVcsQ0FBQ0ssU0FBWixJQUF5QixFQUFqRDtBQUNBTCxNQUFBQSxXQUFXLENBQUNLLFNBQVosQ0FBc0JXLGNBQXRCLEdBQXVDaEIsV0FBVyxDQUFDSyxTQUFaLENBQXNCVyxjQUF0QixJQUF3QyxFQUEvRTtBQUNBaEIsTUFBQUEsV0FBVyxDQUFDSyxTQUFaLENBQXNCVyxjQUF0QixDQUFxQ1QsU0FBckMsSUFBa0RHLFlBQWxEO0FBQ0Q7QUFDRjs7QUFFRCxNQUFJLE9BQU9aLHFCQUFQLEtBQWlDLFdBQXJDLEVBQWtEO0FBQ2hERSxJQUFBQSxXQUFXLENBQUNLLFNBQVosR0FBd0JMLFdBQVcsQ0FBQ0ssU0FBWixJQUF5QixFQUFqRDs7QUFDQSxRQUFJLENBQUNQLHFCQUFMLEVBQTRCO0FBQzFCLGFBQU9FLFdBQVcsQ0FBQ0ssU0FBWixDQUFzQlksaUJBQTdCO0FBQ0QsS0FGRCxNQUVPO0FBQ0xqQixNQUFBQSxXQUFXLENBQUNLLFNBQVosQ0FBc0JZLGlCQUF0QixHQUEwQ25CLHFCQUExQztBQUNEO0FBQ0Y7O0FBRUQsTUFBSUMsT0FBTyxJQUFJLE9BQU9BLE9BQVAsS0FBbUIsUUFBOUIsSUFBMENjLE1BQU0sQ0FBQ0MsSUFBUCxDQUFZZixPQUFaLEVBQXFCZ0IsTUFBckIsR0FBOEIsQ0FBNUUsRUFBK0U7QUFDN0VmLElBQUFBLFdBQVcsQ0FBQ0ssU0FBWixHQUF3QkwsV0FBVyxDQUFDSyxTQUFaLElBQXlCLEVBQWpEO0FBQ0FMLElBQUFBLFdBQVcsQ0FBQ0ssU0FBWixDQUFzQk4sT0FBdEIsR0FBZ0NBLE9BQWhDO0FBQ0Q7O0FBRUQsTUFBSSxDQUFDQyxXQUFXLENBQUNLLFNBQWpCLEVBQTRCO0FBQzFCO0FBQ0EsV0FBT0wsV0FBVyxDQUFDSyxTQUFuQjtBQUNEOztBQUVELFNBQU9MLFdBQVA7QUFDRCxDQS9DRDs7QUFpRE8sTUFBTWtCLG1CQUFOLENBQW9EO0FBQ3pEO0FBSUE7QUFPQUMsRUFBQUEsV0FBVyxDQUFDO0FBQUVDLElBQUFBLEdBQUcsR0FBR0Msa0JBQVNDLGVBQWpCO0FBQWtDQyxJQUFBQSxnQkFBZ0IsR0FBRyxFQUFyRDtBQUF5REMsSUFBQUEsWUFBWSxHQUFHO0FBQXhFLEdBQUQsRUFBb0Y7QUFDN0YsU0FBS0MsSUFBTCxHQUFZTCxHQUFaO0FBQ0EsU0FBSy9CLGlCQUFMLEdBQXlCa0MsZ0JBQXpCO0FBQ0EsU0FBS0csYUFBTCxHQUFxQkYsWUFBckI7QUFDQSxTQUFLRSxhQUFMLENBQW1CQyxlQUFuQixHQUFxQyxJQUFyQztBQUNBLFNBQUtELGFBQUwsQ0FBbUJFLGtCQUFuQixHQUF3QyxJQUF4QyxDQUw2RixDQU83Rjs7QUFDQSxTQUFLQyxVQUFMLEdBQWtCTCxZQUFZLENBQUNNLFNBQS9CO0FBQ0EsU0FBS0MsbUJBQUwsR0FBMkIsSUFBM0I7QUFDQSxXQUFPUCxZQUFZLENBQUNNLFNBQXBCO0FBQ0Q7O0FBRURuRCxFQUFBQSxPQUFPLEdBQUc7QUFDUixRQUFJLEtBQUtxRCxpQkFBVCxFQUE0QjtBQUMxQixhQUFPLEtBQUtBLGlCQUFaO0FBQ0QsS0FITyxDQUtSO0FBQ0E7OztBQUNBLFVBQU1DLFVBQVUsR0FBRyx3QkFBVSx1QkFBUyxLQUFLUixJQUFkLENBQVYsQ0FBbkI7QUFFQSxTQUFLTyxpQkFBTCxHQUF5QjFELFdBQVcsQ0FBQ0ssT0FBWixDQUFvQnNELFVBQXBCLEVBQWdDLEtBQUtQLGFBQXJDLEVBQ3RCOUMsSUFEc0IsQ0FDakJzRCxNQUFNLElBQUk7QUFDZDtBQUNBO0FBQ0E7QUFDQSxZQUFNQyxPQUFPLEdBQUdELE1BQU0sQ0FBQ0UsQ0FBUCxDQUFTRCxPQUF6QjtBQUNBLFlBQU10RCxRQUFRLEdBQUdxRCxNQUFNLENBQUNHLEVBQVAsQ0FBVUYsT0FBTyxDQUFDRyxNQUFsQixDQUFqQjs7QUFDQSxVQUFJLENBQUN6RCxRQUFMLEVBQWU7QUFDYixlQUFPLEtBQUttRCxpQkFBWjtBQUNBO0FBQ0Q7O0FBQ0RuRCxNQUFBQSxRQUFRLENBQUMwRCxFQUFULENBQVksT0FBWixFQUFxQixNQUFNO0FBQ3pCLGVBQU8sS0FBS1AsaUJBQVo7QUFDRCxPQUZEO0FBR0FuRCxNQUFBQSxRQUFRLENBQUMwRCxFQUFULENBQVksT0FBWixFQUFxQixNQUFNO0FBQ3pCLGVBQU8sS0FBS1AsaUJBQVo7QUFDRCxPQUZEO0FBR0EsV0FBS0UsTUFBTCxHQUFjQSxNQUFkO0FBQ0EsV0FBS3JELFFBQUwsR0FBZ0JBLFFBQWhCO0FBQ0QsS0FuQnNCLEVBb0J0QjJELEtBcEJzQixDQW9CaEJDLEdBQUcsSUFBSTtBQUNaLGFBQU8sS0FBS1QsaUJBQVo7QUFDQSxhQUFPVSxPQUFPLENBQUNDLE1BQVIsQ0FBZUYsR0FBZixDQUFQO0FBQ0QsS0F2QnNCLENBQXpCO0FBeUJBLFdBQU8sS0FBS1QsaUJBQVo7QUFDRDs7QUFFRFksRUFBQUEsV0FBVyxDQUFJQyxLQUFKLEVBQStDO0FBQ3hELFFBQUlBLEtBQUssSUFBSUEsS0FBSyxDQUFDQyxJQUFOLEtBQWUsRUFBNUIsRUFBZ0M7QUFDOUI7QUFDQSxhQUFPLEtBQUtaLE1BQVo7QUFDQSxhQUFPLEtBQUtyRCxRQUFaO0FBQ0EsYUFBTyxLQUFLbUQsaUJBQVo7O0FBQ0FlLHNCQUFPRixLQUFQLENBQWEsNkJBQWIsRUFBNEM7QUFBRUEsUUFBQUEsS0FBSyxFQUFFQTtBQUFULE9BQTVDO0FBQ0Q7O0FBQ0QsVUFBTUEsS0FBTjtBQUNEOztBQUVERyxFQUFBQSxjQUFjLEdBQUc7QUFDZixRQUFJLENBQUMsS0FBS2QsTUFBVixFQUFrQjtBQUNoQixhQUFPUSxPQUFPLENBQUNPLE9BQVIsRUFBUDtBQUNEOztBQUNELFdBQU8sS0FBS2YsTUFBTCxDQUFZZ0IsS0FBWixDQUFrQixLQUFsQixDQUFQO0FBQ0Q7O0FBRURDLEVBQUFBLG1CQUFtQixDQUFDQyxJQUFELEVBQWU7QUFDaEMsV0FBTyxLQUFLekUsT0FBTCxHQUNKQyxJQURJLENBQ0MsTUFBTSxLQUFLQyxRQUFMLENBQWNHLFVBQWQsQ0FBeUIsS0FBS0ssaUJBQUwsR0FBeUIrRCxJQUFsRCxDQURQLEVBRUp4RSxJQUZJLENBRUN5RSxhQUFhLElBQUksSUFBSUMsd0JBQUosQ0FBb0JELGFBQXBCLENBRmxCLEVBR0piLEtBSEksQ0FHRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBSFQsQ0FBUDtBQUlEOztBQUVEYyxFQUFBQSxpQkFBaUIsR0FBbUM7QUFDbEQsV0FBTyxLQUFLNUUsT0FBTCxHQUNKQyxJQURJLENBQ0MsTUFBTSxLQUFLdUUsbUJBQUwsQ0FBeUIzRSx5QkFBekIsQ0FEUCxFQUVKSSxJQUZJLENBRUNJLFVBQVUsSUFBSSxJQUFJMkIsOEJBQUosQ0FBMEIzQixVQUExQixDQUZmLENBQVA7QUFHRDs7QUFFRHdFLEVBQUFBLFdBQVcsQ0FBQ0osSUFBRCxFQUFlO0FBQ3hCLFdBQU8sS0FBS3pFLE9BQUwsR0FDSkMsSUFESSxDQUNDLE1BQU07QUFDVixhQUFPLEtBQUtDLFFBQUwsQ0FBYzRFLGVBQWQsQ0FBOEI7QUFBRUwsUUFBQUEsSUFBSSxFQUFFLEtBQUsvRCxpQkFBTCxHQUF5QitEO0FBQWpDLE9BQTlCLEVBQXVFTSxPQUF2RSxFQUFQO0FBQ0QsS0FISSxFQUlKOUUsSUFKSSxDQUlDRSxXQUFXLElBQUk7QUFDbkIsYUFBT0EsV0FBVyxDQUFDaUMsTUFBWixHQUFxQixDQUE1QjtBQUNELEtBTkksRUFPSnlCLEtBUEksQ0FPRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBUFQsQ0FBUDtBQVFEOztBQUVEa0IsRUFBQUEsd0JBQXdCLENBQUNoRSxTQUFELEVBQW9CaUUsSUFBcEIsRUFBOEM7QUFDcEUsV0FBTyxLQUFLTCxpQkFBTCxHQUNKM0UsSUFESSxDQUNDaUYsZ0JBQWdCLElBQ3BCQSxnQkFBZ0IsQ0FBQ0MsWUFBakIsQ0FBOEJuRSxTQUE5QixFQUF5QztBQUN2Q29FLE1BQUFBLElBQUksRUFBRTtBQUFFLHVDQUErQkg7QUFBakM7QUFEaUMsS0FBekMsQ0FGRyxFQU1KcEIsS0FOSSxDQU1FQyxHQUFHLElBQUksS0FBS0csV0FBTCxDQUFpQkgsR0FBakIsQ0FOVCxDQUFQO0FBT0Q7O0FBRUR1QixFQUFBQSwwQkFBMEIsQ0FDeEJyRSxTQUR3QixFQUV4QnNFLGdCQUZ3QixFQUd4QkMsZUFBb0IsR0FBRyxFQUhDLEVBSXhCMUUsTUFKd0IsRUFLVDtBQUNmLFFBQUl5RSxnQkFBZ0IsS0FBSzNELFNBQXpCLEVBQW9DO0FBQ2xDLGFBQU9vQyxPQUFPLENBQUNPLE9BQVIsRUFBUDtBQUNEOztBQUNELFFBQUlwQyxNQUFNLENBQUNDLElBQVAsQ0FBWW9ELGVBQVosRUFBNkJuRCxNQUE3QixLQUF3QyxDQUE1QyxFQUErQztBQUM3Q21ELE1BQUFBLGVBQWUsR0FBRztBQUFFQyxRQUFBQSxJQUFJLEVBQUU7QUFBRWxFLFVBQUFBLEdBQUcsRUFBRTtBQUFQO0FBQVIsT0FBbEI7QUFDRDs7QUFDRCxVQUFNbUUsY0FBYyxHQUFHLEVBQXZCO0FBQ0EsVUFBTUMsZUFBZSxHQUFHLEVBQXhCO0FBQ0F4RCxJQUFBQSxNQUFNLENBQUNDLElBQVAsQ0FBWW1ELGdCQUFaLEVBQThCSyxPQUE5QixDQUFzQ2xCLElBQUksSUFBSTtBQUM1QyxZQUFNbUIsS0FBSyxHQUFHTixnQkFBZ0IsQ0FBQ2IsSUFBRCxDQUE5Qjs7QUFDQSxVQUFJYyxlQUFlLENBQUNkLElBQUQsQ0FBZixJQUF5Qm1CLEtBQUssQ0FBQ0MsSUFBTixLQUFlLFFBQTVDLEVBQXNEO0FBQ3BELGNBQU0sSUFBSUMsY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZQyxhQUE1QixFQUE0QyxTQUFRdkIsSUFBSyx5QkFBekQsQ0FBTjtBQUNEOztBQUNELFVBQUksQ0FBQ2MsZUFBZSxDQUFDZCxJQUFELENBQWhCLElBQTBCbUIsS0FBSyxDQUFDQyxJQUFOLEtBQWUsUUFBN0MsRUFBdUQ7QUFDckQsY0FBTSxJQUFJQyxjQUFNQyxLQUFWLENBQ0pELGNBQU1DLEtBQU4sQ0FBWUMsYUFEUixFQUVILFNBQVF2QixJQUFLLGlDQUZWLENBQU47QUFJRDs7QUFDRCxVQUFJbUIsS0FBSyxDQUFDQyxJQUFOLEtBQWUsUUFBbkIsRUFBNkI7QUFDM0IsY0FBTUksT0FBTyxHQUFHLEtBQUtDLFNBQUwsQ0FBZWxGLFNBQWYsRUFBMEJ5RCxJQUExQixDQUFoQjtBQUNBZ0IsUUFBQUEsY0FBYyxDQUFDVSxJQUFmLENBQW9CRixPQUFwQjtBQUNBLGVBQU9WLGVBQWUsQ0FBQ2QsSUFBRCxDQUF0QjtBQUNELE9BSkQsTUFJTztBQUNMdkMsUUFBQUEsTUFBTSxDQUFDQyxJQUFQLENBQVl5RCxLQUFaLEVBQW1CRCxPQUFuQixDQUEyQlMsR0FBRyxJQUFJO0FBQ2hDLGNBQ0UsQ0FBQ2xFLE1BQU0sQ0FBQ21FLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUNDMUYsTUFERCxFQUVDdUYsR0FBRyxDQUFDM0YsT0FBSixDQUFZLEtBQVosTUFBdUIsQ0FBdkIsR0FBMkIyRixHQUFHLENBQUNJLE9BQUosQ0FBWSxLQUFaLEVBQW1CLEVBQW5CLENBQTNCLEdBQW9ESixHQUZyRCxDQURILEVBS0U7QUFDQSxrQkFBTSxJQUFJTixjQUFNQyxLQUFWLENBQ0pELGNBQU1DLEtBQU4sQ0FBWUMsYUFEUixFQUVILFNBQVFJLEdBQUksb0NBRlQsQ0FBTjtBQUlEO0FBQ0YsU0FaRDtBQWFBYixRQUFBQSxlQUFlLENBQUNkLElBQUQsQ0FBZixHQUF3Qm1CLEtBQXhCO0FBQ0FGLFFBQUFBLGVBQWUsQ0FBQ1MsSUFBaEIsQ0FBcUI7QUFDbkJDLFVBQUFBLEdBQUcsRUFBRVIsS0FEYztBQUVuQm5CLFVBQUFBO0FBRm1CLFNBQXJCO0FBSUQ7QUFDRixLQW5DRDtBQW9DQSxRQUFJZ0MsYUFBYSxHQUFHMUMsT0FBTyxDQUFDTyxPQUFSLEVBQXBCOztBQUNBLFFBQUlvQixlQUFlLENBQUN0RCxNQUFoQixHQUF5QixDQUE3QixFQUFnQztBQUM5QnFFLE1BQUFBLGFBQWEsR0FBRyxLQUFLQyxhQUFMLENBQW1CMUYsU0FBbkIsRUFBOEIwRSxlQUE5QixDQUFoQjtBQUNEOztBQUNELFdBQU8zQixPQUFPLENBQUM0QyxHQUFSLENBQVlsQixjQUFaLEVBQ0p4RixJQURJLENBQ0MsTUFBTXdHLGFBRFAsRUFFSnhHLElBRkksQ0FFQyxNQUFNLEtBQUsyRSxpQkFBTCxFQUZQLEVBR0ozRSxJQUhJLENBR0NpRixnQkFBZ0IsSUFDcEJBLGdCQUFnQixDQUFDQyxZQUFqQixDQUE4Qm5FLFNBQTlCLEVBQXlDO0FBQ3ZDb0UsTUFBQUEsSUFBSSxFQUFFO0FBQUUsNkJBQXFCRztBQUF2QjtBQURpQyxLQUF6QyxDQUpHLEVBUUoxQixLQVJJLENBUUVDLEdBQUcsSUFBSSxLQUFLRyxXQUFMLENBQWlCSCxHQUFqQixDQVJULENBQVA7QUFTRDs7QUFFRDhDLEVBQUFBLG1CQUFtQixDQUFDNUYsU0FBRCxFQUFvQjtBQUNyQyxXQUFPLEtBQUs2RixVQUFMLENBQWdCN0YsU0FBaEIsRUFDSmYsSUFESSxDQUNDbUIsT0FBTyxJQUFJO0FBQ2ZBLE1BQUFBLE9BQU8sR0FBR0EsT0FBTyxDQUFDMEYsTUFBUixDQUFlLENBQUNDLEdBQUQsRUFBTUMsS0FBTixLQUFnQjtBQUN2QyxZQUFJQSxLQUFLLENBQUNaLEdBQU4sQ0FBVWEsSUFBZCxFQUFvQjtBQUNsQixpQkFBT0QsS0FBSyxDQUFDWixHQUFOLENBQVVhLElBQWpCO0FBQ0EsaUJBQU9ELEtBQUssQ0FBQ1osR0FBTixDQUFVYyxLQUFqQjs7QUFDQSxlQUFLLE1BQU10QixLQUFYLElBQW9Cb0IsS0FBSyxDQUFDRyxPQUExQixFQUFtQztBQUNqQ0gsWUFBQUEsS0FBSyxDQUFDWixHQUFOLENBQVVSLEtBQVYsSUFBbUIsTUFBbkI7QUFDRDtBQUNGOztBQUNEbUIsUUFBQUEsR0FBRyxDQUFDQyxLQUFLLENBQUN2QyxJQUFQLENBQUgsR0FBa0J1QyxLQUFLLENBQUNaLEdBQXhCO0FBQ0EsZUFBT1csR0FBUDtBQUNELE9BVlMsRUFVUCxFQVZPLENBQVY7QUFXQSxhQUFPLEtBQUtuQyxpQkFBTCxHQUF5QjNFLElBQXpCLENBQThCaUYsZ0JBQWdCLElBQ25EQSxnQkFBZ0IsQ0FBQ0MsWUFBakIsQ0FBOEJuRSxTQUE5QixFQUF5QztBQUN2Q29FLFFBQUFBLElBQUksRUFBRTtBQUFFLCtCQUFxQmhFO0FBQXZCO0FBRGlDLE9BQXpDLENBREssQ0FBUDtBQUtELEtBbEJJLEVBbUJKeUMsS0FuQkksQ0FtQkVDLEdBQUcsSUFBSSxLQUFLRyxXQUFMLENBQWlCSCxHQUFqQixDQW5CVCxFQW9CSkQsS0FwQkksQ0FvQkUsTUFBTTtBQUNYO0FBQ0EsYUFBT0UsT0FBTyxDQUFDTyxPQUFSLEVBQVA7QUFDRCxLQXZCSSxDQUFQO0FBd0JEOztBQUVEOEMsRUFBQUEsV0FBVyxDQUFDcEcsU0FBRCxFQUFvQkosTUFBcEIsRUFBdUQ7QUFDaEVBLElBQUFBLE1BQU0sR0FBR0QsK0JBQStCLENBQUNDLE1BQUQsQ0FBeEM7QUFDQSxVQUFNUyxXQUFXLEdBQUdILHVDQUF1QyxDQUN6RE4sTUFBTSxDQUFDQyxNQURrRCxFQUV6REcsU0FGeUQsRUFHekRKLE1BQU0sQ0FBQ08scUJBSGtELEVBSXpEUCxNQUFNLENBQUNRLE9BSmtELENBQTNEO0FBTUFDLElBQUFBLFdBQVcsQ0FBQ0MsR0FBWixHQUFrQk4sU0FBbEI7QUFDQSxXQUFPLEtBQUtxRSwwQkFBTCxDQUFnQ3JFLFNBQWhDLEVBQTJDSixNQUFNLENBQUNRLE9BQWxELEVBQTJELEVBQTNELEVBQStEUixNQUFNLENBQUNDLE1BQXRFLEVBQ0paLElBREksQ0FDQyxNQUFNLEtBQUsyRSxpQkFBTCxFQURQLEVBRUozRSxJQUZJLENBRUNpRixnQkFBZ0IsSUFBSUEsZ0JBQWdCLENBQUNtQyxZQUFqQixDQUE4QmhHLFdBQTlCLENBRnJCLEVBR0p3QyxLQUhJLENBR0VDLEdBQUcsSUFBSSxLQUFLRyxXQUFMLENBQWlCSCxHQUFqQixDQUhULENBQVA7QUFJRDs7QUFFRHdELEVBQUFBLG1CQUFtQixDQUFDdEcsU0FBRCxFQUFvQlksU0FBcEIsRUFBdUNDLElBQXZDLEVBQWlFO0FBQ2xGLFdBQU8sS0FBSytDLGlCQUFMLEdBQ0ozRSxJQURJLENBQ0NpRixnQkFBZ0IsSUFBSUEsZ0JBQWdCLENBQUNvQyxtQkFBakIsQ0FBcUN0RyxTQUFyQyxFQUFnRFksU0FBaEQsRUFBMkRDLElBQTNELENBRHJCLEVBRUo1QixJQUZJLENBRUMsTUFBTSxLQUFLc0gscUJBQUwsQ0FBMkJ2RyxTQUEzQixFQUFzQ1ksU0FBdEMsRUFBaURDLElBQWpELENBRlAsRUFHSmdDLEtBSEksQ0FHRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBSFQsQ0FBUDtBQUlELEdBbE93RCxDQW9PekQ7QUFDQTs7O0FBQ0EwRCxFQUFBQSxXQUFXLENBQUN4RyxTQUFELEVBQW9CO0FBQzdCLFdBQ0UsS0FBS3dELG1CQUFMLENBQXlCeEQsU0FBekIsRUFDR2YsSUFESCxDQUNRSSxVQUFVLElBQUlBLFVBQVUsQ0FBQ29ILElBQVgsRUFEdEIsRUFFRzVELEtBRkgsQ0FFU0ssS0FBSyxJQUFJO0FBQ2Q7QUFDQSxVQUFJQSxLQUFLLENBQUN3RCxPQUFOLElBQWlCLGNBQXJCLEVBQXFDO0FBQ25DO0FBQ0Q7O0FBQ0QsWUFBTXhELEtBQU47QUFDRCxLQVJILEVBU0U7QUFURixLQVVHakUsSUFWSCxDQVVRLE1BQU0sS0FBSzJFLGlCQUFMLEVBVmQsRUFXRzNFLElBWEgsQ0FXUWlGLGdCQUFnQixJQUFJQSxnQkFBZ0IsQ0FBQ3lDLG1CQUFqQixDQUFxQzNHLFNBQXJDLENBWDVCLEVBWUc2QyxLQVpILENBWVNDLEdBQUcsSUFBSSxLQUFLRyxXQUFMLENBQWlCSCxHQUFqQixDQVpoQixDQURGO0FBZUQ7O0FBRUQ4RCxFQUFBQSxnQkFBZ0IsQ0FBQ0MsSUFBRCxFQUFnQjtBQUM5QixXQUFPL0gsNEJBQTRCLENBQUMsSUFBRCxDQUE1QixDQUFtQ0csSUFBbkMsQ0FBd0NFLFdBQVcsSUFDeEQ0RCxPQUFPLENBQUM0QyxHQUFSLENBQ0V4RyxXQUFXLENBQUMySCxHQUFaLENBQWdCekgsVUFBVSxJQUFLd0gsSUFBSSxHQUFHeEgsVUFBVSxDQUFDMEgsVUFBWCxDQUFzQixFQUF0QixDQUFILEdBQStCMUgsVUFBVSxDQUFDb0gsSUFBWCxFQUFsRSxDQURGLENBREssQ0FBUDtBQUtELEdBOVB3RCxDQWdRekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFFQTs7O0FBQ0FPLEVBQUFBLFlBQVksQ0FBQ2hILFNBQUQsRUFBb0JKLE1BQXBCLEVBQXdDcUgsVUFBeEMsRUFBOEQ7QUFDeEUsVUFBTUMsZ0JBQWdCLEdBQUdELFVBQVUsQ0FBQ0gsR0FBWCxDQUFlbEcsU0FBUyxJQUFJO0FBQ25ELFVBQUloQixNQUFNLENBQUNDLE1BQVAsQ0FBY2UsU0FBZCxFQUF5QkMsSUFBekIsS0FBa0MsU0FBdEMsRUFBaUQ7QUFDL0MsZUFBUSxNQUFLRCxTQUFVLEVBQXZCO0FBQ0QsT0FGRCxNQUVPO0FBQ0wsZUFBT0EsU0FBUDtBQUNEO0FBQ0YsS0FOd0IsQ0FBekI7QUFPQSxVQUFNdUcsZ0JBQWdCLEdBQUc7QUFBRUMsTUFBQUEsTUFBTSxFQUFFO0FBQVYsS0FBekI7QUFDQUYsSUFBQUEsZ0JBQWdCLENBQUN2QyxPQUFqQixDQUF5QmxCLElBQUksSUFBSTtBQUMvQjBELE1BQUFBLGdCQUFnQixDQUFDLFFBQUQsQ0FBaEIsQ0FBMkIxRCxJQUEzQixJQUFtQyxJQUFuQztBQUNELEtBRkQ7QUFJQSxVQUFNNEQsZ0JBQWdCLEdBQUc7QUFBRUMsTUFBQUEsR0FBRyxFQUFFO0FBQVAsS0FBekI7QUFDQUosSUFBQUEsZ0JBQWdCLENBQUN2QyxPQUFqQixDQUF5QmxCLElBQUksSUFBSTtBQUMvQjRELE1BQUFBLGdCQUFnQixDQUFDLEtBQUQsQ0FBaEIsQ0FBd0JsQyxJQUF4QixDQUE2QjtBQUFFLFNBQUMxQixJQUFELEdBQVE7QUFBRThELFVBQUFBLE9BQU8sRUFBRTtBQUFYO0FBQVYsT0FBN0I7QUFDRCxLQUZEO0FBSUEsVUFBTUMsWUFBWSxHQUFHO0FBQUVKLE1BQUFBLE1BQU0sRUFBRTtBQUFWLEtBQXJCO0FBQ0FILElBQUFBLFVBQVUsQ0FBQ3RDLE9BQVgsQ0FBbUJsQixJQUFJLElBQUk7QUFDekIrRCxNQUFBQSxZQUFZLENBQUMsUUFBRCxDQUFaLENBQXVCL0QsSUFBdkIsSUFBK0IsSUFBL0I7QUFDQStELE1BQUFBLFlBQVksQ0FBQyxRQUFELENBQVosQ0FBd0IsNEJBQTJCL0QsSUFBSyxFQUF4RCxJQUE2RCxJQUE3RDtBQUNELEtBSEQ7QUFLQSxXQUFPLEtBQUtELG1CQUFMLENBQXlCeEQsU0FBekIsRUFDSmYsSUFESSxDQUNDSSxVQUFVLElBQUlBLFVBQVUsQ0FBQ29JLFVBQVgsQ0FBc0JKLGdCQUF0QixFQUF3Q0YsZ0JBQXhDLENBRGYsRUFFSmxJLElBRkksQ0FFQyxNQUFNLEtBQUsyRSxpQkFBTCxFQUZQLEVBR0ozRSxJQUhJLENBR0NpRixnQkFBZ0IsSUFBSUEsZ0JBQWdCLENBQUNDLFlBQWpCLENBQThCbkUsU0FBOUIsRUFBeUN3SCxZQUF6QyxDQUhyQixFQUlKM0UsS0FKSSxDQUlFQyxHQUFHLElBQUksS0FBS0csV0FBTCxDQUFpQkgsR0FBakIsQ0FKVCxDQUFQO0FBS0QsR0FqVHdELENBbVR6RDtBQUNBO0FBQ0E7OztBQUNBNEUsRUFBQUEsYUFBYSxHQUE0QjtBQUN2QyxXQUFPLEtBQUs5RCxpQkFBTCxHQUNKM0UsSUFESSxDQUNDMEksaUJBQWlCLElBQUlBLGlCQUFpQixDQUFDQywyQkFBbEIsRUFEdEIsRUFFSi9FLEtBRkksQ0FFRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBRlQsQ0FBUDtBQUdELEdBMVR3RCxDQTRUekQ7QUFDQTtBQUNBOzs7QUFDQStFLEVBQUFBLFFBQVEsQ0FBQzdILFNBQUQsRUFBMkM7QUFDakQsV0FBTyxLQUFLNEQsaUJBQUwsR0FDSjNFLElBREksQ0FDQzBJLGlCQUFpQixJQUFJQSxpQkFBaUIsQ0FBQ0csMEJBQWxCLENBQTZDOUgsU0FBN0MsQ0FEdEIsRUFFSjZDLEtBRkksQ0FFRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBRlQsQ0FBUDtBQUdELEdBblV3RCxDQXFVekQ7QUFDQTtBQUNBOzs7QUFDQWlGLEVBQUFBLFlBQVksQ0FBQy9ILFNBQUQsRUFBb0JKLE1BQXBCLEVBQXdDb0ksTUFBeEMsRUFBcURDLG9CQUFyRCxFQUFpRjtBQUMzRnJJLElBQUFBLE1BQU0sR0FBR0QsK0JBQStCLENBQUNDLE1BQUQsQ0FBeEM7QUFDQSxVQUFNUyxXQUFXLEdBQUcsdURBQWtDTCxTQUFsQyxFQUE2Q2dJLE1BQTdDLEVBQXFEcEksTUFBckQsQ0FBcEI7QUFDQSxXQUFPLEtBQUs0RCxtQkFBTCxDQUF5QnhELFNBQXpCLEVBQ0pmLElBREksQ0FDQ0ksVUFBVSxJQUFJQSxVQUFVLENBQUM2SSxTQUFYLENBQXFCN0gsV0FBckIsRUFBa0M0SCxvQkFBbEMsQ0FEZixFQUVKcEYsS0FGSSxDQUVFSyxLQUFLLElBQUk7QUFDZCxVQUFJQSxLQUFLLENBQUNDLElBQU4sS0FBZSxLQUFuQixFQUEwQjtBQUN4QjtBQUNBLGNBQU1MLEdBQUcsR0FBRyxJQUFJZ0MsY0FBTUMsS0FBVixDQUNWRCxjQUFNQyxLQUFOLENBQVlvRCxlQURGLEVBRVYsK0RBRlUsQ0FBWjtBQUlBckYsUUFBQUEsR0FBRyxDQUFDc0YsZUFBSixHQUFzQmxGLEtBQXRCOztBQUNBLFlBQUlBLEtBQUssQ0FBQ3dELE9BQVYsRUFBbUI7QUFDakIsZ0JBQU0yQixPQUFPLEdBQUduRixLQUFLLENBQUN3RCxPQUFOLENBQWNuSCxLQUFkLENBQW9CLDZDQUFwQixDQUFoQjs7QUFDQSxjQUFJOEksT0FBTyxJQUFJQyxLQUFLLENBQUNDLE9BQU4sQ0FBY0YsT0FBZCxDQUFmLEVBQXVDO0FBQ3JDdkYsWUFBQUEsR0FBRyxDQUFDMEYsUUFBSixHQUFlO0FBQUVDLGNBQUFBLGdCQUFnQixFQUFFSixPQUFPLENBQUMsQ0FBRDtBQUEzQixhQUFmO0FBQ0Q7QUFDRjs7QUFDRCxjQUFNdkYsR0FBTjtBQUNEOztBQUNELFlBQU1JLEtBQU47QUFDRCxLQW5CSSxFQW9CSkwsS0FwQkksQ0FvQkVDLEdBQUcsSUFBSSxLQUFLRyxXQUFMLENBQWlCSCxHQUFqQixDQXBCVCxDQUFQO0FBcUJELEdBaFd3RCxDQWtXekQ7QUFDQTtBQUNBOzs7QUFDQTRGLEVBQUFBLG9CQUFvQixDQUNsQjFJLFNBRGtCLEVBRWxCSixNQUZrQixFQUdsQitJLEtBSGtCLEVBSWxCVixvQkFKa0IsRUFLbEI7QUFDQXJJLElBQUFBLE1BQU0sR0FBR0QsK0JBQStCLENBQUNDLE1BQUQsQ0FBeEM7QUFDQSxXQUFPLEtBQUs0RCxtQkFBTCxDQUF5QnhELFNBQXpCLEVBQ0pmLElBREksQ0FDQ0ksVUFBVSxJQUFJO0FBQ2xCLFlBQU11SixVQUFVLEdBQUcsb0NBQWU1SSxTQUFmLEVBQTBCMkksS0FBMUIsRUFBaUMvSSxNQUFqQyxDQUFuQjtBQUNBLGFBQU9QLFVBQVUsQ0FBQzBILFVBQVgsQ0FBc0I2QixVQUF0QixFQUFrQ1gsb0JBQWxDLENBQVA7QUFDRCxLQUpJLEVBS0pwRixLQUxJLENBS0VDLEdBQUcsSUFBSSxLQUFLRyxXQUFMLENBQWlCSCxHQUFqQixDQUxULEVBTUo3RCxJQU5JLENBT0gsQ0FBQztBQUFFNEosTUFBQUE7QUFBRixLQUFELEtBQWdCO0FBQ2QsVUFBSUEsTUFBTSxDQUFDQyxDQUFQLEtBQWEsQ0FBakIsRUFBb0I7QUFDbEIsY0FBTSxJQUFJaEUsY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZZ0UsZ0JBQTVCLEVBQThDLG1CQUE5QyxDQUFOO0FBQ0Q7O0FBQ0QsYUFBT2hHLE9BQU8sQ0FBQ08sT0FBUixFQUFQO0FBQ0QsS0FaRSxFQWFILE1BQU07QUFDSixZQUFNLElBQUl3QixjQUFNQyxLQUFWLENBQWdCRCxjQUFNQyxLQUFOLENBQVlpRSxxQkFBNUIsRUFBbUQsd0JBQW5ELENBQU47QUFDRCxLQWZFLENBQVA7QUFpQkQsR0E3WHdELENBK1h6RDs7O0FBQ0FDLEVBQUFBLG9CQUFvQixDQUNsQmpKLFNBRGtCLEVBRWxCSixNQUZrQixFQUdsQitJLEtBSGtCLEVBSWxCTyxNQUprQixFQUtsQmpCLG9CQUxrQixFQU1sQjtBQUNBckksSUFBQUEsTUFBTSxHQUFHRCwrQkFBK0IsQ0FBQ0MsTUFBRCxDQUF4QztBQUNBLFVBQU11SixXQUFXLEdBQUcscUNBQWdCbkosU0FBaEIsRUFBMkJrSixNQUEzQixFQUFtQ3RKLE1BQW5DLENBQXBCO0FBQ0EsVUFBTWdKLFVBQVUsR0FBRyxvQ0FBZTVJLFNBQWYsRUFBMEIySSxLQUExQixFQUFpQy9JLE1BQWpDLENBQW5CO0FBQ0EsV0FBTyxLQUFLNEQsbUJBQUwsQ0FBeUJ4RCxTQUF6QixFQUNKZixJQURJLENBQ0NJLFVBQVUsSUFBSUEsVUFBVSxDQUFDb0ksVUFBWCxDQUFzQm1CLFVBQXRCLEVBQWtDTyxXQUFsQyxFQUErQ2xCLG9CQUEvQyxDQURmLEVBRUpwRixLQUZJLENBRUVDLEdBQUcsSUFBSSxLQUFLRyxXQUFMLENBQWlCSCxHQUFqQixDQUZULENBQVA7QUFHRCxHQTdZd0QsQ0ErWXpEO0FBQ0E7OztBQUNBc0csRUFBQUEsZ0JBQWdCLENBQ2RwSixTQURjLEVBRWRKLE1BRmMsRUFHZCtJLEtBSGMsRUFJZE8sTUFKYyxFQUtkakIsb0JBTGMsRUFNZDtBQUNBckksSUFBQUEsTUFBTSxHQUFHRCwrQkFBK0IsQ0FBQ0MsTUFBRCxDQUF4QztBQUNBLFVBQU11SixXQUFXLEdBQUcscUNBQWdCbkosU0FBaEIsRUFBMkJrSixNQUEzQixFQUFtQ3RKLE1BQW5DLENBQXBCO0FBQ0EsVUFBTWdKLFVBQVUsR0FBRyxvQ0FBZTVJLFNBQWYsRUFBMEIySSxLQUExQixFQUFpQy9JLE1BQWpDLENBQW5CO0FBQ0EsV0FBTyxLQUFLNEQsbUJBQUwsQ0FBeUJ4RCxTQUF6QixFQUNKZixJQURJLENBQ0NJLFVBQVUsSUFDZEEsVUFBVSxDQUFDZ0ssZ0JBQVgsQ0FBNEJELGdCQUE1QixDQUE2Q1IsVUFBN0MsRUFBeURPLFdBQXpELEVBQXNFO0FBQ3BFRyxNQUFBQSxjQUFjLEVBQUUsS0FEb0Q7QUFFcEVDLE1BQUFBLE9BQU8sRUFBRXRCLG9CQUFvQixJQUFJdEg7QUFGbUMsS0FBdEUsQ0FGRyxFQU9KMUIsSUFQSSxDQU9DNEosTUFBTSxJQUFJLDhDQUF5QjdJLFNBQXpCLEVBQW9DNkksTUFBTSxDQUFDVyxLQUEzQyxFQUFrRDVKLE1BQWxELENBUFgsRUFRSmlELEtBUkksQ0FRRUssS0FBSyxJQUFJO0FBQ2QsVUFBSUEsS0FBSyxDQUFDQyxJQUFOLEtBQWUsS0FBbkIsRUFBMEI7QUFDeEIsY0FBTSxJQUFJMkIsY0FBTUMsS0FBVixDQUNKRCxjQUFNQyxLQUFOLENBQVlvRCxlQURSLEVBRUosK0RBRkksQ0FBTjtBQUlEOztBQUNELFlBQU1qRixLQUFOO0FBQ0QsS0FoQkksRUFpQkpMLEtBakJJLENBaUJFQyxHQUFHLElBQUksS0FBS0csV0FBTCxDQUFpQkgsR0FBakIsQ0FqQlQsQ0FBUDtBQWtCRCxHQTdhd0QsQ0ErYXpEOzs7QUFDQTJHLEVBQUFBLGVBQWUsQ0FDYnpKLFNBRGEsRUFFYkosTUFGYSxFQUdiK0ksS0FIYSxFQUliTyxNQUphLEVBS2JqQixvQkFMYSxFQU1iO0FBQ0FySSxJQUFBQSxNQUFNLEdBQUdELCtCQUErQixDQUFDQyxNQUFELENBQXhDO0FBQ0EsVUFBTXVKLFdBQVcsR0FBRyxxQ0FBZ0JuSixTQUFoQixFQUEyQmtKLE1BQTNCLEVBQW1DdEosTUFBbkMsQ0FBcEI7QUFDQSxVQUFNZ0osVUFBVSxHQUFHLG9DQUFlNUksU0FBZixFQUEwQjJJLEtBQTFCLEVBQWlDL0ksTUFBakMsQ0FBbkI7QUFDQSxXQUFPLEtBQUs0RCxtQkFBTCxDQUF5QnhELFNBQXpCLEVBQ0pmLElBREksQ0FDQ0ksVUFBVSxJQUFJQSxVQUFVLENBQUNxSyxTQUFYLENBQXFCZCxVQUFyQixFQUFpQ08sV0FBakMsRUFBOENsQixvQkFBOUMsQ0FEZixFQUVKcEYsS0FGSSxDQUVFQyxHQUFHLElBQUksS0FBS0csV0FBTCxDQUFpQkgsR0FBakIsQ0FGVCxDQUFQO0FBR0QsR0E3YndELENBK2J6RDs7O0FBQ0E2RyxFQUFBQSxJQUFJLENBQ0YzSixTQURFLEVBRUZKLE1BRkUsRUFHRitJLEtBSEUsRUFJRjtBQUFFaUIsSUFBQUEsSUFBRjtBQUFRQyxJQUFBQSxLQUFSO0FBQWVDLElBQUFBLElBQWY7QUFBcUIzSSxJQUFBQSxJQUFyQjtBQUEyQjRJLElBQUFBLGNBQTNCO0FBQTJDQyxJQUFBQSxJQUEzQztBQUFpREMsSUFBQUEsZUFBakQ7QUFBa0VDLElBQUFBO0FBQWxFLEdBSkUsRUFLWTtBQUNkdEssSUFBQUEsTUFBTSxHQUFHRCwrQkFBK0IsQ0FBQ0MsTUFBRCxDQUF4QztBQUNBLFVBQU1nSixVQUFVLEdBQUcsb0NBQWU1SSxTQUFmLEVBQTBCMkksS0FBMUIsRUFBaUMvSSxNQUFqQyxDQUFuQjs7QUFDQSxVQUFNdUssU0FBUyxHQUFHQyxnQkFBRUMsT0FBRixDQUFVUCxJQUFWLEVBQWdCLENBQUNOLEtBQUQsRUFBUTVJLFNBQVIsS0FDaEMsa0NBQWFaLFNBQWIsRUFBd0JZLFNBQXhCLEVBQW1DaEIsTUFBbkMsQ0FEZ0IsQ0FBbEI7O0FBR0EsVUFBTTBLLFNBQVMsR0FBR0YsZ0JBQUV0RSxNQUFGLENBQ2hCM0UsSUFEZ0IsRUFFaEIsQ0FBQ29KLElBQUQsRUFBT25GLEdBQVAsS0FBZTtBQUNiLFVBQUlBLEdBQUcsS0FBSyxLQUFaLEVBQW1CO0FBQ2pCbUYsUUFBQUEsSUFBSSxDQUFDLFFBQUQsQ0FBSixHQUFpQixDQUFqQjtBQUNBQSxRQUFBQSxJQUFJLENBQUMsUUFBRCxDQUFKLEdBQWlCLENBQWpCO0FBQ0QsT0FIRCxNQUdPO0FBQ0xBLFFBQUFBLElBQUksQ0FBQyxrQ0FBYXZLLFNBQWIsRUFBd0JvRixHQUF4QixFQUE2QnhGLE1BQTdCLENBQUQsQ0FBSixHQUE2QyxDQUE3QztBQUNEOztBQUNELGFBQU8ySyxJQUFQO0FBQ0QsS0FWZSxFQVdoQixFQVhnQixDQUFsQixDQU5jLENBb0JkO0FBQ0E7QUFDQTs7O0FBQ0EsUUFBSXBKLElBQUksSUFBSSxDQUFDbUosU0FBUyxDQUFDaEssR0FBdkIsRUFBNEI7QUFDMUJnSyxNQUFBQSxTQUFTLENBQUNoSyxHQUFWLEdBQWdCLENBQWhCO0FBQ0Q7O0FBRUR5SixJQUFBQSxjQUFjLEdBQUcsS0FBS1Msb0JBQUwsQ0FBMEJULGNBQTFCLENBQWpCO0FBQ0EsV0FBTyxLQUFLVSx5QkFBTCxDQUErQnpLLFNBQS9CLEVBQTBDMkksS0FBMUMsRUFBaUQvSSxNQUFqRCxFQUNKWCxJQURJLENBQ0MsTUFBTSxLQUFLdUUsbUJBQUwsQ0FBeUJ4RCxTQUF6QixDQURQLEVBRUpmLElBRkksQ0FFQ0ksVUFBVSxJQUNkQSxVQUFVLENBQUNzSyxJQUFYLENBQWdCZixVQUFoQixFQUE0QjtBQUMxQmdCLE1BQUFBLElBRDBCO0FBRTFCQyxNQUFBQSxLQUYwQjtBQUcxQkMsTUFBQUEsSUFBSSxFQUFFSyxTQUhvQjtBQUkxQmhKLE1BQUFBLElBQUksRUFBRW1KLFNBSm9CO0FBSzFCbkksTUFBQUEsU0FBUyxFQUFFLEtBQUtELFVBTFU7QUFNMUI2SCxNQUFBQSxjQU4wQjtBQU8xQkMsTUFBQUEsSUFQMEI7QUFRMUJDLE1BQUFBLGVBUjBCO0FBUzFCQyxNQUFBQTtBQVQwQixLQUE1QixDQUhHLEVBZUpqTCxJQWZJLENBZUN5TCxPQUFPLElBQUk7QUFDZixVQUFJUixPQUFKLEVBQWE7QUFDWCxlQUFPUSxPQUFQO0FBQ0Q7O0FBQ0QsYUFBT0EsT0FBTyxDQUFDNUQsR0FBUixDQUFZa0IsTUFBTSxJQUFJLDhDQUF5QmhJLFNBQXpCLEVBQW9DZ0ksTUFBcEMsRUFBNENwSSxNQUE1QyxDQUF0QixDQUFQO0FBQ0QsS0FwQkksRUFxQkppRCxLQXJCSSxDQXFCRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBckJULENBQVA7QUFzQkQ7O0FBRUQ2SCxFQUFBQSxXQUFXLENBQ1QzSyxTQURTLEVBRVRKLE1BRlMsRUFHVHFILFVBSFMsRUFJVDJELFNBSlMsRUFLVFgsZUFBd0IsR0FBRyxLQUxsQixFQU1UekgsT0FBZ0IsR0FBRyxFQU5WLEVBT0s7QUFDZDVDLElBQUFBLE1BQU0sR0FBR0QsK0JBQStCLENBQUNDLE1BQUQsQ0FBeEM7QUFDQSxVQUFNaUwsb0JBQW9CLEdBQUcsRUFBN0I7QUFDQSxVQUFNQyxlQUFlLEdBQUc3RCxVQUFVLENBQUNILEdBQVgsQ0FBZWxHLFNBQVMsSUFBSSxrQ0FBYVosU0FBYixFQUF3QlksU0FBeEIsRUFBbUNoQixNQUFuQyxDQUE1QixDQUF4QjtBQUNBa0wsSUFBQUEsZUFBZSxDQUFDbkcsT0FBaEIsQ0FBd0IvRCxTQUFTLElBQUk7QUFDbkNpSyxNQUFBQSxvQkFBb0IsQ0FBQ2pLLFNBQUQsQ0FBcEIsR0FBa0M0QixPQUFPLENBQUN1SSxTQUFSLEtBQXNCcEssU0FBdEIsR0FBa0M2QixPQUFPLENBQUN1SSxTQUExQyxHQUFzRCxDQUF4RjtBQUNELEtBRkQ7QUFJQSxVQUFNQyxjQUFzQixHQUFHO0FBQUVDLE1BQUFBLFVBQVUsRUFBRSxJQUFkO0FBQW9CQyxNQUFBQSxNQUFNLEVBQUU7QUFBNUIsS0FBL0I7QUFDQSxVQUFNQyxnQkFBd0IsR0FBR1AsU0FBUyxHQUFHO0FBQUVuSCxNQUFBQSxJQUFJLEVBQUVtSDtBQUFSLEtBQUgsR0FBeUIsRUFBbkU7QUFDQSxVQUFNUSxVQUFrQixHQUFHNUksT0FBTyxDQUFDNkksR0FBUixLQUFnQjFLLFNBQWhCLEdBQTRCO0FBQUUySyxNQUFBQSxrQkFBa0IsRUFBRTlJLE9BQU8sQ0FBQzZJO0FBQTlCLEtBQTVCLEdBQWtFLEVBQTdGO0FBQ0EsVUFBTUUsc0JBQThCLEdBQUd0QixlQUFlLEdBQ2xEO0FBQUV1QixNQUFBQSxTQUFTLEVBQUU3SCx5QkFBZ0I4SCx3QkFBaEI7QUFBYixLQURrRCxHQUVsRCxFQUZKOztBQUdBLFVBQU1DLFlBQW9CLCtEQUNyQlYsY0FEcUIsR0FFckJPLHNCQUZxQixHQUdyQkosZ0JBSHFCLEdBSXJCQyxVQUpxQixDQUExQjs7QUFPQSxXQUFPLEtBQUs1SCxtQkFBTCxDQUF5QnhELFNBQXpCLEVBQ0pmLElBREksQ0FFSEksVUFBVSxJQUNSLElBQUkwRCxPQUFKLENBQVksQ0FBQ08sT0FBRCxFQUFVTixNQUFWLEtBQ1YzRCxVQUFVLENBQUNnSyxnQkFBWCxDQUE0QnNDLFdBQTVCLENBQXdDZCxvQkFBeEMsRUFBOERhLFlBQTlELEVBQTRFeEksS0FBSyxJQUMvRUEsS0FBSyxHQUFHRixNQUFNLENBQUNFLEtBQUQsQ0FBVCxHQUFtQkksT0FBTyxFQURqQyxDQURGLENBSEMsRUFTSlQsS0FUSSxDQVNFQyxHQUFHLElBQUksS0FBS0csV0FBTCxDQUFpQkgsR0FBakIsQ0FUVCxDQUFQO0FBVUQsR0EvaEJ3RCxDQWlpQnpEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNBOEksRUFBQUEsZ0JBQWdCLENBQUM1TCxTQUFELEVBQW9CSixNQUFwQixFQUF3Q3FILFVBQXhDLEVBQThEO0FBQzVFckgsSUFBQUEsTUFBTSxHQUFHRCwrQkFBK0IsQ0FBQ0MsTUFBRCxDQUF4QztBQUNBLFVBQU1pTCxvQkFBb0IsR0FBRyxFQUE3QjtBQUNBLFVBQU1DLGVBQWUsR0FBRzdELFVBQVUsQ0FBQ0gsR0FBWCxDQUFlbEcsU0FBUyxJQUFJLGtDQUFhWixTQUFiLEVBQXdCWSxTQUF4QixFQUFtQ2hCLE1BQW5DLENBQTVCLENBQXhCO0FBQ0FrTCxJQUFBQSxlQUFlLENBQUNuRyxPQUFoQixDQUF3Qi9ELFNBQVMsSUFBSTtBQUNuQ2lLLE1BQUFBLG9CQUFvQixDQUFDakssU0FBRCxDQUFwQixHQUFrQyxDQUFsQztBQUNELEtBRkQ7QUFHQSxXQUFPLEtBQUs0QyxtQkFBTCxDQUF5QnhELFNBQXpCLEVBQ0pmLElBREksQ0FDQ0ksVUFBVSxJQUFJQSxVQUFVLENBQUN3TSxvQ0FBWCxDQUFnRGhCLG9CQUFoRCxDQURmLEVBRUpoSSxLQUZJLENBRUVLLEtBQUssSUFBSTtBQUNkLFVBQUlBLEtBQUssQ0FBQ0MsSUFBTixLQUFlLEtBQW5CLEVBQTBCO0FBQ3hCLGNBQU0sSUFBSTJCLGNBQU1DLEtBQVYsQ0FDSkQsY0FBTUMsS0FBTixDQUFZb0QsZUFEUixFQUVKLDJFQUZJLENBQU47QUFJRDs7QUFDRCxZQUFNakYsS0FBTjtBQUNELEtBVkksRUFXSkwsS0FYSSxDQVdFQyxHQUFHLElBQUksS0FBS0csV0FBTCxDQUFpQkgsR0FBakIsQ0FYVCxDQUFQO0FBWUQsR0F6akJ3RCxDQTJqQnpEOzs7QUFDQWdKLEVBQUFBLFFBQVEsQ0FBQzlMLFNBQUQsRUFBb0IySSxLQUFwQixFQUFzQztBQUM1QyxXQUFPLEtBQUtuRixtQkFBTCxDQUF5QnhELFNBQXpCLEVBQ0pmLElBREksQ0FDQ0ksVUFBVSxJQUNkQSxVQUFVLENBQUNzSyxJQUFYLENBQWdCaEIsS0FBaEIsRUFBdUI7QUFDckJ4RyxNQUFBQSxTQUFTLEVBQUUsS0FBS0Q7QUFESyxLQUF2QixDQUZHLEVBTUpXLEtBTkksQ0FNRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBTlQsQ0FBUDtBQU9ELEdBcGtCd0QsQ0Fza0J6RDs7O0FBQ0FpSixFQUFBQSxLQUFLLENBQ0gvTCxTQURHLEVBRUhKLE1BRkcsRUFHSCtJLEtBSEcsRUFJSG9CLGNBSkcsRUFLSEMsSUFMRyxFQU1IO0FBQ0FwSyxJQUFBQSxNQUFNLEdBQUdELCtCQUErQixDQUFDQyxNQUFELENBQXhDO0FBQ0FtSyxJQUFBQSxjQUFjLEdBQUcsS0FBS1Msb0JBQUwsQ0FBMEJULGNBQTFCLENBQWpCO0FBQ0EsV0FBTyxLQUFLdkcsbUJBQUwsQ0FBeUJ4RCxTQUF6QixFQUNKZixJQURJLENBQ0NJLFVBQVUsSUFDZEEsVUFBVSxDQUFDME0sS0FBWCxDQUFpQixvQ0FBZS9MLFNBQWYsRUFBMEIySSxLQUExQixFQUFpQy9JLE1BQWpDLEVBQXlDLElBQXpDLENBQWpCLEVBQWlFO0FBQy9EdUMsTUFBQUEsU0FBUyxFQUFFLEtBQUtELFVBRCtDO0FBRS9ENkgsTUFBQUEsY0FGK0Q7QUFHL0RDLE1BQUFBO0FBSCtELEtBQWpFLENBRkcsRUFRSm5ILEtBUkksQ0FRRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBUlQsQ0FBUDtBQVNEOztBQUVEa0osRUFBQUEsUUFBUSxDQUFDaE0sU0FBRCxFQUFvQkosTUFBcEIsRUFBd0MrSSxLQUF4QyxFQUEwRC9ILFNBQTFELEVBQTZFO0FBQ25GaEIsSUFBQUEsTUFBTSxHQUFHRCwrQkFBK0IsQ0FBQ0MsTUFBRCxDQUF4QztBQUNBLFVBQU1xTSxjQUFjLEdBQUdyTSxNQUFNLENBQUNDLE1BQVAsQ0FBY2UsU0FBZCxLQUE0QmhCLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjZSxTQUFkLEVBQXlCQyxJQUF6QixLQUFrQyxTQUFyRjtBQUNBLFVBQU1xTCxjQUFjLEdBQUcsa0NBQWFsTSxTQUFiLEVBQXdCWSxTQUF4QixFQUFtQ2hCLE1BQW5DLENBQXZCO0FBRUEsV0FBTyxLQUFLNEQsbUJBQUwsQ0FBeUJ4RCxTQUF6QixFQUNKZixJQURJLENBQ0NJLFVBQVUsSUFDZEEsVUFBVSxDQUFDMk0sUUFBWCxDQUFvQkUsY0FBcEIsRUFBb0Msb0NBQWVsTSxTQUFmLEVBQTBCMkksS0FBMUIsRUFBaUMvSSxNQUFqQyxDQUFwQyxDQUZHLEVBSUpYLElBSkksQ0FJQ3lMLE9BQU8sSUFBSTtBQUNmQSxNQUFBQSxPQUFPLEdBQUdBLE9BQU8sQ0FBQ3RMLE1BQVIsQ0FBZTJHLEdBQUcsSUFBSUEsR0FBRyxJQUFJLElBQTdCLENBQVY7QUFDQSxhQUFPMkUsT0FBTyxDQUFDNUQsR0FBUixDQUFZa0IsTUFBTSxJQUFJO0FBQzNCLFlBQUlpRSxjQUFKLEVBQW9CO0FBQ2xCLGlCQUFPLDRDQUF1QnJNLE1BQXZCLEVBQStCZ0IsU0FBL0IsRUFBMENvSCxNQUExQyxDQUFQO0FBQ0Q7O0FBQ0QsZUFBTyw4Q0FBeUJoSSxTQUF6QixFQUFvQ2dJLE1BQXBDLEVBQTRDcEksTUFBNUMsQ0FBUDtBQUNELE9BTE0sQ0FBUDtBQU1ELEtBWkksRUFhSmlELEtBYkksQ0FhRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBYlQsQ0FBUDtBQWNEOztBQUVEcUosRUFBQUEsU0FBUyxDQUNQbk0sU0FETyxFQUVQSixNQUZPLEVBR1B3TSxRQUhPLEVBSVByQyxjQUpPLEVBS1BDLElBTE8sRUFNUEUsT0FOTyxFQU9QO0FBQ0EsUUFBSStCLGNBQWMsR0FBRyxLQUFyQjtBQUNBRyxJQUFBQSxRQUFRLEdBQUdBLFFBQVEsQ0FBQ3RGLEdBQVQsQ0FBYXVGLEtBQUssSUFBSTtBQUMvQixVQUFJQSxLQUFLLENBQUNDLE1BQVYsRUFBa0I7QUFDaEJELFFBQUFBLEtBQUssQ0FBQ0MsTUFBTixHQUFlLEtBQUtDLHdCQUFMLENBQThCM00sTUFBOUIsRUFBc0N5TSxLQUFLLENBQUNDLE1BQTVDLENBQWY7O0FBQ0EsWUFDRUQsS0FBSyxDQUFDQyxNQUFOLENBQWFoTSxHQUFiLElBQ0EsT0FBTytMLEtBQUssQ0FBQ0MsTUFBTixDQUFhaE0sR0FBcEIsS0FBNEIsUUFENUIsSUFFQStMLEtBQUssQ0FBQ0MsTUFBTixDQUFhaE0sR0FBYixDQUFpQmIsT0FBakIsQ0FBeUIsTUFBekIsS0FBb0MsQ0FIdEMsRUFJRTtBQUNBd00sVUFBQUEsY0FBYyxHQUFHLElBQWpCO0FBQ0Q7QUFDRjs7QUFDRCxVQUFJSSxLQUFLLENBQUNHLE1BQVYsRUFBa0I7QUFDaEJILFFBQUFBLEtBQUssQ0FBQ0csTUFBTixHQUFlLEtBQUtDLG1CQUFMLENBQXlCN00sTUFBekIsRUFBaUN5TSxLQUFLLENBQUNHLE1BQXZDLENBQWY7QUFDRDs7QUFDRCxVQUFJSCxLQUFLLENBQUNLLFFBQVYsRUFBb0I7QUFDbEJMLFFBQUFBLEtBQUssQ0FBQ0ssUUFBTixHQUFpQixLQUFLQywwQkFBTCxDQUFnQy9NLE1BQWhDLEVBQXdDeU0sS0FBSyxDQUFDSyxRQUE5QyxDQUFqQjtBQUNEOztBQUNELFVBQUlMLEtBQUssQ0FBQ08sUUFBTixJQUFrQlAsS0FBSyxDQUFDTyxRQUFOLENBQWVqRSxLQUFyQyxFQUE0QztBQUMxQzBELFFBQUFBLEtBQUssQ0FBQ08sUUFBTixDQUFlakUsS0FBZixHQUF1QixLQUFLOEQsbUJBQUwsQ0FBeUI3TSxNQUF6QixFQUFpQ3lNLEtBQUssQ0FBQ08sUUFBTixDQUFlakUsS0FBaEQsQ0FBdkI7QUFDRDs7QUFDRCxhQUFPMEQsS0FBUDtBQUNELEtBckJVLENBQVg7QUFzQkF0QyxJQUFBQSxjQUFjLEdBQUcsS0FBS1Msb0JBQUwsQ0FBMEJULGNBQTFCLENBQWpCO0FBQ0EsV0FBTyxLQUFLdkcsbUJBQUwsQ0FBeUJ4RCxTQUF6QixFQUNKZixJQURJLENBQ0NJLFVBQVUsSUFDZEEsVUFBVSxDQUFDOE0sU0FBWCxDQUFxQkMsUUFBckIsRUFBK0I7QUFDN0JyQyxNQUFBQSxjQUQ2QjtBQUU3QjVILE1BQUFBLFNBQVMsRUFBRSxLQUFLRCxVQUZhO0FBRzdCOEgsTUFBQUEsSUFINkI7QUFJN0JFLE1BQUFBO0FBSjZCLEtBQS9CLENBRkcsRUFTSmpMLElBVEksQ0FTQzROLE9BQU8sSUFBSTtBQUNmQSxNQUFBQSxPQUFPLENBQUNsSSxPQUFSLENBQWdCa0UsTUFBTSxJQUFJO0FBQ3hCLFlBQUkzSCxNQUFNLENBQUNtRSxTQUFQLENBQWlCQyxjQUFqQixDQUFnQ0MsSUFBaEMsQ0FBcUNzRCxNQUFyQyxFQUE2QyxLQUE3QyxDQUFKLEVBQXlEO0FBQ3ZELGNBQUlvRCxjQUFjLElBQUlwRCxNQUFNLENBQUN2SSxHQUE3QixFQUFrQztBQUNoQ3VJLFlBQUFBLE1BQU0sQ0FBQ3ZJLEdBQVAsR0FBYXVJLE1BQU0sQ0FBQ3ZJLEdBQVAsQ0FBV3dNLEtBQVgsQ0FBaUIsR0FBakIsRUFBc0IsQ0FBdEIsQ0FBYjtBQUNEOztBQUNELGNBQ0VqRSxNQUFNLENBQUN2SSxHQUFQLElBQWMsSUFBZCxJQUNBdUksTUFBTSxDQUFDdkksR0FBUCxJQUFjSyxTQURkLElBRUMsQ0FBQyxRQUFELEVBQVcsUUFBWCxFQUFxQm9NLFFBQXJCLENBQThCLE9BQU9sRSxNQUFNLENBQUN2SSxHQUE1QyxLQUFvRDhKLGdCQUFFNEMsT0FBRixDQUFVbkUsTUFBTSxDQUFDdkksR0FBakIsQ0FIdkQsRUFJRTtBQUNBdUksWUFBQUEsTUFBTSxDQUFDdkksR0FBUCxHQUFhLElBQWI7QUFDRDs7QUFDRHVJLFVBQUFBLE1BQU0sQ0FBQ3RJLFFBQVAsR0FBa0JzSSxNQUFNLENBQUN2SSxHQUF6QjtBQUNBLGlCQUFPdUksTUFBTSxDQUFDdkksR0FBZDtBQUNEO0FBQ0YsT0FmRDtBQWdCQSxhQUFPdU0sT0FBUDtBQUNELEtBM0JJLEVBNEJKNU4sSUE1QkksQ0E0QkN5TCxPQUFPLElBQUlBLE9BQU8sQ0FBQzVELEdBQVIsQ0FBWWtCLE1BQU0sSUFBSSw4Q0FBeUJoSSxTQUF6QixFQUFvQ2dJLE1BQXBDLEVBQTRDcEksTUFBNUMsQ0FBdEIsQ0E1QlosRUE2QkppRCxLQTdCSSxDQTZCRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBN0JULENBQVA7QUE4QkQsR0E5cUJ3RCxDQWdyQnpEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQTJKLEVBQUFBLG1CQUFtQixDQUFDN00sTUFBRCxFQUFjd00sUUFBZCxFQUFrQztBQUNuRCxRQUFJQSxRQUFRLEtBQUssSUFBakIsRUFBdUI7QUFDckIsYUFBTyxJQUFQO0FBQ0QsS0FGRCxNQUVPLElBQUk5RCxLQUFLLENBQUNDLE9BQU4sQ0FBYzZELFFBQWQsQ0FBSixFQUE2QjtBQUNsQyxhQUFPQSxRQUFRLENBQUN0RixHQUFULENBQWEwQyxLQUFLLElBQUksS0FBS2lELG1CQUFMLENBQXlCN00sTUFBekIsRUFBaUM0SixLQUFqQyxDQUF0QixDQUFQO0FBQ0QsS0FGTSxNQUVBLElBQUksT0FBTzRDLFFBQVAsS0FBb0IsUUFBeEIsRUFBa0M7QUFDdkMsWUFBTWEsV0FBVyxHQUFHLEVBQXBCOztBQUNBLFdBQUssTUFBTXJJLEtBQVgsSUFBb0J3SCxRQUFwQixFQUE4QjtBQUM1QixZQUFJeE0sTUFBTSxDQUFDQyxNQUFQLENBQWMrRSxLQUFkLEtBQXdCaEYsTUFBTSxDQUFDQyxNQUFQLENBQWMrRSxLQUFkLEVBQXFCL0QsSUFBckIsS0FBOEIsU0FBMUQsRUFBcUU7QUFDbkUsY0FBSSxPQUFPdUwsUUFBUSxDQUFDeEgsS0FBRCxDQUFmLEtBQTJCLFFBQS9CLEVBQXlDO0FBQ3ZDO0FBQ0FxSSxZQUFBQSxXQUFXLENBQUUsTUFBS3JJLEtBQU0sRUFBYixDQUFYLEdBQTZCd0gsUUFBUSxDQUFDeEgsS0FBRCxDQUFyQztBQUNELFdBSEQsTUFHTztBQUNMcUksWUFBQUEsV0FBVyxDQUFFLE1BQUtySSxLQUFNLEVBQWIsQ0FBWCxHQUE4QixHQUFFaEYsTUFBTSxDQUFDQyxNQUFQLENBQWMrRSxLQUFkLEVBQXFCOUQsV0FBWSxJQUFHc0wsUUFBUSxDQUFDeEgsS0FBRCxDQUFRLEVBQXBGO0FBQ0Q7QUFDRixTQVBELE1BT08sSUFBSWhGLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjK0UsS0FBZCxLQUF3QmhGLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjK0UsS0FBZCxFQUFxQi9ELElBQXJCLEtBQThCLE1BQTFELEVBQWtFO0FBQ3ZFb00sVUFBQUEsV0FBVyxDQUFDckksS0FBRCxDQUFYLEdBQXFCLEtBQUtzSSxjQUFMLENBQW9CZCxRQUFRLENBQUN4SCxLQUFELENBQTVCLENBQXJCO0FBQ0QsU0FGTSxNQUVBO0FBQ0xxSSxVQUFBQSxXQUFXLENBQUNySSxLQUFELENBQVgsR0FBcUIsS0FBSzZILG1CQUFMLENBQXlCN00sTUFBekIsRUFBaUN3TSxRQUFRLENBQUN4SCxLQUFELENBQXpDLENBQXJCO0FBQ0Q7O0FBRUQsWUFBSUEsS0FBSyxLQUFLLFVBQWQsRUFBMEI7QUFDeEJxSSxVQUFBQSxXQUFXLENBQUMsS0FBRCxDQUFYLEdBQXFCQSxXQUFXLENBQUNySSxLQUFELENBQWhDO0FBQ0EsaUJBQU9xSSxXQUFXLENBQUNySSxLQUFELENBQWxCO0FBQ0QsU0FIRCxNQUdPLElBQUlBLEtBQUssS0FBSyxXQUFkLEVBQTJCO0FBQ2hDcUksVUFBQUEsV0FBVyxDQUFDLGFBQUQsQ0FBWCxHQUE2QkEsV0FBVyxDQUFDckksS0FBRCxDQUF4QztBQUNBLGlCQUFPcUksV0FBVyxDQUFDckksS0FBRCxDQUFsQjtBQUNELFNBSE0sTUFHQSxJQUFJQSxLQUFLLEtBQUssV0FBZCxFQUEyQjtBQUNoQ3FJLFVBQUFBLFdBQVcsQ0FBQyxhQUFELENBQVgsR0FBNkJBLFdBQVcsQ0FBQ3JJLEtBQUQsQ0FBeEM7QUFDQSxpQkFBT3FJLFdBQVcsQ0FBQ3JJLEtBQUQsQ0FBbEI7QUFDRDtBQUNGOztBQUNELGFBQU9xSSxXQUFQO0FBQ0Q7O0FBQ0QsV0FBT2IsUUFBUDtBQUNELEdBdHVCd0QsQ0F3dUJ6RDtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0FPLEVBQUFBLDBCQUEwQixDQUFDL00sTUFBRCxFQUFjd00sUUFBZCxFQUFrQztBQUMxRCxVQUFNYSxXQUFXLEdBQUcsRUFBcEI7O0FBQ0EsU0FBSyxNQUFNckksS0FBWCxJQUFvQndILFFBQXBCLEVBQThCO0FBQzVCLFVBQUl4TSxNQUFNLENBQUNDLE1BQVAsQ0FBYytFLEtBQWQsS0FBd0JoRixNQUFNLENBQUNDLE1BQVAsQ0FBYytFLEtBQWQsRUFBcUIvRCxJQUFyQixLQUE4QixTQUExRCxFQUFxRTtBQUNuRW9NLFFBQUFBLFdBQVcsQ0FBRSxNQUFLckksS0FBTSxFQUFiLENBQVgsR0FBNkJ3SCxRQUFRLENBQUN4SCxLQUFELENBQXJDO0FBQ0QsT0FGRCxNQUVPO0FBQ0xxSSxRQUFBQSxXQUFXLENBQUNySSxLQUFELENBQVgsR0FBcUIsS0FBSzZILG1CQUFMLENBQXlCN00sTUFBekIsRUFBaUN3TSxRQUFRLENBQUN4SCxLQUFELENBQXpDLENBQXJCO0FBQ0Q7O0FBRUQsVUFBSUEsS0FBSyxLQUFLLFVBQWQsRUFBMEI7QUFDeEJxSSxRQUFBQSxXQUFXLENBQUMsS0FBRCxDQUFYLEdBQXFCQSxXQUFXLENBQUNySSxLQUFELENBQWhDO0FBQ0EsZUFBT3FJLFdBQVcsQ0FBQ3JJLEtBQUQsQ0FBbEI7QUFDRCxPQUhELE1BR08sSUFBSUEsS0FBSyxLQUFLLFdBQWQsRUFBMkI7QUFDaENxSSxRQUFBQSxXQUFXLENBQUMsYUFBRCxDQUFYLEdBQTZCQSxXQUFXLENBQUNySSxLQUFELENBQXhDO0FBQ0EsZUFBT3FJLFdBQVcsQ0FBQ3JJLEtBQUQsQ0FBbEI7QUFDRCxPQUhNLE1BR0EsSUFBSUEsS0FBSyxLQUFLLFdBQWQsRUFBMkI7QUFDaENxSSxRQUFBQSxXQUFXLENBQUMsYUFBRCxDQUFYLEdBQTZCQSxXQUFXLENBQUNySSxLQUFELENBQXhDO0FBQ0EsZUFBT3FJLFdBQVcsQ0FBQ3JJLEtBQUQsQ0FBbEI7QUFDRDtBQUNGOztBQUNELFdBQU9xSSxXQUFQO0FBQ0QsR0Fqd0J3RCxDQW13QnpEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNBVixFQUFBQSx3QkFBd0IsQ0FBQzNNLE1BQUQsRUFBY3dNLFFBQWQsRUFBa0M7QUFDeEQsUUFBSTlELEtBQUssQ0FBQ0MsT0FBTixDQUFjNkQsUUFBZCxDQUFKLEVBQTZCO0FBQzNCLGFBQU9BLFFBQVEsQ0FBQ3RGLEdBQVQsQ0FBYTBDLEtBQUssSUFBSSxLQUFLK0Msd0JBQUwsQ0FBOEIzTSxNQUE5QixFQUFzQzRKLEtBQXRDLENBQXRCLENBQVA7QUFDRCxLQUZELE1BRU8sSUFBSSxPQUFPNEMsUUFBUCxLQUFvQixRQUF4QixFQUFrQztBQUN2QyxZQUFNYSxXQUFXLEdBQUcsRUFBcEI7O0FBQ0EsV0FBSyxNQUFNckksS0FBWCxJQUFvQndILFFBQXBCLEVBQThCO0FBQzVCYSxRQUFBQSxXQUFXLENBQUNySSxLQUFELENBQVgsR0FBcUIsS0FBSzJILHdCQUFMLENBQThCM00sTUFBOUIsRUFBc0N3TSxRQUFRLENBQUN4SCxLQUFELENBQTlDLENBQXJCO0FBQ0Q7O0FBQ0QsYUFBT3FJLFdBQVA7QUFDRCxLQU5NLE1BTUEsSUFBSSxPQUFPYixRQUFQLEtBQW9CLFFBQXhCLEVBQWtDO0FBQ3ZDLFlBQU14SCxLQUFLLEdBQUd3SCxRQUFRLENBQUNlLFNBQVQsQ0FBbUIsQ0FBbkIsQ0FBZDs7QUFDQSxVQUFJdk4sTUFBTSxDQUFDQyxNQUFQLENBQWMrRSxLQUFkLEtBQXdCaEYsTUFBTSxDQUFDQyxNQUFQLENBQWMrRSxLQUFkLEVBQXFCL0QsSUFBckIsS0FBOEIsU0FBMUQsRUFBcUU7QUFDbkUsZUFBUSxPQUFNK0QsS0FBTSxFQUFwQjtBQUNELE9BRkQsTUFFTyxJQUFJQSxLQUFLLElBQUksV0FBYixFQUEwQjtBQUMvQixlQUFPLGNBQVA7QUFDRCxPQUZNLE1BRUEsSUFBSUEsS0FBSyxJQUFJLFdBQWIsRUFBMEI7QUFDL0IsZUFBTyxjQUFQO0FBQ0Q7QUFDRjs7QUFDRCxXQUFPd0gsUUFBUDtBQUNELEdBNXhCd0QsQ0E4eEJ6RDtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0FjLEVBQUFBLGNBQWMsQ0FBQzFELEtBQUQsRUFBa0I7QUFDOUIsUUFBSSxPQUFPQSxLQUFQLEtBQWlCLFFBQXJCLEVBQStCO0FBQzdCLGFBQU8sSUFBSTRELElBQUosQ0FBUzVELEtBQVQsQ0FBUDtBQUNEOztBQUVELFVBQU15RCxXQUFXLEdBQUcsRUFBcEI7O0FBQ0EsU0FBSyxNQUFNckksS0FBWCxJQUFvQjRFLEtBQXBCLEVBQTJCO0FBQ3pCeUQsTUFBQUEsV0FBVyxDQUFDckksS0FBRCxDQUFYLEdBQXFCLEtBQUtzSSxjQUFMLENBQW9CMUQsS0FBSyxDQUFDNUUsS0FBRCxDQUF6QixDQUFyQjtBQUNEOztBQUNELFdBQU9xSSxXQUFQO0FBQ0Q7O0FBRUR6QyxFQUFBQSxvQkFBb0IsQ0FBQ1QsY0FBRCxFQUFtQztBQUNyRCxRQUFJQSxjQUFKLEVBQW9CO0FBQ2xCQSxNQUFBQSxjQUFjLEdBQUdBLGNBQWMsQ0FBQ3NELFdBQWYsRUFBakI7QUFDRDs7QUFDRCxZQUFRdEQsY0FBUjtBQUNFLFdBQUssU0FBTDtBQUNFQSxRQUFBQSxjQUFjLEdBQUduTCxjQUFjLENBQUMwTyxPQUFoQztBQUNBOztBQUNGLFdBQUssbUJBQUw7QUFDRXZELFFBQUFBLGNBQWMsR0FBR25MLGNBQWMsQ0FBQzJPLGlCQUFoQztBQUNBOztBQUNGLFdBQUssV0FBTDtBQUNFeEQsUUFBQUEsY0FBYyxHQUFHbkwsY0FBYyxDQUFDNE8sU0FBaEM7QUFDQTs7QUFDRixXQUFLLHFCQUFMO0FBQ0V6RCxRQUFBQSxjQUFjLEdBQUduTCxjQUFjLENBQUM2TyxtQkFBaEM7QUFDQTs7QUFDRixXQUFLLFNBQUw7QUFDRTFELFFBQUFBLGNBQWMsR0FBR25MLGNBQWMsQ0FBQzhPLE9BQWhDO0FBQ0E7O0FBQ0YsV0FBSy9NLFNBQUw7QUFDQSxXQUFLLElBQUw7QUFDQSxXQUFLLEVBQUw7QUFDRTs7QUFDRjtBQUNFLGNBQU0sSUFBSW1FLGNBQU1DLEtBQVYsQ0FBZ0JELGNBQU1DLEtBQU4sQ0FBWUMsYUFBNUIsRUFBMkMsZ0NBQTNDLENBQU47QUFyQko7O0FBdUJBLFdBQU8rRSxjQUFQO0FBQ0Q7O0FBRUQ0RCxFQUFBQSxxQkFBcUIsR0FBa0I7QUFDckMsV0FBTzVLLE9BQU8sQ0FBQ08sT0FBUixFQUFQO0FBQ0Q7O0FBRURxSSxFQUFBQSxXQUFXLENBQUMzTCxTQUFELEVBQW9CZ0csS0FBcEIsRUFBZ0M7QUFDekMsV0FBTyxLQUFLeEMsbUJBQUwsQ0FBeUJ4RCxTQUF6QixFQUNKZixJQURJLENBQ0NJLFVBQVUsSUFBSUEsVUFBVSxDQUFDZ0ssZ0JBQVgsQ0FBNEJzQyxXQUE1QixDQUF3QzNGLEtBQXhDLENBRGYsRUFFSm5ELEtBRkksQ0FFRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBRlQsQ0FBUDtBQUdEOztBQUVENEMsRUFBQUEsYUFBYSxDQUFDMUYsU0FBRCxFQUFvQkksT0FBcEIsRUFBa0M7QUFDN0MsV0FBTyxLQUFLb0QsbUJBQUwsQ0FBeUJ4RCxTQUF6QixFQUNKZixJQURJLENBQ0NJLFVBQVUsSUFBSUEsVUFBVSxDQUFDZ0ssZ0JBQVgsQ0FBNEIzRCxhQUE1QixDQUEwQ3RGLE9BQTFDLENBRGYsRUFFSnlDLEtBRkksQ0FFRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBRlQsQ0FBUDtBQUdEOztBQUVEeUQsRUFBQUEscUJBQXFCLENBQUN2RyxTQUFELEVBQW9CWSxTQUFwQixFQUF1Q0MsSUFBdkMsRUFBa0Q7QUFDckUsUUFBSUEsSUFBSSxJQUFJQSxJQUFJLENBQUNBLElBQUwsS0FBYyxTQUExQixFQUFxQztBQUNuQyxZQUFNbUYsS0FBSyxHQUFHO0FBQ1osU0FBQ3BGLFNBQUQsR0FBYTtBQURELE9BQWQ7QUFHQSxhQUFPLEtBQUsrSyxXQUFMLENBQWlCM0wsU0FBakIsRUFBNEJnRyxLQUE1QixDQUFQO0FBQ0Q7O0FBQ0QsV0FBT2pELE9BQU8sQ0FBQ08sT0FBUixFQUFQO0FBQ0Q7O0FBRURtSCxFQUFBQSx5QkFBeUIsQ0FBQ3pLLFNBQUQsRUFBb0IySSxLQUFwQixFQUFzQy9JLE1BQXRDLEVBQWtFO0FBQ3pGLFNBQUssTUFBTWdCLFNBQVgsSUFBd0IrSCxLQUF4QixFQUErQjtBQUM3QixVQUFJLENBQUNBLEtBQUssQ0FBQy9ILFNBQUQsQ0FBTixJQUFxQixDQUFDK0gsS0FBSyxDQUFDL0gsU0FBRCxDQUFMLENBQWlCZ04sS0FBM0MsRUFBa0Q7QUFDaEQ7QUFDRDs7QUFDRCxZQUFNckosZUFBZSxHQUFHM0UsTUFBTSxDQUFDUSxPQUEvQjs7QUFDQSxXQUFLLE1BQU1nRixHQUFYLElBQWtCYixlQUFsQixFQUFtQztBQUNqQyxjQUFNeUIsS0FBSyxHQUFHekIsZUFBZSxDQUFDYSxHQUFELENBQTdCOztBQUNBLFlBQUlsRSxNQUFNLENBQUNtRSxTQUFQLENBQWlCQyxjQUFqQixDQUFnQ0MsSUFBaEMsQ0FBcUNTLEtBQXJDLEVBQTRDcEYsU0FBNUMsQ0FBSixFQUE0RDtBQUMxRCxpQkFBT21DLE9BQU8sQ0FBQ08sT0FBUixFQUFQO0FBQ0Q7QUFDRjs7QUFDRCxZQUFNc0gsU0FBUyxHQUFJLEdBQUVoSyxTQUFVLE9BQS9CO0FBQ0EsWUFBTWlOLFNBQVMsR0FBRztBQUNoQixTQUFDakQsU0FBRCxHQUFhO0FBQUUsV0FBQ2hLLFNBQUQsR0FBYTtBQUFmO0FBREcsT0FBbEI7QUFHQSxhQUFPLEtBQUt5RCwwQkFBTCxDQUNMckUsU0FESyxFQUVMNk4sU0FGSyxFQUdMdEosZUFISyxFQUlMM0UsTUFBTSxDQUFDQyxNQUpGLEVBS0xnRCxLQUxLLENBS0NLLEtBQUssSUFBSTtBQUNmLFlBQUlBLEtBQUssQ0FBQ0MsSUFBTixLQUFlLEVBQW5CLEVBQXVCO0FBQ3JCO0FBQ0EsaUJBQU8sS0FBS3lDLG1CQUFMLENBQXlCNUYsU0FBekIsQ0FBUDtBQUNEOztBQUNELGNBQU1rRCxLQUFOO0FBQ0QsT0FYTSxDQUFQO0FBWUQ7O0FBQ0QsV0FBT0gsT0FBTyxDQUFDTyxPQUFSLEVBQVA7QUFDRDs7QUFFRHVDLEVBQUFBLFVBQVUsQ0FBQzdGLFNBQUQsRUFBb0I7QUFDNUIsV0FBTyxLQUFLd0QsbUJBQUwsQ0FBeUJ4RCxTQUF6QixFQUNKZixJQURJLENBQ0NJLFVBQVUsSUFBSUEsVUFBVSxDQUFDZ0ssZ0JBQVgsQ0FBNEJqSixPQUE1QixFQURmLEVBRUp5QyxLQUZJLENBRUVDLEdBQUcsSUFBSSxLQUFLRyxXQUFMLENBQWlCSCxHQUFqQixDQUZULENBQVA7QUFHRDs7QUFFRG9DLEVBQUFBLFNBQVMsQ0FBQ2xGLFNBQUQsRUFBb0JnRyxLQUFwQixFQUFnQztBQUN2QyxXQUFPLEtBQUt4QyxtQkFBTCxDQUF5QnhELFNBQXpCLEVBQ0pmLElBREksQ0FDQ0ksVUFBVSxJQUFJQSxVQUFVLENBQUNnSyxnQkFBWCxDQUE0Qm5FLFNBQTVCLENBQXNDYyxLQUF0QyxDQURmLEVBRUpuRCxLQUZJLENBRUVDLEdBQUcsSUFBSSxLQUFLRyxXQUFMLENBQWlCSCxHQUFqQixDQUZULENBQVA7QUFHRDs7QUFFRGdMLEVBQUFBLGNBQWMsQ0FBQzlOLFNBQUQsRUFBb0I7QUFDaEMsV0FBTyxLQUFLd0QsbUJBQUwsQ0FBeUJ4RCxTQUF6QixFQUNKZixJQURJLENBQ0NJLFVBQVUsSUFBSUEsVUFBVSxDQUFDZ0ssZ0JBQVgsQ0FBNEIwRSxXQUE1QixFQURmLEVBRUpsTCxLQUZJLENBRUVDLEdBQUcsSUFBSSxLQUFLRyxXQUFMLENBQWlCSCxHQUFqQixDQUZULENBQVA7QUFHRDs7QUFFRGtMLEVBQUFBLHVCQUF1QixHQUFpQjtBQUN0QyxXQUFPLEtBQUt0RyxhQUFMLEdBQ0p6SSxJQURJLENBQ0NnUCxPQUFPLElBQUk7QUFDZixZQUFNQyxRQUFRLEdBQUdELE9BQU8sQ0FBQ25ILEdBQVIsQ0FBWWxILE1BQU0sSUFBSTtBQUNyQyxlQUFPLEtBQUtnRyxtQkFBTCxDQUF5QmhHLE1BQU0sQ0FBQ0ksU0FBaEMsQ0FBUDtBQUNELE9BRmdCLENBQWpCO0FBR0EsYUFBTytDLE9BQU8sQ0FBQzRDLEdBQVIsQ0FBWXVJLFFBQVosQ0FBUDtBQUNELEtBTkksRUFPSnJMLEtBUEksQ0FPRUMsR0FBRyxJQUFJLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBUFQsQ0FBUDtBQVFEOztBQUVEcUwsRUFBQUEsMEJBQTBCLEdBQWlCO0FBQ3pDLFVBQU1DLG9CQUFvQixHQUFHLEtBQUs3TCxNQUFMLENBQVk4TCxZQUFaLEVBQTdCO0FBQ0FELElBQUFBLG9CQUFvQixDQUFDRSxnQkFBckI7QUFDQSxXQUFPdkwsT0FBTyxDQUFDTyxPQUFSLENBQWdCOEssb0JBQWhCLENBQVA7QUFDRDs7QUFFREcsRUFBQUEsMEJBQTBCLENBQUNILG9CQUFELEVBQTJDO0FBQ25FLFdBQU9BLG9CQUFvQixDQUFDSSxpQkFBckIsR0FBeUN2UCxJQUF6QyxDQUE4QyxNQUFNO0FBQ3pEbVAsTUFBQUEsb0JBQW9CLENBQUNLLFVBQXJCO0FBQ0QsS0FGTSxDQUFQO0FBR0Q7O0FBRURDLEVBQUFBLHlCQUF5QixDQUFDTixvQkFBRCxFQUEyQztBQUNsRSxXQUFPQSxvQkFBb0IsQ0FBQ08sZ0JBQXJCLEdBQXdDMVAsSUFBeEMsQ0FBNkMsTUFBTTtBQUN4RG1QLE1BQUFBLG9CQUFvQixDQUFDSyxVQUFyQjtBQUNELEtBRk0sQ0FBUDtBQUdEOztBQW43QndEOzs7ZUFzN0I1Q2xOLG1CIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCBNb25nb0NvbGxlY3Rpb24gZnJvbSAnLi9Nb25nb0NvbGxlY3Rpb24nO1xuaW1wb3J0IE1vbmdvU2NoZW1hQ29sbGVjdGlvbiBmcm9tICcuL01vbmdvU2NoZW1hQ29sbGVjdGlvbic7XG5pbXBvcnQgeyBTdG9yYWdlQWRhcHRlciB9IGZyb20gJy4uL1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCB0eXBlIHsgU2NoZW1hVHlwZSwgUXVlcnlUeXBlLCBTdG9yYWdlQ2xhc3MsIFF1ZXJ5T3B0aW9ucyB9IGZyb20gJy4uL1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCB7IHBhcnNlIGFzIHBhcnNlVXJsLCBmb3JtYXQgYXMgZm9ybWF0VXJsIH0gZnJvbSAnLi4vLi4vLi4vdmVuZG9yL21vbmdvZGJVcmwnO1xuaW1wb3J0IHtcbiAgcGFyc2VPYmplY3RUb01vbmdvT2JqZWN0Rm9yQ3JlYXRlLFxuICBtb25nb09iamVjdFRvUGFyc2VPYmplY3QsXG4gIHRyYW5zZm9ybUtleSxcbiAgdHJhbnNmb3JtV2hlcmUsXG4gIHRyYW5zZm9ybVVwZGF0ZSxcbiAgdHJhbnNmb3JtUG9pbnRlclN0cmluZyxcbn0gZnJvbSAnLi9Nb25nb1RyYW5zZm9ybSc7XG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBkZWZhdWx0cyBmcm9tICcuLi8uLi8uLi9kZWZhdWx0cyc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uLy4uLy4uL2xvZ2dlcic7XG5cbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuY29uc3QgbW9uZ29kYiA9IHJlcXVpcmUoJ21vbmdvZGInKTtcbmNvbnN0IE1vbmdvQ2xpZW50ID0gbW9uZ29kYi5Nb25nb0NsaWVudDtcbmNvbnN0IFJlYWRQcmVmZXJlbmNlID0gbW9uZ29kYi5SZWFkUHJlZmVyZW5jZTtcblxuY29uc3QgTW9uZ29TY2hlbWFDb2xsZWN0aW9uTmFtZSA9ICdfU0NIRU1BJztcblxuY29uc3Qgc3RvcmFnZUFkYXB0ZXJBbGxDb2xsZWN0aW9ucyA9IG1vbmdvQWRhcHRlciA9PiB7XG4gIHJldHVybiBtb25nb0FkYXB0ZXJcbiAgICAuY29ubmVjdCgpXG4gICAgLnRoZW4oKCkgPT4gbW9uZ29BZGFwdGVyLmRhdGFiYXNlLmNvbGxlY3Rpb25zKCkpXG4gICAgLnRoZW4oY29sbGVjdGlvbnMgPT4ge1xuICAgICAgcmV0dXJuIGNvbGxlY3Rpb25zLmZpbHRlcihjb2xsZWN0aW9uID0+IHtcbiAgICAgICAgaWYgKGNvbGxlY3Rpb24ubmFtZXNwYWNlLm1hdGNoKC9cXC5zeXN0ZW1cXC4vKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBUT0RPOiBJZiB5b3UgaGF2ZSBvbmUgYXBwIHdpdGggYSBjb2xsZWN0aW9uIHByZWZpeCB0aGF0IGhhcHBlbnMgdG8gYmUgYSBwcmVmaXggb2YgYW5vdGhlclxuICAgICAgICAvLyBhcHBzIHByZWZpeCwgdGhpcyB3aWxsIGdvIHZlcnkgdmVyeSBiYWRseS4gV2Ugc2hvdWxkIGZpeCB0aGF0IHNvbWVob3cuXG4gICAgICAgIHJldHVybiBjb2xsZWN0aW9uLmNvbGxlY3Rpb25OYW1lLmluZGV4T2YobW9uZ29BZGFwdGVyLl9jb2xsZWN0aW9uUHJlZml4KSA9PSAwO1xuICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG5jb25zdCBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hID0gKHsgLi4uc2NoZW1hIH0pID0+IHtcbiAgZGVsZXRlIHNjaGVtYS5maWVsZHMuX3JwZXJtO1xuICBkZWxldGUgc2NoZW1hLmZpZWxkcy5fd3Blcm07XG5cbiAgaWYgKHNjaGVtYS5jbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICAvLyBMZWdhY3kgbW9uZ28gYWRhcHRlciBrbm93cyBhYm91dCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHBhc3N3b3JkIGFuZCBfaGFzaGVkX3Bhc3N3b3JkLlxuICAgIC8vIEZ1dHVyZSBkYXRhYmFzZSBhZGFwdGVycyB3aWxsIG9ubHkga25vdyBhYm91dCBfaGFzaGVkX3Bhc3N3b3JkLlxuICAgIC8vIE5vdGU6IFBhcnNlIFNlcnZlciB3aWxsIGJyaW5nIGJhY2sgcGFzc3dvcmQgd2l0aCBpbmplY3REZWZhdWx0U2NoZW1hLCBzbyB3ZSBkb24ndCBuZWVkXG4gICAgLy8gdG8gYWRkIF9oYXNoZWRfcGFzc3dvcmQgYmFjayBldmVyLlxuICAgIGRlbGV0ZSBzY2hlbWEuZmllbGRzLl9oYXNoZWRfcGFzc3dvcmQ7XG4gIH1cblxuICByZXR1cm4gc2NoZW1hO1xufTtcblxuLy8gUmV0dXJucyB7IGNvZGUsIGVycm9yIH0gaWYgaW52YWxpZCwgb3IgeyByZXN1bHQgfSwgYW4gb2JqZWN0XG4vLyBzdWl0YWJsZSBmb3IgaW5zZXJ0aW5nIGludG8gX1NDSEVNQSBjb2xsZWN0aW9uLCBvdGhlcndpc2UuXG5jb25zdCBtb25nb1NjaGVtYUZyb21GaWVsZHNBbmRDbGFzc05hbWVBbmRDTFAgPSAoXG4gIGZpZWxkcyxcbiAgY2xhc3NOYW1lLFxuICBjbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gIGluZGV4ZXNcbikgPT4ge1xuICBjb25zdCBtb25nb09iamVjdCA9IHtcbiAgICBfaWQ6IGNsYXNzTmFtZSxcbiAgICBvYmplY3RJZDogJ3N0cmluZycsXG4gICAgdXBkYXRlZEF0OiAnc3RyaW5nJyxcbiAgICBjcmVhdGVkQXQ6ICdzdHJpbmcnLFxuICAgIF9tZXRhZGF0YTogdW5kZWZpbmVkLFxuICB9O1xuXG4gIGZvciAoY29uc3QgZmllbGROYW1lIGluIGZpZWxkcykge1xuICAgIGNvbnN0IHsgdHlwZSwgdGFyZ2V0Q2xhc3MsIC4uLmZpZWxkT3B0aW9ucyB9ID0gZmllbGRzW2ZpZWxkTmFtZV07XG4gICAgbW9uZ29PYmplY3RbZmllbGROYW1lXSA9IE1vbmdvU2NoZW1hQ29sbGVjdGlvbi5wYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUoe1xuICAgICAgdHlwZSxcbiAgICAgIHRhcmdldENsYXNzLFxuICAgIH0pO1xuICAgIGlmIChmaWVsZE9wdGlvbnMgJiYgT2JqZWN0LmtleXMoZmllbGRPcHRpb25zKS5sZW5ndGggPiAwKSB7XG4gICAgICBtb25nb09iamVjdC5fbWV0YWRhdGEgPSBtb25nb09iamVjdC5fbWV0YWRhdGEgfHwge307XG4gICAgICBtb25nb09iamVjdC5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnMgPSBtb25nb09iamVjdC5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnMgfHwge307XG4gICAgICBtb25nb09iamVjdC5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnNbZmllbGROYW1lXSA9IGZpZWxkT3B0aW9ucztcbiAgICB9XG4gIH1cblxuICBpZiAodHlwZW9mIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBtb25nb09iamVjdC5fbWV0YWRhdGEgPSBtb25nb09iamVjdC5fbWV0YWRhdGEgfHwge307XG4gICAgaWYgKCFjbGFzc0xldmVsUGVybWlzc2lvbnMpIHtcbiAgICAgIGRlbGV0ZSBtb25nb09iamVjdC5fbWV0YWRhdGEuY2xhc3NfcGVybWlzc2lvbnM7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1vbmdvT2JqZWN0Ll9tZXRhZGF0YS5jbGFzc19wZXJtaXNzaW9ucyA9IGNsYXNzTGV2ZWxQZXJtaXNzaW9ucztcbiAgICB9XG4gIH1cblxuICBpZiAoaW5kZXhlcyAmJiB0eXBlb2YgaW5kZXhlcyA9PT0gJ29iamVjdCcgJiYgT2JqZWN0LmtleXMoaW5kZXhlcykubGVuZ3RoID4gMCkge1xuICAgIG1vbmdvT2JqZWN0Ll9tZXRhZGF0YSA9IG1vbmdvT2JqZWN0Ll9tZXRhZGF0YSB8fCB7fTtcbiAgICBtb25nb09iamVjdC5fbWV0YWRhdGEuaW5kZXhlcyA9IGluZGV4ZXM7XG4gIH1cblxuICBpZiAoIW1vbmdvT2JqZWN0Ll9tZXRhZGF0YSkge1xuICAgIC8vIGNsZWFudXAgdGhlIHVudXNlZCBfbWV0YWRhdGFcbiAgICBkZWxldGUgbW9uZ29PYmplY3QuX21ldGFkYXRhO1xuICB9XG5cbiAgcmV0dXJuIG1vbmdvT2JqZWN0O1xufTtcblxuZXhwb3J0IGNsYXNzIE1vbmdvU3RvcmFnZUFkYXB0ZXIgaW1wbGVtZW50cyBTdG9yYWdlQWRhcHRlciB7XG4gIC8vIFByaXZhdGVcbiAgX3VyaTogc3RyaW5nO1xuICBfY29sbGVjdGlvblByZWZpeDogc3RyaW5nO1xuICBfbW9uZ29PcHRpb25zOiBPYmplY3Q7XG4gIC8vIFB1YmxpY1xuICBjb25uZWN0aW9uUHJvbWlzZTogP1Byb21pc2U8YW55PjtcbiAgZGF0YWJhc2U6IGFueTtcbiAgY2xpZW50OiBNb25nb0NsaWVudDtcbiAgX21heFRpbWVNUzogP251bWJlcjtcbiAgY2FuU29ydE9uSm9pblRhYmxlczogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3Rvcih7IHVyaSA9IGRlZmF1bHRzLkRlZmF1bHRNb25nb1VSSSwgY29sbGVjdGlvblByZWZpeCA9ICcnLCBtb25nb09wdGlvbnMgPSB7fSB9OiBhbnkpIHtcbiAgICB0aGlzLl91cmkgPSB1cmk7XG4gICAgdGhpcy5fY29sbGVjdGlvblByZWZpeCA9IGNvbGxlY3Rpb25QcmVmaXg7XG4gICAgdGhpcy5fbW9uZ29PcHRpb25zID0gbW9uZ29PcHRpb25zO1xuICAgIHRoaXMuX21vbmdvT3B0aW9ucy51c2VOZXdVcmxQYXJzZXIgPSB0cnVlO1xuICAgIHRoaXMuX21vbmdvT3B0aW9ucy51c2VVbmlmaWVkVG9wb2xvZ3kgPSB0cnVlO1xuXG4gICAgLy8gTWF4VGltZU1TIGlzIG5vdCBhIGdsb2JhbCBNb25nb0RCIGNsaWVudCBvcHRpb24sIGl0IGlzIGFwcGxpZWQgcGVyIG9wZXJhdGlvbi5cbiAgICB0aGlzLl9tYXhUaW1lTVMgPSBtb25nb09wdGlvbnMubWF4VGltZU1TO1xuICAgIHRoaXMuY2FuU29ydE9uSm9pblRhYmxlcyA9IHRydWU7XG4gICAgZGVsZXRlIG1vbmdvT3B0aW9ucy5tYXhUaW1lTVM7XG4gIH1cblxuICBjb25uZWN0KCkge1xuICAgIGlmICh0aGlzLmNvbm5lY3Rpb25Qcm9taXNlKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9uUHJvbWlzZTtcbiAgICB9XG5cbiAgICAvLyBwYXJzaW5nIGFuZCByZS1mb3JtYXR0aW5nIGNhdXNlcyB0aGUgYXV0aCB2YWx1ZSAoaWYgdGhlcmUpIHRvIGdldCBVUklcbiAgICAvLyBlbmNvZGVkXG4gICAgY29uc3QgZW5jb2RlZFVyaSA9IGZvcm1hdFVybChwYXJzZVVybCh0aGlzLl91cmkpKTtcblxuICAgIHRoaXMuY29ubmVjdGlvblByb21pc2UgPSBNb25nb0NsaWVudC5jb25uZWN0KGVuY29kZWRVcmksIHRoaXMuX21vbmdvT3B0aW9ucylcbiAgICAgIC50aGVuKGNsaWVudCA9PiB7XG4gICAgICAgIC8vIFN0YXJ0aW5nIG1vbmdvREIgMy4wLCB0aGUgTW9uZ29DbGllbnQuY29ubmVjdCBkb24ndCByZXR1cm4gYSBEQiBhbnltb3JlIGJ1dCBhIGNsaWVudFxuICAgICAgICAvLyBGb3J0dW5hdGVseSwgd2UgY2FuIGdldCBiYWNrIHRoZSBvcHRpb25zIGFuZCB1c2UgdGhlbSB0byBzZWxlY3QgdGhlIHByb3BlciBEQi5cbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21vbmdvZGIvbm9kZS1tb25nb2RiLW5hdGl2ZS9ibG9iLzJjMzVkNzZmMDg1NzQyMjViOGRiMDJkN2JlZjY4NzEyM2U2YmIwMTgvbGliL21vbmdvX2NsaWVudC5qcyNMODg1XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBjbGllbnQucy5vcHRpb25zO1xuICAgICAgICBjb25zdCBkYXRhYmFzZSA9IGNsaWVudC5kYihvcHRpb25zLmRiTmFtZSk7XG4gICAgICAgIGlmICghZGF0YWJhc2UpIHtcbiAgICAgICAgICBkZWxldGUgdGhpcy5jb25uZWN0aW9uUHJvbWlzZTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgZGF0YWJhc2Uub24oJ2Vycm9yJywgKCkgPT4ge1xuICAgICAgICAgIGRlbGV0ZSB0aGlzLmNvbm5lY3Rpb25Qcm9taXNlO1xuICAgICAgICB9KTtcbiAgICAgICAgZGF0YWJhc2Uub24oJ2Nsb3NlJywgKCkgPT4ge1xuICAgICAgICAgIGRlbGV0ZSB0aGlzLmNvbm5lY3Rpb25Qcm9taXNlO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5jbGllbnQgPSBjbGllbnQ7XG4gICAgICAgIHRoaXMuZGF0YWJhc2UgPSBkYXRhYmFzZTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgZGVsZXRlIHRoaXMuY29ubmVjdGlvblByb21pc2U7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnIpO1xuICAgICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9uUHJvbWlzZTtcbiAgfVxuXG4gIGhhbmRsZUVycm9yPFQ+KGVycm9yOiA/KEVycm9yIHwgUGFyc2UuRXJyb3IpKTogUHJvbWlzZTxUPiB7XG4gICAgaWYgKGVycm9yICYmIGVycm9yLmNvZGUgPT09IDEzKSB7XG4gICAgICAvLyBVbmF1dGhvcml6ZWQgZXJyb3JcbiAgICAgIGRlbGV0ZSB0aGlzLmNsaWVudDtcbiAgICAgIGRlbGV0ZSB0aGlzLmRhdGFiYXNlO1xuICAgICAgZGVsZXRlIHRoaXMuY29ubmVjdGlvblByb21pc2U7XG4gICAgICBsb2dnZXIuZXJyb3IoJ1JlY2VpdmVkIHVuYXV0aG9yaXplZCBlcnJvcicsIHsgZXJyb3I6IGVycm9yIH0pO1xuICAgIH1cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuXG4gIGhhbmRsZVNodXRkb3duKCkge1xuICAgIGlmICghdGhpcy5jbGllbnQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY2xpZW50LmNsb3NlKGZhbHNlKTtcbiAgfVxuXG4gIF9hZGFwdGl2ZUNvbGxlY3Rpb24obmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdCgpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLmRhdGFiYXNlLmNvbGxlY3Rpb24odGhpcy5fY29sbGVjdGlvblByZWZpeCArIG5hbWUpKVxuICAgICAgLnRoZW4ocmF3Q29sbGVjdGlvbiA9PiBuZXcgTW9uZ29Db2xsZWN0aW9uKHJhd0NvbGxlY3Rpb24pKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgX3NjaGVtYUNvbGxlY3Rpb24oKTogUHJvbWlzZTxNb25nb1NjaGVtYUNvbGxlY3Rpb24+IHtcbiAgICByZXR1cm4gdGhpcy5jb25uZWN0KClcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihNb25nb1NjaGVtYUNvbGxlY3Rpb25OYW1lKSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gbmV3IE1vbmdvU2NoZW1hQ29sbGVjdGlvbihjb2xsZWN0aW9uKSk7XG4gIH1cblxuICBjbGFzc0V4aXN0cyhuYW1lOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5jb25uZWN0KClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YWJhc2UubGlzdENvbGxlY3Rpb25zKHsgbmFtZTogdGhpcy5fY29sbGVjdGlvblByZWZpeCArIG5hbWUgfSkudG9BcnJheSgpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb25zID0+IHtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25zLmxlbmd0aCA+IDA7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgc2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zKGNsYXNzTmFtZTogc3RyaW5nLCBDTFBzOiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpXG4gICAgICAudGhlbihzY2hlbWFDb2xsZWN0aW9uID0+XG4gICAgICAgIHNjaGVtYUNvbGxlY3Rpb24udXBkYXRlU2NoZW1hKGNsYXNzTmFtZSwge1xuICAgICAgICAgICRzZXQ6IHsgJ19tZXRhZGF0YS5jbGFzc19wZXJtaXNzaW9ucyc6IENMUHMgfSxcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIHNldEluZGV4ZXNXaXRoU2NoZW1hRm9ybWF0KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHN1Ym1pdHRlZEluZGV4ZXM6IGFueSxcbiAgICBleGlzdGluZ0luZGV4ZXM6IGFueSA9IHt9LFxuICAgIGZpZWxkczogYW55XG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmIChzdWJtaXR0ZWRJbmRleGVzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgaWYgKE9iamVjdC5rZXlzKGV4aXN0aW5nSW5kZXhlcykubGVuZ3RoID09PSAwKSB7XG4gICAgICBleGlzdGluZ0luZGV4ZXMgPSB7IF9pZF86IHsgX2lkOiAxIH0gfTtcbiAgICB9XG4gICAgY29uc3QgZGVsZXRlUHJvbWlzZXMgPSBbXTtcbiAgICBjb25zdCBpbnNlcnRlZEluZGV4ZXMgPSBbXTtcbiAgICBPYmplY3Qua2V5cyhzdWJtaXR0ZWRJbmRleGVzKS5mb3JFYWNoKG5hbWUgPT4ge1xuICAgICAgY29uc3QgZmllbGQgPSBzdWJtaXR0ZWRJbmRleGVzW25hbWVdO1xuICAgICAgaWYgKGV4aXN0aW5nSW5kZXhlc1tuYW1lXSAmJiBmaWVsZC5fX29wICE9PSAnRGVsZXRlJykge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSwgYEluZGV4ICR7bmFtZX0gZXhpc3RzLCBjYW5ub3QgdXBkYXRlLmApO1xuICAgICAgfVxuICAgICAgaWYgKCFleGlzdGluZ0luZGV4ZXNbbmFtZV0gJiYgZmllbGQuX19vcCA9PT0gJ0RlbGV0ZScpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksXG4gICAgICAgICAgYEluZGV4ICR7bmFtZX0gZG9lcyBub3QgZXhpc3QsIGNhbm5vdCBkZWxldGUuYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKGZpZWxkLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLmRyb3BJbmRleChjbGFzc05hbWUsIG5hbWUpO1xuICAgICAgICBkZWxldGVQcm9taXNlcy5wdXNoKHByb21pc2UpO1xuICAgICAgICBkZWxldGUgZXhpc3RpbmdJbmRleGVzW25hbWVdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgT2JqZWN0LmtleXMoZmllbGQpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKFxuICAgICAgICAgICAgICBmaWVsZHMsXG4gICAgICAgICAgICAgIGtleS5pbmRleE9mKCdfcF8nKSA9PT0gMCA/IGtleS5yZXBsYWNlKCdfcF8nLCAnJykgOiBrZXlcbiAgICAgICAgICAgIClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSxcbiAgICAgICAgICAgICAgYEZpZWxkICR7a2V5fSBkb2VzIG5vdCBleGlzdCwgY2Fubm90IGFkZCBpbmRleC5gXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGV4aXN0aW5nSW5kZXhlc1tuYW1lXSA9IGZpZWxkO1xuICAgICAgICBpbnNlcnRlZEluZGV4ZXMucHVzaCh7XG4gICAgICAgICAga2V5OiBmaWVsZCxcbiAgICAgICAgICBuYW1lLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBsZXQgaW5zZXJ0UHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIGlmIChpbnNlcnRlZEluZGV4ZXMubGVuZ3RoID4gMCkge1xuICAgICAgaW5zZXJ0UHJvbWlzZSA9IHRoaXMuY3JlYXRlSW5kZXhlcyhjbGFzc05hbWUsIGluc2VydGVkSW5kZXhlcyk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLmFsbChkZWxldGVQcm9taXNlcylcbiAgICAgIC50aGVuKCgpID0+IGluc2VydFByb21pc2UpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKCkpXG4gICAgICAudGhlbihzY2hlbWFDb2xsZWN0aW9uID0+XG4gICAgICAgIHNjaGVtYUNvbGxlY3Rpb24udXBkYXRlU2NoZW1hKGNsYXNzTmFtZSwge1xuICAgICAgICAgICRzZXQ6IHsgJ19tZXRhZGF0YS5pbmRleGVzJzogZXhpc3RpbmdJbmRleGVzIH0sXG4gICAgICAgIH0pXG4gICAgICApXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBzZXRJbmRleGVzRnJvbU1vbmdvKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0SW5kZXhlcyhjbGFzc05hbWUpXG4gICAgICAudGhlbihpbmRleGVzID0+IHtcbiAgICAgICAgaW5kZXhlcyA9IGluZGV4ZXMucmVkdWNlKChvYmosIGluZGV4KSA9PiB7XG4gICAgICAgICAgaWYgKGluZGV4LmtleS5fZnRzKSB7XG4gICAgICAgICAgICBkZWxldGUgaW5kZXgua2V5Ll9mdHM7XG4gICAgICAgICAgICBkZWxldGUgaW5kZXgua2V5Ll9mdHN4O1xuICAgICAgICAgICAgZm9yIChjb25zdCBmaWVsZCBpbiBpbmRleC53ZWlnaHRzKSB7XG4gICAgICAgICAgICAgIGluZGV4LmtleVtmaWVsZF0gPSAndGV4dCc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIG9ialtpbmRleC5uYW1lXSA9IGluZGV4LmtleTtcbiAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICB9LCB7fSk7XG4gICAgICAgIHJldHVybiB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKCkudGhlbihzY2hlbWFDb2xsZWN0aW9uID0+XG4gICAgICAgICAgc2NoZW1hQ29sbGVjdGlvbi51cGRhdGVTY2hlbWEoY2xhc3NOYW1lLCB7XG4gICAgICAgICAgICAkc2V0OiB7ICdfbWV0YWRhdGEuaW5kZXhlcyc6IGluZGV4ZXMgfSxcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKVxuICAgICAgLmNhdGNoKCgpID0+IHtcbiAgICAgICAgLy8gSWdub3JlIGlmIGNvbGxlY3Rpb24gbm90IGZvdW5kXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlQ2xhc3MoY2xhc3NOYW1lOiBzdHJpbmcsIHNjaGVtYTogU2NoZW1hVHlwZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb09iamVjdCA9IG1vbmdvU2NoZW1hRnJvbUZpZWxkc0FuZENsYXNzTmFtZUFuZENMUChcbiAgICAgIHNjaGVtYS5maWVsZHMsXG4gICAgICBjbGFzc05hbWUsXG4gICAgICBzY2hlbWEuY2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICAgICAgc2NoZW1hLmluZGV4ZXNcbiAgICApO1xuICAgIG1vbmdvT2JqZWN0Ll9pZCA9IGNsYXNzTmFtZTtcbiAgICByZXR1cm4gdGhpcy5zZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdChjbGFzc05hbWUsIHNjaGVtYS5pbmRleGVzLCB7fSwgc2NoZW1hLmZpZWxkcylcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuX3NjaGVtYUNvbGxlY3Rpb24oKSlcbiAgICAgIC50aGVuKHNjaGVtYUNvbGxlY3Rpb24gPT4gc2NoZW1hQ29sbGVjdGlvbi5pbnNlcnRTY2hlbWEobW9uZ29PYmplY3QpKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgYWRkRmllbGRJZk5vdEV4aXN0cyhjbGFzc05hbWU6IHN0cmluZywgZmllbGROYW1lOiBzdHJpbmcsIHR5cGU6IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKClcbiAgICAgIC50aGVuKHNjaGVtYUNvbGxlY3Rpb24gPT4gc2NoZW1hQ29sbGVjdGlvbi5hZGRGaWVsZElmTm90RXhpc3RzKGNsYXNzTmFtZSwgZmllbGROYW1lLCB0eXBlKSlcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuY3JlYXRlSW5kZXhlc0lmTmVlZGVkKGNsYXNzTmFtZSwgZmllbGROYW1lLCB0eXBlKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIERyb3BzIGEgY29sbGVjdGlvbi4gUmVzb2x2ZXMgd2l0aCB0cnVlIGlmIGl0IHdhcyBhIFBhcnNlIFNjaGVtYSAoZWcuIF9Vc2VyLCBDdXN0b20sIGV0Yy4pXG4gIC8vIGFuZCByZXNvbHZlcyB3aXRoIGZhbHNlIGlmIGl0IHdhc24ndCAoZWcuIGEgam9pbiB0YWJsZSkuIFJlamVjdHMgaWYgZGVsZXRpb24gd2FzIGltcG9zc2libGUuXG4gIGRlbGV0ZUNsYXNzKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5kcm9wKCkpXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgLy8gJ25zIG5vdCBmb3VuZCcgbWVhbnMgY29sbGVjdGlvbiB3YXMgYWxyZWFkeSBnb25lLiBJZ25vcmUgZGVsZXRpb24gYXR0ZW1wdC5cbiAgICAgICAgICBpZiAoZXJyb3IubWVzc2FnZSA9PSAnbnMgbm90IGZvdW5kJykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfSlcbiAgICAgICAgLy8gV2UndmUgZHJvcHBlZCB0aGUgY29sbGVjdGlvbiwgbm93IHJlbW92ZSB0aGUgX1NDSEVNQSBkb2N1bWVudFxuICAgICAgICAudGhlbigoKSA9PiB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKCkpXG4gICAgICAgIC50aGVuKHNjaGVtYUNvbGxlY3Rpb24gPT4gc2NoZW1hQ29sbGVjdGlvbi5maW5kQW5kRGVsZXRlU2NoZW1hKGNsYXNzTmFtZSkpXG4gICAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKVxuICAgICk7XG4gIH1cblxuICBkZWxldGVBbGxDbGFzc2VzKGZhc3Q6IGJvb2xlYW4pIHtcbiAgICByZXR1cm4gc3RvcmFnZUFkYXB0ZXJBbGxDb2xsZWN0aW9ucyh0aGlzKS50aGVuKGNvbGxlY3Rpb25zID0+XG4gICAgICBQcm9taXNlLmFsbChcbiAgICAgICAgY29sbGVjdGlvbnMubWFwKGNvbGxlY3Rpb24gPT4gKGZhc3QgPyBjb2xsZWN0aW9uLmRlbGV0ZU1hbnkoe30pIDogY29sbGVjdGlvbi5kcm9wKCkpKVxuICAgICAgKVxuICAgICk7XG4gIH1cblxuICAvLyBSZW1vdmUgdGhlIGNvbHVtbiBhbmQgYWxsIHRoZSBkYXRhLiBGb3IgUmVsYXRpb25zLCB0aGUgX0pvaW4gY29sbGVjdGlvbiBpcyBoYW5kbGVkXG4gIC8vIHNwZWNpYWxseSwgdGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBkZWxldGUgX0pvaW4gY29sdW1ucy4gSXQgc2hvdWxkLCBob3dldmVyLCBpbmRpY2F0ZVxuICAvLyB0aGF0IHRoZSByZWxhdGlvbiBmaWVsZHMgZG9lcyBub3QgZXhpc3QgYW55bW9yZS4gSW4gbW9uZ28sIHRoaXMgbWVhbnMgcmVtb3ZpbmcgaXQgZnJvbVxuICAvLyB0aGUgX1NDSEVNQSBjb2xsZWN0aW9uLiAgVGhlcmUgc2hvdWxkIGJlIG5vIGFjdHVhbCBkYXRhIGluIHRoZSBjb2xsZWN0aW9uIHVuZGVyIHRoZSBzYW1lIG5hbWVcbiAgLy8gYXMgdGhlIHJlbGF0aW9uIGNvbHVtbiwgc28gaXQncyBmaW5lIHRvIGF0dGVtcHQgdG8gZGVsZXRlIGl0LiBJZiB0aGUgZmllbGRzIGxpc3RlZCB0byBiZVxuICAvLyBkZWxldGVkIGRvIG5vdCBleGlzdCwgdGhpcyBmdW5jdGlvbiBzaG91bGQgcmV0dXJuIHN1Y2Nlc3NmdWxseSBhbnl3YXlzLiBDaGVja2luZyBmb3JcbiAgLy8gYXR0ZW1wdHMgdG8gZGVsZXRlIG5vbi1leGlzdGVudCBmaWVsZHMgaXMgdGhlIHJlc3BvbnNpYmlsaXR5IG9mIFBhcnNlIFNlcnZlci5cblxuICAvLyBQb2ludGVyIGZpZWxkIG5hbWVzIGFyZSBwYXNzZWQgZm9yIGxlZ2FjeSByZWFzb25zOiB0aGUgb3JpZ2luYWwgbW9uZ29cbiAgLy8gZm9ybWF0IHN0b3JlZCBwb2ludGVyIGZpZWxkIG5hbWVzIGRpZmZlcmVudGx5IGluIHRoZSBkYXRhYmFzZSwgYW5kIHRoZXJlZm9yZVxuICAvLyBuZWVkZWQgdG8ga25vdyB0aGUgdHlwZSBvZiB0aGUgZmllbGQgYmVmb3JlIGl0IGNvdWxkIGRlbGV0ZSBpdC4gRnV0dXJlIGRhdGFiYXNlXG4gIC8vIGFkYXB0ZXJzIHNob3VsZCBpZ25vcmUgdGhlIHBvaW50ZXJGaWVsZE5hbWVzIGFyZ3VtZW50LiBBbGwgdGhlIGZpZWxkIG5hbWVzIGFyZSBpblxuICAvLyBmaWVsZE5hbWVzLCB0aGV5IHNob3cgdXAgYWRkaXRpb25hbGx5IGluIHRoZSBwb2ludGVyRmllbGROYW1lcyBkYXRhYmFzZSBmb3IgdXNlXG4gIC8vIGJ5IHRoZSBtb25nbyBhZGFwdGVyLCB3aGljaCBkZWFscyB3aXRoIHRoZSBsZWdhY3kgbW9uZ28gZm9ybWF0LlxuXG4gIC8vIFRoaXMgZnVuY3Rpb24gaXMgbm90IG9ibGlnYXRlZCB0byBkZWxldGUgZmllbGRzIGF0b21pY2FsbHkuIEl0IGlzIGdpdmVuIHRoZSBmaWVsZFxuICAvLyBuYW1lcyBpbiBhIGxpc3Qgc28gdGhhdCBkYXRhYmFzZXMgdGhhdCBhcmUgY2FwYWJsZSBvZiBkZWxldGluZyBmaWVsZHMgYXRvbWljYWxseVxuICAvLyBtYXkgZG8gc28uXG5cbiAgLy8gUmV0dXJucyBhIFByb21pc2UuXG4gIGRlbGV0ZUZpZWxkcyhjbGFzc05hbWU6IHN0cmluZywgc2NoZW1hOiBTY2hlbWFUeXBlLCBmaWVsZE5hbWVzOiBzdHJpbmdbXSkge1xuICAgIGNvbnN0IG1vbmdvRm9ybWF0TmFtZXMgPSBmaWVsZE5hbWVzLm1hcChmaWVsZE5hbWUgPT4ge1xuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgICAgcmV0dXJuIGBfcF8ke2ZpZWxkTmFtZX1gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZpZWxkTmFtZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBjb2xsZWN0aW9uVXBkYXRlID0geyAkdW5zZXQ6IHt9IH07XG4gICAgbW9uZ29Gb3JtYXROYW1lcy5mb3JFYWNoKG5hbWUgPT4ge1xuICAgICAgY29sbGVjdGlvblVwZGF0ZVsnJHVuc2V0J11bbmFtZV0gPSBudWxsO1xuICAgIH0pO1xuXG4gICAgY29uc3QgY29sbGVjdGlvbkZpbHRlciA9IHsgJG9yOiBbXSB9O1xuICAgIG1vbmdvRm9ybWF0TmFtZXMuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgIGNvbGxlY3Rpb25GaWx0ZXJbJyRvciddLnB1c2goeyBbbmFtZV06IHsgJGV4aXN0czogdHJ1ZSB9IH0pO1xuICAgIH0pO1xuXG4gICAgY29uc3Qgc2NoZW1hVXBkYXRlID0geyAkdW5zZXQ6IHt9IH07XG4gICAgZmllbGROYW1lcy5mb3JFYWNoKG5hbWUgPT4ge1xuICAgICAgc2NoZW1hVXBkYXRlWyckdW5zZXQnXVtuYW1lXSA9IG51bGw7XG4gICAgICBzY2hlbWFVcGRhdGVbJyR1bnNldCddW2BfbWV0YWRhdGEuZmllbGRzX29wdGlvbnMuJHtuYW1lfWBdID0gbnVsbDtcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLnVwZGF0ZU1hbnkoY29sbGVjdGlvbkZpbHRlciwgY29sbGVjdGlvblVwZGF0ZSkpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKCkpXG4gICAgICAudGhlbihzY2hlbWFDb2xsZWN0aW9uID0+IHNjaGVtYUNvbGxlY3Rpb24udXBkYXRlU2NoZW1hKGNsYXNzTmFtZSwgc2NoZW1hVXBkYXRlKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIFJldHVybiBhIHByb21pc2UgZm9yIGFsbCBzY2hlbWFzIGtub3duIHRvIHRoaXMgYWRhcHRlciwgaW4gUGFyc2UgZm9ybWF0LiBJbiBjYXNlIHRoZVxuICAvLyBzY2hlbWFzIGNhbm5vdCBiZSByZXRyaWV2ZWQsIHJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVqZWN0cy4gUmVxdWlyZW1lbnRzIGZvciB0aGVcbiAgLy8gcmVqZWN0aW9uIHJlYXNvbiBhcmUgVEJELlxuICBnZXRBbGxDbGFzc2VzKCk6IFByb21pc2U8U3RvcmFnZUNsYXNzW10+IHtcbiAgICByZXR1cm4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpXG4gICAgICAudGhlbihzY2hlbWFzQ29sbGVjdGlvbiA9PiBzY2hlbWFzQ29sbGVjdGlvbi5fZmV0Y2hBbGxTY2hlbWFzRnJvbV9TQ0hFTUEoKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIFJldHVybiBhIHByb21pc2UgZm9yIHRoZSBzY2hlbWEgd2l0aCB0aGUgZ2l2ZW4gbmFtZSwgaW4gUGFyc2UgZm9ybWF0LiBJZlxuICAvLyB0aGlzIGFkYXB0ZXIgZG9lc24ndCBrbm93IGFib3V0IHRoZSBzY2hlbWEsIHJldHVybiBhIHByb21pc2UgdGhhdCByZWplY3RzIHdpdGhcbiAgLy8gdW5kZWZpbmVkIGFzIHRoZSByZWFzb24uXG4gIGdldENsYXNzKGNsYXNzTmFtZTogc3RyaW5nKTogUHJvbWlzZTxTdG9yYWdlQ2xhc3M+IHtcbiAgICByZXR1cm4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpXG4gICAgICAudGhlbihzY2hlbWFzQ29sbGVjdGlvbiA9PiBzY2hlbWFzQ29sbGVjdGlvbi5fZmV0Y2hPbmVTY2hlbWFGcm9tX1NDSEVNQShjbGFzc05hbWUpKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gVE9ETzogQXMgeWV0IG5vdCBwYXJ0aWN1bGFybHkgd2VsbCBzcGVjaWZpZWQuIENyZWF0ZXMgYW4gb2JqZWN0LiBNYXliZSBzaG91bGRuJ3QgZXZlbiBuZWVkIHRoZSBzY2hlbWEsXG4gIC8vIGFuZCBzaG91bGQgaW5mZXIgZnJvbSB0aGUgdHlwZS4gT3IgbWF5YmUgZG9lcyBuZWVkIHRoZSBzY2hlbWEgZm9yIHZhbGlkYXRpb25zLiBPciBtYXliZSBuZWVkc1xuICAvLyB0aGUgc2NoZW1hIG9ubHkgZm9yIHRoZSBsZWdhY3kgbW9uZ28gZm9ybWF0LiBXZSdsbCBmaWd1cmUgdGhhdCBvdXQgbGF0ZXIuXG4gIGNyZWF0ZU9iamVjdChjbGFzc05hbWU6IHN0cmluZywgc2NoZW1hOiBTY2hlbWFUeXBlLCBvYmplY3Q6IGFueSwgdHJhbnNhY3Rpb25hbFNlc3Npb246ID9hbnkpIHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29PYmplY3QgPSBwYXJzZU9iamVjdFRvTW9uZ29PYmplY3RGb3JDcmVhdGUoY2xhc3NOYW1lLCBvYmplY3QsIHNjaGVtYSk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24uaW5zZXJ0T25lKG1vbmdvT2JqZWN0LCB0cmFuc2FjdGlvbmFsU2Vzc2lvbikpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gMTEwMDApIHtcbiAgICAgICAgICAvLyBEdXBsaWNhdGUgdmFsdWVcbiAgICAgICAgICBjb25zdCBlcnIgPSBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUsXG4gICAgICAgICAgICAnQSBkdXBsaWNhdGUgdmFsdWUgZm9yIGEgZmllbGQgd2l0aCB1bmlxdWUgdmFsdWVzIHdhcyBwcm92aWRlZCdcbiAgICAgICAgICApO1xuICAgICAgICAgIGVyci51bmRlcmx5aW5nRXJyb3IgPSBlcnJvcjtcbiAgICAgICAgICBpZiAoZXJyb3IubWVzc2FnZSkge1xuICAgICAgICAgICAgY29uc3QgbWF0Y2hlcyA9IGVycm9yLm1lc3NhZ2UubWF0Y2goL2luZGV4OltcXHNhLXpBLVowLTlfXFwtXFwuXStcXCQ/KFthLXpBLVpfLV0rKV8xLyk7XG4gICAgICAgICAgICBpZiAobWF0Y2hlcyAmJiBBcnJheS5pc0FycmF5KG1hdGNoZXMpKSB7XG4gICAgICAgICAgICAgIGVyci51c2VySW5mbyA9IHsgZHVwbGljYXRlZF9maWVsZDogbWF0Y2hlc1sxXSB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gUmVtb3ZlIGFsbCBvYmplY3RzIHRoYXQgbWF0Y2ggdGhlIGdpdmVuIFBhcnNlIFF1ZXJ5LlxuICAvLyBJZiBubyBvYmplY3RzIG1hdGNoLCByZWplY3Qgd2l0aCBPQkpFQ1RfTk9UX0ZPVU5ELiBJZiBvYmplY3RzIGFyZSBmb3VuZCBhbmQgZGVsZXRlZCwgcmVzb2x2ZSB3aXRoIHVuZGVmaW5lZC5cbiAgLy8gSWYgdGhlcmUgaXMgc29tZSBvdGhlciBlcnJvciwgcmVqZWN0IHdpdGggSU5URVJOQUxfU0VSVkVSX0VSUk9SLlxuICBkZWxldGVPYmplY3RzQnlRdWVyeShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbjogP2FueVxuICApIHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IHtcbiAgICAgICAgY29uc3QgbW9uZ29XaGVyZSA9IHRyYW5zZm9ybVdoZXJlKGNsYXNzTmFtZSwgcXVlcnksIHNjaGVtYSk7XG4gICAgICAgIHJldHVybiBjb2xsZWN0aW9uLmRlbGV0ZU1hbnkobW9uZ29XaGVyZSwgdHJhbnNhY3Rpb25hbFNlc3Npb24pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKVxuICAgICAgLnRoZW4oXG4gICAgICAgICh7IHJlc3VsdCB9KSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3VsdC5uID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ09iamVjdCBub3QgZm91bmQuJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfSxcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsICdEYXRhYmFzZSBhZGFwdGVyIGVycm9yJyk7XG4gICAgICAgIH1cbiAgICAgICk7XG4gIH1cblxuICAvLyBBcHBseSB0aGUgdXBkYXRlIHRvIGFsbCBvYmplY3RzIHRoYXQgbWF0Y2ggdGhlIGdpdmVuIFBhcnNlIFF1ZXJ5LlxuICB1cGRhdGVPYmplY3RzQnlRdWVyeShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICB1cGRhdGU6IGFueSxcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbjogP2FueVxuICApIHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29VcGRhdGUgPSB0cmFuc2Zvcm1VcGRhdGUoY2xhc3NOYW1lLCB1cGRhdGUsIHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29XaGVyZSA9IHRyYW5zZm9ybVdoZXJlKGNsYXNzTmFtZSwgcXVlcnksIHNjaGVtYSk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24udXBkYXRlTWFueShtb25nb1doZXJlLCBtb25nb1VwZGF0ZSwgdHJhbnNhY3Rpb25hbFNlc3Npb24pKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gQXRvbWljYWxseSBmaW5kcyBhbmQgdXBkYXRlcyBhbiBvYmplY3QgYmFzZWQgb24gcXVlcnkuXG4gIC8vIFJldHVybiB2YWx1ZSBub3QgY3VycmVudGx5IHdlbGwgc3BlY2lmaWVkLlxuICBmaW5kT25lQW5kVXBkYXRlKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHVwZGF0ZTogYW55LFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb1VwZGF0ZSA9IHRyYW5zZm9ybVVwZGF0ZShjbGFzc05hbWUsIHVwZGF0ZSwgc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb1doZXJlID0gdHJhbnNmb3JtV2hlcmUoY2xhc3NOYW1lLCBxdWVyeSwgc2NoZW1hKTtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT5cbiAgICAgICAgY29sbGVjdGlvbi5fbW9uZ29Db2xsZWN0aW9uLmZpbmRPbmVBbmRVcGRhdGUobW9uZ29XaGVyZSwgbW9uZ29VcGRhdGUsIHtcbiAgICAgICAgICByZXR1cm5PcmlnaW5hbDogZmFsc2UsXG4gICAgICAgICAgc2Vzc2lvbjogdHJhbnNhY3Rpb25hbFNlc3Npb24gfHwgdW5kZWZpbmVkLFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzdWx0ID0+IG1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdChjbGFzc05hbWUsIHJlc3VsdC52YWx1ZSwgc2NoZW1hKSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvci5jb2RlID09PSAxMTAwMCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLkRVUExJQ0FURV9WQUxVRSxcbiAgICAgICAgICAgICdBIGR1cGxpY2F0ZSB2YWx1ZSBmb3IgYSBmaWVsZCB3aXRoIHVuaXF1ZSB2YWx1ZXMgd2FzIHByb3ZpZGVkJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gSG9wZWZ1bGx5IHdlIGNhbiBnZXQgcmlkIG9mIHRoaXMuIEl0J3Mgb25seSB1c2VkIGZvciBjb25maWcgYW5kIGhvb2tzLlxuICB1cHNlcnRPbmVPYmplY3QoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIHF1ZXJ5OiBRdWVyeVR5cGUsXG4gICAgdXBkYXRlOiBhbnksXG4gICAgdHJhbnNhY3Rpb25hbFNlc3Npb246ID9hbnlcbiAgKSB7XG4gICAgc2NoZW1hID0gY29udmVydFBhcnNlU2NoZW1hVG9Nb25nb1NjaGVtYShzY2hlbWEpO1xuICAgIGNvbnN0IG1vbmdvVXBkYXRlID0gdHJhbnNmb3JtVXBkYXRlKGNsYXNzTmFtZSwgdXBkYXRlLCBzY2hlbWEpO1xuICAgIGNvbnN0IG1vbmdvV2hlcmUgPSB0cmFuc2Zvcm1XaGVyZShjbGFzc05hbWUsIHF1ZXJ5LCBzY2hlbWEpO1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLnVwc2VydE9uZShtb25nb1doZXJlLCBtb25nb1VwZGF0ZSwgdHJhbnNhY3Rpb25hbFNlc3Npb24pKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gRXhlY3V0ZXMgYSBmaW5kLiBBY2NlcHRzOiBjbGFzc05hbWUsIHF1ZXJ5IGluIFBhcnNlIGZvcm1hdCwgYW5kIHsgc2tpcCwgbGltaXQsIHNvcnQgfS5cbiAgZmluZChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICB7IHNraXAsIGxpbWl0LCBzb3J0LCBrZXlzLCByZWFkUHJlZmVyZW5jZSwgaGludCwgY2FzZUluc2Vuc2l0aXZlLCBleHBsYWluIH06IFF1ZXJ5T3B0aW9uc1xuICApOiBQcm9taXNlPGFueT4ge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb1doZXJlID0gdHJhbnNmb3JtV2hlcmUoY2xhc3NOYW1lLCBxdWVyeSwgc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb1NvcnQgPSBfLm1hcEtleXMoc29ydCwgKHZhbHVlLCBmaWVsZE5hbWUpID0+XG4gICAgICB0cmFuc2Zvcm1LZXkoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHNjaGVtYSlcbiAgICApO1xuICAgIGNvbnN0IG1vbmdvS2V5cyA9IF8ucmVkdWNlKFxuICAgICAga2V5cyxcbiAgICAgIChtZW1vLCBrZXkpID0+IHtcbiAgICAgICAgaWYgKGtleSA9PT0gJ0FDTCcpIHtcbiAgICAgICAgICBtZW1vWydfcnBlcm0nXSA9IDE7XG4gICAgICAgICAgbWVtb1snX3dwZXJtJ10gPSAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG1lbW9bdHJhbnNmb3JtS2V5KGNsYXNzTmFtZSwga2V5LCBzY2hlbWEpXSA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lbW87XG4gICAgICB9LFxuICAgICAge31cbiAgICApO1xuXG4gICAgLy8gSWYgd2UgYXJlbid0IHJlcXVlc3RpbmcgdGhlIGBfaWRgIGZpZWxkLCB3ZSBuZWVkIHRvIGV4cGxpY2l0bHkgb3B0IG91dFxuICAgIC8vIG9mIGl0LiBEb2luZyBzbyBpbiBwYXJzZS1zZXJ2ZXIgaXMgdW51c3VhbCwgYnV0IGl0IGNhbiBhbGxvdyB1cyB0b1xuICAgIC8vIG9wdGltaXplIHNvbWUgcXVlcmllcyB3aXRoIGNvdmVyaW5nIGluZGV4ZXMuXG4gICAgaWYgKGtleXMgJiYgIW1vbmdvS2V5cy5faWQpIHtcbiAgICAgIG1vbmdvS2V5cy5faWQgPSAwO1xuICAgIH1cblxuICAgIHJlYWRQcmVmZXJlbmNlID0gdGhpcy5fcGFyc2VSZWFkUHJlZmVyZW5jZShyZWFkUHJlZmVyZW5jZSk7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlVGV4dEluZGV4ZXNJZk5lZWRlZChjbGFzc05hbWUsIHF1ZXJ5LCBzY2hlbWEpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT5cbiAgICAgICAgY29sbGVjdGlvbi5maW5kKG1vbmdvV2hlcmUsIHtcbiAgICAgICAgICBza2lwLFxuICAgICAgICAgIGxpbWl0LFxuICAgICAgICAgIHNvcnQ6IG1vbmdvU29ydCxcbiAgICAgICAgICBrZXlzOiBtb25nb0tleXMsXG4gICAgICAgICAgbWF4VGltZU1TOiB0aGlzLl9tYXhUaW1lTVMsXG4gICAgICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgaGludCxcbiAgICAgICAgICBjYXNlSW5zZW5zaXRpdmUsXG4gICAgICAgICAgZXhwbGFpbixcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC50aGVuKG9iamVjdHMgPT4ge1xuICAgICAgICBpZiAoZXhwbGFpbikge1xuICAgICAgICAgIHJldHVybiBvYmplY3RzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmplY3RzLm1hcChvYmplY3QgPT4gbW9uZ29PYmplY3RUb1BhcnNlT2JqZWN0KGNsYXNzTmFtZSwgb2JqZWN0LCBzY2hlbWEpKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBlbnN1cmVJbmRleChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgZmllbGROYW1lczogc3RyaW5nW10sXG4gICAgaW5kZXhOYW1lOiA/c3RyaW5nLFxuICAgIGNhc2VJbnNlbnNpdGl2ZTogYm9vbGVhbiA9IGZhbHNlLFxuICAgIG9wdGlvbnM/OiBPYmplY3QgPSB7fVxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBpbmRleENyZWF0aW9uUmVxdWVzdCA9IHt9O1xuICAgIGNvbnN0IG1vbmdvRmllbGROYW1lcyA9IGZpZWxkTmFtZXMubWFwKGZpZWxkTmFtZSA9PiB0cmFuc2Zvcm1LZXkoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHNjaGVtYSkpO1xuICAgIG1vbmdvRmllbGROYW1lcy5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICBpbmRleENyZWF0aW9uUmVxdWVzdFtmaWVsZE5hbWVdID0gb3B0aW9ucy5pbmRleFR5cGUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuaW5kZXhUeXBlIDogMTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGRlZmF1bHRPcHRpb25zOiBPYmplY3QgPSB7IGJhY2tncm91bmQ6IHRydWUsIHNwYXJzZTogdHJ1ZSB9O1xuICAgIGNvbnN0IGluZGV4TmFtZU9wdGlvbnM6IE9iamVjdCA9IGluZGV4TmFtZSA/IHsgbmFtZTogaW5kZXhOYW1lIH0gOiB7fTtcbiAgICBjb25zdCB0dGxPcHRpb25zOiBPYmplY3QgPSBvcHRpb25zLnR0bCAhPT0gdW5kZWZpbmVkID8geyBleHBpcmVBZnRlclNlY29uZHM6IG9wdGlvbnMudHRsIH0gOiB7fTtcbiAgICBjb25zdCBjYXNlSW5zZW5zaXRpdmVPcHRpb25zOiBPYmplY3QgPSBjYXNlSW5zZW5zaXRpdmVcbiAgICAgID8geyBjb2xsYXRpb246IE1vbmdvQ29sbGVjdGlvbi5jYXNlSW5zZW5zaXRpdmVDb2xsYXRpb24oKSB9XG4gICAgICA6IHt9O1xuICAgIGNvbnN0IGluZGV4T3B0aW9uczogT2JqZWN0ID0ge1xuICAgICAgLi4uZGVmYXVsdE9wdGlvbnMsXG4gICAgICAuLi5jYXNlSW5zZW5zaXRpdmVPcHRpb25zLFxuICAgICAgLi4uaW5kZXhOYW1lT3B0aW9ucyxcbiAgICAgIC4uLnR0bE9wdGlvbnMsXG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oXG4gICAgICAgIGNvbGxlY3Rpb24gPT5cbiAgICAgICAgICBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PlxuICAgICAgICAgICAgY29sbGVjdGlvbi5fbW9uZ29Db2xsZWN0aW9uLmNyZWF0ZUluZGV4KGluZGV4Q3JlYXRpb25SZXF1ZXN0LCBpbmRleE9wdGlvbnMsIGVycm9yID0+XG4gICAgICAgICAgICAgIGVycm9yID8gcmVqZWN0KGVycm9yKSA6IHJlc29sdmUoKVxuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgIClcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIENyZWF0ZSBhIHVuaXF1ZSBpbmRleC4gVW5pcXVlIGluZGV4ZXMgb24gbnVsbGFibGUgZmllbGRzIGFyZSBub3QgYWxsb3dlZC4gU2luY2Ugd2UgZG9uJ3RcbiAgLy8gY3VycmVudGx5IGtub3cgd2hpY2ggZmllbGRzIGFyZSBudWxsYWJsZSBhbmQgd2hpY2ggYXJlbid0LCB3ZSBpZ25vcmUgdGhhdCBjcml0ZXJpYS5cbiAgLy8gQXMgc3VjaCwgd2Ugc2hvdWxkbid0IGV4cG9zZSB0aGlzIGZ1bmN0aW9uIHRvIHVzZXJzIG9mIHBhcnNlIHVudGlsIHdlIGhhdmUgYW4gb3V0LW9mLWJhbmRcbiAgLy8gV2F5IG9mIGRldGVybWluaW5nIGlmIGEgZmllbGQgaXMgbnVsbGFibGUuIFVuZGVmaW5lZCBkb2Vzbid0IGNvdW50IGFnYWluc3QgdW5pcXVlbmVzcyxcbiAgLy8gd2hpY2ggaXMgd2h5IHdlIHVzZSBzcGFyc2UgaW5kZXhlcy5cbiAgZW5zdXJlVW5pcXVlbmVzcyhjbGFzc05hbWU6IHN0cmluZywgc2NoZW1hOiBTY2hlbWFUeXBlLCBmaWVsZE5hbWVzOiBzdHJpbmdbXSkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBpbmRleENyZWF0aW9uUmVxdWVzdCA9IHt9O1xuICAgIGNvbnN0IG1vbmdvRmllbGROYW1lcyA9IGZpZWxkTmFtZXMubWFwKGZpZWxkTmFtZSA9PiB0cmFuc2Zvcm1LZXkoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHNjaGVtYSkpO1xuICAgIG1vbmdvRmllbGROYW1lcy5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICBpbmRleENyZWF0aW9uUmVxdWVzdFtmaWVsZE5hbWVdID0gMTtcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5fZW5zdXJlU3BhcnNlVW5pcXVlSW5kZXhJbkJhY2tncm91bmQoaW5kZXhDcmVhdGlvblJlcXVlc3QpKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDExMDAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFLFxuICAgICAgICAgICAgJ1RyaWVkIHRvIGVuc3VyZSBmaWVsZCB1bmlxdWVuZXNzIGZvciBhIGNsYXNzIHRoYXQgYWxyZWFkeSBoYXMgZHVwbGljYXRlcy4nXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICAvLyBVc2VkIGluIHRlc3RzXG4gIF9yYXdGaW5kKGNsYXNzTmFtZTogc3RyaW5nLCBxdWVyeTogUXVlcnlUeXBlKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+XG4gICAgICAgIGNvbGxlY3Rpb24uZmluZChxdWVyeSwge1xuICAgICAgICAgIG1heFRpbWVNUzogdGhpcy5fbWF4VGltZU1TLFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gRXhlY3V0ZXMgYSBjb3VudC5cbiAgY291bnQoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIHF1ZXJ5OiBRdWVyeVR5cGUsXG4gICAgcmVhZFByZWZlcmVuY2U6ID9zdHJpbmcsXG4gICAgaGludDogP21peGVkXG4gICkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICByZWFkUHJlZmVyZW5jZSA9IHRoaXMuX3BhcnNlUmVhZFByZWZlcmVuY2UocmVhZFByZWZlcmVuY2UpO1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PlxuICAgICAgICBjb2xsZWN0aW9uLmNvdW50KHRyYW5zZm9ybVdoZXJlKGNsYXNzTmFtZSwgcXVlcnksIHNjaGVtYSwgdHJ1ZSksIHtcbiAgICAgICAgICBtYXhUaW1lTVM6IHRoaXMuX21heFRpbWVNUyxcbiAgICAgICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICBoaW50LFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgZGlzdGluY3QoY2xhc3NOYW1lOiBzdHJpbmcsIHNjaGVtYTogU2NoZW1hVHlwZSwgcXVlcnk6IFF1ZXJ5VHlwZSwgZmllbGROYW1lOiBzdHJpbmcpIHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgY29uc3QgaXNQb2ludGVyRmllbGQgPSBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiYgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdQb2ludGVyJztcbiAgICBjb25zdCB0cmFuc2Zvcm1GaWVsZCA9IHRyYW5zZm9ybUtleShjbGFzc05hbWUsIGZpZWxkTmFtZSwgc2NoZW1hKTtcblxuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PlxuICAgICAgICBjb2xsZWN0aW9uLmRpc3RpbmN0KHRyYW5zZm9ybUZpZWxkLCB0cmFuc2Zvcm1XaGVyZShjbGFzc05hbWUsIHF1ZXJ5LCBzY2hlbWEpKVxuICAgICAgKVxuICAgICAgLnRoZW4ob2JqZWN0cyA9PiB7XG4gICAgICAgIG9iamVjdHMgPSBvYmplY3RzLmZpbHRlcihvYmogPT4gb2JqICE9IG51bGwpO1xuICAgICAgICByZXR1cm4gb2JqZWN0cy5tYXAob2JqZWN0ID0+IHtcbiAgICAgICAgICBpZiAoaXNQb2ludGVyRmllbGQpIHtcbiAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1Qb2ludGVyU3RyaW5nKHNjaGVtYSwgZmllbGROYW1lLCBvYmplY3QpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbW9uZ29PYmplY3RUb1BhcnNlT2JqZWN0KGNsYXNzTmFtZSwgb2JqZWN0LCBzY2hlbWEpO1xuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBhZ2dyZWdhdGUoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBhbnksXG4gICAgcGlwZWxpbmU6IGFueSxcbiAgICByZWFkUHJlZmVyZW5jZTogP3N0cmluZyxcbiAgICBoaW50OiA/bWl4ZWQsXG4gICAgZXhwbGFpbj86IGJvb2xlYW5cbiAgKSB7XG4gICAgbGV0IGlzUG9pbnRlckZpZWxkID0gZmFsc2U7XG4gICAgcGlwZWxpbmUgPSBwaXBlbGluZS5tYXAoc3RhZ2UgPT4ge1xuICAgICAgaWYgKHN0YWdlLiRncm91cCkge1xuICAgICAgICBzdGFnZS4kZ3JvdXAgPSB0aGlzLl9wYXJzZUFnZ3JlZ2F0ZUdyb3VwQXJncyhzY2hlbWEsIHN0YWdlLiRncm91cCk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBzdGFnZS4kZ3JvdXAuX2lkICYmXG4gICAgICAgICAgdHlwZW9mIHN0YWdlLiRncm91cC5faWQgPT09ICdzdHJpbmcnICYmXG4gICAgICAgICAgc3RhZ2UuJGdyb3VwLl9pZC5pbmRleE9mKCckX3BfJykgPj0gMFxuICAgICAgICApIHtcbiAgICAgICAgICBpc1BvaW50ZXJGaWVsZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChzdGFnZS4kbWF0Y2gpIHtcbiAgICAgICAgc3RhZ2UuJG1hdGNoID0gdGhpcy5fcGFyc2VBZ2dyZWdhdGVBcmdzKHNjaGVtYSwgc3RhZ2UuJG1hdGNoKTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFnZS4kcHJvamVjdCkge1xuICAgICAgICBzdGFnZS4kcHJvamVjdCA9IHRoaXMuX3BhcnNlQWdncmVnYXRlUHJvamVjdEFyZ3Moc2NoZW1hLCBzdGFnZS4kcHJvamVjdCk7XG4gICAgICB9XG4gICAgICBpZiAoc3RhZ2UuJGdlb05lYXIgJiYgc3RhZ2UuJGdlb05lYXIucXVlcnkpIHtcbiAgICAgICAgc3RhZ2UuJGdlb05lYXIucXVlcnkgPSB0aGlzLl9wYXJzZUFnZ3JlZ2F0ZUFyZ3Moc2NoZW1hLCBzdGFnZS4kZ2VvTmVhci5xdWVyeSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gc3RhZ2U7XG4gICAgfSk7XG4gICAgcmVhZFByZWZlcmVuY2UgPSB0aGlzLl9wYXJzZVJlYWRQcmVmZXJlbmNlKHJlYWRQcmVmZXJlbmNlKTtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT5cbiAgICAgICAgY29sbGVjdGlvbi5hZ2dyZWdhdGUocGlwZWxpbmUsIHtcbiAgICAgICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICBtYXhUaW1lTVM6IHRoaXMuX21heFRpbWVNUyxcbiAgICAgICAgICBoaW50LFxuICAgICAgICAgIGV4cGxhaW4sXG4gICAgICAgIH0pXG4gICAgICApXG4gICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgcmVzdWx0cy5mb3JFYWNoKHJlc3VsdCA9PiB7XG4gICAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChyZXN1bHQsICdfaWQnKSkge1xuICAgICAgICAgICAgaWYgKGlzUG9pbnRlckZpZWxkICYmIHJlc3VsdC5faWQpIHtcbiAgICAgICAgICAgICAgcmVzdWx0Ll9pZCA9IHJlc3VsdC5faWQuc3BsaXQoJyQnKVsxXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgcmVzdWx0Ll9pZCA9PSBudWxsIHx8XG4gICAgICAgICAgICAgIHJlc3VsdC5faWQgPT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgICAgIChbJ29iamVjdCcsICdzdHJpbmcnXS5pbmNsdWRlcyh0eXBlb2YgcmVzdWx0Ll9pZCkgJiYgXy5pc0VtcHR5KHJlc3VsdC5faWQpKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5faWQgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzdWx0Lm9iamVjdElkID0gcmVzdWx0Ll9pZDtcbiAgICAgICAgICAgIGRlbGV0ZSByZXN1bHQuX2lkO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgfSlcbiAgICAgIC50aGVuKG9iamVjdHMgPT4gb2JqZWN0cy5tYXAob2JqZWN0ID0+IG1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdChjbGFzc05hbWUsIG9iamVjdCwgc2NoZW1hKSkpXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICAvLyBUaGlzIGZ1bmN0aW9uIHdpbGwgcmVjdXJzaXZlbHkgdHJhdmVyc2UgdGhlIHBpcGVsaW5lIGFuZCBjb252ZXJ0IGFueSBQb2ludGVyIG9yIERhdGUgY29sdW1ucy5cbiAgLy8gSWYgd2UgZGV0ZWN0IGEgcG9pbnRlciBjb2x1bW4gd2Ugd2lsbCByZW5hbWUgdGhlIGNvbHVtbiBiZWluZyBxdWVyaWVkIGZvciB0byBtYXRjaCB0aGUgY29sdW1uXG4gIC8vIGluIHRoZSBkYXRhYmFzZS4gV2UgYWxzbyBtb2RpZnkgdGhlIHZhbHVlIHRvIHdoYXQgd2UgZXhwZWN0IHRoZSB2YWx1ZSB0byBiZSBpbiB0aGUgZGF0YWJhc2VcbiAgLy8gYXMgd2VsbC5cbiAgLy8gRm9yIGRhdGVzLCB0aGUgZHJpdmVyIGV4cGVjdHMgYSBEYXRlIG9iamVjdCwgYnV0IHdlIGhhdmUgYSBzdHJpbmcgY29taW5nIGluLiBTbyB3ZSdsbCBjb252ZXJ0XG4gIC8vIHRoZSBzdHJpbmcgdG8gYSBEYXRlIHNvIHRoZSBkcml2ZXIgY2FuIHBlcmZvcm0gdGhlIG5lY2Vzc2FyeSBjb21wYXJpc29uLlxuICAvL1xuICAvLyBUaGUgZ29hbCBvZiB0aGlzIG1ldGhvZCBpcyB0byBsb29rIGZvciB0aGUgXCJsZWF2ZXNcIiBvZiB0aGUgcGlwZWxpbmUgYW5kIGRldGVybWluZSBpZiBpdCBuZWVkc1xuICAvLyB0byBiZSBjb252ZXJ0ZWQuIFRoZSBwaXBlbGluZSBjYW4gaGF2ZSBhIGZldyBkaWZmZXJlbnQgZm9ybXMuIEZvciBtb3JlIGRldGFpbHMsIHNlZTpcbiAgLy8gICAgIGh0dHBzOi8vZG9jcy5tb25nb2RiLmNvbS9tYW51YWwvcmVmZXJlbmNlL29wZXJhdG9yL2FnZ3JlZ2F0aW9uL1xuICAvL1xuICAvLyBJZiB0aGUgcGlwZWxpbmUgaXMgYW4gYXJyYXksIGl0IG1lYW5zIHdlIGFyZSBwcm9iYWJseSBwYXJzaW5nIGFuICckYW5kJyBvciAnJG9yJyBvcGVyYXRvci4gSW5cbiAgLy8gdGhhdCBjYXNlIHdlIG5lZWQgdG8gbG9vcCB0aHJvdWdoIGFsbCBvZiBpdCdzIGNoaWxkcmVuIHRvIGZpbmQgdGhlIGNvbHVtbnMgYmVpbmcgb3BlcmF0ZWQgb24uXG4gIC8vIElmIHRoZSBwaXBlbGluZSBpcyBhbiBvYmplY3QsIHRoZW4gd2UnbGwgbG9vcCB0aHJvdWdoIHRoZSBrZXlzIGNoZWNraW5nIHRvIHNlZSBpZiB0aGUga2V5IG5hbWVcbiAgLy8gbWF0Y2hlcyBvbmUgb2YgdGhlIHNjaGVtYSBjb2x1bW5zLiBJZiBpdCBkb2VzIG1hdGNoIGEgY29sdW1uIGFuZCB0aGUgY29sdW1uIGlzIGEgUG9pbnRlciBvclxuICAvLyBhIERhdGUsIHRoZW4gd2UnbGwgY29udmVydCB0aGUgdmFsdWUgYXMgZGVzY3JpYmVkIGFib3ZlLlxuICAvL1xuICAvLyBBcyBtdWNoIGFzIEkgaGF0ZSByZWN1cnNpb24uLi50aGlzIHNlZW1lZCBsaWtlIGEgZ29vZCBmaXQgZm9yIGl0LiBXZSdyZSBlc3NlbnRpYWxseSB0cmF2ZXJzaW5nXG4gIC8vIGRvd24gYSB0cmVlIHRvIGZpbmQgYSBcImxlYWYgbm9kZVwiIGFuZCBjaGVja2luZyB0byBzZWUgaWYgaXQgbmVlZHMgdG8gYmUgY29udmVydGVkLlxuICBfcGFyc2VBZ2dyZWdhdGVBcmdzKHNjaGVtYTogYW55LCBwaXBlbGluZTogYW55KTogYW55IHtcbiAgICBpZiAocGlwZWxpbmUgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShwaXBlbGluZSkpIHtcbiAgICAgIHJldHVybiBwaXBlbGluZS5tYXAodmFsdWUgPT4gdGhpcy5fcGFyc2VBZ2dyZWdhdGVBcmdzKHNjaGVtYSwgdmFsdWUpKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBwaXBlbGluZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGNvbnN0IHJldHVyblZhbHVlID0ge307XG4gICAgICBmb3IgKGNvbnN0IGZpZWxkIGluIHBpcGVsaW5lKSB7XG4gICAgICAgIGlmIChzY2hlbWEuZmllbGRzW2ZpZWxkXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIHBpcGVsaW5lW2ZpZWxkXSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIC8vIFBhc3Mgb2JqZWN0cyBkb3duIHRvIE1vbmdvREIuLi50aGlzIGlzIG1vcmUgdGhhbiBsaWtlbHkgYW4gJGV4aXN0cyBvcGVyYXRvci5cbiAgICAgICAgICAgIHJldHVyblZhbHVlW2BfcF8ke2ZpZWxkfWBdID0gcGlwZWxpbmVbZmllbGRdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZVtgX3BfJHtmaWVsZH1gXSA9IGAke3NjaGVtYS5maWVsZHNbZmllbGRdLnRhcmdldENsYXNzfSQke3BpcGVsaW5lW2ZpZWxkXX1gO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChzY2hlbWEuZmllbGRzW2ZpZWxkXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnRGF0ZScpIHtcbiAgICAgICAgICByZXR1cm5WYWx1ZVtmaWVsZF0gPSB0aGlzLl9jb252ZXJ0VG9EYXRlKHBpcGVsaW5lW2ZpZWxkXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuVmFsdWVbZmllbGRdID0gdGhpcy5fcGFyc2VBZ2dyZWdhdGVBcmdzKHNjaGVtYSwgcGlwZWxpbmVbZmllbGRdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmaWVsZCA9PT0gJ29iamVjdElkJykge1xuICAgICAgICAgIHJldHVyblZhbHVlWydfaWQnXSA9IHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgICAgICBkZWxldGUgcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgICB9IGVsc2UgaWYgKGZpZWxkID09PSAnY3JlYXRlZEF0Jykge1xuICAgICAgICAgIHJldHVyblZhbHVlWydfY3JlYXRlZF9hdCddID0gcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgICAgIGRlbGV0ZSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICAgIH0gZWxzZSBpZiAoZmllbGQgPT09ICd1cGRhdGVkQXQnKSB7XG4gICAgICAgICAgcmV0dXJuVmFsdWVbJ191cGRhdGVkX2F0J10gPSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICAgICAgZGVsZXRlIHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gcGlwZWxpbmU7XG4gIH1cblxuICAvLyBUaGlzIGZ1bmN0aW9uIGlzIHNsaWdodGx5IGRpZmZlcmVudCB0aGFuIHRoZSBvbmUgYWJvdmUuIFJhdGhlciB0aGFuIHRyeWluZyB0byBjb21iaW5lIHRoZXNlXG4gIC8vIHR3byBmdW5jdGlvbnMgYW5kIG1ha2luZyB0aGUgY29kZSBldmVuIGhhcmRlciB0byB1bmRlcnN0YW5kLCBJIGRlY2lkZWQgdG8gc3BsaXQgaXQgdXAuIFRoZVxuICAvLyBkaWZmZXJlbmNlIHdpdGggdGhpcyBmdW5jdGlvbiBpcyB3ZSBhcmUgbm90IHRyYW5zZm9ybWluZyB0aGUgdmFsdWVzLCBvbmx5IHRoZSBrZXlzIG9mIHRoZVxuICAvLyBwaXBlbGluZS5cbiAgX3BhcnNlQWdncmVnYXRlUHJvamVjdEFyZ3Moc2NoZW1hOiBhbnksIHBpcGVsaW5lOiBhbnkpOiBhbnkge1xuICAgIGNvbnN0IHJldHVyblZhbHVlID0ge307XG4gICAgZm9yIChjb25zdCBmaWVsZCBpbiBwaXBlbGluZSkge1xuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGRdICYmIHNjaGVtYS5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgICByZXR1cm5WYWx1ZVtgX3BfJHtmaWVsZH1gXSA9IHBpcGVsaW5lW2ZpZWxkXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVyblZhbHVlW2ZpZWxkXSA9IHRoaXMuX3BhcnNlQWdncmVnYXRlQXJncyhzY2hlbWEsIHBpcGVsaW5lW2ZpZWxkXSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChmaWVsZCA9PT0gJ29iamVjdElkJykge1xuICAgICAgICByZXR1cm5WYWx1ZVsnX2lkJ10gPSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICAgIGRlbGV0ZSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkID09PSAnY3JlYXRlZEF0Jykge1xuICAgICAgICByZXR1cm5WYWx1ZVsnX2NyZWF0ZWRfYXQnXSA9IHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgICAgZGVsZXRlIHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGQgPT09ICd1cGRhdGVkQXQnKSB7XG4gICAgICAgIHJldHVyblZhbHVlWydfdXBkYXRlZF9hdCddID0gcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgICBkZWxldGUgcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gIH1cblxuICAvLyBUaGlzIGZ1bmN0aW9uIGlzIHNsaWdodGx5IGRpZmZlcmVudCB0aGFuIHRoZSB0d28gYWJvdmUuIE1vbmdvREIgJGdyb3VwIGFnZ3JlZ2F0ZSBsb29rcyBsaWtlOlxuICAvLyAgICAgeyAkZ3JvdXA6IHsgX2lkOiA8ZXhwcmVzc2lvbj4sIDxmaWVsZDE+OiB7IDxhY2N1bXVsYXRvcjE+IDogPGV4cHJlc3Npb24xPiB9LCAuLi4gfSB9XG4gIC8vIFRoZSA8ZXhwcmVzc2lvbj4gY291bGQgYmUgYSBjb2x1bW4gbmFtZSwgcHJlZml4ZWQgd2l0aCB0aGUgJyQnIGNoYXJhY3Rlci4gV2UnbGwgbG9vayBmb3JcbiAgLy8gdGhlc2UgPGV4cHJlc3Npb24+IGFuZCBjaGVjayB0byBzZWUgaWYgaXQgaXMgYSAnUG9pbnRlcicgb3IgaWYgaXQncyBvbmUgb2YgY3JlYXRlZEF0LFxuICAvLyB1cGRhdGVkQXQgb3Igb2JqZWN0SWQgYW5kIGNoYW5nZSBpdCBhY2NvcmRpbmdseS5cbiAgX3BhcnNlQWdncmVnYXRlR3JvdXBBcmdzKHNjaGVtYTogYW55LCBwaXBlbGluZTogYW55KTogYW55IHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShwaXBlbGluZSkpIHtcbiAgICAgIHJldHVybiBwaXBlbGluZS5tYXAodmFsdWUgPT4gdGhpcy5fcGFyc2VBZ2dyZWdhdGVHcm91cEFyZ3Moc2NoZW1hLCB2YWx1ZSkpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHBpcGVsaW5lID09PSAnb2JqZWN0Jykge1xuICAgICAgY29uc3QgcmV0dXJuVmFsdWUgPSB7fTtcbiAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gcGlwZWxpbmUpIHtcbiAgICAgICAgcmV0dXJuVmFsdWVbZmllbGRdID0gdGhpcy5fcGFyc2VBZ2dyZWdhdGVHcm91cEFyZ3Moc2NoZW1hLCBwaXBlbGluZVtmaWVsZF0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHBpcGVsaW5lID09PSAnc3RyaW5nJykge1xuICAgICAgY29uc3QgZmllbGQgPSBwaXBlbGluZS5zdWJzdHJpbmcoMSk7XG4gICAgICBpZiAoc2NoZW1hLmZpZWxkc1tmaWVsZF0gJiYgc2NoZW1hLmZpZWxkc1tmaWVsZF0udHlwZSA9PT0gJ1BvaW50ZXInKSB7XG4gICAgICAgIHJldHVybiBgJF9wXyR7ZmllbGR9YDtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGQgPT0gJ2NyZWF0ZWRBdCcpIHtcbiAgICAgICAgcmV0dXJuICckX2NyZWF0ZWRfYXQnO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZCA9PSAndXBkYXRlZEF0Jykge1xuICAgICAgICByZXR1cm4gJyRfdXBkYXRlZF9hdCc7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwaXBlbGluZTtcbiAgfVxuXG4gIC8vIFRoaXMgZnVuY3Rpb24gd2lsbCBhdHRlbXB0IHRvIGNvbnZlcnQgdGhlIHByb3ZpZGVkIHZhbHVlIHRvIGEgRGF0ZSBvYmplY3QuIFNpbmNlIHRoaXMgaXMgcGFydFxuICAvLyBvZiBhbiBhZ2dyZWdhdGlvbiBwaXBlbGluZSwgdGhlIHZhbHVlIGNhbiBlaXRoZXIgYmUgYSBzdHJpbmcgb3IgaXQgY2FuIGJlIGFub3RoZXIgb2JqZWN0IHdpdGhcbiAgLy8gYW4gb3BlcmF0b3IgaW4gaXQgKGxpa2UgJGd0LCAkbHQsIGV0YykuIEJlY2F1c2Ugb2YgdGhpcyBJIGZlbHQgaXQgd2FzIGVhc2llciB0byBtYWtlIHRoaXMgYVxuICAvLyByZWN1cnNpdmUgbWV0aG9kIHRvIHRyYXZlcnNlIGRvd24gdG8gdGhlIFwibGVhZiBub2RlXCIgd2hpY2ggaXMgZ29pbmcgdG8gYmUgdGhlIHN0cmluZy5cbiAgX2NvbnZlcnRUb0RhdGUodmFsdWU6IGFueSk6IGFueSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgY29uc3QgcmV0dXJuVmFsdWUgPSB7fTtcbiAgICBmb3IgKGNvbnN0IGZpZWxkIGluIHZhbHVlKSB7XG4gICAgICByZXR1cm5WYWx1ZVtmaWVsZF0gPSB0aGlzLl9jb252ZXJ0VG9EYXRlKHZhbHVlW2ZpZWxkXSk7XG4gICAgfVxuICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgfVxuXG4gIF9wYXJzZVJlYWRQcmVmZXJlbmNlKHJlYWRQcmVmZXJlbmNlOiA/c3RyaW5nKTogP3N0cmluZyB7XG4gICAgaWYgKHJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICByZWFkUHJlZmVyZW5jZSA9IHJlYWRQcmVmZXJlbmNlLnRvVXBwZXJDYXNlKCk7XG4gICAgfVxuICAgIHN3aXRjaCAocmVhZFByZWZlcmVuY2UpIHtcbiAgICAgIGNhc2UgJ1BSSU1BUlknOlxuICAgICAgICByZWFkUHJlZmVyZW5jZSA9IFJlYWRQcmVmZXJlbmNlLlBSSU1BUlk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnUFJJTUFSWV9QUkVGRVJSRUQnOlxuICAgICAgICByZWFkUHJlZmVyZW5jZSA9IFJlYWRQcmVmZXJlbmNlLlBSSU1BUllfUFJFRkVSUkVEO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ1NFQ09OREFSWSc6XG4gICAgICAgIHJlYWRQcmVmZXJlbmNlID0gUmVhZFByZWZlcmVuY2UuU0VDT05EQVJZO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ1NFQ09OREFSWV9QUkVGRVJSRUQnOlxuICAgICAgICByZWFkUHJlZmVyZW5jZSA9IFJlYWRQcmVmZXJlbmNlLlNFQ09OREFSWV9QUkVGRVJSRUQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnTkVBUkVTVCc6XG4gICAgICAgIHJlYWRQcmVmZXJlbmNlID0gUmVhZFByZWZlcmVuY2UuTkVBUkVTVDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIHVuZGVmaW5lZDpcbiAgICAgIGNhc2UgbnVsbDpcbiAgICAgIGNhc2UgJyc6XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksICdOb3Qgc3VwcG9ydGVkIHJlYWQgcHJlZmVyZW5jZS4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlYWRQcmVmZXJlbmNlO1xuICB9XG5cbiAgcGVyZm9ybUluaXRpYWxpemF0aW9uKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGNyZWF0ZUluZGV4KGNsYXNzTmFtZTogc3RyaW5nLCBpbmRleDogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24uX21vbmdvQ29sbGVjdGlvbi5jcmVhdGVJbmRleChpbmRleCkpXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBjcmVhdGVJbmRleGVzKGNsYXNzTmFtZTogc3RyaW5nLCBpbmRleGVzOiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5fbW9uZ29Db2xsZWN0aW9uLmNyZWF0ZUluZGV4ZXMoaW5kZXhlcykpXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBjcmVhdGVJbmRleGVzSWZOZWVkZWQoY2xhc3NOYW1lOiBzdHJpbmcsIGZpZWxkTmFtZTogc3RyaW5nLCB0eXBlOiBhbnkpIHtcbiAgICBpZiAodHlwZSAmJiB0eXBlLnR5cGUgPT09ICdQb2x5Z29uJykge1xuICAgICAgY29uc3QgaW5kZXggPSB7XG4gICAgICAgIFtmaWVsZE5hbWVdOiAnMmRzcGhlcmUnLFxuICAgICAgfTtcbiAgICAgIHJldHVybiB0aGlzLmNyZWF0ZUluZGV4KGNsYXNzTmFtZSwgaW5kZXgpO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBjcmVhdGVUZXh0SW5kZXhlc0lmTmVlZGVkKGNsYXNzTmFtZTogc3RyaW5nLCBxdWVyeTogUXVlcnlUeXBlLCBzY2hlbWE6IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGZvciAoY29uc3QgZmllbGROYW1lIGluIHF1ZXJ5KSB7XG4gICAgICBpZiAoIXF1ZXJ5W2ZpZWxkTmFtZV0gfHwgIXF1ZXJ5W2ZpZWxkTmFtZV0uJHRleHQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBleGlzdGluZ0luZGV4ZXMgPSBzY2hlbWEuaW5kZXhlcztcbiAgICAgIGZvciAoY29uc3Qga2V5IGluIGV4aXN0aW5nSW5kZXhlcykge1xuICAgICAgICBjb25zdCBpbmRleCA9IGV4aXN0aW5nSW5kZXhlc1trZXldO1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGluZGV4LCBmaWVsZE5hbWUpKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCBpbmRleE5hbWUgPSBgJHtmaWVsZE5hbWV9X3RleHRgO1xuICAgICAgY29uc3QgdGV4dEluZGV4ID0ge1xuICAgICAgICBbaW5kZXhOYW1lXTogeyBbZmllbGROYW1lXTogJ3RleHQnIH0sXG4gICAgICB9O1xuICAgICAgcmV0dXJuIHRoaXMuc2V0SW5kZXhlc1dpdGhTY2hlbWFGb3JtYXQoXG4gICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgdGV4dEluZGV4LFxuICAgICAgICBleGlzdGluZ0luZGV4ZXMsXG4gICAgICAgIHNjaGVtYS5maWVsZHNcbiAgICAgICkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gODUpIHtcbiAgICAgICAgICAvLyBJbmRleCBleGlzdCB3aXRoIGRpZmZlcmVudCBvcHRpb25zXG4gICAgICAgICAgcmV0dXJuIHRoaXMuc2V0SW5kZXhlc0Zyb21Nb25nbyhjbGFzc05hbWUpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGdldEluZGV4ZXMoY2xhc3NOYW1lOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5fbW9uZ29Db2xsZWN0aW9uLmluZGV4ZXMoKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIGRyb3BJbmRleChjbGFzc05hbWU6IHN0cmluZywgaW5kZXg6IGFueSkge1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLl9tb25nb0NvbGxlY3Rpb24uZHJvcEluZGV4KGluZGV4KSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIGRyb3BBbGxJbmRleGVzKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24uX21vbmdvQ29sbGVjdGlvbi5kcm9wSW5kZXhlcygpKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgdXBkYXRlU2NoZW1hV2l0aEluZGV4ZXMoKTogUHJvbWlzZTxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy5nZXRBbGxDbGFzc2VzKClcbiAgICAgIC50aGVuKGNsYXNzZXMgPT4ge1xuICAgICAgICBjb25zdCBwcm9taXNlcyA9IGNsYXNzZXMubWFwKHNjaGVtYSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuc2V0SW5kZXhlc0Zyb21Nb25nbyhzY2hlbWEuY2xhc3NOYW1lKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgY3JlYXRlVHJhbnNhY3Rpb25hbFNlc3Npb24oKTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCB0cmFuc2FjdGlvbmFsU2VjdGlvbiA9IHRoaXMuY2xpZW50LnN0YXJ0U2Vzc2lvbigpO1xuICAgIHRyYW5zYWN0aW9uYWxTZWN0aW9uLnN0YXJ0VHJhbnNhY3Rpb24oKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRyYW5zYWN0aW9uYWxTZWN0aW9uKTtcbiAgfVxuXG4gIGNvbW1pdFRyYW5zYWN0aW9uYWxTZXNzaW9uKHRyYW5zYWN0aW9uYWxTZWN0aW9uOiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdHJhbnNhY3Rpb25hbFNlY3Rpb24uY29tbWl0VHJhbnNhY3Rpb24oKS50aGVuKCgpID0+IHtcbiAgICAgIHRyYW5zYWN0aW9uYWxTZWN0aW9uLmVuZFNlc3Npb24oKTtcbiAgICB9KTtcbiAgfVxuXG4gIGFib3J0VHJhbnNhY3Rpb25hbFNlc3Npb24odHJhbnNhY3Rpb25hbFNlY3Rpb246IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0cmFuc2FjdGlvbmFsU2VjdGlvbi5hYm9ydFRyYW5zYWN0aW9uKCkudGhlbigoKSA9PiB7XG4gICAgICB0cmFuc2FjdGlvbmFsU2VjdGlvbi5lbmRTZXNzaW9uKCk7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTW9uZ29TdG9yYWdlQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Storage/Mongo/MongoTransform.js b/lib/Adapters/Storage/Mongo/MongoTransform.js new file mode 100644 index 0000000000..1c9a5dd201 --- /dev/null +++ b/lib/Adapters/Storage/Mongo/MongoTransform.js @@ -0,0 +1,1795 @@ +"use strict"; + +var _logger = _interopRequireDefault(require("../../../logger")); + +var _lodash = _interopRequireDefault(require("lodash")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var mongodb = require('mongodb'); + +var Parse = require('parse/node').Parse; + +const transformKey = (className, fieldName, schema) => { + // Check if the schema is known since it's a built-in field. + switch (fieldName) { + case 'objectId': + return '_id'; + + case 'createdAt': + return '_created_at'; + + case 'updatedAt': + return '_updated_at'; + + case 'sessionToken': + return '_session_token'; + + case 'lastUsed': + return '_last_used'; + + case 'timesUsed': + return 'times_used'; + } + + if (schema.fields[fieldName] && schema.fields[fieldName].__type == 'Pointer') { + fieldName = '_p_' + fieldName; + } else if (schema.fields[fieldName] && schema.fields[fieldName].type == 'Pointer') { + fieldName = '_p_' + fieldName; + } + + return fieldName; +}; + +const transformKeyValueForUpdate = (className, restKey, restValue, parseFormatSchema) => { + // Check if the schema is known since it's a built-in field. + var key = restKey; + var timeField = false; + + switch (key) { + case 'objectId': + case '_id': + if (['_GlobalConfig', '_GraphQLConfig'].includes(className)) { + return { + key: key, + value: parseInt(restValue) + }; + } + + key = '_id'; + break; + + case 'createdAt': + case '_created_at': + key = '_created_at'; + timeField = true; + break; + + case 'updatedAt': + case '_updated_at': + key = '_updated_at'; + timeField = true; + break; + + case 'sessionToken': + case '_session_token': + key = '_session_token'; + break; + + case 'expiresAt': + case '_expiresAt': + key = 'expiresAt'; + timeField = true; + break; + + case '_email_verify_token_expires_at': + key = '_email_verify_token_expires_at'; + timeField = true; + break; + + case '_account_lockout_expires_at': + key = '_account_lockout_expires_at'; + timeField = true; + break; + + case '_failed_login_count': + key = '_failed_login_count'; + break; + + case '_perishable_token_expires_at': + key = '_perishable_token_expires_at'; + timeField = true; + break; + + case '_password_changed_at': + key = '_password_changed_at'; + timeField = true; + break; + + case '_rperm': + case '_wperm': + return { + key: key, + value: restValue + }; + + case 'lastUsed': + case '_last_used': + key = '_last_used'; + timeField = true; + break; + + case 'timesUsed': + case 'times_used': + key = 'times_used'; + timeField = true; + break; + } + + if (parseFormatSchema.fields[key] && parseFormatSchema.fields[key].type === 'Pointer' || !parseFormatSchema.fields[key] && restValue && restValue.__type == 'Pointer') { + key = '_p_' + key; + } // Handle atomic values + + + var value = transformTopLevelAtom(restValue); + + if (value !== CannotTransform) { + if (timeField && typeof value === 'string') { + value = new Date(value); + } + + if (restKey.indexOf('.') > 0) { + return { + key, + value: restValue + }; + } + + return { + key, + value + }; + } // Handle arrays + + + if (restValue instanceof Array) { + value = restValue.map(transformInteriorValue); + return { + key, + value + }; + } // Handle update operators + + + if (typeof restValue === 'object' && '__op' in restValue) { + return { + key, + value: transformUpdateOperator(restValue, false) + }; + } // Handle normal objects by recursing + + + value = mapValues(restValue, transformInteriorValue); + return { + key, + value + }; +}; + +const isRegex = value => { + return value && value instanceof RegExp; +}; + +const isStartsWithRegex = value => { + if (!isRegex(value)) { + return false; + } + + const matches = value.toString().match(/\/\^\\Q.*\\E\//); + return !!matches; +}; + +const isAllValuesRegexOrNone = values => { + if (!values || !Array.isArray(values) || values.length === 0) { + return true; + } + + const firstValuesIsRegex = isStartsWithRegex(values[0]); + + if (values.length === 1) { + return firstValuesIsRegex; + } + + for (let i = 1, length = values.length; i < length; ++i) { + if (firstValuesIsRegex !== isStartsWithRegex(values[i])) { + return false; + } + } + + return true; +}; + +const isAnyValueRegex = values => { + return values.some(function (value) { + return isRegex(value); + }); +}; + +const transformInteriorValue = restValue => { + if (restValue !== null && typeof restValue === 'object' && Object.keys(restValue).some(key => key.includes('$') || key.includes('.'))) { + throw new Parse.Error(Parse.Error.INVALID_NESTED_KEY, "Nested keys should not contain the '$' or '.' characters"); + } // Handle atomic values + + + var value = transformInteriorAtom(restValue); + + if (value !== CannotTransform) { + return value; + } // Handle arrays + + + if (restValue instanceof Array) { + return restValue.map(transformInteriorValue); + } // Handle update operators + + + if (typeof restValue === 'object' && '__op' in restValue) { + return transformUpdateOperator(restValue, true); + } // Handle normal objects by recursing + + + return mapValues(restValue, transformInteriorValue); +}; + +const valueAsDate = value => { + if (typeof value === 'string') { + return new Date(value); + } else if (value instanceof Date) { + return value; + } + + return false; +}; + +function transformQueryKeyValue(className, key, value, schema, count = false) { + switch (key) { + case 'createdAt': + if (valueAsDate(value)) { + return { + key: '_created_at', + value: valueAsDate(value) + }; + } + + key = '_created_at'; + break; + + case 'updatedAt': + if (valueAsDate(value)) { + return { + key: '_updated_at', + value: valueAsDate(value) + }; + } + + key = '_updated_at'; + break; + + case 'expiresAt': + if (valueAsDate(value)) { + return { + key: 'expiresAt', + value: valueAsDate(value) + }; + } + + break; + + case '_email_verify_token_expires_at': + if (valueAsDate(value)) { + return { + key: '_email_verify_token_expires_at', + value: valueAsDate(value) + }; + } + + break; + + case 'objectId': + { + if (['_GlobalConfig', '_GraphQLConfig'].includes(className)) { + value = parseInt(value); + } + + return { + key: '_id', + value + }; + } + + case '_account_lockout_expires_at': + if (valueAsDate(value)) { + return { + key: '_account_lockout_expires_at', + value: valueAsDate(value) + }; + } + + break; + + case '_failed_login_count': + return { + key, + value + }; + + case 'sessionToken': + return { + key: '_session_token', + value + }; + + case '_perishable_token_expires_at': + if (valueAsDate(value)) { + return { + key: '_perishable_token_expires_at', + value: valueAsDate(value) + }; + } + + break; + + case '_password_changed_at': + if (valueAsDate(value)) { + return { + key: '_password_changed_at', + value: valueAsDate(value) + }; + } + + break; + + case '_rperm': + case '_wperm': + case '_perishable_token': + case '_email_verify_token': + return { + key, + value + }; + + case '$or': + case '$and': + case '$nor': + return { + key: key, + value: value.map(subQuery => transformWhere(className, subQuery, schema, count)) + }; + + case 'lastUsed': + if (valueAsDate(value)) { + return { + key: '_last_used', + value: valueAsDate(value) + }; + } + + key = '_last_used'; + break; + + case 'timesUsed': + return { + key: 'times_used', + value: value + }; + + default: + { + // Other auth data + const authDataMatch = key.match(/^authData\.([a-zA-Z0-9_]+)\.id$/); + + if (authDataMatch) { + const provider = authDataMatch[1]; // Special-case auth data. + + return { + key: `_auth_data_${provider}.id`, + value + }; + } + } + } + + const expectedTypeIsArray = schema && schema.fields[key] && schema.fields[key].type === 'Array'; + const expectedTypeIsPointer = schema && schema.fields[key] && schema.fields[key].type === 'Pointer'; + const field = schema && schema.fields[key]; + + if (expectedTypeIsPointer || !schema && value && value.__type === 'Pointer') { + key = '_p_' + key; + } // Handle query constraints + + + const transformedConstraint = transformConstraint(value, field, count); + + if (transformedConstraint !== CannotTransform) { + if (transformedConstraint.$text) { + return { + key: '$text', + value: transformedConstraint.$text + }; + } + + if (transformedConstraint.$elemMatch) { + return { + key: '$nor', + value: [{ + [key]: transformedConstraint + }] + }; + } + + return { + key, + value: transformedConstraint + }; + } + + if (expectedTypeIsArray && !(value instanceof Array)) { + return { + key, + value: { + $all: [transformInteriorAtom(value)] + } + }; + } // Handle atomic values + + + if (transformTopLevelAtom(value) !== CannotTransform) { + return { + key, + value: transformTopLevelAtom(value) + }; + } else { + throw new Parse.Error(Parse.Error.INVALID_JSON, `You cannot use ${value} as a query parameter.`); + } +} // Main exposed method to help run queries. +// restWhere is the "where" clause in REST API form. +// Returns the mongo form of the query. + + +function transformWhere(className, restWhere, schema, count = false) { + const mongoWhere = {}; + + for (const restKey in restWhere) { + const out = transformQueryKeyValue(className, restKey, restWhere[restKey], schema, count); + mongoWhere[out.key] = out.value; + } + + return mongoWhere; +} + +const parseObjectKeyValueToMongoObjectKeyValue = (restKey, restValue, schema) => { + // Check if the schema is known since it's a built-in field. + let transformedValue; + let coercedToDate; + + switch (restKey) { + case 'objectId': + return { + key: '_id', + value: restValue + }; + + case 'expiresAt': + transformedValue = transformTopLevelAtom(restValue); + coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; + return { + key: 'expiresAt', + value: coercedToDate + }; + + case '_email_verify_token_expires_at': + transformedValue = transformTopLevelAtom(restValue); + coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; + return { + key: '_email_verify_token_expires_at', + value: coercedToDate + }; + + case '_account_lockout_expires_at': + transformedValue = transformTopLevelAtom(restValue); + coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; + return { + key: '_account_lockout_expires_at', + value: coercedToDate + }; + + case '_perishable_token_expires_at': + transformedValue = transformTopLevelAtom(restValue); + coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; + return { + key: '_perishable_token_expires_at', + value: coercedToDate + }; + + case '_password_changed_at': + transformedValue = transformTopLevelAtom(restValue); + coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; + return { + key: '_password_changed_at', + value: coercedToDate + }; + + case '_failed_login_count': + case '_rperm': + case '_wperm': + case '_email_verify_token': + case '_hashed_password': + case '_perishable_token': + return { + key: restKey, + value: restValue + }; + + case 'sessionToken': + return { + key: '_session_token', + value: restValue + }; + + default: + // Auth data should have been transformed already + if (restKey.match(/^authData\.([a-zA-Z0-9_]+)\.id$/)) { + throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'can only query on ' + restKey); + } // Trust that the auth data has been transformed and save it directly + + + if (restKey.match(/^_auth_data_[a-zA-Z0-9_]+$/)) { + return { + key: restKey, + value: restValue + }; + } + + } //skip straight to transformTopLevelAtom for Bytes, they don't show up in the schema for some reason + + + if (restValue && restValue.__type !== 'Bytes') { + //Note: We may not know the type of a field here, as the user could be saving (null) to a field + //That never existed before, meaning we can't infer the type. + if (schema.fields[restKey] && schema.fields[restKey].type == 'Pointer' || restValue.__type == 'Pointer') { + restKey = '_p_' + restKey; + } + } // Handle atomic values + + + var value = transformTopLevelAtom(restValue); + + if (value !== CannotTransform) { + return { + key: restKey, + value: value + }; + } // ACLs are handled before this method is called + // If an ACL key still exists here, something is wrong. + + + if (restKey === 'ACL') { + throw 'There was a problem transforming an ACL.'; + } // Handle arrays + + + if (restValue instanceof Array) { + value = restValue.map(transformInteriorValue); + return { + key: restKey, + value: value + }; + } // Handle normal objects by recursing + + + if (Object.keys(restValue).some(key => key.includes('$') || key.includes('.'))) { + throw new Parse.Error(Parse.Error.INVALID_NESTED_KEY, "Nested keys should not contain the '$' or '.' characters"); + } + + value = mapValues(restValue, transformInteriorValue); + return { + key: restKey, + value + }; +}; + +const parseObjectToMongoObjectForCreate = (className, restCreate, schema) => { + restCreate = addLegacyACL(restCreate); + const mongoCreate = {}; + + for (const restKey in restCreate) { + if (restCreate[restKey] && restCreate[restKey].__type === 'Relation') { + continue; + } + + const { + key, + value + } = parseObjectKeyValueToMongoObjectKeyValue(restKey, restCreate[restKey], schema); + + if (value !== undefined) { + mongoCreate[key] = value; + } + } // Use the legacy mongo format for createdAt and updatedAt + + + if (mongoCreate.createdAt) { + mongoCreate._created_at = new Date(mongoCreate.createdAt.iso || mongoCreate.createdAt); + delete mongoCreate.createdAt; + } + + if (mongoCreate.updatedAt) { + mongoCreate._updated_at = new Date(mongoCreate.updatedAt.iso || mongoCreate.updatedAt); + delete mongoCreate.updatedAt; + } + + return mongoCreate; +}; // Main exposed method to help update old objects. + + +const transformUpdate = (className, restUpdate, parseFormatSchema) => { + const mongoUpdate = {}; + const acl = addLegacyACL(restUpdate); + + if (acl._rperm || acl._wperm || acl._acl) { + mongoUpdate.$set = {}; + + if (acl._rperm) { + mongoUpdate.$set._rperm = acl._rperm; + } + + if (acl._wperm) { + mongoUpdate.$set._wperm = acl._wperm; + } + + if (acl._acl) { + mongoUpdate.$set._acl = acl._acl; + } + } + + for (var restKey in restUpdate) { + if (restUpdate[restKey] && restUpdate[restKey].__type === 'Relation') { + continue; + } + + var out = transformKeyValueForUpdate(className, restKey, restUpdate[restKey], parseFormatSchema); // If the output value is an object with any $ keys, it's an + // operator that needs to be lifted onto the top level update + // object. + + if (typeof out.value === 'object' && out.value !== null && out.value.__op) { + mongoUpdate[out.value.__op] = mongoUpdate[out.value.__op] || {}; + mongoUpdate[out.value.__op][out.key] = out.value.arg; + } else { + mongoUpdate['$set'] = mongoUpdate['$set'] || {}; + mongoUpdate['$set'][out.key] = out.value; + } + } + + return mongoUpdate; +}; // Add the legacy _acl format. + + +const addLegacyACL = restObject => { + const restObjectCopy = _objectSpread({}, restObject); + + const _acl = {}; + + if (restObject._wperm) { + restObject._wperm.forEach(entry => { + _acl[entry] = { + w: true + }; + }); + + restObjectCopy._acl = _acl; + } + + if (restObject._rperm) { + restObject._rperm.forEach(entry => { + if (!(entry in _acl)) { + _acl[entry] = { + r: true + }; + } else { + _acl[entry].r = true; + } + }); + + restObjectCopy._acl = _acl; + } + + return restObjectCopy; +}; // A sentinel value that helper transformations return when they +// cannot perform a transformation + + +function CannotTransform() {} + +const transformInteriorAtom = atom => { + // TODO: check validity harder for the __type-defined types + if (typeof atom === 'object' && atom && !(atom instanceof Date) && atom.__type === 'Pointer') { + return { + __type: 'Pointer', + className: atom.className, + objectId: atom.objectId + }; + } else if (typeof atom === 'function' || typeof atom === 'symbol') { + throw new Parse.Error(Parse.Error.INVALID_JSON, `cannot transform value: ${atom}`); + } else if (DateCoder.isValidJSON(atom)) { + return DateCoder.JSONToDatabase(atom); + } else if (BytesCoder.isValidJSON(atom)) { + return BytesCoder.JSONToDatabase(atom); + } else if (typeof atom === 'object' && atom && atom.$regex !== undefined) { + return new RegExp(atom.$regex); + } else { + return atom; + } +}; // Helper function to transform an atom from REST format to Mongo format. +// An atom is anything that can't contain other expressions. So it +// includes things where objects are used to represent other +// datatypes, like pointers and dates, but it does not include objects +// or arrays with generic stuff inside. +// Raises an error if this cannot possibly be valid REST format. +// Returns CannotTransform if it's just not an atom + + +function transformTopLevelAtom(atom, field) { + switch (typeof atom) { + case 'number': + case 'boolean': + case 'undefined': + return atom; + + case 'string': + if (field && field.type === 'Pointer') { + return `${field.targetClass}$${atom}`; + } + + return atom; + + case 'symbol': + case 'function': + throw new Parse.Error(Parse.Error.INVALID_JSON, `cannot transform value: ${atom}`); + + case 'object': + if (atom instanceof Date) { + // Technically dates are not rest format, but, it seems pretty + // clear what they should be transformed to, so let's just do it. + return atom; + } + + if (atom === null) { + return atom; + } // TODO: check validity harder for the __type-defined types + + + if (atom.__type == 'Pointer') { + return `${atom.className}$${atom.objectId}`; + } + + if (DateCoder.isValidJSON(atom)) { + return DateCoder.JSONToDatabase(atom); + } + + if (BytesCoder.isValidJSON(atom)) { + return BytesCoder.JSONToDatabase(atom); + } + + if (GeoPointCoder.isValidJSON(atom)) { + return GeoPointCoder.JSONToDatabase(atom); + } + + if (PolygonCoder.isValidJSON(atom)) { + return PolygonCoder.JSONToDatabase(atom); + } + + if (FileCoder.isValidJSON(atom)) { + return FileCoder.JSONToDatabase(atom); + } + + return CannotTransform; + + default: + // I don't think typeof can ever let us get here + throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, `really did not expect value: ${atom}`); + } +} + +function relativeTimeToDate(text, now = new Date()) { + text = text.toLowerCase(); + let parts = text.split(' '); // Filter out whitespace + + parts = parts.filter(part => part !== ''); + const future = parts[0] === 'in'; + const past = parts[parts.length - 1] === 'ago'; + + if (!future && !past && text !== 'now') { + return { + status: 'error', + info: "Time should either start with 'in' or end with 'ago'" + }; + } + + if (future && past) { + return { + status: 'error', + info: "Time cannot have both 'in' and 'ago'" + }; + } // strip the 'ago' or 'in' + + + if (future) { + parts = parts.slice(1); + } else { + // past + parts = parts.slice(0, parts.length - 1); + } + + if (parts.length % 2 !== 0 && text !== 'now') { + return { + status: 'error', + info: 'Invalid time string. Dangling unit or number.' + }; + } + + const pairs = []; + + while (parts.length) { + pairs.push([parts.shift(), parts.shift()]); + } + + let seconds = 0; + + for (const [num, interval] of pairs) { + const val = Number(num); + + if (!Number.isInteger(val)) { + return { + status: 'error', + info: `'${num}' is not an integer.` + }; + } + + switch (interval) { + case 'yr': + case 'yrs': + case 'year': + case 'years': + seconds += val * 31536000; // 365 * 24 * 60 * 60 + + break; + + case 'wk': + case 'wks': + case 'week': + case 'weeks': + seconds += val * 604800; // 7 * 24 * 60 * 60 + + break; + + case 'd': + case 'day': + case 'days': + seconds += val * 86400; // 24 * 60 * 60 + + break; + + case 'hr': + case 'hrs': + case 'hour': + case 'hours': + seconds += val * 3600; // 60 * 60 + + break; + + case 'min': + case 'mins': + case 'minute': + case 'minutes': + seconds += val * 60; + break; + + case 'sec': + case 'secs': + case 'second': + case 'seconds': + seconds += val; + break; + + default: + return { + status: 'error', + info: `Invalid interval: '${interval}'` + }; + } + } + + const milliseconds = seconds * 1000; + + if (future) { + return { + status: 'success', + info: 'future', + result: new Date(now.valueOf() + milliseconds) + }; + } else if (past) { + return { + status: 'success', + info: 'past', + result: new Date(now.valueOf() - milliseconds) + }; + } else { + return { + status: 'success', + info: 'present', + result: new Date(now.valueOf()) + }; + } +} // Transforms a query constraint from REST API format to Mongo format. +// A constraint is something with fields like $lt. +// If it is not a valid constraint but it could be a valid something +// else, return CannotTransform. +// inArray is whether this is an array field. + + +function transformConstraint(constraint, field, count = false) { + const inArray = field && field.type && field.type === 'Array'; + + if (typeof constraint !== 'object' || !constraint) { + return CannotTransform; + } + + const transformFunction = inArray ? transformInteriorAtom : transformTopLevelAtom; + + const transformer = atom => { + const result = transformFunction(atom, field); + + if (result === CannotTransform) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `bad atom: ${JSON.stringify(atom)}`); + } + + return result; + }; // keys is the constraints in reverse alphabetical order. + // This is a hack so that: + // $regex is handled before $options + // $nearSphere is handled before $maxDistance + + + var keys = Object.keys(constraint).sort().reverse(); + var answer = {}; + + for (var key of keys) { + switch (key) { + case '$lt': + case '$lte': + case '$gt': + case '$gte': + case '$exists': + case '$ne': + case '$eq': + { + const val = constraint[key]; + + if (val && typeof val === 'object' && val.$relativeTime) { + if (field && field.type !== 'Date') { + throw new Parse.Error(Parse.Error.INVALID_JSON, '$relativeTime can only be used with Date field'); + } + + switch (key) { + case '$exists': + case '$ne': + case '$eq': + throw new Parse.Error(Parse.Error.INVALID_JSON, '$relativeTime can only be used with the $lt, $lte, $gt, and $gte operators'); + } + + const parserResult = relativeTimeToDate(val.$relativeTime); + + if (parserResult.status === 'success') { + answer[key] = parserResult.result; + break; + } + + _logger.default.info('Error while parsing relative date', parserResult); + + throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $relativeTime (${key}) value. ${parserResult.info}`); + } + + answer[key] = transformer(val); + break; + } + + case '$in': + case '$nin': + { + const arr = constraint[key]; + + if (!(arr instanceof Array)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad ' + key + ' value'); + } + + answer[key] = _lodash.default.flatMap(arr, value => { + return (atom => { + if (Array.isArray(atom)) { + return value.map(transformer); + } else { + return transformer(atom); + } + })(value); + }); + break; + } + + case '$all': + { + const arr = constraint[key]; + + if (!(arr instanceof Array)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad ' + key + ' value'); + } + + answer[key] = arr.map(transformInteriorAtom); + const values = answer[key]; + + if (isAnyValueRegex(values) && !isAllValuesRegexOrNone(values)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'All $all values must be of regex type or none: ' + values); + } + + break; + } + + case '$regex': + var s = constraint[key]; + + if (typeof s !== 'string') { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad regex: ' + s); + } + + answer[key] = s; + break; + + case '$containedBy': + { + const arr = constraint[key]; + + if (!(arr instanceof Array)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $containedBy: should be an array`); + } + + answer.$elemMatch = { + $nin: arr.map(transformer) + }; + break; + } + + case '$options': + answer[key] = constraint[key]; + break; + + case '$text': + { + const search = constraint[key].$search; + + if (typeof search !== 'object') { + throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $search, should be object`); + } + + if (!search.$term || typeof search.$term !== 'string') { + throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $term, should be string`); + } else { + answer[key] = { + $search: search.$term + }; + } + + if (search.$language && typeof search.$language !== 'string') { + throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $language, should be string`); + } else if (search.$language) { + answer[key].$language = search.$language; + } + + if (search.$caseSensitive && typeof search.$caseSensitive !== 'boolean') { + throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $caseSensitive, should be boolean`); + } else if (search.$caseSensitive) { + answer[key].$caseSensitive = search.$caseSensitive; + } + + if (search.$diacriticSensitive && typeof search.$diacriticSensitive !== 'boolean') { + throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $diacriticSensitive, should be boolean`); + } else if (search.$diacriticSensitive) { + answer[key].$diacriticSensitive = search.$diacriticSensitive; + } + + break; + } + + case '$nearSphere': + { + const point = constraint[key]; + + if (count) { + answer.$geoWithin = { + $centerSphere: [[point.longitude, point.latitude], constraint.$maxDistance] + }; + } else { + answer[key] = [point.longitude, point.latitude]; + } + + break; + } + + case '$maxDistance': + { + if (count) { + break; + } + + answer[key] = constraint[key]; + break; + } + // The SDKs don't seem to use these but they are documented in the + // REST API docs. + + case '$maxDistanceInRadians': + answer['$maxDistance'] = constraint[key]; + break; + + case '$maxDistanceInMiles': + answer['$maxDistance'] = constraint[key] / 3959; + break; + + case '$maxDistanceInKilometers': + answer['$maxDistance'] = constraint[key] / 6371; + break; + + case '$select': + case '$dontSelect': + throw new Parse.Error(Parse.Error.COMMAND_UNAVAILABLE, 'the ' + key + ' constraint is not supported yet'); + + case '$within': + var box = constraint[key]['$box']; + + if (!box || box.length != 2) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'malformatted $within arg'); + } + + answer[key] = { + $box: [[box[0].longitude, box[0].latitude], [box[1].longitude, box[1].latitude]] + }; + break; + + case '$geoWithin': + { + const polygon = constraint[key]['$polygon']; + const centerSphere = constraint[key]['$centerSphere']; + + if (polygon !== undefined) { + let points; + + if (typeof polygon === 'object' && polygon.__type === 'Polygon') { + if (!polygon.coordinates || polygon.coordinates.length < 3) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; Polygon.coordinates should contain at least 3 lon/lat pairs'); + } + + points = polygon.coordinates; + } else if (polygon instanceof Array) { + if (polygon.length < 3) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; $polygon should contain at least 3 GeoPoints'); + } + + points = polygon; + } else { + throw new Parse.Error(Parse.Error.INVALID_JSON, "bad $geoWithin value; $polygon should be Polygon object or Array of Parse.GeoPoint's"); + } + + points = points.map(point => { + if (point instanceof Array && point.length === 2) { + Parse.GeoPoint._validate(point[1], point[0]); + + return point; + } + + if (!GeoPointCoder.isValidJSON(point)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value'); + } else { + Parse.GeoPoint._validate(point.latitude, point.longitude); + } + + return [point.longitude, point.latitude]; + }); + answer[key] = { + $polygon: points + }; + } else if (centerSphere !== undefined) { + if (!(centerSphere instanceof Array) || centerSphere.length < 2) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere should be an array of Parse.GeoPoint and distance'); + } // Get point, convert to geo point if necessary and validate + + + let point = centerSphere[0]; + + if (point instanceof Array && point.length === 2) { + point = new Parse.GeoPoint(point[1], point[0]); + } else if (!GeoPointCoder.isValidJSON(point)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere geo point invalid'); + } + + Parse.GeoPoint._validate(point.latitude, point.longitude); // Get distance and validate + + + const distance = centerSphere[1]; + + if (isNaN(distance) || distance < 0) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere distance invalid'); + } + + answer[key] = { + $centerSphere: [[point.longitude, point.latitude], distance] + }; + } + + break; + } + + case '$geoIntersects': + { + const point = constraint[key]['$point']; + + if (!GeoPointCoder.isValidJSON(point)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoIntersect value; $point should be GeoPoint'); + } else { + Parse.GeoPoint._validate(point.latitude, point.longitude); + } + + answer[key] = { + $geometry: { + type: 'Point', + coordinates: [point.longitude, point.latitude] + } + }; + break; + } + + default: + if (key.match(/^\$+/)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad constraint: ' + key); + } + + return CannotTransform; + } + } + + return answer; +} // Transforms an update operator from REST format to mongo format. +// To be transformed, the input should have an __op field. +// If flatten is true, this will flatten operators to their static +// data format. For example, an increment of 2 would simply become a +// 2. +// The output for a non-flattened operator is a hash with __op being +// the mongo op, and arg being the argument. +// The output for a flattened operator is just a value. +// Returns undefined if this should be a no-op. + + +function transformUpdateOperator({ + __op, + amount, + objects +}, flatten) { + switch (__op) { + case 'Delete': + if (flatten) { + return undefined; + } else { + return { + __op: '$unset', + arg: '' + }; + } + + case 'Increment': + if (typeof amount !== 'number') { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'incrementing must provide a number'); + } + + if (flatten) { + return amount; + } else { + return { + __op: '$inc', + arg: amount + }; + } + + case 'Add': + case 'AddUnique': + if (!(objects instanceof Array)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'objects to add must be an array'); + } + + var toAdd = objects.map(transformInteriorAtom); + + if (flatten) { + return toAdd; + } else { + var mongoOp = { + Add: '$push', + AddUnique: '$addToSet' + }[__op]; + return { + __op: mongoOp, + arg: { + $each: toAdd + } + }; + } + + case 'Remove': + if (!(objects instanceof Array)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'objects to remove must be an array'); + } + + var toRemove = objects.map(transformInteriorAtom); + + if (flatten) { + return []; + } else { + return { + __op: '$pullAll', + arg: toRemove + }; + } + + default: + throw new Parse.Error(Parse.Error.COMMAND_UNAVAILABLE, `The ${__op} operator is not supported yet.`); + } +} + +function mapValues(object, iterator) { + const result = {}; + Object.keys(object).forEach(key => { + result[key] = iterator(object[key]); + }); + return result; +} + +const nestedMongoObjectToNestedParseObject = mongoObject => { + switch (typeof mongoObject) { + case 'string': + case 'number': + case 'boolean': + case 'undefined': + return mongoObject; + + case 'symbol': + case 'function': + throw 'bad value in nestedMongoObjectToNestedParseObject'; + + case 'object': + if (mongoObject === null) { + return null; + } + + if (mongoObject instanceof Array) { + return mongoObject.map(nestedMongoObjectToNestedParseObject); + } + + if (mongoObject instanceof Date) { + return Parse._encode(mongoObject); + } + + if (mongoObject instanceof mongodb.Long) { + return mongoObject.toNumber(); + } + + if (mongoObject instanceof mongodb.Double) { + return mongoObject.value; + } + + if (BytesCoder.isValidDatabaseObject(mongoObject)) { + return BytesCoder.databaseToJSON(mongoObject); + } + + if (Object.prototype.hasOwnProperty.call(mongoObject, '__type') && mongoObject.__type == 'Date' && mongoObject.iso instanceof Date) { + mongoObject.iso = mongoObject.iso.toJSON(); + return mongoObject; + } + + return mapValues(mongoObject, nestedMongoObjectToNestedParseObject); + + default: + throw 'unknown js type'; + } +}; + +const transformPointerString = (schema, field, pointerString) => { + const objData = pointerString.split('$'); + + if (objData[0] !== schema.fields[field].targetClass) { + throw 'pointer to incorrect className'; + } + + return { + __type: 'Pointer', + className: objData[0], + objectId: objData[1] + }; +}; // Converts from a mongo-format object to a REST-format object. +// Does not strip out anything based on a lack of authentication. + + +const mongoObjectToParseObject = (className, mongoObject, schema) => { + switch (typeof mongoObject) { + case 'string': + case 'number': + case 'boolean': + case 'undefined': + return mongoObject; + + case 'symbol': + case 'function': + throw 'bad value in mongoObjectToParseObject'; + + case 'object': + { + if (mongoObject === null) { + return null; + } + + if (mongoObject instanceof Array) { + return mongoObject.map(nestedMongoObjectToNestedParseObject); + } + + if (mongoObject instanceof Date) { + return Parse._encode(mongoObject); + } + + if (mongoObject instanceof mongodb.Long) { + return mongoObject.toNumber(); + } + + if (mongoObject instanceof mongodb.Double) { + return mongoObject.value; + } + + if (BytesCoder.isValidDatabaseObject(mongoObject)) { + return BytesCoder.databaseToJSON(mongoObject); + } + + const restObject = {}; + + if (mongoObject._rperm || mongoObject._wperm) { + restObject._rperm = mongoObject._rperm || []; + restObject._wperm = mongoObject._wperm || []; + delete mongoObject._rperm; + delete mongoObject._wperm; + } + + for (var key in mongoObject) { + switch (key) { + case '_id': + restObject['objectId'] = '' + mongoObject[key]; + break; + + case '_hashed_password': + restObject._hashed_password = mongoObject[key]; + break; + + case '_acl': + break; + + case '_email_verify_token': + case '_perishable_token': + case '_perishable_token_expires_at': + case '_password_changed_at': + case '_tombstone': + case '_email_verify_token_expires_at': + case '_account_lockout_expires_at': + case '_failed_login_count': + case '_password_history': + // Those keys will be deleted if needed in the DB Controller + restObject[key] = mongoObject[key]; + break; + + case '_session_token': + restObject['sessionToken'] = mongoObject[key]; + break; + + case 'updatedAt': + case '_updated_at': + restObject['updatedAt'] = Parse._encode(new Date(mongoObject[key])).iso; + break; + + case 'createdAt': + case '_created_at': + restObject['createdAt'] = Parse._encode(new Date(mongoObject[key])).iso; + break; + + case 'expiresAt': + case '_expiresAt': + restObject['expiresAt'] = Parse._encode(new Date(mongoObject[key])); + break; + + case 'lastUsed': + case '_last_used': + restObject['lastUsed'] = Parse._encode(new Date(mongoObject[key])).iso; + break; + + case 'timesUsed': + case 'times_used': + restObject['timesUsed'] = mongoObject[key]; + break; + + case 'authData': + if (className === '_User') { + _logger.default.warn('ignoring authData in _User as this key is reserved to be synthesized of `_auth_data_*` keys'); + } else { + restObject['authData'] = mongoObject[key]; + } + + break; + + default: + // Check other auth data keys + var authDataMatch = key.match(/^_auth_data_([a-zA-Z0-9_]+)$/); + + if (authDataMatch && className === '_User') { + var provider = authDataMatch[1]; + restObject['authData'] = restObject['authData'] || {}; + restObject['authData'][provider] = mongoObject[key]; + break; + } + + if (key.indexOf('_p_') == 0) { + var newKey = key.substring(3); + + if (!schema.fields[newKey]) { + _logger.default.info('transform.js', 'Found a pointer column not in the schema, dropping it.', className, newKey); + + break; + } + + if (schema.fields[newKey].type !== 'Pointer') { + _logger.default.info('transform.js', 'Found a pointer in a non-pointer column, dropping it.', className, key); + + break; + } + + if (mongoObject[key] === null) { + break; + } + + restObject[newKey] = transformPointerString(schema, newKey, mongoObject[key]); + break; + } else if (key[0] == '_' && key != '__type') { + throw 'bad key in untransform: ' + key; + } else { + var value = mongoObject[key]; + + if (schema.fields[key] && schema.fields[key].type === 'File' && FileCoder.isValidDatabaseObject(value)) { + restObject[key] = FileCoder.databaseToJSON(value); + break; + } + + if (schema.fields[key] && schema.fields[key].type === 'GeoPoint' && GeoPointCoder.isValidDatabaseObject(value)) { + restObject[key] = GeoPointCoder.databaseToJSON(value); + break; + } + + if (schema.fields[key] && schema.fields[key].type === 'Polygon' && PolygonCoder.isValidDatabaseObject(value)) { + restObject[key] = PolygonCoder.databaseToJSON(value); + break; + } + + if (schema.fields[key] && schema.fields[key].type === 'Bytes' && BytesCoder.isValidDatabaseObject(value)) { + restObject[key] = BytesCoder.databaseToJSON(value); + break; + } + } + + restObject[key] = nestedMongoObjectToNestedParseObject(mongoObject[key]); + } + } + + const relationFieldNames = Object.keys(schema.fields).filter(fieldName => schema.fields[fieldName].type === 'Relation'); + const relationFields = {}; + relationFieldNames.forEach(relationFieldName => { + relationFields[relationFieldName] = { + __type: 'Relation', + className: schema.fields[relationFieldName].targetClass + }; + }); + return _objectSpread(_objectSpread({}, restObject), relationFields); + } + + default: + throw 'unknown js type'; + } +}; + +var DateCoder = { + JSONToDatabase(json) { + return new Date(json.iso); + }, + + isValidJSON(value) { + return typeof value === 'object' && value !== null && value.__type === 'Date'; + } + +}; +var BytesCoder = { + base64Pattern: new RegExp('^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$'), + + isBase64Value(object) { + if (typeof object !== 'string') { + return false; + } + + return this.base64Pattern.test(object); + }, + + databaseToJSON(object) { + let value; + + if (this.isBase64Value(object)) { + value = object; + } else { + value = object.buffer.toString('base64'); + } + + return { + __type: 'Bytes', + base64: value + }; + }, + + isValidDatabaseObject(object) { + return object instanceof mongodb.Binary || this.isBase64Value(object); + }, + + JSONToDatabase(json) { + return new mongodb.Binary(Buffer.from(json.base64, 'base64')); + }, + + isValidJSON(value) { + return typeof value === 'object' && value !== null && value.__type === 'Bytes'; + } + +}; +var GeoPointCoder = { + databaseToJSON(object) { + return { + __type: 'GeoPoint', + latitude: object[1], + longitude: object[0] + }; + }, + + isValidDatabaseObject(object) { + return object instanceof Array && object.length == 2; + }, + + JSONToDatabase(json) { + return [json.longitude, json.latitude]; + }, + + isValidJSON(value) { + return typeof value === 'object' && value !== null && value.__type === 'GeoPoint'; + } + +}; +var PolygonCoder = { + databaseToJSON(object) { + // Convert lng/lat -> lat/lng + const coords = object.coordinates[0].map(coord => { + return [coord[1], coord[0]]; + }); + return { + __type: 'Polygon', + coordinates: coords + }; + }, + + isValidDatabaseObject(object) { + const coords = object.coordinates[0]; + + if (object.type !== 'Polygon' || !(coords instanceof Array)) { + return false; + } + + for (let i = 0; i < coords.length; i++) { + const point = coords[i]; + + if (!GeoPointCoder.isValidDatabaseObject(point)) { + return false; + } + + Parse.GeoPoint._validate(parseFloat(point[1]), parseFloat(point[0])); + } + + return true; + }, + + JSONToDatabase(json) { + let coords = json.coordinates; // Add first point to the end to close polygon + + if (coords[0][0] !== coords[coords.length - 1][0] || coords[0][1] !== coords[coords.length - 1][1]) { + coords.push(coords[0]); + } + + const unique = coords.filter((item, index, ar) => { + let foundIndex = -1; + + for (let i = 0; i < ar.length; i += 1) { + const pt = ar[i]; + + if (pt[0] === item[0] && pt[1] === item[1]) { + foundIndex = i; + break; + } + } + + return foundIndex === index; + }); + + if (unique.length < 3) { + throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'GeoJSON: Loop must have at least 3 different vertices'); + } // Convert lat/long -> long/lat + + + coords = coords.map(coord => { + return [coord[1], coord[0]]; + }); + return { + type: 'Polygon', + coordinates: [coords] + }; + }, + + isValidJSON(value) { + return typeof value === 'object' && value !== null && value.__type === 'Polygon'; + } + +}; +var FileCoder = { + databaseToJSON(object) { + return { + __type: 'File', + name: object + }; + }, + + isValidDatabaseObject(object) { + return typeof object === 'string'; + }, + + JSONToDatabase(json) { + return json.name; + }, + + isValidJSON(value) { + return typeof value === 'object' && value !== null && value.__type === 'File'; + } + +}; +module.exports = { + transformKey, + parseObjectToMongoObjectForCreate, + transformUpdate, + transformWhere, + mongoObjectToParseObject, + relativeTimeToDate, + transformConstraint, + transformPointerString +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvVHJhbnNmb3JtLmpzIl0sIm5hbWVzIjpbIm1vbmdvZGIiLCJyZXF1aXJlIiwiUGFyc2UiLCJ0cmFuc2Zvcm1LZXkiLCJjbGFzc05hbWUiLCJmaWVsZE5hbWUiLCJzY2hlbWEiLCJmaWVsZHMiLCJfX3R5cGUiLCJ0eXBlIiwidHJhbnNmb3JtS2V5VmFsdWVGb3JVcGRhdGUiLCJyZXN0S2V5IiwicmVzdFZhbHVlIiwicGFyc2VGb3JtYXRTY2hlbWEiLCJrZXkiLCJ0aW1lRmllbGQiLCJpbmNsdWRlcyIsInZhbHVlIiwicGFyc2VJbnQiLCJ0cmFuc2Zvcm1Ub3BMZXZlbEF0b20iLCJDYW5ub3RUcmFuc2Zvcm0iLCJEYXRlIiwiaW5kZXhPZiIsIkFycmF5IiwibWFwIiwidHJhbnNmb3JtSW50ZXJpb3JWYWx1ZSIsInRyYW5zZm9ybVVwZGF0ZU9wZXJhdG9yIiwibWFwVmFsdWVzIiwiaXNSZWdleCIsIlJlZ0V4cCIsImlzU3RhcnRzV2l0aFJlZ2V4IiwibWF0Y2hlcyIsInRvU3RyaW5nIiwibWF0Y2giLCJpc0FsbFZhbHVlc1JlZ2V4T3JOb25lIiwidmFsdWVzIiwiaXNBcnJheSIsImxlbmd0aCIsImZpcnN0VmFsdWVzSXNSZWdleCIsImkiLCJpc0FueVZhbHVlUmVnZXgiLCJzb21lIiwiT2JqZWN0Iiwia2V5cyIsIkVycm9yIiwiSU5WQUxJRF9ORVNURURfS0VZIiwidHJhbnNmb3JtSW50ZXJpb3JBdG9tIiwidmFsdWVBc0RhdGUiLCJ0cmFuc2Zvcm1RdWVyeUtleVZhbHVlIiwiY291bnQiLCJzdWJRdWVyeSIsInRyYW5zZm9ybVdoZXJlIiwiYXV0aERhdGFNYXRjaCIsInByb3ZpZGVyIiwiZXhwZWN0ZWRUeXBlSXNBcnJheSIsImV4cGVjdGVkVHlwZUlzUG9pbnRlciIsImZpZWxkIiwidHJhbnNmb3JtZWRDb25zdHJhaW50IiwidHJhbnNmb3JtQ29uc3RyYWludCIsIiR0ZXh0IiwiJGVsZW1NYXRjaCIsIiRhbGwiLCJJTlZBTElEX0pTT04iLCJyZXN0V2hlcmUiLCJtb25nb1doZXJlIiwib3V0IiwicGFyc2VPYmplY3RLZXlWYWx1ZVRvTW9uZ29PYmplY3RLZXlWYWx1ZSIsInRyYW5zZm9ybWVkVmFsdWUiLCJjb2VyY2VkVG9EYXRlIiwiSU5WQUxJRF9LRVlfTkFNRSIsInBhcnNlT2JqZWN0VG9Nb25nb09iamVjdEZvckNyZWF0ZSIsInJlc3RDcmVhdGUiLCJhZGRMZWdhY3lBQ0wiLCJtb25nb0NyZWF0ZSIsInVuZGVmaW5lZCIsImNyZWF0ZWRBdCIsIl9jcmVhdGVkX2F0IiwiaXNvIiwidXBkYXRlZEF0IiwiX3VwZGF0ZWRfYXQiLCJ0cmFuc2Zvcm1VcGRhdGUiLCJyZXN0VXBkYXRlIiwibW9uZ29VcGRhdGUiLCJhY2wiLCJfcnBlcm0iLCJfd3Blcm0iLCJfYWNsIiwiJHNldCIsIl9fb3AiLCJhcmciLCJyZXN0T2JqZWN0IiwicmVzdE9iamVjdENvcHkiLCJmb3JFYWNoIiwiZW50cnkiLCJ3IiwiciIsImF0b20iLCJvYmplY3RJZCIsIkRhdGVDb2RlciIsImlzVmFsaWRKU09OIiwiSlNPTlRvRGF0YWJhc2UiLCJCeXRlc0NvZGVyIiwiJHJlZ2V4IiwidGFyZ2V0Q2xhc3MiLCJHZW9Qb2ludENvZGVyIiwiUG9seWdvbkNvZGVyIiwiRmlsZUNvZGVyIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwicmVsYXRpdmVUaW1lVG9EYXRlIiwidGV4dCIsIm5vdyIsInRvTG93ZXJDYXNlIiwicGFydHMiLCJzcGxpdCIsImZpbHRlciIsInBhcnQiLCJmdXR1cmUiLCJwYXN0Iiwic3RhdHVzIiwiaW5mbyIsInNsaWNlIiwicGFpcnMiLCJwdXNoIiwic2hpZnQiLCJzZWNvbmRzIiwibnVtIiwiaW50ZXJ2YWwiLCJ2YWwiLCJOdW1iZXIiLCJpc0ludGVnZXIiLCJtaWxsaXNlY29uZHMiLCJyZXN1bHQiLCJ2YWx1ZU9mIiwiY29uc3RyYWludCIsImluQXJyYXkiLCJ0cmFuc2Zvcm1GdW5jdGlvbiIsInRyYW5zZm9ybWVyIiwiSlNPTiIsInN0cmluZ2lmeSIsInNvcnQiLCJyZXZlcnNlIiwiYW5zd2VyIiwiJHJlbGF0aXZlVGltZSIsInBhcnNlclJlc3VsdCIsImxvZyIsImFyciIsIl8iLCJmbGF0TWFwIiwicyIsIiRuaW4iLCJzZWFyY2giLCIkc2VhcmNoIiwiJHRlcm0iLCIkbGFuZ3VhZ2UiLCIkY2FzZVNlbnNpdGl2ZSIsIiRkaWFjcml0aWNTZW5zaXRpdmUiLCJwb2ludCIsIiRnZW9XaXRoaW4iLCIkY2VudGVyU3BoZXJlIiwibG9uZ2l0dWRlIiwibGF0aXR1ZGUiLCIkbWF4RGlzdGFuY2UiLCJDT01NQU5EX1VOQVZBSUxBQkxFIiwiYm94IiwiJGJveCIsInBvbHlnb24iLCJjZW50ZXJTcGhlcmUiLCJwb2ludHMiLCJjb29yZGluYXRlcyIsIkdlb1BvaW50IiwiX3ZhbGlkYXRlIiwiJHBvbHlnb24iLCJkaXN0YW5jZSIsImlzTmFOIiwiJGdlb21ldHJ5IiwiYW1vdW50Iiwib2JqZWN0cyIsImZsYXR0ZW4iLCJ0b0FkZCIsIm1vbmdvT3AiLCJBZGQiLCJBZGRVbmlxdWUiLCIkZWFjaCIsInRvUmVtb3ZlIiwib2JqZWN0IiwiaXRlcmF0b3IiLCJuZXN0ZWRNb25nb09iamVjdFRvTmVzdGVkUGFyc2VPYmplY3QiLCJtb25nb09iamVjdCIsIl9lbmNvZGUiLCJMb25nIiwidG9OdW1iZXIiLCJEb3VibGUiLCJpc1ZhbGlkRGF0YWJhc2VPYmplY3QiLCJkYXRhYmFzZVRvSlNPTiIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInRvSlNPTiIsInRyYW5zZm9ybVBvaW50ZXJTdHJpbmciLCJwb2ludGVyU3RyaW5nIiwib2JqRGF0YSIsIm1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdCIsIl9oYXNoZWRfcGFzc3dvcmQiLCJ3YXJuIiwibmV3S2V5Iiwic3Vic3RyaW5nIiwicmVsYXRpb25GaWVsZE5hbWVzIiwicmVsYXRpb25GaWVsZHMiLCJyZWxhdGlvbkZpZWxkTmFtZSIsImpzb24iLCJiYXNlNjRQYXR0ZXJuIiwiaXNCYXNlNjRWYWx1ZSIsInRlc3QiLCJidWZmZXIiLCJiYXNlNjQiLCJCaW5hcnkiLCJCdWZmZXIiLCJmcm9tIiwiY29vcmRzIiwiY29vcmQiLCJwYXJzZUZsb2F0IiwidW5pcXVlIiwiaXRlbSIsImluZGV4IiwiYXIiLCJmb3VuZEluZGV4IiwicHQiLCJuYW1lIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTs7QUFDQTs7Ozs7Ozs7OztBQUNBLElBQUlBLE9BQU8sR0FBR0MsT0FBTyxDQUFDLFNBQUQsQ0FBckI7O0FBQ0EsSUFBSUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCQyxLQUFsQzs7QUFFQSxNQUFNQyxZQUFZLEdBQUcsQ0FBQ0MsU0FBRCxFQUFZQyxTQUFaLEVBQXVCQyxNQUF2QixLQUFrQztBQUNyRDtBQUNBLFVBQVFELFNBQVI7QUFDRSxTQUFLLFVBQUw7QUFDRSxhQUFPLEtBQVA7O0FBQ0YsU0FBSyxXQUFMO0FBQ0UsYUFBTyxhQUFQOztBQUNGLFNBQUssV0FBTDtBQUNFLGFBQU8sYUFBUDs7QUFDRixTQUFLLGNBQUw7QUFDRSxhQUFPLGdCQUFQOztBQUNGLFNBQUssVUFBTDtBQUNFLGFBQU8sWUFBUDs7QUFDRixTQUFLLFdBQUw7QUFDRSxhQUFPLFlBQVA7QUFaSjs7QUFlQSxNQUFJQyxNQUFNLENBQUNDLE1BQVAsQ0FBY0YsU0FBZCxLQUE0QkMsTUFBTSxDQUFDQyxNQUFQLENBQWNGLFNBQWQsRUFBeUJHLE1BQXpCLElBQW1DLFNBQW5FLEVBQThFO0FBQzVFSCxJQUFBQSxTQUFTLEdBQUcsUUFBUUEsU0FBcEI7QUFDRCxHQUZELE1BRU8sSUFBSUMsTUFBTSxDQUFDQyxNQUFQLENBQWNGLFNBQWQsS0FBNEJDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjRixTQUFkLEVBQXlCSSxJQUF6QixJQUFpQyxTQUFqRSxFQUE0RTtBQUNqRkosSUFBQUEsU0FBUyxHQUFHLFFBQVFBLFNBQXBCO0FBQ0Q7O0FBRUQsU0FBT0EsU0FB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QUFDa0IsSUFBWjtBQUNELEdBZGE7O0FBZ0JkaEksRUFBQUEsV0FBVyxDQUFDbEYsS0FBRCxFQUFRO0FBQ2pCLFdBQU8sT0FBT0EsS0FBUCxLQUFpQixRQUFqQixJQUE2QkEsS0FBSyxLQUFLLElBQXZDLElBQStDQSxLQUFLLENBQUNULE1BQU4sS0FBaUIsTUFBdkU7QUFDRDs7QUFsQmEsQ0FBaEI7QUFxQkE0TixNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZmxPLEVBQUFBLFlBRGU7QUFFZm1FLEVBQUFBLGlDQUZlO0FBR2ZVLEVBQUFBLGVBSGU7QUFJZjdCLEVBQUFBLGNBSmU7QUFLZnNKLEVBQUFBLHdCQUxlO0FBTWY3RixFQUFBQSxrQkFOZTtBQU9mbEQsRUFBQUEsbUJBUGU7QUFRZjRJLEVBQUFBO0FBUmUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgbG9nIGZyb20gJy4uLy4uLy4uL2xvZ2dlcic7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xudmFyIG1vbmdvZGIgPSByZXF1aXJlKCdtb25nb2RiJyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbmNvbnN0IHRyYW5zZm9ybUtleSA9IChjbGFzc05hbWUsIGZpZWxkTmFtZSwgc2NoZW1hKSA9PiB7XG4gIC8vIENoZWNrIGlmIHRoZSBzY2hlbWEgaXMga25vd24gc2luY2UgaXQncyBhIGJ1aWx0LWluIGZpZWxkLlxuICBzd2l0Y2ggKGZpZWxkTmFtZSkge1xuICAgIGNhc2UgJ29iamVjdElkJzpcbiAgICAgIHJldHVybiAnX2lkJztcbiAgICBjYXNlICdjcmVhdGVkQXQnOlxuICAgICAgcmV0dXJuICdfY3JlYXRlZF9hdCc7XG4gICAgY2FzZSAndXBkYXRlZEF0JzpcbiAgICAgIHJldHVybiAnX3VwZGF0ZWRfYXQnO1xuICAgIGNhc2UgJ3Nlc3Npb25Ub2tlbic6XG4gICAgICByZXR1cm4gJ19zZXNzaW9uX3Rva2VuJztcbiAgICBjYXNlICdsYXN0VXNlZCc6XG4gICAgICByZXR1cm4gJ19sYXN0X3VzZWQnO1xuICAgIGNhc2UgJ3RpbWVzVXNlZCc6XG4gICAgICByZXR1cm4gJ3RpbWVzX3VzZWQnO1xuICB9XG5cbiAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0uX190eXBlID09ICdQb2ludGVyJykge1xuICAgIGZpZWxkTmFtZSA9ICdfcF8nICsgZmllbGROYW1lO1xuICB9IGVsc2UgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PSAnUG9pbnRlcicpIHtcbiAgICBmaWVsZE5hbWUgPSAnX3BfJyArIGZpZWxkTmFtZTtcbiAgfVxuXG4gIHJldHVybiBmaWVsZE5hbWU7XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1LZXlWYWx1ZUZvclVwZGF0ZSA9IChjbGFzc05hbWUsIHJlc3RLZXksIHJlc3RWYWx1ZSwgcGFyc2VGb3JtYXRTY2hlbWEpID0+IHtcbiAgLy8gQ2hlY2sgaWYgdGhlIHNjaGVtYSBpcyBrbm93biBzaW5jZSBpdCdzIGEgYnVpbHQtaW4gZmllbGQuXG4gIHZhciBrZXkgPSByZXN0S2V5O1xuICB2YXIgdGltZUZpZWxkID0gZmFsc2U7XG4gIHN3aXRjaCAoa2V5KSB7XG4gICAgY2FzZSAnb2JqZWN0SWQnOlxuICAgIGNhc2UgJ19pZCc6XG4gICAgICBpZiAoWydfR2xvYmFsQ29uZmlnJywgJ19HcmFwaFFMQ29uZmlnJ10uaW5jbHVkZXMoY2xhc3NOYW1lKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgIHZhbHVlOiBwYXJzZUludChyZXN0VmFsdWUpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAga2V5ID0gJ19pZCc7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdjcmVhdGVkQXQnOlxuICAgIGNhc2UgJ19jcmVhdGVkX2F0JzpcbiAgICAgIGtleSA9ICdfY3JlYXRlZF9hdCc7XG4gICAgICB0aW1lRmllbGQgPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndXBkYXRlZEF0JzpcbiAgICBjYXNlICdfdXBkYXRlZF9hdCc6XG4gICAgICBrZXkgPSAnX3VwZGF0ZWRfYXQnO1xuICAgICAgdGltZUZpZWxkID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3Nlc3Npb25Ub2tlbic6XG4gICAgY2FzZSAnX3Nlc3Npb25fdG9rZW4nOlxuICAgICAga2V5ID0gJ19zZXNzaW9uX3Rva2VuJztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2V4cGlyZXNBdCc6XG4gICAgY2FzZSAnX2V4cGlyZXNBdCc6XG4gICAgICBrZXkgPSAnZXhwaXJlc0F0JztcbiAgICAgIHRpbWVGaWVsZCA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnOlxuICAgICAga2V5ID0gJ19lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCc7XG4gICAgICB0aW1lRmllbGQgPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JzpcbiAgICAgIGtleSA9ICdfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQnO1xuICAgICAgdGltZUZpZWxkID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ19mYWlsZWRfbG9naW5fY291bnQnOlxuICAgICAga2V5ID0gJ19mYWlsZWRfbG9naW5fY291bnQnO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCc6XG4gICAgICBrZXkgPSAnX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCc7XG4gICAgICB0aW1lRmllbGQgPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX3Bhc3N3b3JkX2NoYW5nZWRfYXQnOlxuICAgICAga2V5ID0gJ19wYXNzd29yZF9jaGFuZ2VkX2F0JztcbiAgICAgIHRpbWVGaWVsZCA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdfcnBlcm0nOlxuICAgIGNhc2UgJ193cGVybSc6XG4gICAgICByZXR1cm4geyBrZXk6IGtleSwgdmFsdWU6IHJlc3RWYWx1ZSB9O1xuICAgIGNhc2UgJ2xhc3RVc2VkJzpcbiAgICBjYXNlICdfbGFzdF91c2VkJzpcbiAgICAgIGtleSA9ICdfbGFzdF91c2VkJztcbiAgICAgIHRpbWVGaWVsZCA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd0aW1lc1VzZWQnOlxuICAgIGNhc2UgJ3RpbWVzX3VzZWQnOlxuICAgICAga2V5ID0gJ3RpbWVzX3VzZWQnO1xuICAgICAgdGltZUZpZWxkID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgaWYgKFxuICAgIChwYXJzZUZvcm1hdFNjaGVtYS5maWVsZHNba2V5XSAmJiBwYXJzZUZvcm1hdFNjaGVtYS5maWVsZHNba2V5XS50eXBlID09PSAnUG9pbnRlcicpIHx8XG4gICAgKCFwYXJzZUZvcm1hdFNjaGVtYS5maWVsZHNba2V5XSAmJiByZXN0VmFsdWUgJiYgcmVzdFZhbHVlLl9fdHlwZSA9PSAnUG9pbnRlcicpXG4gICkge1xuICAgIGtleSA9ICdfcF8nICsga2V5O1xuICB9XG5cbiAgLy8gSGFuZGxlIGF0b21pYyB2YWx1ZXNcbiAgdmFyIHZhbHVlID0gdHJhbnNmb3JtVG9wTGV2ZWxBdG9tKHJlc3RWYWx1ZSk7XG4gIGlmICh2YWx1ZSAhPT0gQ2Fubm90VHJhbnNmb3JtKSB7XG4gICAgaWYgKHRpbWVGaWVsZCAmJiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICB2YWx1ZSA9IG5ldyBEYXRlKHZhbHVlKTtcbiAgICB9XG4gICAgaWYgKHJlc3RLZXkuaW5kZXhPZignLicpID4gMCkge1xuICAgICAgcmV0dXJuIHsga2V5LCB2YWx1ZTogcmVzdFZhbHVlIH07XG4gICAgfVxuICAgIHJldHVybiB7IGtleSwgdmFsdWUgfTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBhcnJheXNcbiAgaWYgKHJlc3RWYWx1ZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgdmFsdWUgPSByZXN0VmFsdWUubWFwKHRyYW5zZm9ybUludGVyaW9yVmFsdWUpO1xuICAgIHJldHVybiB7IGtleSwgdmFsdWUgfTtcbiAgfVxuXG4gIC8vIEhhbmRsZSB1cGRhdGUgb3BlcmF0b3JzXG4gIGlmICh0eXBlb2YgcmVzdFZhbHVlID09PSAnb2JqZWN0JyAmJiAnX19vcCcgaW4gcmVzdFZhbHVlKSB7XG4gICAgcmV0dXJuIHsga2V5LCB2YWx1ZTogdHJhbnNmb3JtVXBkYXRlT3BlcmF0b3IocmVzdFZhbHVlLCBmYWxzZSkgfTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBub3JtYWwgb2JqZWN0cyBieSByZWN1cnNpbmdcbiAgdmFsdWUgPSBtYXBWYWx1ZXMocmVzdFZhbHVlLCB0cmFuc2Zvcm1JbnRlcmlvclZhbHVlKTtcbiAgcmV0dXJuIHsga2V5LCB2YWx1ZSB9O1xufTtcblxuY29uc3QgaXNSZWdleCA9IHZhbHVlID0+IHtcbiAgcmV0dXJuIHZhbHVlICYmIHZhbHVlIGluc3RhbmNlb2YgUmVnRXhwO1xufTtcblxuY29uc3QgaXNTdGFydHNXaXRoUmVnZXggPSB2YWx1ZSA9PiB7XG4gIGlmICghaXNSZWdleCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBtYXRjaGVzID0gdmFsdWUudG9TdHJpbmcoKS5tYXRjaCgvXFwvXFxeXFxcXFEuKlxcXFxFXFwvLyk7XG4gIHJldHVybiAhIW1hdGNoZXM7XG59O1xuXG5jb25zdCBpc0FsbFZhbHVlc1JlZ2V4T3JOb25lID0gdmFsdWVzID0+IHtcbiAgaWYgKCF2YWx1ZXMgfHwgIUFycmF5LmlzQXJyYXkodmFsdWVzKSB8fCB2YWx1ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBjb25zdCBmaXJzdFZhbHVlc0lzUmVnZXggPSBpc1N0YXJ0c1dpdGhSZWdleCh2YWx1ZXNbMF0pO1xuICBpZiAodmFsdWVzLmxlbmd0aCA9PT0gMSkge1xuICAgIHJldHVybiBmaXJzdFZhbHVlc0lzUmVnZXg7XG4gIH1cblxuICBmb3IgKGxldCBpID0gMSwgbGVuZ3RoID0gdmFsdWVzLmxlbmd0aDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGZpcnN0VmFsdWVzSXNSZWdleCAhPT0gaXNTdGFydHNXaXRoUmVnZXgodmFsdWVzW2ldKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuY29uc3QgaXNBbnlWYWx1ZVJlZ2V4ID0gdmFsdWVzID0+IHtcbiAgcmV0dXJuIHZhbHVlcy5zb21lKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiBpc1JlZ2V4KHZhbHVlKTtcbiAgfSk7XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1JbnRlcmlvclZhbHVlID0gcmVzdFZhbHVlID0+IHtcbiAgaWYgKFxuICAgIHJlc3RWYWx1ZSAhPT0gbnVsbCAmJlxuICAgIHR5cGVvZiByZXN0VmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgT2JqZWN0LmtleXMocmVzdFZhbHVlKS5zb21lKGtleSA9PiBrZXkuaW5jbHVkZXMoJyQnKSB8fCBrZXkuaW5jbHVkZXMoJy4nKSlcbiAgKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9ORVNURURfS0VZLFxuICAgICAgXCJOZXN0ZWQga2V5cyBzaG91bGQgbm90IGNvbnRhaW4gdGhlICckJyBvciAnLicgY2hhcmFjdGVyc1wiXG4gICAgKTtcbiAgfVxuICAvLyBIYW5kbGUgYXRvbWljIHZhbHVlc1xuICB2YXIgdmFsdWUgPSB0cmFuc2Zvcm1JbnRlcmlvckF0b20ocmVzdFZhbHVlKTtcbiAgaWYgKHZhbHVlICE9PSBDYW5ub3RUcmFuc2Zvcm0pIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICAvLyBIYW5kbGUgYXJyYXlzXG4gIGlmIChyZXN0VmFsdWUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgIHJldHVybiByZXN0VmFsdWUubWFwKHRyYW5zZm9ybUludGVyaW9yVmFsdWUpO1xuICB9XG5cbiAgLy8gSGFuZGxlIHVwZGF0ZSBvcGVyYXRvcnNcbiAgaWYgKHR5cGVvZiByZXN0VmFsdWUgPT09ICdvYmplY3QnICYmICdfX29wJyBpbiByZXN0VmFsdWUpIHtcbiAgICByZXR1cm4gdHJhbnNmb3JtVXBkYXRlT3BlcmF0b3IocmVzdFZhbHVlLCB0cnVlKTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBub3JtYWwgb2JqZWN0cyBieSByZWN1cnNpbmdcbiAgcmV0dXJuIG1hcFZhbHVlcyhyZXN0VmFsdWUsIHRyYW5zZm9ybUludGVyaW9yVmFsdWUpO1xufTtcblxuY29uc3QgdmFsdWVBc0RhdGUgPSB2YWx1ZSA9PiB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKHZhbHVlKTtcbiAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuZnVuY3Rpb24gdHJhbnNmb3JtUXVlcnlLZXlWYWx1ZShjbGFzc05hbWUsIGtleSwgdmFsdWUsIHNjaGVtYSwgY291bnQgPSBmYWxzZSkge1xuICBzd2l0Y2ggKGtleSkge1xuICAgIGNhc2UgJ2NyZWF0ZWRBdCc6XG4gICAgICBpZiAodmFsdWVBc0RhdGUodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB7IGtleTogJ19jcmVhdGVkX2F0JywgdmFsdWU6IHZhbHVlQXNEYXRlKHZhbHVlKSB9O1xuICAgICAgfVxuICAgICAga2V5ID0gJ19jcmVhdGVkX2F0JztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3VwZGF0ZWRBdCc6XG4gICAgICBpZiAodmFsdWVBc0RhdGUodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB7IGtleTogJ191cGRhdGVkX2F0JywgdmFsdWU6IHZhbHVlQXNEYXRlKHZhbHVlKSB9O1xuICAgICAgfVxuICAgICAga2V5ID0gJ191cGRhdGVkX2F0JztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2V4cGlyZXNBdCc6XG4gICAgICBpZiAodmFsdWVBc0RhdGUodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB7IGtleTogJ2V4cGlyZXNBdCcsIHZhbHVlOiB2YWx1ZUFzRGF0ZSh2YWx1ZSkgfTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ19lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCc6XG4gICAgICBpZiAodmFsdWVBc0RhdGUodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAga2V5OiAnX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0JyxcbiAgICAgICAgICB2YWx1ZTogdmFsdWVBc0RhdGUodmFsdWUpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnb2JqZWN0SWQnOiB7XG4gICAgICBpZiAoWydfR2xvYmFsQ29uZmlnJywgJ19HcmFwaFFMQ29uZmlnJ10uaW5jbHVkZXMoY2xhc3NOYW1lKSkge1xuICAgICAgICB2YWx1ZSA9IHBhcnNlSW50KHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7IGtleTogJ19pZCcsIHZhbHVlIH07XG4gICAgfVxuICAgIGNhc2UgJ19hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCc6XG4gICAgICBpZiAodmFsdWVBc0RhdGUodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAga2V5OiAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JyxcbiAgICAgICAgICB2YWx1ZTogdmFsdWVBc0RhdGUodmFsdWUpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX2ZhaWxlZF9sb2dpbl9jb3VudCc6XG4gICAgICByZXR1cm4geyBrZXksIHZhbHVlIH07XG4gICAgY2FzZSAnc2Vzc2lvblRva2VuJzpcbiAgICAgIHJldHVybiB7IGtleTogJ19zZXNzaW9uX3Rva2VuJywgdmFsdWUgfTtcbiAgICBjYXNlICdfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0JzpcbiAgICAgIGlmICh2YWx1ZUFzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBrZXk6ICdfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0JyxcbiAgICAgICAgICB2YWx1ZTogdmFsdWVBc0RhdGUodmFsdWUpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX3Bhc3N3b3JkX2NoYW5nZWRfYXQnOlxuICAgICAgaWYgKHZhbHVlQXNEYXRlKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4geyBrZXk6ICdfcGFzc3dvcmRfY2hhbmdlZF9hdCcsIHZhbHVlOiB2YWx1ZUFzRGF0ZSh2YWx1ZSkgfTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ19ycGVybSc6XG4gICAgY2FzZSAnX3dwZXJtJzpcbiAgICBjYXNlICdfcGVyaXNoYWJsZV90b2tlbic6XG4gICAgY2FzZSAnX2VtYWlsX3ZlcmlmeV90b2tlbic6XG4gICAgICByZXR1cm4geyBrZXksIHZhbHVlIH07XG4gICAgY2FzZSAnJG9yJzpcbiAgICBjYXNlICckYW5kJzpcbiAgICBjYXNlICckbm9yJzpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGtleToga2V5LFxuICAgICAgICB2YWx1ZTogdmFsdWUubWFwKHN1YlF1ZXJ5ID0+IHRyYW5zZm9ybVdoZXJlKGNsYXNzTmFtZSwgc3ViUXVlcnksIHNjaGVtYSwgY291bnQpKSxcbiAgICAgIH07XG4gICAgY2FzZSAnbGFzdFVzZWQnOlxuICAgICAgaWYgKHZhbHVlQXNEYXRlKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4geyBrZXk6ICdfbGFzdF91c2VkJywgdmFsdWU6IHZhbHVlQXNEYXRlKHZhbHVlKSB9O1xuICAgICAgfVxuICAgICAga2V5ID0gJ19sYXN0X3VzZWQnO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndGltZXNVc2VkJzpcbiAgICAgIHJldHVybiB7IGtleTogJ3RpbWVzX3VzZWQnLCB2YWx1ZTogdmFsdWUgfTtcbiAgICBkZWZhdWx0OiB7XG4gICAgICAvLyBPdGhlciBhdXRoIGRhdGFcbiAgICAgIGNvbnN0IGF1dGhEYXRhTWF0Y2ggPSBrZXkubWF0Y2goL15hdXRoRGF0YVxcLihbYS16QS1aMC05X10rKVxcLmlkJC8pO1xuICAgICAgaWYgKGF1dGhEYXRhTWF0Y2gpIHtcbiAgICAgICAgY29uc3QgcHJvdmlkZXIgPSBhdXRoRGF0YU1hdGNoWzFdO1xuICAgICAgICAvLyBTcGVjaWFsLWNhc2UgYXV0aCBkYXRhLlxuICAgICAgICByZXR1cm4geyBrZXk6IGBfYXV0aF9kYXRhXyR7cHJvdmlkZXJ9LmlkYCwgdmFsdWUgfTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBleHBlY3RlZFR5cGVJc0FycmF5ID0gc2NoZW1hICYmIHNjaGVtYS5maWVsZHNba2V5XSAmJiBzY2hlbWEuZmllbGRzW2tleV0udHlwZSA9PT0gJ0FycmF5JztcblxuICBjb25zdCBleHBlY3RlZFR5cGVJc1BvaW50ZXIgPVxuICAgIHNjaGVtYSAmJiBzY2hlbWEuZmllbGRzW2tleV0gJiYgc2NoZW1hLmZpZWxkc1trZXldLnR5cGUgPT09ICdQb2ludGVyJztcblxuICBjb25zdCBmaWVsZCA9IHNjaGVtYSAmJiBzY2hlbWEuZmllbGRzW2tleV07XG4gIGlmIChleHBlY3RlZFR5cGVJc1BvaW50ZXIgfHwgKCFzY2hlbWEgJiYgdmFsdWUgJiYgdmFsdWUuX190eXBlID09PSAnUG9pbnRlcicpKSB7XG4gICAga2V5ID0gJ19wXycgKyBrZXk7XG4gIH1cblxuICAvLyBIYW5kbGUgcXVlcnkgY29uc3RyYWludHNcbiAgY29uc3QgdHJhbnNmb3JtZWRDb25zdHJhaW50ID0gdHJhbnNmb3JtQ29uc3RyYWludCh2YWx1ZSwgZmllbGQsIGNvdW50KTtcbiAgaWYgKHRyYW5zZm9ybWVkQ29uc3RyYWludCAhPT0gQ2Fubm90VHJhbnNmb3JtKSB7XG4gICAgaWYgKHRyYW5zZm9ybWVkQ29uc3RyYWludC4kdGV4dCkge1xuICAgICAgcmV0dXJuIHsga2V5OiAnJHRleHQnLCB2YWx1ZTogdHJhbnNmb3JtZWRDb25zdHJhaW50LiR0ZXh0IH07XG4gICAgfVxuICAgIGlmICh0cmFuc2Zvcm1lZENvbnN0cmFpbnQuJGVsZW1NYXRjaCkge1xuICAgICAgcmV0dXJuIHsga2V5OiAnJG5vcicsIHZhbHVlOiBbeyBba2V5XTogdHJhbnNmb3JtZWRDb25zdHJhaW50IH1dIH07XG4gICAgfVxuICAgIHJldHVybiB7IGtleSwgdmFsdWU6IHRyYW5zZm9ybWVkQ29uc3RyYWludCB9O1xuICB9XG5cbiAgaWYgKGV4cGVjdGVkVHlwZUlzQXJyYXkgJiYgISh2YWx1ZSBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgIHJldHVybiB7IGtleSwgdmFsdWU6IHsgJGFsbDogW3RyYW5zZm9ybUludGVyaW9yQXRvbSh2YWx1ZSldIH0gfTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBhdG9taWMgdmFsdWVzXG4gIGlmICh0cmFuc2Zvcm1Ub3BMZXZlbEF0b20odmFsdWUpICE9PSBDYW5ub3RUcmFuc2Zvcm0pIHtcbiAgICByZXR1cm4geyBrZXksIHZhbHVlOiB0cmFuc2Zvcm1Ub3BMZXZlbEF0b20odmFsdWUpIH07XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgYFlvdSBjYW5ub3QgdXNlICR7dmFsdWV9IGFzIGEgcXVlcnkgcGFyYW1ldGVyLmBcbiAgICApO1xuICB9XG59XG5cbi8vIE1haW4gZXhwb3NlZCBtZXRob2QgdG8gaGVscCBydW4gcXVlcmllcy5cbi8vIHJlc3RXaGVyZSBpcyB0aGUgXCJ3aGVyZVwiIGNsYXVzZSBpbiBSRVNUIEFQSSBmb3JtLlxuLy8gUmV0dXJucyB0aGUgbW9uZ28gZm9ybSBvZiB0aGUgcXVlcnkuXG5mdW5jdGlvbiB0cmFuc2Zvcm1XaGVyZShjbGFzc05hbWUsIHJlc3RXaGVyZSwgc2NoZW1hLCBjb3VudCA9IGZhbHNlKSB7XG4gIGNvbnN0IG1vbmdvV2hlcmUgPSB7fTtcbiAgZm9yIChjb25zdCByZXN0S2V5IGluIHJlc3RXaGVyZSkge1xuICAgIGNvbnN0IG91dCA9IHRyYW5zZm9ybVF1ZXJ5S2V5VmFsdWUoY2xhc3NOYW1lLCByZXN0S2V5LCByZXN0V2hlcmVbcmVzdEtleV0sIHNjaGVtYSwgY291bnQpO1xuICAgIG1vbmdvV2hlcmVbb3V0LmtleV0gPSBvdXQudmFsdWU7XG4gIH1cbiAgcmV0dXJuIG1vbmdvV2hlcmU7XG59XG5cbmNvbnN0IHBhcnNlT2JqZWN0S2V5VmFsdWVUb01vbmdvT2JqZWN0S2V5VmFsdWUgPSAocmVzdEtleSwgcmVzdFZhbHVlLCBzY2hlbWEpID0+IHtcbiAgLy8gQ2hlY2sgaWYgdGhlIHNjaGVtYSBpcyBrbm93biBzaW5jZSBpdCdzIGEgYnVpbHQtaW4gZmllbGQuXG4gIGxldCB0cmFuc2Zvcm1lZFZhbHVlO1xuICBsZXQgY29lcmNlZFRvRGF0ZTtcbiAgc3dpdGNoIChyZXN0S2V5KSB7XG4gICAgY2FzZSAnb2JqZWN0SWQnOlxuICAgICAgcmV0dXJuIHsga2V5OiAnX2lkJywgdmFsdWU6IHJlc3RWYWx1ZSB9O1xuICAgIGNhc2UgJ2V4cGlyZXNBdCc6XG4gICAgICB0cmFuc2Zvcm1lZFZhbHVlID0gdHJhbnNmb3JtVG9wTGV2ZWxBdG9tKHJlc3RWYWx1ZSk7XG4gICAgICBjb2VyY2VkVG9EYXRlID1cbiAgICAgICAgdHlwZW9mIHRyYW5zZm9ybWVkVmFsdWUgPT09ICdzdHJpbmcnID8gbmV3IERhdGUodHJhbnNmb3JtZWRWYWx1ZSkgOiB0cmFuc2Zvcm1lZFZhbHVlO1xuICAgICAgcmV0dXJuIHsga2V5OiAnZXhwaXJlc0F0JywgdmFsdWU6IGNvZXJjZWRUb0RhdGUgfTtcbiAgICBjYXNlICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnOlxuICAgICAgdHJhbnNmb3JtZWRWYWx1ZSA9IHRyYW5zZm9ybVRvcExldmVsQXRvbShyZXN0VmFsdWUpO1xuICAgICAgY29lcmNlZFRvRGF0ZSA9XG4gICAgICAgIHR5cGVvZiB0cmFuc2Zvcm1lZFZhbHVlID09PSAnc3RyaW5nJyA/IG5ldyBEYXRlKHRyYW5zZm9ybWVkVmFsdWUpIDogdHJhbnNmb3JtZWRWYWx1ZTtcbiAgICAgIHJldHVybiB7IGtleTogJ19lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCcsIHZhbHVlOiBjb2VyY2VkVG9EYXRlIH07XG4gICAgY2FzZSAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JzpcbiAgICAgIHRyYW5zZm9ybWVkVmFsdWUgPSB0cmFuc2Zvcm1Ub3BMZXZlbEF0b20ocmVzdFZhbHVlKTtcbiAgICAgIGNvZXJjZWRUb0RhdGUgPVxuICAgICAgICB0eXBlb2YgdHJhbnNmb3JtZWRWYWx1ZSA9PT0gJ3N0cmluZycgPyBuZXcgRGF0ZSh0cmFuc2Zvcm1lZFZhbHVlKSA6IHRyYW5zZm9ybWVkVmFsdWU7XG4gICAgICByZXR1cm4geyBrZXk6ICdfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQnLCB2YWx1ZTogY29lcmNlZFRvRGF0ZSB9O1xuICAgIGNhc2UgJ19wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQnOlxuICAgICAgdHJhbnNmb3JtZWRWYWx1ZSA9IHRyYW5zZm9ybVRvcExldmVsQXRvbShyZXN0VmFsdWUpO1xuICAgICAgY29lcmNlZFRvRGF0ZSA9XG4gICAgICAgIHR5cGVvZiB0cmFuc2Zvcm1lZFZhbHVlID09PSAnc3RyaW5nJyA/IG5ldyBEYXRlKHRyYW5zZm9ybWVkVmFsdWUpIDogdHJhbnNmb3JtZWRWYWx1ZTtcbiAgICAgIHJldHVybiB7IGtleTogJ19wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQnLCB2YWx1ZTogY29lcmNlZFRvRGF0ZSB9O1xuICAgIGNhc2UgJ19wYXNzd29yZF9jaGFuZ2VkX2F0JzpcbiAgICAgIHRyYW5zZm9ybWVkVmFsdWUgPSB0cmFuc2Zvcm1Ub3BMZXZlbEF0b20ocmVzdFZhbHVlKTtcbiAgICAgIGNvZXJjZWRUb0RhdGUgPVxuICAgICAgICB0eXBlb2YgdHJhbnNmb3JtZWRWYWx1ZSA9PT0gJ3N0cmluZycgPyBuZXcgRGF0ZSh0cmFuc2Zvcm1lZFZhbHVlKSA6IHRyYW5zZm9ybWVkVmFsdWU7XG4gICAgICByZXR1cm4geyBrZXk6ICdfcGFzc3dvcmRfY2hhbmdlZF9hdCcsIHZhbHVlOiBjb2VyY2VkVG9EYXRlIH07XG4gICAgY2FzZSAnX2ZhaWxlZF9sb2dpbl9jb3VudCc6XG4gICAgY2FzZSAnX3JwZXJtJzpcbiAgICBjYXNlICdfd3Blcm0nOlxuICAgIGNhc2UgJ19lbWFpbF92ZXJpZnlfdG9rZW4nOlxuICAgIGNhc2UgJ19oYXNoZWRfcGFzc3dvcmQnOlxuICAgIGNhc2UgJ19wZXJpc2hhYmxlX3Rva2VuJzpcbiAgICAgIHJldHVybiB7IGtleTogcmVzdEtleSwgdmFsdWU6IHJlc3RWYWx1ZSB9O1xuICAgIGNhc2UgJ3Nlc3Npb25Ub2tlbic6XG4gICAgICByZXR1cm4geyBrZXk6ICdfc2Vzc2lvbl90b2tlbicsIHZhbHVlOiByZXN0VmFsdWUgfTtcbiAgICBkZWZhdWx0OlxuICAgICAgLy8gQXV0aCBkYXRhIHNob3VsZCBoYXZlIGJlZW4gdHJhbnNmb3JtZWQgYWxyZWFkeVxuICAgICAgaWYgKHJlc3RLZXkubWF0Y2goL15hdXRoRGF0YVxcLihbYS16QS1aMC05X10rKVxcLmlkJC8pKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FLCAnY2FuIG9ubHkgcXVlcnkgb24gJyArIHJlc3RLZXkpO1xuICAgICAgfVxuICAgICAgLy8gVHJ1c3QgdGhhdCB0aGUgYXV0aCBkYXRhIGhhcyBiZWVuIHRyYW5zZm9ybWVkIGFuZCBzYXZlIGl0IGRpcmVjdGx5XG4gICAgICBpZiAocmVzdEtleS5tYXRjaCgvXl9hdXRoX2RhdGFfW2EtekEtWjAtOV9dKyQvKSkge1xuICAgICAgICByZXR1cm4geyBrZXk6IHJlc3RLZXksIHZhbHVlOiByZXN0VmFsdWUgfTtcbiAgICAgIH1cbiAgfVxuICAvL3NraXAgc3RyYWlnaHQgdG8gdHJhbnNmb3JtVG9wTGV2ZWxBdG9tIGZvciBCeXRlcywgdGhleSBkb24ndCBzaG93IHVwIGluIHRoZSBzY2hlbWEgZm9yIHNvbWUgcmVhc29uXG4gIGlmIChyZXN0VmFsdWUgJiYgcmVzdFZhbHVlLl9fdHlwZSAhPT0gJ0J5dGVzJykge1xuICAgIC8vTm90ZTogV2UgbWF5IG5vdCBrbm93IHRoZSB0eXBlIG9mIGEgZmllbGQgaGVyZSwgYXMgdGhlIHVzZXIgY291bGQgYmUgc2F2aW5nIChudWxsKSB0byBhIGZpZWxkXG4gICAgLy9UaGF0IG5ldmVyIGV4aXN0ZWQgYmVmb3JlLCBtZWFuaW5nIHdlIGNhbid0IGluZmVyIHRoZSB0eXBlLlxuICAgIGlmIChcbiAgICAgIChzY2hlbWEuZmllbGRzW3Jlc3RLZXldICYmIHNjaGVtYS5maWVsZHNbcmVzdEtleV0udHlwZSA9PSAnUG9pbnRlcicpIHx8XG4gICAgICByZXN0VmFsdWUuX190eXBlID09ICdQb2ludGVyJ1xuICAgICkge1xuICAgICAgcmVzdEtleSA9ICdfcF8nICsgcmVzdEtleTtcbiAgICB9XG4gIH1cblxuICAvLyBIYW5kbGUgYXRvbWljIHZhbHVlc1xuICB2YXIgdmFsdWUgPSB0cmFuc2Zvcm1Ub3BMZXZlbEF0b20ocmVzdFZhbHVlKTtcbiAgaWYgKHZhbHVlICE9PSBDYW5ub3RUcmFuc2Zvcm0pIHtcbiAgICByZXR1cm4geyBrZXk6IHJlc3RLZXksIHZhbHVlOiB2YWx1ZSB9O1xuICB9XG5cbiAgLy8gQUNMcyBhcmUgaGFuZGxlZCBiZWZvcmUgdGhpcyBtZXRob2QgaXMgY2FsbGVkXG4gIC8vIElmIGFuIEFDTCBrZXkgc3RpbGwgZXhpc3RzIGhlcmUsIHNvbWV0aGluZyBpcyB3cm9uZy5cbiAgaWYgKHJlc3RLZXkgPT09ICdBQ0wnKSB7XG4gICAgdGhyb3cgJ1RoZXJlIHdhcyBhIHByb2JsZW0gdHJhbnNmb3JtaW5nIGFuIEFDTC4nO1xuICB9XG5cbiAgLy8gSGFuZGxlIGFycmF5c1xuICBpZiAocmVzdFZhbHVlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICB2YWx1ZSA9IHJlc3RWYWx1ZS5tYXAodHJhbnNmb3JtSW50ZXJpb3JWYWx1ZSk7XG4gICAgcmV0dXJuIHsga2V5OiByZXN0S2V5LCB2YWx1ZTogdmFsdWUgfTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBub3JtYWwgb2JqZWN0cyBieSByZWN1cnNpbmdcbiAgaWYgKE9iamVjdC5rZXlzKHJlc3RWYWx1ZSkuc29tZShrZXkgPT4ga2V5LmluY2x1ZGVzKCckJykgfHwga2V5LmluY2x1ZGVzKCcuJykpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9ORVNURURfS0VZLFxuICAgICAgXCJOZXN0ZWQga2V5cyBzaG91bGQgbm90IGNvbnRhaW4gdGhlICckJyBvciAnLicgY2hhcmFjdGVyc1wiXG4gICAgKTtcbiAgfVxuICB2YWx1ZSA9IG1hcFZhbHVlcyhyZXN0VmFsdWUsIHRyYW5zZm9ybUludGVyaW9yVmFsdWUpO1xuICByZXR1cm4geyBrZXk6IHJlc3RLZXksIHZhbHVlIH07XG59O1xuXG5jb25zdCBwYXJzZU9iamVjdFRvTW9uZ29PYmplY3RGb3JDcmVhdGUgPSAoY2xhc3NOYW1lLCByZXN0Q3JlYXRlLCBzY2hlbWEpID0+IHtcbiAgcmVzdENyZWF0ZSA9IGFkZExlZ2FjeUFDTChyZXN0Q3JlYXRlKTtcbiAgY29uc3QgbW9uZ29DcmVhdGUgPSB7fTtcbiAgZm9yIChjb25zdCByZXN0S2V5IGluIHJlc3RDcmVhdGUpIHtcbiAgICBpZiAocmVzdENyZWF0ZVtyZXN0S2V5XSAmJiByZXN0Q3JlYXRlW3Jlc3RLZXldLl9fdHlwZSA9PT0gJ1JlbGF0aW9uJykge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IHsga2V5LCB2YWx1ZSB9ID0gcGFyc2VPYmplY3RLZXlWYWx1ZVRvTW9uZ29PYmplY3RLZXlWYWx1ZShcbiAgICAgIHJlc3RLZXksXG4gICAgICByZXN0Q3JlYXRlW3Jlc3RLZXldLFxuICAgICAgc2NoZW1hXG4gICAgKTtcbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgbW9uZ29DcmVhdGVba2V5XSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIC8vIFVzZSB0aGUgbGVnYWN5IG1vbmdvIGZvcm1hdCBmb3IgY3JlYXRlZEF0IGFuZCB1cGRhdGVkQXRcbiAgaWYgKG1vbmdvQ3JlYXRlLmNyZWF0ZWRBdCkge1xuICAgIG1vbmdvQ3JlYXRlLl9jcmVhdGVkX2F0ID0gbmV3IERhdGUobW9uZ29DcmVhdGUuY3JlYXRlZEF0LmlzbyB8fCBtb25nb0NyZWF0ZS5jcmVhdGVkQXQpO1xuICAgIGRlbGV0ZSBtb25nb0NyZWF0ZS5jcmVhdGVkQXQ7XG4gIH1cbiAgaWYgKG1vbmdvQ3JlYXRlLnVwZGF0ZWRBdCkge1xuICAgIG1vbmdvQ3JlYXRlLl91cGRhdGVkX2F0ID0gbmV3IERhdGUobW9uZ29DcmVhdGUudXBkYXRlZEF0LmlzbyB8fCBtb25nb0NyZWF0ZS51cGRhdGVkQXQpO1xuICAgIGRlbGV0ZSBtb25nb0NyZWF0ZS51cGRhdGVkQXQ7XG4gIH1cblxuICByZXR1cm4gbW9uZ29DcmVhdGU7XG59O1xuXG4vLyBNYWluIGV4cG9zZWQgbWV0aG9kIHRvIGhlbHAgdXBkYXRlIG9sZCBvYmplY3RzLlxuY29uc3QgdHJhbnNmb3JtVXBkYXRlID0gKGNsYXNzTmFtZSwgcmVzdFVwZGF0ZSwgcGFyc2VGb3JtYXRTY2hlbWEpID0+IHtcbiAgY29uc3QgbW9uZ29VcGRhdGUgPSB7fTtcbiAgY29uc3QgYWNsID0gYWRkTGVnYWN5QUNMKHJlc3RVcGRhdGUpO1xuICBpZiAoYWNsLl9ycGVybSB8fCBhY2wuX3dwZXJtIHx8IGFjbC5fYWNsKSB7XG4gICAgbW9uZ29VcGRhdGUuJHNldCA9IHt9O1xuICAgIGlmIChhY2wuX3JwZXJtKSB7XG4gICAgICBtb25nb1VwZGF0ZS4kc2V0Ll9ycGVybSA9IGFjbC5fcnBlcm07XG4gICAgfVxuICAgIGlmIChhY2wuX3dwZXJtKSB7XG4gICAgICBtb25nb1VwZGF0ZS4kc2V0Ll93cGVybSA9IGFjbC5fd3Blcm07XG4gICAgfVxuICAgIGlmIChhY2wuX2FjbCkge1xuICAgICAgbW9uZ29VcGRhdGUuJHNldC5fYWNsID0gYWNsLl9hY2w7XG4gICAgfVxuICB9XG4gIGZvciAodmFyIHJlc3RLZXkgaW4gcmVzdFVwZGF0ZSkge1xuICAgIGlmIChyZXN0VXBkYXRlW3Jlc3RLZXldICYmIHJlc3RVcGRhdGVbcmVzdEtleV0uX190eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgdmFyIG91dCA9IHRyYW5zZm9ybUtleVZhbHVlRm9yVXBkYXRlKFxuICAgICAgY2xhc3NOYW1lLFxuICAgICAgcmVzdEtleSxcbiAgICAgIHJlc3RVcGRhdGVbcmVzdEtleV0sXG4gICAgICBwYXJzZUZvcm1hdFNjaGVtYVxuICAgICk7XG5cbiAgICAvLyBJZiB0aGUgb3V0cHV0IHZhbHVlIGlzIGFuIG9iamVjdCB3aXRoIGFueSAkIGtleXMsIGl0J3MgYW5cbiAgICAvLyBvcGVyYXRvciB0aGF0IG5lZWRzIHRvIGJlIGxpZnRlZCBvbnRvIHRoZSB0b3AgbGV2ZWwgdXBkYXRlXG4gICAgLy8gb2JqZWN0LlxuICAgIGlmICh0eXBlb2Ygb3V0LnZhbHVlID09PSAnb2JqZWN0JyAmJiBvdXQudmFsdWUgIT09IG51bGwgJiYgb3V0LnZhbHVlLl9fb3ApIHtcbiAgICAgIG1vbmdvVXBkYXRlW291dC52YWx1ZS5fX29wXSA9IG1vbmdvVXBkYXRlW291dC52YWx1ZS5fX29wXSB8fCB7fTtcbiAgICAgIG1vbmdvVXBkYXRlW291dC52YWx1ZS5fX29wXVtvdXQua2V5XSA9IG91dC52YWx1ZS5hcmc7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1vbmdvVXBkYXRlWyckc2V0J10gPSBtb25nb1VwZGF0ZVsnJHNldCddIHx8IHt9O1xuICAgICAgbW9uZ29VcGRhdGVbJyRzZXQnXVtvdXQua2V5XSA9IG91dC52YWx1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbW9uZ29VcGRhdGU7XG59O1xuXG4vLyBBZGQgdGhlIGxlZ2FjeSBfYWNsIGZvcm1hdC5cbmNvbnN0IGFkZExlZ2FjeUFDTCA9IHJlc3RPYmplY3QgPT4ge1xuICBjb25zdCByZXN0T2JqZWN0Q29weSA9IHsgLi4ucmVzdE9iamVjdCB9O1xuICBjb25zdCBfYWNsID0ge307XG5cbiAgaWYgKHJlc3RPYmplY3QuX3dwZXJtKSB7XG4gICAgcmVzdE9iamVjdC5fd3Blcm0uZm9yRWFjaChlbnRyeSA9PiB7XG4gICAgICBfYWNsW2VudHJ5XSA9IHsgdzogdHJ1ZSB9O1xuICAgIH0pO1xuICAgIHJlc3RPYmplY3RDb3B5Ll9hY2wgPSBfYWNsO1xuICB9XG5cbiAgaWYgKHJlc3RPYmplY3QuX3JwZXJtKSB7XG4gICAgcmVzdE9iamVjdC5fcnBlcm0uZm9yRWFjaChlbnRyeSA9PiB7XG4gICAgICBpZiAoIShlbnRyeSBpbiBfYWNsKSkge1xuICAgICAgICBfYWNsW2VudHJ5XSA9IHsgcjogdHJ1ZSB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgX2FjbFtlbnRyeV0uciA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmVzdE9iamVjdENvcHkuX2FjbCA9IF9hY2w7XG4gIH1cblxuICByZXR1cm4gcmVzdE9iamVjdENvcHk7XG59O1xuXG4vLyBBIHNlbnRpbmVsIHZhbHVlIHRoYXQgaGVscGVyIHRyYW5zZm9ybWF0aW9ucyByZXR1cm4gd2hlbiB0aGV5XG4vLyBjYW5ub3QgcGVyZm9ybSBhIHRyYW5zZm9ybWF0aW9uXG5mdW5jdGlvbiBDYW5ub3RUcmFuc2Zvcm0oKSB7fVxuXG5jb25zdCB0cmFuc2Zvcm1JbnRlcmlvckF0b20gPSBhdG9tID0+IHtcbiAgLy8gVE9ETzogY2hlY2sgdmFsaWRpdHkgaGFyZGVyIGZvciB0aGUgX190eXBlLWRlZmluZWQgdHlwZXNcbiAgaWYgKHR5cGVvZiBhdG9tID09PSAnb2JqZWN0JyAmJiBhdG9tICYmICEoYXRvbSBpbnN0YW5jZW9mIERhdGUpICYmIGF0b20uX190eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICByZXR1cm4ge1xuICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICBjbGFzc05hbWU6IGF0b20uY2xhc3NOYW1lLFxuICAgICAgb2JqZWN0SWQ6IGF0b20ub2JqZWN0SWQsXG4gICAgfTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgYXRvbSA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgYXRvbSA9PT0gJ3N5bWJvbCcpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCBgY2Fubm90IHRyYW5zZm9ybSB2YWx1ZTogJHthdG9tfWApO1xuICB9IGVsc2UgaWYgKERhdGVDb2Rlci5pc1ZhbGlkSlNPTihhdG9tKSkge1xuICAgIHJldHVybiBEYXRlQ29kZXIuSlNPTlRvRGF0YWJhc2UoYXRvbSk7XG4gIH0gZWxzZSBpZiAoQnl0ZXNDb2Rlci5pc1ZhbGlkSlNPTihhdG9tKSkge1xuICAgIHJldHVybiBCeXRlc0NvZGVyLkpTT05Ub0RhdGFiYXNlKGF0b20pO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBhdG9tID09PSAnb2JqZWN0JyAmJiBhdG9tICYmIGF0b20uJHJlZ2V4ICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gbmV3IFJlZ0V4cChhdG9tLiRyZWdleCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGF0b207XG4gIH1cbn07XG5cbi8vIEhlbHBlciBmdW5jdGlvbiB0byB0cmFuc2Zvcm0gYW4gYXRvbSBmcm9tIFJFU1QgZm9ybWF0IHRvIE1vbmdvIGZvcm1hdC5cbi8vIEFuIGF0b20gaXMgYW55dGhpbmcgdGhhdCBjYW4ndCBjb250YWluIG90aGVyIGV4cHJlc3Npb25zLiBTbyBpdFxuLy8gaW5jbHVkZXMgdGhpbmdzIHdoZXJlIG9iamVjdHMgYXJlIHVzZWQgdG8gcmVwcmVzZW50IG90aGVyXG4vLyBkYXRhdHlwZXMsIGxpa2UgcG9pbnRlcnMgYW5kIGRhdGVzLCBidXQgaXQgZG9lcyBub3QgaW5jbHVkZSBvYmplY3RzXG4vLyBvciBhcnJheXMgd2l0aCBnZW5lcmljIHN0dWZmIGluc2lkZS5cbi8vIFJhaXNlcyBhbiBlcnJvciBpZiB0aGlzIGNhbm5vdCBwb3NzaWJseSBiZSB2YWxpZCBSRVNUIGZvcm1hdC5cbi8vIFJldHVybnMgQ2Fubm90VHJhbnNmb3JtIGlmIGl0J3MganVzdCBub3QgYW4gYXRvbVxuZnVuY3Rpb24gdHJhbnNmb3JtVG9wTGV2ZWxBdG9tKGF0b20sIGZpZWxkKSB7XG4gIHN3aXRjaCAodHlwZW9mIGF0b20pIHtcbiAgICBjYXNlICdudW1iZXInOlxuICAgIGNhc2UgJ2Jvb2xlYW4nOlxuICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgICByZXR1cm4gYXRvbTtcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgaWYgKGZpZWxkICYmIGZpZWxkLnR5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgICByZXR1cm4gYCR7ZmllbGQudGFyZ2V0Q2xhc3N9JCR7YXRvbX1gO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGF0b207XG4gICAgY2FzZSAnc3ltYm9sJzpcbiAgICBjYXNlICdmdW5jdGlvbic6XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCBgY2Fubm90IHRyYW5zZm9ybSB2YWx1ZTogJHthdG9tfWApO1xuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICBpZiAoYXRvbSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgLy8gVGVjaG5pY2FsbHkgZGF0ZXMgYXJlIG5vdCByZXN0IGZvcm1hdCwgYnV0LCBpdCBzZWVtcyBwcmV0dHlcbiAgICAgICAgLy8gY2xlYXIgd2hhdCB0aGV5IHNob3VsZCBiZSB0cmFuc2Zvcm1lZCB0bywgc28gbGV0J3MganVzdCBkbyBpdC5cbiAgICAgICAgcmV0dXJuIGF0b207XG4gICAgICB9XG5cbiAgICAgIGlmIChhdG9tID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBhdG9tO1xuICAgICAgfVxuXG4gICAgICAvLyBUT0RPOiBjaGVjayB2YWxpZGl0eSBoYXJkZXIgZm9yIHRoZSBfX3R5cGUtZGVmaW5lZCB0eXBlc1xuICAgICAgaWYgKGF0b20uX190eXBlID09ICdQb2ludGVyJykge1xuICAgICAgICByZXR1cm4gYCR7YXRvbS5jbGFzc05hbWV9JCR7YXRvbS5vYmplY3RJZH1gO1xuICAgICAgfVxuICAgICAgaWYgKERhdGVDb2Rlci5pc1ZhbGlkSlNPTihhdG9tKSkge1xuICAgICAgICByZXR1cm4gRGF0ZUNvZGVyLkpTT05Ub0RhdGFiYXNlKGF0b20pO1xuICAgICAgfVxuICAgICAgaWYgKEJ5dGVzQ29kZXIuaXNWYWxpZEpTT04oYXRvbSkpIHtcbiAgICAgICAgcmV0dXJuIEJ5dGVzQ29kZXIuSlNPTlRvRGF0YWJhc2UoYXRvbSk7XG4gICAgICB9XG4gICAgICBpZiAoR2VvUG9pbnRDb2Rlci5pc1ZhbGlkSlNPTihhdG9tKSkge1xuICAgICAgICByZXR1cm4gR2VvUG9pbnRDb2Rlci5KU09OVG9EYXRhYmFzZShhdG9tKTtcbiAgICAgIH1cbiAgICAgIGlmIChQb2x5Z29uQ29kZXIuaXNWYWxpZEpTT04oYXRvbSkpIHtcbiAgICAgICAgcmV0dXJuIFBvbHlnb25Db2Rlci5KU09OVG9EYXRhYmFzZShhdG9tKTtcbiAgICAgIH1cbiAgICAgIGlmIChGaWxlQ29kZXIuaXNWYWxpZEpTT04oYXRvbSkpIHtcbiAgICAgICAgcmV0dXJuIEZpbGVDb2Rlci5KU09OVG9EYXRhYmFzZShhdG9tKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBDYW5ub3RUcmFuc2Zvcm07XG5cbiAgICBkZWZhdWx0OlxuICAgICAgLy8gSSBkb24ndCB0aGluayB0eXBlb2YgY2FuIGV2ZXIgbGV0IHVzIGdldCBoZXJlXG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUixcbiAgICAgICAgYHJlYWxseSBkaWQgbm90IGV4cGVjdCB2YWx1ZTogJHthdG9tfWBcbiAgICAgICk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVsYXRpdmVUaW1lVG9EYXRlKHRleHQsIG5vdyA9IG5ldyBEYXRlKCkpIHtcbiAgdGV4dCA9IHRleHQudG9Mb3dlckNhc2UoKTtcblxuICBsZXQgcGFydHMgPSB0ZXh0LnNwbGl0KCcgJyk7XG5cbiAgLy8gRmlsdGVyIG91dCB3aGl0ZXNwYWNlXG4gIHBhcnRzID0gcGFydHMuZmlsdGVyKHBhcnQgPT4gcGFydCAhPT0gJycpO1xuXG4gIGNvbnN0IGZ1dHVyZSA9IHBhcnRzWzBdID09PSAnaW4nO1xuICBjb25zdCBwYXN0ID0gcGFydHNbcGFydHMubGVuZ3RoIC0gMV0gPT09ICdhZ28nO1xuXG4gIGlmICghZnV0dXJlICYmICFwYXN0ICYmIHRleHQgIT09ICdub3cnKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXR1czogJ2Vycm9yJyxcbiAgICAgIGluZm86IFwiVGltZSBzaG91bGQgZWl0aGVyIHN0YXJ0IHdpdGggJ2luJyBvciBlbmQgd2l0aCAnYWdvJ1wiLFxuICAgIH07XG4gIH1cblxuICBpZiAoZnV0dXJlICYmIHBhc3QpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiAnZXJyb3InLFxuICAgICAgaW5mbzogXCJUaW1lIGNhbm5vdCBoYXZlIGJvdGggJ2luJyBhbmQgJ2FnbydcIixcbiAgICB9O1xuICB9XG5cbiAgLy8gc3RyaXAgdGhlICdhZ28nIG9yICdpbidcbiAgaWYgKGZ1dHVyZSkge1xuICAgIHBhcnRzID0gcGFydHMuc2xpY2UoMSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gcGFzdFxuICAgIHBhcnRzID0gcGFydHMuc2xpY2UoMCwgcGFydHMubGVuZ3RoIC0gMSk7XG4gIH1cblxuICBpZiAocGFydHMubGVuZ3RoICUgMiAhPT0gMCAmJiB0ZXh0ICE9PSAnbm93Jykge1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXM6ICdlcnJvcicsXG4gICAgICBpbmZvOiAnSW52YWxpZCB0aW1lIHN0cmluZy4gRGFuZ2xpbmcgdW5pdCBvciBudW1iZXIuJyxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgcGFpcnMgPSBbXTtcbiAgd2hpbGUgKHBhcnRzLmxlbmd0aCkge1xuICAgIHBhaXJzLnB1c2goW3BhcnRzLnNoaWZ0KCksIHBhcnRzLnNoaWZ0KCldKTtcbiAgfVxuXG4gIGxldCBzZWNvbmRzID0gMDtcbiAgZm9yIChjb25zdCBbbnVtLCBpbnRlcnZhbF0gb2YgcGFpcnMpIHtcbiAgICBjb25zdCB2YWwgPSBOdW1iZXIobnVtKTtcbiAgICBpZiAoIU51bWJlci5pc0ludGVnZXIodmFsKSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3RhdHVzOiAnZXJyb3InLFxuICAgICAgICBpbmZvOiBgJyR7bnVtfScgaXMgbm90IGFuIGludGVnZXIuYCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgc3dpdGNoIChpbnRlcnZhbCkge1xuICAgICAgY2FzZSAneXInOlxuICAgICAgY2FzZSAneXJzJzpcbiAgICAgIGNhc2UgJ3llYXInOlxuICAgICAgY2FzZSAneWVhcnMnOlxuICAgICAgICBzZWNvbmRzICs9IHZhbCAqIDMxNTM2MDAwOyAvLyAzNjUgKiAyNCAqIDYwICogNjBcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3drJzpcbiAgICAgIGNhc2UgJ3drcyc6XG4gICAgICBjYXNlICd3ZWVrJzpcbiAgICAgIGNhc2UgJ3dlZWtzJzpcbiAgICAgICAgc2Vjb25kcyArPSB2YWwgKiA2MDQ4MDA7IC8vIDcgKiAyNCAqIDYwICogNjBcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2QnOlxuICAgICAgY2FzZSAnZGF5JzpcbiAgICAgIGNhc2UgJ2RheXMnOlxuICAgICAgICBzZWNvbmRzICs9IHZhbCAqIDg2NDAwOyAvLyAyNCAqIDYwICogNjBcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2hyJzpcbiAgICAgIGNhc2UgJ2hycyc6XG4gICAgICBjYXNlICdob3VyJzpcbiAgICAgIGNhc2UgJ2hvdXJzJzpcbiAgICAgICAgc2Vjb25kcyArPSB2YWwgKiAzNjAwOyAvLyA2MCAqIDYwXG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdtaW4nOlxuICAgICAgY2FzZSAnbWlucyc6XG4gICAgICBjYXNlICdtaW51dGUnOlxuICAgICAgY2FzZSAnbWludXRlcyc6XG4gICAgICAgIHNlY29uZHMgKz0gdmFsICogNjA7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdzZWMnOlxuICAgICAgY2FzZSAnc2Vjcyc6XG4gICAgICBjYXNlICdzZWNvbmQnOlxuICAgICAgY2FzZSAnc2Vjb25kcyc6XG4gICAgICAgIHNlY29uZHMgKz0gdmFsO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdGF0dXM6ICdlcnJvcicsXG4gICAgICAgICAgaW5mbzogYEludmFsaWQgaW50ZXJ2YWw6ICcke2ludGVydmFsfSdgLFxuICAgICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG1pbGxpc2Vjb25kcyA9IHNlY29uZHMgKiAxMDAwO1xuICBpZiAoZnV0dXJlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnLFxuICAgICAgaW5mbzogJ2Z1dHVyZScsXG4gICAgICByZXN1bHQ6IG5ldyBEYXRlKG5vdy52YWx1ZU9mKCkgKyBtaWxsaXNlY29uZHMpLFxuICAgIH07XG4gIH0gZWxzZSBpZiAocGFzdCkge1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXM6ICdzdWNjZXNzJyxcbiAgICAgIGluZm86ICdwYXN0JyxcbiAgICAgIHJlc3VsdDogbmV3IERhdGUobm93LnZhbHVlT2YoKSAtIG1pbGxpc2Vjb25kcyksXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiAnc3VjY2VzcycsXG4gICAgICBpbmZvOiAncHJlc2VudCcsXG4gICAgICByZXN1bHQ6IG5ldyBEYXRlKG5vdy52YWx1ZU9mKCkpLFxuICAgIH07XG4gIH1cbn1cblxuLy8gVHJhbnNmb3JtcyBhIHF1ZXJ5IGNvbnN0cmFpbnQgZnJvbSBSRVNUIEFQSSBmb3JtYXQgdG8gTW9uZ28gZm9ybWF0LlxuLy8gQSBjb25zdHJhaW50IGlzIHNvbWV0aGluZyB3aXRoIGZpZWxkcyBsaWtlICRsdC5cbi8vIElmIGl0IGlzIG5vdCBhIHZhbGlkIGNvbnN0cmFpbnQgYnV0IGl0IGNvdWxkIGJlIGEgdmFsaWQgc29tZXRoaW5nXG4vLyBlbHNlLCByZXR1cm4gQ2Fubm90VHJhbnNmb3JtLlxuLy8gaW5BcnJheSBpcyB3aGV0aGVyIHRoaXMgaXMgYW4gYXJyYXkgZmllbGQuXG5mdW5jdGlvbiB0cmFuc2Zvcm1Db25zdHJhaW50KGNvbnN0cmFpbnQsIGZpZWxkLCBjb3VudCA9IGZhbHNlKSB7XG4gIGNvbnN0IGluQXJyYXkgPSBmaWVsZCAmJiBmaWVsZC50eXBlICYmIGZpZWxkLnR5cGUgPT09ICdBcnJheSc7XG4gIGlmICh0eXBlb2YgY29uc3RyYWludCAhPT0gJ29iamVjdCcgfHwgIWNvbnN0cmFpbnQpIHtcbiAgICByZXR1cm4gQ2Fubm90VHJhbnNmb3JtO1xuICB9XG4gIGNvbnN0IHRyYW5zZm9ybUZ1bmN0aW9uID0gaW5BcnJheSA/IHRyYW5zZm9ybUludGVyaW9yQXRvbSA6IHRyYW5zZm9ybVRvcExldmVsQXRvbTtcbiAgY29uc3QgdHJhbnNmb3JtZXIgPSBhdG9tID0+IHtcbiAgICBjb25zdCByZXN1bHQgPSB0cmFuc2Zvcm1GdW5jdGlvbihhdG9tLCBmaWVsZCk7XG4gICAgaWYgKHJlc3VsdCA9PT0gQ2Fubm90VHJhbnNmb3JtKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCBgYmFkIGF0b206ICR7SlNPTi5zdHJpbmdpZnkoYXRvbSl9YCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG4gIC8vIGtleXMgaXMgdGhlIGNvbnN0cmFpbnRzIGluIHJldmVyc2UgYWxwaGFiZXRpY2FsIG9yZGVyLlxuICAvLyBUaGlzIGlzIGEgaGFjayBzbyB0aGF0OlxuICAvLyAgICRyZWdleCBpcyBoYW5kbGVkIGJlZm9yZSAkb3B0aW9uc1xuICAvLyAgICRuZWFyU3BoZXJlIGlzIGhhbmRsZWQgYmVmb3JlICRtYXhEaXN0YW5jZVxuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGNvbnN0cmFpbnQpLnNvcnQoKS5yZXZlcnNlKCk7XG4gIHZhciBhbnN3ZXIgPSB7fTtcbiAgZm9yICh2YXIga2V5IG9mIGtleXMpIHtcbiAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgY2FzZSAnJGx0JzpcbiAgICAgIGNhc2UgJyRsdGUnOlxuICAgICAgY2FzZSAnJGd0JzpcbiAgICAgIGNhc2UgJyRndGUnOlxuICAgICAgY2FzZSAnJGV4aXN0cyc6XG4gICAgICBjYXNlICckbmUnOlxuICAgICAgY2FzZSAnJGVxJzoge1xuICAgICAgICBjb25zdCB2YWwgPSBjb25zdHJhaW50W2tleV07XG4gICAgICAgIGlmICh2YWwgJiYgdHlwZW9mIHZhbCA9PT0gJ29iamVjdCcgJiYgdmFsLiRyZWxhdGl2ZVRpbWUpIHtcbiAgICAgICAgICBpZiAoZmllbGQgJiYgZmllbGQudHlwZSAhPT0gJ0RhdGUnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgJyRyZWxhdGl2ZVRpbWUgY2FuIG9ubHkgYmUgdXNlZCB3aXRoIERhdGUgZmllbGQnXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHN3aXRjaCAoa2V5KSB7XG4gICAgICAgICAgICBjYXNlICckZXhpc3RzJzpcbiAgICAgICAgICAgIGNhc2UgJyRuZSc6XG4gICAgICAgICAgICBjYXNlICckZXEnOlxuICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgICAgICckcmVsYXRpdmVUaW1lIGNhbiBvbmx5IGJlIHVzZWQgd2l0aCB0aGUgJGx0LCAkbHRlLCAkZ3QsIGFuZCAkZ3RlIG9wZXJhdG9ycydcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBwYXJzZXJSZXN1bHQgPSByZWxhdGl2ZVRpbWVUb0RhdGUodmFsLiRyZWxhdGl2ZVRpbWUpO1xuICAgICAgICAgIGlmIChwYXJzZXJSZXN1bHQuc3RhdHVzID09PSAnc3VjY2VzcycpIHtcbiAgICAgICAgICAgIGFuc3dlcltrZXldID0gcGFyc2VyUmVzdWx0LnJlc3VsdDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGxvZy5pbmZvKCdFcnJvciB3aGlsZSBwYXJzaW5nIHJlbGF0aXZlIGRhdGUnLCBwYXJzZXJSZXN1bHQpO1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgIGBiYWQgJHJlbGF0aXZlVGltZSAoJHtrZXl9KSB2YWx1ZS4gJHtwYXJzZXJSZXN1bHQuaW5mb31gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGFuc3dlcltrZXldID0gdHJhbnNmb3JtZXIodmFsKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJyRpbic6XG4gICAgICBjYXNlICckbmluJzoge1xuICAgICAgICBjb25zdCBhcnIgPSBjb25zdHJhaW50W2tleV07XG4gICAgICAgIGlmICghKGFyciBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sICdiYWQgJyArIGtleSArICcgdmFsdWUnKTtcbiAgICAgICAgfVxuICAgICAgICBhbnN3ZXJba2V5XSA9IF8uZmxhdE1hcChhcnIsIHZhbHVlID0+IHtcbiAgICAgICAgICByZXR1cm4gKGF0b20gPT4ge1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYXRvbSkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLm1hcCh0cmFuc2Zvcm1lcik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gdHJhbnNmb3JtZXIoYXRvbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSkodmFsdWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICckYWxsJzoge1xuICAgICAgICBjb25zdCBhcnIgPSBjb25zdHJhaW50W2tleV07XG4gICAgICAgIGlmICghKGFyciBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sICdiYWQgJyArIGtleSArICcgdmFsdWUnKTtcbiAgICAgICAgfVxuICAgICAgICBhbnN3ZXJba2V5XSA9IGFyci5tYXAodHJhbnNmb3JtSW50ZXJpb3JBdG9tKTtcblxuICAgICAgICBjb25zdCB2YWx1ZXMgPSBhbnN3ZXJba2V5XTtcbiAgICAgICAgaWYgKGlzQW55VmFsdWVSZWdleCh2YWx1ZXMpICYmICFpc0FsbFZhbHVlc1JlZ2V4T3JOb25lKHZhbHVlcykpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAnQWxsICRhbGwgdmFsdWVzIG11c3QgYmUgb2YgcmVnZXggdHlwZSBvciBub25lOiAnICsgdmFsdWVzXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnJHJlZ2V4JzpcbiAgICAgICAgdmFyIHMgPSBjb25zdHJhaW50W2tleV07XG4gICAgICAgIGlmICh0eXBlb2YgcyAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnYmFkIHJlZ2V4OiAnICsgcyk7XG4gICAgICAgIH1cbiAgICAgICAgYW5zd2VyW2tleV0gPSBzO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnJGNvbnRhaW5lZEJ5Jzoge1xuICAgICAgICBjb25zdCBhcnIgPSBjb25zdHJhaW50W2tleV07XG4gICAgICAgIGlmICghKGFyciBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sIGBiYWQgJGNvbnRhaW5lZEJ5OiBzaG91bGQgYmUgYW4gYXJyYXlgKTtcbiAgICAgICAgfVxuICAgICAgICBhbnN3ZXIuJGVsZW1NYXRjaCA9IHtcbiAgICAgICAgICAkbmluOiBhcnIubWFwKHRyYW5zZm9ybWVyKSxcbiAgICAgICAgfTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICckb3B0aW9ucyc6XG4gICAgICAgIGFuc3dlcltrZXldID0gY29uc3RyYWludFtrZXldO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnJHRleHQnOiB7XG4gICAgICAgIGNvbnN0IHNlYXJjaCA9IGNvbnN0cmFpbnRba2V5XS4kc2VhcmNoO1xuICAgICAgICBpZiAodHlwZW9mIHNlYXJjaCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCBgYmFkICR0ZXh0OiAkc2VhcmNoLCBzaG91bGQgYmUgb2JqZWN0YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFzZWFyY2guJHRlcm0gfHwgdHlwZW9mIHNlYXJjaC4kdGVybSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCBgYmFkICR0ZXh0OiAkdGVybSwgc2hvdWxkIGJlIHN0cmluZ2ApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGFuc3dlcltrZXldID0ge1xuICAgICAgICAgICAgJHNlYXJjaDogc2VhcmNoLiR0ZXJtLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNlYXJjaC4kbGFuZ3VhZ2UgJiYgdHlwZW9mIHNlYXJjaC4kbGFuZ3VhZ2UgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgYGJhZCAkdGV4dDogJGxhbmd1YWdlLCBzaG91bGQgYmUgc3RyaW5nYCk7XG4gICAgICAgIH0gZWxzZSBpZiAoc2VhcmNoLiRsYW5ndWFnZSkge1xuICAgICAgICAgIGFuc3dlcltrZXldLiRsYW5ndWFnZSA9IHNlYXJjaC4kbGFuZ3VhZ2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNlYXJjaC4kY2FzZVNlbnNpdGl2ZSAmJiB0eXBlb2Ygc2VhcmNoLiRjYXNlU2Vuc2l0aXZlICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICBgYmFkICR0ZXh0OiAkY2FzZVNlbnNpdGl2ZSwgc2hvdWxkIGJlIGJvb2xlYW5gXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmIChzZWFyY2guJGNhc2VTZW5zaXRpdmUpIHtcbiAgICAgICAgICBhbnN3ZXJba2V5XS4kY2FzZVNlbnNpdGl2ZSA9IHNlYXJjaC4kY2FzZVNlbnNpdGl2ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2VhcmNoLiRkaWFjcml0aWNTZW5zaXRpdmUgJiYgdHlwZW9mIHNlYXJjaC4kZGlhY3JpdGljU2Vuc2l0aXZlICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICBgYmFkICR0ZXh0OiAkZGlhY3JpdGljU2Vuc2l0aXZlLCBzaG91bGQgYmUgYm9vbGVhbmBcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKHNlYXJjaC4kZGlhY3JpdGljU2Vuc2l0aXZlKSB7XG4gICAgICAgICAgYW5zd2VyW2tleV0uJGRpYWNyaXRpY1NlbnNpdGl2ZSA9IHNlYXJjaC4kZGlhY3JpdGljU2Vuc2l0aXZlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnJG5lYXJTcGhlcmUnOiB7XG4gICAgICAgIGNvbnN0IHBvaW50ID0gY29uc3RyYWludFtrZXldO1xuICAgICAgICBpZiAoY291bnQpIHtcbiAgICAgICAgICBhbnN3ZXIuJGdlb1dpdGhpbiA9IHtcbiAgICAgICAgICAgICRjZW50ZXJTcGhlcmU6IFtbcG9pbnQubG9uZ2l0dWRlLCBwb2ludC5sYXRpdHVkZV0sIGNvbnN0cmFpbnQuJG1heERpc3RhbmNlXSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGFuc3dlcltrZXldID0gW3BvaW50LmxvbmdpdHVkZSwgcG9pbnQubGF0aXR1ZGVdO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnJG1heERpc3RhbmNlJzoge1xuICAgICAgICBpZiAoY291bnQpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBhbnN3ZXJba2V5XSA9IGNvbnN0cmFpbnRba2V5XTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICAvLyBUaGUgU0RLcyBkb24ndCBzZWVtIHRvIHVzZSB0aGVzZSBidXQgdGhleSBhcmUgZG9jdW1lbnRlZCBpbiB0aGVcbiAgICAgIC8vIFJFU1QgQVBJIGRvY3MuXG4gICAgICBjYXNlICckbWF4RGlzdGFuY2VJblJhZGlhbnMnOlxuICAgICAgICBhbnN3ZXJbJyRtYXhEaXN0YW5jZSddID0gY29uc3RyYWludFtrZXldO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRtYXhEaXN0YW5jZUluTWlsZXMnOlxuICAgICAgICBhbnN3ZXJbJyRtYXhEaXN0YW5jZSddID0gY29uc3RyYWludFtrZXldIC8gMzk1OTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICckbWF4RGlzdGFuY2VJbktpbG9tZXRlcnMnOlxuICAgICAgICBhbnN3ZXJbJyRtYXhEaXN0YW5jZSddID0gY29uc3RyYWludFtrZXldIC8gNjM3MTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJyRzZWxlY3QnOlxuICAgICAgY2FzZSAnJGRvbnRTZWxlY3QnOlxuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuQ09NTUFORF9VTkFWQUlMQUJMRSxcbiAgICAgICAgICAndGhlICcgKyBrZXkgKyAnIGNvbnN0cmFpbnQgaXMgbm90IHN1cHBvcnRlZCB5ZXQnXG4gICAgICAgICk7XG5cbiAgICAgIGNhc2UgJyR3aXRoaW4nOlxuICAgICAgICB2YXIgYm94ID0gY29uc3RyYWludFtrZXldWyckYm94J107XG4gICAgICAgIGlmICghYm94IHx8IGJveC5sZW5ndGggIT0gMikge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sICdtYWxmb3JtYXR0ZWQgJHdpdGhpbiBhcmcnKTtcbiAgICAgICAgfVxuICAgICAgICBhbnN3ZXJba2V5XSA9IHtcbiAgICAgICAgICAkYm94OiBbXG4gICAgICAgICAgICBbYm94WzBdLmxvbmdpdHVkZSwgYm94WzBdLmxhdGl0dWRlXSxcbiAgICAgICAgICAgIFtib3hbMV0ubG9uZ2l0dWRlLCBib3hbMV0ubGF0aXR1ZGVdLFxuICAgICAgICAgIF0sXG4gICAgICAgIH07XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICckZ2VvV2l0aGluJzoge1xuICAgICAgICBjb25zdCBwb2x5Z29uID0gY29uc3RyYWludFtrZXldWyckcG9seWdvbiddO1xuICAgICAgICBjb25zdCBjZW50ZXJTcGhlcmUgPSBjb25zdHJhaW50W2tleV1bJyRjZW50ZXJTcGhlcmUnXTtcbiAgICAgICAgaWYgKHBvbHlnb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGxldCBwb2ludHM7XG4gICAgICAgICAgaWYgKHR5cGVvZiBwb2x5Z29uID09PSAnb2JqZWN0JyAmJiBwb2x5Z29uLl9fdHlwZSA9PT0gJ1BvbHlnb24nKSB7XG4gICAgICAgICAgICBpZiAoIXBvbHlnb24uY29vcmRpbmF0ZXMgfHwgcG9seWdvbi5jb29yZGluYXRlcy5sZW5ndGggPCAzKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAgICAgJ2JhZCAkZ2VvV2l0aGluIHZhbHVlOyBQb2x5Z29uLmNvb3JkaW5hdGVzIHNob3VsZCBjb250YWluIGF0IGxlYXN0IDMgbG9uL2xhdCBwYWlycydcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBvaW50cyA9IHBvbHlnb24uY29vcmRpbmF0ZXM7XG4gICAgICAgICAgfSBlbHNlIGlmIChwb2x5Z29uIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgICAgIGlmIChwb2x5Z29uLmxlbmd0aCA8IDMpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7ICRwb2x5Z29uIHNob3VsZCBjb250YWluIGF0IGxlYXN0IDMgR2VvUG9pbnRzJ1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcG9pbnRzID0gcG9seWdvbjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAgIFwiYmFkICRnZW9XaXRoaW4gdmFsdWU7ICRwb2x5Z29uIHNob3VsZCBiZSBQb2x5Z29uIG9iamVjdCBvciBBcnJheSBvZiBQYXJzZS5HZW9Qb2ludCdzXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHBvaW50cyA9IHBvaW50cy5tYXAocG9pbnQgPT4ge1xuICAgICAgICAgICAgaWYgKHBvaW50IGluc3RhbmNlb2YgQXJyYXkgJiYgcG9pbnQubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICAgIFBhcnNlLkdlb1BvaW50Ll92YWxpZGF0ZShwb2ludFsxXSwgcG9pbnRbMF0pO1xuICAgICAgICAgICAgICByZXR1cm4gcG9pbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIUdlb1BvaW50Q29kZXIuaXNWYWxpZEpTT04ocG9pbnQpKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sICdiYWQgJGdlb1dpdGhpbiB2YWx1ZScpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50LmxhdGl0dWRlLCBwb2ludC5sb25naXR1ZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFtwb2ludC5sb25naXR1ZGUsIHBvaW50LmxhdGl0dWRlXTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBhbnN3ZXJba2V5XSA9IHtcbiAgICAgICAgICAgICRwb2x5Z29uOiBwb2ludHMsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIGlmIChjZW50ZXJTcGhlcmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGlmICghKGNlbnRlclNwaGVyZSBpbnN0YW5jZW9mIEFycmF5KSB8fCBjZW50ZXJTcGhlcmUubGVuZ3RoIDwgMikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAgICdiYWQgJGdlb1dpdGhpbiB2YWx1ZTsgJGNlbnRlclNwaGVyZSBzaG91bGQgYmUgYW4gYXJyYXkgb2YgUGFyc2UuR2VvUG9pbnQgYW5kIGRpc3RhbmNlJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gR2V0IHBvaW50LCBjb252ZXJ0IHRvIGdlbyBwb2ludCBpZiBuZWNlc3NhcnkgYW5kIHZhbGlkYXRlXG4gICAgICAgICAgbGV0IHBvaW50ID0gY2VudGVyU3BoZXJlWzBdO1xuICAgICAgICAgIGlmIChwb2ludCBpbnN0YW5jZW9mIEFycmF5ICYmIHBvaW50Lmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgcG9pbnQgPSBuZXcgUGFyc2UuR2VvUG9pbnQocG9pbnRbMV0sIHBvaW50WzBdKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKCFHZW9Qb2ludENvZGVyLmlzVmFsaWRKU09OKHBvaW50KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAgICdiYWQgJGdlb1dpdGhpbiB2YWx1ZTsgJGNlbnRlclNwaGVyZSBnZW8gcG9pbnQgaW52YWxpZCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIFBhcnNlLkdlb1BvaW50Ll92YWxpZGF0ZShwb2ludC5sYXRpdHVkZSwgcG9pbnQubG9uZ2l0dWRlKTtcbiAgICAgICAgICAvLyBHZXQgZGlzdGFuY2UgYW5kIHZhbGlkYXRlXG4gICAgICAgICAgY29uc3QgZGlzdGFuY2UgPSBjZW50ZXJTcGhlcmVbMV07XG4gICAgICAgICAgaWYgKGlzTmFOKGRpc3RhbmNlKSB8fCBkaXN0YW5jZSA8IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7ICRjZW50ZXJTcGhlcmUgZGlzdGFuY2UgaW52YWxpZCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGFuc3dlcltrZXldID0ge1xuICAgICAgICAgICAgJGNlbnRlclNwaGVyZTogW1twb2ludC5sb25naXR1ZGUsIHBvaW50LmxhdGl0dWRlXSwgZGlzdGFuY2VdLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICckZ2VvSW50ZXJzZWN0cyc6IHtcbiAgICAgICAgY29uc3QgcG9pbnQgPSBjb25zdHJhaW50W2tleV1bJyRwb2ludCddO1xuICAgICAgICBpZiAoIUdlb1BvaW50Q29kZXIuaXNWYWxpZEpTT04ocG9pbnQpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgJ2JhZCAkZ2VvSW50ZXJzZWN0IHZhbHVlOyAkcG9pbnQgc2hvdWxkIGJlIEdlb1BvaW50J1xuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50LmxhdGl0dWRlLCBwb2ludC5sb25naXR1ZGUpO1xuICAgICAgICB9XG4gICAgICAgIGFuc3dlcltrZXldID0ge1xuICAgICAgICAgICRnZW9tZXRyeToge1xuICAgICAgICAgICAgdHlwZTogJ1BvaW50JyxcbiAgICAgICAgICAgIGNvb3JkaW5hdGVzOiBbcG9pbnQubG9uZ2l0dWRlLCBwb2ludC5sYXRpdHVkZV0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAoa2V5Lm1hdGNoKC9eXFwkKy8pKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2JhZCBjb25zdHJhaW50OiAnICsga2V5KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gQ2Fubm90VHJhbnNmb3JtO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYW5zd2VyO1xufVxuXG4vLyBUcmFuc2Zvcm1zIGFuIHVwZGF0ZSBvcGVyYXRvciBmcm9tIFJFU1QgZm9ybWF0IHRvIG1vbmdvIGZvcm1hdC5cbi8vIFRvIGJlIHRyYW5zZm9ybWVkLCB0aGUgaW5wdXQgc2hvdWxkIGhhdmUgYW4gX19vcCBmaWVsZC5cbi8vIElmIGZsYXR0ZW4gaXMgdHJ1ZSwgdGhpcyB3aWxsIGZsYXR0ZW4gb3BlcmF0b3JzIHRvIHRoZWlyIHN0YXRpY1xuLy8gZGF0YSBmb3JtYXQuIEZvciBleGFtcGxlLCBhbiBpbmNyZW1lbnQgb2YgMiB3b3VsZCBzaW1wbHkgYmVjb21lIGFcbi8vIDIuXG4vLyBUaGUgb3V0cHV0IGZvciBhIG5vbi1mbGF0dGVuZWQgb3BlcmF0b3IgaXMgYSBoYXNoIHdpdGggX19vcCBiZWluZ1xuLy8gdGhlIG1vbmdvIG9wLCBhbmQgYXJnIGJlaW5nIHRoZSBhcmd1bWVudC5cbi8vIFRoZSBvdXRwdXQgZm9yIGEgZmxhdHRlbmVkIG9wZXJhdG9yIGlzIGp1c3QgYSB2YWx1ZS5cbi8vIFJldHVybnMgdW5kZWZpbmVkIGlmIHRoaXMgc2hvdWxkIGJlIGEgbm8tb3AuXG5cbmZ1bmN0aW9uIHRyYW5zZm9ybVVwZGF0ZU9wZXJhdG9yKHsgX19vcCwgYW1vdW50LCBvYmplY3RzIH0sIGZsYXR0ZW4pIHtcbiAgc3dpdGNoIChfX29wKSB7XG4gICAgY2FzZSAnRGVsZXRlJzpcbiAgICAgIGlmIChmbGF0dGVuKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4geyBfX29wOiAnJHVuc2V0JywgYXJnOiAnJyB9O1xuICAgICAgfVxuXG4gICAgY2FzZSAnSW5jcmVtZW50JzpcbiAgICAgIGlmICh0eXBlb2YgYW1vdW50ICE9PSAnbnVtYmVyJykge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnaW5jcmVtZW50aW5nIG11c3QgcHJvdmlkZSBhIG51bWJlcicpO1xuICAgICAgfVxuICAgICAgaWYgKGZsYXR0ZW4pIHtcbiAgICAgICAgcmV0dXJuIGFtb3VudDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB7IF9fb3A6ICckaW5jJywgYXJnOiBhbW91bnQgfTtcbiAgICAgIH1cblxuICAgIGNhc2UgJ0FkZCc6XG4gICAgY2FzZSAnQWRkVW5pcXVlJzpcbiAgICAgIGlmICghKG9iamVjdHMgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ29iamVjdHMgdG8gYWRkIG11c3QgYmUgYW4gYXJyYXknKTtcbiAgICAgIH1cbiAgICAgIHZhciB0b0FkZCA9IG9iamVjdHMubWFwKHRyYW5zZm9ybUludGVyaW9yQXRvbSk7XG4gICAgICBpZiAoZmxhdHRlbikge1xuICAgICAgICByZXR1cm4gdG9BZGQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgbW9uZ29PcCA9IHtcbiAgICAgICAgICBBZGQ6ICckcHVzaCcsXG4gICAgICAgICAgQWRkVW5pcXVlOiAnJGFkZFRvU2V0JyxcbiAgICAgICAgfVtfX29wXTtcbiAgICAgICAgcmV0dXJuIHsgX19vcDogbW9uZ29PcCwgYXJnOiB7ICRlYWNoOiB0b0FkZCB9IH07XG4gICAgICB9XG5cbiAgICBjYXNlICdSZW1vdmUnOlxuICAgICAgaWYgKCEob2JqZWN0cyBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnb2JqZWN0cyB0byByZW1vdmUgbXVzdCBiZSBhbiBhcnJheScpO1xuICAgICAgfVxuICAgICAgdmFyIHRvUmVtb3ZlID0gb2JqZWN0cy5tYXAodHJhbnNmb3JtSW50ZXJpb3JBdG9tKTtcbiAgICAgIGlmIChmbGF0dGVuKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB7IF9fb3A6ICckcHVsbEFsbCcsIGFyZzogdG9SZW1vdmUgfTtcbiAgICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLkNPTU1BTkRfVU5BVkFJTEFCTEUsXG4gICAgICAgIGBUaGUgJHtfX29wfSBvcGVyYXRvciBpcyBub3Qgc3VwcG9ydGVkIHlldC5gXG4gICAgICApO1xuICB9XG59XG5mdW5jdGlvbiBtYXBWYWx1ZXMob2JqZWN0LCBpdGVyYXRvcikge1xuICBjb25zdCByZXN1bHQgPSB7fTtcbiAgT2JqZWN0LmtleXMob2JqZWN0KS5mb3JFYWNoKGtleSA9PiB7XG4gICAgcmVzdWx0W2tleV0gPSBpdGVyYXRvcihvYmplY3Rba2V5XSk7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5jb25zdCBuZXN0ZWRNb25nb09iamVjdFRvTmVzdGVkUGFyc2VPYmplY3QgPSBtb25nb09iamVjdCA9PiB7XG4gIHN3aXRjaCAodHlwZW9mIG1vbmdvT2JqZWN0KSB7XG4gICAgY2FzZSAnc3RyaW5nJzpcbiAgICBjYXNlICdudW1iZXInOlxuICAgIGNhc2UgJ2Jvb2xlYW4nOlxuICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgICByZXR1cm4gbW9uZ29PYmplY3Q7XG4gICAgY2FzZSAnc3ltYm9sJzpcbiAgICBjYXNlICdmdW5jdGlvbic6XG4gICAgICB0aHJvdyAnYmFkIHZhbHVlIGluIG5lc3RlZE1vbmdvT2JqZWN0VG9OZXN0ZWRQYXJzZU9iamVjdCc7XG4gICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgIGlmIChtb25nb09iamVjdCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChtb25nb09iamVjdCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgIHJldHVybiBtb25nb09iamVjdC5tYXAobmVzdGVkTW9uZ29PYmplY3RUb05lc3RlZFBhcnNlT2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1vbmdvT2JqZWN0IGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICByZXR1cm4gUGFyc2UuX2VuY29kZShtb25nb09iamVjdCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChtb25nb09iamVjdCBpbnN0YW5jZW9mIG1vbmdvZGIuTG9uZykge1xuICAgICAgICByZXR1cm4gbW9uZ29PYmplY3QudG9OdW1iZXIoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1vbmdvT2JqZWN0IGluc3RhbmNlb2YgbW9uZ29kYi5Eb3VibGUpIHtcbiAgICAgICAgcmV0dXJuIG1vbmdvT2JqZWN0LnZhbHVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoQnl0ZXNDb2Rlci5pc1ZhbGlkRGF0YWJhc2VPYmplY3QobW9uZ29PYmplY3QpKSB7XG4gICAgICAgIHJldHVybiBCeXRlc0NvZGVyLmRhdGFiYXNlVG9KU09OKG1vbmdvT2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobW9uZ29PYmplY3QsICdfX3R5cGUnKSAmJlxuICAgICAgICBtb25nb09iamVjdC5fX3R5cGUgPT0gJ0RhdGUnICYmXG4gICAgICAgIG1vbmdvT2JqZWN0LmlzbyBpbnN0YW5jZW9mIERhdGVcbiAgICAgICkge1xuICAgICAgICBtb25nb09iamVjdC5pc28gPSBtb25nb09iamVjdC5pc28udG9KU09OKCk7XG4gICAgICAgIHJldHVybiBtb25nb09iamVjdDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG1hcFZhbHVlcyhtb25nb09iamVjdCwgbmVzdGVkTW9uZ29PYmplY3RUb05lc3RlZFBhcnNlT2JqZWN0KTtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgJ3Vua25vd24ganMgdHlwZSc7XG4gIH1cbn07XG5cbmNvbnN0IHRyYW5zZm9ybVBvaW50ZXJTdHJpbmcgPSAoc2NoZW1hLCBmaWVsZCwgcG9pbnRlclN0cmluZykgPT4ge1xuICBjb25zdCBvYmpEYXRhID0gcG9pbnRlclN0cmluZy5zcGxpdCgnJCcpO1xuICBpZiAob2JqRGF0YVswXSAhPT0gc2NoZW1hLmZpZWxkc1tmaWVsZF0udGFyZ2V0Q2xhc3MpIHtcbiAgICB0aHJvdyAncG9pbnRlciB0byBpbmNvcnJlY3QgY2xhc3NOYW1lJztcbiAgfVxuICByZXR1cm4ge1xuICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgIGNsYXNzTmFtZTogb2JqRGF0YVswXSxcbiAgICBvYmplY3RJZDogb2JqRGF0YVsxXSxcbiAgfTtcbn07XG5cbi8vIENvbnZlcnRzIGZyb20gYSBtb25nby1mb3JtYXQgb2JqZWN0IHRvIGEgUkVTVC1mb3JtYXQgb2JqZWN0LlxuLy8gRG9lcyBub3Qgc3RyaXAgb3V0IGFueXRoaW5nIGJhc2VkIG9uIGEgbGFjayBvZiBhdXRoZW50aWNhdGlvbi5cbmNvbnN0IG1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdCA9IChjbGFzc05hbWUsIG1vbmdvT2JqZWN0LCBzY2hlbWEpID0+IHtcbiAgc3dpdGNoICh0eXBlb2YgbW9uZ29PYmplY3QpIHtcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgIGNhc2UgJ251bWJlcic6XG4gICAgY2FzZSAnYm9vbGVhbic6XG4gICAgY2FzZSAndW5kZWZpbmVkJzpcbiAgICAgIHJldHVybiBtb25nb09iamVjdDtcbiAgICBjYXNlICdzeW1ib2wnOlxuICAgIGNhc2UgJ2Z1bmN0aW9uJzpcbiAgICAgIHRocm93ICdiYWQgdmFsdWUgaW4gbW9uZ29PYmplY3RUb1BhcnNlT2JqZWN0JztcbiAgICBjYXNlICdvYmplY3QnOiB7XG4gICAgICBpZiAobW9uZ29PYmplY3QgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICBpZiAobW9uZ29PYmplY3QgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICByZXR1cm4gbW9uZ29PYmplY3QubWFwKG5lc3RlZE1vbmdvT2JqZWN0VG9OZXN0ZWRQYXJzZU9iamVjdCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChtb25nb09iamVjdCBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgcmV0dXJuIFBhcnNlLl9lbmNvZGUobW9uZ29PYmplY3QpO1xuICAgICAgfVxuXG4gICAgICBpZiAobW9uZ29PYmplY3QgaW5zdGFuY2VvZiBtb25nb2RiLkxvbmcpIHtcbiAgICAgICAgcmV0dXJuIG1vbmdvT2JqZWN0LnRvTnVtYmVyKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChtb25nb09iamVjdCBpbnN0YW5jZW9mIG1vbmdvZGIuRG91YmxlKSB7XG4gICAgICAgIHJldHVybiBtb25nb09iamVjdC52YWx1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKEJ5dGVzQ29kZXIuaXNWYWxpZERhdGFiYXNlT2JqZWN0KG1vbmdvT2JqZWN0KSkge1xuICAgICAgICByZXR1cm4gQnl0ZXNDb2Rlci5kYXRhYmFzZVRvSlNPTihtb25nb09iamVjdCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlc3RPYmplY3QgPSB7fTtcbiAgICAgIGlmIChtb25nb09iamVjdC5fcnBlcm0gfHwgbW9uZ29PYmplY3QuX3dwZXJtKSB7XG4gICAgICAgIHJlc3RPYmplY3QuX3JwZXJtID0gbW9uZ29PYmplY3QuX3JwZXJtIHx8IFtdO1xuICAgICAgICByZXN0T2JqZWN0Ll93cGVybSA9IG1vbmdvT2JqZWN0Ll93cGVybSB8fCBbXTtcbiAgICAgICAgZGVsZXRlIG1vbmdvT2JqZWN0Ll9ycGVybTtcbiAgICAgICAgZGVsZXRlIG1vbmdvT2JqZWN0Ll93cGVybTtcbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIga2V5IGluIG1vbmdvT2JqZWN0KSB7XG4gICAgICAgIHN3aXRjaCAoa2V5KSB7XG4gICAgICAgICAgY2FzZSAnX2lkJzpcbiAgICAgICAgICAgIHJlc3RPYmplY3RbJ29iamVjdElkJ10gPSAnJyArIG1vbmdvT2JqZWN0W2tleV07XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdfaGFzaGVkX3Bhc3N3b3JkJzpcbiAgICAgICAgICAgIHJlc3RPYmplY3QuX2hhc2hlZF9wYXNzd29yZCA9IG1vbmdvT2JqZWN0W2tleV07XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdfYWNsJzpcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ19lbWFpbF92ZXJpZnlfdG9rZW4nOlxuICAgICAgICAgIGNhc2UgJ19wZXJpc2hhYmxlX3Rva2VuJzpcbiAgICAgICAgICBjYXNlICdfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0JzpcbiAgICAgICAgICBjYXNlICdfcGFzc3dvcmRfY2hhbmdlZF9hdCc6XG4gICAgICAgICAgY2FzZSAnX3RvbWJzdG9uZSc6XG4gICAgICAgICAgY2FzZSAnX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0JzpcbiAgICAgICAgICBjYXNlICdfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQnOlxuICAgICAgICAgIGNhc2UgJ19mYWlsZWRfbG9naW5fY291bnQnOlxuICAgICAgICAgIGNhc2UgJ19wYXNzd29yZF9oaXN0b3J5JzpcbiAgICAgICAgICAgIC8vIFRob3NlIGtleXMgd2lsbCBiZSBkZWxldGVkIGlmIG5lZWRlZCBpbiB0aGUgREIgQ29udHJvbGxlclxuICAgICAgICAgICAgcmVzdE9iamVjdFtrZXldID0gbW9uZ29PYmplY3Rba2V5XTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ19zZXNzaW9uX3Rva2VuJzpcbiAgICAgICAgICAgIHJlc3RPYmplY3RbJ3Nlc3Npb25Ub2tlbiddID0gbW9uZ29PYmplY3Rba2V5XTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ3VwZGF0ZWRBdCc6XG4gICAgICAgICAgY2FzZSAnX3VwZGF0ZWRfYXQnOlxuICAgICAgICAgICAgcmVzdE9iamVjdFsndXBkYXRlZEF0J10gPSBQYXJzZS5fZW5jb2RlKG5ldyBEYXRlKG1vbmdvT2JqZWN0W2tleV0pKS5pc287XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdjcmVhdGVkQXQnOlxuICAgICAgICAgIGNhc2UgJ19jcmVhdGVkX2F0JzpcbiAgICAgICAgICAgIHJlc3RPYmplY3RbJ2NyZWF0ZWRBdCddID0gUGFyc2UuX2VuY29kZShuZXcgRGF0ZShtb25nb09iamVjdFtrZXldKSkuaXNvO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZXhwaXJlc0F0JzpcbiAgICAgICAgICBjYXNlICdfZXhwaXJlc0F0JzpcbiAgICAgICAgICAgIHJlc3RPYmplY3RbJ2V4cGlyZXNBdCddID0gUGFyc2UuX2VuY29kZShuZXcgRGF0ZShtb25nb09iamVjdFtrZXldKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdsYXN0VXNlZCc6XG4gICAgICAgICAgY2FzZSAnX2xhc3RfdXNlZCc6XG4gICAgICAgICAgICByZXN0T2JqZWN0WydsYXN0VXNlZCddID0gUGFyc2UuX2VuY29kZShuZXcgRGF0ZShtb25nb09iamVjdFtrZXldKSkuaXNvO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAndGltZXNVc2VkJzpcbiAgICAgICAgICBjYXNlICd0aW1lc191c2VkJzpcbiAgICAgICAgICAgIHJlc3RPYmplY3RbJ3RpbWVzVXNlZCddID0gbW9uZ29PYmplY3Rba2V5XTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ2F1dGhEYXRhJzpcbiAgICAgICAgICAgIGlmIChjbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICAgICAgICAgICAgbG9nLndhcm4oXG4gICAgICAgICAgICAgICAgJ2lnbm9yaW5nIGF1dGhEYXRhIGluIF9Vc2VyIGFzIHRoaXMga2V5IGlzIHJlc2VydmVkIHRvIGJlIHN5bnRoZXNpemVkIG9mIGBfYXV0aF9kYXRhXypgIGtleXMnXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXN0T2JqZWN0WydhdXRoRGF0YSddID0gbW9uZ29PYmplY3Rba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAvLyBDaGVjayBvdGhlciBhdXRoIGRhdGEga2V5c1xuICAgICAgICAgICAgdmFyIGF1dGhEYXRhTWF0Y2ggPSBrZXkubWF0Y2goL15fYXV0aF9kYXRhXyhbYS16QS1aMC05X10rKSQvKTtcbiAgICAgICAgICAgIGlmIChhdXRoRGF0YU1hdGNoICYmIGNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgICAgICAgICAgICB2YXIgcHJvdmlkZXIgPSBhdXRoRGF0YU1hdGNoWzFdO1xuICAgICAgICAgICAgICByZXN0T2JqZWN0WydhdXRoRGF0YSddID0gcmVzdE9iamVjdFsnYXV0aERhdGEnXSB8fCB7fTtcbiAgICAgICAgICAgICAgcmVzdE9iamVjdFsnYXV0aERhdGEnXVtwcm92aWRlcl0gPSBtb25nb09iamVjdFtrZXldO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGtleS5pbmRleE9mKCdfcF8nKSA9PSAwKSB7XG4gICAgICAgICAgICAgIHZhciBuZXdLZXkgPSBrZXkuc3Vic3RyaW5nKDMpO1xuICAgICAgICAgICAgICBpZiAoIXNjaGVtYS5maWVsZHNbbmV3S2V5XSkge1xuICAgICAgICAgICAgICAgIGxvZy5pbmZvKFxuICAgICAgICAgICAgICAgICAgJ3RyYW5zZm9ybS5qcycsXG4gICAgICAgICAgICAgICAgICAnRm91bmQgYSBwb2ludGVyIGNvbHVtbiBub3QgaW4gdGhlIHNjaGVtYSwgZHJvcHBpbmcgaXQuJyxcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgIG5ld0tleVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKHNjaGVtYS5maWVsZHNbbmV3S2V5XS50eXBlICE9PSAnUG9pbnRlcicpIHtcbiAgICAgICAgICAgICAgICBsb2cuaW5mbyhcbiAgICAgICAgICAgICAgICAgICd0cmFuc2Zvcm0uanMnLFxuICAgICAgICAgICAgICAgICAgJ0ZvdW5kIGEgcG9pbnRlciBpbiBhIG5vbi1wb2ludGVyIGNvbHVtbiwgZHJvcHBpbmcgaXQuJyxcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgIGtleVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKG1vbmdvT2JqZWN0W2tleV0gPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXN0T2JqZWN0W25ld0tleV0gPSB0cmFuc2Zvcm1Qb2ludGVyU3RyaW5nKHNjaGVtYSwgbmV3S2V5LCBtb25nb09iamVjdFtrZXldKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGtleVswXSA9PSAnXycgJiYga2V5ICE9ICdfX3R5cGUnKSB7XG4gICAgICAgICAgICAgIHRocm93ICdiYWQga2V5IGluIHVudHJhbnNmb3JtOiAnICsga2V5O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdmFyIHZhbHVlID0gbW9uZ29PYmplY3Rba2V5XTtcbiAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHNjaGVtYS5maWVsZHNba2V5XSAmJlxuICAgICAgICAgICAgICAgIHNjaGVtYS5maWVsZHNba2V5XS50eXBlID09PSAnRmlsZScgJiZcbiAgICAgICAgICAgICAgICBGaWxlQ29kZXIuaXNWYWxpZERhdGFiYXNlT2JqZWN0KHZhbHVlKVxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICByZXN0T2JqZWN0W2tleV0gPSBGaWxlQ29kZXIuZGF0YWJhc2VUb0pTT04odmFsdWUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBzY2hlbWEuZmllbGRzW2tleV0gJiZcbiAgICAgICAgICAgICAgICBzY2hlbWEuZmllbGRzW2tleV0udHlwZSA9PT0gJ0dlb1BvaW50JyAmJlxuICAgICAgICAgICAgICAgIEdlb1BvaW50Q29kZXIuaXNWYWxpZERhdGFiYXNlT2JqZWN0KHZhbHVlKVxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICByZXN0T2JqZWN0W2tleV0gPSBHZW9Qb2ludENvZGVyLmRhdGFiYXNlVG9KU09OKHZhbHVlKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgc2NoZW1hLmZpZWxkc1trZXldICYmXG4gICAgICAgICAgICAgICAgc2NoZW1hLmZpZWxkc1trZXldLnR5cGUgPT09ICdQb2x5Z29uJyAmJlxuICAgICAgICAgICAgICAgIFBvbHlnb25Db2Rlci5pc1ZhbGlkRGF0YWJhc2VPYmplY3QodmFsdWUpXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHJlc3RPYmplY3Rba2V5XSA9IFBvbHlnb25Db2Rlci5kYXRhYmFzZVRvSlNPTih2YWx1ZSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHNjaGVtYS5maWVsZHNba2V5XSAmJlxuICAgICAgICAgICAgICAgIHNjaGVtYS5maWVsZHNba2V5XS50eXBlID09PSAnQnl0ZXMnICYmXG4gICAgICAgICAgICAgICAgQnl0ZXNDb2Rlci5pc1ZhbGlkRGF0YWJhc2VPYmplY3QodmFsdWUpXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHJlc3RPYmplY3Rba2V5XSA9IEJ5dGVzQ29kZXIuZGF0YWJhc2VUb0pTT04odmFsdWUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXN0T2JqZWN0W2tleV0gPSBuZXN0ZWRNb25nb09iamVjdFRvTmVzdGVkUGFyc2VPYmplY3QobW9uZ29PYmplY3Rba2V5XSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVsYXRpb25GaWVsZE5hbWVzID0gT2JqZWN0LmtleXMoc2NoZW1hLmZpZWxkcykuZmlsdGVyKFxuICAgICAgICBmaWVsZE5hbWUgPT4gc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdSZWxhdGlvbidcbiAgICAgICk7XG4gICAgICBjb25zdCByZWxhdGlvbkZpZWxkcyA9IHt9O1xuICAgICAgcmVsYXRpb25GaWVsZE5hbWVzLmZvckVhY2gocmVsYXRpb25GaWVsZE5hbWUgPT4ge1xuICAgICAgICByZWxhdGlvbkZpZWxkc1tyZWxhdGlvbkZpZWxkTmFtZV0gPSB7XG4gICAgICAgICAgX190eXBlOiAnUmVsYXRpb24nLFxuICAgICAgICAgIGNsYXNzTmFtZTogc2NoZW1hLmZpZWxkc1tyZWxhdGlvbkZpZWxkTmFtZV0udGFyZ2V0Q2xhc3MsXG4gICAgICAgIH07XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHsgLi4ucmVzdE9iamVjdCwgLi4ucmVsYXRpb25GaWVsZHMgfTtcbiAgICB9XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93ICd1bmtub3duIGpzIHR5cGUnO1xuICB9XG59O1xuXG52YXIgRGF0ZUNvZGVyID0ge1xuICBKU09OVG9EYXRhYmFzZShqc29uKSB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKGpzb24uaXNvKTtcbiAgfSxcblxuICBpc1ZhbGlkSlNPTih2YWx1ZSkge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmIHZhbHVlLl9fdHlwZSA9PT0gJ0RhdGUnO1xuICB9LFxufTtcblxudmFyIEJ5dGVzQ29kZXIgPSB7XG4gIGJhc2U2NFBhdHRlcm46IG5ldyBSZWdFeHAoJ14oPzpbQS1aYS16MC05Ky9dezR9KSooPzpbQS1aYS16MC05Ky9dezJ9PT18W0EtWmEtejAtOSsvXXszfT0pPyQnKSxcbiAgaXNCYXNlNjRWYWx1ZShvYmplY3QpIHtcbiAgICBpZiAodHlwZW9mIG9iamVjdCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYmFzZTY0UGF0dGVybi50ZXN0KG9iamVjdCk7XG4gIH0sXG5cbiAgZGF0YWJhc2VUb0pTT04ob2JqZWN0KSB7XG4gICAgbGV0IHZhbHVlO1xuICAgIGlmICh0aGlzLmlzQmFzZTY0VmFsdWUob2JqZWN0KSkge1xuICAgICAgdmFsdWUgPSBvYmplY3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlID0gb2JqZWN0LmJ1ZmZlci50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBfX3R5cGU6ICdCeXRlcycsXG4gICAgICBiYXNlNjQ6IHZhbHVlLFxuICAgIH07XG4gIH0sXG5cbiAgaXNWYWxpZERhdGFiYXNlT2JqZWN0KG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBtb25nb2RiLkJpbmFyeSB8fCB0aGlzLmlzQmFzZTY0VmFsdWUob2JqZWN0KTtcbiAgfSxcblxuICBKU09OVG9EYXRhYmFzZShqc29uKSB7XG4gICAgcmV0dXJuIG5ldyBtb25nb2RiLkJpbmFyeShCdWZmZXIuZnJvbShqc29uLmJhc2U2NCwgJ2Jhc2U2NCcpKTtcbiAgfSxcblxuICBpc1ZhbGlkSlNPTih2YWx1ZSkge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmIHZhbHVlLl9fdHlwZSA9PT0gJ0J5dGVzJztcbiAgfSxcbn07XG5cbnZhciBHZW9Qb2ludENvZGVyID0ge1xuICBkYXRhYmFzZVRvSlNPTihvYmplY3QpIHtcbiAgICByZXR1cm4ge1xuICAgICAgX190eXBlOiAnR2VvUG9pbnQnLFxuICAgICAgbGF0aXR1ZGU6IG9iamVjdFsxXSxcbiAgICAgIGxvbmdpdHVkZTogb2JqZWN0WzBdLFxuICAgIH07XG4gIH0sXG5cbiAgaXNWYWxpZERhdGFiYXNlT2JqZWN0KG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBBcnJheSAmJiBvYmplY3QubGVuZ3RoID09IDI7XG4gIH0sXG5cbiAgSlNPTlRvRGF0YWJhc2UoanNvbikge1xuICAgIHJldHVybiBbanNvbi5sb25naXR1ZGUsIGpzb24ubGF0aXR1ZGVdO1xuICB9LFxuXG4gIGlzVmFsaWRKU09OKHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgdmFsdWUuX190eXBlID09PSAnR2VvUG9pbnQnO1xuICB9LFxufTtcblxudmFyIFBvbHlnb25Db2RlciA9IHtcbiAgZGF0YWJhc2VUb0pTT04ob2JqZWN0KSB7XG4gICAgLy8gQ29udmVydCBsbmcvbGF0IC0+IGxhdC9sbmdcbiAgICBjb25zdCBjb29yZHMgPSBvYmplY3QuY29vcmRpbmF0ZXNbMF0ubWFwKGNvb3JkID0+IHtcbiAgICAgIHJldHVybiBbY29vcmRbMV0sIGNvb3JkWzBdXTtcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgX190eXBlOiAnUG9seWdvbicsXG4gICAgICBjb29yZGluYXRlczogY29vcmRzLFxuICAgIH07XG4gIH0sXG5cbiAgaXNWYWxpZERhdGFiYXNlT2JqZWN0KG9iamVjdCkge1xuICAgIGNvbnN0IGNvb3JkcyA9IG9iamVjdC5jb29yZGluYXRlc1swXTtcbiAgICBpZiAob2JqZWN0LnR5cGUgIT09ICdQb2x5Z29uJyB8fCAhKGNvb3JkcyBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvb3Jkcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgcG9pbnQgPSBjb29yZHNbaV07XG4gICAgICBpZiAoIUdlb1BvaW50Q29kZXIuaXNWYWxpZERhdGFiYXNlT2JqZWN0KHBvaW50KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBQYXJzZS5HZW9Qb2ludC5fdmFsaWRhdGUocGFyc2VGbG9hdChwb2ludFsxXSksIHBhcnNlRmxvYXQocG9pbnRbMF0pKTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH0sXG5cbiAgSlNPTlRvRGF0YWJhc2UoanNvbikge1xuICAgIGxldCBjb29yZHMgPSBqc29uLmNvb3JkaW5hdGVzO1xuICAgIC8vIEFkZCBmaXJzdCBwb2ludCB0byB0aGUgZW5kIHRvIGNsb3NlIHBvbHlnb25cbiAgICBpZiAoXG4gICAgICBjb29yZHNbMF1bMF0gIT09IGNvb3Jkc1tjb29yZHMubGVuZ3RoIC0gMV1bMF0gfHxcbiAgICAgIGNvb3Jkc1swXVsxXSAhPT0gY29vcmRzW2Nvb3Jkcy5sZW5ndGggLSAxXVsxXVxuICAgICkge1xuICAgICAgY29vcmRzLnB1c2goY29vcmRzWzBdKTtcbiAgICB9XG4gICAgY29uc3QgdW5pcXVlID0gY29vcmRzLmZpbHRlcigoaXRlbSwgaW5kZXgsIGFyKSA9PiB7XG4gICAgICBsZXQgZm91bmRJbmRleCA9IC0xO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhci5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBjb25zdCBwdCA9IGFyW2ldO1xuICAgICAgICBpZiAocHRbMF0gPT09IGl0ZW1bMF0gJiYgcHRbMV0gPT09IGl0ZW1bMV0pIHtcbiAgICAgICAgICBmb3VuZEluZGV4ID0gaTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZvdW5kSW5kZXggPT09IGluZGV4O1xuICAgIH0pO1xuICAgIGlmICh1bmlxdWUubGVuZ3RoIDwgMykge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsXG4gICAgICAgICdHZW9KU09OOiBMb29wIG11c3QgaGF2ZSBhdCBsZWFzdCAzIGRpZmZlcmVudCB2ZXJ0aWNlcydcbiAgICAgICk7XG4gICAgfVxuICAgIC8vIENvbnZlcnQgbGF0L2xvbmcgLT4gbG9uZy9sYXRcbiAgICBjb29yZHMgPSBjb29yZHMubWFwKGNvb3JkID0+IHtcbiAgICAgIHJldHVybiBbY29vcmRbMV0sIGNvb3JkWzBdXTtcbiAgICB9KTtcbiAgICByZXR1cm4geyB0eXBlOiAnUG9seWdvbicsIGNvb3JkaW5hdGVzOiBbY29vcmRzXSB9O1xuICB9LFxuXG4gIGlzVmFsaWRKU09OKHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgdmFsdWUuX190eXBlID09PSAnUG9seWdvbic7XG4gIH0sXG59O1xuXG52YXIgRmlsZUNvZGVyID0ge1xuICBkYXRhYmFzZVRvSlNPTihvYmplY3QpIHtcbiAgICByZXR1cm4ge1xuICAgICAgX190eXBlOiAnRmlsZScsXG4gICAgICBuYW1lOiBvYmplY3QsXG4gICAgfTtcbiAgfSxcblxuICBpc1ZhbGlkRGF0YWJhc2VPYmplY3Qob2JqZWN0KSB7XG4gICAgcmV0dXJuIHR5cGVvZiBvYmplY3QgPT09ICdzdHJpbmcnO1xuICB9LFxuXG4gIEpTT05Ub0RhdGFiYXNlKGpzb24pIHtcbiAgICByZXR1cm4ganNvbi5uYW1lO1xuICB9LFxuXG4gIGlzVmFsaWRKU09OKHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgdmFsdWUuX190eXBlID09PSAnRmlsZSc7XG4gIH0sXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdHJhbnNmb3JtS2V5LFxuICBwYXJzZU9iamVjdFRvTW9uZ29PYmplY3RGb3JDcmVhdGUsXG4gIHRyYW5zZm9ybVVwZGF0ZSxcbiAgdHJhbnNmb3JtV2hlcmUsXG4gIG1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdCxcbiAgcmVsYXRpdmVUaW1lVG9EYXRlLFxuICB0cmFuc2Zvcm1Db25zdHJhaW50LFxuICB0cmFuc2Zvcm1Qb2ludGVyU3RyaW5nLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/PostgresClient.js b/lib/Adapters/Storage/Postgres/PostgresClient.js new file mode 100644 index 0000000000..9c2899b4d5 --- /dev/null +++ b/lib/Adapters/Storage/Postgres/PostgresClient.js @@ -0,0 +1,40 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.createClient = createClient; + +const parser = require('./PostgresConfigParser'); + +function createClient(uri, databaseOptions) { + let dbOptions = {}; + databaseOptions = databaseOptions || {}; + + if (uri) { + dbOptions = parser.getDatabaseOptionsFromURI(uri); + } + + for (const key in databaseOptions) { + dbOptions[key] = databaseOptions[key]; + } + + const initOptions = dbOptions.initOptions || {}; + initOptions.noWarnings = process && process.env.TESTING; + + const pgp = require('pg-promise')(initOptions); + + const client = pgp(dbOptions); + + if (dbOptions.pgOptions) { + for (const key in dbOptions.pgOptions) { + pgp.pg.defaults[key] = dbOptions.pgOptions[key]; + } + } + + return { + client, + pgp + }; +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL1Bvc3RncmVzL1Bvc3RncmVzQ2xpZW50LmpzIl0sIm5hbWVzIjpbInBhcnNlciIsInJlcXVpcmUiLCJjcmVhdGVDbGllbnQiLCJ1cmkiLCJkYXRhYmFzZU9wdGlvbnMiLCJkYk9wdGlvbnMiLCJnZXREYXRhYmFzZU9wdGlvbnNGcm9tVVJJIiwia2V5IiwiaW5pdE9wdGlvbnMiLCJub1dhcm5pbmdzIiwicHJvY2VzcyIsImVudiIsIlRFU1RJTkciLCJwZ3AiLCJjbGllbnQiLCJwZ09wdGlvbnMiLCJwZyIsImRlZmF1bHRzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUEsTUFBTUEsTUFBTSxHQUFHQyxPQUFPLENBQUMsd0JBQUQsQ0FBdEI7O0FBRU8sU0FBU0MsWUFBVCxDQUFzQkMsR0FBdEIsRUFBMkJDLGVBQTNCLEVBQTRDO0FBQ2pELE1BQUlDLFNBQVMsR0FBRyxFQUFoQjtBQUNBRCxFQUFBQSxlQUFlLEdBQUdBLGVBQWUsSUFBSSxFQUFyQzs7QUFFQSxNQUFJRCxHQUFKLEVBQVM7QUFDUEUsSUFBQUEsU0FBUyxHQUFHTCxNQUFNLENBQUNNLHlCQUFQLENBQWlDSCxHQUFqQyxDQUFaO0FBQ0Q7O0FBRUQsT0FBSyxNQUFNSSxHQUFYLElBQWtCSCxlQUFsQixFQUFtQztBQUNqQ0MsSUFBQUEsU0FBUyxDQUFDRSxHQUFELENBQVQsR0FBaUJILGVBQWUsQ0FBQ0csR0FBRCxDQUFoQztBQUNEOztBQUVELFFBQU1DLFdBQVcsR0FBR0gsU0FBUyxDQUFDRyxXQUFWLElBQXlCLEVBQTdDO0FBQ0FBLEVBQUFBLFdBQVcsQ0FBQ0MsVUFBWixHQUF5QkMsT0FBTyxJQUFJQSxPQUFPLENBQUNDLEdBQVIsQ0FBWUMsT0FBaEQ7O0FBRUEsUUFBTUMsR0FBRyxHQUFHWixPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCTyxXQUF0QixDQUFaOztBQUNBLFFBQU1NLE1BQU0sR0FBR0QsR0FBRyxDQUFDUixTQUFELENBQWxCOztBQUVBLE1BQUlBLFNBQVMsQ0FBQ1UsU0FBZCxFQUF5QjtBQUN2QixTQUFLLE1BQU1SLEdBQVgsSUFBa0JGLFNBQVMsQ0FBQ1UsU0FBNUIsRUFBdUM7QUFDckNGLE1BQUFBLEdBQUcsQ0FBQ0csRUFBSixDQUFPQyxRQUFQLENBQWdCVixHQUFoQixJQUF1QkYsU0FBUyxDQUFDVSxTQUFWLENBQW9CUixHQUFwQixDQUF2QjtBQUNEO0FBQ0Y7O0FBRUQsU0FBTztBQUFFTyxJQUFBQSxNQUFGO0FBQVVELElBQUFBO0FBQVYsR0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgcGFyc2VyID0gcmVxdWlyZSgnLi9Qb3N0Z3Jlc0NvbmZpZ1BhcnNlcicpO1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ2xpZW50KHVyaSwgZGF0YWJhc2VPcHRpb25zKSB7XG4gIGxldCBkYk9wdGlvbnMgPSB7fTtcbiAgZGF0YWJhc2VPcHRpb25zID0gZGF0YWJhc2VPcHRpb25zIHx8IHt9O1xuXG4gIGlmICh1cmkpIHtcbiAgICBkYk9wdGlvbnMgPSBwYXJzZXIuZ2V0RGF0YWJhc2VPcHRpb25zRnJvbVVSSSh1cmkpO1xuICB9XG5cbiAgZm9yIChjb25zdCBrZXkgaW4gZGF0YWJhc2VPcHRpb25zKSB7XG4gICAgZGJPcHRpb25zW2tleV0gPSBkYXRhYmFzZU9wdGlvbnNba2V5XTtcbiAgfVxuXG4gIGNvbnN0IGluaXRPcHRpb25zID0gZGJPcHRpb25zLmluaXRPcHRpb25zIHx8IHt9O1xuICBpbml0T3B0aW9ucy5ub1dhcm5pbmdzID0gcHJvY2VzcyAmJiBwcm9jZXNzLmVudi5URVNUSU5HO1xuXG4gIGNvbnN0IHBncCA9IHJlcXVpcmUoJ3BnLXByb21pc2UnKShpbml0T3B0aW9ucyk7XG4gIGNvbnN0IGNsaWVudCA9IHBncChkYk9wdGlvbnMpO1xuXG4gIGlmIChkYk9wdGlvbnMucGdPcHRpb25zKSB7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gZGJPcHRpb25zLnBnT3B0aW9ucykge1xuICAgICAgcGdwLnBnLmRlZmF1bHRzW2tleV0gPSBkYk9wdGlvbnMucGdPcHRpb25zW2tleV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgY2xpZW50LCBwZ3AgfTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/PostgresConfigParser.js b/lib/Adapters/Storage/Postgres/PostgresConfigParser.js new file mode 100644 index 0000000000..2bd5b7fa6c --- /dev/null +++ b/lib/Adapters/Storage/Postgres/PostgresConfigParser.js @@ -0,0 +1,95 @@ +"use strict"; + +const url = require('url'); + +const fs = require('fs'); + +function getDatabaseOptionsFromURI(uri) { + const databaseOptions = {}; + const parsedURI = url.parse(uri); + const queryParams = parseQueryParams(parsedURI.query); + const authParts = parsedURI.auth ? parsedURI.auth.split(':') : []; + databaseOptions.host = parsedURI.hostname || 'localhost'; + databaseOptions.port = parsedURI.port ? parseInt(parsedURI.port) : 5432; + databaseOptions.database = parsedURI.pathname ? parsedURI.pathname.substr(1) : undefined; + databaseOptions.user = authParts.length > 0 ? authParts[0] : ''; + databaseOptions.password = authParts.length > 1 ? authParts[1] : ''; + + if (queryParams.ssl && queryParams.ssl.toLowerCase() === 'true') { + databaseOptions.ssl = true; + } + + if (queryParams.ca || queryParams.pfx || queryParams.cert || queryParams.key || queryParams.passphrase || queryParams.rejectUnauthorized || queryParams.secureOptions) { + databaseOptions.ssl = {}; + + if (queryParams.ca) { + databaseOptions.ssl.ca = fs.readFileSync(queryParams.ca).toString(); + } + + if (queryParams.pfx) { + databaseOptions.ssl.pfx = fs.readFileSync(queryParams.pfx).toString(); + } + + if (queryParams.cert) { + databaseOptions.ssl.cert = fs.readFileSync(queryParams.cert).toString(); + } + + if (queryParams.key) { + databaseOptions.ssl.key = fs.readFileSync(queryParams.key).toString(); + } + + if (queryParams.passphrase) { + databaseOptions.ssl.passphrase = queryParams.passphrase; + } + + if (queryParams.rejectUnauthorized) { + databaseOptions.ssl.rejectUnauthorized = queryParams.rejectUnauthorized.toLowerCase() === 'true' ? true : false; + } + + if (queryParams.secureOptions) { + databaseOptions.ssl.secureOptions = parseInt(queryParams.secureOptions); + } + } + + databaseOptions.binary = queryParams.binary && queryParams.binary.toLowerCase() === 'true' ? true : false; + databaseOptions.client_encoding = queryParams.client_encoding; + databaseOptions.application_name = queryParams.application_name; + databaseOptions.fallback_application_name = queryParams.fallback_application_name; + + if (queryParams.poolSize) { + databaseOptions.poolSize = parseInt(queryParams.poolSize) || 10; + } + + if (queryParams.max) { + databaseOptions.max = parseInt(queryParams.max) || 10; + } + + if (queryParams.query_timeout) { + databaseOptions.query_timeout = parseInt(queryParams.query_timeout); + } + + if (queryParams.idleTimeoutMillis) { + databaseOptions.idleTimeoutMillis = parseInt(queryParams.idleTimeoutMillis); + } + + if (queryParams.keepAlive) { + databaseOptions.keepAlive = queryParams.keepAlive.toLowerCase() === 'true' ? true : false; + } + + return databaseOptions; +} + +function parseQueryParams(queryString) { + queryString = queryString || ''; + return queryString.split('&').reduce((p, c) => { + const parts = c.split('='); + p[decodeURIComponent(parts[0])] = parts.length > 1 ? decodeURIComponent(parts.slice(1).join('=')) : ''; + return p; + }, {}); +} + +module.exports = { + parseQueryParams: parseQueryParams, + getDatabaseOptionsFromURI: getDatabaseOptionsFromURI +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL1Bvc3RncmVzL1Bvc3RncmVzQ29uZmlnUGFyc2VyLmpzIl0sIm5hbWVzIjpbInVybCIsInJlcXVpcmUiLCJmcyIsImdldERhdGFiYXNlT3B0aW9uc0Zyb21VUkkiLCJ1cmkiLCJkYXRhYmFzZU9wdGlvbnMiLCJwYXJzZWRVUkkiLCJwYXJzZSIsInF1ZXJ5UGFyYW1zIiwicGFyc2VRdWVyeVBhcmFtcyIsInF1ZXJ5IiwiYXV0aFBhcnRzIiwiYXV0aCIsInNwbGl0IiwiaG9zdCIsImhvc3RuYW1lIiwicG9ydCIsInBhcnNlSW50IiwiZGF0YWJhc2UiLCJwYXRobmFtZSIsInN1YnN0ciIsInVuZGVmaW5lZCIsInVzZXIiLCJsZW5ndGgiLCJwYXNzd29yZCIsInNzbCIsInRvTG93ZXJDYXNlIiwiY2EiLCJwZngiLCJjZXJ0Iiwia2V5IiwicGFzc3BocmFzZSIsInJlamVjdFVuYXV0aG9yaXplZCIsInNlY3VyZU9wdGlvbnMiLCJyZWFkRmlsZVN5bmMiLCJ0b1N0cmluZyIsImJpbmFyeSIsImNsaWVudF9lbmNvZGluZyIsImFwcGxpY2F0aW9uX25hbWUiLCJmYWxsYmFja19hcHBsaWNhdGlvbl9uYW1lIiwicG9vbFNpemUiLCJtYXgiLCJxdWVyeV90aW1lb3V0IiwiaWRsZVRpbWVvdXRNaWxsaXMiLCJrZWVwQWxpdmUiLCJxdWVyeVN0cmluZyIsInJlZHVjZSIsInAiLCJjIiwicGFydHMiLCJkZWNvZGVVUklDb21wb25lbnQiLCJzbGljZSIsImpvaW4iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLE1BQU1BLEdBQUcsR0FBR0MsT0FBTyxDQUFDLEtBQUQsQ0FBbkI7O0FBQ0EsTUFBTUMsRUFBRSxHQUFHRCxPQUFPLENBQUMsSUFBRCxDQUFsQjs7QUFDQSxTQUFTRSx5QkFBVCxDQUFtQ0MsR0FBbkMsRUFBd0M7QUFDdEMsUUFBTUMsZUFBZSxHQUFHLEVBQXhCO0FBRUEsUUFBTUMs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QixFQUFFQTtBQUZaLENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgdXJsID0gcmVxdWlyZSgndXJsJyk7XG5jb25zdCBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG5mdW5jdGlvbiBnZXREYXRhYmFzZU9wdGlvbnNGcm9tVVJJKHVyaSkge1xuICBjb25zdCBkYXRhYmFzZU9wdGlvbnMgPSB7fTtcblxuICBjb25zdCBwYXJzZWRVUkkgPSB1cmwucGFyc2UodXJpKTtcbiAgY29uc3QgcXVlcnlQYXJhbXMgPSBwYXJzZVF1ZXJ5UGFyYW1zKHBhcnNlZFVSSS5xdWVyeSk7XG4gIGNvbnN0IGF1dGhQYXJ0cyA9IHBhcnNlZFVSSS5hdXRoID8gcGFyc2VkVVJJLmF1dGguc3BsaXQoJzonKSA6IFtdO1xuXG4gIGRhdGFiYXNlT3B0aW9ucy5ob3N0ID0gcGFyc2VkVVJJLmhvc3RuYW1lIHx8ICdsb2NhbGhvc3QnO1xuICBkYXRhYmFzZU9wdGlvbnMucG9ydCA9IHBhcnNlZFVSSS5wb3J0ID8gcGFyc2VJbnQocGFyc2VkVVJJLnBvcnQpIDogNTQzMjtcbiAgZGF0YWJhc2VPcHRpb25zLmRhdGFiYXNlID0gcGFyc2VkVVJJLnBhdGhuYW1lID8gcGFyc2VkVVJJLnBhdGhuYW1lLnN1YnN0cigxKSA6IHVuZGVmaW5lZDtcblxuICBkYXRhYmFzZU9wdGlvbnMudXNlciA9IGF1dGhQYXJ0cy5sZW5ndGggPiAwID8gYXV0aFBhcnRzWzBdIDogJyc7XG4gIGRhdGFiYXNlT3B0aW9ucy5wYXNzd29yZCA9IGF1dGhQYXJ0cy5sZW5ndGggPiAxID8gYXV0aFBhcnRzWzFdIDogJyc7XG5cbiAgaWYgKHF1ZXJ5UGFyYW1zLnNzbCAmJiBxdWVyeVBhcmFtcy5zc2wudG9Mb3dlckNhc2UoKSA9PT0gJ3RydWUnKSB7XG4gICAgZGF0YWJhc2VPcHRpb25zLnNzbCA9IHRydWU7XG4gIH1cblxuICBpZiAoXG4gICAgcXVlcnlQYXJhbXMuY2EgfHxcbiAgICBxdWVyeVBhcmFtcy5wZnggfHxcbiAgICBxdWVyeVBhcmFtcy5jZXJ0IHx8XG4gICAgcXVlcnlQYXJhbXMua2V5IHx8XG4gICAgcXVlcnlQYXJhbXMucGFzc3BocmFzZSB8fFxuICAgIHF1ZXJ5UGFyYW1zLnJlamVjdFVuYXV0aG9yaXplZCB8fFxuICAgIHF1ZXJ5UGFyYW1zLnNlY3VyZU9wdGlvbnNcbiAgKSB7XG4gICAgZGF0YWJhc2VPcHRpb25zLnNzbCA9IHt9O1xuICAgIGlmIChxdWVyeVBhcmFtcy5jYSkge1xuICAgICAgZGF0YWJhc2VPcHRpb25zLnNzbC5jYSA9IGZzLnJlYWRGaWxlU3luYyhxdWVyeVBhcmFtcy5jYSkudG9TdHJpbmcoKTtcbiAgICB9XG4gICAgaWYgKHF1ZXJ5UGFyYW1zLnBmeCkge1xuICAgICAgZGF0YWJhc2VPcHRpb25zLnNzbC5wZnggPSBmcy5yZWFkRmlsZVN5bmMocXVlcnlQYXJhbXMucGZ4KS50b1N0cmluZygpO1xuICAgIH1cbiAgICBpZiAocXVlcnlQYXJhbXMuY2VydCkge1xuICAgICAgZGF0YWJhc2VPcHRpb25zLnNzbC5jZXJ0ID0gZnMucmVhZEZpbGVTeW5jKHF1ZXJ5UGFyYW1zLmNlcnQpLnRvU3RyaW5nKCk7XG4gICAgfVxuICAgIGlmIChxdWVyeVBhcmFtcy5rZXkpIHtcbiAgICAgIGRhdGFiYXNlT3B0aW9ucy5zc2wua2V5ID0gZnMucmVhZEZpbGVTeW5jKHF1ZXJ5UGFyYW1zLmtleSkudG9TdHJpbmcoKTtcbiAgICB9XG4gICAgaWYgKHF1ZXJ5UGFyYW1zLnBhc3NwaHJhc2UpIHtcbiAgICAgIGRhdGFiYXNlT3B0aW9ucy5zc2wucGFzc3BocmFzZSA9IHF1ZXJ5UGFyYW1zLnBhc3NwaHJhc2U7XG4gICAgfVxuICAgIGlmIChxdWVyeVBhcmFtcy5yZWplY3RVbmF1dGhvcml6ZWQpIHtcbiAgICAgIGRhdGFiYXNlT3B0aW9ucy5zc2wucmVqZWN0VW5hdXRob3JpemVkID1cbiAgICAgICAgcXVlcnlQYXJhbXMucmVqZWN0VW5hdXRob3JpemVkLnRvTG93ZXJDYXNlKCkgPT09ICd0cnVlJyA/IHRydWUgOiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHF1ZXJ5UGFyYW1zLnNlY3VyZU9wdGlvbnMpIHtcbiAgICAgIGRhdGFiYXNlT3B0aW9ucy5zc2wuc2VjdXJlT3B0aW9ucyA9IHBhcnNlSW50KHF1ZXJ5UGFyYW1zLnNlY3VyZU9wdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIGRhdGFiYXNlT3B0aW9ucy5iaW5hcnkgPVxuICAgIHF1ZXJ5UGFyYW1zLmJpbmFyeSAmJiBxdWVyeVBhcmFtcy5iaW5hcnkudG9Mb3dlckNhc2UoKSA9PT0gJ3RydWUnID8gdHJ1ZSA6IGZhbHNlO1xuXG4gIGRhdGFiYXNlT3B0aW9ucy5jbGllbnRfZW5jb2RpbmcgPSBxdWVyeVBhcmFtcy5jbGllbnRfZW5jb2Rpbmc7XG4gIGRhdGFiYXNlT3B0aW9ucy5hcHBsaWNhdGlvbl9uYW1lID0gcXVlcnlQYXJhbXMuYXBwbGljYXRpb25fbmFtZTtcbiAgZGF0YWJhc2VPcHRpb25zLmZhbGxiYWNrX2FwcGxpY2F0aW9uX25hbWUgPSBxdWVyeVBhcmFtcy5mYWxsYmFja19hcHBsaWNhdGlvbl9uYW1lO1xuXG4gIGlmIChxdWVyeVBhcmFtcy5wb29sU2l6ZSkge1xuICAgIGRhdGFiYXNlT3B0aW9ucy5wb29sU2l6ZSA9IHBhcnNlSW50KHF1ZXJ5UGFyYW1zLnBvb2xTaXplKSB8fCAxMDtcbiAgfVxuICBpZiAocXVlcnlQYXJhbXMubWF4KSB7XG4gICAgZGF0YWJhc2VPcHRpb25zLm1heCA9IHBhcnNlSW50KHF1ZXJ5UGFyYW1zLm1heCkgfHwgMTA7XG4gIH1cbiAgaWYgKHF1ZXJ5UGFyYW1zLnF1ZXJ5X3RpbWVvdXQpIHtcbiAgICBkYXRhYmFzZU9wdGlvbnMucXVlcnlfdGltZW91dCA9IHBhcnNlSW50KHF1ZXJ5UGFyYW1zLnF1ZXJ5X3RpbWVvdXQpO1xuICB9XG4gIGlmIChxdWVyeVBhcmFtcy5pZGxlVGltZW91dE1pbGxpcykge1xuICAgIGRhdGFiYXNlT3B0aW9ucy5pZGxlVGltZW91dE1pbGxpcyA9IHBhcnNlSW50KHF1ZXJ5UGFyYW1zLmlkbGVUaW1lb3V0TWlsbGlzKTtcbiAgfVxuICBpZiAocXVlcnlQYXJhbXMua2VlcEFsaXZlKSB7XG4gICAgZGF0YWJhc2VPcHRpb25zLmtlZXBBbGl2ZSA9IHF1ZXJ5UGFyYW1zLmtlZXBBbGl2ZS50b0xvd2VyQ2FzZSgpID09PSAndHJ1ZScgPyB0cnVlIDogZmFsc2U7XG4gIH1cblxuICByZXR1cm4gZGF0YWJhc2VPcHRpb25zO1xufVxuXG5mdW5jdGlvbiBwYXJzZVF1ZXJ5UGFyYW1zKHF1ZXJ5U3RyaW5nKSB7XG4gIHF1ZXJ5U3RyaW5nID0gcXVlcnlTdHJpbmcgfHwgJyc7XG5cbiAgcmV0dXJuIHF1ZXJ5U3RyaW5nLnNwbGl0KCcmJykucmVkdWNlKChwLCBjKSA9PiB7XG4gICAgY29uc3QgcGFydHMgPSBjLnNwbGl0KCc9Jyk7XG4gICAgcFtkZWNvZGVVUklDb21wb25lbnQocGFydHNbMF0pXSA9XG4gICAgICBwYXJ0cy5sZW5ndGggPiAxID8gZGVjb2RlVVJJQ29tcG9uZW50KHBhcnRzLnNsaWNlKDEpLmpvaW4oJz0nKSkgOiAnJztcbiAgICByZXR1cm4gcDtcbiAgfSwge30pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgcGFyc2VRdWVyeVBhcmFtczogcGFyc2VRdWVyeVBhcmFtcyxcbiAgZ2V0RGF0YWJhc2VPcHRpb25zRnJvbVVSSTogZ2V0RGF0YWJhc2VPcHRpb25zRnJvbVVSSSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js new file mode 100644 index 0000000000..3b200835e7 --- /dev/null +++ b/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js @@ -0,0 +1,2494 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.PostgresStorageAdapter = void 0; + +var _PostgresClient = require("./PostgresClient"); + +var _node = _interopRequireDefault(require("parse/node")); + +var _lodash = _interopRequireDefault(require("lodash")); + +var _sql = _interopRequireDefault(require("./sql")); + +var _StorageAdapter = require("../StorageAdapter"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const PostgresRelationDoesNotExistError = '42P01'; +const PostgresDuplicateRelationError = '42P07'; +const PostgresDuplicateColumnError = '42701'; +const PostgresMissingColumnError = '42703'; +const PostgresDuplicateObjectError = '42710'; +const PostgresUniqueIndexViolationError = '23505'; + +const logger = require('../../../logger'); + +const debug = function (...args) { + args = ['PG: ' + arguments[0]].concat(args.slice(1, args.length)); + const log = logger.getLogger(); + log.debug.apply(log, args); +}; + +const parseTypeToPostgresType = type => { + switch (type.type) { + case 'String': + return 'text'; + + case 'Date': + return 'timestamp with time zone'; + + case 'Object': + return 'jsonb'; + + case 'File': + return 'text'; + + case 'Boolean': + return 'boolean'; + + case 'Pointer': + return 'text'; + + case 'Number': + return 'double precision'; + + case 'GeoPoint': + return 'point'; + + case 'Bytes': + return 'jsonb'; + + case 'Polygon': + return 'polygon'; + + case 'Array': + if (type.contents && type.contents.type === 'String') { + return 'text[]'; + } else { + return 'jsonb'; + } + + default: + throw `no type for ${JSON.stringify(type)} yet`; + } +}; + +const ParseToPosgresComparator = { + $gt: '>', + $lt: '<', + $gte: '>=', + $lte: '<=' +}; +const mongoAggregateToPostgres = { + $dayOfMonth: 'DAY', + $dayOfWeek: 'DOW', + $dayOfYear: 'DOY', + $isoDayOfWeek: 'ISODOW', + $isoWeekYear: 'ISOYEAR', + $hour: 'HOUR', + $minute: 'MINUTE', + $second: 'SECOND', + $millisecond: 'MILLISECONDS', + $month: 'MONTH', + $week: 'WEEK', + $year: 'YEAR' +}; + +const toPostgresValue = value => { + if (typeof value === 'object') { + if (value.__type === 'Date') { + return value.iso; + } + + if (value.__type === 'File') { + return value.name; + } + } + + return value; +}; + +const transformValue = value => { + if (typeof value === 'object' && value.__type === 'Pointer') { + return value.objectId; + } + + return value; +}; // Duplicate from then mongo adapter... + + +const emptyCLPS = Object.freeze({ + find: {}, + get: {}, + count: {}, + create: {}, + update: {}, + delete: {}, + addField: {}, + protectedFields: {} +}); +const defaultCLPS = Object.freeze({ + find: { + '*': true + }, + get: { + '*': true + }, + count: { + '*': true + }, + create: { + '*': true + }, + update: { + '*': true + }, + delete: { + '*': true + }, + addField: { + '*': true + }, + protectedFields: { + '*': [] + } +}); + +const toParseSchema = schema => { + if (schema.className === '_User') { + delete schema.fields._hashed_password; + } + + if (schema.fields) { + delete schema.fields._wperm; + delete schema.fields._rperm; + } + + let clps = defaultCLPS; + + if (schema.classLevelPermissions) { + clps = _objectSpread(_objectSpread({}, emptyCLPS), schema.classLevelPermissions); + } + + let indexes = {}; + + if (schema.indexes) { + indexes = _objectSpread({}, schema.indexes); + } + + return { + className: schema.className, + fields: schema.fields, + classLevelPermissions: clps, + indexes + }; +}; + +const toPostgresSchema = schema => { + if (!schema) { + return schema; + } + + schema.fields = schema.fields || {}; + schema.fields._wperm = { + type: 'Array', + contents: { + type: 'String' + } + }; + schema.fields._rperm = { + type: 'Array', + contents: { + type: 'String' + } + }; + + if (schema.className === '_User') { + schema.fields._hashed_password = { + type: 'String' + }; + schema.fields._password_history = { + type: 'Array' + }; + } + + return schema; +}; + +const handleDotFields = object => { + Object.keys(object).forEach(fieldName => { + if (fieldName.indexOf('.') > -1) { + const components = fieldName.split('.'); + const first = components.shift(); + object[first] = object[first] || {}; + let currentObj = object[first]; + let next; + let value = object[fieldName]; + + if (value && value.__op === 'Delete') { + value = undefined; + } + /* eslint-disable no-cond-assign */ + + + while (next = components.shift()) { + /* eslint-enable no-cond-assign */ + currentObj[next] = currentObj[next] || {}; + + if (components.length === 0) { + currentObj[next] = value; + } + + currentObj = currentObj[next]; + } + + delete object[fieldName]; + } + }); + return object; +}; + +const transformDotFieldToComponents = fieldName => { + return fieldName.split('.').map((cmpt, index) => { + if (index === 0) { + return `"${cmpt}"`; + } + + return `'${cmpt}'`; + }); +}; + +const transformDotField = fieldName => { + if (fieldName.indexOf('.') === -1) { + return `"${fieldName}"`; + } + + const components = transformDotFieldToComponents(fieldName); + let name = components.slice(0, components.length - 1).join('->'); + name += '->>' + components[components.length - 1]; + return name; +}; + +const transformAggregateField = fieldName => { + if (typeof fieldName !== 'string') { + return fieldName; + } + + if (fieldName === '$_created_at') { + return 'createdAt'; + } + + if (fieldName === '$_updated_at') { + return 'updatedAt'; + } + + return fieldName.substr(1); +}; + +const validateKeys = object => { + if (typeof object == 'object') { + for (const key in object) { + if (typeof object[key] == 'object') { + validateKeys(object[key]); + } + + if (key.includes('$') || key.includes('.')) { + throw new _node.default.Error(_node.default.Error.INVALID_NESTED_KEY, "Nested keys should not contain the '$' or '.' characters"); + } + } + } +}; // Returns the list of join tables on a schema + + +const joinTablesForSchema = schema => { + const list = []; + + if (schema) { + Object.keys(schema.fields).forEach(field => { + if (schema.fields[field].type === 'Relation') { + list.push(`_Join:${field}:${schema.className}`); + } + }); + } + + return list; +}; + +const buildWhereClause = ({ + schema, + query, + index, + caseInsensitive +}) => { + const patterns = []; + let values = []; + const sorts = []; + schema = toPostgresSchema(schema); + + for (const fieldName in query) { + const isArrayField = schema.fields && schema.fields[fieldName] && schema.fields[fieldName].type === 'Array'; + const initialPatternsLength = patterns.length; + const fieldValue = query[fieldName]; // nothing in the schema, it's gonna blow up + + if (!schema.fields[fieldName]) { + // as it won't exist + if (fieldValue && fieldValue.$exists === false) { + continue; + } + } + + const authDataMatch = fieldName.match(/^_auth_data_([a-zA-Z0-9_]+)$/); + + if (authDataMatch) { + // TODO: Handle querying by _auth_data_provider, authData is stored in authData field + continue; + } else if (caseInsensitive && (fieldName === 'username' || fieldName === 'email')) { + patterns.push(`LOWER($${index}:name) = LOWER($${index + 1})`); + values.push(fieldName, fieldValue); + index += 2; + } else if (fieldName.indexOf('.') >= 0) { + let name = transformDotField(fieldName); + + if (fieldValue === null) { + patterns.push(`$${index}:raw IS NULL`); + values.push(name); + index += 1; + continue; + } else { + if (fieldValue.$in) { + name = transformDotFieldToComponents(fieldName).join('->'); + patterns.push(`($${index}:raw)::jsonb @> $${index + 1}::jsonb`); + values.push(name, JSON.stringify(fieldValue.$in)); + index += 2; + } else if (fieldValue.$regex) {// Handle later + } else if (typeof fieldValue !== 'object') { + patterns.push(`$${index}:raw = $${index + 1}::text`); + values.push(name, fieldValue); + index += 2; + } + } + } else if (fieldValue === null || fieldValue === undefined) { + patterns.push(`$${index}:name IS NULL`); + values.push(fieldName); + index += 1; + continue; + } else if (typeof fieldValue === 'string') { + patterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue); + index += 2; + } else if (typeof fieldValue === 'boolean') { + patterns.push(`$${index}:name = $${index + 1}`); // Can't cast boolean to double precision + + if (schema.fields[fieldName] && schema.fields[fieldName].type === 'Number') { + // Should always return zero results + const MAX_INT_PLUS_ONE = 9223372036854775808; + values.push(fieldName, MAX_INT_PLUS_ONE); + } else { + values.push(fieldName, fieldValue); + } + + index += 2; + } else if (typeof fieldValue === 'number') { + patterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue); + index += 2; + } else if (['$or', '$nor', '$and'].includes(fieldName)) { + const clauses = []; + const clauseValues = []; + fieldValue.forEach(subQuery => { + const clause = buildWhereClause({ + schema, + query: subQuery, + index, + caseInsensitive + }); + + if (clause.pattern.length > 0) { + clauses.push(clause.pattern); + clauseValues.push(...clause.values); + index += clause.values.length; + } + }); + const orOrAnd = fieldName === '$and' ? ' AND ' : ' OR '; + const not = fieldName === '$nor' ? ' NOT ' : ''; + patterns.push(`${not}(${clauses.join(orOrAnd)})`); + values.push(...clauseValues); + } + + if (fieldValue.$ne !== undefined) { + if (isArrayField) { + fieldValue.$ne = JSON.stringify([fieldValue.$ne]); + patterns.push(`NOT array_contains($${index}:name, $${index + 1})`); + } else { + if (fieldValue.$ne === null) { + patterns.push(`$${index}:name IS NOT NULL`); + values.push(fieldName); + index += 1; + continue; + } else { + // if not null, we need to manually exclude null + if (fieldValue.$ne.__type === 'GeoPoint') { + patterns.push(`($${index}:name <> POINT($${index + 1}, $${index + 2}) OR $${index}:name IS NULL)`); + } else { + if (fieldName.indexOf('.') >= 0) { + const constraintFieldName = transformDotField(fieldName); + patterns.push(`(${constraintFieldName} <> $${index} OR ${constraintFieldName} IS NULL)`); + } else { + patterns.push(`($${index}:name <> $${index + 1} OR $${index}:name IS NULL)`); + } + } + } + } + + if (fieldValue.$ne.__type === 'GeoPoint') { + const point = fieldValue.$ne; + values.push(fieldName, point.longitude, point.latitude); + index += 3; + } else { + // TODO: support arrays + values.push(fieldName, fieldValue.$ne); + index += 2; + } + } + + if (fieldValue.$eq !== undefined) { + if (fieldValue.$eq === null) { + patterns.push(`$${index}:name IS NULL`); + values.push(fieldName); + index += 1; + } else { + if (fieldName.indexOf('.') >= 0) { + values.push(fieldValue.$eq); + patterns.push(`${transformDotField(fieldName)} = $${index++}`); + } else { + values.push(fieldName, fieldValue.$eq); + patterns.push(`$${index}:name = $${index + 1}`); + index += 2; + } + } + } + + const isInOrNin = Array.isArray(fieldValue.$in) || Array.isArray(fieldValue.$nin); + + if (Array.isArray(fieldValue.$in) && isArrayField && schema.fields[fieldName].contents && schema.fields[fieldName].contents.type === 'String') { + const inPatterns = []; + let allowNull = false; + values.push(fieldName); + fieldValue.$in.forEach((listElem, listIndex) => { + if (listElem === null) { + allowNull = true; + } else { + values.push(listElem); + inPatterns.push(`$${index + 1 + listIndex - (allowNull ? 1 : 0)}`); + } + }); + + if (allowNull) { + patterns.push(`($${index}:name IS NULL OR $${index}:name && ARRAY[${inPatterns.join()}])`); + } else { + patterns.push(`$${index}:name && ARRAY[${inPatterns.join()}]`); + } + + index = index + 1 + inPatterns.length; + } else if (isInOrNin) { + var createConstraint = (baseArray, notIn) => { + const not = notIn ? ' NOT ' : ''; + + if (baseArray.length > 0) { + if (isArrayField) { + patterns.push(`${not} array_contains($${index}:name, $${index + 1})`); + values.push(fieldName, JSON.stringify(baseArray)); + index += 2; + } else { + // Handle Nested Dot Notation Above + if (fieldName.indexOf('.') >= 0) { + return; + } + + const inPatterns = []; + values.push(fieldName); + baseArray.forEach((listElem, listIndex) => { + if (listElem != null) { + values.push(listElem); + inPatterns.push(`$${index + 1 + listIndex}`); + } + }); + patterns.push(`$${index}:name ${not} IN (${inPatterns.join()})`); + index = index + 1 + inPatterns.length; + } + } else if (!notIn) { + values.push(fieldName); + patterns.push(`$${index}:name IS NULL`); + index = index + 1; + } else { + // Handle empty array + if (notIn) { + patterns.push('1 = 1'); // Return all values + } else { + patterns.push('1 = 2'); // Return no values + } + } + }; + + if (fieldValue.$in) { + createConstraint(_lodash.default.flatMap(fieldValue.$in, elt => elt), false); + } + + if (fieldValue.$nin) { + createConstraint(_lodash.default.flatMap(fieldValue.$nin, elt => elt), true); + } + } else if (typeof fieldValue.$in !== 'undefined') { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $in value'); + } else if (typeof fieldValue.$nin !== 'undefined') { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $nin value'); + } + + if (Array.isArray(fieldValue.$all) && isArrayField) { + if (isAnyValueRegexStartsWith(fieldValue.$all)) { + if (!isAllValuesRegexOrNone(fieldValue.$all)) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'All $all values must be of regex type or none: ' + fieldValue.$all); + } + + for (let i = 0; i < fieldValue.$all.length; i += 1) { + const value = processRegexPattern(fieldValue.$all[i].$regex); + fieldValue.$all[i] = value.substring(1) + '%'; + } + + patterns.push(`array_contains_all_regex($${index}:name, $${index + 1}::jsonb)`); + } else { + patterns.push(`array_contains_all($${index}:name, $${index + 1}::jsonb)`); + } + + values.push(fieldName, JSON.stringify(fieldValue.$all)); + index += 2; + } else if (Array.isArray(fieldValue.$all)) { + if (fieldValue.$all.length === 1) { + patterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue.$all[0].objectId); + index += 2; + } + } + + if (typeof fieldValue.$exists !== 'undefined') { + if (fieldValue.$exists) { + patterns.push(`$${index}:name IS NOT NULL`); + } else { + patterns.push(`$${index}:name IS NULL`); + } + + values.push(fieldName); + index += 1; + } + + if (fieldValue.$containedBy) { + const arr = fieldValue.$containedBy; + + if (!(arr instanceof Array)) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $containedBy: should be an array`); + } + + patterns.push(`$${index}:name <@ $${index + 1}::jsonb`); + values.push(fieldName, JSON.stringify(arr)); + index += 2; + } + + if (fieldValue.$text) { + const search = fieldValue.$text.$search; + let language = 'english'; + + if (typeof search !== 'object') { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $search, should be object`); + } + + if (!search.$term || typeof search.$term !== 'string') { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $term, should be string`); + } + + if (search.$language && typeof search.$language !== 'string') { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $language, should be string`); + } else if (search.$language) { + language = search.$language; + } + + if (search.$caseSensitive && typeof search.$caseSensitive !== 'boolean') { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $caseSensitive, should be boolean`); + } else if (search.$caseSensitive) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $caseSensitive not supported, please use $regex or create a separate lower case column.`); + } + + if (search.$diacriticSensitive && typeof search.$diacriticSensitive !== 'boolean') { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $diacriticSensitive, should be boolean`); + } else if (search.$diacriticSensitive === false) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $diacriticSensitive - false not supported, install Postgres Unaccent Extension`); + } + + patterns.push(`to_tsvector($${index}, $${index + 1}:name) @@ to_tsquery($${index + 2}, $${index + 3})`); + values.push(language, fieldName, language, search.$term); + index += 4; + } + + if (fieldValue.$nearSphere) { + const point = fieldValue.$nearSphere; + const distance = fieldValue.$maxDistance; + const distanceInKM = distance * 6371 * 1000; + patterns.push(`ST_DistanceSphere($${index}:name::geometry, POINT($${index + 1}, $${index + 2})::geometry) <= $${index + 3}`); + sorts.push(`ST_DistanceSphere($${index}:name::geometry, POINT($${index + 1}, $${index + 2})::geometry) ASC`); + values.push(fieldName, point.longitude, point.latitude, distanceInKM); + index += 4; + } + + if (fieldValue.$within && fieldValue.$within.$box) { + const box = fieldValue.$within.$box; + const left = box[0].longitude; + const bottom = box[0].latitude; + const right = box[1].longitude; + const top = box[1].latitude; + patterns.push(`$${index}:name::point <@ $${index + 1}::box`); + values.push(fieldName, `((${left}, ${bottom}), (${right}, ${top}))`); + index += 2; + } + + if (fieldValue.$geoWithin && fieldValue.$geoWithin.$centerSphere) { + const centerSphere = fieldValue.$geoWithin.$centerSphere; + + if (!(centerSphere instanceof Array) || centerSphere.length < 2) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere should be an array of Parse.GeoPoint and distance'); + } // Get point, convert to geo point if necessary and validate + + + let point = centerSphere[0]; + + if (point instanceof Array && point.length === 2) { + point = new _node.default.GeoPoint(point[1], point[0]); + } else if (!GeoPointCoder.isValidJSON(point)) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere geo point invalid'); + } + + _node.default.GeoPoint._validate(point.latitude, point.longitude); // Get distance and validate + + + const distance = centerSphere[1]; + + if (isNaN(distance) || distance < 0) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere distance invalid'); + } + + const distanceInKM = distance * 6371 * 1000; + patterns.push(`ST_DistanceSphere($${index}:name::geometry, POINT($${index + 1}, $${index + 2})::geometry) <= $${index + 3}`); + values.push(fieldName, point.longitude, point.latitude, distanceInKM); + index += 4; + } + + if (fieldValue.$geoWithin && fieldValue.$geoWithin.$polygon) { + const polygon = fieldValue.$geoWithin.$polygon; + let points; + + if (typeof polygon === 'object' && polygon.__type === 'Polygon') { + if (!polygon.coordinates || polygon.coordinates.length < 3) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; Polygon.coordinates should contain at least 3 lon/lat pairs'); + } + + points = polygon.coordinates; + } else if (polygon instanceof Array) { + if (polygon.length < 3) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; $polygon should contain at least 3 GeoPoints'); + } + + points = polygon; + } else { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, "bad $geoWithin value; $polygon should be Polygon object or Array of Parse.GeoPoint's"); + } + + points = points.map(point => { + if (point instanceof Array && point.length === 2) { + _node.default.GeoPoint._validate(point[1], point[0]); + + return `(${point[0]}, ${point[1]})`; + } + + if (typeof point !== 'object' || point.__type !== 'GeoPoint') { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value'); + } else { + _node.default.GeoPoint._validate(point.latitude, point.longitude); + } + + return `(${point.longitude}, ${point.latitude})`; + }).join(', '); + patterns.push(`$${index}:name::point <@ $${index + 1}::polygon`); + values.push(fieldName, `(${points})`); + index += 2; + } + + if (fieldValue.$geoIntersects && fieldValue.$geoIntersects.$point) { + const point = fieldValue.$geoIntersects.$point; + + if (typeof point !== 'object' || point.__type !== 'GeoPoint') { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoIntersect value; $point should be GeoPoint'); + } else { + _node.default.GeoPoint._validate(point.latitude, point.longitude); + } + + patterns.push(`$${index}:name::polygon @> $${index + 1}::point`); + values.push(fieldName, `(${point.longitude}, ${point.latitude})`); + index += 2; + } + + if (fieldValue.$regex) { + let regex = fieldValue.$regex; + let operator = '~'; + const opts = fieldValue.$options; + + if (opts) { + if (opts.indexOf('i') >= 0) { + operator = '~*'; + } + + if (opts.indexOf('x') >= 0) { + regex = removeWhiteSpace(regex); + } + } + + const name = transformDotField(fieldName); + regex = processRegexPattern(regex); + patterns.push(`$${index}:raw ${operator} '$${index + 1}:raw'`); + values.push(name, regex); + index += 2; + } + + if (fieldValue.__type === 'Pointer') { + if (isArrayField) { + patterns.push(`array_contains($${index}:name, $${index + 1})`); + values.push(fieldName, JSON.stringify([fieldValue])); + index += 2; + } else { + patterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue.objectId); + index += 2; + } + } + + if (fieldValue.__type === 'Date') { + patterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue.iso); + index += 2; + } + + if (fieldValue.__type === 'GeoPoint') { + patterns.push(`$${index}:name ~= POINT($${index + 1}, $${index + 2})`); + values.push(fieldName, fieldValue.longitude, fieldValue.latitude); + index += 3; + } + + if (fieldValue.__type === 'Polygon') { + const value = convertPolygonToSQL(fieldValue.coordinates); + patterns.push(`$${index}:name ~= $${index + 1}::polygon`); + values.push(fieldName, value); + index += 2; + } + + Object.keys(ParseToPosgresComparator).forEach(cmp => { + if (fieldValue[cmp] || fieldValue[cmp] === 0) { + const pgComparator = ParseToPosgresComparator[cmp]; + const postgresValue = toPostgresValue(fieldValue[cmp]); + let constraintFieldName; + + if (fieldName.indexOf('.') >= 0) { + let castType; + + switch (typeof postgresValue) { + case 'number': + castType = 'double precision'; + break; + + case 'boolean': + castType = 'boolean'; + break; + + default: + castType = undefined; + } + + constraintFieldName = castType ? `CAST ((${transformDotField(fieldName)}) AS ${castType})` : transformDotField(fieldName); + } else { + constraintFieldName = `$${index++}:name`; + values.push(fieldName); + } + + values.push(postgresValue); + patterns.push(`${constraintFieldName} ${pgComparator} $${index++}`); + } + }); + + if (initialPatternsLength === patterns.length) { + throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, `Postgres doesn't support this query type yet ${JSON.stringify(fieldValue)}`); + } + } + + values = values.map(transformValue); + return { + pattern: patterns.join(' AND '), + values, + sorts + }; +}; + +class PostgresStorageAdapter { + // Private + constructor({ + uri, + collectionPrefix = '', + databaseOptions + }) { + this._collectionPrefix = collectionPrefix; + const { + client, + pgp + } = (0, _PostgresClient.createClient)(uri, databaseOptions); + this._client = client; + this._pgp = pgp; + this.canSortOnJoinTables = false; + } //Note that analyze=true will run the query, executing INSERTS, DELETES, etc. + + + createExplainableQuery(query, analyze = false) { + if (analyze) { + return 'EXPLAIN (ANALYZE, FORMAT JSON) ' + query; + } else { + return 'EXPLAIN (FORMAT JSON) ' + query; + } + } + + handleShutdown() { + if (!this._client) { + return; + } + + this._client.$pool.end(); + } + + async _ensureSchemaCollectionExists(conn) { + conn = conn || this._client; + await conn.none('CREATE TABLE IF NOT EXISTS "_SCHEMA" ( "className" varChar(120), "schema" jsonb, "isParseClass" bool, PRIMARY KEY ("className") )').catch(error => { + if (error.code === PostgresDuplicateRelationError || error.code === PostgresUniqueIndexViolationError || error.code === PostgresDuplicateObjectError) {// Table already exists, must have been created by a different request. Ignore error. + } else { + throw error; + } + }); + } + + async classExists(name) { + return this._client.one('SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1)', [name], a => a.exists); + } + + async setClassLevelPermissions(className, CLPs) { + const self = this; + await this._client.task('set-class-level-permissions', async t => { + await self._ensureSchemaCollectionExists(t); + const values = [className, 'schema', 'classLevelPermissions', JSON.stringify(CLPs)]; + await t.none(`UPDATE "_SCHEMA" SET $2:name = json_object_set_key($2:name, $3::text, $4::jsonb) WHERE "className" = $1`, values); + }); + } + + async setIndexesWithSchemaFormat(className, submittedIndexes, existingIndexes = {}, fields, conn) { + conn = conn || this._client; + const self = this; + + if (submittedIndexes === undefined) { + return Promise.resolve(); + } + + if (Object.keys(existingIndexes).length === 0) { + existingIndexes = { + _id_: { + _id: 1 + } + }; + } + + const deletedIndexes = []; + const insertedIndexes = []; + Object.keys(submittedIndexes).forEach(name => { + const field = submittedIndexes[name]; + + if (existingIndexes[name] && field.__op !== 'Delete') { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Index ${name} exists, cannot update.`); + } + + if (!existingIndexes[name] && field.__op === 'Delete') { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Index ${name} does not exist, cannot delete.`); + } + + if (field.__op === 'Delete') { + deletedIndexes.push(name); + delete existingIndexes[name]; + } else { + Object.keys(field).forEach(key => { + if (!Object.prototype.hasOwnProperty.call(fields, key)) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Field ${key} does not exist, cannot add index.`); + } + }); + existingIndexes[name] = field; + insertedIndexes.push({ + key: field, + name + }); + } + }); + await conn.tx('set-indexes-with-schema-format', async t => { + if (insertedIndexes.length > 0) { + await self.createIndexes(className, insertedIndexes, t); + } + + if (deletedIndexes.length > 0) { + await self.dropIndexes(className, deletedIndexes, t); + } + + await self._ensureSchemaCollectionExists(t); + await t.none('UPDATE "_SCHEMA" SET $2:name = json_object_set_key($2:name, $3::text, $4::jsonb) WHERE "className" = $1', [className, 'schema', 'indexes', JSON.stringify(existingIndexes)]); + }); + } + + async createClass(className, schema, conn) { + conn = conn || this._client; + return conn.tx('create-class', async t => { + await this.createTable(className, schema, t); + await t.none('INSERT INTO "_SCHEMA" ("className", "schema", "isParseClass") VALUES ($, $, true)', { + className, + schema + }); + await this.setIndexesWithSchemaFormat(className, schema.indexes, {}, schema.fields, t); + return toParseSchema(schema); + }).catch(err => { + if (err.code === PostgresUniqueIndexViolationError && err.detail.includes(className)) { + throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, `Class ${className} already exists.`); + } + + throw err; + }); + } // Just create a table, do not insert in schema + + + async createTable(className, schema, conn) { + conn = conn || this._client; + const self = this; + debug('createTable', className, schema); + const valuesArray = []; + const patternsArray = []; + const fields = Object.assign({}, schema.fields); + + if (className === '_User') { + fields._email_verify_token_expires_at = { + type: 'Date' + }; + fields._email_verify_token = { + type: 'String' + }; + fields._account_lockout_expires_at = { + type: 'Date' + }; + fields._failed_login_count = { + type: 'Number' + }; + fields._perishable_token = { + type: 'String' + }; + fields._perishable_token_expires_at = { + type: 'Date' + }; + fields._password_changed_at = { + type: 'Date' + }; + fields._password_history = { + type: 'Array' + }; + } + + let index = 2; + const relations = []; + Object.keys(fields).forEach(fieldName => { + const parseType = fields[fieldName]; // Skip when it's a relation + // We'll create the tables later + + if (parseType.type === 'Relation') { + relations.push(fieldName); + return; + } + + if (['_rperm', '_wperm'].indexOf(fieldName) >= 0) { + parseType.contents = { + type: 'String' + }; + } + + valuesArray.push(fieldName); + valuesArray.push(parseTypeToPostgresType(parseType)); + patternsArray.push(`$${index}:name $${index + 1}:raw`); + + if (fieldName === 'objectId') { + patternsArray.push(`PRIMARY KEY ($${index}:name)`); + } + + index = index + 2; + }); + const qs = `CREATE TABLE IF NOT EXISTS $1:name (${patternsArray.join()})`; + const values = [className, ...valuesArray]; + debug(qs, values); + return conn.task('create-table', async t => { + try { + await self._ensureSchemaCollectionExists(t); + await t.none(qs, values); + } catch (error) { + if (error.code !== PostgresDuplicateRelationError) { + throw error; + } // ELSE: Table already exists, must have been created by a different request. Ignore the error. + + } + + await t.tx('create-table-tx', tx => { + return tx.batch(relations.map(fieldName => { + return tx.none('CREATE TABLE IF NOT EXISTS $ ("relatedId" varChar(120), "owningId" varChar(120), PRIMARY KEY("relatedId", "owningId") )', { + joinTable: `_Join:${fieldName}:${className}` + }); + })); + }); + }); + } + + async schemaUpgrade(className, schema, conn) { + debug('schemaUpgrade', { + className, + schema + }); + conn = conn || this._client; + const self = this; + await conn.tx('schema-upgrade', async t => { + const columns = await t.map('SELECT column_name FROM information_schema.columns WHERE table_name = $', { + className + }, a => a.column_name); + const newColumns = Object.keys(schema.fields).filter(item => columns.indexOf(item) === -1).map(fieldName => self.addFieldIfNotExists(className, fieldName, schema.fields[fieldName], t)); + await t.batch(newColumns); + }); + } + + async addFieldIfNotExists(className, fieldName, type, conn) { + // TODO: Must be revised for invalid logic... + debug('addFieldIfNotExists', { + className, + fieldName, + type + }); + conn = conn || this._client; + const self = this; + await conn.tx('add-field-if-not-exists', async t => { + if (type.type !== 'Relation') { + try { + await t.none('ALTER TABLE $ ADD COLUMN IF NOT EXISTS $ $', { + className, + fieldName, + postgresType: parseTypeToPostgresType(type) + }); + } catch (error) { + if (error.code === PostgresRelationDoesNotExistError) { + return self.createClass(className, { + fields: { + [fieldName]: type + } + }, t); + } + + if (error.code !== PostgresDuplicateColumnError) { + throw error; + } // Column already exists, created by other request. Carry on to see if it's the right type. + + } + } else { + await t.none('CREATE TABLE IF NOT EXISTS $ ("relatedId" varChar(120), "owningId" varChar(120), PRIMARY KEY("relatedId", "owningId") )', { + joinTable: `_Join:${fieldName}:${className}` + }); + } + + const result = await t.any('SELECT "schema" FROM "_SCHEMA" WHERE "className" = $ and ("schema"::json->\'fields\'->$) is not null', { + className, + fieldName + }); + + if (result[0]) { + throw 'Attempted to add a field that already exists'; + } else { + const path = `{fields,${fieldName}}`; + await t.none('UPDATE "_SCHEMA" SET "schema"=jsonb_set("schema", $, $) WHERE "className"=$', { + path, + type, + className + }); + } + }); + } // Drops a collection. Resolves with true if it was a Parse Schema (eg. _User, Custom, etc.) + // and resolves with false if it wasn't (eg. a join table). Rejects if deletion was impossible. + + + async deleteClass(className) { + const operations = [{ + query: `DROP TABLE IF EXISTS $1:name`, + values: [className] + }, { + query: `DELETE FROM "_SCHEMA" WHERE "className" = $1`, + values: [className] + }]; + return this._client.tx(t => t.none(this._pgp.helpers.concat(operations))).then(() => className.indexOf('_Join:') != 0); // resolves with false when _Join table + } // Delete all data known to this adapter. Used for testing. + + + async deleteAllClasses() { + const now = new Date().getTime(); + const helpers = this._pgp.helpers; + debug('deleteAllClasses'); + await this._client.task('delete-all-classes', async t => { + try { + const results = await t.any('SELECT * FROM "_SCHEMA"'); + const joins = results.reduce((list, schema) => { + return list.concat(joinTablesForSchema(schema.schema)); + }, []); + const classes = ['_SCHEMA', '_PushStatus', '_JobStatus', '_JobSchedule', '_Hooks', '_GlobalConfig', '_GraphQLConfig', '_Audience', '_Idempotency', ...results.map(result => result.className), ...joins]; + const queries = classes.map(className => ({ + query: 'DROP TABLE IF EXISTS $', + values: { + className + } + })); + await t.tx(tx => tx.none(helpers.concat(queries))); + } catch (error) { + if (error.code !== PostgresRelationDoesNotExistError) { + throw error; + } // No _SCHEMA collection. Don't delete anything. + + } + }).then(() => { + debug(`deleteAllClasses done in ${new Date().getTime() - now}`); + }); + } // Remove the column and all the data. For Relations, the _Join collection is handled + // specially, this function does not delete _Join columns. It should, however, indicate + // that the relation fields does not exist anymore. In mongo, this means removing it from + // the _SCHEMA collection. There should be no actual data in the collection under the same name + // as the relation column, so it's fine to attempt to delete it. If the fields listed to be + // deleted do not exist, this function should return successfully anyways. Checking for + // attempts to delete non-existent fields is the responsibility of Parse Server. + // This function is not obligated to delete fields atomically. It is given the field + // names in a list so that databases that are capable of deleting fields atomically + // may do so. + // Returns a Promise. + + + async deleteFields(className, schema, fieldNames) { + debug('deleteFields', className, fieldNames); + fieldNames = fieldNames.reduce((list, fieldName) => { + const field = schema.fields[fieldName]; + + if (field.type !== 'Relation') { + list.push(fieldName); + } + + delete schema.fields[fieldName]; + return list; + }, []); + const values = [className, ...fieldNames]; + const columns = fieldNames.map((name, idx) => { + return `$${idx + 2}:name`; + }).join(', DROP COLUMN'); + await this._client.tx('delete-fields', async t => { + await t.none('UPDATE "_SCHEMA" SET "schema" = $ WHERE "className" = $', { + schema, + className + }); + + if (values.length > 1) { + await t.none(`ALTER TABLE $1:name DROP COLUMN IF EXISTS ${columns}`, values); + } + }); + } // Return a promise for all schemas known to this adapter, in Parse format. In case the + // schemas cannot be retrieved, returns a promise that rejects. Requirements for the + // rejection reason are TBD. + + + async getAllClasses() { + const self = this; + return this._client.task('get-all-classes', async t => { + await self._ensureSchemaCollectionExists(t); + return await t.map('SELECT * FROM "_SCHEMA"', null, row => toParseSchema(_objectSpread({ + className: row.className + }, row.schema))); + }); + } // Return a promise for the schema with the given name, in Parse format. If + // this adapter doesn't know about the schema, return a promise that rejects with + // undefined as the reason. + + + async getClass(className) { + debug('getClass', className); + return this._client.any('SELECT * FROM "_SCHEMA" WHERE "className" = $', { + className + }).then(result => { + if (result.length !== 1) { + throw undefined; + } + + return result[0].schema; + }).then(toParseSchema); + } // TODO: remove the mongo format dependency in the return value + + + async createObject(className, schema, object, transactionalSession) { + debug('createObject', className, object); + let columnsArray = []; + const valuesArray = []; + schema = toPostgresSchema(schema); + const geoPoints = {}; + object = handleDotFields(object); + validateKeys(object); + Object.keys(object).forEach(fieldName => { + if (object[fieldName] === null) { + return; + } + + var authDataMatch = fieldName.match(/^_auth_data_([a-zA-Z0-9_]+)$/); + + if (authDataMatch) { + var provider = authDataMatch[1]; + object['authData'] = object['authData'] || {}; + object['authData'][provider] = object[fieldName]; + delete object[fieldName]; + fieldName = 'authData'; + } + + columnsArray.push(fieldName); + + if (!schema.fields[fieldName] && className === '_User') { + if (fieldName === '_email_verify_token' || fieldName === '_failed_login_count' || fieldName === '_perishable_token' || fieldName === '_password_history') { + valuesArray.push(object[fieldName]); + } + + if (fieldName === '_email_verify_token_expires_at') { + if (object[fieldName]) { + valuesArray.push(object[fieldName].iso); + } else { + valuesArray.push(null); + } + } + + if (fieldName === '_account_lockout_expires_at' || fieldName === '_perishable_token_expires_at' || fieldName === '_password_changed_at') { + if (object[fieldName]) { + valuesArray.push(object[fieldName].iso); + } else { + valuesArray.push(null); + } + } + + return; + } + + switch (schema.fields[fieldName].type) { + case 'Date': + if (object[fieldName]) { + valuesArray.push(object[fieldName].iso); + } else { + valuesArray.push(null); + } + + break; + + case 'Pointer': + valuesArray.push(object[fieldName].objectId); + break; + + case 'Array': + if (['_rperm', '_wperm'].indexOf(fieldName) >= 0) { + valuesArray.push(object[fieldName]); + } else { + valuesArray.push(JSON.stringify(object[fieldName])); + } + + break; + + case 'Object': + case 'Bytes': + case 'String': + case 'Number': + case 'Boolean': + valuesArray.push(object[fieldName]); + break; + + case 'File': + valuesArray.push(object[fieldName].name); + break; + + case 'Polygon': + { + const value = convertPolygonToSQL(object[fieldName].coordinates); + valuesArray.push(value); + break; + } + + case 'GeoPoint': + // pop the point and process later + geoPoints[fieldName] = object[fieldName]; + columnsArray.pop(); + break; + + default: + throw `Type ${schema.fields[fieldName].type} not supported yet`; + } + }); + columnsArray = columnsArray.concat(Object.keys(geoPoints)); + const initialValues = valuesArray.map((val, index) => { + let termination = ''; + const fieldName = columnsArray[index]; + + if (['_rperm', '_wperm'].indexOf(fieldName) >= 0) { + termination = '::text[]'; + } else if (schema.fields[fieldName] && schema.fields[fieldName].type === 'Array') { + termination = '::jsonb'; + } + + return `$${index + 2 + columnsArray.length}${termination}`; + }); + const geoPointsInjects = Object.keys(geoPoints).map(key => { + const value = geoPoints[key]; + valuesArray.push(value.longitude, value.latitude); + const l = valuesArray.length + columnsArray.length; + return `POINT($${l}, $${l + 1})`; + }); + const columnsPattern = columnsArray.map((col, index) => `$${index + 2}:name`).join(); + const valuesPattern = initialValues.concat(geoPointsInjects).join(); + const qs = `INSERT INTO $1:name (${columnsPattern}) VALUES (${valuesPattern})`; + const values = [className, ...columnsArray, ...valuesArray]; + debug(qs, values); + const promise = (transactionalSession ? transactionalSession.t : this._client).none(qs, values).then(() => ({ + ops: [object] + })).catch(error => { + if (error.code === PostgresUniqueIndexViolationError) { + const err = new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); + err.underlyingError = error; + + if (error.constraint) { + const matches = error.constraint.match(/unique_([a-zA-Z]+)/); + + if (matches && Array.isArray(matches)) { + err.userInfo = { + duplicated_field: matches[1] + }; + } + } + + error = err; + } + + throw error; + }); + + if (transactionalSession) { + transactionalSession.batch.push(promise); + } + + return promise; + } // Remove all objects that match the given Parse Query. + // If no objects match, reject with OBJECT_NOT_FOUND. If objects are found and deleted, resolve with undefined. + // If there is some other error, reject with INTERNAL_SERVER_ERROR. + + + async deleteObjectsByQuery(className, schema, query, transactionalSession) { + debug('deleteObjectsByQuery', className, query); + const values = [className]; + const index = 2; + const where = buildWhereClause({ + schema, + index, + query, + caseInsensitive: false + }); + values.push(...where.values); + + if (Object.keys(query).length === 0) { + where.pattern = 'TRUE'; + } + + const qs = `WITH deleted AS (DELETE FROM $1:name WHERE ${where.pattern} RETURNING *) SELECT count(*) FROM deleted`; + debug(qs, values); + const promise = (transactionalSession ? transactionalSession.t : this._client).one(qs, values, a => +a.count).then(count => { + if (count === 0) { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } else { + return count; + } + }).catch(error => { + if (error.code !== PostgresRelationDoesNotExistError) { + throw error; + } // ELSE: Don't delete anything if doesn't exist + + }); + + if (transactionalSession) { + transactionalSession.batch.push(promise); + } + + return promise; + } // Return value not currently well specified. + + + async findOneAndUpdate(className, schema, query, update, transactionalSession) { + debug('findOneAndUpdate', className, query, update); + return this.updateObjectsByQuery(className, schema, query, update, transactionalSession).then(val => val[0]); + } // Apply the update to all objects that match the given Parse Query. + + + async updateObjectsByQuery(className, schema, query, update, transactionalSession) { + debug('updateObjectsByQuery', className, query, update); + const updatePatterns = []; + const values = [className]; + let index = 2; + schema = toPostgresSchema(schema); + + const originalUpdate = _objectSpread({}, update); // Set flag for dot notation fields + + + const dotNotationOptions = {}; + Object.keys(update).forEach(fieldName => { + if (fieldName.indexOf('.') > -1) { + const components = fieldName.split('.'); + const first = components.shift(); + dotNotationOptions[first] = true; + } else { + dotNotationOptions[fieldName] = false; + } + }); + update = handleDotFields(update); // Resolve authData first, + // So we don't end up with multiple key updates + + for (const fieldName in update) { + const authDataMatch = fieldName.match(/^_auth_data_([a-zA-Z0-9_]+)$/); + + if (authDataMatch) { + var provider = authDataMatch[1]; + const value = update[fieldName]; + delete update[fieldName]; + update['authData'] = update['authData'] || {}; + update['authData'][provider] = value; + } + } + + for (const fieldName in update) { + const fieldValue = update[fieldName]; // Drop any undefined values. + + if (typeof fieldValue === 'undefined') { + delete update[fieldName]; + } else if (fieldValue === null) { + updatePatterns.push(`$${index}:name = NULL`); + values.push(fieldName); + index += 1; + } else if (fieldName == 'authData') { + // This recursively sets the json_object + // Only 1 level deep + const generate = (jsonb, key, value) => { + return `json_object_set_key(COALESCE(${jsonb}, '{}'::jsonb), ${key}, ${value})::jsonb`; + }; + + const lastKey = `$${index}:name`; + const fieldNameIndex = index; + index += 1; + values.push(fieldName); + const update = Object.keys(fieldValue).reduce((lastKey, key) => { + const str = generate(lastKey, `$${index}::text`, `$${index + 1}::jsonb`); + index += 2; + let value = fieldValue[key]; + + if (value) { + if (value.__op === 'Delete') { + value = null; + } else { + value = JSON.stringify(value); + } + } + + values.push(key, value); + return str; + }, lastKey); + updatePatterns.push(`$${fieldNameIndex}:name = ${update}`); + } else if (fieldValue.__op === 'Increment') { + updatePatterns.push(`$${index}:name = COALESCE($${index}:name, 0) + $${index + 1}`); + values.push(fieldName, fieldValue.amount); + index += 2; + } else if (fieldValue.__op === 'Add') { + updatePatterns.push(`$${index}:name = array_add(COALESCE($${index}:name, '[]'::jsonb), $${index + 1}::jsonb)`); + values.push(fieldName, JSON.stringify(fieldValue.objects)); + index += 2; + } else if (fieldValue.__op === 'Delete') { + updatePatterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, null); + index += 2; + } else if (fieldValue.__op === 'Remove') { + updatePatterns.push(`$${index}:name = array_remove(COALESCE($${index}:name, '[]'::jsonb), $${index + 1}::jsonb)`); + values.push(fieldName, JSON.stringify(fieldValue.objects)); + index += 2; + } else if (fieldValue.__op === 'AddUnique') { + updatePatterns.push(`$${index}:name = array_add_unique(COALESCE($${index}:name, '[]'::jsonb), $${index + 1}::jsonb)`); + values.push(fieldName, JSON.stringify(fieldValue.objects)); + index += 2; + } else if (fieldName === 'updatedAt') { + //TODO: stop special casing this. It should check for __type === 'Date' and use .iso + updatePatterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue); + index += 2; + } else if (typeof fieldValue === 'string') { + updatePatterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue); + index += 2; + } else if (typeof fieldValue === 'boolean') { + updatePatterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue); + index += 2; + } else if (fieldValue.__type === 'Pointer') { + updatePatterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue.objectId); + index += 2; + } else if (fieldValue.__type === 'Date') { + updatePatterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, toPostgresValue(fieldValue)); + index += 2; + } else if (fieldValue instanceof Date) { + updatePatterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue); + index += 2; + } else if (fieldValue.__type === 'File') { + updatePatterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, toPostgresValue(fieldValue)); + index += 2; + } else if (fieldValue.__type === 'GeoPoint') { + updatePatterns.push(`$${index}:name = POINT($${index + 1}, $${index + 2})`); + values.push(fieldName, fieldValue.longitude, fieldValue.latitude); + index += 3; + } else if (fieldValue.__type === 'Polygon') { + const value = convertPolygonToSQL(fieldValue.coordinates); + updatePatterns.push(`$${index}:name = $${index + 1}::polygon`); + values.push(fieldName, value); + index += 2; + } else if (fieldValue.__type === 'Relation') {// noop + } else if (typeof fieldValue === 'number') { + updatePatterns.push(`$${index}:name = $${index + 1}`); + values.push(fieldName, fieldValue); + index += 2; + } else if (typeof fieldValue === 'object' && schema.fields[fieldName] && schema.fields[fieldName].type === 'Object') { + // Gather keys to increment + const keysToIncrement = Object.keys(originalUpdate).filter(k => { + // choose top level fields that have a delete operation set + // Note that Object.keys is iterating over the **original** update object + // and that some of the keys of the original update could be null or undefined: + // (See the above check `if (fieldValue === null || typeof fieldValue == "undefined")`) + const value = originalUpdate[k]; + return value && value.__op === 'Increment' && k.split('.').length === 2 && k.split('.')[0] === fieldName; + }).map(k => k.split('.')[1]); + let incrementPatterns = ''; + + if (keysToIncrement.length > 0) { + incrementPatterns = ' || ' + keysToIncrement.map(c => { + const amount = fieldValue[c].amount; + return `CONCAT('{"${c}":', COALESCE($${index}:name->>'${c}','0')::int + ${amount}, '}')::jsonb`; + }).join(' || '); // Strip the keys + + keysToIncrement.forEach(key => { + delete fieldValue[key]; + }); + } + + const keysToDelete = Object.keys(originalUpdate).filter(k => { + // choose top level fields that have a delete operation set. + const value = originalUpdate[k]; + return value && value.__op === 'Delete' && k.split('.').length === 2 && k.split('.')[0] === fieldName; + }).map(k => k.split('.')[1]); + const deletePatterns = keysToDelete.reduce((p, c, i) => { + return p + ` - '$${index + 1 + i}:value'`; + }, ''); // Override Object + + let updateObject = "'{}'::jsonb"; + + if (dotNotationOptions[fieldName]) { + // Merge Object + updateObject = `COALESCE($${index}:name, '{}'::jsonb)`; + } + + updatePatterns.push(`$${index}:name = (${updateObject} ${deletePatterns} ${incrementPatterns} || $${index + 1 + keysToDelete.length}::jsonb )`); + values.push(fieldName, ...keysToDelete, JSON.stringify(fieldValue)); + index += 2 + keysToDelete.length; + } else if (Array.isArray(fieldValue) && schema.fields[fieldName] && schema.fields[fieldName].type === 'Array') { + const expectedType = parseTypeToPostgresType(schema.fields[fieldName]); + + if (expectedType === 'text[]') { + updatePatterns.push(`$${index}:name = $${index + 1}::text[]`); + values.push(fieldName, fieldValue); + index += 2; + } else { + updatePatterns.push(`$${index}:name = $${index + 1}::jsonb`); + values.push(fieldName, JSON.stringify(fieldValue)); + index += 2; + } + } else { + debug('Not supported update', fieldName, fieldValue); + return Promise.reject(new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, `Postgres doesn't support update ${JSON.stringify(fieldValue)} yet`)); + } + } + + const where = buildWhereClause({ + schema, + index, + query, + caseInsensitive: false + }); + values.push(...where.values); + const whereClause = where.pattern.length > 0 ? `WHERE ${where.pattern}` : ''; + const qs = `UPDATE $1:name SET ${updatePatterns.join()} ${whereClause} RETURNING *`; + debug('update: ', qs, values); + const promise = (transactionalSession ? transactionalSession.t : this._client).any(qs, values); + + if (transactionalSession) { + transactionalSession.batch.push(promise); + } + + return promise; + } // Hopefully, we can get rid of this. It's only used for config and hooks. + + + upsertOneObject(className, schema, query, update, transactionalSession) { + debug('upsertOneObject', { + className, + query, + update + }); + const createValue = Object.assign({}, query, update); + return this.createObject(className, schema, createValue, transactionalSession).catch(error => { + // ignore duplicate value errors as it's upsert + if (error.code !== _node.default.Error.DUPLICATE_VALUE) { + throw error; + } + + return this.findOneAndUpdate(className, schema, query, update, transactionalSession); + }); + } + + find(className, schema, query, { + skip, + limit, + sort, + keys, + caseInsensitive, + explain + }) { + debug('find', className, query, { + skip, + limit, + sort, + keys, + caseInsensitive, + explain + }); + const hasLimit = limit !== undefined; + const hasSkip = skip !== undefined; + let values = [className]; + const where = buildWhereClause({ + schema, + query, + index: 2, + caseInsensitive + }); + values.push(...where.values); + const wherePattern = where.pattern.length > 0 ? `WHERE ${where.pattern}` : ''; + const limitPattern = hasLimit ? `LIMIT $${values.length + 1}` : ''; + + if (hasLimit) { + values.push(limit); + } + + const skipPattern = hasSkip ? `OFFSET $${values.length + 1}` : ''; + + if (hasSkip) { + values.push(skip); + } + + let sortPattern = ''; + + if (sort) { + const sortCopy = sort; + const sorting = Object.keys(sort).map(key => { + const transformKey = transformDotFieldToComponents(key).join('->'); // Using $idx pattern gives: non-integer constant in ORDER BY + + if (sortCopy[key] === 1) { + return `${transformKey} ASC`; + } + + return `${transformKey} DESC`; + }).join(); + sortPattern = sort !== undefined && Object.keys(sort).length > 0 ? `ORDER BY ${sorting}` : ''; + } + + if (where.sorts && Object.keys(where.sorts).length > 0) { + sortPattern = `ORDER BY ${where.sorts.join()}`; + } + + let columns = '*'; + + if (keys) { + // Exclude empty keys + // Replace ACL by it's keys + keys = keys.reduce((memo, key) => { + if (key === 'ACL') { + memo.push('_rperm'); + memo.push('_wperm'); + } else if (key.length > 0) { + memo.push(key); + } + + return memo; + }, []); + columns = keys.map((key, index) => { + if (key === '$score') { + return `ts_rank_cd(to_tsvector($${2}, $${3}:name), to_tsquery($${4}, $${5}), 32) as score`; + } + + return `$${index + values.length + 1}:name`; + }).join(); + values = values.concat(keys); + } + + const originalQuery = `SELECT ${columns} FROM $1:name ${wherePattern} ${sortPattern} ${limitPattern} ${skipPattern}`; + const qs = explain ? this.createExplainableQuery(originalQuery) : originalQuery; + debug(qs, values); + return this._client.any(qs, values).catch(error => { + // Query on non existing table, don't crash + if (error.code !== PostgresRelationDoesNotExistError) { + throw error; + } + + return []; + }).then(results => { + if (explain) { + return results; + } + + return results.map(object => this.postgresObjectToParseObject(className, object, schema)); + }); + } // Converts from a postgres-format object to a REST-format object. + // Does not strip out anything based on a lack of authentication. + + + postgresObjectToParseObject(className, object, schema) { + Object.keys(schema.fields).forEach(fieldName => { + if (schema.fields[fieldName].type === 'Pointer' && object[fieldName]) { + object[fieldName] = { + objectId: object[fieldName], + __type: 'Pointer', + className: schema.fields[fieldName].targetClass + }; + } + + if (schema.fields[fieldName].type === 'Relation') { + object[fieldName] = { + __type: 'Relation', + className: schema.fields[fieldName].targetClass + }; + } + + if (object[fieldName] && schema.fields[fieldName].type === 'GeoPoint') { + object[fieldName] = { + __type: 'GeoPoint', + latitude: object[fieldName].y, + longitude: object[fieldName].x + }; + } + + if (object[fieldName] && schema.fields[fieldName].type === 'Polygon') { + let coords = object[fieldName]; + coords = coords.substr(2, coords.length - 4).split('),('); + coords = coords.map(point => { + return [parseFloat(point.split(',')[1]), parseFloat(point.split(',')[0])]; + }); + object[fieldName] = { + __type: 'Polygon', + coordinates: coords + }; + } + + if (object[fieldName] && schema.fields[fieldName].type === 'File') { + object[fieldName] = { + __type: 'File', + name: object[fieldName] + }; + } + }); //TODO: remove this reliance on the mongo format. DB adapter shouldn't know there is a difference between created at and any other date field. + + if (object.createdAt) { + object.createdAt = object.createdAt.toISOString(); + } + + if (object.updatedAt) { + object.updatedAt = object.updatedAt.toISOString(); + } + + if (object.expiresAt) { + object.expiresAt = { + __type: 'Date', + iso: object.expiresAt.toISOString() + }; + } + + if (object._email_verify_token_expires_at) { + object._email_verify_token_expires_at = { + __type: 'Date', + iso: object._email_verify_token_expires_at.toISOString() + }; + } + + if (object._account_lockout_expires_at) { + object._account_lockout_expires_at = { + __type: 'Date', + iso: object._account_lockout_expires_at.toISOString() + }; + } + + if (object._perishable_token_expires_at) { + object._perishable_token_expires_at = { + __type: 'Date', + iso: object._perishable_token_expires_at.toISOString() + }; + } + + if (object._password_changed_at) { + object._password_changed_at = { + __type: 'Date', + iso: object._password_changed_at.toISOString() + }; + } + + for (const fieldName in object) { + if (object[fieldName] === null) { + delete object[fieldName]; + } + + if (object[fieldName] instanceof Date) { + object[fieldName] = { + __type: 'Date', + iso: object[fieldName].toISOString() + }; + } + } + + return object; + } // Create a unique index. Unique indexes on nullable fields are not allowed. Since we don't + // currently know which fields are nullable and which aren't, we ignore that criteria. + // As such, we shouldn't expose this function to users of parse until we have an out-of-band + // Way of determining if a field is nullable. Undefined doesn't count against uniqueness, + // which is why we use sparse indexes. + + + async ensureUniqueness(className, schema, fieldNames) { + const constraintName = `${className}_unique_${fieldNames.sort().join('_')}`; + const constraintPatterns = fieldNames.map((fieldName, index) => `$${index + 3}:name`); + const qs = `CREATE UNIQUE INDEX IF NOT EXISTS $2:name ON $1:name(${constraintPatterns.join()})`; + return this._client.none(qs, [className, constraintName, ...fieldNames]).catch(error => { + if (error.code === PostgresDuplicateRelationError && error.message.includes(constraintName)) {// Index already exists. Ignore error. + } else if (error.code === PostgresUniqueIndexViolationError && error.message.includes(constraintName)) { + // Cast the error into the proper parse error + throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); + } else { + throw error; + } + }); + } // Executes a count. + + + async count(className, schema, query, readPreference, estimate = true) { + debug('count', className, query, readPreference, estimate); + const values = [className]; + const where = buildWhereClause({ + schema, + query, + index: 2, + caseInsensitive: false + }); + values.push(...where.values); + const wherePattern = where.pattern.length > 0 ? `WHERE ${where.pattern}` : ''; + let qs = ''; + + if (where.pattern.length > 0 || !estimate) { + qs = `SELECT count(*) FROM $1:name ${wherePattern}`; + } else { + qs = 'SELECT reltuples AS approximate_row_count FROM pg_class WHERE relname = $1'; + } + + return this._client.one(qs, values, a => { + if (a.approximate_row_count != null) { + return +a.approximate_row_count; + } else { + return +a.count; + } + }).catch(error => { + if (error.code !== PostgresRelationDoesNotExistError) { + throw error; + } + + return 0; + }); + } + + async distinct(className, schema, query, fieldName) { + debug('distinct', className, query); + let field = fieldName; + let column = fieldName; + const isNested = fieldName.indexOf('.') >= 0; + + if (isNested) { + field = transformDotFieldToComponents(fieldName).join('->'); + column = fieldName.split('.')[0]; + } + + const isArrayField = schema.fields && schema.fields[fieldName] && schema.fields[fieldName].type === 'Array'; + const isPointerField = schema.fields && schema.fields[fieldName] && schema.fields[fieldName].type === 'Pointer'; + const values = [field, column, className]; + const where = buildWhereClause({ + schema, + query, + index: 4, + caseInsensitive: false + }); + values.push(...where.values); + const wherePattern = where.pattern.length > 0 ? `WHERE ${where.pattern}` : ''; + const transformer = isArrayField ? 'jsonb_array_elements' : 'ON'; + let qs = `SELECT DISTINCT ${transformer}($1:name) $2:name FROM $3:name ${wherePattern}`; + + if (isNested) { + qs = `SELECT DISTINCT ${transformer}($1:raw) $2:raw FROM $3:name ${wherePattern}`; + } + + debug(qs, values); + return this._client.any(qs, values).catch(error => { + if (error.code === PostgresMissingColumnError) { + return []; + } + + throw error; + }).then(results => { + if (!isNested) { + results = results.filter(object => object[field] !== null); + return results.map(object => { + if (!isPointerField) { + return object[field]; + } + + return { + __type: 'Pointer', + className: schema.fields[fieldName].targetClass, + objectId: object[field] + }; + }); + } + + const child = fieldName.split('.')[1]; + return results.map(object => object[column][child]); + }).then(results => results.map(object => this.postgresObjectToParseObject(className, object, schema))); + } + + async aggregate(className, schema, pipeline, readPreference, hint, explain) { + debug('aggregate', className, pipeline, readPreference, hint, explain); + const values = [className]; + let index = 2; + let columns = []; + let countField = null; + let groupValues = null; + let wherePattern = ''; + let limitPattern = ''; + let skipPattern = ''; + let sortPattern = ''; + let groupPattern = ''; + + for (let i = 0; i < pipeline.length; i += 1) { + const stage = pipeline[i]; + + if (stage.$group) { + for (const field in stage.$group) { + const value = stage.$group[field]; + + if (value === null || value === undefined) { + continue; + } + + if (field === '_id' && typeof value === 'string' && value !== '') { + columns.push(`$${index}:name AS "objectId"`); + groupPattern = `GROUP BY $${index}:name`; + values.push(transformAggregateField(value)); + index += 1; + continue; + } + + if (field === '_id' && typeof value === 'object' && Object.keys(value).length !== 0) { + groupValues = value; + const groupByFields = []; + + for (const alias in value) { + if (typeof value[alias] === 'string' && value[alias]) { + const source = transformAggregateField(value[alias]); + + if (!groupByFields.includes(`"${source}"`)) { + groupByFields.push(`"${source}"`); + } + + values.push(source, alias); + columns.push(`$${index}:name AS $${index + 1}:name`); + index += 2; + } else { + const operation = Object.keys(value[alias])[0]; + const source = transformAggregateField(value[alias][operation]); + + if (mongoAggregateToPostgres[operation]) { + if (!groupByFields.includes(`"${source}"`)) { + groupByFields.push(`"${source}"`); + } + + columns.push(`EXTRACT(${mongoAggregateToPostgres[operation]} FROM $${index}:name AT TIME ZONE 'UTC') AS $${index + 1}:name`); + values.push(source, alias); + index += 2; + } + } + } + + groupPattern = `GROUP BY $${index}:raw`; + values.push(groupByFields.join()); + index += 1; + continue; + } + + if (typeof value === 'object') { + if (value.$sum) { + if (typeof value.$sum === 'string') { + columns.push(`SUM($${index}:name) AS $${index + 1}:name`); + values.push(transformAggregateField(value.$sum), field); + index += 2; + } else { + countField = field; + columns.push(`COUNT(*) AS $${index}:name`); + values.push(field); + index += 1; + } + } + + if (value.$max) { + columns.push(`MAX($${index}:name) AS $${index + 1}:name`); + values.push(transformAggregateField(value.$max), field); + index += 2; + } + + if (value.$min) { + columns.push(`MIN($${index}:name) AS $${index + 1}:name`); + values.push(transformAggregateField(value.$min), field); + index += 2; + } + + if (value.$avg) { + columns.push(`AVG($${index}:name) AS $${index + 1}:name`); + values.push(transformAggregateField(value.$avg), field); + index += 2; + } + } + } + } else { + columns.push('*'); + } + + if (stage.$project) { + if (columns.includes('*')) { + columns = []; + } + + for (const field in stage.$project) { + const value = stage.$project[field]; + + if (value === 1 || value === true) { + columns.push(`$${index}:name`); + values.push(field); + index += 1; + } + } + } + + if (stage.$match) { + const patterns = []; + const orOrAnd = Object.prototype.hasOwnProperty.call(stage.$match, '$or') ? ' OR ' : ' AND '; + + if (stage.$match.$or) { + const collapse = {}; + stage.$match.$or.forEach(element => { + for (const key in element) { + collapse[key] = element[key]; + } + }); + stage.$match = collapse; + } + + for (const field in stage.$match) { + const value = stage.$match[field]; + const matchPatterns = []; + Object.keys(ParseToPosgresComparator).forEach(cmp => { + if (value[cmp]) { + const pgComparator = ParseToPosgresComparator[cmp]; + matchPatterns.push(`$${index}:name ${pgComparator} $${index + 1}`); + values.push(field, toPostgresValue(value[cmp])); + index += 2; + } + }); + + if (matchPatterns.length > 0) { + patterns.push(`(${matchPatterns.join(' AND ')})`); + } + + if (schema.fields[field] && schema.fields[field].type && matchPatterns.length === 0) { + patterns.push(`$${index}:name = $${index + 1}`); + values.push(field, value); + index += 2; + } + } + + wherePattern = patterns.length > 0 ? `WHERE ${patterns.join(` ${orOrAnd} `)}` : ''; + } + + if (stage.$limit) { + limitPattern = `LIMIT $${index}`; + values.push(stage.$limit); + index += 1; + } + + if (stage.$skip) { + skipPattern = `OFFSET $${index}`; + values.push(stage.$skip); + index += 1; + } + + if (stage.$sort) { + const sort = stage.$sort; + const keys = Object.keys(sort); + const sorting = keys.map(key => { + const transformer = sort[key] === 1 ? 'ASC' : 'DESC'; + const order = `$${index}:name ${transformer}`; + index += 1; + return order; + }).join(); + values.push(...keys); + sortPattern = sort !== undefined && sorting.length > 0 ? `ORDER BY ${sorting}` : ''; + } + } + + if (groupPattern) { + columns.forEach((e, i, a) => { + if (e && e.trim() === '*') { + a[i] = ''; + } + }); + } + + const originalQuery = `SELECT ${columns.filter(Boolean).join()} FROM $1:name ${wherePattern} ${skipPattern} ${groupPattern} ${sortPattern} ${limitPattern}`; + const qs = explain ? this.createExplainableQuery(originalQuery) : originalQuery; + debug(qs, values); + return this._client.any(qs, values).then(a => { + if (explain) { + return a; + } + + const results = a.map(object => this.postgresObjectToParseObject(className, object, schema)); + results.forEach(result => { + if (!Object.prototype.hasOwnProperty.call(result, 'objectId')) { + result.objectId = null; + } + + if (groupValues) { + result.objectId = {}; + + for (const key in groupValues) { + result.objectId[key] = result[key]; + delete result[key]; + } + } + + if (countField) { + result[countField] = parseInt(result[countField], 10); + } + }); + return results; + }); + } + + async performInitialization({ + VolatileClassesSchemas + }) { + // TODO: This method needs to be rewritten to make proper use of connections (@vitaly-t) + debug('performInitialization'); + const promises = VolatileClassesSchemas.map(schema => { + return this.createTable(schema.className, schema).catch(err => { + if (err.code === PostgresDuplicateRelationError || err.code === _node.default.Error.INVALID_CLASS_NAME) { + return Promise.resolve(); + } + + throw err; + }).then(() => this.schemaUpgrade(schema.className, schema)); + }); + return Promise.all(promises).then(() => { + return this._client.tx('perform-initialization', async t => { + await t.none(_sql.default.misc.jsonObjectSetKeys); + await t.none(_sql.default.array.add); + await t.none(_sql.default.array.addUnique); + await t.none(_sql.default.array.remove); + await t.none(_sql.default.array.containsAll); + await t.none(_sql.default.array.containsAllRegex); + await t.none(_sql.default.array.contains); + return t.ctx; + }); + }).then(ctx => { + debug(`initializationDone in ${ctx.duration}`); + }).catch(error => { + /* eslint-disable no-console */ + console.error(error); + }); + } + + async createIndexes(className, indexes, conn) { + return (conn || this._client).tx(t => t.batch(indexes.map(i => { + return t.none('CREATE INDEX IF NOT EXISTS $1:name ON $2:name ($3:name)', [i.name, className, i.key]); + }))); + } + + async createIndexesIfNeeded(className, fieldName, type, conn) { + await (conn || this._client).none('CREATE INDEX IF NOT EXISTS $1:name ON $2:name ($3:name)', [fieldName, className, type]); + } + + async dropIndexes(className, indexes, conn) { + const queries = indexes.map(i => ({ + query: 'DROP INDEX $1:name', + values: i + })); + await (conn || this._client).tx(t => t.none(this._pgp.helpers.concat(queries))); + } + + async getIndexes(className) { + const qs = 'SELECT * FROM pg_indexes WHERE tablename = ${className}'; + return this._client.any(qs, { + className + }); + } + + async updateSchemaWithIndexes() { + return Promise.resolve(); + } // Used for testing purposes + + + async updateEstimatedCount(className) { + return this._client.none('ANALYZE $1:name', [className]); + } + + async createTransactionalSession() { + return new Promise(resolve => { + const transactionalSession = {}; + transactionalSession.result = this._client.tx(t => { + transactionalSession.t = t; + transactionalSession.promise = new Promise(resolve => { + transactionalSession.resolve = resolve; + }); + transactionalSession.batch = []; + resolve(transactionalSession); + return transactionalSession.promise; + }); + }); + } + + commitTransactionalSession(transactionalSession) { + transactionalSession.resolve(transactionalSession.t.batch(transactionalSession.batch)); + return transactionalSession.result; + } + + abortTransactionalSession(transactionalSession) { + const result = transactionalSession.result.catch(); + transactionalSession.batch.push(Promise.reject()); + transactionalSession.resolve(transactionalSession.t.batch(transactionalSession.batch)); + return result; + } + + async ensureIndex(className, schema, fieldNames, indexName, caseInsensitive = false, options = {}) { + const conn = options.conn !== undefined ? options.conn : this._client; + const defaultIndexName = `parse_default_${fieldNames.sort().join('_')}`; + const indexNameOptions = indexName != null ? { + name: indexName + } : { + name: defaultIndexName + }; + const constraintPatterns = caseInsensitive ? fieldNames.map((fieldName, index) => `lower($${index + 3}:name) varchar_pattern_ops`) : fieldNames.map((fieldName, index) => `$${index + 3}:name`); + const qs = `CREATE INDEX IF NOT EXISTS $1:name ON $2:name (${constraintPatterns.join()})`; + await conn.none(qs, [indexNameOptions.name, className, ...fieldNames]).catch(error => { + if (error.code === PostgresDuplicateRelationError && error.message.includes(indexNameOptions.name)) {// Index already exists. Ignore error. + } else if (error.code === PostgresUniqueIndexViolationError && error.message.includes(indexNameOptions.name)) { + // Cast the error into the proper parse error + throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); + } else { + throw error; + } + }); + } + +} + +exports.PostgresStorageAdapter = PostgresStorageAdapter; + +function convertPolygonToSQL(polygon) { + if (polygon.length < 3) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, `Polygon must have at least 3 values`); + } + + if (polygon[0][0] !== polygon[polygon.length - 1][0] || polygon[0][1] !== polygon[polygon.length - 1][1]) { + polygon.push(polygon[0]); + } + + const unique = polygon.filter((item, index, ar) => { + let foundIndex = -1; + + for (let i = 0; i < ar.length; i += 1) { + const pt = ar[i]; + + if (pt[0] === item[0] && pt[1] === item[1]) { + foundIndex = i; + break; + } + } + + return foundIndex === index; + }); + + if (unique.length < 3) { + throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'GeoJSON: Loop must have at least 3 different vertices'); + } + + const points = polygon.map(point => { + _node.default.GeoPoint._validate(parseFloat(point[1]), parseFloat(point[0])); + + return `(${point[1]}, ${point[0]})`; + }).join(', '); + return `(${points})`; +} + +function removeWhiteSpace(regex) { + if (!regex.endsWith('\n')) { + regex += '\n'; + } // remove non escaped comments + + + return regex.replace(/([^\\])#.*\n/gim, '$1') // remove lines starting with a comment + .replace(/^#.*\n/gim, '') // remove non escaped whitespace + .replace(/([^\\])\s+/gim, '$1') // remove whitespace at the beginning of a line + .replace(/^\s+/, '').trim(); +} + +function processRegexPattern(s) { + if (s && s.startsWith('^')) { + // regex for startsWith + return '^' + literalizeRegexPart(s.slice(1)); + } else if (s && s.endsWith('$')) { + // regex for endsWith + return literalizeRegexPart(s.slice(0, s.length - 1)) + '$'; + } // regex for contains + + + return literalizeRegexPart(s); +} + +function isStartsWithRegex(value) { + if (!value || typeof value !== 'string' || !value.startsWith('^')) { + return false; + } + + const matches = value.match(/\^\\Q.*\\E/); + return !!matches; +} + +function isAllValuesRegexOrNone(values) { + if (!values || !Array.isArray(values) || values.length === 0) { + return true; + } + + const firstValuesIsRegex = isStartsWithRegex(values[0].$regex); + + if (values.length === 1) { + return firstValuesIsRegex; + } + + for (let i = 1, length = values.length; i < length; ++i) { + if (firstValuesIsRegex !== isStartsWithRegex(values[i].$regex)) { + return false; + } + } + + return true; +} + +function isAnyValueRegexStartsWith(values) { + return values.some(function (value) { + return isStartsWithRegex(value.$regex); + }); +} + +function createLiteralRegex(remaining) { + return remaining.split('').map(c => { + const regex = RegExp('[0-9 ]|\\p{L}', 'u'); // Support all unicode letter chars + + if (c.match(regex) !== null) { + // don't escape alphanumeric characters + return c; + } // escape everything else (single quotes with single quotes, everything else with a backslash) + + + return c === `'` ? `''` : `\\${c}`; + }).join(''); +} + +function literalizeRegexPart(s) { + const matcher1 = /\\Q((?!\\E).*)\\E$/; + const result1 = s.match(matcher1); + + if (result1 && result1.length > 1 && result1.index > -1) { + // process regex that has a beginning and an end specified for the literal text + const prefix = s.substr(0, result1.index); + const remaining = result1[1]; + return literalizeRegexPart(prefix) + createLiteralRegex(remaining); + } // process regex that has a beginning specified for the literal text + + + const matcher2 = /\\Q((?!\\E).*)$/; + const result2 = s.match(matcher2); + + if (result2 && result2.length > 1 && result2.index > -1) { + const prefix = s.substr(0, result2.index); + const remaining = result2[1]; + return literalizeRegexPart(prefix) + createLiteralRegex(remaining); + } // remove all instances of \Q and \E from the remaining text & escape single quotes + + + return s.replace(/([^\\])(\\E)/, '$1').replace(/([^\\])(\\Q)/, '$1').replace(/^\\E/, '').replace(/^\\Q/, '').replace(/([^'])'/, `$1''`).replace(/^'([^'])/, `''$1`); +} + +var GeoPointCoder = { + isValidJSON(value) { + return typeof value === 'object' && value !== null && value.__type === 'GeoPoint'; + } + +}; +var _default = PostgresStorageAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL1Bvc3RncmVzL1Bvc3RncmVzU3RvcmFnZUFkYXB0ZXIuanMiXSwibmFtZXMiOlsiUG9zdGdyZXNSZWxhdGlvbkRvZXNOb3RFeGlzdEVycm9yIiwiUG9zdGdyZXNEdXBsaWNhdGVSZWxhdGlvbkVycm9yIiwiUG9zdGdyZXNEdXBsaWNhdGVDb2x1bW5FcnJvciIsIlBvc3RncmVzTWlzc2luZ0NvbHVtbkVycm9yIiwiUG9zdGdyZXNEdXBsaWNhdGVPYmplY3RFcnJvciIsIlBvc3RncmVzVW5pcXVlSW5kZXhWaW9sYXRpb25FcnJvciIsImxvZ2dlciIsInJlcXVpcmUiLCJkZWJ1ZyIsImFyZ3MiLCJhcmd1bWVudHMiLCJjb25jYXQiLCJzbGljZSIsImxlbmd0aCIsImxvZyIsImdldExvZ2dlciIsImFwcGx5IiwicGFyc2VUeXBlVG9Qb3N0Z3Jlc1R5cGUiLCJ0eXBlIiwiY29udGVudHMiLCJKU09OIiwic3RyaW5naWZ5IiwiUGFyc2VUb1Bvc2dyZXNDb21wYXJhdG9yIiwiJGd0IiwiJGx0IiwiJGd0ZSIsIiRsdGUiLCJtb25nb0FnZ3JlZ2F0ZVRvUG9zdGdyZXMiLCIkZGF5T2ZNb250aCIsIiRkYXlPZldlZWsiLCIkZGF5T2ZZZWFyIiwiJGlzb0RheU9mV2VlayIsIiRpc29XZWVrWWVhciIsIiRob3VyIiwiJG1pbnV0ZSIsIiRzZWNvbmQiLCIkbWlsbGlzZWNvbmQiLCIkbW9udGgiLCIkd2VlayIsIiR5ZWFyIiwidG9Qb3N0Z3Jlc1ZhbHVlIiwidmFsdWUiLCJfX3R5cGUiLCJpc28iLCJuYW1lIiwidHJhbnNmb3JtVmFsdWUiLCJvYmplY3RJZCIsImVtcHR5Q0xQUyIsIk9iamVjdCIsImZyZWV6ZSIsImZpbmQiLCJnZXQiLCJjb3VudCIsImNyZWF0ZSIsInVwZGF0ZSIsImRlbGV0ZSIsImFkZEZpZWxkIiwicHJvdGVjdGVkRmllbGRzIiwiZGVmYXVsdENMUFMiLCJ0b1BhcnNlU2NoZW1hIiwic2NoZW1hIiwiY2xhc3NOYW1lIiwiZmllbGRzIiwiX2hhc2hlZF9wYXNzd29yZCIsIl93cGVybSIsIl9ycGVybSIsImNscHMiLCJjbGFzc0xldmVsUGVybWlzc2lvbnMiLCJpbmRleGVzIiwidG9Qb3N0Z3Jlc1NjaGVtYSIsIl9wYXNzd29yZF9oaXN0b3J5IiwiaGFuZGxlRG90RmllbGRzIiwib2JqZWN0Iiwia2V5cyIsImZvckVhY2giLCJmaWVsZE5hbWUiLCJpbmRleE9mIiwiY29tcG9uZW50cyIsInNwbGl0IiwiZmlyc3QiLCJzaGlmdCIsImN1cnJlbnRPYmoiLCJuZXh0IiwiX19vcCIsInVuZGVmaW5lZCIsInRyYW5zZm9ybURvdEZpZWxkVG9Db21wb25lbnRzIiwibWFwIiwiY21wdCIsImluZGV4IiwidHJhbnNmb3JtRG90RmllbGQiLCJqb2luIiwidHJhbnNmb3JtQWdncmVnYXRlRmllbGQiLCJzdWJzdHIiLCJ2YWxpZGF0ZUtleXMiLCJrZXkiLCJpbmNsdWRlcyIsIlBhcnNlIiwiRXJyb3IiLCJJTlZBTElEX05FU1RFRF9LRVkiLCJqb2luVGFibGVzRm9yU2NoZW1hIiwibGlzdCIsImZpZWxkIiwicHVzaCIsImJ1aWxkV2hlcmVDbGF1c2UiLCJxdWVyeSIsImNhc2VJbnNlbnNpdGl2ZSIsInBhdHRlcm5zIiwidmFsdWVzIiwic29ydHMiLCJpc0FycmF5RmllbGQiLCJpbml0aWFsUGF0dGVybnNMZW5ndGgiLCJmaWVsZFZhbHVlIiwiJGV4aXN0cyIsImF1dGhEYXRhTWF0Y2giLCJtYXRjaCIsIiRpbiIsIiRyZWdleCIsIk1BWF9JTlRfUExVU19PTkUiLCJjbGF1c2VzIiwiY2xhdXNlVmFsdWVzIiwic3ViUXVlcnkiLCJjbGF1c2UiLCJwYXR0ZXJuIiwib3JPckFuZCIsIm5vdCIsIiRuZSIsImNvbnN0cmFpbnRGaWVsZE5hbWUiLCJwb2ludCIsImxvbmdpdHVkZSIsImxhdGl0dWRlIiwiJGVxIiwiaXNJbk9yTmluIiwiQXJyYXkiLCJpc0FycmF5IiwiJG5pbiIsImluUGF0dGVybnMiLCJhbGxvd051bGwiLCJsaXN0RWxlbSIsImxpc3RJbmRleCIsImNyZWF0ZUNvbnN0cmFpbnQiLCJiYXNlQXJyYXkiLCJub3RJbiIsIl8iLCJmbGF0TWFwIiwiZWx0IiwiSU5WQUxJRF9KU09OIiwiJGFsbCIsImlzQW55VmFsdWVSZWdleFN0YXJ0c1dpdGgiLCJpc0FsbFZhbHVlc1JlZ2V4T3JOb25lIiwiaSIsInByb2Nlc3NSZWdleFBhdHRlcm4iLCJzdWJzdHJpbmciLCIkY29udGFpbmVkQnkiLCJhcnIiLCIkdGV4dCIsInNlYXJjaCIsIiRzZWFyY2giLCJsYW5ndWFnZSIsIiR0ZXJtIiwiJGxhbmd1YWdlIiwiJGNhc2VTZW5zaXRpdmUiLCIkZGlhY3JpdGljU2Vuc2l0aXZlIiwiJG5lYXJTcGhlcmUiLCJkaXN0YW5jZSIsIiRtYXhEaXN0YW5jZSIsImRpc3RhbmNlSW5LTSIsIiR3aXRoaW4iLCIkYm94IiwiYm94IiwibGVmdCIsImJvdHRvbSIsInJpZ2h0IiwidG9wIiwiJGdlb1dpdGhpbiIsIiRjZW50ZXJTcGhlcmUiLCJjZW50ZXJTcGhlcmUiLCJHZW9Qb2ludCIsIkdlb1BvaW50Q29kZXIiLCJpc1ZhbGlkSlNPTiIsIl92YWxpZGF0ZSIsImlzTmFOIiwiJHBvbHlnb24iLCJwb2x5Z29uIiwicG9pbnRzIiwiY29vcmRpbmF0ZXMiLCIkZ2VvSW50ZXJzZWN0cyIsIiRwb2ludCIsInJlZ2V4Iiwib3BlcmF0b3IiLCJvcHRzIiwiJG9wdGlvbnMiLCJyZW1vdmVXaGl0ZVNwYWNlIiwiY29udmVydFBvbHlnb25Ub1NRTCIsImNtcCIsInBnQ29tcGFyYXRvciIsInBvc3RncmVzVmFsdWUiLCJjYXN0VHlwZSIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJQb3N0Z3Jlc1N0b3JhZ2VBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJ1cmkiLCJjb2xsZWN0aW9uUHJlZml4IiwiZGF0YWJhc2VPcHRpb25zIiwiX2NvbGxlY3Rpb25QcmVmaXgiLCJjbGllbnQiLCJwZ3AiLCJfY2xpZW50IiwiX3BncCIsImNhblNvcnRPbkpvaW5UYWJsZXMiLCJjcmVhdGVFeHBsYWluYWJsZVF1ZXJ5IiwiYW5hbHl6ZSIsImhhbmRsZVNodXRkb3duIiwiJHBvb2wiLCJlbmQiLCJfZW5zdXJlU2NoZW1hQ29sbGVjdGlvbkV4aXN0cyIsImNvbm4iLCJub25lIiwiY2F0Y2giLCJlcnJvciIsImNvZGUiLCJjbGFzc0V4aXN0cyIsIm9uZSIsImEiLCJleGlzdHMiLCJzZXRDbGFzc0xldmVsUGVybWlzc2lvbnMiLCJDTFBzIiwic2VsZiIsInRhc2siLCJ0Iiwic2V0SW5kZXhlc1dpdGhTY2hlbWFGb3JtYXQiLCJzdWJtaXR0ZWRJbmRleGVzIiwiZXhpc3RpbmdJbmRleGVzIiwiUHJvbWlzZSIsInJlc29sdmUiLCJfaWRfIiwiX2lkIiwiZGVsZXRlZEluZGV4ZXMiLCJpbnNlcnRlZEluZGV4ZXMiLCJJTlZBTElEX1FVRVJZIiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwidHgiLCJjcmVhdGVJbmRleGVzIiwiZHJvcEluZGV4ZXMiLCJjcmVhdGVDbGFzcyIsImNyZWF0ZVRhYmxlIiwiZXJyIiwiZGV0YWlsIiwiRFVQTElDQVRFX1ZBTFVFIiwidmFsdWVzQXJyYXkiLCJwYXR0ZXJuc0FycmF5IiwiYXNzaWduIiwiX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0IiwiX2VtYWlsX3ZlcmlmeV90b2tlbiIsIl9hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCIsIl9mYWlsZWRfbG9naW5fY291bnQiLCJfcGVyaXNoYWJsZV90b2tlbiIsIl9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQiLCJfcGFzc3dvcmRfY2hhbmdlZF9hdCIsInJlbGF0aW9ucyIsInBhcnNlVHlwZSIsInFzIiwiYmF0Y2giLCJqb2luVGFibGUiLCJzY2hlbWFVcGdyYWRlIiwiY29sdW1ucyIsImNvbHVtbl9uYW1lIiwibmV3Q29sdW1ucyIsImZpbHRlciIsIml0ZW0iLCJhZGRGaWVsZElmTm90RXhpc3RzIiwicG9zdGdyZXNUeXBlIiwicmVzdWx0IiwiYW55IiwicGF0aCIsImRlbGV0ZUNsYXNzIiwib3BlcmF0aW9ucyIsImhlbHBlcnMiLCJ0aGVuIiwiZGVsZXRlQWxsQ2xhc3NlcyIsIm5vdyIsIkRhdGUiLCJnZXRUaW1lIiwicmVzdWx0cyIsImpvaW5zIiwicmVkdWNlIiwiY2xhc3NlcyIsInF1ZXJpZXMiLCJkZWxldGVGaWVsZHMiLCJmaWVsZE5hbWVzIiwiaWR4IiwiZ2V0QWxsQ2xhc3NlcyIsInJvdyIsImdldENsYXNzIiwiY3JlYXRlT2JqZWN0IiwidHJhbnNhY3Rpb25hbFNlc3Npb24iLCJjb2x1bW5zQXJyYXkiLCJnZW9Qb2ludHMiLCJwcm92aWRlciIsInBvcCIsImluaXRpYWxWYWx1ZXMiLCJ2YWwiLCJ0ZXJtaW5hdGlvbiIsImdlb1BvaW50c0luamVjdHMiLCJsIiwiY29sdW1uc1BhdHRlcm4iLCJjb2wiLCJ2YWx1ZXNQYXR0ZXJuIiwicHJvbWlzZSIsIm9wcyIsInVuZGVybHlpbmdFcnJvciIsImNvbnN0cmFpbnQiLCJtYXRjaGVzIiwidXNlckluZm8iLCJkdXBsaWNhdGVkX2ZpZWxkIiwiZGVsZXRlT2JqZWN0c0J5UXVlcnkiLCJ3aGVyZSIsIk9CSkVDVF9OT1RfRk9VTkQiLCJmaW5kT25lQW5kVXBkYXRlIiwidXBkYXRlT2JqZWN0c0J5UXVlcnkiLCJ1cGRhdGVQYXR0ZXJucyIsIm9yaWdpbmFsVXBkYXRlIiwiZG90Tm90YXRpb25PcHRpb25zIiwiZ2VuZXJhdGUiLCJqc29uYiIsImxhc3RLZXkiLCJmaWVsZE5hbWVJbmRleCIsInN0ciIsImFtb3VudCIsIm9iamVjdHMiLCJrZXlzVG9JbmNyZW1lbnQiLCJrIiwiaW5jcmVtZW50UGF0dGVybnMiLCJjIiwia2V5c1RvRGVsZXRlIiwiZGVsZXRlUGF0dGVybnMiLCJwIiwidXBkYXRlT2JqZWN0IiwiZXhwZWN0ZWRUeXBlIiwicmVqZWN0Iiwid2hlcmVDbGF1c2UiLCJ1cHNlcnRPbmVPYmplY3QiLCJjcmVhdGVWYWx1ZSIsInNraXAiLCJsaW1pdCIsInNvcnQiLCJleHBsYWluIiwiaGFzTGltaXQiLCJoYXNTa2lwIiwid2hlcmVQYXR0ZXJuIiwibGltaXRQYXR0ZXJuIiwic2tpcFBhdHRlcm4iLCJzb3J0UGF0dGVybiIsInNvcnRDb3B5Iiwic29ydGluZyIsInRyYW5zZm9ybUtleSIsIm1lbW8iLCJvcmlnaW5hbFF1ZXJ5IiwicG9zdGdyZXNPYmplY3RUb1BhcnNlT2JqZWN0IiwidGFyZ2V0Q2xhc3MiLCJ5IiwieCIsImNvb3JkcyIsInBhcnNlRmxvYXQiLCJjcmVhdGVkQXQiLCJ0b0lTT1N0cmluZyIsInVwZGF0ZWRBdCIsImV4cGlyZXNBdCIsImVuc3VyZVVuaXF1ZW5lc3MiLCJjb25zdHJhaW50TmFtZSIsImNvbnN0cmFpbnRQYXR0ZXJucyIsIm1lc3NhZ2UiLCJyZWFkUHJlZmVyZW5jZSIsImVzdGltYXRlIiwiYXBwcm94aW1hdGVfcm93X2NvdW50IiwiZGlzdGluY3QiLCJjb2x1bW4iLCJpc05lc3RlZCIsImlzUG9pbnRlckZpZWxkIiwidHJhbnNmb3JtZXIiLCJjaGlsZCIsImFnZ3JlZ2F0ZSIsInBpcGVsaW5lIiwiaGludCIsImNvdW50RmllbGQiLCJncm91cFZhbHVlcyIsImdyb3VwUGF0dGVybiIsInN0YWdlIiwiJGdyb3VwIiwiZ3JvdXBCeUZpZWxkcyIsImFsaWFzIiwic291cmNlIiwib3BlcmF0aW9uIiwiJHN1bSIsIiRtYXgiLCIkbWluIiwiJGF2ZyIsIiRwcm9qZWN0IiwiJG1hdGNoIiwiJG9yIiwiY29sbGFwc2UiLCJlbGVtZW50IiwibWF0Y2hQYXR0ZXJucyIsIiRsaW1pdCIsIiRza2lwIiwiJHNvcnQiLCJvcmRlciIsImUiLCJ0cmltIiwiQm9vbGVhbiIsInBhcnNlSW50IiwicGVyZm9ybUluaXRpYWxpemF0aW9uIiwiVm9sYXRpbGVDbGFzc2VzU2NoZW1hcyIsInByb21pc2VzIiwiSU5WQUxJRF9DTEFTU19OQU1FIiwiYWxsIiwic3FsIiwibWlzYyIsImpzb25PYmplY3RTZXRLZXlzIiwiYXJyYXkiLCJhZGQiLCJhZGRVbmlxdWUiLCJyZW1vdmUiLCJjb250YWluc0FsbCIsImNvbnRhaW5zQWxsUmVnZXgiLCJjb250YWlucyIsImN0eCIsImR1cmF0aW9uIiwiY29uc29sZSIsImNyZWF0ZUluZGV4ZXNJZk5lZWRlZCIsImdldEluZGV4ZXMiLCJ1cGRhdGVTY2hlbWFXaXRoSW5kZXhlcyIsInVwZGF0ZUVzdGltYXRlZENvdW50IiwiY3JlYXRlVHJhbnNhY3Rpb25hbFNlc3Npb24iLCJjb21taXRUcmFuc2FjdGlvbmFsU2Vzc2lvbiIsImFib3J0VHJhbnNhY3Rpb25hbFNlc3Npb24iLCJlbnN1cmVJbmRleCIsImluZGV4TmFtZSIsIm9wdGlvbnMiLCJkZWZhdWx0SW5kZXhOYW1lIiwiaW5kZXhOYW1lT3B0aW9ucyIsInVuaXF1ZSIsImFyIiwiZm91bmRJbmRleCIsInB0IiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiZW5kc1dpdGgiLCJyZXBsYWNlIiwicyIsInN0YXJ0c1dpdGgiLCJsaXRlcmFsaXplUmVnZXhQYXJ0IiwiaXNTdGFydHNXaXRoUmVnZXgiLCJmaXJzdFZhbHVlc0lzUmVnZXgiLCJzb21lIiwiY3JlYXRlTGl0ZXJhbFJlZ2V4IiwicmVtYWluaW5nIiwiUmVnRXhwIiwibWF0Y2hlcjEiLCJyZXN1bHQxIiwicHJlZml4IiwibWF0Y2hlcjIiLCJyZXN1bHQyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7O0FBRUE7O0FBRUE7O0FBQ0E7O0FBZ0JBOzs7Ozs7Ozs7O0FBZEEsTUFBTUEsaUNBQWlDLEdBQUcsT0FBMUM7QUFDQSxNQUFNQyw4QkFBOEIsR0FBRyxPQUF2QztBQUNBLE1BQU1DLDRCQUE0QixHQUFHLE9BQXJDO0FBQ0EsTUFBTUMsMEJBQTBCLEdBQUcsT0FBbkM7QUFDQSxNQUFNQyw0QkFBNEIsR0FBRyxPQUFyQztBQUNBLE1BQU1DLGlDQUFpQyxHQUFHLE9BQTFDOztBQUNBLE1BQU1DLE1BQU0sR0FBR0MsT0FBTyxDQUFDLGlCQUFELENBQXRCOztBQUVBLE1BQU1DLEtBQUssR0FBRyxVQUFVLEdBQUdDLElBQWIsRUFBd0I7QUFDcENBLEVBQUFBLElBQUksR0FBRyxD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cUMsQ0FxQnRDOzs7QUFDQSxTQUFPUCxDQUFDLENBQ0xELE9BREksQ0FDSSxjQURKLEVBQ29CLElBRHBCLEVBRUpBLE9BRkksQ0FFSSxjQUZKLEVBRW9CLElBRnBCLEVBR0pBLE9BSEksQ0FHSSxNQUhKLEVBR1ksRUFIWixFQUlKQSxPQUpJLENBSUksTUFKSixFQUlZLEVBSlosRUFLSkEsT0FMSSxDQUtJLFNBTEosRUFLZ0IsTUFMaEIsRUFNSkEsT0FOSSxDQU1JLFVBTkosRUFNaUIsTUFOakIsQ0FBUDtBQU9EOztBQUVELElBQUkvUSxhQUFhLEdBQUc7QUFDbEJDLEVBQUFBLFdBQVcsQ0FBQ3pJLEtBQUQsRUFBUTtBQUNqQixXQUFPLE9BQU9BLEtBQVAsS0FBaUIsUUFBakIsSUFBNkJBLEtBQUssS0FBSyxJQUF2QyxJQUErQ0EsS0FBSyxDQUFDQyxNQUFOLEtBQWlCLFVBQXZFO0FBQ0Q7O0FBSGlCLENBQXBCO2VBTWU0SixzQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG5pbXBvcnQgeyBjcmVhdGVDbGllbnQgfSBmcm9tICcuL1Bvc3RncmVzQ2xpZW50Jztcbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHNxbCBmcm9tICcuL3NxbCc7XG5cbmNvbnN0IFBvc3RncmVzUmVsYXRpb25Eb2VzTm90RXhpc3RFcnJvciA9ICc0MlAwMSc7XG5jb25zdCBQb3N0Z3Jlc0R1cGxpY2F0ZVJlbGF0aW9uRXJyb3IgPSAnNDJQMDcnO1xuY29uc3QgUG9zdGdyZXNEdXBsaWNhdGVDb2x1bW5FcnJvciA9ICc0MjcwMSc7XG5jb25zdCBQb3N0Z3Jlc01pc3NpbmdDb2x1bW5FcnJvciA9ICc0MjcwMyc7XG5jb25zdCBQb3N0Z3Jlc0R1cGxpY2F0ZU9iamVjdEVycm9yID0gJzQyNzEwJztcbmNvbnN0IFBvc3RncmVzVW5pcXVlSW5kZXhWaW9sYXRpb25FcnJvciA9ICcyMzUwNSc7XG5jb25zdCBsb2dnZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9sb2dnZXInKTtcblxuY29uc3QgZGVidWcgPSBmdW5jdGlvbiAoLi4uYXJnczogYW55KSB7XG4gIGFyZ3MgPSBbJ1BHOiAnICsgYXJndW1lbnRzWzBdXS5jb25jYXQoYXJncy5zbGljZSgxLCBhcmdzLmxlbmd0aCkpO1xuICBjb25zdCBsb2cgPSBsb2dnZXIuZ2V0TG9nZ2VyKCk7XG4gIGxvZy5kZWJ1Zy5hcHBseShsb2csIGFyZ3MpO1xufTtcblxuaW1wb3J0IHsgU3RvcmFnZUFkYXB0ZXIgfSBmcm9tICcuLi9TdG9yYWdlQWRhcHRlcic7XG5pbXBvcnQgdHlwZSB7IFNjaGVtYVR5cGUsIFF1ZXJ5VHlwZSwgUXVlcnlPcHRpb25zIH0gZnJvbSAnLi4vU3RvcmFnZUFkYXB0ZXInO1xuXG5jb25zdCBwYXJzZVR5cGVUb1Bvc3RncmVzVHlwZSA9IHR5cGUgPT4ge1xuICBzd2l0Y2ggKHR5cGUudHlwZSkge1xuICAgIGNhc2UgJ1N0cmluZyc6XG4gICAgICByZXR1cm4gJ3RleHQnO1xuICAgIGNhc2UgJ0RhdGUnOlxuICAgICAgcmV0dXJuICd0aW1lc3RhbXAgd2l0aCB0aW1lIHpvbmUnO1xuICAgIGNhc2UgJ09iamVjdCc6XG4gICAgICByZXR1cm4gJ2pzb25iJztcbiAgICBjYXNlICdGaWxlJzpcbiAgICAgIHJldHVybiAndGV4dCc7XG4gICAgY2FzZSAnQm9vbGVhbic6XG4gICAgICByZXR1cm4gJ2Jvb2xlYW4nO1xuICAgIGNhc2UgJ1BvaW50ZXInOlxuICAgICAgcmV0dXJuICd0ZXh0JztcbiAgICBjYXNlICdOdW1iZXInOlxuICAgICAgcmV0dXJuICdkb3VibGUgcHJlY2lzaW9uJztcbiAgICBjYXNlICdHZW9Qb2ludCc6XG4gICAgICByZXR1cm4gJ3BvaW50JztcbiAgICBjYXNlICdCeXRlcyc6XG4gICAgICByZXR1cm4gJ2pzb25iJztcbiAgICBjYXNlICdQb2x5Z29uJzpcbiAgICAgIHJldHVybiAncG9seWdvbic7XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgaWYgKHR5cGUuY29udGVudHMgJiYgdHlwZS5jb250ZW50cy50eXBlID09PSAnU3RyaW5nJykge1xuICAgICAgICByZXR1cm4gJ3RleHRbXSc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gJ2pzb25iJztcbiAgICAgIH1cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgYG5vIHR5cGUgZm9yICR7SlNPTi5zdHJpbmdpZnkodHlwZSl9IHlldGA7XG4gIH1cbn07XG5cbmNvbnN0IFBhcnNlVG9Qb3NncmVzQ29tcGFyYXRvciA9IHtcbiAgJGd0OiAnPicsXG4gICRsdDogJzwnLFxuICAkZ3RlOiAnPj0nLFxuICAkbHRlOiAnPD0nLFxufTtcblxuY29uc3QgbW9uZ29BZ2dyZWdhdGVUb1Bvc3RncmVzID0ge1xuICAkZGF5T2ZNb250aDogJ0RBWScsXG4gICRkYXlPZldlZWs6ICdET1cnLFxuICAkZGF5T2ZZZWFyOiAnRE9ZJyxcbiAgJGlzb0RheU9mV2VlazogJ0lTT0RPVycsXG4gICRpc29XZWVrWWVhcjogJ0lTT1lFQVInLFxuICAkaG91cjogJ0hPVVInLFxuICAkbWludXRlOiAnTUlOVVRFJyxcbiAgJHNlY29uZDogJ1NFQ09ORCcsXG4gICRtaWxsaXNlY29uZDogJ01JTExJU0VDT05EUycsXG4gICRtb250aDogJ01PTlRIJyxcbiAgJHdlZWs6ICdXRUVLJyxcbiAgJHllYXI6ICdZRUFSJyxcbn07XG5cbmNvbnN0IHRvUG9zdGdyZXNWYWx1ZSA9IHZhbHVlID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICBpZiAodmFsdWUuX190eXBlID09PSAnRGF0ZScpIHtcbiAgICAgIHJldHVybiB2YWx1ZS5pc287XG4gICAgfVxuICAgIGlmICh2YWx1ZS5fX3R5cGUgPT09ICdGaWxlJykge1xuICAgICAgcmV0dXJuIHZhbHVlLm5hbWU7XG4gICAgfVxuICB9XG4gIHJldHVybiB2YWx1ZTtcbn07XG5cbmNvbnN0IHRyYW5zZm9ybVZhbHVlID0gdmFsdWUgPT4ge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZS5fX3R5cGUgPT09ICdQb2ludGVyJykge1xuICAgIHJldHVybiB2YWx1ZS5vYmplY3RJZDtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59O1xuXG4vLyBEdXBsaWNhdGUgZnJvbSB0aGVuIG1vbmdvIGFkYXB0ZXIuLi5cbmNvbnN0IGVtcHR5Q0xQUyA9IE9iamVjdC5mcmVlemUoe1xuICBmaW5kOiB7fSxcbiAgZ2V0OiB7fSxcbiAgY291bnQ6IHt9LFxuICBjcmVhdGU6IHt9LFxuICB1cGRhdGU6IHt9LFxuICBkZWxldGU6IHt9LFxuICBhZGRGaWVsZDoge30sXG4gIHByb3RlY3RlZEZpZWxkczoge30sXG59KTtcblxuY29uc3QgZGVmYXVsdENMUFMgPSBPYmplY3QuZnJlZXplKHtcbiAgZmluZDogeyAnKic6IHRydWUgfSxcbiAgZ2V0OiB7ICcqJzogdHJ1ZSB9LFxuICBjb3VudDogeyAnKic6IHRydWUgfSxcbiAgY3JlYXRlOiB7ICcqJzogdHJ1ZSB9LFxuICB1cGRhdGU6IHsgJyonOiB0cnVlIH0sXG4gIGRlbGV0ZTogeyAnKic6IHRydWUgfSxcbiAgYWRkRmllbGQ6IHsgJyonOiB0cnVlIH0sXG4gIHByb3RlY3RlZEZpZWxkczogeyAnKic6IFtdIH0sXG59KTtcblxuY29uc3QgdG9QYXJzZVNjaGVtYSA9IHNjaGVtYSA9PiB7XG4gIGlmIChzY2hlbWEuY2xhc3NOYW1lID09PSAnX1VzZXInKSB7XG4gICAgZGVsZXRlIHNjaGVtYS5maWVsZHMuX2hhc2hlZF9wYXNzd29yZDtcbiAgfVxuICBpZiAoc2NoZW1hLmZpZWxkcykge1xuICAgIGRlbGV0ZSBzY2hlbWEuZmllbGRzLl93cGVybTtcbiAgICBkZWxldGUgc2NoZW1hLmZpZWxkcy5fcnBlcm07XG4gIH1cbiAgbGV0IGNscHMgPSBkZWZhdWx0Q0xQUztcbiAgaWYgKHNjaGVtYS5jbGFzc0xldmVsUGVybWlzc2lvbnMpIHtcbiAgICBjbHBzID0geyAuLi5lbXB0eUNMUFMsIC4uLnNjaGVtYS5jbGFzc0xldmVsUGVybWlzc2lvbnMgfTtcbiAgfVxuICBsZXQgaW5kZXhlcyA9IHt9O1xuICBpZiAoc2NoZW1hLmluZGV4ZXMpIHtcbiAgICBpbmRleGVzID0geyAuLi5zY2hlbWEuaW5kZXhlcyB9O1xuICB9XG4gIHJldHVybiB7XG4gICAgY2xhc3NOYW1lOiBzY2hlbWEuY2xhc3NOYW1lLFxuICAgIGZpZWxkczogc2NoZW1hLmZpZWxkcyxcbiAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IGNscHMsXG4gICAgaW5kZXhlcyxcbiAgfTtcbn07XG5cbmNvbnN0IHRvUG9zdGdyZXNTY2hlbWEgPSBzY2hlbWEgPT4ge1xuICBpZiAoIXNjaGVtYSkge1xuICAgIHJldHVybiBzY2hlbWE7XG4gIH1cbiAgc2NoZW1hLmZpZWxkcyA9IHNjaGVtYS5maWVsZHMgfHwge307XG4gIHNjaGVtYS5maWVsZHMuX3dwZXJtID0geyB0eXBlOiAnQXJyYXknLCBjb250ZW50czogeyB0eXBlOiAnU3RyaW5nJyB9IH07XG4gIHNjaGVtYS5maWVsZHMuX3JwZXJtID0geyB0eXBlOiAnQXJyYXknLCBjb250ZW50czogeyB0eXBlOiAnU3RyaW5nJyB9IH07XG4gIGlmIChzY2hlbWEuY2xhc3NOYW1lID09PSAnX1VzZXInKSB7XG4gICAgc2NoZW1hLmZpZWxkcy5faGFzaGVkX3Bhc3N3b3JkID0geyB0eXBlOiAnU3RyaW5nJyB9O1xuICAgIHNjaGVtYS5maWVsZHMuX3Bhc3N3b3JkX2hpc3RvcnkgPSB7IHR5cGU6ICdBcnJheScgfTtcbiAgfVxuICByZXR1cm4gc2NoZW1hO1xufTtcblxuY29uc3QgaGFuZGxlRG90RmllbGRzID0gb2JqZWN0ID0+IHtcbiAgT2JqZWN0LmtleXMob2JqZWN0KS5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPiAtMSkge1xuICAgICAgY29uc3QgY29tcG9uZW50cyA9IGZpZWxkTmFtZS5zcGxpdCgnLicpO1xuICAgICAgY29uc3QgZmlyc3QgPSBjb21wb25lbnRzLnNoaWZ0KCk7XG4gICAgICBvYmplY3RbZmlyc3RdID0gb2JqZWN0W2ZpcnN0XSB8fCB7fTtcbiAgICAgIGxldCBjdXJyZW50T2JqID0gb2JqZWN0W2ZpcnN0XTtcbiAgICAgIGxldCBuZXh0O1xuICAgICAgbGV0IHZhbHVlID0gb2JqZWN0W2ZpZWxkTmFtZV07XG4gICAgICBpZiAodmFsdWUgJiYgdmFsdWUuX19vcCA9PT0gJ0RlbGV0ZScpIHtcbiAgICAgICAgdmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25kLWFzc2lnbiAqL1xuICAgICAgd2hpbGUgKChuZXh0ID0gY29tcG9uZW50cy5zaGlmdCgpKSkge1xuICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLWNvbmQtYXNzaWduICovXG4gICAgICAgIGN1cnJlbnRPYmpbbmV4dF0gPSBjdXJyZW50T2JqW25leHRdIHx8IHt9O1xuICAgICAgICBpZiAoY29tcG9uZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICBjdXJyZW50T2JqW25leHRdID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudE9iaiA9IGN1cnJlbnRPYmpbbmV4dF07XG4gICAgICB9XG4gICAgICBkZWxldGUgb2JqZWN0W2ZpZWxkTmFtZV07XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIG9iamVjdDtcbn07XG5cbmNvbnN0IHRyYW5zZm9ybURvdEZpZWxkVG9Db21wb25lbnRzID0gZmllbGROYW1lID0+IHtcbiAgcmV0dXJuIGZpZWxkTmFtZS5zcGxpdCgnLicpLm1hcCgoY21wdCwgaW5kZXgpID0+IHtcbiAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgIHJldHVybiBgXCIke2NtcHR9XCJgO1xuICAgIH1cbiAgICByZXR1cm4gYCcke2NtcHR9J2A7XG4gIH0pO1xufTtcblxuY29uc3QgdHJhbnNmb3JtRG90RmllbGQgPSBmaWVsZE5hbWUgPT4ge1xuICBpZiAoZmllbGROYW1lLmluZGV4T2YoJy4nKSA9PT0gLTEpIHtcbiAgICByZXR1cm4gYFwiJHtmaWVsZE5hbWV9XCJgO1xuICB9XG4gIGNvbnN0IGNvbXBvbmVudHMgPSB0cmFuc2Zvcm1Eb3RGaWVsZFRvQ29tcG9uZW50cyhmaWVsZE5hbWUpO1xuICBsZXQgbmFtZSA9IGNvbXBvbmVudHMuc2xpY2UoMCwgY29tcG9uZW50cy5sZW5ndGggLSAxKS5qb2luKCctPicpO1xuICBuYW1lICs9ICctPj4nICsgY29tcG9uZW50c1tjb21wb25lbnRzLmxlbmd0aCAtIDFdO1xuICByZXR1cm4gbmFtZTtcbn07XG5cbmNvbnN0IHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkID0gZmllbGROYW1lID0+IHtcbiAgaWYgKHR5cGVvZiBmaWVsZE5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGZpZWxkTmFtZTtcbiAgfVxuICBpZiAoZmllbGROYW1lID09PSAnJF9jcmVhdGVkX2F0Jykge1xuICAgIHJldHVybiAnY3JlYXRlZEF0JztcbiAgfVxuICBpZiAoZmllbGROYW1lID09PSAnJF91cGRhdGVkX2F0Jykge1xuICAgIHJldHVybiAndXBkYXRlZEF0JztcbiAgfVxuICByZXR1cm4gZmllbGROYW1lLnN1YnN0cigxKTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlS2V5cyA9IG9iamVjdCA9PiB7XG4gIGlmICh0eXBlb2Ygb2JqZWN0ID09ICdvYmplY3QnKSB7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gb2JqZWN0KSB7XG4gICAgICBpZiAodHlwZW9mIG9iamVjdFtrZXldID09ICdvYmplY3QnKSB7XG4gICAgICAgIHZhbGlkYXRlS2V5cyhvYmplY3Rba2V5XSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChrZXkuaW5jbHVkZXMoJyQnKSB8fCBrZXkuaW5jbHVkZXMoJy4nKSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9ORVNURURfS0VZLFxuICAgICAgICAgIFwiTmVzdGVkIGtleXMgc2hvdWxkIG5vdCBjb250YWluIHRoZSAnJCcgb3IgJy4nIGNoYXJhY3RlcnNcIlxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxuLy8gUmV0dXJucyB0aGUgbGlzdCBvZiBqb2luIHRhYmxlcyBvbiBhIHNjaGVtYVxuY29uc3Qgam9pblRhYmxlc0ZvclNjaGVtYSA9IHNjaGVtYSA9PiB7XG4gIGNvbnN0IGxpc3QgPSBbXTtcbiAgaWYgKHNjaGVtYSkge1xuICAgIE9iamVjdC5rZXlzKHNjaGVtYS5maWVsZHMpLmZvckVhY2goZmllbGQgPT4ge1xuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdSZWxhdGlvbicpIHtcbiAgICAgICAgbGlzdC5wdXNoKGBfSm9pbjoke2ZpZWxkfToke3NjaGVtYS5jbGFzc05hbWV9YCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIGxpc3Q7XG59O1xuXG5pbnRlcmZhY2UgV2hlcmVDbGF1c2Uge1xuICBwYXR0ZXJuOiBzdHJpbmc7XG4gIHZhbHVlczogQXJyYXk8YW55PjtcbiAgc29ydHM6IEFycmF5PGFueT47XG59XG5cbmNvbnN0IGJ1aWxkV2hlcmVDbGF1c2UgPSAoeyBzY2hlbWEsIHF1ZXJ5LCBpbmRleCwgY2FzZUluc2Vuc2l0aXZlIH0pOiBXaGVyZUNsYXVzZSA9PiB7XG4gIGNvbnN0IHBhdHRlcm5zID0gW107XG4gIGxldCB2YWx1ZXMgPSBbXTtcbiAgY29uc3Qgc29ydHMgPSBbXTtcblxuICBzY2hlbWEgPSB0b1Bvc3RncmVzU2NoZW1hKHNjaGVtYSk7XG4gIGZvciAoY29uc3QgZmllbGROYW1lIGluIHF1ZXJ5KSB7XG4gICAgY29uc3QgaXNBcnJheUZpZWxkID1cbiAgICAgIHNjaGVtYS5maWVsZHMgJiYgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdICYmIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnQXJyYXknO1xuICAgIGNvbnN0IGluaXRpYWxQYXR0ZXJuc0xlbmd0aCA9IHBhdHRlcm5zLmxlbmd0aDtcbiAgICBjb25zdCBmaWVsZFZhbHVlID0gcXVlcnlbZmllbGROYW1lXTtcblxuICAgIC8vIG5vdGhpbmcgaW4gdGhlIHNjaGVtYSwgaXQncyBnb25uYSBibG93IHVwXG4gICAgaWYgKCFzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0pIHtcbiAgICAgIC8vIGFzIGl0IHdvbid0IGV4aXN0XG4gICAgICBpZiAoZmllbGRWYWx1ZSAmJiBmaWVsZFZhbHVlLiRleGlzdHMgPT09IGZhbHNlKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGF1dGhEYXRhTWF0Y2ggPSBmaWVsZE5hbWUubWF0Y2goL15fYXV0aF9kYXRhXyhbYS16QS1aMC05X10rKSQvKTtcbiAgICBpZiAoYXV0aERhdGFNYXRjaCkge1xuICAgICAgLy8gVE9ETzogSGFuZGxlIHF1ZXJ5aW5nIGJ5IF9hdXRoX2RhdGFfcHJvdmlkZXIsIGF1dGhEYXRhIGlzIHN0b3JlZCBpbiBhdXRoRGF0YSBmaWVsZFxuICAgICAgY29udGludWU7XG4gICAgfSBlbHNlIGlmIChjYXNlSW5zZW5zaXRpdmUgJiYgKGZpZWxkTmFtZSA9PT0gJ3VzZXJuYW1lJyB8fCBmaWVsZE5hbWUgPT09ICdlbWFpbCcpKSB7XG4gICAgICBwYXR0ZXJucy5wdXNoKGBMT1dFUigkJHtpbmRleH06bmFtZSkgPSBMT1dFUigkJHtpbmRleCArIDF9KWApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfSBlbHNlIGlmIChmaWVsZE5hbWUuaW5kZXhPZignLicpID49IDApIHtcbiAgICAgIGxldCBuYW1lID0gdHJhbnNmb3JtRG90RmllbGQoZmllbGROYW1lKTtcbiAgICAgIGlmIChmaWVsZFZhbHVlID09PSBudWxsKSB7XG4gICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpyYXcgSVMgTlVMTGApO1xuICAgICAgICB2YWx1ZXMucHVzaChuYW1lKTtcbiAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZmllbGRWYWx1ZS4kaW4pIHtcbiAgICAgICAgICBuYW1lID0gdHJhbnNmb3JtRG90RmllbGRUb0NvbXBvbmVudHMoZmllbGROYW1lKS5qb2luKCctPicpO1xuICAgICAgICAgIHBhdHRlcm5zLnB1c2goYCgkJHtpbmRleH06cmF3KTo6anNvbmIgQD4gJCR7aW5kZXggKyAxfTo6anNvbmJgKTtcbiAgICAgICAgICB2YWx1ZXMucHVzaChuYW1lLCBKU09OLnN0cmluZ2lmeShmaWVsZFZhbHVlLiRpbikpO1xuICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS4kcmVnZXgpIHtcbiAgICAgICAgICAvLyBIYW5kbGUgbGF0ZXJcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZmllbGRWYWx1ZSAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06cmF3ID0gJCR7aW5kZXggKyAxfTo6dGV4dGApO1xuICAgICAgICAgIHZhbHVlcy5wdXNoKG5hbWUsIGZpZWxkVmFsdWUpO1xuICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGZpZWxkVmFsdWUgPT09IG51bGwgfHwgZmllbGRWYWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSBJUyBOVUxMYCk7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgaW5kZXggKz0gMTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGZpZWxkVmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgZmllbGRWYWx1ZSk7XG4gICAgICBpbmRleCArPSAyO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGZpZWxkVmFsdWUgPT09ICdib29sZWFuJykge1xuICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAvLyBDYW4ndCBjYXN0IGJvb2xlYW4gdG8gZG91YmxlIHByZWNpc2lvblxuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ051bWJlcicpIHtcbiAgICAgICAgLy8gU2hvdWxkIGFsd2F5cyByZXR1cm4gemVybyByZXN1bHRzXG4gICAgICAgIGNvbnN0IE1BWF9JTlRfUExVU19PTkUgPSA5MjIzMzcyMDM2ODU0Nzc1ODA4O1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIE1BWF9JTlRfUExVU19PTkUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlKTtcbiAgICAgIH1cbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lID0gJCR7aW5kZXggKyAxfWApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfSBlbHNlIGlmIChbJyRvcicsICckbm9yJywgJyRhbmQnXS5pbmNsdWRlcyhmaWVsZE5hbWUpKSB7XG4gICAgICBjb25zdCBjbGF1c2VzID0gW107XG4gICAgICBjb25zdCBjbGF1c2VWYWx1ZXMgPSBbXTtcbiAgICAgIGZpZWxkVmFsdWUuZm9yRWFjaChzdWJRdWVyeSA9PiB7XG4gICAgICAgIGNvbnN0IGNsYXVzZSA9IGJ1aWxkV2hlcmVDbGF1c2Uoe1xuICAgICAgICAgIHNjaGVtYSxcbiAgICAgICAgICBxdWVyeTogc3ViUXVlcnksXG4gICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgY2FzZUluc2Vuc2l0aXZlLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGNsYXVzZS5wYXR0ZXJuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBjbGF1c2VzLnB1c2goY2xhdXNlLnBhdHRlcm4pO1xuICAgICAgICAgIGNsYXVzZVZhbHVlcy5wdXNoKC4uLmNsYXVzZS52YWx1ZXMpO1xuICAgICAgICAgIGluZGV4ICs9IGNsYXVzZS52YWx1ZXMubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgb3JPckFuZCA9IGZpZWxkTmFtZSA9PT0gJyRhbmQnID8gJyBBTkQgJyA6ICcgT1IgJztcbiAgICAgIGNvbnN0IG5vdCA9IGZpZWxkTmFtZSA9PT0gJyRub3InID8gJyBOT1QgJyA6ICcnO1xuXG4gICAgICBwYXR0ZXJucy5wdXNoKGAke25vdH0oJHtjbGF1c2VzLmpvaW4ob3JPckFuZCl9KWApO1xuICAgICAgdmFsdWVzLnB1c2goLi4uY2xhdXNlVmFsdWVzKTtcbiAgICB9XG5cbiAgICBpZiAoZmllbGRWYWx1ZS4kbmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGlzQXJyYXlGaWVsZCkge1xuICAgICAgICBmaWVsZFZhbHVlLiRuZSA9IEpTT04uc3RyaW5naWZ5KFtmaWVsZFZhbHVlLiRuZV0pO1xuICAgICAgICBwYXR0ZXJucy5wdXNoKGBOT1QgYXJyYXlfY29udGFpbnMoJCR7aW5kZXh9Om5hbWUsICQke2luZGV4ICsgMX0pYCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZmllbGRWYWx1ZS4kbmUgPT09IG51bGwpIHtcbiAgICAgICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSBJUyBOT1QgTlVMTGApO1xuICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBpZiBub3QgbnVsbCwgd2UgbmVlZCB0byBtYW51YWxseSBleGNsdWRlIG51bGxcbiAgICAgICAgICBpZiAoZmllbGRWYWx1ZS4kbmUuX190eXBlID09PSAnR2VvUG9pbnQnKSB7XG4gICAgICAgICAgICBwYXR0ZXJucy5wdXNoKFxuICAgICAgICAgICAgICBgKCQke2luZGV4fTpuYW1lIDw+IFBPSU5UKCQke2luZGV4ICsgMX0sICQke2luZGV4ICsgMn0pIE9SICQke2luZGV4fTpuYW1lIElTIE5VTEwpYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPj0gMCkge1xuICAgICAgICAgICAgICBjb25zdCBjb25zdHJhaW50RmllbGROYW1lID0gdHJhbnNmb3JtRG90RmllbGQoZmllbGROYW1lKTtcbiAgICAgICAgICAgICAgcGF0dGVybnMucHVzaChcbiAgICAgICAgICAgICAgICBgKCR7Y29uc3RyYWludEZpZWxkTmFtZX0gPD4gJCR7aW5kZXh9IE9SICR7Y29uc3RyYWludEZpZWxkTmFtZX0gSVMgTlVMTClgXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBwYXR0ZXJucy5wdXNoKGAoJCR7aW5kZXh9Om5hbWUgPD4gJCR7aW5kZXggKyAxfSBPUiAkJHtpbmRleH06bmFtZSBJUyBOVUxMKWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZpZWxkVmFsdWUuJG5lLl9fdHlwZSA9PT0gJ0dlb1BvaW50Jykge1xuICAgICAgICBjb25zdCBwb2ludCA9IGZpZWxkVmFsdWUuJG5lO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIHBvaW50LmxvbmdpdHVkZSwgcG9pbnQubGF0aXR1ZGUpO1xuICAgICAgICBpbmRleCArPSAzO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVE9ETzogc3VwcG9ydCBhcnJheXNcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlLiRuZSk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChmaWVsZFZhbHVlLiRlcSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoZmllbGRWYWx1ZS4kZXEgPT09IG51bGwpIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgSVMgTlVMTGApO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgICBpbmRleCArPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPj0gMCkge1xuICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkVmFsdWUuJGVxKTtcbiAgICAgICAgICBwYXR0ZXJucy5wdXNoKGAke3RyYW5zZm9ybURvdEZpZWxkKGZpZWxkTmFtZSl9ID0gJCR7aW5kZXgrK31gKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUuJGVxKTtcbiAgICAgICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgICBpbmRleCArPSAyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGlzSW5Pck5pbiA9IEFycmF5LmlzQXJyYXkoZmllbGRWYWx1ZS4kaW4pIHx8IEFycmF5LmlzQXJyYXkoZmllbGRWYWx1ZS4kbmluKTtcbiAgICBpZiAoXG4gICAgICBBcnJheS5pc0FycmF5KGZpZWxkVmFsdWUuJGluKSAmJlxuICAgICAgaXNBcnJheUZpZWxkICYmXG4gICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0uY29udGVudHMgJiZcbiAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS5jb250ZW50cy50eXBlID09PSAnU3RyaW5nJ1xuICAgICkge1xuICAgICAgY29uc3QgaW5QYXR0ZXJucyA9IFtdO1xuICAgICAgbGV0IGFsbG93TnVsbCA9IGZhbHNlO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lKTtcbiAgICAgIGZpZWxkVmFsdWUuJGluLmZvckVhY2goKGxpc3RFbGVtLCBsaXN0SW5kZXgpID0+IHtcbiAgICAgICAgaWYgKGxpc3RFbGVtID09PSBudWxsKSB7XG4gICAgICAgICAgYWxsb3dOdWxsID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWx1ZXMucHVzaChsaXN0RWxlbSk7XG4gICAgICAgICAgaW5QYXR0ZXJucy5wdXNoKGAkJHtpbmRleCArIDEgKyBsaXN0SW5kZXggLSAoYWxsb3dOdWxsID8gMSA6IDApfWApO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGlmIChhbGxvd051bGwpIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChgKCQke2luZGV4fTpuYW1lIElTIE5VTEwgT1IgJCR7aW5kZXh9Om5hbWUgJiYgQVJSQVlbJHtpblBhdHRlcm5zLmpvaW4oKX1dKWApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgJiYgQVJSQVlbJHtpblBhdHRlcm5zLmpvaW4oKX1dYCk7XG4gICAgICB9XG4gICAgICBpbmRleCA9IGluZGV4ICsgMSArIGluUGF0dGVybnMubGVuZ3RoO1xuICAgIH0gZWxzZSBpZiAoaXNJbk9yTmluKSB7XG4gICAgICB2YXIgY3JlYXRlQ29uc3RyYWludCA9IChiYXNlQXJyYXksIG5vdEluKSA9PiB7XG4gICAgICAgIGNvbnN0IG5vdCA9IG5vdEluID8gJyBOT1QgJyA6ICcnO1xuICAgICAgICBpZiAoYmFzZUFycmF5Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBpZiAoaXNBcnJheUZpZWxkKSB7XG4gICAgICAgICAgICBwYXR0ZXJucy5wdXNoKGAke25vdH0gYXJyYXlfY29udGFpbnMoJCR7aW5kZXh9Om5hbWUsICQke2luZGV4ICsgMX0pYCk7XG4gICAgICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIEpTT04uc3RyaW5naWZ5KGJhc2VBcnJheSkpO1xuICAgICAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gSGFuZGxlIE5lc3RlZCBEb3QgTm90YXRpb24gQWJvdmVcbiAgICAgICAgICAgIGlmIChmaWVsZE5hbWUuaW5kZXhPZignLicpID49IDApIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgaW5QYXR0ZXJucyA9IFtdO1xuICAgICAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgICAgIGJhc2VBcnJheS5mb3JFYWNoKChsaXN0RWxlbSwgbGlzdEluZGV4KSA9PiB7XG4gICAgICAgICAgICAgIGlmIChsaXN0RWxlbSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdmFsdWVzLnB1c2gobGlzdEVsZW0pO1xuICAgICAgICAgICAgICAgIGluUGF0dGVybnMucHVzaChgJCR7aW5kZXggKyAxICsgbGlzdEluZGV4fWApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lICR7bm90fSBJTiAoJHtpblBhdHRlcm5zLmpvaW4oKX0pYCk7XG4gICAgICAgICAgICBpbmRleCA9IGluZGV4ICsgMSArIGluUGF0dGVybnMubGVuZ3RoO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICghbm90SW4pIHtcbiAgICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lIElTIE5VTExgKTtcbiAgICAgICAgICBpbmRleCA9IGluZGV4ICsgMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBIYW5kbGUgZW1wdHkgYXJyYXlcbiAgICAgICAgICBpZiAobm90SW4pIHtcbiAgICAgICAgICAgIHBhdHRlcm5zLnB1c2goJzEgPSAxJyk7IC8vIFJldHVybiBhbGwgdmFsdWVzXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBhdHRlcm5zLnB1c2goJzEgPSAyJyk7IC8vIFJldHVybiBubyB2YWx1ZXNcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBpZiAoZmllbGRWYWx1ZS4kaW4pIHtcbiAgICAgICAgY3JlYXRlQ29uc3RyYWludChcbiAgICAgICAgICBfLmZsYXRNYXAoZmllbGRWYWx1ZS4kaW4sIGVsdCA9PiBlbHQpLFxuICAgICAgICAgIGZhbHNlXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoZmllbGRWYWx1ZS4kbmluKSB7XG4gICAgICAgIGNyZWF0ZUNvbnN0cmFpbnQoXG4gICAgICAgICAgXy5mbGF0TWFwKGZpZWxkVmFsdWUuJG5pbiwgZWx0ID0+IGVsdCksXG4gICAgICAgICAgdHJ1ZVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGZpZWxkVmFsdWUuJGluICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2JhZCAkaW4gdmFsdWUnKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBmaWVsZFZhbHVlLiRuaW4gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnYmFkICRuaW4gdmFsdWUnKTtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShmaWVsZFZhbHVlLiRhbGwpICYmIGlzQXJyYXlGaWVsZCkge1xuICAgICAgaWYgKGlzQW55VmFsdWVSZWdleFN0YXJ0c1dpdGgoZmllbGRWYWx1ZS4kYWxsKSkge1xuICAgICAgICBpZiAoIWlzQWxsVmFsdWVzUmVnZXhPck5vbmUoZmllbGRWYWx1ZS4kYWxsKSkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICdBbGwgJGFsbCB2YWx1ZXMgbXVzdCBiZSBvZiByZWdleCB0eXBlIG9yIG5vbmU6ICcgKyBmaWVsZFZhbHVlLiRhbGxcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmaWVsZFZhbHVlLiRhbGwubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IHByb2Nlc3NSZWdleFBhdHRlcm4oZmllbGRWYWx1ZS4kYWxsW2ldLiRyZWdleCk7XG4gICAgICAgICAgZmllbGRWYWx1ZS4kYWxsW2ldID0gdmFsdWUuc3Vic3RyaW5nKDEpICsgJyUnO1xuICAgICAgICB9XG4gICAgICAgIHBhdHRlcm5zLnB1c2goYGFycmF5X2NvbnRhaW5zX2FsbF9yZWdleCgkJHtpbmRleH06bmFtZSwgJCR7aW5kZXggKyAxfTo6anNvbmIpYCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYXR0ZXJucy5wdXNoKGBhcnJheV9jb250YWluc19hbGwoJCR7aW5kZXh9Om5hbWUsICQke2luZGV4ICsgMX06Ompzb25iKWApO1xuICAgICAgfVxuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBKU09OLnN0cmluZ2lmeShmaWVsZFZhbHVlLiRhbGwpKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGZpZWxkVmFsdWUuJGFsbCkpIHtcbiAgICAgIGlmIChmaWVsZFZhbHVlLiRhbGwubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lID0gJCR7aW5kZXggKyAxfWApO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUuJGFsbFswXS5vYmplY3RJZCk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBmaWVsZFZhbHVlLiRleGlzdHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBpZiAoZmllbGRWYWx1ZS4kZXhpc3RzKSB7XG4gICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lIElTIE5PVCBOVUxMYCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSBJUyBOVUxMYCk7XG4gICAgICB9XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgaW5kZXggKz0gMTtcbiAgICB9XG5cbiAgICBpZiAoZmllbGRWYWx1ZS4kY29udGFpbmVkQnkpIHtcbiAgICAgIGNvbnN0IGFyciA9IGZpZWxkVmFsdWUuJGNvbnRhaW5lZEJ5O1xuICAgICAgaWYgKCEoYXJyIGluc3RhbmNlb2YgQXJyYXkpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sIGBiYWQgJGNvbnRhaW5lZEJ5OiBzaG91bGQgYmUgYW4gYXJyYXlgKTtcbiAgICAgIH1cblxuICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPEAgJCR7aW5kZXggKyAxfTo6anNvbmJgKTtcbiAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgSlNPTi5zdHJpbmdpZnkoYXJyKSk7XG4gICAgICBpbmRleCArPSAyO1xuICAgIH1cblxuICAgIGlmIChmaWVsZFZhbHVlLiR0ZXh0KSB7XG4gICAgICBjb25zdCBzZWFyY2ggPSBmaWVsZFZhbHVlLiR0ZXh0LiRzZWFyY2g7XG4gICAgICBsZXQgbGFuZ3VhZ2UgPSAnZW5nbGlzaCc7XG4gICAgICBpZiAodHlwZW9mIHNlYXJjaCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgYGJhZCAkdGV4dDogJHNlYXJjaCwgc2hvdWxkIGJlIG9iamVjdGApO1xuICAgICAgfVxuICAgICAgaWYgKCFzZWFyY2guJHRlcm0gfHwgdHlwZW9mIHNlYXJjaC4kdGVybSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgYGJhZCAkdGV4dDogJHRlcm0sIHNob3VsZCBiZSBzdHJpbmdgKTtcbiAgICAgIH1cbiAgICAgIGlmIChzZWFyY2guJGxhbmd1YWdlICYmIHR5cGVvZiBzZWFyY2guJGxhbmd1YWdlICE9PSAnc3RyaW5nJykge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCBgYmFkICR0ZXh0OiAkbGFuZ3VhZ2UsIHNob3VsZCBiZSBzdHJpbmdgKTtcbiAgICAgIH0gZWxzZSBpZiAoc2VhcmNoLiRsYW5ndWFnZSkge1xuICAgICAgICBsYW5ndWFnZSA9IHNlYXJjaC4kbGFuZ3VhZ2U7XG4gICAgICB9XG4gICAgICBpZiAoc2VhcmNoLiRjYXNlU2Vuc2l0aXZlICYmIHR5cGVvZiBzZWFyY2guJGNhc2VTZW5zaXRpdmUgIT09ICdib29sZWFuJykge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgIGBiYWQgJHRleHQ6ICRjYXNlU2Vuc2l0aXZlLCBzaG91bGQgYmUgYm9vbGVhbmBcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoc2VhcmNoLiRjYXNlU2Vuc2l0aXZlKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgYGJhZCAkdGV4dDogJGNhc2VTZW5zaXRpdmUgbm90IHN1cHBvcnRlZCwgcGxlYXNlIHVzZSAkcmVnZXggb3IgY3JlYXRlIGEgc2VwYXJhdGUgbG93ZXIgY2FzZSBjb2x1bW4uYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKHNlYXJjaC4kZGlhY3JpdGljU2Vuc2l0aXZlICYmIHR5cGVvZiBzZWFyY2guJGRpYWNyaXRpY1NlbnNpdGl2ZSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgYGJhZCAkdGV4dDogJGRpYWNyaXRpY1NlbnNpdGl2ZSwgc2hvdWxkIGJlIGJvb2xlYW5gXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKHNlYXJjaC4kZGlhY3JpdGljU2Vuc2l0aXZlID09PSBmYWxzZSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgIGBiYWQgJHRleHQ6ICRkaWFjcml0aWNTZW5zaXRpdmUgLSBmYWxzZSBub3Qgc3VwcG9ydGVkLCBpbnN0YWxsIFBvc3RncmVzIFVuYWNjZW50IEV4dGVuc2lvbmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHBhdHRlcm5zLnB1c2goXG4gICAgICAgIGB0b190c3ZlY3RvcigkJHtpbmRleH0sICQke2luZGV4ICsgMX06bmFtZSkgQEAgdG9fdHNxdWVyeSgkJHtpbmRleCArIDJ9LCAkJHtpbmRleCArIDN9KWBcbiAgICAgICk7XG4gICAgICB2YWx1ZXMucHVzaChsYW5ndWFnZSwgZmllbGROYW1lLCBsYW5ndWFnZSwgc2VhcmNoLiR0ZXJtKTtcbiAgICAgIGluZGV4ICs9IDQ7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuJG5lYXJTcGhlcmUpIHtcbiAgICAgIGNvbnN0IHBvaW50ID0gZmllbGRWYWx1ZS4kbmVhclNwaGVyZTtcbiAgICAgIGNvbnN0IGRpc3RhbmNlID0gZmllbGRWYWx1ZS4kbWF4RGlzdGFuY2U7XG4gICAgICBjb25zdCBkaXN0YW5jZUluS00gPSBkaXN0YW5jZSAqIDYzNzEgKiAxMDAwO1xuICAgICAgcGF0dGVybnMucHVzaChcbiAgICAgICAgYFNUX0Rpc3RhbmNlU3BoZXJlKCQke2luZGV4fTpuYW1lOjpnZW9tZXRyeSwgUE9JTlQoJCR7aW5kZXggKyAxfSwgJCR7XG4gICAgICAgICAgaW5kZXggKyAyXG4gICAgICAgIH0pOjpnZW9tZXRyeSkgPD0gJCR7aW5kZXggKyAzfWBcbiAgICAgICk7XG4gICAgICBzb3J0cy5wdXNoKFxuICAgICAgICBgU1RfRGlzdGFuY2VTcGhlcmUoJCR7aW5kZXh9Om5hbWU6Omdlb21ldHJ5LCBQT0lOVCgkJHtpbmRleCArIDF9LCAkJHtcbiAgICAgICAgICBpbmRleCArIDJcbiAgICAgICAgfSk6Omdlb21ldHJ5KSBBU0NgXG4gICAgICApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBwb2ludC5sb25naXR1ZGUsIHBvaW50LmxhdGl0dWRlLCBkaXN0YW5jZUluS00pO1xuICAgICAgaW5kZXggKz0gNDtcbiAgICB9XG5cbiAgICBpZiAoZmllbGRWYWx1ZS4kd2l0aGluICYmIGZpZWxkVmFsdWUuJHdpdGhpbi4kYm94KSB7XG4gICAgICBjb25zdCBib3ggPSBmaWVsZFZhbHVlLiR3aXRoaW4uJGJveDtcbiAgICAgIGNvbnN0IGxlZnQgPSBib3hbMF0ubG9uZ2l0dWRlO1xuICAgICAgY29uc3QgYm90dG9tID0gYm94WzBdLmxhdGl0dWRlO1xuICAgICAgY29uc3QgcmlnaHQgPSBib3hbMV0ubG9uZ2l0dWRlO1xuICAgICAgY29uc3QgdG9wID0gYm94WzFdLmxhdGl0dWRlO1xuXG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZTo6cG9pbnQgPEAgJCR7aW5kZXggKyAxfTo6Ym94YCk7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGAoKCR7bGVmdH0sICR7Ym90dG9tfSksICgke3JpZ2h0fSwgJHt0b3B9KSlgKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuJGdlb1dpdGhpbiAmJiBmaWVsZFZhbHVlLiRnZW9XaXRoaW4uJGNlbnRlclNwaGVyZSkge1xuICAgICAgY29uc3QgY2VudGVyU3BoZXJlID0gZmllbGRWYWx1ZS4kZ2VvV2l0aGluLiRjZW50ZXJTcGhlcmU7XG4gICAgICBpZiAoIShjZW50ZXJTcGhlcmUgaW5zdGFuY2VvZiBBcnJheSkgfHwgY2VudGVyU3BoZXJlLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7ICRjZW50ZXJTcGhlcmUgc2hvdWxkIGJlIGFuIGFycmF5IG9mIFBhcnNlLkdlb1BvaW50IGFuZCBkaXN0YW5jZSdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIC8vIEdldCBwb2ludCwgY29udmVydCB0byBnZW8gcG9pbnQgaWYgbmVjZXNzYXJ5IGFuZCB2YWxpZGF0ZVxuICAgICAgbGV0IHBvaW50ID0gY2VudGVyU3BoZXJlWzBdO1xuICAgICAgaWYgKHBvaW50IGluc3RhbmNlb2YgQXJyYXkgJiYgcG9pbnQubGVuZ3RoID09PSAyKSB7XG4gICAgICAgIHBvaW50ID0gbmV3IFBhcnNlLkdlb1BvaW50KHBvaW50WzFdLCBwb2ludFswXSk7XG4gICAgICB9IGVsc2UgaWYgKCFHZW9Qb2ludENvZGVyLmlzVmFsaWRKU09OKHBvaW50KSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICdiYWQgJGdlb1dpdGhpbiB2YWx1ZTsgJGNlbnRlclNwaGVyZSBnZW8gcG9pbnQgaW52YWxpZCdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIFBhcnNlLkdlb1BvaW50Ll92YWxpZGF0ZShwb2ludC5sYXRpdHVkZSwgcG9pbnQubG9uZ2l0dWRlKTtcbiAgICAgIC8vIEdldCBkaXN0YW5jZSBhbmQgdmFsaWRhdGVcbiAgICAgIGNvbnN0IGRpc3RhbmNlID0gY2VudGVyU3BoZXJlWzFdO1xuICAgICAgaWYgKGlzTmFOKGRpc3RhbmNlKSB8fCBkaXN0YW5jZSA8IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7ICRjZW50ZXJTcGhlcmUgZGlzdGFuY2UgaW52YWxpZCdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRpc3RhbmNlSW5LTSA9IGRpc3RhbmNlICogNjM3MSAqIDEwMDA7XG4gICAgICBwYXR0ZXJucy5wdXNoKFxuICAgICAgICBgU1RfRGlzdGFuY2VTcGhlcmUoJCR7aW5kZXh9Om5hbWU6Omdlb21ldHJ5LCBQT0lOVCgkJHtpbmRleCArIDF9LCAkJHtcbiAgICAgICAgICBpbmRleCArIDJcbiAgICAgICAgfSk6Omdlb21ldHJ5KSA8PSAkJHtpbmRleCArIDN9YFxuICAgICAgKTtcbiAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgcG9pbnQubG9uZ2l0dWRlLCBwb2ludC5sYXRpdHVkZSwgZGlzdGFuY2VJbktNKTtcbiAgICAgIGluZGV4ICs9IDQ7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuJGdlb1dpdGhpbiAmJiBmaWVsZFZhbHVlLiRnZW9XaXRoaW4uJHBvbHlnb24pIHtcbiAgICAgIGNvbnN0IHBvbHlnb24gPSBmaWVsZFZhbHVlLiRnZW9XaXRoaW4uJHBvbHlnb247XG4gICAgICBsZXQgcG9pbnRzO1xuICAgICAgaWYgKHR5cGVvZiBwb2x5Z29uID09PSAnb2JqZWN0JyAmJiBwb2x5Z29uLl9fdHlwZSA9PT0gJ1BvbHlnb24nKSB7XG4gICAgICAgIGlmICghcG9seWdvbi5jb29yZGluYXRlcyB8fCBwb2x5Z29uLmNvb3JkaW5hdGVzLmxlbmd0aCA8IDMpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7IFBvbHlnb24uY29vcmRpbmF0ZXMgc2hvdWxkIGNvbnRhaW4gYXQgbGVhc3QgMyBsb24vbGF0IHBhaXJzJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcG9pbnRzID0gcG9seWdvbi5jb29yZGluYXRlcztcbiAgICAgIH0gZWxzZSBpZiAocG9seWdvbiBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgIGlmIChwb2x5Z29uLmxlbmd0aCA8IDMpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7ICRwb2x5Z29uIHNob3VsZCBjb250YWluIGF0IGxlYXN0IDMgR2VvUG9pbnRzJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcG9pbnRzID0gcG9seWdvbjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgXCJiYWQgJGdlb1dpdGhpbiB2YWx1ZTsgJHBvbHlnb24gc2hvdWxkIGJlIFBvbHlnb24gb2JqZWN0IG9yIEFycmF5IG9mIFBhcnNlLkdlb1BvaW50J3NcIlxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcG9pbnRzID0gcG9pbnRzXG4gICAgICAgIC5tYXAocG9pbnQgPT4ge1xuICAgICAgICAgIGlmIChwb2ludCBpbnN0YW5jZW9mIEFycmF5ICYmIHBvaW50Lmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50WzFdLCBwb2ludFswXSk7XG4gICAgICAgICAgICByZXR1cm4gYCgke3BvaW50WzBdfSwgJHtwb2ludFsxXX0pYDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHR5cGVvZiBwb2ludCAhPT0gJ29iamVjdCcgfHwgcG9pbnQuX190eXBlICE9PSAnR2VvUG9pbnQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnYmFkICRnZW9XaXRoaW4gdmFsdWUnKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50LmxhdGl0dWRlLCBwb2ludC5sb25naXR1ZGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gYCgke3BvaW50LmxvbmdpdHVkZX0sICR7cG9pbnQubGF0aXR1ZGV9KWA7XG4gICAgICAgIH0pXG4gICAgICAgIC5qb2luKCcsICcpO1xuXG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZTo6cG9pbnQgPEAgJCR7aW5kZXggKyAxfTo6cG9seWdvbmApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBgKCR7cG9pbnRzfSlgKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuICAgIGlmIChmaWVsZFZhbHVlLiRnZW9JbnRlcnNlY3RzICYmIGZpZWxkVmFsdWUuJGdlb0ludGVyc2VjdHMuJHBvaW50KSB7XG4gICAgICBjb25zdCBwb2ludCA9IGZpZWxkVmFsdWUuJGdlb0ludGVyc2VjdHMuJHBvaW50O1xuICAgICAgaWYgKHR5cGVvZiBwb2ludCAhPT0gJ29iamVjdCcgfHwgcG9pbnQuX190eXBlICE9PSAnR2VvUG9pbnQnKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgJ2JhZCAkZ2VvSW50ZXJzZWN0IHZhbHVlOyAkcG9pbnQgc2hvdWxkIGJlIEdlb1BvaW50J1xuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50LmxhdGl0dWRlLCBwb2ludC5sb25naXR1ZGUpO1xuICAgICAgfVxuICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWU6OnBvbHlnb24gQD4gJCR7aW5kZXggKyAxfTo6cG9pbnRgKTtcbiAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgYCgke3BvaW50LmxvbmdpdHVkZX0sICR7cG9pbnQubGF0aXR1ZGV9KWApO1xuICAgICAgaW5kZXggKz0gMjtcbiAgICB9XG5cbiAgICBpZiAoZmllbGRWYWx1ZS4kcmVnZXgpIHtcbiAgICAgIGxldCByZWdleCA9IGZpZWxkVmFsdWUuJHJlZ2V4O1xuICAgICAgbGV0IG9wZXJhdG9yID0gJ34nO1xuICAgICAgY29uc3Qgb3B0cyA9IGZpZWxkVmFsdWUuJG9wdGlvbnM7XG4gICAgICBpZiAob3B0cykge1xuICAgICAgICBpZiAob3B0cy5pbmRleE9mKCdpJykgPj0gMCkge1xuICAgICAgICAgIG9wZXJhdG9yID0gJ34qJztcbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0cy5pbmRleE9mKCd4JykgPj0gMCkge1xuICAgICAgICAgIHJlZ2V4ID0gcmVtb3ZlV2hpdGVTcGFjZShyZWdleCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgbmFtZSA9IHRyYW5zZm9ybURvdEZpZWxkKGZpZWxkTmFtZSk7XG4gICAgICByZWdleCA9IHByb2Nlc3NSZWdleFBhdHRlcm4ocmVnZXgpO1xuXG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06cmF3ICR7b3BlcmF0b3J9ICckJHtpbmRleCArIDF9OnJhdydgKTtcbiAgICAgIHZhbHVlcy5wdXNoKG5hbWUsIHJlZ2V4KTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuX190eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgIGlmIChpc0FycmF5RmllbGQpIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChgYXJyYXlfY29udGFpbnMoJCR7aW5kZXh9Om5hbWUsICQke2luZGV4ICsgMX0pYCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgSlNPTi5zdHJpbmdpZnkoW2ZpZWxkVmFsdWVdKSk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlLm9iamVjdElkKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZmllbGRWYWx1ZS5fX3R5cGUgPT09ICdEYXRlJykge1xuICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUuaXNvKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuX190eXBlID09PSAnR2VvUG9pbnQnKSB7XG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSB+PSBQT0lOVCgkJHtpbmRleCArIDF9LCAkJHtpbmRleCArIDJ9KWApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlLmxvbmdpdHVkZSwgZmllbGRWYWx1ZS5sYXRpdHVkZSk7XG4gICAgICBpbmRleCArPSAzO1xuICAgIH1cblxuICAgIGlmIChmaWVsZFZhbHVlLl9fdHlwZSA9PT0gJ1BvbHlnb24nKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGNvbnZlcnRQb2x5Z29uVG9TUUwoZmllbGRWYWx1ZS5jb29yZGluYXRlcyk7XG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSB+PSAkJHtpbmRleCArIDF9Ojpwb2x5Z29uYCk7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIHZhbHVlKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuXG4gICAgT2JqZWN0LmtleXMoUGFyc2VUb1Bvc2dyZXNDb21wYXJhdG9yKS5mb3JFYWNoKGNtcCA9PiB7XG4gICAgICBpZiAoZmllbGRWYWx1ZVtjbXBdIHx8IGZpZWxkVmFsdWVbY21wXSA9PT0gMCkge1xuICAgICAgICBjb25zdCBwZ0NvbXBhcmF0b3IgPSBQYXJzZVRvUG9zZ3Jlc0NvbXBhcmF0b3JbY21wXTtcbiAgICAgICAgY29uc3QgcG9zdGdyZXNWYWx1ZSA9IHRvUG9zdGdyZXNWYWx1ZShmaWVsZFZhbHVlW2NtcF0pO1xuICAgICAgICBsZXQgY29uc3RyYWludEZpZWxkTmFtZTtcbiAgICAgICAgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPj0gMCkge1xuICAgICAgICAgIGxldCBjYXN0VHlwZTtcbiAgICAgICAgICBzd2l0Y2ggKHR5cGVvZiBwb3N0Z3Jlc1ZhbHVlKSB7XG4gICAgICAgICAgICBjYXNlICdudW1iZXInOlxuICAgICAgICAgICAgICBjYXN0VHlwZSA9ICdkb3VibGUgcHJlY2lzaW9uJztcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdib29sZWFuJzpcbiAgICAgICAgICAgICAgY2FzdFR5cGUgPSAnYm9vbGVhbic7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgY2FzdFR5cGUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0cmFpbnRGaWVsZE5hbWUgPSBjYXN0VHlwZVxuICAgICAgICAgICAgPyBgQ0FTVCAoKCR7dHJhbnNmb3JtRG90RmllbGQoZmllbGROYW1lKX0pIEFTICR7Y2FzdFR5cGV9KWBcbiAgICAgICAgICAgIDogdHJhbnNmb3JtRG90RmllbGQoZmllbGROYW1lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdHJhaW50RmllbGROYW1lID0gYCQke2luZGV4Kyt9Om5hbWVgO1xuICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFsdWVzLnB1c2gocG9zdGdyZXNWYWx1ZSk7XG4gICAgICAgIHBhdHRlcm5zLnB1c2goYCR7Y29uc3RyYWludEZpZWxkTmFtZX0gJHtwZ0NvbXBhcmF0b3J9ICQke2luZGV4Kyt9YCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAoaW5pdGlhbFBhdHRlcm5zTGVuZ3RoID09PSBwYXR0ZXJucy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgICAgYFBvc3RncmVzIGRvZXNuJ3Qgc3VwcG9ydCB0aGlzIHF1ZXJ5IHR5cGUgeWV0ICR7SlNPTi5zdHJpbmdpZnkoZmllbGRWYWx1ZSl9YFxuICAgICAgKTtcbiAgICB9XG4gIH1cbiAgdmFsdWVzID0gdmFsdWVzLm1hcCh0cmFuc2Zvcm1WYWx1ZSk7XG4gIHJldHVybiB7IHBhdHRlcm46IHBhdHRlcm5zLmpvaW4oJyBBTkQgJyksIHZhbHVlcywgc29ydHMgfTtcbn07XG5cbmV4cG9ydCBjbGFzcyBQb3N0Z3Jlc1N0b3JhZ2VBZGFwdGVyIGltcGxlbWVudHMgU3RvcmFnZUFkYXB0ZXIge1xuICBjYW5Tb3J0T25Kb2luVGFibGVzOiBib29sZWFuO1xuXG4gIC8vIFByaXZhdGVcbiAgX2NvbGxlY3Rpb25QcmVmaXg6IHN0cmluZztcbiAgX2NsaWVudDogYW55O1xuICBfcGdwOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoeyB1cmksIGNvbGxlY3Rpb25QcmVmaXggPSAnJywgZGF0YWJhc2VPcHRpb25zIH06IGFueSkge1xuICAgIHRoaXMuX2NvbGxlY3Rpb25QcmVmaXggPSBjb2xsZWN0aW9uUHJlZml4O1xuICAgIGNvbnN0IHsgY2xpZW50LCBwZ3AgfSA9IGNyZWF0ZUNsaWVudCh1cmksIGRhdGFiYXNlT3B0aW9ucyk7XG4gICAgdGhpcy5fY2xpZW50ID0gY2xpZW50O1xuICAgIHRoaXMuX3BncCA9IHBncDtcbiAgICB0aGlzLmNhblNvcnRPbkpvaW5UYWJsZXMgPSBmYWxzZTtcbiAgfVxuXG4gIC8vTm90ZSB0aGF0IGFuYWx5emU9dHJ1ZSB3aWxsIHJ1biB0aGUgcXVlcnksIGV4ZWN1dGluZyBJTlNFUlRTLCBERUxFVEVTLCBldGMuXG4gIGNyZWF0ZUV4cGxhaW5hYmxlUXVlcnkocXVlcnk6IHN0cmluZywgYW5hbHl6ZTogYm9vbGVhbiA9IGZhbHNlKSB7XG4gICAgaWYgKGFuYWx5emUpIHtcbiAgICAgIHJldHVybiAnRVhQTEFJTiAoQU5BTFlaRSwgRk9STUFUIEpTT04pICcgKyBxdWVyeTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuICdFWFBMQUlOIChGT1JNQVQgSlNPTikgJyArIHF1ZXJ5O1xuICAgIH1cbiAgfVxuXG4gIGhhbmRsZVNodXRkb3duKCkge1xuICAgIGlmICghdGhpcy5fY2xpZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX2NsaWVudC4kcG9vbC5lbmQoKTtcbiAgfVxuXG4gIGFzeW5jIF9lbnN1cmVTY2hlbWFDb2xsZWN0aW9uRXhpc3RzKGNvbm46IGFueSkge1xuICAgIGNvbm4gPSBjb25uIHx8IHRoaXMuX2NsaWVudDtcbiAgICBhd2FpdCBjb25uXG4gICAgICAubm9uZShcbiAgICAgICAgJ0NSRUFURSBUQUJMRSBJRiBOT1QgRVhJU1RTIFwiX1NDSEVNQVwiICggXCJjbGFzc05hbWVcIiB2YXJDaGFyKDEyMCksIFwic2NoZW1hXCIganNvbmIsIFwiaXNQYXJzZUNsYXNzXCIgYm9vbCwgUFJJTUFSWSBLRVkgKFwiY2xhc3NOYW1lXCIpICknXG4gICAgICApXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZXJyb3IuY29kZSA9PT0gUG9zdGdyZXNEdXBsaWNhdGVSZWxhdGlvbkVycm9yIHx8XG4gICAgICAgICAgZXJyb3IuY29kZSA9PT0gUG9zdGdyZXNVbmlxdWVJbmRleFZpb2xhdGlvbkVycm9yIHx8XG4gICAgICAgICAgZXJyb3IuY29kZSA9PT0gUG9zdGdyZXNEdXBsaWNhdGVPYmplY3RFcnJvclxuICAgICAgICApIHtcbiAgICAgICAgICAvLyBUYWJsZSBhbHJlYWR5IGV4aXN0cywgbXVzdCBoYXZlIGJlZW4gY3JlYXRlZCBieSBhIGRpZmZlcmVudCByZXF1ZXN0LiBJZ25vcmUgZXJyb3IuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgY2xhc3NFeGlzdHMobmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudC5vbmUoXG4gICAgICAnU0VMRUNUIEVYSVNUUyAoU0VMRUNUIDEgRlJPTSBpbmZvcm1hdGlvbl9zY2hlbWEudGFibGVzIFdIRVJFIHRhYmxlX25hbWUgPSAkMSknLFxuICAgICAgW25hbWVdLFxuICAgICAgYSA9PiBhLmV4aXN0c1xuICAgICk7XG4gIH1cblxuICBhc3luYyBzZXRDbGFzc0xldmVsUGVybWlzc2lvbnMoY2xhc3NOYW1lOiBzdHJpbmcsIENMUHM6IGFueSkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGF3YWl0IHRoaXMuX2NsaWVudC50YXNrKCdzZXQtY2xhc3MtbGV2ZWwtcGVybWlzc2lvbnMnLCBhc3luYyB0ID0+IHtcbiAgICAgIGF3YWl0IHNlbGYuX2Vuc3VyZVNjaGVtYUNvbGxlY3Rpb25FeGlzdHModCk7XG4gICAgICBjb25zdCB2YWx1ZXMgPSBbY2xhc3NOYW1lLCAnc2NoZW1hJywgJ2NsYXNzTGV2ZWxQZXJtaXNzaW9ucycsIEpTT04uc3RyaW5naWZ5KENMUHMpXTtcbiAgICAgIGF3YWl0IHQubm9uZShcbiAgICAgICAgYFVQREFURSBcIl9TQ0hFTUFcIiBTRVQgJDI6bmFtZSA9IGpzb25fb2JqZWN0X3NldF9rZXkoJDI6bmFtZSwgJDM6OnRleHQsICQ0Ojpqc29uYikgV0hFUkUgXCJjbGFzc05hbWVcIiA9ICQxYCxcbiAgICAgICAgdmFsdWVzXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgc2V0SW5kZXhlc1dpdGhTY2hlbWFGb3JtYXQoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc3VibWl0dGVkSW5kZXhlczogYW55LFxuICAgIGV4aXN0aW5nSW5kZXhlczogYW55ID0ge30sXG4gICAgZmllbGRzOiBhbnksXG4gICAgY29ubjogP2FueVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25uID0gY29ubiB8fCB0aGlzLl9jbGllbnQ7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgaWYgKHN1Ym1pdHRlZEluZGV4ZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICBpZiAoT2JqZWN0LmtleXMoZXhpc3RpbmdJbmRleGVzKS5sZW5ndGggPT09IDApIHtcbiAgICAgIGV4aXN0aW5nSW5kZXhlcyA9IHsgX2lkXzogeyBfaWQ6IDEgfSB9O1xuICAgIH1cbiAgICBjb25zdCBkZWxldGVkSW5kZXhlcyA9IFtdO1xuICAgIGNvbnN0IGluc2VydGVkSW5kZXhlcyA9IFtdO1xuICAgIE9iamVjdC5rZXlzKHN1Ym1pdHRlZEluZGV4ZXMpLmZvckVhY2gobmFtZSA9PiB7XG4gICAgICBjb25zdCBmaWVsZCA9IHN1Ym1pdHRlZEluZGV4ZXNbbmFtZV07XG4gICAgICBpZiAoZXhpc3RpbmdJbmRleGVzW25hbWVdICYmIGZpZWxkLl9fb3AgIT09ICdEZWxldGUnKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCBgSW5kZXggJHtuYW1lfSBleGlzdHMsIGNhbm5vdCB1cGRhdGUuYCk7XG4gICAgICB9XG4gICAgICBpZiAoIWV4aXN0aW5nSW5kZXhlc1tuYW1lXSAmJiBmaWVsZC5fX29wID09PSAnRGVsZXRlJykge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSxcbiAgICAgICAgICBgSW5kZXggJHtuYW1lfSBkb2VzIG5vdCBleGlzdCwgY2Fubm90IGRlbGV0ZS5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoZmllbGQuX19vcCA9PT0gJ0RlbGV0ZScpIHtcbiAgICAgICAgZGVsZXRlZEluZGV4ZXMucHVzaChuYW1lKTtcbiAgICAgICAgZGVsZXRlIGV4aXN0aW5nSW5kZXhlc1tuYW1lXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIE9iamVjdC5rZXlzKGZpZWxkKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZmllbGRzLCBrZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksXG4gICAgICAgICAgICAgIGBGaWVsZCAke2tleX0gZG9lcyBub3QgZXhpc3QsIGNhbm5vdCBhZGQgaW5kZXguYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBleGlzdGluZ0luZGV4ZXNbbmFtZV0gPSBmaWVsZDtcbiAgICAgICAgaW5zZXJ0ZWRJbmRleGVzLnB1c2goe1xuICAgICAgICAgIGtleTogZmllbGQsXG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgYXdhaXQgY29ubi50eCgnc2V0LWluZGV4ZXMtd2l0aC1zY2hlbWEtZm9ybWF0JywgYXN5bmMgdCA9PiB7XG4gICAgICBpZiAoaW5zZXJ0ZWRJbmRleGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgYXdhaXQgc2VsZi5jcmVhdGVJbmRleGVzKGNsYXNzTmFtZSwgaW5zZXJ0ZWRJbmRleGVzLCB0KTtcbiAgICAgIH1cbiAgICAgIGlmIChkZWxldGVkSW5kZXhlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGF3YWl0IHNlbGYuZHJvcEluZGV4ZXMoY2xhc3NOYW1lLCBkZWxldGVkSW5kZXhlcywgdCk7XG4gICAgICB9XG4gICAgICBhd2FpdCBzZWxmLl9lbnN1cmVTY2hlbWFDb2xsZWN0aW9uRXhpc3RzKHQpO1xuICAgICAgYXdhaXQgdC5ub25lKFxuICAgICAgICAnVVBEQVRFIFwiX1NDSEVNQVwiIFNFVCAkMjpuYW1lID0ganNvbl9vYmplY3Rfc2V0X2tleSgkMjpuYW1lLCAkMzo6dGV4dCwgJDQ6Ompzb25iKSBXSEVSRSBcImNsYXNzTmFtZVwiID0gJDEnLFxuICAgICAgICBbY2xhc3NOYW1lLCAnc2NoZW1hJywgJ2luZGV4ZXMnLCBKU09OLnN0cmluZ2lmeShleGlzdGluZ0luZGV4ZXMpXVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZUNsYXNzKGNsYXNzTmFtZTogc3RyaW5nLCBzY2hlbWE6IFNjaGVtYVR5cGUsIGNvbm46ID9hbnkpIHtcbiAgICBjb25uID0gY29ubiB8fCB0aGlzLl9jbGllbnQ7XG4gICAgcmV0dXJuIGNvbm5cbiAgICAgIC50eCgnY3JlYXRlLWNsYXNzJywgYXN5bmMgdCA9PiB7XG4gICAgICAgIGF3YWl0IHRoaXMuY3JlYXRlVGFibGUoY2xhc3NOYW1lLCBzY2hlbWEsIHQpO1xuICAgICAgICBhd2FpdCB0Lm5vbmUoXG4gICAgICAgICAgJ0lOU0VSVCBJTlRPIFwiX1NDSEVNQVwiIChcImNsYXNzTmFtZVwiLCBcInNjaGVtYVwiLCBcImlzUGFyc2VDbGFzc1wiKSBWQUxVRVMgKCQ8Y2xhc3NOYW1lPiwgJDxzY2hlbWE+LCB0cnVlKScsXG4gICAgICAgICAgeyBjbGFzc05hbWUsIHNjaGVtYSB9XG4gICAgICAgICk7XG4gICAgICAgIGF3YWl0IHRoaXMuc2V0SW5kZXhlc1dpdGhTY2hlbWFGb3JtYXQoY2xhc3NOYW1lLCBzY2hlbWEuaW5kZXhlcywge30sIHNjaGVtYS5maWVsZHMsIHQpO1xuICAgICAgICByZXR1cm4gdG9QYXJzZVNjaGVtYShzY2hlbWEpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4ge1xuICAgICAgICBpZiAoZXJyLmNvZGUgPT09IFBvc3RncmVzVW5pcXVlSW5kZXhWaW9sYXRpb25FcnJvciAmJiBlcnIuZGV0YWlsLmluY2x1ZGVzKGNsYXNzTmFtZSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFLCBgQ2xhc3MgJHtjbGFzc05hbWV9IGFscmVhZHkgZXhpc3RzLmApO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gSnVzdCBjcmVhdGUgYSB0YWJsZSwgZG8gbm90IGluc2VydCBpbiBzY2hlbWFcbiAgYXN5bmMgY3JlYXRlVGFibGUoY2xhc3NOYW1lOiBzdHJpbmcsIHNjaGVtYTogU2NoZW1hVHlwZSwgY29ubjogYW55KSB7XG4gICAgY29ubiA9IGNvbm4gfHwgdGhpcy5fY2xpZW50O1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGRlYnVnKCdjcmVhdGVUYWJsZScsIGNsYXNzTmFtZSwgc2NoZW1hKTtcbiAgICBjb25zdCB2YWx1ZXNBcnJheSA9IFtdO1xuICAgIGNvbnN0IHBhdHRlcm5zQXJyYXkgPSBbXTtcbiAgICBjb25zdCBmaWVsZHMgPSBPYmplY3QuYXNzaWduKHt9LCBzY2hlbWEuZmllbGRzKTtcbiAgICBpZiAoY2xhc3NOYW1lID09PSAnX1VzZXInKSB7XG4gICAgICBmaWVsZHMuX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0ID0geyB0eXBlOiAnRGF0ZScgfTtcbiAgICAgIGZpZWxkcy5fZW1haWxfdmVyaWZ5X3Rva2VuID0geyB0eXBlOiAnU3RyaW5nJyB9O1xuICAgICAgZmllbGRzLl9hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCA9IHsgdHlwZTogJ0RhdGUnIH07XG4gICAgICBmaWVsZHMuX2ZhaWxlZF9sb2dpbl9jb3VudCA9IHsgdHlwZTogJ051bWJlcicgfTtcbiAgICAgIGZpZWxkcy5fcGVyaXNoYWJsZV90b2tlbiA9IHsgdHlwZTogJ1N0cmluZycgfTtcbiAgICAgIGZpZWxkcy5fcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0ID0geyB0eXBlOiAnRGF0ZScgfTtcbiAgICAgIGZpZWxkcy5fcGFzc3dvcmRfY2hhbmdlZF9hdCA9IHsgdHlwZTogJ0RhdGUnIH07XG4gICAgICBmaWVsZHMuX3Bhc3N3b3JkX2hpc3RvcnkgPSB7IHR5cGU6ICdBcnJheScgfTtcbiAgICB9XG4gICAgbGV0IGluZGV4ID0gMjtcbiAgICBjb25zdCByZWxhdGlvbnMgPSBbXTtcbiAgICBPYmplY3Qua2V5cyhmaWVsZHMpLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgIGNvbnN0IHBhcnNlVHlwZSA9IGZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgLy8gU2tpcCB3aGVuIGl0J3MgYSByZWxhdGlvblxuICAgICAgLy8gV2UnbGwgY3JlYXRlIHRoZSB0YWJsZXMgbGF0ZXJcbiAgICAgIGlmIChwYXJzZVR5cGUudHlwZSA9PT0gJ1JlbGF0aW9uJykge1xuICAgICAgICByZWxhdGlvbnMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoWydfcnBlcm0nLCAnX3dwZXJtJ10uaW5kZXhPZihmaWVsZE5hbWUpID49IDApIHtcbiAgICAgICAgcGFyc2VUeXBlLmNvbnRlbnRzID0geyB0eXBlOiAnU3RyaW5nJyB9O1xuICAgICAgfVxuICAgICAgdmFsdWVzQXJyYXkucHVzaChmaWVsZE5hbWUpO1xuICAgICAgdmFsdWVzQXJyYXkucHVzaChwYXJzZVR5cGVUb1Bvc3RncmVzVHlwZShwYXJzZVR5cGUpKTtcbiAgICAgIHBhdHRlcm5zQXJyYXkucHVzaChgJCR7aW5kZXh9Om5hbWUgJCR7aW5kZXggKyAxfTpyYXdgKTtcbiAgICAgIGlmIChmaWVsZE5hbWUgPT09ICdvYmplY3RJZCcpIHtcbiAgICAgICAgcGF0dGVybnNBcnJheS5wdXNoKGBQUklNQVJZIEtFWSAoJCR7aW5kZXh9Om5hbWUpYCk7XG4gICAgICB9XG4gICAgICBpbmRleCA9IGluZGV4ICsgMjtcbiAgICB9KTtcbiAgICBjb25zdCBxcyA9IGBDUkVBVEUgVEFCTEUgSUYgTk9UIEVYSVNUUyAkMTpuYW1lICgke3BhdHRlcm5zQXJyYXkuam9pbigpfSlgO1xuICAgIGNvbnN0IHZhbHVlcyA9IFtjbGFzc05hbWUsIC4uLnZhbHVlc0FycmF5XTtcblxuICAgIGRlYnVnKHFzLCB2YWx1ZXMpO1xuICAgIHJldHVybiBjb25uLnRhc2soJ2NyZWF0ZS10YWJsZScsIGFzeW5jIHQgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc2VsZi5fZW5zdXJlU2NoZW1hQ29sbGVjdGlvbkV4aXN0cyh0KTtcbiAgICAgICAgYXdhaXQgdC5ub25lKHFzLCB2YWx1ZXMpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgIT09IFBvc3RncmVzRHVwbGljYXRlUmVsYXRpb25FcnJvcikge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIC8vIEVMU0U6IFRhYmxlIGFscmVhZHkgZXhpc3RzLCBtdXN0IGhhdmUgYmVlbiBjcmVhdGVkIGJ5IGEgZGlmZmVyZW50IHJlcXVlc3QuIElnbm9yZSB0aGUgZXJyb3IuXG4gICAgICB9XG4gICAgICBhd2FpdCB0LnR4KCdjcmVhdGUtdGFibGUtdHgnLCB0eCA9PiB7XG4gICAgICAgIHJldHVybiB0eC5iYXRjaChcbiAgICAgICAgICByZWxhdGlvbnMubWFwKGZpZWxkTmFtZSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdHgubm9uZShcbiAgICAgICAgICAgICAgJ0NSRUFURSBUQUJMRSBJRiBOT1QgRVhJU1RTICQ8am9pblRhYmxlOm5hbWU+IChcInJlbGF0ZWRJZFwiIHZhckNoYXIoMTIwKSwgXCJvd25pbmdJZFwiIHZhckNoYXIoMTIwKSwgUFJJTUFSWSBLRVkoXCJyZWxhdGVkSWRcIiwgXCJvd25pbmdJZFwiKSApJyxcbiAgICAgICAgICAgICAgeyBqb2luVGFibGU6IGBfSm9pbjoke2ZpZWxkTmFtZX06JHtjbGFzc05hbWV9YCB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHNjaGVtYVVwZ3JhZGUoY2xhc3NOYW1lOiBzdHJpbmcsIHNjaGVtYTogU2NoZW1hVHlwZSwgY29ubjogYW55KSB7XG4gICAgZGVidWcoJ3NjaGVtYVVwZ3JhZGUnLCB7IGNsYXNzTmFtZSwgc2NoZW1hIH0pO1xuICAgIGNvbm4gPSBjb25uIHx8IHRoaXMuX2NsaWVudDtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGF3YWl0IGNvbm4udHgoJ3NjaGVtYS11cGdyYWRlJywgYXN5bmMgdCA9PiB7XG4gICAgICBjb25zdCBjb2x1bW5zID0gYXdhaXQgdC5tYXAoXG4gICAgICAgICdTRUxFQ1QgY29sdW1uX25hbWUgRlJPTSBpbmZvcm1hdGlvbl9zY2hlbWEuY29sdW1ucyBXSEVSRSB0YWJsZV9uYW1lID0gJDxjbGFzc05hbWU+JyxcbiAgICAgICAgeyBjbGFzc05hbWUgfSxcbiAgICAgICAgYSA9PiBhLmNvbHVtbl9uYW1lXG4gICAgICApO1xuICAgICAgY29uc3QgbmV3Q29sdW1ucyA9IE9iamVjdC5rZXlzKHNjaGVtYS5maWVsZHMpXG4gICAgICAgIC5maWx0ZXIoaXRlbSA9PiBjb2x1bW5zLmluZGV4T2YoaXRlbSkgPT09IC0xKVxuICAgICAgICAubWFwKGZpZWxkTmFtZSA9PlxuICAgICAgICAgIHNlbGYuYWRkRmllbGRJZk5vdEV4aXN0cyhjbGFzc05hbWUsIGZpZWxkTmFtZSwgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLCB0KVxuICAgICAgICApO1xuXG4gICAgICBhd2FpdCB0LmJhdGNoKG5ld0NvbHVtbnMpO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgYWRkRmllbGRJZk5vdEV4aXN0cyhjbGFzc05hbWU6IHN0cmluZywgZmllbGROYW1lOiBzdHJpbmcsIHR5cGU6IGFueSwgY29ubjogYW55KSB7XG4gICAgLy8gVE9ETzogTXVzdCBiZSByZXZpc2VkIGZvciBpbnZhbGlkIGxvZ2ljLi4uXG4gICAgZGVidWcoJ2FkZEZpZWxkSWZOb3RFeGlzdHMnLCB7IGNsYXNzTmFtZSwgZmllbGROYW1lLCB0eXBlIH0pO1xuICAgIGNvbm4gPSBjb25uIHx8IHRoaXMuX2NsaWVudDtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBhd2FpdCBjb25uLnR4KCdhZGQtZmllbGQtaWYtbm90LWV4aXN0cycsIGFzeW5jIHQgPT4ge1xuICAgICAgaWYgKHR5cGUudHlwZSAhPT0gJ1JlbGF0aW9uJykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHQubm9uZShcbiAgICAgICAgICAgICdBTFRFUiBUQUJMRSAkPGNsYXNzTmFtZTpuYW1lPiBBREQgQ09MVU1OIElGIE5PVCBFWElTVFMgJDxmaWVsZE5hbWU6bmFtZT4gJDxwb3N0Z3Jlc1R5cGU6cmF3PicsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgZmllbGROYW1lLFxuICAgICAgICAgICAgICBwb3N0Z3Jlc1R5cGU6IHBhcnNlVHlwZVRvUG9zdGdyZXNUeXBlKHR5cGUpLFxuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IFBvc3RncmVzUmVsYXRpb25Eb2VzTm90RXhpc3RFcnJvcikge1xuICAgICAgICAgICAgcmV0dXJuIHNlbGYuY3JlYXRlQ2xhc3MoY2xhc3NOYW1lLCB7IGZpZWxkczogeyBbZmllbGROYW1lXTogdHlwZSB9IH0sIHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZXJyb3IuY29kZSAhPT0gUG9zdGdyZXNEdXBsaWNhdGVDb2x1bW5FcnJvcikge1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIENvbHVtbiBhbHJlYWR5IGV4aXN0cywgY3JlYXRlZCBieSBvdGhlciByZXF1ZXN0LiBDYXJyeSBvbiB0byBzZWUgaWYgaXQncyB0aGUgcmlnaHQgdHlwZS5cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXdhaXQgdC5ub25lKFxuICAgICAgICAgICdDUkVBVEUgVEFCTEUgSUYgTk9UIEVYSVNUUyAkPGpvaW5UYWJsZTpuYW1lPiAoXCJyZWxhdGVkSWRcIiB2YXJDaGFyKDEyMCksIFwib3duaW5nSWRcIiB2YXJDaGFyKDEyMCksIFBSSU1BUlkgS0VZKFwicmVsYXRlZElkXCIsIFwib3duaW5nSWRcIikgKScsXG4gICAgICAgICAgeyBqb2luVGFibGU6IGBfSm9pbjoke2ZpZWxkTmFtZX06JHtjbGFzc05hbWV9YCB9XG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHQuYW55KFxuICAgICAgICAnU0VMRUNUIFwic2NoZW1hXCIgRlJPTSBcIl9TQ0hFTUFcIiBXSEVSRSBcImNsYXNzTmFtZVwiID0gJDxjbGFzc05hbWU+IGFuZCAoXCJzY2hlbWFcIjo6anNvbi0+XFwnZmllbGRzXFwnLT4kPGZpZWxkTmFtZT4pIGlzIG5vdCBudWxsJyxcbiAgICAgICAgeyBjbGFzc05hbWUsIGZpZWxkTmFtZSB9XG4gICAgICApO1xuXG4gICAgICBpZiAocmVzdWx0WzBdKSB7XG4gICAgICAgIHRocm93ICdBdHRlbXB0ZWQgdG8gYWRkIGEgZmllbGQgdGhhdCBhbHJlYWR5IGV4aXN0cyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBwYXRoID0gYHtmaWVsZHMsJHtmaWVsZE5hbWV9fWA7XG4gICAgICAgIGF3YWl0IHQubm9uZShcbiAgICAgICAgICAnVVBEQVRFIFwiX1NDSEVNQVwiIFNFVCBcInNjaGVtYVwiPWpzb25iX3NldChcInNjaGVtYVwiLCAkPHBhdGg+LCAkPHR5cGU+KSAgV0hFUkUgXCJjbGFzc05hbWVcIj0kPGNsYXNzTmFtZT4nLFxuICAgICAgICAgIHsgcGF0aCwgdHlwZSwgY2xhc3NOYW1lIH1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIERyb3BzIGEgY29sbGVjdGlvbi4gUmVzb2x2ZXMgd2l0aCB0cnVlIGlmIGl0IHdhcyBhIFBhcnNlIFNjaGVtYSAoZWcuIF9Vc2VyLCBDdXN0b20sIGV0Yy4pXG4gIC8vIGFuZCByZXNvbHZlcyB3aXRoIGZhbHNlIGlmIGl0IHdhc24ndCAoZWcuIGEgam9pbiB0YWJsZSkuIFJlamVjdHMgaWYgZGVsZXRpb24gd2FzIGltcG9zc2libGUuXG4gIGFzeW5jIGRlbGV0ZUNsYXNzKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3Qgb3BlcmF0aW9ucyA9IFtcbiAgICAgIHsgcXVlcnk6IGBEUk9QIFRBQkxFIElGIEVYSVNUUyAkMTpuYW1lYCwgdmFsdWVzOiBbY2xhc3NOYW1lXSB9LFxuICAgICAge1xuICAgICAgICBxdWVyeTogYERFTEVURSBGUk9NIFwiX1NDSEVNQVwiIFdIRVJFIFwiY2xhc3NOYW1lXCIgPSAkMWAsXG4gICAgICAgIHZhbHVlczogW2NsYXNzTmFtZV0sXG4gICAgICB9LFxuICAgIF07XG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudFxuICAgICAgLnR4KHQgPT4gdC5ub25lKHRoaXMuX3BncC5oZWxwZXJzLmNvbmNhdChvcGVyYXRpb25zKSkpXG4gICAgICAudGhlbigoKSA9PiBjbGFzc05hbWUuaW5kZXhPZignX0pvaW46JykgIT0gMCk7IC8vIHJlc29sdmVzIHdpdGggZmFsc2Ugd2hlbiBfSm9pbiB0YWJsZVxuICB9XG5cbiAgLy8gRGVsZXRlIGFsbCBkYXRhIGtub3duIHRvIHRoaXMgYWRhcHRlci4gVXNlZCBmb3IgdGVzdGluZy5cbiAgYXN5bmMgZGVsZXRlQWxsQ2xhc3NlcygpIHtcbiAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICBjb25zdCBoZWxwZXJzID0gdGhpcy5fcGdwLmhlbHBlcnM7XG4gICAgZGVidWcoJ2RlbGV0ZUFsbENsYXNzZXMnKTtcblxuICAgIGF3YWl0IHRoaXMuX2NsaWVudFxuICAgICAgLnRhc2soJ2RlbGV0ZS1hbGwtY2xhc3NlcycsIGFzeW5jIHQgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0LmFueSgnU0VMRUNUICogRlJPTSBcIl9TQ0hFTUFcIicpO1xuICAgICAgICAgIGNvbnN0IGpvaW5zID0gcmVzdWx0cy5yZWR1Y2UoKGxpc3Q6IEFycmF5PHN0cmluZz4sIHNjaGVtYTogYW55KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gbGlzdC5jb25jYXQoam9pblRhYmxlc0ZvclNjaGVtYShzY2hlbWEuc2NoZW1hKSk7XG4gICAgICAgICAgfSwgW10pO1xuICAgICAgICAgIGNvbnN0IGNsYXNzZXMgPSBbXG4gICAgICAgICAgICAnX1NDSEVNQScsXG4gICAgICAgICAgICAnX1B1c2hTdGF0dXMnLFxuICAgICAgICAgICAgJ19Kb2JTdGF0dXMnLFxuICAgICAgICAgICAgJ19Kb2JTY2hlZHVsZScsXG4gICAgICAgICAgICAnX0hvb2tzJyxcbiAgICAgICAgICAgICdfR2xvYmFsQ29uZmlnJyxcbiAgICAgICAgICAgICdfR3JhcGhRTENvbmZpZycsXG4gICAgICAgICAgICAnX0F1ZGllbmNlJyxcbiAgICAgICAgICAgICdfSWRlbXBvdGVuY3knLFxuICAgICAgICAgICAgLi4ucmVzdWx0cy5tYXAocmVzdWx0ID0+IHJlc3VsdC5jbGFzc05hbWUpLFxuICAgICAgICAgICAgLi4uam9pbnMsXG4gICAgICAgICAgXTtcbiAgICAgICAgICBjb25zdCBxdWVyaWVzID0gY2xhc3Nlcy5tYXAoY2xhc3NOYW1lID0+ICh7XG4gICAgICAgICAgICBxdWVyeTogJ0RST1AgVEFCTEUgSUYgRVhJU1RTICQ8Y2xhc3NOYW1lOm5hbWU+JyxcbiAgICAgICAgICAgIHZhbHVlczogeyBjbGFzc05hbWUgfSxcbiAgICAgICAgICB9KSk7XG4gICAgICAgICAgYXdhaXQgdC50eCh0eCA9PiB0eC5ub25lKGhlbHBlcnMuY29uY2F0KHF1ZXJpZXMpKSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgaWYgKGVycm9yLmNvZGUgIT09IFBvc3RncmVzUmVsYXRpb25Eb2VzTm90RXhpc3RFcnJvcikge1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIE5vIF9TQ0hFTUEgY29sbGVjdGlvbi4gRG9uJ3QgZGVsZXRlIGFueXRoaW5nLlxuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBkZWJ1ZyhgZGVsZXRlQWxsQ2xhc3NlcyBkb25lIGluICR7bmV3IERhdGUoKS5nZXRUaW1lKCkgLSBub3d9YCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8vIFJlbW92ZSB0aGUgY29sdW1uIGFuZCBhbGwgdGhlIGRhdGEuIEZvciBSZWxhdGlvbnMsIHRoZSBfSm9pbiBjb2xsZWN0aW9uIGlzIGhhbmRsZWRcbiAgLy8gc3BlY2lhbGx5LCB0aGlzIGZ1bmN0aW9uIGRvZXMgbm90IGRlbGV0ZSBfSm9pbiBjb2x1bW5zLiBJdCBzaG91bGQsIGhvd2V2ZXIsIGluZGljYXRlXG4gIC8vIHRoYXQgdGhlIHJlbGF0aW9uIGZpZWxkcyBkb2VzIG5vdCBleGlzdCBhbnltb3JlLiBJbiBtb25nbywgdGhpcyBtZWFucyByZW1vdmluZyBpdCBmcm9tXG4gIC8vIHRoZSBfU0NIRU1BIGNvbGxlY3Rpb24uICBUaGVyZSBzaG91bGQgYmUgbm8gYWN0dWFsIGRhdGEgaW4gdGhlIGNvbGxlY3Rpb24gdW5kZXIgdGhlIHNhbWUgbmFtZVxuICAvLyBhcyB0aGUgcmVsYXRpb24gY29sdW1uLCBzbyBpdCdzIGZpbmUgdG8gYXR0ZW1wdCB0byBkZWxldGUgaXQuIElmIHRoZSBmaWVsZHMgbGlzdGVkIHRvIGJlXG4gIC8vIGRlbGV0ZWQgZG8gbm90IGV4aXN0LCB0aGlzIGZ1bmN0aW9uIHNob3VsZCByZXR1cm4gc3VjY2Vzc2Z1bGx5IGFueXdheXMuIENoZWNraW5nIGZvclxuICAvLyBhdHRlbXB0cyB0byBkZWxldGUgbm9uLWV4aXN0ZW50IGZpZWxkcyBpcyB0aGUgcmVzcG9uc2liaWxpdHkgb2YgUGFyc2UgU2VydmVyLlxuXG4gIC8vIFRoaXMgZnVuY3Rpb24gaXMgbm90IG9ibGlnYXRlZCB0byBkZWxldGUgZmllbGRzIGF0b21pY2FsbHkuIEl0IGlzIGdpdmVuIHRoZSBmaWVsZFxuICAvLyBuYW1lcyBpbiBhIGxpc3Qgc28gdGhhdCBkYXRhYmFzZXMgdGhhdCBhcmUgY2FwYWJsZSBvZiBkZWxldGluZyBmaWVsZHMgYXRvbWljYWxseVxuICAvLyBtYXkgZG8gc28uXG5cbiAgLy8gUmV0dXJucyBhIFByb21pc2UuXG4gIGFzeW5jIGRlbGV0ZUZpZWxkcyhjbGFzc05hbWU6IHN0cmluZywgc2NoZW1hOiBTY2hlbWFUeXBlLCBmaWVsZE5hbWVzOiBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGRlYnVnKCdkZWxldGVGaWVsZHMnLCBjbGFzc05hbWUsIGZpZWxkTmFtZXMpO1xuICAgIGZpZWxkTmFtZXMgPSBmaWVsZE5hbWVzLnJlZHVjZSgobGlzdDogQXJyYXk8c3RyaW5nPiwgZmllbGROYW1lOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IGZpZWxkID0gc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgaWYgKGZpZWxkLnR5cGUgIT09ICdSZWxhdGlvbicpIHtcbiAgICAgICAgbGlzdC5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICB9XG4gICAgICBkZWxldGUgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgcmV0dXJuIGxpc3Q7XG4gICAgfSwgW10pO1xuXG4gICAgY29uc3QgdmFsdWVzID0gW2NsYXNzTmFtZSwgLi4uZmllbGROYW1lc107XG4gICAgY29uc3QgY29sdW1ucyA9IGZpZWxkTmFtZXNcbiAgICAgIC5tYXAoKG5hbWUsIGlkeCkgPT4ge1xuICAgICAgICByZXR1cm4gYCQke2lkeCArIDJ9Om5hbWVgO1xuICAgICAgfSlcbiAgICAgIC5qb2luKCcsIERST1AgQ09MVU1OJyk7XG5cbiAgICBhd2FpdCB0aGlzLl9jbGllbnQudHgoJ2RlbGV0ZS1maWVsZHMnLCBhc3luYyB0ID0+IHtcbiAgICAgIGF3YWl0IHQubm9uZSgnVVBEQVRFIFwiX1NDSEVNQVwiIFNFVCBcInNjaGVtYVwiID0gJDxzY2hlbWE+IFdIRVJFIFwiY2xhc3NOYW1lXCIgPSAkPGNsYXNzTmFtZT4nLCB7XG4gICAgICAgIHNjaGVtYSxcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgfSk7XG4gICAgICBpZiAodmFsdWVzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgYXdhaXQgdC5ub25lKGBBTFRFUiBUQUJMRSAkMTpuYW1lIERST1AgQ09MVU1OIElGIEVYSVNUUyAke2NvbHVtbnN9YCwgdmFsdWVzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIFJldHVybiBhIHByb21pc2UgZm9yIGFsbCBzY2hlbWFzIGtub3duIHRvIHRoaXMgYWRhcHRlciwgaW4gUGFyc2UgZm9ybWF0LiBJbiBjYXNlIHRoZVxuICAvLyBzY2hlbWFzIGNhbm5vdCBiZSByZXRyaWV2ZWQsIHJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVqZWN0cy4gUmVxdWlyZW1lbnRzIGZvciB0aGVcbiAgLy8gcmVqZWN0aW9uIHJlYXNvbiBhcmUgVEJELlxuICBhc3luYyBnZXRBbGxDbGFzc2VzKCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIHJldHVybiB0aGlzLl9jbGllbnQudGFzaygnZ2V0LWFsbC1jbGFzc2VzJywgYXN5bmMgdCA9PiB7XG4gICAgICBhd2FpdCBzZWxmLl9lbnN1cmVTY2hlbWFDb2xsZWN0aW9uRXhpc3RzKHQpO1xuICAgICAgcmV0dXJuIGF3YWl0IHQubWFwKCdTRUxFQ1QgKiBGUk9NIFwiX1NDSEVNQVwiJywgbnVsbCwgcm93ID0+XG4gICAgICAgIHRvUGFyc2VTY2hlbWEoeyBjbGFzc05hbWU6IHJvdy5jbGFzc05hbWUsIC4uLnJvdy5zY2hlbWEgfSlcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBSZXR1cm4gYSBwcm9taXNlIGZvciB0aGUgc2NoZW1hIHdpdGggdGhlIGdpdmVuIG5hbWUsIGluIFBhcnNlIGZvcm1hdC4gSWZcbiAgLy8gdGhpcyBhZGFwdGVyIGRvZXNuJ3Qga25vdyBhYm91dCB0aGUgc2NoZW1hLCByZXR1cm4gYSBwcm9taXNlIHRoYXQgcmVqZWN0cyB3aXRoXG4gIC8vIHVuZGVmaW5lZCBhcyB0aGUgcmVhc29uLlxuICBhc3luYyBnZXRDbGFzcyhjbGFzc05hbWU6IHN0cmluZykge1xuICAgIGRlYnVnKCdnZXRDbGFzcycsIGNsYXNzTmFtZSk7XG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudFxuICAgICAgLmFueSgnU0VMRUNUICogRlJPTSBcIl9TQ0hFTUFcIiBXSEVSRSBcImNsYXNzTmFtZVwiID0gJDxjbGFzc05hbWU+Jywge1xuICAgICAgICBjbGFzc05hbWUsXG4gICAgICB9KVxuICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdC5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgICB0aHJvdyB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdFswXS5zY2hlbWE7XG4gICAgICB9KVxuICAgICAgLnRoZW4odG9QYXJzZVNjaGVtYSk7XG4gIH1cblxuICAvLyBUT0RPOiByZW1vdmUgdGhlIG1vbmdvIGZvcm1hdCBkZXBlbmRlbmN5IGluIHRoZSByZXR1cm4gdmFsdWVcbiAgYXN5bmMgY3JlYXRlT2JqZWN0KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBvYmplY3Q6IGFueSxcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbjogP2FueVxuICApIHtcbiAgICBkZWJ1ZygnY3JlYXRlT2JqZWN0JywgY2xhc3NOYW1lLCBvYmplY3QpO1xuICAgIGxldCBjb2x1bW5zQXJyYXkgPSBbXTtcbiAgICBjb25zdCB2YWx1ZXNBcnJheSA9IFtdO1xuICAgIHNjaGVtYSA9IHRvUG9zdGdyZXNTY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBnZW9Qb2ludHMgPSB7fTtcblxuICAgIG9iamVjdCA9IGhhbmRsZURvdEZpZWxkcyhvYmplY3QpO1xuXG4gICAgdmFsaWRhdGVLZXlzKG9iamVjdCk7XG5cbiAgICBPYmplY3Qua2V5cyhvYmplY3QpLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2YXIgYXV0aERhdGFNYXRjaCA9IGZpZWxkTmFtZS5tYXRjaCgvXl9hdXRoX2RhdGFfKFthLXpBLVowLTlfXSspJC8pO1xuICAgICAgaWYgKGF1dGhEYXRhTWF0Y2gpIHtcbiAgICAgICAgdmFyIHByb3ZpZGVyID0gYXV0aERhdGFNYXRjaFsxXTtcbiAgICAgICAgb2JqZWN0WydhdXRoRGF0YSddID0gb2JqZWN0WydhdXRoRGF0YSddIHx8IHt9O1xuICAgICAgICBvYmplY3RbJ2F1dGhEYXRhJ11bcHJvdmlkZXJdID0gb2JqZWN0W2ZpZWxkTmFtZV07XG4gICAgICAgIGRlbGV0ZSBvYmplY3RbZmllbGROYW1lXTtcbiAgICAgICAgZmllbGROYW1lID0gJ2F1dGhEYXRhJztcbiAgICAgIH1cblxuICAgICAgY29sdW1uc0FycmF5LnB1c2goZmllbGROYW1lKTtcbiAgICAgIGlmICghc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdICYmIGNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZmllbGROYW1lID09PSAnX2VtYWlsX3ZlcmlmeV90b2tlbicgfHxcbiAgICAgICAgICBmaWVsZE5hbWUgPT09ICdfZmFpbGVkX2xvZ2luX2NvdW50JyB8fFxuICAgICAgICAgIGZpZWxkTmFtZSA9PT0gJ19wZXJpc2hhYmxlX3Rva2VuJyB8fFxuICAgICAgICAgIGZpZWxkTmFtZSA9PT0gJ19wYXNzd29yZF9oaXN0b3J5J1xuICAgICAgICApIHtcbiAgICAgICAgICB2YWx1ZXNBcnJheS5wdXNoKG9iamVjdFtmaWVsZE5hbWVdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmaWVsZE5hbWUgPT09ICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnKSB7XG4gICAgICAgICAgaWYgKG9iamVjdFtmaWVsZE5hbWVdKSB7XG4gICAgICAgICAgICB2YWx1ZXNBcnJheS5wdXNoKG9iamVjdFtmaWVsZE5hbWVdLmlzbyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhbHVlc0FycmF5LnB1c2gobnVsbCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgIGZpZWxkTmFtZSA9PT0gJ19hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCcgfHxcbiAgICAgICAgICBmaWVsZE5hbWUgPT09ICdfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0JyB8fFxuICAgICAgICAgIGZpZWxkTmFtZSA9PT0gJ19wYXNzd29yZF9jaGFuZ2VkX2F0J1xuICAgICAgICApIHtcbiAgICAgICAgICBpZiAob2JqZWN0W2ZpZWxkTmFtZV0pIHtcbiAgICAgICAgICAgIHZhbHVlc0FycmF5LnB1c2gob2JqZWN0W2ZpZWxkTmFtZV0uaXNvKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsdWVzQXJyYXkucHVzaChudWxsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc3dpdGNoIChzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSkge1xuICAgICAgICBjYXNlICdEYXRlJzpcbiAgICAgICAgICBpZiAob2JqZWN0W2ZpZWxkTmFtZV0pIHtcbiAgICAgICAgICAgIHZhbHVlc0FycmF5LnB1c2gob2JqZWN0W2ZpZWxkTmFtZV0uaXNvKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsdWVzQXJyYXkucHVzaChudWxsKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1BvaW50ZXInOlxuICAgICAgICAgIHZhbHVlc0FycmF5LnB1c2gob2JqZWN0W2ZpZWxkTmFtZV0ub2JqZWN0SWQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdBcnJheSc6XG4gICAgICAgICAgaWYgKFsnX3JwZXJtJywgJ193cGVybSddLmluZGV4T2YoZmllbGROYW1lKSA+PSAwKSB7XG4gICAgICAgICAgICB2YWx1ZXNBcnJheS5wdXNoKG9iamVjdFtmaWVsZE5hbWVdKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsdWVzQXJyYXkucHVzaChKU09OLnN0cmluZ2lmeShvYmplY3RbZmllbGROYW1lXSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnT2JqZWN0JzpcbiAgICAgICAgY2FzZSAnQnl0ZXMnOlxuICAgICAgICBjYXNlICdTdHJpbmcnOlxuICAgICAgICBjYXNlICdOdW1iZXInOlxuICAgICAgICBjYXNlICdCb29sZWFuJzpcbiAgICAgICAgICB2YWx1ZXNBcnJheS5wdXNoKG9iamVjdFtmaWVsZE5hbWVdKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnRmlsZSc6XG4gICAgICAgICAgdmFsdWVzQXJyYXkucHVzaChvYmplY3RbZmllbGROYW1lXS5uYW1lKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnUG9seWdvbic6IHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IGNvbnZlcnRQb2x5Z29uVG9TUUwob2JqZWN0W2ZpZWxkTmFtZV0uY29vcmRpbmF0ZXMpO1xuICAgICAgICAgIHZhbHVlc0FycmF5LnB1c2godmFsdWUpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ0dlb1BvaW50JzpcbiAgICAgICAgICAvLyBwb3AgdGhlIHBvaW50IGFuZCBwcm9jZXNzIGxhdGVyXG4gICAgICAgICAgZ2VvUG9pbnRzW2ZpZWxkTmFtZV0gPSBvYmplY3RbZmllbGROYW1lXTtcbiAgICAgICAgICBjb2x1bW5zQXJyYXkucG9wKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgYFR5cGUgJHtzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZX0gbm90IHN1cHBvcnRlZCB5ZXRgO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29sdW1uc0FycmF5ID0gY29sdW1uc0FycmF5LmNvbmNhdChPYmplY3Qua2V5cyhnZW9Qb2ludHMpKTtcbiAgICBjb25zdCBpbml0aWFsVmFsdWVzID0gdmFsdWVzQXJyYXkubWFwKCh2YWwsIGluZGV4KSA9PiB7XG4gICAgICBsZXQgdGVybWluYXRpb24gPSAnJztcbiAgICAgIGNvbnN0IGZpZWxkTmFtZSA9IGNvbHVtbnNBcnJheVtpbmRleF07XG4gICAgICBpZiAoWydfcnBlcm0nLCAnX3dwZXJtJ10uaW5kZXhPZihmaWVsZE5hbWUpID49IDApIHtcbiAgICAgICAgdGVybWluYXRpb24gPSAnOjp0ZXh0W10nO1xuICAgICAgfSBlbHNlIGlmIChzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiYgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdBcnJheScpIHtcbiAgICAgICAgdGVybWluYXRpb24gPSAnOjpqc29uYic7XG4gICAgICB9XG4gICAgICByZXR1cm4gYCQke2luZGV4ICsgMiArIGNvbHVtbnNBcnJheS5sZW5ndGh9JHt0ZXJtaW5hdGlvbn1gO1xuICAgIH0pO1xuICAgIGNvbnN0IGdlb1BvaW50c0luamVjdHMgPSBPYmplY3Qua2V5cyhnZW9Qb2ludHMpLm1hcChrZXkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSBnZW9Qb2ludHNba2V5XTtcbiAgICAgIHZhbHVlc0FycmF5LnB1c2godmFsdWUubG9uZ2l0dWRlLCB2YWx1ZS5sYXRpdHVkZSk7XG4gICAgICBjb25zdCBsID0gdmFsdWVzQXJyYXkubGVuZ3RoICsgY29sdW1uc0FycmF5Lmxlbmd0aDtcbiAgICAgIHJldHVybiBgUE9JTlQoJCR7bH0sICQke2wgKyAxfSlgO1xuICAgIH0pO1xuXG4gICAgY29uc3QgY29sdW1uc1BhdHRlcm4gPSBjb2x1bW5zQXJyYXkubWFwKChjb2wsIGluZGV4KSA9PiBgJCR7aW5kZXggKyAyfTpuYW1lYCkuam9pbigpO1xuICAgIGNvbnN0IHZhbHVlc1BhdHRlcm4gPSBpbml0aWFsVmFsdWVzLmNvbmNhdChnZW9Qb2ludHNJbmplY3RzKS5qb2luKCk7XG5cbiAgICBjb25zdCBxcyA9IGBJTlNFUlQgSU5UTyAkMTpuYW1lICgke2NvbHVtbnNQYXR0ZXJufSkgVkFMVUVTICgke3ZhbHVlc1BhdHRlcm59KWA7XG4gICAgY29uc3QgdmFsdWVzID0gW2NsYXNzTmFtZSwgLi4uY29sdW1uc0FycmF5LCAuLi52YWx1ZXNBcnJheV07XG4gICAgZGVidWcocXMsIHZhbHVlcyk7XG4gICAgY29uc3QgcHJvbWlzZSA9ICh0cmFuc2FjdGlvbmFsU2Vzc2lvbiA/IHRyYW5zYWN0aW9uYWxTZXNzaW9uLnQgOiB0aGlzLl9jbGllbnQpXG4gICAgICAubm9uZShxcywgdmFsdWVzKVxuICAgICAgLnRoZW4oKCkgPT4gKHsgb3BzOiBbb2JqZWN0XSB9KSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvci5jb2RlID09PSBQb3N0Z3Jlc1VuaXF1ZUluZGV4VmlvbGF0aW9uRXJyb3IpIHtcbiAgICAgICAgICBjb25zdCBlcnIgPSBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUsXG4gICAgICAgICAgICAnQSBkdXBsaWNhdGUgdmFsdWUgZm9yIGEgZmllbGQgd2l0aCB1bmlxdWUgdmFsdWVzIHdhcyBwcm92aWRlZCdcbiAgICAgICAgICApO1xuICAgICAgICAgIGVyci51bmRlcmx5aW5nRXJyb3IgPSBlcnJvcjtcbiAgICAgICAgICBpZiAoZXJyb3IuY29uc3RyYWludCkge1xuICAgICAgICAgICAgY29uc3QgbWF0Y2hlcyA9IGVycm9yLmNvbnN0cmFpbnQubWF0Y2goL3VuaXF1ZV8oW2EtekEtWl0rKS8pO1xuICAgICAgICAgICAgaWYgKG1hdGNoZXMgJiYgQXJyYXkuaXNBcnJheShtYXRjaGVzKSkge1xuICAgICAgICAgICAgICBlcnIudXNlckluZm8gPSB7IGR1cGxpY2F0ZWRfZmllbGQ6IG1hdGNoZXNbMV0gfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgZXJyb3IgPSBlcnI7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcbiAgICBpZiAodHJhbnNhY3Rpb25hbFNlc3Npb24pIHtcbiAgICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uLmJhdGNoLnB1c2gocHJvbWlzZSk7XG4gICAgfVxuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgLy8gUmVtb3ZlIGFsbCBvYmplY3RzIHRoYXQgbWF0Y2ggdGhlIGdpdmVuIFBhcnNlIFF1ZXJ5LlxuICAvLyBJZiBubyBvYmplY3RzIG1hdGNoLCByZWplY3Qgd2l0aCBPQkpFQ1RfTk9UX0ZPVU5ELiBJZiBvYmplY3RzIGFyZSBmb3VuZCBhbmQgZGVsZXRlZCwgcmVzb2x2ZSB3aXRoIHVuZGVmaW5lZC5cbiAgLy8gSWYgdGhlcmUgaXMgc29tZSBvdGhlciBlcnJvciwgcmVqZWN0IHdpdGggSU5URVJOQUxfU0VSVkVSX0VSUk9SLlxuICBhc3luYyBkZWxldGVPYmplY3RzQnlRdWVyeShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbjogP2FueVxuICApIHtcbiAgICBkZWJ1ZygnZGVsZXRlT2JqZWN0c0J5UXVlcnknLCBjbGFzc05hbWUsIHF1ZXJ5KTtcbiAgICBjb25zdCB2YWx1ZXMgPSBbY2xhc3NOYW1lXTtcbiAgICBjb25zdCBpbmRleCA9IDI7XG4gICAgY29uc3Qgd2hlcmUgPSBidWlsZFdoZXJlQ2xhdXNlKHtcbiAgICAgIHNjaGVtYSxcbiAgICAgIGluZGV4LFxuICAgICAgcXVlcnksXG4gICAgICBjYXNlSW5zZW5zaXRpdmU6IGZhbHNlLFxuICAgIH0pO1xuICAgIHZhbHVlcy5wdXNoKC4uLndoZXJlLnZhbHVlcyk7XG4gICAgaWYgKE9iamVjdC5rZXlzKHF1ZXJ5KS5sZW5ndGggPT09IDApIHtcbiAgICAgIHdoZXJlLnBhdHRlcm4gPSAnVFJVRSc7XG4gICAgfVxuICAgIGNvbnN0IHFzID0gYFdJVEggZGVsZXRlZCBBUyAoREVMRVRFIEZST00gJDE6bmFtZSBXSEVSRSAke3doZXJlLnBhdHRlcm59IFJFVFVSTklORyAqKSBTRUxFQ1QgY291bnQoKikgRlJPTSBkZWxldGVkYDtcbiAgICBkZWJ1ZyhxcywgdmFsdWVzKTtcbiAgICBjb25zdCBwcm9taXNlID0gKHRyYW5zYWN0aW9uYWxTZXNzaW9uID8gdHJhbnNhY3Rpb25hbFNlc3Npb24udCA6IHRoaXMuX2NsaWVudClcbiAgICAgIC5vbmUocXMsIHZhbHVlcywgYSA9PiArYS5jb3VudClcbiAgICAgIC50aGVuKGNvdW50ID0+IHtcbiAgICAgICAgaWYgKGNvdW50ID09PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kLicpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBjb3VudDtcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvci5jb2RlICE9PSBQb3N0Z3Jlc1JlbGF0aW9uRG9lc05vdEV4aXN0RXJyb3IpIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICAvLyBFTFNFOiBEb24ndCBkZWxldGUgYW55dGhpbmcgaWYgZG9lc24ndCBleGlzdFxuICAgICAgfSk7XG4gICAgaWYgKHRyYW5zYWN0aW9uYWxTZXNzaW9uKSB7XG4gICAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbi5iYXRjaC5wdXNoKHByb21pc2UpO1xuICAgIH1cbiAgICByZXR1cm4gcHJvbWlzZTtcbiAgfVxuICAvLyBSZXR1cm4gdmFsdWUgbm90IGN1cnJlbnRseSB3ZWxsIHNwZWNpZmllZC5cbiAgYXN5bmMgZmluZE9uZUFuZFVwZGF0ZShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICB1cGRhdGU6IGFueSxcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbjogP2FueVxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIGRlYnVnKCdmaW5kT25lQW5kVXBkYXRlJywgY2xhc3NOYW1lLCBxdWVyeSwgdXBkYXRlKTtcbiAgICByZXR1cm4gdGhpcy51cGRhdGVPYmplY3RzQnlRdWVyeShjbGFzc05hbWUsIHNjaGVtYSwgcXVlcnksIHVwZGF0ZSwgdHJhbnNhY3Rpb25hbFNlc3Npb24pLnRoZW4oXG4gICAgICB2YWwgPT4gdmFsWzBdXG4gICAgKTtcbiAgfVxuXG4gIC8vIEFwcGx5IHRoZSB1cGRhdGUgdG8gYWxsIG9iamVjdHMgdGhhdCBtYXRjaCB0aGUgZ2l2ZW4gUGFyc2UgUXVlcnkuXG4gIGFzeW5jIHVwZGF0ZU9iamVjdHNCeVF1ZXJ5KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHVwZGF0ZTogYW55LFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICk6IFByb21pc2U8W2FueV0+IHtcbiAgICBkZWJ1ZygndXBkYXRlT2JqZWN0c0J5UXVlcnknLCBjbGFzc05hbWUsIHF1ZXJ5LCB1cGRhdGUpO1xuICAgIGNvbnN0IHVwZGF0ZVBhdHRlcm5zID0gW107XG4gICAgY29uc3QgdmFsdWVzID0gW2NsYXNzTmFtZV07XG4gICAgbGV0IGluZGV4ID0gMjtcbiAgICBzY2hlbWEgPSB0b1Bvc3RncmVzU2NoZW1hKHNjaGVtYSk7XG5cbiAgICBjb25zdCBvcmlnaW5hbFVwZGF0ZSA9IHsgLi4udXBkYXRlIH07XG5cbiAgICAvLyBTZXQgZmxhZyBmb3IgZG90IG5vdGF0aW9uIGZpZWxkc1xuICAgIGNvbnN0IGRvdE5vdGF0aW9uT3B0aW9ucyA9IHt9O1xuICAgIE9iamVjdC5rZXlzKHVwZGF0ZSkuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPiAtMSkge1xuICAgICAgICBjb25zdCBjb21wb25lbnRzID0gZmllbGROYW1lLnNwbGl0KCcuJyk7XG4gICAgICAgIGNvbnN0IGZpcnN0ID0gY29tcG9uZW50cy5zaGlmdCgpO1xuICAgICAgICBkb3ROb3RhdGlvbk9wdGlvbnNbZmlyc3RdID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRvdE5vdGF0aW9uT3B0aW9uc1tmaWVsZE5hbWVdID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdXBkYXRlID0gaGFuZGxlRG90RmllbGRzKHVwZGF0ZSk7XG4gICAgLy8gUmVzb2x2ZSBhdXRoRGF0YSBmaXJzdCxcbiAgICAvLyBTbyB3ZSBkb24ndCBlbmQgdXAgd2l0aCBtdWx0aXBsZSBrZXkgdXBkYXRlc1xuICAgIGZvciAoY29uc3QgZmllbGROYW1lIGluIHVwZGF0ZSkge1xuICAgICAgY29uc3QgYXV0aERhdGFNYXRjaCA9IGZpZWxkTmFtZS5tYXRjaCgvXl9hdXRoX2RhdGFfKFthLXpBLVowLTlfXSspJC8pO1xuICAgICAgaWYgKGF1dGhEYXRhTWF0Y2gpIHtcbiAgICAgICAgdmFyIHByb3ZpZGVyID0gYXV0aERhdGFNYXRjaFsxXTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB1cGRhdGVbZmllbGROYW1lXTtcbiAgICAgICAgZGVsZXRlIHVwZGF0ZVtmaWVsZE5hbWVdO1xuICAgICAgICB1cGRhdGVbJ2F1dGhEYXRhJ10gPSB1cGRhdGVbJ2F1dGhEYXRhJ10gfHwge307XG4gICAgICAgIHVwZGF0ZVsnYXV0aERhdGEnXVtwcm92aWRlcl0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBpbiB1cGRhdGUpIHtcbiAgICAgIGNvbnN0IGZpZWxkVmFsdWUgPSB1cGRhdGVbZmllbGROYW1lXTtcbiAgICAgIC8vIERyb3AgYW55IHVuZGVmaW5lZCB2YWx1ZXMuXG4gICAgICBpZiAodHlwZW9mIGZpZWxkVmFsdWUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGRlbGV0ZSB1cGRhdGVbZmllbGROYW1lXTtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9IE5VTExgKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGROYW1lID09ICdhdXRoRGF0YScpIHtcbiAgICAgICAgLy8gVGhpcyByZWN1cnNpdmVseSBzZXRzIHRoZSBqc29uX29iamVjdFxuICAgICAgICAvLyBPbmx5IDEgbGV2ZWwgZGVlcFxuICAgICAgICBjb25zdCBnZW5lcmF0ZSA9IChqc29uYjogc3RyaW5nLCBrZXk6IHN0cmluZywgdmFsdWU6IGFueSkgPT4ge1xuICAgICAgICAgIHJldHVybiBganNvbl9vYmplY3Rfc2V0X2tleShDT0FMRVNDRSgke2pzb25ifSwgJ3t9Jzo6anNvbmIpLCAke2tleX0sICR7dmFsdWV9KTo6anNvbmJgO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBsYXN0S2V5ID0gYCQke2luZGV4fTpuYW1lYDtcbiAgICAgICAgY29uc3QgZmllbGROYW1lSW5kZXggPSBpbmRleDtcbiAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgY29uc3QgdXBkYXRlID0gT2JqZWN0LmtleXMoZmllbGRWYWx1ZSkucmVkdWNlKChsYXN0S2V5OiBzdHJpbmcsIGtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgY29uc3Qgc3RyID0gZ2VuZXJhdGUobGFzdEtleSwgYCQke2luZGV4fTo6dGV4dGAsIGAkJHtpbmRleCArIDF9Ojpqc29uYmApO1xuICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgbGV0IHZhbHVlID0gZmllbGRWYWx1ZVtrZXldO1xuICAgICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgICAgICAgIHZhbHVlID0gbnVsbDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHZhbHVlID0gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICB2YWx1ZXMucHVzaChrZXksIHZhbHVlKTtcbiAgICAgICAgICByZXR1cm4gc3RyO1xuICAgICAgICB9LCBsYXN0S2V5KTtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7ZmllbGROYW1lSW5kZXh9Om5hbWUgPSAke3VwZGF0ZX1gKTtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS5fX29wID09PSAnSW5jcmVtZW50Jykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9IENPQUxFU0NFKCQke2luZGV4fTpuYW1lLCAwKSArICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlLmFtb3VudCk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkVmFsdWUuX19vcCA9PT0gJ0FkZCcpIHtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChcbiAgICAgICAgICBgJCR7aW5kZXh9Om5hbWUgPSBhcnJheV9hZGQoQ09BTEVTQ0UoJCR7aW5kZXh9Om5hbWUsICdbXSc6Ompzb25iKSwgJCR7aW5kZXggKyAxfTo6anNvbmIpYFxuICAgICAgICApO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIEpTT04uc3RyaW5naWZ5KGZpZWxkVmFsdWUub2JqZWN0cykpO1xuICAgICAgICBpbmRleCArPSAyO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgIHVwZGF0ZVBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lID0gJCR7aW5kZXggKyAxfWApO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIG51bGwpO1xuICAgICAgICBpbmRleCArPSAyO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlLl9fb3AgPT09ICdSZW1vdmUnKSB7XG4gICAgICAgIHVwZGF0ZVBhdHRlcm5zLnB1c2goXG4gICAgICAgICAgYCQke2luZGV4fTpuYW1lID0gYXJyYXlfcmVtb3ZlKENPQUxFU0NFKCQke2luZGV4fTpuYW1lLCAnW10nOjpqc29uYiksICQke1xuICAgICAgICAgICAgaW5kZXggKyAxXG4gICAgICAgICAgfTo6anNvbmIpYFxuICAgICAgICApO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIEpTT04uc3RyaW5naWZ5KGZpZWxkVmFsdWUub2JqZWN0cykpO1xuICAgICAgICBpbmRleCArPSAyO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlLl9fb3AgPT09ICdBZGRVbmlxdWUnKSB7XG4gICAgICAgIHVwZGF0ZVBhdHRlcm5zLnB1c2goXG4gICAgICAgICAgYCQke2luZGV4fTpuYW1lID0gYXJyYXlfYWRkX3VuaXF1ZShDT0FMRVNDRSgkJHtpbmRleH06bmFtZSwgJ1tdJzo6anNvbmIpLCAkJHtcbiAgICAgICAgICAgIGluZGV4ICsgMVxuICAgICAgICAgIH06Ompzb25iKWBcbiAgICAgICAgKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBKU09OLnN0cmluZ2lmeShmaWVsZFZhbHVlLm9iamVjdHMpKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGROYW1lID09PSAndXBkYXRlZEF0Jykge1xuICAgICAgICAvL1RPRE86IHN0b3Agc3BlY2lhbCBjYXNpbmcgdGhpcy4gSXQgc2hvdWxkIGNoZWNrIGZvciBfX3R5cGUgPT09ICdEYXRlJyBhbmQgdXNlIC5pc29cbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgZmllbGRWYWx1ZSk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBmaWVsZFZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGZpZWxkVmFsdWUgPT09ICdib29sZWFuJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS5fX3R5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlLm9iamVjdElkKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS5fX3R5cGUgPT09ICdEYXRlJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCB0b1Bvc3RncmVzVmFsdWUoZmllbGRWYWx1ZSkpO1xuICAgICAgICBpbmRleCArPSAyO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS5fX3R5cGUgPT09ICdGaWxlJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCB0b1Bvc3RncmVzVmFsdWUoZmllbGRWYWx1ZSkpO1xuICAgICAgICBpbmRleCArPSAyO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlLl9fdHlwZSA9PT0gJ0dlb1BvaW50Jykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9IFBPSU5UKCQke2luZGV4ICsgMX0sICQke2luZGV4ICsgMn0pYCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgZmllbGRWYWx1ZS5sb25naXR1ZGUsIGZpZWxkVmFsdWUubGF0aXR1ZGUpO1xuICAgICAgICBpbmRleCArPSAzO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlLl9fdHlwZSA9PT0gJ1BvbHlnb24nKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gY29udmVydFBvbHlnb25Ub1NRTChmaWVsZFZhbHVlLmNvb3JkaW5hdGVzKTtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9Ojpwb2x5Z29uYCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgdmFsdWUpO1xuICAgICAgICBpbmRleCArPSAyO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlLl9fdHlwZSA9PT0gJ1JlbGF0aW9uJykge1xuICAgICAgICAvLyBub29wXG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBmaWVsZFZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIHR5cGVvZiBmaWVsZFZhbHVlID09PSAnb2JqZWN0JyAmJlxuICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiZcbiAgICAgICAgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdPYmplY3QnXG4gICAgICApIHtcbiAgICAgICAgLy8gR2F0aGVyIGtleXMgdG8gaW5jcmVtZW50XG4gICAgICAgIGNvbnN0IGtleXNUb0luY3JlbWVudCA9IE9iamVjdC5rZXlzKG9yaWdpbmFsVXBkYXRlKVxuICAgICAgICAgIC5maWx0ZXIoayA9PiB7XG4gICAgICAgICAgICAvLyBjaG9vc2UgdG9wIGxldmVsIGZpZWxkcyB0aGF0IGhhdmUgYSBkZWxldGUgb3BlcmF0aW9uIHNldFxuICAgICAgICAgICAgLy8gTm90ZSB0aGF0IE9iamVjdC5rZXlzIGlzIGl0ZXJhdGluZyBvdmVyIHRoZSAqKm9yaWdpbmFsKiogdXBkYXRlIG9iamVjdFxuICAgICAgICAgICAgLy8gYW5kIHRoYXQgc29tZSBvZiB0aGUga2V5cyBvZiB0aGUgb3JpZ2luYWwgdXBkYXRlIGNvdWxkIGJlIG51bGwgb3IgdW5kZWZpbmVkOlxuICAgICAgICAgICAgLy8gKFNlZSB0aGUgYWJvdmUgY2hlY2sgYGlmIChmaWVsZFZhbHVlID09PSBudWxsIHx8IHR5cGVvZiBmaWVsZFZhbHVlID09IFwidW5kZWZpbmVkXCIpYClcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gb3JpZ2luYWxVcGRhdGVba107XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICB2YWx1ZSAmJlxuICAgICAgICAgICAgICB2YWx1ZS5fX29wID09PSAnSW5jcmVtZW50JyAmJlxuICAgICAgICAgICAgICBrLnNwbGl0KCcuJykubGVuZ3RoID09PSAyICYmXG4gICAgICAgICAgICAgIGsuc3BsaXQoJy4nKVswXSA9PT0gZmllbGROYW1lXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLm1hcChrID0+IGsuc3BsaXQoJy4nKVsxXSk7XG5cbiAgICAgICAgbGV0IGluY3JlbWVudFBhdHRlcm5zID0gJyc7XG4gICAgICAgIGlmIChrZXlzVG9JbmNyZW1lbnQubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGluY3JlbWVudFBhdHRlcm5zID1cbiAgICAgICAgICAgICcgfHwgJyArXG4gICAgICAgICAgICBrZXlzVG9JbmNyZW1lbnRcbiAgICAgICAgICAgICAgLm1hcChjID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBhbW91bnQgPSBmaWVsZFZhbHVlW2NdLmFtb3VudDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYENPTkNBVCgne1wiJHtjfVwiOicsIENPQUxFU0NFKCQke2luZGV4fTpuYW1lLT4+JyR7Y30nLCcwJyk6OmludCArICR7YW1vdW50fSwgJ30nKTo6anNvbmJgO1xuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAuam9pbignIHx8ICcpO1xuICAgICAgICAgIC8vIFN0cmlwIHRoZSBrZXlzXG4gICAgICAgICAga2V5c1RvSW5jcmVtZW50LmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgIGRlbGV0ZSBmaWVsZFZhbHVlW2tleV07XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBrZXlzVG9EZWxldGU6IEFycmF5PHN0cmluZz4gPSBPYmplY3Qua2V5cyhvcmlnaW5hbFVwZGF0ZSlcbiAgICAgICAgICAuZmlsdGVyKGsgPT4ge1xuICAgICAgICAgICAgLy8gY2hvb3NlIHRvcCBsZXZlbCBmaWVsZHMgdGhhdCBoYXZlIGEgZGVsZXRlIG9wZXJhdGlvbiBzZXQuXG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IG9yaWdpbmFsVXBkYXRlW2tdO1xuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgdmFsdWUgJiZcbiAgICAgICAgICAgICAgdmFsdWUuX19vcCA9PT0gJ0RlbGV0ZScgJiZcbiAgICAgICAgICAgICAgay5zcGxpdCgnLicpLmxlbmd0aCA9PT0gMiAmJlxuICAgICAgICAgICAgICBrLnNwbGl0KCcuJylbMF0gPT09IGZpZWxkTmFtZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5tYXAoayA9PiBrLnNwbGl0KCcuJylbMV0pO1xuXG4gICAgICAgIGNvbnN0IGRlbGV0ZVBhdHRlcm5zID0ga2V5c1RvRGVsZXRlLnJlZHVjZSgocDogc3RyaW5nLCBjOiBzdHJpbmcsIGk6IG51bWJlcikgPT4ge1xuICAgICAgICAgIHJldHVybiBwICsgYCAtICckJHtpbmRleCArIDEgKyBpfTp2YWx1ZSdgO1xuICAgICAgICB9LCAnJyk7XG4gICAgICAgIC8vIE92ZXJyaWRlIE9iamVjdFxuICAgICAgICBsZXQgdXBkYXRlT2JqZWN0ID0gXCIne30nOjpqc29uYlwiO1xuXG4gICAgICAgIGlmIChkb3ROb3RhdGlvbk9wdGlvbnNbZmllbGROYW1lXSkge1xuICAgICAgICAgIC8vIE1lcmdlIE9iamVjdFxuICAgICAgICAgIHVwZGF0ZU9iamVjdCA9IGBDT0FMRVNDRSgkJHtpbmRleH06bmFtZSwgJ3t9Jzo6anNvbmIpYDtcbiAgICAgICAgfVxuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKFxuICAgICAgICAgIGAkJHtpbmRleH06bmFtZSA9ICgke3VwZGF0ZU9iamVjdH0gJHtkZWxldGVQYXR0ZXJuc30gJHtpbmNyZW1lbnRQYXR0ZXJuc30gfHwgJCR7XG4gICAgICAgICAgICBpbmRleCArIDEgKyBrZXlzVG9EZWxldGUubGVuZ3RoXG4gICAgICAgICAgfTo6anNvbmIgKWBcbiAgICAgICAgKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCAuLi5rZXlzVG9EZWxldGUsIEpTT04uc3RyaW5naWZ5KGZpZWxkVmFsdWUpKTtcbiAgICAgICAgaW5kZXggKz0gMiArIGtleXNUb0RlbGV0ZS5sZW5ndGg7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBBcnJheS5pc0FycmF5KGZpZWxkVmFsdWUpICYmXG4gICAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJlxuICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ0FycmF5J1xuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkVHlwZSA9IHBhcnNlVHlwZVRvUG9zdGdyZXNUeXBlKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSk7XG4gICAgICAgIGlmIChleHBlY3RlZFR5cGUgPT09ICd0ZXh0W10nKSB7XG4gICAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9Ojp0ZXh0W11gKTtcbiAgICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUpO1xuICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9Ojpqc29uYmApO1xuICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgSlNPTi5zdHJpbmdpZnkoZmllbGRWYWx1ZSkpO1xuICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlYnVnKCdOb3Qgc3VwcG9ydGVkIHVwZGF0ZScsIGZpZWxkTmFtZSwgZmllbGRWYWx1ZSk7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgICBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICAgICAgYFBvc3RncmVzIGRvZXNuJ3Qgc3VwcG9ydCB1cGRhdGUgJHtKU09OLnN0cmluZ2lmeShmaWVsZFZhbHVlKX0geWV0YFxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB3aGVyZSA9IGJ1aWxkV2hlcmVDbGF1c2Uoe1xuICAgICAgc2NoZW1hLFxuICAgICAgaW5kZXgsXG4gICAgICBxdWVyeSxcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZTogZmFsc2UsXG4gICAgfSk7XG4gICAgdmFsdWVzLnB1c2goLi4ud2hlcmUudmFsdWVzKTtcblxuICAgIGNvbnN0IHdoZXJlQ2xhdXNlID0gd2hlcmUucGF0dGVybi5sZW5ndGggPiAwID8gYFdIRVJFICR7d2hlcmUucGF0dGVybn1gIDogJyc7XG4gICAgY29uc3QgcXMgPSBgVVBEQVRFICQxOm5hbWUgU0VUICR7dXBkYXRlUGF0dGVybnMuam9pbigpfSAke3doZXJlQ2xhdXNlfSBSRVRVUk5JTkcgKmA7XG4gICAgZGVidWcoJ3VwZGF0ZTogJywgcXMsIHZhbHVlcyk7XG4gICAgY29uc3QgcHJvbWlzZSA9ICh0cmFuc2FjdGlvbmFsU2Vzc2lvbiA/IHRyYW5zYWN0aW9uYWxTZXNzaW9uLnQgOiB0aGlzLl9jbGllbnQpLmFueShxcywgdmFsdWVzKTtcbiAgICBpZiAodHJhbnNhY3Rpb25hbFNlc3Npb24pIHtcbiAgICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uLmJhdGNoLnB1c2gocHJvbWlzZSk7XG4gICAgfVxuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgLy8gSG9wZWZ1bGx5LCB3ZSBjYW4gZ2V0IHJpZCBvZiB0aGlzLiBJdCdzIG9ubHkgdXNlZCBmb3IgY29uZmlnIGFuZCBob29rcy5cbiAgdXBzZXJ0T25lT2JqZWN0KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHVwZGF0ZTogYW55LFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICkge1xuICAgIGRlYnVnKCd1cHNlcnRPbmVPYmplY3QnLCB7IGNsYXNzTmFtZSwgcXVlcnksIHVwZGF0ZSB9KTtcbiAgICBjb25zdCBjcmVhdGVWYWx1ZSA9IE9iamVjdC5hc3NpZ24oe30sIHF1ZXJ5LCB1cGRhdGUpO1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZU9iamVjdChjbGFzc05hbWUsIHNjaGVtYSwgY3JlYXRlVmFsdWUsIHRyYW5zYWN0aW9uYWxTZXNzaW9uKS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAvLyBpZ25vcmUgZHVwbGljYXRlIHZhbHVlIGVycm9ycyBhcyBpdCdzIHVwc2VydFxuICAgICAgaWYgKGVycm9yLmNvZGUgIT09IFBhcnNlLkVycm9yLkRVUExJQ0FURV9WQUxVRSkge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmZpbmRPbmVBbmRVcGRhdGUoY2xhc3NOYW1lLCBzY2hlbWEsIHF1ZXJ5LCB1cGRhdGUsIHRyYW5zYWN0aW9uYWxTZXNzaW9uKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZpbmQoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIHF1ZXJ5OiBRdWVyeVR5cGUsXG4gICAgeyBza2lwLCBsaW1pdCwgc29ydCwga2V5cywgY2FzZUluc2Vuc2l0aXZlLCBleHBsYWluIH06IFF1ZXJ5T3B0aW9uc1xuICApIHtcbiAgICBkZWJ1ZygnZmluZCcsIGNsYXNzTmFtZSwgcXVlcnksIHtcbiAgICAgIHNraXAsXG4gICAgICBsaW1pdCxcbiAgICAgIHNvcnQsXG4gICAgICBrZXlzLFxuICAgICAgY2FzZUluc2Vuc2l0aXZlLFxuICAgICAgZXhwbGFpbixcbiAgICB9KTtcbiAgICBjb25zdCBoYXNMaW1pdCA9IGxpbWl0ICE9PSB1bmRlZmluZWQ7XG4gICAgY29uc3QgaGFzU2tpcCA9IHNraXAgIT09IHVuZGVmaW5lZDtcbiAgICBsZXQgdmFsdWVzID0gW2NsYXNzTmFtZV07XG4gICAgY29uc3Qgd2hlcmUgPSBidWlsZFdoZXJlQ2xhdXNlKHtcbiAgICAgIHNjaGVtYSxcbiAgICAgIHF1ZXJ5LFxuICAgICAgaW5kZXg6IDIsXG4gICAgICBjYXNlSW5zZW5zaXRpdmUsXG4gICAgfSk7XG4gICAgdmFsdWVzLnB1c2goLi4ud2hlcmUudmFsdWVzKTtcblxuICAgIGNvbnN0IHdoZXJlUGF0dGVybiA9IHdoZXJlLnBhdHRlcm4ubGVuZ3RoID4gMCA/IGBXSEVSRSAke3doZXJlLnBhdHRlcm59YCA6ICcnO1xuICAgIGNvbnN0IGxpbWl0UGF0dGVybiA9IGhhc0xpbWl0ID8gYExJTUlUICQke3ZhbHVlcy5sZW5ndGggKyAxfWAgOiAnJztcbiAgICBpZiAoaGFzTGltaXQpIHtcbiAgICAgIHZhbHVlcy5wdXNoKGxpbWl0KTtcbiAgICB9XG4gICAgY29uc3Qgc2tpcFBhdHRlcm4gPSBoYXNTa2lwID8gYE9GRlNFVCAkJHt2YWx1ZXMubGVuZ3RoICsgMX1gIDogJyc7XG4gICAgaWYgKGhhc1NraXApIHtcbiAgICAgIHZhbHVlcy5wdXNoKHNraXApO1xuICAgIH1cblxuICAgIGxldCBzb3J0UGF0dGVybiA9ICcnO1xuICAgIGlmIChzb3J0KSB7XG4gICAgICBjb25zdCBzb3J0Q29weTogYW55ID0gc29ydDtcbiAgICAgIGNvbnN0IHNvcnRpbmcgPSBPYmplY3Qua2V5cyhzb3J0KVxuICAgICAgICAubWFwKGtleSA9PiB7XG4gICAgICAgICAgY29uc3QgdHJhbnNmb3JtS2V5ID0gdHJhbnNmb3JtRG90RmllbGRUb0NvbXBvbmVudHMoa2V5KS5qb2luKCctPicpO1xuICAgICAgICAgIC8vIFVzaW5nICRpZHggcGF0dGVybiBnaXZlczogIG5vbi1pbnRlZ2VyIGNvbnN0YW50IGluIE9SREVSIEJZXG4gICAgICAgICAgaWYgKHNvcnRDb3B5W2tleV0gPT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiBgJHt0cmFuc2Zvcm1LZXl9IEFTQ2A7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBgJHt0cmFuc2Zvcm1LZXl9IERFU0NgO1xuICAgICAgICB9KVxuICAgICAgICAuam9pbigpO1xuICAgICAgc29ydFBhdHRlcm4gPSBzb3J0ICE9PSB1bmRlZmluZWQgJiYgT2JqZWN0LmtleXMoc29ydCkubGVuZ3RoID4gMCA/IGBPUkRFUiBCWSAke3NvcnRpbmd9YCA6ICcnO1xuICAgIH1cbiAgICBpZiAod2hlcmUuc29ydHMgJiYgT2JqZWN0LmtleXMoKHdoZXJlLnNvcnRzOiBhbnkpKS5sZW5ndGggPiAwKSB7XG4gICAgICBzb3J0UGF0dGVybiA9IGBPUkRFUiBCWSAke3doZXJlLnNvcnRzLmpvaW4oKX1gO1xuICAgIH1cblxuICAgIGxldCBjb2x1bW5zID0gJyonO1xuICAgIGlmIChrZXlzKSB7XG4gICAgICAvLyBFeGNsdWRlIGVtcHR5IGtleXNcbiAgICAgIC8vIFJlcGxhY2UgQUNMIGJ5IGl0J3Mga2V5c1xuICAgICAga2V5cyA9IGtleXMucmVkdWNlKChtZW1vLCBrZXkpID0+IHtcbiAgICAgICAgaWYgKGtleSA9PT0gJ0FDTCcpIHtcbiAgICAgICAgICBtZW1vLnB1c2goJ19ycGVybScpO1xuICAgICAgICAgIG1lbW8ucHVzaCgnX3dwZXJtJyk7XG4gICAgICAgIH0gZWxzZSBpZiAoa2V5Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBtZW1vLnB1c2goa2V5KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVtbztcbiAgICAgIH0sIFtdKTtcbiAgICAgIGNvbHVtbnMgPSBrZXlzXG4gICAgICAgIC5tYXAoKGtleSwgaW5kZXgpID0+IHtcbiAgICAgICAgICBpZiAoa2V5ID09PSAnJHNjb3JlJykge1xuICAgICAgICAgICAgcmV0dXJuIGB0c19yYW5rX2NkKHRvX3RzdmVjdG9yKCQkezJ9LCAkJHszfTpuYW1lKSwgdG9fdHNxdWVyeSgkJHs0fSwgJCR7NX0pLCAzMikgYXMgc2NvcmVgO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gYCQke2luZGV4ICsgdmFsdWVzLmxlbmd0aCArIDF9Om5hbWVgO1xuICAgICAgICB9KVxuICAgICAgICAuam9pbigpO1xuICAgICAgdmFsdWVzID0gdmFsdWVzLmNvbmNhdChrZXlzKTtcbiAgICB9XG5cbiAgICBjb25zdCBvcmlnaW5hbFF1ZXJ5ID0gYFNFTEVDVCAke2NvbHVtbnN9IEZST00gJDE6bmFtZSAke3doZXJlUGF0dGVybn0gJHtzb3J0UGF0dGVybn0gJHtsaW1pdFBhdHRlcm59ICR7c2tpcFBhdHRlcm59YDtcbiAgICBjb25zdCBxcyA9IGV4cGxhaW4gPyB0aGlzLmNyZWF0ZUV4cGxhaW5hYmxlUXVlcnkob3JpZ2luYWxRdWVyeSkgOiBvcmlnaW5hbFF1ZXJ5O1xuICAgIGRlYnVnKHFzLCB2YWx1ZXMpO1xuICAgIHJldHVybiB0aGlzLl9jbGllbnRcbiAgICAgIC5hbnkocXMsIHZhbHVlcylcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIC8vIFF1ZXJ5IG9uIG5vbiBleGlzdGluZyB0YWJsZSwgZG9uJ3QgY3Jhc2hcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgIT09IFBvc3RncmVzUmVsYXRpb25Eb2VzTm90RXhpc3RFcnJvcikge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgaWYgKGV4cGxhaW4pIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0cy5tYXAob2JqZWN0ID0+IHRoaXMucG9zdGdyZXNPYmplY3RUb1BhcnNlT2JqZWN0KGNsYXNzTmFtZSwgb2JqZWN0LCBzY2hlbWEpKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gQ29udmVydHMgZnJvbSBhIHBvc3RncmVzLWZvcm1hdCBvYmplY3QgdG8gYSBSRVNULWZvcm1hdCBvYmplY3QuXG4gIC8vIERvZXMgbm90IHN0cmlwIG91dCBhbnl0aGluZyBiYXNlZCBvbiBhIGxhY2sgb2YgYXV0aGVudGljYXRpb24uXG4gIHBvc3RncmVzT2JqZWN0VG9QYXJzZU9iamVjdChjbGFzc05hbWU6IHN0cmluZywgb2JqZWN0OiBhbnksIHNjaGVtYTogYW55KSB7XG4gICAgT2JqZWN0LmtleXMoc2NoZW1hLmZpZWxkcykuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnUG9pbnRlcicgJiYgb2JqZWN0W2ZpZWxkTmFtZV0pIHtcbiAgICAgICAgb2JqZWN0W2ZpZWxkTmFtZV0gPSB7XG4gICAgICAgICAgb2JqZWN0SWQ6IG9iamVjdFtmaWVsZE5hbWVdLFxuICAgICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICAgIGNsYXNzTmFtZTogc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnRhcmdldENsYXNzLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIG9iamVjdFtmaWVsZE5hbWVdID0ge1xuICAgICAgICAgIF9fdHlwZTogJ1JlbGF0aW9uJyxcbiAgICAgICAgICBjbGFzc05hbWU6IHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50YXJnZXRDbGFzcyxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ0dlb1BvaW50Jykge1xuICAgICAgICBvYmplY3RbZmllbGROYW1lXSA9IHtcbiAgICAgICAgICBfX3R5cGU6ICdHZW9Qb2ludCcsXG4gICAgICAgICAgbGF0aXR1ZGU6IG9iamVjdFtmaWVsZE5hbWVdLnksXG4gICAgICAgICAgbG9uZ2l0dWRlOiBvYmplY3RbZmllbGROYW1lXS54LFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdFtmaWVsZE5hbWVdICYmIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnUG9seWdvbicpIHtcbiAgICAgICAgbGV0IGNvb3JkcyA9IG9iamVjdFtmaWVsZE5hbWVdO1xuICAgICAgICBjb29yZHMgPSBjb29yZHMuc3Vic3RyKDIsIGNvb3Jkcy5sZW5ndGggLSA0KS5zcGxpdCgnKSwoJyk7XG4gICAgICAgIGNvb3JkcyA9IGNvb3Jkcy5tYXAocG9pbnQgPT4ge1xuICAgICAgICAgIHJldHVybiBbcGFyc2VGbG9hdChwb2ludC5zcGxpdCgnLCcpWzFdKSwgcGFyc2VGbG9hdChwb2ludC5zcGxpdCgnLCcpWzBdKV07XG4gICAgICAgIH0pO1xuICAgICAgICBvYmplY3RbZmllbGROYW1lXSA9IHtcbiAgICAgICAgICBfX3R5cGU6ICdQb2x5Z29uJyxcbiAgICAgICAgICBjb29yZGluYXRlczogY29vcmRzLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdFtmaWVsZE5hbWVdICYmIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnRmlsZScpIHtcbiAgICAgICAgb2JqZWN0W2ZpZWxkTmFtZV0gPSB7XG4gICAgICAgICAgX190eXBlOiAnRmlsZScsXG4gICAgICAgICAgbmFtZTogb2JqZWN0W2ZpZWxkTmFtZV0sXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfSk7XG4gICAgLy9UT0RPOiByZW1vdmUgdGhpcyByZWxpYW5jZSBvbiB0aGUgbW9uZ28gZm9ybWF0LiBEQiBhZGFwdGVyIHNob3VsZG4ndCBrbm93IHRoZXJlIGlzIGEgZGlmZmVyZW5jZSBiZXR3ZWVuIGNyZWF0ZWQgYXQgYW5kIGFueSBvdGhlciBkYXRlIGZpZWxkLlxuICAgIGlmIChvYmplY3QuY3JlYXRlZEF0KSB7XG4gICAgICBvYmplY3QuY3JlYXRlZEF0ID0gb2JqZWN0LmNyZWF0ZWRBdC50b0lTT1N0cmluZygpO1xuICAgIH1cbiAgICBpZiAob2JqZWN0LnVwZGF0ZWRBdCkge1xuICAgICAgb2JqZWN0LnVwZGF0ZWRBdCA9IG9iamVjdC51cGRhdGVkQXQudG9JU09TdHJpbmcoKTtcbiAgICB9XG4gICAgaWYgKG9iamVjdC5leHBpcmVzQXQpIHtcbiAgICAgIG9iamVjdC5leHBpcmVzQXQgPSB7XG4gICAgICAgIF9fdHlwZTogJ0RhdGUnLFxuICAgICAgICBpc286IG9iamVjdC5leHBpcmVzQXQudG9JU09TdHJpbmcoKSxcbiAgICAgIH07XG4gICAgfVxuICAgIGlmIChvYmplY3QuX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0KSB7XG4gICAgICBvYmplY3QuX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0ID0ge1xuICAgICAgICBfX3R5cGU6ICdEYXRlJyxcbiAgICAgICAgaXNvOiBvYmplY3QuX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0LnRvSVNPU3RyaW5nKCksXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAob2JqZWN0Ll9hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCkge1xuICAgICAgb2JqZWN0Ll9hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCA9IHtcbiAgICAgICAgX190eXBlOiAnRGF0ZScsXG4gICAgICAgIGlzbzogb2JqZWN0Ll9hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdC50b0lTT1N0cmluZygpLFxuICAgICAgfTtcbiAgICB9XG4gICAgaWYgKG9iamVjdC5fcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0KSB7XG4gICAgICBvYmplY3QuX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCA9IHtcbiAgICAgICAgX190eXBlOiAnRGF0ZScsXG4gICAgICAgIGlzbzogb2JqZWN0Ll9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQudG9JU09TdHJpbmcoKSxcbiAgICAgIH07XG4gICAgfVxuICAgIGlmIChvYmplY3QuX3Bhc3N3b3JkX2NoYW5nZWRfYXQpIHtcbiAgICAgIG9iamVjdC5fcGFzc3dvcmRfY2hhbmdlZF9hdCA9IHtcbiAgICAgICAgX190eXBlOiAnRGF0ZScsXG4gICAgICAgIGlzbzogb2JqZWN0Ll9wYXNzd29yZF9jaGFuZ2VkX2F0LnRvSVNPU3RyaW5nKCksXG4gICAgICB9O1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZmllbGROYW1lIGluIG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdFtmaWVsZE5hbWVdID09PSBudWxsKSB7XG4gICAgICAgIGRlbGV0ZSBvYmplY3RbZmllbGROYW1lXTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgb2JqZWN0W2ZpZWxkTmFtZV0gPSB7XG4gICAgICAgICAgX190eXBlOiAnRGF0ZScsXG4gICAgICAgICAgaXNvOiBvYmplY3RbZmllbGROYW1lXS50b0lTT1N0cmluZygpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvYmplY3Q7XG4gIH1cblxuICAvLyBDcmVhdGUgYSB1bmlxdWUgaW5kZXguIFVuaXF1ZSBpbmRleGVzIG9uIG51bGxhYmxlIGZpZWxkcyBhcmUgbm90IGFsbG93ZWQuIFNpbmNlIHdlIGRvbid0XG4gIC8vIGN1cnJlbnRseSBrbm93IHdoaWNoIGZpZWxkcyBhcmUgbnVsbGFibGUgYW5kIHdoaWNoIGFyZW4ndCwgd2UgaWdub3JlIHRoYXQgY3JpdGVyaWEuXG4gIC8vIEFzIHN1Y2gsIHdlIHNob3VsZG4ndCBleHBvc2UgdGhpcyBmdW5jdGlvbiB0byB1c2VycyBvZiBwYXJzZSB1bnRpbCB3ZSBoYXZlIGFuIG91dC1vZi1iYW5kXG4gIC8vIFdheSBvZiBkZXRlcm1pbmluZyBpZiBhIGZpZWxkIGlzIG51bGxhYmxlLiBVbmRlZmluZWQgZG9lc24ndCBjb3VudCBhZ2FpbnN0IHVuaXF1ZW5lc3MsXG4gIC8vIHdoaWNoIGlzIHdoeSB3ZSB1c2Ugc3BhcnNlIGluZGV4ZXMuXG4gIGFzeW5jIGVuc3VyZVVuaXF1ZW5lc3MoY2xhc3NOYW1lOiBzdHJpbmcsIHNjaGVtYTogU2NoZW1hVHlwZSwgZmllbGROYW1lczogc3RyaW5nW10pIHtcbiAgICBjb25zdCBjb25zdHJhaW50TmFtZSA9IGAke2NsYXNzTmFtZX1fdW5pcXVlXyR7ZmllbGROYW1lcy5zb3J0KCkuam9pbignXycpfWA7XG4gICAgY29uc3QgY29uc3RyYWludFBhdHRlcm5zID0gZmllbGROYW1lcy5tYXAoKGZpZWxkTmFtZSwgaW5kZXgpID0+IGAkJHtpbmRleCArIDN9Om5hbWVgKTtcbiAgICBjb25zdCBxcyA9IGBDUkVBVEUgVU5JUVVFIElOREVYIElGIE5PVCBFWElTVFMgJDI6bmFtZSBPTiAkMTpuYW1lKCR7Y29uc3RyYWludFBhdHRlcm5zLmpvaW4oKX0pYDtcbiAgICByZXR1cm4gdGhpcy5fY2xpZW50Lm5vbmUocXMsIFtjbGFzc05hbWUsIGNvbnN0cmFpbnROYW1lLCAuLi5maWVsZE5hbWVzXSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgaWYgKGVycm9yLmNvZGUgPT09IFBvc3RncmVzRHVwbGljYXRlUmVsYXRpb25FcnJvciAmJiBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKGNvbnN0cmFpbnROYW1lKSkge1xuICAgICAgICAvLyBJbmRleCBhbHJlYWR5IGV4aXN0cy4gSWdub3JlIGVycm9yLlxuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgZXJyb3IuY29kZSA9PT0gUG9zdGdyZXNVbmlxdWVJbmRleFZpb2xhdGlvbkVycm9yICYmXG4gICAgICAgIGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoY29uc3RyYWludE5hbWUpXG4gICAgICApIHtcbiAgICAgICAgLy8gQ2FzdCB0aGUgZXJyb3IgaW50byB0aGUgcHJvcGVyIHBhcnNlIGVycm9yXG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUsXG4gICAgICAgICAgJ0EgZHVwbGljYXRlIHZhbHVlIGZvciBhIGZpZWxkIHdpdGggdW5pcXVlIHZhbHVlcyB3YXMgcHJvdmlkZWQnXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIEV4ZWN1dGVzIGEgY291bnQuXG4gIGFzeW5jIGNvdW50KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHJlYWRQcmVmZXJlbmNlPzogc3RyaW5nLFxuICAgIGVzdGltYXRlPzogYm9vbGVhbiA9IHRydWVcbiAgKSB7XG4gICAgZGVidWcoJ2NvdW50JywgY2xhc3NOYW1lLCBxdWVyeSwgcmVhZFByZWZlcmVuY2UsIGVzdGltYXRlKTtcbiAgICBjb25zdCB2YWx1ZXMgPSBbY2xhc3NOYW1lXTtcbiAgICBjb25zdCB3aGVyZSA9IGJ1aWxkV2hlcmVDbGF1c2Uoe1xuICAgICAgc2NoZW1hLFxuICAgICAgcXVlcnksXG4gICAgICBpbmRleDogMixcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZTogZmFsc2UsXG4gICAgfSk7XG4gICAgdmFsdWVzLnB1c2goLi4ud2hlcmUudmFsdWVzKTtcblxuICAgIGNvbnN0IHdoZXJlUGF0dGVybiA9IHdoZXJlLnBhdHRlcm4ubGVuZ3RoID4gMCA/IGBXSEVSRSAke3doZXJlLnBhdHRlcm59YCA6ICcnO1xuICAgIGxldCBxcyA9ICcnO1xuXG4gICAgaWYgKHdoZXJlLnBhdHRlcm4ubGVuZ3RoID4gMCB8fCAhZXN0aW1hdGUpIHtcbiAgICAgIHFzID0gYFNFTEVDVCBjb3VudCgqKSBGUk9NICQxOm5hbWUgJHt3aGVyZVBhdHRlcm59YDtcbiAgICB9IGVsc2Uge1xuICAgICAgcXMgPSAnU0VMRUNUIHJlbHR1cGxlcyBBUyBhcHByb3hpbWF0ZV9yb3dfY291bnQgRlJPTSBwZ19jbGFzcyBXSEVSRSByZWxuYW1lID0gJDEnO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9jbGllbnRcbiAgICAgIC5vbmUocXMsIHZhbHVlcywgYSA9PiB7XG4gICAgICAgIGlmIChhLmFwcHJveGltYXRlX3Jvd19jb3VudCAhPSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuICthLmFwcHJveGltYXRlX3Jvd19jb3VudDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gK2EuY291bnQ7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSAhPT0gUG9zdGdyZXNSZWxhdGlvbkRvZXNOb3RFeGlzdEVycm9yKSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGRpc3RpbmN0KGNsYXNzTmFtZTogc3RyaW5nLCBzY2hlbWE6IFNjaGVtYVR5cGUsIHF1ZXJ5OiBRdWVyeVR5cGUsIGZpZWxkTmFtZTogc3RyaW5nKSB7XG4gICAgZGVidWcoJ2Rpc3RpbmN0JywgY2xhc3NOYW1lLCBxdWVyeSk7XG4gICAgbGV0IGZpZWxkID0gZmllbGROYW1lO1xuICAgIGxldCBjb2x1bW4gPSBmaWVsZE5hbWU7XG4gICAgY29uc3QgaXNOZXN0ZWQgPSBmaWVsZE5hbWUuaW5kZXhPZignLicpID49IDA7XG4gICAgaWYgKGlzTmVzdGVkKSB7XG4gICAgICBmaWVsZCA9IHRyYW5zZm9ybURvdEZpZWxkVG9Db21wb25lbnRzKGZpZWxkTmFtZSkuam9pbignLT4nKTtcbiAgICAgIGNvbHVtbiA9IGZpZWxkTmFtZS5zcGxpdCgnLicpWzBdO1xuICAgIH1cbiAgICBjb25zdCBpc0FycmF5RmllbGQgPVxuICAgICAgc2NoZW1hLmZpZWxkcyAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiYgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdBcnJheSc7XG4gICAgY29uc3QgaXNQb2ludGVyRmllbGQgPVxuICAgICAgc2NoZW1hLmZpZWxkcyAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiYgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdQb2ludGVyJztcbiAgICBjb25zdCB2YWx1ZXMgPSBbZmllbGQsIGNvbHVtbiwgY2xhc3NOYW1lXTtcbiAgICBjb25zdCB3aGVyZSA9IGJ1aWxkV2hlcmVDbGF1c2Uoe1xuICAgICAgc2NoZW1hLFxuICAgICAgcXVlcnksXG4gICAgICBpbmRleDogNCxcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZTogZmFsc2UsXG4gICAgfSk7XG4gICAgdmFsdWVzLnB1c2goLi4ud2hlcmUudmFsdWVzKTtcblxuICAgIGNvbnN0IHdoZXJlUGF0dGVybiA9IHdoZXJlLnBhdHRlcm4ubGVuZ3RoID4gMCA/IGBXSEVSRSAke3doZXJlLnBhdHRlcm59YCA6ICcnO1xuICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gaXNBcnJheUZpZWxkID8gJ2pzb25iX2FycmF5X2VsZW1lbnRzJyA6ICdPTic7XG4gICAgbGV0IHFzID0gYFNFTEVDVCBESVNUSU5DVCAke3RyYW5zZm9ybWVyfSgkMTpuYW1lKSAkMjpuYW1lIEZST00gJDM6bmFtZSAke3doZXJlUGF0dGVybn1gO1xuICAgIGlmIChpc05lc3RlZCkge1xuICAgICAgcXMgPSBgU0VMRUNUIERJU1RJTkNUICR7dHJhbnNmb3JtZXJ9KCQxOnJhdykgJDI6cmF3IEZST00gJDM6bmFtZSAke3doZXJlUGF0dGVybn1gO1xuICAgIH1cbiAgICBkZWJ1ZyhxcywgdmFsdWVzKTtcbiAgICByZXR1cm4gdGhpcy5fY2xpZW50XG4gICAgICAuYW55KHFzLCB2YWx1ZXMpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gUG9zdGdyZXNNaXNzaW5nQ29sdW1uRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KVxuICAgICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAgIGlmICghaXNOZXN0ZWQpIHtcbiAgICAgICAgICByZXN1bHRzID0gcmVzdWx0cy5maWx0ZXIob2JqZWN0ID0+IG9iamVjdFtmaWVsZF0gIT09IG51bGwpO1xuICAgICAgICAgIHJldHVybiByZXN1bHRzLm1hcChvYmplY3QgPT4ge1xuICAgICAgICAgICAgaWYgKCFpc1BvaW50ZXJGaWVsZCkge1xuICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0W2ZpZWxkXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICAgICAgICBjbGFzc05hbWU6IHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50YXJnZXRDbGFzcyxcbiAgICAgICAgICAgICAgb2JqZWN0SWQ6IG9iamVjdFtmaWVsZF0sXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNoaWxkID0gZmllbGROYW1lLnNwbGl0KCcuJylbMV07XG4gICAgICAgIHJldHVybiByZXN1bHRzLm1hcChvYmplY3QgPT4gb2JqZWN0W2NvbHVtbl1bY2hpbGRdKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXN1bHRzID0+XG4gICAgICAgIHJlc3VsdHMubWFwKG9iamVjdCA9PiB0aGlzLnBvc3RncmVzT2JqZWN0VG9QYXJzZU9iamVjdChjbGFzc05hbWUsIG9iamVjdCwgc2NoZW1hKSlcbiAgICAgICk7XG4gIH1cblxuICBhc3luYyBhZ2dyZWdhdGUoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBhbnksXG4gICAgcGlwZWxpbmU6IGFueSxcbiAgICByZWFkUHJlZmVyZW5jZTogP3N0cmluZyxcbiAgICBoaW50OiA/bWl4ZWQsXG4gICAgZXhwbGFpbj86IGJvb2xlYW5cbiAgKSB7XG4gICAgZGVidWcoJ2FnZ3JlZ2F0ZScsIGNsYXNzTmFtZSwgcGlwZWxpbmUsIHJlYWRQcmVmZXJlbmNlLCBoaW50LCBleHBsYWluKTtcbiAgICBjb25zdCB2YWx1ZXMgPSBbY2xhc3NOYW1lXTtcbiAgICBsZXQgaW5kZXg6IG51bWJlciA9IDI7XG4gICAgbGV0IGNvbHVtbnM6IHN0cmluZ1tdID0gW107XG4gICAgbGV0IGNvdW50RmllbGQgPSBudWxsO1xuICAgIGxldCBncm91cFZhbHVlcyA9IG51bGw7XG4gICAgbGV0IHdoZXJlUGF0dGVybiA9ICcnO1xuICAgIGxldCBsaW1pdFBhdHRlcm4gPSAnJztcbiAgICBsZXQgc2tpcFBhdHRlcm4gPSAnJztcbiAgICBsZXQgc29ydFBhdHRlcm4gPSAnJztcbiAgICBsZXQgZ3JvdXBQYXR0ZXJuID0gJyc7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwaXBlbGluZS5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgY29uc3Qgc3RhZ2UgPSBwaXBlbGluZVtpXTtcbiAgICAgIGlmIChzdGFnZS4kZ3JvdXApIHtcbiAgICAgICAgZm9yIChjb25zdCBmaWVsZCBpbiBzdGFnZS4kZ3JvdXApIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IHN0YWdlLiRncm91cFtmaWVsZF07XG4gICAgICAgICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZmllbGQgPT09ICdfaWQnICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWUgIT09ICcnKSB7XG4gICAgICAgICAgICBjb2x1bW5zLnB1c2goYCQke2luZGV4fTpuYW1lIEFTIFwib2JqZWN0SWRcImApO1xuICAgICAgICAgICAgZ3JvdXBQYXR0ZXJuID0gYEdST1VQIEJZICQke2luZGV4fTpuYW1lYDtcbiAgICAgICAgICAgIHZhbHVlcy5wdXNoKHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlKSk7XG4gICAgICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChmaWVsZCA9PT0gJ19pZCcgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiBPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICBncm91cFZhbHVlcyA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc3QgZ3JvdXBCeUZpZWxkcyA9IFtdO1xuICAgICAgICAgICAgZm9yIChjb25zdCBhbGlhcyBpbiB2YWx1ZSkge1xuICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlW2FsaWFzXSA9PT0gJ3N0cmluZycgJiYgdmFsdWVbYWxpYXNdKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc291cmNlID0gdHJhbnNmb3JtQWdncmVnYXRlRmllbGQodmFsdWVbYWxpYXNdKTtcbiAgICAgICAgICAgICAgICBpZiAoIWdyb3VwQnlGaWVsZHMuaW5jbHVkZXMoYFwiJHtzb3VyY2V9XCJgKSkge1xuICAgICAgICAgICAgICAgICAgZ3JvdXBCeUZpZWxkcy5wdXNoKGBcIiR7c291cmNlfVwiYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHNvdXJjZSwgYWxpYXMpO1xuICAgICAgICAgICAgICAgIGNvbHVtbnMucHVzaChgJCR7aW5kZXh9Om5hbWUgQVMgJCR7aW5kZXggKyAxfTpuYW1lYCk7XG4gICAgICAgICAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcGVyYXRpb24gPSBPYmplY3Qua2V5cyh2YWx1ZVthbGlhc10pWzBdO1xuICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlW2FsaWFzXVtvcGVyYXRpb25dKTtcbiAgICAgICAgICAgICAgICBpZiAobW9uZ29BZ2dyZWdhdGVUb1Bvc3RncmVzW29wZXJhdGlvbl0pIHtcbiAgICAgICAgICAgICAgICAgIGlmICghZ3JvdXBCeUZpZWxkcy5pbmNsdWRlcyhgXCIke3NvdXJjZX1cImApKSB7XG4gICAgICAgICAgICAgICAgICAgIGdyb3VwQnlGaWVsZHMucHVzaChgXCIke3NvdXJjZX1cImApO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgY29sdW1ucy5wdXNoKFxuICAgICAgICAgICAgICAgICAgICBgRVhUUkFDVCgke1xuICAgICAgICAgICAgICAgICAgICAgIG1vbmdvQWdncmVnYXRlVG9Qb3N0Z3Jlc1tvcGVyYXRpb25dXG4gICAgICAgICAgICAgICAgICAgIH0gRlJPTSAkJHtpbmRleH06bmFtZSBBVCBUSU1FIFpPTkUgJ1VUQycpIEFTICQke2luZGV4ICsgMX06bmFtZWBcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICB2YWx1ZXMucHVzaChzb3VyY2UsIGFsaWFzKTtcbiAgICAgICAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBncm91cFBhdHRlcm4gPSBgR1JPVVAgQlkgJCR7aW5kZXh9OnJhd2A7XG4gICAgICAgICAgICB2YWx1ZXMucHVzaChncm91cEJ5RmllbGRzLmpvaW4oKSk7XG4gICAgICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBpZiAodmFsdWUuJHN1bSkge1xuICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlLiRzdW0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgY29sdW1ucy5wdXNoKGBTVU0oJCR7aW5kZXh9Om5hbWUpIEFTICQke2luZGV4ICsgMX06bmFtZWApO1xuICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlLiRzdW0pLCBmaWVsZCk7XG4gICAgICAgICAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb3VudEZpZWxkID0gZmllbGQ7XG4gICAgICAgICAgICAgICAgY29sdW1ucy5wdXNoKGBDT1VOVCgqKSBBUyAkJHtpbmRleH06bmFtZWApO1xuICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkKTtcbiAgICAgICAgICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWUuJG1heCkge1xuICAgICAgICAgICAgICBjb2x1bW5zLnB1c2goYE1BWCgkJHtpbmRleH06bmFtZSkgQVMgJCR7aW5kZXggKyAxfTpuYW1lYCk7XG4gICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlLiRtYXgpLCBmaWVsZCk7XG4gICAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWUuJG1pbikge1xuICAgICAgICAgICAgICBjb2x1bW5zLnB1c2goYE1JTigkJHtpbmRleH06bmFtZSkgQVMgJCR7aW5kZXggKyAxfTpuYW1lYCk7XG4gICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlLiRtaW4pLCBmaWVsZCk7XG4gICAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWUuJGF2Zykge1xuICAgICAgICAgICAgICBjb2x1bW5zLnB1c2goYEFWRygkJHtpbmRleH06bmFtZSkgQVMgJCR7aW5kZXggKyAxfTpuYW1lYCk7XG4gICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlLiRhdmcpLCBmaWVsZCk7XG4gICAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb2x1bW5zLnB1c2goJyonKTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFnZS4kcHJvamVjdCkge1xuICAgICAgICBpZiAoY29sdW1ucy5pbmNsdWRlcygnKicpKSB7XG4gICAgICAgICAgY29sdW1ucyA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gc3RhZ2UuJHByb2plY3QpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IHN0YWdlLiRwcm9qZWN0W2ZpZWxkXTtcbiAgICAgICAgICBpZiAodmFsdWUgPT09IDEgfHwgdmFsdWUgPT09IHRydWUpIHtcbiAgICAgICAgICAgIGNvbHVtbnMucHVzaChgJCR7aW5kZXh9Om5hbWVgKTtcbiAgICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkKTtcbiAgICAgICAgICAgIGluZGV4ICs9IDE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoc3RhZ2UuJG1hdGNoKSB7XG4gICAgICAgIGNvbnN0IHBhdHRlcm5zID0gW107XG4gICAgICAgIGNvbnN0IG9yT3JBbmQgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc3RhZ2UuJG1hdGNoLCAnJG9yJylcbiAgICAgICAgICA/ICcgT1IgJ1xuICAgICAgICAgIDogJyBBTkQgJztcblxuICAgICAgICBpZiAoc3RhZ2UuJG1hdGNoLiRvcikge1xuICAgICAgICAgIGNvbnN0IGNvbGxhcHNlID0ge307XG4gICAgICAgICAgc3RhZ2UuJG1hdGNoLiRvci5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZWxlbWVudCkge1xuICAgICAgICAgICAgICBjb2xsYXBzZVtrZXldID0gZWxlbWVudFtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHN0YWdlLiRtYXRjaCA9IGNvbGxhcHNlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gc3RhZ2UuJG1hdGNoKSB7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSBzdGFnZS4kbWF0Y2hbZmllbGRdO1xuICAgICAgICAgIGNvbnN0IG1hdGNoUGF0dGVybnMgPSBbXTtcbiAgICAgICAgICBPYmplY3Qua2V5cyhQYXJzZVRvUG9zZ3Jlc0NvbXBhcmF0b3IpLmZvckVhY2goY21wID0+IHtcbiAgICAgICAgICAgIGlmICh2YWx1ZVtjbXBdKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHBnQ29tcGFyYXRvciA9IFBhcnNlVG9Qb3NncmVzQ29tcGFyYXRvcltjbXBdO1xuICAgICAgICAgICAgICBtYXRjaFBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lICR7cGdDb21wYXJhdG9yfSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkLCB0b1Bvc3RncmVzVmFsdWUodmFsdWVbY21wXSkpO1xuICAgICAgICAgICAgICBpbmRleCArPSAyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmIChtYXRjaFBhdHRlcm5zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHBhdHRlcm5zLnB1c2goYCgke21hdGNoUGF0dGVybnMuam9pbignIEFORCAnKX0pYCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChzY2hlbWEuZmllbGRzW2ZpZWxkXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkXS50eXBlICYmIG1hdGNoUGF0dGVybnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkLCB2YWx1ZSk7XG4gICAgICAgICAgICBpbmRleCArPSAyO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB3aGVyZVBhdHRlcm4gPSBwYXR0ZXJucy5sZW5ndGggPiAwID8gYFdIRVJFICR7cGF0dGVybnMuam9pbihgICR7b3JPckFuZH0gYCl9YCA6ICcnO1xuICAgICAgfVxuICAgICAgaWYgKHN0YWdlLiRsaW1pdCkge1xuICAgICAgICBsaW1pdFBhdHRlcm4gPSBgTElNSVQgJCR7aW5kZXh9YDtcbiAgICAgICAgdmFsdWVzLnB1c2goc3RhZ2UuJGxpbWl0KTtcbiAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFnZS4kc2tpcCkge1xuICAgICAgICBza2lwUGF0dGVybiA9IGBPRkZTRVQgJCR7aW5kZXh9YDtcbiAgICAgICAgdmFsdWVzLnB1c2goc3RhZ2UuJHNraXApO1xuICAgICAgICBpbmRleCArPSAxO1xuICAgICAgfVxuICAgICAgaWYgKHN0YWdlLiRzb3J0KSB7XG4gICAgICAgIGNvbnN0IHNvcnQgPSBzdGFnZS4kc29ydDtcbiAgICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHNvcnQpO1xuICAgICAgICBjb25zdCBzb3J0aW5nID0ga2V5c1xuICAgICAgICAgIC5tYXAoa2V5ID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gc29ydFtrZXldID09PSAxID8gJ0FTQycgOiAnREVTQyc7XG4gICAgICAgICAgICBjb25zdCBvcmRlciA9IGAkJHtpbmRleH06bmFtZSAke3RyYW5zZm9ybWVyfWA7XG4gICAgICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICAgICAgcmV0dXJuIG9yZGVyO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLmpvaW4oKTtcbiAgICAgICAgdmFsdWVzLnB1c2goLi4ua2V5cyk7XG4gICAgICAgIHNvcnRQYXR0ZXJuID0gc29ydCAhPT0gdW5kZWZpbmVkICYmIHNvcnRpbmcubGVuZ3RoID4gMCA/IGBPUkRFUiBCWSAke3NvcnRpbmd9YCA6ICcnO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChncm91cFBhdHRlcm4pIHtcbiAgICAgIGNvbHVtbnMuZm9yRWFjaCgoZSwgaSwgYSkgPT4ge1xuICAgICAgICBpZiAoZSAmJiBlLnRyaW0oKSA9PT0gJyonKSB7XG4gICAgICAgICAgYVtpXSA9ICcnO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBvcmlnaW5hbFF1ZXJ5ID0gYFNFTEVDVCAke2NvbHVtbnNcbiAgICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAgIC5qb2luKCl9IEZST00gJDE6bmFtZSAke3doZXJlUGF0dGVybn0gJHtza2lwUGF0dGVybn0gJHtncm91cFBhdHRlcm59ICR7c29ydFBhdHRlcm59ICR7bGltaXRQYXR0ZXJufWA7XG4gICAgY29uc3QgcXMgPSBleHBsYWluID8gdGhpcy5jcmVhdGVFeHBsYWluYWJsZVF1ZXJ5KG9yaWdpbmFsUXVlcnkpIDogb3JpZ2luYWxRdWVyeTtcbiAgICBkZWJ1ZyhxcywgdmFsdWVzKTtcbiAgICByZXR1cm4gdGhpcy5fY2xpZW50LmFueShxcywgdmFsdWVzKS50aGVuKGEgPT4ge1xuICAgICAgaWYgKGV4cGxhaW4pIHtcbiAgICAgICAgcmV0dXJuIGE7XG4gICAgICB9XG4gICAgICBjb25zdCByZXN1bHRzID0gYS5tYXAob2JqZWN0ID0+IHRoaXMucG9zdGdyZXNPYmplY3RUb1BhcnNlT2JqZWN0KGNsYXNzTmFtZSwgb2JqZWN0LCBzY2hlbWEpKTtcbiAgICAgIHJlc3VsdHMuZm9yRWFjaChyZXN1bHQgPT4ge1xuICAgICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChyZXN1bHQsICdvYmplY3RJZCcpKSB7XG4gICAgICAgICAgcmVzdWx0Lm9iamVjdElkID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZ3JvdXBWYWx1ZXMpIHtcbiAgICAgICAgICByZXN1bHQub2JqZWN0SWQgPSB7fTtcbiAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBncm91cFZhbHVlcykge1xuICAgICAgICAgICAgcmVzdWx0Lm9iamVjdElkW2tleV0gPSByZXN1bHRba2V5XTtcbiAgICAgICAgICAgIGRlbGV0ZSByZXN1bHRba2V5XTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvdW50RmllbGQpIHtcbiAgICAgICAgICByZXN1bHRbY291bnRGaWVsZF0gPSBwYXJzZUludChyZXN1bHRbY291bnRGaWVsZF0sIDEwKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0cztcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHBlcmZvcm1Jbml0aWFsaXphdGlvbih7IFZvbGF0aWxlQ2xhc3Nlc1NjaGVtYXMgfTogYW55KSB7XG4gICAgLy8gVE9ETzogVGhpcyBtZXRob2QgbmVlZHMgdG8gYmUgcmV3cml0dGVuIHRvIG1ha2UgcHJvcGVyIHVzZSBvZiBjb25uZWN0aW9ucyAoQHZpdGFseS10KVxuICAgIGRlYnVnKCdwZXJmb3JtSW5pdGlhbGl6YXRpb24nKTtcbiAgICBjb25zdCBwcm9taXNlcyA9IFZvbGF0aWxlQ2xhc3Nlc1NjaGVtYXMubWFwKHNjaGVtYSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5jcmVhdGVUYWJsZShzY2hlbWEuY2xhc3NOYW1lLCBzY2hlbWEpXG4gICAgICAgIC5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGVyci5jb2RlID09PSBQb3N0Z3Jlc0R1cGxpY2F0ZVJlbGF0aW9uRXJyb3IgfHxcbiAgICAgICAgICAgIGVyci5jb2RlID09PSBQYXJzZS5FcnJvci5JTlZBTElEX0NMQVNTX05BTUVcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoKSA9PiB0aGlzLnNjaGVtYVVwZ3JhZGUoc2NoZW1hLmNsYXNzTmFtZSwgc2NoZW1hKSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2xpZW50LnR4KCdwZXJmb3JtLWluaXRpYWxpemF0aW9uJywgYXN5bmMgdCA9PiB7XG4gICAgICAgICAgYXdhaXQgdC5ub25lKHNxbC5taXNjLmpzb25PYmplY3RTZXRLZXlzKTtcbiAgICAgICAgICBhd2FpdCB0Lm5vbmUoc3FsLmFycmF5LmFkZCk7XG4gICAgICAgICAgYXdhaXQgdC5ub25lKHNxbC5hcnJheS5hZGRVbmlxdWUpO1xuICAgICAgICAgIGF3YWl0IHQubm9uZShzcWwuYXJyYXkucmVtb3ZlKTtcbiAgICAgICAgICBhd2FpdCB0Lm5vbmUoc3FsLmFycmF5LmNvbnRhaW5zQWxsKTtcbiAgICAgICAgICBhd2FpdCB0Lm5vbmUoc3FsLmFycmF5LmNvbnRhaW5zQWxsUmVnZXgpO1xuICAgICAgICAgIGF3YWl0IHQubm9uZShzcWwuYXJyYXkuY29udGFpbnMpO1xuICAgICAgICAgIHJldHVybiB0LmN0eDtcbiAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oY3R4ID0+IHtcbiAgICAgICAgZGVidWcoYGluaXRpYWxpemF0aW9uRG9uZSBpbiAke2N0eC5kdXJhdGlvbn1gKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgfSk7XG4gIH1cblxuICBhc3luYyBjcmVhdGVJbmRleGVzKGNsYXNzTmFtZTogc3RyaW5nLCBpbmRleGVzOiBhbnksIGNvbm46ID9hbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gKGNvbm4gfHwgdGhpcy5fY2xpZW50KS50eCh0ID0+XG4gICAgICB0LmJhdGNoKFxuICAgICAgICBpbmRleGVzLm1hcChpID0+IHtcbiAgICAgICAgICByZXR1cm4gdC5ub25lKCdDUkVBVEUgSU5ERVggSUYgTk9UIEVYSVNUUyAkMTpuYW1lIE9OICQyOm5hbWUgKCQzOm5hbWUpJywgW1xuICAgICAgICAgICAgaS5uYW1lLFxuICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgaS5rZXksXG4gICAgICAgICAgXSk7XG4gICAgICAgIH0pXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZUluZGV4ZXNJZk5lZWRlZChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBmaWVsZE5hbWU6IHN0cmluZyxcbiAgICB0eXBlOiBhbnksXG4gICAgY29ubjogP2FueVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCAoY29ubiB8fCB0aGlzLl9jbGllbnQpLm5vbmUoJ0NSRUFURSBJTkRFWCBJRiBOT1QgRVhJU1RTICQxOm5hbWUgT04gJDI6bmFtZSAoJDM6bmFtZSknLCBbXG4gICAgICBmaWVsZE5hbWUsXG4gICAgICBjbGFzc05hbWUsXG4gICAgICB0eXBlLFxuICAgIF0pO1xuICB9XG5cbiAgYXN5bmMgZHJvcEluZGV4ZXMoY2xhc3NOYW1lOiBzdHJpbmcsIGluZGV4ZXM6IGFueSwgY29ubjogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcXVlcmllcyA9IGluZGV4ZXMubWFwKGkgPT4gKHtcbiAgICAgIHF1ZXJ5OiAnRFJPUCBJTkRFWCAkMTpuYW1lJyxcbiAgICAgIHZhbHVlczogaSxcbiAgICB9KSk7XG4gICAgYXdhaXQgKGNvbm4gfHwgdGhpcy5fY2xpZW50KS50eCh0ID0+IHQubm9uZSh0aGlzLl9wZ3AuaGVscGVycy5jb25jYXQocXVlcmllcykpKTtcbiAgfVxuXG4gIGFzeW5jIGdldEluZGV4ZXMoY2xhc3NOYW1lOiBzdHJpbmcpIHtcbiAgICBjb25zdCBxcyA9ICdTRUxFQ1QgKiBGUk9NIHBnX2luZGV4ZXMgV0hFUkUgdGFibGVuYW1lID0gJHtjbGFzc05hbWV9JztcbiAgICByZXR1cm4gdGhpcy5fY2xpZW50LmFueShxcywgeyBjbGFzc05hbWUgfSk7XG4gIH1cblxuICBhc3luYyB1cGRhdGVTY2hlbWFXaXRoSW5kZXhlcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICAvLyBVc2VkIGZvciB0ZXN0aW5nIHB1cnBvc2VzXG4gIGFzeW5jIHVwZGF0ZUVzdGltYXRlZENvdW50KGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudC5ub25lKCdBTkFMWVpFICQxOm5hbWUnLCBbY2xhc3NOYW1lXSk7XG4gIH1cblxuICBhc3luYyBjcmVhdGVUcmFuc2FjdGlvbmFsU2Vzc2lvbigpOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uYWxTZXNzaW9uID0ge307XG4gICAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbi5yZXN1bHQgPSB0aGlzLl9jbGllbnQudHgodCA9PiB7XG4gICAgICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uLnQgPSB0O1xuICAgICAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbi5wcm9taXNlID0gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgdHJhbnNhY3Rpb25hbFNlc3Npb24ucmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICAgIH0pO1xuICAgICAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbi5iYXRjaCA9IFtdO1xuICAgICAgICByZXNvbHZlKHRyYW5zYWN0aW9uYWxTZXNzaW9uKTtcbiAgICAgICAgcmV0dXJuIHRyYW5zYWN0aW9uYWxTZXNzaW9uLnByb21pc2U7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGNvbW1pdFRyYW5zYWN0aW9uYWxTZXNzaW9uKHRyYW5zYWN0aW9uYWxTZXNzaW9uOiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbi5yZXNvbHZlKHRyYW5zYWN0aW9uYWxTZXNzaW9uLnQuYmF0Y2godHJhbnNhY3Rpb25hbFNlc3Npb24uYmF0Y2gpKTtcbiAgICByZXR1cm4gdHJhbnNhY3Rpb25hbFNlc3Npb24ucmVzdWx0O1xuICB9XG5cbiAgYWJvcnRUcmFuc2FjdGlvbmFsU2Vzc2lvbih0cmFuc2FjdGlvbmFsU2Vzc2lvbjogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcmVzdWx0ID0gdHJhbnNhY3Rpb25hbFNlc3Npb24ucmVzdWx0LmNhdGNoKCk7XG4gICAgdHJhbnNhY3Rpb25hbFNlc3Npb24uYmF0Y2gucHVzaChQcm9taXNlLnJlamVjdCgpKTtcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbi5yZXNvbHZlKHRyYW5zYWN0aW9uYWxTZXNzaW9uLnQuYmF0Y2godHJhbnNhY3Rpb25hbFNlc3Npb24uYmF0Y2gpKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgYXN5bmMgZW5zdXJlSW5kZXgoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIGZpZWxkTmFtZXM6IHN0cmluZ1tdLFxuICAgIGluZGV4TmFtZTogP3N0cmluZyxcbiAgICBjYXNlSW5zZW5zaXRpdmU6IGJvb2xlYW4gPSBmYWxzZSxcbiAgICBvcHRpb25zPzogT2JqZWN0ID0ge31cbiAgKTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCBjb25uID0gb3B0aW9ucy5jb25uICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNvbm4gOiB0aGlzLl9jbGllbnQ7XG4gICAgY29uc3QgZGVmYXVsdEluZGV4TmFtZSA9IGBwYXJzZV9kZWZhdWx0XyR7ZmllbGROYW1lcy5zb3J0KCkuam9pbignXycpfWA7XG4gICAgY29uc3QgaW5kZXhOYW1lT3B0aW9uczogT2JqZWN0ID1cbiAgICAgIGluZGV4TmFtZSAhPSBudWxsID8geyBuYW1lOiBpbmRleE5hbWUgfSA6IHsgbmFtZTogZGVmYXVsdEluZGV4TmFtZSB9O1xuICAgIGNvbnN0IGNvbnN0cmFpbnRQYXR0ZXJucyA9IGNhc2VJbnNlbnNpdGl2ZVxuICAgICAgPyBmaWVsZE5hbWVzLm1hcCgoZmllbGROYW1lLCBpbmRleCkgPT4gYGxvd2VyKCQke2luZGV4ICsgM306bmFtZSkgdmFyY2hhcl9wYXR0ZXJuX29wc2ApXG4gICAgICA6IGZpZWxkTmFtZXMubWFwKChmaWVsZE5hbWUsIGluZGV4KSA9PiBgJCR7aW5kZXggKyAzfTpuYW1lYCk7XG4gICAgY29uc3QgcXMgPSBgQ1JFQVRFIElOREVYIElGIE5PVCBFWElTVFMgJDE6bmFtZSBPTiAkMjpuYW1lICgke2NvbnN0cmFpbnRQYXR0ZXJucy5qb2luKCl9KWA7XG4gICAgYXdhaXQgY29ubi5ub25lKHFzLCBbaW5kZXhOYW1lT3B0aW9ucy5uYW1lLCBjbGFzc05hbWUsIC4uLmZpZWxkTmFtZXNdKS5jYXRjaChlcnJvciA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIGVycm9yLmNvZGUgPT09IFBvc3RncmVzRHVwbGljYXRlUmVsYXRpb25FcnJvciAmJlxuICAgICAgICBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKGluZGV4TmFtZU9wdGlvbnMubmFtZSlcbiAgICAgICkge1xuICAgICAgICAvLyBJbmRleCBhbHJlYWR5IGV4aXN0cy4gSWdub3JlIGVycm9yLlxuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgZXJyb3IuY29kZSA9PT0gUG9zdGdyZXNVbmlxdWVJbmRleFZpb2xhdGlvbkVycm9yICYmXG4gICAgICAgIGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoaW5kZXhOYW1lT3B0aW9ucy5uYW1lKVxuICAgICAgKSB7XG4gICAgICAgIC8vIENhc3QgdGhlIGVycm9yIGludG8gdGhlIHByb3BlciBwYXJzZSBlcnJvclxuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFLFxuICAgICAgICAgICdBIGR1cGxpY2F0ZSB2YWx1ZSBmb3IgYSBmaWVsZCB3aXRoIHVuaXF1ZSB2YWx1ZXMgd2FzIHByb3ZpZGVkJ1xuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29udmVydFBvbHlnb25Ub1NRTChwb2x5Z29uKSB7XG4gIGlmIChwb2x5Z29uLmxlbmd0aCA8IDMpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCBgUG9seWdvbiBtdXN0IGhhdmUgYXQgbGVhc3QgMyB2YWx1ZXNgKTtcbiAgfVxuICBpZiAoXG4gICAgcG9seWdvblswXVswXSAhPT0gcG9seWdvbltwb2x5Z29uLmxlbmd0aCAtIDFdWzBdIHx8XG4gICAgcG9seWdvblswXVsxXSAhPT0gcG9seWdvbltwb2x5Z29uLmxlbmd0aCAtIDFdWzFdXG4gICkge1xuICAgIHBvbHlnb24ucHVzaChwb2x5Z29uWzBdKTtcbiAgfVxuICBjb25zdCB1bmlxdWUgPSBwb2x5Z29uLmZpbHRlcigoaXRlbSwgaW5kZXgsIGFyKSA9PiB7XG4gICAgbGV0IGZvdW5kSW5kZXggPSAtMTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCBwdCA9IGFyW2ldO1xuICAgICAgaWYgKHB0WzBdID09PSBpdGVtWzBdICYmIHB0WzFdID09PSBpdGVtWzFdKSB7XG4gICAgICAgIGZvdW5kSW5kZXggPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZvdW5kSW5kZXggPT09IGluZGV4O1xuICB9KTtcbiAgaWYgKHVuaXF1ZS5sZW5ndGggPCAzKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgJ0dlb0pTT046IExvb3AgbXVzdCBoYXZlIGF0IGxlYXN0IDMgZGlmZmVyZW50IHZlcnRpY2VzJ1xuICAgICk7XG4gIH1cbiAgY29uc3QgcG9pbnRzID0gcG9seWdvblxuICAgIC5tYXAocG9pbnQgPT4ge1xuICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBhcnNlRmxvYXQocG9pbnRbMV0pLCBwYXJzZUZsb2F0KHBvaW50WzBdKSk7XG4gICAgICByZXR1cm4gYCgke3BvaW50WzFdfSwgJHtwb2ludFswXX0pYDtcbiAgICB9KVxuICAgIC5qb2luKCcsICcpO1xuICByZXR1cm4gYCgke3BvaW50c30pYDtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlV2hpdGVTcGFjZShyZWdleCkge1xuICBpZiAoIXJlZ2V4LmVuZHNXaXRoKCdcXG4nKSkge1xuICAgIHJlZ2V4ICs9ICdcXG4nO1xuICB9XG5cbiAgLy8gcmVtb3ZlIG5vbiBlc2NhcGVkIGNvbW1lbnRzXG4gIHJldHVybiAoXG4gICAgcmVnZXhcbiAgICAgIC5yZXBsYWNlKC8oW15cXFxcXSkjLipcXG4vZ2ltLCAnJDEnKVxuICAgICAgLy8gcmVtb3ZlIGxpbmVzIHN0YXJ0aW5nIHdpdGggYSBjb21tZW50XG4gICAgICAucmVwbGFjZSgvXiMuKlxcbi9naW0sICcnKVxuICAgICAgLy8gcmVtb3ZlIG5vbiBlc2NhcGVkIHdoaXRlc3BhY2VcbiAgICAgIC5yZXBsYWNlKC8oW15cXFxcXSlcXHMrL2dpbSwgJyQxJylcbiAgICAgIC8vIHJlbW92ZSB3aGl0ZXNwYWNlIGF0IHRoZSBiZWdpbm5pbmcgb2YgYSBsaW5lXG4gICAgICAucmVwbGFjZSgvXlxccysvLCAnJylcbiAgICAgIC50cmltKClcbiAgKTtcbn1cblxuZnVuY3Rpb24gcHJvY2Vzc1JlZ2V4UGF0dGVybihzKSB7XG4gIGlmIChzICYmIHMuc3RhcnRzV2l0aCgnXicpKSB7XG4gICAgLy8gcmVnZXggZm9yIHN0YXJ0c1dpdGhcbiAgICByZXR1cm4gJ14nICsgbGl0ZXJhbGl6ZVJlZ2V4UGFydChzLnNsaWNlKDEpKTtcbiAgfSBlbHNlIGlmIChzICYmIHMuZW5kc1dpdGgoJyQnKSkge1xuICAgIC8vIHJlZ2V4IGZvciBlbmRzV2l0aFxuICAgIHJldHVybiBsaXRlcmFsaXplUmVnZXhQYXJ0KHMuc2xpY2UoMCwgcy5sZW5ndGggLSAxKSkgKyAnJCc7XG4gIH1cblxuICAvLyByZWdleCBmb3IgY29udGFpbnNcbiAgcmV0dXJuIGxpdGVyYWxpemVSZWdleFBhcnQocyk7XG59XG5cbmZ1bmN0aW9uIGlzU3RhcnRzV2l0aFJlZ2V4KHZhbHVlKSB7XG4gIGlmICghdmFsdWUgfHwgdHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJyB8fCAhdmFsdWUuc3RhcnRzV2l0aCgnXicpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgbWF0Y2hlcyA9IHZhbHVlLm1hdGNoKC9cXF5cXFxcUS4qXFxcXEUvKTtcbiAgcmV0dXJuICEhbWF0Y2hlcztcbn1cblxuZnVuY3Rpb24gaXNBbGxWYWx1ZXNSZWdleE9yTm9uZSh2YWx1ZXMpIHtcbiAgaWYgKCF2YWx1ZXMgfHwgIUFycmF5LmlzQXJyYXkodmFsdWVzKSB8fCB2YWx1ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBjb25zdCBmaXJzdFZhbHVlc0lzUmVnZXggPSBpc1N0YXJ0c1dpdGhSZWdleCh2YWx1ZXNbMF0uJHJlZ2V4KTtcbiAgaWYgKHZhbHVlcy5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gZmlyc3RWYWx1ZXNJc1JlZ2V4O1xuICB9XG5cbiAgZm9yIChsZXQgaSA9IDEsIGxlbmd0aCA9IHZhbHVlcy5sZW5ndGg7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGlmIChmaXJzdFZhbHVlc0lzUmVnZXggIT09IGlzU3RhcnRzV2l0aFJlZ2V4KHZhbHVlc1tpXS4kcmVnZXgpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGlzQW55VmFsdWVSZWdleFN0YXJ0c1dpdGgodmFsdWVzKSB7XG4gIHJldHVybiB2YWx1ZXMuc29tZShmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gaXNTdGFydHNXaXRoUmVnZXgodmFsdWUuJHJlZ2V4KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUxpdGVyYWxSZWdleChyZW1haW5pbmcpIHtcbiAgcmV0dXJuIHJlbWFpbmluZ1xuICAgIC5zcGxpdCgnJylcbiAgICAubWFwKGMgPT4ge1xuICAgICAgY29uc3QgcmVnZXggPSBSZWdFeHAoJ1swLTkgXXxcXFxccHtMfScsICd1Jyk7IC8vIFN1cHBvcnQgYWxsIHVuaWNvZGUgbGV0dGVyIGNoYXJzXG4gICAgICBpZiAoYy5tYXRjaChyZWdleCkgIT09IG51bGwpIHtcbiAgICAgICAgLy8gZG9uJ3QgZXNjYXBlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzXG4gICAgICAgIHJldHVybiBjO1xuICAgICAgfVxuICAgICAgLy8gZXNjYXBlIGV2ZXJ5dGhpbmcgZWxzZSAoc2luZ2xlIHF1b3RlcyB3aXRoIHNpbmdsZSBxdW90ZXMsIGV2ZXJ5dGhpbmcgZWxzZSB3aXRoIGEgYmFja3NsYXNoKVxuICAgICAgcmV0dXJuIGMgPT09IGAnYCA/IGAnJ2AgOiBgXFxcXCR7Y31gO1xuICAgIH0pXG4gICAgLmpvaW4oJycpO1xufVxuXG5mdW5jdGlvbiBsaXRlcmFsaXplUmVnZXhQYXJ0KHM6IHN0cmluZykge1xuICBjb25zdCBtYXRjaGVyMSA9IC9cXFxcUSgoPyFcXFxcRSkuKilcXFxcRSQvO1xuICBjb25zdCByZXN1bHQxOiBhbnkgPSBzLm1hdGNoKG1hdGNoZXIxKTtcbiAgaWYgKHJlc3VsdDEgJiYgcmVzdWx0MS5sZW5ndGggPiAxICYmIHJlc3VsdDEuaW5kZXggPiAtMSkge1xuICAgIC8vIHByb2Nlc3MgcmVnZXggdGhhdCBoYXMgYSBiZWdpbm5pbmcgYW5kIGFuIGVuZCBzcGVjaWZpZWQgZm9yIHRoZSBsaXRlcmFsIHRleHRcbiAgICBjb25zdCBwcmVmaXggPSBzLnN1YnN0cigwLCByZXN1bHQxLmluZGV4KTtcbiAgICBjb25zdCByZW1haW5pbmcgPSByZXN1bHQxWzFdO1xuXG4gICAgcmV0dXJuIGxpdGVyYWxpemVSZWdleFBhcnQocHJlZml4KSArIGNyZWF0ZUxpdGVyYWxSZWdleChyZW1haW5pbmcpO1xuICB9XG5cbiAgLy8gcHJvY2VzcyByZWdleCB0aGF0IGhhcyBhIGJlZ2lubmluZyBzcGVjaWZpZWQgZm9yIHRoZSBsaXRlcmFsIHRleHRcbiAgY29uc3QgbWF0Y2hlcjIgPSAvXFxcXFEoKD8hXFxcXEUpLiopJC87XG4gIGNvbnN0IHJlc3VsdDI6IGFueSA9IHMubWF0Y2gobWF0Y2hlcjIpO1xuICBpZiAocmVzdWx0MiAmJiByZXN1bHQyLmxlbmd0aCA+IDEgJiYgcmVzdWx0Mi5pbmRleCA+IC0xKSB7XG4gICAgY29uc3QgcHJlZml4ID0gcy5zdWJzdHIoMCwgcmVzdWx0Mi5pbmRleCk7XG4gICAgY29uc3QgcmVtYWluaW5nID0gcmVzdWx0MlsxXTtcblxuICAgIHJldHVybiBsaXRlcmFsaXplUmVnZXhQYXJ0KHByZWZpeCkgKyBjcmVhdGVMaXRlcmFsUmVnZXgocmVtYWluaW5nKTtcbiAgfVxuXG4gIC8vIHJlbW92ZSBhbGwgaW5zdGFuY2VzIG9mIFxcUSBhbmQgXFxFIGZyb20gdGhlIHJlbWFpbmluZyB0ZXh0ICYgZXNjYXBlIHNpbmdsZSBxdW90ZXNcbiAgcmV0dXJuIHNcbiAgICAucmVwbGFjZSgvKFteXFxcXF0pKFxcXFxFKS8sICckMScpXG4gICAgLnJlcGxhY2UoLyhbXlxcXFxdKShcXFxcUSkvLCAnJDEnKVxuICAgIC5yZXBsYWNlKC9eXFxcXEUvLCAnJylcbiAgICAucmVwbGFjZSgvXlxcXFxRLywgJycpXG4gICAgLnJlcGxhY2UoLyhbXiddKScvLCBgJDEnJ2ApXG4gICAgLnJlcGxhY2UoL14nKFteJ10pLywgYCcnJDFgKTtcbn1cblxudmFyIEdlb1BvaW50Q29kZXIgPSB7XG4gIGlzVmFsaWRKU09OKHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgdmFsdWUuX190eXBlID09PSAnR2VvUG9pbnQnO1xuICB9LFxufTtcblxuZXhwb3J0IGRlZmF1bHQgUG9zdGdyZXNTdG9yYWdlQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/sql/array/add-unique.sql b/lib/Adapters/Storage/Postgres/sql/array/add-unique.sql new file mode 100644 index 0000000000..aad90d45f5 --- /dev/null +++ b/lib/Adapters/Storage/Postgres/sql/array/add-unique.sql @@ -0,0 +1,11 @@ +CREATE OR REPLACE FUNCTION array_add_unique( + "array" jsonb, + "values" jsonb +) + RETURNS jsonb + LANGUAGE sql + IMMUTABLE + STRICT +AS $function$ + SELECT array_to_json(ARRAY(SELECT DISTINCT unnest(ARRAY(SELECT DISTINCT jsonb_array_elements("array")) || ARRAY(SELECT DISTINCT jsonb_array_elements("values")))))::jsonb; +$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/array/add.sql b/lib/Adapters/Storage/Postgres/sql/array/add.sql new file mode 100644 index 0000000000..a0b5859908 --- /dev/null +++ b/lib/Adapters/Storage/Postgres/sql/array/add.sql @@ -0,0 +1,11 @@ +CREATE OR REPLACE FUNCTION array_add( + "array" jsonb, + "values" jsonb +) + RETURNS jsonb + LANGUAGE sql + IMMUTABLE + STRICT +AS $function$ + SELECT array_to_json(ARRAY(SELECT unnest(ARRAY(SELECT DISTINCT jsonb_array_elements("array")) || ARRAY(SELECT jsonb_array_elements("values")))))::jsonb; +$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql b/lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql new file mode 100644 index 0000000000..7ca5853a9f --- /dev/null +++ b/lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql @@ -0,0 +1,14 @@ +CREATE OR REPLACE FUNCTION array_contains_all_regex( + "array" jsonb, + "values" jsonb +) + RETURNS boolean + LANGUAGE sql + IMMUTABLE + STRICT +AS $function$ + SELECT CASE + WHEN 0 = jsonb_array_length("values") THEN true = false + ELSE (SELECT RES.CNT = jsonb_array_length("values") FROM (SELECT COUNT(*) as CNT FROM jsonb_array_elements_text("array") as elt WHERE elt LIKE ANY (SELECT jsonb_array_elements_text("values"))) as RES) + END; +$function$; \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/sql/array/contains-all.sql b/lib/Adapters/Storage/Postgres/sql/array/contains-all.sql new file mode 100644 index 0000000000..8db1ca0e7b --- /dev/null +++ b/lib/Adapters/Storage/Postgres/sql/array/contains-all.sql @@ -0,0 +1,14 @@ +CREATE OR REPLACE FUNCTION array_contains_all( + "array" jsonb, + "values" jsonb +) + RETURNS boolean + LANGUAGE sql + IMMUTABLE + STRICT +AS $function$ + SELECT CASE + WHEN 0 = jsonb_array_length("values") THEN true = false + ELSE (SELECT RES.CNT = jsonb_array_length("values") FROM (SELECT COUNT(*) as CNT FROM jsonb_array_elements_text("array") as elt WHERE elt IN (SELECT jsonb_array_elements_text("values"))) as RES) + END; +$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/array/contains.sql b/lib/Adapters/Storage/Postgres/sql/array/contains.sql new file mode 100644 index 0000000000..f7c458782e --- /dev/null +++ b/lib/Adapters/Storage/Postgres/sql/array/contains.sql @@ -0,0 +1,11 @@ +CREATE OR REPLACE FUNCTION array_contains( + "array" jsonb, + "values" jsonb +) + RETURNS boolean + LANGUAGE sql + IMMUTABLE + STRICT +AS $function$ + SELECT RES.CNT >= 1 FROM (SELECT COUNT(*) as CNT FROM jsonb_array_elements("array") as elt WHERE elt IN (SELECT jsonb_array_elements("values"))) as RES; +$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/array/remove.sql b/lib/Adapters/Storage/Postgres/sql/array/remove.sql new file mode 100644 index 0000000000..52895d2f46 --- /dev/null +++ b/lib/Adapters/Storage/Postgres/sql/array/remove.sql @@ -0,0 +1,11 @@ +CREATE OR REPLACE FUNCTION array_remove( + "array" jsonb, + "values" jsonb +) + RETURNS jsonb + LANGUAGE sql + IMMUTABLE + STRICT +AS $function$ + SELECT array_to_json(ARRAY(SELECT * FROM jsonb_array_elements("array") as elt WHERE elt NOT IN (SELECT * FROM (SELECT jsonb_array_elements("values")) AS sub)))::jsonb; +$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/index.js b/lib/Adapters/Storage/Postgres/sql/index.js new file mode 100644 index 0000000000..2fc76f3ab1 --- /dev/null +++ b/lib/Adapters/Storage/Postgres/sql/index.js @@ -0,0 +1,35 @@ +'use strict'; + +var QueryFile = require('pg-promise').QueryFile; + +var path = require('path'); + +module.exports = { + array: { + add: sql('array/add.sql'), + addUnique: sql('array/add-unique.sql'), + contains: sql('array/contains.sql'), + containsAll: sql('array/contains-all.sql'), + containsAllRegex: sql('array/contains-all-regex.sql'), + remove: sql('array/remove.sql') + }, + misc: { + jsonObjectSetKeys: sql('misc/json-object-set-keys.sql') + } +}; /////////////////////////////////////////////// +// Helper for linking to external query files; + +function sql(file) { + var fullPath = path.join(__dirname, file); // generating full path; + + var qf = new QueryFile(fullPath, { + minify: true + }); + + if (qf.error) { + throw qf.error; + } + + return qf; +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL1Bvc3RncmVzL3NxbC9pbmRleC5qcyJdLCJuYW1lcyI6WyJRdWVyeUZpbGUiLCJyZXF1aXJlIiwicGF0aCIsIm1vZHVsZSIsImV4cG9ydHMiLCJhcnJheSIsImFkZCIsInNxbCIsImFkZFVuaXF1ZSIsImNvbnRhaW5zIiwiY29udGFpbnNBbGwiLCJjb250YWluc0FsbFJlZ2V4IiwicmVtb3ZlIiwibWlzYyIsImpzb25PYmplY3RTZXRLZXlzIiwiZmlsZSIsImZ1bGxQYXRoIiwiam9pbiIsIl9fZGlybmFtZSIsInFmIiwibWluaWZ5IiwiZXJyb3IiXSwibWFwcGluZ3MiOiJBQUFBOztBQUVBLElBQUlBLFNBQVMsR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsU0FBdEM7O0FBQ0EsSUFBSUUsSUFBSSxHQUFHRCxPQUFPLENBQUMsTUFBRCxDQUFsQjs7QUFFQUUsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZDLEVBQUFBLEtBQUssRUFBRTtBQUNMQyxJQUFBQSxHQUFHLEVBQUVDLEdBQUcsQ0FBQyxlQUFELENBREg7QUFFTEMsSUFBQUEsU0FBUyxFQUFFRCxHQUFHLENBQUMsc0JBQUQsQ0FGVDtBQUdMRSxJQUFBQSxRQUFRLEVBQUVGLEdBQUcsQ0FBQyxvQkFBRCxDQUhSO0FBSUxHLElBQUFBLFdBQVcsRUFBRUgsR0FBRyxDQUFDLHdCQUFELENBSlg7QUFLTEksSUFBQUEsZ0JBQWdCLEVBQUVKLEdBQUcsQ0FBQyw4QkFBRCxDQUxoQjtBQU1MSyxJQUFBQSxNQUFNLEVBQUVMLEdBQUcsQ0FBQyxrQkFBRDtBQU5OLEdBRFE7QUFTZk0sRUFBQUEsSUFBSSxFQUFFO0FBQ0pDLElBQUFBLGlCQUFpQixFQUFFUCxHQUFHLENBQUMsK0JBQUQ7QUFEbEI7QUFUUyxDQUFqQixDLENBY0E7QUFDQTs7QUFDQSxTQUFTQSxHQUFULENBQWFRLElBQWIsRUFBbUI7QUFDakIsTUFBSUMsUUFBUSxHQUFHZCxJQUFJLENBQUNlLElBQUwsQ0FBVUMsU0FBVixFQUFxQkgsSUFBckIsQ0FBZixDQURpQixDQUMwQjs7QUFFM0MsTUFBSUksRUFBRSxHQUFHLElBQUluQixTQUFKLENBQWNnQixRQUFkLEVBQXdCO0FBQUVJLElBQUFBLE1BQU0sRUFBRTtBQUFWLEdBQXhCLENBQVQ7O0FBRUEsTUFBSUQsRUFBRSxDQUFDRSxLQUFQLEVBQWM7QUFDWixVQUFNRixFQUFFLENBQUNFLEtBQVQ7QUFDRDs7QUFFRCxTQUFPRixFQUFQO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBRdWVyeUZpbGUgPSByZXF1aXJlKCdwZy1wcm9taXNlJykuUXVlcnlGaWxlO1xudmFyIHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBhcnJheToge1xuICAgIGFkZDogc3FsKCdhcnJheS9hZGQuc3FsJyksXG4gICAgYWRkVW5pcXVlOiBzcWwoJ2FycmF5L2FkZC11bmlxdWUuc3FsJyksXG4gICAgY29udGFpbnM6IHNxbCgnYXJyYXkvY29udGFpbnMuc3FsJyksXG4gICAgY29udGFpbnNBbGw6IHNxbCgnYXJyYXkvY29udGFpbnMtYWxsLnNxbCcpLFxuICAgIGNvbnRhaW5zQWxsUmVnZXg6IHNxbCgnYXJyYXkvY29udGFpbnMtYWxsLXJlZ2V4LnNxbCcpLFxuICAgIHJlbW92ZTogc3FsKCdhcnJheS9yZW1vdmUuc3FsJyksXG4gIH0sXG4gIG1pc2M6IHtcbiAgICBqc29uT2JqZWN0U2V0S2V5czogc3FsKCdtaXNjL2pzb24tb2JqZWN0LXNldC1rZXlzLnNxbCcpLFxuICB9LFxufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIEhlbHBlciBmb3IgbGlua2luZyB0byBleHRlcm5hbCBxdWVyeSBmaWxlcztcbmZ1bmN0aW9uIHNxbChmaWxlKSB7XG4gIHZhciBmdWxsUGF0aCA9IHBhdGguam9pbihfX2Rpcm5hbWUsIGZpbGUpOyAvLyBnZW5lcmF0aW5nIGZ1bGwgcGF0aDtcblxuICB2YXIgcWYgPSBuZXcgUXVlcnlGaWxlKGZ1bGxQYXRoLCB7IG1pbmlmeTogdHJ1ZSB9KTtcblxuICBpZiAocWYuZXJyb3IpIHtcbiAgICB0aHJvdyBxZi5lcnJvcjtcbiAgfVxuXG4gIHJldHVybiBxZjtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql b/lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql new file mode 100644 index 0000000000..eb28b36928 --- /dev/null +++ b/lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql @@ -0,0 +1,19 @@ +-- Function to set a key on a nested JSON document + +CREATE OR REPLACE FUNCTION json_object_set_key( + "json" jsonb, + key_to_set TEXT, + value_to_set anyelement +) + RETURNS jsonb + LANGUAGE sql + IMMUTABLE + STRICT +AS $function$ +SELECT concat('{', string_agg(to_json("key") || ':' || "value", ','), '}')::jsonb + FROM (SELECT * + FROM jsonb_each("json") + WHERE key <> key_to_set + UNION ALL + SELECT key_to_set, to_json("value_to_set")::jsonb) AS fields +$function$; diff --git a/lib/Adapters/Storage/StorageAdapter.js b/lib/Adapters/Storage/StorageAdapter.js new file mode 100644 index 0000000000..4310b4ffac --- /dev/null +++ b/lib/Adapters/Storage/StorageAdapter.js @@ -0,0 +1,2 @@ +"use strict"; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbXX0= \ No newline at end of file diff --git a/lib/Adapters/WebSocketServer/WSAdapter.js b/lib/Adapters/WebSocketServer/WSAdapter.js new file mode 100644 index 0000000000..bfd5224448 --- /dev/null +++ b/lib/Adapters/WebSocketServer/WSAdapter.js @@ -0,0 +1,45 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.WSAdapter = void 0; + +var _WSSAdapter = require("./WSSAdapter"); + +/*eslint no-unused-vars: "off"*/ +const WebSocketServer = require('ws').Server; +/** + * Wrapper for ws node module + */ + + +class WSAdapter extends _WSSAdapter.WSSAdapter { + constructor(options) { + super(options); + this.options = options; + } + + onListen() {} + + onConnection(ws) {} + + onError(error) {} + + start() { + const wss = new WebSocketServer({ + server: this.options.server + }); + wss.on('listening', this.onListen); + wss.on('connection', this.onConnection); + wss.on('error', this.onError); + } + + close() {} + +} + +exports.WSAdapter = WSAdapter; +var _default = WSAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9XZWJTb2NrZXRTZXJ2ZXIvV1NBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIldlYlNvY2tldFNlcnZlciIsInJlcXVpcmUiLCJTZXJ2ZXIiLCJXU0FkYXB0ZXIiLCJXU1NBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJvcHRpb25zIiwib25MaXN0ZW4iLCJvbkNvbm5lY3Rpb24iLCJ3cyIsIm9uRXJyb3IiLCJlcnJvciIsInN0YXJ0Iiwid3NzIiwic2VydmVyIiwib24iLCJjbG9zZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUNBOztBQURBO0FBRUEsTUFBTUEsZUFBZSxHQUFHQyxPQUFPLENBQUMsSUFBRCxDQUFQLENBQWNDLE1BQXRDO0FBRUE7QUFDQTtBQUNBOzs7QUFDTyxNQUFNQyxTQUFOLFNBQXdCQyxzQkFBeEIsQ0FBbUM7QUFDeENDLEVBQUFBLFdBQVcsQ0FBQ0MsT0FBRCxFQUFlO0FBQ3hCLFVBQU1BLE9BQU47QUFDQSxTQUFLQSxPQUFMLEdBQWVBLE9BQWY7QUFDRDs7QUFFREMsRUFBQUEsUUFBUSxHQUFHLENBQUU7O0FBQ2JDLEVBQUFBLFlBQVksQ0FBQ0MsRUFBRCxFQUFLLENBQUU7O0FBQ25CQyxFQUFBQSxPQUFPLENBQUNDLEtBQUQsRUFBUSxDQUFFOztBQUNqQkMsRUFBQUEsS0FBSyxHQUFHO0FBQ04sVUFBTUMsR0FBRyxHQUFHLElBQUliLGVBQUosQ0FBb0I7QUFBRWMsTUFBQUEsTUFBTSxFQUFFLEtBQUtSLE9BQUwsQ0FBYVE7QUFBdkIsS0FBcEIsQ0FBWjtBQUNBRCxJQUFBQSxHQUFHLENBQUNFLEVBQUosQ0FBTyxXQUFQLEVBQW9CLEtBQUtSLFFBQXpCO0FBQ0FNLElBQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLFlBQVAsRUFBcUIsS0FBS1AsWUFBMUI7QUFDQUssSUFBQUEsR0FBRyxDQUFDRSxFQUFKLENBQU8sT0FBUCxFQUFnQixLQUFLTCxPQUFyQjtBQUNEOztBQUNETSxFQUFBQSxLQUFLLEdBQUcsQ0FBRTs7QUFmOEI7OztlQWtCM0JiLFMiLCJzb3VyY2VzQ29udGVudCI6WyIvKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG5pbXBvcnQgeyBXU1NBZGFwdGVyIH0gZnJvbSAnLi9XU1NBZGFwdGVyJztcbmNvbnN0IFdlYlNvY2tldFNlcnZlciA9IHJlcXVpcmUoJ3dzJykuU2VydmVyO1xuXG4vKipcbiAqIFdyYXBwZXIgZm9yIHdzIG5vZGUgbW9kdWxlXG4gKi9cbmV4cG9ydCBjbGFzcyBXU0FkYXB0ZXIgZXh0ZW5kcyBXU1NBZGFwdGVyIHtcbiAgY29uc3RydWN0b3Iob3B0aW9uczogYW55KSB7XG4gICAgc3VwZXIob3B0aW9ucyk7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgfVxuXG4gIG9uTGlzdGVuKCkge31cbiAgb25Db25uZWN0aW9uKHdzKSB7fVxuICBvbkVycm9yKGVycm9yKSB7fVxuICBzdGFydCgpIHtcbiAgICBjb25zdCB3c3MgPSBuZXcgV2ViU29ja2V0U2VydmVyKHsgc2VydmVyOiB0aGlzLm9wdGlvbnMuc2VydmVyIH0pO1xuICAgIHdzcy5vbignbGlzdGVuaW5nJywgdGhpcy5vbkxpc3Rlbik7XG4gICAgd3NzLm9uKCdjb25uZWN0aW9uJywgdGhpcy5vbkNvbm5lY3Rpb24pO1xuICAgIHdzcy5vbignZXJyb3InLCB0aGlzLm9uRXJyb3IpO1xuICB9XG4gIGNsb3NlKCkge31cbn1cblxuZXhwb3J0IGRlZmF1bHQgV1NBZGFwdGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/WebSocketServer/WSSAdapter.js b/lib/Adapters/WebSocketServer/WSSAdapter.js new file mode 100644 index 0000000000..1b29837db0 --- /dev/null +++ b/lib/Adapters/WebSocketServer/WSSAdapter.js @@ -0,0 +1,74 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.WSSAdapter = void 0; + +/*eslint no-unused-vars: "off"*/ +// WebSocketServer Adapter +// +// Adapter classes must implement the following functions: +// * onListen() +// * onConnection(ws) +// * onError(error) +// * start() +// * close() +// +// Default is WSAdapter. The above functions will be binded. + +/** + * @module Adapters + */ + +/** + * @interface WSSAdapter + */ +class WSSAdapter { + /** + * @param {Object} options - {http.Server|https.Server} server + */ + constructor(options) { + this.onListen = () => {}; + + this.onConnection = () => {}; + + this.onError = () => {}; + } // /** + // * Emitted when the underlying server has been bound. + // */ + // onListen() {} + // /** + // * Emitted when the handshake is complete. + // * + // * @param {WebSocket} ws - RFC 6455 WebSocket. + // */ + // onConnection(ws) {} + // /** + // * Emitted when error event is called. + // * + // * @param {Error} error - WebSocketServer error + // */ + // onError(error) {} + + /** + * Initialize Connection. + * + * @param {Object} options + */ + + + start(options) {} + /** + * Closes server. + */ + + + close() {} + +} + +exports.WSSAdapter = WSSAdapter; +var _default = WSSAdapter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9XZWJTb2NrZXRTZXJ2ZXIvV1NTQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJXU1NBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJvcHRpb25zIiwib25MaXN0ZW4iLCJvbkNvbm5lY3Rpb24iLCJvbkVycm9yIiwic3RhcnQiLCJjbG9zZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU1BLFVBQU4sQ0FBaUI7QUFDdEI7QUFDRjtBQUNBO0FBQ0VDLEVBQUFBLFdBQVcsQ0FBQ0MsT0FBRCxFQUFVO0FBQ25CLFNBQUtDLFFBQUwsR0FBZ0IsTUFBTSxDQUFFLENBQXhCOztBQUNBLFNBQUtDLFlBQUwsR0FBb0IsTUFBTSxDQUFFLENBQTVCOztBQUNBLFNBQUtDLE9BQUwsR0FBZSxNQUFNLENBQUUsQ0FBdkI7QUFDRCxHQVJxQixDQVV0QjtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNGO0FBQ0E7QUFDQTtBQUNBOzs7QUFDRUMsRUFBQUEsS0FBSyxDQUFDSixPQUFELEVBQVUsQ0FBRTtBQUVqQjtBQUNGO0FBQ0E7OztBQUNFSyxFQUFBQSxLQUFLLEdBQUcsQ0FBRTs7QUF2Q1k7OztlQTBDVFAsVSIsInNvdXJjZXNDb250ZW50IjpbIi8qZXNsaW50IG5vLXVudXNlZC12YXJzOiBcIm9mZlwiKi9cbi8vIFdlYlNvY2tldFNlcnZlciBBZGFwdGVyXG4vL1xuLy8gQWRhcHRlciBjbGFzc2VzIG11c3QgaW1wbGVtZW50IHRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zOlxuLy8gKiBvbkxpc3RlbigpXG4vLyAqIG9uQ29ubmVjdGlvbih3cylcbi8vICogb25FcnJvcihlcnJvcilcbi8vICogc3RhcnQoKVxuLy8gKiBjbG9zZSgpXG4vL1xuLy8gRGVmYXVsdCBpcyBXU0FkYXB0ZXIuIFRoZSBhYm92ZSBmdW5jdGlvbnMgd2lsbCBiZSBiaW5kZWQuXG5cbi8qKlxuICogQG1vZHVsZSBBZGFwdGVyc1xuICovXG4vKipcbiAqIEBpbnRlcmZhY2UgV1NTQWRhcHRlclxuICovXG5leHBvcnQgY2xhc3MgV1NTQWRhcHRlciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIHtodHRwLlNlcnZlcnxodHRwcy5TZXJ2ZXJ9IHNlcnZlclxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgIHRoaXMub25MaXN0ZW4gPSAoKSA9PiB7fTtcbiAgICB0aGlzLm9uQ29ubmVjdGlvbiA9ICgpID0+IHt9O1xuICAgIHRoaXMub25FcnJvciA9ICgpID0+IHt9O1xuICB9XG5cbiAgLy8gLyoqXG4gIC8vICAqIEVtaXR0ZWQgd2hlbiB0aGUgdW5kZXJseWluZyBzZXJ2ZXIgaGFzIGJlZW4gYm91bmQuXG4gIC8vICAqL1xuICAvLyBvbkxpc3RlbigpIHt9XG5cbiAgLy8gLyoqXG4gIC8vICAqIEVtaXR0ZWQgd2hlbiB0aGUgaGFuZHNoYWtlIGlzIGNvbXBsZXRlLlxuICAvLyAgKlxuICAvLyAgKiBAcGFyYW0ge1dlYlNvY2tldH0gd3MgLSBSRkMgNjQ1NSBXZWJTb2NrZXQuXG4gIC8vICAqL1xuICAvLyBvbkNvbm5lY3Rpb24od3MpIHt9XG5cbiAgLy8gLyoqXG4gIC8vICAqIEVtaXR0ZWQgd2hlbiBlcnJvciBldmVudCBpcyBjYWxsZWQuXG4gIC8vICAqXG4gIC8vICAqIEBwYXJhbSB7RXJyb3J9IGVycm9yIC0gV2ViU29ja2V0U2VydmVyIGVycm9yXG4gIC8vICAqL1xuICAvLyBvbkVycm9yKGVycm9yKSB7fVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIENvbm5lY3Rpb24uXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAqL1xuICBzdGFydChvcHRpb25zKSB7fVxuXG4gIC8qKlxuICAgKiBDbG9zZXMgc2VydmVyLlxuICAgKi9cbiAgY2xvc2UoKSB7fVxufVxuXG5leHBvcnQgZGVmYXVsdCBXU1NBZGFwdGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Auth.js b/lib/Auth.js new file mode 100644 index 0000000000..7fe33b66de --- /dev/null +++ b/lib/Auth.js @@ -0,0 +1,373 @@ +"use strict"; + +const cryptoUtils = require('./cryptoUtils'); + +const RestQuery = require('./RestQuery'); + +const Parse = require('parse/node'); // An Auth object tells you who is requesting something and whether +// the master key was used. +// userObject is a Parse.User and can be null if there's no user. + + +function Auth({ + config, + cacheController = undefined, + isMaster = false, + isReadOnly = false, + user, + installationId +}) { + this.config = config; + this.cacheController = cacheController || config && config.cacheController; + this.installationId = installationId; + this.isMaster = isMaster; + this.user = user; + this.isReadOnly = isReadOnly; // Assuming a users roles won't change during a single request, we'll + // only load them once. + + this.userRoles = []; + this.fetchedRoles = false; + this.rolePromise = null; +} // Whether this auth could possibly modify the given user id. +// It still could be forbidden via ACLs even if this returns true. + + +Auth.prototype.isUnauthenticated = function () { + if (this.isMaster) { + return false; + } + + if (this.user) { + return false; + } + + return true; +}; // A helper to get a master-level Auth object + + +function master(config) { + return new Auth({ + config, + isMaster: true + }); +} // A helper to get a master-level Auth object + + +function readOnly(config) { + return new Auth({ + config, + isMaster: true, + isReadOnly: true + }); +} // A helper to get a nobody-level Auth object + + +function nobody(config) { + return new Auth({ + config, + isMaster: false + }); +} // Returns a promise that resolves to an Auth object + + +const getAuthForSessionToken = async function ({ + config, + cacheController, + sessionToken, + installationId +}) { + cacheController = cacheController || config && config.cacheController; + + if (cacheController) { + const userJSON = await cacheController.user.get(sessionToken); + + if (userJSON) { + const cachedUser = Parse.Object.fromJSON(userJSON); + return Promise.resolve(new Auth({ + config, + cacheController, + isMaster: false, + installationId, + user: cachedUser + })); + } + } + + let results; + + if (config) { + const restOptions = { + limit: 1, + include: 'user' + }; + const query = new RestQuery(config, master(config), '_Session', { + sessionToken + }, restOptions); + results = (await query.execute()).results; + } else { + results = (await new Parse.Query(Parse.Session).limit(1).include('user').equalTo('sessionToken', sessionToken).find({ + useMasterKey: true + })).map(obj => obj.toJSON()); + } + + if (results.length !== 1 || !results[0]['user']) { + throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); + } + + const now = new Date(), + expiresAt = results[0].expiresAt ? new Date(results[0].expiresAt.iso) : undefined; + + if (expiresAt < now) { + throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Session token is expired.'); + } + + const obj = results[0]['user']; + delete obj.password; + obj['className'] = '_User'; + obj['sessionToken'] = sessionToken; + + if (cacheController) { + cacheController.user.put(sessionToken, obj); + } + + const userObject = Parse.Object.fromJSON(obj); + return new Auth({ + config, + cacheController, + isMaster: false, + installationId, + user: userObject + }); +}; + +var getAuthForLegacySessionToken = function ({ + config, + sessionToken, + installationId +}) { + var restOptions = { + limit: 1 + }; + var query = new RestQuery(config, master(config), '_User', { + sessionToken + }, restOptions); + return query.execute().then(response => { + var results = response.results; + + if (results.length !== 1) { + throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'invalid legacy session token'); + } + + const obj = results[0]; + obj.className = '_User'; + const userObject = Parse.Object.fromJSON(obj); + return new Auth({ + config, + isMaster: false, + installationId, + user: userObject + }); + }); +}; // Returns a promise that resolves to an array of role names + + +Auth.prototype.getUserRoles = function () { + if (this.isMaster || !this.user) { + return Promise.resolve([]); + } + + if (this.fetchedRoles) { + return Promise.resolve(this.userRoles); + } + + if (this.rolePromise) { + return this.rolePromise; + } + + this.rolePromise = this._loadRoles(); + return this.rolePromise; +}; + +Auth.prototype.getRolesForUser = async function () { + //Stack all Parse.Role + const results = []; + + if (this.config) { + const restWhere = { + users: { + __type: 'Pointer', + className: '_User', + objectId: this.user.id + } + }; + await new RestQuery(this.config, master(this.config), '_Role', restWhere, {}).each(result => results.push(result)); + } else { + await new Parse.Query(Parse.Role).equalTo('users', this.user).each(result => results.push(result.toJSON()), { + useMasterKey: true + }); + } + + return results; +}; // Iterates through the role tree and compiles a user's roles + + +Auth.prototype._loadRoles = async function () { + if (this.cacheController) { + const cachedRoles = await this.cacheController.role.get(this.user.id); + + if (cachedRoles != null) { + this.fetchedRoles = true; + this.userRoles = cachedRoles; + return cachedRoles; + } + } // First get the role ids this user is directly a member of + + + const results = await this.getRolesForUser(); + + if (!results.length) { + this.userRoles = []; + this.fetchedRoles = true; + this.rolePromise = null; + this.cacheRoles(); + return this.userRoles; + } + + const rolesMap = results.reduce((m, r) => { + m.names.push(r.name); + m.ids.push(r.objectId); + return m; + }, { + ids: [], + names: [] + }); // run the recursive finding + + const roleNames = await this._getAllRolesNamesForRoleIds(rolesMap.ids, rolesMap.names); + this.userRoles = roleNames.map(r => { + return 'role:' + r; + }); + this.fetchedRoles = true; + this.rolePromise = null; + this.cacheRoles(); + return this.userRoles; +}; + +Auth.prototype.cacheRoles = function () { + if (!this.cacheController) { + return false; + } + + this.cacheController.role.put(this.user.id, Array(...this.userRoles)); + return true; +}; + +Auth.prototype.getRolesByIds = async function (ins) { + const results = []; // Build an OR query across all parentRoles + + if (!this.config) { + await new Parse.Query(Parse.Role).containedIn('roles', ins.map(id => { + const role = new Parse.Object(Parse.Role); + role.id = id; + return role; + })).each(result => results.push(result.toJSON()), { + useMasterKey: true + }); + } else { + const roles = ins.map(id => { + return { + __type: 'Pointer', + className: '_Role', + objectId: id + }; + }); + const restWhere = { + roles: { + $in: roles + } + }; + await new RestQuery(this.config, master(this.config), '_Role', restWhere, {}).each(result => results.push(result)); + } + + return results; +}; // Given a list of roleIds, find all the parent roles, returns a promise with all names + + +Auth.prototype._getAllRolesNamesForRoleIds = function (roleIDs, names = [], queriedRoles = {}) { + const ins = roleIDs.filter(roleID => { + const wasQueried = queriedRoles[roleID] !== true; + queriedRoles[roleID] = true; + return wasQueried; + }); // all roles are accounted for, return the names + + if (ins.length == 0) { + return Promise.resolve([...new Set(names)]); + } + + return this.getRolesByIds(ins).then(results => { + // Nothing found + if (!results.length) { + return Promise.resolve(names); + } // Map the results with all Ids and names + + + const resultMap = results.reduce((memo, role) => { + memo.names.push(role.name); + memo.ids.push(role.objectId); + return memo; + }, { + ids: [], + names: [] + }); // store the new found names + + names = names.concat(resultMap.names); // find the next ones, circular roles will be cut + + return this._getAllRolesNamesForRoleIds(resultMap.ids, names, queriedRoles); + }).then(names => { + return Promise.resolve([...new Set(names)]); + }); +}; + +const createSession = function (config, { + userId, + createdWith, + installationId, + additionalSessionData +}) { + const token = 'r:' + cryptoUtils.newToken(); + const expiresAt = config.generateSessionExpiresAt(); + const sessionData = { + sessionToken: token, + user: { + __type: 'Pointer', + className: '_User', + objectId: userId + }, + createdWith, + restricted: false, + expiresAt: Parse._encode(expiresAt) + }; + + if (installationId) { + sessionData.installationId = installationId; + } + + Object.assign(sessionData, additionalSessionData); // We need to import RestWrite at this point for the cyclic dependency it has to it + + const RestWrite = require('./RestWrite'); + + return { + sessionData, + createSession: () => new RestWrite(config, master(config), '_Session', null, sessionData).execute() + }; +}; + +module.exports = { + Auth, + master, + nobody, + readOnly, + getAuthForSessionToken, + getAuthForLegacySessionToken, + createSession +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9BdXRoLmpzIl0sIm5hbWVzIjpbImNyeXB0b1V0aWxzIiwicmVxdWlyZSIsIlJlc3RRdWVyeSIsIlBhcnNlIiwiQXV0aCIsImNvbmZpZyIsImNhY2hlQ29udHJvbGxlciIsInVuZGVmaW5lZCIsImlzTWFzdGVyIiwiaXNSZWFkT25seSIsInVzZXIiLCJpbnN0YWxsYXRpb25JZCIsInVzZXJSb2xlcyIsImZldGNoZWRSb2xlcyIsInJvbGVQcm9taXNlIiwicHJvdG90eXBlIiwiaXNVbmF1dGhlbnRpY2F0ZWQiLCJtYXN0ZXIiLCJyZWFkT25seSIsIm5vYm9keSIsImdldEF1dGhGb3JTZXNzaW9uVG9rZW4iLCJzZXNzaW9uVG9rZW4iLCJ1c2VySlNPTiIsImdldCIsImNhY2hlZFVzZXIiLCJPYmplY3QiLCJmcm9tSlNPTiIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVzdWx0cyIsInJlc3RPcHRpb25zIiwibGltaXQiLCJpbmNsdWRlIiwicXVlcnkiLCJleGVjdXRlIiwiUXVlcnkiLCJTZXNzaW9uIiwiZXF1YWxUbyIsImZpbmQiLCJ1c2VNYXN0ZXJLZXkiLCJtYXAiLCJvYmoiLCJ0b0pTT04iLCJsZW5ndGgiLCJFcnJvciIsIklOVkFMSURfU0VTU0lPTl9UT0tFTiIsIm5vdyIsIkRhdGUiLCJleHBpcmVzQXQiLCJpc28iLCJwYXNzd29yZCIsInB1dCIsInVzZXJPYmplY3QiLCJnZXRBdXRoRm9yTGVnYWN5U2Vzc2lvblRva2VuIiwidGhlbiIsInJlc3BvbnNlIiwiY2xhc3NOYW1lIiwiZ2V0VXNlclJvbGVzIiwiX2xvYWRSb2xlcyIsImdldFJvbGVzRm9yVXNlciIsInJlc3RXaGVyZSIsInVzZXJzIiwiX190eXBlIiwib2JqZWN0SWQiLCJpZCIsImVhY2giLCJyZXN1bHQiLCJwdXNoIiwiUm9sZSIsImNhY2hlZFJvbGVzIiwicm9sZSIsImNhY2hlUm9sZXMiLCJyb2xlc01hcCIsInJlZHVjZSIsIm0iLCJyIiwibmFtZXMiLCJuYW1lIiwiaWRzIiwicm9sZU5hbWVzIiwiX2dldEFsbFJvbGVzTmFtZXNGb3JSb2xlSWRzIiwiQXJyYXkiLCJnZXRSb2xlc0J5SWRzIiwiaW5zIiwiY29udGFpbmVkSW4iLCJyb2xlcyIsIiRpbiIsInJvbGVJRHMiLCJxdWVyaWVkUm9sZXMiLCJmaWx0ZXIiLCJyb2xlSUQiLCJ3YXNRdWVyaWVkIiwiU2V0IiwicmVzdWx0TWFwIiwibWVtbyIsImNvbmNhdCIsImNyZWF0ZVNlc3Npb24iLCJ1c2VySWQiLCJjcmVhdGVkV2l0aCIsImFkZGl0aW9uYWxTZXNzaW9uRGF0YSIsInRva2VuIiwibmV3VG9rZW4iLCJnZW5lcmF0ZVNlc3Npb25FeHBpcmVzQXQiLCJzZXNzaW9uRGF0YSIsInJlc3RyaWN0ZWQiLCJfZW5jb2RlIiwiYXNzaWduIiwiUmVzdFdyaXRlIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQSxNQUFNQSxXQUFXLEdBQUdDLE9BQU8sQ0FBQyxlQUFELENBQTNCOztBQUNBLE1BQU1DLFNBQVMsR0FBR0QsT0FBTyxDQUFDLGFBQUQsQ0FBekI7O0FBQ0EsTUFBTUUsS0FBSyxHQUFHRixPQUFPLENBQUMsWUFBRCxDQUFyQixDLENBRUE7QUFDQTtBQUNBOzs7QUFDQSxTQUFTRyxJQUFULENBQWM7QUFDWkMsRUFBQUEsTUFEWTtBQUVaQyxFQUFBQSxlQUFlLEdBQUdDLFNBRk47QUFHWkMsRUFBQUEsUUFBUSxHQUFHLEtBSEM7QUFJWkMsRUFBQUEsVUFBVSxHQUFHLEtBSkQ7QUFLWkMsRUFBQUEsSUFMWTtBQU1aQyxFQUFBQTtBQU5ZLENBQWQsRUFPRztBQUNELE9BQUtOLE1BQUwsR0FBY0EsTUFBZDtBQUNBLE9BQUtDLGVBQUwsR0FBdUJBLGVBQWUsSUFBS0QsTUFBTSxJQUFJQSxNQUFNLENBQUNDLGVBQTVEO0FBQ0EsT0FBS0ssY0FBTCxHQUFzQkEsY0FBdEI7QUFDQSxPQUFLSCxRQUFMLEdBQWdCQSxRQUFoQjtBQUNBLE9BQUtFLElBQUwsR0FBWUEsSUFBWjtBQUNBLE9BQUtELFVBQUwsR0FBa0JB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LGNBQUosRUFBb0I7QUFDbEI0RixJQUFBQSxXQUFXLENBQUM1RixjQUFaLEdBQTZCQSxjQUE3QjtBQUNEOztBQUVEYyxFQUFBQSxNQUFNLENBQUNpRixNQUFQLENBQWNILFdBQWQsRUFBMkJKLHFCQUEzQixFQW5CQSxDQW9CQTs7QUFDQSxRQUFNUSxTQUFTLEdBQUcxRyxPQUFPLENBQUMsYUFBRCxDQUF6Qjs7QUFFQSxTQUFPO0FBQ0xzRyxJQUFBQSxXQURLO0FBRUxQLElBQUFBLGFBQWEsRUFBRSxNQUNiLElBQUlXLFNBQUosQ0FBY3RHLE1BQWQsRUFBc0JZLE1BQU0sQ0FBQ1osTUFBRCxDQUE1QixFQUFzQyxVQUF0QyxFQUFrRCxJQUFsRCxFQUF3RGtHLFdBQXhELEVBQXFFckUsT0FBckU7QUFIRyxHQUFQO0FBS0QsQ0EvQkQ7O0FBaUNBMEUsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2Z6RyxFQUFBQSxJQURlO0FBRWZhLEVBQUFBLE1BRmU7QUFHZkUsRUFBQUEsTUFIZTtBQUlmRCxFQUFBQSxRQUplO0FBS2ZFLEVBQUFBLHNCQUxlO0FBTWZpQyxFQUFBQSw0QkFOZTtBQU9mMkMsRUFBQUE7QUFQZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGNyeXB0b1V0aWxzID0gcmVxdWlyZSgnLi9jcnlwdG9VdGlscycpO1xuY29uc3QgUmVzdFF1ZXJ5ID0gcmVxdWlyZSgnLi9SZXN0UXVlcnknKTtcbmNvbnN0IFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpO1xuXG4vLyBBbiBBdXRoIG9iamVjdCB0ZWxscyB5b3Ugd2hvIGlzIHJlcXVlc3Rpbmcgc29tZXRoaW5nIGFuZCB3aGV0aGVyXG4vLyB0aGUgbWFzdGVyIGtleSB3YXMgdXNlZC5cbi8vIHVzZXJPYmplY3QgaXMgYSBQYXJzZS5Vc2VyIGFuZCBjYW4gYmUgbnVsbCBpZiB0aGVyZSdzIG5vIHVzZXIuXG5mdW5jdGlvbiBBdXRoKHtcbiAgY29uZmlnLFxuICBjYWNoZUNvbnRyb2xsZXIgPSB1bmRlZmluZWQsXG4gIGlzTWFzdGVyID0gZmFsc2UsXG4gIGlzUmVhZE9ubHkgPSBmYWxzZSxcbiAgdXNlcixcbiAgaW5zdGFsbGF0aW9uSWQsXG59KSB7XG4gIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICB0aGlzLmNhY2hlQ29udHJvbGxlciA9IGNhY2hlQ29udHJvbGxlciB8fCAoY29uZmlnICYmIGNvbmZpZy5jYWNoZUNvbnRyb2xsZXIpO1xuICB0aGlzLmluc3RhbGxhdGlvbklkID0gaW5zdGFsbGF0aW9uSWQ7XG4gIHRoaXMuaXNNYXN0ZXIgPSBpc01hc3RlcjtcbiAgdGhpcy51c2VyID0gdXNlcjtcbiAgdGhpcy5pc1JlYWRPbmx5ID0gaXNSZWFkT25seTtcblxuICAvLyBBc3N1bWluZyBhIHVzZXJzIHJvbGVzIHdvbid0IGNoYW5nZSBkdXJpbmcgYSBzaW5nbGUgcmVxdWVzdCwgd2UnbGxcbiAgLy8gb25seSBsb2FkIHRoZW0gb25jZS5cbiAgdGhpcy51c2VyUm9sZXMgPSBbXTtcbiAgdGhpcy5mZXRjaGVkUm9sZXMgPSBmYWxzZTtcbiAgdGhpcy5yb2xlUHJvbWlzZSA9IG51bGw7XG59XG5cbi8vIFdoZXRoZXIgdGhpcyBhdXRoIGNvdWxkIHBvc3NpYmx5IG1vZGlmeSB0aGUgZ2l2ZW4gdXNlciBpZC5cbi8vIEl0IHN0aWxsIGNvdWxkIGJlIGZvcmJpZGRlbiB2aWEgQUNMcyBldmVuIGlmIHRoaXMgcmV0dXJucyB0cnVlLlxuQXV0aC5wcm90b3R5cGUuaXNVbmF1dGhlbnRpY2F0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmlzTWFzdGVyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICh0aGlzLnVzZXIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59O1xuXG4vLyBBIGhlbHBlciB0byBnZXQgYSBtYXN0ZXItbGV2ZWwgQXV0aCBvYmplY3RcbmZ1bmN0aW9uIG1hc3Rlcihjb25maWcpIHtcbiAgcmV0dXJuIG5ldyBBdXRoKHsgY29uZmlnLCBpc01hc3RlcjogdHJ1ZSB9KTtcbn1cblxuLy8gQSBoZWxwZXIgdG8gZ2V0IGEgbWFzdGVyLWxldmVsIEF1dGggb2JqZWN0XG5mdW5jdGlvbiByZWFkT25seShjb25maWcpIHtcbiAgcmV0dXJuIG5ldyBBdXRoKHsgY29uZmlnLCBpc01hc3RlcjogdHJ1ZSwgaXNSZWFkT25seTogdHJ1ZSB9KTtcbn1cblxuLy8gQSBoZWxwZXIgdG8gZ2V0IGEgbm9ib2R5LWxldmVsIEF1dGggb2JqZWN0XG5mdW5jdGlvbiBub2JvZHkoY29uZmlnKSB7XG4gIHJldHVybiBuZXcgQXV0aCh7IGNvbmZpZywgaXNNYXN0ZXI6IGZhbHNlIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIEF1dGggb2JqZWN0XG5jb25zdCBnZXRBdXRoRm9yU2Vzc2lvblRva2VuID0gYXN5bmMgZnVuY3Rpb24gKHtcbiAgY29uZmlnLFxuICBjYWNoZUNvbnRyb2xsZXIsXG4gIHNlc3Npb25Ub2tlbixcbiAgaW5zdGFsbGF0aW9uSWQsXG59KSB7XG4gIGNhY2hlQ29udHJvbGxlciA9IGNhY2hlQ29udHJvbGxlciB8fCAoY29uZmlnICYmIGNvbmZpZy5jYWNoZUNvbnRyb2xsZXIpO1xuICBpZiAoY2FjaGVDb250cm9sbGVyKSB7XG4gICAgY29uc3QgdXNlckpTT04gPSBhd2FpdCBjYWNoZUNvbnRyb2xsZXIudXNlci5nZXQoc2Vzc2lvblRva2VuKTtcbiAgICBpZiAodXNlckpTT04pIHtcbiAgICAgIGNvbnN0IGNhY2hlZFVzZXIgPSBQYXJzZS5PYmplY3QuZnJvbUpTT04odXNlckpTT04pO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShcbiAgICAgICAgbmV3IEF1dGgoe1xuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICBjYWNoZUNvbnRyb2xsZXIsXG4gICAgICAgICAgaXNNYXN0ZXI6IGZhbHNlLFxuICAgICAgICAgIGluc3RhbGxhdGlvbklkLFxuICAgICAgICAgIHVzZXI6IGNhY2hlZFVzZXIsXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGxldCByZXN1bHRzO1xuICBpZiAoY29uZmlnKSB7XG4gICAgY29uc3QgcmVzdE9wdGlvbnMgPSB7XG4gICAgICBsaW1pdDogMSxcbiAgICAgIGluY2x1ZGU6ICd1c2VyJyxcbiAgICB9O1xuXG4gICAgY29uc3QgcXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KGNvbmZpZywgbWFzdGVyKGNvbmZpZyksICdfU2Vzc2lvbicsIHsgc2Vzc2lvblRva2VuIH0sIHJlc3RPcHRpb25zKTtcbiAgICByZXN1bHRzID0gKGF3YWl0IHF1ZXJ5LmV4ZWN1dGUoKSkucmVzdWx0cztcbiAgfSBlbHNlIHtcbiAgICByZXN1bHRzID0gKFxuICAgICAgYXdhaXQgbmV3IFBhcnNlLlF1ZXJ5KFBhcnNlLlNlc3Npb24pXG4gICAgICAgIC5saW1pdCgxKVxuICAgICAgICAuaW5jbHVkZSgndXNlcicpXG4gICAgICAgIC5lcXVhbFRvKCdzZXNzaW9uVG9rZW4nLCBzZXNzaW9uVG9rZW4pXG4gICAgICAgIC5maW5kKHsgdXNlTWFzdGVyS2V5OiB0cnVlIH0pXG4gICAgKS5tYXAob2JqID0+IG9iai50b0pTT04oKSk7XG4gIH1cblxuICBpZiAocmVzdWx0cy5sZW5ndGggIT09IDEgfHwgIXJlc3VsdHNbMF1bJ3VzZXInXSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdJbnZhbGlkIHNlc3Npb24gdG9rZW4nKTtcbiAgfVxuICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpLFxuICAgIGV4cGlyZXNBdCA9IHJlc3VsdHNbMF0uZXhwaXJlc0F0ID8gbmV3IERhdGUocmVzdWx0c1swXS5leHBpcmVzQXQuaXNvKSA6IHVuZGVmaW5lZDtcbiAgaWYgKGV4cGlyZXNBdCA8IG5vdykge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdTZXNzaW9uIHRva2VuIGlzIGV4cGlyZWQuJyk7XG4gIH1cbiAgY29uc3Qgb2JqID0gcmVzdWx0c1swXVsndXNlciddO1xuICBkZWxldGUgb2JqLnBhc3N3b3JkO1xuICBvYmpbJ2NsYXNzTmFtZSddID0gJ19Vc2VyJztcbiAgb2JqWydzZXNzaW9uVG9rZW4nXSA9IHNlc3Npb25Ub2tlbjtcbiAgaWYgKGNhY2hlQ29udHJvbGxlcikge1xuICAgIGNhY2hlQ29udHJvbGxlci51c2VyLnB1dChzZXNzaW9uVG9rZW4sIG9iaik7XG4gIH1cbiAgY29uc3QgdXNlck9iamVjdCA9IFBhcnNlLk9iamVjdC5mcm9tSlNPTihvYmopO1xuICByZXR1cm4gbmV3IEF1dGgoe1xuICAgIGNvbmZpZyxcbiAgICBjYWNoZUNvbnRyb2xsZXIsXG4gICAgaXNNYXN0ZXI6IGZhbHNlLFxuICAgIGluc3RhbGxhdGlvbklkLFxuICAgIHVzZXI6IHVzZXJPYmplY3QsXG4gIH0pO1xufTtcblxudmFyIGdldEF1dGhGb3JMZWdhY3lTZXNzaW9uVG9rZW4gPSBmdW5jdGlvbiAoeyBjb25maWcsIHNlc3Npb25Ub2tlbiwgaW5zdGFsbGF0aW9uSWQgfSkge1xuICB2YXIgcmVzdE9wdGlvbnMgPSB7XG4gICAgbGltaXQ6IDEsXG4gIH07XG4gIHZhciBxdWVyeSA9IG5ldyBSZXN0UXVlcnkoY29uZmlnLCBtYXN0ZXIoY29uZmlnKSwgJ19Vc2VyJywgeyBzZXNzaW9uVG9rZW4gfSwgcmVzdE9wdGlvbnMpO1xuICByZXR1cm4gcXVlcnkuZXhlY3V0ZSgpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgIHZhciByZXN1bHRzID0gcmVzcG9uc2UucmVzdWx0cztcbiAgICBpZiAocmVzdWx0cy5sZW5ndGggIT09IDEpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdpbnZhbGlkIGxlZ2FjeSBzZXNzaW9uIHRva2VuJyk7XG4gICAgfVxuICAgIGNvbnN0IG9iaiA9IHJlc3VsdHNbMF07XG4gICAgb2JqLmNsYXNzTmFtZSA9ICdfVXNlcic7XG4gICAgY29uc3QgdXNlck9iamVjdCA9IFBhcnNlLk9iamVjdC5mcm9tSlNPTihvYmopO1xuICAgIHJldHVybiBuZXcgQXV0aCh7XG4gICAgICBjb25maWcsXG4gICAgICBpc01hc3RlcjogZmFsc2UsXG4gICAgICBpbnN0YWxsYXRpb25JZCxcbiAgICAgIHVzZXI6IHVzZXJPYmplY3QsXG4gICAgfSk7XG4gIH0pO1xufTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBvZiByb2xlIG5hbWVzXG5BdXRoLnByb3RvdHlwZS5nZXRVc2VyUm9sZXMgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmlzTWFzdGVyIHx8ICF0aGlzLnVzZXIpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFtdKTtcbiAgfVxuICBpZiAodGhpcy5mZXRjaGVkUm9sZXMpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMudXNlclJvbGVzKTtcbiAgfVxuICBpZiAodGhpcy5yb2xlUHJvbWlzZSkge1xuICAgIHJldHVybiB0aGlzLnJvbGVQcm9taXNlO1xuICB9XG4gIHRoaXMucm9sZVByb21pc2UgPSB0aGlzLl9sb2FkUm9sZXMoKTtcbiAgcmV0dXJuIHRoaXMucm9sZVByb21pc2U7XG59O1xuXG5BdXRoLnByb3RvdHlwZS5nZXRSb2xlc0ZvclVzZXIgPSBhc3luYyBmdW5jdGlvbiAoKSB7XG4gIC8vU3RhY2sgYWxsIFBhcnNlLlJvbGVcbiAgY29uc3QgcmVzdWx0cyA9IFtdO1xuICBpZiAodGhpcy5jb25maWcpIHtcbiAgICBjb25zdCByZXN0V2hlcmUgPSB7XG4gICAgICB1c2Vyczoge1xuICAgICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgY2xhc3NOYW1lOiAnX1VzZXInLFxuICAgICAgICBvYmplY3RJZDogdGhpcy51c2VyLmlkLFxuICAgICAgfSxcbiAgICB9O1xuICAgIGF3YWl0IG5ldyBSZXN0UXVlcnkodGhpcy5jb25maWcsIG1hc3Rlcih0aGlzLmNvbmZpZyksICdfUm9sZScsIHJlc3RXaGVyZSwge30pLmVhY2gocmVzdWx0ID0+XG4gICAgICByZXN1bHRzLnB1c2gocmVzdWx0KVxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgYXdhaXQgbmV3IFBhcnNlLlF1ZXJ5KFBhcnNlLlJvbGUpXG4gICAgICAuZXF1YWxUbygndXNlcnMnLCB0aGlzLnVzZXIpXG4gICAgICAuZWFjaChyZXN1bHQgPT4gcmVzdWx0cy5wdXNoKHJlc3VsdC50b0pTT04oKSksIHsgdXNlTWFzdGVyS2V5OiB0cnVlIH0pO1xuICB9XG4gIHJldHVybiByZXN1bHRzO1xufTtcblxuLy8gSXRlcmF0ZXMgdGhyb3VnaCB0aGUgcm9sZSB0cmVlIGFuZCBjb21waWxlcyBhIHVzZXIncyByb2xlc1xuQXV0aC5wcm90b3R5cGUuX2xvYWRSb2xlcyA9IGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuY2FjaGVDb250cm9sbGVyKSB7XG4gICAgY29uc3QgY2FjaGVkUm9sZXMgPSBhd2FpdCB0aGlzLmNhY2hlQ29udHJvbGxlci5yb2xlLmdldCh0aGlzLnVzZXIuaWQpO1xuICAgIGlmIChjYWNoZWRSb2xlcyAhPSBudWxsKSB7XG4gICAgICB0aGlzLmZldGNoZWRSb2xlcyA9IHRydWU7XG4gICAgICB0aGlzLnVzZXJSb2xlcyA9IGNhY2hlZFJvbGVzO1xuICAgICAgcmV0dXJuIGNhY2hlZFJvbGVzO1xuICAgIH1cbiAgfVxuXG4gIC8vIEZpcnN0IGdldCB0aGUgcm9sZSBpZHMgdGhpcyB1c2VyIGlzIGRpcmVjdGx5IGEgbWVtYmVyIG9mXG4gIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0aGlzLmdldFJvbGVzRm9yVXNlcigpO1xuICBpZiAoIXJlc3VsdHMubGVuZ3RoKSB7XG4gICAgdGhpcy51c2VyUm9sZXMgPSBbXTtcbiAgICB0aGlzLmZldGNoZWRSb2xlcyA9IHRydWU7XG4gICAgdGhpcy5yb2xlUHJvbWlzZSA9IG51bGw7XG5cbiAgICB0aGlzLmNhY2hlUm9sZXMoKTtcbiAgICByZXR1cm4gdGhpcy51c2VyUm9sZXM7XG4gIH1cblxuICBjb25zdCByb2xlc01hcCA9IHJlc3VsdHMucmVkdWNlKFxuICAgIChtLCByKSA9PiB7XG4gICAgICBtLm5hbWVzLnB1c2goci5uYW1lKTtcbiAgICAgIG0uaWRzLnB1c2goci5vYmplY3RJZCk7XG4gICAgICByZXR1cm4gbTtcbiAgICB9LFxuICAgIHsgaWRzOiBbXSwgbmFtZXM6IFtdIH1cbiAgKTtcblxuICAvLyBydW4gdGhlIHJlY3Vyc2l2ZSBmaW5kaW5nXG4gIGNvbnN0IHJvbGVOYW1lcyA9IGF3YWl0IHRoaXMuX2dldEFsbFJvbGVzTmFtZXNGb3JSb2xlSWRzKHJvbGVzTWFwLmlkcywgcm9sZXNNYXAubmFtZXMpO1xuICB0aGlzLnVzZXJSb2xlcyA9IHJvbGVOYW1lcy5tYXAociA9PiB7XG4gICAgcmV0dXJuICdyb2xlOicgKyByO1xuICB9KTtcbiAgdGhpcy5mZXRjaGVkUm9sZXMgPSB0cnVlO1xuICB0aGlzLnJvbGVQcm9taXNlID0gbnVsbDtcbiAgdGhpcy5jYWNoZVJvbGVzKCk7XG4gIHJldHVybiB0aGlzLnVzZXJSb2xlcztcbn07XG5cbkF1dGgucHJvdG90eXBlLmNhY2hlUm9sZXMgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5jYWNoZUNvbnRyb2xsZXIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdGhpcy5jYWNoZUNvbnRyb2xsZXIucm9sZS5wdXQodGhpcy51c2VyLmlkLCBBcnJheSguLi50aGlzLnVzZXJSb2xlcykpO1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkF1dGgucHJvdG90eXBlLmdldFJvbGVzQnlJZHMgPSBhc3luYyBmdW5jdGlvbiAoaW5zKSB7XG4gIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgLy8gQnVpbGQgYW4gT1IgcXVlcnkgYWNyb3NzIGFsbCBwYXJlbnRSb2xlc1xuICBpZiAoIXRoaXMuY29uZmlnKSB7XG4gICAgYXdhaXQgbmV3IFBhcnNlLlF1ZXJ5KFBhcnNlLlJvbGUpXG4gICAgICAuY29udGFpbmVkSW4oXG4gICAgICAgICdyb2xlcycsXG4gICAgICAgIGlucy5tYXAoaWQgPT4ge1xuICAgICAgICAgIGNvbnN0IHJvbGUgPSBuZXcgUGFyc2UuT2JqZWN0KFBhcnNlLlJvbGUpO1xuICAgICAgICAgIHJvbGUuaWQgPSBpZDtcbiAgICAgICAgICByZXR1cm4gcm9sZTtcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC5lYWNoKHJlc3VsdCA9PiByZXN1bHRzLnB1c2gocmVzdWx0LnRvSlNPTigpKSwgeyB1c2VNYXN0ZXJLZXk6IHRydWUgfSk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3Qgcm9sZXMgPSBpbnMubWFwKGlkID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICBjbGFzc05hbWU6ICdfUm9sZScsXG4gICAgICAgIG9iamVjdElkOiBpZCxcbiAgICAgIH07XG4gICAgfSk7XG4gICAgY29uc3QgcmVzdFdoZXJlID0geyByb2xlczogeyAkaW46IHJvbGVzIH0gfTtcbiAgICBhd2FpdCBuZXcgUmVzdFF1ZXJ5KHRoaXMuY29uZmlnLCBtYXN0ZXIodGhpcy5jb25maWcpLCAnX1JvbGUnLCByZXN0V2hlcmUsIHt9KS5lYWNoKHJlc3VsdCA9PlxuICAgICAgcmVzdWx0cy5wdXNoKHJlc3VsdClcbiAgICApO1xuICB9XG4gIHJldHVybiByZXN1bHRzO1xufTtcblxuLy8gR2l2ZW4gYSBsaXN0IG9mIHJvbGVJZHMsIGZpbmQgYWxsIHRoZSBwYXJlbnQgcm9sZXMsIHJldHVybnMgYSBwcm9taXNlIHdpdGggYWxsIG5hbWVzXG5BdXRoLnByb3RvdHlwZS5fZ2V0QWxsUm9sZXNOYW1lc0ZvclJvbGVJZHMgPSBmdW5jdGlvbiAocm9sZUlEcywgbmFtZXMgPSBbXSwgcXVlcmllZFJvbGVzID0ge30pIHtcbiAgY29uc3QgaW5zID0gcm9sZUlEcy5maWx0ZXIocm9sZUlEID0+IHtcbiAgICBjb25zdCB3YXNRdWVyaWVkID0gcXVlcmllZFJvbGVzW3JvbGVJRF0gIT09IHRydWU7XG4gICAgcXVlcmllZFJvbGVzW3JvbGVJRF0gPSB0cnVlO1xuICAgIHJldHVybiB3YXNRdWVyaWVkO1xuICB9KTtcblxuICAvLyBhbGwgcm9sZXMgYXJlIGFjY291bnRlZCBmb3IsIHJldHVybiB0aGUgbmFtZXNcbiAgaWYgKGlucy5sZW5ndGggPT0gMCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoWy4uLm5ldyBTZXQobmFtZXMpXSk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5nZXRSb2xlc0J5SWRzKGlucylcbiAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIC8vIE5vdGhpbmcgZm91bmRcbiAgICAgIGlmICghcmVzdWx0cy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuYW1lcyk7XG4gICAgICB9XG4gICAgICAvLyBNYXAgdGhlIHJlc3VsdHMgd2l0aCBhbGwgSWRzIGFuZCBuYW1lc1xuICAgICAgY29uc3QgcmVzdWx0TWFwID0gcmVzdWx0cy5yZWR1Y2UoXG4gICAgICAgIChtZW1vLCByb2xlKSA9PiB7XG4gICAgICAgICAgbWVtby5uYW1lcy5wdXNoKHJvbGUubmFtZSk7XG4gICAgICAgICAgbWVtby5pZHMucHVzaChyb2xlLm9iamVjdElkKTtcbiAgICAgICAgICByZXR1cm4gbWVtbztcbiAgICAgICAgfSxcbiAgICAgICAgeyBpZHM6IFtdLCBuYW1lczogW10gfVxuICAgICAgKTtcbiAgICAgIC8vIHN0b3JlIHRoZSBuZXcgZm91bmQgbmFtZXNcbiAgICAgIG5hbWVzID0gbmFtZXMuY29uY2F0KHJlc3VsdE1hcC5uYW1lcyk7XG4gICAgICAvLyBmaW5kIHRoZSBuZXh0IG9uZXMsIGNpcmN1bGFyIHJvbGVzIHdpbGwgYmUgY3V0XG4gICAgICByZXR1cm4gdGhpcy5fZ2V0QWxsUm9sZXNOYW1lc0ZvclJvbGVJZHMocmVzdWx0TWFwLmlkcywgbmFtZXMsIHF1ZXJpZWRSb2xlcyk7XG4gICAgfSlcbiAgICAudGhlbihuYW1lcyA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFsuLi5uZXcgU2V0KG5hbWVzKV0pO1xuICAgIH0pO1xufTtcblxuY29uc3QgY3JlYXRlU2Vzc2lvbiA9IGZ1bmN0aW9uIChcbiAgY29uZmlnLFxuICB7IHVzZXJJZCwgY3JlYXRlZFdpdGgsIGluc3RhbGxhdGlvbklkLCBhZGRpdGlvbmFsU2Vzc2lvbkRhdGEgfVxuKSB7XG4gIGNvbnN0IHRva2VuID0gJ3I6JyArIGNyeXB0b1V0aWxzLm5ld1Rva2VuKCk7XG4gIGNvbnN0IGV4cGlyZXNBdCA9IGNvbmZpZy5nZW5lcmF0ZVNlc3Npb25FeHBpcmVzQXQoKTtcbiAgY29uc3Qgc2Vzc2lvbkRhdGEgPSB7XG4gICAgc2Vzc2lvblRva2VuOiB0b2tlbixcbiAgICB1c2VyOiB7XG4gICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgIGNsYXNzTmFtZTogJ19Vc2VyJyxcbiAgICAgIG9iamVjdElkOiB1c2VySWQsXG4gICAgfSxcbiAgICBjcmVhdGVkV2l0aCxcbiAgICByZXN0cmljdGVkOiBmYWxzZSxcbiAgICBleHBpcmVzQXQ6IFBhcnNlLl9lbmNvZGUoZXhwaXJlc0F0KSxcbiAgfTtcblxuICBpZiAoaW5zdGFsbGF0aW9uSWQpIHtcbiAgICBzZXNzaW9uRGF0YS5pbnN0YWxsYXRpb25JZCA9IGluc3RhbGxhdGlvbklkO1xuICB9XG5cbiAgT2JqZWN0LmFzc2lnbihzZXNzaW9uRGF0YSwgYWRkaXRpb25hbFNlc3Npb25EYXRhKTtcbiAgLy8gV2UgbmVlZCB0byBpbXBvcnQgUmVzdFdyaXRlIGF0IHRoaXMgcG9pbnQgZm9yIHRoZSBjeWNsaWMgZGVwZW5kZW5jeSBpdCBoYXMgdG8gaXRcbiAgY29uc3QgUmVzdFdyaXRlID0gcmVxdWlyZSgnLi9SZXN0V3JpdGUnKTtcblxuICByZXR1cm4ge1xuICAgIHNlc3Npb25EYXRhLFxuICAgIGNyZWF0ZVNlc3Npb246ICgpID0+XG4gICAgICBuZXcgUmVzdFdyaXRlKGNvbmZpZywgbWFzdGVyKGNvbmZpZyksICdfU2Vzc2lvbicsIG51bGwsIHNlc3Npb25EYXRhKS5leGVjdXRlKCksXG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgQXV0aCxcbiAgbWFzdGVyLFxuICBub2JvZHksXG4gIHJlYWRPbmx5LFxuICBnZXRBdXRoRm9yU2Vzc2lvblRva2VuLFxuICBnZXRBdXRoRm9yTGVnYWN5U2Vzc2lvblRva2VuLFxuICBjcmVhdGVTZXNzaW9uLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/ClientSDK.js b/lib/ClientSDK.js new file mode 100644 index 0000000000..ed5cf3beab --- /dev/null +++ b/lib/ClientSDK.js @@ -0,0 +1,47 @@ +"use strict"; + +var semver = require('semver'); + +function compatible(compatibleSDK) { + return function (clientSDK) { + if (typeof clientSDK === 'string') { + clientSDK = fromString(clientSDK); + } // REST API, or custom SDK + + + if (!clientSDK) { + return true; + } + + const clientVersion = clientSDK.version; + const compatiblityVersion = compatibleSDK[clientSDK.sdk]; + return semver.satisfies(clientVersion, compatiblityVersion); + }; +} + +function supportsForwardDelete(clientSDK) { + return compatible({ + js: '>=1.9.0' + })(clientSDK); +} + +function fromString(version) { + const versionRE = /([-a-zA-Z]+)([0-9\.]+)/; + const match = version.toLowerCase().match(versionRE); + + if (match && match.length === 3) { + return { + sdk: match[1], + version: match[2] + }; + } + + return undefined; +} + +module.exports = { + compatible, + supportsForwardDelete, + fromString +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9DbGllbnRTREsuanMiXSwibmFtZXMiOlsic2VtdmVyIiwicmVxdWlyZSIsImNvbXBhdGlibGUiLCJjb21wYXRpYmxlU0RLIiwiY2xpZW50U0RLIiwiZnJvbVN0cmluZyIsImNsaWVudFZlcnNpb24iLCJ2ZXJzaW9uIiwiY29tcGF0aWJsaXR5VmVyc2lvbiIsInNkayIsInNhdGlzZmllcyIsInN1cHBvcnRzRm9yd2FyZERlbGV0ZSIsImpzIiwidmVyc2lvblJFIiwibWF0Y2giLCJ0b0xvd2VyQ2FzZSIsImxlbmd0aCIsInVuZGVmaW5lZCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUEsSUFBSUEsTUFBTSxHQUFHQyxPQUFPLENBQUMsUUFBRCxDQUFwQjs7QUFFQSxTQUFTQyxVQUFULENBQW9CQyxhQUFwQixFQUFtQztBQUNqQyxTQUFPLFVBQVVDLFNBQVYsRUFBcUI7QUFDMUIsUUFBSSxPQUFPQSxTQUFQLEtBQXFCLFFBQXpCLEVBQW1DO0FBQ2pDQSxNQUFBQSxTQUFTLEdBQUdDLFVBQVUsQ0FBQ0QsU0FBRCxDQUF0QjtBQUNELEtBSHlCLENBSTFCOzs7QUFDQSxRQUFJLENBQUNBLFNBQUwsRUFBZ0I7QUFDZCxhQUFPLElBQVA7QUFDRDs7QUFDRCxVQUFNRSxhQUFhLEdBQUdGLFNBQVMsQ0FBQ0csT0FBaEM7QUFDQSxVQUFNQyxtQkFBbUIsR0FBR0wsYUFBYSxDQUFDQyxTQUFTLENBQUNLLEdBQVgsQ0FBekM7QUFDQSxXQUFPVCxNQUFNLENBQUNVLFNBQVAsQ0FBaUJKLGFBQWpCLEVBQWdDRSxtQkFBaEMsQ0FBUDtBQUNELEdBWEQ7QUFZRDs7QUFFRCxTQUFTRyxxQkFBVCxDQUErQlAsU0FBL0IsRUFBMEM7QUFDeEMsU0FBT0YsVUFBVSxDQUFDO0FBQ2hCVSxJQUFBQSxFQUFFLEVBQUU7QUFEWSxHQUFELENBQVYsQ0FFSlIsU0FGSSxDQUFQO0FBR0Q7O0FBRUQsU0FBU0MsVUFBVCxDQUFvQkUsT0FBcEIsRUFBNkI7QUFDM0IsUUFBTU0sU0FBUyxHQUFHLHdCQUFsQjtBQUNBLFFBQU1DLEtBQUssR0FBR1AsT0FBTyxDQUFDUSxXQUFSLEdBQXNCRCxLQUF0QixDQUE0QkQsU0FBNUIsQ0FBZDs7QUFDQSxNQUFJQyxLQUFLLElBQUlBLEtBQUssQ0FBQ0UsTUFBTixLQUFpQixDQUE5QixFQUFpQztBQUMvQixXQUFPO0FBQ0xQLE1BQUFBLEdBQUcsRUFBRUssS0FBSyxDQUFDLENBQUQsQ0FETDtBQUVMUCxNQUFBQSxPQUFPLEVBQUVPLEtBQUssQ0FBQyxDQUFEO0FBRlQsS0FBUDtBQUlEOztBQUNELFNBQU9HLFNBQVA7QUFDRDs7QUFFREMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZqQixFQUFBQSxVQURlO0FBRWZTLEVBQUFBLHFCQUZlO0FBR2ZOLEVBQUFBO0FBSGUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgc2VtdmVyID0gcmVxdWlyZSgnc2VtdmVyJyk7XG5cbmZ1bmN0aW9uIGNvbXBhdGlibGUoY29tcGF0aWJsZVNESykge1xuICByZXR1cm4gZnVuY3Rpb24gKGNsaWVudFNESykge1xuICAgIGlmICh0eXBlb2YgY2xpZW50U0RLID09PSAnc3RyaW5nJykge1xuICAgICAgY2xpZW50U0RLID0gZnJvbVN0cmluZyhjbGllbnRTREspO1xuICAgIH1cbiAgICAvLyBSRVNUIEFQSSwgb3IgY3VzdG9tIFNES1xuICAgIGlmICghY2xpZW50U0RLKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgY2xpZW50VmVyc2lvbiA9IGNsaWVudFNESy52ZXJzaW9uO1xuICAgIGNvbnN0IGNvbXBhdGlibGl0eVZlcnNpb24gPSBjb21wYXRpYmxlU0RLW2NsaWVudFNESy5zZGtdO1xuICAgIHJldHVybiBzZW12ZXIuc2F0aXNmaWVzKGNsaWVudFZlcnNpb24sIGNvbXBhdGlibGl0eVZlcnNpb24pO1xuICB9O1xufVxuXG5mdW5jdGlvbiBzdXBwb3J0c0ZvcndhcmREZWxldGUoY2xpZW50U0RLKSB7XG4gIHJldHVybiBjb21wYXRpYmxlKHtcbiAgICBqczogJz49MS45LjAnLFxuICB9KShjbGllbnRTREspO1xufVxuXG5mdW5jdGlvbiBmcm9tU3RyaW5nKHZlcnNpb24pIHtcbiAgY29uc3QgdmVyc2lvblJFID0gLyhbLWEtekEtWl0rKShbMC05XFwuXSspLztcbiAgY29uc3QgbWF0Y2ggPSB2ZXJzaW9uLnRvTG93ZXJDYXNlKCkubWF0Y2godmVyc2lvblJFKTtcbiAgaWYgKG1hdGNoICYmIG1hdGNoLmxlbmd0aCA9PT0gMykge1xuICAgIHJldHVybiB7XG4gICAgICBzZGs6IG1hdGNoWzFdLFxuICAgICAgdmVyc2lvbjogbWF0Y2hbMl0sXG4gICAgfTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgY29tcGF0aWJsZSxcbiAgc3VwcG9ydHNGb3J3YXJkRGVsZXRlLFxuICBmcm9tU3RyaW5nLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Config.js b/lib/Config.js new file mode 100644 index 0000000000..359b191cc1 --- /dev/null +++ b/lib/Config.js @@ -0,0 +1,471 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.Config = void 0; + +var _cache = _interopRequireDefault(require("./cache")); + +var _SchemaCache = _interopRequireDefault(require("./Controllers/SchemaCache")); + +var _DatabaseController = _interopRequireDefault(require("./Controllers/DatabaseController")); + +var _net = _interopRequireDefault(require("net")); + +var _Definitions = require("./Options/Definitions"); + +var _lodash = require("lodash"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// A Config object provides information about how a specific app is +// configured. +// mount is the URL for the root of the API; includes http, domain, etc. +function removeTrailingSlash(str) { + if (!str) { + return str; + } + + if (str.endsWith('/')) { + str = str.substr(0, str.length - 1); + } + + return str; +} + +class Config { + static get(applicationId, mount) { + const cacheInfo = _cache.default.get(applicationId); + + if (!cacheInfo) { + return; + } + + const config = new Config(); + config.applicationId = applicationId; + Object.keys(cacheInfo).forEach(key => { + if (key == 'databaseController') { + const schemaCache = new _SchemaCache.default(cacheInfo.cacheController, cacheInfo.schemaCacheTTL, cacheInfo.enableSingleSchemaCache); + config.database = new _DatabaseController.default(cacheInfo.databaseController.adapter, schemaCache); + } else { + config[key] = cacheInfo[key]; + } + }); + config.mount = removeTrailingSlash(mount); + config.generateSessionExpiresAt = config.generateSessionExpiresAt.bind(config); + config.generateEmailVerifyTokenExpiresAt = config.generateEmailVerifyTokenExpiresAt.bind(config); + return config; + } + + static put(serverConfiguration) { + Config.validate(serverConfiguration); + + _cache.default.put(serverConfiguration.appId, serverConfiguration); + + Config.setupPasswordValidator(serverConfiguration.passwordPolicy); + return serverConfiguration; + } + + static validate({ + verifyUserEmails, + userController, + appName, + publicServerURL, + revokeSessionOnPasswordReset, + expireInactiveSessions, + sessionLength, + maxLimit, + emailVerifyTokenValidityDuration, + accountLockout, + passwordPolicy, + masterKeyIps, + masterKey, + readOnlyMasterKey, + allowHeaders, + idempotencyOptions, + emailVerifyTokenReuseIfValid, + fileUpload, + pages + }) { + if (masterKey === readOnlyMasterKey) { + throw new Error('masterKey and readOnlyMasterKey should be different'); + } + + const emailAdapter = userController.adapter; + + if (verifyUserEmails) { + this.validateEmailConfiguration({ + emailAdapter, + appName, + publicServerURL, + emailVerifyTokenValidityDuration, + emailVerifyTokenReuseIfValid + }); + } + + this.validateAccountLockoutPolicy(accountLockout); + this.validatePasswordPolicy(passwordPolicy); + this.validateFileUploadOptions(fileUpload); + + if (typeof revokeSessionOnPasswordReset !== 'boolean') { + throw 'revokeSessionOnPasswordReset must be a boolean value'; + } + + if (publicServerURL) { + if (!publicServerURL.startsWith('http://') && !publicServerURL.startsWith('https://')) { + throw 'publicServerURL should be a valid HTTPS URL starting with https://'; + } + } + + this.validateSessionConfiguration(sessionLength, expireInactiveSessions); + this.validateMasterKeyIps(masterKeyIps); + this.validateMaxLimit(maxLimit); + this.validateAllowHeaders(allowHeaders); + this.validateIdempotencyOptions(idempotencyOptions); + this.validatePagesOptions(pages); + } + + static validatePagesOptions(pages) { + if (Object.prototype.toString.call(pages) !== '[object Object]') { + throw 'Parse Server option pages must be an object.'; + } + + if (pages.enableRouter === undefined) { + pages.enableRouter = _Definitions.PagesOptions.enableRouter.default; + } else if (!(0, _lodash.isBoolean)(pages.enableRouter)) { + throw 'Parse Server option pages.enableRouter must be a boolean.'; + } + + if (pages.enableLocalization === undefined) { + pages.enableLocalization = _Definitions.PagesOptions.enableLocalization.default; + } else if (!(0, _lodash.isBoolean)(pages.enableLocalization)) { + throw 'Parse Server option pages.enableLocalization must be a boolean.'; + } + + if (pages.localizationJsonPath === undefined) { + pages.localizationJsonPath = _Definitions.PagesOptions.localizationJsonPath.default; + } else if (!(0, _lodash.isString)(pages.localizationJsonPath)) { + throw 'Parse Server option pages.localizationJsonPath must be a string.'; + } + + if (pages.localizationFallbackLocale === undefined) { + pages.localizationFallbackLocale = _Definitions.PagesOptions.localizationFallbackLocale.default; + } else if (!(0, _lodash.isString)(pages.localizationFallbackLocale)) { + throw 'Parse Server option pages.localizationFallbackLocale must be a string.'; + } + + if (pages.placeholders === undefined) { + pages.placeholders = _Definitions.PagesOptions.placeholders.default; + } else if (Object.prototype.toString.call(pages.placeholders) !== '[object Object]' && typeof pages.placeholders !== 'function') { + throw 'Parse Server option pages.placeholders must be an object or a function.'; + } + + if (pages.forceRedirect === undefined) { + pages.forceRedirect = _Definitions.PagesOptions.forceRedirect.default; + } else if (!(0, _lodash.isBoolean)(pages.forceRedirect)) { + throw 'Parse Server option pages.forceRedirect must be a boolean.'; + } + + if (pages.pagesPath === undefined) { + pages.pagesPath = _Definitions.PagesOptions.pagesPath.default; + } else if (!(0, _lodash.isString)(pages.pagesPath)) { + throw 'Parse Server option pages.pagesPath must be a string.'; + } + + if (pages.pagesEndpoint === undefined) { + pages.pagesEndpoint = _Definitions.PagesOptions.pagesEndpoint.default; + } else if (!(0, _lodash.isString)(pages.pagesEndpoint)) { + throw 'Parse Server option pages.pagesEndpoint must be a string.'; + } + + if (pages.customUrls === undefined) { + pages.customUrls = _Definitions.PagesOptions.customUrls.default; + } else if (Object.prototype.toString.call(pages.customUrls) !== '[object Object]') { + throw 'Parse Server option pages.customUrls must be an object.'; + } + } + + static validateIdempotencyOptions(idempotencyOptions) { + if (!idempotencyOptions) { + return; + } + + if (idempotencyOptions.ttl === undefined) { + idempotencyOptions.ttl = _Definitions.IdempotencyOptions.ttl.default; + } else if (!isNaN(idempotencyOptions.ttl) && idempotencyOptions.ttl <= 0) { + throw 'idempotency TTL value must be greater than 0 seconds'; + } else if (isNaN(idempotencyOptions.ttl)) { + throw 'idempotency TTL value must be a number'; + } + + if (!idempotencyOptions.paths) { + idempotencyOptions.paths = _Definitions.IdempotencyOptions.paths.default; + } else if (!(idempotencyOptions.paths instanceof Array)) { + throw 'idempotency paths must be of an array of strings'; + } + } + + static validateAccountLockoutPolicy(accountLockout) { + if (accountLockout) { + if (typeof accountLockout.duration !== 'number' || accountLockout.duration <= 0 || accountLockout.duration > 99999) { + throw 'Account lockout duration should be greater than 0 and less than 100000'; + } + + if (!Number.isInteger(accountLockout.threshold) || accountLockout.threshold < 1 || accountLockout.threshold > 999) { + throw 'Account lockout threshold should be an integer greater than 0 and less than 1000'; + } + + if (accountLockout.unlockOnPasswordReset === undefined) { + accountLockout.unlockOnPasswordReset = _Definitions.AccountLockoutOptions.unlockOnPasswordReset.default; + } else if (!(0, _lodash.isBoolean)(accountLockout.unlockOnPasswordReset)) { + throw 'Parse Server option accountLockout.unlockOnPasswordReset must be a boolean.'; + } + } + } + + static validatePasswordPolicy(passwordPolicy) { + if (passwordPolicy) { + if (passwordPolicy.maxPasswordAge !== undefined && (typeof passwordPolicy.maxPasswordAge !== 'number' || passwordPolicy.maxPasswordAge < 0)) { + throw 'passwordPolicy.maxPasswordAge must be a positive number'; + } + + if (passwordPolicy.resetTokenValidityDuration !== undefined && (typeof passwordPolicy.resetTokenValidityDuration !== 'number' || passwordPolicy.resetTokenValidityDuration <= 0)) { + throw 'passwordPolicy.resetTokenValidityDuration must be a positive number'; + } + + if (passwordPolicy.validatorPattern) { + if (typeof passwordPolicy.validatorPattern === 'string') { + passwordPolicy.validatorPattern = new RegExp(passwordPolicy.validatorPattern); + } else if (!(passwordPolicy.validatorPattern instanceof RegExp)) { + throw 'passwordPolicy.validatorPattern must be a regex string or RegExp object.'; + } + } + + if (passwordPolicy.validatorCallback && typeof passwordPolicy.validatorCallback !== 'function') { + throw 'passwordPolicy.validatorCallback must be a function.'; + } + + if (passwordPolicy.doNotAllowUsername && typeof passwordPolicy.doNotAllowUsername !== 'boolean') { + throw 'passwordPolicy.doNotAllowUsername must be a boolean value.'; + } + + if (passwordPolicy.maxPasswordHistory && (!Number.isInteger(passwordPolicy.maxPasswordHistory) || passwordPolicy.maxPasswordHistory <= 0 || passwordPolicy.maxPasswordHistory > 20)) { + throw 'passwordPolicy.maxPasswordHistory must be an integer ranging 0 - 20'; + } + + if (passwordPolicy.resetTokenReuseIfValid && typeof passwordPolicy.resetTokenReuseIfValid !== 'boolean') { + throw 'resetTokenReuseIfValid must be a boolean value'; + } + + if (passwordPolicy.resetTokenReuseIfValid && !passwordPolicy.resetTokenValidityDuration) { + throw 'You cannot use resetTokenReuseIfValid without resetTokenValidityDuration'; + } + } + } // if the passwordPolicy.validatorPattern is configured then setup a callback to process the pattern + + + static setupPasswordValidator(passwordPolicy) { + if (passwordPolicy && passwordPolicy.validatorPattern) { + passwordPolicy.patternValidator = value => { + return passwordPolicy.validatorPattern.test(value); + }; + } + } + + static validateEmailConfiguration({ + emailAdapter, + appName, + publicServerURL, + emailVerifyTokenValidityDuration, + emailVerifyTokenReuseIfValid + }) { + if (!emailAdapter) { + throw 'An emailAdapter is required for e-mail verification and password resets.'; + } + + if (typeof appName !== 'string') { + throw 'An app name is required for e-mail verification and password resets.'; + } + + if (typeof publicServerURL !== 'string') { + throw 'A public server url is required for e-mail verification and password resets.'; + } + + if (emailVerifyTokenValidityDuration) { + if (isNaN(emailVerifyTokenValidityDuration)) { + throw 'Email verify token validity duration must be a valid number.'; + } else if (emailVerifyTokenValidityDuration <= 0) { + throw 'Email verify token validity duration must be a value greater than 0.'; + } + } + + if (emailVerifyTokenReuseIfValid && typeof emailVerifyTokenReuseIfValid !== 'boolean') { + throw 'emailVerifyTokenReuseIfValid must be a boolean value'; + } + + if (emailVerifyTokenReuseIfValid && !emailVerifyTokenValidityDuration) { + throw 'You cannot use emailVerifyTokenReuseIfValid without emailVerifyTokenValidityDuration'; + } + } + + static validateFileUploadOptions(fileUpload) { + try { + if (fileUpload == null || typeof fileUpload !== 'object' || fileUpload instanceof Array) { + throw 'fileUpload must be an object value.'; + } + } catch (e) { + if (e instanceof ReferenceError) { + return; + } + + throw e; + } + + if (fileUpload.enableForAnonymousUser === undefined) { + fileUpload.enableForAnonymousUser = _Definitions.FileUploadOptions.enableForAnonymousUser.default; + } else if (typeof fileUpload.enableForAnonymousUser !== 'boolean') { + throw 'fileUpload.enableForAnonymousUser must be a boolean value.'; + } + + if (fileUpload.enableForPublic === undefined) { + fileUpload.enableForPublic = _Definitions.FileUploadOptions.enableForPublic.default; + } else if (typeof fileUpload.enableForPublic !== 'boolean') { + throw 'fileUpload.enableForPublic must be a boolean value.'; + } + + if (fileUpload.enableForAuthenticatedUser === undefined) { + fileUpload.enableForAuthenticatedUser = _Definitions.FileUploadOptions.enableForAuthenticatedUser.default; + } else if (typeof fileUpload.enableForAuthenticatedUser !== 'boolean') { + throw 'fileUpload.enableForAuthenticatedUser must be a boolean value.'; + } + } + + static validateMasterKeyIps(masterKeyIps) { + for (const ip of masterKeyIps) { + if (!_net.default.isIP(ip)) { + throw `Invalid ip in masterKeyIps: ${ip}`; + } + } + } + + get mount() { + var mount = this._mount; + + if (this.publicServerURL) { + mount = this.publicServerURL; + } + + return mount; + } + + set mount(newValue) { + this._mount = newValue; + } + + static validateSessionConfiguration(sessionLength, expireInactiveSessions) { + if (expireInactiveSessions) { + if (isNaN(sessionLength)) { + throw 'Session length must be a valid number.'; + } else if (sessionLength <= 0) { + throw 'Session length must be a value greater than 0.'; + } + } + } + + static validateMaxLimit(maxLimit) { + if (maxLimit <= 0) { + throw 'Max limit must be a value greater than 0.'; + } + } + + static validateAllowHeaders(allowHeaders) { + if (![null, undefined].includes(allowHeaders)) { + if (Array.isArray(allowHeaders)) { + allowHeaders.forEach(header => { + if (typeof header !== 'string') { + throw 'Allow headers must only contain strings'; + } else if (!header.trim().length) { + throw 'Allow headers must not contain empty strings'; + } + }); + } else { + throw 'Allow headers must be an array'; + } + } + } + + generateEmailVerifyTokenExpiresAt() { + if (!this.verifyUserEmails || !this.emailVerifyTokenValidityDuration) { + return undefined; + } + + var now = new Date(); + return new Date(now.getTime() + this.emailVerifyTokenValidityDuration * 1000); + } + + generatePasswordResetTokenExpiresAt() { + if (!this.passwordPolicy || !this.passwordPolicy.resetTokenValidityDuration) { + return undefined; + } + + const now = new Date(); + return new Date(now.getTime() + this.passwordPolicy.resetTokenValidityDuration * 1000); + } + + generateSessionExpiresAt() { + if (!this.expireInactiveSessions) { + return undefined; + } + + var now = new Date(); + return new Date(now.getTime() + this.sessionLength * 1000); + } + + get invalidLinkURL() { + return this.customPages.invalidLink || `${this.publicServerURL}/apps/invalid_link.html`; + } + + get invalidVerificationLinkURL() { + return this.customPages.invalidVerificationLink || `${this.publicServerURL}/apps/invalid_verification_link.html`; + } + + get linkSendSuccessURL() { + return this.customPages.linkSendSuccess || `${this.publicServerURL}/apps/link_send_success.html`; + } + + get linkSendFailURL() { + return this.customPages.linkSendFail || `${this.publicServerURL}/apps/link_send_fail.html`; + } + + get verifyEmailSuccessURL() { + return this.customPages.verifyEmailSuccess || `${this.publicServerURL}/apps/verify_email_success.html`; + } + + get choosePasswordURL() { + return this.customPages.choosePassword || `${this.publicServerURL}/apps/choose_password`; + } + + get requestResetPasswordURL() { + return `${this.publicServerURL}/apps/${this.applicationId}/request_password_reset`; + } + + get passwordResetSuccessURL() { + return this.customPages.passwordResetSuccess || `${this.publicServerURL}/apps/password_reset_success.html`; + } + + get parseFrameURL() { + return this.customPages.parseFrameURL; + } + + get verifyEmailURL() { + return `${this.publicServerURL}/apps/${this.applicationId}/verify_email`; + } + +} + +exports.Config = Config; +var _default = Config; +exports.default = _default; +module.exports = Config; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9Db25maWcuanMiXSwibmFtZXMiOlsicmVtb3ZlVHJhaWxpbmdTbGFzaCIsInN0ciIsImVuZHNXaXRoIiwic3Vic3RyIiwibGVuZ3RoIiwiQ29uZmlnIiwiZ2V0IiwiYXBwbGljYXRpb25JZCIsIm1vdW50IiwiY2FjaGVJbmZvIiwiQXBwQ2FjaGUiLCJjb25maWciLCJPYmplY3QiLCJrZXlzIiwiZm9yRWFjaCIsImtleSIsInNjaGVtYUNhY2hlIiwiU2NoZW1hQ2FjaGUiLCJjYWNoZUNvbnRyb2xsZXIiLCJzY2hlbWFDYWNoZVRUTCIsImVuYWJsZVNpbmdsZVNjaGVtYUNhY2hlIiwiZGF0YWJhc2UiLCJEYXRhYmFzZUNvbnRyb2xsZXIiLCJkYXRhYmFzZUNvbnRyb2xsZXIiLCJhZGFwdGVyIiwiZ2VuZXJhdGVTZXNzaW9uRXhwaXJlc0F0IiwiYmluZCIsImdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbkV4cGlyZXNBdCIsInB1dCIsInNlcnZlckNvbmZpZ3VyYXRpb24iLCJ2YWxpZGF0ZSIsImFwcElkIiwic2V0dXBQYXNzd29yZFZhbGlkYXRvciIsInBhc3N3b3JkUG9saWN5IiwidmVyaWZ5VXNlckVtYWlscyIsInVzZXJDb250cm9sbGVyIiwiYXBwTmFtZSIsInB1YmxpY1NlcnZlclVSTCIsInJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQiLCJleHBpcmVJbmFjdGl2ZVNlc3Npb25zIiwic2Vzc2lvbkxlbmd0aCIsIm1heExpbWl0IiwiZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJhY2NvdW50TG9ja291dCIsIm1hc3RlcktleUlwcyIsIm1hc3RlcktleSIsInJlYWRPbmx5TWFzdGVyS2V5IiwiYWxsb3dIZWFkZXJzIiwiaWRlbXBvdGVuY3lPcHRpb25zIiwiZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZCIsImZpbGVVcGxvYWQiLCJwYWdlcyIsIkVycm9yIiwiZW1haWxBZGFwdGVyIiwidmFsaWRhdGVFbWFpbENvbmZpZ3VyYXRpb24iLCJ2YWxpZGF0ZUFjY291bnRMb2Nrb3V0UG9saWN5IiwidmFsaWRhdGVQYXNzd29yZFBvbGljeSIsInZhbGlkYXRlRmlsZVVwbG9hZE9wdGlvbnMiLCJzdGFydHNXaXRoIiwidmFsaWRhdGVTZXNzaW9uQ29uZmlndXJhdGlvbiIsInZhbGlkYXRlTWFzdGVyS2V5SXBzIiwidmFsaWRhdGVNYXhMaW1pdCIsInZhbGlkYXRlQWxsb3dIZWFkZXJzIiwidmFsaWRhdGVJZGVtcG90ZW5jeU9wdGlvbnMiLCJ2YWxpZGF0ZVBhZ2VzT3B0aW9ucyIsInByb3RvdHlwZSIsInRvU3RyaW5nIiwiY2FsbCIsImVuYWJsZVJvdXRlciIsInVuZGVmaW5lZCIsIlBhZ2VzT3B0aW9ucyIsImRlZmF1bHQiLCJlbmFibGVMb2NhbGl6YXRpb24iLCJsb2NhbGl6YXRpb25Kc29uUGF0aCIsImxvY2FsaXphdGlvbkZhbGxiYWNrTG9jYWxlIiwicGxhY2Vob2xkZXJzIiwiZm9yY2VSZWRpcmVjdCIsInBhZ2VzUGF0aCIsInBhZ2VzRW5kcG9pbnQiLCJjdXN0b21VcmxzIiwidHRsIiwiSWRlbXBvdGVuY3lPcHRpb25zIiwiaXNOYU4iLCJwYXRocyIsIkFycmF5IiwiZHVyYXRpb24iLCJOdW1iZXIiLCJpc0ludGVnZXIiLCJ0aHJlc2hvbGQiLCJ1bmxvY2tPblBhc3N3b3JkUmVzZXQiLCJBY2NvdW50TG9ja291dE9wdGlvbnMiLCJtYXhQYXNzd29yZEFnZSIsInJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uIiwidmFsaWRhdG9yUGF0dGVybiIsIlJlZ0V4cCIsInZhbGlkYXRvckNhbGxiYWNrIiwiZG9Ob3RBbGxvd1VzZXJuYW1lIiwibWF4UGFzc3dvcmRIaXN0b3J5IiwicmVzZXRUb2tlblJldXNlSWZWYWxpZCIsInBhdHRlcm5WYWxpZGF0b3IiLCJ2YWx1ZSIsInRlc3QiLCJlIiwiUmVmZXJlbmNlRXJyb3IiLCJlbmFibGVGb3JBbm9ueW1vdXNVc2VyIiwiRmlsZVVwbG9hZE9wdGlvbnMiLCJlbmFibGVGb3JQdWJsaWMiLCJlbmFibGVGb3JBdXRoZW50aWNhdGVkVXNlciIsImlwIiwibmV0IiwiaXNJUCIsIl9tb3VudCIsIm5ld1ZhbHVlIiwiaW5jbHVkZXMiLCJpc0FycmF5IiwiaGVhZGVyIiwidHJpbSIsIm5vdyIsIkRhdGUiLCJnZXRUaW1lIiwiZ2VuZXJhdGVQYXNzd29yZFJlc2V0VG9rZW5FeHBpcmVzQXQiLCJpbnZhbGlkTGlua1VSTCIsImN1c3RvbVBhZ2VzIiwiaW52YWxpZExpbmsiLCJpbnZhbGlkVmVyaWZpY2F0aW9uTGlua1VSTCIsImludmFsaWRWZXJpZmljYXRpb25MaW5rIiwibGlua1NlbmRTdWNjZXNzVVJMIiwibGlua1NlbmRTdWNjZXNzIiwibGlua1NlbmRGYWlsVVJMIiwibGlua1NlbmRGYWlsIiwidmVyaWZ5RW1haWxTdWNjZXNzVVJMIiwidmVyaWZ5RW1haWxTdWNjZXNzIiwiY2hvb3NlUGFzc3dvcmRVUkwiLCJjaG9vc2VQYXNzd29yZCIsInJlcXVlc3RSZXNldFBhc3N3b3JkVVJMIiwicGFzc3dvcmRSZXNldFN1Y2Nlc3NVUkwiLCJwYXNzd29yZFJlc2V0U3VjY2VzcyIsInBhcnNlRnJhbWVVUkwiLCJ2ZXJpZnlFbWFpbFVSTCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFJQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFNQTs7OztBQWRBO0FBQ0E7QUFDQTtBQWNBLFNBQVNBLG1CQUFULENBQTZCQyxHQUE3QixFQUFrQztBQUNoQyxNQUFJLENBQUNBLEdBQUwsRUFBVTtBQUNSLFdBQU9BLEdBQVA7QUFDRDs7QUFDRCxNQUFJQSxHQUFHLENBQUNDLFFBQUosQ0FBYSxHQUFiLENBQUosRUFBdUI7QUFDckJELElBQUFBLEdBQUcsR0FBR0EsR0FBRyxDQUFDRSxNQUFKLENBQVcsQ0FBWCxFQUFjRixHQUFHLENBQUNHLE1BQUosR0FBYSxDQUEzQixDQUFOO0FBQ0Q7O0FBQ0QsU0FBT0gsR0FBUDtBQUNEOztBQUVNLE1BQU1JLE1BQU4sQ0FBYTtBQUNsQixT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V0FBTCxDQUFpQlcsY0FBakIsSUFBb0MsR0FBRSxLQUFLaEcsZUFBZ0IsdUJBQWxFO0FBQ0Q7O0FBRUQsTUFBSWlHLHVCQUFKLEdBQThCO0FBQzVCLFdBQVEsR0FBRSxLQUFLakcsZUFBZ0IsU0FBUSxLQUFLOUIsYUFBYyx5QkFBMUQ7QUFDRDs7QUFFRCxNQUFJZ0ksdUJBQUosR0FBOEI7QUFDNUIsV0FDRSxLQUFLYixXQUFMLENBQWlCYyxvQkFBakIsSUFDQyxHQUFFLEtBQUtuRyxlQUFnQixtQ0FGMUI7QUFJRDs7QUFFRCxNQUFJb0csYUFBSixHQUFvQjtBQUNsQixXQUFPLEtBQUtmLFdBQUwsQ0FBaUJlLGFBQXhCO0FBQ0Q7O0FBRUQsTUFBSUMsY0FBSixHQUFxQjtBQUNuQixXQUFRLEdBQUUsS0FBS3JHLGVBQWdCLFNBQVEsS0FBSzlCLGFBQWMsZUFBMUQ7QUFDRDs7QUEzYmlCOzs7ZUE4YkxGLE07O0FBQ2ZzSSxNQUFNLENBQUNDLE9BQVAsR0FBaUJ2SSxNQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEEgQ29uZmlnIG9iamVjdCBwcm92aWRlcyBpbmZvcm1hdGlvbiBhYm91dCBob3cgYSBzcGVjaWZpYyBhcHAgaXNcbi8vIGNvbmZpZ3VyZWQuXG4vLyBtb3VudCBpcyB0aGUgVVJMIGZvciB0aGUgcm9vdCBvZiB0aGUgQVBJOyBpbmNsdWRlcyBodHRwLCBkb21haW4sIGV0Yy5cblxuaW1wb3J0IEFwcENhY2hlIGZyb20gJy4vY2FjaGUnO1xuaW1wb3J0IFNjaGVtYUNhY2hlIGZyb20gJy4vQ29udHJvbGxlcnMvU2NoZW1hQ2FjaGUnO1xuaW1wb3J0IERhdGFiYXNlQ29udHJvbGxlciBmcm9tICcuL0NvbnRyb2xsZXJzL0RhdGFiYXNlQ29udHJvbGxlcic7XG5pbXBvcnQgbmV0IGZyb20gJ25ldCc7XG5pbXBvcnQge1xuICBJZGVtcG90ZW5jeU9wdGlvbnMsXG4gIEZpbGVVcGxvYWRPcHRpb25zLFxuICBBY2NvdW50TG9ja291dE9wdGlvbnMsXG4gIFBhZ2VzT3B0aW9ucyxcbn0gZnJvbSAnLi9PcHRpb25zL0RlZmluaXRpb25zJztcbmltcG9ydCB7IGlzQm9vbGVhbiwgaXNTdHJpbmcgfSBmcm9tICdsb2Rhc2gnO1xuXG5mdW5jdGlvbiByZW1vdmVUcmFpbGluZ1NsYXNoKHN0cikge1xuICBpZiAoIXN0cikge1xuICAgIHJldHVybiBzdHI7XG4gIH1cbiAgaWYgKHN0ci5lbmRzV2l0aCgnLycpKSB7XG4gICAgc3RyID0gc3RyLnN1YnN0cigwLCBzdHIubGVuZ3RoIC0gMSk7XG4gIH1cbiAgcmV0dXJuIHN0cjtcbn1cblxuZXhwb3J0IGNsYXNzIENvbmZpZyB7XG4gIHN0YXRpYyBnZXQoYXBwbGljYXRpb25JZDogc3RyaW5nLCBtb3VudDogc3RyaW5nKSB7XG4gICAgY29uc3QgY2FjaGVJbmZvID0gQXBwQ2FjaGUuZ2V0KGFwcGxpY2F0aW9uSWQpO1xuICAgIGlmICghY2FjaGVJbmZvKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBDb25maWcoKTtcbiAgICBjb25maWcuYXBwbGljYXRpb25JZCA9IGFwcGxpY2F0aW9uSWQ7XG4gICAgT2JqZWN0LmtleXMoY2FjaGVJbmZvKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBpZiAoa2V5ID09ICdkYXRhYmFzZUNvbnRyb2xsZXInKSB7XG4gICAgICAgIGNvbnN0IHNjaGVtYUNhY2hlID0gbmV3IFNjaGVtYUNhY2hlKFxuICAgICAgICAgIGNhY2hlSW5mby5jYWNoZUNvbnRyb2xsZXIsXG4gICAgICAgICAgY2FjaGVJbmZvLnNjaGVtYUNhY2hlVFRMLFxuICAgICAgICAgIGNhY2hlSW5mby5lbmFibGVTaW5nbGVTY2hlbWFDYWNoZVxuICAgICAgICApO1xuICAgICAgICBjb25maWcuZGF0YWJhc2UgPSBuZXcgRGF0YWJhc2VDb250cm9sbGVyKGNhY2hlSW5mby5kYXRhYmFzZUNvbnRyb2xsZXIuYWRhcHRlciwgc2NoZW1hQ2FjaGUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uZmlnW2tleV0gPSBjYWNoZUluZm9ba2V5XTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25maWcubW91bnQgPSByZW1vdmVUcmFpbGluZ1NsYXNoKG1vdW50KTtcbiAgICBjb25maWcuZ2VuZXJhdGVTZXNzaW9uRXhwaXJlc0F0ID0gY29uZmlnLmdlbmVyYXRlU2Vzc2lvbkV4cGlyZXNBdC5iaW5kKGNvbmZpZyk7XG4gICAgY29uZmlnLmdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbkV4cGlyZXNBdCA9IGNvbmZpZy5nZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW5FeHBpcmVzQXQuYmluZChcbiAgICAgIGNvbmZpZ1xuICAgICk7XG4gICAgcmV0dXJuIGNvbmZpZztcbiAgfVxuXG4gIHN0YXRpYyBwdXQoc2VydmVyQ29uZmlndXJhdGlvbikge1xuICAgIENvbmZpZy52YWxpZGF0ZShzZXJ2ZXJDb25maWd1cmF0aW9uKTtcbiAgICBBcHBDYWNoZS5wdXQoc2VydmVyQ29uZmlndXJhdGlvbi5hcHBJZCwgc2VydmVyQ29uZmlndXJhdGlvbik7XG4gICAgQ29uZmlnLnNldHVwUGFzc3dvcmRWYWxpZGF0b3Ioc2VydmVyQ29uZmlndXJhdGlvbi5wYXNzd29yZFBvbGljeSk7XG4gICAgcmV0dXJuIHNlcnZlckNvbmZpZ3VyYXRpb247XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGUoe1xuICAgIHZlcmlmeVVzZXJFbWFpbHMsXG4gICAgdXNlckNvbnRyb2xsZXIsXG4gICAgYXBwTmFtZSxcbiAgICBwdWJsaWNTZXJ2ZXJVUkwsXG4gICAgcmV2b2tlU2Vzc2lvbk9uUGFzc3dvcmRSZXNldCxcbiAgICBleHBpcmVJbmFjdGl2ZVNlc3Npb25zLFxuICAgIHNlc3Npb25MZW5ndGgsXG4gICAgbWF4TGltaXQsXG4gICAgZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24sXG4gICAgYWNjb3VudExvY2tvdXQsXG4gICAgcGFzc3dvcmRQb2xpY3ksXG4gICAgbWFzdGVyS2V5SXBzLFxuICAgIG1hc3RlcktleSxcbiAgICByZWFkT25seU1hc3RlcktleSxcbiAgICBhbGxvd0hlYWRlcnMsXG4gICAgaWRlbXBvdGVuY3lPcHRpb25zLFxuICAgIGVtYWlsVmVyaWZ5VG9rZW5SZXVzZUlmVmFsaWQsXG4gICAgZmlsZVVwbG9hZCxcbiAgICBwYWdlcyxcbiAgfSkge1xuICAgIGlmIChtYXN0ZXJLZXkgPT09IHJlYWRPbmx5TWFzdGVyS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21hc3RlcktleSBhbmQgcmVhZE9ubHlNYXN0ZXJLZXkgc2hvdWxkIGJlIGRpZmZlcmVudCcpO1xuICAgIH1cblxuICAgIGNvbnN0IGVtYWlsQWRhcHRlciA9IHVzZXJDb250cm9sbGVyLmFkYXB0ZXI7XG4gICAgaWYgKHZlcmlmeVVzZXJFbWFpbHMpIHtcbiAgICAgIHRoaXMudmFsaWRhdGVFbWFpbENvbmZpZ3VyYXRpb24oe1xuICAgICAgICBlbWFpbEFkYXB0ZXIsXG4gICAgICAgIGFwcE5hbWUsXG4gICAgICAgIHB1YmxpY1NlcnZlclVSTCxcbiAgICAgICAgZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24sXG4gICAgICAgIGVtYWlsVmVyaWZ5VG9rZW5SZXVzZUlmVmFsaWQsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLnZhbGlkYXRlQWNjb3VudExvY2tvdXRQb2xpY3koYWNjb3VudExvY2tvdXQpO1xuICAgIHRoaXMudmFsaWRhdGVQYXNzd29yZFBvbGljeShwYXNzd29yZFBvbGljeSk7XG4gICAgdGhpcy52YWxpZGF0ZUZpbGVVcGxvYWRPcHRpb25zKGZpbGVVcGxvYWQpO1xuXG4gICAgaWYgKHR5cGVvZiByZXZva2VTZXNzaW9uT25QYXNzd29yZFJlc2V0ICE9PSAnYm9vbGVhbicpIHtcbiAgICAgIHRocm93ICdyZXZva2VTZXNzaW9uT25QYXNzd29yZFJlc2V0IG11c3QgYmUgYSBib29sZWFuIHZhbHVlJztcbiAgICB9XG5cbiAgICBpZiAocHVibGljU2VydmVyVVJMKSB7XG4gICAgICBpZiAoIXB1YmxpY1NlcnZlclVSTC5zdGFydHNXaXRoKCdodHRwOi8vJykgJiYgIXB1YmxpY1NlcnZlclVSTC5zdGFydHNXaXRoKCdodHRwczovLycpKSB7XG4gICAgICAgIHRocm93ICdwdWJsaWNTZXJ2ZXJVUkwgc2hvdWxkIGJlIGEgdmFsaWQgSFRUUFMgVVJMIHN0YXJ0aW5nIHdpdGggaHR0cHM6Ly8nO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnZhbGlkYXRlU2Vzc2lvbkNvbmZpZ3VyYXRpb24oc2Vzc2lvbkxlbmd0aCwgZXhwaXJlSW5hY3RpdmVTZXNzaW9ucyk7XG4gICAgdGhpcy52YWxpZGF0ZU1hc3RlcktleUlwcyhtYXN0ZXJLZXlJcHMpO1xuICAgIHRoaXMudmFsaWRhdGVNYXhMaW1pdChtYXhMaW1pdCk7XG4gICAgdGhpcy52YWxpZGF0ZUFsbG93SGVhZGVycyhhbGxvd0hlYWRlcnMpO1xuICAgIHRoaXMudmFsaWRhdGVJZGVtcG90ZW5jeU9wdGlvbnMoaWRlbXBvdGVuY3lPcHRpb25zKTtcbiAgICB0aGlzLnZhbGlkYXRlUGFnZXNPcHRpb25zKHBhZ2VzKTtcbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZVBhZ2VzT3B0aW9ucyhwYWdlcykge1xuICAgIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwocGFnZXMpICE9PSAnW29iamVjdCBPYmplY3RdJykge1xuICAgICAgdGhyb3cgJ1BhcnNlIFNlcnZlciBvcHRpb24gcGFnZXMgbXVzdCBiZSBhbiBvYmplY3QuJztcbiAgICB9XG4gICAgaWYgKHBhZ2VzLmVuYWJsZVJvdXRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBwYWdlcy5lbmFibGVSb3V0ZXIgPSBQYWdlc09wdGlvbnMuZW5hYmxlUm91dGVyLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICghaXNCb29sZWFuKHBhZ2VzLmVuYWJsZVJvdXRlcikpIHtcbiAgICAgIHRocm93ICdQYXJzZSBTZXJ2ZXIgb3B0aW9uIHBhZ2VzLmVuYWJsZVJvdXRlciBtdXN0IGJlIGEgYm9vbGVhbi4nO1xuICAgIH1cbiAgICBpZiAocGFnZXMuZW5hYmxlTG9jYWxpemF0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHBhZ2VzLmVuYWJsZUxvY2FsaXphdGlvbiA9IFBhZ2VzT3B0aW9ucy5lbmFibGVMb2NhbGl6YXRpb24uZGVmYXVsdDtcbiAgICB9IGVsc2UgaWYgKCFpc0Jvb2xlYW4ocGFnZXMuZW5hYmxlTG9jYWxpemF0aW9uKSkge1xuICAgICAgdGhyb3cgJ1BhcnNlIFNlcnZlciBvcHRpb24gcGFnZXMuZW5hYmxlTG9jYWxpemF0aW9uIG11c3QgYmUgYSBib29sZWFuLic7XG4gICAgfVxuICAgIGlmIChwYWdlcy5sb2NhbGl6YXRpb25Kc29uUGF0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBwYWdlcy5sb2NhbGl6YXRpb25Kc29uUGF0aCA9IFBhZ2VzT3B0aW9ucy5sb2NhbGl6YXRpb25Kc29uUGF0aC5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAoIWlzU3RyaW5nKHBhZ2VzLmxvY2FsaXphdGlvbkpzb25QYXRoKSkge1xuICAgICAgdGhyb3cgJ1BhcnNlIFNlcnZlciBvcHRpb24gcGFnZXMubG9jYWxpemF0aW9uSnNvblBhdGggbXVzdCBiZSBhIHN0cmluZy4nO1xuICAgIH1cbiAgICBpZiAocGFnZXMubG9jYWxpemF0aW9uRmFsbGJhY2tMb2NhbGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcGFnZXMubG9jYWxpemF0aW9uRmFsbGJhY2tMb2NhbGUgPSBQYWdlc09wdGlvbnMubG9jYWxpemF0aW9uRmFsbGJhY2tMb2NhbGUuZGVmYXVsdDtcbiAgICB9IGVsc2UgaWYgKCFpc1N0cmluZyhwYWdlcy5sb2NhbGl6YXRpb25GYWxsYmFja0xvY2FsZSkpIHtcbiAgICAgIHRocm93ICdQYXJzZSBTZXJ2ZXIgb3B0aW9uIHBhZ2VzLmxvY2FsaXphdGlvbkZhbGxiYWNrTG9jYWxlIG11c3QgYmUgYSBzdHJpbmcuJztcbiAgICB9XG4gICAgaWYgKHBhZ2VzLnBsYWNlaG9sZGVycyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBwYWdlcy5wbGFjZWhvbGRlcnMgPSBQYWdlc09wdGlvbnMucGxhY2Vob2xkZXJzLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChwYWdlcy5wbGFjZWhvbGRlcnMpICE9PSAnW29iamVjdCBPYmplY3RdJyAmJlxuICAgICAgdHlwZW9mIHBhZ2VzLnBsYWNlaG9sZGVycyAhPT0gJ2Z1bmN0aW9uJ1xuICAgICkge1xuICAgICAgdGhyb3cgJ1BhcnNlIFNlcnZlciBvcHRpb24gcGFnZXMucGxhY2Vob2xkZXJzIG11c3QgYmUgYW4gb2JqZWN0IG9yIGEgZnVuY3Rpb24uJztcbiAgICB9XG4gICAgaWYgKHBhZ2VzLmZvcmNlUmVkaXJlY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcGFnZXMuZm9yY2VSZWRpcmVjdCA9IFBhZ2VzT3B0aW9ucy5mb3JjZVJlZGlyZWN0LmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICghaXNCb29sZWFuKHBhZ2VzLmZvcmNlUmVkaXJlY3QpKSB7XG4gICAgICB0aHJvdyAnUGFyc2UgU2VydmVyIG9wdGlvbiBwYWdlcy5mb3JjZVJlZGlyZWN0IG11c3QgYmUgYSBib29sZWFuLic7XG4gICAgfVxuICAgIGlmIChwYWdlcy5wYWdlc1BhdGggPT09IHVuZGVmaW5lZCkge1xuICAgICAgcGFnZXMucGFnZXNQYXRoID0gUGFnZXNPcHRpb25zLnBhZ2VzUGF0aC5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAoIWlzU3RyaW5nKHBhZ2VzLnBhZ2VzUGF0aCkpIHtcbiAgICAgIHRocm93ICdQYXJzZSBTZXJ2ZXIgb3B0aW9uIHBhZ2VzLnBhZ2VzUGF0aCBtdXN0IGJlIGEgc3RyaW5nLic7XG4gICAgfVxuICAgIGlmIChwYWdlcy5wYWdlc0VuZHBvaW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHBhZ2VzLnBhZ2VzRW5kcG9pbnQgPSBQYWdlc09wdGlvbnMucGFnZXNFbmRwb2ludC5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAoIWlzU3RyaW5nKHBhZ2VzLnBhZ2VzRW5kcG9pbnQpKSB7XG4gICAgICB0aHJvdyAnUGFyc2UgU2VydmVyIG9wdGlvbiBwYWdlcy5wYWdlc0VuZHBvaW50IG11c3QgYmUgYSBzdHJpbmcuJztcbiAgICB9XG4gICAgaWYgKHBhZ2VzLmN1c3RvbVVybHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcGFnZXMuY3VzdG9tVXJscyA9IFBhZ2VzT3B0aW9ucy5jdXN0b21VcmxzLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwocGFnZXMuY3VzdG9tVXJscykgIT09ICdbb2JqZWN0IE9iamVjdF0nKSB7XG4gICAgICB0aHJvdyAnUGFyc2UgU2VydmVyIG9wdGlvbiBwYWdlcy5jdXN0b21VcmxzIG11c3QgYmUgYW4gb2JqZWN0Lic7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlSWRlbXBvdGVuY3lPcHRpb25zKGlkZW1wb3RlbmN5T3B0aW9ucykge1xuICAgIGlmICghaWRlbXBvdGVuY3lPcHRpb25zKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChpZGVtcG90ZW5jeU9wdGlvbnMudHRsID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGlkZW1wb3RlbmN5T3B0aW9ucy50dGwgPSBJZGVtcG90ZW5jeU9wdGlvbnMudHRsLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICghaXNOYU4oaWRlbXBvdGVuY3lPcHRpb25zLnR0bCkgJiYgaWRlbXBvdGVuY3lPcHRpb25zLnR0bCA8PSAwKSB7XG4gICAgICB0aHJvdyAnaWRlbXBvdGVuY3kgVFRMIHZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAgc2Vjb25kcyc7XG4gICAgfSBlbHNlIGlmIChpc05hTihpZGVtcG90ZW5jeU9wdGlvbnMudHRsKSkge1xuICAgICAgdGhyb3cgJ2lkZW1wb3RlbmN5IFRUTCB2YWx1ZSBtdXN0IGJlIGEgbnVtYmVyJztcbiAgICB9XG4gICAgaWYgKCFpZGVtcG90ZW5jeU9wdGlvbnMucGF0aHMpIHtcbiAgICAgIGlkZW1wb3RlbmN5T3B0aW9ucy5wYXRocyA9IElkZW1wb3RlbmN5T3B0aW9ucy5wYXRocy5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAoIShpZGVtcG90ZW5jeU9wdGlvbnMucGF0aHMgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICAgIHRocm93ICdpZGVtcG90ZW5jeSBwYXRocyBtdXN0IGJlIG9mIGFuIGFycmF5IG9mIHN0cmluZ3MnO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZUFjY291bnRMb2Nrb3V0UG9saWN5KGFjY291bnRMb2Nrb3V0KSB7XG4gICAgaWYgKGFjY291bnRMb2Nrb3V0KSB7XG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiBhY2NvdW50TG9ja291dC5kdXJhdGlvbiAhPT0gJ251bWJlcicgfHxcbiAgICAgICAgYWNjb3VudExvY2tvdXQuZHVyYXRpb24gPD0gMCB8fFxuICAgICAgICBhY2NvdW50TG9ja291dC5kdXJhdGlvbiA+IDk5OTk5XG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgJ0FjY291bnQgbG9ja291dCBkdXJhdGlvbiBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIDAgYW5kIGxlc3MgdGhhbiAxMDAwMDAnO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgICFOdW1iZXIuaXNJbnRlZ2VyKGFjY291bnRMb2Nrb3V0LnRocmVzaG9sZCkgfHxcbiAgICAgICAgYWNjb3VudExvY2tvdXQudGhyZXNob2xkIDwgMSB8fFxuICAgICAgICBhY2NvdW50TG9ja291dC50aHJlc2hvbGQgPiA5OTlcbiAgICAgICkge1xuICAgICAgICB0aHJvdyAnQWNjb3VudCBsb2Nrb3V0IHRocmVzaG9sZCBzaG91bGQgYmUgYW4gaW50ZWdlciBncmVhdGVyIHRoYW4gMCBhbmQgbGVzcyB0aGFuIDEwMDAnO1xuICAgICAgfVxuXG4gICAgICBpZiAoYWNjb3VudExvY2tvdXQudW5sb2NrT25QYXNzd29yZFJlc2V0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYWNjb3VudExvY2tvdXQudW5sb2NrT25QYXNzd29yZFJlc2V0ID0gQWNjb3VudExvY2tvdXRPcHRpb25zLnVubG9ja09uUGFzc3dvcmRSZXNldC5kZWZhdWx0O1xuICAgICAgfSBlbHNlIGlmICghaXNCb29sZWFuKGFjY291bnRMb2Nrb3V0LnVubG9ja09uUGFzc3dvcmRSZXNldCkpIHtcbiAgICAgICAgdGhyb3cgJ1BhcnNlIFNlcnZlciBvcHRpb24gYWNjb3VudExvY2tvdXQudW5sb2NrT25QYXNzd29yZFJlc2V0IG11c3QgYmUgYSBib29sZWFuLic7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlUGFzc3dvcmRQb2xpY3kocGFzc3dvcmRQb2xpY3kpIHtcbiAgICBpZiAocGFzc3dvcmRQb2xpY3kpIHtcbiAgICAgIGlmIChcbiAgICAgICAgcGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRBZ2UgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAodHlwZW9mIHBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkQWdlICE9PSAnbnVtYmVyJyB8fCBwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEFnZSA8IDApXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgJ3Bhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkQWdlIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIHBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgKHR5cGVvZiBwYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbiAhPT0gJ251bWJlcicgfHxcbiAgICAgICAgICBwYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbiA8PSAwKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93ICdwYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbiBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJztcbiAgICAgIH1cblxuICAgICAgaWYgKHBhc3N3b3JkUG9saWN5LnZhbGlkYXRvclBhdHRlcm4pIHtcbiAgICAgICAgaWYgKHR5cGVvZiBwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIHBhc3N3b3JkUG9saWN5LnZhbGlkYXRvclBhdHRlcm4gPSBuZXcgUmVnRXhwKHBhc3N3b3JkUG9saWN5LnZhbGlkYXRvclBhdHRlcm4pO1xuICAgICAgICB9IGVsc2UgaWYgKCEocGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yUGF0dGVybiBpbnN0YW5jZW9mIFJlZ0V4cCkpIHtcbiAgICAgICAgICB0aHJvdyAncGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yUGF0dGVybiBtdXN0IGJlIGEgcmVnZXggc3RyaW5nIG9yIFJlZ0V4cCBvYmplY3QuJztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIHBhc3N3b3JkUG9saWN5LnZhbGlkYXRvckNhbGxiYWNrICYmXG4gICAgICAgIHR5cGVvZiBwYXNzd29yZFBvbGljeS52YWxpZGF0b3JDYWxsYmFjayAhPT0gJ2Z1bmN0aW9uJ1xuICAgICAgKSB7XG4gICAgICAgIHRocm93ICdwYXNzd29yZFBvbGljeS52YWxpZGF0b3JDYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24uJztcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBwYXNzd29yZFBvbGljeS5kb05vdEFsbG93VXNlcm5hbWUgJiZcbiAgICAgICAgdHlwZW9mIHBhc3N3b3JkUG9saWN5LmRvTm90QWxsb3dVc2VybmFtZSAhPT0gJ2Jvb2xlYW4nXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgJ3Bhc3N3b3JkUG9saWN5LmRvTm90QWxsb3dVc2VybmFtZSBtdXN0IGJlIGEgYm9vbGVhbiB2YWx1ZS4nO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIHBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeSAmJlxuICAgICAgICAoIU51bWJlci5pc0ludGVnZXIocGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRIaXN0b3J5KSB8fFxuICAgICAgICAgIHBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeSA8PSAwIHx8XG4gICAgICAgICAgcGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRIaXN0b3J5ID4gMjApXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgJ3Bhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeSBtdXN0IGJlIGFuIGludGVnZXIgcmFuZ2luZyAwIC0gMjAnO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIHBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5SZXVzZUlmVmFsaWQgJiZcbiAgICAgICAgdHlwZW9mIHBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5SZXVzZUlmVmFsaWQgIT09ICdib29sZWFuJ1xuICAgICAgKSB7XG4gICAgICAgIHRocm93ICdyZXNldFRva2VuUmV1c2VJZlZhbGlkIG11c3QgYmUgYSBib29sZWFuIHZhbHVlJztcbiAgICAgIH1cbiAgICAgIGlmIChwYXNzd29yZFBvbGljeS5yZXNldFRva2VuUmV1c2VJZlZhbGlkICYmICFwYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbikge1xuICAgICAgICB0aHJvdyAnWW91IGNhbm5vdCB1c2UgcmVzZXRUb2tlblJldXNlSWZWYWxpZCB3aXRob3V0IHJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uJztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGUgcGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yUGF0dGVybiBpcyBjb25maWd1cmVkIHRoZW4gc2V0dXAgYSBjYWxsYmFjayB0byBwcm9jZXNzIHRoZSBwYXR0ZXJuXG4gIHN0YXRpYyBzZXR1cFBhc3N3b3JkVmFsaWRhdG9yKHBhc3N3b3JkUG9saWN5KSB7XG4gICAgaWYgKHBhc3N3b3JkUG9saWN5ICYmIHBhc3N3b3JkUG9saWN5LnZhbGlkYXRvclBhdHRlcm4pIHtcbiAgICAgIHBhc3N3b3JkUG9saWN5LnBhdHRlcm5WYWxpZGF0b3IgPSB2YWx1ZSA9PiB7XG4gICAgICAgIHJldHVybiBwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuLnRlc3QodmFsdWUpO1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVFbWFpbENvbmZpZ3VyYXRpb24oe1xuICAgIGVtYWlsQWRhcHRlcixcbiAgICBhcHBOYW1lLFxuICAgIHB1YmxpY1NlcnZlclVSTCxcbiAgICBlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbixcbiAgICBlbWFpbFZlcmlmeVRva2VuUmV1c2VJZlZhbGlkLFxuICB9KSB7XG4gICAgaWYgKCFlbWFpbEFkYXB0ZXIpIHtcbiAgICAgIHRocm93ICdBbiBlbWFpbEFkYXB0ZXIgaXMgcmVxdWlyZWQgZm9yIGUtbWFpbCB2ZXJpZmljYXRpb24gYW5kIHBhc3N3b3JkIHJlc2V0cy4nO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGFwcE5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyAnQW4gYXBwIG5hbWUgaXMgcmVxdWlyZWQgZm9yIGUtbWFpbCB2ZXJpZmljYXRpb24gYW5kIHBhc3N3b3JkIHJlc2V0cy4nO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHB1YmxpY1NlcnZlclVSTCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93ICdBIHB1YmxpYyBzZXJ2ZXIgdXJsIGlzIHJlcXVpcmVkIGZvciBlLW1haWwgdmVyaWZpY2F0aW9uIGFuZCBwYXNzd29yZCByZXNldHMuJztcbiAgICB9XG4gICAgaWYgKGVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSB7XG4gICAgICBpZiAoaXNOYU4oZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24pKSB7XG4gICAgICAgIHRocm93ICdFbWFpbCB2ZXJpZnkgdG9rZW4gdmFsaWRpdHkgZHVyYXRpb24gbXVzdCBiZSBhIHZhbGlkIG51bWJlci4nO1xuICAgICAgfSBlbHNlIGlmIChlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbiA8PSAwKSB7XG4gICAgICAgIHRocm93ICdFbWFpbCB2ZXJpZnkgdG9rZW4gdmFsaWRpdHkgZHVyYXRpb24gbXVzdCBiZSBhIHZhbHVlIGdyZWF0ZXIgdGhhbiAwLic7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlbWFpbFZlcmlmeVRva2VuUmV1c2VJZlZhbGlkICYmIHR5cGVvZiBlbWFpbFZlcmlmeVRva2VuUmV1c2VJZlZhbGlkICE9PSAnYm9vbGVhbicpIHtcbiAgICAgIHRocm93ICdlbWFpbFZlcmlmeVRva2VuUmV1c2VJZlZhbGlkIG11c3QgYmUgYSBib29sZWFuIHZhbHVlJztcbiAgICB9XG4gICAgaWYgKGVtYWlsVmVyaWZ5VG9rZW5SZXVzZUlmVmFsaWQgJiYgIWVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSB7XG4gICAgICB0aHJvdyAnWW91IGNhbm5vdCB1c2UgZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZCB3aXRob3V0IGVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uJztcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVGaWxlVXBsb2FkT3B0aW9ucyhmaWxlVXBsb2FkKSB7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChmaWxlVXBsb2FkID09IG51bGwgfHwgdHlwZW9mIGZpbGVVcGxvYWQgIT09ICdvYmplY3QnIHx8IGZpbGVVcGxvYWQgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICB0aHJvdyAnZmlsZVVwbG9hZCBtdXN0IGJlIGFuIG9iamVjdCB2YWx1ZS4nO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChlIGluc3RhbmNlb2YgUmVmZXJlbmNlRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gICAgaWYgKGZpbGVVcGxvYWQuZW5hYmxlRm9yQW5vbnltb3VzVXNlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBmaWxlVXBsb2FkLmVuYWJsZUZvckFub255bW91c1VzZXIgPSBGaWxlVXBsb2FkT3B0aW9ucy5lbmFibGVGb3JBbm9ueW1vdXNVc2VyLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZmlsZVVwbG9hZC5lbmFibGVGb3JBbm9ueW1vdXNVc2VyICE9PSAnYm9vbGVhbicpIHtcbiAgICAgIHRocm93ICdmaWxlVXBsb2FkLmVuYWJsZUZvckFub255bW91c1VzZXIgbXVzdCBiZSBhIGJvb2xlYW4gdmFsdWUuJztcbiAgICB9XG4gICAgaWYgKGZpbGVVcGxvYWQuZW5hYmxlRm9yUHVibGljID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGZpbGVVcGxvYWQuZW5hYmxlRm9yUHVibGljID0gRmlsZVVwbG9hZE9wdGlvbnMuZW5hYmxlRm9yUHVibGljLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZmlsZVVwbG9hZC5lbmFibGVGb3JQdWJsaWMgIT09ICdib29sZWFuJykge1xuICAgICAgdGhyb3cgJ2ZpbGVVcGxvYWQuZW5hYmxlRm9yUHVibGljIG11c3QgYmUgYSBib29sZWFuIHZhbHVlLic7XG4gICAgfVxuICAgIGlmIChmaWxlVXBsb2FkLmVuYWJsZUZvckF1dGhlbnRpY2F0ZWRVc2VyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGZpbGVVcGxvYWQuZW5hYmxlRm9yQXV0aGVudGljYXRlZFVzZXIgPSBGaWxlVXBsb2FkT3B0aW9ucy5lbmFibGVGb3JBdXRoZW50aWNhdGVkVXNlci5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGZpbGVVcGxvYWQuZW5hYmxlRm9yQXV0aGVudGljYXRlZFVzZXIgIT09ICdib29sZWFuJykge1xuICAgICAgdGhyb3cgJ2ZpbGVVcGxvYWQuZW5hYmxlRm9yQXV0aGVudGljYXRlZFVzZXIgbXVzdCBiZSBhIGJvb2xlYW4gdmFsdWUuJztcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVNYXN0ZXJLZXlJcHMobWFzdGVyS2V5SXBzKSB7XG4gICAgZm9yIChjb25zdCBpcCBvZiBtYXN0ZXJLZXlJcHMpIHtcbiAgICAgIGlmICghbmV0LmlzSVAoaXApKSB7XG4gICAgICAgIHRocm93IGBJbnZhbGlkIGlwIGluIG1hc3RlcktleUlwczogJHtpcH1gO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGdldCBtb3VudCgpIHtcbiAgICB2YXIgbW91bnQgPSB0aGlzLl9tb3VudDtcbiAgICBpZiAodGhpcy5wdWJsaWNTZXJ2ZXJVUkwpIHtcbiAgICAgIG1vdW50ID0gdGhpcy5wdWJsaWNTZXJ2ZXJVUkw7XG4gICAgfVxuICAgIHJldHVybiBtb3VudDtcbiAgfVxuXG4gIHNldCBtb3VudChuZXdWYWx1ZSkge1xuICAgIHRoaXMuX21vdW50ID0gbmV3VmFsdWU7XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVTZXNzaW9uQ29uZmlndXJhdGlvbihzZXNzaW9uTGVuZ3RoLCBleHBpcmVJbmFjdGl2ZVNlc3Npb25zKSB7XG4gICAgaWYgKGV4cGlyZUluYWN0aXZlU2Vzc2lvbnMpIHtcbiAgICAgIGlmIChpc05hTihzZXNzaW9uTGVuZ3RoKSkge1xuICAgICAgICB0aHJvdyAnU2Vzc2lvbiBsZW5ndGggbXVzdCBiZSBhIHZhbGlkIG51bWJlci4nO1xuICAgICAgfSBlbHNlIGlmIChzZXNzaW9uTGVuZ3RoIDw9IDApIHtcbiAgICAgICAgdGhyb3cgJ1Nlc3Npb24gbGVuZ3RoIG11c3QgYmUgYSB2YWx1ZSBncmVhdGVyIHRoYW4gMC4nO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZU1heExpbWl0KG1heExpbWl0KSB7XG4gICAgaWYgKG1heExpbWl0IDw9IDApIHtcbiAgICAgIHRocm93ICdNYXggbGltaXQgbXVzdCBiZSBhIHZhbHVlIGdyZWF0ZXIgdGhhbiAwLic7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlQWxsb3dIZWFkZXJzKGFsbG93SGVhZGVycykge1xuICAgIGlmICghW251bGwsIHVuZGVmaW5lZF0uaW5jbHVkZXMoYWxsb3dIZWFkZXJzKSkge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYWxsb3dIZWFkZXJzKSkge1xuICAgICAgICBhbGxvd0hlYWRlcnMuZm9yRWFjaChoZWFkZXIgPT4ge1xuICAgICAgICAgIGlmICh0eXBlb2YgaGVhZGVyICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGhyb3cgJ0FsbG93IGhlYWRlcnMgbXVzdCBvbmx5IGNvbnRhaW4gc3RyaW5ncyc7XG4gICAgICAgICAgfSBlbHNlIGlmICghaGVhZGVyLnRyaW0oKS5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93ICdBbGxvdyBoZWFkZXJzIG11c3Qgbm90IGNvbnRhaW4gZW1wdHkgc3RyaW5ncyc7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93ICdBbGxvdyBoZWFkZXJzIG11c3QgYmUgYW4gYXJyYXknO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbkV4cGlyZXNBdCgpIHtcbiAgICBpZiAoIXRoaXMudmVyaWZ5VXNlckVtYWlscyB8fCAhdGhpcy5lbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbikge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgdmFyIG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgcmV0dXJuIG5ldyBEYXRlKG5vdy5nZXRUaW1lKCkgKyB0aGlzLmVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uICogMTAwMCk7XG4gIH1cblxuICBnZW5lcmF0ZVBhc3N3b3JkUmVzZXRUb2tlbkV4cGlyZXNBdCgpIHtcbiAgICBpZiAoIXRoaXMucGFzc3dvcmRQb2xpY3kgfHwgIXRoaXMucGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24pIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgcmV0dXJuIG5ldyBEYXRlKG5vdy5nZXRUaW1lKCkgKyB0aGlzLnBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uICogMTAwMCk7XG4gIH1cblxuICBnZW5lcmF0ZVNlc3Npb25FeHBpcmVzQXQoKSB7XG4gICAgaWYgKCF0aGlzLmV4cGlyZUluYWN0aXZlU2Vzc2lvbnMpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHZhciBub3cgPSBuZXcgRGF0ZSgpO1xuICAgIHJldHVybiBuZXcgRGF0ZShub3cuZ2V0VGltZSgpICsgdGhpcy5zZXNzaW9uTGVuZ3RoICogMTAwMCk7XG4gIH1cblxuICBnZXQgaW52YWxpZExpbmtVUkwoKSB7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tUGFnZXMuaW52YWxpZExpbmsgfHwgYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9L2FwcHMvaW52YWxpZF9saW5rLmh0bWxgO1xuICB9XG5cbiAgZ2V0IGludmFsaWRWZXJpZmljYXRpb25MaW5rVVJMKCkge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmN1c3RvbVBhZ2VzLmludmFsaWRWZXJpZmljYXRpb25MaW5rIHx8XG4gICAgICBgJHt0aGlzLnB1YmxpY1NlcnZlclVSTH0vYXBwcy9pbnZhbGlkX3ZlcmlmaWNhdGlvbl9saW5rLmh0bWxgXG4gICAgKTtcbiAgfVxuXG4gIGdldCBsaW5rU2VuZFN1Y2Nlc3NVUkwoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuY3VzdG9tUGFnZXMubGlua1NlbmRTdWNjZXNzIHx8IGAke3RoaXMucHVibGljU2VydmVyVVJMfS9hcHBzL2xpbmtfc2VuZF9zdWNjZXNzLmh0bWxgXG4gICAgKTtcbiAgfVxuXG4gIGdldCBsaW5rU2VuZEZhaWxVUkwoKSB7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tUGFnZXMubGlua1NlbmRGYWlsIHx8IGAke3RoaXMucHVibGljU2VydmVyVVJMfS9hcHBzL2xpbmtfc2VuZF9mYWlsLmh0bWxgO1xuICB9XG5cbiAgZ2V0IHZlcmlmeUVtYWlsU3VjY2Vzc1VSTCgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5jdXN0b21QYWdlcy52ZXJpZnlFbWFpbFN1Y2Nlc3MgfHxcbiAgICAgIGAke3RoaXMucHVibGljU2VydmVyVVJMfS9hcHBzL3ZlcmlmeV9lbWFpbF9zdWNjZXNzLmh0bWxgXG4gICAgKTtcbiAgfVxuXG4gIGdldCBjaG9vc2VQYXNzd29yZFVSTCgpIHtcbiAgICByZXR1cm4gdGhpcy5jdXN0b21QYWdlcy5jaG9vc2VQYXNzd29yZCB8fCBgJHt0aGlzLnB1YmxpY1NlcnZlclVSTH0vYXBwcy9jaG9vc2VfcGFzc3dvcmRgO1xuICB9XG5cbiAgZ2V0IHJlcXVlc3RSZXNldFBhc3N3b3JkVVJMKCkge1xuICAgIHJldHVybiBgJHt0aGlzLnB1YmxpY1NlcnZlclVSTH0vYXBwcy8ke3RoaXMuYXBwbGljYXRpb25JZH0vcmVxdWVzdF9wYXNzd29yZF9yZXNldGA7XG4gIH1cblxuICBnZXQgcGFzc3dvcmRSZXNldFN1Y2Nlc3NVUkwoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuY3VzdG9tUGFnZXMucGFzc3dvcmRSZXNldFN1Y2Nlc3MgfHxcbiAgICAgIGAke3RoaXMucHVibGljU2VydmVyVVJMfS9hcHBzL3Bhc3N3b3JkX3Jlc2V0X3N1Y2Nlc3MuaHRtbGBcbiAgICApO1xuICB9XG5cbiAgZ2V0IHBhcnNlRnJhbWVVUkwoKSB7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tUGFnZXMucGFyc2VGcmFtZVVSTDtcbiAgfVxuXG4gIGdldCB2ZXJpZnlFbWFpbFVSTCgpIHtcbiAgICByZXR1cm4gYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9L2FwcHMvJHt0aGlzLmFwcGxpY2F0aW9uSWR9L3ZlcmlmeV9lbWFpbGA7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ29uZmlnO1xubW9kdWxlLmV4cG9ydHMgPSBDb25maWc7XG4iXX0= \ No newline at end of file diff --git a/lib/Controllers/AdaptableController.js b/lib/Controllers/AdaptableController.js new file mode 100644 index 0000000000..fca1d5c819 --- /dev/null +++ b/lib/Controllers/AdaptableController.js @@ -0,0 +1,88 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.AdaptableController = void 0; + +var _Config = _interopRequireDefault(require("../Config")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/* +AdaptableController.js + +AdaptableController is the base class for all controllers +that support adapter, +The super class takes care of creating the right instance for the adapter +based on the parameters passed + + */ +// _adapter is private, use Symbol +var _adapter = Symbol(); + +class AdaptableController { + constructor(adapter, appId, options) { + this.options = options; + this.appId = appId; + this.adapter = adapter; + } + + set adapter(adapter) { + this.validateAdapter(adapter); + this[_adapter] = adapter; + } + + get adapter() { + return this[_adapter]; + } + + get config() { + return _Config.default.get(this.appId); + } + + expectedAdapterType() { + throw new Error('Subclasses should implement expectedAdapterType()'); + } + + validateAdapter(adapter) { + AdaptableController.validateAdapter(adapter, this); + } + + static validateAdapter(adapter, self, ExpectedType) { + if (!adapter) { + throw new Error(this.constructor.name + ' requires an adapter'); + } + + const Type = ExpectedType || self.expectedAdapterType(); // Allow skipping for testing + + if (!Type) { + return; + } // Makes sure the prototype matches + + + const mismatches = Object.getOwnPropertyNames(Type.prototype).reduce((obj, key) => { + const adapterType = typeof adapter[key]; + const expectedType = typeof Type.prototype[key]; + + if (adapterType !== expectedType) { + obj[key] = { + expected: expectedType, + actual: adapterType + }; + } + + return obj; + }, {}); + + if (Object.keys(mismatches).length > 0) { + throw new Error("Adapter prototype don't match expected prototype", adapter, mismatches); + } + } + +} + +exports.AdaptableController = AdaptableController; +var _default = AdaptableController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9BZGFwdGFibGVDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIl9hZGFwdGVyIiwiU3ltYm9sIiwiQWRhcHRhYmxlQ29udHJvbGxlciIsImNvbnN0cnVjdG9yIiwiYWRhcHRlciIsImFwcElkIiwib3B0aW9ucyIsInZhbGlkYXRlQWRhcHRlciIsImNvbmZpZyIsIkNvbmZpZyIsImdldCIsImV4cGVjdGVkQWRhcHRlclR5cGUiLCJFcnJvciIsInNlbGYiLCJFeHBlY3RlZFR5cGUiLCJuYW1lIiwiVHlwZSIsIm1pc21hdGNoZXMiLCJPYmplY3QiLCJnZXRPd25Qcm9wZXJ0eU5hbWVzIiwicHJvdG90eXBlIiwicmVkdWNlIiwib2JqIiwia2V5IiwiYWRhcHRlclR5cGUiLCJleHBlY3RlZFR5cGUiLCJleHBlY3RlZCIsImFjdHVhbCIsImtleXMiLCJsZW5ndGgiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFZQTs7OztBQVpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0EsSUFBSUEsUUFBUSxHQUFHQyxNQUFNLEVBQXJCOztBQUdPLE1BQU1DLG1CQUFOLENBQTBCO0FBQy9CQyxFQUFBQSxXQUFXLENBQUNDLE9BQUQsRUFBVUMsS0FBVixFQUFpQkMsT0FBakIsRUFBMEI7QUFDbkMsU0FBS0EsT0FBTCxHQUFlQSxPQUFmO0FBQ0EsU0FBS0QsS0FBTCxHQUFhQSxLQUFiO0FBQ0EsU0FBS0QsT0FBTCxHQUFlQSxPQUFmO0FBQ0Q7O0FBRUQsTUFBSUEsT0FBSixDQUFZQSxPQUFaLEVBQXFCO0FBQ25CLFNBQUtHLGVBQUwsQ0FBcUJILE9BQXJCO0FBQ0EsU0FBS0osUUFBTCxJQUFpQkksT0FBakI7QUFDRDs7QUFFRCxNQUFJQSxPQUFKLEdBQWM7QUFDWixXQUFPLEtBQUtKLFFBQUwsQ0FBUDtBQUNEOztBQUVELE1BQUlRLE1BQUosR0FBYTtBQUNYLFdBQU9DLGdCQUFPQyxHQUFQLENBQVcsS0FBS0wsS0FBaEIsQ0FBUDtBQUNEOztBQUVETSxFQUFBQSxtQkFBbUIsR0FBRztBQUNwQixVQUFNLElBQUlDLEtBQUosQ0FBVSxtREFBVixDQUFOO0FBQ0Q7O0FBRURMLEVBQUFBLGVBQWUsQ0FBQ0gsT0FBRCxFQUFVO0FBQ3ZCRixJQUFBQSxtQkFBbUIsQ0FBQ0ssZUFBcEIsQ0FBb0NILE9BQXBDLEVBQTZDLElBQTdDO0FBQ0Q7O0FBRUQsU0FBT0csZUFBUCxDQUF1QkgsT0FBdkIsRUFBZ0NTLElBQWhDLEVBQXNDQyxZQUF0QyxFQUFvRDtBQUNsRCxRQUFJLENBQUNWLE9BQUwsRUFBYztBQUNaLFlBQU0sSUFBSVEsS0FBSixDQUFVLEtBQUtULFdBQUwsQ0FBaUJZLElBQWpCLEdBQXdCLHNCQUFsQyxDQUFOO0FBQ0Q7O0FBRUQsVUFBTUMsSUFBSSxHQUFHRixZQUFZLElBQUlELElBQUksQ0FBQ0YsbUJBQUwsRUFBN0IsQ0FMa0QsQ0FNbEQ7O0FBQ0EsUUFBSSxDQUFDSyxJQUFMLEVBQVc7QUFDVDtBQUNELEtBVGlELENBV2xEOzs7QUFDQSxVQUFNQyxVQUFVLEdBQUdDLE1BQU0sQ0FBQ0MsbUJBQVAsQ0FBMkJILElBQUksQ0FBQ0ksU0FBaEMsRUFBMkNDLE1BQTNDLENBQWtELENBQUNDLEdBQUQsRUFBTUMsR0FBTixLQUFjO0FBQ2pGLFlBQU1DLFdBQVcsR0FBRyxPQUFPcEIsT0FBTyxDQUFDbUIsR0FBRCxDQUFsQztBQUNBLFlBQU1FLFlBQVksR0FBRyxPQUFPVCxJQUFJLENBQUNJLFNBQUwsQ0FBZUcsR0FBZixDQUE1Qjs7QUFDQSxVQUFJQyxXQUFXLEtBQUtDLFlBQXBCLEVBQWtDO0FBQ2hDSCxRQUFBQSxHQUFHLENBQUNDLEdBQUQsQ0FBSCxHQUFXO0FBQ1RHLFVBQUFBLFFBQVEsRUFBRUQsWUFERDtBQUVURSxVQUFBQSxNQUFNLEVBQUVIO0FBRkMsU0FBWDtBQUlEOztBQUNELGFBQU9GLEdBQVA7QUFDRCxLQVZrQixFQVVoQixFQVZnQixDQUFuQjs7QUFZQSxRQUFJSixNQUFNLENBQUNVLElBQVAsQ0FBWVgsVUFBWixFQUF3QlksTUFBeEIsR0FBaUMsQ0FBckMsRUFBd0M7QUFDdEMsWUFBTSxJQUFJakIsS0FBSixDQUFVLGtEQUFWLEVBQThEUixPQUE5RCxFQUF1RWEsVUFBdkUsQ0FBTjtBQUNEO0FBQ0Y7O0FBdkQ4Qjs7O2VBMERsQmYsbUIiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuQWRhcHRhYmxlQ29udHJvbGxlci5qc1xuXG5BZGFwdGFibGVDb250cm9sbGVyIGlzIHRoZSBiYXNlIGNsYXNzIGZvciBhbGwgY29udHJvbGxlcnNcbnRoYXQgc3VwcG9ydCBhZGFwdGVyLFxuVGhlIHN1cGVyIGNsYXNzIHRha2VzIGNhcmUgb2YgY3JlYXRpbmcgdGhlIHJpZ2h0IGluc3RhbmNlIGZvciB0aGUgYWRhcHRlclxuYmFzZWQgb24gdGhlIHBhcmFtZXRlcnMgcGFzc2VkXG5cbiAqL1xuXG4vLyBfYWRhcHRlciBpcyBwcml2YXRlLCB1c2UgU3ltYm9sXG52YXIgX2FkYXB0ZXIgPSBTeW1ib2woKTtcbmltcG9ydCBDb25maWcgZnJvbSAnLi4vQ29uZmlnJztcblxuZXhwb3J0IGNsYXNzIEFkYXB0YWJsZUNvbnRyb2xsZXIge1xuICBjb25zdHJ1Y3RvcihhZGFwdGVyLCBhcHBJZCwgb3B0aW9ucykge1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgdGhpcy5hcHBJZCA9IGFwcElkO1xuICAgIHRoaXMuYWRhcHRlciA9IGFkYXB0ZXI7XG4gIH1cblxuICBzZXQgYWRhcHRlcihhZGFwdGVyKSB7XG4gICAgdGhpcy52YWxpZGF0ZUFkYXB0ZXIoYWRhcHRlcik7XG4gICAgdGhpc1tfYWRhcHRlcl0gPSBhZGFwdGVyO1xuICB9XG5cbiAgZ2V0IGFkYXB0ZXIoKSB7XG4gICAgcmV0dXJuIHRoaXNbX2FkYXB0ZXJdO1xuICB9XG5cbiAgZ2V0IGNvbmZpZygpIHtcbiAgICByZXR1cm4gQ29uZmlnLmdldCh0aGlzLmFwcElkKTtcbiAgfVxuXG4gIGV4cGVjdGVkQWRhcHRlclR5cGUoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTdWJjbGFzc2VzIHNob3VsZCBpbXBsZW1lbnQgZXhwZWN0ZWRBZGFwdGVyVHlwZSgpJyk7XG4gIH1cblxuICB2YWxpZGF0ZUFkYXB0ZXIoYWRhcHRlcikge1xuICAgIEFkYXB0YWJsZUNvbnRyb2xsZXIudmFsaWRhdGVBZGFwdGVyKGFkYXB0ZXIsIHRoaXMpO1xuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlQWRhcHRlcihhZGFwdGVyLCBzZWxmLCBFeHBlY3RlZFR5cGUpIHtcbiAgICBpZiAoIWFkYXB0ZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0aGlzLmNvbnN0cnVjdG9yLm5hbWUgKyAnIHJlcXVpcmVzIGFuIGFkYXB0ZXInKTtcbiAgICB9XG5cbiAgICBjb25zdCBUeXBlID0gRXhwZWN0ZWRUeXBlIHx8IHNlbGYuZXhwZWN0ZWRBZGFwdGVyVHlwZSgpO1xuICAgIC8vIEFsbG93IHNraXBwaW5nIGZvciB0ZXN0aW5nXG4gICAgaWYgKCFUeXBlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gTWFrZXMgc3VyZSB0aGUgcHJvdG90eXBlIG1hdGNoZXNcbiAgICBjb25zdCBtaXNtYXRjaGVzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoVHlwZS5wcm90b3R5cGUpLnJlZHVjZSgob2JqLCBrZXkpID0+IHtcbiAgICAgIGNvbnN0IGFkYXB0ZXJUeXBlID0gdHlwZW9mIGFkYXB0ZXJba2V5XTtcbiAgICAgIGNvbnN0IGV4cGVjdGVkVHlwZSA9IHR5cGVvZiBUeXBlLnByb3RvdHlwZVtrZXldO1xuICAgICAgaWYgKGFkYXB0ZXJUeXBlICE9PSBleHBlY3RlZFR5cGUpIHtcbiAgICAgICAgb2JqW2tleV0gPSB7XG4gICAgICAgICAgZXhwZWN0ZWQ6IGV4cGVjdGVkVHlwZSxcbiAgICAgICAgICBhY3R1YWw6IGFkYXB0ZXJUeXBlLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9iajtcbiAgICB9LCB7fSk7XG5cbiAgICBpZiAoT2JqZWN0LmtleXMobWlzbWF0Y2hlcykubGVuZ3RoID4gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQWRhcHRlciBwcm90b3R5cGUgZG9uJ3QgbWF0Y2ggZXhwZWN0ZWQgcHJvdG90eXBlXCIsIGFkYXB0ZXIsIG1pc21hdGNoZXMpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBBZGFwdGFibGVDb250cm9sbGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/AnalyticsController.js b/lib/Controllers/AnalyticsController.js new file mode 100644 index 0000000000..1416558aca --- /dev/null +++ b/lib/Controllers/AnalyticsController.js @@ -0,0 +1,52 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.AnalyticsController = void 0; + +var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); + +var _AnalyticsAdapter = require("../Adapters/Analytics/AnalyticsAdapter"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class AnalyticsController extends _AdaptableController.default { + appOpened(req) { + return Promise.resolve().then(() => { + return this.adapter.appOpened(req.body, req); + }).then(response => { + return { + response: response || {} + }; + }).catch(() => { + return { + response: {} + }; + }); + } + + trackEvent(req) { + return Promise.resolve().then(() => { + return this.adapter.trackEvent(req.params.eventName, req.body, req); + }).then(response => { + return { + response: response || {} + }; + }).catch(() => { + return { + response: {} + }; + }); + } + + expectedAdapterType() { + return _AnalyticsAdapter.AnalyticsAdapter; + } + +} + +exports.AnalyticsController = AnalyticsController; +var _default = AnalyticsController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9BbmFseXRpY3NDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIkFuYWx5dGljc0NvbnRyb2xsZXIiLCJBZGFwdGFibGVDb250cm9sbGVyIiwiYXBwT3BlbmVkIiwicmVxIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ0aGVuIiwiYWRhcHRlciIsImJvZHkiLCJyZXNwb25zZSIsImNhdGNoIiwidHJhY2tFdmVudCIsInBhcmFtcyIsImV2ZW50TmFtZSIsImV4cGVjdGVkQWRhcHRlclR5cGUiLCJBbmFseXRpY3NBZGFwdGVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7Ozs7QUFFTyxNQUFNQSxtQkFBTixTQUFrQ0MsNEJBQWxDLENBQXNEO0FBQzNEQyxFQUFBQSxTQUFTLENBQUNDLEdBQUQsRUFBTTtBQUNiLFdBQU9DLE9BQU8sQ0FBQ0MsT0FBUixHQUNKQyxJQURJLENBQ0MsTUFBTTtBQUNWLGFBQU8sS0FBS0MsT0FBTCxDQUFhTCxTQUFiLENBQXVCQyxHQUFHLENBQUNLLElBQTNCLEVBQWlDTCxHQUFqQyxDQUFQO0FBQ0QsS0FISSxFQUlKRyxJQUpJLENBSUNHLFFBQVEsSUFBSTtBQUNoQixhQUFPO0FBQUVBLFFBQUFBLFFBQVEsRUFBRUEsUUFBUSxJQUFJO0FBQXhCLE9BQVA7QUFDRCxLQU5JLEVBT0pDLEtBUEksQ0FPRSxNQUFNO0FBQ1gsYUFBTztBQUFFRCxRQUFBQSxRQUFRLEVBQUU7QUFBWixPQUFQO0FBQ0QsS0FUSSxDQUFQO0FBVUQ7O0FBRURFLEVBQUFBLFVBQVUsQ0FBQ1IsR0FBRCxFQUFNO0FBQ2QsV0FBT0MsT0FBTyxDQUFDQyxPQUFSLEdBQ0pDLElBREksQ0FDQyxNQUFNO0FBQ1YsYUFBTyxLQUFLQyxPQUFMLENBQWFJLFVBQWIsQ0FBd0JSLEdBQUcsQ0FBQ1MsTUFBSixDQUFXQyxTQUFuQyxFQUE4Q1YsR0FBRyxDQUFDSyxJQUFsRCxFQUF3REwsR0FBeEQsQ0FBUDtBQUNELEtBSEksRUFJSkcsSUFKSSxDQUlDRyxRQUFRLElBQUk7QUFDaEIsYUFBTztBQUFFQSxRQUFBQSxRQUFRLEVBQUVBLFFBQVEsSUFBSTtBQUF4QixPQUFQO0FBQ0QsS0FOSSxFQU9KQyxLQVBJLENBT0UsTUFBTTtBQUNYLGFBQU87QUFBRUQsUUFBQUEsUUFBUSxFQUFFO0FBQVosT0FBUDtBQUNELEtBVEksQ0FBUDtBQVVEOztBQUVESyxFQUFBQSxtQkFBbUIsR0FBRztBQUNwQixXQUFPQyxrQ0FBUDtBQUNEOztBQTdCMEQ7OztlQWdDOUNmLG1CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFkYXB0YWJsZUNvbnRyb2xsZXIgZnJvbSAnLi9BZGFwdGFibGVDb250cm9sbGVyJztcbmltcG9ydCB7IEFuYWx5dGljc0FkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9BbmFseXRpY3MvQW5hbHl0aWNzQWRhcHRlcic7XG5cbmV4cG9ydCBjbGFzcyBBbmFseXRpY3NDb250cm9sbGVyIGV4dGVuZHMgQWRhcHRhYmxlQ29udHJvbGxlciB7XG4gIGFwcE9wZW5lZChyZXEpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci5hcHBPcGVuZWQocmVxLmJvZHksIHJlcSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICByZXR1cm4geyByZXNwb25zZTogcmVzcG9uc2UgfHwge30gfTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKCkgPT4ge1xuICAgICAgICByZXR1cm4geyByZXNwb25zZToge30gfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgdHJhY2tFdmVudChyZXEpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci50cmFja0V2ZW50KHJlcS5wYXJhbXMuZXZlbnROYW1lLCByZXEuYm9keSwgcmVxKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiByZXNwb25zZSB8fCB7fSB9O1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7fSB9O1xuICAgICAgfSk7XG4gIH1cblxuICBleHBlY3RlZEFkYXB0ZXJUeXBlKCkge1xuICAgIHJldHVybiBBbmFseXRpY3NBZGFwdGVyO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEFuYWx5dGljc0NvbnRyb2xsZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Controllers/CacheController.js b/lib/Controllers/CacheController.js new file mode 100644 index 0000000000..1369350df4 --- /dev/null +++ b/lib/Controllers/CacheController.js @@ -0,0 +1,92 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.CacheController = exports.SubCache = void 0; + +var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); + +var _CacheAdapter = _interopRequireDefault(require("../Adapters/Cache/CacheAdapter")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const KEY_SEPARATOR_CHAR = ':'; + +function joinKeys(...keys) { + return keys.join(KEY_SEPARATOR_CHAR); +} +/** + * Prefix all calls to the cache via a prefix string, useful when grouping Cache by object type. + * + * eg "Role" or "Session" + */ + + +class SubCache { + constructor(prefix, cacheController, ttl) { + this.prefix = prefix; + this.cache = cacheController; + this.ttl = ttl; + } + + get(key) { + const cacheKey = joinKeys(this.prefix, key); + return this.cache.get(cacheKey); + } + + put(key, value, ttl) { + const cacheKey = joinKeys(this.prefix, key); + return this.cache.put(cacheKey, value, ttl); + } + + del(key) { + const cacheKey = joinKeys(this.prefix, key); + return this.cache.del(cacheKey); + } + + clear() { + return this.cache.clear(); + } + +} + +exports.SubCache = SubCache; + +class CacheController extends _AdaptableController.default { + constructor(adapter, appId, options = {}) { + super(adapter, appId, options); + this.role = new SubCache('role', this); + this.user = new SubCache('user', this); + this.graphQL = new SubCache('graphQL', this); + } + + get(key) { + const cacheKey = joinKeys(this.appId, key); + return this.adapter.get(cacheKey).then(null, () => Promise.resolve(null)); + } + + put(key, value, ttl) { + const cacheKey = joinKeys(this.appId, key); + return this.adapter.put(cacheKey, value, ttl); + } + + del(key) { + const cacheKey = joinKeys(this.appId, key); + return this.adapter.del(cacheKey); + } + + clear() { + return this.adapter.clear(); + } + + expectedAdapterType() { + return _CacheAdapter.default; + } + +} + +exports.CacheController = CacheController; +var _default = CacheController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9DYWNoZUNvbnRyb2xsZXIuanMiXSwibmFtZXMiOlsiS0VZX1NFUEFSQVRPUl9DSEFSIiwiam9pbktleXMiLCJrZXlzIiwiam9pbiIsIlN1YkNhY2hlIiwiY29uc3RydWN0b3IiLCJwcmVmaXgiLCJjYWNoZUNvbnRyb2xsZXIiLCJ0dGwiLCJjYWNoZSIsImdldCIsImtleSIsImNhY2hlS2V5IiwicHV0IiwidmFsdWUiLCJkZWwiLCJjbGVhciIsIkNhY2hlQ29udHJvbGxlciIsIkFkYXB0YWJsZUNvbnRyb2xsZXIiLCJhZGFwdGVyIiwiYXBwSWQiLCJvcHRpb25zIiwicm9sZSIsInVzZXIiLCJncmFwaFFMIiwidGhlbiIsIlByb21pc2UiLCJyZXNvbHZlIiwiZXhwZWN0ZWRBZGFwdGVyVHlwZSIsIkNhY2hlQWRhcHRlciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7O0FBRUEsTUFBTUEsa0JBQWtCLEdBQUcsR0FBM0I7O0FBRUEsU0FBU0MsUUFBVCxDQUFrQixHQUFHQyxJQUFyQixFQUEyQjtBQUN6QixTQUFPQSxJQUFJLENBQUNDLElBQUwsQ0FBVUgsa0JBQVYsQ0FBUDtBQUNEO0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ08sTUFBTUksUUFBTixDQUFlO0FBQ3BCQyxFQUFBQSxXQUFXLENBQUNDLE1BQUQsRUFBU0MsZUFBVCxFQUEwQkMsR0FBMUIsRUFBK0I7QUFDeEMsU0FBS0YsTUFBTCxHQUFjQSxNQUFkO0FBQ0EsU0FBS0csS0FBTCxHQUFhRixlQUFiO0FBQ0EsU0FBS0MsR0FBTCxHQUFXQSxHQUFYO0FBQ0Q7O0FBRURFLEVBQUFBLEdBQUcsQ0FBQ0MsR0FBRCxFQUFNO0FBQ1AsVUFBTUMsUUFBUSxHQUFHWCxRQUFRLENBQUMsS0FBS0ssTUFBTixFQUFjSyxHQUFkLENBQXpCO0FBQ0EsV0FBTyxLQUFLRixLQUFMLENBQVdDLEdBQVgsQ0FBZUUsUUFBZixDQUFQO0FBQ0Q7O0FBRURDLEVBQUFBLEdBQUcsQ0FBQ0YsR0FBRCxFQUFNRyxLQUFOLEVBQWFOLEdBQWIsRUFBa0I7QUFDbkIsVUFBTUksUUFBUSxHQUFHWCxRQUFRLENBQUMsS0FBS0ssTUFBTixFQUFjSyxHQUFkLENBQXpCO0FBQ0EsV0FBTyxLQUFLRixLQUFMLENBQVdJLEdBQVgsQ0FBZUQsUUFBZixFQUF5QkUsS0FBekIsRUFBZ0NOLEdBQWhDLENBQVA7QUFDRDs7QUFFRE8sRUFBQUEsR0FBRyxDQUFDSixHQUFELEVBQU07QUFDUCxVQUFNQyxRQUFRLEdBQUdYLFFBQVEsQ0FBQyxLQUFLSyxNQUFOLEVBQWNLLEdBQWQsQ0FBekI7QUFDQSxXQUFPLEtBQUtGLEtBQUwsQ0FBV00sR0FBWCxDQUFlSCxRQUFmLENBQVA7QUFDRDs7QUFFREksRUFBQUEsS0FBSyxHQUFHO0FBQ04sV0FBTyxLQUFLUCxLQUFMLENBQVdPLEtBQVgsRUFBUDtBQUNEOztBQXhCbUI7Ozs7QUEyQmYsTUFBTUMsZUFBTixTQUE4QkMsNEJBQTlCLENBQWtEO0FBQ3ZEYixFQUFBQSxXQUFXLENBQUNjLE9BQUQsRUFBVUMsS0FBVixFQUFpQkMsT0FBTyxHQUFHLEVBQTNCLEVBQStCO0FBQ3hDLFVBQU1GLE9BQU4sRUFBZUMsS0FBZixFQUFzQkMsT0FBdEI7QUFFQSxTQUFLQyxJQUFMLEdBQVksSUFBSWxCLFFBQUosQ0FBYSxNQUFiLEVBQXFCLElBQXJCLENBQVo7QUFDQSxTQUFLbUIsSUFBTCxHQUFZLElBQUluQixRQUFKLENBQWEsTUFBYixFQUFxQixJQUFyQixDQUFaO0FBQ0EsU0FBS29CLE9BQUwsR0FBZSxJQUFJcEIsUUFBSixDQUFhLFNBQWIsRUFBd0IsSUFBeEIsQ0FBZjtBQUNEOztBQUVETSxFQUFBQSxHQUFHLENBQUNDLEdBQUQsRUFBTTtBQUNQLFVBQU1DLFFBQVEsR0FBR1gsUUFBUSxDQUFDLEtBQUttQixLQUFOLEVBQWFULEdBQWIsQ0FBekI7QUFDQSxXQUFPLEtBQUtRLE9BQUwsQ0FBYVQsR0FBYixDQUFpQkUsUUFBakIsRUFBMkJhLElBQTNCLENBQWdDLElBQWhDLEVBQXNDLE1BQU1DLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQixJQUFoQixDQUE1QyxDQUFQO0FBQ0Q7O0FBRURkLEVBQUFBLEdBQUcsQ0FBQ0YsR0FBRCxFQUFNRyxLQUFOLEVBQWFOLEdBQWIsRUFBa0I7QUFDbkIsVUFBTUksUUFBUSxHQUFHWCxRQUFRLENBQUMsS0FBS21CLEtBQU4sRUFBYVQsR0FBYixDQUF6QjtBQUNBLFdBQU8sS0FBS1EsT0FBTCxDQUFhTixHQUFiLENBQWlCRCxRQUFqQixFQUEyQkUsS0FBM0IsRUFBa0NOLEdBQWxDLENBQVA7QUFDRDs7QUFFRE8sRUFBQUEsR0FBRyxDQUFDSixHQUFELEVBQU07QUFDUCxVQUFNQyxRQUFRLEdBQUdYLFFBQVEsQ0FBQyxLQUFLbUIsS0FBTixFQUFhVCxHQUFiLENBQXpCO0FBQ0EsV0FBTyxLQUFLUSxPQUFMLENBQWFKLEdBQWIsQ0FBaUJILFFBQWpCLENBQVA7QUFDRDs7QUFFREksRUFBQUEsS0FBSyxHQUFHO0FBQ04sV0FBTyxLQUFLRyxPQUFMLENBQWFILEtBQWIsRUFBUDtBQUNEOztBQUVEWSxFQUFBQSxtQkFBbUIsR0FBRztBQUNwQixXQUFPQyxxQkFBUDtBQUNEOztBQTlCc0Q7OztlQWlDMUNaLGUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQWRhcHRhYmxlQ29udHJvbGxlciBmcm9tICcuL0FkYXB0YWJsZUNvbnRyb2xsZXInO1xuaW1wb3J0IENhY2hlQWRhcHRlciBmcm9tICcuLi9BZGFwdGVycy9DYWNoZS9DYWNoZUFkYXB0ZXInO1xuXG5jb25zdCBLRVlfU0VQQVJBVE9SX0NIQVIgPSAnOic7XG5cbmZ1bmN0aW9uIGpvaW5LZXlzKC4uLmtleXMpIHtcbiAgcmV0dXJuIGtleXMuam9pbihLRVlfU0VQQVJBVE9SX0NIQVIpO1xufVxuXG4vKipcbiAqIFByZWZpeCBhbGwgY2FsbHMgdG8gdGhlIGNhY2hlIHZpYSBhIHByZWZpeCBzdHJpbmcsIHVzZWZ1bCB3aGVuIGdyb3VwaW5nIENhY2hlIGJ5IG9iamVjdCB0eXBlLlxuICpcbiAqIGVnIFwiUm9sZVwiIG9yIFwiU2Vzc2lvblwiXG4gKi9cbmV4cG9ydCBjbGFzcyBTdWJDYWNoZSB7XG4gIGNvbnN0cnVjdG9yKHByZWZpeCwgY2FjaGVDb250cm9sbGVyLCB0dGwpIHtcbiAgICB0aGlzLnByZWZpeCA9IHByZWZpeDtcbiAgICB0aGlzLmNhY2hlID0gY2FjaGVDb250cm9sbGVyO1xuICAgIHRoaXMudHRsID0gdHRsO1xuICB9XG5cbiAgZ2V0KGtleSkge1xuICAgIGNvbnN0IGNhY2hlS2V5ID0gam9pbktleXModGhpcy5wcmVmaXgsIGtleSk7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0KGNhY2hlS2V5KTtcbiAgfVxuXG4gIHB1dChrZXksIHZhbHVlLCB0dGwpIHtcbiAgICBjb25zdCBjYWNoZUtleSA9IGpvaW5LZXlzKHRoaXMucHJlZml4LCBrZXkpO1xuICAgIHJldHVybiB0aGlzLmNhY2hlLnB1dChjYWNoZUtleSwgdmFsdWUsIHR0bCk7XG4gIH1cblxuICBkZWwoa2V5KSB7XG4gICAgY29uc3QgY2FjaGVLZXkgPSBqb2luS2V5cyh0aGlzLnByZWZpeCwga2V5KTtcbiAgICByZXR1cm4gdGhpcy5jYWNoZS5kZWwoY2FjaGVLZXkpO1xuICB9XG5cbiAgY2xlYXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGUuY2xlYXIoKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgQ2FjaGVDb250cm9sbGVyIGV4dGVuZHMgQWRhcHRhYmxlQ29udHJvbGxlciB7XG4gIGNvbnN0cnVjdG9yKGFkYXB0ZXIsIGFwcElkLCBvcHRpb25zID0ge30pIHtcbiAgICBzdXBlcihhZGFwdGVyLCBhcHBJZCwgb3B0aW9ucyk7XG5cbiAgICB0aGlzLnJvbGUgPSBuZXcgU3ViQ2FjaGUoJ3JvbGUnLCB0aGlzKTtcbiAgICB0aGlzLnVzZXIgPSBuZXcgU3ViQ2FjaGUoJ3VzZXInLCB0aGlzKTtcbiAgICB0aGlzLmdyYXBoUUwgPSBuZXcgU3ViQ2FjaGUoJ2dyYXBoUUwnLCB0aGlzKTtcbiAgfVxuXG4gIGdldChrZXkpIHtcbiAgICBjb25zdCBjYWNoZUtleSA9IGpvaW5LZXlzKHRoaXMuYXBwSWQsIGtleSk7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5nZXQoY2FjaGVLZXkpLnRoZW4obnVsbCwgKCkgPT4gUHJvbWlzZS5yZXNvbHZlKG51bGwpKTtcbiAgfVxuXG4gIHB1dChrZXksIHZhbHVlLCB0dGwpIHtcbiAgICBjb25zdCBjYWNoZUtleSA9IGpvaW5LZXlzKHRoaXMuYXBwSWQsIGtleSk7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5wdXQoY2FjaGVLZXksIHZhbHVlLCB0dGwpO1xuICB9XG5cbiAgZGVsKGtleSkge1xuICAgIGNvbnN0IGNhY2hlS2V5ID0gam9pbktleXModGhpcy5hcHBJZCwga2V5KTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmRlbChjYWNoZUtleSk7XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmNsZWFyKCk7XG4gIH1cblxuICBleHBlY3RlZEFkYXB0ZXJUeXBlKCkge1xuICAgIHJldHVybiBDYWNoZUFkYXB0ZXI7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ2FjaGVDb250cm9sbGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/DatabaseController.js b/lib/Controllers/DatabaseController.js new file mode 100644 index 0000000000..9d1f68d6b1 --- /dev/null +++ b/lib/Controllers/DatabaseController.js @@ -0,0 +1,1568 @@ +"use strict"; + +var _node = require("parse/node"); + +var _lodash = _interopRequireDefault(require("lodash")); + +var _intersect = _interopRequireDefault(require("intersect")); + +var _deepcopy = _interopRequireDefault(require("deepcopy")); + +var _logger = _interopRequireDefault(require("../logger")); + +var SchemaController = _interopRequireWildcard(require("./SchemaController")); + +var _StorageAdapter = require("../Adapters/Storage/StorageAdapter"); + +var _MongoStorageAdapter = _interopRequireDefault(require("../Adapters/Storage/Mongo/MongoStorageAdapter")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } + +function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } + +function addWriteACL(query, acl) { + const newQuery = _lodash.default.cloneDeep(query); //Can't be any existing '_wperm' query, we don't allow client queries on that, no need to $and + + + newQuery._wperm = { + $in: [null, ...acl] + }; + return newQuery; +} + +function addReadACL(query, acl) { + const newQuery = _lodash.default.cloneDeep(query); //Can't be any existing '_rperm' query, we don't allow client queries on that, no need to $and + + + newQuery._rperm = { + $in: [null, '*', ...acl] + }; + return newQuery; +} // Transforms a REST API formatted ACL object to our two-field mongo format. + + +const transformObjectACL = (_ref) => { + let { + ACL + } = _ref, + result = _objectWithoutProperties(_ref, ["ACL"]); + + if (!ACL) { + return result; + } + + result._wperm = []; + result._rperm = []; + + for (const entry in ACL) { + if (ACL[entry].read) { + result._rperm.push(entry); + } + + if (ACL[entry].write) { + result._wperm.push(entry); + } + } + + return result; +}; + +const specialQuerykeys = ['$and', '$or', '$nor', '_rperm', '_wperm', '_perishable_token', '_email_verify_token', '_email_verify_token_expires_at', '_account_lockout_expires_at', '_failed_login_count']; + +const isSpecialQueryKey = key => { + return specialQuerykeys.indexOf(key) >= 0; +}; + +const validateQuery = query => { + if (query.ACL) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, 'Cannot query on ACL.'); + } + + if (query.$or) { + if (query.$or instanceof Array) { + query.$or.forEach(validateQuery); + } else { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, 'Bad $or format - use an array value.'); + } + } + + if (query.$and) { + if (query.$and instanceof Array) { + query.$and.forEach(validateQuery); + } else { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, 'Bad $and format - use an array value.'); + } + } + + if (query.$nor) { + if (query.$nor instanceof Array && query.$nor.length > 0) { + query.$nor.forEach(validateQuery); + } else { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, 'Bad $nor format - use an array of at least 1 value.'); + } + } + + Object.keys(query).forEach(key => { + if (query && query[key] && query[key].$regex) { + if (typeof query[key].$options === 'string') { + if (!query[key].$options.match(/^[imxs]+$/)) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, `Bad $options value for query: ${query[key].$options}`); + } + } + } + + if (!isSpecialQueryKey(key) && !key.match(/^[a-zA-Z][a-zA-Z0-9_\.]*$/)) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Invalid key name: ${key}`); + } + }); +}; // Filters out any data that shouldn't be on this REST-formatted object. + + +const filterSensitiveData = (isMaster, aclGroup, auth, operation, schema, className, protectedFields, object) => { + let userId = null; + if (auth && auth.user) userId = auth.user.id; // replace protectedFields when using pointer-permissions + + const perms = schema.getClassLevelPermissions(className); + + if (perms) { + const isReadOperation = ['get', 'find'].indexOf(operation) > -1; + + if (isReadOperation && perms.protectedFields) { + // extract protectedFields added with the pointer-permission prefix + const protectedFieldsPointerPerm = Object.keys(perms.protectedFields).filter(key => key.startsWith('userField:')).map(key => { + return { + key: key.substring(10), + value: perms.protectedFields[key] + }; + }); + const newProtectedFields = []; + let overrideProtectedFields = false; // check if the object grants the current user access based on the extracted fields + + protectedFieldsPointerPerm.forEach(pointerPerm => { + let pointerPermIncludesUser = false; + const readUserFieldValue = object[pointerPerm.key]; + + if (readUserFieldValue) { + if (Array.isArray(readUserFieldValue)) { + pointerPermIncludesUser = readUserFieldValue.some(user => user.objectId && user.objectId === userId); + } else { + pointerPermIncludesUser = readUserFieldValue.objectId && readUserFieldValue.objectId === userId; + } + } + + if (pointerPermIncludesUser) { + overrideProtectedFields = true; + newProtectedFields.push(pointerPerm.value); + } + }); // if at least one pointer-permission affected the current user + // intersect vs protectedFields from previous stage (@see addProtectedFields) + // Sets theory (intersections): A x (B x C) == (A x B) x C + + if (overrideProtectedFields && protectedFields) { + newProtectedFields.push(protectedFields); + } // intersect all sets of protectedFields + + + newProtectedFields.forEach(fields => { + if (fields) { + // if there're no protctedFields by other criteria ( id / role / auth) + // then we must intersect each set (per userField) + if (!protectedFields) { + protectedFields = fields; + } else { + protectedFields = protectedFields.filter(v => fields.includes(v)); + } + } + }); + } + } + + const isUserClass = className === '_User'; + /* special treat for the user class: don't filter protectedFields if currently loggedin user is + the retrieved user */ + + if (!(isUserClass && userId && object.objectId === userId)) { + protectedFields && protectedFields.forEach(k => delete object[k]); // fields not requested by client (excluded), + //but were needed to apply protecttedFields + + perms.protectedFields && perms.protectedFields.temporaryKeys && perms.protectedFields.temporaryKeys.forEach(k => delete object[k]); + } + + if (!isUserClass) { + return object; + } + + object.password = object._hashed_password; + delete object._hashed_password; + delete object.sessionToken; + + if (isMaster) { + return object; + } + + delete object._email_verify_token; + delete object._perishable_token; + delete object._perishable_token_expires_at; + delete object._tombstone; + delete object._email_verify_token_expires_at; + delete object._failed_login_count; + delete object._account_lockout_expires_at; + delete object._password_changed_at; + delete object._password_history; + + if (aclGroup.indexOf(object.objectId) > -1) { + return object; + } + + delete object.authData; + return object; +}; + +// Runs an update on the database. +// Returns a promise for an object with the new values for field +// modifications that don't know their results ahead of time, like +// 'increment'. +// Options: +// acl: a list of strings. If the object to be updated has an ACL, +// one of the provided strings must provide the caller with +// write permissions. +const specialKeysForUpdate = ['_hashed_password', '_perishable_token', '_email_verify_token', '_email_verify_token_expires_at', '_account_lockout_expires_at', '_failed_login_count', '_perishable_token_expires_at', '_password_changed_at', '_password_history']; + +const isSpecialUpdateKey = key => { + return specialKeysForUpdate.indexOf(key) >= 0; +}; + +function expandResultOnKeyPath(object, key, value) { + if (key.indexOf('.') < 0) { + object[key] = value[key]; + return object; + } + + const path = key.split('.'); + const firstKey = path[0]; + const nextPath = path.slice(1).join('.'); + object[firstKey] = expandResultOnKeyPath(object[firstKey] || {}, nextPath, value[firstKey]); + delete object[key]; + return object; +} + +function sanitizeDatabaseResult(originalObject, result) { + const response = {}; + + if (!result) { + return Promise.resolve(response); + } + + Object.keys(originalObject).forEach(key => { + const keyUpdate = originalObject[key]; // determine if that was an op + + if (keyUpdate && typeof keyUpdate === 'object' && keyUpdate.__op && ['Add', 'AddUnique', 'Remove', 'Increment'].indexOf(keyUpdate.__op) > -1) { + // only valid ops that produce an actionable result + // the op may have happend on a keypath + expandResultOnKeyPath(response, key, result); + } + }); + return Promise.resolve(response); +} + +function joinTableName(className, key) { + return `_Join:${key}:${className}`; +} + +const flattenUpdateOperatorsForCreate = object => { + for (const key in object) { + if (object[key] && object[key].__op) { + switch (object[key].__op) { + case 'Increment': + if (typeof object[key].amount !== 'number') { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_JSON, 'objects to add must be an array'); + } + + object[key] = object[key].amount; + break; + + case 'Add': + if (!(object[key].objects instanceof Array)) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_JSON, 'objects to add must be an array'); + } + + object[key] = object[key].objects; + break; + + case 'AddUnique': + if (!(object[key].objects instanceof Array)) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_JSON, 'objects to add must be an array'); + } + + object[key] = object[key].objects; + break; + + case 'Remove': + if (!(object[key].objects instanceof Array)) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_JSON, 'objects to add must be an array'); + } + + object[key] = []; + break; + + case 'Delete': + delete object[key]; + break; + + default: + throw new _node.Parse.Error(_node.Parse.Error.COMMAND_UNAVAILABLE, `The ${object[key].__op} operator is not supported yet.`); + } + } + } +}; + +const transformAuthData = (className, object, schema) => { + if (object.authData && className === '_User') { + Object.keys(object.authData).forEach(provider => { + const providerData = object.authData[provider]; + const fieldName = `_auth_data_${provider}`; + + if (providerData == null) { + object[fieldName] = { + __op: 'Delete' + }; + } else { + object[fieldName] = providerData; + schema.fields[fieldName] = { + type: 'Object' + }; + } + }); + delete object.authData; + } +}; // Transforms a Database format ACL to a REST API format ACL + + +const untransformObjectACL = (_ref2) => { + let { + _rperm, + _wperm + } = _ref2, + output = _objectWithoutProperties(_ref2, ["_rperm", "_wperm"]); + + if (_rperm || _wperm) { + output.ACL = {}; + + (_rperm || []).forEach(entry => { + if (!output.ACL[entry]) { + output.ACL[entry] = { + read: true + }; + } else { + output.ACL[entry]['read'] = true; + } + }); + + (_wperm || []).forEach(entry => { + if (!output.ACL[entry]) { + output.ACL[entry] = { + write: true + }; + } else { + output.ACL[entry]['write'] = true; + } + }); + } + + return output; +}; +/** + * When querying, the fieldName may be compound, extract the root fieldName + * `temperature.celsius` becomes `temperature` + * @param {string} fieldName that may be a compound field name + * @returns {string} the root name of the field + */ + + +const getRootFieldName = fieldName => { + return fieldName.split('.')[0]; +}; + +const relationSchema = { + fields: { + relatedId: { + type: 'String' + }, + owningId: { + type: 'String' + } + } +}; + +class DatabaseController { + constructor(adapter, schemaCache) { + this.adapter = adapter; + this.schemaCache = schemaCache; // We don't want a mutable this.schema, because then you could have + // one request that uses different schemas for different parts of + // it. Instead, use loadSchema to get a schema. + + this.schemaPromise = null; + this._transactionalSession = null; + } + + collectionExists(className) { + return this.adapter.classExists(className); + } + + purgeCollection(className) { + return this.loadSchema().then(schemaController => schemaController.getOneSchema(className)).then(schema => this.adapter.deleteObjectsByQuery(className, schema, {})); + } + + validateClassName(className) { + if (!SchemaController.classNameIsValid(className)) { + return Promise.reject(new _node.Parse.Error(_node.Parse.Error.INVALID_CLASS_NAME, 'invalid className: ' + className)); + } + + return Promise.resolve(); + } // Returns a promise for a schemaController. + + + loadSchema(options = { + clearCache: false + }) { + if (this.schemaPromise != null) { + return this.schemaPromise; + } + + this.schemaPromise = SchemaController.load(this.adapter, this.schemaCache, options); + this.schemaPromise.then(() => delete this.schemaPromise, () => delete this.schemaPromise); + return this.loadSchema(options); + } + + loadSchemaIfNeeded(schemaController, options = { + clearCache: false + }) { + return schemaController ? Promise.resolve(schemaController) : this.loadSchema(options); + } // Returns a promise for the classname that is related to the given + // classname through the key. + // TODO: make this not in the DatabaseController interface + + + redirectClassNameForKey(className, key) { + return this.loadSchema().then(schema => { + var t = schema.getExpectedType(className, key); + + if (t != null && typeof t !== 'string' && t.type === 'Relation') { + return t.targetClass; + } + + return className; + }); + } // Uses the schema to validate the object (REST API format). + // Returns a promise that resolves to the new schema. + // This does not update this.schema, because in a situation like a + // batch request, that could confuse other users of the schema. + + + validateObject(className, object, query, runOptions) { + let schema; + const acl = runOptions.acl; + const isMaster = acl === undefined; + var aclGroup = acl || []; + return this.loadSchema().then(s => { + schema = s; + + if (isMaster) { + return Promise.resolve(); + } + + return this.canAddField(schema, className, object, aclGroup, runOptions); + }).then(() => { + return schema.validateObject(className, object, query); + }); + } + + update(className, query, update, { + acl, + many, + upsert, + addsField + } = {}, skipSanitization = false, validateOnly = false, validSchemaController) { + const originalQuery = query; + const originalUpdate = update; // Make a copy of the object, so we don't mutate the incoming data. + + update = (0, _deepcopy.default)(update); + var relationUpdates = []; + var isMaster = acl === undefined; + var aclGroup = acl || []; + return this.loadSchemaIfNeeded(validSchemaController).then(schemaController => { + return (isMaster ? Promise.resolve() : schemaController.validatePermission(className, aclGroup, 'update')).then(() => { + relationUpdates = this.collectRelationUpdates(className, originalQuery.objectId, update); + + if (!isMaster) { + query = this.addPointerPermissions(schemaController, className, 'update', query, aclGroup); + + if (addsField) { + query = { + $and: [query, this.addPointerPermissions(schemaController, className, 'addField', query, aclGroup)] + }; + } + } + + if (!query) { + return Promise.resolve(); + } + + if (acl) { + query = addWriteACL(query, acl); + } + + validateQuery(query); + return schemaController.getOneSchema(className, true).catch(error => { + // If the schema doesn't exist, pretend it exists with no fields. This behavior + // will likely need revisiting. + if (error === undefined) { + return { + fields: {} + }; + } + + throw error; + }).then(schema => { + Object.keys(update).forEach(fieldName => { + if (fieldName.match(/^authData\.([a-zA-Z0-9_]+)\.id$/)) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Invalid field name for update: ${fieldName}`); + } + + const rootFieldName = getRootFieldName(fieldName); + + if (!SchemaController.fieldNameIsValid(rootFieldName, className) && !isSpecialUpdateKey(rootFieldName)) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Invalid field name for update: ${fieldName}`); + } + }); + + for (const updateOperation in update) { + if (update[updateOperation] && typeof update[updateOperation] === 'object' && Object.keys(update[updateOperation]).some(innerKey => innerKey.includes('$') || innerKey.includes('.'))) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_NESTED_KEY, "Nested keys should not contain the '$' or '.' characters"); + } + } + + update = transformObjectACL(update); + transformAuthData(className, update, schema); + + if (validateOnly) { + return this.adapter.find(className, schema, query, {}).then(result => { + if (!result || !result.length) { + throw new _node.Parse.Error(_node.Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } + + return {}; + }); + } + + if (many) { + return this.adapter.updateObjectsByQuery(className, schema, query, update, this._transactionalSession); + } else if (upsert) { + return this.adapter.upsertOneObject(className, schema, query, update, this._transactionalSession); + } else { + return this.adapter.findOneAndUpdate(className, schema, query, update, this._transactionalSession); + } + }); + }).then(result => { + if (!result) { + throw new _node.Parse.Error(_node.Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } + + if (validateOnly) { + return result; + } + + return this.handleRelationUpdates(className, originalQuery.objectId, update, relationUpdates).then(() => { + return result; + }); + }).then(result => { + if (skipSanitization) { + return Promise.resolve(result); + } + + return sanitizeDatabaseResult(originalUpdate, result); + }); + }); + } // Collect all relation-updating operations from a REST-format update. + // Returns a list of all relation updates to perform + // This mutates update. + + + collectRelationUpdates(className, objectId, update) { + var ops = []; + var deleteMe = []; + objectId = update.objectId || objectId; + + var process = (op, key) => { + if (!op) { + return; + } + + if (op.__op == 'AddRelation') { + ops.push({ + key, + op + }); + deleteMe.push(key); + } + + if (op.__op == 'RemoveRelation') { + ops.push({ + key, + op + }); + deleteMe.push(key); + } + + if (op.__op == 'Batch') { + for (var x of op.ops) { + process(x, key); + } + } + }; + + for (const key in update) { + process(update[key], key); + } + + for (const key of deleteMe) { + delete update[key]; + } + + return ops; + } // Processes relation-updating operations from a REST-format update. + // Returns a promise that resolves when all updates have been performed + + + handleRelationUpdates(className, objectId, update, ops) { + var pending = []; + objectId = update.objectId || objectId; + ops.forEach(({ + key, + op + }) => { + if (!op) { + return; + } + + if (op.__op == 'AddRelation') { + for (const object of op.objects) { + pending.push(this.addRelation(key, className, objectId, object.objectId)); + } + } + + if (op.__op == 'RemoveRelation') { + for (const object of op.objects) { + pending.push(this.removeRelation(key, className, objectId, object.objectId)); + } + } + }); + return Promise.all(pending); + } // Adds a relation. + // Returns a promise that resolves successfully iff the add was successful. + + + addRelation(key, fromClassName, fromId, toId) { + const doc = { + relatedId: toId, + owningId: fromId + }; + return this.adapter.upsertOneObject(`_Join:${key}:${fromClassName}`, relationSchema, doc, doc, this._transactionalSession); + } // Removes a relation. + // Returns a promise that resolves successfully iff the remove was + // successful. + + + removeRelation(key, fromClassName, fromId, toId) { + var doc = { + relatedId: toId, + owningId: fromId + }; + return this.adapter.deleteObjectsByQuery(`_Join:${key}:${fromClassName}`, relationSchema, doc, this._transactionalSession).catch(error => { + // We don't care if they try to delete a non-existent relation. + if (error.code == _node.Parse.Error.OBJECT_NOT_FOUND) { + return; + } + + throw error; + }); + } // Removes objects matches this query from the database. + // Returns a promise that resolves successfully iff the object was + // deleted. + // Options: + // acl: a list of strings. If the object to be updated has an ACL, + // one of the provided strings must provide the caller with + // write permissions. + + + destroy(className, query, { + acl + } = {}, validSchemaController) { + const isMaster = acl === undefined; + const aclGroup = acl || []; + return this.loadSchemaIfNeeded(validSchemaController).then(schemaController => { + return (isMaster ? Promise.resolve() : schemaController.validatePermission(className, aclGroup, 'delete')).then(() => { + if (!isMaster) { + query = this.addPointerPermissions(schemaController, className, 'delete', query, aclGroup); + + if (!query) { + throw new _node.Parse.Error(_node.Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } + } // delete by query + + + if (acl) { + query = addWriteACL(query, acl); + } + + validateQuery(query); + return schemaController.getOneSchema(className).catch(error => { + // If the schema doesn't exist, pretend it exists with no fields. This behavior + // will likely need revisiting. + if (error === undefined) { + return { + fields: {} + }; + } + + throw error; + }).then(parseFormatSchema => this.adapter.deleteObjectsByQuery(className, parseFormatSchema, query, this._transactionalSession)).catch(error => { + // When deleting sessions while changing passwords, don't throw an error if they don't have any sessions. + if (className === '_Session' && error.code === _node.Parse.Error.OBJECT_NOT_FOUND) { + return Promise.resolve({}); + } + + throw error; + }); + }); + }); + } // Inserts an object into the database. + // Returns a promise that resolves successfully iff the object saved. + + + create(className, object, { + acl + } = {}, validateOnly = false, validSchemaController) { + // Make a copy of the object, so we don't mutate the incoming data. + const originalObject = object; + object = transformObjectACL(object); + object.createdAt = { + iso: object.createdAt, + __type: 'Date' + }; + object.updatedAt = { + iso: object.updatedAt, + __type: 'Date' + }; + var isMaster = acl === undefined; + var aclGroup = acl || []; + const relationUpdates = this.collectRelationUpdates(className, null, object); + return this.validateClassName(className).then(() => this.loadSchemaIfNeeded(validSchemaController)).then(schemaController => { + return (isMaster ? Promise.resolve() : schemaController.validatePermission(className, aclGroup, 'create')).then(() => schemaController.enforceClassExists(className)).then(() => schemaController.getOneSchema(className, true)).then(schema => { + transformAuthData(className, object, schema); + flattenUpdateOperatorsForCreate(object); + + if (validateOnly) { + return {}; + } + + return this.adapter.createObject(className, SchemaController.convertSchemaToAdapterSchema(schema), object, this._transactionalSession); + }).then(result => { + if (validateOnly) { + return originalObject; + } + + return this.handleRelationUpdates(className, object.objectId, object, relationUpdates).then(() => { + return sanitizeDatabaseResult(originalObject, result.ops[0]); + }); + }); + }); + } + + canAddField(schema, className, object, aclGroup, runOptions) { + const classSchema = schema.schemaData[className]; + + if (!classSchema) { + return Promise.resolve(); + } + + const fields = Object.keys(object); + const schemaFields = Object.keys(classSchema.fields); + const newKeys = fields.filter(field => { + // Skip fields that are unset + if (object[field] && object[field].__op && object[field].__op === 'Delete') { + return false; + } + + return schemaFields.indexOf(field) < 0; + }); + + if (newKeys.length > 0) { + // adds a marker that new field is being adding during update + runOptions.addsField = true; + const action = runOptions.action; + return schema.validatePermission(className, aclGroup, 'addField', action); + } + + return Promise.resolve(); + } // Won't delete collections in the system namespace + + /** + * Delete all classes and clears the schema cache + * + * @param {boolean} fast set to true if it's ok to just delete rows and not indexes + * @returns {Promise} when the deletions completes + */ + + + deleteEverything(fast = false) { + this.schemaPromise = null; + return Promise.all([this.adapter.deleteAllClasses(fast), this.schemaCache.clear()]); + } // Returns a promise for a list of related ids given an owning id. + // className here is the owning className. + + + relatedIds(className, key, owningId, queryOptions) { + const { + skip, + limit, + sort + } = queryOptions; + const findOptions = {}; + + if (sort && sort.createdAt && this.adapter.canSortOnJoinTables) { + findOptions.sort = { + _id: sort.createdAt + }; + findOptions.limit = limit; + findOptions.skip = skip; + queryOptions.skip = 0; + } + + return this.adapter.find(joinTableName(className, key), relationSchema, { + owningId + }, findOptions).then(results => results.map(result => result.relatedId)); + } // Returns a promise for a list of owning ids given some related ids. + // className here is the owning className. + + + owningIds(className, key, relatedIds) { + return this.adapter.find(joinTableName(className, key), relationSchema, { + relatedId: { + $in: relatedIds + } + }, { + keys: ['owningId'] + }).then(results => results.map(result => result.owningId)); + } // Modifies query so that it no longer has $in on relation fields, or + // equal-to-pointer constraints on relation fields. + // Returns a promise that resolves when query is mutated + + + reduceInRelation(className, query, schema) { + // Search for an in-relation or equal-to-relation + // Make it sequential for now, not sure of paralleization side effects + if (query['$or']) { + const ors = query['$or']; + return Promise.all(ors.map((aQuery, index) => { + return this.reduceInRelation(className, aQuery, schema).then(aQuery => { + query['$or'][index] = aQuery; + }); + })).then(() => { + return Promise.resolve(query); + }); + } + + const promises = Object.keys(query).map(key => { + const t = schema.getExpectedType(className, key); + + if (!t || t.type !== 'Relation') { + return Promise.resolve(query); + } + + let queries = null; + + if (query[key] && (query[key]['$in'] || query[key]['$ne'] || query[key]['$nin'] || query[key].__type == 'Pointer')) { + // Build the list of queries + queries = Object.keys(query[key]).map(constraintKey => { + let relatedIds; + let isNegation = false; + + if (constraintKey === 'objectId') { + relatedIds = [query[key].objectId]; + } else if (constraintKey == '$in') { + relatedIds = query[key]['$in'].map(r => r.objectId); + } else if (constraintKey == '$nin') { + isNegation = true; + relatedIds = query[key]['$nin'].map(r => r.objectId); + } else if (constraintKey == '$ne') { + isNegation = true; + relatedIds = [query[key]['$ne'].objectId]; + } else { + return; + } + + return { + isNegation, + relatedIds + }; + }); + } else { + queries = [{ + isNegation: false, + relatedIds: [] + }]; + } // remove the current queryKey as we don,t need it anymore + + + delete query[key]; // execute each query independently to build the list of + // $in / $nin + + const promises = queries.map(q => { + if (!q) { + return Promise.resolve(); + } + + return this.owningIds(className, key, q.relatedIds).then(ids => { + if (q.isNegation) { + this.addNotInObjectIdsIds(ids, query); + } else { + this.addInObjectIdsIds(ids, query); + } + + return Promise.resolve(); + }); + }); + return Promise.all(promises).then(() => { + return Promise.resolve(); + }); + }); + return Promise.all(promises).then(() => { + return Promise.resolve(query); + }); + } // Modifies query so that it no longer has $relatedTo + // Returns a promise that resolves when query is mutated + + + reduceRelationKeys(className, query, queryOptions) { + if (query['$or']) { + return Promise.all(query['$or'].map(aQuery => { + return this.reduceRelationKeys(className, aQuery, queryOptions); + })); + } + + var relatedTo = query['$relatedTo']; + + if (relatedTo) { + return this.relatedIds(relatedTo.object.className, relatedTo.key, relatedTo.object.objectId, queryOptions).then(ids => { + delete query['$relatedTo']; + this.addInObjectIdsIds(ids, query); + return this.reduceRelationKeys(className, query, queryOptions); + }).then(() => {}); + } + } + + addInObjectIdsIds(ids = null, query) { + const idsFromString = typeof query.objectId === 'string' ? [query.objectId] : null; + const idsFromEq = query.objectId && query.objectId['$eq'] ? [query.objectId['$eq']] : null; + const idsFromIn = query.objectId && query.objectId['$in'] ? query.objectId['$in'] : null; // -disable-next + + const allIds = [idsFromString, idsFromEq, idsFromIn, ids].filter(list => list !== null); + const totalLength = allIds.reduce((memo, list) => memo + list.length, 0); + let idsIntersection = []; + + if (totalLength > 125) { + idsIntersection = _intersect.default.big(allIds); + } else { + idsIntersection = (0, _intersect.default)(allIds); + } // Need to make sure we don't clobber existing shorthand $eq constraints on objectId. + + + if (!('objectId' in query)) { + query.objectId = { + $in: undefined + }; + } else if (typeof query.objectId === 'string') { + query.objectId = { + $in: undefined, + $eq: query.objectId + }; + } + + query.objectId['$in'] = idsIntersection; + return query; + } + + addNotInObjectIdsIds(ids = [], query) { + const idsFromNin = query.objectId && query.objectId['$nin'] ? query.objectId['$nin'] : []; + let allIds = [...idsFromNin, ...ids].filter(list => list !== null); // make a set and spread to remove duplicates + + allIds = [...new Set(allIds)]; // Need to make sure we don't clobber existing shorthand $eq constraints on objectId. + + if (!('objectId' in query)) { + query.objectId = { + $nin: undefined + }; + } else if (typeof query.objectId === 'string') { + query.objectId = { + $nin: undefined, + $eq: query.objectId + }; + } + + query.objectId['$nin'] = allIds; + return query; + } // Runs a query on the database. + // Returns a promise that resolves to a list of items. + // Options: + // skip number of results to skip. + // limit limit to this number of results. + // sort an object where keys are the fields to sort by. + // the value is +1 for ascending, -1 for descending. + // count run a count instead of returning results. + // acl restrict this operation with an ACL for the provided array + // of user objectIds and roles. acl: null means no user. + // when this field is not present, don't do anything regarding ACLs. + // caseInsensitive make string comparisons case insensitive + // TODO: make userIds not needed here. The db adapter shouldn't know + // anything about users, ideally. Then, improve the format of the ACL + // arg to work like the others. + + + find(className, query, { + skip, + limit, + acl, + sort = {}, + count, + keys, + op, + distinct, + pipeline, + readPreference, + hint, + caseInsensitive = false, + explain + } = {}, auth = {}, validSchemaController) { + const isMaster = acl === undefined; + const aclGroup = acl || []; + op = op || (typeof query.objectId == 'string' && Object.keys(query).length === 1 ? 'get' : 'find'); // Count operation if counting + + op = count === true ? 'count' : op; + let classExists = true; + return this.loadSchemaIfNeeded(validSchemaController).then(schemaController => { + //Allow volatile classes if querying with Master (for _PushStatus) + //TODO: Move volatile classes concept into mongo adapter, postgres adapter shouldn't care + //that api.parse.com breaks when _PushStatus exists in mongo. + return schemaController.getOneSchema(className, isMaster).catch(error => { + // Behavior for non-existent classes is kinda weird on Parse.com. Probably doesn't matter too much. + // For now, pretend the class exists but has no objects, + if (error === undefined) { + classExists = false; + return { + fields: {} + }; + } + + throw error; + }).then(schema => { + // Parse.com treats queries on _created_at and _updated_at as if they were queries on createdAt and updatedAt, + // so duplicate that behavior here. If both are specified, the correct behavior to match Parse.com is to + // use the one that appears first in the sort list. + if (sort._created_at) { + sort.createdAt = sort._created_at; + delete sort._created_at; + } + + if (sort._updated_at) { + sort.updatedAt = sort._updated_at; + delete sort._updated_at; + } + + const queryOptions = { + skip, + limit, + sort, + keys, + readPreference, + hint, + caseInsensitive, + explain + }; + Object.keys(sort).forEach(fieldName => { + if (fieldName.match(/^authData\.([a-zA-Z0-9_]+)\.id$/)) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Cannot sort by ${fieldName}`); + } + + const rootFieldName = getRootFieldName(fieldName); + + if (!SchemaController.fieldNameIsValid(rootFieldName, className)) { + throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Invalid field name: ${fieldName}.`); + } + }); + return (isMaster ? Promise.resolve() : schemaController.validatePermission(className, aclGroup, op)).then(() => this.reduceRelationKeys(className, query, queryOptions)).then(() => this.reduceInRelation(className, query, schemaController)).then(() => { + let protectedFields; + + if (!isMaster) { + query = this.addPointerPermissions(schemaController, className, op, query, aclGroup); + /* Don't use projections to optimize the protectedFields since the protectedFields + based on pointer-permissions are determined after querying. The filtering can + overwrite the protected fields. */ + + protectedFields = this.addProtectedFields(schemaController, className, query, aclGroup, auth, queryOptions); + } + + if (!query) { + if (op === 'get') { + throw new _node.Parse.Error(_node.Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } else { + return []; + } + } + + if (!isMaster) { + if (op === 'update' || op === 'delete') { + query = addWriteACL(query, aclGroup); + } else { + query = addReadACL(query, aclGroup); + } + } + + validateQuery(query); + + if (count) { + if (!classExists) { + return 0; + } else { + return this.adapter.count(className, schema, query, readPreference, undefined, hint); + } + } else if (distinct) { + if (!classExists) { + return []; + } else { + return this.adapter.distinct(className, schema, query, distinct); + } + } else if (pipeline) { + if (!classExists) { + return []; + } else { + return this.adapter.aggregate(className, schema, pipeline, readPreference, hint, explain); + } + } else if (explain) { + return this.adapter.find(className, schema, query, queryOptions); + } else { + return this.adapter.find(className, schema, query, queryOptions).then(objects => objects.map(object => { + object = untransformObjectACL(object); + return filterSensitiveData(isMaster, aclGroup, auth, op, schemaController, className, protectedFields, object); + })).catch(error => { + throw new _node.Parse.Error(_node.Parse.Error.INTERNAL_SERVER_ERROR, error); + }); + } + }); + }); + }); + } + + deleteSchema(className) { + return this.loadSchema({ + clearCache: true + }).then(schemaController => schemaController.getOneSchema(className, true)).catch(error => { + if (error === undefined) { + return { + fields: {} + }; + } else { + throw error; + } + }).then(schema => { + return this.collectionExists(className).then(() => this.adapter.count(className, { + fields: {} + }, null, '', false)).then(count => { + if (count > 0) { + throw new _node.Parse.Error(255, `Class ${className} is not empty, contains ${count} objects, cannot drop schema.`); + } + + return this.adapter.deleteClass(className); + }).then(wasParseCollection => { + if (wasParseCollection) { + const relationFieldNames = Object.keys(schema.fields).filter(fieldName => schema.fields[fieldName].type === 'Relation'); + return Promise.all(relationFieldNames.map(name => this.adapter.deleteClass(joinTableName(className, name)))).then(() => { + return; + }); + } else { + return Promise.resolve(); + } + }); + }); + } // This helps to create intermediate objects for simpler comparison of + // key value pairs used in query objects. Each key value pair will represented + // in a similar way to json + + + objectToEntriesStrings(query) { + return Object.entries(query).map(a => a.map(s => JSON.stringify(s)).join(':')); + } // Naive logic reducer for OR operations meant to be used only for pointer permissions. + + + reduceOrOperation(query) { + if (!query.$or) { + return query; + } + + const queries = query.$or.map(q => this.objectToEntriesStrings(q)); + let repeat = false; + + do { + repeat = false; + + for (let i = 0; i < queries.length - 1; i++) { + for (let j = i + 1; j < queries.length; j++) { + const [shorter, longer] = queries[i].length > queries[j].length ? [j, i] : [i, j]; + const foundEntries = queries[shorter].reduce((acc, entry) => acc + (queries[longer].includes(entry) ? 1 : 0), 0); + const shorterEntries = queries[shorter].length; + + if (foundEntries === shorterEntries) { + // If the shorter query is completely contained in the longer one, we can strike + // out the longer query. + query.$or.splice(longer, 1); + queries.splice(longer, 1); + repeat = true; + break; + } + } + } + } while (repeat); + + if (query.$or.length === 1) { + query = _objectSpread(_objectSpread({}, query), query.$or[0]); + delete query.$or; + } + + return query; + } // Naive logic reducer for AND operations meant to be used only for pointer permissions. + + + reduceAndOperation(query) { + if (!query.$and) { + return query; + } + + const queries = query.$and.map(q => this.objectToEntriesStrings(q)); + let repeat = false; + + do { + repeat = false; + + for (let i = 0; i < queries.length - 1; i++) { + for (let j = i + 1; j < queries.length; j++) { + const [shorter, longer] = queries[i].length > queries[j].length ? [j, i] : [i, j]; + const foundEntries = queries[shorter].reduce((acc, entry) => acc + (queries[longer].includes(entry) ? 1 : 0), 0); + const shorterEntries = queries[shorter].length; + + if (foundEntries === shorterEntries) { + // If the shorter query is completely contained in the longer one, we can strike + // out the shorter query. + query.$and.splice(shorter, 1); + queries.splice(shorter, 1); + repeat = true; + break; + } + } + } + } while (repeat); + + if (query.$and.length === 1) { + query = _objectSpread(_objectSpread({}, query), query.$and[0]); + delete query.$and; + } + + return query; + } // Constraints query using CLP's pointer permissions (PP) if any. + // 1. Etract the user id from caller's ACLgroup; + // 2. Exctract a list of field names that are PP for target collection and operation; + // 3. Constraint the original query so that each PP field must + // point to caller's id (or contain it in case of PP field being an array) + + + addPointerPermissions(schema, className, operation, query, aclGroup = []) { + // Check if class has public permission for operation + // If the BaseCLP pass, let go through + if (schema.testPermissionsForClassName(className, aclGroup, operation)) { + return query; + } + + const perms = schema.getClassLevelPermissions(className); + const userACL = aclGroup.filter(acl => { + return acl.indexOf('role:') != 0 && acl != '*'; + }); + const groupKey = ['get', 'find', 'count'].indexOf(operation) > -1 ? 'readUserFields' : 'writeUserFields'; + const permFields = []; + + if (perms[operation] && perms[operation].pointerFields) { + permFields.push(...perms[operation].pointerFields); + } + + if (perms[groupKey]) { + for (const field of perms[groupKey]) { + if (!permFields.includes(field)) { + permFields.push(field); + } + } + } // the ACL should have exactly 1 user + + + if (permFields.length > 0) { + // the ACL should have exactly 1 user + // No user set return undefined + // If the length is > 1, that means we didn't de-dupe users correctly + if (userACL.length != 1) { + return; + } + + const userId = userACL[0]; + const userPointer = { + __type: 'Pointer', + className: '_User', + objectId: userId + }; + const queries = permFields.map(key => { + const fieldDescriptor = schema.getExpectedType(className, key); + const fieldType = fieldDescriptor && typeof fieldDescriptor === 'object' && Object.prototype.hasOwnProperty.call(fieldDescriptor, 'type') ? fieldDescriptor.type : null; + let queryClause; + + if (fieldType === 'Pointer') { + // constraint for single pointer setup + queryClause = { + [key]: userPointer + }; + } else if (fieldType === 'Array') { + // constraint for users-array setup + queryClause = { + [key]: { + $all: [userPointer] + } + }; + } else if (fieldType === 'Object') { + // constraint for object setup + queryClause = { + [key]: userPointer + }; + } else { + // This means that there is a CLP field of an unexpected type. This condition should not happen, which is + // why is being treated as an error. + throw Error(`An unexpected condition occurred when resolving pointer permissions: ${className} ${key}`); + } // if we already have a constraint on the key, use the $and + + + if (Object.prototype.hasOwnProperty.call(query, key)) { + return this.reduceAndOperation({ + $and: [queryClause, query] + }); + } // otherwise just add the constaint + + + return Object.assign({}, query, queryClause); + }); + return queries.length === 1 ? queries[0] : this.reduceOrOperation({ + $or: queries + }); + } else { + return query; + } + } + + addProtectedFields(schema, className, query = {}, aclGroup = [], auth = {}, queryOptions = {}) { + const perms = schema.getClassLevelPermissions(className); + if (!perms) return null; + const protectedFields = perms.protectedFields; + if (!protectedFields) return null; + if (aclGroup.indexOf(query.objectId) > -1) return null; // for queries where "keys" are set and do not include all 'userField':{field}, + // we have to transparently include it, and then remove before returning to client + // Because if such key not projected the permission won't be enforced properly + // PS this is called when 'excludeKeys' already reduced to 'keys' + + const preserveKeys = queryOptions.keys; // these are keys that need to be included only + // to be able to apply protectedFields by pointer + // and then unset before returning to client (later in filterSensitiveFields) + + const serverOnlyKeys = []; + const authenticated = auth.user; // map to allow check without array search + + const roles = (auth.userRoles || []).reduce((acc, r) => { + acc[r] = protectedFields[r]; + return acc; + }, {}); // array of sets of protected fields. separate item for each applicable criteria + + const protectedKeysSets = []; + + for (const key in protectedFields) { + // skip userFields + if (key.startsWith('userField:')) { + if (preserveKeys) { + const fieldName = key.substring(10); + + if (!preserveKeys.includes(fieldName)) { + // 1. put it there temporarily + queryOptions.keys && queryOptions.keys.push(fieldName); // 2. preserve it delete later + + serverOnlyKeys.push(fieldName); + } + } + + continue; + } // add public tier + + + if (key === '*') { + protectedKeysSets.push(protectedFields[key]); + continue; + } + + if (authenticated) { + if (key === 'authenticated') { + // for logged in users + protectedKeysSets.push(protectedFields[key]); + continue; + } + + if (roles[key] && key.startsWith('role:')) { + // add applicable roles + protectedKeysSets.push(roles[key]); + } + } + } // check if there's a rule for current user's id + + + if (authenticated) { + const userId = auth.user.id; + + if (perms.protectedFields[userId]) { + protectedKeysSets.push(perms.protectedFields[userId]); + } + } // preserve fields to be removed before sending response to client + + + if (serverOnlyKeys.length > 0) { + perms.protectedFields.temporaryKeys = serverOnlyKeys; + } + + let protectedKeys = protectedKeysSets.reduce((acc, next) => { + if (next) { + acc.push(...next); + } + + return acc; + }, []); // intersect all sets of protectedFields + + protectedKeysSets.forEach(fields => { + if (fields) { + protectedKeys = protectedKeys.filter(v => fields.includes(v)); + } + }); + return protectedKeys; + } + + createTransactionalSession() { + return this.adapter.createTransactionalSession().then(transactionalSession => { + this._transactionalSession = transactionalSession; + }); + } + + commitTransactionalSession() { + if (!this._transactionalSession) { + throw new Error('There is no transactional session to commit'); + } + + return this.adapter.commitTransactionalSession(this._transactionalSession).then(() => { + this._transactionalSession = null; + }); + } + + abortTransactionalSession() { + if (!this._transactionalSession) { + throw new Error('There is no transactional session to abort'); + } + + return this.adapter.abortTransactionalSession(this._transactionalSession).then(() => { + this._transactionalSession = null; + }); + } // TODO: create indexes on first creation of a _User object. Otherwise it's impossible to + // have a Parse app without it having a _User collection. + + + performInitialization() { + const requiredUserFields = { + fields: _objectSpread(_objectSpread({}, SchemaController.defaultColumns._Default), SchemaController.defaultColumns._User) + }; + const requiredRoleFields = { + fields: _objectSpread(_objectSpread({}, SchemaController.defaultColumns._Default), SchemaController.defaultColumns._Role) + }; + const requiredIdempotencyFields = { + fields: _objectSpread(_objectSpread({}, SchemaController.defaultColumns._Default), SchemaController.defaultColumns._Idempotency) + }; + const userClassPromise = this.loadSchema().then(schema => schema.enforceClassExists('_User')); + const roleClassPromise = this.loadSchema().then(schema => schema.enforceClassExists('_Role')); + const idempotencyClassPromise = this.adapter instanceof _MongoStorageAdapter.default ? this.loadSchema().then(schema => schema.enforceClassExists('_Idempotency')) : Promise.resolve(); + const usernameUniqueness = userClassPromise.then(() => this.adapter.ensureUniqueness('_User', requiredUserFields, ['username'])).catch(error => { + _logger.default.warn('Unable to ensure uniqueness for usernames: ', error); + + throw error; + }); + const usernameCaseInsensitiveIndex = userClassPromise.then(() => this.adapter.ensureIndex('_User', requiredUserFields, ['username'], 'case_insensitive_username', true)).catch(error => { + _logger.default.warn('Unable to create case insensitive username index: ', error); + + throw error; + }); + const emailUniqueness = userClassPromise.then(() => this.adapter.ensureUniqueness('_User', requiredUserFields, ['email'])).catch(error => { + _logger.default.warn('Unable to ensure uniqueness for user email addresses: ', error); + + throw error; + }); + const emailCaseInsensitiveIndex = userClassPromise.then(() => this.adapter.ensureIndex('_User', requiredUserFields, ['email'], 'case_insensitive_email', true)).catch(error => { + _logger.default.warn('Unable to create case insensitive email index: ', error); + + throw error; + }); + const roleUniqueness = roleClassPromise.then(() => this.adapter.ensureUniqueness('_Role', requiredRoleFields, ['name'])).catch(error => { + _logger.default.warn('Unable to ensure uniqueness for role name: ', error); + + throw error; + }); + const idempotencyRequestIdIndex = this.adapter instanceof _MongoStorageAdapter.default ? idempotencyClassPromise.then(() => this.adapter.ensureUniqueness('_Idempotency', requiredIdempotencyFields, ['reqId'])).catch(error => { + _logger.default.warn('Unable to ensure uniqueness for idempotency request ID: ', error); + + throw error; + }) : Promise.resolve(); + const idempotencyExpireIndex = this.adapter instanceof _MongoStorageAdapter.default ? idempotencyClassPromise.then(() => this.adapter.ensureIndex('_Idempotency', requiredIdempotencyFields, ['expire'], 'ttl', false, { + ttl: 0 + })).catch(error => { + _logger.default.warn('Unable to create TTL index for idempotency expire date: ', error); + + throw error; + }) : Promise.resolve(); + const indexPromise = this.adapter.updateSchemaWithIndexes(); // Create tables for volatile classes + + const adapterInit = this.adapter.performInitialization({ + VolatileClassesSchemas: SchemaController.VolatileClassesSchemas + }); + return Promise.all([usernameUniqueness, usernameCaseInsensitiveIndex, emailUniqueness, emailCaseInsensitiveIndex, roleUniqueness, idempotencyRequestIdIndex, idempotencyExpireIndex, adapterInit, indexPromise]); + } + +} + +module.exports = DatabaseController; // Expose validateQuery for tests + +module.exports._validateQuery = validateQuery; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9EYXRhYmFzZUNvbnRyb2xsZXIuanMiXSwibmFtZXMiOlsiYWRkV3JpdGVBQ0wiLCJxdWVyeSIsImFjbCIsIm5ld1F1ZXJ5IiwiXyIsImNsb25lRGVlcCIsIl93cGVybSIsIiRpbiIsImFkZFJlYWRBQ0wiLCJfcnBlcm0iLCJ0cmFuc2Zvcm1PYmplY3RBQ0wiLCJBQ0wiLCJyZXN1bHQiLCJlbnRyeSIsInJlYWQiLCJwdXNoIiwid3JpdGUiLCJzcGVjaWFsUXVlcnlrZXlzIiwiaXNTcGVjaWFsUXVlcnlLZXkiLCJrZXkiLCJpbmRleE9mIiwidmFsaWRhdGVRdWVyeSIsIlBhcnNlIiwiRXJyb3IiLCJJTlZBTElEX1FVRVJZIiwiJG9yIiwiQXJyYXkiLCJmb3JFYWNoIiwiJGFuZCIsIiRub3IiLCJsZW5ndGgiLCJPYmplY3QiLCJrZXlzIiwiJHJlZ2V4IiwiJG9wdGlvbnMiLCJtYXRjaCIsIklOVkFMSURfS0VZX05BTUUiLCJmaWx0ZXJTZW5zaXRpdmVEYXRhIiwiaXNNYXN0ZXIiLCJhY2xHcm91cCIsImF1dGgiLCJvcGVyYXRpb24iLCJzY2hlbWEiLCJjbGFzc05hbWUiLCJwcm90ZWN0ZWRGaWVsZHMiLCJvYmplY3QiLCJ1c2VySWQiLCJ1c2VyIiwiaWQiLCJwZXJtcyIsImdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsImlzUmVhZE9wZXJhdGlvbiIsInByb3RlY3RlZEZpZWxkc1BvaW50ZXJQZXJtIiwiZmlsdGVyIiwic3RhcnRzV2l0aCIsIm1hcCIsInN1YnN0cmluZyIsInZhbHVlIiwibmV3UHJvdGVjdGVkRmllbGRzIiwib3ZlcnJpZGVQcm90ZWN0ZWRGaWVsZHMiLCJwb2ludGVyUGVybSIsInBvaW50ZXJQZXJtSW5jbHVkZXNVc2VyIiwicmVhZFVzZXJGaWVsZFZhbHVlIiwiaXNBcnJheSIsInNvbWUiLCJvYmplY3RJZCIsImZpZWxkcyIsInYiLCJpbmNsdWRlcyIsImlzVXNlckNsYXNzIiwiayIsInRlbXBvcmFyeUtleXMiLCJwYXNzd29yZCIsIl9oYXNoZWRfcGFzc3dvcmQiLCJzZXNzaW9uVG9rZW4iLCJfZW1haWxfdmVyaWZ5X3Rva2VuIiwiX3BlcmlzaGFibGVfdG9rZW4iLCJfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0IiwiX3RvbWJzdG9uZSIsIl9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCIsIl9mYWlsZWRfbG9naW5fY291bnQiLCJfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQiLCJfcGFzc3dvcmRfY2hhbmdlZF9hdCIsIl9wYXNzd29yZF9oaXN0b3J5IiwiYXV0aERhdGEiLCJzcGVjaWFsS2V5c0ZvclVwZGF0ZSIsImlzU3BlY2lhbFVwZGF0ZUtleSIsImV4cGFuZFJlc3VsdE9uS2V5UGF0aCIsInBhdGgiLCJzcGxpdCIsImZpcnN0S2V5IiwibmV4dFBhdGgiLCJzbGljZSIsImpvaW4iLCJzYW5pdGl6ZURhdGFiYXNlUmVzdWx0Iiwib3JpZ2luYWxPYmplY3QiLCJyZXNwb25zZSIsIlByb21pc2UiLCJyZXNvbHZlIiwia2V5VXBkYXRlIiwiX19vcCIsImpvaW5UYWJsZU5hbWUiLCJmbGF0dGVuVXBkYXRlT3BlcmF0b3JzRm9yQ3JlYXRlIiwiYW1vdW50IiwiSU5WQUxJRF9KU09OIiwib2JqZWN0cyIsIkNPTU1BTkRfVU5BVkFJTEFCTEUiLCJ0cmFuc2Zvcm1BdXRoRGF0YSIsInByb3ZpZGVyIiwicHJvdmlkZXJEYXRhIiwiZmllbGROYW1lIiwidHlwZSIsInVudHJhbnNmb3JtT2JqZWN0QUNMIiwib3V0cHV0IiwiZ2V0Um9vdEZpZWxkTmFtZSIsInJlbGF0aW9uU2NoZW1hIiwicmVsYXRlZElkIiwib3duaW5nSWQiLCJEYXRhYmFzZUNvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImFkYXB0ZXIiLCJzY2hlbWFDYWNoZSIsInNjaGVtYVByb21pc2UiLCJfdHJhbnNhY3Rpb25hbFNlc3Npb24iLCJjb2xsZWN0aW9uRXhpc3RzIiwiY2xhc3NFeGlzdHMiLCJwdXJnZUNvbGxlY3Rpb24iLCJsb2FkU2NoZW1hIiwidGhlbiIsInNjaGVtYUNvbnRyb2xsZXIiLCJnZXRPbmVTY2hlbWEiLCJkZWxldGVPYmplY3RzQnlRdWVyeSIsInZhbGlkYXRlQ2xhc3NOYW1lIiwiU2NoZW1hQ29udHJvbGxlciIsImNsYXNzTmFtZUlzVmFsaWQiLCJyZWplY3QiLCJJTlZBTElEX0NMQVNTX05BTUUiLCJvcHRpb25zIiwiY2xlYXJDYWNoZSIsImxvYWQiLCJsb2FkU2NoZW1hSWZOZWVkZWQiLCJyZWRpcmVjdENsYXNzTmFtZUZvcktleSIsInQiLCJnZXRFeHBlY3RlZFR5cGUiLCJ0YXJnZXRDbGFzcyIsInZhbGlkYXRlT2JqZWN0IiwicnVuT3B0aW9ucyIsInVuZGVmaW5lZCIsInMiLCJjYW5BZGRGaWVsZCIsInVwZGF0ZSIsIm1hbnkiLCJ1cHNlcnQiLCJhZGRzRmllbGQiLCJza2lwU2FuaXRpemF0aW9uIiwidmFsaWRhdGVPbmx5IiwidmFsaWRTY2hlbWFDb250cm9sbGVyIiwib3JpZ2luYWxRdWVyeSIsIm9yaWdpbmFsVXBkYXRlIiwicmVsYXRpb25VcGRhdGVzIiwidmFsaWRhdGVQZXJtaXNzaW9uIiwiY29sbGVjdFJlbGF0aW9uVXBkYXRlcyIsImFkZFBvaW50ZXJQZXJtaXNzaW9ucyIsImNhdGNoIiwiZXJyb3IiLCJyb290RmllbGROYW1lIiwiZmllbGROYW1lSXNWYWxpZCIsInVwZGF0ZU9wZXJhdGlvbiIsImlubmVyS2V5IiwiSU5WQUxJRF9ORVNURURfS0VZIiwiZmluZCIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ1cGRhdGVPYmplY3RzQnlRdWVyeSIsInVwc2VydE9uZU9iamVjdCIsImZpbmRPbmVBbmRVcGRhdGUiLCJoYW5kbGVSZWxhdGlvblVwZGF0ZXMiLCJvcHMiLCJkZWxldGVNZSIsInByb2Nlc3MiLCJvcCIsIngiLCJwZW5kaW5nIiwiYWRkUmVsYXRpb24iLCJyZW1vdmVSZWxhdGlvbiIsImFsbCIsImZyb21DbGFzc05hbWUiLCJmcm9tSWQiLCJ0b0lkIiwiZG9jIiwiY29kZSIsImRlc3Ryb3kiLCJwYXJzZUZvcm1hdFNjaGVtYSIsImNyZWF0ZSIsImNyZWF0ZWRBdCIsImlzbyIsIl9fdHlwZSIsInVwZGF0ZWRBdCIsImVuZm9yY2VDbGFzc0V4aXN0cyIsImNyZWF0ZU9iamVjdCIsImNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEiLCJjbGFzc1NjaGVtYSIsInNjaGVtYURhdGEiLCJzY2hlbWFGaWVsZHMiLCJuZXdLZXlzIiwiZmllbGQiLCJhY3Rpb24iLCJkZWxldGVFdmVyeXRoaW5nIiwiZmFzdCIsImRlbGV0ZUFsbENsYXNzZXMiLCJjbGVhciIsInJlbGF0ZWRJZHMiLCJxdWVyeU9wdGlvbnMiLCJza2lwIiwibGltaXQiLCJzb3J0IiwiZmluZE9wdGlvbnMiLCJjYW5Tb3J0T25Kb2luVGFibGVzIiwiX2lkIiwicmVzdWx0cyIsIm93bmluZ0lkcyIsInJlZHVjZUluUmVsYXRpb24iLCJvcnMiLCJhUXVlcnkiLCJpbmRleCIsInByb21pc2VzIiwicXVlcmllcyIsImNvbnN0cmFpbnRLZXkiLCJpc05lZ2F0aW9uIiwiciIsInEiLCJpZHMiLCJhZGROb3RJbk9iamVjdElkc0lkcyIsImFkZEluT2JqZWN0SWRzSWRzIiwicmVkdWNlUmVsYXRpb25LZXlzIiwicmVsYXRlZFRvIiwiaWRzRnJvbVN0cmluZyIsImlkc0Zyb21FcSIsImlkc0Zyb21JbiIsImFsbElkcyIsImxpc3QiLCJ0b3RhbExlbmd0aCIsInJlZHVjZSIsIm1lbW8iLCJpZHNJbnRlcnNlY3Rpb24iLCJpbnRlcnNlY3QiLCJiaWciLCIkZXEiLCJpZHNGcm9tTmluIiwiU2V0IiwiJG5pbiIsImNvdW50IiwiZGlzdGluY3QiLCJwaXBlbGluZSIsInJlYWRQcmVmZXJlbmNlIiwiaGludCIsImNhc2VJbnNlbnNpdGl2ZSIsImV4cGxhaW4iLCJfY3JlYXRlZF9hdCIsIl91cGRhdGVkX2F0IiwiYWRkUHJvdGVjdGVkRmllbGRzIiwiYWdncmVnYXRlIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiZGVsZXRlU2NoZW1hIiwiZGVsZXRlQ2xhc3MiLCJ3YXNQYXJzZUNvbGxlY3Rpb24iLCJyZWxhdGlvbkZpZWxkTmFtZXMiLCJuYW1lIiwib2JqZWN0VG9FbnRyaWVzU3RyaW5ncyIsImVudHJpZXMiLCJhIiwiSlNPTiIsInN0cmluZ2lmeSIsInJlZHVjZU9yT3BlcmF0aW9uIiwicmVwZWF0IiwiaSIsImoiLCJzaG9ydGVyIiwibG9uZ2VyIiwiZm91bmRFbnRyaWVzIiwiYWNjIiwic2hvcnRlckVudHJpZXMiLCJzcGxpY2UiLCJyZWR1Y2VBbmRPcGVyYXRpb24iLCJ0ZXN0UGVybWlzc2lvbnNGb3JDbGFzc05hbWUiLCJ1c2VyQUNMIiwiZ3JvdXBLZXkiLCJwZXJtRmllbGRzIiwicG9pbnRlckZpZWxkcyIsInVzZXJQb2ludGVyIiwiZmllbGREZXNjcmlwdG9yIiwiZmllbGRUeXBlIiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwicXVlcnlDbGF1c2UiLCIkYWxsIiwiYXNzaWduIiwicHJlc2VydmVLZXlzIiwic2VydmVyT25seUtleXMiLCJhdXRoZW50aWNhdGVkIiwicm9sZXMiLCJ1c2VyUm9sZXMiLCJwcm90ZWN0ZWRLZXlzU2V0cyIsInByb3RlY3RlZEtleXMiLCJuZXh0IiwiY3JlYXRlVHJhbnNhY3Rpb25hbFNlc3Npb24iLCJ0cmFuc2FjdGlvbmFsU2Vzc2lvbiIsImNvbW1pdFRyYW5zYWN0aW9uYWxTZXNzaW9uIiwiYWJvcnRUcmFuc2FjdGlvbmFsU2Vzc2lvbiIsInBlcmZvcm1Jbml0aWFsaXphdGlvbiIsInJlcXVpcmVkVXNlckZpZWxkcyIsImRlZmF1bHRDb2x1bW5zIiwiX0RlZmF1bHQiLCJfVXNlciIsInJlcXVpcmVkUm9sZUZpZWxkcyIsIl9Sb2xlIiwicmVxdWlyZWRJZGVtcG90ZW5jeUZpZWxkcyIsIl9JZGVtcG90ZW5jeSIsInVzZXJDbGFzc1Byb21pc2UiLCJyb2xlQ2xhc3NQcm9taXNlIiwiaWRlbXBvdGVuY3lDbGFzc1Byb21pc2UiLCJNb25nb1N0b3JhZ2VBZGFwdGVyIiwidXNlcm5hbWVVbmlxdWVuZXNzIiwiZW5zdXJlVW5pcXVlbmVzcyIsImxvZ2dlciIsIndhcm4iLCJ1c2VybmFtZUNhc2VJbnNlbnNpdGl2ZUluZGV4IiwiZW5zdXJlSW5kZXgiLCJlbWFpbFVuaXF1ZW5lc3MiLCJlbWFpbENhc2VJbnNlbnNpdGl2ZUluZGV4Iiwicm9sZVVuaXF1ZW5lc3MiLCJpZGVtcG90ZW5jeVJlcXVlc3RJZEluZGV4IiwiaWRlbXBvdGVuY3lFeHBpcmVJbmRleCIsInR0bCIsImluZGV4UHJvbWlzZSIsInVwZGF0ZVNjaGVtYVdpdGhJbmRleGVzIiwiYWRhcHRlckluaXQiLCJWb2xhdGlsZUNsYXNzZXNTY2hlbWFzIiwibW9kdWxlIiwiZXhwb3J0cyIsIl92YWxpZGF0ZVF1ZXJ5Il0sIm1hcHBpbmdzIjoiOztBQUtBOztBQUVBOztBQUVBOztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQTJOQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBeE5BLFNBQVNBLFdBQVQsQ0FBcUJDLEtBQXJCLEVBQTRCQyxHQUE1QixFQUFpQztBQUMvQixRQUFNQyxRQUFRLEdBQUdDLGdCQUFFQyxTQUFGLENBQVlKLEtBQVosQ0FBakIsQ0FEK0IsQ0FFL0I7OztBQUNBRSxFQUFBQSxRQUFRLENBQUNHLE1BQVQsR0FBa0I7QUFBRUMsSUFBQUEsR0FBRyxFQUFFLENBQUMsSUFBRCxFQUFPLEdBQUdMLEdBQVY7QUFBUCxHQUFsQjtBQUNBLFNBQU9DLFFBQVA7QUFDRDs7QUFFRCxTQUFTSyxVQUFULENBQW9CUCxLQUFwQixFQUEyQkMsR0FBM0IsRUFBZ0M7QUFDOUIsUUFBTUMsUUFBUSxHQUFHQyxnQkFBRUMsU0FBRixDQUFZSixLQUFaLENBQWpCLENBRDhCLENBRTlCOzs7QUFDQUUsRUFBQUEsUUFBUSxDQUFDTSxNQUFULEdBQWtCO0FBQUVGLElBQUFBLEdBQUcsRUFBRSxDQUFDLElBQUQsRUFBTyxHQUFQLEVBQVksR0FBR0wsR0FBZjtBQUFQLEdBQWxCO0FBQ0EsU0FBT0MsUUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0EsTUFBTU8sa0JBQWtCLEdBQUcsVUFBd0I7QUFBQSxNQUF2QjtBQUFFQyxJQUFBQTtBQUFGLEdBQXVCO0FBQUEsTUFBYkMsTUFBYTs7QUFDakQsTUFBSSxDQUFDRCxHQUFMLEVBQVU7QUFDUixXQUFPQyxNQUFQO0FBQ0Q7O0FBRURBLEVBQUFBLE1BQU0sQ0FBQ04sTUFBUCxHQUFnQixFQUFoQjtBQUNBTSxFQUFBQSxNQUFNLENBQUNILE1BQVAsR0FBZ0IsRUFBaEI7O0FBRUEsT0FBSyxNQUFNSSxLQUFYLElBQW9CRixHQUFwQixFQUF5QjtBQUN2QixRQUFJQSxHQUFHLENBQUNFLEtBQUQsQ0FBSCxDQUFXQyxJQUFmLEVBQXFCO0FBQ25CRixNQUFBQSxNQUFNLENBQUNILE1BQVAsQ0FBY00sSUFBZCxDQUFtQkYsS0FBbkI7QUFDRDs7QUFDRCxRQUFJRixHQUFHLENBQUNFLEtBQUQsQ0FBSCxDQUFXRyxLQUFmLEVBQXNCO0FBQ3BCSixNQUFBQSxNQUFNLENBQUNOLE1BQVAsQ0FBY1MsSUFBZCxDQUFtQkYsS0FBbkI7QUFDRDtBQUNGOztBQUNELFNBQU9ELE1BQVA7QUFDRCxDQWpCRDs7QUFtQkEsTUFBTUssZ0JBQWdCLEdBQUcsQ0FDdkIsTUFEdUIsRUFFdkIsS0FGdUIsRUFHdkIsTUFIdUIsRUFJdkIsUUFKdUIsRUFLdkIsUUFMdUIsRUFNdkIsbUJBTnVCLEVBT3ZCLHFCQVB1QixFQVF2QixnQ0FSdUIsRUFTdkIsNkJBVHVCLEVBVXZCLHFCQVZ1QixDQUF6Qjs7QUFhQSxNQUFNQyxpQkFBaUIsR0FBR0MsR0FBRyxJQUFJO0FBQy9CLFNBQU9GLGdCQUFnQixDQUFDRyxPQUFqQixDQUF5QkQsR0FBekIsS0FBaUMsQ0FBeEM7QUFDRCxDQUZEOztBQUlBLE1BQU1FLGFBQWEsR0FBSXBCLEtBQUQsSUFBc0I7QUFDMUMsTUFBSUEsS0FBSyxDQUFDVSxHQUFWLEVBQWU7QUFDYixVQUFNLElBQUlXLFlBQU1DLEtBQVYsQ0FBZ0JELFlBQU1DLEtBQU4sQ0FBWUMsYUFBNUIsRUFBMkMsc0JBQTNDLENBQU47QUFDRDs7QUFFRCxNQUFJdkIsS0FBSyxDQUFDd0IsR0FBVixFQUFlO0FBQ2IsUUFBSXhCLEtBQUssQ0FBQ3dCLEdBQU4sWUFBcUJDLEtBQXpCLEVBQWdDO0FBQzlCekIsTUFBQUEsS0FBSyxDQUFDd0IsR0FBTixDQUFVRSxPQUFWLENBQWtCTixhQUFsQjtBQUNELEtBRkQsTUFFTztBQUNMLFlBQU0sSUFBSUMsWUFBTUMsS0FBVixDQUFnQkQsWUFBTUMsS0FBTixDQUFZQyxhQUE1QixFQUEyQyxzQ0FBM0MsQ0FBTjtBQUNEO0FBQ0Y7O0FBRUQsTUFBSXZCLEtBQUssQ0FBQzJCLElBQVYsRUFBZ0I7QUFDZCxRQUFJM0IsS0FBSyxDQUFDMkIsSUFBTixZQUFzQkYsS0FBMUIsRUFBaUM7QUFDL0J6QixNQUFBQSxLQUFLLENBQUMyQixJQUFOLENBQVdELE9BQVgsQ0FBbUJOLGFBQW5CO0FBQ0QsS0FGRCxNQUVPO0FBQ0wsWUFBTSxJQUFJQyxZQUFNQyxLQUFWLENBQWdCRCxZQUFNQyxLQUFOLENBQVlDLGFBQTVCLEVBQTJDLHVDQUEzQyxDQUFOO0FBQ0Q7QUFDRjs7QUFFRCxNQUFJdkIsS0FBSyxDQUFDNEIsSUFBVixFQUFnQjtBQUNkLFFBQUk1QixLQUFLLENBQUM0QixJQUFOLFlBQXNCSCxLQUF0QixJQUErQnpCLEtBQUssQ0FBQzRCLElBQU4sQ0FBV0MsTUFBWCxHQUFvQixDQUF2RCxFQUEwRDtBQUN4RDdCLE1BQUFBLEtBQUssQ0FBQzRCLElBQU4sQ0FBV0YsT0FBWCxDQUFtQk4sYUFBbkI7QUFDRCxLQUZELE1BRU87QUFDTCxZQUFNLElBQUlDLFlBQU1DLEtBQVYsQ0FDSkQsWUFBTUMsS0FBTixDQUFZQyxhQURSLEVBRUoscURBRkksQ0FBTjtBQUlEO0FBQ0Y7O0FBRURPLEVBQUFBLE1BQU0sQ0FBQ0MsSUFBUCxDQUFZL0IsS0FBWixFQUFtQjBCLE9BQW5CLENBQTJCUixHQUFHLElBQUk7QUFDaEMsUUFBSWxCLEtBQUssSUFBSUEsS0FBSyxDQUFDa0IsR0FBRCxDQUFkLElBQXVCbEIsS0FBSyxDQUFDa0IsR0FBRCxDQUFMLENBQVdjLE1BQXRDLEVBQThDO0FBQzVDLFVBQUksT0FBT2hDLEtBQUssQ0FBQ2tCLEdBQUQsQ0FBTCxDQUFXZSxRQUFsQixLQUErQixRQUFuQyxFQUE2QztBQUMzQyxZQUFJLENBQUNqQyxLQUFLLENBQUNrQixHQUFELENBQUwsQ0FBV2UsUUFBWCxDQUFvQkMsS0FBcEIsQ0FBMEIsV0FBMUIsQ0FBTCxFQUE2QztBQUMzQyxnQkFBTSxJQUFJYixZQUFNQyxLQUFWLENBQ0pELFlBQU1DLEtBQU4sQ0FBWUMsYUFEUixFQUVILGlDQUFnQ3ZCLEtBQUssQ0FBQ2tCLEdBQUQsQ0FBTCxDQUFXZSxRQUFTLEVBRmpELENBQU47QUFJRDtBQUNGO0FBQ0Y7O0FBQ0QsUUFBSSxDQUFDaEIsaUJBQWlCLENBQUNDLEdBQUQsQ0FBbEIsSUFBMkIsQ0FBQ0EsR0FBRyxDQUFDZ0IsS0FBSixDQUFVLDJCQUFWLENBQWhDLEVBQXdFO0FBQ3RFLFlBQU0sSUFBSWIsWUFBTUMsS0FBVixDQUFnQkQsWUFBTUMsS0FBTixDQUFZYSxnQkFBNUIsRUFBK0MscUJBQW9CakIsR0FBSSxFQUF2RSxDQUFOO0FBQ0Q7QUFDRixHQWREO0FBZUQsQ0EvQ0QsQyxDQWlEQTs7O0FBQ0EsTUFBTWtCLG1CQUFtQixHQUFHLENBQzFCQyxRQUQwQixFQUUxQkMsUUFGMEIsRUFHMUJDLElBSDBCLEVBSTFCQyxTQUowQixFQUsxQkMsTUFMMEIsRUFNMUJDLFNBTjBCLEVBTzFCQyxlQVAwQixFQVExQkMsTUFSMEIsS0FTdkI7QUFDSCxNQUFJQyxNQUFNLEdBQUcsSUFBYjtBQUNBLE1BQUlOLElBQUksSUFBSUEsSUFBSSxDQUFDTyxJQUFqQixFQUF1QkQsTUFBTSxHQUFHTixJQUFJLENBQUNPLElBQUwsQ0FBVUMsRUFBbkIsQ0FGcEIsQ0FJSDs7QUFDQSxRQUFNQyxLQUFLLEdBQUdQLE1BQU0sQ0FBQ1Esd0JBQVAsQ0FBZ0NQLFNBQWhDLENBQWQ7O0FBQ0EsTUFBSU0sS0FBSixFQUFXO0FBQ1QsVUFBTUUsZUFBZSxHQUFHLENBQUMsS0FBRCxFQUFRLE1BQVIsRUFBZ0IvQixPQUFoQixDQUF3QnFCLFNBQXhCLElBQXFDLENBQUMsQ0FBOUQ7O0FBRUEsUUFBSVUsZUFBZSxJQUFJRixLQUFLLENBQUNMLGVBQTdCLEVBQThDO0FBQzVDO0FBQ0EsWUFBTVEsMEJBQTBCLEdBQUdyQixNQUFNLENBQUNDLElBQVAsQ0FBWWlCLEtBQUssQ0FBQ0wsZUFBbEIsRUFDaENTLE1BRGdDLENBQ3pCbEMsR0FBRyxJQUFJQSxHQUFHLENBQUNtQyxVQUFKLENBQWUsWUFBZixDQURrQixFQUVoQ0MsR0FGZ0MsQ0FFNUJwQyxHQUFHLElBQUk7QUFDVixlQUFPO0FBQUVBLFVBQUFBLEdBQUcsRUFBRUEsR0FBRyxDQUFDcUMsU0FBSixDQUFjLEVBQWQsQ0FBUDtBQUEwQkMsVUFBQUEsS0FBSyxFQUFFUixLQUFLLENBQUNMLGVBQU4sQ0FBc0J6QixHQUF0QjtBQUFqQyxTQUFQO0FBQ0QsT0FKZ0MsQ0FBbkM7QUFNQSxZQUFNdUMsa0JBQW1DLEdBQUcsRUFBNUM7QUFDQSxVQUFJQyx1QkFBdUIsR0FBRyxLQUE5QixDQVQ0QyxDQVc1Qzs7QUFDQVAsTUFBQUEsMEJBQTBCLENBQUN6QixPQUEzQixDQUFtQ2lDLFdBQVcsSUFBSTtBQUNoRCxZQUFJQyx1QkFBdUIsR0FBRyxLQUE5QjtBQUNBLGNBQU1DLGtCQUFrQixHQUFHakIsTUFBTSxDQUFDZSxXQUFXLENBQUN6QyxHQUFiLENBQWpDOztBQUNBLFlBQUkyQyxrQkFBSixFQUF3QjtBQUN0QixjQUFJcEMsS0FBSyxDQUFDcUMsT0FBTixDQUFjRCxrQkFBZCxDQUFKLEVBQXVDO0FBQ3JDRCxZQUFBQSx1QkFBdUIsR0FBR0Msa0JBQWtCLENBQUNFLElBQW5CLENBQ3hCakIsSUFBSSxJQUFJQSxJQUFJLENBQUNrQixRQUFMLElBQWlCbEIsSUFBSSxDQUFDa0IsUUFBTCxLQUFrQm5CLE1BRG5CLENBQTFCO0FBR0QsV0FKRCxNQUlPO0FBQ0xlLFlBQUFBLHVCQUF1QixHQUNyQkMsa0JBQWtCLENBQUNHLFFBQW5CLElBQStCSCxrQkFBa0IsQ0FBQ0csUUFBbkIsS0FBZ0NuQixNQURqRTtBQUVEO0FBQ0Y7O0FBRUQsWUFBSWUsdUJBQUosRUFBNkI7QUFDM0JGLFVBQUFBLHVCQUF1QixHQUFHLElBQTFCO0FBQ0FELFVBQUFBLGtCQUFrQixDQUFDM0MsSUFBbkIsQ0FBd0I2QyxXQUFXLENBQUNILEtBQXBDO0FBQ0Q7QUFDRixPQWxCRCxFQVo0QyxDQWdDNUM7QUFDQTtBQUNBOztBQUNBLFVBQUlFLHVCQUF1QixJQUFJZixlQUEvQixFQUFnRDtBQUM5Q2MsUUFBQUEsa0JBQWtCLENBQUMzQyxJQUFuQixDQUF3QjZCLGVBQXhCO0FBQ0QsT0FyQzJDLENBc0M1Qzs7O0FBQ0FjLE1BQUFBLGtCQUFrQixDQUFDL0IsT0FBbkIsQ0FBMkJ1QyxNQUFNLElBQUk7QUFDbkMsWUFBSUEsTUFBSixFQUFZO0FBQ1Y7QUFDQTtBQUNBLGNBQUksQ0FBQ3RCLGVBQUwsRUFBc0I7QUFDcEJBLFlBQUFBLGVBQWUsR0FBR3NCLE1BQWxCO0FBQ0QsV0FGRCxNQUVPO0FBQ0x0QixZQUFBQSxlQUFlLEdBQUdBLGVBQWUsQ0FBQ1MsTUFBaEIsQ0FBdUJjLENBQUMsSUFBSUQsTUFBTSxDQUFDRSxRQUFQLENBQWdCRCxDQUFoQixDQUE1QixDQUFsQjtBQUNEO0FBQ0Y7QUFDRixPQVZEO0FBV0Q7QUFDRjs7QUFFRCxRQUFNRSxXQUFXLEdBQUcxQixTQUFTLEtBQUssT0FBbEM7QUFFQTtBQUNGOztBQUNFLE1BQUksRUFBRTBCLFdBQVcsSUFBSXZCLE1BQWYsSUFBeUJELE1BQU0sQ0FBQ29CLFFBQVAsS0FBb0JuQixNQUEvQyxDQUFKLEVBQTREO0FBQzFERixJQUFBQSxlQUFlLElBQUlBLGVBQWUsQ0FBQ2pCLE9BQWhCLENBQXdCMkMsQ0FBQyxJQUFJLE9BQU96QixNQUFNLENBQUN5QixDQUFELENBQTFDLENBQW5CLENBRDBELENBRzFEO0FBQ0E7O0FBQ0FyQixJQUFBQSxLQUFLLENBQUNMLGVBQU4sSUFDRUssS0FBSyxDQUFDTCxlQUFOLENBQXNCMkIsYUFEeEIsSUFFRXRCLEtBQUssQ0FBQ0wsZUFBTixDQUFzQjJCLGFBQXRCLENBQW9DNUMsT0FBcEMsQ0FBNEMyQyxDQUFDLElBQUksT0FBT3pCLE1BQU0sQ0FBQ3lCLENBQUQsQ0FBOUQsQ0FGRjtBQUdEOztBQUVELE1BQUksQ0FBQ0QsV0FBTCxFQUFrQjtBQUNoQixXQUFPeEIsTUFBUDtBQUNEOztBQUVEQSxFQUFBQSxNQUFNLENBQUMyQixRQUFQLEdBQWtCM0IsTUFBTSxDQUFDNEIsZ0JBQXpCO0FBQ0EsU0FBTzVCLE1BQU0sQ0FBQzRCLGdCQUFkO0FBRUEsU0FBTzVCLE1BQU0sQ0FBQzZCLFlBQWQ7O0FBRUEsTUFBSXBDLFFBQUosRUFBYztBQUNaLFdBQU9PLE1BQVA7QUFDRDs7QUFDRCxTQUFPQSxNQUFNLENBQUM4QixtQkFBZDtBQUNBLFNBQU85QixNQUFNLENBQUMrQixpQkFBZDtBQUNBLFNBQU8vQixNQUFNLENBQUNnQyw0QkFBZDtBQUNBLFNBQU9oQyxNQUFNLENBQUNpQyxVQUFkO0FBQ0EsU0FBT2pDLE1BQU0sQ0FBQ2tDLDhCQUFkO0FBQ0EsU0FBT2xDLE1BQU0sQ0FBQ21DLG1CQUFkO0FBQ0EsU0FBT25DLE1BQU0sQ0FBQ29DLDJCQUFkO0FBQ0EsU0FBT3BDLE1BQU0sQ0FBQ3FDLG9CQUFkO0FBQ0EsU0FBT3JDLE1BQU0sQ0FBQ3NDLGlCQUFkOztBQUVBLE1BQUk1QyxRQUFRLENBQUNuQixPQUFULENBQWlCeUIsTUFBTSxDQUFDb0IsUUFBeEIsSUFBb0MsQ0FBQyxDQUF6QyxFQUE0QztBQUMxQyxXQUFPcEIsTUFBUDtBQUNEOztBQUNELFNBQU9BLE1BQU0sQ0FBQ3VDLFFBQWQ7QUFDQSxTQUFPdkMsTUFBUDtBQUNELENBaEhEOztBQXFIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTXdDLG9CQUFvQixHQUFHLENBQzNCLGtCQUQyQixFQUUzQixtQkFGMkIsRUFHM0IscUJBSDJCLEVBSTNCLGdDQUoyQixFQUszQiw2QkFMMkIsRUFNM0IscUJBTjJCLEVBTzNCLDhCQVAyQixFQVEzQixzQkFSMkIsRUFTM0IsbUJBVDJCLENBQTdCOztBQVlBLE1BQU1DLGtCQUFrQixHQUFHbkUsR0FBRyxJQUFJO0FBQ2hDLFNBQU9rRSxvQkFBb0IsQ0FBQ2pFLE9BQXJCLENBQTZCRCxHQUE3QixLQUFxQyxDQUE1QztBQUNELENBRkQ7O0FBSUEsU0FBU29FLHFCQUFULENBQStCMUMsTUFBL0IsRUFBdUMxQixHQUF2QyxFQUE0Q3NDLEtBQTVDLEVBQW1EO0FBQ2pELE1BQUl0QyxHQUFHLENBQUNDLE9BQUosQ0FBWSxHQUFaLElBQW1CLENBQXZCLEVBQTBCO0FBQ3hCeUIsSUFBQUEsTUFBTSxDQUFDMUIsR0FBRCxDQUFOLEdBQWNzQyxLQUFLLENBQUN0QyxHQUFELENBQW5CO0FBQ0EsV0FBTzBCLE1BQVA7QUFDRDs7QUFDRCxRQUFNMkMsSUFBSSxHQUFHckUsR0FBRyxDQUFDc0UsS0FBSixDQUFVLEdBQVYsQ0FBYjtBQUNBLFFBQU1DLFFBQVEsR0FBR0YsSUFBSSxDQUFDLENBQUQsQ0FBckI7QUFDQSxRQUFNRyxRQUFRLEdBQUdILElBQUksQ0FBQ0ksS0FBTCxDQUFXLENBQVgsRUFBY0MsSUFBZCxDQUFtQixHQUFuQixDQUFqQjtBQUNBaEQsRUFBQUEsTUFBTSxDQUFDNkMsUUFBRCxDQUFOLEdBQW1CSCxxQkFBcUIsQ0FBQzFDLE1BQU0sQ0FBQzZDLFFBQUQsQ0FBTixJQUFvQixFQUFyQixFQUF5QkMsUUFBekIsRUFBbUNsQyxLQUFLLENBQUNpQyxRQUFELENBQXhDLENBQXhDO0FBQ0EsU0FBTzdDLE1BQU0sQ0FBQzFCLEdBQUQsQ0FBYjtBQUNBLFNBQU8wQixNQUFQO0FBQ0Q7O0FBRUQsU0FBU2lELHNCQUFULENBQWdDQyxjQUFoQyxFQUFnRG5GLE1BQWhELEVBQXNFO0FBQ3BFLFFBQU1vRixRQUFRLEdBQUcsRUFBakI7O0FBQ0EsTUFBSSxDQUFDcEYsTUFBTCxFQUFhO0FBQ1gsV0FBT3FGLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQkYsUUFBaEIsQ0FBUDtBQUNEOztBQUNEakUsRUFBQUEsTUFBTSxDQUFDQyxJQUFQLENBQVkrRCxjQUFaLEVBQTRCcEUsT0FBNUIsQ0FBb0NSLEdBQUcsSUFBSTtBQUN6QyxVQUFNZ0YsU0FBUyxHQUFHSixjQUFjLENBQUM1RSxHQUFELENBQWhDLENBRHlDLENBRXpDOztBQUNBLFFBQ0VnRixTQUFTLElBQ1QsT0FBT0EsU0FBUCxLQUFxQixRQURyQixJQUVBQSxTQUFTLENBQUNDLElBRlYsSUFHQSxDQUFDLEtBQUQsRUFBUSxXQUFSLEVBQXFCLFFBQXJCLEVBQStCLFdBQS9CLEVBQTRDaEYsT0FBNUMsQ0FBb0QrRSxTQUFTLENBQUNDLElBQTlELElBQXNFLENBQUMsQ0FKekUsRUFLRTtBQUNBO0FBQ0E7QUFDQWIsTUFBQUEscUJBQXFCLENBQUNTLFFBQUQsRUFBVzdFLEdBQVgsRUFBZ0JQLE1BQWhCLENBQXJCO0FBQ0Q7QUFDRixHQWJEO0FBY0EsU0FBT3FGLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQkYsUUFBaEIsQ0FBUDtBQUNEOztBQUVELFNBQVNLLGFBQVQsQ0FBdUIxRCxTQUF2QixFQUFrQ3hCLEdBQWxDLEVBQXVDO0FBQ3JDLFNBQVEsU0FBUUEsR0FBSSxJQUFHd0IsU0FBVSxFQUFqQztBQUNEOztBQUVELE1BQU0yRCwrQkFBK0IsR0FBR3pELE1BQU0sSUFBSTtBQUNoRCxPQUFLLE1BQU0xQixHQUFYLElBQWtCMEIsTUFBbEIsRUFBMEI7QUFDeEIsUUFBSUEsTUFBTSxDQUFDMUIsR0FBRCxDQUFOLElBQWUwQixNQUFNLENBQUMxQixHQUFELENBQU4sQ0FBWWlGLElBQS9CLEVBQXFDO0FBQ25DLGNBQVF2RCxNQUFNLENBQUMxQixHQUFELENBQU4sQ0FBWWlGLElBQXBCO0FBQ0UsYUFBSyxXQUFMO0FBQ0UsY0FBSSxPQUFPdkQsTUFBTSxDQUFDMUIsR0FBRCxDQUFOLENBQVlvRixNQUFuQixLQUE4QixRQUFsQyxFQUE0QztBQUMxQyxrQkFBTSxJQUFJakYsWUFBTUMsS0FBVixDQUFnQkQsWUFBTUMsS0FBTixDQUFZaUYsWUFBNUIsRUFBMEMsaUNBQTFDLENBQU47QUFDRDs7QUFDRDNELFVBQUFBLE1BQU0sQ0FBQzFCLEdBQUQsQ0FBTixHQUFjMEIsTUFBTSxDQUFDMUIsR0FBRCxDQUFOLENBQVlvRixNQUExQjtBQUNBOztBQUNGLGFBQUssS0FBTDtBQUNFLGNBQUksRUFBRTFELE1BQU0sQ0FBQzFCLEdBQUQsQ0FBTixDQUFZc0YsT0FBWixZQUErQi9FLEtBQWpDLENBQUosRUFBNkM7QUFDM0Msa0JBQU0sSUFBSUosWUFBTUMsS0FBVixDQUFnQkQsWUFBTUMsS0FBTixDQUFZaUYsWUFBNUIsRUFBMEMsaUNBQTFDLENBQU47QUFDRDs7QUFDRDNELFVBQUFBLE1BQU0sQ0FBQzFCLEdBQUQsQ0FBTixHQUFjMEIsTUFBTSxDQUFDMUIsR0FBRCxDQUFOLENBQVlzRixPQUExQjtBQUNBOztBQUNGLGFBQUssV0FBTDtBQUNFLGNBQUksRUFBRTVELE1BQU0sQ0FBQzFCLEdBQUQsQ0FBTixDQUFZc0YsT0FBWixZQUErQi9FLEtBQWpDLENBQUosRUFBNkM7QUFDM0Msa0JBQU0sSUFBSUosWUFBTUMsS0FBVixDQUFnQkQsWUFBTUMsS0FBTixDQUFZaUYsWUFBNUIsRUFBMEMsaUNBQTFDLENBQU47QUFDRDs7QUFDRDNELFVBQUFBLE1BQU0sQ0FBQzFCLEdBQUQsQ0FBTixHQUFjMEIsTUFBTSxDQUFDMUIsR0FBRCxDQUFOLENBQVlzRixPQUExQjtBQUNBOztBQUNGLGFBQUssUUFBTDtBQUNFLGNBQUksRUFBRTVELE1BQU0sQ0FBQzFCLEdBQUQsQ0FBTixDQUFZc0YsT0FBWixZQUErQi9FLEtBQWpDLENBQUosRUFBNkM7QUFDM0Msa0JBQU0sSUFBSUosWUFBTUMsS0FBVixDQUFnQkQsWUFBTUMsS0FBTixDQUFZaUYsWUFBNUIsRUFBMEMsaUNBQTFDLENBQU47QUFDRDs7QUFDRDNELFVBQUFBLE1BQU0sQ0FBQzFCLEdBQUQsQ0FBTixHQUFjLEVBQWQ7QUFDQTs7QUFDRixhQUFLLFFBQUw7QUFDRSxpQkFBTzBCLE1BQU0sQ0FBQzFCLEdBQUQsQ0FBYjtBQUNBOztBQUNGO0FBQ0UsZ0JBQU0sSUFBSUcsWUFBTUMsS0FBVixDQUNKRCxZQUFNQyxLQUFOLENBQVltRixtQkFEUixFQUVILE9BQU03RCxNQUFNLENBQUMxQixHQUFELENBQU4sQ0FBWWlGLElBQUssaUNBRnBCLENBQU47QUE3Qko7QUFrQ0Q7QUFDRjtBQUNGLENBdkNEOztBQXlDQSxNQUFNTyxpQkFBaUIsR0FBRyxDQUFDaEUsU0FBRCxFQUFZRSxNQUFaLEVBQW9CSCxNQUFwQixLQUErQjtBQUN2RCxNQUFJRyxNQUFNLENBQUN1QyxRQUFQLElBQW1CekMsU0FBUyxLQUFLLE9BQXJDLEVBQThDO0FBQzVDWixJQUFBQSxNQUFNLENBQUNDLElBQVAsQ0FBWWEsTUFBTSxDQUFDdUMsUUFBbkIsRUFBNkJ6RCxPQUE3QixDQUFxQ2lGLFFBQVEsSUFBSTtBQUMvQyxZQUFNQyxZQUFZLEdBQUdoRSxNQUFNLENBQUN1QyxRQUFQLENBQWdCd0IsUUFBaEIsQ0FBckI7QUFDQSxZQUFNRSxTQUFTLEdBQUksY0FBYUYsUUFBUyxFQUF6Qzs7QUFDQSxVQUFJQyxZQUFZLElBQUksSUFBcEIsRUFBMEI7QUFDeEJoRSxRQUFBQSxNQUFNLENBQUNpRSxTQUFELENBQU4sR0FBb0I7QUFDbEJWLFVBQUFBLElBQUksRUFBRTtBQURZLFNBQXBCO0FBR0QsT0FKRCxNQUlPO0FBQ0x2RCxRQUFBQSxNQUFNLENBQUNpRSxTQUFELENBQU4sR0FBb0JELFlBQXBCO0FBQ0FuRSxRQUFBQSxNQUFNLENBQUN3QixNQUFQLENBQWM0QyxTQUFkLElBQTJCO0FBQUVDLFVBQUFBLElBQUksRUFBRTtBQUFSLFNBQTNCO0FBQ0Q7QUFDRixLQVhEO0FBWUEsV0FBT2xFLE1BQU0sQ0FBQ3VDLFFBQWQ7QUFDRDtBQUNGLENBaEJELEMsQ0FpQkE7OztBQUNBLE1BQU00QixvQkFBb0IsR0FBRyxXQUFtQztBQUFBLE1BQWxDO0FBQUV2RyxJQUFBQSxNQUFGO0FBQVVILElBQUFBO0FBQVYsR0FBa0M7QUFBQSxNQUFiMkcsTUFBYTs7QUFDOUQsTUFBSXhHLE1BQU0sSUFBSUgsTUFBZCxFQUFzQjtBQUNwQjJHLElBQUFBLE1BQU0sQ0FBQ3RHLEdBQVAsR0FBYSxFQUFiOztBQUVBLEtBQUNGLE1BQU0sSUFBSSxFQUFYLEVBQWVrQixPQUFmLENBQXVCZCxLQUFLLElBQUk7QUFDOUIsVUFBSSxDQUFDb0csTUFBTSxDQUFDdEcsR0FBUCxDQUFXRSxLQUFYLENBQUwsRUFBd0I7QUFDdEJvRyxRQUFBQSxNQUFNLENBQUN0RyxHQUFQLENBQVdFLEtBQVgsSUFBb0I7QUFBRUMsVUFBQUEsSUFBSSxFQUFFO0FBQVIsU0FBcEI7QUFDRCxPQUZELE1BRU87QUFDTG1HLFFBQUFBLE1BQU0sQ0FBQ3RHLEdBQVAsQ0FBV0UsS0FBWCxFQUFrQixNQUFsQixJQUE0QixJQUE1QjtBQUNEO0FBQ0YsS0FORDs7QUFRQSxLQUFDUCxNQUFNLElBQUksRUFBWCxFQUFlcUIsT0FBZixDQUF1QmQsS0FBSyxJQUFJO0FBQzlCLFVBQUksQ0FBQ29HLE1BQU0sQ0FBQ3RHLEdBQVAsQ0FBV0UsS0FBWCxDQUFMLEVBQXdCO0FBQ3RCb0csUUFBQUEsTUFBTSxDQUFDdEcsR0FBUCxDQUFXRSxLQUFYLElBQW9CO0FBQUVHLFVBQUFBLEtBQUssRUFBRTtBQUFULFNBQXBCO0FBQ0QsT0FGRCxNQUVPO0FBQ0xpRyxRQUFBQSxNQUFNLENBQUN0RyxHQUFQLENBQVdFLEtBQVgsRUFBa0IsT0FBbEIsSUFBNkIsSUFBN0I7QUFDRDtBQUNGLEtBTkQ7QUFPRDs7QUFDRCxTQUFPb0csTUFBUDtBQUNELENBckJEO0FBdUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0EsTUFBTUMsZ0JBQWdCLEdBQUlKLFNBQUQsSUFBK0I7QUFDdEQsU0FBT0EsU0FBUyxDQUFDckIsS0FBVixDQUFnQixHQUFoQixFQUFxQixDQUFyQixDQUFQO0FBQ0QsQ0FGRDs7QUFJQSxNQUFNMEIsY0FBYyxHQUFHO0FBQ3JCakQsRUFBQUEsTUFBTSxFQUFFO0FBQUVrRCxJQUFBQSxTQUFTLEVBQUU7QUFBRUwsTUFBQUEsSUFBSSxFQUFFO0FBQVIsS0FBYjtBQUFpQ00sSUFBQUEsUUFBUSxFQUFFO0FBQUVOLE1BQUFBLElBQUksRUFBRTtBQUFSO0FBQTNDO0FBRGEsQ0FBdkI7O0FBSUEsTUFBTU8sa0JBQU4sQ0FBeUI7QUFNdkJDLEVBQUFBLFdBQVcsQ0FBQ0MsT0FBRCxFQUEwQkMsV0FBMUIsRUFBNEM7QUFDckQsU0FBS0QsT0FBTCxHQUFlQSxPQUFmO0FBQ0EsU0FBS0MsV0FBTCxHQUFtQkEsV0FBbkIsQ0FGcUQsQ0FHckQ7QUFDQTtBQUNBOztBQUNBLFNBQUtDLGFBQUwsR0FBcUIsSUFBckI7QUFDQSxTQUFLQyxxQkFBTCxHQUE2QixJQUE3QjtBQUNEOztBQUVEQyxFQUFBQSxnQkFBZ0IsQ0FBQ2pGLFNBQUQsRUFBc0M7QUFDcEQsV0FBTyxLQUFLNkUsT0FBTCxDQUFhSyxXQUFiLENBQXlCbEYsU0FBekIsQ0FBUDtBQUNEOztBQUVEbUYsRUFBQUEsZUFBZSxDQUFDbkYsU0FBRCxFQUFtQztBQUNoRCxXQUFPLEtBQUtvRixVQUFMLEdBQ0pDLElBREksQ0FDQ0MsZ0JBQWdCLElBQUlBLGdCQUFnQixDQUFDQyxZQUFqQixDQUE4QnZGLFNBQTlCLENBRHJCLEVBRUpxRixJQUZJLENBRUN0RixNQUFNLElBQUksS0FBSzhFLE9BQUwsQ0FBYVcsb0JBQWIsQ0FBa0N4RixTQUFsQyxFQUE2Q0QsTUFBN0MsRUFBcUQsRUFBckQsQ0FGWCxDQUFQO0FBR0Q7O0FBRUQwRixFQUFBQSxpQkFBaUIsQ0FBQ3pGLFNBQUQsRUFBbUM7QUFDbEQsUUFBSSxDQUFDMEYsZ0JBQWdCLENBQUNDLGdCQUFqQixDQUFrQzNGLFNBQWxDLENBQUwsRUFBbUQ7QUFDakQsYUFBT3NELE9BQU8sQ0FBQ3NDLE1BQVIsQ0FDTCxJQUFJakgsWUFBTUMsS0FBVixDQUFnQkQsWUFBTUMsS0FBTixDQUFZaUgsa0JBQTVCLEVBQWdELHdCQUF3QjdGLFNBQXhFLENBREssQ0FBUDtBQUdEOztBQUNELFdBQU9zRCxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELEdBakNzQixDQW1DdkI7OztBQUNBNkIsRUFBQUEsVUFBVSxDQUNSVSxPQUEwQixHQUFHO0FBQUVDLElBQUFBLFVBQVUsRUFBRTtBQUFkLEdBRHJCLEVBRW9DO0FBQzVDLFFBQUksS0FBS2hCLGFBQUwsSUFBc0IsSUFBMUIsRUFBZ0M7QUFDOUIsYUFBTyxLQUFLQSxhQUFaO0FBQ0Q7O0FBQ0QsU0FBS0EsYUFBTCxHQUFxQlcsZ0JBQWdCLENBQUNNLElBQWpCLENBQXNCLEtBQUtuQixPQUEzQixFQUFvQyxLQUFLQyxXQUF6QyxFQUFzRGdCLE9BQXRELENBQXJCO0FBQ0EsU0FBS2YsYUFBTCxDQUFtQk0sSUFBbkIsQ0FDRSxNQUFNLE9BQU8sS0FBS04sYUFEcEIsRUFFRSxNQUFNLE9BQU8sS0FBS0EsYUFGcEI7QUFJQSxXQUFPLEtBQUtLLFVBQUwsQ0FBZ0JVLE9BQWhCLENBQVA7QUFDRDs7QUFFREcsRUFBQUEsa0JBQWtCLENBQ2hCWCxnQkFEZ0IsRUFFaEJRLE9BQTBCLEdBQUc7QUFBRUMsSUFBQUEsVUFBVSxFQUFFO0FBQWQsR0FGYixFQUc0QjtBQUM1QyxXQUFPVCxnQkFBZ0IsR0FBR2hDLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQitCLGdCQUFoQixDQUFILEdBQXVDLEtBQUtGLFVBQUwsQ0FBZ0JVLE9BQWhCLENBQTlEO0FBQ0QsR0F2RHNCLENBeUR2QjtBQUNBO0FBQ0E7OztBQUNBSSxFQUFBQSx1QkFBdUIsQ0FBQ2xHLFNBQUQsRUFBb0J4QixHQUFwQixFQUFtRDtBQUN4RSxXQUFPLEtBQUs0RyxVQUFMLEdBQWtCQyxJQUFsQixDQUF1QnRGLE1BQU0sSUFBSTtBQUN0QyxVQUFJb0csQ0FBQyxHQUFHcEcsTUFBTSxDQUFDcUcsZUFBUCxDQUF1QnBHLFNBQXZCLEVBQWtDeEIsR0FBbEMsQ0FBUjs7QUFDQSxVQUFJMkgsQ0FBQyxJQUFJLElBQUwsSUFBYSxPQUFPQSxDQUFQLEtBQWEsUUFBMUIsSUFBc0NBLENBQUMsQ0FBQy9CLElBQUYsS0FBVyxVQUFyRCxFQUFpRTtBQUMvRCxlQUFPK0IsQ0FBQyxDQUFDRSxXQUFUO0FBQ0Q7O0FBQ0QsYUFBT3JHLFNBQVA7QUFDRCxLQU5NLENBQVA7QUFPRCxHQXBFc0IsQ0FzRXZCO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQXNHLEVBQUFBLGNBQWMsQ0FDWnRHLFNBRFksRUFFWkUsTUFGWSxFQUdaNUMsS0FIWSxFQUlaaUosVUFKWSxFQUtNO0FBQ2xCLFFBQUl4RyxNQUFKO0FBQ0EsVUFBTXhDLEdBQUcsR0FBR2dKLFVBQVUsQ0FBQ2hKLEdBQXZCO0FBQ0EsVUFBTW9DLFFBQVEsR0FBR3BDLEdBQUcsS0FBS2lKLFNBQXpCO0FBQ0EsUUFBSTVHLFFBQWtCLEdBQUdyQyxHQUFHLElBQUksRUFBaEM7QUFDQSxXQUFPLEtBQUs2SCxVQUFMLEdBQ0pDLElBREksQ0FDQ29CLENBQUMsSUFBSTtBQUNUMUcsTUFBQUEsTUFBTSxHQUFHMEcsQ0FBVDs7QUFDQSxVQUFJOUcsUUFBSixFQUFjO0FBQ1osZUFBTzJELE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0Q7O0FBQ0QsYUFBTyxLQUFLbUQsV0FBTCxDQUFpQjNHLE1BQWpCLEVBQXlCQyxTQUF6QixFQUFvQ0UsTUFBcEMsRUFBNENOLFFBQTVDLEVBQXNEMkcsVUFBdEQsQ0FBUDtBQUNELEtBUEksRUFRSmxCLElBUkksQ0FRQyxNQUFNO0FBQ1YsYUFBT3RGLE1BQU0sQ0FBQ3VHLGNBQVAsQ0FBc0J0RyxTQUF0QixFQUFpQ0UsTUFBakMsRUFBeUM1QyxLQUF6QyxDQUFQO0FBQ0QsS0FWSSxDQUFQO0FBV0Q7O0FBRURxSixFQUFBQSxNQUFNLENBQ0ozRyxTQURJLEVBRUoxQyxLQUZJLEVBR0pxSixNQUhJLEVBSUo7QUFBRXBKLElBQUFBLEdBQUY7QUFBT3FKLElBQUFBLElBQVA7QUFBYUMsSUFBQUEsTUFBYjtBQUFxQkMsSUFBQUE7QUFBckIsTUFBcUQsRUFKakQsRUFLSkMsZ0JBQXlCLEdBQUcsS0FMeEIsRUFNSkMsWUFBcUIsR0FBRyxLQU5wQixFQU9KQyxxQkFQSSxFQVFVO0FBQ2QsVUFBTUMsYUFBYSxHQUFHNUosS0FBdEI7QUFDQSxVQUFNNkosY0FBYyxHQUFHUixNQUF2QixDQUZjLENBR2Q7O0FBQ0FBLElBQUFBLE1BQU0sR0FBRyx1QkFBU0EsTUFBVCxDQUFUO0FBQ0EsUUFBSVMsZUFBZSxHQUFHLEVBQXRCO0FBQ0EsUUFBSXpILFFBQVEsR0FBR3BDLEdBQUcsS0FBS2lKLFNBQXZCO0FBQ0EsUUFBSTVHLFFBQVEsR0FBR3JDLEdBQUcsSUFBSSxFQUF0QjtBQUVBLFdBQU8sS0FBSzBJLGtCQUFMLENBQXdCZ0IscUJBQXhCLEVBQStDNUIsSUFBL0MsQ0FBb0RDLGdCQUFnQixJQUFJO0FBQzdFLGFBQU8sQ0FBQzNGLFFBQVEsR0FDWjJELE9BQU8sQ0FBQ0MsT0FBUixFQURZLEdBRVorQixnQkFBZ0IsQ0FBQytCLGtCQUFqQixDQUFvQ3JILFNBQXBDLEVBQStDSixRQUEvQyxFQUF5RCxRQUF6RCxDQUZHLEVBSUp5RixJQUpJLENBSUMsTUFBTTtBQUNWK0IsUUFBQUEsZUFBZSxHQUFHLEtBQUtFLHNCQUFMLENBQTRCdEgsU0FBNUIsRUFBdUNrSCxhQUFhLENBQUM1RixRQUFyRCxFQUErRHFGLE1BQS9ELENBQWxCOztBQUNBLFlBQUksQ0FBQ2hILFFBQUwsRUFBZTtBQUNickMsVUFBQUEsS0FBSyxHQUFHLEtBQUtpSyxxQkFBTCxDQUNOakMsZ0JBRE0sRUFFTnRGLFNBRk0sRUFHTixRQUhNLEVBSU4xQyxLQUpNLEVBS05zQyxRQUxNLENBQVI7O0FBUUEsY0FBSWtILFNBQUosRUFBZTtBQUNieEosWUFBQUEsS0FBSyxHQUFHO0FBQ04yQixjQUFBQSxJQUFJLEVBQUUsQ0FDSjNCLEtBREksRUFFSixLQUFLaUsscUJBQUwsQ0FDRWpDLGdCQURGLEVBRUV0RixTQUZGLEVBR0UsVUFIRixFQUlFMUMsS0FKRixFQUtFc0MsUUFMRixDQUZJO0FBREEsYUFBUjtBQVlEO0FBQ0Y7O0FBQ0QsWUFBSSxDQUFDdEMsS0FBTCxFQUFZO0FBQ1YsaUJBQU9nRyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUNELFlBQUloRyxHQUFKLEVBQVM7QUFDUEQsVUFBQUEsS0FBSyxHQUFHRCxXQUFXLENBQUNDLEtBQUQsRUFBUUMsR0FBUixDQUFuQjtBQUNEOztBQUNEbUIsUUFBQUEsYUFBYSxDQUFDcEIsS0FBRCxDQUFiO0FBQ0EsZUFBT2dJLGdCQUFnQixDQUNwQkMsWUFESSxDQUNTdkYsU0FEVCxFQUNvQixJQURwQixFQUVKd0gsS0FGSSxDQUVFQyxLQUFLLElBQUk7QUFDZDtBQUNBO0FBQ0EsY0FBSUEsS0FBSyxLQUFLakIsU0FBZCxFQUF5QjtBQUN2QixtQkFBTztBQUFFakYsY0FBQUEsTUFBTSxFQUFFO0FBQVYsYUFBUDtBQUNEOztBQUNELGdCQUFNa0csS0FBTjtBQUNELFNBVEksRUFVSnBDLElBVkksQ0FVQ3RGLE1BQU0sSUFBSTtBQUNkWCxVQUFBQSxNQUFNLENBQUNDLElBQVAsQ0FBWXNILE1BQVosRUFBb0IzSCxPQUFwQixDQUE0Qm1GLFNBQVMsSUFBSTtBQUN2QyxnQkFBSUEsU0FBUyxDQUFDM0UsS0FBVixDQUFnQixpQ0FBaEIsQ0FBSixFQUF3RDtBQUN0RCxvQkFBTSxJQUFJYixZQUFNQyxLQUFWLENBQ0pELFlBQU1DLEtBQU4sQ0FBWWEsZ0JBRFIsRUFFSCxrQ0FBaUMwRSxTQUFVLEVBRnhDLENBQU47QUFJRDs7QUFDRCxrQkFBTXVELGFBQWEsR0FBR25ELGdCQUFnQixDQUFDSixTQUFELENBQXRDOztBQUNBLGdCQUNFLENBQUN1QixnQkFBZ0IsQ0FBQ2lDLGdCQUFqQixDQUFrQ0QsYUFBbEMsRUFBaUQxSCxTQUFqRCxDQUFELElBQ0EsQ0FBQzJDLGtCQUFrQixDQUFDK0UsYUFBRCxDQUZyQixFQUdFO0FBQ0Esb0JBQU0sSUFBSS9JLFlBQU1DLEtBQVYsQ0FDSkQsWUFBTUMsS0FBTixDQUFZYSxnQkFEUixFQUVILGtDQUFpQzBFLFNBQVUsRUFGeEMsQ0FBTjtBQUlEO0FBQ0YsV0FqQkQ7O0FBa0JBLGVBQUssTUFBTXlELGVBQVgsSUFBOEJqQixNQUE5QixFQUFzQztBQUNwQyxnQkFDRUEsTUFBTSxDQUFDaUIsZUFBRCxDQUFOLElBQ0EsT0FBT2pCLE1BQU0sQ0FBQ2lCLGVBQUQsQ0FBYixLQUFtQyxRQURuQyxJQUVBeEksTUFBTSxDQUFDQyxJQUFQLENBQVlzSCxNQUFNLENBQUNpQixlQUFELENBQWxCLEVBQXFDdkcsSUFBckMsQ0FDRXdHLFFBQVEsSUFBSUEsUUFBUSxDQUFDcEcsUUFBVCxDQUFrQixHQUFsQixLQUEwQm9HLFFBQVEsQ0FBQ3BHLFFBQVQsQ0FBa0IsR0FBbEIsQ0FEeEMsQ0FIRixFQU1FO0FBQ0Esb0JBQU0sSUFBSTlDLFlBQU1DLEtBQVYsQ0FDSkQsWUFBTUMsS0FBTixDQUFZa0osa0JBRFIsRUFFSiwwREFGSSxDQUFOO0FBSUQ7QUFDRjs7QUFDRG5CLFVBQUFBLE1BQU0sR0FBRzVJLGtCQUFrQixDQUFDNEksTUFBRCxDQUEzQjtBQUNBM0MsVUFBQUEsaUJBQWlCLENBQUNoRSxTQUFELEVBQVkyRyxNQUFaLEVBQW9CNUcsTUFBcEIsQ0FBakI7O0FBQ0EsY0FBSWlILFlBQUosRUFBa0I7QUFDaEIsbUJBQU8sS0FBS25DLE9BQUwsQ0FBYWtELElBQWIsQ0FBa0IvSCxTQUFsQixFQUE2QkQsTUFBN0IsRUFBcUN6QyxLQUFyQyxFQUE0QyxFQUE1QyxFQUFnRCtILElBQWhELENBQXFEcEgsTUFBTSxJQUFJO0FBQ3BFLGtCQUFJLENBQUNBLE1BQUQsSUFBVyxDQUFDQSxNQUFNLENBQUNrQixNQUF2QixFQUErQjtBQUM3QixzQkFBTSxJQUFJUixZQUFNQyxLQUFWLENBQWdCRCxZQUFNQyxLQUFOLENBQVlvSixnQkFBNUIsRUFBOEMsbUJBQTlDLENBQU47QUFDRDs7QUFDRCxxQkFBTyxFQUFQO0FBQ0QsYUFMTSxDQUFQO0FBTUQ7O0FBQ0QsY0FBSXBCLElBQUosRUFBVTtBQUNSLG1CQUFPLEtBQUsvQixPQUFMLENBQWFvRCxvQkFBYixDQUNMakksU0FESyxFQUVMRCxNQUZLLEVBR0x6QyxLQUhLLEVBSUxxSixNQUpLLEVBS0wsS0FBSzNCLHFCQUxBLENBQVA7QUFPRCxXQVJELE1BUU8sSUFBSTZCLE1BQUosRUFBWTtBQUNqQixtQkFBTyxLQUFLaEMsT0FBTCxDQUFhcUQsZUFBYixDQUNMbEksU0FESyxFQUVMRCxNQUZLLEVBR0x6QyxLQUhLLEVBSUxxSixNQUpLLEVBS0wsS0FBSzNCLHFCQUxBLENBQVA7QUFPRCxXQVJNLE1BUUE7QUFDTCxtQkFBTyxLQUFLSCxPQUFMLENBQWFzRCxnQkFBYixDQUNMbkksU0FESyxFQUVMRCxNQUZLLEVBR0x6QyxLQUhLLEVBSUxxSixNQUpLLEVBS0wsS0FBSzNCLHFCQUxBLENBQVA7QUFPRDtBQUNGLFNBOUVJLENBQVA7QUErRUQsT0FwSEksRUFxSEpLLElBckhJLENBcUhFcEgsTUFBRCxJQUFpQjtBQUNyQixZQUFJLENBQUNBLE1BQUwsRUFBYTtBQUNYLGdCQUFNLElBQUlVLFlBQU1DLEtBQVYsQ0FBZ0JELFlBQU1DLEtBQU4sQ0FBWW9KLGdCQUE1QixFQUE4QyxtQkFBOUMsQ0FBTjtBQUNEOztBQUNELFlBQUloQixZQUFKLEVBQWtCO0FBQ2hCLGlCQUFPL0ksTUFBUDtBQUNEOztBQUNELGVBQU8sS0FBS21LLHFCQUFMLENBQ0xwSSxTQURLLEVBRUxrSCxhQUFhLENBQUM1RixRQUZULEVBR0xxRixNQUhLLEVBSUxTLGVBSkssRUFLTC9CLElBTEssQ0FLQSxNQUFNO0FBQ1gsaUJBQU9wSCxNQUFQO0FBQ0QsU0FQTSxDQUFQO0FBUUQsT0FwSUksRUFxSUpvSCxJQXJJSSxDQXFJQ3BILE1BQU0sSUFBSTtBQUNkLFlBQUk4SSxnQkFBSixFQUFzQjtBQUNwQixpQkFBT3pELE9BQU8sQ0FBQ0MsT0FBUixDQUFnQnRGLE1BQWhCLENBQVA7QUFDRDs7QUFDRCxlQUFPa0Ysc0JBQXNCLENBQUNnRSxjQUFELEVBQWlCbEosTUFBakIsQ0FBN0I7QUFDRCxPQTFJSSxDQUFQO0FBMklELEtBNUlNLENBQVA7QUE2SUQsR0EvUHNCLENBaVF2QjtBQUNBO0FBQ0E7OztBQUNBcUosRUFBQUEsc0JBQXNCLENBQUN0SCxTQUFELEVBQW9Cc0IsUUFBcEIsRUFBdUNxRixNQUF2QyxFQUFvRDtBQUN4RSxRQUFJMEIsR0FBRyxHQUFHLEVBQVY7QUFDQSxRQUFJQyxRQUFRLEdBQUcsRUFBZjtBQUNBaEgsSUFBQUEsUUFBUSxHQUFHcUYsTUFBTSxDQUFDckYsUUFBUCxJQUFtQkEsUUFBOUI7O0FBRUEsUUFBSWlILE9BQU8sR0FBRyxDQUFDQyxFQUFELEVBQUtoSyxHQUFMLEtBQWE7QUFDekIsVUFBSSxDQUFDZ0ssRUFBTCxFQUFTO0FBQ1A7QUFDRDs7QUFDRCxVQUFJQSxFQUFFLENBQUMvRSxJQUFILElBQVcsYUFBZixFQUE4QjtBQUM1QjRFLFFBQUFBLEdBQUcsQ0FBQ2pLLElBQUosQ0FBUztBQUFFSSxVQUFBQSxHQUFGO0FBQU9nSyxVQUFBQTtBQUFQLFNBQVQ7QUFDQUYsUUFBQUEsUUFBUSxDQUFDbEssSUFBVCxDQUFjSSxHQUFkO0FBQ0Q7O0FBRUQsVUFBSWdLLEVBQUUsQ0FBQy9FLElBQUgsSUFBVyxnQkFBZixFQUFpQztBQUMvQjRFLFFBQUFBLEdBQUcsQ0FBQ2pLLElBQUosQ0FBUztBQUFFSSxVQUFBQSxHQUFGO0FBQU9nSyxVQUFBQTtBQUFQLFNBQVQ7QUFDQUYsUUFBQUEsUUFBUSxDQUFDbEssSUFBVCxDQUFjSSxHQUFkO0FBQ0Q7O0FBRUQsVUFBSWdLLEVBQUUsQ0FBQy9FLElBQUgsSUFBVyxPQUFmLEVBQXdCO0FBQ3RCLGFBQUssSUFBSWdGLENBQVQsSUFBY0QsRUFBRSxDQUFDSCxHQUFqQixFQUFzQjtBQUNwQkUsVUFBQUEsT0FBTyxDQUFDRSxDQUFELEVBQUlqSyxHQUFKLENBQVA7QUFDRDtBQUNGO0FBQ0YsS0FuQkQ7O0FBcUJBLFNBQUssTUFBTUEsR0FBWCxJQUFrQm1JLE1BQWxCLEVBQTBCO0FBQ3hCNEIsTUFBQUEsT0FBTyxDQUFDNUIsTUFBTSxDQUFDbkksR0FBRCxDQUFQLEVBQWNBLEdBQWQsQ0FBUDtBQUNEOztBQUNELFNBQUssTUFBTUEsR0FBWCxJQUFrQjhKLFFBQWxCLEVBQTRCO0FBQzFCLGFBQU8zQixNQUFNLENBQUNuSSxHQUFELENBQWI7QUFDRDs7QUFDRCxXQUFPNkosR0FBUDtBQUNELEdBclNzQixDQXVTdkI7QUFDQTs7O0FBQ0FELEVBQUFBLHFCQUFxQixDQUFDcEksU0FBRCxFQUFvQnNCLFFBQXBCLEVBQXNDcUYsTUFBdEMsRUFBbUQwQixHQUFuRCxFQUE2RDtBQUNoRixRQUFJSyxPQUFPLEdBQUcsRUFBZDtBQUNBcEgsSUFBQUEsUUFBUSxHQUFHcUYsTUFBTSxDQUFDckYsUUFBUCxJQUFtQkEsUUFBOUI7QUFDQStHLElBQUFBLEdBQUcsQ0FBQ3JKLE9BQUosQ0FBWSxDQUFDO0FBQUVSLE1BQUFBLEdBQUY7QUFBT2dLLE1BQUFBO0FBQVAsS0FBRCxLQUFpQjtBQUMzQixVQUFJLENBQUNBLEVBQUwsRUFBUztBQUNQO0FBQ0Q7O0FBQ0QsVUFBSUEsRUFBRSxDQUFDL0UsSUFBSCxJQUFXLGFBQWYsRUFBOEI7QUFDNUIsYUFBSyxNQUFNdkQsTUFBWCxJQUFxQnNJLEVBQUUsQ0FBQzFFLE9BQXhCLEVBQWlDO0FBQy9CNEUsVUFBQUEsT0FBTyxDQUFDdEssSUFBUixDQUFhLEtBQUt1SyxXQUFMLENBQWlCbkssR0FBakIsRUFBc0J3QixTQUF0QixFQUFpQ3NCLFFBQWpDLEVBQTJDcEIsTUFBTSxDQUFDb0IsUUFBbEQsQ0FBYjtBQUNEO0FBQ0Y7O0FBRUQsVUFBSWtILEVBQUUsQ0FBQy9FLElBQUgsSUFBVyxnQkFBZixFQUFpQztBQUMvQixhQUFLLE1BQU12RCxNQUFYLElBQXFCc0ksRUFBRSxDQUFDMUUsT0FBeEIsRUFBaUM7QUFDL0I0RSxVQUFBQSxPQUFPLENBQUN0SyxJQUFSLENBQWEsS0FBS3dLLGNBQUwsQ0FBb0JwSyxHQUFwQixFQUF5QndCLFNBQXpCLEVBQW9Dc0IsUUFBcEMsRUFBOENwQixNQUFNLENBQUNvQixRQUFyRCxDQUFiO0FBQ0Q7QUFDRjtBQUNGLEtBZkQ7QUFpQkEsV0FBT2dDLE9BQU8sQ0FBQ3VGLEdBQVIsQ0FBWUgsT0FBWixDQUFQO0FBQ0QsR0E5VHNCLENBZ1V2QjtBQUNBOzs7QUFDQUMsRUFBQUEsV0FBVyxDQUFDbkssR0FBRCxFQUFjc0ssYUFBZCxFQUFxQ0MsTUFBckMsRUFBcURDLElBQXJELEVBQW1FO0FBQzVFLFVBQU1DLEdBQUcsR0FBRztBQUNWeEUsTUFBQUEsU0FBUyxFQUFFdUUsSUFERDtBQUVWdEUsTUFBQUEsUUFBUSxFQUFFcUU7QUFGQSxLQUFaO0FBSUEsV0FBTyxLQUFLbEUsT0FBTCxDQUFhcUQsZUFBYixDQUNKLFNBQVExSixHQUFJLElBQUdzSyxhQUFjLEVBRHpCLEVBRUx0RSxjQUZLLEVBR0x5RSxHQUhLLEVBSUxBLEdBSkssRUFLTCxLQUFLakUscUJBTEEsQ0FBUDtBQU9ELEdBOVVzQixDQWdWdkI7QUFDQTtBQUNBOzs7QUFDQTRELEVBQUFBLGNBQWMsQ0FBQ3BLLEdBQUQsRUFBY3NLLGFBQWQsRUFBcUNDLE1BQXJDLEVBQXFEQyxJQUFyRCxFQUFtRTtBQUMvRSxRQUFJQyxHQUFHLEdBQUc7QUFDUnhFLE1BQUFBLFNBQVMsRUFBRXVFLElBREg7QUFFUnRFLE1BQUFBLFFBQVEsRUFBRXFFO0FBRkYsS0FBVjtBQUlBLFdBQU8sS0FBS2xFLE9BQUwsQ0FDSlcsb0JBREksQ0FFRixTQUFRaEgsR0FBSSxJQUFHc0ssYUFBYyxFQUYzQixFQUdIdEUsY0FIRyxFQUlIeUUsR0FKRyxFQUtILEtBQUtqRSxxQkFMRixFQU9Kd0MsS0FQSSxDQU9FQyxLQUFLLElBQUk7QUFDZDtBQUNBLFVBQUlBLEtBQUssQ0FBQ3lCLElBQU4sSUFBY3ZLLFlBQU1DLEtBQU4sQ0FBWW9KLGdCQUE5QixFQUFnRDtBQUM5QztBQUNEOztBQUNELFlBQU1QLEtBQU47QUFDRCxLQWJJLENBQVA7QUFjRCxHQXRXc0IsQ0F3V3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQTBCLEVBQUFBLE9BQU8sQ0FDTG5KLFNBREssRUFFTDFDLEtBRkssRUFHTDtBQUFFQyxJQUFBQTtBQUFGLE1BQXdCLEVBSG5CLEVBSUwwSixxQkFKSyxFQUtTO0FBQ2QsVUFBTXRILFFBQVEsR0FBR3BDLEdBQUcsS0FBS2lKLFNBQXpCO0FBQ0EsVUFBTTVHLFFBQVEsR0FBR3JDLEdBQUcsSUFBSSxFQUF4QjtBQUVBLFdBQU8sS0FBSzBJLGtCQUFMLENBQXdCZ0IscUJBQXhCLEVBQStDNUIsSUFBL0MsQ0FBb0RDLGdCQUFnQixJQUFJO0FBQzdFLGFBQU8sQ0FBQzNGLFFBQVEsR0FDWjJELE9BQU8sQ0FBQ0MsT0FBUixFQURZLEdBRVorQixnQkFBZ0IsQ0FBQytCLGtCQUFqQixDQUFvQ3JILFNBQXBDLEVBQStDSixRQUEvQyxFQUF5RCxRQUF6RCxDQUZHLEVBR0x5RixJQUhLLENBR0EsTUFBTTtBQUNYLFlBQUksQ0FBQzFGLFFBQUwsRUFBZTtBQUNickMsVUFBQUEsS0FBSyxHQUFHLEtBQUtpSyxxQkFBTCxDQUNOakMsZ0JBRE0sRUFFTnRGLFNBRk0sRUFHTixRQUhNLEVBSU4xQyxLQUpNLEVBS05zQyxRQUxNLENBQVI7O0FBT0EsY0FBSSxDQUFDdEMsS0FBTCxFQUFZO0FBQ1Ysa0JBQU0sSUFBSXFCLFlBQU1DLEtBQVYsQ0FBZ0JELFlBQU1DLEtBQU4sQ0FBWW9KLGdCQUE1QixFQUE4QyxtQkFBOUMsQ0FBTjtBQUNEO0FBQ0YsU0FaVSxDQWFYOzs7QUFDQSxZQUFJekssR0FBSixFQUFTO0FBQ1BELFVBQUFBLEtBQUssR0FBR0QsV0FBVyxDQUFDQyxLQUFELEVBQVFDLEdBQVIsQ0FBbkI7QUFDRDs7QUFDRG1CLFFBQUFBLGFBQWEsQ0FBQ3BCLEtBQUQsQ0FBYjtBQUNBLGVBQU9nSSxnQkFBZ0IsQ0FDcEJDLFlBREksQ0FDU3ZGLFNBRFQsRUFFSndILEtBRkksQ0FFRUMsS0FBSyxJQUFJO0FBQ2Q7QUFDQTtBQUNBLGNBQUlBLEtBQUssS0FBS2pCLFNBQWQsRUFBeUI7QUFDdkIsbUJBQU87QUFBRWpGLGNBQUFBLE1BQU0sRUFBRTtBQUFWLGFBQVA7QUFDRDs7QUFDRCxnQkFBTWtHLEtBQU47QUFDRCxTQVRJLEVBVUpwQyxJQVZJLENBVUMrRCxpQkFBaUIsSUFDckIsS0FBS3ZFLE9BQUwsQ0FBYVcsb0JBQWIsQ0FDRXhGLFNBREYsRUFFRW9KLGlCQUZGLEVBR0U5TCxLQUhGLEVBSUUsS0FBSzBILHFCQUpQLENBWEcsRUFrQkp3QyxLQWxCSSxDQWtCRUMsS0FBSyxJQUFJO0FBQ2Q7QUFDQSxjQUFJekgsU0FBUyxLQUFLLFVBQWQsSUFBNEJ5SCxLQUFLLENBQUN5QixJQUFOLEtBQWV2SyxZQUFNQyxLQUFOLENBQVlvSixnQkFBM0QsRUFBNkU7QUFDM0UsbUJBQU8xRSxPQUFPLENBQUNDLE9BQVIsQ0FBZ0IsRUFBaEIsQ0FBUDtBQUNEOztBQUNELGdCQUFNa0UsS0FBTjtBQUNELFNBeEJJLENBQVA7QUF5QkQsT0E5Q00sQ0FBUDtBQStDRCxLQWhETSxDQUFQO0FBaURELEdBemFzQixDQTJhdkI7QUFDQTs7O0FBQ0E0QixFQUFBQSxNQUFNLENBQ0pySixTQURJLEVBRUpFLE1BRkksRUFHSjtBQUFFM0MsSUFBQUE7QUFBRixNQUF3QixFQUhwQixFQUlKeUosWUFBcUIsR0FBRyxLQUpwQixFQUtKQyxxQkFMSSxFQU1VO0FBQ2Q7QUFDQSxVQUFNN0QsY0FBYyxHQUFHbEQsTUFBdkI7QUFDQUEsSUFBQUEsTUFBTSxHQUFHbkMsa0JBQWtCLENBQUNtQyxNQUFELENBQTNCO0FBRUFBLElBQUFBLE1BQU0sQ0FBQ29KLFNBQVAsR0FBbUI7QUFBRUMsTUFBQUEsR0FBRyxFQUFFckosTUFBTSxDQUFDb0osU0FBZDtBQUF5QkUsTUFBQUEsTUFBTSxFQUFFO0FBQWpDLEtBQW5CO0FBQ0F0SixJQUFBQSxNQUFNLENBQUN1SixTQUFQLEdBQW1CO0FBQUVGLE1BQUFBLEdBQUcsRUFBRXJKLE1BQU0sQ0FBQ3VKLFNBQWQ7QUFBeUJELE1BQUFBLE1BQU0sRUFBRTtBQUFqQyxLQUFuQjtBQUVBLFFBQUk3SixRQUFRLEdBQUdwQyxHQUFHLEtBQUtpSixTQUF2QjtBQUNBLFFBQUk1RyxRQUFRLEdBQUdyQyxHQUFHLElBQUksRUFBdEI7QUFDQSxVQUFNNkosZUFBZSxHQUFHLEtBQUtFLHNCQUFMLENBQTRCdEgsU0FBNUIsRUFBdUMsSUFBdkMsRUFBNkNFLE1BQTdDLENBQXhCO0FBRUEsV0FBTyxLQUFLdUYsaUJBQUwsQ0FBdUJ6RixTQUF2QixFQUNKcUYsSUFESSxDQUNDLE1BQU0sS0FBS1ksa0JBQUwsQ0FBd0JnQixxQkFBeEIsQ0FEUCxFQUVKNUIsSUFGSSxDQUVDQyxnQkFBZ0IsSUFBSTtBQUN4QixhQUFPLENBQUMzRixRQUFRLEdBQ1oyRCxPQUFPLENBQUNDLE9BQVIsRUFEWSxHQUVaK0IsZ0JBQWdCLENBQUMrQixrQkFBakIsQ0FBb0NySCxTQUFwQyxFQUErQ0osUUFBL0MsRUFBeUQsUUFBekQsQ0FGRyxFQUlKeUYsSUFKSSxDQUlDLE1BQU1DLGdCQUFnQixDQUFDb0Usa0JBQWpCLENBQW9DMUosU0FBcEMsQ0FKUCxFQUtKcUYsSUFMSSxDQUtDLE1BQU1DLGdCQUFnQixDQUFDQyxZQUFqQixDQUE4QnZGLFNBQTlCLEVBQXlDLElBQXpDLENBTFAsRUFNSnFGLElBTkksQ0FNQ3RGLE1BQU0sSUFBSTtBQUNkaUUsUUFBQUEsaUJBQWlCLENBQUNoRSxTQUFELEVBQVlFLE1BQVosRUFBb0JILE1BQXBCLENBQWpCO0FBQ0E0RCxRQUFBQSwrQkFBK0IsQ0FBQ3pELE1BQUQsQ0FBL0I7O0FBQ0EsWUFBSThHLFlBQUosRUFBa0I7QUFDaEIsaUJBQU8sRUFBUDtBQUNEOztBQUNELGVBQU8sS0FBS25DLE9BQUwsQ0FBYThFLFlBQWIsQ0FDTDNKLFNBREssRUFFTDBGLGdCQUFnQixDQUFDa0UsNEJBQWpCLENBQThDN0osTUFBOUMsQ0FGSyxFQUdMRyxNQUhLLEVBSUwsS0FBSzhFLHFCQUpBLENBQVA7QUFNRCxPQWxCSSxFQW1CSkssSUFuQkksQ0FtQkNwSCxNQUFNLElBQUk7QUFDZCxZQUFJK0ksWUFBSixFQUFrQjtBQUNoQixpQkFBTzVELGNBQVA7QUFDRDs7QUFDRCxlQUFPLEtBQUtnRixxQkFBTCxDQUNMcEksU0FESyxFQUVMRSxNQUFNLENBQUNvQixRQUZGLEVBR0xwQixNQUhLLEVBSUxrSCxlQUpLLEVBS0wvQixJQUxLLENBS0EsTUFBTTtBQUNYLGlCQUFPbEMsc0JBQXNCLENBQUNDLGNBQUQsRUFBaUJuRixNQUFNLENBQUNvSyxHQUFQLENBQVcsQ0FBWCxDQUFqQixDQUE3QjtBQUNELFNBUE0sQ0FBUDtBQVFELE9BL0JJLENBQVA7QUFnQ0QsS0FuQ0ksQ0FBUDtBQW9DRDs7QUFFRDNCLEVBQUFBLFdBQVcsQ0FDVDNHLE1BRFMsRUFFVEMsU0FGUyxFQUdURSxNQUhTLEVBSVROLFFBSlMsRUFLVDJHLFVBTFMsRUFNTTtBQUNmLFVBQU1zRCxXQUFXLEdBQUc5SixNQUFNLENBQUMrSixVQUFQLENBQWtCOUosU0FBbEIsQ0FBcEI7O0FBQ0EsUUFBSSxDQUFDNkosV0FBTCxFQUFrQjtBQUNoQixhQUFPdkcsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFDRCxVQUFNaEMsTUFBTSxHQUFHbkMsTUFBTSxDQUFDQyxJQUFQLENBQVlhLE1BQVosQ0FBZjtBQUNBLFVBQU02SixZQUFZLEdBQUczSyxNQUFNLENBQUNDLElBQVAsQ0FBWXdLLFdBQVcsQ0FBQ3RJLE1BQXhCLENBQXJCO0FBQ0EsVUFBTXlJLE9BQU8sR0FBR3pJLE1BQU0sQ0FBQ2IsTUFBUCxDQUFjdUosS0FBSyxJQUFJO0FBQ3JDO0FBQ0EsVUFBSS9KLE1BQU0sQ0FBQytKLEtBQUQsQ0FBTixJQUFpQi9KLE1BQU0sQ0FBQytKLEtBQUQsQ0FBTixDQUFjeEcsSUFBL0IsSUFBdUN2RCxNQUFNLENBQUMrSixLQUFELENBQU4sQ0FBY3hHLElBQWQsS0FBdUIsUUFBbEUsRUFBNEU7QUFDMUUsZUFBTyxLQUFQO0FBQ0Q7O0FBQ0QsYUFBT3NHLFlBQVksQ0FBQ3RMLE9BQWIsQ0FBcUJ3TCxLQUFyQixJQUE4QixDQUFyQztBQUNELEtBTmUsQ0FBaEI7O0FBT0EsUUFBSUQsT0FBTyxDQUFDN0ssTUFBUixHQUFpQixDQUFyQixFQUF3QjtBQUN0QjtBQUNBb0gsTUFBQUEsVUFBVSxDQUFDTyxTQUFYLEdBQXVCLElBQXZCO0FBRUEsWUFBTW9ELE1BQU0sR0FBRzNELFVBQVUsQ0FBQzJELE1BQTFCO0FBQ0EsYUFBT25LLE1BQU0sQ0FBQ3NILGtCQUFQLENBQTBCckgsU0FBMUIsRUFBcUNKLFFBQXJDLEVBQStDLFVBQS9DLEVBQTJEc0ssTUFBM0QsQ0FBUDtBQUNEOztBQUNELFdBQU81RyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELEdBamdCc0IsQ0FtZ0J2Qjs7QUFDQTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNFNEcsRUFBQUEsZ0JBQWdCLENBQUNDLElBQWEsR0FBRyxLQUFqQixFQUFzQztBQUNwRCxTQUFLckYsYUFBTCxHQUFxQixJQUFyQjtBQUNBLFdBQU96QixPQUFPLENBQUN1RixHQUFSLENBQVksQ0FBQyxLQUFLaEUsT0FBTCxDQUFhd0YsZ0JBQWIsQ0FBOEJELElBQTlCLENBQUQsRUFBc0MsS0FBS3RGLFdBQUwsQ0FBaUJ3RixLQUFqQixFQUF0QyxDQUFaLENBQVA7QUFDRCxHQTdnQnNCLENBK2dCdkI7QUFDQTs7O0FBQ0FDLEVBQUFBLFVBQVUsQ0FDUnZLLFNBRFEsRUFFUnhCLEdBRlEsRUFHUmtHLFFBSFEsRUFJUjhGLFlBSlEsRUFLZ0I7QUFDeEIsVUFBTTtBQUFFQyxNQUFBQSxJQUFGO0FBQVFDLE1BQUFBLEtBQVI7QUFBZUMsTUFBQUE7QUFBZixRQUF3QkgsWUFBOUI7QUFDQSxVQUFNSSxXQUFXLEdBQUcsRUFBcEI7O0FBQ0EsUUFBSUQsSUFBSSxJQUFJQSxJQUFJLENBQUNyQixTQUFiLElBQTBCLEtBQUt6RSxPQUFMLENBQWFnRyxtQkFBM0MsRUFBZ0U7QUFDOURELE1BQUFBLFdBQVcsQ0FBQ0QsSUFBWixHQUFtQjtBQUFFRyxRQUFBQSxHQUFHLEVBQUVILElBQUksQ0FBQ3JCO0FBQVosT0FBbkI7QUFDQXNCLE1BQUFBLFdBQVcsQ0FBQ0YsS0FBWixHQUFvQkEsS0FBcEI7QUFDQUUsTUFBQUEsV0FBVyxDQUFDSCxJQUFaLEdBQW1CQSxJQUFuQjtBQUNBRCxNQUFBQSxZQUFZLENBQUNDLElBQWIsR0FBb0IsQ0FBcEI7QUFDRDs7QUFDRCxXQUFPLEtBQUs1RixPQUFMLENBQ0prRCxJQURJLENBQ0NyRSxhQUFhLENBQUMxRCxTQUFELEVBQVl4QixHQUFaLENBRGQsRUFDZ0NnRyxjQURoQyxFQUNnRDtBQUFFRSxNQUFBQTtBQUFGLEtBRGhELEVBQzhEa0csV0FEOUQsRUFFSnZGLElBRkksQ0FFQzBGLE9BQU8sSUFBSUEsT0FBTyxDQUFDbkssR0FBUixDQUFZM0MsTUFBTSxJQUFJQSxNQUFNLENBQUN3RyxTQUE3QixDQUZaLENBQVA7QUFHRCxHQWxpQnNCLENBb2lCdkI7QUFDQTs7O0FBQ0F1RyxFQUFBQSxTQUFTLENBQUNoTCxTQUFELEVBQW9CeEIsR0FBcEIsRUFBaUMrTCxVQUFqQyxFQUEwRTtBQUNqRixXQUFPLEtBQUsxRixPQUFMLENBQ0prRCxJQURJLENBRUhyRSxhQUFhLENBQUMxRCxTQUFELEVBQVl4QixHQUFaLENBRlYsRUFHSGdHLGNBSEcsRUFJSDtBQUFFQyxNQUFBQSxTQUFTLEVBQUU7QUFBRTdHLFFBQUFBLEdBQUcsRUFBRTJNO0FBQVA7QUFBYixLQUpHLEVBS0g7QUFBRWxMLE1BQUFBLElBQUksRUFBRSxDQUFDLFVBQUQ7QUFBUixLQUxHLEVBT0pnRyxJQVBJLENBT0MwRixPQUFPLElBQUlBLE9BQU8sQ0FBQ25LLEdBQVIsQ0FBWTNDLE1BQU0sSUFBSUEsTUFBTSxDQUFDeUcsUUFBN0IsQ0FQWixDQUFQO0FBUUQsR0EvaUJzQixDQWlqQnZCO0FBQ0E7QUFDQTs7O0FBQ0F1RyxFQUFBQSxnQkFBZ0IsQ0FBQ2pMLFNBQUQsRUFBb0IxQyxLQUFwQixFQUFnQ3lDLE1BQWhDLEVBQTJEO0FBQ3pFO0FBQ0E7QUFDQSxRQUFJekMsS0FBSyxDQUFDLEtBQUQsQ0FBVCxFQUFrQjtBQUNoQixZQUFNNE4sR0FBRyxHQUFHNU4sS0FBSyxDQUFDLEtBQUQsQ0FBakI7QUFDQSxhQUFPZ0csT0FBTyxDQUFDdUYsR0FBUixDQUNMcUMsR0FBRyxDQUFDdEssR0FBSixDQUFRLENBQUN1SyxNQUFELEVBQVNDLEtBQVQsS0FBbUI7QUFDekIsZUFBTyxLQUFLSCxnQkFBTCxDQUFzQmpMLFNBQXRCLEVBQWlDbUwsTUFBakMsRUFBeUNwTCxNQUF6QyxFQUFpRHNGLElBQWpELENBQXNEOEYsTUFBTSxJQUFJO0FBQ3JFN04sVUFBQUEsS0FBSyxDQUFDLEtBQUQsQ0FBTCxDQUFhOE4sS0FBYixJQUFzQkQsTUFBdEI7QUFDRCxTQUZNLENBQVA7QUFHRCxPQUpELENBREssRUFNTDlGLElBTkssQ0FNQSxNQUFNO0FBQ1gsZUFBTy9CLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQmpHLEtBQWhCLENBQVA7QUFDRCxPQVJNLENBQVA7QUFTRDs7QUFFRCxVQUFNK04sUUFBUSxHQUFHak0sTUFBTSxDQUFDQyxJQUFQLENBQVkvQixLQUFaLEVBQW1Cc0QsR0FBbkIsQ0FBdUJwQyxHQUFHLElBQUk7QUFDN0MsWUFBTTJILENBQUMsR0FBR3BHLE1BQU0sQ0FBQ3FHLGVBQVAsQ0FBdUJwRyxTQUF2QixFQUFrQ3hCLEdBQWxDLENBQVY7O0FBQ0EsVUFBSSxDQUFDMkgsQ0FBRCxJQUFNQSxDQUFDLENBQUMvQixJQUFGLEtBQVcsVUFBckIsRUFBaUM7QUFDL0IsZUFBT2QsT0FBTyxDQUFDQyxPQUFSLENBQWdCakcsS0FBaEIsQ0FBUDtBQUNEOztBQUNELFVBQUlnTyxPQUFpQixHQUFHLElBQXhCOztBQUNBLFVBQ0VoTyxLQUFLLENBQUNrQixHQUFELENBQUwsS0FDQ2xCLEtBQUssQ0FBQ2tCLEdBQUQsQ0FBTCxDQUFXLEtBQVgsS0FDQ2xCLEtBQUssQ0FBQ2tCLEdBQUQsQ0FBTCxDQUFXLEtBQVgsQ0FERCxJQUVDbEIsS0FBSyxDQUFDa0IsR0FBRCxDQUFMLENBQVcsTUFBWCxDQUZELElBR0NsQixLQUFLLENBQUNrQixHQUFELENBQUwsQ0FBV2dMLE1BQVgsSUFBcUIsU0FKdkIsQ0FERixFQU1FO0FBQ0E7QUFDQThCLFFBQUFBLE9BQU8sR0FBR2xNLE1BQU0sQ0FBQ0MsSUFBUCxDQUFZL0IsS0FBSyxDQUFDa0IsR0FBRCxDQUFqQixFQUF3Qm9DLEdBQXhCLENBQTRCMkssYUFBYSxJQUFJO0FBQ3JELGNBQUloQixVQUFKO0FBQ0EsY0FBSWlCLFVBQVUsR0FBRyxLQUFqQjs7QUFDQSxjQUFJRCxhQUFhLEtBQUssVUFBdEIsRUFBa0M7QUFDaENoQixZQUFBQSxVQUFVLEdBQUcsQ0FBQ2pOLEtBQUssQ0FBQ2tCLEdBQUQsQ0FBTCxDQUFXOEMsUUFBWixDQUFiO0FBQ0QsV0FGRCxNQUVPLElBQUlpSyxhQUFhLElBQUksS0FBckIsRUFBNEI7QUFDakNoQixZQUFBQSxVQUFVLEdBQUdqTixLQUFLLENBQUNrQixHQUFELENBQUwsQ0FBVyxLQUFYLEVBQWtCb0MsR0FBbEIsQ0FBc0I2SyxDQUFDLElBQUlBLENBQUMsQ0FBQ25LLFFBQTdCLENBQWI7QUFDRCxXQUZNLE1BRUEsSUFBSWlLLGFBQWEsSUFBSSxNQUFyQixFQUE2QjtBQUNsQ0MsWUFBQUEsVUFBVSxHQUFHLElBQWI7QUFDQWpCLFlBQUFBLFVBQVUsR0FBR2pOLEtBQUssQ0FBQ2tCLEdBQUQsQ0FBTCxDQUFXLE1BQVgsRUFBbUJvQyxHQUFuQixDQUF1QjZLLENBQUMsSUFBSUEsQ0FBQyxDQUFDbkssUUFBOUIsQ0FBYjtBQUNELFdBSE0sTUFHQSxJQUFJaUssYUFBYSxJQUFJLEtBQXJCLEVBQTRCO0FBQ2pDQyxZQUFBQSxVQUFVLEdBQUcsSUFBYjtBQUNBakIsWUFBQUEsVUFBVSxHQUFHLENBQUNqTixLQUFLLENBQUNrQixHQUFELENBQUwsQ0FBVyxLQUFYLEVBQWtCOEMsUUFBbkIsQ0FBYjtBQUNELFdBSE0sTUFHQTtBQUNMO0FBQ0Q7O0FBQ0QsaUJBQU87QUFDTGtLLFlBQUFBLFVBREs7QUFFTGpCLFlBQUFBO0FBRkssV0FBUDtBQUlELFNBcEJTLENBQVY7QUFxQkQsT0E3QkQsTUE2Qk87QUFDTGUsUUFBQUEsT0FBTyxHQUFHLENBQUM7QUFBRUUsVUFBQUEsVUFBVSxFQUFFLEtBQWQ7QUFBcUJqQixVQUFBQSxVQUFVLEVBQUU7QUFBakMsU0FBRCxDQUFWO0FBQ0QsT0FyQzRDLENBdUM3Qzs7O0FBQ0EsYUFBT2pOLEtBQUssQ0FBQ2tCLEdBQUQsQ0FBWixDQXhDNkMsQ0F5QzdDO0FBQ0E7O0FBQ0EsWUFBTTZNLFFBQVEsR0FBR0MsT0FBTyxDQUFDMUssR0FBUixDQUFZOEssQ0FBQyxJQUFJO0FBQ2hDLFlBQUksQ0FBQ0EsQ0FBTCxFQUFRO0FBQ04saUJBQU9wSSxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUNELGVBQU8sS0FBS3lILFNBQUwsQ0FBZWhMLFNBQWYsRUFBMEJ4QixHQUExQixFQUErQmtOLENBQUMsQ0FBQ25CLFVBQWpDLEVBQTZDbEYsSUFBN0MsQ0FBa0RzRyxHQUFHLElBQUk7QUFDOUQsY0FBSUQsQ0FBQyxDQUFDRixVQUFOLEVBQWtCO0FBQ2hCLGlCQUFLSSxvQkFBTCxDQUEwQkQsR0FBMUIsRUFBK0JyTyxLQUEvQjtBQUNELFdBRkQsTUFFTztBQUNMLGlCQUFLdU8saUJBQUwsQ0FBdUJGLEdBQXZCLEVBQTRCck8sS0FBNUI7QUFDRDs7QUFDRCxpQkFBT2dHLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsU0FQTSxDQUFQO0FBUUQsT0FaZ0IsQ0FBakI7QUFjQSxhQUFPRCxPQUFPLENBQUN1RixHQUFSLENBQVl3QyxRQUFaLEVBQXNCaEcsSUFBdEIsQ0FBMkIsTUFBTTtBQUN0QyxlQUFPL0IsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxPQUZNLENBQVA7QUFHRCxLQTVEZ0IsQ0FBakI7QUE4REEsV0FBT0QsT0FBTyxDQUFDdUYsR0FBUixDQUFZd0MsUUFBWixFQUFzQmhHLElBQXRCLENBQTJCLE1BQU07QUFDdEMsYUFBTy9CLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQmpHLEtBQWhCLENBQVA7QUFDRCxLQUZNLENBQVA7QUFHRCxHQXJvQnNCLENBdW9CdkI7QUFDQTs7O0FBQ0F3TyxFQUFBQSxrQkFBa0IsQ0FBQzlMLFNBQUQsRUFBb0IxQyxLQUFwQixFQUFnQ2tOLFlBQWhDLEVBQW1FO0FBQ25GLFFBQUlsTixLQUFLLENBQUMsS0FBRCxDQUFULEVBQWtCO0FBQ2hCLGFBQU9nRyxPQUFPLENBQUN1RixHQUFSLENBQ0x2TCxLQUFLLENBQUMsS0FBRCxDQUFMLENBQWFzRCxHQUFiLENBQWlCdUssTUFBTSxJQUFJO0FBQ3pCLGVBQU8sS0FBS1csa0JBQUwsQ0FBd0I5TCxTQUF4QixFQUFtQ21MLE1BQW5DLEVBQTJDWCxZQUEzQyxDQUFQO0FBQ0QsT0FGRCxDQURLLENBQVA7QUFLRDs7QUFFRCxRQUFJdUIsU0FBUyxHQUFHek8sS0FBSyxDQUFDLFlBQUQsQ0FBckI7O0FBQ0EsUUFBSXlPLFNBQUosRUFBZTtBQUNiLGFBQU8sS0FBS3hCLFVBQUwsQ0FDTHdCLFNBQVMsQ0FBQzdMLE1BQVYsQ0FBaUJGLFNBRFosRUFFTCtMLFNBQVMsQ0FBQ3ZOLEdBRkwsRUFHTHVOLFNBQVMsQ0FBQzdMLE1BQVYsQ0FBaUJvQixRQUhaLEVBSUxrSixZQUpLLEVBTUpuRixJQU5JLENBTUNzRyxHQUFHLElBQUk7QUFDWCxlQUFPck8sS0FBSyxDQUFDLFlBQUQsQ0FBWjtBQUNBLGFBQUt1TyxpQkFBTCxDQUF1QkYsR0FBdkIsRUFBNEJyTyxLQUE1QjtBQUNBLGVBQU8sS0FBS3dPLGtCQUFMLENBQXdCOUwsU0FBeEIsRUFBbUMxQyxLQUFuQyxFQUEwQ2tOLFlBQTFDLENBQVA7QUFDRCxPQVZJLEVBV0puRixJQVhJLENBV0MsTUFBTSxDQUFFLENBWFQsQ0FBUDtBQVlEO0FBQ0Y7O0FBRUR3RyxFQUFBQSxpQkFBaUIsQ0FBQ0YsR0FBbUIsR0FBRyxJQUF2QixFQUE2QnJPLEtBQTdCLEVBQXlDO0FBQ3hELFVBQU0wTyxhQUE2QixHQUNqQyxPQUFPMU8sS0FBSyxDQUFDZ0UsUUFBYixLQUEwQixRQUExQixHQUFxQyxDQUFDaEUsS0FBSyxDQUFDZ0UsUUFBUCxDQUFyQyxHQUF3RCxJQUQxRDtBQUVBLFVBQU0ySyxTQUF5QixHQUM3QjNPLEtBQUssQ0FBQ2dFLFFBQU4sSUFBa0JoRSxLQUFLLENBQUNnRSxRQUFOLENBQWUsS0FBZixDQUFsQixHQUEwQyxDQUFDaEUsS0FBSyxDQUFDZ0UsUUFBTixDQUFlLEtBQWYsQ0FBRCxDQUExQyxHQUFvRSxJQUR0RTtBQUVBLFVBQU00SyxTQUF5QixHQUM3QjVPLEtBQUssQ0FBQ2dFLFFBQU4sSUFBa0JoRSxLQUFLLENBQUNnRSxRQUFOLENBQWUsS0FBZixDQUFsQixHQUEwQ2hFLEtBQUssQ0FBQ2dFLFFBQU4sQ0FBZSxLQUFmLENBQTFDLEdBQWtFLElBRHBFLENBTHdELENBUXhEOztBQUNBLFVBQU02SyxNQUE0QixHQUFHLENBQUNILGFBQUQsRUFBZ0JDLFNBQWhCLEVBQTJCQyxTQUEzQixFQUFzQ1AsR0FBdEMsRUFBMkNqTCxNQUEzQyxDQUNuQzBMLElBQUksSUFBSUEsSUFBSSxLQUFLLElBRGtCLENBQXJDO0FBR0EsVUFBTUMsV0FBVyxHQUFHRixNQUFNLENBQUNHLE1BQVAsQ0FBYyxDQUFDQyxJQUFELEVBQU9ILElBQVAsS0FBZ0JHLElBQUksR0FBR0gsSUFBSSxDQUFDak4sTUFBMUMsRUFBa0QsQ0FBbEQsQ0FBcEI7QUFFQSxRQUFJcU4sZUFBZSxHQUFHLEVBQXRCOztBQUNBLFFBQUlILFdBQVcsR0FBRyxHQUFsQixFQUF1QjtBQUNyQkcsTUFBQUEsZUFBZSxHQUFHQyxtQkFBVUMsR0FBVixDQUFjUCxNQUFkLENBQWxCO0FBQ0QsS0FGRCxNQUVPO0FBQ0xLLE1BQUFBLGVBQWUsR0FBRyx3QkFBVUwsTUFBVixDQUFsQjtBQUNELEtBbkJ1RCxDQXFCeEQ7OztBQUNBLFFBQUksRUFBRSxjQUFjN08sS0FBaEIsQ0FBSixFQUE0QjtBQUMxQkEsTUFBQUEsS0FBSyxDQUFDZ0UsUUFBTixHQUFpQjtBQUNmMUQsUUFBQUEsR0FBRyxFQUFFNEk7QUFEVSxPQUFqQjtBQUdELEtBSkQsTUFJTyxJQUFJLE9BQU9sSixLQUFLLENBQUNnRSxRQUFiLEtBQTBCLFFBQTlCLEVBQXdDO0FBQzdDaEUsTUFBQUEsS0FBSyxDQUFDZ0UsUUFBTixHQUFpQjtBQUNmMUQsUUFBQUEsR0FBRyxFQUFFNEksU0FEVTtBQUVmbUcsUUFBQUEsR0FBRyxFQUFFclAsS0FBSyxDQUFDZ0U7QUFGSSxPQUFqQjtBQUlEOztBQUNEaEUsSUFBQUEsS0FBSyxDQUFDZ0UsUUFBTixDQUFlLEtBQWYsSUFBd0JrTCxlQUF4QjtBQUVBLFdBQU9sUCxLQUFQO0FBQ0Q7O0FBRURzTyxFQUFBQSxvQkFBb0IsQ0FBQ0QsR0FBYSxHQUFHLEVBQWpCLEVBQXFCck8sS0FBckIsRUFBaUM7QUFDbkQsVUFBTXNQLFVBQVUsR0FBR3RQLEtBQUssQ0FBQ2dFLFFBQU4sSUFBa0JoRSxLQUFLLENBQUNnRSxRQUFOLENBQWUsTUFBZixDQUFsQixHQUEyQ2hFLEtBQUssQ0FBQ2dFLFFBQU4sQ0FBZSxNQUFmLENBQTNDLEdBQW9FLEVBQXZGO0FBQ0EsUUFBSTZLLE1BQU0sR0FBRyxDQUFDLEdBQUdTLFVBQUosRUFBZ0IsR0FBR2pCLEdBQW5CLEVBQXdCakwsTUFBeEIsQ0FBK0IwTCxJQUFJLElBQUlBLElBQUksS0FBSyxJQUFoRCxDQUFiLENBRm1ELENBSW5EOztBQUNBRCxJQUFBQSxNQUFNLEdBQUcsQ0FBQyxHQUFHLElBQUlVLEdBQUosQ0FBUVYsTUFBUixDQUFKLENBQVQsQ0FMbUQsQ0FPbkQ7O0FBQ0EsUUFBSSxFQUFFLGNBQWM3TyxLQUFoQixDQUFKLEVBQTRCO0FBQzFCQSxNQUFBQSxLQUFLLENBQUNnRSxRQUFOLEdBQWlCO0FBQ2Z3TCxRQUFBQSxJQUFJLEVBQUV0RztBQURTLE9BQWpCO0FBR0QsS0FKRCxNQUlPLElBQUksT0FBT2xKLEtBQUssQ0FBQ2dFLFFBQWIsS0FBMEIsUUFBOUIsRUFBd0M7QUFDN0NoRSxNQUFBQSxLQUFLLENBQUNnRSxRQUFOLEdBQWlCO0FBQ2Z3TCxRQUFBQSxJQUFJLEVBQUV0RyxTQURTO0FBRWZtRyxRQUFBQSxHQUFHLEVBQUVyUCxLQUFLLENBQUNnRTtBQUZJLE9BQWpCO0FBSUQ7O0FBRURoRSxJQUFBQSxLQUFLLENBQUNnRSxRQUFOLENBQWUsTUFBZixJQUF5QjZLLE1BQXpCO0FBQ0EsV0FBTzdPLEtBQVA7QUFDRCxHQTd0QnNCLENBK3RCdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQXlLLEVBQUFBLElBQUksQ0FDRi9ILFNBREUsRUFFRjFDLEtBRkUsRUFHRjtBQUNFbU4sSUFBQUEsSUFERjtBQUVFQyxJQUFBQSxLQUZGO0FBR0VuTixJQUFBQSxHQUhGO0FBSUVvTixJQUFBQSxJQUFJLEdBQUcsRUFKVDtBQUtFb0MsSUFBQUEsS0FMRjtBQU1FMU4sSUFBQUEsSUFORjtBQU9FbUosSUFBQUEsRUFQRjtBQVFFd0UsSUFBQUEsUUFSRjtBQVNFQyxJQUFBQSxRQVRGO0FBVUVDLElBQUFBLGNBVkY7QUFXRUMsSUFBQUEsSUFYRjtBQVlFQyxJQUFBQSxlQUFlLEdBQUcsS0FacEI7QUFhRUMsSUFBQUE7QUFiRixNQWNTLEVBakJQLEVBa0JGeE4sSUFBUyxHQUFHLEVBbEJWLEVBbUJGb0gscUJBbkJFLEVBb0JZO0FBQ2QsVUFBTXRILFFBQVEsR0FBR3BDLEdBQUcsS0FBS2lKLFNBQXpCO0FBQ0EsVUFBTTVHLFFBQVEsR0FBR3JDLEdBQUcsSUFBSSxFQUF4QjtBQUNBaUwsSUFBQUEsRUFBRSxHQUNBQSxFQUFFLEtBQUssT0FBT2xMLEtBQUssQ0FBQ2dFLFFBQWIsSUFBeUIsUUFBekIsSUFBcUNsQyxNQUFNLENBQUNDLElBQVAsQ0FBWS9CLEtBQVosRUFBbUI2QixNQUFuQixLQUE4QixDQUFuRSxHQUF1RSxLQUF2RSxHQUErRSxNQUFwRixDQURKLENBSGMsQ0FLZDs7QUFDQXFKLElBQUFBLEVBQUUsR0FBR3VFLEtBQUssS0FBSyxJQUFWLEdBQWlCLE9BQWpCLEdBQTJCdkUsRUFBaEM7QUFFQSxRQUFJdEQsV0FBVyxHQUFHLElBQWxCO0FBQ0EsV0FBTyxLQUFLZSxrQkFBTCxDQUF3QmdCLHFCQUF4QixFQUErQzVCLElBQS9DLENBQW9EQyxnQkFBZ0IsSUFBSTtBQUM3RTtBQUNBO0FBQ0E7QUFDQSxhQUFPQSxnQkFBZ0IsQ0FDcEJDLFlBREksQ0FDU3ZGLFNBRFQsRUFDb0JMLFFBRHBCLEVBRUo2SCxLQUZJLENBRUVDLEtBQUssSUFBSTtBQUNkO0FBQ0E7QUFDQSxZQUFJQSxLQUFLLEtBQUtqQixTQUFkLEVBQXlCO0FBQ3ZCdEIsVUFBQUEsV0FBVyxHQUFHLEtBQWQ7QUFDQSxpQkFBTztBQUFFM0QsWUFBQUEsTUFBTSxFQUFFO0FBQVYsV0FBUDtBQUNEOztBQUNELGNBQU1rRyxLQUFOO0FBQ0QsT0FWSSxFQVdKcEMsSUFYSSxDQVdDdEYsTUFBTSxJQUFJO0FBQ2Q7QUFDQTtBQUNBO0FBQ0EsWUFBSTRLLElBQUksQ0FBQzJDLFdBQVQsRUFBc0I7QUFDcEIzQyxVQUFBQSxJQUFJLENBQUNyQixTQUFMLEdBQWlCcUIsSUFBSSxDQUFDMkMsV0FBdEI7QUFDQSxpQkFBTzNDLElBQUksQ0FBQzJDLFdBQVo7QUFDRDs7QUFDRCxZQUFJM0MsSUFBSSxDQUFDNEMsV0FBVCxFQUFzQjtBQUNwQjVDLFVBQUFBLElBQUksQ0FBQ2xCLFNBQUwsR0FBaUJrQixJQUFJLENBQUM0QyxXQUF0QjtBQUNBLGlCQUFPNUMsSUFBSSxDQUFDNEMsV0FBWjtBQUNEOztBQUNELGNBQU0vQyxZQUFZLEdBQUc7QUFDbkJDLFVBQUFBLElBRG1CO0FBRW5CQyxVQUFBQSxLQUZtQjtBQUduQkMsVUFBQUEsSUFIbUI7QUFJbkJ0TCxVQUFBQSxJQUptQjtBQUtuQjZOLFVBQUFBLGNBTG1CO0FBTW5CQyxVQUFBQSxJQU5tQjtBQU9uQkMsVUFBQUEsZUFQbUI7QUFRbkJDLFVBQUFBO0FBUm1CLFNBQXJCO0FBVUFqTyxRQUFBQSxNQUFNLENBQUNDLElBQVAsQ0FBWXNMLElBQVosRUFBa0IzTCxPQUFsQixDQUEwQm1GLFNBQVMsSUFBSTtBQUNyQyxjQUFJQSxTQUFTLENBQUMzRSxLQUFWLENBQWdCLGlDQUFoQixDQUFKLEVBQXdEO0FBQ3RELGtCQUFNLElBQUliLFlBQU1DLEtBQVYsQ0FBZ0JELFlBQU1DLEtBQU4sQ0FBWWEsZ0JBQTVCLEVBQStDLGtCQUFpQjBFLFNBQVUsRUFBMUUsQ0FBTjtBQUNEOztBQUNELGdCQUFNdUQsYUFBYSxHQUFHbkQsZ0JBQWdCLENBQUNKLFNBQUQsQ0FBdEM7O0FBQ0EsY0FBSSxDQUFDdUIsZ0JBQWdCLENBQUNpQyxnQkFBakIsQ0FBa0NELGFBQWxDLEVBQWlEMUgsU0FBakQsQ0FBTCxFQUFrRTtBQUNoRSxrQkFBTSxJQUFJckIsWUFBTUMsS0FBVixDQUNKRCxZQUFNQyxLQUFOLENBQVlhLGdCQURSLEVBRUgsdUJBQXNCMEUsU0FBVSxHQUY3QixDQUFOO0FBSUQ7QUFDRixTQVhEO0FBWUEsZUFBTyxDQUFDeEUsUUFBUSxHQUNaMkQsT0FBTyxDQUFDQyxPQUFSLEVBRFksR0FFWitCLGdCQUFnQixDQUFDK0Isa0JBQWpCLENBQW9DckgsU0FBcEMsRUFBK0NKLFFBQS9DLEVBQXlENEksRUFBekQsQ0FGRyxFQUlKbkQsSUFKSSxDQUlDLE1BQU0sS0FBS3lHLGtCQUFMLENBQXdCOUwsU0FBeEIsRUFBbUMxQyxLQUFuQyxFQUEwQ2tOLFlBQTFDLENBSlAsRUFLSm5GLElBTEksQ0FLQyxNQUFNLEtBQUs0RixnQkFBTCxDQUFzQmpMLFNBQXRCLEVBQWlDMUMsS0FBakMsRUFBd0NnSSxnQkFBeEMsQ0FMUCxFQU1KRCxJQU5JLENBTUMsTUFBTTtBQUNWLGNBQUlwRixlQUFKOztBQUNBLGNBQUksQ0FBQ04sUUFBTCxFQUFlO0FBQ2JyQyxZQUFBQSxLQUFLLEdBQUcsS0FBS2lLLHFCQUFMLENBQ05qQyxnQkFETSxFQUVOdEYsU0FGTSxFQUdOd0ksRUFITSxFQUlObEwsS0FKTSxFQUtOc0MsUUFMTSxDQUFSO0FBT0E7QUFDaEI7QUFDQTs7QUFDZ0JLLFlBQUFBLGVBQWUsR0FBRyxLQUFLdU4sa0JBQUwsQ0FDaEJsSSxnQkFEZ0IsRUFFaEJ0RixTQUZnQixFQUdoQjFDLEtBSGdCLEVBSWhCc0MsUUFKZ0IsRUFLaEJDLElBTGdCLEVBTWhCMkssWUFOZ0IsQ0FBbEI7QUFRRDs7QUFDRCxjQUFJLENBQUNsTixLQUFMLEVBQVk7QUFDVixnQkFBSWtMLEVBQUUsS0FBSyxLQUFYLEVBQWtCO0FBQ2hCLG9CQUFNLElBQUk3SixZQUFNQyxLQUFWLENBQWdCRCxZQUFNQyxLQUFOLENBQVlvSixnQkFBNUIsRUFBOEMsbUJBQTlDLENBQU47QUFDRCxhQUZELE1BRU87QUFDTCxxQkFBTyxFQUFQO0FBQ0Q7QUFDRjs7QUFDRCxjQUFJLENBQUNySSxRQUFMLEVBQWU7QUFDYixnQkFBSTZJLEVBQUUsS0FBSyxRQUFQLElBQW1CQSxFQUFFLEtBQUssUUFBOUIsRUFBd0M7QUFDdENsTCxjQUFBQSxLQUFLLEdBQUdELFdBQVcsQ0FBQ0MsS0FBRCxFQUFRc0MsUUFBUixDQUFuQjtBQUNELGFBRkQsTUFFTztBQUNMdEMsY0FBQUEsS0FBSyxHQUFHTyxVQUFVLENBQUNQLEtBQUQsRUFBUXNDLFFBQVIsQ0FBbEI7QUFDRDtBQUNGOztBQUNEbEIsVUFBQUEsYUFBYSxDQUFDcEIsS0FBRCxDQUFiOztBQUNBLGNBQUl5UCxLQUFKLEVBQVc7QUFDVCxnQkFBSSxDQUFDN0gsV0FBTCxFQUFrQjtBQUNoQixxQkFBTyxDQUFQO0FBQ0QsYUFGRCxNQUVPO0FBQ0wscUJBQU8sS0FBS0wsT0FBTCxDQUFha0ksS0FBYixDQUNML00sU0FESyxFQUVMRCxNQUZLLEVBR0x6QyxLQUhLLEVBSUw0UCxjQUpLLEVBS0wxRyxTQUxLLEVBTUwyRyxJQU5LLENBQVA7QUFRRDtBQUNGLFdBYkQsTUFhTyxJQUFJSCxRQUFKLEVBQWM7QUFDbkIsZ0JBQUksQ0FBQzlILFdBQUwsRUFBa0I7QUFDaEIscUJBQU8sRUFBUDtBQUNELGFBRkQsTUFFTztBQUNMLHFCQUFPLEtBQUtMLE9BQUwsQ0FBYW1JLFFBQWIsQ0FBc0JoTixTQUF0QixFQUFpQ0QsTUFBakMsRUFBeUN6QyxLQUF6QyxFQUFnRDBQLFFBQWhELENBQVA7QUFDRDtBQUNGLFdBTk0sTUFNQSxJQUFJQyxRQUFKLEVBQWM7QUFDbkIsZ0JBQUksQ0FBQy9ILFdBQUwsRUFBa0I7QUFDaEIscUJBQU8sRUFBUDtBQUNELGFBRkQsTUFFTztBQUNMLHFCQUFPLEtBQUtMLE9BQUwsQ0FBYTRJLFNBQWIsQ0FDTHpOLFNBREssRUFFTEQsTUFGSyxFQUdMa04sUUFISyxFQUlMQyxjQUpLLEVBS0xDLElBTEssRUFNTEUsT0FOSyxDQUFQO0FBUUQ7QUFDRixXQWJNLE1BYUEsSUFBSUEsT0FBSixFQUFhO0FBQ2xCLG1CQUFPLEtBQUt4SSxPQUFMLENBQWFrRCxJQUFiLENBQWtCL0gsU0FBbEIsRUFBNkJELE1BQTdCLEVBQXFDekMsS0FBckMsRUFBNENrTixZQUE1QyxDQUFQO0FBQ0QsV0FGTSxNQUVBO0FBQ0wsbUJBQU8sS0FBSzNGLE9BQUwsQ0FDSmtELElBREksQ0FDQy9ILFNBREQsRUFDWUQsTUFEWixFQUNvQnpDLEtBRHBCLEVBQzJCa04sWUFEM0IsRUFFSm5GLElBRkksQ0FFQ3ZCLE9BQU8sSUFDWEEsT0FBTyxDQUFDbEQsR0FBUixDQUFZVixNQUFNLElBQUk7QUFDcEJBLGNBQUFBLE1BQU0sR0FBR21FLG9CQUFvQixDQUFDbkUsTUFBRCxDQUE3QjtBQUNBLHFCQUFPUixtQkFBbUIsQ0FDeEJDLFFBRHdCLEVBRXhCQyxRQUZ3QixFQUd4QkMsSUFId0IsRUFJeEIySSxFQUp3QixFQUt4QmxELGdCQUx3QixFQU14QnRGLFNBTndCLEVBT3hCQyxlQVB3QixFQVF4QkMsTUFSd0IsQ0FBMUI7QUFVRCxhQVpELENBSEcsRUFpQkpzSCxLQWpCSSxDQWlCRUMsS0FBSyxJQUFJO0FBQ2Qsb0JBQU0sSUFBSTlJLFlBQU1DLEtBQVYsQ0FBZ0JELFlBQU1DLEtBQU4sQ0FBWThPLHFCQUE1QixFQUFtRGpHLEtBQW5ELENBQU47QUFDRCxhQW5CSSxDQUFQO0FBb0JEO0FBQ0YsU0FuR0ksQ0FBUDtBQW9HRCxPQWpKSSxDQUFQO0FBa0pELEtBdEpNLENBQVA7QUF1SkQ7O0FBRURrRyxFQUFBQSxZQUFZLENBQUMzTixTQUFELEVBQW1DO0FBQzdDLFdBQU8sS0FBS29GLFVBQUwsQ0FBZ0I7QUFBRVcsTUFBQUEsVUFBVSxFQUFFO0FBQWQsS0FBaEIsRUFDSlYsSUFESSxDQUNDQyxnQkFBZ0IsSUFBSUEsZ0JBQWdCLENBQUNDLFlBQWpCLENBQThCdkYsU0FBOUIsRUFBeUMsSUFBekMsQ0FEckIsRUFFSndILEtBRkksQ0FFRUMsS0FBSyxJQUFJO0FBQ2QsVUFBSUEsS0FBSyxLQUFLakIsU0FBZCxFQUF5QjtBQUN2QixlQUFPO0FBQUVqRixVQUFBQSxNQUFNLEVBQUU7QUFBVixTQUFQO0FBQ0QsT0FGRCxNQUVPO0FBQ0wsY0FBTWtHLEtBQU47QUFDRDtBQUNGLEtBUkksRUFTSnBDLElBVEksQ0FTRXRGLE1BQUQsSUFBaUI7QUFDckIsYUFBTyxLQUFLa0YsZ0JBQUwsQ0FBc0JqRixTQUF0QixFQUNKcUYsSUFESSxDQUNDLE1BQU0sS0FBS1IsT0FBTCxDQUFha0ksS0FBYixDQUFtQi9NLFNBQW5CLEVBQThCO0FBQUV1QixRQUFBQSxNQUFNLEVBQUU7QUFBVixPQUE5QixFQUE4QyxJQUE5QyxFQUFvRCxFQUFwRCxFQUF3RCxLQUF4RCxDQURQLEVBRUo4RCxJQUZJLENBRUMwSCxLQUFLLElBQUk7QUFDYixZQUFJQSxLQUFLLEdBQUcsQ0FBWixFQUFlO0FBQ2IsZ0JBQU0sSUFBSXBPLFlBQU1DLEtBQVYsQ0FDSixHQURJLEVBRUgsU0FBUW9CLFNBQVUsMkJBQTBCK00sS0FBTSwrQkFGL0MsQ0FBTjtBQUlEOztBQUNELGVBQU8sS0FBS2xJLE9BQUwsQ0FBYStJLFdBQWIsQ0FBeUI1TixTQUF6QixDQUFQO0FBQ0QsT0FWSSxFQVdKcUYsSUFYSSxDQVdDd0ksa0JBQWtCLElBQUk7QUFDMUIsWUFBSUEsa0JBQUosRUFBd0I7QUFDdEIsZ0JBQU1DLGtCQUFrQixHQUFHMU8sTUFBTSxDQUFDQyxJQUFQLENBQVlVLE1BQU0sQ0FBQ3dCLE1BQW5CLEVBQTJCYixNQUEzQixDQUN6QnlELFNBQVMsSUFBSXBFLE1BQU0sQ0FBQ3dCLE1BQVAsQ0FBYzRDLFNBQWQsRUFBeUJDLElBQXpCLEtBQWtDLFVBRHRCLENBQTNCO0FBR0EsaUJBQU9kLE9BQU8sQ0FBQ3VGLEdBQVIsQ0FDTGlGLGtCQUFrQixDQUFDbE4sR0FBbkIsQ0FBdUJtTixJQUFJLElBQ3pCLEtBQUtsSixPQUFMLENBQWErSSxXQUFiLENBQXlCbEssYUFBYSxDQUFDMUQsU0FBRCxFQUFZK04sSUFBWixDQUF0QyxDQURGLENBREssRUFJTDFJLElBSkssQ0FJQSxNQUFNO0FBQ1g7QUFDRCxXQU5NLENBQVA7QUFPRCxTQVhELE1BV087QUFDTCxpQkFBTy9CLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0Q7QUFDRixPQTFCSSxDQUFQO0FBMkJELEtBckNJLENBQVA7QUFzQ0QsR0EzOEJzQixDQTY4QnZCO0FBQ0E7QUFDQTs7O0FBQ0F5SyxFQUFBQSxzQkFBc0IsQ0FBQzFRLEtBQUQsRUFBNEI7QUFDaEQsV0FBTzhCLE1BQU0sQ0FBQzZPLE9BQVAsQ0FBZTNRLEtBQWYsRUFBc0JzRCxHQUF0QixDQUEwQnNOLENBQUMsSUFBSUEsQ0FBQyxDQUFDdE4sR0FBRixDQUFNNkYsQ0FBQyxJQUFJMEgsSUFBSSxDQUFDQyxTQUFMLENBQWUzSCxDQUFmLENBQVgsRUFBOEJ2RCxJQUE5QixDQUFtQyxHQUFuQyxDQUEvQixDQUFQO0FBQ0QsR0FsOUJzQixDQW85QnZCOzs7QUFDQW1MLEVBQUFBLGlCQUFpQixDQUFDL1EsS0FBRCxFQUFrQztBQUNqRCxRQUFJLENBQUNBLEtBQUssQ0FBQ3dCLEdBQVgsRUFBZ0I7QUFDZCxhQUFPeEIsS0FBUDtBQUNEOztBQUNELFVBQU1nTyxPQUFPLEdBQUdoTyxLQUFLLENBQUN3QixHQUFOLENBQVU4QixHQUFWLENBQWM4SyxDQUFDLElBQUksS0FBS3NDLHNCQUFMLENBQTRCdEMsQ0FBNUIsQ0FBbkIsQ0FBaEI7QUFDQSxRQUFJNEMsTUFBTSxHQUFHLEtBQWI7O0FBQ0EsT0FBRztBQUNEQSxNQUFBQSxNQUFNLEdBQUcsS0FBVDs7QUFDQSxXQUFLLElBQUlDLENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUdqRCxPQUFPLENBQUNuTSxNQUFSLEdBQWlCLENBQXJDLEVBQXdDb1AsQ0FBQyxFQUF6QyxFQUE2QztBQUMzQyxhQUFLLElBQUlDLENBQUMsR0FBR0QsQ0FBQyxHQUFHLENBQWpCLEVBQW9CQyxDQUFDLEdBQUdsRCxPQUFPLENBQUNuTSxNQUFoQyxFQUF3Q3FQLENBQUMsRUFBekMsRUFBNkM7QUFDM0MsZ0JBQU0sQ0FBQ0MsT0FBRCxFQUFVQyxNQUFWLElBQW9CcEQsT0FBTyxDQUFDaUQsQ0FBRCxDQUFQLENBQVdwUCxNQUFYLEdBQW9CbU0sT0FBTyxDQUFDa0QsQ0FBRCxDQUFQLENBQVdyUCxNQUEvQixHQUF3QyxDQUFDcVAsQ0FBRCxFQUFJRCxDQUFKLENBQXhDLEdBQWlELENBQUNBLENBQUQsRUFBSUMsQ0FBSixDQUEzRTtBQUNBLGdCQUFNRyxZQUFZLEdBQUdyRCxPQUFPLENBQUNtRCxPQUFELENBQVAsQ0FBaUJuQyxNQUFqQixDQUNuQixDQUFDc0MsR0FBRCxFQUFNMVEsS0FBTixLQUFnQjBRLEdBQUcsSUFBSXRELE9BQU8sQ0FBQ29ELE1BQUQsQ0FBUCxDQUFnQmpOLFFBQWhCLENBQXlCdkQsS0FBekIsSUFBa0MsQ0FBbEMsR0FBc0MsQ0FBMUMsQ0FEQSxFQUVuQixDQUZtQixDQUFyQjtBQUlBLGdCQUFNMlEsY0FBYyxHQUFHdkQsT0FBTyxDQUFDbUQsT0FBRCxDQUFQLENBQWlCdFAsTUFBeEM7O0FBQ0EsY0FBSXdQLFlBQVksS0FBS0UsY0FBckIsRUFBcUM7QUFDbkM7QUFDQTtBQUNBdlIsWUFBQUEsS0FBSyxDQUFDd0IsR0FBTixDQUFVZ1EsTUFBVixDQUFpQkosTUFBakIsRUFBeUIsQ0FBekI7QUFDQXBELFlBQUFBLE9BQU8sQ0FBQ3dELE1BQVIsQ0FBZUosTUFBZixFQUF1QixDQUF2QjtBQUNBSixZQUFBQSxNQUFNLEdBQUcsSUFBVDtBQUNBO0FBQ0Q7QUFDRjtBQUNGO0FBQ0YsS0FwQkQsUUFvQlNBLE1BcEJUOztBQXFCQSxRQUFJaFIsS0FBSyxDQUFDd0IsR0FBTixDQUFVSyxNQUFWLEtBQXFCLENBQXpCLEVBQTRCO0FBQzFCN0IsTUFBQUEsS0FBSyxtQ0FBUUEsS0FBUixHQUFrQkEsS0FBSyxDQUFDd0IsR0FBTixDQUFVLENBQVYsQ0FBbEIsQ0FBTDtBQUNBLGFBQU94QixLQUFLLENBQUN3QixHQUFiO0FBQ0Q7O0FBQ0QsV0FBT3hCLEtBQVA7QUFDRCxHQXIvQnNCLENBdS9CdkI7OztBQUNBeVIsRUFBQUEsa0JBQWtCLENBQUN6UixLQUFELEVBQW1DO0FBQ25ELFFBQUksQ0FBQ0EsS0FBSyxDQUFDMkIsSUFBWCxFQUFpQjtBQUNmLGFBQU8zQixLQUFQO0FBQ0Q7O0FBQ0QsVUFBTWdPLE9BQU8sR0FBR2hPLEtBQUssQ0FBQzJCLElBQU4sQ0FBVzJCLEdBQVgsQ0FBZThLLENBQUMsSUFBSSxLQUFLc0Msc0JBQUwsQ0FBNEJ0QyxDQUE1QixDQUFwQixDQUFoQjtBQUNBLFFBQUk0QyxNQUFNLEdBQUcsS0FBYjs7QUFDQSxPQUFHO0FBQ0RBLE1BQUFBLE1BQU0sR0FBRyxLQUFUOztBQUNBLFdBQUssSUFBSUMsQ0FBQyxHQUFHLENBQWIsRUFBZ0JBLENBQUMsR0FBR2pELE9BQU8sQ0FBQ25NLE1BQVIsR0FBaUIsQ0FBckMsRUFBd0NvUCxDQUFDLEVBQXpDLEVBQTZDO0FBQzNDLGFBQUssSUFBSUMsQ0FBQyxHQUFHRCxDQUFDLEdBQUcsQ0FBakIsRUFBb0JDLENBQUMsR0FBR2xELE9BQU8sQ0FBQ25NLE1BQWhDLEVBQXdDcVAsQ0FBQyxFQUF6QyxFQUE2QztBQUMzQyxnQkFBTSxDQUFDQyxPQUFELEVBQVVDLE1BQVYsSUFBb0JwRCxPQUFPLENBQUNpRCxDQUFELENBQVAsQ0FBV3BQLE1BQVgsR0FBb0JtTSxPQUFPLENBQUNrRCxDQUFELENBQVAsQ0FBV3JQLE1BQS9CLEdBQXdDLENBQUNxUCxDQUFELEVBQUlELENBQUosQ0FBeEMsR0FBaUQsQ0FBQ0EsQ0FBRCxFQUFJQyxDQUFKLENBQTNFO0FBQ0EsZ0JBQU1HLFlBQVksR0FBR3JELE9BQU8sQ0FBQ21ELE9BQUQsQ0FBUCxDQUFpQm5DLE1BQWpCLENBQ25CLENBQUNzQyxHQUFELEVBQU0xUSxLQUFOLEtBQWdCMFEsR0FBRyxJQUFJdEQsT0FBTyxDQUFDb0QsTUFBRCxDQUFQLENBQWdCak4sUUFBaEIsQ0FBeUJ2RCxLQUF6QixJQUFrQyxDQUFsQyxHQUFzQyxDQUExQyxDQURBLEVBRW5CLENBRm1CLENBQXJCO0FBSUEsZ0JBQU0yUSxjQUFjLEdBQUd2RCxPQUFPLENBQUNtRCxPQUFELENBQVAsQ0FBaUJ0UCxNQUF4Qzs7QUFDQSxjQUFJd1AsWUFBWSxLQUFLRSxjQUFyQixFQUFxQztBQUNuQztBQUNBO0FBQ0F2UixZQUFBQSxLQUFLLENBQUMyQixJQUFOLENBQVc2UCxNQUFYLENBQWtCTCxPQUFsQixFQUEyQixDQUEzQjtBQUNBbkQsWUFBQUEsT0FBTyxDQUFDd0QsTUFBUixDQUFlTCxPQUFmLEVBQXdCLENBQXhCO0FBQ0FILFlBQUFBLE1BQU0sR0FBRyxJQUFUO0FBQ0E7QUFDRDtBQUNGO0FBQ0Y7QUFDRixLQXBCRCxRQW9CU0EsTUFwQlQ7O0FBcUJBLFFBQUloUixLQUFLLENBQUMyQixJQUFOLENBQVdFLE1BQVgsS0FBc0IsQ0FBMUIsRUFBNkI7QUFDM0I3QixNQUFBQSxLQUFLLG1DQUFRQSxLQUFSLEdBQWtCQSxLQUFLLENBQUMyQixJQUFOLENBQVcsQ0FBWCxDQUFsQixDQUFMO0FBQ0EsYUFBTzNCLEtBQUssQ0FBQzJCLElBQWI7QUFDRDs7QUFDRCxXQUFPM0IsS0FBUDtBQUNELEdBeGhDc0IsQ0EwaEN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQWlLLEVBQUFBLHFCQUFxQixDQUNuQnhILE1BRG1CLEVBRW5CQyxTQUZtQixFQUduQkYsU0FIbUIsRUFJbkJ4QyxLQUptQixFQUtuQnNDLFFBQWUsR0FBRyxFQUxDLEVBTWQ7QUFDTDtBQUNBO0FBQ0EsUUFBSUcsTUFBTSxDQUFDaVAsMkJBQVAsQ0FBbUNoUCxTQUFuQyxFQUE4Q0osUUFBOUMsRUFBd0RFLFNBQXhELENBQUosRUFBd0U7QUFDdEUsYUFBT3hDLEtBQVA7QUFDRDs7QUFDRCxVQUFNZ0QsS0FBSyxHQUFHUCxNQUFNLENBQUNRLHdCQUFQLENBQWdDUCxTQUFoQyxDQUFkO0FBRUEsVUFBTWlQLE9BQU8sR0FBR3JQLFFBQVEsQ0FBQ2MsTUFBVCxDQUFnQm5ELEdBQUcsSUFBSTtBQUNyQyxhQUFPQSxHQUFHLENBQUNrQixPQUFKLENBQVksT0FBWixLQUF3QixDQUF4QixJQUE2QmxCLEdBQUcsSUFBSSxHQUEzQztBQUNELEtBRmUsQ0FBaEI7QUFJQSxVQUFNMlIsUUFBUSxHQUNaLENBQUMsS0FBRCxFQUFRLE1BQVIsRUFBZ0IsT0FBaEIsRUFBeUJ6USxPQUF6QixDQUFpQ3FCLFNBQWpDLElBQThDLENBQUMsQ0FBL0MsR0FBbUQsZ0JBQW5ELEdBQXNFLGlCQUR4RTtBQUdBLFVBQU1xUCxVQUFVLEdBQUcsRUFBbkI7O0FBRUEsUUFBSTdPLEtBQUssQ0FBQ1IsU0FBRCxDQUFMLElBQW9CUSxLQUFLLENBQUNSLFNBQUQsQ0FBTCxDQUFpQnNQLGFBQXpDLEVBQXdEO0FBQ3RERCxNQUFBQSxVQUFVLENBQUMvUSxJQUFYLENBQWdCLEdBQUdrQyxLQUFLLENBQUNSLFNBQUQsQ0FBTCxDQUFpQnNQLGFBQXBDO0FBQ0Q7O0FBRUQsUUFBSTlPLEtBQUssQ0FBQzRPLFFBQUQsQ0FBVCxFQUFxQjtBQUNuQixXQUFLLE1BQU1qRixLQUFYLElBQW9CM0osS0FBSyxDQUFDNE8sUUFBRCxDQUF6QixFQUFxQztBQUNuQyxZQUFJLENBQUNDLFVBQVUsQ0FBQzFOLFFBQVgsQ0FBb0J3SSxLQUFwQixDQUFMLEVBQWlDO0FBQy9Ca0YsVUFBQUEsVUFBVSxDQUFDL1EsSUFBWCxDQUFnQjZMLEtBQWhCO0FBQ0Q7QUFDRjtBQUNGLEtBM0JJLENBNEJMOzs7QUFDQSxRQUFJa0YsVUFBVSxDQUFDaFEsTUFBWCxHQUFvQixDQUF4QixFQUEyQjtBQUN6QjtBQUNBO0FBQ0E7QUFDQSxVQUFJOFAsT0FBTyxDQUFDOVAsTUFBUixJQUFrQixDQUF0QixFQUF5QjtBQUN2QjtBQUNEOztBQUNELFlBQU1nQixNQUFNLEdBQUc4TyxPQUFPLENBQUMsQ0FBRCxDQUF0QjtBQUNBLFlBQU1JLFdBQVcsR0FBRztBQUNsQjdGLFFBQUFBLE1BQU0sRUFBRSxTQURVO0FBRWxCeEosUUFBQUEsU0FBUyxFQUFFLE9BRk87QUFHbEJzQixRQUFBQSxRQUFRLEVBQUVuQjtBQUhRLE9BQXBCO0FBTUEsWUFBTW1MLE9BQU8sR0FBRzZELFVBQVUsQ0FBQ3ZPLEdBQVgsQ0FBZXBDLEdBQUcsSUFBSTtBQUNwQyxjQUFNOFEsZUFBZSxHQUFHdlAsTUFBTSxDQUFDcUcsZUFBUCxDQUF1QnBHLFNBQXZCLEVBQWtDeEIsR0FBbEMsQ0FBeEI7QUFDQSxjQUFNK1EsU0FBUyxHQUNiRCxlQUFlLElBQ2YsT0FBT0EsZUFBUCxLQUEyQixRQUQzQixJQUVBbFEsTUFBTSxDQUFDb1EsU0FBUCxDQUFpQkMsY0FBakIsQ0FBZ0NDLElBQWhDLENBQXFDSixlQUFyQyxFQUFzRCxNQUF0RCxDQUZBLEdBR0lBLGVBQWUsQ0FBQ2xMLElBSHBCLEdBSUksSUFMTjtBQU9BLFlBQUl1TCxXQUFKOztBQUVBLFlBQUlKLFNBQVMsS0FBSyxTQUFsQixFQUE2QjtBQUMzQjtBQUNBSSxVQUFBQSxXQUFXLEdBQUc7QUFBRSxhQUFDblIsR0FBRCxHQUFPNlE7QUFBVCxXQUFkO0FBQ0QsU0FIRCxNQUdPLElBQUlFLFNBQVMsS0FBSyxPQUFsQixFQUEyQjtBQUNoQztBQUNBSSxVQUFBQSxXQUFXLEdBQUc7QUFBRSxhQUFDblIsR0FBRCxHQUFPO0FBQUVvUixjQUFBQSxJQUFJLEVBQUUsQ0FBQ1AsV0FBRDtBQUFSO0FBQVQsV0FBZDtBQUNELFNBSE0sTUFHQSxJQUFJRSxTQUFTLEtBQUssUUFBbEIsRUFBNEI7QUFDakM7QUFDQUksVUFBQUEsV0FBVyxHQUFHO0FBQUUsYUFBQ25SLEdBQUQsR0FBTzZRO0FBQVQsV0FBZDtBQUNELFNBSE0sTUFHQTtBQUNMO0FBQ0E7QUFDQSxnQkFBTXpRLEtBQUssQ0FDUix3RUFBdUVvQixTQUFVLElBQUd4QixHQUFJLEVBRGhGLENBQVg7QUFHRCxTQTFCbUMsQ0EyQnBDOzs7QUFDQSxZQUFJWSxNQUFNLENBQUNvUSxTQUFQLENBQWlCQyxjQUFqQixDQUFnQ0MsSUFBaEMsQ0FBcUNwUyxLQUFyQyxFQUE0Q2tCLEdBQTVDLENBQUosRUFBc0Q7QUFDcEQsaUJBQU8sS0FBS3VRLGtCQUFMLENBQXdCO0FBQUU5UCxZQUFBQSxJQUFJLEVBQUUsQ0FBQzBRLFdBQUQsRUFBY3JTLEtBQWQ7QUFBUixXQUF4QixDQUFQO0FBQ0QsU0E5Qm1DLENBK0JwQzs7O0FBQ0EsZUFBTzhCLE1BQU0sQ0FBQ3lRLE1BQVAsQ0FBYyxFQUFkLEVBQWtCdlMsS0FBbEIsRUFBeUJxUyxXQUF6QixDQUFQO0FBQ0QsT0FqQ2UsQ0FBaEI7QUFtQ0EsYUFBT3JFLE9BQU8sQ0FBQ25NLE1BQVIsS0FBbUIsQ0FBbkIsR0FBdUJtTSxPQUFPLENBQUMsQ0FBRCxDQUE5QixHQUFvQyxLQUFLK0MsaUJBQUwsQ0FBdUI7QUFBRXZQLFFBQUFBLEdBQUcsRUFBRXdNO0FBQVAsT0FBdkIsQ0FBM0M7QUFDRCxLQWxERCxNQWtETztBQUNMLGFBQU9oTyxLQUFQO0FBQ0Q7QUFDRjs7QUFFRGtRLEVBQUFBLGtCQUFrQixDQUNoQnpOLE1BRGdCLEVBRWhCQyxTQUZnQixFQUdoQjFDLEtBQVUsR0FBRyxFQUhHLEVBSWhCc0MsUUFBZSxHQUFHLEVBSkYsRUFLaEJDLElBQVMsR0FBRyxFQUxJLEVBTWhCMkssWUFBOEIsR0FBRyxFQU5qQixFQU9DO0FBQ2pCLFVBQU1sSyxLQUFLLEdBQUdQLE1BQU0sQ0FBQ1Esd0JBQVAsQ0FBZ0NQLFNBQWhDLENBQWQ7QUFDQSxRQUFJLENBQUNNLEtBQUwsRUFBWSxPQUFPLElBQVA7QUFFWixVQUFNTCxlQUFlLEdBQUdLLEtBQUssQ0FBQ0wsZUFBOUI7QUFDQSxRQUFJLENBQUNBLGVBQUwsRUFBc0IsT0FBTyxJQUFQO0FBRXRCLFFBQUlMLFFBQVEsQ0FBQ25CLE9BQVQsQ0FBaUJuQixLQUFLLENBQUNnRSxRQUF2QixJQUFtQyxDQUFDLENBQXhDLEVBQTJDLE9BQU8sSUFBUCxDQVAxQixDQVNqQjtBQUNBO0FBQ0E7QUFDQTs7QUFDQSxVQUFNd08sWUFBWSxHQUFHdEYsWUFBWSxDQUFDbkwsSUFBbEMsQ0FiaUIsQ0FlakI7QUFDQTtBQUNBOztBQUNBLFVBQU0wUSxjQUFjLEdBQUcsRUFBdkI7QUFFQSxVQUFNQyxhQUFhLEdBQUduUSxJQUFJLENBQUNPLElBQTNCLENBcEJpQixDQXNCakI7O0FBQ0EsVUFBTTZQLEtBQUssR0FBRyxDQUFDcFEsSUFBSSxDQUFDcVEsU0FBTCxJQUFrQixFQUFuQixFQUF1QjVELE1BQXZCLENBQThCLENBQUNzQyxHQUFELEVBQU1uRCxDQUFOLEtBQVk7QUFDdERtRCxNQUFBQSxHQUFHLENBQUNuRCxDQUFELENBQUgsR0FBU3hMLGVBQWUsQ0FBQ3dMLENBQUQsQ0FBeEI7QUFDQSxhQUFPbUQsR0FBUDtBQUNELEtBSGEsRUFHWCxFQUhXLENBQWQsQ0F2QmlCLENBNEJqQjs7QUFDQSxVQUFNdUIsaUJBQWlCLEdBQUcsRUFBMUI7O0FBRUEsU0FBSyxNQUFNM1IsR0FBWCxJQUFrQnlCLGVBQWxCLEVBQW1DO0FBQ2pDO0FBQ0EsVUFBSXpCLEdBQUcsQ0FBQ21DLFVBQUosQ0FBZSxZQUFmLENBQUosRUFBa0M7QUFDaEMsWUFBSW1QLFlBQUosRUFBa0I7QUFDaEIsZ0JBQU0zTCxTQUFTLEdBQUczRixHQUFHLENBQUNxQyxTQUFKLENBQWMsRUFBZCxDQUFsQjs7QUFDQSxjQUFJLENBQUNpUCxZQUFZLENBQUNyTyxRQUFiLENBQXNCMEMsU0FBdEIsQ0FBTCxFQUF1QztBQUNyQztBQUNBcUcsWUFBQUEsWUFBWSxDQUFDbkwsSUFBYixJQUFxQm1MLFlBQVksQ0FBQ25MLElBQWIsQ0FBa0JqQixJQUFsQixDQUF1QitGLFNBQXZCLENBQXJCLENBRnFDLENBR3JDOztBQUNBNEwsWUFBQUEsY0FBYyxDQUFDM1IsSUFBZixDQUFvQitGLFNBQXBCO0FBQ0Q7QUFDRjs7QUFDRDtBQUNELE9BYmdDLENBZWpDOzs7QUFDQSxVQUFJM0YsR0FBRyxLQUFLLEdBQVosRUFBaUI7QUFDZjJSLFFBQUFBLGlCQUFpQixDQUFDL1IsSUFBbEIsQ0FBdUI2QixlQUFlLENBQUN6QixHQUFELENBQXRDO0FBQ0E7QUFDRDs7QUFFRCxVQUFJd1IsYUFBSixFQUFtQjtBQUNqQixZQUFJeFIsR0FBRyxLQUFLLGVBQVosRUFBNkI7QUFDM0I7QUFDQTJSLFVBQUFBLGlCQUFpQixDQUFDL1IsSUFBbEIsQ0FBdUI2QixlQUFlLENBQUN6QixHQUFELENBQXRDO0FBQ0E7QUFDRDs7QUFFRCxZQUFJeVIsS0FBSyxDQUFDelIsR0FBRCxDQUFMLElBQWNBLEdBQUcsQ0FBQ21DLFVBQUosQ0FBZSxPQUFmLENBQWxCLEVBQTJDO0FBQ3pDO0FBQ0F3UCxVQUFBQSxpQkFBaUIsQ0FBQy9SLElBQWxCLENBQXVCNlIsS0FBSyxDQUFDelIsR0FBRCxDQUE1QjtBQUNEO0FBQ0Y7QUFDRixLQWhFZ0IsQ0FrRWpCOzs7QUFDQSxRQUFJd1IsYUFBSixFQUFtQjtBQUNqQixZQUFNN1AsTUFBTSxHQUFHTixJQUFJLENBQUNPLElBQUwsQ0FBVUMsRUFBekI7O0FBQ0EsVUFBSUMsS0FBSyxDQUFDTCxlQUFOLENBQXNCRSxNQUF0QixDQUFKLEVBQW1DO0FBQ2pDZ1EsUUFBQUEsaUJBQWlCLENBQUMvUixJQUFsQixDQUF1QmtDLEtBQUssQ0FBQ0wsZUFBTixDQUFzQkUsTUFBdEIsQ0FBdkI7QUFDRDtBQUNGLEtBeEVnQixDQTBFakI7OztBQUNBLFFBQUk0UCxjQUFjLENBQUM1USxNQUFmLEdBQXdCLENBQTVCLEVBQStCO0FBQzdCbUIsTUFBQUEsS0FBSyxDQUFDTCxlQUFOLENBQXNCMkIsYUFBdEIsR0FBc0NtTyxjQUF0QztBQUNEOztBQUVELFFBQUlLLGFBQWEsR0FBR0QsaUJBQWlCLENBQUM3RCxNQUFsQixDQUF5QixDQUFDc0MsR0FBRCxFQUFNeUIsSUFBTixLQUFlO0FBQzFELFVBQUlBLElBQUosRUFBVTtBQUNSekIsUUFBQUEsR0FBRyxDQUFDeFEsSUFBSixDQUFTLEdBQUdpUyxJQUFaO0FBQ0Q7O0FBQ0QsYUFBT3pCLEdBQVA7QUFDRCxLQUxtQixFQUtqQixFQUxpQixDQUFwQixDQS9FaUIsQ0FzRmpCOztBQUNBdUIsSUFBQUEsaUJBQWlCLENBQUNuUixPQUFsQixDQUEwQnVDLE1BQU0sSUFBSTtBQUNsQyxVQUFJQSxNQUFKLEVBQVk7QUFDVjZPLFFBQUFBLGFBQWEsR0FBR0EsYUFBYSxDQUFDMVAsTUFBZCxDQUFxQmMsQ0FBQyxJQUFJRCxNQUFNLENBQUNFLFFBQVAsQ0FBZ0JELENBQWhCLENBQTFCLENBQWhCO0FBQ0Q7QUFDRixLQUpEO0FBTUEsV0FBTzRPLGFBQVA7QUFDRDs7QUFFREUsRUFBQUEsMEJBQTBCLEdBQUc7QUFDM0IsV0FBTyxLQUFLekwsT0FBTCxDQUFheUwsMEJBQWIsR0FBMENqTCxJQUExQyxDQUErQ2tMLG9CQUFvQixJQUFJO0FBQzVFLFdBQUt2TCxxQkFBTCxHQUE2QnVMLG9CQUE3QjtBQUNELEtBRk0sQ0FBUDtBQUdEOztBQUVEQyxFQUFBQSwwQkFBMEIsR0FBRztBQUMzQixRQUFJLENBQUMsS0FBS3hMLHFCQUFWLEVBQWlDO0FBQy9CLFlBQU0sSUFBSXBHLEtBQUosQ0FBVSw2Q0FBVixDQUFOO0FBQ0Q7O0FBQ0QsV0FBTyxLQUFLaUcsT0FBTCxDQUFhMkwsMEJBQWIsQ0FBd0MsS0FBS3hMLHFCQUE3QyxFQUFvRUssSUFBcEUsQ0FBeUUsTUFBTTtBQUNwRixXQUFLTCxxQkFBTCxHQUE2QixJQUE3QjtBQUNELEtBRk0sQ0FBUDtBQUdEOztBQUVEeUwsRUFBQUEseUJBQXlCLEdBQUc7QUFDMUIsUUFBSSxDQUFDLEtBQUt6TCxxQkFBVixFQUFpQztBQUMvQixZQUFNLElBQUlwRyxLQUFKLENBQVUsNENBQVYsQ0FBTjtBQUNEOztBQUNELFdBQU8sS0FBS2lHLE9BQUwsQ0FBYTRMLHlCQUFiLENBQXVDLEtBQUt6TCxxQkFBNUMsRUFBbUVLLElBQW5FLENBQXdFLE1BQU07QUFDbkYsV0FBS0wscUJBQUwsR0FBNkIsSUFBN0I7QUFDRCxLQUZNLENBQVA7QUFHRCxHQXR2Q3NCLENBd3ZDdkI7QUFDQTs7O0FBQ0EwTCxFQUFBQSxxQkFBcUIsR0FBRztBQUN0QixVQUFNQyxrQkFBa0IsR0FBRztBQUN6QnBQLE1BQUFBLE1BQU0sa0NBQ0RtRSxnQkFBZ0IsQ0FBQ2tMLGNBQWpCLENBQWdDQyxRQUQvQixHQUVEbkwsZ0JBQWdCLENBQUNrTCxjQUFqQixDQUFnQ0UsS0FGL0I7QUFEbUIsS0FBM0I7QUFNQSxVQUFNQyxrQkFBa0IsR0FBRztBQUN6QnhQLE1BQUFBLE1BQU0sa0NBQ0RtRSxnQkFBZ0IsQ0FBQ2tMLGNBQWpCLENBQWdDQyxRQUQvQixHQUVEbkwsZ0JBQWdCLENBQUNrTCxjQUFqQixDQUFnQ0ksS0FGL0I7QUFEbUIsS0FBM0I7QUFNQSxVQUFNQyx5QkFBeUIsR0FBRztBQUNoQzFQLE1BQUFBLE1BQU0sa0NBQ0RtRSxnQkFBZ0IsQ0FBQ2tMLGNBQWpCLENBQWdDQyxRQUQvQixHQUVEbkwsZ0JBQWdCLENBQUNrTCxjQUFqQixDQUFnQ00sWUFGL0I7QUFEMEIsS0FBbEM7QUFPQSxVQUFNQyxnQkFBZ0IsR0FBRyxLQUFLL0wsVUFBTCxHQUFrQkMsSUFBbEIsQ0FBdUJ0RixNQUFNLElBQUlBLE1BQU0sQ0FBQzJKLGtCQUFQLENBQTBCLE9BQTFCLENBQWpDLENBQXpCO0FBQ0EsVUFBTTBILGdCQUFnQixHQUFHLEtBQUtoTSxVQUFMLEdBQWtCQyxJQUFsQixDQUF1QnRGLE1BQU0sSUFBSUEsTUFBTSxDQUFDMkosa0JBQVAsQ0FBMEIsT0FBMUIsQ0FBakMsQ0FBekI7QUFDQSxVQUFNMkgsdUJBQXVCLEdBQzNCLEtBQUt4TSxPQUFMLFlBQXdCeU0sNEJBQXhCLEdBQ0ksS0FBS2xNLFVBQUwsR0FBa0JDLElBQWxCLENBQXVCdEYsTUFBTSxJQUFJQSxNQUFNLENBQUMySixrQkFBUCxDQUEwQixjQUExQixDQUFqQyxDQURKLEdBRUlwRyxPQUFPLENBQUNDLE9BQVIsRUFITjtBQUtBLFVBQU1nTyxrQkFBa0IsR0FBR0osZ0JBQWdCLENBQ3hDOUwsSUFEd0IsQ0FDbkIsTUFBTSxLQUFLUixPQUFMLENBQWEyTSxnQkFBYixDQUE4QixPQUE5QixFQUF1Q2Isa0JBQXZDLEVBQTJELENBQUMsVUFBRCxDQUEzRCxDQURhLEVBRXhCbkosS0FGd0IsQ0FFbEJDLEtBQUssSUFBSTtBQUNkZ0ssc0JBQU9DLElBQVAsQ0FBWSw2Q0FBWixFQUEyRGpLLEtBQTNEOztBQUNBLFlBQU1BLEtBQU47QUFDRCxLQUx3QixDQUEzQjtBQU9BLFVBQU1rSyw0QkFBNEIsR0FBR1IsZ0JBQWdCLENBQ2xEOUwsSUFEa0MsQ0FDN0IsTUFDSixLQUFLUixPQUFMLENBQWErTSxXQUFiLENBQ0UsT0FERixFQUVFakIsa0JBRkYsRUFHRSxDQUFDLFVBQUQsQ0FIRixFQUlFLDJCQUpGLEVBS0UsSUFMRixDQUZpQyxFQVVsQ25KLEtBVmtDLENBVTVCQyxLQUFLLElBQUk7QUFDZGdLLHNCQUFPQyxJQUFQLENBQVksb0RBQVosRUFBa0VqSyxLQUFsRTs7QUFDQSxZQUFNQSxLQUFOO0FBQ0QsS0Fia0MsQ0FBckM7QUFlQSxVQUFNb0ssZUFBZSxHQUFHVixnQkFBZ0IsQ0FDckM5TCxJQURxQixDQUNoQixNQUFNLEtBQUtSLE9BQUwsQ0FBYTJNLGdCQUFiLENBQThCLE9BQTlCLEVBQXVDYixrQkFBdkMsRUFBMkQsQ0FBQyxPQUFELENBQTNELENBRFUsRUFFckJuSixLQUZxQixDQUVmQyxLQUFLLElBQUk7QUFDZGdLLHNCQUFPQyxJQUFQLENBQVksd0RBQVosRUFBc0VqSyxLQUF0RTs7QUFDQSxZQUFNQSxLQUFOO0FBQ0QsS0FMcUIsQ0FBeEI7QUFPQSxVQUFNcUsseUJBQXlCLEdBQUdYLGdCQUFnQixDQUMvQzlMLElBRCtCLENBQzFCLE1BQ0osS0FBS1IsT0FBTCxDQUFhK00sV0FBYixDQUNFLE9BREYsRUFFRWpCLGtCQUZGLEVBR0UsQ0FBQyxPQUFELENBSEYsRUFJRSx3QkFKRixFQUtFLElBTEYsQ0FGOEIsRUFVL0JuSixLQVYrQixDQVV6QkMsS0FBSyxJQUFJO0FBQ2RnSyxzQkFBT0MsSUFBUCxDQUFZLGlEQUFaLEVBQStEakssS0FBL0Q7O0FBQ0EsWUFBTUEsS0FBTjtBQUNELEtBYitCLENBQWxDO0FBZUEsVUFBTXNLLGNBQWMsR0FBR1gsZ0JBQWdCLENBQ3BDL0wsSUFEb0IsQ0FDZixNQUFNLEtBQUtSLE9BQUwsQ0FBYTJNLGdCQUFiLENBQThCLE9BQTlCLEVBQXVDVCxrQkFBdkMsRUFBMkQsQ0FBQyxNQUFELENBQTNELENBRFMsRUFFcEJ2SixLQUZvQixDQUVkQyxLQUFLLElBQUk7QUFDZGdLLHNCQUFPQyxJQUFQLENBQVksNkNBQVosRUFBMkRqSyxLQUEzRDs7QUFDQSxZQUFNQSxLQUFOO0FBQ0QsS0FMb0IsQ0FBdkI7QUFPQSxVQUFNdUsseUJBQXlCLEdBQzdCLEtBQUtuTixPQUFMLFlBQXdCeU0sNEJBQXhCLEdBQ0lELHVCQUF1QixDQUN0QmhNLElBREQsQ0FDTSxNQUNKLEtBQUtSLE9BQUwsQ0FBYTJNLGdCQUFiLENBQThCLGNBQTlCLEVBQThDUCx5QkFBOUMsRUFBeUUsQ0FBQyxPQUFELENBQXpFLENBRkYsRUFJQ3pKLEtBSkQsQ0FJT0MsS0FBSyxJQUFJO0FBQ2RnSyxzQkFBT0MsSUFBUCxDQUFZLDBEQUFaLEVBQXdFakssS0FBeEU7O0FBQ0EsWUFBTUEsS0FBTjtBQUNELEtBUEQsQ0FESixHQVNJbkUsT0FBTyxDQUFDQyxPQUFSLEVBVk47QUFZQSxVQUFNME8sc0JBQXNCLEdBQzFCLEtBQUtwTixPQUFMLFlBQXdCeU0sNEJBQXhCLEdBQ0lELHVCQUF1QixDQUN0QmhNLElBREQsQ0FDTSxNQUNKLEtBQUtSLE9BQUwsQ0FBYStNLFdBQWIsQ0FDRSxjQURGLEVBRUVYLHlCQUZGLEVBR0UsQ0FBQyxRQUFELENBSEYsRUFJRSxLQUpGLEVBS0UsS0FMRixFQU1FO0FBQUVpQixNQUFBQSxHQUFHLEVBQUU7QUFBUCxLQU5GLENBRkYsRUFXQzFLLEtBWEQsQ0FXT0MsS0FBSyxJQUFJO0FBQ2RnSyxzQkFBT0MsSUFBUCxDQUFZLDBEQUFaLEVBQXdFakssS0FBeEU7O0FBQ0EsWUFBTUEsS0FBTjtBQUNELEtBZEQsQ0FESixHQWdCSW5FLE9BQU8sQ0FBQ0MsT0FBUixFQWpCTjtBQW1CQSxVQUFNNE8sWUFBWSxHQUFHLEtBQUt0TixPQUFMLENBQWF1Tix1QkFBYixFQUFyQixDQTdHc0IsQ0ErR3RCOztBQUNBLFVBQU1DLFdBQVcsR0FBRyxLQUFLeE4sT0FBTCxDQUFhNkwscUJBQWIsQ0FBbUM7QUFDckQ0QixNQUFBQSxzQkFBc0IsRUFBRTVNLGdCQUFnQixDQUFDNE07QUFEWSxLQUFuQyxDQUFwQjtBQUdBLFdBQU9oUCxPQUFPLENBQUN1RixHQUFSLENBQVksQ0FDakIwSSxrQkFEaUIsRUFFakJJLDRCQUZpQixFQUdqQkUsZUFIaUIsRUFJakJDLHlCQUppQixFQUtqQkMsY0FMaUIsRUFNakJDLHlCQU5pQixFQU9qQkMsc0JBUGlCLEVBUWpCSSxXQVJpQixFQVNqQkYsWUFUaUIsQ0FBWixDQUFQO0FBV0Q7O0FBeDNDc0I7O0FBNjNDekJJLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjdOLGtCQUFqQixDLENBQ0E7O0FBQ0E0TixNQUFNLENBQUNDLE9BQVAsQ0FBZUMsY0FBZixHQUFnQy9ULGFBQWhDIiwic291cmNlc0NvbnRlbnQiOlsi77u/Ly8gQGZsb3dcbi8vIEEgZGF0YWJhc2UgYWRhcHRlciB0aGF0IHdvcmtzIHdpdGggZGF0YSBleHBvcnRlZCBmcm9tIHRoZSBob3N0ZWRcbi8vIFBhcnNlIGRhdGFiYXNlLlxuXG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCB7IFBhcnNlIH0gZnJvbSAncGFyc2Uvbm9kZSc7XG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCBpbnRlcnNlY3QgZnJvbSAnaW50ZXJzZWN0Jztcbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuaW1wb3J0IGRlZXBjb3B5IGZyb20gJ2RlZXBjb3B5JztcbmltcG9ydCBsb2dnZXIgZnJvbSAnLi4vbG9nZ2VyJztcbmltcG9ydCAqIGFzIFNjaGVtYUNvbnRyb2xsZXIgZnJvbSAnLi9TY2hlbWFDb250cm9sbGVyJztcbmltcG9ydCB7IFN0b3JhZ2VBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvU3RvcmFnZS9TdG9yYWdlQWRhcHRlcic7XG5pbXBvcnQgdHlwZSB7IFF1ZXJ5T3B0aW9ucywgRnVsbFF1ZXJ5T3B0aW9ucyB9IGZyb20gJy4uL0FkYXB0ZXJzL1N0b3JhZ2UvU3RvcmFnZUFkYXB0ZXInO1xuXG5mdW5jdGlvbiBhZGRXcml0ZUFDTChxdWVyeSwgYWNsKSB7XG4gIGNvbnN0IG5ld1F1ZXJ5ID0gXy5jbG9uZURlZXAocXVlcnkpO1xuICAvL0Nhbid0IGJlIGFueSBleGlzdGluZyAnX3dwZXJtJyBxdWVyeSwgd2UgZG9uJ3QgYWxsb3cgY2xpZW50IHF1ZXJpZXMgb24gdGhhdCwgbm8gbmVlZCB0byAkYW5kXG4gIG5ld1F1ZXJ5Ll93cGVybSA9IHsgJGluOiBbbnVsbCwgLi4uYWNsXSB9O1xuICByZXR1cm4gbmV3UXVlcnk7XG59XG5cbmZ1bmN0aW9uIGFkZFJlYWRBQ0wocXVlcnksIGFjbCkge1xuICBjb25zdCBuZXdRdWVyeSA9IF8uY2xvbmVEZWVwKHF1ZXJ5KTtcbiAgLy9DYW4ndCBiZSBhbnkgZXhpc3RpbmcgJ19ycGVybScgcXVlcnksIHdlIGRvbid0IGFsbG93IGNsaWVudCBxdWVyaWVzIG9uIHRoYXQsIG5vIG5lZWQgdG8gJGFuZFxuICBuZXdRdWVyeS5fcnBlcm0gPSB7ICRpbjogW251bGwsICcqJywgLi4uYWNsXSB9O1xuICByZXR1cm4gbmV3UXVlcnk7XG59XG5cbi8vIFRyYW5zZm9ybXMgYSBSRVNUIEFQSSBmb3JtYXR0ZWQgQUNMIG9iamVjdCB0byBvdXIgdHdvLWZpZWxkIG1vbmdvIGZvcm1hdC5cbmNvbnN0IHRyYW5zZm9ybU9iamVjdEFDTCA9ICh7IEFDTCwgLi4ucmVzdWx0IH0pID0+IHtcbiAgaWYgKCFBQ0wpIHtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcmVzdWx0Ll93cGVybSA9IFtdO1xuICByZXN1bHQuX3JwZXJtID0gW107XG5cbiAgZm9yIChjb25zdCBlbnRyeSBpbiBBQ0wpIHtcbiAgICBpZiAoQUNMW2VudHJ5XS5yZWFkKSB7XG4gICAgICByZXN1bHQuX3JwZXJtLnB1c2goZW50cnkpO1xuICAgIH1cbiAgICBpZiAoQUNMW2VudHJ5XS53cml0ZSkge1xuICAgICAgcmVzdWx0Ll93cGVybS5wdXNoKGVudHJ5KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbmNvbnN0IHNwZWNpYWxRdWVyeWtleXMgPSBbXG4gICckYW5kJyxcbiAgJyRvcicsXG4gICckbm9yJyxcbiAgJ19ycGVybScsXG4gICdfd3Blcm0nLFxuICAnX3BlcmlzaGFibGVfdG9rZW4nLFxuICAnX2VtYWlsX3ZlcmlmeV90b2tlbicsXG4gICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnLFxuICAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JyxcbiAgJ19mYWlsZWRfbG9naW5fY291bnQnLFxuXTtcblxuY29uc3QgaXNTcGVjaWFsUXVlcnlLZXkgPSBrZXkgPT4ge1xuICByZXR1cm4gc3BlY2lhbFF1ZXJ5a2V5cy5pbmRleE9mKGtleSkgPj0gMDtcbn07XG5cbmNvbnN0IHZhbGlkYXRlUXVlcnkgPSAocXVlcnk6IGFueSk6IHZvaWQgPT4ge1xuICBpZiAocXVlcnkuQUNMKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksICdDYW5ub3QgcXVlcnkgb24gQUNMLicpO1xuICB9XG5cbiAgaWYgKHF1ZXJ5LiRvcikge1xuICAgIGlmIChxdWVyeS4kb3IgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgcXVlcnkuJG9yLmZvckVhY2godmFsaWRhdGVRdWVyeSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnQmFkICRvciBmb3JtYXQgLSB1c2UgYW4gYXJyYXkgdmFsdWUuJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHF1ZXJ5LiRhbmQpIHtcbiAgICBpZiAocXVlcnkuJGFuZCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICBxdWVyeS4kYW5kLmZvckVhY2godmFsaWRhdGVRdWVyeSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnQmFkICRhbmQgZm9ybWF0IC0gdXNlIGFuIGFycmF5IHZhbHVlLicpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChxdWVyeS4kbm9yKSB7XG4gICAgaWYgKHF1ZXJ5LiRub3IgaW5zdGFuY2VvZiBBcnJheSAmJiBxdWVyeS4kbm9yLmxlbmd0aCA+IDApIHtcbiAgICAgIHF1ZXJ5LiRub3IuZm9yRWFjaCh2YWxpZGF0ZVF1ZXJ5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAnQmFkICRub3IgZm9ybWF0IC0gdXNlIGFuIGFycmF5IG9mIGF0IGxlYXN0IDEgdmFsdWUuJ1xuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBPYmplY3Qua2V5cyhxdWVyeSkuZm9yRWFjaChrZXkgPT4ge1xuICAgIGlmIChxdWVyeSAmJiBxdWVyeVtrZXldICYmIHF1ZXJ5W2tleV0uJHJlZ2V4KSB7XG4gICAgICBpZiAodHlwZW9mIHF1ZXJ5W2tleV0uJG9wdGlvbnMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGlmICghcXVlcnlba2V5XS4kb3B0aW9ucy5tYXRjaCgvXltpbXhzXSskLykpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAgICAgYEJhZCAkb3B0aW9ucyB2YWx1ZSBmb3IgcXVlcnk6ICR7cXVlcnlba2V5XS4kb3B0aW9uc31gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWlzU3BlY2lhbFF1ZXJ5S2V5KGtleSkgJiYgIWtleS5tYXRjaCgvXlthLXpBLVpdW2EtekEtWjAtOV9cXC5dKiQvKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUsIGBJbnZhbGlkIGtleSBuYW1lOiAke2tleX1gKTtcbiAgICB9XG4gIH0pO1xufTtcblxuLy8gRmlsdGVycyBvdXQgYW55IGRhdGEgdGhhdCBzaG91bGRuJ3QgYmUgb24gdGhpcyBSRVNULWZvcm1hdHRlZCBvYmplY3QuXG5jb25zdCBmaWx0ZXJTZW5zaXRpdmVEYXRhID0gKFxuICBpc01hc3RlcjogYm9vbGVhbixcbiAgYWNsR3JvdXA6IGFueVtdLFxuICBhdXRoOiBhbnksXG4gIG9wZXJhdGlvbjogYW55LFxuICBzY2hlbWE6IFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlcixcbiAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gIHByb3RlY3RlZEZpZWxkczogbnVsbCB8IEFycmF5PGFueT4sXG4gIG9iamVjdDogYW55XG4pID0+IHtcbiAgbGV0IHVzZXJJZCA9IG51bGw7XG4gIGlmIChhdXRoICYmIGF1dGgudXNlcikgdXNlcklkID0gYXV0aC51c2VyLmlkO1xuXG4gIC8vIHJlcGxhY2UgcHJvdGVjdGVkRmllbGRzIHdoZW4gdXNpbmcgcG9pbnRlci1wZXJtaXNzaW9uc1xuICBjb25zdCBwZXJtcyA9IHNjaGVtYS5nZXRDbGFzc0xldmVsUGVybWlzc2lvbnMoY2xhc3NOYW1lKTtcbiAgaWYgKHBlcm1zKSB7XG4gICAgY29uc3QgaXNSZWFkT3BlcmF0aW9uID0gWydnZXQnLCAnZmluZCddLmluZGV4T2Yob3BlcmF0aW9uKSA+IC0xO1xuXG4gICAgaWYgKGlzUmVhZE9wZXJhdGlvbiAmJiBwZXJtcy5wcm90ZWN0ZWRGaWVsZHMpIHtcbiAgICAgIC8vIGV4dHJhY3QgcHJvdGVjdGVkRmllbGRzIGFkZGVkIHdpdGggdGhlIHBvaW50ZXItcGVybWlzc2lvbiBwcmVmaXhcbiAgICAgIGNvbnN0IHByb3RlY3RlZEZpZWxkc1BvaW50ZXJQZXJtID0gT2JqZWN0LmtleXMocGVybXMucHJvdGVjdGVkRmllbGRzKVxuICAgICAgICAuZmlsdGVyKGtleSA9PiBrZXkuc3RhcnRzV2l0aCgndXNlckZpZWxkOicpKVxuICAgICAgICAubWFwKGtleSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHsga2V5OiBrZXkuc3Vic3RyaW5nKDEwKSwgdmFsdWU6IHBlcm1zLnByb3RlY3RlZEZpZWxkc1trZXldIH07XG4gICAgICAgIH0pO1xuXG4gICAgICBjb25zdCBuZXdQcm90ZWN0ZWRGaWVsZHM6IEFycmF5PHN0cmluZz5bXSA9IFtdO1xuICAgICAgbGV0IG92ZXJyaWRlUHJvdGVjdGVkRmllbGRzID0gZmFsc2U7XG5cbiAgICAgIC8vIGNoZWNrIGlmIHRoZSBvYmplY3QgZ3JhbnRzIHRoZSBjdXJyZW50IHVzZXIgYWNjZXNzIGJhc2VkIG9uIHRoZSBleHRyYWN0ZWQgZmllbGRzXG4gICAgICBwcm90ZWN0ZWRGaWVsZHNQb2ludGVyUGVybS5mb3JFYWNoKHBvaW50ZXJQZXJtID0+IHtcbiAgICAgICAgbGV0IHBvaW50ZXJQZXJtSW5jbHVkZXNVc2VyID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IHJlYWRVc2VyRmllbGRWYWx1ZSA9IG9iamVjdFtwb2ludGVyUGVybS5rZXldO1xuICAgICAgICBpZiAocmVhZFVzZXJGaWVsZFZhbHVlKSB7XG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmVhZFVzZXJGaWVsZFZhbHVlKSkge1xuICAgICAgICAgICAgcG9pbnRlclBlcm1JbmNsdWRlc1VzZXIgPSByZWFkVXNlckZpZWxkVmFsdWUuc29tZShcbiAgICAgICAgICAgICAgdXNlciA9PiB1c2VyLm9iamVjdElkICYmIHVzZXIub2JqZWN0SWQgPT09IHVzZXJJZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcG9pbnRlclBlcm1JbmNsdWRlc1VzZXIgPVxuICAgICAgICAgICAgICByZWFkVXNlckZpZWxkVmFsdWUub2JqZWN0SWQgJiYgcmVhZFVzZXJGaWVsZFZhbHVlLm9iamVjdElkID09PSB1c2VySWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvaW50ZXJQZXJtSW5jbHVkZXNVc2VyKSB7XG4gICAgICAgICAgb3ZlcnJpZGVQcm90ZWN0ZWRGaWVsZHMgPSB0cnVlO1xuICAgICAgICAgIG5ld1Byb3RlY3RlZEZpZWxkcy5wdXNoKHBvaW50ZXJQZXJtLnZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8vIGlmIGF0IGxlYXN0IG9uZSBwb2ludGVyLXBlcm1pc3Npb24gYWZmZWN0ZWQgdGhlIGN1cnJlbnQgdXNlclxuICAgICAgLy8gaW50ZXJzZWN0IHZzIHByb3RlY3RlZEZpZWxkcyBmcm9tIHByZXZpb3VzIHN0YWdlIChAc2VlIGFkZFByb3RlY3RlZEZpZWxkcylcbiAgICAgIC8vIFNldHMgdGhlb3J5IChpbnRlcnNlY3Rpb25zKTogQSB4IChCIHggQykgPT0gKEEgeCBCKSB4IENcbiAgICAgIGlmIChvdmVycmlkZVByb3RlY3RlZEZpZWxkcyAmJiBwcm90ZWN0ZWRGaWVsZHMpIHtcbiAgICAgICAgbmV3UHJvdGVjdGVkRmllbGRzLnB1c2gocHJvdGVjdGVkRmllbGRzKTtcbiAgICAgIH1cbiAgICAgIC8vIGludGVyc2VjdCBhbGwgc2V0cyBvZiBwcm90ZWN0ZWRGaWVsZHNcbiAgICAgIG5ld1Byb3RlY3RlZEZpZWxkcy5mb3JFYWNoKGZpZWxkcyA9PiB7XG4gICAgICAgIGlmIChmaWVsZHMpIHtcbiAgICAgICAgICAvLyBpZiB0aGVyZSdyZSBubyBwcm90Y3RlZEZpZWxkcyBieSBvdGhlciBjcml0ZXJpYSAoIGlkIC8gcm9sZSAvIGF1dGgpXG4gICAgICAgICAgLy8gdGhlbiB3ZSBtdXN0IGludGVyc2VjdCBlYWNoIHNldCAocGVyIHVzZXJGaWVsZClcbiAgICAgICAgICBpZiAoIXByb3RlY3RlZEZpZWxkcykge1xuICAgICAgICAgICAgcHJvdGVjdGVkRmllbGRzID0gZmllbGRzO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm90ZWN0ZWRGaWVsZHMgPSBwcm90ZWN0ZWRGaWVsZHMuZmlsdGVyKHYgPT4gZmllbGRzLmluY2x1ZGVzKHYpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGlzVXNlckNsYXNzID0gY2xhc3NOYW1lID09PSAnX1VzZXInO1xuXG4gIC8qIHNwZWNpYWwgdHJlYXQgZm9yIHRoZSB1c2VyIGNsYXNzOiBkb24ndCBmaWx0ZXIgcHJvdGVjdGVkRmllbGRzIGlmIGN1cnJlbnRseSBsb2dnZWRpbiB1c2VyIGlzXG4gIHRoZSByZXRyaWV2ZWQgdXNlciAqL1xuICBpZiAoIShpc1VzZXJDbGFzcyAmJiB1c2VySWQgJiYgb2JqZWN0Lm9iamVjdElkID09PSB1c2VySWQpKSB7XG4gICAgcHJvdGVjdGVkRmllbGRzICYmIHByb3RlY3RlZEZpZWxkcy5mb3JFYWNoKGsgPT4gZGVsZXRlIG9iamVjdFtrXSk7XG5cbiAgICAvLyBmaWVsZHMgbm90IHJlcXVlc3RlZCBieSBjbGllbnQgKGV4Y2x1ZGVkKSxcbiAgICAvL2J1dCB3ZXJlIG5lZWRlZCB0byBhcHBseSBwcm90ZWN0dGVkRmllbGRzXG4gICAgcGVybXMucHJvdGVjdGVkRmllbGRzICYmXG4gICAgICBwZXJtcy5wcm90ZWN0ZWRGaWVsZHMudGVtcG9yYXJ5S2V5cyAmJlxuICAgICAgcGVybXMucHJvdGVjdGVkRmllbGRzLnRlbXBvcmFyeUtleXMuZm9yRWFjaChrID0+IGRlbGV0ZSBvYmplY3Rba10pO1xuICB9XG5cbiAgaWYgKCFpc1VzZXJDbGFzcykge1xuICAgIHJldHVybiBvYmplY3Q7XG4gIH1cblxuICBvYmplY3QucGFzc3dvcmQgPSBvYmplY3QuX2hhc2hlZF9wYXNzd29yZDtcbiAgZGVsZXRlIG9iamVjdC5faGFzaGVkX3Bhc3N3b3JkO1xuXG4gIGRlbGV0ZSBvYmplY3Quc2Vzc2lvblRva2VuO1xuXG4gIGlmIChpc01hc3Rlcikge1xuICAgIHJldHVybiBvYmplY3Q7XG4gIH1cbiAgZGVsZXRlIG9iamVjdC5fZW1haWxfdmVyaWZ5X3Rva2VuO1xuICBkZWxldGUgb2JqZWN0Ll9wZXJpc2hhYmxlX3Rva2VuO1xuICBkZWxldGUgb2JqZWN0Ll9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQ7XG4gIGRlbGV0ZSBvYmplY3QuX3RvbWJzdG9uZTtcbiAgZGVsZXRlIG9iamVjdC5fZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQ7XG4gIGRlbGV0ZSBvYmplY3QuX2ZhaWxlZF9sb2dpbl9jb3VudDtcbiAgZGVsZXRlIG9iamVjdC5fYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQ7XG4gIGRlbGV0ZSBvYmplY3QuX3Bhc3N3b3JkX2NoYW5nZWRfYXQ7XG4gIGRlbGV0ZSBvYmplY3QuX3Bhc3N3b3JkX2hpc3Rvcnk7XG5cbiAgaWYgKGFjbEdyb3VwLmluZGV4T2Yob2JqZWN0Lm9iamVjdElkKSA+IC0xKSB7XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfVxuICBkZWxldGUgb2JqZWN0LmF1dGhEYXRhO1xuICByZXR1cm4gb2JqZWN0O1xufTtcblxuaW1wb3J0IHR5cGUgeyBMb2FkU2NoZW1hT3B0aW9ucyB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IE1vbmdvU3RvcmFnZUFkYXB0ZXIgZnJvbSAnLi4vQWRhcHRlcnMvU3RvcmFnZS9Nb25nby9Nb25nb1N0b3JhZ2VBZGFwdGVyJztcblxuLy8gUnVucyBhbiB1cGRhdGUgb24gdGhlIGRhdGFiYXNlLlxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGFuIG9iamVjdCB3aXRoIHRoZSBuZXcgdmFsdWVzIGZvciBmaWVsZFxuLy8gbW9kaWZpY2F0aW9ucyB0aGF0IGRvbid0IGtub3cgdGhlaXIgcmVzdWx0cyBhaGVhZCBvZiB0aW1lLCBsaWtlXG4vLyAnaW5jcmVtZW50Jy5cbi8vIE9wdGlvbnM6XG4vLyAgIGFjbDogIGEgbGlzdCBvZiBzdHJpbmdzLiBJZiB0aGUgb2JqZWN0IHRvIGJlIHVwZGF0ZWQgaGFzIGFuIEFDTCxcbi8vICAgICAgICAgb25lIG9mIHRoZSBwcm92aWRlZCBzdHJpbmdzIG11c3QgcHJvdmlkZSB0aGUgY2FsbGVyIHdpdGhcbi8vICAgICAgICAgd3JpdGUgcGVybWlzc2lvbnMuXG5jb25zdCBzcGVjaWFsS2V5c0ZvclVwZGF0ZSA9IFtcbiAgJ19oYXNoZWRfcGFzc3dvcmQnLFxuICAnX3BlcmlzaGFibGVfdG9rZW4nLFxuICAnX2VtYWlsX3ZlcmlmeV90b2tlbicsXG4gICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnLFxuICAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JyxcbiAgJ19mYWlsZWRfbG9naW5fY291bnQnLFxuICAnX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCcsXG4gICdfcGFzc3dvcmRfY2hhbmdlZF9hdCcsXG4gICdfcGFzc3dvcmRfaGlzdG9yeScsXG5dO1xuXG5jb25zdCBpc1NwZWNpYWxVcGRhdGVLZXkgPSBrZXkgPT4ge1xuICByZXR1cm4gc3BlY2lhbEtleXNGb3JVcGRhdGUuaW5kZXhPZihrZXkpID49IDA7XG59O1xuXG5mdW5jdGlvbiBleHBhbmRSZXN1bHRPbktleVBhdGgob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gIGlmIChrZXkuaW5kZXhPZignLicpIDwgMCkge1xuICAgIG9iamVjdFtrZXldID0gdmFsdWVba2V5XTtcbiAgICByZXR1cm4gb2JqZWN0O1xuICB9XG4gIGNvbnN0IHBhdGggPSBrZXkuc3BsaXQoJy4nKTtcbiAgY29uc3QgZmlyc3RLZXkgPSBwYXRoWzBdO1xuICBjb25zdCBuZXh0UGF0aCA9IHBhdGguc2xpY2UoMSkuam9pbignLicpO1xuICBvYmplY3RbZmlyc3RLZXldID0gZXhwYW5kUmVzdWx0T25LZXlQYXRoKG9iamVjdFtmaXJzdEtleV0gfHwge30sIG5leHRQYXRoLCB2YWx1ZVtmaXJzdEtleV0pO1xuICBkZWxldGUgb2JqZWN0W2tleV07XG4gIHJldHVybiBvYmplY3Q7XG59XG5cbmZ1bmN0aW9uIHNhbml0aXplRGF0YWJhc2VSZXN1bHQob3JpZ2luYWxPYmplY3QsIHJlc3VsdCk6IFByb21pc2U8YW55PiB7XG4gIGNvbnN0IHJlc3BvbnNlID0ge307XG4gIGlmICghcmVzdWx0KSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXNwb25zZSk7XG4gIH1cbiAgT2JqZWN0LmtleXMob3JpZ2luYWxPYmplY3QpLmZvckVhY2goa2V5ID0+IHtcbiAgICBjb25zdCBrZXlVcGRhdGUgPSBvcmlnaW5hbE9iamVjdFtrZXldO1xuICAgIC8vIGRldGVybWluZSBpZiB0aGF0IHdhcyBhbiBvcFxuICAgIGlmIChcbiAgICAgIGtleVVwZGF0ZSAmJlxuICAgICAgdHlwZW9mIGtleVVwZGF0ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgIGtleVVwZGF0ZS5fX29wICYmXG4gICAgICBbJ0FkZCcsICdBZGRVbmlxdWUnLCAnUmVtb3ZlJywgJ0luY3JlbWVudCddLmluZGV4T2Yoa2V5VXBkYXRlLl9fb3ApID4gLTFcbiAgICApIHtcbiAgICAgIC8vIG9ubHkgdmFsaWQgb3BzIHRoYXQgcHJvZHVjZSBhbiBhY3Rpb25hYmxlIHJlc3VsdFxuICAgICAgLy8gdGhlIG9wIG1heSBoYXZlIGhhcHBlbmQgb24gYSBrZXlwYXRoXG4gICAgICBleHBhbmRSZXN1bHRPbktleVBhdGgocmVzcG9uc2UsIGtleSwgcmVzdWx0KTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3BvbnNlKTtcbn1cblxuZnVuY3Rpb24gam9pblRhYmxlTmFtZShjbGFzc05hbWUsIGtleSkge1xuICByZXR1cm4gYF9Kb2luOiR7a2V5fToke2NsYXNzTmFtZX1gO1xufVxuXG5jb25zdCBmbGF0dGVuVXBkYXRlT3BlcmF0b3JzRm9yQ3JlYXRlID0gb2JqZWN0ID0+IHtcbiAgZm9yIChjb25zdCBrZXkgaW4gb2JqZWN0KSB7XG4gICAgaWYgKG9iamVjdFtrZXldICYmIG9iamVjdFtrZXldLl9fb3ApIHtcbiAgICAgIHN3aXRjaCAob2JqZWN0W2tleV0uX19vcCkge1xuICAgICAgICBjYXNlICdJbmNyZW1lbnQnOlxuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0W2tleV0uYW1vdW50ICE9PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ29iamVjdHMgdG8gYWRkIG11c3QgYmUgYW4gYXJyYXknKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgb2JqZWN0W2tleV0gPSBvYmplY3Rba2V5XS5hbW91bnQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0FkZCc6XG4gICAgICAgICAgaWYgKCEob2JqZWN0W2tleV0ub2JqZWN0cyBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ29iamVjdHMgdG8gYWRkIG11c3QgYmUgYW4gYXJyYXknKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgb2JqZWN0W2tleV0gPSBvYmplY3Rba2V5XS5vYmplY3RzO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdBZGRVbmlxdWUnOlxuICAgICAgICAgIGlmICghKG9iamVjdFtrZXldLm9iamVjdHMgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sICdvYmplY3RzIHRvIGFkZCBtdXN0IGJlIGFuIGFycmF5Jyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIG9iamVjdFtrZXldID0gb2JqZWN0W2tleV0ub2JqZWN0cztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnUmVtb3ZlJzpcbiAgICAgICAgICBpZiAoIShvYmplY3Rba2V5XS5vYmplY3RzIGluc3RhbmNlb2YgQXJyYXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnb2JqZWN0cyB0byBhZGQgbXVzdCBiZSBhbiBhcnJheScpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBvYmplY3Rba2V5XSA9IFtdO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdEZWxldGUnOlxuICAgICAgICAgIGRlbGV0ZSBvYmplY3Rba2V5XTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5DT01NQU5EX1VOQVZBSUxBQkxFLFxuICAgICAgICAgICAgYFRoZSAke29iamVjdFtrZXldLl9fb3B9IG9wZXJhdG9yIGlzIG5vdCBzdXBwb3J0ZWQgeWV0LmBcbiAgICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxuY29uc3QgdHJhbnNmb3JtQXV0aERhdGEgPSAoY2xhc3NOYW1lLCBvYmplY3QsIHNjaGVtYSkgPT4ge1xuICBpZiAob2JqZWN0LmF1dGhEYXRhICYmIGNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIE9iamVjdC5rZXlzKG9iamVjdC5hdXRoRGF0YSkuZm9yRWFjaChwcm92aWRlciA9PiB7XG4gICAgICBjb25zdCBwcm92aWRlckRhdGEgPSBvYmplY3QuYXV0aERhdGFbcHJvdmlkZXJdO1xuICAgICAgY29uc3QgZmllbGROYW1lID0gYF9hdXRoX2RhdGFfJHtwcm92aWRlcn1gO1xuICAgICAgaWYgKHByb3ZpZGVyRGF0YSA9PSBudWxsKSB7XG4gICAgICAgIG9iamVjdFtmaWVsZE5hbWVdID0ge1xuICAgICAgICAgIF9fb3A6ICdEZWxldGUnLFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb2JqZWN0W2ZpZWxkTmFtZV0gPSBwcm92aWRlckRhdGE7XG4gICAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSA9IHsgdHlwZTogJ09iamVjdCcgfTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBkZWxldGUgb2JqZWN0LmF1dGhEYXRhO1xuICB9XG59O1xuLy8gVHJhbnNmb3JtcyBhIERhdGFiYXNlIGZvcm1hdCBBQ0wgdG8gYSBSRVNUIEFQSSBmb3JtYXQgQUNMXG5jb25zdCB1bnRyYW5zZm9ybU9iamVjdEFDTCA9ICh7IF9ycGVybSwgX3dwZXJtLCAuLi5vdXRwdXQgfSkgPT4ge1xuICBpZiAoX3JwZXJtIHx8IF93cGVybSkge1xuICAgIG91dHB1dC5BQ0wgPSB7fTtcblxuICAgIChfcnBlcm0gfHwgW10pLmZvckVhY2goZW50cnkgPT4ge1xuICAgICAgaWYgKCFvdXRwdXQuQUNMW2VudHJ5XSkge1xuICAgICAgICBvdXRwdXQuQUNMW2VudHJ5XSA9IHsgcmVhZDogdHJ1ZSB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0cHV0LkFDTFtlbnRyeV1bJ3JlYWQnXSA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAoX3dwZXJtIHx8IFtdKS5mb3JFYWNoKGVudHJ5ID0+IHtcbiAgICAgIGlmICghb3V0cHV0LkFDTFtlbnRyeV0pIHtcbiAgICAgICAgb3V0cHV0LkFDTFtlbnRyeV0gPSB7IHdyaXRlOiB0cnVlIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvdXRwdXQuQUNMW2VudHJ5XVsnd3JpdGUnXSA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIG91dHB1dDtcbn07XG5cbi8qKlxuICogV2hlbiBxdWVyeWluZywgdGhlIGZpZWxkTmFtZSBtYXkgYmUgY29tcG91bmQsIGV4dHJhY3QgdGhlIHJvb3QgZmllbGROYW1lXG4gKiAgICAgYHRlbXBlcmF0dXJlLmNlbHNpdXNgIGJlY29tZXMgYHRlbXBlcmF0dXJlYFxuICogQHBhcmFtIHtzdHJpbmd9IGZpZWxkTmFtZSB0aGF0IG1heSBiZSBhIGNvbXBvdW5kIGZpZWxkIG5hbWVcbiAqIEByZXR1cm5zIHtzdHJpbmd9IHRoZSByb290IG5hbWUgb2YgdGhlIGZpZWxkXG4gKi9cbmNvbnN0IGdldFJvb3RGaWVsZE5hbWUgPSAoZmllbGROYW1lOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICByZXR1cm4gZmllbGROYW1lLnNwbGl0KCcuJylbMF07XG59O1xuXG5jb25zdCByZWxhdGlvblNjaGVtYSA9IHtcbiAgZmllbGRzOiB7IHJlbGF0ZWRJZDogeyB0eXBlOiAnU3RyaW5nJyB9LCBvd25pbmdJZDogeyB0eXBlOiAnU3RyaW5nJyB9IH0sXG59O1xuXG5jbGFzcyBEYXRhYmFzZUNvbnRyb2xsZXIge1xuICBhZGFwdGVyOiBTdG9yYWdlQWRhcHRlcjtcbiAgc2NoZW1hQ2FjaGU6IGFueTtcbiAgc2NoZW1hUHJvbWlzZTogP1Byb21pc2U8U2NoZW1hQ29udHJvbGxlci5TY2hlbWFDb250cm9sbGVyPjtcbiAgX3RyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55O1xuXG4gIGNvbnN0cnVjdG9yKGFkYXB0ZXI6IFN0b3JhZ2VBZGFwdGVyLCBzY2hlbWFDYWNoZTogYW55KSB7XG4gICAgdGhpcy5hZGFwdGVyID0gYWRhcHRlcjtcbiAgICB0aGlzLnNjaGVtYUNhY2hlID0gc2NoZW1hQ2FjaGU7XG4gICAgLy8gV2UgZG9uJ3Qgd2FudCBhIG11dGFibGUgdGhpcy5zY2hlbWEsIGJlY2F1c2UgdGhlbiB5b3UgY291bGQgaGF2ZVxuICAgIC8vIG9uZSByZXF1ZXN0IHRoYXQgdXNlcyBkaWZmZXJlbnQgc2NoZW1hcyBmb3IgZGlmZmVyZW50IHBhcnRzIG9mXG4gICAgLy8gaXQuIEluc3RlYWQsIHVzZSBsb2FkU2NoZW1hIHRvIGdldCBhIHNjaGVtYS5cbiAgICB0aGlzLnNjaGVtYVByb21pc2UgPSBudWxsO1xuICAgIHRoaXMuX3RyYW5zYWN0aW9uYWxTZXNzaW9uID0gbnVsbDtcbiAgfVxuXG4gIGNvbGxlY3Rpb25FeGlzdHMoY2xhc3NOYW1lOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmNsYXNzRXhpc3RzKGNsYXNzTmFtZSk7XG4gIH1cblxuICBwdXJnZUNvbGxlY3Rpb24oY2xhc3NOYW1lOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5sb2FkU2NoZW1hKClcbiAgICAgIC50aGVuKHNjaGVtYUNvbnRyb2xsZXIgPT4gc2NoZW1hQ29udHJvbGxlci5nZXRPbmVTY2hlbWEoY2xhc3NOYW1lKSlcbiAgICAgIC50aGVuKHNjaGVtYSA9PiB0aGlzLmFkYXB0ZXIuZGVsZXRlT2JqZWN0c0J5UXVlcnkoY2xhc3NOYW1lLCBzY2hlbWEsIHt9KSk7XG4gIH1cblxuICB2YWxpZGF0ZUNsYXNzTmFtZShjbGFzc05hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghU2NoZW1hQ29udHJvbGxlci5jbGFzc05hbWVJc1ZhbGlkKGNsYXNzTmFtZSkpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSwgJ2ludmFsaWQgY2xhc3NOYW1lOiAnICsgY2xhc3NOYW1lKVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGEgc2NoZW1hQ29udHJvbGxlci5cbiAgbG9hZFNjaGVtYShcbiAgICBvcHRpb25zOiBMb2FkU2NoZW1hT3B0aW9ucyA9IHsgY2xlYXJDYWNoZTogZmFsc2UgfVxuICApOiBQcm9taXNlPFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlcj4ge1xuICAgIGlmICh0aGlzLnNjaGVtYVByb21pc2UgIT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2NoZW1hUHJvbWlzZTtcbiAgICB9XG4gICAgdGhpcy5zY2hlbWFQcm9taXNlID0gU2NoZW1hQ29udHJvbGxlci5sb2FkKHRoaXMuYWRhcHRlciwgdGhpcy5zY2hlbWFDYWNoZSwgb3B0aW9ucyk7XG4gICAgdGhpcy5zY2hlbWFQcm9taXNlLnRoZW4oXG4gICAgICAoKSA9PiBkZWxldGUgdGhpcy5zY2hlbWFQcm9taXNlLFxuICAgICAgKCkgPT4gZGVsZXRlIHRoaXMuc2NoZW1hUHJvbWlzZVxuICAgICk7XG4gICAgcmV0dXJuIHRoaXMubG9hZFNjaGVtYShvcHRpb25zKTtcbiAgfVxuXG4gIGxvYWRTY2hlbWFJZk5lZWRlZChcbiAgICBzY2hlbWFDb250cm9sbGVyOiBTY2hlbWFDb250cm9sbGVyLlNjaGVtYUNvbnRyb2xsZXIsXG4gICAgb3B0aW9uczogTG9hZFNjaGVtYU9wdGlvbnMgPSB7IGNsZWFyQ2FjaGU6IGZhbHNlIH1cbiAgKTogUHJvbWlzZTxTY2hlbWFDb250cm9sbGVyLlNjaGVtYUNvbnRyb2xsZXI+IHtcbiAgICByZXR1cm4gc2NoZW1hQ29udHJvbGxlciA/IFByb21pc2UucmVzb2x2ZShzY2hlbWFDb250cm9sbGVyKSA6IHRoaXMubG9hZFNjaGVtYShvcHRpb25zKTtcbiAgfVxuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgY2xhc3NuYW1lIHRoYXQgaXMgcmVsYXRlZCB0byB0aGUgZ2l2ZW5cbiAgLy8gY2xhc3NuYW1lIHRocm91Z2ggdGhlIGtleS5cbiAgLy8gVE9ETzogbWFrZSB0aGlzIG5vdCBpbiB0aGUgRGF0YWJhc2VDb250cm9sbGVyIGludGVyZmFjZVxuICByZWRpcmVjdENsYXNzTmFtZUZvcktleShjbGFzc05hbWU6IHN0cmluZywga2V5OiBzdHJpbmcpOiBQcm9taXNlPD9zdHJpbmc+IHtcbiAgICByZXR1cm4gdGhpcy5sb2FkU2NoZW1hKCkudGhlbihzY2hlbWEgPT4ge1xuICAgICAgdmFyIHQgPSBzY2hlbWEuZ2V0RXhwZWN0ZWRUeXBlKGNsYXNzTmFtZSwga2V5KTtcbiAgICAgIGlmICh0ICE9IG51bGwgJiYgdHlwZW9mIHQgIT09ICdzdHJpbmcnICYmIHQudHlwZSA9PT0gJ1JlbGF0aW9uJykge1xuICAgICAgICByZXR1cm4gdC50YXJnZXRDbGFzcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBjbGFzc05hbWU7XG4gICAgfSk7XG4gIH1cblxuICAvLyBVc2VzIHRoZSBzY2hlbWEgdG8gdmFsaWRhdGUgdGhlIG9iamVjdCAoUkVTVCBBUEkgZm9ybWF0KS5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgbmV3IHNjaGVtYS5cbiAgLy8gVGhpcyBkb2VzIG5vdCB1cGRhdGUgdGhpcy5zY2hlbWEsIGJlY2F1c2UgaW4gYSBzaXR1YXRpb24gbGlrZSBhXG4gIC8vIGJhdGNoIHJlcXVlc3QsIHRoYXQgY291bGQgY29uZnVzZSBvdGhlciB1c2VycyBvZiB0aGUgc2NoZW1hLlxuICB2YWxpZGF0ZU9iamVjdChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBvYmplY3Q6IGFueSxcbiAgICBxdWVyeTogYW55LFxuICAgIHJ1bk9wdGlvbnM6IFF1ZXJ5T3B0aW9uc1xuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBsZXQgc2NoZW1hO1xuICAgIGNvbnN0IGFjbCA9IHJ1bk9wdGlvbnMuYWNsO1xuICAgIGNvbnN0IGlzTWFzdGVyID0gYWNsID09PSB1bmRlZmluZWQ7XG4gICAgdmFyIGFjbEdyb3VwOiBzdHJpbmdbXSA9IGFjbCB8fCBbXTtcbiAgICByZXR1cm4gdGhpcy5sb2FkU2NoZW1hKClcbiAgICAgIC50aGVuKHMgPT4ge1xuICAgICAgICBzY2hlbWEgPSBzO1xuICAgICAgICBpZiAoaXNNYXN0ZXIpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuY2FuQWRkRmllbGQoc2NoZW1hLCBjbGFzc05hbWUsIG9iamVjdCwgYWNsR3JvdXAsIHJ1bk9wdGlvbnMpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHNjaGVtYS52YWxpZGF0ZU9iamVjdChjbGFzc05hbWUsIG9iamVjdCwgcXVlcnkpO1xuICAgICAgfSk7XG4gIH1cblxuICB1cGRhdGUoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgcXVlcnk6IGFueSxcbiAgICB1cGRhdGU6IGFueSxcbiAgICB7IGFjbCwgbWFueSwgdXBzZXJ0LCBhZGRzRmllbGQgfTogRnVsbFF1ZXJ5T3B0aW9ucyA9IHt9LFxuICAgIHNraXBTYW5pdGl6YXRpb246IGJvb2xlYW4gPSBmYWxzZSxcbiAgICB2YWxpZGF0ZU9ubHk6IGJvb2xlYW4gPSBmYWxzZSxcbiAgICB2YWxpZFNjaGVtYUNvbnRyb2xsZXI6IFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlclxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IG9yaWdpbmFsUXVlcnkgPSBxdWVyeTtcbiAgICBjb25zdCBvcmlnaW5hbFVwZGF0ZSA9IHVwZGF0ZTtcbiAgICAvLyBNYWtlIGEgY29weSBvZiB0aGUgb2JqZWN0LCBzbyB3ZSBkb24ndCBtdXRhdGUgdGhlIGluY29taW5nIGRhdGEuXG4gICAgdXBkYXRlID0gZGVlcGNvcHkodXBkYXRlKTtcbiAgICB2YXIgcmVsYXRpb25VcGRhdGVzID0gW107XG4gICAgdmFyIGlzTWFzdGVyID0gYWNsID09PSB1bmRlZmluZWQ7XG4gICAgdmFyIGFjbEdyb3VwID0gYWNsIHx8IFtdO1xuXG4gICAgcmV0dXJuIHRoaXMubG9hZFNjaGVtYUlmTmVlZGVkKHZhbGlkU2NoZW1hQ29udHJvbGxlcikudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHtcbiAgICAgIHJldHVybiAoaXNNYXN0ZXJcbiAgICAgICAgPyBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICA6IHNjaGVtYUNvbnRyb2xsZXIudmFsaWRhdGVQZXJtaXNzaW9uKGNsYXNzTmFtZSwgYWNsR3JvdXAsICd1cGRhdGUnKVxuICAgICAgKVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgcmVsYXRpb25VcGRhdGVzID0gdGhpcy5jb2xsZWN0UmVsYXRpb25VcGRhdGVzKGNsYXNzTmFtZSwgb3JpZ2luYWxRdWVyeS5vYmplY3RJZCwgdXBkYXRlKTtcbiAgICAgICAgICBpZiAoIWlzTWFzdGVyKSB7XG4gICAgICAgICAgICBxdWVyeSA9IHRoaXMuYWRkUG9pbnRlclBlcm1pc3Npb25zKFxuICAgICAgICAgICAgICBzY2hlbWFDb250cm9sbGVyLFxuICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgICd1cGRhdGUnLFxuICAgICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgICAgYWNsR3JvdXBcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGlmIChhZGRzRmllbGQpIHtcbiAgICAgICAgICAgICAgcXVlcnkgPSB7XG4gICAgICAgICAgICAgICAgJGFuZDogW1xuICAgICAgICAgICAgICAgICAgcXVlcnksXG4gICAgICAgICAgICAgICAgICB0aGlzLmFkZFBvaW50ZXJQZXJtaXNzaW9ucyhcbiAgICAgICAgICAgICAgICAgICAgc2NoZW1hQ29udHJvbGxlcixcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgICAnYWRkRmllbGQnLFxuICAgICAgICAgICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgICAgICAgICAgYWNsR3JvdXBcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFxdWVyeSkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoYWNsKSB7XG4gICAgICAgICAgICBxdWVyeSA9IGFkZFdyaXRlQUNMKHF1ZXJ5LCBhY2wpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YWxpZGF0ZVF1ZXJ5KHF1ZXJ5KTtcbiAgICAgICAgICByZXR1cm4gc2NoZW1hQ29udHJvbGxlclxuICAgICAgICAgICAgLmdldE9uZVNjaGVtYShjbGFzc05hbWUsIHRydWUpXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAvLyBJZiB0aGUgc2NoZW1hIGRvZXNuJ3QgZXhpc3QsIHByZXRlbmQgaXQgZXhpc3RzIHdpdGggbm8gZmllbGRzLiBUaGlzIGJlaGF2aW9yXG4gICAgICAgICAgICAgIC8vIHdpbGwgbGlrZWx5IG5lZWQgcmV2aXNpdGluZy5cbiAgICAgICAgICAgICAgaWYgKGVycm9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBmaWVsZHM6IHt9IH07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnRoZW4oc2NoZW1hID0+IHtcbiAgICAgICAgICAgICAgT2JqZWN0LmtleXModXBkYXRlKS5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGZpZWxkTmFtZS5tYXRjaCgvXmF1dGhEYXRhXFwuKFthLXpBLVowLTlfXSspXFwuaWQkLykpIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSxcbiAgICAgICAgICAgICAgICAgICAgYEludmFsaWQgZmllbGQgbmFtZSBmb3IgdXBkYXRlOiAke2ZpZWxkTmFtZX1gXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCByb290RmllbGROYW1lID0gZ2V0Um9vdEZpZWxkTmFtZShmaWVsZE5hbWUpO1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICFTY2hlbWFDb250cm9sbGVyLmZpZWxkTmFtZUlzVmFsaWQocm9vdEZpZWxkTmFtZSwgY2xhc3NOYW1lKSAmJlxuICAgICAgICAgICAgICAgICAgIWlzU3BlY2lhbFVwZGF0ZUtleShyb290RmllbGROYW1lKVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FLFxuICAgICAgICAgICAgICAgICAgICBgSW52YWxpZCBmaWVsZCBuYW1lIGZvciB1cGRhdGU6ICR7ZmllbGROYW1lfWBcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgZm9yIChjb25zdCB1cGRhdGVPcGVyYXRpb24gaW4gdXBkYXRlKSB7XG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgdXBkYXRlW3VwZGF0ZU9wZXJhdGlvbl0gJiZcbiAgICAgICAgICAgICAgICAgIHR5cGVvZiB1cGRhdGVbdXBkYXRlT3BlcmF0aW9uXSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgICAgICAgICAgIE9iamVjdC5rZXlzKHVwZGF0ZVt1cGRhdGVPcGVyYXRpb25dKS5zb21lKFxuICAgICAgICAgICAgICAgICAgICBpbm5lcktleSA9PiBpbm5lcktleS5pbmNsdWRlcygnJCcpIHx8IGlubmVyS2V5LmluY2x1ZGVzKCcuJylcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9ORVNURURfS0VZLFxuICAgICAgICAgICAgICAgICAgICBcIk5lc3RlZCBrZXlzIHNob3VsZCBub3QgY29udGFpbiB0aGUgJyQnIG9yICcuJyBjaGFyYWN0ZXJzXCJcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHVwZGF0ZSA9IHRyYW5zZm9ybU9iamVjdEFDTCh1cGRhdGUpO1xuICAgICAgICAgICAgICB0cmFuc2Zvcm1BdXRoRGF0YShjbGFzc05hbWUsIHVwZGF0ZSwgc2NoZW1hKTtcbiAgICAgICAgICAgICAgaWYgKHZhbGlkYXRlT25seSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuZmluZChjbGFzc05hbWUsIHNjaGVtYSwgcXVlcnksIHt9KS50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgICAgICAgICBpZiAoIXJlc3VsdCB8fCAhcmVzdWx0Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ09iamVjdCBub3QgZm91bmQuJyk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKG1hbnkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnVwZGF0ZU9iamVjdHNCeVF1ZXJ5KFxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgICAgICAgICAgcXVlcnksXG4gICAgICAgICAgICAgICAgICB1cGRhdGUsXG4gICAgICAgICAgICAgICAgICB0aGlzLl90cmFuc2FjdGlvbmFsU2Vzc2lvblxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAodXBzZXJ0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci51cHNlcnRPbmVPYmplY3QoXG4gICAgICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgICBzY2hlbWEsXG4gICAgICAgICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgICAgICAgIHVwZGF0ZSxcbiAgICAgICAgICAgICAgICAgIHRoaXMuX3RyYW5zYWN0aW9uYWxTZXNzaW9uXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmZpbmRPbmVBbmRVcGRhdGUoXG4gICAgICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgICBzY2hlbWEsXG4gICAgICAgICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgICAgICAgIHVwZGF0ZSxcbiAgICAgICAgICAgICAgICAgIHRoaXMuX3RyYW5zYWN0aW9uYWxTZXNzaW9uXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKChyZXN1bHQ6IGFueSkgPT4ge1xuICAgICAgICAgIGlmICghcmVzdWx0KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ09iamVjdCBub3QgZm91bmQuJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh2YWxpZGF0ZU9ubHkpIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZVJlbGF0aW9uVXBkYXRlcyhcbiAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgIG9yaWdpbmFsUXVlcnkub2JqZWN0SWQsXG4gICAgICAgICAgICB1cGRhdGUsXG4gICAgICAgICAgICByZWxhdGlvblVwZGF0ZXNcbiAgICAgICAgICApLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICBpZiAoc2tpcFNhbml0aXphdGlvbikge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gc2FuaXRpemVEYXRhYmFzZVJlc3VsdChvcmlnaW5hbFVwZGF0ZSwgcmVzdWx0KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBDb2xsZWN0IGFsbCByZWxhdGlvbi11cGRhdGluZyBvcGVyYXRpb25zIGZyb20gYSBSRVNULWZvcm1hdCB1cGRhdGUuXG4gIC8vIFJldHVybnMgYSBsaXN0IG9mIGFsbCByZWxhdGlvbiB1cGRhdGVzIHRvIHBlcmZvcm1cbiAgLy8gVGhpcyBtdXRhdGVzIHVwZGF0ZS5cbiAgY29sbGVjdFJlbGF0aW9uVXBkYXRlcyhjbGFzc05hbWU6IHN0cmluZywgb2JqZWN0SWQ6ID9zdHJpbmcsIHVwZGF0ZTogYW55KSB7XG4gICAgdmFyIG9wcyA9IFtdO1xuICAgIHZhciBkZWxldGVNZSA9IFtdO1xuICAgIG9iamVjdElkID0gdXBkYXRlLm9iamVjdElkIHx8IG9iamVjdElkO1xuXG4gICAgdmFyIHByb2Nlc3MgPSAob3AsIGtleSkgPT4ge1xuICAgICAgaWYgKCFvcCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAob3AuX19vcCA9PSAnQWRkUmVsYXRpb24nKSB7XG4gICAgICAgIG9wcy5wdXNoKHsga2V5LCBvcCB9KTtcbiAgICAgICAgZGVsZXRlTWUucHVzaChrZXkpO1xuICAgICAgfVxuXG4gICAgICBpZiAob3AuX19vcCA9PSAnUmVtb3ZlUmVsYXRpb24nKSB7XG4gICAgICAgIG9wcy5wdXNoKHsga2V5LCBvcCB9KTtcbiAgICAgICAgZGVsZXRlTWUucHVzaChrZXkpO1xuICAgICAgfVxuXG4gICAgICBpZiAob3AuX19vcCA9PSAnQmF0Y2gnKSB7XG4gICAgICAgIGZvciAodmFyIHggb2Ygb3Aub3BzKSB7XG4gICAgICAgICAgcHJvY2Vzcyh4LCBrZXkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIGZvciAoY29uc3Qga2V5IGluIHVwZGF0ZSkge1xuICAgICAgcHJvY2Vzcyh1cGRhdGVba2V5XSwga2V5KTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBrZXkgb2YgZGVsZXRlTWUpIHtcbiAgICAgIGRlbGV0ZSB1cGRhdGVba2V5XTtcbiAgICB9XG4gICAgcmV0dXJuIG9wcztcbiAgfVxuXG4gIC8vIFByb2Nlc3NlcyByZWxhdGlvbi11cGRhdGluZyBvcGVyYXRpb25zIGZyb20gYSBSRVNULWZvcm1hdCB1cGRhdGUuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBhbGwgdXBkYXRlcyBoYXZlIGJlZW4gcGVyZm9ybWVkXG4gIGhhbmRsZVJlbGF0aW9uVXBkYXRlcyhjbGFzc05hbWU6IHN0cmluZywgb2JqZWN0SWQ6IHN0cmluZywgdXBkYXRlOiBhbnksIG9wczogYW55KSB7XG4gICAgdmFyIHBlbmRpbmcgPSBbXTtcbiAgICBvYmplY3RJZCA9IHVwZGF0ZS5vYmplY3RJZCB8fCBvYmplY3RJZDtcbiAgICBvcHMuZm9yRWFjaCgoeyBrZXksIG9wIH0pID0+IHtcbiAgICAgIGlmICghb3ApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKG9wLl9fb3AgPT0gJ0FkZFJlbGF0aW9uJykge1xuICAgICAgICBmb3IgKGNvbnN0IG9iamVjdCBvZiBvcC5vYmplY3RzKSB7XG4gICAgICAgICAgcGVuZGluZy5wdXNoKHRoaXMuYWRkUmVsYXRpb24oa2V5LCBjbGFzc05hbWUsIG9iamVjdElkLCBvYmplY3Qub2JqZWN0SWQpKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAob3AuX19vcCA9PSAnUmVtb3ZlUmVsYXRpb24nKSB7XG4gICAgICAgIGZvciAoY29uc3Qgb2JqZWN0IG9mIG9wLm9iamVjdHMpIHtcbiAgICAgICAgICBwZW5kaW5nLnB1c2godGhpcy5yZW1vdmVSZWxhdGlvbihrZXksIGNsYXNzTmFtZSwgb2JqZWN0SWQsIG9iamVjdC5vYmplY3RJZCkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwocGVuZGluZyk7XG4gIH1cblxuICAvLyBBZGRzIGEgcmVsYXRpb24uXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgc3VjY2Vzc2Z1bGx5IGlmZiB0aGUgYWRkIHdhcyBzdWNjZXNzZnVsLlxuICBhZGRSZWxhdGlvbihrZXk6IHN0cmluZywgZnJvbUNsYXNzTmFtZTogc3RyaW5nLCBmcm9tSWQ6IHN0cmluZywgdG9JZDogc3RyaW5nKSB7XG4gICAgY29uc3QgZG9jID0ge1xuICAgICAgcmVsYXRlZElkOiB0b0lkLFxuICAgICAgb3duaW5nSWQ6IGZyb21JZCxcbiAgICB9O1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIudXBzZXJ0T25lT2JqZWN0KFxuICAgICAgYF9Kb2luOiR7a2V5fToke2Zyb21DbGFzc05hbWV9YCxcbiAgICAgIHJlbGF0aW9uU2NoZW1hLFxuICAgICAgZG9jLFxuICAgICAgZG9jLFxuICAgICAgdGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb25cbiAgICApO1xuICB9XG5cbiAgLy8gUmVtb3ZlcyBhIHJlbGF0aW9uLlxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHN1Y2Nlc3NmdWxseSBpZmYgdGhlIHJlbW92ZSB3YXNcbiAgLy8gc3VjY2Vzc2Z1bC5cbiAgcmVtb3ZlUmVsYXRpb24oa2V5OiBzdHJpbmcsIGZyb21DbGFzc05hbWU6IHN0cmluZywgZnJvbUlkOiBzdHJpbmcsIHRvSWQ6IHN0cmluZykge1xuICAgIHZhciBkb2MgPSB7XG4gICAgICByZWxhdGVkSWQ6IHRvSWQsXG4gICAgICBvd25pbmdJZDogZnJvbUlkLFxuICAgIH07XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlclxuICAgICAgLmRlbGV0ZU9iamVjdHNCeVF1ZXJ5KFxuICAgICAgICBgX0pvaW46JHtrZXl9OiR7ZnJvbUNsYXNzTmFtZX1gLFxuICAgICAgICByZWxhdGlvblNjaGVtYSxcbiAgICAgICAgZG9jLFxuICAgICAgICB0aGlzLl90cmFuc2FjdGlvbmFsU2Vzc2lvblxuICAgICAgKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgLy8gV2UgZG9uJ3QgY2FyZSBpZiB0aGV5IHRyeSB0byBkZWxldGUgYSBub24tZXhpc3RlbnQgcmVsYXRpb24uXG4gICAgICAgIGlmIChlcnJvci5jb2RlID09IFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8vIFJlbW92ZXMgb2JqZWN0cyBtYXRjaGVzIHRoaXMgcXVlcnkgZnJvbSB0aGUgZGF0YWJhc2UuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgc3VjY2Vzc2Z1bGx5IGlmZiB0aGUgb2JqZWN0IHdhc1xuICAvLyBkZWxldGVkLlxuICAvLyBPcHRpb25zOlxuICAvLyAgIGFjbDogIGEgbGlzdCBvZiBzdHJpbmdzLiBJZiB0aGUgb2JqZWN0IHRvIGJlIHVwZGF0ZWQgaGFzIGFuIEFDTCxcbiAgLy8gICAgICAgICBvbmUgb2YgdGhlIHByb3ZpZGVkIHN0cmluZ3MgbXVzdCBwcm92aWRlIHRoZSBjYWxsZXIgd2l0aFxuICAvLyAgICAgICAgIHdyaXRlIHBlcm1pc3Npb25zLlxuICBkZXN0cm95KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHF1ZXJ5OiBhbnksXG4gICAgeyBhY2wgfTogUXVlcnlPcHRpb25zID0ge30sXG4gICAgdmFsaWRTY2hlbWFDb250cm9sbGVyOiBTY2hlbWFDb250cm9sbGVyLlNjaGVtYUNvbnRyb2xsZXJcbiAgKTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCBpc01hc3RlciA9IGFjbCA9PT0gdW5kZWZpbmVkO1xuICAgIGNvbnN0IGFjbEdyb3VwID0gYWNsIHx8IFtdO1xuXG4gICAgcmV0dXJuIHRoaXMubG9hZFNjaGVtYUlmTmVlZGVkKHZhbGlkU2NoZW1hQ29udHJvbGxlcikudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHtcbiAgICAgIHJldHVybiAoaXNNYXN0ZXJcbiAgICAgICAgPyBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICA6IHNjaGVtYUNvbnRyb2xsZXIudmFsaWRhdGVQZXJtaXNzaW9uKGNsYXNzTmFtZSwgYWNsR3JvdXAsICdkZWxldGUnKVxuICAgICAgKS50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKCFpc01hc3Rlcikge1xuICAgICAgICAgIHF1ZXJ5ID0gdGhpcy5hZGRQb2ludGVyUGVybWlzc2lvbnMoXG4gICAgICAgICAgICBzY2hlbWFDb250cm9sbGVyLFxuICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgJ2RlbGV0ZScsXG4gICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgIGFjbEdyb3VwXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoIXF1ZXJ5KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ09iamVjdCBub3QgZm91bmQuJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIGRlbGV0ZSBieSBxdWVyeVxuICAgICAgICBpZiAoYWNsKSB7XG4gICAgICAgICAgcXVlcnkgPSBhZGRXcml0ZUFDTChxdWVyeSwgYWNsKTtcbiAgICAgICAgfVxuICAgICAgICB2YWxpZGF0ZVF1ZXJ5KHF1ZXJ5KTtcbiAgICAgICAgcmV0dXJuIHNjaGVtYUNvbnRyb2xsZXJcbiAgICAgICAgICAuZ2V0T25lU2NoZW1hKGNsYXNzTmFtZSlcbiAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgLy8gSWYgdGhlIHNjaGVtYSBkb2Vzbid0IGV4aXN0LCBwcmV0ZW5kIGl0IGV4aXN0cyB3aXRoIG5vIGZpZWxkcy4gVGhpcyBiZWhhdmlvclxuICAgICAgICAgICAgLy8gd2lsbCBsaWtlbHkgbmVlZCByZXZpc2l0aW5nLlxuICAgICAgICAgICAgaWYgKGVycm9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHsgZmllbGRzOiB7fSB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAudGhlbihwYXJzZUZvcm1hdFNjaGVtYSA9PlxuICAgICAgICAgICAgdGhpcy5hZGFwdGVyLmRlbGV0ZU9iamVjdHNCeVF1ZXJ5KFxuICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgIHBhcnNlRm9ybWF0U2NoZW1hLFxuICAgICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgICAgdGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb25cbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgIC8vIFdoZW4gZGVsZXRpbmcgc2Vzc2lvbnMgd2hpbGUgY2hhbmdpbmcgcGFzc3dvcmRzLCBkb24ndCB0aHJvdyBhbiBlcnJvciBpZiB0aGV5IGRvbid0IGhhdmUgYW55IHNlc3Npb25zLlxuICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PT0gJ19TZXNzaW9uJyAmJiBlcnJvci5jb2RlID09PSBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5EKSB7XG4gICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe30pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIEluc2VydHMgYW4gb2JqZWN0IGludG8gdGhlIGRhdGFiYXNlLlxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHN1Y2Nlc3NmdWxseSBpZmYgdGhlIG9iamVjdCBzYXZlZC5cbiAgY3JlYXRlKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIG9iamVjdDogYW55LFxuICAgIHsgYWNsIH06IFF1ZXJ5T3B0aW9ucyA9IHt9LFxuICAgIHZhbGlkYXRlT25seTogYm9vbGVhbiA9IGZhbHNlLFxuICAgIHZhbGlkU2NoZW1hQ29udHJvbGxlcjogU2NoZW1hQ29udHJvbGxlci5TY2hlbWFDb250cm9sbGVyXG4gICk6IFByb21pc2U8YW55PiB7XG4gICAgLy8gTWFrZSBhIGNvcHkgb2YgdGhlIG9iamVjdCwgc28gd2UgZG9uJ3QgbXV0YXRlIHRoZSBpbmNvbWluZyBkYXRhLlxuICAgIGNvbnN0IG9yaWdpbmFsT2JqZWN0ID0gb2JqZWN0O1xuICAgIG9iamVjdCA9IHRyYW5zZm9ybU9iamVjdEFDTChvYmplY3QpO1xuXG4gICAgb2JqZWN0LmNyZWF0ZWRBdCA9IHsgaXNvOiBvYmplY3QuY3JlYXRlZEF0LCBfX3R5cGU6ICdEYXRlJyB9O1xuICAgIG9iamVjdC51cGRhdGVkQXQgPSB7IGlzbzogb2JqZWN0LnVwZGF0ZWRBdCwgX190eXBlOiAnRGF0ZScgfTtcblxuICAgIHZhciBpc01hc3RlciA9IGFjbCA9PT0gdW5kZWZpbmVkO1xuICAgIHZhciBhY2xHcm91cCA9IGFjbCB8fCBbXTtcbiAgICBjb25zdCByZWxhdGlvblVwZGF0ZXMgPSB0aGlzLmNvbGxlY3RSZWxhdGlvblVwZGF0ZXMoY2xhc3NOYW1lLCBudWxsLCBvYmplY3QpO1xuXG4gICAgcmV0dXJuIHRoaXMudmFsaWRhdGVDbGFzc05hbWUoY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5sb2FkU2NoZW1hSWZOZWVkZWQodmFsaWRTY2hlbWFDb250cm9sbGVyKSlcbiAgICAgIC50aGVuKHNjaGVtYUNvbnRyb2xsZXIgPT4ge1xuICAgICAgICByZXR1cm4gKGlzTWFzdGVyXG4gICAgICAgICAgPyBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICAgIDogc2NoZW1hQ29udHJvbGxlci52YWxpZGF0ZVBlcm1pc3Npb24oY2xhc3NOYW1lLCBhY2xHcm91cCwgJ2NyZWF0ZScpXG4gICAgICAgIClcbiAgICAgICAgICAudGhlbigoKSA9PiBzY2hlbWFDb250cm9sbGVyLmVuZm9yY2VDbGFzc0V4aXN0cyhjbGFzc05hbWUpKVxuICAgICAgICAgIC50aGVuKCgpID0+IHNjaGVtYUNvbnRyb2xsZXIuZ2V0T25lU2NoZW1hKGNsYXNzTmFtZSwgdHJ1ZSkpXG4gICAgICAgICAgLnRoZW4oc2NoZW1hID0+IHtcbiAgICAgICAgICAgIHRyYW5zZm9ybUF1dGhEYXRhKGNsYXNzTmFtZSwgb2JqZWN0LCBzY2hlbWEpO1xuICAgICAgICAgICAgZmxhdHRlblVwZGF0ZU9wZXJhdG9yc0ZvckNyZWF0ZShvYmplY3QpO1xuICAgICAgICAgICAgaWYgKHZhbGlkYXRlT25seSkge1xuICAgICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmNyZWF0ZU9iamVjdChcbiAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICBTY2hlbWFDb250cm9sbGVyLmNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEoc2NoZW1hKSxcbiAgICAgICAgICAgICAgb2JqZWN0LFxuICAgICAgICAgICAgICB0aGlzLl90cmFuc2FjdGlvbmFsU2Vzc2lvblxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgICBpZiAodmFsaWRhdGVPbmx5KSB7XG4gICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbE9iamVjdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZVJlbGF0aW9uVXBkYXRlcyhcbiAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICBvYmplY3Qub2JqZWN0SWQsXG4gICAgICAgICAgICAgIG9iamVjdCxcbiAgICAgICAgICAgICAgcmVsYXRpb25VcGRhdGVzXG4gICAgICAgICAgICApLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gc2FuaXRpemVEYXRhYmFzZVJlc3VsdChvcmlnaW5hbE9iamVjdCwgcmVzdWx0Lm9wc1swXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgIH0pO1xuICB9XG5cbiAgY2FuQWRkRmllbGQoXG4gICAgc2NoZW1hOiBTY2hlbWFDb250cm9sbGVyLlNjaGVtYUNvbnRyb2xsZXIsXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgb2JqZWN0OiBhbnksXG4gICAgYWNsR3JvdXA6IHN0cmluZ1tdLFxuICAgIHJ1bk9wdGlvbnM6IFF1ZXJ5T3B0aW9uc1xuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBjbGFzc1NjaGVtYSA9IHNjaGVtYS5zY2hlbWFEYXRhW2NsYXNzTmFtZV07XG4gICAgaWYgKCFjbGFzc1NjaGVtYSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICBjb25zdCBmaWVsZHMgPSBPYmplY3Qua2V5cyhvYmplY3QpO1xuICAgIGNvbnN0IHNjaGVtYUZpZWxkcyA9IE9iamVjdC5rZXlzKGNsYXNzU2NoZW1hLmZpZWxkcyk7XG4gICAgY29uc3QgbmV3S2V5cyA9IGZpZWxkcy5maWx0ZXIoZmllbGQgPT4ge1xuICAgICAgLy8gU2tpcCBmaWVsZHMgdGhhdCBhcmUgdW5zZXRcbiAgICAgIGlmIChvYmplY3RbZmllbGRdICYmIG9iamVjdFtmaWVsZF0uX19vcCAmJiBvYmplY3RbZmllbGRdLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzY2hlbWFGaWVsZHMuaW5kZXhPZihmaWVsZCkgPCAwO1xuICAgIH0pO1xuICAgIGlmIChuZXdLZXlzLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIGFkZHMgYSBtYXJrZXIgdGhhdCBuZXcgZmllbGQgaXMgYmVpbmcgYWRkaW5nIGR1cmluZyB1cGRhdGVcbiAgICAgIHJ1bk9wdGlvbnMuYWRkc0ZpZWxkID0gdHJ1ZTtcblxuICAgICAgY29uc3QgYWN0aW9uID0gcnVuT3B0aW9ucy5hY3Rpb247XG4gICAgICByZXR1cm4gc2NoZW1hLnZhbGlkYXRlUGVybWlzc2lvbihjbGFzc05hbWUsIGFjbEdyb3VwLCAnYWRkRmllbGQnLCBhY3Rpb24pO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICAvLyBXb24ndCBkZWxldGUgY29sbGVjdGlvbnMgaW4gdGhlIHN5c3RlbSBuYW1lc3BhY2VcbiAgLyoqXG4gICAqIERlbGV0ZSBhbGwgY2xhc3NlcyBhbmQgY2xlYXJzIHRoZSBzY2hlbWEgY2FjaGVcbiAgICpcbiAgICogQHBhcmFtIHtib29sZWFufSBmYXN0IHNldCB0byB0cnVlIGlmIGl0J3Mgb2sgdG8ganVzdCBkZWxldGUgcm93cyBhbmQgbm90IGluZGV4ZXNcbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IHdoZW4gdGhlIGRlbGV0aW9ucyBjb21wbGV0ZXNcbiAgICovXG4gIGRlbGV0ZUV2ZXJ5dGhpbmcoZmFzdDogYm9vbGVhbiA9IGZhbHNlKTogUHJvbWlzZTxhbnk+IHtcbiAgICB0aGlzLnNjaGVtYVByb21pc2UgPSBudWxsO1xuICAgIHJldHVybiBQcm9taXNlLmFsbChbdGhpcy5hZGFwdGVyLmRlbGV0ZUFsbENsYXNzZXMoZmFzdCksIHRoaXMuc2NoZW1hQ2FjaGUuY2xlYXIoKV0pO1xuICB9XG5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGEgbGlzdCBvZiByZWxhdGVkIGlkcyBnaXZlbiBhbiBvd25pbmcgaWQuXG4gIC8vIGNsYXNzTmFtZSBoZXJlIGlzIHRoZSBvd25pbmcgY2xhc3NOYW1lLlxuICByZWxhdGVkSWRzKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIGtleTogc3RyaW5nLFxuICAgIG93bmluZ0lkOiBzdHJpbmcsXG4gICAgcXVlcnlPcHRpb25zOiBRdWVyeU9wdGlvbnNcbiAgKTogUHJvbWlzZTxBcnJheTxzdHJpbmc+PiB7XG4gICAgY29uc3QgeyBza2lwLCBsaW1pdCwgc29ydCB9ID0gcXVlcnlPcHRpb25zO1xuICAgIGNvbnN0IGZpbmRPcHRpb25zID0ge307XG4gICAgaWYgKHNvcnQgJiYgc29ydC5jcmVhdGVkQXQgJiYgdGhpcy5hZGFwdGVyLmNhblNvcnRPbkpvaW5UYWJsZXMpIHtcbiAgICAgIGZpbmRPcHRpb25zLnNvcnQgPSB7IF9pZDogc29ydC5jcmVhdGVkQXQgfTtcbiAgICAgIGZpbmRPcHRpb25zLmxpbWl0ID0gbGltaXQ7XG4gICAgICBmaW5kT3B0aW9ucy5za2lwID0gc2tpcDtcbiAgICAgIHF1ZXJ5T3B0aW9ucy5za2lwID0gMDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlclxuICAgICAgLmZpbmQoam9pblRhYmxlTmFtZShjbGFzc05hbWUsIGtleSksIHJlbGF0aW9uU2NoZW1hLCB7IG93bmluZ0lkIH0sIGZpbmRPcHRpb25zKVxuICAgICAgLnRoZW4ocmVzdWx0cyA9PiByZXN1bHRzLm1hcChyZXN1bHQgPT4gcmVzdWx0LnJlbGF0ZWRJZCkpO1xuICB9XG5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGEgbGlzdCBvZiBvd25pbmcgaWRzIGdpdmVuIHNvbWUgcmVsYXRlZCBpZHMuXG4gIC8vIGNsYXNzTmFtZSBoZXJlIGlzIHRoZSBvd25pbmcgY2xhc3NOYW1lLlxuICBvd25pbmdJZHMoY2xhc3NOYW1lOiBzdHJpbmcsIGtleTogc3RyaW5nLCByZWxhdGVkSWRzOiBzdHJpbmdbXSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyXG4gICAgICAuZmluZChcbiAgICAgICAgam9pblRhYmxlTmFtZShjbGFzc05hbWUsIGtleSksXG4gICAgICAgIHJlbGF0aW9uU2NoZW1hLFxuICAgICAgICB7IHJlbGF0ZWRJZDogeyAkaW46IHJlbGF0ZWRJZHMgfSB9LFxuICAgICAgICB7IGtleXM6IFsnb3duaW5nSWQnXSB9XG4gICAgICApXG4gICAgICAudGhlbihyZXN1bHRzID0+IHJlc3VsdHMubWFwKHJlc3VsdCA9PiByZXN1bHQub3duaW5nSWQpKTtcbiAgfVxuXG4gIC8vIE1vZGlmaWVzIHF1ZXJ5IHNvIHRoYXQgaXQgbm8gbG9uZ2VyIGhhcyAkaW4gb24gcmVsYXRpb24gZmllbGRzLCBvclxuICAvLyBlcXVhbC10by1wb2ludGVyIGNvbnN0cmFpbnRzIG9uIHJlbGF0aW9uIGZpZWxkcy5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHF1ZXJ5IGlzIG11dGF0ZWRcbiAgcmVkdWNlSW5SZWxhdGlvbihjbGFzc05hbWU6IHN0cmluZywgcXVlcnk6IGFueSwgc2NoZW1hOiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgIC8vIFNlYXJjaCBmb3IgYW4gaW4tcmVsYXRpb24gb3IgZXF1YWwtdG8tcmVsYXRpb25cbiAgICAvLyBNYWtlIGl0IHNlcXVlbnRpYWwgZm9yIG5vdywgbm90IHN1cmUgb2YgcGFyYWxsZWl6YXRpb24gc2lkZSBlZmZlY3RzXG4gICAgaWYgKHF1ZXJ5Wyckb3InXSkge1xuICAgICAgY29uc3Qgb3JzID0gcXVlcnlbJyRvciddO1xuICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgICAgICBvcnMubWFwKChhUXVlcnksIGluZGV4KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucmVkdWNlSW5SZWxhdGlvbihjbGFzc05hbWUsIGFRdWVyeSwgc2NoZW1hKS50aGVuKGFRdWVyeSA9PiB7XG4gICAgICAgICAgICBxdWVyeVsnJG9yJ11baW5kZXhdID0gYVF1ZXJ5O1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgKS50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShxdWVyeSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBwcm9taXNlcyA9IE9iamVjdC5rZXlzKHF1ZXJ5KS5tYXAoa2V5ID0+IHtcbiAgICAgIGNvbnN0IHQgPSBzY2hlbWEuZ2V0RXhwZWN0ZWRUeXBlKGNsYXNzTmFtZSwga2V5KTtcbiAgICAgIGlmICghdCB8fCB0LnR5cGUgIT09ICdSZWxhdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShxdWVyeSk7XG4gICAgICB9XG4gICAgICBsZXQgcXVlcmllczogPyhhbnlbXSkgPSBudWxsO1xuICAgICAgaWYgKFxuICAgICAgICBxdWVyeVtrZXldICYmXG4gICAgICAgIChxdWVyeVtrZXldWyckaW4nXSB8fFxuICAgICAgICAgIHF1ZXJ5W2tleV1bJyRuZSddIHx8XG4gICAgICAgICAgcXVlcnlba2V5XVsnJG5pbiddIHx8XG4gICAgICAgICAgcXVlcnlba2V5XS5fX3R5cGUgPT0gJ1BvaW50ZXInKVxuICAgICAgKSB7XG4gICAgICAgIC8vIEJ1aWxkIHRoZSBsaXN0IG9mIHF1ZXJpZXNcbiAgICAgICAgcXVlcmllcyA9IE9iamVjdC5rZXlzKHF1ZXJ5W2tleV0pLm1hcChjb25zdHJhaW50S2V5ID0+IHtcbiAgICAgICAgICBsZXQgcmVsYXRlZElkcztcbiAgICAgICAgICBsZXQgaXNOZWdhdGlvbiA9IGZhbHNlO1xuICAgICAgICAgIGlmIChjb25zdHJhaW50S2V5ID09PSAnb2JqZWN0SWQnKSB7XG4gICAgICAgICAgICByZWxhdGVkSWRzID0gW3F1ZXJ5W2tleV0ub2JqZWN0SWRdO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY29uc3RyYWludEtleSA9PSAnJGluJykge1xuICAgICAgICAgICAgcmVsYXRlZElkcyA9IHF1ZXJ5W2tleV1bJyRpbiddLm1hcChyID0+IHIub2JqZWN0SWQpO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY29uc3RyYWludEtleSA9PSAnJG5pbicpIHtcbiAgICAgICAgICAgIGlzTmVnYXRpb24gPSB0cnVlO1xuICAgICAgICAgICAgcmVsYXRlZElkcyA9IHF1ZXJ5W2tleV1bJyRuaW4nXS5tYXAociA9PiByLm9iamVjdElkKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGNvbnN0cmFpbnRLZXkgPT0gJyRuZScpIHtcbiAgICAgICAgICAgIGlzTmVnYXRpb24gPSB0cnVlO1xuICAgICAgICAgICAgcmVsYXRlZElkcyA9IFtxdWVyeVtrZXldWyckbmUnXS5vYmplY3RJZF07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGlzTmVnYXRpb24sXG4gICAgICAgICAgICByZWxhdGVkSWRzLFxuICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcXVlcmllcyA9IFt7IGlzTmVnYXRpb246IGZhbHNlLCByZWxhdGVkSWRzOiBbXSB9XTtcbiAgICAgIH1cblxuICAgICAgLy8gcmVtb3ZlIHRoZSBjdXJyZW50IHF1ZXJ5S2V5IGFzIHdlIGRvbix0IG5lZWQgaXQgYW55bW9yZVxuICAgICAgZGVsZXRlIHF1ZXJ5W2tleV07XG4gICAgICAvLyBleGVjdXRlIGVhY2ggcXVlcnkgaW5kZXBlbmRlbnRseSB0byBidWlsZCB0aGUgbGlzdCBvZlxuICAgICAgLy8gJGluIC8gJG5pblxuICAgICAgY29uc3QgcHJvbWlzZXMgPSBxdWVyaWVzLm1hcChxID0+IHtcbiAgICAgICAgaWYgKCFxKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLm93bmluZ0lkcyhjbGFzc05hbWUsIGtleSwgcS5yZWxhdGVkSWRzKS50aGVuKGlkcyA9PiB7XG4gICAgICAgICAgaWYgKHEuaXNOZWdhdGlvbikge1xuICAgICAgICAgICAgdGhpcy5hZGROb3RJbk9iamVjdElkc0lkcyhpZHMsIHF1ZXJ5KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hZGRJbk9iamVjdElkc0lkcyhpZHMsIHF1ZXJ5KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHF1ZXJ5KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIE1vZGlmaWVzIHF1ZXJ5IHNvIHRoYXQgaXQgbm8gbG9uZ2VyIGhhcyAkcmVsYXRlZFRvXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBxdWVyeSBpcyBtdXRhdGVkXG4gIHJlZHVjZVJlbGF0aW9uS2V5cyhjbGFzc05hbWU6IHN0cmluZywgcXVlcnk6IGFueSwgcXVlcnlPcHRpb25zOiBhbnkpOiA/UHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHF1ZXJ5Wyckb3InXSkge1xuICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgICAgICBxdWVyeVsnJG9yJ10ubWFwKGFRdWVyeSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucmVkdWNlUmVsYXRpb25LZXlzKGNsYXNzTmFtZSwgYVF1ZXJ5LCBxdWVyeU9wdGlvbnMpO1xuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9XG5cbiAgICB2YXIgcmVsYXRlZFRvID0gcXVlcnlbJyRyZWxhdGVkVG8nXTtcbiAgICBpZiAocmVsYXRlZFRvKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZWxhdGVkSWRzKFxuICAgICAgICByZWxhdGVkVG8ub2JqZWN0LmNsYXNzTmFtZSxcbiAgICAgICAgcmVsYXRlZFRvLmtleSxcbiAgICAgICAgcmVsYXRlZFRvLm9iamVjdC5vYmplY3RJZCxcbiAgICAgICAgcXVlcnlPcHRpb25zXG4gICAgICApXG4gICAgICAgIC50aGVuKGlkcyA9PiB7XG4gICAgICAgICAgZGVsZXRlIHF1ZXJ5WyckcmVsYXRlZFRvJ107XG4gICAgICAgICAgdGhpcy5hZGRJbk9iamVjdElkc0lkcyhpZHMsIHF1ZXJ5KTtcbiAgICAgICAgICByZXR1cm4gdGhpcy5yZWR1Y2VSZWxhdGlvbktleXMoY2xhc3NOYW1lLCBxdWVyeSwgcXVlcnlPcHRpb25zKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKCkgPT4ge30pO1xuICAgIH1cbiAgfVxuXG4gIGFkZEluT2JqZWN0SWRzSWRzKGlkczogP0FycmF5PHN0cmluZz4gPSBudWxsLCBxdWVyeTogYW55KSB7XG4gICAgY29uc3QgaWRzRnJvbVN0cmluZzogP0FycmF5PHN0cmluZz4gPVxuICAgICAgdHlwZW9mIHF1ZXJ5Lm9iamVjdElkID09PSAnc3RyaW5nJyA/IFtxdWVyeS5vYmplY3RJZF0gOiBudWxsO1xuICAgIGNvbnN0IGlkc0Zyb21FcTogP0FycmF5PHN0cmluZz4gPVxuICAgICAgcXVlcnkub2JqZWN0SWQgJiYgcXVlcnkub2JqZWN0SWRbJyRlcSddID8gW3F1ZXJ5Lm9iamVjdElkWyckZXEnXV0gOiBudWxsO1xuICAgIGNvbnN0IGlkc0Zyb21JbjogP0FycmF5PHN0cmluZz4gPVxuICAgICAgcXVlcnkub2JqZWN0SWQgJiYgcXVlcnkub2JqZWN0SWRbJyRpbiddID8gcXVlcnkub2JqZWN0SWRbJyRpbiddIDogbnVsbDtcblxuICAgIC8vIEBmbG93LWRpc2FibGUtbmV4dFxuICAgIGNvbnN0IGFsbElkczogQXJyYXk8QXJyYXk8c3RyaW5nPj4gPSBbaWRzRnJvbVN0cmluZywgaWRzRnJvbUVxLCBpZHNGcm9tSW4sIGlkc10uZmlsdGVyKFxuICAgICAgbGlzdCA9PiBsaXN0ICE9PSBudWxsXG4gICAgKTtcbiAgICBjb25zdCB0b3RhbExlbmd0aCA9IGFsbElkcy5yZWR1Y2UoKG1lbW8sIGxpc3QpID0+IG1lbW8gKyBsaXN0Lmxlbmd0aCwgMCk7XG5cbiAgICBsZXQgaWRzSW50ZXJzZWN0aW9uID0gW107XG4gICAgaWYgKHRvdGFsTGVuZ3RoID4gMTI1KSB7XG4gICAgICBpZHNJbnRlcnNlY3Rpb24gPSBpbnRlcnNlY3QuYmlnKGFsbElkcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlkc0ludGVyc2VjdGlvbiA9IGludGVyc2VjdChhbGxJZHMpO1xuICAgIH1cblxuICAgIC8vIE5lZWQgdG8gbWFrZSBzdXJlIHdlIGRvbid0IGNsb2JiZXIgZXhpc3Rpbmcgc2hvcnRoYW5kICRlcSBjb25zdHJhaW50cyBvbiBvYmplY3RJZC5cbiAgICBpZiAoISgnb2JqZWN0SWQnIGluIHF1ZXJ5KSkge1xuICAgICAgcXVlcnkub2JqZWN0SWQgPSB7XG4gICAgICAgICRpbjogdW5kZWZpbmVkLFxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBxdWVyeS5vYmplY3RJZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHF1ZXJ5Lm9iamVjdElkID0ge1xuICAgICAgICAkaW46IHVuZGVmaW5lZCxcbiAgICAgICAgJGVxOiBxdWVyeS5vYmplY3RJZCxcbiAgICAgIH07XG4gICAgfVxuICAgIHF1ZXJ5Lm9iamVjdElkWyckaW4nXSA9IGlkc0ludGVyc2VjdGlvbjtcblxuICAgIHJldHVybiBxdWVyeTtcbiAgfVxuXG4gIGFkZE5vdEluT2JqZWN0SWRzSWRzKGlkczogc3RyaW5nW10gPSBbXSwgcXVlcnk6IGFueSkge1xuICAgIGNvbnN0IGlkc0Zyb21OaW4gPSBxdWVyeS5vYmplY3RJZCAmJiBxdWVyeS5vYmplY3RJZFsnJG5pbiddID8gcXVlcnkub2JqZWN0SWRbJyRuaW4nXSA6IFtdO1xuICAgIGxldCBhbGxJZHMgPSBbLi4uaWRzRnJvbU5pbiwgLi4uaWRzXS5maWx0ZXIobGlzdCA9PiBsaXN0ICE9PSBudWxsKTtcblxuICAgIC8vIG1ha2UgYSBzZXQgYW5kIHNwcmVhZCB0byByZW1vdmUgZHVwbGljYXRlc1xuICAgIGFsbElkcyA9IFsuLi5uZXcgU2V0KGFsbElkcyldO1xuXG4gICAgLy8gTmVlZCB0byBtYWtlIHN1cmUgd2UgZG9uJ3QgY2xvYmJlciBleGlzdGluZyBzaG9ydGhhbmQgJGVxIGNvbnN0cmFpbnRzIG9uIG9iamVjdElkLlxuICAgIGlmICghKCdvYmplY3RJZCcgaW4gcXVlcnkpKSB7XG4gICAgICBxdWVyeS5vYmplY3RJZCA9IHtcbiAgICAgICAgJG5pbjogdW5kZWZpbmVkLFxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBxdWVyeS5vYmplY3RJZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHF1ZXJ5Lm9iamVjdElkID0ge1xuICAgICAgICAkbmluOiB1bmRlZmluZWQsXG4gICAgICAgICRlcTogcXVlcnkub2JqZWN0SWQsXG4gICAgICB9O1xuICAgIH1cblxuICAgIHF1ZXJ5Lm9iamVjdElkWyckbmluJ10gPSBhbGxJZHM7XG4gICAgcmV0dXJuIHF1ZXJ5O1xuICB9XG5cbiAgLy8gUnVucyBhIHF1ZXJ5IG9uIHRoZSBkYXRhYmFzZS5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIGxpc3Qgb2YgaXRlbXMuXG4gIC8vIE9wdGlvbnM6XG4gIC8vICAgc2tpcCAgICBudW1iZXIgb2YgcmVzdWx0cyB0byBza2lwLlxuICAvLyAgIGxpbWl0ICAgbGltaXQgdG8gdGhpcyBudW1iZXIgb2YgcmVzdWx0cy5cbiAgLy8gICBzb3J0ICAgIGFuIG9iamVjdCB3aGVyZSBrZXlzIGFyZSB0aGUgZmllbGRzIHRvIHNvcnQgYnkuXG4gIC8vICAgICAgICAgICB0aGUgdmFsdWUgaXMgKzEgZm9yIGFzY2VuZGluZywgLTEgZm9yIGRlc2NlbmRpbmcuXG4gIC8vICAgY291bnQgICBydW4gYSBjb3VudCBpbnN0ZWFkIG9mIHJldHVybmluZyByZXN1bHRzLlxuICAvLyAgIGFjbCAgICAgcmVzdHJpY3QgdGhpcyBvcGVyYXRpb24gd2l0aCBhbiBBQ0wgZm9yIHRoZSBwcm92aWRlZCBhcnJheVxuICAvLyAgICAgICAgICAgb2YgdXNlciBvYmplY3RJZHMgYW5kIHJvbGVzLiBhY2w6IG51bGwgbWVhbnMgbm8gdXNlci5cbiAgLy8gICAgICAgICAgIHdoZW4gdGhpcyBmaWVsZCBpcyBub3QgcHJlc2VudCwgZG9uJ3QgZG8gYW55dGhpbmcgcmVnYXJkaW5nIEFDTHMuXG4gIC8vICBjYXNlSW5zZW5zaXRpdmUgbWFrZSBzdHJpbmcgY29tcGFyaXNvbnMgY2FzZSBpbnNlbnNpdGl2ZVxuICAvLyBUT0RPOiBtYWtlIHVzZXJJZHMgbm90IG5lZWRlZCBoZXJlLiBUaGUgZGIgYWRhcHRlciBzaG91bGRuJ3Qga25vd1xuICAvLyBhbnl0aGluZyBhYm91dCB1c2VycywgaWRlYWxseS4gVGhlbiwgaW1wcm92ZSB0aGUgZm9ybWF0IG9mIHRoZSBBQ0xcbiAgLy8gYXJnIHRvIHdvcmsgbGlrZSB0aGUgb3RoZXJzLlxuICBmaW5kKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHF1ZXJ5OiBhbnksXG4gICAge1xuICAgICAgc2tpcCxcbiAgICAgIGxpbWl0LFxuICAgICAgYWNsLFxuICAgICAgc29ydCA9IHt9LFxuICAgICAgY291bnQsXG4gICAgICBrZXlzLFxuICAgICAgb3AsXG4gICAgICBkaXN0aW5jdCxcbiAgICAgIHBpcGVsaW5lLFxuICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICBoaW50LFxuICAgICAgY2FzZUluc2Vuc2l0aXZlID0gZmFsc2UsXG4gICAgICBleHBsYWluLFxuICAgIH06IGFueSA9IHt9LFxuICAgIGF1dGg6IGFueSA9IHt9LFxuICAgIHZhbGlkU2NoZW1hQ29udHJvbGxlcjogU2NoZW1hQ29udHJvbGxlci5TY2hlbWFDb250cm9sbGVyXG4gICk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3QgaXNNYXN0ZXIgPSBhY2wgPT09IHVuZGVmaW5lZDtcbiAgICBjb25zdCBhY2xHcm91cCA9IGFjbCB8fCBbXTtcbiAgICBvcCA9XG4gICAgICBvcCB8fCAodHlwZW9mIHF1ZXJ5Lm9iamVjdElkID09ICdzdHJpbmcnICYmIE9iamVjdC5rZXlzKHF1ZXJ5KS5sZW5ndGggPT09IDEgPyAnZ2V0JyA6ICdmaW5kJyk7XG4gICAgLy8gQ291bnQgb3BlcmF0aW9uIGlmIGNvdW50aW5nXG4gICAgb3AgPSBjb3VudCA9PT0gdHJ1ZSA/ICdjb3VudCcgOiBvcDtcblxuICAgIGxldCBjbGFzc0V4aXN0cyA9IHRydWU7XG4gICAgcmV0dXJuIHRoaXMubG9hZFNjaGVtYUlmTmVlZGVkKHZhbGlkU2NoZW1hQ29udHJvbGxlcikudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHtcbiAgICAgIC8vQWxsb3cgdm9sYXRpbGUgY2xhc3NlcyBpZiBxdWVyeWluZyB3aXRoIE1hc3RlciAoZm9yIF9QdXNoU3RhdHVzKVxuICAgICAgLy9UT0RPOiBNb3ZlIHZvbGF0aWxlIGNsYXNzZXMgY29uY2VwdCBpbnRvIG1vbmdvIGFkYXB0ZXIsIHBvc3RncmVzIGFkYXB0ZXIgc2hvdWxkbid0IGNhcmVcbiAgICAgIC8vdGhhdCBhcGkucGFyc2UuY29tIGJyZWFrcyB3aGVuIF9QdXNoU3RhdHVzIGV4aXN0cyBpbiBtb25nby5cbiAgICAgIHJldHVybiBzY2hlbWFDb250cm9sbGVyXG4gICAgICAgIC5nZXRPbmVTY2hlbWEoY2xhc3NOYW1lLCBpc01hc3RlcilcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAvLyBCZWhhdmlvciBmb3Igbm9uLWV4aXN0ZW50IGNsYXNzZXMgaXMga2luZGEgd2VpcmQgb24gUGFyc2UuY29tLiBQcm9iYWJseSBkb2Vzbid0IG1hdHRlciB0b28gbXVjaC5cbiAgICAgICAgICAvLyBGb3Igbm93LCBwcmV0ZW5kIHRoZSBjbGFzcyBleGlzdHMgYnV0IGhhcyBubyBvYmplY3RzLFxuICAgICAgICAgIGlmIChlcnJvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjbGFzc0V4aXN0cyA9IGZhbHNlO1xuICAgICAgICAgICAgcmV0dXJuIHsgZmllbGRzOiB7fSB9O1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oc2NoZW1hID0+IHtcbiAgICAgICAgICAvLyBQYXJzZS5jb20gdHJlYXRzIHF1ZXJpZXMgb24gX2NyZWF0ZWRfYXQgYW5kIF91cGRhdGVkX2F0IGFzIGlmIHRoZXkgd2VyZSBxdWVyaWVzIG9uIGNyZWF0ZWRBdCBhbmQgdXBkYXRlZEF0LFxuICAgICAgICAgIC8vIHNvIGR1cGxpY2F0ZSB0aGF0IGJlaGF2aW9yIGhlcmUuIElmIGJvdGggYXJlIHNwZWNpZmllZCwgdGhlIGNvcnJlY3QgYmVoYXZpb3IgdG8gbWF0Y2ggUGFyc2UuY29tIGlzIHRvXG4gICAgICAgICAgLy8gdXNlIHRoZSBvbmUgdGhhdCBhcHBlYXJzIGZpcnN0IGluIHRoZSBzb3J0IGxpc3QuXG4gICAgICAgICAgaWYgKHNvcnQuX2NyZWF0ZWRfYXQpIHtcbiAgICAgICAgICAgIHNvcnQuY3JlYXRlZEF0ID0gc29ydC5fY3JlYXRlZF9hdDtcbiAgICAgICAgICAgIGRlbGV0ZSBzb3J0Ll9jcmVhdGVkX2F0O1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoc29ydC5fdXBkYXRlZF9hdCkge1xuICAgICAgICAgICAgc29ydC51cGRhdGVkQXQgPSBzb3J0Ll91cGRhdGVkX2F0O1xuICAgICAgICAgICAgZGVsZXRlIHNvcnQuX3VwZGF0ZWRfYXQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHF1ZXJ5T3B0aW9ucyA9IHtcbiAgICAgICAgICAgIHNraXAsXG4gICAgICAgICAgICBsaW1pdCxcbiAgICAgICAgICAgIHNvcnQsXG4gICAgICAgICAgICBrZXlzLFxuICAgICAgICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICBoaW50LFxuICAgICAgICAgICAgY2FzZUluc2Vuc2l0aXZlLFxuICAgICAgICAgICAgZXhwbGFpbixcbiAgICAgICAgICB9O1xuICAgICAgICAgIE9iamVjdC5rZXlzKHNvcnQpLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgICAgICAgIGlmIChmaWVsZE5hbWUubWF0Y2goL15hdXRoRGF0YVxcLihbYS16QS1aMC05X10rKVxcLmlkJC8pKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FLCBgQ2Fubm90IHNvcnQgYnkgJHtmaWVsZE5hbWV9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCByb290RmllbGROYW1lID0gZ2V0Um9vdEZpZWxkTmFtZShmaWVsZE5hbWUpO1xuICAgICAgICAgICAgaWYgKCFTY2hlbWFDb250cm9sbGVyLmZpZWxkTmFtZUlzVmFsaWQocm9vdEZpZWxkTmFtZSwgY2xhc3NOYW1lKSkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSxcbiAgICAgICAgICAgICAgICBgSW52YWxpZCBmaWVsZCBuYW1lOiAke2ZpZWxkTmFtZX0uYFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybiAoaXNNYXN0ZXJcbiAgICAgICAgICAgID8gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgICAgIDogc2NoZW1hQ29udHJvbGxlci52YWxpZGF0ZVBlcm1pc3Npb24oY2xhc3NOYW1lLCBhY2xHcm91cCwgb3ApXG4gICAgICAgICAgKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5yZWR1Y2VSZWxhdGlvbktleXMoY2xhc3NOYW1lLCBxdWVyeSwgcXVlcnlPcHRpb25zKSlcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMucmVkdWNlSW5SZWxhdGlvbihjbGFzc05hbWUsIHF1ZXJ5LCBzY2hlbWFDb250cm9sbGVyKSlcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgbGV0IHByb3RlY3RlZEZpZWxkcztcbiAgICAgICAgICAgICAgaWYgKCFpc01hc3Rlcikge1xuICAgICAgICAgICAgICAgIHF1ZXJ5ID0gdGhpcy5hZGRQb2ludGVyUGVybWlzc2lvbnMoXG4gICAgICAgICAgICAgICAgICBzY2hlbWFDb250cm9sbGVyLFxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgb3AsXG4gICAgICAgICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgICAgICAgIGFjbEdyb3VwXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAvKiBEb24ndCB1c2UgcHJvamVjdGlvbnMgdG8gb3B0aW1pemUgdGhlIHByb3RlY3RlZEZpZWxkcyBzaW5jZSB0aGUgcHJvdGVjdGVkRmllbGRzXG4gICAgICAgICAgICAgICAgICBiYXNlZCBvbiBwb2ludGVyLXBlcm1pc3Npb25zIGFyZSBkZXRlcm1pbmVkIGFmdGVyIHF1ZXJ5aW5nLiBUaGUgZmlsdGVyaW5nIGNhblxuICAgICAgICAgICAgICAgICAgb3ZlcndyaXRlIHRoZSBwcm90ZWN0ZWQgZmllbGRzLiAqL1xuICAgICAgICAgICAgICAgIHByb3RlY3RlZEZpZWxkcyA9IHRoaXMuYWRkUHJvdGVjdGVkRmllbGRzKFxuICAgICAgICAgICAgICAgICAgc2NoZW1hQ29udHJvbGxlcixcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgIHF1ZXJ5LFxuICAgICAgICAgICAgICAgICAgYWNsR3JvdXAsXG4gICAgICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICAgICAgcXVlcnlPcHRpb25zXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoIXF1ZXJ5KSB7XG4gICAgICAgICAgICAgICAgaWYgKG9wID09PSAnZ2V0Jykge1xuICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kLicpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmICghaXNNYXN0ZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAob3AgPT09ICd1cGRhdGUnIHx8IG9wID09PSAnZGVsZXRlJykge1xuICAgICAgICAgICAgICAgICAgcXVlcnkgPSBhZGRXcml0ZUFDTChxdWVyeSwgYWNsR3JvdXApO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBxdWVyeSA9IGFkZFJlYWRBQ0wocXVlcnksIGFjbEdyb3VwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdmFsaWRhdGVRdWVyeShxdWVyeSk7XG4gICAgICAgICAgICAgIGlmIChjb3VudCkge1xuICAgICAgICAgICAgICAgIGlmICghY2xhc3NFeGlzdHMpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmNvdW50KFxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgICAgIHNjaGVtYSxcbiAgICAgICAgICAgICAgICAgICAgcXVlcnksXG4gICAgICAgICAgICAgICAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgIGhpbnRcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGRpc3RpbmN0KSB7XG4gICAgICAgICAgICAgICAgaWYgKCFjbGFzc0V4aXN0cykge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmRpc3RpbmN0KGNsYXNzTmFtZSwgc2NoZW1hLCBxdWVyeSwgZGlzdGluY3QpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChwaXBlbGluZSkge1xuICAgICAgICAgICAgICAgIGlmICghY2xhc3NFeGlzdHMpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci5hZ2dyZWdhdGUoXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgICAgICAgICAgICBwaXBlbGluZSxcbiAgICAgICAgICAgICAgICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICAgICAgICAgIGhpbnQsXG4gICAgICAgICAgICAgICAgICAgIGV4cGxhaW5cbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGV4cGxhaW4pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmZpbmQoY2xhc3NOYW1lLCBzY2hlbWEsIHF1ZXJ5LCBxdWVyeU9wdGlvbnMpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXJcbiAgICAgICAgICAgICAgICAgIC5maW5kKGNsYXNzTmFtZSwgc2NoZW1hLCBxdWVyeSwgcXVlcnlPcHRpb25zKVxuICAgICAgICAgICAgICAgICAgLnRoZW4ob2JqZWN0cyA9PlxuICAgICAgICAgICAgICAgICAgICBvYmplY3RzLm1hcChvYmplY3QgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgIG9iamVjdCA9IHVudHJhbnNmb3JtT2JqZWN0QUNMKG9iamVjdCk7XG4gICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbHRlclNlbnNpdGl2ZURhdGEoXG4gICAgICAgICAgICAgICAgICAgICAgICBpc01hc3RlcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjbEdyb3VwLFxuICAgICAgICAgICAgICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2NoZW1hQ29udHJvbGxlcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb3RlY3RlZEZpZWxkcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdFxuICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZGVsZXRlU2NoZW1hKGNsYXNzTmFtZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMubG9hZFNjaGVtYSh7IGNsZWFyQ2FjaGU6IHRydWUgfSlcbiAgICAgIC50aGVuKHNjaGVtYUNvbnRyb2xsZXIgPT4gc2NoZW1hQ29udHJvbGxlci5nZXRPbmVTY2hlbWEoY2xhc3NOYW1lLCB0cnVlKSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmV0dXJuIHsgZmllbGRzOiB7fSB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLnRoZW4oKHNjaGVtYTogYW55KSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbGxlY3Rpb25FeGlzdHMoY2xhc3NOYW1lKVxuICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMuYWRhcHRlci5jb3VudChjbGFzc05hbWUsIHsgZmllbGRzOiB7fSB9LCBudWxsLCAnJywgZmFsc2UpKVxuICAgICAgICAgIC50aGVuKGNvdW50ID0+IHtcbiAgICAgICAgICAgIGlmIChjb3VudCA+IDApIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIDI1NSxcbiAgICAgICAgICAgICAgICBgQ2xhc3MgJHtjbGFzc05hbWV9IGlzIG5vdCBlbXB0eSwgY29udGFpbnMgJHtjb3VudH0gb2JqZWN0cywgY2Fubm90IGRyb3Agc2NoZW1hLmBcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuZGVsZXRlQ2xhc3MoY2xhc3NOYW1lKTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC50aGVuKHdhc1BhcnNlQ29sbGVjdGlvbiA9PiB7XG4gICAgICAgICAgICBpZiAod2FzUGFyc2VDb2xsZWN0aW9uKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHJlbGF0aW9uRmllbGROYW1lcyA9IE9iamVjdC5rZXlzKHNjaGVtYS5maWVsZHMpLmZpbHRlcihcbiAgICAgICAgICAgICAgICBmaWVsZE5hbWUgPT4gc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdSZWxhdGlvbidcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgICAgICAgICAgICAgIHJlbGF0aW9uRmllbGROYW1lcy5tYXAobmFtZSA9PlxuICAgICAgICAgICAgICAgICAgdGhpcy5hZGFwdGVyLmRlbGV0ZUNsYXNzKGpvaW5UYWJsZU5hbWUoY2xhc3NOYW1lLCBuYW1lKSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gVGhpcyBoZWxwcyB0byBjcmVhdGUgaW50ZXJtZWRpYXRlIG9iamVjdHMgZm9yIHNpbXBsZXIgY29tcGFyaXNvbiBvZlxuICAvLyBrZXkgdmFsdWUgcGFpcnMgdXNlZCBpbiBxdWVyeSBvYmplY3RzLiBFYWNoIGtleSB2YWx1ZSBwYWlyIHdpbGwgcmVwcmVzZW50ZWRcbiAgLy8gaW4gYSBzaW1pbGFyIHdheSB0byBqc29uXG4gIG9iamVjdFRvRW50cmllc1N0cmluZ3MocXVlcnk6IGFueSk6IEFycmF5PHN0cmluZz4ge1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyhxdWVyeSkubWFwKGEgPT4gYS5tYXAocyA9PiBKU09OLnN0cmluZ2lmeShzKSkuam9pbignOicpKTtcbiAgfVxuXG4gIC8vIE5haXZlIGxvZ2ljIHJlZHVjZXIgZm9yIE9SIG9wZXJhdGlvbnMgbWVhbnQgdG8gYmUgdXNlZCBvbmx5IGZvciBwb2ludGVyIHBlcm1pc3Npb25zLlxuICByZWR1Y2VPck9wZXJhdGlvbihxdWVyeTogeyAkb3I6IEFycmF5PGFueT4gfSk6IGFueSB7XG4gICAgaWYgKCFxdWVyeS4kb3IpIHtcbiAgICAgIHJldHVybiBxdWVyeTtcbiAgICB9XG4gICAgY29uc3QgcXVlcmllcyA9IHF1ZXJ5LiRvci5tYXAocSA9PiB0aGlzLm9iamVjdFRvRW50cmllc1N0cmluZ3MocSkpO1xuICAgIGxldCByZXBlYXQgPSBmYWxzZTtcbiAgICBkbyB7XG4gICAgICByZXBlYXQgPSBmYWxzZTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcXVlcmllcy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgcXVlcmllcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgIGNvbnN0IFtzaG9ydGVyLCBsb25nZXJdID0gcXVlcmllc1tpXS5sZW5ndGggPiBxdWVyaWVzW2pdLmxlbmd0aCA/IFtqLCBpXSA6IFtpLCBqXTtcbiAgICAgICAgICBjb25zdCBmb3VuZEVudHJpZXMgPSBxdWVyaWVzW3Nob3J0ZXJdLnJlZHVjZShcbiAgICAgICAgICAgIChhY2MsIGVudHJ5KSA9PiBhY2MgKyAocXVlcmllc1tsb25nZXJdLmluY2x1ZGVzKGVudHJ5KSA/IDEgOiAwKSxcbiAgICAgICAgICAgIDBcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IHNob3J0ZXJFbnRyaWVzID0gcXVlcmllc1tzaG9ydGVyXS5sZW5ndGg7XG4gICAgICAgICAgaWYgKGZvdW5kRW50cmllcyA9PT0gc2hvcnRlckVudHJpZXMpIHtcbiAgICAgICAgICAgIC8vIElmIHRoZSBzaG9ydGVyIHF1ZXJ5IGlzIGNvbXBsZXRlbHkgY29udGFpbmVkIGluIHRoZSBsb25nZXIgb25lLCB3ZSBjYW4gc3RyaWtlXG4gICAgICAgICAgICAvLyBvdXQgdGhlIGxvbmdlciBxdWVyeS5cbiAgICAgICAgICAgIHF1ZXJ5LiRvci5zcGxpY2UobG9uZ2VyLCAxKTtcbiAgICAgICAgICAgIHF1ZXJpZXMuc3BsaWNlKGxvbmdlciwgMSk7XG4gICAgICAgICAgICByZXBlYXQgPSB0cnVlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSB3aGlsZSAocmVwZWF0KTtcbiAgICBpZiAocXVlcnkuJG9yLmxlbmd0aCA9PT0gMSkge1xuICAgICAgcXVlcnkgPSB7IC4uLnF1ZXJ5LCAuLi5xdWVyeS4kb3JbMF0gfTtcbiAgICAgIGRlbGV0ZSBxdWVyeS4kb3I7XG4gICAgfVxuICAgIHJldHVybiBxdWVyeTtcbiAgfVxuXG4gIC8vIE5haXZlIGxvZ2ljIHJlZHVjZXIgZm9yIEFORCBvcGVyYXRpb25zIG1lYW50IHRvIGJlIHVzZWQgb25seSBmb3IgcG9pbnRlciBwZXJtaXNzaW9ucy5cbiAgcmVkdWNlQW5kT3BlcmF0aW9uKHF1ZXJ5OiB7ICRhbmQ6IEFycmF5PGFueT4gfSk6IGFueSB7XG4gICAgaWYgKCFxdWVyeS4kYW5kKSB7XG4gICAgICByZXR1cm4gcXVlcnk7XG4gICAgfVxuICAgIGNvbnN0IHF1ZXJpZXMgPSBxdWVyeS4kYW5kLm1hcChxID0+IHRoaXMub2JqZWN0VG9FbnRyaWVzU3RyaW5ncyhxKSk7XG4gICAgbGV0IHJlcGVhdCA9IGZhbHNlO1xuICAgIGRvIHtcbiAgICAgIHJlcGVhdCA9IGZhbHNlO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBxdWVyaWVzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCBxdWVyaWVzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgY29uc3QgW3Nob3J0ZXIsIGxvbmdlcl0gPSBxdWVyaWVzW2ldLmxlbmd0aCA+IHF1ZXJpZXNbal0ubGVuZ3RoID8gW2osIGldIDogW2ksIGpdO1xuICAgICAgICAgIGNvbnN0IGZvdW5kRW50cmllcyA9IHF1ZXJpZXNbc2hvcnRlcl0ucmVkdWNlKFxuICAgICAgICAgICAgKGFjYywgZW50cnkpID0+IGFjYyArIChxdWVyaWVzW2xvbmdlcl0uaW5jbHVkZXMoZW50cnkpID8gMSA6IDApLFxuICAgICAgICAgICAgMFxuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3Qgc2hvcnRlckVudHJpZXMgPSBxdWVyaWVzW3Nob3J0ZXJdLmxlbmd0aDtcbiAgICAgICAgICBpZiAoZm91bmRFbnRyaWVzID09PSBzaG9ydGVyRW50cmllcykge1xuICAgICAgICAgICAgLy8gSWYgdGhlIHNob3J0ZXIgcXVlcnkgaXMgY29tcGxldGVseSBjb250YWluZWQgaW4gdGhlIGxvbmdlciBvbmUsIHdlIGNhbiBzdHJpa2VcbiAgICAgICAgICAgIC8vIG91dCB0aGUgc2hvcnRlciBxdWVyeS5cbiAgICAgICAgICAgIHF1ZXJ5LiRhbmQuc3BsaWNlKHNob3J0ZXIsIDEpO1xuICAgICAgICAgICAgcXVlcmllcy5zcGxpY2Uoc2hvcnRlciwgMSk7XG4gICAgICAgICAgICByZXBlYXQgPSB0cnVlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSB3aGlsZSAocmVwZWF0KTtcbiAgICBpZiAocXVlcnkuJGFuZC5sZW5ndGggPT09IDEpIHtcbiAgICAgIHF1ZXJ5ID0geyAuLi5xdWVyeSwgLi4ucXVlcnkuJGFuZFswXSB9O1xuICAgICAgZGVsZXRlIHF1ZXJ5LiRhbmQ7XG4gICAgfVxuICAgIHJldHVybiBxdWVyeTtcbiAgfVxuXG4gIC8vIENvbnN0cmFpbnRzIHF1ZXJ5IHVzaW5nIENMUCdzIHBvaW50ZXIgcGVybWlzc2lvbnMgKFBQKSBpZiBhbnkuXG4gIC8vIDEuIEV0cmFjdCB0aGUgdXNlciBpZCBmcm9tIGNhbGxlcidzIEFDTGdyb3VwO1xuICAvLyAyLiBFeGN0cmFjdCBhIGxpc3Qgb2YgZmllbGQgbmFtZXMgdGhhdCBhcmUgUFAgZm9yIHRhcmdldCBjb2xsZWN0aW9uIGFuZCBvcGVyYXRpb247XG4gIC8vIDMuIENvbnN0cmFpbnQgdGhlIG9yaWdpbmFsIHF1ZXJ5IHNvIHRoYXQgZWFjaCBQUCBmaWVsZCBtdXN0XG4gIC8vIHBvaW50IHRvIGNhbGxlcidzIGlkIChvciBjb250YWluIGl0IGluIGNhc2Ugb2YgUFAgZmllbGQgYmVpbmcgYW4gYXJyYXkpXG4gIGFkZFBvaW50ZXJQZXJtaXNzaW9ucyhcbiAgICBzY2hlbWE6IFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlcixcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBvcGVyYXRpb246IHN0cmluZyxcbiAgICBxdWVyeTogYW55LFxuICAgIGFjbEdyb3VwOiBhbnlbXSA9IFtdXG4gICk6IGFueSB7XG4gICAgLy8gQ2hlY2sgaWYgY2xhc3MgaGFzIHB1YmxpYyBwZXJtaXNzaW9uIGZvciBvcGVyYXRpb25cbiAgICAvLyBJZiB0aGUgQmFzZUNMUCBwYXNzLCBsZXQgZ28gdGhyb3VnaFxuICAgIGlmIChzY2hlbWEudGVzdFBlcm1pc3Npb25zRm9yQ2xhc3NOYW1lKGNsYXNzTmFtZSwgYWNsR3JvdXAsIG9wZXJhdGlvbikpIHtcbiAgICAgIHJldHVybiBxdWVyeTtcbiAgICB9XG4gICAgY29uc3QgcGVybXMgPSBzY2hlbWEuZ2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zKGNsYXNzTmFtZSk7XG5cbiAgICBjb25zdCB1c2VyQUNMID0gYWNsR3JvdXAuZmlsdGVyKGFjbCA9PiB7XG4gICAgICByZXR1cm4gYWNsLmluZGV4T2YoJ3JvbGU6JykgIT0gMCAmJiBhY2wgIT0gJyonO1xuICAgIH0pO1xuXG4gICAgY29uc3QgZ3JvdXBLZXkgPVxuICAgICAgWydnZXQnLCAnZmluZCcsICdjb3VudCddLmluZGV4T2Yob3BlcmF0aW9uKSA+IC0xID8gJ3JlYWRVc2VyRmllbGRzJyA6ICd3cml0ZVVzZXJGaWVsZHMnO1xuXG4gICAgY29uc3QgcGVybUZpZWxkcyA9IFtdO1xuXG4gICAgaWYgKHBlcm1zW29wZXJhdGlvbl0gJiYgcGVybXNbb3BlcmF0aW9uXS5wb2ludGVyRmllbGRzKSB7XG4gICAgICBwZXJtRmllbGRzLnB1c2goLi4ucGVybXNbb3BlcmF0aW9uXS5wb2ludGVyRmllbGRzKTtcbiAgICB9XG5cbiAgICBpZiAocGVybXNbZ3JvdXBLZXldKSB7XG4gICAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIHBlcm1zW2dyb3VwS2V5XSkge1xuICAgICAgICBpZiAoIXBlcm1GaWVsZHMuaW5jbHVkZXMoZmllbGQpKSB7XG4gICAgICAgICAgcGVybUZpZWxkcy5wdXNoKGZpZWxkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyB0aGUgQUNMIHNob3VsZCBoYXZlIGV4YWN0bHkgMSB1c2VyXG4gICAgaWYgKHBlcm1GaWVsZHMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gdGhlIEFDTCBzaG91bGQgaGF2ZSBleGFjdGx5IDEgdXNlclxuICAgICAgLy8gTm8gdXNlciBzZXQgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgLy8gSWYgdGhlIGxlbmd0aCBpcyA+IDEsIHRoYXQgbWVhbnMgd2UgZGlkbid0IGRlLWR1cGUgdXNlcnMgY29ycmVjdGx5XG4gICAgICBpZiAodXNlckFDTC5sZW5ndGggIT0gMSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCB1c2VySWQgPSB1c2VyQUNMWzBdO1xuICAgICAgY29uc3QgdXNlclBvaW50ZXIgPSB7XG4gICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICBjbGFzc05hbWU6ICdfVXNlcicsXG4gICAgICAgIG9iamVjdElkOiB1c2VySWQsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBxdWVyaWVzID0gcGVybUZpZWxkcy5tYXAoa2V5ID0+IHtcbiAgICAgICAgY29uc3QgZmllbGREZXNjcmlwdG9yID0gc2NoZW1hLmdldEV4cGVjdGVkVHlwZShjbGFzc05hbWUsIGtleSk7XG4gICAgICAgIGNvbnN0IGZpZWxkVHlwZSA9XG4gICAgICAgICAgZmllbGREZXNjcmlwdG9yICYmXG4gICAgICAgICAgdHlwZW9mIGZpZWxkRGVzY3JpcHRvciA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZmllbGREZXNjcmlwdG9yLCAndHlwZScpXG4gICAgICAgICAgICA/IGZpZWxkRGVzY3JpcHRvci50eXBlXG4gICAgICAgICAgICA6IG51bGw7XG5cbiAgICAgICAgbGV0IHF1ZXJ5Q2xhdXNlO1xuXG4gICAgICAgIGlmIChmaWVsZFR5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgICAgIC8vIGNvbnN0cmFpbnQgZm9yIHNpbmdsZSBwb2ludGVyIHNldHVwXG4gICAgICAgICAgcXVlcnlDbGF1c2UgPSB7IFtrZXldOiB1c2VyUG9pbnRlciB9O1xuICAgICAgICB9IGVsc2UgaWYgKGZpZWxkVHlwZSA9PT0gJ0FycmF5Jykge1xuICAgICAgICAgIC8vIGNvbnN0cmFpbnQgZm9yIHVzZXJzLWFycmF5IHNldHVwXG4gICAgICAgICAgcXVlcnlDbGF1c2UgPSB7IFtrZXldOiB7ICRhbGw6IFt1c2VyUG9pbnRlcl0gfSB9O1xuICAgICAgICB9IGVsc2UgaWYgKGZpZWxkVHlwZSA9PT0gJ09iamVjdCcpIHtcbiAgICAgICAgICAvLyBjb25zdHJhaW50IGZvciBvYmplY3Qgc2V0dXBcbiAgICAgICAgICBxdWVyeUNsYXVzZSA9IHsgW2tleV06IHVzZXJQb2ludGVyIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gVGhpcyBtZWFucyB0aGF0IHRoZXJlIGlzIGEgQ0xQIGZpZWxkIG9mIGFuIHVuZXhwZWN0ZWQgdHlwZS4gVGhpcyBjb25kaXRpb24gc2hvdWxkIG5vdCBoYXBwZW4sIHdoaWNoIGlzXG4gICAgICAgICAgLy8gd2h5IGlzIGJlaW5nIHRyZWF0ZWQgYXMgYW4gZXJyb3IuXG4gICAgICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgICAgICBgQW4gdW5leHBlY3RlZCBjb25kaXRpb24gb2NjdXJyZWQgd2hlbiByZXNvbHZpbmcgcG9pbnRlciBwZXJtaXNzaW9uczogJHtjbGFzc05hbWV9ICR7a2V5fWBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIC8vIGlmIHdlIGFscmVhZHkgaGF2ZSBhIGNvbnN0cmFpbnQgb24gdGhlIGtleSwgdXNlIHRoZSAkYW5kXG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocXVlcnksIGtleSkpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5yZWR1Y2VBbmRPcGVyYXRpb24oeyAkYW5kOiBbcXVlcnlDbGF1c2UsIHF1ZXJ5XSB9KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBvdGhlcndpc2UganVzdCBhZGQgdGhlIGNvbnN0YWludFxuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgcXVlcnksIHF1ZXJ5Q2xhdXNlKTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gcXVlcmllcy5sZW5ndGggPT09IDEgPyBxdWVyaWVzWzBdIDogdGhpcy5yZWR1Y2VPck9wZXJhdGlvbih7ICRvcjogcXVlcmllcyB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHF1ZXJ5O1xuICAgIH1cbiAgfVxuXG4gIGFkZFByb3RlY3RlZEZpZWxkcyhcbiAgICBzY2hlbWE6IFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlcixcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBxdWVyeTogYW55ID0ge30sXG4gICAgYWNsR3JvdXA6IGFueVtdID0gW10sXG4gICAgYXV0aDogYW55ID0ge30sXG4gICAgcXVlcnlPcHRpb25zOiBGdWxsUXVlcnlPcHRpb25zID0ge31cbiAgKTogbnVsbCB8IHN0cmluZ1tdIHtcbiAgICBjb25zdCBwZXJtcyA9IHNjaGVtYS5nZXRDbGFzc0xldmVsUGVybWlzc2lvbnMoY2xhc3NOYW1lKTtcbiAgICBpZiAoIXBlcm1zKSByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IHByb3RlY3RlZEZpZWxkcyA9IHBlcm1zLnByb3RlY3RlZEZpZWxkcztcbiAgICBpZiAoIXByb3RlY3RlZEZpZWxkcykgcmV0dXJuIG51bGw7XG5cbiAgICBpZiAoYWNsR3JvdXAuaW5kZXhPZihxdWVyeS5vYmplY3RJZCkgPiAtMSkgcmV0dXJuIG51bGw7XG5cbiAgICAvLyBmb3IgcXVlcmllcyB3aGVyZSBcImtleXNcIiBhcmUgc2V0IGFuZCBkbyBub3QgaW5jbHVkZSBhbGwgJ3VzZXJGaWVsZCc6e2ZpZWxkfSxcbiAgICAvLyB3ZSBoYXZlIHRvIHRyYW5zcGFyZW50bHkgaW5jbHVkZSBpdCwgYW5kIHRoZW4gcmVtb3ZlIGJlZm9yZSByZXR1cm5pbmcgdG8gY2xpZW50XG4gICAgLy8gQmVjYXVzZSBpZiBzdWNoIGtleSBub3QgcHJvamVjdGVkIHRoZSBwZXJtaXNzaW9uIHdvbid0IGJlIGVuZm9yY2VkIHByb3Blcmx5XG4gICAgLy8gUFMgdGhpcyBpcyBjYWxsZWQgd2hlbiAnZXhjbHVkZUtleXMnIGFscmVhZHkgcmVkdWNlZCB0byAna2V5cydcbiAgICBjb25zdCBwcmVzZXJ2ZUtleXMgPSBxdWVyeU9wdGlvbnMua2V5cztcblxuICAgIC8vIHRoZXNlIGFyZSBrZXlzIHRoYXQgbmVlZCB0byBiZSBpbmNsdWRlZCBvbmx5XG4gICAgLy8gdG8gYmUgYWJsZSB0byBhcHBseSBwcm90ZWN0ZWRGaWVsZHMgYnkgcG9pbnRlclxuICAgIC8vIGFuZCB0aGVuIHVuc2V0IGJlZm9yZSByZXR1cm5pbmcgdG8gY2xpZW50IChsYXRlciBpbiAgZmlsdGVyU2Vuc2l0aXZlRmllbGRzKVxuICAgIGNvbnN0IHNlcnZlck9ubHlLZXlzID0gW107XG5cbiAgICBjb25zdCBhdXRoZW50aWNhdGVkID0gYXV0aC51c2VyO1xuXG4gICAgLy8gbWFwIHRvIGFsbG93IGNoZWNrIHdpdGhvdXQgYXJyYXkgc2VhcmNoXG4gICAgY29uc3Qgcm9sZXMgPSAoYXV0aC51c2VyUm9sZXMgfHwgW10pLnJlZHVjZSgoYWNjLCByKSA9PiB7XG4gICAgICBhY2Nbcl0gPSBwcm90ZWN0ZWRGaWVsZHNbcl07XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHt9KTtcblxuICAgIC8vIGFycmF5IG9mIHNldHMgb2YgcHJvdGVjdGVkIGZpZWxkcy4gc2VwYXJhdGUgaXRlbSBmb3IgZWFjaCBhcHBsaWNhYmxlIGNyaXRlcmlhXG4gICAgY29uc3QgcHJvdGVjdGVkS2V5c1NldHMgPSBbXTtcblxuICAgIGZvciAoY29uc3Qga2V5IGluIHByb3RlY3RlZEZpZWxkcykge1xuICAgICAgLy8gc2tpcCB1c2VyRmllbGRzXG4gICAgICBpZiAoa2V5LnN0YXJ0c1dpdGgoJ3VzZXJGaWVsZDonKSkge1xuICAgICAgICBpZiAocHJlc2VydmVLZXlzKSB7XG4gICAgICAgICAgY29uc3QgZmllbGROYW1lID0ga2V5LnN1YnN0cmluZygxMCk7XG4gICAgICAgICAgaWYgKCFwcmVzZXJ2ZUtleXMuaW5jbHVkZXMoZmllbGROYW1lKSkge1xuICAgICAgICAgICAgLy8gMS4gcHV0IGl0IHRoZXJlIHRlbXBvcmFyaWx5XG4gICAgICAgICAgICBxdWVyeU9wdGlvbnMua2V5cyAmJiBxdWVyeU9wdGlvbnMua2V5cy5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICAgICAgICAvLyAyLiBwcmVzZXJ2ZSBpdCBkZWxldGUgbGF0ZXJcbiAgICAgICAgICAgIHNlcnZlck9ubHlLZXlzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGFkZCBwdWJsaWMgdGllclxuICAgICAgaWYgKGtleSA9PT0gJyonKSB7XG4gICAgICAgIHByb3RlY3RlZEtleXNTZXRzLnB1c2gocHJvdGVjdGVkRmllbGRzW2tleV0pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGF1dGhlbnRpY2F0ZWQpIHtcbiAgICAgICAgaWYgKGtleSA9PT0gJ2F1dGhlbnRpY2F0ZWQnKSB7XG4gICAgICAgICAgLy8gZm9yIGxvZ2dlZCBpbiB1c2Vyc1xuICAgICAgICAgIHByb3RlY3RlZEtleXNTZXRzLnB1c2gocHJvdGVjdGVkRmllbGRzW2tleV0pO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJvbGVzW2tleV0gJiYga2V5LnN0YXJ0c1dpdGgoJ3JvbGU6JykpIHtcbiAgICAgICAgICAvLyBhZGQgYXBwbGljYWJsZSByb2xlc1xuICAgICAgICAgIHByb3RlY3RlZEtleXNTZXRzLnB1c2gocm9sZXNba2V5XSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBjaGVjayBpZiB0aGVyZSdzIGEgcnVsZSBmb3IgY3VycmVudCB1c2VyJ3MgaWRcbiAgICBpZiAoYXV0aGVudGljYXRlZCkge1xuICAgICAgY29uc3QgdXNlcklkID0gYXV0aC51c2VyLmlkO1xuICAgICAgaWYgKHBlcm1zLnByb3RlY3RlZEZpZWxkc1t1c2VySWRdKSB7XG4gICAgICAgIHByb3RlY3RlZEtleXNTZXRzLnB1c2gocGVybXMucHJvdGVjdGVkRmllbGRzW3VzZXJJZF0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHByZXNlcnZlIGZpZWxkcyB0byBiZSByZW1vdmVkIGJlZm9yZSBzZW5kaW5nIHJlc3BvbnNlIHRvIGNsaWVudFxuICAgIGlmIChzZXJ2ZXJPbmx5S2V5cy5sZW5ndGggPiAwKSB7XG4gICAgICBwZXJtcy5wcm90ZWN0ZWRGaWVsZHMudGVtcG9yYXJ5S2V5cyA9IHNlcnZlck9ubHlLZXlzO1xuICAgIH1cblxuICAgIGxldCBwcm90ZWN0ZWRLZXlzID0gcHJvdGVjdGVkS2V5c1NldHMucmVkdWNlKChhY2MsIG5leHQpID0+IHtcbiAgICAgIGlmIChuZXh0KSB7XG4gICAgICAgIGFjYy5wdXNoKC4uLm5leHQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCBbXSk7XG5cbiAgICAvLyBpbnRlcnNlY3QgYWxsIHNldHMgb2YgcHJvdGVjdGVkRmllbGRzXG4gICAgcHJvdGVjdGVkS2V5c1NldHMuZm9yRWFjaChmaWVsZHMgPT4ge1xuICAgICAgaWYgKGZpZWxkcykge1xuICAgICAgICBwcm90ZWN0ZWRLZXlzID0gcHJvdGVjdGVkS2V5cy5maWx0ZXIodiA9PiBmaWVsZHMuaW5jbHVkZXModikpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHByb3RlY3RlZEtleXM7XG4gIH1cblxuICBjcmVhdGVUcmFuc2FjdGlvbmFsU2Vzc2lvbigpIHtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uKCkudGhlbih0cmFuc2FjdGlvbmFsU2Vzc2lvbiA9PiB7XG4gICAgICB0aGlzLl90cmFuc2FjdGlvbmFsU2Vzc2lvbiA9IHRyYW5zYWN0aW9uYWxTZXNzaW9uO1xuICAgIH0pO1xuICB9XG5cbiAgY29tbWl0VHJhbnNhY3Rpb25hbFNlc3Npb24oKSB7XG4gICAgaWYgKCF0aGlzLl90cmFuc2FjdGlvbmFsU2Vzc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGVyZSBpcyBubyB0cmFuc2FjdGlvbmFsIHNlc3Npb24gdG8gY29tbWl0Jyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuY29tbWl0VHJhbnNhY3Rpb25hbFNlc3Npb24odGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb24pLnRoZW4oKCkgPT4ge1xuICAgICAgdGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb24gPSBudWxsO1xuICAgIH0pO1xuICB9XG5cbiAgYWJvcnRUcmFuc2FjdGlvbmFsU2Vzc2lvbigpIHtcbiAgICBpZiAoIXRoaXMuX3RyYW5zYWN0aW9uYWxTZXNzaW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZXJlIGlzIG5vIHRyYW5zYWN0aW9uYWwgc2Vzc2lvbiB0byBhYm9ydCcpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmFib3J0VHJhbnNhY3Rpb25hbFNlc3Npb24odGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb24pLnRoZW4oKCkgPT4ge1xuICAgICAgdGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb24gPSBudWxsO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gVE9ETzogY3JlYXRlIGluZGV4ZXMgb24gZmlyc3QgY3JlYXRpb24gb2YgYSBfVXNlciBvYmplY3QuIE90aGVyd2lzZSBpdCdzIGltcG9zc2libGUgdG9cbiAgLy8gaGF2ZSBhIFBhcnNlIGFwcCB3aXRob3V0IGl0IGhhdmluZyBhIF9Vc2VyIGNvbGxlY3Rpb24uXG4gIHBlcmZvcm1Jbml0aWFsaXphdGlvbigpIHtcbiAgICBjb25zdCByZXF1aXJlZFVzZXJGaWVsZHMgPSB7XG4gICAgICBmaWVsZHM6IHtcbiAgICAgICAgLi4uU2NoZW1hQ29udHJvbGxlci5kZWZhdWx0Q29sdW1ucy5fRGVmYXVsdCxcbiAgICAgICAgLi4uU2NoZW1hQ29udHJvbGxlci5kZWZhdWx0Q29sdW1ucy5fVXNlcixcbiAgICAgIH0sXG4gICAgfTtcbiAgICBjb25zdCByZXF1aXJlZFJvbGVGaWVsZHMgPSB7XG4gICAgICBmaWVsZHM6IHtcbiAgICAgICAgLi4uU2NoZW1hQ29udHJvbGxlci5kZWZhdWx0Q29sdW1ucy5fRGVmYXVsdCxcbiAgICAgICAgLi4uU2NoZW1hQ29udHJvbGxlci5kZWZhdWx0Q29sdW1ucy5fUm9sZSxcbiAgICAgIH0sXG4gICAgfTtcbiAgICBjb25zdCByZXF1aXJlZElkZW1wb3RlbmN5RmllbGRzID0ge1xuICAgICAgZmllbGRzOiB7XG4gICAgICAgIC4uLlNjaGVtYUNvbnRyb2xsZXIuZGVmYXVsdENvbHVtbnMuX0RlZmF1bHQsXG4gICAgICAgIC4uLlNjaGVtYUNvbnRyb2xsZXIuZGVmYXVsdENvbHVtbnMuX0lkZW1wb3RlbmN5LFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgY29uc3QgdXNlckNsYXNzUHJvbWlzZSA9IHRoaXMubG9hZFNjaGVtYSgpLnRoZW4oc2NoZW1hID0+IHNjaGVtYS5lbmZvcmNlQ2xhc3NFeGlzdHMoJ19Vc2VyJykpO1xuICAgIGNvbnN0IHJvbGVDbGFzc1Byb21pc2UgPSB0aGlzLmxvYWRTY2hlbWEoKS50aGVuKHNjaGVtYSA9PiBzY2hlbWEuZW5mb3JjZUNsYXNzRXhpc3RzKCdfUm9sZScpKTtcbiAgICBjb25zdCBpZGVtcG90ZW5jeUNsYXNzUHJvbWlzZSA9XG4gICAgICB0aGlzLmFkYXB0ZXIgaW5zdGFuY2VvZiBNb25nb1N0b3JhZ2VBZGFwdGVyXG4gICAgICAgID8gdGhpcy5sb2FkU2NoZW1hKCkudGhlbihzY2hlbWEgPT4gc2NoZW1hLmVuZm9yY2VDbGFzc0V4aXN0cygnX0lkZW1wb3RlbmN5JykpXG4gICAgICAgIDogUHJvbWlzZS5yZXNvbHZlKCk7XG5cbiAgICBjb25zdCB1c2VybmFtZVVuaXF1ZW5lc3MgPSB1c2VyQ2xhc3NQcm9taXNlXG4gICAgICAudGhlbigoKSA9PiB0aGlzLmFkYXB0ZXIuZW5zdXJlVW5pcXVlbmVzcygnX1VzZXInLCByZXF1aXJlZFVzZXJGaWVsZHMsIFsndXNlcm5hbWUnXSkpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBsb2dnZXIud2FybignVW5hYmxlIHRvIGVuc3VyZSB1bmlxdWVuZXNzIGZvciB1c2VybmFtZXM6ICcsIGVycm9yKTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcblxuICAgIGNvbnN0IHVzZXJuYW1lQ2FzZUluc2Vuc2l0aXZlSW5kZXggPSB1c2VyQ2xhc3NQcm9taXNlXG4gICAgICAudGhlbigoKSA9PlxuICAgICAgICB0aGlzLmFkYXB0ZXIuZW5zdXJlSW5kZXgoXG4gICAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAgICByZXF1aXJlZFVzZXJGaWVsZHMsXG4gICAgICAgICAgWyd1c2VybmFtZSddLFxuICAgICAgICAgICdjYXNlX2luc2Vuc2l0aXZlX3VzZXJuYW1lJyxcbiAgICAgICAgICB0cnVlXG4gICAgICAgIClcbiAgICAgIClcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdVbmFibGUgdG8gY3JlYXRlIGNhc2UgaW5zZW5zaXRpdmUgdXNlcm5hbWUgaW5kZXg6ICcsIGVycm9yKTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcblxuICAgIGNvbnN0IGVtYWlsVW5pcXVlbmVzcyA9IHVzZXJDbGFzc1Byb21pc2VcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuYWRhcHRlci5lbnN1cmVVbmlxdWVuZXNzKCdfVXNlcicsIHJlcXVpcmVkVXNlckZpZWxkcywgWydlbWFpbCddKSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdVbmFibGUgdG8gZW5zdXJlIHVuaXF1ZW5lc3MgZm9yIHVzZXIgZW1haWwgYWRkcmVzc2VzOiAnLCBlcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG5cbiAgICBjb25zdCBlbWFpbENhc2VJbnNlbnNpdGl2ZUluZGV4ID0gdXNlckNsYXNzUHJvbWlzZVxuICAgICAgLnRoZW4oKCkgPT5cbiAgICAgICAgdGhpcy5hZGFwdGVyLmVuc3VyZUluZGV4KFxuICAgICAgICAgICdfVXNlcicsXG4gICAgICAgICAgcmVxdWlyZWRVc2VyRmllbGRzLFxuICAgICAgICAgIFsnZW1haWwnXSxcbiAgICAgICAgICAnY2FzZV9pbnNlbnNpdGl2ZV9lbWFpbCcsXG4gICAgICAgICAgdHJ1ZVxuICAgICAgICApXG4gICAgICApXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBsb2dnZXIud2FybignVW5hYmxlIHRvIGNyZWF0ZSBjYXNlIGluc2Vuc2l0aXZlIGVtYWlsIGluZGV4OiAnLCBlcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG5cbiAgICBjb25zdCByb2xlVW5pcXVlbmVzcyA9IHJvbGVDbGFzc1Byb21pc2VcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuYWRhcHRlci5lbnN1cmVVbmlxdWVuZXNzKCdfUm9sZScsIHJlcXVpcmVkUm9sZUZpZWxkcywgWyduYW1lJ10pKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1VuYWJsZSB0byBlbnN1cmUgdW5pcXVlbmVzcyBmb3Igcm9sZSBuYW1lOiAnLCBlcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG5cbiAgICBjb25zdCBpZGVtcG90ZW5jeVJlcXVlc3RJZEluZGV4ID1cbiAgICAgIHRoaXMuYWRhcHRlciBpbnN0YW5jZW9mIE1vbmdvU3RvcmFnZUFkYXB0ZXJcbiAgICAgICAgPyBpZGVtcG90ZW5jeUNsYXNzUHJvbWlzZVxuICAgICAgICAgIC50aGVuKCgpID0+XG4gICAgICAgICAgICB0aGlzLmFkYXB0ZXIuZW5zdXJlVW5pcXVlbmVzcygnX0lkZW1wb3RlbmN5JywgcmVxdWlyZWRJZGVtcG90ZW5jeUZpZWxkcywgWydyZXFJZCddKVxuICAgICAgICAgIClcbiAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ1VuYWJsZSB0byBlbnN1cmUgdW5pcXVlbmVzcyBmb3IgaWRlbXBvdGVuY3kgcmVxdWVzdCBJRDogJywgZXJyb3IpO1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfSlcbiAgICAgICAgOiBQcm9taXNlLnJlc29sdmUoKTtcblxuICAgIGNvbnN0IGlkZW1wb3RlbmN5RXhwaXJlSW5kZXggPVxuICAgICAgdGhpcy5hZGFwdGVyIGluc3RhbmNlb2YgTW9uZ29TdG9yYWdlQWRhcHRlclxuICAgICAgICA/IGlkZW1wb3RlbmN5Q2xhc3NQcm9taXNlXG4gICAgICAgICAgLnRoZW4oKCkgPT5cbiAgICAgICAgICAgIHRoaXMuYWRhcHRlci5lbnN1cmVJbmRleChcbiAgICAgICAgICAgICAgJ19JZGVtcG90ZW5jeScsXG4gICAgICAgICAgICAgIHJlcXVpcmVkSWRlbXBvdGVuY3lGaWVsZHMsXG4gICAgICAgICAgICAgIFsnZXhwaXJlJ10sXG4gICAgICAgICAgICAgICd0dGwnLFxuICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgeyB0dGw6IDAgfVxuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ1VuYWJsZSB0byBjcmVhdGUgVFRMIGluZGV4IGZvciBpZGVtcG90ZW5jeSBleHBpcmUgZGF0ZTogJywgZXJyb3IpO1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfSlcbiAgICAgICAgOiBQcm9taXNlLnJlc29sdmUoKTtcblxuICAgIGNvbnN0IGluZGV4UHJvbWlzZSA9IHRoaXMuYWRhcHRlci51cGRhdGVTY2hlbWFXaXRoSW5kZXhlcygpO1xuXG4gICAgLy8gQ3JlYXRlIHRhYmxlcyBmb3Igdm9sYXRpbGUgY2xhc3Nlc1xuICAgIGNvbnN0IGFkYXB0ZXJJbml0ID0gdGhpcy5hZGFwdGVyLnBlcmZvcm1Jbml0aWFsaXphdGlvbih7XG4gICAgICBWb2xhdGlsZUNsYXNzZXNTY2hlbWFzOiBTY2hlbWFDb250cm9sbGVyLlZvbGF0aWxlQ2xhc3Nlc1NjaGVtYXMsXG4gICAgfSk7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKFtcbiAgICAgIHVzZXJuYW1lVW5pcXVlbmVzcyxcbiAgICAgIHVzZXJuYW1lQ2FzZUluc2Vuc2l0aXZlSW5kZXgsXG4gICAgICBlbWFpbFVuaXF1ZW5lc3MsXG4gICAgICBlbWFpbENhc2VJbnNlbnNpdGl2ZUluZGV4LFxuICAgICAgcm9sZVVuaXF1ZW5lc3MsXG4gICAgICBpZGVtcG90ZW5jeVJlcXVlc3RJZEluZGV4LFxuICAgICAgaWRlbXBvdGVuY3lFeHBpcmVJbmRleCxcbiAgICAgIGFkYXB0ZXJJbml0LFxuICAgICAgaW5kZXhQcm9taXNlLFxuICAgIF0pO1xuICB9XG5cbiAgc3RhdGljIF92YWxpZGF0ZVF1ZXJ5OiBhbnkgPT4gdm9pZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBEYXRhYmFzZUNvbnRyb2xsZXI7XG4vLyBFeHBvc2UgdmFsaWRhdGVRdWVyeSBmb3IgdGVzdHNcbm1vZHVsZS5leHBvcnRzLl92YWxpZGF0ZVF1ZXJ5ID0gdmFsaWRhdGVRdWVyeTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/FilesController.js b/lib/Controllers/FilesController.js new file mode 100644 index 0000000000..a5e3b29465 --- /dev/null +++ b/lib/Controllers/FilesController.js @@ -0,0 +1,136 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.FilesController = void 0; + +var _cryptoUtils = require("../cryptoUtils"); + +var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); + +var _FilesAdapter = require("../Adapters/Files/FilesAdapter"); + +var _path = _interopRequireDefault(require("path")); + +var _mime = _interopRequireDefault(require("mime")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// FilesController.js +const Parse = require('parse').Parse; + +const legacyFilesRegex = new RegExp('^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}-.*'); + +class FilesController extends _AdaptableController.default { + getFileData(config, filename) { + return this.adapter.getFileData(filename); + } + + createFile(config, filename, data, contentType, options) { + const extname = _path.default.extname(filename); + + const hasExtension = extname.length > 0; + + if (!hasExtension && contentType && _mime.default.getExtension(contentType)) { + filename = filename + '.' + _mime.default.getExtension(contentType); + } else if (hasExtension && !contentType) { + contentType = _mime.default.getType(filename); + } + + if (!this.options.preserveFileName) { + filename = (0, _cryptoUtils.randomHexString)(32) + '_' + filename; + } + + const location = this.adapter.getFileLocation(config, filename); + return this.adapter.createFile(filename, data, contentType, options).then(() => { + return Promise.resolve({ + url: location, + name: filename + }); + }); + } + + deleteFile(config, filename) { + return this.adapter.deleteFile(filename); + } + + getMetadata(filename) { + if (typeof this.adapter.getMetadata === 'function') { + return this.adapter.getMetadata(filename); + } + + return Promise.resolve({}); + } + /** + * Find file references in REST-format object and adds the url key + * with the current mount point and app id. + * Object may be a single object or list of REST-format objects. + */ + + + expandFilesInObject(config, object) { + if (object instanceof Array) { + object.map(obj => this.expandFilesInObject(config, obj)); + return; + } + + if (typeof object !== 'object') { + return; + } + + for (const key in object) { + const fileObject = object[key]; + + if (fileObject && fileObject['__type'] === 'File') { + if (fileObject['url']) { + continue; + } + + const filename = fileObject['name']; // all filenames starting with "tfss-" should be from files.parsetfss.com + // all filenames starting with a "-" seperated UUID should be from files.parse.com + // all other filenames have been migrated or created from Parse Server + + if (config.fileKey === undefined) { + fileObject['url'] = this.adapter.getFileLocation(config, filename); + } else { + if (filename.indexOf('tfss-') === 0) { + fileObject['url'] = 'http://files.parsetfss.com/' + config.fileKey + '/' + encodeURIComponent(filename); + } else if (legacyFilesRegex.test(filename)) { + fileObject['url'] = 'http://files.parse.com/' + config.fileKey + '/' + encodeURIComponent(filename); + } else { + fileObject['url'] = this.adapter.getFileLocation(config, filename); + } + } + } + } + } + + expectedAdapterType() { + return _FilesAdapter.FilesAdapter; + } + + handleFileStream(config, filename, req, res, contentType) { + return this.adapter.handleFileStream(filename, req, res, contentType); + } + + validateFilename(filename) { + if (typeof this.adapter.validateFilename === 'function') { + const error = this.adapter.validateFilename(filename); + + if (typeof error !== 'string') { + return error; + } + + return new Parse.Error(Parse.Error.INVALID_FILE_NAME, error); + } + + return (0, _FilesAdapter.validateFilename)(filename); + } + +} + +exports.FilesController = FilesController; +var _default = FilesController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9GaWxlc0NvbnRyb2xsZXIuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwibGVnYWN5RmlsZXNSZWdleCIsIlJlZ0V4cCIsIkZpbGVzQ29udHJvbGxlciIsIkFkYXB0YWJsZUNvbnRyb2xsZXIiLCJnZXRGaWxlRGF0YSIsImNvbmZpZyIsImZpbGVuYW1lIiwiYWRhcHRlciIsImNyZWF0ZUZpbGUiLCJkYXRhIiwiY29udGVudFR5cGUiLCJvcHRpb25zIiwiZXh0bmFtZSIsInBhdGgiLCJoYXNFeHRlbnNpb24iLCJsZW5ndGgiLCJtaW1lIiwiZ2V0RXh0ZW5zaW9uIiwiZ2V0VHlwZSIsInByZXNlcnZlRmlsZU5hbWUiLCJsb2NhdGlvbiIsImdldEZpbGVMb2NhdGlvbiIsInRoZW4iLCJQcm9taXNlIiwicmVzb2x2ZSIsInVybCIsIm5hbWUiLCJkZWxldGVGaWxlIiwiZ2V0TWV0YWRhdGEiLCJleHBhbmRGaWxlc0luT2JqZWN0Iiwib2JqZWN0IiwiQXJyYXkiLCJtYXAiLCJvYmoiLCJrZXkiLCJmaWxlT2JqZWN0IiwiZmlsZUtleSIsInVuZGVmaW5lZCIsImluZGV4T2YiLCJlbmNvZGVVUklDb21wb25lbnQiLCJ0ZXN0IiwiZXhwZWN0ZWRBZGFwdGVyVHlwZSIsIkZpbGVzQWRhcHRlciIsImhhbmRsZUZpbGVTdHJlYW0iLCJyZXEiLCJyZXMiLCJ2YWxpZGF0ZUZpbGVuYW1lIiwiZXJyb3IiLCJFcnJvciIsIklOVkFMSURfRklMRV9OQU1FIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFMQTtBQU1BLE1BQU1BLEtBQUssR0FBR0MsT0FBTyxDQUFDLE9BQUQsQ0FBUCxDQUFpQkQsS0FBL0I7O0FBRUEsTUFBTUUsZ0JBQWdCLEdBQUcsSUFBSUMsTUFBSixDQUN2QixpRkFEdUIsQ0FBekI7O0FBSU8sTUFBTUMsZUFBTixTQUE4QkMsNEJBQTlCLENBQWtEO0FBQ3ZE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QUFDeEMsUUFBRCxFQUFXO0FBQ3pCLFFBQUksT0FBTyxLQUFLQyxPQUFMLENBQWF1QyxnQkFBcEIsS0FBeUMsVUFBN0MsRUFBeUQ7QUFDdkQsWUFBTUMsS0FBSyxHQUFHLEtBQUt4QyxPQUFMLENBQWF1QyxnQkFBYixDQUE4QnhDLFFBQTlCLENBQWQ7O0FBQ0EsVUFBSSxPQUFPeUMsS0FBUCxLQUFpQixRQUFyQixFQUErQjtBQUM3QixlQUFPQSxLQUFQO0FBQ0Q7O0FBQ0QsYUFBTyxJQUFJakQsS0FBSyxDQUFDa0QsS0FBVixDQUFnQmxELEtBQUssQ0FBQ2tELEtBQU4sQ0FBWUMsaUJBQTVCLEVBQStDRixLQUEvQyxDQUFQO0FBQ0Q7O0FBQ0QsV0FBTyxvQ0FBaUJ6QyxRQUFqQixDQUFQO0FBQ0Q7O0FBakdzRDs7O2VBb0cxQ0osZSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEZpbGVzQ29udHJvbGxlci5qc1xuaW1wb3J0IHsgcmFuZG9tSGV4U3RyaW5nIH0gZnJvbSAnLi4vY3J5cHRvVXRpbHMnO1xuaW1wb3J0IEFkYXB0YWJsZUNvbnRyb2xsZXIgZnJvbSAnLi9BZGFwdGFibGVDb250cm9sbGVyJztcbmltcG9ydCB7IHZhbGlkYXRlRmlsZW5hbWUsIEZpbGVzQWRhcHRlciB9IGZyb20gJy4uL0FkYXB0ZXJzL0ZpbGVzL0ZpbGVzQWRhcHRlcic7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCBtaW1lIGZyb20gJ21pbWUnO1xuY29uc3QgUGFyc2UgPSByZXF1aXJlKCdwYXJzZScpLlBhcnNlO1xuXG5jb25zdCBsZWdhY3lGaWxlc1JlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgJ15bMC05YS1mQS1GXXs4fS1bMC05YS1mQS1GXXs0fS1bMC05YS1mQS1GXXs0fS1bMC05YS1mQS1GXXs0fS1bMC05YS1mQS1GXXsxMn0tLionXG4pO1xuXG5leHBvcnQgY2xhc3MgRmlsZXNDb250cm9sbGVyIGV4dGVuZHMgQWRhcHRhYmxlQ29udHJvbGxlciB7XG4gIGdldEZpbGVEYXRhKGNvbmZpZywgZmlsZW5hbWUpIHtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmdldEZpbGVEYXRhKGZpbGVuYW1lKTtcbiAgfVxuXG4gIGNyZWF0ZUZpbGUoY29uZmlnLCBmaWxlbmFtZSwgZGF0YSwgY29udGVudFR5cGUsIG9wdGlvbnMpIHtcbiAgICBjb25zdCBleHRuYW1lID0gcGF0aC5leHRuYW1lKGZpbGVuYW1lKTtcblxuICAgIGNvbnN0IGhhc0V4dGVuc2lvbiA9IGV4dG5hbWUubGVuZ3RoID4gMDtcblxuICAgIGlmICghaGFzRXh0ZW5zaW9uICYmIGNvbnRlbnRUeXBlICYmIG1pbWUuZ2V0RXh0ZW5zaW9uKGNvbnRlbnRUeXBlKSkge1xuICAgICAgZmlsZW5hbWUgPSBmaWxlbmFtZSArICcuJyArIG1pbWUuZ2V0RXh0ZW5zaW9uKGNvbnRlbnRUeXBlKTtcbiAgICB9IGVsc2UgaWYgKGhhc0V4dGVuc2lvbiAmJiAhY29udGVudFR5cGUpIHtcbiAgICAgIGNvbnRlbnRUeXBlID0gbWltZS5nZXRUeXBlKGZpbGVuYW1lKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMub3B0aW9ucy5wcmVzZXJ2ZUZpbGVOYW1lKSB7XG4gICAgICBmaWxlbmFtZSA9IHJhbmRvbUhleFN0cmluZygzMikgKyAnXycgKyBmaWxlbmFtZTtcbiAgICB9XG5cbiAgICBjb25zdCBsb2NhdGlvbiA9IHRoaXMuYWRhcHRlci5nZXRGaWxlTG9jYXRpb24oY29uZmlnLCBmaWxlbmFtZSk7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5jcmVhdGVGaWxlKGZpbGVuYW1lLCBkYXRhLCBjb250ZW50VHlwZSwgb3B0aW9ucykudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgdXJsOiBsb2NhdGlvbixcbiAgICAgICAgbmFtZTogZmlsZW5hbWUsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGRlbGV0ZUZpbGUoY29uZmlnLCBmaWxlbmFtZSkge1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuZGVsZXRlRmlsZShmaWxlbmFtZSk7XG4gIH1cblxuICBnZXRNZXRhZGF0YShmaWxlbmFtZSkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5hZGFwdGVyLmdldE1ldGFkYXRhID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmdldE1ldGFkYXRhKGZpbGVuYW1lKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gIH1cblxuICAvKipcbiAgICogRmluZCBmaWxlIHJlZmVyZW5jZXMgaW4gUkVTVC1mb3JtYXQgb2JqZWN0IGFuZCBhZGRzIHRoZSB1cmwga2V5XG4gICAqIHdpdGggdGhlIGN1cnJlbnQgbW91bnQgcG9pbnQgYW5kIGFwcCBpZC5cbiAgICogT2JqZWN0IG1heSBiZSBhIHNpbmdsZSBvYmplY3Qgb3IgbGlzdCBvZiBSRVNULWZvcm1hdCBvYmplY3RzLlxuICAgKi9cbiAgZXhwYW5kRmlsZXNJbk9iamVjdChjb25maWcsIG9iamVjdCkge1xuICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgb2JqZWN0Lm1hcChvYmogPT4gdGhpcy5leHBhbmRGaWxlc0luT2JqZWN0KGNvbmZpZywgb2JqKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqZWN0ICE9PSAnb2JqZWN0Jykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGtleSBpbiBvYmplY3QpIHtcbiAgICAgIGNvbnN0IGZpbGVPYmplY3QgPSBvYmplY3Rba2V5XTtcbiAgICAgIGlmIChmaWxlT2JqZWN0ICYmIGZpbGVPYmplY3RbJ19fdHlwZSddID09PSAnRmlsZScpIHtcbiAgICAgICAgaWYgKGZpbGVPYmplY3RbJ3VybCddKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZmlsZW5hbWUgPSBmaWxlT2JqZWN0WyduYW1lJ107XG4gICAgICAgIC8vIGFsbCBmaWxlbmFtZXMgc3RhcnRpbmcgd2l0aCBcInRmc3MtXCIgc2hvdWxkIGJlIGZyb20gZmlsZXMucGFyc2V0ZnNzLmNvbVxuICAgICAgICAvLyBhbGwgZmlsZW5hbWVzIHN0YXJ0aW5nIHdpdGggYSBcIi1cIiBzZXBlcmF0ZWQgVVVJRCBzaG91bGQgYmUgZnJvbSBmaWxlcy5wYXJzZS5jb21cbiAgICAgICAgLy8gYWxsIG90aGVyIGZpbGVuYW1lcyBoYXZlIGJlZW4gbWlncmF0ZWQgb3IgY3JlYXRlZCBmcm9tIFBhcnNlIFNlcnZlclxuICAgICAgICBpZiAoY29uZmlnLmZpbGVLZXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGZpbGVPYmplY3RbJ3VybCddID0gdGhpcy5hZGFwdGVyLmdldEZpbGVMb2NhdGlvbihjb25maWcsIGZpbGVuYW1lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoZmlsZW5hbWUuaW5kZXhPZigndGZzcy0nKSA9PT0gMCkge1xuICAgICAgICAgICAgZmlsZU9iamVjdFsndXJsJ10gPVxuICAgICAgICAgICAgICAnaHR0cDovL2ZpbGVzLnBhcnNldGZzcy5jb20vJyArIGNvbmZpZy5maWxlS2V5ICsgJy8nICsgZW5jb2RlVVJJQ29tcG9uZW50KGZpbGVuYW1lKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGxlZ2FjeUZpbGVzUmVnZXgudGVzdChmaWxlbmFtZSkpIHtcbiAgICAgICAgICAgIGZpbGVPYmplY3RbJ3VybCddID1cbiAgICAgICAgICAgICAgJ2h0dHA6Ly9maWxlcy5wYXJzZS5jb20vJyArIGNvbmZpZy5maWxlS2V5ICsgJy8nICsgZW5jb2RlVVJJQ29tcG9uZW50KGZpbGVuYW1lKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZmlsZU9iamVjdFsndXJsJ10gPSB0aGlzLmFkYXB0ZXIuZ2V0RmlsZUxvY2F0aW9uKGNvbmZpZywgZmlsZW5hbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGV4cGVjdGVkQWRhcHRlclR5cGUoKSB7XG4gICAgcmV0dXJuIEZpbGVzQWRhcHRlcjtcbiAgfVxuXG4gIGhhbmRsZUZpbGVTdHJlYW0oY29uZmlnLCBmaWxlbmFtZSwgcmVxLCByZXMsIGNvbnRlbnRUeXBlKSB7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5oYW5kbGVGaWxlU3RyZWFtKGZpbGVuYW1lLCByZXEsIHJlcywgY29udGVudFR5cGUpO1xuICB9XG5cbiAgdmFsaWRhdGVGaWxlbmFtZShmaWxlbmFtZSkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5hZGFwdGVyLnZhbGlkYXRlRmlsZW5hbWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGNvbnN0IGVycm9yID0gdGhpcy5hZGFwdGVyLnZhbGlkYXRlRmlsZW5hbWUoZmlsZW5hbWUpO1xuICAgICAgaWYgKHR5cGVvZiBlcnJvciAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0ZJTEVfTkFNRSwgZXJyb3IpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsaWRhdGVGaWxlbmFtZShmaWxlbmFtZSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRmlsZXNDb250cm9sbGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/HooksController.js b/lib/Controllers/HooksController.js new file mode 100644 index 0000000000..cec8c49e9e --- /dev/null +++ b/lib/Controllers/HooksController.js @@ -0,0 +1,302 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.HooksController = void 0; + +var triggers = _interopRequireWildcard(require("../triggers")); + +var Parse = _interopRequireWildcard(require("parse/node")); + +var _request = _interopRequireDefault(require("../request")); + +var _logger = require("../logger"); + +var _http = _interopRequireDefault(require("http")); + +var _https = _interopRequireDefault(require("https")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +// -disable-next +// -disable-next +const DefaultHooksCollectionName = '_Hooks'; +const HTTPAgents = { + http: new _http.default.Agent({ + keepAlive: true + }), + https: new _https.default.Agent({ + keepAlive: true + }) +}; + +class HooksController { + constructor(applicationId, databaseController, webhookKey) { + this._applicationId = applicationId; + this._webhookKey = webhookKey; + this.database = databaseController; + } + + load() { + return this._getHooks().then(hooks => { + hooks = hooks || []; + hooks.forEach(hook => { + this.addHookToTriggers(hook); + }); + }); + } + + getFunction(functionName) { + return this._getHooks({ + functionName: functionName + }).then(results => results[0]); + } + + getFunctions() { + return this._getHooks({ + functionName: { + $exists: true + } + }); + } + + getTrigger(className, triggerName) { + return this._getHooks({ + className: className, + triggerName: triggerName + }).then(results => results[0]); + } + + getTriggers() { + return this._getHooks({ + className: { + $exists: true + }, + triggerName: { + $exists: true + } + }); + } + + deleteFunction(functionName) { + triggers.removeFunction(functionName, this._applicationId); + return this._removeHooks({ + functionName: functionName + }); + } + + deleteTrigger(className, triggerName) { + triggers.removeTrigger(triggerName, className, this._applicationId); + return this._removeHooks({ + className: className, + triggerName: triggerName + }); + } + + _getHooks(query = {}) { + return this.database.find(DefaultHooksCollectionName, query).then(results => { + return results.map(result => { + delete result.objectId; + return result; + }); + }); + } + + _removeHooks(query) { + return this.database.destroy(DefaultHooksCollectionName, query).then(() => { + return Promise.resolve({}); + }); + } + + saveHook(hook) { + var query; + + if (hook.functionName && hook.url) { + query = { + functionName: hook.functionName + }; + } else if (hook.triggerName && hook.className && hook.url) { + query = { + className: hook.className, + triggerName: hook.triggerName + }; + } else { + throw new Parse.Error(143, 'invalid hook declaration'); + } + + return this.database.update(DefaultHooksCollectionName, query, hook, { + upsert: true + }).then(() => { + return Promise.resolve(hook); + }); + } + + addHookToTriggers(hook) { + var wrappedFunction = wrapToHTTPRequest(hook, this._webhookKey); + wrappedFunction.url = hook.url; + + if (hook.className) { + triggers.addTrigger(hook.triggerName, hook.className, wrappedFunction, this._applicationId); + } else { + triggers.addFunction(hook.functionName, wrappedFunction, null, this._applicationId); + } + } + + addHook(hook) { + this.addHookToTriggers(hook); + return this.saveHook(hook); + } + + createOrUpdateHook(aHook) { + var hook; + + if (aHook && aHook.functionName && aHook.url) { + hook = {}; + hook.functionName = aHook.functionName; + hook.url = aHook.url; + } else if (aHook && aHook.className && aHook.url && aHook.triggerName && triggers.Types[aHook.triggerName]) { + hook = {}; + hook.className = aHook.className; + hook.url = aHook.url; + hook.triggerName = aHook.triggerName; + } else { + throw new Parse.Error(143, 'invalid hook declaration'); + } + + return this.addHook(hook); + } + + createHook(aHook) { + if (aHook.functionName) { + return this.getFunction(aHook.functionName).then(result => { + if (result) { + throw new Parse.Error(143, `function name: ${aHook.functionName} already exits`); + } else { + return this.createOrUpdateHook(aHook); + } + }); + } else if (aHook.className && aHook.triggerName) { + return this.getTrigger(aHook.className, aHook.triggerName).then(result => { + if (result) { + throw new Parse.Error(143, `class ${aHook.className} already has trigger ${aHook.triggerName}`); + } + + return this.createOrUpdateHook(aHook); + }); + } + + throw new Parse.Error(143, 'invalid hook declaration'); + } + + updateHook(aHook) { + if (aHook.functionName) { + return this.getFunction(aHook.functionName).then(result => { + if (result) { + return this.createOrUpdateHook(aHook); + } + + throw new Parse.Error(143, `no function named: ${aHook.functionName} is defined`); + }); + } else if (aHook.className && aHook.triggerName) { + return this.getTrigger(aHook.className, aHook.triggerName).then(result => { + if (result) { + return this.createOrUpdateHook(aHook); + } + + throw new Parse.Error(143, `class ${aHook.className} does not exist`); + }); + } + + throw new Parse.Error(143, 'invalid hook declaration'); + } + +} + +exports.HooksController = HooksController; + +function wrapToHTTPRequest(hook, key) { + return req => { + const jsonBody = {}; + + for (var i in req) { + jsonBody[i] = req[i]; + } + + if (req.object) { + jsonBody.object = req.object.toJSON(); + jsonBody.object.className = req.object.className; + } + + if (req.original) { + jsonBody.original = req.original.toJSON(); + jsonBody.original.className = req.original.className; + } + + const jsonRequest = { + url: hook.url, + headers: { + 'Content-Type': 'application/json' + }, + body: jsonBody, + method: 'POST' + }; + const agent = hook.url.startsWith('https') ? HTTPAgents['https'] : HTTPAgents['http']; + jsonRequest.agent = agent; + + if (key) { + jsonRequest.headers['X-Parse-Webhook-Key'] = key; + } else { + _logger.logger.warn('Making outgoing webhook request without webhookKey being set!'); + } + + return (0, _request.default)(jsonRequest).then(response => { + let err; + let result; + let body = response.data; + + if (body) { + if (typeof body === 'string') { + try { + body = JSON.parse(body); + } catch (e) { + err = { + error: 'Malformed response', + code: -1, + partialResponse: body.substring(0, 100) + }; + } + } + + if (!err) { + result = body.success; + err = body.error; + } + } + + if (err) { + throw err; + } else if (hook.triggerName === 'beforeSave') { + if (typeof result === 'object') { + delete result.createdAt; + delete result.updatedAt; + delete result.className; + } + + return { + object: result + }; + } else { + return result; + } + }); + }; +} + +var _default = HooksController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9Ib29rc0NvbnRyb2xsZXIuanMiXSwibmFtZXMiOlsiRGVmYXVsdEhvb2tzQ29sbGVjdGlvbk5hbWUiLCJIVFRQQWdlbnRzIiwiaHR0cCIsIkFnZW50Iiwia2VlcEFsaXZlIiwiaHR0cHMiLCJIb29rc0NvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImFwcGxpY2F0aW9uSWQiLCJkYXRhYmFzZUNvbnRyb2xsZXIiLCJ3ZWJob29rS2V5IiwiX2FwcGxpY2F0aW9uSWQiLCJfd2ViaG9va0tleSIsImRhdGFiYXNlIiwibG9hZCIsIl9nZXRIb29rcyIsInRoZW4iLCJob29rcyIsImZvckVhY2giLCJob29rIiwiYWRkSG9va1RvVHJpZ2dlcnMiLCJnZXRGdW5jdGlvbiIsImZ1bmN0aW9uTmFtZSIsInJlc3VsdHMiLCJnZXRGdW5jdGlvbnMiLCIkZXhpc3RzIiwiZ2V0VHJpZ2dlciIsImNsYXNzTmFtZSIsInRyaWdnZXJOYW1lIiwiZ2V0VHJpZ2dlcnMiLCJkZWxldGVGdW5jdGlvbiIsInRyaWdnZXJzIiwicmVtb3ZlRnVuY3Rpb24iLCJfcmVtb3ZlSG9va3MiLCJkZWxldGVUcmlnZ2VyIiwicmVtb3ZlVHJpZ2dlciIsInF1ZXJ5IiwiZmluZCIsIm1hcCIsInJlc3VsdCIsIm9iamVjdElkIiwiZGVzdHJveSIsIlByb21pc2UiLCJyZXNvbHZlIiwic2F2ZUhvb2siLCJ1cmwiLCJQYXJzZSIsIkVycm9yIiwidXBkYXRlIiwidXBzZXJ0Iiwid3JhcHBlZEZ1bmN0aW9uIiwid3JhcFRvSFRUUFJlcXVlc3QiLCJhZGRUcmlnZ2VyIiwiYWRkRnVuY3Rpb24iLCJhZGRIb29rIiwiY3JlYXRlT3JVcGRhdGVIb29rIiwiYUhvb2siLCJUeXBlcyIsImNyZWF0ZUhvb2siLCJ1cGRhdGVIb29rIiwia2V5IiwicmVxIiwianNvbkJvZHkiLCJpIiwib2JqZWN0IiwidG9KU09OIiwib3JpZ2luYWwiLCJqc29uUmVxdWVzdCIsImhlYWRlcnMiLCJib2R5IiwibWV0aG9kIiwiYWdlbnQiLCJzdGFydHNXaXRoIiwibG9nZ2VyIiwid2FybiIsInJlc3BvbnNlIiwiZXJyIiwiZGF0YSIsIkpTT04iLCJwYXJzZSIsImUiLCJlcnJvciIsImNvZGUiLCJwYXJ0aWFsUmVzcG9uc2UiLCJzdWJzdHJpbmciLCJzdWNjZXNzIiwiY3JlYXRlZEF0IiwidXBkYXRlZEF0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBRUE7O0FBRUE7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBTkE7QUFFQTtBQU1BLE1BQU1BLDBCQUEwQixHQUFHLFFBQW5DO0FBQ0EsTUFBTUMsVUFBVSxHQUFHO0FBQ2pCQyxFQUFBQSxJQUFJLEVBQUUsSUFBSUEsY0FBS0MsS0FBVCxDQUFlO0FBQUVDLElBQUFBLFNBQVMsRUFBRTtBQUFiLEdBQWYsQ0FEVztBQUVqQkMsRUFBQUEsS0FBSyxFQUFFLElBQUlBLGVBQU1GLEtBQVYsQ0FBZ0I7QUFBRUMsSUFBQUEsU0FBUyxFQUFFO0FBQWIsR0FBaEI7QUFGVSxDQUFuQjs7QUFLTyxNQUFNRSxlQUFOLENBQXNCO0FBSzNCQyxFQUFBQSxXQUFXLENBQUNDLGFBQUQsRUFBd0JDLGtCQUF4QixFQUE0Q0MsVUFBNUMsRUFBd0Q7QUFDakUsU0FBS0MsY0FBTCxHQUFzQkgsYUFBdEI7QUFDQSxTQUFLSSxXQUFMLEdBQW1CRixVQUFuQjtBQUNBLFNBQUtHLFFBQUwsR0FBZ0JKLGtCQUFoQjtBQUNEOztBQUVESyxFQUFBQSxJQUFJLEdBQUc7QUFDTCxXQUFPLEtBQUtDLFNBQUwsR0FBaUJDLElBQWpCLENBQXNCQyxLQUFLLElBQUk7QUFDcENBLE1BQUFBLEtBQUssR0FBR0EsS0FBSyxJQUFJLEVBQWpCO0FBQ0FBLE1BQUFBLEtBQUssQ0FBQ0MsT0FBTixDQUFjQyxJQUFJLElBQUk7QUFDcEIsYUFBS0MsaUJBQUwsQ0FBdUJELElBQXZCO0FBQ0QsT0FGRDtBQUdELEtBTE0sQ0FBUDtBQU1EOztBQUVERSxFQUFBQSxXQUFXLENBQUNDLFlBQUQsRUFBZTtB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RUpDLGNBQUFBLElBQUksRUFBRSxDQUFDLENBRkg7QUFHSkMsY0FBQUEsZUFBZSxFQUFFZCxJQUFJLENBQUNlLFNBQUwsQ0FBZSxDQUFmLEVBQWtCLEdBQWxCO0FBSGIsYUFBTjtBQUtEO0FBQ0Y7O0FBQ0QsWUFBSSxDQUFDUixHQUFMLEVBQVU7QUFDUnJDLFVBQUFBLE1BQU0sR0FBRzhCLElBQUksQ0FBQ2dCLE9BQWQ7QUFDQVQsVUFBQUEsR0FBRyxHQUFHUCxJQUFJLENBQUNZLEtBQVg7QUFDRDtBQUNGOztBQUNELFVBQUlMLEdBQUosRUFBUztBQUNQLGNBQU1BLEdBQU47QUFDRCxPQUZELE1BRU8sSUFBSXpELElBQUksQ0FBQ1MsV0FBTCxLQUFxQixZQUF6QixFQUF1QztBQUM1QyxZQUFJLE9BQU9XLE1BQVAsS0FBa0IsUUFBdEIsRUFBZ0M7QUFDOUIsaUJBQU9BLE1BQU0sQ0FBQytDLFNBQWQ7QUFDQSxpQkFBTy9DLE1BQU0sQ0FBQ2dELFNBQWQ7QUFDQSxpQkFBT2hELE1BQU0sQ0FBQ1osU0FBZDtBQUNEOztBQUNELGVBQU87QUFBRXFDLFVBQUFBLE1BQU0sRUFBRXpCO0FBQVYsU0FBUDtBQUNELE9BUE0sTUFPQTtBQUNMLGVBQU9BLE1BQVA7QUFDRDtBQUNGLEtBakNNLENBQVA7QUFrQ0QsR0FoRUQ7QUFpRUQ7O2VBRWNqQyxlIiwic291cmNlc0NvbnRlbnQiOlsiLyoqIEBmbG93IHdlYWsgKi9cblxuaW1wb3J0ICogYXMgdHJpZ2dlcnMgZnJvbSAnLi4vdHJpZ2dlcnMnO1xuLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG5pbXBvcnQgKiBhcyBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuaW1wb3J0IHJlcXVlc3QgZnJvbSAnLi4vcmVxdWVzdCc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi9sb2dnZXInO1xuaW1wb3J0IGh0dHAgZnJvbSAnaHR0cCc7XG5pbXBvcnQgaHR0cHMgZnJvbSAnaHR0cHMnO1xuXG5jb25zdCBEZWZhdWx0SG9va3NDb2xsZWN0aW9uTmFtZSA9ICdfSG9va3MnO1xuY29uc3QgSFRUUEFnZW50cyA9IHtcbiAgaHR0cDogbmV3IGh0dHAuQWdlbnQoeyBrZWVwQWxpdmU6IHRydWUgfSksXG4gIGh0dHBzOiBuZXcgaHR0cHMuQWdlbnQoeyBrZWVwQWxpdmU6IHRydWUgfSksXG59O1xuXG5leHBvcnQgY2xhc3MgSG9va3NDb250cm9sbGVyIHtcbiAgX2FwcGxpY2F0aW9uSWQ6IHN0cmluZztcbiAgX3dlYmhvb2tLZXk6IHN0cmluZztcbiAgZGF0YWJhc2U6IGFueTtcblxuICBjb25zdHJ1Y3RvcihhcHBsaWNhdGlvbklkOiBzdHJpbmcsIGRhdGFiYXNlQ29udHJvbGxlciwgd2ViaG9va0tleSkge1xuICAgIHRoaXMuX2FwcGxpY2F0aW9uSWQgPSBhcHBsaWNhdGlvbklkO1xuICAgIHRoaXMuX3dlYmhvb2tLZXkgPSB3ZWJob29rS2V5O1xuICAgIHRoaXMuZGF0YWJhc2UgPSBkYXRhYmFzZUNvbnRyb2xsZXI7XG4gIH1cblxuICBsb2FkKCkge1xuICAgIHJldHVybiB0aGlzLl9nZXRIb29rcygpLnRoZW4oaG9va3MgPT4ge1xuICAgICAgaG9va3MgPSBob29rcyB8fCBbXTtcbiAgICAgIGhvb2tzLmZvckVhY2goaG9vayA9PiB7XG4gICAgICAgIHRoaXMuYWRkSG9va1RvVHJpZ2dlcnMoaG9vayk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldEZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSkge1xuICAgIHJldHVybiB0aGlzLl9nZXRIb29rcyh7IGZ1bmN0aW9uTmFtZTogZnVuY3Rpb25OYW1lIH0pLnRoZW4ocmVzdWx0cyA9PiByZXN1bHRzWzBdKTtcbiAgfVxuXG4gIGdldEZ1bmN0aW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0SG9va3MoeyBmdW5jdGlvbk5hbWU6IHsgJGV4aXN0czogdHJ1ZSB9IH0pO1xuICB9XG5cbiAgZ2V0VHJpZ2dlcihjbGFzc05hbWUsIHRyaWdnZXJOYW1lKSB7XG4gICAgcmV0dXJuIHRoaXMuX2dldEhvb2tzKHtcbiAgICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lLFxuICAgICAgdHJpZ2dlck5hbWU6IHRyaWdnZXJOYW1lLFxuICAgIH0pLnRoZW4ocmVzdWx0cyA9PiByZXN1bHRzWzBdKTtcbiAgfVxuXG4gIGdldFRyaWdnZXJzKCkge1xuICAgIHJldHVybiB0aGlzLl9nZXRIb29rcyh7XG4gICAgICBjbGFzc05hbWU6IHsgJGV4aXN0czogdHJ1ZSB9LFxuICAgICAgdHJpZ2dlck5hbWU6IHsgJGV4aXN0czogdHJ1ZSB9LFxuICAgIH0pO1xuICB9XG5cbiAgZGVsZXRlRnVuY3Rpb24oZnVuY3Rpb25OYW1lKSB7XG4gICAgdHJpZ2dlcnMucmVtb3ZlRnVuY3Rpb24oZnVuY3Rpb25OYW1lLCB0aGlzLl9hcHBsaWNhdGlvbklkKTtcbiAgICByZXR1cm4gdGhpcy5fcmVtb3ZlSG9va3MoeyBmdW5jdGlvbk5hbWU6IGZ1bmN0aW9uTmFtZSB9KTtcbiAgfVxuXG4gIGRlbGV0ZVRyaWdnZXIoY2xhc3NOYW1lLCB0cmlnZ2VyTmFtZSkge1xuICAgIHRyaWdnZXJzLnJlbW92ZVRyaWdnZXIodHJpZ2dlck5hbWUsIGNsYXNzTmFtZSwgdGhpcy5fYXBwbGljYXRpb25JZCk7XG4gICAgcmV0dXJuIHRoaXMuX3JlbW92ZUhvb2tzKHtcbiAgICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lLFxuICAgICAgdHJpZ2dlck5hbWU6IHRyaWdnZXJOYW1lLFxuICAgIH0pO1xuICB9XG5cbiAgX2dldEhvb2tzKHF1ZXJ5ID0ge30pIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhYmFzZS5maW5kKERlZmF1bHRIb29rc0NvbGxlY3Rpb25OYW1lLCBxdWVyeSkudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIHJldHVybiByZXN1bHRzLm1hcChyZXN1bHQgPT4ge1xuICAgICAgICBkZWxldGUgcmVzdWx0Lm9iamVjdElkO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBfcmVtb3ZlSG9va3MocXVlcnkpIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhYmFzZS5kZXN0cm95KERlZmF1bHRIb29rc0NvbGxlY3Rpb25OYW1lLCBxdWVyeSkudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHNhdmVIb29rKGhvb2spIHtcbiAgICB2YXIgcXVlcnk7XG4gICAgaWYgKGhvb2suZnVuY3Rpb25OYW1lICYmIGhvb2sudXJsKSB7XG4gICAgICBxdWVyeSA9IHsgZnVuY3Rpb25OYW1lOiBob29rLmZ1bmN0aW9uTmFtZSB9O1xuICAgIH0gZWxzZSBpZiAoaG9vay50cmlnZ2VyTmFtZSAmJiBob29rLmNsYXNzTmFtZSAmJiBob29rLnVybCkge1xuICAgICAgcXVlcnkgPSB7IGNsYXNzTmFtZTogaG9vay5jbGFzc05hbWUsIHRyaWdnZXJOYW1lOiBob29rLnRyaWdnZXJOYW1lIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigxNDMsICdpbnZhbGlkIGhvb2sgZGVjbGFyYXRpb24nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZGF0YWJhc2VcbiAgICAgIC51cGRhdGUoRGVmYXVsdEhvb2tzQ29sbGVjdGlvbk5hbWUsIHF1ZXJ5LCBob29rLCB7IHVwc2VydDogdHJ1ZSB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGhvb2spO1xuICAgICAgfSk7XG4gIH1cblxuICBhZGRIb29rVG9UcmlnZ2Vycyhob29rKSB7XG4gICAgdmFyIHdyYXBwZWRGdW5jdGlvbiA9IHdyYXBUb0hUVFBSZXF1ZXN0KGhvb2ssIHRoaXMuX3dlYmhvb2tLZXkpO1xuICAgIHdyYXBwZWRGdW5jdGlvbi51cmwgPSBob29rLnVybDtcbiAgICBpZiAoaG9vay5jbGFzc05hbWUpIHtcbiAgICAgIHRyaWdnZXJzLmFkZFRyaWdnZXIoaG9vay50cmlnZ2VyTmFtZSwgaG9vay5jbGFzc05hbWUsIHdyYXBwZWRGdW5jdGlvbiwgdGhpcy5fYXBwbGljYXRpb25JZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRyaWdnZXJzLmFkZEZ1bmN0aW9uKGhvb2suZnVuY3Rpb25OYW1lLCB3cmFwcGVkRnVuY3Rpb24sIG51bGwsIHRoaXMuX2FwcGxpY2F0aW9uSWQpO1xuICAgIH1cbiAgfVxuXG4gIGFkZEhvb2soaG9vaykge1xuICAgIHRoaXMuYWRkSG9va1RvVHJpZ2dlcnMoaG9vayk7XG4gICAgcmV0dXJuIHRoaXMuc2F2ZUhvb2soaG9vayk7XG4gIH1cblxuICBjcmVhdGVPclVwZGF0ZUhvb2soYUhvb2spIHtcbiAgICB2YXIgaG9vaztcbiAgICBpZiAoYUhvb2sgJiYgYUhvb2suZnVuY3Rpb25OYW1lICYmIGFIb29rLnVybCkge1xuICAgICAgaG9vayA9IHt9O1xuICAgICAgaG9vay5mdW5jdGlvbk5hbWUgPSBhSG9vay5mdW5jdGlvbk5hbWU7XG4gICAgICBob29rLnVybCA9IGFIb29rLnVybDtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgYUhvb2sgJiZcbiAgICAgIGFIb29rLmNsYXNzTmFtZSAmJlxuICAgICAgYUhvb2sudXJsICYmXG4gICAgICBhSG9vay50cmlnZ2VyTmFtZSAmJlxuICAgICAgdHJpZ2dlcnMuVHlwZXNbYUhvb2sudHJpZ2dlck5hbWVdXG4gICAgKSB7XG4gICAgICBob29rID0ge307XG4gICAgICBob29rLmNsYXNzTmFtZSA9IGFIb29rLmNsYXNzTmFtZTtcbiAgICAgIGhvb2sudXJsID0gYUhvb2sudXJsO1xuICAgICAgaG9vay50cmlnZ2VyTmFtZSA9IGFIb29rLnRyaWdnZXJOYW1lO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTQzLCAnaW52YWxpZCBob29rIGRlY2xhcmF0aW9uJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuYWRkSG9vayhob29rKTtcbiAgfVxuXG4gIGNyZWF0ZUhvb2soYUhvb2spIHtcbiAgICBpZiAoYUhvb2suZnVuY3Rpb25OYW1lKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRGdW5jdGlvbihhSG9vay5mdW5jdGlvbk5hbWUpLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigxNDMsIGBmdW5jdGlvbiBuYW1lOiAke2FIb29rLmZ1bmN0aW9uTmFtZX0gYWxyZWFkeSBleGl0c2ApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZU9yVXBkYXRlSG9vayhhSG9vayk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoYUhvb2suY2xhc3NOYW1lICYmIGFIb29rLnRyaWdnZXJOYW1lKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRUcmlnZ2VyKGFIb29rLmNsYXNzTmFtZSwgYUhvb2sudHJpZ2dlck5hbWUpLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIDE0MyxcbiAgICAgICAgICAgIGBjbGFzcyAke2FIb29rLmNsYXNzTmFtZX0gYWxyZWFkeSBoYXMgdHJpZ2dlciAke2FIb29rLnRyaWdnZXJOYW1lfWBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZU9yVXBkYXRlSG9vayhhSG9vayk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTQzLCAnaW52YWxpZCBob29rIGRlY2xhcmF0aW9uJyk7XG4gIH1cblxuICB1cGRhdGVIb29rKGFIb29rKSB7XG4gICAgaWYgKGFIb29rLmZ1bmN0aW9uTmFtZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0RnVuY3Rpb24oYUhvb2suZnVuY3Rpb25OYW1lKS50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVPclVwZGF0ZUhvb2soYUhvb2spO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigxNDMsIGBubyBmdW5jdGlvbiBuYW1lZDogJHthSG9vay5mdW5jdGlvbk5hbWV9IGlzIGRlZmluZWRgKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoYUhvb2suY2xhc3NOYW1lICYmIGFIb29rLnRyaWdnZXJOYW1lKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRUcmlnZ2VyKGFIb29rLmNsYXNzTmFtZSwgYUhvb2sudHJpZ2dlck5hbWUpLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZU9yVXBkYXRlSG9vayhhSG9vayk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDE0MywgYGNsYXNzICR7YUhvb2suY2xhc3NOYW1lfSBkb2VzIG5vdCBleGlzdGApO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigxNDMsICdpbnZhbGlkIGhvb2sgZGVjbGFyYXRpb24nKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB3cmFwVG9IVFRQUmVxdWVzdChob29rLCBrZXkpIHtcbiAgcmV0dXJuIHJlcSA9PiB7XG4gICAgY29uc3QganNvbkJvZHkgPSB7fTtcbiAgICBmb3IgKHZhciBpIGluIHJlcSkge1xuICAgICAganNvbkJvZHlbaV0gPSByZXFbaV07XG4gICAgfVxuICAgIGlmIChyZXEub2JqZWN0KSB7XG4gICAgICBqc29uQm9keS5vYmplY3QgPSByZXEub2JqZWN0LnRvSlNPTigpO1xuICAgICAganNvbkJvZHkub2JqZWN0LmNsYXNzTmFtZSA9IHJlcS5vYmplY3QuY2xhc3NOYW1lO1xuICAgIH1cbiAgICBpZiAocmVxLm9yaWdpbmFsKSB7XG4gICAgICBqc29uQm9keS5vcmlnaW5hbCA9IHJlcS5vcmlnaW5hbC50b0pTT04oKTtcbiAgICAgIGpzb25Cb2R5Lm9yaWdpbmFsLmNsYXNzTmFtZSA9IHJlcS5vcmlnaW5hbC5jbGFzc05hbWU7XG4gICAgfVxuICAgIGNvbnN0IGpzb25SZXF1ZXN0OiBhbnkgPSB7XG4gICAgICB1cmw6IGhvb2sudXJsLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgfSxcbiAgICAgIGJvZHk6IGpzb25Cb2R5LFxuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgfTtcblxuICAgIGNvbnN0IGFnZW50ID0gaG9vay51cmwuc3RhcnRzV2l0aCgnaHR0cHMnKSA/IEhUVFBBZ2VudHNbJ2h0dHBzJ10gOiBIVFRQQWdlbnRzWydodHRwJ107XG4gICAganNvblJlcXVlc3QuYWdlbnQgPSBhZ2VudDtcblxuICAgIGlmIChrZXkpIHtcbiAgICAgIGpzb25SZXF1ZXN0LmhlYWRlcnNbJ1gtUGFyc2UtV2ViaG9vay1LZXknXSA9IGtleTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9nZ2VyLndhcm4oJ01ha2luZyBvdXRnb2luZyB3ZWJob29rIHJlcXVlc3Qgd2l0aG91dCB3ZWJob29rS2V5IGJlaW5nIHNldCEnKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcXVlc3QoanNvblJlcXVlc3QpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgbGV0IGVycjtcbiAgICAgIGxldCByZXN1bHQ7XG4gICAgICBsZXQgYm9keSA9IHJlc3BvbnNlLmRhdGE7XG4gICAgICBpZiAoYm9keSkge1xuICAgICAgICBpZiAodHlwZW9mIGJvZHkgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGJvZHkgPSBKU09OLnBhcnNlKGJvZHkpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGVyciA9IHtcbiAgICAgICAgICAgICAgZXJyb3I6ICdNYWxmb3JtZWQgcmVzcG9uc2UnLFxuICAgICAgICAgICAgICBjb2RlOiAtMSxcbiAgICAgICAgICAgICAgcGFydGlhbFJlc3BvbnNlOiBib2R5LnN1YnN0cmluZygwLCAxMDApLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFlcnIpIHtcbiAgICAgICAgICByZXN1bHQgPSBib2R5LnN1Y2Nlc3M7XG4gICAgICAgICAgZXJyID0gYm9keS5lcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGVycikge1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9IGVsc2UgaWYgKGhvb2sudHJpZ2dlck5hbWUgPT09ICdiZWZvcmVTYXZlJykge1xuICAgICAgICBpZiAodHlwZW9mIHJlc3VsdCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICBkZWxldGUgcmVzdWx0LmNyZWF0ZWRBdDtcbiAgICAgICAgICBkZWxldGUgcmVzdWx0LnVwZGF0ZWRBdDtcbiAgICAgICAgICBkZWxldGUgcmVzdWx0LmNsYXNzTmFtZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBvYmplY3Q6IHJlc3VsdCB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgSG9va3NDb250cm9sbGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/LiveQueryController.js b/lib/Controllers/LiveQueryController.js new file mode 100644 index 0000000000..ac461a03aa --- /dev/null +++ b/lib/Controllers/LiveQueryController.js @@ -0,0 +1,78 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.LiveQueryController = void 0; + +var _ParseCloudCodePublisher = require("../LiveQuery/ParseCloudCodePublisher"); + +var _Options = require("../Options"); + +class LiveQueryController { + constructor(config) { + // If config is empty, we just assume no classs needs to be registered as LiveQuery + if (!config || !config.classNames) { + this.classNames = new Set(); + } else if (config.classNames instanceof Array) { + const classNames = config.classNames.map(name => new RegExp("^" + name + "$")); + this.classNames = new Set(classNames); + } else { + throw 'liveQuery.classes should be an array of string'; + } + + this.liveQueryPublisher = new _ParseCloudCodePublisher.ParseCloudCodePublisher(config); + } + + onAfterSave(className, currentObject, originalObject, classLevelPermissions) { + if (!this.hasLiveQuery(className)) { + return; + } + + const req = this._makePublisherRequest(currentObject, originalObject, classLevelPermissions); + + this.liveQueryPublisher.onCloudCodeAfterSave(req); + } + + onAfterDelete(className, currentObject, originalObject, classLevelPermissions) { + if (!this.hasLiveQuery(className)) { + return; + } + + const req = this._makePublisherRequest(currentObject, originalObject, classLevelPermissions); + + this.liveQueryPublisher.onCloudCodeAfterDelete(req); + } + + hasLiveQuery(className) { + for (const name of this.classNames) { + if (name.test(className)) { + return true; + } + } + + return false; + } + + _makePublisherRequest(currentObject, originalObject, classLevelPermissions) { + const req = { + object: currentObject + }; + + if (currentObject) { + req.original = originalObject; + } + + if (classLevelPermissions) { + req.classLevelPermissions = classLevelPermissions; + } + + return req; + } + +} + +exports.LiveQueryController = LiveQueryController; +var _default = LiveQueryController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9MaXZlUXVlcnlDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIkxpdmVRdWVyeUNvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImNvbmZpZyIsImNsYXNzTmFtZXMiLCJTZXQiLCJBcnJheSIsIm1hcCIsIm5hbWUiLCJSZWdFeHAiLCJsaXZlUXVlcnlQdWJsaXNoZXIiLCJQYXJzZUNsb3VkQ29kZVB1Ymxpc2hlciIsIm9uQWZ0ZXJTYXZlIiwiY2xhc3NOYW1lIiwiY3VycmVudE9iamVjdCIsIm9yaWdpbmFsT2JqZWN0IiwiY2xhc3NMZXZlbFBlcm1pc3Npb25zIiwiaGFzTGl2ZVF1ZXJ5IiwicmVxIiwiX21ha2VQdWJsaXNoZXJSZXF1ZXN0Iiwib25DbG91ZENvZGVBZnRlclNhdmUiLCJvbkFmdGVyRGVsZXRlIiwib25DbG91ZENvZGVBZnRlckRlbGV0ZSIsInRlc3QiLCJvYmplY3QiLCJvcmlnaW5hbCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNPLE1BQU1BLG1CQUFOLENBQTBCO0FBSS9CQyxFQUFBQSxXQUFXLENBQUNDLE1BQUQsRUFBNEI7QUFDckM7QUFDQSxRQUFJLENBQUNBLE1BQUQsSUFBVyxDQUFDQSxNQUFNLENBQUNDLFVBQXZCLEVBQW1DO0FBQ2pDLFdBQUtBLFVBQUwsR0FBa0IsSUFBSUMsR0FBSixFQUFsQjtBQUNELEtBRkQsTUFFTyxJQUFJRixNQUFNLENBQUNDLFVBQVAsWUFBNkJFLEtBQWpDLEVBQXdDO0FBQzdDLFlBQU1GLFVBQVUsR0FBR0QsTUFBTSxDQUFDQyxVQUFQLENBQ2hCRyxHQURnQixDQUNaQyxJQUFJLElBQUksSUFBSUMsTUFBSixDQUFXLE1BQU1ELElBQU4sR0FBYSxHQUF4QixDQURJLENBQW5CO0FBRUEsV0FBS0osVUFBTCxHQUFrQixJQUFJQyxHQUFKLENBQVFELFVBQVIsQ0FBbEI7QUFDRCxLQUpNLE1BSUE7QUFDTCxZQUFNLGdEQUFOO0FBQ0Q7O0FBQ0QsU0FBS00sa0JBQUwsR0FBMEIsSUFBSUMsZ0RBQUosQ0FBNEJSLE1BQTVCLENBQTFCO0FBQ0Q7O0FBRURTLEVBQUFBLFdBQVcsQ0FDVEMsU0FEUyxFQUVUQyxhQUZTLEVBR1RDLGNBSFMsRUFJVEMscUJBSlMsRUFLVDtBQUNBLFFBQUksQ0FBQyxLQUFLQyxZQUFMLENBQWtCSixTQUFsQixDQUFMLEVBQW1DO0FBQ2pDO0FBQ0Q7O0FBQ0QsVUFBTUssR0FBRyxHQUFHLEtBQUtDLHFCQUFMLENBQTJCTCxhQUEzQixFQUEwQ0MsY0FBMUMsRUFBMERDLHFCQUExRCxDQUFaOztBQUNBLFNBQUtOLGtCQUFMLENBQXdCVSxvQkFBeEIsQ0FBNkNGLEdBQTdDO0FBQ0Q7O0FBRURHLEVBQUFBLGFBQWEsQ0FDWFIsU0FEVyxFQUVYQyxhQUZXLEVBR1hDLGNBSFcsRUFJWEMscUJBSlcsRUFLWDtBQUNBLFFBQUksQ0FBQyxLQUFLQyxZQUFMLENBQWtCSixTQUFsQixDQUFMLEVBQW1DO0FBQ2pDO0FBQ0Q7O0FBQ0QsVUFBTUssR0FBRyxHQUFHLEtBQUtDLHFCQUFMLENBQTJCTCxhQUEzQixFQUEwQ0MsY0FBMUMsRUFBMERDLHFCQUExRCxDQUFaOztBQUNBLFNBQUtOLGtCQUFMLENBQXdCWSxzQkFBeEIsQ0FBK0NKLEdBQS9DO0FBQ0Q7O0FBRURELEVBQUFBLFlBQVksQ0FBQ0osU0FBRCxFQUE2QjtBQUN2QyxTQUFLLE1BQU1MLElBQVgsSUFBbUIsS0FBS0osVUFBeEIsRUFBb0M7QUFDbEMsVUFBSUksSUFBSSxDQUFDZSxJQUFMLENBQVVWLFNBQVYsQ0FBSixFQUEwQjtBQUN4QixlQUFPLElBQVA7QUFDRDtBQUNGOztBQUNELFdBQU8sS0FBUDtBQUNEOztBQUVETSxFQUFBQSxxQkFBcUIsQ0FBQ0wsYUFBRCxFQUFxQkMsY0FBckIsRUFBMENDLHFCQUExQyxFQUE0RTtBQUMvRixVQUFNRSxHQUFHLEdBQUc7QUFDVk0sTUFBQUEsTUFBTSxFQUFFVjtBQURFLEtBQVo7O0FBR0EsUUFBSUEsYUFBSixFQUFtQjtBQUNqQkksTUFBQUEsR0FBRyxDQUFDTyxRQUFKLEdBQWVWLGNBQWY7QUFDRDs7QUFDRCxRQUFJQyxxQkFBSixFQUEyQjtBQUN6QkUsTUFBQUEsR0FBRyxDQUFDRixxQkFBSixHQUE0QkEscUJBQTVCO0FBQ0Q7O0FBQ0QsV0FBT0UsR0FBUDtBQUNEOztBQWhFOEI7OztlQW1FbEJqQixtQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBhcnNlQ2xvdWRDb2RlUHVibGlzaGVyIH0gZnJvbSAnLi4vTGl2ZVF1ZXJ5L1BhcnNlQ2xvdWRDb2RlUHVibGlzaGVyJztcbmltcG9ydCB7IExpdmVRdWVyeU9wdGlvbnMgfSBmcm9tICcuLi9PcHRpb25zJztcbmV4cG9ydCBjbGFzcyBMaXZlUXVlcnlDb250cm9sbGVyIHtcbiAgY2xhc3NOYW1lczogYW55O1xuICBsaXZlUXVlcnlQdWJsaXNoZXI6IGFueTtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6ID9MaXZlUXVlcnlPcHRpb25zKSB7XG4gICAgLy8gSWYgY29uZmlnIGlzIGVtcHR5LCB3ZSBqdXN0IGFzc3VtZSBubyBjbGFzc3MgbmVlZHMgdG8gYmUgcmVnaXN0ZXJlZCBhcyBMaXZlUXVlcnlcbiAgICBpZiAoIWNvbmZpZyB8fCAhY29uZmlnLmNsYXNzTmFtZXMpIHtcbiAgICAgIHRoaXMuY2xhc3NOYW1lcyA9IG5ldyBTZXQoKTtcbiAgICB9IGVsc2UgaWYgKGNvbmZpZy5jbGFzc05hbWVzIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgIGNvbnN0IGNsYXNzTmFtZXMgPSBjb25maWcuY2xhc3NOYW1lc1xuICAgICAgICAubWFwKG5hbWUgPT4gbmV3IFJlZ0V4cChcIl5cIiArIG5hbWUgKyBcIiRcIikpO1xuICAgICAgdGhpcy5jbGFzc05hbWVzID0gbmV3IFNldChjbGFzc05hbWVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgJ2xpdmVRdWVyeS5jbGFzc2VzIHNob3VsZCBiZSBhbiBhcnJheSBvZiBzdHJpbmcnO1xuICAgIH1cbiAgICB0aGlzLmxpdmVRdWVyeVB1Ymxpc2hlciA9IG5ldyBQYXJzZUNsb3VkQ29kZVB1Ymxpc2hlcihjb25maWcpO1xuICB9XG5cbiAgb25BZnRlclNhdmUoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgY3VycmVudE9iamVjdDogYW55LFxuICAgIG9yaWdpbmFsT2JqZWN0OiBhbnksXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiA/YW55XG4gICkge1xuICAgIGlmICghdGhpcy5oYXNMaXZlUXVlcnkoY2xhc3NOYW1lKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByZXEgPSB0aGlzLl9tYWtlUHVibGlzaGVyUmVxdWVzdChjdXJyZW50T2JqZWN0LCBvcmlnaW5hbE9iamVjdCwgY2xhc3NMZXZlbFBlcm1pc3Npb25zKTtcbiAgICB0aGlzLmxpdmVRdWVyeVB1Ymxpc2hlci5vbkNsb3VkQ29kZUFmdGVyU2F2ZShyZXEpO1xuICB9XG5cbiAgb25BZnRlckRlbGV0ZShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBjdXJyZW50T2JqZWN0OiBhbnksXG4gICAgb3JpZ2luYWxPYmplY3Q6IGFueSxcbiAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IGFueVxuICApIHtcbiAgICBpZiAoIXRoaXMuaGFzTGl2ZVF1ZXJ5KGNsYXNzTmFtZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcmVxID0gdGhpcy5fbWFrZVB1Ymxpc2hlclJlcXVlc3QoY3VycmVudE9iamVjdCwgb3JpZ2luYWxPYmplY3QsIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyk7XG4gICAgdGhpcy5saXZlUXVlcnlQdWJsaXNoZXIub25DbG91ZENvZGVBZnRlckRlbGV0ZShyZXEpO1xuICB9XG5cbiAgaGFzTGl2ZVF1ZXJ5KGNsYXNzTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgZm9yIChjb25zdCBuYW1lIG9mIHRoaXMuY2xhc3NOYW1lcykge1xuICAgICAgaWYgKG5hbWUudGVzdChjbGFzc05hbWUpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBfbWFrZVB1Ymxpc2hlclJlcXVlc3QoY3VycmVudE9iamVjdDogYW55LCBvcmlnaW5hbE9iamVjdDogYW55LCBjbGFzc0xldmVsUGVybWlzc2lvbnM6ID9hbnkpOiBhbnkge1xuICAgIGNvbnN0IHJlcSA9IHtcbiAgICAgIG9iamVjdDogY3VycmVudE9iamVjdCxcbiAgICB9O1xuICAgIGlmIChjdXJyZW50T2JqZWN0KSB7XG4gICAgICByZXEub3JpZ2luYWwgPSBvcmlnaW5hbE9iamVjdDtcbiAgICB9XG4gICAgaWYgKGNsYXNzTGV2ZWxQZXJtaXNzaW9ucykge1xuICAgICAgcmVxLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucyA9IGNsYXNzTGV2ZWxQZXJtaXNzaW9ucztcbiAgICB9XG4gICAgcmV0dXJuIHJlcTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBMaXZlUXVlcnlDb250cm9sbGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/LoggerController.js b/lib/Controllers/LoggerController.js new file mode 100644 index 0000000000..be11d8877f --- /dev/null +++ b/lib/Controllers/LoggerController.js @@ -0,0 +1,265 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.LoggerController = exports.LogOrder = exports.LogLevel = void 0; + +var _node = require("parse/node"); + +var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); + +var _LoggerAdapter = require("../Adapters/Logger/LoggerAdapter"); + +var _url = _interopRequireDefault(require("url")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000; +const LOG_STRING_TRUNCATE_LENGTH = 1000; +const truncationMarker = '... (truncated)'; +const LogLevel = { + INFO: 'info', + ERROR: 'error' +}; +exports.LogLevel = LogLevel; +const LogOrder = { + DESCENDING: 'desc', + ASCENDING: 'asc' +}; +exports.LogOrder = LogOrder; +const logLevels = ['error', 'warn', 'info', 'debug', 'verbose', 'silly']; + +class LoggerController extends _AdaptableController.default { + constructor(adapter, appId, options = { + logLevel: 'info' + }) { + super(adapter, appId, options); + let level = 'info'; + + if (options.verbose) { + level = 'verbose'; + } + + if (options.logLevel) { + level = options.logLevel; + } + + const index = logLevels.indexOf(level); // info by default + + logLevels.forEach((level, levelIndex) => { + if (levelIndex > index) { + // silence the levels that are > maxIndex + this[level] = () => {}; + } + }); + } + + maskSensitiveUrl(urlString) { + const urlObj = _url.default.parse(urlString, true); + + const query = urlObj.query; + let sanitizedQuery = '?'; + + for (const key in query) { + if (key !== 'password') { + // normal value + sanitizedQuery += key + '=' + query[key] + '&'; + } else { + // password value, redact it + sanitizedQuery += key + '=' + '********' + '&'; + } + } // trim last character, ? or & + + + sanitizedQuery = sanitizedQuery.slice(0, -1); // return original path name with sanitized params attached + + return urlObj.pathname + sanitizedQuery; + } + + maskSensitive(argArray) { + return argArray.map(e => { + if (!e) { + return e; + } + + if (typeof e === 'string') { + return e.replace(/(password".?:.?")[^"]*"/g, '$1********"'); + } // else it is an object... + // check the url + + + if (e.url) { + // for strings + if (typeof e.url === 'string') { + e.url = this.maskSensitiveUrl(e.url); + } else if (Array.isArray(e.url)) { + // for strings in array + e.url = e.url.map(item => { + if (typeof item === 'string') { + return this.maskSensitiveUrl(item); + } + + return item; + }); + } + } + + if (e.body) { + for (const key of Object.keys(e.body)) { + if (key === 'password') { + e.body[key] = '********'; + break; + } + } + } + + if (e.params) { + for (const key of Object.keys(e.params)) { + if (key === 'password') { + e.params[key] = '********'; + break; + } + } + } + + return e; + }); + } + + log(level, args) { + // make the passed in arguments object an array with the spread operator + args = this.maskSensitive([...args]); + args = [].concat(level, args.map(arg => { + if (typeof arg === 'function') { + return arg(); + } + + return arg; + })); + this.adapter.log.apply(this.adapter, args); + } + + info() { + return this.log('info', arguments); + } + + error() { + return this.log('error', arguments); + } + + warn() { + return this.log('warn', arguments); + } + + verbose() { + return this.log('verbose', arguments); + } + + debug() { + return this.log('debug', arguments); + } + + silly() { + return this.log('silly', arguments); + } + + logRequest({ + method, + url, + headers, + body + }) { + this.verbose(() => { + const stringifiedBody = JSON.stringify(body, null, 2); + return `REQUEST for [${method}] ${url}: ${stringifiedBody}`; + }, { + method, + url, + headers, + body + }); + } + + logResponse({ + method, + url, + result + }) { + this.verbose(() => { + const stringifiedResponse = JSON.stringify(result, null, 2); + return `RESPONSE from [${method}] ${url}: ${stringifiedResponse}`; + }, { + result: result + }); + } // check that date input is valid + + + static validDateTime(date) { + if (!date) { + return null; + } + + date = new Date(date); + + if (!isNaN(date.getTime())) { + return date; + } + + return null; + } + + truncateLogMessage(string) { + if (string && string.length > LOG_STRING_TRUNCATE_LENGTH) { + const truncated = string.substring(0, LOG_STRING_TRUNCATE_LENGTH) + truncationMarker; + return truncated; + } + + return string; + } + + static parseOptions(options = {}) { + const from = LoggerController.validDateTime(options.from) || new Date(Date.now() - 7 * MILLISECONDS_IN_A_DAY); + const until = LoggerController.validDateTime(options.until) || new Date(); + const size = Number(options.size) || 10; + const order = options.order || LogOrder.DESCENDING; + const level = options.level || LogLevel.INFO; + return { + from, + until, + size, + order, + level + }; + } // Returns a promise for a {response} object. + // query params: + // level (optional) Level of logging you want to query for (info || error) + // from (optional) Start time for the search. Defaults to 1 week ago. + // until (optional) End time for the search. Defaults to current time. + // order (optional) Direction of results returned, either “asc” or “desc”. Defaults to “desc”. + // size (optional) Number of rows returned by search. Defaults to 10 + + + getLogs(options = {}) { + if (!this.adapter) { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Logger adapter is not available'); + } + + if (typeof this.adapter.query !== 'function') { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Querying logs is not supported with this adapter'); + } + + options = LoggerController.parseOptions(options); + return this.adapter.query(options); + } + + expectedAdapterType() { + return _LoggerAdapter.LoggerAdapter; + } + +} + +exports.LoggerController = LoggerController; +var _default = LoggerController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9Mb2dnZXJDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIk1JTExJU0VDT05EU19JTl9BX0RBWSIsIkxPR19TVFJJTkdfVFJVTkNBVEVfTEVOR1RIIiwidHJ1bmNhdGlvbk1hcmtlciIsIkxvZ0xldmVsIiwiSU5GTyIsIkVSUk9SIiwiTG9nT3JkZXIiLCJERVNDRU5ESU5HIiwiQVNDRU5ESU5HIiwibG9nTGV2ZWxzIiwiTG9nZ2VyQ29udHJvbGxlciIsIkFkYXB0YWJsZUNvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImFkYXB0ZXIiLCJhcHBJZCIsIm9wdGlvbnMiLCJsb2dMZXZlbCIsImxldmVsIiwidmVyYm9zZSIsImluZGV4IiwiaW5kZXhPZiIsImZvckVhY2giLCJsZXZlbEluZGV4IiwibWFza1NlbnNpdGl2ZVVybCIsInVybFN0cmluZyIsInVybE9iaiIsInVybCIsInBhcnNlIiwicXVlcnkiLCJzYW5pdGl6ZWRRdWVyeSIsImtleSIsInNsaWNlIiwicGF0aG5hbWUiLCJtYXNrU2Vuc2l0aXZlIiwiYXJnQXJyYXkiLCJtYXAiLCJlIiwicmVwbGFjZSIsIkFycmF5IiwiaXNBcnJheSIsIml0ZW0iLCJib2R5IiwiT2JqZWN0Iiwia2V5cyIsInBhcmFtcyIsImxvZyIsImFyZ3MiLCJjb25jYXQiLCJhcmciLCJhcHBseSIsImluZm8iLCJhcmd1bWVudHMiLCJlcnJvciIsIndhcm4iLCJkZWJ1ZyIsInNpbGx5IiwibG9nUmVxdWVzdCIsIm1ldGhvZCIsImhlYWRlcnMiLCJzdHJpbmdpZmllZEJvZHkiLCJKU09OIiwic3RyaW5naWZ5IiwibG9nUmVzcG9uc2UiLCJyZXN1bHQiLCJzdHJpbmdpZmllZFJlc3BvbnNlIiwidmFsaWREYXRlVGltZSIsImRhdGUiLCJEYXRlIiwiaXNOYU4iLCJnZXRUaW1lIiwidHJ1bmNhdGVMb2dNZXNzYWdlIiwic3RyaW5nIiwibGVuZ3RoIiwidHJ1bmNhdGVkIiwic3Vic3RyaW5nIiwicGFyc2VPcHRpb25zIiwiZnJvbSIsIm5vdyIsInVudGlsIiwic2l6ZSIsIk51bWJlciIsIm9yZGVyIiwiZ2V0TG9ncyIsIlBhcnNlIiwiRXJyb3IiLCJQVVNIX01JU0NPTkZJR1VSRUQiLCJleHBlY3RlZEFkYXB0ZXJUeXBlIiwiTG9nZ2VyQWRhcHRlciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRUEsTUFBTUEscUJBQXFCLEdBQUcsS0FBSyxFQUFMLEdBQVUsRUFBVixHQUFlLElBQTdDO0FBQ0EsTUFBTUMsMEJBQTBCLEdBQUcsSUFBbkM7QUFDQSxNQUFNQyxnQkFBZ0IsR0FBRyxpQkFBekI7QUFFTyxNQUFNQyxRQUFRLEdBQUc7QUFDdEJDLEVBQUFBLElBQUksRUFBRSxNQURnQjtBQUV0QkMsRUFBQUEsS0FBSyxFQUFFO0FBRmUsQ0FBakI7O0FBS0EsTUFBTUMsUUFBUSxHQUFHO0FBQ3RCQyxFQUFBQSxVQUFVLEVBQUUsTUFEVTtBQUV0QkMsRUFBQUEsU0FBUyxFQUFFO0FBRlcsQ0FBakI7O0FBS1AsTUFBTUMsU0FBUyxHQUFHLENBQUMsT0FBRCxFQUFVLE1BQVYsRUFBa0IsTUFBbEIsRUFBMEIsT0FBMUIsRUFBbUMsU0FBbkMsRUFBOEMsT0FBOUMsQ0FBbEI7O0FBRU8sTUFBTUMsZ0JBQU4sU0FBK0JDLDRCQUEvQixDQUFtRDtBQUN4REMsRUFBQUEsV0FBVyxDQUFDQyxPQUFELEVBQVVDLEtBQVYsRUFBaUJDLE9BQU8sR0FBRztBQUFFQyxJQUFBQSxRQUFRLEVBQUU7QUFBWixHQUEzQixFQUFpRDtBQUMxRCxVQUFNSCxPQUFOLEVBQWVDLEtBQWYsRUFBc0JDLE9BQXRCO0FBQ0EsUUFBSUUsS0FBSyxHQUFHLE1BQVo7O0FBQ0EsUUFBSUYsT0FBTyxDQUFDRyxPQUFaLEVBQXFCO0FBQ25CRCxNQUFBQSxLQUFLLEdBQUcsU0FBUjtBQUNEOztBQUNELFFBQUlGLE9BQU8sQ0FBQ0MsUUFBWixFQUFzQjtBQUNwQkMsTUFBQUEsS0FBSyxHQUFHRixPQUFPLENBQUND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LEtBSks7QUFLTGhFLE1BQUFBO0FBTEssS0FBUDtBQU9ELEdBak11RCxDQW1NeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNBaUUsRUFBQUEsT0FBTyxDQUFDbkUsT0FBTyxHQUFHLEVBQVgsRUFBZTtBQUNwQixRQUFJLENBQUMsS0FBS0YsT0FBVixFQUFtQjtBQUNqQixZQUFNLElBQUlzRSxZQUFNQyxLQUFWLENBQWdCRCxZQUFNQyxLQUFOLENBQVlDLGtCQUE1QixFQUFnRCxpQ0FBaEQsQ0FBTjtBQUNEOztBQUNELFFBQUksT0FBTyxLQUFLeEUsT0FBTCxDQUFhZSxLQUFwQixLQUE4QixVQUFsQyxFQUE4QztBQUM1QyxZQUFNLElBQUl1RCxZQUFNQyxLQUFWLENBQ0pELFlBQU1DLEtBQU4sQ0FBWUMsa0JBRFIsRUFFSixrREFGSSxDQUFOO0FBSUQ7O0FBQ0R0RSxJQUFBQSxPQUFPLEdBQUdMLGdCQUFnQixDQUFDaUUsWUFBakIsQ0FBOEI1RCxPQUE5QixDQUFWO0FBQ0EsV0FBTyxLQUFLRixPQUFMLENBQWFlLEtBQWIsQ0FBbUJiLE9BQW5CLENBQVA7QUFDRDs7QUFFRHVFLEVBQUFBLG1CQUFtQixHQUFHO0FBQ3BCLFdBQU9DLDRCQUFQO0FBQ0Q7O0FBMU51RDs7O2VBNk4zQzdFLGdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUGFyc2UgfSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBBZGFwdGFibGVDb250cm9sbGVyIGZyb20gJy4vQWRhcHRhYmxlQ29udHJvbGxlcic7XG5pbXBvcnQgeyBMb2dnZXJBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvTG9nZ2VyL0xvZ2dlckFkYXB0ZXInO1xuaW1wb3J0IHVybCBmcm9tICd1cmwnO1xuXG5jb25zdCBNSUxMSVNFQ09ORFNfSU5fQV9EQVkgPSAyNCAqIDYwICogNjAgKiAxMDAwO1xuY29uc3QgTE9HX1NUUklOR19UUlVOQ0FURV9MRU5HVEggPSAxMDAwO1xuY29uc3QgdHJ1bmNhdGlvbk1hcmtlciA9ICcuLi4gKHRydW5jYXRlZCknO1xuXG5leHBvcnQgY29uc3QgTG9nTGV2ZWwgPSB7XG4gIElORk86ICdpbmZvJyxcbiAgRVJST1I6ICdlcnJvcicsXG59O1xuXG5leHBvcnQgY29uc3QgTG9nT3JkZXIgPSB7XG4gIERFU0NFTkRJTkc6ICdkZXNjJyxcbiAgQVNDRU5ESU5HOiAnYXNjJyxcbn07XG5cbmNvbnN0IGxvZ0xldmVscyA9IFsnZXJyb3InLCAnd2FybicsICdpbmZvJywgJ2RlYnVnJywgJ3ZlcmJvc2UnLCAnc2lsbHknXTtcblxuZXhwb3J0IGNsYXNzIExvZ2dlckNvbnRyb2xsZXIgZXh0ZW5kcyBBZGFwdGFibGVDb250cm9sbGVyIHtcbiAgY29uc3RydWN0b3IoYWRhcHRlciwgYXBwSWQsIG9wdGlvbnMgPSB7IGxvZ0xldmVsOiAnaW5mbycgfSkge1xuICAgIHN1cGVyKGFkYXB0ZXIsIGFwcElkLCBvcHRpb25zKTtcbiAgICBsZXQgbGV2ZWwgPSAnaW5mbyc7XG4gICAgaWYgKG9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgbGV2ZWwgPSAndmVyYm9zZSc7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmxvZ0xldmVsKSB7XG4gICAgICBsZXZlbCA9IG9wdGlvbnMubG9nTGV2ZWw7XG4gICAgfVxuICAgIGNvbnN0IGluZGV4ID0gbG9nTGV2ZWxzLmluZGV4T2YobGV2ZWwpOyAvLyBpbmZvIGJ5IGRlZmF1bHRcbiAgICBsb2dMZXZlbHMuZm9yRWFjaCgobGV2ZWwsIGxldmVsSW5kZXgpID0+IHtcbiAgICAgIGlmIChsZXZlbEluZGV4ID4gaW5kZXgpIHtcbiAgICAgICAgLy8gc2lsZW5jZSB0aGUgbGV2ZWxzIHRoYXQgYXJlID4gbWF4SW5kZXhcbiAgICAgICAgdGhpc1tsZXZlbF0gPSAoKSA9PiB7fTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG1hc2tTZW5zaXRpdmVVcmwodXJsU3RyaW5nKSB7XG4gICAgY29uc3QgdXJsT2JqID0gdXJsLnBhcnNlKHVybFN0cmluZywgdHJ1ZSk7XG4gICAgY29uc3QgcXVlcnkgPSB1cmxPYmoucXVlcnk7XG4gICAgbGV0IHNhbml0aXplZFF1ZXJ5ID0gJz8nO1xuXG4gICAgZm9yIChjb25zdCBrZXkgaW4gcXVlcnkpIHtcbiAgICAgIGlmIChrZXkgIT09ICdwYXNzd29yZCcpIHtcbiAgICAgICAgLy8gbm9ybWFsIHZhbHVlXG4gICAgICAgIHNhbml0aXplZFF1ZXJ5ICs9IGtleSArICc9JyArIHF1ZXJ5W2tleV0gKyAnJic7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBwYXNzd29yZCB2YWx1ZSwgcmVkYWN0IGl0XG4gICAgICAgIHNhbml0aXplZFF1ZXJ5ICs9IGtleSArICc9JyArICcqKioqKioqKicgKyAnJic7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdHJpbSBsYXN0IGNoYXJhY3RlciwgPyBvciAmXG4gICAgc2FuaXRpemVkUXVlcnkgPSBzYW5pdGl6ZWRRdWVyeS5zbGljZSgwLCAtMSk7XG5cbiAgICAvLyByZXR1cm4gb3JpZ2luYWwgcGF0aCBuYW1lIHdpdGggc2FuaXRpemVkIHBhcmFtcyBhdHRhY2hlZFxuICAgIHJldHVybiB1cmxPYmoucGF0aG5hbWUgKyBzYW5pdGl6ZWRRdWVyeTtcbiAgfVxuXG4gIG1hc2tTZW5zaXRpdmUoYXJnQXJyYXkpIHtcbiAgICByZXR1cm4gYXJnQXJyYXkubWFwKGUgPT4ge1xuICAgICAgaWYgKCFlKSB7XG4gICAgICAgIHJldHVybiBlO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBlLnJlcGxhY2UoLyhwYXNzd29yZFwiLj86Lj9cIilbXlwiXSpcIi9nLCAnJDEqKioqKioqKlwiJyk7XG4gICAgICB9XG4gICAgICAvLyBlbHNlIGl0IGlzIGFuIG9iamVjdC4uLlxuXG4gICAgICAvLyBjaGVjayB0aGUgdXJsXG4gICAgICBpZiAoZS51cmwpIHtcbiAgICAgICAgLy8gZm9yIHN0cmluZ3NcbiAgICAgICAgaWYgKHR5cGVvZiBlLnVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBlLnVybCA9IHRoaXMubWFza1NlbnNpdGl2ZVVybChlLnVybCk7XG4gICAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShlLnVybCkpIHtcbiAgICAgICAgICAvLyBmb3Igc3RyaW5ncyBpbiBhcnJheVxuICAgICAgICAgIGUudXJsID0gZS51cmwubWFwKGl0ZW0gPT4ge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5tYXNrU2Vuc2l0aXZlVXJsKGl0ZW0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gaXRlbTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZS5ib2R5KSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGUuYm9keSkpIHtcbiAgICAgICAgICBpZiAoa2V5ID09PSAncGFzc3dvcmQnKSB7XG4gICAgICAgICAgICBlLmJvZHlba2V5XSA9ICcqKioqKioqKic7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGUucGFyYW1zKSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGUucGFyYW1zKSkge1xuICAgICAgICAgIGlmIChrZXkgPT09ICdwYXNzd29yZCcpIHtcbiAgICAgICAgICAgIGUucGFyYW1zW2tleV0gPSAnKioqKioqKionO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBlO1xuICAgIH0pO1xuICB9XG5cbiAgbG9nKGxldmVsLCBhcmdzKSB7XG4gICAgLy8gbWFrZSB0aGUgcGFzc2VkIGluIGFyZ3VtZW50cyBvYmplY3QgYW4gYXJyYXkgd2l0aCB0aGUgc3ByZWFkIG9wZXJhdG9yXG4gICAgYXJncyA9IHRoaXMubWFza1NlbnNpdGl2ZShbLi4uYXJnc10pO1xuICAgIGFyZ3MgPSBbXS5jb25jYXQoXG4gICAgICBsZXZlbCxcbiAgICAgIGFyZ3MubWFwKGFyZyA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgcmV0dXJuIGFyZygpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhcmc7XG4gICAgICB9KVxuICAgICk7XG4gICAgdGhpcy5hZGFwdGVyLmxvZy5hcHBseSh0aGlzLmFkYXB0ZXIsIGFyZ3MpO1xuICB9XG5cbiAgaW5mbygpIHtcbiAgICByZXR1cm4gdGhpcy5sb2coJ2luZm8nLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgZXJyb3IoKSB7XG4gICAgcmV0dXJuIHRoaXMubG9nKCdlcnJvcicsIGFyZ3VtZW50cyk7XG4gIH1cblxuICB3YXJuKCkge1xuICAgIHJldHVybiB0aGlzLmxvZygnd2FybicsIGFyZ3VtZW50cyk7XG4gIH1cblxuICB2ZXJib3NlKCkge1xuICAgIHJldHVybiB0aGlzLmxvZygndmVyYm9zZScsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBkZWJ1ZygpIHtcbiAgICByZXR1cm4gdGhpcy5sb2coJ2RlYnVnJywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIHNpbGx5KCkge1xuICAgIHJldHVybiB0aGlzLmxvZygnc2lsbHknLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgbG9nUmVxdWVzdCh7IG1ldGhvZCwgdXJsLCBoZWFkZXJzLCBib2R5IH0pIHtcbiAgICB0aGlzLnZlcmJvc2UoXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHN0cmluZ2lmaWVkQm9keSA9IEpTT04uc3RyaW5naWZ5KGJvZHksIG51bGwsIDIpO1xuICAgICAgICByZXR1cm4gYFJFUVVFU1QgZm9yIFske21ldGhvZH1dICR7dXJsfTogJHtzdHJpbmdpZmllZEJvZHl9YDtcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG1ldGhvZCxcbiAgICAgICAgdXJsLFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICBib2R5LFxuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBsb2dSZXNwb25zZSh7IG1ldGhvZCwgdXJsLCByZXN1bHQgfSkge1xuICAgIHRoaXMudmVyYm9zZShcbiAgICAgICgpID0+IHtcbiAgICAgICAgY29uc3Qgc3RyaW5naWZpZWRSZXNwb25zZSA9IEpTT04uc3RyaW5naWZ5KHJlc3VsdCwgbnVsbCwgMik7XG4gICAgICAgIHJldHVybiBgUkVTUE9OU0UgZnJvbSBbJHttZXRob2R9XSAke3VybH06ICR7c3RyaW5naWZpZWRSZXNwb25zZX1gO1xuICAgICAgfSxcbiAgICAgIHsgcmVzdWx0OiByZXN1bHQgfVxuICAgICk7XG4gIH1cbiAgLy8gY2hlY2sgdGhhdCBkYXRlIGlucHV0IGlzIHZhbGlkXG4gIHN0YXRpYyB2YWxpZERhdGVUaW1lKGRhdGUpIHtcbiAgICBpZiAoIWRhdGUpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBkYXRlID0gbmV3IERhdGUoZGF0ZSk7XG5cbiAgICBpZiAoIWlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB0cnVuY2F0ZUxvZ01lc3NhZ2Uoc3RyaW5nKSB7XG4gICAgaWYgKHN0cmluZyAmJiBzdHJpbmcubGVuZ3RoID4gTE9HX1NUUklOR19UUlVOQ0FURV9MRU5HVEgpIHtcbiAgICAgIGNvbnN0IHRydW5jYXRlZCA9IHN0cmluZy5zdWJzdHJpbmcoMCwgTE9HX1NUUklOR19UUlVOQ0FURV9MRU5HVEgpICsgdHJ1bmNhdGlvbk1hcmtlcjtcbiAgICAgIHJldHVybiB0cnVuY2F0ZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0cmluZztcbiAgfVxuXG4gIHN0YXRpYyBwYXJzZU9wdGlvbnMob3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgZnJvbSA9XG4gICAgICBMb2dnZXJDb250cm9sbGVyLnZhbGlkRGF0ZVRpbWUob3B0aW9ucy5mcm9tKSB8fFxuICAgICAgbmV3IERhdGUoRGF0ZS5ub3coKSAtIDcgKiBNSUxMSVNFQ09ORFNfSU5fQV9EQVkpO1xuICAgIGNvbnN0IHVudGlsID0gTG9nZ2VyQ29udHJvbGxlci52YWxpZERhdGVUaW1lKG9wdGlvbnMudW50aWwpIHx8IG5ldyBEYXRlKCk7XG4gICAgY29uc3Qgc2l6ZSA9IE51bWJlcihvcHRpb25zLnNpemUpIHx8IDEwO1xuICAgIGNvbnN0IG9yZGVyID0gb3B0aW9ucy5vcmRlciB8fCBMb2dPcmRlci5ERVNDRU5ESU5HO1xuICAgIGNvbnN0IGxldmVsID0gb3B0aW9ucy5sZXZlbCB8fCBMb2dMZXZlbC5JTkZPO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGZyb20sXG4gICAgICB1bnRpbCxcbiAgICAgIHNpemUsXG4gICAgICBvcmRlcixcbiAgICAgIGxldmVsLFxuICAgIH07XG4gIH1cblxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYSB7cmVzcG9uc2V9IG9iamVjdC5cbiAgLy8gcXVlcnkgcGFyYW1zOlxuICAvLyBsZXZlbCAob3B0aW9uYWwpIExldmVsIG9mIGxvZ2dpbmcgeW91IHdhbnQgdG8gcXVlcnkgZm9yIChpbmZvIHx8IGVycm9yKVxuICAvLyBmcm9tIChvcHRpb25hbCkgU3RhcnQgdGltZSBmb3IgdGhlIHNlYXJjaC4gRGVmYXVsdHMgdG8gMSB3ZWVrIGFnby5cbiAgLy8gdW50aWwgKG9wdGlvbmFsKSBFbmQgdGltZSBmb3IgdGhlIHNlYXJjaC4gRGVmYXVsdHMgdG8gY3VycmVudCB0aW1lLlxuICAvLyBvcmRlciAob3B0aW9uYWwpIERpcmVjdGlvbiBvZiByZXN1bHRzIHJldHVybmVkLCBlaXRoZXIg4oCcYXNj4oCdIG9yIOKAnGRlc2PigJ0uIERlZmF1bHRzIHRvIOKAnGRlc2PigJ0uXG4gIC8vIHNpemUgKG9wdGlvbmFsKSBOdW1iZXIgb2Ygcm93cyByZXR1cm5lZCBieSBzZWFyY2guIERlZmF1bHRzIHRvIDEwXG4gIGdldExvZ3Mob3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKCF0aGlzLmFkYXB0ZXIpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5QVVNIX01JU0NPTkZJR1VSRUQsICdMb2dnZXIgYWRhcHRlciBpcyBub3QgYXZhaWxhYmxlJyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdGhpcy5hZGFwdGVyLnF1ZXJ5ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgJ1F1ZXJ5aW5nIGxvZ3MgaXMgbm90IHN1cHBvcnRlZCB3aXRoIHRoaXMgYWRhcHRlcidcbiAgICAgICk7XG4gICAgfVxuICAgIG9wdGlvbnMgPSBMb2dnZXJDb250cm9sbGVyLnBhcnNlT3B0aW9ucyhvcHRpb25zKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnF1ZXJ5KG9wdGlvbnMpO1xuICB9XG5cbiAgZXhwZWN0ZWRBZGFwdGVyVHlwZSgpIHtcbiAgICByZXR1cm4gTG9nZ2VyQWRhcHRlcjtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBMb2dnZXJDb250cm9sbGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/ParseGraphQLController.js b/lib/Controllers/ParseGraphQLController.js new file mode 100644 index 0000000000..64dabf14fb --- /dev/null +++ b/lib/Controllers/ParseGraphQLController.js @@ -0,0 +1,358 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.GraphQLConfigKey = exports.GraphQLConfigId = exports.GraphQLConfigClassName = exports.default = void 0; + +var _requiredParameter = _interopRequireDefault(require("../../lib/requiredParameter")); + +var _DatabaseController = _interopRequireDefault(require("./DatabaseController")); + +var _CacheController = _interopRequireDefault(require("./CacheController")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } + +function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const GraphQLConfigClassName = '_GraphQLConfig'; +exports.GraphQLConfigClassName = GraphQLConfigClassName; +const GraphQLConfigId = '1'; +exports.GraphQLConfigId = GraphQLConfigId; +const GraphQLConfigKey = 'config'; +exports.GraphQLConfigKey = GraphQLConfigKey; + +class ParseGraphQLController { + constructor(params = {}) { + this.databaseController = params.databaseController || (0, _requiredParameter.default)(`ParseGraphQLController requires a "databaseController" to be instantiated.`); + this.cacheController = params.cacheController; + this.isMounted = !!params.mountGraphQL; + this.configCacheKey = GraphQLConfigKey; + } + + async getGraphQLConfig() { + if (this.isMounted) { + const _cachedConfig = await this._getCachedGraphQLConfig(); + + if (_cachedConfig) { + return _cachedConfig; + } + } + + const results = await this.databaseController.find(GraphQLConfigClassName, { + objectId: GraphQLConfigId + }, { + limit: 1 + }); + let graphQLConfig; + + if (results.length != 1) { + // If there is no config in the database - return empty config. + return {}; + } else { + graphQLConfig = results[0][GraphQLConfigKey]; + } + + if (this.isMounted) { + this._putCachedGraphQLConfig(graphQLConfig); + } + + return graphQLConfig; + } + + async updateGraphQLConfig(graphQLConfig) { + // throws if invalid + this._validateGraphQLConfig(graphQLConfig || (0, _requiredParameter.default)('You must provide a graphQLConfig!')); // Transform in dot notation to make sure it works + + + const update = Object.keys(graphQLConfig).reduce((acc, key) => { + return { + [GraphQLConfigKey]: _objectSpread(_objectSpread({}, acc[GraphQLConfigKey]), {}, { + [key]: graphQLConfig[key] + }) + }; + }, { + [GraphQLConfigKey]: {} + }); + await this.databaseController.update(GraphQLConfigClassName, { + objectId: GraphQLConfigId + }, update, { + upsert: true + }); + + if (this.isMounted) { + this._putCachedGraphQLConfig(graphQLConfig); + } + + return { + response: { + result: true + } + }; + } + + _getCachedGraphQLConfig() { + return this.cacheController.graphQL.get(this.configCacheKey); + } + + _putCachedGraphQLConfig(graphQLConfig) { + return this.cacheController.graphQL.put(this.configCacheKey, graphQLConfig, 60000); + } + + _validateGraphQLConfig(graphQLConfig) { + const errorMessages = []; + + if (!graphQLConfig) { + errorMessages.push('cannot be undefined, null or empty'); + } else if (!isValidSimpleObject(graphQLConfig)) { + errorMessages.push('must be a valid object'); + } else { + const { + enabledForClasses = null, + disabledForClasses = null, + classConfigs = null + } = graphQLConfig, + invalidKeys = _objectWithoutProperties(graphQLConfig, ["enabledForClasses", "disabledForClasses", "classConfigs"]); + + if (Object.keys(invalidKeys).length) { + errorMessages.push(`encountered invalid keys: [${Object.keys(invalidKeys)}]`); + } + + if (enabledForClasses !== null && !isValidStringArray(enabledForClasses)) { + errorMessages.push(`"enabledForClasses" is not a valid array`); + } + + if (disabledForClasses !== null && !isValidStringArray(disabledForClasses)) { + errorMessages.push(`"disabledForClasses" is not a valid array`); + } + + if (classConfigs !== null) { + if (Array.isArray(classConfigs)) { + classConfigs.forEach(classConfig => { + const errorMessage = this._validateClassConfig(classConfig); + + if (errorMessage) { + errorMessages.push(`classConfig:${classConfig.className} is invalid because ${errorMessage}`); + } + }); + } else { + errorMessages.push(`"classConfigs" is not a valid array`); + } + } + } + + if (errorMessages.length) { + throw new Error(`Invalid graphQLConfig: ${errorMessages.join('; ')}`); + } + } + + _validateClassConfig(classConfig) { + if (!isValidSimpleObject(classConfig)) { + return 'it must be a valid object'; + } else { + const { + className, + type = null, + query = null, + mutation = null + } = classConfig, + invalidKeys = _objectWithoutProperties(classConfig, ["className", "type", "query", "mutation"]); + + if (Object.keys(invalidKeys).length) { + return `"invalidKeys" [${Object.keys(invalidKeys)}] should not be present`; + } + + if (typeof className !== 'string' || !className.trim().length) { + // TODO consider checking class exists in schema? + return `"className" must be a valid string`; + } + + if (type !== null) { + if (!isValidSimpleObject(type)) { + return `"type" must be a valid object`; + } + + const { + inputFields = null, + outputFields = null, + constraintFields = null, + sortFields = null + } = type, + invalidKeys = _objectWithoutProperties(type, ["inputFields", "outputFields", "constraintFields", "sortFields"]); + + if (Object.keys(invalidKeys).length) { + return `"type" contains invalid keys, [${Object.keys(invalidKeys)}]`; + } else if (outputFields !== null && !isValidStringArray(outputFields)) { + return `"outputFields" must be a valid string array`; + } else if (constraintFields !== null && !isValidStringArray(constraintFields)) { + return `"constraintFields" must be a valid string array`; + } + + if (sortFields !== null) { + if (Array.isArray(sortFields)) { + let errorMessage; + sortFields.every((sortField, index) => { + if (!isValidSimpleObject(sortField)) { + errorMessage = `"sortField" at index ${index} is not a valid object`; + return false; + } else { + const { + field, + asc, + desc + } = sortField, + invalidKeys = _objectWithoutProperties(sortField, ["field", "asc", "desc"]); + + if (Object.keys(invalidKeys).length) { + errorMessage = `"sortField" at index ${index} contains invalid keys, [${Object.keys(invalidKeys)}]`; + return false; + } else { + if (typeof field !== 'string' || field.trim().length === 0) { + errorMessage = `"sortField" at index ${index} did not provide the "field" as a string`; + return false; + } else if (typeof asc !== 'boolean' || typeof desc !== 'boolean') { + errorMessage = `"sortField" at index ${index} did not provide "asc" or "desc" as booleans`; + return false; + } + } + } + + return true; + }); + + if (errorMessage) { + return errorMessage; + } + } else { + return `"sortFields" must be a valid array.`; + } + } + + if (inputFields !== null) { + if (isValidSimpleObject(inputFields)) { + const { + create = null, + update = null + } = inputFields, + invalidKeys = _objectWithoutProperties(inputFields, ["create", "update"]); + + if (Object.keys(invalidKeys).length) { + return `"inputFields" contains invalid keys: [${Object.keys(invalidKeys)}]`; + } else { + if (update !== null && !isValidStringArray(update)) { + return `"inputFields.update" must be a valid string array`; + } else if (create !== null) { + if (!isValidStringArray(create)) { + return `"inputFields.create" must be a valid string array`; + } else if (className === '_User') { + if (!create.includes('username') || !create.includes('password')) { + return `"inputFields.create" must include required fields, username and password`; + } + } + } + } + } else { + return `"inputFields" must be a valid object`; + } + } + } + + if (query !== null) { + if (isValidSimpleObject(query)) { + const { + find = null, + get = null, + findAlias = null, + getAlias = null + } = query, + invalidKeys = _objectWithoutProperties(query, ["find", "get", "findAlias", "getAlias"]); + + if (Object.keys(invalidKeys).length) { + return `"query" contains invalid keys, [${Object.keys(invalidKeys)}]`; + } else if (find !== null && typeof find !== 'boolean') { + return `"query.find" must be a boolean`; + } else if (get !== null && typeof get !== 'boolean') { + return `"query.get" must be a boolean`; + } else if (findAlias !== null && typeof findAlias !== 'string') { + return `"query.findAlias" must be a string`; + } else if (getAlias !== null && typeof getAlias !== 'string') { + return `"query.getAlias" must be a string`; + } + } else { + return `"query" must be a valid object`; + } + } + + if (mutation !== null) { + if (isValidSimpleObject(mutation)) { + const { + create = null, + update = null, + destroy = null, + createAlias = null, + updateAlias = null, + destroyAlias = null + } = mutation, + invalidKeys = _objectWithoutProperties(mutation, ["create", "update", "destroy", "createAlias", "updateAlias", "destroyAlias"]); + + if (Object.keys(invalidKeys).length) { + return `"mutation" contains invalid keys, [${Object.keys(invalidKeys)}]`; + } + + if (create !== null && typeof create !== 'boolean') { + return `"mutation.create" must be a boolean`; + } + + if (update !== null && typeof update !== 'boolean') { + return `"mutation.update" must be a boolean`; + } + + if (destroy !== null && typeof destroy !== 'boolean') { + return `"mutation.destroy" must be a boolean`; + } + + if (createAlias !== null && typeof createAlias !== 'string') { + return `"mutation.createAlias" must be a string`; + } + + if (updateAlias !== null && typeof updateAlias !== 'string') { + return `"mutation.updateAlias" must be a string`; + } + + if (destroyAlias !== null && typeof destroyAlias !== 'string') { + return `"mutation.destroyAlias" must be a string`; + } + } else { + return `"mutation" must be a valid object`; + } + } + } + } + +} + +const isValidStringArray = function (array) { + return Array.isArray(array) ? !array.some(s => typeof s !== 'string' || s.trim().length < 1) : false; +}; +/** + * Ensures the obj is a simple JSON/{} + * object, i.e. not an array, null, date + * etc. + */ + + +const isValidSimpleObject = function (obj) { + return typeof obj === 'object' && !Array.isArray(obj) && obj !== null && obj instanceof Date !== true && obj instanceof Promise !== true; +}; + +var _default = ParseGraphQLController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9QYXJzZUdyYXBoUUxDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIkdyYXBoUUxDb25maWdDbGFzc05hbWUiLCJHcmFwaFFMQ29uZmlnSWQiLCJHcmFwaFFMQ29uZmlnS2V5IiwiUGFyc2VHcmFwaFFMQ29udHJvbGxlciIsImNvbnN0cnVjdG9yIiwicGFyYW1zIiwiZGF0YWJhc2VDb250cm9sbGVyIiwiY2FjaGVDb250cm9sbGVyIiwiaXNNb3VudGVkIiwibW91bnRHcmFwaFFMIiwiY29uZmlnQ2FjaGVLZXkiLCJnZXRHcmFwaFFMQ29uZmlnIiwiX2NhY2hlZENvbmZpZyIsIl9nZXRDYWNoZWRHcmFwaFFMQ29uZmlnIiwicmVzdWx0cyIsImZpbmQiLCJvYmplY3RJZCIsImxpbWl0IiwiZ3JhcGhRTENvbmZpZyIsImxlbmd0aCIsIl9wdXRDYWNoZWRHcmFwaFFMQ29uZmlnIiwidXBkYXRlR3JhcGhRTENvbmZpZyIsIl92YWxpZGF0ZUdyYXBoUUxDb25maWciLCJ1cGRhdGUiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwiYWNjIiwia2V5IiwidXBzZXJ0IiwicmVzcG9uc2UiLCJyZXN1bHQiLCJncmFwaFFMIiwiZ2V0IiwicHV0IiwiZXJyb3JNZXNzYWdlcyIsInB1c2giLCJpc1ZhbGlkU2ltcGxlT2JqZWN0IiwiZW5hYmxlZEZvckNsYXNzZXMiLCJkaXNhYmxlZEZvckNsYXNzZXMiLCJjbGFzc0NvbmZpZ3MiLCJpbnZhbGlkS2V5cyIsImlzVmFsaWRTdHJpbmdBcnJheSIsIkFycmF5IiwiaXNBcnJheSIsImZvckVhY2giLCJjbGFzc0NvbmZpZyIsImVycm9yTWVzc2FnZSIsIl92YWxpZGF0ZUNsYXNzQ29uZmlnIiwiY2xhc3NOYW1lIiwiRXJyb3IiLCJqb2luIiwidHlwZSIsInF1ZXJ5IiwibXV0YXRpb24iLCJ0cmltIiwiaW5wdXRGaWVsZHMiLCJvdXRwdXRGaWVsZHMiLCJjb25zdHJhaW50RmllbGRzIiwic29ydEZpZWxkcyIsImV2ZXJ5Iiwic29ydEZpZWxkIiwiaW5kZXgiLCJmaWVsZCIsImFzYyIsImRlc2MiLCJjcmVhdGUiLCJpbmNsdWRlcyIsImZpbmRBbGlhcyIsImdldEFsaWFzIiwiZGVzdHJveSIsImNyZWF0ZUFsaWFzIiwidXBkYXRlQWxpYXMiLCJkZXN0cm95QWxpYXMiLCJhcnJheSIsInNvbWUiLCJzIiwib2JqIiwiRGF0ZSIsIlByb21pc2UiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7Ozs7Ozs7QUFFQSxNQUFNQSxzQkFBc0IsR0FBRyxnQkFBL0I7O0FBQ0EsTUFBTUMsZUFBZSxHQUFHLEdBQXhCOztBQUNBLE1BQU1DLGdCQUFnQixHQUFHLFFBQXpCOzs7QUFFQSxNQUFNQyxzQkFBTixDQUE2QjtBQU0zQkMsRUFBQUEsV0FBVyxDQUNUQyxNQUdDLEdBQUcsRUFKSyxFQUtUO0FBQ0EsU0FBS0Msa0JBQUwsR0FDRUQsTUFBTSxDQUFDQyxrQkFBUCxJQUNBLGdDQUNHLDRFQURILENBRkY7QUFLQSxTQUFLQyxlQUFMLEdBQXVCRixNQUFNLENBQUNFLGVBQTlCO0FBQ0EsU0FBS0MsU0FBTCxHQUFpQixDQUFDLENBQUNILE1BQU0sQ0FBQ0ksWUFBMUI7QUFDQSxTQUFLQyxjQUFMLEdBQXNCUixnQkFBdEI7QUFDRDs7QUFFRCxRQUFNUyxnQkFBTixHQUFzRDtBQUNwRCxRQUFJLEtBQUtILFNBQVQsRUFBb0I7QUFDbEIsWUFBTUksYUFBYSxHQUFHLE1BQU0sS0FBS0MsdUJBQUwsRUFBNUI7O0FBQ0EsVUFBSUQsYUFBSixFQUFtQjtBQUNqQixlQUFPQSxhQUFQO0FBQ0Q7QUFDRjs7QUFFRCxVQUFNRSxPQUFPLEdBQUcsTUFBTSxLQUFLUixrQkFBTCxDQUF3QlMsSUFBeEIsQ0FDcEJmLHNCQURvQixFQUVwQjtBQUFFZ0IsTUFBQUEsUUFBUSxFQUFFZjtBQUFaLEtBRm9CLEVBR3BCO0FBQUVnQixNQUFBQSxLQUFLLEVBQUU7QUFBVCxLQUhvQixDQUF0QjtBQU1BLFFBQUlDLGFB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QUFhLFFBQWIsSUFBeUJBLENBQUMsQ0FBQ3JCLElBQUYsR0FBU3BDLE1BQVQsR0FBa0IsQ0FBM0QsQ0FERSxHQUVILEtBRko7QUFHRCxDQUpEO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0EsTUFBTWtCLG1CQUFtQixHQUFHLFVBQVV3QyxHQUFWLEVBQXdCO0FBQ2xELFNBQ0UsT0FBT0EsR0FBUCxLQUFlLFFBQWYsSUFDQSxDQUFDbEMsS0FBSyxDQUFDQyxPQUFOLENBQWNpQyxHQUFkLENBREQsSUFFQUEsR0FBRyxLQUFLLElBRlIsSUFHQUEsR0FBRyxZQUFZQyxJQUFmLEtBQXdCLElBSHhCLElBSUFELEdBQUcsWUFBWUUsT0FBZixLQUEyQixJQUw3QjtBQU9ELENBUkQ7O2VBd0RlNUUsc0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcmVxdWlyZWRQYXJhbWV0ZXIgZnJvbSAnLi4vLi4vbGliL3JlcXVpcmVkUGFyYW1ldGVyJztcbmltcG9ydCBEYXRhYmFzZUNvbnRyb2xsZXIgZnJvbSAnLi9EYXRhYmFzZUNvbnRyb2xsZXInO1xuaW1wb3J0IENhY2hlQ29udHJvbGxlciBmcm9tICcuL0NhY2hlQ29udHJvbGxlcic7XG5cbmNvbnN0IEdyYXBoUUxDb25maWdDbGFzc05hbWUgPSAnX0dyYXBoUUxDb25maWcnO1xuY29uc3QgR3JhcGhRTENvbmZpZ0lkID0gJzEnO1xuY29uc3QgR3JhcGhRTENvbmZpZ0tleSA9ICdjb25maWcnO1xuXG5jbGFzcyBQYXJzZUdyYXBoUUxDb250cm9sbGVyIHtcbiAgZGF0YWJhc2VDb250cm9sbGVyOiBEYXRhYmFzZUNvbnRyb2xsZXI7XG4gIGNhY2hlQ29udHJvbGxlcjogQ2FjaGVDb250cm9sbGVyO1xuICBpc01vdW50ZWQ6IGJvb2xlYW47XG4gIGNvbmZpZ0NhY2hlS2V5OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcGFyYW1zOiB7XG4gICAgICBkYXRhYmFzZUNvbnRyb2xsZXI6IERhdGFiYXNlQ29udHJvbGxlcixcbiAgICAgIGNhY2hlQ29udHJvbGxlcjogQ2FjaGVDb250cm9sbGVyLFxuICAgIH0gPSB7fVxuICApIHtcbiAgICB0aGlzLmRhdGFiYXNlQ29udHJvbGxlciA9XG4gICAgICBwYXJhbXMuZGF0YWJhc2VDb250cm9sbGVyIHx8XG4gICAgICByZXF1aXJlZFBhcmFtZXRlcihcbiAgICAgICAgYFBhcnNlR3JhcGhRTENvbnRyb2xsZXIgcmVxdWlyZXMgYSBcImRhdGFiYXNlQ29udHJvbGxlclwiIHRvIGJlIGluc3RhbnRpYXRlZC5gXG4gICAgICApO1xuICAgIHRoaXMuY2FjaGVDb250cm9sbGVyID0gcGFyYW1zLmNhY2hlQ29udHJvbGxlcjtcbiAgICB0aGlzLmlzTW91bnRlZCA9ICEhcGFyYW1zLm1vdW50R3JhcGhRTDtcbiAgICB0aGlzLmNvbmZpZ0NhY2hlS2V5ID0gR3JhcGhRTENvbmZpZ0tleTtcbiAgfVxuXG4gIGFzeW5jIGdldEdyYXBoUUxDb25maWcoKTogUHJvbWlzZTxQYXJzZUdyYXBoUUxDb25maWc+IHtcbiAgICBpZiAodGhpcy5pc01vdW50ZWQpIHtcbiAgICAgIGNvbnN0IF9jYWNoZWRDb25maWcgPSBhd2FpdCB0aGlzLl9nZXRDYWNoZWRHcmFwaFFMQ29uZmlnKCk7XG4gICAgICBpZiAoX2NhY2hlZENvbmZpZykge1xuICAgICAgICByZXR1cm4gX2NhY2hlZENvbmZpZztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5kYXRhYmFzZUNvbnRyb2xsZXIuZmluZChcbiAgICAgIEdyYXBoUUxDb25maWdDbGFzc05hbWUsXG4gICAgICB7IG9iamVjdElkOiBHcmFwaFFMQ29uZmlnSWQgfSxcbiAgICAgIHsgbGltaXQ6IDEgfVxuICAgICk7XG5cbiAgICBsZXQgZ3JhcGhRTENvbmZpZztcbiAgICBpZiAocmVzdWx0cy5sZW5ndGggIT0gMSkge1xuICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gY29uZmlnIGluIHRoZSBkYXRhYmFzZSAtIHJldHVybiBlbXB0eSBjb25maWcuXG4gICAgICByZXR1cm4ge307XG4gICAgfSBlbHNlIHtcbiAgICAgIGdyYXBoUUxDb25maWcgPSByZXN1bHRzWzBdW0dyYXBoUUxDb25maWdLZXldO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzTW91bnRlZCkge1xuICAgICAgdGhpcy5fcHV0Q2FjaGVkR3JhcGhRTENvbmZpZyhncmFwaFFMQ29uZmlnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZ3JhcGhRTENvbmZpZztcbiAgfVxuXG4gIGFzeW5jIHVwZGF0ZUdyYXBoUUxDb25maWcoZ3JhcGhRTENvbmZpZzogUGFyc2VHcmFwaFFMQ29uZmlnKTogUHJvbWlzZTxQYXJzZUdyYXBoUUxDb25maWc+IHtcbiAgICAvLyB0aHJvd3MgaWYgaW52YWxpZFxuICAgIHRoaXMuX3ZhbGlkYXRlR3JhcGhRTENvbmZpZyhcbiAgICAgIGdyYXBoUUxDb25maWcgfHwgcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYSBncmFwaFFMQ29uZmlnIScpXG4gICAgKTtcblxuICAgIC8vIFRyYW5zZm9ybSBpbiBkb3Qgbm90YXRpb24gdG8gbWFrZSBzdXJlIGl0IHdvcmtzXG4gICAgY29uc3QgdXBkYXRlID0gT2JqZWN0LmtleXMoZ3JhcGhRTENvbmZpZykucmVkdWNlKFxuICAgICAgKGFjYywga2V5KSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgW0dyYXBoUUxDb25maWdLZXldOiB7XG4gICAgICAgICAgICAuLi5hY2NbR3JhcGhRTENvbmZpZ0tleV0sXG4gICAgICAgICAgICBba2V5XTogZ3JhcGhRTENvbmZpZ1trZXldLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgICAgeyBbR3JhcGhRTENvbmZpZ0tleV06IHt9IH1cbiAgICApO1xuXG4gICAgYXdhaXQgdGhpcy5kYXRhYmFzZUNvbnRyb2xsZXIudXBkYXRlKFxuICAgICAgR3JhcGhRTENvbmZpZ0NsYXNzTmFtZSxcbiAgICAgIHsgb2JqZWN0SWQ6IEdyYXBoUUxDb25maWdJZCB9LFxuICAgICAgdXBkYXRlLFxuICAgICAgeyB1cHNlcnQ6IHRydWUgfVxuICAgICk7XG5cbiAgICBpZiAodGhpcy5pc01vdW50ZWQpIHtcbiAgICAgIHRoaXMuX3B1dENhY2hlZEdyYXBoUUxDb25maWcoZ3JhcGhRTENvbmZpZyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgcmVzcG9uc2U6IHsgcmVzdWx0OiB0cnVlIH0gfTtcbiAgfVxuXG4gIF9nZXRDYWNoZWRHcmFwaFFMQ29uZmlnKCkge1xuICAgIHJldHVybiB0aGlzLmNhY2hlQ29udHJvbGxlci5ncmFwaFFMLmdldCh0aGlzLmNvbmZpZ0NhY2hlS2V5KTtcbiAgfVxuXG4gIF9wdXRDYWNoZWRHcmFwaFFMQ29uZmlnKGdyYXBoUUxDb25maWc6IFBhcnNlR3JhcGhRTENvbmZpZykge1xuICAgIHJldHVybiB0aGlzLmNhY2hlQ29udHJvbGxlci5ncmFwaFFMLnB1dCh0aGlzLmNvbmZpZ0NhY2hlS2V5LCBncmFwaFFMQ29uZmlnLCA2MDAwMCk7XG4gIH1cblxuICBfdmFsaWRhdGVHcmFwaFFMQ29uZmlnKGdyYXBoUUxDb25maWc6ID9QYXJzZUdyYXBoUUxDb25maWcpOiB2b2lkIHtcbiAgICBjb25zdCBlcnJvck1lc3NhZ2VzOiBzdHJpbmcgPSBbXTtcbiAgICBpZiAoIWdyYXBoUUxDb25maWcpIHtcbiAgICAgIGVycm9yTWVzc2FnZXMucHVzaCgnY2Fubm90IGJlIHVuZGVmaW5lZCwgbnVsbCBvciBlbXB0eScpO1xuICAgIH0gZWxzZSBpZiAoIWlzVmFsaWRTaW1wbGVPYmplY3QoZ3JhcGhRTENvbmZpZykpIHtcbiAgICAgIGVycm9yTWVzc2FnZXMucHVzaCgnbXVzdCBiZSBhIHZhbGlkIG9iamVjdCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB7XG4gICAgICAgIGVuYWJsZWRGb3JDbGFzc2VzID0gbnVsbCxcbiAgICAgICAgZGlzYWJsZWRGb3JDbGFzc2VzID0gbnVsbCxcbiAgICAgICAgY2xhc3NDb25maWdzID0gbnVsbCxcbiAgICAgICAgLi4uaW52YWxpZEtleXNcbiAgICAgIH0gPSBncmFwaFFMQ29uZmlnO1xuXG4gICAgICBpZiAoT2JqZWN0LmtleXMoaW52YWxpZEtleXMpLmxlbmd0aCkge1xuICAgICAgICBlcnJvck1lc3NhZ2VzLnB1c2goYGVuY291bnRlcmVkIGludmFsaWQga2V5czogWyR7T2JqZWN0LmtleXMoaW52YWxpZEtleXMpfV1gKTtcbiAgICAgIH1cbiAgICAgIGlmIChlbmFibGVkRm9yQ2xhc3NlcyAhPT0gbnVsbCAmJiAhaXNWYWxpZFN0cmluZ0FycmF5KGVuYWJsZWRGb3JDbGFzc2VzKSkge1xuICAgICAgICBlcnJvck1lc3NhZ2VzLnB1c2goYFwiZW5hYmxlZEZvckNsYXNzZXNcIiBpcyBub3QgYSB2YWxpZCBhcnJheWApO1xuICAgICAgfVxuICAgICAgaWYgKGRpc2FibGVkRm9yQ2xhc3NlcyAhPT0gbnVsbCAmJiAhaXNWYWxpZFN0cmluZ0FycmF5KGRpc2FibGVkRm9yQ2xhc3NlcykpIHtcbiAgICAgICAgZXJyb3JNZXNzYWdlcy5wdXNoKGBcImRpc2FibGVkRm9yQ2xhc3Nlc1wiIGlzIG5vdCBhIHZhbGlkIGFycmF5YCk7XG4gICAgICB9XG4gICAgICBpZiAoY2xhc3NDb25maWdzICE9PSBudWxsKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGNsYXNzQ29uZmlncykpIHtcbiAgICAgICAgICBjbGFzc0NvbmZpZ3MuZm9yRWFjaChjbGFzc0NvbmZpZyA9PiB7XG4gICAgICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSB0aGlzLl92YWxpZGF0ZUNsYXNzQ29uZmlnKGNsYXNzQ29uZmlnKTtcbiAgICAgICAgICAgIGlmIChlcnJvck1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlcy5wdXNoKFxuICAgICAgICAgICAgICAgIGBjbGFzc0NvbmZpZzoke2NsYXNzQ29uZmlnLmNsYXNzTmFtZX0gaXMgaW52YWxpZCBiZWNhdXNlICR7ZXJyb3JNZXNzYWdlfWBcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBlcnJvck1lc3NhZ2VzLnB1c2goYFwiY2xhc3NDb25maWdzXCIgaXMgbm90IGEgdmFsaWQgYXJyYXlgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZXJyb3JNZXNzYWdlcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBncmFwaFFMQ29uZmlnOiAke2Vycm9yTWVzc2FnZXMuam9pbignOyAnKX1gKTtcbiAgICB9XG4gIH1cblxuICBfdmFsaWRhdGVDbGFzc0NvbmZpZyhjbGFzc0NvbmZpZzogP1BhcnNlR3JhcGhRTENsYXNzQ29uZmlnKTogc3RyaW5nIHwgdm9pZCB7XG4gICAgaWYgKCFpc1ZhbGlkU2ltcGxlT2JqZWN0KGNsYXNzQ29uZmlnKSkge1xuICAgICAgcmV0dXJuICdpdCBtdXN0IGJlIGEgdmFsaWQgb2JqZWN0JztcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgeyBjbGFzc05hbWUsIHR5cGUgPSBudWxsLCBxdWVyeSA9IG51bGwsIG11dGF0aW9uID0gbnVsbCwgLi4uaW52YWxpZEtleXMgfSA9IGNsYXNzQ29uZmlnO1xuICAgICAgaWYgKE9iamVjdC5rZXlzKGludmFsaWRLZXlzKS5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIGBcImludmFsaWRLZXlzXCIgWyR7T2JqZWN0LmtleXMoaW52YWxpZEtleXMpfV0gc2hvdWxkIG5vdCBiZSBwcmVzZW50YDtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgY2xhc3NOYW1lICE9PSAnc3RyaW5nJyB8fCAhY2xhc3NOYW1lLnRyaW0oKS5sZW5ndGgpIHtcbiAgICAgICAgLy8gVE9ETyBjb25zaWRlciBjaGVja2luZyBjbGFzcyBleGlzdHMgaW4gc2NoZW1hP1xuICAgICAgICByZXR1cm4gYFwiY2xhc3NOYW1lXCIgbXVzdCBiZSBhIHZhbGlkIHN0cmluZ2A7XG4gICAgICB9XG4gICAgICBpZiAodHlwZSAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoIWlzVmFsaWRTaW1wbGVPYmplY3QodHlwZSkpIHtcbiAgICAgICAgICByZXR1cm4gYFwidHlwZVwiIG11c3QgYmUgYSB2YWxpZCBvYmplY3RgO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHtcbiAgICAgICAgICBpbnB1dEZpZWxkcyA9IG51bGwsXG4gICAgICAgICAgb3V0cHV0RmllbGRzID0gbnVsbCxcbiAgICAgICAgICBjb25zdHJhaW50RmllbGRzID0gbnVsbCxcbiAgICAgICAgICBzb3J0RmllbGRzID0gbnVsbCxcbiAgICAgICAgICAuLi5pbnZhbGlkS2V5c1xuICAgICAgICB9ID0gdHlwZTtcbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKGludmFsaWRLZXlzKS5sZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm4gYFwidHlwZVwiIGNvbnRhaW5zIGludmFsaWQga2V5cywgWyR7T2JqZWN0LmtleXMoaW52YWxpZEtleXMpfV1gO1xuICAgICAgICB9IGVsc2UgaWYgKG91dHB1dEZpZWxkcyAhPT0gbnVsbCAmJiAhaXNWYWxpZFN0cmluZ0FycmF5KG91dHB1dEZpZWxkcykpIHtcbiAgICAgICAgICByZXR1cm4gYFwib3V0cHV0RmllbGRzXCIgbXVzdCBiZSBhIHZhbGlkIHN0cmluZyBhcnJheWA7XG4gICAgICAgIH0gZWxzZSBpZiAoY29uc3RyYWludEZpZWxkcyAhPT0gbnVsbCAmJiAhaXNWYWxpZFN0cmluZ0FycmF5KGNvbnN0cmFpbnRGaWVsZHMpKSB7XG4gICAgICAgICAgcmV0dXJuIGBcImNvbnN0cmFpbnRGaWVsZHNcIiBtdXN0IGJlIGEgdmFsaWQgc3RyaW5nIGFycmF5YDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc29ydEZpZWxkcyAhPT0gbnVsbCkge1xuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHNvcnRGaWVsZHMpKSB7XG4gICAgICAgICAgICBsZXQgZXJyb3JNZXNzYWdlO1xuICAgICAgICAgICAgc29ydEZpZWxkcy5ldmVyeSgoc29ydEZpZWxkLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICBpZiAoIWlzVmFsaWRTaW1wbGVPYmplY3Qoc29ydEZpZWxkKSkge1xuICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGBcInNvcnRGaWVsZFwiIGF0IGluZGV4ICR7aW5kZXh9IGlzIG5vdCBhIHZhbGlkIG9iamVjdGA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgZmllbGQsIGFzYywgZGVzYywgLi4uaW52YWxpZEtleXMgfSA9IHNvcnRGaWVsZDtcbiAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXMoaW52YWxpZEtleXMpLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gYFwic29ydEZpZWxkXCIgYXQgaW5kZXggJHtpbmRleH0gY29udGFpbnMgaW52YWxpZCBrZXlzLCBbJHtPYmplY3Qua2V5cyhcbiAgICAgICAgICAgICAgICAgICAgaW52YWxpZEtleXNcbiAgICAgICAgICAgICAgICAgICl9XWA7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZmllbGQgIT09ICdzdHJpbmcnIHx8IGZpZWxkLnRyaW0oKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gYFwic29ydEZpZWxkXCIgYXQgaW5kZXggJHtpbmRleH0gZGlkIG5vdCBwcm92aWRlIHRoZSBcImZpZWxkXCIgYXMgYSBzdHJpbmdgO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBhc2MgIT09ICdib29sZWFuJyB8fCB0eXBlb2YgZGVzYyAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGBcInNvcnRGaWVsZFwiIGF0IGluZGV4ICR7aW5kZXh9IGRpZCBub3QgcHJvdmlkZSBcImFzY1wiIG9yIFwiZGVzY1wiIGFzIGJvb2xlYW5zYDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKGVycm9yTWVzc2FnZSkge1xuICAgICAgICAgICAgICByZXR1cm4gZXJyb3JNZXNzYWdlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gYFwic29ydEZpZWxkc1wiIG11c3QgYmUgYSB2YWxpZCBhcnJheS5gO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoaW5wdXRGaWVsZHMgIT09IG51bGwpIHtcbiAgICAgICAgICBpZiAoaXNWYWxpZFNpbXBsZU9iamVjdChpbnB1dEZpZWxkcykpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgY3JlYXRlID0gbnVsbCwgdXBkYXRlID0gbnVsbCwgLi4uaW52YWxpZEtleXMgfSA9IGlucHV0RmllbGRzO1xuICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKGludmFsaWRLZXlzKS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGBcImlucHV0RmllbGRzXCIgY29udGFpbnMgaW52YWxpZCBrZXlzOiBbJHtPYmplY3Qua2V5cyhpbnZhbGlkS2V5cyl9XWA7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpZiAodXBkYXRlICE9PSBudWxsICYmICFpc1ZhbGlkU3RyaW5nQXJyYXkodXBkYXRlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBgXCJpbnB1dEZpZWxkcy51cGRhdGVcIiBtdXN0IGJlIGEgdmFsaWQgc3RyaW5nIGFycmF5YDtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChjcmVhdGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWlzVmFsaWRTdHJpbmdBcnJheShjcmVhdGUpKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gYFwiaW5wdXRGaWVsZHMuY3JlYXRlXCIgbXVzdCBiZSBhIHZhbGlkIHN0cmluZyBhcnJheWA7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICAgICAgICAgICAgICAgIGlmICghY3JlYXRlLmluY2x1ZGVzKCd1c2VybmFtZScpIHx8ICFjcmVhdGUuaW5jbHVkZXMoJ3Bhc3N3b3JkJykpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcImlucHV0RmllbGRzLmNyZWF0ZVwiIG11c3QgaW5jbHVkZSByZXF1aXJlZCBmaWVsZHMsIHVzZXJuYW1lIGFuZCBwYXNzd29yZGA7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBgXCJpbnB1dEZpZWxkc1wiIG11c3QgYmUgYSB2YWxpZCBvYmplY3RgO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHF1ZXJ5ICE9PSBudWxsKSB7XG4gICAgICAgIGlmIChpc1ZhbGlkU2ltcGxlT2JqZWN0KHF1ZXJ5KSkge1xuICAgICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgIGZpbmQgPSBudWxsLFxuICAgICAgICAgICAgZ2V0ID0gbnVsbCxcbiAgICAgICAgICAgIGZpbmRBbGlhcyA9IG51bGwsXG4gICAgICAgICAgICBnZXRBbGlhcyA9IG51bGwsXG4gICAgICAgICAgICAuLi5pbnZhbGlkS2V5c1xuICAgICAgICAgIH0gPSBxdWVyeTtcbiAgICAgICAgICBpZiAoT2JqZWN0LmtleXMoaW52YWxpZEtleXMpLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGBcInF1ZXJ5XCIgY29udGFpbnMgaW52YWxpZCBrZXlzLCBbJHtPYmplY3Qua2V5cyhpbnZhbGlkS2V5cyl9XWA7XG4gICAgICAgICAgfSBlbHNlIGlmIChmaW5kICE9PSBudWxsICYmIHR5cGVvZiBmaW5kICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIHJldHVybiBgXCJxdWVyeS5maW5kXCIgbXVzdCBiZSBhIGJvb2xlYW5gO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZ2V0ICE9PSBudWxsICYmIHR5cGVvZiBnZXQgIT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgcmV0dXJuIGBcInF1ZXJ5LmdldFwiIG11c3QgYmUgYSBib29sZWFuYDtcbiAgICAgICAgICB9IGVsc2UgaWYgKGZpbmRBbGlhcyAhPT0gbnVsbCAmJiB0eXBlb2YgZmluZEFsaWFzICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGBcInF1ZXJ5LmZpbmRBbGlhc1wiIG11c3QgYmUgYSBzdHJpbmdgO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZ2V0QWxpYXMgIT09IG51bGwgJiYgdHlwZW9mIGdldEFsaWFzICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGBcInF1ZXJ5LmdldEFsaWFzXCIgbXVzdCBiZSBhIHN0cmluZ2A7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBgXCJxdWVyeVwiIG11c3QgYmUgYSB2YWxpZCBvYmplY3RgO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobXV0YXRpb24gIT09IG51bGwpIHtcbiAgICAgICAgaWYgKGlzVmFsaWRTaW1wbGVPYmplY3QobXV0YXRpb24pKSB7XG4gICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgY3JlYXRlID0gbnVsbCxcbiAgICAgICAgICAgIHVwZGF0ZSA9IG51bGwsXG4gICAgICAgICAgICBkZXN0cm95ID0gbnVsbCxcbiAgICAgICAgICAgIGNyZWF0ZUFsaWFzID0gbnVsbCxcbiAgICAgICAgICAgIHVwZGF0ZUFsaWFzID0gbnVsbCxcbiAgICAgICAgICAgIGRlc3Ryb3lBbGlhcyA9IG51bGwsXG4gICAgICAgICAgICAuLi5pbnZhbGlkS2V5c1xuICAgICAgICAgIH0gPSBtdXRhdGlvbjtcbiAgICAgICAgICBpZiAoT2JqZWN0LmtleXMoaW52YWxpZEtleXMpLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGBcIm11dGF0aW9uXCIgY29udGFpbnMgaW52YWxpZCBrZXlzLCBbJHtPYmplY3Qua2V5cyhpbnZhbGlkS2V5cyl9XWA7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChjcmVhdGUgIT09IG51bGwgJiYgdHlwZW9mIGNyZWF0ZSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwibXV0YXRpb24uY3JlYXRlXCIgbXVzdCBiZSBhIGJvb2xlYW5gO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodXBkYXRlICE9PSBudWxsICYmIHR5cGVvZiB1cGRhdGUgIT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgcmV0dXJuIGBcIm11dGF0aW9uLnVwZGF0ZVwiIG11c3QgYmUgYSBib29sZWFuYDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGRlc3Ryb3kgIT09IG51bGwgJiYgdHlwZW9mIGRlc3Ryb3kgIT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgcmV0dXJuIGBcIm11dGF0aW9uLmRlc3Ryb3lcIiBtdXN0IGJlIGEgYm9vbGVhbmA7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChjcmVhdGVBbGlhcyAhPT0gbnVsbCAmJiB0eXBlb2YgY3JlYXRlQWxpYXMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwibXV0YXRpb24uY3JlYXRlQWxpYXNcIiBtdXN0IGJlIGEgc3RyaW5nYDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHVwZGF0ZUFsaWFzICE9PSBudWxsICYmIHR5cGVvZiB1cGRhdGVBbGlhcyAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBgXCJtdXRhdGlvbi51cGRhdGVBbGlhc1wiIG11c3QgYmUgYSBzdHJpbmdgO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZGVzdHJveUFsaWFzICE9PSBudWxsICYmIHR5cGVvZiBkZXN0cm95QWxpYXMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwibXV0YXRpb24uZGVzdHJveUFsaWFzXCIgbXVzdCBiZSBhIHN0cmluZ2A7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBgXCJtdXRhdGlvblwiIG11c3QgYmUgYSB2YWxpZCBvYmplY3RgO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmNvbnN0IGlzVmFsaWRTdHJpbmdBcnJheSA9IGZ1bmN0aW9uIChhcnJheSk6IGJvb2xlYW4ge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheShhcnJheSlcbiAgICA/ICFhcnJheS5zb21lKHMgPT4gdHlwZW9mIHMgIT09ICdzdHJpbmcnIHx8IHMudHJpbSgpLmxlbmd0aCA8IDEpXG4gICAgOiBmYWxzZTtcbn07XG4vKipcbiAqIEVuc3VyZXMgdGhlIG9iaiBpcyBhIHNpbXBsZSBKU09OL3t9XG4gKiBvYmplY3QsIGkuZS4gbm90IGFuIGFycmF5LCBudWxsLCBkYXRlXG4gKiBldGMuXG4gKi9cbmNvbnN0IGlzVmFsaWRTaW1wbGVPYmplY3QgPSBmdW5jdGlvbiAob2JqKTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgdHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiZcbiAgICAhQXJyYXkuaXNBcnJheShvYmopICYmXG4gICAgb2JqICE9PSBudWxsICYmXG4gICAgb2JqIGluc3RhbmNlb2YgRGF0ZSAhPT0gdHJ1ZSAmJlxuICAgIG9iaiBpbnN0YW5jZW9mIFByb21pc2UgIT09IHRydWVcbiAgKTtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFyc2VHcmFwaFFMQ29uZmlnIHtcbiAgZW5hYmxlZEZvckNsYXNzZXM/OiBzdHJpbmdbXTtcbiAgZGlzYWJsZWRGb3JDbGFzc2VzPzogc3RyaW5nW107XG4gIGNsYXNzQ29uZmlncz86IFBhcnNlR3JhcGhRTENsYXNzQ29uZmlnW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFyc2VHcmFwaFFMQ2xhc3NDb25maWcge1xuICBjbGFzc05hbWU6IHN0cmluZztcbiAgLyogVGhlIGB0eXBlYCBvYmplY3QgY29udGFpbnMgb3B0aW9ucyBmb3IgaG93IHRoZSBjbGFzcyB0eXBlcyBhcmUgZ2VuZXJhdGVkICovXG4gIHR5cGU6ID97XG4gICAgLyogRmllbGRzIHRoYXQgYXJlIGFsbG93ZWQgd2hlbiBjcmVhdGluZyBvciB1cGRhdGluZyBhbiBvYmplY3QuICovXG4gICAgaW5wdXRGaWVsZHM6ID97XG4gICAgICAvKiBMZWF2ZSBibGFuayB0byBhbGxvdyBhbGwgYXZhaWxhYmxlIGZpZWxkcyBpbiB0aGUgc2NoZW1hLiAqL1xuICAgICAgY3JlYXRlPzogc3RyaW5nW10sXG4gICAgICB1cGRhdGU/OiBzdHJpbmdbXSxcbiAgICB9LFxuICAgIC8qIEZpZWxkcyBvbiB0aGUgZWRnZXMgdGhhdCBjYW4gYmUgcmVzb2x2ZWQgZnJvbSBhIHF1ZXJ5LCBpLmUuIHRoZSBSZXN1bHQgVHlwZS4gKi9cbiAgICBvdXRwdXRGaWVsZHM6ID8oc3RyaW5nW10pLFxuICAgIC8qIEZpZWxkcyBieSB3aGljaCBhIHF1ZXJ5IGNhbiBiZSBmaWx0ZXJlZCwgaS5lLiB0aGUgYHdoZXJlYCBvYmplY3QuICovXG4gICAgY29uc3RyYWludEZpZWxkczogPyhzdHJpbmdbXSksXG4gICAgLyogRmllbGRzIGJ5IHdoaWNoIGEgcXVlcnkgY2FuIGJlIHNvcnRlZDsgKi9cbiAgICBzb3J0RmllbGRzOiA/KHtcbiAgICAgIGZpZWxkOiBzdHJpbmcsXG4gICAgICBhc2M6IGJvb2xlYW4sXG4gICAgICBkZXNjOiBib29sZWFuLFxuICAgIH1bXSksXG4gIH07XG4gIC8qIFRoZSBgcXVlcnlgIG9iamVjdCBjb250YWlucyBvcHRpb25zIGZvciB3aGljaCBjbGFzcyBxdWVyaWVzIGFyZSBnZW5lcmF0ZWQgKi9cbiAgcXVlcnk6ID97XG4gICAgZ2V0OiA/Ym9vbGVhbixcbiAgICBmaW5kOiA/Ym9vbGVhbixcbiAgICBmaW5kQWxpYXM6ID9TdHJpbmcsXG4gICAgZ2V0QWxpYXM6ID9TdHJpbmcsXG4gIH07XG4gIC8qIFRoZSBgbXV0YXRpb25gIG9iamVjdCBjb250YWlucyBvcHRpb25zIGZvciB3aGljaCBjbGFzcyBtdXRhdGlvbnMgYXJlIGdlbmVyYXRlZCAqL1xuICBtdXRhdGlvbjogP3tcbiAgICBjcmVhdGU6ID9ib29sZWFuLFxuICAgIHVwZGF0ZTogP2Jvb2xlYW4sXG4gICAgLy8gZGVsZXRlIGlzIGEgcmVzZXJ2ZWQga2V5IHdvcmQgaW4ganNcbiAgICBkZXN0cm95OiA/Ym9vbGVhbixcbiAgICBjcmVhdGVBbGlhczogP1N0cmluZyxcbiAgICB1cGRhdGVBbGlhczogP1N0cmluZyxcbiAgICBkZXN0cm95QWxpYXM6ID9TdHJpbmcsXG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBhcnNlR3JhcGhRTENvbnRyb2xsZXI7XG5leHBvcnQgeyBHcmFwaFFMQ29uZmlnQ2xhc3NOYW1lLCBHcmFwaFFMQ29uZmlnSWQsIEdyYXBoUUxDb25maWdLZXkgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/PushController.js b/lib/Controllers/PushController.js new file mode 100644 index 0000000000..e1608934b3 --- /dev/null +++ b/lib/Controllers/PushController.js @@ -0,0 +1,257 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.PushController = void 0; + +var _node = require("parse/node"); + +var _RestQuery = _interopRequireDefault(require("../RestQuery")); + +var _RestWrite = _interopRequireDefault(require("../RestWrite")); + +var _Auth = require("../Auth"); + +var _StatusHandler = require("../StatusHandler"); + +var _utils = require("../Push/utils"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class PushController { + sendPush(body = {}, where = {}, config, auth, onPushStatusSaved = () => {}, now = new Date()) { + if (!config.hasPushSupport) { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Missing push configuration'); + } // Replace the expiration_time and push_time with a valid Unix epoch milliseconds time + + + body.expiration_time = PushController.getExpirationTime(body); + body.expiration_interval = PushController.getExpirationInterval(body); + + if (body.expiration_time && body.expiration_interval) { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Both expiration_time and expiration_interval cannot be set'); + } // Immediate push + + + if (body.expiration_interval && !Object.prototype.hasOwnProperty.call(body, 'push_time')) { + const ttlMs = body.expiration_interval * 1000; + body.expiration_time = new Date(now.valueOf() + ttlMs).valueOf(); + } + + const pushTime = PushController.getPushTime(body); + + if (pushTime && pushTime.date !== 'undefined') { + body['push_time'] = PushController.formatPushTime(pushTime); + } // TODO: If the req can pass the checking, we return immediately instead of waiting + // pushes to be sent. We probably change this behaviour in the future. + + + let badgeUpdate = () => { + return Promise.resolve(); + }; + + if (body.data && body.data.badge) { + const badge = body.data.badge; + let restUpdate = {}; + + if (typeof badge == 'string' && badge.toLowerCase() === 'increment') { + restUpdate = { + badge: { + __op: 'Increment', + amount: 1 + } + }; + } else if (typeof badge == 'object' && typeof badge.__op == 'string' && badge.__op.toLowerCase() == 'increment' && Number(badge.amount)) { + restUpdate = { + badge: { + __op: 'Increment', + amount: badge.amount + } + }; + } else if (Number(badge)) { + restUpdate = { + badge: badge + }; + } else { + throw "Invalid value for badge, expected number or 'Increment' or {increment: number}"; + } // Force filtering on only valid device tokens + + + const updateWhere = (0, _utils.applyDeviceTokenExists)(where); + + badgeUpdate = () => { + // Build a real RestQuery so we can use it in RestWrite + const restQuery = new _RestQuery.default(config, (0, _Auth.master)(config), '_Installation', updateWhere); + return restQuery.buildRestWhere().then(() => { + const write = new _RestWrite.default(config, (0, _Auth.master)(config), '_Installation', restQuery.restWhere, restUpdate); + write.runOptions.many = true; + return write.execute(); + }); + }; + } + + const pushStatus = (0, _StatusHandler.pushStatusHandler)(config); + return Promise.resolve().then(() => { + return pushStatus.setInitial(body, where); + }).then(() => { + onPushStatusSaved(pushStatus.objectId); + return badgeUpdate(); + }).then(() => { + // Update audience lastUsed and timesUsed + if (body.audience_id) { + const audienceId = body.audience_id; + var updateAudience = { + lastUsed: { + __type: 'Date', + iso: new Date().toISOString() + }, + timesUsed: { + __op: 'Increment', + amount: 1 + } + }; + const write = new _RestWrite.default(config, (0, _Auth.master)(config), '_Audience', { + objectId: audienceId + }, updateAudience); + write.execute(); + } // Don't wait for the audience update promise to resolve. + + + return Promise.resolve(); + }).then(() => { + if (Object.prototype.hasOwnProperty.call(body, 'push_time') && config.hasPushScheduledSupport) { + return Promise.resolve(); + } + + return config.pushControllerQueue.enqueue(body, where, config, auth, pushStatus); + }).catch(err => { + return pushStatus.fail(err).then(() => { + throw err; + }); + }); + } + /** + * Get expiration time from the request body. + * @param {Object} request A request object + * @returns {Number|undefined} The expiration time if it exists in the request + */ + + + static getExpirationTime(body = {}) { + var hasExpirationTime = Object.prototype.hasOwnProperty.call(body, 'expiration_time'); + + if (!hasExpirationTime) { + return; + } + + var expirationTimeParam = body['expiration_time']; + var expirationTime; + + if (typeof expirationTimeParam === 'number') { + expirationTime = new Date(expirationTimeParam * 1000); + } else if (typeof expirationTimeParam === 'string') { + expirationTime = new Date(expirationTimeParam); + } else { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['expiration_time'] + ' is not valid time.'); + } // Check expirationTime is valid or not, if it is not valid, expirationTime is NaN + + + if (!isFinite(expirationTime)) { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['expiration_time'] + ' is not valid time.'); + } + + return expirationTime.valueOf(); + } + + static getExpirationInterval(body = {}) { + const hasExpirationInterval = Object.prototype.hasOwnProperty.call(body, 'expiration_interval'); + + if (!hasExpirationInterval) { + return; + } + + var expirationIntervalParam = body['expiration_interval']; + + if (typeof expirationIntervalParam !== 'number' || expirationIntervalParam <= 0) { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, `expiration_interval must be a number greater than 0`); + } + + return expirationIntervalParam; + } + /** + * Get push time from the request body. + * @param {Object} request A request object + * @returns {Number|undefined} The push time if it exists in the request + */ + + + static getPushTime(body = {}) { + var hasPushTime = Object.prototype.hasOwnProperty.call(body, 'push_time'); + + if (!hasPushTime) { + return; + } + + var pushTimeParam = body['push_time']; + var date; + var isLocalTime = true; + + if (typeof pushTimeParam === 'number') { + date = new Date(pushTimeParam * 1000); + } else if (typeof pushTimeParam === 'string') { + isLocalTime = !PushController.pushTimeHasTimezoneComponent(pushTimeParam); + date = new Date(pushTimeParam); + } else { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['push_time'] + ' is not valid time.'); + } // Check pushTime is valid or not, if it is not valid, pushTime is NaN + + + if (!isFinite(date)) { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['push_time'] + ' is not valid time.'); + } + + return { + date, + isLocalTime + }; + } + /** + * Checks if a ISO8601 formatted date contains a timezone component + * @param pushTimeParam {string} + * @returns {boolean} + */ + + + static pushTimeHasTimezoneComponent(pushTimeParam) { + const offsetPattern = /(.+)([+-])\d\d:\d\d$/; + return pushTimeParam.indexOf('Z') === pushTimeParam.length - 1 || offsetPattern.test(pushTimeParam) // 2007-04-05T12:30Z + ; // 2007-04-05T12:30.000+02:00, 2007-04-05T12:30.000-02:00 + } + /** + * Converts a date to ISO format in UTC time and strips the timezone if `isLocalTime` is true + * @param date {Date} + * @param isLocalTime {boolean} + * @returns {string} + */ + + + static formatPushTime({ + date, + isLocalTime + }) { + if (isLocalTime) { + // Strip 'Z' + const isoString = date.toISOString(); + return isoString.substring(0, isoString.indexOf('Z')); + } + + return date.toISOString(); + } + +} + +exports.PushController = PushController; +var _default = PushController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9QdXNoQ29udHJvbGxlci5qcyJdLCJuYW1lcyI6WyJQdXNoQ29udHJvbGxlciIsInNlbmRQdXNoIiwiYm9keSIsIndoZXJlIiwiY29uZmlnIiwiYXV0aCIsIm9uUHVzaFN0YXR1c1NhdmVkIiwibm93IiwiRGF0ZSIsImhhc1B1c2hTdXBwb3J0IiwiUGFyc2UiLCJFcnJvciIsIlBVU0hfTUlTQ09ORklHVVJFRCIsImV4cGlyYXRpb25fdGltZSIsImdldEV4cGlyYXRpb25UaW1lIiwiZXhwaXJhdGlvbl9pbnRlcnZhbCIsImdldEV4cGlyYXRpb25JbnRlcnZhbCIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInR0bE1zIiwidmFsdWVPZiIsInB1c2hUaW1lIiwiZ2V0UHVzaFRpbWUiLCJkYXRlIiwiZm9ybWF0UHVzaFRpbWUiLCJiYWRnZVVwZGF0ZSIsIlByb21pc2UiLCJyZXNvbHZlIiwiZGF0YSIsImJhZGdlIiwicmVzdFVwZGF0ZSIsInRvTG93ZXJDYXNlIiwiX19vcCIsImFtb3VudCIsIk51bWJlciIsInVwZGF0ZVdoZXJlIiwicmVzdFF1ZXJ5IiwiUmVzdFF1ZXJ5IiwiYnVpbGRSZXN0V2hlcmUiLCJ0aGVuIiwid3JpdGUiLCJSZXN0V3JpdGUiLCJyZXN0V2hlcmUiLCJydW5PcHRpb25zIiwibWFueSIsImV4ZWN1dGUiLCJwdXNoU3RhdHVzIiwic2V0SW5pdGlhbCIsIm9iamVjdElkIiwiYXVkaWVuY2VfaWQiLCJhdWRpZW5jZUlkIiwidXBkYXRlQXVkaWVuY2UiLCJsYXN0VXNlZCIsIl9fdHlwZSIsImlzbyIsInRvSVNPU3RyaW5nIiwidGltZXNVc2VkIiwiaGFzUHVzaFNjaGVkdWxlZFN1cHBvcnQiLCJwdXNoQ29udHJvbGxlclF1ZXVlIiwiZW5xdWV1ZSIsImNhdGNoIiwiZXJyIiwiZmFpbCIsImhhc0V4cGlyYXRpb25UaW1lIiwiZXhwaXJhdGlvblRpbWVQYXJhbSIsImV4cGlyYXRpb25UaW1lIiwiaXNGaW5pdGUiLCJoYXNFeHBpcmF0aW9uSW50ZXJ2YWwiLCJleHBpcmF0aW9uSW50ZXJ2YWxQYXJhbSIsImhhc1B1c2hUaW1lIiwicHVzaFRpbWVQYXJhbSIsImlzTG9jYWxUaW1lIiwicHVzaFRpbWVIYXNUaW1lem9uZUNvbXBvbmVudCIsIm9mZnNldFBhdHRlcm4iLCJpbmRleE9mIiwibGVuZ3RoIiwidGVzdCIsImlzb1N0cmluZyIsInN1YnN0cmluZyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRU8sTUFBTUEsY0FBTixDQUFxQjtBQUMxQkMsRUFBQUEsUUFBUSxDQUFDQyxJQUFJLEdBQUcsRUFBUixFQUFZQyxLQUFLLEdBQUcsRUFBcEIsRUFBd0JDLE1BQXhCLEVBQWdDQyxJQUFoQyxFQUFzQ0MsaUJBQWlCLEdBQUcsTUFBTSxDQUFFLENBQWxFLEVBQW9FQyxHQUFHLEdBQUcsSUFBSUMsSUFBSixFQUExRSxFQUFzRjtBQUM1RixRQUFJLENBQUNKLE1BQU0sQ0FBQ0ssY0FBWixFQUE0QjtBQUMxQixZQUFNLElBQUlDLFlBQU1DLEtBQVYsQ0FBZ0JELFlBQU1DLEtBQU4sQ0FBWUMsa0JBQTVCLEVBQWdELDRCQUFoRCxDQUFOO0FBQ0QsS0FIMkYsQ0FLNUY7OztBQUNBVixJQUFBQSxJQUFJLENBQUNXLGVBQUwsR0FBdUJiLGNBQWMsQ0FBQ2MsaUJBQWYsQ0FBaUNaLElBQWpDLENBQXZCO0FBQ0FBLElBQUFBLElBQUksQ0FBQ2EsbUJBQUwsR0FBMkJmLGNBQWMsQ0FBQ2dCLHFCQUFmLENBQXFDZCxJQUFyQyxDQUEzQjs7QUFDQSxRQUFJQSxJQUFJLENBQUNXLGVBQUwsSUFBd0JYLElBQUksQ0FBQ2EsbUJBQWpDLEVBQXNEO0FBQ3BELFlBQU0sSUFBSUwsWUFBTUMsS0FBVixDQUNKRCxZQUFNQyxLQUFOLENBQVlDLGtCQURSLEVBRUosNERBRkksQ0FBTjtBQUlELEtBYjJGLENBZTVGOzs7QUFDQSxRQUFJVixJ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SUFBZCxDQUFtQk4sYUFBbkIsQ0FEN0QsQ0FDK0Y7QUFEL0YsS0FGa0UsQ0FJL0Q7QUFDSjtBQUVEO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0UsU0FBTzlDLGNBQVAsQ0FBc0I7QUFBRUQsSUFBQUEsSUFBRjtBQUFRZ0QsSUFBQUE7QUFBUixHQUF0QixFQUFtRjtBQUNqRixRQUFJQSxXQUFKLEVBQWlCO0FBQ2Y7QUFDQSxZQUFNTSxTQUFTLEdBQUd0RCxJQUFJLENBQUNnQyxXQUFMLEVBQWxCO0FBQ0EsYUFBT3NCLFNBQVMsQ0FBQ0MsU0FBVixDQUFvQixDQUFwQixFQUF1QkQsU0FBUyxDQUFDSCxPQUFWLENBQWtCLEdBQWxCLENBQXZCLENBQVA7QUFDRDs7QUFDRCxXQUFPbkQsSUFBSSxDQUFDZ0MsV0FBTCxFQUFQO0FBQ0Q7O0FBbk95Qjs7O2VBc09iekQsYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBhcnNlIH0gZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgUmVzdFF1ZXJ5IGZyb20gJy4uL1Jlc3RRdWVyeSc7XG5pbXBvcnQgUmVzdFdyaXRlIGZyb20gJy4uL1Jlc3RXcml0ZSc7XG5pbXBvcnQgeyBtYXN0ZXIgfSBmcm9tICcuLi9BdXRoJztcbmltcG9ydCB7IHB1c2hTdGF0dXNIYW5kbGVyIH0gZnJvbSAnLi4vU3RhdHVzSGFuZGxlcic7XG5pbXBvcnQgeyBhcHBseURldmljZVRva2VuRXhpc3RzIH0gZnJvbSAnLi4vUHVzaC91dGlscyc7XG5cbmV4cG9ydCBjbGFzcyBQdXNoQ29udHJvbGxlciB7XG4gIHNlbmRQdXNoKGJvZHkgPSB7fSwgd2hlcmUgPSB7fSwgY29uZmlnLCBhdXRoLCBvblB1c2hTdGF0dXNTYXZlZCA9ICgpID0+IHt9LCBub3cgPSBuZXcgRGF0ZSgpKSB7XG4gICAgaWYgKCFjb25maWcuaGFzUHVzaFN1cHBvcnQpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5QVVNIX01JU0NPTkZJR1VSRUQsICdNaXNzaW5nIHB1c2ggY29uZmlndXJhdGlvbicpO1xuICAgIH1cblxuICAgIC8vIFJlcGxhY2UgdGhlIGV4cGlyYXRpb25fdGltZSBhbmQgcHVzaF90aW1lIHdpdGggYSB2YWxpZCBVbml4IGVwb2NoIG1pbGxpc2Vjb25kcyB0aW1lXG4gICAgYm9keS5leHBpcmF0aW9uX3RpbWUgPSBQdXNoQ29udHJvbGxlci5nZXRFeHBpcmF0aW9uVGltZShib2R5KTtcbiAgICBib2R5LmV4cGlyYXRpb25faW50ZXJ2YWwgPSBQdXNoQ29udHJvbGxlci5nZXRFeHBpcmF0aW9uSW50ZXJ2YWwoYm9keSk7XG4gICAgaWYgKGJvZHkuZXhwaXJhdGlvbl90aW1lICYmIGJvZHkuZXhwaXJhdGlvbl9pbnRlcnZhbCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5QVVNIX01JU0NPTkZJR1VSRUQsXG4gICAgICAgICdCb3RoIGV4cGlyYXRpb25fdGltZSBhbmQgZXhwaXJhdGlvbl9pbnRlcnZhbCBjYW5ub3QgYmUgc2V0J1xuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBJbW1lZGlhdGUgcHVzaFxuICAgIGlmIChib2R5LmV4cGlyYXRpb25faW50ZXJ2YWwgJiYgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChib2R5LCAncHVzaF90aW1lJykpIHtcbiAgICAgIGNvbnN0IHR0bE1zID0gYm9keS5leHBpcmF0aW9uX2ludGVydmFsICogMTAwMDtcbiAgICAgIGJvZHkuZXhwaXJhdGlvbl90aW1lID0gbmV3IERhdGUobm93LnZhbHVlT2YoKSArIHR0bE1zKS52YWx1ZU9mKCk7XG4gICAgfVxuXG4gICAgY29uc3QgcHVzaFRpbWUgPSBQdXNoQ29udHJvbGxlci5nZXRQdXNoVGltZShib2R5KTtcbiAgICBpZiAocHVzaFRpbWUgJiYgcHVzaFRpbWUuZGF0ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGJvZHlbJ3B1c2hfdGltZSddID0gUHVzaENvbnRyb2xsZXIuZm9ybWF0UHVzaFRpbWUocHVzaFRpbWUpO1xuICAgIH1cblxuICAgIC8vIFRPRE86IElmIHRoZSByZXEgY2FuIHBhc3MgdGhlIGNoZWNraW5nLCB3ZSByZXR1cm4gaW1tZWRpYXRlbHkgaW5zdGVhZCBvZiB3YWl0aW5nXG4gICAgLy8gcHVzaGVzIHRvIGJlIHNlbnQuIFdlIHByb2JhYmx5IGNoYW5nZSB0aGlzIGJlaGF2aW91ciBpbiB0aGUgZnV0dXJlLlxuICAgIGxldCBiYWRnZVVwZGF0ZSA9ICgpID0+IHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9O1xuXG4gICAgaWYgKGJvZHkuZGF0YSAmJiBib2R5LmRhdGEuYmFkZ2UpIHtcbiAgICAgIGNvbnN0IGJhZGdlID0gYm9keS5kYXRhLmJhZGdlO1xuICAgICAgbGV0IHJlc3RVcGRhdGUgPSB7fTtcbiAgICAgIGlmICh0eXBlb2YgYmFkZ2UgPT0gJ3N0cmluZycgJiYgYmFkZ2UudG9Mb3dlckNhc2UoKSA9PT0gJ2luY3JlbWVudCcpIHtcbiAgICAgICAgcmVzdFVwZGF0ZSA9IHsgYmFkZ2U6IHsgX19vcDogJ0luY3JlbWVudCcsIGFtb3VudDogMSB9IH07XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICB0eXBlb2YgYmFkZ2UgPT0gJ29iamVjdCcgJiZcbiAgICAgICAgdHlwZW9mIGJhZGdlLl9fb3AgPT0gJ3N0cmluZycgJiZcbiAgICAgICAgYmFkZ2UuX19vcC50b0xvd2VyQ2FzZSgpID09ICdpbmNyZW1lbnQnICYmXG4gICAgICAgIE51bWJlcihiYWRnZS5hbW91bnQpXG4gICAgICApIHtcbiAgICAgICAgcmVzdFVwZGF0ZSA9IHsgYmFkZ2U6IHsgX19vcDogJ0luY3JlbWVudCcsIGFtb3VudDogYmFkZ2UuYW1vdW50IH0gfTtcbiAgICAgIH0gZWxzZSBpZiAoTnVtYmVyKGJhZGdlKSkge1xuICAgICAgICByZXN0VXBkYXRlID0geyBiYWRnZTogYmFkZ2UgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IFwiSW52YWxpZCB2YWx1ZSBmb3IgYmFkZ2UsIGV4cGVjdGVkIG51bWJlciBvciAnSW5jcmVtZW50JyBvciB7aW5jcmVtZW50OiBudW1iZXJ9XCI7XG4gICAgICB9XG5cbiAgICAgIC8vIEZvcmNlIGZpbHRlcmluZyBvbiBvbmx5IHZhbGlkIGRldmljZSB0b2tlbnNcbiAgICAgIGNvbnN0IHVwZGF0ZVdoZXJlID0gYXBwbHlEZXZpY2VUb2tlbkV4aXN0cyh3aGVyZSk7XG4gICAgICBiYWRnZVVwZGF0ZSA9ICgpID0+IHtcbiAgICAgICAgLy8gQnVpbGQgYSByZWFsIFJlc3RRdWVyeSBzbyB3ZSBjYW4gdXNlIGl0IGluIFJlc3RXcml0ZVxuICAgICAgICBjb25zdCByZXN0UXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KGNvbmZpZywgbWFzdGVyKGNvbmZpZyksICdfSW5zdGFsbGF0aW9uJywgdXBkYXRlV2hlcmUpO1xuICAgICAgICByZXR1cm4gcmVzdFF1ZXJ5LmJ1aWxkUmVzdFdoZXJlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgY29uc3Qgd3JpdGUgPSBuZXcgUmVzdFdyaXRlKFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgbWFzdGVyKGNvbmZpZyksXG4gICAgICAgICAgICAnX0luc3RhbGxhdGlvbicsXG4gICAgICAgICAgICByZXN0UXVlcnkucmVzdFdoZXJlLFxuICAgICAgICAgICAgcmVzdFVwZGF0ZVxuICAgICAgICAgICk7XG4gICAgICAgICAgd3JpdGUucnVuT3B0aW9ucy5tYW55ID0gdHJ1ZTtcbiAgICAgICAgICByZXR1cm4gd3JpdGUuZXhlY3V0ZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH07XG4gICAgfVxuICAgIGNvbnN0IHB1c2hTdGF0dXMgPSBwdXNoU3RhdHVzSGFuZGxlcihjb25maWcpO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gcHVzaFN0YXR1cy5zZXRJbml0aWFsKGJvZHksIHdoZXJlKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIG9uUHVzaFN0YXR1c1NhdmVkKHB1c2hTdGF0dXMub2JqZWN0SWQpO1xuICAgICAgICByZXR1cm4gYmFkZ2VVcGRhdGUoKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIC8vIFVwZGF0ZSBhdWRpZW5jZSBsYXN0VXNlZCBhbmQgdGltZXNVc2VkXG4gICAgICAgIGlmIChib2R5LmF1ZGllbmNlX2lkKSB7XG4gICAgICAgICAgY29uc3QgYXVkaWVuY2VJZCA9IGJvZHkuYXVkaWVuY2VfaWQ7XG5cbiAgICAgICAgICB2YXIgdXBkYXRlQXVkaWVuY2UgPSB7XG4gICAgICAgICAgICBsYXN0VXNlZDogeyBfX3R5cGU6ICdEYXRlJywgaXNvOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkgfSxcbiAgICAgICAgICAgIHRpbWVzVXNlZDogeyBfX29wOiAnSW5jcmVtZW50JywgYW1vdW50OiAxIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgICBjb25zdCB3cml0ZSA9IG5ldyBSZXN0V3JpdGUoXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBtYXN0ZXIoY29uZmlnKSxcbiAgICAgICAgICAgICdfQXVkaWVuY2UnLFxuICAgICAgICAgICAgeyBvYmplY3RJZDogYXVkaWVuY2VJZCB9LFxuICAgICAgICAgICAgdXBkYXRlQXVkaWVuY2VcbiAgICAgICAgICApO1xuICAgICAgICAgIHdyaXRlLmV4ZWN1dGUoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBEb24ndCB3YWl0IGZvciB0aGUgYXVkaWVuY2UgdXBkYXRlIHByb21pc2UgdG8gcmVzb2x2ZS5cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChib2R5LCAncHVzaF90aW1lJykgJiZcbiAgICAgICAgICBjb25maWcuaGFzUHVzaFNjaGVkdWxlZFN1cHBvcnRcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb25maWcucHVzaENvbnRyb2xsZXJRdWV1ZS5lbnF1ZXVlKGJvZHksIHdoZXJlLCBjb25maWcsIGF1dGgsIHB1c2hTdGF0dXMpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4ge1xuICAgICAgICByZXR1cm4gcHVzaFN0YXR1cy5mYWlsKGVycikudGhlbigoKSA9PiB7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBleHBpcmF0aW9uIHRpbWUgZnJvbSB0aGUgcmVxdWVzdCBib2R5LlxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxdWVzdCBBIHJlcXVlc3Qgb2JqZWN0XG4gICAqIEByZXR1cm5zIHtOdW1iZXJ8dW5kZWZpbmVkfSBUaGUgZXhwaXJhdGlvbiB0aW1lIGlmIGl0IGV4aXN0cyBpbiB0aGUgcmVxdWVzdFxuICAgKi9cbiAgc3RhdGljIGdldEV4cGlyYXRpb25UaW1lKGJvZHkgPSB7fSkge1xuICAgIHZhciBoYXNFeHBpcmF0aW9uVGltZSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChib2R5LCAnZXhwaXJhdGlvbl90aW1lJyk7XG4gICAgaWYgKCFoYXNFeHBpcmF0aW9uVGltZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgZXhwaXJhdGlvblRpbWVQYXJhbSA9IGJvZHlbJ2V4cGlyYXRpb25fdGltZSddO1xuICAgIHZhciBleHBpcmF0aW9uVGltZTtcbiAgICBpZiAodHlwZW9mIGV4cGlyYXRpb25UaW1lUGFyYW0gPT09ICdudW1iZXInKSB7XG4gICAgICBleHBpcmF0aW9uVGltZSA9IG5ldyBEYXRlKGV4cGlyYXRpb25UaW1lUGFyYW0gKiAxMDAwKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBleHBpcmF0aW9uVGltZVBhcmFtID09PSAnc3RyaW5nJykge1xuICAgICAgZXhwaXJhdGlvblRpbWUgPSBuZXcgRGF0ZShleHBpcmF0aW9uVGltZVBhcmFtKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5QVVNIX01JU0NPTkZJR1VSRUQsXG4gICAgICAgIGJvZHlbJ2V4cGlyYXRpb25fdGltZSddICsgJyBpcyBub3QgdmFsaWQgdGltZS4nXG4gICAgICApO1xuICAgIH1cbiAgICAvLyBDaGVjayBleHBpcmF0aW9uVGltZSBpcyB2YWxpZCBvciBub3QsIGlmIGl0IGlzIG5vdCB2YWxpZCwgZXhwaXJhdGlvblRpbWUgaXMgTmFOXG4gICAgaWYgKCFpc0Zpbml0ZShleHBpcmF0aW9uVGltZSkpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICBib2R5WydleHBpcmF0aW9uX3RpbWUnXSArICcgaXMgbm90IHZhbGlkIHRpbWUuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIGV4cGlyYXRpb25UaW1lLnZhbHVlT2YoKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRFeHBpcmF0aW9uSW50ZXJ2YWwoYm9keSA9IHt9KSB7XG4gICAgY29uc3QgaGFzRXhwaXJhdGlvbkludGVydmFsID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGJvZHksICdleHBpcmF0aW9uX2ludGVydmFsJyk7XG4gICAgaWYgKCFoYXNFeHBpcmF0aW9uSW50ZXJ2YWwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgZXhwaXJhdGlvbkludGVydmFsUGFyYW0gPSBib2R5WydleHBpcmF0aW9uX2ludGVydmFsJ107XG4gICAgaWYgKHR5cGVvZiBleHBpcmF0aW9uSW50ZXJ2YWxQYXJhbSAhPT0gJ251bWJlcicgfHwgZXhwaXJhdGlvbkludGVydmFsUGFyYW0gPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5QVVNIX01JU0NPTkZJR1VSRUQsXG4gICAgICAgIGBleHBpcmF0aW9uX2ludGVydmFsIG11c3QgYmUgYSBudW1iZXIgZ3JlYXRlciB0aGFuIDBgXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gZXhwaXJhdGlvbkludGVydmFsUGFyYW07XG4gIH1cblxuICAvKipcbiAgICogR2V0IHB1c2ggdGltZSBmcm9tIHRoZSByZXF1ZXN0IGJvZHkuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSByZXF1ZXN0IEEgcmVxdWVzdCBvYmplY3RcbiAgICogQHJldHVybnMge051bWJlcnx1bmRlZmluZWR9IFRoZSBwdXNoIHRpbWUgaWYgaXQgZXhpc3RzIGluIHRoZSByZXF1ZXN0XG4gICAqL1xuICBzdGF0aWMgZ2V0UHVzaFRpbWUoYm9keSA9IHt9KSB7XG4gICAgdmFyIGhhc1B1c2hUaW1lID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGJvZHksICdwdXNoX3RpbWUnKTtcbiAgICBpZiAoIWhhc1B1c2hUaW1lKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciBwdXNoVGltZVBhcmFtID0gYm9keVsncHVzaF90aW1lJ107XG4gICAgdmFyIGRhdGU7XG4gICAgdmFyIGlzTG9jYWxUaW1lID0gdHJ1ZTtcblxuICAgIGlmICh0eXBlb2YgcHVzaFRpbWVQYXJhbSA9PT0gJ251bWJlcicpIHtcbiAgICAgIGRhdGUgPSBuZXcgRGF0ZShwdXNoVGltZVBhcmFtICogMTAwMCk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcHVzaFRpbWVQYXJhbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlzTG9jYWxUaW1lID0gIVB1c2hDb250cm9sbGVyLnB1c2hUaW1lSGFzVGltZXpvbmVDb21wb25lbnQocHVzaFRpbWVQYXJhbSk7XG4gICAgICBkYXRlID0gbmV3IERhdGUocHVzaFRpbWVQYXJhbSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICBib2R5WydwdXNoX3RpbWUnXSArICcgaXMgbm90IHZhbGlkIHRpbWUuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgLy8gQ2hlY2sgcHVzaFRpbWUgaXMgdmFsaWQgb3Igbm90LCBpZiBpdCBpcyBub3QgdmFsaWQsIHB1c2hUaW1lIGlzIE5hTlxuICAgIGlmICghaXNGaW5pdGUoZGF0ZSkpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICBib2R5WydwdXNoX3RpbWUnXSArICcgaXMgbm90IHZhbGlkIHRpbWUuJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGF0ZSxcbiAgICAgIGlzTG9jYWxUaW1lLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGEgSVNPODYwMSBmb3JtYXR0ZWQgZGF0ZSBjb250YWlucyBhIHRpbWV6b25lIGNvbXBvbmVudFxuICAgKiBAcGFyYW0gcHVzaFRpbWVQYXJhbSB7c3RyaW5nfVxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICovXG4gIHN0YXRpYyBwdXNoVGltZUhhc1RpbWV6b25lQ29tcG9uZW50KHB1c2hUaW1lUGFyYW06IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IG9mZnNldFBhdHRlcm4gPSAvKC4rKShbKy1dKVxcZFxcZDpcXGRcXGQkLztcbiAgICByZXR1cm4gKFxuICAgICAgcHVzaFRpbWVQYXJhbS5pbmRleE9mKCdaJykgPT09IHB1c2hUaW1lUGFyYW0ubGVuZ3RoIC0gMSB8fCBvZmZzZXRQYXR0ZXJuLnRlc3QocHVzaFRpbWVQYXJhbSkgLy8gMjAwNy0wNC0wNVQxMjozMFpcbiAgICApOyAvLyAyMDA3LTA0LTA1VDEyOjMwLjAwMCswMjowMCwgMjAwNy0wNC0wNVQxMjozMC4wMDAtMDI6MDBcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhIGRhdGUgdG8gSVNPIGZvcm1hdCBpbiBVVEMgdGltZSBhbmQgc3RyaXBzIHRoZSB0aW1lem9uZSBpZiBgaXNMb2NhbFRpbWVgIGlzIHRydWVcbiAgICogQHBhcmFtIGRhdGUge0RhdGV9XG4gICAqIEBwYXJhbSBpc0xvY2FsVGltZSB7Ym9vbGVhbn1cbiAgICogQHJldHVybnMge3N0cmluZ31cbiAgICovXG4gIHN0YXRpYyBmb3JtYXRQdXNoVGltZSh7IGRhdGUsIGlzTG9jYWxUaW1lIH06IHsgZGF0ZTogRGF0ZSwgaXNMb2NhbFRpbWU6IGJvb2xlYW4gfSkge1xuICAgIGlmIChpc0xvY2FsVGltZSkge1xuICAgICAgLy8gU3RyaXAgJ1onXG4gICAgICBjb25zdCBpc29TdHJpbmcgPSBkYXRlLnRvSVNPU3RyaW5nKCk7XG4gICAgICByZXR1cm4gaXNvU3RyaW5nLnN1YnN0cmluZygwLCBpc29TdHJpbmcuaW5kZXhPZignWicpKTtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGUudG9JU09TdHJpbmcoKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQdXNoQ29udHJvbGxlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/SchemaCache.js b/lib/Controllers/SchemaCache.js new file mode 100644 index 0000000000..638bb91ad5 --- /dev/null +++ b/lib/Controllers/SchemaCache.js @@ -0,0 +1,75 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _cryptoUtils = require("../cryptoUtils"); + +var _defaults = _interopRequireDefault(require("../defaults")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const MAIN_SCHEMA = '__MAIN_SCHEMA'; +const SCHEMA_CACHE_PREFIX = '__SCHEMA'; + +class SchemaCache { + constructor(cacheController, ttl = _defaults.default.schemaCacheTTL, singleCache = false) { + this.ttl = ttl; + + if (typeof ttl == 'string') { + this.ttl = parseInt(ttl); + } + + this.cache = cacheController; + this.prefix = SCHEMA_CACHE_PREFIX; + + if (!singleCache) { + this.prefix += (0, _cryptoUtils.randomString)(20); + } + } + + getAllClasses() { + if (!this.ttl) { + return Promise.resolve(null); + } + + return this.cache.get(this.prefix + MAIN_SCHEMA); + } + + setAllClasses(schema) { + if (!this.ttl) { + return Promise.resolve(null); + } + + return this.cache.put(this.prefix + MAIN_SCHEMA, schema, this.ttl); + } + + getOneSchema(className) { + if (!this.ttl) { + return Promise.resolve(null); + } + + return this.cache.get(this.prefix + MAIN_SCHEMA).then(cachedSchemas => { + cachedSchemas = cachedSchemas || []; + const schema = cachedSchemas.find(cachedSchema => { + return cachedSchema.className === className; + }); + + if (schema) { + return Promise.resolve(schema); + } + + return Promise.resolve(null); + }); + } + + clear() { + return this.cache.del(this.prefix + MAIN_SCHEMA); + } + +} + +exports.default = SchemaCache; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9TY2hlbWFDYWNoZS5qcyJdLCJuYW1lcyI6WyJNQUlOX1NDSEVNQSIsIlNDSEVNQV9DQUNIRV9QUkVGSVgiLCJTY2hlbWFDYWNoZSIsImNvbnN0cnVjdG9yIiwiY2FjaGVDb250cm9sbGVyIiwidHRsIiwiZGVmYXVsdHMiLCJzY2hlbWFDYWNoZVRUTCIsInNpbmdsZUNhY2hlIiwicGFyc2VJbnQiLCJjYWNoZSIsInByZWZpeCIsImdldEFsbENsYXNzZXMiLCJQcm9taXNlIiwicmVzb2x2ZSIsImdldCIsInNldEFsbENsYXNzZXMiLCJzY2hlbWEiLCJwdXQiLCJnZXRPbmVTY2hlbWEiLCJjbGFzc05hbWUiLCJ0aGVuIiwiY2FjaGVkU2NoZW1hcyIsImZpbmQiLCJjYWNoZWRTY2hlbWEiLCJjbGVhciIsImRlbCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUdBOztBQUNBOzs7O0FBSkEsTUFBTUEsV0FBVyxHQUFHLGVBQXBCO0FBQ0EsTUFBTUMsbUJBQW1CLEdBQUcsVUFBNUI7O0FBS2UsTUFBTUMsV0FBTixDQUFrQjtBQUcvQkMsRUFBQUEsV0FBVyxDQUFDQyxlQUFELEVBQWtCQyxHQUFHLEdBQUdDLGtCQUFTQyxjQUFqQyxFQUFpREMsV0FBVyxHQUFHLEtBQS9ELEVBQXNFO0FBQy9FLFNBQUtILEdBQUwsR0FBV0EsR0FBWDs7QUFDQSxRQUFJLE9BQU9BLEdBQVAsSUFBYyxRQUFsQixFQUE0QjtBQUMxQixXQUFLQSxHQUFMLEdBQVdJLFFBQVEsQ0FBQ0osR0FBRCxDQUFuQjtBQUNEOztBQUNELFNBQUtLLEtBQUwsR0FBYU4sZUFBYjtBQUNBLFNBQUtPLE1BQUwsR0FBY1YsbUJBQWQ7O0FBQ0EsUUFBSSxDQUFDTyxXQUFMLEVBQWtCO0FBQ2hCLFdBQUtHLE1BQUwsSUFBZSwrQkFBYSxFQUFiLENBQWY7QUFDRDtBQUNGOztBQUVEQyxFQUFBQSxhQUFhLEdBQUc7QUFDZCxRQUFJLENBQUMsS0FBS1AsR0FBVixFQUFlO0FBQ2IsYUFBT1EsT0FBTyxDQUFDQyxPQUFSLENBQWdCLElBQWhCLENBQVA7QUFDRDs7QUFDRCxXQUFPLEtBQUtKLEtBQUwsQ0FBV0ssR0FBWCxDQUFlLEtBQUtKLE1BQUwsR0FBY1gsV0FBN0IsQ0FBUDtBQUNEOztBQUVEZ0IsRUFBQUEsYUFBYSxDQUFDQyxNQUFELEVBQVM7QUFDcEIsUUFBSSxDQUFDLEtBQUtaLEdBQVYsRUFBZTtBQUNiLGFBQU9RLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQixJQUFoQixDQUFQO0FBQ0Q7O0FBQ0QsV0FBTyxLQUFLSixLQUFMLENBQVdRLEdBQVgsQ0FBZSxLQUFLUCxNQUFMLEdBQWNYLFdBQTdCLEVBQTBDaUIsTUFBMUMsRUFBa0QsS0FBS1osR0FBdkQsQ0FBUDtBQUNEOztBQUVEYyxFQUFBQSxZQUFZLENBQUNDLFNBQUQsRUFBWTtBQUN0QixRQUFJLENBQUMsS0FBS2YsR0FBVixFQUFlO0FBQ2IsYUFBT1EsT0FBTyxDQUFDQyxPQUFSLENBQWdCLElBQWhCLENBQVA7QUFDRDs7QUFDRCxXQUFPLEtBQUtKLEtBQUwsQ0FBV0ssR0FBWCxDQUFlLEtBQUtKLE1BQUwsR0FBY1gsV0FBN0IsRUFBMENxQixJQUExQyxDQUErQ0MsYUFBYSxJQUFJO0FBQ3JFQSxNQUFBQSxhQUFhLEdBQUdBLGFBQWEsSUFBSSxFQUFqQztBQUNBLFlBQU1MLE1BQU0sR0FBR0ssYUFBYSxDQUFDQyxJQUFkLENBQW1CQyxZQUFZLElBQUk7QUFDaEQsZUFBT0EsWUFBWSxDQUFDSixTQUFiLEtBQTJCQSxTQUFsQztBQUNELE9BRmMsQ0FBZjs7QUFHQSxVQUFJSCxNQUFKLEVBQVk7QUFDVixlQUFPSixPQUFPLENBQUNDLE9BQVIsQ0FBZ0JHLE1BQWhCLENBQVA7QUFDRDs7QUFDRCxhQUFPSixPQUFPLENBQUNDLE9BQVIsQ0FBZ0IsSUFBaEIsQ0FBUDtBQUNELEtBVE0sQ0FBUDtBQVVEOztBQUVEVyxFQUFBQSxLQUFLLEdBQUc7QUFDTixXQUFPLEtBQUtmLEtBQUwsQ0FBV2dCLEdBQVgsQ0FBZSxLQUFLZixNQUFMLEdBQWNYLFdBQTdCLENBQVA7QUFDRDs7QUEvQzhCIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgTUFJTl9TQ0hFTUEgPSAnX19NQUlOX1NDSEVNQSc7XG5jb25zdCBTQ0hFTUFfQ0FDSEVfUFJFRklYID0gJ19fU0NIRU1BJztcblxuaW1wb3J0IHsgcmFuZG9tU3RyaW5nIH0gZnJvbSAnLi4vY3J5cHRvVXRpbHMnO1xuaW1wb3J0IGRlZmF1bHRzIGZyb20gJy4uL2RlZmF1bHRzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2NoZW1hQ2FjaGUge1xuICBjYWNoZTogT2JqZWN0O1xuXG4gIGNvbnN0cnVjdG9yKGNhY2hlQ29udHJvbGxlciwgdHRsID0gZGVmYXVsdHMuc2NoZW1hQ2FjaGVUVEwsIHNpbmdsZUNhY2hlID0gZmFsc2UpIHtcbiAgICB0aGlzLnR0bCA9IHR0bDtcbiAgICBpZiAodHlwZW9mIHR0bCA9PSAnc3RyaW5nJykge1xuICAgICAgdGhpcy50dGwgPSBwYXJzZUludCh0dGwpO1xuICAgIH1cbiAgICB0aGlzLmNhY2hlID0gY2FjaGVDb250cm9sbGVyO1xuICAgIHRoaXMucHJlZml4ID0gU0NIRU1BX0NBQ0hFX1BSRUZJWDtcbiAgICBpZiAoIXNpbmdsZUNhY2hlKSB7XG4gICAgICB0aGlzLnByZWZpeCArPSByYW5kb21TdHJpbmcoMjApO1xuICAgIH1cbiAgfVxuXG4gIGdldEFsbENsYXNzZXMoKSB7XG4gICAgaWYgKCF0aGlzLnR0bCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShudWxsKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0KHRoaXMucHJlZml4ICsgTUFJTl9TQ0hFTUEpO1xuICB9XG5cbiAgc2V0QWxsQ2xhc3NlcyhzY2hlbWEpIHtcbiAgICBpZiAoIXRoaXMudHRsKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG51bGwpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jYWNoZS5wdXQodGhpcy5wcmVmaXggKyBNQUlOX1NDSEVNQSwgc2NoZW1hLCB0aGlzLnR0bCk7XG4gIH1cblxuICBnZXRPbmVTY2hlbWEoY2xhc3NOYW1lKSB7XG4gICAgaWYgKCF0aGlzLnR0bCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShudWxsKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0KHRoaXMucHJlZml4ICsgTUFJTl9TQ0hFTUEpLnRoZW4oY2FjaGVkU2NoZW1hcyA9PiB7XG4gICAgICBjYWNoZWRTY2hlbWFzID0gY2FjaGVkU2NoZW1hcyB8fCBbXTtcbiAgICAgIGNvbnN0IHNjaGVtYSA9IGNhY2hlZFNjaGVtYXMuZmluZChjYWNoZWRTY2hlbWEgPT4ge1xuICAgICAgICByZXR1cm4gY2FjaGVkU2NoZW1hLmNsYXNzTmFtZSA9PT0gY2xhc3NOYW1lO1xuICAgICAgfSk7XG4gICAgICBpZiAoc2NoZW1hKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoc2NoZW1hKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobnVsbCk7XG4gICAgfSk7XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICByZXR1cm4gdGhpcy5jYWNoZS5kZWwodGhpcy5wcmVmaXggKyBNQUlOX1NDSEVNQSk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/SchemaController.js b/lib/Controllers/SchemaController.js new file mode 100644 index 0000000000..cf11ba237f --- /dev/null +++ b/lib/Controllers/SchemaController.js @@ -0,0 +1,1670 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.classNameIsValid = classNameIsValid; +exports.fieldNameIsValid = fieldNameIsValid; +exports.invalidClassNameMessage = invalidClassNameMessage; +exports.buildMergedSchemaObject = buildMergedSchemaObject; +exports.VolatileClassesSchemas = exports.convertSchemaToAdapterSchema = exports.defaultColumns = exports.systemClasses = exports.load = exports.SchemaController = exports.default = void 0; + +var _StorageAdapter = require("../Adapters/Storage/StorageAdapter"); + +var _DatabaseController = _interopRequireDefault(require("./DatabaseController")); + +var _Config = _interopRequireDefault(require("../Config")); + +var _deepcopy = _interopRequireDefault(require("deepcopy")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } + +// This class handles schema validation, persistence, and modification. +// +// Each individual Schema object should be immutable. The helpers to +// do things with the Schema just return a new schema when the schema +// is changed. +// +// The canonical place to store this Schema is in the database itself, +// in a _SCHEMA collection. This is not the right way to do it for an +// open source framework, but it's backward compatible, so we're +// keeping it this way for now. +// +// In API-handling code, you should only use the Schema class via the +// DatabaseController. This will let us replace the schema logic for +// different databases. +// TODO: hide all schema logic inside the database adapter. +// -disable-next +const Parse = require('parse/node').Parse; + +const defaultColumns = Object.freeze({ + // Contain the default columns for every parse object type (except _Join collection) + _Default: { + objectId: { + type: 'String' + }, + createdAt: { + type: 'Date' + }, + updatedAt: { + type: 'Date' + }, + ACL: { + type: 'ACL' + } + }, + // The additional default columns for the _User collection (in addition to DefaultCols) + _User: { + username: { + type: 'String' + }, + password: { + type: 'String' + }, + email: { + type: 'String' + }, + emailVerified: { + type: 'Boolean' + }, + authData: { + type: 'Object' + } + }, + // The additional default columns for the _Installation collection (in addition to DefaultCols) + _Installation: { + installationId: { + type: 'String' + }, + deviceToken: { + type: 'String' + }, + channels: { + type: 'Array' + }, + deviceType: { + type: 'String' + }, + pushType: { + type: 'String' + }, + GCMSenderId: { + type: 'String' + }, + timeZone: { + type: 'String' + }, + localeIdentifier: { + type: 'String' + }, + badge: { + type: 'Number' + }, + appVersion: { + type: 'String' + }, + appName: { + type: 'String' + }, + appIdentifier: { + type: 'String' + }, + parseVersion: { + type: 'String' + } + }, + // The additional default columns for the _Role collection (in addition to DefaultCols) + _Role: { + name: { + type: 'String' + }, + users: { + type: 'Relation', + targetClass: '_User' + }, + roles: { + type: 'Relation', + targetClass: '_Role' + } + }, + // The additional default columns for the _Session collection (in addition to DefaultCols) + _Session: { + restricted: { + type: 'Boolean' + }, + user: { + type: 'Pointer', + targetClass: '_User' + }, + installationId: { + type: 'String' + }, + sessionToken: { + type: 'String' + }, + expiresAt: { + type: 'Date' + }, + createdWith: { + type: 'Object' + } + }, + _Product: { + productIdentifier: { + type: 'String' + }, + download: { + type: 'File' + }, + downloadName: { + type: 'String' + }, + icon: { + type: 'File' + }, + order: { + type: 'Number' + }, + title: { + type: 'String' + }, + subtitle: { + type: 'String' + } + }, + _PushStatus: { + pushTime: { + type: 'String' + }, + source: { + type: 'String' + }, + // rest or webui + query: { + type: 'String' + }, + // the stringified JSON query + payload: { + type: 'String' + }, + // the stringified JSON payload, + title: { + type: 'String' + }, + expiry: { + type: 'Number' + }, + expiration_interval: { + type: 'Number' + }, + status: { + type: 'String' + }, + numSent: { + type: 'Number' + }, + numFailed: { + type: 'Number' + }, + pushHash: { + type: 'String' + }, + errorMessage: { + type: 'Object' + }, + sentPerType: { + type: 'Object' + }, + failedPerType: { + type: 'Object' + }, + sentPerUTCOffset: { + type: 'Object' + }, + failedPerUTCOffset: { + type: 'Object' + }, + count: { + type: 'Number' + } // tracks # of batches queued and pending + + }, + _JobStatus: { + jobName: { + type: 'String' + }, + source: { + type: 'String' + }, + status: { + type: 'String' + }, + message: { + type: 'String' + }, + params: { + type: 'Object' + }, + // params received when calling the job + finishedAt: { + type: 'Date' + } + }, + _JobSchedule: { + jobName: { + type: 'String' + }, + description: { + type: 'String' + }, + params: { + type: 'String' + }, + startAfter: { + type: 'String' + }, + daysOfWeek: { + type: 'Array' + }, + timeOfDay: { + type: 'String' + }, + lastRun: { + type: 'Number' + }, + repeatMinutes: { + type: 'Number' + } + }, + _Hooks: { + functionName: { + type: 'String' + }, + className: { + type: 'String' + }, + triggerName: { + type: 'String' + }, + url: { + type: 'String' + } + }, + _GlobalConfig: { + objectId: { + type: 'String' + }, + params: { + type: 'Object' + }, + masterKeyOnly: { + type: 'Object' + } + }, + _GraphQLConfig: { + objectId: { + type: 'String' + }, + config: { + type: 'Object' + } + }, + _Audience: { + objectId: { + type: 'String' + }, + name: { + type: 'String' + }, + query: { + type: 'String' + }, + //storing query as JSON string to prevent "Nested keys should not contain the '$' or '.' characters" error + lastUsed: { + type: 'Date' + }, + timesUsed: { + type: 'Number' + } + }, + _Idempotency: { + reqId: { + type: 'String' + }, + expire: { + type: 'Date' + } + } +}); +exports.defaultColumns = defaultColumns; +const requiredColumns = Object.freeze({ + _Product: ['productIdentifier', 'icon', 'order', 'title', 'subtitle'], + _Role: ['name', 'ACL'] +}); +const invalidColumns = ['length']; +const systemClasses = Object.freeze(['_User', '_Installation', '_Role', '_Session', '_Product', '_PushStatus', '_JobStatus', '_JobSchedule', '_Audience', '_Idempotency']); +exports.systemClasses = systemClasses; +const volatileClasses = Object.freeze(['_JobStatus', '_PushStatus', '_Hooks', '_GlobalConfig', '_GraphQLConfig', '_JobSchedule', '_Audience', '_Idempotency']); // Anything that start with role + +const roleRegex = /^role:.*/; // Anything that starts with userField (allowed for protected fields only) + +const protectedFieldsPointerRegex = /^userField:.*/; // * permission + +const publicRegex = /^\*$/; +const authenticatedRegex = /^authenticated$/; +const requiresAuthenticationRegex = /^requiresAuthentication$/; +const clpPointerRegex = /^pointerFields$/; // regex for validating entities in protectedFields object + +const protectedFieldsRegex = Object.freeze([protectedFieldsPointerRegex, publicRegex, authenticatedRegex, roleRegex]); // clp regex + +const clpFieldsRegex = Object.freeze([clpPointerRegex, publicRegex, requiresAuthenticationRegex, roleRegex]); + +function validatePermissionKey(key, userIdRegExp) { + let matchesSome = false; + + for (const regEx of clpFieldsRegex) { + if (key.match(regEx) !== null) { + matchesSome = true; + break; + } + } // userId depends on startup options so it's dynamic + + + const valid = matchesSome || key.match(userIdRegExp) !== null; + + if (!valid) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `'${key}' is not a valid key for class level permissions`); + } +} + +function validateProtectedFieldsKey(key, userIdRegExp) { + let matchesSome = false; + + for (const regEx of protectedFieldsRegex) { + if (key.match(regEx) !== null) { + matchesSome = true; + break; + } + } // userId regex depends on launch options so it's dynamic + + + const valid = matchesSome || key.match(userIdRegExp) !== null; + + if (!valid) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `'${key}' is not a valid key for class level permissions`); + } +} + +const CLPValidKeys = Object.freeze(['find', 'count', 'get', 'create', 'update', 'delete', 'addField', 'readUserFields', 'writeUserFields', 'protectedFields']); // validation before setting class-level permissions on collection + +function validateCLP(perms, fields, userIdRegExp) { + if (!perms) { + return; + } + + for (const operationKey in perms) { + if (CLPValidKeys.indexOf(operationKey) == -1) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `${operationKey} is not a valid operation for class level permissions`); + } + + const operation = perms[operationKey]; // proceed with next operationKey + // throws when root fields are of wrong type + + validateCLPjson(operation, operationKey); + + if (operationKey === 'readUserFields' || operationKey === 'writeUserFields') { + // validate grouped pointer permissions + // must be an array with field names + for (const fieldName of operation) { + validatePointerPermission(fieldName, fields, operationKey); + } // readUserFields and writerUserFields do not have nesdted fields + // proceed with next operationKey + + + continue; + } // validate protected fields + + + if (operationKey === 'protectedFields') { + for (const entity in operation) { + // throws on unexpected key + validateProtectedFieldsKey(entity, userIdRegExp); + const protectedFields = operation[entity]; + + if (!Array.isArray(protectedFields)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `'${protectedFields}' is not a valid value for protectedFields[${entity}] - expected an array.`); + } // if the field is in form of array + + + for (const field of protectedFields) { + // do not alloow to protect default fields + if (defaultColumns._Default[field]) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `Default field '${field}' can not be protected`); + } // field should exist on collection + + + if (!Object.prototype.hasOwnProperty.call(fields, field)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `Field '${field}' in protectedFields:${entity} does not exist`); + } + } + } // proceed with next operationKey + + + continue; + } // validate other fields + // Entity can be: + // "*" - Public, + // "requiresAuthentication" - authenticated users, + // "objectId" - _User id, + // "role:rolename", + // "pointerFields" - array of field names containing pointers to users + + + for (const entity in operation) { + // throws on unexpected key + validatePermissionKey(entity, userIdRegExp); // entity can be either: + // "pointerFields": string[] + + if (entity === 'pointerFields') { + const pointerFields = operation[entity]; + + if (Array.isArray(pointerFields)) { + for (const pointerField of pointerFields) { + validatePointerPermission(pointerField, fields, operation); + } + } else { + throw new Parse.Error(Parse.Error.INVALID_JSON, `'${pointerFields}' is not a valid value for ${operationKey}[${entity}] - expected an array.`); + } // proceed with next entity key + + + continue; + } // or [entity]: boolean + + + const permit = operation[entity]; + + if (permit !== true) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `'${permit}' is not a valid value for class level permissions ${operationKey}:${entity}:${permit}`); + } + } + } +} + +function validateCLPjson(operation, operationKey) { + if (operationKey === 'readUserFields' || operationKey === 'writeUserFields') { + if (!Array.isArray(operation)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `'${operation}' is not a valid value for class level permissions ${operationKey} - must be an array`); + } + } else { + if (typeof operation === 'object' && operation !== null) { + // ok to proceed + return; + } else { + throw new Parse.Error(Parse.Error.INVALID_JSON, `'${operation}' is not a valid value for class level permissions ${operationKey} - must be an object`); + } + } +} + +function validatePointerPermission(fieldName, fields, operation) { + // Uses collection schema to ensure the field is of type: + // - Pointer<_User> (pointers) + // - Array + // + // It's not possible to enforce type on Array's items in schema + // so we accept any Array field, and later when applying permissions + // only items that are pointers to _User are considered. + if (!(fields[fieldName] && (fields[fieldName].type == 'Pointer' && fields[fieldName].targetClass == '_User' || fields[fieldName].type == 'Array'))) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `'${fieldName}' is not a valid column for class level pointer permissions ${operation}`); + } +} + +const joinClassRegex = /^_Join:[A-Za-z0-9_]+:[A-Za-z0-9_]+/; +const classAndFieldRegex = /^[A-Za-z][A-Za-z0-9_]*$/; + +function classNameIsValid(className) { + // Valid classes must: + return (// Be one of _User, _Installation, _Role, _Session OR + systemClasses.indexOf(className) > -1 || // Be a join table OR + joinClassRegex.test(className) || // Include only alpha-numeric and underscores, and not start with an underscore or number + fieldNameIsValid(className, className) + ); +} // Valid fields must be alpha-numeric, and not start with an underscore or number +// must not be a reserved key + + +function fieldNameIsValid(fieldName, className) { + if (className && className !== '_Hooks') { + if (fieldName === 'className') { + return false; + } + } + + return classAndFieldRegex.test(fieldName) && !invalidColumns.includes(fieldName); +} // Checks that it's not trying to clobber one of the default fields of the class. + + +function fieldNameIsValidForClass(fieldName, className) { + if (!fieldNameIsValid(fieldName, className)) { + return false; + } + + if (defaultColumns._Default[fieldName]) { + return false; + } + + if (defaultColumns[className] && defaultColumns[className][fieldName]) { + return false; + } + + return true; +} + +function invalidClassNameMessage(className) { + return 'Invalid classname: ' + className + ', classnames can only have alphanumeric characters and _, and must start with an alpha character '; +} + +const invalidJsonError = new Parse.Error(Parse.Error.INVALID_JSON, 'invalid JSON'); +const validNonRelationOrPointerTypes = ['Number', 'String', 'Boolean', 'Date', 'Object', 'Array', 'GeoPoint', 'File', 'Bytes', 'Polygon']; // Returns an error suitable for throwing if the type is invalid + +const fieldTypeIsInvalid = ({ + type, + targetClass +}) => { + if (['Pointer', 'Relation'].indexOf(type) >= 0) { + if (!targetClass) { + return new Parse.Error(135, `type ${type} needs a class name`); + } else if (typeof targetClass !== 'string') { + return invalidJsonError; + } else if (!classNameIsValid(targetClass)) { + return new Parse.Error(Parse.Error.INVALID_CLASS_NAME, invalidClassNameMessage(targetClass)); + } else { + return undefined; + } + } + + if (typeof type !== 'string') { + return invalidJsonError; + } + + if (validNonRelationOrPointerTypes.indexOf(type) < 0) { + return new Parse.Error(Parse.Error.INCORRECT_TYPE, `invalid field type: ${type}`); + } + + return undefined; +}; + +const convertSchemaToAdapterSchema = schema => { + schema = injectDefaultSchema(schema); + delete schema.fields.ACL; + schema.fields._rperm = { + type: 'Array' + }; + schema.fields._wperm = { + type: 'Array' + }; + + if (schema.className === '_User') { + delete schema.fields.password; + schema.fields._hashed_password = { + type: 'String' + }; + } + + return schema; +}; + +exports.convertSchemaToAdapterSchema = convertSchemaToAdapterSchema; + +const convertAdapterSchemaToParseSchema = (_ref) => { + let schema = _extends({}, _ref); + + delete schema.fields._rperm; + delete schema.fields._wperm; + schema.fields.ACL = { + type: 'ACL' + }; + + if (schema.className === '_User') { + delete schema.fields.authData; //Auth data is implicit + + delete schema.fields._hashed_password; + schema.fields.password = { + type: 'String' + }; + } + + if (schema.indexes && Object.keys(schema.indexes).length === 0) { + delete schema.indexes; + } + + return schema; +}; + +class SchemaData { + constructor(allSchemas = [], protectedFields = {}) { + this.__data = {}; + this.__protectedFields = protectedFields; + allSchemas.forEach(schema => { + if (volatileClasses.includes(schema.className)) { + return; + } + + Object.defineProperty(this, schema.className, { + get: () => { + if (!this.__data[schema.className]) { + const data = {}; + data.fields = injectDefaultSchema(schema).fields; + data.classLevelPermissions = (0, _deepcopy.default)(schema.classLevelPermissions); + data.indexes = schema.indexes; + const classProtectedFields = this.__protectedFields[schema.className]; + + if (classProtectedFields) { + for (const key in classProtectedFields) { + const unq = new Set([...(data.classLevelPermissions.protectedFields[key] || []), ...classProtectedFields[key]]); + data.classLevelPermissions.protectedFields[key] = Array.from(unq); + } + } + + this.__data[schema.className] = data; + } + + return this.__data[schema.className]; + } + }); + }); // Inject the in-memory classes + + volatileClasses.forEach(className => { + Object.defineProperty(this, className, { + get: () => { + if (!this.__data[className]) { + const schema = injectDefaultSchema({ + className, + fields: {}, + classLevelPermissions: {} + }); + const data = {}; + data.fields = schema.fields; + data.classLevelPermissions = schema.classLevelPermissions; + data.indexes = schema.indexes; + this.__data[className] = data; + } + + return this.__data[className]; + } + }); + }); + } + +} + +const injectDefaultSchema = ({ + className, + fields, + classLevelPermissions, + indexes +}) => { + const defaultSchema = { + className, + fields: _objectSpread(_objectSpread(_objectSpread({}, defaultColumns._Default), defaultColumns[className] || {}), fields), + classLevelPermissions + }; + + if (indexes && Object.keys(indexes).length !== 0) { + defaultSchema.indexes = indexes; + } + + return defaultSchema; +}; + +const _HooksSchema = { + className: '_Hooks', + fields: defaultColumns._Hooks +}; +const _GlobalConfigSchema = { + className: '_GlobalConfig', + fields: defaultColumns._GlobalConfig +}; +const _GraphQLConfigSchema = { + className: '_GraphQLConfig', + fields: defaultColumns._GraphQLConfig +}; + +const _PushStatusSchema = convertSchemaToAdapterSchema(injectDefaultSchema({ + className: '_PushStatus', + fields: {}, + classLevelPermissions: {} +})); + +const _JobStatusSchema = convertSchemaToAdapterSchema(injectDefaultSchema({ + className: '_JobStatus', + fields: {}, + classLevelPermissions: {} +})); + +const _JobScheduleSchema = convertSchemaToAdapterSchema(injectDefaultSchema({ + className: '_JobSchedule', + fields: {}, + classLevelPermissions: {} +})); + +const _AudienceSchema = convertSchemaToAdapterSchema(injectDefaultSchema({ + className: '_Audience', + fields: defaultColumns._Audience, + classLevelPermissions: {} +})); + +const _IdempotencySchema = convertSchemaToAdapterSchema(injectDefaultSchema({ + className: '_Idempotency', + fields: defaultColumns._Idempotency, + classLevelPermissions: {} +})); + +const VolatileClassesSchemas = [_HooksSchema, _JobStatusSchema, _JobScheduleSchema, _PushStatusSchema, _GlobalConfigSchema, _GraphQLConfigSchema, _AudienceSchema, _IdempotencySchema]; +exports.VolatileClassesSchemas = VolatileClassesSchemas; + +const dbTypeMatchesObjectType = (dbType, objectType) => { + if (dbType.type !== objectType.type) return false; + if (dbType.targetClass !== objectType.targetClass) return false; + if (dbType === objectType.type) return true; + if (dbType.type === objectType.type) return true; + return false; +}; + +const typeToString = type => { + if (typeof type === 'string') { + return type; + } + + if (type.targetClass) { + return `${type.type}<${type.targetClass}>`; + } + + return `${type.type}`; +}; // Stores the entire schema of the app in a weird hybrid format somewhere between +// the mongo format and the Parse format. Soon, this will all be Parse format. + + +class SchemaController { + constructor(databaseAdapter, schemaCache) { + this._dbAdapter = databaseAdapter; + this._cache = schemaCache; + this.schemaData = new SchemaData(); + this.protectedFields = _Config.default.get(Parse.applicationId).protectedFields; + + const customIds = _Config.default.get(Parse.applicationId).allowCustomObjectId; + + const customIdRegEx = /^.{1,}$/u; // 1+ chars + + const autoIdRegEx = /^[a-zA-Z0-9]{1,}$/; + this.userIdRegEx = customIds ? customIdRegEx : autoIdRegEx; + } + + reloadData(options = { + clearCache: false + }) { + if (this.reloadDataPromise && !options.clearCache) { + return this.reloadDataPromise; + } + + this.reloadDataPromise = this.getAllClasses(options).then(allSchemas => { + this.schemaData = new SchemaData(allSchemas, this.protectedFields); + delete this.reloadDataPromise; + }, err => { + this.schemaData = new SchemaData(); + delete this.reloadDataPromise; + throw err; + }).then(() => {}); + return this.reloadDataPromise; + } + + getAllClasses(options = { + clearCache: false + }) { + if (options.clearCache) { + return this.setAllClasses(); + } + + return this._cache.getAllClasses().then(allClasses => { + if (allClasses && allClasses.length) { + return Promise.resolve(allClasses); + } + + return this.setAllClasses(); + }); + } + + setAllClasses() { + return this._dbAdapter.getAllClasses().then(allSchemas => allSchemas.map(injectDefaultSchema)).then(allSchemas => { + /* eslint-disable no-console */ + this._cache.setAllClasses(allSchemas).catch(error => console.error('Error saving schema to cache:', error)); + /* eslint-enable no-console */ + + + return allSchemas; + }); + } + + getOneSchema(className, allowVolatileClasses = false, options = { + clearCache: false + }) { + let promise = Promise.resolve(); + + if (options.clearCache) { + promise = this._cache.clear(); + } + + return promise.then(() => { + if (allowVolatileClasses && volatileClasses.indexOf(className) > -1) { + const data = this.schemaData[className]; + return Promise.resolve({ + className, + fields: data.fields, + classLevelPermissions: data.classLevelPermissions, + indexes: data.indexes + }); + } + + return this._cache.getOneSchema(className).then(cached => { + if (cached && !options.clearCache) { + return Promise.resolve(cached); + } + + return this.setAllClasses().then(allSchemas => { + const oneSchema = allSchemas.find(schema => schema.className === className); + + if (!oneSchema) { + return Promise.reject(undefined); + } + + return oneSchema; + }); + }); + }); + } // Create a new class that includes the three default fields. + // ACL is an implicit column that does not get an entry in the + // _SCHEMAS database. Returns a promise that resolves with the + // created schema, in mongo format. + // on success, and rejects with an error on fail. Ensure you + // have authorization (master key, or client class creation + // enabled) before calling this function. + + + addClassIfNotExists(className, fields = {}, classLevelPermissions, indexes = {}) { + var validationError = this.validateNewClass(className, fields, classLevelPermissions); + + if (validationError) { + if (validationError instanceof Parse.Error) { + return Promise.reject(validationError); + } else if (validationError.code && validationError.error) { + return Promise.reject(new Parse.Error(validationError.code, validationError.error)); + } + + return Promise.reject(validationError); + } + + return this._dbAdapter.createClass(className, convertSchemaToAdapterSchema({ + fields, + classLevelPermissions, + indexes, + className + })).then(convertAdapterSchemaToParseSchema).catch(error => { + if (error && error.code === Parse.Error.DUPLICATE_VALUE) { + throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} already exists.`); + } else { + throw error; + } + }); + } + + updateClass(className, submittedFields, classLevelPermissions, indexes, database) { + return this.getOneSchema(className).then(schema => { + const existingFields = schema.fields; + Object.keys(submittedFields).forEach(name => { + const field = submittedFields[name]; + + if (existingFields[name] && field.__op !== 'Delete') { + throw new Parse.Error(255, `Field ${name} exists, cannot update.`); + } + + if (!existingFields[name] && field.__op === 'Delete') { + throw new Parse.Error(255, `Field ${name} does not exist, cannot delete.`); + } + }); + delete existingFields._rperm; + delete existingFields._wperm; + const newSchema = buildMergedSchemaObject(existingFields, submittedFields); + const defaultFields = defaultColumns[className] || defaultColumns._Default; + const fullNewSchema = Object.assign({}, newSchema, defaultFields); + const validationError = this.validateSchemaData(className, newSchema, classLevelPermissions, Object.keys(existingFields)); + + if (validationError) { + throw new Parse.Error(validationError.code, validationError.error); + } // Finally we have checked to make sure the request is valid and we can start deleting fields. + // Do all deletions first, then a single save to _SCHEMA collection to handle all additions. + + + const deletedFields = []; + const insertedFields = []; + Object.keys(submittedFields).forEach(fieldName => { + if (submittedFields[fieldName].__op === 'Delete') { + deletedFields.push(fieldName); + } else { + insertedFields.push(fieldName); + } + }); + let deletePromise = Promise.resolve(); + + if (deletedFields.length > 0) { + deletePromise = this.deleteFields(deletedFields, className, database); + } + + let enforceFields = []; + return deletePromise // Delete Everything + .then(() => this.reloadData({ + clearCache: true + })) // Reload our Schema, so we have all the new values + .then(() => { + const promises = insertedFields.map(fieldName => { + const type = submittedFields[fieldName]; + return this.enforceFieldExists(className, fieldName, type); + }); + return Promise.all(promises); + }).then(results => { + enforceFields = results.filter(result => !!result); + return this.setPermissions(className, classLevelPermissions, newSchema); + }).then(() => this._dbAdapter.setIndexesWithSchemaFormat(className, indexes, schema.indexes, fullNewSchema)).then(() => this.reloadData({ + clearCache: true + })) //TODO: Move this logic into the database adapter + .then(() => { + this.ensureFields(enforceFields); + const schema = this.schemaData[className]; + const reloadedSchema = { + className: className, + fields: schema.fields, + classLevelPermissions: schema.classLevelPermissions + }; + + if (schema.indexes && Object.keys(schema.indexes).length !== 0) { + reloadedSchema.indexes = schema.indexes; + } + + return reloadedSchema; + }); + }).catch(error => { + if (error === undefined) { + throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} does not exist.`); + } else { + throw error; + } + }); + } // Returns a promise that resolves successfully to the new schema + // object or fails with a reason. + + + enforceClassExists(className) { + if (this.schemaData[className]) { + return Promise.resolve(this); + } // We don't have this class. Update the schema + + + return this.addClassIfNotExists(className) // The schema update succeeded. Reload the schema + .then(() => this.reloadData({ + clearCache: true + })).catch(() => { + // The schema update failed. This can be okay - it might + // have failed because there's a race condition and a different + // client is making the exact same schema update that we want. + // So just reload the schema. + return this.reloadData({ + clearCache: true + }); + }).then(() => { + // Ensure that the schema now validates + if (this.schemaData[className]) { + return this; + } else { + throw new Parse.Error(Parse.Error.INVALID_JSON, `Failed to add ${className}`); + } + }).catch(() => { + // The schema still doesn't validate. Give up + throw new Parse.Error(Parse.Error.INVALID_JSON, 'schema class name does not revalidate'); + }); + } + + validateNewClass(className, fields = {}, classLevelPermissions) { + if (this.schemaData[className]) { + throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} already exists.`); + } + + if (!classNameIsValid(className)) { + return { + code: Parse.Error.INVALID_CLASS_NAME, + error: invalidClassNameMessage(className) + }; + } + + return this.validateSchemaData(className, fields, classLevelPermissions, []); + } + + validateSchemaData(className, fields, classLevelPermissions, existingFieldNames) { + for (const fieldName in fields) { + if (existingFieldNames.indexOf(fieldName) < 0) { + if (!fieldNameIsValid(fieldName, className)) { + return { + code: Parse.Error.INVALID_KEY_NAME, + error: 'invalid field name: ' + fieldName + }; + } + + if (!fieldNameIsValidForClass(fieldName, className)) { + return { + code: 136, + error: 'field ' + fieldName + ' cannot be added' + }; + } + + const fieldType = fields[fieldName]; + const error = fieldTypeIsInvalid(fieldType); + if (error) return { + code: error.code, + error: error.message + }; + + if (fieldType.defaultValue !== undefined) { + let defaultValueType = getType(fieldType.defaultValue); + + if (typeof defaultValueType === 'string') { + defaultValueType = { + type: defaultValueType + }; + } else if (typeof defaultValueType === 'object' && fieldType.type === 'Relation') { + return { + code: Parse.Error.INCORRECT_TYPE, + error: `The 'default value' option is not applicable for ${typeToString(fieldType)}` + }; + } + + if (!dbTypeMatchesObjectType(fieldType, defaultValueType)) { + return { + code: Parse.Error.INCORRECT_TYPE, + error: `schema mismatch for ${className}.${fieldName} default value; expected ${typeToString(fieldType)} but got ${typeToString(defaultValueType)}` + }; + } + } else if (fieldType.required) { + if (typeof fieldType === 'object' && fieldType.type === 'Relation') { + return { + code: Parse.Error.INCORRECT_TYPE, + error: `The 'required' option is not applicable for ${typeToString(fieldType)}` + }; + } + } + } + } + + for (const fieldName in defaultColumns[className]) { + fields[fieldName] = defaultColumns[className][fieldName]; + } + + const geoPoints = Object.keys(fields).filter(key => fields[key] && fields[key].type === 'GeoPoint'); + + if (geoPoints.length > 1) { + return { + code: Parse.Error.INCORRECT_TYPE, + error: 'currently, only one GeoPoint field may exist in an object. Adding ' + geoPoints[1] + ' when ' + geoPoints[0] + ' already exists.' + }; + } + + validateCLP(classLevelPermissions, fields, this.userIdRegEx); + } // Sets the Class-level permissions for a given className, which must exist. + + + setPermissions(className, perms, newSchema) { + if (typeof perms === 'undefined') { + return Promise.resolve(); + } + + validateCLP(perms, newSchema, this.userIdRegEx); + return this._dbAdapter.setClassLevelPermissions(className, perms); + } // Returns a promise that resolves successfully to the new schema + // object if the provided className-fieldName-type tuple is valid. + // The className must already be validated. + // If 'freeze' is true, refuse to update the schema for this field. + + + enforceFieldExists(className, fieldName, type) { + if (fieldName.indexOf('.') > 0) { + // subdocument key (x.y) => ok if x is of type 'object' + fieldName = fieldName.split('.')[0]; + type = 'Object'; + } + + if (!fieldNameIsValid(fieldName, className)) { + throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, `Invalid field name: ${fieldName}.`); + } // If someone tries to create a new field with null/undefined as the value, return; + + + if (!type) { + return undefined; + } + + const expectedType = this.getExpectedType(className, fieldName); + + if (typeof type === 'string') { + type = { + type + }; + } + + if (type.defaultValue !== undefined) { + let defaultValueType = getType(type.defaultValue); + + if (typeof defaultValueType === 'string') { + defaultValueType = { + type: defaultValueType + }; + } + + if (!dbTypeMatchesObjectType(type, defaultValueType)) { + throw new Parse.Error(Parse.Error.INCORRECT_TYPE, `schema mismatch for ${className}.${fieldName} default value; expected ${typeToString(type)} but got ${typeToString(defaultValueType)}`); + } + } + + if (expectedType) { + if (!dbTypeMatchesObjectType(expectedType, type)) { + throw new Parse.Error(Parse.Error.INCORRECT_TYPE, `schema mismatch for ${className}.${fieldName}; expected ${typeToString(expectedType)} but got ${typeToString(type)}`); + } + + return undefined; + } + + return this._dbAdapter.addFieldIfNotExists(className, fieldName, type).catch(error => { + if (error.code == Parse.Error.INCORRECT_TYPE) { + // Make sure that we throw errors when it is appropriate to do so. + throw error; + } // The update failed. This can be okay - it might have been a race + // condition where another client updated the schema in the same + // way that we wanted to. So, just reload the schema + + + return Promise.resolve(); + }).then(() => { + return { + className, + fieldName, + type + }; + }); + } + + ensureFields(fields) { + for (let i = 0; i < fields.length; i += 1) { + const { + className, + fieldName + } = fields[i]; + let { + type + } = fields[i]; + const expectedType = this.getExpectedType(className, fieldName); + + if (typeof type === 'string') { + type = { + type: type + }; + } + + if (!expectedType || !dbTypeMatchesObjectType(expectedType, type)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, `Could not add field ${fieldName}`); + } + } + } // maintain compatibility + + + deleteField(fieldName, className, database) { + return this.deleteFields([fieldName], className, database); + } // Delete fields, and remove that data from all objects. This is intended + // to remove unused fields, if other writers are writing objects that include + // this field, the field may reappear. Returns a Promise that resolves with + // no object on success, or rejects with { code, error } on failure. + // Passing the database and prefix is necessary in order to drop relation collections + // and remove fields from objects. Ideally the database would belong to + // a database adapter and this function would close over it or access it via member. + + + deleteFields(fieldNames, className, database) { + if (!classNameIsValid(className)) { + throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, invalidClassNameMessage(className)); + } + + fieldNames.forEach(fieldName => { + if (!fieldNameIsValid(fieldName, className)) { + throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, `invalid field name: ${fieldName}`); + } //Don't allow deleting the default fields. + + + if (!fieldNameIsValidForClass(fieldName, className)) { + throw new Parse.Error(136, `field ${fieldName} cannot be changed`); + } + }); + return this.getOneSchema(className, false, { + clearCache: true + }).catch(error => { + if (error === undefined) { + throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} does not exist.`); + } else { + throw error; + } + }).then(schema => { + fieldNames.forEach(fieldName => { + if (!schema.fields[fieldName]) { + throw new Parse.Error(255, `Field ${fieldName} does not exist, cannot delete.`); + } + }); + + const schemaFields = _objectSpread({}, schema.fields); + + return database.adapter.deleteFields(className, schema, fieldNames).then(() => { + return Promise.all(fieldNames.map(fieldName => { + const field = schemaFields[fieldName]; + + if (field && field.type === 'Relation') { + //For relations, drop the _Join table + return database.adapter.deleteClass(`_Join:${fieldName}:${className}`); + } + + return Promise.resolve(); + })); + }); + }).then(() => this._cache.clear()); + } // Validates an object provided in REST format. + // Returns a promise that resolves to the new schema if this object is + // valid. + + + async validateObject(className, object, query) { + let geocount = 0; + const schema = await this.enforceClassExists(className); + const promises = []; + + for (const fieldName in object) { + if (object[fieldName] === undefined) { + continue; + } + + const expected = getType(object[fieldName]); + + if (expected === 'GeoPoint') { + geocount++; + } + + if (geocount > 1) { + // Make sure all field validation operations run before we return. + // If not - we are continuing to run logic, but already provided response from the server. + return Promise.reject(new Parse.Error(Parse.Error.INCORRECT_TYPE, 'there can only be one geopoint field in a class')); + } + + if (!expected) { + continue; + } + + if (fieldName === 'ACL') { + // Every object has ACL implicitly. + continue; + } + + promises.push(schema.enforceFieldExists(className, fieldName, expected)); + } + + const results = await Promise.all(promises); + const enforceFields = results.filter(result => !!result); + + if (enforceFields.length !== 0) { + await this.reloadData({ + clearCache: true + }); + } + + this.ensureFields(enforceFields); + const promise = Promise.resolve(schema); + return thenValidateRequiredColumns(promise, className, object, query); + } // Validates that all the properties are set for the object + + + validateRequiredColumns(className, object, query) { + const columns = requiredColumns[className]; + + if (!columns || columns.length == 0) { + return Promise.resolve(this); + } + + const missingColumns = columns.filter(function (column) { + if (query && query.objectId) { + if (object[column] && typeof object[column] === 'object') { + // Trying to delete a required column + return object[column].__op == 'Delete'; + } // Not trying to do anything there + + + return false; + } + + return !object[column]; + }); + + if (missingColumns.length > 0) { + throw new Parse.Error(Parse.Error.INCORRECT_TYPE, missingColumns[0] + ' is required.'); + } + + return Promise.resolve(this); + } + + testPermissionsForClassName(className, aclGroup, operation) { + return SchemaController.testPermissions(this.getClassLevelPermissions(className), aclGroup, operation); + } // Tests that the class level permission let pass the operation for a given aclGroup + + + static testPermissions(classPermissions, aclGroup, operation) { + if (!classPermissions || !classPermissions[operation]) { + return true; + } + + const perms = classPermissions[operation]; + + if (perms['*']) { + return true; + } // Check permissions against the aclGroup provided (array of userId/roles) + + + if (aclGroup.some(acl => { + return perms[acl] === true; + })) { + return true; + } + + return false; + } // Validates an operation passes class-level-permissions set in the schema + + + static validatePermission(classPermissions, className, aclGroup, operation, action) { + if (SchemaController.testPermissions(classPermissions, aclGroup, operation)) { + return Promise.resolve(); + } + + if (!classPermissions || !classPermissions[operation]) { + return true; + } + + const perms = classPermissions[operation]; // If only for authenticated users + // make sure we have an aclGroup + + if (perms['requiresAuthentication']) { + // If aclGroup has * (public) + if (!aclGroup || aclGroup.length == 0) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Permission denied, user needs to be authenticated.'); + } else if (aclGroup.indexOf('*') > -1 && aclGroup.length == 1) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Permission denied, user needs to be authenticated.'); + } // requiresAuthentication passed, just move forward + // probably would be wise at some point to rename to 'authenticatedUser' + + + return Promise.resolve(); + } // No matching CLP, let's check the Pointer permissions + // And handle those later + + + const permissionField = ['get', 'find', 'count'].indexOf(operation) > -1 ? 'readUserFields' : 'writeUserFields'; // Reject create when write lockdown + + if (permissionField == 'writeUserFields' && operation == 'create') { + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, `Permission denied for action ${operation} on class ${className}.`); + } // Process the readUserFields later + + + if (Array.isArray(classPermissions[permissionField]) && classPermissions[permissionField].length > 0) { + return Promise.resolve(); + } + + const pointerFields = classPermissions[operation].pointerFields; + + if (Array.isArray(pointerFields) && pointerFields.length > 0) { + // any op except 'addField as part of create' is ok. + if (operation !== 'addField' || action === 'update') { + // We can allow adding field on update flow only. + return Promise.resolve(); + } + } + + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, `Permission denied for action ${operation} on class ${className}.`); + } // Validates an operation passes class-level-permissions set in the schema + + + validatePermission(className, aclGroup, operation, action) { + return SchemaController.validatePermission(this.getClassLevelPermissions(className), className, aclGroup, operation, action); + } + + getClassLevelPermissions(className) { + return this.schemaData[className] && this.schemaData[className].classLevelPermissions; + } // Returns the expected type for a className+key combination + // or undefined if the schema is not set + + + getExpectedType(className, fieldName) { + if (this.schemaData[className]) { + const expectedType = this.schemaData[className].fields[fieldName]; + return expectedType === 'map' ? 'Object' : expectedType; + } + + return undefined; + } // Checks if a given class is in the schema. + + + hasClass(className) { + if (this.schemaData[className]) { + return Promise.resolve(true); + } + + return this.reloadData().then(() => !!this.schemaData[className]); + } + +} // Returns a promise for a new Schema. + + +exports.SchemaController = exports.default = SchemaController; + +const load = (dbAdapter, schemaCache, options) => { + const schema = new SchemaController(dbAdapter, schemaCache); + return schema.reloadData(options).then(() => schema); +}; // Builds a new schema (in schema API response format) out of an +// existing mongo schema + a schemas API put request. This response +// does not include the default fields, as it is intended to be passed +// to mongoSchemaFromFieldsAndClassName. No validation is done here, it +// is done in mongoSchemaFromFieldsAndClassName. + + +exports.load = load; + +function buildMergedSchemaObject(existingFields, putRequest) { + const newSchema = {}; // -disable-next + + const sysSchemaField = Object.keys(defaultColumns).indexOf(existingFields._id) === -1 ? [] : Object.keys(defaultColumns[existingFields._id]); + + for (const oldField in existingFields) { + if (oldField !== '_id' && oldField !== 'ACL' && oldField !== 'updatedAt' && oldField !== 'createdAt' && oldField !== 'objectId') { + if (sysSchemaField.length > 0 && sysSchemaField.indexOf(oldField) !== -1) { + continue; + } + + const fieldIsDeleted = putRequest[oldField] && putRequest[oldField].__op === 'Delete'; + + if (!fieldIsDeleted) { + newSchema[oldField] = existingFields[oldField]; + } + } + } + + for (const newField in putRequest) { + if (newField !== 'objectId' && putRequest[newField].__op !== 'Delete') { + if (sysSchemaField.length > 0 && sysSchemaField.indexOf(newField) !== -1) { + continue; + } + + newSchema[newField] = putRequest[newField]; + } + } + + return newSchema; +} // Given a schema promise, construct another schema promise that +// validates this field once the schema loads. + + +function thenValidateRequiredColumns(schemaPromise, className, object, query) { + return schemaPromise.then(schema => { + return schema.validateRequiredColumns(className, object, query); + }); +} // Gets the type from a REST API formatted object, where 'type' is +// extended past javascript types to include the rest of the Parse +// type system. +// The output should be a valid schema value. +// TODO: ensure that this is compatible with the format used in Open DB + + +function getType(obj) { + const type = typeof obj; + + switch (type) { + case 'boolean': + return 'Boolean'; + + case 'string': + return 'String'; + + case 'number': + return 'Number'; + + case 'map': + case 'object': + if (!obj) { + return undefined; + } + + return getObjectType(obj); + + case 'function': + case 'symbol': + case 'undefined': + default: + throw 'bad obj: ' + obj; + } +} // This gets the type for non-JSON types like pointers and files, but +// also gets the appropriate type for $ operators. +// Returns null if the type is unknown. + + +function getObjectType(obj) { + if (obj instanceof Array) { + return 'Array'; + } + + if (obj.__type) { + switch (obj.__type) { + case 'Pointer': + if (obj.className) { + return { + type: 'Pointer', + targetClass: obj.className + }; + } + + break; + + case 'Relation': + if (obj.className) { + return { + type: 'Relation', + targetClass: obj.className + }; + } + + break; + + case 'File': + if (obj.name) { + return 'File'; + } + + break; + + case 'Date': + if (obj.iso) { + return 'Date'; + } + + break; + + case 'GeoPoint': + if (obj.latitude != null && obj.longitude != null) { + return 'GeoPoint'; + } + + break; + + case 'Bytes': + if (obj.base64) { + return 'Bytes'; + } + + break; + + case 'Polygon': + if (obj.coordinates) { + return 'Polygon'; + } + + break; + } + + throw new Parse.Error(Parse.Error.INCORRECT_TYPE, 'This is not a valid ' + obj.__type); + } + + if (obj['$ne']) { + return getObjectType(obj['$ne']); + } + + if (obj.__op) { + switch (obj.__op) { + case 'Increment': + return 'Number'; + + case 'Delete': + return null; + + case 'Add': + case 'AddUnique': + case 'Remove': + return 'Array'; + + case 'AddRelation': + case 'RemoveRelation': + return { + type: 'Relation', + targetClass: obj.objects[0].className + }; + + case 'Batch': + return getObjectType(obj.ops[0]); + + default: + throw 'unexpected op: ' + obj.__op; + } + } + + return 'Object'; +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9TY2hlbWFDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsImRlZmF1bHRDb2x1bW5zIiwiT2JqZWN0IiwiZnJlZXplIiwiX0RlZmF1bHQiLCJvYmplY3RJZCIsInR5cGUiLCJjcmVhdGVkQXQiLCJ1cGRhdGVkQXQiLCJBQ0wiLCJfVXNlciIsInVzZXJuYW1lIiwicGFzc3dvcmQiLCJlbWFpbCIsImVtYWlsVmVyaWZpZWQiLCJhdXRoRGF0YSIsIl9JbnN0YWxsYXRpb24iLCJpbnN0YWxsYXRpb25JZCIsImRldmljZVRva2VuIiwiY2hhbm5lbHMiLCJkZXZpY2VUeXBlIiwicHVzaFR5cGUiLCJHQ01TZW5kZXJJZCIsInRpbWVab25lIiwibG9jYWxlSWRlbnRpZmllciIsImJhZGdlIiwiYXBwVmVyc2lvbiIsImFwcE5hbWUiLCJhcHBJZGVudGlmaWVyIiwicGFyc2VWZXJzaW9uIiwiX1JvbGUiLCJuYW1lIiwidXNlcnMiLCJ0YXJnZXRDbGFzcyIsInJvbGVzIiwiX1Nlc3Npb24iLCJyZXN0cmljdGVkIiwidXNlciIsInNlc3Npb25Ub2tlbiIsImV4cGlyZXNBdCIsImNyZWF0ZWRXaXRoIiwiX1Byb2R1Y3QiLCJwcm9kdWN0SWRlbnRpZmllciIsImRvd25sb2FkIiwiZG93bmxvYWROYW1lIiwiaWNvbiIsIm9yZGVyIiwidGl0bGUiLCJzdWJ0aXRsZSIsIl9QdXNoU3RhdHVzIiwicHVzaFRpbWUiLCJzb3VyY2UiLCJxdWVyeSIsInBheWxvYWQiLCJleHBpcnkiLCJleHBpcmF0aW9uX2ludGVydmFsIiwic3RhdHVzIiwibnVtU2VudCIsIm51bUZhaWxlZCIsInB1c2hIYXNoIiwiZXJyb3JNZXNzYWdlIiwic2VudFBlclR5cGUiLCJmYWlsZWRQZXJUeXBlIiwic2VudFBlclVUQ09mZnNldCIsImZhaWxlZFBlclVUQ09mZnNldCIsImNvdW50IiwiX0pvYlN0YXR1cyIsImpvYk5hbWUiLCJtZXNzYWdlIiwicGFyYW1zIiwiZmluaXNoZWRBdCIsIl9Kb2JTY2hlZHVsZSIsImRlc2NyaXB0aW9uIiwic3RhcnRBZnRlciIsImRheXNPZldlZWsiLCJ0aW1lT2ZEYXkiLCJsYXN0UnVuIiwicmVwZWF0TWludXRlcyIsIl9Ib29rcyIsImZ1bmN0aW9uTmFtZSIsImNsYXNzTmFtZSIsInRyaWdnZXJOYW1lIiwidXJsIiwiX0dsb2JhbENvbmZpZyIsIm1hc3RlcktleU9ubHkiLCJfR3JhcGhRTENvbmZpZyIsImNvbmZpZyIsIl9BdWRpZW5jZSIsImxhc3RVc2VkIiwidGltZXNVc2VkIiwiX0lkZW1wb3RlbmN5IiwicmVxSWQiLCJleHBpcmUiLCJyZXF1aXJlZENvbHVtbnMiLCJpbnZhbGlkQ29sdW1ucyIsInN5c3RlbUNsYXNzZXMiLCJ2b2xhdGlsZUNsYXNzZXMiLCJyb2xlUmVnZXgiLCJwcm90ZWN0ZWRGaWVsZHNQb2ludGVyUmVnZXgiLCJwdWJsaWNSZWdleCIsImF1dGhlbnRpY2F0ZWRSZWdleCIsInJlcXVpcmVzQXV0aGVudGljYXRpb25SZWdleCIsImNscFBvaW50ZXJSZWdleCIsInByb3RlY3RlZEZpZWxkc1JlZ2V4IiwiY2xwRmllbGRzUmVnZXgiLCJ2YWxpZGF0ZVBlcm1pc3Npb25LZXkiLCJrZXkiLCJ1c2VySWRSZWdFeHAiLCJtYXRjaGVzU29tZSIsInJlZ0V4IiwibWF0Y2giLCJ2YWxpZCIsIkVycm9yIiwiSU5WQUxJRF9KU09OIiwidmFsaWRhdGVQcm90ZWN0ZWRGaWVsZHNLZXkiLCJDTFBWYWxpZEtleXMiLCJ2YWxpZGF0ZUNMUCIsInBlcm1zIiwiZmllbGRzIiwib3BlcmF0aW9uS2V5IiwiaW5kZXhPZiIsIm9wZXJhdGlvbiIsInZhbGlkYXRlQ0xQanNvbiIsImZpZWxkTmFtZSIsInZhbGlkYXRlUG9pbnRlclBlcm1pc3Npb24iLCJlbnRpdHkiLCJwcm90ZWN0ZWRGaWVsZHMiLCJBcnJheSIsImlzQXJyYXkiLCJmaWVsZCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInBvaW50ZXJGaWVsZHMiLCJwb2ludGVyRmllbGQiLCJwZXJtaXQiLCJqb2luQ2xhc3NSZWdleCIsImNsYXNzQW5kRmllbGRSZWdleCIsImNsYXNzTmFtZUlzVmFsaWQiLCJ0ZXN0IiwiZmllbGROYW1lSXNWYWxpZCIsImluY2x1ZGVzIiwiZmllbGROYW1lSXNWYWxpZEZvckNsYXNzIiwiaW52YWxpZENsYXNzTmFtZU1lc3NhZ2UiLCJpbnZhbGlkSnNvbkVycm9yIiwidmFsaWROb25SZWxhdGlvbk9yUG9pbnRlclR5cGVzIiwiZmllbGRUeXBlSXNJbnZhbGlkIiwiSU5WQUxJRF9DTEFTU19OQU1FIiwidW5kZWZpbmVkIiwiSU5DT1JSRUNUX1RZUEUiLCJjb252ZXJ0U2NoZW1hVG9BZGFwdGVyU2NoZW1hIiwic2NoZW1hIiwiaW5qZWN0RGVmYXVsdFNjaGVtYSIsIl9ycGVybSIsIl93cGVybSIsIl9oYXNoZWRfcGFzc3dvcmQiLCJjb252ZXJ0QWRhcHRlclNjaGVtYVRvUGFyc2VTY2hlbWEiLCJpbmRleGVzIiwia2V5cyIsImxlbmd0aCIsIlNjaGVtYURhdGEiLCJjb25zdHJ1Y3RvciIsImFsbFNjaGVtYXMiLCJfX2RhdGEiLCJfX3Byb3RlY3RlZEZpZWxkcyIsImZvckVhY2giLCJkZWZpbmVQcm9wZXJ0eSIsImdldCIsImRhdGEiLCJjbGFzc0xldmVsUGVybWlzc2lvbnMiLCJjbGFzc1Byb3RlY3RlZEZpZWxkcyIsInVucSIsIlNldCIsImZyb20iLCJkZWZhdWx0U2NoZW1hIiwiX0hvb2tzU2NoZW1hIiwiX0dsb2JhbENvbmZpZ1NjaGVtYSIsIl9HcmFwaFFMQ29uZmlnU2NoZW1hIiwiX1B1c2hTdGF0dXNTY2hlbWEiLCJfSm9iU3RhdHVzU2NoZW1hIiwiX0pvYlNjaGVkdWxlU2NoZW1hIiwiX0F1ZGllbmNlU2NoZW1hIiwiX0lkZW1wb3RlbmN5U2NoZW1hIiwiVm9sYXRpbGVDbGFzc2VzU2NoZW1hcyIsImRiVHlwZU1hdGNoZXNPYmplY3RUeXBlIiwiZGJUeXBlIiwib2JqZWN0VHlwZSIsInR5cGVUb1N0cmluZyIsIlNjaGVtYUNvbnRyb2xsZXIiLCJkYXRhYmFzZUFkYXB0ZXIiLCJzY2hlbWFDYWNoZSIsIl9kYkFkYXB0ZXIiLCJfY2FjaGUiLCJzY2hlbWFEYXRhIiwiQ29uZmlnIiwiYXBwbGljYXRpb25JZCIsImN1c3RvbUlkcyIsImFsbG93Q3VzdG9tT2JqZWN0SWQiLCJjdXN0b21JZFJlZ0V4IiwiYXV0b0lkUmVnRXgiLCJ1c2VySWRSZWdFeCIsInJlbG9hZERhdGEiLCJvcHRpb25zIiwiY2xlYXJDYWNoZSIsInJlbG9hZERhdGFQcm9taXNlIiwiZ2V0QWxsQ2xhc3NlcyIsInRoZW4iLCJlcnIiLCJzZXRBbGxDbGFzc2VzIiwiYWxsQ2xhc3NlcyIsIlByb21pc2UiLCJyZXNvbHZlIiwibWFwIiwiY2F0Y2giLCJlcnJvciIsImNvbnNvbGUiLCJnZXRPbmVTY2hlbWEiLCJhbGxvd1ZvbGF0aWxlQ2xhc3NlcyIsInByb21pc2UiLCJjbGVhciIsImNhY2hlZCIsIm9uZVNjaGVtYSIsImZpbmQiLCJyZWplY3QiLCJhZGRDbGFzc0lmTm90RXhpc3RzIiwidmFsaWRhdGlvbkVycm9yIiwidmFsaWRhdGVOZXdDbGFzcyIsImNvZGUiLCJjcmVhdGVDbGFzcyIsIkRVUExJQ0FURV9WQUxVRSIsInVwZGF0ZUNsYXNzIiwic3VibWl0dGVkRmllbGRzIiwiZGF0YWJhc2UiLCJleGlzdGluZ0ZpZWxkcyIsIl9fb3AiLCJuZXdTY2hlbWEiLCJidWlsZE1lcmdlZFNjaGVtYU9iamVjdCIsImRlZmF1bHRGaWVsZHMiLCJmdWxsTmV3U2NoZW1hIiwiYXNzaWduIiwidmFsaWRhdGVTY2hlbWFEYXRhIiwiZGVsZXRlZEZpZWxkcyIsImluc2VydGVkRmllbGRzIiwicHVzaCIsImRlbGV0ZVByb21pc2UiLCJkZWxldGVGaWVsZHMiLCJlbmZvcmNlRmllbGRzIiwicHJvbWlzZXMiLCJlbmZvcmNlRmllbGRFeGlzdHMiLCJhbGwiLCJyZXN1bHRzIiwiZmlsdGVyIiwicmVzdWx0Iiwic2V0UGVybWlzc2lvbnMiLCJzZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdCIsImVuc3VyZUZpZWxkcyIsInJlbG9hZGVkU2NoZW1hIiwiZW5mb3JjZUNsYXNzRXhpc3RzIiwiZXhpc3RpbmdGaWVsZE5hbWVzIiwiSU5WQUxJRF9LRVlfTkFNRSIsImZpZWxkVHlwZSIsImRlZmF1bHRWYWx1ZSIsImRlZmF1bHRWYWx1ZVR5cGUiLCJnZXRUeXBlIiwicmVxdWlyZWQiLCJnZW9Qb2ludHMiLCJzZXRDbGFzc0xldmVsUGVybWlzc2lvbnMiLCJzcGxpdCIsImV4cGVjdGVkVHlwZSIsImdldEV4cGVjdGVkVHlwZSIsImFkZEZpZWxkSWZOb3RFeGlzdHMiLCJpIiwiZGVsZXRlRmllbGQiLCJmaWVsZE5hbWVzIiwic2NoZW1hRmllbGRzIiwiYWRhcHRlciIsImRlbGV0ZUNsYXNzIiwidmFsaWRhdGVPYmplY3QiLCJvYmplY3QiLCJnZW9jb3VudCIsImV4cGVjdGVkIiwidGhlblZhbGlkYXRlUmVxdWlyZWRDb2x1bW5zIiwidmFsaWRhdGVSZXF1aXJlZENvbHVtbnMiLCJjb2x1bW5zIiwibWlzc2luZ0NvbHVtbnMiLCJjb2x1bW4iLCJ0ZXN0UGVybWlzc2lvbnNGb3JDbGFzc05hbWUiLCJhY2xHcm91cCIsInRlc3RQZXJtaXNzaW9ucyIsImdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsImNsYXNzUGVybWlzc2lvbnMiLCJzb21lIiwiYWNsIiwidmFsaWRhdGVQZXJtaXNzaW9uIiwiYWN0aW9uIiwiT0JKRUNUX05PVF9GT1VORCIsInBlcm1pc3Npb25GaWVsZCIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJoYXNDbGFzcyIsImxvYWQiLCJkYkFkYXB0ZXIiLCJwdXRSZXF1ZXN0Iiwic3lzU2NoZW1hRmllbGQiLCJfaWQiLCJvbGRGaWVsZCIsImZpZWxkSXNEZWxldGVkIiwibmV3RmllbGQiLCJzY2hlbWFQcm9taXNlIiwib2JqIiwiZ2V0T2JqZWN0VHlwZSIsIl9fdHlwZSIsImlzbyIsImxhdGl0dWRlIiwibG9uZ2l0dWRlIiwiYmFzZTY0IiwiY29vcmRpbmF0ZXMi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ZW50IjpbIi8vIEBmbG93XG4vLyBUaGlzIGNsYXNzIGhhbmRsZXMgc2NoZW1hIHZhbGlkYXRpb24sIHBlcnNpc3RlbmNlLCBhbmQgbW9kaWZpY2F0aW9uLlxuLy9cbi8vIEVhY2ggaW5kaXZpZHVhbCBTY2hlbWEgb2JqZWN0IHNob3VsZCBiZSBpbW11dGFibGUuIFRoZSBoZWxwZXJzIHRvXG4vLyBkbyB0aGluZ3Mgd2l0aCB0aGUgU2NoZW1hIGp1c3QgcmV0dXJuIGEgbmV3IHNjaGVtYSB3aGVuIHRoZSBzY2hlbWFcbi8vIGlzIGNoYW5nZWQuXG4vL1xuLy8gVGhlIGNhbm9uaWNhbCBwbGFjZSB0byBzdG9yZSB0aGlzIFNjaGVtYSBpcyBpbiB0aGUgZGF0YWJhc2UgaXRzZWxmLFxuLy8gaW4gYSBfU0NIRU1BIGNvbGxlY3Rpb24uIFRoaXMgaXMgbm90IHRoZSByaWdodCB3YXkgdG8gZG8gaXQgZm9yIGFuXG4vLyBvcGVuIHNvdXJjZSBmcmFtZXdvcmssIGJ1dCBpdCdzIGJhY2t3YXJkIGNvbXBhdGlibGUsIHNvIHdlJ3JlXG4vLyBrZWVwaW5nIGl0IHRoaXMgd2F5IGZvciBub3cuXG4vL1xuLy8gSW4gQVBJLWhhbmRsaW5nIGNvZGUsIHlvdSBzaG91bGQgb25seSB1c2UgdGhlIFNjaGVtYSBjbGFzcyB2aWEgdGhlXG4vLyBEYXRhYmFzZUNvbnRyb2xsZXIuIFRoaXMgd2lsbCBsZXQgdXMgcmVwbGFjZSB0aGUgc2NoZW1hIGxvZ2ljIGZvclxuLy8gZGlmZmVyZW50IGRhdGFiYXNlcy5cbi8vIFRPRE86IGhpZGUgYWxsIHNjaGVtYSBsb2dpYyBpbnNpZGUgdGhlIGRhdGFiYXNlIGFkYXB0ZXIuXG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmNvbnN0IFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuaW1wb3J0IHsgU3RvcmFnZUFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9TdG9yYWdlL1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCBEYXRhYmFzZUNvbnRyb2xsZXIgZnJvbSAnLi9EYXRhYmFzZUNvbnRyb2xsZXInO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuLi9Db25maWcnO1xuLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG5pbXBvcnQgZGVlcGNvcHkgZnJvbSAnZGVlcGNvcHknO1xuaW1wb3J0IHR5cGUge1xuICBTY2hlbWEsXG4gIFNjaGVtYUZpZWxkcyxcbiAgQ2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICBTY2hlbWFGaWVsZCxcbiAgTG9hZFNjaGVtYU9wdGlvbnMsXG59IGZyb20gJy4vdHlwZXMnO1xuXG5jb25zdCBkZWZhdWx0Q29sdW1uczogeyBbc3RyaW5nXTogU2NoZW1hRmllbGRzIH0gPSBPYmplY3QuZnJlZXplKHtcbiAgLy8gQ29udGFpbiB0aGUgZGVmYXVsdCBjb2x1bW5zIGZvciBldmVyeSBwYXJzZSBvYmplY3QgdHlwZSAoZXhjZXB0IF9Kb2luIGNvbGxlY3Rpb24pXG4gIF9EZWZhdWx0OiB7XG4gICAgb2JqZWN0SWQ6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBjcmVhdGVkQXQ6IHsgdHlwZTogJ0RhdGUnIH0sXG4gICAgdXBkYXRlZEF0OiB7IHR5cGU6ICdEYXRlJyB9LFxuICAgIEFDTDogeyB0eXBlOiAnQUNMJyB9LFxuICB9LFxuICAvLyBUaGUgYWRkaXRpb25hbCBkZWZhdWx0IGNvbHVtbnMgZm9yIHRoZSBfVXNlciBjb2xsZWN0aW9uIChpbiBhZGRpdGlvbiB0byBEZWZhdWx0Q29scylcbiAgX1VzZXI6IHtcbiAgICB1c2VybmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHBhc3N3b3JkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZW1haWw6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBlbWFpbFZlcmlmaWVkOiB7IHR5cGU6ICdCb29sZWFuJyB9LFxuICAgIGF1dGhEYXRhOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gIH0sXG4gIC8vIFRoZSBhZGRpdGlvbmFsIGRlZmF1bHQgY29sdW1ucyBmb3IgdGhlIF9JbnN0YWxsYXRpb24gY29sbGVjdGlvbiAoaW4gYWRkaXRpb24gdG8gRGVmYXVsdENvbHMpXG4gIF9JbnN0YWxsYXRpb246IHtcbiAgICBpbnN0YWxsYXRpb25JZDogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGRldmljZVRva2VuOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgY2hhbm5lbHM6IHsgdHlwZTogJ0FycmF5JyB9LFxuICAgIGRldmljZVR5cGU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBwdXNoVHlwZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIEdDTVNlbmRlcklkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgdGltZVpvbmU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBsb2NhbGVJZGVudGlmaWVyOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgYmFkZ2U6IHsgdHlwZTogJ051bWJlcicgfSxcbiAgICBhcHBWZXJzaW9uOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgYXBwTmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGFwcElkZW50aWZpZXI6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBwYXJzZVZlcnNpb246IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgfSxcbiAgLy8gVGhlIGFkZGl0aW9uYWwgZGVmYXVsdCBjb2x1bW5zIGZvciB0aGUgX1JvbGUgY29sbGVjdGlvbiAoaW4gYWRkaXRpb24gdG8gRGVmYXVsdENvbHMpXG4gIF9Sb2xlOiB7XG4gICAgbmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHVzZXJzOiB7IHR5cGU6ICdSZWxhdGlvbicsIHRhcmdldENsYXNzOiAnX1VzZXInIH0sXG4gICAgcm9sZXM6IHsgdHlwZTogJ1JlbGF0aW9uJywgdGFyZ2V0Q2xhc3M6ICdfUm9sZScgfSxcbiAgfSxcbiAgLy8gVGhlIGFkZGl0aW9uYWwgZGVmYXVsdCBjb2x1bW5zIGZvciB0aGUgX1Nlc3Npb24gY29sbGVjdGlvbiAoaW4gYWRkaXRpb24gdG8gRGVmYXVsdENvbHMpXG4gIF9TZXNzaW9uOiB7XG4gICAgcmVzdHJpY3RlZDogeyB0eXBlOiAnQm9vbGVhbicgfSxcbiAgICB1c2VyOiB7IHR5cGU6ICdQb2ludGVyJywgdGFyZ2V0Q2xhc3M6ICdfVXNlcicgfSxcbiAgICBpbnN0YWxsYXRpb25JZDogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHNlc3Npb25Ub2tlbjogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGV4cGlyZXNBdDogeyB0eXBlOiAnRGF0ZScgfSxcbiAgICBjcmVhdGVkV2l0aDogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICB9LFxuICBfUHJvZHVjdDoge1xuICAgIHByb2R1Y3RJZGVudGlmaWVyOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZG93bmxvYWQ6IHsgdHlwZTogJ0ZpbGUnIH0sXG4gICAgZG93bmxvYWROYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgaWNvbjogeyB0eXBlOiAnRmlsZScgfSxcbiAgICBvcmRlcjogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICAgIHRpdGxlOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgc3VidGl0bGU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgfSxcbiAgX1B1c2hTdGF0dXM6IHtcbiAgICBwdXNoVGltZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHNvdXJjZTogeyB0eXBlOiAnU3RyaW5nJyB9LCAvLyByZXN0IG9yIHdlYnVpXG4gICAgcXVlcnk6IHsgdHlwZTogJ1N0cmluZycgfSwgLy8gdGhlIHN0cmluZ2lmaWVkIEpTT04gcXVlcnlcbiAgICBwYXlsb2FkOiB7IHR5cGU6ICdTdHJpbmcnIH0sIC8vIHRoZSBzdHJpbmdpZmllZCBKU09OIHBheWxvYWQsXG4gICAgdGl0bGU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBleHBpcnk6IHsgdHlwZTogJ051bWJlcicgfSxcbiAgICBleHBpcmF0aW9uX2ludGVydmFsOiB7IHR5cGU6ICdOdW1iZXInIH0sXG4gICAgc3RhdHVzOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgbnVtU2VudDogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICAgIG51bUZhaWxlZDogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICAgIHB1c2hIYXNoOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZXJyb3JNZXNzYWdlOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gICAgc2VudFBlclR5cGU6IHsgdHlwZTogJ09iamVjdCcgfSxcbiAgICBmYWlsZWRQZXJUeXBlOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gICAgc2VudFBlclVUQ09mZnNldDogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICAgIGZhaWxlZFBlclVUQ09mZnNldDogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICAgIGNvdW50OiB7IHR5cGU6ICdOdW1iZXInIH0sIC8vIHRyYWNrcyAjIG9mIGJhdGNoZXMgcXVldWVkIGFuZCBwZW5kaW5nXG4gIH0sXG4gIF9Kb2JTdGF0dXM6IHtcbiAgICBqb2JOYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgc291cmNlOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgc3RhdHVzOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgbWVzc2FnZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHBhcmFtczogeyB0eXBlOiAnT2JqZWN0JyB9LCAvLyBwYXJhbXMgcmVjZWl2ZWQgd2hlbiBjYWxsaW5nIHRoZSBqb2JcbiAgICBmaW5pc2hlZEF0OiB7IHR5cGU6ICdEYXRlJyB9LFxuICB9LFxuICBfSm9iU2NoZWR1bGU6IHtcbiAgICBqb2JOYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZGVzY3JpcHRpb246IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBwYXJhbXM6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBzdGFydEFmdGVyOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZGF5c09mV2VlazogeyB0eXBlOiAnQXJyYXknIH0sXG4gICAgdGltZU9mRGF5OiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgbGFzdFJ1bjogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICAgIHJlcGVhdE1pbnV0ZXM6IHsgdHlwZTogJ051bWJlcicgfSxcbiAgfSxcbiAgX0hvb2tzOiB7XG4gICAgZnVuY3Rpb25OYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgY2xhc3NOYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgdHJpZ2dlck5hbWU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICB1cmw6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgfSxcbiAgX0dsb2JhbENvbmZpZzoge1xuICAgIG9iamVjdElkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgcGFyYW1zOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gICAgbWFzdGVyS2V5T25seTogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICB9LFxuICBfR3JhcGhRTENvbmZpZzoge1xuICAgIG9iamVjdElkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgY29uZmlnOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gIH0sXG4gIF9BdWRpZW5jZToge1xuICAgIG9iamVjdElkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgbmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHF1ZXJ5OiB7IHR5cGU6ICdTdHJpbmcnIH0sIC8vc3RvcmluZyBxdWVyeSBhcyBKU09OIHN0cmluZyB0byBwcmV2ZW50IFwiTmVzdGVkIGtleXMgc2hvdWxkIG5vdCBjb250YWluIHRoZSAnJCcgb3IgJy4nIGNoYXJhY3RlcnNcIiBlcnJvclxuICAgIGxhc3RVc2VkOiB7IHR5cGU6ICdEYXRlJyB9LFxuICAgIHRpbWVzVXNlZDogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICB9LFxuICBfSWRlbXBvdGVuY3k6IHtcbiAgICByZXFJZDogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGV4cGlyZTogeyB0eXBlOiAnRGF0ZScgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCByZXF1aXJlZENvbHVtbnMgPSBPYmplY3QuZnJlZXplKHtcbiAgX1Byb2R1Y3Q6IFsncHJvZHVjdElkZW50aWZpZXInLCAnaWNvbicsICdvcmRlcicsICd0aXRsZScsICdzdWJ0aXRsZSddLFxuICBfUm9sZTogWyduYW1lJywgJ0FDTCddLFxufSk7XG5cbmNvbnN0IGludmFsaWRDb2x1bW5zID0gWydsZW5ndGgnXTtcblxuY29uc3Qgc3lzdGVtQ2xhc3NlcyA9IE9iamVjdC5mcmVlemUoW1xuICAnX1VzZXInLFxuICAnX0luc3RhbGxhdGlvbicsXG4gICdfUm9sZScsXG4gICdfU2Vzc2lvbicsXG4gICdfUHJvZHVjdCcsXG4gICdfUHVzaFN0YXR1cycsXG4gICdfSm9iU3RhdHVzJyxcbiAgJ19Kb2JTY2hlZHVsZScsXG4gICdfQXVkaWVuY2UnLFxuICAnX0lkZW1wb3RlbmN5Jyxcbl0pO1xuXG5jb25zdCB2b2xhdGlsZUNsYXNzZXMgPSBPYmplY3QuZnJlZXplKFtcbiAgJ19Kb2JTdGF0dXMnLFxuICAnX1B1c2hTdGF0dXMnLFxuICAnX0hvb2tzJyxcbiAgJ19HbG9iYWxDb25maWcnLFxuICAnX0dyYXBoUUxDb25maWcnLFxuICAnX0pvYlNjaGVkdWxlJyxcbiAgJ19BdWRpZW5jZScsXG4gICdfSWRlbXBvdGVuY3knLFxuXSk7XG5cbi8vIEFueXRoaW5nIHRoYXQgc3RhcnQgd2l0aCByb2xlXG5jb25zdCByb2xlUmVnZXggPSAvXnJvbGU6LiovO1xuLy8gQW55dGhpbmcgdGhhdCBzdGFydHMgd2l0aCB1c2VyRmllbGQgKGFsbG93ZWQgZm9yIHByb3RlY3RlZCBmaWVsZHMgb25seSlcbmNvbnN0IHByb3RlY3RlZEZpZWxkc1BvaW50ZXJSZWdleCA9IC9edXNlckZpZWxkOi4qLztcbi8vICogcGVybWlzc2lvblxuY29uc3QgcHVibGljUmVnZXggPSAvXlxcKiQvO1xuXG5jb25zdCBhdXRoZW50aWNhdGVkUmVnZXggPSAvXmF1dGhlbnRpY2F0ZWQkLztcblxuY29uc3QgcmVxdWlyZXNBdXRoZW50aWNhdGlvblJlZ2V4ID0gL15yZXF1aXJlc0F1dGhlbnRpY2F0aW9uJC87XG5cbmNvbnN0IGNscFBvaW50ZXJSZWdleCA9IC9ecG9pbnRlckZpZWxkcyQvO1xuXG4vLyByZWdleCBmb3IgdmFsaWRhdGluZyBlbnRpdGllcyBpbiBwcm90ZWN0ZWRGaWVsZHMgb2JqZWN0XG5jb25zdCBwcm90ZWN0ZWRGaWVsZHNSZWdleCA9IE9iamVjdC5mcmVlemUoW1xuICBwcm90ZWN0ZWRGaWVsZHNQb2ludGVyUmVnZXgsXG4gIHB1YmxpY1JlZ2V4LFxuICBhdXRoZW50aWNhdGVkUmVnZXgsXG4gIHJvbGVSZWdleCxcbl0pO1xuXG4vLyBjbHAgcmVnZXhcbmNvbnN0IGNscEZpZWxkc1JlZ2V4ID0gT2JqZWN0LmZyZWV6ZShbXG4gIGNscFBvaW50ZXJSZWdleCxcbiAgcHVibGljUmVnZXgsXG4gIHJlcXVpcmVzQXV0aGVudGljYXRpb25SZWdleCxcbiAgcm9sZVJlZ2V4LFxuXSk7XG5cbmZ1bmN0aW9uIHZhbGlkYXRlUGVybWlzc2lvbktleShrZXksIHVzZXJJZFJlZ0V4cCkge1xuICBsZXQgbWF0Y2hlc1NvbWUgPSBmYWxzZTtcbiAgZm9yIChjb25zdCByZWdFeCBvZiBjbHBGaWVsZHNSZWdleCkge1xuICAgIGlmIChrZXkubWF0Y2gocmVnRXgpICE9PSBudWxsKSB7XG4gICAgICBtYXRjaGVzU29tZSA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvLyB1c2VySWQgZGVwZW5kcyBvbiBzdGFydHVwIG9wdGlvbnMgc28gaXQncyBkeW5hbWljXG4gIGNvbnN0IHZhbGlkID0gbWF0Y2hlc1NvbWUgfHwga2V5Lm1hdGNoKHVzZXJJZFJlZ0V4cCkgIT09IG51bGw7XG4gIGlmICghdmFsaWQpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICBgJyR7a2V5fScgaXMgbm90IGEgdmFsaWQga2V5IGZvciBjbGFzcyBsZXZlbCBwZXJtaXNzaW9uc2BcbiAgICApO1xuICB9XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlUHJvdGVjdGVkRmllbGRzS2V5KGtleSwgdXNlcklkUmVnRXhwKSB7XG4gIGxldCBtYXRjaGVzU29tZSA9IGZhbHNlO1xuICBmb3IgKGNvbnN0IHJlZ0V4IG9mIHByb3RlY3RlZEZpZWxkc1JlZ2V4KSB7XG4gICAgaWYgKGtleS5tYXRjaChyZWdFeCkgIT09IG51bGwpIHtcbiAgICAgIG1hdGNoZXNTb21lID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8vIHVzZXJJZCByZWdleCBkZXBlbmRzIG9uIGxhdW5jaCBvcHRpb25zIHNvIGl0J3MgZHluYW1pY1xuICBjb25zdCB2YWxpZCA9IG1hdGNoZXNTb21lIHx8IGtleS5tYXRjaCh1c2VySWRSZWdFeHApICE9PSBudWxsO1xuICBpZiAoIXZhbGlkKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgYCcke2tleX0nIGlzIG5vdCBhIHZhbGlkIGtleSBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnNgXG4gICAgKTtcbiAgfVxufVxuXG5jb25zdCBDTFBWYWxpZEtleXMgPSBPYmplY3QuZnJlZXplKFtcbiAgJ2ZpbmQnLFxuICAnY291bnQnLFxuICAnZ2V0JyxcbiAgJ2NyZWF0ZScsXG4gICd1cGRhdGUnLFxuICAnZGVsZXRlJyxcbiAgJ2FkZEZpZWxkJyxcbiAgJ3JlYWRVc2VyRmllbGRzJyxcbiAgJ3dyaXRlVXNlckZpZWxkcycsXG4gICdwcm90ZWN0ZWRGaWVsZHMnLFxuXSk7XG5cbi8vIHZhbGlkYXRpb24gYmVmb3JlIHNldHRpbmcgY2xhc3MtbGV2ZWwgcGVybWlzc2lvbnMgb24gY29sbGVjdGlvblxuZnVuY3Rpb24gdmFsaWRhdGVDTFAocGVybXM6IENsYXNzTGV2ZWxQZXJtaXNzaW9ucywgZmllbGRzOiBTY2hlbWFGaWVsZHMsIHVzZXJJZFJlZ0V4cDogUmVnRXhwKSB7XG4gIGlmICghcGVybXMpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgZm9yIChjb25zdCBvcGVyYXRpb25LZXkgaW4gcGVybXMpIHtcbiAgICBpZiAoQ0xQVmFsaWRLZXlzLmluZGV4T2Yob3BlcmF0aW9uS2V5KSA9PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgIGAke29wZXJhdGlvbktleX0gaXMgbm90IGEgdmFsaWQgb3BlcmF0aW9uIGZvciBjbGFzcyBsZXZlbCBwZXJtaXNzaW9uc2BcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3Qgb3BlcmF0aW9uID0gcGVybXNbb3BlcmF0aW9uS2V5XTtcbiAgICAvLyBwcm9jZWVkIHdpdGggbmV4dCBvcGVyYXRpb25LZXlcblxuICAgIC8vIHRocm93cyB3aGVuIHJvb3QgZmllbGRzIGFyZSBvZiB3cm9uZyB0eXBlXG4gICAgdmFsaWRhdGVDTFBqc29uKG9wZXJhdGlvbiwgb3BlcmF0aW9uS2V5KTtcblxuICAgIGlmIChvcGVyYXRpb25LZXkgPT09ICdyZWFkVXNlckZpZWxkcycgfHwgb3BlcmF0aW9uS2V5ID09PSAnd3JpdGVVc2VyRmllbGRzJykge1xuICAgICAgLy8gdmFsaWRhdGUgZ3JvdXBlZCBwb2ludGVyIHBlcm1pc3Npb25zXG4gICAgICAvLyBtdXN0IGJlIGFuIGFycmF5IHdpdGggZmllbGQgbmFtZXNcbiAgICAgIGZvciAoY29uc3QgZmllbGROYW1lIG9mIG9wZXJhdGlvbikge1xuICAgICAgICB2YWxpZGF0ZVBvaW50ZXJQZXJtaXNzaW9uKGZpZWxkTmFtZSwgZmllbGRzLCBvcGVyYXRpb25LZXkpO1xuICAgICAgfVxuICAgICAgLy8gcmVhZFVzZXJGaWVsZHMgYW5kIHdyaXRlclVzZXJGaWVsZHMgZG8gbm90IGhhdmUgbmVzZHRlZCBmaWVsZHNcbiAgICAgIC8vIHByb2NlZWQgd2l0aCBuZXh0IG9wZXJhdGlvbktleVxuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gdmFsaWRhdGUgcHJvdGVjdGVkIGZpZWxkc1xuICAgIGlmIChvcGVyYXRpb25LZXkgPT09ICdwcm90ZWN0ZWRGaWVsZHMnKSB7XG4gICAgICBmb3IgKGNvbnN0IGVudGl0eSBpbiBvcGVyYXRpb24pIHtcbiAgICAgICAgLy8gdGhyb3dzIG9uIHVuZXhwZWN0ZWQga2V5XG4gICAgICAgIHZhbGlkYXRlUHJvdGVjdGVkRmllbGRzS2V5KGVudGl0eSwgdXNlcklkUmVnRXhwKTtcblxuICAgICAgICBjb25zdCBwcm90ZWN0ZWRGaWVsZHMgPSBvcGVyYXRpb25bZW50aXR5XTtcblxuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkocHJvdGVjdGVkRmllbGRzKSkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgIGAnJHtwcm90ZWN0ZWRGaWVsZHN9JyBpcyBub3QgYSB2YWxpZCB2YWx1ZSBmb3IgcHJvdGVjdGVkRmllbGRzWyR7ZW50aXR5fV0gLSBleHBlY3RlZCBhbiBhcnJheS5gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIHRoZSBmaWVsZCBpcyBpbiBmb3JtIG9mIGFycmF5XG4gICAgICAgIGZvciAoY29uc3QgZmllbGQgb2YgcHJvdGVjdGVkRmllbGRzKSB7XG4gICAgICAgICAgLy8gZG8gbm90IGFsbG9vdyB0byBwcm90ZWN0IGRlZmF1bHQgZmllbGRzXG4gICAgICAgICAgaWYgKGRlZmF1bHRDb2x1bW5zLl9EZWZhdWx0W2ZpZWxkXSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAgIGBEZWZhdWx0IGZpZWxkICcke2ZpZWxkfScgY2FuIG5vdCBiZSBwcm90ZWN0ZWRgXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBmaWVsZCBzaG91bGQgZXhpc3Qgb24gY29sbGVjdGlvblxuICAgICAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGZpZWxkcywgZmllbGQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgYEZpZWxkICcke2ZpZWxkfScgaW4gcHJvdGVjdGVkRmllbGRzOiR7ZW50aXR5fSBkb2VzIG5vdCBleGlzdGBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBwcm9jZWVkIHdpdGggbmV4dCBvcGVyYXRpb25LZXlcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIHZhbGlkYXRlIG90aGVyIGZpZWxkc1xuICAgIC8vIEVudGl0eSBjYW4gYmU6XG4gICAgLy8gXCIqXCIgLSBQdWJsaWMsXG4gICAgLy8gXCJyZXF1aXJlc0F1dGhlbnRpY2F0aW9uXCIgLSBhdXRoZW50aWNhdGVkIHVzZXJzLFxuICAgIC8vIFwib2JqZWN0SWRcIiAtIF9Vc2VyIGlkLFxuICAgIC8vIFwicm9sZTpyb2xlbmFtZVwiLFxuICAgIC8vIFwicG9pbnRlckZpZWxkc1wiIC0gYXJyYXkgb2YgZmllbGQgbmFtZXMgY29udGFpbmluZyBwb2ludGVycyB0byB1c2Vyc1xuICAgIGZvciAoY29uc3QgZW50aXR5IGluIG9wZXJhdGlvbikge1xuICAgICAgLy8gdGhyb3dzIG9uIHVuZXhwZWN0ZWQga2V5XG4gICAgICB2YWxpZGF0ZVBlcm1pc3Npb25LZXkoZW50aXR5LCB1c2VySWRSZWdFeHApO1xuXG4gICAgICAvLyBlbnRpdHkgY2FuIGJlIGVpdGhlcjpcbiAgICAgIC8vIFwicG9pbnRlckZpZWxkc1wiOiBzdHJpbmdbXVxuICAgICAgaWYgKGVudGl0eSA9PT0gJ3BvaW50ZXJGaWVsZHMnKSB7XG4gICAgICAgIGNvbnN0IHBvaW50ZXJGaWVsZHMgPSBvcGVyYXRpb25bZW50aXR5XTtcblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShwb2ludGVyRmllbGRzKSkge1xuICAgICAgICAgIGZvciAoY29uc3QgcG9pbnRlckZpZWxkIG9mIHBvaW50ZXJGaWVsZHMpIHtcbiAgICAgICAgICAgIHZhbGlkYXRlUG9pbnRlclBlcm1pc3Npb24ocG9pbnRlckZpZWxkLCBmaWVsZHMsIG9wZXJhdGlvbik7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgIGAnJHtwb2ludGVyRmllbGRzfScgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yICR7b3BlcmF0aW9uS2V5fVske2VudGl0eX1dIC0gZXhwZWN0ZWQgYW4gYXJyYXkuYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcHJvY2VlZCB3aXRoIG5leHQgZW50aXR5IGtleVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gb3IgW2VudGl0eV06IGJvb2xlYW5cbiAgICAgIGNvbnN0IHBlcm1pdCA9IG9wZXJhdGlvbltlbnRpdHldO1xuXG4gICAgICBpZiAocGVybWl0ICE9PSB0cnVlKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgYCcke3Blcm1pdH0nIGlzIG5vdCBhIHZhbGlkIHZhbHVlIGZvciBjbGFzcyBsZXZlbCBwZXJtaXNzaW9ucyAke29wZXJhdGlvbktleX06JHtlbnRpdHl9OiR7cGVybWl0fWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVDTFBqc29uKG9wZXJhdGlvbjogYW55LCBvcGVyYXRpb25LZXk6IHN0cmluZykge1xuICBpZiAob3BlcmF0aW9uS2V5ID09PSAncmVhZFVzZXJGaWVsZHMnIHx8IG9wZXJhdGlvbktleSA9PT0gJ3dyaXRlVXNlckZpZWxkcycpIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkob3BlcmF0aW9uKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgIGAnJHtvcGVyYXRpb259JyBpcyBub3QgYSB2YWxpZCB2YWx1ZSBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnMgJHtvcGVyYXRpb25LZXl9IC0gbXVzdCBiZSBhbiBhcnJheWBcbiAgICAgICk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmICh0eXBlb2Ygb3BlcmF0aW9uID09PSAnb2JqZWN0JyAmJiBvcGVyYXRpb24gIT09IG51bGwpIHtcbiAgICAgIC8vIG9rIHRvIHByb2NlZWRcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgIGAnJHtvcGVyYXRpb259JyBpcyBub3QgYSB2YWxpZCB2YWx1ZSBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnMgJHtvcGVyYXRpb25LZXl9IC0gbXVzdCBiZSBhbiBvYmplY3RgXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZVBvaW50ZXJQZXJtaXNzaW9uKGZpZWxkTmFtZTogc3RyaW5nLCBmaWVsZHM6IE9iamVjdCwgb3BlcmF0aW9uOiBzdHJpbmcpIHtcbiAgLy8gVXNlcyBjb2xsZWN0aW9uIHNjaGVtYSB0byBlbnN1cmUgdGhlIGZpZWxkIGlzIG9mIHR5cGU6XG4gIC8vIC0gUG9pbnRlcjxfVXNlcj4gKHBvaW50ZXJzKVxuICAvLyAtIEFycmF5XG4gIC8vXG4gIC8vICAgIEl0J3Mgbm90IHBvc3NpYmxlIHRvIGVuZm9yY2UgdHlwZSBvbiBBcnJheSdzIGl0ZW1zIGluIHNjaGVtYVxuICAvLyAgc28gd2UgYWNjZXB0IGFueSBBcnJheSBmaWVsZCwgYW5kIGxhdGVyIHdoZW4gYXBwbHlpbmcgcGVybWlzc2lvbnNcbiAgLy8gIG9ubHkgaXRlbXMgdGhhdCBhcmUgcG9pbnRlcnMgdG8gX1VzZXIgYXJlIGNvbnNpZGVyZWQuXG4gIGlmIChcbiAgICAhKFxuICAgICAgZmllbGRzW2ZpZWxkTmFtZV0gJiZcbiAgICAgICgoZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PSAnUG9pbnRlcicgJiYgZmllbGRzW2ZpZWxkTmFtZV0udGFyZ2V0Q2xhc3MgPT0gJ19Vc2VyJykgfHxcbiAgICAgICAgZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PSAnQXJyYXknKVxuICAgIClcbiAgKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgYCcke2ZpZWxkTmFtZX0nIGlzIG5vdCBhIHZhbGlkIGNvbHVtbiBmb3IgY2xhc3MgbGV2ZWwgcG9pbnRlciBwZXJtaXNzaW9ucyAke29wZXJhdGlvbn1gXG4gICAgKTtcbiAgfVxufVxuXG5jb25zdCBqb2luQ2xhc3NSZWdleCA9IC9eX0pvaW46W0EtWmEtejAtOV9dKzpbQS1aYS16MC05X10rLztcbmNvbnN0IGNsYXNzQW5kRmllbGRSZWdleCA9IC9eW0EtWmEtel1bQS1aYS16MC05X10qJC87XG5mdW5jdGlvbiBjbGFzc05hbWVJc1ZhbGlkKGNsYXNzTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIC8vIFZhbGlkIGNsYXNzZXMgbXVzdDpcbiAgcmV0dXJuIChcbiAgICAvLyBCZSBvbmUgb2YgX1VzZXIsIF9JbnN0YWxsYXRpb24sIF9Sb2xlLCBfU2Vzc2lvbiBPUlxuICAgIHN5c3RlbUNsYXNzZXMuaW5kZXhPZihjbGFzc05hbWUpID4gLTEgfHxcbiAgICAvLyBCZSBhIGpvaW4gdGFibGUgT1JcbiAgICBqb2luQ2xhc3NSZWdleC50ZXN0KGNsYXNzTmFtZSkgfHxcbiAgICAvLyBJbmNsdWRlIG9ubHkgYWxwaGEtbnVtZXJpYyBhbmQgdW5kZXJzY29yZXMsIGFuZCBub3Qgc3RhcnQgd2l0aCBhbiB1bmRlcnNjb3JlIG9yIG51bWJlclxuICAgIGZpZWxkTmFtZUlzVmFsaWQoY2xhc3NOYW1lLCBjbGFzc05hbWUpXG4gICk7XG59XG5cbi8vIFZhbGlkIGZpZWxkcyBtdXN0IGJlIGFscGhhLW51bWVyaWMsIGFuZCBub3Qgc3RhcnQgd2l0aCBhbiB1bmRlcnNjb3JlIG9yIG51bWJlclxuLy8gbXVzdCBub3QgYmUgYSByZXNlcnZlZCBrZXlcbmZ1bmN0aW9uIGZpZWxkTmFtZUlzVmFsaWQoZmllbGROYW1lOiBzdHJpbmcsIGNsYXNzTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmIChjbGFzc05hbWUgJiYgY2xhc3NOYW1lICE9PSAnX0hvb2tzJykge1xuICAgIGlmIChmaWVsZE5hbWUgPT09ICdjbGFzc05hbWUnKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiBjbGFzc0FuZEZpZWxkUmVnZXgudGVzdChmaWVsZE5hbWUpICYmICFpbnZhbGlkQ29sdW1ucy5pbmNsdWRlcyhmaWVsZE5hbWUpO1xufVxuXG4vLyBDaGVja3MgdGhhdCBpdCdzIG5vdCB0cnlpbmcgdG8gY2xvYmJlciBvbmUgb2YgdGhlIGRlZmF1bHQgZmllbGRzIG9mIHRoZSBjbGFzcy5cbmZ1bmN0aW9uIGZpZWxkTmFtZUlzVmFsaWRGb3JDbGFzcyhmaWVsZE5hbWU6IHN0cmluZywgY2xhc3NOYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgaWYgKCFmaWVsZE5hbWVJc1ZhbGlkKGZpZWxkTmFtZSwgY2xhc3NOYW1lKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoZGVmYXVsdENvbHVtbnMuX0RlZmF1bHRbZmllbGROYW1lXSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoZGVmYXVsdENvbHVtbnNbY2xhc3NOYW1lXSAmJiBkZWZhdWx0Q29sdW1uc1tjbGFzc05hbWVdW2ZpZWxkTmFtZV0pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGludmFsaWRDbGFzc05hbWVNZXNzYWdlKGNsYXNzTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIChcbiAgICAnSW52YWxpZCBjbGFzc25hbWU6ICcgK1xuICAgIGNsYXNzTmFtZSArXG4gICAgJywgY2xhc3NuYW1lcyBjYW4gb25seSBoYXZlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIGFuZCBfLCBhbmQgbXVzdCBzdGFydCB3aXRoIGFuIGFscGhhIGNoYXJhY3RlciAnXG4gICk7XG59XG5cbmNvbnN0IGludmFsaWRKc29uRXJyb3IgPSBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnaW52YWxpZCBKU09OJyk7XG5jb25zdCB2YWxpZE5vblJlbGF0aW9uT3JQb2ludGVyVHlwZXMgPSBbXG4gICdOdW1iZXInLFxuICAnU3RyaW5nJyxcbiAgJ0Jvb2xlYW4nLFxuICAnRGF0ZScsXG4gICdPYmplY3QnLFxuICAnQXJyYXknLFxuICAnR2VvUG9pbnQnLFxuICAnRmlsZScsXG4gICdCeXRlcycsXG4gICdQb2x5Z29uJyxcbl07XG4vLyBSZXR1cm5zIGFuIGVycm9yIHN1aXRhYmxlIGZvciB0aHJvd2luZyBpZiB0aGUgdHlwZSBpcyBpbnZhbGlkXG5jb25zdCBmaWVsZFR5cGVJc0ludmFsaWQgPSAoeyB0eXBlLCB0YXJnZXRDbGFzcyB9KSA9PiB7XG4gIGlmIChbJ1BvaW50ZXInLCAnUmVsYXRpb24nXS5pbmRleE9mKHR5cGUpID49IDApIHtcbiAgICBpZiAoIXRhcmdldENsYXNzKSB7XG4gICAgICByZXR1cm4gbmV3IFBhcnNlLkVycm9yKDEzNSwgYHR5cGUgJHt0eXBlfSBuZWVkcyBhIGNsYXNzIG5hbWVgKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB0YXJnZXRDbGFzcyAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBpbnZhbGlkSnNvbkVycm9yO1xuICAgIH0gZWxzZSBpZiAoIWNsYXNzTmFtZUlzVmFsaWQodGFyZ2V0Q2xhc3MpKSB7XG4gICAgICByZXR1cm4gbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSwgaW52YWxpZENsYXNzTmFtZU1lc3NhZ2UodGFyZ2V0Q2xhc3MpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgaWYgKHR5cGVvZiB0eXBlICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBpbnZhbGlkSnNvbkVycm9yO1xuICB9XG4gIGlmICh2YWxpZE5vblJlbGF0aW9uT3JQb2ludGVyVHlwZXMuaW5kZXhPZih0eXBlKSA8IDApIHtcbiAgICByZXR1cm4gbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLCBgaW52YWxpZCBmaWVsZCB0eXBlOiAke3R5cGV9YCk7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn07XG5cbmNvbnN0IGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEgPSAoc2NoZW1hOiBhbnkpID0+IHtcbiAgc2NoZW1hID0gaW5qZWN0RGVmYXVsdFNjaGVtYShzY2hlbWEpO1xuICBkZWxldGUgc2NoZW1hLmZpZWxkcy5BQ0w7XG4gIHNjaGVtYS5maWVsZHMuX3JwZXJtID0geyB0eXBlOiAnQXJyYXknIH07XG4gIHNjaGVtYS5maWVsZHMuX3dwZXJtID0geyB0eXBlOiAnQXJyYXknIH07XG5cbiAgaWYgKHNjaGVtYS5jbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICBkZWxldGUgc2NoZW1hLmZpZWxkcy5wYXNzd29yZDtcbiAgICBzY2hlbWEuZmllbGRzLl9oYXNoZWRfcGFzc3dvcmQgPSB7IHR5cGU6ICdTdHJpbmcnIH07XG4gIH1cblxuICByZXR1cm4gc2NoZW1hO1xufTtcblxuY29uc3QgY29udmVydEFkYXB0ZXJTY2hlbWFUb1BhcnNlU2NoZW1hID0gKHsgLi4uc2NoZW1hIH0pID0+IHtcbiAgZGVsZXRlIHNjaGVtYS5maWVsZHMuX3JwZXJtO1xuICBkZWxldGUgc2NoZW1hLmZpZWxkcy5fd3Blcm07XG5cbiAgc2NoZW1hLmZpZWxkcy5BQ0wgPSB7IHR5cGU6ICdBQ0wnIH07XG5cbiAgaWYgKHNjaGVtYS5jbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICBkZWxldGUgc2NoZW1hLmZpZWxkcy5hdXRoRGF0YTsgLy9BdXRoIGRhdGEgaXMgaW1wbGljaXRcbiAgICBkZWxldGUgc2NoZW1hLmZpZWxkcy5faGFzaGVkX3Bhc3N3b3JkO1xuICAgIHNjaGVtYS5maWVsZHMucGFzc3dvcmQgPSB7IHR5cGU6ICdTdHJpbmcnIH07XG4gIH1cblxuICBpZiAoc2NoZW1hLmluZGV4ZXMgJiYgT2JqZWN0LmtleXMoc2NoZW1hLmluZGV4ZXMpLmxlbmd0aCA9PT0gMCkge1xuICAgIGRlbGV0ZSBzY2hlbWEuaW5kZXhlcztcbiAgfVxuXG4gIHJldHVybiBzY2hlbWE7XG59O1xuXG5jbGFzcyBTY2hlbWFEYXRhIHtcbiAgX19kYXRhOiBhbnk7XG4gIF9fcHJvdGVjdGVkRmllbGRzOiBhbnk7XG4gIGNvbnN0cnVjdG9yKGFsbFNjaGVtYXMgPSBbXSwgcHJvdGVjdGVkRmllbGRzID0ge30pIHtcbiAgICB0aGlzLl9fZGF0YSA9IHt9O1xuICAgIHRoaXMuX19wcm90ZWN0ZWRGaWVsZHMgPSBwcm90ZWN0ZWRGaWVsZHM7XG4gICAgYWxsU2NoZW1hcy5mb3JFYWNoKHNjaGVtYSA9PiB7XG4gICAgICBpZiAodm9sYXRpbGVDbGFzc2VzLmluY2x1ZGVzKHNjaGVtYS5jbGFzc05hbWUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBzY2hlbWEuY2xhc3NOYW1lLCB7XG4gICAgICAgIGdldDogKCkgPT4ge1xuICAgICAgICAgIGlmICghdGhpcy5fX2RhdGFbc2NoZW1hLmNsYXNzTmFtZV0pIHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSB7fTtcbiAgICAgICAgICAgIGRhdGEuZmllbGRzID0gaW5qZWN0RGVmYXVsdFNjaGVtYShzY2hlbWEpLmZpZWxkcztcbiAgICAgICAgICAgIGRhdGEuY2xhc3NMZXZlbFBlcm1pc3Npb25zID0gZGVlcGNvcHkoc2NoZW1hLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucyk7XG4gICAgICAgICAgICBkYXRhLmluZGV4ZXMgPSBzY2hlbWEuaW5kZXhlcztcblxuICAgICAgICAgICAgY29uc3QgY2xhc3NQcm90ZWN0ZWRGaWVsZHMgPSB0aGlzLl9fcHJvdGVjdGVkRmllbGRzW3NjaGVtYS5jbGFzc05hbWVdO1xuICAgICAgICAgICAgaWYgKGNsYXNzUHJvdGVjdGVkRmllbGRzKSB7XG4gICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIGNsYXNzUHJvdGVjdGVkRmllbGRzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdW5xID0gbmV3IFNldChbXG4gICAgICAgICAgICAgICAgICAuLi4oZGF0YS5jbGFzc0xldmVsUGVybWlzc2lvbnMucHJvdGVjdGVkRmllbGRzW2tleV0gfHwgW10pLFxuICAgICAgICAgICAgICAgICAgLi4uY2xhc3NQcm90ZWN0ZWRGaWVsZHNba2V5XSxcbiAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICBkYXRhLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucy5wcm90ZWN0ZWRGaWVsZHNba2V5XSA9IEFycmF5LmZyb20odW5xKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLl9fZGF0YVtzY2hlbWEuY2xhc3NOYW1lXSA9IGRhdGE7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0aGlzLl9fZGF0YVtzY2hlbWEuY2xhc3NOYW1lXTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gSW5qZWN0IHRoZSBpbi1tZW1vcnkgY2xhc3Nlc1xuICAgIHZvbGF0aWxlQ2xhc3Nlcy5mb3JFYWNoKGNsYXNzTmFtZSA9PiB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgY2xhc3NOYW1lLCB7XG4gICAgICAgIGdldDogKCkgPT4ge1xuICAgICAgICAgIGlmICghdGhpcy5fX2RhdGFbY2xhc3NOYW1lXSkge1xuICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0gaW5qZWN0RGVmYXVsdFNjaGVtYSh7XG4gICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgZmllbGRzOiB7fSxcbiAgICAgICAgICAgICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiB7fSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgZGF0YSA9IHt9O1xuICAgICAgICAgICAgZGF0YS5maWVsZHMgPSBzY2hlbWEuZmllbGRzO1xuICAgICAgICAgICAgZGF0YS5jbGFzc0xldmVsUGVybWlzc2lvbnMgPSBzY2hlbWEuY2xhc3NMZXZlbFBlcm1pc3Npb25zO1xuICAgICAgICAgICAgZGF0YS5pbmRleGVzID0gc2NoZW1hLmluZGV4ZXM7XG4gICAgICAgICAgICB0aGlzLl9fZGF0YVtjbGFzc05hbWVdID0gZGF0YTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRoaXMuX19kYXRhW2NsYXNzTmFtZV07XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxufVxuXG5jb25zdCBpbmplY3REZWZhdWx0U2NoZW1hID0gKHsgY2xhc3NOYW1lLCBmaWVsZHMsIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgaW5kZXhlcyB9OiBTY2hlbWEpID0+IHtcbiAgY29uc3QgZGVmYXVsdFNjaGVtYTogU2NoZW1hID0ge1xuICAgIGNsYXNzTmFtZSxcbiAgICBmaWVsZHM6IHtcbiAgICAgIC4uLmRlZmF1bHRDb2x1bW5zLl9EZWZhdWx0LFxuICAgICAgLi4uKGRlZmF1bHRDb2x1bW5zW2NsYXNzTmFtZV0gfHwge30pLFxuICAgICAgLi4uZmllbGRzLFxuICAgIH0sXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICB9O1xuICBpZiAoaW5kZXhlcyAmJiBPYmplY3Qua2V5cyhpbmRleGVzKS5sZW5ndGggIT09IDApIHtcbiAgICBkZWZhdWx0U2NoZW1hLmluZGV4ZXMgPSBpbmRleGVzO1xuICB9XG4gIHJldHVybiBkZWZhdWx0U2NoZW1hO1xufTtcblxuY29uc3QgX0hvb2tzU2NoZW1hID0geyBjbGFzc05hbWU6ICdfSG9va3MnLCBmaWVsZHM6IGRlZmF1bHRDb2x1bW5zLl9Ib29rcyB9O1xuY29uc3QgX0dsb2JhbENvbmZpZ1NjaGVtYSA9IHtcbiAgY2xhc3NOYW1lOiAnX0dsb2JhbENvbmZpZycsXG4gIGZpZWxkczogZGVmYXVsdENvbHVtbnMuX0dsb2JhbENvbmZpZyxcbn07XG5jb25zdCBfR3JhcGhRTENvbmZpZ1NjaGVtYSA9IHtcbiAgY2xhc3NOYW1lOiAnX0dyYXBoUUxDb25maWcnLFxuICBmaWVsZHM6IGRlZmF1bHRDb2x1bW5zLl9HcmFwaFFMQ29uZmlnLFxufTtcbmNvbnN0IF9QdXNoU3RhdHVzU2NoZW1hID0gY29udmVydFNjaGVtYVRvQWRhcHRlclNjaGVtYShcbiAgaW5qZWN0RGVmYXVsdFNjaGVtYSh7XG4gICAgY2xhc3NOYW1lOiAnX1B1c2hTdGF0dXMnLFxuICAgIGZpZWxkczoge30sXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiB7fSxcbiAgfSlcbik7XG5jb25zdCBfSm9iU3RhdHVzU2NoZW1hID0gY29udmVydFNjaGVtYVRvQWRhcHRlclNjaGVtYShcbiAgaW5qZWN0RGVmYXVsdFNjaGVtYSh7XG4gICAgY2xhc3NOYW1lOiAnX0pvYlN0YXR1cycsXG4gICAgZmllbGRzOiB7fSxcbiAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IHt9LFxuICB9KVxuKTtcbmNvbnN0IF9Kb2JTY2hlZHVsZVNjaGVtYSA9IGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEoXG4gIGluamVjdERlZmF1bHRTY2hlbWEoe1xuICAgIGNsYXNzTmFtZTogJ19Kb2JTY2hlZHVsZScsXG4gICAgZmllbGRzOiB7fSxcbiAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IHt9LFxuICB9KVxuKTtcbmNvbnN0IF9BdWRpZW5jZVNjaGVtYSA9IGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEoXG4gIGluamVjdERlZmF1bHRTY2hlbWEoe1xuICAgIGNsYXNzTmFtZTogJ19BdWRpZW5jZScsXG4gICAgZmllbGRzOiBkZWZhdWx0Q29sdW1ucy5fQXVkaWVuY2UsXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiB7fSxcbiAgfSlcbik7XG5jb25zdCBfSWRlbXBvdGVuY3lTY2hlbWEgPSBjb252ZXJ0U2NoZW1hVG9BZGFwdGVyU2NoZW1hKFxuICBpbmplY3REZWZhdWx0U2NoZW1hKHtcbiAgICBjbGFzc05hbWU6ICdfSWRlbXBvdGVuY3knLFxuICAgIGZpZWxkczogZGVmYXVsdENvbHVtbnMuX0lkZW1wb3RlbmN5LFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczoge30sXG4gIH0pXG4pO1xuY29uc3QgVm9sYXRpbGVDbGFzc2VzU2NoZW1hcyA9IFtcbiAgX0hvb2tzU2NoZW1hLFxuICBfSm9iU3RhdHVzU2NoZW1hLFxuICBfSm9iU2NoZWR1bGVTY2hlbWEsXG4gIF9QdXNoU3RhdHVzU2NoZW1hLFxuICBfR2xvYmFsQ29uZmlnU2NoZW1hLFxuICBfR3JhcGhRTENvbmZpZ1NjaGVtYSxcbiAgX0F1ZGllbmNlU2NoZW1hLFxuICBfSWRlbXBvdGVuY3lTY2hlbWEsXG5dO1xuXG5jb25zdCBkYlR5cGVNYXRjaGVzT2JqZWN0VHlwZSA9IChkYlR5cGU6IFNjaGVtYUZpZWxkIHwgc3RyaW5nLCBvYmplY3RUeXBlOiBTY2hlbWFGaWVsZCkgPT4ge1xuICBpZiAoZGJUeXBlLnR5cGUgIT09IG9iamVjdFR5cGUudHlwZSkgcmV0dXJuIGZhbHNlO1xuICBpZiAoZGJUeXBlLnRhcmdldENsYXNzICE9PSBvYmplY3RUeXBlLnRhcmdldENsYXNzKSByZXR1cm4gZmFsc2U7XG4gIGlmIChkYlR5cGUgPT09IG9iamVjdFR5cGUudHlwZSkgcmV0dXJuIHRydWU7XG4gIGlmIChkYlR5cGUudHlwZSA9PT0gb2JqZWN0VHlwZS50eXBlKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuY29uc3QgdHlwZVRvU3RyaW5nID0gKHR5cGU6IFNjaGVtYUZpZWxkIHwgc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB0eXBlO1xuICB9XG4gIGlmICh0eXBlLnRhcmdldENsYXNzKSB7XG4gICAgcmV0dXJuIGAke3R5cGUudHlwZX08JHt0eXBlLnRhcmdldENsYXNzfT5gO1xuICB9XG4gIHJldHVybiBgJHt0eXBlLnR5cGV9YDtcbn07XG5cbi8vIFN0b3JlcyB0aGUgZW50aXJlIHNjaGVtYSBvZiB0aGUgYXBwIGluIGEgd2VpcmQgaHlicmlkIGZvcm1hdCBzb21ld2hlcmUgYmV0d2VlblxuLy8gdGhlIG1vbmdvIGZvcm1hdCBhbmQgdGhlIFBhcnNlIGZvcm1hdC4gU29vbiwgdGhpcyB3aWxsIGFsbCBiZSBQYXJzZSBmb3JtYXQuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTY2hlbWFDb250cm9sbGVyIHtcbiAgX2RiQWRhcHRlcjogU3RvcmFnZUFkYXB0ZXI7XG4gIHNjaGVtYURhdGE6IHsgW3N0cmluZ106IFNjaGVtYSB9O1xuICBfY2FjaGU6IGFueTtcbiAgcmVsb2FkRGF0YVByb21pc2U6ID9Qcm9taXNlPGFueT47XG4gIHByb3RlY3RlZEZpZWxkczogYW55O1xuICB1c2VySWRSZWdFeDogUmVnRXhwO1xuXG4gIGNvbnN0cnVjdG9yKGRhdGFiYXNlQWRhcHRlcjogU3RvcmFnZUFkYXB0ZXIsIHNjaGVtYUNhY2hlOiBhbnkpIHtcbiAgICB0aGlzLl9kYkFkYXB0ZXIgPSBkYXRhYmFzZUFkYXB0ZXI7XG4gICAgdGhpcy5fY2FjaGUgPSBzY2hlbWFDYWNoZTtcbiAgICB0aGlzLnNjaGVtYURhdGEgPSBuZXcgU2NoZW1hRGF0YSgpO1xuICAgIHRoaXMucHJvdGVjdGVkRmllbGRzID0gQ29uZmlnLmdldChQYXJzZS5hcHBsaWNhdGlvbklkKS5wcm90ZWN0ZWRGaWVsZHM7XG5cbiAgICBjb25zdCBjdXN0b21JZHMgPSBDb25maWcuZ2V0KFBhcnNlLmFwcGxpY2F0aW9uSWQpLmFsbG93Q3VzdG9tT2JqZWN0SWQ7XG5cbiAgICBjb25zdCBjdXN0b21JZFJlZ0V4ID0gL14uezEsfSQvdTsgLy8gMSsgY2hhcnNcbiAgICBjb25zdCBhdXRvSWRSZWdFeCA9IC9eW2EtekEtWjAtOV17MSx9JC87XG5cbiAgICB0aGlzLnVzZXJJZFJlZ0V4ID0gY3VzdG9tSWRzID8gY3VzdG9tSWRSZWdFeCA6IGF1dG9JZFJlZ0V4O1xuICB9XG5cbiAgcmVsb2FkRGF0YShvcHRpb25zOiBMb2FkU2NoZW1hT3B0aW9ucyA9IHsgY2xlYXJDYWNoZTogZmFsc2UgfSk6IFByb21pc2U8YW55PiB7XG4gICAgaWYgKHRoaXMucmVsb2FkRGF0YVByb21pc2UgJiYgIW9wdGlvbnMuY2xlYXJDYWNoZSkge1xuICAgICAgcmV0dXJuIHRoaXMucmVsb2FkRGF0YVByb21pc2U7XG4gICAgfVxuICAgIHRoaXMucmVsb2FkRGF0YVByb21pc2UgPSB0aGlzLmdldEFsbENsYXNzZXMob3B0aW9ucylcbiAgICAgIC50aGVuKFxuICAgICAgICBhbGxTY2hlbWFzID0+IHtcbiAgICAgICAgICB0aGlzLnNjaGVtYURhdGEgPSBuZXcgU2NoZW1hRGF0YShhbGxTY2hlbWFzLCB0aGlzLnByb3RlY3RlZEZpZWxkcyk7XG4gICAgICAgICAgZGVsZXRlIHRoaXMucmVsb2FkRGF0YVByb21pc2U7XG4gICAgICAgIH0sXG4gICAgICAgIGVyciA9PiB7XG4gICAgICAgICAgdGhpcy5zY2hlbWFEYXRhID0gbmV3IFNjaGVtYURhdGEoKTtcbiAgICAgICAgICBkZWxldGUgdGhpcy5yZWxvYWREYXRhUHJvbWlzZTtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgIClcbiAgICAgIC50aGVuKCgpID0+IHt9KTtcbiAgICByZXR1cm4gdGhpcy5yZWxvYWREYXRhUHJvbWlzZTtcbiAgfVxuXG4gIGdldEFsbENsYXNzZXMob3B0aW9uczogTG9hZFNjaGVtYU9wdGlvbnMgPSB7IGNsZWFyQ2FjaGU6IGZhbHNlIH0pOiBQcm9taXNlPEFycmF5PFNjaGVtYT4+IHtcbiAgICBpZiAob3B0aW9ucy5jbGVhckNhY2hlKSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRBbGxDbGFzc2VzKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9jYWNoZS5nZXRBbGxDbGFzc2VzKCkudGhlbihhbGxDbGFzc2VzID0+IHtcbiAgICAgIGlmIChhbGxDbGFzc2VzICYmIGFsbENsYXNzZXMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoYWxsQ2xhc3Nlcyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5zZXRBbGxDbGFzc2VzKCk7XG4gICAgfSk7XG4gIH1cblxuICBzZXRBbGxDbGFzc2VzKCk6IFByb21pc2U8QXJyYXk8U2NoZW1hPj4ge1xuICAgIHJldHVybiB0aGlzLl9kYkFkYXB0ZXJcbiAgICAgIC5nZXRBbGxDbGFzc2VzKClcbiAgICAgIC50aGVuKGFsbFNjaGVtYXMgPT4gYWxsU2NoZW1hcy5tYXAoaW5qZWN0RGVmYXVsdFNjaGVtYSkpXG4gICAgICAudGhlbihhbGxTY2hlbWFzID0+IHtcbiAgICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuICAgICAgICB0aGlzLl9jYWNoZVxuICAgICAgICAgIC5zZXRBbGxDbGFzc2VzKGFsbFNjaGVtYXMpXG4gICAgICAgICAgLmNhdGNoKGVycm9yID0+IGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNhdmluZyBzY2hlbWEgdG8gY2FjaGU6JywgZXJyb3IpKTtcbiAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby1jb25zb2xlICovXG4gICAgICAgIHJldHVybiBhbGxTY2hlbWFzO1xuICAgICAgfSk7XG4gIH1cblxuICBnZXRPbmVTY2hlbWEoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgYWxsb3dWb2xhdGlsZUNsYXNzZXM6IGJvb2xlYW4gPSBmYWxzZSxcbiAgICBvcHRpb25zOiBMb2FkU2NoZW1hT3B0aW9ucyA9IHsgY2xlYXJDYWNoZTogZmFsc2UgfVxuICApOiBQcm9taXNlPFNjaGVtYT4ge1xuICAgIGxldCBwcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgaWYgKG9wdGlvbnMuY2xlYXJDYWNoZSkge1xuICAgICAgcHJvbWlzZSA9IHRoaXMuX2NhY2hlLmNsZWFyKCk7XG4gICAgfVxuICAgIHJldHVybiBwcm9taXNlLnRoZW4oKCkgPT4ge1xuICAgICAgaWYgKGFsbG93Vm9sYXRpbGVDbGFzc2VzICYmIHZvbGF0aWxlQ2xhc3Nlcy5pbmRleE9mKGNsYXNzTmFtZSkgPiAtMSkge1xuICAgICAgICBjb25zdCBkYXRhID0gdGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV07XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICBmaWVsZHM6IGRhdGEuZmllbGRzLFxuICAgICAgICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogZGF0YS5jbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gICAgICAgICAgaW5kZXhlczogZGF0YS5pbmRleGVzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZS5nZXRPbmVTY2hlbWEoY2xhc3NOYW1lKS50aGVuKGNhY2hlZCA9PiB7XG4gICAgICAgIGlmIChjYWNoZWQgJiYgIW9wdGlvbnMuY2xlYXJDYWNoZSkge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoY2FjaGVkKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5zZXRBbGxDbGFzc2VzKCkudGhlbihhbGxTY2hlbWFzID0+IHtcbiAgICAgICAgICBjb25zdCBvbmVTY2hlbWEgPSBhbGxTY2hlbWFzLmZpbmQoc2NoZW1hID0+IHNjaGVtYS5jbGFzc05hbWUgPT09IGNsYXNzTmFtZSk7XG4gICAgICAgICAgaWYgKCFvbmVTY2hlbWEpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCh1bmRlZmluZWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gb25lU2NoZW1hO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gQ3JlYXRlIGEgbmV3IGNsYXNzIHRoYXQgaW5jbHVkZXMgdGhlIHRocmVlIGRlZmF1bHQgZmllbGRzLlxuICAvLyBBQ0wgaXMgYW4gaW1wbGljaXQgY29sdW1uIHRoYXQgZG9lcyBub3QgZ2V0IGFuIGVudHJ5IGluIHRoZVxuICAvLyBfU0NIRU1BUyBkYXRhYmFzZS4gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZVxuICAvLyBjcmVhdGVkIHNjaGVtYSwgaW4gbW9uZ28gZm9ybWF0LlxuICAvLyBvbiBzdWNjZXNzLCBhbmQgcmVqZWN0cyB3aXRoIGFuIGVycm9yIG9uIGZhaWwuIEVuc3VyZSB5b3VcbiAgLy8gaGF2ZSBhdXRob3JpemF0aW9uIChtYXN0ZXIga2V5LCBvciBjbGllbnQgY2xhc3MgY3JlYXRpb25cbiAgLy8gZW5hYmxlZCkgYmVmb3JlIGNhbGxpbmcgdGhpcyBmdW5jdGlvbi5cbiAgYWRkQ2xhc3NJZk5vdEV4aXN0cyhcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBmaWVsZHM6IFNjaGVtYUZpZWxkcyA9IHt9LFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogYW55LFxuICAgIGluZGV4ZXM6IGFueSA9IHt9XG4gICk6IFByb21pc2U8dm9pZCB8IFNjaGVtYT4ge1xuICAgIHZhciB2YWxpZGF0aW9uRXJyb3IgPSB0aGlzLnZhbGlkYXRlTmV3Q2xhc3MoY2xhc3NOYW1lLCBmaWVsZHMsIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyk7XG4gICAgaWYgKHZhbGlkYXRpb25FcnJvcikge1xuICAgICAgaWYgKHZhbGlkYXRpb25FcnJvciBpbnN0YW5jZW9mIFBhcnNlLkVycm9yKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCh2YWxpZGF0aW9uRXJyb3IpO1xuICAgICAgfSBlbHNlIGlmICh2YWxpZGF0aW9uRXJyb3IuY29kZSAmJiB2YWxpZGF0aW9uRXJyb3IuZXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBQYXJzZS5FcnJvcih2YWxpZGF0aW9uRXJyb3IuY29kZSwgdmFsaWRhdGlvbkVycm9yLmVycm9yKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QodmFsaWRhdGlvbkVycm9yKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fZGJBZGFwdGVyXG4gICAgICAuY3JlYXRlQ2xhc3MoXG4gICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgY29udmVydFNjaGVtYVRvQWRhcHRlclNjaGVtYSh7XG4gICAgICAgICAgZmllbGRzLFxuICAgICAgICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgICAgICBpbmRleGVzLFxuICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC50aGVuKGNvbnZlcnRBZGFwdGVyU2NoZW1hVG9QYXJzZVNjaGVtYSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvciAmJiBlcnJvci5jb2RlID09PSBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0NMQVNTX05BTUUsXG4gICAgICAgICAgICBgQ2xhc3MgJHtjbGFzc05hbWV9IGFscmVhZHkgZXhpc3RzLmBcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIHVwZGF0ZUNsYXNzKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHN1Ym1pdHRlZEZpZWxkczogU2NoZW1hRmllbGRzLFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogYW55LFxuICAgIGluZGV4ZXM6IGFueSxcbiAgICBkYXRhYmFzZTogRGF0YWJhc2VDb250cm9sbGVyXG4gICkge1xuICAgIHJldHVybiB0aGlzLmdldE9uZVNjaGVtYShjbGFzc05hbWUpXG4gICAgICAudGhlbihzY2hlbWEgPT4ge1xuICAgICAgICBjb25zdCBleGlzdGluZ0ZpZWxkcyA9IHNjaGVtYS5maWVsZHM7XG4gICAgICAgIE9iamVjdC5rZXlzKHN1Ym1pdHRlZEZpZWxkcykuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgICAgICBjb25zdCBmaWVsZCA9IHN1Ym1pdHRlZEZpZWxkc1tuYW1lXTtcbiAgICAgICAgICBpZiAoZXhpc3RpbmdGaWVsZHNbbmFtZV0gJiYgZmllbGQuX19vcCAhPT0gJ0RlbGV0ZScpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigyNTUsIGBGaWVsZCAke25hbWV9IGV4aXN0cywgY2Fubm90IHVwZGF0ZS5gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFleGlzdGluZ0ZpZWxkc1tuYW1lXSAmJiBmaWVsZC5fX29wID09PSAnRGVsZXRlJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDI1NSwgYEZpZWxkICR7bmFtZX0gZG9lcyBub3QgZXhpc3QsIGNhbm5vdCBkZWxldGUuYCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBkZWxldGUgZXhpc3RpbmdGaWVsZHMuX3JwZXJtO1xuICAgICAgICBkZWxldGUgZXhpc3RpbmdGaWVsZHMuX3dwZXJtO1xuICAgICAgICBjb25zdCBuZXdTY2hlbWEgPSBidWlsZE1lcmdlZFNjaGVtYU9iamVjdChleGlzdGluZ0ZpZWxkcywgc3VibWl0dGVkRmllbGRzKTtcbiAgICAgICAgY29uc3QgZGVmYXVsdEZpZWxkcyA9IGRlZmF1bHRDb2x1bW5zW2NsYXNzTmFtZV0gfHwgZGVmYXVsdENvbHVtbnMuX0RlZmF1bHQ7XG4gICAgICAgIGNvbnN0IGZ1bGxOZXdTY2hlbWEgPSBPYmplY3QuYXNzaWduKHt9LCBuZXdTY2hlbWEsIGRlZmF1bHRGaWVsZHMpO1xuICAgICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3IgPSB0aGlzLnZhbGlkYXRlU2NoZW1hRGF0YShcbiAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgbmV3U2NoZW1hLFxuICAgICAgICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgICAgICBPYmplY3Qua2V5cyhleGlzdGluZ0ZpZWxkcylcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHZhbGlkYXRpb25FcnJvcikge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcih2YWxpZGF0aW9uRXJyb3IuY29kZSwgdmFsaWRhdGlvbkVycm9yLmVycm9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZpbmFsbHkgd2UgaGF2ZSBjaGVja2VkIHRvIG1ha2Ugc3VyZSB0aGUgcmVxdWVzdCBpcyB2YWxpZCBhbmQgd2UgY2FuIHN0YXJ0IGRlbGV0aW5nIGZpZWxkcy5cbiAgICAgICAgLy8gRG8gYWxsIGRlbGV0aW9ucyBmaXJzdCwgdGhlbiBhIHNpbmdsZSBzYXZlIHRvIF9TQ0hFTUEgY29sbGVjdGlvbiB0byBoYW5kbGUgYWxsIGFkZGl0aW9ucy5cbiAgICAgICAgY29uc3QgZGVsZXRlZEZpZWxkczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgY29uc3QgaW5zZXJ0ZWRGaWVsZHMgPSBbXTtcbiAgICAgICAgT2JqZWN0LmtleXMoc3VibWl0dGVkRmllbGRzKS5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICAgICAgaWYgKHN1Ym1pdHRlZEZpZWxkc1tmaWVsZE5hbWVdLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgICAgICBkZWxldGVkRmllbGRzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaW5zZXJ0ZWRGaWVsZHMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgbGV0IGRlbGV0ZVByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgaWYgKGRlbGV0ZWRGaWVsZHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGRlbGV0ZVByb21pc2UgPSB0aGlzLmRlbGV0ZUZpZWxkcyhkZWxldGVkRmllbGRzLCBjbGFzc05hbWUsIGRhdGFiYXNlKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgZW5mb3JjZUZpZWxkcyA9IFtdO1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIGRlbGV0ZVByb21pc2UgLy8gRGVsZXRlIEV2ZXJ5dGhpbmdcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMucmVsb2FkRGF0YSh7IGNsZWFyQ2FjaGU6IHRydWUgfSkpIC8vIFJlbG9hZCBvdXIgU2NoZW1hLCBzbyB3ZSBoYXZlIGFsbCB0aGUgbmV3IHZhbHVlc1xuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IGluc2VydGVkRmllbGRzLm1hcChmaWVsZE5hbWUgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHR5cGUgPSBzdWJtaXR0ZWRGaWVsZHNbZmllbGROYW1lXTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbmZvcmNlRmllbGRFeGlzdHMoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHR5cGUpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgICAgICAgZW5mb3JjZUZpZWxkcyA9IHJlc3VsdHMuZmlsdGVyKHJlc3VsdCA9PiAhIXJlc3VsdCk7XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLnNldFBlcm1pc3Npb25zKGNsYXNzTmFtZSwgY2xhc3NMZXZlbFBlcm1pc3Npb25zLCBuZXdTY2hlbWEpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKCgpID0+XG4gICAgICAgICAgICAgIHRoaXMuX2RiQWRhcHRlci5zZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdChcbiAgICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgaW5kZXhlcyxcbiAgICAgICAgICAgICAgICBzY2hlbWEuaW5kZXhlcyxcbiAgICAgICAgICAgICAgICBmdWxsTmV3U2NoZW1hXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMucmVsb2FkRGF0YSh7IGNsZWFyQ2FjaGU6IHRydWUgfSkpXG4gICAgICAgICAgICAvL1RPRE86IE1vdmUgdGhpcyBsb2dpYyBpbnRvIHRoZSBkYXRhYmFzZSBhZGFwdGVyXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuZW5zdXJlRmllbGRzKGVuZm9yY2VGaWVsZHMpO1xuICAgICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB0aGlzLnNjaGVtYURhdGFbY2xhc3NOYW1lXTtcbiAgICAgICAgICAgICAgY29uc3QgcmVsb2FkZWRTY2hlbWE6IFNjaGVtYSA9IHtcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU6IGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICBmaWVsZHM6IHNjaGVtYS5maWVsZHMsXG4gICAgICAgICAgICAgICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiBzY2hlbWEuY2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICBpZiAoc2NoZW1hLmluZGV4ZXMgJiYgT2JqZWN0LmtleXMoc2NoZW1hLmluZGV4ZXMpLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgICAgIHJlbG9hZGVkU2NoZW1hLmluZGV4ZXMgPSBzY2hlbWEuaW5kZXhlcztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gcmVsb2FkZWRTY2hlbWE7XG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLFxuICAgICAgICAgICAgYENsYXNzICR7Y2xhc3NOYW1lfSBkb2VzIG5vdCBleGlzdC5gXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHN1Y2Nlc3NmdWxseSB0byB0aGUgbmV3IHNjaGVtYVxuICAvLyBvYmplY3Qgb3IgZmFpbHMgd2l0aCBhIHJlYXNvbi5cbiAgZW5mb3JjZUNsYXNzRXhpc3RzKGNsYXNzTmFtZTogc3RyaW5nKTogUHJvbWlzZTxTY2hlbWFDb250cm9sbGVyPiB7XG4gICAgaWYgKHRoaXMuc2NoZW1hRGF0YVtjbGFzc05hbWVdKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMpO1xuICAgIH1cbiAgICAvLyBXZSBkb24ndCBoYXZlIHRoaXMgY2xhc3MuIFVwZGF0ZSB0aGUgc2NoZW1hXG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuYWRkQ2xhc3NJZk5vdEV4aXN0cyhjbGFzc05hbWUpXG4gICAgICAgIC8vIFRoZSBzY2hlbWEgdXBkYXRlIHN1Y2NlZWRlZC4gUmVsb2FkIHRoZSBzY2hlbWFcbiAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5yZWxvYWREYXRhKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KSlcbiAgICAgICAgLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAvLyBUaGUgc2NoZW1hIHVwZGF0ZSBmYWlsZWQuIFRoaXMgY2FuIGJlIG9rYXkgLSBpdCBtaWdodFxuICAgICAgICAgIC8vIGhhdmUgZmFpbGVkIGJlY2F1c2UgdGhlcmUncyBhIHJhY2UgY29uZGl0aW9uIGFuZCBhIGRpZmZlcmVudFxuICAgICAgICAgIC8vIGNsaWVudCBpcyBtYWtpbmcgdGhlIGV4YWN0IHNhbWUgc2NoZW1hIHVwZGF0ZSB0aGF0IHdlIHdhbnQuXG4gICAgICAgICAgLy8gU28ganVzdCByZWxvYWQgdGhlIHNjaGVtYS5cbiAgICAgICAgICByZXR1cm4gdGhpcy5yZWxvYWREYXRhKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIC8vIEVuc3VyZSB0aGF0IHRoZSBzY2hlbWEgbm93IHZhbGlkYXRlc1xuICAgICAgICAgIGlmICh0aGlzLnNjaGVtYURhdGFbY2xhc3NOYW1lXSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sIGBGYWlsZWQgdG8gYWRkICR7Y2xhc3NOYW1lfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAvLyBUaGUgc2NoZW1hIHN0aWxsIGRvZXNuJ3QgdmFsaWRhdGUuIEdpdmUgdXBcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnc2NoZW1hIGNsYXNzIG5hbWUgZG9lcyBub3QgcmV2YWxpZGF0ZScpO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cblxuICB2YWxpZGF0ZU5ld0NsYXNzKGNsYXNzTmFtZTogc3RyaW5nLCBmaWVsZHM6IFNjaGVtYUZpZWxkcyA9IHt9LCBjbGFzc0xldmVsUGVybWlzc2lvbnM6IGFueSk6IGFueSB7XG4gICAgaWYgKHRoaXMuc2NoZW1hRGF0YVtjbGFzc05hbWVdKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLCBgQ2xhc3MgJHtjbGFzc05hbWV9IGFscmVhZHkgZXhpc3RzLmApO1xuICAgIH1cbiAgICBpZiAoIWNsYXNzTmFtZUlzVmFsaWQoY2xhc3NOYW1lKSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29kZTogUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLFxuICAgICAgICBlcnJvcjogaW52YWxpZENsYXNzTmFtZU1lc3NhZ2UoY2xhc3NOYW1lKSxcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnZhbGlkYXRlU2NoZW1hRGF0YShjbGFzc05hbWUsIGZpZWxkcywgY2xhc3NMZXZlbFBlcm1pc3Npb25zLCBbXSk7XG4gIH1cblxuICB2YWxpZGF0ZVNjaGVtYURhdGEoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgZmllbGRzOiBTY2hlbWFGaWVsZHMsXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiBDbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gICAgZXhpc3RpbmdGaWVsZE5hbWVzOiBBcnJheTxzdHJpbmc+XG4gICkge1xuICAgIGZvciAoY29uc3QgZmllbGROYW1lIGluIGZpZWxkcykge1xuICAgICAgaWYgKGV4aXN0aW5nRmllbGROYW1lcy5pbmRleE9mKGZpZWxkTmFtZSkgPCAwKSB7XG4gICAgICAgIGlmICghZmllbGROYW1lSXNWYWxpZChmaWVsZE5hbWUsIGNsYXNzTmFtZSkpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29kZTogUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSxcbiAgICAgICAgICAgIGVycm9yOiAnaW52YWxpZCBmaWVsZCBuYW1lOiAnICsgZmllbGROYW1lLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFmaWVsZE5hbWVJc1ZhbGlkRm9yQ2xhc3MoZmllbGROYW1lLCBjbGFzc05hbWUpKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvZGU6IDEzNixcbiAgICAgICAgICAgIGVycm9yOiAnZmllbGQgJyArIGZpZWxkTmFtZSArICcgY2Fubm90IGJlIGFkZGVkJyxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGZpZWxkVHlwZSA9IGZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgICBjb25zdCBlcnJvciA9IGZpZWxkVHlwZUlzSW52YWxpZChmaWVsZFR5cGUpO1xuICAgICAgICBpZiAoZXJyb3IpIHJldHVybiB7IGNvZGU6IGVycm9yLmNvZGUsIGVycm9yOiBlcnJvci5tZXNzYWdlIH07XG4gICAgICAgIGlmIChmaWVsZFR5cGUuZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBsZXQgZGVmYXVsdFZhbHVlVHlwZSA9IGdldFR5cGUoZmllbGRUeXBlLmRlZmF1bHRWYWx1ZSk7XG4gICAgICAgICAgaWYgKHR5cGVvZiBkZWZhdWx0VmFsdWVUeXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgZGVmYXVsdFZhbHVlVHlwZSA9IHsgdHlwZTogZGVmYXVsdFZhbHVlVHlwZSB9O1xuICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGRlZmF1bHRWYWx1ZVR5cGUgPT09ICdvYmplY3QnICYmIGZpZWxkVHlwZS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBjb2RlOiBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSxcbiAgICAgICAgICAgICAgZXJyb3I6IGBUaGUgJ2RlZmF1bHQgdmFsdWUnIG9wdGlvbiBpcyBub3QgYXBwbGljYWJsZSBmb3IgJHt0eXBlVG9TdHJpbmcoZmllbGRUeXBlKX1gLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFkYlR5cGVNYXRjaGVzT2JqZWN0VHlwZShmaWVsZFR5cGUsIGRlZmF1bHRWYWx1ZVR5cGUpKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBjb2RlOiBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSxcbiAgICAgICAgICAgICAgZXJyb3I6IGBzY2hlbWEgbWlzbWF0Y2ggZm9yICR7Y2xhc3NOYW1lfS4ke2ZpZWxkTmFtZX0gZGVmYXVsdCB2YWx1ZTsgZXhwZWN0ZWQgJHt0eXBlVG9TdHJpbmcoXG4gICAgICAgICAgICAgICAgZmllbGRUeXBlXG4gICAgICAgICAgICAgICl9IGJ1dCBnb3QgJHt0eXBlVG9TdHJpbmcoZGVmYXVsdFZhbHVlVHlwZSl9YCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGZpZWxkVHlwZS5yZXF1aXJlZCkge1xuICAgICAgICAgIGlmICh0eXBlb2YgZmllbGRUeXBlID09PSAnb2JqZWN0JyAmJiBmaWVsZFR5cGUudHlwZSA9PT0gJ1JlbGF0aW9uJykge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgY29kZTogUGFyc2UuRXJyb3IuSU5DT1JSRUNUX1RZUEUsXG4gICAgICAgICAgICAgIGVycm9yOiBgVGhlICdyZXF1aXJlZCcgb3B0aW9uIGlzIG5vdCBhcHBsaWNhYmxlIGZvciAke3R5cGVUb1N0cmluZyhmaWVsZFR5cGUpfWAsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZmllbGROYW1lIGluIGRlZmF1bHRDb2x1bW5zW2NsYXNzTmFtZV0pIHtcbiAgICAgIGZpZWxkc1tmaWVsZE5hbWVdID0gZGVmYXVsdENvbHVtbnNbY2xhc3NOYW1lXVtmaWVsZE5hbWVdO1xuICAgIH1cblxuICAgIGNvbnN0IGdlb1BvaW50cyA9IE9iamVjdC5rZXlzKGZpZWxkcykuZmlsdGVyKFxuICAgICAga2V5ID0+IGZpZWxkc1trZXldICYmIGZpZWxkc1trZXldLnR5cGUgPT09ICdHZW9Qb2ludCdcbiAgICApO1xuICAgIGlmIChnZW9Qb2ludHMubGVuZ3RoID4gMSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29kZTogUGFyc2UuRXJyb3IuSU5DT1JSRUNUX1RZUEUsXG4gICAgICAgIGVycm9yOlxuICAgICAgICAgICdjdXJyZW50bHksIG9ubHkgb25lIEdlb1BvaW50IGZpZWxkIG1heSBleGlzdCBpbiBhbiBvYmplY3QuIEFkZGluZyAnICtcbiAgICAgICAgICBnZW9Qb2ludHNbMV0gK1xuICAgICAgICAgICcgd2hlbiAnICtcbiAgICAgICAgICBnZW9Qb2ludHNbMF0gK1xuICAgICAgICAgICcgYWxyZWFkeSBleGlzdHMuJyxcbiAgICAgIH07XG4gICAgfVxuICAgIHZhbGlkYXRlQ0xQKGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgZmllbGRzLCB0aGlzLnVzZXJJZFJlZ0V4KTtcbiAgfVxuXG4gIC8vIFNldHMgdGhlIENsYXNzLWxldmVsIHBlcm1pc3Npb25zIGZvciBhIGdpdmVuIGNsYXNzTmFtZSwgd2hpY2ggbXVzdCBleGlzdC5cbiAgc2V0UGVybWlzc2lvbnMoY2xhc3NOYW1lOiBzdHJpbmcsIHBlcm1zOiBhbnksIG5ld1NjaGVtYTogU2NoZW1hRmllbGRzKSB7XG4gICAgaWYgKHR5cGVvZiBwZXJtcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgdmFsaWRhdGVDTFAocGVybXMsIG5ld1NjaGVtYSwgdGhpcy51c2VySWRSZWdFeCk7XG4gICAgcmV0dXJuIHRoaXMuX2RiQWRhcHRlci5zZXRDbGFzc0xldmVsUGVybWlzc2lvbnMoY2xhc3NOYW1lLCBwZXJtcyk7XG4gIH1cblxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHN1Y2Nlc3NmdWxseSB0byB0aGUgbmV3IHNjaGVtYVxuICAvLyBvYmplY3QgaWYgdGhlIHByb3ZpZGVkIGNsYXNzTmFtZS1maWVsZE5hbWUtdHlwZSB0dXBsZSBpcyB2YWxpZC5cbiAgLy8gVGhlIGNsYXNzTmFtZSBtdXN0IGFscmVhZHkgYmUgdmFsaWRhdGVkLlxuICAvLyBJZiAnZnJlZXplJyBpcyB0cnVlLCByZWZ1c2UgdG8gdXBkYXRlIHRoZSBzY2hlbWEgZm9yIHRoaXMgZmllbGQuXG4gIGVuZm9yY2VGaWVsZEV4aXN0cyhjbGFzc05hbWU6IHN0cmluZywgZmllbGROYW1lOiBzdHJpbmcsIHR5cGU6IHN0cmluZyB8IFNjaGVtYUZpZWxkKSB7XG4gICAgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPiAwKSB7XG4gICAgICAvLyBzdWJkb2N1bWVudCBrZXkgKHgueSkgPT4gb2sgaWYgeCBpcyBvZiB0eXBlICdvYmplY3QnXG4gICAgICBmaWVsZE5hbWUgPSBmaWVsZE5hbWUuc3BsaXQoJy4nKVswXTtcbiAgICAgIHR5cGUgPSAnT2JqZWN0JztcbiAgICB9XG4gICAgaWYgKCFmaWVsZE5hbWVJc1ZhbGlkKGZpZWxkTmFtZSwgY2xhc3NOYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUsIGBJbnZhbGlkIGZpZWxkIG5hbWU6ICR7ZmllbGROYW1lfS5gKTtcbiAgICB9XG5cbiAgICAvLyBJZiBzb21lb25lIHRyaWVzIHRvIGNyZWF0ZSBhIG5ldyBmaWVsZCB3aXRoIG51bGwvdW5kZWZpbmVkIGFzIHRoZSB2YWx1ZSwgcmV0dXJuO1xuICAgIGlmICghdHlwZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBleHBlY3RlZFR5cGUgPSB0aGlzLmdldEV4cGVjdGVkVHlwZShjbGFzc05hbWUsIGZpZWxkTmFtZSk7XG4gICAgaWYgKHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgdHlwZSA9ICh7IHR5cGUgfTogU2NoZW1hRmllbGQpO1xuICAgIH1cblxuICAgIGlmICh0eXBlLmRlZmF1bHRWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBsZXQgZGVmYXVsdFZhbHVlVHlwZSA9IGdldFR5cGUodHlwZS5kZWZhdWx0VmFsdWUpO1xuICAgICAgaWYgKHR5cGVvZiBkZWZhdWx0VmFsdWVUeXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICBkZWZhdWx0VmFsdWVUeXBlID0geyB0eXBlOiBkZWZhdWx0VmFsdWVUeXBlIH07XG4gICAgICB9XG4gICAgICBpZiAoIWRiVHlwZU1hdGNoZXNPYmplY3RUeXBlKHR5cGUsIGRlZmF1bHRWYWx1ZVR5cGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSxcbiAgICAgICAgICBgc2NoZW1hIG1pc21hdGNoIGZvciAke2NsYXNzTmFtZX0uJHtmaWVsZE5hbWV9IGRlZmF1bHQgdmFsdWU7IGV4cGVjdGVkICR7dHlwZVRvU3RyaW5nKFxuICAgICAgICAgICAgdHlwZVxuICAgICAgICAgICl9IGJ1dCBnb3QgJHt0eXBlVG9TdHJpbmcoZGVmYXVsdFZhbHVlVHlwZSl9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChleHBlY3RlZFR5cGUpIHtcbiAgICAgIGlmICghZGJUeXBlTWF0Y2hlc09iamVjdFR5cGUoZXhwZWN0ZWRUeXBlLCB0eXBlKSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5DT1JSRUNUX1RZUEUsXG4gICAgICAgICAgYHNjaGVtYSBtaXNtYXRjaCBmb3IgJHtjbGFzc05hbWV9LiR7ZmllbGROYW1lfTsgZXhwZWN0ZWQgJHt0eXBlVG9TdHJpbmcoXG4gICAgICAgICAgICBleHBlY3RlZFR5cGVcbiAgICAgICAgICApfSBidXQgZ290ICR7dHlwZVRvU3RyaW5nKHR5cGUpfWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2RiQWRhcHRlclxuICAgICAgLmFkZEZpZWxkSWZOb3RFeGlzdHMoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHR5cGUpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PSBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSkge1xuICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHdlIHRocm93IGVycm9ycyB3aGVuIGl0IGlzIGFwcHJvcHJpYXRlIHRvIGRvIHNvLlxuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRoZSB1cGRhdGUgZmFpbGVkLiBUaGlzIGNhbiBiZSBva2F5IC0gaXQgbWlnaHQgaGF2ZSBiZWVuIGEgcmFjZVxuICAgICAgICAvLyBjb25kaXRpb24gd2hlcmUgYW5vdGhlciBjbGllbnQgdXBkYXRlZCB0aGUgc2NoZW1hIGluIHRoZSBzYW1lXG4gICAgICAgIC8vIHdheSB0aGF0IHdlIHdhbnRlZCB0by4gU28sIGp1c3QgcmVsb2FkIHRoZSBzY2hlbWFcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgZmllbGROYW1lLFxuICAgICAgICAgIHR5cGUsXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgfVxuXG4gIGVuc3VyZUZpZWxkcyhmaWVsZHM6IGFueSkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZmllbGRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCB7IGNsYXNzTmFtZSwgZmllbGROYW1lIH0gPSBmaWVsZHNbaV07XG4gICAgICBsZXQgeyB0eXBlIH0gPSBmaWVsZHNbaV07XG4gICAgICBjb25zdCBleHBlY3RlZFR5cGUgPSB0aGlzLmdldEV4cGVjdGVkVHlwZShjbGFzc05hbWUsIGZpZWxkTmFtZSk7XG4gICAgICBpZiAodHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHR5cGUgPSB7IHR5cGU6IHR5cGUgfTtcbiAgICAgIH1cbiAgICAgIGlmICghZXhwZWN0ZWRUeXBlIHx8ICFkYlR5cGVNYXRjaGVzT2JqZWN0VHlwZShleHBlY3RlZFR5cGUsIHR5cGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sIGBDb3VsZCBub3QgYWRkIGZpZWxkICR7ZmllbGROYW1lfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIG1haW50YWluIGNvbXBhdGliaWxpdHlcbiAgZGVsZXRlRmllbGQoZmllbGROYW1lOiBzdHJpbmcsIGNsYXNzTmFtZTogc3RyaW5nLCBkYXRhYmFzZTogRGF0YWJhc2VDb250cm9sbGVyKSB7XG4gICAgcmV0dXJuIHRoaXMuZGVsZXRlRmllbGRzKFtmaWVsZE5hbWVdLCBjbGFzc05hbWUsIGRhdGFiYXNlKTtcbiAgfVxuXG4gIC8vIERlbGV0ZSBmaWVsZHMsIGFuZCByZW1vdmUgdGhhdCBkYXRhIGZyb20gYWxsIG9iamVjdHMuIFRoaXMgaXMgaW50ZW5kZWRcbiAgLy8gdG8gcmVtb3ZlIHVudXNlZCBmaWVsZHMsIGlmIG90aGVyIHdyaXRlcnMgYXJlIHdyaXRpbmcgb2JqZWN0cyB0aGF0IGluY2x1ZGVcbiAgLy8gdGhpcyBmaWVsZCwgdGhlIGZpZWxkIG1heSByZWFwcGVhci4gUmV0dXJucyBhIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoXG4gIC8vIG5vIG9iamVjdCBvbiBzdWNjZXNzLCBvciByZWplY3RzIHdpdGggeyBjb2RlLCBlcnJvciB9IG9uIGZhaWx1cmUuXG4gIC8vIFBhc3NpbmcgdGhlIGRhdGFiYXNlIGFuZCBwcmVmaXggaXMgbmVjZXNzYXJ5IGluIG9yZGVyIHRvIGRyb3AgcmVsYXRpb24gY29sbGVjdGlvbnNcbiAgLy8gYW5kIHJlbW92ZSBmaWVsZHMgZnJvbSBvYmplY3RzLiBJZGVhbGx5IHRoZSBkYXRhYmFzZSB3b3VsZCBiZWxvbmcgdG9cbiAgLy8gYSBkYXRhYmFzZSBhZGFwdGVyIGFuZCB0aGlzIGZ1bmN0aW9uIHdvdWxkIGNsb3NlIG92ZXIgaXQgb3IgYWNjZXNzIGl0IHZpYSBtZW1iZXIuXG4gIGRlbGV0ZUZpZWxkcyhmaWVsZE5hbWVzOiBBcnJheTxzdHJpbmc+LCBjbGFzc05hbWU6IHN0cmluZywgZGF0YWJhc2U6IERhdGFiYXNlQ29udHJvbGxlcikge1xuICAgIGlmICghY2xhc3NOYW1lSXNWYWxpZChjbGFzc05hbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLCBpbnZhbGlkQ2xhc3NOYW1lTWVzc2FnZShjbGFzc05hbWUpKTtcbiAgICB9XG5cbiAgICBmaWVsZE5hbWVzLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgIGlmICghZmllbGROYW1lSXNWYWxpZChmaWVsZE5hbWUsIGNsYXNzTmFtZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUsIGBpbnZhbGlkIGZpZWxkIG5hbWU6ICR7ZmllbGROYW1lfWApO1xuICAgICAgfVxuICAgICAgLy9Eb24ndCBhbGxvdyBkZWxldGluZyB0aGUgZGVmYXVsdCBmaWVsZHMuXG4gICAgICBpZiAoIWZpZWxkTmFtZUlzVmFsaWRGb3JDbGFzcyhmaWVsZE5hbWUsIGNsYXNzTmFtZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDEzNiwgYGZpZWxkICR7ZmllbGROYW1lfSBjYW5ub3QgYmUgY2hhbmdlZGApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMuZ2V0T25lU2NoZW1hKGNsYXNzTmFtZSwgZmFsc2UsIHsgY2xlYXJDYWNoZTogdHJ1ZSB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0NMQVNTX05BTUUsXG4gICAgICAgICAgICBgQ2xhc3MgJHtjbGFzc05hbWV9IGRvZXMgbm90IGV4aXN0LmBcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLnRoZW4oc2NoZW1hID0+IHtcbiAgICAgICAgZmllbGROYW1lcy5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICAgICAgaWYgKCFzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigyNTUsIGBGaWVsZCAke2ZpZWxkTmFtZX0gZG9lcyBub3QgZXhpc3QsIGNhbm5vdCBkZWxldGUuYCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBzY2hlbWFGaWVsZHMgPSB7IC4uLnNjaGVtYS5maWVsZHMgfTtcbiAgICAgICAgcmV0dXJuIGRhdGFiYXNlLmFkYXB0ZXIuZGVsZXRlRmllbGRzKGNsYXNzTmFtZSwgc2NoZW1hLCBmaWVsZE5hbWVzKS50aGVuKCgpID0+IHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICBmaWVsZE5hbWVzLm1hcChmaWVsZE5hbWUgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBmaWVsZCA9IHNjaGVtYUZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgICAgICAgICBpZiAoZmllbGQgJiYgZmllbGQudHlwZSA9PT0gJ1JlbGF0aW9uJykge1xuICAgICAgICAgICAgICAgIC8vRm9yIHJlbGF0aW9ucywgZHJvcCB0aGUgX0pvaW4gdGFibGVcbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YWJhc2UuYWRhcHRlci5kZWxldGVDbGFzcyhgX0pvaW46JHtmaWVsZE5hbWV9OiR7Y2xhc3NOYW1lfWApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5fY2FjaGUuY2xlYXIoKSk7XG4gIH1cblxuICAvLyBWYWxpZGF0ZXMgYW4gb2JqZWN0IHByb3ZpZGVkIGluIFJFU1QgZm9ybWF0LlxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBuZXcgc2NoZW1hIGlmIHRoaXMgb2JqZWN0IGlzXG4gIC8vIHZhbGlkLlxuICBhc3luYyB2YWxpZGF0ZU9iamVjdChjbGFzc05hbWU6IHN0cmluZywgb2JqZWN0OiBhbnksIHF1ZXJ5OiBhbnkpIHtcbiAgICBsZXQgZ2VvY291bnQgPSAwO1xuICAgIGNvbnN0IHNjaGVtYSA9IGF3YWl0IHRoaXMuZW5mb3JjZUNsYXNzRXhpc3RzKGNsYXNzTmFtZSk7XG4gICAgY29uc3QgcHJvbWlzZXMgPSBbXTtcblxuICAgIGZvciAoY29uc3QgZmllbGROYW1lIGluIG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdFtmaWVsZE5hbWVdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBleHBlY3RlZCA9IGdldFR5cGUob2JqZWN0W2ZpZWxkTmFtZV0pO1xuICAgICAgaWYgKGV4cGVjdGVkID09PSAnR2VvUG9pbnQnKSB7XG4gICAgICAgIGdlb2NvdW50Kys7XG4gICAgICB9XG4gICAgICBpZiAoZ2VvY291bnQgPiAxKSB7XG4gICAgICAgIC8vIE1ha2Ugc3VyZSBhbGwgZmllbGQgdmFsaWRhdGlvbiBvcGVyYXRpb25zIHJ1biBiZWZvcmUgd2UgcmV0dXJuLlxuICAgICAgICAvLyBJZiBub3QgLSB3ZSBhcmUgY29udGludWluZyB0byBydW4gbG9naWMsIGJ1dCBhbHJlYWR5IHByb3ZpZGVkIHJlc3BvbnNlIGZyb20gdGhlIHNlcnZlci5cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KFxuICAgICAgICAgIG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLFxuICAgICAgICAgICAgJ3RoZXJlIGNhbiBvbmx5IGJlIG9uZSBnZW9wb2ludCBmaWVsZCBpbiBhIGNsYXNzJ1xuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmICghZXhwZWN0ZWQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoZmllbGROYW1lID09PSAnQUNMJykge1xuICAgICAgICAvLyBFdmVyeSBvYmplY3QgaGFzIEFDTCBpbXBsaWNpdGx5LlxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHByb21pc2VzLnB1c2goc2NoZW1hLmVuZm9yY2VGaWVsZEV4aXN0cyhjbGFzc05hbWUsIGZpZWxkTmFtZSwgZXhwZWN0ZWQpKTtcbiAgICB9XG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICBjb25zdCBlbmZvcmNlRmllbGRzID0gcmVzdWx0cy5maWx0ZXIocmVzdWx0ID0+ICEhcmVzdWx0KTtcblxuICAgIGlmIChlbmZvcmNlRmllbGRzLmxlbmd0aCAhPT0gMCkge1xuICAgICAgYXdhaXQgdGhpcy5yZWxvYWREYXRhKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KTtcbiAgICB9XG4gICAgdGhpcy5lbnN1cmVGaWVsZHMoZW5mb3JjZUZpZWxkcyk7XG5cbiAgICBjb25zdCBwcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKHNjaGVtYSk7XG4gICAgcmV0dXJuIHRoZW5WYWxpZGF0ZVJlcXVpcmVkQ29sdW1ucyhwcm9taXNlLCBjbGFzc05hbWUsIG9iamVjdCwgcXVlcnkpO1xuICB9XG5cbiAgLy8gVmFsaWRhdGVzIHRoYXQgYWxsIHRoZSBwcm9wZXJ0aWVzIGFyZSBzZXQgZm9yIHRoZSBvYmplY3RcbiAgdmFsaWRhdGVSZXF1aXJlZENvbHVtbnMoY2xhc3NOYW1lOiBzdHJpbmcsIG9iamVjdDogYW55LCBxdWVyeTogYW55KSB7XG4gICAgY29uc3QgY29sdW1ucyA9IHJlcXVpcmVkQ29sdW1uc1tjbGFzc05hbWVdO1xuICAgIGlmICghY29sdW1ucyB8fCBjb2x1bW5zLmxlbmd0aCA9PSAwKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMpO1xuICAgIH1cblxuICAgIGNvbnN0IG1pc3NpbmdDb2x1bW5zID0gY29sdW1ucy5maWx0ZXIoZnVuY3Rpb24gKGNvbHVtbikge1xuICAgICAgaWYgKHF1ZXJ5ICYmIHF1ZXJ5Lm9iamVjdElkKSB7XG4gICAgICAgIGlmIChvYmplY3RbY29sdW1uXSAmJiB0eXBlb2Ygb2JqZWN0W2NvbHVtbl0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgLy8gVHJ5aW5nIHRvIGRlbGV0ZSBhIHJlcXVpcmVkIGNvbHVtblxuICAgICAgICAgIHJldHVybiBvYmplY3RbY29sdW1uXS5fX29wID09ICdEZWxldGUnO1xuICAgICAgICB9XG4gICAgICAgIC8vIE5vdCB0cnlpbmcgdG8gZG8gYW55dGhpbmcgdGhlcmVcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuICFvYmplY3RbY29sdW1uXTtcbiAgICB9KTtcblxuICAgIGlmIChtaXNzaW5nQ29sdW1ucy5sZW5ndGggPiAwKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5DT1JSRUNUX1RZUEUsIG1pc3NpbmdDb2x1bW5zWzBdICsgJyBpcyByZXF1aXJlZC4nKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzKTtcbiAgfVxuXG4gIHRlc3RQZXJtaXNzaW9uc0ZvckNsYXNzTmFtZShjbGFzc05hbWU6IHN0cmluZywgYWNsR3JvdXA6IHN0cmluZ1tdLCBvcGVyYXRpb246IHN0cmluZykge1xuICAgIHJldHVybiBTY2hlbWFDb250cm9sbGVyLnRlc3RQZXJtaXNzaW9ucyhcbiAgICAgIHRoaXMuZ2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zKGNsYXNzTmFtZSksXG4gICAgICBhY2xHcm91cCxcbiAgICAgIG9wZXJhdGlvblxuICAgICk7XG4gIH1cblxuICAvLyBUZXN0cyB0aGF0IHRoZSBjbGFzcyBsZXZlbCBwZXJtaXNzaW9uIGxldCBwYXNzIHRoZSBvcGVyYXRpb24gZm9yIGEgZ2l2ZW4gYWNsR3JvdXBcbiAgc3RhdGljIHRlc3RQZXJtaXNzaW9ucyhjbGFzc1Blcm1pc3Npb25zOiA/YW55LCBhY2xHcm91cDogc3RyaW5nW10sIG9wZXJhdGlvbjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKCFjbGFzc1Blcm1pc3Npb25zIHx8ICFjbGFzc1Blcm1pc3Npb25zW29wZXJhdGlvbl0pIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjb25zdCBwZXJtcyA9IGNsYXNzUGVybWlzc2lvbnNbb3BlcmF0aW9uXTtcbiAgICBpZiAocGVybXNbJyonXSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8vIENoZWNrIHBlcm1pc3Npb25zIGFnYWluc3QgdGhlIGFjbEdyb3VwIHByb3ZpZGVkIChhcnJheSBvZiB1c2VySWQvcm9sZXMpXG4gICAgaWYgKFxuICAgICAgYWNsR3JvdXAuc29tZShhY2wgPT4ge1xuICAgICAgICByZXR1cm4gcGVybXNbYWNsXSA9PT0gdHJ1ZTtcbiAgICAgIH0pXG4gICAgKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gVmFsaWRhdGVzIGFuIG9wZXJhdGlvbiBwYXNzZXMgY2xhc3MtbGV2ZWwtcGVybWlzc2lvbnMgc2V0IGluIHRoZSBzY2hlbWFcbiAgc3RhdGljIHZhbGlkYXRlUGVybWlzc2lvbihcbiAgICBjbGFzc1Blcm1pc3Npb25zOiA/YW55LFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIGFjbEdyb3VwOiBzdHJpbmdbXSxcbiAgICBvcGVyYXRpb246IHN0cmluZyxcbiAgICBhY3Rpb24/OiBzdHJpbmdcbiAgKSB7XG4gICAgaWYgKFNjaGVtYUNvbnRyb2xsZXIudGVzdFBlcm1pc3Npb25zKGNsYXNzUGVybWlzc2lvbnMsIGFjbEdyb3VwLCBvcGVyYXRpb24pKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuXG4gICAgaWYgKCFjbGFzc1Blcm1pc3Npb25zIHx8ICFjbGFzc1Blcm1pc3Npb25zW29wZXJhdGlvbl0pIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjb25zdCBwZXJtcyA9IGNsYXNzUGVybWlzc2lvbnNbb3BlcmF0aW9uXTtcbiAgICAvLyBJZiBvbmx5IGZvciBhdXRoZW50aWNhdGVkIHVzZXJzXG4gICAgLy8gbWFrZSBzdXJlIHdlIGhhdmUgYW4gYWNsR3JvdXBcbiAgICBpZiAocGVybXNbJ3JlcXVpcmVzQXV0aGVudGljYXRpb24nXSkge1xuICAgICAgLy8gSWYgYWNsR3JvdXAgaGFzICogKHB1YmxpYylcbiAgICAgIGlmICghYWNsR3JvdXAgfHwgYWNsR3JvdXAubGVuZ3RoID09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICAgJ1Blcm1pc3Npb24gZGVuaWVkLCB1c2VyIG5lZWRzIHRvIGJlIGF1dGhlbnRpY2F0ZWQuJ1xuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmIChhY2xHcm91cC5pbmRleE9mKCcqJykgPiAtMSAmJiBhY2xHcm91cC5sZW5ndGggPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICAgICAnUGVybWlzc2lvbiBkZW5pZWQsIHVzZXIgbmVlZHMgdG8gYmUgYXV0aGVudGljYXRlZC4nXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICAvLyByZXF1aXJlc0F1dGhlbnRpY2F0aW9uIHBhc3NlZCwganVzdCBtb3ZlIGZvcndhcmRcbiAgICAgIC8vIHByb2JhYmx5IHdvdWxkIGJlIHdpc2UgYXQgc29tZSBwb2ludCB0byByZW5hbWUgdG8gJ2F1dGhlbnRpY2F0ZWRVc2VyJ1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIC8vIE5vIG1hdGNoaW5nIENMUCwgbGV0J3MgY2hlY2sgdGhlIFBvaW50ZXIgcGVybWlzc2lvbnNcbiAgICAvLyBBbmQgaGFuZGxlIHRob3NlIGxhdGVyXG4gICAgY29uc3QgcGVybWlzc2lvbkZpZWxkID1cbiAgICAgIFsnZ2V0JywgJ2ZpbmQnLCAnY291bnQnXS5pbmRleE9mKG9wZXJhdGlvbikgPiAtMSA/ICdyZWFkVXNlckZpZWxkcycgOiAnd3JpdGVVc2VyRmllbGRzJztcblxuICAgIC8vIFJlamVjdCBjcmVhdGUgd2hlbiB3cml0ZSBsb2NrZG93blxuICAgIGlmIChwZXJtaXNzaW9uRmllbGQgPT0gJ3dyaXRlVXNlckZpZWxkcycgJiYgb3BlcmF0aW9uID09ICdjcmVhdGUnKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sXG4gICAgICAgIGBQZXJtaXNzaW9uIGRlbmllZCBmb3IgYWN0aW9uICR7b3BlcmF0aW9ufSBvbiBjbGFzcyAke2NsYXNzTmFtZX0uYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBQcm9jZXNzIHRoZSByZWFkVXNlckZpZWxkcyBsYXRlclxuICAgIGlmIChcbiAgICAgIEFycmF5LmlzQXJyYXkoY2xhc3NQZXJtaXNzaW9uc1twZXJtaXNzaW9uRmllbGRdKSAmJlxuICAgICAgY2xhc3NQZXJtaXNzaW9uc1twZXJtaXNzaW9uRmllbGRdLmxlbmd0aCA+IDBcbiAgICApIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG5cbiAgICBjb25zdCBwb2ludGVyRmllbGRzID0gY2xhc3NQZXJtaXNzaW9uc1tvcGVyYXRpb25dLnBvaW50ZXJGaWVsZHM7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocG9pbnRlckZpZWxkcykgJiYgcG9pbnRlckZpZWxkcy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBhbnkgb3AgZXhjZXB0ICdhZGRGaWVsZCBhcyBwYXJ0IG9mIGNyZWF0ZScgaXMgb2suXG4gICAgICBpZiAob3BlcmF0aW9uICE9PSAnYWRkRmllbGQnIHx8IGFjdGlvbiA9PT0gJ3VwZGF0ZScpIHtcbiAgICAgICAgLy8gV2UgY2FuIGFsbG93IGFkZGluZyBmaWVsZCBvbiB1cGRhdGUgZmxvdyBvbmx5LlxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgIGBQZXJtaXNzaW9uIGRlbmllZCBmb3IgYWN0aW9uICR7b3BlcmF0aW9ufSBvbiBjbGFzcyAke2NsYXNzTmFtZX0uYFxuICAgICk7XG4gIH1cblxuICAvLyBWYWxpZGF0ZXMgYW4gb3BlcmF0aW9uIHBhc3NlcyBjbGFzcy1sZXZlbC1wZXJtaXNzaW9ucyBzZXQgaW4gdGhlIHNjaGVtYVxuICB2YWxpZGF0ZVBlcm1pc3Npb24oY2xhc3NOYW1lOiBzdHJpbmcsIGFjbEdyb3VwOiBzdHJpbmdbXSwgb3BlcmF0aW9uOiBzdHJpbmcsIGFjdGlvbj86IHN0cmluZykge1xuICAgIHJldHVybiBTY2hlbWFDb250cm9sbGVyLnZhbGlkYXRlUGVybWlzc2lvbihcbiAgICAgIHRoaXMuZ2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zKGNsYXNzTmFtZSksXG4gICAgICBjbGFzc05hbWUsXG4gICAgICBhY2xHcm91cCxcbiAgICAgIG9wZXJhdGlvbixcbiAgICAgIGFjdGlvblxuICAgICk7XG4gIH1cblxuICBnZXRDbGFzc0xldmVsUGVybWlzc2lvbnMoY2xhc3NOYW1lOiBzdHJpbmcpOiBhbnkge1xuICAgIHJldHVybiB0aGlzLnNjaGVtYURhdGFbY2xhc3NOYW1lXSAmJiB0aGlzLnNjaGVtYURhdGFbY2xhc3NOYW1lXS5jbGFzc0xldmVsUGVybWlzc2lvbnM7XG4gIH1cblxuICAvLyBSZXR1cm5zIHRoZSBleHBlY3RlZCB0eXBlIGZvciBhIGNsYXNzTmFtZStrZXkgY29tYmluYXRpb25cbiAgLy8gb3IgdW5kZWZpbmVkIGlmIHRoZSBzY2hlbWEgaXMgbm90IHNldFxuICBnZXRFeHBlY3RlZFR5cGUoY2xhc3NOYW1lOiBzdHJpbmcsIGZpZWxkTmFtZTogc3RyaW5nKTogPyhTY2hlbWFGaWVsZCB8IHN0cmluZykge1xuICAgIGlmICh0aGlzLnNjaGVtYURhdGFbY2xhc3NOYW1lXSkge1xuICAgICAgY29uc3QgZXhwZWN0ZWRUeXBlID0gdGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV0uZmllbGRzW2ZpZWxkTmFtZV07XG4gICAgICByZXR1cm4gZXhwZWN0ZWRUeXBlID09PSAnbWFwJyA/ICdPYmplY3QnIDogZXhwZWN0ZWRUeXBlO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLy8gQ2hlY2tzIGlmIGEgZ2l2ZW4gY2xhc3MgaXMgaW4gdGhlIHNjaGVtYS5cbiAgaGFzQ2xhc3MoY2xhc3NOYW1lOiBzdHJpbmcpIHtcbiAgICBpZiAodGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV0pIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodHJ1ZSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnJlbG9hZERhdGEoKS50aGVuKCgpID0+ICEhdGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV0pO1xuICB9XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIGZvciBhIG5ldyBTY2hlbWEuXG5jb25zdCBsb2FkID0gKFxuICBkYkFkYXB0ZXI6IFN0b3JhZ2VBZGFwdGVyLFxuICBzY2hlbWFDYWNoZTogYW55LFxuICBvcHRpb25zOiBhbnlcbik6IFByb21pc2U8U2NoZW1hQ29udHJvbGxlcj4gPT4ge1xuICBjb25zdCBzY2hlbWEgPSBuZXcgU2NoZW1hQ29udHJvbGxlcihkYkFkYXB0ZXIsIHNjaGVtYUNhY2hlKTtcbiAgcmV0dXJuIHNjaGVtYS5yZWxvYWREYXRhKG9wdGlvbnMpLnRoZW4oKCkgPT4gc2NoZW1hKTtcbn07XG5cbi8vIEJ1aWxkcyBhIG5ldyBzY2hlbWEgKGluIHNjaGVtYSBBUEkgcmVzcG9uc2UgZm9ybWF0KSBvdXQgb2YgYW5cbi8vIGV4aXN0aW5nIG1vbmdvIHNjaGVtYSArIGEgc2NoZW1hcyBBUEkgcHV0IHJlcXVlc3QuIFRoaXMgcmVzcG9uc2Vcbi8vIGRvZXMgbm90IGluY2x1ZGUgdGhlIGRlZmF1bHQgZmllbGRzLCBhcyBpdCBpcyBpbnRlbmRlZCB0byBiZSBwYXNzZWRcbi8vIHRvIG1vbmdvU2NoZW1hRnJvbUZpZWxkc0FuZENsYXNzTmFtZS4gTm8gdmFsaWRhdGlvbiBpcyBkb25lIGhlcmUsIGl0XG4vLyBpcyBkb25lIGluIG1vbmdvU2NoZW1hRnJvbUZpZWxkc0FuZENsYXNzTmFtZS5cbmZ1bmN0aW9uIGJ1aWxkTWVyZ2VkU2NoZW1hT2JqZWN0KGV4aXN0aW5nRmllbGRzOiBTY2hlbWFGaWVsZHMsIHB1dFJlcXVlc3Q6IGFueSk6IFNjaGVtYUZpZWxkcyB7XG4gIGNvbnN0IG5ld1NjaGVtYSA9IHt9O1xuICAvLyBAZmxvdy1kaXNhYmxlLW5leHRcbiAgY29uc3Qgc3lzU2NoZW1hRmllbGQgPVxuICAgIE9iamVjdC5rZXlzKGRlZmF1bHRDb2x1bW5zKS5pbmRleE9mKGV4aXN0aW5nRmllbGRzLl9pZCkgPT09IC0xXG4gICAgICA/IFtdXG4gICAgICA6IE9iamVjdC5rZXlzKGRlZmF1bHRDb2x1bW5zW2V4aXN0aW5nRmllbGRzLl9pZF0pO1xuICBmb3IgKGNvbnN0IG9sZEZpZWxkIGluIGV4aXN0aW5nRmllbGRzKSB7XG4gICAgaWYgKFxuICAgICAgb2xkRmllbGQgIT09ICdfaWQnICYmXG4gICAgICBvbGRGaWVsZCAhPT0gJ0FDTCcgJiZcbiAgICAgIG9sZEZpZWxkICE9PSAndXBkYXRlZEF0JyAmJlxuICAgICAgb2xkRmllbGQgIT09ICdjcmVhdGVkQXQnICYmXG4gICAgICBvbGRGaWVsZCAhPT0gJ29iamVjdElkJ1xuICAgICkge1xuICAgICAgaWYgKHN5c1NjaGVtYUZpZWxkLmxlbmd0aCA+IDAgJiYgc3lzU2NoZW1hRmllbGQuaW5kZXhPZihvbGRGaWVsZCkgIT09IC0xKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgZmllbGRJc0RlbGV0ZWQgPSBwdXRSZXF1ZXN0W29sZEZpZWxkXSAmJiBwdXRSZXF1ZXN0W29sZEZpZWxkXS5fX29wID09PSAnRGVsZXRlJztcbiAgICAgIGlmICghZmllbGRJc0RlbGV0ZWQpIHtcbiAgICAgICAgbmV3U2NoZW1hW29sZEZpZWxkXSA9IGV4aXN0aW5nRmllbGRzW29sZEZpZWxkXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZm9yIChjb25zdCBuZXdGaWVsZCBpbiBwdXRSZXF1ZXN0KSB7XG4gICAgaWYgKG5ld0ZpZWxkICE9PSAnb2JqZWN0SWQnICYmIHB1dFJlcXVlc3RbbmV3RmllbGRdLl9fb3AgIT09ICdEZWxldGUnKSB7XG4gICAgICBpZiAoc3lzU2NoZW1hRmllbGQubGVuZ3RoID4gMCAmJiBzeXNTY2hlbWFGaWVsZC5pbmRleE9mKG5ld0ZpZWxkKSAhPT0gLTEpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBuZXdTY2hlbWFbbmV3RmllbGRdID0gcHV0UmVxdWVzdFtuZXdGaWVsZF07XG4gICAgfVxuICB9XG4gIHJldHVybiBuZXdTY2hlbWE7XG59XG5cbi8vIEdpdmVuIGEgc2NoZW1hIHByb21pc2UsIGNvbnN0cnVjdCBhbm90aGVyIHNjaGVtYSBwcm9taXNlIHRoYXRcbi8vIHZhbGlkYXRlcyB0aGlzIGZpZWxkIG9uY2UgdGhlIHNjaGVtYSBsb2Fkcy5cbmZ1bmN0aW9uIHRoZW5WYWxpZGF0ZVJlcXVpcmVkQ29sdW1ucyhzY2hlbWFQcm9taXNlLCBjbGFzc05hbWUsIG9iamVjdCwgcXVlcnkpIHtcbiAgcmV0dXJuIHNjaGVtYVByb21pc2UudGhlbihzY2hlbWEgPT4ge1xuICAgIHJldHVybiBzY2hlbWEudmFsaWRhdGVSZXF1aXJlZENvbHVtbnMoY2xhc3NOYW1lLCBvYmplY3QsIHF1ZXJ5KTtcbiAgfSk7XG59XG5cbi8vIEdldHMgdGhlIHR5cGUgZnJvbSBhIFJFU1QgQVBJIGZvcm1hdHRlZCBvYmplY3QsIHdoZXJlICd0eXBlJyBpc1xuLy8gZXh0ZW5kZWQgcGFzdCBqYXZhc2NyaXB0IHR5cGVzIHRvIGluY2x1ZGUgdGhlIHJlc3Qgb2YgdGhlIFBhcnNlXG4vLyB0eXBlIHN5c3RlbS5cbi8vIFRoZSBvdXRwdXQgc2hvdWxkIGJlIGEgdmFsaWQgc2NoZW1hIHZhbHVlLlxuLy8gVE9ETzogZW5zdXJlIHRoYXQgdGhpcyBpcyBjb21wYXRpYmxlIHdpdGggdGhlIGZvcm1hdCB1c2VkIGluIE9wZW4gREJcbmZ1bmN0aW9uIGdldFR5cGUob2JqOiBhbnkpOiA/KFNjaGVtYUZpZWxkIHwgc3RyaW5nKSB7XG4gIGNvbnN0IHR5cGUgPSB0eXBlb2Ygb2JqO1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdib29sZWFuJzpcbiAgICAgIHJldHVybiAnQm9vbGVhbic7XG4gICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgIHJldHVybiAnU3RyaW5nJztcbiAgICBjYXNlICdudW1iZXInOlxuICAgICAgcmV0dXJuICdOdW1iZXInO1xuICAgIGNhc2UgJ21hcCc6XG4gICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgIGlmICghb2JqKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gZ2V0T2JqZWN0VHlwZShvYmopO1xuICAgIGNhc2UgJ2Z1bmN0aW9uJzpcbiAgICBjYXNlICdzeW1ib2wnOlxuICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93ICdiYWQgb2JqOiAnICsgb2JqO1xuICB9XG59XG5cbi8vIFRoaXMgZ2V0cyB0aGUgdHlwZSBmb3Igbm9uLUpTT04gdHlwZXMgbGlrZSBwb2ludGVycyBhbmQgZmlsZXMsIGJ1dFxuLy8gYWxzbyBnZXRzIHRoZSBhcHByb3ByaWF0ZSB0eXBlIGZvciAkIG9wZXJhdG9ycy5cbi8vIFJldHVybnMgbnVsbCBpZiB0aGUgdHlwZSBpcyB1bmtub3duLlxuZnVuY3Rpb24gZ2V0T2JqZWN0VHlwZShvYmopOiA/KFNjaGVtYUZpZWxkIHwgc3RyaW5nKSB7XG4gIGlmIChvYmogaW5zdGFuY2VvZiBBcnJheSkge1xuICAgIHJldHVybiAnQXJyYXknO1xuICB9XG4gIGlmIChvYmouX190eXBlKSB7XG4gICAgc3dpdGNoIChvYmouX190eXBlKSB7XG4gICAgICBjYXNlICdQb2ludGVyJzpcbiAgICAgICAgaWYgKG9iai5jbGFzc05hbWUpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICAgICAgdGFyZ2V0Q2xhc3M6IG9iai5jbGFzc05hbWUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ1JlbGF0aW9uJzpcbiAgICAgICAgaWYgKG9iai5jbGFzc05hbWUpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ1JlbGF0aW9uJyxcbiAgICAgICAgICAgIHRhcmdldENsYXNzOiBvYmouY2xhc3NOYW1lLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdGaWxlJzpcbiAgICAgICAgaWYgKG9iai5uYW1lKSB7XG4gICAgICAgICAgcmV0dXJuICdGaWxlJztcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0RhdGUnOlxuICAgICAgICBpZiAob2JqLmlzbykge1xuICAgICAgICAgIHJldHVybiAnRGF0ZSc7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdHZW9Qb2ludCc6XG4gICAgICAgIGlmIChvYmoubGF0aXR1ZGUgIT0gbnVsbCAmJiBvYmoubG9uZ2l0dWRlICE9IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gJ0dlb1BvaW50JztcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0J5dGVzJzpcbiAgICAgICAgaWYgKG9iai5iYXNlNjQpIHtcbiAgICAgICAgICByZXR1cm4gJ0J5dGVzJztcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ1BvbHlnb24nOlxuICAgICAgICBpZiAob2JqLmNvb3JkaW5hdGVzKSB7XG4gICAgICAgICAgcmV0dXJuICdQb2x5Z29uJztcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLCAnVGhpcyBpcyBub3QgYSB2YWxpZCAnICsgb2JqLl9fdHlwZSk7XG4gIH1cbiAgaWYgKG9ialsnJG5lJ10pIHtcbiAgICByZXR1cm4gZ2V0T2JqZWN0VHlwZShvYmpbJyRuZSddKTtcbiAgfVxuICBpZiAob2JqLl9fb3ApIHtcbiAgICBzd2l0Y2ggKG9iai5fX29wKSB7XG4gICAgICBjYXNlICdJbmNyZW1lbnQnOlxuICAgICAgICByZXR1cm4gJ051bWJlcic7XG4gICAgICBjYXNlICdEZWxldGUnOlxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIGNhc2UgJ0FkZCc6XG4gICAgICBjYXNlICdBZGRVbmlxdWUnOlxuICAgICAgY2FzZSAnUmVtb3ZlJzpcbiAgICAgICAgcmV0dXJuICdBcnJheSc7XG4gICAgICBjYXNlICdBZGRSZWxhdGlvbic6XG4gICAgICBjYXNlICdSZW1vdmVSZWxhdGlvbic6XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdHlwZTogJ1JlbGF0aW9uJyxcbiAgICAgICAgICB0YXJnZXRDbGFzczogb2JqLm9iamVjdHNbMF0uY2xhc3NOYW1lLFxuICAgICAgICB9O1xuICAgICAgY2FzZSAnQmF0Y2gnOlxuICAgICAgICByZXR1cm4gZ2V0T2JqZWN0VHlwZShvYmoub3BzWzBdKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93ICd1bmV4cGVjdGVkIG9wOiAnICsgb2JqLl9fb3A7XG4gICAgfVxuICB9XG4gIHJldHVybiAnT2JqZWN0Jztcbn1cblxuZXhwb3J0IHtcbiAgbG9hZCxcbiAgY2xhc3NOYW1lSXNWYWxpZCxcbiAgZmllbGROYW1lSXNWYWxpZCxcbiAgaW52YWxpZENsYXNzTmFtZU1lc3NhZ2UsXG4gIGJ1aWxkTWVyZ2VkU2NoZW1hT2JqZWN0LFxuICBzeXN0ZW1DbGFzc2VzLFxuICBkZWZhdWx0Q29sdW1ucyxcbiAgY29udmVydFNjaGVtYVRvQWRhcHRlclNjaGVtYSxcbiAgVm9sYXRpbGVDbGFzc2VzU2NoZW1hcyxcbiAgU2NoZW1hQ29udHJvbGxlcixcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Controllers/UserController.js b/lib/Controllers/UserController.js new file mode 100644 index 0000000000..b327209870 --- /dev/null +++ b/lib/Controllers/UserController.js @@ -0,0 +1,375 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.UserController = void 0; + +var _cryptoUtils = require("../cryptoUtils"); + +var _triggers = require("../triggers"); + +var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); + +var _MailAdapter = _interopRequireDefault(require("../Adapters/Email/MailAdapter")); + +var _rest = _interopRequireDefault(require("../rest")); + +var _node = _interopRequireDefault(require("parse/node")); + +var _AccountLockout = _interopRequireDefault(require("../AccountLockout")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var RestQuery = require('../RestQuery'); + +var Auth = require('../Auth'); + +class UserController extends _AdaptableController.default { + constructor(adapter, appId, options = {}) { + super(adapter, appId, options); + } + + validateAdapter(adapter) { + // Allow no adapter + if (!adapter && !this.shouldVerifyEmails) { + return; + } + + super.validateAdapter(adapter); + } + + expectedAdapterType() { + return _MailAdapter.default; + } + + get shouldVerifyEmails() { + return this.options.verifyUserEmails; + } + + setEmailVerifyToken(user) { + if (this.shouldVerifyEmails) { + user._email_verify_token = (0, _cryptoUtils.randomString)(25); + user.emailVerified = false; + + if (this.config.emailVerifyTokenValidityDuration) { + user._email_verify_token_expires_at = _node.default._encode(this.config.generateEmailVerifyTokenExpiresAt()); + } + } + } + + verifyEmail(username, token) { + if (!this.shouldVerifyEmails) { + // Trying to verify email when not enabled + // TODO: Better error here. + throw undefined; + } + + const query = { + username: username, + _email_verify_token: token + }; + const updateFields = { + emailVerified: true, + _email_verify_token: { + __op: 'Delete' + } + }; // if the email verify token needs to be validated then + // add additional query params and additional fields that need to be updated + + if (this.config.emailVerifyTokenValidityDuration) { + query.emailVerified = false; + query._email_verify_token_expires_at = { + $gt: _node.default._encode(new Date()) + }; + updateFields._email_verify_token_expires_at = { + __op: 'Delete' + }; + } + + const masterAuth = Auth.master(this.config); + var findUserForEmailVerification = new RestQuery(this.config, Auth.master(this.config), '_User', { + username: username + }); + return findUserForEmailVerification.execute().then(result => { + if (result.results.length && result.results[0].emailVerified) { + return Promise.resolve(result.results.length[0]); + } else if (result.results.length) { + query.objectId = result.results[0].objectId; + } + + return _rest.default.update(this.config, masterAuth, '_User', query, updateFields); + }); + } + + checkResetTokenValidity(username, token) { + return this.config.database.find('_User', { + username: username, + _perishable_token: token + }, { + limit: 1 + }).then(results => { + if (results.length != 1) { + throw 'Failed to reset password: username / email / token is invalid'; + } + + if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenValidityDuration) { + let expiresDate = results[0]._perishable_token_expires_at; + + if (expiresDate && expiresDate.__type == 'Date') { + expiresDate = new Date(expiresDate.iso); + } + + if (expiresDate < new Date()) throw 'The password reset link has expired'; + } + + return results[0]; + }); + } + + getUserIfNeeded(user) { + if (user.username && user.email) { + return Promise.resolve(user); + } + + var where = {}; + + if (user.username) { + where.username = user.username; + } + + if (user.email) { + where.email = user.email; + } + + var query = new RestQuery(this.config, Auth.master(this.config), '_User', where); + return query.execute().then(function (result) { + if (result.results.length != 1) { + throw undefined; + } + + return result.results[0]; + }); + } + + sendVerificationEmail(user) { + if (!this.shouldVerifyEmails) { + return; + } + + const token = encodeURIComponent(user._email_verify_token); // We may need to fetch the user in case of update email + + this.getUserIfNeeded(user).then(user => { + const username = encodeURIComponent(user.username); + const link = buildEmailLink(this.config.verifyEmailURL, username, token, this.config); + const options = { + appName: this.config.appName, + link: link, + user: (0, _triggers.inflate)('_User', user) + }; + + if (this.adapter.sendVerificationEmail) { + this.adapter.sendVerificationEmail(options); + } else { + this.adapter.sendMail(this.defaultVerificationEmail(options)); + } + }); + } + /** + * Regenerates the given user's email verification token + * + * @param user + * @returns {*} + */ + + + regenerateEmailVerifyToken(user) { + const { + _email_verify_token + } = user; + let { + _email_verify_token_expires_at + } = user; + + if (_email_verify_token_expires_at && _email_verify_token_expires_at.__type === 'Date') { + _email_verify_token_expires_at = _email_verify_token_expires_at.iso; + } + + if (this.config.emailVerifyTokenReuseIfValid && this.config.emailVerifyTokenValidityDuration && _email_verify_token && new Date() < new Date(_email_verify_token_expires_at)) { + return Promise.resolve(); + } + + this.setEmailVerifyToken(user); + return this.config.database.update('_User', { + username: user.username + }, user); + } + + resendVerificationEmail(username) { + return this.getUserIfNeeded({ + username: username + }).then(aUser => { + if (!aUser || aUser.emailVerified) { + throw undefined; + } + + return this.regenerateEmailVerifyToken(aUser).then(() => { + this.sendVerificationEmail(aUser); + }); + }); + } + + setPasswordResetToken(email) { + const token = { + _perishable_token: (0, _cryptoUtils.randomString)(25) + }; + + if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenValidityDuration) { + token._perishable_token_expires_at = _node.default._encode(this.config.generatePasswordResetTokenExpiresAt()); + } + + return this.config.database.update('_User', { + $or: [{ + email + }, { + username: email, + email: { + $exists: false + } + }] + }, token, {}, true); + } + + async sendPasswordResetEmail(email) { + if (!this.adapter) { + throw 'Trying to send a reset password but no adapter is set'; // TODO: No adapter? + } + + let user; + + if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenReuseIfValid && this.config.passwordPolicy.resetTokenValidityDuration) { + const results = await this.config.database.find('_User', { + $or: [{ + email, + _perishable_token: { + $exists: true + } + }, { + username: email, + email: { + $exists: false + }, + _perishable_token: { + $exists: true + } + }] + }, { + limit: 1 + }); + + if (results.length == 1) { + let expiresDate = results[0]._perishable_token_expires_at; + + if (expiresDate && expiresDate.__type == 'Date') { + expiresDate = new Date(expiresDate.iso); + } + + if (expiresDate > new Date()) { + user = results[0]; + } + } + } + + if (!user || !user._perishable_token) { + user = await this.setPasswordResetToken(email); + } + + const token = encodeURIComponent(user._perishable_token); + const username = encodeURIComponent(user.username); + const link = buildEmailLink(this.config.requestResetPasswordURL, username, token, this.config); + const options = { + appName: this.config.appName, + link: link, + user: (0, _triggers.inflate)('_User', user) + }; + + if (this.adapter.sendPasswordResetEmail) { + this.adapter.sendPasswordResetEmail(options); + } else { + this.adapter.sendMail(this.defaultResetPasswordEmail(options)); + } + + return Promise.resolve(user); + } + + updatePassword(username, token, password) { + return this.checkResetTokenValidity(username, token).then(user => updateUserPassword(user, password, this.config)).then(user => { + const accountLockoutPolicy = new _AccountLockout.default(user, this.config); + return accountLockoutPolicy.unlockAccount(); + }).catch(error => { + if (error && error.message) { + // in case of Parse.Error, fail with the error message only + return Promise.reject(error.message); + } else { + return Promise.reject(error); + } + }); + } + + defaultVerificationEmail({ + link, + user, + appName + }) { + const text = 'Hi,\n\n' + 'You are being asked to confirm the e-mail address ' + user.get('email') + ' with ' + appName + '\n\n' + '' + 'Click here to confirm it:\n' + link; + const to = user.get('email'); + const subject = 'Please verify your e-mail for ' + appName; + return { + text, + to, + subject + }; + } + + defaultResetPasswordEmail({ + link, + user, + appName + }) { + const text = 'Hi,\n\n' + 'You requested to reset your password for ' + appName + (user.get('username') ? " (your username is '" + user.get('username') + "')" : '') + '.\n\n' + '' + 'Click here to reset it:\n' + link; + const to = user.get('email') || user.get('username'); + const subject = 'Password Reset for ' + appName; + return { + text, + to, + subject + }; + } + +} // Mark this private + + +exports.UserController = UserController; + +function updateUserPassword(user, password, config) { + return _rest.default.update(config, Auth.master(config), '_User', { + objectId: user.objectId + }, { + password: password + }).then(() => user); +} + +function buildEmailLink(destination, username, token, config) { + const usernameAndToken = `token=${token}&username=${username}`; + + if (config.parseFrameURL) { + const destinationWithoutHost = destination.replace(config.publicServerURL, ''); + return `${config.parseFrameURL}?link=${encodeURIComponent(destinationWithoutHost)}&${usernameAndToken}`; + } else { + return `${destination}?${usernameAndToken}`; + } +} + +var _default = UserController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9Vc2VyQ29udHJvbGxlci5qcyJdLCJuYW1lcyI6WyJSZXN0UXVlcnkiLCJyZXF1aXJlIiwiQXV0aCIsIlVzZXJDb250cm9sbGVyIiwiQWRhcHRhYmxlQ29udHJvbGxlciIsImNvbnN0cnVjdG9yIiwiYWRhcHRlciIsImFwcElkIiwib3B0aW9ucyIsInZhbGlkYXRlQWRhcHRlciIsInNob3VsZFZlcmlmeUVtYWlscyIsImV4cGVjdGVkQWRhcHRlclR5cGUiLCJNYWlsQWRhcHRlciIsInZlcmlmeVVzZXJFbWFpbHMiLCJzZXRFbWFpbFZlcmlmeVRva2VuIiwidXNlciIsIl9lbWFpbF92ZXJpZnlfdG9rZW4iLCJlbWFpbFZlcmlmaWVkIiwiY29uZmlnIiwiZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQiLCJQYXJzZSIsIl9lbmNvZGUiLCJnZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW5FeHBpcmVzQXQiLCJ2ZXJpZnlFbWFpbCIsInVzZXJuYW1lIiwidG9rZW4iLCJ1bmRlZmluZWQiLCJxdWVyeSIsInVwZGF0ZUZpZWxkcyIsIl9fb3AiLCIkZ3QiLCJEYXRlIiwibWFzdGVyQXV0aCIsIm1hc3RlciIsImZpbmRVc2VyRm9yRW1haWxWZXJpZmljYXRpb24iLCJleGVjdXRlIiwidGhlbiIsInJlc3VsdCIsInJlc3VsdHMiLCJsZW5ndGgiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm9iamVjdElkIiwicmVzdCIsInVwZGF0ZSIsImNoZWNrUmVzZXRUb2tlblZhbGlkaXR5IiwiZGF0YWJhc2UiLCJmaW5kIiwiX3BlcmlzaGFibGVfdG9rZW4iLCJsaW1pdCIsInBhc3N3b3JkUG9saWN5IiwicmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJleHBpcmVzRGF0ZSIsIl9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQiLCJfX3R5cGUiLCJpc28iLCJnZXRVc2VySWZOZWVkZWQiLCJlbWFpbCIsIndoZXJlIiwic2VuZFZlcmlmaWNhdGlvbkVtYWlsIiwiZW5jb2RlVVJJQ29tcG9uZW50IiwibGluayIsImJ1aWxkRW1haWxMaW5rIiwidmVyaWZ5RW1haWxVUkwiLCJhcHBOYW1lIiwic2VuZE1haWwiLCJkZWZhdWx0VmVyaWZpY2F0aW9uRW1haWwiLCJyZWdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbiIsImVtYWlsVmVyaWZ5VG9rZW5SZXVzZUlmVmFsaWQiLCJyZXNlbmRWZXJpZmljYXRpb25FbWFpbCIsImFVc2VyIiwic2V0UGFzc3dvcmRSZXNldFRva2VuIiwiZ2VuZXJhdGVQYXNzd29yZFJlc2V0VG9rZW5FeHBpcmVzQXQiLCIkb3IiLCIkZXhpc3RzIiwic2VuZFBhc3N3b3JkUmVzZXRFbWFpbCIsInJlc2V0VG9rZW5SZXVzZUlmVmFsaWQiLCJyZXF1ZXN0UmVzZXRQYXNzd29yZFVSTCIsImRlZmF1bHRSZXNldFBhc3N3b3JkRW1haWwiLCJ1cGRhdGVQYXNzd29yZCIsInBhc3N3b3JkIiwidXBkYXRlVXNlclBhc3N3b3JkIiwiYWNjb3VudExvY2tvdXRQb2xpY3kiLCJBY2NvdW50TG9ja291dCIsInVubG9ja0FjY291bnQiLCJjYXRjaCIsImVycm9yIiwibWVzc2FnZSIsInJlamVjdCIsInRleHQiLCJnZXQiLCJ0byIsInN1YmplY3QiLCJkZXN0aW5hdGlvbiIsInVzZXJuYW1lQW5kVG9rZW4iLCJwYXJzZUZyYW1lVVJMIiwiZGVzdGluYXRpb25XaXRob3V0SG9zdCIsInJlcGxhY2UiLCJwdWJsaWNTZXJ2ZXJVUkwiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUVBLElBQUlBLFNBQVMsR0FBR0MsT0FBTyxDQUFDLGNBQUQsQ0FBdkI7O0FBQ0EsSUFBSUMsSUFBSSxHQUFHRCxPQUFPLENBQUMsU0FBRCxDQUFsQjs7QUFFTyxNQUFNRSxjQUFOLFNBQTZCQyw0QkFBN0IsQ0FBaUQ7QUFDdERDLEVB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QUFEWixHQUxLLEVBUUw1QyxJQVJLLENBUUEsTUFBTXRCLElBUk4sQ0FBUDtBQVNEOztBQUVELFNBQVNnRCxjQUFULENBQXdCK0IsV0FBeEIsRUFBcUNyRSxRQUFyQyxFQUErQ0MsS0FBL0MsRUFBc0RSLE1BQXRELEVBQThEO0FBQzVELFFBQU02RSxnQkFBZ0IsR0FBSSxTQUFRckUsS0FBTSxhQUFZRCxRQUFTLEVBQTdEOztBQUVBLE1BQUlQLE1BQU0sQ0FBQzhFLGFBQVgsRUFBMEI7QUFDeEIsVUFBTUMsc0JBQXNCLEdBQUdILFdBQVcsQ0FBQ0ksT0FBWixDQUFvQmhGLE1BQU0sQ0FBQ2lGLGVBQTNCLEVBQTRDLEVBQTVDLENBQS9CO0FBRUEsV0FBUSxHQUFFakYsTUFBTSxDQUFDOEUsYUFBYyxTQUFRbkMsa0JBQWtCLENBQ3ZEb0Msc0JBRHVELENBRXZELElBQUdGLGdCQUFpQixFQUZ0QjtBQUdELEdBTkQsTUFNTztBQUNMLFdBQVEsR0FBRUQsV0FBWSxJQUFHQyxnQkFBaUIsRUFBMUM7QUFDRDtBQUNGOztlQUVjNUYsYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHJhbmRvbVN0cmluZyB9IGZyb20gJy4uL2NyeXB0b1V0aWxzJztcbmltcG9ydCB7IGluZmxhdGUgfSBmcm9tICcuLi90cmlnZ2Vycyc7XG5pbXBvcnQgQWRhcHRhYmxlQ29udHJvbGxlciBmcm9tICcuL0FkYXB0YWJsZUNvbnRyb2xsZXInO1xuaW1wb3J0IE1haWxBZGFwdGVyIGZyb20gJy4uL0FkYXB0ZXJzL0VtYWlsL01haWxBZGFwdGVyJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IEFjY291bnRMb2Nrb3V0IGZyb20gJy4uL0FjY291bnRMb2Nrb3V0JztcblxudmFyIFJlc3RRdWVyeSA9IHJlcXVpcmUoJy4uL1Jlc3RRdWVyeScpO1xudmFyIEF1dGggPSByZXF1aXJlKCcuLi9BdXRoJyk7XG5cbmV4cG9ydCBjbGFzcyBVc2VyQ29udHJvbGxlciBleHRlbmRzIEFkYXB0YWJsZUNvbnRyb2xsZXIge1xuICBjb25zdHJ1Y3RvcihhZGFwdGVyLCBhcHBJZCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgc3VwZXIoYWRhcHRlciwgYXBwSWQsIG9wdGlvbnMpO1xuICB9XG5cbiAgdmFsaWRhdGVBZGFwdGVyKGFkYXB0ZXIpIHtcbiAgICAvLyBBbGxvdyBubyBhZGFwdGVyXG4gICAgaWYgKCFhZGFwdGVyICYmICF0aGlzLnNob3VsZFZlcmlmeUVtYWlscykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzdXBlci52YWxpZGF0ZUFkYXB0ZXIoYWRhcHRlcik7XG4gIH1cblxuICBleHBlY3RlZEFkYXB0ZXJUeXBlKCkge1xuICAgIHJldHVybiBNYWlsQWRhcHRlcjtcbiAgfVxuXG4gIGdldCBzaG91bGRWZXJpZnlFbWFpbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy52ZXJpZnlVc2VyRW1haWxzO1xuICB9XG5cbiAgc2V0RW1haWxWZXJpZnlUb2tlbih1c2VyKSB7XG4gICAgaWYgKHRoaXMuc2hvdWxkVmVyaWZ5RW1haWxzKSB7XG4gICAgICB1c2VyLl9lbWFpbF92ZXJpZnlfdG9rZW4gPSByYW5kb21TdHJpbmcoMjUpO1xuICAgICAgdXNlci5lbWFpbFZlcmlmaWVkID0gZmFsc2U7XG5cbiAgICAgIGlmICh0aGlzLmNvbmZpZy5lbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbikge1xuICAgICAgICB1c2VyLl9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCA9IFBhcnNlLl9lbmNvZGUoXG4gICAgICAgICAgdGhpcy5jb25maWcuZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuRXhwaXJlc0F0KClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2ZXJpZnlFbWFpbCh1c2VybmFtZSwgdG9rZW4pIHtcbiAgICBpZiAoIXRoaXMuc2hvdWxkVmVyaWZ5RW1haWxzKSB7XG4gICAgICAvLyBUcnlpbmcgdG8gdmVyaWZ5IGVtYWlsIHdoZW4gbm90IGVuYWJsZWRcbiAgICAgIC8vIFRPRE86IEJldHRlciBlcnJvciBoZXJlLlxuICAgICAgdGhyb3cgdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IHF1ZXJ5ID0geyB1c2VybmFtZTogdXNlcm5hbWUsIF9lbWFpbF92ZXJpZnlfdG9rZW46IHRva2VuIH07XG4gICAgY29uc3QgdXBkYXRlRmllbGRzID0ge1xuICAgICAgZW1haWxWZXJpZmllZDogdHJ1ZSxcbiAgICAgIF9lbWFpbF92ZXJpZnlfdG9rZW46IHsgX19vcDogJ0RlbGV0ZScgfSxcbiAgICB9O1xuXG4gICAgLy8gaWYgdGhlIGVtYWlsIHZlcmlmeSB0b2tlbiBuZWVkcyB0byBiZSB2YWxpZGF0ZWQgdGhlblxuICAgIC8vIGFkZCBhZGRpdGlvbmFsIHF1ZXJ5IHBhcmFtcyBhbmQgYWRkaXRpb25hbCBmaWVsZHMgdGhhdCBuZWVkIHRvIGJlIHVwZGF0ZWRcbiAgICBpZiAodGhpcy5jb25maWcuZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24pIHtcbiAgICAgIHF1ZXJ5LmVtYWlsVmVyaWZpZWQgPSBmYWxzZTtcbiAgICAgIHF1ZXJ5Ll9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCA9IHsgJGd0OiBQYXJzZS5fZW5jb2RlKG5ldyBEYXRlKCkpIH07XG5cbiAgICAgIHVwZGF0ZUZpZWxkcy5fZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQgPSB7IF9fb3A6ICdEZWxldGUnIH07XG4gICAgfVxuICAgIGNvbnN0IG1hc3RlckF1dGggPSBBdXRoLm1hc3Rlcih0aGlzLmNvbmZpZyk7XG4gICAgdmFyIGZpbmRVc2VyRm9yRW1haWxWZXJpZmljYXRpb24gPSBuZXcgUmVzdFF1ZXJ5KFxuICAgICAgdGhpcy5jb25maWcsXG4gICAgICBBdXRoLm1hc3Rlcih0aGlzLmNvbmZpZyksXG4gICAgICAnX1VzZXInLFxuICAgICAgeyB1c2VybmFtZTogdXNlcm5hbWUgfVxuICAgICk7XG4gICAgcmV0dXJuIGZpbmRVc2VyRm9yRW1haWxWZXJpZmljYXRpb24uZXhlY3V0ZSgpLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgIGlmIChyZXN1bHQucmVzdWx0cy5sZW5ndGggJiYgcmVzdWx0LnJlc3VsdHNbMF0uZW1haWxWZXJpZmllZCkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3VsdC5yZXN1bHRzLmxlbmd0aFswXSk7XG4gICAgICB9IGVsc2UgaWYgKHJlc3VsdC5yZXN1bHRzLmxlbmd0aCkge1xuICAgICAgICBxdWVyeS5vYmplY3RJZCA9IHJlc3VsdC5yZXN1bHRzWzBdLm9iamVjdElkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3QudXBkYXRlKHRoaXMuY29uZmlnLCBtYXN0ZXJBdXRoLCAnX1VzZXInLCBxdWVyeSwgdXBkYXRlRmllbGRzKTtcbiAgICB9KTtcbiAgfVxuXG4gIGNoZWNrUmVzZXRUb2tlblZhbGlkaXR5KHVzZXJuYW1lLCB0b2tlbikge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgICAgLmZpbmQoXG4gICAgICAgICdfVXNlcicsXG4gICAgICAgIHtcbiAgICAgICAgICB1c2VybmFtZTogdXNlcm5hbWUsXG4gICAgICAgICAgX3BlcmlzaGFibGVfdG9rZW46IHRva2VuLFxuICAgICAgICB9LFxuICAgICAgICB7IGxpbWl0OiAxIH1cbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggIT0gMSkge1xuICAgICAgICAgIHRocm93ICdGYWlsZWQgdG8gcmVzZXQgcGFzc3dvcmQ6IHVzZXJuYW1lIC8gZW1haWwgLyB0b2tlbiBpcyBpbnZhbGlkJztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeSAmJiB0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbikge1xuICAgICAgICAgIGxldCBleHBpcmVzRGF0ZSA9IHJlc3VsdHNbMF0uX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdDtcbiAgICAgICAgICBpZiAoZXhwaXJlc0RhdGUgJiYgZXhwaXJlc0RhdGUuX190eXBlID09ICdEYXRlJykge1xuICAgICAgICAgICAgZXhwaXJlc0RhdGUgPSBuZXcgRGF0ZShleHBpcmVzRGF0ZS5pc28pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZXhwaXJlc0RhdGUgPCBuZXcgRGF0ZSgpKSB0aHJvdyAnVGhlIHBhc3N3b3JkIHJlc2V0IGxpbmsgaGFzIGV4cGlyZWQnO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRzWzBdO1xuICAgICAgfSk7XG4gIH1cblxuICBnZXRVc2VySWZOZWVkZWQodXNlcikge1xuICAgIGlmICh1c2VyLnVzZXJuYW1lICYmIHVzZXIuZW1haWwpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodXNlcik7XG4gICAgfVxuICAgIHZhciB3aGVyZSA9IHt9O1xuICAgIGlmICh1c2VyLnVzZXJuYW1lKSB7XG4gICAgICB3aGVyZS51c2VybmFtZSA9IHVzZXIudXNlcm5hbWU7XG4gICAgfVxuICAgIGlmICh1c2VyLmVtYWlsKSB7XG4gICAgICB3aGVyZS5lbWFpbCA9IHVzZXIuZW1haWw7XG4gICAgfVxuXG4gICAgdmFyIHF1ZXJ5ID0gbmV3IFJlc3RRdWVyeSh0aGlzLmNvbmZpZywgQXV0aC5tYXN0ZXIodGhpcy5jb25maWcpLCAnX1VzZXInLCB3aGVyZSk7XG4gICAgcmV0dXJuIHF1ZXJ5LmV4ZWN1dGUoKS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgIGlmIChyZXN1bHQucmVzdWx0cy5sZW5ndGggIT0gMSkge1xuICAgICAgICB0aHJvdyB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0LnJlc3VsdHNbMF07XG4gICAgfSk7XG4gIH1cblxuICBzZW5kVmVyaWZpY2F0aW9uRW1haWwodXNlcikge1xuICAgIGlmICghdGhpcy5zaG91bGRWZXJpZnlFbWFpbHMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgdG9rZW4gPSBlbmNvZGVVUklDb21wb25lbnQodXNlci5fZW1haWxfdmVyaWZ5X3Rva2VuKTtcbiAgICAvLyBXZSBtYXkgbmVlZCB0byBmZXRjaCB0aGUgdXNlciBpbiBjYXNlIG9mIHVwZGF0ZSBlbWFpbFxuICAgIHRoaXMuZ2V0VXNlcklmTmVlZGVkKHVzZXIpLnRoZW4odXNlciA9PiB7XG4gICAgICBjb25zdCB1c2VybmFtZSA9IGVuY29kZVVSSUNvbXBvbmVudCh1c2VyLnVzZXJuYW1lKTtcblxuICAgICAgY29uc3QgbGluayA9IGJ1aWxkRW1haWxMaW5rKHRoaXMuY29uZmlnLnZlcmlmeUVtYWlsVVJMLCB1c2VybmFtZSwgdG9rZW4sIHRoaXMuY29uZmlnKTtcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgIGFwcE5hbWU6IHRoaXMuY29uZmlnLmFwcE5hbWUsXG4gICAgICAgIGxpbms6IGxpbmssXG4gICAgICAgIHVzZXI6IGluZmxhdGUoJ19Vc2VyJywgdXNlciksXG4gICAgICB9O1xuICAgICAgaWYgKHRoaXMuYWRhcHRlci5zZW5kVmVyaWZpY2F0aW9uRW1haWwpIHtcbiAgICAgICAgdGhpcy5hZGFwdGVyLnNlbmRWZXJpZmljYXRpb25FbWFpbChvcHRpb25zKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYWRhcHRlci5zZW5kTWFpbCh0aGlzLmRlZmF1bHRWZXJpZmljYXRpb25FbWFpbChvcHRpb25zKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVnZW5lcmF0ZXMgdGhlIGdpdmVuIHVzZXIncyBlbWFpbCB2ZXJpZmljYXRpb24gdG9rZW5cbiAgICpcbiAgICogQHBhcmFtIHVzZXJcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICByZWdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbih1c2VyKSB7XG4gICAgY29uc3QgeyBfZW1haWxfdmVyaWZ5X3Rva2VuIH0gPSB1c2VyO1xuICAgIGxldCB7IF9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCB9ID0gdXNlcjtcbiAgICBpZiAoX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0ICYmIF9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdC5fX3R5cGUgPT09ICdEYXRlJykge1xuICAgICAgX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0ID0gX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0LmlzbztcbiAgICB9XG4gICAgaWYgKFxuICAgICAgdGhpcy5jb25maWcuZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZCAmJlxuICAgICAgdGhpcy5jb25maWcuZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24gJiZcbiAgICAgIF9lbWFpbF92ZXJpZnlfdG9rZW4gJiZcbiAgICAgIG5ldyBEYXRlKCkgPCBuZXcgRGF0ZShfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQpXG4gICAgKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIHRoaXMuc2V0RW1haWxWZXJpZnlUb2tlbih1c2VyKTtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UudXBkYXRlKCdfVXNlcicsIHsgdXNlcm5hbWU6IHVzZXIudXNlcm5hbWUgfSwgdXNlcik7XG4gIH1cblxuICByZXNlbmRWZXJpZmljYXRpb25FbWFpbCh1c2VybmFtZSkge1xuICAgIHJldHVybiB0aGlzLmdldFVzZXJJZk5lZWRlZCh7IHVzZXJuYW1lOiB1c2VybmFtZSB9KS50aGVuKGFVc2VyID0+IHtcbiAgICAgIGlmICghYVVzZXIgfHwgYVVzZXIuZW1haWxWZXJpZmllZCkge1xuICAgICAgICB0aHJvdyB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5yZWdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbihhVXNlcikudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMuc2VuZFZlcmlmaWNhdGlvbkVtYWlsKGFVc2VyKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgc2V0UGFzc3dvcmRSZXNldFRva2VuKGVtYWlsKSB7XG4gICAgY29uc3QgdG9rZW4gPSB7IF9wZXJpc2hhYmxlX3Rva2VuOiByYW5kb21TdHJpbmcoMjUpIH07XG5cbiAgICBpZiAodGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kgJiYgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24pIHtcbiAgICAgIHRva2VuLl9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQgPSBQYXJzZS5fZW5jb2RlKFxuICAgICAgICB0aGlzLmNvbmZpZy5nZW5lcmF0ZVBhc3N3b3JkUmVzZXRUb2tlbkV4cGlyZXNBdCgpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZS51cGRhdGUoXG4gICAgICAnX1VzZXInLFxuICAgICAgeyAkb3I6IFt7IGVtYWlsIH0sIHsgdXNlcm5hbWU6IGVtYWlsLCBlbWFpbDogeyAkZXhpc3RzOiBmYWxzZSB9IH1dIH0sXG4gICAgICB0b2tlbixcbiAgICAgIHt9LFxuICAgICAgdHJ1ZVxuICAgICk7XG4gIH1cblxuICBhc3luYyBzZW5kUGFzc3dvcmRSZXNldEVtYWlsKGVtYWlsKSB7XG4gICAgaWYgKCF0aGlzLmFkYXB0ZXIpIHtcbiAgICAgIHRocm93ICdUcnlpbmcgdG8gc2VuZCBhIHJlc2V0IHBhc3N3b3JkIGJ1dCBubyBhZGFwdGVyIGlzIHNldCc7XG4gICAgICAvLyAgVE9ETzogTm8gYWRhcHRlcj9cbiAgICB9XG4gICAgbGV0IHVzZXI7XG4gICAgaWYgKFxuICAgICAgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kgJiZcbiAgICAgIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5SZXVzZUlmVmFsaWQgJiZcbiAgICAgIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uXG4gICAgKSB7XG4gICAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5jb25maWcuZGF0YWJhc2UuZmluZChcbiAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAge1xuICAgICAgICAgICRvcjogW1xuICAgICAgICAgICAgeyBlbWFpbCwgX3BlcmlzaGFibGVfdG9rZW46IHsgJGV4aXN0czogdHJ1ZSB9IH0sXG4gICAgICAgICAgICB7IHVzZXJuYW1lOiBlbWFpbCwgZW1haWw6IHsgJGV4aXN0czogZmFsc2UgfSwgX3BlcmlzaGFibGVfdG9rZW46IHsgJGV4aXN0czogdHJ1ZSB9IH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgeyBsaW1pdDogMSB9XG4gICAgICApO1xuICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID09IDEpIHtcbiAgICAgICAgbGV0IGV4cGlyZXNEYXRlID0gcmVzdWx0c1swXS5fcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0O1xuICAgICAgICBpZiAoZXhwaXJlc0RhdGUgJiYgZXhwaXJlc0RhdGUuX190eXBlID09ICdEYXRlJykge1xuICAgICAgICAgIGV4cGlyZXNEYXRlID0gbmV3IERhdGUoZXhwaXJlc0RhdGUuaXNvKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXhwaXJlc0RhdGUgPiBuZXcgRGF0ZSgpKSB7XG4gICAgICAgICAgdXNlciA9IHJlc3VsdHNbMF07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCF1c2VyIHx8ICF1c2VyLl9wZXJpc2hhYmxlX3Rva2VuKSB7XG4gICAgICB1c2VyID0gYXdhaXQgdGhpcy5zZXRQYXNzd29yZFJlc2V0VG9rZW4oZW1haWwpO1xuICAgIH1cbiAgICBjb25zdCB0b2tlbiA9IGVuY29kZVVSSUNvbXBvbmVudCh1c2VyLl9wZXJpc2hhYmxlX3Rva2VuKTtcbiAgICBjb25zdCB1c2VybmFtZSA9IGVuY29kZVVSSUNvbXBvbmVudCh1c2VyLnVzZXJuYW1lKTtcblxuICAgIGNvbnN0IGxpbmsgPSBidWlsZEVtYWlsTGluayh0aGlzLmNvbmZpZy5yZXF1ZXN0UmVzZXRQYXNzd29yZFVSTCwgdXNlcm5hbWUsIHRva2VuLCB0aGlzLmNvbmZpZyk7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgIGFwcE5hbWU6IHRoaXMuY29uZmlnLmFwcE5hbWUsXG4gICAgICBsaW5rOiBsaW5rLFxuICAgICAgdXNlcjogaW5mbGF0ZSgnX1VzZXInLCB1c2VyKSxcbiAgICB9O1xuXG4gICAgaWYgKHRoaXMuYWRhcHRlci5zZW5kUGFzc3dvcmRSZXNldEVtYWlsKSB7XG4gICAgICB0aGlzLmFkYXB0ZXIuc2VuZFBhc3N3b3JkUmVzZXRFbWFpbChvcHRpb25zKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hZGFwdGVyLnNlbmRNYWlsKHRoaXMuZGVmYXVsdFJlc2V0UGFzc3dvcmRFbWFpbChvcHRpb25zKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh1c2VyKTtcbiAgfVxuXG4gIHVwZGF0ZVBhc3N3b3JkKHVzZXJuYW1lLCB0b2tlbiwgcGFzc3dvcmQpIHtcbiAgICByZXR1cm4gdGhpcy5jaGVja1Jlc2V0VG9rZW5WYWxpZGl0eSh1c2VybmFtZSwgdG9rZW4pXG4gICAgICAudGhlbih1c2VyID0+IHVwZGF0ZVVzZXJQYXNzd29yZCh1c2VyLCBwYXNzd29yZCwgdGhpcy5jb25maWcpKVxuICAgICAgLnRoZW4odXNlciA9PiB7XG4gICAgICAgIGNvbnN0IGFjY291bnRMb2Nrb3V0UG9saWN5ID0gbmV3IEFjY291bnRMb2Nrb3V0KHVzZXIsIHRoaXMuY29uZmlnKTtcbiAgICAgICAgcmV0dXJuIGFjY291bnRMb2Nrb3V0UG9saWN5LnVubG9ja0FjY291bnQoKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgJiYgZXJyb3IubWVzc2FnZSkge1xuICAgICAgICAgIC8vIGluIGNhc2Ugb2YgUGFyc2UuRXJyb3IsIGZhaWwgd2l0aCB0aGUgZXJyb3IgbWVzc2FnZSBvbmx5XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycm9yLm1lc3NhZ2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgZGVmYXVsdFZlcmlmaWNhdGlvbkVtYWlsKHsgbGluaywgdXNlciwgYXBwTmFtZSB9KSB7XG4gICAgY29uc3QgdGV4dCA9XG4gICAgICAnSGksXFxuXFxuJyArXG4gICAgICAnWW91IGFyZSBiZWluZyBhc2tlZCB0byBjb25maXJtIHRoZSBlLW1haWwgYWRkcmVzcyAnICtcbiAgICAgIHVzZXIuZ2V0KCdlbWFpbCcpICtcbiAgICAgICcgd2l0aCAnICtcbiAgICAgIGFwcE5hbWUgK1xuICAgICAgJ1xcblxcbicgK1xuICAgICAgJycgK1xuICAgICAgJ0NsaWNrIGhlcmUgdG8gY29uZmlybSBpdDpcXG4nICtcbiAgICAgIGxpbms7XG4gICAgY29uc3QgdG8gPSB1c2VyLmdldCgnZW1haWwnKTtcbiAgICBjb25zdCBzdWJqZWN0ID0gJ1BsZWFzZSB2ZXJpZnkgeW91ciBlLW1haWwgZm9yICcgKyBhcHBOYW1lO1xuICAgIHJldHVybiB7IHRleHQsIHRvLCBzdWJqZWN0IH07XG4gIH1cblxuICBkZWZhdWx0UmVzZXRQYXNzd29yZEVtYWlsKHsgbGluaywgdXNlciwgYXBwTmFtZSB9KSB7XG4gICAgY29uc3QgdGV4dCA9XG4gICAgICAnSGksXFxuXFxuJyArXG4gICAgICAnWW91IHJlcXVlc3RlZCB0byByZXNldCB5b3VyIHBhc3N3b3JkIGZvciAnICtcbiAgICAgIGFwcE5hbWUgK1xuICAgICAgKHVzZXIuZ2V0KCd1c2VybmFtZScpID8gXCIgKHlvdXIgdXNlcm5hbWUgaXMgJ1wiICsgdXNlci5nZXQoJ3VzZXJuYW1lJykgKyBcIicpXCIgOiAnJykgK1xuICAgICAgJy5cXG5cXG4nICtcbiAgICAgICcnICtcbiAgICAgICdDbGljayBoZXJlIHRvIHJlc2V0IGl0OlxcbicgK1xuICAgICAgbGluaztcbiAgICBjb25zdCB0byA9IHVzZXIuZ2V0KCdlbWFpbCcpIHx8IHVzZXIuZ2V0KCd1c2VybmFtZScpO1xuICAgIGNvbnN0IHN1YmplY3QgPSAnUGFzc3dvcmQgUmVzZXQgZm9yICcgKyBhcHBOYW1lO1xuICAgIHJldHVybiB7IHRleHQsIHRvLCBzdWJqZWN0IH07XG4gIH1cbn1cblxuLy8gTWFyayB0aGlzIHByaXZhdGVcbmZ1bmN0aW9uIHVwZGF0ZVVzZXJQYXNzd29yZCh1c2VyLCBwYXNzd29yZCwgY29uZmlnKSB7XG4gIHJldHVybiByZXN0LnVwZGF0ZShcbiAgICBjb25maWcsXG4gICAgQXV0aC5tYXN0ZXIoY29uZmlnKSxcbiAgICAnX1VzZXInLFxuICAgIHsgb2JqZWN0SWQ6IHVzZXIub2JqZWN0SWQgfSxcbiAgICB7XG4gICAgICBwYXNzd29yZDogcGFzc3dvcmQsXG4gICAgfVxuICApLnRoZW4oKCkgPT4gdXNlcik7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkRW1haWxMaW5rKGRlc3RpbmF0aW9uLCB1c2VybmFtZSwgdG9rZW4sIGNvbmZpZykge1xuICBjb25zdCB1c2VybmFtZUFuZFRva2VuID0gYHRva2VuPSR7dG9rZW59JnVzZXJuYW1lPSR7dXNlcm5hbWV9YDtcblxuICBpZiAoY29uZmlnLnBhcnNlRnJhbWVVUkwpIHtcbiAgICBjb25zdCBkZXN0aW5hdGlvbldpdGhvdXRIb3N0ID0gZGVzdGluYXRpb24ucmVwbGFjZShjb25maWcucHVibGljU2VydmVyVVJMLCAnJyk7XG5cbiAgICByZXR1cm4gYCR7Y29uZmlnLnBhcnNlRnJhbWVVUkx9P2xpbms9JHtlbmNvZGVVUklDb21wb25lbnQoXG4gICAgICBkZXN0aW5hdGlvbldpdGhvdXRIb3N0XG4gICAgKX0mJHt1c2VybmFtZUFuZFRva2VufWA7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGAke2Rlc3RpbmF0aW9ufT8ke3VzZXJuYW1lQW5kVG9rZW59YDtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBVc2VyQ29udHJvbGxlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/index.js b/lib/Controllers/index.js new file mode 100644 index 0000000000..e3ace5883c --- /dev/null +++ b/lib/Controllers/index.js @@ -0,0 +1,312 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getControllers = getControllers; +exports.getLoggerController = getLoggerController; +exports.getFilesController = getFilesController; +exports.getUserController = getUserController; +exports.getCacheController = getCacheController; +exports.getParseGraphQLController = getParseGraphQLController; +exports.getAnalyticsController = getAnalyticsController; +exports.getLiveQueryController = getLiveQueryController; +exports.getDatabaseController = getDatabaseController; +exports.getHooksController = getHooksController; +exports.getPushController = getPushController; +exports.getAuthDataManager = getAuthDataManager; +exports.getDatabaseAdapter = getDatabaseAdapter; + +var _Auth = _interopRequireDefault(require("../Adapters/Auth")); + +var _Options = require("../Options"); + +var _AdapterLoader = require("../Adapters/AdapterLoader"); + +var _defaults = _interopRequireDefault(require("../defaults")); + +var _url = _interopRequireDefault(require("url")); + +var _LoggerController = require("./LoggerController"); + +var _FilesController = require("./FilesController"); + +var _HooksController = require("./HooksController"); + +var _UserController = require("./UserController"); + +var _CacheController = require("./CacheController"); + +var _LiveQueryController = require("./LiveQueryController"); + +var _AnalyticsController = require("./AnalyticsController"); + +var _PushController = require("./PushController"); + +var _PushQueue = require("../Push/PushQueue"); + +var _PushWorker = require("../Push/PushWorker"); + +var _DatabaseController = _interopRequireDefault(require("./DatabaseController")); + +var _SchemaCache = _interopRequireDefault(require("./SchemaCache")); + +var _GridFSBucketAdapter = require("../Adapters/Files/GridFSBucketAdapter"); + +var _WinstonLoggerAdapter = require("../Adapters/Logger/WinstonLoggerAdapter"); + +var _InMemoryCacheAdapter = require("../Adapters/Cache/InMemoryCacheAdapter"); + +var _AnalyticsAdapter = require("../Adapters/Analytics/AnalyticsAdapter"); + +var _MongoStorageAdapter = _interopRequireDefault(require("../Adapters/Storage/Mongo/MongoStorageAdapter")); + +var _PostgresStorageAdapter = _interopRequireDefault(require("../Adapters/Storage/Postgres/PostgresStorageAdapter")); + +var _pushAdapter = _interopRequireDefault(require("@parse/push-adapter")); + +var _ParseGraphQLController = _interopRequireDefault(require("./ParseGraphQLController")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function getControllers(options) { + const loggerController = getLoggerController(options); + const filesController = getFilesController(options); + const userController = getUserController(options); + const { + pushController, + hasPushScheduledSupport, + hasPushSupport, + pushControllerQueue, + pushWorker + } = getPushController(options); + const cacheController = getCacheController(options); + const analyticsController = getAnalyticsController(options); + const liveQueryController = getLiveQueryController(options); + const databaseController = getDatabaseController(options, cacheController); + const hooksController = getHooksController(options, databaseController); + const authDataManager = getAuthDataManager(options); + const parseGraphQLController = getParseGraphQLController(options, { + databaseController, + cacheController + }); + return { + loggerController, + filesController, + userController, + pushController, + hasPushScheduledSupport, + hasPushSupport, + pushWorker, + pushControllerQueue, + analyticsController, + cacheController, + parseGraphQLController, + liveQueryController, + databaseController, + hooksController, + authDataManager + }; +} + +function getLoggerController(options) { + const { + appId, + jsonLogs, + logsFolder, + verbose, + logLevel, + maxLogFiles, + silent, + loggerAdapter + } = options; + const loggerOptions = { + jsonLogs, + logsFolder, + verbose, + logLevel, + silent, + maxLogFiles + }; + const loggerControllerAdapter = (0, _AdapterLoader.loadAdapter)(loggerAdapter, _WinstonLoggerAdapter.WinstonLoggerAdapter, loggerOptions); + return new _LoggerController.LoggerController(loggerControllerAdapter, appId, loggerOptions); +} + +function getFilesController(options) { + const { + appId, + databaseURI, + filesAdapter, + databaseAdapter, + preserveFileName, + fileKey + } = options; + + if (!filesAdapter && databaseAdapter) { + throw 'When using an explicit database adapter, you must also use an explicit filesAdapter.'; + } + + const filesControllerAdapter = (0, _AdapterLoader.loadAdapter)(filesAdapter, () => { + return new _GridFSBucketAdapter.GridFSBucketAdapter(databaseURI, {}, fileKey); + }); + return new _FilesController.FilesController(filesControllerAdapter, appId, { + preserveFileName + }); +} + +function getUserController(options) { + const { + appId, + emailAdapter, + verifyUserEmails + } = options; + const emailControllerAdapter = (0, _AdapterLoader.loadAdapter)(emailAdapter); + return new _UserController.UserController(emailControllerAdapter, appId, { + verifyUserEmails + }); +} + +function getCacheController(options) { + const { + appId, + cacheAdapter, + cacheTTL, + cacheMaxSize + } = options; + const cacheControllerAdapter = (0, _AdapterLoader.loadAdapter)(cacheAdapter, _InMemoryCacheAdapter.InMemoryCacheAdapter, { + appId: appId, + ttl: cacheTTL, + maxSize: cacheMaxSize + }); + return new _CacheController.CacheController(cacheControllerAdapter, appId); +} + +function getParseGraphQLController(options, controllerDeps) { + return new _ParseGraphQLController.default(_objectSpread({ + mountGraphQL: options.mountGraphQL + }, controllerDeps)); +} + +function getAnalyticsController(options) { + const { + analyticsAdapter + } = options; + const analyticsControllerAdapter = (0, _AdapterLoader.loadAdapter)(analyticsAdapter, _AnalyticsAdapter.AnalyticsAdapter); + return new _AnalyticsController.AnalyticsController(analyticsControllerAdapter); +} + +function getLiveQueryController(options) { + return new _LiveQueryController.LiveQueryController(options.liveQuery); +} + +function getDatabaseController(options, cacheController) { + const { + databaseURI, + databaseOptions, + collectionPrefix, + schemaCacheTTL, + enableSingleSchemaCache + } = options; + let { + databaseAdapter + } = options; + + if ((databaseOptions || databaseURI && databaseURI !== _defaults.default.databaseURI || collectionPrefix !== _defaults.default.collectionPrefix) && databaseAdapter) { + throw 'You cannot specify both a databaseAdapter and a databaseURI/databaseOptions/collectionPrefix.'; + } else if (!databaseAdapter) { + databaseAdapter = getDatabaseAdapter(databaseURI, collectionPrefix, databaseOptions); + } else { + databaseAdapter = (0, _AdapterLoader.loadAdapter)(databaseAdapter); + } + + return new _DatabaseController.default(databaseAdapter, new _SchemaCache.default(cacheController, schemaCacheTTL, enableSingleSchemaCache)); +} + +function getHooksController(options, databaseController) { + const { + appId, + webhookKey + } = options; + return new _HooksController.HooksController(appId, databaseController, webhookKey); +} + +function getPushController(options) { + const { + scheduledPush, + push + } = options; + const pushOptions = Object.assign({}, push); + const pushQueueOptions = pushOptions.queueOptions || {}; + + if (pushOptions.queueOptions) { + delete pushOptions.queueOptions; + } // Pass the push options too as it works with the default + + + const pushAdapter = (0, _AdapterLoader.loadAdapter)(pushOptions && pushOptions.adapter, _pushAdapter.default, pushOptions); // We pass the options and the base class for the adatper, + // Note that passing an instance would work too + + const pushController = new _PushController.PushController(); + const hasPushSupport = !!(pushAdapter && push); + const hasPushScheduledSupport = hasPushSupport && scheduledPush === true; + const { + disablePushWorker + } = pushQueueOptions; + const pushControllerQueue = new _PushQueue.PushQueue(pushQueueOptions); + let pushWorker; + + if (!disablePushWorker) { + pushWorker = new _PushWorker.PushWorker(pushAdapter, pushQueueOptions); + } + + return { + pushController, + hasPushSupport, + hasPushScheduledSupport, + pushControllerQueue, + pushWorker + }; +} + +function getAuthDataManager(options) { + const { + auth, + enableAnonymousUsers + } = options; + return (0, _Auth.default)(auth, enableAnonymousUsers); +} + +function getDatabaseAdapter(databaseURI, collectionPrefix, databaseOptions) { + let protocol; + + try { + const parsedURI = _url.default.parse(databaseURI); + + protocol = parsedURI.protocol ? parsedURI.protocol.toLowerCase() : null; + } catch (e) { + /* */ + } + + switch (protocol) { + case 'postgres:': + return new _PostgresStorageAdapter.default({ + uri: databaseURI, + collectionPrefix, + databaseOptions + }); + + default: + return new _MongoStorageAdapter.default({ + uri: databaseURI, + collectionPrefix, + mongoOptions: databaseOptions + }); + } +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9pbmRleC5qcyJdLCJuYW1lcyI6WyJnZXRDb250cm9sbGVycyIsIm9wdGlvbnMiLCJsb2dnZXJDb250cm9sbGVyIiwiZ2V0TG9nZ2VyQ29udHJvbGxlciIsImZpbGVzQ29udHJvbGxlciIsImdldEZpbGVzQ29udHJvbGxlciIsInVzZXJDb250cm9sbGVyIiwiZ2V0VXNlckNvbnRyb2xsZXIiLCJwdXNoQ29udHJvbGxlciIsImhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0IiwiaGFzUHVzaFN1cHBvcnQiLCJwdXNoQ29udHJvbGxlclF1ZXVlIiwicHVzaFdvcmtlciIsImdldFB1c2hDb250cm9sbGVyIiwiY2FjaGVDb250cm9sbGVyIiwiZ2V0Q2FjaGVDb250cm9sbGVyIiwiYW5hbHl0aWNzQ29udHJvbGxlciIsImdldEFuYWx5dGljc0NvbnRyb2xsZXIiLCJsaXZlUXVlcnlDb250cm9sbGVyIiwiZ2V0TGl2ZVF1ZXJ5Q29udHJvbGxlciIsImRhdGFiYXNlQ29udHJvbGxlciIsImdldERhdGFiYXNlQ29udHJvbGxlciIsImhvb2tzQ29udHJvbGxlciIsImdldEhvb2tzQ29udHJvbGxlciIsImF1dGhEYXRhTWFuYWdlciIsImdldEF1dGhEYXRhTWFuYWdlciIsInBhcnNlR3JhcGhRTENvbnRyb2xsZXIiLCJnZXRQYXJzZUdyYXBoUUxDb250cm9sbGVyIiwiYXBwSWQiLCJqc29uTG9ncyIsImxvZ3NGb2xkZXIiLCJ2ZXJib3NlIiwibG9nTGV2ZWwiLCJtYXhMb2dGaWxlcyIsInNpbGVudCIsImxvZ2dlckFkYXB0ZXIiLCJsb2dnZXJPcHRpb25zIiwibG9nZ2VyQ29udHJvbGxlckFkYXB0ZXIiLCJXaW5zdG9uTG9nZ2VyQWRhcHRlciIsIkxvZ2dlckNvbnRyb2xsZXIiLCJkYXRhYmFzZVVSSSIsImZpbGVzQWRhcHRlciIsImRhdGFiYXNlQWRhcHRlciIsInByZXNlcnZlRmlsZU5hbWUiLCJmaWxlS2V5IiwiZmlsZXNDb250cm9sbGVyQWRhcHRlciIsIkdyaWRGU0J1Y2tldEFkYXB0ZXIiLCJGaWxlc0NvbnRyb2xsZXIiLCJlbWFpbEFkYXB0ZXIiLCJ2ZXJpZnlVc2VyRW1haWxzIiwiZW1haWxDb250cm9sbGVyQWRhcHRlciIsIlVzZXJDb250cm9sbGVyIiwiY2FjaGVBZGFwdGVyIiwiY2FjaGVUVEwiLCJjYWNoZU1heFNpemUiLCJjYWNoZUNvbnRyb2xsZXJBZGFwdGVyIiwiSW5NZW1vcnlDYWNoZUFkYXB0ZXIiLCJ0dGwiLCJtYXhTaXplIiwiQ2FjaGVDb250cm9sbGVyIiwiY29udHJvbGxlckRlcHMiLCJQYXJzZUdyYXBoUUxDb250cm9sbGVyIiwibW91bnRHcmFwaFFMIiwiYW5hbHl0aWNzQWRhcHRlciIsImFuYWx5dGljc0NvbnRyb2xsZXJBZGFwdGVyIiwiQW5hbHl0aWNzQWRhcHRlciIsIkFuYWx5dGljc0NvbnRyb2xsZXIiLCJMaXZlUXVlcnlDb250cm9sbGVyIiwibGl2ZVF1ZXJ5IiwiZGF0YWJhc2VPcHRpb25zIiwiY29sbGVjdGlvblByZWZpeCIsInNjaGVtYUNhY2hlVFRMIiwiZW5hYmxlU2luZ2xlU2NoZW1hQ2FjaGUiLCJkZWZhdWx0cyIsImdldERhdGFiYXNlQWRhcHRlciIsIkRhdGFiYXNlQ29udHJvbGxlciIsIlNjaGVtYUNhY2hlIiwid2ViaG9va0tleSIsIkhvb2tzQ29udHJvbGxlciIsInNjaGVkdWxlZFB1c2giLCJwdXNoIiwicHVzaE9wdGlvbnMiLCJPYmplY3QiLCJhc3NpZ24iLCJwdXNoUXVldWVPcHRpb25zIiwicXVldWVPcHRpb25zIiwicHVzaEFkYXB0ZXIiLCJhZGFwdGVyIiwiUGFyc2VQdXNoQWRhcHRlciIsIlB1c2hDb250cm9sbGVyIiwiZGlzYWJsZVB1c2hXb3JrZXIiLCJQdXNoUXVldWUiLCJQdXNoV29ya2VyIiwiYXV0aCIsImVuYWJsZUFub255bW91c1VzZXJzIiwicHJvdG9jb2wiLCJwYXJzZWRVUkkiLCJ1cmwiLCJwYXJzZSIsInRvTG93ZXJDYXNlIiwiZSIsIlBvc3RncmVzU3Rv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QUEsR0FBRyxFQUFFOUQsV0FEMkI7QUFFaEM4QixRQUFBQSxnQkFGZ0M7QUFHaENELFFBQUFBO0FBSGdDLE9BQTNCLENBQVA7O0FBS0Y7QUFDRSxhQUFPLElBQUlrQyw0QkFBSixDQUF3QjtBQUM3QkQsUUFBQUEsR0FBRyxFQUFFOUQsV0FEd0I7QUFFN0I4QixRQUFBQSxnQkFGNkI7QUFHN0JrQyxRQUFBQSxZQUFZLEVBQUVuQztBQUhlLE9BQXhCLENBQVA7QUFSSjtBQWNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGF1dGhEYXRhTWFuYWdlciBmcm9tICcuLi9BZGFwdGVycy9BdXRoJztcbmltcG9ydCB7IFBhcnNlU2VydmVyT3B0aW9ucyB9IGZyb20gJy4uL09wdGlvbnMnO1xuaW1wb3J0IHsgbG9hZEFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9BZGFwdGVyTG9hZGVyJztcbmltcG9ydCBkZWZhdWx0cyBmcm9tICcuLi9kZWZhdWx0cyc7XG5pbXBvcnQgdXJsIGZyb20gJ3VybCc7XG4vLyBDb250cm9sbGVyc1xuaW1wb3J0IHsgTG9nZ2VyQ29udHJvbGxlciB9IGZyb20gJy4vTG9nZ2VyQ29udHJvbGxlcic7XG5pbXBvcnQgeyBGaWxlc0NvbnRyb2xsZXIgfSBmcm9tICcuL0ZpbGVzQ29udHJvbGxlcic7XG5pbXBvcnQgeyBIb29rc0NvbnRyb2xsZXIgfSBmcm9tICcuL0hvb2tzQ29udHJvbGxlcic7XG5pbXBvcnQgeyBVc2VyQ29udHJvbGxlciB9IGZyb20gJy4vVXNlckNvbnRyb2xsZXInO1xuaW1wb3J0IHsgQ2FjaGVDb250cm9sbGVyIH0gZnJvbSAnLi9DYWNoZUNvbnRyb2xsZXInO1xuaW1wb3J0IHsgTGl2ZVF1ZXJ5Q29udHJvbGxlciB9IGZyb20gJy4vTGl2ZVF1ZXJ5Q29udHJvbGxlcic7XG5pbXBvcnQgeyBBbmFseXRpY3NDb250cm9sbGVyIH0gZnJvbSAnLi9BbmFseXRpY3NDb250cm9sbGVyJztcbmltcG9ydCB7IFB1c2hDb250cm9sbGVyIH0gZnJvbSAnLi9QdXNoQ29udHJvbGxlcic7XG5pbXBvcnQgeyBQdXNoUXVldWUgfSBmcm9tICcuLi9QdXNoL1B1c2hRdWV1ZSc7XG5pbXBvcnQgeyBQdXNoV29ya2VyIH0gZnJvbSAnLi4vUHVzaC9QdXNoV29ya2VyJztcbmltcG9ydCBEYXRhYmFzZUNvbnRyb2xsZXIgZnJvbSAnLi9EYXRhYmFzZUNvbnRyb2xsZXInO1xuaW1wb3J0IFNjaGVtYUNhY2hlIGZyb20gJy4vU2NoZW1hQ2FjaGUnO1xuXG4vLyBBZGFwdGVyc1xuaW1wb3J0IHsgR3JpZEZTQnVja2V0QWRhcHRlciB9IGZyb20gJy4uL0FkYXB0ZXJzL0ZpbGVzL0dyaWRGU0J1Y2tldEFkYXB0ZXInO1xuaW1wb3J0IHsgV2luc3RvbkxvZ2dlckFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9Mb2dnZXIvV2luc3RvbkxvZ2dlckFkYXB0ZXInO1xuaW1wb3J0IHsgSW5NZW1vcnlDYWNoZUFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9DYWNoZS9Jbk1lbW9yeUNhY2hlQWRhcHRlcic7XG5pbXBvcnQgeyBBbmFseXRpY3NBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvQW5hbHl0aWNzL0FuYWx5dGljc0FkYXB0ZXInO1xuaW1wb3J0IE1vbmdvU3RvcmFnZUFkYXB0ZXIgZnJvbSAnLi4vQWRhcHRlcnMvU3RvcmFnZS9Nb25nby9Nb25nb1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCBQb3N0Z3Jlc1N0b3JhZ2VBZGFwdGVyIGZyb20gJy4uL0FkYXB0ZXJzL1N0b3JhZ2UvUG9zdGdyZXMvUG9zdGdyZXNTdG9yYWdlQWRhcHRlcic7XG5pbXBvcnQgUGFyc2VQdXNoQWRhcHRlciBmcm9tICdAcGFyc2UvcHVzaC1hZGFwdGVyJztcbmltcG9ydCBQYXJzZUdyYXBoUUxDb250cm9sbGVyIGZyb20gJy4vUGFyc2VHcmFwaFFMQ29udHJvbGxlcic7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb250cm9sbGVycyhvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMpIHtcbiAgY29uc3QgbG9nZ2VyQ29udHJvbGxlciA9IGdldExvZ2dlckNvbnRyb2xsZXIob3B0aW9ucyk7XG4gIGNvbnN0IGZpbGVzQ29udHJvbGxlciA9IGdldEZpbGVzQ29udHJvbGxlcihvcHRpb25zKTtcbiAgY29uc3QgdXNlckNvbnRyb2xsZXIgPSBnZXRVc2VyQ29udHJvbGxlcihvcHRpb25zKTtcbiAgY29uc3Qge1xuICAgIHB1c2hDb250cm9sbGVyLFxuICAgIGhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0LFxuICAgIGhhc1B1c2hTdXBwb3J0LFxuICAgIHB1c2hDb250cm9sbGVyUXVldWUsXG4gICAgcHVzaFdvcmtlcixcbiAgfSA9IGdldFB1c2hDb250cm9sbGVyKG9wdGlvbnMpO1xuICBjb25zdCBjYWNoZUNvbnRyb2xsZXIgPSBnZXRDYWNoZUNvbnRyb2xsZXIob3B0aW9ucyk7XG4gIGNvbnN0IGFuYWx5dGljc0NvbnRyb2xsZXIgPSBnZXRBbmFseXRpY3NDb250cm9sbGVyKG9wdGlvbnMpO1xuICBjb25zdCBsaXZlUXVlcnlDb250cm9sbGVyID0gZ2V0TGl2ZVF1ZXJ5Q29udHJvbGxlcihvcHRpb25zKTtcbiAgY29uc3QgZGF0YWJhc2VDb250cm9sbGVyID0gZ2V0RGF0YWJhc2VDb250cm9sbGVyKG9wdGlvbnMsIGNhY2hlQ29udHJvbGxlcik7XG4gIGNvbnN0IGhvb2tzQ29udHJvbGxlciA9IGdldEhvb2tzQ29udHJvbGxlcihvcHRpb25zLCBkYXRhYmFzZUNvbnRyb2xsZXIpO1xuICBjb25zdCBhdXRoRGF0YU1hbmFnZXIgPSBnZXRBdXRoRGF0YU1hbmFnZXIob3B0aW9ucyk7XG4gIGNvbnN0IHBhcnNlR3JhcGhRTENvbnRyb2xsZXIgPSBnZXRQYXJzZUdyYXBoUUxDb250cm9sbGVyKG9wdGlvbnMsIHtcbiAgICBkYXRhYmFzZUNvbnRyb2xsZXIsXG4gICAgY2FjaGVDb250cm9sbGVyLFxuICB9KTtcbiAgcmV0dXJuIHtcbiAgICBsb2dnZXJDb250cm9sbGVyLFxuICAgIGZpbGVzQ29udHJvbGxlcixcbiAgICB1c2VyQ29udHJvbGxlcixcbiAgICBwdXNoQ29udHJvbGxlcixcbiAgICBoYXNQdXNoU2NoZWR1bGVkU3VwcG9ydCxcbiAgICBoYXNQdXNoU3VwcG9ydCxcbiAgICBwdXNoV29ya2VyLFxuICAgIHB1c2hDb250cm9sbGVyUXVldWUsXG4gICAgYW5hbHl0aWNzQ29udHJvbGxlcixcbiAgICBjYWNoZUNvbnRyb2xsZXIsXG4gICAgcGFyc2VHcmFwaFFMQ29udHJvbGxlcixcbiAgICBsaXZlUXVlcnlDb250cm9sbGVyLFxuICAgIGRhdGFiYXNlQ29udHJvbGxlcixcbiAgICBob29rc0NvbnRyb2xsZXIsXG4gICAgYXV0aERhdGFNYW5hZ2VyLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TG9nZ2VyQ29udHJvbGxlcihvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMpOiBMb2dnZXJDb250cm9sbGVyIHtcbiAgY29uc3Qge1xuICAgIGFwcElkLFxuICAgIGpzb25Mb2dzLFxuICAgIGxvZ3NGb2xkZXIsXG4gICAgdmVyYm9zZSxcbiAgICBsb2dMZXZlbCxcbiAgICBtYXhMb2dGaWxlcyxcbiAgICBzaWxlbnQsXG4gICAgbG9nZ2VyQWRhcHRlcixcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGxvZ2dlck9wdGlvbnMgPSB7XG4gICAganNvbkxvZ3MsXG4gICAgbG9nc0ZvbGRlcixcbiAgICB2ZXJib3NlLFxuICAgIGxvZ0xldmVsLFxuICAgIHNpbGVudCxcbiAgICBtYXhMb2dGaWxlcyxcbiAgfTtcbiAgY29uc3QgbG9nZ2VyQ29udHJvbGxlckFkYXB0ZXIgPSBsb2FkQWRhcHRlcihsb2dnZXJBZGFwdGVyLCBXaW5zdG9uTG9nZ2VyQWRhcHRlciwgbG9nZ2VyT3B0aW9ucyk7XG4gIHJldHVybiBuZXcgTG9nZ2VyQ29udHJvbGxlcihsb2dnZXJDb250cm9sbGVyQWRhcHRlciwgYXBwSWQsIGxvZ2dlck9wdGlvbnMpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmlsZXNDb250cm9sbGVyKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucyk6IEZpbGVzQ29udHJvbGxlciB7XG4gIGNvbnN0IHsgYXBwSWQsIGRhdGFiYXNlVVJJLCBmaWxlc0FkYXB0ZXIsIGRhdGFiYXNlQWRhcHRlciwgcHJlc2VydmVGaWxlTmFtZSwgZmlsZUtleSB9ID0gb3B0aW9ucztcbiAgaWYgKCFmaWxlc0FkYXB0ZXIgJiYgZGF0YWJhc2VBZGFwdGVyKSB7XG4gICAgdGhyb3cgJ1doZW4gdXNpbmcgYW4gZXhwbGljaXQgZGF0YWJhc2UgYWRhcHRlciwgeW91IG11c3QgYWxzbyB1c2UgYW4gZXhwbGljaXQgZmlsZXNBZGFwdGVyLic7XG4gIH1cbiAgY29uc3QgZmlsZXNDb250cm9sbGVyQWRhcHRlciA9IGxvYWRBZGFwdGVyKGZpbGVzQWRhcHRlciwgKCkgPT4ge1xuICAgIHJldHVybiBuZXcgR3JpZEZTQnVja2V0QWRhcHRlcihkYXRhYmFzZVVSSSwge30sIGZpbGVLZXkpO1xuICB9KTtcbiAgcmV0dXJuIG5ldyBGaWxlc0NvbnRyb2xsZXIoZmlsZXNDb250cm9sbGVyQWRhcHRlciwgYXBwSWQsIHtcbiAgICBwcmVzZXJ2ZUZpbGVOYW1lLFxuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFVzZXJDb250cm9sbGVyKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucyk6IFVzZXJDb250cm9sbGVyIHtcbiAgY29uc3QgeyBhcHBJZCwgZW1haWxBZGFwdGVyLCB2ZXJpZnlVc2VyRW1haWxzIH0gPSBvcHRpb25zO1xuICBjb25zdCBlbWFpbENvbnRyb2xsZXJBZGFwdGVyID0gbG9hZEFkYXB0ZXIoZW1haWxBZGFwdGVyKTtcbiAgcmV0dXJuIG5ldyBVc2VyQ29udHJvbGxlcihlbWFpbENvbnRyb2xsZXJBZGFwdGVyLCBhcHBJZCwge1xuICAgIHZlcmlmeVVzZXJFbWFpbHMsXG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2FjaGVDb250cm9sbGVyKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucyk6IENhY2hlQ29udHJvbGxlciB7XG4gIGNvbnN0IHsgYXBwSWQsIGNhY2hlQWRhcHRlciwgY2FjaGVUVEwsIGNhY2hlTWF4U2l6ZSB9ID0gb3B0aW9ucztcbiAgY29uc3QgY2FjaGVDb250cm9sbGVyQWRhcHRlciA9IGxvYWRBZGFwdGVyKGNhY2hlQWRhcHRlciwgSW5NZW1vcnlDYWNoZUFkYXB0ZXIsIHtcbiAgICBhcHBJZDogYXBwSWQsXG4gICAgdHRsOiBjYWNoZVRUTCxcbiAgICBtYXhTaXplOiBjYWNoZU1heFNpemUsXG4gIH0pO1xuICByZXR1cm4gbmV3IENhY2hlQ29udHJvbGxlcihjYWNoZUNvbnRyb2xsZXJBZGFwdGVyLCBhcHBJZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQYXJzZUdyYXBoUUxDb250cm9sbGVyKFxuICBvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMsXG4gIGNvbnRyb2xsZXJEZXBzXG4pOiBQYXJzZUdyYXBoUUxDb250cm9sbGVyIHtcbiAgcmV0dXJuIG5ldyBQYXJzZUdyYXBoUUxDb250cm9sbGVyKHtcbiAgICBtb3VudEdyYXBoUUw6IG9wdGlvbnMubW91bnRHcmFwaFFMLFxuICAgIC4uLmNvbnRyb2xsZXJEZXBzLFxuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEFuYWx5dGljc0NvbnRyb2xsZXIob3B0aW9uczogUGFyc2VTZXJ2ZXJPcHRpb25zKTogQW5hbHl0aWNzQ29udHJvbGxlciB7XG4gIGNvbnN0IHsgYW5hbHl0aWNzQWRhcHRlciB9ID0gb3B0aW9ucztcbiAgY29uc3QgYW5hbHl0aWNzQ29udHJvbGxlckFkYXB0ZXIgPSBsb2FkQWRhcHRlcihhbmFseXRpY3NBZGFwdGVyLCBBbmFseXRpY3NBZGFwdGVyKTtcbiAgcmV0dXJuIG5ldyBBbmFseXRpY3NDb250cm9sbGVyKGFuYWx5dGljc0NvbnRyb2xsZXJBZGFwdGVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldExpdmVRdWVyeUNvbnRyb2xsZXIob3B0aW9uczogUGFyc2VTZXJ2ZXJPcHRpb25zKTogTGl2ZVF1ZXJ5Q29udHJvbGxlciB7XG4gIHJldHVybiBuZXcgTGl2ZVF1ZXJ5Q29udHJvbGxlcihvcHRpb25zLmxpdmVRdWVyeSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREYXRhYmFzZUNvbnRyb2xsZXIoXG4gIG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucyxcbiAgY2FjaGVDb250cm9sbGVyOiBDYWNoZUNvbnRyb2xsZXJcbik6IERhdGFiYXNlQ29udHJvbGxlciB7XG4gIGNvbnN0IHtcbiAgICBkYXRhYmFzZVVSSSxcbiAgICBkYXRhYmFzZU9wdGlvbnMsXG4gICAgY29sbGVjdGlvblByZWZpeCxcbiAgICBzY2hlbWFDYWNoZVRUTCxcbiAgICBlbmFibGVTaW5nbGVTY2hlbWFDYWNoZSxcbiAgfSA9IG9wdGlvbnM7XG4gIGxldCB7IGRhdGFiYXNlQWRhcHRlciB9ID0gb3B0aW9ucztcbiAgaWYgKFxuICAgIChkYXRhYmFzZU9wdGlvbnMgfHxcbiAgICAgIChkYXRhYmFzZVVSSSAmJiBkYXRhYmFzZVVSSSAhPT0gZGVmYXVsdHMuZGF0YWJhc2VVUkkpIHx8XG4gICAgICBjb2xsZWN0aW9uUHJlZml4ICE9PSBkZWZhdWx0cy5jb2xsZWN0aW9uUHJlZml4KSAmJlxuICAgIGRhdGFiYXNlQWRhcHRlclxuICApIHtcbiAgICB0aHJvdyAnWW91IGNhbm5vdCBzcGVjaWZ5IGJvdGggYSBkYXRhYmFzZUFkYXB0ZXIgYW5kIGEgZGF0YWJhc2VVUkkvZGF0YWJhc2VPcHRpb25zL2NvbGxlY3Rpb25QcmVmaXguJztcbiAgfSBlbHNlIGlmICghZGF0YWJhc2VBZGFwdGVyKSB7XG4gICAgZGF0YWJhc2VBZGFwdGVyID0gZ2V0RGF0YWJhc2VBZGFwdGVyKGRhdGFiYXNlVVJJLCBjb2xsZWN0aW9uUHJlZml4LCBkYXRhYmFzZU9wdGlvbnMpO1xuICB9IGVsc2Uge1xuICAgIGRhdGFiYXNlQWRhcHRlciA9IGxvYWRBZGFwdGVyKGRhdGFiYXNlQWRhcHRlcik7XG4gIH1cbiAgcmV0dXJuIG5ldyBEYXRhYmFzZUNvbnRyb2xsZXIoXG4gICAgZGF0YWJhc2VBZGFwdGVyLFxuICAgIG5ldyBTY2hlbWFDYWNoZShjYWNoZUNvbnRyb2xsZXIsIHNjaGVtYUNhY2hlVFRMLCBlbmFibGVTaW5nbGVTY2hlbWFDYWNoZSlcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEhvb2tzQ29udHJvbGxlcihcbiAgb3B0aW9uczogUGFyc2VTZXJ2ZXJPcHRpb25zLFxuICBkYXRhYmFzZUNvbnRyb2xsZXI6IERhdGFiYXNlQ29udHJvbGxlclxuKTogSG9va3NDb250cm9sbGVyIHtcbiAgY29uc3QgeyBhcHBJZCwgd2ViaG9va0tleSB9ID0gb3B0aW9ucztcbiAgcmV0dXJuIG5ldyBIb29rc0NvbnRyb2xsZXIoYXBwSWQsIGRhdGFiYXNlQ29udHJvbGxlciwgd2ViaG9va0tleSk7XG59XG5cbmludGVyZmFjZSBQdXNoQ29udHJvbGxpbmcge1xuICBwdXNoQ29udHJvbGxlcjogUHVzaENvbnRyb2xsZXI7XG4gIGhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0OiBib29sZWFuO1xuICBwdXNoQ29udHJvbGxlclF1ZXVlOiBQdXNoUXVldWU7XG4gIHB1c2hXb3JrZXI6IFB1c2hXb3JrZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQdXNoQ29udHJvbGxlcihvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMpOiBQdXNoQ29udHJvbGxpbmcge1xuICBjb25zdCB7IHNjaGVkdWxlZFB1c2gsIHB1c2ggfSA9IG9wdGlvbnM7XG5cbiAgY29uc3QgcHVzaE9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBwdXNoKTtcbiAgY29uc3QgcHVzaFF1ZXVlT3B0aW9ucyA9IHB1c2hPcHRpb25zLnF1ZXVlT3B0aW9ucyB8fCB7fTtcbiAgaWYgKHB1c2hPcHRpb25zLnF1ZXVlT3B0aW9ucykge1xuICAgIGRlbGV0ZSBwdXNoT3B0aW9ucy5xdWV1ZU9wdGlvbnM7XG4gIH1cblxuICAvLyBQYXNzIHRoZSBwdXNoIG9wdGlvbnMgdG9vIGFzIGl0IHdvcmtzIHdpdGggdGhlIGRlZmF1bHRcbiAgY29uc3QgcHVzaEFkYXB0ZXIgPSBsb2FkQWRhcHRlcihcbiAgICBwdXNoT3B0aW9ucyAmJiBwdXNoT3B0aW9ucy5hZGFwdGVyLFxuICAgIFBhcnNlUHVzaEFkYXB0ZXIsXG4gICAgcHVzaE9wdGlvbnNcbiAgKTtcbiAgLy8gV2UgcGFzcyB0aGUgb3B0aW9ucyBhbmQgdGhlIGJhc2UgY2xhc3MgZm9yIHRoZSBhZGF0cGVyLFxuICAvLyBOb3RlIHRoYXQgcGFzc2luZyBhbiBpbnN0YW5jZSB3b3VsZCB3b3JrIHRvb1xuICBjb25zdCBwdXNoQ29udHJvbGxlciA9IG5ldyBQdXNoQ29udHJvbGxlcigpO1xuICBjb25zdCBoYXNQdXNoU3VwcG9ydCA9ICEhKHB1c2hBZGFwdGVyICYmIHB1c2gpO1xuICBjb25zdCBoYXNQdXNoU2NoZWR1bGVkU3VwcG9ydCA9IGhhc1B1c2hTdXBwb3J0ICYmIHNjaGVkdWxlZFB1c2ggPT09IHRydWU7XG5cbiAgY29uc3QgeyBkaXNhYmxlUHVzaFdvcmtlciB9ID0gcHVzaFF1ZXVlT3B0aW9ucztcblxuICBjb25zdCBwdXNoQ29udHJvbGxlclF1ZXVlID0gbmV3IFB1c2hRdWV1ZShwdXNoUXVldWVPcHRpb25zKTtcbiAgbGV0IHB1c2hXb3JrZXI7XG4gIGlmICghZGlzYWJsZVB1c2hXb3JrZXIpIHtcbiAgICBwdXNoV29ya2VyID0gbmV3IFB1c2hXb3JrZXIocHVzaEFkYXB0ZXIsIHB1c2hRdWV1ZU9wdGlvbnMpO1xuICB9XG4gIHJldHVybiB7XG4gICAgcHVzaENvbnRyb2xsZXIsXG4gICAgaGFzUHVzaFN1cHBvcnQsXG4gICAgaGFzUHVzaFNjaGVkdWxlZFN1cHBvcnQsXG4gICAgcHVzaENvbnRyb2xsZXJRdWV1ZSxcbiAgICBwdXNoV29ya2VyLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXV0aERhdGFNYW5hZ2VyKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucykge1xuICBjb25zdCB7IGF1dGgsIGVuYWJsZUFub255bW91c1VzZXJzIH0gPSBvcHRpb25zO1xuICByZXR1cm4gYXV0aERhdGFNYW5hZ2VyKGF1dGgsIGVuYWJsZUFub255bW91c1VzZXJzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERhdGFiYXNlQWRhcHRlcihkYXRhYmFzZVVSSSwgY29sbGVjdGlvblByZWZpeCwgZGF0YWJhc2VPcHRpb25zKSB7XG4gIGxldCBwcm90b2NvbDtcbiAgdHJ5IHtcbiAgICBjb25zdCBwYXJzZWRVUkkgPSB1cmwucGFyc2UoZGF0YWJhc2VVUkkpO1xuICAgIHByb3RvY29sID0gcGFyc2VkVVJJLnByb3RvY29sID8gcGFyc2VkVVJJLnByb3RvY29sLnRvTG93ZXJDYXNlKCkgOiBudWxsO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLyogKi9cbiAgfVxuICBzd2l0Y2ggKHByb3RvY29sKSB7XG4gICAgY2FzZSAncG9zdGdyZXM6JzpcbiAgICAgIHJldHVybiBuZXcgUG9zdGdyZXNTdG9yYWdlQWRhcHRlcih7XG4gICAgICAgIHVyaTogZGF0YWJhc2VVUkksXG4gICAgICAgIGNvbGxlY3Rpb25QcmVmaXgsXG4gICAgICAgIGRhdGFiYXNlT3B0aW9ucyxcbiAgICAgIH0pO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gbmV3IE1vbmdvU3RvcmFnZUFkYXB0ZXIoe1xuICAgICAgICB1cmk6IGRhdGFiYXNlVVJJLFxuICAgICAgICBjb2xsZWN0aW9uUHJlZml4LFxuICAgICAgICBtb25nb09wdGlvbnM6IGRhdGFiYXNlT3B0aW9ucyxcbiAgICAgIH0pO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Controllers/types.js b/lib/Controllers/types.js new file mode 100644 index 0000000000..4310b4ffac --- /dev/null +++ b/lib/Controllers/types.js @@ -0,0 +1,2 @@ +"use strict"; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbXX0= \ No newline at end of file diff --git a/lib/GraphQL/ParseGraphQLSchema.js b/lib/GraphQL/ParseGraphQLSchema.js new file mode 100644 index 0000000000..874d8fb3ef --- /dev/null +++ b/lib/GraphQL/ParseGraphQLSchema.js @@ -0,0 +1,446 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ParseGraphQLSchema = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _graphql = require("graphql"); + +var _stitch = require("@graphql-tools/stitch"); + +var _utils = require("@graphql-tools/utils"); + +var _requiredParameter = _interopRequireDefault(require("../requiredParameter")); + +var defaultGraphQLTypes = _interopRequireWildcard(require("./loaders/defaultGraphQLTypes")); + +var parseClassTypes = _interopRequireWildcard(require("./loaders/parseClassTypes")); + +var parseClassQueries = _interopRequireWildcard(require("./loaders/parseClassQueries")); + +var parseClassMutations = _interopRequireWildcard(require("./loaders/parseClassMutations")); + +var defaultGraphQLQueries = _interopRequireWildcard(require("./loaders/defaultGraphQLQueries")); + +var defaultGraphQLMutations = _interopRequireWildcard(require("./loaders/defaultGraphQLMutations")); + +var _ParseGraphQLController = _interopRequireWildcard(require("../Controllers/ParseGraphQLController")); + +var _DatabaseController = _interopRequireDefault(require("../Controllers/DatabaseController")); + +var _parseGraphQLUtils = require("./parseGraphQLUtils"); + +var schemaDirectives = _interopRequireWildcard(require("./loaders/schemaDirectives")); + +var schemaTypes = _interopRequireWildcard(require("./loaders/schemaTypes")); + +var _triggers = require("../triggers"); + +var defaultRelaySchema = _interopRequireWildcard(require("./loaders/defaultRelaySchema")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const RESERVED_GRAPHQL_TYPE_NAMES = ['String', 'Boolean', 'Int', 'Float', 'ID', 'ArrayResult', 'Query', 'Mutation', 'Subscription', 'CreateFileInput', 'CreateFilePayload', 'Viewer', 'SignUpInput', 'SignUpPayload', 'LogInInput', 'LogInPayload', 'LogOutInput', 'LogOutPayload', 'CloudCodeFunction', 'CallCloudCodeInput', 'CallCloudCodePayload', 'CreateClassInput', 'CreateClassPayload', 'UpdateClassInput', 'UpdateClassPayload', 'DeleteClassInput', 'DeleteClassPayload', 'PageInfo']; +const RESERVED_GRAPHQL_QUERY_NAMES = ['health', 'viewer', 'class', 'classes']; +const RESERVED_GRAPHQL_MUTATION_NAMES = ['signUp', 'logIn', 'logOut', 'createFile', 'callCloudCode', 'createClass', 'updateClass', 'deleteClass']; + +class ParseGraphQLSchema { + constructor(params = {}) { + this.parseGraphQLController = params.parseGraphQLController || (0, _requiredParameter.default)('You must provide a parseGraphQLController instance!'); + this.databaseController = params.databaseController || (0, _requiredParameter.default)('You must provide a databaseController instance!'); + this.log = params.log || (0, _requiredParameter.default)('You must provide a log instance!'); + this.graphQLCustomTypeDefs = params.graphQLCustomTypeDefs; + this.appId = params.appId || (0, _requiredParameter.default)('You must provide the appId!'); + } + + async load() { + const { + parseGraphQLConfig + } = await this._initializeSchemaAndConfig(); + const parseClasses = await this._getClassesForSchema(parseGraphQLConfig); + const parseClassesString = JSON.stringify(parseClasses); + const functionNames = await this._getFunctionNames(); + const functionNamesString = JSON.stringify(functionNames); + + if (this.graphQLSchema && !this._hasSchemaInputChanged({ + parseClasses, + parseClassesString, + parseGraphQLConfig, + functionNamesString + })) { + return this.graphQLSchema; + } + + this.parseClasses = parseClasses; + this.parseClassesString = parseClassesString; + this.parseGraphQLConfig = parseGraphQLConfig; + this.functionNames = functionNames; + this.functionNamesString = functionNamesString; + this.parseClassTypes = {}; + this.viewerType = null; + this.graphQLAutoSchema = null; + this.graphQLSchema = null; + this.graphQLTypes = []; + this.graphQLQueries = {}; + this.graphQLMutations = {}; + this.graphQLSubscriptions = {}; + this.graphQLSchemaDirectivesDefinitions = null; + this.graphQLSchemaDirectives = {}; + this.relayNodeInterface = null; + defaultGraphQLTypes.load(this); + defaultRelaySchema.load(this); + schemaTypes.load(this); + + this._getParseClassesWithConfig(parseClasses, parseGraphQLConfig).forEach(([parseClass, parseClassConfig]) => { + parseClassTypes.load(this, parseClass, parseClassConfig); + parseClassQueries.load(this, parseClass, parseClassConfig); + parseClassMutations.load(this, parseClass, parseClassConfig); + }); + + defaultGraphQLTypes.loadArrayResult(this, parseClasses); + defaultGraphQLQueries.load(this); + defaultGraphQLMutations.load(this); + let graphQLQuery = undefined; + + if (Object.keys(this.graphQLQueries).length > 0) { + graphQLQuery = new _graphql.GraphQLObjectType({ + name: 'Query', + description: 'Query is the top level type for queries.', + fields: this.graphQLQueries + }); + this.addGraphQLType(graphQLQuery, true, true); + } + + let graphQLMutation = undefined; + + if (Object.keys(this.graphQLMutations).length > 0) { + graphQLMutation = new _graphql.GraphQLObjectType({ + name: 'Mutation', + description: 'Mutation is the top level type for mutations.', + fields: this.graphQLMutations + }); + this.addGraphQLType(graphQLMutation, true, true); + } + + let graphQLSubscription = undefined; + + if (Object.keys(this.graphQLSubscriptions).length > 0) { + graphQLSubscription = new _graphql.GraphQLObjectType({ + name: 'Subscription', + description: 'Subscription is the top level type for subscriptions.', + fields: this.graphQLSubscriptions + }); + this.addGraphQLType(graphQLSubscription, true, true); + } + + this.graphQLAutoSchema = new _graphql.GraphQLSchema({ + types: this.graphQLTypes, + query: graphQLQuery, + mutation: graphQLMutation, + subscription: graphQLSubscription + }); + + if (this.graphQLCustomTypeDefs) { + schemaDirectives.load(this); + + if (typeof this.graphQLCustomTypeDefs.getTypeMap === 'function') { + const customGraphQLSchemaTypeMap = this.graphQLCustomTypeDefs.getTypeMap(); + + const findAndReplaceLastType = (parent, key) => { + if (parent[key].name) { + if (this.graphQLAutoSchema.getType(parent[key].name) && this.graphQLAutoSchema.getType(parent[key].name) !== parent[key]) { + // To avoid unresolved field on overloaded schema + // replace the final type with the auto schema one + parent[key] = this.graphQLAutoSchema.getType(parent[key].name); + } + } else { + if (parent[key].ofType) { + findAndReplaceLastType(parent[key], 'ofType'); + } + } + }; + + Object.values(customGraphQLSchemaTypeMap).forEach(customGraphQLSchemaType => { + if (!customGraphQLSchemaType || !customGraphQLSchemaType.name || customGraphQLSchemaType.name.startsWith('__')) { + return; + } + + const autoGraphQLSchemaType = this.graphQLAutoSchema.getType(customGraphQLSchemaType.name); + + if (!autoGraphQLSchemaType) { + this.graphQLAutoSchema._typeMap[customGraphQLSchemaType.name] = customGraphQLSchemaType; + } + }); + Object.values(customGraphQLSchemaTypeMap).forEach(customGraphQLSchemaType => { + if (!customGraphQLSchemaType || !customGraphQLSchemaType.name || customGraphQLSchemaType.name.startsWith('__')) { + return; + } + + const autoGraphQLSchemaType = this.graphQLAutoSchema.getType(customGraphQLSchemaType.name); + + if (autoGraphQLSchemaType && typeof customGraphQLSchemaType.getFields === 'function') { + Object.values(customGraphQLSchemaType.getFields()).forEach(field => { + findAndReplaceLastType(field, 'type'); + }); + autoGraphQLSchemaType._fields = _objectSpread(_objectSpread({}, autoGraphQLSchemaType.getFields()), customGraphQLSchemaType.getFields()); + } + }); + this.graphQLSchema = (0, _stitch.stitchSchemas)({ + schemas: [this.graphQLSchemaDirectivesDefinitions, this.graphQLAutoSchema], + mergeDirectives: true + }); + } else if (typeof this.graphQLCustomTypeDefs === 'function') { + this.graphQLSchema = await this.graphQLCustomTypeDefs({ + directivesDefinitionsSchema: this.graphQLSchemaDirectivesDefinitions, + autoSchema: this.graphQLAutoSchema, + stitchSchemas: _stitch.stitchSchemas + }); + } else { + this.graphQLSchema = (0, _stitch.stitchSchemas)({ + schemas: [this.graphQLSchemaDirectivesDefinitions, this.graphQLAutoSchema, this.graphQLCustomTypeDefs], + mergeDirectives: true + }); + } + + const graphQLSchemaTypeMap = this.graphQLSchema.getTypeMap(); + Object.keys(graphQLSchemaTypeMap).forEach(graphQLSchemaTypeName => { + const graphQLSchemaType = graphQLSchemaTypeMap[graphQLSchemaTypeName]; + + if (typeof graphQLSchemaType.getFields === 'function' && this.graphQLCustomTypeDefs.definitions) { + const graphQLCustomTypeDef = this.graphQLCustomTypeDefs.definitions.find(definition => definition.name.value === graphQLSchemaTypeName); + + if (graphQLCustomTypeDef) { + const graphQLSchemaTypeFieldMap = graphQLSchemaType.getFields(); + Object.keys(graphQLSchemaTypeFieldMap).forEach(graphQLSchemaTypeFieldName => { + const graphQLSchemaTypeField = graphQLSchemaTypeFieldMap[graphQLSchemaTypeFieldName]; + + if (!graphQLSchemaTypeField.astNode) { + const astNode = graphQLCustomTypeDef.fields.find(field => field.name.value === graphQLSchemaTypeFieldName); + + if (astNode) { + graphQLSchemaTypeField.astNode = astNode; + } + } + }); + } + } + }); + + _utils.SchemaDirectiveVisitor.visitSchemaDirectives(this.graphQLSchema, this.graphQLSchemaDirectives); + } else { + this.graphQLSchema = this.graphQLAutoSchema; + } + + return this.graphQLSchema; + } + + addGraphQLType(type, throwError = false, ignoreReserved = false, ignoreConnection = false) { + if (!ignoreReserved && RESERVED_GRAPHQL_TYPE_NAMES.includes(type.name) || this.graphQLTypes.find(existingType => existingType.name === type.name) || !ignoreConnection && type.name.endsWith('Connection')) { + const message = `Type ${type.name} could not be added to the auto schema because it collided with an existing type.`; + + if (throwError) { + throw new Error(message); + } + + this.log.warn(message); + return undefined; + } + + this.graphQLTypes.push(type); + return type; + } + + addGraphQLQuery(fieldName, field, throwError = false, ignoreReserved = false) { + if (!ignoreReserved && RESERVED_GRAPHQL_QUERY_NAMES.includes(fieldName) || this.graphQLQueries[fieldName]) { + const message = `Query ${fieldName} could not be added to the auto schema because it collided with an existing field.`; + + if (throwError) { + throw new Error(message); + } + + this.log.warn(message); + return undefined; + } + + this.graphQLQueries[fieldName] = field; + return field; + } + + addGraphQLMutation(fieldName, field, throwError = false, ignoreReserved = false) { + if (!ignoreReserved && RESERVED_GRAPHQL_MUTATION_NAMES.includes(fieldName) || this.graphQLMutations[fieldName]) { + const message = `Mutation ${fieldName} could not be added to the auto schema because it collided with an existing field.`; + + if (throwError) { + throw new Error(message); + } + + this.log.warn(message); + return undefined; + } + + this.graphQLMutations[fieldName] = field; + return field; + } + + handleError(error) { + if (error instanceof _node.default.Error) { + this.log.error('Parse error: ', error); + } else { + this.log.error('Uncaught internal server error.', error, error.stack); + } + + throw (0, _parseGraphQLUtils.toGraphQLError)(error); + } + + async _initializeSchemaAndConfig() { + const [schemaController, parseGraphQLConfig] = await Promise.all([this.databaseController.loadSchema(), this.parseGraphQLController.getGraphQLConfig()]); + this.schemaController = schemaController; + return { + parseGraphQLConfig + }; + } + /** + * Gets all classes found by the `schemaController` + * minus those filtered out by the app's parseGraphQLConfig. + */ + + + async _getClassesForSchema(parseGraphQLConfig) { + const { + enabledForClasses, + disabledForClasses + } = parseGraphQLConfig; + const allClasses = await this.schemaController.getAllClasses(); + + if (Array.isArray(enabledForClasses) || Array.isArray(disabledForClasses)) { + let includedClasses = allClasses; + + if (enabledForClasses) { + includedClasses = allClasses.filter(clazz => { + return enabledForClasses.includes(clazz.className); + }); + } + + if (disabledForClasses) { + // Classes included in `enabledForClasses` that + // are also present in `disabledForClasses` will + // still be filtered out + includedClasses = includedClasses.filter(clazz => { + return !disabledForClasses.includes(clazz.className); + }); + } + + this.isUsersClassDisabled = !includedClasses.some(clazz => { + return clazz.className === '_User'; + }); + return includedClasses; + } else { + return allClasses; + } + } + /** + * This method returns a list of tuples + * that provide the parseClass along with + * its parseClassConfig where provided. + */ + + + _getParseClassesWithConfig(parseClasses, parseGraphQLConfig) { + const { + classConfigs + } = parseGraphQLConfig; // Make sures that the default classes and classes that + // starts with capitalized letter will be generated first. + + const sortClasses = (a, b) => { + a = a.className; + b = b.className; + + if (a[0] === '_') { + if (b[0] !== '_') { + return -1; + } + } + + if (b[0] === '_') { + if (a[0] !== '_') { + return 1; + } + } + + if (a === b) { + return 0; + } else if (a < b) { + return -1; + } else { + return 1; + } + }; + + return parseClasses.sort(sortClasses).map(parseClass => { + let parseClassConfig; + + if (classConfigs) { + parseClassConfig = classConfigs.find(c => c.className === parseClass.className); + } + + return [parseClass, parseClassConfig]; + }); + } + + async _getFunctionNames() { + return await (0, _triggers.getFunctionNames)(this.appId).filter(functionName => { + if (/^[_a-zA-Z][_a-zA-Z0-9]*$/.test(functionName)) { + return true; + } else { + this.log.warn(`Function ${functionName} could not be added to the auto schema because GraphQL names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/.`); + return false; + } + }); + } + /** + * Checks for changes to the parseClasses + * objects (i.e. database schema) or to + * the parseGraphQLConfig object. If no + * changes are found, return true; + */ + + + _hasSchemaInputChanged(params) { + const { + parseClasses, + parseClassesString, + parseGraphQLConfig, + functionNamesString + } = params; + + if (JSON.stringify(this.parseGraphQLConfig) === JSON.stringify(parseGraphQLConfig) && this.functionNamesString === functionNamesString) { + if (this.parseClasses === parseClasses) { + return false; + } + + if (this.parseClassesString === parseClassesString) { + this.parseClasses = parseClasses; + return false; + } + } + + return true; + } + +} + +exports.ParseGraphQLSchema = ParseGraphQLSchema; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9HcmFwaFFML1BhcnNlR3JhcGhRTFNjaGVtYS5qcyJdLCJuYW1lcyI6WyJSRVNFUlZFRF9HUkFQSFFMX1RZUEVfTkFNRVMiLCJSRVNFUlZFRF9HUkFQSFFMX1FVRVJZX05BTUVTIiwiUkVTRVJWRURfR1JBUEhRTF9NVVRBVElPTl9OQU1FUyIsIlBhcnNlR3JhcGhRTFNjaGVtYSIsImNvbnN0cnVjdG9yIiwicGFyYW1zIiwicGFyc2VHcmFwaFFMQ29udHJvbGxlciIsImRhdGFiYXNlQ29udHJvbGxlciIsImxvZyIsImdyYXBoUUxDdXN0b21UeXBlRGVmcyIsImFwcElkIiwibG9hZCIsInBhcnNlR3JhcGhRTENvbmZpZyIsIl9pbml0aWFsaXplU2NoZW1hQW5kQ29uZmlnIiwicGFyc2VDbGFzc2VzIiwiX2dldENsYXNzZXNGb3JTY2hlbWEiLCJwYXJzZUNsYXNzZXNTdHJpbmciLCJKU09OIiwic3RyaW5naWZ5IiwiZnVuY3Rpb25OYW1lcyIsIl9nZXRGdW5jdGlvbk5hbWVzIiwiZnVuY3Rpb25OYW1lc1N0cmluZyIsImdyYXBoUUxTY2hlbWEiLCJfaGFzU2NoZW1hSW5wdXRDaGFuZ2VkIiwicGFyc2VDbGFzc1R5cGVzIiwidmlld2VyVHlwZSIsImdyYXBoUUxBdXRvU2NoZW1hIiwiZ3JhcGhRTFR5cGVzIiwiZ3JhcGhRTFF1ZXJpZXMiLCJncmFwaFFMTXV0YXRpb25zIiwiZ3JhcGhRTFN1YnNjcmlwdGlvbnMiLCJncmFwaFFMU2NoZW1hRGlyZWN0aXZlc0RlZmluaXRpb25zIiwiZ3JhcGhRTFNjaGVtYURpcmVjdGl2ZXMiLCJyZWxheU5vZGVJbnRlcmZhY2UiLCJkZWZhdWx0R3JhcGhRTFR5cGVzIiwiZGVmYXVsdFJlbGF5U2NoZW1hIiwic2NoZW1hVHlwZXMiLCJfZ2V0UGFyc2VDbGFzc2VzV2l0aENvbmZpZyIsImZvckVhY2giLCJwYXJzZUNsYXNzIiwicGFyc2VDbGFzc0NvbmZpZyIsInBhcnNlQ2xhc3NRdWVyaWVzIiwicGFyc2VDbGFzc011dGF0aW9ucyIsImxvYWRBcnJheVJlc3VsdCIsImRlZmF1bHRHcmFwaFFMUXVlcmllcyIsImRlZmF1bHRHcmFwaFFMTXV0YXRpb25zIiwiZ3JhcGhRTFF1ZXJ5IiwidW5kZWZpbmVkIiwiT2JqZWN0Iiwia2V5cyIsImxlbmd0aCIsIkdyYXBoUUxPYmplY3RUeXBlIiwibmFtZSIsImRlc2NyaXB0aW9uIiwiZmllbGRzIiwiYWRkR3JhcGhRTFR5cGUiLCJncmFwaFFMTXV0YXRpb24iLCJncmFwaFFMU3Vic2NyaXB0aW9uIiwiR3JhcGhRTFNjaGVtYSIsInR5cGVzIiwicXVlcnkiLCJtdXRhdGlvbiIsInN1YnNjcmlwdGlvbiIsInNjaGVtYURpcmVjdGl2ZXMiLCJnZXRUeXBlTWFwIiwiY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGVNYXAiLCJmaW5kQW5kUmVwbGFjZUxhc3RUeXBlIiwicGFyZW50Iiwia2V5IiwiZ2V0VHlwZSIsIm9mVHlwZSIsInZhbHVlcyIsImN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlIiwic3RhcnRzV2l0aCIsImF1dG9HcmFwaFFMU2NoZW1hVHlwZSIsIl90eXBlTWFwIiwiZ2V0RmllbGRzIiwiZmllbGQiLCJfZmllbGRzIiwic2NoZW1hcyIsIm1lcmdlRGlyZWN0aXZlcyIsImRpcmVjdGl2ZXNEZWZpbml0aW9uc1NjaGVtYSIsImF1dG9TY2hlbWEiLCJzdGl0Y2hTY2hlbWFzIiwiZ3JhcGhRTFNjaGVtYVR5cGVNYXAiLCJncmFwaFFMU2NoZW1hVHlwZU5hbWUiLCJncmFwaFFMU2NoZW1hVHlwZSIsImRlZmluaXRpb25zIiwiZ3JhcGhRTEN1c3RvbVR5cGVEZWYiLCJmaW5kIiwiZGVmaW5pdGlvbiIsInZhbHVlIiwiZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZE1hcCIsImdyYXBoUUxTY2hlbWFUeXBlRmllbGROYW1lIiwiZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZCIsImFzdE5vZGUiLCJTY2hlbWFEaXJlY3RpdmVWaXNpdG9yIiwidmlzaXRTY2hlbWFEaXJlY3RpdmVzIiwidHlwZSIsInRocm93RXJyb3IiLCJpZ25vcmVSZXNlcnZlZCIsImlnbm9yZUNvbm5lY3Rpb24iLCJpbmNsdWRlcyIsImV4aXN0aW5nVHlwZSIsImVuZHNXaXRoIiwibWVzc2FnZSIsIkVycm9yIiwid2FybiIsInB1c2giLCJhZGRHcmFwaFFMUXVlcnkiLCJmaWVsZE5hbWUiLCJhZGRHcmFwaFFMTXV0YXRpb24iLCJoYW5kbGVFcnJvciIsImVycm9yIiwiUGFyc2UiLCJzdGFjayIsInNjaGVtYUNvbnRyb2xsZXIiLCJQcm9taXNlIiwiYWxsIiwibG9hZFNjaGVtYSIsImdldEdyYXBoUUxDb25maWciLCJlbmFibGVkRm9yQ2xhc3NlcyIsImRpc2FibGVkRm9yQ2xhc3NlcyIsImFsbENsYXNzZXMiLCJnZXRBbGxDbGFzc2VzIiwiQXJyYXkiLCJpc0FycmF5IiwiaW5jbHVkZWRDbGFzc2VzIiwiZmlsdGVyIiwiY2xhenoiLCJjbGFzc05hbWUiLCJpc1VzZXJzQ2xhc3NEaXNhYmxlZCIsInNvbWUiLCJjbGFzc0NvbmZpZ3MiLCJzb3J0Q2xhc3NlcyIsImEiLCJiIiwic29ydCIsIm1hcCIsImMiLCJmdW5jdGlvbk5hbWUiLCJ0ZXN0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FBRUEsTUFBTUEsMkJBQTJCLEdBQUcsQ0FDbEMsUUFEa0MsRUFFbEMsU0FGa0MsRUFHbEMsS0FIa0MsRUFJbEMsT0FKa0MsRUFLbEMsSUFMa0MsRUFNbEMsYUFOa0MsRUFPbEMsT0FQa0MsRUFRbEMsVUFSa0MsRUFTbEMsY0FUa0MsRUFVbEMsaUJBVmtDLEVBV2xDLG1CQVhrQyxFQVlsQyxRQVprQyxFQWFsQyxhQWJrQyxFQWNsQyxlQWRrQyxFQWVsQyxZQWZrQyxFQWdCbEMsY0FoQmtDLEVBaUJsQyxhQWpCa0MsRUFrQmxDLGVBbEJrQyxF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RDtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNFckgsRUFBQUEsc0JBQXNCLENBQUNsQixNQUFELEVBS1Y7QUFDVixVQUFNO0FBQUVTLE1BQUFBLFlBQUY7QUFBZ0JFLE1BQUFBLGtCQUFoQjtBQUFvQ0osTUFBQUEsa0JBQXBDO0FBQXdEUyxNQUFBQTtBQUF4RCxRQUFnRmhCLE1BQXRGOztBQUVBLFFBQ0VZLElBQUksQ0FBQ0MsU0FBTCxDQUFlLEtBQUtOLGtCQUFwQixNQUE0Q0ssSUFBSSxDQUFDQyxTQUFMLENBQWVOLGtCQUFmLENBQTVDLElBQ0EsS0FBS1MsbUJBQUwsS0FBNkJBLG1CQUYvQixFQUdFO0FBQ0EsVUFBSSxLQUFLUCxZQUFMLEtBQXNCQSxZQUExQixFQUF3QztBQUN0QyxlQUFPLEtBQVA7QUFDRDs7QUFFRCxVQUFJLEtBQUtFLGtCQUFMLEtBQTRCQSxrQkFBaEMsRUFBb0Q7QUFDbEQsYUFBS0YsWUFBTCxHQUFvQkEsWUFBcEI7QUFDQSxlQUFPLEtBQVA7QUFDRDtBQUNGOztBQUVELFdBQU8sSUFBUDtBQUNEOztBQXRhc0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBHcmFwaFFMU2NoZW1hLCBHcmFwaFFMT2JqZWN0VHlwZSwgRG9jdW1lbnROb2RlLCBHcmFwaFFMTmFtZWRUeXBlIH0gZnJvbSAnZ3JhcGhxbCc7XG5pbXBvcnQgeyBzdGl0Y2hTY2hlbWFzIH0gZnJvbSAnQGdyYXBocWwtdG9vbHMvc3RpdGNoJztcbmltcG9ydCB7IFNjaGVtYURpcmVjdGl2ZVZpc2l0b3IgfSBmcm9tICdAZ3JhcGhxbC10b29scy91dGlscyc7XG5pbXBvcnQgcmVxdWlyZWRQYXJhbWV0ZXIgZnJvbSAnLi4vcmVxdWlyZWRQYXJhbWV0ZXInO1xuaW1wb3J0ICogYXMgZGVmYXVsdEdyYXBoUUxUeXBlcyBmcm9tICcuL2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQgKiBhcyBwYXJzZUNsYXNzVHlwZXMgZnJvbSAnLi9sb2FkZXJzL3BhcnNlQ2xhc3NUeXBlcyc7XG5pbXBvcnQgKiBhcyBwYXJzZUNsYXNzUXVlcmllcyBmcm9tICcuL2xvYWRlcnMvcGFyc2VDbGFzc1F1ZXJpZXMnO1xuaW1wb3J0ICogYXMgcGFyc2VDbGFzc011dGF0aW9ucyBmcm9tICcuL2xvYWRlcnMvcGFyc2VDbGFzc011dGF0aW9ucyc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFF1ZXJpZXMgZnJvbSAnLi9sb2FkZXJzL2RlZmF1bHRHcmFwaFFMUXVlcmllcyc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTE11dGF0aW9ucyBmcm9tICcuL2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxNdXRhdGlvbnMnO1xuaW1wb3J0IFBhcnNlR3JhcGhRTENvbnRyb2xsZXIsIHsgUGFyc2VHcmFwaFFMQ29uZmlnIH0gZnJvbSAnLi4vQ29udHJvbGxlcnMvUGFyc2VHcmFwaFFMQ29udHJvbGxlcic7XG5pbXBvcnQgRGF0YWJhc2VDb250cm9sbGVyIGZyb20gJy4uL0NvbnRyb2xsZXJzL0RhdGFiYXNlQ29udHJvbGxlcic7XG5pbXBvcnQgeyB0b0dyYXBoUUxFcnJvciB9IGZyb20gJy4vcGFyc2VHcmFwaFFMVXRpbHMnO1xuaW1wb3J0ICogYXMgc2NoZW1hRGlyZWN0aXZlcyBmcm9tICcuL2xvYWRlcnMvc2NoZW1hRGlyZWN0aXZlcyc7XG5pbXBvcnQgKiBhcyBzY2hlbWFUeXBlcyBmcm9tICcuL2xvYWRlcnMvc2NoZW1hVHlwZXMnO1xuaW1wb3J0IHsgZ2V0RnVuY3Rpb25OYW1lcyB9IGZyb20gJy4uL3RyaWdnZXJzJztcbmltcG9ydCAqIGFzIGRlZmF1bHRSZWxheVNjaGVtYSBmcm9tICcuL2xvYWRlcnMvZGVmYXVsdFJlbGF5U2NoZW1hJztcblxuY29uc3QgUkVTRVJWRURfR1JBUEhRTF9UWVBFX05BTUVTID0gW1xuICAnU3RyaW5nJyxcbiAgJ0Jvb2xlYW4nLFxuICAnSW50JyxcbiAgJ0Zsb2F0JyxcbiAgJ0lEJyxcbiAgJ0FycmF5UmVzdWx0JyxcbiAgJ1F1ZXJ5JyxcbiAgJ011dGF0aW9uJyxcbiAgJ1N1YnNjcmlwdGlvbicsXG4gICdDcmVhdGVGaWxlSW5wdXQnLFxuICAnQ3JlYXRlRmlsZVBheWxvYWQnLFxuICAnVmlld2VyJyxcbiAgJ1NpZ25VcElucHV0JyxcbiAgJ1NpZ25VcFBheWxvYWQnLFxuICAnTG9nSW5JbnB1dCcsXG4gICdMb2dJblBheWxvYWQnLFxuICAnTG9nT3V0SW5wdXQnLFxuICAnTG9nT3V0UGF5bG9hZCcsXG4gICdDbG91ZENvZGVGdW5jdGlvbicsXG4gICdDYWxsQ2xvdWRDb2RlSW5wdXQnLFxuICAnQ2FsbENsb3VkQ29kZVBheWxvYWQnLFxuICAnQ3JlYXRlQ2xhc3NJbnB1dCcsXG4gICdDcmVhdGVDbGFzc1BheWxvYWQnLFxuICAnVXBkYXRlQ2xhc3NJbnB1dCcsXG4gICdVcGRhdGVDbGFzc1BheWxvYWQnLFxuICAnRGVsZXRlQ2xhc3NJbnB1dCcsXG4gICdEZWxldGVDbGFzc1BheWxvYWQnLFxuICAnUGFnZUluZm8nLFxuXTtcbmNvbnN0IFJFU0VSVkVEX0dSQVBIUUxfUVVFUllfTkFNRVMgPSBbJ2hlYWx0aCcsICd2aWV3ZXInLCAnY2xhc3MnLCAnY2xhc3NlcyddO1xuY29uc3QgUkVTRVJWRURfR1JBUEhRTF9NVVRBVElPTl9OQU1FUyA9IFtcbiAgJ3NpZ25VcCcsXG4gICdsb2dJbicsXG4gICdsb2dPdXQnLFxuICAnY3JlYXRlRmlsZScsXG4gICdjYWxsQ2xvdWRDb2RlJyxcbiAgJ2NyZWF0ZUNsYXNzJyxcbiAgJ3VwZGF0ZUNsYXNzJyxcbiAgJ2RlbGV0ZUNsYXNzJyxcbl07XG5cbmNsYXNzIFBhcnNlR3JhcGhRTFNjaGVtYSB7XG4gIGRhdGFiYXNlQ29udHJvbGxlcjogRGF0YWJhc2VDb250cm9sbGVyO1xuICBwYXJzZUdyYXBoUUxDb250cm9sbGVyOiBQYXJzZUdyYXBoUUxDb250cm9sbGVyO1xuICBwYXJzZUdyYXBoUUxDb25maWc6IFBhcnNlR3JhcGhRTENvbmZpZztcbiAgbG9nOiBhbnk7XG4gIGFwcElkOiBzdHJpbmc7XG4gIGdyYXBoUUxDdXN0b21UeXBlRGVmczogPyhzdHJpbmcgfCBHcmFwaFFMU2NoZW1hIHwgRG9jdW1lbnROb2RlIHwgR3JhcGhRTE5hbWVkVHlwZVtdKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwYXJhbXM6IHtcbiAgICAgIGRhdGFiYXNlQ29udHJvbGxlcjogRGF0YWJhc2VDb250cm9sbGVyLFxuICAgICAgcGFyc2VHcmFwaFFMQ29udHJvbGxlcjogUGFyc2VHcmFwaFFMQ29udHJvbGxlcixcbiAgICAgIGxvZzogYW55LFxuICAgICAgYXBwSWQ6IHN0cmluZyxcbiAgICAgIGdyYXBoUUxDdXN0b21UeXBlRGVmczogPyhzdHJpbmcgfCBHcmFwaFFMU2NoZW1hIHwgRG9jdW1lbnROb2RlIHwgR3JhcGhRTE5hbWVkVHlwZVtdKSxcbiAgICB9ID0ge31cbiAgKSB7XG4gICAgdGhpcy5wYXJzZUdyYXBoUUxDb250cm9sbGVyID1cbiAgICAgIHBhcmFtcy5wYXJzZUdyYXBoUUxDb250cm9sbGVyIHx8XG4gICAgICByZXF1aXJlZFBhcmFtZXRlcignWW91IG11c3QgcHJvdmlkZSBhIHBhcnNlR3JhcGhRTENvbnRyb2xsZXIgaW5zdGFuY2UhJyk7XG4gICAgdGhpcy5kYXRhYmFzZUNvbnRyb2xsZXIgPVxuICAgICAgcGFyYW1zLmRhdGFiYXNlQ29udHJvbGxlciB8fFxuICAgICAgcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYSBkYXRhYmFzZUNvbnRyb2xsZXIgaW5zdGFuY2UhJyk7XG4gICAgdGhpcy5sb2cgPSBwYXJhbXMubG9nIHx8IHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGEgbG9nIGluc3RhbmNlIScpO1xuICAgIHRoaXMuZ3JhcGhRTEN1c3RvbVR5cGVEZWZzID0gcGFyYW1zLmdyYXBoUUxDdXN0b21UeXBlRGVmcztcbiAgICB0aGlzLmFwcElkID0gcGFyYW1zLmFwcElkIHx8IHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIHRoZSBhcHBJZCEnKTtcbiAgfVxuXG4gIGFzeW5jIGxvYWQoKSB7XG4gICAgY29uc3QgeyBwYXJzZUdyYXBoUUxDb25maWcgfSA9IGF3YWl0IHRoaXMuX2luaXRpYWxpemVTY2hlbWFBbmRDb25maWcoKTtcbiAgICBjb25zdCBwYXJzZUNsYXNzZXMgPSBhd2FpdCB0aGlzLl9nZXRDbGFzc2VzRm9yU2NoZW1hKHBhcnNlR3JhcGhRTENvbmZpZyk7XG4gICAgY29uc3QgcGFyc2VDbGFzc2VzU3RyaW5nID0gSlNPTi5zdHJpbmdpZnkocGFyc2VDbGFzc2VzKTtcbiAgICBjb25zdCBmdW5jdGlvbk5hbWVzID0gYXdhaXQgdGhpcy5fZ2V0RnVuY3Rpb25OYW1lcygpO1xuICAgIGNvbnN0IGZ1bmN0aW9uTmFtZXNTdHJpbmcgPSBKU09OLnN0cmluZ2lmeShmdW5jdGlvbk5hbWVzKTtcblxuICAgIGlmIChcbiAgICAgIHRoaXMuZ3JhcGhRTFNjaGVtYSAmJlxuICAgICAgIXRoaXMuX2hhc1NjaGVtYUlucHV0Q2hhbmdlZCh7XG4gICAgICAgIHBhcnNlQ2xhc3NlcyxcbiAgICAgICAgcGFyc2VDbGFzc2VzU3RyaW5nLFxuICAgICAgICBwYXJzZUdyYXBoUUxDb25maWcsXG4gICAgICAgIGZ1bmN0aW9uTmFtZXNTdHJpbmcsXG4gICAgICB9KVxuICAgICkge1xuICAgICAgcmV0dXJuIHRoaXMuZ3JhcGhRTFNjaGVtYTtcbiAgICB9XG5cbiAgICB0aGlzLnBhcnNlQ2xhc3NlcyA9IHBhcnNlQ2xhc3NlcztcbiAgICB0aGlzLnBhcnNlQ2xhc3Nlc1N0cmluZyA9IHBhcnNlQ2xhc3Nlc1N0cmluZztcbiAgICB0aGlzLnBhcnNlR3JhcGhRTENvbmZpZyA9IHBhcnNlR3JhcGhRTENvbmZpZztcbiAgICB0aGlzLmZ1bmN0aW9uTmFtZXMgPSBmdW5jdGlvbk5hbWVzO1xuICAgIHRoaXMuZnVuY3Rpb25OYW1lc1N0cmluZyA9IGZ1bmN0aW9uTmFtZXNTdHJpbmc7XG4gICAgdGhpcy5wYXJzZUNsYXNzVHlwZXMgPSB7fTtcbiAgICB0aGlzLnZpZXdlclR5cGUgPSBudWxsO1xuICAgIHRoaXMuZ3JhcGhRTEF1dG9TY2hlbWEgPSBudWxsO1xuICAgIHRoaXMuZ3JhcGhRTFNjaGVtYSA9IG51bGw7XG4gICAgdGhpcy5ncmFwaFFMVHlwZXMgPSBbXTtcbiAgICB0aGlzLmdyYXBoUUxRdWVyaWVzID0ge307XG4gICAgdGhpcy5ncmFwaFFMTXV0YXRpb25zID0ge307XG4gICAgdGhpcy5ncmFwaFFMU3Vic2NyaXB0aW9ucyA9IHt9O1xuICAgIHRoaXMuZ3JhcGhRTFNjaGVtYURpcmVjdGl2ZXNEZWZpbml0aW9ucyA9IG51bGw7XG4gICAgdGhpcy5ncmFwaFFMU2NoZW1hRGlyZWN0aXZlcyA9IHt9O1xuICAgIHRoaXMucmVsYXlOb2RlSW50ZXJmYWNlID0gbnVsbDtcblxuICAgIGRlZmF1bHRHcmFwaFFMVHlwZXMubG9hZCh0aGlzKTtcbiAgICBkZWZhdWx0UmVsYXlTY2hlbWEubG9hZCh0aGlzKTtcbiAgICBzY2hlbWFUeXBlcy5sb2FkKHRoaXMpO1xuXG4gICAgdGhpcy5fZ2V0UGFyc2VDbGFzc2VzV2l0aENvbmZpZyhwYXJzZUNsYXNzZXMsIHBhcnNlR3JhcGhRTENvbmZpZykuZm9yRWFjaChcbiAgICAgIChbcGFyc2VDbGFzcywgcGFyc2VDbGFzc0NvbmZpZ10pID0+IHtcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzLmxvYWQodGhpcywgcGFyc2VDbGFzcywgcGFyc2VDbGFzc0NvbmZpZyk7XG4gICAgICAgIHBhcnNlQ2xhc3NRdWVyaWVzLmxvYWQodGhpcywgcGFyc2VDbGFzcywgcGFyc2VDbGFzc0NvbmZpZyk7XG4gICAgICAgIHBhcnNlQ2xhc3NNdXRhdGlvbnMubG9hZCh0aGlzLCBwYXJzZUNsYXNzLCBwYXJzZUNsYXNzQ29uZmlnKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgZGVmYXVsdEdyYXBoUUxUeXBlcy5sb2FkQXJyYXlSZXN1bHQodGhpcywgcGFyc2VDbGFzc2VzKTtcbiAgICBkZWZhdWx0R3JhcGhRTFF1ZXJpZXMubG9hZCh0aGlzKTtcbiAgICBkZWZhdWx0R3JhcGhRTE11dGF0aW9ucy5sb2FkKHRoaXMpO1xuXG4gICAgbGV0IGdyYXBoUUxRdWVyeSA9IHVuZGVmaW5lZDtcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5ncmFwaFFMUXVlcmllcykubGVuZ3RoID4gMCkge1xuICAgICAgZ3JhcGhRTFF1ZXJ5ID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgICAgICAgbmFtZTogJ1F1ZXJ5JyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdRdWVyeSBpcyB0aGUgdG9wIGxldmVsIHR5cGUgZm9yIHF1ZXJpZXMuJyxcbiAgICAgICAgZmllbGRzOiB0aGlzLmdyYXBoUUxRdWVyaWVzLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmFkZEdyYXBoUUxUeXBlKGdyYXBoUUxRdWVyeSwgdHJ1ZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgbGV0IGdyYXBoUUxNdXRhdGlvbiA9IHVuZGVmaW5lZDtcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5ncmFwaFFMTXV0YXRpb25zKS5sZW5ndGggPiAwKSB7XG4gICAgICBncmFwaFFMTXV0YXRpb24gPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICAgICAgICBuYW1lOiAnTXV0YXRpb24nLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ011dGF0aW9uIGlzIHRoZSB0b3AgbGV2ZWwgdHlwZSBmb3IgbXV0YXRpb25zLicsXG4gICAgICAgIGZpZWxkczogdGhpcy5ncmFwaFFMTXV0YXRpb25zLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmFkZEdyYXBoUUxUeXBlKGdyYXBoUUxNdXRhdGlvbiwgdHJ1ZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgbGV0IGdyYXBoUUxTdWJzY3JpcHRpb24gPSB1bmRlZmluZWQ7XG4gICAgaWYgKE9iamVjdC5rZXlzKHRoaXMuZ3JhcGhRTFN1YnNjcmlwdGlvbnMpLmxlbmd0aCA+IDApIHtcbiAgICAgIGdyYXBoUUxTdWJzY3JpcHRpb24gPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICAgICAgICBuYW1lOiAnU3Vic2NyaXB0aW9uJyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdTdWJzY3JpcHRpb24gaXMgdGhlIHRvcCBsZXZlbCB0eXBlIGZvciBzdWJzY3JpcHRpb25zLicsXG4gICAgICAgIGZpZWxkczogdGhpcy5ncmFwaFFMU3Vic2NyaXB0aW9ucyxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5hZGRHcmFwaFFMVHlwZShncmFwaFFMU3Vic2NyaXB0aW9uLCB0cnVlLCB0cnVlKTtcbiAgICB9XG5cbiAgICB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hID0gbmV3IEdyYXBoUUxTY2hlbWEoe1xuICAgICAgdHlwZXM6IHRoaXMuZ3JhcGhRTFR5cGVzLFxuICAgICAgcXVlcnk6IGdyYXBoUUxRdWVyeSxcbiAgICAgIG11dGF0aW9uOiBncmFwaFFMTXV0YXRpb24sXG4gICAgICBzdWJzY3JpcHRpb246IGdyYXBoUUxTdWJzY3JpcHRpb24sXG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMpIHtcbiAgICAgIHNjaGVtYURpcmVjdGl2ZXMubG9hZCh0aGlzKTtcblxuICAgICAgaWYgKHR5cGVvZiB0aGlzLmdyYXBoUUxDdXN0b21UeXBlRGVmcy5nZXRUeXBlTWFwID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGNvbnN0IGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlTWFwID0gdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMuZ2V0VHlwZU1hcCgpO1xuICAgICAgICBjb25zdCBmaW5kQW5kUmVwbGFjZUxhc3RUeXBlID0gKHBhcmVudCwga2V5KSA9PiB7XG4gICAgICAgICAgaWYgKHBhcmVudFtrZXldLm5hbWUpIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgdGhpcy5ncmFwaFFMQXV0b1NjaGVtYS5nZXRUeXBlKHBhcmVudFtrZXldLm5hbWUpICYmXG4gICAgICAgICAgICAgIHRoaXMuZ3JhcGhRTEF1dG9TY2hlbWEuZ2V0VHlwZShwYXJlbnRba2V5XS5uYW1lKSAhPT0gcGFyZW50W2tleV1cbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAvLyBUbyBhdm9pZCB1bnJlc29sdmVkIGZpZWxkIG9uIG92ZXJsb2FkZWQgc2NoZW1hXG4gICAgICAgICAgICAgIC8vIHJlcGxhY2UgdGhlIGZpbmFsIHR5cGUgd2l0aCB0aGUgYXV0byBzY2hlbWEgb25lXG4gICAgICAgICAgICAgIHBhcmVudFtrZXldID0gdGhpcy5ncmFwaFFMQXV0b1NjaGVtYS5nZXRUeXBlKHBhcmVudFtrZXldLm5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAocGFyZW50W2tleV0ub2ZUeXBlKSB7XG4gICAgICAgICAgICAgIGZpbmRBbmRSZXBsYWNlTGFzdFR5cGUocGFyZW50W2tleV0sICdvZlR5cGUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIE9iamVjdC52YWx1ZXMoY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGVNYXApLmZvckVhY2goY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGUgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICFjdXN0b21HcmFwaFFMU2NoZW1hVHlwZSB8fFxuICAgICAgICAgICAgIWN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLm5hbWUgfHxcbiAgICAgICAgICAgIGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLm5hbWUuc3RhcnRzV2l0aCgnX18nKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBhdXRvR3JhcGhRTFNjaGVtYVR5cGUgPSB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hLmdldFR5cGUoXG4gICAgICAgICAgICBjdXN0b21HcmFwaFFMU2NoZW1hVHlwZS5uYW1lXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoIWF1dG9HcmFwaFFMU2NoZW1hVHlwZSkge1xuICAgICAgICAgICAgdGhpcy5ncmFwaFFMQXV0b1NjaGVtYS5fdHlwZU1hcFtjdXN0b21HcmFwaFFMU2NoZW1hVHlwZS5uYW1lXSA9IGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIE9iamVjdC52YWx1ZXMoY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGVNYXApLmZvckVhY2goY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGUgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICFjdXN0b21HcmFwaFFMU2NoZW1hVHlwZSB8fFxuICAgICAgICAgICAgIWN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLm5hbWUgfHxcbiAgICAgICAgICAgIGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLm5hbWUuc3RhcnRzV2l0aCgnX18nKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBhdXRvR3JhcGhRTFNjaGVtYVR5cGUgPSB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hLmdldFR5cGUoXG4gICAgICAgICAgICBjdXN0b21HcmFwaFFMU2NoZW1hVHlwZS5uYW1lXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGlmIChhdXRvR3JhcGhRTFNjaGVtYVR5cGUgJiYgdHlwZW9mIGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLmdldEZpZWxkcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgT2JqZWN0LnZhbHVlcyhjdXN0b21HcmFwaFFMU2NoZW1hVHlwZS5nZXRGaWVsZHMoKSkuZm9yRWFjaChmaWVsZCA9PiB7XG4gICAgICAgICAgICAgIGZpbmRBbmRSZXBsYWNlTGFzdFR5cGUoZmllbGQsICd0eXBlJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGF1dG9HcmFwaFFMU2NoZW1hVHlwZS5fZmllbGRzID0ge1xuICAgICAgICAgICAgICAuLi5hdXRvR3JhcGhRTFNjaGVtYVR5cGUuZ2V0RmllbGRzKCksXG4gICAgICAgICAgICAgIC4uLmN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLmdldEZpZWxkcygpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmdyYXBoUUxTY2hlbWEgPSBzdGl0Y2hTY2hlbWFzKHtcbiAgICAgICAgICBzY2hlbWFzOiBbdGhpcy5ncmFwaFFMU2NoZW1hRGlyZWN0aXZlc0RlZmluaXRpb25zLCB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hXSxcbiAgICAgICAgICBtZXJnZURpcmVjdGl2ZXM6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5ncmFwaFFMU2NoZW1hID0gYXdhaXQgdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMoe1xuICAgICAgICAgIGRpcmVjdGl2ZXNEZWZpbml0aW9uc1NjaGVtYTogdGhpcy5ncmFwaFFMU2NoZW1hRGlyZWN0aXZlc0RlZmluaXRpb25zLFxuICAgICAgICAgIGF1dG9TY2hlbWE6IHRoaXMuZ3JhcGhRTEF1dG9TY2hlbWEsXG4gICAgICAgICAgc3RpdGNoU2NoZW1hcyxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmdyYXBoUUxTY2hlbWEgPSBzdGl0Y2hTY2hlbWFzKHtcbiAgICAgICAgICBzY2hlbWFzOiBbXG4gICAgICAgICAgICB0aGlzLmdyYXBoUUxTY2hlbWFEaXJlY3RpdmVzRGVmaW5pdGlvbnMsXG4gICAgICAgICAgICB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hLFxuICAgICAgICAgICAgdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMsXG4gICAgICAgICAgXSxcbiAgICAgICAgICBtZXJnZURpcmVjdGl2ZXM6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBncmFwaFFMU2NoZW1hVHlwZU1hcCA9IHRoaXMuZ3JhcGhRTFNjaGVtYS5nZXRUeXBlTWFwKCk7XG4gICAgICBPYmplY3Qua2V5cyhncmFwaFFMU2NoZW1hVHlwZU1hcCkuZm9yRWFjaChncmFwaFFMU2NoZW1hVHlwZU5hbWUgPT4ge1xuICAgICAgICBjb25zdCBncmFwaFFMU2NoZW1hVHlwZSA9IGdyYXBoUUxTY2hlbWFUeXBlTWFwW2dyYXBoUUxTY2hlbWFUeXBlTmFtZV07XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0eXBlb2YgZ3JhcGhRTFNjaGVtYVR5cGUuZ2V0RmllbGRzID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgICAgdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMuZGVmaW5pdGlvbnNcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgZ3JhcGhRTEN1c3RvbVR5cGVEZWYgPSB0aGlzLmdyYXBoUUxDdXN0b21UeXBlRGVmcy5kZWZpbml0aW9ucy5maW5kKFxuICAgICAgICAgICAgZGVmaW5pdGlvbiA9PiBkZWZpbml0aW9uLm5hbWUudmFsdWUgPT09IGdyYXBoUUxTY2hlbWFUeXBlTmFtZVxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKGdyYXBoUUxDdXN0b21UeXBlRGVmKSB7XG4gICAgICAgICAgICBjb25zdCBncmFwaFFMU2NoZW1hVHlwZUZpZWxkTWFwID0gZ3JhcGhRTFNjaGVtYVR5cGUuZ2V0RmllbGRzKCk7XG4gICAgICAgICAgICBPYmplY3Qua2V5cyhncmFwaFFMU2NoZW1hVHlwZUZpZWxkTWFwKS5mb3JFYWNoKGdyYXBoUUxTY2hlbWFUeXBlRmllbGROYW1lID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZCA9IGdyYXBoUUxTY2hlbWFUeXBlRmllbGRNYXBbZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZE5hbWVdO1xuICAgICAgICAgICAgICBpZiAoIWdyYXBoUUxTY2hlbWFUeXBlRmllbGQuYXN0Tm9kZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFzdE5vZGUgPSBncmFwaFFMQ3VzdG9tVHlwZURlZi5maWVsZHMuZmluZChcbiAgICAgICAgICAgICAgICAgIGZpZWxkID0+IGZpZWxkLm5hbWUudmFsdWUgPT09IGdyYXBoUUxTY2hlbWFUeXBlRmllbGROYW1lXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBpZiAoYXN0Tm9kZSkge1xuICAgICAgICAgICAgICAgICAgZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZC5hc3ROb2RlID0gYXN0Tm9kZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIFNjaGVtYURpcmVjdGl2ZVZpc2l0b3IudmlzaXRTY2hlbWFEaXJlY3RpdmVzKFxuICAgICAgICB0aGlzLmdyYXBoUUxTY2hlbWEsXG4gICAgICAgIHRoaXMuZ3JhcGhRTFNjaGVtYURpcmVjdGl2ZXNcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZ3JhcGhRTFNjaGVtYSA9IHRoaXMuZ3JhcGhRTEF1dG9TY2hlbWE7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZ3JhcGhRTFNjaGVtYTtcbiAgfVxuXG4gIGFkZEdyYXBoUUxUeXBlKHR5cGUsIHRocm93RXJyb3IgPSBmYWxzZSwgaWdub3JlUmVzZXJ2ZWQgPSBmYWxzZSwgaWdub3JlQ29ubmVjdGlvbiA9IGZhbHNlKSB7XG4gICAgaWYgKFxuICAgICAgKCFpZ25vcmVSZXNlcnZlZCAmJiBSRVNFUlZFRF9HUkFQSFFMX1RZUEVfTkFNRVMuaW5jbHVkZXModHlwZS5uYW1lKSkgfHxcbiAgICAgIHRoaXMuZ3JhcGhRTFR5cGVzLmZpbmQoZXhpc3RpbmdUeXBlID0+IGV4aXN0aW5nVHlwZS5uYW1lID09PSB0eXBlLm5hbWUpIHx8XG4gICAgICAoIWlnbm9yZUNvbm5lY3Rpb24gJiYgdHlwZS5uYW1lLmVuZHNXaXRoKCdDb25uZWN0aW9uJykpXG4gICAgKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gYFR5cGUgJHt0eXBlLm5hbWV9IGNvdWxkIG5vdCBiZSBhZGRlZCB0byB0aGUgYXV0byBzY2hlbWEgYmVjYXVzZSBpdCBjb2xsaWRlZCB3aXRoIGFuIGV4aXN0aW5nIHR5cGUuYDtcbiAgICAgIGlmICh0aHJvd0Vycm9yKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubG9nLndhcm4obWVzc2FnZSk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICB0aGlzLmdyYXBoUUxUeXBlcy5wdXNoKHR5cGUpO1xuICAgIHJldHVybiB0eXBlO1xuICB9XG5cbiAgYWRkR3JhcGhRTFF1ZXJ5KGZpZWxkTmFtZSwgZmllbGQsIHRocm93RXJyb3IgPSBmYWxzZSwgaWdub3JlUmVzZXJ2ZWQgPSBmYWxzZSkge1xuICAgIGlmIChcbiAgICAgICghaWdub3JlUmVzZXJ2ZWQgJiYgUkVTRVJWRURfR1JBUEhRTF9RVUVSWV9OQU1FUy5pbmNsdWRlcyhmaWVsZE5hbWUpKSB8fFxuICAgICAgdGhpcy5ncmFwaFFMUXVlcmllc1tmaWVsZE5hbWVdXG4gICAgKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gYFF1ZXJ5ICR7ZmllbGROYW1lfSBjb3VsZCBub3QgYmUgYWRkZWQgdG8gdGhlIGF1dG8gc2NoZW1hIGJlY2F1c2UgaXQgY29sbGlkZWQgd2l0aCBhbiBleGlzdGluZyBmaWVsZC5gO1xuICAgICAgaWYgKHRocm93RXJyb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2cud2FybihtZXNzYWdlKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRoaXMuZ3JhcGhRTFF1ZXJpZXNbZmllbGROYW1lXSA9IGZpZWxkO1xuICAgIHJldHVybiBmaWVsZDtcbiAgfVxuXG4gIGFkZEdyYXBoUUxNdXRhdGlvbihmaWVsZE5hbWUsIGZpZWxkLCB0aHJvd0Vycm9yID0gZmFsc2UsIGlnbm9yZVJlc2VydmVkID0gZmFsc2UpIHtcbiAgICBpZiAoXG4gICAgICAoIWlnbm9yZVJlc2VydmVkICYmIFJFU0VSVkVEX0dSQVBIUUxfTVVUQVRJT05fTkFNRVMuaW5jbHVkZXMoZmllbGROYW1lKSkgfHxcbiAgICAgIHRoaXMuZ3JhcGhRTE11dGF0aW9uc1tmaWVsZE5hbWVdXG4gICAgKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gYE11dGF0aW9uICR7ZmllbGROYW1lfSBjb3VsZCBub3QgYmUgYWRkZWQgdG8gdGhlIGF1dG8gc2NoZW1hIGJlY2F1c2UgaXQgY29sbGlkZWQgd2l0aCBhbiBleGlzdGluZyBmaWVsZC5gO1xuICAgICAgaWYgKHRocm93RXJyb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2cud2FybihtZXNzYWdlKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRoaXMuZ3JhcGhRTE11dGF0aW9uc1tmaWVsZE5hbWVdID0gZmllbGQ7XG4gICAgcmV0dXJuIGZpZWxkO1xuICB9XG5cbiAgaGFuZGxlRXJyb3IoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBQYXJzZS5FcnJvcikge1xuICAgICAgdGhpcy5sb2cuZXJyb3IoJ1BhcnNlIGVycm9yOiAnLCBlcnJvcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubG9nLmVycm9yKCdVbmNhdWdodCBpbnRlcm5hbCBzZXJ2ZXIgZXJyb3IuJywgZXJyb3IsIGVycm9yLnN0YWNrKTtcbiAgICB9XG4gICAgdGhyb3cgdG9HcmFwaFFMRXJyb3IoZXJyb3IpO1xuICB9XG5cbiAgYXN5bmMgX2luaXRpYWxpemVTY2hlbWFBbmRDb25maWcoKSB7XG4gICAgY29uc3QgW3NjaGVtYUNvbnRyb2xsZXIsIHBhcnNlR3JhcGhRTENvbmZpZ10gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICB0aGlzLmRhdGFiYXNlQ29udHJvbGxlci5sb2FkU2NoZW1hKCksXG4gICAgICB0aGlzLnBhcnNlR3JhcGhRTENvbnRyb2xsZXIuZ2V0R3JhcGhRTENvbmZpZygpLFxuICAgIF0pO1xuXG4gICAgdGhpcy5zY2hlbWFDb250cm9sbGVyID0gc2NoZW1hQ29udHJvbGxlcjtcblxuICAgIHJldHVybiB7XG4gICAgICBwYXJzZUdyYXBoUUxDb25maWcsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGFsbCBjbGFzc2VzIGZvdW5kIGJ5IHRoZSBgc2NoZW1hQ29udHJvbGxlcmBcbiAgICogbWludXMgdGhvc2UgZmlsdGVyZWQgb3V0IGJ5IHRoZSBhcHAncyBwYXJzZUdyYXBoUUxDb25maWcuXG4gICAqL1xuICBhc3luYyBfZ2V0Q2xhc3Nlc0ZvclNjaGVtYShwYXJzZUdyYXBoUUxDb25maWc6IFBhcnNlR3JhcGhRTENvbmZpZykge1xuICAgIGNvbnN0IHsgZW5hYmxlZEZvckNsYXNzZXMsIGRpc2FibGVkRm9yQ2xhc3NlcyB9ID0gcGFyc2VHcmFwaFFMQ29uZmlnO1xuICAgIGNvbnN0IGFsbENsYXNzZXMgPSBhd2FpdCB0aGlzLnNjaGVtYUNvbnRyb2xsZXIuZ2V0QWxsQ2xhc3NlcygpO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZW5hYmxlZEZvckNsYXNzZXMpIHx8IEFycmF5LmlzQXJyYXkoZGlzYWJsZWRGb3JDbGFzc2VzKSkge1xuICAgICAgbGV0IGluY2x1ZGVkQ2xhc3NlcyA9IGFsbENsYXNzZXM7XG4gICAgICBpZiAoZW5hYmxlZEZvckNsYXNzZXMpIHtcbiAgICAgICAgaW5jbHVkZWRDbGFzc2VzID0gYWxsQ2xhc3Nlcy5maWx0ZXIoY2xhenogPT4ge1xuICAgICAgICAgIHJldHVybiBlbmFibGVkRm9yQ2xhc3Nlcy5pbmNsdWRlcyhjbGF6ei5jbGFzc05hbWUpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChkaXNhYmxlZEZvckNsYXNzZXMpIHtcbiAgICAgICAgLy8gQ2xhc3NlcyBpbmNsdWRlZCBpbiBgZW5hYmxlZEZvckNsYXNzZXNgIHRoYXRcbiAgICAgICAgLy8gYXJlIGFsc28gcHJlc2VudCBpbiBgZGlzYWJsZWRGb3JDbGFzc2VzYCB3aWxsXG4gICAgICAgIC8vIHN0aWxsIGJlIGZpbHRlcmVkIG91dFxuICAgICAgICBpbmNsdWRlZENsYXNzZXMgPSBpbmNsdWRlZENsYXNzZXMuZmlsdGVyKGNsYXp6ID0+IHtcbiAgICAgICAgICByZXR1cm4gIWRpc2FibGVkRm9yQ2xhc3Nlcy5pbmNsdWRlcyhjbGF6ei5jbGFzc05hbWUpO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5pc1VzZXJzQ2xhc3NEaXNhYmxlZCA9ICFpbmNsdWRlZENsYXNzZXMuc29tZShjbGF6eiA9PiB7XG4gICAgICAgIHJldHVybiBjbGF6ei5jbGFzc05hbWUgPT09ICdfVXNlcic7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGluY2x1ZGVkQ2xhc3NlcztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGFsbENsYXNzZXM7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYSBsaXN0IG9mIHR1cGxlc1xuICAgKiB0aGF0IHByb3ZpZGUgdGhlIHBhcnNlQ2xhc3MgYWxvbmcgd2l0aFxuICAgKiBpdHMgcGFyc2VDbGFzc0NvbmZpZyB3aGVyZSBwcm92aWRlZC5cbiAgICovXG4gIF9nZXRQYXJzZUNsYXNzZXNXaXRoQ29uZmlnKHBhcnNlQ2xhc3NlcywgcGFyc2VHcmFwaFFMQ29uZmlnOiBQYXJzZUdyYXBoUUxDb25maWcpIHtcbiAgICBjb25zdCB7IGNsYXNzQ29uZmlncyB9ID0gcGFyc2VHcmFwaFFMQ29uZmlnO1xuXG4gICAgLy8gTWFrZSBzdXJlcyB0aGF0IHRoZSBkZWZhdWx0IGNsYXNzZXMgYW5kIGNsYXNzZXMgdGhhdFxuICAgIC8vIHN0YXJ0cyB3aXRoIGNhcGl0YWxpemVkIGxldHRlciB3aWxsIGJlIGdlbmVyYXRlZCBmaXJzdC5cbiAgICBjb25zdCBzb3J0Q2xhc3NlcyA9IChhLCBiKSA9PiB7XG4gICAgICBhID0gYS5jbGFzc05hbWU7XG4gICAgICBiID0gYi5jbGFzc05hbWU7XG4gICAgICBpZiAoYVswXSA9PT0gJ18nKSB7XG4gICAgICAgIGlmIChiWzBdICE9PSAnXycpIHtcbiAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChiWzBdID09PSAnXycpIHtcbiAgICAgICAgaWYgKGFbMF0gIT09ICdfJykge1xuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoYSA9PT0gYikge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH0gZWxzZSBpZiAoYSA8IGIpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBwYXJzZUNsYXNzZXMuc29ydChzb3J0Q2xhc3NlcykubWFwKHBhcnNlQ2xhc3MgPT4ge1xuICAgICAgbGV0IHBhcnNlQ2xhc3NDb25maWc7XG4gICAgICBpZiAoY2xhc3NDb25maWdzKSB7XG4gICAgICAgIHBhcnNlQ2xhc3NDb25maWcgPSBjbGFzc0NvbmZpZ3MuZmluZChjID0+IGMuY2xhc3NOYW1lID09PSBwYXJzZUNsYXNzLmNsYXNzTmFtZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gW3BhcnNlQ2xhc3MsIHBhcnNlQ2xhc3NDb25maWddO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgX2dldEZ1bmN0aW9uTmFtZXMoKSB7XG4gICAgcmV0dXJuIGF3YWl0IGdldEZ1bmN0aW9uTmFtZXModGhpcy5hcHBJZCkuZmlsdGVyKGZ1bmN0aW9uTmFtZSA9PiB7XG4gICAgICBpZiAoL15bX2EtekEtWl1bX2EtekEtWjAtOV0qJC8udGVzdChmdW5jdGlvbk5hbWUpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5sb2cud2FybihcbiAgICAgICAgICBgRnVuY3Rpb24gJHtmdW5jdGlvbk5hbWV9IGNvdWxkIG5vdCBiZSBhZGRlZCB0byB0aGUgYXV0byBzY2hlbWEgYmVjYXVzZSBHcmFwaFFMIG5hbWVzIG11c3QgbWF0Y2ggL15bX2EtekEtWl1bX2EtekEtWjAtOV0qJC8uYFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGZvciBjaGFuZ2VzIHRvIHRoZSBwYXJzZUNsYXNzZXNcbiAgICogb2JqZWN0cyAoaS5lLiBkYXRhYmFzZSBzY2hlbWEpIG9yIHRvXG4gICAqIHRoZSBwYXJzZUdyYXBoUUxDb25maWcgb2JqZWN0LiBJZiBub1xuICAgKiBjaGFuZ2VzIGFyZSBmb3VuZCwgcmV0dXJuIHRydWU7XG4gICAqL1xuICBfaGFzU2NoZW1hSW5wdXRDaGFuZ2VkKHBhcmFtczoge1xuICAgIHBhcnNlQ2xhc3NlczogYW55LFxuICAgIHBhcnNlQ2xhc3Nlc1N0cmluZzogc3RyaW5nLFxuICAgIHBhcnNlR3JhcGhRTENvbmZpZzogP1BhcnNlR3JhcGhRTENvbmZpZyxcbiAgICBmdW5jdGlvbk5hbWVzU3RyaW5nOiBzdHJpbmcsXG4gIH0pOiBib29sZWFuIHtcbiAgICBjb25zdCB7IHBhcnNlQ2xhc3NlcywgcGFyc2VDbGFzc2VzU3RyaW5nLCBwYXJzZUdyYXBoUUxDb25maWcsIGZ1bmN0aW9uTmFtZXNTdHJpbmcgfSA9IHBhcmFtcztcblxuICAgIGlmIChcbiAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMucGFyc2VHcmFwaFFMQ29uZmlnKSA9PT0gSlNPTi5zdHJpbmdpZnkocGFyc2VHcmFwaFFMQ29uZmlnKSAmJlxuICAgICAgdGhpcy5mdW5jdGlvbk5hbWVzU3RyaW5nID09PSBmdW5jdGlvbk5hbWVzU3RyaW5nXG4gICAgKSB7XG4gICAgICBpZiAodGhpcy5wYXJzZUNsYXNzZXMgPT09IHBhcnNlQ2xhc3Nlcykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnBhcnNlQ2xhc3Nlc1N0cmluZyA9PT0gcGFyc2VDbGFzc2VzU3RyaW5nKSB7XG4gICAgICAgIHRoaXMucGFyc2VDbGFzc2VzID0gcGFyc2VDbGFzc2VzO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cblxuZXhwb3J0IHsgUGFyc2VHcmFwaFFMU2NoZW1hIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/ParseGraphQLServer.js b/lib/GraphQL/ParseGraphQLServer.js new file mode 100644 index 0000000000..3025e6ae74 --- /dev/null +++ b/lib/GraphQL/ParseGraphQLServer.js @@ -0,0 +1,140 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ParseGraphQLServer = void 0; + +var _cors = _interopRequireDefault(require("cors")); + +var _bodyParser = _interopRequireDefault(require("body-parser")); + +var _graphqlUpload = require("graphql-upload"); + +var _expressApollo = require("apollo-server-express/dist/expressApollo"); + +var _graphqlPlaygroundHtml = require("@apollographql/graphql-playground-html"); + +var _graphql = require("graphql"); + +var _subscriptionsTransportWs = require("subscriptions-transport-ws"); + +var _middlewares = require("../middlewares"); + +var _requiredParameter = _interopRequireDefault(require("../requiredParameter")); + +var _logger = _interopRequireDefault(require("../logger")); + +var _ParseGraphQLSchema = require("./ParseGraphQLSchema"); + +var _ParseGraphQLController = _interopRequireWildcard(require("../Controllers/ParseGraphQLController")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class ParseGraphQLServer { + constructor(parseServer, config) { + this.parseServer = parseServer || (0, _requiredParameter.default)('You must provide a parseServer instance!'); + + if (!config || !config.graphQLPath) { + (0, _requiredParameter.default)('You must provide a config.graphQLPath!'); + } + + this.config = config; + this.parseGraphQLController = this.parseServer.config.parseGraphQLController; + this.log = this.parseServer.config && this.parseServer.config.loggerController || _logger.default; + this.parseGraphQLSchema = new _ParseGraphQLSchema.ParseGraphQLSchema({ + parseGraphQLController: this.parseGraphQLController, + databaseController: this.parseServer.config.databaseController, + log: this.log, + graphQLCustomTypeDefs: this.config.graphQLCustomTypeDefs, + appId: this.parseServer.config.appId + }); + } + + async _getGraphQLOptions(req) { + try { + return { + schema: await this.parseGraphQLSchema.load(), + context: { + info: req.info, + config: req.config, + auth: req.auth + }, + formatError: error => { + // Allow to console.log here to debug + return error; + } + }; + } catch (e) { + this.log.error(e.stack || typeof e.toString === 'function' && e.toString() || e); + throw e; + } + } + + _transformMaxUploadSizeToBytes(maxUploadSize) { + const unitMap = { + kb: 1, + mb: 2, + gb: 3 + }; + return Number(maxUploadSize.slice(0, -2)) * Math.pow(1024, unitMap[maxUploadSize.slice(-2).toLowerCase()]); + } + + applyGraphQL(app) { + if (!app || !app.use) { + (0, _requiredParameter.default)('You must provide an Express.js app instance!'); + } + + app.use(this.config.graphQLPath, (0, _graphqlUpload.graphqlUploadExpress)({ + maxFileSize: this._transformMaxUploadSizeToBytes(this.parseServer.config.maxUploadSize || '20mb') + })); + app.use(this.config.graphQLPath, (0, _cors.default)()); + app.use(this.config.graphQLPath, _bodyParser.default.json()); + app.use(this.config.graphQLPath, _middlewares.handleParseHeaders); + app.use(this.config.graphQLPath, _middlewares.handleParseErrors); + app.use(this.config.graphQLPath, (0, _expressApollo.graphqlExpress)(async req => await this._getGraphQLOptions(req))); + } + + applyPlayground(app) { + if (!app || !app.get) { + (0, _requiredParameter.default)('You must provide an Express.js app instance!'); + } + + app.get(this.config.playgroundPath || (0, _requiredParameter.default)('You must provide a config.playgroundPath to applyPlayground!'), (_req, res) => { + res.setHeader('Content-Type', 'text/html'); + res.write((0, _graphqlPlaygroundHtml.renderPlaygroundPage)({ + endpoint: this.config.graphQLPath, + version: '1.7.25', + subscriptionEndpoint: this.config.subscriptionsPath, + headers: { + 'X-Parse-Application-Id': this.parseServer.config.appId, + 'X-Parse-Master-Key': this.parseServer.config.masterKey + } + })); + res.end(); + }); + } + + createSubscriptions(server) { + _subscriptionsTransportWs.SubscriptionServer.create({ + execute: _graphql.execute, + subscribe: _graphql.subscribe, + onOperation: async (_message, params, webSocket) => Object.assign({}, params, await this._getGraphQLOptions(webSocket.upgradeReq)) + }, { + server, + path: this.config.subscriptionsPath || (0, _requiredParameter.default)('You must provide a config.subscriptionsPath to createSubscriptions!') + }); + } + + setGraphQLConfig(graphQLConfig) { + return this.parseGraphQLController.updateGraphQLConfig(graphQLConfig); + } + +} + +exports.ParseGraphQLServer = ParseGraphQLServer; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9HcmFwaFFML1BhcnNlR3JhcGhRTFNlcnZlci5qcyJdLCJuYW1lcyI6WyJQYXJzZUdyYXBoUUxTZXJ2ZXIiLCJjb25zdHJ1Y3RvciIsInBhcnNlU2VydmVyIiwiY29uZmlnIiwiZ3JhcGhRTFBhdGgiLCJwYXJzZUdyYXBoUUxDb250cm9sbGVyIiwibG9nIiwibG9nZ2VyQ29udHJvbGxlciIsImRlZmF1bHRMb2dnZXIiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJQYXJzZUdyYXBoUUxTY2hlbWEiLCJkYXRhYmFzZUNvbnRyb2xsZXIiLCJncmFwaFFMQ3VzdG9tVHlwZURlZnMiLCJhcHBJZCIsIl9nZXRHcmFwaFFMT3B0aW9ucyIsInJlcSIsInNjaGVtYSIsImxvYWQiLCJjb250ZXh0IiwiaW5mbyIsImF1dGgiLCJmb3JtYXRFcnJvciIsImVycm9yIiwiZSIsInN0YWNrIiwidG9TdHJpbmciLCJfdHJhbnNmb3JtTWF4VXBsb2FkU2l6ZVRvQnl0ZXMiLCJtYXhVcGxvYWRTaXplIiwidW5pdE1hcCIsImtiIiwibWIiLCJnYiIsIk51bWJlciIsInNsaWNlIiwiTWF0aCIsInBvdyIsInRvTG93ZXJDYXNlIiwiYXBwbHlHcmFwaFFMIiwiYXBwIiwidXNlIiwibWF4RmlsZVNpemUiLCJib2R5UGFyc2VyIiwianNvbiIsImhhbmRsZVBhcnNlSGVhZGVycyIsImhhbmRsZVBhcnNlRXJyb3JzIiwiYXBwbHlQbGF5Z3JvdW5kIiwiZ2V0IiwicGxheWdyb3VuZFBhdGgiLCJfcmVxIiwicmVzIiwic2V0SGVhZGVyIiwid3JpdGUiLCJlbmRwb2ludCIsInZlcnNpb24iLCJzdWJzY3JpcHRpb25FbmRwb2ludCIsInN1YnNjcmlwdGlvbnNQYXRoIiwiaGVhZGVycyIsIm1hc3RlcktleSIsImVuZCIsImNyZWF0ZVN1YnNjcmlwdGlvbnMiLCJzZXJ2ZXIiLCJTdWJzY3JpcHRpb25TZXJ2ZXIiLCJjcmVhdGUiLCJleGVjdXRlIiwic3Vic2NyaWJlIiwib25PcGVyYXRpb24iLCJfbWVzc2FnZSIsInBhcmFtcyIsIndlYlNvY2tldCIsIk9iamVjdCIsImFzc2lnbiIsInVwZ3JhZGVSZXEiLCJwYXRoIiwic2V0R3JhcGhRTENvbmZpZyIsImdyYXBoUUxDb25maWciLCJ1cGRhdGVHcmFwaFFMQ29uZmlnIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBRUEsTUFBTUEsa0JBQU4sQ0FBeUI7QUFHdkJDLEVBQUFBLFdBQVcsQ0FBQ0MsV0FBRCxFQUFjQyxNQUFkLEVBQXNCO0FBQy9CLFNBQUtELFdBQUwsR0FBbUJBLFdBQVcsSUFBSSxnQ0FBa0IsMENBQWxCLENBQWxDOztBQUNBLFFBQUksQ0FBQ0MsTUFBRCxJQUFXLENBQUNBLE1BQU0sQ0FBQ0MsV0FBdkIsRUFBb0M7QUFDbEMsc0NBQWtCLHdDQUFsQjtBQUNEOztBQUNELFNBQUtELE1BQUwsR0FBY0EsTUFBZDtBQUNBLFNBQUtFLHNCQUFMLEdBQThCLEtBQUtILFdBQUwsQ0FBaUJDLE1BQWpCLENBQXdCRSxzQkFBdEQ7QUFDQSxTQUFLQyxHQUFMLEdBQ0csS0FBS0osV0FBTCxDQUFpQkMsTUFBakIsSUFBMkIsS0FBS0QsV0FBTCxDQUFpQkMsTUFBakIsQ0FBd0JJLGdCQUFwRCxJQUF5RUMsZUFEM0U7QUFFQSxTQUFLQyxrQkFBTCxHQUEwQixJQUFJQyxzQ0FBSixDQUF1QjtBQUMvQ0wsTUFBQUEsc0JBQXNCLEVBQUUsS0FBS0Esc0JBRGtCO0FBRS9DTSxNQUFBQSxrQkFBa0IsRUFBRSxLQUFLVCxXQUFMLENBQWlCQyxNQUFqQixDQUF3QlEsa0JBRkc7QUFHL0NMLE1BQUFBLEdBQUcsRUFBRSxLQUFLQSxHQUhxQztBQUkvQ00sTUFBQUEscUJBQXFCLEVBQUUsS0FBS1QsTUFBTCxDQUFZUyxxQkFKWTtBQUsvQ0MsTUFBQUEsS0FBSyxFQUFFLEtBQUtYLFdBQUwsQ0FBaUJDLE1BQWpCLENBQXdC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QixDQUFnREQsYUFBaEQsQ0FBUDtBQUNEOztBQXpIc0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY29yc01pZGRsZXdhcmUgZnJvbSAnY29ycyc7XG5pbXBvcnQgYm9keVBhcnNlciBmcm9tICdib2R5LXBhcnNlcic7XG5pbXBvcnQgeyBncmFwaHFsVXBsb2FkRXhwcmVzcyB9IGZyb20gJ2dyYXBocWwtdXBsb2FkJztcbmltcG9ydCB7IGdyYXBocWxFeHByZXNzIH0gZnJvbSAnYXBvbGxvLXNlcnZlci1leHByZXNzL2Rpc3QvZXhwcmVzc0Fwb2xsbyc7XG5pbXBvcnQgeyByZW5kZXJQbGF5Z3JvdW5kUGFnZSB9IGZyb20gJ0BhcG9sbG9ncmFwaHFsL2dyYXBocWwtcGxheWdyb3VuZC1odG1sJztcbmltcG9ydCB7IGV4ZWN1dGUsIHN1YnNjcmliZSB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uU2VydmVyIH0gZnJvbSAnc3Vic2NyaXB0aW9ucy10cmFuc3BvcnQtd3MnO1xuaW1wb3J0IHsgaGFuZGxlUGFyc2VFcnJvcnMsIGhhbmRsZVBhcnNlSGVhZGVycyB9IGZyb20gJy4uL21pZGRsZXdhcmVzJztcbmltcG9ydCByZXF1aXJlZFBhcmFtZXRlciBmcm9tICcuLi9yZXF1aXJlZFBhcmFtZXRlcic7XG5pbXBvcnQgZGVmYXVsdExvZ2dlciBmcm9tICcuLi9sb2dnZXInO1xuaW1wb3J0IHsgUGFyc2VHcmFwaFFMU2NoZW1hIH0gZnJvbSAnLi9QYXJzZUdyYXBoUUxTY2hlbWEnO1xuaW1wb3J0IFBhcnNlR3JhcGhRTENvbnRyb2xsZXIsIHsgUGFyc2VHcmFwaFFMQ29uZmlnIH0gZnJvbSAnLi4vQ29udHJvbGxlcnMvUGFyc2VHcmFwaFFMQ29udHJvbGxlcic7XG5cbmNsYXNzIFBhcnNlR3JhcGhRTFNlcnZlciB7XG4gIHBhcnNlR3JhcGhRTENvbnRyb2xsZXI6IFBhcnNlR3JhcGhRTENvbnRyb2xsZXI7XG5cbiAgY29uc3RydWN0b3IocGFyc2VTZXJ2ZXIsIGNvbmZpZykge1xuICAgIHRoaXMucGFyc2VTZXJ2ZXIgPSBwYXJzZVNlcnZlciB8fCByZXF1aXJlZFBhcmFtZXRlcignWW91IG11c3QgcHJvdmlkZSBhIHBhcnNlU2VydmVyIGluc3RhbmNlIScpO1xuICAgIGlmICghY29uZmlnIHx8ICFjb25maWcuZ3JhcGhRTFBhdGgpIHtcbiAgICAgIHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGEgY29uZmlnLmdyYXBoUUxQYXRoIScpO1xuICAgIH1cbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICB0aGlzLnBhcnNlR3JhcGhRTENvbnRyb2xsZXIgPSB0aGlzLnBhcnNlU2VydmVyLmNvbmZpZy5wYXJzZUdyYXBoUUxDb250cm9sbGVyO1xuICAgIHRoaXMubG9nID1cbiAgICAgICh0aGlzLnBhcnNlU2VydmVyLmNvbmZpZyAmJiB0aGlzLnBhcnNlU2VydmVyLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyKSB8fCBkZWZhdWx0TG9nZ2VyO1xuICAgIHRoaXMucGFyc2VHcmFwaFFMU2NoZW1hID0gbmV3IFBhcnNlR3JhcGhRTFNjaGVtYSh7XG4gICAgICBwYXJzZUdyYXBoUUxDb250cm9sbGVyOiB0aGlzLnBhcnNlR3JhcGhRTENvbnRyb2xsZXIsXG4gICAgICBkYXRhYmFzZUNvbnRyb2xsZXI6IHRoaXMucGFyc2VTZXJ2ZXIuY29uZmlnLmRhdGFiYXNlQ29udHJvbGxlcixcbiAgICAgIGxvZzogdGhpcy5sb2csXG4gICAgICBncmFwaFFMQ3VzdG9tVHlwZURlZnM6IHRoaXMuY29uZmlnLmdyYXBoUUxDdXN0b21UeXBlRGVmcyxcbiAgICAgIGFwcElkOiB0aGlzLnBhcnNlU2VydmVyLmNvbmZpZy5hcHBJZCxcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIF9nZXRHcmFwaFFMT3B0aW9ucyhyZXEpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc2NoZW1hOiBhd2FpdCB0aGlzLnBhcnNlR3JhcGhRTFNjaGVtYS5sb2FkKCksXG4gICAgICAgIGNvbnRleHQ6IHtcbiAgICAgICAgICBpbmZvOiByZXEuaW5mbyxcbiAgICAgICAgICBjb25maWc6IHJlcS5jb25maWcsXG4gICAgICAgICAgYXV0aDogcmVxLmF1dGgsXG4gICAgICAgIH0sXG4gICAgICAgIGZvcm1hdEVycm9yOiBlcnJvciA9PiB7XG4gICAgICAgICAgLy8gQWxsb3cgdG8gY29uc29sZS5sb2cgaGVyZSB0byBkZWJ1Z1xuICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5sb2cuZXJyb3IoZS5zdGFjayB8fCAodHlwZW9mIGUudG9TdHJpbmcgPT09ICdmdW5jdGlvbicgJiYgZS50b1N0cmluZygpKSB8fCBlKTtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG5cbiAgX3RyYW5zZm9ybU1heFVwbG9hZFNpemVUb0J5dGVzKG1heFVwbG9hZFNpemUpIHtcbiAgICBjb25zdCB1bml0TWFwID0ge1xuICAgICAga2I6IDEsXG4gICAgICBtYjogMixcbiAgICAgIGdiOiAzLFxuICAgIH07XG5cbiAgICByZXR1cm4gKFxuICAgICAgTnVtYmVyKG1heFVwbG9hZFNpemUuc2xpY2UoMCwgLTIpKSAqXG4gICAgICBNYXRoLnBvdygxMDI0LCB1bml0TWFwW21heFVwbG9hZFNpemUuc2xpY2UoLTIpLnRvTG93ZXJDYXNlKCldKVxuICAgICk7XG4gIH1cblxuICBhcHBseUdyYXBoUUwoYXBwKSB7XG4gICAgaWYgKCFhcHAgfHwgIWFwcC51c2UpIHtcbiAgICAgIHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGFuIEV4cHJlc3MuanMgYXBwIGluc3RhbmNlIScpO1xuICAgIH1cblxuICAgIGFwcC51c2UoXG4gICAgICB0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCxcbiAgICAgIGdyYXBocWxVcGxvYWRFeHByZXNzKHtcbiAgICAgICAgbWF4RmlsZVNpemU6IHRoaXMuX3RyYW5zZm9ybU1heFVwbG9hZFNpemVUb0J5dGVzKFxuICAgICAgICAgIHRoaXMucGFyc2VTZXJ2ZXIuY29uZmlnLm1heFVwbG9hZFNpemUgfHwgJzIwbWInXG4gICAgICAgICksXG4gICAgICB9KVxuICAgICk7XG4gICAgYXBwLnVzZSh0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCwgY29yc01pZGRsZXdhcmUoKSk7XG4gICAgYXBwLnVzZSh0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCwgYm9keVBhcnNlci5qc29uKCkpO1xuICAgIGFwcC51c2UodGhpcy5jb25maWcuZ3JhcGhRTFBhdGgsIGhhbmRsZVBhcnNlSGVhZGVycyk7XG4gICAgYXBwLnVzZSh0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCwgaGFuZGxlUGFyc2VFcnJvcnMpO1xuICAgIGFwcC51c2UoXG4gICAgICB0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCxcbiAgICAgIGdyYXBocWxFeHByZXNzKGFzeW5jIHJlcSA9PiBhd2FpdCB0aGlzLl9nZXRHcmFwaFFMT3B0aW9ucyhyZXEpKVxuICAgICk7XG4gIH1cblxuICBhcHBseVBsYXlncm91bmQoYXBwKSB7XG4gICAgaWYgKCFhcHAgfHwgIWFwcC5nZXQpIHtcbiAgICAgIHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGFuIEV4cHJlc3MuanMgYXBwIGluc3RhbmNlIScpO1xuICAgIH1cbiAgICBhcHAuZ2V0KFxuICAgICAgdGhpcy5jb25maWcucGxheWdyb3VuZFBhdGggfHxcbiAgICAgICAgcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYSBjb25maWcucGxheWdyb3VuZFBhdGggdG8gYXBwbHlQbGF5Z3JvdW5kIScpLFxuICAgICAgKF9yZXEsIHJlcykgPT4ge1xuICAgICAgICByZXMuc2V0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAndGV4dC9odG1sJyk7XG4gICAgICAgIHJlcy53cml0ZShcbiAgICAgICAgICByZW5kZXJQbGF5Z3JvdW5kUGFnZSh7XG4gICAgICAgICAgICBlbmRwb2ludDogdGhpcy5jb25maWcuZ3JhcGhRTFBhdGgsXG4gICAgICAgICAgICB2ZXJzaW9uOiAnMS43LjI1JyxcbiAgICAgICAgICAgIHN1YnNjcmlwdGlvbkVuZHBvaW50OiB0aGlzLmNvbmZpZy5zdWJzY3JpcHRpb25zUGF0aCxcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgJ1gtUGFyc2UtQXBwbGljYXRpb24tSWQnOiB0aGlzLnBhcnNlU2VydmVyLmNvbmZpZy5hcHBJZCxcbiAgICAgICAgICAgICAgJ1gtUGFyc2UtTWFzdGVyLUtleSc6IHRoaXMucGFyc2VTZXJ2ZXIuY29uZmlnLm1hc3RlcktleSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBjcmVhdGVTdWJzY3JpcHRpb25zKHNlcnZlcikge1xuICAgIFN1YnNjcmlwdGlvblNlcnZlci5jcmVhdGUoXG4gICAgICB7XG4gICAgICAgIGV4ZWN1dGUsXG4gICAgICAgIHN1YnNjcmliZSxcbiAgICAgICAgb25PcGVyYXRpb246IGFzeW5jIChfbWVzc2FnZSwgcGFyYW1zLCB3ZWJTb2NrZXQpID0+XG4gICAgICAgICAgT2JqZWN0LmFzc2lnbih7fSwgcGFyYW1zLCBhd2FpdCB0aGlzLl9nZXRHcmFwaFFMT3B0aW9ucyh3ZWJTb2NrZXQudXBncmFkZVJlcSkpLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgc2VydmVyLFxuICAgICAgICBwYXRoOlxuICAgICAgICAgIHRoaXMuY29uZmlnLnN1YnNjcmlwdGlvbnNQYXRoIHx8XG4gICAgICAgICAgcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYSBjb25maWcuc3Vic2NyaXB0aW9uc1BhdGggdG8gY3JlYXRlU3Vic2NyaXB0aW9ucyEnKSxcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgc2V0R3JhcGhRTENvbmZpZyhncmFwaFFMQ29uZmlnOiBQYXJzZUdyYXBoUUxDb25maWcpOiBQcm9taXNlIHtcbiAgICByZXR1cm4gdGhpcy5wYXJzZUdyYXBoUUxDb250cm9sbGVyLnVwZGF0ZUdyYXBoUUxDb25maWcoZ3JhcGhRTENvbmZpZyk7XG4gIH1cbn1cblxuZXhwb3J0IHsgUGFyc2VHcmFwaFFMU2VydmVyIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/helpers/objectsMutations.js b/lib/GraphQL/helpers/objectsMutations.js new file mode 100644 index 0000000000..2658a07253 --- /dev/null +++ b/lib/GraphQL/helpers/objectsMutations.js @@ -0,0 +1,40 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.deleteObject = exports.updateObject = exports.createObject = void 0; + +var _rest = _interopRequireDefault(require("../../rest")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const createObject = async (className, fields, config, auth, info) => { + if (!fields) { + fields = {}; + } + + return (await _rest.default.create(config, auth, className, fields, info.clientSDK, info.context)).response; +}; + +exports.createObject = createObject; + +const updateObject = async (className, objectId, fields, config, auth, info) => { + if (!fields) { + fields = {}; + } + + return (await _rest.default.update(config, auth, className, { + objectId + }, fields, info.clientSDK, info.context)).response; +}; + +exports.updateObject = updateObject; + +const deleteObject = async (className, objectId, config, auth, info) => { + await _rest.default.del(config, auth, className, objectId, info.context); + return true; +}; + +exports.deleteObject = deleteObject; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2hlbHBlcnMvb2JqZWN0c011dGF0aW9ucy5qcyJdLCJuYW1lcyI6WyJjcmVhdGVPYmplY3QiLCJjbGFzc05hbWUiLCJmaWVsZHMiLCJjb25maWciLCJhdXRoIiwiaW5mbyIsInJlc3QiLCJjcmVhdGUiLCJjbGllbnRTREsiLCJjb250ZXh0IiwicmVzcG9uc2UiLCJ1cGRhdGVPYmplY3QiLCJvYmplY3RJZCIsInVwZGF0ZSIsImRlbGV0ZU9iamVjdCIsImRlbCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7O0FBRUEsTUFBTUEsWUFBWSxHQUFHLE9BQU9DLFNBQVAsRUFBa0JDLE1BQWxCLEVBQTBCQyxNQUExQixFQUFrQ0MsSUFBbEMsRUFBd0NDLElBQXhDLEtBQWlEO0FBQ3BFLE1BQUksQ0FBQ0gsTUFBTCxFQUFhO0FBQ1hBLElBQUFBLE1BQU0sR0FBRyxFQUFUO0FBQ0Q7O0FBRUQsU0FBTyxDQUFDLE1BQU1JLGNBQUtDLE1BQUwsQ0FBWUosTUFBWixFQUFvQkMsSUFBcEIsRUFBMEJILFNBQTFCLEVBQXFDQyxNQUFyQyxFQUE2Q0csSUFBSSxDQUFDRyxTQUFsRCxFQUE2REgsSUFBSSxDQUFDSSxPQUFsRSxDQUFQLEVBQ0pDLFFBREg7QUFFRCxDQVBEOzs7O0FBU0EsTUFBTUMsWUFBWSxHQUFHLE9BQU9WLFNBQVAsRUFBa0JXLFFBQWxCLEVBQTRCVixNQUE1QixFQUFvQ0MsTUFBcEMsRUFBNENDLElBQTVDLEVBQWtEQyxJQUFsRCxLQUEyRDtBQUM5RSxNQUFJLENBQUNILE1BQUwsRUFBYTtBQUNYQSxJQUFBQSxNQUFNLEdBQUcsRUFBVDtBQUNEOztBQUVELFNBQU8sQ0FDTCxNQUFNSSxjQUFLTyxNQUFMLENBQVlWLE1BQVosRUFBb0JDLElBQXBCLEVBQTBCSCxTQUExQixFQUFxQztBQUFFVyxJQUFBQTtBQUFGLEdBQXJDLEVBQW1EVixNQUFuRCxFQUEyREcsSUFBSSxDQUFDRyxTQUFoRSxFQUEyRUgsSUFBSSxDQUFDSSxPQUFoRixDQURELEVBRUxDLFFBRkY7QUFHRCxDQVJEOzs7O0FBVUEsTUFBTUksWUFBWSxHQUFHLE9BQU9iLFNBQVAsRUFBa0JXLFFBQWxCLEVBQTRCVCxNQUE1QixFQUFvQ0MsSUFBcEMsRUFBMENDLElBQTFDLEtBQW1EO0FBQ3RFLFFBQU1DLGNBQUtTLEdBQUwsQ0FBU1osTUFBVCxFQUFpQkMsSUFBakIsRUFBdUJILFNBQXZCLEVBQWtDVyxRQUFsQyxFQUE0Q1AsSUFBSSxDQUFDSSxPQUFqRCxDQUFOO0FBQ0EsU0FBTyxJQUFQO0FBQ0QsQ0FIRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCByZXN0IGZyb20gJy4uLy4uL3Jlc3QnO1xuXG5jb25zdCBjcmVhdGVPYmplY3QgPSBhc3luYyAoY2xhc3NOYW1lLCBmaWVsZHMsIGNvbmZpZywgYXV0aCwgaW5mbykgPT4ge1xuICBpZiAoIWZpZWxkcykge1xuICAgIGZpZWxkcyA9IHt9O1xuICB9XG5cbiAgcmV0dXJuIChhd2FpdCByZXN0LmNyZWF0ZShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgZmllbGRzLCBpbmZvLmNsaWVudFNESywgaW5mby5jb250ZXh0KSlcbiAgICAucmVzcG9uc2U7XG59O1xuXG5jb25zdCB1cGRhdGVPYmplY3QgPSBhc3luYyAoY2xhc3NOYW1lLCBvYmplY3RJZCwgZmllbGRzLCBjb25maWcsIGF1dGgsIGluZm8pID0+IHtcbiAgaWYgKCFmaWVsZHMpIHtcbiAgICBmaWVsZHMgPSB7fTtcbiAgfVxuXG4gIHJldHVybiAoXG4gICAgYXdhaXQgcmVzdC51cGRhdGUoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIHsgb2JqZWN0SWQgfSwgZmllbGRzLCBpbmZvLmNsaWVudFNESywgaW5mby5jb250ZXh0KVxuICApLnJlc3BvbnNlO1xufTtcblxuY29uc3QgZGVsZXRlT2JqZWN0ID0gYXN5bmMgKGNsYXNzTmFtZSwgb2JqZWN0SWQsIGNvbmZpZywgYXV0aCwgaW5mbykgPT4ge1xuICBhd2FpdCByZXN0LmRlbChjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgb2JqZWN0SWQsIGluZm8uY29udGV4dCk7XG4gIHJldHVybiB0cnVlO1xufTtcblxuZXhwb3J0IHsgY3JlYXRlT2JqZWN0LCB1cGRhdGVPYmplY3QsIGRlbGV0ZU9iamVjdCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/helpers/objectsQueries.js b/lib/GraphQL/helpers/objectsQueries.js new file mode 100644 index 0000000000..ec9decc0b7 --- /dev/null +++ b/lib/GraphQL/helpers/objectsQueries.js @@ -0,0 +1,309 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.needToGetAllKeys = exports.calculateSkipAndLimit = exports.findObjects = exports.getObject = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _graphqlRelay = require("graphql-relay"); + +var _rest = _interopRequireDefault(require("../../rest")); + +var _query = require("../transformers/query"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// Eslint/Prettier conflict + +/* eslint-disable*/ +const needToGetAllKeys = (fields, keys, parseClasses) => keys ? keys.split(',').some(keyName => { + const key = keyName.split('.'); + + if (fields[key[0]]) { + if (fields[key[0]].type === 'Relation') return false; + + if (fields[key[0]].type === 'Pointer') { + const subClass = parseClasses.find(({ + className: parseClassName + }) => fields[key[0]].targetClass === parseClassName); + + if (subClass && subClass.fields[key[1]]) { + // Current sub key is not custom + return false; + } + } else if (!key[1] || fields[key[0]].type === 'Array' || fields[key[0]].type === 'Object') { + // current key is not custom + return false; + } + } // Key not found into Parse Schema so it's custom + + + return true; +}) : true; +/* eslint-enable*/ + + +exports.needToGetAllKeys = needToGetAllKeys; + +const getObject = async (className, objectId, keys, include, readPreference, includeReadPreference, config, auth, info, parseClasses) => { + const options = {}; + + try { + if (!needToGetAllKeys(parseClasses.find(({ + className: parseClassName + }) => className === parseClassName).fields, keys, parseClasses)) { + options.keys = keys; + } + } catch (e) { + console.log(e); + } + + if (include) { + options.include = include; + + if (includeReadPreference) { + options.includeReadPreference = includeReadPreference; + } + } + + if (readPreference) { + options.readPreference = readPreference; + } + + const response = await _rest.default.get(config, auth, className, objectId, options, info.clientSDK, info.context); + + if (!response.results || response.results.length == 0) { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } + + const object = response.results[0]; + + if (className === '_User') { + delete object.sessionToken; + } + + return object; +}; + +exports.getObject = getObject; + +const findObjects = async (className, where, order, skipInput, first, after, last, before, keys, include, includeAll, readPreference, includeReadPreference, subqueryReadPreference, config, auth, info, selectedFields, parseClasses) => { + if (!where) { + where = {}; + } + + (0, _query.transformQueryInputToParse)(where, className, parseClasses); + const skipAndLimitCalculation = calculateSkipAndLimit(skipInput, first, after, last, before, config.maxLimit); + let { + skip + } = skipAndLimitCalculation; + const { + limit, + needToPreCount + } = skipAndLimitCalculation; + let preCount = undefined; + + if (needToPreCount) { + const preCountOptions = { + limit: 0, + count: true + }; + + if (readPreference) { + preCountOptions.readPreference = readPreference; + } + + if (Object.keys(where).length > 0 && subqueryReadPreference) { + preCountOptions.subqueryReadPreference = subqueryReadPreference; + } + + preCount = (await _rest.default.find(config, auth, className, where, preCountOptions, info.clientSDK, info.context)).count; + + if ((skip || 0) + limit < preCount) { + skip = preCount - limit; + } + } + + const options = {}; + + if (selectedFields.find(field => field.startsWith('edges.') || field.startsWith('pageInfo.'))) { + if (limit || limit === 0) { + options.limit = limit; + } else { + options.limit = 100; + } + + if (options.limit !== 0) { + if (order) { + options.order = order; + } + + if (skip) { + options.skip = skip; + } + + if (config.maxLimit && options.limit > config.maxLimit) { + // Silently replace the limit on the query with the max configured + options.limit = config.maxLimit; + } + + if (!needToGetAllKeys(parseClasses.find(({ + className: parseClassName + }) => className === parseClassName).fields, keys, parseClasses)) { + options.keys = keys; + } + + if (includeAll === true) { + options.includeAll = includeAll; + } + + if (!options.includeAll && include) { + options.include = include; + } + + if ((options.includeAll || options.include) && includeReadPreference) { + options.includeReadPreference = includeReadPreference; + } + } + } else { + options.limit = 0; + } + + if ((selectedFields.includes('count') || selectedFields.includes('pageInfo.hasPreviousPage') || selectedFields.includes('pageInfo.hasNextPage')) && !needToPreCount) { + options.count = true; + } + + if (readPreference) { + options.readPreference = readPreference; + } + + if (Object.keys(where).length > 0 && subqueryReadPreference) { + options.subqueryReadPreference = subqueryReadPreference; + } + + let results, count; + + if (options.count || !options.limit || options.limit && options.limit > 0) { + const findResult = await _rest.default.find(config, auth, className, where, options, info.clientSDK, info.context); + results = findResult.results; + count = findResult.count; + } + + let edges = null; + let pageInfo = null; + + if (results) { + edges = results.map((result, index) => ({ + cursor: (0, _graphqlRelay.offsetToCursor)((skip || 0) + index), + node: result + })); + pageInfo = { + hasPreviousPage: (preCount && preCount > 0 || count && count > 0) && skip !== undefined && skip > 0, + startCursor: (0, _graphqlRelay.offsetToCursor)(skip || 0), + endCursor: (0, _graphqlRelay.offsetToCursor)((skip || 0) + (results.length || 1) - 1), + hasNextPage: (preCount || count) > (skip || 0) + results.length + }; + } + + return { + edges, + pageInfo, + count: preCount || count + }; +}; + +exports.findObjects = findObjects; + +const calculateSkipAndLimit = (skipInput, first, after, last, before, maxLimit) => { + let skip = undefined; + let limit = undefined; + let needToPreCount = false; // Validates the skip input + + if (skipInput || skipInput === 0) { + if (skipInput < 0) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Skip should be a positive number'); + } + + skip = skipInput; + } // Validates the after param + + + if (after) { + after = (0, _graphqlRelay.cursorToOffset)(after); + + if (!after && after !== 0 || after < 0) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'After is not a valid cursor'); + } // If skip and after are passed, a new skip is calculated by adding them + + + skip = (skip || 0) + (after + 1); + } // Validates the first param + + + if (first || first === 0) { + if (first < 0) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'First should be a positive number'); + } // The first param is translated to the limit param of the Parse legacy API + + + limit = first; + } // Validates the before param + + + if (before || before === 0) { + // This method converts the cursor to the index of the object + before = (0, _graphqlRelay.cursorToOffset)(before); + + if (!before && before !== 0 || before < 0) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Before is not a valid cursor'); + } + + if ((skip || 0) >= before) { + // If the before index is less then the skip, no objects will be returned + limit = 0; + } else if (!limit && limit !== 0 || (skip || 0) + limit > before) { + // If there is no limit set, the limit is calculated. Or, if the limit (plus skip) is bigger than the before index, the new limit is set. + limit = before - (skip || 0); + } + } // Validates the last param + + + if (last || last === 0) { + if (last < 0) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Last should be a positive number'); + } + + if (last > maxLimit) { + // Last can't be bigger than Parse server maxLimit config. + last = maxLimit; + } + + if (limit || limit === 0) { + // If there is a previous limit set, it may be adjusted + if (last < limit) { + // if last is less than the current limit + skip = (skip || 0) + (limit - last); // The skip is adjusted + + limit = last; // the limit is adjusted + } + } else if (last === 0) { + // No objects will be returned + limit = 0; + } else { + // No previous limit set, the limit will be equal to last and pre count is needed. + limit = last; + needToPreCount = true; + } + } + + return { + skip, + limit, + needToPreCount + }; +}; + +exports.calculateSkipAndLimit = calculateSkipAndLimit; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2hlbHBlcnMvb2JqZWN0c1F1ZXJpZXMuanMiXSwibmFtZXMiOlsibmVlZFRvR2V0QWxsS2V5cyIsImZpZWxkcyIsImtleXMiLCJwYXJzZUNsYXNzZXMiLCJzcGxpdCIsInNvbWUiLCJrZXlOYW1lIiwia2V5IiwidHlwZSIsInN1YkNsYXNzIiwiZmluZCIsImNsYXNzTmFtZSIsInBhcnNlQ2xhc3NOYW1lIiwidGFyZ2V0Q2xhc3MiLCJnZXRPYmplY3QiLCJvYmplY3RJZCIsImluY2x1ZGUiLCJyZWFkUHJlZmVyZW5jZSIsImluY2x1ZGVSZWFkUHJlZmVyZW5jZSIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwib3B0aW9ucyIsImUiLCJjb25zb2xlIiwibG9nIiwicmVzcG9uc2UiLCJyZXN0IiwiZ2V0IiwiY2xpZW50U0RLIiwiY29udGV4dCIsInJlc3VsdHMiLCJsZW5ndGgiLCJQYXJzZSIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsIm9iamVjdCIsInNlc3Npb25Ub2tlbiIsImZpbmRPYmplY3RzIiwid2hlcmUiLCJvcmRlciIsInNraXBJbnB1dCIsImZpcnN0IiwiYWZ0ZXIiLCJsYXN0IiwiYmVmb3JlIiwiaW5jbHVkZUFsbCIsInN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UiLCJzZWxlY3RlZEZpZWxkcyIsInNraXBBbmRMaW1pdENhbGN1bGF0aW9uIiwiY2FsY3VsYXRlU2tpcEFuZExpbWl0IiwibWF4TGltaXQiLCJza2lwIiwibGltaXQiLCJuZWVkVG9QcmVDb3VudCIsInByZUNvdW50IiwidW5kZWZpbmVkIiwicHJlQ291bnRPcHRpb25zIiwiY291bnQiLCJPYmplY3QiLCJmaWVsZCIsInN0YXJ0c1dpdGgiLCJpbmNsdWRlcyIsImZpbmRSZXN1bHQiLCJlZGdlcyIsInBhZ2VJbmZvIiwibWFwIiwicmVzdWx0IiwiaW5kZXgiLCJjdXJzb3IiLCJub2RlIiwiaGFzUHJldmlvdXNQYWdlIiwic3RhcnRDdXJzb3IiLCJl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a0I7QUFDaEI7QUFDQUQsUUFBQUEsSUFBSSxHQUFHLENBQUNBLElBQUksSUFBSSxDQUFULEtBQWVDLEtBQUssR0FBR1QsSUFBdkIsQ0FBUCxDQUZnQixDQUVxQjs7QUFDckNTLFFBQUFBLEtBQUssR0FBR1QsSUFBUixDQUhnQixDQUdGO0FBQ2Y7QUFDRixLQVBELE1BT08sSUFBSUEsSUFBSSxLQUFLLENBQWIsRUFBZ0I7QUFDckI7QUFDQVMsTUFBQUEsS0FBSyxHQUFHLENBQVI7QUFDRCxLQUhNLE1BR0E7QUFDTDtBQUNBQSxNQUFBQSxLQUFLLEdBQUdULElBQVI7QUFDQVUsTUFBQUEsY0FBYyxHQUFHLElBQWpCO0FBQ0Q7QUFDRjs7QUFDRCxTQUFPO0FBQ0xGLElBQUFBLElBREs7QUFFTEMsSUFBQUEsS0FGSztBQUdMQyxJQUFBQTtBQUhLLEdBQVA7QUFLRCxDQW5GRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCB7IG9mZnNldFRvQ3Vyc29yLCBjdXJzb3JUb09mZnNldCB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0IHJlc3QgZnJvbSAnLi4vLi4vcmVzdCc7XG5pbXBvcnQgeyB0cmFuc2Zvcm1RdWVyeUlucHV0VG9QYXJzZSB9IGZyb20gJy4uL3RyYW5zZm9ybWVycy9xdWVyeSc7XG5cbi8vIEVzbGludC9QcmV0dGllciBjb25mbGljdFxuLyogZXNsaW50LWRpc2FibGUqL1xuY29uc3QgbmVlZFRvR2V0QWxsS2V5cyA9IChmaWVsZHMsIGtleXMsIHBhcnNlQ2xhc3NlcykgPT5cbiAga2V5c1xuICAgID8ga2V5cy5zcGxpdCgnLCcpLnNvbWUoa2V5TmFtZSA9PiB7XG4gICAgICAgIGNvbnN0IGtleSA9IGtleU5hbWUuc3BsaXQoJy4nKTtcbiAgICAgICAgaWYgKGZpZWxkc1trZXlbMF1dKSB7XG4gICAgICAgICAgaWYgKGZpZWxkc1trZXlbMF1dLnR5cGUgPT09ICdSZWxhdGlvbicpIHJldHVybiBmYWxzZTtcbiAgICAgICAgICBpZiAoZmllbGRzW2tleVswXV0udHlwZSA9PT0gJ1BvaW50ZXInKSB7XG4gICAgICAgICAgICBjb25zdCBzdWJDbGFzcyA9IHBhcnNlQ2xhc3Nlcy5maW5kKFxuICAgICAgICAgICAgICAoeyBjbGFzc05hbWU6IHBhcnNlQ2xhc3NOYW1lIH0pID0+IGZpZWxkc1trZXlbMF1dLnRhcmdldENsYXNzID09PSBwYXJzZUNsYXNzTmFtZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChzdWJDbGFzcyAmJiBzdWJDbGFzcy5maWVsZHNba2V5WzFdXSkge1xuICAgICAgICAgICAgICAvLyBDdXJyZW50IHN1YiBrZXkgaXMgbm90IGN1c3RvbVxuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgICFrZXlbMV0gfHxcbiAgICAgICAgICAgIGZpZWxkc1trZXlbMF1dLnR5cGUgPT09ICdBcnJheScgfHxcbiAgICAgICAgICAgIGZpZWxkc1trZXlbMF1dLnR5cGUgPT09ICdPYmplY3QnXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICAvLyBjdXJyZW50IGtleSBpcyBub3QgY3VzdG9tXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIEtleSBub3QgZm91bmQgaW50byBQYXJzZSBTY2hlbWEgc28gaXQncyBjdXN0b21cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9KVxuICAgIDogdHJ1ZTtcbi8qIGVzbGludC1lbmFibGUqL1xuXG5jb25zdCBnZXRPYmplY3QgPSBhc3luYyAoXG4gIGNsYXNzTmFtZSxcbiAgb2JqZWN0SWQsXG4gIGtleXMsXG4gIGluY2x1ZGUsXG4gIHJlYWRQcmVmZXJlbmNlLFxuICBpbmNsdWRlUmVhZFByZWZlcmVuY2UsXG4gIGNvbmZpZyxcbiAgYXV0aCxcbiAgaW5mbyxcbiAgcGFyc2VDbGFzc2VzXG4pID0+IHtcbiAgY29uc3Qgb3B0aW9ucyA9IHt9O1xuICB0cnkge1xuICAgIGlmIChcbiAgICAgICFuZWVkVG9HZXRBbGxLZXlzKFxuICAgICAgICBwYXJzZUNsYXNzZXMuZmluZCgoeyBjbGFzc05hbWU6IHBhcnNlQ2xhc3NOYW1lIH0pID0+IGNsYXNzTmFtZSA9PT0gcGFyc2VDbGFzc05hbWUpLmZpZWxkcyxcbiAgICAgICAga2V5cyxcbiAgICAgICAgcGFyc2VDbGFzc2VzXG4gICAgICApXG4gICAgKSB7XG4gICAgICBvcHRpb25zLmtleXMgPSBrZXlzO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUubG9nKGUpO1xuICB9XG4gIGlmIChpbmNsdWRlKSB7XG4gICAgb3B0aW9ucy5pbmNsdWRlID0gaW5jbHVkZTtcbiAgICBpZiAoaW5jbHVkZVJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICBvcHRpb25zLmluY2x1ZGVSZWFkUHJlZmVyZW5jZSA9IGluY2x1ZGVSZWFkUHJlZmVyZW5jZTtcbiAgICB9XG4gIH1cbiAgaWYgKHJlYWRQcmVmZXJlbmNlKSB7XG4gICAgb3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHJlYWRQcmVmZXJlbmNlO1xuICB9XG5cbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCByZXN0LmdldChcbiAgICBjb25maWcsXG4gICAgYXV0aCxcbiAgICBjbGFzc05hbWUsXG4gICAgb2JqZWN0SWQsXG4gICAgb3B0aW9ucyxcbiAgICBpbmZvLmNsaWVudFNESyxcbiAgICBpbmZvLmNvbnRleHRcbiAgKTtcblxuICBpZiAoIXJlc3BvbnNlLnJlc3VsdHMgfHwgcmVzcG9uc2UucmVzdWx0cy5sZW5ndGggPT0gMCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnT2JqZWN0IG5vdCBmb3VuZC4nKTtcbiAgfVxuXG4gIGNvbnN0IG9iamVjdCA9IHJlc3BvbnNlLnJlc3VsdHNbMF07XG4gIGlmIChjbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICBkZWxldGUgb2JqZWN0LnNlc3Npb25Ub2tlbjtcbiAgfVxuICByZXR1cm4gb2JqZWN0O1xufTtcblxuY29uc3QgZmluZE9iamVjdHMgPSBhc3luYyAoXG4gIGNsYXNzTmFtZSxcbiAgd2hlcmUsXG4gIG9yZGVyLFxuICBza2lwSW5wdXQsXG4gIGZpcnN0LFxuICBhZnRlcixcbiAgbGFzdCxcbiAgYmVmb3JlLFxuICBrZXlzLFxuICBpbmNsdWRlLFxuICBpbmNsdWRlQWxsLFxuICByZWFkUHJlZmVyZW5jZSxcbiAgaW5jbHVkZVJlYWRQcmVmZXJlbmNlLFxuICBzdWJxdWVyeVJlYWRQcmVmZXJlbmNlLFxuICBjb25maWcsXG4gIGF1dGgsXG4gIGluZm8sXG4gIHNlbGVjdGVkRmllbGRzLFxuICBwYXJzZUNsYXNzZXNcbikgPT4ge1xuICBpZiAoIXdoZXJlKSB7XG4gICAgd2hlcmUgPSB7fTtcbiAgfVxuICB0cmFuc2Zvcm1RdWVyeUlucHV0VG9QYXJzZSh3aGVyZSwgY2xhc3NOYW1lLCBwYXJzZUNsYXNzZXMpO1xuICBjb25zdCBza2lwQW5kTGltaXRDYWxjdWxhdGlvbiA9IGNhbGN1bGF0ZVNraXBBbmRMaW1pdChcbiAgICBza2lwSW5wdXQsXG4gICAgZmlyc3QsXG4gICAgYWZ0ZXIsXG4gICAgbGFzdCxcbiAgICBiZWZvcmUsXG4gICAgY29uZmlnLm1heExpbWl0XG4gICk7XG4gIGxldCB7IHNraXAgfSA9IHNraXBBbmRMaW1pdENhbGN1bGF0aW9uO1xuICBjb25zdCB7IGxpbWl0LCBuZWVkVG9QcmVDb3VudCB9ID0gc2tpcEFuZExpbWl0Q2FsY3VsYXRpb247XG4gIGxldCBwcmVDb3VudCA9IHVuZGVmaW5lZDtcbiAgaWYgKG5lZWRUb1ByZUNvdW50KSB7XG4gICAgY29uc3QgcHJlQ291bnRPcHRpb25zID0ge1xuICAgICAgbGltaXQ6IDAsXG4gICAgICBjb3VudDogdHJ1ZSxcbiAgICB9O1xuICAgIGlmIChyZWFkUHJlZmVyZW5jZSkge1xuICAgICAgcHJlQ291bnRPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gcmVhZFByZWZlcmVuY2U7XG4gICAgfVxuICAgIGlmIChPYmplY3Qua2V5cyh3aGVyZSkubGVuZ3RoID4gMCAmJiBzdWJxdWVyeVJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICBwcmVDb3VudE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSA9IHN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U7XG4gICAgfVxuICAgIHByZUNvdW50ID0gKFxuICAgICAgYXdhaXQgcmVzdC5maW5kKGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCB3aGVyZSwgcHJlQ291bnRPcHRpb25zLCBpbmZvLmNsaWVudFNESywgaW5mby5jb250ZXh0KVxuICAgICkuY291bnQ7XG4gICAgaWYgKChza2lwIHx8IDApICsgbGltaXQgPCBwcmVDb3VudCkge1xuICAgICAgc2tpcCA9IHByZUNvdW50IC0gbGltaXQ7XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgb3B0aW9ucyA9IHt9O1xuXG4gIGlmIChzZWxlY3RlZEZpZWxkcy5maW5kKGZpZWxkID0+IGZpZWxkLnN0YXJ0c1dpdGgoJ2VkZ2VzLicpIHx8IGZpZWxkLnN0YXJ0c1dpdGgoJ3BhZ2VJbmZvLicpKSkge1xuICAgIGlmIChsaW1pdCB8fCBsaW1pdCA9PT0gMCkge1xuICAgICAgb3B0aW9ucy5saW1pdCA9IGxpbWl0O1xuICAgIH0gZWxzZSB7XG4gICAgICBvcHRpb25zLmxpbWl0ID0gMTAwO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy5saW1pdCAhPT0gMCkge1xuICAgICAgaWYgKG9yZGVyKSB7XG4gICAgICAgIG9wdGlvbnMub3JkZXIgPSBvcmRlcjtcbiAgICAgIH1cbiAgICAgIGlmIChza2lwKSB7XG4gICAgICAgIG9wdGlvbnMuc2tpcCA9IHNraXA7XG4gICAgICB9XG4gICAgICBpZiAoY29uZmlnLm1heExpbWl0ICYmIG9wdGlvbnMubGltaXQgPiBjb25maWcubWF4TGltaXQpIHtcbiAgICAgICAgLy8gU2lsZW50bHkgcmVwbGFjZSB0aGUgbGltaXQgb24gdGhlIHF1ZXJ5IHdpdGggdGhlIG1heCBjb25maWd1cmVkXG4gICAgICAgIG9wdGlvbnMubGltaXQgPSBjb25maWcubWF4TGltaXQ7XG4gICAgICB9XG4gICAgICBpZiAoXG4gICAgICAgICFuZWVkVG9HZXRBbGxLZXlzKFxuICAgICAgICAgIHBhcnNlQ2xhc3Nlcy5maW5kKCh7IGNsYXNzTmFtZTogcGFyc2VDbGFzc05hbWUgfSkgPT4gY2xhc3NOYW1lID09PSBwYXJzZUNsYXNzTmFtZSkuZmllbGRzLFxuICAgICAgICAgIGtleXMsXG4gICAgICAgICAgcGFyc2VDbGFzc2VzXG4gICAgICAgIClcbiAgICAgICkge1xuICAgICAgICBvcHRpb25zLmtleXMgPSBrZXlzO1xuICAgICAgfVxuICAgICAgaWYgKGluY2x1ZGVBbGwgPT09IHRydWUpIHtcbiAgICAgICAgb3B0aW9ucy5pbmNsdWRlQWxsID0gaW5jbHVkZUFsbDtcbiAgICAgIH1cbiAgICAgIGlmICghb3B0aW9ucy5pbmNsdWRlQWxsICYmIGluY2x1ZGUpIHtcbiAgICAgICAgb3B0aW9ucy5pbmNsdWRlID0gaW5jbHVkZTtcbiAgICAgIH1cbiAgICAgIGlmICgob3B0aW9ucy5pbmNsdWRlQWxsIHx8IG9wdGlvbnMuaW5jbHVkZSkgJiYgaW5jbHVkZVJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICAgIG9wdGlvbnMuaW5jbHVkZVJlYWRQcmVmZXJlbmNlID0gaW5jbHVkZVJlYWRQcmVmZXJlbmNlO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBvcHRpb25zLmxpbWl0ID0gMDtcbiAgfVxuXG4gIGlmIChcbiAgICAoc2VsZWN0ZWRGaWVsZHMuaW5jbHVkZXMoJ2NvdW50JykgfHxcbiAgICAgIHNlbGVjdGVkRmllbGRzLmluY2x1ZGVzKCdwYWdlSW5mby5oYXNQcmV2aW91c1BhZ2UnKSB8fFxuICAgICAgc2VsZWN0ZWRGaWVsZHMuaW5jbHVkZXMoJ3BhZ2VJbmZvLmhhc05leHRQYWdlJykpICYmXG4gICAgIW5lZWRUb1ByZUNvdW50XG4gICkge1xuICAgIG9wdGlvbnMuY291bnQgPSB0cnVlO1xuICB9XG5cbiAgaWYgKHJlYWRQcmVmZXJlbmNlKSB7XG4gICAgb3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHJlYWRQcmVmZXJlbmNlO1xuICB9XG4gIGlmIChPYmplY3Qua2V5cyh3aGVyZSkubGVuZ3RoID4gMCAmJiBzdWJxdWVyeVJlYWRQcmVmZXJlbmNlKSB7XG4gICAgb3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlID0gc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgfVxuXG4gIGxldCByZXN1bHRzLCBjb3VudDtcbiAgaWYgKG9wdGlvbnMuY291bnQgfHwgIW9wdGlvbnMubGltaXQgfHwgKG9wdGlvbnMubGltaXQgJiYgb3B0aW9ucy5saW1pdCA+IDApKSB7XG4gICAgY29uc3QgZmluZFJlc3VsdCA9IGF3YWl0IHJlc3QuZmluZChcbiAgICAgIGNvbmZpZyxcbiAgICAgIGF1dGgsXG4gICAgICBjbGFzc05hbWUsXG4gICAgICB3aGVyZSxcbiAgICAgIG9wdGlvbnMsXG4gICAgICBpbmZvLmNsaWVudFNESyxcbiAgICAgIGluZm8uY29udGV4dFxuICAgICk7XG4gICAgcmVzdWx0cyA9IGZpbmRSZXN1bHQucmVzdWx0cztcbiAgICBjb3VudCA9IGZpbmRSZXN1bHQuY291bnQ7XG4gIH1cblxuICBsZXQgZWRnZXMgPSBudWxsO1xuICBsZXQgcGFnZUluZm8gPSBudWxsO1xuICBpZiAocmVzdWx0cykge1xuICAgIGVkZ2VzID0gcmVzdWx0cy5tYXAoKHJlc3VsdCwgaW5kZXgpID0+ICh7XG4gICAgICBjdXJzb3I6IG9mZnNldFRvQ3Vyc29yKChza2lwIHx8IDApICsgaW5kZXgpLFxuICAgICAgbm9kZTogcmVzdWx0LFxuICAgIH0pKTtcblxuICAgIHBhZ2VJbmZvID0ge1xuICAgICAgaGFzUHJldmlvdXNQYWdlOlxuICAgICAgICAoKHByZUNvdW50ICYmIHByZUNvdW50ID4gMCkgfHwgKGNvdW50ICYmIGNvdW50ID4gMCkpICYmIHNraXAgIT09IHVuZGVmaW5lZCAmJiBza2lwID4gMCxcbiAgICAgIHN0YXJ0Q3Vyc29yOiBvZmZzZXRUb0N1cnNvcihza2lwIHx8IDApLFxuICAgICAgZW5kQ3Vyc29yOiBvZmZzZXRUb0N1cnNvcigoc2tpcCB8fCAwKSArIChyZXN1bHRzLmxlbmd0aCB8fCAxKSAtIDEpLFxuICAgICAgaGFzTmV4dFBhZ2U6IChwcmVDb3VudCB8fCBjb3VudCkgPiAoc2tpcCB8fCAwKSArIHJlc3VsdHMubGVuZ3RoLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGVkZ2VzLFxuICAgIHBhZ2VJbmZvLFxuICAgIGNvdW50OiBwcmVDb3VudCB8fCBjb3VudCxcbiAgfTtcbn07XG5cbmNvbnN0IGNhbGN1bGF0ZVNraXBBbmRMaW1pdCA9IChza2lwSW5wdXQsIGZpcnN0LCBhZnRlciwgbGFzdCwgYmVmb3JlLCBtYXhMaW1pdCkgPT4ge1xuICBsZXQgc2tpcCA9IHVuZGVmaW5lZDtcbiAgbGV0IGxpbWl0ID0gdW5kZWZpbmVkO1xuICBsZXQgbmVlZFRvUHJlQ291bnQgPSBmYWxzZTtcblxuICAvLyBWYWxpZGF0ZXMgdGhlIHNraXAgaW5wdXRcbiAgaWYgKHNraXBJbnB1dCB8fCBza2lwSW5wdXQgPT09IDApIHtcbiAgICBpZiAoc2tpcElucHV0IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksICdTa2lwIHNob3VsZCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICAgIH1cbiAgICBza2lwID0gc2tpcElucHV0O1xuICB9XG5cbiAgLy8gVmFsaWRhdGVzIHRoZSBhZnRlciBwYXJhbVxuICBpZiAoYWZ0ZXIpIHtcbiAgICBhZnRlciA9IGN1cnNvclRvT2Zmc2V0KGFmdGVyKTtcbiAgICBpZiAoKCFhZnRlciAmJiBhZnRlciAhPT0gMCkgfHwgYWZ0ZXIgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSwgJ0FmdGVyIGlzIG5vdCBhIHZhbGlkIGN1cnNvcicpO1xuICAgIH1cblxuICAgIC8vIElmIHNraXAgYW5kIGFmdGVyIGFyZSBwYXNzZWQsIGEgbmV3IHNraXAgaXMgY2FsY3VsYXRlZCBieSBhZGRpbmcgdGhlbVxuICAgIHNraXAgPSAoc2tpcCB8fCAwKSArIChhZnRlciArIDEpO1xuICB9XG5cbiAgLy8gVmFsaWRhdGVzIHRoZSBmaXJzdCBwYXJhbVxuICBpZiAoZmlyc3QgfHwgZmlyc3QgPT09IDApIHtcbiAgICBpZiAoZmlyc3QgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSwgJ0ZpcnN0IHNob3VsZCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICAgIH1cblxuICAgIC8vIFRoZSBmaXJzdCBwYXJhbSBpcyB0cmFuc2xhdGVkIHRvIHRoZSBsaW1pdCBwYXJhbSBvZiB0aGUgUGFyc2UgbGVnYWN5IEFQSVxuICAgIGxpbWl0ID0gZmlyc3Q7XG4gIH1cblxuICAvLyBWYWxpZGF0ZXMgdGhlIGJlZm9yZSBwYXJhbVxuICBpZiAoYmVmb3JlIHx8IGJlZm9yZSA9PT0gMCkge1xuICAgIC8vIFRoaXMgbWV0aG9kIGNvbnZlcnRzIHRoZSBjdXJzb3IgdG8gdGhlIGluZGV4IG9mIHRoZSBvYmplY3RcbiAgICBiZWZvcmUgPSBjdXJzb3JUb09mZnNldChiZWZvcmUpO1xuICAgIGlmICgoIWJlZm9yZSAmJiBiZWZvcmUgIT09IDApIHx8IGJlZm9yZSA8IDApIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnQmVmb3JlIGlzIG5vdCBhIHZhbGlkIGN1cnNvcicpO1xuICAgIH1cblxuICAgIGlmICgoc2tpcCB8fCAwKSA+PSBiZWZvcmUpIHtcbiAgICAgIC8vIElmIHRoZSBiZWZvcmUgaW5kZXggaXMgbGVzcyB0aGVuIHRoZSBza2lwLCBubyBvYmplY3RzIHdpbGwgYmUgcmV0dXJuZWRcbiAgICAgIGxpbWl0ID0gMDtcbiAgICB9IGVsc2UgaWYgKCghbGltaXQgJiYgbGltaXQgIT09IDApIHx8IChza2lwIHx8IDApICsgbGltaXQgPiBiZWZvcmUpIHtcbiAgICAgIC8vIElmIHRoZXJlIGlzIG5vIGxpbWl0IHNldCwgdGhlIGxpbWl0IGlzIGNhbGN1bGF0ZWQuIE9yLCBpZiB0aGUgbGltaXQgKHBsdXMgc2tpcCkgaXMgYmlnZ2VyIHRoYW4gdGhlIGJlZm9yZSBpbmRleCwgdGhlIG5ldyBsaW1pdCBpcyBzZXQuXG4gICAgICBsaW1pdCA9IGJlZm9yZSAtIChza2lwIHx8IDApO1xuICAgIH1cbiAgfVxuXG4gIC8vIFZhbGlkYXRlcyB0aGUgbGFzdCBwYXJhbVxuICBpZiAobGFzdCB8fCBsYXN0ID09PSAwKSB7XG4gICAgaWYgKGxhc3QgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSwgJ0xhc3Qgc2hvdWxkIGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gICAgfVxuXG4gICAgaWYgKGxhc3QgPiBtYXhMaW1pdCkge1xuICAgICAgLy8gTGFzdCBjYW4ndCBiZSBiaWdnZXIgdGhhbiBQYXJzZSBzZXJ2ZXIgbWF4TGltaXQgY29uZmlnLlxuICAgICAgbGFzdCA9IG1heExpbWl0O1xuICAgIH1cblxuICAgIGlmIChsaW1pdCB8fCBsaW1pdCA9PT0gMCkge1xuICAgICAgLy8gSWYgdGhlcmUgaXMgYSBwcmV2aW91cyBsaW1pdCBzZXQsIGl0IG1heSBiZSBhZGp1c3RlZFxuICAgICAgaWYgKGxhc3QgPCBsaW1pdCkge1xuICAgICAgICAvLyBpZiBsYXN0IGlzIGxlc3MgdGhhbiB0aGUgY3VycmVudCBsaW1pdFxuICAgICAgICBza2lwID0gKHNraXAgfHwgMCkgKyAobGltaXQgLSBsYXN0KTsgLy8gVGhlIHNraXAgaXMgYWRqdXN0ZWRcbiAgICAgICAgbGltaXQgPSBsYXN0OyAvLyB0aGUgbGltaXQgaXMgYWRqdXN0ZWRcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGxhc3QgPT09IDApIHtcbiAgICAgIC8vIE5vIG9iamVjdHMgd2lsbCBiZSByZXR1cm5lZFxuICAgICAgbGltaXQgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBObyBwcmV2aW91cyBsaW1pdCBzZXQsIHRoZSBsaW1pdCB3aWxsIGJlIGVxdWFsIHRvIGxhc3QgYW5kIHByZSBjb3VudCBpcyBuZWVkZWQuXG4gICAgICBsaW1pdCA9IGxhc3Q7XG4gICAgICBuZWVkVG9QcmVDb3VudCA9IHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiB7XG4gICAgc2tpcCxcbiAgICBsaW1pdCxcbiAgICBuZWVkVG9QcmVDb3VudCxcbiAgfTtcbn07XG5cbmV4cG9ydCB7IGdldE9iamVjdCwgZmluZE9iamVjdHMsIGNhbGN1bGF0ZVNraXBBbmRMaW1pdCwgbmVlZFRvR2V0QWxsS2V5cyB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/defaultGraphQLMutations.js b/lib/GraphQL/loaders/defaultGraphQLMutations.js new file mode 100644 index 0000000000..afe32cc4fb --- /dev/null +++ b/lib/GraphQL/loaders/defaultGraphQLMutations.js @@ -0,0 +1,28 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = void 0; + +var filesMutations = _interopRequireWildcard(require("./filesMutations")); + +var usersMutations = _interopRequireWildcard(require("./usersMutations")); + +var functionsMutations = _interopRequireWildcard(require("./functionsMutations")); + +var schemaMutations = _interopRequireWildcard(require("./schemaMutations")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +const load = parseGraphQLSchema => { + filesMutations.load(parseGraphQLSchema); + usersMutations.load(parseGraphQLSchema); + functionsMutations.load(parseGraphQLSchema); + schemaMutations.load(parseGraphQLSchema); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxNdXRhdGlvbnMuanMiXSwibmFtZXMiOlsibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsImZpbGVzTXV0YXRpb25zIiwidXNlcnNNdXRhdGlvbnMiLCJmdW5jdGlvbnNNdXRhdGlvbnMiLCJzY2hlbWFNdXRhdGlvbnMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7O0FBRUEsTUFBTUEsSUFBSSxHQUFHQyxrQkFBa0IsSUFBSTtBQUNqQ0MsRUFBQUEsY0FBYyxDQUFDRixJQUFmLENBQW9CQyxrQkFBcEI7QUFDQUUsRUFBQUEsY0FBYyxDQUFDSCxJQUFmLENBQW9CQyxrQkFBcEI7QUFDQUcsRUFBQUEsa0JBQWtCLENBQUNKLElBQW5CLENBQXdCQyxrQkFBeEI7QUFDQUksRUFBQUEsZUFBZSxDQUFDTCxJQUFoQixDQUFxQkMsa0JBQXJCO0FBQ0QsQ0FMRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZpbGVzTXV0YXRpb25zIGZyb20gJy4vZmlsZXNNdXRhdGlvbnMnO1xuaW1wb3J0ICogYXMgdXNlcnNNdXRhdGlvbnMgZnJvbSAnLi91c2Vyc011dGF0aW9ucyc7XG5pbXBvcnQgKiBhcyBmdW5jdGlvbnNNdXRhdGlvbnMgZnJvbSAnLi9mdW5jdGlvbnNNdXRhdGlvbnMnO1xuaW1wb3J0ICogYXMgc2NoZW1hTXV0YXRpb25zIGZyb20gJy4vc2NoZW1hTXV0YXRpb25zJztcblxuY29uc3QgbG9hZCA9IHBhcnNlR3JhcGhRTFNjaGVtYSA9PiB7XG4gIGZpbGVzTXV0YXRpb25zLmxvYWQocGFyc2VHcmFwaFFMU2NoZW1hKTtcbiAgdXNlcnNNdXRhdGlvbnMubG9hZChwYXJzZUdyYXBoUUxTY2hlbWEpO1xuICBmdW5jdGlvbnNNdXRhdGlvbnMubG9hZChwYXJzZUdyYXBoUUxTY2hlbWEpO1xuICBzY2hlbWFNdXRhdGlvbnMubG9hZChwYXJzZUdyYXBoUUxTY2hlbWEpO1xufTtcblxuZXhwb3J0IHsgbG9hZCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/defaultGraphQLQueries.js b/lib/GraphQL/loaders/defaultGraphQLQueries.js new file mode 100644 index 0000000000..58a4f474d6 --- /dev/null +++ b/lib/GraphQL/loaders/defaultGraphQLQueries.js @@ -0,0 +1,29 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = void 0; + +var _graphql = require("graphql"); + +var usersQueries = _interopRequireWildcard(require("./usersQueries")); + +var schemaQueries = _interopRequireWildcard(require("./schemaQueries")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +const load = parseGraphQLSchema => { + parseGraphQLSchema.addGraphQLQuery('health', { + description: 'The health query can be used to check if the server is up and running.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean), + resolve: () => true + }, true, true); + usersQueries.load(parseGraphQLSchema); + schemaQueries.load(parseGraphQLSchema); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxRdWVyaWVzLmpzIl0sIm5hbWVzIjpbImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJhZGRHcmFwaFFMUXVlcnkiLCJkZXNjcmlwdGlvbiIsInR5cGUiLCJHcmFwaFFMTm9uTnVsbCIsIkdyYXBoUUxCb29sZWFuIiwicmVzb2x2ZSIsInVzZXJzUXVlcmllcyIsInNjaGVtYVF1ZXJpZXMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7O0FBRUEsTUFBTUEsSUFBSSxHQUFHQyxrQkFBa0IsSUFBSTtBQUNqQ0EsRUFBQUEsa0JBQWtCLENBQUNDLGVBQW5CLENBQ0UsUUFERixFQUVFO0FBQ0VDLElBQUFBLFdBQVcsRUFBRSx3RUFEZjtBQUVFQyxJQUFBQSxJQUFJLEVBQUUsSUFBSUMsdUJBQUosQ0FBbUJDLHVCQUFuQixDQUZSO0FBR0VDLElBQUFBLE9BQU8sRUFBRSxNQUFNO0FBSGpCLEdBRkYsRUFPRSxJQVBGLEVBUUUsSUFSRjtBQVdBQyxFQUFBQSxZQUFZLENBQUNSLElBQWIsQ0FBa0JDLGtCQUFsQjtBQUNBUSxFQUFBQSxhQUFhLENBQUNULElBQWQsQ0FBbUJDLGtCQUFuQjtBQUNELENBZEQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBHcmFwaFFMTm9uTnVsbCwgR3JhcGhRTEJvb2xlYW4gfSBmcm9tICdncmFwaHFsJztcbmltcG9ydCAqIGFzIHVzZXJzUXVlcmllcyBmcm9tICcuL3VzZXJzUXVlcmllcyc7XG5pbXBvcnQgKiBhcyBzY2hlbWFRdWVyaWVzIGZyb20gJy4vc2NoZW1hUXVlcmllcyc7XG5cbmNvbnN0IGxvYWQgPSBwYXJzZUdyYXBoUUxTY2hlbWEgPT4ge1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFF1ZXJ5KFxuICAgICdoZWFsdGgnLFxuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIGhlYWx0aCBxdWVyeSBjYW4gYmUgdXNlZCB0byBjaGVjayBpZiB0aGUgc2VydmVyIGlzIHVwIGFuZCBydW5uaW5nLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgICAgcmVzb2x2ZTogKCkgPT4gdHJ1ZSxcbiAgICB9LFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuXG4gIHVzZXJzUXVlcmllcy5sb2FkKHBhcnNlR3JhcGhRTFNjaGVtYSk7XG4gIHNjaGVtYVF1ZXJpZXMubG9hZChwYXJzZUdyYXBoUUxTY2hlbWEpO1xufTtcblxuZXhwb3J0IHsgbG9hZCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/defaultGraphQLTypes.js b/lib/GraphQL/loaders/defaultGraphQLTypes.js new file mode 100644 index 0000000000..14487e4658 --- /dev/null +++ b/lib/GraphQL/loaders/defaultGraphQLTypes.js @@ -0,0 +1,1271 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.loadArrayResult = exports.load = exports.PUBLIC_ACL = exports.ROLE_ACL = exports.USER_ACL = exports.ACL = exports.PUBLIC_ACL_INPUT = exports.ROLE_ACL_INPUT = exports.USER_ACL_INPUT = exports.ACL_INPUT = exports.ELEMENT = exports.ARRAY_RESULT = exports.POLYGON_WHERE_INPUT = exports.GEO_POINT_WHERE_INPUT = exports.FILE_WHERE_INPUT = exports.BYTES_WHERE_INPUT = exports.DATE_WHERE_INPUT = exports.OBJECT_WHERE_INPUT = exports.KEY_VALUE_INPUT = exports.ARRAY_WHERE_INPUT = exports.BOOLEAN_WHERE_INPUT = exports.NUMBER_WHERE_INPUT = exports.STRING_WHERE_INPUT = exports.ID_WHERE_INPUT = exports.notInQueryKey = exports.inQueryKey = exports.options = exports.matchesRegex = exports.exists = exports.notIn = exports.inOp = exports.greaterThanOrEqualTo = exports.greaterThan = exports.lessThanOrEqualTo = exports.lessThan = exports.notEqualTo = exports.equalTo = exports.GEO_INTERSECTS_INPUT = exports.GEO_WITHIN_INPUT = exports.CENTER_SPHERE_INPUT = exports.WITHIN_INPUT = exports.BOX_INPUT = exports.TEXT_INPUT = exports.SEARCH_INPUT = exports.COUNT_ATT = exports.LIMIT_ATT = exports.SKIP_ATT = exports.WHERE_ATT = exports.READ_OPTIONS_ATT = exports.READ_OPTIONS_INPUT = exports.SUBQUERY_READ_PREFERENCE_ATT = exports.INCLUDE_READ_PREFERENCE_ATT = exports.READ_PREFERENCE_ATT = exports.READ_PREFERENCE = exports.SESSION_TOKEN_ATT = exports.PARSE_OBJECT = exports.PARSE_OBJECT_FIELDS = exports.UPDATE_RESULT_FIELDS = exports.CREATE_RESULT_FIELDS = exports.INPUT_FIELDS = exports.CREATED_AT_ATT = exports.UPDATED_AT_ATT = exports.OBJECT_ID_ATT = exports.GLOBAL_OR_OBJECT_ID_ATT = exports.CLASS_NAME_ATT = exports.OBJECT_ID = exports.POLYGON = exports.POLYGON_INPUT = exports.GEO_POINT = exports.GEO_POINT_INPUT = exports.GEO_POINT_FIELDS = exports.FILE_INPUT = exports.FILE_INFO = exports.FILE = exports.SELECT_INPUT = exports.SUBQUERY_INPUT = exports.parseFileValue = exports.BYTES = exports.DATE = exports.serializeDateIso = exports.parseDateIsoValue = exports.OBJECT = exports.ANY = exports.parseObjectFields = exports.parseListValues = exports.parseValue = exports.parseBooleanValue = exports.parseFloatValue = exports.parseIntValue = exports.parseStringValue = exports.TypeValidationError = void 0; + +var _graphql = require("graphql"); + +var _graphqlRelay = require("graphql-relay"); + +var _links = require("@graphql-tools/links"); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +class TypeValidationError extends Error { + constructor(value, type) { + super(`${value} is not a valid ${type}`); + } + +} + +exports.TypeValidationError = TypeValidationError; + +const parseStringValue = value => { + if (typeof value === 'string') { + return value; + } + + throw new TypeValidationError(value, 'String'); +}; + +exports.parseStringValue = parseStringValue; + +const parseIntValue = value => { + if (typeof value === 'string') { + const int = Number(value); + + if (Number.isInteger(int)) { + return int; + } + } + + throw new TypeValidationError(value, 'Int'); +}; + +exports.parseIntValue = parseIntValue; + +const parseFloatValue = value => { + if (typeof value === 'string') { + const float = Number(value); + + if (!isNaN(float)) { + return float; + } + } + + throw new TypeValidationError(value, 'Float'); +}; + +exports.parseFloatValue = parseFloatValue; + +const parseBooleanValue = value => { + if (typeof value === 'boolean') { + return value; + } + + throw new TypeValidationError(value, 'Boolean'); +}; + +exports.parseBooleanValue = parseBooleanValue; + +const parseValue = value => { + switch (value.kind) { + case _graphql.Kind.STRING: + return parseStringValue(value.value); + + case _graphql.Kind.INT: + return parseIntValue(value.value); + + case _graphql.Kind.FLOAT: + return parseFloatValue(value.value); + + case _graphql.Kind.BOOLEAN: + return parseBooleanValue(value.value); + + case _graphql.Kind.LIST: + return parseListValues(value.values); + + case _graphql.Kind.OBJECT: + return parseObjectFields(value.fields); + + default: + return value.value; + } +}; + +exports.parseValue = parseValue; + +const parseListValues = values => { + if (Array.isArray(values)) { + return values.map(value => parseValue(value)); + } + + throw new TypeValidationError(values, 'List'); +}; + +exports.parseListValues = parseListValues; + +const parseObjectFields = fields => { + if (Array.isArray(fields)) { + return fields.reduce((object, field) => _objectSpread(_objectSpread({}, object), {}, { + [field.name.value]: parseValue(field.value) + }), {}); + } + + throw new TypeValidationError(fields, 'Object'); +}; + +exports.parseObjectFields = parseObjectFields; +const ANY = new _graphql.GraphQLScalarType({ + name: 'Any', + description: 'The Any scalar type is used in operations and types that involve any type of value.', + parseValue: value => value, + serialize: value => value, + parseLiteral: ast => parseValue(ast) +}); +exports.ANY = ANY; +const OBJECT = new _graphql.GraphQLScalarType({ + name: 'Object', + description: 'The Object scalar type is used in operations and types that involve objects.', + + parseValue(value) { + if (typeof value === 'object') { + return value; + } + + throw new TypeValidationError(value, 'Object'); + }, + + serialize(value) { + if (typeof value === 'object') { + return value; + } + + throw new TypeValidationError(value, 'Object'); + }, + + parseLiteral(ast) { + if (ast.kind === _graphql.Kind.OBJECT) { + return parseObjectFields(ast.fields); + } + + throw new TypeValidationError(ast.kind, 'Object'); + } + +}); +exports.OBJECT = OBJECT; + +const parseDateIsoValue = value => { + if (typeof value === 'string') { + const date = new Date(value); + + if (!isNaN(date)) { + return date; + } + } else if (value instanceof Date) { + return value; + } + + throw new TypeValidationError(value, 'Date'); +}; + +exports.parseDateIsoValue = parseDateIsoValue; + +const serializeDateIso = value => { + if (typeof value === 'string') { + return value; + } + + if (value instanceof Date) { + return value.toISOString(); + } + + throw new TypeValidationError(value, 'Date'); +}; + +exports.serializeDateIso = serializeDateIso; + +const parseDateIsoLiteral = ast => { + if (ast.kind === _graphql.Kind.STRING) { + return parseDateIsoValue(ast.value); + } + + throw new TypeValidationError(ast.kind, 'Date'); +}; + +const DATE = new _graphql.GraphQLScalarType({ + name: 'Date', + description: 'The Date scalar type is used in operations and types that involve dates.', + + parseValue(value) { + if (typeof value === 'string' || value instanceof Date) { + return { + __type: 'Date', + iso: parseDateIsoValue(value) + }; + } else if (typeof value === 'object' && value.__type === 'Date' && value.iso) { + return { + __type: value.__type, + iso: parseDateIsoValue(value.iso) + }; + } + + throw new TypeValidationError(value, 'Date'); + }, + + serialize(value) { + if (typeof value === 'string' || value instanceof Date) { + return serializeDateIso(value); + } else if (typeof value === 'object' && value.__type === 'Date' && value.iso) { + return serializeDateIso(value.iso); + } + + throw new TypeValidationError(value, 'Date'); + }, + + parseLiteral(ast) { + if (ast.kind === _graphql.Kind.STRING) { + return { + __type: 'Date', + iso: parseDateIsoLiteral(ast) + }; + } else if (ast.kind === _graphql.Kind.OBJECT) { + const __type = ast.fields.find(field => field.name.value === '__type'); + + const iso = ast.fields.find(field => field.name.value === 'iso'); + + if (__type && __type.value && __type.value.value === 'Date' && iso) { + return { + __type: __type.value.value, + iso: parseDateIsoLiteral(iso.value) + }; + } + } + + throw new TypeValidationError(ast.kind, 'Date'); + } + +}); +exports.DATE = DATE; +const BYTES = new _graphql.GraphQLScalarType({ + name: 'Bytes', + description: 'The Bytes scalar type is used in operations and types that involve base 64 binary data.', + + parseValue(value) { + if (typeof value === 'string') { + return { + __type: 'Bytes', + base64: value + }; + } else if (typeof value === 'object' && value.__type === 'Bytes' && typeof value.base64 === 'string') { + return value; + } + + throw new TypeValidationError(value, 'Bytes'); + }, + + serialize(value) { + if (typeof value === 'string') { + return value; + } else if (typeof value === 'object' && value.__type === 'Bytes' && typeof value.base64 === 'string') { + return value.base64; + } + + throw new TypeValidationError(value, 'Bytes'); + }, + + parseLiteral(ast) { + if (ast.kind === _graphql.Kind.STRING) { + return { + __type: 'Bytes', + base64: ast.value + }; + } else if (ast.kind === _graphql.Kind.OBJECT) { + const __type = ast.fields.find(field => field.name.value === '__type'); + + const base64 = ast.fields.find(field => field.name.value === 'base64'); + + if (__type && __type.value && __type.value.value === 'Bytes' && base64 && base64.value && typeof base64.value.value === 'string') { + return { + __type: __type.value.value, + base64: base64.value.value + }; + } + } + + throw new TypeValidationError(ast.kind, 'Bytes'); + } + +}); +exports.BYTES = BYTES; + +const parseFileValue = value => { + if (typeof value === 'string') { + return { + __type: 'File', + name: value + }; + } else if (typeof value === 'object' && value.__type === 'File' && typeof value.name === 'string' && (value.url === undefined || typeof value.url === 'string')) { + return value; + } + + throw new TypeValidationError(value, 'File'); +}; + +exports.parseFileValue = parseFileValue; +const FILE = new _graphql.GraphQLScalarType({ + name: 'File', + description: 'The File scalar type is used in operations and types that involve files.', + parseValue: parseFileValue, + serialize: value => { + if (typeof value === 'string') { + return value; + } else if (typeof value === 'object' && value.__type === 'File' && typeof value.name === 'string' && (value.url === undefined || typeof value.url === 'string')) { + return value.name; + } + + throw new TypeValidationError(value, 'File'); + }, + + parseLiteral(ast) { + if (ast.kind === _graphql.Kind.STRING) { + return parseFileValue(ast.value); + } else if (ast.kind === _graphql.Kind.OBJECT) { + const __type = ast.fields.find(field => field.name.value === '__type'); + + const name = ast.fields.find(field => field.name.value === 'name'); + const url = ast.fields.find(field => field.name.value === 'url'); + + if (__type && __type.value && name && name.value) { + return parseFileValue({ + __type: __type.value.value, + name: name.value.value, + url: url && url.value ? url.value.value : undefined + }); + } + } + + throw new TypeValidationError(ast.kind, 'File'); + } + +}); +exports.FILE = FILE; +const FILE_INFO = new _graphql.GraphQLObjectType({ + name: 'FileInfo', + description: 'The FileInfo object type is used to return the information about files.', + fields: { + name: { + description: 'This is the file name.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + }, + url: { + description: 'This is the url in which the file can be downloaded.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + } + } +}); +exports.FILE_INFO = FILE_INFO; +const FILE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'FileInput', + fields: { + file: { + description: 'A File Scalar can be an url or a FileInfo object. If this field is set to null the file will be unlinked.', + type: FILE + }, + upload: { + description: 'Use this field if you want to create a new file.', + type: _links.GraphQLUpload + }, + unlink: { + description: 'Use this field if you want to unlink the file (the file will not be deleted on cloud storage)', + type: _graphql.GraphQLBoolean + } + } +}); +exports.FILE_INPUT = FILE_INPUT; +const GEO_POINT_FIELDS = { + latitude: { + description: 'This is the latitude.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLFloat) + }, + longitude: { + description: 'This is the longitude.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLFloat) + } +}; +exports.GEO_POINT_FIELDS = GEO_POINT_FIELDS; +const GEO_POINT_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'GeoPointInput', + description: 'The GeoPointInput type is used in operations that involve inputting fields of type geo point.', + fields: GEO_POINT_FIELDS +}); +exports.GEO_POINT_INPUT = GEO_POINT_INPUT; +const GEO_POINT = new _graphql.GraphQLObjectType({ + name: 'GeoPoint', + description: 'The GeoPoint object type is used to return the information about geo point fields.', + fields: GEO_POINT_FIELDS +}); +exports.GEO_POINT = GEO_POINT; +const POLYGON_INPUT = new _graphql.GraphQLList(new _graphql.GraphQLNonNull(GEO_POINT_INPUT)); +exports.POLYGON_INPUT = POLYGON_INPUT; +const POLYGON = new _graphql.GraphQLList(new _graphql.GraphQLNonNull(GEO_POINT)); +exports.POLYGON = POLYGON; +const USER_ACL_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'UserACLInput', + description: 'Allow to manage users in ACL.', + fields: { + userId: { + description: 'ID of the targetted User.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLID) + }, + read: { + description: 'Allow the user to read the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + }, + write: { + description: 'Allow the user to write on the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + } + } +}); +exports.USER_ACL_INPUT = USER_ACL_INPUT; +const ROLE_ACL_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'RoleACLInput', + description: 'Allow to manage roles in ACL.', + fields: { + roleName: { + description: 'Name of the targetted Role.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + }, + read: { + description: 'Allow users who are members of the role to read the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + }, + write: { + description: 'Allow users who are members of the role to write on the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + } + } +}); +exports.ROLE_ACL_INPUT = ROLE_ACL_INPUT; +const PUBLIC_ACL_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'PublicACLInput', + description: 'Allow to manage public rights.', + fields: { + read: { + description: 'Allow anyone to read the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + }, + write: { + description: 'Allow anyone to write on the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + } + } +}); +exports.PUBLIC_ACL_INPUT = PUBLIC_ACL_INPUT; +const ACL_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'ACLInput', + description: 'Allow to manage access rights. If not provided object will be publicly readable and writable', + fields: { + users: { + description: 'Access control list for users.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(USER_ACL_INPUT)) + }, + roles: { + description: 'Access control list for roles.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(ROLE_ACL_INPUT)) + }, + public: { + description: 'Public access control list.', + type: PUBLIC_ACL_INPUT + } + } +}); +exports.ACL_INPUT = ACL_INPUT; +const USER_ACL = new _graphql.GraphQLObjectType({ + name: 'UserACL', + description: 'Allow to manage users in ACL. If read and write are null the users have read and write rights.', + fields: { + userId: { + description: 'ID of the targetted User.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLID) + }, + read: { + description: 'Allow the user to read the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + }, + write: { + description: 'Allow the user to write on the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + } + } +}); +exports.USER_ACL = USER_ACL; +const ROLE_ACL = new _graphql.GraphQLObjectType({ + name: 'RoleACL', + description: 'Allow to manage roles in ACL. If read and write are null the role have read and write rights.', + fields: { + roleName: { + description: 'Name of the targetted Role.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLID) + }, + read: { + description: 'Allow users who are members of the role to read the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + }, + write: { + description: 'Allow users who are members of the role to write on the current object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + } + } +}); +exports.ROLE_ACL = ROLE_ACL; +const PUBLIC_ACL = new _graphql.GraphQLObjectType({ + name: 'PublicACL', + description: 'Allow to manage public rights.', + fields: { + read: { + description: 'Allow anyone to read the current object.', + type: _graphql.GraphQLBoolean + }, + write: { + description: 'Allow anyone to write on the current object.', + type: _graphql.GraphQLBoolean + } + } +}); +exports.PUBLIC_ACL = PUBLIC_ACL; +const ACL = new _graphql.GraphQLObjectType({ + name: 'ACL', + description: 'Current access control list of the current object.', + fields: { + users: { + description: 'Access control list for users.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(USER_ACL)), + + resolve(p) { + const users = []; + Object.keys(p).forEach(rule => { + if (rule !== '*' && rule.indexOf('role:') !== 0) { + users.push({ + userId: (0, _graphqlRelay.toGlobalId)('_User', rule), + read: p[rule].read ? true : false, + write: p[rule].write ? true : false + }); + } + }); + return users.length ? users : null; + } + + }, + roles: { + description: 'Access control list for roles.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(ROLE_ACL)), + + resolve(p) { + const roles = []; + Object.keys(p).forEach(rule => { + if (rule.indexOf('role:') === 0) { + roles.push({ + roleName: rule.replace('role:', ''), + read: p[rule].read ? true : false, + write: p[rule].write ? true : false + }); + } + }); + return roles.length ? roles : null; + } + + }, + public: { + description: 'Public access control list.', + type: PUBLIC_ACL, + + resolve(p) { + /* eslint-disable */ + return p['*'] ? { + read: p['*'].read ? true : false, + write: p['*'].write ? true : false + } : null; + } + + } + } +}); +exports.ACL = ACL; +const OBJECT_ID = new _graphql.GraphQLNonNull(_graphql.GraphQLID); +exports.OBJECT_ID = OBJECT_ID; +const CLASS_NAME_ATT = { + description: 'This is the class name of the object.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) +}; +exports.CLASS_NAME_ATT = CLASS_NAME_ATT; +const GLOBAL_OR_OBJECT_ID_ATT = { + description: 'This is the object id. You can use either the global or the object id.', + type: OBJECT_ID +}; +exports.GLOBAL_OR_OBJECT_ID_ATT = GLOBAL_OR_OBJECT_ID_ATT; +const OBJECT_ID_ATT = { + description: 'This is the object id.', + type: OBJECT_ID +}; +exports.OBJECT_ID_ATT = OBJECT_ID_ATT; +const CREATED_AT_ATT = { + description: 'This is the date in which the object was created.', + type: new _graphql.GraphQLNonNull(DATE) +}; +exports.CREATED_AT_ATT = CREATED_AT_ATT; +const UPDATED_AT_ATT = { + description: 'This is the date in which the object was las updated.', + type: new _graphql.GraphQLNonNull(DATE) +}; +exports.UPDATED_AT_ATT = UPDATED_AT_ATT; +const INPUT_FIELDS = { + ACL: { + type: ACL + } +}; +exports.INPUT_FIELDS = INPUT_FIELDS; +const CREATE_RESULT_FIELDS = { + objectId: OBJECT_ID_ATT, + createdAt: CREATED_AT_ATT +}; +exports.CREATE_RESULT_FIELDS = CREATE_RESULT_FIELDS; +const UPDATE_RESULT_FIELDS = { + updatedAt: UPDATED_AT_ATT +}; +exports.UPDATE_RESULT_FIELDS = UPDATE_RESULT_FIELDS; + +const PARSE_OBJECT_FIELDS = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, CREATE_RESULT_FIELDS), UPDATE_RESULT_FIELDS), INPUT_FIELDS), {}, { + ACL: { + type: new _graphql.GraphQLNonNull(ACL), + resolve: ({ + ACL + }) => ACL ? ACL : { + '*': { + read: true, + write: true + } + } + } +}); + +exports.PARSE_OBJECT_FIELDS = PARSE_OBJECT_FIELDS; +const PARSE_OBJECT = new _graphql.GraphQLInterfaceType({ + name: 'ParseObject', + description: 'The ParseObject interface type is used as a base type for the auto generated object types.', + fields: PARSE_OBJECT_FIELDS +}); +exports.PARSE_OBJECT = PARSE_OBJECT; +const SESSION_TOKEN_ATT = { + description: 'The current user session token.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) +}; +exports.SESSION_TOKEN_ATT = SESSION_TOKEN_ATT; +const READ_PREFERENCE = new _graphql.GraphQLEnumType({ + name: 'ReadPreference', + description: 'The ReadPreference enum type is used in queries in order to select in which database replica the operation must run.', + values: { + PRIMARY: { + value: 'PRIMARY' + }, + PRIMARY_PREFERRED: { + value: 'PRIMARY_PREFERRED' + }, + SECONDARY: { + value: 'SECONDARY' + }, + SECONDARY_PREFERRED: { + value: 'SECONDARY_PREFERRED' + }, + NEAREST: { + value: 'NEAREST' + } + } +}); +exports.READ_PREFERENCE = READ_PREFERENCE; +const READ_PREFERENCE_ATT = { + description: 'The read preference for the main query to be executed.', + type: READ_PREFERENCE +}; +exports.READ_PREFERENCE_ATT = READ_PREFERENCE_ATT; +const INCLUDE_READ_PREFERENCE_ATT = { + description: 'The read preference for the queries to be executed to include fields.', + type: READ_PREFERENCE +}; +exports.INCLUDE_READ_PREFERENCE_ATT = INCLUDE_READ_PREFERENCE_ATT; +const SUBQUERY_READ_PREFERENCE_ATT = { + description: 'The read preference for the subqueries that may be required.', + type: READ_PREFERENCE +}; +exports.SUBQUERY_READ_PREFERENCE_ATT = SUBQUERY_READ_PREFERENCE_ATT; +const READ_OPTIONS_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'ReadOptionsInput', + description: 'The ReadOptionsInputt type is used in queries in order to set the read preferences.', + fields: { + readPreference: READ_PREFERENCE_ATT, + includeReadPreference: INCLUDE_READ_PREFERENCE_ATT, + subqueryReadPreference: SUBQUERY_READ_PREFERENCE_ATT + } +}); +exports.READ_OPTIONS_INPUT = READ_OPTIONS_INPUT; +const READ_OPTIONS_ATT = { + description: 'The read options for the query to be executed.', + type: READ_OPTIONS_INPUT +}; +exports.READ_OPTIONS_ATT = READ_OPTIONS_ATT; +const WHERE_ATT = { + description: 'These are the conditions that the objects need to match in order to be found', + type: OBJECT +}; +exports.WHERE_ATT = WHERE_ATT; +const SKIP_ATT = { + description: 'This is the number of objects that must be skipped to return.', + type: _graphql.GraphQLInt +}; +exports.SKIP_ATT = SKIP_ATT; +const LIMIT_ATT = { + description: 'This is the limit number of objects that must be returned.', + type: _graphql.GraphQLInt +}; +exports.LIMIT_ATT = LIMIT_ATT; +const COUNT_ATT = { + description: 'This is the total matched objecs count that is returned when the count flag is set.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLInt) +}; +exports.COUNT_ATT = COUNT_ATT; +const SEARCH_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SearchInput', + description: 'The SearchInput type is used to specifiy a search operation on a full text search.', + fields: { + term: { + description: 'This is the term to be searched.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + }, + language: { + description: 'This is the language to tetermine the list of stop words and the rules for tokenizer.', + type: _graphql.GraphQLString + }, + caseSensitive: { + description: 'This is the flag to enable or disable case sensitive search.', + type: _graphql.GraphQLBoolean + }, + diacriticSensitive: { + description: 'This is the flag to enable or disable diacritic sensitive search.', + type: _graphql.GraphQLBoolean + } + } +}); +exports.SEARCH_INPUT = SEARCH_INPUT; +const TEXT_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'TextInput', + description: 'The TextInput type is used to specify a text operation on a constraint.', + fields: { + search: { + description: 'This is the search to be executed.', + type: new _graphql.GraphQLNonNull(SEARCH_INPUT) + } + } +}); +exports.TEXT_INPUT = TEXT_INPUT; +const BOX_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'BoxInput', + description: 'The BoxInput type is used to specifiy a box operation on a within geo query.', + fields: { + bottomLeft: { + description: 'This is the bottom left coordinates of the box.', + type: new _graphql.GraphQLNonNull(GEO_POINT_INPUT) + }, + upperRight: { + description: 'This is the upper right coordinates of the box.', + type: new _graphql.GraphQLNonNull(GEO_POINT_INPUT) + } + } +}); +exports.BOX_INPUT = BOX_INPUT; +const WITHIN_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'WithinInput', + description: 'The WithinInput type is used to specify a within operation on a constraint.', + fields: { + box: { + description: 'This is the box to be specified.', + type: new _graphql.GraphQLNonNull(BOX_INPUT) + } + } +}); +exports.WITHIN_INPUT = WITHIN_INPUT; +const CENTER_SPHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'CenterSphereInput', + description: 'The CenterSphereInput type is used to specifiy a centerSphere operation on a geoWithin query.', + fields: { + center: { + description: 'This is the center of the sphere.', + type: new _graphql.GraphQLNonNull(GEO_POINT_INPUT) + }, + distance: { + description: 'This is the radius of the sphere.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLFloat) + } + } +}); +exports.CENTER_SPHERE_INPUT = CENTER_SPHERE_INPUT; +const GEO_WITHIN_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'GeoWithinInput', + description: 'The GeoWithinInput type is used to specify a geoWithin operation on a constraint.', + fields: { + polygon: { + description: 'This is the polygon to be specified.', + type: POLYGON_INPUT + }, + centerSphere: { + description: 'This is the sphere to be specified.', + type: CENTER_SPHERE_INPUT + } + } +}); +exports.GEO_WITHIN_INPUT = GEO_WITHIN_INPUT; +const GEO_INTERSECTS_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'GeoIntersectsInput', + description: 'The GeoIntersectsInput type is used to specify a geoIntersects operation on a constraint.', + fields: { + point: { + description: 'This is the point to be specified.', + type: GEO_POINT_INPUT + } + } +}); +exports.GEO_INTERSECTS_INPUT = GEO_INTERSECTS_INPUT; + +const equalTo = type => ({ + description: 'This is the equalTo operator to specify a constraint to select the objects where the value of a field equals to a specified value.', + type +}); + +exports.equalTo = equalTo; + +const notEqualTo = type => ({ + description: 'This is the notEqualTo operator to specify a constraint to select the objects where the value of a field do not equal to a specified value.', + type +}); + +exports.notEqualTo = notEqualTo; + +const lessThan = type => ({ + description: 'This is the lessThan operator to specify a constraint to select the objects where the value of a field is less than a specified value.', + type +}); + +exports.lessThan = lessThan; + +const lessThanOrEqualTo = type => ({ + description: 'This is the lessThanOrEqualTo operator to specify a constraint to select the objects where the value of a field is less than or equal to a specified value.', + type +}); + +exports.lessThanOrEqualTo = lessThanOrEqualTo; + +const greaterThan = type => ({ + description: 'This is the greaterThan operator to specify a constraint to select the objects where the value of a field is greater than a specified value.', + type +}); + +exports.greaterThan = greaterThan; + +const greaterThanOrEqualTo = type => ({ + description: 'This is the greaterThanOrEqualTo operator to specify a constraint to select the objects where the value of a field is greater than or equal to a specified value.', + type +}); + +exports.greaterThanOrEqualTo = greaterThanOrEqualTo; + +const inOp = type => ({ + description: 'This is the in operator to specify a constraint to select the objects where the value of a field equals any value in the specified array.', + type: new _graphql.GraphQLList(type) +}); + +exports.inOp = inOp; + +const notIn = type => ({ + description: 'This is the notIn operator to specify a constraint to select the objects where the value of a field do not equal any value in the specified array.', + type: new _graphql.GraphQLList(type) +}); + +exports.notIn = notIn; +const exists = { + description: 'This is the exists operator to specify a constraint to select the objects where a field exists (or do not exist).', + type: _graphql.GraphQLBoolean +}; +exports.exists = exists; +const matchesRegex = { + description: 'This is the matchesRegex operator to specify a constraint to select the objects where the value of a field matches a specified regular expression.', + type: _graphql.GraphQLString +}; +exports.matchesRegex = matchesRegex; +const options = { + description: 'This is the options operator to specify optional flags (such as "i" and "m") to be added to a matchesRegex operation in the same set of constraints.', + type: _graphql.GraphQLString +}; +exports.options = options; +const SUBQUERY_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SubqueryInput', + description: 'The SubqueryInput type is used to specify a sub query to another class.', + fields: { + className: CLASS_NAME_ATT, + where: Object.assign({}, WHERE_ATT, { + type: new _graphql.GraphQLNonNull(WHERE_ATT.type) + }) + } +}); +exports.SUBQUERY_INPUT = SUBQUERY_INPUT; +const SELECT_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SelectInput', + description: 'The SelectInput type is used to specify an inQueryKey or a notInQueryKey operation on a constraint.', + fields: { + query: { + description: 'This is the subquery to be executed.', + type: new _graphql.GraphQLNonNull(SUBQUERY_INPUT) + }, + key: { + description: 'This is the key in the result of the subquery that must match (not match) the field.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + } + } +}); +exports.SELECT_INPUT = SELECT_INPUT; +const inQueryKey = { + description: 'This is the inQueryKey operator to specify a constraint to select the objects where a field equals to a key in the result of a different query.', + type: SELECT_INPUT +}; +exports.inQueryKey = inQueryKey; +const notInQueryKey = { + description: 'This is the notInQueryKey operator to specify a constraint to select the objects where a field do not equal to a key in the result of a different query.', + type: SELECT_INPUT +}; +exports.notInQueryKey = notInQueryKey; +const ID_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'IdWhereInput', + description: 'The IdWhereInput input type is used in operations that involve filtering objects by an id.', + fields: { + equalTo: equalTo(_graphql.GraphQLID), + notEqualTo: notEqualTo(_graphql.GraphQLID), + lessThan: lessThan(_graphql.GraphQLID), + lessThanOrEqualTo: lessThanOrEqualTo(_graphql.GraphQLID), + greaterThan: greaterThan(_graphql.GraphQLID), + greaterThanOrEqualTo: greaterThanOrEqualTo(_graphql.GraphQLID), + in: inOp(_graphql.GraphQLID), + notIn: notIn(_graphql.GraphQLID), + exists, + inQueryKey, + notInQueryKey + } +}); +exports.ID_WHERE_INPUT = ID_WHERE_INPUT; +const STRING_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'StringWhereInput', + description: 'The StringWhereInput input type is used in operations that involve filtering objects by a field of type String.', + fields: { + equalTo: equalTo(_graphql.GraphQLString), + notEqualTo: notEqualTo(_graphql.GraphQLString), + lessThan: lessThan(_graphql.GraphQLString), + lessThanOrEqualTo: lessThanOrEqualTo(_graphql.GraphQLString), + greaterThan: greaterThan(_graphql.GraphQLString), + greaterThanOrEqualTo: greaterThanOrEqualTo(_graphql.GraphQLString), + in: inOp(_graphql.GraphQLString), + notIn: notIn(_graphql.GraphQLString), + exists, + matchesRegex, + options, + text: { + description: 'This is the $text operator to specify a full text search constraint.', + type: TEXT_INPUT + }, + inQueryKey, + notInQueryKey + } +}); +exports.STRING_WHERE_INPUT = STRING_WHERE_INPUT; +const NUMBER_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'NumberWhereInput', + description: 'The NumberWhereInput input type is used in operations that involve filtering objects by a field of type Number.', + fields: { + equalTo: equalTo(_graphql.GraphQLFloat), + notEqualTo: notEqualTo(_graphql.GraphQLFloat), + lessThan: lessThan(_graphql.GraphQLFloat), + lessThanOrEqualTo: lessThanOrEqualTo(_graphql.GraphQLFloat), + greaterThan: greaterThan(_graphql.GraphQLFloat), + greaterThanOrEqualTo: greaterThanOrEqualTo(_graphql.GraphQLFloat), + in: inOp(_graphql.GraphQLFloat), + notIn: notIn(_graphql.GraphQLFloat), + exists, + inQueryKey, + notInQueryKey + } +}); +exports.NUMBER_WHERE_INPUT = NUMBER_WHERE_INPUT; +const BOOLEAN_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'BooleanWhereInput', + description: 'The BooleanWhereInput input type is used in operations that involve filtering objects by a field of type Boolean.', + fields: { + equalTo: equalTo(_graphql.GraphQLBoolean), + notEqualTo: notEqualTo(_graphql.GraphQLBoolean), + exists, + inQueryKey, + notInQueryKey + } +}); +exports.BOOLEAN_WHERE_INPUT = BOOLEAN_WHERE_INPUT; +const ARRAY_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'ArrayWhereInput', + description: 'The ArrayWhereInput input type is used in operations that involve filtering objects by a field of type Array.', + fields: { + equalTo: equalTo(ANY), + notEqualTo: notEqualTo(ANY), + lessThan: lessThan(ANY), + lessThanOrEqualTo: lessThanOrEqualTo(ANY), + greaterThan: greaterThan(ANY), + greaterThanOrEqualTo: greaterThanOrEqualTo(ANY), + in: inOp(ANY), + notIn: notIn(ANY), + exists, + containedBy: { + description: 'This is the containedBy operator to specify a constraint to select the objects where the values of an array field is contained by another specified array.', + type: new _graphql.GraphQLList(ANY) + }, + contains: { + description: 'This is the contains operator to specify a constraint to select the objects where the values of an array field contain all elements of another specified array.', + type: new _graphql.GraphQLList(ANY) + }, + inQueryKey, + notInQueryKey + } +}); +exports.ARRAY_WHERE_INPUT = ARRAY_WHERE_INPUT; +const KEY_VALUE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'KeyValueInput', + description: 'An entry from an object, i.e., a pair of key and value.', + fields: { + key: { + description: 'The key used to retrieve the value of this entry.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + }, + value: { + description: 'The value of the entry. Could be any type of scalar data.', + type: new _graphql.GraphQLNonNull(ANY) + } + } +}); +exports.KEY_VALUE_INPUT = KEY_VALUE_INPUT; +const OBJECT_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'ObjectWhereInput', + description: 'The ObjectWhereInput input type is used in operations that involve filtering result by a field of type Object.', + fields: { + equalTo: equalTo(KEY_VALUE_INPUT), + notEqualTo: notEqualTo(KEY_VALUE_INPUT), + in: inOp(KEY_VALUE_INPUT), + notIn: notIn(KEY_VALUE_INPUT), + lessThan: lessThan(KEY_VALUE_INPUT), + lessThanOrEqualTo: lessThanOrEqualTo(KEY_VALUE_INPUT), + greaterThan: greaterThan(KEY_VALUE_INPUT), + greaterThanOrEqualTo: greaterThanOrEqualTo(KEY_VALUE_INPUT), + exists, + inQueryKey, + notInQueryKey + } +}); +exports.OBJECT_WHERE_INPUT = OBJECT_WHERE_INPUT; +const DATE_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'DateWhereInput', + description: 'The DateWhereInput input type is used in operations that involve filtering objects by a field of type Date.', + fields: { + equalTo: equalTo(DATE), + notEqualTo: notEqualTo(DATE), + lessThan: lessThan(DATE), + lessThanOrEqualTo: lessThanOrEqualTo(DATE), + greaterThan: greaterThan(DATE), + greaterThanOrEqualTo: greaterThanOrEqualTo(DATE), + in: inOp(DATE), + notIn: notIn(DATE), + exists, + inQueryKey, + notInQueryKey + } +}); +exports.DATE_WHERE_INPUT = DATE_WHERE_INPUT; +const BYTES_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'BytesWhereInput', + description: 'The BytesWhereInput input type is used in operations that involve filtering objects by a field of type Bytes.', + fields: { + equalTo: equalTo(BYTES), + notEqualTo: notEqualTo(BYTES), + lessThan: lessThan(BYTES), + lessThanOrEqualTo: lessThanOrEqualTo(BYTES), + greaterThan: greaterThan(BYTES), + greaterThanOrEqualTo: greaterThanOrEqualTo(BYTES), + in: inOp(BYTES), + notIn: notIn(BYTES), + exists, + inQueryKey, + notInQueryKey + } +}); +exports.BYTES_WHERE_INPUT = BYTES_WHERE_INPUT; +const FILE_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'FileWhereInput', + description: 'The FileWhereInput input type is used in operations that involve filtering objects by a field of type File.', + fields: { + equalTo: equalTo(FILE), + notEqualTo: notEqualTo(FILE), + lessThan: lessThan(FILE), + lessThanOrEqualTo: lessThanOrEqualTo(FILE), + greaterThan: greaterThan(FILE), + greaterThanOrEqualTo: greaterThanOrEqualTo(FILE), + in: inOp(FILE), + notIn: notIn(FILE), + exists, + matchesRegex, + options, + inQueryKey, + notInQueryKey + } +}); +exports.FILE_WHERE_INPUT = FILE_WHERE_INPUT; +const GEO_POINT_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'GeoPointWhereInput', + description: 'The GeoPointWhereInput input type is used in operations that involve filtering objects by a field of type GeoPoint.', + fields: { + exists, + nearSphere: { + description: 'This is the nearSphere operator to specify a constraint to select the objects where the values of a geo point field is near to another geo point.', + type: GEO_POINT_INPUT + }, + maxDistance: { + description: 'This is the maxDistance operator to specify a constraint to select the objects where the values of a geo point field is at a max distance (in radians) from the geo point specified in the $nearSphere operator.', + type: _graphql.GraphQLFloat + }, + maxDistanceInRadians: { + description: 'This is the maxDistanceInRadians operator to specify a constraint to select the objects where the values of a geo point field is at a max distance (in radians) from the geo point specified in the $nearSphere operator.', + type: _graphql.GraphQLFloat + }, + maxDistanceInMiles: { + description: 'This is the maxDistanceInMiles operator to specify a constraint to select the objects where the values of a geo point field is at a max distance (in miles) from the geo point specified in the $nearSphere operator.', + type: _graphql.GraphQLFloat + }, + maxDistanceInKilometers: { + description: 'This is the maxDistanceInKilometers operator to specify a constraint to select the objects where the values of a geo point field is at a max distance (in kilometers) from the geo point specified in the $nearSphere operator.', + type: _graphql.GraphQLFloat + }, + within: { + description: 'This is the within operator to specify a constraint to select the objects where the values of a geo point field is within a specified box.', + type: WITHIN_INPUT + }, + geoWithin: { + description: 'This is the geoWithin operator to specify a constraint to select the objects where the values of a geo point field is within a specified polygon or sphere.', + type: GEO_WITHIN_INPUT + } + } +}); +exports.GEO_POINT_WHERE_INPUT = GEO_POINT_WHERE_INPUT; +const POLYGON_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'PolygonWhereInput', + description: 'The PolygonWhereInput input type is used in operations that involve filtering objects by a field of type Polygon.', + fields: { + exists, + geoIntersects: { + description: 'This is the geoIntersects operator to specify a constraint to select the objects where the values of a polygon field intersect a specified point.', + type: GEO_INTERSECTS_INPUT + } + } +}); +exports.POLYGON_WHERE_INPUT = POLYGON_WHERE_INPUT; +const ELEMENT = new _graphql.GraphQLObjectType({ + name: 'Element', + description: "The Element object type is used to return array items' value.", + fields: { + value: { + description: 'Return the value of the element in the array', + type: new _graphql.GraphQLNonNull(ANY) + } + } +}); // Default static union type, we update types and resolveType function later + +exports.ELEMENT = ELEMENT; +let ARRAY_RESULT; +exports.ARRAY_RESULT = ARRAY_RESULT; + +const loadArrayResult = (parseGraphQLSchema, parseClasses) => { + const classTypes = parseClasses.filter(parseClass => parseGraphQLSchema.parseClassTypes[parseClass.className].classGraphQLOutputType ? true : false).map(parseClass => parseGraphQLSchema.parseClassTypes[parseClass.className].classGraphQLOutputType); + exports.ARRAY_RESULT = ARRAY_RESULT = new _graphql.GraphQLUnionType({ + name: 'ArrayResult', + description: 'Use Inline Fragment on Array to get results: https://graphql.org/learn/queries/#inline-fragments', + types: () => [ELEMENT, ...classTypes], + resolveType: value => { + if (value.__type === 'Object' && value.className && value.objectId) { + if (parseGraphQLSchema.parseClassTypes[value.className]) { + return parseGraphQLSchema.parseClassTypes[value.className].classGraphQLOutputType; + } else { + return ELEMENT; + } + } else { + return ELEMENT; + } + } + }); + parseGraphQLSchema.graphQLTypes.push(ARRAY_RESULT); +}; + +exports.loadArrayResult = loadArrayResult; + +const load = parseGraphQLSchema => { + parseGraphQLSchema.addGraphQLType(_links.GraphQLUpload, true); + parseGraphQLSchema.addGraphQLType(ANY, true); + parseGraphQLSchema.addGraphQLType(OBJECT, true); + parseGraphQLSchema.addGraphQLType(DATE, true); + parseGraphQLSchema.addGraphQLType(BYTES, true); + parseGraphQLSchema.addGraphQLType(FILE, true); + parseGraphQLSchema.addGraphQLType(FILE_INFO, true); + parseGraphQLSchema.addGraphQLType(FILE_INPUT, true); + parseGraphQLSchema.addGraphQLType(GEO_POINT_INPUT, true); + parseGraphQLSchema.addGraphQLType(GEO_POINT, true); + parseGraphQLSchema.addGraphQLType(PARSE_OBJECT, true); + parseGraphQLSchema.addGraphQLType(READ_PREFERENCE, true); + parseGraphQLSchema.addGraphQLType(READ_OPTIONS_INPUT, true); + parseGraphQLSchema.addGraphQLType(SEARCH_INPUT, true); + parseGraphQLSchema.addGraphQLType(TEXT_INPUT, true); + parseGraphQLSchema.addGraphQLType(BOX_INPUT, true); + parseGraphQLSchema.addGraphQLType(WITHIN_INPUT, true); + parseGraphQLSchema.addGraphQLType(CENTER_SPHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(GEO_WITHIN_INPUT, true); + parseGraphQLSchema.addGraphQLType(GEO_INTERSECTS_INPUT, true); + parseGraphQLSchema.addGraphQLType(ID_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(STRING_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(NUMBER_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(BOOLEAN_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(ARRAY_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(KEY_VALUE_INPUT, true); + parseGraphQLSchema.addGraphQLType(OBJECT_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(DATE_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(BYTES_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(FILE_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(GEO_POINT_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(POLYGON_WHERE_INPUT, true); + parseGraphQLSchema.addGraphQLType(ELEMENT, true); + parseGraphQLSchema.addGraphQLType(ACL_INPUT, true); + parseGraphQLSchema.addGraphQLType(USER_ACL_INPUT, true); + parseGraphQLSchema.addGraphQLType(ROLE_ACL_INPUT, true); + parseGraphQLSchema.addGraphQLType(PUBLIC_ACL_INPUT, true); + parseGraphQLSchema.addGraphQLType(ACL, true); + parseGraphQLSchema.addGraphQLType(USER_ACL, true); + parseGraphQLSchema.addGraphQLType(ROLE_ACL, true); + parseGraphQLSchema.addGraphQLType(PUBLIC_ACL, true); + parseGraphQLSchema.addGraphQLType(SUBQUERY_INPUT, true); + parseGraphQLSchema.addGraphQLType(SELECT_INPUT, true); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxUeXBlcy5qcyJdLCJuYW1lcyI6WyJUeXBlVmFsaWRhdGlvbkVycm9yIiwiRXJyb3IiLCJjb25zdHJ1Y3RvciIsInZhbHVlIiwidHlwZSIsInBhcnNlU3RyaW5nVmFsdWUiLCJwYXJzZUludFZhbHVlIiwiaW50IiwiTnVtYmVyIiwiaXNJbnRlZ2VyIiwicGFyc2VGbG9hdFZhbHVlIiwiZmxvYXQiLCJpc05hTiIsInBhcnNlQm9vbGVhblZhbHVlIiwicGFyc2VWYWx1ZSIsImtpbmQiLCJLaW5kIiwiU1RSSU5HIiwiSU5UIiwiRkxPQVQiLCJCT09MRUFOIiwiTElTVCIsInBhcnNlTGlzdFZhbHVlcyIsInZhbHVlcyIsIk9CSkVDVCIsInBhcnNlT2JqZWN0RmllbGRzIiwiZmllbGRzIiwiQXJyYXkiLCJpc0FycmF5IiwibWFwIiwicmVkdWNlIiwib2JqZWN0IiwiZmllbGQiLCJuYW1lIiwiQU5ZIiwiR3JhcGhRTFNjYWxhclR5cGUiLCJkZXNjcmlwdGlvbiIsInNlcmlhbGl6ZSIsInBhcnNlTGl0ZXJhbCIsImFzdCIsInBhcnNlRGF0ZUlzb1ZhbHVlIiwiZGF0ZSIsIkRhdGUiLCJzZXJpYWxpemVEYXRlSXNvIiwidG9JU09TdHJpbmciLCJwYXJzZURhdGVJc29MaXRlcmFsIiwiREFURSIsIl9fdHlwZSIsImlzbyIsImZpbmQiLCJCWVRFUyIsImJhc2U2NCIsInBhcnNlRmlsZVZhbHVlIiwidXJsIiwidW5kZWZpbmVkIiwiRklMRSIsIkZJTEVfSU5GTyIsIkdyYXBoUUxPYmplY3RUeXBlIiwiR3JhcGhRTE5vbk51bGwiLCJHcmFwaFFMU3RyaW5nIiwiRklMRV9JTlBVVCIsIkdyYXBoUUxJbnB1dE9iamVjdFR5cGUiLCJmaWxlIiwidXBsb2FkIiwiR3JhcGhRTFVwbG9hZCIsInVubGluayIsIkdyYXBoUUxCb29sZWFuIiwiR0VPX1BPSU5UX0ZJRUxEUyIsImxhdGl0dWRlIiwiR3JhcGhRTEZsb2F0IiwibG9uZ2l0dWRlIiwiR0VPX1BPSU5UX0lOUFVUIiwiR0VPX1BPSU5UIiwiUE9MWUdPTl9JTlBVVCIsIkdyYXBoUUxMaXN0IiwiUE9MWUdPTiIsIlVTRVJfQUNMX0lOUFVUIiwidXNlcklkIiwiR3JhcGhRTElEIiwicmVhZCIsIndyaXRlIiwiUk9MRV9BQ0xfSU5QVVQiLCJyb2xlTmFtZSIsIlBVQkxJQ19BQ0xfSU5QVVQiLCJBQ0xfSU5QVVQiLCJ1c2VycyIsInJvbGVzIiwicHVibGljIiwiVVNFUl9BQ0wiLCJST0xFX0FDTCIsIlBVQkxJQ19BQ0wiLCJBQ0wiLCJyZXNvbHZlIiwicCIsIk9iamVjdCIsImtleXMiLCJmb3JFYWNoIiwicnVsZSIsImluZGV4T2YiLCJwdXNoIiwibGVuZ3RoIiwicmVwbGFjZSIsIk9CSkVDVF9JRCIsIkNMQVNTX05BTUVfQVRUIiwiR0xPQkFMX09SX09CSkVDVF9JRF9BVFQiLCJPQkpFQ1RfSURfQVRUIiwiQ1JFQVRFRF9BVF9BVFQiLCJVUERBVEVEX0FUX0FUVCIsIklOUFVUX0ZJRUxEUyIsIkNSRUFURV9SRVNVTFRfRklFTERTIiwib2JqZWN0SWQiLCJjcmVhdGVkQXQiLCJVUERBVEVfUkVTVUxUX0ZJRUxEUyIsInVwZGF0ZWRBdCIsIlBBUlNFX09CSkVDVF9GSUVMRFMiLCJQQVJTRV9PQkpFQ1QiLCJHcmFwaFFMSW50ZXJmYWNlVHlwZSIsIlNFU1NJT05fVE9LRU5fQVRUIiwiUkVBRF9QUkVGRVJFTkNFIiwiR3JhcGhRTEVudW1UeXBlIiwiUFJJTUFSWSIsIlBSSU1BUllfUFJFRkVSUkVEIiwiU0VDT05EQVJZIiwiU0VDT05EQVJZX1BSRUZFUlJFRCIsIk5FQVJFU1QiLCJSRUFEX1BSRUZFUkVOQ0VfQVRUIiwiSU5DTFVERV9SRUFEX1BSRUZFUkVOQ0VfQVRUIiwiU1VCUVVFUllfUkVBRF9QUkVGRVJFTkNFX0FUVCIsIlJFQURfT1BUSU9OU19JTlBVVCIsInJlYWRQcmVmZXJlbmNlIiwiaW5jbHVkZVJlYWRQcmVmZXJlbmNlIiwic3VicXVlcnlSZWFkUHJlZmVyZW5jZSIsIlJFQURfT1BUSU9OU19BVFQiLCJXSEVSRV9BVFQiLCJTS0lQX0FUVCIsIkdyYXBoUUxJbnQiLCJMSU1JVF9BVFQiLCJDT1VOVF9BVFQiLCJTRUFSQ0hfSU5QVVQiLCJ0ZXJtIiwibGFuZ3VhZ2UiLCJjYXNlU2Vuc2l0aXZlIiwiZGlhY3JpdGljU2Vuc2l0aXZlIiwiVEVYVF9JTlBVVCIsInNlYXJjaCIsIkJPWF9JTlBVVCIsImJvdHRvbUxlZnQiLCJ1cHBlclJpZ2h0IiwiV0lUSElOX0lOUFVUIiwiYm94IiwiQ0VOVEVSX1NQSEVSRV9JTlBVVCIsImNlbnRlciIsImRpc3RhbmNlIiwiR0VPX1dJVEhJTl9JTlBVVCIsInBvbHlnb24iLCJjZW50ZXJTcGhlcmUiLCJHRU9fSU5URVJTRUNUU19JTlBVVCIsInBvaW50IiwiZXF1YWxUbyIsIm5vdEVxdWFsVG8iLCJsZXNzVGhhbiIsImxlc3NUaGFuT3JFcXVhbFRvIiwiZ3JlYXRlclRoYW4iLCJncmVhdGVyVGhhbk9yRXF1YWxUbyIsImluT3AiLCJub3RJbiIsImV4aXN0cyIsIm1hdGNoZXNSZWdleCIsIm9wdGlvbnMiLCJTVUJRVUVSWV9JTlBVVCIsImNsYXNzTmFtZSIsIndoZXJlIiwiYXNzaWduIiwiU0VMRUNUX0lOUFVUIiwicXVlcnkiLCJrZXkiLCJpblF1ZXJ5S2V5Iiwibm90SW5RdWVyeUtleSIsIklEX1dIRVJFX0lOUFVUIiwiaW4iLCJTVFJJTkdfV0hFUkVfSU5QVVQiLCJ0ZXh0IiwiTlVNQkVSX1dIRVJFX0lOUFVUIiwiQk9PTEVBTl9XSEVSRV9JTlBVVCIsIkFSUkFZX1dIRVJFX0lOUFVUIiwiY29udGFpbmVkQnkiLCJjb250YWlucyIsIktFWV9WQUxVRV9JTlBVVCIsIk9CSkVDVF9XSEVSRV9JTlBVVCIsIkRBVEVfV0hFUkVfSU5QVVQiLCJCWVRFU19XSEVSRV9JTlBVVCIsIkZJTEVfV0hFUkVfSU5QVVQiLCJHRU9fUE9JTlRfV0hFUkVfSU5QVVQiLCJuZWFyU3BoZXJlIiwibWF4RGlzdGFuY2UiLCJtYXhEaXN0YW5jZUluUmFkaWFucyIsIm1heERpc3RhbmNlSW5NaWxlcyIsIm1heERpc3RhbmNlSW5LaWxvbWV0ZXJzIiwid2l0aGluIiwiZ2VvV2l0aGluIiwiUE9MWUdPTl9XSEVSRV9JTlBVVCIsImdlb0ludGVyc2VjdHMiLCJFTEVNRU5UIiwiQVJSQVlfUkVTVUxUIiwibG9hZEFycmF5UmVzdWx0IiwicGFyc2VHcmFwaFFMU2NoZW1hIiwicGFyc2VDbGFzc2VzIiwiY2xhc3NUeXBlcyIsImZpbHRlciIsInBhcnNlQ2xhc3MiLCJwYXJzZUNsYXNzVHlwZXMiLCJjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIiwiR3JhcGhRTFVuaW9uVHlwZSIsInR5cGVzIiwicmVzb2x2ZVR5cGUiLCJncmFwaFFMVHlwZXMiLCJsb2FkIiwiYWRkR3JhcGhRTFR5cGUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFnQkE7O0FBQ0E7Ozs7Ozs7O0FBRUEsTUFBTUEsbUJBQU4sU0FBa0NDLEtBQWxDLENBQXdDO0FBQ3RDQyxFQUFBQSxXQUFXLENBQUNDLEtBQUQsRUFBUUMsSUFBUixFQUFjO0FBQ3ZCLFVBQU8sR0FBRUQsS0FBTSxtQkFBa0JDLElBQUssRUFBdEM7QUFDRDs7QUFIcUM7Ozs7QUFNeEMsTUFBTUMsZ0JBQWdCLEdBQUdGLEtBQUssSUFBSTtBQUNoQyxNQUFJLE9BQU9BLEtBQVAsS0FBaUIsUUFBckIsRUFBK0I7QUFDN0IsV0FBT0EsS0FBUDtBQUNEOztBQUVELFFBQU0sSUFBSUgsbUJBQUosQ0FBd0JHLEtBQXhCLEVBQStCLFFBQS9CLENBQU47QUFDRCxDQU5EOzs7O0FBUUEsTUFBTUcsYUFBYSxHQUFHSCxLQUFLLElBQUk7QUFDN0IsTUFBSSxPQUFPQSxLQUFQLEtBQWlCLFFBQXJCLEVBQStCO0FBQzdCLFVBQU1JLEdBQUcsR0FBR0MsTUFBTSxDQUFDTCxLQUFELENBQWxCOztBQUNBLFFBQUlLLE1BQU0sQ0FBQ0MsU0FBUCxDQUFpQkYsR0FBakIsQ0FBSixFQUEyQjtBQUN6QixhQUFPQSxHQUFQO0FBQ0Q7QUFDRjs7QUFF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QUFBQSxrQkFBa0IsQ0FBQ1ksY0FBbkIsQ0FBa0MvSCxVQUFsQyxFQUE4QyxJQUE5QztBQUNBbUgsRUFBQUEsa0JBQWtCLENBQUNZLGNBQW5CLENBQWtDaEQsY0FBbEMsRUFBa0QsSUFBbEQ7QUFDQW9DLEVBQUFBLGtCQUFrQixDQUFDWSxjQUFuQixDQUFrQzVDLFlBQWxDLEVBQWdELElBQWhEO0FBQ0QsQ0E1Q0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBLaW5kLFxuICBHcmFwaFFMTm9uTnVsbCxcbiAgR3JhcGhRTFNjYWxhclR5cGUsXG4gIEdyYXBoUUxJRCxcbiAgR3JhcGhRTFN0cmluZyxcbiAgR3JhcGhRTE9iamVjdFR5cGUsXG4gIEdyYXBoUUxJbnRlcmZhY2VUeXBlLFxuICBHcmFwaFFMRW51bVR5cGUsXG4gIEdyYXBoUUxJbnQsXG4gIEdyYXBoUUxGbG9hdCxcbiAgR3JhcGhRTExpc3QsXG4gIEdyYXBoUUxJbnB1dE9iamVjdFR5cGUsXG4gIEdyYXBoUUxCb29sZWFuLFxuICBHcmFwaFFMVW5pb25UeXBlLFxufSBmcm9tICdncmFwaHFsJztcbmltcG9ydCB7IHRvR2xvYmFsSWQgfSBmcm9tICdncmFwaHFsLXJlbGF5JztcbmltcG9ydCB7IEdyYXBoUUxVcGxvYWQgfSBmcm9tICdAZ3JhcGhxbC10b29scy9saW5rcyc7XG5cbmNsYXNzIFR5cGVWYWxpZGF0aW9uRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKHZhbHVlLCB0eXBlKSB7XG4gICAgc3VwZXIoYCR7dmFsdWV9IGlzIG5vdCBhIHZhbGlkICR7dHlwZX1gKTtcbiAgfVxufVxuXG5jb25zdCBwYXJzZVN0cmluZ1ZhbHVlID0gdmFsdWUgPT4ge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHZhbHVlLCAnU3RyaW5nJyk7XG59O1xuXG5jb25zdCBwYXJzZUludFZhbHVlID0gdmFsdWUgPT4ge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIGNvbnN0IGludCA9IE51bWJlcih2YWx1ZSk7XG4gICAgaWYgKE51bWJlci5pc0ludGVnZXIoaW50KSkge1xuICAgICAgcmV0dXJuIGludDtcbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ0ludCcpO1xufTtcblxuY29uc3QgcGFyc2VGbG9hdFZhbHVlID0gdmFsdWUgPT4ge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIGNvbnN0IGZsb2F0ID0gTnVtYmVyKHZhbHVlKTtcbiAgICBpZiAoIWlzTmFOKGZsb2F0KSkge1xuICAgICAgcmV0dXJuIGZsb2F0O1xuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHZhbHVlLCAnRmxvYXQnKTtcbn07XG5cbmNvbnN0IHBhcnNlQm9vbGVhblZhbHVlID0gdmFsdWUgPT4ge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ0Jvb2xlYW4nKTtcbn07XG5cbmNvbnN0IHBhcnNlVmFsdWUgPSB2YWx1ZSA9PiB7XG4gIHN3aXRjaCAodmFsdWUua2luZCkge1xuICAgIGNhc2UgS2luZC5TVFJJTkc6XG4gICAgICByZXR1cm4gcGFyc2VTdHJpbmdWYWx1ZSh2YWx1ZS52YWx1ZSk7XG5cbiAgICBjYXNlIEtpbmQuSU5UOlxuICAgICAgcmV0dXJuIHBhcnNlSW50VmFsdWUodmFsdWUudmFsdWUpO1xuXG4gICAgY2FzZSBLaW5kLkZMT0FUOlxuICAgICAgcmV0dXJuIHBhcnNlRmxvYXRWYWx1ZSh2YWx1ZS52YWx1ZSk7XG5cbiAgICBjYXNlIEtpbmQuQk9PTEVBTjpcbiAgICAgIHJldHVybiBwYXJzZUJvb2xlYW5WYWx1ZSh2YWx1ZS52YWx1ZSk7XG5cbiAgICBjYXNlIEtpbmQuTElTVDpcbiAgICAgIHJldHVybiBwYXJzZUxpc3RWYWx1ZXModmFsdWUudmFsdWVzKTtcblxuICAgIGNhc2UgS2luZC5PQkpFQ1Q6XG4gICAgICByZXR1cm4gcGFyc2VPYmplY3RGaWVsZHModmFsdWUuZmllbGRzKTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gdmFsdWUudmFsdWU7XG4gIH1cbn07XG5cbmNvbnN0IHBhcnNlTGlzdFZhbHVlcyA9IHZhbHVlcyA9PiB7XG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlcykpIHtcbiAgICByZXR1cm4gdmFsdWVzLm1hcCh2YWx1ZSA9PiBwYXJzZVZhbHVlKHZhbHVlKSk7XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZXMsICdMaXN0Jyk7XG59O1xuXG5jb25zdCBwYXJzZU9iamVjdEZpZWxkcyA9IGZpZWxkcyA9PiB7XG4gIGlmIChBcnJheS5pc0FycmF5KGZpZWxkcykpIHtcbiAgICByZXR1cm4gZmllbGRzLnJlZHVjZShcbiAgICAgIChvYmplY3QsIGZpZWxkKSA9PiAoe1xuICAgICAgICAuLi5vYmplY3QsXG4gICAgICAgIFtmaWVsZC5uYW1lLnZhbHVlXTogcGFyc2VWYWx1ZShmaWVsZC52YWx1ZSksXG4gICAgICB9KSxcbiAgICAgIHt9XG4gICAgKTtcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKGZpZWxkcywgJ09iamVjdCcpO1xufTtcblxuY29uc3QgQU5ZID0gbmV3IEdyYXBoUUxTY2FsYXJUeXBlKHtcbiAgbmFtZTogJ0FueScsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgQW55IHNjYWxhciB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyBhbmQgdHlwZXMgdGhhdCBpbnZvbHZlIGFueSB0eXBlIG9mIHZhbHVlLicsXG4gIHBhcnNlVmFsdWU6IHZhbHVlID0+IHZhbHVlLFxuICBzZXJpYWxpemU6IHZhbHVlID0+IHZhbHVlLFxuICBwYXJzZUxpdGVyYWw6IGFzdCA9PiBwYXJzZVZhbHVlKGFzdCksXG59KTtcblxuY29uc3QgT0JKRUNUID0gbmV3IEdyYXBoUUxTY2FsYXJUeXBlKHtcbiAgbmFtZTogJ09iamVjdCcsXG4gIGRlc2NyaXB0aW9uOiAnVGhlIE9iamVjdCBzY2FsYXIgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgYW5kIHR5cGVzIHRoYXQgaW52b2x2ZSBvYmplY3RzLicsXG4gIHBhcnNlVmFsdWUodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHZhbHVlLCAnT2JqZWN0Jyk7XG4gIH0sXG4gIHNlcmlhbGl6ZSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdPYmplY3QnKTtcbiAgfSxcbiAgcGFyc2VMaXRlcmFsKGFzdCkge1xuICAgIGlmIChhc3Qua2luZCA9PT0gS2luZC5PQkpFQ1QpIHtcbiAgICAgIHJldHVybiBwYXJzZU9iamVjdEZpZWxkcyhhc3QuZmllbGRzKTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcihhc3Qua2luZCwgJ09iamVjdCcpO1xuICB9LFxufSk7XG5cbmNvbnN0IHBhcnNlRGF0ZUlzb1ZhbHVlID0gdmFsdWUgPT4ge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgaWYgKCFpc05hTihkYXRlKSkge1xuICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHZhbHVlLCAnRGF0ZScpO1xufTtcblxuY29uc3Qgc2VyaWFsaXplRGF0ZUlzbyA9IHZhbHVlID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgIHJldHVybiB2YWx1ZS50b0lTT1N0cmluZygpO1xuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdEYXRlJyk7XG59O1xuXG5jb25zdCBwYXJzZURhdGVJc29MaXRlcmFsID0gYXN0ID0+IHtcbiAgaWYgKGFzdC5raW5kID09PSBLaW5kLlNUUklORykge1xuICAgIHJldHVybiBwYXJzZURhdGVJc29WYWx1ZShhc3QudmFsdWUpO1xuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IoYXN0LmtpbmQsICdEYXRlJyk7XG59O1xuXG5jb25zdCBEQVRFID0gbmV3IEdyYXBoUUxTY2FsYXJUeXBlKHtcbiAgbmFtZTogJ0RhdGUnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBEYXRlIHNjYWxhciB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyBhbmQgdHlwZXMgdGhhdCBpbnZvbHZlIGRhdGVzLicsXG4gIHBhcnNlVmFsdWUodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyB8fCB2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIF9fdHlwZTogJ0RhdGUnLFxuICAgICAgICBpc286IHBhcnNlRGF0ZUlzb1ZhbHVlKHZhbHVlKSxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlLl9fdHlwZSA9PT0gJ0RhdGUnICYmIHZhbHVlLmlzbykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgX190eXBlOiB2YWx1ZS5fX3R5cGUsXG4gICAgICAgIGlzbzogcGFyc2VEYXRlSXNvVmFsdWUodmFsdWUuaXNvKSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdEYXRlJyk7XG4gIH0sXG4gIHNlcmlhbGl6ZSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnIHx8IHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgcmV0dXJuIHNlcmlhbGl6ZURhdGVJc28odmFsdWUpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZS5fX3R5cGUgPT09ICdEYXRlJyAmJiB2YWx1ZS5pc28pIHtcbiAgICAgIHJldHVybiBzZXJpYWxpemVEYXRlSXNvKHZhbHVlLmlzbyk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdEYXRlJyk7XG4gIH0sXG4gIHBhcnNlTGl0ZXJhbChhc3QpIHtcbiAgICBpZiAoYXN0LmtpbmQgPT09IEtpbmQuU1RSSU5HKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBfX3R5cGU6ICdEYXRlJyxcbiAgICAgICAgaXNvOiBwYXJzZURhdGVJc29MaXRlcmFsKGFzdCksXG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoYXN0LmtpbmQgPT09IEtpbmQuT0JKRUNUKSB7XG4gICAgICBjb25zdCBfX3R5cGUgPSBhc3QuZmllbGRzLmZpbmQoZmllbGQgPT4gZmllbGQubmFtZS52YWx1ZSA9PT0gJ19fdHlwZScpO1xuICAgICAgY29uc3QgaXNvID0gYXN0LmZpZWxkcy5maW5kKGZpZWxkID0+IGZpZWxkLm5hbWUudmFsdWUgPT09ICdpc28nKTtcbiAgICAgIGlmIChfX3R5cGUgJiYgX190eXBlLnZhbHVlICYmIF9fdHlwZS52YWx1ZS52YWx1ZSA9PT0gJ0RhdGUnICYmIGlzbykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIF9fdHlwZTogX190eXBlLnZhbHVlLnZhbHVlLFxuICAgICAgICAgIGlzbzogcGFyc2VEYXRlSXNvTGl0ZXJhbChpc28udmFsdWUpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKGFzdC5raW5kLCAnRGF0ZScpO1xuICB9LFxufSk7XG5cbmNvbnN0IEJZVEVTID0gbmV3IEdyYXBoUUxTY2FsYXJUeXBlKHtcbiAgbmFtZTogJ0J5dGVzJyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBCeXRlcyBzY2FsYXIgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgYW5kIHR5cGVzIHRoYXQgaW52b2x2ZSBiYXNlIDY0IGJpbmFyeSBkYXRhLicsXG4gIHBhcnNlVmFsdWUodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgX190eXBlOiAnQnl0ZXMnLFxuICAgICAgICBiYXNlNjQ6IHZhbHVlLFxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJlxuICAgICAgdmFsdWUuX190eXBlID09PSAnQnl0ZXMnICYmXG4gICAgICB0eXBlb2YgdmFsdWUuYmFzZTY0ID09PSAnc3RyaW5nJ1xuICAgICkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHZhbHVlLCAnQnl0ZXMnKTtcbiAgfSxcbiAgc2VyaWFsaXplKHZhbHVlKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJlxuICAgICAgdmFsdWUuX190eXBlID09PSAnQnl0ZXMnICYmXG4gICAgICB0eXBlb2YgdmFsdWUuYmFzZTY0ID09PSAnc3RyaW5nJ1xuICAgICkge1xuICAgICAgcmV0dXJuIHZhbHVlLmJhc2U2NDtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ0J5dGVzJyk7XG4gIH0sXG4gIHBhcnNlTGl0ZXJhbChhc3QpIHtcbiAgICBpZiAoYXN0LmtpbmQgPT09IEtpbmQuU1RSSU5HKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBfX3R5cGU6ICdCeXRlcycsXG4gICAgICAgIGJhc2U2NDogYXN0LnZhbHVlLFxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKGFzdC5raW5kID09PSBLaW5kLk9CSkVDVCkge1xuICAgICAgY29uc3QgX190eXBlID0gYXN0LmZpZWxkcy5maW5kKGZpZWxkID0+IGZpZWxkLm5hbWUudmFsdWUgPT09ICdfX3R5cGUnKTtcbiAgICAgIGNvbnN0IGJhc2U2NCA9IGFzdC5maWVsZHMuZmluZChmaWVsZCA9PiBmaWVsZC5uYW1lLnZhbHVlID09PSAnYmFzZTY0Jyk7XG4gICAgICBpZiAoXG4gICAgICAgIF9fdHlwZSAmJlxuICAgICAgICBfX3R5cGUudmFsdWUgJiZcbiAgICAgICAgX190eXBlLnZhbHVlLnZhbHVlID09PSAnQnl0ZXMnICYmXG4gICAgICAgIGJhc2U2NCAmJlxuICAgICAgICBiYXNlNjQudmFsdWUgJiZcbiAgICAgICAgdHlwZW9mIGJhc2U2NC52YWx1ZS52YWx1ZSA9PT0gJ3N0cmluZydcbiAgICAgICkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIF9fdHlwZTogX190eXBlLnZhbHVlLnZhbHVlLFxuICAgICAgICAgIGJhc2U2NDogYmFzZTY0LnZhbHVlLnZhbHVlLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKGFzdC5raW5kLCAnQnl0ZXMnKTtcbiAgfSxcbn0pO1xuXG5jb25zdCBwYXJzZUZpbGVWYWx1ZSA9IHZhbHVlID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4ge1xuICAgICAgX190eXBlOiAnRmlsZScsXG4gICAgICBuYW1lOiB2YWx1ZSxcbiAgICB9O1xuICB9IGVsc2UgaWYgKFxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICB2YWx1ZS5fX3R5cGUgPT09ICdGaWxlJyAmJlxuICAgIHR5cGVvZiB2YWx1ZS5uYW1lID09PSAnc3RyaW5nJyAmJlxuICAgICh2YWx1ZS51cmwgPT09IHVuZGVmaW5lZCB8fCB0eXBlb2YgdmFsdWUudXJsID09PSAnc3RyaW5nJylcbiAgKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdGaWxlJyk7XG59O1xuXG5jb25zdCBGSUxFID0gbmV3IEdyYXBoUUxTY2FsYXJUeXBlKHtcbiAgbmFtZTogJ0ZpbGUnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBGaWxlIHNjYWxhciB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyBhbmQgdHlwZXMgdGhhdCBpbnZvbHZlIGZpbGVzLicsXG4gIHBhcnNlVmFsdWU6IHBhcnNlRmlsZVZhbHVlLFxuICBzZXJpYWxpemU6IHZhbHVlID0+IHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICB2YWx1ZS5fX3R5cGUgPT09ICdGaWxlJyAmJlxuICAgICAgdHlwZW9mIHZhbHVlLm5hbWUgPT09ICdzdHJpbmcnICYmXG4gICAgICAodmFsdWUudXJsID09PSB1bmRlZmluZWQgfHwgdHlwZW9mIHZhbHVlLnVybCA9PT0gJ3N0cmluZycpXG4gICAgKSB7XG4gICAgICByZXR1cm4gdmFsdWUubmFtZTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ0ZpbGUnKTtcbiAgfSxcbiAgcGFyc2VMaXRlcmFsKGFzdCkge1xuICAgIGlmIChhc3Qua2luZCA9PT0gS2luZC5TVFJJTkcpIHtcbiAgICAgIHJldHVybiBwYXJzZUZpbGVWYWx1ZShhc3QudmFsdWUpO1xuICAgIH0gZWxzZSBpZiAoYXN0LmtpbmQgPT09IEtpbmQuT0JKRUNUKSB7XG4gICAgICBjb25zdCBfX3R5cGUgPSBhc3QuZmllbGRzLmZpbmQoZmllbGQgPT4gZmllbGQubmFtZS52YWx1ZSA9PT0gJ19fdHlwZScpO1xuICAgICAgY29uc3QgbmFtZSA9IGFzdC5maWVsZHMuZmluZChmaWVsZCA9PiBmaWVsZC5uYW1lLnZhbHVlID09PSAnbmFtZScpO1xuICAgICAgY29uc3QgdXJsID0gYXN0LmZpZWxkcy5maW5kKGZpZWxkID0+IGZpZWxkLm5hbWUudmFsdWUgPT09ICd1cmwnKTtcbiAgICAgIGlmIChfX3R5cGUgJiYgX190eXBlLnZhbHVlICYmIG5hbWUgJiYgbmFtZS52YWx1ZSkge1xuICAgICAgICByZXR1cm4gcGFyc2VGaWxlVmFsdWUoe1xuICAgICAgICAgIF9fdHlwZTogX190eXBlLnZhbHVlLnZhbHVlLFxuICAgICAgICAgIG5hbWU6IG5hbWUudmFsdWUudmFsdWUsXG4gICAgICAgICAgdXJsOiB1cmwgJiYgdXJsLnZhbHVlID8gdXJsLnZhbHVlLnZhbHVlIDogdW5kZWZpbmVkLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcihhc3Qua2luZCwgJ0ZpbGUnKTtcbiAgfSxcbn0pO1xuXG5jb25zdCBGSUxFX0lORk8gPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICBuYW1lOiAnRmlsZUluZm8nLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBGaWxlSW5mbyBvYmplY3QgdHlwZSBpcyB1c2VkIHRvIHJldHVybiB0aGUgaW5mb3JtYXRpb24gYWJvdXQgZmlsZXMuJyxcbiAgZmllbGRzOiB7XG4gICAgbmFtZToge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBmaWxlIG5hbWUuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbiAgICB9LFxuICAgIHVybDoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSB1cmwgaW4gd2hpY2ggdGhlIGZpbGUgY2FuIGJlIGRvd25sb2FkZWQuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IEZJTEVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdGaWxlSW5wdXQnLFxuICBmaWVsZHM6IHtcbiAgICBmaWxlOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0EgRmlsZSBTY2FsYXIgY2FuIGJlIGFuIHVybCBvciBhIEZpbGVJbmZvIG9iamVjdC4gSWYgdGhpcyBmaWVsZCBpcyBzZXQgdG8gbnVsbCB0aGUgZmlsZSB3aWxsIGJlIHVubGlua2VkLicsXG4gICAgICB0eXBlOiBGSUxFLFxuICAgIH0sXG4gICAgdXBsb2FkOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1VzZSB0aGlzIGZpZWxkIGlmIHlvdSB3YW50IHRvIGNyZWF0ZSBhIG5ldyBmaWxlLicsXG4gICAgICB0eXBlOiBHcmFwaFFMVXBsb2FkLFxuICAgIH0sXG4gICAgdW5saW5rOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1VzZSB0aGlzIGZpZWxkIGlmIHlvdSB3YW50IHRvIHVubGluayB0aGUgZmlsZSAodGhlIGZpbGUgd2lsbCBub3QgYmUgZGVsZXRlZCBvbiBjbG91ZCBzdG9yYWdlKScsXG4gICAgICB0eXBlOiBHcmFwaFFMQm9vbGVhbixcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IEdFT19QT0lOVF9GSUVMRFMgPSB7XG4gIGxhdGl0dWRlOiB7XG4gICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBsYXRpdHVkZS4nLFxuICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMRmxvYXQpLFxuICB9LFxuICBsb25naXR1ZGU6IHtcbiAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGxvbmdpdHVkZS4nLFxuICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMRmxvYXQpLFxuICB9LFxufTtcblxuY29uc3QgR0VPX1BPSU5UX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnR2VvUG9pbnRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgR2VvUG9pbnRJbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgaW5wdXR0aW5nIGZpZWxkcyBvZiB0eXBlIGdlbyBwb2ludC4nLFxuICBmaWVsZHM6IEdFT19QT0lOVF9GSUVMRFMsXG59KTtcblxuY29uc3QgR0VPX1BPSU5UID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0dlb1BvaW50JyxcbiAgZGVzY3JpcHRpb246ICdUaGUgR2VvUG9pbnQgb2JqZWN0IHR5cGUgaXMgdXNlZCB0byByZXR1cm4gdGhlIGluZm9ybWF0aW9uIGFib3V0IGdlbyBwb2ludCBmaWVsZHMuJyxcbiAgZmllbGRzOiBHRU9fUE9JTlRfRklFTERTLFxufSk7XG5cbmNvbnN0IFBPTFlHT05fSU5QVVQgPSBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKEdFT19QT0lOVF9JTlBVVCkpO1xuXG5jb25zdCBQT0xZR09OID0gbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChHRU9fUE9JTlQpKTtcblxuY29uc3QgVVNFUl9BQ0xfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdVc2VyQUNMSW5wdXQnLFxuICBkZXNjcmlwdGlvbjogJ0FsbG93IHRvIG1hbmFnZSB1c2VycyBpbiBBQ0wuJyxcbiAgZmllbGRzOiB7XG4gICAgdXNlcklkOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0lEIG9mIHRoZSB0YXJnZXR0ZWQgVXNlci4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxJRCksXG4gICAgfSxcbiAgICByZWFkOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0FsbG93IHRoZSB1c2VyIHRvIHJlYWQgdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gICAgd3JpdGU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQWxsb3cgdGhlIHVzZXIgdG8gd3JpdGUgb24gdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgUk9MRV9BQ0xfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdSb2xlQUNMSW5wdXQnLFxuICBkZXNjcmlwdGlvbjogJ0FsbG93IHRvIG1hbmFnZSByb2xlcyBpbiBBQ0wuJyxcbiAgZmllbGRzOiB7XG4gICAgcm9sZU5hbWU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnTmFtZSBvZiB0aGUgdGFyZ2V0dGVkIFJvbGUuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbiAgICB9LFxuICAgIHJlYWQ6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQWxsb3cgdXNlcnMgd2hvIGFyZSBtZW1iZXJzIG9mIHRoZSByb2xlIHRvIHJlYWQgdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gICAgd3JpdGU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQWxsb3cgdXNlcnMgd2hvIGFyZSBtZW1iZXJzIG9mIHRoZSByb2xlIHRvIHdyaXRlIG9uIHRoZSBjdXJyZW50IG9iamVjdC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxCb29sZWFuKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFBVQkxJQ19BQ0xfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdQdWJsaWNBQ0xJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOiAnQWxsb3cgdG8gbWFuYWdlIHB1YmxpYyByaWdodHMuJyxcbiAgZmllbGRzOiB7XG4gICAgcmVhZDoge1xuICAgICAgZGVzY3JpcHRpb246ICdBbGxvdyBhbnlvbmUgdG8gcmVhZCB0aGUgY3VycmVudCBvYmplY3QuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMQm9vbGVhbiksXG4gICAgfSxcbiAgICB3cml0ZToge1xuICAgICAgZGVzY3JpcHRpb246ICdBbGxvdyBhbnlvbmUgdG8gd3JpdGUgb24gdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgQUNMX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnQUNMSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnQWxsb3cgdG8gbWFuYWdlIGFjY2VzcyByaWdodHMuIElmIG5vdCBwcm92aWRlZCBvYmplY3Qgd2lsbCBiZSBwdWJsaWNseSByZWFkYWJsZSBhbmQgd3JpdGFibGUnLFxuICBmaWVsZHM6IHtcbiAgICB1c2Vyczoge1xuICAgICAgZGVzY3JpcHRpb246ICdBY2Nlc3MgY29udHJvbCBsaXN0IGZvciB1c2Vycy4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChVU0VSX0FDTF9JTlBVVCkpLFxuICAgIH0sXG4gICAgcm9sZXM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQWNjZXNzIGNvbnRyb2wgbGlzdCBmb3Igcm9sZXMuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoUk9MRV9BQ0xfSU5QVVQpKSxcbiAgICB9LFxuICAgIHB1YmxpYzoge1xuICAgICAgZGVzY3JpcHRpb246ICdQdWJsaWMgYWNjZXNzIGNvbnRyb2wgbGlzdC4nLFxuICAgICAgdHlwZTogUFVCTElDX0FDTF9JTlBVVCxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFVTRVJfQUNMID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1VzZXJBQ0wnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnQWxsb3cgdG8gbWFuYWdlIHVzZXJzIGluIEFDTC4gSWYgcmVhZCBhbmQgd3JpdGUgYXJlIG51bGwgdGhlIHVzZXJzIGhhdmUgcmVhZCBhbmQgd3JpdGUgcmlnaHRzLicsXG4gIGZpZWxkczoge1xuICAgIHVzZXJJZDoge1xuICAgICAgZGVzY3JpcHRpb246ICdJRCBvZiB0aGUgdGFyZ2V0dGVkIFVzZXIuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMSUQpLFxuICAgIH0sXG4gICAgcmVhZDoge1xuICAgICAgZGVzY3JpcHRpb246ICdBbGxvdyB0aGUgdXNlciB0byByZWFkIHRoZSBjdXJyZW50IG9iamVjdC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxCb29sZWFuKSxcbiAgICB9LFxuICAgIHdyaXRlOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0FsbG93IHRoZSB1c2VyIHRvIHdyaXRlIG9uIHRoZSBjdXJyZW50IG9iamVjdC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxCb29sZWFuKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFJPTEVfQUNMID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1JvbGVBQ0wnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnQWxsb3cgdG8gbWFuYWdlIHJvbGVzIGluIEFDTC4gSWYgcmVhZCBhbmQgd3JpdGUgYXJlIG51bGwgdGhlIHJvbGUgaGF2ZSByZWFkIGFuZCB3cml0ZSByaWdodHMuJyxcbiAgZmllbGRzOiB7XG4gICAgcm9sZU5hbWU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnTmFtZSBvZiB0aGUgdGFyZ2V0dGVkIFJvbGUuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMSUQpLFxuICAgIH0sXG4gICAgcmVhZDoge1xuICAgICAgZGVzY3JpcHRpb246ICdBbGxvdyB1c2VycyB3aG8gYXJlIG1lbWJlcnMgb2YgdGhlIHJvbGUgdG8gcmVhZCB0aGUgY3VycmVudCBvYmplY3QuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMQm9vbGVhbiksXG4gICAgfSxcbiAgICB3cml0ZToge1xuICAgICAgZGVzY3JpcHRpb246ICdBbGxvdyB1c2VycyB3aG8gYXJlIG1lbWJlcnMgb2YgdGhlIHJvbGUgdG8gd3JpdGUgb24gdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgUFVCTElDX0FDTCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdQdWJsaWNBQ0wnLFxuICBkZXNjcmlwdGlvbjogJ0FsbG93IHRvIG1hbmFnZSBwdWJsaWMgcmlnaHRzLicsXG4gIGZpZWxkczoge1xuICAgIHJlYWQ6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQWxsb3cgYW55b25lIHRvIHJlYWQgdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBHcmFwaFFMQm9vbGVhbixcbiAgICB9LFxuICAgIHdyaXRlOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0FsbG93IGFueW9uZSB0byB3cml0ZSBvbiB0aGUgY3VycmVudCBvYmplY3QuJyxcbiAgICAgIHR5cGU6IEdyYXBoUUxCb29sZWFuLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgQUNMID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0FDTCcsXG4gIGRlc2NyaXB0aW9uOiAnQ3VycmVudCBhY2Nlc3MgY29udHJvbCBsaXN0IG9mIHRoZSBjdXJyZW50IG9iamVjdC4nLFxuICBmaWVsZHM6IHtcbiAgICB1c2Vyczoge1xuICAgICAgZGVzY3JpcHRpb246ICdBY2Nlc3MgY29udHJvbCBsaXN0IGZvciB1c2Vycy4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChVU0VSX0FDTCkpLFxuICAgICAgcmVzb2x2ZShwKSB7XG4gICAgICAgIGNvbnN0IHVzZXJzID0gW107XG4gICAgICAgIE9iamVjdC5rZXlzKHApLmZvckVhY2gocnVsZSA9PiB7XG4gICAgICAgICAgaWYgKHJ1bGUgIT09ICcqJyAmJiBydWxlLmluZGV4T2YoJ3JvbGU6JykgIT09IDApIHtcbiAgICAgICAgICAgIHVzZXJzLnB1c2goe1xuICAgICAgICAgICAgICB1c2VySWQ6IHRvR2xvYmFsSWQoJ19Vc2VyJywgcnVsZSksXG4gICAgICAgICAgICAgIHJlYWQ6IHBbcnVsZV0ucmVhZCA/IHRydWUgOiBmYWxzZSxcbiAgICAgICAgICAgICAgd3JpdGU6IHBbcnVsZV0ud3JpdGUgPyB0cnVlIDogZmFsc2UsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdXNlcnMubGVuZ3RoID8gdXNlcnMgOiBudWxsO1xuICAgICAgfSxcbiAgICB9LFxuICAgIHJvbGVzOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0FjY2VzcyBjb250cm9sIGxpc3QgZm9yIHJvbGVzLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKFJPTEVfQUNMKSksXG4gICAgICByZXNvbHZlKHApIHtcbiAgICAgICAgY29uc3Qgcm9sZXMgPSBbXTtcbiAgICAgICAgT2JqZWN0LmtleXMocCkuZm9yRWFjaChydWxlID0+IHtcbiAgICAgICAgICBpZiAocnVsZS5pbmRleE9mKCdyb2xlOicpID09PSAwKSB7XG4gICAgICAgICAgICByb2xlcy5wdXNoKHtcbiAgICAgICAgICAgICAgcm9sZU5hbWU6IHJ1bGUucmVwbGFjZSgncm9sZTonLCAnJyksXG4gICAgICAgICAgICAgIHJlYWQ6IHBbcnVsZV0ucmVhZCA/IHRydWUgOiBmYWxzZSxcbiAgICAgICAgICAgICAgd3JpdGU6IHBbcnVsZV0ud3JpdGUgPyB0cnVlIDogZmFsc2UsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcm9sZXMubGVuZ3RoID8gcm9sZXMgOiBudWxsO1xuICAgICAgfSxcbiAgICB9LFxuICAgIHB1YmxpYzoge1xuICAgICAgZGVzY3JpcHRpb246ICdQdWJsaWMgYWNjZXNzIGNvbnRyb2wgbGlzdC4nLFxuICAgICAgdHlwZTogUFVCTElDX0FDTCxcbiAgICAgIHJlc29sdmUocCkge1xuICAgICAgICAvKiBlc2xpbnQtZGlzYWJsZSAqL1xuICAgICAgICByZXR1cm4gcFsnKiddXG4gICAgICAgICAgPyB7XG4gICAgICAgICAgICAgIHJlYWQ6IHBbJyonXS5yZWFkID8gdHJ1ZSA6IGZhbHNlLFxuICAgICAgICAgICAgICB3cml0ZTogcFsnKiddLndyaXRlID8gdHJ1ZSA6IGZhbHNlLFxuICAgICAgICAgICAgfVxuICAgICAgICAgIDogbnVsbDtcbiAgICAgIH0sXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBPQkpFQ1RfSUQgPSBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTElEKTtcblxuY29uc3QgQ0xBU1NfTkFNRV9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgY2xhc3MgbmFtZSBvZiB0aGUgb2JqZWN0LicsXG4gIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbn07XG5cbmNvbnN0IEdMT0JBTF9PUl9PQkpFQ1RfSURfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIG9iamVjdCBpZC4gWW91IGNhbiB1c2UgZWl0aGVyIHRoZSBnbG9iYWwgb3IgdGhlIG9iamVjdCBpZC4nLFxuICB0eXBlOiBPQkpFQ1RfSUQsXG59O1xuXG5jb25zdCBPQkpFQ1RfSURfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIG9iamVjdCBpZC4nLFxuICB0eXBlOiBPQkpFQ1RfSUQsXG59O1xuXG5jb25zdCBDUkVBVEVEX0FUX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBkYXRlIGluIHdoaWNoIHRoZSBvYmplY3Qgd2FzIGNyZWF0ZWQuJyxcbiAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKERBVEUpLFxufTtcblxuY29uc3QgVVBEQVRFRF9BVF9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgZGF0ZSBpbiB3aGljaCB0aGUgb2JqZWN0IHdhcyBsYXMgdXBkYXRlZC4nLFxuICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoREFURSksXG59O1xuXG5jb25zdCBJTlBVVF9GSUVMRFMgPSB7XG4gIEFDTDoge1xuICAgIHR5cGU6IEFDTCxcbiAgfSxcbn07XG5cbmNvbnN0IENSRUFURV9SRVNVTFRfRklFTERTID0ge1xuICBvYmplY3RJZDogT0JKRUNUX0lEX0FUVCxcbiAgY3JlYXRlZEF0OiBDUkVBVEVEX0FUX0FUVCxcbn07XG5cbmNvbnN0IFVQREFURV9SRVNVTFRfRklFTERTID0ge1xuICB1cGRhdGVkQXQ6IFVQREFURURfQVRfQVRULFxufTtcblxuY29uc3QgUEFSU0VfT0JKRUNUX0ZJRUxEUyA9IHtcbiAgLi4uQ1JFQVRFX1JFU1VMVF9GSUVMRFMsXG4gIC4uLlVQREFURV9SRVNVTFRfRklFTERTLFxuICAuLi5JTlBVVF9GSUVMRFMsXG4gIEFDTDoge1xuICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChBQ0wpLFxuICAgIHJlc29sdmU6ICh7IEFDTCB9KSA9PiAoQUNMID8gQUNMIDogeyAnKic6IHsgcmVhZDogdHJ1ZSwgd3JpdGU6IHRydWUgfSB9KSxcbiAgfSxcbn07XG5cbmNvbnN0IFBBUlNFX09CSkVDVCA9IG5ldyBHcmFwaFFMSW50ZXJmYWNlVHlwZSh7XG4gIG5hbWU6ICdQYXJzZU9iamVjdCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgUGFyc2VPYmplY3QgaW50ZXJmYWNlIHR5cGUgaXMgdXNlZCBhcyBhIGJhc2UgdHlwZSBmb3IgdGhlIGF1dG8gZ2VuZXJhdGVkIG9iamVjdCB0eXBlcy4nLFxuICBmaWVsZHM6IFBBUlNFX09CSkVDVF9GSUVMRFMsXG59KTtcblxuY29uc3QgU0VTU0lPTl9UT0tFTl9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhlIGN1cnJlbnQgdXNlciBzZXNzaW9uIHRva2VuLicsXG4gIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbn07XG5cbmNvbnN0IFJFQURfUFJFRkVSRU5DRSA9IG5ldyBHcmFwaFFMRW51bVR5cGUoe1xuICBuYW1lOiAnUmVhZFByZWZlcmVuY2UnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFJlYWRQcmVmZXJlbmNlIGVudW0gdHlwZSBpcyB1c2VkIGluIHF1ZXJpZXMgaW4gb3JkZXIgdG8gc2VsZWN0IGluIHdoaWNoIGRhdGFiYXNlIHJlcGxpY2EgdGhlIG9wZXJhdGlvbiBtdXN0IHJ1bi4nLFxuICB2YWx1ZXM6IHtcbiAgICBQUklNQVJZOiB7IHZhbHVlOiAnUFJJTUFSWScgfSxcbiAgICBQUklNQVJZX1BSRUZFUlJFRDogeyB2YWx1ZTogJ1BSSU1BUllfUFJFRkVSUkVEJyB9LFxuICAgIFNFQ09OREFSWTogeyB2YWx1ZTogJ1NFQ09OREFSWScgfSxcbiAgICBTRUNPTkRBUllfUFJFRkVSUkVEOiB7IHZhbHVlOiAnU0VDT05EQVJZX1BSRUZFUlJFRCcgfSxcbiAgICBORUFSRVNUOiB7IHZhbHVlOiAnTkVBUkVTVCcgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBSRUFEX1BSRUZFUkVOQ0VfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoZSByZWFkIHByZWZlcmVuY2UgZm9yIHRoZSBtYWluIHF1ZXJ5IHRvIGJlIGV4ZWN1dGVkLicsXG4gIHR5cGU6IFJFQURfUFJFRkVSRU5DRSxcbn07XG5cbmNvbnN0IElOQ0xVREVfUkVBRF9QUkVGRVJFTkNFX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246ICdUaGUgcmVhZCBwcmVmZXJlbmNlIGZvciB0aGUgcXVlcmllcyB0byBiZSBleGVjdXRlZCB0byBpbmNsdWRlIGZpZWxkcy4nLFxuICB0eXBlOiBSRUFEX1BSRUZFUkVOQ0UsXG59O1xuXG5jb25zdCBTVUJRVUVSWV9SRUFEX1BSRUZFUkVOQ0VfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoZSByZWFkIHByZWZlcmVuY2UgZm9yIHRoZSBzdWJxdWVyaWVzIHRoYXQgbWF5IGJlIHJlcXVpcmVkLicsXG4gIHR5cGU6IFJFQURfUFJFRkVSRU5DRSxcbn07XG5cbmNvbnN0IFJFQURfT1BUSU9OU19JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1JlYWRPcHRpb25zSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFJlYWRPcHRpb25zSW5wdXR0IHR5cGUgaXMgdXNlZCBpbiBxdWVyaWVzIGluIG9yZGVyIHRvIHNldCB0aGUgcmVhZCBwcmVmZXJlbmNlcy4nLFxuICBmaWVsZHM6IHtcbiAgICByZWFkUHJlZmVyZW5jZTogUkVBRF9QUkVGRVJFTkNFX0FUVCxcbiAgICBpbmNsdWRlUmVhZFByZWZlcmVuY2U6IElOQ0xVREVfUkVBRF9QUkVGRVJFTkNFX0FUVCxcbiAgICBzdWJxdWVyeVJlYWRQcmVmZXJlbmNlOiBTVUJRVUVSWV9SRUFEX1BSRUZFUkVOQ0VfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFJFQURfT1BUSU9OU19BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhlIHJlYWQgb3B0aW9ucyBmb3IgdGhlIHF1ZXJ5IHRvIGJlIGV4ZWN1dGVkLicsXG4gIHR5cGU6IFJFQURfT1BUSU9OU19JTlBVVCxcbn07XG5cbmNvbnN0IFdIRVJFX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIGNvbmRpdGlvbnMgdGhhdCB0aGUgb2JqZWN0cyBuZWVkIHRvIG1hdGNoIGluIG9yZGVyIHRvIGJlIGZvdW5kJyxcbiAgdHlwZTogT0JKRUNULFxufTtcblxuY29uc3QgU0tJUF9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgbnVtYmVyIG9mIG9iamVjdHMgdGhhdCBtdXN0IGJlIHNraXBwZWQgdG8gcmV0dXJuLicsXG4gIHR5cGU6IEdyYXBoUUxJbnQsXG59O1xuXG5jb25zdCBMSU1JVF9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgbGltaXQgbnVtYmVyIG9mIG9iamVjdHMgdGhhdCBtdXN0IGJlIHJldHVybmVkLicsXG4gIHR5cGU6IEdyYXBoUUxJbnQsXG59O1xuXG5jb25zdCBDT1VOVF9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSB0b3RhbCBtYXRjaGVkIG9iamVjcyBjb3VudCB0aGF0IGlzIHJldHVybmVkIHdoZW4gdGhlIGNvdW50IGZsYWcgaXMgc2V0LicsXG4gIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMSW50KSxcbn07XG5cbmNvbnN0IFNFQVJDSF9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NlYXJjaElucHV0JyxcbiAgZGVzY3JpcHRpb246ICdUaGUgU2VhcmNoSW5wdXQgdHlwZSBpcyB1c2VkIHRvIHNwZWNpZml5IGEgc2VhcmNoIG9wZXJhdGlvbiBvbiBhIGZ1bGwgdGV4dCBzZWFyY2guJyxcbiAgZmllbGRzOiB7XG4gICAgdGVybToge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSB0ZXJtIHRvIGJlIHNlYXJjaGVkLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgfSxcbiAgICBsYW5ndWFnZToge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSBsYW5ndWFnZSB0byB0ZXRlcm1pbmUgdGhlIGxpc3Qgb2Ygc3RvcCB3b3JkcyBhbmQgdGhlIHJ1bGVzIGZvciB0b2tlbml6ZXIuJyxcbiAgICAgIHR5cGU6IEdyYXBoUUxTdHJpbmcsXG4gICAgfSxcbiAgICBjYXNlU2Vuc2l0aXZlOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGZsYWcgdG8gZW5hYmxlIG9yIGRpc2FibGUgY2FzZSBzZW5zaXRpdmUgc2VhcmNoLicsXG4gICAgICB0eXBlOiBHcmFwaFFMQm9vbGVhbixcbiAgICB9LFxuICAgIGRpYWNyaXRpY1NlbnNpdGl2ZToge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBmbGFnIHRvIGVuYWJsZSBvciBkaXNhYmxlIGRpYWNyaXRpYyBzZW5zaXRpdmUgc2VhcmNoLicsXG4gICAgICB0eXBlOiBHcmFwaFFMQm9vbGVhbixcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFRFWFRfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdUZXh0SW5wdXQnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBUZXh0SW5wdXQgdHlwZSBpcyB1c2VkIHRvIHNwZWNpZnkgYSB0ZXh0IG9wZXJhdGlvbiBvbiBhIGNvbnN0cmFpbnQuJyxcbiAgZmllbGRzOiB7XG4gICAgc2VhcmNoOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIHNlYXJjaCB0byBiZSBleGVjdXRlZC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKFNFQVJDSF9JTlBVVCksXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBCT1hfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdCb3hJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOiAnVGhlIEJveElucHV0IHR5cGUgaXMgdXNlZCB0byBzcGVjaWZpeSBhIGJveCBvcGVyYXRpb24gb24gYSB3aXRoaW4gZ2VvIHF1ZXJ5LicsXG4gIGZpZWxkczoge1xuICAgIGJvdHRvbUxlZnQ6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgYm90dG9tIGxlZnQgY29vcmRpbmF0ZXMgb2YgdGhlIGJveC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdFT19QT0lOVF9JTlBVVCksXG4gICAgfSxcbiAgICB1cHBlclJpZ2h0OiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIHVwcGVyIHJpZ2h0IGNvb3JkaW5hdGVzIG9mIHRoZSBib3guJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHRU9fUE9JTlRfSU5QVVQpLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgV0lUSElOX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnV2l0aGluSW5wdXQnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBXaXRoaW5JbnB1dCB0eXBlIGlzIHVzZWQgdG8gc3BlY2lmeSBhIHdpdGhpbiBvcGVyYXRpb24gb24gYSBjb25zdHJhaW50LicsXG4gIGZpZWxkczoge1xuICAgIGJveDoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBib3ggdG8gYmUgc3BlY2lmaWVkLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoQk9YX0lOUFVUKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IENFTlRFUl9TUEhFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdDZW50ZXJTcGhlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgQ2VudGVyU3BoZXJlSW5wdXQgdHlwZSBpcyB1c2VkIHRvIHNwZWNpZml5IGEgY2VudGVyU3BoZXJlIG9wZXJhdGlvbiBvbiBhIGdlb1dpdGhpbiBxdWVyeS4nLFxuICBmaWVsZHM6IHtcbiAgICBjZW50ZXI6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgY2VudGVyIG9mIHRoZSBzcGhlcmUuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHRU9fUE9JTlRfSU5QVVQpLFxuICAgIH0sXG4gICAgZGlzdGFuY2U6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgcmFkaXVzIG9mIHRoZSBzcGhlcmUuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMRmxvYXQpLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgR0VPX1dJVEhJTl9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0dlb1dpdGhpbklucHV0JyxcbiAgZGVzY3JpcHRpb246ICdUaGUgR2VvV2l0aGluSW5wdXQgdHlwZSBpcyB1c2VkIHRvIHNwZWNpZnkgYSBnZW9XaXRoaW4gb3BlcmF0aW9uIG9uIGEgY29uc3RyYWludC4nLFxuICBmaWVsZHM6IHtcbiAgICBwb2x5Z29uOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIHBvbHlnb24gdG8gYmUgc3BlY2lmaWVkLicsXG4gICAgICB0eXBlOiBQT0xZR09OX0lOUFVULFxuICAgIH0sXG4gICAgY2VudGVyU3BoZXJlOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIHNwaGVyZSB0byBiZSBzcGVjaWZpZWQuJyxcbiAgICAgIHR5cGU6IENFTlRFUl9TUEhFUkVfSU5QVVQsXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBHRU9fSU5URVJTRUNUU19JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0dlb0ludGVyc2VjdHNJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgR2VvSW50ZXJzZWN0c0lucHV0IHR5cGUgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZ2VvSW50ZXJzZWN0cyBvcGVyYXRpb24gb24gYSBjb25zdHJhaW50LicsXG4gIGZpZWxkczoge1xuICAgIHBvaW50OiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIHBvaW50IHRvIGJlIHNwZWNpZmllZC4nLFxuICAgICAgdHlwZTogR0VPX1BPSU5UX0lOUFVULFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgZXF1YWxUbyA9IHR5cGUgPT4gKHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIGVxdWFsVG8gb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIHRoZSB2YWx1ZSBvZiBhIGZpZWxkIGVxdWFscyB0byBhIHNwZWNpZmllZCB2YWx1ZS4nLFxuICB0eXBlLFxufSk7XG5cbmNvbnN0IG5vdEVxdWFsVG8gPSB0eXBlID0+ICh7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBub3RFcXVhbFRvIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBkbyBub3QgZXF1YWwgdG8gYSBzcGVjaWZpZWQgdmFsdWUuJyxcbiAgdHlwZSxcbn0pO1xuXG5jb25zdCBsZXNzVGhhbiA9IHR5cGUgPT4gKHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIGxlc3NUaGFuIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBpcyBsZXNzIHRoYW4gYSBzcGVjaWZpZWQgdmFsdWUuJyxcbiAgdHlwZSxcbn0pO1xuXG5jb25zdCBsZXNzVGhhbk9yRXF1YWxUbyA9IHR5cGUgPT4gKHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIGxlc3NUaGFuT3JFcXVhbFRvIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gYSBzcGVjaWZpZWQgdmFsdWUuJyxcbiAgdHlwZSxcbn0pO1xuXG5jb25zdCBncmVhdGVyVGhhbiA9IHR5cGUgPT4gKHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIGdyZWF0ZXJUaGFuIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBpcyBncmVhdGVyIHRoYW4gYSBzcGVjaWZpZWQgdmFsdWUuJyxcbiAgdHlwZSxcbn0pO1xuXG5jb25zdCBncmVhdGVyVGhhbk9yRXF1YWxUbyA9IHR5cGUgPT4gKHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIGdyZWF0ZXJUaGFuT3JFcXVhbFRvIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYSBzcGVjaWZpZWQgdmFsdWUuJyxcbiAgdHlwZSxcbn0pO1xuXG5jb25zdCBpbk9wID0gdHlwZSA9PiAoe1xuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhpcyBpcyB0aGUgaW4gb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIHRoZSB2YWx1ZSBvZiBhIGZpZWxkIGVxdWFscyBhbnkgdmFsdWUgaW4gdGhlIHNwZWNpZmllZCBhcnJheS4nLFxuICB0eXBlOiBuZXcgR3JhcGhRTExpc3QodHlwZSksXG59KTtcblxuY29uc3Qgbm90SW4gPSB0eXBlID0+ICh7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBub3RJbiBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlIG9mIGEgZmllbGQgZG8gbm90IGVxdWFsIGFueSB2YWx1ZSBpbiB0aGUgc3BlY2lmaWVkIGFycmF5LicsXG4gIHR5cGU6IG5ldyBHcmFwaFFMTGlzdCh0eXBlKSxcbn0pO1xuXG5jb25zdCBleGlzdHMgPSB7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBleGlzdHMgb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIGEgZmllbGQgZXhpc3RzIChvciBkbyBub3QgZXhpc3QpLicsXG4gIHR5cGU6IEdyYXBoUUxCb29sZWFuLFxufTtcblxuY29uc3QgbWF0Y2hlc1JlZ2V4ID0ge1xuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhpcyBpcyB0aGUgbWF0Y2hlc1JlZ2V4IG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBtYXRjaGVzIGEgc3BlY2lmaWVkIHJlZ3VsYXIgZXhwcmVzc2lvbi4nLFxuICB0eXBlOiBHcmFwaFFMU3RyaW5nLFxufTtcblxuY29uc3Qgb3B0aW9ucyA9IHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIG9wdGlvbnMgb3BlcmF0b3IgdG8gc3BlY2lmeSBvcHRpb25hbCBmbGFncyAoc3VjaCBhcyBcImlcIiBhbmQgXCJtXCIpIHRvIGJlIGFkZGVkIHRvIGEgbWF0Y2hlc1JlZ2V4IG9wZXJhdGlvbiBpbiB0aGUgc2FtZSBzZXQgb2YgY29uc3RyYWludHMuJyxcbiAgdHlwZTogR3JhcGhRTFN0cmluZyxcbn07XG5cbmNvbnN0IFNVQlFVRVJZX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU3VicXVlcnlJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOiAnVGhlIFN1YnF1ZXJ5SW5wdXQgdHlwZSBpcyB1c2VkIHRvIHNwZWNpZnkgYSBzdWIgcXVlcnkgdG8gYW5vdGhlciBjbGFzcy4nLFxuICBmaWVsZHM6IHtcbiAgICBjbGFzc05hbWU6IENMQVNTX05BTUVfQVRULFxuICAgIHdoZXJlOiBPYmplY3QuYXNzaWduKHt9LCBXSEVSRV9BVFQsIHtcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChXSEVSRV9BVFQudHlwZSksXG4gICAgfSksXG4gIH0sXG59KTtcblxuY29uc3QgU0VMRUNUX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2VsZWN0SW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNlbGVjdElucHV0IHR5cGUgaXMgdXNlZCB0byBzcGVjaWZ5IGFuIGluUXVlcnlLZXkgb3IgYSBub3RJblF1ZXJ5S2V5IG9wZXJhdGlvbiBvbiBhIGNvbnN0cmFpbnQuJyxcbiAgZmllbGRzOiB7XG4gICAgcXVlcnk6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgc3VicXVlcnkgdG8gYmUgZXhlY3V0ZWQuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChTVUJRVUVSWV9JTlBVVCksXG4gICAgfSxcbiAgICBrZXk6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhpcyBpcyB0aGUga2V5IGluIHRoZSByZXN1bHQgb2YgdGhlIHN1YnF1ZXJ5IHRoYXQgbXVzdCBtYXRjaCAobm90IG1hdGNoKSB0aGUgZmllbGQuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IGluUXVlcnlLZXkgPSB7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBpblF1ZXJ5S2V5IG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSBhIGZpZWxkIGVxdWFscyB0byBhIGtleSBpbiB0aGUgcmVzdWx0IG9mIGEgZGlmZmVyZW50IHF1ZXJ5LicsXG4gIHR5cGU6IFNFTEVDVF9JTlBVVCxcbn07XG5cbmNvbnN0IG5vdEluUXVlcnlLZXkgPSB7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBub3RJblF1ZXJ5S2V5IG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSBhIGZpZWxkIGRvIG5vdCBlcXVhbCB0byBhIGtleSBpbiB0aGUgcmVzdWx0IG9mIGEgZGlmZmVyZW50IHF1ZXJ5LicsXG4gIHR5cGU6IFNFTEVDVF9JTlBVVCxcbn07XG5cbmNvbnN0IElEX1dIRVJFX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnSWRXaGVyZUlucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBJZFdoZXJlSW5wdXQgaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGZpbHRlcmluZyBvYmplY3RzIGJ5IGFuIGlkLicsXG4gIGZpZWxkczoge1xuICAgIGVxdWFsVG86IGVxdWFsVG8oR3JhcGhRTElEKSxcbiAgICBub3RFcXVhbFRvOiBub3RFcXVhbFRvKEdyYXBoUUxJRCksXG4gICAgbGVzc1RoYW46IGxlc3NUaGFuKEdyYXBoUUxJRCksXG4gICAgbGVzc1RoYW5PckVxdWFsVG86IGxlc3NUaGFuT3JFcXVhbFRvKEdyYXBoUUxJRCksXG4gICAgZ3JlYXRlclRoYW46IGdyZWF0ZXJUaGFuKEdyYXBoUUxJRCksXG4gICAgZ3JlYXRlclRoYW5PckVxdWFsVG86IGdyZWF0ZXJUaGFuT3JFcXVhbFRvKEdyYXBoUUxJRCksXG4gICAgaW46IGluT3AoR3JhcGhRTElEKSxcbiAgICBub3RJbjogbm90SW4oR3JhcGhRTElEKSxcbiAgICBleGlzdHMsXG4gICAgaW5RdWVyeUtleSxcbiAgICBub3RJblF1ZXJ5S2V5LFxuICB9LFxufSk7XG5cbmNvbnN0IFNUUklOR19XSEVSRV9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1N0cmluZ1doZXJlSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFN0cmluZ1doZXJlSW5wdXQgaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGZpbHRlcmluZyBvYmplY3RzIGJ5IGEgZmllbGQgb2YgdHlwZSBTdHJpbmcuJyxcbiAgZmllbGRzOiB7XG4gICAgZXF1YWxUbzogZXF1YWxUbyhHcmFwaFFMU3RyaW5nKSxcbiAgICBub3RFcXVhbFRvOiBub3RFcXVhbFRvKEdyYXBoUUxTdHJpbmcpLFxuICAgIGxlc3NUaGFuOiBsZXNzVGhhbihHcmFwaFFMU3RyaW5nKSxcbiAgICBsZXNzVGhhbk9yRXF1YWxUbzogbGVzc1RoYW5PckVxdWFsVG8oR3JhcGhRTFN0cmluZyksXG4gICAgZ3JlYXRlclRoYW46IGdyZWF0ZXJUaGFuKEdyYXBoUUxTdHJpbmcpLFxuICAgIGdyZWF0ZXJUaGFuT3JFcXVhbFRvOiBncmVhdGVyVGhhbk9yRXF1YWxUbyhHcmFwaFFMU3RyaW5nKSxcbiAgICBpbjogaW5PcChHcmFwaFFMU3RyaW5nKSxcbiAgICBub3RJbjogbm90SW4oR3JhcGhRTFN0cmluZyksXG4gICAgZXhpc3RzLFxuICAgIG1hdGNoZXNSZWdleCxcbiAgICBvcHRpb25zLFxuICAgIHRleHQ6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgJHRleHQgb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGZ1bGwgdGV4dCBzZWFyY2ggY29uc3RyYWludC4nLFxuICAgICAgdHlwZTogVEVYVF9JTlBVVCxcbiAgICB9LFxuICAgIGluUXVlcnlLZXksXG4gICAgbm90SW5RdWVyeUtleSxcbiAgfSxcbn0pO1xuXG5jb25zdCBOVU1CRVJfV0hFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdOdW1iZXJXaGVyZUlucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBOdW1iZXJXaGVyZUlucHV0IGlucHV0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBmaWx0ZXJpbmcgb2JqZWN0cyBieSBhIGZpZWxkIG9mIHR5cGUgTnVtYmVyLicsXG4gIGZpZWxkczoge1xuICAgIGVxdWFsVG86IGVxdWFsVG8oR3JhcGhRTEZsb2F0KSxcbiAgICBub3RFcXVhbFRvOiBub3RFcXVhbFRvKEdyYXBoUUxGbG9hdCksXG4gICAgbGVzc1RoYW46IGxlc3NUaGFuKEdyYXBoUUxGbG9hdCksXG4gICAgbGVzc1RoYW5PckVxdWFsVG86IGxlc3NUaGFuT3JFcXVhbFRvKEdyYXBoUUxGbG9hdCksXG4gICAgZ3JlYXRlclRoYW46IGdyZWF0ZXJUaGFuKEdyYXBoUUxGbG9hdCksXG4gICAgZ3JlYXRlclRoYW5PckVxdWFsVG86IGdyZWF0ZXJUaGFuT3JFcXVhbFRvKEdyYXBoUUxGbG9hdCksXG4gICAgaW46IGluT3AoR3JhcGhRTEZsb2F0KSxcbiAgICBub3RJbjogbm90SW4oR3JhcGhRTEZsb2F0KSxcbiAgICBleGlzdHMsXG4gICAgaW5RdWVyeUtleSxcbiAgICBub3RJblF1ZXJ5S2V5LFxuICB9LFxufSk7XG5cbmNvbnN0IEJPT0xFQU5fV0hFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdCb29sZWFuV2hlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgQm9vbGVhbldoZXJlSW5wdXQgaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGZpbHRlcmluZyBvYmplY3RzIGJ5IGEgZmllbGQgb2YgdHlwZSBCb29sZWFuLicsXG4gIGZpZWxkczoge1xuICAgIGVxdWFsVG86IGVxdWFsVG8oR3JhcGhRTEJvb2xlYW4pLFxuICAgIG5vdEVxdWFsVG86IG5vdEVxdWFsVG8oR3JhcGhRTEJvb2xlYW4pLFxuICAgIGV4aXN0cyxcbiAgICBpblF1ZXJ5S2V5LFxuICAgIG5vdEluUXVlcnlLZXksXG4gIH0sXG59KTtcblxuY29uc3QgQVJSQVlfV0hFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdBcnJheVdoZXJlSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIEFycmF5V2hlcmVJbnB1dCBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIG9iamVjdHMgYnkgYSBmaWVsZCBvZiB0eXBlIEFycmF5LicsXG4gIGZpZWxkczoge1xuICAgIGVxdWFsVG86IGVxdWFsVG8oQU5ZKSxcbiAgICBub3RFcXVhbFRvOiBub3RFcXVhbFRvKEFOWSksXG4gICAgbGVzc1RoYW46IGxlc3NUaGFuKEFOWSksXG4gICAgbGVzc1RoYW5PckVxdWFsVG86IGxlc3NUaGFuT3JFcXVhbFRvKEFOWSksXG4gICAgZ3JlYXRlclRoYW46IGdyZWF0ZXJUaGFuKEFOWSksXG4gICAgZ3JlYXRlclRoYW5PckVxdWFsVG86IGdyZWF0ZXJUaGFuT3JFcXVhbFRvKEFOWSksXG4gICAgaW46IGluT3AoQU5ZKSxcbiAgICBub3RJbjogbm90SW4oQU5ZKSxcbiAgICBleGlzdHMsXG4gICAgY29udGFpbmVkQnk6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhpcyBpcyB0aGUgY29udGFpbmVkQnkgb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIHRoZSB2YWx1ZXMgb2YgYW4gYXJyYXkgZmllbGQgaXMgY29udGFpbmVkIGJ5IGFub3RoZXIgc3BlY2lmaWVkIGFycmF5LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QoQU5ZKSxcbiAgICB9LFxuICAgIGNvbnRhaW5zOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIGNvbnRhaW5zIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWVzIG9mIGFuIGFycmF5IGZpZWxkIGNvbnRhaW4gYWxsIGVsZW1lbnRzIG9mIGFub3RoZXIgc3BlY2lmaWVkIGFycmF5LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QoQU5ZKSxcbiAgICB9LFxuICAgIGluUXVlcnlLZXksXG4gICAgbm90SW5RdWVyeUtleSxcbiAgfSxcbn0pO1xuXG5jb25zdCBLRVlfVkFMVUVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdLZXlWYWx1ZUlucHV0JyxcbiAgZGVzY3JpcHRpb246ICdBbiBlbnRyeSBmcm9tIGFuIG9iamVjdCwgaS5lLiwgYSBwYWlyIG9mIGtleSBhbmQgdmFsdWUuJyxcbiAgZmllbGRzOiB7XG4gICAga2V5OiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSBrZXkgdXNlZCB0byByZXRyaWV2ZSB0aGUgdmFsdWUgb2YgdGhpcyBlbnRyeS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxTdHJpbmcpLFxuICAgIH0sXG4gICAgdmFsdWU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIHZhbHVlIG9mIHRoZSBlbnRyeS4gQ291bGQgYmUgYW55IHR5cGUgb2Ygc2NhbGFyIGRhdGEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChBTlkpLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgT0JKRUNUX1dIRVJFX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnT2JqZWN0V2hlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgT2JqZWN0V2hlcmVJbnB1dCBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIHJlc3VsdCBieSBhIGZpZWxkIG9mIHR5cGUgT2JqZWN0LicsXG4gIGZpZWxkczoge1xuICAgIGVxdWFsVG86IGVxdWFsVG8oS0VZX1ZBTFVFX0lOUFVUKSxcbiAgICBub3RFcXVhbFRvOiBub3RFcXVhbFRvKEtFWV9WQUxVRV9JTlBVVCksXG4gICAgaW46IGluT3AoS0VZX1ZBTFVFX0lOUFVUKSxcbiAgICBub3RJbjogbm90SW4oS0VZX1ZBTFVFX0lOUFVUKSxcbiAgICBsZXNzVGhhbjogbGVzc1RoYW4oS0VZX1ZBTFVFX0lOUFVUKSxcbiAgICBsZXNzVGhhbk9yRXF1YWxUbzogbGVzc1RoYW5PckVxdWFsVG8oS0VZX1ZBTFVFX0lOUFVUKSxcbiAgICBncmVhdGVyVGhhbjogZ3JlYXRlclRoYW4oS0VZX1ZBTFVFX0lOUFVUKSxcbiAgICBncmVhdGVyVGhhbk9yRXF1YWxUbzogZ3JlYXRlclRoYW5PckVxdWFsVG8oS0VZX1ZBTFVFX0lOUFVUKSxcbiAgICBleGlzdHMsXG4gICAgaW5RdWVyeUtleSxcbiAgICBub3RJblF1ZXJ5S2V5LFxuICB9LFxufSk7XG5cbmNvbnN0IERBVEVfV0hFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdEYXRlV2hlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgRGF0ZVdoZXJlSW5wdXQgaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGZpbHRlcmluZyBvYmplY3RzIGJ5IGEgZmllbGQgb2YgdHlwZSBEYXRlLicsXG4gIGZpZWxkczoge1xuICAgIGVxdWFsVG86IGVxdWFsVG8oREFURSksXG4gICAgbm90RXF1YWxUbzogbm90RXF1YWxUbyhEQVRFKSxcbiAgICBsZXNzVGhhbjogbGVzc1RoYW4oREFURSksXG4gICAgbGVzc1RoYW5PckVxdWFsVG86IGxlc3NUaGFuT3JFcXVhbFRvKERBVEUpLFxuICAgIGdyZWF0ZXJUaGFuOiBncmVhdGVyVGhhbihEQVRFKSxcbiAgICBncmVhdGVyVGhhbk9yRXF1YWxUbzogZ3JlYXRlclRoYW5PckVxdWFsVG8oREFURSksXG4gICAgaW46IGluT3AoREFURSksXG4gICAgbm90SW46IG5vdEluKERBVEUpLFxuICAgIGV4aXN0cyxcbiAgICBpblF1ZXJ5S2V5LFxuICAgIG5vdEluUXVlcnlLZXksXG4gIH0sXG59KTtcblxuY29uc3QgQllURVNfV0hFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdCeXRlc1doZXJlSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIEJ5dGVzV2hlcmVJbnB1dCBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIG9iamVjdHMgYnkgYSBmaWVsZCBvZiB0eXBlIEJ5dGVzLicsXG4gIGZpZWxkczoge1xuICAgIGVxdWFsVG86IGVxdWFsVG8oQllURVMpLFxuICAgIG5vdEVxdWFsVG86IG5vdEVxdWFsVG8oQllURVMpLFxuICAgIGxlc3NUaGFuOiBsZXNzVGhhbihCWVRFUyksXG4gICAgbGVzc1RoYW5PckVxdWFsVG86IGxlc3NUaGFuT3JFcXVhbFRvKEJZVEVTKSxcbiAgICBncmVhdGVyVGhhbjogZ3JlYXRlclRoYW4oQllURVMpLFxuICAgIGdyZWF0ZXJUaGFuT3JFcXVhbFRvOiBncmVhdGVyVGhhbk9yRXF1YWxUbyhCWVRFUyksXG4gICAgaW46IGluT3AoQllURVMpLFxuICAgIG5vdEluOiBub3RJbihCWVRFUyksXG4gICAgZXhpc3RzLFxuICAgIGluUXVlcnlLZXksXG4gICAgbm90SW5RdWVyeUtleSxcbiAgfSxcbn0pO1xuXG5jb25zdCBGSUxFX1dIRVJFX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnRmlsZVdoZXJlSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIEZpbGVXaGVyZUlucHV0IGlucHV0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBmaWx0ZXJpbmcgb2JqZWN0cyBieSBhIGZpZWxkIG9mIHR5cGUgRmlsZS4nLFxuICBmaWVsZHM6IHtcbiAgICBlcXVhbFRvOiBlcXVhbFRvKEZJTEUpLFxuICAgIG5vdEVxdWFsVG86IG5vdEVxdWFsVG8oRklMRSksXG4gICAgbGVzc1RoYW46IGxlc3NUaGFuKEZJTEUpLFxuICAgIGxlc3NUaGFuT3JFcXVhbFRvOiBsZXNzVGhhbk9yRXF1YWxUbyhGSUxFKSxcbiAgICBncmVhdGVyVGhhbjogZ3JlYXRlclRoYW4oRklMRSksXG4gICAgZ3JlYXRlclRoYW5PckVxdWFsVG86IGdyZWF0ZXJUaGFuT3JFcXVhbFRvKEZJTEUpLFxuICAgIGluOiBpbk9wKEZJTEUpLFxuICAgIG5vdEluOiBub3RJbihGSUxFKSxcbiAgICBleGlzdHMsXG4gICAgbWF0Y2hlc1JlZ2V4LFxuICAgIG9wdGlvbnMsXG4gICAgaW5RdWVyeUtleSxcbiAgICBub3RJblF1ZXJ5S2V5LFxuICB9LFxufSk7XG5cbmNvbnN0IEdFT19QT0lOVF9XSEVSRV9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0dlb1BvaW50V2hlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgR2VvUG9pbnRXaGVyZUlucHV0IGlucHV0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBmaWx0ZXJpbmcgb2JqZWN0cyBieSBhIGZpZWxkIG9mIHR5cGUgR2VvUG9pbnQuJyxcbiAgZmllbGRzOiB7XG4gICAgZXhpc3RzLFxuICAgIG5lYXJTcGhlcmU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhpcyBpcyB0aGUgbmVhclNwaGVyZSBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlcyBvZiBhIGdlbyBwb2ludCBmaWVsZCBpcyBuZWFyIHRvIGFub3RoZXIgZ2VvIHBvaW50LicsXG4gICAgICB0eXBlOiBHRU9fUE9JTlRfSU5QVVQsXG4gICAgfSxcbiAgICBtYXhEaXN0YW5jZToge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSBtYXhEaXN0YW5jZSBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlcyBvZiBhIGdlbyBwb2ludCBmaWVsZCBpcyBhdCBhIG1heCBkaXN0YW5jZSAoaW4gcmFkaWFucykgZnJvbSB0aGUgZ2VvIHBvaW50IHNwZWNpZmllZCBpbiB0aGUgJG5lYXJTcGhlcmUgb3BlcmF0b3IuJyxcbiAgICAgIHR5cGU6IEdyYXBoUUxGbG9hdCxcbiAgICB9LFxuICAgIG1heERpc3RhbmNlSW5SYWRpYW5zOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIG1heERpc3RhbmNlSW5SYWRpYW5zIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWVzIG9mIGEgZ2VvIHBvaW50IGZpZWxkIGlzIGF0IGEgbWF4IGRpc3RhbmNlIChpbiByYWRpYW5zKSBmcm9tIHRoZSBnZW8gcG9pbnQgc3BlY2lmaWVkIGluIHRoZSAkbmVhclNwaGVyZSBvcGVyYXRvci4nLFxuICAgICAgdHlwZTogR3JhcGhRTEZsb2F0LFxuICAgIH0sXG4gICAgbWF4RGlzdGFuY2VJbk1pbGVzOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIG1heERpc3RhbmNlSW5NaWxlcyBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlcyBvZiBhIGdlbyBwb2ludCBmaWVsZCBpcyBhdCBhIG1heCBkaXN0YW5jZSAoaW4gbWlsZXMpIGZyb20gdGhlIGdlbyBwb2ludCBzcGVjaWZpZWQgaW4gdGhlICRuZWFyU3BoZXJlIG9wZXJhdG9yLicsXG4gICAgICB0eXBlOiBHcmFwaFFMRmxvYXQsXG4gICAgfSxcbiAgICBtYXhEaXN0YW5jZUluS2lsb21ldGVyczoge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSBtYXhEaXN0YW5jZUluS2lsb21ldGVycyBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlcyBvZiBhIGdlbyBwb2ludCBmaWVsZCBpcyBhdCBhIG1heCBkaXN0YW5jZSAoaW4ga2lsb21ldGVycykgZnJvbSB0aGUgZ2VvIHBvaW50IHNwZWNpZmllZCBpbiB0aGUgJG5lYXJTcGhlcmUgb3BlcmF0b3IuJyxcbiAgICAgIHR5cGU6IEdyYXBoUUxGbG9hdCxcbiAgICB9LFxuICAgIHdpdGhpbjoge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSB3aXRoaW4gb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIHRoZSB2YWx1ZXMgb2YgYSBnZW8gcG9pbnQgZmllbGQgaXMgd2l0aGluIGEgc3BlY2lmaWVkIGJveC4nLFxuICAgICAgdHlwZTogV0lUSElOX0lOUFVULFxuICAgIH0sXG4gICAgZ2VvV2l0aGluOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIGdlb1dpdGhpbiBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlcyBvZiBhIGdlbyBwb2ludCBmaWVsZCBpcyB3aXRoaW4gYSBzcGVjaWZpZWQgcG9seWdvbiBvciBzcGhlcmUuJyxcbiAgICAgIHR5cGU6IEdFT19XSVRISU5fSU5QVVQsXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBQT0xZR09OX1dIRVJFX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnUG9seWdvbldoZXJlSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFBvbHlnb25XaGVyZUlucHV0IGlucHV0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBmaWx0ZXJpbmcgb2JqZWN0cyBieSBhIGZpZWxkIG9mIHR5cGUgUG9seWdvbi4nLFxuICBmaWVsZHM6IHtcbiAgICBleGlzdHMsXG4gICAgZ2VvSW50ZXJzZWN0czoge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSBnZW9JbnRlcnNlY3RzIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWVzIG9mIGEgcG9seWdvbiBmaWVsZCBpbnRlcnNlY3QgYSBzcGVjaWZpZWQgcG9pbnQuJyxcbiAgICAgIHR5cGU6IEdFT19JTlRFUlNFQ1RTX0lOUFVULFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgRUxFTUVOVCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdFbGVtZW50JyxcbiAgZGVzY3JpcHRpb246IFwiVGhlIEVsZW1lbnQgb2JqZWN0IHR5cGUgaXMgdXNlZCB0byByZXR1cm4gYXJyYXkgaXRlbXMnIHZhbHVlLlwiLFxuICBmaWVsZHM6IHtcbiAgICB2YWx1ZToge1xuICAgICAgZGVzY3JpcHRpb246ICdSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBlbGVtZW50IGluIHRoZSBhcnJheScsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoQU5ZKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbi8vIERlZmF1bHQgc3RhdGljIHVuaW9uIHR5cGUsIHdlIHVwZGF0ZSB0eXBlcyBhbmQgcmVzb2x2ZVR5cGUgZnVuY3Rpb24gbGF0ZXJcbmxldCBBUlJBWV9SRVNVTFQ7XG5cbmNvbnN0IGxvYWRBcnJheVJlc3VsdCA9IChwYXJzZUdyYXBoUUxTY2hlbWEsIHBhcnNlQ2xhc3NlcykgPT4ge1xuICBjb25zdCBjbGFzc1R5cGVzID0gcGFyc2VDbGFzc2VzXG4gICAgLmZpbHRlcihwYXJzZUNsYXNzID0+XG4gICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzW3BhcnNlQ2xhc3MuY2xhc3NOYW1lXS5jbGFzc0dyYXBoUUxPdXRwdXRUeXBlID8gdHJ1ZSA6IGZhbHNlXG4gICAgKVxuICAgIC5tYXAoXG4gICAgICBwYXJzZUNsYXNzID0+IHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzVHlwZXNbcGFyc2VDbGFzcy5jbGFzc05hbWVdLmNsYXNzR3JhcGhRTE91dHB1dFR5cGVcbiAgICApO1xuICBBUlJBWV9SRVNVTFQgPSBuZXcgR3JhcGhRTFVuaW9uVHlwZSh7XG4gICAgbmFtZTogJ0FycmF5UmVzdWx0JyxcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgICdVc2UgSW5saW5lIEZyYWdtZW50IG9uIEFycmF5IHRvIGdldCByZXN1bHRzOiBodHRwczovL2dyYXBocWwub3JnL2xlYXJuL3F1ZXJpZXMvI2lubGluZS1mcmFnbWVudHMnLFxuICAgIHR5cGVzOiAoKSA9PiBbRUxFTUVOVCwgLi4uY2xhc3NUeXBlc10sXG4gICAgcmVzb2x2ZVR5cGU6IHZhbHVlID0+IHtcbiAgICAgIGlmICh2YWx1ZS5fX3R5cGUgPT09ICdPYmplY3QnICYmIHZhbHVlLmNsYXNzTmFtZSAmJiB2YWx1ZS5vYmplY3RJZCkge1xuICAgICAgICBpZiAocGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1t2YWx1ZS5jbGFzc05hbWVdKSB7XG4gICAgICAgICAgcmV0dXJuIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzVHlwZXNbdmFsdWUuY2xhc3NOYW1lXS5jbGFzc0dyYXBoUUxPdXRwdXRUeXBlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBFTEVNRU5UO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gRUxFTUVOVDtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmdyYXBoUUxUeXBlcy5wdXNoKEFSUkFZX1JFU1VMVCk7XG59O1xuXG5jb25zdCBsb2FkID0gcGFyc2VHcmFwaFFMU2NoZW1hID0+IHtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEdyYXBoUUxVcGxvYWQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoQU5ZLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKE9CSkVDVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShEQVRFLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEJZVEVTLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEZJTEUsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoRklMRV9JTkZPLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEZJTEVfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoR0VPX1BPSU5UX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEdFT19QT0lOVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShQQVJTRV9PQkpFQ1QsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoUkVBRF9QUkVGRVJFTkNFLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFJFQURfT1BUSU9OU19JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTRUFSQ0hfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoVEVYVF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShCT1hfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoV0lUSElOX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKENFTlRFUl9TUEhFUkVfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoR0VPX1dJVEhJTl9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShHRU9fSU5URVJTRUNUU19JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShJRF9XSEVSRV9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTVFJJTkdfV0hFUkVfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoTlVNQkVSX1dIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEJPT0xFQU5fV0hFUkVfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoQVJSQVlfV0hFUkVfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoS0VZX1ZBTFVFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKE9CSkVDVF9XSEVSRV9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShEQVRFX1dIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEJZVEVTX1dIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEZJTEVfV0hFUkVfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoR0VPX1BPSU5UX1dIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFBPTFlHT05fV0hFUkVfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoRUxFTUVOVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShBQ0xfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoVVNFUl9BQ0xfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoUk9MRV9BQ0xfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoUFVCTElDX0FDTF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShBQ0wsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoVVNFUl9BQ0wsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoUk9MRV9BQ0wsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoUFVCTElDX0FDTCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTVUJRVUVSWV9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTRUxFQ1RfSU5QVVQsIHRydWUpO1xufTtcblxuZXhwb3J0IHtcbiAgVHlwZVZhbGlkYXRpb25FcnJvcixcbiAgcGFyc2VTdHJpbmdWYWx1ZSxcbiAgcGFyc2VJbnRWYWx1ZSxcbiAgcGFyc2VGbG9hdFZhbHVlLFxuICBwYXJzZUJvb2xlYW5WYWx1ZSxcbiAgcGFyc2VWYWx1ZSxcbiAgcGFyc2VMaXN0VmFsdWVzLFxuICBwYXJzZU9iamVjdEZpZWxkcyxcbiAgQU5ZLFxuICBPQkpFQ1QsXG4gIHBhcnNlRGF0ZUlzb1ZhbHVlLFxuICBzZXJpYWxpemVEYXRlSXNvLFxuICBEQVRFLFxuICBCWVRFUyxcbiAgcGFyc2VGaWxlVmFsdWUsXG4gIFNVQlFVRVJZX0lOUFVULFxuICBTRUxFQ1RfSU5QVVQsXG4gIEZJTEUsXG4gIEZJTEVfSU5GTyxcbiAgRklMRV9JTlBVVCxcbiAgR0VPX1BPSU5UX0ZJRUxEUyxcbiAgR0VPX1BPSU5UX0lOUFVULFxuICBHRU9fUE9JTlQsXG4gIFBPTFlHT05fSU5QVVQsXG4gIFBPTFlHT04sXG4gIE9CSkVDVF9JRCxcbiAgQ0xBU1NfTkFNRV9BVFQsXG4gIEdMT0JBTF9PUl9PQkpFQ1RfSURfQVRULFxuICBPQkpFQ1RfSURfQVRULFxuICBVUERBVEVEX0FUX0FUVCxcbiAgQ1JFQVRFRF9BVF9BVFQsXG4gIElOUFVUX0ZJRUxEUyxcbiAgQ1JFQVRFX1JFU1VMVF9GSUVMRFMsXG4gIFVQREFURV9SRVNVTFRfRklFTERTLFxuICBQQVJTRV9PQkpFQ1RfRklFTERTLFxuICBQQVJTRV9PQkpFQ1QsXG4gIFNFU1NJT05fVE9LRU5fQVRULFxuICBSRUFEX1BSRUZFUkVOQ0UsXG4gIFJFQURfUFJFRkVSRU5DRV9BVFQsXG4gIElOQ0xVREVfUkVBRF9QUkVGRVJFTkNFX0FUVCxcbiAgU1VCUVVFUllfUkVBRF9QUkVGRVJFTkNFX0FUVCxcbiAgUkVBRF9PUFRJT05TX0lOUFVULFxuICBSRUFEX09QVElPTlNfQVRULFxuICBXSEVSRV9BVFQsXG4gIFNLSVBfQVRULFxuICBMSU1JVF9BVFQsXG4gIENPVU5UX0FUVCxcbiAgU0VBUkNIX0lOUFVULFxuICBURVhUX0lOUFVULFxuICBCT1hfSU5QVVQsXG4gIFdJVEhJTl9JTlBVVCxcbiAgQ0VOVEVSX1NQSEVSRV9JTlBVVCxcbiAgR0VPX1dJVEhJTl9JTlBVVCxcbiAgR0VPX0lOVEVSU0VDVFNfSU5QVVQsXG4gIGVxdWFsVG8sXG4gIG5vdEVxdWFsVG8sXG4gIGxlc3NUaGFuLFxuICBsZXNzVGhhbk9yRXF1YWxUbyxcbiAgZ3JlYXRlclRoYW4sXG4gIGdyZWF0ZXJUaGFuT3JFcXVhbFRvLFxuICBpbk9wLFxuICBub3RJbixcbiAgZXhpc3RzLFxuICBtYXRjaGVzUmVnZXgsXG4gIG9wdGlvbnMsXG4gIGluUXVlcnlLZXksXG4gIG5vdEluUXVlcnlLZXksXG4gIElEX1dIRVJFX0lOUFVULFxuICBTVFJJTkdfV0hFUkVfSU5QVVQsXG4gIE5VTUJFUl9XSEVSRV9JTlBVVCxcbiAgQk9PTEVBTl9XSEVSRV9JTlBVVCxcbiAgQVJSQVlfV0hFUkVfSU5QVVQsXG4gIEtFWV9WQUxVRV9JTlBVVCxcbiAgT0JKRUNUX1dIRVJFX0lOUFVULFxuICBEQVRFX1dIRVJFX0lOUFVULFxuICBCWVRFU19XSEVSRV9JTlBVVCxcbiAgRklMRV9XSEVSRV9JTlBVVCxcbiAgR0VPX1BPSU5UX1dIRVJFX0lOUFVULFxuICBQT0xZR09OX1dIRVJFX0lOUFVULFxuICBBUlJBWV9SRVNVTFQsXG4gIEVMRU1FTlQsXG4gIEFDTF9JTlBVVCxcbiAgVVNFUl9BQ0xfSU5QVVQsXG4gIFJPTEVfQUNMX0lOUFVULFxuICBQVUJMSUNfQUNMX0lOUFVULFxuICBBQ0wsXG4gIFVTRVJfQUNMLFxuICBST0xFX0FDTCxcbiAgUFVCTElDX0FDTCxcbiAgbG9hZCxcbiAgbG9hZEFycmF5UmVzdWx0LFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/defaultRelaySchema.js b/lib/GraphQL/loaders/defaultRelaySchema.js new file mode 100644 index 0000000000..9cbe35176b --- /dev/null +++ b/lib/GraphQL/loaders/defaultRelaySchema.js @@ -0,0 +1,71 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = exports.GLOBAL_ID_ATT = void 0; + +var _graphqlRelay = require("graphql-relay"); + +var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); + +var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); + +var objectsQueries = _interopRequireWildcard(require("../helpers/objectsQueries")); + +var _parseClassTypes = require("./parseClassTypes"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const GLOBAL_ID_ATT = { + description: 'This is the global id.', + type: defaultGraphQLTypes.OBJECT_ID +}; +exports.GLOBAL_ID_ATT = GLOBAL_ID_ATT; + +const load = parseGraphQLSchema => { + const { + nodeInterface, + nodeField + } = (0, _graphqlRelay.nodeDefinitions)(async (globalId, context, queryInfo) => { + try { + const { + type, + id + } = (0, _graphqlRelay.fromGlobalId)(globalId); + const { + config, + auth, + info + } = context; + const selectedFields = (0, _graphqlListFields.default)(queryInfo); + const { + keys, + include + } = (0, _parseClassTypes.extractKeysAndInclude)(selectedFields); + return _objectSpread({ + className: type + }, await objectsQueries.getObject(type, id, keys, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses)); + } catch (e) { + parseGraphQLSchema.handleError(e); + } + }, obj => { + return parseGraphQLSchema.parseClassTypes[obj.className].classGraphQLOutputType; + }); + parseGraphQLSchema.addGraphQLType(nodeInterface, true); + parseGraphQLSchema.relayNodeInterface = nodeInterface; + parseGraphQLSchema.addGraphQLQuery('node', nodeField, true); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZGVmYXVsdFJlbGF5U2NoZW1hLmpzIl0sIm5hbWVzIjpbIkdMT0JBTF9JRF9BVFQiLCJkZXNjcmlwdGlvbiIsInR5cGUiLCJkZWZhdWx0R3JhcGhRTFR5cGVzIiwiT0JKRUNUX0lEIiwibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsIm5vZGVJbnRlcmZhY2UiLCJub2RlRmllbGQiLCJnbG9iYWxJZCIsImNvbnRleHQiLCJxdWVyeUluZm8iLCJpZCIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwic2VsZWN0ZWRGaWVsZHMiLCJrZXlzIiwiaW5jbHVkZSIsImNsYXNzTmFtZSIsIm9iamVjdHNRdWVyaWVzIiwiZ2V0T2JqZWN0IiwidW5kZWZpbmVkIiwicGFyc2VDbGFzc2VzIiwiZSIsImhhbmRsZUVycm9yIiwib2JqIiwicGFyc2VDbGFzc1R5cGVzIiwiY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSIsImFkZEdyYXBoUUxUeXBlIiwicmVsYXlOb2RlSW50ZXJmYWNlIiwiYWRkR3JhcGhRTFF1ZXJ5Il0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FBRUEsTUFBTUEsYUFBYSxHQUFHO0FBQ3BCQyxFQUFBQSxXQUFXLEVBQUUsd0JBRE87QUFFcEJDLEVBQUFBLElBQUksRUFBRUMsbUJBQW1CLENBQUNDO0FBRk4sQ0FBdEI7OztBQUtBLE1BQU1DLElBQUksR0FBR0Msa0JBQWtCLElBQUk7QUFDakMsUUFBTTtBQUFFQyxJQUFBQSxhQUFGO0FBQWlCQyxJQUFBQTtBQUFqQixNQUErQixtQ0FDbkMsT0FBT0MsUUFBUCxFQUFpQkMsT0FBakIsRUFBMEJDLFNBQTFCLEtBQXdDO0FBQ3RDLFFBQUk7QUFDRixZQUFNO0FBQUVULFFBQUFBLElBQUY7QUFBUVUsUUFBQUE7QUFBUixVQUFlLGdDQUFhSCxRQUFiLENBQXJCO0FBQ0EsWUFBTTtBQUFFSSxRQUFBQSxNQUFGO0FBQVVDLFFBQUFBLElBQVY7QUFBZ0JDLFFBQUFBO0FBQWhCLFVBQXlCTCxPQUEvQjtBQUNBLFlBQU1NLGNBQWMsR0FBRyxnQ0FBY0wsU0FBZCxDQUF2QjtBQUVBLFlBQU07QUFBRU0sUUFBQUEsSUFBRjtBQUFRQyxRQUFBQTtBQUFSLFVBQW9CLDRDQUFzQkYsY0FBdEIsQ0FBMUI7QUFFQTtBQUNFRyxRQUFBQSxTQUFTLEVBQUVqQjtBQURiLFNBRU0sTUFBTWtCLGNBQWMsQ0FBQ0MsU0FBZixDQUNSbkIsSUFEUSxFQUVSVSxFQUZRLEVBR1JLLElBSFEsRUFJUkMsT0FKUSxFQUtSSSxTQUxRLEVBTVJBLFNBTlEsRUFPUlQsTUFQUSxFQVFSQyxJQVJRLEVBU1JDLElBVFEsRUFVUlQsa0JBQWtCLENBQUNpQixZQVZYLENBRlo7QUFlRCxLQXRCRCxDQXNCRSxPQUFPQyxDQUFQLEVBQVU7QUFDVmxCLE1BQUFBLGtCQUFrQixDQUFDbUIsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRixHQTNCa0MsRUE0Qm5DRSxHQUFHLElBQUk7QUFDTCxXQUFPcEIsa0JBQWtCLENBQUNxQixlQUFuQixDQUFtQ0QsR0FBRyxDQUFDUCxTQUF2QyxFQUFrRFMsc0JBQXpEO0FBQ0QsR0E5QmtDLENBQXJDO0FBaUNBdEIsRUFBQUEsa0JBQWtCLENBQUN1QixjQUFuQixDQUFrQ3RCLGFBQWxDLEVBQWlELElBQWpEO0FBQ0FELEVBQUFBLGtCQUFrQixDQUFDd0Isa0JBQW5CLEdBQXdDdkIsYUFBeEM7QUFDQUQsRUFBQUEsa0JBQWtCLENBQUN5QixlQUFuQixDQUFtQyxNQUFuQyxFQUEyQ3ZCLFNBQTNDLEVBQXNELElBQXREO0FBQ0QsQ0FyQ0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBub2RlRGVmaW5pdGlvbnMsIGZyb21HbG9iYWxJZCB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0IGdldEZpZWxkTmFtZXMgZnJvbSAnZ3JhcGhxbC1saXN0LWZpZWxkcyc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4vZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQgKiBhcyBvYmplY3RzUXVlcmllcyBmcm9tICcuLi9oZWxwZXJzL29iamVjdHNRdWVyaWVzJztcbmltcG9ydCB7IGV4dHJhY3RLZXlzQW5kSW5jbHVkZSB9IGZyb20gJy4vcGFyc2VDbGFzc1R5cGVzJztcblxuY29uc3QgR0xPQkFMX0lEX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBnbG9iYWwgaWQuJyxcbiAgdHlwZTogZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1RfSUQsXG59O1xuXG5jb25zdCBsb2FkID0gcGFyc2VHcmFwaFFMU2NoZW1hID0+IHtcbiAgY29uc3QgeyBub2RlSW50ZXJmYWNlLCBub2RlRmllbGQgfSA9IG5vZGVEZWZpbml0aW9ucyhcbiAgICBhc3luYyAoZ2xvYmFsSWQsIGNvbnRleHQsIHF1ZXJ5SW5mbykgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyB0eXBlLCBpZCB9ID0gZnJvbUdsb2JhbElkKGdsb2JhbElkKTtcbiAgICAgICAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkRmllbGRzID0gZ2V0RmllbGROYW1lcyhxdWVyeUluZm8pO1xuXG4gICAgICAgIGNvbnN0IHsga2V5cywgaW5jbHVkZSB9ID0gZXh0cmFjdEtleXNBbmRJbmNsdWRlKHNlbGVjdGVkRmllbGRzKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNsYXNzTmFtZTogdHlwZSxcbiAgICAgICAgICAuLi4oYXdhaXQgb2JqZWN0c1F1ZXJpZXMuZ2V0T2JqZWN0KFxuICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAga2V5cyxcbiAgICAgICAgICAgIGluY2x1ZGUsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzZXNcbiAgICAgICAgICApKSxcbiAgICAgICAgfTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgfVxuICAgIH0sXG4gICAgb2JqID0+IHtcbiAgICAgIHJldHVybiBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzW29iai5jbGFzc05hbWVdLmNsYXNzR3JhcGhRTE91dHB1dFR5cGU7XG4gICAgfVxuICApO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShub2RlSW50ZXJmYWNlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLnJlbGF5Tm9kZUludGVyZmFjZSA9IG5vZGVJbnRlcmZhY2U7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMUXVlcnkoJ25vZGUnLCBub2RlRmllbGQsIHRydWUpO1xufTtcblxuZXhwb3J0IHsgR0xPQkFMX0lEX0FUVCwgbG9hZCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/filesMutations.js b/lib/GraphQL/loaders/filesMutations.js new file mode 100644 index 0000000000..ada46e07be --- /dev/null +++ b/lib/GraphQL/loaders/filesMutations.js @@ -0,0 +1,103 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.handleUpload = exports.load = void 0; + +var _graphql = require("graphql"); + +var _graphqlRelay = require("graphql-relay"); + +var _links = require("@graphql-tools/links"); + +var _node = _interopRequireDefault(require("parse/node")); + +var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); + +var _logger = _interopRequireDefault(require("../../logger")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const handleUpload = async (upload, config) => { + const { + createReadStream, + filename, + mimetype + } = await upload; + let data = null; + + if (createReadStream) { + const stream = createReadStream(); + data = await new Promise((resolve, reject) => { + const chunks = []; + stream.on('error', reject).on('data', chunk => chunks.push(chunk)).on('end', () => resolve(Buffer.concat(chunks))); + }); + } + + if (!data || !data.length) { + throw new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, 'Invalid file upload.'); + } + + if (filename.length > 128) { + throw new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename too long.'); + } + + if (!filename.match(/^[_a-zA-Z0-9][a-zA-Z0-9@\.\ ~_-]*$/)) { + throw new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename contains invalid characters.'); + } + + try { + return { + fileInfo: await config.filesController.createFile(config, filename, data, mimetype) + }; + } catch (e) { + _logger.default.error('Error creating a file: ', e); + + throw new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, `Could not store file: ${filename}.`); + } +}; + +exports.handleUpload = handleUpload; + +const load = parseGraphQLSchema => { + const createMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'CreateFile', + description: 'The createFile mutation can be used to create and upload a new file.', + inputFields: { + upload: { + description: 'This is the new file to be created and uploaded.', + type: new _graphql.GraphQLNonNull(_links.GraphQLUpload) + } + }, + outputFields: { + fileInfo: { + description: 'This is the created file info.', + type: new _graphql.GraphQLNonNull(defaultGraphQLTypes.FILE_INFO) + } + }, + mutateAndGetPayload: async (args, context) => { + try { + const { + upload + } = args; + const { + config + } = context; + return handleUpload(upload, config); + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(createMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(createMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('createFile', createMutation, true, true); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZmlsZXNNdXRhdGlvbnMuanMiXSwibmFtZXMiOlsiaGFuZGxlVXBsb2FkIiwidXBsb2FkIiwiY29uZmlnIiwiY3JlYXRlUmVhZFN0cmVhbSIsImZpbGVuYW1lIiwibWltZXR5cGUiLCJkYXRhIiwic3RyZWFtIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJjaHVua3MiLCJvbiIsImNodW5rIiwicHVzaCIsIkJ1ZmZlciIsImNvbmNhdCIsImxlbmd0aCIsIlBhcnNlIiwiRXJyb3IiLCJGSUxFX1NBVkVfRVJST1IiLCJJTlZBTElEX0ZJTEVfTkFNRSIsIm1hdGNoIiwiZmlsZUluZm8iLCJmaWxlc0NvbnRyb2xsZXIiLCJjcmVhdGVGaWxlIiwiZSIsImxvZ2dlciIsImVycm9yIiwibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsImNyZWF0ZU11dGF0aW9uIiwibmFtZSIsImRlc2NyaXB0aW9uIiwiaW5wdXRGaWVsZHMiLCJ0eXBlIiwiR3JhcGhRTE5vbk51bGwiLCJHcmFwaFFMVXBsb2FkIiwib3V0cHV0RmllbGRzIiwiZGVmYXVsdEdyYXBoUUxUeXBlcyIsIkZJTEVfSU5GTyIsIm11dGF0ZUFuZEdldFBheWxvYWQiLCJhcmdzIiwiY29udGV4dCIsImhhbmRsZUVycm9yIiwiYWRkR3JhcGhRTFR5cGUiLCJpbnB1dCIsIm9mVHlwZSIsImFkZEdyYXBoUUxNdXRhdGlvbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVBLE1BQU1BLFlBQVksR0FBRyxPQUFPQyxNQUFQLEVBQWVDLE1BQWYsS0FBMEI7QUFDN0MsUUFBTTtBQUFFQyxJQUFBQSxnQkFBRjtBQUFvQkMsSUFBQUEsUUFBcEI7QUFBOEJDLElBQUFBO0FBQTlCLE1BQTJDLE1BQU1KLE1BQXZEO0FBQ0EsTUFBSUssSUFBSSxHQUFHLElBQVg7O0FBQ0EsTUFBSUgsZ0JBQUos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QUEwQkFJLEVBQUFBLGtCQUFrQixDQUFDZSxjQUFuQixDQUFrQ2QsY0FBYyxDQUFDVyxJQUFmLENBQW9CSSxLQUFwQixDQUEwQlgsSUFBMUIsQ0FBK0JZLE1BQWpFLEVBQXlFLElBQXpFLEVBQStFLElBQS9FO0FBQ0FqQixFQUFBQSxrQkFBa0IsQ0FBQ2UsY0FBbkIsQ0FBa0NkLGNBQWMsQ0FBQ0ksSUFBakQsRUFBdUQsSUFBdkQsRUFBNkQsSUFBN0Q7QUFDQUwsRUFBQUEsa0JBQWtCLENBQUNrQixrQkFBbkIsQ0FBc0MsWUFBdEMsRUFBb0RqQixjQUFwRCxFQUFvRSxJQUFwRSxFQUEwRSxJQUExRTtBQUNELENBOUJEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgR3JhcGhRTE5vbk51bGwgfSBmcm9tICdncmFwaHFsJztcbmltcG9ydCB7IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQgfSBmcm9tICdncmFwaHFsLXJlbGF5JztcbmltcG9ydCB7IEdyYXBoUUxVcGxvYWQgfSBmcm9tICdAZ3JhcGhxbC10b29scy9saW5rcyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4vZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uLy4uL2xvZ2dlcic7XG5cbmNvbnN0IGhhbmRsZVVwbG9hZCA9IGFzeW5jICh1cGxvYWQsIGNvbmZpZykgPT4ge1xuICBjb25zdCB7IGNyZWF0ZVJlYWRTdHJlYW0sIGZpbGVuYW1lLCBtaW1ldHlwZSB9ID0gYXdhaXQgdXBsb2FkO1xuICBsZXQgZGF0YSA9IG51bGw7XG4gIGlmIChjcmVhdGVSZWFkU3RyZWFtKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY3JlYXRlUmVhZFN0cmVhbSgpO1xuICAgIGRhdGEgPSBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBjaHVua3MgPSBbXTtcbiAgICAgIHN0cmVhbVxuICAgICAgICAub24oJ2Vycm9yJywgcmVqZWN0KVxuICAgICAgICAub24oJ2RhdGEnLCBjaHVuayA9PiBjaHVua3MucHVzaChjaHVuaykpXG4gICAgICAgIC5vbignZW5kJywgKCkgPT4gcmVzb2x2ZShCdWZmZXIuY29uY2F0KGNodW5rcykpKTtcbiAgICB9KTtcbiAgfVxuXG4gIGlmICghZGF0YSB8fCAhZGF0YS5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRklMRV9TQVZFX0VSUk9SLCAnSW52YWxpZCBmaWxlIHVwbG9hZC4nKTtcbiAgfVxuXG4gIGlmIChmaWxlbmFtZS5sZW5ndGggPiAxMjgpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9GSUxFX05BTUUsICdGaWxlbmFtZSB0b28gbG9uZy4nKTtcbiAgfVxuXG4gIGlmICghZmlsZW5hbWUubWF0Y2goL15bX2EtekEtWjAtOV1bYS16QS1aMC05QFxcLlxcIH5fLV0qJC8pKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfRklMRV9OQU1FLCAnRmlsZW5hbWUgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXJzLicpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4ge1xuICAgICAgZmlsZUluZm86IGF3YWl0IGNvbmZpZy5maWxlc0NvbnRyb2xsZXIuY3JlYXRlRmlsZShjb25maWcsIGZpbGVuYW1lLCBkYXRhLCBtaW1ldHlwZSksXG4gICAgfTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGxvZ2dlci5lcnJvcignRXJyb3IgY3JlYXRpbmcgYSBmaWxlOiAnLCBlKTtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRklMRV9TQVZFX0VSUk9SLCBgQ291bGQgbm90IHN0b3JlIGZpbGU6ICR7ZmlsZW5hbWV9LmApO1xuICB9XG59O1xuXG5jb25zdCBsb2FkID0gcGFyc2VHcmFwaFFMU2NoZW1hID0+IHtcbiAgY29uc3QgY3JlYXRlTXV0YXRpb24gPSBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkKHtcbiAgICBuYW1lOiAnQ3JlYXRlRmlsZScsXG4gICAgZGVzY3JpcHRpb246ICdUaGUgY3JlYXRlRmlsZSBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBjcmVhdGUgYW5kIHVwbG9hZCBhIG5ldyBmaWxlLicsXG4gICAgaW5wdXRGaWVsZHM6IHtcbiAgICAgIHVwbG9hZDoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIG5ldyBmaWxlIHRvIGJlIGNyZWF0ZWQgYW5kIHVwbG9hZGVkLicsXG4gICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMVXBsb2FkKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgIGZpbGVJbmZvOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgY3JlYXRlZCBmaWxlIGluZm8uJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKGRlZmF1bHRHcmFwaFFMVHlwZXMuRklMRV9JTkZPKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBtdXRhdGVBbmRHZXRQYXlsb2FkOiBhc3luYyAoYXJncywgY29udGV4dCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyB1cGxvYWQgfSA9IGFyZ3M7XG4gICAgICAgIGNvbnN0IHsgY29uZmlnIH0gPSBjb250ZXh0O1xuICAgICAgICByZXR1cm4gaGFuZGxlVXBsb2FkKHVwbG9hZCwgY29uZmlnKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjcmVhdGVNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNyZWF0ZU11dGF0aW9uLnR5cGUsIHRydWUsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTE11dGF0aW9uKCdjcmVhdGVGaWxlJywgY3JlYXRlTXV0YXRpb24sIHRydWUsIHRydWUpO1xufTtcblxuZXhwb3J0IHsgbG9hZCwgaGFuZGxlVXBsb2FkIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/loaders/functionsMutations.js b/lib/GraphQL/loaders/functionsMutations.js new file mode 100644 index 0000000000..e8246ee21a --- /dev/null +++ b/lib/GraphQL/loaders/functionsMutations.js @@ -0,0 +1,90 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = void 0; + +var _graphql = require("graphql"); + +var _graphqlRelay = require("graphql-relay"); + +var _FunctionsRouter = require("../../Routers/FunctionsRouter"); + +var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const load = parseGraphQLSchema => { + if (parseGraphQLSchema.functionNames.length > 0) { + const cloudCodeFunctionEnum = parseGraphQLSchema.addGraphQLType(new _graphql.GraphQLEnumType({ + name: 'CloudCodeFunction', + description: 'The CloudCodeFunction enum type contains a list of all available cloud code functions.', + values: parseGraphQLSchema.functionNames.reduce((values, functionName) => _objectSpread(_objectSpread({}, values), {}, { + [functionName]: { + value: functionName + } + }), {}) + }), true, true); + const callCloudCodeMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'CallCloudCode', + description: 'The callCloudCode mutation can be used to invoke a cloud code function.', + inputFields: { + functionName: { + description: 'This is the function to be called.', + type: new _graphql.GraphQLNonNull(cloudCodeFunctionEnum) + }, + params: { + description: 'These are the params to be passed to the function.', + type: defaultGraphQLTypes.OBJECT + } + }, + outputFields: { + result: { + description: 'This is the result value of the cloud code function execution.', + type: defaultGraphQLTypes.ANY + } + }, + mutateAndGetPayload: async (args, context) => { + try { + const { + functionName, + params + } = args; + const { + config, + auth, + info + } = context; + return { + result: (await _FunctionsRouter.FunctionsRouter.handleCloudFunction({ + params: { + functionName + }, + config, + auth, + info, + body: params + })).response.result + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(callCloudCodeMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(callCloudCodeMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('callCloudCode', callCloudCodeMutation, true, true); + } +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZnVuY3Rpb25zTXV0YXRpb25zLmpzIl0sIm5hbWVzIjpbImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJmdW5jdGlvbk5hbWVzIiwibGVuZ3RoIiwiY2xvdWRDb2RlRnVuY3Rpb25FbnVtIiwiYWRkR3JhcGhRTFR5cGUiLCJHcmFwaFFMRW51bVR5cGUiLCJuYW1lIiwiZGVzY3JpcHRpb24iLCJ2YWx1ZXMiLCJyZWR1Y2UiLCJmdW5jdGlvbk5hbWUiLCJ2YWx1ZSIsImNhbGxDbG91ZENvZGVNdXRhdGlvbiIsImlucHV0RmllbGRzIiwidHlwZSIsIkdyYXBoUUxOb25OdWxsIiwicGFyYW1zIiwiZGVmYXVsdEdyYXBoUUxUeXBlcyIsIk9CSkVDVCIsIm91dHB1dEZpZWxkcyIsInJlc3VsdCIsIkFOWSIsIm11dGF0ZUFuZEdldFBheWxvYWQiLCJhcmdzIiwiY29udGV4dCIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwiRnVuY3Rpb25zUm91dGVyIiwiaGFuZGxlQ2xvdWRGdW5jdGlvbiIsImJvZHkiLCJyZXNwb25zZSIsImUiLCJoYW5kbGVFcnJvciIsImlucHV0Iiwib2ZUeXBlIiwiYWRkR3JhcGhRTE11dGF0aW9uIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7OztBQUVBLE1BQU1BLElBQUksR0FBR0Msa0JBQWtCLElBQUk7QUFDakMsTUFBSUEsa0JBQWtCLENBQUNDLGFBQW5CLENBQWlDQyxNQUFqQyxHQUEwQyxDQUE5QyxFQUFpRDtBQUMvQyxVQUFNQyxxQkFBcUIsR0FBR0gsa0JBQWtCLENBQUNJLGNBQW5CLENBQzVCLElBQUlDLHdCQUFKLENBQW9CO0FBQ2xCQyxNQUFBQSxJQUFJLEVBQUUsbUJBRFk7QUFFbEJDLE1BQUFBLFdBQVcsRUFDVCx3RkFIZ0I7QUFJbEJDLE1BQUFBLE1BQU0sRUFBRVIsa0JBQWtCLENBQUNDLGFBQW5CLENBQWlDUSxNQUFqQyxDQUNOLENBQUNELE1BQUQsRUFBU0UsWUFBVCxxQ0FDS0YsTUFETDtBQUVFLFNBQUNFLFlBQUQsR0FBZ0I7QUFBRUMsVUFBQUEsS0FBSyxFQUFFRDtBQUFUO0FBRmxCLFFBRE0sRUFLTixFQUxNO0FBSlUsS0FBcEIsQ0FENEIsRUFhNUIsSUFiNEIsRUFjNUIsSUFkNEIsQ0FBOUI7QUFpQkEsVUFBTUUscUJBQXFCLEdBQUcsZ0RBQTZCO0FBQ3pETixNQUFBQSxJQUFJLEVBQUUsZUFEbUQ7QUFFekRDLE1BQUFBLFdBQVcsRUFBRSx5RUFGNEM7QUFHekRNLE1BQUFBLFdBQVcsRUFBRTtBQUNYSCxRQUFBQSxZQUFZLEVBQUU7QUFDWkgsVUFBQUEsV0FBVyxFQUFFLG9DQUREO0FBRVpPLFVBQUFBLElBQUksRUFBRSxJQUFJQyx1QkFBSixDQUFtQloscUJBQW5CO0FBRk0sU0FESDtBQUtYYSxRQUFBQSxNQUFNLEVBQUU7QUFDTlQsVUFBQUEsV0FBVyxFQUFFLG9EQURQO0FBRU5PLFVBQUFBLElBQUksRUFBRUcsbUJBQW1CLENBQUNDO0FBRnBCO0FBTEcsT0FINEM7QUFhekRDLE1BQUFBLFlBQVksRUFBRTtBQUNaQyxRQUFBQSxNQUFNLEVBQUU7QUFDTmIsVUFBQUEsV0FBVyxFQUFFLGdFQURQO0FBRU5PLFVBQUFBLElBQUksRUFBRUcsbUJBQW1CLENBQUNJO0FBRnBCO0FBREksT0FiMkM7QUFtQnpEQyxNQUFBQSxtQkFBbUIsRUFBRSxPQUFPQyxJQUFQLEVBQWFDLE9BQWIsS0FBeUI7QUFDNUMsWUFBSTtBQUNGLGdCQUFNO0FBQUVkLFlBQUFBLFlBQUY7QUFBZ0JNLFlBQUFBO0FBQWhCLGNBQTJCTyxJQUFqQztBQUNBLGdCQUFNO0FBQUVFLFlBQUFBLE1BQUY7QUFBVUMsWUFBQUEsSUFBVjtBQUFnQkMsWUFBQUE7QUFBaEIsY0FBeUJILE9BQS9CO0FBRUEsaUJBQU87QUFDTEosWUFBQUEsTUFBTSxFQUFFLENBQ04sTUFBTVEsaUNBQWdCQyxtQkFBaEIsQ0FBb0M7QUFDeENiLGNBQUFBLE1BQU0sRUFBRTtBQUNOTixnQkFBQUE7QUFETSxlQURnQztBQUl4Q2UsY0FBQUEsTUFKd0M7QUFLeENDLGNBQUFBLElBTHdDO0FBTXhDQyxjQUFBQSxJQU53QztBQU94Q0csY0FBQUEsSUFBSSxFQUFFZDtBQVBrQyxhQUFwQyxDQURBLEVBVU5lLFFBVk0sQ0FVR1g7QUFYTixXQUFQO0FBYUQsU0FqQkQsQ0FpQkUsT0FBT1ksQ0FBUCxFQUFVO0FBQ1ZoQyxVQUFBQSxrQkFBa0IsQ0FBQ2lDLFdBQW5CLENBQStCRCxDQUEvQjtBQUNEO0FBQ0Y7QUF4Q3dELEtBQTdCLENBQTlCO0FBMkNBaEMsSUFBQUEsa0JBQWtCLENBQUNJLGNBQW5CLENBQWtDUSxxQkFBcUIsQ0FBQ1csSUFBdEIsQ0FBMkJXLEtBQTNCLENBQWlDcEIsSUFBakMsQ0FBc0NxQixNQUF4RSxFQUFnRixJQUFoRixFQUFzRixJQUF0RjtBQUNBbkMsSUFBQUEsa0JBQWtCLENBQUNJLGNBQW5CLENBQWtDUSxxQkFBcUIsQ0FBQ0UsSUFBeEQsRUFBOEQsSUFBOUQsRUFBb0UsSUFBcEU7QUFDQWQsSUFBQUEsa0JBQWtCLENBQUNvQyxrQkFBbkIsQ0FBc0MsZUFBdEMsRUFBdUR4QixxQkFBdkQsRUFBOEUsSUFBOUUsRUFBb0YsSUFBcEY7QUFDRDtBQUNGLENBbEVEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgR3JhcGhRTE5vbk51bGwsIEdyYXBoUUxFbnVtVHlwZSB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0IHsgRnVuY3Rpb25zUm91dGVyIH0gZnJvbSAnLi4vLi4vUm91dGVycy9GdW5jdGlvbnNSb3V0ZXInO1xuaW1wb3J0ICogYXMgZGVmYXVsdEdyYXBoUUxUeXBlcyBmcm9tICcuL2RlZmF1bHRHcmFwaFFMVHlwZXMnO1xuXG5jb25zdCBsb2FkID0gcGFyc2VHcmFwaFFMU2NoZW1hID0+IHtcbiAgaWYgKHBhcnNlR3JhcGhRTFNjaGVtYS5mdW5jdGlvbk5hbWVzLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBjbG91ZENvZGVGdW5jdGlvbkVudW0gPSBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoXG4gICAgICBuZXcgR3JhcGhRTEVudW1UeXBlKHtcbiAgICAgICAgbmFtZTogJ0Nsb3VkQ29kZUZ1bmN0aW9uJyxcbiAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgJ1RoZSBDbG91ZENvZGVGdW5jdGlvbiBlbnVtIHR5cGUgY29udGFpbnMgYSBsaXN0IG9mIGFsbCBhdmFpbGFibGUgY2xvdWQgY29kZSBmdW5jdGlvbnMuJyxcbiAgICAgICAgdmFsdWVzOiBwYXJzZUdyYXBoUUxTY2hlbWEuZnVuY3Rpb25OYW1lcy5yZWR1Y2UoXG4gICAgICAgICAgKHZhbHVlcywgZnVuY3Rpb25OYW1lKSA9PiAoe1xuICAgICAgICAgICAgLi4udmFsdWVzLFxuICAgICAgICAgICAgW2Z1bmN0aW9uTmFtZV06IHsgdmFsdWU6IGZ1bmN0aW9uTmFtZSB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIHt9XG4gICAgICAgICksXG4gICAgICB9KSxcbiAgICAgIHRydWUsXG4gICAgICB0cnVlXG4gICAgKTtcblxuICAgIGNvbnN0IGNhbGxDbG91ZENvZGVNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgICAgbmFtZTogJ0NhbGxDbG91ZENvZGUnLFxuICAgICAgZGVzY3JpcHRpb246ICdUaGUgY2FsbENsb3VkQ29kZSBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBpbnZva2UgYSBjbG91ZCBjb2RlIGZ1bmN0aW9uLicsXG4gICAgICBpbnB1dEZpZWxkczoge1xuICAgICAgICBmdW5jdGlvbk5hbWU6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZC4nLFxuICAgICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChjbG91ZENvZGVGdW5jdGlvbkVudW0pLFxuICAgICAgICB9LFxuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1RoZXNlIGFyZSB0aGUgcGFyYW1zIHRvIGJlIHBhc3NlZCB0byB0aGUgZnVuY3Rpb24uJyxcbiAgICAgICAgICB0eXBlOiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgICAgcmVzdWx0OiB7XG4gICAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSByZXN1bHQgdmFsdWUgb2YgdGhlIGNsb3VkIGNvZGUgZnVuY3Rpb24gZXhlY3V0aW9uLicsXG4gICAgICAgICAgdHlwZTogZGVmYXVsdEdyYXBoUUxUeXBlcy5BTlksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgbXV0YXRlQW5kR2V0UGF5bG9hZDogYXN5bmMgKGFyZ3MsIGNvbnRleHQpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB7IGZ1bmN0aW9uTmFtZSwgcGFyYW1zIH0gPSBhcmdzO1xuICAgICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlc3VsdDogKFxuICAgICAgICAgICAgICBhd2FpdCBGdW5jdGlvbnNSb3V0ZXIuaGFuZGxlQ2xvdWRGdW5jdGlvbih7XG4gICAgICAgICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICAgICAgICBmdW5jdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgICAgICBpbmZvLFxuICAgICAgICAgICAgICAgIGJvZHk6IHBhcmFtcyxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICkucmVzcG9uc2UucmVzdWx0LFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoY2FsbENsb3VkQ29kZU11dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGUsIHRydWUsIHRydWUpO1xuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjYWxsQ2xvdWRDb2RlTXV0YXRpb24udHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbignY2FsbENsb3VkQ29kZScsIGNhbGxDbG91ZENvZGVNdXRhdGlvbiwgdHJ1ZSwgdHJ1ZSk7XG4gIH1cbn07XG5cbmV4cG9ydCB7IGxvYWQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/parseClassMutations.js b/lib/GraphQL/loaders/parseClassMutations.js new file mode 100644 index 0000000000..56441fe1c2 --- /dev/null +++ b/lib/GraphQL/loaders/parseClassMutations.js @@ -0,0 +1,288 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = void 0; + +var _graphql = require("graphql"); + +var _graphqlRelay = require("graphql-relay"); + +var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); + +var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); + +var _parseGraphQLUtils = require("../parseGraphQLUtils"); + +var objectsMutations = _interopRequireWildcard(require("../helpers/objectsMutations")); + +var objectsQueries = _interopRequireWildcard(require("../helpers/objectsQueries")); + +var _ParseGraphQLController = require("../../Controllers/ParseGraphQLController"); + +var _className = require("../transformers/className"); + +var _mutation = require("../transformers/mutation"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const getOnlyRequiredFields = (updatedFields, selectedFieldsString, includedFieldsString, nativeObjectFields) => { + const includedFields = includedFieldsString ? includedFieldsString.split(',') : []; + const selectedFields = selectedFieldsString ? selectedFieldsString.split(',') : []; + const missingFields = selectedFields.filter(field => !nativeObjectFields.includes(field) || includedFields.includes(field)).join(','); + + if (!missingFields.length) { + return { + needGet: false, + keys: '' + }; + } else { + return { + needGet: true, + keys: missingFields + }; + } +}; + +const load = function (parseGraphQLSchema, parseClass, parseClassConfig) { + const className = parseClass.className; + const graphQLClassName = (0, _className.transformClassNameToGraphQL)(className); + const getGraphQLQueryName = graphQLClassName.charAt(0).toLowerCase() + graphQLClassName.slice(1); + const { + create: isCreateEnabled = true, + update: isUpdateEnabled = true, + destroy: isDestroyEnabled = true, + createAlias = '', + updateAlias = '', + destroyAlias = '' + } = (0, _parseGraphQLUtils.getParseClassMutationConfig)(parseClassConfig); + const { + classGraphQLCreateType, + classGraphQLUpdateType, + classGraphQLOutputType + } = parseGraphQLSchema.parseClassTypes[className]; + + if (isCreateEnabled) { + const createGraphQLMutationName = createAlias || `create${graphQLClassName}`; + const createGraphQLMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: `Create${graphQLClassName}`, + description: `The ${createGraphQLMutationName} mutation can be used to create a new object of the ${graphQLClassName} class.`, + inputFields: { + fields: { + description: 'These are the fields that will be used to create the new object.', + type: classGraphQLCreateType || defaultGraphQLTypes.OBJECT + } + }, + outputFields: { + [getGraphQLQueryName]: { + description: 'This is the created object.', + type: new _graphql.GraphQLNonNull(classGraphQLOutputType || defaultGraphQLTypes.OBJECT) + } + }, + mutateAndGetPayload: async (args, context, mutationInfo) => { + try { + let { + fields + } = args; + if (!fields) fields = {}; + const { + config, + auth, + info + } = context; + const parseFields = await (0, _mutation.transformTypes)('create', fields, { + className, + parseGraphQLSchema, + req: { + config, + auth, + info + } + }); + const createdObject = await objectsMutations.createObject(className, parseFields, config, auth, info); + const selectedFields = (0, _graphqlListFields.default)(mutationInfo).filter(field => field.startsWith(`${getGraphQLQueryName}.`)).map(field => field.replace(`${getGraphQLQueryName}.`, '')); + const { + keys, + include + } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields); + const { + keys: requiredKeys, + needGet + } = getOnlyRequiredFields(fields, keys, include, ['id', 'objectId', 'createdAt', 'updatedAt']); + const needToGetAllKeys = objectsQueries.needToGetAllKeys(parseClass.fields, keys, parseGraphQLSchema.parseClasses); + let optimizedObject = {}; + + if (needGet && !needToGetAllKeys) { + optimizedObject = await objectsQueries.getObject(className, createdObject.objectId, requiredKeys, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); + } else if (needToGetAllKeys) { + optimizedObject = await objectsQueries.getObject(className, createdObject.objectId, undefined, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); + } + + return { + [getGraphQLQueryName]: _objectSpread(_objectSpread(_objectSpread({}, createdObject), {}, { + updatedAt: createdObject.createdAt + }, parseFields), optimizedObject) + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + + if (parseGraphQLSchema.addGraphQLType(createGraphQLMutation.args.input.type.ofType) && parseGraphQLSchema.addGraphQLType(createGraphQLMutation.type)) { + parseGraphQLSchema.addGraphQLMutation(createGraphQLMutationName, createGraphQLMutation); + } + } + + if (isUpdateEnabled) { + const updateGraphQLMutationName = updateAlias || `update${graphQLClassName}`; + const updateGraphQLMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: `Update${graphQLClassName}`, + description: `The ${updateGraphQLMutationName} mutation can be used to update an object of the ${graphQLClassName} class.`, + inputFields: { + id: defaultGraphQLTypes.GLOBAL_OR_OBJECT_ID_ATT, + fields: { + description: 'These are the fields that will be used to update the object.', + type: classGraphQLUpdateType || defaultGraphQLTypes.OBJECT + } + }, + outputFields: { + [getGraphQLQueryName]: { + description: 'This is the updated object.', + type: new _graphql.GraphQLNonNull(classGraphQLOutputType || defaultGraphQLTypes.OBJECT) + } + }, + mutateAndGetPayload: async (args, context, mutationInfo) => { + try { + let { + id, + fields + } = args; + if (!fields) fields = {}; + const { + config, + auth, + info + } = context; + const globalIdObject = (0, _graphqlRelay.fromGlobalId)(id); + + if (globalIdObject.type === className) { + id = globalIdObject.id; + } + + const parseFields = await (0, _mutation.transformTypes)('update', fields, { + className, + parseGraphQLSchema, + req: { + config, + auth, + info + } + }); + const updatedObject = await objectsMutations.updateObject(className, id, parseFields, config, auth, info); + const selectedFields = (0, _graphqlListFields.default)(mutationInfo).filter(field => field.startsWith(`${getGraphQLQueryName}.`)).map(field => field.replace(`${getGraphQLQueryName}.`, '')); + const { + keys, + include + } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields); + const { + keys: requiredKeys, + needGet + } = getOnlyRequiredFields(fields, keys, include, ['id', 'objectId', 'updatedAt']); + const needToGetAllKeys = objectsQueries.needToGetAllKeys(parseClass.fields, keys, parseGraphQLSchema.parseClasses); + let optimizedObject = {}; + + if (needGet && !needToGetAllKeys) { + optimizedObject = await objectsQueries.getObject(className, id, requiredKeys, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); + } else if (needToGetAllKeys) { + optimizedObject = await objectsQueries.getObject(className, id, undefined, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); + } + + return { + [getGraphQLQueryName]: _objectSpread(_objectSpread(_objectSpread({ + objectId: id + }, updatedObject), parseFields), optimizedObject) + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + + if (parseGraphQLSchema.addGraphQLType(updateGraphQLMutation.args.input.type.ofType) && parseGraphQLSchema.addGraphQLType(updateGraphQLMutation.type)) { + parseGraphQLSchema.addGraphQLMutation(updateGraphQLMutationName, updateGraphQLMutation); + } + } + + if (isDestroyEnabled) { + const deleteGraphQLMutationName = destroyAlias || `delete${graphQLClassName}`; + const deleteGraphQLMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: `Delete${graphQLClassName}`, + description: `The ${deleteGraphQLMutationName} mutation can be used to delete an object of the ${graphQLClassName} class.`, + inputFields: { + id: defaultGraphQLTypes.GLOBAL_OR_OBJECT_ID_ATT + }, + outputFields: { + [getGraphQLQueryName]: { + description: 'This is the deleted object.', + type: new _graphql.GraphQLNonNull(classGraphQLOutputType || defaultGraphQLTypes.OBJECT) + } + }, + mutateAndGetPayload: async (args, context, mutationInfo) => { + try { + let { + id + } = args; + const { + config, + auth, + info + } = context; + const globalIdObject = (0, _graphqlRelay.fromGlobalId)(id); + + if (globalIdObject.type === className) { + id = globalIdObject.id; + } + + const selectedFields = (0, _graphqlListFields.default)(mutationInfo).filter(field => field.startsWith(`${getGraphQLQueryName}.`)).map(field => field.replace(`${getGraphQLQueryName}.`, '')); + const { + keys, + include + } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields); + let optimizedObject = {}; + + if (keys && keys.split(',').filter(key => !['id', 'objectId'].includes(key)).length > 0) { + optimizedObject = await objectsQueries.getObject(className, id, keys, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); + } + + await objectsMutations.deleteObject(className, id, config, auth, info); + return { + [getGraphQLQueryName]: _objectSpread({ + objectId: id + }, optimizedObject) + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + + if (parseGraphQLSchema.addGraphQLType(deleteGraphQLMutation.args.input.type.ofType) && parseGraphQLSchema.addGraphQLType(deleteGraphQLMutation.type)) { + parseGraphQLSchema.addGraphQLMutation(deleteGraphQLMutationName, deleteGraphQLMutation); + } + } +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvcGFyc2VDbGFzc011dGF0aW9ucy5qcyJdLCJuYW1lcyI6WyJnZXRPbmx5UmVxdWlyZWRGaWVsZHMiLCJ1cGRhdGVkRmllbGRzIiwic2VsZWN0ZWRGaWVsZHNTdHJpbmciLCJpbmNsdWRlZEZpZWxkc1N0cmluZyIsIm5hdGl2ZU9iamVjdEZpZWxkcyIsImluY2x1ZGVkRmllbGRzIiwic3BsaXQiLCJzZWxlY3RlZEZpZWxkcyIsIm1pc3NpbmdGaWVsZHMiLCJmaWx0ZXIiLCJmaWVsZCIsImluY2x1ZGVzIiwiam9pbiIsImxlbmd0aCIsIm5lZWRHZXQiLCJrZXlzIiwibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsInBhcnNlQ2xhc3MiLCJwYXJzZUNsYXNzQ29uZmlnIiwiY2xhc3NOYW1lIiwiZ3JhcGhRTENsYXNzTmFtZSIsImdldEdyYXBoUUxRdWVyeU5hbWUiLCJjaGFyQXQiLCJ0b0xvd2VyQ2FzZSIsInNsaWNlIiwiY3JlYXRlIiwiaXNDcmVhdGVFbmFibGVkIiwidXBkYXRlIiwiaXNVcGRhdGVFbmFibGVkIiwiZGVzdHJveSIsImlzRGVzdHJveUVuYWJsZWQiLCJjcmVhdGVBbGlhcyIsInVwZGF0ZUFsaWFzIiwiZGVzdHJveUFsaWFzIiwiY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSIsImNsYXNzR3JhcGhRTFVwZGF0ZVR5cGUiLCJjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIiwicGFyc2VDbGFzc1R5cGVzIiwiY3JlYXRlR3JhcGhRTE11dGF0aW9uTmFtZSIsImNyZWF0ZUdyYXBoUUxNdXRhdGlvbiIsIm5hbWUiLCJkZXNjcmlwdGlvbiIsImlucHV0RmllbGRzIiwiZmllbGRzIiwidHlwZSIsImRlZmF1bHRHcmFwaFFMVHlwZXMiLCJPQkpFQ1QiLCJvdXRwdXRGaWVsZHMiLCJHcmFwaFFMTm9uTnVsbCIsIm11dGF0ZUFuZEdldFBheWxvYWQiLCJhcmdzIiwiY29udGV4dCIsIm11dGF0aW9uSW5mbyIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwicGFyc2VGaWVsZHMiLCJyZXEiLCJjcmVhdGVkT2JqZWN0Iiwib2JqZWN0c011dGF0aW9ucyIsImNyZWF0ZU9iamVjdCIsInN0YXJ0c1dpdGgiLCJtYXAiLCJyZXBsYWNlIiwiaW5jbHVkZSIsInJlcXVpcmVkS2V5cyIsIm5lZWRUb0dldEFsbEtleXMiLCJvYmplY3RzUXVlcmllcyIsInBhcnNlQ2xhc3NlcyIsIm9wdGltaXplZE9iamVjdCIsImdldE9iamVjdCIsIm9iamVjdElkIiwidW5kZWZpbmVkIiwidXBkYXRlZEF0IiwiY3JlYXRlZEF0IiwiZSIsImhhbmRsZUVycm9yIiwiYWRkR3JhcGhRTFR5cGUiLCJpbnB1dCIsIm9mVHlwZSIsImFkZEdyYXBoUUxNdXRhdGlvbiIsInVwZGF0ZUdyYXBoUUxNdXRhdGlvbk5hbWUiLCJ1cGRhdGVHcmFwaFFMTXV0YXRpb24iLCJpZCIsIkdMT0JBTF9PUl9PQkpFQ1RfSURfQVRUIiwiZ2xvYmFsSWRPYmplY3QiLCJ1cGRhdGVkT2JqZWN0IiwidXBkYXRlT2JqZWN0IiwiZGVsZXRlR3JhcGhRTE11dGF0aW9uTmFtZSIsImRlbGV0ZUdyYXBoUUxNdXRhdGlvbiIsImtleSIsImRlbGV0ZU9iamVjdCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7Ozs7Ozs7OztBQUVBLE1BQU1BLHFCQUFxQixHQUFHLENBQzVCQyxhQUQ0QixFQUU1QkMsb0JBRjRCLEVBRzVCQyxvQkFINEIsRUFJNUJDLGtCQUo0QixLQUt6QjtBQUNILFFBQU1DLGNBQWMsR0FBR0Ysb0JBQW9CLEdBQUdBLG9CQUFvQixDQUFDRyxLQUFyQixDQUEyQixHQUEzQixDQUFILEdBQXFDLEVBQWhGO0FBQ0EsUUFBTUMsY0FBYyxHQUFHTCxvQkFBb0IsR0FBR0Esb0JBQW9CLENBQUNJLEtBQXJCLENBQTJCLEdBQTNCLENBQUgsR0FBcUMsRUFBaEY7QUFDQSxRQUFN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RCxDQW9DRSxPQUFPTSxDQUFQLEVBQVU7QUFDVjNELFVBQUFBLGtCQUFrQixDQUFDNEQsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRjtBQXBEd0QsS0FBN0IsQ0FBOUI7O0FBdURBLFFBQ0UzRCxrQkFBa0IsQ0FBQzZELGNBQW5CLENBQWtDWSxxQkFBcUIsQ0FBQ3ZDLElBQXRCLENBQTJCNEIsS0FBM0IsQ0FBaUNsQyxJQUFqQyxDQUFzQ21DLE1BQXhFLEtBQ0EvRCxrQkFBa0IsQ0FBQzZELGNBQW5CLENBQWtDWSxxQkFBcUIsQ0FBQzdDLElBQXhELENBRkYsRUFHRTtBQUNBNUIsTUFBQUEsa0JBQWtCLENBQUNnRSxrQkFBbkIsQ0FBc0NRLHlCQUF0QyxFQUFpRUMscUJBQWpFO0FBQ0Q7QUFDRjtBQUNGLENBdFNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgR3JhcGhRTE5vbk51bGwgfSBmcm9tICdncmFwaHFsJztcbmltcG9ydCB7IGZyb21HbG9iYWxJZCwgbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0IGdldEZpZWxkTmFtZXMgZnJvbSAnZ3JhcGhxbC1saXN0LWZpZWxkcyc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4vZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQgeyBleHRyYWN0S2V5c0FuZEluY2x1ZGUsIGdldFBhcnNlQ2xhc3NNdXRhdGlvbkNvbmZpZyB9IGZyb20gJy4uL3BhcnNlR3JhcGhRTFV0aWxzJztcbmltcG9ydCAqIGFzIG9iamVjdHNNdXRhdGlvbnMgZnJvbSAnLi4vaGVscGVycy9vYmplY3RzTXV0YXRpb25zJztcbmltcG9ydCAqIGFzIG9iamVjdHNRdWVyaWVzIGZyb20gJy4uL2hlbHBlcnMvb2JqZWN0c1F1ZXJpZXMnO1xuaW1wb3J0IHsgUGFyc2VHcmFwaFFMQ2xhc3NDb25maWcgfSBmcm9tICcuLi8uLi9Db250cm9sbGVycy9QYXJzZUdyYXBoUUxDb250cm9sbGVyJztcbmltcG9ydCB7IHRyYW5zZm9ybUNsYXNzTmFtZVRvR3JhcGhRTCB9IGZyb20gJy4uL3RyYW5zZm9ybWVycy9jbGFzc05hbWUnO1xuaW1wb3J0IHsgdHJhbnNmb3JtVHlwZXMgfSBmcm9tICcuLi90cmFuc2Zvcm1lcnMvbXV0YXRpb24nO1xuXG5jb25zdCBnZXRPbmx5UmVxdWlyZWRGaWVsZHMgPSAoXG4gIHVwZGF0ZWRGaWVsZHMsXG4gIHNlbGVjdGVkRmllbGRzU3RyaW5nLFxuICBpbmNsdWRlZEZpZWxkc1N0cmluZyxcbiAgbmF0aXZlT2JqZWN0RmllbGRzXG4pID0+IHtcbiAgY29uc3QgaW5jbHVkZWRGaWVsZHMgPSBpbmNsdWRlZEZpZWxkc1N0cmluZyA/IGluY2x1ZGVkRmllbGRzU3RyaW5nLnNwbGl0KCcsJykgOiBbXTtcbiAgY29uc3Qgc2VsZWN0ZWRGaWVsZHMgPSBzZWxlY3RlZEZpZWxkc1N0cmluZyA/IHNlbGVjdGVkRmllbGRzU3RyaW5nLnNwbGl0KCcsJykgOiBbXTtcbiAgY29uc3QgbWlzc2luZ0ZpZWxkcyA9IHNlbGVjdGVkRmllbGRzXG4gICAgLmZpbHRlcihmaWVsZCA9PiAhbmF0aXZlT2JqZWN0RmllbGRzLmluY2x1ZGVzKGZpZWxkKSB8fCBpbmNsdWRlZEZpZWxkcy5pbmNsdWRlcyhmaWVsZCkpXG4gICAgLmpvaW4oJywnKTtcbiAgaWYgKCFtaXNzaW5nRmllbGRzLmxlbmd0aCkge1xuICAgIHJldHVybiB7IG5lZWRHZXQ6IGZhbHNlLCBrZXlzOiAnJyB9O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB7IG5lZWRHZXQ6IHRydWUsIGtleXM6IG1pc3NpbmdGaWVsZHMgfTtcbiAgfVxufTtcblxuY29uc3QgbG9hZCA9IGZ1bmN0aW9uIChwYXJzZUdyYXBoUUxTY2hlbWEsIHBhcnNlQ2xhc3MsIHBhcnNlQ2xhc3NDb25maWc6ID9QYXJzZUdyYXBoUUxDbGFzc0NvbmZpZykge1xuICBjb25zdCBjbGFzc05hbWUgPSBwYXJzZUNsYXNzLmNsYXNzTmFtZTtcbiAgY29uc3QgZ3JhcGhRTENsYXNzTmFtZSA9IHRyYW5zZm9ybUNsYXNzTmFtZVRvR3JhcGhRTChjbGFzc05hbWUpO1xuICBjb25zdCBnZXRHcmFwaFFMUXVlcnlOYW1lID0gZ3JhcGhRTENsYXNzTmFtZS5jaGFyQXQoMCkudG9Mb3dlckNhc2UoKSArIGdyYXBoUUxDbGFzc05hbWUuc2xpY2UoMSk7XG5cbiAgY29uc3Qge1xuICAgIGNyZWF0ZTogaXNDcmVhdGVFbmFibGVkID0gdHJ1ZSxcbiAgICB1cGRhdGU6IGlzVXBkYXRlRW5hYmxlZCA9IHRydWUsXG4gICAgZGVzdHJveTogaXNEZXN0cm95RW5hYmxlZCA9IHRydWUsXG4gICAgY3JlYXRlQWxpYXM6IGNyZWF0ZUFsaWFzID0gJycsXG4gICAgdXBkYXRlQWxpYXM6IHVwZGF0ZUFsaWFzID0gJycsXG4gICAgZGVzdHJveUFsaWFzOiBkZXN0cm95QWxpYXMgPSAnJyxcbiAgfSA9IGdldFBhcnNlQ2xhc3NNdXRhdGlvbkNvbmZpZyhwYXJzZUNsYXNzQ29uZmlnKTtcblxuICBjb25zdCB7XG4gICAgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSxcbiAgICBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlLFxuICAgIGNsYXNzR3JhcGhRTE91dHB1dFR5cGUsXG4gIH0gPSBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzW2NsYXNzTmFtZV07XG5cbiAgaWYgKGlzQ3JlYXRlRW5hYmxlZCkge1xuICAgIGNvbnN0IGNyZWF0ZUdyYXBoUUxNdXRhdGlvbk5hbWUgPSBjcmVhdGVBbGlhcyB8fCBgY3JlYXRlJHtncmFwaFFMQ2xhc3NOYW1lfWA7XG4gICAgY29uc3QgY3JlYXRlR3JhcGhRTE11dGF0aW9uID0gbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCh7XG4gICAgICBuYW1lOiBgQ3JlYXRlJHtncmFwaFFMQ2xhc3NOYW1lfWAsXG4gICAgICBkZXNjcmlwdGlvbjogYFRoZSAke2NyZWF0ZUdyYXBoUUxNdXRhdGlvbk5hbWV9IG11dGF0aW9uIGNhbiBiZSB1c2VkIHRvIGNyZWF0ZSBhIG5ldyBvYmplY3Qgb2YgdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuYCxcbiAgICAgIGlucHV0RmllbGRzOiB7XG4gICAgICAgIGZpZWxkczoge1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnVGhlc2UgYXJlIHRoZSBmaWVsZHMgdGhhdCB3aWxsIGJlIHVzZWQgdG8gY3JlYXRlIHRoZSBuZXcgb2JqZWN0LicsXG4gICAgICAgICAgdHlwZTogY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSB8fCBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgICAgW2dldEdyYXBoUUxRdWVyeU5hbWVdOiB7XG4gICAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBjcmVhdGVkIG9iamVjdC4nLFxuICAgICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIHx8IGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUKSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBtdXRhdGVBbmRHZXRQYXlsb2FkOiBhc3luYyAoYXJncywgY29udGV4dCwgbXV0YXRpb25JbmZvKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgbGV0IHsgZmllbGRzIH0gPSBhcmdzO1xuICAgICAgICAgIGlmICghZmllbGRzKSBmaWVsZHMgPSB7fTtcbiAgICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcblxuICAgICAgICAgIGNvbnN0IHBhcnNlRmllbGRzID0gYXdhaXQgdHJhbnNmb3JtVHlwZXMoJ2NyZWF0ZScsIGZpZWxkcywge1xuICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLFxuICAgICAgICAgICAgcmVxOiB7IGNvbmZpZywgYXV0aCwgaW5mbyB9LFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3QgY3JlYXRlZE9iamVjdCA9IGF3YWl0IG9iamVjdHNNdXRhdGlvbnMuY3JlYXRlT2JqZWN0KFxuICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgcGFyc2VGaWVsZHMsXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgaW5mb1xuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3Qgc2VsZWN0ZWRGaWVsZHMgPSBnZXRGaWVsZE5hbWVzKG11dGF0aW9uSW5mbylcbiAgICAgICAgICAgIC5maWx0ZXIoZmllbGQgPT4gZmllbGQuc3RhcnRzV2l0aChgJHtnZXRHcmFwaFFMUXVlcnlOYW1lfS5gKSlcbiAgICAgICAgICAgIC5tYXAoZmllbGQgPT4gZmllbGQucmVwbGFjZShgJHtnZXRHcmFwaFFMUXVlcnlOYW1lfS5gLCAnJykpO1xuICAgICAgICAgIGNvbnN0IHsga2V5cywgaW5jbHVkZSB9ID0gZXh0cmFjdEtleXNBbmRJbmNsdWRlKHNlbGVjdGVkRmllbGRzKTtcbiAgICAgICAgICBjb25zdCB7IGtleXM6IHJlcXVpcmVkS2V5cywgbmVlZEdldCB9ID0gZ2V0T25seVJlcXVpcmVkRmllbGRzKGZpZWxkcywga2V5cywgaW5jbHVkZSwgW1xuICAgICAgICAgICAgJ2lkJyxcbiAgICAgICAgICAgICdvYmplY3RJZCcsXG4gICAgICAgICAgICAnY3JlYXRlZEF0JyxcbiAgICAgICAgICAgICd1cGRhdGVkQXQnLFxuICAgICAgICAgIF0pO1xuICAgICAgICAgIGNvbnN0IG5lZWRUb0dldEFsbEtleXMgPSBvYmplY3RzUXVlcmllcy5uZWVkVG9HZXRBbGxLZXlzKFxuICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHMsXG4gICAgICAgICAgICBrZXlzLFxuICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3Nlc1xuICAgICAgICAgICk7XG4gICAgICAgICAgbGV0IG9wdGltaXplZE9iamVjdCA9IHt9O1xuICAgICAgICAgIGlmIChuZWVkR2V0ICYmICFuZWVkVG9HZXRBbGxLZXlzKSB7XG4gICAgICAgICAgICBvcHRpbWl6ZWRPYmplY3QgPSBhd2FpdCBvYmplY3RzUXVlcmllcy5nZXRPYmplY3QoXG4gICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgY3JlYXRlZE9iamVjdC5vYmplY3RJZCxcbiAgICAgICAgICAgICAgcmVxdWlyZWRLZXlzLFxuICAgICAgICAgICAgICBpbmNsdWRlLFxuICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICBpbmZvLFxuICAgICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc2VzXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSBpZiAobmVlZFRvR2V0QWxsS2V5cykge1xuICAgICAgICAgICAgb3B0aW1pemVkT2JqZWN0ID0gYXdhaXQgb2JqZWN0c1F1ZXJpZXMuZ2V0T2JqZWN0KFxuICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgIGNyZWF0ZWRPYmplY3Qub2JqZWN0SWQsXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgaW5jbHVkZSxcbiAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3Nlc1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIFtnZXRHcmFwaFFMUXVlcnlOYW1lXToge1xuICAgICAgICAgICAgICAuLi5jcmVhdGVkT2JqZWN0LFxuICAgICAgICAgICAgICB1cGRhdGVkQXQ6IGNyZWF0ZWRPYmplY3QuY3JlYXRlZEF0LFxuICAgICAgICAgICAgICAuLi5wYXJzZUZpZWxkcyxcbiAgICAgICAgICAgICAgLi4ub3B0aW1pemVkT2JqZWN0LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgaWYgKFxuICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNyZWF0ZUdyYXBoUUxNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlKSAmJlxuICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNyZWF0ZUdyYXBoUUxNdXRhdGlvbi50eXBlKVxuICAgICkge1xuICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbihjcmVhdGVHcmFwaFFMTXV0YXRpb25OYW1lLCBjcmVhdGVHcmFwaFFMTXV0YXRpb24pO1xuICAgIH1cbiAgfVxuXG4gIGlmIChpc1VwZGF0ZUVuYWJsZWQpIHtcbiAgICBjb25zdCB1cGRhdGVHcmFwaFFMTXV0YXRpb25OYW1lID0gdXBkYXRlQWxpYXMgfHwgYHVwZGF0ZSR7Z3JhcGhRTENsYXNzTmFtZX1gO1xuICAgIGNvbnN0IHVwZGF0ZUdyYXBoUUxNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgICAgbmFtZTogYFVwZGF0ZSR7Z3JhcGhRTENsYXNzTmFtZX1gLFxuICAgICAgZGVzY3JpcHRpb246IGBUaGUgJHt1cGRhdGVHcmFwaFFMTXV0YXRpb25OYW1lfSBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byB1cGRhdGUgYW4gb2JqZWN0IG9mIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLmAsXG4gICAgICBpbnB1dEZpZWxkczoge1xuICAgICAgICBpZDogZGVmYXVsdEdyYXBoUUxUeXBlcy5HTE9CQUxfT1JfT0JKRUNUX0lEX0FUVCxcbiAgICAgICAgZmllbGRzOiB7XG4gICAgICAgICAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIGZpZWxkcyB0aGF0IHdpbGwgYmUgdXNlZCB0byB1cGRhdGUgdGhlIG9iamVjdC4nLFxuICAgICAgICAgIHR5cGU6IGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGUgfHwgZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1QsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgb3V0cHV0RmllbGRzOiB7XG4gICAgICAgIFtnZXRHcmFwaFFMUXVlcnlOYW1lXToge1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgdXBkYXRlZCBvYmplY3QuJyxcbiAgICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSB8fCBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVCksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgbXV0YXRlQW5kR2V0UGF5bG9hZDogYXN5bmMgKGFyZ3MsIGNvbnRleHQsIG11dGF0aW9uSW5mbykgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGxldCB7IGlkLCBmaWVsZHMgfSA9IGFyZ3M7XG4gICAgICAgICAgaWYgKCFmaWVsZHMpIGZpZWxkcyA9IHt9O1xuICAgICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuXG4gICAgICAgICAgY29uc3QgZ2xvYmFsSWRPYmplY3QgPSBmcm9tR2xvYmFsSWQoaWQpO1xuXG4gICAgICAgICAgaWYgKGdsb2JhbElkT2JqZWN0LnR5cGUgPT09IGNsYXNzTmFtZSkge1xuICAgICAgICAgICAgaWQgPSBnbG9iYWxJZE9iamVjdC5pZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBwYXJzZUZpZWxkcyA9IGF3YWl0IHRyYW5zZm9ybVR5cGVzKCd1cGRhdGUnLCBmaWVsZHMsIHtcbiAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYSxcbiAgICAgICAgICAgIHJlcTogeyBjb25maWcsIGF1dGgsIGluZm8gfSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IHVwZGF0ZWRPYmplY3QgPSBhd2FpdCBvYmplY3RzTXV0YXRpb25zLnVwZGF0ZU9iamVjdChcbiAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgcGFyc2VGaWVsZHMsXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgaW5mb1xuICAgICAgICAgICk7XG5cbiAgICAgICAgICBjb25zdCBzZWxlY3RlZEZpZWxkcyA9IGdldEZpZWxkTmFtZXMobXV0YXRpb25JbmZvKVxuICAgICAgICAgICAgLmZpbHRlcihmaWVsZCA9PiBmaWVsZC5zdGFydHNXaXRoKGAke2dldEdyYXBoUUxRdWVyeU5hbWV9LmApKVxuICAgICAgICAgICAgLm1hcChmaWVsZCA9PiBmaWVsZC5yZXBsYWNlKGAke2dldEdyYXBoUUxRdWVyeU5hbWV9LmAsICcnKSk7XG4gICAgICAgICAgY29uc3QgeyBrZXlzLCBpbmNsdWRlIH0gPSBleHRyYWN0S2V5c0FuZEluY2x1ZGUoc2VsZWN0ZWRGaWVsZHMpO1xuICAgICAgICAgIGNvbnN0IHsga2V5czogcmVxdWlyZWRLZXlzLCBuZWVkR2V0IH0gPSBnZXRPbmx5UmVxdWlyZWRGaWVsZHMoZmllbGRzLCBrZXlzLCBpbmNsdWRlLCBbXG4gICAgICAgICAgICAnaWQnLFxuICAgICAgICAgICAgJ29iamVjdElkJyxcbiAgICAgICAgICAgICd1cGRhdGVkQXQnLFxuICAgICAgICAgIF0pO1xuICAgICAgICAgIGNvbnN0IG5lZWRUb0dldEFsbEtleXMgPSBvYmplY3RzUXVlcmllcy5uZWVkVG9HZXRBbGxLZXlzKFxuICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHMsXG4gICAgICAgICAgICBrZXlzLFxuICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3Nlc1xuICAgICAgICAgICk7XG4gICAgICAgICAgbGV0IG9wdGltaXplZE9iamVjdCA9IHt9O1xuICAgICAgICAgIGlmIChuZWVkR2V0ICYmICFuZWVkVG9HZXRBbGxLZXlzKSB7XG4gICAgICAgICAgICBvcHRpbWl6ZWRPYmplY3QgPSBhd2FpdCBvYmplY3RzUXVlcmllcy5nZXRPYmplY3QoXG4gICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICAgIHJlcXVpcmVkS2V5cyxcbiAgICAgICAgICAgICAgaW5jbHVkZSxcbiAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3Nlc1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKG5lZWRUb0dldEFsbEtleXMpIHtcbiAgICAgICAgICAgIG9wdGltaXplZE9iamVjdCA9IGF3YWl0IG9iamVjdHNRdWVyaWVzLmdldE9iamVjdChcbiAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICBpZCxcbiAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICBpbmNsdWRlLFxuICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICBpbmZvLFxuICAgICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc2VzXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgW2dldEdyYXBoUUxRdWVyeU5hbWVdOiB7XG4gICAgICAgICAgICAgIG9iamVjdElkOiBpZCxcbiAgICAgICAgICAgICAgLi4udXBkYXRlZE9iamVjdCxcbiAgICAgICAgICAgICAgLi4ucGFyc2VGaWVsZHMsXG4gICAgICAgICAgICAgIC4uLm9wdGltaXplZE9iamVjdCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGlmIChcbiAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZSh1cGRhdGVHcmFwaFFMTXV0YXRpb24uYXJncy5pbnB1dC50eXBlLm9mVHlwZSkgJiZcbiAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZSh1cGRhdGVHcmFwaFFMTXV0YXRpb24udHlwZSlcbiAgICApIHtcbiAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24odXBkYXRlR3JhcGhRTE11dGF0aW9uTmFtZSwgdXBkYXRlR3JhcGhRTE11dGF0aW9uKTtcbiAgICB9XG4gIH1cblxuICBpZiAoaXNEZXN0cm95RW5hYmxlZCkge1xuICAgIGNvbnN0IGRlbGV0ZUdyYXBoUUxNdXRhdGlvbk5hbWUgPSBkZXN0cm95QWxpYXMgfHwgYGRlbGV0ZSR7Z3JhcGhRTENsYXNzTmFtZX1gO1xuICAgIGNvbnN0IGRlbGV0ZUdyYXBoUUxNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgICAgbmFtZTogYERlbGV0ZSR7Z3JhcGhRTENsYXNzTmFtZX1gLFxuICAgICAgZGVzY3JpcHRpb246IGBUaGUgJHtkZWxldGVHcmFwaFFMTXV0YXRpb25OYW1lfSBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBkZWxldGUgYW4gb2JqZWN0IG9mIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLmAsXG4gICAgICBpbnB1dEZpZWxkczoge1xuICAgICAgICBpZDogZGVmYXVsdEdyYXBoUUxUeXBlcy5HTE9CQUxfT1JfT0JKRUNUX0lEX0FUVCxcbiAgICAgIH0sXG4gICAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgICAgW2dldEdyYXBoUUxRdWVyeU5hbWVdOiB7XG4gICAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBkZWxldGVkIG9iamVjdC4nLFxuICAgICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIHx8IGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUKSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBtdXRhdGVBbmRHZXRQYXlsb2FkOiBhc3luYyAoYXJncywgY29udGV4dCwgbXV0YXRpb25JbmZvKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgbGV0IHsgaWQgfSA9IGFyZ3M7XG4gICAgICAgICAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG5cbiAgICAgICAgICBjb25zdCBnbG9iYWxJZE9iamVjdCA9IGZyb21HbG9iYWxJZChpZCk7XG5cbiAgICAgICAgICBpZiAoZ2xvYmFsSWRPYmplY3QudHlwZSA9PT0gY2xhc3NOYW1lKSB7XG4gICAgICAgICAgICBpZCA9IGdsb2JhbElkT2JqZWN0LmlkO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHNlbGVjdGVkRmllbGRzID0gZ2V0RmllbGROYW1lcyhtdXRhdGlvbkluZm8pXG4gICAgICAgICAgICAuZmlsdGVyKGZpZWxkID0+IGZpZWxkLnN0YXJ0c1dpdGgoYCR7Z2V0R3JhcGhRTFF1ZXJ5TmFtZX0uYCkpXG4gICAgICAgICAgICAubWFwKGZpZWxkID0+IGZpZWxkLnJlcGxhY2UoYCR7Z2V0R3JhcGhRTFF1ZXJ5TmFtZX0uYCwgJycpKTtcbiAgICAgICAgICBjb25zdCB7IGtleXMsIGluY2x1ZGUgfSA9IGV4dHJhY3RLZXlzQW5kSW5jbHVkZShzZWxlY3RlZEZpZWxkcyk7XG4gICAgICAgICAgbGV0IG9wdGltaXplZE9iamVjdCA9IHt9O1xuICAgICAgICAgIGlmIChrZXlzICYmIGtleXMuc3BsaXQoJywnKS5maWx0ZXIoa2V5ID0+ICFbJ2lkJywgJ29iamVjdElkJ10uaW5jbHVkZXMoa2V5KSkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgb3B0aW1pemVkT2JqZWN0ID0gYXdhaXQgb2JqZWN0c1F1ZXJpZXMuZ2V0T2JqZWN0KFxuICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgICBrZXlzLFxuICAgICAgICAgICAgICBpbmNsdWRlLFxuICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICBpbmZvLFxuICAgICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc2VzXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBhd2FpdCBvYmplY3RzTXV0YXRpb25zLmRlbGV0ZU9iamVjdChjbGFzc05hbWUsIGlkLCBjb25maWcsIGF1dGgsIGluZm8pO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBbZ2V0R3JhcGhRTFF1ZXJ5TmFtZV06IHtcbiAgICAgICAgICAgICAgb2JqZWN0SWQ6IGlkLFxuICAgICAgICAgICAgICAuLi5vcHRpbWl6ZWRPYmplY3QsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAoXG4gICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoZGVsZXRlR3JhcGhRTE11dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGUpICYmXG4gICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoZGVsZXRlR3JhcGhRTE11dGF0aW9uLnR5cGUpXG4gICAgKSB7XG4gICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTE11dGF0aW9uKGRlbGV0ZUdyYXBoUUxNdXRhdGlvbk5hbWUsIGRlbGV0ZUdyYXBoUUxNdXRhdGlvbik7XG4gICAgfVxuICB9XG59O1xuXG5leHBvcnQgeyBsb2FkIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/loaders/parseClassQueries.js b/lib/GraphQL/loaders/parseClassQueries.js new file mode 100644 index 0000000000..e834ec09c2 --- /dev/null +++ b/lib/GraphQL/loaders/parseClassQueries.js @@ -0,0 +1,150 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = void 0; + +var _graphql = require("graphql"); + +var _graphqlRelay = require("graphql-relay"); + +var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); + +var _pluralize = _interopRequireDefault(require("pluralize")); + +var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); + +var objectsQueries = _interopRequireWildcard(require("../helpers/objectsQueries")); + +var _ParseGraphQLController = require("../../Controllers/ParseGraphQLController"); + +var _className = require("../transformers/className"); + +var _parseGraphQLUtils = require("../parseGraphQLUtils"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const getParseClassQueryConfig = function (parseClassConfig) { + return parseClassConfig && parseClassConfig.query || {}; +}; + +const getQuery = async (parseClass, _source, args, context, queryInfo, parseClasses) => { + let { + id + } = args; + const { + options + } = args; + const { + readPreference, + includeReadPreference + } = options || {}; + const { + config, + auth, + info + } = context; + const selectedFields = (0, _graphqlListFields.default)(queryInfo); + const globalIdObject = (0, _graphqlRelay.fromGlobalId)(id); + + if (globalIdObject.type === parseClass.className) { + id = globalIdObject.id; + } + + const { + keys, + include + } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields); + return await objectsQueries.getObject(parseClass.className, id, keys, include, readPreference, includeReadPreference, config, auth, info, parseClasses); +}; + +const load = function (parseGraphQLSchema, parseClass, parseClassConfig) { + const className = parseClass.className; + const graphQLClassName = (0, _className.transformClassNameToGraphQL)(className); + const { + get: isGetEnabled = true, + find: isFindEnabled = true, + getAlias = '', + findAlias = '' + } = getParseClassQueryConfig(parseClassConfig); + const { + classGraphQLOutputType, + classGraphQLFindArgs, + classGraphQLFindResultType + } = parseGraphQLSchema.parseClassTypes[className]; + + if (isGetEnabled) { + const lowerCaseClassName = graphQLClassName.charAt(0).toLowerCase() + graphQLClassName.slice(1); + const getGraphQLQueryName = getAlias || lowerCaseClassName; + parseGraphQLSchema.addGraphQLQuery(getGraphQLQueryName, { + description: `The ${getGraphQLQueryName} query can be used to get an object of the ${graphQLClassName} class by its id.`, + args: { + id: defaultGraphQLTypes.GLOBAL_OR_OBJECT_ID_ATT, + options: defaultGraphQLTypes.READ_OPTIONS_ATT + }, + type: new _graphql.GraphQLNonNull(classGraphQLOutputType || defaultGraphQLTypes.OBJECT), + + async resolve(_source, args, context, queryInfo) { + try { + return await getQuery(parseClass, _source, args, context, queryInfo, parseGraphQLSchema.parseClasses); + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + + }); + } + + if (isFindEnabled) { + const lowerCaseClassName = graphQLClassName.charAt(0).toLowerCase() + graphQLClassName.slice(1); + const findGraphQLQueryName = findAlias || (0, _pluralize.default)(lowerCaseClassName); + parseGraphQLSchema.addGraphQLQuery(findGraphQLQueryName, { + description: `The ${findGraphQLQueryName} query can be used to find objects of the ${graphQLClassName} class.`, + args: classGraphQLFindArgs, + type: new _graphql.GraphQLNonNull(classGraphQLFindResultType || defaultGraphQLTypes.OBJECT), + + async resolve(_source, args, context, queryInfo) { + try { + const { + where, + order, + skip, + first, + after, + last, + before, + options + } = args; + const { + readPreference, + includeReadPreference, + subqueryReadPreference + } = options || {}; + const { + config, + auth, + info + } = context; + const selectedFields = (0, _graphqlListFields.default)(queryInfo); + const { + keys, + include + } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields.filter(field => field.startsWith('edges.node.')).map(field => field.replace('edges.node.', ''))); + const parseOrder = order && order.join(','); + return await objectsQueries.findObjects(className, where, parseOrder, skip, first, after, last, before, keys, include, false, readPreference, includeReadPreference, subqueryReadPreference, config, auth, info, selectedFields, parseGraphQLSchema.parseClasses); + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + + }); + } +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvcGFyc2VDbGFzc1F1ZXJpZXMuanMiXSwibmFtZXMiOlsiZ2V0UGFyc2VDbGFzc1F1ZXJ5Q29uZmlnIiwicGFyc2VDbGFzc0NvbmZpZyIsInF1ZXJ5IiwiZ2V0UXVlcnkiLCJwYXJzZUNsYXNzIiwiX3NvdXJjZSIsImFyZ3MiLCJjb250ZXh0IiwicXVlcnlJbmZvIiwicGFyc2VDbGFzc2VzIiwiaWQiLCJvcHRpb25zIiwicmVhZFByZWZlcmVuY2UiLCJpbmNsdWRlUmVhZFByZWZlcmVuY2UiLCJjb25maWciLCJhdXRoIiwiaW5mbyIsInNlbGVjdGVkRmllbGRzIiwiZ2xvYmFsSWRPYmplY3QiLCJ0eXBlIiwiY2xhc3NOYW1lIiwia2V5cyIsImluY2x1ZGUiLCJvYmplY3RzUXVlcmllcyIsImdldE9iamVjdCIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJncmFwaFFMQ2xhc3NOYW1lIiwiZ2V0IiwiaXNHZXRFbmFibGVkIiwiZmluZCIsImlzRmluZEVuYWJsZWQiLCJnZXRBbGlhcyIsImZpbmRBbGlhcyIsImNsYXNzR3JhcGhRTE91dHB1dFR5cGUiLCJjbGFzc0dyYXBoUUxGaW5kQXJncyIsImNsYXNzR3JhcGhRTEZpbmRSZXN1bHRUeXBlIiwicGFyc2VDbGFzc1R5cGVzIiwibG93ZXJDYXNlQ2xhc3NOYW1lIiwiY2hhckF0IiwidG9Mb3dlckNhc2UiLCJzbGljZSIsImdldEdyYXBoUUxRdWVyeU5hbWUiLCJhZGRHcmFwaFFMUXVlcnkiLCJkZXNjcmlwdGlvbiIsImRlZmF1bHRHcmFwaFFMVHlwZXMiLCJHTE9CQUxfT1JfT0JKRUNUX0lEX0FUVCIsIlJFQURfT1BUSU9OU19BVFQiLCJHcmFwaFFMTm9uTnVsbCIsIk9CSkVDVCIsInJlc29sdmUiLCJlIiwiaGFuZGxlRXJyb3IiLCJmaW5kR3JhcGhRTFF1ZXJ5TmFtZSIsIndoZXJlIiwib3JkZXIiLCJza2lwIiwiZmlyc3QiLCJhZnRlciIsImxhc3QiLCJiZWZvcmUiLCJzdWJxdWVyeVJlYWRQcmVmZXJlbmNlIiwiZmlsdGVyIiwiZmllbGQiLCJzdGFydHNXaXRoIiwibWFwIiwicmVwbGFjZSIsInBhcnNlT3JkZXIiLCJqb2luIiwiZmluZE9iamVjdHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFQSxNQUFNQSx3QkFBd0IsR0FBRyxVQUFVQyxnQkFBVixFQUFzRDtBQUNyRixTQUFRQSxnQkFBZ0IsSUFBSUEsZ0JBQWdCLENBQUNDLEtBQXRDLElBQWdELEVBQXZEO0FBQ0QsQ0FGRDs7QUFJQSxNQUFNQyxRQUFRLEdBQUcsT0FBT0MsVUFBUCxFQUFtQkMsT0FBbkIsRUFBNEJDLElBQTVCLEVBQWtDQyxPQUFsQyxFQUEyQ0MsU0FBM0MsRUFBc0RDLFlBQXRELEtBQXVFO0FBQ3RGLE1BQUk7QUFBRUMsSUFBQUE7QUFBRixNQUFTSixJQUFiO0FBQ0EsUUFBTTtBQUFFSyxJQUFBQTtBQUFGLE1BQWNMLElBQXBCO0FBQ0EsUUFBTTtBQUFFTSxJQUFBQSxjQUFGO0FBQWtCQyxJQUFBQTtBQUFsQixNQUE0Q0YsT0FBTyxJQUFJLEVBQTdEO0FBQ0EsUUFBTTtBQUFFRyxJQUFBQSxNQUFGO0FBQVVDLElBQUFBLElBQVY7QUFBZ0JDLElBQUFBO0FBQWhCLE1BQXlCVCxPQUEvQjtBQUNBLFFBQU1VLGNBQWMsR0FBRyxnQ0FBY1QsU0FBZCxDQUF2QjtBQUVBLFFBQU1VLGNBQWMsR0FBRyxnQ0FBYVIsRUFBYixDQUF2Qjs7QUFFQSxNQUFJUSxjQUFjLENBQUNDLElBQWYsS0FBd0JmLFVBQVUsQ0FBQ2dCLFNBQXZDLEVBQWtEO0FBQ2hEVixJQUFBQSxFQUFFLEdBQUdRLGNBQWMsQ0FBQ1IsRUFBcEI7QUFDRDs7QUFFRCxRQUFNO0FBQUVXLElBQUFBLElBQUY7QUFBUUMsSUFBQUE7QUFBUixNQUFvQiw4Q0FBc0JMLGNBQXRCLENBQTFCO0FBRUEsU0FBTyxNQUFNTSxj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QyxPQVZXLEVBV1gsS0FYVyxFQVlYVixjQVpXLEVBYVhDLHFCQWJXLEVBY1hnRCxzQkFkVyxFQWVYL0MsTUFmVyxFQWdCWEMsSUFoQlcsRUFpQlhDLElBakJXLEVBa0JYQyxjQWxCVyxFQW1CWFMsa0JBQWtCLENBQUNqQixZQW5CUixDQUFiO0FBcUJELFNBbENELENBa0NFLE9BQU8wQyxDQUFQLEVBQVU7QUFDVnpCLFVBQUFBLGtCQUFrQixDQUFDMEIsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRjs7QUExQ3NELEtBQXpEO0FBNENEO0FBQ0YsQ0EvRkQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBHcmFwaFFMTm9uTnVsbCB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgZnJvbUdsb2JhbElkIH0gZnJvbSAnZ3JhcGhxbC1yZWxheSc7XG5pbXBvcnQgZ2V0RmllbGROYW1lcyBmcm9tICdncmFwaHFsLWxpc3QtZmllbGRzJztcbmltcG9ydCBwbHVyYWxpemUgZnJvbSAncGx1cmFsaXplJztcbmltcG9ydCAqIGFzIGRlZmF1bHRHcmFwaFFMVHlwZXMgZnJvbSAnLi9kZWZhdWx0R3JhcGhRTFR5cGVzJztcbmltcG9ydCAqIGFzIG9iamVjdHNRdWVyaWVzIGZyb20gJy4uL2hlbHBlcnMvb2JqZWN0c1F1ZXJpZXMnO1xuaW1wb3J0IHsgUGFyc2VHcmFwaFFMQ2xhc3NDb25maWcgfSBmcm9tICcuLi8uLi9Db250cm9sbGVycy9QYXJzZUdyYXBoUUxDb250cm9sbGVyJztcbmltcG9ydCB7IHRyYW5zZm9ybUNsYXNzTmFtZVRvR3JhcGhRTCB9IGZyb20gJy4uL3RyYW5zZm9ybWVycy9jbGFzc05hbWUnO1xuaW1wb3J0IHsgZXh0cmFjdEtleXNBbmRJbmNsdWRlIH0gZnJvbSAnLi4vcGFyc2VHcmFwaFFMVXRpbHMnO1xuXG5jb25zdCBnZXRQYXJzZUNsYXNzUXVlcnlDb25maWcgPSBmdW5jdGlvbiAocGFyc2VDbGFzc0NvbmZpZzogP1BhcnNlR3JhcGhRTENsYXNzQ29uZmlnKSB7XG4gIHJldHVybiAocGFyc2VDbGFzc0NvbmZpZyAmJiBwYXJzZUNsYXNzQ29uZmlnLnF1ZXJ5KSB8fCB7fTtcbn07XG5cbmNvbnN0IGdldFF1ZXJ5ID0gYXN5bmMgKHBhcnNlQ2xhc3MsIF9zb3VyY2UsIGFyZ3MsIGNvbnRleHQsIHF1ZXJ5SW5mbywgcGFyc2VDbGFzc2VzKSA9PiB7XG4gIGxldCB7IGlkIH0gPSBhcmdzO1xuICBjb25zdCB7IG9wdGlvbnMgfSA9IGFyZ3M7XG4gIGNvbnN0IHsgcmVhZFByZWZlcmVuY2UsIGluY2x1ZGVSZWFkUHJlZmVyZW5jZSB9ID0gb3B0aW9ucyB8fCB7fTtcbiAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHNlbGVjdGVkRmllbGRzID0gZ2V0RmllbGROYW1lcyhxdWVyeUluZm8pO1xuXG4gIGNvbnN0IGdsb2JhbElkT2JqZWN0ID0gZnJvbUdsb2JhbElkKGlkKTtcblxuICBpZiAoZ2xvYmFsSWRPYmplY3QudHlwZSA9PT0gcGFyc2VDbGFzcy5jbGFzc05hbWUpIHtcbiAgICBpZCA9IGdsb2JhbElkT2JqZWN0LmlkO1xuICB9XG5cbiAgY29uc3QgeyBrZXlzLCBpbmNsdWRlIH0gPSBleHRyYWN0S2V5c0FuZEluY2x1ZGUoc2VsZWN0ZWRGaWVsZHMpO1xuXG4gIHJldHVybiBhd2FpdCBvYmplY3RzUXVlcmllcy5nZXRPYmplY3QoXG4gICAgcGFyc2VDbGFzcy5jbGFzc05hbWUsXG4gICAgaWQsXG4gICAga2V5cyxcbiAgICBpbmNsdWRlLFxuICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgIGluY2x1ZGVSZWFkUHJlZmVyZW5jZSxcbiAgICBjb25maWcsXG4gICAgYXV0aCxcbiAgICBpbmZvLFxuICAgIHBhcnNlQ2xhc3Nlc1xuICApO1xufTtcblxuY29uc3QgbG9hZCA9IGZ1bmN0aW9uIChwYXJzZUdyYXBoUUxTY2hlbWEsIHBhcnNlQ2xhc3MsIHBhcnNlQ2xhc3NDb25maWc6ID9QYXJzZUdyYXBoUUxDbGFzc0NvbmZpZykge1xuICBjb25zdCBjbGFzc05hbWUgPSBwYXJzZUNsYXNzLmNsYXNzTmFtZTtcbiAgY29uc3QgZ3JhcGhRTENsYXNzTmFtZSA9IHRyYW5zZm9ybUNsYXNzTmFtZVRvR3JhcGhRTChjbGFzc05hbWUpO1xuICBjb25zdCB7XG4gICAgZ2V0OiBpc0dldEVuYWJsZWQgPSB0cnVlLFxuICAgIGZpbmQ6IGlzRmluZEVuYWJsZWQgPSB0cnVlLFxuICAgIGdldEFsaWFzOiBnZXRBbGlhcyA9ICcnLFxuICAgIGZpbmRBbGlhczogZmluZEFsaWFzID0gJycsXG4gIH0gPSBnZXRQYXJzZUNsYXNzUXVlcnlDb25maWcocGFyc2VDbGFzc0NvbmZpZyk7XG5cbiAgY29uc3Qge1xuICAgIGNsYXNzR3JhcGhRTE91dHB1dFR5cGUsXG4gICAgY2xhc3NHcmFwaFFMRmluZEFyZ3MsXG4gICAgY2xhc3NHcmFwaFFMRmluZFJlc3VsdFR5cGUsXG4gIH0gPSBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzW2NsYXNzTmFtZV07XG5cbiAgaWYgKGlzR2V0RW5hYmxlZCkge1xuICAgIGNvbnN0IGxvd2VyQ2FzZUNsYXNzTmFtZSA9IGdyYXBoUUxDbGFzc05hbWUuY2hhckF0KDApLnRvTG93ZXJDYXNlKCkgKyBncmFwaFFMQ2xhc3NOYW1lLnNsaWNlKDEpO1xuXG4gICAgY29uc3QgZ2V0R3JhcGhRTFF1ZXJ5TmFtZSA9IGdldEFsaWFzIHx8IGxvd2VyQ2FzZUNsYXNzTmFtZTtcblxuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMUXVlcnkoZ2V0R3JhcGhRTFF1ZXJ5TmFtZSwge1xuICAgICAgZGVzY3JpcHRpb246IGBUaGUgJHtnZXRHcmFwaFFMUXVlcnlOYW1lfSBxdWVyeSBjYW4gYmUgdXNlZCB0byBnZXQgYW4gb2JqZWN0IG9mIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzIGJ5IGl0cyBpZC5gLFxuICAgICAgYXJnczoge1xuICAgICAgICBpZDogZGVmYXVsdEdyYXBoUUxUeXBlcy5HTE9CQUxfT1JfT0JKRUNUX0lEX0FUVCxcbiAgICAgICAgb3B0aW9uczogZGVmYXVsdEdyYXBoUUxUeXBlcy5SRUFEX09QVElPTlNfQVRULFxuICAgICAgfSxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIHx8IGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUKSxcbiAgICAgIGFzeW5jIHJlc29sdmUoX3NvdXJjZSwgYXJncywgY29udGV4dCwgcXVlcnlJbmZvKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IGdldFF1ZXJ5KFxuICAgICAgICAgICAgcGFyc2VDbGFzcyxcbiAgICAgICAgICAgIF9zb3VyY2UsXG4gICAgICAgICAgICBhcmdzLFxuICAgICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICAgIHF1ZXJ5SW5mbyxcbiAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzZXNcbiAgICAgICAgICApO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgaWYgKGlzRmluZEVuYWJsZWQpIHtcbiAgICBjb25zdCBsb3dlckNhc2VDbGFzc05hbWUgPSBncmFwaFFMQ2xhc3NOYW1lLmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpICsgZ3JhcGhRTENsYXNzTmFtZS5zbGljZSgxKTtcblxuICAgIGNvbnN0IGZpbmRHcmFwaFFMUXVlcnlOYW1lID0gZmluZEFsaWFzIHx8IHBsdXJhbGl6ZShsb3dlckNhc2VDbGFzc05hbWUpO1xuXG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxRdWVyeShmaW5kR3JhcGhRTFF1ZXJ5TmFtZSwge1xuICAgICAgZGVzY3JpcHRpb246IGBUaGUgJHtmaW5kR3JhcGhRTFF1ZXJ5TmFtZX0gcXVlcnkgY2FuIGJlIHVzZWQgdG8gZmluZCBvYmplY3RzIG9mIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLmAsXG4gICAgICBhcmdzOiBjbGFzc0dyYXBoUUxGaW5kQXJncyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxGaW5kUmVzdWx0VHlwZSB8fCBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVCksXG4gICAgICBhc3luYyByZXNvbHZlKF9zb3VyY2UsIGFyZ3MsIGNvbnRleHQsIHF1ZXJ5SW5mbykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHsgd2hlcmUsIG9yZGVyLCBza2lwLCBmaXJzdCwgYWZ0ZXIsIGxhc3QsIGJlZm9yZSwgb3B0aW9ucyB9ID0gYXJncztcbiAgICAgICAgICBjb25zdCB7IHJlYWRQcmVmZXJlbmNlLCBpbmNsdWRlUmVhZFByZWZlcmVuY2UsIHN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UgfSA9IG9wdGlvbnMgfHwge307XG4gICAgICAgICAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG4gICAgICAgICAgY29uc3Qgc2VsZWN0ZWRGaWVsZHMgPSBnZXRGaWVsZE5hbWVzKHF1ZXJ5SW5mbyk7XG5cbiAgICAgICAgICBjb25zdCB7IGtleXMsIGluY2x1ZGUgfSA9IGV4dHJhY3RLZXlzQW5kSW5jbHVkZShcbiAgICAgICAgICAgIHNlbGVjdGVkRmllbGRzXG4gICAgICAgICAgICAgIC5maWx0ZXIoZmllbGQgPT4gZmllbGQuc3RhcnRzV2l0aCgnZWRnZXMubm9kZS4nKSlcbiAgICAgICAgICAgICAgLm1hcChmaWVsZCA9PiBmaWVsZC5yZXBsYWNlKCdlZGdlcy5ub2RlLicsICcnKSlcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IHBhcnNlT3JkZXIgPSBvcmRlciAmJiBvcmRlci5qb2luKCcsJyk7XG5cbiAgICAgICAgICByZXR1cm4gYXdhaXQgb2JqZWN0c1F1ZXJpZXMuZmluZE9iamVjdHMoXG4gICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICB3aGVyZSxcbiAgICAgICAgICAgIHBhcnNlT3JkZXIsXG4gICAgICAgICAgICBza2lwLFxuICAgICAgICAgICAgZmlyc3QsXG4gICAgICAgICAgICBhZnRlcixcbiAgICAgICAgICAgIGxhc3QsXG4gICAgICAgICAgICBiZWZvcmUsXG4gICAgICAgICAgICBrZXlzLFxuICAgICAgICAgICAgaW5jbHVkZSxcbiAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICBpbmNsdWRlUmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICBzdWJxdWVyeVJlYWRQcmVmZXJlbmNlLFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgIGluZm8sXG4gICAgICAgICAgICBzZWxlY3RlZEZpZWxkcyxcbiAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzZXNcbiAgICAgICAgICApO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG59O1xuXG5leHBvcnQgeyBsb2FkIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/loaders/parseClassTypes.js b/lib/GraphQL/loaders/parseClassTypes.js new file mode 100644 index 0000000000..33e7bf5ea1 --- /dev/null +++ b/lib/GraphQL/loaders/parseClassTypes.js @@ -0,0 +1,531 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +Object.defineProperty(exports, "extractKeysAndInclude", { + enumerable: true, + get: function () { + return _parseGraphQLUtils.extractKeysAndInclude; + } +}); +exports.load = void 0; + +var _graphql = require("graphql"); + +var _graphqlRelay = require("graphql-relay"); + +var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); + +var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); + +var objectsQueries = _interopRequireWildcard(require("../helpers/objectsQueries")); + +var _ParseGraphQLController = require("../../Controllers/ParseGraphQLController"); + +var _className = require("../transformers/className"); + +var _inputType = require("../transformers/inputType"); + +var _outputType = require("../transformers/outputType"); + +var _constraintType = require("../transformers/constraintType"); + +var _parseGraphQLUtils = require("../parseGraphQLUtils"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const getParseClassTypeConfig = function (parseClassConfig) { + return parseClassConfig && parseClassConfig.type || {}; +}; + +const getInputFieldsAndConstraints = function (parseClass, parseClassConfig) { + const classFields = Object.keys(parseClass.fields).concat('id'); + const { + inputFields: allowedInputFields, + outputFields: allowedOutputFields, + constraintFields: allowedConstraintFields, + sortFields: allowedSortFields + } = getParseClassTypeConfig(parseClassConfig); + let classOutputFields; + let classCreateFields; + let classUpdateFields; + let classConstraintFields; + let classSortFields; // All allowed customs fields + + const classCustomFields = classFields.filter(field => { + return !Object.keys(defaultGraphQLTypes.PARSE_OBJECT_FIELDS).includes(field) && field !== 'id'; + }); + + if (allowedInputFields && allowedInputFields.create) { + classCreateFields = classCustomFields.filter(field => { + return allowedInputFields.create.includes(field); + }); + } else { + classCreateFields = classCustomFields; + } + + if (allowedInputFields && allowedInputFields.update) { + classUpdateFields = classCustomFields.filter(field => { + return allowedInputFields.update.includes(field); + }); + } else { + classUpdateFields = classCustomFields; + } + + if (allowedOutputFields) { + classOutputFields = classCustomFields.filter(field => { + return allowedOutputFields.includes(field); + }); + } else { + classOutputFields = classCustomFields; + } // Filters the "password" field from class _User + + + if (parseClass.className === '_User') { + classOutputFields = classOutputFields.filter(outputField => outputField !== 'password'); + } + + if (allowedConstraintFields) { + classConstraintFields = classCustomFields.filter(field => { + return allowedConstraintFields.includes(field); + }); + } else { + classConstraintFields = classFields; + } + + if (allowedSortFields) { + classSortFields = allowedSortFields; + + if (!classSortFields.length) { + // must have at least 1 order field + // otherwise the FindArgs Input Type will throw. + classSortFields.push({ + field: 'id', + asc: true, + desc: true + }); + } + } else { + classSortFields = classFields.map(field => { + return { + field, + asc: true, + desc: true + }; + }); + } + + return { + classCreateFields, + classUpdateFields, + classConstraintFields, + classOutputFields, + classSortFields + }; +}; + +const load = (parseGraphQLSchema, parseClass, parseClassConfig) => { + const className = parseClass.className; + const graphQLClassName = (0, _className.transformClassNameToGraphQL)(className); + const { + classCreateFields, + classUpdateFields, + classOutputFields, + classConstraintFields, + classSortFields + } = getInputFieldsAndConstraints(parseClass, parseClassConfig); + const { + create: isCreateEnabled = true, + update: isUpdateEnabled = true + } = (0, _parseGraphQLUtils.getParseClassMutationConfig)(parseClassConfig); + const classGraphQLCreateTypeName = `Create${graphQLClassName}FieldsInput`; + let classGraphQLCreateType = new _graphql.GraphQLInputObjectType({ + name: classGraphQLCreateTypeName, + description: `The ${classGraphQLCreateTypeName} input type is used in operations that involve creation of objects in the ${graphQLClassName} class.`, + fields: () => classCreateFields.reduce((fields, field) => { + const type = (0, _inputType.transformInputTypeToGraphQL)(parseClass.fields[field].type, parseClass.fields[field].targetClass, parseGraphQLSchema.parseClassTypes); + + if (type) { + return _objectSpread(_objectSpread({}, fields), {}, { + [field]: { + description: `This is the object ${field}.`, + type: className === '_User' && (field === 'username' || field === 'password') || parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type + } + }); + } else { + return fields; + } + }, { + ACL: { + type: defaultGraphQLTypes.ACL_INPUT + } + }) + }); + classGraphQLCreateType = parseGraphQLSchema.addGraphQLType(classGraphQLCreateType); + const classGraphQLUpdateTypeName = `Update${graphQLClassName}FieldsInput`; + let classGraphQLUpdateType = new _graphql.GraphQLInputObjectType({ + name: classGraphQLUpdateTypeName, + description: `The ${classGraphQLUpdateTypeName} input type is used in operations that involve creation of objects in the ${graphQLClassName} class.`, + fields: () => classUpdateFields.reduce((fields, field) => { + const type = (0, _inputType.transformInputTypeToGraphQL)(parseClass.fields[field].type, parseClass.fields[field].targetClass, parseGraphQLSchema.parseClassTypes); + + if (type) { + return _objectSpread(_objectSpread({}, fields), {}, { + [field]: { + description: `This is the object ${field}.`, + type + } + }); + } else { + return fields; + } + }, { + ACL: { + type: defaultGraphQLTypes.ACL_INPUT + } + }) + }); + classGraphQLUpdateType = parseGraphQLSchema.addGraphQLType(classGraphQLUpdateType); + const classGraphQLPointerTypeName = `${graphQLClassName}PointerInput`; + let classGraphQLPointerType = new _graphql.GraphQLInputObjectType({ + name: classGraphQLPointerTypeName, + description: `Allow to link OR add and link an object of the ${graphQLClassName} class.`, + fields: () => { + const fields = { + link: { + description: `Link an existing object from ${graphQLClassName} class. You can use either the global or the object id.`, + type: _graphql.GraphQLID + } + }; + + if (isCreateEnabled) { + fields['createAndLink'] = { + description: `Create and link an object from ${graphQLClassName} class.`, + type: classGraphQLCreateType + }; + } + + return fields; + } + }); + classGraphQLPointerType = parseGraphQLSchema.addGraphQLType(classGraphQLPointerType) || defaultGraphQLTypes.OBJECT; + const classGraphQLRelationTypeName = `${graphQLClassName}RelationInput`; + let classGraphQLRelationType = new _graphql.GraphQLInputObjectType({ + name: classGraphQLRelationTypeName, + description: `Allow to add, remove, createAndAdd objects of the ${graphQLClassName} class into a relation field.`, + fields: () => { + const fields = { + add: { + description: `Add existing objects from the ${graphQLClassName} class into the relation. You can use either the global or the object ids.`, + type: new _graphql.GraphQLList(defaultGraphQLTypes.OBJECT_ID) + }, + remove: { + description: `Remove existing objects from the ${graphQLClassName} class out of the relation. You can use either the global or the object ids.`, + type: new _graphql.GraphQLList(defaultGraphQLTypes.OBJECT_ID) + } + }; + + if (isCreateEnabled) { + fields['createAndAdd'] = { + description: `Create and add objects of the ${graphQLClassName} class into the relation.`, + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLCreateType)) + }; + } + + return fields; + } + }); + classGraphQLRelationType = parseGraphQLSchema.addGraphQLType(classGraphQLRelationType) || defaultGraphQLTypes.OBJECT; + const classGraphQLConstraintsTypeName = `${graphQLClassName}WhereInput`; + let classGraphQLConstraintsType = new _graphql.GraphQLInputObjectType({ + name: classGraphQLConstraintsTypeName, + description: `The ${classGraphQLConstraintsTypeName} input type is used in operations that involve filtering objects of ${graphQLClassName} class.`, + fields: () => _objectSpread(_objectSpread({}, classConstraintFields.reduce((fields, field) => { + if (['OR', 'AND', 'NOR'].includes(field)) { + parseGraphQLSchema.log.warn(`Field ${field} could not be added to the auto schema ${classGraphQLConstraintsTypeName} because it collided with an existing one.`); + return fields; + } + + const parseField = field === 'id' ? 'objectId' : field; + const type = (0, _constraintType.transformConstraintTypeToGraphQL)(parseClass.fields[parseField].type, parseClass.fields[parseField].targetClass, parseGraphQLSchema.parseClassTypes, field); + + if (type) { + return _objectSpread(_objectSpread({}, fields), {}, { + [field]: { + description: `This is the object ${field}.`, + type + } + }); + } else { + return fields; + } + }, {})), {}, { + OR: { + description: 'This is the OR operator to compound constraints.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLConstraintsType)) + }, + AND: { + description: 'This is the AND operator to compound constraints.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLConstraintsType)) + }, + NOR: { + description: 'This is the NOR operator to compound constraints.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLConstraintsType)) + } + }) + }); + classGraphQLConstraintsType = parseGraphQLSchema.addGraphQLType(classGraphQLConstraintsType) || defaultGraphQLTypes.OBJECT; + const classGraphQLRelationConstraintsTypeName = `${graphQLClassName}RelationWhereInput`; + let classGraphQLRelationConstraintsType = new _graphql.GraphQLInputObjectType({ + name: classGraphQLRelationConstraintsTypeName, + description: `The ${classGraphQLRelationConstraintsTypeName} input type is used in operations that involve filtering objects of ${graphQLClassName} class.`, + fields: () => ({ + have: { + description: 'Run a relational/pointer query where at least one child object can match.', + type: classGraphQLConstraintsType + }, + haveNot: { + description: 'Run an inverted relational/pointer query where at least one child object can match.', + type: classGraphQLConstraintsType + }, + exists: { + description: 'Check if the relation/pointer contains objects.', + type: _graphql.GraphQLBoolean + } + }) + }); + classGraphQLRelationConstraintsType = parseGraphQLSchema.addGraphQLType(classGraphQLRelationConstraintsType) || defaultGraphQLTypes.OBJECT; + const classGraphQLOrderTypeName = `${graphQLClassName}Order`; + let classGraphQLOrderType = new _graphql.GraphQLEnumType({ + name: classGraphQLOrderTypeName, + description: `The ${classGraphQLOrderTypeName} input type is used when sorting objects of the ${graphQLClassName} class.`, + values: classSortFields.reduce((sortFields, fieldConfig) => { + const { + field, + asc, + desc + } = fieldConfig; + + const updatedSortFields = _objectSpread({}, sortFields); + + const value = field === 'id' ? 'objectId' : field; + + if (asc) { + updatedSortFields[`${field}_ASC`] = { + value + }; + } + + if (desc) { + updatedSortFields[`${field}_DESC`] = { + value: `-${value}` + }; + } + + return updatedSortFields; + }, {}) + }); + classGraphQLOrderType = parseGraphQLSchema.addGraphQLType(classGraphQLOrderType); + + const classGraphQLFindArgs = _objectSpread(_objectSpread({ + where: { + description: 'These are the conditions that the objects need to match in order to be found.', + type: classGraphQLConstraintsType + }, + order: { + description: 'The fields to be used when sorting the data fetched.', + type: classGraphQLOrderType ? new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLOrderType)) : _graphql.GraphQLString + }, + skip: defaultGraphQLTypes.SKIP_ATT + }, _graphqlRelay.connectionArgs), {}, { + options: defaultGraphQLTypes.READ_OPTIONS_ATT + }); + + const classGraphQLOutputTypeName = `${graphQLClassName}`; + const interfaces = [defaultGraphQLTypes.PARSE_OBJECT, parseGraphQLSchema.relayNodeInterface]; + + const parseObjectFields = _objectSpread({ + id: (0, _graphqlRelay.globalIdField)(className, obj => obj.objectId) + }, defaultGraphQLTypes.PARSE_OBJECT_FIELDS); + + const outputFields = () => { + return classOutputFields.reduce((fields, field) => { + const type = (0, _outputType.transformOutputTypeToGraphQL)(parseClass.fields[field].type, parseClass.fields[field].targetClass, parseGraphQLSchema.parseClassTypes); + + if (parseClass.fields[field].type === 'Relation') { + const targetParseClassTypes = parseGraphQLSchema.parseClassTypes[parseClass.fields[field].targetClass]; + const args = targetParseClassTypes ? targetParseClassTypes.classGraphQLFindArgs : undefined; + return _objectSpread(_objectSpread({}, fields), {}, { + [field]: { + description: `This is the object ${field}.`, + args, + type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type, + + async resolve(source, args, context, queryInfo) { + try { + const { + where, + order, + skip, + first, + after, + last, + before, + options + } = args; + const { + readPreference, + includeReadPreference, + subqueryReadPreference + } = options || {}; + const { + config, + auth, + info + } = context; + const selectedFields = (0, _graphqlListFields.default)(queryInfo); + const { + keys, + include + } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields.filter(field => field.startsWith('edges.node.')).map(field => field.replace('edges.node.', ''))); + const parseOrder = order && order.join(','); + return objectsQueries.findObjects(source[field].className, _objectSpread({ + $relatedTo: { + object: { + __type: 'Pointer', + className: className, + objectId: source.objectId + }, + key: field + } + }, where || {}), parseOrder, skip, first, after, last, before, keys, include, false, readPreference, includeReadPreference, subqueryReadPreference, config, auth, info, selectedFields, parseGraphQLSchema.parseClasses); + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + + } + }); + } else if (parseClass.fields[field].type === 'Polygon') { + return _objectSpread(_objectSpread({}, fields), {}, { + [field]: { + description: `This is the object ${field}.`, + type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type, + + async resolve(source) { + if (source[field] && source[field].coordinates) { + return source[field].coordinates.map(coordinate => ({ + latitude: coordinate[0], + longitude: coordinate[1] + })); + } else { + return null; + } + } + + } + }); + } else if (parseClass.fields[field].type === 'Array') { + return _objectSpread(_objectSpread({}, fields), {}, { + [field]: { + description: `Use Inline Fragment on Array to get results: https://graphql.org/learn/queries/#inline-fragments`, + type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type, + + async resolve(source) { + if (!source[field]) return null; + return source[field].map(async elem => { + if (elem.className && elem.objectId && elem.__type === 'Object') { + return elem; + } else { + return { + value: elem + }; + } + }); + } + + } + }); + } else if (type) { + return _objectSpread(_objectSpread({}, fields), {}, { + [field]: { + description: `This is the object ${field}.`, + type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type + } + }); + } else { + return fields; + } + }, parseObjectFields); + }; + + let classGraphQLOutputType = new _graphql.GraphQLObjectType({ + name: classGraphQLOutputTypeName, + description: `The ${classGraphQLOutputTypeName} object type is used in operations that involve outputting objects of ${graphQLClassName} class.`, + interfaces, + fields: outputFields + }); + classGraphQLOutputType = parseGraphQLSchema.addGraphQLType(classGraphQLOutputType); + const { + connectionType, + edgeType + } = (0, _graphqlRelay.connectionDefinitions)({ + name: graphQLClassName, + connectionFields: { + count: defaultGraphQLTypes.COUNT_ATT + }, + nodeType: classGraphQLOutputType || defaultGraphQLTypes.OBJECT + }); + let classGraphQLFindResultType = undefined; + + if (parseGraphQLSchema.addGraphQLType(edgeType) && parseGraphQLSchema.addGraphQLType(connectionType, false, false, true)) { + classGraphQLFindResultType = connectionType; + } + + parseGraphQLSchema.parseClassTypes[className] = { + classGraphQLPointerType, + classGraphQLRelationType, + classGraphQLCreateType, + classGraphQLUpdateType, + classGraphQLConstraintsType, + classGraphQLRelationConstraintsType, + classGraphQLFindArgs, + classGraphQLOutputType, + classGraphQLFindResultType, + config: { + parseClassConfig, + isCreateEnabled, + isUpdateEnabled + } + }; + + if (className === '_User') { + const viewerType = new _graphql.GraphQLObjectType({ + name: 'Viewer', + description: `The Viewer object type is used in operations that involve outputting the current user data.`, + fields: () => ({ + sessionToken: defaultGraphQLTypes.SESSION_TOKEN_ATT, + user: { + description: 'This is the current user.', + type: new _graphql.GraphQLNonNull(classGraphQLOutputType) + } + }) + }); + parseGraphQLSchema.addGraphQLType(viewerType, true, true); + parseGraphQLSchema.viewerType = viewerType; + } +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvcGFyc2VDbGFzc1R5cGVzLmpzIl0sIm5hbWVzIjpbImdldFBhcnNlQ2xhc3NUeXBlQ29uZmlnIiwicGFyc2VDbGFzc0NvbmZpZyIsInR5cGUiLCJnZXRJbnB1dEZpZWxkc0FuZENvbnN0cmFpbnRzIiwicGFyc2VDbGFzcyIsImNsYXNzRmllbGRzIiwiT2JqZWN0Iiwia2V5cyIsImZpZWxkcyIsImNvbmNhdCIsImlucHV0RmllbGRzIiwiYWxsb3dlZElucHV0RmllbGRzIiwib3V0cHV0RmllbGRzIiwiYWxsb3dlZE91dHB1dEZpZWxkcyIsImNvbnN0cmFpbnRGaWVsZHMiLCJhbGxvd2VkQ29uc3RyYWludEZpZWxkcyIsInNvcnRGaWVsZHMiLCJhbGxvd2VkU29ydEZpZWxkcyIsImNsYXNzT3V0cHV0RmllbGRzIiwiY2xhc3NDcmVhdGVGaWVsZHMiLCJjbGFzc1VwZGF0ZUZpZWxkcyIsImNsYXNzQ29uc3RyYWludEZpZWxkcyIsImNsYXNzU29ydEZpZWxkcyIsImNsYXNzQ3VzdG9tRmllbGRzIiwiZmlsdGVyIiwiZmllbGQiLCJkZWZhdWx0R3JhcGhRTFR5cGVzIiwiUEFSU0VfT0JKRUNUX0ZJRUxEUyIsImluY2x1ZGVzIiwiY3JlYXRlIiwidXBkYXRlIiwiY2xhc3NOYW1lIiwib3V0cHV0RmllbGQiLCJsZW5ndGgiLCJwdXNoIiwiYXNjIiwiZGVzYyIsIm1hcCIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJncmFwaFFMQ2xhc3NOYW1lIiwiaXNDcmVhdGVFbmFibGVkIiwiaXNVcGRhdGVFbmFibGVkIiwiY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZU5hbWUiLCJjbGFzc0dyYXBoUUxDcmVhdGVUeXBlIiwiR3JhcGhRTElucHV0T2JqZWN0VHlwZSIsIm5hbWUiLCJkZXNjcmlwdGlvbiIsInJlZHVjZSIsInRhcmdldENsYXNzIiwicGFyc2VDbGFzc1R5cGVzIiwicmVxdWlyZWQiLCJHcmFwaFFMTm9uTnVsbCIsIkFDTCIsIkFDTF9JTlBVVCIsImFkZEdyYXBoUUxUeXBlIiwiY2xhc3NHcmFwaFFMVXBkYXRlVHlwZU5hbWUiLCJjbGFzc0dyYXBoUUxVcGRhdGVUeXBlIiwiY2xhc3NHcmFwaFFMUG9pbnRlclR5cGVOYW1lIiwiY2xhc3NHcmFwaFFMUG9pbnRlclR5cGUiLCJsaW5rIiwiR3JhcGhRTElEIiwiT0JKRUNUIiwiY2xhc3NHcmFwaFFMUmVsYXRpb25UeXBlTmFtZSIsImNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZSIsImFkZCIsIkdyYXBoUUxMaXN0IiwiT0JKRUNUX0lEIiwicmVtb3ZlIiwiY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlTmFtZSIsImNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSIsImxvZyIsIndhcm4iLCJwYXJzZUZpZWxkIiwiT1IiLCJBTkQiLCJOT1IiLCJjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZU5hbWUiLCJjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZSIsImhhdmUiLCJoYXZlTm90IiwiZXhpc3RzIiwiR3JhcGhRTEJvb2xlYW4iLCJjbGFzc0dyYXBoUUxPcmRlclR5cGVOYW1lIiwiY2xhc3NHcmFwaFFMT3JkZXJUeXBlIiwiR3JhcGhRTEVudW1UeXBlIiwidmFsdWVzIiwiZmllbGRDb25maWciLCJ1cGRhdGVkU29ydEZpZWxkcyIsInZhbHVlIiwiY2xhc3NHcmFwaFFMRmluZEFyZ3MiLCJ3aGVyZSIsIm9yZGVyIiwiR3JhcGhRTFN0cmluZyIsInNraXAiLCJTS0lQX0FUVCIsImNvbm5lY3Rpb25BcmdzIiwib3B0aW9ucyIsIlJFQURfT1BUSU9OU19BVFQiLCJjbGFzc0dyYXBoUUxPdXRwdXRUeXBlTmFtZSIsImludGVyZmFjZXMiLCJQQVJTRV9PQkpFQ1QiLCJyZWxheU5vZGVJbnRlcmZhY2UiLCJwYXJzZU9iamVjdEZpZWxkcyIsImlkIiwib2JqIiwib2JqZWN0SWQiLCJ0YXJnZXRQYXJzZUNsYXNzVHlwZXMiLCJhcmdzIiwidW5kZWZpbmVkIiwicmVzb2x2ZSIsInNvdXJjZSIsImNvbnRleHQiLCJxdWVyeUluZm8iLCJmaXJzdCIsImFmdGVyIiwibGFzdCIsImJlZm9yZSIsInJlYWRQcmVmZXJlbmNlIiwiaW5jbHVkZVJlYWRQcmVmZXJlbmNlIiwic3VicXVlcnlSZWFkUHJlZmVyZW5jZSIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwic2VsZWN0ZWRGaWVsZHMiLCJpbmNsdWRlIiwic3RhcnRzV2l0aCIsInJlcGxhY2UiLCJwYXJzZU9yZGVyIiwiam9pbiIsIm9iamVjdHNRdWVyaWVzIiwiZmluZE9iamVjdHMiLCIkcmVsYXRlZFRvIiwib2JqZWN0IiwiX190eXBlIiwia2V5IiwicGFyc2VDbGFzc2VzIiwiZSIsImhhbmRsZUVycm9yIiwiY29vcmRpbmF0ZXMiLCJjb29yZGluYXRlIiwibGF0aXR1ZGUiLCJsb25naXR1ZGUiLCJlbGVtIiwiY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSIsIkdyYXBoUUxPYmplY3RUeXBlIiwiY29ubmVjdGlvblR5cGUiLCJlZGdlVHlwZSIsImNvbm5lY3Rpb25GaWVsZHMiLCJjb3VudCIsIkNPVU5UX0FUVCIsIm5vZGVUeXBlIiwiY2xhc3NHcmFwaFFMRmluZFJlc3VsdFR5cGUiLCJ2aWV3ZXJUeXBlIiwic2Vzc2lvblRva2VuIiwiU0VTU0lPTl9UT0tFTl9BVFQiLCJ1c2VyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBQUE7O0FBVUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FBRUEsTUFBTUEsdUJBQXVCLEdBQUcsVUFBVUMsZ0JBQVYsRUFBc0Q7QUFDcEYsU0FBUUEsZ0JBQWdCLElBQUlBLGdCQUFnQixDQUFDQyxJQUF0QyxJQUErQyxFQUF0RDtBQUNELENBRkQ7O0FBSUEsTUFBTUMsNEJBQTRCLEdBQUcsVUFDbkNDLFVBRG1DLEVBRW5DSCxnQkFGbUMsRUFHbkM7QUFDQSxRQUFNSSxXQUFXLEdBQUdDLE1BQU0s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QixDQUFDVyxlQUFuQixDQUFtQ25CLFNBQW5DLElBQWdEO0FBQzlDNEIsSUFBQUEsdUJBRDhDO0FBRTlDSyxJQUFBQSx3QkFGOEM7QUFHOUNwQixJQUFBQSxzQkFIOEM7QUFJOUNhLElBQUFBLHNCQUo4QztBQUs5Q2EsSUFBQUEsMkJBTDhDO0FBTTlDUSxJQUFBQSxtQ0FOOEM7QUFPOUNZLElBQUFBLG9CQVA4QztBQVE5Q3NELElBQUFBLHNCQVI4QztBQVM5Q1EsSUFBQUEsMEJBVDhDO0FBVTlDL0IsSUFBQUEsTUFBTSxFQUFFO0FBQ054SCxNQUFBQSxnQkFETTtBQUVOd0MsTUFBQUEsZUFGTTtBQUdOQyxNQUFBQTtBQUhNO0FBVnNDLEdBQWhEOztBQWlCQSxNQUFJWCxTQUFTLEtBQUssT0FBbEIsRUFBMkI7QUFDekIsVUFBTTBILFVBQVUsR0FBRyxJQUFJUiwwQkFBSixDQUFzQjtBQUN2Q25HLE1BQUFBLElBQUksRUFBRSxRQURpQztBQUV2Q0MsTUFBQUEsV0FBVyxFQUFHLDZGQUZ5QjtBQUd2Q3ZDLE1BQUFBLE1BQU0sRUFBRSxPQUFPO0FBQ2JrSixRQUFBQSxZQUFZLEVBQUVoSSxtQkFBbUIsQ0FBQ2lJLGlCQURyQjtBQUViQyxRQUFBQSxJQUFJLEVBQUU7QUFDSjdHLFVBQUFBLFdBQVcsRUFBRSwyQkFEVDtBQUVKN0MsVUFBQUEsSUFBSSxFQUFFLElBQUlrRCx1QkFBSixDQUFtQjRGLHNCQUFuQjtBQUZGO0FBRk8sT0FBUDtBQUgrQixLQUF0QixDQUFuQjtBQVdBekcsSUFBQUEsa0JBQWtCLENBQUNnQixjQUFuQixDQUFrQ2tHLFVBQWxDLEVBQThDLElBQTlDLEVBQW9ELElBQXBEO0FBQ0FsSCxJQUFBQSxrQkFBa0IsQ0FBQ2tILFVBQW5CLEdBQWdDQSxVQUFoQztBQUNEO0FBQ0YsQ0FuYUQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBHcmFwaFFMSUQsXG4gIEdyYXBoUUxPYmplY3RUeXBlLFxuICBHcmFwaFFMU3RyaW5nLFxuICBHcmFwaFFMTGlzdCxcbiAgR3JhcGhRTElucHV0T2JqZWN0VHlwZSxcbiAgR3JhcGhRTE5vbk51bGwsXG4gIEdyYXBoUUxCb29sZWFuLFxuICBHcmFwaFFMRW51bVR5cGUsXG59IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgZ2xvYmFsSWRGaWVsZCwgY29ubmVjdGlvbkFyZ3MsIGNvbm5lY3Rpb25EZWZpbml0aW9ucyB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0IGdldEZpZWxkTmFtZXMgZnJvbSAnZ3JhcGhxbC1saXN0LWZpZWxkcyc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4vZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQgKiBhcyBvYmplY3RzUXVlcmllcyBmcm9tICcuLi9oZWxwZXJzL29iamVjdHNRdWVyaWVzJztcbmltcG9ydCB7IFBhcnNlR3JhcGhRTENsYXNzQ29uZmlnIH0gZnJvbSAnLi4vLi4vQ29udHJvbGxlcnMvUGFyc2VHcmFwaFFMQ29udHJvbGxlcic7XG5pbXBvcnQgeyB0cmFuc2Zvcm1DbGFzc05hbWVUb0dyYXBoUUwgfSBmcm9tICcuLi90cmFuc2Zvcm1lcnMvY2xhc3NOYW1lJztcbmltcG9ydCB7IHRyYW5zZm9ybUlucHV0VHlwZVRvR3JhcGhRTCB9IGZyb20gJy4uL3RyYW5zZm9ybWVycy9pbnB1dFR5cGUnO1xuaW1wb3J0IHsgdHJhbnNmb3JtT3V0cHV0VHlwZVRvR3JhcGhRTCB9IGZyb20gJy4uL3RyYW5zZm9ybWVycy9vdXRwdXRUeXBlJztcbmltcG9ydCB7IHRyYW5zZm9ybUNvbnN0cmFpbnRUeXBlVG9HcmFwaFFMIH0gZnJvbSAnLi4vdHJhbnNmb3JtZXJzL2NvbnN0cmFpbnRUeXBlJztcbmltcG9ydCB7IGV4dHJhY3RLZXlzQW5kSW5jbHVkZSwgZ2V0UGFyc2VDbGFzc011dGF0aW9uQ29uZmlnIH0gZnJvbSAnLi4vcGFyc2VHcmFwaFFMVXRpbHMnO1xuXG5jb25zdCBnZXRQYXJzZUNsYXNzVHlwZUNvbmZpZyA9IGZ1bmN0aW9uIChwYXJzZUNsYXNzQ29uZmlnOiA/UGFyc2VHcmFwaFFMQ2xhc3NDb25maWcpIHtcbiAgcmV0dXJuIChwYXJzZUNsYXNzQ29uZmlnICYmIHBhcnNlQ2xhc3NDb25maWcudHlwZSkgfHwge307XG59O1xuXG5jb25zdCBnZXRJbnB1dEZpZWxkc0FuZENvbnN0cmFpbnRzID0gZnVuY3Rpb24gKFxuICBwYXJzZUNsYXNzLFxuICBwYXJzZUNsYXNzQ29uZmlnOiA/UGFyc2VHcmFwaFFMQ2xhc3NDb25maWdcbikge1xuICBjb25zdCBjbGFzc0ZpZWxkcyA9IE9iamVjdC5rZXlzKHBhcnNlQ2xhc3MuZmllbGRzKS5jb25jYXQoJ2lkJyk7XG4gIGNvbnN0IHtcbiAgICBpbnB1dEZpZWxkczogYWxsb3dlZElucHV0RmllbGRzLFxuICAgIG91dHB1dEZpZWxkczogYWxsb3dlZE91dHB1dEZpZWxkcyxcbiAgICBjb25zdHJhaW50RmllbGRzOiBhbGxvd2VkQ29uc3RyYWludEZpZWxkcyxcbiAgICBzb3J0RmllbGRzOiBhbGxvd2VkU29ydEZpZWxkcyxcbiAgfSA9IGdldFBhcnNlQ2xhc3NUeXBlQ29uZmlnKHBhcnNlQ2xhc3NDb25maWcpO1xuXG4gIGxldCBjbGFzc091dHB1dEZpZWxkcztcbiAgbGV0IGNsYXNzQ3JlYXRlRmllbGRzO1xuICBsZXQgY2xhc3NVcGRhdGVGaWVsZHM7XG4gIGxldCBjbGFzc0NvbnN0cmFpbnRGaWVsZHM7XG4gIGxldCBjbGFzc1NvcnRGaWVsZHM7XG5cbiAgLy8gQWxsIGFsbG93ZWQgY3VzdG9tcyBmaWVsZHNcbiAgY29uc3QgY2xhc3NDdXN0b21GaWVsZHMgPSBjbGFzc0ZpZWxkcy5maWx0ZXIoZmllbGQgPT4ge1xuICAgIHJldHVybiAhT2JqZWN0LmtleXMoZGVmYXVsdEdyYXBoUUxUeXBlcy5QQVJTRV9PQkpFQ1RfRklFTERTKS5pbmNsdWRlcyhmaWVsZCkgJiYgZmllbGQgIT09ICdpZCc7XG4gIH0pO1xuXG4gIGlmIChhbGxvd2VkSW5wdXRGaWVsZHMgJiYgYWxsb3dlZElucHV0RmllbGRzLmNyZWF0ZSkge1xuICAgIGNsYXNzQ3JlYXRlRmllbGRzID0gY2xhc3NDdXN0b21GaWVsZHMuZmlsdGVyKGZpZWxkID0+IHtcbiAgICAgIHJldHVybiBhbGxvd2VkSW5wdXRGaWVsZHMuY3JlYXRlLmluY2x1ZGVzKGZpZWxkKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBjbGFzc0NyZWF0ZUZpZWxkcyA9IGNsYXNzQ3VzdG9tRmllbGRzO1xuICB9XG4gIGlmIChhbGxvd2VkSW5wdXRGaWVsZHMgJiYgYWxsb3dlZElucHV0RmllbGRzLnVwZGF0ZSkge1xuICAgIGNsYXNzVXBkYXRlRmllbGRzID0gY2xhc3NDdXN0b21GaWVsZHMuZmlsdGVyKGZpZWxkID0+IHtcbiAgICAgIHJldHVybiBhbGxvd2VkSW5wdXRGaWVsZHMudXBkYXRlLmluY2x1ZGVzKGZpZWxkKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBjbGFzc1VwZGF0ZUZpZWxkcyA9IGNsYXNzQ3VzdG9tRmllbGRzO1xuICB9XG5cbiAgaWYgKGFsbG93ZWRPdXRwdXRGaWVsZHMpIHtcbiAgICBjbGFzc091dHB1dEZpZWxkcyA9IGNsYXNzQ3VzdG9tRmllbGRzLmZpbHRlcihmaWVsZCA9PiB7XG4gICAgICByZXR1cm4gYWxsb3dlZE91dHB1dEZpZWxkcy5pbmNsdWRlcyhmaWVsZCk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgY2xhc3NPdXRwdXRGaWVsZHMgPSBjbGFzc0N1c3RvbUZpZWxkcztcbiAgfVxuICAvLyBGaWx0ZXJzIHRoZSBcInBhc3N3b3JkXCIgZmllbGQgZnJvbSBjbGFzcyBfVXNlclxuICBpZiAocGFyc2VDbGFzcy5jbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICBjbGFzc091dHB1dEZpZWxkcyA9IGNsYXNzT3V0cHV0RmllbGRzLmZpbHRlcihvdXRwdXRGaWVsZCA9PiBvdXRwdXRGaWVsZCAhPT0gJ3Bhc3N3b3JkJyk7XG4gIH1cblxuICBpZiAoYWxsb3dlZENvbnN0cmFpbnRGaWVsZHMpIHtcbiAgICBjbGFzc0NvbnN0cmFpbnRGaWVsZHMgPSBjbGFzc0N1c3RvbUZpZWxkcy5maWx0ZXIoZmllbGQgPT4ge1xuICAgICAgcmV0dXJuIGFsbG93ZWRDb25zdHJhaW50RmllbGRzLmluY2x1ZGVzKGZpZWxkKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBjbGFzc0NvbnN0cmFpbnRGaWVsZHMgPSBjbGFzc0ZpZWxkcztcbiAgfVxuXG4gIGlmIChhbGxvd2VkU29ydEZpZWxkcykge1xuICAgIGNsYXNzU29ydEZpZWxkcyA9IGFsbG93ZWRTb3J0RmllbGRzO1xuICAgIGlmICghY2xhc3NTb3J0RmllbGRzLmxlbmd0aCkge1xuICAgICAgLy8gbXVzdCBoYXZlIGF0IGxlYXN0IDEgb3JkZXIgZmllbGRcbiAgICAgIC8vIG90aGVyd2lzZSB0aGUgRmluZEFyZ3MgSW5wdXQgVHlwZSB3aWxsIHRocm93LlxuICAgICAgY2xhc3NTb3J0RmllbGRzLnB1c2goe1xuICAgICAgICBmaWVsZDogJ2lkJyxcbiAgICAgICAgYXNjOiB0cnVlLFxuICAgICAgICBkZXNjOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGNsYXNzU29ydEZpZWxkcyA9IGNsYXNzRmllbGRzLm1hcChmaWVsZCA9PiB7XG4gICAgICByZXR1cm4geyBmaWVsZCwgYXNjOiB0cnVlLCBkZXNjOiB0cnVlIH07XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGNsYXNzQ3JlYXRlRmllbGRzLFxuICAgIGNsYXNzVXBkYXRlRmllbGRzLFxuICAgIGNsYXNzQ29uc3RyYWludEZpZWxkcyxcbiAgICBjbGFzc091dHB1dEZpZWxkcyxcbiAgICBjbGFzc1NvcnRGaWVsZHMsXG4gIH07XG59O1xuXG5jb25zdCBsb2FkID0gKHBhcnNlR3JhcGhRTFNjaGVtYSwgcGFyc2VDbGFzcywgcGFyc2VDbGFzc0NvbmZpZzogP1BhcnNlR3JhcGhRTENsYXNzQ29uZmlnKSA9PiB7XG4gIGNvbnN0IGNsYXNzTmFtZSA9IHBhcnNlQ2xhc3MuY2xhc3NOYW1lO1xuICBjb25zdCBncmFwaFFMQ2xhc3NOYW1lID0gdHJhbnNmb3JtQ2xhc3NOYW1lVG9HcmFwaFFMKGNsYXNzTmFtZSk7XG4gIGNvbnN0IHtcbiAgICBjbGFzc0NyZWF0ZUZpZWxkcyxcbiAgICBjbGFzc1VwZGF0ZUZpZWxkcyxcbiAgICBjbGFzc091dHB1dEZpZWxkcyxcbiAgICBjbGFzc0NvbnN0cmFpbnRGaWVsZHMsXG4gICAgY2xhc3NTb3J0RmllbGRzLFxuICB9ID0gZ2V0SW5wdXRGaWVsZHNBbmRDb25zdHJhaW50cyhwYXJzZUNsYXNzLCBwYXJzZUNsYXNzQ29uZmlnKTtcblxuICBjb25zdCB7XG4gICAgY3JlYXRlOiBpc0NyZWF0ZUVuYWJsZWQgPSB0cnVlLFxuICAgIHVwZGF0ZTogaXNVcGRhdGVFbmFibGVkID0gdHJ1ZSxcbiAgfSA9IGdldFBhcnNlQ2xhc3NNdXRhdGlvbkNvbmZpZyhwYXJzZUNsYXNzQ29uZmlnKTtcblxuICBjb25zdCBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlTmFtZSA9IGBDcmVhdGUke2dyYXBoUUxDbGFzc05hbWV9RmllbGRzSW5wdXRgO1xuICBsZXQgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgICBuYW1lOiBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlTmFtZSxcbiAgICBkZXNjcmlwdGlvbjogYFRoZSAke2NsYXNzR3JhcGhRTENyZWF0ZVR5cGVOYW1lfSBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgY3JlYXRpb24gb2Ygb2JqZWN0cyBpbiB0aGUgJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgIGZpZWxkczogKCkgPT5cbiAgICAgIGNsYXNzQ3JlYXRlRmllbGRzLnJlZHVjZShcbiAgICAgICAgKGZpZWxkcywgZmllbGQpID0+IHtcbiAgICAgICAgICBjb25zdCB0eXBlID0gdHJhbnNmb3JtSW5wdXRUeXBlVG9HcmFwaFFMKFxuICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnR5cGUsXG4gICAgICAgICAgICBwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0udGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAodHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgLi4uZmllbGRzLFxuICAgICAgICAgICAgICBbZmllbGRdOiB7XG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IGBUaGlzIGlzIHRoZSBvYmplY3QgJHtmaWVsZH0uYCxcbiAgICAgICAgICAgICAgICB0eXBlOlxuICAgICAgICAgICAgICAgICAgKGNsYXNzTmFtZSA9PT0gJ19Vc2VyJyAmJiAoZmllbGQgPT09ICd1c2VybmFtZScgfHwgZmllbGQgPT09ICdwYXNzd29yZCcpKSB8fFxuICAgICAgICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgID8gbmV3IEdyYXBoUUxOb25OdWxsKHR5cGUpXG4gICAgICAgICAgICAgICAgICAgIDogdHlwZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmaWVsZHM7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgQUNMOiB7IHR5cGU6IGRlZmF1bHRHcmFwaFFMVHlwZXMuQUNMX0lOUFVUIH0sXG4gICAgICAgIH1cbiAgICAgICksXG4gIH0pO1xuICBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlID0gcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNsYXNzR3JhcGhRTENyZWF0ZVR5cGUpO1xuXG4gIGNvbnN0IGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGVOYW1lID0gYFVwZGF0ZSR7Z3JhcGhRTENsYXNzTmFtZX1GaWVsZHNJbnB1dGA7XG4gIGxldCBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICAgIG5hbWU6IGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGVOYW1lLFxuICAgIGRlc2NyaXB0aW9uOiBgVGhlICR7Y2xhc3NHcmFwaFFMVXBkYXRlVHlwZU5hbWV9IGlucHV0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBjcmVhdGlvbiBvZiBvYmplY3RzIGluIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLmAsXG4gICAgZmllbGRzOiAoKSA9PlxuICAgICAgY2xhc3NVcGRhdGVGaWVsZHMucmVkdWNlKFxuICAgICAgICAoZmllbGRzLCBmaWVsZCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHR5cGUgPSB0cmFuc2Zvcm1JbnB1dFR5cGVUb0dyYXBoUUwoXG4gICAgICAgICAgICBwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0udHlwZSxcbiAgICAgICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50YXJnZXRDbGFzcyxcbiAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzVHlwZXNcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmICh0eXBlKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAuLi5maWVsZHMsXG4gICAgICAgICAgICAgIFtmaWVsZF06IHtcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogYFRoaXMgaXMgdGhlIG9iamVjdCAke2ZpZWxkfS5gLFxuICAgICAgICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZmllbGRzO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIEFDTDogeyB0eXBlOiBkZWZhdWx0R3JhcGhRTFR5cGVzLkFDTF9JTlBVVCB9LFxuICAgICAgICB9XG4gICAgICApLFxuICB9KTtcbiAgY2xhc3NHcmFwaFFMVXBkYXRlVHlwZSA9IHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjbGFzc0dyYXBoUUxVcGRhdGVUeXBlKTtcblxuICBjb25zdCBjbGFzc0dyYXBoUUxQb2ludGVyVHlwZU5hbWUgPSBgJHtncmFwaFFMQ2xhc3NOYW1lfVBvaW50ZXJJbnB1dGA7XG4gIGxldCBjbGFzc0dyYXBoUUxQb2ludGVyVHlwZSA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgICBuYW1lOiBjbGFzc0dyYXBoUUxQb2ludGVyVHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBBbGxvdyB0byBsaW5rIE9SIGFkZCBhbmQgbGluayBhbiBvYmplY3Qgb2YgdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuYCxcbiAgICBmaWVsZHM6ICgpID0+IHtcbiAgICAgIGNvbnN0IGZpZWxkcyA9IHtcbiAgICAgICAgbGluazoge1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiBgTGluayBhbiBleGlzdGluZyBvYmplY3QgZnJvbSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLiBZb3UgY2FuIHVzZSBlaXRoZXIgdGhlIGdsb2JhbCBvciB0aGUgb2JqZWN0IGlkLmAsXG4gICAgICAgICAgdHlwZTogR3JhcGhRTElELFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGlmIChpc0NyZWF0ZUVuYWJsZWQpIHtcbiAgICAgICAgZmllbGRzWydjcmVhdGVBbmRMaW5rJ10gPSB7XG4gICAgICAgICAgZGVzY3JpcHRpb246IGBDcmVhdGUgYW5kIGxpbmsgYW4gb2JqZWN0IGZyb20gJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgICAgICAgIHR5cGU6IGNsYXNzR3JhcGhRTENyZWF0ZVR5cGUsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gZmllbGRzO1xuICAgIH0sXG4gIH0pO1xuICBjbGFzc0dyYXBoUUxQb2ludGVyVHlwZSA9XG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNsYXNzR3JhcGhRTFBvaW50ZXJUeXBlKSB8fCBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVDtcblxuICBjb25zdCBjbGFzc0dyYXBoUUxSZWxhdGlvblR5cGVOYW1lID0gYCR7Z3JhcGhRTENsYXNzTmFtZX1SZWxhdGlvbklucHV0YDtcbiAgbGV0IGNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZSA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgICBuYW1lOiBjbGFzc0dyYXBoUUxSZWxhdGlvblR5cGVOYW1lLFxuICAgIGRlc2NyaXB0aW9uOiBgQWxsb3cgdG8gYWRkLCByZW1vdmUsIGNyZWF0ZUFuZEFkZCBvYmplY3RzIG9mIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzIGludG8gYSByZWxhdGlvbiBmaWVsZC5gLFxuICAgIGZpZWxkczogKCkgPT4ge1xuICAgICAgY29uc3QgZmllbGRzID0ge1xuICAgICAgICBhZGQ6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogYEFkZCBleGlzdGluZyBvYmplY3RzIGZyb20gdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MgaW50byB0aGUgcmVsYXRpb24uIFlvdSBjYW4gdXNlIGVpdGhlciB0aGUgZ2xvYmFsIG9yIHRoZSBvYmplY3QgaWRzLmAsXG4gICAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUX0lEKSxcbiAgICAgICAgfSxcbiAgICAgICAgcmVtb3ZlOiB7XG4gICAgICAgICAgZGVzY3JpcHRpb246IGBSZW1vdmUgZXhpc3Rpbmcgb2JqZWN0cyBmcm9tIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzIG91dCBvZiB0aGUgcmVsYXRpb24uIFlvdSBjYW4gdXNlIGVpdGhlciB0aGUgZ2xvYmFsIG9yIHRoZSBvYmplY3QgaWRzLmAsXG4gICAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUX0lEKSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBpZiAoaXNDcmVhdGVFbmFibGVkKSB7XG4gICAgICAgIGZpZWxkc1snY3JlYXRlQW5kQWRkJ10gPSB7XG4gICAgICAgICAgZGVzY3JpcHRpb246IGBDcmVhdGUgYW5kIGFkZCBvYmplY3RzIG9mIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzIGludG8gdGhlIHJlbGF0aW9uLmAsXG4gICAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxDcmVhdGVUeXBlKSksXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gZmllbGRzO1xuICAgIH0sXG4gIH0pO1xuICBjbGFzc0dyYXBoUUxSZWxhdGlvblR5cGUgPVxuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjbGFzc0dyYXBoUUxSZWxhdGlvblR5cGUpIHx8IGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUO1xuXG4gIGNvbnN0IGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZU5hbWUgPSBgJHtncmFwaFFMQ2xhc3NOYW1lfVdoZXJlSW5wdXRgO1xuICBsZXQgY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICAgIG5hbWU6IGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBUaGUgJHtjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGVOYW1lfSBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIG9iamVjdHMgb2YgJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgIGZpZWxkczogKCkgPT4gKHtcbiAgICAgIC4uLmNsYXNzQ29uc3RyYWludEZpZWxkcy5yZWR1Y2UoKGZpZWxkcywgZmllbGQpID0+IHtcbiAgICAgICAgaWYgKFsnT1InLCAnQU5EJywgJ05PUiddLmluY2x1ZGVzKGZpZWxkKSkge1xuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5sb2cud2FybihcbiAgICAgICAgICAgIGBGaWVsZCAke2ZpZWxkfSBjb3VsZCBub3QgYmUgYWRkZWQgdG8gdGhlIGF1dG8gc2NoZW1hICR7Y2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlTmFtZX0gYmVjYXVzZSBpdCBjb2xsaWRlZCB3aXRoIGFuIGV4aXN0aW5nIG9uZS5gXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4gZmllbGRzO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhcnNlRmllbGQgPSBmaWVsZCA9PT0gJ2lkJyA/ICdvYmplY3RJZCcgOiBmaWVsZDtcbiAgICAgICAgY29uc3QgdHlwZSA9IHRyYW5zZm9ybUNvbnN0cmFpbnRUeXBlVG9HcmFwaFFMKFxuICAgICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzW3BhcnNlRmllbGRdLnR5cGUsXG4gICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbcGFyc2VGaWVsZF0udGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlcyxcbiAgICAgICAgICBmaWVsZFxuICAgICAgICApO1xuICAgICAgICBpZiAodHlwZSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5maWVsZHMsXG4gICAgICAgICAgICBbZmllbGRdOiB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgVGhpcyBpcyB0aGUgb2JqZWN0ICR7ZmllbGR9LmAsXG4gICAgICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGZpZWxkcztcbiAgICAgICAgfVxuICAgICAgfSwge30pLFxuICAgICAgT1I6IHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBPUiBvcGVyYXRvciB0byBjb21wb3VuZCBjb25zdHJhaW50cy4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSkpLFxuICAgICAgfSxcbiAgICAgIEFORDoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIEFORCBvcGVyYXRvciB0byBjb21wb3VuZCBjb25zdHJhaW50cy4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSkpLFxuICAgICAgfSxcbiAgICAgIE5PUjoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIE5PUiBvcGVyYXRvciB0byBjb21wb3VuZCBjb25zdHJhaW50cy4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSkpLFxuICAgICAgfSxcbiAgICB9KSxcbiAgfSk7XG4gIGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSA9XG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSkgfHwgZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1Q7XG5cbiAgY29uc3QgY2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGVOYW1lID0gYCR7Z3JhcGhRTENsYXNzTmFtZX1SZWxhdGlvbldoZXJlSW5wdXRgO1xuICBsZXQgY2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGUgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gICAgbmFtZTogY2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGVOYW1lLFxuICAgIGRlc2NyaXB0aW9uOiBgVGhlICR7Y2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGVOYW1lfSBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIG9iamVjdHMgb2YgJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgIGZpZWxkczogKCkgPT4gKHtcbiAgICAgIGhhdmU6IHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdSdW4gYSByZWxhdGlvbmFsL3BvaW50ZXIgcXVlcnkgd2hlcmUgYXQgbGVhc3Qgb25lIGNoaWxkIG9iamVjdCBjYW4gbWF0Y2guJyxcbiAgICAgICAgdHlwZTogY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlLFxuICAgICAgfSxcbiAgICAgIGhhdmVOb3Q6IHtcbiAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgJ1J1biBhbiBpbnZlcnRlZCByZWxhdGlvbmFsL3BvaW50ZXIgcXVlcnkgd2hlcmUgYXQgbGVhc3Qgb25lIGNoaWxkIG9iamVjdCBjYW4gbWF0Y2guJyxcbiAgICAgICAgdHlwZTogY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlLFxuICAgICAgfSxcbiAgICAgIGV4aXN0czoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ0NoZWNrIGlmIHRoZSByZWxhdGlvbi9wb2ludGVyIGNvbnRhaW5zIG9iamVjdHMuJyxcbiAgICAgICAgdHlwZTogR3JhcGhRTEJvb2xlYW4sXG4gICAgICB9LFxuICAgIH0pLFxuICB9KTtcbiAgY2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGUgPVxuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZSkgfHxcbiAgICBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVDtcblxuICBjb25zdCBjbGFzc0dyYXBoUUxPcmRlclR5cGVOYW1lID0gYCR7Z3JhcGhRTENsYXNzTmFtZX1PcmRlcmA7XG4gIGxldCBjbGFzc0dyYXBoUUxPcmRlclR5cGUgPSBuZXcgR3JhcGhRTEVudW1UeXBlKHtcbiAgICBuYW1lOiBjbGFzc0dyYXBoUUxPcmRlclR5cGVOYW1lLFxuICAgIGRlc2NyaXB0aW9uOiBgVGhlICR7Y2xhc3NHcmFwaFFMT3JkZXJUeXBlTmFtZX0gaW5wdXQgdHlwZSBpcyB1c2VkIHdoZW4gc29ydGluZyBvYmplY3RzIG9mIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLmAsXG4gICAgdmFsdWVzOiBjbGFzc1NvcnRGaWVsZHMucmVkdWNlKChzb3J0RmllbGRzLCBmaWVsZENvbmZpZykgPT4ge1xuICAgICAgY29uc3QgeyBmaWVsZCwgYXNjLCBkZXNjIH0gPSBmaWVsZENvbmZpZztcbiAgICAgIGNvbnN0IHVwZGF0ZWRTb3J0RmllbGRzID0ge1xuICAgICAgICAuLi5zb3J0RmllbGRzLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHZhbHVlID0gZmllbGQgPT09ICdpZCcgPyAnb2JqZWN0SWQnIDogZmllbGQ7XG4gICAgICBpZiAoYXNjKSB7XG4gICAgICAgIHVwZGF0ZWRTb3J0RmllbGRzW2Ake2ZpZWxkfV9BU0NgXSA9IHsgdmFsdWUgfTtcbiAgICAgIH1cbiAgICAgIGlmIChkZXNjKSB7XG4gICAgICAgIHVwZGF0ZWRTb3J0RmllbGRzW2Ake2ZpZWxkfV9ERVNDYF0gPSB7IHZhbHVlOiBgLSR7dmFsdWV9YCB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHVwZGF0ZWRTb3J0RmllbGRzO1xuICAgIH0sIHt9KSxcbiAgfSk7XG4gIGNsYXNzR3JhcGhRTE9yZGVyVHlwZSA9IHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjbGFzc0dyYXBoUUxPcmRlclR5cGUpO1xuXG4gIGNvbnN0IGNsYXNzR3JhcGhRTEZpbmRBcmdzID0ge1xuICAgIHdoZXJlOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZXNlIGFyZSB0aGUgY29uZGl0aW9ucyB0aGF0IHRoZSBvYmplY3RzIG5lZWQgdG8gbWF0Y2ggaW4gb3JkZXIgdG8gYmUgZm91bmQuJyxcbiAgICAgIHR5cGU6IGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSxcbiAgICB9LFxuICAgIG9yZGVyOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSBmaWVsZHMgdG8gYmUgdXNlZCB3aGVuIHNvcnRpbmcgdGhlIGRhdGEgZmV0Y2hlZC4nLFxuICAgICAgdHlwZTogY2xhc3NHcmFwaFFMT3JkZXJUeXBlXG4gICAgICAgID8gbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxPcmRlclR5cGUpKVxuICAgICAgICA6IEdyYXBoUUxTdHJpbmcsXG4gICAgfSxcbiAgICBza2lwOiBkZWZhdWx0R3JhcGhRTFR5cGVzLlNLSVBfQVRULFxuICAgIC4uLmNvbm5lY3Rpb25BcmdzLFxuICAgIG9wdGlvbnM6IGRlZmF1bHRHcmFwaFFMVHlwZXMuUkVBRF9PUFRJT05TX0FUVCxcbiAgfTtcbiAgY29uc3QgY2xhc3NHcmFwaFFMT3V0cHV0VHlwZU5hbWUgPSBgJHtncmFwaFFMQ2xhc3NOYW1lfWA7XG4gIGNvbnN0IGludGVyZmFjZXMgPSBbZGVmYXVsdEdyYXBoUUxUeXBlcy5QQVJTRV9PQkpFQ1QsIHBhcnNlR3JhcGhRTFNjaGVtYS5yZWxheU5vZGVJbnRlcmZhY2VdO1xuICBjb25zdCBwYXJzZU9iamVjdEZpZWxkcyA9IHtcbiAgICBpZDogZ2xvYmFsSWRGaWVsZChjbGFzc05hbWUsIG9iaiA9PiBvYmoub2JqZWN0SWQpLFxuICAgIC4uLmRlZmF1bHRHcmFwaFFMVHlwZXMuUEFSU0VfT0JKRUNUX0ZJRUxEUyxcbiAgfTtcbiAgY29uc3Qgb3V0cHV0RmllbGRzID0gKCkgPT4ge1xuICAgIHJldHVybiBjbGFzc091dHB1dEZpZWxkcy5yZWR1Y2UoKGZpZWxkcywgZmllbGQpID0+IHtcbiAgICAgIGNvbnN0IHR5cGUgPSB0cmFuc2Zvcm1PdXRwdXRUeXBlVG9HcmFwaFFMKFxuICAgICAgICBwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0udHlwZSxcbiAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnRhcmdldENsYXNzLFxuICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzXG4gICAgICApO1xuICAgICAgaWYgKHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIGNvbnN0IHRhcmdldFBhcnNlQ2xhc3NUeXBlcyA9XG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1twYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0udGFyZ2V0Q2xhc3NdO1xuICAgICAgICBjb25zdCBhcmdzID0gdGFyZ2V0UGFyc2VDbGFzc1R5cGVzID8gdGFyZ2V0UGFyc2VDbGFzc1R5cGVzLmNsYXNzR3JhcGhRTEZpbmRBcmdzIDogdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLmZpZWxkcyxcbiAgICAgICAgICBbZmllbGRdOiB7XG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogYFRoaXMgaXMgdGhlIG9iamVjdCAke2ZpZWxkfS5gLFxuICAgICAgICAgICAgYXJncyxcbiAgICAgICAgICAgIHR5cGU6IHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS5yZXF1aXJlZCA/IG5ldyBHcmFwaFFMTm9uTnVsbCh0eXBlKSA6IHR5cGUsXG4gICAgICAgICAgICBhc3luYyByZXNvbHZlKHNvdXJjZSwgYXJncywgY29udGV4dCwgcXVlcnlJbmZvKSB7XG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeyB3aGVyZSwgb3JkZXIsIHNraXAsIGZpcnN0LCBhZnRlciwgbGFzdCwgYmVmb3JlLCBvcHRpb25zIH0gPSBhcmdzO1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgcmVhZFByZWZlcmVuY2UsIGluY2x1ZGVSZWFkUHJlZmVyZW5jZSwgc3VicXVlcnlSZWFkUHJlZmVyZW5jZSB9ID1cbiAgICAgICAgICAgICAgICAgIG9wdGlvbnMgfHwge307XG4gICAgICAgICAgICAgICAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2VsZWN0ZWRGaWVsZHMgPSBnZXRGaWVsZE5hbWVzKHF1ZXJ5SW5mbyk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCB7IGtleXMsIGluY2x1ZGUgfSA9IGV4dHJhY3RLZXlzQW5kSW5jbHVkZShcbiAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRmllbGRzXG4gICAgICAgICAgICAgICAgICAgIC5maWx0ZXIoZmllbGQgPT4gZmllbGQuc3RhcnRzV2l0aCgnZWRnZXMubm9kZS4nKSlcbiAgICAgICAgICAgICAgICAgICAgLm1hcChmaWVsZCA9PiBmaWVsZC5yZXBsYWNlKCdlZGdlcy5ub2RlLicsICcnKSlcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlT3JkZXIgPSBvcmRlciAmJiBvcmRlci5qb2luKCcsJyk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0c1F1ZXJpZXMuZmluZE9iamVjdHMoXG4gICAgICAgICAgICAgICAgICBzb3VyY2VbZmllbGRdLmNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgJHJlbGF0ZWRUbzoge1xuICAgICAgICAgICAgICAgICAgICAgIG9iamVjdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdElkOiBzb3VyY2Uub2JqZWN0SWQsXG4gICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICBrZXk6IGZpZWxkLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAuLi4od2hlcmUgfHwge30pLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHBhcnNlT3JkZXIsXG4gICAgICAgICAgICAgICAgICBza2lwLFxuICAgICAgICAgICAgICAgICAgZmlyc3QsXG4gICAgICAgICAgICAgICAgICBhZnRlcixcbiAgICAgICAgICAgICAgICAgIGxhc3QsXG4gICAgICAgICAgICAgICAgICBiZWZvcmUsXG4gICAgICAgICAgICAgICAgICBrZXlzLFxuICAgICAgICAgICAgICAgICAgaW5jbHVkZSxcbiAgICAgICAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICAgICAgICBpbmNsdWRlUmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICAgICAgICBzdWJxdWVyeVJlYWRQcmVmZXJlbmNlLFxuICAgICAgICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgICAgICAgIGluZm8sXG4gICAgICAgICAgICAgICAgICBzZWxlY3RlZEZpZWxkcyxcbiAgICAgICAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzZXNcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9IGVsc2UgaWYgKHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnUG9seWdvbicpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5maWVsZHMsXG4gICAgICAgICAgW2ZpZWxkXToge1xuICAgICAgICAgICAgZGVzY3JpcHRpb246IGBUaGlzIGlzIHRoZSBvYmplY3QgJHtmaWVsZH0uYCxcbiAgICAgICAgICAgIHR5cGU6IHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS5yZXF1aXJlZCA/IG5ldyBHcmFwaFFMTm9uTnVsbCh0eXBlKSA6IHR5cGUsXG4gICAgICAgICAgICBhc3luYyByZXNvbHZlKHNvdXJjZSkge1xuICAgICAgICAgICAgICBpZiAoc291cmNlW2ZpZWxkXSAmJiBzb3VyY2VbZmllbGRdLmNvb3JkaW5hdGVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNvdXJjZVtmaWVsZF0uY29vcmRpbmF0ZXMubWFwKGNvb3JkaW5hdGUgPT4gKHtcbiAgICAgICAgICAgICAgICAgIGxhdGl0dWRlOiBjb29yZGluYXRlWzBdLFxuICAgICAgICAgICAgICAgICAgbG9uZ2l0dWRlOiBjb29yZGluYXRlWzFdLFxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIGlmIChwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0udHlwZSA9PT0gJ0FycmF5Jykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLmZpZWxkcyxcbiAgICAgICAgICBbZmllbGRdOiB7XG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogYFVzZSBJbmxpbmUgRnJhZ21lbnQgb24gQXJyYXkgdG8gZ2V0IHJlc3VsdHM6IGh0dHBzOi8vZ3JhcGhxbC5vcmcvbGVhcm4vcXVlcmllcy8jaW5saW5lLWZyYWdtZW50c2AsXG4gICAgICAgICAgICB0eXBlOiBwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0ucmVxdWlyZWQgPyBuZXcgR3JhcGhRTE5vbk51bGwodHlwZSkgOiB0eXBlLFxuICAgICAgICAgICAgYXN5bmMgcmVzb2x2ZShzb3VyY2UpIHtcbiAgICAgICAgICAgICAgaWYgKCFzb3VyY2VbZmllbGRdKSByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgcmV0dXJuIHNvdXJjZVtmaWVsZF0ubWFwKGFzeW5jIGVsZW0gPT4ge1xuICAgICAgICAgICAgICAgIGlmIChlbGVtLmNsYXNzTmFtZSAmJiBlbGVtLm9iamVjdElkICYmIGVsZW0uX190eXBlID09PSAnT2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGVsZW07XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBlbGVtIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLmZpZWxkcyxcbiAgICAgICAgICBbZmllbGRdOiB7XG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogYFRoaXMgaXMgdGhlIG9iamVjdCAke2ZpZWxkfS5gLFxuICAgICAgICAgICAgdHlwZTogcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnJlcXVpcmVkID8gbmV3IEdyYXBoUUxOb25OdWxsKHR5cGUpIDogdHlwZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZpZWxkcztcbiAgICAgIH1cbiAgICB9LCBwYXJzZU9iamVjdEZpZWxkcyk7XG4gIH07XG4gIGxldCBjbGFzc0dyYXBoUUxPdXRwdXRUeXBlID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgICBuYW1lOiBjbGFzc0dyYXBoUUxPdXRwdXRUeXBlTmFtZSxcbiAgICBkZXNjcmlwdGlvbjogYFRoZSAke2NsYXNzR3JhcGhRTE91dHB1dFR5cGVOYW1lfSBvYmplY3QgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIG91dHB1dHRpbmcgb2JqZWN0cyBvZiAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLmAsXG4gICAgaW50ZXJmYWNlcyxcbiAgICBmaWVsZHM6IG91dHB1dEZpZWxkcyxcbiAgfSk7XG4gIGNsYXNzR3JhcGhRTE91dHB1dFR5cGUgPSBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSk7XG5cbiAgY29uc3QgeyBjb25uZWN0aW9uVHlwZSwgZWRnZVR5cGUgfSA9IGNvbm5lY3Rpb25EZWZpbml0aW9ucyh7XG4gICAgbmFtZTogZ3JhcGhRTENsYXNzTmFtZSxcbiAgICBjb25uZWN0aW9uRmllbGRzOiB7XG4gICAgICBjb3VudDogZGVmYXVsdEdyYXBoUUxUeXBlcy5DT1VOVF9BVFQsXG4gICAgfSxcbiAgICBub2RlVHlwZTogY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSB8fCBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVCxcbiAgfSk7XG4gIGxldCBjbGFzc0dyYXBoUUxGaW5kUmVzdWx0VHlwZSA9IHVuZGVmaW5lZDtcbiAgaWYgKFxuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShlZGdlVHlwZSkgJiZcbiAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoY29ubmVjdGlvblR5cGUsIGZhbHNlLCBmYWxzZSwgdHJ1ZSlcbiAgKSB7XG4gICAgY2xhc3NHcmFwaFFMRmluZFJlc3VsdFR5cGUgPSBjb25uZWN0aW9uVHlwZTtcbiAgfVxuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzVHlwZXNbY2xhc3NOYW1lXSA9IHtcbiAgICBjbGFzc0dyYXBoUUxQb2ludGVyVHlwZSxcbiAgICBjbGFzc0dyYXBoUUxSZWxhdGlvblR5cGUsXG4gICAgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSxcbiAgICBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlLFxuICAgIGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSxcbiAgICBjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZSxcbiAgICBjbGFzc0dyYXBoUUxGaW5kQXJncyxcbiAgICBjbGFzc0dyYXBoUUxPdXRwdXRUeXBlLFxuICAgIGNsYXNzR3JhcGhRTEZpbmRSZXN1bHRUeXBlLFxuICAgIGNvbmZpZzoge1xuICAgICAgcGFyc2VDbGFzc0NvbmZpZyxcbiAgICAgIGlzQ3JlYXRlRW5hYmxlZCxcbiAgICAgIGlzVXBkYXRlRW5hYmxlZCxcbiAgICB9LFxuICB9O1xuXG4gIGlmIChjbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICBjb25zdCB2aWV3ZXJUeXBlID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgICAgIG5hbWU6ICdWaWV3ZXInLFxuICAgICAgZGVzY3JpcHRpb246IGBUaGUgVmlld2VyIG9iamVjdCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgb3V0cHV0dGluZyB0aGUgY3VycmVudCB1c2VyIGRhdGEuYCxcbiAgICAgIGZpZWxkczogKCkgPT4gKHtcbiAgICAgICAgc2Vzc2lvblRva2VuOiBkZWZhdWx0R3JhcGhRTFR5cGVzLlNFU1NJT05fVE9LRU5fQVRULFxuICAgICAgICB1c2VyOiB7XG4gICAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBjdXJyZW50IHVzZXIuJyxcbiAgICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSksXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICB9KTtcbiAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUodmlld2VyVHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLnZpZXdlclR5cGUgPSB2aWV3ZXJUeXBlO1xuICB9XG59O1xuXG5leHBvcnQgeyBleHRyYWN0S2V5c0FuZEluY2x1ZGUsIGxvYWQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/schemaDirectives.js b/lib/GraphQL/loaders/schemaDirectives.js new file mode 100644 index 0000000000..a792079b0e --- /dev/null +++ b/lib/GraphQL/loaders/schemaDirectives.js @@ -0,0 +1,72 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = exports.definitions = void 0; + +var _graphqlTag = _interopRequireDefault(require("graphql-tag")); + +var _utils = require("@graphql-tools/utils"); + +var _FunctionsRouter = require("../../Routers/FunctionsRouter"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const definitions = (0, _graphqlTag.default)` + directive @resolve(to: String) on FIELD_DEFINITION + directive @mock(with: Any!) on FIELD_DEFINITION +`; +exports.definitions = definitions; + +const load = parseGraphQLSchema => { + parseGraphQLSchema.graphQLSchemaDirectivesDefinitions = definitions; + + class ResolveDirectiveVisitor extends _utils.SchemaDirectiveVisitor { + visitFieldDefinition(field) { + field.resolve = async (_source, args, context) => { + try { + const { + config, + auth, + info + } = context; + let functionName = field.name; + + if (this.args.to) { + functionName = this.args.to; + } + + return (await _FunctionsRouter.FunctionsRouter.handleCloudFunction({ + params: { + functionName + }, + config, + auth, + info, + body: args + })).response.result; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + }; + } + + } + + parseGraphQLSchema.graphQLSchemaDirectives.resolve = ResolveDirectiveVisitor; + + class MockDirectiveVisitor extends _utils.SchemaDirectiveVisitor { + visitFieldDefinition(field) { + field.resolve = () => { + return this.args.with; + }; + } + + } + + parseGraphQLSchema.graphQLSchemaDirectives.mock = MockDirectiveVisitor; +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvc2NoZW1hRGlyZWN0aXZlcy5qcyJdLCJuYW1lcyI6WyJkZWZpbml0aW9ucyIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJncmFwaFFMU2NoZW1hRGlyZWN0aXZlc0RlZmluaXRpb25zIiwiUmVzb2x2ZURpcmVjdGl2ZVZpc2l0b3IiLCJTY2hlbWFEaXJlY3RpdmVWaXNpdG9yIiwidmlzaXRGaWVsZERlZmluaXRpb24iLCJmaWVsZCIsInJlc29sdmUiLCJfc291cmNlIiwiYXJncyIsImNvbnRleHQiLCJjb25maWciLCJhdXRoIiwiaW5mbyIsImZ1bmN0aW9uTmFtZSIsIm5hbWUiLCJ0byIsIkZ1bmN0aW9uc1JvdXRlciIsImhhbmRsZUNsb3VkRnVuY3Rpb24iLCJwYXJhbXMiLCJib2R5IiwicmVzcG9uc2UiLCJyZXN1bHQiLCJlIiwiaGFuZGxlRXJyb3IiLCJncmFwaFFMU2NoZW1hRGlyZWN0aXZlcyIsIk1vY2tEaXJlY3RpdmVWaXNpdG9yIiwid2l0aCIsIm1vY2siXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7OztBQUVPLE1BQU1BLFdBQVcsR0FBRyx3QkFBSTtBQUMvQjtBQUNBO0FBQ0EsQ0FITzs7O0FBS1AsTUFBTUMsSUFBSSxHQUFHQyxrQkFBa0IsSUFBSTtBQUNqQ0EsRUFBQUEsa0JBQWtCLENBQUNDLGtDQUFuQixHQUF3REgsV0FBeEQ7O0FBRUEsUUFBTUksdUJBQU4sU0FBc0NDLDZCQUF0QyxDQUE2RDtBQUMzREMsSUFBQUEsb0JBQW9CLENBQUNDLEtBQUQsRUFBUTtBQUMxQkEsTUFBQUEsS0FBSyxDQUFDQyxPQUFOLEdBQWdCLE9BQU9DLE9BQVAsRUFBZ0JDLElBQWhCLEVBQXNCQyxPQUF0QixLQUFrQztBQUNoRCxZQUFJO0FBQ0YsZ0JBQU07QUFBRUMsWUFBQUEsTUFBRjtBQUFVQyxZQUFBQSxJQUFWO0FBQWdCQyxZQUFBQTtBQUFoQixjQUF5QkgsT0FBL0I7QUFFQSxjQUFJSSxZQUFZLEdBQUdSLEtBQUssQ0FBQ1MsSUFBekI7O0FBQ0EsY0FBSSxLQUFLTixJQUFMLENBQVVPLEVBQWQsRUFBa0I7QUFDaEJGLFlBQUFBLFlBQVksR0FBRyxLQUFLTCxJQUFMLENBQVVPLEVBQXpCO0FBQ0Q7O0FBRUQsaUJBQU8sQ0FDTCxNQUFNQyxpQ0FBZ0JDLG1CQUFoQixDQUFvQztBQUN4Q0MsWUFBQUEsTUFBTSxFQUFFO0FBQ05MLGNBQUFBO0FBRE0sYUFEZ0M7QUFJeENILFlBQUFBLE1BSndDO0FBS3hDQyxZQUFBQSxJQUx3QztBQU14Q0MsWUFBQUEsSUFOd0M7QUFPeENPLFlBQUFBLElBQUksRUFBRVg7QUFQa0MsV0FBcEMsQ0FERCxFQVVMWSxRQVZLLENBVUlDLE1BVlg7QUFXRCxTQW5CRCxDQW1CRSxPQUFPQyxDQUFQLEVBQVU7QUFDVnRCLFVBQUFBLGtCQUFrQixDQUFDdUIsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRixPQXZCRDtBQXdCRDs7QUExQjBEOztBQTZCN0R0QixFQUFBQSxrQkFBa0IsQ0FBQ3dCLHVCQUFuQixDQUEyQ2xCLE9BQTNDLEdBQXFESix1QkFBckQ7O0FBRUEsUUFBTXVCLG9CQUFOLFNBQW1DdEIsNkJBQW5DLENBQTBEO0FBQ3hEQyxJQUFBQSxvQkFBb0IsQ0FBQ0MsS0FBRCxFQUFRO0FBQzFCQSxNQUFBQSxLQUFLLENBQUNDLE9BQU4sR0FBZ0IsTUFBTTtBQUNwQixlQUFPLEtBQUtFLElBQUwsQ0FBVWtCLElBQWpCO0FBQ0QsT0FGRDtBQUdEOztBQUx1RDs7QUFRMUQxQixFQUFBQSxrQkFBa0IsQ0FBQ3dCLHVCQUFuQixDQUEyQ0csSUFBM0MsR0FBa0RGLG9CQUFsRDtBQUNELENBM0NEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGdxbCBmcm9tICdncmFwaHFsLXRhZyc7XG5pbXBvcnQgeyBTY2hlbWFEaXJlY3RpdmVWaXNpdG9yIH0gZnJvbSAnQGdyYXBocWwtdG9vbHMvdXRpbHMnO1xuaW1wb3J0IHsgRnVuY3Rpb25zUm91dGVyIH0gZnJvbSAnLi4vLi4vUm91dGVycy9GdW5jdGlvbnNSb3V0ZXInO1xuXG5leHBvcnQgY29uc3QgZGVmaW5pdGlvbnMgPSBncWxgXG4gIGRpcmVjdGl2ZSBAcmVzb2x2ZSh0bzogU3RyaW5nKSBvbiBGSUVMRF9ERUZJTklUSU9OXG4gIGRpcmVjdGl2ZSBAbW9jayh3aXRoOiBBbnkhKSBvbiBGSUVMRF9ERUZJTklUSU9OXG5gO1xuXG5jb25zdCBsb2FkID0gcGFyc2VHcmFwaFFMU2NoZW1hID0+IHtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmdyYXBoUUxTY2hlbWFEaXJlY3RpdmVzRGVmaW5pdGlvbnMgPSBkZWZpbml0aW9ucztcblxuICBjbGFzcyBSZXNvbHZlRGlyZWN0aXZlVmlzaXRvciBleHRlbmRzIFNjaGVtYURpcmVjdGl2ZVZpc2l0b3Ige1xuICAgIHZpc2l0RmllbGREZWZpbml0aW9uKGZpZWxkKSB7XG4gICAgICBmaWVsZC5yZXNvbHZlID0gYXN5bmMgKF9zb3VyY2UsIGFyZ3MsIGNvbnRleHQpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcblxuICAgICAgICAgIGxldCBmdW5jdGlvbk5hbWUgPSBmaWVsZC5uYW1lO1xuICAgICAgICAgIGlmICh0aGlzLmFyZ3MudG8pIHtcbiAgICAgICAgICAgIGZ1bmN0aW9uTmFtZSA9IHRoaXMuYXJncy50bztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgYXdhaXQgRnVuY3Rpb25zUm91dGVyLmhhbmRsZUNsb3VkRnVuY3Rpb24oe1xuICAgICAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgICAgICBmdW5jdGlvbk5hbWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICAgICAgYm9keTogYXJncyxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKS5yZXNwb25zZS5yZXN1bHQ7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmdyYXBoUUxTY2hlbWFEaXJlY3RpdmVzLnJlc29sdmUgPSBSZXNvbHZlRGlyZWN0aXZlVmlzaXRvcjtcblxuICBjbGFzcyBNb2NrRGlyZWN0aXZlVmlzaXRvciBleHRlbmRzIFNjaGVtYURpcmVjdGl2ZVZpc2l0b3Ige1xuICAgIHZpc2l0RmllbGREZWZpbml0aW9uKGZpZWxkKSB7XG4gICAgICBmaWVsZC5yZXNvbHZlID0gKCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5hcmdzLndpdGg7XG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5ncmFwaFFMU2NoZW1hRGlyZWN0aXZlcy5tb2NrID0gTW9ja0RpcmVjdGl2ZVZpc2l0b3I7XG59O1xuXG5leHBvcnQgeyBsb2FkIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/loaders/schemaMutations.js b/lib/GraphQL/loaders/schemaMutations.js new file mode 100644 index 0000000000..bc85bdf1a7 --- /dev/null +++ b/lib/GraphQL/loaders/schemaMutations.js @@ -0,0 +1,179 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _graphql = require("graphql"); + +var _graphqlRelay = require("graphql-relay"); + +var schemaTypes = _interopRequireWildcard(require("./schemaTypes")); + +var _schemaFields = require("../transformers/schemaFields"); + +var _parseGraphQLUtils = require("../parseGraphQLUtils"); + +var _schemaQueries = require("./schemaQueries"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const load = parseGraphQLSchema => { + const createClassMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'CreateClass', + description: 'The createClass mutation can be used to create the schema for a new object class.', + inputFields: { + name: schemaTypes.CLASS_NAME_ATT, + schemaFields: { + description: "These are the schema's fields of the object class.", + type: schemaTypes.SCHEMA_FIELDS_INPUT + } + }, + outputFields: { + class: { + description: 'This is the created class.', + type: new _graphql.GraphQLNonNull(schemaTypes.CLASS) + } + }, + mutateAndGetPayload: async (args, context) => { + try { + const { + name, + schemaFields + } = args; + const { + config, + auth + } = context; + (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); + + if (auth.isReadOnly) { + throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to create a schema."); + } + + const schema = await config.database.loadSchema({ + clearCache: true + }); + const parseClass = await schema.addClassIfNotExists(name, (0, _schemaFields.transformToParse)(schemaFields)); + return { + class: { + name: parseClass.className, + schemaFields: (0, _schemaFields.transformToGraphQL)(parseClass.fields) + } + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(createClassMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(createClassMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('createClass', createClassMutation, true, true); + const updateClassMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'UpdateClass', + description: 'The updateClass mutation can be used to update the schema for an existing object class.', + inputFields: { + name: schemaTypes.CLASS_NAME_ATT, + schemaFields: { + description: "These are the schema's fields of the object class.", + type: schemaTypes.SCHEMA_FIELDS_INPUT + } + }, + outputFields: { + class: { + description: 'This is the updated class.', + type: new _graphql.GraphQLNonNull(schemaTypes.CLASS) + } + }, + mutateAndGetPayload: async (args, context) => { + try { + const { + name, + schemaFields + } = args; + const { + config, + auth + } = context; + (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); + + if (auth.isReadOnly) { + throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to update a schema."); + } + + const schema = await config.database.loadSchema({ + clearCache: true + }); + const existingParseClass = await (0, _schemaQueries.getClass)(name, schema); + const parseClass = await schema.updateClass(name, (0, _schemaFields.transformToParse)(schemaFields, existingParseClass.fields), undefined, undefined, config.database); + return { + class: { + name: parseClass.className, + schemaFields: (0, _schemaFields.transformToGraphQL)(parseClass.fields) + } + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(updateClassMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(updateClassMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('updateClass', updateClassMutation, true, true); + const deleteClassMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'DeleteClass', + description: 'The deleteClass mutation can be used to delete an existing object class.', + inputFields: { + name: schemaTypes.CLASS_NAME_ATT + }, + outputFields: { + class: { + description: 'This is the deleted class.', + type: new _graphql.GraphQLNonNull(schemaTypes.CLASS) + } + }, + mutateAndGetPayload: async (args, context) => { + try { + const { + name + } = args; + const { + config, + auth + } = context; + (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); + + if (auth.isReadOnly) { + throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to delete a schema."); + } + + const schema = await config.database.loadSchema({ + clearCache: true + }); + const existingParseClass = await (0, _schemaQueries.getClass)(name, schema); + await config.database.deleteSchema(name); + return { + class: { + name: existingParseClass.className, + schemaFields: (0, _schemaFields.transformToGraphQL)(existingParseClass.fields) + } + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(deleteClassMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(deleteClassMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('deleteClass', deleteClassMutation, true, true); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvc2NoZW1hTXV0YXRpb25zLmpzIl0sIm5hbWVzIjpbImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJjcmVhdGVDbGFzc011dGF0aW9uIiwibmFtZSIsImRlc2NyaXB0aW9uIiwiaW5wdXRGaWVsZHMiLCJzY2hlbWFUeXBlcyIsIkNMQVNTX05BTUVfQVRUIiwic2NoZW1hRmllbGRzIiwidHlwZSIsIlNDSEVNQV9GSUVMRFNfSU5QVVQiLCJvdXRwdXRGaWVsZHMiLCJjbGFzcyIsIkdyYXBoUUxOb25OdWxsIiwiQ0xBU1MiLCJtdXRhdGVBbmRHZXRQYXlsb2FkIiwiYXJncyIsImNvbnRleHQiLCJjb25maWciLCJhdXRoIiwiaXNSZWFkT25seSIsIlBhcnNlIiwiRXJyb3IiLCJPUEVSQVRJT05fRk9SQklEREVOIiwic2NoZW1hIiwiZGF0YWJhc2UiLCJsb2FkU2NoZW1hIiwiY2xlYXJDYWNoZSIsInBhcnNlQ2xhc3MiLCJhZGRDbGFzc0lmTm90RXhpc3RzIiwiY2xhc3NOYW1lIiwiZmllbGRzIiwiZSIsImhhbmRsZUVycm9yIiwiYWRkR3JhcGhRTFR5cGUiLCJpbnB1dCIsIm9mVHlwZSIsImFkZEdyYXBoUUxNdXRhdGlvbiIsInVwZGF0ZUNsYXNzTXV0YXRpb24iLCJleGlzdGluZ1BhcnNlQ2xhc3MiLCJ1cGRhdGVDbGFzcyIsInVuZGVmaW5lZCIsImRlbGV0ZUNsYXNzTXV0YXRpb24iLCJkZWxldGVTY2hlbWEiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFQSxNQUFNQSxJQUFJLEdBQUdDLGtCQUFrQixJQUFJO0FBQ2pDLFFBQU1DLG1CQUFtQixHQUFHLGdEQUE2QjtBQUN2REMsSUFBQUEsSUFBSSxFQUFFLGFBRGlEO0FBRXZEQyxJQUFBQSxXQUFXLEVBQ1QsbUZBSHFEO0FBSXZEQyxJQUFBQSxXQUFXLEVBQUU7QUFDWEYs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QUNBLGNBQU1ZLGtCQUFrQixHQUFHLE1BQU0sNkJBQVNwQyxJQUFULEVBQWVxQixNQUFmLENBQWpDO0FBQ0EsY0FBTU4sTUFBTSxDQUFDTyxRQUFQLENBQWdCa0IsWUFBaEIsQ0FBNkJ4QyxJQUE3QixDQUFOO0FBQ0EsZUFBTztBQUNMUyxVQUFBQSxLQUFLLEVBQUU7QUFDTFQsWUFBQUEsSUFBSSxFQUFFb0Msa0JBQWtCLENBQUNULFNBRHBCO0FBRUx0QixZQUFBQSxZQUFZLEVBQUUsc0NBQW1CK0Isa0JBQWtCLENBQUNSLE1BQXRDO0FBRlQ7QUFERixTQUFQO0FBTUQsT0F0QkQsQ0FzQkUsT0FBT0MsQ0FBUCxFQUFVO0FBQ1YvQixRQUFBQSxrQkFBa0IsQ0FBQ2dDLFdBQW5CLENBQStCRCxDQUEvQjtBQUNEO0FBQ0Y7QUF0Q3NELEdBQTdCLENBQTVCO0FBeUNBL0IsRUFBQUEsa0JBQWtCLENBQUNpQyxjQUFuQixDQUFrQ1EsbUJBQW1CLENBQUMxQixJQUFwQixDQUF5Qm1CLEtBQXpCLENBQStCMUIsSUFBL0IsQ0FBb0MyQixNQUF0RSxFQUE4RSxJQUE5RSxFQUFvRixJQUFwRjtBQUNBbkMsRUFBQUEsa0JBQWtCLENBQUNpQyxjQUFuQixDQUFrQ1EsbUJBQW1CLENBQUNqQyxJQUF0RCxFQUE0RCxJQUE1RCxFQUFrRSxJQUFsRTtBQUNBUixFQUFBQSxrQkFBa0IsQ0FBQ29DLGtCQUFuQixDQUFzQyxhQUF0QyxFQUFxREssbUJBQXJELEVBQTBFLElBQTFFLEVBQWdGLElBQWhGO0FBQ0QsQ0F0SkQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBHcmFwaFFMTm9uTnVsbCB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0ICogYXMgc2NoZW1hVHlwZXMgZnJvbSAnLi9zY2hlbWFUeXBlcyc7XG5pbXBvcnQgeyB0cmFuc2Zvcm1Ub1BhcnNlLCB0cmFuc2Zvcm1Ub0dyYXBoUUwgfSBmcm9tICcuLi90cmFuc2Zvcm1lcnMvc2NoZW1hRmllbGRzJztcbmltcG9ydCB7IGVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MgfSBmcm9tICcuLi9wYXJzZUdyYXBoUUxVdGlscyc7XG5pbXBvcnQgeyBnZXRDbGFzcyB9IGZyb20gJy4vc2NoZW1hUXVlcmllcyc7XG5cbmNvbnN0IGxvYWQgPSBwYXJzZUdyYXBoUUxTY2hlbWEgPT4ge1xuICBjb25zdCBjcmVhdGVDbGFzc011dGF0aW9uID0gbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCh7XG4gICAgbmFtZTogJ0NyZWF0ZUNsYXNzJyxcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgICdUaGUgY3JlYXRlQ2xhc3MgbXV0YXRpb24gY2FuIGJlIHVzZWQgdG8gY3JlYXRlIHRoZSBzY2hlbWEgZm9yIGEgbmV3IG9iamVjdCBjbGFzcy4nLFxuICAgIGlucHV0RmllbGRzOiB7XG4gICAgICBuYW1lOiBzY2hlbWFUeXBlcy5DTEFTU19OQU1FX0FUVCxcbiAgICAgIHNjaGVtYUZpZWxkczoge1xuICAgICAgICBkZXNjcmlwdGlvbjogXCJUaGVzZSBhcmUgdGhlIHNjaGVtYSdzIGZpZWxkcyBvZiB0aGUgb2JqZWN0IGNsYXNzLlwiLFxuICAgICAgICB0eXBlOiBzY2hlbWFUeXBlcy5TQ0hFTUFfRklFTERTX0lOUFVULFxuICAgICAgfSxcbiAgICB9LFxuICAgIG91dHB1dEZpZWxkczoge1xuICAgICAgY2xhc3M6IHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBjcmVhdGVkIGNsYXNzLicsXG4gICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChzY2hlbWFUeXBlcy5DTEFTUyksXG4gICAgICB9LFxuICAgIH0sXG4gICAgbXV0YXRlQW5kR2V0UGF5bG9hZDogYXN5bmMgKGFyZ3MsIGNvbnRleHQpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgbmFtZSwgc2NoZW1hRmllbGRzIH0gPSBhcmdzO1xuICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCB9ID0gY29udGV4dDtcblxuICAgICAgICBlbmZvcmNlTWFzdGVyS2V5QWNjZXNzKGF1dGgpO1xuXG4gICAgICAgIGlmIChhdXRoLmlzUmVhZE9ubHkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICAgICAgXCJyZWFkLW9ubHkgbWFzdGVyS2V5IGlzbid0IGFsbG93ZWQgdG8gY3JlYXRlIGEgc2NoZW1hLlwiXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNjaGVtYSA9IGF3YWl0IGNvbmZpZy5kYXRhYmFzZS5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KTtcbiAgICAgICAgY29uc3QgcGFyc2VDbGFzcyA9IGF3YWl0IHNjaGVtYS5hZGRDbGFzc0lmTm90RXhpc3RzKG5hbWUsIHRyYW5zZm9ybVRvUGFyc2Uoc2NoZW1hRmllbGRzKSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgY2xhc3M6IHtcbiAgICAgICAgICAgIG5hbWU6IHBhcnNlQ2xhc3MuY2xhc3NOYW1lLFxuICAgICAgICAgICAgc2NoZW1hRmllbGRzOiB0cmFuc2Zvcm1Ub0dyYXBoUUwocGFyc2VDbGFzcy5maWVsZHMpLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcblxuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoY3JlYXRlQ2xhc3NNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNyZWF0ZUNsYXNzTXV0YXRpb24udHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oJ2NyZWF0ZUNsYXNzJywgY3JlYXRlQ2xhc3NNdXRhdGlvbiwgdHJ1ZSwgdHJ1ZSk7XG5cbiAgY29uc3QgdXBkYXRlQ2xhc3NNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgIG5hbWU6ICdVcGRhdGVDbGFzcycsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICAnVGhlIHVwZGF0ZUNsYXNzIG11dGF0aW9uIGNhbiBiZSB1c2VkIHRvIHVwZGF0ZSB0aGUgc2NoZW1hIGZvciBhbiBleGlzdGluZyBvYmplY3QgY2xhc3MuJyxcbiAgICBpbnB1dEZpZWxkczoge1xuICAgICAgbmFtZTogc2NoZW1hVHlwZXMuQ0xBU1NfTkFNRV9BVFQsXG4gICAgICBzY2hlbWFGaWVsZHM6IHtcbiAgICAgICAgZGVzY3JpcHRpb246IFwiVGhlc2UgYXJlIHRoZSBzY2hlbWEncyBmaWVsZHMgb2YgdGhlIG9iamVjdCBjbGFzcy5cIixcbiAgICAgICAgdHlwZTogc2NoZW1hVHlwZXMuU0NIRU1BX0ZJRUxEU19JTlBVVCxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgIGNsYXNzOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgdXBkYXRlZCBjbGFzcy4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoc2NoZW1hVHlwZXMuQ0xBU1MpLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jIChhcmdzLCBjb250ZXh0KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB7IG5hbWUsIHNjaGVtYUZpZWxkcyB9ID0gYXJncztcbiAgICAgICAgY29uc3QgeyBjb25maWcsIGF1dGggfSA9IGNvbnRleHQ7XG5cbiAgICAgICAgZW5mb3JjZU1hc3RlcktleUFjY2VzcyhhdXRoKTtcblxuICAgICAgICBpZiAoYXV0aC5pc1JlYWRPbmx5KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgICAgICAgIFwicmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIHVwZGF0ZSBhIHNjaGVtYS5cIlxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzY2hlbWEgPSBhd2FpdCBjb25maWcuZGF0YWJhc2UubG9hZFNjaGVtYSh7IGNsZWFyQ2FjaGU6IHRydWUgfSk7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nUGFyc2VDbGFzcyA9IGF3YWl0IGdldENsYXNzKG5hbWUsIHNjaGVtYSk7XG4gICAgICAgIGNvbnN0IHBhcnNlQ2xhc3MgPSBhd2FpdCBzY2hlbWEudXBkYXRlQ2xhc3MoXG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgICB0cmFuc2Zvcm1Ub1BhcnNlKHNjaGVtYUZpZWxkcywgZXhpc3RpbmdQYXJzZUNsYXNzLmZpZWxkcyksXG4gICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICBjb25maWcuZGF0YWJhc2VcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjbGFzczoge1xuICAgICAgICAgICAgbmFtZTogcGFyc2VDbGFzcy5jbGFzc05hbWUsXG4gICAgICAgICAgICBzY2hlbWFGaWVsZHM6IHRyYW5zZm9ybVRvR3JhcGhRTChwYXJzZUNsYXNzLmZpZWxkcyksXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZSh1cGRhdGVDbGFzc011dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGUsIHRydWUsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUodXBkYXRlQ2xhc3NNdXRhdGlvbi50eXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbigndXBkYXRlQ2xhc3MnLCB1cGRhdGVDbGFzc011dGF0aW9uLCB0cnVlLCB0cnVlKTtcblxuICBjb25zdCBkZWxldGVDbGFzc011dGF0aW9uID0gbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCh7XG4gICAgbmFtZTogJ0RlbGV0ZUNsYXNzJyxcbiAgICBkZXNjcmlwdGlvbjogJ1RoZSBkZWxldGVDbGFzcyBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBkZWxldGUgYW4gZXhpc3Rpbmcgb2JqZWN0IGNsYXNzLicsXG4gICAgaW5wdXRGaWVsZHM6IHtcbiAgICAgIG5hbWU6IHNjaGVtYVR5cGVzLkNMQVNTX05BTUVfQVRULFxuICAgIH0sXG4gICAgb3V0cHV0RmllbGRzOiB7XG4gICAgICBjbGFzczoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGRlbGV0ZWQgY2xhc3MuJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKHNjaGVtYVR5cGVzLkNMQVNTKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBtdXRhdGVBbmRHZXRQYXlsb2FkOiBhc3luYyAoYXJncywgY29udGV4dCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyBuYW1lIH0gPSBhcmdzO1xuICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCB9ID0gY29udGV4dDtcblxuICAgICAgICBlbmZvcmNlTWFzdGVyS2V5QWNjZXNzKGF1dGgpO1xuXG4gICAgICAgIGlmIChhdXRoLmlzUmVhZE9ubHkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICAgICAgXCJyZWFkLW9ubHkgbWFzdGVyS2V5IGlzbid0IGFsbG93ZWQgdG8gZGVsZXRlIGEgc2NoZW1hLlwiXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNjaGVtYSA9IGF3YWl0IGNvbmZpZy5kYXRhYmFzZS5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KTtcbiAgICAgICAgY29uc3QgZXhpc3RpbmdQYXJzZUNsYXNzID0gYXdhaXQgZ2V0Q2xhc3MobmFtZSwgc2NoZW1hKTtcbiAgICAgICAgYXdhaXQgY29uZmlnLmRhdGFiYXNlLmRlbGV0ZVNjaGVtYShuYW1lKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjbGFzczoge1xuICAgICAgICAgICAgbmFtZTogZXhpc3RpbmdQYXJzZUNsYXNzLmNsYXNzTmFtZSxcbiAgICAgICAgICAgIHNjaGVtYUZpZWxkczogdHJhbnNmb3JtVG9HcmFwaFFMKGV4aXN0aW5nUGFyc2VDbGFzcy5maWVsZHMpLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcblxuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoZGVsZXRlQ2xhc3NNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGRlbGV0ZUNsYXNzTXV0YXRpb24udHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oJ2RlbGV0ZUNsYXNzJywgZGVsZXRlQ2xhc3NNdXRhdGlvbiwgdHJ1ZSwgdHJ1ZSk7XG59O1xuXG5leHBvcnQgeyBsb2FkIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/loaders/schemaQueries.js b/lib/GraphQL/loaders/schemaQueries.js new file mode 100644 index 0000000000..33bef76fe1 --- /dev/null +++ b/lib/GraphQL/loaders/schemaQueries.js @@ -0,0 +1,93 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = exports.getClass = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _graphql = require("graphql"); + +var _schemaFields = require("../transformers/schemaFields"); + +var schemaTypes = _interopRequireWildcard(require("./schemaTypes")); + +var _parseGraphQLUtils = require("../parseGraphQLUtils"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const getClass = async (name, schema) => { + try { + return await schema.getOneSchema(name, true); + } catch (e) { + if (e === undefined) { + throw new _node.default.Error(_node.default.Error.INVALID_CLASS_NAME, `Class ${name} does not exist.`); + } else { + throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'Database adapter error.'); + } + } +}; + +exports.getClass = getClass; + +const load = parseGraphQLSchema => { + parseGraphQLSchema.addGraphQLQuery('class', { + description: 'The class query can be used to retrieve an existing object class.', + args: { + name: schemaTypes.CLASS_NAME_ATT + }, + type: new _graphql.GraphQLNonNull(schemaTypes.CLASS), + resolve: async (_source, args, context) => { + try { + const { + name + } = args; + const { + config, + auth + } = context; + (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); + const schema = await config.database.loadSchema({ + clearCache: true + }); + const parseClass = await getClass(name, schema); + return { + name: parseClass.className, + schemaFields: (0, _schemaFields.transformToGraphQL)(parseClass.fields) + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }, true, true); + parseGraphQLSchema.addGraphQLQuery('classes', { + description: 'The classes query can be used to retrieve the existing object classes.', + type: new _graphql.GraphQLNonNull(new _graphql.GraphQLList(new _graphql.GraphQLNonNull(schemaTypes.CLASS))), + resolve: async (_source, _args, context) => { + try { + const { + config, + auth + } = context; + (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); + const schema = await config.database.loadSchema({ + clearCache: true + }); + return (await schema.getAllClasses(true)).map(parseClass => ({ + name: parseClass.className, + schemaFields: (0, _schemaFields.transformToGraphQL)(parseClass.fields) + })); + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }, true, true); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvc2NoZW1hUXVlcmllcy5qcyJdLCJuYW1lcyI6WyJnZXRDbGFzcyIsIm5hbWUiLCJzY2hlbWEiLCJnZXRPbmVTY2hlbWEiLCJlIiwidW5kZWZpbmVkIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfQ0xBU1NfTkFNRSIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJhZGRHcmFwaFFMUXVlcnkiLCJkZXNjcmlwdGlvbiIsImFyZ3MiLCJzY2hlbWFUeXBlcyIsIkNMQVNTX05BTUVfQVRUIiwidHlwZSIsIkdyYXBoUUxOb25OdWxsIiwiQ0xBU1MiLCJyZXNvbHZlIiwiX3NvdXJjZSIsImNvbnRleHQiLCJjb25maWciLCJhdXRoIiwiZGF0YWJhc2UiLCJsb2FkU2NoZW1hIiwiY2xlYXJDYWNoZSIsInBhcnNlQ2xhc3MiLCJjbGFzc05hbWUiLCJzY2hlbWFGaWVsZHMiLCJmaWVsZHMiLCJoYW5kbGVFcnJvciIsIkdyYXBoUUxMaXN0IiwiX2FyZ3MiLCJnZXRBbGxDbGFzc2VzIiwibWFwIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBRUEsTUFBTUEsUUFBUSxHQUFHLE9BQU9DLElBQVAsRUFBYUMsTUFBYixLQUF3QjtBQUN2QyxNQUFJO0FBQ0YsV0FBTyxNQUFNQSxNQUFNLENBQUNDLFlBQVAsQ0FBb0JGLElBQXBCLEVBQTBCLElBQTFCLENBQWI7QUFDRCxHQUZELENBRUUsT0FBT0csQ0FBUCxFQUFVO0FBQ1YsUUFBSUEsQ0FBQyxLQUFLQyxTQUFWLEVBQXFCO0FBQ25CLFlBQU0sSUFBSUMsY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZQyxrQkFBNUIsRUFBaUQsU0FBUVAsSUFBSyxrQkFBOUQsQ0FBTjtBQUNELEtBRkQsTUFFTztBQUNMLFlBQU0sSUFBSUssY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZRSxxQkFBNUIsRUFBbUQseUJBQW5ELENBQU47QUFDRDtBQUNGO0FBQ0YsQ0FWRDs7OztBQVlBLE1BQU1DLElBQUksR0FBR0Msa0JBQWtCLElBQUk7QUFDakNBLEVBQUFBLGtCQUFrQixDQUFDQyxlQUFuQixDQUNFLE9BREYsRUFFRTtBQUNFQyxJQUFBQSxXQUFXLEVBQUUsbUVBRGY7QUFFRUMsSUFBQUEsSUFBSSxFQUFFO0FBQ0piLE1BQUFBLElBQUksRUFBRWMsV0FBVyxDQUFDQztBQURkLEtBRlI7QUFLRUMsSUFBQUEsSUFBSSxFQUFFLElBQUlDLHVCQUFKLENBQW1CSCxXQUFXLENBQUNJLEtBQS9CLENBTFI7QUFNRUMsSUFBQUEsT0FBTyxFQUFFLE9BQU9DLE9BQVAsRUFBZ0JQLElBQWhCLEVBQXNCUSxPQUF0QixLQUFrQztBQUN6QyxVQUFJO0FBQ0YsY0FBTTtBQUFFckIsVUFBQUE7QUFBRixZQUFXYSxJQUFqQjtBQUNBLGNBQU07QUFBRVMsVUFBQUEsTUFBRjtBQUFVQyxVQUFBQTtBQUFWLFlBQW1CRixPQUF6QjtBQUVBLHVEQUF1QkUsSUFBdkI7QUFFQSxjQUFNdEIsTUFBTSxHQUFHLE1BQU1xQixNQUFNLENBQUNFLFFBQVAsQ0FBZ0JDLFVBQWhCLENBQTJCO0FBQUVDLFVBQUFBLFVBQVUsRUFBRTtBQUFkLFNBQTNCLENBQXJCO0FBQ0EsY0FBTUMsVUFBVSxHQUFHLE1BQU01QixRQUFRLENBQUNDLElBQUQsRUFBT0MsTUFBUCxDQUFqQztBQUNBLGVBQU87QUFDTEQsVUFBQUEsSUFBSSxFQUFFMkIsVUFBVSxDQUFDQyxTQURaO0FBRUxDLFVBQUFBLFlBQVksRUFBRSxzQ0FBbUJGLFVBQVUsQ0FBQ0csTUFBOUI7QUFGVCxTQUFQO0FBSUQsT0FaRCxDQVlFLE9BQU8zQixDQUFQLEVBQVU7QUFDVk8sUUFBQUEsa0JBQWtCLENBQUNxQixXQUFuQixDQUErQjVCLENBQS9CO0FBQ0Q7QUFDRjtBQXRCSCxHQUZGLEVBMEJFLElBMUJGLEVBMkJFLElBM0JGO0FBOEJBTyxFQUFBQSxrQkFBa0IsQ0FBQ0MsZUFBbkIsQ0FDRSxTQURGLEVBRUU7QUFDRUMsSUFBQUEsV0FBVyxFQUFFLHdFQURmO0FBRUVJLElBQUFBLElBQUksRUFBRSxJQUFJQyx1QkFBSixDQUFtQixJQUFJZSxvQkFBSixDQUFnQixJQUFJZix1QkFBSixDQUFtQkgsV0FBVyxDQUFDSSxLQUEvQixDQUFoQixDQUFuQixDQUZSO0FBR0VDLElBQUFBLE9BQU8sRUFBRSxPQUFPQyxPQUFQLEVBQWdCYSxLQUFoQixFQUF1QlosT0FBdkIsS0FBbUM7QUFDMUMsVUFBSTtBQUNGLGNBQU07QUFBRUMsVUFBQUEsTUFBRjtBQUFVQyxVQUFBQTtBQUFWLFlBQW1CRixPQUF6QjtBQUVBLHVEQUF1QkUsSUFBdkI7QUFFQSxjQUFNdEIsTUFBTSxHQUFHLE1BQU1xQixNQUFNLENBQUNFLFFBQVAsQ0FBZ0JDLFVBQWhCLENBQTJCO0FBQUVDLFVBQUFBLFVBQVUsRUFBRTtBQUFkLFNBQTNCLENBQXJCO0FBQ0EsZUFBTyxDQUFDLE1BQU16QixNQUFNLENBQUNpQyxhQUFQLENBQXFCLElBQXJCLENBQVAsRUFBbUNDLEdBQW5DLENBQXVDUixVQUFVLEtBQUs7QUFDM0QzQixVQUFBQSxJQUFJLEVBQUUyQixVQUFVLENBQUNDLFNBRDBDO0FBRTNEQyxVQUFBQSxZQUFZLEVBQUUsc0NBQW1CRixVQUFVLENBQUNHLE1BQTlCO0FBRjZDLFNBQUwsQ0FBakQsQ0FBUDtBQUlELE9BVkQsQ0FVRSxPQUFPM0IsQ0FBUCxFQUFVO0FBQ1ZPLFFBQUFBLGtCQUFrQixDQUFDcUIsV0FBbkIsQ0FBK0I1QixDQUEvQjtBQUNEO0FBQ0Y7QUFqQkgsR0FGRixFQXFCRSxJQXJCRixFQXNCRSxJQXRCRjtBQXdCRCxDQXZERCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCB7IEdyYXBoUUxOb25OdWxsLCBHcmFwaFFMTGlzdCB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgdHJhbnNmb3JtVG9HcmFwaFFMIH0gZnJvbSAnLi4vdHJhbnNmb3JtZXJzL3NjaGVtYUZpZWxkcyc7XG5pbXBvcnQgKiBhcyBzY2hlbWFUeXBlcyBmcm9tICcuL3NjaGVtYVR5cGVzJztcbmltcG9ydCB7IGVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MgfSBmcm9tICcuLi9wYXJzZUdyYXBoUUxVdGlscyc7XG5cbmNvbnN0IGdldENsYXNzID0gYXN5bmMgKG5hbWUsIHNjaGVtYSkgPT4ge1xuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBzY2hlbWEuZ2V0T25lU2NoZW1hKG5hbWUsIHRydWUpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSwgYENsYXNzICR7bmFtZX0gZG9lcyBub3QgZXhpc3QuYCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsICdEYXRhYmFzZSBhZGFwdGVyIGVycm9yLicpO1xuICAgIH1cbiAgfVxufTtcblxuY29uc3QgbG9hZCA9IHBhcnNlR3JhcGhRTFNjaGVtYSA9PiB7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMUXVlcnkoXG4gICAgJ2NsYXNzJyxcbiAgICB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSBjbGFzcyBxdWVyeSBjYW4gYmUgdXNlZCB0byByZXRyaWV2ZSBhbiBleGlzdGluZyBvYmplY3QgY2xhc3MuJyxcbiAgICAgIGFyZ3M6IHtcbiAgICAgICAgbmFtZTogc2NoZW1hVHlwZXMuQ0xBU1NfTkFNRV9BVFQsXG4gICAgICB9LFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKHNjaGVtYVR5cGVzLkNMQVNTKSxcbiAgICAgIHJlc29sdmU6IGFzeW5jIChfc291cmNlLCBhcmdzLCBjb250ZXh0KSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgeyBuYW1lIH0gPSBhcmdzO1xuICAgICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoIH0gPSBjb250ZXh0O1xuXG4gICAgICAgICAgZW5mb3JjZU1hc3RlcktleUFjY2VzcyhhdXRoKTtcblxuICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IGF3YWl0IGNvbmZpZy5kYXRhYmFzZS5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KTtcbiAgICAgICAgICBjb25zdCBwYXJzZUNsYXNzID0gYXdhaXQgZ2V0Q2xhc3MobmFtZSwgc2NoZW1hKTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbmFtZTogcGFyc2VDbGFzcy5jbGFzc05hbWUsXG4gICAgICAgICAgICBzY2hlbWFGaWVsZHM6IHRyYW5zZm9ybVRvR3JhcGhRTChwYXJzZUNsYXNzLmZpZWxkcyksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9LFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMUXVlcnkoXG4gICAgJ2NsYXNzZXMnLFxuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIGNsYXNzZXMgcXVlcnkgY2FuIGJlIHVzZWQgdG8gcmV0cmlldmUgdGhlIGV4aXN0aW5nIG9iamVjdCBjbGFzc2VzLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwobmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChzY2hlbWFUeXBlcy5DTEFTUykpKSxcbiAgICAgIHJlc29sdmU6IGFzeW5jIChfc291cmNlLCBfYXJncywgY29udGV4dCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoIH0gPSBjb250ZXh0O1xuXG4gICAgICAgICAgZW5mb3JjZU1hc3RlcktleUFjY2VzcyhhdXRoKTtcblxuICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IGF3YWl0IGNvbmZpZy5kYXRhYmFzZS5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KTtcbiAgICAgICAgICByZXR1cm4gKGF3YWl0IHNjaGVtYS5nZXRBbGxDbGFzc2VzKHRydWUpKS5tYXAocGFyc2VDbGFzcyA9PiAoe1xuICAgICAgICAgICAgbmFtZTogcGFyc2VDbGFzcy5jbGFzc05hbWUsXG4gICAgICAgICAgICBzY2hlbWFGaWVsZHM6IHRyYW5zZm9ybVRvR3JhcGhRTChwYXJzZUNsYXNzLmZpZWxkcyksXG4gICAgICAgICAgfSkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0sXG4gICAgdHJ1ZSxcbiAgICB0cnVlXG4gICk7XG59O1xuXG5leHBvcnQgeyBnZXRDbGFzcywgbG9hZCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/schemaTypes.js b/lib/GraphQL/loaders/schemaTypes.js new file mode 100644 index 0000000000..832edfa0e1 --- /dev/null +++ b/lib/GraphQL/loaders/schemaTypes.js @@ -0,0 +1,376 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = exports.CLASS = exports.CLASS_NAME_ATT = exports.SCHEMA_FIELDS_INPUT = exports.SCHEMA_ACL_FIELD = exports.SCHEMA_RELATION_FIELD = exports.SCHEMA_RELATION_FIELD_INPUT = exports.SCHEMA_POINTER_FIELD = exports.SCHEMA_POINTER_FIELD_INPUT = exports.TARGET_CLASS_ATT = exports.SCHEMA_BYTES_FIELD = exports.SCHEMA_BYTES_FIELD_INPUT = exports.SCHEMA_POLYGON_FIELD = exports.SCHEMA_POLYGON_FIELD_INPUT = exports.SCHEMA_GEO_POINT_FIELD = exports.SCHEMA_GEO_POINT_FIELD_INPUT = exports.SCHEMA_FILE_FIELD = exports.SCHEMA_FILE_FIELD_INPUT = exports.SCHEMA_DATE_FIELD = exports.SCHEMA_DATE_FIELD_INPUT = exports.SCHEMA_OBJECT_FIELD = exports.SCHEMA_OBJECT_FIELD_INPUT = exports.SCHEMA_ARRAY_FIELD = exports.SCHEMA_ARRAY_FIELD_INPUT = exports.SCHEMA_BOOLEAN_FIELD = exports.SCHEMA_BOOLEAN_FIELD_INPUT = exports.SCHEMA_NUMBER_FIELD = exports.SCHEMA_NUMBER_FIELD_INPUT = exports.SCHEMA_STRING_FIELD = exports.SCHEMA_STRING_FIELD_INPUT = exports.SCHEMA_FIELD_INPUT = exports.SCHEMA_FIELD_NAME_ATT = void 0; + +var _graphql = require("graphql"); + +const SCHEMA_FIELD_NAME_ATT = { + description: 'This is the field name.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) +}; +exports.SCHEMA_FIELD_NAME_ATT = SCHEMA_FIELD_NAME_ATT; +const SCHEMA_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaFieldInput', + description: 'The SchemaFieldInput is used to specify a field of an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_FIELD_INPUT = SCHEMA_FIELD_INPUT; +const SCHEMA_FIELD = new _graphql.GraphQLInterfaceType({ + name: 'SchemaField', + description: 'The SchemaField interface type is used as a base type for the different supported fields of an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + }, + resolveType: value => ({ + String: SCHEMA_STRING_FIELD, + Number: SCHEMA_NUMBER_FIELD, + Boolean: SCHEMA_BOOLEAN_FIELD, + Array: SCHEMA_ARRAY_FIELD, + Object: SCHEMA_OBJECT_FIELD, + Date: SCHEMA_DATE_FIELD, + File: SCHEMA_FILE_FIELD, + GeoPoint: SCHEMA_GEO_POINT_FIELD, + Polygon: SCHEMA_POLYGON_FIELD, + Bytes: SCHEMA_BYTES_FIELD, + Pointer: SCHEMA_POINTER_FIELD, + Relation: SCHEMA_RELATION_FIELD, + ACL: SCHEMA_ACL_FIELD + })[value.type] +}); +const SCHEMA_STRING_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaStringFieldInput', + description: 'The SchemaStringFieldInput is used to specify a field of type string for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_STRING_FIELD_INPUT = SCHEMA_STRING_FIELD_INPUT; +const SCHEMA_STRING_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaStringField', + description: 'The SchemaStringField is used to return information of a String field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_STRING_FIELD = SCHEMA_STRING_FIELD; +const SCHEMA_NUMBER_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaNumberFieldInput', + description: 'The SchemaNumberFieldInput is used to specify a field of type number for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_NUMBER_FIELD_INPUT = SCHEMA_NUMBER_FIELD_INPUT; +const SCHEMA_NUMBER_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaNumberField', + description: 'The SchemaNumberField is used to return information of a Number field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_NUMBER_FIELD = SCHEMA_NUMBER_FIELD; +const SCHEMA_BOOLEAN_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaBooleanFieldInput', + description: 'The SchemaBooleanFieldInput is used to specify a field of type boolean for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_BOOLEAN_FIELD_INPUT = SCHEMA_BOOLEAN_FIELD_INPUT; +const SCHEMA_BOOLEAN_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaBooleanField', + description: 'The SchemaBooleanField is used to return information of a Boolean field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_BOOLEAN_FIELD = SCHEMA_BOOLEAN_FIELD; +const SCHEMA_ARRAY_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaArrayFieldInput', + description: 'The SchemaArrayFieldInput is used to specify a field of type array for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_ARRAY_FIELD_INPUT = SCHEMA_ARRAY_FIELD_INPUT; +const SCHEMA_ARRAY_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaArrayField', + description: 'The SchemaArrayField is used to return information of an Array field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_ARRAY_FIELD = SCHEMA_ARRAY_FIELD; +const SCHEMA_OBJECT_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaObjectFieldInput', + description: 'The SchemaObjectFieldInput is used to specify a field of type object for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_OBJECT_FIELD_INPUT = SCHEMA_OBJECT_FIELD_INPUT; +const SCHEMA_OBJECT_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaObjectField', + description: 'The SchemaObjectField is used to return information of an Object field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_OBJECT_FIELD = SCHEMA_OBJECT_FIELD; +const SCHEMA_DATE_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaDateFieldInput', + description: 'The SchemaDateFieldInput is used to specify a field of type date for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_DATE_FIELD_INPUT = SCHEMA_DATE_FIELD_INPUT; +const SCHEMA_DATE_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaDateField', + description: 'The SchemaDateField is used to return information of a Date field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_DATE_FIELD = SCHEMA_DATE_FIELD; +const SCHEMA_FILE_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaFileFieldInput', + description: 'The SchemaFileFieldInput is used to specify a field of type file for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_FILE_FIELD_INPUT = SCHEMA_FILE_FIELD_INPUT; +const SCHEMA_FILE_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaFileField', + description: 'The SchemaFileField is used to return information of a File field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_FILE_FIELD = SCHEMA_FILE_FIELD; +const SCHEMA_GEO_POINT_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaGeoPointFieldInput', + description: 'The SchemaGeoPointFieldInput is used to specify a field of type geo point for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_GEO_POINT_FIELD_INPUT = SCHEMA_GEO_POINT_FIELD_INPUT; +const SCHEMA_GEO_POINT_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaGeoPointField', + description: 'The SchemaGeoPointField is used to return information of a Geo Point field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_GEO_POINT_FIELD = SCHEMA_GEO_POINT_FIELD; +const SCHEMA_POLYGON_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaPolygonFieldInput', + description: 'The SchemaPolygonFieldInput is used to specify a field of type polygon for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_POLYGON_FIELD_INPUT = SCHEMA_POLYGON_FIELD_INPUT; +const SCHEMA_POLYGON_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaPolygonField', + description: 'The SchemaPolygonField is used to return information of a Polygon field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_POLYGON_FIELD = SCHEMA_POLYGON_FIELD; +const SCHEMA_BYTES_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaBytesFieldInput', + description: 'The SchemaBytesFieldInput is used to specify a field of type bytes for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_BYTES_FIELD_INPUT = SCHEMA_BYTES_FIELD_INPUT; +const SCHEMA_BYTES_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaBytesField', + description: 'The SchemaBytesField is used to return information of a Bytes field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_BYTES_FIELD = SCHEMA_BYTES_FIELD; +const TARGET_CLASS_ATT = { + description: 'This is the name of the target class for the field.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) +}; +exports.TARGET_CLASS_ATT = TARGET_CLASS_ATT; +const SCHEMA_POINTER_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'PointerFieldInput', + description: 'The PointerFieldInput is used to specify a field of type pointer for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT, + targetClassName: TARGET_CLASS_ATT + } +}); +exports.SCHEMA_POINTER_FIELD_INPUT = SCHEMA_POINTER_FIELD_INPUT; +const SCHEMA_POINTER_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaPointerField', + description: 'The SchemaPointerField is used to return information of a Pointer field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT, + targetClassName: TARGET_CLASS_ATT + } +}); +exports.SCHEMA_POINTER_FIELD = SCHEMA_POINTER_FIELD; +const SCHEMA_RELATION_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'RelationFieldInput', + description: 'The RelationFieldInput is used to specify a field of type relation for an object class schema.', + fields: { + name: SCHEMA_FIELD_NAME_ATT, + targetClassName: TARGET_CLASS_ATT + } +}); +exports.SCHEMA_RELATION_FIELD_INPUT = SCHEMA_RELATION_FIELD_INPUT; +const SCHEMA_RELATION_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaRelationField', + description: 'The SchemaRelationField is used to return information of a Relation field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT, + targetClassName: TARGET_CLASS_ATT + } +}); +exports.SCHEMA_RELATION_FIELD = SCHEMA_RELATION_FIELD; +const SCHEMA_ACL_FIELD = new _graphql.GraphQLObjectType({ + name: 'SchemaACLField', + description: 'The SchemaACLField is used to return information of an ACL field.', + interfaces: [SCHEMA_FIELD], + fields: { + name: SCHEMA_FIELD_NAME_ATT + } +}); +exports.SCHEMA_ACL_FIELD = SCHEMA_ACL_FIELD; +const SCHEMA_FIELDS_INPUT = new _graphql.GraphQLInputObjectType({ + name: 'SchemaFieldsInput', + description: `The CreateClassSchemaInput type is used to specify the schema for a new object class to be created.`, + fields: { + addStrings: { + description: 'These are the String fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_STRING_FIELD_INPUT)) + }, + addNumbers: { + description: 'These are the Number fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_NUMBER_FIELD_INPUT)) + }, + addBooleans: { + description: 'These are the Boolean fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_BOOLEAN_FIELD_INPUT)) + }, + addArrays: { + description: 'These are the Array fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_ARRAY_FIELD_INPUT)) + }, + addObjects: { + description: 'These are the Object fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_OBJECT_FIELD_INPUT)) + }, + addDates: { + description: 'These are the Date fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_DATE_FIELD_INPUT)) + }, + addFiles: { + description: 'These are the File fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_FILE_FIELD_INPUT)) + }, + addGeoPoint: { + description: 'This is the Geo Point field to be added to the class schema. Currently it is supported only one GeoPoint field per Class.', + type: SCHEMA_GEO_POINT_FIELD_INPUT + }, + addPolygons: { + description: 'These are the Polygon fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_POLYGON_FIELD_INPUT)) + }, + addBytes: { + description: 'These are the Bytes fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_BYTES_FIELD_INPUT)) + }, + addPointers: { + description: 'These are the Pointer fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_POINTER_FIELD_INPUT)) + }, + addRelations: { + description: 'These are the Relation fields to be added to the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_RELATION_FIELD_INPUT)) + }, + remove: { + description: 'These are the fields to be removed from the class schema.', + type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_FIELD_INPUT)) + } + } +}); +exports.SCHEMA_FIELDS_INPUT = SCHEMA_FIELDS_INPUT; +const CLASS_NAME_ATT = { + description: 'This is the name of the object class.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) +}; +exports.CLASS_NAME_ATT = CLASS_NAME_ATT; +const CLASS = new _graphql.GraphQLObjectType({ + name: 'Class', + description: `The Class type is used to return the information about an object class.`, + fields: { + name: CLASS_NAME_ATT, + schemaFields: { + description: "These are the schema's fields of the object class.", + type: new _graphql.GraphQLNonNull(new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_FIELD))) + } + } +}); +exports.CLASS = CLASS; + +const load = parseGraphQLSchema => { + parseGraphQLSchema.addGraphQLType(SCHEMA_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_STRING_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_STRING_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_NUMBER_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_NUMBER_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_BOOLEAN_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_BOOLEAN_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_ARRAY_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_ARRAY_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_OBJECT_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_OBJECT_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_DATE_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_DATE_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_FILE_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_FILE_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_GEO_POINT_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_GEO_POINT_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_POLYGON_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_POLYGON_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_BYTES_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_BYTES_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_POINTER_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_POINTER_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_RELATION_FIELD_INPUT, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_RELATION_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_ACL_FIELD, true); + parseGraphQLSchema.addGraphQLType(SCHEMA_FIELDS_INPUT, true); + parseGraphQLSchema.addGraphQLType(CLASS, true); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvc2NoZW1hVHlwZXMuanMiXSwibmFtZXMiOlsiU0NIRU1BX0ZJRUxEX05BTUVfQVRUIiwiZGVzY3JpcHRpb24iLCJ0eXBlIiwiR3JhcGhRTE5vbk51bGwiLCJHcmFwaFFMU3RyaW5nIiwiU0NIRU1BX0ZJRUxEX0lOUFVUIiwiR3JhcGhRTElucHV0T2JqZWN0VHlwZSIsIm5hbWUiLCJmaWVsZHMiLCJTQ0hFTUFfRklFTEQiLCJHcmFwaFFMSW50ZXJmYWNlVHlwZSIsInJlc29sdmVUeXBlIiwidmFsdWUiLCJTdHJpbmciLCJTQ0hFTUFfU1RSSU5HX0ZJRUxEIiwiTnVtYmVyIiwiU0NIRU1BX05VTUJFUl9GSUVMRCIsIkJvb2xlYW4iLCJTQ0hFTUFfQk9PTEVBTl9GSUVMRCIsIkFycmF5IiwiU0NIRU1BX0FSUkFZX0ZJRUxEIiwiT2JqZWN0IiwiU0NIRU1BX09CSkVDVF9GSUVMRCIsIkRhdGUiLCJTQ0hFTUFfREFURV9GSUVMRCIsIkZpbGUiLCJTQ0hFTUFfRklMRV9GSUVMRCIsIkdlb1BvaW50IiwiU0NIRU1BX0dFT19QT0lOVF9GSUVMRCIsIlBvbHlnb24iLCJTQ0hFTUFfUE9MWUdPTl9GSUVMRCIsIkJ5dGVzIiwiU0NIRU1BX0JZVEVTX0ZJRUxEIiwiUG9pbnRlciIsIlNDSEVNQV9QT0lOVEVSX0ZJRUxEIiwiUmVsYXRpb24iLCJTQ0hFTUFfUkVMQVRJT05fRklFTEQiLCJBQ0wiLCJTQ0hFTUFfQUNMX0ZJRUxEIiwiU0NIRU1BX1NUUklOR19GSUVMRF9JTlBVVCIsIkdyYXBoUUxPYmplY3RUeXBlIiwiaW50ZXJmYWNlcyIsIlNDSEVNQV9OVU1CRVJfRklFTERfSU5QVVQiLCJTQ0hFTUFfQk9PTEVBTl9GSUVMRF9JTlBVVCIsIlNDSEVNQV9BUlJBWV9GSUVMRF9JTlBVVCIsIlNDSEVNQV9PQkpFQ1RfRklFTERfSU5QVVQiLCJTQ0hFTUFfREFURV9GSUVMRF9JTlBVVCIsIlNDSEVNQV9GSUxFX0ZJRUxEX0lOUFVUIiwiU0NIRU1BX0dFT19QT0lOVF9GSUVMRF9JTlBVVCIsIlNDSEVNQV9QT0xZR09OX0ZJRUxEX0lOUFVUIiwiU0NIRU1BX0JZVEVTX0ZJRUxEX0lOUFVUIiwiVEFSR0VUX0NMQVNTX0FUVCIsIlNDSEVNQV9QT0lOVEVSX0ZJRUxEX0lOUFVUIiwidGFyZ2V0Q2xhc3NOYW1lIiwiU0NIRU1BX1JFTEFUSU9OX0ZJRUxEX0lOUFVUIiwiU0NIRU1BX0ZJRUxEU19JTlBVVCIsImFkZFN0cmluZ3MiLCJHcmFwaFFMTGlzdCIsImFkZE51bWJlcnMiLCJhZGRCb29sZWFucyIsImFkZEFycmF5cyIsImFkZE9iamVjdHMiLCJhZGREYXRlcyIsImFkZEZpbGVzIiwiYWRkR2VvUG9pbnQiLCJhZGRQb2x5Z29ucyIsImFkZEJ5dGVzIiwiYWRkUG9pbnRlcnMiLCJhZGRSZWxhdGlvbnMiLCJyZW1vdmUiLCJDTEFTU19OQU1FX0FUVCIsIkNMQVNTIiwic2NoZW1hRmllbGRzIiwibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsImFkZEdyYXBoUUxUeXBlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBU0EsTUFBTUEscUJBQXFCLEdBQUc7QUFDNUJDLEVBQUFBLFdBQVcsRUFBRSx5QkFEZTtBQUU1QkMsRUFBQUEsSUFBSSxFQUFFLElBQUlDLHVCQUFKLENBQW1CQyxzQkFBbkI7QUFGc0IsQ0FBOUI7O0FBS0EsTUFBTUMsa0JBQWtCLEdBQUcsSUFBSUMsK0JBQUosQ0FBMkI7QUFDcERDLEVBQUFBLElBQUksRUFBRSxrQkFEOEM7QUFFcEROLEVBQUFBLFdBQVcsRUFBRSw0RUFGdUM7QUFHcERPLEVBQUFBLE1BQU0sRUFBRTtBQUNORCxJQUFBQSxJQUFJLEVBQUVQO0FBREE7QUFINEMsQ0FBM0IsQ0FBM0I7O0FBUUEsTUFBTVMsWUFBWSxHQUFHLElBQUlDLDZCQUFKLENBQXlCO0FBQzVDSCxFQUFBQSxJQUFJLEVBQUUsYUFEc0M7QUFFNUNOLEVBQUFBLFdBQVcsRUFDVCxxSEFIMEM7QUFJNUNPLEVBQUFBLE1BQU0s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QUFuQixDQUFrQzFCLDBCQUFsQyxFQUE4RCxJQUE5RDtBQUNBeUIsRUFBQUEsa0JBQWtCLENBQUNDLGNBQW5CLENBQWtDN0Msb0JBQWxDLEVBQXdELElBQXhEO0FBQ0E0QyxFQUFBQSxrQkFBa0IsQ0FBQ0MsY0FBbkIsQ0FBa0N6Qix3QkFBbEMsRUFBNEQsSUFBNUQ7QUFDQXdCLEVBQUFBLGtCQUFrQixDQUFDQyxjQUFuQixDQUFrQzNDLGtCQUFsQyxFQUFzRCxJQUF0RDtBQUNBMEMsRUFBQUEsa0JBQWtCLENBQUNDLGNBQW5CLENBQWtDdkIsMEJBQWxDLEVBQThELElBQTlEO0FBQ0FzQixFQUFBQSxrQkFBa0IsQ0FBQ0MsY0FBbkIsQ0FBa0N6QyxvQkFBbEMsRUFBd0QsSUFBeEQ7QUFDQXdDLEVBQUFBLGtCQUFrQixDQUFDQyxjQUFuQixDQUFrQ3JCLDJCQUFsQyxFQUErRCxJQUEvRDtBQUNBb0IsRUFBQUEsa0JBQWtCLENBQUNDLGNBQW5CLENBQWtDdkMscUJBQWxDLEVBQXlELElBQXpEO0FBQ0FzQyxFQUFBQSxrQkFBa0IsQ0FBQ0MsY0FBbkIsQ0FBa0NyQyxnQkFBbEMsRUFBb0QsSUFBcEQ7QUFDQW9DLEVBQUFBLGtCQUFrQixDQUFDQyxjQUFuQixDQUFrQ3BCLG1CQUFsQyxFQUF1RCxJQUF2RDtBQUNBbUIsRUFBQUEsa0JBQWtCLENBQUNDLGNBQW5CLENBQWtDSixLQUFsQyxFQUF5QyxJQUF6QztBQUNELENBN0JEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgR3JhcGhRTE5vbk51bGwsXG4gIEdyYXBoUUxTdHJpbmcsXG4gIEdyYXBoUUxJbnB1dE9iamVjdFR5cGUsXG4gIEdyYXBoUUxMaXN0LFxuICBHcmFwaFFMT2JqZWN0VHlwZSxcbiAgR3JhcGhRTEludGVyZmFjZVR5cGUsXG59IGZyb20gJ2dyYXBocWwnO1xuXG5jb25zdCBTQ0hFTUFfRklFTERfTkFNRV9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgZmllbGQgbmFtZS4nLFxuICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG59O1xuXG5jb25zdCBTQ0hFTUFfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFGaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246ICdUaGUgU2NoZW1hRmllbGRJbnB1dCBpcyB1c2VkIHRvIHNwZWNpZnkgYSBmaWVsZCBvZiBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfRklFTEQgPSBuZXcgR3JhcGhRTEludGVyZmFjZVR5cGUoe1xuICBuYW1lOiAnU2NoZW1hRmllbGQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYUZpZWxkIGludGVyZmFjZSB0eXBlIGlzIHVzZWQgYXMgYSBiYXNlIHR5cGUgZm9yIHRoZSBkaWZmZXJlbnQgc3VwcG9ydGVkIGZpZWxkcyBvZiBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbiAgcmVzb2x2ZVR5cGU6IHZhbHVlID0+XG4gICAgKHtcbiAgICAgIFN0cmluZzogU0NIRU1BX1NUUklOR19GSUVMRCxcbiAgICAgIE51bWJlcjogU0NIRU1BX05VTUJFUl9GSUVMRCxcbiAgICAgIEJvb2xlYW46IFNDSEVNQV9CT09MRUFOX0ZJRUxELFxuICAgICAgQXJyYXk6IFNDSEVNQV9BUlJBWV9GSUVMRCxcbiAgICAgIE9iamVjdDogU0NIRU1BX09CSkVDVF9GSUVMRCxcbiAgICAgIERhdGU6IFNDSEVNQV9EQVRFX0ZJRUxELFxuICAgICAgRmlsZTogU0NIRU1BX0ZJTEVfRklFTEQsXG4gICAgICBHZW9Qb2ludDogU0NIRU1BX0dFT19QT0lOVF9GSUVMRCxcbiAgICAgIFBvbHlnb246IFNDSEVNQV9QT0xZR09OX0ZJRUxELFxuICAgICAgQnl0ZXM6IFNDSEVNQV9CWVRFU19GSUVMRCxcbiAgICAgIFBvaW50ZXI6IFNDSEVNQV9QT0lOVEVSX0ZJRUxELFxuICAgICAgUmVsYXRpb246IFNDSEVNQV9SRUxBVElPTl9GSUVMRCxcbiAgICAgIEFDTDogU0NIRU1BX0FDTF9GSUVMRCxcbiAgICB9W3ZhbHVlLnR5cGVdKSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfU1RSSU5HX0ZJRUxEX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hU3RyaW5nRmllbGRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hU3RyaW5nRmllbGRJbnB1dCBpcyB1c2VkIHRvIHNwZWNpZnkgYSBmaWVsZCBvZiB0eXBlIHN0cmluZyBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX1NUUklOR19GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFTdHJpbmdGaWVsZCcsXG4gIGRlc2NyaXB0aW9uOiAnVGhlIFNjaGVtYVN0cmluZ0ZpZWxkIGlzIHVzZWQgdG8gcmV0dXJuIGluZm9ybWF0aW9uIG9mIGEgU3RyaW5nIGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX05VTUJFUl9GSUVMRF9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYU51bWJlckZpZWxkSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYU51bWJlckZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSBudW1iZXIgZm9yIGFuIG9iamVjdCBjbGFzcyBzY2hlbWEuJyxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9OVU1CRVJfRklFTEQgPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hTnVtYmVyRmllbGQnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBTY2hlbWFOdW1iZXJGaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhIE51bWJlciBmaWVsZC4nLFxuICBpbnRlcmZhY2VzOiBbU0NIRU1BX0ZJRUxEXSxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9CT09MRUFOX0ZJRUxEX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hQm9vbGVhbkZpZWxkSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYUJvb2xlYW5GaWVsZElucHV0IGlzIHVzZWQgdG8gc3BlY2lmeSBhIGZpZWxkIG9mIHR5cGUgYm9vbGVhbiBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0JPT0xFQU5fRklFTEQgPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hQm9vbGVhbkZpZWxkJyxcbiAgZGVzY3JpcHRpb246ICdUaGUgU2NoZW1hQm9vbGVhbkZpZWxkIGlzIHVzZWQgdG8gcmV0dXJuIGluZm9ybWF0aW9uIG9mIGEgQm9vbGVhbiBmaWVsZC4nLFxuICBpbnRlcmZhY2VzOiBbU0NIRU1BX0ZJRUxEXSxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9BUlJBWV9GSUVMRF9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYUFycmF5RmllbGRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hQXJyYXlGaWVsZElucHV0IGlzIHVzZWQgdG8gc3BlY2lmeSBhIGZpZWxkIG9mIHR5cGUgYXJyYXkgZm9yIGFuIG9iamVjdCBjbGFzcyBzY2hlbWEuJyxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9BUlJBWV9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFBcnJheUZpZWxkJyxcbiAgZGVzY3JpcHRpb246ICdUaGUgU2NoZW1hQXJyYXlGaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhbiBBcnJheSBmaWVsZC4nLFxuICBpbnRlcmZhY2VzOiBbU0NIRU1BX0ZJRUxEXSxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9PQkpFQ1RfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFPYmplY3RGaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFPYmplY3RGaWVsZElucHV0IGlzIHVzZWQgdG8gc3BlY2lmeSBhIGZpZWxkIG9mIHR5cGUgb2JqZWN0IGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfT0JKRUNUX0ZJRUxEID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYU9iamVjdEZpZWxkJyxcbiAgZGVzY3JpcHRpb246ICdUaGUgU2NoZW1hT2JqZWN0RmllbGQgaXMgdXNlZCB0byByZXR1cm4gaW5mb3JtYXRpb24gb2YgYW4gT2JqZWN0IGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0RBVEVfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFEYXRlRmllbGRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hRGF0ZUZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSBkYXRlIGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfREFURV9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFEYXRlRmllbGQnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBTY2hlbWFEYXRlRmllbGQgaXMgdXNlZCB0byByZXR1cm4gaW5mb3JtYXRpb24gb2YgYSBEYXRlIGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0ZJTEVfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFGaWxlRmllbGRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hRmlsZUZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSBmaWxlIGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfRklMRV9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFGaWxlRmllbGQnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBTY2hlbWFGaWxlRmllbGQgaXMgdXNlZCB0byByZXR1cm4gaW5mb3JtYXRpb24gb2YgYSBGaWxlIGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0dFT19QT0lOVF9GSUVMRF9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYUdlb1BvaW50RmllbGRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hR2VvUG9pbnRGaWVsZElucHV0IGlzIHVzZWQgdG8gc3BlY2lmeSBhIGZpZWxkIG9mIHR5cGUgZ2VvIHBvaW50IGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfR0VPX1BPSU5UX0ZJRUxEID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYUdlb1BvaW50RmllbGQnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBTY2hlbWFHZW9Qb2ludEZpZWxkIGlzIHVzZWQgdG8gcmV0dXJuIGluZm9ybWF0aW9uIG9mIGEgR2VvIFBvaW50IGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX1BPTFlHT05fRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFQb2x5Z29uRmllbGRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hUG9seWdvbkZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSBwb2x5Z29uIGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfUE9MWUdPTl9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFQb2x5Z29uRmllbGQnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBTY2hlbWFQb2x5Z29uRmllbGQgaXMgdXNlZCB0byByZXR1cm4gaW5mb3JtYXRpb24gb2YgYSBQb2x5Z29uIGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0JZVEVTX0ZJRUxEX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hQnl0ZXNGaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFCeXRlc0ZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSBieXRlcyBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0JZVEVTX0ZJRUxEID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYUJ5dGVzRmllbGQnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBTY2hlbWFCeXRlc0ZpZWxkIGlzIHVzZWQgdG8gcmV0dXJuIGluZm9ybWF0aW9uIG9mIGEgQnl0ZXMgZmllbGQuJyxcbiAgaW50ZXJmYWNlczogW1NDSEVNQV9GSUVMRF0sXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBUQVJHRVRfQ0xBU1NfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIG5hbWUgb2YgdGhlIHRhcmdldCBjbGFzcyBmb3IgdGhlIGZpZWxkLicsXG4gIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbn07XG5cbmNvbnN0IFNDSEVNQV9QT0lOVEVSX0ZJRUxEX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnUG9pbnRlckZpZWxkSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFBvaW50ZXJGaWVsZElucHV0IGlzIHVzZWQgdG8gc3BlY2lmeSBhIGZpZWxkIG9mIHR5cGUgcG9pbnRlciBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gICAgdGFyZ2V0Q2xhc3NOYW1lOiBUQVJHRVRfQ0xBU1NfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9QT0lOVEVSX0ZJRUxEID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYVBvaW50ZXJGaWVsZCcsXG4gIGRlc2NyaXB0aW9uOiAnVGhlIFNjaGVtYVBvaW50ZXJGaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhIFBvaW50ZXIgZmllbGQuJyxcbiAgaW50ZXJmYWNlczogW1NDSEVNQV9GSUVMRF0sXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgICB0YXJnZXRDbGFzc05hbWU6IFRBUkdFVF9DTEFTU19BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX1JFTEFUSU9OX0ZJRUxEX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnUmVsYXRpb25GaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBSZWxhdGlvbkZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSByZWxhdGlvbiBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gICAgdGFyZ2V0Q2xhc3NOYW1lOiBUQVJHRVRfQ0xBU1NfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9SRUxBVElPTl9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFSZWxhdGlvbkZpZWxkJyxcbiAgZGVzY3JpcHRpb246ICdUaGUgU2NoZW1hUmVsYXRpb25GaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhIFJlbGF0aW9uIGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gICAgdGFyZ2V0Q2xhc3NOYW1lOiBUQVJHRVRfQ0xBU1NfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9BQ0xfRklFTEQgPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hQUNMRmllbGQnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBTY2hlbWFBQ0xGaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhbiBBQ0wgZmllbGQuJyxcbiAgaW50ZXJmYWNlczogW1NDSEVNQV9GSUVMRF0sXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfRklFTERTX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hRmllbGRzSW5wdXQnLFxuICBkZXNjcmlwdGlvbjogYFRoZSBDcmVhdGVDbGFzc1NjaGVtYUlucHV0IHR5cGUgaXMgdXNlZCB0byBzcGVjaWZ5IHRoZSBzY2hlbWEgZm9yIGEgbmV3IG9iamVjdCBjbGFzcyB0byBiZSBjcmVhdGVkLmAsXG4gIGZpZWxkczoge1xuICAgIGFkZFN0cmluZ3M6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlc2UgYXJlIHRoZSBTdHJpbmcgZmllbGRzIHRvIGJlIGFkZGVkIHRvIHRoZSBjbGFzcyBzY2hlbWEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoU0NIRU1BX1NUUklOR19GSUVMRF9JTlBVVCkpLFxuICAgIH0sXG4gICAgYWRkTnVtYmVyczoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIE51bWJlciBmaWVsZHMgdG8gYmUgYWRkZWQgdG8gdGhlIGNsYXNzIHNjaGVtYS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfTlVNQkVSX0ZJRUxEX0lOUFVUKSksXG4gICAgfSxcbiAgICBhZGRCb29sZWFuczoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIEJvb2xlYW4gZmllbGRzIHRvIGJlIGFkZGVkIHRvIHRoZSBjbGFzcyBzY2hlbWEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoU0NIRU1BX0JPT0xFQU5fRklFTERfSU5QVVQpKSxcbiAgICB9LFxuICAgIGFkZEFycmF5czoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIEFycmF5IGZpZWxkcyB0byBiZSBhZGRlZCB0byB0aGUgY2xhc3Mgc2NoZW1hLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKFNDSEVNQV9BUlJBWV9GSUVMRF9JTlBVVCkpLFxuICAgIH0sXG4gICAgYWRkT2JqZWN0czoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIE9iamVjdCBmaWVsZHMgdG8gYmUgYWRkZWQgdG8gdGhlIGNsYXNzIHNjaGVtYS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfT0JKRUNUX0ZJRUxEX0lOUFVUKSksXG4gICAgfSxcbiAgICBhZGREYXRlczoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIERhdGUgZmllbGRzIHRvIGJlIGFkZGVkIHRvIHRoZSBjbGFzcyBzY2hlbWEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoU0NIRU1BX0RBVEVfRklFTERfSU5QVVQpKSxcbiAgICB9LFxuICAgIGFkZEZpbGVzOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZXNlIGFyZSB0aGUgRmlsZSBmaWVsZHMgdG8gYmUgYWRkZWQgdG8gdGhlIGNsYXNzIHNjaGVtYS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfRklMRV9GSUVMRF9JTlBVVCkpLFxuICAgIH0sXG4gICAgYWRkR2VvUG9pbnQ6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhpcyBpcyB0aGUgR2VvIFBvaW50IGZpZWxkIHRvIGJlIGFkZGVkIHRvIHRoZSBjbGFzcyBzY2hlbWEuIEN1cnJlbnRseSBpdCBpcyBzdXBwb3J0ZWQgb25seSBvbmUgR2VvUG9pbnQgZmllbGQgcGVyIENsYXNzLicsXG4gICAgICB0eXBlOiBTQ0hFTUFfR0VPX1BPSU5UX0ZJRUxEX0lOUFVULFxuICAgIH0sXG4gICAgYWRkUG9seWdvbnM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlc2UgYXJlIHRoZSBQb2x5Z29uIGZpZWxkcyB0byBiZSBhZGRlZCB0byB0aGUgY2xhc3Mgc2NoZW1hLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKFNDSEVNQV9QT0xZR09OX0ZJRUxEX0lOUFVUKSksXG4gICAgfSxcbiAgICBhZGRCeXRlczoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIEJ5dGVzIGZpZWxkcyB0byBiZSBhZGRlZCB0byB0aGUgY2xhc3Mgc2NoZW1hLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKFNDSEVNQV9CWVRFU19GSUVMRF9JTlBVVCkpLFxuICAgIH0sXG4gICAgYWRkUG9pbnRlcnM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlc2UgYXJlIHRoZSBQb2ludGVyIGZpZWxkcyB0byBiZSBhZGRlZCB0byB0aGUgY2xhc3Mgc2NoZW1hLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKFNDSEVNQV9QT0lOVEVSX0ZJRUxEX0lOUFVUKSksXG4gICAgfSxcbiAgICBhZGRSZWxhdGlvbnM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlc2UgYXJlIHRoZSBSZWxhdGlvbiBmaWVsZHMgdG8gYmUgYWRkZWQgdG8gdGhlIGNsYXNzIHNjaGVtYS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfUkVMQVRJT05fRklFTERfSU5QVVQpKSxcbiAgICB9LFxuICAgIHJlbW92ZToge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIGZpZWxkcyB0byBiZSByZW1vdmVkIGZyb20gdGhlIGNsYXNzIHNjaGVtYS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfRklFTERfSU5QVVQpKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IENMQVNTX05BTUVfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIG5hbWUgb2YgdGhlIG9iamVjdCBjbGFzcy4nLFxuICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG59O1xuXG5jb25zdCBDTEFTUyA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdDbGFzcycsXG4gIGRlc2NyaXB0aW9uOiBgVGhlIENsYXNzIHR5cGUgaXMgdXNlZCB0byByZXR1cm4gdGhlIGluZm9ybWF0aW9uIGFib3V0IGFuIG9iamVjdCBjbGFzcy5gLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBDTEFTU19OQU1FX0FUVCxcbiAgICBzY2hlbWFGaWVsZHM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlRoZXNlIGFyZSB0aGUgc2NoZW1hJ3MgZmllbGRzIG9mIHRoZSBvYmplY3QgY2xhc3MuXCIsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwobmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfRklFTEQpKSksXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBsb2FkID0gcGFyc2VHcmFwaFFMU2NoZW1hID0+IHtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfU1RSSU5HX0ZJRUxEX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9TVFJJTkdfRklFTEQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX05VTUJFUl9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfTlVNQkVSX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9CT09MRUFOX0ZJRUxEX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9CT09MRUFOX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9BUlJBWV9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfQVJSQVlfRklFTEQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX09CSkVDVF9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfT0JKRUNUX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9EQVRFX0ZJRUxEX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9EQVRFX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9GSUxFX0ZJRUxEX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9GSUxFX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9HRU9fUE9JTlRfRklFTERfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX0dFT19QT0lOVF9GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfUE9MWUdPTl9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfUE9MWUdPTl9GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfQllURVNfRklFTERfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX0JZVEVTX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9QT0lOVEVSX0ZJRUxEX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9QT0lOVEVSX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9SRUxBVElPTl9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfUkVMQVRJT05fRklFTEQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX0FDTF9GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfRklFTERTX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKENMQVNTLCB0cnVlKTtcbn07XG5cbmV4cG9ydCB7XG4gIFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgU0NIRU1BX0ZJRUxEX0lOUFVULFxuICBTQ0hFTUFfU1RSSU5HX0ZJRUxEX0lOUFVULFxuICBTQ0hFTUFfU1RSSU5HX0ZJRUxELFxuICBTQ0hFTUFfTlVNQkVSX0ZJRUxEX0lOUFVULFxuICBTQ0hFTUFfTlVNQkVSX0ZJRUxELFxuICBTQ0hFTUFfQk9PTEVBTl9GSUVMRF9JTlBVVCxcbiAgU0NIRU1BX0JPT0xFQU5fRklFTEQsXG4gIFNDSEVNQV9BUlJBWV9GSUVMRF9JTlBVVCxcbiAgU0NIRU1BX0FSUkFZX0ZJRUxELFxuICBTQ0hFTUFfT0JKRUNUX0ZJRUxEX0lOUFVULFxuICBTQ0hFTUFfT0JKRUNUX0ZJRUxELFxuICBTQ0hFTUFfREFURV9GSUVMRF9JTlBVVCxcbiAgU0NIRU1BX0RBVEVfRklFTEQsXG4gIFNDSEVNQV9GSUxFX0ZJRUxEX0lOUFVULFxuICBTQ0hFTUFfRklMRV9GSUVMRCxcbiAgU0NIRU1BX0dFT19QT0lOVF9GSUVMRF9JTlBVVCxcbiAgU0NIRU1BX0dFT19QT0lOVF9GSUVMRCxcbiAgU0NIRU1BX1BPTFlHT05fRklFTERfSU5QVVQsXG4gIFNDSEVNQV9QT0xZR09OX0ZJRUxELFxuICBTQ0hFTUFfQllURVNfRklFTERfSU5QVVQsXG4gIFNDSEVNQV9CWVRFU19GSUVMRCxcbiAgVEFSR0VUX0NMQVNTX0FUVCxcbiAgU0NIRU1BX1BPSU5URVJfRklFTERfSU5QVVQsXG4gIFNDSEVNQV9QT0lOVEVSX0ZJRUxELFxuICBTQ0hFTUFfUkVMQVRJT05fRklFTERfSU5QVVQsXG4gIFNDSEVNQV9SRUxBVElPTl9GSUVMRCxcbiAgU0NIRU1BX0FDTF9GSUVMRCxcbiAgU0NIRU1BX0ZJRUxEU19JTlBVVCxcbiAgQ0xBU1NfTkFNRV9BVFQsXG4gIENMQVNTLFxuICBsb2FkLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/usersMutations.js b/lib/GraphQL/loaders/usersMutations.js new file mode 100644 index 0000000000..9170c52015 --- /dev/null +++ b/lib/GraphQL/loaders/usersMutations.js @@ -0,0 +1,332 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.load = void 0; + +var _graphql = require("graphql"); + +var _graphqlRelay = require("graphql-relay"); + +var _UsersRouter = _interopRequireDefault(require("../../Routers/UsersRouter")); + +var objectsMutations = _interopRequireWildcard(require("../helpers/objectsMutations")); + +var _defaultGraphQLTypes = require("./defaultGraphQLTypes"); + +var _usersQueries = require("./usersQueries"); + +var _mutation = require("../transformers/mutation"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const usersRouter = new _UsersRouter.default(); + +const load = parseGraphQLSchema => { + if (parseGraphQLSchema.isUsersClassDisabled) { + return; + } + + const signUpMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'SignUp', + description: 'The signUp mutation can be used to create and sign up a new user.', + inputFields: { + fields: { + descriptions: 'These are the fields of the new user to be created and signed up.', + type: parseGraphQLSchema.parseClassTypes['_User'].classGraphQLCreateType + } + }, + outputFields: { + viewer: { + description: 'This is the new user that was created, signed up and returned as a viewer.', + type: new _graphql.GraphQLNonNull(parseGraphQLSchema.viewerType) + } + }, + mutateAndGetPayload: async (args, context, mutationInfo) => { + try { + const { + fields + } = args; + const { + config, + auth, + info + } = context; + const parseFields = await (0, _mutation.transformTypes)('create', fields, { + className: '_User', + parseGraphQLSchema, + req: { + config, + auth, + info + } + }); + const { + sessionToken, + objectId + } = await objectsMutations.createObject('_User', parseFields, config, auth, info); + context.info.sessionToken = sessionToken; + return { + viewer: await (0, _usersQueries.getUserFromSessionToken)(context, mutationInfo, 'viewer.user.', objectId) + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(signUpMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(signUpMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('signUp', signUpMutation, true, true); + const logInWithMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'LogInWith', + description: 'The logInWith mutation can be used to signup, login user with 3rd party authentication system. This mutation create a user if the authData do not correspond to an existing one.', + inputFields: { + authData: { + descriptions: 'This is the auth data of your custom auth provider', + type: new _graphql.GraphQLNonNull(_defaultGraphQLTypes.OBJECT) + }, + fields: { + descriptions: 'These are the fields of the user to be created/updated and logged in.', + type: new _graphql.GraphQLInputObjectType({ + name: 'UserLoginWithInput', + fields: () => { + const classGraphQLCreateFields = parseGraphQLSchema.parseClassTypes['_User'].classGraphQLCreateType.getFields(); + return Object.keys(classGraphQLCreateFields).reduce((fields, fieldName) => { + if (fieldName !== 'password' && fieldName !== 'username' && fieldName !== 'authData') { + fields[fieldName] = classGraphQLCreateFields[fieldName]; + } + + return fields; + }, {}); + } + }) + } + }, + outputFields: { + viewer: { + description: 'This is the new user that was created, signed up and returned as a viewer.', + type: new _graphql.GraphQLNonNull(parseGraphQLSchema.viewerType) + } + }, + mutateAndGetPayload: async (args, context, mutationInfo) => { + try { + const { + fields, + authData + } = args; + const { + config, + auth, + info + } = context; + const parseFields = await (0, _mutation.transformTypes)('create', fields, { + className: '_User', + parseGraphQLSchema, + req: { + config, + auth, + info + } + }); + const { + sessionToken, + objectId + } = await objectsMutations.createObject('_User', _objectSpread(_objectSpread({}, parseFields), {}, { + authData + }), config, auth, info); + context.info.sessionToken = sessionToken; + return { + viewer: await (0, _usersQueries.getUserFromSessionToken)(context, mutationInfo, 'viewer.user.', objectId) + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(logInWithMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(logInWithMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('logInWith', logInWithMutation, true, true); + const logInMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'LogIn', + description: 'The logIn mutation can be used to log in an existing user.', + inputFields: { + username: { + description: 'This is the username used to log in the user.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + }, + password: { + description: 'This is the password used to log in the user.', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + } + }, + outputFields: { + viewer: { + description: 'This is the existing user that was logged in and returned as a viewer.', + type: new _graphql.GraphQLNonNull(parseGraphQLSchema.viewerType) + } + }, + mutateAndGetPayload: async (args, context, mutationInfo) => { + try { + const { + username, + password + } = args; + const { + config, + auth, + info + } = context; + const { + sessionToken, + objectId + } = (await usersRouter.handleLogIn({ + body: { + username, + password + }, + query: {}, + config, + auth, + info + })).response; + context.info.sessionToken = sessionToken; + return { + viewer: await (0, _usersQueries.getUserFromSessionToken)(context, mutationInfo, 'viewer.user.', objectId) + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(logInMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(logInMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('logIn', logInMutation, true, true); + const logOutMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'LogOut', + description: 'The logOut mutation can be used to log out an existing user.', + outputFields: { + ok: { + description: "It's always true.", + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + } + }, + mutateAndGetPayload: async (_args, context) => { + try { + const { + config, + auth, + info + } = context; + await usersRouter.handleLogOut({ + config, + auth, + info + }); + return { + ok: true + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(logOutMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(logOutMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('logOut', logOutMutation, true, true); + const resetPasswordMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'ResetPassword', + description: 'The resetPassword mutation can be used to reset the password of an existing user.', + inputFields: { + email: { + descriptions: 'Email of the user that should receive the reset email', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + } + }, + outputFields: { + ok: { + description: "It's always true.", + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + } + }, + mutateAndGetPayload: async ({ + email + }, context) => { + const { + config, + auth, + info + } = context; + await usersRouter.handleResetRequest({ + body: { + email + }, + config, + auth, + info + }); + return { + ok: true + }; + } + }); + parseGraphQLSchema.addGraphQLType(resetPasswordMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(resetPasswordMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('resetPassword', resetPasswordMutation, true, true); + const sendVerificationEmailMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ + name: 'SendVerificationEmail', + description: 'The sendVerificationEmail mutation can be used to send the verification email again.', + inputFields: { + email: { + descriptions: 'Email of the user that should receive the verification email', + type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) + } + }, + outputFields: { + ok: { + description: "It's always true.", + type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) + } + }, + mutateAndGetPayload: async ({ + email + }, context) => { + try { + const { + config, + auth, + info + } = context; + await usersRouter.handleVerificationEmailRequest({ + body: { + email + }, + config, + auth, + info + }); + return { + ok: true + }; + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + }); + parseGraphQLSchema.addGraphQLType(sendVerificationEmailMutation.args.input.type.ofType, true, true); + parseGraphQLSchema.addGraphQLType(sendVerificationEmailMutation.type, true, true); + parseGraphQLSchema.addGraphQLMutation('sendVerificationEmail', sendVerificationEmailMutation, true, true); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvdXNlcnNNdXRhdGlvbnMuanMiXSwibmFtZXMiOlsidXNlcnNSb3V0ZXIiLCJVc2Vyc1JvdXRlciIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJpc1VzZXJzQ2xhc3NEaXNhYmxlZCIsInNpZ25VcE11dGF0aW9uIiwibmFtZSIsImRlc2NyaXB0aW9uIiwiaW5wdXRGaWVsZHMiLCJmaWVsZHMiLCJkZXNjcmlwdGlvbnMiLCJ0eXBlIiwicGFyc2VDbGFzc1R5cGVzIiwiY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSIsIm91dHB1dEZpZWxkcyIsInZpZXdlciIsIkdyYXBoUUxOb25OdWxsIiwidmlld2VyVHlwZSIsIm11dGF0ZUFuZEdldFBheWxvYWQiLCJhcmdzIiwiY29udGV4dCIsIm11dGF0aW9uSW5mbyIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwicGFyc2VGaWVsZHMiLCJjbGFzc05hbWUiLCJyZXEiLCJzZXNzaW9uVG9rZW4iLCJvYmplY3RJZCIsIm9iamVjdHNNdXRhdGlvbnMiLCJjcmVhdGVPYmplY3QiLCJlIiwiaGFuZGxlRXJyb3IiLCJhZGRHcmFwaFFMVHlwZSIsImlucHV0Iiwib2ZUeXBlIiwiYWRkR3JhcGhRTE11dGF0aW9uIiwibG9nSW5XaXRoTXV0YXRpb24iLCJhdXRoRGF0YSIsIk9CSkVDVCIsIkdyYXBoUUxJbnB1dE9iamVjdFR5cGUiLCJjbGFzc0dyYXBoUUxDcmVhdGVGaWVsZHMiLCJnZXRGaWVsZHMiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwiZmllbGROYW1lIiwibG9nSW5NdXRhdGlvbiIsInVzZXJuYW1lIiwiR3JhcGhRTFN0cmluZyIsInBhc3N3b3JkIiwiaGFuZGxlTG9nSW4iLCJib2R5IiwicXVlcnkiLCJyZXNwb25zZSIsImxvZ091dE11dGF0aW9uIiwib2siLCJHcmFwaFFMQm9vbGVhbiIsIl9hcmdzIiwiaGFuZGxlTG9nT3V0IiwicmVzZXRQYXNzd29yZE11dGF0aW9uIiwiZW1haWwiLCJoYW5kbGVSZXNldFJlcXVlc3QiLCJzZW5kVmVyaWZpY2F0aW9uRW1haWxNdXRhdGlvbiIsImhhbmRsZVZlcmlmaWNhdGlvbkVtYWlsUmVxdWVzdCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7Ozs7Ozs7OztBQUVBLE1BQU1BLFdBQVcsR0FBRyxJQUFJQyxvQkFBSixFQUFwQjs7QUFFQSxNQUFNQyxJQUFJLEdBQUdDLGtCQUFrQixJQUFJO0FBQ2pDLE1BQUlBLGtCQUFrQixDQUFDQyxvQkFBdkIsRUFBNkM7QUFDM0M7QUFDRDs7QUFFRCxRQUFNQyxjQUFjLEdBQUcsZ0RBQTZCO0FBQ2xEQyxJQUFBQSxJQUFJLEVBQUUsUUFENEM7QUFFbERDLElBQUFBLFdBQVcsRUFBRSxtRUFGcUM7QUFHbERDLElBQUFBLFdBQVcsRUFBRTtBQUNYQyxNQUFBQSxNQUFNLEVBQUU7QUFDTkMsUUFBQUEsWUFBWSxFQUFFLG1FQURSO0FBRU5DLFFBQUFBLElBQUksRUFBRVIsa0JBQWtCLENBQUNTLGVBQW5CLENBQW1DLE9BQW5DLEVBQTRDQztBQUY1QztBQURHLEtBSHFDO0FBU2xEQyxJQUFBQSxZQUFZLEVBQUU7QUFDWkMsTUFBQUEsTUFBTSxFQUFFO0FBQ05SLFFBQUFBLFdBQVcsRUFBRSw0RUFEUDtBQUVOSSxRQUFBQSxJQUFJLEVBQUUsSUFBSUssdUJBQUosQ0FBbUJiLGtCQUFrQixDQUFDYyxVQUF0QztBQUZBO0FBREksS0FUb0M7QUFlbERDLElBQUFBLG1CQUFtQixFQUFFLE9BQU9DLElBQVAsRUFBYUMsT0FBYixFQUFzQkMsWUFBdEIsS0FBdUM7QUFDMUQsVUFBSTtBQUNGLGNBQU07QUFBRVosVUFBQUE7QUFBRixZQUFhVSxJQUFuQjtBQUNBLGNBQU07QUFBRUcsVUFBQUEsTUFBRjtBQUFVQyxVQUFBQSxJQUFWO0FBQWdCQyxVQUFBQTtBQUFoQixZQUF5QkosT0FBL0I7QUFFQSxjQUFNSyxXQUFXLEdBQUcsTUFB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QixDQUErQkQsQ0FBL0I7QUFDRDtBQUNGO0FBakNnRSxHQUE3QixDQUF0QztBQW9DQTdCLEVBQUFBLGtCQUFrQixDQUFDK0IsY0FBbkIsQ0FDRThCLDZCQUE2QixDQUFDN0MsSUFBOUIsQ0FBbUNnQixLQUFuQyxDQUF5Q3hCLElBQXpDLENBQThDeUIsTUFEaEQsRUFFRSxJQUZGLEVBR0UsSUFIRjtBQUtBakMsRUFBQUEsa0JBQWtCLENBQUMrQixjQUFuQixDQUFrQzhCLDZCQUE2QixDQUFDckQsSUFBaEUsRUFBc0UsSUFBdEUsRUFBNEUsSUFBNUU7QUFDQVIsRUFBQUEsa0JBQWtCLENBQUNrQyxrQkFBbkIsQ0FDRSx1QkFERixFQUVFMkIsNkJBRkYsRUFHRSxJQUhGLEVBSUUsSUFKRjtBQU1ELENBbFNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgR3JhcGhRTE5vbk51bGwsIEdyYXBoUUxTdHJpbmcsIEdyYXBoUUxCb29sZWFuLCBHcmFwaFFMSW5wdXRPYmplY3RUeXBlIH0gZnJvbSAnZ3JhcGhxbCc7XG5pbXBvcnQgeyBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkIH0gZnJvbSAnZ3JhcGhxbC1yZWxheSc7XG5pbXBvcnQgVXNlcnNSb3V0ZXIgZnJvbSAnLi4vLi4vUm91dGVycy9Vc2Vyc1JvdXRlcic7XG5pbXBvcnQgKiBhcyBvYmplY3RzTXV0YXRpb25zIGZyb20gJy4uL2hlbHBlcnMvb2JqZWN0c011dGF0aW9ucyc7XG5pbXBvcnQgeyBPQkpFQ1QgfSBmcm9tICcuL2RlZmF1bHRHcmFwaFFMVHlwZXMnO1xuaW1wb3J0IHsgZ2V0VXNlckZyb21TZXNzaW9uVG9rZW4gfSBmcm9tICcuL3VzZXJzUXVlcmllcyc7XG5pbXBvcnQgeyB0cmFuc2Zvcm1UeXBlcyB9IGZyb20gJy4uL3RyYW5zZm9ybWVycy9tdXRhdGlvbic7XG5cbmNvbnN0IHVzZXJzUm91dGVyID0gbmV3IFVzZXJzUm91dGVyKCk7XG5cbmNvbnN0IGxvYWQgPSBwYXJzZUdyYXBoUUxTY2hlbWEgPT4ge1xuICBpZiAocGFyc2VHcmFwaFFMU2NoZW1hLmlzVXNlcnNDbGFzc0Rpc2FibGVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3Qgc2lnblVwTXV0YXRpb24gPSBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkKHtcbiAgICBuYW1lOiAnU2lnblVwJyxcbiAgICBkZXNjcmlwdGlvbjogJ1RoZSBzaWduVXAgbXV0YXRpb24gY2FuIGJlIHVzZWQgdG8gY3JlYXRlIGFuZCBzaWduIHVwIGEgbmV3IHVzZXIuJyxcbiAgICBpbnB1dEZpZWxkczoge1xuICAgICAgZmllbGRzOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uczogJ1RoZXNlIGFyZSB0aGUgZmllbGRzIG9mIHRoZSBuZXcgdXNlciB0byBiZSBjcmVhdGVkIGFuZCBzaWduZWQgdXAuJyxcbiAgICAgICAgdHlwZTogcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1snX1VzZXInXS5jbGFzc0dyYXBoUUxDcmVhdGVUeXBlLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG91dHB1dEZpZWxkczoge1xuICAgICAgdmlld2VyOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgbmV3IHVzZXIgdGhhdCB3YXMgY3JlYXRlZCwgc2lnbmVkIHVwIGFuZCByZXR1cm5lZCBhcyBhIHZpZXdlci4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwocGFyc2VHcmFwaFFMU2NoZW1hLnZpZXdlclR5cGUpLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jIChhcmdzLCBjb250ZXh0LCBtdXRhdGlvbkluZm8pID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgZmllbGRzIH0gPSBhcmdzO1xuICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcblxuICAgICAgICBjb25zdCBwYXJzZUZpZWxkcyA9IGF3YWl0IHRyYW5zZm9ybVR5cGVzKCdjcmVhdGUnLCBmaWVsZHMsIHtcbiAgICAgICAgICBjbGFzc05hbWU6ICdfVXNlcicsXG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLFxuICAgICAgICAgIHJlcTogeyBjb25maWcsIGF1dGgsIGluZm8gfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgeyBzZXNzaW9uVG9rZW4sIG9iamVjdElkIH0gPSBhd2FpdCBvYmplY3RzTXV0YXRpb25zLmNyZWF0ZU9iamVjdChcbiAgICAgICAgICAnX1VzZXInLFxuICAgICAgICAgIHBhcnNlRmllbGRzLFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICBhdXRoLFxuICAgICAgICAgIGluZm9cbiAgICAgICAgKTtcblxuICAgICAgICBjb250ZXh0LmluZm8uc2Vzc2lvblRva2VuID0gc2Vzc2lvblRva2VuO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmlld2VyOiBhd2FpdCBnZXRVc2VyRnJvbVNlc3Npb25Ub2tlbihjb250ZXh0LCBtdXRhdGlvbkluZm8sICd2aWV3ZXIudXNlci4nLCBvYmplY3RJZCksXG4gICAgICAgIH07XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcblxuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoc2lnblVwTXV0YXRpb24uYXJncy5pbnB1dC50eXBlLm9mVHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShzaWduVXBNdXRhdGlvbi50eXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbignc2lnblVwJywgc2lnblVwTXV0YXRpb24sIHRydWUsIHRydWUpO1xuICBjb25zdCBsb2dJbldpdGhNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgIG5hbWU6ICdMb2dJbldpdGgnLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgJ1RoZSBsb2dJbldpdGggbXV0YXRpb24gY2FuIGJlIHVzZWQgdG8gc2lnbnVwLCBsb2dpbiB1c2VyIHdpdGggM3JkIHBhcnR5IGF1dGhlbnRpY2F0aW9uIHN5c3RlbS4gVGhpcyBtdXRhdGlvbiBjcmVhdGUgYSB1c2VyIGlmIHRoZSBhdXRoRGF0YSBkbyBub3QgY29ycmVzcG9uZCB0byBhbiBleGlzdGluZyBvbmUuJyxcbiAgICBpbnB1dEZpZWxkczoge1xuICAgICAgYXV0aERhdGE6IHtcbiAgICAgICAgZGVzY3JpcHRpb25zOiAnVGhpcyBpcyB0aGUgYXV0aCBkYXRhIG9mIHlvdXIgY3VzdG9tIGF1dGggcHJvdmlkZXInLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoT0JKRUNUKSxcbiAgICAgIH0sXG4gICAgICBmaWVsZHM6IHtcbiAgICAgICAgZGVzY3JpcHRpb25zOiAnVGhlc2UgYXJlIHRoZSBmaWVsZHMgb2YgdGhlIHVzZXIgdG8gYmUgY3JlYXRlZC91cGRhdGVkIGFuZCBsb2dnZWQgaW4uJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICAgICAgICAgIG5hbWU6ICdVc2VyTG9naW5XaXRoSW5wdXQnLFxuICAgICAgICAgIGZpZWxkczogKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY2xhc3NHcmFwaFFMQ3JlYXRlRmllbGRzID0gcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1tcbiAgICAgICAgICAgICAgJ19Vc2VyJ1xuICAgICAgICAgICAgXS5jbGFzc0dyYXBoUUxDcmVhdGVUeXBlLmdldEZpZWxkcygpO1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKGNsYXNzR3JhcGhRTENyZWF0ZUZpZWxkcykucmVkdWNlKChmaWVsZHMsIGZpZWxkTmFtZSkgPT4ge1xuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgZmllbGROYW1lICE9PSAncGFzc3dvcmQnICYmXG4gICAgICAgICAgICAgICAgZmllbGROYW1lICE9PSAndXNlcm5hbWUnICYmXG4gICAgICAgICAgICAgICAgZmllbGROYW1lICE9PSAnYXV0aERhdGEnXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGZpZWxkc1tmaWVsZE5hbWVdID0gY2xhc3NHcmFwaFFMQ3JlYXRlRmllbGRzW2ZpZWxkTmFtZV07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIGZpZWxkcztcbiAgICAgICAgICAgIH0sIHt9KTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgIHZpZXdlcjoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIG5ldyB1c2VyIHRoYXQgd2FzIGNyZWF0ZWQsIHNpZ25lZCB1cCBhbmQgcmV0dXJuZWQgYXMgYSB2aWV3ZXIuJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKHBhcnNlR3JhcGhRTFNjaGVtYS52aWV3ZXJUeXBlKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBtdXRhdGVBbmRHZXRQYXlsb2FkOiBhc3luYyAoYXJncywgY29udGV4dCwgbXV0YXRpb25JbmZvKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB7IGZpZWxkcywgYXV0aERhdGEgfSA9IGFyZ3M7XG4gICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuXG4gICAgICAgIGNvbnN0IHBhcnNlRmllbGRzID0gYXdhaXQgdHJhbnNmb3JtVHlwZXMoJ2NyZWF0ZScsIGZpZWxkcywge1xuICAgICAgICAgIGNsYXNzTmFtZTogJ19Vc2VyJyxcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEsXG4gICAgICAgICAgcmVxOiB7IGNvbmZpZywgYXV0aCwgaW5mbyB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB7IHNlc3Npb25Ub2tlbiwgb2JqZWN0SWQgfSA9IGF3YWl0IG9iamVjdHNNdXRhdGlvbnMuY3JlYXRlT2JqZWN0KFxuICAgICAgICAgICdfVXNlcicsXG4gICAgICAgICAgeyAuLi5wYXJzZUZpZWxkcywgYXV0aERhdGEgfSxcbiAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgYXV0aCxcbiAgICAgICAgICBpbmZvXG4gICAgICAgICk7XG5cbiAgICAgICAgY29udGV4dC5pbmZvLnNlc3Npb25Ub2tlbiA9IHNlc3Npb25Ub2tlbjtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHZpZXdlcjogYXdhaXQgZ2V0VXNlckZyb21TZXNzaW9uVG9rZW4oY29udGV4dCwgbXV0YXRpb25JbmZvLCAndmlld2VyLnVzZXIuJywgb2JqZWN0SWQpLFxuICAgICAgICB9O1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGxvZ0luV2l0aE11dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGUsIHRydWUsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUobG9nSW5XaXRoTXV0YXRpb24udHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oJ2xvZ0luV2l0aCcsIGxvZ0luV2l0aE11dGF0aW9uLCB0cnVlLCB0cnVlKTtcblxuICBjb25zdCBsb2dJbk11dGF0aW9uID0gbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCh7XG4gICAgbmFtZTogJ0xvZ0luJyxcbiAgICBkZXNjcmlwdGlvbjogJ1RoZSBsb2dJbiBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBsb2cgaW4gYW4gZXhpc3RpbmcgdXNlci4nLFxuICAgIGlucHV0RmllbGRzOiB7XG4gICAgICB1c2VybmFtZToge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIHVzZXJuYW1lIHVzZWQgdG8gbG9nIGluIHRoZSB1c2VyLicsXG4gICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbiAgICAgIH0sXG4gICAgICBwYXNzd29yZDoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIHBhc3N3b3JkIHVzZWQgdG8gbG9nIGluIHRoZSB1c2VyLicsXG4gICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgIHZpZXdlcjoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGV4aXN0aW5nIHVzZXIgdGhhdCB3YXMgbG9nZ2VkIGluIGFuZCByZXR1cm5lZCBhcyBhIHZpZXdlci4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwocGFyc2VHcmFwaFFMU2NoZW1hLnZpZXdlclR5cGUpLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jIChhcmdzLCBjb250ZXh0LCBtdXRhdGlvbkluZm8pID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgdXNlcm5hbWUsIHBhc3N3b3JkIH0gPSBhcmdzO1xuICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcblxuICAgICAgICBjb25zdCB7IHNlc3Npb25Ub2tlbiwgb2JqZWN0SWQgfSA9IChcbiAgICAgICAgICBhd2FpdCB1c2Vyc1JvdXRlci5oYW5kbGVMb2dJbih7XG4gICAgICAgICAgICBib2R5OiB7XG4gICAgICAgICAgICAgIHVzZXJuYW1lLFxuICAgICAgICAgICAgICBwYXNzd29yZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBxdWVyeToge30sXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICB9KVxuICAgICAgICApLnJlc3BvbnNlO1xuXG4gICAgICAgIGNvbnRleHQuaW5mby5zZXNzaW9uVG9rZW4gPSBzZXNzaW9uVG9rZW47XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB2aWV3ZXI6IGF3YWl0IGdldFVzZXJGcm9tU2Vzc2lvblRva2VuKGNvbnRleHQsIG11dGF0aW9uSW5mbywgJ3ZpZXdlci51c2VyLicsIG9iamVjdElkKSxcbiAgICAgICAgfTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShsb2dJbk11dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGUsIHRydWUsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUobG9nSW5NdXRhdGlvbi50eXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbignbG9nSW4nLCBsb2dJbk11dGF0aW9uLCB0cnVlLCB0cnVlKTtcblxuICBjb25zdCBsb2dPdXRNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgIG5hbWU6ICdMb2dPdXQnLFxuICAgIGRlc2NyaXB0aW9uOiAnVGhlIGxvZ091dCBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBsb2cgb3V0IGFuIGV4aXN0aW5nIHVzZXIuJyxcbiAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgIG9rOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIkl0J3MgYWx3YXlzIHRydWUuXCIsXG4gICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMQm9vbGVhbiksXG4gICAgICB9LFxuICAgIH0sXG4gICAgbXV0YXRlQW5kR2V0UGF5bG9hZDogYXN5bmMgKF9hcmdzLCBjb250ZXh0KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcblxuICAgICAgICBhd2FpdCB1c2Vyc1JvdXRlci5oYW5kbGVMb2dPdXQoe1xuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICBhdXRoLFxuICAgICAgICAgIGluZm8sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB7IG9rOiB0cnVlIH07XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcblxuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUobG9nT3V0TXV0YXRpb24uYXJncy5pbnB1dC50eXBlLm9mVHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShsb2dPdXRNdXRhdGlvbi50eXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbignbG9nT3V0JywgbG9nT3V0TXV0YXRpb24sIHRydWUsIHRydWUpO1xuXG4gIGNvbnN0IHJlc2V0UGFzc3dvcmRNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgIG5hbWU6ICdSZXNldFBhc3N3b3JkJyxcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgICdUaGUgcmVzZXRQYXNzd29yZCBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byByZXNldCB0aGUgcGFzc3dvcmQgb2YgYW4gZXhpc3RpbmcgdXNlci4nLFxuICAgIGlucHV0RmllbGRzOiB7XG4gICAgICBlbWFpbDoge1xuICAgICAgICBkZXNjcmlwdGlvbnM6ICdFbWFpbCBvZiB0aGUgdXNlciB0aGF0IHNob3VsZCByZWNlaXZlIHRoZSByZXNldCBlbWFpbCcsXG4gICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgIG9rOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIkl0J3MgYWx3YXlzIHRydWUuXCIsXG4gICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMQm9vbGVhbiksXG4gICAgICB9LFxuICAgIH0sXG4gICAgbXV0YXRlQW5kR2V0UGF5bG9hZDogYXN5bmMgKHsgZW1haWwgfSwgY29udGV4dCkgPT4ge1xuICAgICAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG5cbiAgICAgIGF3YWl0IHVzZXJzUm91dGVyLmhhbmRsZVJlc2V0UmVxdWVzdCh7XG4gICAgICAgIGJvZHk6IHtcbiAgICAgICAgICBlbWFpbCxcbiAgICAgICAgfSxcbiAgICAgICAgY29uZmlnLFxuICAgICAgICBhdXRoLFxuICAgICAgICBpbmZvLFxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB7IG9rOiB0cnVlIH07XG4gICAgfSxcbiAgfSk7XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKHJlc2V0UGFzc3dvcmRNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKHJlc2V0UGFzc3dvcmRNdXRhdGlvbi50eXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbigncmVzZXRQYXNzd29yZCcsIHJlc2V0UGFzc3dvcmRNdXRhdGlvbiwgdHJ1ZSwgdHJ1ZSk7XG5cbiAgY29uc3Qgc2VuZFZlcmlmaWNhdGlvbkVtYWlsTXV0YXRpb24gPSBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkKHtcbiAgICBuYW1lOiAnU2VuZFZlcmlmaWNhdGlvbkVtYWlsJyxcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgICdUaGUgc2VuZFZlcmlmaWNhdGlvbkVtYWlsIG11dGF0aW9uIGNhbiBiZSB1c2VkIHRvIHNlbmQgdGhlIHZlcmlmaWNhdGlvbiBlbWFpbCBhZ2Fpbi4nLFxuICAgIGlucHV0RmllbGRzOiB7XG4gICAgICBlbWFpbDoge1xuICAgICAgICBkZXNjcmlwdGlvbnM6ICdFbWFpbCBvZiB0aGUgdXNlciB0aGF0IHNob3VsZCByZWNlaXZlIHRoZSB2ZXJpZmljYXRpb24gZW1haWwnLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgICB9LFxuICAgIH0sXG4gICAgb3V0cHV0RmllbGRzOiB7XG4gICAgICBvazoge1xuICAgICAgICBkZXNjcmlwdGlvbjogXCJJdCdzIGFsd2F5cyB0cnVlLlwiLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jICh7IGVtYWlsIH0sIGNvbnRleHQpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuXG4gICAgICAgIGF3YWl0IHVzZXJzUm91dGVyLmhhbmRsZVZlcmlmaWNhdGlvbkVtYWlsUmVxdWVzdCh7XG4gICAgICAgICAgYm9keToge1xuICAgICAgICAgICAgZW1haWwsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgYXV0aCxcbiAgICAgICAgICBpbmZvLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4geyBvazogdHJ1ZSB9O1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFxuICAgIHNlbmRWZXJpZmljYXRpb25FbWFpbE11dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGUsXG4gICAgdHJ1ZSxcbiAgICB0cnVlXG4gICk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShzZW5kVmVyaWZpY2F0aW9uRW1haWxNdXRhdGlvbi50eXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbihcbiAgICAnc2VuZFZlcmlmaWNhdGlvbkVtYWlsJyxcbiAgICBzZW5kVmVyaWZpY2F0aW9uRW1haWxNdXRhdGlvbixcbiAgICB0cnVlLFxuICAgIHRydWVcbiAgKTtcbn07XG5cbmV4cG9ydCB7IGxvYWQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/usersQueries.js b/lib/GraphQL/loaders/usersQueries.js new file mode 100644 index 0000000000..a085211ef6 --- /dev/null +++ b/lib/GraphQL/loaders/usersQueries.js @@ -0,0 +1,111 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.getUserFromSessionToken = exports.load = void 0; + +var _graphql = require("graphql"); + +var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); + +var _node = _interopRequireDefault(require("parse/node")); + +var _rest = _interopRequireDefault(require("../../rest")); + +var _parseClassTypes = require("./parseClassTypes"); + +var _Auth = require("../../Auth"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const getUserFromSessionToken = async (context, queryInfo, keysPrefix, userId) => { + const { + info, + config + } = context; + + if (!info || !info.sessionToken) { + throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); + } + + const sessionToken = info.sessionToken; + const selectedFields = (0, _graphqlListFields.default)(queryInfo).filter(field => field.startsWith(keysPrefix)).map(field => field.replace(keysPrefix, '')); + const keysAndInclude = (0, _parseClassTypes.extractKeysAndInclude)(selectedFields); + const { + keys + } = keysAndInclude; + let { + include + } = keysAndInclude; + + if (userId && !keys && !include) { + return { + sessionToken + }; + } else if (keys && !include) { + include = 'user'; + } + + if (userId) { + // We need to re create the auth context + // to avoid security breach if userId is provided + context.auth = new _Auth.Auth({ + config, + isMaster: context.auth.isMaster, + user: { + id: userId + } + }); + } + + const options = {}; + + if (keys) { + options.keys = keys.split(',').map(key => `${key}`).join(','); + } + + if (include) { + options.include = include.split(',').map(included => `${included}`).join(','); + } + + const response = await _rest.default.find(config, context.auth, '_User', // Get the user it self from auth object + { + objectId: context.auth.user.id + }, options, info.clientVersion, info.context); + + if (!response.results || response.results.length == 0) { + throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); + } else { + const user = response.results[0]; + return { + sessionToken, + user + }; + } +}; + +exports.getUserFromSessionToken = getUserFromSessionToken; + +const load = parseGraphQLSchema => { + if (parseGraphQLSchema.isUsersClassDisabled) { + return; + } + + parseGraphQLSchema.addGraphQLQuery('viewer', { + description: 'The viewer query can be used to return the current user data.', + type: new _graphql.GraphQLNonNull(parseGraphQLSchema.viewerType), + + async resolve(_source, _args, context, queryInfo) { + try { + return await getUserFromSessionToken(context, queryInfo, 'user.', false); + } catch (e) { + parseGraphQLSchema.handleError(e); + } + } + + }, true, true); +}; + +exports.load = load; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvdXNlcnNRdWVyaWVzLmpzIl0sIm5hbWVzIjpbImdldFVzZXJGcm9tU2Vzc2lvblRva2VuIiwiY29udGV4dCIsInF1ZXJ5SW5mbyIsImtleXNQcmVmaXgiLCJ1c2VySWQiLCJpbmZvIiwiY29uZmlnIiwic2Vzc2lvblRva2VuIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfU0VTU0lPTl9UT0tFTiIsInNlbGVjdGVkRmllbGRzIiwiZmlsdGVyIiwiZmllbGQiLCJzdGFydHNXaXRoIiwibWFwIiwicmVwbGFjZSIsImtleXNBbmRJbmNsdWRlIiwia2V5cyIsImluY2x1ZGUiLCJhdXRoIiwiQXV0aCIsImlzTWFzdGVyIiwidXNlciIsImlkIiwib3B0aW9ucyIsInNwbGl0Iiwia2V5Iiwiam9pbiIsImluY2x1ZGVkIiwicmVzcG9uc2UiLCJyZXN0IiwiZmluZCIsIm9iamVjdElkIiwiY2xpZW50VmVyc2lvbiIsInJlc3VsdHMiLCJsZW5ndGgiLCJsb2FkIiwicGFyc2VHcmFwaFFMU2NoZW1hIiwiaXNVc2Vyc0NsYXNzRGlzYWJsZWQiLCJhZGRHcmFwaFFMUXVlcnkiLCJkZXNjcmlwdGlvbiIsInR5cGUiLCJHcmFwaFFMTm9uTnVsbCIsInZpZXdlclR5cGUiLCJyZXNvbHZlIiwiX3NvdXJjZSIsIl9hcmdzIiwiZSIsImhhbmRsZUVycm9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxNQUFNQSx1QkFBdUIsR0FBRyxPQUFPQyxPQUFQLEVBQWdCQyxTQUFoQixFQUEyQkMsVUFBM0IsRUFBdUNDLE1BQXZDLEtBQWtEO0FBQ2hGLFFBQU07QUFBRUMsSUFBQUEsSUFBRjtBQUFRQyxJQUFBQTtBQUFSLE1BQW1CTCxPQUF6Qjs7QUFDQSxNQUFJLENBQUNJLElBQUQsSUFBUyxDQUFDQSxJQUFJLENBQUNFLFlBQW5CLEVBQWlDO0FBQy9CLFVBQU0sSUFB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Q0FBQ0UsZUFBbkIsQ0FDRSxRQURGLEVBRUU7QUFDRUMsSUFBQUEsV0FBVyxFQUFFLCtEQURmO0FBRUVDLElBQUFBLElBQUksRUFBRSxJQUFJQyx1QkFBSixDQUFtQkwsa0JBQWtCLENBQUNNLFVBQXRDLENBRlI7O0FBR0UsVUFBTUMsT0FBTixDQUFjQyxPQUFkLEVBQXVCQyxLQUF2QixFQUE4QjlDLE9BQTlCLEVBQXVDQyxTQUF2QyxFQUFrRDtBQUNoRCxVQUFJO0FBQ0YsZUFBTyxNQUFNRix1QkFBdUIsQ0FBQ0MsT0FBRCxFQUFVQyxTQUFWLEVBQXFCLE9BQXJCLEVBQThCLEtBQTlCLENBQXBDO0FBQ0QsT0FGRCxDQUVFLE9BQU84QyxDQUFQLEVBQVU7QUFDVlYsUUFBQUEsa0JBQWtCLENBQUNXLFdBQW5CLENBQStCRCxDQUEvQjtBQUNEO0FBQ0Y7O0FBVEgsR0FGRixFQWFFLElBYkYsRUFjRSxJQWRGO0FBZ0JELENBckJEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgR3JhcGhRTE5vbk51bGwgfSBmcm9tICdncmFwaHFsJztcbmltcG9ydCBnZXRGaWVsZE5hbWVzIGZyb20gJ2dyYXBocWwtbGlzdC1maWVsZHMnO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IHJlc3QgZnJvbSAnLi4vLi4vcmVzdCc7XG5pbXBvcnQgeyBleHRyYWN0S2V5c0FuZEluY2x1ZGUgfSBmcm9tICcuL3BhcnNlQ2xhc3NUeXBlcyc7XG5pbXBvcnQgeyBBdXRoIH0gZnJvbSAnLi4vLi4vQXV0aCc7XG5cbmNvbnN0IGdldFVzZXJGcm9tU2Vzc2lvblRva2VuID0gYXN5bmMgKGNvbnRleHQsIHF1ZXJ5SW5mbywga2V5c1ByZWZpeCwgdXNlcklkKSA9PiB7XG4gIGNvbnN0IHsgaW5mbywgY29uZmlnIH0gPSBjb250ZXh0O1xuICBpZiAoIWluZm8gfHwgIWluZm8uc2Vzc2lvblRva2VuKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTiwgJ0ludmFsaWQgc2Vzc2lvbiB0b2tlbicpO1xuICB9XG4gIGNvbnN0IHNlc3Npb25Ub2tlbiA9IGluZm8uc2Vzc2lvblRva2VuO1xuICBjb25zdCBzZWxlY3RlZEZpZWxkcyA9IGdldEZpZWxkTmFtZXMocXVlcnlJbmZvKVxuICAgIC5maWx0ZXIoZmllbGQgPT4gZmllbGQuc3RhcnRzV2l0aChrZXlzUHJlZml4KSlcbiAgICAubWFwKGZpZWxkID0+IGZpZWxkLnJlcGxhY2Uoa2V5c1ByZWZpeCwgJycpKTtcblxuICBjb25zdCBrZXlzQW5kSW5jbHVkZSA9IGV4dHJhY3RLZXlzQW5kSW5jbHVkZShzZWxlY3RlZEZpZWxkcyk7XG4gIGNvbnN0IHsga2V5cyB9ID0ga2V5c0FuZEluY2x1ZGU7XG4gIGxldCB7IGluY2x1ZGUgfSA9IGtleXNBbmRJbmNsdWRlO1xuXG4gIGlmICh1c2VySWQgJiYgIWtleXMgJiYgIWluY2x1ZGUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc2Vzc2lvblRva2VuLFxuICAgIH07XG4gIH0gZWxzZSBpZiAoa2V5cyAmJiAhaW5jbHVkZSkge1xuICAgIGluY2x1ZGUgPSAndXNlcic7XG4gIH1cblxuICBpZiAodXNlcklkKSB7XG4gICAgLy8gV2UgbmVlZCB0byByZSBjcmVhdGUgdGhlIGF1dGggY29udGV4dFxuICAgIC8vIHRvIGF2b2lkIHNlY3VyaXR5IGJyZWFjaCBpZiB1c2VySWQgaXMgcHJvdmlkZWRcbiAgICBjb250ZXh0LmF1dGggPSBuZXcgQXV0aCh7XG4gICAgICBjb25maWcsXG4gICAgICBpc01hc3RlcjogY29udGV4dC5hdXRoLmlzTWFzdGVyLFxuICAgICAgdXNlcjogeyBpZDogdXNlcklkIH0sXG4gICAgfSk7XG4gIH1cblxuICBjb25zdCBvcHRpb25zID0ge307XG4gIGlmIChrZXlzKSB7XG4gICAgb3B0aW9ucy5rZXlzID0ga2V5c1xuICAgICAgLnNwbGl0KCcsJylcbiAgICAgIC5tYXAoa2V5ID0+IGAke2tleX1gKVxuICAgICAgLmpvaW4oJywnKTtcbiAgfVxuICBpZiAoaW5jbHVkZSkge1xuICAgIG9wdGlvbnMuaW5jbHVkZSA9IGluY2x1ZGVcbiAgICAgIC5zcGxpdCgnLCcpXG4gICAgICAubWFwKGluY2x1ZGVkID0+IGAke2luY2x1ZGVkfWApXG4gICAgICAuam9pbignLCcpO1xuICB9XG5cbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCByZXN0LmZpbmQoXG4gICAgY29uZmlnLFxuICAgIGNvbnRleHQuYXV0aCxcbiAgICAnX1VzZXInLFxuICAgIC8vIEdldCB0aGUgdXNlciBpdCBzZWxmIGZyb20gYXV0aCBvYmplY3RcbiAgICB7IG9iamVjdElkOiBjb250ZXh0LmF1dGgudXNlci5pZCB9LFxuICAgIG9wdGlvbnMsXG4gICAgaW5mby5jbGllbnRWZXJzaW9uLFxuICAgIGluZm8uY29udGV4dFxuICApO1xuICBpZiAoIXJlc3BvbnNlLnJlc3VsdHMgfHwgcmVzcG9uc2UucmVzdWx0cy5sZW5ndGggPT0gMCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdJbnZhbGlkIHNlc3Npb24gdG9rZW4nKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCB1c2VyID0gcmVzcG9uc2UucmVzdWx0c1swXTtcbiAgICByZXR1cm4ge1xuICAgICAgc2Vzc2lvblRva2VuLFxuICAgICAgdXNlcixcbiAgICB9O1xuICB9XG59O1xuXG5jb25zdCBsb2FkID0gcGFyc2VHcmFwaFFMU2NoZW1hID0+IHtcbiAgaWYgKHBhcnNlR3JhcGhRTFNjaGVtYS5pc1VzZXJzQ2xhc3NEaXNhYmxlZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMUXVlcnkoXG4gICAgJ3ZpZXdlcicsXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGUgdmlld2VyIHF1ZXJ5IGNhbiBiZSB1c2VkIHRvIHJldHVybiB0aGUgY3VycmVudCB1c2VyIGRhdGEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChwYXJzZUdyYXBoUUxTY2hlbWEudmlld2VyVHlwZSksXG4gICAgICBhc3luYyByZXNvbHZlKF9zb3VyY2UsIF9hcmdzLCBjb250ZXh0LCBxdWVyeUluZm8pIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgZ2V0VXNlckZyb21TZXNzaW9uVG9rZW4oY29udGV4dCwgcXVlcnlJbmZvLCAndXNlci4nLCBmYWxzZSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSxcbiAgICB0cnVlLFxuICAgIHRydWVcbiAgKTtcbn07XG5cbmV4cG9ydCB7IGxvYWQsIGdldFVzZXJGcm9tU2Vzc2lvblRva2VuIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/parseGraphQLUtils.js b/lib/GraphQL/parseGraphQLUtils.js new file mode 100644 index 0000000000..3677a6ca26 --- /dev/null +++ b/lib/GraphQL/parseGraphQLUtils.js @@ -0,0 +1,69 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.enforceMasterKeyAccess = enforceMasterKeyAccess; +exports.toGraphQLError = toGraphQLError; +exports.getParseClassMutationConfig = exports.extractKeysAndInclude = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _apolloServerCore = require("apollo-server-core"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function enforceMasterKeyAccess(auth) { + if (!auth.isMaster) { + throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, 'unauthorized: master key is required'); + } +} + +function toGraphQLError(error) { + let code, message; + + if (error instanceof _node.default.Error) { + code = error.code; + message = error.message; + } else { + code = _node.default.Error.INTERNAL_SERVER_ERROR; + message = 'Internal server error'; + } + + return new _apolloServerCore.ApolloError(message, code); +} + +const extractKeysAndInclude = selectedFields => { + selectedFields = selectedFields.filter(field => !field.includes('__typename')); // Handles "id" field for both current and included objects + + selectedFields = selectedFields.map(field => { + if (field === 'id') return 'objectId'; + return field.endsWith('.id') ? `${field.substring(0, field.lastIndexOf('.id'))}.objectId` : field; + }); + let keys = undefined; + let include = undefined; + + if (selectedFields.length > 0) { + keys = [...new Set(selectedFields)].join(','); // We can use this shortcut since optimization is handled + // later on RestQuery, avoid overhead here. + + include = keys; + } + + return { + // If authData is detected keys will not work properly + // since authData has a special storage behavior + // so we need to skip keys currently + keys: keys && keys.indexOf('authData') === -1 ? keys : undefined, + include + }; +}; + +exports.extractKeysAndInclude = extractKeysAndInclude; + +const getParseClassMutationConfig = function (parseClassConfig) { + return parseClassConfig && parseClassConfig.mutation || {}; +}; + +exports.getParseClassMutationConfig = getParseClassMutationConfig; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9HcmFwaFFML3BhcnNlR3JhcGhRTFV0aWxzLmpzIl0sIm5hbWVzIjpbImVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiLCJhdXRoIiwiaXNNYXN0ZXIiLCJQYXJzZSIsIkVycm9yIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsInRvR3JhcGhRTEVycm9yIiwiZXJyb3IiLCJjb2RlIiwibWVzc2FnZSIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsIkFwb2xsb0Vycm9yIiwiZXh0cmFjdEtleXNBbmRJbmNsdWRlIiwic2VsZWN0ZWRGaWVsZHMiLCJmaWx0ZXIiLCJmaWVsZCIsImluY2x1ZGVzIiwibWFwIiwiZW5kc1dpdGgiLCJzdWJzdHJpbmciLCJsYXN0SW5kZXhPZiIsImtleXMiLCJ1bmRlZmluZWQiLCJpbmNsdWRlIiwibGVuZ3RoIiwiU2V0Iiwiam9pbiIsImluZGV4T2YiLCJnZXRQYXJzZUNsYXNzTXV0YXRpb25Db25maWciLCJwYXJzZUNsYXNzQ29uZmlnIiwibXV0YXRpb24iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBOztBQUNBOzs7O0FBRU8sU0FBU0Esc0JBQVQsQ0FBZ0NDLElBQWhDLEVBQXNDO0FBQzNDLE1BQUksQ0FBQ0EsSUFBSSxDQUFDQyxRQUFWLEVBQW9CO0FBQ2xCLFVBQU0sSUFBSUMsY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZQyxtQkFBNUIsRUFBaUQsc0NBQWpELENBQU47QUFDRDtBQUNGOztBQUVNLFNBQVNDLGNBQVQsQ0FBd0JDLEtBQXhCLEVBQStCO0FBQ3BDLE1BQUlDLElBQUosRUFBVUMsT0FBVjs7QUFDQSxNQUFJRixLQUFLLFlBQVlKLGNBQU1DLEtBQTNCLEVBQWtDO0FBQ2hDSSxJQUFBQSxJQUFJLEdBQUdELEtBQUssQ0FBQ0MsSUFBYjtBQUNBQyxJQUFBQSxPQUFPLEdBQUdGLEtBQUssQ0FBQ0UsT0FBaEI7QUFDRCxHQUhELE1BR087QUFDTEQsSUFBQUEsSUFBSSxHQUFHTCxjQUFNQyxLQUFOLENBQVlNLHFCQUFuQjtBQUNBRCxJQUFBQSxPQUFPLEdBQUcsdUJBQVY7QUFDRDs7QUFDRCxTQUFPLElBQUlFLDZCQUFKLENBQWdCRixPQUFoQixFQUF5QkQsSUFBekIsQ0FBUDtBQUNEOztBQUVNLE1BQU1JLHFCQUFxQixHQUFHQyxjQUFjLElBQUk7QUFDckRBLEVBQUFBLGNBQWMsR0FBR0EsY0FBYyxDQUFDQyxNQUFmLENBQXNCQyxLQUFLLElBQUksQ0FBQ0EsS0FBSyxDQUFDQyxRQUFOLENBQWUsWUFBZixDQUFoQyxDQUFqQixDQURxRCxDQUVyRDs7QUFDQUgsRUFBQUEsY0FBYyxHQUFHQSxjQUFjLENBQUNJLEdBQWYsQ0FBbUJGLEtBQUssSUFBSTtBQUMzQyxRQUFJQSxLQUFLLEtBQUssSUFBZCxFQUFvQixPQUFPLFVBQVA7QUFDcEIsV0FBT0EsS0FBSyxDQUFDRyxRQUFOLENBQWUsS0FBZixJQUNGLEdBQUVILEtBQUssQ0FBQ0ksU0FBTixDQUFnQixDQUFoQixFQUFtQkosS0FBSyxDQUFDSyxXQUFOLENBQWtCLEtBQWxCLENBQW5CLENBQTZDLFdBRDdDLEdBRUhMLEtBRko7QUFHRCxHQUxnQixDQUFqQjtBQU1BLE1BQUlNLElBQUksR0FBR0MsU0FBWDtBQUNBLE1BQUlDLE9BQU8sR0FBR0QsU0FBZDs7QUFFQSxNQUFJVCxjQUFjLENBQUNXLE1BQWYsR0FBd0IsQ0FBNUIsRUFBK0I7QUFDN0JILElBQUFBLElBQUksR0FBRyxDQUFDLEdBQUcsSUFBSUksR0FBSixDQUFRWixjQUFSLENBQUosRUFBNkJhLElBQTdCLENBQWtDLEdBQWxDLENBQVAsQ0FENkIsQ0FFN0I7QUFDQTs7QUFDQUgsSUFBQUEsT0FBTyxHQUFHRixJQUFWO0FBQ0Q7O0FBRUQsU0FBTztBQUNMO0FBQ0E7QUFDQTtBQUNBQSxJQUFBQSxJQUFJLEVBQUVBLElBQUksSUFBSUEsSUFBSSxDQUFDTSxPQUFMLENBQWEsVUFBYixNQUE2QixDQUFDLENBQXRDLEdBQTBDTixJQUExQyxHQUFpREMsU0FKbEQ7QUFLTEMsSUFBQUE7QUFMSyxHQUFQO0FBT0QsQ0ExQk07Ozs7QUE0QkEsTUFBTUssMkJBQTJCLEdBQUcsVUFBVUMsZ0JBQVYsRUFBNEI7QUFDckUsU0FBUUEsZ0JBQWdCLElBQUlBLGdCQUFnQixDQUFDQyxRQUF0QyxJQUFtRCxFQUExRDtBQUNELENBRk0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBBcG9sbG9FcnJvciB9IGZyb20gJ2Fwb2xsby1zZXJ2ZXItY29yZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBlbmZvcmNlTWFzdGVyS2V5QWNjZXNzKGF1dGgpIHtcbiAgaWYgKCFhdXRoLmlzTWFzdGVyKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sICd1bmF1dGhvcml6ZWQ6IG1hc3RlciBrZXkgaXMgcmVxdWlyZWQnKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdG9HcmFwaFFMRXJyb3IoZXJyb3IpIHtcbiAgbGV0IGNvZGUsIG1lc3NhZ2U7XG4gIGlmIChlcnJvciBpbnN0YW5jZW9mIFBhcnNlLkVycm9yKSB7XG4gICAgY29kZSA9IGVycm9yLmNvZGU7XG4gICAgbWVzc2FnZSA9IGVycm9yLm1lc3NhZ2U7XG4gIH0gZWxzZSB7XG4gICAgY29kZSA9IFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUjtcbiAgICBtZXNzYWdlID0gJ0ludGVybmFsIHNlcnZlciBlcnJvcic7XG4gIH1cbiAgcmV0dXJuIG5ldyBBcG9sbG9FcnJvcihtZXNzYWdlLCBjb2RlKTtcbn1cblxuZXhwb3J0IGNvbnN0IGV4dHJhY3RLZXlzQW5kSW5jbHVkZSA9IHNlbGVjdGVkRmllbGRzID0+IHtcbiAgc2VsZWN0ZWRGaWVsZHMgPSBzZWxlY3RlZEZpZWxkcy5maWx0ZXIoZmllbGQgPT4gIWZpZWxkLmluY2x1ZGVzKCdfX3R5cGVuYW1lJykpO1xuICAvLyBIYW5kbGVzIFwiaWRcIiBmaWVsZCBmb3IgYm90aCBjdXJyZW50IGFuZCBpbmNsdWRlZCBvYmplY3RzXG4gIHNlbGVjdGVkRmllbGRzID0gc2VsZWN0ZWRGaWVsZHMubWFwKGZpZWxkID0+IHtcbiAgICBpZiAoZmllbGQgPT09ICdpZCcpIHJldHVybiAnb2JqZWN0SWQnO1xuICAgIHJldHVybiBmaWVsZC5lbmRzV2l0aCgnLmlkJylcbiAgICAgID8gYCR7ZmllbGQuc3Vic3RyaW5nKDAsIGZpZWxkLmxhc3RJbmRleE9mKCcuaWQnKSl9Lm9iamVjdElkYFxuICAgICAgOiBmaWVsZDtcbiAgfSk7XG4gIGxldCBrZXlzID0gdW5kZWZpbmVkO1xuICBsZXQgaW5jbHVkZSA9IHVuZGVmaW5lZDtcblxuICBpZiAoc2VsZWN0ZWRGaWVsZHMubGVuZ3RoID4gMCkge1xuICAgIGtleXMgPSBbLi4ubmV3IFNldChzZWxlY3RlZEZpZWxkcyldLmpvaW4oJywnKTtcbiAgICAvLyBXZSBjYW4gdXNlIHRoaXMgc2hvcnRjdXQgc2luY2Ugb3B0aW1pemF0aW9uIGlzIGhhbmRsZWRcbiAgICAvLyBsYXRlciBvbiBSZXN0UXVlcnksIGF2b2lkIG92ZXJoZWFkIGhlcmUuXG4gICAgaW5jbHVkZSA9IGtleXM7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIC8vIElmIGF1dGhEYXRhIGlzIGRldGVjdGVkIGtleXMgd2lsbCBub3Qgd29yayBwcm9wZXJseVxuICAgIC8vIHNpbmNlIGF1dGhEYXRhIGhhcyBhIHNwZWNpYWwgc3RvcmFnZSBiZWhhdmlvclxuICAgIC8vIHNvIHdlIG5lZWQgdG8gc2tpcCBrZXlzIGN1cnJlbnRseVxuICAgIGtleXM6IGtleXMgJiYga2V5cy5pbmRleE9mKCdhdXRoRGF0YScpID09PSAtMSA/IGtleXMgOiB1bmRlZmluZWQsXG4gICAgaW5jbHVkZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRQYXJzZUNsYXNzTXV0YXRpb25Db25maWcgPSBmdW5jdGlvbiAocGFyc2VDbGFzc0NvbmZpZykge1xuICByZXR1cm4gKHBhcnNlQ2xhc3NDb25maWcgJiYgcGFyc2VDbGFzc0NvbmZpZy5tdXRhdGlvbikgfHwge307XG59O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/transformers/className.js b/lib/GraphQL/transformers/className.js new file mode 100644 index 0000000000..a3b221d3fe --- /dev/null +++ b/lib/GraphQL/transformers/className.js @@ -0,0 +1,17 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.transformClassNameToGraphQL = void 0; + +const transformClassNameToGraphQL = className => { + if (className[0] === '_') { + className = className.slice(1); + } + + return className[0].toUpperCase() + className.slice(1); +}; + +exports.transformClassNameToGraphQL = transformClassNameToGraphQL; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9jbGFzc05hbWUuanMiXSwibmFtZXMiOlsidHJhbnNmb3JtQ2xhc3NOYW1lVG9HcmFwaFFMIiwiY2xhc3NOYW1lIiwic2xpY2UiLCJ0b1VwcGVyQ2FzZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBLE1BQU1BLDJCQUEyQixHQUFHQyxTQUFTLElBQUk7QUFDL0MsTUFBSUEsU0FBUyxDQUFDLENBQUQsQ0FBVCxLQUFpQixHQUFyQixFQUEwQjtBQUN4QkEsSUFBQUEsU0FBUyxHQUFHQSxTQUFTLENBQUNDLEtBQVYsQ0FBZ0IsQ0FBaEIsQ0FBWjtBQUNEOztBQUNELFNBQU9ELFNBQVMsQ0FBQyxDQUFELENBQVQsQ0FBYUUsV0FBYixLQUE2QkYsU0FBUyxDQUFDQyxLQUFWLENBQWdCLENBQWhCLENBQXBDO0FBQ0QsQ0FMRCIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHRyYW5zZm9ybUNsYXNzTmFtZVRvR3JhcGhRTCA9IGNsYXNzTmFtZSA9PiB7XG4gIGlmIChjbGFzc05hbWVbMF0gPT09ICdfJykge1xuICAgIGNsYXNzTmFtZSA9IGNsYXNzTmFtZS5zbGljZSgxKTtcbiAgfVxuICByZXR1cm4gY2xhc3NOYW1lWzBdLnRvVXBwZXJDYXNlKCkgKyBjbGFzc05hbWUuc2xpY2UoMSk7XG59O1xuXG5leHBvcnQgeyB0cmFuc2Zvcm1DbGFzc05hbWVUb0dyYXBoUUwgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/transformers/constraintType.js b/lib/GraphQL/transformers/constraintType.js new file mode 100644 index 0000000000..8f1bb7e138 --- /dev/null +++ b/lib/GraphQL/transformers/constraintType.js @@ -0,0 +1,73 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.transformConstraintTypeToGraphQL = void 0; + +var defaultGraphQLTypes = _interopRequireWildcard(require("../loaders/defaultGraphQLTypes")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +const transformConstraintTypeToGraphQL = (parseType, targetClass, parseClassTypes, fieldName) => { + if (fieldName === 'id' || fieldName === 'objectId') { + return defaultGraphQLTypes.ID_WHERE_INPUT; + } + + switch (parseType) { + case 'String': + return defaultGraphQLTypes.STRING_WHERE_INPUT; + + case 'Number': + return defaultGraphQLTypes.NUMBER_WHERE_INPUT; + + case 'Boolean': + return defaultGraphQLTypes.BOOLEAN_WHERE_INPUT; + + case 'Array': + return defaultGraphQLTypes.ARRAY_WHERE_INPUT; + + case 'Object': + return defaultGraphQLTypes.OBJECT_WHERE_INPUT; + + case 'Date': + return defaultGraphQLTypes.DATE_WHERE_INPUT; + + case 'Pointer': + if (parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLRelationConstraintsType) { + return parseClassTypes[targetClass].classGraphQLRelationConstraintsType; + } else { + return defaultGraphQLTypes.OBJECT; + } + + case 'File': + return defaultGraphQLTypes.FILE_WHERE_INPUT; + + case 'GeoPoint': + return defaultGraphQLTypes.GEO_POINT_WHERE_INPUT; + + case 'Polygon': + return defaultGraphQLTypes.POLYGON_WHERE_INPUT; + + case 'Bytes': + return defaultGraphQLTypes.BYTES_WHERE_INPUT; + + case 'ACL': + return defaultGraphQLTypes.OBJECT_WHERE_INPUT; + + case 'Relation': + if (parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLRelationConstraintsType) { + return parseClassTypes[targetClass].classGraphQLRelationConstraintsType; + } else { + return defaultGraphQLTypes.OBJECT; + } + + default: + return undefined; + } +}; + +exports.transformConstraintTypeToGraphQL = transformConstraintTypeToGraphQL; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9jb25zdHJhaW50VHlwZS5qcyJdLCJuYW1lcyI6WyJ0cmFuc2Zvcm1Db25zdHJhaW50VHlwZVRvR3JhcGhRTCIsInBhcnNlVHlwZSIsInRhcmdldENsYXNzIiwicGFyc2VDbGFzc1R5cGVzIiwiZmllbGROYW1lIiwiZGVmYXVsdEdyYXBoUUxUeXBlcyIsIklEX1dIRVJFX0lOUFVUIiwiU1RSSU5HX1dIRVJFX0lOUFVUIiwiTlVNQkVSX1dIRVJFX0lOUFVUIiwiQk9PTEVBTl9XSEVSRV9JTlBVVCIsIkFSUkFZX1dIRVJFX0lOUFVUIiwiT0JKRUNUX1dIRVJFX0lOUFVUIiwiREFURV9XSEVSRV9JTlBVVCIsImNsYXNzR3JhcGhRTFJlbGF0aW9uQ29uc3RyYWludHNUeXBlIiwiT0JKRUNUIiwiRklMRV9XSEVSRV9JTlBVVCIsIkdFT19QT0lOVF9XSEVSRV9JTlBVVCIsIlBPTFlHT05fV0hFUkVfSU5QVVQiLCJCWVRFU19XSEVSRV9JTlBVVCIsInVuZGVmaW5lZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7Ozs7QUFFQSxNQUFNQSxnQ0FBZ0MsR0FBRyxDQUFDQyxTQUFELEVBQVlDLFdBQVosRUFBeUJDLGVBQXpCLEVBQTBDQyxTQUExQyxLQUF3RDtBQUMvRixNQUFJQSxTQUFTLEtBQUssSUFBZCxJQUFzQkEsU0FBUyxLQUFLLFVBQXhDLEVBQW9EO0FBQ2xELFdBQU9DLG1CQUFtQixDQUFDQyxjQUEzQjtBQUNEOztBQUVELFVBQVFMLFNBQVI7QUFDRSxTQUFLLFFBQUw7QUFDRSxhQUFPSSxtQkFBbUIsQ0FBQ0Usa0JBQTNCOztBQUNGLFNBQUssUUFBTDtBQUNFLGFBQU9GLG1CQUFtQixDQUFDRyxrQkFBM0I7O0FBQ0YsU0FBSyxTQUFMO0FBQ0UsYUFBT0gsbUJBQW1CLENBQUNJLG1CQUEzQjs7QUFDRixTQUFLLE9BQUw7QUFDRSxhQUFPSixtQkFBbUIsQ0FBQ0ssaUJBQTNCOztBQUNGLFNBQUssUUFBTDtBQUNFLGFBQU9MLG1CQUFtQixDQUFDTSxrQkFBM0I7O0FBQ0YsU0FBSyxNQUFMO0FBQ0UsYUFBT04sbUJBQW1CLENBQUNPLGdCQUEzQjs7QUFDRixTQUFLLFNBQUw7QUFDRSxVQUNFVCxlQUFlLENBQUNELFdBQUQsQ0FBZixJQUNBQyxlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2QlcsbUNBRi9CLEVBR0U7QUFDQSxlQUFPVixlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2QlcsbUNBQXBDO0FBQ0QsT0FMRCxNQUtPO0FBQ0wsZUFBT1IsbUJBQW1CLENBQUNTLE1BQTNCO0FBQ0Q7O0FBQ0gsU0FBSyxNQUFMO0FBQ0UsYUFBT1QsbUJBQW1CLENBQUNVLGdCQUEzQjs7QUFDRixTQUFLLFVBQUw7QUFDRSxhQUFPVixtQkFBbUIsQ0FBQ1cscUJBQTNCOztBQUNGLFNBQUssU0FBTDtBQUNFLGFBQU9YLG1CQUFtQixDQUFDWSxtQkFBM0I7O0FBQ0YsU0FBSyxPQUFMO0FBQ0UsYUFBT1osbUJBQW1CLENBQUNhLGlCQUEzQjs7QUFDRixTQUFLLEtBQUw7QUFDRSxhQUFPYixtQkFBbUIsQ0FBQ00sa0JBQTNCOztBQUNGLFNBQUssVUFBTDtBQUNFLFVBQ0VSLGVBQWUsQ0FBQ0QsV0FBRCxDQUFmLElBQ0FDLGVBQWUsQ0FBQ0QsV0FBRCxDQUFmLENBQTZCVyxtQ0FGL0IsRUFHRTtBQUNBLGVBQU9WLGVBQWUsQ0FBQ0QsV0FBRCxDQUFmLENBQTZCVyxtQ0FBcEM7QUFDRCxPQUxELE1BS087QUFDTCxlQUFPUixtQkFBbUIsQ0FBQ1MsTUFBM0I7QUFDRDs7QUFDSDtBQUNFLGFBQU9LLFNBQVA7QUExQ0o7QUE0Q0QsQ0FqREQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4uL2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5cbmNvbnN0IHRyYW5zZm9ybUNvbnN0cmFpbnRUeXBlVG9HcmFwaFFMID0gKHBhcnNlVHlwZSwgdGFyZ2V0Q2xhc3MsIHBhcnNlQ2xhc3NUeXBlcywgZmllbGROYW1lKSA9PiB7XG4gIGlmIChmaWVsZE5hbWUgPT09ICdpZCcgfHwgZmllbGROYW1lID09PSAnb2JqZWN0SWQnKSB7XG4gICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuSURfV0hFUkVfSU5QVVQ7XG4gIH1cblxuICBzd2l0Y2ggKHBhcnNlVHlwZSkge1xuICAgIGNhc2UgJ1N0cmluZyc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5TVFJJTkdfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnTnVtYmVyJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk5VTUJFUl9XSEVSRV9JTlBVVDtcbiAgICBjYXNlICdCb29sZWFuJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkJPT0xFQU5fV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuQVJSQVlfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnT2JqZWN0JzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVF9XSEVSRV9JTlBVVDtcbiAgICBjYXNlICdEYXRlJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkRBVEVfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnUG9pbnRlcic6XG4gICAgICBpZiAoXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10gJiZcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXS5jbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdLmNsYXNzR3JhcGhRTFJlbGF0aW9uQ29uc3RyYWludHNUeXBlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUO1xuICAgICAgfVxuICAgIGNhc2UgJ0ZpbGUnOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuRklMRV9XSEVSRV9JTlBVVDtcbiAgICBjYXNlICdHZW9Qb2ludCc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5HRU9fUE9JTlRfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnUG9seWdvbic6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5QT0xZR09OX1dIRVJFX0lOUFVUO1xuICAgIGNhc2UgJ0J5dGVzJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkJZVEVTX1dIRVJFX0lOUFVUO1xuICAgIGNhc2UgJ0FDTCc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1RfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnUmVsYXRpb24nOlxuICAgICAgaWYgKFxuICAgICAgICBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdICYmXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10uY2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGVcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXS5jbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVDtcbiAgICAgIH1cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufTtcblxuZXhwb3J0IHsgdHJhbnNmb3JtQ29uc3RyYWludFR5cGVUb0dyYXBoUUwgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/transformers/inputType.js b/lib/GraphQL/transformers/inputType.js new file mode 100644 index 0000000000..af04ed30b5 --- /dev/null +++ b/lib/GraphQL/transformers/inputType.js @@ -0,0 +1,71 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.transformInputTypeToGraphQL = void 0; + +var _graphql = require("graphql"); + +var defaultGraphQLTypes = _interopRequireWildcard(require("../loaders/defaultGraphQLTypes")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +const transformInputTypeToGraphQL = (parseType, targetClass, parseClassTypes) => { + switch (parseType) { + case 'String': + return _graphql.GraphQLString; + + case 'Number': + return _graphql.GraphQLFloat; + + case 'Boolean': + return _graphql.GraphQLBoolean; + + case 'Array': + return new _graphql.GraphQLList(defaultGraphQLTypes.ANY); + + case 'Object': + return defaultGraphQLTypes.OBJECT; + + case 'Date': + return defaultGraphQLTypes.DATE; + + case 'Pointer': + if (parseClassTypes && parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLPointerType) { + return parseClassTypes[targetClass].classGraphQLPointerType; + } else { + return defaultGraphQLTypes.OBJECT; + } + + case 'Relation': + if (parseClassTypes && parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLRelationType) { + return parseClassTypes[targetClass].classGraphQLRelationType; + } else { + return defaultGraphQLTypes.OBJECT; + } + + case 'File': + return defaultGraphQLTypes.FILE_INPUT; + + case 'GeoPoint': + return defaultGraphQLTypes.GEO_POINT_INPUT; + + case 'Polygon': + return defaultGraphQLTypes.POLYGON_INPUT; + + case 'Bytes': + return defaultGraphQLTypes.BYTES; + + case 'ACL': + return defaultGraphQLTypes.ACL_INPUT; + + default: + return undefined; + } +}; + +exports.transformInputTypeToGraphQL = transformInputTypeToGraphQL; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9pbnB1dFR5cGUuanMiXSwibmFtZXMiOlsidHJhbnNmb3JtSW5wdXRUeXBlVG9HcmFwaFFMIiwicGFyc2VUeXBlIiwidGFyZ2V0Q2xhc3MiLCJwYXJzZUNsYXNzVHlwZXMiLCJHcmFwaFFMU3RyaW5nIiwiR3JhcGhRTEZsb2F0IiwiR3JhcGhRTEJvb2xlYW4iLCJHcmFwaFFMTGlzdCIsImRlZmF1bHRHcmFwaFFMVHlwZXMiLCJBTlkiLCJPQkpFQ1QiLCJEQVRFIiwiY2xhc3NHcmFwaFFMUG9pbnRlclR5cGUiLCJjbGFzc0dyYXBoUUxSZWxhdGlvblR5cGUiLCJGSUxFX0lOUFVUIiwiR0VPX1BPSU5UX0lOUFVUIiwiUE9MWUdPTl9JTlBVVCIsIkJZVEVTIiwiQUNMX0lOUFVUIiwidW5kZWZpbmVkIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7Ozs7OztBQUVBLE1BQU1BLDJCQUEyQixHQUFHLENBQUNDLFNBQUQsRUFBWUMsV0FBWixFQUF5QkMsZUFBekIsS0FBNkM7QUFDL0UsVUFBUUYsU0FBUjtBQUNFLFNBQUssUUFBTDtBQUNFLGFBQU9HLHNCQUFQOztBQUNGLFNBQUssUUFBTDtBQUNFLGFBQU9DLHFCQUFQOztBQUNGLFNBQUssU0FBTDtBQUNFLGFBQU9DLHVCQUFQOztBQUNGLFNBQUssT0FBTDtBQUNFLGFBQU8sSUFBSUMsb0JBQUosQ0FBZ0JDLG1CQUFtQixDQUFDQyxHQUFwQyxDQUFQOztBQUNGLFNBQUssUUFBTDtBQUNFLGFBQU9ELG1CQUFtQixDQUFDRSxNQUEzQjs7QUFDRixTQUFLLE1BQUw7QUFDRSxhQUFPRixtQkFBbUIsQ0FBQ0csSUFBM0I7O0FBQ0YsU0FBSyxTQUFMO0FBQ0UsVUFDRVIsZUFBZSxJQUNmQSxlQUFlLENBQUNELFdBQUQsQ0FEZixJQUVBQyxlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2QlUsdUJBSC9CLEVBSUU7QUFDQSxlQUFPVCxlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2QlUsdUJBQXBDO0FBQ0QsT0FORCxNQU1PO0FBQ0wsZUFBT0osbUJBQW1CLENBQUNFLE1BQTNCO0FBQ0Q7O0FBQ0gsU0FBSyxVQUFMO0FBQ0UsVUFDRVAsZUFBZSxJQUNmQSxlQUFlLENBQUNELFdBQUQsQ0FEZixJQUVBQyxlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2Qlcsd0JBSC9CLEVBSUU7QUFDQSxlQUFPVixlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2Qlcsd0JBQXBDO0FBQ0QsT0FORCxNQU1PO0FBQ0wsZUFBT0wsbUJBQW1CLENBQUNFLE1BQTNCO0FBQ0Q7O0FBQ0gsU0FBSyxNQUFMO0FBQ0UsYUFBT0YsbUJBQW1CLENBQUNNLFVBQTNCOztBQUNGLFNBQUssVUFBTDtBQUNFLGFBQU9OLG1CQUFtQixDQUFDTyxlQUEzQjs7QUFDRixTQUFLLFNBQUw7QUFDRSxhQUFPUCxtQkFBbUIsQ0FBQ1EsYUFBM0I7O0FBQ0YsU0FBSyxPQUFMO0FBQ0UsYUFBT1IsbUJBQW1CLENBQUNTLEtBQTNCOztBQUNGLFNBQUssS0FBTDtBQUNFLGFBQU9ULG1CQUFtQixDQUFDVSxTQUEzQjs7QUFDRjtBQUNFLGFBQU9DLFNBQVA7QUE1Q0o7QUE4Q0QsQ0EvQ0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBHcmFwaFFMU3RyaW5nLCBHcmFwaFFMRmxvYXQsIEdyYXBoUUxCb29sZWFuLCBHcmFwaFFMTGlzdCB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0ICogYXMgZGVmYXVsdEdyYXBoUUxUeXBlcyBmcm9tICcuLi9sb2FkZXJzL2RlZmF1bHRHcmFwaFFMVHlwZXMnO1xuXG5jb25zdCB0cmFuc2Zvcm1JbnB1dFR5cGVUb0dyYXBoUUwgPSAocGFyc2VUeXBlLCB0YXJnZXRDbGFzcywgcGFyc2VDbGFzc1R5cGVzKSA9PiB7XG4gIHN3aXRjaCAocGFyc2VUeXBlKSB7XG4gICAgY2FzZSAnU3RyaW5nJzpcbiAgICAgIHJldHVybiBHcmFwaFFMU3RyaW5nO1xuICAgIGNhc2UgJ051bWJlcic6XG4gICAgICByZXR1cm4gR3JhcGhRTEZsb2F0O1xuICAgIGNhc2UgJ0Jvb2xlYW4nOlxuICAgICAgcmV0dXJuIEdyYXBoUUxCb29sZWFuO1xuICAgIGNhc2UgJ0FycmF5JzpcbiAgICAgIHJldHVybiBuZXcgR3JhcGhRTExpc3QoZGVmYXVsdEdyYXBoUUxUeXBlcy5BTlkpO1xuICAgIGNhc2UgJ09iamVjdCc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1Q7XG4gICAgY2FzZSAnRGF0ZSc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5EQVRFO1xuICAgIGNhc2UgJ1BvaW50ZXInOlxuICAgICAgaWYgKFxuICAgICAgICBwYXJzZUNsYXNzVHlwZXMgJiZcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXSAmJlxuICAgICAgICBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdLmNsYXNzR3JhcGhRTFBvaW50ZXJUeXBlXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10uY2xhc3NHcmFwaFFMUG9pbnRlclR5cGU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1Q7XG4gICAgICB9XG4gICAgY2FzZSAnUmVsYXRpb24nOlxuICAgICAgaWYgKFxuICAgICAgICBwYXJzZUNsYXNzVHlwZXMgJiZcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXSAmJlxuICAgICAgICBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdLmNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdLmNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVDtcbiAgICAgIH1cbiAgICBjYXNlICdGaWxlJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkZJTEVfSU5QVVQ7XG4gICAgY2FzZSAnR2VvUG9pbnQnOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuR0VPX1BPSU5UX0lOUFVUO1xuICAgIGNhc2UgJ1BvbHlnb24nOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuUE9MWUdPTl9JTlBVVDtcbiAgICBjYXNlICdCeXRlcyc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5CWVRFUztcbiAgICBjYXNlICdBQ0wnOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuQUNMX0lOUFVUO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59O1xuXG5leHBvcnQgeyB0cmFuc2Zvcm1JbnB1dFR5cGVUb0dyYXBoUUwgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/transformers/mutation.js b/lib/GraphQL/transformers/mutation.js new file mode 100644 index 0000000000..1cefb52b90 --- /dev/null +++ b/lib/GraphQL/transformers/mutation.js @@ -0,0 +1,275 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.transformTypes = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _graphqlRelay = require("graphql-relay"); + +var _filesMutations = require("../loaders/filesMutations"); + +var defaultGraphQLTypes = _interopRequireWildcard(require("../loaders/defaultGraphQLTypes")); + +var objectsMutations = _interopRequireWildcard(require("../helpers/objectsMutations")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const transformTypes = async (inputType, fields, { + className, + parseGraphQLSchema, + req +}) => { + const { + classGraphQLCreateType, + classGraphQLUpdateType, + config: { + isCreateEnabled, + isUpdateEnabled + } + } = parseGraphQLSchema.parseClassTypes[className]; + const parseClass = parseGraphQLSchema.parseClasses.find(clazz => clazz.className === className); + + if (fields) { + const classGraphQLCreateTypeFields = isCreateEnabled && classGraphQLCreateType ? classGraphQLCreateType.getFields() : null; + const classGraphQLUpdateTypeFields = isUpdateEnabled && classGraphQLUpdateType ? classGraphQLUpdateType.getFields() : null; + const promises = Object.keys(fields).map(async field => { + let inputTypeField; + + if (inputType === 'create' && classGraphQLCreateTypeFields) { + inputTypeField = classGraphQLCreateTypeFields[field]; + } else if (classGraphQLUpdateTypeFields) { + inputTypeField = classGraphQLUpdateTypeFields[field]; + } + + if (inputTypeField) { + switch (true) { + case inputTypeField.type === defaultGraphQLTypes.GEO_POINT_INPUT: + fields[field] = transformers.geoPoint(fields[field]); + break; + + case inputTypeField.type === defaultGraphQLTypes.POLYGON_INPUT: + fields[field] = transformers.polygon(fields[field]); + break; + + case inputTypeField.type === defaultGraphQLTypes.FILE_INPUT: + fields[field] = await transformers.file(fields[field], req); + break; + + case parseClass.fields[field].type === 'Relation': + fields[field] = await transformers.relation(parseClass.fields[field].targetClass, field, fields[field], parseGraphQLSchema, req); + break; + + case parseClass.fields[field].type === 'Pointer': + fields[field] = await transformers.pointer(parseClass.fields[field].targetClass, field, fields[field], parseGraphQLSchema, req); + break; + } + } + }); + await Promise.all(promises); + if (fields.ACL) fields.ACL = transformers.ACL(fields.ACL); + } + + return fields; +}; + +exports.transformTypes = transformTypes; +const transformers = { + file: async ({ + file, + upload + }, { + config + }) => { + if (file === null && !upload) { + return null; + } + + if (upload) { + const { + fileInfo + } = await (0, _filesMutations.handleUpload)(upload, config); + return _objectSpread(_objectSpread({}, fileInfo), {}, { + __type: 'File' + }); + } else if (file && file.name) { + return { + name: file.name, + __type: 'File', + url: file.url + }; + } + + throw new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, 'Invalid file upload.'); + }, + polygon: value => ({ + __type: 'Polygon', + coordinates: value.map(geoPoint => [geoPoint.latitude, geoPoint.longitude]) + }), + geoPoint: value => _objectSpread(_objectSpread({}, value), {}, { + __type: 'GeoPoint' + }), + ACL: value => { + const parseACL = {}; + + if (value.public) { + parseACL['*'] = { + read: value.public.read, + write: value.public.write + }; + } + + if (value.users) { + value.users.forEach(rule => { + const globalIdObject = (0, _graphqlRelay.fromGlobalId)(rule.userId); + + if (globalIdObject.type === '_User') { + rule.userId = globalIdObject.id; + } + + parseACL[rule.userId] = { + read: rule.read, + write: rule.write + }; + }); + } + + if (value.roles) { + value.roles.forEach(rule => { + parseACL[`role:${rule.roleName}`] = { + read: rule.read, + write: rule.write + }; + }); + } + + return parseACL; + }, + relation: async (targetClass, field, value, parseGraphQLSchema, { + config, + auth, + info + }) => { + if (Object.keys(value).length === 0) throw new _node.default.Error(_node.default.Error.INVALID_POINTER, `You need to provide at least one operation on the relation mutation of field ${field}`); + const op = { + __op: 'Batch', + ops: [] + }; + let nestedObjectsToAdd = []; + + if (value.createAndAdd) { + nestedObjectsToAdd = (await Promise.all(value.createAndAdd.map(async input => { + const parseFields = await transformTypes('create', input, { + className: targetClass, + parseGraphQLSchema, + req: { + config, + auth, + info + } + }); + return objectsMutations.createObject(targetClass, parseFields, config, auth, info); + }))).map(object => ({ + __type: 'Pointer', + className: targetClass, + objectId: object.objectId + })); + } + + if (value.add || nestedObjectsToAdd.length > 0) { + if (!value.add) value.add = []; + value.add = value.add.map(input => { + const globalIdObject = (0, _graphqlRelay.fromGlobalId)(input); + + if (globalIdObject.type === targetClass) { + input = globalIdObject.id; + } + + return { + __type: 'Pointer', + className: targetClass, + objectId: input + }; + }); + op.ops.push({ + __op: 'AddRelation', + objects: [...value.add, ...nestedObjectsToAdd] + }); + } + + if (value.remove) { + op.ops.push({ + __op: 'RemoveRelation', + objects: value.remove.map(input => { + const globalIdObject = (0, _graphqlRelay.fromGlobalId)(input); + + if (globalIdObject.type === targetClass) { + input = globalIdObject.id; + } + + return { + __type: 'Pointer', + className: targetClass, + objectId: input + }; + }) + }); + } + + return op; + }, + pointer: async (targetClass, field, value, parseGraphQLSchema, { + config, + auth, + info + }) => { + if (Object.keys(value).length > 1 || Object.keys(value).length === 0) throw new _node.default.Error(_node.default.Error.INVALID_POINTER, `You need to provide link OR createLink on the pointer mutation of field ${field}`); + let nestedObjectToAdd; + + if (value.createAndLink) { + const parseFields = await transformTypes('create', value.createAndLink, { + className: targetClass, + parseGraphQLSchema, + req: { + config, + auth, + info + } + }); + nestedObjectToAdd = await objectsMutations.createObject(targetClass, parseFields, config, auth, info); + return { + __type: 'Pointer', + className: targetClass, + objectId: nestedObjectToAdd.objectId + }; + } + + if (value.link) { + let objectId = value.link; + const globalIdObject = (0, _graphqlRelay.fromGlobalId)(objectId); + + if (globalIdObject.type === targetClass) { + objectId = globalIdObject.id; + } + + return { + __type: 'Pointer', + className: targetClass, + objectId + }; + } + } +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9tdXRhdGlvbi5qcyJdLCJuYW1lcyI6WyJ0cmFuc2Zvcm1UeXBlcyIsImlucHV0VHlwZSIsImZpZWxkcyIsImNsYXNzTmFtZSIsInBhcnNlR3JhcGhRTFNjaGVtYSIsInJlcSIsImNsYXNzR3JhcGhRTENyZWF0ZVR5cGUiLCJjbGFzc0dyYXBoUUxVcGRhdGVUeXBlIiwiY29uZmlnIiwiaXNDcmVhdGVFbmFibGVkIiwiaXNVcGRhdGVFbmFibGVkIiwicGFyc2VDbGFzc1R5cGVzIiwicGFyc2VDbGFzcyIsInBhcnNlQ2xhc3NlcyIsImZpbmQiLCJjbGF6eiIsImNsYXNzR3JhcGhRTENyZWF0ZVR5cGVGaWVsZHMiLCJnZXRGaWVsZHMiLCJjbGFzc0dyYXBoUUxVcGRhdGVUeXBlRmllbGRzIiwicHJvbWlzZXMiLCJPYmplY3QiLCJrZXlzIiwibWFwIiwiZmllbGQiLCJpbnB1dFR5cGVGaWVsZCIsInR5cGUiLCJkZWZhdWx0R3JhcGhRTFR5cGVzIiwiR0VPX1BPSU5UX0lOUFVUIiwidHJhbnNmb3JtZXJzIiwiZ2VvUG9pbnQiLCJQT0xZR09OX0lOUFVUIiwicG9seWdvbiIsIkZJTEVfSU5QVVQiLCJmaWxlIiwicmVsYXRpb24iLCJ0YXJnZXRDbGFzcyIsInBvaW50ZXIiLCJQcm9taXNlIiwiYWxsIiwiQUNMIiwidXBsb2FkIiwiZmlsZUluZm8iLCJfX3R5cGUiLCJuYW1lIiwidXJsIiwiUGFyc2UiLCJFcnJvciIsIkZJTEVfU0FWRV9FUlJPUiIsInZhbHVlIiwiY29vcmRpbmF0ZXMiLCJsYXRpdHVkZSIsImxvbmdpdHVkZSIsInBhcnNlQUNMIiwicHVibGljIiwicmVhZCIsIndyaXRlIiwidXNlcnMiLCJmb3JFYWNoIiwicnVsZSIsImdsb2JhbElkT2JqZWN0IiwidXNlcklkIiwiaWQiLCJyb2xlcyIsInJvbGVOYW1lIiwiYXV0aCIsImluZm8iLCJsZW5ndGgiLCJJTlZBTElEX1BPSU5URVIiLCJvcCIsIl9fb3AiLCJvcHMiLCJuZXN0ZWRPYmplY3RzVG9BZGQiLCJjcmVhdGVBbmRBZGQiLCJpbnB1dCIsInBhcnNlRmllbGRzIiwib2JqZWN0c011dGF0aW9ucyIsImNyZWF0ZU9iamVjdCIsIm9iamVjdCIsIm9iamVjdElkIiwiYWRkIiwicHVzaCIsIm9iamVjdHMiLCJyZW1vdmUiLCJuZXN0ZWRPYmplY3RUb0FkZCIsImNyZWF0ZUFuZExpbmsiLCJsaW5rIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FBRUEsTUFBTUEsY0FBYyxHQUFHLE9BQ3JCQyxTQURxQixFQUVyQkMsTUFGcUIsRUFHckI7QUFBRUMsRUFBQUEsU0FBRjtBQUFhQyxFQUFBQSxrQkFBYjtBQUFpQ0MsRUFBQUE7QUFBakMsQ0FIcUIsS0FJbEI7QUFDSCxRQUFNO0FBQ0pDLElBQUFBLHNCQURJO0FBRUpDLElBQUFBLHNCQUZJO0FBR0pDLElBQUFBLE1BQU0sRUFBRTtBQUFFQyxNQUFBQSxlQUFGO0FBQW1CQyxNQUFBQTtBQUFuQjtBQUhKLE1BSUZOLGtCQUFrQixDQUFDTyxlQUFuQixDQUFtQ1IsU0FBbkMsQ0FKSjtBQUtBLFFBQU1TLFVBQVUsR0FBR1Isa0JBQWtCLENBQUNTLFlBQW5CLENBQWdDQyxJQUFoQyxDQUFxQ0MsS0FBSyxJQUFJQSxLQUFLLENBQUNaLFNBQU4sS0FBb0JBLFNBQWxFLENBQW5COztBQUNBLE1BQUlELE1BQUosRUFBWTtBQUNWLFVBQU1jLDRCQUE0QixHQUNoQ1AsZUFBZSxJQUFJSCxzQkFBbkIsR0FBNENBLHNCQUFzQixDQUFDVyxTQUF2QixFQUE1QyxHQUFpRixJQURuRjtBQUVBLFVBQU1DLDRCQUE0QixHQUNoQ1IsZUFBZSxJQUFJSCxzQkFBbkIsR0FBNENBLHNCQUFzQixDQUFDVSxTQUF2QixFQUE1QyxHQUFpRixJQURuRjtBQUVBLFVBQU1FLFFBQVEsR0FBR0MsTUFBTSxDQUFDQyxJQUFQLENBQVluQixNQUFaLEVBQW9Cb0IsR0FBcEIs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QVEsRUFBRUssaUJBQWlCLENBQUNMO0FBSHZCLE9BQVA7QUFLRDs7QUFDRCxRQUFJOUIsS0FBSyxDQUFDcUMsSUFBVixFQUFnQjtBQUNkLFVBQUlQLFFBQVEsR0FBRzlCLEtBQUssQ0FBQ3FDLElBQXJCO0FBQ0EsWUFBTTFCLGNBQWMsR0FBRyxnQ0FBYW1CLFFBQWIsQ0FBdkI7O0FBQ0EsVUFBSW5CLGNBQWMsQ0FBQ2xDLElBQWYsS0FBd0JVLFdBQTVCLEVBQXlDO0FBQ3ZDMkMsUUFBQUEsUUFBUSxHQUFHbkIsY0FBYyxDQUFDRSxFQUExQjtBQUNEOztBQUNELGFBQU87QUFDTG5CLFFBQUFBLE1BQU0sRUFBRSxTQURIO0FBRUx2QyxRQUFBQSxTQUFTLEVBQUVnQyxXQUZOO0FBR0wyQyxRQUFBQTtBQUhLLE9BQVA7QUFLRDtBQUNGO0FBL0prQixDQUFyQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCB7IGZyb21HbG9iYWxJZCB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0IHsgaGFuZGxlVXBsb2FkIH0gZnJvbSAnLi4vbG9hZGVycy9maWxlc011dGF0aW9ucyc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4uL2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQgKiBhcyBvYmplY3RzTXV0YXRpb25zIGZyb20gJy4uL2hlbHBlcnMvb2JqZWN0c011dGF0aW9ucyc7XG5cbmNvbnN0IHRyYW5zZm9ybVR5cGVzID0gYXN5bmMgKFxuICBpbnB1dFR5cGU6ICdjcmVhdGUnIHwgJ3VwZGF0ZScsXG4gIGZpZWxkcyxcbiAgeyBjbGFzc05hbWUsIHBhcnNlR3JhcGhRTFNjaGVtYSwgcmVxIH1cbikgPT4ge1xuICBjb25zdCB7XG4gICAgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSxcbiAgICBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlLFxuICAgIGNvbmZpZzogeyBpc0NyZWF0ZUVuYWJsZWQsIGlzVXBkYXRlRW5hYmxlZCB9LFxuICB9ID0gcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1tjbGFzc05hbWVdO1xuICBjb25zdCBwYXJzZUNsYXNzID0gcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3Nlcy5maW5kKGNsYXp6ID0+IGNsYXp6LmNsYXNzTmFtZSA9PT0gY2xhc3NOYW1lKTtcbiAgaWYgKGZpZWxkcykge1xuICAgIGNvbnN0IGNsYXNzR3JhcGhRTENyZWF0ZVR5cGVGaWVsZHMgPVxuICAgICAgaXNDcmVhdGVFbmFibGVkICYmIGNsYXNzR3JhcGhRTENyZWF0ZVR5cGUgPyBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlLmdldEZpZWxkcygpIDogbnVsbDtcbiAgICBjb25zdCBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlRmllbGRzID1cbiAgICAgIGlzVXBkYXRlRW5hYmxlZCAmJiBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlID8gY2xhc3NHcmFwaFFMVXBkYXRlVHlwZS5nZXRGaWVsZHMoKSA6IG51bGw7XG4gICAgY29uc3QgcHJvbWlzZXMgPSBPYmplY3Qua2V5cyhmaWVsZHMpLm1hcChhc3luYyBmaWVsZCA9PiB7XG4gICAgICBsZXQgaW5wdXRUeXBlRmllbGQ7XG4gICAgICBpZiAoaW5wdXRUeXBlID09PSAnY3JlYXRlJyAmJiBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlRmllbGRzKSB7XG4gICAgICAgIGlucHV0VHlwZUZpZWxkID0gY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZUZpZWxkc1tmaWVsZF07XG4gICAgICB9IGVsc2UgaWYgKGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGVGaWVsZHMpIHtcbiAgICAgICAgaW5wdXRUeXBlRmllbGQgPSBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlRmllbGRzW2ZpZWxkXTtcbiAgICAgIH1cbiAgICAgIGlmIChpbnB1dFR5cGVGaWVsZCkge1xuICAgICAgICBzd2l0Y2ggKHRydWUpIHtcbiAgICAgICAgICBjYXNlIGlucHV0VHlwZUZpZWxkLnR5cGUgPT09IGRlZmF1bHRHcmFwaFFMVHlwZXMuR0VPX1BPSU5UX0lOUFVUOlxuICAgICAgICAgICAgZmllbGRzW2ZpZWxkXSA9IHRyYW5zZm9ybWVycy5nZW9Qb2ludChmaWVsZHNbZmllbGRdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgaW5wdXRUeXBlRmllbGQudHlwZSA9PT0gZGVmYXVsdEdyYXBoUUxUeXBlcy5QT0xZR09OX0lOUFVUOlxuICAgICAgICAgICAgZmllbGRzW2ZpZWxkXSA9IHRyYW5zZm9ybWVycy5wb2x5Z29uKGZpZWxkc1tmaWVsZF0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSBpbnB1dFR5cGVGaWVsZC50eXBlID09PSBkZWZhdWx0R3JhcGhRTFR5cGVzLkZJTEVfSU5QVVQ6XG4gICAgICAgICAgICBmaWVsZHNbZmllbGRdID0gYXdhaXQgdHJhbnNmb3JtZXJzLmZpbGUoZmllbGRzW2ZpZWxkXSwgcmVxKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdSZWxhdGlvbic6XG4gICAgICAgICAgICBmaWVsZHNbZmllbGRdID0gYXdhaXQgdHJhbnNmb3JtZXJzLnJlbGF0aW9uKFxuICAgICAgICAgICAgICBwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0udGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICAgIGZpZWxkLFxuICAgICAgICAgICAgICBmaWVsZHNbZmllbGRdLFxuICAgICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEsXG4gICAgICAgICAgICAgIHJlcVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdQb2ludGVyJzpcbiAgICAgICAgICAgIGZpZWxkc1tmaWVsZF0gPSBhd2FpdCB0cmFuc2Zvcm1lcnMucG9pbnRlcihcbiAgICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnRhcmdldENsYXNzLFxuICAgICAgICAgICAgICBmaWVsZCxcbiAgICAgICAgICAgICAgZmllbGRzW2ZpZWxkXSxcbiAgICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLFxuICAgICAgICAgICAgICByZXFcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICBpZiAoZmllbGRzLkFDTCkgZmllbGRzLkFDTCA9IHRyYW5zZm9ybWVycy5BQ0woZmllbGRzLkFDTCk7XG4gIH1cbiAgcmV0dXJuIGZpZWxkcztcbn07XG5cbmNvbnN0IHRyYW5zZm9ybWVycyA9IHtcbiAgZmlsZTogYXN5bmMgKHsgZmlsZSwgdXBsb2FkIH0sIHsgY29uZmlnIH0pID0+IHtcbiAgICBpZiAoZmlsZSA9PT0gbnVsbCAmJiAhdXBsb2FkKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKHVwbG9hZCkge1xuICAgICAgY29uc3QgeyBmaWxlSW5mbyB9ID0gYXdhaXQgaGFuZGxlVXBsb2FkKHVwbG9hZCwgY29uZmlnKTtcbiAgICAgIHJldHVybiB7IC4uLmZpbGVJbmZvLCBfX3R5cGU6ICdGaWxlJyB9O1xuICAgIH0gZWxzZSBpZiAoZmlsZSAmJiBmaWxlLm5hbWUpIHtcbiAgICAgIHJldHVybiB7IG5hbWU6IGZpbGUubmFtZSwgX190eXBlOiAnRmlsZScsIHVybDogZmlsZS51cmwgfTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkZJTEVfU0FWRV9FUlJPUiwgJ0ludmFsaWQgZmlsZSB1cGxvYWQuJyk7XG4gIH0sXG4gIHBvbHlnb246IHZhbHVlID0+ICh7XG4gICAgX190eXBlOiAnUG9seWdvbicsXG4gICAgY29vcmRpbmF0ZXM6IHZhbHVlLm1hcChnZW9Qb2ludCA9PiBbZ2VvUG9pbnQubGF0aXR1ZGUsIGdlb1BvaW50LmxvbmdpdHVkZV0pLFxuICB9KSxcbiAgZ2VvUG9pbnQ6IHZhbHVlID0+ICh7XG4gICAgLi4udmFsdWUsXG4gICAgX190eXBlOiAnR2VvUG9pbnQnLFxuICB9KSxcbiAgQUNMOiB2YWx1ZSA9PiB7XG4gICAgY29uc3QgcGFyc2VBQ0wgPSB7fTtcbiAgICBpZiAodmFsdWUucHVibGljKSB7XG4gICAgICBwYXJzZUFDTFsnKiddID0ge1xuICAgICAgICByZWFkOiB2YWx1ZS5wdWJsaWMucmVhZCxcbiAgICAgICAgd3JpdGU6IHZhbHVlLnB1YmxpYy53cml0ZSxcbiAgICAgIH07XG4gICAgfVxuICAgIGlmICh2YWx1ZS51c2Vycykge1xuICAgICAgdmFsdWUudXNlcnMuZm9yRWFjaChydWxlID0+IHtcbiAgICAgICAgY29uc3QgZ2xvYmFsSWRPYmplY3QgPSBmcm9tR2xvYmFsSWQocnVsZS51c2VySWQpO1xuICAgICAgICBpZiAoZ2xvYmFsSWRPYmplY3QudHlwZSA9PT0gJ19Vc2VyJykge1xuICAgICAgICAgIHJ1bGUudXNlcklkID0gZ2xvYmFsSWRPYmplY3QuaWQ7XG4gICAgICAgIH1cbiAgICAgICAgcGFyc2VBQ0xbcnVsZS51c2VySWRdID0ge1xuICAgICAgICAgIHJlYWQ6IHJ1bGUucmVhZCxcbiAgICAgICAgICB3cml0ZTogcnVsZS53cml0ZSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAodmFsdWUucm9sZXMpIHtcbiAgICAgIHZhbHVlLnJvbGVzLmZvckVhY2gocnVsZSA9PiB7XG4gICAgICAgIHBhcnNlQUNMW2Byb2xlOiR7cnVsZS5yb2xlTmFtZX1gXSA9IHtcbiAgICAgICAgICByZWFkOiBydWxlLnJlYWQsXG4gICAgICAgICAgd3JpdGU6IHJ1bGUud3JpdGUsXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHBhcnNlQUNMO1xuICB9LFxuICByZWxhdGlvbjogYXN5bmMgKHRhcmdldENsYXNzLCBmaWVsZCwgdmFsdWUsIHBhcnNlR3JhcGhRTFNjaGVtYSwgeyBjb25maWcsIGF1dGgsIGluZm8gfSkgPT4ge1xuICAgIGlmIChPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoID09PSAwKVxuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1BPSU5URVIsXG4gICAgICAgIGBZb3UgbmVlZCB0byBwcm92aWRlIGF0IGxlYXN0IG9uZSBvcGVyYXRpb24gb24gdGhlIHJlbGF0aW9uIG11dGF0aW9uIG9mIGZpZWxkICR7ZmllbGR9YFxuICAgICAgKTtcblxuICAgIGNvbnN0IG9wID0ge1xuICAgICAgX19vcDogJ0JhdGNoJyxcbiAgICAgIG9wczogW10sXG4gICAgfTtcbiAgICBsZXQgbmVzdGVkT2JqZWN0c1RvQWRkID0gW107XG5cbiAgICBpZiAodmFsdWUuY3JlYXRlQW5kQWRkKSB7XG4gICAgICBuZXN0ZWRPYmplY3RzVG9BZGQgPSAoXG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgIHZhbHVlLmNyZWF0ZUFuZEFkZC5tYXAoYXN5bmMgaW5wdXQgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGFyc2VGaWVsZHMgPSBhd2FpdCB0cmFuc2Zvcm1UeXBlcygnY3JlYXRlJywgaW5wdXQsIHtcbiAgICAgICAgICAgICAgY2xhc3NOYW1lOiB0YXJnZXRDbGFzcyxcbiAgICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLFxuICAgICAgICAgICAgICByZXE6IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBvYmplY3RzTXV0YXRpb25zLmNyZWF0ZU9iamVjdCh0YXJnZXRDbGFzcywgcGFyc2VGaWVsZHMsIGNvbmZpZywgYXV0aCwgaW5mbyk7XG4gICAgICAgICAgfSlcbiAgICAgICAgKVxuICAgICAgKS5tYXAob2JqZWN0ID0+ICh7XG4gICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICBvYmplY3RJZDogb2JqZWN0Lm9iamVjdElkLFxuICAgICAgfSkpO1xuICAgIH1cblxuICAgIGlmICh2YWx1ZS5hZGQgfHwgbmVzdGVkT2JqZWN0c1RvQWRkLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmICghdmFsdWUuYWRkKSB2YWx1ZS5hZGQgPSBbXTtcbiAgICAgIHZhbHVlLmFkZCA9IHZhbHVlLmFkZC5tYXAoaW5wdXQgPT4ge1xuICAgICAgICBjb25zdCBnbG9iYWxJZE9iamVjdCA9IGZyb21HbG9iYWxJZChpbnB1dCk7XG4gICAgICAgIGlmIChnbG9iYWxJZE9iamVjdC50eXBlID09PSB0YXJnZXRDbGFzcykge1xuICAgICAgICAgIGlucHV0ID0gZ2xvYmFsSWRPYmplY3QuaWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICAgIG9iamVjdElkOiBpbnB1dCxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgICAgb3Aub3BzLnB1c2goe1xuICAgICAgICBfX29wOiAnQWRkUmVsYXRpb24nLFxuICAgICAgICBvYmplY3RzOiBbLi4udmFsdWUuYWRkLCAuLi5uZXN0ZWRPYmplY3RzVG9BZGRdLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHZhbHVlLnJlbW92ZSkge1xuICAgICAgb3Aub3BzLnB1c2goe1xuICAgICAgICBfX29wOiAnUmVtb3ZlUmVsYXRpb24nLFxuICAgICAgICBvYmplY3RzOiB2YWx1ZS5yZW1vdmUubWFwKGlucHV0ID0+IHtcbiAgICAgICAgICBjb25zdCBnbG9iYWxJZE9iamVjdCA9IGZyb21HbG9iYWxJZChpbnB1dCk7XG4gICAgICAgICAgaWYgKGdsb2JhbElkT2JqZWN0LnR5cGUgPT09IHRhcmdldENsYXNzKSB7XG4gICAgICAgICAgICBpbnB1dCA9IGdsb2JhbElkT2JqZWN0LmlkO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICAgICAgb2JqZWN0SWQ6IGlucHV0LFxuICAgICAgICAgIH07XG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBvcDtcbiAgfSxcbiAgcG9pbnRlcjogYXN5bmMgKHRhcmdldENsYXNzLCBmaWVsZCwgdmFsdWUsIHBhcnNlR3JhcGhRTFNjaGVtYSwgeyBjb25maWcsIGF1dGgsIGluZm8gfSkgPT4ge1xuICAgIGlmIChPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoID4gMSB8fCBPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoID09PSAwKVxuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1BPSU5URVIsXG4gICAgICAgIGBZb3UgbmVlZCB0byBwcm92aWRlIGxpbmsgT1IgY3JlYXRlTGluayBvbiB0aGUgcG9pbnRlciBtdXRhdGlvbiBvZiBmaWVsZCAke2ZpZWxkfWBcbiAgICAgICk7XG5cbiAgICBsZXQgbmVzdGVkT2JqZWN0VG9BZGQ7XG4gICAgaWYgKHZhbHVlLmNyZWF0ZUFuZExpbmspIHtcbiAgICAgIGNvbnN0IHBhcnNlRmllbGRzID0gYXdhaXQgdHJhbnNmb3JtVHlwZXMoJ2NyZWF0ZScsIHZhbHVlLmNyZWF0ZUFuZExpbmssIHtcbiAgICAgICAgY2xhc3NOYW1lOiB0YXJnZXRDbGFzcyxcbiAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLFxuICAgICAgICByZXE6IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0sXG4gICAgICB9KTtcbiAgICAgIG5lc3RlZE9iamVjdFRvQWRkID0gYXdhaXQgb2JqZWN0c011dGF0aW9ucy5jcmVhdGVPYmplY3QoXG4gICAgICAgIHRhcmdldENsYXNzLFxuICAgICAgICBwYXJzZUZpZWxkcyxcbiAgICAgICAgY29uZmlnLFxuICAgICAgICBhdXRoLFxuICAgICAgICBpbmZvXG4gICAgICApO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICAgIGNsYXNzTmFtZTogdGFyZ2V0Q2xhc3MsXG4gICAgICAgIG9iamVjdElkOiBuZXN0ZWRPYmplY3RUb0FkZC5vYmplY3RJZCxcbiAgICAgIH07XG4gICAgfVxuICAgIGlmICh2YWx1ZS5saW5rKSB7XG4gICAgICBsZXQgb2JqZWN0SWQgPSB2YWx1ZS5saW5rO1xuICAgICAgY29uc3QgZ2xvYmFsSWRPYmplY3QgPSBmcm9tR2xvYmFsSWQob2JqZWN0SWQpO1xuICAgICAgaWYgKGdsb2JhbElkT2JqZWN0LnR5cGUgPT09IHRhcmdldENsYXNzKSB7XG4gICAgICAgIG9iamVjdElkID0gZ2xvYmFsSWRPYmplY3QuaWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgY2xhc3NOYW1lOiB0YXJnZXRDbGFzcyxcbiAgICAgICAgb2JqZWN0SWQsXG4gICAgICB9O1xuICAgIH1cbiAgfSxcbn07XG5cbmV4cG9ydCB7IHRyYW5zZm9ybVR5cGVzIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/transformers/outputType.js b/lib/GraphQL/transformers/outputType.js new file mode 100644 index 0000000000..e4713fafb8 --- /dev/null +++ b/lib/GraphQL/transformers/outputType.js @@ -0,0 +1,71 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.transformOutputTypeToGraphQL = void 0; + +var defaultGraphQLTypes = _interopRequireWildcard(require("../loaders/defaultGraphQLTypes")); + +var _graphql = require("graphql"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +const transformOutputTypeToGraphQL = (parseType, targetClass, parseClassTypes) => { + switch (parseType) { + case 'String': + return _graphql.GraphQLString; + + case 'Number': + return _graphql.GraphQLFloat; + + case 'Boolean': + return _graphql.GraphQLBoolean; + + case 'Array': + return new _graphql.GraphQLList(defaultGraphQLTypes.ARRAY_RESULT); + + case 'Object': + return defaultGraphQLTypes.OBJECT; + + case 'Date': + return defaultGraphQLTypes.DATE; + + case 'Pointer': + if (parseClassTypes && parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLOutputType) { + return parseClassTypes[targetClass].classGraphQLOutputType; + } else { + return defaultGraphQLTypes.OBJECT; + } + + case 'Relation': + if (parseClassTypes && parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLFindResultType) { + return new _graphql.GraphQLNonNull(parseClassTypes[targetClass].classGraphQLFindResultType); + } else { + return new _graphql.GraphQLNonNull(defaultGraphQLTypes.OBJECT); + } + + case 'File': + return defaultGraphQLTypes.FILE_INFO; + + case 'GeoPoint': + return defaultGraphQLTypes.GEO_POINT; + + case 'Polygon': + return defaultGraphQLTypes.POLYGON; + + case 'Bytes': + return defaultGraphQLTypes.BYTES; + + case 'ACL': + return new _graphql.GraphQLNonNull(defaultGraphQLTypes.ACL); + + default: + return undefined; + } +}; + +exports.transformOutputTypeToGraphQL = transformOutputTypeToGraphQL; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9vdXRwdXRUeXBlLmpzIl0sIm5hbWVzIjpbInRyYW5zZm9ybU91dHB1dFR5cGVUb0dyYXBoUUwiLCJwYXJzZVR5cGUiLCJ0YXJnZXRDbGFzcyIsInBhcnNlQ2xhc3NUeXBlcyIsIkdyYXBoUUxTdHJpbmciLCJHcmFwaFFMRmxvYXQiLCJHcmFwaFFMQm9vbGVhbiIsIkdyYXBoUUxMaXN0IiwiZGVmYXVsdEdyYXBoUUxUeXBlcyIsIkFSUkFZX1JFU1VMVCIsIk9CSkVDVCIsIkRBVEUiLCJjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIiwiY2xhc3NHcmFwaFFMRmluZFJlc3VsdFR5cGUiLCJHcmFwaFFMTm9uTnVsbCIsIkZJTEVfSU5GTyIsIkdFT19QT0lOVCIsIlBPTFlHT04iLCJCWVRFUyIsIkFDTCIsInVuZGVmaW5lZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7Ozs7QUFFQSxNQUFNQSw0QkFBNEIsR0FBRyxDQUFDQyxTQUFELEVBQVlDLFdBQVosRUFBeUJDLGVBQXpCLEtBQTZDO0FBQ2hGLFVBQVFGLFNBQVI7QUFDRSxTQUFLLFFBQUw7QUFDRSxhQUFPRyxzQkFBUDs7QUFDRixTQUFLLFFBQUw7QUFDRSxhQUFPQyxxQkFBUDs7QUFDRixTQUFLLFNBQUw7QUFDRSxhQUFPQyx1QkFBUDs7QUFDRixTQUFLLE9BQUw7QUFDRSxhQUFPLElBQUlDLG9CQUFKLENBQWdCQyxtQkFBbUIsQ0FBQ0MsWUFBcEMsQ0FBUDs7QUFDRixTQUFLLFFBQUw7QUFDRSxhQUFPRCxtQkFBbUIsQ0FBQ0UsTUFBM0I7O0FBQ0YsU0FBSyxNQUFMO0FBQ0UsYUFBT0YsbUJBQW1CLENBQUNHLElBQTNCOztBQUNGLFNBQUssU0FBTDtBQUNFLFVBQ0VSLGVBQWUsSUFDZkEsZUFBZSxDQUFDRCxXQUFELENBRGYsSUFFQUMsZUFBZSxDQUFDRCxXQUFELENBQWYsQ0FBNkJVLHNCQUgvQixFQUlFO0FBQ0EsZUFBT1QsZUFBZSxDQUFDRCxXQUFELENBQWYsQ0FBNkJVLHNCQUFwQztBQUNELE9BTkQsTUFNTztBQUNMLGVBQU9KLG1CQUFtQixDQUFDRSxNQUEzQjtBQUNEOztBQUNILFNBQUssVUFBTDtBQUNFLFVBQ0VQLGVBQWUsSUFDZkEsZUFBZSxDQUFDRCxXQUFELENBRGYsSUFFQUMsZUFBZSxDQUFDRCxXQUFELENBQWYsQ0FBNkJXLDBCQUgvQixFQUlFO0FBQ0EsZUFBTyxJQUFJQyx1QkFBSixDQUFtQlgsZUFBZSxDQUFDRCxXQUFELENBQWYsQ0FBNkJXLDBCQUFoRCxDQUFQO0FBQ0QsT0FORCxNQU1PO0FBQ0wsZUFBTyxJQUFJQyx1QkFBSixDQUFtQk4sbUJBQW1CLENBQUNFLE1BQXZDLENBQVA7QUFDRDs7QUFDSCxTQUFLLE1BQUw7QUFDRSxhQUFPRixtQkFBbUIsQ0FBQ08sU0FBM0I7O0FBQ0YsU0FBSyxVQUFMO0FBQ0UsYUFBT1AsbUJBQW1CLENBQUNRLFNBQTNCOztBQUNGLFNBQUssU0FBTDtBQUNFLGFBQU9SLG1CQUFtQixDQUFDUyxPQUEzQjs7QUFDRixTQUFLLE9BQUw7QUFDRSxhQUFPVCxtQkFBbUIsQ0FBQ1UsS0FBM0I7O0FBQ0YsU0FBSyxLQUFMO0FBQ0UsYUFBTyxJQUFJSix1QkFBSixDQUFtQk4sbUJBQW1CLENBQUNXLEdBQXZDLENBQVA7O0FBQ0Y7QUFDRSxhQUFPQyxTQUFQO0FBNUNKO0FBOENELENBL0NEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZGVmYXVsdEdyYXBoUUxUeXBlcyBmcm9tICcuLi9sb2FkZXJzL2RlZmF1bHRHcmFwaFFMVHlwZXMnO1xuaW1wb3J0IHsgR3JhcGhRTFN0cmluZywgR3JhcGhRTEZsb2F0LCBHcmFwaFFMQm9vbGVhbiwgR3JhcGhRTExpc3QsIEdyYXBoUUxOb25OdWxsIH0gZnJvbSAnZ3JhcGhxbCc7XG5cbmNvbnN0IHRyYW5zZm9ybU91dHB1dFR5cGVUb0dyYXBoUUwgPSAocGFyc2VUeXBlLCB0YXJnZXRDbGFzcywgcGFyc2VDbGFzc1R5cGVzKSA9PiB7XG4gIHN3aXRjaCAocGFyc2VUeXBlKSB7XG4gICAgY2FzZSAnU3RyaW5nJzpcbiAgICAgIHJldHVybiBHcmFwaFFMU3RyaW5nO1xuICAgIGNhc2UgJ051bWJlcic6XG4gICAgICByZXR1cm4gR3JhcGhRTEZsb2F0O1xuICAgIGNhc2UgJ0Jvb2xlYW4nOlxuICAgICAgcmV0dXJuIEdyYXBoUUxCb29sZWFuO1xuICAgIGNhc2UgJ0FycmF5JzpcbiAgICAgIHJldHVybiBuZXcgR3JhcGhRTExpc3QoZGVmYXVsdEdyYXBoUUxUeXBlcy5BUlJBWV9SRVNVTFQpO1xuICAgIGNhc2UgJ09iamVjdCc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1Q7XG4gICAgY2FzZSAnRGF0ZSc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5EQVRFO1xuICAgIGNhc2UgJ1BvaW50ZXInOlxuICAgICAgaWYgKFxuICAgICAgICBwYXJzZUNsYXNzVHlwZXMgJiZcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXSAmJlxuICAgICAgICBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdLmNsYXNzR3JhcGhRTE91dHB1dFR5cGVcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXS5jbGFzc0dyYXBoUUxPdXRwdXRUeXBlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUO1xuICAgICAgfVxuICAgIGNhc2UgJ1JlbGF0aW9uJzpcbiAgICAgIGlmIChcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzICYmXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10gJiZcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXS5jbGFzc0dyYXBoUUxGaW5kUmVzdWx0VHlwZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBuZXcgR3JhcGhRTE5vbk51bGwocGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXS5jbGFzc0dyYXBoUUxGaW5kUmVzdWx0VHlwZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbmV3IEdyYXBoUUxOb25OdWxsKGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUKTtcbiAgICAgIH1cbiAgICBjYXNlICdGaWxlJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkZJTEVfSU5GTztcbiAgICBjYXNlICdHZW9Qb2ludCc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5HRU9fUE9JTlQ7XG4gICAgY2FzZSAnUG9seWdvbic6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5QT0xZR09OO1xuICAgIGNhc2UgJ0J5dGVzJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkJZVEVTO1xuICAgIGNhc2UgJ0FDTCc6XG4gICAgICByZXR1cm4gbmV3IEdyYXBoUUxOb25OdWxsKGRlZmF1bHRHcmFwaFFMVHlwZXMuQUNMKTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufTtcblxuZXhwb3J0IHsgdHJhbnNmb3JtT3V0cHV0VHlwZVRvR3JhcGhRTCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/transformers/query.js b/lib/GraphQL/transformers/query.js new file mode 100644 index 0000000000..d13b1cbb09 --- /dev/null +++ b/lib/GraphQL/transformers/query.js @@ -0,0 +1,273 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.transformQueryInputToParse = exports.transformQueryConstraintInputToParse = void 0; + +var _graphqlRelay = require("graphql-relay"); + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const parseQueryMap = { + OR: '$or', + AND: '$and', + NOR: '$nor' +}; +const parseConstraintMap = { + equalTo: '$eq', + notEqualTo: '$ne', + lessThan: '$lt', + lessThanOrEqualTo: '$lte', + greaterThan: '$gt', + greaterThanOrEqualTo: '$gte', + in: '$in', + notIn: '$nin', + exists: '$exists', + inQueryKey: '$select', + notInQueryKey: '$dontSelect', + inQuery: '$inQuery', + notInQuery: '$notInQuery', + containedBy: '$containedBy', + contains: '$all', + matchesRegex: '$regex', + options: '$options', + text: '$text', + search: '$search', + term: '$term', + language: '$language', + caseSensitive: '$caseSensitive', + diacriticSensitive: '$diacriticSensitive', + nearSphere: '$nearSphere', + maxDistance: '$maxDistance', + maxDistanceInRadians: '$maxDistanceInRadians', + maxDistanceInMiles: '$maxDistanceInMiles', + maxDistanceInKilometers: '$maxDistanceInKilometers', + within: '$within', + box: '$box', + geoWithin: '$geoWithin', + polygon: '$polygon', + centerSphere: '$centerSphere', + geoIntersects: '$geoIntersects', + point: '$point' +}; + +const transformQueryConstraintInputToParse = (constraints, parentFieldName, className, parentConstraints, parseClasses) => { + const fields = parseClasses.find(parseClass => parseClass.className === className).fields; + + if (parentFieldName === 'id' && className) { + Object.keys(constraints).forEach(constraintName => { + const constraintValue = constraints[constraintName]; + + if (typeof constraintValue === 'string') { + const globalIdObject = (0, _graphqlRelay.fromGlobalId)(constraintValue); + + if (globalIdObject.type === className) { + constraints[constraintName] = globalIdObject.id; + } + } else if (Array.isArray(constraintValue)) { + constraints[constraintName] = constraintValue.map(value => { + const globalIdObject = (0, _graphqlRelay.fromGlobalId)(value); + + if (globalIdObject.type === className) { + return globalIdObject.id; + } + + return value; + }); + } + }); + parentConstraints.objectId = constraints; + delete parentConstraints.id; + } + + Object.keys(constraints).forEach(fieldName => { + let fieldValue = constraints[fieldName]; + + if (parseConstraintMap[fieldName]) { + constraints[parseConstraintMap[fieldName]] = constraints[fieldName]; + delete constraints[fieldName]; + } + /** + * If we have a key-value pair, we need to change the way the constraint is structured. + * + * Example: + * From: + * { + * "someField": { + * "lessThan": { + * "key":"foo.bar", + * "value": 100 + * }, + * "greaterThan": { + * "key":"foo.bar", + * "value": 10 + * } + * } + * } + * + * To: + * { + * "someField.foo.bar": { + * "$lt": 100, + * "$gt": 10 + * } + * } + */ + + + if (fieldValue.key && fieldValue.value && parentConstraints && parentFieldName) { + delete parentConstraints[parentFieldName]; + parentConstraints[`${parentFieldName}.${fieldValue.key}`] = _objectSpread(_objectSpread({}, parentConstraints[`${parentFieldName}.${fieldValue.key}`]), {}, { + [parseConstraintMap[fieldName]]: fieldValue.value + }); + } else if (fields[parentFieldName] && (fields[parentFieldName].type === 'Pointer' || fields[parentFieldName].type === 'Relation')) { + const { + targetClass + } = fields[parentFieldName]; + + if (fieldName === 'exists') { + if (fields[parentFieldName].type === 'Relation') { + const whereTarget = fieldValue ? 'where' : 'notWhere'; + + if (constraints[whereTarget]) { + if (constraints[whereTarget].objectId) { + constraints[whereTarget].objectId = _objectSpread(_objectSpread({}, constraints[whereTarget].objectId), {}, { + $exists: fieldValue + }); + } else { + constraints[whereTarget].objectId = { + $exists: fieldValue + }; + } + } else { + const parseWhereTarget = fieldValue ? '$inQuery' : '$notInQuery'; + parentConstraints[parentFieldName][parseWhereTarget] = { + where: { + objectId: { + $exists: true + } + }, + className: targetClass + }; + } + + delete constraints.$exists; + } else { + parentConstraints[parentFieldName].$exists = fieldValue; + } + + return; + } + + switch (fieldName) { + case 'have': + parentConstraints[parentFieldName].$inQuery = { + where: fieldValue, + className: targetClass + }; + transformQueryInputToParse(parentConstraints[parentFieldName].$inQuery.where, targetClass, parseClasses); + break; + + case 'haveNot': + parentConstraints[parentFieldName].$notInQuery = { + where: fieldValue, + className: targetClass + }; + transformQueryInputToParse(parentConstraints[parentFieldName].$notInQuery.where, targetClass, parseClasses); + break; + } + + delete constraints[fieldName]; + return; + } + + switch (fieldName) { + case 'point': + if (typeof fieldValue === 'object' && !fieldValue.__type) { + fieldValue.__type = 'GeoPoint'; + } + + break; + + case 'nearSphere': + if (typeof fieldValue === 'object' && !fieldValue.__type) { + fieldValue.__type = 'GeoPoint'; + } + + break; + + case 'box': + if (typeof fieldValue === 'object' && fieldValue.bottomLeft && fieldValue.upperRight) { + fieldValue = [_objectSpread({ + __type: 'GeoPoint' + }, fieldValue.bottomLeft), _objectSpread({ + __type: 'GeoPoint' + }, fieldValue.upperRight)]; + constraints[parseConstraintMap[fieldName]] = fieldValue; + } + + break; + + case 'polygon': + if (fieldValue instanceof Array) { + fieldValue.forEach(geoPoint => { + if (typeof geoPoint === 'object' && !geoPoint.__type) { + geoPoint.__type = 'GeoPoint'; + } + }); + } + + break; + + case 'centerSphere': + if (typeof fieldValue === 'object' && fieldValue.center && fieldValue.distance) { + fieldValue = [_objectSpread({ + __type: 'GeoPoint' + }, fieldValue.center), fieldValue.distance]; + constraints[parseConstraintMap[fieldName]] = fieldValue; + } + + break; + } + + if (typeof fieldValue === 'object') { + if (fieldName === 'where') { + transformQueryInputToParse(fieldValue, className, parseClasses); + } else { + transformQueryConstraintInputToParse(fieldValue, fieldName, className, constraints, parseClasses); + } + } + }); +}; + +exports.transformQueryConstraintInputToParse = transformQueryConstraintInputToParse; + +const transformQueryInputToParse = (constraints, className, parseClasses) => { + if (!constraints || typeof constraints !== 'object') { + return; + } + + Object.keys(constraints).forEach(fieldName => { + const fieldValue = constraints[fieldName]; + + if (parseQueryMap[fieldName]) { + delete constraints[fieldName]; + fieldName = parseQueryMap[fieldName]; + constraints[fieldName] = fieldValue; + fieldValue.forEach(fieldValueItem => { + transformQueryInputToParse(fieldValueItem, className, parseClasses); + }); + return; + } else { + transformQueryConstraintInputToParse(fieldValue, fieldName, className, constraints, parseClasses); + } + }); +}; + +exports.transformQueryInputToParse = transformQueryInputToParse; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9xdWVyeS5qcyJdLCJuYW1lcyI6WyJwYXJzZVF1ZXJ5TWFwIiwiT1IiLCJBTkQiLCJOT1IiLCJwYXJzZUNvbnN0cmFpbnRNYXAiLCJlcXVhbFRvIiwibm90RXF1YWxUbyIsImxlc3NUaGFuIiwibGVzc1RoYW5PckVxdWFsVG8iLCJncmVhdGVyVGhhbiIsImdyZWF0ZXJUaGFuT3JFcXVhbFRvIiwiaW4iLCJub3RJbiIsImV4aXN0cyIsImluUXVlcnlLZXkiLCJub3RJblF1ZXJ5S2V5IiwiaW5RdWVyeSIsIm5vdEluUXVlcnkiLCJjb250YWluZWRCeSIsImNvbnRhaW5zIiwibWF0Y2hlc1JlZ2V4Iiwib3B0aW9ucyIsInRleHQiLCJzZWFyY2giLCJ0ZXJtIiwibGFuZ3VhZ2UiLCJjYXNlU2Vuc2l0aXZlIiwiZGlhY3JpdGljU2Vuc2l0aXZlIiwibmVhclNwaGVyZSIsIm1heERpc3RhbmNlIiwibWF4RGlzdGFuY2VJblJhZGlhbnMiLCJtYXhEaXN0YW5jZUluTWlsZXMiLCJtYXhEaXN0YW5jZUluS2lsb21ldGVycyIsIndpdGhpbiIsImJveCIsImdlb1dpdGhpbiIsInBvbHlnb24iLCJjZW50ZXJTcGhlcmUiLCJnZW9JbnRlcnNlY3RzIiwicG9pbnQiLCJ0cmFuc2Zvcm1RdWVyeUNvbnN0cmFpbnRJbnB1dFRvUGFyc2UiLCJjb25zdHJhaW50cyIsInBhcmVudEZpZWxkTmFtZSIsImNsYXNzTmFtZSIsInBhcmVudENvbnN0cmFpbnRzIiwicGFyc2VDbGFzc2VzIiwiZmllbGRzIiwiZmluZCIsInBhcnNlQ2xhc3MiLCJPYmplY3QiLCJrZXlzIiwiZm9yRWFjaCIsImNvbnN0cmFpbnROYW1lIiwiY29uc3RyYWludFZhbHVlIiwiZ2xvYmFsSWRPYmplY3QiLCJ0eXBlIiwiaWQiLCJBcnJheSIsImlzQXJyYXkiLCJtYXAiLCJ2YWx1ZSIsIm9iamVjdElkIiwiZmllbGROYW1lIiwiZmllbGRWYWx1ZSIsImtleSIsInRhcmdldENsYXNzIiwid2hlcmVUYXJnZXQiLCIkZXhpc3RzIiwicGFyc2VXaGVyZVRhcmdldCIsIndoZXJlIiwiJGluUXVlcnkiLCJ0cmFuc2Zvcm1RdWVyeUlucHV0VG9QYXJzZSIsIiRub3RJblF1ZXJ5IiwiX190eXBlIiwiYm90dG9tTGVmdCIsInVwcGVyUmlnaHQiLCJnZW9Qb2ludCIsImNlbnRlciIsImRpc3RhbmNlIiwiZmllbGRWYWx1ZUl0ZW0iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7Ozs7Ozs7QUFFQSxNQUFNQSxhQUFhLEdBQUc7QUFDcEJDLEVBQUFBLEVBQUUsRUFBRSxLQURnQjtBQUVwQkMsRUFBQUEsR0FBRyxFQUFFLE1BRmU7QUFHcEJDLEVBQUFBLEdBQUcsRUFBRTtBQUhlLENBQXRCO0FBTUEsTUFBTUMsa0JBQWtCLEdBQUc7QUFDekJDLEVBQUFBLE9BQU8sRUFBRSxLQURnQjtBQUV6QkMsRUFBQUEsVUFBVSxFQUFFLEtBRmE7QUFHekJDLEVBQUFBLFFBQVEsRUFBRSxLQUhlO0FBSXpCQyxFQUFBQSxpQkFBaUIsRUFBRSxNQUpNO0FBS3pCQyxFQUFBQSxXQUFXLEVBQUUsS0FMWTtBQU16QkMsRUFBQUEsb0JBQW9CLEVBQUUsTUFORztBQU96QkMsRUFBQUEsRUFBRSxFQUFFLEtBUHFCO0FBUXpCQyxFQUFBQSxLQUFLLEVBQUUsTUFSa0I7QUFTekJDLEVBQUFBLE1BQU0sRUFBRSxTQVRpQjtBQVV6QkMsRUFBQUEsVUFBVSxFQUFFLFNBVmE7QUFXekJDLEVBQUFBLGFBQWEsRUFBRSxhQVhVO0FBWXpCQyxFQUFBQSxPQUFPLEVBQUUsVUFaZ0I7QUFhekJDLEVBQUFBLFVBQVUsRUFBRSxhQWJhO0FBY3pCQyxFQUFBQSxXQUFXLEVBQUUsY0FkWTtBQWV6QkMsRUFBQUEsUUFBUSxFQUFFLE1BZmU7QUFnQnpCQyxFQUFBQSxZQUFZLEVBQUUsUUFoQlc7QUFpQnpCQyxFQUFBQSxPQUFPLEVBQUUsVUFqQmdCO0FBa0J6QkMsRUFBQUEsSUFBSSxFQUFFLE9BbEJtQjtBQW1CekJD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LEVBQUFBLE1BQU0sQ0FBQ0MsSUFBUCxDQUFZVCxXQUFaLEVBQXlCVSxPQUF6QixDQUFpQ1csU0FBUyxJQUFJO0FBQzVDLFVBQU1DLFVBQVUsR0FBR3RCLFdBQVcsQ0FBQ3FCLFNBQUQsQ0FBOUI7O0FBRUEsUUFBSTlELGFBQWEsQ0FBQzhELFNBQUQsQ0FBakIsRUFBOEI7QUFDNUIsYUFBT3JCLFdBQVcsQ0FBQ3FCLFNBQUQsQ0FBbEI7QUFDQUEsTUFBQUEsU0FBUyxHQUFHOUQsYUFBYSxDQUFDOEQsU0FBRCxDQUF6QjtBQUNBckIsTUFBQUEsV0FBVyxDQUFDcUIsU0FBRCxDQUFYLEdBQXlCQyxVQUF6QjtBQUNBQSxNQUFBQSxVQUFVLENBQUNaLE9BQVgsQ0FBbUI0QixjQUFjLElBQUk7QUFDbkNSLFFBQUFBLDBCQUEwQixDQUFDUSxjQUFELEVBQWlCcEMsU0FBakIsRUFBNEJFLFlBQTVCLENBQTFCO0FBQ0QsT0FGRDtBQUdBO0FBQ0QsS0FSRCxNQVFPO0FBQ0xMLE1BQUFBLG9DQUFvQyxDQUNsQ3VCLFVBRGtDLEVBRWxDRCxTQUZrQyxFQUdsQ25CLFNBSGtDLEVBSWxDRixXQUprQyxFQUtsQ0ksWUFMa0MsQ0FBcEM7QUFPRDtBQUNGLEdBcEJEO0FBcUJELENBMUJEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZnJvbUdsb2JhbElkIH0gZnJvbSAnZ3JhcGhxbC1yZWxheSc7XG5cbmNvbnN0IHBhcnNlUXVlcnlNYXAgPSB7XG4gIE9SOiAnJG9yJyxcbiAgQU5EOiAnJGFuZCcsXG4gIE5PUjogJyRub3InLFxufTtcblxuY29uc3QgcGFyc2VDb25zdHJhaW50TWFwID0ge1xuICBlcXVhbFRvOiAnJGVxJyxcbiAgbm90RXF1YWxUbzogJyRuZScsXG4gIGxlc3NUaGFuOiAnJGx0JyxcbiAgbGVzc1RoYW5PckVxdWFsVG86ICckbHRlJyxcbiAgZ3JlYXRlclRoYW46ICckZ3QnLFxuICBncmVhdGVyVGhhbk9yRXF1YWxUbzogJyRndGUnLFxuICBpbjogJyRpbicsXG4gIG5vdEluOiAnJG5pbicsXG4gIGV4aXN0czogJyRleGlzdHMnLFxuICBpblF1ZXJ5S2V5OiAnJHNlbGVjdCcsXG4gIG5vdEluUXVlcnlLZXk6ICckZG9udFNlbGVjdCcsXG4gIGluUXVlcnk6ICckaW5RdWVyeScsXG4gIG5vdEluUXVlcnk6ICckbm90SW5RdWVyeScsXG4gIGNvbnRhaW5lZEJ5OiAnJGNvbnRhaW5lZEJ5JyxcbiAgY29udGFpbnM6ICckYWxsJyxcbiAgbWF0Y2hlc1JlZ2V4OiAnJHJlZ2V4JyxcbiAgb3B0aW9uczogJyRvcHRpb25zJyxcbiAgdGV4dDogJyR0ZXh0JyxcbiAgc2VhcmNoOiAnJHNlYXJjaCcsXG4gIHRlcm06ICckdGVybScsXG4gIGxhbmd1YWdlOiAnJGxhbmd1YWdlJyxcbiAgY2FzZVNlbnNpdGl2ZTogJyRjYXNlU2Vuc2l0aXZlJyxcbiAgZGlhY3JpdGljU2Vuc2l0aXZlOiAnJGRpYWNyaXRpY1NlbnNpdGl2ZScsXG4gIG5lYXJTcGhlcmU6ICckbmVhclNwaGVyZScsXG4gIG1heERpc3RhbmNlOiAnJG1heERpc3RhbmNlJyxcbiAgbWF4RGlzdGFuY2VJblJhZGlhbnM6ICckbWF4RGlzdGFuY2VJblJhZGlhbnMnLFxuICBtYXhEaXN0YW5jZUluTWlsZXM6ICckbWF4RGlzdGFuY2VJbk1pbGVzJyxcbiAgbWF4RGlzdGFuY2VJbktpbG9tZXRlcnM6ICckbWF4RGlzdGFuY2VJbktpbG9tZXRlcnMnLFxuICB3aXRoaW46ICckd2l0aGluJyxcbiAgYm94OiAnJGJveCcsXG4gIGdlb1dpdGhpbjogJyRnZW9XaXRoaW4nLFxuICBwb2x5Z29uOiAnJHBvbHlnb24nLFxuICBjZW50ZXJTcGhlcmU6ICckY2VudGVyU3BoZXJlJyxcbiAgZ2VvSW50ZXJzZWN0czogJyRnZW9JbnRlcnNlY3RzJyxcbiAgcG9pbnQ6ICckcG9pbnQnLFxufTtcblxuY29uc3QgdHJhbnNmb3JtUXVlcnlDb25zdHJhaW50SW5wdXRUb1BhcnNlID0gKFxuICBjb25zdHJhaW50cyxcbiAgcGFyZW50RmllbGROYW1lLFxuICBjbGFzc05hbWUsXG4gIHBhcmVudENvbnN0cmFpbnRzLFxuICBwYXJzZUNsYXNzZXNcbikgPT4ge1xuICBjb25zdCBmaWVsZHMgPSBwYXJzZUNsYXNzZXMuZmluZChwYXJzZUNsYXNzID0+IHBhcnNlQ2xhc3MuY2xhc3NOYW1lID09PSBjbGFzc05hbWUpLmZpZWxkcztcbiAgaWYgKHBhcmVudEZpZWxkTmFtZSA9PT0gJ2lkJyAmJiBjbGFzc05hbWUpIHtcbiAgICBPYmplY3Qua2V5cyhjb25zdHJhaW50cykuZm9yRWFjaChjb25zdHJhaW50TmFtZSA9PiB7XG4gICAgICBjb25zdCBjb25zdHJhaW50VmFsdWUgPSBjb25zdHJhaW50c1tjb25zdHJhaW50TmFtZV07XG4gICAgICBpZiAodHlwZW9mIGNvbnN0cmFpbnRWYWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc3QgZ2xvYmFsSWRPYmplY3QgPSBmcm9tR2xvYmFsSWQoY29uc3RyYWludFZhbHVlKTtcblxuICAgICAgICBpZiAoZ2xvYmFsSWRPYmplY3QudHlwZSA9PT0gY2xhc3NOYW1lKSB7XG4gICAgICAgICAgY29uc3RyYWludHNbY29uc3RyYWludE5hbWVdID0gZ2xvYmFsSWRPYmplY3QuaWQ7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShjb25zdHJhaW50VmFsdWUpKSB7XG4gICAgICAgIGNvbnN0cmFpbnRzW2NvbnN0cmFpbnROYW1lXSA9IGNvbnN0cmFpbnRWYWx1ZS5tYXAodmFsdWUgPT4ge1xuICAgICAgICAgIGNvbnN0IGdsb2JhbElkT2JqZWN0ID0gZnJvbUdsb2JhbElkKHZhbHVlKTtcblxuICAgICAgICAgIGlmIChnbG9iYWxJZE9iamVjdC50eXBlID09PSBjbGFzc05hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiBnbG9iYWxJZE9iamVjdC5pZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHBhcmVudENvbnN0cmFpbnRzLm9iamVjdElkID0gY29uc3RyYWludHM7XG4gICAgZGVsZXRlIHBhcmVudENvbnN0cmFpbnRzLmlkO1xuICB9XG4gIE9iamVjdC5rZXlzKGNvbnN0cmFpbnRzKS5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgbGV0IGZpZWxkVmFsdWUgPSBjb25zdHJhaW50c1tmaWVsZE5hbWVdO1xuICAgIGlmIChwYXJzZUNvbnN0cmFpbnRNYXBbZmllbGROYW1lXSkge1xuICAgICAgY29uc3RyYWludHNbcGFyc2VDb25zdHJhaW50TWFwW2ZpZWxkTmFtZV1dID0gY29uc3RyYWludHNbZmllbGROYW1lXTtcbiAgICAgIGRlbGV0ZSBjb25zdHJhaW50c1tmaWVsZE5hbWVdO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB3ZSBoYXZlIGEga2V5LXZhbHVlIHBhaXIsIHdlIG5lZWQgdG8gY2hhbmdlIHRoZSB3YXkgdGhlIGNvbnN0cmFpbnQgaXMgc3RydWN0dXJlZC5cbiAgICAgKlxuICAgICAqIEV4YW1wbGU6XG4gICAgICogICBGcm9tOlxuICAgICAqICAge1xuICAgICAqICAgICBcInNvbWVGaWVsZFwiOiB7XG4gICAgICogICAgICAgXCJsZXNzVGhhblwiOiB7XG4gICAgICogICAgICAgICBcImtleVwiOlwiZm9vLmJhclwiLFxuICAgICAqICAgICAgICAgXCJ2YWx1ZVwiOiAxMDBcbiAgICAgKiAgICAgICB9LFxuICAgICAqICAgICAgIFwiZ3JlYXRlclRoYW5cIjoge1xuICAgICAqICAgICAgICAgXCJrZXlcIjpcImZvby5iYXJcIixcbiAgICAgKiAgICAgICAgIFwidmFsdWVcIjogMTBcbiAgICAgKiAgICAgICB9XG4gICAgICogICAgIH1cbiAgICAgKiAgIH1cbiAgICAgKlxuICAgICAqICAgVG86XG4gICAgICogICB7XG4gICAgICogICAgIFwic29tZUZpZWxkLmZvby5iYXJcIjoge1xuICAgICAqICAgICAgIFwiJGx0XCI6IDEwMCxcbiAgICAgKiAgICAgICBcIiRndFwiOiAxMFxuICAgICAqICAgICAgfVxuICAgICAqICAgfVxuICAgICAqL1xuICAgIGlmIChmaWVsZFZhbHVlLmtleSAmJiBmaWVsZFZhbHVlLnZhbHVlICYmIHBhcmVudENvbnN0cmFpbnRzICYmIHBhcmVudEZpZWxkTmFtZSkge1xuICAgICAgZGVsZXRlIHBhcmVudENvbnN0cmFpbnRzW3BhcmVudEZpZWxkTmFtZV07XG4gICAgICBwYXJlbnRDb25zdHJhaW50c1tgJHtwYXJlbnRGaWVsZE5hbWV9LiR7ZmllbGRWYWx1ZS5rZXl9YF0gPSB7XG4gICAgICAgIC4uLnBhcmVudENvbnN0cmFpbnRzW2Ake3BhcmVudEZpZWxkTmFtZX0uJHtmaWVsZFZhbHVlLmtleX1gXSxcbiAgICAgICAgW3BhcnNlQ29uc3RyYWludE1hcFtmaWVsZE5hbWVdXTogZmllbGRWYWx1ZS52YWx1ZSxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIGZpZWxkc1twYXJlbnRGaWVsZE5hbWVdICYmXG4gICAgICAoZmllbGRzW3BhcmVudEZpZWxkTmFtZV0udHlwZSA9PT0gJ1BvaW50ZXInIHx8IGZpZWxkc1twYXJlbnRGaWVsZE5hbWVdLnR5cGUgPT09ICdSZWxhdGlvbicpXG4gICAgKSB7XG4gICAgICBjb25zdCB7IHRhcmdldENsYXNzIH0gPSBmaWVsZHNbcGFyZW50RmllbGROYW1lXTtcbiAgICAgIGlmIChmaWVsZE5hbWUgPT09ICdleGlzdHMnKSB7XG4gICAgICAgIGlmIChmaWVsZHNbcGFyZW50RmllbGROYW1lXS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgICAgY29uc3Qgd2hlcmVUYXJnZXQgPSBmaWVsZFZhbHVlID8gJ3doZXJlJyA6ICdub3RXaGVyZSc7XG4gICAgICAgICAgaWYgKGNvbnN0cmFpbnRzW3doZXJlVGFyZ2V0XSkge1xuICAgICAgICAgICAgaWYgKGNvbnN0cmFpbnRzW3doZXJlVGFyZ2V0XS5vYmplY3RJZCkge1xuICAgICAgICAgICAgICBjb25zdHJhaW50c1t3aGVyZVRhcmdldF0ub2JqZWN0SWQgPSB7XG4gICAgICAgICAgICAgICAgLi4uY29uc3RyYWludHNbd2hlcmVUYXJnZXRdLm9iamVjdElkLFxuICAgICAgICAgICAgICAgICRleGlzdHM6IGZpZWxkVmFsdWUsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjb25zdHJhaW50c1t3aGVyZVRhcmdldF0ub2JqZWN0SWQgPSB7XG4gICAgICAgICAgICAgICAgJGV4aXN0czogZmllbGRWYWx1ZSxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgcGFyc2VXaGVyZVRhcmdldCA9IGZpZWxkVmFsdWUgPyAnJGluUXVlcnknIDogJyRub3RJblF1ZXJ5JztcbiAgICAgICAgICAgIHBhcmVudENvbnN0cmFpbnRzW3BhcmVudEZpZWxkTmFtZV1bcGFyc2VXaGVyZVRhcmdldF0gPSB7XG4gICAgICAgICAgICAgIHdoZXJlOiB7IG9iamVjdElkOiB7ICRleGlzdHM6IHRydWUgfSB9LFxuICAgICAgICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVsZXRlIGNvbnN0cmFpbnRzLiRleGlzdHM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcGFyZW50Q29uc3RyYWludHNbcGFyZW50RmllbGROYW1lXS4kZXhpc3RzID0gZmllbGRWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzd2l0Y2ggKGZpZWxkTmFtZSkge1xuICAgICAgICBjYXNlICdoYXZlJzpcbiAgICAgICAgICBwYXJlbnRDb25zdHJhaW50c1twYXJlbnRGaWVsZE5hbWVdLiRpblF1ZXJ5ID0ge1xuICAgICAgICAgICAgd2hlcmU6IGZpZWxkVmFsdWUsXG4gICAgICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICAgIH07XG4gICAgICAgICAgdHJhbnNmb3JtUXVlcnlJbnB1dFRvUGFyc2UoXG4gICAgICAgICAgICBwYXJlbnRDb25zdHJhaW50c1twYXJlbnRGaWVsZE5hbWVdLiRpblF1ZXJ5LndoZXJlLFxuICAgICAgICAgICAgdGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICBwYXJzZUNsYXNzZXNcbiAgICAgICAgICApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdoYXZlTm90JzpcbiAgICAgICAgICBwYXJlbnRDb25zdHJhaW50c1twYXJlbnRGaWVsZE5hbWVdLiRub3RJblF1ZXJ5ID0ge1xuICAgICAgICAgICAgd2hlcmU6IGZpZWxkVmFsdWUsXG4gICAgICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICAgIH07XG4gICAgICAgICAgdHJhbnNmb3JtUXVlcnlJbnB1dFRvUGFyc2UoXG4gICAgICAgICAgICBwYXJlbnRDb25zdHJhaW50c1twYXJlbnRGaWVsZE5hbWVdLiRub3RJblF1ZXJ5LndoZXJlLFxuICAgICAgICAgICAgdGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICBwYXJzZUNsYXNzZXNcbiAgICAgICAgICApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZGVsZXRlIGNvbnN0cmFpbnRzW2ZpZWxkTmFtZV07XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHN3aXRjaCAoZmllbGROYW1lKSB7XG4gICAgICBjYXNlICdwb2ludCc6XG4gICAgICAgIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ29iamVjdCcgJiYgIWZpZWxkVmFsdWUuX190eXBlKSB7XG4gICAgICAgICAgZmllbGRWYWx1ZS5fX3R5cGUgPSAnR2VvUG9pbnQnO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbmVhclNwaGVyZSc6XG4gICAgICAgIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ29iamVjdCcgJiYgIWZpZWxkVmFsdWUuX190eXBlKSB7XG4gICAgICAgICAgZmllbGRWYWx1ZS5fX3R5cGUgPSAnR2VvUG9pbnQnO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYm94JzpcbiAgICAgICAgaWYgKHR5cGVvZiBmaWVsZFZhbHVlID09PSAnb2JqZWN0JyAmJiBmaWVsZFZhbHVlLmJvdHRvbUxlZnQgJiYgZmllbGRWYWx1ZS51cHBlclJpZ2h0KSB7XG4gICAgICAgICAgZmllbGRWYWx1ZSA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgX190eXBlOiAnR2VvUG9pbnQnLFxuICAgICAgICAgICAgICAuLi5maWVsZFZhbHVlLmJvdHRvbUxlZnQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBfX3R5cGU6ICdHZW9Qb2ludCcsXG4gICAgICAgICAgICAgIC4uLmZpZWxkVmFsdWUudXBwZXJSaWdodCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXTtcbiAgICAgICAgICBjb25zdHJhaW50c1twYXJzZUNvbnN0cmFpbnRNYXBbZmllbGROYW1lXV0gPSBmaWVsZFZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAncG9seWdvbic6XG4gICAgICAgIGlmIChmaWVsZFZhbHVlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgICBmaWVsZFZhbHVlLmZvckVhY2goZ2VvUG9pbnQgPT4ge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBnZW9Qb2ludCA9PT0gJ29iamVjdCcgJiYgIWdlb1BvaW50Ll9fdHlwZSkge1xuICAgICAgICAgICAgICBnZW9Qb2ludC5fX3R5cGUgPSAnR2VvUG9pbnQnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnY2VudGVyU3BoZXJlJzpcbiAgICAgICAgaWYgKHR5cGVvZiBmaWVsZFZhbHVlID09PSAnb2JqZWN0JyAmJiBmaWVsZFZhbHVlLmNlbnRlciAmJiBmaWVsZFZhbHVlLmRpc3RhbmNlKSB7XG4gICAgICAgICAgZmllbGRWYWx1ZSA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgX190eXBlOiAnR2VvUG9pbnQnLFxuICAgICAgICAgICAgICAuLi5maWVsZFZhbHVlLmNlbnRlcixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBmaWVsZFZhbHVlLmRpc3RhbmNlLFxuICAgICAgICAgIF07XG4gICAgICAgICAgY29uc3RyYWludHNbcGFyc2VDb25zdHJhaW50TWFwW2ZpZWxkTmFtZV1dID0gZmllbGRWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBmaWVsZFZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKGZpZWxkTmFtZSA9PT0gJ3doZXJlJykge1xuICAgICAgICB0cmFuc2Zvcm1RdWVyeUlucHV0VG9QYXJzZShmaWVsZFZhbHVlLCBjbGFzc05hbWUsIHBhcnNlQ2xhc3Nlcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0cmFuc2Zvcm1RdWVyeUNvbnN0cmFpbnRJbnB1dFRvUGFyc2UoXG4gICAgICAgICAgZmllbGRWYWx1ZSxcbiAgICAgICAgICBmaWVsZE5hbWUsXG4gICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgIGNvbnN0cmFpbnRzLFxuICAgICAgICAgIHBhcnNlQ2xhc3Nlc1xuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1RdWVyeUlucHV0VG9QYXJzZSA9IChjb25zdHJhaW50cywgY2xhc3NOYW1lLCBwYXJzZUNsYXNzZXMpID0+IHtcbiAgaWYgKCFjb25zdHJhaW50cyB8fCB0eXBlb2YgY29uc3RyYWludHMgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgT2JqZWN0LmtleXMoY29uc3RyYWludHMpLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICBjb25zdCBmaWVsZFZhbHVlID0gY29uc3RyYWludHNbZmllbGROYW1lXTtcblxuICAgIGlmIChwYXJzZVF1ZXJ5TWFwW2ZpZWxkTmFtZV0pIHtcbiAgICAgIGRlbGV0ZSBjb25zdHJhaW50c1tmaWVsZE5hbWVdO1xuICAgICAgZmllbGROYW1lID0gcGFyc2VRdWVyeU1hcFtmaWVsZE5hbWVdO1xuICAgICAgY29uc3RyYWludHNbZmllbGROYW1lXSA9IGZpZWxkVmFsdWU7XG4gICAgICBmaWVsZFZhbHVlLmZvckVhY2goZmllbGRWYWx1ZUl0ZW0gPT4ge1xuICAgICAgICB0cmFuc2Zvcm1RdWVyeUlucHV0VG9QYXJzZShmaWVsZFZhbHVlSXRlbSwgY2xhc3NOYW1lLCBwYXJzZUNsYXNzZXMpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIHtcbiAgICAgIHRyYW5zZm9ybVF1ZXJ5Q29uc3RyYWludElucHV0VG9QYXJzZShcbiAgICAgICAgZmllbGRWYWx1ZSxcbiAgICAgICAgZmllbGROYW1lLFxuICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgIGNvbnN0cmFpbnRzLFxuICAgICAgICBwYXJzZUNsYXNzZXNcbiAgICAgICk7XG4gICAgfVxuICB9KTtcbn07XG5cbmV4cG9ydCB7IHRyYW5zZm9ybVF1ZXJ5Q29uc3RyYWludElucHV0VG9QYXJzZSwgdHJhbnNmb3JtUXVlcnlJbnB1dFRvUGFyc2UgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/transformers/schemaFields.js b/lib/GraphQL/transformers/schemaFields.js new file mode 100644 index 0000000000..1ca178f576 --- /dev/null +++ b/lib/GraphQL/transformers/schemaFields.js @@ -0,0 +1,128 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.transformToGraphQL = exports.transformToParse = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const transformToParse = (graphQLSchemaFields, existingFields) => { + if (!graphQLSchemaFields) { + return {}; + } + + let parseSchemaFields = {}; + + const reducerGenerator = type => (parseSchemaFields, field) => { + if (type === 'Remove') { + if (existingFields[field.name]) { + return _objectSpread(_objectSpread({}, parseSchemaFields), {}, { + [field.name]: { + __op: 'Delete' + } + }); + } else { + return parseSchemaFields; + } + } + + if (graphQLSchemaFields.remove && graphQLSchemaFields.remove.find(removeField => removeField.name === field.name)) { + return parseSchemaFields; + } + + if (parseSchemaFields[field.name] || existingFields && existingFields[field.name]) { + throw new _node.default.Error(_node.default.Error.INVALID_KEY_NAME, `Duplicated field name: ${field.name}`); + } + + if (type === 'Relation' || type === 'Pointer') { + return _objectSpread(_objectSpread({}, parseSchemaFields), {}, { + [field.name]: { + type, + targetClass: field.targetClassName + } + }); + } + + return _objectSpread(_objectSpread({}, parseSchemaFields), {}, { + [field.name]: { + type + } + }); + }; + + if (graphQLSchemaFields.addStrings) { + parseSchemaFields = graphQLSchemaFields.addStrings.reduce(reducerGenerator('String'), parseSchemaFields); + } + + if (graphQLSchemaFields.addNumbers) { + parseSchemaFields = graphQLSchemaFields.addNumbers.reduce(reducerGenerator('Number'), parseSchemaFields); + } + + if (graphQLSchemaFields.addBooleans) { + parseSchemaFields = graphQLSchemaFields.addBooleans.reduce(reducerGenerator('Boolean'), parseSchemaFields); + } + + if (graphQLSchemaFields.addArrays) { + parseSchemaFields = graphQLSchemaFields.addArrays.reduce(reducerGenerator('Array'), parseSchemaFields); + } + + if (graphQLSchemaFields.addObjects) { + parseSchemaFields = graphQLSchemaFields.addObjects.reduce(reducerGenerator('Object'), parseSchemaFields); + } + + if (graphQLSchemaFields.addDates) { + parseSchemaFields = graphQLSchemaFields.addDates.reduce(reducerGenerator('Date'), parseSchemaFields); + } + + if (graphQLSchemaFields.addFiles) { + parseSchemaFields = graphQLSchemaFields.addFiles.reduce(reducerGenerator('File'), parseSchemaFields); + } + + if (graphQLSchemaFields.addGeoPoint) { + parseSchemaFields = [graphQLSchemaFields.addGeoPoint].reduce(reducerGenerator('GeoPoint'), parseSchemaFields); + } + + if (graphQLSchemaFields.addPolygons) { + parseSchemaFields = graphQLSchemaFields.addPolygons.reduce(reducerGenerator('Polygon'), parseSchemaFields); + } + + if (graphQLSchemaFields.addBytes) { + parseSchemaFields = graphQLSchemaFields.addBytes.reduce(reducerGenerator('Bytes'), parseSchemaFields); + } + + if (graphQLSchemaFields.addPointers) { + parseSchemaFields = graphQLSchemaFields.addPointers.reduce(reducerGenerator('Pointer'), parseSchemaFields); + } + + if (graphQLSchemaFields.addRelations) { + parseSchemaFields = graphQLSchemaFields.addRelations.reduce(reducerGenerator('Relation'), parseSchemaFields); + } + + if (existingFields && graphQLSchemaFields.remove) { + parseSchemaFields = graphQLSchemaFields.remove.reduce(reducerGenerator('Remove'), parseSchemaFields); + } + + return parseSchemaFields; +}; + +exports.transformToParse = transformToParse; + +const transformToGraphQL = parseSchemaFields => { + return Object.keys(parseSchemaFields).map(name => ({ + name, + type: parseSchemaFields[name].type, + targetClassName: parseSchemaFields[name].targetClass + })); +}; + +exports.transformToGraphQL = transformToGraphQL; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9zY2hlbWFGaWVsZHMuanMiXSwibmFtZXMiOlsidHJhbnNmb3JtVG9QYXJzZSIsImdyYXBoUUxTY2hlbWFGaWVsZHMiLCJleGlzdGluZ0ZpZWxkcyIsInBhcnNlU2NoZW1hRmllbGRzIiwicmVkdWNlckdlbmVyYXRvciIsInR5cGUiLCJmaWVsZCIsIm5hbWUiLCJfX29wIiwicmVtb3ZlIiwiZmluZCIsInJlbW92ZUZpZWxkIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfS0VZX05BTUUiLCJ0YXJnZXRDbGFzcyIsInRhcmdldENsYXNzTmFtZSIsImFkZFN0cmluZ3MiLCJyZWR1Y2UiLCJhZGROdW1iZXJzIiwiYWRkQm9vbGVhbnMiLCJhZGRBcnJheXMiLCJhZGRPYmplY3RzIiwiYWRkRGF0ZXMiLCJhZGRGaWxlcyIsImFkZEdlb1BvaW50IiwiYWRkUG9seWdvbnMiLCJhZGRCeXRlcyIsImFkZFBvaW50ZXJzIiwiYWRkUmVsYXRpb25zIiwidHJhbnNmb3JtVG9HcmFwaFFMIiwiT2JqZWN0Iiwia2V5cyIsIm1hcCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7Ozs7Ozs7O0FBRUEsTUFBTUEsZ0JBQWdCLEdBQUcsQ0FBQ0MsbUJBQUQsRUFBc0JDLGNBQXRCLEtBQXlDO0FBQ2hFLE1BQUksQ0FBQ0QsbUJBQUwsRUFBMEI7QUFDeEIsV0FBTyxFQUFQO0FBQ0Q7O0FBRUQsTUFBSUUsaUJBQWlCLEdBQUcsRUFBeEI7O0FBRUEsUUFBTUMsZ0JBQWdCLEdBQUdDLElBQUksSUFBSSxDQUFDRixpQkFBRCxFQUFvQkcsS0FBcEIsS0FBOEI7QUFDN0QsUUFBSUQsSUFBSSxLQUFLLFFBQWIsRUFBdUI7QUFDckIsVUFBSUgsY0FBYyxDQUFDSSxLQUFLLENBQUNDLElBQVAsQ0FBbEIsRUFBZ0M7QUFDOUIsK0NBQ0tKLGlCQURMO0FBRUUsV0FBQ0csS0FBSyxDQUFDQyxJQUFQLEdBQWM7QUFDWkMsWUFBQUEsSUFB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QTlIRDs7OztBQWdJQSxNQUFNMkIsa0JBQWtCLEdBQUczQixpQkFBaUIsSUFBSTtBQUM5QyxTQUFPNEIsTUFBTSxDQUFDQyxJQUFQLENBQVk3QixpQkFBWixFQUErQjhCLEdBQS9CLENBQW1DMUIsSUFBSSxLQUFLO0FBQ2pEQSxJQUFBQSxJQURpRDtBQUVqREYsSUFBQUEsSUFBSSxFQUFFRixpQkFBaUIsQ0FBQ0ksSUFBRCxDQUFqQixDQUF3QkYsSUFGbUI7QUFHakRXLElBQUFBLGVBQWUsRUFBRWIsaUJBQWlCLENBQUNJLElBQUQsQ0FBakIsQ0FBd0JRO0FBSFEsR0FBTCxDQUF2QyxDQUFQO0FBS0QsQ0FORCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcblxuY29uc3QgdHJhbnNmb3JtVG9QYXJzZSA9IChncmFwaFFMU2NoZW1hRmllbGRzLCBleGlzdGluZ0ZpZWxkcykgPT4ge1xuICBpZiAoIWdyYXBoUUxTY2hlbWFGaWVsZHMpIHtcbiAgICByZXR1cm4ge307XG4gIH1cblxuICBsZXQgcGFyc2VTY2hlbWFGaWVsZHMgPSB7fTtcblxuICBjb25zdCByZWR1Y2VyR2VuZXJhdG9yID0gdHlwZSA9PiAocGFyc2VTY2hlbWFGaWVsZHMsIGZpZWxkKSA9PiB7XG4gICAgaWYgKHR5cGUgPT09ICdSZW1vdmUnKSB7XG4gICAgICBpZiAoZXhpc3RpbmdGaWVsZHNbZmllbGQubmFtZV0pIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5wYXJzZVNjaGVtYUZpZWxkcyxcbiAgICAgICAgICBbZmllbGQubmFtZV06IHtcbiAgICAgICAgICAgIF9fb3A6ICdEZWxldGUnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gcGFyc2VTY2hlbWFGaWVsZHM7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChcbiAgICAgIGdyYXBoUUxTY2hlbWFGaWVsZHMucmVtb3ZlICYmXG4gICAgICBncmFwaFFMU2NoZW1hRmllbGRzLnJlbW92ZS5maW5kKHJlbW92ZUZpZWxkID0+IHJlbW92ZUZpZWxkLm5hbWUgPT09IGZpZWxkLm5hbWUpXG4gICAgKSB7XG4gICAgICByZXR1cm4gcGFyc2VTY2hlbWFGaWVsZHM7XG4gICAgfVxuICAgIGlmIChwYXJzZVNjaGVtYUZpZWxkc1tmaWVsZC5uYW1lXSB8fCAoZXhpc3RpbmdGaWVsZHMgJiYgZXhpc3RpbmdGaWVsZHNbZmllbGQubmFtZV0pKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSwgYER1cGxpY2F0ZWQgZmllbGQgbmFtZTogJHtmaWVsZC5uYW1lfWApO1xuICAgIH1cbiAgICBpZiAodHlwZSA9PT0gJ1JlbGF0aW9uJyB8fCB0eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLnBhcnNlU2NoZW1hRmllbGRzLFxuICAgICAgICBbZmllbGQubmFtZV06IHtcbiAgICAgICAgICB0eXBlLFxuICAgICAgICAgIHRhcmdldENsYXNzOiBmaWVsZC50YXJnZXRDbGFzc05hbWUsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgLi4ucGFyc2VTY2hlbWFGaWVsZHMsXG4gICAgICBbZmllbGQubmFtZV06IHtcbiAgICAgICAgdHlwZSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfTtcblxuICBpZiAoZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRTdHJpbmdzKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLmFkZFN0cmluZ3MucmVkdWNlKFxuICAgICAgcmVkdWNlckdlbmVyYXRvcignU3RyaW5nJyksXG4gICAgICBwYXJzZVNjaGVtYUZpZWxkc1xuICAgICk7XG4gIH1cbiAgaWYgKGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkTnVtYmVycykge1xuICAgIHBhcnNlU2NoZW1hRmllbGRzID0gZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGROdW1iZXJzLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ051bWJlcicpLFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNcbiAgICApO1xuICB9XG4gIGlmIChncmFwaFFMU2NoZW1hRmllbGRzLmFkZEJvb2xlYW5zKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLmFkZEJvb2xlYW5zLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ0Jvb2xlYW4nKSxcbiAgICAgIHBhcnNlU2NoZW1hRmllbGRzXG4gICAgKTtcbiAgfVxuICBpZiAoZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRBcnJheXMpIHtcbiAgICBwYXJzZVNjaGVtYUZpZWxkcyA9IGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkQXJyYXlzLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ0FycmF5JyksXG4gICAgICBwYXJzZVNjaGVtYUZpZWxkc1xuICAgICk7XG4gIH1cbiAgaWYgKGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkT2JqZWN0cykge1xuICAgIHBhcnNlU2NoZW1hRmllbGRzID0gZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRPYmplY3RzLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ09iamVjdCcpLFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNcbiAgICApO1xuICB9XG4gIGlmIChncmFwaFFMU2NoZW1hRmllbGRzLmFkZERhdGVzKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLmFkZERhdGVzLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ0RhdGUnKSxcbiAgICAgIHBhcnNlU2NoZW1hRmllbGRzXG4gICAgKTtcbiAgfVxuICBpZiAoZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRGaWxlcykge1xuICAgIHBhcnNlU2NoZW1hRmllbGRzID0gZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRGaWxlcy5yZWR1Y2UoXG4gICAgICByZWR1Y2VyR2VuZXJhdG9yKCdGaWxlJyksXG4gICAgICBwYXJzZVNjaGVtYUZpZWxkc1xuICAgICk7XG4gIH1cbiAgaWYgKGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkR2VvUG9pbnQpIHtcbiAgICBwYXJzZVNjaGVtYUZpZWxkcyA9IFtncmFwaFFMU2NoZW1hRmllbGRzLmFkZEdlb1BvaW50XS5yZWR1Y2UoXG4gICAgICByZWR1Y2VyR2VuZXJhdG9yKCdHZW9Qb2ludCcpLFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNcbiAgICApO1xuICB9XG4gIGlmIChncmFwaFFMU2NoZW1hRmllbGRzLmFkZFBvbHlnb25zKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLmFkZFBvbHlnb25zLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ1BvbHlnb24nKSxcbiAgICAgIHBhcnNlU2NoZW1hRmllbGRzXG4gICAgKTtcbiAgfVxuICBpZiAoZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRCeXRlcykge1xuICAgIHBhcnNlU2NoZW1hRmllbGRzID0gZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRCeXRlcy5yZWR1Y2UoXG4gICAgICByZWR1Y2VyR2VuZXJhdG9yKCdCeXRlcycpLFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNcbiAgICApO1xuICB9XG4gIGlmIChncmFwaFFMU2NoZW1hRmllbGRzLmFkZFBvaW50ZXJzKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLmFkZFBvaW50ZXJzLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ1BvaW50ZXInKSxcbiAgICAgIHBhcnNlU2NoZW1hRmllbGRzXG4gICAgKTtcbiAgfVxuICBpZiAoZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRSZWxhdGlvbnMpIHtcbiAgICBwYXJzZVNjaGVtYUZpZWxkcyA9IGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkUmVsYXRpb25zLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ1JlbGF0aW9uJyksXG4gICAgICBwYXJzZVNjaGVtYUZpZWxkc1xuICAgICk7XG4gIH1cbiAgaWYgKGV4aXN0aW5nRmllbGRzICYmIGdyYXBoUUxTY2hlbWFGaWVsZHMucmVtb3ZlKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLnJlbW92ZS5yZWR1Y2UoXG4gICAgICByZWR1Y2VyR2VuZXJhdG9yKCdSZW1vdmUnKSxcbiAgICAgIHBhcnNlU2NoZW1hRmllbGRzXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiBwYXJzZVNjaGVtYUZpZWxkcztcbn07XG5cbmNvbnN0IHRyYW5zZm9ybVRvR3JhcGhRTCA9IHBhcnNlU2NoZW1hRmllbGRzID0+IHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKHBhcnNlU2NoZW1hRmllbGRzKS5tYXAobmFtZSA9PiAoe1xuICAgIG5hbWUsXG4gICAgdHlwZTogcGFyc2VTY2hlbWFGaWVsZHNbbmFtZV0udHlwZSxcbiAgICB0YXJnZXRDbGFzc05hbWU6IHBhcnNlU2NoZW1hRmllbGRzW25hbWVdLnRhcmdldENsYXNzLFxuICB9KSk7XG59O1xuXG5leHBvcnQgeyB0cmFuc2Zvcm1Ub1BhcnNlLCB0cmFuc2Zvcm1Ub0dyYXBoUUwgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/Client.js b/lib/LiveQuery/Client.js new file mode 100644 index 0000000000..205e284d05 --- /dev/null +++ b/lib/LiveQuery/Client.js @@ -0,0 +1,114 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Client = void 0; + +var _logger = _interopRequireDefault(require("../logger")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const dafaultFields = ['className', 'objectId', 'updatedAt', 'createdAt', 'ACL']; + +class Client { + constructor(id, parseWebSocket, hasMasterKey = false, sessionToken, installationId) { + this.id = id; + this.parseWebSocket = parseWebSocket; + this.hasMasterKey = hasMasterKey; + this.sessionToken = sessionToken; + this.installationId = installationId; + this.roles = []; + this.subscriptionInfos = new Map(); + this.pushConnect = this._pushEvent('connected'); + this.pushSubscribe = this._pushEvent('subscribed'); + this.pushUnsubscribe = this._pushEvent('unsubscribed'); + this.pushCreate = this._pushEvent('create'); + this.pushEnter = this._pushEvent('enter'); + this.pushUpdate = this._pushEvent('update'); + this.pushDelete = this._pushEvent('delete'); + this.pushLeave = this._pushEvent('leave'); + } + + static pushResponse(parseWebSocket, message) { + _logger.default.verbose('Push Response : %j', message); + + parseWebSocket.send(message); + } + + static pushError(parseWebSocket, code, error, reconnect = true, requestId = null) { + Client.pushResponse(parseWebSocket, JSON.stringify({ + op: 'error', + error, + code, + reconnect, + requestId + })); + } + + addSubscriptionInfo(requestId, subscriptionInfo) { + this.subscriptionInfos.set(requestId, subscriptionInfo); + } + + getSubscriptionInfo(requestId) { + return this.subscriptionInfos.get(requestId); + } + + deleteSubscriptionInfo(requestId) { + return this.subscriptionInfos.delete(requestId); + } + + _pushEvent(type) { + return function (subscriptionId, parseObjectJSON, parseOriginalObjectJSON) { + const response = { + op: type, + clientId: this.id, + installationId: this.installationId + }; + + if (typeof subscriptionId !== 'undefined') { + response['requestId'] = subscriptionId; + } + + if (typeof parseObjectJSON !== 'undefined') { + let fields; + + if (this.subscriptionInfos.has(subscriptionId)) { + fields = this.subscriptionInfos.get(subscriptionId).fields; + } + + response['object'] = this._toJSONWithFields(parseObjectJSON, fields); + + if (parseOriginalObjectJSON) { + response['original'] = this._toJSONWithFields(parseOriginalObjectJSON, fields); + } + } + + Client.pushResponse(this.parseWebSocket, JSON.stringify(response)); + }; + } + + _toJSONWithFields(parseObjectJSON, fields) { + if (!fields) { + return parseObjectJSON; + } + + const limitedParseObject = {}; + + for (const field of dafaultFields) { + limitedParseObject[field] = parseObjectJSON[field]; + } + + for (const field of fields) { + if (field in parseObjectJSON) { + limitedParseObject[field] = parseObjectJSON[field]; + } + } + + return limitedParseObject; + } + +} + +exports.Client = Client; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvQ2xpZW50LmpzIl0sIm5hbWVzIjpbImRhZmF1bHRGaWVsZHMiLCJDbGllbnQiLCJjb25zdHJ1Y3RvciIsImlkIiwicGFyc2VXZWJTb2NrZXQiLCJoYXNNYXN0ZXJLZXkiLCJzZXNzaW9uVG9rZW4iLCJpbnN0YWxsYXRpb25JZCIsInJvbGVzIiwic3Vic2NyaXB0aW9uSW5mb3MiLCJNYXAiLCJwdXNoQ29ubmVjdCIsIl9wdXNoRXZlbnQiLCJwdXNoU3Vic2NyaWJlIiwicHVzaFVuc3Vic2NyaWJlIiwicHVzaENyZWF0ZSIsInB1c2hFbnRlciIsInB1c2hVcGRhdGUiLCJwdXNoRGVsZXRlIiwicHVzaExlYXZlIiwicHVzaFJlc3BvbnNlIiwibWVzc2FnZSIsImxvZ2dlciIsInZlcmJvc2UiLCJzZW5kIiwicHVzaEVycm9yIiwiY29kZSIsImVycm9yIiwicmVjb25uZWN0IiwicmVxdWVzdElkIiwiSlNPTiIsInN0cmluZ2lmeSIsIm9wIiwiYWRkU3Vic2NyaXB0aW9uSW5mbyIsInN1YnNjcmlwdGlvbkluZm8iLCJzZXQiLCJnZXRTdWJzY3JpcHRpb25JbmZvIiwiZ2V0IiwiZGVsZXRlU3Vic2NyaXB0aW9uSW5mbyIsImRlbGV0ZSIsInR5cGUiLCJzdWJzY3JpcHRpb25JZCIsInBhcnNlT2JqZWN0SlNPTiIsInBhcnNlT3JpZ2luYWxPYmplY3RKU09OIiwicmVzcG9uc2UiLCJjbGllbnRJZCIsImZpZWxkcyIsImhhcyIsIl90b0pTT05XaXRoRmllbGRzIiwibGltaXRlZFBhcnNlT2JqZWN0IiwiZmllbGQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7OztBQUtBLE1BQU1BLGFBQWEsR0FBRyxDQUFDLFdBQUQsRUFBYyxVQUFkLEVBQTBCLFdBQTFCLEVBQXVDLFdBQXZDLEVBQW9ELEtBQXBELENBQXRCOztBQUVBLE1BQU1DLE1BQU4sQ0FBYTtBQWtCWEMsRUFBQUEsV0FBVyxDQUNUQyxFQURTLEVBRVRDLGNBRlMsRUFHVEMsWUFBcUIsR0FBRyxLQUhmLEVBSVRDLFlBSlMsRUFLVEMsY0FMUyxFQU1UO0FBQ0EsU0FBS0osRUFBTCxHQUFVQSxFQUFWO0FBQ0EsU0FBS0MsY0FBTCxHQUFzQkEsY0FBdEI7QUFDQSxTQUFLQyxZQUFMLEdBQW9CQSxZQUFwQjtBQUNBLFNBQUtDLFlBQUwsR0FBb0JBLFlBQXBCO0FBQ0EsU0FBS0MsY0FBTCxHQUFzQkEsY0FBdEI7QUFDQSxTQUFLQyxLQUFMLEdBQWEsRUFBYjtBQUNBLFNBQUtDLGlCQUFMLEdBQXlCLElBQUlDLEdBQUosRUFBekI7QUFDQSxTQUFLQyxXQUFMLEdBQW1CLEtBQUtDLFVBQUwsQ0FBZ0IsV0FBaEIsQ0FBbkI7QUFDQSxTQUFLQyxhQUFMLEdBQXFCLEtBQUtELFVBQUwsQ0FBZ0IsWUFBaEIsQ0FBckI7QUFDQSxTQUFLRSxlQUFMLEdBQXVCLEtBQUtGLFVBQUwsQ0FBZ0IsY0FBaEIsQ0FBdkI7QUFDQSxTQUFLRyxVQUFMLEdBQWtCLEtBQUtILFVBQUwsQ0FBZ0IsUUFBaEIsQ0FBbEI7QUFDQSxTQUFLSSxTQUFMLEdBQWlCLEtBQUtKLFVBQUwsQ0FBZ0IsT0FBaEIsQ0FBakI7QUFDQSxTQUFLSyxVQUFMLEdBQWtCLEtBQUtMLFVBQUwsQ0FBZ0IsUUFBaEIsQ0FBbEI7QUFDQSxTQUFLTSxVQUFMLEdBQWtCLEtBQUtOLFVBQUwsQ0FBZ0IsUUFBaEIsQ0FBbEI7QUFDQSxTQUFLTyxTQUFMLEdBQWlCLEtBQUtQLFVBQUwsQ0FBZ0IsT0FBaEIsQ0FBakI7QUFDRDs7QUFFRCxTQUFPUSxZQUFQLENBQW9CaEIsY0FBcEIsRUFBeUNpQixPQUF6QyxFQUFpRTtBQUMvREMsb0JBQU9DLE9BQVAsQ0FBZSxvQkFBZixFQUFxQ0YsT0FBckM7O0FBQ0FqQixJQUFBQSxjQUFjLENBQUNvQixJQUFmLENBQW9CSCxPQUFwQjtBQUNEOztBQUVELFNBQU9JLFNBQVAsQ0FDRXJCLGNBREYsRUFFRXNCLElBRkYsRUFHRUMsS0FIRixFQUlFQyxTQUFrQixHQUFHLElBSnZCLEVBS0VDLFNBQXdCLEdBQUcsSUFMN0IsRUFNUTtBQUNONUIsSUFBQUEsTUFBTSxDQUFDbUIsWUFBUCxDQUNFaEIsY0FERixFQUVFMEIsSUFBSSxDQUFDQyxTQUFMLENBQWU7QUFDYkMsTUFBQUEsRUFBRSxFQUFFLE9BRFM7QUFFYkwsTUFBQUEsS0FGYTtBQUdiRCxNQUFBQSxJQUhhO0FBSWJFLE1BQUFBLFNBSmE7QUFLYkMsTUFBQUE7QUFMYSxLQUFmLENBRkY7QUFVRDs7QUFFREksRUFBQUEsbUJBQW1CLENBQUNKLFNBQUQsRUFBb0JLLGdCQUFwQixFQUFpRDtBQUNsRSxTQUFLekIsaUJBQUwsQ0FBdUIwQixHQUF2QixDQUEyQk4sU0FBM0IsRUFBc0NLLGdCQUF0QztBQUNEOztBQUVERSxFQUFBQSxtQkFBbUIsQ0FBQ1AsU0FBRCxFQUF5QjtBQUMxQyxXQUFPLEtBQUtwQixpQkFBTCxDQUF1QjRCLEdBQXZCLENBQTJCUixTQUEzQixDQUFQO0FBQ0Q7O0FBRURTLEVBQUFBLHNCQUFzQixDQUFDVCxTQUFELEVBQTBCO0FBQzlDLFdBQU8sS0FBS3BCLGlCQUFMLENBQXVCOEIsTUFBdkIsQ0FBOEJWLFNBQTlCLENBQVA7QUFDRDs7QUFFRGpCLEVBQUFBLFVBQVUsQ0FBQzRCLElBQUQsRUFBeUI7QUFDakMsV0FBTyxVQUNMQyxjQURLLEVBRUxDLGVBRkssRUFHTEMsdUJBSEssRUFJQztBQUNOLFlBQU1DLFFBQWlCLEdBQUc7QUFDeEJaLFFBQUFBLEVBQUUsRUFBRVEsSUFEb0I7QUFFeEJLLFFBQUFBLFFBQVEsRUFBRSxLQUFLMUMsRUFGUztBQUd4QkksUUFBQUEsY0FBYyxFQUFFLEtBQUtBO0FBSEcsT0FBMUI7O0FBS0EsVUFBSSxPQUFPa0MsY0FBUCxLQUEwQixXQUE5QixFQUEyQztBQUN6Q0csUUFBQUEsUUFBUSxDQUFDLFdBQUQsQ0FBUixHQUF3QkgsY0FBeEI7QUFDRDs7QUFDRCxVQUFJLE9BQU9DLGVBQVAsS0FBMkIsV0FBL0IsRUFBNEM7QUFDMUMsWUFBSUksTUFBSjs7QUFDQSxZQUFJLEtBQUtyQyxpQkFBTCxDQUF1QnNDLEdBQXZCLENBQTJCTixjQUEzQixDQUFKLEVBQWdEO0FBQzlDSyxVQUFBQSxNQUFNLEdBQUcsS0FBS3JDLGlCQUFMLENBQXVCNEIsR0FBdkIsQ0FBMkJJLGNBQTNCLEVBQTJDSyxNQUFwRDtBQUNEOztBQUNERixRQUFBQSxRQUFRLENBQUMsUUFBRCxDQUFSLEdBQXFCLEtBQUtJLGlCQUFMLENBQXVCTixlQUF2QixFQUF3Q0ksTUFBeEMsQ0FBckI7O0FBQ0EsWUFBSUgsdUJBQUosRUFBNkI7QUFDM0JDLFVBQUFBLFFBQVEsQ0FBQyxVQUFELENBQVIsR0FBdUIsS0FBS0ksaUJBQUwsQ0FBdUJMLHVCQUF2QixFQUFnREcsTUFBaEQsQ0FBdkI7QUFDRDtBQUNGOztBQUNEN0MsTUFBQUEsTUFBTSxDQUFDbUIsWUFBUCxDQUFvQixLQUFLaEIsY0FBekIsRUFBeUMwQixJQUFJLENBQUNDLFNBQUwsQ0FBZWEsUUFBZixDQUF6QztBQUNELEtBeEJEO0FBeUJEOztBQUVESSxFQUFBQSxpQkFBaUIsQ0FBQ04sZUFBRCxFQUF1QkksTUFBdkIsRUFBeUQ7QUFDeEUsUUFBSSxDQUFDQSxNQUFMLEVBQWE7QUFDWCxhQUFPSixlQUFQO0FBQ0Q7O0FBQ0QsVUFBTU8sa0JBQWtCLEdBQUcsRUFBM0I7O0FBQ0EsU0FBSyxNQUFNQyxLQUFYLElBQW9CbEQsYUFBcEIsRUFBbUM7QUFDakNpRCxNQUFBQSxrQkFBa0IsQ0FBQ0MsS0FBRCxDQUFsQixHQUE0QlIsZUFBZSxDQUFDUSxLQUFELENBQTNDO0FBQ0Q7O0FBQ0QsU0FBSyxNQUFNQSxLQUFYLElBQW9CSixNQUFwQixFQUE0QjtBQUMxQixVQUFJSSxLQUFLLElBQUlSLGVBQWIsRUFBOEI7QUFDNUJPLFFBQUFBLGtCQUFrQixDQUFDQyxLQUFELENBQWxCLEdBQTRCUixlQUFlLENBQUNRLEtBQUQsQ0FBM0M7QUFDRDtBQUNGOztBQUNELFdBQU9ELGtCQUFQO0FBQ0Q7O0FBeEhVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGxvZ2dlciBmcm9tICcuLi9sb2dnZXInO1xuXG5pbXBvcnQgdHlwZSB7IEZsYXR0ZW5lZE9iamVjdERhdGEgfSBmcm9tICcuL1N1YnNjcmlwdGlvbic7XG5leHBvcnQgdHlwZSBNZXNzYWdlID0geyBbYXR0cjogc3RyaW5nXTogYW55IH07XG5cbmNvbnN0IGRhZmF1bHRGaWVsZHMgPSBbJ2NsYXNzTmFtZScsICdvYmplY3RJZCcsICd1cGRhdGVkQXQnLCAnY3JlYXRlZEF0JywgJ0FDTCddO1xuXG5jbGFzcyBDbGllbnQge1xuICBpZDogbnVtYmVyO1xuICBwYXJzZVdlYlNvY2tldDogYW55O1xuICBoYXNNYXN0ZXJLZXk6IGJvb2xlYW47XG4gIHNlc3Npb25Ub2tlbjogc3RyaW5nO1xuICBpbnN0YWxsYXRpb25JZDogc3RyaW5nO1xuICB1c2VySWQ6IHN0cmluZztcbiAgcm9sZXM6IEFycmF5PHN0cmluZz47XG4gIHN1YnNjcmlwdGlvbkluZm9zOiBPYmplY3Q7XG4gIHB1c2hDb25uZWN0OiBGdW5jdGlvbjtcbiAgcHVzaFN1YnNjcmliZTogRnVuY3Rpb247XG4gIHB1c2hVbnN1YnNjcmliZTogRnVuY3Rpb247XG4gIHB1c2hDcmVhdGU6IEZ1bmN0aW9uO1xuICBwdXNoRW50ZXI6IEZ1bmN0aW9uO1xuICBwdXNoVXBkYXRlOiBGdW5jdGlvbjtcbiAgcHVzaERlbGV0ZTogRnVuY3Rpb247XG4gIHB1c2hMZWF2ZTogRnVuY3Rpb247XG5cbiAgY29uc3RydWN0b3IoXG4gICAgaWQ6IG51bWJlcixcbiAgICBwYXJzZVdlYlNvY2tldDogYW55LFxuICAgIGhhc01hc3RlcktleTogYm9vbGVhbiA9IGZhbHNlLFxuICAgIHNlc3Npb25Ub2tlbjogc3RyaW5nLFxuICAgIGluc3RhbGxhdGlvbklkOiBzdHJpbmdcbiAgKSB7XG4gICAgdGhpcy5pZCA9IGlkO1xuICAgIHRoaXMucGFyc2VXZWJTb2NrZXQgPSBwYXJzZVdlYlNvY2tldDtcbiAgICB0aGlzLmhhc01hc3RlcktleSA9IGhhc01hc3RlcktleTtcbiAgICB0aGlzLnNlc3Npb25Ub2tlbiA9IHNlc3Npb25Ub2tlbjtcbiAgICB0aGlzLmluc3RhbGxhdGlvbklkID0gaW5zdGFsbGF0aW9uSWQ7XG4gICAgdGhpcy5yb2xlcyA9IFtdO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uSW5mb3MgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5wdXNoQ29ubmVjdCA9IHRoaXMuX3B1c2hFdmVudCgnY29ubmVjdGVkJyk7XG4gICAgdGhpcy5wdXNoU3Vic2NyaWJlID0gdGhpcy5fcHVzaEV2ZW50KCdzdWJzY3JpYmVkJyk7XG4gICAgdGhpcy5wdXNoVW5zdWJzY3JpYmUgPSB0aGlzLl9wdXNoRXZlbnQoJ3Vuc3Vic2NyaWJlZCcpO1xuICAgIHRoaXMucHVzaENyZWF0ZSA9IHRoaXMuX3B1c2hFdmVudCgnY3JlYXRlJyk7XG4gICAgdGhpcy5wdXNoRW50ZXIgPSB0aGlzLl9wdXNoRXZlbnQoJ2VudGVyJyk7XG4gICAgdGhpcy5wdXNoVXBkYXRlID0gdGhpcy5fcHVzaEV2ZW50KCd1cGRhdGUnKTtcbiAgICB0aGlzLnB1c2hEZWxldGUgPSB0aGlzLl9wdXNoRXZlbnQoJ2RlbGV0ZScpO1xuICAgIHRoaXMucHVzaExlYXZlID0gdGhpcy5fcHVzaEV2ZW50KCdsZWF2ZScpO1xuICB9XG5cbiAgc3RhdGljIHB1c2hSZXNwb25zZShwYXJzZVdlYlNvY2tldDogYW55LCBtZXNzYWdlOiBNZXNzYWdlKTogdm9pZCB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoJ1B1c2ggUmVzcG9uc2UgOiAlaicsIG1lc3NhZ2UpO1xuICAgIHBhcnNlV2ViU29ja2V0LnNlbmQobWVzc2FnZSk7XG4gIH1cblxuICBzdGF0aWMgcHVzaEVycm9yKFxuICAgIHBhcnNlV2ViU29ja2V0OiBhbnksXG4gICAgY29kZTogbnVtYmVyLFxuICAgIGVycm9yOiBzdHJpbmcsXG4gICAgcmVjb25uZWN0OiBib29sZWFuID0gdHJ1ZSxcbiAgICByZXF1ZXN0SWQ6IG51bWJlciB8IHZvaWQgPSBudWxsXG4gICk6IHZvaWQge1xuICAgIENsaWVudC5wdXNoUmVzcG9uc2UoXG4gICAgICBwYXJzZVdlYlNvY2tldCxcbiAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgb3A6ICdlcnJvcicsXG4gICAgICAgIGVycm9yLFxuICAgICAgICBjb2RlLFxuICAgICAgICByZWNvbm5lY3QsXG4gICAgICAgIHJlcXVlc3RJZCxcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIGFkZFN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdElkOiBudW1iZXIsIHN1YnNjcmlwdGlvbkluZm86IGFueSk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uSW5mb3Muc2V0KHJlcXVlc3RJZCwgc3Vic2NyaXB0aW9uSW5mbyk7XG4gIH1cblxuICBnZXRTdWJzY3JpcHRpb25JbmZvKHJlcXVlc3RJZDogbnVtYmVyKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5zdWJzY3JpcHRpb25JbmZvcy5nZXQocmVxdWVzdElkKTtcbiAgfVxuXG4gIGRlbGV0ZVN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdElkOiBudW1iZXIpOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5zdWJzY3JpcHRpb25JbmZvcy5kZWxldGUocmVxdWVzdElkKTtcbiAgfVxuXG4gIF9wdXNoRXZlbnQodHlwZTogc3RyaW5nKTogRnVuY3Rpb24ge1xuICAgIHJldHVybiBmdW5jdGlvbiAoXG4gICAgICBzdWJzY3JpcHRpb25JZDogbnVtYmVyLFxuICAgICAgcGFyc2VPYmplY3RKU09OOiBhbnksXG4gICAgICBwYXJzZU9yaWdpbmFsT2JqZWN0SlNPTjogYW55XG4gICAgKTogdm9pZCB7XG4gICAgICBjb25zdCByZXNwb25zZTogTWVzc2FnZSA9IHtcbiAgICAgICAgb3A6IHR5cGUsXG4gICAgICAgIGNsaWVudElkOiB0aGlzLmlkLFxuICAgICAgICBpbnN0YWxsYXRpb25JZDogdGhpcy5pbnN0YWxsYXRpb25JZCxcbiAgICAgIH07XG4gICAgICBpZiAodHlwZW9mIHN1YnNjcmlwdGlvbklkICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXNwb25zZVsncmVxdWVzdElkJ10gPSBzdWJzY3JpcHRpb25JZDtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgcGFyc2VPYmplY3RKU09OICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBsZXQgZmllbGRzO1xuICAgICAgICBpZiAodGhpcy5zdWJzY3JpcHRpb25JbmZvcy5oYXMoc3Vic2NyaXB0aW9uSWQpKSB7XG4gICAgICAgICAgZmllbGRzID0gdGhpcy5zdWJzY3JpcHRpb25JbmZvcy5nZXQoc3Vic2NyaXB0aW9uSWQpLmZpZWxkcztcbiAgICAgICAgfVxuICAgICAgICByZXNwb25zZVsnb2JqZWN0J10gPSB0aGlzLl90b0pTT05XaXRoRmllbGRzKHBhcnNlT2JqZWN0SlNPTiwgZmllbGRzKTtcbiAgICAgICAgaWYgKHBhcnNlT3JpZ2luYWxPYmplY3RKU09OKSB7XG4gICAgICAgICAgcmVzcG9uc2VbJ29yaWdpbmFsJ10gPSB0aGlzLl90b0pTT05XaXRoRmllbGRzKHBhcnNlT3JpZ2luYWxPYmplY3RKU09OLCBmaWVsZHMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBDbGllbnQucHVzaFJlc3BvbnNlKHRoaXMucGFyc2VXZWJTb2NrZXQsIEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlKSk7XG4gICAgfTtcbiAgfVxuXG4gIF90b0pTT05XaXRoRmllbGRzKHBhcnNlT2JqZWN0SlNPTjogYW55LCBmaWVsZHM6IGFueSk6IEZsYXR0ZW5lZE9iamVjdERhdGEge1xuICAgIGlmICghZmllbGRzKSB7XG4gICAgICByZXR1cm4gcGFyc2VPYmplY3RKU09OO1xuICAgIH1cbiAgICBjb25zdCBsaW1pdGVkUGFyc2VPYmplY3QgPSB7fTtcbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIGRhZmF1bHRGaWVsZHMpIHtcbiAgICAgIGxpbWl0ZWRQYXJzZU9iamVjdFtmaWVsZF0gPSBwYXJzZU9iamVjdEpTT05bZmllbGRdO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIGZpZWxkcykge1xuICAgICAgaWYgKGZpZWxkIGluIHBhcnNlT2JqZWN0SlNPTikge1xuICAgICAgICBsaW1pdGVkUGFyc2VPYmplY3RbZmllbGRdID0gcGFyc2VPYmplY3RKU09OW2ZpZWxkXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGxpbWl0ZWRQYXJzZU9iamVjdDtcbiAgfVxufVxuXG5leHBvcnQgeyBDbGllbnQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/Id.js b/lib/LiveQuery/Id.js new file mode 100644 index 0000000000..379e29b88d --- /dev/null +++ b/lib/LiveQuery/Id.js @@ -0,0 +1,26 @@ +"use strict"; + +class Id { + constructor(className, objectId) { + this.className = className; + this.objectId = objectId; + } + + toString() { + return this.className + ':' + this.objectId; + } + + static fromString(str) { + var split = str.split(':'); + + if (split.length !== 2) { + throw new TypeError('Cannot create Id object from this string'); + } + + return new Id(split[0], split[1]); + } + +} + +module.exports = Id; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvSWQuanMiXSwibmFtZXMiOlsiSWQiLCJjb25zdHJ1Y3RvciIsImNsYXNzTmFtZSIsIm9iamVjdElkIiwidG9TdHJpbmciLCJmcm9tU3RyaW5nIiwic3RyIiwic3BsaXQiLCJsZW5ndGgiLCJUeXBlRXJyb3IiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLE1BQU1BLEVBQU4sQ0FBUztBQUlQQyxFQUFBQSxXQUFXLENBQUNDLFNBQUQsRUFBb0JDLFFBQXBCLEVBQXNDO0FBQy9DLFNBQUtELFNBQUwsR0FBaUJBLFNBQWpCO0FBQ0EsU0FBS0MsUUFBTCxHQUFnQkEsUUFBaEI7QUFDRDs7QUFDREMsRUFBQUEsUUFBUSxHQUFXO0FBQ2pCLFdBQU8sS0FBS0YsU0FBTCxHQUFpQixHQUFqQixHQUF1QixLQUFLQyxRQUFuQztBQUNEOztBQUVELFNBQU9FLFVBQVAsQ0FBa0JDLEdBQWxCLEVBQStCO0FBQzdCLFFBQUlDLEtBQUssR0FBR0QsR0FBRyxDQUFDQyxLQUFKLENBQVUsR0FBVixDQUFaOztBQUNBLFFBQUlBLEtBQUssQ0FBQ0MsTUFBTixLQUFpQixDQUFyQixFQUF3QjtBQUN0QixZQUFNLElBQUlDLFNBQUosQ0FBYywwQ0FBZCxDQUFOO0FBQ0Q7O0FBQ0QsV0FBTyxJQUFJVCxFQUFKLENBQU9PLEtBQUssQ0FBQyxDQUFELENBQVosRUFBaUJBLEtBQUssQ0FBQyxDQUFELENBQXRCLENBQVA7QUFDRDs7QUFsQk07O0FBcUJURyxNQUFNLENBQUNDLE9BQVAsR0FBaUJYLEVBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiY2xhc3MgSWQge1xuICBjbGFzc05hbWU6IHN0cmluZztcbiAgb2JqZWN0SWQ6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihjbGFzc05hbWU6IHN0cmluZywgb2JqZWN0SWQ6IHN0cmluZykge1xuICAgIHRoaXMuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xuICAgIHRoaXMub2JqZWN0SWQgPSBvYmplY3RJZDtcbiAgfVxuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmNsYXNzTmFtZSArICc6JyArIHRoaXMub2JqZWN0SWQ7XG4gIH1cblxuICBzdGF0aWMgZnJvbVN0cmluZyhzdHI6IHN0cmluZykge1xuICAgIHZhciBzcGxpdCA9IHN0ci5zcGxpdCgnOicpO1xuICAgIGlmIChzcGxpdC5sZW5ndGggIT09IDIpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjcmVhdGUgSWQgb2JqZWN0IGZyb20gdGhpcyBzdHJpbmcnKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBJZChzcGxpdFswXSwgc3BsaXRbMV0pO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gSWQ7XG4iXX0= \ No newline at end of file diff --git a/lib/LiveQuery/ParseCloudCodePublisher.js b/lib/LiveQuery/ParseCloudCodePublisher.js new file mode 100644 index 0000000000..974770a79f --- /dev/null +++ b/lib/LiveQuery/ParseCloudCodePublisher.js @@ -0,0 +1,50 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ParseCloudCodePublisher = void 0; + +var _ParsePubSub = require("./ParsePubSub"); + +var _node = _interopRequireDefault(require("parse/node")); + +var _logger = _interopRequireDefault(require("../logger")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class ParseCloudCodePublisher { + // config object of the publisher, right now it only contains the redisURL, + // but we may extend it later. + constructor(config = {}) { + this.parsePublisher = _ParsePubSub.ParsePubSub.createPublisher(config); + } + + onCloudCodeAfterSave(request) { + this._onCloudCodeMessage(_node.default.applicationId + 'afterSave', request); + } + + onCloudCodeAfterDelete(request) { + this._onCloudCodeMessage(_node.default.applicationId + 'afterDelete', request); + } // Request is the request object from cloud code functions. request.object is a ParseObject. + + + _onCloudCodeMessage(type, request) { + _logger.default.verbose('Raw request from cloud code current : %j | original : %j', request.object, request.original); // We need the full JSON which includes className + + + const message = { + currentParseObject: request.object._toFullJSON() + }; + + if (request.original) { + message.originalParseObject = request.original._toFullJSON(); + } + + this.parsePublisher.publish(type, JSON.stringify(message)); + } + +} + +exports.ParseCloudCodePublisher = ParseCloudCodePublisher; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUGFyc2VDbG91ZENvZGVQdWJsaXNoZXIuanMiXSwibmFtZXMiOlsiUGFyc2VDbG91ZENvZGVQdWJsaXNoZXIiLCJjb25zdHJ1Y3RvciIsImNvbmZpZyIsInBhcnNlUHVibGlzaGVyIiwiUGFyc2VQdWJTdWIiLCJjcmVhdGVQdWJsaXNoZXIiLCJvbkNsb3VkQ29kZUFmdGVyU2F2ZSIsInJlcXVlc3QiLCJfb25DbG91ZENvZGVNZXNzYWdlIiwiUGFyc2UiLCJhcHBsaWNhdGlvbklkIiwib25DbG91ZENvZGVBZnRlckRlbGV0ZSIsInR5cGUiLCJsb2dnZXIiLCJ2ZXJib3NlIiwib2JqZWN0Iiwib3JpZ2luYWwiLCJtZXNzYWdlIiwiY3VycmVudFBhcnNlT2JqZWN0IiwiX3RvRnVsbEpTT04iLCJvcmlnaW5hbFBhcnNlT2JqZWN0IiwicHVibGlzaCIsIkpTT04iLCJzdHJpbmdpZnkiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7OztBQUVBLE1BQU1BLHVCQUFOLENBQThCO0FBRzVCO0FBQ0E7QUFDQUMsRUFBQUEsV0FBVyxDQUFDQyxNQUFXLEdBQUcsRUFBZixFQUFtQjtBQUM1QixTQUFLQyxjQUFMLEdBQXNCQyx5QkFBWUMsZUFBWixDQUE0QkgsTUFBNUIsQ0FBdEI7QUFDRDs7QUFFREksRUFBQUEsb0JBQW9CLENBQUNDLE9BQUQsRUFBcUI7QUFDdkMsU0FBS0MsbUJBQUwsQ0FBeUJDLGNBQU1DLGFBQU4sR0FBc0IsV0FBL0MsRUFBNERILE9BQTVEO0FBQ0Q7O0FBRURJLEVBQUFBLHNCQUFzQixDQUFDSixPQUFELEVBQXFCO0FBQ3pDLFNBQUtDLG1CQUFMLENBQXlCQyxjQUFNQyxhQUFOLEdBQXNCLGFBQS9DLEVBQThESCxPQUE5RDtBQUNELEdBZjJCLENBaUI1Qjs7O0FBQ0FDLEVBQUFBLG1CQUFtQixDQUFDSSxJQUFELEVBQWVMLE9BQWYsRUFBbUM7QUFDcERNLG9CQUFPQyxPQUFQLENBQ0UsMERBREYsRUFFRVAsT0FBTyxDQUFDUSxNQUZWLEVBR0VSLE9BQU8sQ0FBQ1MsUUFIVixFQURvRCxDQU1wRDs7O0FBQ0EsVUFBTUMsT0FBTyxHQUFHO0FBQ2RDLE1BQUFBLGtCQUFrQixFQUFFWCxPQUFPLENBQUNRLE1BQVIsQ0FBZUksV0FBZjtBQUROLEtBQWhCOztBQUdBLFFBQUlaLE9BQU8sQ0FBQ1MsUUFBWixFQUFzQjtBQUNwQkMsTUFBQUEsT0FBTyxDQUFDRyxtQkFBUixHQUE4QmIsT0FBTyxDQUFDUyxRQUFSLENBQWlCRyxXQUFqQixFQUE5QjtBQUNEOztBQUNELFNBQUtoQixjQUFMLENBQW9Ca0IsT0FBcEIsQ0FBNEJULElBQTVCLEVBQWtDVSxJQUFJLENBQUNDLFNBQUwsQ0FBZU4sT0FBZixDQUFsQztBQUNEOztBQWhDMkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBQYXJzZVB1YlN1YiB9IGZyb20gJy4vUGFyc2VQdWJTdWInO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IGxvZ2dlciBmcm9tICcuLi9sb2dnZXInO1xuXG5jbGFzcyBQYXJzZUNsb3VkQ29kZVB1Ymxpc2hlciB7XG4gIHBhcnNlUHVibGlzaGVyOiBPYmplY3Q7XG5cbiAgLy8gY29uZmlnIG9iamVjdCBvZiB0aGUgcHVibGlzaGVyLCByaWdodCBub3cgaXQgb25seSBjb250YWlucyB0aGUgcmVkaXNVUkwsXG4gIC8vIGJ1dCB3ZSBtYXkgZXh0ZW5kIGl0IGxhdGVyLlxuICBjb25zdHJ1Y3Rvcihjb25maWc6IGFueSA9IHt9KSB7XG4gICAgdGhpcy5wYXJzZVB1Ymxpc2hlciA9IFBhcnNlUHViU3ViLmNyZWF0ZVB1Ymxpc2hlcihjb25maWcpO1xuICB9XG5cbiAgb25DbG91ZENvZGVBZnRlclNhdmUocmVxdWVzdDogYW55KTogdm9pZCB7XG4gICAgdGhpcy5fb25DbG91ZENvZGVNZXNzYWdlKFBhcnNlLmFwcGxpY2F0aW9uSWQgKyAnYWZ0ZXJTYXZlJywgcmVxdWVzdCk7XG4gIH1cblxuICBvbkNsb3VkQ29kZUFmdGVyRGVsZXRlKHJlcXVlc3Q6IGFueSk6IHZvaWQge1xuICAgIHRoaXMuX29uQ2xvdWRDb2RlTWVzc2FnZShQYXJzZS5hcHBsaWNhdGlvbklkICsgJ2FmdGVyRGVsZXRlJywgcmVxdWVzdCk7XG4gIH1cblxuICAvLyBSZXF1ZXN0IGlzIHRoZSByZXF1ZXN0IG9iamVjdCBmcm9tIGNsb3VkIGNvZGUgZnVuY3Rpb25zLiByZXF1ZXN0Lm9iamVjdCBpcyBhIFBhcnNlT2JqZWN0LlxuICBfb25DbG91ZENvZGVNZXNzYWdlKHR5cGU6IHN0cmluZywgcmVxdWVzdDogYW55KTogdm9pZCB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoXG4gICAgICAnUmF3IHJlcXVlc3QgZnJvbSBjbG91ZCBjb2RlIGN1cnJlbnQgOiAlaiB8IG9yaWdpbmFsIDogJWonLFxuICAgICAgcmVxdWVzdC5vYmplY3QsXG4gICAgICByZXF1ZXN0Lm9yaWdpbmFsXG4gICAgKTtcbiAgICAvLyBXZSBuZWVkIHRoZSBmdWxsIEpTT04gd2hpY2ggaW5jbHVkZXMgY2xhc3NOYW1lXG4gICAgY29uc3QgbWVzc2FnZSA9IHtcbiAgICAgIGN1cnJlbnRQYXJzZU9iamVjdDogcmVxdWVzdC5vYmplY3QuX3RvRnVsbEpTT04oKSxcbiAgICB9O1xuICAgIGlmIChyZXF1ZXN0Lm9yaWdpbmFsKSB7XG4gICAgICBtZXNzYWdlLm9yaWdpbmFsUGFyc2VPYmplY3QgPSByZXF1ZXN0Lm9yaWdpbmFsLl90b0Z1bGxKU09OKCk7XG4gICAgfVxuICAgIHRoaXMucGFyc2VQdWJsaXNoZXIucHVibGlzaCh0eXBlLCBKU09OLnN0cmluZ2lmeShtZXNzYWdlKSk7XG4gIH1cbn1cblxuZXhwb3J0IHsgUGFyc2VDbG91ZENvZGVQdWJsaXNoZXIgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/ParseLiveQueryServer.js b/lib/LiveQuery/ParseLiveQueryServer.js new file mode 100644 index 0000000000..a286c9daf7 --- /dev/null +++ b/lib/LiveQuery/ParseLiveQueryServer.js @@ -0,0 +1,848 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ParseLiveQueryServer = void 0; + +var _tv = _interopRequireDefault(require("tv4")); + +var _node = _interopRequireDefault(require("parse/node")); + +var _Subscription = require("./Subscription"); + +var _Client = require("./Client"); + +var _ParseWebSocketServer = require("./ParseWebSocketServer"); + +var _logger = _interopRequireDefault(require("../logger")); + +var _RequestSchema = _interopRequireDefault(require("./RequestSchema")); + +var _QueryTools = require("./QueryTools"); + +var _ParsePubSub = require("./ParsePubSub"); + +var _SchemaController = _interopRequireDefault(require("../Controllers/SchemaController")); + +var _lodash = _interopRequireDefault(require("lodash")); + +var _uuid = require("uuid"); + +var _triggers = require("../triggers"); + +var _Auth = require("../Auth"); + +var _Controllers = require("../Controllers"); + +var _lruCache = _interopRequireDefault(require("lru-cache")); + +var _UsersRouter = _interopRequireDefault(require("../Routers/UsersRouter")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class ParseLiveQueryServer { + // className -> (queryHash -> subscription) + // The subscriber we use to get object update from publisher + constructor(server, config = {}, parseServerConfig = {}) { + this.server = server; + this.clients = new Map(); + this.subscriptions = new Map(); + this.config = config; + config.appId = config.appId || _node.default.applicationId; + config.masterKey = config.masterKey || _node.default.masterKey; // Store keys, convert obj to map + + const keyPairs = config.keyPairs || {}; + this.keyPairs = new Map(); + + for (const key of Object.keys(keyPairs)) { + this.keyPairs.set(key, keyPairs[key]); + } + + _logger.default.verbose('Support key pairs', this.keyPairs); // Initialize Parse + + + _node.default.Object.disableSingleInstance(); + + const serverURL = config.serverURL || _node.default.serverURL; + _node.default.serverURL = serverURL; + + _node.default.initialize(config.appId, _node.default.javaScriptKey, config.masterKey); // The cache controller is a proper cache controller + // with access to User and Roles + + + this.cacheController = (0, _Controllers.getCacheController)(parseServerConfig); + config.cacheTimeout = config.cacheTimeout || 5 * 1000; // 5s + // This auth cache stores the promises for each auth resolution. + // The main benefit is to be able to reuse the same user / session token resolution. + + this.authCache = new _lruCache.default({ + max: 500, + // 500 concurrent + maxAge: config.cacheTimeout + }); // Initialize websocket server + + this.parseWebSocketServer = new _ParseWebSocketServer.ParseWebSocketServer(server, parseWebsocket => this._onConnect(parseWebsocket), config); // Initialize subscriber + + this.subscriber = _ParsePubSub.ParsePubSub.createSubscriber(config); + this.subscriber.subscribe(_node.default.applicationId + 'afterSave'); + this.subscriber.subscribe(_node.default.applicationId + 'afterDelete'); // Register message handler for subscriber. When publisher get messages, it will publish message + // to the subscribers and the handler will be called. + + this.subscriber.on('message', (channel, messageStr) => { + _logger.default.verbose('Subscribe message %j', messageStr); + + let message; + + try { + message = JSON.parse(messageStr); + } catch (e) { + _logger.default.error('unable to parse message', messageStr, e); + + return; + } + + this._inflateParseObject(message); + + if (channel === _node.default.applicationId + 'afterSave') { + this._onAfterSave(message); + } else if (channel === _node.default.applicationId + 'afterDelete') { + this._onAfterDelete(message); + } else { + _logger.default.error('Get message %s from unknown channel %j', message, channel); + } + }); + } // Message is the JSON object from publisher. Message.currentParseObject is the ParseObject JSON after changes. + // Message.originalParseObject is the original ParseObject JSON. + + + _inflateParseObject(message) { + // Inflate merged object + const currentParseObject = message.currentParseObject; + + _UsersRouter.default.removeHiddenProperties(currentParseObject); + + let className = currentParseObject.className; + let parseObject = new _node.default.Object(className); + + parseObject._finishFetch(currentParseObject); + + message.currentParseObject = parseObject; // Inflate original object + + const originalParseObject = message.originalParseObject; + + if (originalParseObject) { + _UsersRouter.default.removeHiddenProperties(originalParseObject); + + className = originalParseObject.className; + parseObject = new _node.default.Object(className); + + parseObject._finishFetch(originalParseObject); + + message.originalParseObject = parseObject; + } + } // Message is the JSON object from publisher after inflated. Message.currentParseObject is the ParseObject after changes. + // Message.originalParseObject is the original ParseObject. + + + _onAfterDelete(message) { + _logger.default.verbose(_node.default.applicationId + 'afterDelete is triggered'); + + let deletedParseObject = message.currentParseObject.toJSON(); + const classLevelPermissions = message.classLevelPermissions; + const className = deletedParseObject.className; + + _logger.default.verbose('ClassName: %j | ObjectId: %s', className, deletedParseObject.id); + + _logger.default.verbose('Current client number : %d', this.clients.size); + + const classSubscriptions = this.subscriptions.get(className); + + if (typeof classSubscriptions === 'undefined') { + _logger.default.debug('Can not find subscriptions under this class ' + className); + + return; + } + + for (const subscription of classSubscriptions.values()) { + const isSubscriptionMatched = this._matchesSubscription(deletedParseObject, subscription); + + if (!isSubscriptionMatched) { + continue; + } + + for (const [clientId, requestIds] of _lodash.default.entries(subscription.clientRequestIds)) { + const client = this.clients.get(clientId); + + if (typeof client === 'undefined') { + continue; + } + + for (const requestId of requestIds) { + const acl = message.currentParseObject.getACL(); // Check CLP + + const op = this._getCLPOperation(subscription.query); + + let res = {}; + + this._matchesCLP(classLevelPermissions, message.currentParseObject, client, requestId, op).then(() => { + // Check ACL + return this._matchesACL(acl, client, requestId); + }).then(isMatched => { + if (!isMatched) { + return null; + } + + res = { + event: 'delete', + sessionToken: client.sessionToken, + object: deletedParseObject, + clients: this.clients.size, + subscriptions: this.subscriptions.size, + useMasterKey: client.hasMasterKey, + installationId: client.installationId, + sendEvent: true + }; + return (0, _triggers.maybeRunAfterEventTrigger)('afterEvent', className, res); + }).then(() => { + if (!res.sendEvent) { + return; + } + + if (res.object && typeof res.object.toJSON === 'function') { + deletedParseObject = res.object.toJSON(); + deletedParseObject.className = className; + } + + client.pushDelete(requestId, deletedParseObject); + }).catch(error => { + _Client.Client.pushError(client.parseWebSocket, error.code || 141, error.message || error, false, requestId); + + _logger.default.error(`Failed running afterLiveQueryEvent on class ${className} for event ${res.event} with session ${res.sessionToken} with:\n Error: ` + JSON.stringify(error)); + }); + } + } + } + } // Message is the JSON object from publisher after inflated. Message.currentParseObject is the ParseObject after changes. + // Message.originalParseObject is the original ParseObject. + + + _onAfterSave(message) { + _logger.default.verbose(_node.default.applicationId + 'afterSave is triggered'); + + let originalParseObject = null; + + if (message.originalParseObject) { + originalParseObject = message.originalParseObject.toJSON(); + } + + const classLevelPermissions = message.classLevelPermissions; + let currentParseObject = message.currentParseObject.toJSON(); + const className = currentParseObject.className; + + _logger.default.verbose('ClassName: %s | ObjectId: %s', className, currentParseObject.id); + + _logger.default.verbose('Current client number : %d', this.clients.size); + + const classSubscriptions = this.subscriptions.get(className); + + if (typeof classSubscriptions === 'undefined') { + _logger.default.debug('Can not find subscriptions under this class ' + className); + + return; + } + + for (const subscription of classSubscriptions.values()) { + const isOriginalSubscriptionMatched = this._matchesSubscription(originalParseObject, subscription); + + const isCurrentSubscriptionMatched = this._matchesSubscription(currentParseObject, subscription); + + for (const [clientId, requestIds] of _lodash.default.entries(subscription.clientRequestIds)) { + const client = this.clients.get(clientId); + + if (typeof client === 'undefined') { + continue; + } + + for (const requestId of requestIds) { + // Set orignal ParseObject ACL checking promise, if the object does not match + // subscription, we do not need to check ACL + let originalACLCheckingPromise; + + if (!isOriginalSubscriptionMatched) { + originalACLCheckingPromise = Promise.resolve(false); + } else { + let originalACL; + + if (message.originalParseObject) { + originalACL = message.originalParseObject.getACL(); + } + + originalACLCheckingPromise = this._matchesACL(originalACL, client, requestId); + } // Set current ParseObject ACL checking promise, if the object does not match + // subscription, we do not need to check ACL + + + let currentACLCheckingPromise; + let res = {}; + + if (!isCurrentSubscriptionMatched) { + currentACLCheckingPromise = Promise.resolve(false); + } else { + const currentACL = message.currentParseObject.getACL(); + currentACLCheckingPromise = this._matchesACL(currentACL, client, requestId); + } + + const op = this._getCLPOperation(subscription.query); + + this._matchesCLP(classLevelPermissions, message.currentParseObject, client, requestId, op).then(() => { + return Promise.all([originalACLCheckingPromise, currentACLCheckingPromise]); + }).then(([isOriginalMatched, isCurrentMatched]) => { + _logger.default.verbose('Original %j | Current %j | Match: %s, %s, %s, %s | Query: %s', originalParseObject, currentParseObject, isOriginalSubscriptionMatched, isCurrentSubscriptionMatched, isOriginalMatched, isCurrentMatched, subscription.hash); // Decide event type + + + let type; + + if (isOriginalMatched && isCurrentMatched) { + type = 'update'; + } else if (isOriginalMatched && !isCurrentMatched) { + type = 'leave'; + } else if (!isOriginalMatched && isCurrentMatched) { + if (originalParseObject) { + type = 'enter'; + } else { + type = 'create'; + } + } else { + return null; + } + + message.event = type; + res = { + event: type, + sessionToken: client.sessionToken, + object: currentParseObject, + original: originalParseObject, + clients: this.clients.size, + subscriptions: this.subscriptions.size, + useMasterKey: client.hasMasterKey, + installationId: client.installationId, + sendEvent: true + }; + return (0, _triggers.maybeRunAfterEventTrigger)('afterEvent', className, res); + }).then(() => { + if (!res.sendEvent) { + return; + } + + if (res.object && typeof res.object.toJSON === 'function') { + currentParseObject = res.object.toJSON(); + currentParseObject.className = res.object.className || className; + } + + if (res.original && typeof res.original.toJSON === 'function') { + originalParseObject = res.original.toJSON(); + originalParseObject.className = res.original.className || className; + } + + const functionName = 'push' + message.event.charAt(0).toUpperCase() + message.event.slice(1); + + if (client[functionName]) { + client[functionName](requestId, currentParseObject, originalParseObject); + } + }, error => { + _Client.Client.pushError(client.parseWebSocket, error.code || 141, error.message || error, false, requestId); + + _logger.default.error(`Failed running afterLiveQueryEvent on class ${className} for event ${res.event} with session ${res.sessionToken} with:\n Error: ` + JSON.stringify(error)); + }); + } + } + } + } + + _onConnect(parseWebsocket) { + parseWebsocket.on('message', request => { + if (typeof request === 'string') { + try { + request = JSON.parse(request); + } catch (e) { + _logger.default.error('unable to parse request', request, e); + + return; + } + } + + _logger.default.verbose('Request: %j', request); // Check whether this request is a valid request, return error directly if not + + + if (!_tv.default.validate(request, _RequestSchema.default['general']) || !_tv.default.validate(request, _RequestSchema.default[request.op])) { + _Client.Client.pushError(parseWebsocket, 1, _tv.default.error.message); + + _logger.default.error('Connect message error %s', _tv.default.error.message); + + return; + } + + switch (request.op) { + case 'connect': + this._handleConnect(parseWebsocket, request); + + break; + + case 'subscribe': + this._handleSubscribe(parseWebsocket, request); + + break; + + case 'update': + this._handleUpdateSubscription(parseWebsocket, request); + + break; + + case 'unsubscribe': + this._handleUnsubscribe(parseWebsocket, request); + + break; + + default: + _Client.Client.pushError(parseWebsocket, 3, 'Get unknown operation'); + + _logger.default.error('Get unknown operation', request.op); + + } + }); + parseWebsocket.on('disconnect', () => { + _logger.default.info(`Client disconnect: ${parseWebsocket.clientId}`); + + const clientId = parseWebsocket.clientId; + + if (!this.clients.has(clientId)) { + (0, _triggers.runLiveQueryEventHandlers)({ + event: 'ws_disconnect_error', + clients: this.clients.size, + subscriptions: this.subscriptions.size, + error: `Unable to find client ${clientId}` + }); + + _logger.default.error(`Can not find client ${clientId} on disconnect`); + + return; + } // Delete client + + + const client = this.clients.get(clientId); + this.clients.delete(clientId); // Delete client from subscriptions + + for (const [requestId, subscriptionInfo] of _lodash.default.entries(client.subscriptionInfos)) { + const subscription = subscriptionInfo.subscription; + subscription.deleteClientSubscription(clientId, requestId); // If there is no client which is subscribing this subscription, remove it from subscriptions + + const classSubscriptions = this.subscriptions.get(subscription.className); + + if (!subscription.hasSubscribingClient()) { + classSubscriptions.delete(subscription.hash); + } // If there is no subscriptions under this class, remove it from subscriptions + + + if (classSubscriptions.size === 0) { + this.subscriptions.delete(subscription.className); + } + } + + _logger.default.verbose('Current clients %d', this.clients.size); + + _logger.default.verbose('Current subscriptions %d', this.subscriptions.size); + + (0, _triggers.runLiveQueryEventHandlers)({ + event: 'ws_disconnect', + clients: this.clients.size, + subscriptions: this.subscriptions.size, + useMasterKey: client.hasMasterKey, + installationId: client.installationId, + sessionToken: client.sessionToken + }); + }); + (0, _triggers.runLiveQueryEventHandlers)({ + event: 'ws_connect', + clients: this.clients.size, + subscriptions: this.subscriptions.size + }); + } + + _matchesSubscription(parseObject, subscription) { + // Object is undefined or null, not match + if (!parseObject) { + return false; + } + + return (0, _QueryTools.matchesQuery)(parseObject, subscription.query); + } + + getAuthForSessionToken(sessionToken) { + if (!sessionToken) { + return Promise.resolve({}); + } + + const fromCache = this.authCache.get(sessionToken); + + if (fromCache) { + return fromCache; + } + + const authPromise = (0, _Auth.getAuthForSessionToken)({ + cacheController: this.cacheController, + sessionToken: sessionToken + }).then(auth => { + return { + auth, + userId: auth && auth.user && auth.user.id + }; + }).catch(error => { + // There was an error with the session token + const result = {}; + + if (error && error.code === _node.default.Error.INVALID_SESSION_TOKEN) { + result.error = error; + this.authCache.set(sessionToken, Promise.resolve(result), this.config.cacheTimeout); + } else { + this.authCache.del(sessionToken); + } + + return result; + }); + this.authCache.set(sessionToken, authPromise); + return authPromise; + } + + async _matchesCLP(classLevelPermissions, object, client, requestId, op) { + // try to match on user first, less expensive than with roles + const subscriptionInfo = client.getSubscriptionInfo(requestId); + const aclGroup = ['*']; + let userId; + + if (typeof subscriptionInfo !== 'undefined') { + const { + userId + } = await this.getAuthForSessionToken(subscriptionInfo.sessionToken); + + if (userId) { + aclGroup.push(userId); + } + } + + try { + await _SchemaController.default.validatePermission(classLevelPermissions, object.className, aclGroup, op); + return true; + } catch (e) { + _logger.default.verbose(`Failed matching CLP for ${object.id} ${userId} ${e}`); + + return false; + } // TODO: handle roles permissions + // Object.keys(classLevelPermissions).forEach((key) => { + // const perm = classLevelPermissions[key]; + // Object.keys(perm).forEach((key) => { + // if (key.indexOf('role')) + // }); + // }) + // // it's rejected here, check the roles + // var rolesQuery = new Parse.Query(Parse.Role); + // rolesQuery.equalTo("users", user); + // return rolesQuery.find({useMasterKey:true}); + + } + + _getCLPOperation(query) { + return typeof query === 'object' && Object.keys(query).length == 1 && typeof query.objectId === 'string' ? 'get' : 'find'; + } + + async _verifyACL(acl, token) { + if (!token) { + return false; + } + + const { + auth, + userId + } = await this.getAuthForSessionToken(token); // Getting the session token failed + // This means that no additional auth is available + // At this point, just bail out as no additional visibility can be inferred. + + if (!auth || !userId) { + return false; + } + + const isSubscriptionSessionTokenMatched = acl.getReadAccess(userId); + + if (isSubscriptionSessionTokenMatched) { + return true; + } // Check if the user has any roles that match the ACL + + + return Promise.resolve().then(async () => { + // Resolve false right away if the acl doesn't have any roles + const acl_has_roles = Object.keys(acl.permissionsById).some(key => key.startsWith('role:')); + + if (!acl_has_roles) { + return false; + } + + const roleNames = await auth.getUserRoles(); // Finally, see if any of the user's roles allow them read access + + for (const role of roleNames) { + // We use getReadAccess as `role` is in the form `role:roleName` + if (acl.getReadAccess(role)) { + return true; + } + } + + return false; + }).catch(() => { + return false; + }); + } + + async _matchesACL(acl, client, requestId) { + // Return true directly if ACL isn't present, ACL is public read, or client has master key + if (!acl || acl.getPublicReadAccess() || client.hasMasterKey) { + return true; + } // Check subscription sessionToken matches ACL first + + + const subscriptionInfo = client.getSubscriptionInfo(requestId); + + if (typeof subscriptionInfo === 'undefined') { + return false; + } + + const subscriptionToken = subscriptionInfo.sessionToken; + const clientSessionToken = client.sessionToken; + + if (await this._verifyACL(acl, subscriptionToken)) { + return true; + } + + if (await this._verifyACL(acl, clientSessionToken)) { + return true; + } + + return false; + } + + async _handleConnect(parseWebsocket, request) { + if (!this._validateKeys(request, this.keyPairs)) { + _Client.Client.pushError(parseWebsocket, 4, 'Key in request is not valid'); + + _logger.default.error('Key in request is not valid'); + + return; + } + + const hasMasterKey = this._hasMasterKey(request, this.keyPairs); + + const clientId = (0, _uuid.v4)(); + const client = new _Client.Client(clientId, parseWebsocket, hasMasterKey, request.sessionToken, request.installationId); + + try { + const req = { + client, + event: 'connect', + clients: this.clients.size, + subscriptions: this.subscriptions.size, + sessionToken: request.sessionToken, + useMasterKey: client.hasMasterKey, + installationId: request.installationId + }; + await (0, _triggers.maybeRunConnectTrigger)('beforeConnect', req); + parseWebsocket.clientId = clientId; + this.clients.set(parseWebsocket.clientId, client); + + _logger.default.info(`Create new client: ${parseWebsocket.clientId}`); + + client.pushConnect(); + (0, _triggers.runLiveQueryEventHandlers)(req); + } catch (error) { + _Client.Client.pushError(parseWebsocket, error.code || 141, error.message || error, false); + + _logger.default.error(`Failed running beforeConnect for session ${request.sessionToken} with:\n Error: ` + JSON.stringify(error)); + } + } + + _hasMasterKey(request, validKeyPairs) { + if (!validKeyPairs || validKeyPairs.size == 0 || !validKeyPairs.has('masterKey')) { + return false; + } + + if (!request || !Object.prototype.hasOwnProperty.call(request, 'masterKey')) { + return false; + } + + return request.masterKey === validKeyPairs.get('masterKey'); + } + + _validateKeys(request, validKeyPairs) { + if (!validKeyPairs || validKeyPairs.size == 0) { + return true; + } + + let isValid = false; + + for (const [key, secret] of validKeyPairs) { + if (!request[key] || request[key] !== secret) { + continue; + } + + isValid = true; + break; + } + + return isValid; + } + + async _handleSubscribe(parseWebsocket, request) { + // If we can not find this client, return error to client + if (!Object.prototype.hasOwnProperty.call(parseWebsocket, 'clientId')) { + _Client.Client.pushError(parseWebsocket, 2, 'Can not find this client, make sure you connect to server before subscribing'); + + _logger.default.error('Can not find this client, make sure you connect to server before subscribing'); + + return; + } + + const client = this.clients.get(parseWebsocket.clientId); + const className = request.query.className; + + try { + await (0, _triggers.maybeRunSubscribeTrigger)('beforeSubscribe', className, request); // Get subscription from subscriptions, create one if necessary + + const subscriptionHash = (0, _QueryTools.queryHash)(request.query); // Add className to subscriptions if necessary + + if (!this.subscriptions.has(className)) { + this.subscriptions.set(className, new Map()); + } + + const classSubscriptions = this.subscriptions.get(className); + let subscription; + + if (classSubscriptions.has(subscriptionHash)) { + subscription = classSubscriptions.get(subscriptionHash); + } else { + subscription = new _Subscription.Subscription(className, request.query.where, subscriptionHash); + classSubscriptions.set(subscriptionHash, subscription); + } // Add subscriptionInfo to client + + + const subscriptionInfo = { + subscription: subscription + }; // Add selected fields, sessionToken and installationId for this subscription if necessary + + if (request.query.fields) { + subscriptionInfo.fields = request.query.fields; + } + + if (request.sessionToken) { + subscriptionInfo.sessionToken = request.sessionToken; + } + + client.addSubscriptionInfo(request.requestId, subscriptionInfo); // Add clientId to subscription + + subscription.addClientSubscription(parseWebsocket.clientId, request.requestId); + client.pushSubscribe(request.requestId); + + _logger.default.verbose(`Create client ${parseWebsocket.clientId} new subscription: ${request.requestId}`); + + _logger.default.verbose('Current client number: %d', this.clients.size); + + (0, _triggers.runLiveQueryEventHandlers)({ + client, + event: 'subscribe', + clients: this.clients.size, + subscriptions: this.subscriptions.size, + sessionToken: request.sessionToken, + useMasterKey: client.hasMasterKey, + installationId: client.installationId + }); + } catch (e) { + _Client.Client.pushError(parseWebsocket, e.code || 141, e.message || e, false, request.requestId); + + _logger.default.error(`Failed running beforeSubscribe on ${className} for session ${request.sessionToken} with:\n Error: ` + JSON.stringify(e)); + } + } + + _handleUpdateSubscription(parseWebsocket, request) { + this._handleUnsubscribe(parseWebsocket, request, false); + + this._handleSubscribe(parseWebsocket, request); + } + + _handleUnsubscribe(parseWebsocket, request, notifyClient = true) { + // If we can not find this client, return error to client + if (!Object.prototype.hasOwnProperty.call(parseWebsocket, 'clientId')) { + _Client.Client.pushError(parseWebsocket, 2, 'Can not find this client, make sure you connect to server before unsubscribing'); + + _logger.default.error('Can not find this client, make sure you connect to server before unsubscribing'); + + return; + } + + const requestId = request.requestId; + const client = this.clients.get(parseWebsocket.clientId); + + if (typeof client === 'undefined') { + _Client.Client.pushError(parseWebsocket, 2, 'Cannot find client with clientId ' + parseWebsocket.clientId + '. Make sure you connect to live query server before unsubscribing.'); + + _logger.default.error('Can not find this client ' + parseWebsocket.clientId); + + return; + } + + const subscriptionInfo = client.getSubscriptionInfo(requestId); + + if (typeof subscriptionInfo === 'undefined') { + _Client.Client.pushError(parseWebsocket, 2, 'Cannot find subscription with clientId ' + parseWebsocket.clientId + ' subscriptionId ' + requestId + '. Make sure you subscribe to live query server before unsubscribing.'); + + _logger.default.error('Can not find subscription with clientId ' + parseWebsocket.clientId + ' subscriptionId ' + requestId); + + return; + } // Remove subscription from client + + + client.deleteSubscriptionInfo(requestId); // Remove client from subscription + + const subscription = subscriptionInfo.subscription; + const className = subscription.className; + subscription.deleteClientSubscription(parseWebsocket.clientId, requestId); // If there is no client which is subscribing this subscription, remove it from subscriptions + + const classSubscriptions = this.subscriptions.get(className); + + if (!subscription.hasSubscribingClient()) { + classSubscriptions.delete(subscription.hash); + } // If there is no subscriptions under this class, remove it from subscriptions + + + if (classSubscriptions.size === 0) { + this.subscriptions.delete(className); + } + + (0, _triggers.runLiveQueryEventHandlers)({ + client, + event: 'unsubscribe', + clients: this.clients.size, + subscriptions: this.subscriptions.size, + sessionToken: subscriptionInfo.sessionToken, + useMasterKey: client.hasMasterKey, + installationId: client.installationId + }); + + if (!notifyClient) { + return; + } + + client.pushUnsubscribe(request.requestId); + + _logger.default.verbose(`Delete client: ${parseWebsocket.clientId} | subscription: ${request.requestId}`); + } + +} + +exports.ParseLiveQueryServer = ParseLiveQueryServer; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUGFyc2VMaXZlUXVlcnlTZXJ2ZXIuanMiXSwibmFtZXMiOlsiUGFyc2VMaXZlUXVlcnlTZXJ2ZXIiLCJjb25zdHJ1Y3RvciIsInNlcnZlciIsImNvbmZpZyIsInBhcnNlU2VydmVyQ29uZmlnIiwiY2xpZW50cyIsIk1hcCIsInN1YnNjcmlwdGlvbnMiLCJhcHBJZCIsIlBhcnNlIiwiYXBwbGljYXRpb25JZCIsIm1hc3RlcktleSIsImtleVBhaXJzIiwia2V5IiwiT2JqZWN0Iiwia2V5cyIsInNldCIsImxvZ2dlciIsInZlcmJvc2UiLCJkaXNhYmxlU2luZ2xlSW5zdGFuY2UiLCJzZXJ2ZXJVUkwiLCJpbml0aWFsaXplIiwiamF2YVNjcmlwdEtleSIsImNhY2hlQ29udHJvbGxlciIsImNhY2hlVGltZW91dCIsImF1dGhDYWNoZSIsIkxSVSIsIm1heCIsIm1heEFnZSIsInBhcnNlV2ViU29ja2V0U2VydmVyIiwiUGFyc2VXZWJTb2NrZXRTZXJ2ZXIiLCJwYXJzZVdlYnNvY2tldCIsIl9vbkNvbm5lY3QiLCJzdWJzY3JpYmVyIiwiUGFyc2VQdWJTdWIiLCJjcmVhdGVTdWJzY3JpYmVyIiwic3Vic2NyaWJlIiwib24iLCJjaGFubmVsIiwibWVzc2FnZVN0ciIsIm1lc3NhZ2UiLCJKU09OIiwicGFyc2UiLCJlIiwiZXJyb3IiLCJfaW5mbGF0ZVBhcnNlT2JqZWN0IiwiX29uQWZ0ZXJTYXZlIiwiX29uQWZ0ZXJEZWxldGUiLCJjdXJyZW50UGFyc2VPYmplY3QiLCJVc2VyUm91dGVyIiwicmVtb3ZlSGlkZGVuUHJvcGVydGllcyIsImNsYXNzTmFtZSIsInBhcnNlT2JqZWN0IiwiX2ZpbmlzaEZldGNoIiwib3JpZ2luYWxQYXJzZU9iamVjdCIsImRlbGV0ZWRQYXJzZU9iamVjdCIsInRvSlNPTiIsImNsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsImlkIiwic2l6ZSIsImNsYXNzU3Vic2NyaXB0aW9ucyIsImdldCIsImRlYnVnIiwic3Vic2NyaXB0aW9uIiwidmFsdWVzIiwiaXNTdWJzY3JpcHRpb25NYXRjaGVkIiwiX21hdGNoZXNTdWJzY3JpcHRpb24iLCJjbGllbnRJZCIsInJlcXVlc3RJZHMiLCJfIiwiZW50cmllcyIsImNsaWVudFJlcXVlc3RJZHMiLCJjbGllbnQiLCJyZXF1ZXN0SWQiLCJhY2wiLCJnZXRBQ0wiLCJvcCIsIl9nZXRDTFBPcGVyYXRpb24iLCJxdWVyeSIsInJlcyIsIl9tYXRjaGVzQ0xQIiwidGhlbiIsIl9tYXRjaGVzQUNMIiwiaXNNYXRjaGVkIiwiZXZlbnQiLCJzZXNzaW9uVG9rZW4iLCJvYmplY3QiLCJ1c2VNYXN0ZXJLZXkiLCJoYXNNYXN0ZXJLZXkiLCJpbnN0YWxsYXRpb25JZCIsInNlbmRFdmVudCIsInB1c2hEZWxldGUiLCJjYXRjaCIsIkNsaWVudCIsInB1c2hFcnJvciIsInBhcnNlV2ViU29ja2V0IiwiY29kZSIsInN0cmluZ2lmeSIsImlzT3JpZ2luYWxTdWJzY3JpcHRpb25NYXRjaGVkIiwiaXNDdXJyZW50U3Vic2NyaXB0aW9uTWF0Y2hlZCIsIm9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJvcmlnaW5hbEFDTCIsImN1cnJlbnRBQ0xDaGVja2luZ1Byb21pc2UiLCJjdXJyZW50QUNMIiwiYWxsIiwiaXNPcmlnaW5hbE1hdGNoZWQiLCJpc0N1cnJlbnRNYXRjaGVkIiwiaGFzaCIsInR5cGUiLCJvcmlnaW5hbCIsImZ1bmN0aW9uTmFtZSIsImNoYXJBdCIsInRvVXBwZXJDYXNlIiwic2xpY2UiLCJyZXF1ZXN0IiwidHY0IiwidmFsaWRhdGUiLCJSZXF1ZXN0U2NoZW1hIiwiX2hhbmRsZUNvbm5lY3QiLCJfaGFuZGxlU3Vic2NyaWJlIiwiX2hhbmRsZVVwZGF0ZVN1YnNjcmlwdGlvbiIsIl9oYW5kbGVVbnN1YnNjcmliZSIsImluZm8iLCJoYXMiLCJkZWxldGUiLCJzdWJzY3JpcHRpb25JbmZvIiwic3Vic2NyaXB0aW9uSW5mb3MiLCJkZWxldGVDbGllbnRTdWJzY3JpcHRpb24iLCJoYXNTdWJzY3JpYmluZ0NsaWVudCIsImdldEF1dGhGb3JTZXNzaW9uVG9rZW4iLCJmcm9tQ2FjaGUiLCJhdXRoUHJvbWlzZSIsImF1dGgiLCJ1c2VySWQiLCJ1c2VyIiwicmVzdWx0IiwiRXJyb3IiLCJJTlZBTElEX1NFU1NJT05fVE9LRU4iLCJkZWwiLCJnZXRTdWJzY3JpcHRpb25JbmZvIiwiYWNsR3JvdXAiLCJwdXNoIiwiU2NoZW1hQ29udHJvbGxlciIsInZhbGlkYXRlUGVybWlzc2lvbiIsImxlbmd0aCIsIm9iamVjdElkIiwiX3ZlcmlmeUFDTCIsInRva2VuIiwiaXNTdWJzY3JpcHRpb25TZXNzaW9uVG9rZW5NYXRjaGVkIiwiZ2V0UmVhZEFjY2VzcyIsImFjbF9oYXNfcm9sZXMiLCJwZXJtaXNzaW9uc0J5SWQiLCJzb21lIiwic3RhcnRzV2l0aCIsInJvbGVOYW1lcyIsImdldFVzZXJSb2xlcyIsInJvbGUiLCJnZXRQdWJsaWNSZWFkQWNjZXNzIiwic3Vic2NyaXB0aW9uVG9rZW4iLCJjbGllbnRTZXNzaW9uVG9rZW4iLCJfdmFsaWRhdGVLZXlzIiwiX2hhc01hc3RlcktleSIsInJlcSIsInB1c2hDb25uZWN0IiwidmFsaWRLZXlQYWlycyIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImlzVmFsaWQiLCJzZWNyZXQiLCJzdWJzY3JpcHRpb25IYXNoIiwiU3Vic2NyaXB0aW9uIiwid2hlcmUiLCJmaWVsZHMiLCJhZGRTdWJzY3JpcHRpb25JbmZvIiwiYWRkQ2xpZW50U3Vic2NyaXB0aW9uIiwicHVzaFN1YnNjcmliZSIsIm5vdGlmeUNsaWVudCIsImRlbGV0ZVN1YnNjcmlwdGlvbkluZm8iLCJwdXNoVW5zdWJzY3JpYmUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFNQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztB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LFlBQVksQ0FBQ21FLG9CQUFiLEVBQUwsRUFBMEM7QUFDeEN0RSxNQUFBQSxrQkFBa0IsQ0FBQ2tFLE1BQW5CLENBQTBCL0QsWUFBWSxDQUFDOEMsSUFBdkM7QUFDRCxLQXpEc0YsQ0EwRHZGOzs7QUFDQSxRQUFJakQsa0JBQWtCLENBQUNELElBQW5CLEtBQTRCLENBQWhDLEVBQW1DO0FBQ2pDLFdBQUtwRCxhQUFMLENBQW1CdUgsTUFBbkIsQ0FBMEIzRSxTQUExQjtBQUNEOztBQUNELDZDQUEwQjtBQUN4QnFCLE1BQUFBLE1BRHdCO0FBRXhCWSxNQUFBQSxLQUFLLEVBQUUsYUFGaUI7QUFHeEIvRSxNQUFBQSxPQUFPLEVBQUUsS0FBS0EsT0FBTCxDQUFhc0QsSUFIRTtBQUl4QnBELE1BQUFBLGFBQWEsRUFBRSxLQUFLQSxhQUFMLENBQW1Cb0QsSUFKVjtBQUt4QjBCLE1BQUFBLFlBQVksRUFBRTBDLGdCQUFnQixDQUFDMUMsWUFMUDtBQU14QkUsTUFBQUEsWUFBWSxFQUFFZixNQUFNLENBQUNnQixZQU5HO0FBT3hCQyxNQUFBQSxjQUFjLEVBQUVqQixNQUFNLENBQUNpQjtBQVBDLEtBQTFCOztBQVVBLFFBQUksQ0FBQzBGLFlBQUwsRUFBbUI7QUFDakI7QUFDRDs7QUFFRDNHLElBQUFBLE1BQU0sQ0FBQzZHLGVBQVAsQ0FBdUJqRSxPQUFPLENBQUMzQyxTQUEvQjs7QUFFQXhELG9CQUFPQyxPQUFQLENBQ0csa0JBQWlCYSxjQUFjLENBQUNvQyxRQUFTLG9CQUFtQmlELE9BQU8sQ0FBQzNDLFNBQVUsRUFEakY7QUFHRDs7QUF2eEJ3QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0djQgZnJvbSAndHY0JztcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJy4vU3Vic2NyaXB0aW9uJztcbmltcG9ydCB7IENsaWVudCB9IGZyb20gJy4vQ2xpZW50JztcbmltcG9ydCB7IFBhcnNlV2ViU29ja2V0U2VydmVyIH0gZnJvbSAnLi9QYXJzZVdlYlNvY2tldFNlcnZlcic7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5pbXBvcnQgUmVxdWVzdFNjaGVtYSBmcm9tICcuL1JlcXVlc3RTY2hlbWEnO1xuaW1wb3J0IHsgbWF0Y2hlc1F1ZXJ5LCBxdWVyeUhhc2ggfSBmcm9tICcuL1F1ZXJ5VG9vbHMnO1xuaW1wb3J0IHsgUGFyc2VQdWJTdWIgfSBmcm9tICcuL1BhcnNlUHViU3ViJztcbmltcG9ydCBTY2hlbWFDb250cm9sbGVyIGZyb20gJy4uL0NvbnRyb2xsZXJzL1NjaGVtYUNvbnRyb2xsZXInO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IHY0IGFzIHV1aWR2NCB9IGZyb20gJ3V1aWQnO1xuaW1wb3J0IHtcbiAgcnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyxcbiAgbWF5YmVSdW5Db25uZWN0VHJpZ2dlcixcbiAgbWF5YmVSdW5TdWJzY3JpYmVUcmlnZ2VyLFxuICBtYXliZVJ1bkFmdGVyRXZlbnRUcmlnZ2VyLFxufSBmcm9tICcuLi90cmlnZ2Vycyc7XG5pbXBvcnQgeyBnZXRBdXRoRm9yU2Vzc2lvblRva2VuLCBBdXRoIH0gZnJvbSAnLi4vQXV0aCc7XG5pbXBvcnQgeyBnZXRDYWNoZUNvbnRyb2xsZXIgfSBmcm9tICcuLi9Db250cm9sbGVycyc7XG5pbXBvcnQgTFJVIGZyb20gJ2xydS1jYWNoZSc7XG5pbXBvcnQgVXNlclJvdXRlciBmcm9tICcuLi9Sb3V0ZXJzL1VzZXJzUm91dGVyJztcblxuY2xhc3MgUGFyc2VMaXZlUXVlcnlTZXJ2ZXIge1xuICBjbGllbnRzOiBNYXA7XG4gIC8vIGNsYXNzTmFtZSAtPiAocXVlcnlIYXNoIC0+IHN1YnNjcmlwdGlvbilcbiAgc3Vic2NyaXB0aW9uczogT2JqZWN0O1xuICBwYXJzZVdlYlNvY2tldFNlcnZlcjogT2JqZWN0O1xuICBrZXlQYWlyczogYW55O1xuICAvLyBUaGUgc3Vic2NyaWJlciB3ZSB1c2UgdG8gZ2V0IG9iamVjdCB1cGRhdGUgZnJvbSBwdWJsaXNoZXJcbiAgc3Vic2NyaWJlcjogT2JqZWN0O1xuXG4gIGNvbnN0cnVjdG9yKHNlcnZlcjogYW55LCBjb25maWc6IGFueSA9IHt9LCBwYXJzZVNlcnZlckNvbmZpZzogYW55ID0ge30pIHtcbiAgICB0aGlzLnNlcnZlciA9IHNlcnZlcjtcbiAgICB0aGlzLmNsaWVudHMgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuXG4gICAgY29uZmlnLmFwcElkID0gY29uZmlnLmFwcElkIHx8IFBhcnNlLmFwcGxpY2F0aW9uSWQ7XG4gICAgY29uZmlnLm1hc3RlcktleSA9IGNvbmZpZy5tYXN0ZXJLZXkgfHwgUGFyc2UubWFzdGVyS2V5O1xuXG4gICAgLy8gU3RvcmUga2V5cywgY29udmVydCBvYmogdG8gbWFwXG4gICAgY29uc3Qga2V5UGFpcnMgPSBjb25maWcua2V5UGFpcnMgfHwge307XG4gICAgdGhpcy5rZXlQYWlycyA9IG5ldyBNYXAoKTtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhrZXlQYWlycykpIHtcbiAgICAgIHRoaXMua2V5UGFpcnMuc2V0KGtleSwga2V5UGFpcnNba2V5XSk7XG4gICAgfVxuICAgIGxvZ2dlci52ZXJib3NlKCdTdXBwb3J0IGtleSBwYWlycycsIHRoaXMua2V5UGFpcnMpO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSBQYXJzZVxuICAgIFBhcnNlLk9iamVjdC5kaXNhYmxlU2luZ2xlSW5zdGFuY2UoKTtcbiAgICBjb25zdCBzZXJ2ZXJVUkwgPSBjb25maWcuc2VydmVyVVJMIHx8IFBhcnNlLnNlcnZlclVSTDtcbiAgICBQYXJzZS5zZXJ2ZXJVUkwgPSBzZXJ2ZXJVUkw7XG4gICAgUGFyc2UuaW5pdGlhbGl6ZShjb25maWcuYXBwSWQsIFBhcnNlLmphdmFTY3JpcHRLZXksIGNvbmZpZy5tYXN0ZXJLZXkpO1xuXG4gICAgLy8gVGhlIGNhY2hlIGNvbnRyb2xsZXIgaXMgYSBwcm9wZXIgY2FjaGUgY29udHJvbGxlclxuICAgIC8vIHdpdGggYWNjZXNzIHRvIFVzZXIgYW5kIFJvbGVzXG4gICAgdGhpcy5jYWNoZUNvbnRyb2xsZXIgPSBnZXRDYWNoZUNvbnRyb2xsZXIocGFyc2VTZXJ2ZXJDb25maWcpO1xuXG4gICAgY29uZmlnLmNhY2hlVGltZW91dCA9IGNvbmZpZy5jYWNoZVRpbWVvdXQgfHwgNSAqIDEwMDA7IC8vIDVzXG5cbiAgICAvLyBUaGlzIGF1dGggY2FjaGUgc3RvcmVzIHRoZSBwcm9taXNlcyBmb3IgZWFjaCBhdXRoIHJlc29sdXRpb24uXG4gICAgLy8gVGhlIG1haW4gYmVuZWZpdCBpcyB0byBiZSBhYmxlIHRvIHJldXNlIHRoZSBzYW1lIHVzZXIgLyBzZXNzaW9uIHRva2VuIHJlc29sdXRpb24uXG4gICAgdGhpcy5hdXRoQ2FjaGUgPSBuZXcgTFJVKHtcbiAgICAgIG1heDogNTAwLCAvLyA1MDAgY29uY3VycmVudFxuICAgICAgbWF4QWdlOiBjb25maWcuY2FjaGVUaW1lb3V0LFxuICAgIH0pO1xuICAgIC8vIEluaXRpYWxpemUgd2Vic29ja2V0IHNlcnZlclxuICAgIHRoaXMucGFyc2VXZWJTb2NrZXRTZXJ2ZXIgPSBuZXcgUGFyc2VXZWJTb2NrZXRTZXJ2ZXIoXG4gICAgICBzZXJ2ZXIsXG4gICAgICBwYXJzZVdlYnNvY2tldCA9PiB0aGlzLl9vbkNvbm5lY3QocGFyc2VXZWJzb2NrZXQpLFxuICAgICAgY29uZmlnXG4gICAgKTtcblxuICAgIC8vIEluaXRpYWxpemUgc3Vic2NyaWJlclxuICAgIHRoaXMuc3Vic2NyaWJlciA9IFBhcnNlUHViU3ViLmNyZWF0ZVN1YnNjcmliZXIoY29uZmlnKTtcbiAgICB0aGlzLnN1YnNjcmliZXIuc3Vic2NyaWJlKFBhcnNlLmFwcGxpY2F0aW9uSWQgKyAnYWZ0ZXJTYXZlJyk7XG4gICAgdGhpcy5zdWJzY3JpYmVyLnN1YnNjcmliZShQYXJzZS5hcHBsaWNhdGlvbklkICsgJ2FmdGVyRGVsZXRlJyk7XG4gICAgLy8gUmVnaXN0ZXIgbWVzc2FnZSBoYW5kbGVyIGZvciBzdWJzY3JpYmVyLiBXaGVuIHB1Ymxpc2hlciBnZXQgbWVzc2FnZXMsIGl0IHdpbGwgcHVibGlzaCBtZXNzYWdlXG4gICAgLy8gdG8gdGhlIHN1YnNjcmliZXJzIGFuZCB0aGUgaGFuZGxlciB3aWxsIGJlIGNhbGxlZC5cbiAgICB0aGlzLnN1YnNjcmliZXIub24oJ21lc3NhZ2UnLCAoY2hhbm5lbCwgbWVzc2FnZVN0cikgPT4ge1xuICAgICAgbG9nZ2VyLnZlcmJvc2UoJ1N1YnNjcmliZSBtZXNzYWdlICVqJywgbWVzc2FnZVN0cik7XG4gICAgICBsZXQgbWVzc2FnZTtcbiAgICAgIHRyeSB7XG4gICAgICAgIG1lc3NhZ2UgPSBKU09OLnBhcnNlKG1lc3NhZ2VTdHIpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ3VuYWJsZSB0byBwYXJzZSBtZXNzYWdlJywgbWVzc2FnZVN0ciwgZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2luZmxhdGVQYXJzZU9iamVjdChtZXNzYWdlKTtcbiAgICAgIGlmIChjaGFubmVsID09PSBQYXJzZS5hcHBsaWNhdGlvbklkICsgJ2FmdGVyU2F2ZScpIHtcbiAgICAgICAgdGhpcy5fb25BZnRlclNhdmUobWVzc2FnZSk7XG4gICAgICB9IGVsc2UgaWYgKGNoYW5uZWwgPT09IFBhcnNlLmFwcGxpY2F0aW9uSWQgKyAnYWZ0ZXJEZWxldGUnKSB7XG4gICAgICAgIHRoaXMuX29uQWZ0ZXJEZWxldGUobWVzc2FnZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ0dldCBtZXNzYWdlICVzIGZyb20gdW5rbm93biBjaGFubmVsICVqJywgbWVzc2FnZSwgY2hhbm5lbCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBNZXNzYWdlIGlzIHRoZSBKU09OIG9iamVjdCBmcm9tIHB1Ymxpc2hlci4gTWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QgaXMgdGhlIFBhcnNlT2JqZWN0IEpTT04gYWZ0ZXIgY2hhbmdlcy5cbiAgLy8gTWVzc2FnZS5vcmlnaW5hbFBhcnNlT2JqZWN0IGlzIHRoZSBvcmlnaW5hbCBQYXJzZU9iamVjdCBKU09OLlxuICBfaW5mbGF0ZVBhcnNlT2JqZWN0KG1lc3NhZ2U6IGFueSk6IHZvaWQge1xuICAgIC8vIEluZmxhdGUgbWVyZ2VkIG9iamVjdFxuICAgIGNvbnN0IGN1cnJlbnRQYXJzZU9iamVjdCA9IG1lc3NhZ2UuY3VycmVudFBhcnNlT2JqZWN0O1xuICAgIFVzZXJSb3V0ZXIucmVtb3ZlSGlkZGVuUHJvcGVydGllcyhjdXJyZW50UGFyc2VPYmplY3QpO1xuICAgIGxldCBjbGFzc05hbWUgPSBjdXJyZW50UGFyc2VPYmplY3QuY2xhc3NOYW1lO1xuICAgIGxldCBwYXJzZU9iamVjdCA9IG5ldyBQYXJzZS5PYmplY3QoY2xhc3NOYW1lKTtcbiAgICBwYXJzZU9iamVjdC5fZmluaXNoRmV0Y2goY3VycmVudFBhcnNlT2JqZWN0KTtcbiAgICBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdCA9IHBhcnNlT2JqZWN0O1xuICAgIC8vIEluZmxhdGUgb3JpZ2luYWwgb2JqZWN0XG4gICAgY29uc3Qgb3JpZ2luYWxQYXJzZU9iamVjdCA9IG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdDtcbiAgICBpZiAob3JpZ2luYWxQYXJzZU9iamVjdCkge1xuICAgICAgVXNlclJvdXRlci5yZW1vdmVIaWRkZW5Qcm9wZXJ0aWVzKG9yaWdpbmFsUGFyc2VPYmplY3QpO1xuICAgICAgY2xhc3NOYW1lID0gb3JpZ2luYWxQYXJzZU9iamVjdC5jbGFzc05hbWU7XG4gICAgICBwYXJzZU9iamVjdCA9IG5ldyBQYXJzZS5PYmplY3QoY2xhc3NOYW1lKTtcbiAgICAgIHBhcnNlT2JqZWN0Ll9maW5pc2hGZXRjaChvcmlnaW5hbFBhcnNlT2JqZWN0KTtcbiAgICAgIG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdCA9IHBhcnNlT2JqZWN0O1xuICAgIH1cbiAgfVxuXG4gIC8vIE1lc3NhZ2UgaXMgdGhlIEpTT04gb2JqZWN0IGZyb20gcHVibGlzaGVyIGFmdGVyIGluZmxhdGVkLiBNZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdCBpcyB0aGUgUGFyc2VPYmplY3QgYWZ0ZXIgY2hhbmdlcy5cbiAgLy8gTWVzc2FnZS5vcmlnaW5hbFBhcnNlT2JqZWN0IGlzIHRoZSBvcmlnaW5hbCBQYXJzZU9iamVjdC5cbiAgX29uQWZ0ZXJEZWxldGUobWVzc2FnZTogYW55KTogdm9pZCB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoUGFyc2UuYXBwbGljYXRpb25JZCArICdhZnRlckRlbGV0ZSBpcyB0cmlnZ2VyZWQnKTtcblxuICAgIGxldCBkZWxldGVkUGFyc2VPYmplY3QgPSBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdC50b0pTT04oKTtcbiAgICBjb25zdCBjbGFzc0xldmVsUGVybWlzc2lvbnMgPSBtZXNzYWdlLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucztcbiAgICBjb25zdCBjbGFzc05hbWUgPSBkZWxldGVkUGFyc2VPYmplY3QuY2xhc3NOYW1lO1xuICAgIGxvZ2dlci52ZXJib3NlKCdDbGFzc05hbWU6ICVqIHwgT2JqZWN0SWQ6ICVzJywgY2xhc3NOYW1lLCBkZWxldGVkUGFyc2VPYmplY3QuaWQpO1xuICAgIGxvZ2dlci52ZXJib3NlKCdDdXJyZW50IGNsaWVudCBudW1iZXIgOiAlZCcsIHRoaXMuY2xpZW50cy5zaXplKTtcblxuICAgIGNvbnN0IGNsYXNzU3Vic2NyaXB0aW9ucyA9IHRoaXMuc3Vic2NyaXB0aW9ucy5nZXQoY2xhc3NOYW1lKTtcbiAgICBpZiAodHlwZW9mIGNsYXNzU3Vic2NyaXB0aW9ucyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZygnQ2FuIG5vdCBmaW5kIHN1YnNjcmlwdGlvbnMgdW5kZXIgdGhpcyBjbGFzcyAnICsgY2xhc3NOYW1lKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZm9yIChjb25zdCBzdWJzY3JpcHRpb24gb2YgY2xhc3NTdWJzY3JpcHRpb25zLnZhbHVlcygpKSB7XG4gICAgICBjb25zdCBpc1N1YnNjcmlwdGlvbk1hdGNoZWQgPSB0aGlzLl9tYXRjaGVzU3Vic2NyaXB0aW9uKGRlbGV0ZWRQYXJzZU9iamVjdCwgc3Vic2NyaXB0aW9uKTtcbiAgICAgIGlmICghaXNTdWJzY3JpcHRpb25NYXRjaGVkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBbY2xpZW50SWQsIHJlcXVlc3RJZHNdIG9mIF8uZW50cmllcyhzdWJzY3JpcHRpb24uY2xpZW50UmVxdWVzdElkcykpIHtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRzLmdldChjbGllbnRJZCk7XG4gICAgICAgIGlmICh0eXBlb2YgY2xpZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgcmVxdWVzdElkIG9mIHJlcXVlc3RJZHMpIHtcbiAgICAgICAgICBjb25zdCBhY2wgPSBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdC5nZXRBQ0woKTtcbiAgICAgICAgICAvLyBDaGVjayBDTFBcbiAgICAgICAgICBjb25zdCBvcCA9IHRoaXMuX2dldENMUE9wZXJhdGlvbihzdWJzY3JpcHRpb24ucXVlcnkpO1xuICAgICAgICAgIGxldCByZXMgPSB7fTtcbiAgICAgICAgICB0aGlzLl9tYXRjaGVzQ0xQKGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgbWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QsIGNsaWVudCwgcmVxdWVzdElkLCBvcClcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgLy8gQ2hlY2sgQUNMXG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tYXRjaGVzQUNMKGFjbCwgY2xpZW50LCByZXF1ZXN0SWQpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKGlzTWF0Y2hlZCA9PiB7XG4gICAgICAgICAgICAgIGlmICghaXNNYXRjaGVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmVzID0ge1xuICAgICAgICAgICAgICAgIGV2ZW50OiAnZGVsZXRlJyxcbiAgICAgICAgICAgICAgICBzZXNzaW9uVG9rZW46IGNsaWVudC5zZXNzaW9uVG9rZW4sXG4gICAgICAgICAgICAgICAgb2JqZWN0OiBkZWxldGVkUGFyc2VPYmplY3QsXG4gICAgICAgICAgICAgICAgY2xpZW50czogdGhpcy5jbGllbnRzLnNpemUsXG4gICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgICAgICAgICAgICAgdXNlTWFzdGVyS2V5OiBjbGllbnQuaGFzTWFzdGVyS2V5LFxuICAgICAgICAgICAgICAgIGluc3RhbGxhdGlvbklkOiBjbGllbnQuaW5zdGFsbGF0aW9uSWQsXG4gICAgICAgICAgICAgICAgc2VuZEV2ZW50OiB0cnVlLFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICByZXR1cm4gbWF5YmVSdW5BZnRlckV2ZW50VHJpZ2dlcignYWZ0ZXJFdmVudCcsIGNsYXNzTmFtZSwgcmVzKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgIGlmICghcmVzLnNlbmRFdmVudCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAocmVzLm9iamVjdCAmJiB0eXBlb2YgcmVzLm9iamVjdC50b0pTT04gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICBkZWxldGVkUGFyc2VPYmplY3QgPSByZXMub2JqZWN0LnRvSlNPTigpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZWRQYXJzZU9iamVjdC5jbGFzc05hbWUgPSBjbGFzc05hbWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgY2xpZW50LnB1c2hEZWxldGUocmVxdWVzdElkLCBkZWxldGVkUGFyc2VPYmplY3QpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgIENsaWVudC5wdXNoRXJyb3IoXG4gICAgICAgICAgICAgICAgY2xpZW50LnBhcnNlV2ViU29ja2V0LFxuICAgICAgICAgICAgICAgIGVycm9yLmNvZGUgfHwgMTQxLFxuICAgICAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgfHwgZXJyb3IsXG4gICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICAgcmVxdWVzdElkXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAgICBgRmFpbGVkIHJ1bm5pbmcgYWZ0ZXJMaXZlUXVlcnlFdmVudCBvbiBjbGFzcyAke2NsYXNzTmFtZX0gZm9yIGV2ZW50ICR7cmVzLmV2ZW50fSB3aXRoIHNlc3Npb24gJHtyZXMuc2Vzc2lvblRva2VufSB3aXRoOlxcbiBFcnJvcjogYCArXG4gICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShlcnJvcilcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gTWVzc2FnZSBpcyB0aGUgSlNPTiBvYmplY3QgZnJvbSBwdWJsaXNoZXIgYWZ0ZXIgaW5mbGF0ZWQuIE1lc3NhZ2UuY3VycmVudFBhcnNlT2JqZWN0IGlzIHRoZSBQYXJzZU9iamVjdCBhZnRlciBjaGFuZ2VzLlxuICAvLyBNZXNzYWdlLm9yaWdpbmFsUGFyc2VPYmplY3QgaXMgdGhlIG9yaWdpbmFsIFBhcnNlT2JqZWN0LlxuICBfb25BZnRlclNhdmUobWVzc2FnZTogYW55KTogdm9pZCB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoUGFyc2UuYXBwbGljYXRpb25JZCArICdhZnRlclNhdmUgaXMgdHJpZ2dlcmVkJyk7XG5cbiAgICBsZXQgb3JpZ2luYWxQYXJzZU9iamVjdCA9IG51bGw7XG4gICAgaWYgKG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdCkge1xuICAgICAgb3JpZ2luYWxQYXJzZU9iamVjdCA9IG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdC50b0pTT04oKTtcbiAgICB9XG4gICAgY29uc3QgY2xhc3NMZXZlbFBlcm1pc3Npb25zID0gbWVzc2FnZS5jbGFzc0xldmVsUGVybWlzc2lvbnM7XG4gICAgbGV0IGN1cnJlbnRQYXJzZU9iamVjdCA9IG1lc3NhZ2UuY3VycmVudFBhcnNlT2JqZWN0LnRvSlNPTigpO1xuICAgIGNvbnN0IGNsYXNzTmFtZSA9IGN1cnJlbnRQYXJzZU9iamVjdC5jbGFzc05hbWU7XG4gICAgbG9nZ2VyLnZlcmJvc2UoJ0NsYXNzTmFtZTogJXMgfCBPYmplY3RJZDogJXMnLCBjbGFzc05hbWUsIGN1cnJlbnRQYXJzZU9iamVjdC5pZCk7XG4gICAgbG9nZ2VyLnZlcmJvc2UoJ0N1cnJlbnQgY2xpZW50IG51bWJlciA6ICVkJywgdGhpcy5jbGllbnRzLnNpemUpO1xuXG4gICAgY29uc3QgY2xhc3NTdWJzY3JpcHRpb25zID0gdGhpcy5zdWJzY3JpcHRpb25zLmdldChjbGFzc05hbWUpO1xuICAgIGlmICh0eXBlb2YgY2xhc3NTdWJzY3JpcHRpb25zID09PSAndW5kZWZpbmVkJykge1xuICAgICAgbG9nZ2VyLmRlYnVnKCdDYW4gbm90IGZpbmQgc3Vic2NyaXB0aW9ucyB1bmRlciB0aGlzIGNsYXNzICcgKyBjbGFzc05hbWUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHN1YnNjcmlwdGlvbiBvZiBjbGFzc1N1YnNjcmlwdGlvbnMudmFsdWVzKCkpIHtcbiAgICAgIGNvbnN0IGlzT3JpZ2luYWxTdWJzY3JpcHRpb25NYXRjaGVkID0gdGhpcy5fbWF0Y2hlc1N1YnNjcmlwdGlvbihcbiAgICAgICAgb3JpZ2luYWxQYXJzZU9iamVjdCxcbiAgICAgICAgc3Vic2NyaXB0aW9uXG4gICAgICApO1xuICAgICAgY29uc3QgaXNDdXJyZW50U3Vic2NyaXB0aW9uTWF0Y2hlZCA9IHRoaXMuX21hdGNoZXNTdWJzY3JpcHRpb24oXG4gICAgICAgIGN1cnJlbnRQYXJzZU9iamVjdCxcbiAgICAgICAgc3Vic2NyaXB0aW9uXG4gICAgICApO1xuICAgICAgZm9yIChjb25zdCBbY2xpZW50SWQsIHJlcXVlc3RJZHNdIG9mIF8uZW50cmllcyhzdWJzY3JpcHRpb24uY2xpZW50UmVxdWVzdElkcykpIHtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRzLmdldChjbGllbnRJZCk7XG4gICAgICAgIGlmICh0eXBlb2YgY2xpZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgcmVxdWVzdElkIG9mIHJlcXVlc3RJZHMpIHtcbiAgICAgICAgICAvLyBTZXQgb3JpZ25hbCBQYXJzZU9iamVjdCBBQ0wgY2hlY2tpbmcgcHJvbWlzZSwgaWYgdGhlIG9iamVjdCBkb2VzIG5vdCBtYXRjaFxuICAgICAgICAgIC8vIHN1YnNjcmlwdGlvbiwgd2UgZG8gbm90IG5lZWQgdG8gY2hlY2sgQUNMXG4gICAgICAgICAgbGV0IG9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlO1xuICAgICAgICAgIGlmICghaXNPcmlnaW5hbFN1YnNjcmlwdGlvbk1hdGNoZWQpIHtcbiAgICAgICAgICAgIG9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IG9yaWdpbmFsQUNMO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdCkge1xuICAgICAgICAgICAgICBvcmlnaW5hbEFDTCA9IG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdC5nZXRBQ0woKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlID0gdGhpcy5fbWF0Y2hlc0FDTChvcmlnaW5hbEFDTCwgY2xpZW50LCByZXF1ZXN0SWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBTZXQgY3VycmVudCBQYXJzZU9iamVjdCBBQ0wgY2hlY2tpbmcgcHJvbWlzZSwgaWYgdGhlIG9iamVjdCBkb2VzIG5vdCBtYXRjaFxuICAgICAgICAgIC8vIHN1YnNjcmlwdGlvbiwgd2UgZG8gbm90IG5lZWQgdG8gY2hlY2sgQUNMXG4gICAgICAgICAgbGV0IGN1cnJlbnRBQ0xDaGVja2luZ1Byb21pc2U7XG4gICAgICAgICAgbGV0IHJlcyA9IHt9O1xuICAgICAgICAgIGlmICghaXNDdXJyZW50U3Vic2NyaXB0aW9uTWF0Y2hlZCkge1xuICAgICAgICAgICAgY3VycmVudEFDTENoZWNraW5nUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRBQ0wgPSBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdC5nZXRBQ0woKTtcbiAgICAgICAgICAgIGN1cnJlbnRBQ0xDaGVja2luZ1Byb21pc2UgPSB0aGlzLl9tYXRjaGVzQUNMKGN1cnJlbnRBQ0wsIGNsaWVudCwgcmVxdWVzdElkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3Qgb3AgPSB0aGlzLl9nZXRDTFBPcGVyYXRpb24oc3Vic2NyaXB0aW9uLnF1ZXJ5KTtcbiAgICAgICAgICB0aGlzLl9tYXRjaGVzQ0xQKGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgbWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QsIGNsaWVudCwgcmVxdWVzdElkLCBvcClcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtvcmlnaW5hbEFDTENoZWNraW5nUHJvbWlzZSwgY3VycmVudEFDTENoZWNraW5nUHJvbWlzZV0pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKChbaXNPcmlnaW5hbE1hdGNoZWQsIGlzQ3VycmVudE1hdGNoZWRdKSA9PiB7XG4gICAgICAgICAgICAgIGxvZ2dlci52ZXJib3NlKFxuICAgICAgICAgICAgICAgICdPcmlnaW5hbCAlaiB8IEN1cnJlbnQgJWogfCBNYXRjaDogJXMsICVzLCAlcywgJXMgfCBRdWVyeTogJXMnLFxuICAgICAgICAgICAgICAgIG9yaWdpbmFsUGFyc2VPYmplY3QsXG4gICAgICAgICAgICAgICAgY3VycmVudFBhcnNlT2JqZWN0LFxuICAgICAgICAgICAgICAgIGlzT3JpZ2luYWxTdWJzY3JpcHRpb25NYXRjaGVkLFxuICAgICAgICAgICAgICAgIGlzQ3VycmVudFN1YnNjcmlwdGlvbk1hdGNoZWQsXG4gICAgICAgICAgICAgICAgaXNPcmlnaW5hbE1hdGNoZWQsXG4gICAgICAgICAgICAgICAgaXNDdXJyZW50TWF0Y2hlZCxcbiAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb24uaGFzaFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAvLyBEZWNpZGUgZXZlbnQgdHlwZVxuICAgICAgICAgICAgICBsZXQgdHlwZTtcbiAgICAgICAgICAgICAgaWYgKGlzT3JpZ2luYWxNYXRjaGVkICYmIGlzQ3VycmVudE1hdGNoZWQpIHtcbiAgICAgICAgICAgICAgICB0eXBlID0gJ3VwZGF0ZSc7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNPcmlnaW5hbE1hdGNoZWQgJiYgIWlzQ3VycmVudE1hdGNoZWQpIHtcbiAgICAgICAgICAgICAgICB0eXBlID0gJ2xlYXZlJztcbiAgICAgICAgICAgICAgfSBlbHNlIGlmICghaXNPcmlnaW5hbE1hdGNoZWQgJiYgaXNDdXJyZW50TWF0Y2hlZCkge1xuICAgICAgICAgICAgICAgIGlmIChvcmlnaW5hbFBhcnNlT2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgICB0eXBlID0gJ2VudGVyJztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgdHlwZSA9ICdjcmVhdGUnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBtZXNzYWdlLmV2ZW50ID0gdHlwZTtcbiAgICAgICAgICAgICAgcmVzID0ge1xuICAgICAgICAgICAgICAgIGV2ZW50OiB0eXBlLFxuICAgICAgICAgICAgICAgIHNlc3Npb25Ub2tlbjogY2xpZW50LnNlc3Npb25Ub2tlbixcbiAgICAgICAgICAgICAgICBvYmplY3Q6IGN1cnJlbnRQYXJzZU9iamVjdCxcbiAgICAgICAgICAgICAgICBvcmlnaW5hbDogb3JpZ2luYWxQYXJzZU9iamVjdCxcbiAgICAgICAgICAgICAgICBjbGllbnRzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb25zOiB0aGlzLnN1YnNjcmlwdGlvbnMuc2l6ZSxcbiAgICAgICAgICAgICAgICB1c2VNYXN0ZXJLZXk6IGNsaWVudC5oYXNNYXN0ZXJLZXksXG4gICAgICAgICAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IGNsaWVudC5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgICAgICAgICBzZW5kRXZlbnQ6IHRydWUsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIHJldHVybiBtYXliZVJ1bkFmdGVyRXZlbnRUcmlnZ2VyKCdhZnRlckV2ZW50JywgY2xhc3NOYW1lLCByZXMpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFyZXMuc2VuZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChyZXMub2JqZWN0ICYmIHR5cGVvZiByZXMub2JqZWN0LnRvSlNPTiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgY3VycmVudFBhcnNlT2JqZWN0ID0gcmVzLm9iamVjdC50b0pTT04oKTtcbiAgICAgICAgICAgICAgICAgIGN1cnJlbnRQYXJzZU9iamVjdC5jbGFzc05hbWUgPSByZXMub2JqZWN0LmNsYXNzTmFtZSB8fCBjbGFzc05hbWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHJlcy5vcmlnaW5hbCAmJiB0eXBlb2YgcmVzLm9yaWdpbmFsLnRvSlNPTiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgb3JpZ2luYWxQYXJzZU9iamVjdCA9IHJlcy5vcmlnaW5hbC50b0pTT04oKTtcbiAgICAgICAgICAgICAgICAgIG9yaWdpbmFsUGFyc2VPYmplY3QuY2xhc3NOYW1lID0gcmVzLm9yaWdpbmFsLmNsYXNzTmFtZSB8fCBjbGFzc05hbWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGZ1bmN0aW9uTmFtZSA9XG4gICAgICAgICAgICAgICAgICAncHVzaCcgKyBtZXNzYWdlLmV2ZW50LmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgbWVzc2FnZS5ldmVudC5zbGljZSgxKTtcbiAgICAgICAgICAgICAgICBpZiAoY2xpZW50W2Z1bmN0aW9uTmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgIGNsaWVudFtmdW5jdGlvbk5hbWVdKHJlcXVlc3RJZCwgY3VycmVudFBhcnNlT2JqZWN0LCBvcmlnaW5hbFBhcnNlT2JqZWN0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBDbGllbnQucHVzaEVycm9yKFxuICAgICAgICAgICAgICAgICAgY2xpZW50LnBhcnNlV2ViU29ja2V0LFxuICAgICAgICAgICAgICAgICAgZXJyb3IuY29kZSB8fCAxNDEsXG4gICAgICAgICAgICAgICAgICBlcnJvci5tZXNzYWdlIHx8IGVycm9yLFxuICAgICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICAgICByZXF1ZXN0SWRcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAgICAgIGBGYWlsZWQgcnVubmluZyBhZnRlckxpdmVRdWVyeUV2ZW50IG9uIGNsYXNzICR7Y2xhc3NOYW1lfSBmb3IgZXZlbnQgJHtyZXMuZXZlbnR9IHdpdGggc2Vzc2lvbiAke3Jlcy5zZXNzaW9uVG9rZW59IHdpdGg6XFxuIEVycm9yOiBgICtcbiAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkoZXJyb3IpXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIF9vbkNvbm5lY3QocGFyc2VXZWJzb2NrZXQ6IGFueSk6IHZvaWQge1xuICAgIHBhcnNlV2Vic29ja2V0Lm9uKCdtZXNzYWdlJywgcmVxdWVzdCA9PiB7XG4gICAgICBpZiAodHlwZW9mIHJlcXVlc3QgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmVxdWVzdCA9IEpTT04ucGFyc2UocmVxdWVzdCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoJ3VuYWJsZSB0byBwYXJzZSByZXF1ZXN0JywgcmVxdWVzdCwgZSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBsb2dnZXIudmVyYm9zZSgnUmVxdWVzdDogJWonLCByZXF1ZXN0KTtcblxuICAgICAgLy8gQ2hlY2sgd2hldGhlciB0aGlzIHJlcXVlc3QgaXMgYSB2YWxpZCByZXF1ZXN0LCByZXR1cm4gZXJyb3IgZGlyZWN0bHkgaWYgbm90XG4gICAgICBpZiAoXG4gICAgICAgICF0djQudmFsaWRhdGUocmVxdWVzdCwgUmVxdWVzdFNjaGVtYVsnZ2VuZXJhbCddKSB8fFxuICAgICAgICAhdHY0LnZhbGlkYXRlKHJlcXVlc3QsIFJlcXVlc3RTY2hlbWFbcmVxdWVzdC5vcF0pXG4gICAgICApIHtcbiAgICAgICAgQ2xpZW50LnB1c2hFcnJvcihwYXJzZVdlYnNvY2tldCwgMSwgdHY0LmVycm9yLm1lc3NhZ2UpO1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ0Nvbm5lY3QgbWVzc2FnZSBlcnJvciAlcycsIHR2NC5lcnJvci5tZXNzYWdlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBzd2l0Y2ggKHJlcXVlc3Qub3ApIHtcbiAgICAgICAgY2FzZSAnY29ubmVjdCc6XG4gICAgICAgICAgdGhpcy5faGFuZGxlQ29ubmVjdChwYXJzZVdlYnNvY2tldCwgcmVxdWVzdCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3N1YnNjcmliZSc6XG4gICAgICAgICAgdGhpcy5faGFuZGxlU3Vic2NyaWJlKHBhcnNlV2Vic29ja2V0LCByZXF1ZXN0KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAndXBkYXRlJzpcbiAgICAgICAgICB0aGlzLl9oYW5kbGVVcGRhdGVTdWJzY3JpcHRpb24ocGFyc2VXZWJzb2NrZXQsIHJlcXVlc3QpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICd1bnN1YnNjcmliZSc6XG4gICAgICAgICAgdGhpcy5faGFuZGxlVW5zdWJzY3JpYmUocGFyc2VXZWJzb2NrZXQsIHJlcXVlc3QpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIENsaWVudC5wdXNoRXJyb3IocGFyc2VXZWJzb2NrZXQsIDMsICdHZXQgdW5rbm93biBvcGVyYXRpb24nKTtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0dldCB1bmtub3duIG9wZXJhdGlvbicsIHJlcXVlc3Qub3ApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcGFyc2VXZWJzb2NrZXQub24oJ2Rpc2Nvbm5lY3QnLCAoKSA9PiB7XG4gICAgICBsb2dnZXIuaW5mbyhgQ2xpZW50IGRpc2Nvbm5lY3Q6ICR7cGFyc2VXZWJzb2NrZXQuY2xpZW50SWR9YCk7XG4gICAgICBjb25zdCBjbGllbnRJZCA9IHBhcnNlV2Vic29ja2V0LmNsaWVudElkO1xuICAgICAgaWYgKCF0aGlzLmNsaWVudHMuaGFzKGNsaWVudElkKSkge1xuICAgICAgICBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzKHtcbiAgICAgICAgICBldmVudDogJ3dzX2Rpc2Nvbm5lY3RfZXJyb3InLFxuICAgICAgICAgIGNsaWVudHM6IHRoaXMuY2xpZW50cy5zaXplLFxuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IHRoaXMuc3Vic2NyaXB0aW9ucy5zaXplLFxuICAgICAgICAgIGVycm9yOiBgVW5hYmxlIHRvIGZpbmQgY2xpZW50ICR7Y2xpZW50SWR9YCxcbiAgICAgICAgfSk7XG4gICAgICAgIGxvZ2dlci5lcnJvcihgQ2FuIG5vdCBmaW5kIGNsaWVudCAke2NsaWVudElkfSBvbiBkaXNjb25uZWN0YCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gRGVsZXRlIGNsaWVudFxuICAgICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRzLmdldChjbGllbnRJZCk7XG4gICAgICB0aGlzLmNsaWVudHMuZGVsZXRlKGNsaWVudElkKTtcblxuICAgICAgLy8gRGVsZXRlIGNsaWVudCBmcm9tIHN1YnNjcmlwdGlvbnNcbiAgICAgIGZvciAoY29uc3QgW3JlcXVlc3RJZCwgc3Vic2NyaXB0aW9uSW5mb10gb2YgXy5lbnRyaWVzKGNsaWVudC5zdWJzY3JpcHRpb25JbmZvcykpIHtcbiAgICAgICAgY29uc3Qgc3Vic2NyaXB0aW9uID0gc3Vic2NyaXB0aW9uSW5mby5zdWJzY3JpcHRpb247XG4gICAgICAgIHN1YnNjcmlwdGlvbi5kZWxldGVDbGllbnRTdWJzY3JpcHRpb24oY2xpZW50SWQsIHJlcXVlc3RJZCk7XG5cbiAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gY2xpZW50IHdoaWNoIGlzIHN1YnNjcmliaW5nIHRoaXMgc3Vic2NyaXB0aW9uLCByZW1vdmUgaXQgZnJvbSBzdWJzY3JpcHRpb25zXG4gICAgICAgIGNvbnN0IGNsYXNzU3Vic2NyaXB0aW9ucyA9IHRoaXMuc3Vic2NyaXB0aW9ucy5nZXQoc3Vic2NyaXB0aW9uLmNsYXNzTmFtZSk7XG4gICAgICAgIGlmICghc3Vic2NyaXB0aW9uLmhhc1N1YnNjcmliaW5nQ2xpZW50KCkpIHtcbiAgICAgICAgICBjbGFzc1N1YnNjcmlwdGlvbnMuZGVsZXRlKHN1YnNjcmlwdGlvbi5oYXNoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBJZiB0aGVyZSBpcyBubyBzdWJzY3JpcHRpb25zIHVuZGVyIHRoaXMgY2xhc3MsIHJlbW92ZSBpdCBmcm9tIHN1YnNjcmlwdGlvbnNcbiAgICAgICAgaWYgKGNsYXNzU3Vic2NyaXB0aW9ucy5zaXplID09PSAwKSB7XG4gICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmRlbGV0ZShzdWJzY3JpcHRpb24uY2xhc3NOYW1lKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBsb2dnZXIudmVyYm9zZSgnQ3VycmVudCBjbGllbnRzICVkJywgdGhpcy5jbGllbnRzLnNpemUpO1xuICAgICAgbG9nZ2VyLnZlcmJvc2UoJ0N1cnJlbnQgc3Vic2NyaXB0aW9ucyAlZCcsIHRoaXMuc3Vic2NyaXB0aW9ucy5zaXplKTtcbiAgICAgIHJ1bkxpdmVRdWVyeUV2ZW50SGFuZGxlcnMoe1xuICAgICAgICBldmVudDogJ3dzX2Rpc2Nvbm5lY3QnLFxuICAgICAgICBjbGllbnRzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgICAgIHVzZU1hc3RlcktleTogY2xpZW50Lmhhc01hc3RlcktleSxcbiAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IGNsaWVudC5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgc2Vzc2lvblRva2VuOiBjbGllbnQuc2Vzc2lvblRva2VuLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzKHtcbiAgICAgIGV2ZW50OiAnd3NfY29ubmVjdCcsXG4gICAgICBjbGllbnRzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgIHN1YnNjcmlwdGlvbnM6IHRoaXMuc3Vic2NyaXB0aW9ucy5zaXplLFxuICAgIH0pO1xuICB9XG5cbiAgX21hdGNoZXNTdWJzY3JpcHRpb24ocGFyc2VPYmplY3Q6IGFueSwgc3Vic2NyaXB0aW9uOiBhbnkpOiBib29sZWFuIHtcbiAgICAvLyBPYmplY3QgaXMgdW5kZWZpbmVkIG9yIG51bGwsIG5vdCBtYXRjaFxuICAgIGlmICghcGFyc2VPYmplY3QpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoZXNRdWVyeShwYXJzZU9iamVjdCwgc3Vic2NyaXB0aW9uLnF1ZXJ5KTtcbiAgfVxuXG4gIGdldEF1dGhGb3JTZXNzaW9uVG9rZW4oc2Vzc2lvblRva2VuOiA/c3RyaW5nKTogUHJvbWlzZTx7IGF1dGg6ID9BdXRoLCB1c2VySWQ6ID9zdHJpbmcgfT4ge1xuICAgIGlmICghc2Vzc2lvblRva2VuKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgICB9XG4gICAgY29uc3QgZnJvbUNhY2hlID0gdGhpcy5hdXRoQ2FjaGUuZ2V0KHNlc3Npb25Ub2tlbik7XG4gICAgaWYgKGZyb21DYWNoZSkge1xuICAgICAgcmV0dXJuIGZyb21DYWNoZTtcbiAgICB9XG4gICAgY29uc3QgYXV0aFByb21pc2UgPSBnZXRBdXRoRm9yU2Vzc2lvblRva2VuKHtcbiAgICAgIGNhY2hlQ29udHJvbGxlcjogdGhpcy5jYWNoZUNvbnRyb2xsZXIsXG4gICAgICBzZXNzaW9uVG9rZW46IHNlc3Npb25Ub2tlbixcbiAgICB9KVxuICAgICAgLnRoZW4oYXV0aCA9PiB7XG4gICAgICAgIHJldHVybiB7IGF1dGgsIHVzZXJJZDogYXV0aCAmJiBhdXRoLnVzZXIgJiYgYXV0aC51c2VyLmlkIH07XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgLy8gVGhlcmUgd2FzIGFuIGVycm9yIHdpdGggdGhlIHNlc3Npb24gdG9rZW5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0ge307XG4gICAgICAgIGlmIChlcnJvciAmJiBlcnJvci5jb2RlID09PSBQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4pIHtcbiAgICAgICAgICByZXN1bHQuZXJyb3IgPSBlcnJvcjtcbiAgICAgICAgICB0aGlzLmF1dGhDYWNoZS5zZXQoc2Vzc2lvblRva2VuLCBQcm9taXNlLnJlc29sdmUocmVzdWx0KSwgdGhpcy5jb25maWcuY2FjaGVUaW1lb3V0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmF1dGhDYWNoZS5kZWwoc2Vzc2lvblRva2VuKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSk7XG4gICAgdGhpcy5hdXRoQ2FjaGUuc2V0KHNlc3Npb25Ub2tlbiwgYXV0aFByb21pc2UpO1xuICAgIHJldHVybiBhdXRoUHJvbWlzZTtcbiAgfVxuXG4gIGFzeW5jIF9tYXRjaGVzQ0xQKFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogP2FueSxcbiAgICBvYmplY3Q6IGFueSxcbiAgICBjbGllbnQ6IGFueSxcbiAgICByZXF1ZXN0SWQ6IG51bWJlcixcbiAgICBvcDogc3RyaW5nXG4gICk6IGFueSB7XG4gICAgLy8gdHJ5IHRvIG1hdGNoIG9uIHVzZXIgZmlyc3QsIGxlc3MgZXhwZW5zaXZlIHRoYW4gd2l0aCByb2xlc1xuICAgIGNvbnN0IHN1YnNjcmlwdGlvbkluZm8gPSBjbGllbnQuZ2V0U3Vic2NyaXB0aW9uSW5mbyhyZXF1ZXN0SWQpO1xuICAgIGNvbnN0IGFjbEdyb3VwID0gWycqJ107XG4gICAgbGV0IHVzZXJJZDtcbiAgICBpZiAodHlwZW9mIHN1YnNjcmlwdGlvbkluZm8gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBjb25zdCB7IHVzZXJJZCB9ID0gYXdhaXQgdGhpcy5nZXRBdXRoRm9yU2Vzc2lvblRva2VuKHN1YnNjcmlwdGlvbkluZm8uc2Vzc2lvblRva2VuKTtcbiAgICAgIGlmICh1c2VySWQpIHtcbiAgICAgICAgYWNsR3JvdXAucHVzaCh1c2VySWQpO1xuICAgICAgfVxuICAgIH1cbiAgICB0cnkge1xuICAgICAgYXdhaXQgU2NoZW1hQ29udHJvbGxlci52YWxpZGF0ZVBlcm1pc3Npb24oXG4gICAgICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgICAgb2JqZWN0LmNsYXNzTmFtZSxcbiAgICAgICAgYWNsR3JvdXAsXG4gICAgICAgIG9wXG4gICAgICApO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgbG9nZ2VyLnZlcmJvc2UoYEZhaWxlZCBtYXRjaGluZyBDTFAgZm9yICR7b2JqZWN0LmlkfSAke3VzZXJJZH0gJHtlfWApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICAvLyBUT0RPOiBoYW5kbGUgcm9sZXMgcGVybWlzc2lvbnNcbiAgICAvLyBPYmplY3Qua2V5cyhjbGFzc0xldmVsUGVybWlzc2lvbnMpLmZvckVhY2goKGtleSkgPT4ge1xuICAgIC8vICAgY29uc3QgcGVybSA9IGNsYXNzTGV2ZWxQZXJtaXNzaW9uc1trZXldO1xuICAgIC8vICAgT2JqZWN0LmtleXMocGVybSkuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgLy8gICAgIGlmIChrZXkuaW5kZXhPZigncm9sZScpKVxuICAgIC8vICAgfSk7XG4gICAgLy8gfSlcbiAgICAvLyAvLyBpdCdzIHJlamVjdGVkIGhlcmUsIGNoZWNrIHRoZSByb2xlc1xuICAgIC8vIHZhciByb2xlc1F1ZXJ5ID0gbmV3IFBhcnNlLlF1ZXJ5KFBhcnNlLlJvbGUpO1xuICAgIC8vIHJvbGVzUXVlcnkuZXF1YWxUbyhcInVzZXJzXCIsIHVzZXIpO1xuICAgIC8vIHJldHVybiByb2xlc1F1ZXJ5LmZpbmQoe3VzZU1hc3RlcktleTp0cnVlfSk7XG4gIH1cblxuICBfZ2V0Q0xQT3BlcmF0aW9uKHF1ZXJ5OiBhbnkpIHtcbiAgICByZXR1cm4gdHlwZW9mIHF1ZXJ5ID09PSAnb2JqZWN0JyAmJlxuICAgICAgT2JqZWN0LmtleXMocXVlcnkpLmxlbmd0aCA9PSAxICYmXG4gICAgICB0eXBlb2YgcXVlcnkub2JqZWN0SWQgPT09ICdzdHJpbmcnXG4gICAgICA/ICdnZXQnXG4gICAgICA6ICdmaW5kJztcbiAgfVxuXG4gIGFzeW5jIF92ZXJpZnlBQ0woYWNsOiBhbnksIHRva2VuOiBzdHJpbmcpIHtcbiAgICBpZiAoIXRva2VuKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgeyBhdXRoLCB1c2VySWQgfSA9IGF3YWl0IHRoaXMuZ2V0QXV0aEZvclNlc3Npb25Ub2tlbih0b2tlbik7XG5cbiAgICAvLyBHZXR0aW5nIHRoZSBzZXNzaW9uIHRva2VuIGZhaWxlZFxuICAgIC8vIFRoaXMgbWVhbnMgdGhhdCBubyBhZGRpdGlvbmFsIGF1dGggaXMgYXZhaWxhYmxlXG4gICAgLy8gQXQgdGhpcyBwb2ludCwganVzdCBiYWlsIG91dCBhcyBubyBhZGRpdGlvbmFsIHZpc2liaWxpdHkgY2FuIGJlIGluZmVycmVkLlxuICAgIGlmICghYXV0aCB8fCAhdXNlcklkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IGlzU3Vic2NyaXB0aW9uU2Vzc2lvblRva2VuTWF0Y2hlZCA9IGFjbC5nZXRSZWFkQWNjZXNzKHVzZXJJZCk7XG4gICAgaWYgKGlzU3Vic2NyaXB0aW9uU2Vzc2lvblRva2VuTWF0Y2hlZCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgdGhlIHVzZXIgaGFzIGFueSByb2xlcyB0aGF0IG1hdGNoIHRoZSBBQ0xcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgIC50aGVuKGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8gUmVzb2x2ZSBmYWxzZSByaWdodCBhd2F5IGlmIHRoZSBhY2wgZG9lc24ndCBoYXZlIGFueSByb2xlc1xuICAgICAgICBjb25zdCBhY2xfaGFzX3JvbGVzID0gT2JqZWN0LmtleXMoYWNsLnBlcm1pc3Npb25zQnlJZCkuc29tZShrZXkgPT4ga2V5LnN0YXJ0c1dpdGgoJ3JvbGU6JykpO1xuICAgICAgICBpZiAoIWFjbF9oYXNfcm9sZXMpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByb2xlTmFtZXMgPSBhd2FpdCBhdXRoLmdldFVzZXJSb2xlcygpO1xuICAgICAgICAvLyBGaW5hbGx5LCBzZWUgaWYgYW55IG9mIHRoZSB1c2VyJ3Mgcm9sZXMgYWxsb3cgdGhlbSByZWFkIGFjY2Vzc1xuICAgICAgICBmb3IgKGNvbnN0IHJvbGUgb2Ygcm9sZU5hbWVzKSB7XG4gICAgICAgICAgLy8gV2UgdXNlIGdldFJlYWRBY2Nlc3MgYXMgYHJvbGVgIGlzIGluIHRoZSBmb3JtIGByb2xlOnJvbGVOYW1lYFxuICAgICAgICAgIGlmIChhY2wuZ2V0UmVhZEFjY2Vzcyhyb2xlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKCkgPT4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIF9tYXRjaGVzQUNMKGFjbDogYW55LCBjbGllbnQ6IGFueSwgcmVxdWVzdElkOiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAvLyBSZXR1cm4gdHJ1ZSBkaXJlY3RseSBpZiBBQ0wgaXNuJ3QgcHJlc2VudCwgQUNMIGlzIHB1YmxpYyByZWFkLCBvciBjbGllbnQgaGFzIG1hc3RlciBrZXlcbiAgICBpZiAoIWFjbCB8fCBhY2wuZ2V0UHVibGljUmVhZEFjY2VzcygpIHx8IGNsaWVudC5oYXNNYXN0ZXJLZXkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvLyBDaGVjayBzdWJzY3JpcHRpb24gc2Vzc2lvblRva2VuIG1hdGNoZXMgQUNMIGZpcnN0XG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uSW5mbyA9IGNsaWVudC5nZXRTdWJzY3JpcHRpb25JbmZvKHJlcXVlc3RJZCk7XG4gICAgaWYgKHR5cGVvZiBzdWJzY3JpcHRpb25JbmZvID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IHN1YnNjcmlwdGlvblRva2VuID0gc3Vic2NyaXB0aW9uSW5mby5zZXNzaW9uVG9rZW47XG4gICAgY29uc3QgY2xpZW50U2Vzc2lvblRva2VuID0gY2xpZW50LnNlc3Npb25Ub2tlbjtcblxuICAgIGlmIChhd2FpdCB0aGlzLl92ZXJpZnlBQ0woYWNsLCBzdWJzY3JpcHRpb25Ub2tlbikpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChhd2FpdCB0aGlzLl92ZXJpZnlBQ0woYWNsLCBjbGllbnRTZXNzaW9uVG9rZW4pKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBhc3luYyBfaGFuZGxlQ29ubmVjdChwYXJzZVdlYnNvY2tldDogYW55LCByZXF1ZXN0OiBhbnkpOiBhbnkge1xuICAgIGlmICghdGhpcy5fdmFsaWRhdGVLZXlzKHJlcXVlc3QsIHRoaXMua2V5UGFpcnMpKSB7XG4gICAgICBDbGllbnQucHVzaEVycm9yKHBhcnNlV2Vic29ja2V0LCA0LCAnS2V5IGluIHJlcXVlc3QgaXMgbm90IHZhbGlkJyk7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0tleSBpbiByZXF1ZXN0IGlzIG5vdCB2YWxpZCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBoYXNNYXN0ZXJLZXkgPSB0aGlzLl9oYXNNYXN0ZXJLZXkocmVxdWVzdCwgdGhpcy5rZXlQYWlycyk7XG4gICAgY29uc3QgY2xpZW50SWQgPSB1dWlkdjQoKTtcbiAgICBjb25zdCBjbGllbnQgPSBuZXcgQ2xpZW50KFxuICAgICAgY2xpZW50SWQsXG4gICAgICBwYXJzZVdlYnNvY2tldCxcbiAgICAgIGhhc01hc3RlcktleSxcbiAgICAgIHJlcXVlc3Quc2Vzc2lvblRva2VuLFxuICAgICAgcmVxdWVzdC5pbnN0YWxsYXRpb25JZFxuICAgICk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcSA9IHtcbiAgICAgICAgY2xpZW50LFxuICAgICAgICBldmVudDogJ2Nvbm5lY3QnLFxuICAgICAgICBjbGllbnRzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgICAgIHNlc3Npb25Ub2tlbjogcmVxdWVzdC5zZXNzaW9uVG9rZW4sXG4gICAgICAgIHVzZU1hc3RlcktleTogY2xpZW50Lmhhc01hc3RlcktleSxcbiAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IHJlcXVlc3QuaW5zdGFsbGF0aW9uSWQsXG4gICAgICB9O1xuICAgICAgYXdhaXQgbWF5YmVSdW5Db25uZWN0VHJpZ2dlcignYmVmb3JlQ29ubmVjdCcsIHJlcSk7XG4gICAgICBwYXJzZVdlYnNvY2tldC5jbGllbnRJZCA9IGNsaWVudElkO1xuICAgICAgdGhpcy5jbGllbnRzLnNldChwYXJzZVdlYnNvY2tldC5jbGllbnRJZCwgY2xpZW50KTtcbiAgICAgIGxvZ2dlci5pbmZvKGBDcmVhdGUgbmV3IGNsaWVudDogJHtwYXJzZVdlYnNvY2tldC5jbGllbnRJZH1gKTtcbiAgICAgIGNsaWVudC5wdXNoQ29ubmVjdCgpO1xuICAgICAgcnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyhyZXEpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBDbGllbnQucHVzaEVycm9yKHBhcnNlV2Vic29ja2V0LCBlcnJvci5jb2RlIHx8IDE0MSwgZXJyb3IubWVzc2FnZSB8fCBlcnJvciwgZmFsc2UpO1xuICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICBgRmFpbGVkIHJ1bm5pbmcgYmVmb3JlQ29ubmVjdCBmb3Igc2Vzc2lvbiAke3JlcXVlc3Quc2Vzc2lvblRva2VufSB3aXRoOlxcbiBFcnJvcjogYCArXG4gICAgICAgICAgSlNPTi5zdHJpbmdpZnkoZXJyb3IpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIF9oYXNNYXN0ZXJLZXkocmVxdWVzdDogYW55LCB2YWxpZEtleVBhaXJzOiBhbnkpOiBib29sZWFuIHtcbiAgICBpZiAoIXZhbGlkS2V5UGFpcnMgfHwgdmFsaWRLZXlQYWlycy5zaXplID09IDAgfHwgIXZhbGlkS2V5UGFpcnMuaGFzKCdtYXN0ZXJLZXknKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIXJlcXVlc3QgfHwgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChyZXF1ZXN0LCAnbWFzdGVyS2V5JykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcXVlc3QubWFzdGVyS2V5ID09PSB2YWxpZEtleVBhaXJzLmdldCgnbWFzdGVyS2V5Jyk7XG4gIH1cblxuICBfdmFsaWRhdGVLZXlzKHJlcXVlc3Q6IGFueSwgdmFsaWRLZXlQYWlyczogYW55KTogYm9vbGVhbiB7XG4gICAgaWYgKCF2YWxpZEtleVBhaXJzIHx8IHZhbGlkS2V5UGFpcnMuc2l6ZSA9PSAwKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgbGV0IGlzVmFsaWQgPSBmYWxzZTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHNlY3JldF0gb2YgdmFsaWRLZXlQYWlycykge1xuICAgICAgaWYgKCFyZXF1ZXN0W2tleV0gfHwgcmVxdWVzdFtrZXldICE9PSBzZWNyZXQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpc1ZhbGlkID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gaXNWYWxpZDtcbiAgfVxuXG4gIGFzeW5jIF9oYW5kbGVTdWJzY3JpYmUocGFyc2VXZWJzb2NrZXQ6IGFueSwgcmVxdWVzdDogYW55KTogYW55IHtcbiAgICAvLyBJZiB3ZSBjYW4gbm90IGZpbmQgdGhpcyBjbGllbnQsIHJldHVybiBlcnJvciB0byBjbGllbnRcbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChwYXJzZVdlYnNvY2tldCwgJ2NsaWVudElkJykpIHtcbiAgICAgIENsaWVudC5wdXNoRXJyb3IoXG4gICAgICAgIHBhcnNlV2Vic29ja2V0LFxuICAgICAgICAyLFxuICAgICAgICAnQ2FuIG5vdCBmaW5kIHRoaXMgY2xpZW50LCBtYWtlIHN1cmUgeW91IGNvbm5lY3QgdG8gc2VydmVyIGJlZm9yZSBzdWJzY3JpYmluZydcbiAgICAgICk7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0NhbiBub3QgZmluZCB0aGlzIGNsaWVudCwgbWFrZSBzdXJlIHlvdSBjb25uZWN0IHRvIHNlcnZlciBiZWZvcmUgc3Vic2NyaWJpbmcnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRzLmdldChwYXJzZVdlYnNvY2tldC5jbGllbnRJZCk7XG4gICAgY29uc3QgY2xhc3NOYW1lID0gcmVxdWVzdC5xdWVyeS5jbGFzc05hbWU7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IG1heWJlUnVuU3Vic2NyaWJlVHJpZ2dlcignYmVmb3JlU3Vic2NyaWJlJywgY2xhc3NOYW1lLCByZXF1ZXN0KTtcblxuICAgICAgLy8gR2V0IHN1YnNjcmlwdGlvbiBmcm9tIHN1YnNjcmlwdGlvbnMsIGNyZWF0ZSBvbmUgaWYgbmVjZXNzYXJ5XG4gICAgICBjb25zdCBzdWJzY3JpcHRpb25IYXNoID0gcXVlcnlIYXNoKHJlcXVlc3QucXVlcnkpO1xuICAgICAgLy8gQWRkIGNsYXNzTmFtZSB0byBzdWJzY3JpcHRpb25zIGlmIG5lY2Vzc2FyeVxuXG4gICAgICBpZiAoIXRoaXMuc3Vic2NyaXB0aW9ucy5oYXMoY2xhc3NOYW1lKSkge1xuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuc2V0KGNsYXNzTmFtZSwgbmV3IE1hcCgpKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNsYXNzU3Vic2NyaXB0aW9ucyA9IHRoaXMuc3Vic2NyaXB0aW9ucy5nZXQoY2xhc3NOYW1lKTtcbiAgICAgIGxldCBzdWJzY3JpcHRpb247XG4gICAgICBpZiAoY2xhc3NTdWJzY3JpcHRpb25zLmhhcyhzdWJzY3JpcHRpb25IYXNoKSkge1xuICAgICAgICBzdWJzY3JpcHRpb24gPSBjbGFzc1N1YnNjcmlwdGlvbnMuZ2V0KHN1YnNjcmlwdGlvbkhhc2gpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbihjbGFzc05hbWUsIHJlcXVlc3QucXVlcnkud2hlcmUsIHN1YnNjcmlwdGlvbkhhc2gpO1xuICAgICAgICBjbGFzc1N1YnNjcmlwdGlvbnMuc2V0KHN1YnNjcmlwdGlvbkhhc2gsIHN1YnNjcmlwdGlvbik7XG4gICAgICB9XG5cbiAgICAgIC8vIEFkZCBzdWJzY3JpcHRpb25JbmZvIHRvIGNsaWVudFxuICAgICAgY29uc3Qgc3Vic2NyaXB0aW9uSW5mbyA9IHtcbiAgICAgICAgc3Vic2NyaXB0aW9uOiBzdWJzY3JpcHRpb24sXG4gICAgICB9O1xuICAgICAgLy8gQWRkIHNlbGVjdGVkIGZpZWxkcywgc2Vzc2lvblRva2VuIGFuZCBpbnN0YWxsYXRpb25JZCBmb3IgdGhpcyBzdWJzY3JpcHRpb24gaWYgbmVjZXNzYXJ5XG4gICAgICBpZiAocmVxdWVzdC5xdWVyeS5maWVsZHMpIHtcbiAgICAgICAgc3Vic2NyaXB0aW9uSW5mby5maWVsZHMgPSByZXF1ZXN0LnF1ZXJ5LmZpZWxkcztcbiAgICAgIH1cbiAgICAgIGlmIChyZXF1ZXN0LnNlc3Npb25Ub2tlbikge1xuICAgICAgICBzdWJzY3JpcHRpb25JbmZvLnNlc3Npb25Ub2tlbiA9IHJlcXVlc3Quc2Vzc2lvblRva2VuO1xuICAgICAgfVxuICAgICAgY2xpZW50LmFkZFN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdC5yZXF1ZXN0SWQsIHN1YnNjcmlwdGlvbkluZm8pO1xuXG4gICAgICAvLyBBZGQgY2xpZW50SWQgdG8gc3Vic2NyaXB0aW9uXG4gICAgICBzdWJzY3JpcHRpb24uYWRkQ2xpZW50U3Vic2NyaXB0aW9uKHBhcnNlV2Vic29ja2V0LmNsaWVudElkLCByZXF1ZXN0LnJlcXVlc3RJZCk7XG5cbiAgICAgIGNsaWVudC5wdXNoU3Vic2NyaWJlKHJlcXVlc3QucmVxdWVzdElkKTtcblxuICAgICAgbG9nZ2VyLnZlcmJvc2UoXG4gICAgICAgIGBDcmVhdGUgY2xpZW50ICR7cGFyc2VXZWJzb2NrZXQuY2xpZW50SWR9IG5ldyBzdWJzY3JpcHRpb246ICR7cmVxdWVzdC5yZXF1ZXN0SWR9YFxuICAgICAgKTtcbiAgICAgIGxvZ2dlci52ZXJib3NlKCdDdXJyZW50IGNsaWVudCBudW1iZXI6ICVkJywgdGhpcy5jbGllbnRzLnNpemUpO1xuICAgICAgcnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyh7XG4gICAgICAgIGNsaWVudCxcbiAgICAgICAgZXZlbnQ6ICdzdWJzY3JpYmUnLFxuICAgICAgICBjbGllbnRzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgICAgIHNlc3Npb25Ub2tlbjogcmVxdWVzdC5zZXNzaW9uVG9rZW4sXG4gICAgICAgIHVzZU1hc3RlcktleTogY2xpZW50Lmhhc01hc3RlcktleSxcbiAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IGNsaWVudC5pbnN0YWxsYXRpb25JZCxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIENsaWVudC5wdXNoRXJyb3IocGFyc2VXZWJzb2NrZXQsIGUuY29kZSB8fCAxNDEsIGUubWVzc2FnZSB8fCBlLCBmYWxzZSwgcmVxdWVzdC5yZXF1ZXN0SWQpO1xuICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICBgRmFpbGVkIHJ1bm5pbmcgYmVmb3JlU3Vic2NyaWJlIG9uICR7Y2xhc3NOYW1lfSBmb3Igc2Vzc2lvbiAke3JlcXVlc3Quc2Vzc2lvblRva2VufSB3aXRoOlxcbiBFcnJvcjogYCArXG4gICAgICAgICAgSlNPTi5zdHJpbmdpZnkoZSlcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgX2hhbmRsZVVwZGF0ZVN1YnNjcmlwdGlvbihwYXJzZVdlYnNvY2tldDogYW55LCByZXF1ZXN0OiBhbnkpOiBhbnkge1xuICAgIHRoaXMuX2hhbmRsZVVuc3Vic2NyaWJlKHBhcnNlV2Vic29ja2V0LCByZXF1ZXN0LCBmYWxzZSk7XG4gICAgdGhpcy5faGFuZGxlU3Vic2NyaWJlKHBhcnNlV2Vic29ja2V0LCByZXF1ZXN0KTtcbiAgfVxuXG4gIF9oYW5kbGVVbnN1YnNjcmliZShwYXJzZVdlYnNvY2tldDogYW55LCByZXF1ZXN0OiBhbnksIG5vdGlmeUNsaWVudDogYm9vbGVhbiA9IHRydWUpOiBhbnkge1xuICAgIC8vIElmIHdlIGNhbiBub3QgZmluZCB0aGlzIGNsaWVudCwgcmV0dXJuIGVycm9yIHRvIGNsaWVudFxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHBhcnNlV2Vic29ja2V0LCAnY2xpZW50SWQnKSkge1xuICAgICAgQ2xpZW50LnB1c2hFcnJvcihcbiAgICAgICAgcGFyc2VXZWJzb2NrZXQsXG4gICAgICAgIDIsXG4gICAgICAgICdDYW4gbm90IGZpbmQgdGhpcyBjbGllbnQsIG1ha2Ugc3VyZSB5b3UgY29ubmVjdCB0byBzZXJ2ZXIgYmVmb3JlIHVuc3Vic2NyaWJpbmcnXG4gICAgICApO1xuICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAnQ2FuIG5vdCBmaW5kIHRoaXMgY2xpZW50LCBtYWtlIHN1cmUgeW91IGNvbm5lY3QgdG8gc2VydmVyIGJlZm9yZSB1bnN1YnNjcmliaW5nJ1xuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcmVxdWVzdElkID0gcmVxdWVzdC5yZXF1ZXN0SWQ7XG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRzLmdldChwYXJzZVdlYnNvY2tldC5jbGllbnRJZCk7XG4gICAgaWYgKHR5cGVvZiBjbGllbnQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBDbGllbnQucHVzaEVycm9yKFxuICAgICAgICBwYXJzZVdlYnNvY2tldCxcbiAgICAgICAgMixcbiAgICAgICAgJ0Nhbm5vdCBmaW5kIGNsaWVudCB3aXRoIGNsaWVudElkICcgK1xuICAgICAgICAgIHBhcnNlV2Vic29ja2V0LmNsaWVudElkICtcbiAgICAgICAgICAnLiBNYWtlIHN1cmUgeW91IGNvbm5lY3QgdG8gbGl2ZSBxdWVyeSBzZXJ2ZXIgYmVmb3JlIHVuc3Vic2NyaWJpbmcuJ1xuICAgICAgKTtcbiAgICAgIGxvZ2dlci5lcnJvcignQ2FuIG5vdCBmaW5kIHRoaXMgY2xpZW50ICcgKyBwYXJzZVdlYnNvY2tldC5jbGllbnRJZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uSW5mbyA9IGNsaWVudC5nZXRTdWJzY3JpcHRpb25JbmZvKHJlcXVlc3RJZCk7XG4gICAgaWYgKHR5cGVvZiBzdWJzY3JpcHRpb25JbmZvID09PSAndW5kZWZpbmVkJykge1xuICAgICAgQ2xpZW50LnB1c2hFcnJvcihcbiAgICAgICAgcGFyc2VXZWJzb2NrZXQsXG4gICAgICAgIDIsXG4gICAgICAgICdDYW5ub3QgZmluZCBzdWJzY3JpcHRpb24gd2l0aCBjbGllbnRJZCAnICtcbiAgICAgICAgICBwYXJzZVdlYnNvY2tldC5jbGllbnRJZCArXG4gICAgICAgICAgJyBzdWJzY3JpcHRpb25JZCAnICtcbiAgICAgICAgICByZXF1ZXN0SWQgK1xuICAgICAgICAgICcuIE1ha2Ugc3VyZSB5b3Ugc3Vic2NyaWJlIHRvIGxpdmUgcXVlcnkgc2VydmVyIGJlZm9yZSB1bnN1YnNjcmliaW5nLidcbiAgICAgICk7XG4gICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICdDYW4gbm90IGZpbmQgc3Vic2NyaXB0aW9uIHdpdGggY2xpZW50SWQgJyArXG4gICAgICAgICAgcGFyc2VXZWJzb2NrZXQuY2xpZW50SWQgK1xuICAgICAgICAgICcgc3Vic2NyaXB0aW9uSWQgJyArXG4gICAgICAgICAgcmVxdWVzdElkXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFJlbW92ZSBzdWJzY3JpcHRpb24gZnJvbSBjbGllbnRcbiAgICBjbGllbnQuZGVsZXRlU3Vic2NyaXB0aW9uSW5mbyhyZXF1ZXN0SWQpO1xuICAgIC8vIFJlbW92ZSBjbGllbnQgZnJvbSBzdWJzY3JpcHRpb25cbiAgICBjb25zdCBzdWJzY3JpcHRpb24gPSBzdWJzY3JpcHRpb25JbmZvLnN1YnNjcmlwdGlvbjtcbiAgICBjb25zdCBjbGFzc05hbWUgPSBzdWJzY3JpcHRpb24uY2xhc3NOYW1lO1xuICAgIHN1YnNjcmlwdGlvbi5kZWxldGVDbGllbnRTdWJzY3JpcHRpb24ocGFyc2VXZWJzb2NrZXQuY2xpZW50SWQsIHJlcXVlc3RJZCk7XG4gICAgLy8gSWYgdGhlcmUgaXMgbm8gY2xpZW50IHdoaWNoIGlzIHN1YnNjcmliaW5nIHRoaXMgc3Vic2NyaXB0aW9uLCByZW1vdmUgaXQgZnJvbSBzdWJzY3JpcHRpb25zXG4gICAgY29uc3QgY2xhc3NTdWJzY3JpcHRpb25zID0gdGhpcy5zdWJzY3JpcHRpb25zLmdldChjbGFzc05hbWUpO1xuICAgIGlmICghc3Vic2NyaXB0aW9uLmhhc1N1YnNjcmliaW5nQ2xpZW50KCkpIHtcbiAgICAgIGNsYXNzU3Vic2NyaXB0aW9ucy5kZWxldGUoc3Vic2NyaXB0aW9uLmhhc2gpO1xuICAgIH1cbiAgICAvLyBJZiB0aGVyZSBpcyBubyBzdWJzY3JpcHRpb25zIHVuZGVyIHRoaXMgY2xhc3MsIHJlbW92ZSBpdCBmcm9tIHN1YnNjcmlwdGlvbnNcbiAgICBpZiAoY2xhc3NTdWJzY3JpcHRpb25zLnNpemUgPT09IDApIHtcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5kZWxldGUoY2xhc3NOYW1lKTtcbiAgICB9XG4gICAgcnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyh7XG4gICAgICBjbGllbnQsXG4gICAgICBldmVudDogJ3Vuc3Vic2NyaWJlJyxcbiAgICAgIGNsaWVudHM6IHRoaXMuY2xpZW50cy5zaXplLFxuICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgICBzZXNzaW9uVG9rZW46IHN1YnNjcmlwdGlvbkluZm8uc2Vzc2lvblRva2VuLFxuICAgICAgdXNlTWFzdGVyS2V5OiBjbGllbnQuaGFzTWFzdGVyS2V5LFxuICAgICAgaW5zdGFsbGF0aW9uSWQ6IGNsaWVudC5pbnN0YWxsYXRpb25JZCxcbiAgICB9KTtcblxuICAgIGlmICghbm90aWZ5Q2xpZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY2xpZW50LnB1c2hVbnN1YnNjcmliZShyZXF1ZXN0LnJlcXVlc3RJZCk7XG5cbiAgICBsb2dnZXIudmVyYm9zZShcbiAgICAgIGBEZWxldGUgY2xpZW50OiAke3BhcnNlV2Vic29ja2V0LmNsaWVudElkfSB8IHN1YnNjcmlwdGlvbjogJHtyZXF1ZXN0LnJlcXVlc3RJZH1gXG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgeyBQYXJzZUxpdmVRdWVyeVNlcnZlciB9O1xuIl19 \ No newline at end of file diff --git a/lib/LiveQuery/ParsePubSub.js b/lib/LiveQuery/ParsePubSub.js new file mode 100644 index 0000000000..87f2438cff --- /dev/null +++ b/lib/LiveQuery/ParsePubSub.js @@ -0,0 +1,49 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ParsePubSub = void 0; + +var _AdapterLoader = require("../Adapters/AdapterLoader"); + +var _EventEmitterPubSub = require("../Adapters/PubSub/EventEmitterPubSub"); + +var _RedisPubSub = require("../Adapters/PubSub/RedisPubSub"); + +const ParsePubSub = {}; +exports.ParsePubSub = ParsePubSub; + +function useRedis(config) { + const redisURL = config.redisURL; + return typeof redisURL !== 'undefined' && redisURL !== ''; +} + +ParsePubSub.createPublisher = function (config) { + if (useRedis(config)) { + return _RedisPubSub.RedisPubSub.createPublisher(config); + } else { + const adapter = (0, _AdapterLoader.loadAdapter)(config.pubSubAdapter, _EventEmitterPubSub.EventEmitterPubSub, config); + + if (typeof adapter.createPublisher !== 'function') { + throw 'pubSubAdapter should have createPublisher()'; + } + + return adapter.createPublisher(config); + } +}; + +ParsePubSub.createSubscriber = function (config) { + if (useRedis(config)) { + return _RedisPubSub.RedisPubSub.createSubscriber(config); + } else { + const adapter = (0, _AdapterLoader.loadAdapter)(config.pubSubAdapter, _EventEmitterPubSub.EventEmitterPubSub, config); + + if (typeof adapter.createSubscriber !== 'function') { + throw 'pubSubAdapter should have createSubscriber()'; + } + + return adapter.createSubscriber(config); + } +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUGFyc2VQdWJTdWIuanMiXSwibmFtZXMiOlsiUGFyc2VQdWJTdWIiLCJ1c2VSZWRpcyIsImNvbmZpZyIsInJlZGlzVVJMIiwiY3JlYXRlUHVibGlzaGVyIiwiUmVkaXNQdWJTdWIiLCJhZGFwdGVyIiwicHViU3ViQWRhcHRlciIsIkV2ZW50RW1pdHRlclB1YlN1YiIsImNyZWF0ZVN1YnNjcmliZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFFQTs7QUFFQSxNQUFNQSxXQUFXLEdBQUcsRUFBcEI7OztBQUVBLFNBQVNDLFFBQVQsQ0FBa0JDLE1BQWxCLEVBQXdDO0FBQ3RDLFFBQU1DLFFBQVEsR0FBR0QsTUFBTSxDQUFDQyxRQUF4QjtBQUNBLFNBQU8sT0FBT0EsUUFBUCxLQUFvQixXQUFwQixJQUFtQ0EsUUFBUSxLQUFLLEVBQXZEO0FBQ0Q7O0FBRURILFdBQVcsQ0FBQ0ksZUFBWixHQUE4QixVQUFVRixNQUFWLEVBQTRCO0FBQ3hELE1BQUlELFFBQVEsQ0FBQ0MsTUFBRCxDQUFaLEVBQXNCO0FBQ3BCLFdBQU9HLHlCQUFZRCxlQUFaLENBQTRCRixNQUE1QixDQUFQO0FBQ0QsR0FGRCxNQUVPO0FBQ0wsVUFBTUksT0FBTyxHQUFHLGdDQUFZSixNQUFNLENBQUNLLGFBQW5CLEVBQWtDQyxzQ0FBbEMsRUFBc0ROLE1BQXRELENBQWhCOztBQUNBLFFBQUksT0FBT0ksT0FBTyxDQUFDRixlQUFmLEtBQW1DLFVBQXZDLEVBQW1EO0FBQ2pELFlBQU0sNkNBQU47QUFDRDs7QUFDRCxXQUFPRSxPQUFPLENBQUNGLGVBQVIsQ0FBd0JGLE1BQXhCLENBQVA7QUFDRDtBQUNGLENBVkQ7O0FBWUFGLFdBQVcsQ0FBQ1MsZ0JBQVosR0FBK0IsVUFBVVAsTUFBVixFQUE2QjtBQUMxRCxNQUFJRCxRQUFRLENBQUNDLE1BQUQsQ0FBWixFQUFzQjtBQUNwQixXQUFPRyx5QkFBWUksZ0JBQVosQ0FBNkJQLE1BQTdCLENBQVA7QUFDRCxHQUZELE1BRU87QUFDTCxVQUFNSSxPQUFPLEdBQUcsZ0NBQVlKLE1BQU0sQ0FBQ0ssYUFBbkIsRUFBa0NDLHNDQUFsQyxFQUFzRE4sTUFBdEQsQ0FBaEI7O0FBQ0EsUUFBSSxPQUFPSSxPQUFPLENBQUNHLGdCQUFmLEtBQW9DLFVBQXhDLEVBQW9EO0FBQ2xELFlBQU0sOENBQU47QUFDRDs7QUFDRCxXQUFPSCxPQUFPLENBQUNHLGdCQUFSLENBQXlCUCxNQUF6QixDQUFQO0FBQ0Q7QUFDRixDQVZEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbG9hZEFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9BZGFwdGVyTG9hZGVyJztcbmltcG9ydCB7IEV2ZW50RW1pdHRlclB1YlN1YiB9IGZyb20gJy4uL0FkYXB0ZXJzL1B1YlN1Yi9FdmVudEVtaXR0ZXJQdWJTdWInO1xuXG5pbXBvcnQgeyBSZWRpc1B1YlN1YiB9IGZyb20gJy4uL0FkYXB0ZXJzL1B1YlN1Yi9SZWRpc1B1YlN1Yic7XG5cbmNvbnN0IFBhcnNlUHViU3ViID0ge307XG5cbmZ1bmN0aW9uIHVzZVJlZGlzKGNvbmZpZzogYW55KTogYm9vbGVhbiB7XG4gIGNvbnN0IHJlZGlzVVJMID0gY29uZmlnLnJlZGlzVVJMO1xuICByZXR1cm4gdHlwZW9mIHJlZGlzVVJMICE9PSAndW5kZWZpbmVkJyAmJiByZWRpc1VSTCAhPT0gJyc7XG59XG5cblBhcnNlUHViU3ViLmNyZWF0ZVB1Ymxpc2hlciA9IGZ1bmN0aW9uIChjb25maWc6IGFueSk6IGFueSB7XG4gIGlmICh1c2VSZWRpcyhjb25maWcpKSB7XG4gICAgcmV0dXJuIFJlZGlzUHViU3ViLmNyZWF0ZVB1Ymxpc2hlcihjb25maWcpO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGFkYXB0ZXIgPSBsb2FkQWRhcHRlcihjb25maWcucHViU3ViQWRhcHRlciwgRXZlbnRFbWl0dGVyUHViU3ViLCBjb25maWcpO1xuICAgIGlmICh0eXBlb2YgYWRhcHRlci5jcmVhdGVQdWJsaXNoZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRocm93ICdwdWJTdWJBZGFwdGVyIHNob3VsZCBoYXZlIGNyZWF0ZVB1Ymxpc2hlcigpJztcbiAgICB9XG4gICAgcmV0dXJuIGFkYXB0ZXIuY3JlYXRlUHVibGlzaGVyKGNvbmZpZyk7XG4gIH1cbn07XG5cblBhcnNlUHViU3ViLmNyZWF0ZVN1YnNjcmliZXIgPSBmdW5jdGlvbiAoY29uZmlnOiBhbnkpOiB2b2lkIHtcbiAgaWYgKHVzZVJlZGlzKGNvbmZpZykpIHtcbiAgICByZXR1cm4gUmVkaXNQdWJTdWIuY3JlYXRlU3Vic2NyaWJlcihjb25maWcpO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGFkYXB0ZXIgPSBsb2FkQWRhcHRlcihjb25maWcucHViU3ViQWRhcHRlciwgRXZlbnRFbWl0dGVyUHViU3ViLCBjb25maWcpO1xuICAgIGlmICh0eXBlb2YgYWRhcHRlci5jcmVhdGVTdWJzY3JpYmVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyAncHViU3ViQWRhcHRlciBzaG91bGQgaGF2ZSBjcmVhdGVTdWJzY3JpYmVyKCknO1xuICAgIH1cbiAgICByZXR1cm4gYWRhcHRlci5jcmVhdGVTdWJzY3JpYmVyKGNvbmZpZyk7XG4gIH1cbn07XG5cbmV4cG9ydCB7IFBhcnNlUHViU3ViIH07XG4iXX0= \ No newline at end of file diff --git a/lib/LiveQuery/ParseWebSocketServer.js b/lib/LiveQuery/ParseWebSocketServer.js new file mode 100644 index 0000000000..b7ab9d6099 --- /dev/null +++ b/lib/LiveQuery/ParseWebSocketServer.js @@ -0,0 +1,80 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ParseWebSocket = exports.ParseWebSocketServer = void 0; + +var _AdapterLoader = require("../Adapters/AdapterLoader"); + +var _WSAdapter = require("../Adapters/WebSocketServer/WSAdapter"); + +var _logger = _interopRequireDefault(require("../logger")); + +var _events = _interopRequireDefault(require("events")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class ParseWebSocketServer { + constructor(server, onConnect, config) { + config.server = server; + const wss = (0, _AdapterLoader.loadAdapter)(config.wssAdapter, _WSAdapter.WSAdapter, config); + + wss.onListen = () => { + _logger.default.info('Parse LiveQuery Server starts running'); + }; + + wss.onConnection = ws => { + ws.on('error', error => { + _logger.default.error(error.message); + + _logger.default.error(JSON.stringify(ws)); + }); + onConnect(new ParseWebSocket(ws)); // Send ping to client periodically + + const pingIntervalId = setInterval(() => { + if (ws.readyState == ws.OPEN) { + ws.ping(); + } else { + clearInterval(pingIntervalId); + } + }, config.websocketTimeout || 10 * 1000); + }; + + wss.onError = error => { + _logger.default.error(error); + }; + + wss.start(); + this.server = wss; + } + + close() { + if (this.server && this.server.close) { + this.server.close(); + } + } + +} + +exports.ParseWebSocketServer = ParseWebSocketServer; + +class ParseWebSocket extends _events.default.EventEmitter { + constructor(ws) { + super(); + + ws.onmessage = request => this.emit('message', request && request.data ? request.data : request); + + ws.onclose = () => this.emit('disconnect'); + + this.ws = ws; + } + + send(message) { + this.ws.send(message); + } + +} + +exports.ParseWebSocket = ParseWebSocket; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUGFyc2VXZWJTb2NrZXRTZXJ2ZXIuanMiXSwibmFtZXMiOlsiUGFyc2VXZWJTb2NrZXRTZXJ2ZXIiLCJjb25zdHJ1Y3RvciIsInNlcnZlciIsIm9uQ29ubmVjdCIsImNvbmZpZyIsIndzcyIsIndzc0FkYXB0ZXIiLCJXU0FkYXB0ZXIiLCJvbkxpc3RlbiIsImxvZ2dlciIsImluZm8iLCJvbkNvbm5lY3Rpb24iLCJ3cyIsIm9uIiwiZXJyb3IiLCJtZXNzYWdlIiwiSlNPTiIsInN0cmluZ2lmeSIsIlBhcnNlV2ViU29ja2V0IiwicGluZ0ludGVydmFsSWQiLCJzZXRJbnRlcnZhbCIsInJlYWR5U3RhdGUiLCJPUEVOIiwicGluZyIsImNsZWFySW50ZXJ2YWwiLCJ3ZWJzb2NrZXRUaW1lb3V0Iiwib25FcnJvciIsInN0YXJ0IiwiY2xvc2UiLCJldmVudHMiLCJFdmVudEVtaXR0ZXIiLCJvbm1lc3NhZ2UiLCJyZXF1ZXN0IiwiZW1pdCIsImRhdGEiLCJvbmNsb3NlIiwic2VuZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRU8sTUFBTUEsb0JBQU4sQ0FBMkI7QUFHaENDLEVBQUFBLFdBQVcsQ0FBQ0MsTUFBRCxFQUFjQyxTQUFkLEVBQW1DQyxNQUFuQyxFQUEyQztBQUNwREEsSUFBQUEsTUFBTSxDQUFDRixNQUFQLEdBQWdCQSxNQUFoQjtBQUNBLFVBQU1HLEdBQUcsR0FBRyxnQ0FBWUQsTUFBTSxDQUFDRSxVQUFuQixFQUErQkMsb0JBQS9CLEVBQTBDSCxNQUExQyxDQUFaOztBQUNBQyxJQUFBQSxHQUFHLENBQUNHLFFBQUosR0FBZSxNQUFNO0FBQ25CQyxzQkFBT0MsSUFBUCxDQUFZLHVDQUFaO0FBQ0QsS0FGRDs7QUFHQUwsSUFBQUEsR0FBRyxDQUFDTSxZQUFKLEdBQW1CQyxFQUFFLElBQUk7QUFDdkJBLE1BQUFBLEVBQUUsQ0FBQ0MsRUFBSCxDQUFNLE9BQU4sRUFBZUMsS0FBSyxJQUFJO0FBQ3RCTCx3QkFBT0ssS0FBUCxDQUFhQSxLQUFLLENBQUNDLE9BQW5COztBQUNBTix3QkFBT0ssS0FBUCxDQUFhRSxJQUFJLENBQUNDLFNBQUwsQ0FBZUwsRUFBZixDQUFiO0FBQ0QsT0FIRDtBQUlBVCxNQUFBQSxTQUFTLENBQUMsSUFBSWUsY0FBSixDQUFtQk4sRUFBbkIsQ0FBRCxDQUFULENBTHVCLENBTXZCOztBQUNBLFlBQU1PLGNBQWMsR0FBR0MsV0FBVyxDQUFDLE1BQU07QUFDdkMsWUFBSVIsRUFBRSxDQUFDUyxVQUFILElBQWlCVCxFQUFFLENBQUNVLElBQXhCLEVBQThCO0FBQzVCVixVQUFBQSxFQUFFLENBQUNXLElBQUg7QUFDRCxTQUZELE1BRU87QUFDTEMsVUFBQUEsYUFBYSxDQUFDTCxjQUFELENBQWI7QUFDRDtBQUNGLE9BTmlDLEVBTS9CZixNQUFNLENBQUNxQixnQkFBUCxJQUEyQixLQUFLLElBTkQsQ0FBbEM7QUFPRCxLQWREOztBQWVBcEIsSUFBQUEsR0FBRyxDQUFDcUIsT0FBSixHQUFjWixLQUFLLElBQUk7QUFDckJMLHNCQUFPSyxLQUFQLENBQWFBLEtBQWI7QUFDRCxLQUZEOztBQUdBVCxJQUFBQSxHQUFHLENBQUNzQixLQUFKO0FBQ0EsU0FBS3pCLE1BQUwsR0FBY0csR0FBZDtBQUNEOztBQUVEdUIsRUFBQUEsS0FBSyxHQUFHO0FBQ04sUUFBSSxLQUFLMUIsTUFBTCxJQUFlLEtBQUtBLE1BQUwsQ0FBWTBCLEtBQS9CLEVBQXNDO0FBQ3BDLFdBQUsxQixNQUFMLENBQVkwQixLQUFaO0FBQ0Q7QUFDRjs7QUFuQytCOzs7O0FBc0MzQixNQUFNVixjQUFOLFNBQTZCVyxnQkFBT0MsWUFBcEMsQ0FBaUQ7QUFHdEQ3QixFQUFBQSxXQUFXLENBQUNXLEVBQUQsRUFBVTtBQUNuQjs7QUFDQUEsSUFBQUEsRUFBRSxDQUFDbUIsU0FBSCxHQUFlQyxPQUFPLElBQ3BCLEtBQUtDLElBQUwsQ0FBVSxTQUFWLEVBQXFCRCxPQUFPLElBQUlBLE9BQU8sQ0FBQ0UsSUFBbkIsR0FBMEJGLE9BQU8sQ0FBQ0UsSUFBbEMsR0FBeUNGLE9BQTlELENBREY7O0FBRUFwQixJQUFBQSxFQUFFLENBQUN1QixPQUFILEdBQWEsTUFBTSxLQUFLRixJQUFMLENBQVUsWUFBVixDQUFuQjs7QUFDQSxTQUFLckIsRUFBTCxHQUFVQSxFQUFWO0FBQ0Q7O0FBRUR3QixFQUFBQSxJQUFJLENBQUNyQixPQUFELEVBQXFCO0FBQ3ZCLFNBQUtILEVBQUwsQ0FBUXdCLElBQVIsQ0FBYXJCLE9BQWI7QUFDRDs7QUFicUQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBsb2FkQWRhcHRlciB9IGZyb20gJy4uL0FkYXB0ZXJzL0FkYXB0ZXJMb2FkZXInO1xuaW1wb3J0IHsgV1NBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvV2ViU29ja2V0U2VydmVyL1dTQWRhcHRlcic7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5pbXBvcnQgZXZlbnRzIGZyb20gJ2V2ZW50cyc7XG5cbmV4cG9ydCBjbGFzcyBQYXJzZVdlYlNvY2tldFNlcnZlciB7XG4gIHNlcnZlcjogT2JqZWN0O1xuXG4gIGNvbnN0cnVjdG9yKHNlcnZlcjogYW55LCBvbkNvbm5lY3Q6IEZ1bmN0aW9uLCBjb25maWcpIHtcbiAgICBjb25maWcuc2VydmVyID0gc2VydmVyO1xuICAgIGNvbnN0IHdzcyA9IGxvYWRBZGFwdGVyKGNvbmZpZy53c3NBZGFwdGVyLCBXU0FkYXB0ZXIsIGNvbmZpZyk7XG4gICAgd3NzLm9uTGlzdGVuID0gKCkgPT4ge1xuICAgICAgbG9nZ2VyLmluZm8oJ1BhcnNlIExpdmVRdWVyeSBTZXJ2ZXIgc3RhcnRzIHJ1bm5pbmcnKTtcbiAgICB9O1xuICAgIHdzcy5vbkNvbm5lY3Rpb24gPSB3cyA9PiB7XG4gICAgICB3cy5vbignZXJyb3InLCBlcnJvciA9PiB7XG4gICAgICAgIGxvZ2dlci5lcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgICAgbG9nZ2VyLmVycm9yKEpTT04uc3RyaW5naWZ5KHdzKSk7XG4gICAgICB9KTtcbiAgICAgIG9uQ29ubmVjdChuZXcgUGFyc2VXZWJTb2NrZXQod3MpKTtcbiAgICAgIC8vIFNlbmQgcGluZyB0byBjbGllbnQgcGVyaW9kaWNhbGx5XG4gICAgICBjb25zdCBwaW5nSW50ZXJ2YWxJZCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgaWYgKHdzLnJlYWR5U3RhdGUgPT0gd3MuT1BFTikge1xuICAgICAgICAgIHdzLnBpbmcoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjbGVhckludGVydmFsKHBpbmdJbnRlcnZhbElkKTtcbiAgICAgICAgfVxuICAgICAgfSwgY29uZmlnLndlYnNvY2tldFRpbWVvdXQgfHwgMTAgKiAxMDAwKTtcbiAgICB9O1xuICAgIHdzcy5vbkVycm9yID0gZXJyb3IgPT4ge1xuICAgICAgbG9nZ2VyLmVycm9yKGVycm9yKTtcbiAgICB9O1xuICAgIHdzcy5zdGFydCgpO1xuICAgIHRoaXMuc2VydmVyID0gd3NzO1xuICB9XG5cbiAgY2xvc2UoKSB7XG4gICAgaWYgKHRoaXMuc2VydmVyICYmIHRoaXMuc2VydmVyLmNsb3NlKSB7XG4gICAgICB0aGlzLnNlcnZlci5jbG9zZSgpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUGFyc2VXZWJTb2NrZXQgZXh0ZW5kcyBldmVudHMuRXZlbnRFbWl0dGVyIHtcbiAgd3M6IGFueTtcblxuICBjb25zdHJ1Y3Rvcih3czogYW55KSB7XG4gICAgc3VwZXIoKTtcbiAgICB3cy5vbm1lc3NhZ2UgPSByZXF1ZXN0ID0+XG4gICAgICB0aGlzLmVtaXQoJ21lc3NhZ2UnLCByZXF1ZXN0ICYmIHJlcXVlc3QuZGF0YSA/IHJlcXVlc3QuZGF0YSA6IHJlcXVlc3QpO1xuICAgIHdzLm9uY2xvc2UgPSAoKSA9PiB0aGlzLmVtaXQoJ2Rpc2Nvbm5lY3QnKTtcbiAgICB0aGlzLndzID0gd3M7XG4gIH1cblxuICBzZW5kKG1lc3NhZ2U6IGFueSk6IHZvaWQge1xuICAgIHRoaXMud3Muc2VuZChtZXNzYWdlKTtcbiAgfVxufVxuIl19 \ No newline at end of file diff --git a/lib/LiveQuery/QueryTools.js b/lib/LiveQuery/QueryTools.js new file mode 100644 index 0000000000..6185b13082 --- /dev/null +++ b/lib/LiveQuery/QueryTools.js @@ -0,0 +1,452 @@ +"use strict"; + +var equalObjects = require('./equalObjects'); + +var Id = require('./Id'); + +var Parse = require('parse/node'); +/** + * Query Hashes are deterministic hashes for Parse Queries. + * Any two queries that have the same set of constraints will produce the same + * hash. This lets us reliably group components by the queries they depend upon, + * and quickly determine if a query has changed. + */ + +/** + * Convert $or queries into an array of where conditions + */ + + +function flattenOrQueries(where) { + if (!Object.prototype.hasOwnProperty.call(where, '$or')) { + return where; + } + + var accum = []; + + for (var i = 0; i < where.$or.length; i++) { + accum = accum.concat(where.$or[i]); + } + + return accum; +} +/** + * Deterministically turns an object into a string. Disregards ordering + */ + + +function stringify(object) { + if (typeof object !== 'object' || object === null) { + if (typeof object === 'string') { + return '"' + object.replace(/\|/g, '%|') + '"'; + } + + return object + ''; + } + + if (Array.isArray(object)) { + var copy = object.map(stringify); + copy.sort(); + return '[' + copy.join(',') + ']'; + } + + var sections = []; + var keys = Object.keys(object); + keys.sort(); + + for (var k = 0; k < keys.length; k++) { + sections.push(stringify(keys[k]) + ':' + stringify(object[keys[k]])); + } + + return '{' + sections.join(',') + '}'; +} +/** + * Generate a hash from a query, with unique fields for columns, values, order, + * skip, and limit. + */ + + +function queryHash(query) { + if (query instanceof Parse.Query) { + query = { + className: query.className, + where: query._where + }; + } + + var where = flattenOrQueries(query.where || {}); + var columns = []; + var values = []; + var i; + + if (Array.isArray(where)) { + var uniqueColumns = {}; + + for (i = 0; i < where.length; i++) { + var subValues = {}; + var keys = Object.keys(where[i]); + keys.sort(); + + for (var j = 0; j < keys.length; j++) { + subValues[keys[j]] = where[i][keys[j]]; + uniqueColumns[keys[j]] = true; + } + + values.push(subValues); + } + + columns = Object.keys(uniqueColumns); + columns.sort(); + } else { + columns = Object.keys(where); + columns.sort(); + + for (i = 0; i < columns.length; i++) { + values.push(where[columns[i]]); + } + } + + var sections = [columns.join(','), stringify(values)]; + return query.className + ':' + sections.join('|'); +} +/** + * contains -- Determines if an object is contained in a list with special handling for Parse pointers. + */ + + +function contains(haystack, needle) { + if (needle && needle.__type && needle.__type === 'Pointer') { + for (const i in haystack) { + const ptr = haystack[i]; + + if (typeof ptr === 'string' && ptr === needle.objectId) { + return true; + } + + if (ptr.className === needle.className && ptr.objectId === needle.objectId) { + return true; + } + } + + return false; + } + + return haystack.indexOf(needle) > -1; +} +/** + * matchesQuery -- Determines if an object would be returned by a Parse Query + * It's a lightweight, where-clause only implementation of a full query engine. + * Since we find queries that match objects, rather than objects that match + * queries, we can avoid building a full-blown query tool. + */ + + +function matchesQuery(object, query) { + if (query instanceof Parse.Query) { + var className = object.id instanceof Id ? object.id.className : object.className; + + if (className !== query.className) { + return false; + } + + return matchesQuery(object, query._where); + } + + for (var field in query) { + if (!matchesKeyConstraints(object, field, query[field])) { + return false; + } + } + + return true; +} + +function equalObjectsGeneric(obj, compareTo, eqlFn) { + if (Array.isArray(obj)) { + for (var i = 0; i < obj.length; i++) { + if (eqlFn(obj[i], compareTo)) { + return true; + } + } + + return false; + } + + return eqlFn(obj, compareTo); +} +/** + * Determines whether an object matches a single key's constraints + */ + + +function matchesKeyConstraints(object, key, constraints) { + if (constraints === null) { + return false; + } + + if (key.indexOf('.') >= 0) { + // Key references a subobject + var keyComponents = key.split('.'); + var subObjectKey = keyComponents[0]; + var keyRemainder = keyComponents.slice(1).join('.'); + return matchesKeyConstraints(object[subObjectKey] || {}, keyRemainder, constraints); + } + + var i; + + if (key === '$or') { + for (i = 0; i < constraints.length; i++) { + if (matchesQuery(object, constraints[i])) { + return true; + } + } + + return false; + } + + if (key === '$and') { + for (i = 0; i < constraints.length; i++) { + if (!matchesQuery(object, constraints[i])) { + return false; + } + } + + return true; + } + + if (key === '$nor') { + for (i = 0; i < constraints.length; i++) { + if (matchesQuery(object, constraints[i])) { + return false; + } + } + + return true; + } + + if (key === '$relatedTo') { + // Bail! We can't handle relational queries locally + return false; + } // Decode Date JSON value + + + if (object[key] && object[key].__type == 'Date') { + object[key] = new Date(object[key].iso); + } // Equality (or Array contains) cases + + + if (typeof constraints !== 'object') { + if (Array.isArray(object[key])) { + return object[key].indexOf(constraints) > -1; + } + + return object[key] === constraints; + } + + var compareTo; + + if (constraints.__type) { + if (constraints.__type === 'Pointer') { + return equalObjectsGeneric(object[key], constraints, function (obj, ptr) { + return typeof obj !== 'undefined' && ptr.className === obj.className && ptr.objectId === obj.objectId; + }); + } + + return equalObjectsGeneric(object[key], Parse._decode(key, constraints), equalObjects); + } // More complex cases + + + for (var condition in constraints) { + compareTo = constraints[condition]; + + if (compareTo.__type) { + compareTo = Parse._decode(key, compareTo); + } + + switch (condition) { + case '$lt': + if (object[key] >= compareTo) { + return false; + } + + break; + + case '$lte': + if (object[key] > compareTo) { + return false; + } + + break; + + case '$gt': + if (object[key] <= compareTo) { + return false; + } + + break; + + case '$gte': + if (object[key] < compareTo) { + return false; + } + + break; + + case '$ne': + if (equalObjects(object[key], compareTo)) { + return false; + } + + break; + + case '$in': + if (!contains(compareTo, object[key])) { + return false; + } + + break; + + case '$nin': + if (contains(compareTo, object[key])) { + return false; + } + + break; + + case '$all': + for (i = 0; i < compareTo.length; i++) { + if (object[key].indexOf(compareTo[i]) < 0) { + return false; + } + } + + break; + + case '$exists': + { + const propertyExists = typeof object[key] !== 'undefined'; + const existenceIsRequired = constraints['$exists']; + + if (typeof constraints['$exists'] !== 'boolean') { + // The SDK will never submit a non-boolean for $exists, but if someone + // tries to submit a non-boolean for $exits outside the SDKs, just ignore it. + break; + } + + if (!propertyExists && existenceIsRequired || propertyExists && !existenceIsRequired) { + return false; + } + + break; + } + + case '$regex': + if (typeof compareTo === 'object') { + return compareTo.test(object[key]); + } // JS doesn't support perl-style escaping + + + var expString = ''; + var escapeEnd = -2; + var escapeStart = compareTo.indexOf('\\Q'); + + while (escapeStart > -1) { + // Add the unescaped portion + expString += compareTo.substring(escapeEnd + 2, escapeStart); + escapeEnd = compareTo.indexOf('\\E', escapeStart); + + if (escapeEnd > -1) { + expString += compareTo.substring(escapeStart + 2, escapeEnd).replace(/\\\\\\\\E/g, '\\E').replace(/\W/g, '\\$&'); + } + + escapeStart = compareTo.indexOf('\\Q', escapeEnd); + } + + expString += compareTo.substring(Math.max(escapeStart, escapeEnd + 2)); + var exp = new RegExp(expString, constraints.$options || ''); + + if (!exp.test(object[key])) { + return false; + } + + break; + + case '$nearSphere': + if (!compareTo || !object[key]) { + return false; + } + + var distance = compareTo.radiansTo(object[key]); + var max = constraints.$maxDistance || Infinity; + return distance <= max; + + case '$within': + if (!compareTo || !object[key]) { + return false; + } + + var southWest = compareTo.$box[0]; + var northEast = compareTo.$box[1]; + + if (southWest.latitude > northEast.latitude || southWest.longitude > northEast.longitude) { + // Invalid box, crosses the date line + return false; + } + + return object[key].latitude > southWest.latitude && object[key].latitude < northEast.latitude && object[key].longitude > southWest.longitude && object[key].longitude < northEast.longitude; + + case '$containedBy': + { + for (const value of object[key]) { + if (!contains(compareTo, value)) { + return false; + } + } + + return true; + } + + case '$geoWithin': + { + const points = compareTo.$polygon.map(geoPoint => [geoPoint.latitude, geoPoint.longitude]); + const polygon = new Parse.Polygon(points); + return polygon.containsPoint(object[key]); + } + + case '$geoIntersects': + { + const polygon = new Parse.Polygon(object[key].coordinates); + const point = new Parse.GeoPoint(compareTo.$point); + return polygon.containsPoint(point); + } + + case '$options': + // Not a query type, but a way to add options to $regex. Ignore and + // avoid the default + break; + + case '$maxDistance': + // Not a query type, but a way to add a cap to $nearSphere. Ignore and + // avoid the default + break; + + case '$select': + return false; + + case '$dontSelect': + return false; + + default: + return false; + } + } + + return true; +} + +var QueryTools = { + queryHash: queryHash, + matchesQuery: matchesQuery +}; +module.exports = QueryTools; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUXVlcnlUb29scy5qcyJdLCJuYW1lcyI6WyJlcXVhbE9iamVjdHMiLCJyZXF1aXJlIiwiSWQiLCJQYXJzZSIsImZsYXR0ZW5PclF1ZXJpZXMiLCJ3aGVyZSIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImFjY3VtIiwiaSIsIiRvciIsImxlbmd0aCIsImNvbmNhdCIsInN0cmluZ2lmeSIsIm9iamVjdCIsInJlcGxhY2UiLCJBcnJheSIsImlzQXJyYXkiLCJjb3B5IiwibWFwIiwic29ydCIsImpvaW4iLCJzZWN0aW9ucyIsImtleXMiLCJrIiwicHVzaCIsInF1ZXJ5SGFzaCIsInF1ZXJ5IiwiUXVlcnkiLCJjbGFzc05hbWUiLCJfd2hlcmUiLCJjb2x1bW5zIiwidmFsdWVzIiwidW5pcXVlQ29sdW1ucyIsInN1YlZhbHVlcyIsImoiLCJjb250YWlucyIsImhheXN0YWNrIiwibmVlZGxlIiwiX190eXBlIiwicHRyIiwib2JqZWN0SWQiLCJpbmRleE9mIiwibWF0Y2hlc1F1ZXJ5IiwiaWQiLCJmaWVsZCIsIm1hdGNoZXNLZXlDb25zdHJhaW50cyIsImVxdWFsT2JqZWN0c0dlbmVyaWMiLCJvYmoiLCJjb21wYXJlVG8iLCJlcWxGbiIsImtleSIsImNvbnN0cmFpbnRzIiwia2V5Q29tcG9uZW50cyIsInNwbGl0Iiwic3ViT2JqZWN0S2V5Iiwia2V5UmVtYWluZGVyIiwic2xpY2UiLCJEYXRlIiwiaXNvIiwiX2RlY29kZSIsImNvbmRpdGlvbiIsInByb3BlcnR5RXhpc3RzIiwiZXhpc3RlbmNlSXNSZXF1aXJlZCIsInRlc3QiLCJleHBTdHJpbmciLCJlc2NhcGVFbmQiLCJlc2NhcGVTdGFydCIsInN1YnN0cmluZyIsIk1hdGgiLCJtYXgiLCJleHAiLCJSZWdFeHAiLCIkb3B0aW9ucyIsImRpc3RhbmNlIiwicmFkaWFuc1RvIiwiJG1heERpc3RhbmNlIiwiSW5maW5pdHkiLCJzb3V0aFdlc3QiLCIkYm94Iiwibm9ydGhFYXN0IiwibGF0aXR1ZGUiLCJsb25naXR1ZGUiLCJ2YWx1ZSIsInBvaW50cyIsIiRwb2x5Z29uIiwiZ2VvUG9pbnQiLCJwb2x5Z29uIiwiUG9seWdvbiIsImNvbnRhaW5zUG9pbnQiLCJjb29yZGluYXRlcyIsInBvaW50IiwiR2VvUG9pbnQiLCIkcG9pbnQiLCJRdWVyeVRvb2xzIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQSxJQUFJQSxZQUFZLEdBQUdDLE9BQU8sQ0FBQyxnQkFBRCxDQUExQjs7QUFDQSxJQUFJQyxFQUFFLEdBQUdELE9BQU8sQ0FBQyxNQUFELENBQWhCOztBQUNBLElBQUlFLEtBQUssR0FBR0YsT0FBTyxDQUFDLFlBQUQsQ0FBbkI7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFDQSxTQUFTRyxnQkFBVCxDQUEwQkMsS0FBMUIsRUFBaUM7QUFDL0IsTUFBSSxDQUFDQyxNQUFNLENBQUNDLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUFxQ0osS0FBckMsRUFBNEMsS0FBNUMsQ0FBTCxFQUF5RDtBQUN2RCxXQUFPQSxLQUFQO0FBQ0Q7O0FBQ0QsTUFBSUssS0FBSyxHQUFHLEVBQVo7O0FBQ0EsT0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHTixLQUFLLENBQUNPLEdBQU4sQ0FBVUMsTUFBOUIsRUFBc0NGLENBQUMsRUFBdkMsRUFBMkM7QUFDekNELElBQUFBLEtBQUssR0FBR0EsS0FBSyxDQUFDSSxNQUFOLENBQWFULEtBQUssQ0FBQ08sR0FBTixDQUFVRCxDQUFWLENBQWIsQ0FBUjtBQUNEOztBQUNELFNBQU9ELEtBQVA7QUFDRDtBQUVEO0FBQ0E7QUFDQTs7O0FBQ0EsU0FBU0ssU0FBVCxDQUFtQkMsTUFBbkIsRUFBbUM7QUFDakMsTUFBSSxPQUFPQSxNQUFQLEtBQWtCLFFBQWxCLElBQThCQSxNQUFNLEtBQUssSUFBN0MsRUFBbUQ7QUFDakQs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cUMsR0FBRCxDQUFOLENBQVl1QyxXQUE5QixDQUFoQjtBQUNBLGdCQUFNQyxLQUFLLEdBQUcsSUFBSTFGLEtBQUssQ0FBQzJGLFFBQVYsQ0FBbUIzQyxTQUFTLENBQUM0QyxNQUE3QixDQUFkO0FBQ0EsaUJBQU9OLE9BQU8sQ0FBQ0UsYUFBUixDQUFzQkUsS0FBdEIsQ0FBUDtBQUNEOztBQUNELFdBQUssVUFBTDtBQUNFO0FBQ0E7QUFDQTs7QUFDRixXQUFLLGNBQUw7QUFDRTtBQUNBO0FBQ0E7O0FBQ0YsV0FBSyxTQUFMO0FBQ0UsZUFBTyxLQUFQOztBQUNGLFdBQUssYUFBTDtBQUNFLGVBQU8sS0FBUDs7QUFDRjtBQUNFLGVBQU8sS0FBUDtBQXpJSjtBQTJJRDs7QUFDRCxTQUFPLElBQVA7QUFDRDs7QUFFRCxJQUFJRyxVQUFVLEdBQUc7QUFDZnBFLEVBQUFBLFNBQVMsRUFBRUEsU0FESTtBQUVmaUIsRUFBQUEsWUFBWSxFQUFFQTtBQUZDLENBQWpCO0FBS0FvRCxNQUFNLENBQUNDLE9BQVAsR0FBaUJGLFVBQWpCIiwic291cmNlc0NvbnRlbnQiOlsidmFyIGVxdWFsT2JqZWN0cyA9IHJlcXVpcmUoJy4vZXF1YWxPYmplY3RzJyk7XG52YXIgSWQgPSByZXF1aXJlKCcuL0lkJyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5cbi8qKlxuICogUXVlcnkgSGFzaGVzIGFyZSBkZXRlcm1pbmlzdGljIGhhc2hlcyBmb3IgUGFyc2UgUXVlcmllcy5cbiAqIEFueSB0d28gcXVlcmllcyB0aGF0IGhhdmUgdGhlIHNhbWUgc2V0IG9mIGNvbnN0cmFpbnRzIHdpbGwgcHJvZHVjZSB0aGUgc2FtZVxuICogaGFzaC4gVGhpcyBsZXRzIHVzIHJlbGlhYmx5IGdyb3VwIGNvbXBvbmVudHMgYnkgdGhlIHF1ZXJpZXMgdGhleSBkZXBlbmQgdXBvbixcbiAqIGFuZCBxdWlja2x5IGRldGVybWluZSBpZiBhIHF1ZXJ5IGhhcyBjaGFuZ2VkLlxuICovXG5cbi8qKlxuICogQ29udmVydCAkb3IgcXVlcmllcyBpbnRvIGFuIGFycmF5IG9mIHdoZXJlIGNvbmRpdGlvbnNcbiAqL1xuZnVuY3Rpb24gZmxhdHRlbk9yUXVlcmllcyh3aGVyZSkge1xuICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh3aGVyZSwgJyRvcicpKSB7XG4gICAgcmV0dXJuIHdoZXJlO1xuICB9XG4gIHZhciBhY2N1bSA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHdoZXJlLiRvci5sZW5ndGg7IGkrKykge1xuICAgIGFjY3VtID0gYWNjdW0uY29uY2F0KHdoZXJlLiRvcltpXSk7XG4gIH1cbiAgcmV0dXJuIGFjY3VtO1xufVxuXG4vKipcbiAqIERldGVybWluaXN0aWNhbGx5IHR1cm5zIGFuIG9iamVjdCBpbnRvIGEgc3RyaW5nLiBEaXNyZWdhcmRzIG9yZGVyaW5nXG4gKi9cbmZ1bmN0aW9uIHN0cmluZ2lmeShvYmplY3QpOiBzdHJpbmcge1xuICBpZiAodHlwZW9mIG9iamVjdCAhPT0gJ29iamVjdCcgfHwgb2JqZWN0ID09PSBudWxsKSB7XG4gICAgaWYgKHR5cGVvZiBvYmplY3QgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gJ1wiJyArIG9iamVjdC5yZXBsYWNlKC9cXHwvZywgJyV8JykgKyAnXCInO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0ICsgJyc7XG4gIH1cbiAgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkge1xuICAgIHZhciBjb3B5ID0gb2JqZWN0Lm1hcChzdHJpbmdpZnkpO1xuICAgIGNvcHkuc29ydCgpO1xuICAgIHJldHVybiAnWycgKyBjb3B5LmpvaW4oJywnKSArICddJztcbiAgfVxuICB2YXIgc2VjdGlvbnMgPSBbXTtcbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmplY3QpO1xuICBrZXlzLnNvcnQoKTtcbiAgZm9yICh2YXIgayA9IDA7IGsgPCBrZXlzLmxlbmd0aDsgaysrKSB7XG4gICAgc2VjdGlvbnMucHVzaChzdHJpbmdpZnkoa2V5c1trXSkgKyAnOicgKyBzdHJpbmdpZnkob2JqZWN0W2tleXNba11dKSk7XG4gIH1cbiAgcmV0dXJuICd7JyArIHNlY3Rpb25zLmpvaW4oJywnKSArICd9Jztcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBhIGhhc2ggZnJvbSBhIHF1ZXJ5LCB3aXRoIHVuaXF1ZSBmaWVsZHMgZm9yIGNvbHVtbnMsIHZhbHVlcywgb3JkZXIsXG4gKiBza2lwLCBhbmQgbGltaXQuXG4gKi9cbmZ1bmN0aW9uIHF1ZXJ5SGFzaChxdWVyeSkge1xuICBpZiAocXVlcnkgaW5zdGFuY2VvZiBQYXJzZS5RdWVyeSkge1xuICAgIHF1ZXJ5ID0ge1xuICAgICAgY2xhc3NOYW1lOiBxdWVyeS5jbGFzc05hbWUsXG4gICAgICB3aGVyZTogcXVlcnkuX3doZXJlLFxuICAgIH07XG4gIH1cbiAgdmFyIHdoZXJlID0gZmxhdHRlbk9yUXVlcmllcyhxdWVyeS53aGVyZSB8fCB7fSk7XG4gIHZhciBjb2x1bW5zID0gW107XG4gIHZhciB2YWx1ZXMgPSBbXTtcbiAgdmFyIGk7XG4gIGlmIChBcnJheS5pc0FycmF5KHdoZXJlKSkge1xuICAgIHZhciB1bmlxdWVDb2x1bW5zID0ge307XG4gICAgZm9yIChpID0gMDsgaSA8IHdoZXJlLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgc3ViVmFsdWVzID0ge307XG4gICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHdoZXJlW2ldKTtcbiAgICAgIGtleXMuc29ydCgpO1xuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBrZXlzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIHN1YlZhbHVlc1trZXlzW2pdXSA9IHdoZXJlW2ldW2tleXNbal1dO1xuICAgICAgICB1bmlxdWVDb2x1bW5zW2tleXNbal1dID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHZhbHVlcy5wdXNoKHN1YlZhbHVlcyk7XG4gICAgfVxuICAgIGNvbHVtbnMgPSBPYmplY3Qua2V5cyh1bmlxdWVDb2x1bW5zKTtcbiAgICBjb2x1bW5zLnNvcnQoKTtcbiAgfSBlbHNlIHtcbiAgICBjb2x1bW5zID0gT2JqZWN0LmtleXMod2hlcmUpO1xuICAgIGNvbHVtbnMuc29ydCgpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBjb2x1bW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YWx1ZXMucHVzaCh3aGVyZVtjb2x1bW5zW2ldXSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIHNlY3Rpb25zID0gW2NvbHVtbnMuam9pbignLCcpLCBzdHJpbmdpZnkodmFsdWVzKV07XG5cbiAgcmV0dXJuIHF1ZXJ5LmNsYXNzTmFtZSArICc6JyArIHNlY3Rpb25zLmpvaW4oJ3wnKTtcbn1cblxuLyoqXG4gKiBjb250YWlucyAtLSBEZXRlcm1pbmVzIGlmIGFuIG9iamVjdCBpcyBjb250YWluZWQgaW4gYSBsaXN0IHdpdGggc3BlY2lhbCBoYW5kbGluZyBmb3IgUGFyc2UgcG9pbnRlcnMuXG4gKi9cbmZ1bmN0aW9uIGNvbnRhaW5zKGhheXN0YWNrOiBBcnJheSwgbmVlZGxlOiBhbnkpOiBib29sZWFuIHtcbiAgaWYgKG5lZWRsZSAmJiBuZWVkbGUuX190eXBlICYmIG5lZWRsZS5fX3R5cGUgPT09ICdQb2ludGVyJykge1xuICAgIGZvciAoY29uc3QgaSBpbiBoYXlzdGFjaykge1xuICAgICAgY29uc3QgcHRyID0gaGF5c3RhY2tbaV07XG4gICAgICBpZiAodHlwZW9mIHB0ciA9PT0gJ3N0cmluZycgJiYgcHRyID09PSBuZWVkbGUub2JqZWN0SWQpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBpZiAocHRyLmNsYXNzTmFtZSA9PT0gbmVlZGxlLmNsYXNzTmFtZSAmJiBwdHIub2JqZWN0SWQgPT09IG5lZWRsZS5vYmplY3RJZCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiBoYXlzdGFjay5pbmRleE9mKG5lZWRsZSkgPiAtMTtcbn1cbi8qKlxuICogbWF0Y2hlc1F1ZXJ5IC0tIERldGVybWluZXMgaWYgYW4gb2JqZWN0IHdvdWxkIGJlIHJldHVybmVkIGJ5IGEgUGFyc2UgUXVlcnlcbiAqIEl0J3MgYSBsaWdodHdlaWdodCwgd2hlcmUtY2xhdXNlIG9ubHkgaW1wbGVtZW50YXRpb24gb2YgYSBmdWxsIHF1ZXJ5IGVuZ2luZS5cbiAqIFNpbmNlIHdlIGZpbmQgcXVlcmllcyB0aGF0IG1hdGNoIG9iamVjdHMsIHJhdGhlciB0aGFuIG9iamVjdHMgdGhhdCBtYXRjaFxuICogcXVlcmllcywgd2UgY2FuIGF2b2lkIGJ1aWxkaW5nIGEgZnVsbC1ibG93biBxdWVyeSB0b29sLlxuICovXG5mdW5jdGlvbiBtYXRjaGVzUXVlcnkob2JqZWN0OiBhbnksIHF1ZXJ5OiBhbnkpOiBib29sZWFuIHtcbiAgaWYgKHF1ZXJ5IGluc3RhbmNlb2YgUGFyc2UuUXVlcnkpIHtcbiAgICB2YXIgY2xhc3NOYW1lID0gb2JqZWN0LmlkIGluc3RhbmNlb2YgSWQgPyBvYmplY3QuaWQuY2xhc3NOYW1lIDogb2JqZWN0LmNsYXNzTmFtZTtcbiAgICBpZiAoY2xhc3NOYW1lICE9PSBxdWVyeS5jbGFzc05hbWUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoZXNRdWVyeShvYmplY3QsIHF1ZXJ5Ll93aGVyZSk7XG4gIH1cbiAgZm9yICh2YXIgZmllbGQgaW4gcXVlcnkpIHtcbiAgICBpZiAoIW1hdGNoZXNLZXlDb25zdHJhaW50cyhvYmplY3QsIGZpZWxkLCBxdWVyeVtmaWVsZF0pKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBlcXVhbE9iamVjdHNHZW5lcmljKG9iaiwgY29tcGFyZVRvLCBlcWxGbikge1xuICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChlcWxGbihvYmpbaV0sIGNvbXBhcmVUbykpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBlcWxGbihvYmosIGNvbXBhcmVUbyk7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIGFuIG9iamVjdCBtYXRjaGVzIGEgc2luZ2xlIGtleSdzIGNvbnN0cmFpbnRzXG4gKi9cbmZ1bmN0aW9uIG1hdGNoZXNLZXlDb25zdHJhaW50cyhvYmplY3QsIGtleSwgY29uc3RyYWludHMpIHtcbiAgaWYgKGNvbnN0cmFpbnRzID09PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChrZXkuaW5kZXhPZignLicpID49IDApIHtcbiAgICAvLyBLZXkgcmVmZXJlbmNlcyBhIHN1Ym9iamVjdFxuICAgIHZhciBrZXlDb21wb25lbnRzID0ga2V5LnNwbGl0KCcuJyk7XG4gICAgdmFyIHN1Yk9iamVjdEtleSA9IGtleUNvbXBvbmVudHNbMF07XG4gICAgdmFyIGtleVJlbWFpbmRlciA9IGtleUNvbXBvbmVudHMuc2xpY2UoMSkuam9pbignLicpO1xuICAgIHJldHVybiBtYXRjaGVzS2V5Q29uc3RyYWludHMob2JqZWN0W3N1Yk9iamVjdEtleV0gfHwge30sIGtleVJlbWFpbmRlciwgY29uc3RyYWludHMpO1xuICB9XG4gIHZhciBpO1xuICBpZiAoa2V5ID09PSAnJG9yJykge1xuICAgIGZvciAoaSA9IDA7IGkgPCBjb25zdHJhaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKG1hdGNoZXNRdWVyeShvYmplY3QsIGNvbnN0cmFpbnRzW2ldKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChrZXkgPT09ICckYW5kJykge1xuICAgIGZvciAoaSA9IDA7IGkgPCBjb25zdHJhaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKCFtYXRjaGVzUXVlcnkob2JqZWN0LCBjb25zdHJhaW50c1tpXSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoa2V5ID09PSAnJG5vcicpIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgY29uc3RyYWludHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChtYXRjaGVzUXVlcnkob2JqZWN0LCBjb25zdHJhaW50c1tpXSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoa2V5ID09PSAnJHJlbGF0ZWRUbycpIHtcbiAgICAvLyBCYWlsISBXZSBjYW4ndCBoYW5kbGUgcmVsYXRpb25hbCBxdWVyaWVzIGxvY2FsbHlcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gRGVjb2RlIERhdGUgSlNPTiB2YWx1ZVxuICBpZiAob2JqZWN0W2tleV0gJiYgb2JqZWN0W2tleV0uX190eXBlID09ICdEYXRlJykge1xuICAgIG9iamVjdFtrZXldID0gbmV3IERhdGUob2JqZWN0W2tleV0uaXNvKTtcbiAgfVxuICAvLyBFcXVhbGl0eSAob3IgQXJyYXkgY29udGFpbnMpIGNhc2VzXG4gIGlmICh0eXBlb2YgY29uc3RyYWludHMgIT09ICdvYmplY3QnKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0W2tleV0pKSB7XG4gICAgICByZXR1cm4gb2JqZWN0W2tleV0uaW5kZXhPZihjb25zdHJhaW50cykgPiAtMTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdFtrZXldID09PSBjb25zdHJhaW50cztcbiAgfVxuICB2YXIgY29tcGFyZVRvO1xuICBpZiAoY29uc3RyYWludHMuX190eXBlKSB7XG4gICAgaWYgKGNvbnN0cmFpbnRzLl9fdHlwZSA9PT0gJ1BvaW50ZXInKSB7XG4gICAgICByZXR1cm4gZXF1YWxPYmplY3RzR2VuZXJpYyhvYmplY3Rba2V5XSwgY29uc3RyYWludHMsIGZ1bmN0aW9uIChvYmosIHB0cikge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIHR5cGVvZiBvYmogIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgICAgcHRyLmNsYXNzTmFtZSA9PT0gb2JqLmNsYXNzTmFtZSAmJlxuICAgICAgICAgIHB0ci5vYmplY3RJZCA9PT0gb2JqLm9iamVjdElkXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXF1YWxPYmplY3RzR2VuZXJpYyhvYmplY3Rba2V5XSwgUGFyc2UuX2RlY29kZShrZXksIGNvbnN0cmFpbnRzKSwgZXF1YWxPYmplY3RzKTtcbiAgfVxuICAvLyBNb3JlIGNvbXBsZXggY2FzZXNcbiAgZm9yICh2YXIgY29uZGl0aW9uIGluIGNvbnN0cmFpbnRzKSB7XG4gICAgY29tcGFyZVRvID0gY29uc3RyYWludHNbY29uZGl0aW9uXTtcbiAgICBpZiAoY29tcGFyZVRvLl9fdHlwZSkge1xuICAgICAgY29tcGFyZVRvID0gUGFyc2UuX2RlY29kZShrZXksIGNvbXBhcmVUbyk7XG4gICAgfVxuICAgIHN3aXRjaCAoY29uZGl0aW9uKSB7XG4gICAgICBjYXNlICckbHQnOlxuICAgICAgICBpZiAob2JqZWN0W2tleV0gPj0gY29tcGFyZVRvKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJGx0ZSc6XG4gICAgICAgIGlmIChvYmplY3Rba2V5XSA+IGNvbXBhcmVUbykge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRndCc6XG4gICAgICAgIGlmIChvYmplY3Rba2V5XSA8PSBjb21wYXJlVG8pIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICckZ3RlJzpcbiAgICAgICAgaWYgKG9iamVjdFtrZXldIDwgY29tcGFyZVRvKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJG5lJzpcbiAgICAgICAgaWYgKGVxdWFsT2JqZWN0cyhvYmplY3Rba2V5XSwgY29tcGFyZVRvKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRpbic6XG4gICAgICAgIGlmICghY29udGFpbnMoY29tcGFyZVRvLCBvYmplY3Rba2V5XSkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICckbmluJzpcbiAgICAgICAgaWYgKGNvbnRhaW5zKGNvbXBhcmVUbywgb2JqZWN0W2tleV0pKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJGFsbCc6XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb21wYXJlVG8ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpZiAob2JqZWN0W2tleV0uaW5kZXhPZihjb21wYXJlVG9baV0pIDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRleGlzdHMnOiB7XG4gICAgICAgIGNvbnN0IHByb3BlcnR5RXhpc3RzID0gdHlwZW9mIG9iamVjdFtrZXldICE9PSAndW5kZWZpbmVkJztcbiAgICAgICAgY29uc3QgZXhpc3RlbmNlSXNSZXF1aXJlZCA9IGNvbnN0cmFpbnRzWyckZXhpc3RzJ107XG4gICAgICAgIGlmICh0eXBlb2YgY29uc3RyYWludHNbJyRleGlzdHMnXSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgLy8gVGhlIFNESyB3aWxsIG5ldmVyIHN1Ym1pdCBhIG5vbi1ib29sZWFuIGZvciAkZXhpc3RzLCBidXQgaWYgc29tZW9uZVxuICAgICAgICAgIC8vIHRyaWVzIHRvIHN1Ym1pdCBhIG5vbi1ib29sZWFuIGZvciAkZXhpdHMgb3V0c2lkZSB0aGUgU0RLcywganVzdCBpZ25vcmUgaXQuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCghcHJvcGVydHlFeGlzdHMgJiYgZXhpc3RlbmNlSXNSZXF1aXJlZCkgfHwgKHByb3BlcnR5RXhpc3RzICYmICFleGlzdGVuY2VJc1JlcXVpcmVkKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJyRyZWdleCc6XG4gICAgICAgIGlmICh0eXBlb2YgY29tcGFyZVRvID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIHJldHVybiBjb21wYXJlVG8udGVzdChvYmplY3Rba2V5XSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSlMgZG9lc24ndCBzdXBwb3J0IHBlcmwtc3R5bGUgZXNjYXBpbmdcbiAgICAgICAgdmFyIGV4cFN0cmluZyA9ICcnO1xuICAgICAgICB2YXIgZXNjYXBlRW5kID0gLTI7XG4gICAgICAgIHZhciBlc2NhcGVTdGFydCA9IGNvbXBhcmVUby5pbmRleE9mKCdcXFxcUScpO1xuICAgICAgICB3aGlsZSAoZXNjYXBlU3RhcnQgPiAtMSkge1xuICAgICAgICAgIC8vIEFkZCB0aGUgdW5lc2NhcGVkIHBvcnRpb25cbiAgICAgICAgICBleHBTdHJpbmcgKz0gY29tcGFyZVRvLnN1YnN0cmluZyhlc2NhcGVFbmQgKyAyLCBlc2NhcGVTdGFydCk7XG4gICAgICAgICAgZXNjYXBlRW5kID0gY29tcGFyZVRvLmluZGV4T2YoJ1xcXFxFJywgZXNjYXBlU3RhcnQpO1xuICAgICAgICAgIGlmIChlc2NhcGVFbmQgPiAtMSkge1xuICAgICAgICAgICAgZXhwU3RyaW5nICs9IGNvbXBhcmVUb1xuICAgICAgICAgICAgICAuc3Vic3RyaW5nKGVzY2FwZVN0YXJ0ICsgMiwgZXNjYXBlRW5kKVxuICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFxcXFxcXFxcXFxcXEUvZywgJ1xcXFxFJylcbiAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcVy9nLCAnXFxcXCQmJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZXNjYXBlU3RhcnQgPSBjb21wYXJlVG8uaW5kZXhPZignXFxcXFEnLCBlc2NhcGVFbmQpO1xuICAgICAgICB9XG4gICAgICAgIGV4cFN0cmluZyArPSBjb21wYXJlVG8uc3Vic3RyaW5nKE1hdGgubWF4KGVzY2FwZVN0YXJ0LCBlc2NhcGVFbmQgKyAyKSk7XG4gICAgICAgIHZhciBleHAgPSBuZXcgUmVnRXhwKGV4cFN0cmluZywgY29uc3RyYWludHMuJG9wdGlvbnMgfHwgJycpO1xuICAgICAgICBpZiAoIWV4cC50ZXN0KG9iamVjdFtrZXldKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRuZWFyU3BoZXJlJzpcbiAgICAgICAgaWYgKCFjb21wYXJlVG8gfHwgIW9iamVjdFtrZXldKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBkaXN0YW5jZSA9IGNvbXBhcmVUby5yYWRpYW5zVG8ob2JqZWN0W2tleV0pO1xuICAgICAgICB2YXIgbWF4ID0gY29uc3RyYWludHMuJG1heERpc3RhbmNlIHx8IEluZmluaXR5O1xuICAgICAgICByZXR1cm4gZGlzdGFuY2UgPD0gbWF4O1xuICAgICAgY2FzZSAnJHdpdGhpbic6XG4gICAgICAgIGlmICghY29tcGFyZVRvIHx8ICFvYmplY3Rba2V5XSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc291dGhXZXN0ID0gY29tcGFyZVRvLiRib3hbMF07XG4gICAgICAgIHZhciBub3J0aEVhc3QgPSBjb21wYXJlVG8uJGJveFsxXTtcbiAgICAgICAgaWYgKHNvdXRoV2VzdC5sYXRpdHVkZSA+IG5vcnRoRWFzdC5sYXRpdHVkZSB8fCBzb3V0aFdlc3QubG9uZ2l0dWRlID4gbm9ydGhFYXN0LmxvbmdpdHVkZSkge1xuICAgICAgICAgIC8vIEludmFsaWQgYm94LCBjcm9zc2VzIHRoZSBkYXRlIGxpbmVcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICBvYmplY3Rba2V5XS5sYXRpdHVkZSA+IHNvdXRoV2VzdC5sYXRpdHVkZSAmJlxuICAgICAgICAgIG9iamVjdFtrZXldLmxhdGl0dWRlIDwgbm9ydGhFYXN0LmxhdGl0dWRlICYmXG4gICAgICAgICAgb2JqZWN0W2tleV0ubG9uZ2l0dWRlID4gc291dGhXZXN0LmxvbmdpdHVkZSAmJlxuICAgICAgICAgIG9iamVjdFtrZXldLmxvbmdpdHVkZSA8IG5vcnRoRWFzdC5sb25naXR1ZGVcbiAgICAgICAgKTtcbiAgICAgIGNhc2UgJyRjb250YWluZWRCeSc6IHtcbiAgICAgICAgZm9yIChjb25zdCB2YWx1ZSBvZiBvYmplY3Rba2V5XSkge1xuICAgICAgICAgIGlmICghY29udGFpbnMoY29tcGFyZVRvLCB2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBjYXNlICckZ2VvV2l0aGluJzoge1xuICAgICAgICBjb25zdCBwb2ludHMgPSBjb21wYXJlVG8uJHBvbHlnb24ubWFwKGdlb1BvaW50ID0+IFtnZW9Qb2ludC5sYXRpdHVkZSwgZ2VvUG9pbnQubG9uZ2l0dWRlXSk7XG4gICAgICAgIGNvbnN0IHBvbHlnb24gPSBuZXcgUGFyc2UuUG9seWdvbihwb2ludHMpO1xuICAgICAgICByZXR1cm4gcG9seWdvbi5jb250YWluc1BvaW50KG9iamVjdFtrZXldKTtcbiAgICAgIH1cbiAgICAgIGNhc2UgJyRnZW9JbnRlcnNlY3RzJzoge1xuICAgICAgICBjb25zdCBwb2x5Z29uID0gbmV3IFBhcnNlLlBvbHlnb24ob2JqZWN0W2tleV0uY29vcmRpbmF0ZXMpO1xuICAgICAgICBjb25zdCBwb2ludCA9IG5ldyBQYXJzZS5HZW9Qb2ludChjb21wYXJlVG8uJHBvaW50KTtcbiAgICAgICAgcmV0dXJuIHBvbHlnb24uY29udGFpbnNQb2ludChwb2ludCk7XG4gICAgICB9XG4gICAgICBjYXNlICckb3B0aW9ucyc6XG4gICAgICAgIC8vIE5vdCBhIHF1ZXJ5IHR5cGUsIGJ1dCBhIHdheSB0byBhZGQgb3B0aW9ucyB0byAkcmVnZXguIElnbm9yZSBhbmRcbiAgICAgICAgLy8gYXZvaWQgdGhlIGRlZmF1bHRcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICckbWF4RGlzdGFuY2UnOlxuICAgICAgICAvLyBOb3QgYSBxdWVyeSB0eXBlLCBidXQgYSB3YXkgdG8gYWRkIGEgY2FwIHRvICRuZWFyU3BoZXJlLiBJZ25vcmUgYW5kXG4gICAgICAgIC8vIGF2b2lkIHRoZSBkZWZhdWx0XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJHNlbGVjdCc6XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIGNhc2UgJyRkb250U2VsZWN0JzpcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxudmFyIFF1ZXJ5VG9vbHMgPSB7XG4gIHF1ZXJ5SGFzaDogcXVlcnlIYXNoLFxuICBtYXRjaGVzUXVlcnk6IG1hdGNoZXNRdWVyeSxcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUXVlcnlUb29scztcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/RequestSchema.js b/lib/LiveQuery/RequestSchema.js new file mode 100644 index 0000000000..08cb08c4c0 --- /dev/null +++ b/lib/LiveQuery/RequestSchema.js @@ -0,0 +1,146 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; +const general = { + title: 'General request schema', + type: 'object', + properties: { + op: { + type: 'string', + enum: ['connect', 'subscribe', 'unsubscribe', 'update'] + } + }, + required: ['op'] +}; +const connect = { + title: 'Connect operation schema', + type: 'object', + properties: { + op: 'connect', + applicationId: { + type: 'string' + }, + javascriptKey: { + type: 'string' + }, + masterKey: { + type: 'string' + }, + clientKey: { + type: 'string' + }, + windowsKey: { + type: 'string' + }, + restAPIKey: { + type: 'string' + }, + sessionToken: { + type: 'string' + }, + installationId: { + type: 'string' + } + }, + required: ['op', 'applicationId'], + additionalProperties: false +}; +const subscribe = { + title: 'Subscribe operation schema', + type: 'object', + properties: { + op: 'subscribe', + requestId: { + type: 'number' + }, + query: { + title: 'Query field schema', + type: 'object', + properties: { + className: { + type: 'string' + }, + where: { + type: 'object' + }, + fields: { + type: 'array', + items: { + type: 'string' + }, + minItems: 1, + uniqueItems: true + } + }, + required: ['where', 'className'], + additionalProperties: false + }, + sessionToken: { + type: 'string' + } + }, + required: ['op', 'requestId', 'query'], + additionalProperties: false +}; +const update = { + title: 'Update operation schema', + type: 'object', + properties: { + op: 'update', + requestId: { + type: 'number' + }, + query: { + title: 'Query field schema', + type: 'object', + properties: { + className: { + type: 'string' + }, + where: { + type: 'object' + }, + fields: { + type: 'array', + items: { + type: 'string' + }, + minItems: 1, + uniqueItems: true + } + }, + required: ['where', 'className'], + additionalProperties: false + }, + sessionToken: { + type: 'string' + } + }, + required: ['op', 'requestId', 'query'], + additionalProperties: false +}; +const unsubscribe = { + title: 'Unsubscribe operation schema', + type: 'object', + properties: { + op: 'unsubscribe', + requestId: { + type: 'number' + } + }, + required: ['op', 'requestId'], + additionalProperties: false +}; +const RequestSchema = { + general: general, + connect: connect, + subscribe: subscribe, + update: update, + unsubscribe: unsubscribe +}; +var _default = RequestSchema; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUmVxdWVzdFNjaGVtYS5qcyJdLCJuYW1lcyI6WyJnZW5lcmFsIiwidGl0bGUiLCJ0eXBlIiwicHJvcGVydGllcyIsIm9wIiwiZW51bSIsInJlcXVpcmVkIiwiY29ubmVjdCIsImFwcGxpY2F0aW9uSWQiLCJqYXZhc2NyaXB0S2V5IiwibWFzdGVyS2V5IiwiY2xpZW50S2V5Iiwid2luZG93c0tleSIsInJlc3RBUElLZXkiLCJzZXNzaW9uVG9rZW4iLCJpbnN0YWxsYXRpb25JZCIsImFkZGl0aW9uYWxQcm9wZXJ0aWVzIiwic3Vic2NyaWJlIiwicmVxdWVzdElkIiwicXVlcnkiLCJjbGFzc05hbWUiLCJ3aGVyZSIsImZpZWxkcyIsIml0ZW1zIiwibWluSXRlbXMiLCJ1bmlxdWVJdGVtcyIsInVwZGF0ZSIsInVuc3Vic2NyaWJlIiwiUmVxdWVzdFNjaGVtYSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsTUFBTUEsT0FBTyxHQUFHO0FBQ2RDLEVBQUFBLEtBQUssRUFBRSx3QkFETztBQUVkQyxFQUFBQSxJQUFJLEVBQUUsUUFGUTtBQUdkQyxFQUFBQSxVQUFVLEVBQUU7QUFDVkMsSUFBQUEsRUFBRSxFQUFFO0FBQ0ZGLE1BQUFBLElBQUksRUFBRSxRQURKO0FBRUZHLE1BQUFBLElBQUksRUFBRSxDQUFDLFNBQUQsRUFBWSxXQUFaLEVBQXlCLGFBQXpCLEVBQXdDLFFBQXhDO0FBRko7QUFETSxHQUhFO0FBU2RDLEVBQUFBLFFBQVEsRUFBRSxDQUFDLElBQUQ7QUFUSSxDQUFoQjtBQVlBLE1BQU1DLE9BQU8sR0FBRztBQUNkTixFQUFBQSxLQUFLLEVBQUUsMEJBRE87QUFFZEMsRUFBQUEsSUFBSSxFQUFFLFFBRlE7QUFHZEMsRUFBQUEsVUFBVSxFQUFFO0FBQ1ZDLElBQUFBLEVBQUUsRUFBRSxTQURNO0FBRVZJLElBQUFBLGFBQWEsRUFBRTtBQUNiTixNQUFBQSxJQUFJLEVBQUU7QUFETyxLQUZMO0FBS1ZPLElBQUFBLGFBQWEs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LENBTEo7QUFNTkMsVUFBQUEsV0FBVyxFQUFFO0FBTlA7QUFQRSxPQUhQO0FBbUJMbkIsTUFBQUEsUUFBUSxFQUFFLENBQUMsT0FBRCxFQUFVLFdBQVYsQ0FuQkw7QUFvQkxVLE1BQUFBLG9CQUFvQixFQUFFO0FBcEJqQixLQUxHO0FBMkJWRixJQUFBQSxZQUFZLEVBQUU7QUFDWlosTUFBQUEsSUFBSSxFQUFFO0FBRE07QUEzQkosR0FIQztBQWtDYkksRUFBQUEsUUFBUSxFQUFFLENBQUMsSUFBRCxFQUFPLFdBQVAsRUFBb0IsT0FBcEIsQ0FsQ0c7QUFtQ2JVLEVBQUFBLG9CQUFvQixFQUFFO0FBbkNULENBQWY7QUFzQ0EsTUFBTVcsV0FBVyxHQUFHO0FBQ2xCMUIsRUFBQUEsS0FBSyxFQUFFLDhCQURXO0FBRWxCQyxFQUFBQSxJQUFJLEVBQUUsUUFGWTtBQUdsQkMsRUFBQUEsVUFBVSxFQUFFO0FBQ1ZDLElBQUFBLEVBQUUsRUFBRSxhQURNO0FBRVZjLElBQUFBLFNBQVMsRUFBRTtBQUNUaEIsTUFBQUEsSUFBSSxFQUFFO0FBREc7QUFGRCxHQUhNO0FBU2xCSSxFQUFBQSxRQUFRLEVBQUUsQ0FBQyxJQUFELEVBQU8sV0FBUCxDQVRRO0FBVWxCVSxFQUFBQSxvQkFBb0IsRUFBRTtBQVZKLENBQXBCO0FBYUEsTUFBTVksYUFBYSxHQUFHO0FBQ3BCNUIsRUFBQUEsT0FBTyxFQUFFQSxPQURXO0FBRXBCTyxFQUFBQSxPQUFPLEVBQUVBLE9BRlc7QUFHcEJVLEVBQUFBLFNBQVMsRUFBRUEsU0FIUztBQUlwQlMsRUFBQUEsTUFBTSxFQUFFQSxNQUpZO0FBS3BCQyxFQUFBQSxXQUFXLEVBQUVBO0FBTE8sQ0FBdEI7ZUFRZUMsYSIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGdlbmVyYWwgPSB7XG4gIHRpdGxlOiAnR2VuZXJhbCByZXF1ZXN0IHNjaGVtYScsXG4gIHR5cGU6ICdvYmplY3QnLFxuICBwcm9wZXJ0aWVzOiB7XG4gICAgb3A6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZW51bTogWydjb25uZWN0JywgJ3N1YnNjcmliZScsICd1bnN1YnNjcmliZScsICd1cGRhdGUnXSxcbiAgICB9LFxuICB9LFxuICByZXF1aXJlZDogWydvcCddLFxufTtcblxuY29uc3QgY29ubmVjdCA9IHtcbiAgdGl0bGU6ICdDb25uZWN0IG9wZXJhdGlvbiBzY2hlbWEnLFxuICB0eXBlOiAnb2JqZWN0JyxcbiAgcHJvcGVydGllczoge1xuICAgIG9wOiAnY29ubmVjdCcsXG4gICAgYXBwbGljYXRpb25JZDoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgICBqYXZhc2NyaXB0S2V5OiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICB9LFxuICAgIG1hc3RlcktleToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgICBjbGllbnRLZXk6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgIH0sXG4gICAgd2luZG93c0tleToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgICByZXN0QVBJS2V5OiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICB9LFxuICAgIHNlc3Npb25Ub2tlbjoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgICBpbnN0YWxsYXRpb25JZDoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgfSxcbiAgcmVxdWlyZWQ6IFsnb3AnLCAnYXBwbGljYXRpb25JZCddLFxuICBhZGRpdGlvbmFsUHJvcGVydGllczogZmFsc2UsXG59O1xuXG5jb25zdCBzdWJzY3JpYmUgPSB7XG4gIHRpdGxlOiAnU3Vic2NyaWJlIG9wZXJhdGlvbiBzY2hlbWEnLFxuICB0eXBlOiAnb2JqZWN0JyxcbiAgcHJvcGVydGllczoge1xuICAgIG9wOiAnc3Vic2NyaWJlJyxcbiAgICByZXF1ZXN0SWQ6IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgIH0sXG4gICAgcXVlcnk6IHtcbiAgICAgIHRpdGxlOiAnUXVlcnkgZmllbGQgc2NoZW1hJyxcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBjbGFzc05hbWU6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgfSxcbiAgICAgICAgd2hlcmU6IHtcbiAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgfSxcbiAgICAgICAgZmllbGRzOiB7XG4gICAgICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgICAgICBpdGVtczoge1xuICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBtaW5JdGVtczogMSxcbiAgICAgICAgICB1bmlxdWVJdGVtczogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICByZXF1aXJlZDogWyd3aGVyZScsICdjbGFzc05hbWUnXSxcbiAgICAgIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbiAgICB9LFxuICAgIHNlc3Npb25Ub2tlbjoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgfSxcbiAgcmVxdWlyZWQ6IFsnb3AnLCAncmVxdWVzdElkJywgJ3F1ZXJ5J10sXG4gIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbn07XG5cbmNvbnN0IHVwZGF0ZSA9IHtcbiAgdGl0bGU6ICdVcGRhdGUgb3BlcmF0aW9uIHNjaGVtYScsXG4gIHR5cGU6ICdvYmplY3QnLFxuICBwcm9wZXJ0aWVzOiB7XG4gICAgb3A6ICd1cGRhdGUnLFxuICAgIHJlcXVlc3RJZDoge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgfSxcbiAgICBxdWVyeToge1xuICAgICAgdGl0bGU6ICdRdWVyeSBmaWVsZCBzY2hlbWEnLFxuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGNsYXNzTmFtZToge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICB9LFxuICAgICAgICB3aGVyZToge1xuICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICB9LFxuICAgICAgICBmaWVsZHM6IHtcbiAgICAgICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgICAgIGl0ZW1zOiB7XG4gICAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG1pbkl0ZW1zOiAxLFxuICAgICAgICAgIHVuaXF1ZUl0ZW1zOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbJ3doZXJlJywgJ2NsYXNzTmFtZSddLFxuICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxuICAgIH0sXG4gICAgc2Vzc2lvblRva2VuOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICB9LFxuICB9LFxuICByZXF1aXJlZDogWydvcCcsICdyZXF1ZXN0SWQnLCAncXVlcnknXSxcbiAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxufTtcblxuY29uc3QgdW5zdWJzY3JpYmUgPSB7XG4gIHRpdGxlOiAnVW5zdWJzY3JpYmUgb3BlcmF0aW9uIHNjaGVtYScsXG4gIHR5cGU6ICdvYmplY3QnLFxuICBwcm9wZXJ0aWVzOiB7XG4gICAgb3A6ICd1bnN1YnNjcmliZScsXG4gICAgcmVxdWVzdElkOiB7XG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICB9LFxuICB9LFxuICByZXF1aXJlZDogWydvcCcsICdyZXF1ZXN0SWQnXSxcbiAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxufTtcblxuY29uc3QgUmVxdWVzdFNjaGVtYSA9IHtcbiAgZ2VuZXJhbDogZ2VuZXJhbCxcbiAgY29ubmVjdDogY29ubmVjdCxcbiAgc3Vic2NyaWJlOiBzdWJzY3JpYmUsXG4gIHVwZGF0ZTogdXBkYXRlLFxuICB1bnN1YnNjcmliZTogdW5zdWJzY3JpYmUsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBSZXF1ZXN0U2NoZW1hO1xuIl19 \ No newline at end of file diff --git a/lib/LiveQuery/SessionTokenCache.js b/lib/LiveQuery/SessionTokenCache.js new file mode 100644 index 0000000000..07a9a06965 --- /dev/null +++ b/lib/LiveQuery/SessionTokenCache.js @@ -0,0 +1,67 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SessionTokenCache = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _lruCache = _interopRequireDefault(require("lru-cache")); + +var _logger = _interopRequireDefault(require("../logger")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function userForSessionToken(sessionToken) { + var q = new _node.default.Query('_Session'); + q.equalTo('sessionToken', sessionToken); + return q.first({ + useMasterKey: true + }).then(function (session) { + if (!session) { + return Promise.reject('No session found for session token'); + } + + return session.get('user'); + }); +} + +class SessionTokenCache { + constructor(timeout = 30 * 24 * 60 * 60 * 1000, maxSize = 10000) { + this.cache = new _lruCache.default({ + max: maxSize, + maxAge: timeout + }); + } + + getUserId(sessionToken) { + if (!sessionToken) { + return Promise.reject('Empty sessionToken'); + } + + const userId = this.cache.get(sessionToken); + + if (userId) { + _logger.default.verbose('Fetch userId %s of sessionToken %s from Cache', userId, sessionToken); + + return Promise.resolve(userId); + } + + return userForSessionToken(sessionToken).then(user => { + _logger.default.verbose('Fetch userId %s of sessionToken %s from Parse', user.id, sessionToken); + + const userId = user.id; + this.cache.set(sessionToken, userId); + return Promise.resolve(userId); + }, error => { + _logger.default.error('Can not fetch userId for sessionToken %j, error %j', sessionToken, error); + + return Promise.reject(error); + }); + } + +} + +exports.SessionTokenCache = SessionTokenCache; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvU2Vzc2lvblRva2VuQ2FjaGUuanMiXSwibmFtZXMiOlsidXNlckZvclNlc3Npb25Ub2tlbiIsInNlc3Npb25Ub2tlbiIsInEiLCJQYXJzZSIsIlF1ZXJ5IiwiZXF1YWxUbyIsImZpcnN0IiwidXNlTWFzdGVyS2V5IiwidGhlbiIsInNlc3Npb24iLCJQcm9taXNlIiwicmVqZWN0IiwiZ2V0IiwiU2Vzc2lvblRva2VuQ2FjaGUiLCJjb25zdHJ1Y3RvciIsInRpbWVvdXQiLCJtYXhTaXplIiwiY2FjaGUiLCJMUlUiLCJtYXgiLCJtYXhBZ2UiLCJnZXRVc2VySWQiLCJ1c2VySWQiLCJsb2dnZXIiLCJ2ZXJib3NlIiwicmVzb2x2ZSIsInVzZXIiLCJpZCIsInNldCIsImVycm9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxTQUFTQSxtQkFBVCxDQUE2QkMsWUFBN0IsRUFBMkM7QUFDekMsTUFBSUMsQ0FBQyxHQUFHLElBQUlDLGNBQU1DLEtBQVYsQ0FBZ0IsVUFBaEIsQ0FBUjtBQUNBRixFQUFBQSxDQUFDLENBQUNHLE9BQUYsQ0FBVSxjQUFWLEVBQTBCSixZQUExQjtBQUNBLFNBQU9DLENBQUMsQ0FBQ0ksS0FBRixDQUFRO0FBQUVDLElBQUFBLFlBQVksRUFBRTtBQUFoQixHQUFSLEVBQWdDQyxJQUFoQyxDQUFxQyxVQUFVQyxPQUFWLEVBQW1CO0FBQzdELFFBQUksQ0FBQ0EsT0FBTCxFQUFjO0FBQ1osYUFBT0MsT0FBTyxDQUFDQyxNQUFSLENBQWUsb0NBQWYsQ0FBUDtBQUNEOztBQUNELFdBQU9GLE9BQU8sQ0FBQ0csR0FBUixDQUFZLE1BQVosQ0FBUDtBQUNELEdBTE0sQ0FBUDtBQU1EOztBQUVELE1BQU1DLGlCQUFOLENBQXdCO0FBR3RCQyxFQUFBQSxXQUFXLENBQUNDLE9BQWUsR0FBRyxLQUFLLEVBQUwsR0FBVSxFQUFWLEdBQWUsRUFBZixHQUFvQixJQUF2QyxFQUE2Q0MsT0FBZSxHQUFHLEtBQS9ELEVBQXNFO0FBQy9FLFNBQUtDLEtBQUwsR0FBYSxJQUFJQyxpQkFBSixDQUFRO0FBQ25CQyxNQUFBQSxHQUFHLEVBQUVILE9BRGM7QUFFbkJJLE1BQUFBLE1BQU0sRUFBRUw7QUFGVyxLQUFSLENBQWI7QUFJRDs7QUFFRE0sRUFBQUEsU0FBUyxDQUFDcEIsWUFBRCxFQUE0QjtBQUNuQyxRQUFJLENBQUNBLFlBQUwsRUFBbUI7QUFDakIsYUFBT1MsT0FBTyxDQUFDQyxNQUFSLENBQWUsb0JBQWYsQ0FBUDtBQUNEOztBQUNELFVBQU1XLE1BQU0sR0FBRyxLQUFLTCxLQUFMLENBQVdMLEdBQVgsQ0FBZVgsWUFBZixDQUFmOztBQUNBLFFBQUlxQixNQUFKLEVBQVk7QUFDVkMsc0JBQU9DLE9BQVAsQ0FBZSwrQ0FBZixFQUFnRUYsTUFBaEUsRUFBd0VyQixZQUF4RTs7QUFDQSxhQUFPUyxPQUFPLENBQUNlLE9BQVIsQ0FBZ0JILE1BQWhCLENBQVA7QUFDRDs7QUFDRCxXQUFPdEIsbUJBQW1CLENBQUNDLFlBQUQsQ0FBbkIsQ0FBa0NPLElBQWxDLENBQ0xrQixJQUFJLElBQUk7QUFDTkgsc0JBQU9DLE9BQVAsQ0FBZSwrQ0FBZixFQUFnRUUsSUFBSSxDQUFDQyxFQUFyRSxFQUF5RTFCLFlBQXpFOztBQUNBLFlBQU1xQixNQUFNLEdBQUdJLElBQUksQ0FBQ0MsRUFBcEI7QUFDQSxXQUFLVixLQUFMLENBQVdXLEdBQVgsQ0FBZTNCLFlBQWYsRUFBNkJxQixNQUE3QjtBQUNBLGFBQU9aLE9BQU8sQ0FBQ2UsT0FBUixDQUFnQkgsTUFBaEIsQ0FBUDtBQUNELEtBTkksRUFPTE8sS0FBSyxJQUFJO0FBQ1BOLHNCQUFPTSxLQUFQLENBQWEsb0RBQWIsRUFBbUU1QixZQUFuRSxFQUFpRjRCLEtBQWpGOztBQUNBLGFBQU9uQixPQUFPLENBQUNDLE1BQVIsQ0FBZWtCLEtBQWYsQ0FBUDtBQUNELEtBVkksQ0FBUDtBQVlEOztBQS9CcUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgTFJVIGZyb20gJ2xydS1jYWNoZSc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5cbmZ1bmN0aW9uIHVzZXJGb3JTZXNzaW9uVG9rZW4oc2Vzc2lvblRva2VuKSB7XG4gIHZhciBxID0gbmV3IFBhcnNlLlF1ZXJ5KCdfU2Vzc2lvbicpO1xuICBxLmVxdWFsVG8oJ3Nlc3Npb25Ub2tlbicsIHNlc3Npb25Ub2tlbik7XG4gIHJldHVybiBxLmZpcnN0KHsgdXNlTWFzdGVyS2V5OiB0cnVlIH0pLnRoZW4oZnVuY3Rpb24gKHNlc3Npb24pIHtcbiAgICBpZiAoIXNlc3Npb24pIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgnTm8gc2Vzc2lvbiBmb3VuZCBmb3Igc2Vzc2lvbiB0b2tlbicpO1xuICAgIH1cbiAgICByZXR1cm4gc2Vzc2lvbi5nZXQoJ3VzZXInKTtcbiAgfSk7XG59XG5cbmNsYXNzIFNlc3Npb25Ub2tlbkNhY2hlIHtcbiAgY2FjaGU6IE9iamVjdDtcblxuICBjb25zdHJ1Y3Rvcih0aW1lb3V0OiBudW1iZXIgPSAzMCAqIDI0ICogNjAgKiA2MCAqIDEwMDAsIG1heFNpemU6IG51bWJlciA9IDEwMDAwKSB7XG4gICAgdGhpcy5jYWNoZSA9IG5ldyBMUlUoe1xuICAgICAgbWF4OiBtYXhTaXplLFxuICAgICAgbWF4QWdlOiB0aW1lb3V0LFxuICAgIH0pO1xuICB9XG5cbiAgZ2V0VXNlcklkKHNlc3Npb25Ub2tlbjogc3RyaW5nKTogYW55IHtcbiAgICBpZiAoIXNlc3Npb25Ub2tlbikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdFbXB0eSBzZXNzaW9uVG9rZW4nKTtcbiAgICB9XG4gICAgY29uc3QgdXNlcklkID0gdGhpcy5jYWNoZS5nZXQoc2Vzc2lvblRva2VuKTtcbiAgICBpZiAodXNlcklkKSB7XG4gICAgICBsb2dnZXIudmVyYm9zZSgnRmV0Y2ggdXNlcklkICVzIG9mIHNlc3Npb25Ub2tlbiAlcyBmcm9tIENhY2hlJywgdXNlcklkLCBzZXNzaW9uVG9rZW4pO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh1c2VySWQpO1xuICAgIH1cbiAgICByZXR1cm4gdXNlckZvclNlc3Npb25Ub2tlbihzZXNzaW9uVG9rZW4pLnRoZW4oXG4gICAgICB1c2VyID0+IHtcbiAgICAgICAgbG9nZ2VyLnZlcmJvc2UoJ0ZldGNoIHVzZXJJZCAlcyBvZiBzZXNzaW9uVG9rZW4gJXMgZnJvbSBQYXJzZScsIHVzZXIuaWQsIHNlc3Npb25Ub2tlbik7XG4gICAgICAgIGNvbnN0IHVzZXJJZCA9IHVzZXIuaWQ7XG4gICAgICAgIHRoaXMuY2FjaGUuc2V0KHNlc3Npb25Ub2tlbiwgdXNlcklkKTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh1c2VySWQpO1xuICAgICAgfSxcbiAgICAgIGVycm9yID0+IHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKCdDYW4gbm90IGZldGNoIHVzZXJJZCBmb3Igc2Vzc2lvblRva2VuICVqLCBlcnJvciAlaicsIHNlc3Npb25Ub2tlbiwgZXJyb3IpO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpO1xuICAgICAgfVxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IHsgU2Vzc2lvblRva2VuQ2FjaGUgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/Subscription.js b/lib/LiveQuery/Subscription.js new file mode 100644 index 0000000000..a424955752 --- /dev/null +++ b/lib/LiveQuery/Subscription.js @@ -0,0 +1,61 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Subscription = void 0; + +var _logger = _interopRequireDefault(require("../logger")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class Subscription { + // It is query condition eg query.where + constructor(className, query, queryHash) { + this.className = className; + this.query = query; + this.hash = queryHash; + this.clientRequestIds = new Map(); + } + + addClientSubscription(clientId, requestId) { + if (!this.clientRequestIds.has(clientId)) { + this.clientRequestIds.set(clientId, []); + } + + const requestIds = this.clientRequestIds.get(clientId); + requestIds.push(requestId); + } + + deleteClientSubscription(clientId, requestId) { + const requestIds = this.clientRequestIds.get(clientId); + + if (typeof requestIds === 'undefined') { + _logger.default.error('Can not find client %d to delete', clientId); + + return; + } + + const index = requestIds.indexOf(requestId); + + if (index < 0) { + _logger.default.error('Can not find client %d subscription %d to delete', clientId, requestId); + + return; + } + + requestIds.splice(index, 1); // Delete client reference if it has no subscription + + if (requestIds.length == 0) { + this.clientRequestIds.delete(clientId); + } + } + + hasSubscribingClient() { + return this.clientRequestIds.size > 0; + } + +} + +exports.Subscription = Subscription; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvU3Vic2NyaXB0aW9uLmpzIl0sIm5hbWVzIjpbIlN1YnNjcmlwdGlvbiIsImNvbnN0cnVjdG9yIiwiY2xhc3NOYW1lIiwicXVlcnkiLCJxdWVyeUhhc2giLCJoYXNoIiwiY2xpZW50UmVxdWVzdElkcyIsIk1hcCIsImFkZENsaWVudFN1YnNjcmlwdGlvbiIsImNsaWVudElkIiwicmVxdWVzdElkIiwiaGFzIiwic2V0IiwicmVxdWVzdElkcyIsImdldCIsInB1c2giLCJkZWxldGVDbGllbnRTdWJzY3JpcHRpb24iLCJsb2dnZXIiLCJlcnJvciIsImluZGV4IiwiaW5kZXhPZiIsInNwbGljZSIsImxlbmd0aCIsImRlbGV0ZSIsImhhc1N1YnNjcmliaW5nQ2xpZW50Iiwic2l6ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7O0FBS0EsTUFBTUEsWUFBTixDQUFtQjtBQUNqQjtBQU1BQyxFQUFBQSxXQUFXLENBQUNDLFNBQUQsRUFBb0JDLEtBQXBCLEVBQXNDQyxTQUF0QyxFQUF5RDtBQUNsRSxTQUFLRixTQUFMLEdBQWlCQSxTQUFqQjtBQUNBLFNBQUtDLEtBQUwsR0FBYUEsS0FBYjtBQUNBLFNBQUtFLElBQUwsR0FBWUQsU0FBWjtBQUNBLFNBQUtFLGdCQUFMLEdBQXdCLElBQUlDLEdBQUosRUFBeEI7QUFDRDs7QUFFREMsRUFBQUEscUJBQXFCLENBQUNDLFFBQUQsRUFBbUJDLFNBQW5CLEVBQTRDO0FBQy9ELFFBQUksQ0FBQyxLQUFLSixnQkFBTCxDQUFzQkssR0FBdEIsQ0FBMEJGLFFBQTFCLENBQUwsRUFBMEM7QUFDeEMsV0FBS0gsZ0JBQUwsQ0FBc0JNLEdBQXRCLENBQTBCSCxRQUExQixFQUFvQyxFQUFwQztBQUNEOztBQUNELFVBQU1JLFVBQVUsR0FBRyxLQUFLUCxnQkFBTCxDQUFzQlEsR0FBdEIsQ0FBMEJMLFFBQTFCLENBQW5CO0FBQ0FJLElBQUFBLFVBQVUsQ0FBQ0UsSUFBWCxDQUFnQkwsU0FBaEI7QUFDRDs7QUFFRE0sRUFBQUEsd0JBQXdCLENBQUNQLFFBQUQsRUFBbUJDLFNBQW5CLEVBQTRDO0FBQ2xFLFVBQU1HLFVBQVUsR0FBRyxLQUFLUCxnQkFBTCxDQUFzQlEsR0FBdEIsQ0FBMEJMLFFBQTFCLENBQW5COztBQUNBLFFBQUksT0FBT0ksVUFBUCxLQUFzQixXQUExQixFQUF1QztBQUNyQ0ksc0JBQU9DLEtBQVAsQ0FBYSxrQ0FBYixFQUFpRFQsUUFBakQ7O0FBQ0E7QUFDRDs7QUFFRCxVQUFNVSxLQUFLLEdBQUdOLFVBQVUsQ0FBQ08sT0FBWCxDQUFtQlYsU0FBbkIsQ0FBZDs7QUFDQSxRQUFJUyxLQUFLLEdBQUcsQ0FBWixFQUFlO0FBQ2JGLHNCQUFPQyxLQUFQLENBQWEsa0RBQWIsRUFBaUVULFFBQWpFLEVBQTJFQyxTQUEzRTs7QUFDQTtBQUNEOztBQUNERyxJQUFBQSxVQUFVLENBQUNRLE1BQVgsQ0FBa0JGLEtBQWxCLEVBQXlCLENBQXpCLEVBWmtFLENBYWxFOztBQUNBLFFBQUlOLFVBQVUsQ0FBQ1MsTUFBWCxJQUFxQixDQUF6QixFQUE0QjtBQUMxQixXQUFLaEIsZ0JBQUwsQ0FBc0JpQixNQUF0QixDQUE2QmQsUUFBN0I7QUFDRDtBQUNGOztBQUVEZSxFQUFBQSxvQkFBb0IsR0FBWTtBQUM5QixXQUFPLEtBQUtsQixnQkFBTCxDQUFzQm1CLElBQXRCLEdBQTZCLENBQXBDO0FBQ0Q7O0FBM0NnQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBsb2dnZXIgZnJvbSAnLi4vbG9nZ2VyJztcblxuZXhwb3J0IHR5cGUgRmxhdHRlbmVkT2JqZWN0RGF0YSA9IHsgW2F0dHI6IHN0cmluZ106IGFueSB9O1xuZXhwb3J0IHR5cGUgUXVlcnlEYXRhID0geyBbYXR0cjogc3RyaW5nXTogYW55IH07XG5cbmNsYXNzIFN1YnNjcmlwdGlvbiB7XG4gIC8vIEl0IGlzIHF1ZXJ5IGNvbmRpdGlvbiBlZyBxdWVyeS53aGVyZVxuICBxdWVyeTogUXVlcnlEYXRhO1xuICBjbGFzc05hbWU6IHN0cmluZztcbiAgaGFzaDogc3RyaW5nO1xuICBjbGllbnRSZXF1ZXN0SWRzOiBPYmplY3Q7XG5cbiAgY29uc3RydWN0b3IoY2xhc3NOYW1lOiBzdHJpbmcsIHF1ZXJ5OiBRdWVyeURhdGEsIHF1ZXJ5SGFzaDogc3RyaW5nKSB7XG4gICAgdGhpcy5jbGFzc05hbWUgPSBjbGFzc05hbWU7XG4gICAgdGhpcy5xdWVyeSA9IHF1ZXJ5O1xuICAgIHRoaXMuaGFzaCA9IHF1ZXJ5SGFzaDtcbiAgICB0aGlzLmNsaWVudFJlcXVlc3RJZHMgPSBuZXcgTWFwKCk7XG4gIH1cblxuICBhZGRDbGllbnRTdWJzY3JpcHRpb24oY2xpZW50SWQ6IG51bWJlciwgcmVxdWVzdElkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY2xpZW50UmVxdWVzdElkcy5oYXMoY2xpZW50SWQpKSB7XG4gICAgICB0aGlzLmNsaWVudFJlcXVlc3RJZHMuc2V0KGNsaWVudElkLCBbXSk7XG4gICAgfVxuICAgIGNvbnN0IHJlcXVlc3RJZHMgPSB0aGlzLmNsaWVudFJlcXVlc3RJZHMuZ2V0KGNsaWVudElkKTtcbiAgICByZXF1ZXN0SWRzLnB1c2gocmVxdWVzdElkKTtcbiAgfVxuXG4gIGRlbGV0ZUNsaWVudFN1YnNjcmlwdGlvbihjbGllbnRJZDogbnVtYmVyLCByZXF1ZXN0SWQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHJlcXVlc3RJZHMgPSB0aGlzLmNsaWVudFJlcXVlc3RJZHMuZ2V0KGNsaWVudElkKTtcbiAgICBpZiAodHlwZW9mIHJlcXVlc3RJZHMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0NhbiBub3QgZmluZCBjbGllbnQgJWQgdG8gZGVsZXRlJywgY2xpZW50SWQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGluZGV4ID0gcmVxdWVzdElkcy5pbmRleE9mKHJlcXVlc3RJZCk7XG4gICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgbG9nZ2VyLmVycm9yKCdDYW4gbm90IGZpbmQgY2xpZW50ICVkIHN1YnNjcmlwdGlvbiAlZCB0byBkZWxldGUnLCBjbGllbnRJZCwgcmVxdWVzdElkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcmVxdWVzdElkcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIC8vIERlbGV0ZSBjbGllbnQgcmVmZXJlbmNlIGlmIGl0IGhhcyBubyBzdWJzY3JpcHRpb25cbiAgICBpZiAocmVxdWVzdElkcy5sZW5ndGggPT0gMCkge1xuICAgICAgdGhpcy5jbGllbnRSZXF1ZXN0SWRzLmRlbGV0ZShjbGllbnRJZCk7XG4gICAgfVxuICB9XG5cbiAgaGFzU3Vic2NyaWJpbmdDbGllbnQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY2xpZW50UmVxdWVzdElkcy5zaXplID4gMDtcbiAgfVxufVxuXG5leHBvcnQgeyBTdWJzY3JpcHRpb24gfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/equalObjects.js b/lib/LiveQuery/equalObjects.js new file mode 100644 index 0000000000..7adfc2cc20 --- /dev/null +++ b/lib/LiveQuery/equalObjects.js @@ -0,0 +1,62 @@ +"use strict"; + +var toString = Object.prototype.toString; +/** + * Determines whether two objects represent the same primitive, special Parse + * type, or full Parse Object. + */ + +function equalObjects(a, b) { + if (typeof a !== typeof b) { + return false; + } + + if (typeof a !== 'object') { + return a === b; + } + + if (a === b) { + return true; + } + + if (toString.call(a) === '[object Date]') { + if (toString.call(b) === '[object Date]') { + return +a === +b; + } + + return false; + } + + if (Array.isArray(a)) { + if (Array.isArray(b)) { + if (a.length !== b.length) { + return false; + } + + for (var i = 0; i < a.length; i++) { + if (!equalObjects(a[i], b[i])) { + return false; + } + } + + return true; + } + + return false; + } + + if (Object.keys(a).length !== Object.keys(b).length) { + return false; + } + + for (var key in a) { + if (!equalObjects(a[key], b[key])) { + return false; + } + } + + return true; +} + +module.exports = equalObjects; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvZXF1YWxPYmplY3RzLmpzIl0sIm5hbWVzIjpbInRvU3RyaW5nIiwiT2JqZWN0IiwicHJvdG90eXBlIiwiZXF1YWxPYmplY3RzIiwiYSIsImIiLCJjYWxsIiwiQXJyYXkiLCJpc0FycmF5IiwibGVuZ3RoIiwiaSIsImtleXMiLCJrZXkiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLElBQUlBLFFBQVEsR0FBR0MsTUFBTSxDQUFDQyxTQUFQLENBQWlCRixRQUFoQztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUNBLFNBQVNHLFlBQVQsQ0FBc0JDLENBQXRCLEVBQXlCQyxDQUF6QixFQUE0QjtBQUMxQixNQUFJLE9BQU9ELENBQVAsS0FBYSxPQUFPQyxDQUF4QixFQUEyQjtBQUN6QixXQUFPLEtBQVA7QUFDRDs7QUFDRCxNQUFJLE9BQU9ELENBQVAsS0FBYSxRQUFqQixFQUEyQjtBQUN6QixXQUFPQSxDQUFDLEtBQUtDLENBQWI7QUFDRDs7QUFDRCxNQUFJRCxDQUFDLEtBQUtDLENBQVYsRUFBYTtBQUNYLFdBQU8sSUFBUDtBQUNEOztBQUNELE1BQUlMLFFBQVEsQ0FBQ00sSUFBVCxDQUFjRixDQUFkLE1BQXFCLGVBQXpCLEVBQTBDO0FBQ3hDLFFBQUlKLFFBQVEsQ0FBQ00sSUFBVCxDQUFjRCxDQUFkLE1BQXFCLGVBQXpCLEVBQTBDO0FBQ3hDLGFBQU8sQ0FBQ0QsQ0FBRCxLQUFPLENBQUNDLENBQWY7QUFDRDs7QUFDRCxXQUFPLEtBQVA7QUFDRDs7QUFDRCxNQUFJRSxLQUFLLENBQUNDLE9BQU4sQ0FBY0osQ0FBZCxDQUFKLEVBQXNCO0FBQ3BCLFFBQUlHLEtBQUssQ0FBQ0MsT0FBTixDQUFjSCxDQUFkLENBQUosRUFBc0I7QUFDcEIsVUFBSUQsQ0FBQyxDQUFDSyxNQUFGLEtBQWFKLENBQUMsQ0FBQ0ksTUFBbkIsRUFBMkI7QUFDekIsZUFBTyxLQUFQO0FBQ0Q7O0FBQ0QsV0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHTixDQUFDLENBQUNLLE1BQXRCLEVBQThCQyxDQUFDLEVBQS9CLEVBQW1DO0FBQ2pDLFlBQUksQ0FBQ1AsWUFBWSxDQUFDQyxDQUFDLENBQUNNLENBQUQsQ0FBRixFQUFPTCxDQUFDLENBQUNLLENBQUQsQ0FBUixDQUFqQixFQUErQjtBQUM3QixpQkFBTyxLQUFQO0FBQ0Q7QUFDRjs7QUFDRCxhQUFPLElBQVA7QUFDRDs7QUFDRCxXQUFPLEtBQVA7QUFDRDs7QUFDRCxNQUFJVCxNQUFNLENBQUNVLElBQVAsQ0FBWVAsQ0FBWixFQUFlSyxNQUFmLEtBQTBCUixNQUFNLENBQUNVLElBQVAsQ0FBWU4sQ0FBWixFQUFlSSxNQUE3QyxFQUFxRDtBQUNuRCxXQUFPLEtBQVA7QUFDRDs7QUFDRCxPQUFLLElBQUlHLEdBQVQsSUFBZ0JSLENBQWhCLEVBQW1CO0FBQ2pCLFFBQUksQ0FBQ0QsWUFBWSxDQUFDQyxDQUFDLENBQUNRLEdBQUQsQ0FBRixFQUFTUCxDQUFDLENBQUNPLEdBQUQsQ0FBVixDQUFqQixFQUFtQztBQUNqQyxhQUFPLEtBQVA7QUFDRDtBQUNGOztBQUNELFNBQU8sSUFBUDtBQUNEOztBQUVEQyxNQUFNLENBQUNDLE9BQVAsR0FBaUJYLFlBQWpCIiwic291cmNlc0NvbnRlbnQiOlsidmFyIHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxuLyoqXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgdHdvIG9iamVjdHMgcmVwcmVzZW50IHRoZSBzYW1lIHByaW1pdGl2ZSwgc3BlY2lhbCBQYXJzZVxuICogdHlwZSwgb3IgZnVsbCBQYXJzZSBPYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGVxdWFsT2JqZWN0cyhhLCBiKSB7XG4gIGlmICh0eXBlb2YgYSAhPT0gdHlwZW9mIGIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHR5cGVvZiBhICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBhID09PSBiO1xuICB9XG4gIGlmIChhID09PSBiKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKHRvU3RyaW5nLmNhbGwoYSkgPT09ICdbb2JqZWN0IERhdGVdJykge1xuICAgIGlmICh0b1N0cmluZy5jYWxsKGIpID09PSAnW29iamVjdCBEYXRlXScpIHtcbiAgICAgIHJldHVybiArYSA9PT0gK2I7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoQXJyYXkuaXNBcnJheShhKSkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGIpKSB7XG4gICAgICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoIWVxdWFsT2JqZWN0cyhhW2ldLCBiW2ldKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoT2JqZWN0LmtleXMoYSkubGVuZ3RoICE9PSBPYmplY3Qua2V5cyhiKS5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgZm9yICh2YXIga2V5IGluIGEpIHtcbiAgICBpZiAoIWVxdWFsT2JqZWN0cyhhW2tleV0sIGJba2V5XSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXF1YWxPYmplY3RzO1xuIl19 \ No newline at end of file diff --git a/lib/Options/Definitions.js b/lib/Options/Definitions.js new file mode 100644 index 0000000000..b2a74cfae1 --- /dev/null +++ b/lib/Options/Definitions.js @@ -0,0 +1,715 @@ +"use strict"; + +/* +**** GENERATED CODE **** +This code has been generated by resources/buildConfigDefinitions.js +Do not edit manually, but update Options/index.js +*/ +var parsers = require('./parsers'); + +module.exports.ParseServerOptions = { + accountLockout: { + env: 'PARSE_SERVER_ACCOUNT_LOCKOUT', + help: 'account lockout policy for failed login attempts', + action: parsers.objectParser + }, + allowClientClassCreation: { + env: 'PARSE_SERVER_ALLOW_CLIENT_CLASS_CREATION', + help: 'Enable (or disable) client class creation, defaults to true', + action: parsers.booleanParser, + default: true + }, + allowCustomObjectId: { + env: 'PARSE_SERVER_ALLOW_CUSTOM_OBJECT_ID', + help: 'Enable (or disable) custom objectId', + action: parsers.booleanParser, + default: false + }, + allowHeaders: { + env: 'PARSE_SERVER_ALLOW_HEADERS', + help: 'Add headers to Access-Control-Allow-Headers', + action: parsers.arrayParser + }, + allowOrigin: { + env: 'PARSE_SERVER_ALLOW_ORIGIN', + help: 'Sets the origin to Access-Control-Allow-Origin' + }, + analyticsAdapter: { + env: 'PARSE_SERVER_ANALYTICS_ADAPTER', + help: 'Adapter module for the analytics', + action: parsers.moduleOrObjectParser + }, + appId: { + env: 'PARSE_SERVER_APPLICATION_ID', + help: 'Your Parse Application ID', + required: true + }, + appName: { + env: 'PARSE_SERVER_APP_NAME', + help: 'Sets the app name' + }, + auth: { + env: 'PARSE_SERVER_AUTH_PROVIDERS', + help: 'Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication', + action: parsers.objectParser + }, + cacheAdapter: { + env: 'PARSE_SERVER_CACHE_ADAPTER', + help: 'Adapter module for the cache', + action: parsers.moduleOrObjectParser + }, + cacheMaxSize: { + env: 'PARSE_SERVER_CACHE_MAX_SIZE', + help: 'Sets the maximum size for the in memory cache, defaults to 10000', + action: parsers.numberParser('cacheMaxSize'), + default: 10000 + }, + cacheTTL: { + env: 'PARSE_SERVER_CACHE_TTL', + help: 'Sets the TTL for the in memory cache (in ms), defaults to 5000 (5 seconds)', + action: parsers.numberParser('cacheTTL'), + default: 5000 + }, + clientKey: { + env: 'PARSE_SERVER_CLIENT_KEY', + help: 'Key for iOS, MacOS, tvOS clients' + }, + cloud: { + env: 'PARSE_SERVER_CLOUD', + help: 'Full path to your cloud code main.js' + }, + cluster: { + env: 'PARSE_SERVER_CLUSTER', + help: 'Run with cluster, optionally set the number of processes default to os.cpus().length', + action: parsers.numberOrBooleanParser + }, + collectionPrefix: { + env: 'PARSE_SERVER_COLLECTION_PREFIX', + help: 'A collection prefix for the classes', + default: '' + }, + customPages: { + env: 'PARSE_SERVER_CUSTOM_PAGES', + help: 'custom pages for password validation and reset', + action: parsers.objectParser, + default: {} + }, + databaseAdapter: { + env: 'PARSE_SERVER_DATABASE_ADAPTER', + help: 'Adapter module for the database', + action: parsers.moduleOrObjectParser + }, + databaseOptions: { + env: 'PARSE_SERVER_DATABASE_OPTIONS', + help: 'Options to pass to the mongodb client', + action: parsers.objectParser + }, + databaseURI: { + env: 'PARSE_SERVER_DATABASE_URI', + help: 'The full URI to your database. Supported databases are mongodb or postgres.', + required: true, + default: 'mongodb://localhost:27017/parse' + }, + directAccess: { + env: 'PARSE_SERVER_ENABLE_EXPERIMENTAL_DIRECT_ACCESS', + help: 'Replace HTTP Interface when using JS SDK in current node runtime, defaults to false. Caution, this is an experimental feature that may not be appropriate for production.', + action: parsers.booleanParser, + default: false + }, + dotNetKey: { + env: 'PARSE_SERVER_DOT_NET_KEY', + help: 'Key for Unity and .Net SDK' + }, + emailAdapter: { + env: 'PARSE_SERVER_EMAIL_ADAPTER', + help: 'Adapter module for email sending', + action: parsers.moduleOrObjectParser + }, + emailVerifyTokenReuseIfValid: { + env: 'PARSE_SERVER_EMAIL_VERIFY_TOKEN_REUSE_IF_VALID', + help: 'an existing email verify token should be reused when resend verification email is requested', + action: parsers.booleanParser, + default: false + }, + emailVerifyTokenValidityDuration: { + env: 'PARSE_SERVER_EMAIL_VERIFY_TOKEN_VALIDITY_DURATION', + help: 'Email verification token validity duration, in seconds', + action: parsers.numberParser('emailVerifyTokenValidityDuration') + }, + enableAnonymousUsers: { + env: 'PARSE_SERVER_ENABLE_ANON_USERS', + help: 'Enable (or disable) anonymous users, defaults to true', + action: parsers.booleanParser, + default: true + }, + enableExpressErrorHandler: { + env: 'PARSE_SERVER_ENABLE_EXPRESS_ERROR_HANDLER', + help: 'Enables the default express error handler for all errors', + action: parsers.booleanParser, + default: false + }, + enableSingleSchemaCache: { + env: 'PARSE_SERVER_ENABLE_SINGLE_SCHEMA_CACHE', + help: 'Use a single schema cache shared across requests. Reduces number of queries made to _SCHEMA, defaults to false, i.e. unique schema cache per request.', + action: parsers.booleanParser, + default: false + }, + encryptionKey: { + env: 'PARSE_SERVER_ENCRYPTION_KEY', + help: 'Key for encrypting your files' + }, + expireInactiveSessions: { + env: 'PARSE_SERVER_EXPIRE_INACTIVE_SESSIONS', + help: 'Sets wether we should expire the inactive sessions, defaults to true', + action: parsers.booleanParser, + default: true + }, + fileKey: { + env: 'PARSE_SERVER_FILE_KEY', + help: 'Key for your files' + }, + filesAdapter: { + env: 'PARSE_SERVER_FILES_ADAPTER', + help: 'Adapter module for the files sub-system', + action: parsers.moduleOrObjectParser + }, + fileUpload: { + env: 'PARSE_SERVER_FILE_UPLOAD_OPTIONS', + help: 'Options for file uploads', + action: parsers.objectParser, + default: {} + }, + graphQLPath: { + env: 'PARSE_SERVER_GRAPHQL_PATH', + help: 'Mount path for the GraphQL endpoint, defaults to /graphql', + default: '/graphql' + }, + graphQLSchema: { + env: 'PARSE_SERVER_GRAPH_QLSCHEMA', + help: 'Full path to your GraphQL custom schema.graphql file' + }, + host: { + env: 'PARSE_SERVER_HOST', + help: 'The host to serve ParseServer on, defaults to 0.0.0.0', + default: '0.0.0.0' + }, + idempotencyOptions: { + env: 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_OPTIONS', + help: 'Options for request idempotency to deduplicate identical requests that may be caused by network issues. Caution, this is an experimental feature that may not be appropriate for production.', + action: parsers.objectParser, + default: {} + }, + javascriptKey: { + env: 'PARSE_SERVER_JAVASCRIPT_KEY', + help: 'Key for the Javascript SDK' + }, + jsonLogs: { + env: 'JSON_LOGS', + help: 'Log as structured JSON objects', + action: parsers.booleanParser + }, + liveQuery: { + env: 'PARSE_SERVER_LIVE_QUERY', + help: "parse-server's LiveQuery configuration object", + action: parsers.objectParser + }, + liveQueryServerOptions: { + env: 'PARSE_SERVER_LIVE_QUERY_SERVER_OPTIONS', + help: 'Live query server configuration options (will start the liveQuery server)', + action: parsers.objectParser + }, + loggerAdapter: { + env: 'PARSE_SERVER_LOGGER_ADAPTER', + help: 'Adapter module for the logging sub-system', + action: parsers.moduleOrObjectParser + }, + logLevel: { + env: 'PARSE_SERVER_LOG_LEVEL', + help: 'Sets the level for logs' + }, + logsFolder: { + env: 'PARSE_SERVER_LOGS_FOLDER', + help: "Folder for the logs (defaults to './logs'); set to null to disable file based logging", + default: './logs' + }, + masterKey: { + env: 'PARSE_SERVER_MASTER_KEY', + help: 'Your Parse Master Key', + required: true + }, + masterKeyIps: { + env: 'PARSE_SERVER_MASTER_KEY_IPS', + help: 'Restrict masterKey to be used by only these ips, defaults to [] (allow all ips)', + action: parsers.arrayParser, + default: [] + }, + maxLimit: { + env: 'PARSE_SERVER_MAX_LIMIT', + help: 'Max value for limit option on queries, defaults to unlimited', + action: parsers.numberParser('maxLimit') + }, + maxLogFiles: { + env: 'PARSE_SERVER_MAX_LOG_FILES', + help: "Maximum number of logs to keep. If not set, no logs will be removed. This can be a number of files or number of days. If using days, add 'd' as the suffix. (default: null)", + action: parsers.objectParser + }, + maxUploadSize: { + env: 'PARSE_SERVER_MAX_UPLOAD_SIZE', + help: 'Max file size for uploads, defaults to 20mb', + default: '20mb' + }, + middleware: { + env: 'PARSE_SERVER_MIDDLEWARE', + help: 'middleware for express server, can be string or function' + }, + mountGraphQL: { + env: 'PARSE_SERVER_MOUNT_GRAPHQL', + help: 'Mounts the GraphQL endpoint', + action: parsers.booleanParser, + default: false + }, + mountPath: { + env: 'PARSE_SERVER_MOUNT_PATH', + help: 'Mount path for the server, defaults to /parse', + default: '/parse' + }, + mountPlayground: { + env: 'PARSE_SERVER_MOUNT_PLAYGROUND', + help: 'Mounts the GraphQL Playground - never use this option in production', + action: parsers.booleanParser, + default: false + }, + objectIdSize: { + env: 'PARSE_SERVER_OBJECT_ID_SIZE', + help: "Sets the number of characters in generated object id's, default 10", + action: parsers.numberParser('objectIdSize'), + default: 10 + }, + pages: { + env: 'PARSE_SERVER_PAGES', + help: 'The options for pages such as password reset and email verification. Caution, this is an experimental feature that may not be appropriate for production.', + action: parsers.objectParser, + default: {} + }, + passwordPolicy: { + env: 'PARSE_SERVER_PASSWORD_POLICY', + help: 'Password policy for enforcing password related rules', + action: parsers.objectParser + }, + playgroundPath: { + env: 'PARSE_SERVER_PLAYGROUND_PATH', + help: 'Mount path for the GraphQL Playground, defaults to /playground', + default: '/playground' + }, + port: { + env: 'PORT', + help: 'The port to run the ParseServer, defaults to 1337.', + action: parsers.numberParser('port'), + default: 1337 + }, + preserveFileName: { + env: 'PARSE_SERVER_PRESERVE_FILE_NAME', + help: 'Enable (or disable) the addition of a unique hash to the file names', + action: parsers.booleanParser, + default: false + }, + preventLoginWithUnverifiedEmail: { + env: 'PARSE_SERVER_PREVENT_LOGIN_WITH_UNVERIFIED_EMAIL', + help: 'Prevent user from login if email is not verified and PARSE_SERVER_VERIFY_USER_EMAILS is true, defaults to false', + action: parsers.booleanParser, + default: false + }, + protectedFields: { + env: 'PARSE_SERVER_PROTECTED_FIELDS', + help: 'Protected fields that should be treated with extra security when fetching details.', + action: parsers.objectParser, + default: { + _User: { + '*': ['email'] + } + } + }, + publicServerURL: { + env: 'PARSE_PUBLIC_SERVER_URL', + help: 'Public URL to your parse server with http:// or https://.' + }, + push: { + env: 'PARSE_SERVER_PUSH', + help: 'Configuration for push, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#push-notifications', + action: parsers.objectParser + }, + readOnlyMasterKey: { + env: 'PARSE_SERVER_READ_ONLY_MASTER_KEY', + help: 'Read-only key, which has the same capabilities as MasterKey without writes' + }, + restAPIKey: { + env: 'PARSE_SERVER_REST_API_KEY', + help: 'Key for REST calls' + }, + revokeSessionOnPasswordReset: { + env: 'PARSE_SERVER_REVOKE_SESSION_ON_PASSWORD_RESET', + help: "When a user changes their password, either through the reset password email or while logged in, all sessions are revoked if this is true. Set to false if you don't want to revoke sessions.", + action: parsers.booleanParser, + default: true + }, + scheduledPush: { + env: 'PARSE_SERVER_SCHEDULED_PUSH', + help: 'Configuration for push scheduling, defaults to false.', + action: parsers.booleanParser, + default: false + }, + schemaCacheTTL: { + env: 'PARSE_SERVER_SCHEMA_CACHE_TTL', + help: 'The TTL for caching the schema for optimizing read/write operations. You should put a long TTL when your DB is in production. default to 5000; set 0 to disable.', + action: parsers.numberParser('schemaCacheTTL'), + default: 5000 + }, + serverCloseComplete: { + env: 'PARSE_SERVER_SERVER_CLOSE_COMPLETE', + help: 'Callback when server has closed' + }, + serverStartComplete: { + env: 'PARSE_SERVER_SERVER_START_COMPLETE', + help: 'Callback when server has started' + }, + serverURL: { + env: 'PARSE_SERVER_URL', + help: 'URL to your parse server with http:// or https://.', + required: true + }, + sessionLength: { + env: 'PARSE_SERVER_SESSION_LENGTH', + help: 'Session duration, in seconds, defaults to 1 year', + action: parsers.numberParser('sessionLength'), + default: 31536000 + }, + silent: { + env: 'SILENT', + help: 'Disables console output', + action: parsers.booleanParser + }, + startLiveQueryServer: { + env: 'PARSE_SERVER_START_LIVE_QUERY_SERVER', + help: 'Starts the liveQuery server', + action: parsers.booleanParser + }, + userSensitiveFields: { + env: 'PARSE_SERVER_USER_SENSITIVE_FIELDS', + help: 'Personally identifiable information fields in the user table the should be removed for non-authorized users. Deprecated @see protectedFields', + action: parsers.arrayParser + }, + verbose: { + env: 'VERBOSE', + help: 'Set the logging to verbose', + action: parsers.booleanParser + }, + verifyUserEmails: { + env: 'PARSE_SERVER_VERIFY_USER_EMAILS', + help: 'Enable (or disable) user email validation, defaults to false', + action: parsers.booleanParser, + default: false + }, + webhookKey: { + env: 'PARSE_SERVER_WEBHOOK_KEY', + help: 'Key sent with outgoing webhook calls' + } +}; +module.exports.PagesOptions = { + customUrls: { + env: 'PARSE_SERVER_PAGES_CUSTOM_URLS', + help: 'The URLs to the custom pages.', + action: parsers.objectParser, + default: {} + }, + enableLocalization: { + env: 'PARSE_SERVER_PAGES_ENABLE_LOCALIZATION', + help: 'Is true if pages should be localized; this has no effect on custom page redirects.', + action: parsers.booleanParser, + default: false + }, + enableRouter: { + env: 'PARSE_SERVER_PAGES_ENABLE_ROUTER', + help: 'Is true if the pages router should be enabled; this is required for any of the pages options to take effect. Caution, this is an experimental feature that may not be appropriate for production.', + action: parsers.booleanParser, + default: false + }, + forceRedirect: { + env: 'PARSE_SERVER_PAGES_FORCE_REDIRECT', + help: 'Is true if responses should always be redirects and never content, false if the response type should depend on the request type (GET request -> content response; POST request -> redirect response).', + action: parsers.booleanParser, + default: false + }, + localizationFallbackLocale: { + env: 'PARSE_SERVER_PAGES_LOCALIZATION_FALLBACK_LOCALE', + help: 'The fallback locale for localization if no matching translation is provided for the given locale. This is only relevant when providing translation resources via JSON file.', + default: 'en' + }, + localizationJsonPath: { + env: 'PARSE_SERVER_PAGES_LOCALIZATION_JSON_PATH', + help: 'The path to the JSON file for localization; the translations will be used to fill template placeholders according to the locale.' + }, + pagesEndpoint: { + env: 'PARSE_SERVER_PAGES_PAGES_ENDPOINT', + help: "The API endpoint for the pages. Default is 'apps'.", + default: 'apps' + }, + pagesPath: { + env: 'PARSE_SERVER_PAGES_PAGES_PATH', + help: "The path to the pages directory; this also defines where the static endpoint '/apps' points to. Default is the './public/' directory.", + default: './public' + }, + placeholders: { + env: 'PARSE_SERVER_PAGES_PLACEHOLDERS', + help: 'The placeholder keys and values which will be filled in pages; this can be a simple object or a callback function.', + action: parsers.objectParser, + default: {} + } +}; +module.exports.PagesCustomUrlsOptions = { + emailVerificationLinkExpired: { + env: 'PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_LINK_EXPIRED', + help: 'The URL to the custom page for email verification -> link expired.' + }, + emailVerificationLinkInvalid: { + env: 'PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_LINK_INVALID', + help: 'The URL to the custom page for email verification -> link invalid.' + }, + emailVerificationSendFail: { + env: 'PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_SEND_FAIL', + help: 'The URL to the custom page for email verification -> link send fail.' + }, + emailVerificationSendSuccess: { + env: 'PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_SEND_SUCCESS', + help: 'The URL to the custom page for email verification -> resend link -> success.' + }, + emailVerificationSuccess: { + env: 'PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_SUCCESS', + help: 'The URL to the custom page for email verification -> success.' + }, + passwordReset: { + env: 'PARSE_SERVER_PAGES_CUSTOM_URL_PASSWORD_RESET', + help: 'The URL to the custom page for password reset.' + }, + passwordResetLinkInvalid: { + env: 'PARSE_SERVER_PAGES_CUSTOM_URL_PASSWORD_RESET_LINK_INVALID', + help: 'The URL to the custom page for password reset -> link invalid.' + }, + passwordResetSuccess: { + env: 'PARSE_SERVER_PAGES_CUSTOM_URL_PASSWORD_RESET_SUCCESS', + help: 'The URL to the custom page for password reset -> success.' + } +}; +module.exports.CustomPagesOptions = { + choosePassword: { + env: 'PARSE_SERVER_CUSTOM_PAGES_CHOOSE_PASSWORD', + help: 'choose password page path' + }, + expiredVerificationLink: { + env: 'PARSE_SERVER_CUSTOM_PAGES_EXPIRED_VERIFICATION_LINK', + help: 'expired verification link page path' + }, + invalidLink: { + env: 'PARSE_SERVER_CUSTOM_PAGES_INVALID_LINK', + help: 'invalid link page path' + }, + invalidPasswordResetLink: { + env: 'PARSE_SERVER_CUSTOM_PAGES_INVALID_PASSWORD_RESET_LINK', + help: 'invalid password reset link page path' + }, + invalidVerificationLink: { + env: 'PARSE_SERVER_CUSTOM_PAGES_INVALID_VERIFICATION_LINK', + help: 'invalid verification link page path' + }, + linkSendFail: { + env: 'PARSE_SERVER_CUSTOM_PAGES_LINK_SEND_FAIL', + help: 'verification link send fail page path' + }, + linkSendSuccess: { + env: 'PARSE_SERVER_CUSTOM_PAGES_LINK_SEND_SUCCESS', + help: 'verification link send success page path' + }, + parseFrameURL: { + env: 'PARSE_SERVER_CUSTOM_PAGES_PARSE_FRAME_URL', + help: 'for masking user-facing pages' + }, + passwordResetSuccess: { + env: 'PARSE_SERVER_CUSTOM_PAGES_PASSWORD_RESET_SUCCESS', + help: 'password reset success page path' + }, + verifyEmailSuccess: { + env: 'PARSE_SERVER_CUSTOM_PAGES_VERIFY_EMAIL_SUCCESS', + help: 'verify email success page path' + } +}; +module.exports.LiveQueryOptions = { + classNames: { + env: 'PARSE_SERVER_LIVEQUERY_CLASSNAMES', + help: "parse-server's LiveQuery classNames", + action: parsers.arrayParser + }, + pubSubAdapter: { + env: 'PARSE_SERVER_LIVEQUERY_PUB_SUB_ADAPTER', + help: 'LiveQuery pubsub adapter', + action: parsers.moduleOrObjectParser + }, + redisOptions: { + env: 'PARSE_SERVER_LIVEQUERY_REDIS_OPTIONS', + help: "parse-server's LiveQuery redisOptions", + action: parsers.objectParser + }, + redisURL: { + env: 'PARSE_SERVER_LIVEQUERY_REDIS_URL', + help: "parse-server's LiveQuery redisURL" + }, + wssAdapter: { + env: 'PARSE_SERVER_LIVEQUERY_WSS_ADAPTER', + help: 'Adapter module for the WebSocketServer', + action: parsers.moduleOrObjectParser + } +}; +module.exports.LiveQueryServerOptions = { + appId: { + env: 'PARSE_LIVE_QUERY_SERVER_APP_ID', + help: 'This string should match the appId in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same appId.' + }, + cacheTimeout: { + env: 'PARSE_LIVE_QUERY_SERVER_CACHE_TIMEOUT', + help: "Number in milliseconds. When clients provide the sessionToken to the LiveQuery server, the LiveQuery server will try to fetch its ParseUser's objectId from parse server and store it in the cache. The value defines the duration of the cache. Check the following Security section and our protocol specification for details, defaults to 5 * 1000 ms (5 seconds).", + action: parsers.numberParser('cacheTimeout') + }, + keyPairs: { + env: 'PARSE_LIVE_QUERY_SERVER_KEY_PAIRS', + help: 'A JSON object that serves as a whitelist of keys. It is used for validating clients when they try to connect to the LiveQuery server. Check the following Security section and our protocol specification for details.', + action: parsers.objectParser + }, + logLevel: { + env: 'PARSE_LIVE_QUERY_SERVER_LOG_LEVEL', + help: 'This string defines the log level of the LiveQuery server. We support VERBOSE, INFO, ERROR, NONE, defaults to INFO.' + }, + masterKey: { + env: 'PARSE_LIVE_QUERY_SERVER_MASTER_KEY', + help: 'This string should match the masterKey in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same masterKey.' + }, + port: { + env: 'PARSE_LIVE_QUERY_SERVER_PORT', + help: 'The port to run the LiveQuery server, defaults to 1337.', + action: parsers.numberParser('port'), + default: 1337 + }, + pubSubAdapter: { + env: 'PARSE_LIVE_QUERY_SERVER_PUB_SUB_ADAPTER', + help: 'LiveQuery pubsub adapter', + action: parsers.moduleOrObjectParser + }, + redisOptions: { + env: 'PARSE_LIVE_QUERY_SERVER_REDIS_OPTIONS', + help: "parse-server's LiveQuery redisOptions", + action: parsers.objectParser + }, + redisURL: { + env: 'PARSE_LIVE_QUERY_SERVER_REDIS_URL', + help: "parse-server's LiveQuery redisURL" + }, + serverURL: { + env: 'PARSE_LIVE_QUERY_SERVER_SERVER_URL', + help: 'This string should match the serverURL in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same serverURL.' + }, + websocketTimeout: { + env: 'PARSE_LIVE_QUERY_SERVER_WEBSOCKET_TIMEOUT', + help: 'Number of milliseconds between ping/pong frames. The WebSocket server sends ping/pong frames to the clients to keep the WebSocket alive. This value defines the interval of the ping/pong frame from the server to clients, defaults to 10 * 1000 ms (10 s).', + action: parsers.numberParser('websocketTimeout') + }, + wssAdapter: { + env: 'PARSE_LIVE_QUERY_SERVER_WSS_ADAPTER', + help: 'Adapter module for the WebSocketServer', + action: parsers.moduleOrObjectParser + } +}; +module.exports.IdempotencyOptions = { + paths: { + env: 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_PATHS', + help: 'An array of paths for which the feature should be enabled. The mount path must not be included, for example instead of `/parse/functions/myFunction` specifiy `functions/myFunction`. The entries are interpreted as regular expression, for example `functions/.*` matches all functions, `jobs/.*` matches all jobs, `classes/.*` matches all classes, `.*` matches all paths.', + action: parsers.arrayParser, + default: [] + }, + ttl: { + env: 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_TTL', + help: 'The duration in seconds after which a request record is discarded from the database, defaults to 300s.', + action: parsers.numberParser('ttl'), + default: 300 + } +}; +module.exports.AccountLockoutOptions = { + duration: { + env: 'PARSE_SERVER_ACCOUNT_LOCKOUT_DURATION', + help: 'number of minutes that a locked-out account remains locked out before automatically becoming unlocked.', + action: parsers.numberParser('duration') + }, + threshold: { + env: 'PARSE_SERVER_ACCOUNT_LOCKOUT_THRESHOLD', + help: 'number of failed sign-in attempts that will cause a user account to be locked', + action: parsers.numberParser('threshold') + }, + unlockOnPasswordReset: { + env: 'PARSE_SERVER_ACCOUNT_LOCKOUT_UNLOCK_ON_PASSWORD_RESET', + help: 'Is true if the account lock should be removed after a successful password reset.', + action: parsers.booleanParser, + default: false + } +}; +module.exports.PasswordPolicyOptions = { + doNotAllowUsername: { + env: 'PARSE_SERVER_PASSWORD_POLICY_DO_NOT_ALLOW_USERNAME', + help: 'disallow username in passwords', + action: parsers.booleanParser + }, + maxPasswordAge: { + env: 'PARSE_SERVER_PASSWORD_POLICY_MAX_PASSWORD_AGE', + help: 'days for password expiry', + action: parsers.numberParser('maxPasswordAge') + }, + maxPasswordHistory: { + env: 'PARSE_SERVER_PASSWORD_POLICY_MAX_PASSWORD_HISTORY', + help: 'setting to prevent reuse of previous n passwords', + action: parsers.numberParser('maxPasswordHistory') + }, + resetTokenReuseIfValid: { + env: 'PARSE_SERVER_PASSWORD_POLICY_RESET_TOKEN_REUSE_IF_VALID', + help: "resend token if it's still valid", + action: parsers.booleanParser + }, + resetTokenValidityDuration: { + env: 'PARSE_SERVER_PASSWORD_POLICY_RESET_TOKEN_VALIDITY_DURATION', + help: 'time for token to expire', + action: parsers.numberParser('resetTokenValidityDuration') + }, + validatorCallback: { + env: 'PARSE_SERVER_PASSWORD_POLICY_VALIDATOR_CALLBACK', + help: 'a callback function to be invoked to validate the password' + }, + validatorPattern: { + env: 'PARSE_SERVER_PASSWORD_POLICY_VALIDATOR_PATTERN', + help: 'a RegExp object or a regex string representing the pattern to enforce' + } +}; +module.exports.FileUploadOptions = { + enableForAnonymousUser: { + env: 'PARSE_SERVER_FILE_UPLOAD_ENABLE_FOR_ANONYMOUS_USER', + help: 'Is true if file upload should be allowed for anonymous users.', + action: parsers.booleanParser, + default: false + }, + enableForAuthenticatedUser: { + env: 'PARSE_SERVER_FILE_UPLOAD_ENABLE_FOR_AUTHENTICATED_USER', + help: 'Is true if file upload should be allowed for authenticated users.', + action: parsers.booleanParser, + default: true + }, + enableForPublic: { + env: 'PARSE_SERVER_FILE_UPLOAD_ENABLE_FOR_PUBLIC', + help: 'Is true if file upload should be allowed for anyone, regardless of user authentication.', + action: parsers.booleanParser, + default: false + } +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9PcHRpb25zL0RlZmluaXRpb25zLmpzIl0sIm5hbWVzIjpbInBhcnNlcnMiLCJyZXF1aXJlIiwibW9kdWxlIiwiZXhwb3J0cyIsIlBhcnNlU2VydmVyT3B0aW9ucyIsImFjY291bnRMb2Nrb3V0IiwiZW52IiwiaGVscCIsImFjdGlvbiIsIm9iamVjdFBhcnNlciIsImFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbiIsImJvb2xlYW5QYXJzZXIiLCJkZWZhdWx0IiwiYWxsb3dDdXN0b21PYmplY3RJZCIsImFsbG93SGVhZGVycyIsImFycmF5UGFyc2VyIiwiYWxsb3dPcmlnaW4iLCJhbmFseXRpY3NBZGFwdGVyIiwibW9kdWxlT3JPYmplY3RQYXJzZXIiLCJhcHBJZCIsInJlcXVpcmVkIiwiYXBwTmFtZSIsImF1dGgiLCJjYWNoZUFkYXB0ZXIiLCJjYWNoZU1heFNpemUiLCJudW1iZXJQYXJzZXIiLCJjYWNoZVRUTCIsImNsaWVudEtleSIsImNsb3VkIiwiY2x1c3RlciIsIm51bWJlck9yQm9vbGVhblBhcnNlciIsImNvbGxlY3Rpb25QcmVmaXgiLCJjdXN0b21QYWdlcyIsImRhdGFiYXNlQWRhcHRlciIsImRhdGFiYXNlT3B0aW9ucyIsImRhdGFiYXNlVVJJIiwiZGlyZWN0QWNjZXNzIiwiZG90TmV0S2V5IiwiZW1haWxBZGFwdGVyIiwiZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZCIsImVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uIiwiZW5hYmxlQW5vbnltb3VzVXNlcnMiLCJlbmFibGVFeHByZXNzRXJyb3JIYW5kbGVyIiwiZW5hYmxlU2luZ2xlU2NoZW1hQ2FjaGUiLCJlbmNyeXB0aW9uS2V5IiwiZXhwaXJlSW5hY3RpdmVTZXNzaW9ucyIsImZpbGVLZXkiLCJmaWxlc0FkYXB0ZXIiLCJmaWxlVXBsb2FkIiwiZ3JhcGhRTFBhdGgiLCJncmFwaFFMU2NoZW1hIiwiaG9zdCIsImlkZW1wb3RlbmN5T3B0aW9ucyIsImphdmFzY3JpcHRLZXkiLCJqc29uTG9ncyIsImxpdmVRdWVyeSIsImxpdmVRdWVyeVNlcnZlck9wdGlvbnMiLCJsb2dnZXJBZGFwdGVyIiwibG9nTGV2ZWwiLCJsb2dzRm9sZGVyIiwibWFzdGVyS2V5IiwibWFzdGVyS2V5SXBzIiwibWF4TGltaXQiLCJtYXhMb2dGaWxlcyIsIm1heFVwbG9hZFNpemUiLCJtaWRkbGV3YXJlIiwibW91bnRHcmFwaFFMIiwibW91bnRQYXRoIiwibW91bnRQbGF5Z3JvdW5kIiwib2JqZWN0SWRTaXplIiwicGFnZXMiLCJwYXNzd29yZFBvbGljeSIsInBsYXlncm91bmRQYXRoIiwicG9ydCIsInByZXNlcnZlRmlsZU5hbWUiLCJwcmV2ZW50TG9naW5XaXRoVW52ZXJpZmllZEVtYWlsIiwicHJvdGVjdGVkRmllbGRzIiwiX1VzZXIiLCJwdWJsaWNTZXJ2ZXJVUkwiLCJwdXNoIiwicmVhZE9ubHlNYXN0ZXJLZXkiLCJyZXN0QVBJS2V5IiwicmV2b2tlU2Vzc2lvbk9uUGFzc3dvcmRSZXNldCIsInNjaGVkdWxlZFB1c2giLCJzY2hlbWFDYWNoZVRUTCIsInNlcnZlckNsb3NlQ29tcGxldGUiLCJzZXJ2ZXJTdGFydENvbXBsZXRlIiwic2VydmVyVVJMIiwic2Vzc2lvbkxlbmd0aCIsInNpbGVudCIsInN0YXJ0TGl2ZVF1ZXJ5U2VydmVyIiwidXNlclNlbnNpdGl2ZUZpZWxkcyIsInZlcmJvc2UiLCJ2ZXJpZnlVc2VyRW1haWxzIiwid2ViaG9va0tleSIsIlBhZ2VzT3B0aW9ucyIsImN1c3RvbVVybHMiLCJlbmFibGVMb2NhbGl6YXRpb24iLCJlbmFibGVSb3V0ZXIiLCJmb3JjZVJlZGlyZWN0IiwibG9jYWxpemF0aW9uRmFsbGJhY2tMb2NhbGUiLCJsb2NhbGl6YXRpb25Kc29uUGF0aCIsInBhZ2VzRW5kcG9pbnQiLCJwYWdlc1BhdGgiLCJwbGFjZWhvbGRlcnMiLCJQYWdlc0N1c3RvbVVybHNPcHRpb25zIiwiZW1haWxWZXJpZmljYXRpb25MaW5rRXhwaXJlZCIsImVtYWlsVmVyaWZpY2F0aW9uTGlua0ludmFsaWQiLCJlbWFpbFZlcmlmaWNhdGlvblNlbmRGYWlsIiwiZW1haWxWZXJpZmljYXRpb25TZW5kU3VjY2VzcyIsImVtYWlsVmVyaWZpY2F0aW9uU3VjY2VzcyIsInBhc3N3b3JkUmVzZXQiLCJwYXNzd29yZFJlc2V0TGlua0ludmFsaWQiLCJwYXNzd29yZFJlc2V0U3VjY2VzcyIsIkN1c3RvbVBhZ2VzT3B0aW9ucyIsImNob29zZVBhc3N3b3JkIiwiZXhwaXJlZFZlcmlmaWNhdGlvbkxpbmsiLCJpbnZhbGlkTGluayIsImludmFsaWRQYXNzd29yZFJlc2V0TGluayIsImludmFsaWRWZXJpZmljYXRpb25MaW5rIiwibGlua1NlbmRGYWlsIiwibGlua1NlbmRTdWNjZXNzIiwicGFyc2VGcmFtZVVSTCIsInZlcmlmeUVtYWlsU3VjY2VzcyIsIkxpdmVRdWVyeU9wdGlvbnMiLCJjbGFzc05hbWVzIiwicHViU3ViQWRhcHRlciIsInJlZGlzT3B0aW9ucyIsInJlZGlzVVJMIiwid3NzQWRhcHRlciIsIkxpdmVRdWVyeVNlcnZlck9wdGlvbnMiLCJjYWNoZVRpbWVvdXQiLCJrZXlQYWlycyIsIndlYnNvY2tldFRpbWVvdXQiLCJJZGVtcG90ZW5jeU9wdGlvbnMiLCJwYXRocyIsInR0bCIsIkFjY291bnRMb2Nrb3V0T3B0aW9ucyIsImR1cmF0aW9uIiwidGhyZXNob2xkIiwidW5sb2NrT25QYXNzd29yZFJlc2V0IiwiUGFzc3dvcmRQb2xpY3lPcHRpb25zIiwiZG9Ob3RBbGxvd1VzZXJuYW1lIiwibWF4UGFzc3dvcmRBZ2UiLCJtYXhQYXNzd29yZEhpc3RvcnkiLCJyZXNldFRva2VuUmV1c2VJZlZhbGlkIiwicmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJ2YWxpZGF0b3JDYWxsYmFjayIsInZhbGlkYXRvclBhdHRlcm4iLCJGaWxlVXBsb2FkT3B0aW9ucyIsImVuYWJsZUZvckFub255bW91c1VzZXIiLCJlbmFibGVGb3JBdXRoZW50aWNhdGVkVXNlciIsImVuYWJsZUZvclB1Ymxp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SSxJQUFBQSxHQUFHLEVBQUUsaURBRFk7QUFFakJDLElBQUFBLElBQUksRUFBRTtBQUZXLEdBMUJrQjtBQThCckM2SSxFQUFBQSxnQkFBZ0IsRUFBRTtBQUNoQjlJLElBQUFBLEdBQUcsRUFBRSxnREFEVztBQUVoQkMsSUFBQUEsSUFBSSxFQUFFO0FBRlU7QUE5Qm1CLENBQXZDO0FBbUNBTCxNQUFNLENBQUNDLE9BQVAsQ0FBZWtKLGlCQUFmLEdBQW1DO0FBQ2pDQyxFQUFBQSxzQkFBc0IsRUFBRTtBQUN0QmhKLElBQUFBLEdBQUcsRUFBRSxvREFEaUI7QUFFdEJDLElBQUFBLElBQUksRUFBRSwrREFGZ0I7QUFHdEJDLElBQUFBLE1BQU0sRUFBRVIsT0FBTyxDQUFDVyxhQUhNO0FBSXRCQyxJQUFBQSxPQUFPLEVBQUU7QUFKYSxHQURTO0FBT2pDMkksRUFBQUEsMEJBQTBCLEVBQUU7QUFDMUJqSixJQUFBQSxHQUFHLEVBQUUsd0RBRHFCO0FBRTFCQyxJQUFBQSxJQUFJLEVBQUUsbUVBRm9CO0FBRzFCQyxJQUFBQSxNQUFNLEVBQUVSLE9BQU8sQ0FBQ1csYUFIVTtBQUkxQkMsSUFBQUEsT0FBTyxFQUFFO0FBSmlCLEdBUEs7QUFhakM0SSxFQUFBQSxlQUFlLEVBQUU7QUFDZmxKLElBQUFBLEdBQUcsRUFBRSw0Q0FEVTtBQUVmQyxJQUFBQSxJQUFJLEVBQUUseUZBRlM7QUFHZkMsSUFBQUEsTUFBTSxFQUFFUixPQUFPLENBQUNXLGFBSEQ7QUFJZkMsSUFBQUEsT0FBTyxFQUFFO0FBSk07QUFiZ0IsQ0FBbkMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuKioqKiBHRU5FUkFURUQgQ09ERSAqKioqXG5UaGlzIGNvZGUgaGFzIGJlZW4gZ2VuZXJhdGVkIGJ5IHJlc291cmNlcy9idWlsZENvbmZpZ0RlZmluaXRpb25zLmpzXG5EbyBub3QgZWRpdCBtYW51YWxseSwgYnV0IHVwZGF0ZSBPcHRpb25zL2luZGV4LmpzXG4qL1xudmFyIHBhcnNlcnMgPSByZXF1aXJlKCcuL3BhcnNlcnMnKTtcblxubW9kdWxlLmV4cG9ydHMuUGFyc2VTZXJ2ZXJPcHRpb25zID0ge1xuICBhY2NvdW50TG9ja291dDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9BQ0NPVU5UX0xPQ0tPVVQnLFxuICAgIGhlbHA6ICdhY2NvdW50IGxvY2tvdXQgcG9saWN5IGZvciBmYWlsZWQgbG9naW4gYXR0ZW1wdHMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5vYmplY3RQYXJzZXIsXG4gIH0sXG4gIGFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbjoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9BTExPV19DTElFTlRfQ0xBU1NfQ1JFQVRJT04nLFxuICAgIGhlbHA6ICdFbmFibGUgKG9yIGRpc2FibGUpIGNsaWVudCBjbGFzcyBjcmVhdGlvbiwgZGVmYXVsdHMgdG8gdHJ1ZScsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogdHJ1ZSxcbiAgfSxcbiAgYWxsb3dDdXN0b21PYmplY3RJZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9BTExPV19DVVNUT01fT0JKRUNUX0lEJyxcbiAgICBoZWxwOiAnRW5hYmxlIChvciBkaXNhYmxlKSBjdXN0b20gb2JqZWN0SWQnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IGZhbHNlLFxuICB9LFxuICBhbGxvd0hlYWRlcnM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQUxMT1dfSEVBREVSUycsXG4gICAgaGVscDogJ0FkZCBoZWFkZXJzIHRvIEFjY2Vzcy1Db250cm9sLUFsbG93LUhlYWRlcnMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5hcnJheVBhcnNlcixcbiAgfSxcbiAgYWxsb3dPcmlnaW46IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQUxMT1dfT1JJR0lOJyxcbiAgICBoZWxwOiAnU2V0cyB0aGUgb3JpZ2luIHRvIEFjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbicsXG4gIH0sXG4gIGFuYWx5dGljc0FkYXB0ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQU5BTFlUSUNTX0FEQVBURVInLFxuICAgIGhlbHA6ICdBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGFuYWx5dGljcycsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm1vZHVsZU9yT2JqZWN0UGFyc2VyLFxuICB9LFxuICBhcHBJZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9BUFBMSUNBVElPTl9JRCcsXG4gICAgaGVscDogJ1lvdXIgUGFyc2UgQXBwbGljYXRpb24gSUQnLFxuICAgIHJlcXVpcmVkOiB0cnVlLFxuICB9LFxuICBhcHBOYW1lOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0FQUF9OQU1FJyxcbiAgICBoZWxwOiAnU2V0cyB0aGUgYXBwIG5hbWUnLFxuICB9LFxuICBhdXRoOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0FVVEhfUFJPVklERVJTJyxcbiAgICBoZWxwOlxuICAgICAgJ0NvbmZpZ3VyYXRpb24gZm9yIHlvdXIgYXV0aGVudGljYXRpb24gcHJvdmlkZXJzLCBhcyBzdHJpbmdpZmllZCBKU09OLiBTZWUgaHR0cDovL2RvY3MucGFyc2VwbGF0Zm9ybS5vcmcvcGFyc2Utc2VydmVyL2d1aWRlLyNvYXV0aC1hbmQtM3JkLXBhcnR5LWF1dGhlbnRpY2F0aW9uJyxcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICBjYWNoZUFkYXB0ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ0FDSEVfQURBUFRFUicsXG4gICAgaGVscDogJ0FkYXB0ZXIgbW9kdWxlIGZvciB0aGUgY2FjaGUnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5tb2R1bGVPck9iamVjdFBhcnNlcixcbiAgfSxcbiAgY2FjaGVNYXhTaXplOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0NBQ0hFX01BWF9TSVpFJyxcbiAgICBoZWxwOiAnU2V0cyB0aGUgbWF4aW11bSBzaXplIGZvciB0aGUgaW4gbWVtb3J5IGNhY2hlLCBkZWZhdWx0cyB0byAxMDAwMCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm51bWJlclBhcnNlcignY2FjaGVNYXhTaXplJyksXG4gICAgZGVmYXVsdDogMTAwMDAsXG4gIH0sXG4gIGNhY2hlVFRMOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0NBQ0hFX1RUTCcsXG4gICAgaGVscDogJ1NldHMgdGhlIFRUTCBmb3IgdGhlIGluIG1lbW9yeSBjYWNoZSAoaW4gbXMpLCBkZWZhdWx0cyB0byA1MDAwICg1IHNlY29uZHMpJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCdjYWNoZVRUTCcpLFxuICAgIGRlZmF1bHQ6IDUwMDAsXG4gIH0sXG4gIGNsaWVudEtleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DTElFTlRfS0VZJyxcbiAgICBoZWxwOiAnS2V5IGZvciBpT1MsIE1hY09TLCB0dk9TIGNsaWVudHMnLFxuICB9LFxuICBjbG91ZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DTE9VRCcsXG4gICAgaGVscDogJ0Z1bGwgcGF0aCB0byB5b3VyIGNsb3VkIGNvZGUgbWFpbi5qcycsXG4gIH0sXG4gIGNsdXN0ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ0xVU1RFUicsXG4gICAgaGVscDogJ1J1biB3aXRoIGNsdXN0ZXIsIG9wdGlvbmFsbHkgc2V0IHRoZSBudW1iZXIgb2YgcHJvY2Vzc2VzIGRlZmF1bHQgdG8gb3MuY3B1cygpLmxlbmd0aCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm51bWJlck9yQm9vbGVhblBhcnNlcixcbiAgfSxcbiAgY29sbGVjdGlvblByZWZpeDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DT0xMRUNUSU9OX1BSRUZJWCcsXG4gICAgaGVscDogJ0EgY29sbGVjdGlvbiBwcmVmaXggZm9yIHRoZSBjbGFzc2VzJyxcbiAgICBkZWZhdWx0OiAnJyxcbiAgfSxcbiAgY3VzdG9tUGFnZXM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTJyxcbiAgICBoZWxwOiAnY3VzdG9tIHBhZ2VzIGZvciBwYXNzd29yZCB2YWxpZGF0aW9uIGFuZCByZXNldCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgICBkZWZhdWx0OiB7fSxcbiAgfSxcbiAgZGF0YWJhc2VBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0RBVEFCQVNFX0FEQVBURVInLFxuICAgIGhlbHA6ICdBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGRhdGFiYXNlJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubW9kdWxlT3JPYmplY3RQYXJzZXIsXG4gIH0sXG4gIGRhdGFiYXNlT3B0aW9uczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9EQVRBQkFTRV9PUFRJT05TJyxcbiAgICBoZWxwOiAnT3B0aW9ucyB0byBwYXNzIHRvIHRoZSBtb25nb2RiIGNsaWVudCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgfSxcbiAgZGF0YWJhc2VVUkk6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfREFUQUJBU0VfVVJJJyxcbiAgICBoZWxwOiAnVGhlIGZ1bGwgVVJJIHRvIHlvdXIgZGF0YWJhc2UuIFN1cHBvcnRlZCBkYXRhYmFzZXMgYXJlIG1vbmdvZGIgb3IgcG9zdGdyZXMuJyxcbiAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICBkZWZhdWx0OiAnbW9uZ29kYjovL2xvY2FsaG9zdDoyNzAxNy9wYXJzZScsXG4gIH0sXG4gIGRpcmVjdEFjY2Vzczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9FTkFCTEVfRVhQRVJJTUVOVEFMX0RJUkVDVF9BQ0NFU1MnLFxuICAgIGhlbHA6XG4gICAgICAnUmVwbGFjZSBIVFRQIEludGVyZmFjZSB3aGVuIHVzaW5nIEpTIFNESyBpbiBjdXJyZW50IG5vZGUgcnVudGltZSwgZGVmYXVsdHMgdG8gZmFsc2UuIENhdXRpb24sIHRoaXMgaXMgYW4gZXhwZXJpbWVudGFsIGZlYXR1cmUgdGhhdCBtYXkgbm90IGJlIGFwcHJvcHJpYXRlIGZvciBwcm9kdWN0aW9uLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIGRvdE5ldEtleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9ET1RfTkVUX0tFWScsXG4gICAgaGVscDogJ0tleSBmb3IgVW5pdHkgYW5kIC5OZXQgU0RLJyxcbiAgfSxcbiAgZW1haWxBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VNQUlMX0FEQVBURVInLFxuICAgIGhlbHA6ICdBZGFwdGVyIG1vZHVsZSBmb3IgZW1haWwgc2VuZGluZycsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm1vZHVsZU9yT2JqZWN0UGFyc2VyLFxuICB9LFxuICBlbWFpbFZlcmlmeVRva2VuUmV1c2VJZlZhbGlkOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VNQUlMX1ZFUklGWV9UT0tFTl9SRVVTRV9JRl9WQUxJRCcsXG4gICAgaGVscDpcbiAgICAgICdhbiBleGlzdGluZyBlbWFpbCB2ZXJpZnkgdG9rZW4gc2hvdWxkIGJlIHJldXNlZCB3aGVuIHJlc2VuZCB2ZXJpZmljYXRpb24gZW1haWwgaXMgcmVxdWVzdGVkJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbiAgZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb246IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfRU1BSUxfVkVSSUZZX1RPS0VOX1ZBTElESVRZX0RVUkFUSU9OJyxcbiAgICBoZWxwOiAnRW1haWwgdmVyaWZpY2F0aW9uIHRva2VuIHZhbGlkaXR5IGR1cmF0aW9uLCBpbiBzZWNvbmRzJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCdlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbicpLFxuICB9LFxuICBlbmFibGVBbm9ueW1vdXNVc2Vyczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9FTkFCTEVfQU5PTl9VU0VSUycsXG4gICAgaGVscDogJ0VuYWJsZSAob3IgZGlzYWJsZSkgYW5vbnltb3VzIHVzZXJzLCBkZWZhdWx0cyB0byB0cnVlJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiB0cnVlLFxuICB9LFxuICBlbmFibGVFeHByZXNzRXJyb3JIYW5kbGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VOQUJMRV9FWFBSRVNTX0VSUk9SX0hBTkRMRVInLFxuICAgIGhlbHA6ICdFbmFibGVzIHRoZSBkZWZhdWx0IGV4cHJlc3MgZXJyb3IgaGFuZGxlciBmb3IgYWxsIGVycm9ycycsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIGVuYWJsZVNpbmdsZVNjaGVtYUNhY2hlOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VOQUJMRV9TSU5HTEVfU0NIRU1BX0NBQ0hFJyxcbiAgICBoZWxwOlxuICAgICAgJ1VzZSBhIHNpbmdsZSBzY2hlbWEgY2FjaGUgc2hhcmVkIGFjcm9zcyByZXF1ZXN0cy4gUmVkdWNlcyBudW1iZXIgb2YgcXVlcmllcyBtYWRlIHRvIF9TQ0hFTUEsIGRlZmF1bHRzIHRvIGZhbHNlLCBpLmUuIHVuaXF1ZSBzY2hlbWEgY2FjaGUgcGVyIHJlcXVlc3QuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbiAgZW5jcnlwdGlvbktleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9FTkNSWVBUSU9OX0tFWScsXG4gICAgaGVscDogJ0tleSBmb3IgZW5jcnlwdGluZyB5b3VyIGZpbGVzJyxcbiAgfSxcbiAgZXhwaXJlSW5hY3RpdmVTZXNzaW9uczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9FWFBJUkVfSU5BQ1RJVkVfU0VTU0lPTlMnLFxuICAgIGhlbHA6ICdTZXRzIHdldGhlciB3ZSBzaG91bGQgZXhwaXJlIHRoZSBpbmFjdGl2ZSBzZXNzaW9ucywgZGVmYXVsdHMgdG8gdHJ1ZScsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogdHJ1ZSxcbiAgfSxcbiAgZmlsZUtleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9GSUxFX0tFWScsXG4gICAgaGVscDogJ0tleSBmb3IgeW91ciBmaWxlcycsXG4gIH0sXG4gIGZpbGVzQWRhcHRlcjoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9GSUxFU19BREFQVEVSJyxcbiAgICBoZWxwOiAnQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBmaWxlcyBzdWItc3lzdGVtJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubW9kdWxlT3JPYmplY3RQYXJzZXIsXG4gIH0sXG4gIGZpbGVVcGxvYWQ6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfRklMRV9VUExPQURfT1BUSU9OUycsXG4gICAgaGVscDogJ09wdGlvbnMgZm9yIGZpbGUgdXBsb2FkcycsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgICBkZWZhdWx0OiB7fSxcbiAgfSxcbiAgZ3JhcGhRTFBhdGg6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfR1JBUEhRTF9QQVRIJyxcbiAgICBoZWxwOiAnTW91bnQgcGF0aCBmb3IgdGhlIEdyYXBoUUwgZW5kcG9pbnQsIGRlZmF1bHRzIHRvIC9ncmFwaHFsJyxcbiAgICBkZWZhdWx0OiAnL2dyYXBocWwnLFxuICB9LFxuICBncmFwaFFMU2NoZW1hOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0dSQVBIX1FMU0NIRU1BJyxcbiAgICBoZWxwOiAnRnVsbCBwYXRoIHRvIHlvdXIgR3JhcGhRTCBjdXN0b20gc2NoZW1hLmdyYXBocWwgZmlsZScsXG4gIH0sXG4gIGhvc3Q6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfSE9TVCcsXG4gICAgaGVscDogJ1RoZSBob3N0IHRvIHNlcnZlIFBhcnNlU2VydmVyIG9uLCBkZWZhdWx0cyB0byAwLjAuMC4wJyxcbiAgICBkZWZhdWx0OiAnMC4wLjAuMCcsXG4gIH0sXG4gIGlkZW1wb3RlbmN5T3B0aW9uczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9FWFBFUklNRU5UQUxfSURFTVBPVEVOQ1lfT1BUSU9OUycsXG4gICAgaGVscDpcbiAgICAgICdPcHRpb25zIGZvciByZXF1ZXN0IGlkZW1wb3RlbmN5IHRvIGRlZHVwbGljYXRlIGlkZW50aWNhbCByZXF1ZXN0cyB0aGF0IG1heSBiZSBjYXVzZWQgYnkgbmV0d29yayBpc3N1ZXMuIENhdXRpb24sIHRoaXMgaXMgYW4gZXhwZXJpbWVudGFsIGZlYXR1cmUgdGhhdCBtYXkgbm90IGJlIGFwcHJvcHJpYXRlIGZvciBwcm9kdWN0aW9uLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgICBkZWZhdWx0OiB7fSxcbiAgfSxcbiAgamF2YXNjcmlwdEtleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9KQVZBU0NSSVBUX0tFWScsXG4gICAgaGVscDogJ0tleSBmb3IgdGhlIEphdmFzY3JpcHQgU0RLJyxcbiAgfSxcbiAganNvbkxvZ3M6IHtcbiAgICBlbnY6ICdKU09OX0xPR1MnLFxuICAgIGhlbHA6ICdMb2cgYXMgc3RydWN0dXJlZCBKU09OIG9iamVjdHMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICB9LFxuICBsaXZlUXVlcnk6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTElWRV9RVUVSWScsXG4gICAgaGVscDogXCJwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgY29uZmlndXJhdGlvbiBvYmplY3RcIixcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICBsaXZlUXVlcnlTZXJ2ZXJPcHRpb25zOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xJVkVfUVVFUllfU0VSVkVSX09QVElPTlMnLFxuICAgIGhlbHA6ICdMaXZlIHF1ZXJ5IHNlcnZlciBjb25maWd1cmF0aW9uIG9wdGlvbnMgKHdpbGwgc3RhcnQgdGhlIGxpdmVRdWVyeSBzZXJ2ZXIpJyxcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICBsb2dnZXJBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xPR0dFUl9BREFQVEVSJyxcbiAgICBoZWxwOiAnQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBsb2dnaW5nIHN1Yi1zeXN0ZW0nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5tb2R1bGVPck9iamVjdFBhcnNlcixcbiAgfSxcbiAgbG9nTGV2ZWw6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTE9HX0xFVkVMJyxcbiAgICBoZWxwOiAnU2V0cyB0aGUgbGV2ZWwgZm9yIGxvZ3MnLFxuICB9LFxuICBsb2dzRm9sZGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xPR1NfRk9MREVSJyxcbiAgICBoZWxwOiBcIkZvbGRlciBmb3IgdGhlIGxvZ3MgKGRlZmF1bHRzIHRvICcuL2xvZ3MnKTsgc2V0IHRvIG51bGwgdG8gZGlzYWJsZSBmaWxlIGJhc2VkIGxvZ2dpbmdcIixcbiAgICBkZWZhdWx0OiAnLi9sb2dzJyxcbiAgfSxcbiAgbWFzdGVyS2V5OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX01BU1RFUl9LRVknLFxuICAgIGhlbHA6ICdZb3VyIFBhcnNlIE1hc3RlciBLZXknLFxuICAgIHJlcXVpcmVkOiB0cnVlLFxuICB9LFxuICBtYXN0ZXJLZXlJcHM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTUFTVEVSX0tFWV9JUFMnLFxuICAgIGhlbHA6ICdSZXN0cmljdCBtYXN0ZXJLZXkgdG8gYmUgdXNlZCBieSBvbmx5IHRoZXNlIGlwcywgZGVmYXVsdHMgdG8gW10gKGFsbG93IGFsbCBpcHMpJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYXJyYXlQYXJzZXIsXG4gICAgZGVmYXVsdDogW10sXG4gIH0sXG4gIG1heExpbWl0OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX01BWF9MSU1JVCcsXG4gICAgaGVscDogJ01heCB2YWx1ZSBmb3IgbGltaXQgb3B0aW9uIG9uIHF1ZXJpZXMsIGRlZmF1bHRzIHRvIHVubGltaXRlZCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm51bWJlclBhcnNlcignbWF4TGltaXQnKSxcbiAgfSxcbiAgbWF4TG9nRmlsZXM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTUFYX0xPR19GSUxFUycsXG4gICAgaGVscDpcbiAgICAgIFwiTWF4aW11bSBudW1iZXIgb2YgbG9ncyB0byBrZWVwLiBJZiBub3Qgc2V0LCBubyBsb2dzIHdpbGwgYmUgcmVtb3ZlZC4gVGhpcyBjYW4gYmUgYSBudW1iZXIgb2YgZmlsZXMgb3IgbnVtYmVyIG9mIGRheXMuIElmIHVzaW5nIGRheXMsIGFkZCAnZCcgYXMgdGhlIHN1ZmZpeC4gKGRlZmF1bHQ6IG51bGwpXCIsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgfSxcbiAgbWF4VXBsb2FkU2l6ZToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9NQVhfVVBMT0FEX1NJWkUnLFxuICAgIGhlbHA6ICdNYXggZmlsZSBzaXplIGZvciB1cGxvYWRzLCBkZWZhdWx0cyB0byAyMG1iJyxcbiAgICBkZWZhdWx0OiAnMjBtYicsXG4gIH0sXG4gIG1pZGRsZXdhcmU6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTUlERExFV0FSRScsXG4gICAgaGVscDogJ21pZGRsZXdhcmUgZm9yIGV4cHJlc3Mgc2VydmVyLCBjYW4gYmUgc3RyaW5nIG9yIGZ1bmN0aW9uJyxcbiAgfSxcbiAgbW91bnRHcmFwaFFMOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX01PVU5UX0dSQVBIUUwnLFxuICAgIGhlbHA6ICdNb3VudHMgdGhlIEdyYXBoUUwgZW5kcG9pbnQnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IGZhbHNlLFxuICB9LFxuICBtb3VudFBhdGg6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTU9VTlRfUEFUSCcsXG4gICAgaGVscDogJ01vdW50IHBhdGggZm9yIHRoZSBzZXJ2ZXIsIGRlZmF1bHRzIHRvIC9wYXJzZScsXG4gICAgZGVmYXVsdDogJy9wYXJzZScsXG4gIH0sXG4gIG1vdW50UGxheWdyb3VuZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9NT1VOVF9QTEFZR1JPVU5EJyxcbiAgICBoZWxwOiAnTW91bnRzIHRoZSBHcmFwaFFMIFBsYXlncm91bmQgLSBuZXZlciB1c2UgdGhpcyBvcHRpb24gaW4gcHJvZHVjdGlvbicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIG9iamVjdElkU2l6ZToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9PQkpFQ1RfSURfU0laRScsXG4gICAgaGVscDogXCJTZXRzIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiBnZW5lcmF0ZWQgb2JqZWN0IGlkJ3MsIGRlZmF1bHQgMTBcIixcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCdvYmplY3RJZFNpemUnKSxcbiAgICBkZWZhdWx0OiAxMCxcbiAgfSxcbiAgcGFnZXM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUEFHRVMnLFxuICAgIGhlbHA6XG4gICAgICAnVGhlIG9wdGlvbnMgZm9yIHBhZ2VzIHN1Y2ggYXMgcGFzc3dvcmQgcmVzZXQgYW5kIGVtYWlsIHZlcmlmaWNhdGlvbi4gQ2F1dGlvbiwgdGhpcyBpcyBhbiBleHBlcmltZW50YWwgZmVhdHVyZSB0aGF0IG1heSBub3QgYmUgYXBwcm9wcmlhdGUgZm9yIHByb2R1Y3Rpb24uJyxcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICAgIGRlZmF1bHQ6IHt9LFxuICB9LFxuICBwYXNzd29yZFBvbGljeToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QQVNTV09SRF9QT0xJQ1knLFxuICAgIGhlbHA6ICdQYXNzd29yZCBwb2xpY3kgZm9yIGVuZm9yY2luZyBwYXNzd29yZCByZWxhdGVkIHJ1bGVzJyxcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICBwbGF5Z3JvdW5kUGF0aDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QTEFZR1JPVU5EX1BBVEgnLFxuICAgIGhlbHA6ICdNb3VudCBwYXRoIGZvciB0aGUgR3JhcGhRTCBQbGF5Z3JvdW5kLCBkZWZhdWx0cyB0byAvcGxheWdyb3VuZCcsXG4gICAgZGVmYXVsdDogJy9wbGF5Z3JvdW5kJyxcbiAgfSxcbiAgcG9ydDoge1xuICAgIGVudjogJ1BPUlQnLFxuICAgIGhlbHA6ICdUaGUgcG9ydCB0byBydW4gdGhlIFBhcnNlU2VydmVyLCBkZWZhdWx0cyB0byAxMzM3LicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm51bWJlclBhcnNlcigncG9ydCcpLFxuICAgIGRlZmF1bHQ6IDEzMzcsXG4gIH0sXG4gIHByZXNlcnZlRmlsZU5hbWU6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUFJFU0VSVkVfRklMRV9OQU1FJyxcbiAgICBoZWxwOiAnRW5hYmxlIChvciBkaXNhYmxlKSB0aGUgYWRkaXRpb24gb2YgYSB1bmlxdWUgaGFzaCB0byB0aGUgZmlsZSBuYW1lcycsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIHByZXZlbnRMb2dpbldpdGhVbnZlcmlmaWVkRW1haWw6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUFJFVkVOVF9MT0dJTl9XSVRIX1VOVkVSSUZJRURfRU1BSUwnLFxuICAgIGhlbHA6XG4gICAgICAnUHJldmVudCB1c2VyIGZyb20gbG9naW4gaWYgZW1haWwgaXMgbm90IHZlcmlmaWVkIGFuZCBQQVJTRV9TRVJWRVJfVkVSSUZZX1VTRVJfRU1BSUxTIGlzIHRydWUsIGRlZmF1bHRzIHRvIGZhbHNlJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbiAgcHJvdGVjdGVkRmllbGRzOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BST1RFQ1RFRF9GSUVMRFMnLFxuICAgIGhlbHA6ICdQcm90ZWN0ZWQgZmllbGRzIHRoYXQgc2hvdWxkIGJlIHRyZWF0ZWQgd2l0aCBleHRyYSBzZWN1cml0eSB3aGVuIGZldGNoaW5nIGRldGFpbHMuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICAgIGRlZmF1bHQ6IHtcbiAgICAgIF9Vc2VyOiB7XG4gICAgICAgICcqJzogWydlbWFpbCddLFxuICAgICAgfSxcbiAgICB9LFxuICB9LFxuICBwdWJsaWNTZXJ2ZXJVUkw6IHtcbiAgICBlbnY6ICdQQVJTRV9QVUJMSUNfU0VSVkVSX1VSTCcsXG4gICAgaGVscDogJ1B1YmxpYyBVUkwgdG8geW91ciBwYXJzZSBzZXJ2ZXIgd2l0aCBodHRwOi8vIG9yIGh0dHBzOi8vLicsXG4gIH0sXG4gIHB1c2g6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUFVTSCcsXG4gICAgaGVscDpcbiAgICAgICdDb25maWd1cmF0aW9uIGZvciBwdXNoLCBhcyBzdHJpbmdpZmllZCBKU09OLiBTZWUgaHR0cDovL2RvY3MucGFyc2VwbGF0Zm9ybS5vcmcvcGFyc2Utc2VydmVyL2d1aWRlLyNwdXNoLW5vdGlmaWNhdGlvbnMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5vYmplY3RQYXJzZXIsXG4gIH0sXG4gIHJlYWRPbmx5TWFzdGVyS2V5OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1JFQURfT05MWV9NQVNURVJfS0VZJyxcbiAgICBoZWxwOiAnUmVhZC1vbmx5IGtleSwgd2hpY2ggaGFzIHRoZSBzYW1lIGNhcGFiaWxpdGllcyBhcyBNYXN0ZXJLZXkgd2l0aG91dCB3cml0ZXMnLFxuICB9LFxuICByZXN0QVBJS2V5OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1JFU1RfQVBJX0tFWScsXG4gICAgaGVscDogJ0tleSBmb3IgUkVTVCBjYWxscycsXG4gIH0sXG4gIHJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQ6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUkVWT0tFX1NFU1NJT05fT05fUEFTU1dPUkRfUkVTRVQnLFxuICAgIGhlbHA6XG4gICAgICBcIldoZW4gYSB1c2VyIGNoYW5nZXMgdGhlaXIgcGFzc3dvcmQsIGVpdGhlciB0aHJvdWdoIHRoZSByZXNldCBwYXNzd29yZCBlbWFpbCBvciB3aGlsZSBsb2dnZWQgaW4sIGFsbCBzZXNzaW9ucyBhcmUgcmV2b2tlZCBpZiB0aGlzIGlzIHRydWUuIFNldCB0byBmYWxzZSBpZiB5b3UgZG9uJ3Qgd2FudCB0byByZXZva2Ugc2Vzc2lvbnMuXCIsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogdHJ1ZSxcbiAgfSxcbiAgc2NoZWR1bGVkUHVzaDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9TQ0hFRFVMRURfUFVTSCcsXG4gICAgaGVscDogJ0NvbmZpZ3VyYXRpb24gZm9yIHB1c2ggc2NoZWR1bGluZywgZGVmYXVsdHMgdG8gZmFsc2UuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbiAgc2NoZW1hQ2FjaGVUVEw6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfU0NIRU1BX0NBQ0hFX1RUTCcsXG4gICAgaGVscDpcbiAgICAgICdUaGUgVFRMIGZvciBjYWNoaW5nIHRoZSBzY2hlbWEgZm9yIG9wdGltaXppbmcgcmVhZC93cml0ZSBvcGVyYXRpb25zLiBZb3Ugc2hvdWxkIHB1dCBhIGxvbmcgVFRMIHdoZW4geW91ciBEQiBpcyBpbiBwcm9kdWN0aW9uLiBkZWZhdWx0IHRvIDUwMDA7IHNldCAwIHRvIGRpc2FibGUuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCdzY2hlbWFDYWNoZVRUTCcpLFxuICAgIGRlZmF1bHQ6IDUwMDAsXG4gIH0sXG4gIHNlcnZlckNsb3NlQ29tcGxldGU6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfU0VSVkVSX0NMT1NFX0NPTVBMRVRFJyxcbiAgICBoZWxwOiAnQ2FsbGJhY2sgd2hlbiBzZXJ2ZXIgaGFzIGNsb3NlZCcsXG4gIH0sXG4gIHNlcnZlclN0YXJ0Q29tcGxldGU6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfU0VSVkVSX1NUQVJUX0NPTVBMRVRFJyxcbiAgICBoZWxwOiAnQ2FsbGJhY2sgd2hlbiBzZXJ2ZXIgaGFzIHN0YXJ0ZWQnLFxuICB9LFxuICBzZXJ2ZXJVUkw6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfVVJMJyxcbiAgICBoZWxwOiAnVVJMIHRvIHlvdXIgcGFyc2Ugc2VydmVyIHdpdGggaHR0cDovLyBvciBodHRwczovLy4nLFxuICAgIHJlcXVpcmVkOiB0cnVlLFxuICB9LFxuICBzZXNzaW9uTGVuZ3RoOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1NFU1NJT05fTEVOR1RIJyxcbiAgICBoZWxwOiAnU2Vzc2lvbiBkdXJhdGlvbiwgaW4gc2Vjb25kcywgZGVmYXVsdHMgdG8gMSB5ZWFyJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCdzZXNzaW9uTGVuZ3RoJyksXG4gICAgZGVmYXVsdDogMzE1MzYwMDAsXG4gIH0sXG4gIHNpbGVudDoge1xuICAgIGVudjogJ1NJTEVOVCcsXG4gICAgaGVscDogJ0Rpc2FibGVzIGNvbnNvbGUgb3V0cHV0JyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgfSxcbiAgc3RhcnRMaXZlUXVlcnlTZXJ2ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfU1RBUlRfTElWRV9RVUVSWV9TRVJWRVInLFxuICAgIGhlbHA6ICdTdGFydHMgdGhlIGxpdmVRdWVyeSBzZXJ2ZXInLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICB9LFxuICB1c2VyU2Vuc2l0aXZlRmllbGRzOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1VTRVJfU0VOU0lUSVZFX0ZJRUxEUycsXG4gICAgaGVscDpcbiAgICAgICdQZXJzb25hbGx5IGlkZW50aWZpYWJsZSBpbmZvcm1hdGlvbiBmaWVsZHMgaW4gdGhlIHVzZXIgdGFibGUgdGhlIHNob3VsZCBiZSByZW1vdmVkIGZvciBub24tYXV0aG9yaXplZCB1c2Vycy4gRGVwcmVjYXRlZCBAc2VlIHByb3RlY3RlZEZpZWxkcycsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmFycmF5UGFyc2VyLFxuICB9LFxuICB2ZXJib3NlOiB7XG4gICAgZW52OiAnVkVSQk9TRScsXG4gICAgaGVscDogJ1NldCB0aGUgbG9nZ2luZyB0byB2ZXJib3NlJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgfSxcbiAgdmVyaWZ5VXNlckVtYWlsczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9WRVJJRllfVVNFUl9FTUFJTFMnLFxuICAgIGhlbHA6ICdFbmFibGUgKG9yIGRpc2FibGUpIHVzZXIgZW1haWwgdmFsaWRhdGlvbiwgZGVmYXVsdHMgdG8gZmFsc2UnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IGZhbHNlLFxuICB9LFxuICB3ZWJob29rS2V5OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1dFQkhPT0tfS0VZJyxcbiAgICBoZWxwOiAnS2V5IHNlbnQgd2l0aCBvdXRnb2luZyB3ZWJob29rIGNhbGxzJyxcbiAgfSxcbn07XG5tb2R1bGUuZXhwb3J0cy5QYWdlc09wdGlvbnMgPSB7XG4gIGN1c3RvbVVybHM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUEFHRVNfQ1VTVE9NX1VSTFMnLFxuICAgIGhlbHA6ICdUaGUgVVJMcyB0byB0aGUgY3VzdG9tIHBhZ2VzLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgICBkZWZhdWx0OiB7fSxcbiAgfSxcbiAgZW5hYmxlTG9jYWxpemF0aW9uOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BBR0VTX0VOQUJMRV9MT0NBTElaQVRJT04nLFxuICAgIGhlbHA6ICdJcyB0cnVlIGlmIHBhZ2VzIHNob3VsZCBiZSBsb2NhbGl6ZWQ7IHRoaXMgaGFzIG5vIGVmZmVjdCBvbiBjdXN0b20gcGFnZSByZWRpcmVjdHMuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbiAgZW5hYmxlUm91dGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BBR0VTX0VOQUJMRV9ST1VURVInLFxuICAgIGhlbHA6XG4gICAgICAnSXMgdHJ1ZSBpZiB0aGUgcGFnZXMgcm91dGVyIHNob3VsZCBiZSBlbmFibGVkOyB0aGlzIGlzIHJlcXVpcmVkIGZvciBhbnkgb2YgdGhlIHBhZ2VzIG9wdGlvbnMgdG8gdGFrZSBlZmZlY3QuIENhdXRpb24sIHRoaXMgaXMgYW4gZXhwZXJpbWVudGFsIGZlYXR1cmUgdGhhdCBtYXkgbm90IGJlIGFwcHJvcHJpYXRlIGZvciBwcm9kdWN0aW9uLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIGZvcmNlUmVkaXJlY3Q6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUEFHRVNfRk9SQ0VfUkVESVJFQ1QnLFxuICAgIGhlbHA6XG4gICAgICAnSXMgdHJ1ZSBpZiByZXNwb25zZXMgc2hvdWxkIGFsd2F5cyBiZSByZWRpcmVjdHMgYW5kIG5ldmVyIGNvbnRlbnQsIGZhbHNlIGlmIHRoZSByZXNwb25zZSB0eXBlIHNob3VsZCBkZXBlbmQgb24gdGhlIHJlcXVlc3QgdHlwZSAoR0VUIHJlcXVlc3QgLT4gY29udGVudCByZXNwb25zZTsgUE9TVCByZXF1ZXN0IC0+IHJlZGlyZWN0IHJlc3BvbnNlKS4nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IGZhbHNlLFxuICB9LFxuICBsb2NhbGl6YXRpb25GYWxsYmFja0xvY2FsZToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QQUdFU19MT0NBTElaQVRJT05fRkFMTEJBQ0tfTE9DQUxFJyxcbiAgICBoZWxwOlxuICAgICAgJ1RoZSBmYWxsYmFjayBsb2NhbGUgZm9yIGxvY2FsaXphdGlvbiBpZiBubyBtYXRjaGluZyB0cmFuc2xhdGlvbiBpcyBwcm92aWRlZCBmb3IgdGhlIGdpdmVuIGxvY2FsZS4gVGhpcyBpcyBvbmx5IHJlbGV2YW50IHdoZW4gcHJvdmlkaW5nIHRyYW5zbGF0aW9uIHJlc291cmNlcyB2aWEgSlNPTiBmaWxlLicsXG4gICAgZGVmYXVsdDogJ2VuJyxcbiAgfSxcbiAgbG9jYWxpemF0aW9uSnNvblBhdGg6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUEFHRVNfTE9DQUxJWkFUSU9OX0pTT05fUEFUSCcsXG4gICAgaGVscDpcbiAgICAgICdUaGUgcGF0aCB0byB0aGUgSlNPTiBmaWxlIGZvciBsb2NhbGl6YXRpb247IHRoZSB0cmFuc2xhdGlvbnMgd2lsbCBiZSB1c2VkIHRvIGZpbGwgdGVtcGxhdGUgcGxhY2Vob2xkZXJzIGFjY29yZGluZyB0byB0aGUgbG9jYWxlLicsXG4gIH0sXG4gIHBhZ2VzRW5kcG9pbnQ6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUEFHRVNfUEFHRVNfRU5EUE9JTlQnLFxuICAgIGhlbHA6IFwiVGhlIEFQSSBlbmRwb2ludCBmb3IgdGhlIHBhZ2VzLiBEZWZhdWx0IGlzICdhcHBzJy5cIixcbiAgICBkZWZhdWx0OiAnYXBwcycsXG4gIH0sXG4gIHBhZ2VzUGF0aDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QQUdFU19QQUdFU19QQVRIJyxcbiAgICBoZWxwOlxuICAgICAgXCJUaGUgcGF0aCB0byB0aGUgcGFnZXMgZGlyZWN0b3J5OyB0aGlzIGFsc28gZGVmaW5lcyB3aGVyZSB0aGUgc3RhdGljIGVuZHBvaW50ICcvYXBwcycgcG9pbnRzIHRvLiBEZWZhdWx0IGlzIHRoZSAnLi9wdWJsaWMvJyBkaXJlY3RvcnkuXCIsXG4gICAgZGVmYXVsdDogJy4vcHVibGljJyxcbiAgfSxcbiAgcGxhY2Vob2xkZXJzOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BBR0VTX1BMQUNFSE9MREVSUycsXG4gICAgaGVscDpcbiAgICAgICdUaGUgcGxhY2Vob2xkZXIga2V5cyBhbmQgdmFsdWVzIHdoaWNoIHdpbGwgYmUgZmlsbGVkIGluIHBhZ2VzOyB0aGlzIGNhbiBiZSBhIHNpbXBsZSBvYmplY3Qgb3IgYSBjYWxsYmFjayBmdW5jdGlvbi4nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5vYmplY3RQYXJzZXIsXG4gICAgZGVmYXVsdDoge30sXG4gIH0sXG59O1xubW9kdWxlLmV4cG9ydHMuUGFnZXNDdXN0b21VcmxzT3B0aW9ucyA9IHtcbiAgZW1haWxWZXJpZmljYXRpb25MaW5rRXhwaXJlZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QQUdFU19DVVNUT01fVVJMX0VNQUlMX1ZFUklGSUNBVElPTl9MSU5LX0VYUElSRUQnLFxuICAgIGhlbHA6ICdUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgZW1haWwgdmVyaWZpY2F0aW9uIC0+IGxpbmsgZXhwaXJlZC4nLFxuICB9LFxuICBlbWFpbFZlcmlmaWNhdGlvbkxpbmtJbnZhbGlkOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BBR0VTX0NVU1RPTV9VUkxfRU1BSUxfVkVSSUZJQ0FUSU9OX0xJTktfSU5WQUxJRCcsXG4gICAgaGVscDogJ1RoZSBVUkwgdG8gdGhlIGN1c3RvbSBwYWdlIGZvciBlbWFpbCB2ZXJpZmljYXRpb24gLT4gbGluayBpbnZhbGlkLicsXG4gIH0sXG4gIGVtYWlsVmVyaWZpY2F0aW9uU2VuZEZhaWw6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUEFHRVNfQ1VTVE9NX1VSTF9FTUFJTF9WRVJJRklDQVRJT05fU0VORF9GQUlMJyxcbiAgICBoZWxwOiAnVGhlIFVSTCB0byB0aGUgY3VzdG9tIHBhZ2UgZm9yIGVtYWlsIHZlcmlmaWNhdGlvbiAtPiBsaW5rIHNlbmQgZmFpbC4nLFxuICB9LFxuICBlbWFpbFZlcmlmaWNhdGlvblNlbmRTdWNjZXNzOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BBR0VTX0NVU1RPTV9VUkxfRU1BSUxfVkVSSUZJQ0FUSU9OX1NFTkRfU1VDQ0VTUycsXG4gICAgaGVscDogJ1RoZSBVUkwgdG8gdGhlIGN1c3RvbSBwYWdlIGZvciBlbWFpbCB2ZXJpZmljYXRpb24gLT4gcmVzZW5kIGxpbmsgLT4gc3VjY2Vzcy4nLFxuICB9LFxuICBlbWFpbFZlcmlmaWNhdGlvblN1Y2Nlc3M6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUEFHRVNfQ1VTVE9NX1VSTF9FTUFJTF9WRVJJRklDQVRJT05fU1VDQ0VTUycsXG4gICAgaGVscDogJ1RoZSBVUkwgdG8gdGhlIGN1c3RvbSBwYWdlIGZvciBlbWFpbCB2ZXJpZmljYXRpb24gLT4gc3VjY2Vzcy4nLFxuICB9LFxuICBwYXNzd29yZFJlc2V0OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BBR0VTX0NVU1RPTV9VUkxfUEFTU1dPUkRfUkVTRVQnLFxuICAgIGhlbHA6ICdUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgcGFzc3dvcmQgcmVzZXQuJyxcbiAgfSxcbiAgcGFzc3dvcmRSZXNldExpbmtJbnZhbGlkOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BBR0VTX0NVU1RPTV9VUkxfUEFTU1dPUkRfUkVTRVRfTElOS19JTlZBTElEJyxcbiAgICBoZWxwOiAnVGhlIFVSTCB0byB0aGUgY3VzdG9tIHBhZ2UgZm9yIHBhc3N3b3JkIHJlc2V0IC0+IGxpbmsgaW52YWxpZC4nLFxuICB9LFxuICBwYXNzd29yZFJlc2V0U3VjY2Vzczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QQUdFU19DVVNUT01fVVJMX1BBU1NXT1JEX1JFU0VUX1NVQ0NFU1MnLFxuICAgIGhlbHA6ICdUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgcGFzc3dvcmQgcmVzZXQgLT4gc3VjY2Vzcy4nLFxuICB9LFxufTtcbm1vZHVsZS5leHBvcnRzLkN1c3RvbVBhZ2VzT3B0aW9ucyA9IHtcbiAgY2hvb3NlUGFzc3dvcmQ6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTX0NIT09TRV9QQVNTV09SRCcsXG4gICAgaGVscDogJ2Nob29zZSBwYXNzd29yZCBwYWdlIHBhdGgnLFxuICB9LFxuICBleHBpcmVkVmVyaWZpY2F0aW9uTGluazoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DVVNUT01fUEFHRVNfRVhQSVJFRF9WRVJJRklDQVRJT05fTElOSycsXG4gICAgaGVscDogJ2V4cGlyZWQgdmVyaWZpY2F0aW9uIGxpbmsgcGFnZSBwYXRoJyxcbiAgfSxcbiAgaW52YWxpZExpbms6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTX0lOVkFMSURfTElOSycsXG4gICAgaGVscDogJ2ludmFsaWQgbGluayBwYWdlIHBhdGgnLFxuICB9LFxuICBpbnZhbGlkUGFzc3dvcmRSZXNldExpbms6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTX0lOVkFMSURfUEFTU1dPUkRfUkVTRVRfTElOSycsXG4gICAgaGVscDogJ2ludmFsaWQgcGFzc3dvcmQgcmVzZXQgbGluayBwYWdlIHBhdGgnLFxuICB9LFxuICBpbnZhbGlkVmVyaWZpY2F0aW9uTGluazoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DVVNUT01fUEFHRVNfSU5WQUxJRF9WRVJJRklDQVRJT05fTElOSycsXG4gICAgaGVscDogJ2ludmFsaWQgdmVyaWZpY2F0aW9uIGxpbmsgcGFnZSBwYXRoJyxcbiAgfSxcbiAgbGlua1NlbmRGYWlsOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0NVU1RPTV9QQUdFU19MSU5LX1NFTkRfRkFJTCcsXG4gICAgaGVscDogJ3ZlcmlmaWNhdGlvbiBsaW5rIHNlbmQgZmFpbCBwYWdlIHBhdGgnLFxuICB9LFxuICBsaW5rU2VuZFN1Y2Nlc3M6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTX0xJTktfU0VORF9TVUNDRVNTJyxcbiAgICBoZWxwOiAndmVyaWZpY2F0aW9uIGxpbmsgc2VuZCBzdWNjZXNzIHBhZ2UgcGF0aCcsXG4gIH0sXG4gIHBhcnNlRnJhbWVVUkw6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTX1BBUlNFX0ZSQU1FX1VSTCcsXG4gICAgaGVscDogJ2ZvciBtYXNraW5nIHVzZXItZmFjaW5nIHBhZ2VzJyxcbiAgfSxcbiAgcGFzc3dvcmRSZXNldFN1Y2Nlc3M6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTX1BBU1NXT1JEX1JFU0VUX1NVQ0NFU1MnLFxuICAgIGhlbHA6ICdwYXNzd29yZCByZXNldCBzdWNjZXNzIHBhZ2UgcGF0aCcsXG4gIH0sXG4gIHZlcmlmeUVtYWlsU3VjY2Vzczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DVVNUT01fUEFHRVNfVkVSSUZZX0VNQUlMX1NVQ0NFU1MnLFxuICAgIGhlbHA6ICd2ZXJpZnkgZW1haWwgc3VjY2VzcyBwYWdlIHBhdGgnLFxuICB9LFxufTtcbm1vZHVsZS5leHBvcnRzLkxpdmVRdWVyeU9wdGlvbnMgPSB7XG4gIGNsYXNzTmFtZXM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTElWRVFVRVJZX0NMQVNTTkFNRVMnLFxuICAgIGhlbHA6IFwicGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IGNsYXNzTmFtZXNcIixcbiAgICBhY3Rpb246IHBhcnNlcnMuYXJyYXlQYXJzZXIsXG4gIH0sXG4gIHB1YlN1YkFkYXB0ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTElWRVFVRVJZX1BVQl9TVUJfQURBUFRFUicsXG4gICAgaGVscDogJ0xpdmVRdWVyeSBwdWJzdWIgYWRhcHRlcicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm1vZHVsZU9yT2JqZWN0UGFyc2VyLFxuICB9LFxuICByZWRpc09wdGlvbnM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTElWRVFVRVJZX1JFRElTX09QVElPTlMnLFxuICAgIGhlbHA6IFwicGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IHJlZGlzT3B0aW9uc1wiLFxuICAgIGFjdGlvbjogcGFyc2Vycy5vYmplY3RQYXJzZXIsXG4gIH0sXG4gIHJlZGlzVVJMOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xJVkVRVUVSWV9SRURJU19VUkwnLFxuICAgIGhlbHA6IFwicGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IHJlZGlzVVJMXCIsXG4gIH0sXG4gIHdzc0FkYXB0ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTElWRVFVRVJZX1dTU19BREFQVEVSJyxcbiAgICBoZWxwOiAnQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBXZWJTb2NrZXRTZXJ2ZXInLFxuICAgIGFjdGlvbjogcGFyc2Vycy5tb2R1bGVPck9iamVjdFBhcnNlcixcbiAgfSxcbn07XG5tb2R1bGUuZXhwb3J0cy5MaXZlUXVlcnlTZXJ2ZXJPcHRpb25zID0ge1xuICBhcHBJZDoge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX0FQUF9JRCcsXG4gICAgaGVscDpcbiAgICAgICdUaGlzIHN0cmluZyBzaG91bGQgbWF0Y2ggdGhlIGFwcElkIGluIHVzZSBieSB5b3VyIFBhcnNlIFNlcnZlci4gSWYgeW91IGRlcGxveSB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciBhbG9uZ3NpZGUgUGFyc2UgU2VydmVyLCB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciB3aWxsIHRyeSB0byB1c2UgdGhlIHNhbWUgYXBwSWQuJyxcbiAgfSxcbiAgY2FjaGVUaW1lb3V0OiB7XG4gICAgZW52OiAnUEFSU0VfTElWRV9RVUVSWV9TRVJWRVJfQ0FDSEVfVElNRU9VVCcsXG4gICAgaGVscDpcbiAgICAgIFwiTnVtYmVyIGluIG1pbGxpc2Vjb25kcy4gV2hlbiBjbGllbnRzIHByb3ZpZGUgdGhlIHNlc3Npb25Ub2tlbiB0byB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciwgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgd2lsbCB0cnkgdG8gZmV0Y2ggaXRzIFBhcnNlVXNlcidzIG9iamVjdElkIGZyb20gcGFyc2Ugc2VydmVyIGFuZCBzdG9yZSBpdCBpbiB0aGUgY2FjaGUuIFRoZSB2YWx1ZSBkZWZpbmVzIHRoZSBkdXJhdGlvbiBvZiB0aGUgY2FjaGUuIENoZWNrIHRoZSBmb2xsb3dpbmcgU2VjdXJpdHkgc2VjdGlvbiBhbmQgb3VyIHByb3RvY29sIHNwZWNpZmljYXRpb24gZm9yIGRldGFpbHMsIGRlZmF1bHRzIHRvIDUgKiAxMDAwIG1zICg1IHNlY29uZHMpLlwiLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ2NhY2hlVGltZW91dCcpLFxuICB9LFxuICBrZXlQYWlyczoge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX0tFWV9QQUlSUycsXG4gICAgaGVscDpcbiAgICAgICdBIEpTT04gb2JqZWN0IHRoYXQgc2VydmVzIGFzIGEgd2hpdGVsaXN0IG9mIGtleXMuIEl0IGlzIHVzZWQgZm9yIHZhbGlkYXRpbmcgY2xpZW50cyB3aGVuIHRoZXkgdHJ5IHRvIGNvbm5lY3QgdG8gdGhlIExpdmVRdWVyeSBzZXJ2ZXIuIENoZWNrIHRoZSBmb2xsb3dpbmcgU2VjdXJpdHkgc2VjdGlvbiBhbmQgb3VyIHByb3RvY29sIHNwZWNpZmljYXRpb24gZm9yIGRldGFpbHMuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICBsb2dMZXZlbDoge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX0xPR19MRVZFTCcsXG4gICAgaGVscDpcbiAgICAgICdUaGlzIHN0cmluZyBkZWZpbmVzIHRoZSBsb2cgbGV2ZWwgb2YgdGhlIExpdmVRdWVyeSBzZXJ2ZXIuIFdlIHN1cHBvcnQgVkVSQk9TRSwgSU5GTywgRVJST1IsIE5PTkUsIGRlZmF1bHRzIHRvIElORk8uJyxcbiAgfSxcbiAgbWFzdGVyS2V5OiB7XG4gICAgZW52OiAnUEFSU0VfTElWRV9RVUVSWV9TRVJWRVJfTUFTVEVSX0tFWScsXG4gICAgaGVscDpcbiAgICAgICdUaGlzIHN0cmluZyBzaG91bGQgbWF0Y2ggdGhlIG1hc3RlcktleSBpbiB1c2UgYnkgeW91ciBQYXJzZSBTZXJ2ZXIuIElmIHlvdSBkZXBsb3kgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgYWxvbmdzaWRlIFBhcnNlIFNlcnZlciwgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgd2lsbCB0cnkgdG8gdXNlIHRoZSBzYW1lIG1hc3RlcktleS4nLFxuICB9LFxuICBwb3J0OiB7XG4gICAgZW52OiAnUEFSU0VfTElWRV9RVUVSWV9TRVJWRVJfUE9SVCcsXG4gICAgaGVscDogJ1RoZSBwb3J0IHRvIHJ1biB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciwgZGVmYXVsdHMgdG8gMTMzNy4nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ3BvcnQnKSxcbiAgICBkZWZhdWx0OiAxMzM3LFxuICB9LFxuICBwdWJTdWJBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfTElWRV9RVUVSWV9TRVJWRVJfUFVCX1NVQl9BREFQVEVSJyxcbiAgICBoZWxwOiAnTGl2ZVF1ZXJ5IHB1YnN1YiBhZGFwdGVyJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubW9kdWxlT3JPYmplY3RQYXJzZXIsXG4gIH0sXG4gIHJlZGlzT3B0aW9uczoge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX1JFRElTX09QVElPTlMnLFxuICAgIGhlbHA6IFwicGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IHJlZGlzT3B0aW9uc1wiLFxuICAgIGFjdGlvbjogcGFyc2Vycy5vYmplY3RQYXJzZXIsXG4gIH0sXG4gIHJlZGlzVVJMOiB7XG4gICAgZW52OiAnUEFSU0VfTElWRV9RVUVSWV9TRVJWRVJfUkVESVNfVVJMJyxcbiAgICBoZWxwOiBcInBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSByZWRpc1VSTFwiLFxuICB9LFxuICBzZXJ2ZXJVUkw6IHtcbiAgICBlbnY6ICdQQVJTRV9MSVZFX1FVRVJZX1NFUlZFUl9TRVJWRVJfVVJMJyxcbiAgICBoZWxwOlxuICAgICAgJ1RoaXMgc3RyaW5nIHNob3VsZCBtYXRjaCB0aGUgc2VydmVyVVJMIGluIHVzZSBieSB5b3VyIFBhcnNlIFNlcnZlci4gSWYgeW91IGRlcGxveSB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciBhbG9uZ3NpZGUgUGFyc2UgU2VydmVyLCB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciB3aWxsIHRyeSB0byB1c2UgdGhlIHNhbWUgc2VydmVyVVJMLicsXG4gIH0sXG4gIHdlYnNvY2tldFRpbWVvdXQ6IHtcbiAgICBlbnY6ICdQQVJTRV9MSVZFX1FVRVJZX1NFUlZFUl9XRUJTT0NLRVRfVElNRU9VVCcsXG4gICAgaGVscDpcbiAgICAgICdOdW1iZXIgb2YgbWlsbGlzZWNvbmRzIGJldHdlZW4gcGluZy9wb25nIGZyYW1lcy4gVGhlIFdlYlNvY2tldCBzZXJ2ZXIgc2VuZHMgcGluZy9wb25nIGZyYW1lcyB0byB0aGUgY2xpZW50cyB0byBrZWVwIHRoZSBXZWJTb2NrZXQgYWxpdmUuIFRoaXMgdmFsdWUgZGVmaW5lcyB0aGUgaW50ZXJ2YWwgb2YgdGhlIHBpbmcvcG9uZyBmcmFtZSBmcm9tIHRoZSBzZXJ2ZXIgdG8gY2xpZW50cywgZGVmYXVsdHMgdG8gMTAgKiAxMDAwIG1zICgxMCBzKS4nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ3dlYnNvY2tldFRpbWVvdXQnKSxcbiAgfSxcbiAgd3NzQWRhcHRlcjoge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX1dTU19BREFQVEVSJyxcbiAgICBoZWxwOiAnQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBXZWJTb2NrZXRTZXJ2ZXInLFxuICAgIGFjdGlvbjogcGFyc2Vycy5tb2R1bGVPck9iamVjdFBhcnNlcixcbiAgfSxcbn07XG5tb2R1bGUuZXhwb3J0cy5JZGVtcG90ZW5jeU9wdGlvbnMgPSB7XG4gIHBhdGhzOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VYUEVSSU1FTlRBTF9JREVNUE9URU5DWV9QQVRIUycsXG4gICAgaGVscDpcbiAgICAgICdBbiBhcnJheSBvZiBwYXRocyBmb3Igd2hpY2ggdGhlIGZlYXR1cmUgc2hvdWxkIGJlIGVuYWJsZWQuIFRoZSBtb3VudCBwYXRoIG11c3Qgbm90IGJlIGluY2x1ZGVkLCBmb3IgZXhhbXBsZSBpbnN0ZWFkIG9mIGAvcGFyc2UvZnVuY3Rpb25zL215RnVuY3Rpb25gIHNwZWNpZml5IGBmdW5jdGlvbnMvbXlGdW5jdGlvbmAuIFRoZSBlbnRyaWVzIGFyZSBpbnRlcnByZXRlZCBhcyByZWd1bGFyIGV4cHJlc3Npb24sIGZvciBleGFtcGxlIGBmdW5jdGlvbnMvLipgIG1hdGNoZXMgYWxsIGZ1bmN0aW9ucywgYGpvYnMvLipgIG1hdGNoZXMgYWxsIGpvYnMsIGBjbGFzc2VzLy4qYCBtYXRjaGVzIGFsbCBjbGFzc2VzLCBgLipgIG1hdGNoZXMgYWxsIHBhdGhzLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmFycmF5UGFyc2VyLFxuICAgIGRlZmF1bHQ6IFtdLFxuICB9LFxuICB0dGw6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfRVhQRVJJTUVOVEFMX0lERU1QT1RFTkNZX1RUTCcsXG4gICAgaGVscDpcbiAgICAgICdUaGUgZHVyYXRpb24gaW4gc2Vjb25kcyBhZnRlciB3aGljaCBhIHJlcXVlc3QgcmVjb3JkIGlzIGRpc2NhcmRlZCBmcm9tIHRoZSBkYXRhYmFzZSwgZGVmYXVsdHMgdG8gMzAwcy4nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ3R0bCcpLFxuICAgIGRlZmF1bHQ6IDMwMCxcbiAgfSxcbn07XG5tb2R1bGUuZXhwb3J0cy5BY2NvdW50TG9ja291dE9wdGlvbnMgPSB7XG4gIGR1cmF0aW9uOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0FDQ09VTlRfTE9DS09VVF9EVVJBVElPTicsXG4gICAgaGVscDpcbiAgICAgICdudW1iZXIgb2YgbWludXRlcyB0aGF0IGEgbG9ja2VkLW91dCBhY2NvdW50IHJlbWFpbnMgbG9ja2VkIG91dCBiZWZvcmUgYXV0b21hdGljYWxseSBiZWNvbWluZyB1bmxvY2tlZC4nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ2R1cmF0aW9uJyksXG4gIH0sXG4gIHRocmVzaG9sZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9BQ0NPVU5UX0xPQ0tPVVRfVEhSRVNIT0xEJyxcbiAgICBoZWxwOiAnbnVtYmVyIG9mIGZhaWxlZCBzaWduLWluIGF0dGVtcHRzIHRoYXQgd2lsbCBjYXVzZSBhIHVzZXIgYWNjb3VudCB0byBiZSBsb2NrZWQnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ3RocmVzaG9sZCcpLFxuICB9LFxuICB1bmxvY2tPblBhc3N3b3JkUmVzZXQ6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQUNDT1VOVF9MT0NLT1VUX1VOTE9DS19PTl9QQVNTV09SRF9SRVNFVCcsXG4gICAgaGVscDogJ0lzIHRydWUgaWYgdGhlIGFjY291bnQgbG9jayBzaG91bGQgYmUgcmVtb3ZlZCBhZnRlciBhIHN1Y2Nlc3NmdWwgcGFzc3dvcmQgcmVzZXQuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbn07XG5tb2R1bGUuZXhwb3J0cy5QYXNzd29yZFBvbGljeU9wdGlvbnMgPSB7XG4gIGRvTm90QWxsb3dVc2VybmFtZToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QQVNTV09SRF9QT0xJQ1lfRE9fTk9UX0FMTE9XX1VTRVJOQU1FJyxcbiAgICBoZWxwOiAnZGlzYWxsb3cgdXNlcm5hbWUgaW4gcGFzc3dvcmRzJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgfSxcbiAgbWF4UGFzc3dvcmRBZ2U6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUEFTU1dPUkRfUE9MSUNZX01BWF9QQVNTV09SRF9BR0UnLFxuICAgIGhlbHA6ICdkYXlzIGZvciBwYXNzd29yZCBleHBpcnknLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ21heFBhc3N3b3JkQWdlJyksXG4gIH0sXG4gIG1heFBhc3N3b3JkSGlzdG9yeToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QQVNTV09SRF9QT0xJQ1lfTUFYX1BBU1NXT1JEX0hJU1RPUlknLFxuICAgIGhlbHA6ICdzZXR0aW5nIHRvIHByZXZlbnQgcmV1c2Ugb2YgcHJldmlvdXMgbiBwYXNzd29yZHMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ21heFBhc3N3b3JkSGlzdG9yeScpLFxuICB9LFxuICByZXNldFRva2VuUmV1c2VJZlZhbGlkOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BBU1NXT1JEX1BPTElDWV9SRVNFVF9UT0tFTl9SRVVTRV9JRl9WQUxJRCcsXG4gICAgaGVscDogXCJyZXNlbmQgdG9rZW4gaWYgaXQncyBzdGlsbCB2YWxpZFwiLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICB9LFxuICByZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbjoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QQVNTV09SRF9QT0xJQ1lfUkVTRVRfVE9LRU5fVkFMSURJVFlfRFVSQVRJT04nLFxuICAgIGhlbHA6ICd0aW1lIGZvciB0b2tlbiB0byBleHBpcmUnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ3Jlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uJyksXG4gIH0sXG4gIHZhbGlkYXRvckNhbGxiYWNrOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BBU1NXT1JEX1BPTElDWV9WQUxJREFUT1JfQ0FMTEJBQ0snLFxuICAgIGhlbHA6ICdhIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGJlIGludm9rZWQgdG8gdmFsaWRhdGUgdGhlIHBhc3N3b3JkJyxcbiAgfSxcbiAgdmFsaWRhdG9yUGF0dGVybjoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QQVNTV09SRF9QT0xJQ1lfVkFMSURBVE9SX1BBVFRFUk4nLFxuICAgIGhlbHA6ICdhIFJlZ0V4cCBvYmplY3Qgb3IgYSByZWdleCBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBwYXR0ZXJuIHRvIGVuZm9yY2UnLFxuICB9LFxufTtcbm1vZHVsZS5leHBvcnRzLkZpbGVVcGxvYWRPcHRpb25zID0ge1xuICBlbmFibGVGb3JBbm9ueW1vdXNVc2VyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0ZJTEVfVVBMT0FEX0VOQUJMRV9GT1JfQU5PTllNT1VTX1VTRVInLFxuICAgIGhlbHA6ICdJcyB0cnVlIGlmIGZpbGUgdXBsb2FkIHNob3VsZCBiZSBhbGxvd2VkIGZvciBhbm9ueW1vdXMgdXNlcnMuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbiAgZW5hYmxlRm9yQXV0aGVudGljYXRlZFVzZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfRklMRV9VUExPQURfRU5BQkxFX0ZPUl9BVVRIRU5USUNBVEVEX1VTRVInLFxuICAgIGhlbHA6ICdJcyB0cnVlIGlmIGZpbGUgdXBsb2FkIHNob3VsZCBiZSBhbGxvd2VkIGZvciBhdXRoZW50aWNhdGVkIHVzZXJzLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogdHJ1ZSxcbiAgfSxcbiAgZW5hYmxlRm9yUHVibGljOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0ZJTEVfVVBMT0FEX0VOQUJMRV9GT1JfUFVCTElDJyxcbiAgICBoZWxwOiAnSXMgdHJ1ZSBpZiBmaWxlIHVwbG9hZCBzaG91bGQgYmUgYWxsb3dlZCBmb3IgYW55b25lLCByZWdhcmRsZXNzIG9mIHVzZXIgYXV0aGVudGljYXRpb24uJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Options/docs.js b/lib/Options/docs.js new file mode 100644 index 0000000000..ce971eafec --- /dev/null +++ b/lib/Options/docs.js @@ -0,0 +1,178 @@ +/** + * @interface ParseServerOptions + * @property {AccountLockoutOptions} accountLockout account lockout policy for failed login attempts + * @property {Boolean} allowClientClassCreation Enable (or disable) client class creation, defaults to true + * @property {Boolean} allowCustomObjectId Enable (or disable) custom objectId + * @property {String[]} allowHeaders Add headers to Access-Control-Allow-Headers + * @property {String} allowOrigin Sets the origin to Access-Control-Allow-Origin + * @property {Adapter} analyticsAdapter Adapter module for the analytics + * @property {String} appId Your Parse Application ID + * @property {String} appName Sets the app name + * @property {Any} auth Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication + * @property {Adapter} cacheAdapter Adapter module for the cache + * @property {Number} cacheMaxSize Sets the maximum size for the in memory cache, defaults to 10000 + * @property {Number} cacheTTL Sets the TTL for the in memory cache (in ms), defaults to 5000 (5 seconds) + * @property {String} clientKey Key for iOS, MacOS, tvOS clients + * @property {String} cloud Full path to your cloud code main.js + * @property {Number|Boolean} cluster Run with cluster, optionally set the number of processes default to os.cpus().length + * @property {String} collectionPrefix A collection prefix for the classes + * @property {CustomPagesOptions} customPages custom pages for password validation and reset + * @property {Adapter} databaseAdapter Adapter module for the database + * @property {Any} databaseOptions Options to pass to the mongodb client + * @property {String} databaseURI The full URI to your database. Supported databases are mongodb or postgres. + * @property {Boolean} directAccess Replace HTTP Interface when using JS SDK in current node runtime, defaults to false. Caution, this is an experimental feature that may not be appropriate for production. + * @property {String} dotNetKey Key for Unity and .Net SDK + * @property {Adapter} emailAdapter Adapter module for email sending + * @property {Boolean} emailVerifyTokenReuseIfValid an existing email verify token should be reused when resend verification email is requested + * @property {Number} emailVerifyTokenValidityDuration Email verification token validity duration, in seconds + * @property {Boolean} enableAnonymousUsers Enable (or disable) anonymous users, defaults to true + * @property {Boolean} enableExpressErrorHandler Enables the default express error handler for all errors + * @property {Boolean} enableSingleSchemaCache Use a single schema cache shared across requests. Reduces number of queries made to _SCHEMA, defaults to false, i.e. unique schema cache per request. + * @property {String} encryptionKey Key for encrypting your files + * @property {Boolean} expireInactiveSessions Sets wether we should expire the inactive sessions, defaults to true + * @property {String} fileKey Key for your files + * @property {Adapter} filesAdapter Adapter module for the files sub-system + * @property {FileUploadOptions} fileUpload Options for file uploads + * @property {String} graphQLPath Mount path for the GraphQL endpoint, defaults to /graphql + * @property {String} graphQLSchema Full path to your GraphQL custom schema.graphql file + * @property {String} host The host to serve ParseServer on, defaults to 0.0.0.0 + * @property {IdempotencyOptions} idempotencyOptions Options for request idempotency to deduplicate identical requests that may be caused by network issues. Caution, this is an experimental feature that may not be appropriate for production. + * @property {String} javascriptKey Key for the Javascript SDK + * @property {Boolean} jsonLogs Log as structured JSON objects + * @property {LiveQueryOptions} liveQuery parse-server's LiveQuery configuration object + * @property {LiveQueryServerOptions} liveQueryServerOptions Live query server configuration options (will start the liveQuery server) + * @property {Adapter} loggerAdapter Adapter module for the logging sub-system + * @property {String} logLevel Sets the level for logs + * @property {String} logsFolder Folder for the logs (defaults to './logs'); set to null to disable file based logging + * @property {String} masterKey Your Parse Master Key + * @property {String[]} masterKeyIps Restrict masterKey to be used by only these ips, defaults to [] (allow all ips) + * @property {Number} maxLimit Max value for limit option on queries, defaults to unlimited + * @property {Number|String} maxLogFiles Maximum number of logs to keep. If not set, no logs will be removed. This can be a number of files or number of days. If using days, add 'd' as the suffix. (default: null) + * @property {String} maxUploadSize Max file size for uploads, defaults to 20mb + * @property {Union} middleware middleware for express server, can be string or function + * @property {Boolean} mountGraphQL Mounts the GraphQL endpoint + * @property {String} mountPath Mount path for the server, defaults to /parse + * @property {Boolean} mountPlayground Mounts the GraphQL Playground - never use this option in production + * @property {Number} objectIdSize Sets the number of characters in generated object id's, default 10 + * @property {PagesOptions} pages The options for pages such as password reset and email verification. Caution, this is an experimental feature that may not be appropriate for production. + * @property {PasswordPolicyOptions} passwordPolicy Password policy for enforcing password related rules + * @property {String} playgroundPath Mount path for the GraphQL Playground, defaults to /playground + * @property {Number} port The port to run the ParseServer, defaults to 1337. + * @property {Boolean} preserveFileName Enable (or disable) the addition of a unique hash to the file names + * @property {Boolean} preventLoginWithUnverifiedEmail Prevent user from login if email is not verified and PARSE_SERVER_VERIFY_USER_EMAILS is true, defaults to false + * @property {ProtectedFields} protectedFields Protected fields that should be treated with extra security when fetching details. + * @property {String} publicServerURL Public URL to your parse server with http:// or https://. + * @property {Any} push Configuration for push, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#push-notifications + * @property {String} readOnlyMasterKey Read-only key, which has the same capabilities as MasterKey without writes + * @property {String} restAPIKey Key for REST calls + * @property {Boolean} revokeSessionOnPasswordReset When a user changes their password, either through the reset password email or while logged in, all sessions are revoked if this is true. Set to false if you don't want to revoke sessions. + * @property {Boolean} scheduledPush Configuration for push scheduling, defaults to false. + * @property {Number} schemaCacheTTL The TTL for caching the schema for optimizing read/write operations. You should put a long TTL when your DB is in production. default to 5000; set 0 to disable. + * @property {Function} serverCloseComplete Callback when server has closed + * @property {Function} serverStartComplete Callback when server has started + * @property {String} serverURL URL to your parse server with http:// or https://. + * @property {Number} sessionLength Session duration, in seconds, defaults to 1 year + * @property {Boolean} silent Disables console output + * @property {Boolean} startLiveQueryServer Starts the liveQuery server + * @property {String[]} userSensitiveFields Personally identifiable information fields in the user table the should be removed for non-authorized users. Deprecated @see protectedFields + * @property {Boolean} verbose Set the logging to verbose + * @property {Boolean} verifyUserEmails Enable (or disable) user email validation, defaults to false + * @property {String} webhookKey Key sent with outgoing webhook calls + */ + +/** + * @interface PagesOptions + * @property {PagesCustomUrlsOptions} customUrls The URLs to the custom pages. + * @property {Boolean} enableLocalization Is true if pages should be localized; this has no effect on custom page redirects. + * @property {Boolean} enableRouter Is true if the pages router should be enabled; this is required for any of the pages options to take effect. Caution, this is an experimental feature that may not be appropriate for production. + * @property {Boolean} forceRedirect Is true if responses should always be redirects and never content, false if the response type should depend on the request type (GET request -> content response; POST request -> redirect response). + * @property {String} localizationFallbackLocale The fallback locale for localization if no matching translation is provided for the given locale. This is only relevant when providing translation resources via JSON file. + * @property {String} localizationJsonPath The path to the JSON file for localization; the translations will be used to fill template placeholders according to the locale. + * @property {String} pagesEndpoint The API endpoint for the pages. Default is 'apps'. + * @property {String} pagesPath The path to the pages directory; this also defines where the static endpoint '/apps' points to. Default is the './public/' directory. + * @property {Object} placeholders The placeholder keys and values which will be filled in pages; this can be a simple object or a callback function. + */ + +/** + * @interface PagesCustomUrlsOptions + * @property {String} emailVerificationLinkExpired The URL to the custom page for email verification -> link expired. + * @property {String} emailVerificationLinkInvalid The URL to the custom page for email verification -> link invalid. + * @property {String} emailVerificationSendFail The URL to the custom page for email verification -> link send fail. + * @property {String} emailVerificationSendSuccess The URL to the custom page for email verification -> resend link -> success. + * @property {String} emailVerificationSuccess The URL to the custom page for email verification -> success. + * @property {String} passwordReset The URL to the custom page for password reset. + * @property {String} passwordResetLinkInvalid The URL to the custom page for password reset -> link invalid. + * @property {String} passwordResetSuccess The URL to the custom page for password reset -> success. + */ + +/** + * @interface CustomPagesOptions + * @property {String} choosePassword choose password page path + * @property {String} expiredVerificationLink expired verification link page path + * @property {String} invalidLink invalid link page path + * @property {String} invalidPasswordResetLink invalid password reset link page path + * @property {String} invalidVerificationLink invalid verification link page path + * @property {String} linkSendFail verification link send fail page path + * @property {String} linkSendSuccess verification link send success page path + * @property {String} parseFrameURL for masking user-facing pages + * @property {String} passwordResetSuccess password reset success page path + * @property {String} verifyEmailSuccess verify email success page path + */ + +/** + * @interface LiveQueryOptions + * @property {String[]} classNames parse-server's LiveQuery classNames + * @property {Adapter} pubSubAdapter LiveQuery pubsub adapter + * @property {Any} redisOptions parse-server's LiveQuery redisOptions + * @property {String} redisURL parse-server's LiveQuery redisURL + * @property {Adapter} wssAdapter Adapter module for the WebSocketServer + */ + +/** + * @interface LiveQueryServerOptions + * @property {String} appId This string should match the appId in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same appId. + * @property {Number} cacheTimeout Number in milliseconds. When clients provide the sessionToken to the LiveQuery server, the LiveQuery server will try to fetch its ParseUser's objectId from parse server and store it in the cache. The value defines the duration of the cache. Check the following Security section and our protocol specification for details, defaults to 5 * 1000 ms (5 seconds). + * @property {Any} keyPairs A JSON object that serves as a whitelist of keys. It is used for validating clients when they try to connect to the LiveQuery server. Check the following Security section and our protocol specification for details. + * @property {String} logLevel This string defines the log level of the LiveQuery server. We support VERBOSE, INFO, ERROR, NONE, defaults to INFO. + * @property {String} masterKey This string should match the masterKey in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same masterKey. + * @property {Number} port The port to run the LiveQuery server, defaults to 1337. + * @property {Adapter} pubSubAdapter LiveQuery pubsub adapter + * @property {Any} redisOptions parse-server's LiveQuery redisOptions + * @property {String} redisURL parse-server's LiveQuery redisURL + * @property {String} serverURL This string should match the serverURL in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same serverURL. + * @property {Number} websocketTimeout Number of milliseconds between ping/pong frames. The WebSocket server sends ping/pong frames to the clients to keep the WebSocket alive. This value defines the interval of the ping/pong frame from the server to clients, defaults to 10 * 1000 ms (10 s). + * @property {Adapter} wssAdapter Adapter module for the WebSocketServer + */ + +/** + * @interface IdempotencyOptions + * @property {String[]} paths An array of paths for which the feature should be enabled. The mount path must not be included, for example instead of `/parse/functions/myFunction` specifiy `functions/myFunction`. The entries are interpreted as regular expression, for example `functions/.*` matches all functions, `jobs/.*` matches all jobs, `classes/.*` matches all classes, `.*` matches all paths. + * @property {Number} ttl The duration in seconds after which a request record is discarded from the database, defaults to 300s. + */ + +/** + * @interface AccountLockoutOptions + * @property {Number} duration number of minutes that a locked-out account remains locked out before automatically becoming unlocked. + * @property {Number} threshold number of failed sign-in attempts that will cause a user account to be locked + * @property {Boolean} unlockOnPasswordReset Is true if the account lock should be removed after a successful password reset. + */ + +/** + * @interface PasswordPolicyOptions + * @property {Boolean} doNotAllowUsername disallow username in passwords + * @property {Number} maxPasswordAge days for password expiry + * @property {Number} maxPasswordHistory setting to prevent reuse of previous n passwords + * @property {Boolean} resetTokenReuseIfValid resend token if it's still valid + * @property {Number} resetTokenValidityDuration time for token to expire + * @property {Function} validatorCallback a callback function to be invoked to validate the password + * @property {String} validatorPattern a RegExp object or a regex string representing the pattern to enforce + */ + +/** + * @interface FileUploadOptions + * @property {Boolean} enableForAnonymousUser Is true if file upload should be allowed for anonymous users. + * @property {Boolean} enableForAuthenticatedUser Is true if file upload should be allowed for authenticated users. + * @property {Boolean} enableForPublic Is true if file upload should be allowed for anyone, regardless of user authentication. + */ +"use strict"; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9PcHRpb25zL2RvY3MuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGludGVyZmFjZSBQYXJzZVNlcnZlck9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7QWNjb3VudExvY2tvdXRPcHRpb25zfSBhY2NvdW50TG9ja291dCBhY2NvdW50IGxvY2tvdXQgcG9saWN5IGZvciBmYWlsZWQgbG9naW4gYXR0ZW1wdHNcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gYWxsb3dDbGllbnRDbGFzc0NyZWF0aW9uIEVuYWJsZSAob3IgZGlzYWJsZSkgY2xpZW50IGNsYXNzIGNyZWF0aW9uLCBkZWZhdWx0cyB0byB0cnVlXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGFsbG93Q3VzdG9tT2JqZWN0SWQgRW5hYmxlIChvciBkaXNhYmxlKSBjdXN0b20gb2JqZWN0SWRcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nW119IGFsbG93SGVhZGVycyBBZGQgaGVhZGVycyB0byBBY2Nlc3MtQ29udHJvbC1BbGxvdy1IZWFkZXJzXG4gKiBAcHJvcGVydHkge1N0cmluZ30gYWxsb3dPcmlnaW4gU2V0cyB0aGUgb3JpZ2luIHRvIEFjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpblxuICogQHByb3BlcnR5IHtBZGFwdGVyPEFuYWx5dGljc0FkYXB0ZXI+fSBhbmFseXRpY3NBZGFwdGVyIEFkYXB0ZXIgbW9kdWxlIGZvciB0aGUgYW5hbHl0aWNzXG4gKiBAcHJvcGVydHkge1N0cmluZ30gYXBwSWQgWW91ciBQYXJzZSBBcHBsaWNhdGlvbiBJRFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGFwcE5hbWUgU2V0cyB0aGUgYXBwIG5hbWVcbiAqIEBwcm9wZXJ0eSB7QW55fSBhdXRoIENvbmZpZ3VyYXRpb24gZm9yIHlvdXIgYXV0aGVudGljYXRpb24gcHJvdmlkZXJzLCBhcyBzdHJpbmdpZmllZCBKU09OLiBTZWUgaHR0cDovL2RvY3MucGFyc2VwbGF0Zm9ybS5vcmcvcGFyc2Utc2VydmVyL2d1aWRlLyNvYXV0aC1hbmQtM3JkLXBhcnR5LWF1dGhlbnRpY2F0aW9uXG4gKiBAcHJvcGVydHkge0FkYXB0ZXI8Q2FjaGVBZGFwdGVyPn0gY2FjaGVBZGFwdGVyIEFkYXB0ZXIgbW9kdWxlIGZvciB0aGUgY2FjaGVcbiAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBjYWNoZU1heFNpemUgU2V0cyB0aGUgbWF4aW11bSBzaXplIGZvciB0aGUgaW4gbWVtb3J5IGNhY2hlLCBkZWZhdWx0cyB0byAxMDAwMFxuICogQHByb3BlcnR5IHtOdW1iZXJ9IGNhY2hlVFRMIFNldHMgdGhlIFRUTCBmb3IgdGhlIGluIG1lbW9yeSBjYWNoZSAoaW4gbXMpLCBkZWZhdWx0cyB0byA1MDAwICg1IHNlY29uZHMpXG4gKiBAcHJvcGVydHkge1N0cmluZ30gY2xpZW50S2V5IEtleSBmb3IgaU9TLCBNYWNPUywgdHZPUyBjbGllbnRzXG4gKiBAcHJvcGVydHkge1N0cmluZ30gY2xvdWQgRnVsbCBwYXRoIHRvIHlvdXIgY2xvdWQgY29kZSBtYWluLmpzXG4gKiBAcHJvcGVydHkge051bWJlcnxCb29sZWFufSBjbHVzdGVyIFJ1biB3aXRoIGNsdXN0ZXIsIG9wdGlvbmFsbHkgc2V0IHRoZSBudW1iZXIgb2YgcHJvY2Vzc2VzIGRlZmF1bHQgdG8gb3MuY3B1cygpLmxlbmd0aFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGNvbGxlY3Rpb25QcmVmaXggQSBjb2xsZWN0aW9uIHByZWZpeCBmb3IgdGhlIGNsYXNzZXNcbiAqIEBwcm9wZXJ0eSB7Q3VzdG9tUGFnZXNPcHRpb25zfSBjdXN0b21QYWdlcyBjdXN0b20gcGFnZXMgZm9yIHBhc3N3b3JkIHZhbGlkYXRpb24gYW5kIHJlc2V0XG4gKiBAcHJvcGVydHkge0FkYXB0ZXI8U3RvcmFnZUFkYXB0ZXI+fSBkYXRhYmFzZUFkYXB0ZXIgQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBkYXRhYmFzZVxuICogQHByb3BlcnR5IHtBbnl9IGRhdGFiYXNlT3B0aW9ucyBPcHRpb25zIHRvIHBhc3MgdG8gdGhlIG1vbmdvZGIgY2xpZW50XG4gKiBAcHJvcGVydHkge1N0cmluZ30gZGF0YWJhc2VVUkkgVGhlIGZ1bGwgVVJJIHRvIHlvdXIgZGF0YWJhc2UuIFN1cHBvcnRlZCBkYXRhYmFzZXMgYXJlIG1vbmdvZGIgb3IgcG9zdGdyZXMuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGRpcmVjdEFjY2VzcyBSZXBsYWNlIEhUVFAgSW50ZXJmYWNlIHdoZW4gdXNpbmcgSlMgU0RLIGluIGN1cnJlbnQgbm9kZSBydW50aW1lLCBkZWZhdWx0cyB0byBmYWxzZS4gQ2F1dGlvbiwgdGhpcyBpcyBhbiBleHBlcmltZW50YWwgZmVhdHVyZSB0aGF0IG1heSBub3QgYmUgYXBwcm9wcmlhdGUgZm9yIHByb2R1Y3Rpb24uXG4gKiBAcHJvcGVydHkge1N0cmluZ30gZG90TmV0S2V5IEtleSBmb3IgVW5pdHkgYW5kIC5OZXQgU0RLXG4gKiBAcHJvcGVydHkge0FkYXB0ZXI8TWFpbEFkYXB0ZXI+fSBlbWFpbEFkYXB0ZXIgQWRhcHRlciBtb2R1bGUgZm9yIGVtYWlsIHNlbmRpbmdcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZCBhbiBleGlzdGluZyBlbWFpbCB2ZXJpZnkgdG9rZW4gc2hvdWxkIGJlIHJldXNlZCB3aGVuIHJlc2VuZCB2ZXJpZmljYXRpb24gZW1haWwgaXMgcmVxdWVzdGVkXG4gKiBAcHJvcGVydHkge051bWJlcn0gZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24gRW1haWwgdmVyaWZpY2F0aW9uIHRva2VuIHZhbGlkaXR5IGR1cmF0aW9uLCBpbiBzZWNvbmRzXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGVuYWJsZUFub255bW91c1VzZXJzIEVuYWJsZSAob3IgZGlzYWJsZSkgYW5vbnltb3VzIHVzZXJzLCBkZWZhdWx0cyB0byB0cnVlXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGVuYWJsZUV4cHJlc3NFcnJvckhhbmRsZXIgRW5hYmxlcyB0aGUgZGVmYXVsdCBleHByZXNzIGVycm9yIGhhbmRsZXIgZm9yIGFsbCBlcnJvcnNcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gZW5hYmxlU2luZ2xlU2NoZW1hQ2FjaGUgVXNlIGEgc2luZ2xlIHNjaGVtYSBjYWNoZSBzaGFyZWQgYWNyb3NzIHJlcXVlc3RzLiBSZWR1Y2VzIG51bWJlciBvZiBxdWVyaWVzIG1hZGUgdG8gX1NDSEVNQSwgZGVmYXVsdHMgdG8gZmFsc2UsIGkuZS4gdW5pcXVlIHNjaGVtYSBjYWNoZSBwZXIgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBlbmNyeXB0aW9uS2V5IEtleSBmb3IgZW5jcnlwdGluZyB5b3VyIGZpbGVzXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGV4cGlyZUluYWN0aXZlU2Vzc2lvbnMgU2V0cyB3ZXRoZXIgd2Ugc2hvdWxkIGV4cGlyZSB0aGUgaW5hY3RpdmUgc2Vzc2lvbnMsIGRlZmF1bHRzIHRvIHRydWVcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBmaWxlS2V5IEtleSBmb3IgeW91ciBmaWxlc1xuICogQHByb3BlcnR5IHtBZGFwdGVyPEZpbGVzQWRhcHRlcj59IGZpbGVzQWRhcHRlciBBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGZpbGVzIHN1Yi1zeXN0ZW1cbiAqIEBwcm9wZXJ0eSB7RmlsZVVwbG9hZE9wdGlvbnN9IGZpbGVVcGxvYWQgT3B0aW9ucyBmb3IgZmlsZSB1cGxvYWRzXG4gKiBAcHJvcGVydHkge1N0cmluZ30gZ3JhcGhRTFBhdGggTW91bnQgcGF0aCBmb3IgdGhlIEdyYXBoUUwgZW5kcG9pbnQsIGRlZmF1bHRzIHRvIC9ncmFwaHFsXG4gKiBAcHJvcGVydHkge1N0cmluZ30gZ3JhcGhRTFNjaGVtYSBGdWxsIHBhdGggdG8geW91ciBHcmFwaFFMIGN1c3RvbSBzY2hlbWEuZ3JhcGhxbCBmaWxlXG4gKiBAcHJvcGVydHkge1N0cmluZ30gaG9zdCBUaGUgaG9zdCB0byBzZXJ2ZSBQYXJzZVNlcnZlciBvbiwgZGVmYXVsdHMgdG8gMC4wLjAuMFxuICogQHByb3BlcnR5IHtJZGVtcG90ZW5jeU9wdGlvbnN9IGlkZW1wb3RlbmN5T3B0aW9ucyBPcHRpb25zIGZvciByZXF1ZXN0IGlkZW1wb3RlbmN5IHRvIGRlZHVwbGljYXRlIGlkZW50aWNhbCByZXF1ZXN0cyB0aGF0IG1heSBiZSBjYXVzZWQgYnkgbmV0d29yayBpc3N1ZXMuIENhdXRpb24sIHRoaXMgaXMgYW4gZXhwZXJpbWVudGFsIGZlYXR1cmUgdGhhdCBtYXkgbm90IGJlIGFwcHJvcHJpYXRlIGZvciBwcm9kdWN0aW9uLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGphdmFzY3JpcHRLZXkgS2V5IGZvciB0aGUgSmF2YXNjcmlwdCBTREtcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0ganNvbkxvZ3MgTG9nIGFzIHN0cnVjdHVyZWQgSlNPTiBvYmplY3RzXG4gKiBAcHJvcGVydHkge0xpdmVRdWVyeU9wdGlvbnN9IGxpdmVRdWVyeSBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgY29uZmlndXJhdGlvbiBvYmplY3RcbiAqIEBwcm9wZXJ0eSB7TGl2ZVF1ZXJ5U2VydmVyT3B0aW9uc30gbGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucyBMaXZlIHF1ZXJ5IHNlcnZlciBjb25maWd1cmF0aW9uIG9wdGlvbnMgKHdpbGwgc3RhcnQgdGhlIGxpdmVRdWVyeSBzZXJ2ZXIpXG4gKiBAcHJvcGVydHkge0FkYXB0ZXI8TG9nZ2VyQWRhcHRlcj59IGxvZ2dlckFkYXB0ZXIgQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBsb2dnaW5nIHN1Yi1zeXN0ZW1cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBsb2dMZXZlbCBTZXRzIHRoZSBsZXZlbCBmb3IgbG9nc1xuICogQHByb3BlcnR5IHtTdHJpbmd9IGxvZ3NGb2xkZXIgRm9sZGVyIGZvciB0aGUgbG9ncyAoZGVmYXVsdHMgdG8gJy4vbG9ncycpOyBzZXQgdG8gbnVsbCB0byBkaXNhYmxlIGZpbGUgYmFzZWQgbG9nZ2luZ1xuICogQHByb3BlcnR5IHtTdHJpbmd9IG1hc3RlcktleSBZb3VyIFBhcnNlIE1hc3RlciBLZXlcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nW119IG1hc3RlcktleUlwcyBSZXN0cmljdCBtYXN0ZXJLZXkgdG8gYmUgdXNlZCBieSBvbmx5IHRoZXNlIGlwcywgZGVmYXVsdHMgdG8gW10gKGFsbG93IGFsbCBpcHMpXG4gKiBAcHJvcGVydHkge051bWJlcn0gbWF4TGltaXQgTWF4IHZhbHVlIGZvciBsaW1pdCBvcHRpb24gb24gcXVlcmllcywgZGVmYXVsdHMgdG8gdW5saW1pdGVkXG4gKiBAcHJvcGVydHkge051bWJlcnxTdHJpbmd9IG1heExvZ0ZpbGVzIE1heGltdW0gbnVtYmVyIG9mIGxvZ3MgdG8ga2VlcC4gSWYgbm90IHNldCwgbm8gbG9ncyB3aWxsIGJlIHJlbW92ZWQuIFRoaXMgY2FuIGJlIGEgbnVtYmVyIG9mIGZpbGVzIG9yIG51bWJlciBvZiBkYXlzLiBJZiB1c2luZyBkYXlzLCBhZGQgJ2QnIGFzIHRoZSBzdWZmaXguIChkZWZhdWx0OiBudWxsKVxuICogQHByb3BlcnR5IHtTdHJpbmd9IG1heFVwbG9hZFNpemUgTWF4IGZpbGUgc2l6ZSBmb3IgdXBsb2FkcywgZGVmYXVsdHMgdG8gMjBtYlxuICogQHByb3BlcnR5IHtVbmlvbn0gbWlkZGxld2FyZSBtaWRkbGV3YXJlIGZvciBleHByZXNzIHNlcnZlciwgY2FuIGJlIHN0cmluZyBvciBmdW5jdGlvblxuICogQHByb3BlcnR5IHtCb29sZWFufSBtb3VudEdyYXBoUUwgTW91bnRzIHRoZSBHcmFwaFFMIGVuZHBvaW50XG4gKiBAcHJvcGVydHkge1N0cmluZ30gbW91bnRQYXRoIE1vdW50IHBhdGggZm9yIHRoZSBzZXJ2ZXIsIGRlZmF1bHRzIHRvIC9wYXJzZVxuICogQHByb3BlcnR5IHtCb29sZWFufSBtb3VudFBsYXlncm91bmQgTW91bnRzIHRoZSBHcmFwaFFMIFBsYXlncm91bmQgLSBuZXZlciB1c2UgdGhpcyBvcHRpb24gaW4gcHJvZHVjdGlvblxuICogQHByb3BlcnR5IHtOdW1iZXJ9IG9iamVjdElkU2l6ZSBTZXRzIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiBnZW5lcmF0ZWQgb2JqZWN0IGlkJ3MsIGRlZmF1bHQgMTBcbiAqIEBwcm9wZXJ0eSB7UGFnZXNPcHRpb25zfSBwYWdlcyBUaGUgb3B0aW9ucyBmb3IgcGFnZXMgc3VjaCBhcyBwYXNzd29yZCByZXNldCBhbmQgZW1haWwgdmVyaWZpY2F0aW9uLiBDYXV0aW9uLCB0aGlzIGlzIGFuIGV4cGVyaW1lbnRhbCBmZWF0dXJlIHRoYXQgbWF5IG5vdCBiZSBhcHByb3ByaWF0ZSBmb3IgcHJvZHVjdGlvbi5cbiAqIEBwcm9wZXJ0eSB7UGFzc3dvcmRQb2xpY3lPcHRpb25zfSBwYXNzd29yZFBvbGljeSBQYXNzd29yZCBwb2xpY3kgZm9yIGVuZm9yY2luZyBwYXNzd29yZCByZWxhdGVkIHJ1bGVzXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcGxheWdyb3VuZFBhdGggTW91bnQgcGF0aCBmb3IgdGhlIEdyYXBoUUwgUGxheWdyb3VuZCwgZGVmYXVsdHMgdG8gL3BsYXlncm91bmRcbiAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBwb3J0IFRoZSBwb3J0IHRvIHJ1biB0aGUgUGFyc2VTZXJ2ZXIsIGRlZmF1bHRzIHRvIDEzMzcuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHByZXNlcnZlRmlsZU5hbWUgRW5hYmxlIChvciBkaXNhYmxlKSB0aGUgYWRkaXRpb24gb2YgYSB1bmlxdWUgaGFzaCB0byB0aGUgZmlsZSBuYW1lc1xuICogQHByb3BlcnR5IHtCb29sZWFufSBwcmV2ZW50TG9naW5XaXRoVW52ZXJpZmllZEVtYWlsIFByZXZlbnQgdXNlciBmcm9tIGxvZ2luIGlmIGVtYWlsIGlzIG5vdCB2ZXJpZmllZCBhbmQgUEFSU0VfU0VSVkVSX1ZFUklGWV9VU0VSX0VNQUlMUyBpcyB0cnVlLCBkZWZhdWx0cyB0byBmYWxzZVxuICogQHByb3BlcnR5IHtQcm90ZWN0ZWRGaWVsZHN9IHByb3RlY3RlZEZpZWxkcyBQcm90ZWN0ZWQgZmllbGRzIHRoYXQgc2hvdWxkIGJlIHRyZWF0ZWQgd2l0aCBleHRyYSBzZWN1cml0eSB3aGVuIGZldGNoaW5nIGRldGFpbHMuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcHVibGljU2VydmVyVVJMIFB1YmxpYyBVUkwgdG8geW91ciBwYXJzZSBzZXJ2ZXIgd2l0aCBodHRwOi8vIG9yIGh0dHBzOi8vLlxuICogQHByb3BlcnR5IHtBbnl9IHB1c2ggQ29uZmlndXJhdGlvbiBmb3IgcHVzaCwgYXMgc3RyaW5naWZpZWQgSlNPTi4gU2VlIGh0dHA6Ly9kb2NzLnBhcnNlcGxhdGZvcm0ub3JnL3BhcnNlLXNlcnZlci9ndWlkZS8jcHVzaC1ub3RpZmljYXRpb25zXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcmVhZE9ubHlNYXN0ZXJLZXkgUmVhZC1vbmx5IGtleSwgd2hpY2ggaGFzIHRoZSBzYW1lIGNhcGFiaWxpdGllcyBhcyBNYXN0ZXJLZXkgd2l0aG91dCB3cml0ZXNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSByZXN0QVBJS2V5IEtleSBmb3IgUkVTVCBjYWxsc1xuICogQHByb3BlcnR5IHtCb29sZWFufSByZXZva2VTZXNzaW9uT25QYXNzd29yZFJlc2V0IFdoZW4gYSB1c2VyIGNoYW5nZXMgdGhlaXIgcGFzc3dvcmQsIGVpdGhlciB0aHJvdWdoIHRoZSByZXNldCBwYXNzd29yZCBlbWFpbCBvciB3aGlsZSBsb2dnZWQgaW4sIGFsbCBzZXNzaW9ucyBhcmUgcmV2b2tlZCBpZiB0aGlzIGlzIHRydWUuIFNldCB0byBmYWxzZSBpZiB5b3UgZG9uJ3Qgd2FudCB0byByZXZva2Ugc2Vzc2lvbnMuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHNjaGVkdWxlZFB1c2ggQ29uZmlndXJhdGlvbiBmb3IgcHVzaCBzY2hlZHVsaW5nLCBkZWZhdWx0cyB0byBmYWxzZS5cbiAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBzY2hlbWFDYWNoZVRUTCBUaGUgVFRMIGZvciBjYWNoaW5nIHRoZSBzY2hlbWEgZm9yIG9wdGltaXppbmcgcmVhZC93cml0ZSBvcGVyYXRpb25zLiBZb3Ugc2hvdWxkIHB1dCBhIGxvbmcgVFRMIHdoZW4geW91ciBEQiBpcyBpbiBwcm9kdWN0aW9uLiBkZWZhdWx0IHRvIDUwMDA7IHNldCAwIHRvIGRpc2FibGUuXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBzZXJ2ZXJDbG9zZUNvbXBsZXRlIENhbGxiYWNrIHdoZW4gc2VydmVyIGhhcyBjbG9zZWRcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IHNlcnZlclN0YXJ0Q29tcGxldGUgQ2FsbGJhY2sgd2hlbiBzZXJ2ZXIgaGFzIHN0YXJ0ZWRcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBzZXJ2ZXJVUkwgVVJMIHRvIHlvdXIgcGFyc2Ugc2VydmVyIHdpdGggaHR0cDovLyBvciBodHRwczovLy5cbiAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBzZXNzaW9uTGVuZ3RoIFNlc3Npb24gZHVyYXRpb24sIGluIHNlY29uZHMsIGRlZmF1bHRzIHRvIDEgeWVhclxuICogQHByb3BlcnR5IHtCb29sZWFufSBzaWxlbnQgRGlzYWJsZXMgY29uc29sZSBvdXRwdXRcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gc3RhcnRMaXZlUXVlcnlTZXJ2ZXIgU3RhcnRzIHRoZSBsaXZlUXVlcnkgc2VydmVyXG4gKiBAcHJvcGVydHkge1N0cmluZ1tdfSB1c2VyU2Vuc2l0aXZlRmllbGRzIFBlcnNvbmFsbHkgaWRlbnRpZmlhYmxlIGluZm9ybWF0aW9uIGZpZWxkcyBpbiB0aGUgdXNlciB0YWJsZSB0aGUgc2hvdWxkIGJlIHJlbW92ZWQgZm9yIG5vbi1hdXRob3JpemVkIHVzZXJzLiBEZXByZWNhdGVkIEBzZWUgcHJvdGVjdGVkRmllbGRzXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHZlcmJvc2UgU2V0IHRoZSBsb2dnaW5nIHRvIHZlcmJvc2VcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gdmVyaWZ5VXNlckVtYWlscyBFbmFibGUgKG9yIGRpc2FibGUpIHVzZXIgZW1haWwgdmFsaWRhdGlvbiwgZGVmYXVsdHMgdG8gZmFsc2VcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSB3ZWJob29rS2V5IEtleSBzZW50IHdpdGggb3V0Z29pbmcgd2ViaG9vayBjYWxsc1xuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBQYWdlc09wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7UGFnZXNDdXN0b21VcmxzT3B0aW9uc30gY3VzdG9tVXJscyBUaGUgVVJMcyB0byB0aGUgY3VzdG9tIHBhZ2VzLlxuICogQHByb3BlcnR5IHtCb29sZWFufSBlbmFibGVMb2NhbGl6YXRpb24gSXMgdHJ1ZSBpZiBwYWdlcyBzaG91bGQgYmUgbG9jYWxpemVkOyB0aGlzIGhhcyBubyBlZmZlY3Qgb24gY3VzdG9tIHBhZ2UgcmVkaXJlY3RzLlxuICogQHByb3BlcnR5IHtCb29sZWFufSBlbmFibGVSb3V0ZXIgSXMgdHJ1ZSBpZiB0aGUgcGFnZXMgcm91dGVyIHNob3VsZCBiZSBlbmFibGVkOyB0aGlzIGlzIHJlcXVpcmVkIGZvciBhbnkgb2YgdGhlIHBhZ2VzIG9wdGlvbnMgdG8gdGFrZSBlZmZlY3QuIENhdXRpb24sIHRoaXMgaXMgYW4gZXhwZXJpbWVudGFsIGZlYXR1cmUgdGhhdCBtYXkgbm90IGJlIGFwcHJvcHJpYXRlIGZvciBwcm9kdWN0aW9uLlxuICogQHByb3BlcnR5IHtCb29sZWFufSBmb3JjZVJlZGlyZWN0IElzIHRydWUgaWYgcmVzcG9uc2VzIHNob3VsZCBhbHdheXMgYmUgcmVkaXJlY3RzIGFuZCBuZXZlciBjb250ZW50LCBmYWxzZSBpZiB0aGUgcmVzcG9uc2UgdHlwZSBzaG91bGQgZGVwZW5kIG9uIHRoZSByZXF1ZXN0IHR5cGUgKEdFVCByZXF1ZXN0IC0+IGNvbnRlbnQgcmVzcG9uc2U7IFBPU1QgcmVxdWVzdCAtPiByZWRpcmVjdCByZXNwb25zZSkuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gbG9jYWxpemF0aW9uRmFsbGJhY2tMb2NhbGUgVGhlIGZhbGxiYWNrIGxvY2FsZSBmb3IgbG9jYWxpemF0aW9uIGlmIG5vIG1hdGNoaW5nIHRyYW5zbGF0aW9uIGlzIHByb3ZpZGVkIGZvciB0aGUgZ2l2ZW4gbG9jYWxlLiBUaGlzIGlzIG9ubHkgcmVsZXZhbnQgd2hlbiBwcm92aWRpbmcgdHJhbnNsYXRpb24gcmVzb3VyY2VzIHZpYSBKU09OIGZpbGUuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gbG9jYWxpemF0aW9uSnNvblBhdGggVGhlIHBhdGggdG8gdGhlIEpTT04gZmlsZSBmb3IgbG9jYWxpemF0aW9uOyB0aGUgdHJhbnNsYXRpb25zIHdpbGwgYmUgdXNlZCB0byBmaWxsIHRlbXBsYXRlIHBsYWNlaG9sZGVycyBhY2NvcmRpbmcgdG8gdGhlIGxvY2FsZS5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBwYWdlc0VuZHBvaW50IFRoZSBBUEkgZW5kcG9pbnQgZm9yIHRoZSBwYWdlcy4gRGVmYXVsdCBpcyAnYXBwcycuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcGFnZXNQYXRoIFRoZSBwYXRoIHRvIHRoZSBwYWdlcyBkaXJlY3Rvcnk7IHRoaXMgYWxzbyBkZWZpbmVzIHdoZXJlIHRoZSBzdGF0aWMgZW5kcG9pbnQgJy9hcHBzJyBwb2ludHMgdG8uIERlZmF1bHQgaXMgdGhlICcuL3B1YmxpYy8nIGRpcmVjdG9yeS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBwbGFjZWhvbGRlcnMgVGhlIHBsYWNlaG9sZGVyIGtleXMgYW5kIHZhbHVlcyB3aGljaCB3aWxsIGJlIGZpbGxlZCBpbiBwYWdlczsgdGhpcyBjYW4gYmUgYSBzaW1wbGUgb2JqZWN0IG9yIGEgY2FsbGJhY2sgZnVuY3Rpb24uXG4gKi9cblxuLyoqXG4gKiBAaW50ZXJmYWNlIFBhZ2VzQ3VzdG9tVXJsc09wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBlbWFpbFZlcmlmaWNhdGlvbkxpbmtFeHBpcmVkIFRoZSBVUkwgdG8gdGhlIGN1c3RvbSBwYWdlIGZvciBlbWFpbCB2ZXJpZmljYXRpb24gLT4gbGluayBleHBpcmVkLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGVtYWlsVmVyaWZpY2F0aW9uTGlua0ludmFsaWQgVGhlIFVSTCB0byB0aGUgY3VzdG9tIHBhZ2UgZm9yIGVtYWlsIHZlcmlmaWNhdGlvbiAtPiBsaW5rIGludmFsaWQuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gZW1haWxWZXJpZmljYXRpb25TZW5kRmFpbCBUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgZW1haWwgdmVyaWZpY2F0aW9uIC0+IGxpbmsgc2VuZCBmYWlsLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGVtYWlsVmVyaWZpY2F0aW9uU2VuZFN1Y2Nlc3MgVGhlIFVSTCB0byB0aGUgY3VzdG9tIHBhZ2UgZm9yIGVtYWlsIHZlcmlmaWNhdGlvbiAtPiByZXNlbmQgbGluayAtPiBzdWNjZXNzLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGVtYWlsVmVyaWZpY2F0aW9uU3VjY2VzcyBUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgZW1haWwgdmVyaWZpY2F0aW9uIC0+IHN1Y2Nlc3MuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcGFzc3dvcmRSZXNldCBUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgcGFzc3dvcmQgcmVzZXQuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcGFzc3dvcmRSZXNldExpbmtJbnZhbGlkIFRoZSBVUkwgdG8gdGhlIGN1c3RvbSBwYWdlIGZvciBwYXNzd29yZCByZXNldCAtPiBsaW5rIGludmFsaWQuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcGFzc3dvcmRSZXNldFN1Y2Nlc3MgVGhlIFVSTCB0byB0aGUgY3VzdG9tIHBhZ2UgZm9yIHBhc3N3b3JkIHJlc2V0IC0+IHN1Y2Nlc3MuXG4gKi9cblxuLyoqXG4gKiBAaW50ZXJmYWNlIEN1c3RvbVBhZ2VzT3B0aW9uc1xuICogQHByb3BlcnR5IHtTdHJpbmd9IGNob29zZVBhc3N3b3JkIGNob29zZSBwYXNzd29yZCBwYWdlIHBhdGhcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBleHBpcmVkVmVyaWZpY2F0aW9uTGluayBleHBpcmVkIHZlcmlmaWNhdGlvbiBsaW5rIHBhZ2UgcGF0aFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGludmFsaWRMaW5rIGludmFsaWQgbGluayBwYWdlIHBhdGhcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpbnZhbGlkUGFzc3dvcmRSZXNldExpbmsgaW52YWxpZCBwYXNzd29yZCByZXNldCBsaW5rIHBhZ2UgcGF0aFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGludmFsaWRWZXJpZmljYXRpb25MaW5rIGludmFsaWQgdmVyaWZpY2F0aW9uIGxpbmsgcGFnZSBwYXRoXG4gKiBAcHJvcGVydHkge1N0cmluZ30gbGlua1NlbmRGYWlsIHZlcmlmaWNhdGlvbiBsaW5rIHNlbmQgZmFpbCBwYWdlIHBhdGhcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBsaW5rU2VuZFN1Y2Nlc3MgdmVyaWZpY2F0aW9uIGxpbmsgc2VuZCBzdWNjZXNzIHBhZ2UgcGF0aFxuICogQHByb3BlcnR5IHtTdHJpbmd9IHBhcnNlRnJhbWVVUkwgZm9yIG1hc2tpbmcgdXNlci1mYWNpbmcgcGFnZXNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBwYXNzd29yZFJlc2V0U3VjY2VzcyBwYXNzd29yZCByZXNldCBzdWNjZXNzIHBhZ2UgcGF0aFxuICogQHByb3BlcnR5IHtTdHJpbmd9IHZlcmlmeUVtYWlsU3VjY2VzcyB2ZXJpZnkgZW1haWwgc3VjY2VzcyBwYWdlIHBhdGhcbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgTGl2ZVF1ZXJ5T3B0aW9uc1xuICogQHByb3BlcnR5IHtTdHJpbmdbXX0gY2xhc3NOYW1lcyBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgY2xhc3NOYW1lc1xuICogQHByb3BlcnR5IHtBZGFwdGVyPFB1YlN1YkFkYXB0ZXI+fSBwdWJTdWJBZGFwdGVyIExpdmVRdWVyeSBwdWJzdWIgYWRhcHRlclxuICogQHByb3BlcnR5IHtBbnl9IHJlZGlzT3B0aW9ucyBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgcmVkaXNPcHRpb25zXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcmVkaXNVUkwgcGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IHJlZGlzVVJMXG4gKiBAcHJvcGVydHkge0FkYXB0ZXI8V1NTQWRhcHRlcj59IHdzc0FkYXB0ZXIgQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBXZWJTb2NrZXRTZXJ2ZXJcbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgTGl2ZVF1ZXJ5U2VydmVyT3B0aW9uc1xuICogQHByb3BlcnR5IHtTdHJpbmd9IGFwcElkIFRoaXMgc3RyaW5nIHNob3VsZCBtYXRjaCB0aGUgYXBwSWQgaW4gdXNlIGJ5IHlvdXIgUGFyc2UgU2VydmVyLiBJZiB5b3UgZGVwbG95IHRoZSBMaXZlUXVlcnkgc2VydmVyIGFsb25nc2lkZSBQYXJzZSBTZXJ2ZXIsIHRoZSBMaXZlUXVlcnkgc2VydmVyIHdpbGwgdHJ5IHRvIHVzZSB0aGUgc2FtZSBhcHBJZC5cbiAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBjYWNoZVRpbWVvdXQgTnVtYmVyIGluIG1pbGxpc2Vjb25kcy4gV2hlbiBjbGllbnRzIHByb3ZpZGUgdGhlIHNlc3Npb25Ub2tlbiB0byB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciwgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgd2lsbCB0cnkgdG8gZmV0Y2ggaXRzIFBhcnNlVXNlcidzIG9iamVjdElkIGZyb20gcGFyc2Ugc2VydmVyIGFuZCBzdG9yZSBpdCBpbiB0aGUgY2FjaGUuIFRoZSB2YWx1ZSBkZWZpbmVzIHRoZSBkdXJhdGlvbiBvZiB0aGUgY2FjaGUuIENoZWNrIHRoZSBmb2xsb3dpbmcgU2VjdXJpdHkgc2VjdGlvbiBhbmQgb3VyIHByb3RvY29sIHNwZWNpZmljYXRpb24gZm9yIGRldGFpbHMsIGRlZmF1bHRzIHRvIDUgKiAxMDAwIG1zICg1IHNlY29uZHMpLlxuICogQHByb3BlcnR5IHtBbnl9IGtleVBhaXJzIEEgSlNPTiBvYmplY3QgdGhhdCBzZXJ2ZXMgYXMgYSB3aGl0ZWxpc3Qgb2Yga2V5cy4gSXQgaXMgdXNlZCBmb3IgdmFsaWRhdGluZyBjbGllbnRzIHdoZW4gdGhleSB0cnkgdG8gY29ubmVjdCB0byB0aGUgTGl2ZVF1ZXJ5IHNlcnZlci4gQ2hlY2sgdGhlIGZvbGxvd2luZyBTZWN1cml0eSBzZWN0aW9uIGFuZCBvdXIgcHJvdG9jb2wgc3BlY2lmaWNhdGlvbiBmb3IgZGV0YWlscy5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBsb2dMZXZlbCBUaGlzIHN0cmluZyBkZWZpbmVzIHRoZSBsb2cgbGV2ZWwgb2YgdGhlIExpdmVRdWVyeSBzZXJ2ZXIuIFdlIHN1cHBvcnQgVkVSQk9TRSwgSU5GTywgRVJST1IsIE5PTkUsIGRlZmF1bHRzIHRvIElORk8uXG4gKiBAcHJvcGVydHkge1N0cmluZ30gbWFzdGVyS2V5IFRoaXMgc3RyaW5nIHNob3VsZCBtYXRjaCB0aGUgbWFzdGVyS2V5IGluIHVzZSBieSB5b3VyIFBhcnNlIFNlcnZlci4gSWYgeW91IGRlcGxveSB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciBhbG9uZ3NpZGUgUGFyc2UgU2VydmVyLCB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciB3aWxsIHRyeSB0byB1c2UgdGhlIHNhbWUgbWFzdGVyS2V5LlxuICogQHByb3BlcnR5IHtOdW1iZXJ9IHBvcnQgVGhlIHBvcnQgdG8gcnVuIHRoZSBMaXZlUXVlcnkgc2VydmVyLCBkZWZhdWx0cyB0byAxMzM3LlxuICogQHByb3BlcnR5IHtBZGFwdGVyPFB1YlN1YkFkYXB0ZXI+fSBwdWJTdWJBZGFwdGVyIExpdmVRdWVyeSBwdWJzdWIgYWRhcHRlclxuICogQHByb3BlcnR5IHtBbnl9IHJlZGlzT3B0aW9ucyBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgcmVkaXNPcHRpb25zXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcmVkaXNVUkwgcGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IHJlZGlzVVJMXG4gKiBAcHJvcGVydHkge1N0cmluZ30gc2VydmVyVVJMIFRoaXMgc3RyaW5nIHNob3VsZCBtYXRjaCB0aGUgc2VydmVyVVJMIGluIHVzZSBieSB5b3VyIFBhcnNlIFNlcnZlci4gSWYgeW91IGRlcGxveSB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciBhbG9uZ3NpZGUgUGFyc2UgU2VydmVyLCB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciB3aWxsIHRyeSB0byB1c2UgdGhlIHNhbWUgc2VydmVyVVJMLlxuICogQHByb3BlcnR5IHtOdW1iZXJ9IHdlYnNvY2tldFRpbWVvdXQgTnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBiZXR3ZWVuIHBpbmcvcG9uZyBmcmFtZXMuIFRoZSBXZWJTb2NrZXQgc2VydmVyIHNlbmRzIHBpbmcvcG9uZyBmcmFtZXMgdG8gdGhlIGNsaWVudHMgdG8ga2VlcCB0aGUgV2ViU29ja2V0IGFsaXZlLiBUaGlzIHZhbHVlIGRlZmluZXMgdGhlIGludGVydmFsIG9mIHRoZSBwaW5nL3BvbmcgZnJhbWUgZnJvbSB0aGUgc2VydmVyIHRvIGNsaWVudHMsIGRlZmF1bHRzIHRvIDEwICogMTAwMCBtcyAoMTAgcykuXG4gKiBAcHJvcGVydHkge0FkYXB0ZXI8V1NTQWRhcHRlcj59IHdzc0FkYXB0ZXIgQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBXZWJTb2NrZXRTZXJ2ZXJcbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgSWRlbXBvdGVuY3lPcHRpb25zXG4gKiBAcHJvcGVydHkge1N0cmluZ1tdfSBwYXRocyBBbiBhcnJheSBvZiBwYXRocyBmb3Igd2hpY2ggdGhlIGZlYXR1cmUgc2hvdWxkIGJlIGVuYWJsZWQuIFRoZSBtb3VudCBwYXRoIG11c3Qgbm90IGJlIGluY2x1ZGVkLCBmb3IgZXhhbXBsZSBpbnN0ZWFkIG9mIGAvcGFyc2UvZnVuY3Rpb25zL215RnVuY3Rpb25gIHNwZWNpZml5IGBmdW5jdGlvbnMvbXlGdW5jdGlvbmAuIFRoZSBlbnRyaWVzIGFyZSBpbnRlcnByZXRlZCBhcyByZWd1bGFyIGV4cHJlc3Npb24sIGZvciBleGFtcGxlIGBmdW5jdGlvbnMvLipgIG1hdGNoZXMgYWxsIGZ1bmN0aW9ucywgYGpvYnMvLipgIG1hdGNoZXMgYWxsIGpvYnMsIGBjbGFzc2VzLy4qYCBtYXRjaGVzIGFsbCBjbGFzc2VzLCBgLipgIG1hdGNoZXMgYWxsIHBhdGhzLlxuICogQHByb3BlcnR5IHtOdW1iZXJ9IHR0bCBUaGUgZHVyYXRpb24gaW4gc2Vjb25kcyBhZnRlciB3aGljaCBhIHJlcXVlc3QgcmVjb3JkIGlzIGRpc2NhcmRlZCBmcm9tIHRoZSBkYXRhYmFzZSwgZGVmYXVsdHMgdG8gMzAwcy5cbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgQWNjb3VudExvY2tvdXRPcHRpb25zXG4gKiBAcHJvcGVydHkge051bWJlcn0gZHVyYXRpb24gbnVtYmVyIG9mIG1pbnV0ZXMgdGhhdCBhIGxvY2tlZC1vdXQgYWNjb3VudCByZW1haW5zIGxvY2tlZCBvdXQgYmVmb3JlIGF1dG9tYXRpY2FsbHkgYmVjb21pbmcgdW5sb2NrZWQuXG4gKiBAcHJvcGVydHkge051bWJlcn0gdGhyZXNob2xkIG51bWJlciBvZiBmYWlsZWQgc2lnbi1pbiBhdHRlbXB0cyB0aGF0IHdpbGwgY2F1c2UgYSB1c2VyIGFjY291bnQgdG8gYmUgbG9ja2VkXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHVubG9ja09uUGFzc3dvcmRSZXNldCBJcyB0cnVlIGlmIHRoZSBhY2NvdW50IGxvY2sgc2hvdWxkIGJlIHJlbW92ZWQgYWZ0ZXIgYSBzdWNjZXNzZnVsIHBhc3N3b3JkIHJlc2V0LlxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBQYXNzd29yZFBvbGljeU9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gZG9Ob3RBbGxvd1VzZXJuYW1lIGRpc2FsbG93IHVzZXJuYW1lIGluIHBhc3N3b3Jkc1xuICogQHByb3BlcnR5IHtOdW1iZXJ9IG1heFBhc3N3b3JkQWdlIGRheXMgZm9yIHBhc3N3b3JkIGV4cGlyeVxuICogQHByb3BlcnR5IHtOdW1iZXJ9IG1heFBhc3N3b3JkSGlzdG9yeSBzZXR0aW5nIHRvIHByZXZlbnQgcmV1c2Ugb2YgcHJldmlvdXMgbiBwYXNzd29yZHNcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gcmVzZXRUb2tlblJldXNlSWZWYWxpZCByZXNlbmQgdG9rZW4gaWYgaXQncyBzdGlsbCB2YWxpZFxuICogQHByb3BlcnR5IHtOdW1iZXJ9IHJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uIHRpbWUgZm9yIHRva2VuIHRvIGV4cGlyZVxuICogQHByb3BlcnR5IHtGdW5jdGlvbn0gdmFsaWRhdG9yQ2FsbGJhY2sgYSBjYWxsYmFjayBmdW5jdGlvbiB0byBiZSBpbnZva2VkIHRvIHZhbGlkYXRlIHRoZSBwYXNzd29yZFxuICogQHByb3BlcnR5IHtTdHJpbmd9IHZhbGlkYXRvclBhdHRlcm4gYSBSZWdFeHAgb2JqZWN0IG9yIGEgcmVnZXggc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgcGF0dGVybiB0byBlbmZvcmNlXG4gKi9cblxuLyoqXG4gKiBAaW50ZXJmYWNlIEZpbGVVcGxvYWRPcHRpb25zXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGVuYWJsZUZvckFub255bW91c1VzZXIgSXMgdHJ1ZSBpZiBmaWxlIHVwbG9hZCBzaG91bGQgYmUgYWxsb3dlZCBmb3IgYW5vbnltb3VzIHVzZXJzLlxuICogQHByb3BlcnR5IHtCb29sZWFufSBlbmFibGVGb3JBdXRoZW50aWNhdGVkVXNlciBJcyB0cnVlIGlmIGZpbGUgdXBsb2FkIHNob3VsZCBiZSBhbGxvd2VkIGZvciBhdXRoZW50aWNhdGVkIHVzZXJzLlxuICogQHByb3BlcnR5IHtCb29sZWFufSBlbmFibGVGb3JQdWJsaWMgSXMgdHJ1ZSBpZiBmaWxlIHVwbG9hZCBzaG91bGQgYmUgYWxsb3dlZCBmb3IgYW55b25lLCByZWdhcmRsZXNzIG9mIHVzZXIgYXV0aGVudGljYXRpb24uXG4gKi9cbiJdfQ== \ No newline at end of file diff --git a/lib/Options/index.js b/lib/Options/index.js new file mode 100644 index 0000000000..19f00164db --- /dev/null +++ b/lib/Options/index.js @@ -0,0 +1,18 @@ +"use strict"; + +var _AnalyticsAdapter = require("../Adapters/Analytics/AnalyticsAdapter"); + +var _FilesAdapter = require("../Adapters/Files/FilesAdapter"); + +var _LoggerAdapter = require("../Adapters/Logger/LoggerAdapter"); + +var _StorageAdapter = require("../Adapters/Storage/StorageAdapter"); + +var _CacheAdapter = require("../Adapters/Cache/CacheAdapter"); + +var _MailAdapter = require("../Adapters/Email/MailAdapter"); + +var _PubSubAdapter = require("../Adapters/PubSub/PubSubAdapter"); + +var _WSSAdapter = require("../Adapters/WebSocketServer/WSSAdapter"); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9PcHRpb25zL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0EiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBbmFseXRpY3NBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvQW5hbHl0aWNzL0FuYWx5dGljc0FkYXB0ZXInO1xuaW1wb3J0IHsgRmlsZXNBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvRmlsZXMvRmlsZXNBZGFwdGVyJztcbmltcG9ydCB7IExvZ2dlckFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9Mb2dnZXIvTG9nZ2VyQWRhcHRlcic7XG5pbXBvcnQgeyBTdG9yYWdlQWRhcHRlciB9IGZyb20gJy4uL0FkYXB0ZXJzL1N0b3JhZ2UvU3RvcmFnZUFkYXB0ZXInO1xuaW1wb3J0IHsgQ2FjaGVBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvQ2FjaGUvQ2FjaGVBZGFwdGVyJztcbmltcG9ydCB7IE1haWxBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvRW1haWwvTWFpbEFkYXB0ZXInO1xuaW1wb3J0IHsgUHViU3ViQWRhcHRlciB9IGZyb20gJy4uL0FkYXB0ZXJzL1B1YlN1Yi9QdWJTdWJBZGFwdGVyJztcbmltcG9ydCB7IFdTU0FkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9XZWJTb2NrZXRTZXJ2ZXIvV1NTQWRhcHRlcic7XG5cbi8vIEBmbG93XG50eXBlIEFkYXB0ZXI8VD4gPSBzdHJpbmcgfCBhbnkgfCBUO1xudHlwZSBOdW1iZXJPckJvb2xlYW4gPSBudW1iZXIgfCBib29sZWFuO1xudHlwZSBOdW1iZXJPclN0cmluZyA9IG51bWJlciB8IHN0cmluZztcbnR5cGUgUHJvdGVjdGVkRmllbGRzID0gYW55O1xuXG5leHBvcnQgaW50ZXJmYWNlIFBhcnNlU2VydmVyT3B0aW9ucyB7XG4gIC8qIFlvdXIgUGFyc2UgQXBwbGljYXRpb24gSURcbiAgOkVOVjogUEFSU0VfU0VSVkVSX0FQUExJQ0FUSU9OX0lEICovXG4gIGFwcElkOiBzdHJpbmc7XG4gIC8qIFlvdXIgUGFyc2UgTWFzdGVyIEtleSAqL1xuICBtYXN0ZXJLZXk6IHN0cmluZztcbiAgLyogVVJMIHRvIHlvdXIgcGFyc2Ugc2VydmVyIHdpdGggaHR0cDovLyBvciBodHRwczovLy5cbiAgOkVOVjogUEFSU0VfU0VSVkVSX1VSTCAqL1xuICBzZXJ2ZXJVUkw6IHN0cmluZztcbiAgLyogUmVzdHJpY3QgbWFzdGVyS2V5IHRvIGJlIHVzZWQgYnkgb25seSB0aGVzZSBpcHMsIGRlZmF1bHRzIHRvIFtdIChhbGxvdyBhbGwgaXBzKVxuICA6REVGQVVMVDogW10gKi9cbiAgbWFzdGVyS2V5SXBzOiA/KHN0cmluZ1tdKTtcbiAgLyogU2V0cyB0aGUgYXBwIG5hbWUgKi9cbiAgYXBwTmFtZTogP3N0cmluZztcbiAgLyogQWRkIGhlYWRlcnMgdG8gQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycyAqL1xuICBhbGxvd0hlYWRlcnM6ID8oc3RyaW5nW10pO1xuICAvKiBTZXRzIHRoZSBvcmlnaW4gdG8gQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luICovXG4gIGFsbG93T3JpZ2luOiA/c3RyaW5nO1xuICAvKiBBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGFuYWx5dGljcyAqL1xuICBhbmFseXRpY3NBZGFwdGVyOiA/QWRhcHRlcjxBbmFseXRpY3NBZGFwdGVyPjtcbiAgLyogQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBmaWxlcyBzdWItc3lzdGVtICovXG4gIGZpbGVzQWRhcHRlcjogP0FkYXB0ZXI8RmlsZXNBZGFwdGVyPjtcbiAgLyogQ29uZmlndXJhdGlvbiBmb3IgcHVzaCwgYXMgc3RyaW5naWZpZWQgSlNPTi4gU2VlIGh0dHA6Ly9kb2NzLnBhcnNlcGxhdGZvcm0ub3JnL3BhcnNlLXNlcnZlci9ndWlkZS8jcHVzaC1ub3RpZmljYXRpb25zICovXG4gIHB1c2g6ID9hbnk7XG4gIC8qIENvbmZpZ3VyYXRpb24gZm9yIHB1c2ggc2NoZWR1bGluZywgZGVmYXVsdHMgdG8gZmFsc2UuXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICBzY2hlZHVsZWRQdXNoOiA/Ym9vbGVhbjtcbiAgLyogQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBsb2dnaW5nIHN1Yi1zeXN0ZW0gKi9cbiAgbG9nZ2VyQWRhcHRlcjogP0FkYXB0ZXI8TG9nZ2VyQWRhcHRlcj47XG4gIC8qIExvZyBhcyBzdHJ1Y3R1cmVkIEpTT04gb2JqZWN0c1xuICA6RU5WOiBKU09OX0xPR1MgKi9cbiAganNvbkxvZ3M6ID9ib29sZWFuO1xuICAvKiBGb2xkZXIgZm9yIHRoZSBsb2dzIChkZWZhdWx0cyB0byAnLi9sb2dzJyk7IHNldCB0byBudWxsIHRvIGRpc2FibGUgZmlsZSBiYXNlZCBsb2dnaW5nXG4gIDpFTlY6IFBBUlNFX1NFUlZFUl9MT0dTX0ZPTERFUlxuICA6REVGQVVMVDogLi9sb2dzICovXG4gIGxvZ3NGb2xkZXI6ID9zdHJpbmc7XG4gIC8qIFNldCB0aGUgbG9nZ2luZyB0byB2ZXJib3NlXG4gIDpFTlY6IFZFUkJPU0UgKi9cbiAgdmVyYm9zZTogP2Jvb2xlYW47XG4gIC8qIFNldHMgdGhlIGxldmVsIGZvciBsb2dzICovXG4gIGxvZ0xldmVsOiA/c3RyaW5nO1xuICAvKiBNYXhpbXVtIG51bWJlciBvZiBsb2dzIHRvIGtlZXAuIElmIG5vdCBzZXQsIG5vIGxvZ3Mgd2lsbCBiZSByZW1vdmVkLiBUaGlzIGNhbiBiZSBhIG51bWJlciBvZiBmaWxlcyBvciBudW1iZXIgb2YgZGF5cy4gSWYgdXNpbmcgZGF5cywgYWRkICdkJyBhcyB0aGUgc3VmZml4LiAoZGVmYXVsdDogbnVsbCkgKi9cbiAgbWF4TG9nRmlsZXM6ID9OdW1iZXJPclN0cmluZztcbiAgLyogRGlzYWJsZXMgY29uc29sZSBvdXRwdXRcbiAgOkVOVjogU0lMRU5UICovXG4gIHNpbGVudDogP2Jvb2xlYW47XG4gIC8qIFRoZSBmdWxsIFVSSSB0byB5b3VyIGRhdGFiYXNlLiBTdXBwb3J0ZWQgZGF0YWJhc2VzIGFyZSBtb25nb2RiIG9yIHBvc3RncmVzLlxuICA6REVGQVVMVDogbW9uZ29kYjovL2xvY2FsaG9zdDoyNzAxNy9wYXJzZSAqL1xuICBkYXRhYmFzZVVSSTogc3RyaW5nO1xuICAvKiBPcHRpb25zIHRvIHBhc3MgdG8gdGhlIG1vbmdvZGIgY2xpZW50ICovXG4gIGRhdGFiYXNlT3B0aW9uczogP2FueTtcbiAgLyogQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBkYXRhYmFzZSAqL1xuICBkYXRhYmFzZUFkYXB0ZXI6ID9BZGFwdGVyPFN0b3JhZ2VBZGFwdGVyPjtcbiAgLyogRnVsbCBwYXRoIHRvIHlvdXIgY2xvdWQgY29kZSBtYWluLmpzICovXG4gIGNsb3VkOiA/c3RyaW5nO1xuICAvKiBBIGNvbGxlY3Rpb24gcHJlZml4IGZvciB0aGUgY2xhc3Nlc1xuICA6REVGQVVMVDogJycgKi9cbiAgY29sbGVjdGlvblByZWZpeDogP3N0cmluZztcbiAgLyogS2V5IGZvciBpT1MsIE1hY09TLCB0dk9TIGNsaWVudHMgKi9cbiAgY2xpZW50S2V5OiA/c3RyaW5nO1xuICAvKiBLZXkgZm9yIHRoZSBKYXZhc2NyaXB0IFNESyAqL1xuICBqYXZhc2NyaXB0S2V5OiA/c3RyaW5nO1xuICAvKiBLZXkgZm9yIFVuaXR5IGFuZCAuTmV0IFNESyAqL1xuICBkb3ROZXRLZXk6ID9zdHJpbmc7XG4gIC8qIEtleSBmb3IgZW5jcnlwdGluZyB5b3VyIGZpbGVzXG4gIDpFTlY6IFBBUlNFX1NFUlZFUl9FTkNSWVBUSU9OX0tFWSAqL1xuICBlbmNyeXB0aW9uS2V5OiA/c3RyaW5nO1xuICAvKiBLZXkgZm9yIFJFU1QgY2FsbHNcbiAgOkVOVjogUEFSU0VfU0VSVkVSX1JFU1RfQVBJX0tFWSAqL1xuICByZXN0QVBJS2V5OiA/c3RyaW5nO1xuICAvKiBSZWFkLW9ubHkga2V5LCB3aGljaCBoYXMgdGhlIHNhbWUgY2FwYWJpbGl0aWVzIGFzIE1hc3RlcktleSB3aXRob3V0IHdyaXRlcyAqL1xuICByZWFkT25seU1hc3RlcktleTogP3N0cmluZztcbiAgLyogS2V5IHNlbnQgd2l0aCBvdXRnb2luZyB3ZWJob29rIGNhbGxzICovXG4gIHdlYmhvb2tLZXk6ID9zdHJpbmc7XG4gIC8qIEtleSBmb3IgeW91ciBmaWxlcyAqL1xuICBmaWxlS2V5OiA/c3RyaW5nO1xuICAvKiBFbmFibGUgKG9yIGRpc2FibGUpIHRoZSBhZGRpdGlvbiBvZiBhIHVuaXF1ZSBoYXNoIHRvIHRoZSBmaWxlIG5hbWVzXG4gIDpFTlY6IFBBUlNFX1NFUlZFUl9QUkVTRVJWRV9GSUxFX05BTUVcbiAgOkRFRkFVTFQ6IGZhbHNlICovXG4gIHByZXNlcnZlRmlsZU5hbWU6ID9ib29sZWFuO1xuICAvKiBQZXJzb25hbGx5IGlkZW50aWZpYWJsZSBpbmZvcm1hdGlvbiBmaWVsZHMgaW4gdGhlIHVzZXIgdGFibGUgdGhlIHNob3VsZCBiZSByZW1vdmVkIGZvciBub24tYXV0aG9yaXplZCB1c2Vycy4gRGVwcmVjYXRlZCBAc2VlIHByb3RlY3RlZEZpZWxkcyAqL1xuICB1c2VyU2Vuc2l0aXZlRmllbGRzOiA/KHN0cmluZ1tdKTtcbiAgLyogUHJvdGVjdGVkIGZpZWxkcyB0aGF0IHNob3VsZCBiZSB0cmVhdGVkIHdpdGggZXh0cmEgc2VjdXJpdHkgd2hlbiBmZXRjaGluZyBkZXRhaWxzLlxuICA6REVGQVVMVDoge1wiX1VzZXJcIjoge1wiKlwiOiBbXCJlbWFpbFwiXX19ICovXG4gIHByb3RlY3RlZEZpZWxkczogP1Byb3RlY3RlZEZpZWxkcztcbiAgLyogRW5hYmxlIChvciBkaXNhYmxlKSBhbm9ueW1vdXMgdXNlcnMsIGRlZmF1bHRzIHRvIHRydWVcbiAgOkVOVjogUEFSU0VfU0VSVkVSX0VOQUJMRV9BTk9OX1VTRVJTXG4gIDpERUZBVUxUOiB0cnVlICovXG4gIGVuYWJsZUFub255bW91c1VzZXJzOiA/Ym9vbGVhbjtcbiAgLyogRW5hYmxlIChvciBkaXNhYmxlKSBjbGllbnQgY2xhc3MgY3JlYXRpb24sIGRlZmF1bHRzIHRvIHRydWVcbiAgOkVOVjogUEFSU0VfU0VSVkVSX0FMTE9XX0NMSUVOVF9DTEFTU19DUkVBVElPTlxuICA6REVGQVVMVDogdHJ1ZSAqL1xuICBhbGxvd0NsaWVudENsYXNzQ3JlYXRpb246ID9ib29sZWFuO1xuICAvKiBFbmFibGUgKG9yIGRpc2FibGUpIGN1c3RvbSBvYmplY3RJZFxuICA6RU5WOiBQQVJTRV9TRVJWRVJfQUxMT1dfQ1VTVE9NX09CSkVDVF9JRFxuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgYWxsb3dDdXN0b21PYmplY3RJZDogP2Jvb2xlYW47XG4gIC8qIENvbmZpZ3VyYXRpb24gZm9yIHlvdXIgYXV0aGVudGljYXRpb24gcHJvdmlkZXJzLCBhcyBzdHJpbmdpZmllZCBKU09OLiBTZWUgaHR0cDovL2RvY3MucGFyc2VwbGF0Zm9ybS5vcmcvcGFyc2Utc2VydmVyL2d1aWRlLyNvYXV0aC1hbmQtM3JkLXBhcnR5LWF1dGhlbnRpY2F0aW9uXG4gIDpFTlY6IFBBUlNFX1NFUlZFUl9BVVRIX1BST1ZJREVSUyAqL1xuICBhdXRoOiA/YW55O1xuICAvKiBNYXggZmlsZSBzaXplIGZvciB1cGxvYWRzLCBkZWZhdWx0cyB0byAyMG1iXG4gIDpERUZBVUxUOiAyMG1iICovXG4gIG1heFVwbG9hZFNpemU6ID9zdHJpbmc7XG4gIC8qIEVuYWJsZSAob3IgZGlzYWJsZSkgdXNlciBlbWFpbCB2YWxpZGF0aW9uLCBkZWZhdWx0cyB0byBmYWxzZVxuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgdmVyaWZ5VXNlckVtYWlsczogP2Jvb2xlYW47XG4gIC8qIFByZXZlbnQgdXNlciBmcm9tIGxvZ2luIGlmIGVtYWlsIGlzIG5vdCB2ZXJpZmllZCBhbmQgUEFSU0VfU0VSVkVSX1ZFUklGWV9VU0VSX0VNQUlMUyBpcyB0cnVlLCBkZWZhdWx0cyB0byBmYWxzZVxuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgcHJldmVudExvZ2luV2l0aFVudmVyaWZpZWRFbWFpbDogP2Jvb2xlYW47XG4gIC8qIEVtYWlsIHZlcmlmaWNhdGlvbiB0b2tlbiB2YWxpZGl0eSBkdXJhdGlvbiwgaW4gc2Vjb25kcyAqL1xuICBlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbjogP251bWJlcjtcbiAgLyogYW4gZXhpc3RpbmcgZW1haWwgdmVyaWZ5IHRva2VuIHNob3VsZCBiZSByZXVzZWQgd2hlbiByZXNlbmQgdmVyaWZpY2F0aW9uIGVtYWlsIGlzIHJlcXVlc3RlZFxuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZDogP2Jvb2xlYW47XG4gIC8qIGFjY291bnQgbG9ja291dCBwb2xpY3kgZm9yIGZhaWxlZCBsb2dpbiBhdHRlbXB0cyAqL1xuICBhY2NvdW50TG9ja291dDogP0FjY291bnRMb2Nrb3V0T3B0aW9ucztcbiAgLyogUGFzc3dvcmQgcG9saWN5IGZvciBlbmZvcmNpbmcgcGFzc3dvcmQgcmVsYXRlZCBydWxlcyAqL1xuICBwYXNzd29yZFBvbGljeTogP1Bhc3N3b3JkUG9saWN5T3B0aW9ucztcbiAgLyogQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBjYWNoZSAqL1xuICBjYWNoZUFkYXB0ZXI6ID9BZGFwdGVyPENhY2hlQWRhcHRlcj47XG4gIC8qIEFkYXB0ZXIgbW9kdWxlIGZvciBlbWFpbCBzZW5kaW5nICovXG4gIGVtYWlsQWRhcHRlcjogP0FkYXB0ZXI8TWFpbEFkYXB0ZXI+O1xuICAvKiBQdWJsaWMgVVJMIHRvIHlvdXIgcGFyc2Ugc2VydmVyIHdpdGggaHR0cDovLyBvciBodHRwczovLy5cbiAgOkVOVjogUEFSU0VfUFVCTElDX1NFUlZFUl9VUkwgKi9cbiAgcHVibGljU2VydmVyVVJMOiA/c3RyaW5nO1xuICAvKiBUaGUgb3B0aW9ucyBmb3IgcGFnZXMgc3VjaCBhcyBwYXNzd29yZCByZXNldCBhbmQgZW1haWwgdmVyaWZpY2F0aW9uLiBDYXV0aW9uLCB0aGlzIGlzIGFuIGV4cGVyaW1lbnRhbCBmZWF0dXJlIHRoYXQgbWF5IG5vdCBiZSBhcHByb3ByaWF0ZSBmb3IgcHJvZHVjdGlvbi5cbiAgOkRFRkFVTFQ6IHt9ICovXG4gIHBhZ2VzOiA/UGFnZXNPcHRpb25zO1xuICAvKiBjdXN0b20gcGFnZXMgZm9yIHBhc3N3b3JkIHZhbGlkYXRpb24gYW5kIHJlc2V0XG4gIDpERUZBVUxUOiB7fSAqL1xuICBjdXN0b21QYWdlczogP0N1c3RvbVBhZ2VzT3B0aW9ucztcbiAgLyogcGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IGNvbmZpZ3VyYXRpb24gb2JqZWN0ICovXG4gIGxpdmVRdWVyeTogP0xpdmVRdWVyeU9wdGlvbnM7XG4gIC8qIFNlc3Npb24gZHVyYXRpb24sIGluIHNlY29uZHMsIGRlZmF1bHRzIHRvIDEgeWVhclxuICA6REVGQVVMVDogMzE1MzYwMDAgKi9cbiAgc2Vzc2lvbkxlbmd0aDogP251bWJlcjtcbiAgLyogTWF4IHZhbHVlIGZvciBsaW1pdCBvcHRpb24gb24gcXVlcmllcywgZGVmYXVsdHMgdG8gdW5saW1pdGVkICovXG4gIG1heExpbWl0OiA/bnVtYmVyO1xuICAvKiBTZXRzIHdldGhlciB3ZSBzaG91bGQgZXhwaXJlIHRoZSBpbmFjdGl2ZSBzZXNzaW9ucywgZGVmYXVsdHMgdG8gdHJ1ZVxuICA6REVGQVVMVDogdHJ1ZSAqL1xuICBleHBpcmVJbmFjdGl2ZVNlc3Npb25zOiA/Ym9vbGVhbjtcbiAgLyogV2hlbiBhIHVzZXIgY2hhbmdlcyB0aGVpciBwYXNzd29yZCwgZWl0aGVyIHRocm91Z2ggdGhlIHJlc2V0IHBhc3N3b3JkIGVtYWlsIG9yIHdoaWxlIGxvZ2dlZCBpbiwgYWxsIHNlc3Npb25zIGFyZSByZXZva2VkIGlmIHRoaXMgaXMgdHJ1ZS4gU2V0IHRvIGZhbHNlIGlmIHlvdSBkb24ndCB3YW50IHRvIHJldm9rZSBzZXNzaW9ucy5cbiAgOkRFRkFVTFQ6IHRydWUgKi9cbiAgcmV2b2tlU2Vzc2lvbk9uUGFzc3dvcmRSZXNldDogP2Jvb2xlYW47XG4gIC8qIFRoZSBUVEwgZm9yIGNhY2hpbmcgdGhlIHNjaGVtYSBmb3Igb3B0aW1pemluZyByZWFkL3dyaXRlIG9wZXJhdGlvbnMuIFlvdSBzaG91bGQgcHV0IGEgbG9uZyBUVEwgd2hlbiB5b3VyIERCIGlzIGluIHByb2R1Y3Rpb24uIGRlZmF1bHQgdG8gNTAwMDsgc2V0IDAgdG8gZGlzYWJsZS5cbiAgOkRFRkFVTFQ6IDUwMDAgKi9cbiAgc2NoZW1hQ2FjaGVUVEw6ID9udW1iZXI7XG4gIC8qIFNldHMgdGhlIFRUTCBmb3IgdGhlIGluIG1lbW9yeSBjYWNoZSAoaW4gbXMpLCBkZWZhdWx0cyB0byA1MDAwICg1IHNlY29uZHMpXG4gIDpERUZBVUxUOiA1MDAwICovXG4gIGNhY2hlVFRMOiA/bnVtYmVyO1xuICAvKiBTZXRzIHRoZSBtYXhpbXVtIHNpemUgZm9yIHRoZSBpbiBtZW1vcnkgY2FjaGUsIGRlZmF1bHRzIHRvIDEwMDAwXG4gIDpERUZBVUxUOiAxMDAwMCAqL1xuICBjYWNoZU1heFNpemU6ID9udW1iZXI7XG4gIC8qIFJlcGxhY2UgSFRUUCBJbnRlcmZhY2Ugd2hlbiB1c2luZyBKUyBTREsgaW4gY3VycmVudCBub2RlIHJ1bnRpbWUsIGRlZmF1bHRzIHRvIGZhbHNlLiBDYXV0aW9uLCB0aGlzIGlzIGFuIGV4cGVyaW1lbnRhbCBmZWF0dXJlIHRoYXQgbWF5IG5vdCBiZSBhcHByb3ByaWF0ZSBmb3IgcHJvZHVjdGlvbi5cbiAgOkVOVjogUEFSU0VfU0VSVkVSX0VOQUJMRV9FWFBFUklNRU5UQUxfRElSRUNUX0FDQ0VTU1xuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgZGlyZWN0QWNjZXNzOiA/Ym9vbGVhbjtcbiAgLyogVXNlIGEgc2luZ2xlIHNjaGVtYSBjYWNoZSBzaGFyZWQgYWNyb3NzIHJlcXVlc3RzLiBSZWR1Y2VzIG51bWJlciBvZiBxdWVyaWVzIG1hZGUgdG8gX1NDSEVNQSwgZGVmYXVsdHMgdG8gZmFsc2UsIGkuZS4gdW5pcXVlIHNjaGVtYSBjYWNoZSBwZXIgcmVxdWVzdC5cbiAgOkRFRkFVTFQ6IGZhbHNlICovXG4gIGVuYWJsZVNpbmdsZVNjaGVtYUNhY2hlOiA/Ym9vbGVhbjtcbiAgLyogRW5hYmxlcyB0aGUgZGVmYXVsdCBleHByZXNzIGVycm9yIGhhbmRsZXIgZm9yIGFsbCBlcnJvcnNcbiAgOkRFRkFVTFQ6IGZhbHNlICovXG4gIGVuYWJsZUV4cHJlc3NFcnJvckhhbmRsZXI6ID9ib29sZWFuO1xuICAvKiBTZXRzIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiBnZW5lcmF0ZWQgb2JqZWN0IGlkJ3MsIGRlZmF1bHQgMTBcbiAgOkRFRkFVTFQ6IDEwICovXG4gIG9iamVjdElkU2l6ZTogP251bWJlcjtcbiAgLyogVGhlIHBvcnQgdG8gcnVuIHRoZSBQYXJzZVNlcnZlciwgZGVmYXVsdHMgdG8gMTMzNy5cbiAgOkVOVjogUE9SVFxuICA6REVGQVVMVDogMTMzNyAqL1xuICBwb3J0OiA/bnVtYmVyO1xuICAvKiBUaGUgaG9zdCB0byBzZXJ2ZSBQYXJzZVNlcnZlciBvbiwgZGVmYXVsdHMgdG8gMC4wLjAuMFxuICA6REVGQVVMVDogMC4wLjAuMCAqL1xuICBob3N0OiA/c3RyaW5nO1xuICAvKiBNb3VudCBwYXRoIGZvciB0aGUgc2VydmVyLCBkZWZhdWx0cyB0byAvcGFyc2VcbiAgOkRFRkFVTFQ6IC9wYXJzZSAqL1xuICBtb3VudFBhdGg6ID9zdHJpbmc7XG4gIC8qIFJ1biB3aXRoIGNsdXN0ZXIsIG9wdGlvbmFsbHkgc2V0IHRoZSBudW1iZXIgb2YgcHJvY2Vzc2VzIGRlZmF1bHQgdG8gb3MuY3B1cygpLmxlbmd0aCAqL1xuICBjbHVzdGVyOiA/TnVtYmVyT3JCb29sZWFuO1xuICAvKiBtaWRkbGV3YXJlIGZvciBleHByZXNzIHNlcnZlciwgY2FuIGJlIHN0cmluZyBvciBmdW5jdGlvbiAqL1xuICBtaWRkbGV3YXJlOiA/KCgoKSA9PiB2b2lkKSB8IHN0cmluZyk7XG4gIC8qIFN0YXJ0cyB0aGUgbGl2ZVF1ZXJ5IHNlcnZlciAqL1xuICBzdGFydExpdmVRdWVyeVNlcnZlcjogP2Jvb2xlYW47XG4gIC8qIExpdmUgcXVlcnkgc2VydmVyIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyAod2lsbCBzdGFydCB0aGUgbGl2ZVF1ZXJ5IHNlcnZlcikgKi9cbiAgbGl2ZVF1ZXJ5U2VydmVyT3B0aW9uczogP0xpdmVRdWVyeVNlcnZlck9wdGlvbnM7XG4gIC8qIE9wdGlvbnMgZm9yIHJlcXVlc3QgaWRlbXBvdGVuY3kgdG8gZGVkdXBsaWNhdGUgaWRlbnRpY2FsIHJlcXVlc3RzIHRoYXQgbWF5IGJlIGNhdXNlZCBieSBuZXR3b3JrIGlzc3Vlcy4gQ2F1dGlvbiwgdGhpcyBpcyBhbiBleHBlcmltZW50YWwgZmVhdHVyZSB0aGF0IG1heSBub3QgYmUgYXBwcm9wcmlhdGUgZm9yIHByb2R1Y3Rpb24uXG4gIDpFTlY6IFBBUlNFX1NFUlZFUl9FWFBFUklNRU5UQUxfSURFTVBPVEVOQ1lfT1BUSU9OU1xuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgaWRlbXBvdGVuY3lPcHRpb25zOiA/SWRlbXBvdGVuY3lPcHRpb25zO1xuICAvKiBPcHRpb25zIGZvciBmaWxlIHVwbG9hZHNcbiAgOkVOVjogUEFSU0VfU0VSVkVSX0ZJTEVfVVBMT0FEX09QVElPTlNcbiAgOkRFRkFVTFQ6IHt9ICovXG4gIGZpbGVVcGxvYWQ6ID9GaWxlVXBsb2FkT3B0aW9ucztcbiAgLyogRnVsbCBwYXRoIHRvIHlvdXIgR3JhcGhRTCBjdXN0b20gc2NoZW1hLmdyYXBocWwgZmlsZSAqL1xuICBncmFwaFFMU2NoZW1hOiA/c3RyaW5nO1xuICAvKiBNb3VudHMgdGhlIEdyYXBoUUwgZW5kcG9pbnRcbiAgOkVOVjogUEFSU0VfU0VSVkVSX01PVU5UX0dSQVBIUUxcbiAgOkRFRkFVTFQ6IGZhbHNlICovXG4gIG1vdW50R3JhcGhRTDogP2Jvb2xlYW47XG4gIC8qIE1vdW50IHBhdGggZm9yIHRoZSBHcmFwaFFMIGVuZHBvaW50LCBkZWZhdWx0cyB0byAvZ3JhcGhxbFxuICA6RU5WOiBQQVJTRV9TRVJWRVJfR1JBUEhRTF9QQVRIXG4gIDpERUZBVUxUOiAvZ3JhcGhxbCAqL1xuICBncmFwaFFMUGF0aDogP3N0cmluZztcbiAgLyogTW91bnRzIHRoZSBHcmFwaFFMIFBsYXlncm91bmQgLSBuZXZlciB1c2UgdGhpcyBvcHRpb24gaW4gcHJvZHVjdGlvblxuICA6RU5WOiBQQVJTRV9TRVJWRVJfTU9VTlRfUExBWUdST1VORFxuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgbW91bnRQbGF5Z3JvdW5kOiA/Ym9vbGVhbjtcbiAgLyogTW91bnQgcGF0aCBmb3IgdGhlIEdyYXBoUUwgUGxheWdyb3VuZCwgZGVmYXVsdHMgdG8gL3BsYXlncm91bmRcbiAgOkVOVjogUEFSU0VfU0VSVkVSX1BMQVlHUk9VTkRfUEFUSFxuICA6REVGQVVMVDogL3BsYXlncm91bmQgKi9cbiAgcGxheWdyb3VuZFBhdGg6ID9zdHJpbmc7XG4gIC8qIENhbGxiYWNrIHdoZW4gc2VydmVyIGhhcyBzdGFydGVkICovXG4gIHNlcnZlclN0YXJ0Q29tcGxldGU6ID8oZXJyb3I6ID9FcnJvcikgPT4gdm9pZDtcbiAgLyogQ2FsbGJhY2sgd2hlbiBzZXJ2ZXIgaGFzIGNsb3NlZCAqL1xuICBzZXJ2ZXJDbG9zZUNvbXBsZXRlOiA/KCkgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQYWdlc09wdGlvbnMge1xuICAvKiBJcyB0cnVlIGlmIHRoZSBwYWdlcyByb3V0ZXIgc2hvdWxkIGJlIGVuYWJsZWQ7IHRoaXMgaXMgcmVxdWlyZWQgZm9yIGFueSBvZiB0aGUgcGFnZXMgb3B0aW9ucyB0byB0YWtlIGVmZmVjdC4gQ2F1dGlvbiwgdGhpcyBpcyBhbiBleHBlcmltZW50YWwgZmVhdHVyZSB0aGF0IG1heSBub3QgYmUgYXBwcm9wcmlhdGUgZm9yIHByb2R1Y3Rpb24uXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICBlbmFibGVSb3V0ZXI6ID9ib29sZWFuO1xuICAvKiBJcyB0cnVlIGlmIHBhZ2VzIHNob3VsZCBiZSBsb2NhbGl6ZWQ7IHRoaXMgaGFzIG5vIGVmZmVjdCBvbiBjdXN0b20gcGFnZSByZWRpcmVjdHMuXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICBlbmFibGVMb2NhbGl6YXRpb246ID9ib29sZWFuO1xuICAvKiBUaGUgcGF0aCB0byB0aGUgSlNPTiBmaWxlIGZvciBsb2NhbGl6YXRpb247IHRoZSB0cmFuc2xhdGlvbnMgd2lsbCBiZSB1c2VkIHRvIGZpbGwgdGVtcGxhdGUgcGxhY2Vob2xkZXJzIGFjY29yZGluZyB0byB0aGUgbG9jYWxlLiAqL1xuICBsb2NhbGl6YXRpb25Kc29uUGF0aDogP3N0cmluZztcbiAgLyogVGhlIGZhbGxiYWNrIGxvY2FsZSBmb3IgbG9jYWxpemF0aW9uIGlmIG5vIG1hdGNoaW5nIHRyYW5zbGF0aW9uIGlzIHByb3ZpZGVkIGZvciB0aGUgZ2l2ZW4gbG9jYWxlLiBUaGlzIGlzIG9ubHkgcmVsZXZhbnQgd2hlbiBwcm92aWRpbmcgdHJhbnNsYXRpb24gcmVzb3VyY2VzIHZpYSBKU09OIGZpbGUuXG4gIDpERUZBVUxUOiBlbiAqL1xuICBsb2NhbGl6YXRpb25GYWxsYmFja0xvY2FsZTogP3N0cmluZztcbiAgLyogVGhlIHBsYWNlaG9sZGVyIGtleXMgYW5kIHZhbHVlcyB3aGljaCB3aWxsIGJlIGZpbGxlZCBpbiBwYWdlczsgdGhpcyBjYW4gYmUgYSBzaW1wbGUgb2JqZWN0IG9yIGEgY2FsbGJhY2sgZnVuY3Rpb24uXG4gIDpERUZBVUxUOiB7fSAqL1xuICBwbGFjZWhvbGRlcnM6ID9PYmplY3Q7XG4gIC8qIElzIHRydWUgaWYgcmVzcG9uc2VzIHNob3VsZCBhbHdheXMgYmUgcmVkaXJlY3RzIGFuZCBuZXZlciBjb250ZW50LCBmYWxzZSBpZiB0aGUgcmVzcG9uc2UgdHlwZSBzaG91bGQgZGVwZW5kIG9uIHRoZSByZXF1ZXN0IHR5cGUgKEdFVCByZXF1ZXN0IC0+IGNvbnRlbnQgcmVzcG9uc2U7IFBPU1QgcmVxdWVzdCAtPiByZWRpcmVjdCByZXNwb25zZSkuXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICBmb3JjZVJlZGlyZWN0OiA/Ym9vbGVhbjtcbiAgLyogVGhlIHBhdGggdG8gdGhlIHBhZ2VzIGRpcmVjdG9yeTsgdGhpcyBhbHNvIGRlZmluZXMgd2hlcmUgdGhlIHN0YXRpYyBlbmRwb2ludCAnL2FwcHMnIHBvaW50cyB0by4gRGVmYXVsdCBpcyB0aGUgJy4vcHVibGljLycgZGlyZWN0b3J5LlxuICA6REVGQVVMVDogLi9wdWJsaWMgKi9cbiAgcGFnZXNQYXRoOiA/c3RyaW5nO1xuICAvKiBUaGUgQVBJIGVuZHBvaW50IGZvciB0aGUgcGFnZXMuIERlZmF1bHQgaXMgJ2FwcHMnLlxuICA6REVGQVVMVDogYXBwcyAqL1xuICBwYWdlc0VuZHBvaW50OiA/c3RyaW5nO1xuICAvKiBUaGUgVVJMcyB0byB0aGUgY3VzdG9tIHBhZ2VzLlxuICA6REVGQVVMVDoge30gKi9cbiAgY3VzdG9tVXJsczogP1BhZ2VzQ3VzdG9tVXJsc09wdGlvbnM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFnZXNDdXN0b21VcmxzT3B0aW9ucyB7XG4gIC8qIFRoZSBVUkwgdG8gdGhlIGN1c3RvbSBwYWdlIGZvciBwYXNzd29yZCByZXNldC4gKi9cbiAgcGFzc3dvcmRSZXNldDogP3N0cmluZztcbiAgLyogVGhlIFVSTCB0byB0aGUgY3VzdG9tIHBhZ2UgZm9yIHBhc3N3b3JkIHJlc2V0IC0+IGxpbmsgaW52YWxpZC4gKi9cbiAgcGFzc3dvcmRSZXNldExpbmtJbnZhbGlkOiA/c3RyaW5nO1xuICAvKiBUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgcGFzc3dvcmQgcmVzZXQgLT4gc3VjY2Vzcy4gKi9cbiAgcGFzc3dvcmRSZXNldFN1Y2Nlc3M6ID9zdHJpbmc7XG4gIC8qIFRoZSBVUkwgdG8gdGhlIGN1c3RvbSBwYWdlIGZvciBlbWFpbCB2ZXJpZmljYXRpb24gLT4gc3VjY2Vzcy4gKi9cbiAgZW1haWxWZXJpZmljYXRpb25TdWNjZXNzOiA/c3RyaW5nO1xuICAvKiBUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgZW1haWwgdmVyaWZpY2F0aW9uIC0+IGxpbmsgc2VuZCBmYWlsLiAqL1xuICBlbWFpbFZlcmlmaWNhdGlvblNlbmRGYWlsOiA/c3RyaW5nO1xuICAvKiBUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgZW1haWwgdmVyaWZpY2F0aW9uIC0+IHJlc2VuZCBsaW5rIC0+IHN1Y2Nlc3MuICovXG4gIGVtYWlsVmVyaWZpY2F0aW9uU2VuZFN1Y2Nlc3M6ID9zdHJpbmc7XG4gIC8qIFRoZSBVUkwgdG8gdGhlIGN1c3RvbSBwYWdlIGZvciBlbWFpbCB2ZXJpZmljYXRpb24gLT4gbGluayBpbnZhbGlkLiAqL1xuICBlbWFpbFZlcmlmaWNhdGlvbkxpbmtJbnZhbGlkOiA/c3RyaW5nO1xuICAvKiBUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgZW1haWwgdmVyaWZpY2F0aW9uIC0+IGxpbmsgZXhwaXJlZC4gKi9cbiAgZW1haWxWZXJpZmljYXRpb25MaW5rRXhwaXJlZDogP3N0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDdXN0b21QYWdlc09wdGlvbnMge1xuICAvKiBpbnZhbGlkIGxpbmsgcGFnZSBwYXRoICovXG4gIGludmFsaWRMaW5rOiA/c3RyaW5nO1xuICAvKiB2ZXJpZmljYXRpb24gbGluayBzZW5kIGZhaWwgcGFnZSBwYXRoICovXG4gIGxpbmtTZW5kRmFpbDogP3N0cmluZztcbiAgLyogY2hvb3NlIHBhc3N3b3JkIHBhZ2UgcGF0aCAqL1xuICBjaG9vc2VQYXNzd29yZDogP3N0cmluZztcbiAgLyogdmVyaWZpY2F0aW9uIGxpbmsgc2VuZCBzdWNjZXNzIHBhZ2UgcGF0aCAqL1xuICBsaW5rU2VuZFN1Y2Nlc3M6ID9zdHJpbmc7XG4gIC8qIHZlcmlmeSBlbWFpbCBzdWNjZXNzIHBhZ2UgcGF0aCAqL1xuICB2ZXJpZnlFbWFpbFN1Y2Nlc3M6ID9zdHJpbmc7XG4gIC8qIHBhc3N3b3JkIHJlc2V0IHN1Y2Nlc3MgcGFnZSBwYXRoICovXG4gIHBhc3N3b3JkUmVzZXRTdWNjZXNzOiA/c3RyaW5nO1xuICAvKiBpbnZhbGlkIHZlcmlmaWNhdGlvbiBsaW5rIHBhZ2UgcGF0aCAqL1xuICBpbnZhbGlkVmVyaWZpY2F0aW9uTGluazogP3N0cmluZztcbiAgLyogZXhwaXJlZCB2ZXJpZmljYXRpb24gbGluayBwYWdlIHBhdGggKi9cbiAgZXhwaXJlZFZlcmlmaWNhdGlvbkxpbms6ID9zdHJpbmc7XG4gIC8qIGludmFsaWQgcGFzc3dvcmQgcmVzZXQgbGluayBwYWdlIHBhdGggKi9cbiAgaW52YWxpZFBhc3N3b3JkUmVzZXRMaW5rOiA/c3RyaW5nO1xuICAvKiBmb3IgbWFza2luZyB1c2VyLWZhY2luZyBwYWdlcyAqL1xuICBwYXJzZUZyYW1lVVJMOiA/c3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExpdmVRdWVyeU9wdGlvbnMge1xuICAvKiBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgY2xhc3NOYW1lc1xuICA6RU5WOiBQQVJTRV9TRVJWRVJfTElWRVFVRVJZX0NMQVNTTkFNRVMgKi9cbiAgY2xhc3NOYW1lczogPyhzdHJpbmdbXSk7XG4gIC8qIHBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSByZWRpc09wdGlvbnMgKi9cbiAgcmVkaXNPcHRpb25zOiA/YW55O1xuICAvKiBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgcmVkaXNVUkwgKi9cbiAgcmVkaXNVUkw6ID9zdHJpbmc7XG4gIC8qIExpdmVRdWVyeSBwdWJzdWIgYWRhcHRlciAqL1xuICBwdWJTdWJBZGFwdGVyOiA/QWRhcHRlcjxQdWJTdWJBZGFwdGVyPjtcbiAgLyogQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBXZWJTb2NrZXRTZXJ2ZXIgKi9cbiAgd3NzQWRhcHRlcjogP0FkYXB0ZXI8V1NTQWRhcHRlcj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucyB7XG4gIC8qIFRoaXMgc3RyaW5nIHNob3VsZCBtYXRjaCB0aGUgYXBwSWQgaW4gdXNlIGJ5IHlvdXIgUGFyc2UgU2VydmVyLiBJZiB5b3UgZGVwbG95IHRoZSBMaXZlUXVlcnkgc2VydmVyIGFsb25nc2lkZSBQYXJzZSBTZXJ2ZXIsIHRoZSBMaXZlUXVlcnkgc2VydmVyIHdpbGwgdHJ5IHRvIHVzZSB0aGUgc2FtZSBhcHBJZC4qL1xuICBhcHBJZDogP3N0cmluZztcbiAgLyogVGhpcyBzdHJpbmcgc2hvdWxkIG1hdGNoIHRoZSBtYXN0ZXJLZXkgaW4gdXNlIGJ5IHlvdXIgUGFyc2UgU2VydmVyLiBJZiB5b3UgZGVwbG95IHRoZSBMaXZlUXVlcnkgc2VydmVyIGFsb25nc2lkZSBQYXJzZSBTZXJ2ZXIsIHRoZSBMaXZlUXVlcnkgc2VydmVyIHdpbGwgdHJ5IHRvIHVzZSB0aGUgc2FtZSBtYXN0ZXJLZXkuKi9cbiAgbWFzdGVyS2V5OiA/c3RyaW5nO1xuICAvKiBUaGlzIHN0cmluZyBzaG91bGQgbWF0Y2ggdGhlIHNlcnZlclVSTCBpbiB1c2UgYnkgeW91ciBQYXJzZSBTZXJ2ZXIuIElmIHlvdSBkZXBsb3kgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgYWxvbmdzaWRlIFBhcnNlIFNlcnZlciwgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgd2lsbCB0cnkgdG8gdXNlIHRoZSBzYW1lIHNlcnZlclVSTC4qL1xuICBzZXJ2ZXJVUkw6ID9zdHJpbmc7XG4gIC8qIEEgSlNPTiBvYmplY3QgdGhhdCBzZXJ2ZXMgYXMgYSB3aGl0ZWxpc3Qgb2Yga2V5cy4gSXQgaXMgdXNlZCBmb3IgdmFsaWRhdGluZyBjbGllbnRzIHdoZW4gdGhleSB0cnkgdG8gY29ubmVjdCB0byB0aGUgTGl2ZVF1ZXJ5IHNlcnZlci4gQ2hlY2sgdGhlIGZvbGxvd2luZyBTZWN1cml0eSBzZWN0aW9uIGFuZCBvdXIgcHJvdG9jb2wgc3BlY2lmaWNhdGlvbiBmb3IgZGV0YWlscy4qL1xuICBrZXlQYWlyczogP2FueTtcbiAgLyogTnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBiZXR3ZWVuIHBpbmcvcG9uZyBmcmFtZXMuIFRoZSBXZWJTb2NrZXQgc2VydmVyIHNlbmRzIHBpbmcvcG9uZyBmcmFtZXMgdG8gdGhlIGNsaWVudHMgdG8ga2VlcCB0aGUgV2ViU29ja2V0IGFsaXZlLiBUaGlzIHZhbHVlIGRlZmluZXMgdGhlIGludGVydmFsIG9mIHRoZSBwaW5nL3BvbmcgZnJhbWUgZnJvbSB0aGUgc2VydmVyIHRvIGNsaWVudHMsIGRlZmF1bHRzIHRvIDEwICogMTAwMCBtcyAoMTAgcykuKi9cbiAgd2Vic29ja2V0VGltZW91dDogP251bWJlcjtcbiAgLyogTnVtYmVyIGluIG1pbGxpc2Vjb25kcy4gV2hlbiBjbGllbnRzIHByb3ZpZGUgdGhlIHNlc3Npb25Ub2tlbiB0byB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciwgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgd2lsbCB0cnkgdG8gZmV0Y2ggaXRzIFBhcnNlVXNlcidzIG9iamVjdElkIGZyb20gcGFyc2Ugc2VydmVyIGFuZCBzdG9yZSBpdCBpbiB0aGUgY2FjaGUuIFRoZSB2YWx1ZSBkZWZpbmVzIHRoZSBkdXJhdGlvbiBvZiB0aGUgY2FjaGUuIENoZWNrIHRoZSBmb2xsb3dpbmcgU2VjdXJpdHkgc2VjdGlvbiBhbmQgb3VyIHByb3RvY29sIHNwZWNpZmljYXRpb24gZm9yIGRldGFpbHMsIGRlZmF1bHRzIHRvIDUgKiAxMDAwIG1zICg1IHNlY29uZHMpLiovXG4gIGNhY2hlVGltZW91dDogP251bWJlcjtcbiAgLyogVGhpcyBzdHJpbmcgZGVmaW5lcyB0aGUgbG9nIGxldmVsIG9mIHRoZSBMaXZlUXVlcnkgc2VydmVyLiBXZSBzdXBwb3J0IFZFUkJPU0UsIElORk8sIEVSUk9SLCBOT05FLCBkZWZhdWx0cyB0byBJTkZPLiovXG4gIGxvZ0xldmVsOiA/c3RyaW5nO1xuICAvKiBUaGUgcG9ydCB0byBydW4gdGhlIExpdmVRdWVyeSBzZXJ2ZXIsIGRlZmF1bHRzIHRvIDEzMzcuXG4gIDpERUZBVUxUOiAxMzM3ICovXG4gIHBvcnQ6ID9udW1iZXI7XG4gIC8qIHBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSByZWRpc09wdGlvbnMgKi9cbiAgcmVkaXNPcHRpb25zOiA/YW55O1xuICAvKiBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgcmVkaXNVUkwgKi9cbiAgcmVkaXNVUkw6ID9zdHJpbmc7XG4gIC8qIExpdmVRdWVyeSBwdWJzdWIgYWRhcHRlciAqL1xuICBwdWJTdWJBZGFwdGVyOiA/QWRhcHRlcjxQdWJTdWJBZGFwdGVyPjtcbiAgLyogQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBXZWJTb2NrZXRTZXJ2ZXIgKi9cbiAgd3NzQWRhcHRlcjogP0FkYXB0ZXI8V1NTQWRhcHRlcj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSWRlbXBvdGVuY3lPcHRpb25zIHtcbiAgLyogQW4gYXJyYXkgb2YgcGF0aHMgZm9yIHdoaWNoIHRoZSBmZWF0dXJlIHNob3VsZCBiZSBlbmFibGVkLiBUaGUgbW91bnQgcGF0aCBtdXN0IG5vdCBiZSBpbmNsdWRlZCwgZm9yIGV4YW1wbGUgaW5zdGVhZCBvZiBgL3BhcnNlL2Z1bmN0aW9ucy9teUZ1bmN0aW9uYCBzcGVjaWZpeSBgZnVuY3Rpb25zL215RnVuY3Rpb25gLiBUaGUgZW50cmllcyBhcmUgaW50ZXJwcmV0ZWQgYXMgcmVndWxhciBleHByZXNzaW9uLCBmb3IgZXhhbXBsZSBgZnVuY3Rpb25zLy4qYCBtYXRjaGVzIGFsbCBmdW5jdGlvbnMsIGBqb2JzLy4qYCBtYXRjaGVzIGFsbCBqb2JzLCBgY2xhc3Nlcy8uKmAgbWF0Y2hlcyBhbGwgY2xhc3NlcywgYC4qYCBtYXRjaGVzIGFsbCBwYXRocy5cbiAgOkRFRkFVTFQ6IFtdICovXG4gIHBhdGhzOiA/KHN0cmluZ1tdKTtcbiAgLyogVGhlIGR1cmF0aW9uIGluIHNlY29uZHMgYWZ0ZXIgd2hpY2ggYSByZXF1ZXN0IHJlY29yZCBpcyBkaXNjYXJkZWQgZnJvbSB0aGUgZGF0YWJhc2UsIGRlZmF1bHRzIHRvIDMwMHMuXG4gIDpERUZBVUxUOiAzMDAgKi9cbiAgdHRsOiA/bnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFjY291bnRMb2Nrb3V0T3B0aW9ucyB7XG4gIC8qIG51bWJlciBvZiBtaW51dGVzIHRoYXQgYSBsb2NrZWQtb3V0IGFjY291bnQgcmVtYWlucyBsb2NrZWQgb3V0IGJlZm9yZSBhdXRvbWF0aWNhbGx5IGJlY29taW5nIHVubG9ja2VkLiAqL1xuICBkdXJhdGlvbjogP251bWJlcjtcbiAgLyogbnVtYmVyIG9mIGZhaWxlZCBzaWduLWluIGF0dGVtcHRzIHRoYXQgd2lsbCBjYXVzZSBhIHVzZXIgYWNjb3VudCB0byBiZSBsb2NrZWQgKi9cbiAgdGhyZXNob2xkOiA/bnVtYmVyO1xuICAvKiBJcyB0cnVlIGlmIHRoZSBhY2NvdW50IGxvY2sgc2hvdWxkIGJlIHJlbW92ZWQgYWZ0ZXIgYSBzdWNjZXNzZnVsIHBhc3N3b3JkIHJlc2V0LlxuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgdW5sb2NrT25QYXNzd29yZFJlc2V0OiA/Ym9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQYXNzd29yZFBvbGljeU9wdGlvbnMge1xuICAvKiBhIFJlZ0V4cCBvYmplY3Qgb3IgYSByZWdleCBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBwYXR0ZXJuIHRvIGVuZm9yY2UgKi9cbiAgdmFsaWRhdG9yUGF0dGVybjogP3N0cmluZztcbiAgLyogYSBjYWxsYmFjayBmdW5jdGlvbiB0byBiZSBpbnZva2VkIHRvIHZhbGlkYXRlIHRoZSBwYXNzd29yZCAgKi9cbiAgdmFsaWRhdG9yQ2FsbGJhY2s6ID8oKSA9PiB2b2lkO1xuICAvKiBkaXNhbGxvdyB1c2VybmFtZSBpbiBwYXNzd29yZHMgKi9cbiAgZG9Ob3RBbGxvd1VzZXJuYW1lOiA/Ym9vbGVhbjtcbiAgLyogZGF5cyBmb3IgcGFzc3dvcmQgZXhwaXJ5ICovXG4gIG1heFBhc3N3b3JkQWdlOiA/bnVtYmVyO1xuICAvKiBzZXR0aW5nIHRvIHByZXZlbnQgcmV1c2Ugb2YgcHJldmlvdXMgbiBwYXNzd29yZHMgKi9cbiAgbWF4UGFzc3dvcmRIaXN0b3J5OiA/bnVtYmVyO1xuICAvKiB0aW1lIGZvciB0b2tlbiB0byBleHBpcmUgKi9cbiAgcmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb246ID9udW1iZXI7XG4gIC8qIHJlc2VuZCB0b2tlbiBpZiBpdCdzIHN0aWxsIHZhbGlkICovXG4gIHJlc2V0VG9rZW5SZXVzZUlmVmFsaWQ6ID9ib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEZpbGVVcGxvYWRPcHRpb25zIHtcbiAgLyogIElzIHRydWUgaWYgZmlsZSB1cGxvYWQgc2hvdWxkIGJlIGFsbG93ZWQgZm9yIGFub255bW91cyB1c2Vycy5cbiAgOkRFRkFVTFQ6IGZhbHNlICovXG4gIGVuYWJsZUZvckFub255bW91c1VzZXI6ID9ib29sZWFuO1xuICAvKiBJcyB0cnVlIGlmIGZpbGUgdXBsb2FkIHNob3VsZCBiZSBhbGxvd2VkIGZvciBhdXRoZW50aWNhdGVkIHVzZXJzLlxuICA6REVGQVVMVDogdHJ1ZSAqL1xuICBlbmFibGVGb3JBdXRoZW50aWNhdGVkVXNlcjogP2Jvb2xlYW47XG4gIC8qIElzIHRydWUgaWYgZmlsZSB1cGxvYWQgc2hvdWxkIGJlIGFsbG93ZWQgZm9yIGFueW9uZSwgcmVnYXJkbGVzcyBvZiB1c2VyIGF1dGhlbnRpY2F0aW9uLlxuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgZW5hYmxlRm9yUHVibGljOiA/Ym9vbGVhbjtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Options/parsers.js b/lib/Options/parsers.js new file mode 100644 index 0000000000..d5bc65c7d4 --- /dev/null +++ b/lib/Options/parsers.js @@ -0,0 +1,90 @@ +"use strict"; + +function numberParser(key) { + return function (opt) { + const intOpt = parseInt(opt); + + if (!Number.isInteger(intOpt)) { + throw new Error(`Key ${key} has invalid value ${opt}`); + } + + return intOpt; + }; +} + +function numberOrBoolParser(key) { + return function (opt) { + if (typeof opt === 'boolean') { + return opt; + } + + if (opt === 'true') { + return true; + } + + if (opt === 'false') { + return false; + } + + return numberParser(key)(opt); + }; +} + +function objectParser(opt) { + if (typeof opt == 'object') { + return opt; + } + + return JSON.parse(opt); +} + +function arrayParser(opt) { + if (Array.isArray(opt)) { + return opt; + } else if (typeof opt === 'string') { + return opt.split(','); + } else { + throw new Error(`${opt} should be a comma separated string or an array`); + } +} + +function moduleOrObjectParser(opt) { + if (typeof opt == 'object') { + return opt; + } + + try { + return JSON.parse(opt); + } catch (e) { + /* */ + } + + return opt; +} + +function booleanParser(opt) { + if (opt == true || opt == 'true' || opt == '1') { + return true; + } + + return false; +} + +function nullParser(opt) { + if (opt == 'null') { + return null; + } + + return opt; +} + +module.exports = { + numberParser, + numberOrBoolParser, + nullParser, + booleanParser, + moduleOrObjectParser, + arrayParser, + objectParser +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9PcHRpb25zL3BhcnNlcnMuanMiXSwibmFtZXMiOlsibnVtYmVyUGFyc2VyIiwia2V5Iiwib3B0IiwiaW50T3B0IiwicGFyc2VJbnQiLCJOdW1iZXIiLCJpc0ludGVnZXIiLCJFcnJvciIsIm51bWJlck9yQm9vbFBhcnNlciIsIm9iamVjdFBhcnNlciIsIkpTT04iLCJwYXJzZSIsImFycmF5UGFyc2VyIiwiQXJyYXkiLCJpc0FycmF5Iiwic3BsaXQiLCJtb2R1bGVPck9iamVjdFBhcnNlciIsImUiLCJib29sZWFuUGFyc2VyIiwibnVsbFBhcnNlciIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUEsU0FBU0EsWUFBVCxDQUFzQkMsR0FBdEIsRUFBMkI7QUFDekIsU0FBTyxVQUFVQyxHQUFWLEVBQWU7QUFDcEIsVUFBTUMsTUFBTSxHQUFHQyxRQUFRLENBQUNGLEdBQUQsQ0FBdkI7O0FBQ0EsUUFBSSxDQUFDRyxNQUFNLENBQUNDLFNBQVAsQ0FBaUJILE1BQWpCLENBQUwsRUFBK0I7QUFDN0IsWUFBTSxJQUFJSSxLQUFKLENBQVcsT0FBTU4sR0FBSSxzQkFBcUJDLEdBQUksRUFBOUMsQ0FBTjtBQUNEOztBQUNELFdBQU9DLE1BQVA7QUFDRCxHQU5EO0FBT0Q7O0FBRUQsU0FBU0ssa0JBQVQsQ0FBNEJQLEdBQTVCLEVBQWlDO0FBQy9CLFNBQU8sVUFBVUMsR0FBVixFQUFlO0FBQ3BCLFFBQUksT0FBT0EsR0FBUCxLQUFlLFNBQW5CLEVBQThCO0FBQzVCLGFBQU9BLEdBQVA7QUFDRDs7QUFDRCxRQUFJQSxHQUFHLEtBQUssTUFBWixFQUFvQjtBQUNsQixhQUFPLElBQVA7QUFDRDs7QUFDRCxRQUFJQSxHQUFHLEtBQUssT0FBWixFQUFxQjtBQUNuQixhQUFPLEtBQVA7QUFDRDs7QUFDRCxXQUFPRixZQUFZLENBQUNDLEdBQUQsQ0FBWixDQUFrQkMsR0FBbEIsQ0FBUDtBQUNELEdBWEQ7QUFZRDs7QUFFRCxTQUFTTyxZQUFULENBQXNCUCxHQUF0QixFQUEyQjtBQUN6QixNQUFJLE9BQU9BLEdBQVAsSUFBYyxRQUFsQixFQUE0QjtBQUMxQixXQUFPQSxHQUFQO0FBQ0Q7O0FBQ0QsU0FBT1EsSUFBSSxDQUFDQyxLQUFMLENBQVdULEdBQVgsQ0FBUDtBQUNEOztBQUVELFNBQVNVLFdBQVQsQ0FBcUJWLEdBQXJCLEVBQTBCO0FBQ3hCLE1BQUlXLEtBQUssQ0FBQ0MsT0FBTixDQUFjWixHQUFkLENBQUosRUFBd0I7QUFDdEIsV0FBT0EsR0FBUDtBQUNELEdBRkQsTUFFTyxJQUFJLE9BQU9BLEdBQVAsS0FBZSxRQUFuQixFQUE2QjtBQUNsQyxXQUFPQSxHQUFHLENBQUNhLEtBQUosQ0FBVSxHQUFWLENBQVA7QUFDRCxHQUZNLE1BRUE7QUFDTCxVQUFNLElBQUlSLEtBQUosQ0FBVyxHQUFFTCxHQUFJLGlEQUFqQixDQUFOO0FBQ0Q7QUFDRjs7QUFFRCxTQUFTYyxvQkFBVCxDQUE4QmQsR0FBOUIsRUFBbUM7QUFDakMsTUFBSSxPQUFPQSxHQUFQLElBQWMsUUFBbEIsRUFBNEI7QUFDMUIsV0FBT0EsR0FBUDtBQUNEOztBQUNELE1BQUk7QUFDRixXQUFPUSxJQUFJLENBQUNDLEtBQUwsQ0FBV1QsR0FBWCxDQUFQO0FBQ0QsR0FGRCxDQUVFLE9BQU9lLENBQVAsRUFBVTtBQUNWO0FBQ0Q7O0FBQ0QsU0FBT2YsR0FBUDtBQUNEOztBQUVELFNBQVNnQixhQUFULENBQXVCaEIsR0FBdkIsRUFBNEI7QUFDMUIsTUFBSUEsR0FBRyxJQUFJLElBQVAsSUFBZUEsR0FBRyxJQUFJLE1BQXRCLElBQWdDQSxHQUFHLElBQUksR0FBM0MsRUFBZ0Q7QUFDOUMsV0FBTyxJQUFQO0FBQ0Q7O0FBQ0QsU0FBTyxLQUFQO0FBQ0Q7O0FBRUQsU0FBU2lCLFVBQVQsQ0FBb0JqQixHQUFwQixFQUF5QjtBQUN2QixNQUFJQSxHQUFHLElBQUksTUFBWCxFQUFtQjtBQUNqQixXQUFPLElBQVA7QUFDRDs7QUFDRCxTQUFPQSxHQUFQO0FBQ0Q7O0FBRURrQixNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZnJCLEVBQUFBLFlBRGU7QUFFZlEsRUFBQUEsa0JBRmU7QUFHZlcsRUFBQUEsVUFIZTtBQUlmRCxFQUFBQSxhQUplO0FBS2ZGLEVBQUFBLG9CQUxlO0FBTWZKLEVBQUFBLFdBTmU7QUFPZkgsRUFBQUE7QUFQZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIG51bWJlclBhcnNlcihrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChvcHQpIHtcbiAgICBjb25zdCBpbnRPcHQgPSBwYXJzZUludChvcHQpO1xuICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihpbnRPcHQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEtleSAke2tleX0gaGFzIGludmFsaWQgdmFsdWUgJHtvcHR9YCk7XG4gICAgfVxuICAgIHJldHVybiBpbnRPcHQ7XG4gIH07XG59XG5cbmZ1bmN0aW9uIG51bWJlck9yQm9vbFBhcnNlcihrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChvcHQpIHtcbiAgICBpZiAodHlwZW9mIG9wdCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICByZXR1cm4gb3B0O1xuICAgIH1cbiAgICBpZiAob3B0ID09PSAndHJ1ZScpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAob3B0ID09PSAnZmFsc2UnKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBudW1iZXJQYXJzZXIoa2V5KShvcHQpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBvYmplY3RQYXJzZXIob3B0KSB7XG4gIGlmICh0eXBlb2Ygb3B0ID09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIG9wdDtcbiAgfVxuICByZXR1cm4gSlNPTi5wYXJzZShvcHQpO1xufVxuXG5mdW5jdGlvbiBhcnJheVBhcnNlcihvcHQpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkob3B0KSkge1xuICAgIHJldHVybiBvcHQ7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG9wdCA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gb3B0LnNwbGl0KCcsJyk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke29wdH0gc2hvdWxkIGJlIGEgY29tbWEgc2VwYXJhdGVkIHN0cmluZyBvciBhbiBhcnJheWApO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1vZHVsZU9yT2JqZWN0UGFyc2VyKG9wdCkge1xuICBpZiAodHlwZW9mIG9wdCA9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBvcHQ7XG4gIH1cbiAgdHJ5IHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShvcHQpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLyogKi9cbiAgfVxuICByZXR1cm4gb3B0O1xufVxuXG5mdW5jdGlvbiBib29sZWFuUGFyc2VyKG9wdCkge1xuICBpZiAob3B0ID09IHRydWUgfHwgb3B0ID09ICd0cnVlJyB8fCBvcHQgPT0gJzEnKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBudWxsUGFyc2VyKG9wdCkge1xuICBpZiAob3B0ID09ICdudWxsJykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiBvcHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBudW1iZXJQYXJzZXIsXG4gIG51bWJlck9yQm9vbFBhcnNlcixcbiAgbnVsbFBhcnNlcixcbiAgYm9vbGVhblBhcnNlcixcbiAgbW9kdWxlT3JPYmplY3RQYXJzZXIsXG4gIGFycmF5UGFyc2VyLFxuICBvYmplY3RQYXJzZXIsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Page.js b/lib/Page.js new file mode 100644 index 0000000000..324e123cc8 --- /dev/null +++ b/lib/Page.js @@ -0,0 +1,53 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.Page = void 0; + +/*eslint no-unused-vars: "off"*/ + +/** + * @interface Page + * Page + * Page content that is returned by PageRouter. + */ +class Page { + /** + * @description Creates a page. + * @param {Object} params The page parameters. + * @param {String} params.id The page identifier. + * @param {String} params.defaultFile The page file name. + * @returns {Page} The page. + */ + constructor(params = {}) { + const { + id, + defaultFile + } = params; + this._id = id; + this._defaultFile = defaultFile; + } + + get id() { + return this._id; + } + + get defaultFile() { + return this._defaultFile; + } + + set id(v) { + this._id = v; + } + + set defaultFile(v) { + this._defaultFile = v; + } + +} + +exports.Page = Page; +var _default = Page; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9QYWdlLmpzIl0sIm5hbWVzIjpbIlBhZ2UiLCJjb25zdHJ1Y3RvciIsInBhcmFtcyIsImlkIiwiZGVmYXVsdEZpbGUiLCJfaWQiLCJfZGVmYXVsdEZpbGUiLCJ2Il0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU1BLElBQU4sQ0FBVztBQUNoQjtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNFQyxFQUFBQSxXQUFXLENBQUNDLE1BQU0sR0FBRyxFQUFWLEVBQWM7QUFDdkIsVUFBTTtBQUFFQyxNQUFBQSxFQUFGO0FBQU1DLE1BQUFBO0FBQU4sUUFBc0JGLE1BQTVCO0FBRUEsU0FBS0csR0FBTCxHQUFXRixFQUFYO0FBQ0EsU0FBS0csWUFBTCxHQUFvQkYsV0FBcEI7QUFDRDs7QUFFRCxNQUFJRCxFQUFKLEdBQVM7QUFDUCxXQUFPLEtBQUtFLEdBQVo7QUFDRDs7QUFDRCxNQUFJRCxXQUFKLEdBQWtCO0FBQ2hCLFdBQU8sS0FBS0UsWUFBWjtBQUNEOztBQUNELE1BQUlILEVBQUosQ0FBT0ksQ0FBUCxFQUFVO0FBQ1IsU0FBS0YsR0FBTCxHQUFXRSxDQUFYO0FBQ0Q7O0FBQ0QsTUFBSUgsV0FBSixDQUFnQkcsQ0FBaEIsRUFBbUI7QUFDakIsU0FBS0QsWUFBTCxHQUFvQkMsQ0FBcEI7QUFDRDs7QUExQmU7OztlQTZCSFAsSSIsInNvdXJjZXNDb250ZW50IjpbIi8qZXNsaW50IG5vLXVudXNlZC12YXJzOiBcIm9mZlwiKi9cbi8qKlxuICogQGludGVyZmFjZSBQYWdlXG4gKiBQYWdlXG4gKiBQYWdlIGNvbnRlbnQgdGhhdCBpcyByZXR1cm5lZCBieSBQYWdlUm91dGVyLlxuICovXG5leHBvcnQgY2xhc3MgUGFnZSB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIHBhZ2UuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgVGhlIHBhZ2UgcGFyYW1ldGVycy5cbiAgICogQHBhcmFtIHtTdHJpbmd9IHBhcmFtcy5pZCBUaGUgcGFnZSBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gcGFyYW1zLmRlZmF1bHRGaWxlIFRoZSBwYWdlIGZpbGUgbmFtZS5cbiAgICogQHJldHVybnMge1BhZ2V9IFRoZSBwYWdlLlxuICAgKi9cbiAgY29uc3RydWN0b3IocGFyYW1zID0ge30pIHtcbiAgICBjb25zdCB7IGlkLCBkZWZhdWx0RmlsZSB9ID0gcGFyYW1zO1xuXG4gICAgdGhpcy5faWQgPSBpZDtcbiAgICB0aGlzLl9kZWZhdWx0RmlsZSA9IGRlZmF1bHRGaWxlO1xuICB9XG5cbiAgZ2V0IGlkKCkge1xuICAgIHJldHVybiB0aGlzLl9pZDtcbiAgfVxuICBnZXQgZGVmYXVsdEZpbGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2RlZmF1bHRGaWxlO1xuICB9XG4gIHNldCBpZCh2KSB7XG4gICAgdGhpcy5faWQgPSB2O1xuICB9XG4gIHNldCBkZWZhdWx0RmlsZSh2KSB7XG4gICAgdGhpcy5fZGVmYXVsdEZpbGUgPSB2O1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBhZ2U7XG4iXX0= \ No newline at end of file diff --git a/lib/ParseMessageQueue.js b/lib/ParseMessageQueue.js new file mode 100644 index 0000000000..3bf0e42236 --- /dev/null +++ b/lib/ParseMessageQueue.js @@ -0,0 +1,34 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ParseMessageQueue = void 0; + +var _AdapterLoader = require("./Adapters/AdapterLoader"); + +var _EventEmitterMQ = require("./Adapters/MessageQueue/EventEmitterMQ"); + +const ParseMessageQueue = {}; +exports.ParseMessageQueue = ParseMessageQueue; + +ParseMessageQueue.createPublisher = function (config) { + const adapter = (0, _AdapterLoader.loadAdapter)(config.messageQueueAdapter, _EventEmitterMQ.EventEmitterMQ, config); + + if (typeof adapter.createPublisher !== 'function') { + throw 'pubSubAdapter should have createPublisher()'; + } + + return adapter.createPublisher(config); +}; + +ParseMessageQueue.createSubscriber = function (config) { + const adapter = (0, _AdapterLoader.loadAdapter)(config.messageQueueAdapter, _EventEmitterMQ.EventEmitterMQ, config); + + if (typeof adapter.createSubscriber !== 'function') { + throw 'messageQueueAdapter should have createSubscriber()'; + } + + return adapter.createSubscriber(config); +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9QYXJzZU1lc3NhZ2VRdWV1ZS5qcyJdLCJuYW1lcyI6WyJQYXJzZU1lc3NhZ2VRdWV1ZSIsImNyZWF0ZVB1Ymxpc2hlciIsImNvbmZpZyIsImFkYXB0ZXIiLCJtZXNzYWdlUXVldWVBZGFwdGVyIiwiRXZlbnRFbWl0dGVyTVEiLCJjcmVhdGVTdWJzY3JpYmVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBRUEsTUFBTUEsaUJBQWlCLEdBQUcsRUFBMUI7OztBQUVBQSxpQkFBaUIsQ0FBQ0MsZUFBbEIsR0FBb0MsVUFBVUMsTUFBVixFQUE0QjtBQUM5RCxRQUFNQyxPQUFPLEdBQUcsZ0NBQVlELE1BQU0sQ0FBQ0UsbUJBQW5CLEVBQXdDQyw4QkFBeEMsRUFBd0RILE1BQXhELENBQWhCOztBQUNBLE1BQUksT0FBT0MsT0FBTyxDQUFDRixlQUFmLEtBQW1DLFVBQXZDLEVBQW1EO0FBQ2pELFVBQU0sNkNBQU47QUFDRDs7QUFDRCxTQUFPRSxPQUFPLENBQUNGLGVBQVIsQ0FBd0JDLE1BQXhCLENBQVA7QUFDRCxDQU5EOztBQVFBRixpQkFBaUIsQ0FBQ00sZ0JBQWxCLEdBQXFDLFVBQVVKLE1BQVYsRUFBNkI7QUFDaEUsUUFBTUMsT0FBTyxHQUFHLGdDQUFZRCxNQUFNLENBQUNFLG1CQUFuQixFQUF3Q0MsOEJBQXhDLEVBQXdESCxNQUF4RCxDQUFoQjs7QUFDQSxNQUFJLE9BQU9DLE9BQU8sQ0FBQ0csZ0JBQWYsS0FBb0MsVUFBeEMsRUFBb0Q7QUFDbEQsVUFBTSxvREFBTjtBQUNEOztBQUNELFNBQU9ILE9BQU8sQ0FBQ0csZ0JBQVIsQ0FBeUJKLE1BQXpCLENBQVA7QUFDRCxDQU5EIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbG9hZEFkYXB0ZXIgfSBmcm9tICcuL0FkYXB0ZXJzL0FkYXB0ZXJMb2FkZXInO1xuaW1wb3J0IHsgRXZlbnRFbWl0dGVyTVEgfSBmcm9tICcuL0FkYXB0ZXJzL01lc3NhZ2VRdWV1ZS9FdmVudEVtaXR0ZXJNUSc7XG5cbmNvbnN0IFBhcnNlTWVzc2FnZVF1ZXVlID0ge307XG5cblBhcnNlTWVzc2FnZVF1ZXVlLmNyZWF0ZVB1Ymxpc2hlciA9IGZ1bmN0aW9uIChjb25maWc6IGFueSk6IGFueSB7XG4gIGNvbnN0IGFkYXB0ZXIgPSBsb2FkQWRhcHRlcihjb25maWcubWVzc2FnZVF1ZXVlQWRhcHRlciwgRXZlbnRFbWl0dGVyTVEsIGNvbmZpZyk7XG4gIGlmICh0eXBlb2YgYWRhcHRlci5jcmVhdGVQdWJsaXNoZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyAncHViU3ViQWRhcHRlciBzaG91bGQgaGF2ZSBjcmVhdGVQdWJsaXNoZXIoKSc7XG4gIH1cbiAgcmV0dXJuIGFkYXB0ZXIuY3JlYXRlUHVibGlzaGVyKGNvbmZpZyk7XG59O1xuXG5QYXJzZU1lc3NhZ2VRdWV1ZS5jcmVhdGVTdWJzY3JpYmVyID0gZnVuY3Rpb24gKGNvbmZpZzogYW55KTogdm9pZCB7XG4gIGNvbnN0IGFkYXB0ZXIgPSBsb2FkQWRhcHRlcihjb25maWcubWVzc2FnZVF1ZXVlQWRhcHRlciwgRXZlbnRFbWl0dGVyTVEsIGNvbmZpZyk7XG4gIGlmICh0eXBlb2YgYWRhcHRlci5jcmVhdGVTdWJzY3JpYmVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgJ21lc3NhZ2VRdWV1ZUFkYXB0ZXIgc2hvdWxkIGhhdmUgY3JlYXRlU3Vic2NyaWJlcigpJztcbiAgfVxuICByZXR1cm4gYWRhcHRlci5jcmVhdGVTdWJzY3JpYmVyKGNvbmZpZyk7XG59O1xuXG5leHBvcnQgeyBQYXJzZU1lc3NhZ2VRdWV1ZSB9O1xuIl19 \ No newline at end of file diff --git a/lib/ParseServer.js b/lib/ParseServer.js new file mode 100644 index 0000000000..7081dac4fb --- /dev/null +++ b/lib/ParseServer.js @@ -0,0 +1,499 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _Options = require("./Options"); + +var _defaults = _interopRequireDefault(require("./defaults")); + +var logging = _interopRequireWildcard(require("./logger")); + +var _Config = _interopRequireDefault(require("./Config")); + +var _PromiseRouter = _interopRequireDefault(require("./PromiseRouter")); + +var _requiredParameter = _interopRequireDefault(require("./requiredParameter")); + +var _AnalyticsRouter = require("./Routers/AnalyticsRouter"); + +var _ClassesRouter = require("./Routers/ClassesRouter"); + +var _FeaturesRouter = require("./Routers/FeaturesRouter"); + +var _FilesRouter = require("./Routers/FilesRouter"); + +var _FunctionsRouter = require("./Routers/FunctionsRouter"); + +var _GlobalConfigRouter = require("./Routers/GlobalConfigRouter"); + +var _GraphQLRouter = require("./Routers/GraphQLRouter"); + +var _HooksRouter = require("./Routers/HooksRouter"); + +var _IAPValidationRouter = require("./Routers/IAPValidationRouter"); + +var _InstallationsRouter = require("./Routers/InstallationsRouter"); + +var _LogsRouter = require("./Routers/LogsRouter"); + +var _ParseLiveQueryServer = require("./LiveQuery/ParseLiveQueryServer"); + +var _PagesRouter = require("./Routers/PagesRouter"); + +var _PublicAPIRouter = require("./Routers/PublicAPIRouter"); + +var _PushRouter = require("./Routers/PushRouter"); + +var _CloudCodeRouter = require("./Routers/CloudCodeRouter"); + +var _RolesRouter = require("./Routers/RolesRouter"); + +var _SchemasRouter = require("./Routers/SchemasRouter"); + +var _SessionsRouter = require("./Routers/SessionsRouter"); + +var _UsersRouter = require("./Routers/UsersRouter"); + +var _PurgeRouter = require("./Routers/PurgeRouter"); + +var _AudiencesRouter = require("./Routers/AudiencesRouter"); + +var _AggregateRouter = require("./Routers/AggregateRouter"); + +var _ParseServerRESTController = require("./ParseServerRESTController"); + +var controllers = _interopRequireWildcard(require("./Controllers")); + +var _ParseGraphQLServer = require("./GraphQL/ParseGraphQLServer"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// ParseServer - open-source compatible API Server for Parse apps +var batch = require('./batch'), + bodyParser = require('body-parser'), + express = require('express'), + middlewares = require('./middlewares'), + Parse = require('parse/node').Parse, + { + parse +} = require('graphql'), + path = require('path'), + fs = require('fs'); + +// Mutate the Parse object to add the Cloud Code handlers +addParseCloud(); // ParseServer works like a constructor of an express app. +// https://parseplatform.org/parse-server/api/master/ParseServerOptions.html + +class ParseServer { + /** + * @constructor + * @param {ParseServerOptions} options the parse server initialization options + */ + constructor(options) { + injectDefaults(options); + const { + appId = (0, _requiredParameter.default)('You must provide an appId!'), + masterKey = (0, _requiredParameter.default)('You must provide a masterKey!'), + cloud, + javascriptKey, + serverURL = (0, _requiredParameter.default)('You must provide a serverURL!'), + serverStartComplete + } = options; // Initialize the node client SDK automatically + + Parse.initialize(appId, javascriptKey || 'unused', masterKey); + Parse.serverURL = serverURL; + const allControllers = controllers.getControllers(options); + const { + loggerController, + databaseController, + hooksController + } = allControllers; + this.config = _Config.default.put(Object.assign({}, options, allControllers)); + logging.setLogger(loggerController); + const dbInitPromise = databaseController.performInitialization(); + const hooksLoadPromise = hooksController.load(); // Note: Tests will start to fail if any validation happens after this is called. + + Promise.all([dbInitPromise, hooksLoadPromise]).then(() => { + if (serverStartComplete) { + serverStartComplete(); + } + }).catch(error => { + if (serverStartComplete) { + serverStartComplete(error); + } else { + console.error(error); + process.exit(1); + } + }); + + if (cloud) { + addParseCloud(); + + if (typeof cloud === 'function') { + cloud(Parse); + } else if (typeof cloud === 'string') { + require(path.resolve(process.cwd(), cloud)); + } else { + throw "argument 'cloud' must either be a string or a function"; + } + } + } + + get app() { + if (!this._app) { + this._app = ParseServer.app(this.config); + } + + return this._app; + } + + handleShutdown() { + const promises = []; + const { + adapter: databaseAdapter + } = this.config.databaseController; + + if (databaseAdapter && typeof databaseAdapter.handleShutdown === 'function') { + promises.push(databaseAdapter.handleShutdown()); + } + + const { + adapter: fileAdapter + } = this.config.filesController; + + if (fileAdapter && typeof fileAdapter.handleShutdown === 'function') { + promises.push(fileAdapter.handleShutdown()); + } + + const { + adapter: cacheAdapter + } = this.config.cacheController; + + if (cacheAdapter && typeof cacheAdapter.handleShutdown === 'function') { + promises.push(cacheAdapter.handleShutdown()); + } + + return (promises.length > 0 ? Promise.all(promises) : Promise.resolve()).then(() => { + if (this.config.serverCloseComplete) { + this.config.serverCloseComplete(); + } + }); + } + /** + * @static + * Create an express app for the parse server + * @param {Object} options let you specify the maxUploadSize when creating the express app */ + + + static app(options) { + const { + maxUploadSize = '20mb', + appId, + directAccess, + pages + } = options; // This app serves the Parse API directly. + // It's the equivalent of https://api.parse.com/1 in the hosted Parse API. + + var api = express(); //api.use("/apps", express.static(__dirname + "/public")); + + api.use(middlewares.allowCrossDomain(appId)); // File handling needs to be before default middlewares are applied + + api.use('/', new _FilesRouter.FilesRouter().expressRouter({ + maxUploadSize: maxUploadSize + })); + api.use('/health', function (req, res) { + res.json({ + status: 'ok' + }); + }); + api.use('/', bodyParser.urlencoded({ + extended: false + }), pages.enableRouter ? new _PagesRouter.PagesRouter(pages).expressRouter() : new _PublicAPIRouter.PublicAPIRouter().expressRouter()); + api.use(bodyParser.json({ + type: '*/*', + limit: maxUploadSize + })); + api.use(middlewares.allowMethodOverride); + api.use(middlewares.handleParseHeaders); + const appRouter = ParseServer.promiseRouter({ + appId + }); + api.use(appRouter.expressRouter()); + api.use(middlewares.handleParseErrors); // run the following when not testing + + if (!process.env.TESTING) { + //This causes tests to spew some useless warnings, so disable in test + + /* istanbul ignore next */ + process.on('uncaughtException', err => { + if (err.code === 'EADDRINUSE') { + // user-friendly message for this common error + process.stderr.write(`Unable to listen on port ${err.port}. The port is already in use.`); + process.exit(0); + } else { + throw err; + } + }); // verify the server url after a 'mount' event is received + + /* istanbul ignore next */ + + api.on('mount', function () { + ParseServer.verifyServerUrl(); + }); + } + + if (process.env.PARSE_SERVER_ENABLE_EXPERIMENTAL_DIRECT_ACCESS === '1' || directAccess) { + Parse.CoreManager.setRESTController((0, _ParseServerRESTController.ParseServerRESTController)(appId, appRouter)); + } + + return api; + } + + static promiseRouter({ + appId + }) { + const routers = [new _ClassesRouter.ClassesRouter(), new _UsersRouter.UsersRouter(), new _SessionsRouter.SessionsRouter(), new _RolesRouter.RolesRouter(), new _AnalyticsRouter.AnalyticsRouter(), new _InstallationsRouter.InstallationsRouter(), new _FunctionsRouter.FunctionsRouter(), new _SchemasRouter.SchemasRouter(), new _PushRouter.PushRouter(), new _LogsRouter.LogsRouter(), new _IAPValidationRouter.IAPValidationRouter(), new _FeaturesRouter.FeaturesRouter(), new _GlobalConfigRouter.GlobalConfigRouter(), new _GraphQLRouter.GraphQLRouter(), new _PurgeRouter.PurgeRouter(), new _HooksRouter.HooksRouter(), new _CloudCodeRouter.CloudCodeRouter(), new _AudiencesRouter.AudiencesRouter(), new _AggregateRouter.AggregateRouter()]; + const routes = routers.reduce((memo, router) => { + return memo.concat(router.routes); + }, []); + const appRouter = new _PromiseRouter.default(routes, appId); + batch.mountOnto(appRouter); + return appRouter; + } + /** + * starts the parse server's express app + * @param {ParseServerOptions} options to use to start the server + * @param {Function} callback called when the server has started + * @returns {ParseServer} the parse server instance + */ + + + start(options, callback) { + const app = express(); + + if (options.middleware) { + let middleware; + + if (typeof options.middleware == 'string') { + middleware = require(path.resolve(process.cwd(), options.middleware)); + } else { + middleware = options.middleware; // use as-is let express fail + } + + app.use(middleware); + } + + app.use(options.mountPath, this.app); + + if (options.mountGraphQL === true || options.mountPlayground === true) { + let graphQLCustomTypeDefs = undefined; + + if (typeof options.graphQLSchema === 'string') { + graphQLCustomTypeDefs = parse(fs.readFileSync(options.graphQLSchema, 'utf8')); + } else if (typeof options.graphQLSchema === 'object' || typeof options.graphQLSchema === 'function') { + graphQLCustomTypeDefs = options.graphQLSchema; + } + + const parseGraphQLServer = new _ParseGraphQLServer.ParseGraphQLServer(this, { + graphQLPath: options.graphQLPath, + playgroundPath: options.playgroundPath, + graphQLCustomTypeDefs + }); + + if (options.mountGraphQL) { + parseGraphQLServer.applyGraphQL(app); + } + + if (options.mountPlayground) { + parseGraphQLServer.applyPlayground(app); + } + } + + const server = app.listen(options.port, options.host, callback); + this.server = server; + + if (options.startLiveQueryServer || options.liveQueryServerOptions) { + this.liveQueryServer = ParseServer.createLiveQueryServer(server, options.liveQueryServerOptions, options); + } + /* istanbul ignore next */ + + + if (!process.env.TESTING) { + configureListeners(this); + } + + this.expressApp = app; + return this; + } + /** + * Creates a new ParseServer and starts it. + * @param {ParseServerOptions} options used to start the server + * @param {Function} callback called when the server has started + * @returns {ParseServer} the parse server instance + */ + + + static start(options, callback) { + const parseServer = new ParseServer(options); + return parseServer.start(options, callback); + } + /** + * Helper method to create a liveQuery server + * @static + * @param {Server} httpServer an optional http server to pass + * @param {LiveQueryServerOptions} config options for the liveQueryServer + * @param {ParseServerOptions} options options for the ParseServer + * @returns {ParseLiveQueryServer} the live query server instance + */ + + + static createLiveQueryServer(httpServer, config, options) { + if (!httpServer || config && config.port) { + var app = express(); + httpServer = require('http').createServer(app); + httpServer.listen(config.port); + } + + return new _ParseLiveQueryServer.ParseLiveQueryServer(httpServer, config, options); + } + + static verifyServerUrl(callback) { + // perform a health check on the serverURL value + if (Parse.serverURL) { + const request = require('./request'); + + request({ + url: Parse.serverURL.replace(/\/$/, '') + '/health' + }).catch(response => response).then(response => { + const json = response.data || null; + + if (response.status !== 200 || !json || json && json.status !== 'ok') { + /* eslint-disable no-console */ + console.warn(`\nWARNING, Unable to connect to '${Parse.serverURL}'.` + ` Cloud code and push notifications may be unavailable!\n`); + /* eslint-enable no-console */ + + if (callback) { + callback(false); + } + } else { + if (callback) { + callback(true); + } + } + }); + } + } + +} + +function addParseCloud() { + const ParseCloud = require('./cloud-code/Parse.Cloud'); + + Object.assign(Parse.Cloud, ParseCloud); + global.Parse = Parse; +} + +function injectDefaults(options) { + Object.keys(_defaults.default).forEach(key => { + if (!Object.prototype.hasOwnProperty.call(options, key)) { + options[key] = _defaults.default[key]; + } + }); + + if (!Object.prototype.hasOwnProperty.call(options, 'serverURL')) { + options.serverURL = `http://localhost:${options.port}${options.mountPath}`; + } // Reserved Characters + + + if (options.appId) { + const regex = /[!#$%'()*+&/:;=?@[\]{}^,|<>]/g; + + if (options.appId.match(regex)) { + console.warn(`\nWARNING, appId that contains special characters can cause issues while using with urls.\n`); + } + } // Backwards compatibility + + + if (options.userSensitiveFields) { + /* eslint-disable no-console */ + !process.env.TESTING && console.warn(`\nDEPRECATED: userSensitiveFields has been replaced by protectedFields allowing the ability to protect fields in all classes with CLP. \n`); + /* eslint-enable no-console */ + + const userSensitiveFields = Array.from(new Set([...(_defaults.default.userSensitiveFields || []), ...(options.userSensitiveFields || [])])); // If the options.protectedFields is unset, + // it'll be assigned the default above. + // Here, protect against the case where protectedFields + // is set, but doesn't have _User. + + if (!('_User' in options.protectedFields)) { + options.protectedFields = Object.assign({ + _User: [] + }, options.protectedFields); + } + + options.protectedFields['_User']['*'] = Array.from(new Set([...(options.protectedFields['_User']['*'] || []), ...userSensitiveFields])); + } // Merge protectedFields options with defaults. + + + Object.keys(_defaults.default.protectedFields).forEach(c => { + const cur = options.protectedFields[c]; + + if (!cur) { + options.protectedFields[c] = _defaults.default.protectedFields[c]; + } else { + Object.keys(_defaults.default.protectedFields[c]).forEach(r => { + const unq = new Set([...(options.protectedFields[c][r] || []), ..._defaults.default.protectedFields[c][r]]); + options.protectedFields[c][r] = Array.from(unq); + }); + } + }); + options.masterKeyIps = Array.from(new Set(options.masterKeyIps.concat(_defaults.default.masterKeyIps, options.masterKeyIps))); +} // Those can't be tested as it requires a subprocess + +/* istanbul ignore next */ + + +function configureListeners(parseServer) { + const server = parseServer.server; + const sockets = {}; + /* Currently, express doesn't shut down immediately after receiving SIGINT/SIGTERM if it has client connections that haven't timed out. (This is a known issue with node - https://github.com/nodejs/node/issues/2642) + This function, along with `destroyAliveConnections()`, intend to fix this behavior such that parse server will close all open connections and initiate the shutdown process as soon as it receives a SIGINT/SIGTERM signal. */ + + server.on('connection', socket => { + const socketId = socket.remoteAddress + ':' + socket.remotePort; + sockets[socketId] = socket; + socket.on('close', () => { + delete sockets[socketId]; + }); + }); + + const destroyAliveConnections = function () { + for (const socketId in sockets) { + try { + sockets[socketId].destroy(); + } catch (e) { + /* */ + } + } + }; + + const handleShutdown = function () { + process.stdout.write('Termination signal received. Shutting down.'); + destroyAliveConnections(); + server.close(); + parseServer.handleShutdown(); + }; + + process.on('SIGTERM', handleShutdown); + process.on('SIGINT', handleShutdown); +} + +var _default = ParseServer; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9QYXJzZVNlcnZlci5qcyJdLCJuYW1lcyI6WyJiYXRjaCIsInJlcXVpcmUiLCJib2R5UGFyc2VyIiwiZXhwcmVzcyIsIm1pZGRsZXdhcmVzIiwiUGFyc2UiLCJwYXJzZSIsInBhdGgiLCJmcyIsImFkZFBhcnNlQ2xvdWQiLCJQYXJzZVNlcnZlciIsImNvbnN0cnVjdG9yIiwib3B0aW9ucyIsImluamVjdERlZmF1bHRzIiwiYXBwSWQiLCJtYXN0ZXJLZXkiLCJjbG91ZCIsImphdmFzY3JpcHRLZXkiLCJzZXJ2ZXJVUkwiLCJzZXJ2ZXJTdGFydENvbXBsZXRlIiwiaW5pdGlhbGl6ZSIsImFsbENvbnRyb2xsZXJzIiwiY29udHJvbGxlcnMiLCJnZXRDb250cm9sbGVycyIsImxvZ2dlckNvbnRyb2xsZXIiLCJkYXRhYmFzZUNvbnRyb2xsZXIiLCJob29rc0NvbnRyb2xsZXIiLCJjb25maWciLCJDb25maWciLCJwdXQiLCJPYmplY3QiLCJhc3NpZ24iLCJsb2dnaW5nIiwic2V0TG9nZ2VyIiwiZGJJbml0UHJvbWlzZSIsInBlcmZvcm1Jbml0aWFsaXphdGlvbiIsImhvb2tzTG9hZFByb21pc2UiLCJsb2FkIiwiUHJvbWlzZSIsImFsbCIsInRoZW4iLCJjYXRjaCIsImVycm9yIiwiY29uc29sZSIsInByb2Nlc3MiLCJleGl0IiwicmVzb2x2ZSIsImN3ZCIsImFwcCIsIl9hcHAiLCJoYW5kbGVTaHV0ZG93biIsInByb21pc2VzIiwiYWRhcHRlciIsImRhdGFiYXNlQWRhcHRlciIsInB1c2giLCJmaWxlQWRhcHRlciIsImZpbGVzQ29udHJvbGxlciIsImNhY2hlQWRhcHRlciIsImNhY2hlQ29udHJvbGxlciIsImxlbmd0aCIsInNlcnZlckNsb3NlQ29tcGxldGUiLCJtYXhVcGxvYWRTaXplIiwiZGlyZWN0QWNjZXNzIiwicGFnZXMiLCJhcGkiLCJ1c2UiLCJhbGxvd0Nyb3NzRG9tYWluIiwiRmlsZXNSb3V0ZXIiLCJleHByZXNzUm91dGVyIiwicmVxIiwicmVzIiwianNvbiIsInN0YXR1cyIsInVybGVuY29kZWQiLCJleHRlbmRlZCIsImVuYWJsZVJvdXRlciIsIlBhZ2VzUm91dGVyIiwiUHVibGljQVBJUm91dGVyIiwidHlwZSIsImxpbWl0IiwiYWxsb3dNZXRob2RPdmVycmlkZSIsImhhbmRsZVBhcnNlSGVhZGVycyIsImFwcFJvdXRlciIsInByb21pc2VSb3V0ZXIiLCJoYW5kbGVQYXJzZUVycm9ycyIsImVudiIsIlRFU1RJTkciLCJvbiIsImVyciIsImNvZGUiLCJzdGRlcnIiLCJ3cml0ZSIsInBvcnQiLCJ2ZXJpZnlTZXJ2ZXJVcmwiLCJQQVJTRV9TRVJWRVJfRU5BQkxFX0VYUEVSSU1FTlRBTF9ESVJFQ1RfQUNDRVNTIiwiQ29yZU1hbmFnZXIiLCJzZXRSRVNUQ29udHJvbGxlciIsInJvdXRlcnMiLCJDbGFzc2VzUm91dGVyIiwiVXNlcnNSb3V0ZXIiLCJTZXNzaW9uc1JvdXRlciIsIlJvbGVzUm91dGVyIiwiQW5hbHl0aWNzUm91dGVyIiwiSW5zdGFsbGF0aW9uc1JvdXRlciIsIkZ1bmN0aW9uc1JvdXRlciIsIlNjaGVtYXNSb3V0ZXIiLCJQdXNoUm91dGVyIiwiTG9nc1JvdXRlciIsIklBUFZhbGlkYXRpb25Sb3V0ZXIiLCJGZWF0dXJlc1JvdXRlciIsIkdsb2JhbENvbmZpZ1JvdXRlciIsIkdyYXBoUUxSb3V0ZXIiLCJQdXJnZVJvdXRlciIsIkhvb2tzUm91dGVyIiwiQ2xvdWRDb2RlUm91dGVyIiwiQXVkaWVuY2VzUm91dGVyIiwiQWdncmVnYXRlUm91dGVyIiwicm91dGVzIiwicmVkdWNlIiwibWVtbyIsInJvdXRlciIsImNvbmNhdCIsIlByb21pc2VSb3V0ZXIiLCJtb3VudE9udG8iLCJzdGFydCIsImNhbGxiYWNrIiwibWlkZGxld2FyZSIsIm1vdW50UGF0aCIsIm1vdW50R3JhcGhRTCIsIm1vdW50UGxheWdyb3VuZCIsImdyYXBoUUxDdXN0b21UeXBlRGVmcyIsInVuZGVmaW5lZCIsImdyYXBoUUxTY2hlbWEiLCJyZWFkRmlsZVN5bmMiLCJwYXJzZUdyYXBoUUxTZXJ2ZXIiLCJQYXJzZUdyYXBoUUxTZXJ2ZXIiLCJncmFwaFFMUGF0aCIsInBsYXlncm91bmRQYXRoIiwiYXBwbHlHcmFwaFFMIiwiYXBwbHlQbGF5Z3JvdW5kIiwic2VydmVyIiwibGlzdGVuIiwiaG9zdCIsInN0YXJ0TGl2ZVF1ZXJ5U2VydmVyIiwibGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucyIsImxpdmVRdWVyeVNlcnZlciIsImNyZWF0ZUxpdmVRdWVyeVNlcnZlciIsImNvbmZpZ3VyZUxpc3RlbmVycyIsImV4cHJlc3NBcHAiLCJwYXJzZVNlcnZlciIsImh0dHBTZXJ2ZXIiLCJjcmVhdGVTZXJ2ZXIiLCJQYXJzZUxpdmVRdWVyeVNlcnZlciIsInJlcXVlc3QiLCJ1cmwiLCJyZXBsYWNlIiwicmVzcG9uc2UiLCJkYXRhIiwid2FybiIsIlBhcnNlQ2xvdWQiLCJDbG91ZCIsImdsb2JhbCIsImtleXMiLCJkZWZhdWx0cyIsImZvckVhY2giLCJrZXkiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJyZWdleCIsIm1hdGNoIiwidXNlclNlbnNpdGl2ZUZpZWxkcyIsIkFycmF5IiwiZnJvbSIsIlNldCIsInByb3RlY3RlZEZpZWxkcyIsIl9Vc2VyIiwiYyIsImN1ciIsInIiLCJ1bnEiLCJtYXN0ZXJLZXlJcHMiLCJzb2NrZXRzIiwic29ja2V0Iiwic29ja2V0SWQiLCJyZW1vdGVBZGRyZXNzIiwicmVtb3RlUG9ydCIsImRlc3Ryb3lBbGl2ZUNvbm5lY3Rpb25zIiwiZGVzdHJveSIsImUiLCJzdGRvdXQiLCJjbG9zZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQVdBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNB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LENBRUUsT0FBT0MsQ0FBUCxFQUFVO0FBQ1Y7QUFDRDtBQUNGO0FBQ0YsR0FSRDs7QUFVQSxRQUFNM0ksY0FBYyxHQUFHLFlBQVk7QUFDakNOLElBQUFBLE9BQU8sQ0FBQ2tKLE1BQVIsQ0FBZW5HLEtBQWYsQ0FBcUIsNkNBQXJCO0FBQ0FnRyxJQUFBQSx1QkFBdUI7QUFDdkIvQyxJQUFBQSxNQUFNLENBQUNtRCxLQUFQO0FBQ0ExQyxJQUFBQSxXQUFXLENBQUNuRyxjQUFaO0FBQ0QsR0FMRDs7QUFNQU4sRUFBQUEsT0FBTyxDQUFDMkMsRUFBUixDQUFXLFNBQVgsRUFBc0JyQyxjQUF0QjtBQUNBTixFQUFBQSxPQUFPLENBQUMyQyxFQUFSLENBQVcsUUFBWCxFQUFxQnJDLGNBQXJCO0FBQ0Q7O2VBRWN4QyxXIiwic291cmNlc0NvbnRlbnQiOlsiLy8gUGFyc2VTZXJ2ZXIgLSBvcGVuLXNvdXJjZSBjb21wYXRpYmxlIEFQSSBTZXJ2ZXIgZm9yIFBhcnNlIGFwcHNcblxudmFyIGJhdGNoID0gcmVxdWlyZSgnLi9iYXRjaCcpLFxuICBib2R5UGFyc2VyID0gcmVxdWlyZSgnYm9keS1wYXJzZXInKSxcbiAgZXhwcmVzcyA9IHJlcXVpcmUoJ2V4cHJlc3MnKSxcbiAgbWlkZGxld2FyZXMgPSByZXF1aXJlKCcuL21pZGRsZXdhcmVzJyksXG4gIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlLFxuICB7IHBhcnNlIH0gPSByZXF1aXJlKCdncmFwaHFsJyksXG4gIHBhdGggPSByZXF1aXJlKCdwYXRoJyksXG4gIGZzID0gcmVxdWlyZSgnZnMnKTtcblxuaW1wb3J0IHsgUGFyc2VTZXJ2ZXJPcHRpb25zLCBMaXZlUXVlcnlTZXJ2ZXJPcHRpb25zIH0gZnJvbSAnLi9PcHRpb25zJztcbmltcG9ydCBkZWZhdWx0cyBmcm9tICcuL2RlZmF1bHRzJztcbmltcG9ydCAqIGFzIGxvZ2dpbmcgZnJvbSAnLi9sb2dnZXInO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuL0NvbmZpZyc7XG5pbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0IHJlcXVpcmVkUGFyYW1ldGVyIGZyb20gJy4vcmVxdWlyZWRQYXJhbWV0ZXInO1xuaW1wb3J0IHsgQW5hbHl0aWNzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0FuYWx5dGljc1JvdXRlcic7XG5pbXBvcnQgeyBDbGFzc2VzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0NsYXNzZXNSb3V0ZXInO1xuaW1wb3J0IHsgRmVhdHVyZXNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvRmVhdHVyZXNSb3V0ZXInO1xuaW1wb3J0IHsgRmlsZXNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvRmlsZXNSb3V0ZXInO1xuaW1wb3J0IHsgRnVuY3Rpb25zUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0Z1bmN0aW9uc1JvdXRlcic7XG5pbXBvcnQgeyBHbG9iYWxDb25maWdSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvR2xvYmFsQ29uZmlnUm91dGVyJztcbmltcG9ydCB7IEdyYXBoUUxSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvR3JhcGhRTFJvdXRlcic7XG5pbXBvcnQgeyBIb29rc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9Ib29rc1JvdXRlcic7XG5pbXBvcnQgeyBJQVBWYWxpZGF0aW9uUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0lBUFZhbGlkYXRpb25Sb3V0ZXInO1xuaW1wb3J0IHsgSW5zdGFsbGF0aW9uc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9JbnN0YWxsYXRpb25zUm91dGVyJztcbmltcG9ydCB7IExvZ3NSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvTG9nc1JvdXRlcic7XG5pbXBvcnQgeyBQYXJzZUxpdmVRdWVyeVNlcnZlciB9IGZyb20gJy4vTGl2ZVF1ZXJ5L1BhcnNlTGl2ZVF1ZXJ5U2VydmVyJztcbmltcG9ydCB7IFBhZ2VzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL1BhZ2VzUm91dGVyJztcbmltcG9ydCB7IFB1YmxpY0FQSVJvdXRlciB9IGZyb20gJy4vUm91dGVycy9QdWJsaWNBUElSb3V0ZXInO1xuaW1wb3J0IHsgUHVzaFJvdXRlciB9IGZyb20gJy4vUm91dGVycy9QdXNoUm91dGVyJztcbmltcG9ydCB7IENsb3VkQ29kZVJvdXRlciB9IGZyb20gJy4vUm91dGVycy9DbG91ZENvZGVSb3V0ZXInO1xuaW1wb3J0IHsgUm9sZXNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvUm9sZXNSb3V0ZXInO1xuaW1wb3J0IHsgU2NoZW1hc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9TY2hlbWFzUm91dGVyJztcbmltcG9ydCB7IFNlc3Npb25zUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL1Nlc3Npb25zUm91dGVyJztcbmltcG9ydCB7IFVzZXJzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL1VzZXJzUm91dGVyJztcbmltcG9ydCB7IFB1cmdlUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL1B1cmdlUm91dGVyJztcbmltcG9ydCB7IEF1ZGllbmNlc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9BdWRpZW5jZXNSb3V0ZXInO1xuaW1wb3J0IHsgQWdncmVnYXRlUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0FnZ3JlZ2F0ZVJvdXRlcic7XG5pbXBvcnQgeyBQYXJzZVNlcnZlclJFU1RDb250cm9sbGVyIH0gZnJvbSAnLi9QYXJzZVNlcnZlclJFU1RDb250cm9sbGVyJztcbmltcG9ydCAqIGFzIGNvbnRyb2xsZXJzIGZyb20gJy4vQ29udHJvbGxlcnMnO1xuaW1wb3J0IHsgUGFyc2VHcmFwaFFMU2VydmVyIH0gZnJvbSAnLi9HcmFwaFFML1BhcnNlR3JhcGhRTFNlcnZlcic7XG5cbi8vIE11dGF0ZSB0aGUgUGFyc2Ugb2JqZWN0IHRvIGFkZCB0aGUgQ2xvdWQgQ29kZSBoYW5kbGVyc1xuYWRkUGFyc2VDbG91ZCgpO1xuXG4vLyBQYXJzZVNlcnZlciB3b3JrcyBsaWtlIGEgY29uc3RydWN0b3Igb2YgYW4gZXhwcmVzcyBhcHAuXG4vLyBodHRwczovL3BhcnNlcGxhdGZvcm0ub3JnL3BhcnNlLXNlcnZlci9hcGkvbWFzdGVyL1BhcnNlU2VydmVyT3B0aW9ucy5odG1sXG5jbGFzcyBQYXJzZVNlcnZlciB7XG4gIC8qKlxuICAgKiBAY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtQYXJzZVNlcnZlck9wdGlvbnN9IG9wdGlvbnMgdGhlIHBhcnNlIHNlcnZlciBpbml0aWFsaXphdGlvbiBvcHRpb25zXG4gICAqL1xuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMpIHtcbiAgICBpbmplY3REZWZhdWx0cyhvcHRpb25zKTtcbiAgICBjb25zdCB7XG4gICAgICBhcHBJZCA9IHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGFuIGFwcElkIScpLFxuICAgICAgbWFzdGVyS2V5ID0gcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYSBtYXN0ZXJLZXkhJyksXG4gICAgICBjbG91ZCxcbiAgICAgIGphdmFzY3JpcHRLZXksXG4gICAgICBzZXJ2ZXJVUkwgPSByZXF1aXJlZFBhcmFtZXRlcignWW91IG11c3QgcHJvdmlkZSBhIHNlcnZlclVSTCEnKSxcbiAgICAgIHNlcnZlclN0YXJ0Q29tcGxldGUsXG4gICAgfSA9IG9wdGlvbnM7XG4gICAgLy8gSW5pdGlhbGl6ZSB0aGUgbm9kZSBjbGllbnQgU0RLIGF1dG9tYXRpY2FsbHlcbiAgICBQYXJzZS5pbml0aWFsaXplKGFwcElkLCBqYXZhc2NyaXB0S2V5IHx8ICd1bnVzZWQnLCBtYXN0ZXJLZXkpO1xuICAgIFBhcnNlLnNlcnZlclVSTCA9IHNlcnZlclVSTDtcblxuICAgIGNvbnN0IGFsbENvbnRyb2xsZXJzID0gY29udHJvbGxlcnMuZ2V0Q29udHJvbGxlcnMob3B0aW9ucyk7XG5cbiAgICBjb25zdCB7IGxvZ2dlckNvbnRyb2xsZXIsIGRhdGFiYXNlQ29udHJvbGxlciwgaG9va3NDb250cm9sbGVyIH0gPSBhbGxDb250cm9sbGVycztcbiAgICB0aGlzLmNvbmZpZyA9IENvbmZpZy5wdXQoT2JqZWN0LmFzc2lnbih7fSwgb3B0aW9ucywgYWxsQ29udHJvbGxlcnMpKTtcblxuICAgIGxvZ2dpbmcuc2V0TG9nZ2VyKGxvZ2dlckNvbnRyb2xsZXIpO1xuICAgIGNvbnN0IGRiSW5pdFByb21pc2UgPSBkYXRhYmFzZUNvbnRyb2xsZXIucGVyZm9ybUluaXRpYWxpemF0aW9uKCk7XG4gICAgY29uc3QgaG9va3NMb2FkUHJvbWlzZSA9IGhvb2tzQ29udHJvbGxlci5sb2FkKCk7XG5cbiAgICAvLyBOb3RlOiBUZXN0cyB3aWxsIHN0YXJ0IHRvIGZhaWwgaWYgYW55IHZhbGlkYXRpb24gaGFwcGVucyBhZnRlciB0aGlzIGlzIGNhbGxlZC5cbiAgICBQcm9taXNlLmFsbChbZGJJbml0UHJvbWlzZSwgaG9va3NMb2FkUHJvbWlzZV0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIGlmIChzZXJ2ZXJTdGFydENvbXBsZXRlKSB7XG4gICAgICAgICAgc2VydmVyU3RhcnRDb21wbGV0ZSgpO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKHNlcnZlclN0YXJ0Q29tcGxldGUpIHtcbiAgICAgICAgICBzZXJ2ZXJTdGFydENvbXBsZXRlKGVycm9yKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgaWYgKGNsb3VkKSB7XG4gICAgICBhZGRQYXJzZUNsb3VkKCk7XG4gICAgICBpZiAodHlwZW9mIGNsb3VkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGNsb3VkKFBhcnNlKTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGNsb3VkID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXF1aXJlKHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBjbG91ZCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgXCJhcmd1bWVudCAnY2xvdWQnIG11c3QgZWl0aGVyIGJlIGEgc3RyaW5nIG9yIGEgZnVuY3Rpb25cIjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBnZXQgYXBwKCkge1xuICAgIGlmICghdGhpcy5fYXBwKSB7XG4gICAgICB0aGlzLl9hcHAgPSBQYXJzZVNlcnZlci5hcHAodGhpcy5jb25maWcpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fYXBwO1xuICB9XG5cbiAgaGFuZGxlU2h1dGRvd24oKSB7XG4gICAgY29uc3QgcHJvbWlzZXMgPSBbXTtcbiAgICBjb25zdCB7IGFkYXB0ZXI6IGRhdGFiYXNlQWRhcHRlciB9ID0gdGhpcy5jb25maWcuZGF0YWJhc2VDb250cm9sbGVyO1xuICAgIGlmIChkYXRhYmFzZUFkYXB0ZXIgJiYgdHlwZW9mIGRhdGFiYXNlQWRhcHRlci5oYW5kbGVTaHV0ZG93biA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcHJvbWlzZXMucHVzaChkYXRhYmFzZUFkYXB0ZXIuaGFuZGxlU2h1dGRvd24oKSk7XG4gICAgfVxuICAgIGNvbnN0IHsgYWRhcHRlcjogZmlsZUFkYXB0ZXIgfSA9IHRoaXMuY29uZmlnLmZpbGVzQ29udHJvbGxlcjtcbiAgICBpZiAoZmlsZUFkYXB0ZXIgJiYgdHlwZW9mIGZpbGVBZGFwdGVyLmhhbmRsZVNodXRkb3duID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwcm9taXNlcy5wdXNoKGZpbGVBZGFwdGVyLmhhbmRsZVNodXRkb3duKCkpO1xuICAgIH1cbiAgICBjb25zdCB7IGFkYXB0ZXI6IGNhY2hlQWRhcHRlciB9ID0gdGhpcy5jb25maWcuY2FjaGVDb250cm9sbGVyO1xuICAgIGlmIChjYWNoZUFkYXB0ZXIgJiYgdHlwZW9mIGNhY2hlQWRhcHRlci5oYW5kbGVTaHV0ZG93biA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcHJvbWlzZXMucHVzaChjYWNoZUFkYXB0ZXIuaGFuZGxlU2h1dGRvd24oKSk7XG4gICAgfVxuICAgIHJldHVybiAocHJvbWlzZXMubGVuZ3RoID4gMCA/IFByb21pc2UuYWxsKHByb21pc2VzKSA6IFByb21pc2UucmVzb2x2ZSgpKS50aGVuKCgpID0+IHtcbiAgICAgIGlmICh0aGlzLmNvbmZpZy5zZXJ2ZXJDbG9zZUNvbXBsZXRlKSB7XG4gICAgICAgIHRoaXMuY29uZmlnLnNlcnZlckNsb3NlQ29tcGxldGUoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3RhdGljXG4gICAqIENyZWF0ZSBhbiBleHByZXNzIGFwcCBmb3IgdGhlIHBhcnNlIHNlcnZlclxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBsZXQgeW91IHNwZWNpZnkgdGhlIG1heFVwbG9hZFNpemUgd2hlbiBjcmVhdGluZyB0aGUgZXhwcmVzcyBhcHAgICovXG4gIHN0YXRpYyBhcHAob3B0aW9ucykge1xuICAgIGNvbnN0IHsgbWF4VXBsb2FkU2l6ZSA9ICcyMG1iJywgYXBwSWQsIGRpcmVjdEFjY2VzcywgcGFnZXMgfSA9IG9wdGlvbnM7XG4gICAgLy8gVGhpcyBhcHAgc2VydmVzIHRoZSBQYXJzZSBBUEkgZGlyZWN0bHkuXG4gICAgLy8gSXQncyB0aGUgZXF1aXZhbGVudCBvZiBodHRwczovL2FwaS5wYXJzZS5jb20vMSBpbiB0aGUgaG9zdGVkIFBhcnNlIEFQSS5cbiAgICB2YXIgYXBpID0gZXhwcmVzcygpO1xuICAgIC8vYXBpLnVzZShcIi9hcHBzXCIsIGV4cHJlc3Muc3RhdGljKF9fZGlybmFtZSArIFwiL3B1YmxpY1wiKSk7XG4gICAgYXBpLnVzZShtaWRkbGV3YXJlcy5hbGxvd0Nyb3NzRG9tYWluKGFwcElkKSk7XG4gICAgLy8gRmlsZSBoYW5kbGluZyBuZWVkcyB0byBiZSBiZWZvcmUgZGVmYXVsdCBtaWRkbGV3YXJlcyBhcmUgYXBwbGllZFxuICAgIGFwaS51c2UoXG4gICAgICAnLycsXG4gICAgICBuZXcgRmlsZXNSb3V0ZXIoKS5leHByZXNzUm91dGVyKHtcbiAgICAgICAgbWF4VXBsb2FkU2l6ZTogbWF4VXBsb2FkU2l6ZSxcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIGFwaS51c2UoJy9oZWFsdGgnLCBmdW5jdGlvbiAocmVxLCByZXMpIHtcbiAgICAgIHJlcy5qc29uKHtcbiAgICAgICAgc3RhdHVzOiAnb2snLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBhcGkudXNlKFxuICAgICAgJy8nLFxuICAgICAgYm9keVBhcnNlci51cmxlbmNvZGVkKHsgZXh0ZW5kZWQ6IGZhbHNlIH0pLFxuICAgICAgcGFnZXMuZW5hYmxlUm91dGVyXG4gICAgICAgID8gbmV3IFBhZ2VzUm91dGVyKHBhZ2VzKS5leHByZXNzUm91dGVyKClcbiAgICAgICAgOiBuZXcgUHVibGljQVBJUm91dGVyKCkuZXhwcmVzc1JvdXRlcigpXG4gICAgKTtcblxuICAgIGFwaS51c2UoYm9keVBhcnNlci5qc29uKHsgdHlwZTogJyovKicsIGxpbWl0OiBtYXhVcGxvYWRTaXplIH0pKTtcbiAgICBhcGkudXNlKG1pZGRsZXdhcmVzLmFsbG93TWV0aG9kT3ZlcnJpZGUpO1xuICAgIGFwaS51c2UobWlkZGxld2FyZXMuaGFuZGxlUGFyc2VIZWFkZXJzKTtcblxuICAgIGNvbnN0IGFwcFJvdXRlciA9IFBhcnNlU2VydmVyLnByb21pc2VSb3V0ZXIoeyBhcHBJZCB9KTtcbiAgICBhcGkudXNlKGFwcFJvdXRlci5leHByZXNzUm91dGVyKCkpO1xuXG4gICAgYXBpLnVzZShtaWRkbGV3YXJlcy5oYW5kbGVQYXJzZUVycm9ycyk7XG5cbiAgICAvLyBydW4gdGhlIGZvbGxvd2luZyB3aGVuIG5vdCB0ZXN0aW5nXG4gICAgaWYgKCFwcm9jZXNzLmVudi5URVNUSU5HKSB7XG4gICAgICAvL1RoaXMgY2F1c2VzIHRlc3RzIHRvIHNwZXcgc29tZSB1c2VsZXNzIHdhcm5pbmdzLCBzbyBkaXNhYmxlIGluIHRlc3RcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICBwcm9jZXNzLm9uKCd1bmNhdWdodEV4Y2VwdGlvbicsIGVyciA9PiB7XG4gICAgICAgIGlmIChlcnIuY29kZSA9PT0gJ0VBRERSSU5VU0UnKSB7XG4gICAgICAgICAgLy8gdXNlci1mcmllbmRseSBtZXNzYWdlIGZvciB0aGlzIGNvbW1vbiBlcnJvclxuICAgICAgICAgIHByb2Nlc3Muc3RkZXJyLndyaXRlKGBVbmFibGUgdG8gbGlzdGVuIG9uIHBvcnQgJHtlcnIucG9ydH0uIFRoZSBwb3J0IGlzIGFscmVhZHkgaW4gdXNlLmApO1xuICAgICAgICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgLy8gdmVyaWZ5IHRoZSBzZXJ2ZXIgdXJsIGFmdGVyIGEgJ21vdW50JyBldmVudCBpcyByZWNlaXZlZFxuICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgIGFwaS5vbignbW91bnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIFBhcnNlU2VydmVyLnZlcmlmeVNlcnZlclVybCgpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChwcm9jZXNzLmVudi5QQVJTRV9TRVJWRVJfRU5BQkxFX0VYUEVSSU1FTlRBTF9ESVJFQ1RfQUNDRVNTID09PSAnMScgfHwgZGlyZWN0QWNjZXNzKSB7XG4gICAgICBQYXJzZS5Db3JlTWFuYWdlci5zZXRSRVNUQ29udHJvbGxlcihQYXJzZVNlcnZlclJFU1RDb250cm9sbGVyKGFwcElkLCBhcHBSb3V0ZXIpKTtcbiAgICB9XG4gICAgcmV0dXJuIGFwaTtcbiAgfVxuXG4gIHN0YXRpYyBwcm9taXNlUm91dGVyKHsgYXBwSWQgfSkge1xuICAgIGNvbnN0IHJvdXRlcnMgPSBbXG4gICAgICBuZXcgQ2xhc3Nlc1JvdXRlcigpLFxuICAgICAgbmV3IFVzZXJzUm91dGVyKCksXG4gICAgICBuZXcgU2Vzc2lvbnNSb3V0ZXIoKSxcbiAgICAgIG5ldyBSb2xlc1JvdXRlcigpLFxuICAgICAgbmV3IEFuYWx5dGljc1JvdXRlcigpLFxuICAgICAgbmV3IEluc3RhbGxhdGlvbnNSb3V0ZXIoKSxcbiAgICAgIG5ldyBGdW5jdGlvbnNSb3V0ZXIoKSxcbiAgICAgIG5ldyBTY2hlbWFzUm91dGVyKCksXG4gICAgICBuZXcgUHVzaFJvdXRlcigpLFxuICAgICAgbmV3IExvZ3NSb3V0ZXIoKSxcbiAgICAgIG5ldyBJQVBWYWxpZGF0aW9uUm91dGVyKCksXG4gICAgICBuZXcgRmVhdHVyZXNSb3V0ZXIoKSxcbiAgICAgIG5ldyBHbG9iYWxDb25maWdSb3V0ZXIoKSxcbiAgICAgIG5ldyBHcmFwaFFMUm91dGVyKCksXG4gICAgICBuZXcgUHVyZ2VSb3V0ZXIoKSxcbiAgICAgIG5ldyBIb29rc1JvdXRlcigpLFxuICAgICAgbmV3IENsb3VkQ29kZVJvdXRlcigpLFxuICAgICAgbmV3IEF1ZGllbmNlc1JvdXRlcigpLFxuICAgICAgbmV3IEFnZ3JlZ2F0ZVJvdXRlcigpLFxuICAgIF07XG5cbiAgICBjb25zdCByb3V0ZXMgPSByb3V0ZXJzLnJlZHVjZSgobWVtbywgcm91dGVyKSA9PiB7XG4gICAgICByZXR1cm4gbWVtby5jb25jYXQocm91dGVyLnJvdXRlcyk7XG4gICAgfSwgW10pO1xuXG4gICAgY29uc3QgYXBwUm91dGVyID0gbmV3IFByb21pc2VSb3V0ZXIocm91dGVzLCBhcHBJZCk7XG5cbiAgICBiYXRjaC5tb3VudE9udG8oYXBwUm91dGVyKTtcbiAgICByZXR1cm4gYXBwUm91dGVyO1xuICB9XG5cbiAgLyoqXG4gICAqIHN0YXJ0cyB0aGUgcGFyc2Ugc2VydmVyJ3MgZXhwcmVzcyBhcHBcbiAgICogQHBhcmFtIHtQYXJzZVNlcnZlck9wdGlvbnN9IG9wdGlvbnMgdG8gdXNlIHRvIHN0YXJ0IHRoZSBzZXJ2ZXJcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgY2FsbGVkIHdoZW4gdGhlIHNlcnZlciBoYXMgc3RhcnRlZFxuICAgKiBAcmV0dXJucyB7UGFyc2VTZXJ2ZXJ9IHRoZSBwYXJzZSBzZXJ2ZXIgaW5zdGFuY2VcbiAgICovXG4gIHN0YXJ0KG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucywgY2FsbGJhY2s6ID8oKSA9PiB2b2lkKSB7XG4gICAgY29uc3QgYXBwID0gZXhwcmVzcygpO1xuICAgIGlmIChvcHRpb25zLm1pZGRsZXdhcmUpIHtcbiAgICAgIGxldCBtaWRkbGV3YXJlO1xuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLm1pZGRsZXdhcmUgPT0gJ3N0cmluZycpIHtcbiAgICAgICAgbWlkZGxld2FyZSA9IHJlcXVpcmUocGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIG9wdGlvbnMubWlkZGxld2FyZSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWlkZGxld2FyZSA9IG9wdGlvbnMubWlkZGxld2FyZTsgLy8gdXNlIGFzLWlzIGxldCBleHByZXNzIGZhaWxcbiAgICAgIH1cbiAgICAgIGFwcC51c2UobWlkZGxld2FyZSk7XG4gICAgfVxuXG4gICAgYXBwLnVzZShvcHRpb25zLm1vdW50UGF0aCwgdGhpcy5hcHApO1xuXG4gICAgaWYgKG9wdGlvbnMubW91bnRHcmFwaFFMID09PSB0cnVlIHx8IG9wdGlvbnMubW91bnRQbGF5Z3JvdW5kID09PSB0cnVlKSB7XG4gICAgICBsZXQgZ3JhcGhRTEN1c3RvbVR5cGVEZWZzID0gdW5kZWZpbmVkO1xuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLmdyYXBoUUxTY2hlbWEgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGdyYXBoUUxDdXN0b21UeXBlRGVmcyA9IHBhcnNlKGZzLnJlYWRGaWxlU3luYyhvcHRpb25zLmdyYXBoUUxTY2hlbWEsICd1dGY4JykpO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgdHlwZW9mIG9wdGlvbnMuZ3JhcGhRTFNjaGVtYSA9PT0gJ29iamVjdCcgfHxcbiAgICAgICAgdHlwZW9mIG9wdGlvbnMuZ3JhcGhRTFNjaGVtYSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgKSB7XG4gICAgICAgIGdyYXBoUUxDdXN0b21UeXBlRGVmcyA9IG9wdGlvbnMuZ3JhcGhRTFNjaGVtYTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGFyc2VHcmFwaFFMU2VydmVyID0gbmV3IFBhcnNlR3JhcGhRTFNlcnZlcih0aGlzLCB7XG4gICAgICAgIGdyYXBoUUxQYXRoOiBvcHRpb25zLmdyYXBoUUxQYXRoLFxuICAgICAgICBwbGF5Z3JvdW5kUGF0aDogb3B0aW9ucy5wbGF5Z3JvdW5kUGF0aCxcbiAgICAgICAgZ3JhcGhRTEN1c3RvbVR5cGVEZWZzLFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChvcHRpb25zLm1vdW50R3JhcGhRTCkge1xuICAgICAgICBwYXJzZUdyYXBoUUxTZXJ2ZXIuYXBwbHlHcmFwaFFMKGFwcCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zLm1vdW50UGxheWdyb3VuZCkge1xuICAgICAgICBwYXJzZUdyYXBoUUxTZXJ2ZXIuYXBwbHlQbGF5Z3JvdW5kKGFwcCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgc2VydmVyID0gYXBwLmxpc3RlbihvcHRpb25zLnBvcnQsIG9wdGlvbnMuaG9zdCwgY2FsbGJhY2spO1xuICAgIHRoaXMuc2VydmVyID0gc2VydmVyO1xuXG4gICAgaWYgKG9wdGlvbnMuc3RhcnRMaXZlUXVlcnlTZXJ2ZXIgfHwgb3B0aW9ucy5saXZlUXVlcnlTZXJ2ZXJPcHRpb25zKSB7XG4gICAgICB0aGlzLmxpdmVRdWVyeVNlcnZlciA9IFBhcnNlU2VydmVyLmNyZWF0ZUxpdmVRdWVyeVNlcnZlcihcbiAgICAgICAgc2VydmVyLFxuICAgICAgICBvcHRpb25zLmxpdmVRdWVyeVNlcnZlck9wdGlvbnMsXG4gICAgICAgIG9wdGlvbnNcbiAgICAgICk7XG4gICAgfVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgaWYgKCFwcm9jZXNzLmVudi5URVNUSU5HKSB7XG4gICAgICBjb25maWd1cmVMaXN0ZW5lcnModGhpcyk7XG4gICAgfVxuICAgIHRoaXMuZXhwcmVzc0FwcCA9IGFwcDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IFBhcnNlU2VydmVyIGFuZCBzdGFydHMgaXQuXG4gICAqIEBwYXJhbSB7UGFyc2VTZXJ2ZXJPcHRpb25zfSBvcHRpb25zIHVzZWQgdG8gc3RhcnQgdGhlIHNlcnZlclxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBjYWxsZWQgd2hlbiB0aGUgc2VydmVyIGhhcyBzdGFydGVkXG4gICAqIEByZXR1cm5zIHtQYXJzZVNlcnZlcn0gdGhlIHBhcnNlIHNlcnZlciBpbnN0YW5jZVxuICAgKi9cbiAgc3RhdGljIHN0YXJ0KG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucywgY2FsbGJhY2s6ID8oKSA9PiB2b2lkKSB7XG4gICAgY29uc3QgcGFyc2VTZXJ2ZXIgPSBuZXcgUGFyc2VTZXJ2ZXIob3B0aW9ucyk7XG4gICAgcmV0dXJuIHBhcnNlU2VydmVyLnN0YXJ0KG9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIZWxwZXIgbWV0aG9kIHRvIGNyZWF0ZSBhIGxpdmVRdWVyeSBzZXJ2ZXJcbiAgICogQHN0YXRpY1xuICAgKiBAcGFyYW0ge1NlcnZlcn0gaHR0cFNlcnZlciBhbiBvcHRpb25hbCBodHRwIHNlcnZlciB0byBwYXNzXG4gICAqIEBwYXJhbSB7TGl2ZVF1ZXJ5U2VydmVyT3B0aW9uc30gY29uZmlnIG9wdGlvbnMgZm9yIHRoZSBsaXZlUXVlcnlTZXJ2ZXJcbiAgICogQHBhcmFtIHtQYXJzZVNlcnZlck9wdGlvbnN9IG9wdGlvbnMgb3B0aW9ucyBmb3IgdGhlIFBhcnNlU2VydmVyXG4gICAqIEByZXR1cm5zIHtQYXJzZUxpdmVRdWVyeVNlcnZlcn0gdGhlIGxpdmUgcXVlcnkgc2VydmVyIGluc3RhbmNlXG4gICAqL1xuICBzdGF0aWMgY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyKFxuICAgIGh0dHBTZXJ2ZXIsXG4gICAgY29uZmlnOiBMaXZlUXVlcnlTZXJ2ZXJPcHRpb25zLFxuICAgIG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9uc1xuICApIHtcbiAgICBpZiAoIWh0dHBTZXJ2ZXIgfHwgKGNvbmZpZyAmJiBjb25maWcucG9ydCkpIHtcbiAgICAgIHZhciBhcHAgPSBleHByZXNzKCk7XG4gICAgICBodHRwU2VydmVyID0gcmVxdWlyZSgnaHR0cCcpLmNyZWF0ZVNlcnZlcihhcHApO1xuICAgICAgaHR0cFNlcnZlci5saXN0ZW4oY29uZmlnLnBvcnQpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFBhcnNlTGl2ZVF1ZXJ5U2VydmVyKGh0dHBTZXJ2ZXIsIGNvbmZpZywgb3B0aW9ucyk7XG4gIH1cblxuICBzdGF0aWMgdmVyaWZ5U2VydmVyVXJsKGNhbGxiYWNrKSB7XG4gICAgLy8gcGVyZm9ybSBhIGhlYWx0aCBjaGVjayBvbiB0aGUgc2VydmVyVVJMIHZhbHVlXG4gICAgaWYgKFBhcnNlLnNlcnZlclVSTCkge1xuICAgICAgY29uc3QgcmVxdWVzdCA9IHJlcXVpcmUoJy4vcmVxdWVzdCcpO1xuICAgICAgcmVxdWVzdCh7IHVybDogUGFyc2Uuc2VydmVyVVJMLnJlcGxhY2UoL1xcLyQvLCAnJykgKyAnL2hlYWx0aCcgfSlcbiAgICAgICAgLmNhdGNoKHJlc3BvbnNlID0+IHJlc3BvbnNlKVxuICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgY29uc3QganNvbiA9IHJlc3BvbnNlLmRhdGEgfHwgbnVsbDtcbiAgICAgICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzICE9PSAyMDAgfHwgIWpzb24gfHwgKGpzb24gJiYganNvbi5zdGF0dXMgIT09ICdvaycpKSB7XG4gICAgICAgICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgIGBcXG5XQVJOSU5HLCBVbmFibGUgdG8gY29ubmVjdCB0byAnJHtQYXJzZS5zZXJ2ZXJVUkx9Jy5gICtcbiAgICAgICAgICAgICAgICBgIENsb3VkIGNvZGUgYW5kIHB1c2ggbm90aWZpY2F0aW9ucyBtYXkgYmUgdW5hdmFpbGFibGUhXFxuYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIC8qIGVzbGludC1lbmFibGUgbm8tY29uc29sZSAqL1xuICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrKGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrKHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGFkZFBhcnNlQ2xvdWQoKSB7XG4gIGNvbnN0IFBhcnNlQ2xvdWQgPSByZXF1aXJlKCcuL2Nsb3VkLWNvZGUvUGFyc2UuQ2xvdWQnKTtcbiAgT2JqZWN0LmFzc2lnbihQYXJzZS5DbG91ZCwgUGFyc2VDbG91ZCk7XG4gIGdsb2JhbC5QYXJzZSA9IFBhcnNlO1xufVxuXG5mdW5jdGlvbiBpbmplY3REZWZhdWx0cyhvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMpIHtcbiAgT2JqZWN0LmtleXMoZGVmYXVsdHMpLmZvckVhY2goa2V5ID0+IHtcbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvcHRpb25zLCBrZXkpKSB7XG4gICAgICBvcHRpb25zW2tleV0gPSBkZWZhdWx0c1trZXldO1xuICAgIH1cbiAgfSk7XG5cbiAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob3B0aW9ucywgJ3NlcnZlclVSTCcpKSB7XG4gICAgb3B0aW9ucy5zZXJ2ZXJVUkwgPSBgaHR0cDovL2xvY2FsaG9zdDoke29wdGlvbnMucG9ydH0ke29wdGlvbnMubW91bnRQYXRofWA7XG4gIH1cblxuICAvLyBSZXNlcnZlZCBDaGFyYWN0ZXJzXG4gIGlmIChvcHRpb25zLmFwcElkKSB7XG4gICAgY29uc3QgcmVnZXggPSAvWyEjJCUnKCkqKyYvOjs9P0BbXFxde31eLHw8Pl0vZztcbiAgICBpZiAob3B0aW9ucy5hcHBJZC5tYXRjaChyZWdleCkpIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYFxcbldBUk5JTkcsIGFwcElkIHRoYXQgY29udGFpbnMgc3BlY2lhbCBjaGFyYWN0ZXJzIGNhbiBjYXVzZSBpc3N1ZXMgd2hpbGUgdXNpbmcgd2l0aCB1cmxzLlxcbmBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLy8gQmFja3dhcmRzIGNvbXBhdGliaWxpdHlcbiAgaWYgKG9wdGlvbnMudXNlclNlbnNpdGl2ZUZpZWxkcykge1xuICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbiAgICAhcHJvY2Vzcy5lbnYuVEVTVElORyAmJlxuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBgXFxuREVQUkVDQVRFRDogdXNlclNlbnNpdGl2ZUZpZWxkcyBoYXMgYmVlbiByZXBsYWNlZCBieSBwcm90ZWN0ZWRGaWVsZHMgYWxsb3dpbmcgdGhlIGFiaWxpdHkgdG8gcHJvdGVjdCBmaWVsZHMgaW4gYWxsIGNsYXNzZXMgd2l0aCBDTFAuIFxcbmBcbiAgICAgICk7XG4gICAgLyogZXNsaW50LWVuYWJsZSBuby1jb25zb2xlICovXG5cbiAgICBjb25zdCB1c2VyU2Vuc2l0aXZlRmllbGRzID0gQXJyYXkuZnJvbShcbiAgICAgIG5ldyBTZXQoWy4uLihkZWZhdWx0cy51c2VyU2Vuc2l0aXZlRmllbGRzIHx8IFtdKSwgLi4uKG9wdGlvbnMudXNlclNlbnNpdGl2ZUZpZWxkcyB8fCBbXSldKVxuICAgICk7XG5cbiAgICAvLyBJZiB0aGUgb3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHMgaXMgdW5zZXQsXG4gICAgLy8gaXQnbGwgYmUgYXNzaWduZWQgdGhlIGRlZmF1bHQgYWJvdmUuXG4gICAgLy8gSGVyZSwgcHJvdGVjdCBhZ2FpbnN0IHRoZSBjYXNlIHdoZXJlIHByb3RlY3RlZEZpZWxkc1xuICAgIC8vIGlzIHNldCwgYnV0IGRvZXNuJ3QgaGF2ZSBfVXNlci5cbiAgICBpZiAoISgnX1VzZXInIGluIG9wdGlvbnMucHJvdGVjdGVkRmllbGRzKSkge1xuICAgICAgb3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHMgPSBPYmplY3QuYXNzaWduKHsgX1VzZXI6IFtdIH0sIG9wdGlvbnMucHJvdGVjdGVkRmllbGRzKTtcbiAgICB9XG5cbiAgICBvcHRpb25zLnByb3RlY3RlZEZpZWxkc1snX1VzZXInXVsnKiddID0gQXJyYXkuZnJvbShcbiAgICAgIG5ldyBTZXQoWy4uLihvcHRpb25zLnByb3RlY3RlZEZpZWxkc1snX1VzZXInXVsnKiddIHx8IFtdKSwgLi4udXNlclNlbnNpdGl2ZUZpZWxkc10pXG4gICAgKTtcbiAgfVxuXG4gIC8vIE1lcmdlIHByb3RlY3RlZEZpZWxkcyBvcHRpb25zIHdpdGggZGVmYXVsdHMuXG4gIE9iamVjdC5rZXlzKGRlZmF1bHRzLnByb3RlY3RlZEZpZWxkcykuZm9yRWFjaChjID0+IHtcbiAgICBjb25zdCBjdXIgPSBvcHRpb25zLnByb3RlY3RlZEZpZWxkc1tjXTtcbiAgICBpZiAoIWN1cikge1xuICAgICAgb3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHNbY10gPSBkZWZhdWx0cy5wcm90ZWN0ZWRGaWVsZHNbY107XG4gICAgfSBlbHNlIHtcbiAgICAgIE9iamVjdC5rZXlzKGRlZmF1bHRzLnByb3RlY3RlZEZpZWxkc1tjXSkuZm9yRWFjaChyID0+IHtcbiAgICAgICAgY29uc3QgdW5xID0gbmV3IFNldChbXG4gICAgICAgICAgLi4uKG9wdGlvbnMucHJvdGVjdGVkRmllbGRzW2NdW3JdIHx8IFtdKSxcbiAgICAgICAgICAuLi5kZWZhdWx0cy5wcm90ZWN0ZWRGaWVsZHNbY11bcl0sXG4gICAgICAgIF0pO1xuICAgICAgICBvcHRpb25zLnByb3RlY3RlZEZpZWxkc1tjXVtyXSA9IEFycmF5LmZyb20odW5xKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgb3B0aW9ucy5tYXN0ZXJLZXlJcHMgPSBBcnJheS5mcm9tKFxuICAgIG5ldyBTZXQob3B0aW9ucy5tYXN0ZXJLZXlJcHMuY29uY2F0KGRlZmF1bHRzLm1hc3RlcktleUlwcywgb3B0aW9ucy5tYXN0ZXJLZXlJcHMpKVxuICApO1xufVxuXG4vLyBUaG9zZSBjYW4ndCBiZSB0ZXN0ZWQgYXMgaXQgcmVxdWlyZXMgYSBzdWJwcm9jZXNzXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuZnVuY3Rpb24gY29uZmlndXJlTGlzdGVuZXJzKHBhcnNlU2VydmVyKSB7XG4gIGNvbnN0IHNlcnZlciA9IHBhcnNlU2VydmVyLnNlcnZlcjtcbiAgY29uc3Qgc29ja2V0cyA9IHt9O1xuICAvKiBDdXJyZW50bHksIGV4cHJlc3MgZG9lc24ndCBzaHV0IGRvd24gaW1tZWRpYXRlbHkgYWZ0ZXIgcmVjZWl2aW5nIFNJR0lOVC9TSUdURVJNIGlmIGl0IGhhcyBjbGllbnQgY29ubmVjdGlvbnMgdGhhdCBoYXZlbid0IHRpbWVkIG91dC4gKFRoaXMgaXMgYSBrbm93biBpc3N1ZSB3aXRoIG5vZGUgLSBodHRwczovL2dpdGh1Yi5jb20vbm9kZWpzL25vZGUvaXNzdWVzLzI2NDIpXG4gICAgVGhpcyBmdW5jdGlvbiwgYWxvbmcgd2l0aCBgZGVzdHJveUFsaXZlQ29ubmVjdGlvbnMoKWAsIGludGVuZCB0byBmaXggdGhpcyBiZWhhdmlvciBzdWNoIHRoYXQgcGFyc2Ugc2VydmVyIHdpbGwgY2xvc2UgYWxsIG9wZW4gY29ubmVjdGlvbnMgYW5kIGluaXRpYXRlIHRoZSBzaHV0ZG93biBwcm9jZXNzIGFzIHNvb24gYXMgaXQgcmVjZWl2ZXMgYSBTSUdJTlQvU0lHVEVSTSBzaWduYWwuICovXG4gIHNlcnZlci5vbignY29ubmVjdGlvbicsIHNvY2tldCA9PiB7XG4gICAgY29uc3Qgc29ja2V0SWQgPSBzb2NrZXQucmVtb3RlQWRkcmVzcyArICc6JyArIHNvY2tldC5yZW1vdGVQb3J0O1xuICAgIHNvY2tldHNbc29ja2V0SWRdID0gc29ja2V0O1xuICAgIHNvY2tldC5vbignY2xvc2UnLCAoKSA9PiB7XG4gICAgICBkZWxldGUgc29ja2V0c1tzb2NrZXRJZF07XG4gICAgfSk7XG4gIH0pO1xuXG4gIGNvbnN0IGRlc3Ryb3lBbGl2ZUNvbm5lY3Rpb25zID0gZnVuY3Rpb24gKCkge1xuICAgIGZvciAoY29uc3Qgc29ja2V0SWQgaW4gc29ja2V0cykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgc29ja2V0c1tzb2NrZXRJZF0uZGVzdHJveSgpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvKiAqL1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBjb25zdCBoYW5kbGVTaHV0ZG93biA9IGZ1bmN0aW9uICgpIHtcbiAgICBwcm9jZXNzLnN0ZG91dC53cml0ZSgnVGVybWluYXRpb24gc2lnbmFsIHJlY2VpdmVkLiBTaHV0dGluZyBkb3duLicpO1xuICAgIGRlc3Ryb3lBbGl2ZUNvbm5lY3Rpb25zKCk7XG4gICAgc2VydmVyLmNsb3NlKCk7XG4gICAgcGFyc2VTZXJ2ZXIuaGFuZGxlU2h1dGRvd24oKTtcbiAgfTtcbiAgcHJvY2Vzcy5vbignU0lHVEVSTScsIGhhbmRsZVNodXRkb3duKTtcbiAgcHJvY2Vzcy5vbignU0lHSU5UJywgaGFuZGxlU2h1dGRvd24pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBQYXJzZVNlcnZlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/ParseServerRESTController.js b/lib/ParseServerRESTController.js new file mode 100644 index 0000000000..9602de13a6 --- /dev/null +++ b/lib/ParseServerRESTController.js @@ -0,0 +1,184 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ParseServerRESTController = ParseServerRESTController; +exports.default = void 0; + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const Config = require('./Config'); + +const Auth = require('./Auth'); + +const RESTController = require('parse/lib/node/RESTController'); + +const URL = require('url'); + +const Parse = require('parse/node'); + +function getSessionToken(options) { + if (options && typeof options.sessionToken === 'string') { + return Promise.resolve(options.sessionToken); + } + + return Promise.resolve(null); +} + +function getAuth(options = {}, config) { + const installationId = options.installationId || 'cloud'; + + if (options.useMasterKey) { + return Promise.resolve(new Auth.Auth({ + config, + isMaster: true, + installationId + })); + } + + return getSessionToken(options).then(sessionToken => { + if (sessionToken) { + options.sessionToken = sessionToken; + return Auth.getAuthForSessionToken({ + config, + sessionToken: sessionToken, + installationId + }); + } else { + return Promise.resolve(new Auth.Auth({ + config, + installationId + })); + } + }); +} + +function ParseServerRESTController(applicationId, router) { + function handleRequest(method, path, data = {}, options = {}, config) { + // Store the arguments, for later use if internal fails + const args = arguments; + + if (!config) { + config = Config.get(applicationId); + } + + const serverURL = URL.parse(config.serverURL); + + if (path.indexOf(serverURL.path) === 0) { + path = path.slice(serverURL.path.length, path.length); + } + + if (path[0] !== '/') { + path = '/' + path; + } + + if (path === '/batch') { + let initialPromise = Promise.resolve(); + + if (data.transaction === true) { + initialPromise = config.database.createTransactionalSession(); + } + + return initialPromise.then(() => { + const promises = data.requests.map(request => { + return handleRequest(request.method, request.path, request.body, options, config).then(response => { + if (options.returnStatus) { + const status = response._status; + delete response._status; + return { + success: response, + _status: status + }; + } + + return { + success: response + }; + }, error => { + return { + error: { + code: error.code, + error: error.message + } + }; + }); + }); + return Promise.all(promises).then(result => { + if (data.transaction === true) { + if (result.find(resultItem => typeof resultItem.error === 'object')) { + return config.database.abortTransactionalSession().then(() => { + return Promise.reject(result); + }); + } else { + return config.database.commitTransactionalSession().then(() => { + return result; + }); + } + } else { + return result; + } + }); + }); + } + + let query; + + if (method === 'GET') { + query = data; + } + + return new Promise((resolve, reject) => { + getAuth(options, config).then(auth => { + const request = { + body: data, + config, + auth, + info: { + applicationId: applicationId, + sessionToken: options.sessionToken, + installationId: options.installationId, + context: options.context || {} // Add context + + }, + query + }; + return Promise.resolve().then(() => { + return router.tryRouteRequest(method, path, request); + }).then(resp => { + const { + response, + status + } = resp; + + if (options.returnStatus) { + resolve(_objectSpread(_objectSpread({}, response), {}, { + _status: status + })); + } else { + resolve(response); + } + }, err => { + if (err instanceof Parse.Error && err.code == Parse.Error.INVALID_JSON && err.message == `cannot route ${method} ${path}`) { + RESTController.request.apply(null, args).then(resolve, reject); + } else { + reject(err); + } + }); + }, reject); + }); + } + + return { + request: handleRequest, + ajax: RESTController.ajax + }; +} + +var _default = ParseServerRESTController; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9QYXJzZVNlcnZlclJFU1RDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIkNvbmZpZyIsInJlcXVpcmUiLCJBdXRoIiwiUkVTVENvbnRyb2xsZXIiLCJVUkwiLCJQYXJzZSIsImdldFNlc3Npb25Ub2tlbiIsIm9wdGlvbnMiLCJzZXNzaW9uVG9rZW4iLCJQcm9taXNlIiwicmVzb2x2ZSIsImdldEF1dGgiLCJjb25maWciLCJpbnN0YWxsYXRpb25JZCIsInVzZU1hc3RlcktleSIsImlzTWFzdGVyIiwidGhlbiIsImdldEF1dGhGb3JTZXNzaW9uVG9rZW4iLCJQYXJzZVNlcnZlclJFU1RDb250cm9sbGVyIiwiYXBwbGljYXRpb25JZCIsInJvdXRlciIsImhhbmRsZVJlcXVlc3QiLCJtZXRob2QiLCJwYXRoIiwiZGF0YSIsImFyZ3MiLCJhcmd1bWVudHMiLCJnZXQiLCJzZXJ2ZXJVUkwiLCJwYXJzZSIsImluZGV4T2YiLCJzbGljZSIsImxlbmd0aCIsImluaXRpYWxQcm9taXNlIiwidHJhbnNhY3Rpb24iLCJkYXRhYmFzZSIsImNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uIiwicHJvbWlzZXMiLCJyZXF1ZXN0cyIsIm1hcCIsInJlcXVlc3QiLCJib2R5IiwicmVzcG9uc2UiLCJyZXR1cm5TdGF0dXMiLCJzdGF0dXMiLCJfc3RhdHVzIiwic3VjY2VzcyIsImVycm9yIiwiY29kZSIsIm1lc3NhZ2UiLCJhbGwiLCJyZXN1bHQiLCJmaW5kIiwicmVzdWx0SXRlbSIsImFib3J0VHJhbnNhY3Rpb25hbFNlc3Npb24iLCJyZWplY3QiLCJjb21taXRUcmFuc2FjdGlvbmFsU2Vzc2lvbiIsInF1ZXJ5IiwiYXV0aCIsImluZm8iLCJjb250ZXh0IiwidHJ5Um91dGVSZXF1ZXN0IiwicmVzcCIsImVyciIsIkVycm9yIiwiSU5WQUxJRF9KU09OIiwiYXBwbHkiLCJhamF4Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQUFBLE1BQU1BLE1BQU0sR0FBR0MsT0FB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SUFBSSxFQUFFaEUsY0FBYyxDQUFDZ0U7QUFGaEIsR0FBUDtBQUlEOztlQUVjakQseUIiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBDb25maWcgPSByZXF1aXJlKCcuL0NvbmZpZycpO1xuY29uc3QgQXV0aCA9IHJlcXVpcmUoJy4vQXV0aCcpO1xuY29uc3QgUkVTVENvbnRyb2xsZXIgPSByZXF1aXJlKCdwYXJzZS9saWIvbm9kZS9SRVNUQ29udHJvbGxlcicpO1xuY29uc3QgVVJMID0gcmVxdWlyZSgndXJsJyk7XG5jb25zdCBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKTtcblxuZnVuY3Rpb24gZ2V0U2Vzc2lvblRva2VuKG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgJiYgdHlwZW9mIG9wdGlvbnMuc2Vzc2lvblRva2VuID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUob3B0aW9ucy5zZXNzaW9uVG9rZW4pO1xuICB9XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUobnVsbCk7XG59XG5cbmZ1bmN0aW9uIGdldEF1dGgob3B0aW9ucyA9IHt9LCBjb25maWcpIHtcbiAgY29uc3QgaW5zdGFsbGF0aW9uSWQgPSBvcHRpb25zLmluc3RhbGxhdGlvbklkIHx8ICdjbG91ZCc7XG4gIGlmIChvcHRpb25zLnVzZU1hc3RlcktleSkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IEF1dGguQXV0aCh7IGNvbmZpZywgaXNNYXN0ZXI6IHRydWUsIGluc3RhbGxhdGlvbklkIH0pKTtcbiAgfVxuICByZXR1cm4gZ2V0U2Vzc2lvblRva2VuKG9wdGlvbnMpLnRoZW4oc2Vzc2lvblRva2VuID0+IHtcbiAgICBpZiAoc2Vzc2lvblRva2VuKSB7XG4gICAgICBvcHRpb25zLnNlc3Npb25Ub2tlbiA9IHNlc3Npb25Ub2tlbjtcbiAgICAgIHJldHVybiBBdXRoLmdldEF1dGhGb3JTZXNzaW9uVG9rZW4oe1xuICAgICAgICBjb25maWcsXG4gICAgICAgIHNlc3Npb25Ub2tlbjogc2Vzc2lvblRva2VuLFxuICAgICAgICBpbnN0YWxsYXRpb25JZCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBBdXRoLkF1dGgoeyBjb25maWcsIGluc3RhbGxhdGlvbklkIH0pKTtcbiAgICB9XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBQYXJzZVNlcnZlclJFU1RDb250cm9sbGVyKGFwcGxpY2F0aW9uSWQsIHJvdXRlcikge1xuICBmdW5jdGlvbiBoYW5kbGVSZXF1ZXN0KG1ldGhvZCwgcGF0aCwgZGF0YSA9IHt9LCBvcHRpb25zID0ge30sIGNvbmZpZykge1xuICAgIC8vIFN0b3JlIHRoZSBhcmd1bWVudHMsIGZvciBsYXRlciB1c2UgaWYgaW50ZXJuYWwgZmFpbHNcbiAgICBjb25zdCBhcmdzID0gYXJndW1lbnRzO1xuXG4gICAgaWYgKCFjb25maWcpIHtcbiAgICAgIGNvbmZpZyA9IENvbmZpZy5nZXQoYXBwbGljYXRpb25JZCk7XG4gICAgfVxuICAgIGNvbnN0IHNlcnZlclVSTCA9IFVSTC5wYXJzZShjb25maWcuc2VydmVyVVJMKTtcbiAgICBpZiAocGF0aC5pbmRleE9mKHNlcnZlclVSTC5wYXRoKSA9PT0gMCkge1xuICAgICAgcGF0aCA9IHBhdGguc2xpY2Uoc2VydmVyVVJMLnBhdGgubGVuZ3RoLCBwYXRoLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgaWYgKHBhdGhbMF0gIT09ICcvJykge1xuICAgICAgcGF0aCA9ICcvJyArIHBhdGg7XG4gICAgfVxuXG4gICAgaWYgKHBhdGggPT09ICcvYmF0Y2gnKSB7XG4gICAgICBsZXQgaW5pdGlhbFByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgIGlmIChkYXRhLnRyYW5zYWN0aW9uID09PSB0cnVlKSB7XG4gICAgICAgIGluaXRpYWxQcm9taXNlID0gY29uZmlnLmRhdGFiYXNlLmNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gaW5pdGlhbFByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gZGF0YS5yZXF1ZXN0cy5tYXAocmVxdWVzdCA9PiB7XG4gICAgICAgICAgcmV0dXJuIGhhbmRsZVJlcXVlc3QocmVxdWVzdC5tZXRob2QsIHJlcXVlc3QucGF0aCwgcmVxdWVzdC5ib2R5LCBvcHRpb25zLCBjb25maWcpLnRoZW4oXG4gICAgICAgICAgICByZXNwb25zZSA9PiB7XG4gICAgICAgICAgICAgIGlmIChvcHRpb25zLnJldHVyblN0YXR1cykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0YXR1cyA9IHJlc3BvbnNlLl9zdGF0dXM7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHJlc3BvbnNlLl9zdGF0dXM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogcmVzcG9uc2UsIF9zdGF0dXM6IHN0YXR1cyB9O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHJlc3BvbnNlIH07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXJyb3IgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGVycm9yOiB7IGNvZGU6IGVycm9yLmNvZGUsIGVycm9yOiBlcnJvci5tZXNzYWdlIH0sXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIGlmIChkYXRhLnRyYW5zYWN0aW9uID09PSB0cnVlKSB7XG4gICAgICAgICAgICBpZiAocmVzdWx0LmZpbmQocmVzdWx0SXRlbSA9PiB0eXBlb2YgcmVzdWx0SXRlbS5lcnJvciA9PT0gJ29iamVjdCcpKSB7XG4gICAgICAgICAgICAgIHJldHVybiBjb25maWcuZGF0YWJhc2UuYWJvcnRUcmFuc2FjdGlvbmFsU2Vzc2lvbigpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChyZXN1bHQpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBjb25maWcuZGF0YWJhc2UuY29tbWl0VHJhbnNhY3Rpb25hbFNlc3Npb24oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgbGV0IHF1ZXJ5O1xuICAgIGlmIChtZXRob2QgPT09ICdHRVQnKSB7XG4gICAgICBxdWVyeSA9IGRhdGE7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGdldEF1dGgob3B0aW9ucywgY29uZmlnKS50aGVuKGF1dGggPT4ge1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0ge1xuICAgICAgICAgIGJvZHk6IGRhdGEsXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIGF1dGgsXG4gICAgICAgICAgaW5mbzoge1xuICAgICAgICAgICAgYXBwbGljYXRpb25JZDogYXBwbGljYXRpb25JZCxcbiAgICAgICAgICAgIHNlc3Npb25Ub2tlbjogb3B0aW9ucy5zZXNzaW9uVG9rZW4sXG4gICAgICAgICAgICBpbnN0YWxsYXRpb25JZDogb3B0aW9ucy5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgICAgIGNvbnRleHQ6IG9wdGlvbnMuY29udGV4dCB8fCB7fSwgLy8gQWRkIGNvbnRleHRcbiAgICAgICAgICB9LFxuICAgICAgICAgIHF1ZXJ5LFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gcm91dGVyLnRyeVJvdXRlUmVxdWVzdChtZXRob2QsIHBhdGgsIHJlcXVlc3QpO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnRoZW4oXG4gICAgICAgICAgICByZXNwID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgeyByZXNwb25zZSwgc3RhdHVzIH0gPSByZXNwO1xuICAgICAgICAgICAgICBpZiAob3B0aW9ucy5yZXR1cm5TdGF0dXMpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHsgLi4ucmVzcG9uc2UsIF9zdGF0dXM6IHN0YXR1cyB9KTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVyciA9PiB7XG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBlcnIgaW5zdGFuY2VvZiBQYXJzZS5FcnJvciAmJlxuICAgICAgICAgICAgICAgIGVyci5jb2RlID09IFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiAmJlxuICAgICAgICAgICAgICAgIGVyci5tZXNzYWdlID09IGBjYW5ub3Qgcm91dGUgJHttZXRob2R9ICR7cGF0aH1gXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIFJFU1RDb250cm9sbGVyLnJlcXVlc3QuYXBwbHkobnVsbCwgYXJncykudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgIH0sIHJlamVjdCk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHJlcXVlc3Q6IGhhbmRsZVJlcXVlc3QsXG4gICAgYWpheDogUkVTVENvbnRyb2xsZXIuYWpheCxcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgUGFyc2VTZXJ2ZXJSRVNUQ29udHJvbGxlcjtcbmV4cG9ydCB7IFBhcnNlU2VydmVyUkVTVENvbnRyb2xsZXIgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/PromiseRouter.js b/lib/PromiseRouter.js new file mode 100644 index 0000000000..348b89f044 --- /dev/null +++ b/lib/PromiseRouter.js @@ -0,0 +1,255 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _express = _interopRequireDefault(require("express")); + +var _logger = _interopRequireDefault(require("./logger")); + +var _util = require("util"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// A router that is based on promises rather than req/res/next. +// This is intended to replace the use of express.Router to handle +// subsections of the API surface. +// This will make it easier to have methods like 'batch' that +// themselves use our routing information, without disturbing express +// components that external developers may be modifying. +const Layer = require('express/lib/router/layer'); + +function validateParameter(key, value) { + if (key == 'className') { + if (value.match(/_?[A-Za-z][A-Za-z_0-9]*/)) { + return value; + } + } else if (key == 'objectId') { + if (value.match(/[A-Za-z0-9]+/)) { + return value; + } + } else { + return value; + } +} + +class PromiseRouter { + // Each entry should be an object with: + // path: the path to route, in express format + // method: the HTTP method that this route handles. + // Must be one of: POST, GET, PUT, DELETE + // handler: a function that takes request, and returns a promise. + // Successful handlers should resolve to an object with fields: + // status: optional. the http status code. defaults to 200 + // response: a json object with the content of the response + // location: optional. a location header + constructor(routes = [], appId) { + this.routes = routes; + this.appId = appId; + this.mountRoutes(); + } // Leave the opportunity to + // subclasses to mount their routes by overriding + + + mountRoutes() {} // Merge the routes into this one + + + merge(router) { + for (var route of router.routes) { + this.routes.push(route); + } + } + + route(method, path, ...handlers) { + switch (method) { + case 'POST': + case 'GET': + case 'PUT': + case 'DELETE': + break; + + default: + throw 'cannot route method: ' + method; + } + + let handler = handlers[0]; + + if (handlers.length > 1) { + handler = function (req) { + return handlers.reduce((promise, handler) => { + return promise.then(() => { + return handler(req); + }); + }, Promise.resolve()); + }; + } + + this.routes.push({ + path: path, + method: method, + handler: handler, + layer: new Layer(path, null, handler) + }); + } // Returns an object with: + // handler: the handler that should deal with this request + // params: any :-params that got parsed from the path + // Returns undefined if there is no match. + + + match(method, path) { + for (var route of this.routes) { + if (route.method != method) { + continue; + } + + const layer = route.layer || new Layer(route.path, null, route.handler); + const match = layer.match(path); + + if (match) { + const params = layer.params; + Object.keys(params).forEach(key => { + params[key] = validateParameter(key, params[key]); + }); + return { + params: params, + handler: route.handler + }; + } + } + } // Mount the routes on this router onto an express app (or express router) + + + mountOnto(expressApp) { + this.routes.forEach(route => { + const method = route.method.toLowerCase(); + const handler = makeExpressHandler(this.appId, route.handler); + expressApp[method].call(expressApp, route.path, handler); + }); + return expressApp; + } + + expressRouter() { + return this.mountOnto(_express.default.Router()); + } + + tryRouteRequest(method, path, request) { + var match = this.match(method, path); + + if (!match) { + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'cannot route ' + method + ' ' + path); + } + + request.params = match.params; + return new Promise((resolve, reject) => { + match.handler(request).then(resolve, reject); + }); + } + +} // A helper function to make an express handler out of a a promise +// handler. +// Express handlers should never throw; if a promise handler throws we +// just treat it like it resolved to an error. + + +exports.default = PromiseRouter; + +function makeExpressHandler(appId, promiseHandler) { + return function (req, res, next) { + try { + const url = maskSensitiveUrl(req); + const body = Object.assign({}, req.body); + const method = req.method; + const headers = req.headers; + + _logger.default.logRequest({ + method, + url, + headers, + body + }); + + promiseHandler(req).then(result => { + clearSchemaCache(req); + + if (!result.response && !result.location && !result.text) { + _logger.default.error('the handler did not include a "response" or a "location" field'); + + throw 'control should not get here'; + } + + _logger.default.logResponse({ + method, + url, + result + }); + + var status = result.status || 200; + res.status(status); + + if (result.headers) { + Object.keys(result.headers).forEach(header => { + res.set(header, result.headers[header]); + }); + } + + if (result.text) { + res.send(result.text); + return; + } + + if (result.location) { + res.set('Location', result.location); // Override the default expressjs response + // as it double encodes %encoded chars in URL + + if (!result.response) { + res.send('Found. Redirecting to ' + result.location); + return; + } + } + + res.json(result.response); + }, error => { + clearSchemaCache(req); + next(error); + }).catch(e => { + clearSchemaCache(req); + + _logger.default.error(`Error generating response. ${(0, _util.inspect)(e)}`, { + error: e + }); + + next(e); + }); + } catch (e) { + clearSchemaCache(req); + + _logger.default.error(`Error handling request: ${(0, _util.inspect)(e)}`, { + error: e + }); + + next(e); + } + }; +} + +function maskSensitiveUrl(req) { + let maskUrl = req.originalUrl.toString(); + const shouldMaskUrl = req.method === 'GET' && req.originalUrl.includes('/login') && !req.originalUrl.includes('classes'); + + if (shouldMaskUrl) { + maskUrl = _logger.default.maskSensitiveUrl(maskUrl); + } + + return maskUrl; +} + +function clearSchemaCache(req) { + if (req.config && !req.config.enableSingleSchemaCache) { + req.config.database.schemaCache.clear(); + } +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9Qcm9taXNlUm91dGVyLmpzIl0sIm5hbWVzIjpbIkxheWVyIiwicmVxdWlyZSIsInZhbGlkYXRlUGFyYW1ldGVyIiwia2V5IiwidmFsdWUiLCJtYXRjaCIsIlByb21pc2VSb3V0ZXIiLCJjb25zdHJ1Y3RvciIsInJvdXRlcyIsImFwcElkIiwibW91bnRSb3V0ZXMiLCJtZXJnZSIsInJvdXRlciIsInJvdXRlIiwicHVzaCIsIm1ldGhvZCIsInBhdGgiLCJoYW5kbGVycyIsImhhbmRsZXIiLCJsZW5ndGgiLCJyZXEiLCJyZWR1Y2UiLCJwcm9taXNlIiwidGhlbiIsIlByb21pc2UiLCJyZXNvbHZlIiwibGF5ZXIiLCJwYXJhbXMiLCJPYmplY3QiLCJrZXlzIiwiZm9yRWFjaCIsIm1vdW50T250byIsImV4cHJlc3NBcHAiLCJ0b0xvd2VyQ2FzZSIsIm1ha2VFeHByZXNzSGFuZGxlciIsImNhbGwiLCJleHByZXNzUm91dGVyIiwiZXhwcmVzcyIsIlJvdXRlciIsInRyeVJvdXRlUmVxdWVzdCIsInJlcXVlc3QiLCJQYXJzZSIsIkVycm9yIiwiSU5WQUxJRF9KU09OIiwicmVqZWN0IiwicHJvbWlzZUhhbmRsZXIiLCJyZXMiLCJuZXh0IiwidXJsIiwibWFza1NlbnNpdGl2ZVVybCIsImJvZHkiLCJhc3NpZ24iLCJoZWFkZXJzIiwibG9nIiwibG9nUmVxdWVzdCIsInJlc3VsdCIsImNsZWFyU2NoZW1hQ2FjaGUiLCJyZXNwb25zZSIsImxvY2F0aW9uIiwidGV4dCIsImVycm9yIiwibG9nUmVzcG9uc2UiLCJzdGF0dXMiLCJoZWFkZXIiLCJzZXQiLCJzZW5kIiwianNvbiIsImNhdGNoIiwiZSIsIm1hc2tVcmwiLCJvcmlnaW5hbFVybCIsInRvU3RyaW5nIiwic2hvdWxkTWFza1VybCIsImluY2x1ZGVzIiwiY29uZmlnIiwiZW5hYmxlU2luZ2xlU2NoZW1hQ2FjaGUiLCJkYXRhYmFzZSIsInNjaGVtYUNhY2hlIiwiY2xlYXIiXSwibWFwcGluZ3MiOiI7Ozs7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QkcsUUFBaEIsQ0FBeUIsU0FBekIsQ0FISDs7QUFJQSxNQUFJRCxhQUFKLEVBQW1CO0FBQ2pCSCxJQUFBQSxPQUFPLEdBQUdoQixnQkFBSUosZ0JBQUosQ0FBcUJvQixPQUFyQixDQUFWO0FBQ0Q7O0FBQ0QsU0FBT0EsT0FBUDtBQUNEOztBQUVELFNBQVNiLGdCQUFULENBQTBCcEMsR0FBMUIsRUFBK0I7QUFDN0IsTUFBSUEsR0FBRyxDQUFDc0QsTUFBSixJQUFjLENBQUN0RCxHQUFHLENBQUNzRCxNQUFKLENBQVdDLHVCQUE5QixFQUF1RDtBQUNyRHZELElBQUFBLEdBQUcsQ0FBQ3NELE1BQUosQ0FBV0UsUUFBWCxDQUFvQkMsV0FBcEIsQ0FBZ0NDLEtBQWhDO0FBQ0Q7QUFDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEEgcm91dGVyIHRoYXQgaXMgYmFzZWQgb24gcHJvbWlzZXMgcmF0aGVyIHRoYW4gcmVxL3Jlcy9uZXh0LlxuLy8gVGhpcyBpcyBpbnRlbmRlZCB0byByZXBsYWNlIHRoZSB1c2Ugb2YgZXhwcmVzcy5Sb3V0ZXIgdG8gaGFuZGxlXG4vLyBzdWJzZWN0aW9ucyBvZiB0aGUgQVBJIHN1cmZhY2UuXG4vLyBUaGlzIHdpbGwgbWFrZSBpdCBlYXNpZXIgdG8gaGF2ZSBtZXRob2RzIGxpa2UgJ2JhdGNoJyB0aGF0XG4vLyB0aGVtc2VsdmVzIHVzZSBvdXIgcm91dGluZyBpbmZvcm1hdGlvbiwgd2l0aG91dCBkaXN0dXJiaW5nIGV4cHJlc3Ncbi8vIGNvbXBvbmVudHMgdGhhdCBleHRlcm5hbCBkZXZlbG9wZXJzIG1heSBiZSBtb2RpZnlpbmcuXG5cbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBleHByZXNzIGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IGxvZyBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgeyBpbnNwZWN0IH0gZnJvbSAndXRpbCc7XG5jb25zdCBMYXllciA9IHJlcXVpcmUoJ2V4cHJlc3MvbGliL3JvdXRlci9sYXllcicpO1xuXG5mdW5jdGlvbiB2YWxpZGF0ZVBhcmFtZXRlcihrZXksIHZhbHVlKSB7XG4gIGlmIChrZXkgPT0gJ2NsYXNzTmFtZScpIHtcbiAgICBpZiAodmFsdWUubWF0Y2goL18/W0EtWmEtel1bQS1aYS16XzAtOV0qLykpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoa2V5ID09ICdvYmplY3RJZCcpIHtcbiAgICBpZiAodmFsdWUubWF0Y2goL1tBLVphLXowLTldKy8pKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQcm9taXNlUm91dGVyIHtcbiAgLy8gRWFjaCBlbnRyeSBzaG91bGQgYmUgYW4gb2JqZWN0IHdpdGg6XG4gIC8vIHBhdGg6IHRoZSBwYXRoIHRvIHJvdXRlLCBpbiBleHByZXNzIGZvcm1hdFxuICAvLyBtZXRob2Q6IHRoZSBIVFRQIG1ldGhvZCB0aGF0IHRoaXMgcm91dGUgaGFuZGxlcy5cbiAgLy8gICBNdXN0IGJlIG9uZSBvZjogUE9TVCwgR0VULCBQVVQsIERFTEVURVxuICAvLyBoYW5kbGVyOiBhIGZ1bmN0aW9uIHRoYXQgdGFrZXMgcmVxdWVzdCwgYW5kIHJldHVybnMgYSBwcm9taXNlLlxuICAvLyAgIFN1Y2Nlc3NmdWwgaGFuZGxlcnMgc2hvdWxkIHJlc29sdmUgdG8gYW4gb2JqZWN0IHdpdGggZmllbGRzOlxuICAvLyAgICAgc3RhdHVzOiBvcHRpb25hbC4gdGhlIGh0dHAgc3RhdHVzIGNvZGUuIGRlZmF1bHRzIHRvIDIwMFxuICAvLyAgICAgcmVzcG9uc2U6IGEganNvbiBvYmplY3Qgd2l0aCB0aGUgY29udGVudCBvZiB0aGUgcmVzcG9uc2VcbiAgLy8gICAgIGxvY2F0aW9uOiBvcHRpb25hbC4gYSBsb2NhdGlvbiBoZWFkZXJcbiAgY29uc3RydWN0b3Iocm91dGVzID0gW10sIGFwcElkKSB7XG4gICAgdGhpcy5yb3V0ZXMgPSByb3V0ZXM7XG4gICAgdGhpcy5hcHBJZCA9IGFwcElkO1xuICAgIHRoaXMubW91bnRSb3V0ZXMoKTtcbiAgfVxuXG4gIC8vIExlYXZlIHRoZSBvcHBvcnR1bml0eSB0b1xuICAvLyBzdWJjbGFzc2VzIHRvIG1vdW50IHRoZWlyIHJvdXRlcyBieSBvdmVycmlkaW5nXG4gIG1vdW50Um91dGVzKCkge31cblxuICAvLyBNZXJnZSB0aGUgcm91dGVzIGludG8gdGhpcyBvbmVcbiAgbWVyZ2Uocm91dGVyKSB7XG4gICAgZm9yICh2YXIgcm91dGUgb2Ygcm91dGVyLnJvdXRlcykge1xuICAgICAgdGhpcy5yb3V0ZXMucHVzaChyb3V0ZSk7XG4gICAgfVxuICB9XG5cbiAgcm91dGUobWV0aG9kLCBwYXRoLCAuLi5oYW5kbGVycykge1xuICAgIHN3aXRjaCAobWV0aG9kKSB7XG4gICAgICBjYXNlICdQT1NUJzpcbiAgICAgIGNhc2UgJ0dFVCc6XG4gICAgICBjYXNlICdQVVQnOlxuICAgICAgY2FzZSAnREVMRVRFJzpcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyAnY2Fubm90IHJvdXRlIG1ldGhvZDogJyArIG1ldGhvZDtcbiAgICB9XG5cbiAgICBsZXQgaGFuZGxlciA9IGhhbmRsZXJzWzBdO1xuXG4gICAgaWYgKGhhbmRsZXJzLmxlbmd0aCA+IDEpIHtcbiAgICAgIGhhbmRsZXIgPSBmdW5jdGlvbiAocmVxKSB7XG4gICAgICAgIHJldHVybiBoYW5kbGVycy5yZWR1Y2UoKHByb21pc2UsIGhhbmRsZXIpID0+IHtcbiAgICAgICAgICByZXR1cm4gcHJvbWlzZS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGVyKHJlcSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0sIFByb21pc2UucmVzb2x2ZSgpKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdGhpcy5yb3V0ZXMucHVzaCh7XG4gICAgICBwYXRoOiBwYXRoLFxuICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICBoYW5kbGVyOiBoYW5kbGVyLFxuICAgICAgbGF5ZXI6IG5ldyBMYXllcihwYXRoLCBudWxsLCBoYW5kbGVyKSxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFJldHVybnMgYW4gb2JqZWN0IHdpdGg6XG4gIC8vICAgaGFuZGxlcjogdGhlIGhhbmRsZXIgdGhhdCBzaG91bGQgZGVhbCB3aXRoIHRoaXMgcmVxdWVzdFxuICAvLyAgIHBhcmFtczogYW55IDotcGFyYW1zIHRoYXQgZ290IHBhcnNlZCBmcm9tIHRoZSBwYXRoXG4gIC8vIFJldHVybnMgdW5kZWZpbmVkIGlmIHRoZXJlIGlzIG5vIG1hdGNoLlxuICBtYXRjaChtZXRob2QsIHBhdGgpIHtcbiAgICBmb3IgKHZhciByb3V0ZSBvZiB0aGlzLnJvdXRlcykge1xuICAgICAgaWYgKHJvdXRlLm1ldGhvZCAhPSBtZXRob2QpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBsYXllciA9IHJvdXRlLmxheWVyIHx8IG5ldyBMYXllcihyb3V0ZS5wYXRoLCBudWxsLCByb3V0ZS5oYW5kbGVyKTtcbiAgICAgIGNvbnN0IG1hdGNoID0gbGF5ZXIubWF0Y2gocGF0aCk7XG4gICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgY29uc3QgcGFyYW1zID0gbGF5ZXIucGFyYW1zO1xuICAgICAgICBPYmplY3Qua2V5cyhwYXJhbXMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICBwYXJhbXNba2V5XSA9IHZhbGlkYXRlUGFyYW1ldGVyKGtleSwgcGFyYW1zW2tleV0pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHsgcGFyYW1zOiBwYXJhbXMsIGhhbmRsZXI6IHJvdXRlLmhhbmRsZXIgfTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBNb3VudCB0aGUgcm91dGVzIG9uIHRoaXMgcm91dGVyIG9udG8gYW4gZXhwcmVzcyBhcHAgKG9yIGV4cHJlc3Mgcm91dGVyKVxuICBtb3VudE9udG8oZXhwcmVzc0FwcCkge1xuICAgIHRoaXMucm91dGVzLmZvckVhY2gocm91dGUgPT4ge1xuICAgICAgY29uc3QgbWV0aG9kID0gcm91dGUubWV0aG9kLnRvTG93ZXJDYXNlKCk7XG4gICAgICBjb25zdCBoYW5kbGVyID0gbWFrZUV4cHJlc3NIYW5kbGVyKHRoaXMuYXBwSWQsIHJvdXRlLmhhbmRsZXIpO1xuICAgICAgZXhwcmVzc0FwcFttZXRob2RdLmNhbGwoZXhwcmVzc0FwcCwgcm91dGUucGF0aCwgaGFuZGxlcik7XG4gICAgfSk7XG4gICAgcmV0dXJuIGV4cHJlc3NBcHA7XG4gIH1cblxuICBleHByZXNzUm91dGVyKCkge1xuICAgIHJldHVybiB0aGlzLm1vdW50T250byhleHByZXNzLlJvdXRlcigpKTtcbiAgfVxuXG4gIHRyeVJvdXRlUmVxdWVzdChtZXRob2QsIHBhdGgsIHJlcXVlc3QpIHtcbiAgICB2YXIgbWF0Y2ggPSB0aGlzLm1hdGNoKG1ldGhvZCwgcGF0aCk7XG4gICAgaWYgKCFtYXRjaCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2Nhbm5vdCByb3V0ZSAnICsgbWV0aG9kICsgJyAnICsgcGF0aCk7XG4gICAgfVxuICAgIHJlcXVlc3QucGFyYW1zID0gbWF0Y2gucGFyYW1zO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBtYXRjaC5oYW5kbGVyKHJlcXVlc3QpLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcbiAgICB9KTtcbiAgfVxufVxuXG4vLyBBIGhlbHBlciBmdW5jdGlvbiB0byBtYWtlIGFuIGV4cHJlc3MgaGFuZGxlciBvdXQgb2YgYSBhIHByb21pc2Vcbi8vIGhhbmRsZXIuXG4vLyBFeHByZXNzIGhhbmRsZXJzIHNob3VsZCBuZXZlciB0aHJvdzsgaWYgYSBwcm9taXNlIGhhbmRsZXIgdGhyb3dzIHdlXG4vLyBqdXN0IHRyZWF0IGl0IGxpa2UgaXQgcmVzb2x2ZWQgdG8gYW4gZXJyb3IuXG5mdW5jdGlvbiBtYWtlRXhwcmVzc0hhbmRsZXIoYXBwSWQsIHByb21pc2VIYW5kbGVyKSB7XG4gIHJldHVybiBmdW5jdGlvbiAocmVxLCByZXMsIG5leHQpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdXJsID0gbWFza1NlbnNpdGl2ZVVybChyZXEpO1xuICAgICAgY29uc3QgYm9keSA9IE9iamVjdC5hc3NpZ24oe30sIHJlcS5ib2R5KTtcbiAgICAgIGNvbnN0IG1ldGhvZCA9IHJlcS5tZXRob2Q7XG4gICAgICBjb25zdCBoZWFkZXJzID0gcmVxLmhlYWRlcnM7XG4gICAgICBsb2cubG9nUmVxdWVzdCh7XG4gICAgICAgIG1ldGhvZCxcbiAgICAgICAgdXJsLFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICBib2R5LFxuICAgICAgfSk7XG4gICAgICBwcm9taXNlSGFuZGxlcihyZXEpXG4gICAgICAgIC50aGVuKFxuICAgICAgICAgIHJlc3VsdCA9PiB7XG4gICAgICAgICAgICBjbGVhclNjaGVtYUNhY2hlKHJlcSk7XG4gICAgICAgICAgICBpZiAoIXJlc3VsdC5yZXNwb25zZSAmJiAhcmVzdWx0LmxvY2F0aW9uICYmICFyZXN1bHQudGV4dCkge1xuICAgICAgICAgICAgICBsb2cuZXJyb3IoJ3RoZSBoYW5kbGVyIGRpZCBub3QgaW5jbHVkZSBhIFwicmVzcG9uc2VcIiBvciBhIFwibG9jYXRpb25cIiBmaWVsZCcpO1xuICAgICAgICAgICAgICB0aHJvdyAnY29udHJvbCBzaG91bGQgbm90IGdldCBoZXJlJztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbG9nLmxvZ1Jlc3BvbnNlKHsgbWV0aG9kLCB1cmwsIHJlc3VsdCB9KTtcblxuICAgICAgICAgICAgdmFyIHN0YXR1cyA9IHJlc3VsdC5zdGF0dXMgfHwgMjAwO1xuICAgICAgICAgICAgcmVzLnN0YXR1cyhzdGF0dXMpO1xuXG4gICAgICAgICAgICBpZiAocmVzdWx0LmhlYWRlcnMpIHtcbiAgICAgICAgICAgICAgT2JqZWN0LmtleXMocmVzdWx0LmhlYWRlcnMpLmZvckVhY2goaGVhZGVyID0+IHtcbiAgICAgICAgICAgICAgICByZXMuc2V0KGhlYWRlciwgcmVzdWx0LmhlYWRlcnNbaGVhZGVyXSk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocmVzdWx0LnRleHQpIHtcbiAgICAgICAgICAgICAgcmVzLnNlbmQocmVzdWx0LnRleHQpO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChyZXN1bHQubG9jYXRpb24pIHtcbiAgICAgICAgICAgICAgcmVzLnNldCgnTG9jYXRpb24nLCByZXN1bHQubG9jYXRpb24pO1xuICAgICAgICAgICAgICAvLyBPdmVycmlkZSB0aGUgZGVmYXVsdCBleHByZXNzanMgcmVzcG9uc2VcbiAgICAgICAgICAgICAgLy8gYXMgaXQgZG91YmxlIGVuY29kZXMgJWVuY29kZWQgY2hhcnMgaW4gVVJMXG4gICAgICAgICAgICAgIGlmICghcmVzdWx0LnJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgcmVzLnNlbmQoJ0ZvdW5kLiBSZWRpcmVjdGluZyB0byAnICsgcmVzdWx0LmxvY2F0aW9uKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlcy5qc29uKHJlc3VsdC5yZXNwb25zZSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBlcnJvciA9PiB7XG4gICAgICAgICAgICBjbGVhclNjaGVtYUNhY2hlKHJlcSk7XG4gICAgICAgICAgICBuZXh0KGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIClcbiAgICAgICAgLmNhdGNoKGUgPT4ge1xuICAgICAgICAgIGNsZWFyU2NoZW1hQ2FjaGUocmVxKTtcbiAgICAgICAgICBsb2cuZXJyb3IoYEVycm9yIGdlbmVyYXRpbmcgcmVzcG9uc2UuICR7aW5zcGVjdChlKX1gLCB7IGVycm9yOiBlIH0pO1xuICAgICAgICAgIG5leHQoZSk7XG4gICAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNsZWFyU2NoZW1hQ2FjaGUocmVxKTtcbiAgICAgIGxvZy5lcnJvcihgRXJyb3IgaGFuZGxpbmcgcmVxdWVzdDogJHtpbnNwZWN0KGUpfWAsIHsgZXJyb3I6IGUgfSk7XG4gICAgICBuZXh0KGUpO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gbWFza1NlbnNpdGl2ZVVybChyZXEpIHtcbiAgbGV0IG1hc2tVcmwgPSByZXEub3JpZ2luYWxVcmwudG9TdHJpbmcoKTtcbiAgY29uc3Qgc2hvdWxkTWFza1VybCA9XG4gICAgcmVxLm1ldGhvZCA9PT0gJ0dFVCcgJiZcbiAgICByZXEub3JpZ2luYWxVcmwuaW5jbHVkZXMoJy9sb2dpbicpICYmXG4gICAgIXJlcS5vcmlnaW5hbFVybC5pbmNsdWRlcygnY2xhc3NlcycpO1xuICBpZiAoc2hvdWxkTWFza1VybCkge1xuICAgIG1hc2tVcmwgPSBsb2cubWFza1NlbnNpdGl2ZVVybChtYXNrVXJsKTtcbiAgfVxuICByZXR1cm4gbWFza1VybDtcbn1cblxuZnVuY3Rpb24gY2xlYXJTY2hlbWFDYWNoZShyZXEpIHtcbiAgaWYgKHJlcS5jb25maWcgJiYgIXJlcS5jb25maWcuZW5hYmxlU2luZ2xlU2NoZW1hQ2FjaGUpIHtcbiAgICByZXEuY29uZmlnLmRhdGFiYXNlLnNjaGVtYUNhY2hlLmNsZWFyKCk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Push/PushQueue.js b/lib/Push/PushQueue.js new file mode 100644 index 0000000000..f3e2d1d755 --- /dev/null +++ b/lib/Push/PushQueue.js @@ -0,0 +1,79 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.PushQueue = void 0; + +var _ParseMessageQueue = require("../ParseMessageQueue"); + +var _rest = _interopRequireDefault(require("../rest")); + +var _utils = require("./utils"); + +var _node = _interopRequireDefault(require("parse/node")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const PUSH_CHANNEL = 'parse-server-push'; +const DEFAULT_BATCH_SIZE = 100; + +class PushQueue { + // config object of the publisher, right now it only contains the redisURL, + // but we may extend it later. + constructor(config = {}) { + this.channel = config.channel || PushQueue.defaultPushChannel(); + this.batchSize = config.batchSize || DEFAULT_BATCH_SIZE; + this.parsePublisher = _ParseMessageQueue.ParseMessageQueue.createPublisher(config); + } + + static defaultPushChannel() { + return `${_node.default.applicationId}-${PUSH_CHANNEL}`; + } + + enqueue(body, where, config, auth, pushStatus) { + const limit = this.batchSize; + where = (0, _utils.applyDeviceTokenExists)(where); // Order by objectId so no impact on the DB + + const order = 'objectId'; + return Promise.resolve().then(() => { + return _rest.default.find(config, auth, '_Installation', where, { + limit: 0, + count: true + }); + }).then(({ + results, + count + }) => { + if (!results || count == 0) { + return pushStatus.complete(); + } + + pushStatus.setRunning(Math.ceil(count / limit)); + let skip = 0; + + while (skip < count) { + const query = { + where, + limit, + skip, + order + }; + const pushWorkItem = { + body, + query, + pushStatus: { + objectId: pushStatus.objectId + }, + applicationId: config.applicationId + }; + this.parsePublisher.publish(this.channel, JSON.stringify(pushWorkItem)); + skip += limit; + } + }); + } + +} + +exports.PushQueue = PushQueue; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9QdXNoL1B1c2hRdWV1ZS5qcyJdLCJuYW1lcyI6WyJQVVNIX0NIQU5ORUwiLCJERUZBVUxUX0JBVENIX1NJWkUiLCJQdXNoUXVldWUiLCJjb25zdHJ1Y3RvciIsImNvbmZpZyIsImNoYW5uZWwiLCJkZWZhdWx0UHVzaENoYW5uZWwiLCJiYXRjaFNpemUiLCJwYXJzZVB1Ymxpc2hlciIsIlBhcnNlTWVzc2FnZVF1ZXVlIiwiY3JlYXRlUHVibGlzaGVyIiwiUGFyc2UiLCJhcHBsaWNhdGlvbklkIiwiZW5xdWV1ZSIsImJvZHkiLCJ3aGVyZSIsImF1dGgiLCJwdXNoU3RhdHVzIiwibGltaXQiLCJvcmRlciIsIlByb21pc2UiLCJyZXNvbHZlIiwidGhlbiIsInJlc3QiLCJmaW5kIiwiY291bnQiLCJyZXN1bHRzIiwiY29tcGxldGUiLCJzZXRSdW5uaW5nIiwiTWF0aCIsImNlaWwiLCJza2lwIiwicXVlcnkiLCJwdXNoV29ya0l0ZW0iLCJvYmplY3RJZCIsInB1Ymxpc2giLCJKU09OIiwic3RyaW5naWZ5Il0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxNQUFNQSxZQUFZLEdBQUcsbUJBQXJCO0FBQ0EsTUFBTUMsa0JBQWtCLEdBQUcsR0FBM0I7O0FBRU8sTUFBTUMsU0FBTixDQUFnQjtBQUtyQjtBQUNBO0FBQ0FDLEVBQUFBLFdBQVcsQ0FBQ0MsTUFBVyxHQUFHLEVBQWYsRUFBbUI7QUFDNUIsU0FBS0MsT0FBTCxHQUFlRCxNQUFNLENBQUNDLE9BQVAsSUFBa0JILFNBQVMsQ0FBQ0ksa0JBQVYsRUFBakM7QUFDQSxTQUFLQyxTQUFMLEdBQWlCSCxNQUFNLENBQUNHLFNBQVAsSUFBb0JOLGtCQUFyQztBQUNBLFNBQUtPLGNBQUwsR0FBc0JDLHFDQUFrQkMsZUFBbEIsQ0FBa0NOLE1BQWxDLENBQXRCO0FBQ0Q7O0FBRUQsU0FBT0Usa0JBQVAsR0FBNEI7QUFDMUIsV0FBUSxHQUFFSyxjQUFNQyxhQUFjLElBQUdaLFlBQWEsRUFBOUM7QUFDRDs7QUFFRGEsRUFBQUEsT0FBTyxDQUFDQyxJQUFELEVBQU9DLEtBQVAsRUFBY1gsTUFBZCxFQUFzQlksSUFBdEIsRUFBNEJDLFVBQTVCLEVBQXdDO0FBQzdDLFVBQU1DLEtBQUssR0FBRyxLQUFLWCxTQUFuQjtBQUVBUSxJQUFBQSxLQUFLLEdBQUcsbUNBQXVCQSxLQUF2QixDQUFSLENBSDZDLENBSzdDOztBQUNBLFVBQU1JLEtBQUssR0FBRyxVQUFkO0FBQ0EsV0FBT0MsT0FBTyxDQUFDQyxPQUFSLEdBQ0pDLElBREksQ0FDQyxNQUFNO0FBQ1YsYUFBT0MsY0FBS0MsSUFBTCxDQUFVcEIsTUFBVixFQUFrQlksSUFBbEIsRUFBd0IsZUFBeEIsRUFBeUNELEtBQXpDLEVBQWdEO0FBQ3JERyxRQUFBQSxLQUFLLEVBQUUsQ0FEOEM7QUFFckRPLFFBQUFBLEtBQUssRUFBRTtBQUY4QyxPQUFoRCxDQUFQO0FBSUQsS0FOSSxFQU9KSCxJQVBJLENBT0MsQ0FBQztBQUFFSSxNQUFBQSxPQUFGO0FBQVdELE1BQUFBO0FBQVgsS0FBRCxLQUF3QjtBQUM1QixVQUFJLENBQUNDLE9BQUQsSUFBWUQsS0FBSyxJQUFJLENBQXpCLEVBQTRCO0FBQzFCLGVBQU9SLFVBQVUsQ0FBQ1UsUUFBWCxFQUFQO0FBQ0Q7O0FBQ0RWLE1BQUFBLFVBQVUsQ0FBQ1csVUFBWCxDQUFzQkMsSUFBSSxDQUFDQyxJQUFMLENBQVVMLEtBQUssR0FBR1AsS0FBbEIsQ0FBdEI7QUFDQSxVQUFJYSxJQUFJLEdBQUcsQ0FBWDs7QUFDQSxhQUFPQSxJQUFJLEdBQUdOLEtBQWQsRUFBcUI7QUFDbkIsY0FBTU8sS0FBSyxHQUFHO0FBQ1pqQixVQUFBQSxLQURZO0FBRVpHLFVBQUFBLEtBRlk7QUFHWmEsVUFBQUEsSUFIWTtBQUlaWixVQUFBQTtBQUpZLFNBQWQ7QUFPQSxjQUFNYyxZQUFZLEdBQUc7QUFDbkJuQixVQUFBQSxJQURtQjtBQUVuQmtCLFVBQUFBLEtBRm1CO0FBR25CZixVQUFBQSxVQUFVLEVBQUU7QUFBRWlCLFlBQUFBLFFBQVEsRUFBRWpCLFVBQVUsQ0FBQ2lCO0FBQXZCLFdBSE87QUFJbkJ0QixVQUFBQSxhQUFhLEVBQUVSLE1BQU0sQ0FBQ1E7QUFKSCxTQUFyQjtBQU1BLGFBQUtKLGNBQUwsQ0FBb0IyQixPQUFwQixDQUE0QixLQUFLOUIsT0FBakMsRUFBMEMrQixJQUFJLENBQUNDLFNBQUwsQ0FBZUosWUFBZixDQUExQztBQUNBRixRQUFBQSxJQUFJLElBQUliLEtBQVI7QUFDRDtBQUNGLEtBOUJJLENBQVA7QUErQkQ7O0FBdkRvQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBhcnNlTWVzc2FnZVF1ZXVlIH0gZnJvbSAnLi4vUGFyc2VNZXNzYWdlUXVldWUnO1xuaW1wb3J0IHJlc3QgZnJvbSAnLi4vcmVzdCc7XG5pbXBvcnQgeyBhcHBseURldmljZVRva2VuRXhpc3RzIH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5cbmNvbnN0IFBVU0hfQ0hBTk5FTCA9ICdwYXJzZS1zZXJ2ZXItcHVzaCc7XG5jb25zdCBERUZBVUxUX0JBVENIX1NJWkUgPSAxMDA7XG5cbmV4cG9ydCBjbGFzcyBQdXNoUXVldWUge1xuICBwYXJzZVB1Ymxpc2hlcjogT2JqZWN0O1xuICBjaGFubmVsOiBTdHJpbmc7XG4gIGJhdGNoU2l6ZTogTnVtYmVyO1xuXG4gIC8vIGNvbmZpZyBvYmplY3Qgb2YgdGhlIHB1Ymxpc2hlciwgcmlnaHQgbm93IGl0IG9ubHkgY29udGFpbnMgdGhlIHJlZGlzVVJMLFxuICAvLyBidXQgd2UgbWF5IGV4dGVuZCBpdCBsYXRlci5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBhbnkgPSB7fSkge1xuICAgIHRoaXMuY2hhbm5lbCA9IGNvbmZpZy5jaGFubmVsIHx8IFB1c2hRdWV1ZS5kZWZhdWx0UHVzaENoYW5uZWwoKTtcbiAgICB0aGlzLmJhdGNoU2l6ZSA9IGNvbmZpZy5iYXRjaFNpemUgfHwgREVGQVVMVF9CQVRDSF9TSVpFO1xuICAgIHRoaXMucGFyc2VQdWJsaXNoZXIgPSBQYXJzZU1lc3NhZ2VRdWV1ZS5jcmVhdGVQdWJsaXNoZXIoY29uZmlnKTtcbiAgfVxuXG4gIHN0YXRpYyBkZWZhdWx0UHVzaENoYW5uZWwoKSB7XG4gICAgcmV0dXJuIGAke1BhcnNlLmFwcGxpY2F0aW9uSWR9LSR7UFVTSF9DSEFOTkVMfWA7XG4gIH1cblxuICBlbnF1ZXVlKGJvZHksIHdoZXJlLCBjb25maWcsIGF1dGgsIHB1c2hTdGF0dXMpIHtcbiAgICBjb25zdCBsaW1pdCA9IHRoaXMuYmF0Y2hTaXplO1xuXG4gICAgd2hlcmUgPSBhcHBseURldmljZVRva2VuRXhpc3RzKHdoZXJlKTtcblxuICAgIC8vIE9yZGVyIGJ5IG9iamVjdElkIHNvIG5vIGltcGFjdCBvbiB0aGUgREJcbiAgICBjb25zdCBvcmRlciA9ICdvYmplY3RJZCc7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiByZXN0LmZpbmQoY29uZmlnLCBhdXRoLCAnX0luc3RhbGxhdGlvbicsIHdoZXJlLCB7XG4gICAgICAgICAgbGltaXQ6IDAsXG4gICAgICAgICAgY291bnQ6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCh7IHJlc3VsdHMsIGNvdW50IH0pID0+IHtcbiAgICAgICAgaWYgKCFyZXN1bHRzIHx8IGNvdW50ID09IDApIHtcbiAgICAgICAgICByZXR1cm4gcHVzaFN0YXR1cy5jb21wbGV0ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHB1c2hTdGF0dXMuc2V0UnVubmluZyhNYXRoLmNlaWwoY291bnQgLyBsaW1pdCkpO1xuICAgICAgICBsZXQgc2tpcCA9IDA7XG4gICAgICAgIHdoaWxlIChza2lwIDwgY291bnQpIHtcbiAgICAgICAgICBjb25zdCBxdWVyeSA9IHtcbiAgICAgICAgICAgIHdoZXJlLFxuICAgICAgICAgICAgbGltaXQsXG4gICAgICAgICAgICBza2lwLFxuICAgICAgICAgICAgb3JkZXIsXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGNvbnN0IHB1c2hXb3JrSXRlbSA9IHtcbiAgICAgICAgICAgIGJvZHksXG4gICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgIHB1c2hTdGF0dXM6IHsgb2JqZWN0SWQ6IHB1c2hTdGF0dXMub2JqZWN0SWQgfSxcbiAgICAgICAgICAgIGFwcGxpY2F0aW9uSWQ6IGNvbmZpZy5hcHBsaWNhdGlvbklkLFxuICAgICAgICAgIH07XG4gICAgICAgICAgdGhpcy5wYXJzZVB1Ymxpc2hlci5wdWJsaXNoKHRoaXMuY2hhbm5lbCwgSlNPTi5zdHJpbmdpZnkocHVzaFdvcmtJdGVtKSk7XG4gICAgICAgICAgc2tpcCArPSBsaW1pdDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Push/PushWorker.js b/lib/Push/PushWorker.js new file mode 100644 index 0000000000..d845117b7b --- /dev/null +++ b/lib/Push/PushWorker.js @@ -0,0 +1,130 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.PushWorker = void 0; + +var _deepcopy = _interopRequireDefault(require("deepcopy")); + +var _AdaptableController = _interopRequireDefault(require("../Controllers/AdaptableController")); + +var _Auth = require("../Auth"); + +var _Config = _interopRequireDefault(require("../Config")); + +var _PushAdapter = require("../Adapters/Push/PushAdapter"); + +var _rest = _interopRequireDefault(require("../rest")); + +var _StatusHandler = require("../StatusHandler"); + +var utils = _interopRequireWildcard(require("./utils")); + +var _ParseMessageQueue = require("../ParseMessageQueue"); + +var _PushQueue = require("./PushQueue"); + +var _logger = _interopRequireDefault(require("../logger")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// -disable-next +function groupByBadge(installations) { + return installations.reduce((map, installation) => { + const badge = installation.badge + ''; + map[badge] = map[badge] || []; + map[badge].push(installation); + return map; + }, {}); +} + +class PushWorker { + constructor(pushAdapter, subscriberConfig = {}) { + _AdaptableController.default.validateAdapter(pushAdapter, this, _PushAdapter.PushAdapter); + + this.adapter = pushAdapter; + this.channel = subscriberConfig.channel || _PushQueue.PushQueue.defaultPushChannel(); + this.subscriber = _ParseMessageQueue.ParseMessageQueue.createSubscriber(subscriberConfig); + + if (this.subscriber) { + const subscriber = this.subscriber; + subscriber.subscribe(this.channel); + subscriber.on('message', (channel, messageStr) => { + const workItem = JSON.parse(messageStr); + this.run(workItem); + }); + } + } + + run({ + body, + query, + pushStatus, + applicationId, + UTCOffset + }) { + const config = _Config.default.get(applicationId); + + const auth = (0, _Auth.master)(config); + const where = utils.applyDeviceTokenExists(query.where); + delete query.where; + pushStatus = (0, _StatusHandler.pushStatusHandler)(config, pushStatus.objectId); + return _rest.default.find(config, auth, '_Installation', where, query).then(({ + results + }) => { + if (results.length == 0) { + return; + } + + return this.sendToAdapter(body, results, pushStatus, config, UTCOffset); + }); + } + + sendToAdapter(body, installations, pushStatus, config, UTCOffset) { + // Check if we have locales in the push body + const locales = utils.getLocalesFromPush(body); + + if (locales.length > 0) { + // Get all tranformed bodies for each locale + const bodiesPerLocales = utils.bodiesPerLocales(body, locales); // Group installations on the specified locales (en, fr, default etc...) + + const grouppedInstallations = utils.groupByLocaleIdentifier(installations, locales); + const promises = Object.keys(grouppedInstallations).map(locale => { + const installations = grouppedInstallations[locale]; + const body = bodiesPerLocales[locale]; + return this.sendToAdapter(body, installations, pushStatus, config, UTCOffset); + }); + return Promise.all(promises); + } + + if (!utils.isPushIncrementing(body)) { + _logger.default.verbose(`Sending push to ${installations.length}`); + + return this.adapter.send(body, installations, pushStatus.objectId).then(results => { + return pushStatus.trackSent(results, UTCOffset).then(() => results); + }); + } // Collect the badges to reduce the # of calls + + + const badgeInstallationsMap = groupByBadge(installations); // Map the on the badges count and return the send result + + const promises = Object.keys(badgeInstallationsMap).map(badge => { + const payload = (0, _deepcopy.default)(body); + payload.data.badge = parseInt(badge); + const installations = badgeInstallationsMap[badge]; + return this.sendToAdapter(payload, installations, pushStatus, config, UTCOffset); + }); + return Promise.all(promises); + } + +} + +exports.PushWorker = PushWorker; +var _default = PushWorker; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9QdXNoL1B1c2hXb3JrZXIuanMiXSwibmFtZXMiOlsiZ3JvdXBCeUJhZGdlIiwiaW5zdGFsbGF0aW9ucyIsInJlZHVjZSIsIm1hcCIsImluc3RhbGxhdGlvbiIsImJhZGdlIiwicHVzaCIsIlB1c2hXb3JrZXIiLCJjb25zdHJ1Y3RvciIsInB1c2hBZGFwdGVyIiwic3Vic2NyaWJlckNvbmZpZyIsIkFkYXB0YWJsZUNvbnRyb2xsZXIiLCJ2YWxpZGF0ZUFkYXB0ZXIiLCJQdXNoQWRhcHRlciIsImFkYXB0ZXIiLCJjaGFubmVsIiwiUHVzaFF1ZXVlIiwiZGVmYXVsdFB1c2hDaGFubmVsIiwic3Vic2NyaWJlciIsIlBhcnNlTWVzc2FnZVF1ZXVlIiwiY3JlYXRlU3Vic2NyaWJlciIsInN1YnNjcmliZSIsIm9uIiwibWVzc2FnZVN0ciIsIndvcmtJdGVtIiwiSlNPTiIsInBhcnNlIiwicnVuIiwiYm9keSIsInF1ZXJ5IiwicHVzaFN0YXR1cyIsImFwcGxpY2F0aW9uSWQiLCJVVENPZmZzZXQiLCJjb25maWciLCJDb25maWciLCJnZXQiLCJhdXRoIiwid2hlcmUiLCJ1dGlscyIsImFwcGx5RGV2aWNlVG9rZW5FeGlzdHMiLCJvYmplY3RJZCIsInJlc3QiLCJmaW5kIiwidGhlbiIsInJlc3VsdHMiLCJsZW5ndGgiLCJzZW5kVG9BZGFwdGVyIiwibG9jYWxlcyIsImdldExvY2FsZXNGcm9tUHVzaCIsImJvZGllc1BlckxvY2FsZXMiLCJncm91cHBlZEluc3RhbGxhdGlvbnMiLCJncm91cEJ5TG9jYWxlSWRlbnRpZmllciIsInByb21pc2VzIiwiT2JqZWN0Iiwia2V5cyIsImxvY2FsZSIsIlByb21pc2UiLCJhbGwiLCJpc1B1c2hJbmNyZW1lbnRpbmciLCJsb2dnZXIiLCJ2ZXJib3NlIiwic2VuZCIsInRyYWNrU2VudCIsImJhZGdlSW5zdGFsbGF0aW9uc01hcCIsInBheWxvYWQiLCJkYXRhIiwicGFyc2VJbnQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7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O0FBR0QsS0F0QlcsQ0F3Qlo7OztBQUNBLFVBQU1tQixxQkFBcUIsR0FBRy9ELFlBQVksQ0FBQ0MsYUFBRCxDQUExQyxDQXpCWSxDQTJCWjs7QUFDQSxVQUFNbUQsUUFBUSxHQUFHQyxNQUFNLENBQUNDLElBQVAsQ0FBWVMscUJBQVosRUFBbUM1RCxHQUFuQyxDQUF1Q0UsS0FBSyxJQUFJO0FBQy9ELFlBQU0yRCxPQUFPLEdBQUcsdUJBQVNwQyxJQUFULENBQWhCO0FBQ0FvQyxNQUFBQSxPQUFPLENBQUNDLElBQVIsQ0FBYTVELEtBQWIsR0FBcUI2RCxRQUFRLENBQUM3RCxLQUFELENBQTdCO0FBQ0EsWUFBTUosYUFBYSxHQUFHOEQscUJBQXFCLENBQUMxRCxLQUFELENBQTNDO0FBQ0EsYUFBTyxLQUFLeUMsYUFBTCxDQUFtQmtCLE9BQW5CLEVBQTRCL0QsYUFBNUIsRUFBMkM2QixVQUEzQyxFQUF1REcsTUFBdkQsRUFBK0RELFNBQS9ELENBQVA7QUFDRCxLQUxnQixDQUFqQjtBQU1BLFdBQU93QixPQUFPLENBQUNDLEdBQVIsQ0FBWUwsUUFBWixDQUFQO0FBQ0Q7O0FBNUVxQjs7O2VBK0VUN0MsVSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCBkZWVwY29weSBmcm9tICdkZWVwY29weSc7XG5pbXBvcnQgQWRhcHRhYmxlQ29udHJvbGxlciBmcm9tICcuLi9Db250cm9sbGVycy9BZGFwdGFibGVDb250cm9sbGVyJztcbmltcG9ydCB7IG1hc3RlciB9IGZyb20gJy4uL0F1dGgnO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuLi9Db25maWcnO1xuaW1wb3J0IHsgUHVzaEFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9QdXNoL1B1c2hBZGFwdGVyJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IHsgcHVzaFN0YXR1c0hhbmRsZXIgfSBmcm9tICcuLi9TdGF0dXNIYW5kbGVyJztcbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHsgUGFyc2VNZXNzYWdlUXVldWUgfSBmcm9tICcuLi9QYXJzZU1lc3NhZ2VRdWV1ZSc7XG5pbXBvcnQgeyBQdXNoUXVldWUgfSBmcm9tICcuL1B1c2hRdWV1ZSc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5cbmZ1bmN0aW9uIGdyb3VwQnlCYWRnZShpbnN0YWxsYXRpb25zKSB7XG4gIHJldHVybiBpbnN0YWxsYXRpb25zLnJlZHVjZSgobWFwLCBpbnN0YWxsYXRpb24pID0+IHtcbiAgICBjb25zdCBiYWRnZSA9IGluc3RhbGxhdGlvbi5iYWRnZSArICcnO1xuICAgIG1hcFtiYWRnZV0gPSBtYXBbYmFkZ2VdIHx8IFtdO1xuICAgIG1hcFtiYWRnZV0ucHVzaChpbnN0YWxsYXRpb24pO1xuICAgIHJldHVybiBtYXA7XG4gIH0sIHt9KTtcbn1cblxuZXhwb3J0IGNsYXNzIFB1c2hXb3JrZXIge1xuICBzdWJzY3JpYmVyOiA/YW55O1xuICBhZGFwdGVyOiBhbnk7XG4gIGNoYW5uZWw6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihwdXNoQWRhcHRlcjogUHVzaEFkYXB0ZXIsIHN1YnNjcmliZXJDb25maWc6IGFueSA9IHt9KSB7XG4gICAgQWRhcHRhYmxlQ29udHJvbGxlci52YWxpZGF0ZUFkYXB0ZXIocHVzaEFkYXB0ZXIsIHRoaXMsIFB1c2hBZGFwdGVyKTtcbiAgICB0aGlzLmFkYXB0ZXIgPSBwdXNoQWRhcHRlcjtcblxuICAgIHRoaXMuY2hhbm5lbCA9IHN1YnNjcmliZXJDb25maWcuY2hhbm5lbCB8fCBQdXNoUXVldWUuZGVmYXVsdFB1c2hDaGFubmVsKCk7XG4gICAgdGhpcy5zdWJzY3JpYmVyID0gUGFyc2VNZXNzYWdlUXVldWUuY3JlYXRlU3Vic2NyaWJlcihzdWJzY3JpYmVyQ29uZmlnKTtcbiAgICBpZiAodGhpcy5zdWJzY3JpYmVyKSB7XG4gICAgICBjb25zdCBzdWJzY3JpYmVyID0gdGhpcy5zdWJzY3JpYmVyO1xuICAgICAgc3Vic2NyaWJlci5zdWJzY3JpYmUodGhpcy5jaGFubmVsKTtcbiAgICAgIHN1YnNjcmliZXIub24oJ21lc3NhZ2UnLCAoY2hhbm5lbCwgbWVzc2FnZVN0cikgPT4ge1xuICAgICAgICBjb25zdCB3b3JrSXRlbSA9IEpTT04ucGFyc2UobWVzc2FnZVN0cik7XG4gICAgICAgIHRoaXMucnVuKHdvcmtJdGVtKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHJ1bih7IGJvZHksIHF1ZXJ5LCBwdXNoU3RhdHVzLCBhcHBsaWNhdGlvbklkLCBVVENPZmZzZXQgfTogYW55KTogUHJvbWlzZTwqPiB7XG4gICAgY29uc3QgY29uZmlnID0gQ29uZmlnLmdldChhcHBsaWNhdGlvbklkKTtcbiAgICBjb25zdCBhdXRoID0gbWFzdGVyKGNvbmZpZyk7XG4gICAgY29uc3Qgd2hlcmUgPSB1dGlscy5hcHBseURldmljZVRva2VuRXhpc3RzKHF1ZXJ5LndoZXJlKTtcbiAgICBkZWxldGUgcXVlcnkud2hlcmU7XG4gICAgcHVzaFN0YXR1cyA9IHB1c2hTdGF0dXNIYW5kbGVyKGNvbmZpZywgcHVzaFN0YXR1cy5vYmplY3RJZCk7XG4gICAgcmV0dXJuIHJlc3QuZmluZChjb25maWcsIGF1dGgsICdfSW5zdGFsbGF0aW9uJywgd2hlcmUsIHF1ZXJ5KS50aGVuKCh7IHJlc3VsdHMgfSkgPT4ge1xuICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2VuZFRvQWRhcHRlcihib2R5LCByZXN1bHRzLCBwdXNoU3RhdHVzLCBjb25maWcsIFVUQ09mZnNldCk7XG4gICAgfSk7XG4gIH1cblxuICBzZW5kVG9BZGFwdGVyKFxuICAgIGJvZHk6IGFueSxcbiAgICBpbnN0YWxsYXRpb25zOiBhbnlbXSxcbiAgICBwdXNoU3RhdHVzOiBhbnksXG4gICAgY29uZmlnOiBDb25maWcsXG4gICAgVVRDT2Zmc2V0OiA/YW55XG4gICk6IFByb21pc2U8Kj4ge1xuICAgIC8vIENoZWNrIGlmIHdlIGhhdmUgbG9jYWxlcyBpbiB0aGUgcHVzaCBib2R5XG4gICAgY29uc3QgbG9jYWxlcyA9IHV0aWxzLmdldExvY2FsZXNGcm9tUHVzaChib2R5KTtcbiAgICBpZiAobG9jYWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBHZXQgYWxsIHRyYW5mb3JtZWQgYm9kaWVzIGZvciBlYWNoIGxvY2FsZVxuICAgICAgY29uc3QgYm9kaWVzUGVyTG9jYWxlcyA9IHV0aWxzLmJvZGllc1BlckxvY2FsZXMoYm9keSwgbG9jYWxlcyk7XG5cbiAgICAgIC8vIEdyb3VwIGluc3RhbGxhdGlvbnMgb24gdGhlIHNwZWNpZmllZCBsb2NhbGVzIChlbiwgZnIsIGRlZmF1bHQgZXRjLi4uKVxuICAgICAgY29uc3QgZ3JvdXBwZWRJbnN0YWxsYXRpb25zID0gdXRpbHMuZ3JvdXBCeUxvY2FsZUlkZW50aWZpZXIoaW5zdGFsbGF0aW9ucywgbG9jYWxlcyk7XG4gICAgICBjb25zdCBwcm9taXNlcyA9IE9iamVjdC5rZXlzKGdyb3VwcGVkSW5zdGFsbGF0aW9ucykubWFwKGxvY2FsZSA9PiB7XG4gICAgICAgIGNvbnN0IGluc3RhbGxhdGlvbnMgPSBncm91cHBlZEluc3RhbGxhdGlvbnNbbG9jYWxlXTtcbiAgICAgICAgY29uc3QgYm9keSA9IGJvZGllc1BlckxvY2FsZXNbbG9jYWxlXTtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VuZFRvQWRhcHRlcihib2R5LCBpbnN0YWxsYXRpb25zLCBwdXNoU3RhdHVzLCBjb25maWcsIFVUQ09mZnNldCk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgfVxuXG4gICAgaWYgKCF1dGlscy5pc1B1c2hJbmNyZW1lbnRpbmcoYm9keSkpIHtcbiAgICAgIGxvZ2dlci52ZXJib3NlKGBTZW5kaW5nIHB1c2ggdG8gJHtpbnN0YWxsYXRpb25zLmxlbmd0aH1gKTtcbiAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuc2VuZChib2R5LCBpbnN0YWxsYXRpb25zLCBwdXNoU3RhdHVzLm9iamVjdElkKS50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICByZXR1cm4gcHVzaFN0YXR1cy50cmFja1NlbnQocmVzdWx0cywgVVRDT2Zmc2V0KS50aGVuKCgpID0+IHJlc3VsdHMpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gQ29sbGVjdCB0aGUgYmFkZ2VzIHRvIHJlZHVjZSB0aGUgIyBvZiBjYWxsc1xuICAgIGNvbnN0IGJhZGdlSW5zdGFsbGF0aW9uc01hcCA9IGdyb3VwQnlCYWRnZShpbnN0YWxsYXRpb25zKTtcblxuICAgIC8vIE1hcCB0aGUgb24gdGhlIGJhZGdlcyBjb3VudCBhbmQgcmV0dXJuIHRoZSBzZW5kIHJlc3VsdFxuICAgIGNvbnN0IHByb21pc2VzID0gT2JqZWN0LmtleXMoYmFkZ2VJbnN0YWxsYXRpb25zTWFwKS5tYXAoYmFkZ2UgPT4ge1xuICAgICAgY29uc3QgcGF5bG9hZCA9IGRlZXBjb3B5KGJvZHkpO1xuICAgICAgcGF5bG9hZC5kYXRhLmJhZGdlID0gcGFyc2VJbnQoYmFkZ2UpO1xuICAgICAgY29uc3QgaW5zdGFsbGF0aW9ucyA9IGJhZGdlSW5zdGFsbGF0aW9uc01hcFtiYWRnZV07XG4gICAgICByZXR1cm4gdGhpcy5zZW5kVG9BZGFwdGVyKHBheWxvYWQsIGluc3RhbGxhdGlvbnMsIHB1c2hTdGF0dXMsIGNvbmZpZywgVVRDT2Zmc2V0KTtcbiAgICB9KTtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1c2hXb3JrZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Push/utils.js b/lib/Push/utils.js new file mode 100644 index 0000000000..0092d90ebd --- /dev/null +++ b/lib/Push/utils.js @@ -0,0 +1,159 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.isPushIncrementing = isPushIncrementing; +exports.getLocalesFromPush = getLocalesFromPush; +exports.transformPushBodyForLocale = transformPushBodyForLocale; +exports.stripLocalesFromBody = stripLocalesFromBody; +exports.bodiesPerLocales = bodiesPerLocales; +exports.groupByLocaleIdentifier = groupByLocaleIdentifier; +exports.validatePushType = validatePushType; +exports.applyDeviceTokenExists = applyDeviceTokenExists; + +var _node = _interopRequireDefault(require("parse/node")); + +var _deepcopy = _interopRequireDefault(require("deepcopy")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function isPushIncrementing(body) { + if (!body.data || !body.data.badge) { + return false; + } + + const badge = body.data.badge; + + if (typeof badge == 'string' && badge.toLowerCase() == 'increment') { + return true; + } + + return typeof badge == 'object' && typeof badge.__op == 'string' && badge.__op.toLowerCase() == 'increment' && Number(badge.amount); +} + +const localizableKeys = ['alert', 'title']; + +function getLocalesFromPush(body) { + const data = body.data; + + if (!data) { + return []; + } + + return [...new Set(Object.keys(data).reduce((memo, key) => { + localizableKeys.forEach(localizableKey => { + if (key.indexOf(`${localizableKey}-`) == 0) { + memo.push(key.slice(localizableKey.length + 1)); + } + }); + return memo; + }, []))]; +} + +function transformPushBodyForLocale(body, locale) { + const data = body.data; + + if (!data) { + return body; + } + + body = (0, _deepcopy.default)(body); + localizableKeys.forEach(key => { + const localeValue = body.data[`${key}-${locale}`]; + + if (localeValue) { + body.data[key] = localeValue; + } + }); + return stripLocalesFromBody(body); +} + +function stripLocalesFromBody(body) { + if (!body.data) { + return body; + } + + Object.keys(body.data).forEach(key => { + localizableKeys.forEach(localizableKey => { + if (key.indexOf(`${localizableKey}-`) == 0) { + delete body.data[key]; + } + }); + }); + return body; +} + +function bodiesPerLocales(body, locales = []) { + // Get all tranformed bodies for each locale + const result = locales.reduce((memo, locale) => { + memo[locale] = transformPushBodyForLocale(body, locale); + return memo; + }, {}); // Set the default locale, with the stripped body + + result.default = stripLocalesFromBody(body); + return result; +} + +function groupByLocaleIdentifier(installations, locales = []) { + return installations.reduce((map, installation) => { + let added = false; + locales.forEach(locale => { + if (added) { + return; + } + + if (installation.localeIdentifier && installation.localeIdentifier.indexOf(locale) === 0) { + added = true; + map[locale] = map[locale] || []; + map[locale].push(installation); + } + }); + + if (!added) { + map.default.push(installation); + } + + return map; + }, { + default: [] + }); +} +/** + * Check whether the deviceType parameter in qury condition is valid or not. + * @param {Object} where A query condition + * @param {Array} validPushTypes An array of valid push types(string) + */ + + +function validatePushType(where = {}, validPushTypes = []) { + var deviceTypeField = where.deviceType || {}; + var deviceTypes = []; + + if (typeof deviceTypeField === 'string') { + deviceTypes.push(deviceTypeField); + } else if (Array.isArray(deviceTypeField['$in'])) { + deviceTypes.concat(deviceTypeField['$in']); + } + + for (var i = 0; i < deviceTypes.length; i++) { + var deviceType = deviceTypes[i]; + + if (validPushTypes.indexOf(deviceType) < 0) { + throw new _node.default.Error(_node.default.Error.PUSH_MISCONFIGURED, deviceType + ' is not supported push type.'); + } + } +} + +function applyDeviceTokenExists(where) { + where = (0, _deepcopy.default)(where); + + if (!Object.prototype.hasOwnProperty.call(where, 'deviceToken')) { + where['deviceToken'] = { + $exists: true + }; + } + + return where; +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9QdXNoL3V0aWxzLmpzIl0sIm5hbWVzIjpbImlzUHVzaEluY3JlbWVudGluZyIsImJvZHkiLCJkYXRhIiwiYmFkZ2UiLCJ0b0xvd2VyQ2FzZSIsIl9fb3AiLCJOdW1iZXIiLCJhbW91bnQiLCJsb2NhbGl6YWJsZUtleXMiLCJnZXRMb2NhbGVzRnJvbVB1c2giLCJTZXQiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwibWVtbyIsImtleSIsImZvckVhY2giLCJsb2NhbGl6YWJsZUtleSIsImluZGV4T2YiLCJwdXNoIiwic2xpY2UiLCJsZW5ndGgiLCJ0cmFuc2Zvcm1QdXNoQm9keUZvckxvY2FsZSIsImxvY2FsZSIsImxvY2FsZVZhbHVlIiwic3RyaXBMb2NhbGVzRnJvbUJvZHkiLCJib2RpZXNQZXJMb2NhbGVzIiwibG9jYWxlcyIsInJlc3VsdCIsImRlZmF1bHQiLCJncm91cEJ5TG9jYWxlSWRlbnRpZmllciIsImluc3RhbGxhdGlvbnMiLCJtYXAiLCJpbnN0YWxsYXRpb24iLCJhZGRlZCIsImxvY2FsZUlkZW50aWZpZXIiLCJ2YWxpZGF0ZVB1c2hUeXBlIiwid2hlcmUiLCJ2YWxpZFB1c2hUeXBlcyIsImRldmljZVR5cGVGaWVsZCIsImRldmljZVR5cGUiLCJkZXZpY2VUeXBlcyIsIkFycmF5IiwiaXNBcnJheSIsImNvbmNhdCIsImkiLCJQYXJzZSIsIkVycm9yIiwiUFVTSF9NSVNDT05GSUdVUkVEIiwiYXBwbHlEZXZpY2VUb2tlbkV4aXN0cyIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIiRleGlzdHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7Ozs7QUFFTyxTQUFTQSxrQkFBVCxDQUE0QkMsSUFBNUIsRUFBa0M7QUFDdkMsTUFBSSxDQUFDQSxJQUFJLENBQUNDLElBQU4sSUFBYyxDQUFDRCxJQUFJLENBQUNDLElBQUwsQ0FBVUMsS0FBN0IsRUFBb0M7QUFDbEMsV0FBTyxLQUFQO0FB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LENBQUwsR0FBdUI7QUFBRWdCLE1BQUFBLE9BQU8sRUFBRTtBQUFYLEtBQXZCO0FBQ0Q7O0FBQ0QsU0FBT2hCLEtBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBkZWVwY29weSBmcm9tICdkZWVwY29weSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1B1c2hJbmNyZW1lbnRpbmcoYm9keSkge1xuICBpZiAoIWJvZHkuZGF0YSB8fCAhYm9keS5kYXRhLmJhZGdlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgYmFkZ2UgPSBib2R5LmRhdGEuYmFkZ2U7XG4gIGlmICh0eXBlb2YgYmFkZ2UgPT0gJ3N0cmluZycgJiYgYmFkZ2UudG9Mb3dlckNhc2UoKSA9PSAnaW5jcmVtZW50Jykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIChcbiAgICB0eXBlb2YgYmFkZ2UgPT0gJ29iamVjdCcgJiZcbiAgICB0eXBlb2YgYmFkZ2UuX19vcCA9PSAnc3RyaW5nJyAmJlxuICAgIGJhZGdlLl9fb3AudG9Mb3dlckNhc2UoKSA9PSAnaW5jcmVtZW50JyAmJlxuICAgIE51bWJlcihiYWRnZS5hbW91bnQpXG4gICk7XG59XG5cbmNvbnN0IGxvY2FsaXphYmxlS2V5cyA9IFsnYWxlcnQnLCAndGl0bGUnXTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldExvY2FsZXNGcm9tUHVzaChib2R5KSB7XG4gIGNvbnN0IGRhdGEgPSBib2R5LmRhdGE7XG4gIGlmICghZGF0YSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuICByZXR1cm4gW1xuICAgIC4uLm5ldyBTZXQoXG4gICAgICBPYmplY3Qua2V5cyhkYXRhKS5yZWR1Y2UoKG1lbW8sIGtleSkgPT4ge1xuICAgICAgICBsb2NhbGl6YWJsZUtleXMuZm9yRWFjaChsb2NhbGl6YWJsZUtleSA9PiB7XG4gICAgICAgICAgaWYgKGtleS5pbmRleE9mKGAke2xvY2FsaXphYmxlS2V5fS1gKSA9PSAwKSB7XG4gICAgICAgICAgICBtZW1vLnB1c2goa2V5LnNsaWNlKGxvY2FsaXphYmxlS2V5Lmxlbmd0aCArIDEpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbWVtbztcbiAgICAgIH0sIFtdKVxuICAgICksXG4gIF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2Zvcm1QdXNoQm9keUZvckxvY2FsZShib2R5LCBsb2NhbGUpIHtcbiAgY29uc3QgZGF0YSA9IGJvZHkuZGF0YTtcbiAgaWYgKCFkYXRhKSB7XG4gICAgcmV0dXJuIGJvZHk7XG4gIH1cbiAgYm9keSA9IGRlZXBjb3B5KGJvZHkpO1xuICBsb2NhbGl6YWJsZUtleXMuZm9yRWFjaChrZXkgPT4ge1xuICAgIGNvbnN0IGxvY2FsZVZhbHVlID0gYm9keS5kYXRhW2Ake2tleX0tJHtsb2NhbGV9YF07XG4gICAgaWYgKGxvY2FsZVZhbHVlKSB7XG4gICAgICBib2R5LmRhdGFba2V5XSA9IGxvY2FsZVZhbHVlO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBzdHJpcExvY2FsZXNGcm9tQm9keShib2R5KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHN0cmlwTG9jYWxlc0Zyb21Cb2R5KGJvZHkpIHtcbiAgaWYgKCFib2R5LmRhdGEpIHtcbiAgICByZXR1cm4gYm9keTtcbiAgfVxuICBPYmplY3Qua2V5cyhib2R5LmRhdGEpLmZvckVhY2goa2V5ID0+IHtcbiAgICBsb2NhbGl6YWJsZUtleXMuZm9yRWFjaChsb2NhbGl6YWJsZUtleSA9PiB7XG4gICAgICBpZiAoa2V5LmluZGV4T2YoYCR7bG9jYWxpemFibGVLZXl9LWApID09IDApIHtcbiAgICAgICAgZGVsZXRlIGJvZHkuZGF0YVtrZXldO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbiAgcmV0dXJuIGJvZHk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBib2RpZXNQZXJMb2NhbGVzKGJvZHksIGxvY2FsZXMgPSBbXSkge1xuICAvLyBHZXQgYWxsIHRyYW5mb3JtZWQgYm9kaWVzIGZvciBlYWNoIGxvY2FsZVxuICBjb25zdCByZXN1bHQgPSBsb2NhbGVzLnJlZHVjZSgobWVtbywgbG9jYWxlKSA9PiB7XG4gICAgbWVtb1tsb2NhbGVdID0gdHJhbnNmb3JtUHVzaEJvZHlGb3JMb2NhbGUoYm9keSwgbG9jYWxlKTtcbiAgICByZXR1cm4gbWVtbztcbiAgfSwge30pO1xuICAvLyBTZXQgdGhlIGRlZmF1bHQgbG9jYWxlLCB3aXRoIHRoZSBzdHJpcHBlZCBib2R5XG4gIHJlc3VsdC5kZWZhdWx0ID0gc3RyaXBMb2NhbGVzRnJvbUJvZHkoYm9keSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBncm91cEJ5TG9jYWxlSWRlbnRpZmllcihpbnN0YWxsYXRpb25zLCBsb2NhbGVzID0gW10pIHtcbiAgcmV0dXJuIGluc3RhbGxhdGlvbnMucmVkdWNlKFxuICAgIChtYXAsIGluc3RhbGxhdGlvbikgPT4ge1xuICAgICAgbGV0IGFkZGVkID0gZmFsc2U7XG4gICAgICBsb2NhbGVzLmZvckVhY2gobG9jYWxlID0+IHtcbiAgICAgICAgaWYgKGFkZGVkKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpbnN0YWxsYXRpb24ubG9jYWxlSWRlbnRpZmllciAmJiBpbnN0YWxsYXRpb24ubG9jYWxlSWRlbnRpZmllci5pbmRleE9mKGxvY2FsZSkgPT09IDApIHtcbiAgICAgICAgICBhZGRlZCA9IHRydWU7XG4gICAgICAgICAgbWFwW2xvY2FsZV0gPSBtYXBbbG9jYWxlXSB8fCBbXTtcbiAgICAgICAgICBtYXBbbG9jYWxlXS5wdXNoKGluc3RhbGxhdGlvbik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKCFhZGRlZCkge1xuICAgICAgICBtYXAuZGVmYXVsdC5wdXNoKGluc3RhbGxhdGlvbik7XG4gICAgICB9XG4gICAgICByZXR1cm4gbWFwO1xuICAgIH0sXG4gICAgeyBkZWZhdWx0OiBbXSB9XG4gICk7XG59XG5cbi8qKlxuICogQ2hlY2sgd2hldGhlciB0aGUgZGV2aWNlVHlwZSBwYXJhbWV0ZXIgaW4gcXVyeSBjb25kaXRpb24gaXMgdmFsaWQgb3Igbm90LlxuICogQHBhcmFtIHtPYmplY3R9IHdoZXJlIEEgcXVlcnkgY29uZGl0aW9uXG4gKiBAcGFyYW0ge0FycmF5fSB2YWxpZFB1c2hUeXBlcyBBbiBhcnJheSBvZiB2YWxpZCBwdXNoIHR5cGVzKHN0cmluZylcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlUHVzaFR5cGUod2hlcmUgPSB7fSwgdmFsaWRQdXNoVHlwZXMgPSBbXSkge1xuICB2YXIgZGV2aWNlVHlwZUZpZWxkID0gd2hlcmUuZGV2aWNlVHlwZSB8fCB7fTtcbiAgdmFyIGRldmljZVR5cGVzID0gW107XG4gIGlmICh0eXBlb2YgZGV2aWNlVHlwZUZpZWxkID09PSAnc3RyaW5nJykge1xuICAgIGRldmljZVR5cGVzLnB1c2goZGV2aWNlVHlwZUZpZWxkKTtcbiAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGRldmljZVR5cGVGaWVsZFsnJGluJ10pKSB7XG4gICAgZGV2aWNlVHlwZXMuY29uY2F0KGRldmljZVR5cGVGaWVsZFsnJGluJ10pO1xuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZGV2aWNlVHlwZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZGV2aWNlVHlwZSA9IGRldmljZVR5cGVzW2ldO1xuICAgIGlmICh2YWxpZFB1c2hUeXBlcy5pbmRleE9mKGRldmljZVR5cGUpIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5QVVNIX01JU0NPTkZJR1VSRUQsXG4gICAgICAgIGRldmljZVR5cGUgKyAnIGlzIG5vdCBzdXBwb3J0ZWQgcHVzaCB0eXBlLidcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhcHBseURldmljZVRva2VuRXhpc3RzKHdoZXJlKSB7XG4gIHdoZXJlID0gZGVlcGNvcHkod2hlcmUpO1xuICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh3aGVyZSwgJ2RldmljZVRva2VuJykpIHtcbiAgICB3aGVyZVsnZGV2aWNlVG9rZW4nXSA9IHsgJGV4aXN0czogdHJ1ZSB9O1xuICB9XG4gIHJldHVybiB3aGVyZTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/RestQuery.js b/lib/RestQuery.js new file mode 100644 index 0000000000..850595acc5 --- /dev/null +++ b/lib/RestQuery.js @@ -0,0 +1,979 @@ +"use strict"; + +// An object that encapsulates everything we need to run a 'find' +// operation, encoded in the REST API format. +var SchemaController = require('./Controllers/SchemaController'); + +var Parse = require('parse/node').Parse; + +const triggers = require('./triggers'); + +const { + continueWhile +} = require('parse/lib/node/promiseUtils'); + +const AlwaysSelectedKeys = ['objectId', 'createdAt', 'updatedAt', 'ACL']; // restOptions can include: +// skip +// limit +// order +// count +// include +// keys +// excludeKeys +// redirectClassNameForKey +// readPreference +// includeReadPreference +// subqueryReadPreference + +function RestQuery(config, auth, className, restWhere = {}, restOptions = {}, clientSDK, runAfterFind = true, context) { + this.config = config; + this.auth = auth; + this.className = className; + this.restWhere = restWhere; + this.restOptions = restOptions; + this.clientSDK = clientSDK; + this.runAfterFind = runAfterFind; + this.response = null; + this.findOptions = {}; + this.context = context || {}; + + if (!this.auth.isMaster) { + if (this.className == '_Session') { + if (!this.auth.user) { + throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); + } + + this.restWhere = { + $and: [this.restWhere, { + user: { + __type: 'Pointer', + className: '_User', + objectId: this.auth.user.id + } + }] + }; + } + } + + this.doCount = false; + this.includeAll = false; // The format for this.include is not the same as the format for the + // include option - it's the paths we should include, in order, + // stored as arrays, taking into account that we need to include foo + // before including foo.bar. Also it should dedupe. + // For example, passing an arg of include=foo.bar,foo.baz could lead to + // this.include = [['foo'], ['foo', 'baz'], ['foo', 'bar']] + + this.include = []; // If we have keys, we probably want to force some includes (n-1 level) + // See issue: https://github.com/parse-community/parse-server/issues/3185 + + if (Object.prototype.hasOwnProperty.call(restOptions, 'keys')) { + const keysForInclude = restOptions.keys.split(',').filter(key => { + // At least 2 components + return key.split('.').length > 1; + }).map(key => { + // Slice the last component (a.b.c -> a.b) + // Otherwise we'll include one level too much. + return key.slice(0, key.lastIndexOf('.')); + }).join(','); // Concat the possibly present include string with the one from the keys + // Dedup / sorting is handle in 'include' case. + + if (keysForInclude.length > 0) { + if (!restOptions.include || restOptions.include.length == 0) { + restOptions.include = keysForInclude; + } else { + restOptions.include += ',' + keysForInclude; + } + } + } + + for (var option in restOptions) { + switch (option) { + case 'keys': + { + const keys = restOptions.keys.split(',').filter(key => key.length > 0).concat(AlwaysSelectedKeys); + this.keys = Array.from(new Set(keys)); + break; + } + + case 'excludeKeys': + { + const exclude = restOptions.excludeKeys.split(',').filter(k => AlwaysSelectedKeys.indexOf(k) < 0); + this.excludeKeys = Array.from(new Set(exclude)); + break; + } + + case 'count': + this.doCount = true; + break; + + case 'includeAll': + this.includeAll = true; + break; + + case 'explain': + case 'hint': + case 'distinct': + case 'pipeline': + case 'skip': + case 'limit': + case 'readPreference': + this.findOptions[option] = restOptions[option]; + break; + + case 'order': + var fields = restOptions.order.split(','); + this.findOptions.sort = fields.reduce((sortMap, field) => { + field = field.trim(); + + if (field === '$score') { + sortMap.score = { + $meta: 'textScore' + }; + } else if (field[0] == '-') { + sortMap[field.slice(1)] = -1; + } else { + sortMap[field] = 1; + } + + return sortMap; + }, {}); + break; + + case 'include': + { + const paths = restOptions.include.split(','); + + if (paths.includes('*')) { + this.includeAll = true; + break; + } // Load the existing includes (from keys) + + + const pathSet = paths.reduce((memo, path) => { + // Split each paths on . (a.b.c -> [a,b,c]) + // reduce to create all paths + // ([a,b,c] -> {a: true, 'a.b': true, 'a.b.c': true}) + return path.split('.').reduce((memo, path, index, parts) => { + memo[parts.slice(0, index + 1).join('.')] = true; + return memo; + }, memo); + }, {}); + this.include = Object.keys(pathSet).map(s => { + return s.split('.'); + }).sort((a, b) => { + return a.length - b.length; // Sort by number of components + }); + break; + } + + case 'redirectClassNameForKey': + this.redirectKey = restOptions.redirectClassNameForKey; + this.redirectClassName = null; + break; + + case 'includeReadPreference': + case 'subqueryReadPreference': + break; + + default: + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad option: ' + option); + } + } +} // A convenient method to perform all the steps of processing a query +// in order. +// Returns a promise for the response - an object with optional keys +// 'results' and 'count'. +// TODO: consolidate the replaceX functions + + +RestQuery.prototype.execute = function (executeOptions) { + return Promise.resolve().then(() => { + return this.buildRestWhere(); + }).then(() => { + return this.handleIncludeAll(); + }).then(() => { + return this.handleExcludeKeys(); + }).then(() => { + return this.runFind(executeOptions); + }).then(() => { + return this.runCount(); + }).then(() => { + return this.handleInclude(); + }).then(() => { + return this.runAfterFindTrigger(); + }).then(() => { + return this.response; + }); +}; + +RestQuery.prototype.each = function (callback) { + const { + config, + auth, + className, + restWhere, + restOptions, + clientSDK + } = this; // if the limit is set, use it + + restOptions.limit = restOptions.limit || 100; + restOptions.order = 'objectId'; + let finished = false; + return continueWhile(() => { + return !finished; + }, async () => { + const query = new RestQuery(config, auth, className, restWhere, restOptions, clientSDK, this.runAfterFind, this.context); + const { + results + } = await query.execute(); + results.forEach(callback); + finished = results.length < restOptions.limit; + + if (!finished) { + restWhere.objectId = Object.assign({}, restWhere.objectId, { + $gt: results[results.length - 1].objectId + }); + } + }); +}; + +RestQuery.prototype.buildRestWhere = function () { + return Promise.resolve().then(() => { + return this.getUserAndRoleACL(); + }).then(() => { + return this.redirectClassNameForKey(); + }).then(() => { + return this.validateClientClassCreation(); + }).then(() => { + return this.replaceSelect(); + }).then(() => { + return this.replaceDontSelect(); + }).then(() => { + return this.replaceInQuery(); + }).then(() => { + return this.replaceNotInQuery(); + }).then(() => { + return this.replaceEquality(); + }); +}; // Uses the Auth object to get the list of roles, adds the user id + + +RestQuery.prototype.getUserAndRoleACL = function () { + if (this.auth.isMaster) { + return Promise.resolve(); + } + + this.findOptions.acl = ['*']; + + if (this.auth.user) { + return this.auth.getUserRoles().then(roles => { + this.findOptions.acl = this.findOptions.acl.concat(roles, [this.auth.user.id]); + return; + }); + } else { + return Promise.resolve(); + } +}; // Changes the className if redirectClassNameForKey is set. +// Returns a promise. + + +RestQuery.prototype.redirectClassNameForKey = function () { + if (!this.redirectKey) { + return Promise.resolve(); + } // We need to change the class name based on the schema + + + return this.config.database.redirectClassNameForKey(this.className, this.redirectKey).then(newClassName => { + this.className = newClassName; + this.redirectClassName = newClassName; + }); +}; // Validates this operation against the allowClientClassCreation config. + + +RestQuery.prototype.validateClientClassCreation = function () { + if (this.config.allowClientClassCreation === false && !this.auth.isMaster && SchemaController.systemClasses.indexOf(this.className) === -1) { + return this.config.database.loadSchema().then(schemaController => schemaController.hasClass(this.className)).then(hasClass => { + if (hasClass !== true) { + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'This user is not allowed to access ' + 'non-existent class: ' + this.className); + } + }); + } else { + return Promise.resolve(); + } +}; + +function transformInQuery(inQueryObject, className, results) { + var values = []; + + for (var result of results) { + values.push({ + __type: 'Pointer', + className: className, + objectId: result.objectId + }); + } + + delete inQueryObject['$inQuery']; + + if (Array.isArray(inQueryObject['$in'])) { + inQueryObject['$in'] = inQueryObject['$in'].concat(values); + } else { + inQueryObject['$in'] = values; + } +} // Replaces a $inQuery clause by running the subquery, if there is an +// $inQuery clause. +// The $inQuery clause turns into an $in with values that are just +// pointers to the objects returned in the subquery. + + +RestQuery.prototype.replaceInQuery = function () { + var inQueryObject = findObjectWithKey(this.restWhere, '$inQuery'); + + if (!inQueryObject) { + return; + } // The inQuery value must have precisely two keys - where and className + + + var inQueryValue = inQueryObject['$inQuery']; + + if (!inQueryValue.where || !inQueryValue.className) { + throw new Parse.Error(Parse.Error.INVALID_QUERY, 'improper usage of $inQuery'); + } + + const additionalOptions = { + redirectClassNameForKey: inQueryValue.redirectClassNameForKey + }; + + if (this.restOptions.subqueryReadPreference) { + additionalOptions.readPreference = this.restOptions.subqueryReadPreference; + additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference; + } else if (this.restOptions.readPreference) { + additionalOptions.readPreference = this.restOptions.readPreference; + } + + var subquery = new RestQuery(this.config, this.auth, inQueryValue.className, inQueryValue.where, additionalOptions); + return subquery.execute().then(response => { + transformInQuery(inQueryObject, subquery.className, response.results); // Recurse to repeat + + return this.replaceInQuery(); + }); +}; + +function transformNotInQuery(notInQueryObject, className, results) { + var values = []; + + for (var result of results) { + values.push({ + __type: 'Pointer', + className: className, + objectId: result.objectId + }); + } + + delete notInQueryObject['$notInQuery']; + + if (Array.isArray(notInQueryObject['$nin'])) { + notInQueryObject['$nin'] = notInQueryObject['$nin'].concat(values); + } else { + notInQueryObject['$nin'] = values; + } +} // Replaces a $notInQuery clause by running the subquery, if there is an +// $notInQuery clause. +// The $notInQuery clause turns into a $nin with values that are just +// pointers to the objects returned in the subquery. + + +RestQuery.prototype.replaceNotInQuery = function () { + var notInQueryObject = findObjectWithKey(this.restWhere, '$notInQuery'); + + if (!notInQueryObject) { + return; + } // The notInQuery value must have precisely two keys - where and className + + + var notInQueryValue = notInQueryObject['$notInQuery']; + + if (!notInQueryValue.where || !notInQueryValue.className) { + throw new Parse.Error(Parse.Error.INVALID_QUERY, 'improper usage of $notInQuery'); + } + + const additionalOptions = { + redirectClassNameForKey: notInQueryValue.redirectClassNameForKey + }; + + if (this.restOptions.subqueryReadPreference) { + additionalOptions.readPreference = this.restOptions.subqueryReadPreference; + additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference; + } else if (this.restOptions.readPreference) { + additionalOptions.readPreference = this.restOptions.readPreference; + } + + var subquery = new RestQuery(this.config, this.auth, notInQueryValue.className, notInQueryValue.where, additionalOptions); + return subquery.execute().then(response => { + transformNotInQuery(notInQueryObject, subquery.className, response.results); // Recurse to repeat + + return this.replaceNotInQuery(); + }); +}; // Used to get the deepest object from json using dot notation. + + +const getDeepestObjectFromKey = (json, key, idx, src) => { + if (key in json) { + return json[key]; + } + + src.splice(1); // Exit Early +}; + +const transformSelect = (selectObject, key, objects) => { + var values = []; + + for (var result of objects) { + values.push(key.split('.').reduce(getDeepestObjectFromKey, result)); + } + + delete selectObject['$select']; + + if (Array.isArray(selectObject['$in'])) { + selectObject['$in'] = selectObject['$in'].concat(values); + } else { + selectObject['$in'] = values; + } +}; // Replaces a $select clause by running the subquery, if there is a +// $select clause. +// The $select clause turns into an $in with values selected out of +// the subquery. +// Returns a possible-promise. + + +RestQuery.prototype.replaceSelect = function () { + var selectObject = findObjectWithKey(this.restWhere, '$select'); + + if (!selectObject) { + return; + } // The select value must have precisely two keys - query and key + + + var selectValue = selectObject['$select']; // iOS SDK don't send where if not set, let it pass + + if (!selectValue.query || !selectValue.key || typeof selectValue.query !== 'object' || !selectValue.query.className || Object.keys(selectValue).length !== 2) { + throw new Parse.Error(Parse.Error.INVALID_QUERY, 'improper usage of $select'); + } + + const additionalOptions = { + redirectClassNameForKey: selectValue.query.redirectClassNameForKey + }; + + if (this.restOptions.subqueryReadPreference) { + additionalOptions.readPreference = this.restOptions.subqueryReadPreference; + additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference; + } else if (this.restOptions.readPreference) { + additionalOptions.readPreference = this.restOptions.readPreference; + } + + var subquery = new RestQuery(this.config, this.auth, selectValue.query.className, selectValue.query.where, additionalOptions); + return subquery.execute().then(response => { + transformSelect(selectObject, selectValue.key, response.results); // Keep replacing $select clauses + + return this.replaceSelect(); + }); +}; + +const transformDontSelect = (dontSelectObject, key, objects) => { + var values = []; + + for (var result of objects) { + values.push(key.split('.').reduce(getDeepestObjectFromKey, result)); + } + + delete dontSelectObject['$dontSelect']; + + if (Array.isArray(dontSelectObject['$nin'])) { + dontSelectObject['$nin'] = dontSelectObject['$nin'].concat(values); + } else { + dontSelectObject['$nin'] = values; + } +}; // Replaces a $dontSelect clause by running the subquery, if there is a +// $dontSelect clause. +// The $dontSelect clause turns into an $nin with values selected out of +// the subquery. +// Returns a possible-promise. + + +RestQuery.prototype.replaceDontSelect = function () { + var dontSelectObject = findObjectWithKey(this.restWhere, '$dontSelect'); + + if (!dontSelectObject) { + return; + } // The dontSelect value must have precisely two keys - query and key + + + var dontSelectValue = dontSelectObject['$dontSelect']; + + if (!dontSelectValue.query || !dontSelectValue.key || typeof dontSelectValue.query !== 'object' || !dontSelectValue.query.className || Object.keys(dontSelectValue).length !== 2) { + throw new Parse.Error(Parse.Error.INVALID_QUERY, 'improper usage of $dontSelect'); + } + + const additionalOptions = { + redirectClassNameForKey: dontSelectValue.query.redirectClassNameForKey + }; + + if (this.restOptions.subqueryReadPreference) { + additionalOptions.readPreference = this.restOptions.subqueryReadPreference; + additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference; + } else if (this.restOptions.readPreference) { + additionalOptions.readPreference = this.restOptions.readPreference; + } + + var subquery = new RestQuery(this.config, this.auth, dontSelectValue.query.className, dontSelectValue.query.where, additionalOptions); + return subquery.execute().then(response => { + transformDontSelect(dontSelectObject, dontSelectValue.key, response.results); // Keep replacing $dontSelect clauses + + return this.replaceDontSelect(); + }); +}; + +const cleanResultAuthData = function (result) { + delete result.password; + + if (result.authData) { + Object.keys(result.authData).forEach(provider => { + if (result.authData[provider] === null) { + delete result.authData[provider]; + } + }); + + if (Object.keys(result.authData).length == 0) { + delete result.authData; + } + } +}; + +const replaceEqualityConstraint = constraint => { + if (typeof constraint !== 'object') { + return constraint; + } + + const equalToObject = {}; + let hasDirectConstraint = false; + let hasOperatorConstraint = false; + + for (const key in constraint) { + if (key.indexOf('$') !== 0) { + hasDirectConstraint = true; + equalToObject[key] = constraint[key]; + } else { + hasOperatorConstraint = true; + } + } + + if (hasDirectConstraint && hasOperatorConstraint) { + constraint['$eq'] = equalToObject; + Object.keys(equalToObject).forEach(key => { + delete constraint[key]; + }); + } + + return constraint; +}; + +RestQuery.prototype.replaceEquality = function () { + if (typeof this.restWhere !== 'object') { + return; + } + + for (const key in this.restWhere) { + this.restWhere[key] = replaceEqualityConstraint(this.restWhere[key]); + } +}; // Returns a promise for whether it was successful. +// Populates this.response with an object that only has 'results'. + + +RestQuery.prototype.runFind = function (options = {}) { + if (this.findOptions.limit === 0) { + this.response = { + results: [] + }; + return Promise.resolve(); + } + + const findOptions = Object.assign({}, this.findOptions); + + if (this.keys) { + findOptions.keys = this.keys.map(key => { + return key.split('.')[0]; + }); + } + + if (options.op) { + findOptions.op = options.op; + } + + return this.config.database.find(this.className, this.restWhere, findOptions, this.auth).then(results => { + if (this.className === '_User' && findOptions.explain !== true) { + for (var result of results) { + cleanResultAuthData(result); + } + } + + this.config.filesController.expandFilesInObject(this.config, results); + + if (this.redirectClassName) { + for (var r of results) { + r.className = this.redirectClassName; + } + } + + this.response = { + results: results + }; + }); +}; // Returns a promise for whether it was successful. +// Populates this.response.count with the count + + +RestQuery.prototype.runCount = function () { + if (!this.doCount) { + return; + } + + this.findOptions.count = true; + delete this.findOptions.skip; + delete this.findOptions.limit; + return this.config.database.find(this.className, this.restWhere, this.findOptions).then(c => { + this.response.count = c; + }); +}; // Augments this.response with all pointers on an object + + +RestQuery.prototype.handleIncludeAll = function () { + if (!this.includeAll) { + return; + } + + return this.config.database.loadSchema().then(schemaController => schemaController.getOneSchema(this.className)).then(schema => { + const includeFields = []; + const keyFields = []; + + for (const field in schema.fields) { + if (schema.fields[field].type && schema.fields[field].type === 'Pointer' || schema.fields[field].type && schema.fields[field].type === 'Array') { + includeFields.push([field]); + keyFields.push(field); + } + } // Add fields to include, keys, remove dups + + + this.include = [...new Set([...this.include, ...includeFields])]; // if this.keys not set, then all keys are already included + + if (this.keys) { + this.keys = [...new Set([...this.keys, ...keyFields])]; + } + }); +}; // Updates property `this.keys` to contain all keys but the ones unselected. + + +RestQuery.prototype.handleExcludeKeys = function () { + if (!this.excludeKeys) { + return; + } + + if (this.keys) { + this.keys = this.keys.filter(k => !this.excludeKeys.includes(k)); + return; + } + + return this.config.database.loadSchema().then(schemaController => schemaController.getOneSchema(this.className)).then(schema => { + const fields = Object.keys(schema.fields); + this.keys = fields.filter(k => !this.excludeKeys.includes(k)); + }); +}; // Augments this.response with data at the paths provided in this.include. + + +RestQuery.prototype.handleInclude = function () { + if (this.include.length == 0) { + return; + } + + var pathResponse = includePath(this.config, this.auth, this.response, this.include[0], this.restOptions); + + if (pathResponse.then) { + return pathResponse.then(newResponse => { + this.response = newResponse; + this.include = this.include.slice(1); + return this.handleInclude(); + }); + } else if (this.include.length > 0) { + this.include = this.include.slice(1); + return this.handleInclude(); + } + + return pathResponse; +}; //Returns a promise of a processed set of results + + +RestQuery.prototype.runAfterFindTrigger = function () { + if (!this.response) { + return; + } + + if (!this.runAfterFind) { + return; + } // Avoid doing any setup for triggers if there is no 'afterFind' trigger for this class. + + + const hasAfterFindHook = triggers.triggerExists(this.className, triggers.Types.afterFind, this.config.applicationId); + + if (!hasAfterFindHook) { + return Promise.resolve(); + } // Skip Aggregate and Distinct Queries + + + if (this.findOptions.pipeline || this.findOptions.distinct) { + return Promise.resolve(); + } + + const json = Object.assign({}, this.restOptions); + json.where = this.restWhere; + const parseQuery = new Parse.Query(this.className); + parseQuery.withJSON(json); // Run afterFind trigger and set the new results + + return triggers.maybeRunAfterFindTrigger(triggers.Types.afterFind, this.auth, this.className, this.response.results, this.config, parseQuery, this.context).then(results => { + // Ensure we properly set the className back + if (this.redirectClassName) { + this.response.results = results.map(object => { + if (object instanceof Parse.Object) { + object = object.toJSON(); + } + + object.className = this.redirectClassName; + return object; + }); + } else { + this.response.results = results; + } + }); +}; // Adds included values to the response. +// Path is a list of field names. +// Returns a promise for an augmented response. + + +function includePath(config, auth, response, path, restOptions = {}) { + var pointers = findPointers(response.results, path); + + if (pointers.length == 0) { + return response; + } + + const pointersHash = {}; + + for (var pointer of pointers) { + if (!pointer) { + continue; + } + + const className = pointer.className; // only include the good pointers + + if (className) { + pointersHash[className] = pointersHash[className] || new Set(); + pointersHash[className].add(pointer.objectId); + } + } + + const includeRestOptions = {}; + + if (restOptions.keys) { + const keys = new Set(restOptions.keys.split(',')); + const keySet = Array.from(keys).reduce((set, key) => { + const keyPath = key.split('.'); + let i = 0; + + for (i; i < path.length; i++) { + if (path[i] != keyPath[i]) { + return set; + } + } + + if (i < keyPath.length) { + set.add(keyPath[i]); + } + + return set; + }, new Set()); + + if (keySet.size > 0) { + includeRestOptions.keys = Array.from(keySet).join(','); + } + } + + if (restOptions.includeReadPreference) { + includeRestOptions.readPreference = restOptions.includeReadPreference; + includeRestOptions.includeReadPreference = restOptions.includeReadPreference; + } else if (restOptions.readPreference) { + includeRestOptions.readPreference = restOptions.readPreference; + } + + const queryPromises = Object.keys(pointersHash).map(className => { + const objectIds = Array.from(pointersHash[className]); + let where; + + if (objectIds.length === 1) { + where = { + objectId: objectIds[0] + }; + } else { + where = { + objectId: { + $in: objectIds + } + }; + } + + var query = new RestQuery(config, auth, className, where, includeRestOptions); + return query.execute({ + op: 'get' + }).then(results => { + results.className = className; + return Promise.resolve(results); + }); + }); // Get the objects for all these object ids + + return Promise.all(queryPromises).then(responses => { + var replace = responses.reduce((replace, includeResponse) => { + for (var obj of includeResponse.results) { + obj.__type = 'Object'; + obj.className = includeResponse.className; + + if (obj.className == '_User' && !auth.isMaster) { + delete obj.sessionToken; + delete obj.authData; + } + + replace[obj.objectId] = obj; + } + + return replace; + }, {}); + var resp = { + results: replacePointers(response.results, path, replace) + }; + + if (response.count) { + resp.count = response.count; + } + + return resp; + }); +} // Object may be a list of REST-format object to find pointers in, or +// it may be a single object. +// If the path yields things that aren't pointers, this throws an error. +// Path is a list of fields to search into. +// Returns a list of pointers in REST format. + + +function findPointers(object, path) { + if (object instanceof Array) { + var answer = []; + + for (var x of object) { + answer = answer.concat(findPointers(x, path)); + } + + return answer; + } + + if (typeof object !== 'object' || !object) { + return []; + } + + if (path.length == 0) { + if (object === null || object.__type == 'Pointer') { + return [object]; + } + + return []; + } + + var subobject = object[path[0]]; + + if (!subobject) { + return []; + } + + return findPointers(subobject, path.slice(1)); +} // Object may be a list of REST-format objects to replace pointers +// in, or it may be a single object. +// Path is a list of fields to search into. +// replace is a map from object id -> object. +// Returns something analogous to object, but with the appropriate +// pointers inflated. + + +function replacePointers(object, path, replace) { + if (object instanceof Array) { + return object.map(obj => replacePointers(obj, path, replace)).filter(obj => typeof obj !== 'undefined'); + } + + if (typeof object !== 'object' || !object) { + return object; + } + + if (path.length === 0) { + if (object && object.__type === 'Pointer') { + return replace[object.objectId]; + } + + return object; + } + + var subobject = object[path[0]]; + + if (!subobject) { + return object; + } + + var newsub = replacePointers(subobject, path.slice(1), replace); + var answer = {}; + + for (var key in object) { + if (key == path[0]) { + answer[key] = newsub; + } else { + answer[key] = object[key]; + } + } + + return answer; +} // Finds a subobject that has the given key, if there is one. +// Returns undefined otherwise. + + +function findObjectWithKey(root, key) { + if (typeof root !== 'object') { + return; + } + + if (root instanceof Array) { + for (var item of root) { + const answer = findObjectWithKey(item, key); + + if (answer) { + return answer; + } + } + } + + if (root && root[key]) { + return root; + } + + for (var subkey in root) { + const answer = findObjectWithKey(root[subkey], key); + + if (answer) { + return answer; + } + } +} + +module.exports = RestQuery; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9SZXN0UXVlcnkuanMiXSwibmFtZXMiOlsiU2NoZW1hQ29udHJvbGxlciIsInJlcXVpcmUiLCJQYXJzZSIsInRyaWdnZXJzIiwiY29udGludWVXaGlsZSIsIkFsd2F5c1NlbGVjdGVkS2V5cyIsIlJlc3RRdWVyeSIsImNvbmZpZyIsImF1dGgiLCJjbGFzc05hbWUiLCJyZXN0V2hlcmUiLCJyZXN0T3B0aW9ucyIsImNsaWVudFNESyIsInJ1bkFmdGVyRmluZCIsImNvbnRleHQiLCJyZXNwb25zZSIsImZpbmRPcHRpb25zIiwiaXNNYXN0ZXIiLCJ1c2VyIiwiRXJyb3IiLCJJTlZBTElEX1NFU1NJT05fVE9LRU4iLCIkYW5kIiwiX190eXBlIiwib2JqZWN0SWQiLCJpZCIsImRvQ291bnQiLCJpbmNsdWRlQWxsIiwiaW5jbHVkZSIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImtleXNGb3JJbmNsdWRlIiwia2V5cyIsInNwbGl0IiwiZmlsdGVyIiwia2V5IiwibGVuZ3RoIiwibWFwIiwic2xpY2UiLCJsYXN0SW5kZXhPZiIsImpvaW4iLCJvcHRpb24iLCJjb25jYXQiLCJBcnJheSIsImZyb20iLCJTZXQiLCJleGNsdWRlIiwiZXhjbHVkZUtleXMiLCJrIiwiaW5kZXhPZiIsImZpZWxkcyIsIm9yZGVyIiwic29ydCIsInJlZHVjZSIsInNvcnRNYXAiLCJmaWVsZCIsInRyaW0iLCJzY29yZSIsIiRtZXRhIiwicGF0aHMiLCJpbmNsdWRlcyIsInBhdGhTZXQiLCJtZW1vIiwicGF0aCIsImluZGV4IiwicGFydHMiLCJzIiwiYSIsImIiLCJyZWRpcmVjdEtleSIsInJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5IiwicmVkaXJlY3RDbGFzc05hbWUiLCJJTlZBTElEX0pTT04iLCJleGVjdXRlIiwiZXhlY3V0ZU9wdGlvbnMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInRoZW4iLCJidWlsZFJlc3RXaGVyZSIsImhhbmRsZUluY2x1ZGVBbGwiLCJoYW5kbGVFeGNsdWRlS2V5cyIsInJ1bkZpbmQiLCJydW5Db3VudCIsImhhbmRsZUluY2x1ZGUiLCJydW5BZnRlckZpbmRUcmlnZ2VyIiwiZWFjaCIsImNhbGxiYWNrIiwibGltaXQiLCJmaW5pc2hlZCIsInF1ZXJ5IiwicmVzdWx0cyIsImZvckVhY2giLCJhc3NpZ24iLCIkZ3QiLCJnZXRVc2VyQW5kUm9sZUFDTCIsInZhbGlkYXRlQ2xpZW50Q2xhc3NDcmVhdGlvbiIsInJlcGxhY2VTZWxlY3QiLCJyZXBsYWNlRG9udFNlbGVjdCIsInJlcGxhY2VJblF1ZXJ5IiwicmVwbGFjZU5vdEluUXVlcnkiLCJyZXBsYWNlRXF1YWxpdHkiLCJhY2wiLCJnZXRVc2VyUm9sZXMiLCJyb2xlcyIsImRhdGFiYXNlIiwibmV3Q2xhc3NOYW1lIiwiYWxsb3dDbGllbnRDbGFzc0NyZWF0aW9uIiwic3lzdGVtQ2xhc3NlcyIsImxvYWRTY2hlbWEiLCJzY2hlbWFDb250cm9sbGVyIiwiaGFzQ2xhc3MiLCJPUEVSQVRJT05fRk9SQklEREVOIiwidHJhbnNmb3JtSW5RdWVyeSIsImluUXVlcnlPYmplY3QiLCJ2YWx1ZXMiLCJyZXN1bHQiLCJwdXNoIiwiaXNBcnJheSIsImZpbmRPYmplY3RXaXRoS2V5IiwiaW5RdWVyeVZhbHVlIiwid2hlcmUiLCJJTlZBTElEX1FVRVJZIiwiYWRkaXRpb25hbE9wdGlvbnMiLCJzdWJxdWVyeVJlYWRQcmVmZXJlbmNlIiwicmVhZFByZWZlcmVuY2UiLCJzdWJxdWVyeSIsInRyYW5zZm9ybU5vdEluUXVlcnkiLCJub3RJblF1ZXJ5T2JqZWN0Iiwibm90SW5RdWVyeVZhbHVlIiwiZ2V0RGVlcGVzdE9iamVjdEZyb21LZXkiLCJqc29uIiwiaWR4Iiwic3JjIiwic3BsaWNlIiwidHJhbnNmb3JtU2VsZWN0Iiwic2VsZWN0T2JqZWN0Iiwib2JqZWN0cyIsInNlbGVjdFZhbHVlIiwidHJhbnNmb3JtRG9udFNlbGVjdCIsImRvbnRTZWxlY3RPYmplY3QiLCJkb250U2VsZWN0VmFsdWUiLCJjbGVhblJlc3VsdEF1dGhEYXRhIiwicGFzc3dvcmQiLCJhdXRoRGF0YSIsInByb3ZpZGVyIiwicmVwbGFjZUVxdWFsaXR5Q29uc3RyYWludCIsImNvbnN0cmFpbnQiLCJlcXVhbFRvT2JqZWN0IiwiaGFzRGlyZWN0Q29uc3RyYWludCIsImhhc09wZXJhdG9yQ29uc3RyYWludCIsIm9wdGlvbnMiLCJvcCIsImZpbmQiLCJleHBsYWluIiwiZmlsZXNDb250cm9sbGVyIiwiZXhwYW5kRmlsZXNJbk9iamVjdCIsInIiLCJjb3VudCIsInNraXAiLCJjIiwiZ2V0T25lU2NoZW1hIiwic2NoZW1hIiwiaW5jbHVkZUZpZWxkcyIsImtleUZpZWxkcyIsInR5cGUiLCJwYXRoUmVzcG9uc2UiLCJpbmNsdWRlUGF0aCIsIm5ld1Jlc3BvbnNlIiwiaGFzQWZ0ZXJGaW5kSG9vayIsInRyaWdnZXJFeGlzdHMiLCJUeXBlcyIsImFmdGVyRmluZCIsImFwcGxpY2F0aW9uSWQiLCJwaXBlbGluZSIsImRpc3RpbmN0IiwicGFyc2VRdWVyeSIsIlF1ZXJ5Iiwid2l0aEpTT04iLCJtYXliZVJ1bkFmdGVyRmluZFRyaWdnZXIiLCJvYmplY3QiLCJ0b0pTT04iLCJwb2ludGVycyIsImZpbmRQb2ludGVycyIsInBvaW50ZXJzSGFzaCIsInBvaW50ZXIiLCJhZGQiLCJpbmNsdWRlUmVzdE9wdGlvbnMiLCJrZXlTZXQiLCJzZXQiLCJrZXlQYXRoIiwiaSIsInNpemUiLCJpbmNsdWRlUmVhZFByZWZlcmVuY2UiLCJxdWVyeVByb21pc2VzIiwib2JqZWN0SWRzIiwiJGluIiwiYWxsIiwicmVzcG9uc2VzIiwicmVwbGFjZSIsImluY2x1ZGVSZXNwb25zZSIsIm9iaiIsInNlc3Npb25Ub2tlbiIsInJlc3AiLCJyZXBsYWNlUG9pbnRlcnMiLCJhbnN3ZXIiLCJ4Iiwic3Vib2JqZWN0IiwibmV3c3ViIiwicm9vdCIsIml0ZW0iLCJzdWJrZXkiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFFQSxJQUFJ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LE1BQU0sQ0FBQ3pLLEdBQUQsQ0FBTixHQUFjNEssTUFBZDtBQUNELEtBRkQsTUFFTztBQUNMSCxNQUFBQSxNQUFNLENBQUN6SyxHQUFELENBQU4sR0FBY2dKLE1BQU0sQ0FBQ2hKLEdBQUQsQ0FBcEI7QUFDRDtBQUNGOztBQUNELFNBQU95SyxNQUFQO0FBQ0QsQyxDQUVEO0FBQ0E7OztBQUNBLFNBQVN0RixpQkFBVCxDQUEyQjBGLElBQTNCLEVBQWlDN0ssR0FBakMsRUFBc0M7QUFDcEMsTUFBSSxPQUFPNkssSUFBUCxLQUFnQixRQUFwQixFQUE4QjtBQUM1QjtBQUNEOztBQUNELE1BQUlBLElBQUksWUFBWXJLLEtBQXBCLEVBQTJCO0FBQ3pCLFNBQUssSUFBSXNLLElBQVQsSUFBaUJELElBQWpCLEVBQXVCO0FBQ3JCLFlBQU1KLE1BQU0sR0FBR3RGLGlCQUFpQixDQUFDMkYsSUFBRCxFQUFPOUssR0FBUCxDQUFoQzs7QUFDQSxVQUFJeUssTUFBSixFQUFZO0FBQ1YsZUFBT0EsTUFBUDtBQUNEO0FBQ0Y7QUFDRjs7QUFDRCxNQUFJSSxJQUFJLElBQUlBLElBQUksQ0FBQzdLLEdBQUQsQ0FBaEIsRUFBdUI7QUFDckIsV0FBTzZLLElBQVA7QUFDRDs7QUFDRCxPQUFLLElBQUlFLE1BQVQsSUFBbUJGLElBQW5CLEVBQXlCO0FBQ3ZCLFVBQU1KLE1BQU0sR0FBR3RGLGlCQUFpQixDQUFDMEYsSUFBSSxDQUFDRSxNQUFELENBQUwsRUFBZS9LLEdBQWYsQ0FBaEM7O0FBQ0EsUUFBSXlLLE1BQUosRUFBWTtBQUNWLGFBQU9BLE1BQVA7QUFDRDtBQUNGO0FBQ0Y7O0FBRURPLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQi9NLFNBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQW4gb2JqZWN0IHRoYXQgZW5jYXBzdWxhdGVzIGV2ZXJ5dGhpbmcgd2UgbmVlZCB0byBydW4gYSAnZmluZCdcbi8vIG9wZXJhdGlvbiwgZW5jb2RlZCBpbiB0aGUgUkVTVCBBUEkgZm9ybWF0LlxuXG52YXIgU2NoZW1hQ29udHJvbGxlciA9IHJlcXVpcmUoJy4vQ29udHJvbGxlcnMvU2NoZW1hQ29udHJvbGxlcicpO1xudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuY29uc3QgdHJpZ2dlcnMgPSByZXF1aXJlKCcuL3RyaWdnZXJzJyk7XG5jb25zdCB7IGNvbnRpbnVlV2hpbGUgfSA9IHJlcXVpcmUoJ3BhcnNlL2xpYi9ub2RlL3Byb21pc2VVdGlscycpO1xuY29uc3QgQWx3YXlzU2VsZWN0ZWRLZXlzID0gWydvYmplY3RJZCcsICdjcmVhdGVkQXQnLCAndXBkYXRlZEF0JywgJ0FDTCddO1xuLy8gcmVzdE9wdGlvbnMgY2FuIGluY2x1ZGU6XG4vLyAgIHNraXBcbi8vICAgbGltaXRcbi8vICAgb3JkZXJcbi8vICAgY291bnRcbi8vICAgaW5jbHVkZVxuLy8gICBrZXlzXG4vLyAgIGV4Y2x1ZGVLZXlzXG4vLyAgIHJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5XG4vLyAgIHJlYWRQcmVmZXJlbmNlXG4vLyAgIGluY2x1ZGVSZWFkUHJlZmVyZW5jZVxuLy8gICBzdWJxdWVyeVJlYWRQcmVmZXJlbmNlXG5mdW5jdGlvbiBSZXN0UXVlcnkoXG4gIGNvbmZpZyxcbiAgYXV0aCxcbiAgY2xhc3NOYW1lLFxuICByZXN0V2hlcmUgPSB7fSxcbiAgcmVzdE9wdGlvbnMgPSB7fSxcbiAgY2xpZW50U0RLLFxuICBydW5BZnRlckZpbmQgPSB0cnVlLFxuICBjb250ZXh0XG4pIHtcbiAgdGhpcy5jb25maWcgPSBjb25maWc7XG4gIHRoaXMuYXV0aCA9IGF1dGg7XG4gIHRoaXMuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xuICB0aGlzLnJlc3RXaGVyZSA9IHJlc3RXaGVyZTtcbiAgdGhpcy5yZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zO1xuICB0aGlzLmNsaWVudFNESyA9IGNsaWVudFNESztcbiAgdGhpcy5ydW5BZnRlckZpbmQgPSBydW5BZnRlckZpbmQ7XG4gIHRoaXMucmVzcG9uc2UgPSBudWxsO1xuICB0aGlzLmZpbmRPcHRpb25zID0ge307XG4gIHRoaXMuY29udGV4dCA9IGNvbnRleHQgfHwge307XG5cbiAgaWYgKCF0aGlzLmF1dGguaXNNYXN0ZXIpIHtcbiAgICBpZiAodGhpcy5jbGFzc05hbWUgPT0gJ19TZXNzaW9uJykge1xuICAgICAgaWYgKCF0aGlzLmF1dGgudXNlcikge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOLCAnSW52YWxpZCBzZXNzaW9uIHRva2VuJyk7XG4gICAgICB9XG4gICAgICB0aGlzLnJlc3RXaGVyZSA9IHtcbiAgICAgICAgJGFuZDogW1xuICAgICAgICAgIHRoaXMucmVzdFdoZXJlLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVzZXI6IHtcbiAgICAgICAgICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICAgICAgICAgIGNsYXNzTmFtZTogJ19Vc2VyJyxcbiAgICAgICAgICAgICAgb2JqZWN0SWQ6IHRoaXMuYXV0aC51c2VyLmlkLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICB0aGlzLmRvQ291bnQgPSBmYWxzZTtcbiAgdGhpcy5pbmNsdWRlQWxsID0gZmFsc2U7XG5cbiAgLy8gVGhlIGZvcm1hdCBmb3IgdGhpcy5pbmNsdWRlIGlzIG5vdCB0aGUgc2FtZSBhcyB0aGUgZm9ybWF0IGZvciB0aGVcbiAgLy8gaW5jbHVkZSBvcHRpb24gLSBpdCdzIHRoZSBwYXRocyB3ZSBzaG91bGQgaW5jbHVkZSwgaW4gb3JkZXIsXG4gIC8vIHN0b3JlZCBhcyBhcnJheXMsIHRha2luZyBpbnRvIGFjY291bnQgdGhhdCB3ZSBuZWVkIHRvIGluY2x1ZGUgZm9vXG4gIC8vIGJlZm9yZSBpbmNsdWRpbmcgZm9vLmJhci4gQWxzbyBpdCBzaG91bGQgZGVkdXBlLlxuICAvLyBGb3IgZXhhbXBsZSwgcGFzc2luZyBhbiBhcmcgb2YgaW5jbHVkZT1mb28uYmFyLGZvby5iYXogY291bGQgbGVhZCB0b1xuICAvLyB0aGlzLmluY2x1ZGUgPSBbWydmb28nXSwgWydmb28nLCAnYmF6J10sIFsnZm9vJywgJ2JhciddXVxuICB0aGlzLmluY2x1ZGUgPSBbXTtcblxuICAvLyBJZiB3ZSBoYXZlIGtleXMsIHdlIHByb2JhYmx5IHdhbnQgdG8gZm9yY2Ugc29tZSBpbmNsdWRlcyAobi0xIGxldmVsKVxuICAvLyBTZWUgaXNzdWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9wYXJzZS1jb21tdW5pdHkvcGFyc2Utc2VydmVyL2lzc3Vlcy8zMTg1XG4gIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocmVzdE9wdGlvbnMsICdrZXlzJykpIHtcbiAgICBjb25zdCBrZXlzRm9ySW5jbHVkZSA9IHJlc3RPcHRpb25zLmtleXNcbiAgICAgIC5zcGxpdCgnLCcpXG4gICAgICAuZmlsdGVyKGtleSA9PiB7XG4gICAgICAgIC8vIEF0IGxlYXN0IDIgY29tcG9uZW50c1xuICAgICAgICByZXR1cm4ga2V5LnNwbGl0KCcuJykubGVuZ3RoID4gMTtcbiAgICAgIH0pXG4gICAgICAubWFwKGtleSA9PiB7XG4gICAgICAgIC8vIFNsaWNlIHRoZSBsYXN0IGNvbXBvbmVudCAoYS5iLmMgLT4gYS5iKVxuICAgICAgICAvLyBPdGhlcndpc2Ugd2UnbGwgaW5jbHVkZSBvbmUgbGV2ZWwgdG9vIG11Y2guXG4gICAgICAgIHJldHVybiBrZXkuc2xpY2UoMCwga2V5Lmxhc3RJbmRleE9mKCcuJykpO1xuICAgICAgfSlcbiAgICAgIC5qb2luKCcsJyk7XG5cbiAgICAvLyBDb25jYXQgdGhlIHBvc3NpYmx5IHByZXNlbnQgaW5jbHVkZSBzdHJpbmcgd2l0aCB0aGUgb25lIGZyb20gdGhlIGtleXNcbiAgICAvLyBEZWR1cCAvIHNvcnRpbmcgaXMgaGFuZGxlIGluICdpbmNsdWRlJyBjYXNlLlxuICAgIGlmIChrZXlzRm9ySW5jbHVkZS5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAoIXJlc3RPcHRpb25zLmluY2x1ZGUgfHwgcmVzdE9wdGlvbnMuaW5jbHVkZS5sZW5ndGggPT0gMCkge1xuICAgICAgICByZXN0T3B0aW9ucy5pbmNsdWRlID0ga2V5c0ZvckluY2x1ZGU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN0T3B0aW9ucy5pbmNsdWRlICs9ICcsJyArIGtleXNGb3JJbmNsdWRlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZvciAodmFyIG9wdGlvbiBpbiByZXN0T3B0aW9ucykge1xuICAgIHN3aXRjaCAob3B0aW9uKSB7XG4gICAgICBjYXNlICdrZXlzJzoge1xuICAgICAgICBjb25zdCBrZXlzID0gcmVzdE9wdGlvbnMua2V5cy5zcGxpdCgnLCcpLmZpbHRlcihrZXkgPT4ga2V5Lmxlbmd0aCA+IDApLmNvbmNhdChBbHdheXNTZWxlY3RlZEtleXMpO1xuICAgICAgICB0aGlzLmtleXMgPSBBcnJheS5mcm9tKG5ldyBTZXQoa2V5cykpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2V4Y2x1ZGVLZXlzJzoge1xuICAgICAgICBjb25zdCBleGNsdWRlID0gcmVzdE9wdGlvbnMuZXhjbHVkZUtleXNcbiAgICAgICAgICAuc3BsaXQoJywnKVxuICAgICAgICAgIC5maWx0ZXIoayA9PiBBbHdheXNTZWxlY3RlZEtleXMuaW5kZXhPZihrKSA8IDApO1xuICAgICAgICB0aGlzLmV4Y2x1ZGVLZXlzID0gQXJyYXkuZnJvbShuZXcgU2V0KGV4Y2x1ZGUpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdjb3VudCc6XG4gICAgICAgIHRoaXMuZG9Db3VudCA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW5jbHVkZUFsbCc6XG4gICAgICAgIHRoaXMuaW5jbHVkZUFsbCA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnZXhwbGFpbic6XG4gICAgICBjYXNlICdoaW50JzpcbiAgICAgIGNhc2UgJ2Rpc3RpbmN0JzpcbiAgICAgIGNhc2UgJ3BpcGVsaW5lJzpcbiAgICAgIGNhc2UgJ3NraXAnOlxuICAgICAgY2FzZSAnbGltaXQnOlxuICAgICAgY2FzZSAncmVhZFByZWZlcmVuY2UnOlxuICAgICAgICB0aGlzLmZpbmRPcHRpb25zW29wdGlvbl0gPSByZXN0T3B0aW9uc1tvcHRpb25dO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ29yZGVyJzpcbiAgICAgICAgdmFyIGZpZWxkcyA9IHJlc3RPcHRpb25zLm9yZGVyLnNwbGl0KCcsJyk7XG4gICAgICAgIHRoaXMuZmluZE9wdGlvbnMuc29ydCA9IGZpZWxkcy5yZWR1Y2UoKHNvcnRNYXAsIGZpZWxkKSA9PiB7XG4gICAgICAgICAgZmllbGQgPSBmaWVsZC50cmltKCk7XG4gICAgICAgICAgaWYgKGZpZWxkID09PSAnJHNjb3JlJykge1xuICAgICAgICAgICAgc29ydE1hcC5zY29yZSA9IHsgJG1ldGE6ICd0ZXh0U2NvcmUnIH07XG4gICAgICAgICAgfSBlbHNlIGlmIChmaWVsZFswXSA9PSAnLScpIHtcbiAgICAgICAgICAgIHNvcnRNYXBbZmllbGQuc2xpY2UoMSldID0gLTE7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNvcnRNYXBbZmllbGRdID0gMTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHNvcnRNYXA7XG4gICAgICAgIH0sIHt9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdpbmNsdWRlJzoge1xuICAgICAgICBjb25zdCBwYXRocyA9IHJlc3RPcHRpb25zLmluY2x1ZGUuc3BsaXQoJywnKTtcbiAgICAgICAgaWYgKHBhdGhzLmluY2x1ZGVzKCcqJykpIHtcbiAgICAgICAgICB0aGlzLmluY2x1ZGVBbGwgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIC8vIExvYWQgdGhlIGV4aXN0aW5nIGluY2x1ZGVzIChmcm9tIGtleXMpXG4gICAgICAgIGNvbnN0IHBhdGhTZXQgPSBwYXRocy5yZWR1Y2UoKG1lbW8sIHBhdGgpID0+IHtcbiAgICAgICAgICAvLyBTcGxpdCBlYWNoIHBhdGhzIG9uIC4gKGEuYi5jIC0+IFthLGIsY10pXG4gICAgICAgICAgLy8gcmVkdWNlIHRvIGNyZWF0ZSBhbGwgcGF0aHNcbiAgICAgICAgICAvLyAoW2EsYixjXSAtPiB7YTogdHJ1ZSwgJ2EuYic6IHRydWUsICdhLmIuYyc6IHRydWV9KVxuICAgICAgICAgIHJldHVybiBwYXRoLnNwbGl0KCcuJykucmVkdWNlKChtZW1vLCBwYXRoLCBpbmRleCwgcGFydHMpID0+IHtcbiAgICAgICAgICAgIG1lbW9bcGFydHMuc2xpY2UoMCwgaW5kZXggKyAxKS5qb2luKCcuJyldID0gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybiBtZW1vO1xuICAgICAgICAgIH0sIG1lbW8pO1xuICAgICAgICB9LCB7fSk7XG5cbiAgICAgICAgdGhpcy5pbmNsdWRlID0gT2JqZWN0LmtleXMocGF0aFNldClcbiAgICAgICAgICAubWFwKHMgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHMuc3BsaXQoJy4nKTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gYS5sZW5ndGggLSBiLmxlbmd0aDsgLy8gU29ydCBieSBudW1iZXIgb2YgY29tcG9uZW50c1xuICAgICAgICAgIH0pO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ3JlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5JzpcbiAgICAgICAgdGhpcy5yZWRpcmVjdEtleSA9IHJlc3RPcHRpb25zLnJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5O1xuICAgICAgICB0aGlzLnJlZGlyZWN0Q2xhc3NOYW1lID0gbnVsbDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdpbmNsdWRlUmVhZFByZWZlcmVuY2UnOlxuICAgICAgY2FzZSAnc3VicXVlcnlSZWFkUHJlZmVyZW5jZSc6XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2JhZCBvcHRpb246ICcgKyBvcHRpb24pO1xuICAgIH1cbiAgfVxufVxuXG4vLyBBIGNvbnZlbmllbnQgbWV0aG9kIHRvIHBlcmZvcm0gYWxsIHRoZSBzdGVwcyBvZiBwcm9jZXNzaW5nIGEgcXVlcnlcbi8vIGluIG9yZGVyLlxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXNwb25zZSAtIGFuIG9iamVjdCB3aXRoIG9wdGlvbmFsIGtleXNcbi8vICdyZXN1bHRzJyBhbmQgJ2NvdW50Jy5cbi8vIFRPRE86IGNvbnNvbGlkYXRlIHRoZSByZXBsYWNlWCBmdW5jdGlvbnNcblJlc3RRdWVyeS5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uIChleGVjdXRlT3B0aW9ucykge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5idWlsZFJlc3RXaGVyZSgpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlSW5jbHVkZUFsbCgpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRXhjbHVkZUtleXMoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnJ1bkZpbmQoZXhlY3V0ZU9wdGlvbnMpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMucnVuQ291bnQoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUluY2x1ZGUoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnJ1bkFmdGVyRmluZFRyaWdnZXIoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnJlc3BvbnNlO1xuICAgIH0pO1xufTtcblxuUmVzdFF1ZXJ5LnByb3RvdHlwZS5lYWNoID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIHJlc3RXaGVyZSwgcmVzdE9wdGlvbnMsIGNsaWVudFNESyB9ID0gdGhpcztcbiAgLy8gaWYgdGhlIGxpbWl0IGlzIHNldCwgdXNlIGl0XG4gIHJlc3RPcHRpb25zLmxpbWl0ID0gcmVzdE9wdGlvbnMubGltaXQgfHwgMTAwO1xuICByZXN0T3B0aW9ucy5vcmRlciA9ICdvYmplY3RJZCc7XG4gIGxldCBmaW5pc2hlZCA9IGZhbHNlO1xuXG4gIHJldHVybiBjb250aW51ZVdoaWxlKFxuICAgICgpID0+IHtcbiAgICAgIHJldHVybiAhZmluaXNoZWQ7XG4gICAgfSxcbiAgICBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBxdWVyeSA9IG5ldyBSZXN0UXVlcnkoXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgYXV0aCxcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICByZXN0V2hlcmUsXG4gICAgICAgIHJlc3RPcHRpb25zLFxuICAgICAgICBjbGllbnRTREssXG4gICAgICAgIHRoaXMucnVuQWZ0ZXJGaW5kLFxuICAgICAgICB0aGlzLmNvbnRleHRcbiAgICAgICk7XG4gICAgICBjb25zdCB7IHJlc3VsdHMgfSA9IGF3YWl0IHF1ZXJ5LmV4ZWN1dGUoKTtcbiAgICAgIHJlc3VsdHMuZm9yRWFjaChjYWxsYmFjayk7XG4gICAgICBmaW5pc2hlZCA9IHJlc3VsdHMubGVuZ3RoIDwgcmVzdE9wdGlvbnMubGltaXQ7XG4gICAgICBpZiAoIWZpbmlzaGVkKSB7XG4gICAgICAgIHJlc3RXaGVyZS5vYmplY3RJZCA9IE9iamVjdC5hc3NpZ24oe30sIHJlc3RXaGVyZS5vYmplY3RJZCwge1xuICAgICAgICAgICRndDogcmVzdWx0c1tyZXN1bHRzLmxlbmd0aCAtIDFdLm9iamVjdElkLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICk7XG59O1xuXG5SZXN0UXVlcnkucHJvdG90eXBlLmJ1aWxkUmVzdFdoZXJlID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRVc2VyQW5kUm9sZUFDTCgpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMucmVkaXJlY3RDbGFzc05hbWVGb3JLZXkoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlQ2xpZW50Q2xhc3NDcmVhdGlvbigpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMucmVwbGFjZVNlbGVjdCgpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMucmVwbGFjZURvbnRTZWxlY3QoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnJlcGxhY2VJblF1ZXJ5KCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5yZXBsYWNlTm90SW5RdWVyeSgpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMucmVwbGFjZUVxdWFsaXR5KCk7XG4gICAgfSk7XG59O1xuXG4vLyBVc2VzIHRoZSBBdXRoIG9iamVjdCB0byBnZXQgdGhlIGxpc3Qgb2Ygcm9sZXMsIGFkZHMgdGhlIHVzZXIgaWRcblJlc3RRdWVyeS5wcm90b3R5cGUuZ2V0VXNlckFuZFJvbGVBQ0wgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmF1dGguaXNNYXN0ZXIpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICB0aGlzLmZpbmRPcHRpb25zLmFjbCA9IFsnKiddO1xuXG4gIGlmICh0aGlzLmF1dGgudXNlcikge1xuICAgIHJldHVybiB0aGlzLmF1dGguZ2V0VXNlclJvbGVzKCkudGhlbihyb2xlcyA9PiB7XG4gICAgICB0aGlzLmZpbmRPcHRpb25zLmFjbCA9IHRoaXMuZmluZE9wdGlvbnMuYWNsLmNvbmNhdChyb2xlcywgW3RoaXMuYXV0aC51c2VyLmlkXSk7XG4gICAgICByZXR1cm47XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG59O1xuXG4vLyBDaGFuZ2VzIHRoZSBjbGFzc05hbWUgaWYgcmVkaXJlY3RDbGFzc05hbWVGb3JLZXkgaXMgc2V0LlxuLy8gUmV0dXJucyBhIHByb21pc2UuXG5SZXN0UXVlcnkucHJvdG90eXBlLnJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5ID0gZnVuY3Rpb24gKCkge1xuICBpZiAoIXRoaXMucmVkaXJlY3RLZXkpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICAvLyBXZSBuZWVkIHRvIGNoYW5nZSB0aGUgY2xhc3MgbmFtZSBiYXNlZCBvbiB0aGUgc2NoZW1hXG4gIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgIC5yZWRpcmVjdENsYXNzTmFtZUZvcktleSh0aGlzLmNsYXNzTmFtZSwgdGhpcy5yZWRpcmVjdEtleSlcbiAgICAudGhlbihuZXdDbGFzc05hbWUgPT4ge1xuICAgICAgdGhpcy5jbGFzc05hbWUgPSBuZXdDbGFzc05hbWU7XG4gICAgICB0aGlzLnJlZGlyZWN0Q2xhc3NOYW1lID0gbmV3Q2xhc3NOYW1lO1xuICAgIH0pO1xufTtcblxuLy8gVmFsaWRhdGVzIHRoaXMgb3BlcmF0aW9uIGFnYWluc3QgdGhlIGFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbiBjb25maWcuXG5SZXN0UXVlcnkucHJvdG90eXBlLnZhbGlkYXRlQ2xpZW50Q2xhc3NDcmVhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKFxuICAgIHRoaXMuY29uZmlnLmFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbiA9PT0gZmFsc2UgJiZcbiAgICAhdGhpcy5hdXRoLmlzTWFzdGVyICYmXG4gICAgU2NoZW1hQ29udHJvbGxlci5zeXN0ZW1DbGFzc2VzLmluZGV4T2YodGhpcy5jbGFzc05hbWUpID09PSAtMVxuICApIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAgIC5sb2FkU2NoZW1hKClcbiAgICAgIC50aGVuKHNjaGVtYUNvbnRyb2xsZXIgPT4gc2NoZW1hQ29udHJvbGxlci5oYXNDbGFzcyh0aGlzLmNsYXNzTmFtZSkpXG4gICAgICAudGhlbihoYXNDbGFzcyA9PiB7XG4gICAgICAgIGlmIChoYXNDbGFzcyAhPT0gdHJ1ZSkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sXG4gICAgICAgICAgICAnVGhpcyB1c2VyIGlzIG5vdCBhbGxvd2VkIHRvIGFjY2VzcyAnICsgJ25vbi1leGlzdGVudCBjbGFzczogJyArIHRoaXMuY2xhc3NOYW1lXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG59O1xuXG5mdW5jdGlvbiB0cmFuc2Zvcm1JblF1ZXJ5KGluUXVlcnlPYmplY3QsIGNsYXNzTmFtZSwgcmVzdWx0cykge1xuICB2YXIgdmFsdWVzID0gW107XG4gIGZvciAodmFyIHJlc3VsdCBvZiByZXN1bHRzKSB7XG4gICAgdmFsdWVzLnB1c2goe1xuICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICBjbGFzc05hbWU6IGNsYXNzTmFtZSxcbiAgICAgIG9iamVjdElkOiByZXN1bHQub2JqZWN0SWQsXG4gICAgfSk7XG4gIH1cbiAgZGVsZXRlIGluUXVlcnlPYmplY3RbJyRpblF1ZXJ5J107XG4gIGlmIChBcnJheS5pc0FycmF5KGluUXVlcnlPYmplY3RbJyRpbiddKSkge1xuICAgIGluUXVlcnlPYmplY3RbJyRpbiddID0gaW5RdWVyeU9iamVjdFsnJGluJ10uY29uY2F0KHZhbHVlcyk7XG4gIH0gZWxzZSB7XG4gICAgaW5RdWVyeU9iamVjdFsnJGluJ10gPSB2YWx1ZXM7XG4gIH1cbn1cblxuLy8gUmVwbGFjZXMgYSAkaW5RdWVyeSBjbGF1c2UgYnkgcnVubmluZyB0aGUgc3VicXVlcnksIGlmIHRoZXJlIGlzIGFuXG4vLyAkaW5RdWVyeSBjbGF1c2UuXG4vLyBUaGUgJGluUXVlcnkgY2xhdXNlIHR1cm5zIGludG8gYW4gJGluIHdpdGggdmFsdWVzIHRoYXQgYXJlIGp1c3Rcbi8vIHBvaW50ZXJzIHRvIHRoZSBvYmplY3RzIHJldHVybmVkIGluIHRoZSBzdWJxdWVyeS5cblJlc3RRdWVyeS5wcm90b3R5cGUucmVwbGFjZUluUXVlcnkgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBpblF1ZXJ5T2JqZWN0ID0gZmluZE9iamVjdFdpdGhLZXkodGhpcy5yZXN0V2hlcmUsICckaW5RdWVyeScpO1xuICBpZiAoIWluUXVlcnlPYmplY3QpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBUaGUgaW5RdWVyeSB2YWx1ZSBtdXN0IGhhdmUgcHJlY2lzZWx5IHR3byBrZXlzIC0gd2hlcmUgYW5kIGNsYXNzTmFtZVxuICB2YXIgaW5RdWVyeVZhbHVlID0gaW5RdWVyeU9iamVjdFsnJGluUXVlcnknXTtcbiAgaWYgKCFpblF1ZXJ5VmFsdWUud2hlcmUgfHwgIWluUXVlcnlWYWx1ZS5jbGFzc05hbWUpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSwgJ2ltcHJvcGVyIHVzYWdlIG9mICRpblF1ZXJ5Jyk7XG4gIH1cblxuICBjb25zdCBhZGRpdGlvbmFsT3B0aW9ucyA9IHtcbiAgICByZWRpcmVjdENsYXNzTmFtZUZvcktleTogaW5RdWVyeVZhbHVlLnJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5LFxuICB9O1xuXG4gIGlmICh0aGlzLnJlc3RPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UpIHtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHRoaXMucmVzdE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlO1xuICB9IGVsc2UgaWYgKHRoaXMucmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2UpIHtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHRoaXMucmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2U7XG4gIH1cblxuICB2YXIgc3VicXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KFxuICAgIHRoaXMuY29uZmlnLFxuICAgIHRoaXMuYXV0aCxcbiAgICBpblF1ZXJ5VmFsdWUuY2xhc3NOYW1lLFxuICAgIGluUXVlcnlWYWx1ZS53aGVyZSxcbiAgICBhZGRpdGlvbmFsT3B0aW9uc1xuICApO1xuICByZXR1cm4gc3VicXVlcnkuZXhlY3V0ZSgpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgIHRyYW5zZm9ybUluUXVlcnkoaW5RdWVyeU9iamVjdCwgc3VicXVlcnkuY2xhc3NOYW1lLCByZXNwb25zZS5yZXN1bHRzKTtcbiAgICAvLyBSZWN1cnNlIHRvIHJlcGVhdFxuICAgIHJldHVybiB0aGlzLnJlcGxhY2VJblF1ZXJ5KCk7XG4gIH0pO1xufTtcblxuZnVuY3Rpb24gdHJhbnNmb3JtTm90SW5RdWVyeShub3RJblF1ZXJ5T2JqZWN0LCBjbGFzc05hbWUsIHJlc3VsdHMpIHtcbiAgdmFyIHZhbHVlcyA9IFtdO1xuICBmb3IgKHZhciByZXN1bHQgb2YgcmVzdWx0cykge1xuICAgIHZhbHVlcy5wdXNoKHtcbiAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgY2xhc3NOYW1lOiBjbGFzc05hbWUsXG4gICAgICBvYmplY3RJZDogcmVzdWx0Lm9iamVjdElkLFxuICAgIH0pO1xuICB9XG4gIGRlbGV0ZSBub3RJblF1ZXJ5T2JqZWN0Wyckbm90SW5RdWVyeSddO1xuICBpZiAoQXJyYXkuaXNBcnJheShub3RJblF1ZXJ5T2JqZWN0WyckbmluJ10pKSB7XG4gICAgbm90SW5RdWVyeU9iamVjdFsnJG5pbiddID0gbm90SW5RdWVyeU9iamVjdFsnJG5pbiddLmNvbmNhdCh2YWx1ZXMpO1xuICB9IGVsc2Uge1xuICAgIG5vdEluUXVlcnlPYmplY3RbJyRuaW4nXSA9IHZhbHVlcztcbiAgfVxufVxuXG4vLyBSZXBsYWNlcyBhICRub3RJblF1ZXJ5IGNsYXVzZSBieSBydW5uaW5nIHRoZSBzdWJxdWVyeSwgaWYgdGhlcmUgaXMgYW5cbi8vICRub3RJblF1ZXJ5IGNsYXVzZS5cbi8vIFRoZSAkbm90SW5RdWVyeSBjbGF1c2UgdHVybnMgaW50byBhICRuaW4gd2l0aCB2YWx1ZXMgdGhhdCBhcmUganVzdFxuLy8gcG9pbnRlcnMgdG8gdGhlIG9iamVjdHMgcmV0dXJuZWQgaW4gdGhlIHN1YnF1ZXJ5LlxuUmVzdFF1ZXJ5LnByb3RvdHlwZS5yZXBsYWNlTm90SW5RdWVyeSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG5vdEluUXVlcnlPYmplY3QgPSBmaW5kT2JqZWN0V2l0aEtleSh0aGlzLnJlc3RXaGVyZSwgJyRub3RJblF1ZXJ5Jyk7XG4gIGlmICghbm90SW5RdWVyeU9iamVjdCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIFRoZSBub3RJblF1ZXJ5IHZhbHVlIG11c3QgaGF2ZSBwcmVjaXNlbHkgdHdvIGtleXMgLSB3aGVyZSBhbmQgY2xhc3NOYW1lXG4gIHZhciBub3RJblF1ZXJ5VmFsdWUgPSBub3RJblF1ZXJ5T2JqZWN0Wyckbm90SW5RdWVyeSddO1xuICBpZiAoIW5vdEluUXVlcnlWYWx1ZS53aGVyZSB8fCAhbm90SW5RdWVyeVZhbHVlLmNsYXNzTmFtZSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnaW1wcm9wZXIgdXNhZ2Ugb2YgJG5vdEluUXVlcnknKTtcbiAgfVxuXG4gIGNvbnN0IGFkZGl0aW9uYWxPcHRpb25zID0ge1xuICAgIHJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5OiBub3RJblF1ZXJ5VmFsdWUucmVkaXJlY3RDbGFzc05hbWVGb3JLZXksXG4gIH07XG5cbiAgaWYgKHRoaXMucmVzdE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSkge1xuICAgIGFkZGl0aW9uYWxPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlO1xuICAgIGFkZGl0aW9uYWxPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UgPSB0aGlzLnJlc3RPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U7XG4gIH0gZWxzZSBpZiAodGhpcy5yZXN0T3B0aW9ucy5yZWFkUHJlZmVyZW5jZSkge1xuICAgIGFkZGl0aW9uYWxPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5yZWFkUHJlZmVyZW5jZTtcbiAgfVxuXG4gIHZhciBzdWJxdWVyeSA9IG5ldyBSZXN0UXVlcnkoXG4gICAgdGhpcy5jb25maWcsXG4gICAgdGhpcy5hdXRoLFxuICAgIG5vdEluUXVlcnlWYWx1ZS5jbGFzc05hbWUsXG4gICAgbm90SW5RdWVyeVZhbHVlLndoZXJlLFxuICAgIGFkZGl0aW9uYWxPcHRpb25zXG4gICk7XG4gIHJldHVybiBzdWJxdWVyeS5leGVjdXRlKCkudGhlbihyZXNwb25zZSA9PiB7XG4gICAgdHJhbnNmb3JtTm90SW5RdWVyeShub3RJblF1ZXJ5T2JqZWN0LCBzdWJxdWVyeS5jbGFzc05hbWUsIHJlc3BvbnNlLnJlc3VsdHMpO1xuICAgIC8vIFJlY3Vyc2UgdG8gcmVwZWF0XG4gICAgcmV0dXJuIHRoaXMucmVwbGFjZU5vdEluUXVlcnkoKTtcbiAgfSk7XG59O1xuXG4vLyBVc2VkIHRvIGdldCB0aGUgZGVlcGVzdCBvYmplY3QgZnJvbSBqc29uIHVzaW5nIGRvdCBub3RhdGlvbi5cbmNvbnN0IGdldERlZXBlc3RPYmplY3RGcm9tS2V5ID0gKGpzb24sIGtleSwgaWR4LCBzcmMpID0+IHtcbiAgaWYgKGtleSBpbiBqc29uKSB7XG4gICAgcmV0dXJuIGpzb25ba2V5XTtcbiAgfVxuICBzcmMuc3BsaWNlKDEpOyAvLyBFeGl0IEVhcmx5XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1TZWxlY3QgPSAoc2VsZWN0T2JqZWN0LCBrZXksIG9iamVjdHMpID0+IHtcbiAgdmFyIHZhbHVlcyA9IFtdO1xuICBmb3IgKHZhciByZXN1bHQgb2Ygb2JqZWN0cykge1xuICAgIHZhbHVlcy5wdXNoKGtleS5zcGxpdCgnLicpLnJlZHVjZShnZXREZWVwZXN0T2JqZWN0RnJvbUtleSwgcmVzdWx0KSk7XG4gIH1cbiAgZGVsZXRlIHNlbGVjdE9iamVjdFsnJHNlbGVjdCddO1xuICBpZiAoQXJyYXkuaXNBcnJheShzZWxlY3RPYmplY3RbJyRpbiddKSkge1xuICAgIHNlbGVjdE9iamVjdFsnJGluJ10gPSBzZWxlY3RPYmplY3RbJyRpbiddLmNvbmNhdCh2YWx1ZXMpO1xuICB9IGVsc2Uge1xuICAgIHNlbGVjdE9iamVjdFsnJGluJ10gPSB2YWx1ZXM7XG4gIH1cbn07XG5cbi8vIFJlcGxhY2VzIGEgJHNlbGVjdCBjbGF1c2UgYnkgcnVubmluZyB0aGUgc3VicXVlcnksIGlmIHRoZXJlIGlzIGFcbi8vICRzZWxlY3QgY2xhdXNlLlxuLy8gVGhlICRzZWxlY3QgY2xhdXNlIHR1cm5zIGludG8gYW4gJGluIHdpdGggdmFsdWVzIHNlbGVjdGVkIG91dCBvZlxuLy8gdGhlIHN1YnF1ZXJ5LlxuLy8gUmV0dXJucyBhIHBvc3NpYmxlLXByb21pc2UuXG5SZXN0UXVlcnkucHJvdG90eXBlLnJlcGxhY2VTZWxlY3QgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzZWxlY3RPYmplY3QgPSBmaW5kT2JqZWN0V2l0aEtleSh0aGlzLnJlc3RXaGVyZSwgJyRzZWxlY3QnKTtcbiAgaWYgKCFzZWxlY3RPYmplY3QpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBUaGUgc2VsZWN0IHZhbHVlIG11c3QgaGF2ZSBwcmVjaXNlbHkgdHdvIGtleXMgLSBxdWVyeSBhbmQga2V5XG4gIHZhciBzZWxlY3RWYWx1ZSA9IHNlbGVjdE9iamVjdFsnJHNlbGVjdCddO1xuICAvLyBpT1MgU0RLIGRvbid0IHNlbmQgd2hlcmUgaWYgbm90IHNldCwgbGV0IGl0IHBhc3NcbiAgaWYgKFxuICAgICFzZWxlY3RWYWx1ZS5xdWVyeSB8fFxuICAgICFzZWxlY3RWYWx1ZS5rZXkgfHxcbiAgICB0eXBlb2Ygc2VsZWN0VmFsdWUucXVlcnkgIT09ICdvYmplY3QnIHx8XG4gICAgIXNlbGVjdFZhbHVlLnF1ZXJ5LmNsYXNzTmFtZSB8fFxuICAgIE9iamVjdC5rZXlzKHNlbGVjdFZhbHVlKS5sZW5ndGggIT09IDJcbiAgKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksICdpbXByb3BlciB1c2FnZSBvZiAkc2VsZWN0Jyk7XG4gIH1cblxuICBjb25zdCBhZGRpdGlvbmFsT3B0aW9ucyA9IHtcbiAgICByZWRpcmVjdENsYXNzTmFtZUZvcktleTogc2VsZWN0VmFsdWUucXVlcnkucmVkaXJlY3RDbGFzc05hbWVGb3JLZXksXG4gIH07XG5cbiAgaWYgKHRoaXMucmVzdE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSkge1xuICAgIGFkZGl0aW9uYWxPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlO1xuICAgIGFkZGl0aW9uYWxPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UgPSB0aGlzLnJlc3RPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U7XG4gIH0gZWxzZSBpZiAodGhpcy5yZXN0T3B0aW9ucy5yZWFkUHJlZmVyZW5jZSkge1xuICAgIGFkZGl0aW9uYWxPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5yZWFkUHJlZmVyZW5jZTtcbiAgfVxuXG4gIHZhciBzdWJxdWVyeSA9IG5ldyBSZXN0UXVlcnkoXG4gICAgdGhpcy5jb25maWcsXG4gICAgdGhpcy5hdXRoLFxuICAgIHNlbGVjdFZhbHVlLnF1ZXJ5LmNsYXNzTmFtZSxcbiAgICBzZWxlY3RWYWx1ZS5xdWVyeS53aGVyZSxcbiAgICBhZGRpdGlvbmFsT3B0aW9uc1xuICApO1xuICByZXR1cm4gc3VicXVlcnkuZXhlY3V0ZSgpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgIHRyYW5zZm9ybVNlbGVjdChzZWxlY3RPYmplY3QsIHNlbGVjdFZhbHVlLmtleSwgcmVzcG9uc2UucmVzdWx0cyk7XG4gICAgLy8gS2VlcCByZXBsYWNpbmcgJHNlbGVjdCBjbGF1c2VzXG4gICAgcmV0dXJuIHRoaXMucmVwbGFjZVNlbGVjdCgpO1xuICB9KTtcbn07XG5cbmNvbnN0IHRyYW5zZm9ybURvbnRTZWxlY3QgPSAoZG9udFNlbGVjdE9iamVjdCwga2V5LCBvYmplY3RzKSA9PiB7XG4gIHZhciB2YWx1ZXMgPSBbXTtcbiAgZm9yICh2YXIgcmVzdWx0IG9mIG9iamVjdHMpIHtcbiAgICB2YWx1ZXMucHVzaChrZXkuc3BsaXQoJy4nKS5yZWR1Y2UoZ2V0RGVlcGVzdE9iamVjdEZyb21LZXksIHJlc3VsdCkpO1xuICB9XG4gIGRlbGV0ZSBkb250U2VsZWN0T2JqZWN0WyckZG9udFNlbGVjdCddO1xuICBpZiAoQXJyYXkuaXNBcnJheShkb250U2VsZWN0T2JqZWN0WyckbmluJ10pKSB7XG4gICAgZG9udFNlbGVjdE9iamVjdFsnJG5pbiddID0gZG9udFNlbGVjdE9iamVjdFsnJG5pbiddLmNvbmNhdCh2YWx1ZXMpO1xuICB9IGVsc2Uge1xuICAgIGRvbnRTZWxlY3RPYmplY3RbJyRuaW4nXSA9IHZhbHVlcztcbiAgfVxufTtcblxuLy8gUmVwbGFjZXMgYSAkZG9udFNlbGVjdCBjbGF1c2UgYnkgcnVubmluZyB0aGUgc3VicXVlcnksIGlmIHRoZXJlIGlzIGFcbi8vICRkb250U2VsZWN0IGNsYXVzZS5cbi8vIFRoZSAkZG9udFNlbGVjdCBjbGF1c2UgdHVybnMgaW50byBhbiAkbmluIHdpdGggdmFsdWVzIHNlbGVjdGVkIG91dCBvZlxuLy8gdGhlIHN1YnF1ZXJ5LlxuLy8gUmV0dXJucyBhIHBvc3NpYmxlLXByb21pc2UuXG5SZXN0UXVlcnkucHJvdG90eXBlLnJlcGxhY2VEb250U2VsZWN0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgZG9udFNlbGVjdE9iamVjdCA9IGZpbmRPYmplY3RXaXRoS2V5KHRoaXMucmVzdFdoZXJlLCAnJGRvbnRTZWxlY3QnKTtcbiAgaWYgKCFkb250U2VsZWN0T2JqZWN0KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gVGhlIGRvbnRTZWxlY3QgdmFsdWUgbXVzdCBoYXZlIHByZWNpc2VseSB0d28ga2V5cyAtIHF1ZXJ5IGFuZCBrZXlcbiAgdmFyIGRvbnRTZWxlY3RWYWx1ZSA9IGRvbnRTZWxlY3RPYmplY3RbJyRkb250U2VsZWN0J107XG4gIGlmIChcbiAgICAhZG9udFNlbGVjdFZhbHVlLnF1ZXJ5IHx8XG4gICAgIWRvbnRTZWxlY3RWYWx1ZS5rZXkgfHxcbiAgICB0eXBlb2YgZG9udFNlbGVjdFZhbHVlLnF1ZXJ5ICE9PSAnb2JqZWN0JyB8fFxuICAgICFkb250U2VsZWN0VmFsdWUucXVlcnkuY2xhc3NOYW1lIHx8XG4gICAgT2JqZWN0LmtleXMoZG9udFNlbGVjdFZhbHVlKS5sZW5ndGggIT09IDJcbiAgKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksICdpbXByb3BlciB1c2FnZSBvZiAkZG9udFNlbGVjdCcpO1xuICB9XG4gIGNvbnN0IGFkZGl0aW9uYWxPcHRpb25zID0ge1xuICAgIHJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5OiBkb250U2VsZWN0VmFsdWUucXVlcnkucmVkaXJlY3RDbGFzc05hbWVGb3JLZXksXG4gIH07XG5cbiAgaWYgKHRoaXMucmVzdE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSkge1xuICAgIGFkZGl0aW9uYWxPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlO1xuICAgIGFkZGl0aW9uYWxPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UgPSB0aGlzLnJlc3RPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U7XG4gIH0gZWxzZSBpZiAodGhpcy5yZXN0T3B0aW9ucy5yZWFkUHJlZmVyZW5jZSkge1xuICAgIGFkZGl0aW9uYWxPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5yZWFkUHJlZmVyZW5jZTtcbiAgfVxuXG4gIHZhciBzdWJxdWVyeSA9IG5ldyBSZXN0UXVlcnkoXG4gICAgdGhpcy5jb25maWcsXG4gICAgdGhpcy5hdXRoLFxuICAgIGRvbnRTZWxlY3RWYWx1ZS5xdWVyeS5jbGFzc05hbWUsXG4gICAgZG9udFNlbGVjdFZhbHVlLnF1ZXJ5LndoZXJlLFxuICAgIGFkZGl0aW9uYWxPcHRpb25zXG4gICk7XG4gIHJldHVybiBzdWJxdWVyeS5leGVjdXRlKCkudGhlbihyZXNwb25zZSA9PiB7XG4gICAgdHJhbnNmb3JtRG9udFNlbGVjdChkb250U2VsZWN0T2JqZWN0LCBkb250U2VsZWN0VmFsdWUua2V5LCByZXNwb25zZS5yZXN1bHRzKTtcbiAgICAvLyBLZWVwIHJlcGxhY2luZyAkZG9udFNlbGVjdCBjbGF1c2VzXG4gICAgcmV0dXJuIHRoaXMucmVwbGFjZURvbnRTZWxlY3QoKTtcbiAgfSk7XG59O1xuXG5jb25zdCBjbGVhblJlc3VsdEF1dGhEYXRhID0gZnVuY3Rpb24gKHJlc3VsdCkge1xuICBkZWxldGUgcmVzdWx0LnBhc3N3b3JkO1xuICBpZiAocmVzdWx0LmF1dGhEYXRhKSB7XG4gICAgT2JqZWN0LmtleXMocmVzdWx0LmF1dGhEYXRhKS5mb3JFYWNoKHByb3ZpZGVyID0+IHtcbiAgICAgIGlmIChyZXN1bHQuYXV0aERhdGFbcHJvdmlkZXJdID09PSBudWxsKSB7XG4gICAgICAgIGRlbGV0ZSByZXN1bHQuYXV0aERhdGFbcHJvdmlkZXJdO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKE9iamVjdC5rZXlzKHJlc3VsdC5hdXRoRGF0YSkubGVuZ3RoID09IDApIHtcbiAgICAgIGRlbGV0ZSByZXN1bHQuYXV0aERhdGE7XG4gICAgfVxuICB9XG59O1xuXG5jb25zdCByZXBsYWNlRXF1YWxpdHlDb25zdHJhaW50ID0gY29uc3RyYWludCA9PiB7XG4gIGlmICh0eXBlb2YgY29uc3RyYWludCAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gY29uc3RyYWludDtcbiAgfVxuICBjb25zdCBlcXVhbFRvT2JqZWN0ID0ge307XG4gIGxldCBoYXNEaXJlY3RDb25zdHJhaW50ID0gZmFsc2U7XG4gIGxldCBoYXNPcGVyYXRvckNvbnN0cmFpbnQgPSBmYWxzZTtcbiAgZm9yIChjb25zdCBrZXkgaW4gY29uc3RyYWludCkge1xuICAgIGlmIChrZXkuaW5kZXhPZignJCcpICE9PSAwKSB7XG4gICAgICBoYXNEaXJlY3RDb25zdHJhaW50ID0gdHJ1ZTtcbiAgICAgIGVxdWFsVG9PYmplY3Rba2V5XSA9IGNvbnN0cmFpbnRba2V5XTtcbiAgICB9IGVsc2Uge1xuICAgICAgaGFzT3BlcmF0b3JDb25zdHJhaW50ID0gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgaWYgKGhhc0RpcmVjdENvbnN0cmFpbnQgJiYgaGFzT3BlcmF0b3JDb25zdHJhaW50KSB7XG4gICAgY29uc3RyYWludFsnJGVxJ10gPSBlcXVhbFRvT2JqZWN0O1xuICAgIE9iamVjdC5rZXlzKGVxdWFsVG9PYmplY3QpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGRlbGV0ZSBjb25zdHJhaW50W2tleV07XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIGNvbnN0cmFpbnQ7XG59O1xuXG5SZXN0UXVlcnkucHJvdG90eXBlLnJlcGxhY2VFcXVhbGl0eSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHR5cGVvZiB0aGlzLnJlc3RXaGVyZSAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgZm9yIChjb25zdCBrZXkgaW4gdGhpcy5yZXN0V2hlcmUpIHtcbiAgICB0aGlzLnJlc3RXaGVyZVtrZXldID0gcmVwbGFjZUVxdWFsaXR5Q29uc3RyYWludCh0aGlzLnJlc3RXaGVyZVtrZXldKTtcbiAgfVxufTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIHdoZXRoZXIgaXQgd2FzIHN1Y2Nlc3NmdWwuXG4vLyBQb3B1bGF0ZXMgdGhpcy5yZXNwb25zZSB3aXRoIGFuIG9iamVjdCB0aGF0IG9ubHkgaGFzICdyZXN1bHRzJy5cblJlc3RRdWVyeS5wcm90b3R5cGUucnVuRmluZCA9IGZ1bmN0aW9uIChvcHRpb25zID0ge30pIHtcbiAgaWYgKHRoaXMuZmluZE9wdGlvbnMubGltaXQgPT09IDApIHtcbiAgICB0aGlzLnJlc3BvbnNlID0geyByZXN1bHRzOiBbXSB9O1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuICBjb25zdCBmaW5kT3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oe30sIHRoaXMuZmluZE9wdGlvbnMpO1xuICBpZiAodGhpcy5rZXlzKSB7XG4gICAgZmluZE9wdGlvbnMua2V5cyA9IHRoaXMua2V5cy5tYXAoa2V5ID0+IHtcbiAgICAgIHJldHVybiBrZXkuc3BsaXQoJy4nKVswXTtcbiAgICB9KTtcbiAgfVxuICBpZiAob3B0aW9ucy5vcCkge1xuICAgIGZpbmRPcHRpb25zLm9wID0gb3B0aW9ucy5vcDtcbiAgfVxuICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAuZmluZCh0aGlzLmNsYXNzTmFtZSwgdGhpcy5yZXN0V2hlcmUsIGZpbmRPcHRpb25zLCB0aGlzLmF1dGgpXG4gICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICBpZiAodGhpcy5jbGFzc05hbWUgPT09ICdfVXNlcicgJiYgZmluZE9wdGlvbnMuZXhwbGFpbiAhPT0gdHJ1ZSkge1xuICAgICAgICBmb3IgKHZhciByZXN1bHQgb2YgcmVzdWx0cykge1xuICAgICAgICAgIGNsZWFuUmVzdWx0QXV0aERhdGEocmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLmNvbmZpZy5maWxlc0NvbnRyb2xsZXIuZXhwYW5kRmlsZXNJbk9iamVjdCh0aGlzLmNvbmZpZywgcmVzdWx0cyk7XG5cbiAgICAgIGlmICh0aGlzLnJlZGlyZWN0Q2xhc3NOYW1lKSB7XG4gICAgICAgIGZvciAodmFyIHIgb2YgcmVzdWx0cykge1xuICAgICAgICAgIHIuY2xhc3NOYW1lID0gdGhpcy5yZWRpcmVjdENsYXNzTmFtZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5yZXNwb25zZSA9IHsgcmVzdWx0czogcmVzdWx0cyB9O1xuICAgIH0pO1xufTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIHdoZXRoZXIgaXQgd2FzIHN1Y2Nlc3NmdWwuXG4vLyBQb3B1bGF0ZXMgdGhpcy5yZXNwb25zZS5jb3VudCB3aXRoIHRoZSBjb3VudFxuUmVzdFF1ZXJ5LnByb3RvdHlwZS5ydW5Db3VudCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCF0aGlzLmRvQ291bnQpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdGhpcy5maW5kT3B0aW9ucy5jb3VudCA9IHRydWU7XG4gIGRlbGV0ZSB0aGlzLmZpbmRPcHRpb25zLnNraXA7XG4gIGRlbGV0ZSB0aGlzLmZpbmRPcHRpb25zLmxpbWl0O1xuICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UuZmluZCh0aGlzLmNsYXNzTmFtZSwgdGhpcy5yZXN0V2hlcmUsIHRoaXMuZmluZE9wdGlvbnMpLnRoZW4oYyA9PiB7XG4gICAgdGhpcy5yZXNwb25zZS5jb3VudCA9IGM7XG4gIH0pO1xufTtcblxuLy8gQXVnbWVudHMgdGhpcy5yZXNwb25zZSB3aXRoIGFsbCBwb2ludGVycyBvbiBhbiBvYmplY3RcblJlc3RRdWVyeS5wcm90b3R5cGUuaGFuZGxlSW5jbHVkZUFsbCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCF0aGlzLmluY2x1ZGVBbGwpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgLmxvYWRTY2hlbWEoKVxuICAgIC50aGVuKHNjaGVtYUNvbnRyb2xsZXIgPT4gc2NoZW1hQ29udHJvbGxlci5nZXRPbmVTY2hlbWEodGhpcy5jbGFzc05hbWUpKVxuICAgIC50aGVuKHNjaGVtYSA9PiB7XG4gICAgICBjb25zdCBpbmNsdWRlRmllbGRzID0gW107XG4gICAgICBjb25zdCBrZXlGaWVsZHMgPSBbXTtcbiAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gc2NoZW1hLmZpZWxkcykge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgKHNjaGVtYS5maWVsZHNbZmllbGRdLnR5cGUgJiYgc2NoZW1hLmZpZWxkc1tmaWVsZF0udHlwZSA9PT0gJ1BvaW50ZXInKSB8fFxuICAgICAgICAgIChzY2hlbWEuZmllbGRzW2ZpZWxkXS50eXBlICYmIHNjaGVtYS5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdBcnJheScpXG4gICAgICAgICkge1xuICAgICAgICAgIGluY2x1ZGVGaWVsZHMucHVzaChbZmllbGRdKTtcbiAgICAgICAgICBrZXlGaWVsZHMucHVzaChmaWVsZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIEFkZCBmaWVsZHMgdG8gaW5jbHVkZSwga2V5cywgcmVtb3ZlIGR1cHNcbiAgICAgIHRoaXMuaW5jbHVkZSA9IFsuLi5uZXcgU2V0KFsuLi50aGlzLmluY2x1ZGUsIC4uLmluY2x1ZGVGaWVsZHNdKV07XG4gICAgICAvLyBpZiB0aGlzLmtleXMgbm90IHNldCwgdGhlbiBhbGwga2V5cyBhcmUgYWxyZWFkeSBpbmNsdWRlZFxuICAgICAgaWYgKHRoaXMua2V5cykge1xuICAgICAgICB0aGlzLmtleXMgPSBbLi4ubmV3IFNldChbLi4udGhpcy5rZXlzLCAuLi5rZXlGaWVsZHNdKV07XG4gICAgICB9XG4gICAgfSk7XG59O1xuXG4vLyBVcGRhdGVzIHByb3BlcnR5IGB0aGlzLmtleXNgIHRvIGNvbnRhaW4gYWxsIGtleXMgYnV0IHRoZSBvbmVzIHVuc2VsZWN0ZWQuXG5SZXN0UXVlcnkucHJvdG90eXBlLmhhbmRsZUV4Y2x1ZGVLZXlzID0gZnVuY3Rpb24gKCkge1xuICBpZiAoIXRoaXMuZXhjbHVkZUtleXMpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHRoaXMua2V5cykge1xuICAgIHRoaXMua2V5cyA9IHRoaXMua2V5cy5maWx0ZXIoayA9PiAhdGhpcy5leGNsdWRlS2V5cy5pbmNsdWRlcyhrKSk7XG4gICAgcmV0dXJuO1xuICB9XG4gIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgIC5sb2FkU2NoZW1hKClcbiAgICAudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHNjaGVtYUNvbnRyb2xsZXIuZ2V0T25lU2NoZW1hKHRoaXMuY2xhc3NOYW1lKSlcbiAgICAudGhlbihzY2hlbWEgPT4ge1xuICAgICAgY29uc3QgZmllbGRzID0gT2JqZWN0LmtleXMoc2NoZW1hLmZpZWxkcyk7XG4gICAgICB0aGlzLmtleXMgPSBmaWVsZHMuZmlsdGVyKGsgPT4gIXRoaXMuZXhjbHVkZUtleXMuaW5jbHVkZXMoaykpO1xuICAgIH0pO1xufTtcblxuLy8gQXVnbWVudHMgdGhpcy5yZXNwb25zZSB3aXRoIGRhdGEgYXQgdGhlIHBhdGhzIHByb3ZpZGVkIGluIHRoaXMuaW5jbHVkZS5cblJlc3RRdWVyeS5wcm90b3R5cGUuaGFuZGxlSW5jbHVkZSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuaW5jbHVkZS5sZW5ndGggPT0gMCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBwYXRoUmVzcG9uc2UgPSBpbmNsdWRlUGF0aChcbiAgICB0aGlzLmNvbmZpZyxcbiAgICB0aGlzLmF1dGgsXG4gICAgdGhpcy5yZXNwb25zZSxcbiAgICB0aGlzLmluY2x1ZGVbMF0sXG4gICAgdGhpcy5yZXN0T3B0aW9uc1xuICApO1xuICBpZiAocGF0aFJlc3BvbnNlLnRoZW4pIHtcbiAgICByZXR1cm4gcGF0aFJlc3BvbnNlLnRoZW4obmV3UmVzcG9uc2UgPT4ge1xuICAgICAgdGhpcy5yZXNwb25zZSA9IG5ld1Jlc3BvbnNlO1xuICAgICAgdGhpcy5pbmNsdWRlID0gdGhpcy5pbmNsdWRlLnNsaWNlKDEpO1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlSW5jbHVkZSgpO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKHRoaXMuaW5jbHVkZS5sZW5ndGggPiAwKSB7XG4gICAgdGhpcy5pbmNsdWRlID0gdGhpcy5pbmNsdWRlLnNsaWNlKDEpO1xuICAgIHJldHVybiB0aGlzLmhhbmRsZUluY2x1ZGUoKTtcbiAgfVxuXG4gIHJldHVybiBwYXRoUmVzcG9uc2U7XG59O1xuXG4vL1JldHVybnMgYSBwcm9taXNlIG9mIGEgcHJvY2Vzc2VkIHNldCBvZiByZXN1bHRzXG5SZXN0UXVlcnkucHJvdG90eXBlLnJ1bkFmdGVyRmluZFRyaWdnZXIgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5yZXNwb25zZSkge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoIXRoaXMucnVuQWZ0ZXJGaW5kKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIEF2b2lkIGRvaW5nIGFueSBzZXR1cCBmb3IgdHJpZ2dlcnMgaWYgdGhlcmUgaXMgbm8gJ2FmdGVyRmluZCcgdHJpZ2dlciBmb3IgdGhpcyBjbGFzcy5cbiAgY29uc3QgaGFzQWZ0ZXJGaW5kSG9vayA9IHRyaWdnZXJzLnRyaWdnZXJFeGlzdHMoXG4gICAgdGhpcy5jbGFzc05hbWUsXG4gICAgdHJpZ2dlcnMuVHlwZXMuYWZ0ZXJGaW5kLFxuICAgIHRoaXMuY29uZmlnLmFwcGxpY2F0aW9uSWRcbiAgKTtcbiAgaWYgKCFoYXNBZnRlckZpbmRIb29rKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG4gIC8vIFNraXAgQWdncmVnYXRlIGFuZCBEaXN0aW5jdCBRdWVyaWVzXG4gIGlmICh0aGlzLmZpbmRPcHRpb25zLnBpcGVsaW5lIHx8IHRoaXMuZmluZE9wdGlvbnMuZGlzdGluY3QpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBjb25zdCBqc29uID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5yZXN0T3B0aW9ucyk7XG4gIGpzb24ud2hlcmUgPSB0aGlzLnJlc3RXaGVyZTtcbiAgY29uc3QgcGFyc2VRdWVyeSA9IG5ldyBQYXJzZS5RdWVyeSh0aGlzLmNsYXNzTmFtZSk7XG4gIHBhcnNlUXVlcnkud2l0aEpTT04oanNvbik7XG4gIC8vIFJ1biBhZnRlckZpbmQgdHJpZ2dlciBhbmQgc2V0IHRoZSBuZXcgcmVzdWx0c1xuICByZXR1cm4gdHJpZ2dlcnNcbiAgICAubWF5YmVSdW5BZnRlckZpbmRUcmlnZ2VyKFxuICAgICAgdHJpZ2dlcnMuVHlwZXMuYWZ0ZXJGaW5kLFxuICAgICAgdGhpcy5hdXRoLFxuICAgICAgdGhpcy5jbGFzc05hbWUsXG4gICAgICB0aGlzLnJlc3BvbnNlLnJlc3VsdHMsXG4gICAgICB0aGlzLmNvbmZpZyxcbiAgICAgIHBhcnNlUXVlcnksXG4gICAgICB0aGlzLmNvbnRleHRcbiAgICApXG4gICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAvLyBFbnN1cmUgd2UgcHJvcGVybHkgc2V0IHRoZSBjbGFzc05hbWUgYmFja1xuICAgICAgaWYgKHRoaXMucmVkaXJlY3RDbGFzc05hbWUpIHtcbiAgICAgICAgdGhpcy5yZXNwb25zZS5yZXN1bHRzID0gcmVzdWx0cy5tYXAob2JqZWN0ID0+IHtcbiAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgUGFyc2UuT2JqZWN0KSB7XG4gICAgICAgICAgICBvYmplY3QgPSBvYmplY3QudG9KU09OKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIG9iamVjdC5jbGFzc05hbWUgPSB0aGlzLnJlZGlyZWN0Q2xhc3NOYW1lO1xuICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5yZXNwb25zZS5yZXN1bHRzID0gcmVzdWx0cztcbiAgICAgIH1cbiAgICB9KTtcbn07XG5cbi8vIEFkZHMgaW5jbHVkZWQgdmFsdWVzIHRvIHRoZSByZXNwb25zZS5cbi8vIFBhdGggaXMgYSBsaXN0IG9mIGZpZWxkIG5hbWVzLlxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGFuIGF1Z21lbnRlZCByZXNwb25zZS5cbmZ1bmN0aW9uIGluY2x1ZGVQYXRoKGNvbmZpZywgYXV0aCwgcmVzcG9uc2UsIHBhdGgsIHJlc3RPcHRpb25zID0ge30pIHtcbiAgdmFyIHBvaW50ZXJzID0gZmluZFBvaW50ZXJzKHJlc3BvbnNlLnJlc3VsdHMsIHBhdGgpO1xuICBpZiAocG9pbnRlcnMubGVuZ3RoID09IDApIHtcbiAgICByZXR1cm4gcmVzcG9uc2U7XG4gIH1cbiAgY29uc3QgcG9pbnRlcnNIYXNoID0ge307XG4gIGZvciAodmFyIHBvaW50ZXIgb2YgcG9pbnRlcnMpIHtcbiAgICBpZiAoIXBvaW50ZXIpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBjb25zdCBjbGFzc05hbWUgPSBwb2ludGVyLmNsYXNzTmFtZTtcbiAgICAvLyBvbmx5IGluY2x1ZGUgdGhlIGdvb2QgcG9pbnRlcnNcbiAgICBpZiAoY2xhc3NOYW1lKSB7XG4gICAgICBwb2ludGVyc0hhc2hbY2xhc3NOYW1lXSA9IHBvaW50ZXJzSGFzaFtjbGFzc05hbWVdIHx8IG5ldyBTZXQoKTtcbiAgICAgIHBvaW50ZXJzSGFzaFtjbGFzc05hbWVdLmFkZChwb2ludGVyLm9iamVjdElkKTtcbiAgICB9XG4gIH1cbiAgY29uc3QgaW5jbHVkZVJlc3RPcHRpb25zID0ge307XG4gIGlmIChyZXN0T3B0aW9ucy5rZXlzKSB7XG4gICAgY29uc3Qga2V5cyA9IG5ldyBTZXQocmVzdE9wdGlvbnMua2V5cy5zcGxpdCgnLCcpKTtcbiAgICBjb25zdCBrZXlTZXQgPSBBcnJheS5mcm9tKGtleXMpLnJlZHVjZSgoc2V0LCBrZXkpID0+IHtcbiAgICAgIGNvbnN0IGtleVBhdGggPSBrZXkuc3BsaXQoJy4nKTtcbiAgICAgIGxldCBpID0gMDtcbiAgICAgIGZvciAoaTsgaSA8IHBhdGgubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHBhdGhbaV0gIT0ga2V5UGF0aFtpXSkge1xuICAgICAgICAgIHJldHVybiBzZXQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChpIDwga2V5UGF0aC5sZW5ndGgpIHtcbiAgICAgICAgc2V0LmFkZChrZXlQYXRoW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzZXQ7XG4gICAgfSwgbmV3IFNldCgpKTtcbiAgICBpZiAoa2V5U2V0LnNpemUgPiAwKSB7XG4gICAgICBpbmNsdWRlUmVzdE9wdGlvbnMua2V5cyA9IEFycmF5LmZyb20oa2V5U2V0KS5qb2luKCcsJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHJlc3RPcHRpb25zLmluY2x1ZGVSZWFkUHJlZmVyZW5jZSkge1xuICAgIGluY2x1ZGVSZXN0T3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHJlc3RPcHRpb25zLmluY2x1ZGVSZWFkUHJlZmVyZW5jZTtcbiAgICBpbmNsdWRlUmVzdE9wdGlvbnMuaW5jbHVkZVJlYWRQcmVmZXJlbmNlID0gcmVzdE9wdGlvbnMuaW5jbHVkZVJlYWRQcmVmZXJlbmNlO1xuICB9IGVsc2UgaWYgKHJlc3RPcHRpb25zLnJlYWRQcmVmZXJlbmNlKSB7XG4gICAgaW5jbHVkZVJlc3RPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gcmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2U7XG4gIH1cblxuICBjb25zdCBxdWVyeVByb21pc2VzID0gT2JqZWN0LmtleXMocG9pbnRlcnNIYXNoKS5tYXAoY2xhc3NOYW1lID0+IHtcbiAgICBjb25zdCBvYmplY3RJZHMgPSBBcnJheS5mcm9tKHBvaW50ZXJzSGFzaFtjbGFzc05hbWVdKTtcbiAgICBsZXQgd2hlcmU7XG4gICAgaWYgKG9iamVjdElkcy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHdoZXJlID0geyBvYmplY3RJZDogb2JqZWN0SWRzWzBdIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHdoZXJlID0geyBvYmplY3RJZDogeyAkaW46IG9iamVjdElkcyB9IH07XG4gICAgfVxuICAgIHZhciBxdWVyeSA9IG5ldyBSZXN0UXVlcnkoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIHdoZXJlLCBpbmNsdWRlUmVzdE9wdGlvbnMpO1xuICAgIHJldHVybiBxdWVyeS5leGVjdXRlKHsgb3A6ICdnZXQnIH0pLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICByZXN1bHRzLmNsYXNzTmFtZSA9IGNsYXNzTmFtZTtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVzdWx0cyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIEdldCB0aGUgb2JqZWN0cyBmb3IgYWxsIHRoZXNlIG9iamVjdCBpZHNcbiAgcmV0dXJuIFByb21pc2UuYWxsKHF1ZXJ5UHJvbWlzZXMpLnRoZW4ocmVzcG9uc2VzID0+IHtcbiAgICB2YXIgcmVwbGFjZSA9IHJlc3BvbnNlcy5yZWR1Y2UoKHJlcGxhY2UsIGluY2x1ZGVSZXNwb25zZSkgPT4ge1xuICAgICAgZm9yICh2YXIgb2JqIG9mIGluY2x1ZGVSZXNwb25zZS5yZXN1bHRzKSB7XG4gICAgICAgIG9iai5fX3R5cGUgPSAnT2JqZWN0JztcbiAgICAgICAgb2JqLmNsYXNzTmFtZSA9IGluY2x1ZGVSZXNwb25zZS5jbGFzc05hbWU7XG5cbiAgICAgICAgaWYgKG9iai5jbGFzc05hbWUgPT0gJ19Vc2VyJyAmJiAhYXV0aC5pc01hc3Rlcikge1xuICAgICAgICAgIGRlbGV0ZSBvYmouc2Vzc2lvblRva2VuO1xuICAgICAgICAgIGRlbGV0ZSBvYmouYXV0aERhdGE7XG4gICAgICAgIH1cbiAgICAgICAgcmVwbGFjZVtvYmoub2JqZWN0SWRdID0gb2JqO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlcGxhY2U7XG4gICAgfSwge30pO1xuXG4gICAgdmFyIHJlc3AgPSB7XG4gICAgICByZXN1bHRzOiByZXBsYWNlUG9pbnRlcnMocmVzcG9uc2UucmVzdWx0cywgcGF0aCwgcmVwbGFjZSksXG4gICAgfTtcbiAgICBpZiAocmVzcG9uc2UuY291bnQpIHtcbiAgICAgIHJlc3AuY291bnQgPSByZXNwb25zZS5jb3VudDtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3A7XG4gIH0pO1xufVxuXG4vLyBPYmplY3QgbWF5IGJlIGEgbGlzdCBvZiBSRVNULWZvcm1hdCBvYmplY3QgdG8gZmluZCBwb2ludGVycyBpbiwgb3Jcbi8vIGl0IG1heSBiZSBhIHNpbmdsZSBvYmplY3QuXG4vLyBJZiB0aGUgcGF0aCB5aWVsZHMgdGhpbmdzIHRoYXQgYXJlbid0IHBvaW50ZXJzLCB0aGlzIHRocm93cyBhbiBlcnJvci5cbi8vIFBhdGggaXMgYSBsaXN0IG9mIGZpZWxkcyB0byBzZWFyY2ggaW50by5cbi8vIFJldHVybnMgYSBsaXN0IG9mIHBvaW50ZXJzIGluIFJFU1QgZm9ybWF0LlxuZnVuY3Rpb24gZmluZFBvaW50ZXJzKG9iamVjdCwgcGF0aCkge1xuICBpZiAob2JqZWN0IGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICB2YXIgYW5zd2VyID0gW107XG4gICAgZm9yICh2YXIgeCBvZiBvYmplY3QpIHtcbiAgICAgIGFuc3dlciA9IGFuc3dlci5jb25jYXQoZmluZFBvaW50ZXJzKHgsIHBhdGgpKTtcbiAgICB9XG4gICAgcmV0dXJuIGFuc3dlcjtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb2JqZWN0ICE9PSAnb2JqZWN0JyB8fCAhb2JqZWN0KSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgaWYgKHBhdGgubGVuZ3RoID09IDApIHtcbiAgICBpZiAob2JqZWN0ID09PSBudWxsIHx8IG9iamVjdC5fX3R5cGUgPT0gJ1BvaW50ZXInKSB7XG4gICAgICByZXR1cm4gW29iamVjdF07XG4gICAgfVxuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHZhciBzdWJvYmplY3QgPSBvYmplY3RbcGF0aFswXV07XG4gIGlmICghc3Vib2JqZWN0KSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIHJldHVybiBmaW5kUG9pbnRlcnMoc3Vib2JqZWN0LCBwYXRoLnNsaWNlKDEpKTtcbn1cblxuLy8gT2JqZWN0IG1heSBiZSBhIGxpc3Qgb2YgUkVTVC1mb3JtYXQgb2JqZWN0cyB0byByZXBsYWNlIHBvaW50ZXJzXG4vLyBpbiwgb3IgaXQgbWF5IGJlIGEgc2luZ2xlIG9iamVjdC5cbi8vIFBhdGggaXMgYSBsaXN0IG9mIGZpZWxkcyB0byBzZWFyY2ggaW50by5cbi8vIHJlcGxhY2UgaXMgYSBtYXAgZnJvbSBvYmplY3QgaWQgLT4gb2JqZWN0LlxuLy8gUmV0dXJucyBzb21ldGhpbmcgYW5hbG9nb3VzIHRvIG9iamVjdCwgYnV0IHdpdGggdGhlIGFwcHJvcHJpYXRlXG4vLyBwb2ludGVycyBpbmZsYXRlZC5cbmZ1bmN0aW9uIHJlcGxhY2VQb2ludGVycyhvYmplY3QsIHBhdGgsIHJlcGxhY2UpIHtcbiAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgcmV0dXJuIG9iamVjdFxuICAgICAgLm1hcChvYmogPT4gcmVwbGFjZVBvaW50ZXJzKG9iaiwgcGF0aCwgcmVwbGFjZSkpXG4gICAgICAuZmlsdGVyKG9iaiA9PiB0eXBlb2Ygb2JqICE9PSAndW5kZWZpbmVkJyk7XG4gIH1cblxuICBpZiAodHlwZW9mIG9iamVjdCAhPT0gJ29iamVjdCcgfHwgIW9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3Q7XG4gIH1cblxuICBpZiAocGF0aC5sZW5ndGggPT09IDApIHtcbiAgICBpZiAob2JqZWN0ICYmIG9iamVjdC5fX3R5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgcmV0dXJuIHJlcGxhY2Vbb2JqZWN0Lm9iamVjdElkXTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfVxuXG4gIHZhciBzdWJvYmplY3QgPSBvYmplY3RbcGF0aFswXV07XG4gIGlmICghc3Vib2JqZWN0KSB7XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfVxuICB2YXIgbmV3c3ViID0gcmVwbGFjZVBvaW50ZXJzKHN1Ym9iamVjdCwgcGF0aC5zbGljZSgxKSwgcmVwbGFjZSk7XG4gIHZhciBhbnN3ZXIgPSB7fTtcbiAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgIGlmIChrZXkgPT0gcGF0aFswXSkge1xuICAgICAgYW5zd2VyW2tleV0gPSBuZXdzdWI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFuc3dlcltrZXldID0gb2JqZWN0W2tleV07XG4gICAgfVxuICB9XG4gIHJldHVybiBhbnN3ZXI7XG59XG5cbi8vIEZpbmRzIGEgc3Vib2JqZWN0IHRoYXQgaGFzIHRoZSBnaXZlbiBrZXksIGlmIHRoZXJlIGlzIG9uZS5cbi8vIFJldHVybnMgdW5kZWZpbmVkIG90aGVyd2lzZS5cbmZ1bmN0aW9uIGZpbmRPYmplY3RXaXRoS2V5KHJvb3QsIGtleSkge1xuICBpZiAodHlwZW9mIHJvb3QgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChyb290IGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICBmb3IgKHZhciBpdGVtIG9mIHJvb3QpIHtcbiAgICAgIGNvbnN0IGFuc3dlciA9IGZpbmRPYmplY3RXaXRoS2V5KGl0ZW0sIGtleSk7XG4gICAgICBpZiAoYW5zd2VyKSB7XG4gICAgICAgIHJldHVybiBhbnN3ZXI7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlmIChyb290ICYmIHJvb3Rba2V5XSkge1xuICAgIHJldHVybiByb290O1xuICB9XG4gIGZvciAodmFyIHN1YmtleSBpbiByb290KSB7XG4gICAgY29uc3QgYW5zd2VyID0gZmluZE9iamVjdFdpdGhLZXkocm9vdFtzdWJrZXldLCBrZXkpO1xuICAgIGlmIChhbnN3ZXIpIHtcbiAgICAgIHJldHVybiBhbnN3ZXI7XG4gICAgfVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gUmVzdFF1ZXJ5O1xuIl19 \ No newline at end of file diff --git a/lib/RestWrite.js b/lib/RestWrite.js new file mode 100644 index 0000000000..2b2be3e25e --- /dev/null +++ b/lib/RestWrite.js @@ -0,0 +1,1485 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _RestQuery = _interopRequireDefault(require("./RestQuery")); + +var _lodash = _interopRequireDefault(require("lodash")); + +var _logger = _interopRequireDefault(require("./logger")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// A RestWrite encapsulates everything we need to run an operation +// that writes to the database. +// This could be either a "create" or an "update". +var SchemaController = require('./Controllers/SchemaController'); + +var deepcopy = require('deepcopy'); + +const Auth = require('./Auth'); + +var cryptoUtils = require('./cryptoUtils'); + +var passwordCrypto = require('./password'); + +var Parse = require('parse/node'); + +var triggers = require('./triggers'); + +var ClientSDK = require('./ClientSDK'); + +// query and data are both provided in REST API format. So data +// types are encoded by plain old objects. +// If query is null, this is a "create" and the data in data should be +// created. +// Otherwise this is an "update" - the object matching the query +// should get updated with data. +// RestWrite will handle objectId, createdAt, and updatedAt for +// everything. It also knows to use triggers and special modifications +// for the _User class. +function RestWrite(config, auth, className, query, data, originalData, clientSDK, context, action) { + if (auth.isReadOnly) { + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'Cannot perform a write operation when using readOnlyMasterKey'); + } + + this.config = config; + this.auth = auth; + this.className = className; + this.clientSDK = clientSDK; + this.storage = {}; + this.runOptions = {}; + this.context = context || {}; + + if (action) { + this.runOptions.action = action; + } + + if (!query) { + if (this.config.allowCustomObjectId) { + if (Object.prototype.hasOwnProperty.call(data, 'objectId') && !data.objectId) { + throw new Parse.Error(Parse.Error.MISSING_OBJECT_ID, 'objectId must not be empty, null or undefined'); + } + } else { + if (data.objectId) { + throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'objectId is an invalid field name.'); + } + + if (data.id) { + throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'id is an invalid field name.'); + } + } + } // When the operation is complete, this.response may have several + // fields. + // response: the actual data to be returned + // status: the http status code. if not present, treated like a 200 + // location: the location header. if not present, no location header + + + this.response = null; // Processing this operation may mutate our data, so we operate on a + // copy + + this.query = deepcopy(query); + this.data = deepcopy(data); // We never change originalData, so we do not need a deep copy + + this.originalData = originalData; // The timestamp we'll use for this whole operation + + this.updatedAt = Parse._encode(new Date()).iso; // Shared SchemaController to be reused to reduce the number of loadSchema() calls per request + // Once set the schemaData should be immutable + + this.validSchemaController = null; +} // A convenient method to perform all the steps of processing the +// write, in order. +// Returns a promise for a {response, status, location} object. +// status and location are optional. + + +RestWrite.prototype.execute = function () { + return Promise.resolve().then(() => { + return this.getUserAndRoleACL(); + }).then(() => { + return this.validateClientClassCreation(); + }).then(() => { + return this.handleInstallation(); + }).then(() => { + return this.handleSession(); + }).then(() => { + return this.validateAuthData(); + }).then(() => { + return this.runBeforeSaveTrigger(); + }).then(() => { + return this.deleteEmailResetTokenIfNeeded(); + }).then(() => { + return this.validateSchema(); + }).then(schemaController => { + this.validSchemaController = schemaController; + return this.setRequiredFieldsIfNeeded(); + }).then(() => { + return this.transformUser(); + }).then(() => { + return this.expandFilesForExistingObjects(); + }).then(() => { + return this.destroyDuplicatedSessions(); + }).then(() => { + return this.runDatabaseOperation(); + }).then(() => { + return this.createSessionTokenIfNeeded(); + }).then(() => { + return this.handleFollowup(); + }).then(() => { + return this.runAfterSaveTrigger(); + }).then(() => { + return this.cleanUserAuthData(); + }).then(() => { + return this.response; + }); +}; // Uses the Auth object to get the list of roles, adds the user id + + +RestWrite.prototype.getUserAndRoleACL = function () { + if (this.auth.isMaster) { + return Promise.resolve(); + } + + this.runOptions.acl = ['*']; + + if (this.auth.user) { + return this.auth.getUserRoles().then(roles => { + this.runOptions.acl = this.runOptions.acl.concat(roles, [this.auth.user.id]); + return; + }); + } else { + return Promise.resolve(); + } +}; // Validates this operation against the allowClientClassCreation config. + + +RestWrite.prototype.validateClientClassCreation = function () { + if (this.config.allowClientClassCreation === false && !this.auth.isMaster && SchemaController.systemClasses.indexOf(this.className) === -1) { + return this.config.database.loadSchema().then(schemaController => schemaController.hasClass(this.className)).then(hasClass => { + if (hasClass !== true) { + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'This user is not allowed to access ' + 'non-existent class: ' + this.className); + } + }); + } else { + return Promise.resolve(); + } +}; // Validates this operation against the schema. + + +RestWrite.prototype.validateSchema = function () { + return this.config.database.validateObject(this.className, this.data, this.query, this.runOptions); +}; // Runs any beforeSave triggers against this operation. +// Any change leads to our data being mutated. + + +RestWrite.prototype.runBeforeSaveTrigger = function () { + if (this.response) { + return; + } // Avoid doing any setup for triggers if there is no 'beforeSave' trigger for this class. + + + if (!triggers.triggerExists(this.className, triggers.Types.beforeSave, this.config.applicationId)) { + return Promise.resolve(); + } // Cloud code gets a bit of extra data for its objects + + + var extraData = { + className: this.className + }; + + if (this.query && this.query.objectId) { + extraData.objectId = this.query.objectId; + } + + let originalObject = null; + const updatedObject = this.buildUpdatedObject(extraData); + + if (this.query && this.query.objectId) { + // This is an update for existing object. + originalObject = triggers.inflate(extraData, this.originalData); + } + + return Promise.resolve().then(() => { + // Before calling the trigger, validate the permissions for the save operation + let databasePromise = null; + + if (this.query) { + // Validate for updating + databasePromise = this.config.database.update(this.className, this.query, this.data, this.runOptions, true, true); + } else { + // Validate for creating + databasePromise = this.config.database.create(this.className, this.data, this.runOptions, true); + } // In the case that there is no permission for the operation, it throws an error + + + return databasePromise.then(result => { + if (!result || result.length <= 0) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } + }); + }).then(() => { + return triggers.maybeRunTrigger(triggers.Types.beforeSave, this.auth, updatedObject, originalObject, this.config, this.context); + }).then(response => { + if (response && response.object) { + this.storage.fieldsChangedByTrigger = _lodash.default.reduce(response.object, (result, value, key) => { + if (!_lodash.default.isEqual(this.data[key], value)) { + result.push(key); + } + + return result; + }, []); + this.data = response.object; // We should delete the objectId for an update write + + if (this.query && this.query.objectId) { + delete this.data.objectId; + } + } + }); +}; + +RestWrite.prototype.runBeforeLoginTrigger = async function (userData) { + // Avoid doing any setup for triggers if there is no 'beforeLogin' trigger + if (!triggers.triggerExists(this.className, triggers.Types.beforeLogin, this.config.applicationId)) { + return; + } // Cloud code gets a bit of extra data for its objects + + + const extraData = { + className: this.className + }; // Expand file objects + + this.config.filesController.expandFilesInObject(this.config, userData); + const user = triggers.inflate(extraData, userData); // no need to return a response + + await triggers.maybeRunTrigger(triggers.Types.beforeLogin, this.auth, user, null, this.config, this.context); +}; + +RestWrite.prototype.setRequiredFieldsIfNeeded = function () { + if (this.data) { + return this.validSchemaController.getAllClasses().then(allClasses => { + const schema = allClasses.find(oneClass => oneClass.className === this.className); + + const setRequiredFieldIfNeeded = (fieldName, setDefault) => { + if (this.data[fieldName] === undefined || this.data[fieldName] === null || this.data[fieldName] === '' || typeof this.data[fieldName] === 'object' && this.data[fieldName].__op === 'Delete') { + if (setDefault && schema.fields[fieldName] && schema.fields[fieldName].defaultValue !== null && schema.fields[fieldName].defaultValue !== undefined && (this.data[fieldName] === undefined || typeof this.data[fieldName] === 'object' && this.data[fieldName].__op === 'Delete')) { + this.data[fieldName] = schema.fields[fieldName].defaultValue; + this.storage.fieldsChangedByTrigger = this.storage.fieldsChangedByTrigger || []; + + if (this.storage.fieldsChangedByTrigger.indexOf(fieldName) < 0) { + this.storage.fieldsChangedByTrigger.push(fieldName); + } + } else if (schema.fields[fieldName] && schema.fields[fieldName].required === true) { + throw new Parse.Error(Parse.Error.VALIDATION_ERROR, `${fieldName} is required`); + } + } + }; // Add default fields + + + this.data.updatedAt = this.updatedAt; + + if (!this.query) { + this.data.createdAt = this.updatedAt; // Only assign new objectId if we are creating new object + + if (!this.data.objectId) { + this.data.objectId = cryptoUtils.newObjectId(this.config.objectIdSize); + } + + if (schema) { + Object.keys(schema.fields).forEach(fieldName => { + setRequiredFieldIfNeeded(fieldName, true); + }); + } + } else if (schema) { + Object.keys(this.data).forEach(fieldName => { + setRequiredFieldIfNeeded(fieldName, false); + }); + } + }); + } + + return Promise.resolve(); +}; // Transforms auth data for a user object. +// Does nothing if this isn't a user object. +// Returns a promise for when we're done if it can't finish this tick. + + +RestWrite.prototype.validateAuthData = function () { + if (this.className !== '_User') { + return; + } + + if (!this.query && !this.data.authData) { + if (typeof this.data.username !== 'string' || _lodash.default.isEmpty(this.data.username)) { + throw new Parse.Error(Parse.Error.USERNAME_MISSING, 'bad or missing username'); + } + + if (typeof this.data.password !== 'string' || _lodash.default.isEmpty(this.data.password)) { + throw new Parse.Error(Parse.Error.PASSWORD_MISSING, 'password is required'); + } + } + + if (this.data.authData && !Object.keys(this.data.authData).length || !Object.prototype.hasOwnProperty.call(this.data, 'authData')) { + // Handle saving authData to {} or if authData doesn't exist + return; + } else if (Object.prototype.hasOwnProperty.call(this.data, 'authData') && !this.data.authData) { + // Handle saving authData to null + throw new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE, 'This authentication method is unsupported.'); + } + + var authData = this.data.authData; + var providers = Object.keys(authData); + + if (providers.length > 0) { + const canHandleAuthData = providers.reduce((canHandle, provider) => { + var providerAuthData = authData[provider]; + var hasToken = providerAuthData && providerAuthData.id; + return canHandle && (hasToken || providerAuthData == null); + }, true); + + if (canHandleAuthData) { + return this.handleAuthData(authData); + } + } + + throw new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE, 'This authentication method is unsupported.'); +}; + +RestWrite.prototype.handleAuthDataValidation = function (authData) { + const validations = Object.keys(authData).map(provider => { + if (authData[provider] === null) { + return Promise.resolve(); + } + + const validateAuthData = this.config.authDataManager.getValidatorForProvider(provider); + + if (!validateAuthData) { + throw new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE, 'This authentication method is unsupported.'); + } + + return validateAuthData(authData[provider]); + }); + return Promise.all(validations); +}; + +RestWrite.prototype.findUsersWithAuthData = function (authData) { + const providers = Object.keys(authData); + const query = providers.reduce((memo, provider) => { + if (!authData[provider]) { + return memo; + } + + const queryKey = `authData.${provider}.id`; + const query = {}; + query[queryKey] = authData[provider].id; + memo.push(query); + return memo; + }, []).filter(q => { + return typeof q !== 'undefined'; + }); + let findPromise = Promise.resolve([]); + + if (query.length > 0) { + findPromise = this.config.database.find(this.className, { + $or: query + }, {}); + } + + return findPromise; +}; + +RestWrite.prototype.filteredObjectsByACL = function (objects) { + if (this.auth.isMaster) { + return objects; + } + + return objects.filter(object => { + if (!object.ACL) { + return true; // legacy users that have no ACL field on them + } // Regular users that have been locked out. + + + return object.ACL && Object.keys(object.ACL).length > 0; + }); +}; + +RestWrite.prototype.handleAuthData = function (authData) { + let results; + return this.findUsersWithAuthData(authData).then(async r => { + results = this.filteredObjectsByACL(r); + + if (results.length == 1) { + this.storage['authProvider'] = Object.keys(authData).join(','); + const userResult = results[0]; + const mutatedAuthData = {}; + Object.keys(authData).forEach(provider => { + const providerData = authData[provider]; + const userAuthData = userResult.authData[provider]; + + if (!_lodash.default.isEqual(providerData, userAuthData)) { + mutatedAuthData[provider] = providerData; + } + }); + const hasMutatedAuthData = Object.keys(mutatedAuthData).length !== 0; + let userId; + + if (this.query && this.query.objectId) { + userId = this.query.objectId; + } else if (this.auth && this.auth.user && this.auth.user.id) { + userId = this.auth.user.id; + } + + if (!userId || userId === userResult.objectId) { + // no user making the call + // OR the user making the call is the right one + // Login with auth data + delete results[0].password; // need to set the objectId first otherwise location has trailing undefined + + this.data.objectId = userResult.objectId; + + if (!this.query || !this.query.objectId) { + // this a login call, no userId passed + this.response = { + response: userResult, + location: this.location() + }; // Run beforeLogin hook before storing any updates + // to authData on the db; changes to userResult + // will be ignored. + + await this.runBeforeLoginTrigger(deepcopy(userResult)); + } // If we didn't change the auth data, just keep going + + + if (!hasMutatedAuthData) { + return; + } // We have authData that is updated on login + // that can happen when token are refreshed, + // We should update the token and let the user in + // We should only check the mutated keys + + + return this.handleAuthDataValidation(mutatedAuthData).then(async () => { + // IF we have a response, we'll skip the database operation / beforeSave / afterSave etc... + // we need to set it up there. + // We are supposed to have a response only on LOGIN with authData, so we skip those + // If we're not logging in, but just updating the current user, we can safely skip that part + if (this.response) { + // Assign the new authData in the response + Object.keys(mutatedAuthData).forEach(provider => { + this.response.response.authData[provider] = mutatedAuthData[provider]; + }); // Run the DB update directly, as 'master' + // Just update the authData part + // Then we're good for the user, early exit of sorts + + return this.config.database.update(this.className, { + objectId: this.data.objectId + }, { + authData: mutatedAuthData + }, {}); + } + }); + } else if (userId) { + // Trying to update auth data but users + // are different + if (userResult.objectId !== userId) { + throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used'); + } // No auth data was mutated, just keep going + + + if (!hasMutatedAuthData) { + return; + } + } + } + + return this.handleAuthDataValidation(authData).then(() => { + if (results.length > 1) { + // More than 1 user with the passed id's + throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used'); + } + }); + }); +}; // The non-third-party parts of User transformation + + +RestWrite.prototype.transformUser = function () { + var promise = Promise.resolve(); + + if (this.className !== '_User') { + return promise; + } + + if (!this.auth.isMaster && 'emailVerified' in this.data) { + const error = `Clients aren't allowed to manually update email verification.`; + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); + } // Do not cleanup session if objectId is not set + + + if (this.query && this.objectId()) { + // If we're updating a _User object, we need to clear out the cache for that user. Find all their + // session tokens, and remove them from the cache. + promise = new _RestQuery.default(this.config, Auth.master(this.config), '_Session', { + user: { + __type: 'Pointer', + className: '_User', + objectId: this.objectId() + } + }).execute().then(results => { + results.results.forEach(session => this.config.cacheController.user.del(session.sessionToken)); + }); + } + + return promise.then(() => { + // Transform the password + if (this.data.password === undefined) { + // ignore only if undefined. should proceed if empty ('') + return Promise.resolve(); + } + + if (this.query) { + this.storage['clearSessions'] = true; // Generate a new session only if the user requested + + if (!this.auth.isMaster) { + this.storage['generateNewSession'] = true; + } + } + + return this._validatePasswordPolicy().then(() => { + return passwordCrypto.hash(this.data.password).then(hashedPassword => { + this.data._hashed_password = hashedPassword; + delete this.data.password; + }); + }); + }).then(() => { + return this._validateUserName(); + }).then(() => { + return this._validateEmail(); + }); +}; + +RestWrite.prototype._validateUserName = function () { + // Check for username uniqueness + if (!this.data.username) { + if (!this.query) { + this.data.username = cryptoUtils.randomString(25); + this.responseShouldHaveUsername = true; + } + + return Promise.resolve(); + } + /* + Usernames should be unique when compared case insensitively + Users should be able to make case sensitive usernames and + login using the case they entered. I.e. 'Snoopy' should preclude + 'snoopy' as a valid username. + */ + + + return this.config.database.find(this.className, { + username: this.data.username, + objectId: { + $ne: this.objectId() + } + }, { + limit: 1, + caseInsensitive: true + }, {}, this.validSchemaController).then(results => { + if (results.length > 0) { + throw new Parse.Error(Parse.Error.USERNAME_TAKEN, 'Account already exists for this username.'); + } + + return; + }); +}; +/* + As with usernames, Parse should not allow case insensitive collisions of email. + unlike with usernames (which can have case insensitive collisions in the case of + auth adapters), emails should never have a case insensitive collision. + + This behavior can be enforced through a properly configured index see: + https://docs.mongodb.com/manual/core/index-case-insensitive/#create-a-case-insensitive-index + which could be implemented instead of this code based validation. + + Given that this lookup should be a relatively low use case and that the case sensitive + unique index will be used by the db for the query, this is an adequate solution. +*/ + + +RestWrite.prototype._validateEmail = function () { + if (!this.data.email || this.data.email.__op === 'Delete') { + return Promise.resolve(); + } // Validate basic email address format + + + if (!this.data.email.match(/^.+@.+$/)) { + return Promise.reject(new Parse.Error(Parse.Error.INVALID_EMAIL_ADDRESS, 'Email address format is invalid.')); + } // Case insensitive match, see note above function. + + + return this.config.database.find(this.className, { + email: this.data.email, + objectId: { + $ne: this.objectId() + } + }, { + limit: 1, + caseInsensitive: true + }, {}, this.validSchemaController).then(results => { + if (results.length > 0) { + throw new Parse.Error(Parse.Error.EMAIL_TAKEN, 'Account already exists for this email address.'); + } + + if (!this.data.authData || !Object.keys(this.data.authData).length || Object.keys(this.data.authData).length === 1 && Object.keys(this.data.authData)[0] === 'anonymous') { + // We updated the email, send a new validation + this.storage['sendVerificationEmail'] = true; + this.config.userController.setEmailVerifyToken(this.data); + } + }); +}; + +RestWrite.prototype._validatePasswordPolicy = function () { + if (!this.config.passwordPolicy) return Promise.resolve(); + return this._validatePasswordRequirements().then(() => { + return this._validatePasswordHistory(); + }); +}; + +RestWrite.prototype._validatePasswordRequirements = function () { + // check if the password conforms to the defined password policy if configured + // If we specified a custom error in our configuration use it. + // Example: "Passwords must include a Capital Letter, Lowercase Letter, and a number." + // + // This is especially useful on the generic "password reset" page, + // as it allows the programmer to communicate specific requirements instead of: + // a. making the user guess whats wrong + // b. making a custom password reset page that shows the requirements + const policyError = this.config.passwordPolicy.validationError ? this.config.passwordPolicy.validationError : 'Password does not meet the Password Policy requirements.'; + const containsUsernameError = 'Password cannot contain your username.'; // check whether the password meets the password strength requirements + + if (this.config.passwordPolicy.patternValidator && !this.config.passwordPolicy.patternValidator(this.data.password) || this.config.passwordPolicy.validatorCallback && !this.config.passwordPolicy.validatorCallback(this.data.password)) { + return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, policyError)); + } // check whether password contain username + + + if (this.config.passwordPolicy.doNotAllowUsername === true) { + if (this.data.username) { + // username is not passed during password reset + if (this.data.password.indexOf(this.data.username) >= 0) return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, containsUsernameError)); + } else { + // retrieve the User object using objectId during password reset + return this.config.database.find('_User', { + objectId: this.objectId() + }).then(results => { + if (results.length != 1) { + throw undefined; + } + + if (this.data.password.indexOf(results[0].username) >= 0) return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, containsUsernameError)); + return Promise.resolve(); + }); + } + } + + return Promise.resolve(); +}; + +RestWrite.prototype._validatePasswordHistory = function () { + // check whether password is repeating from specified history + if (this.query && this.config.passwordPolicy.maxPasswordHistory) { + return this.config.database.find('_User', { + objectId: this.objectId() + }, { + keys: ['_password_history', '_hashed_password'] + }).then(results => { + if (results.length != 1) { + throw undefined; + } + + const user = results[0]; + let oldPasswords = []; + if (user._password_history) oldPasswords = _lodash.default.take(user._password_history, this.config.passwordPolicy.maxPasswordHistory - 1); + oldPasswords.push(user.password); + const newPassword = this.data.password; // compare the new password hash with all old password hashes + + const promises = oldPasswords.map(function (hash) { + return passwordCrypto.compare(newPassword, hash).then(result => { + if (result) // reject if there is a match + return Promise.reject('REPEAT_PASSWORD'); + return Promise.resolve(); + }); + }); // wait for all comparisons to complete + + return Promise.all(promises).then(() => { + return Promise.resolve(); + }).catch(err => { + if (err === 'REPEAT_PASSWORD') // a match was found + return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, `New password should not be the same as last ${this.config.passwordPolicy.maxPasswordHistory} passwords.`)); + throw err; + }); + }); + } + + return Promise.resolve(); +}; + +RestWrite.prototype.createSessionTokenIfNeeded = function () { + if (this.className !== '_User') { + return; + } // Don't generate session for updating user (this.query is set) unless authData exists + + + if (this.query && !this.data.authData) { + return; + } // Don't generate new sessionToken if linking via sessionToken + + + if (this.auth.user && this.data.authData) { + return; + } + + if (!this.storage['authProvider'] && // signup call, with + this.config.preventLoginWithUnverifiedEmail && // no login without verification + this.config.verifyUserEmails) { + // verification is on + return; // do not create the session token in that case! + } + + return this.createSessionToken(); +}; + +RestWrite.prototype.createSessionToken = async function () { + // cloud installationId from Cloud Code, + // never create session tokens from there. + if (this.auth.installationId && this.auth.installationId === 'cloud') { + return; + } + + const { + sessionData, + createSession + } = Auth.createSession(this.config, { + userId: this.objectId(), + createdWith: { + action: this.storage['authProvider'] ? 'login' : 'signup', + authProvider: this.storage['authProvider'] || 'password' + }, + installationId: this.auth.installationId + }); + + if (this.response && this.response.response) { + this.response.response.sessionToken = sessionData.sessionToken; + } + + return createSession(); +}; // Delete email reset tokens if user is changing password or email. + + +RestWrite.prototype.deleteEmailResetTokenIfNeeded = function () { + if (this.className !== '_User' || this.query === null) { + // null query means create + return; + } + + if ('password' in this.data || 'email' in this.data) { + const addOps = { + _perishable_token: { + __op: 'Delete' + }, + _perishable_token_expires_at: { + __op: 'Delete' + } + }; + this.data = Object.assign(this.data, addOps); + } +}; + +RestWrite.prototype.destroyDuplicatedSessions = function () { + // Only for _Session, and at creation time + if (this.className != '_Session' || this.query) { + return; + } // Destroy the sessions in 'Background' + + + const { + user, + installationId, + sessionToken + } = this.data; + + if (!user || !installationId) { + return; + } + + if (!user.objectId) { + return; + } + + this.config.database.destroy('_Session', { + user, + installationId, + sessionToken: { + $ne: sessionToken + } + }, {}, this.validSchemaController); +}; // Handles any followup logic + + +RestWrite.prototype.handleFollowup = function () { + if (this.storage && this.storage['clearSessions'] && this.config.revokeSessionOnPasswordReset) { + var sessionQuery = { + user: { + __type: 'Pointer', + className: '_User', + objectId: this.objectId() + } + }; + delete this.storage['clearSessions']; + return this.config.database.destroy('_Session', sessionQuery).then(this.handleFollowup.bind(this)); + } + + if (this.storage && this.storage['generateNewSession']) { + delete this.storage['generateNewSession']; + return this.createSessionToken().then(this.handleFollowup.bind(this)); + } + + if (this.storage && this.storage['sendVerificationEmail']) { + delete this.storage['sendVerificationEmail']; // Fire and forget! + + this.config.userController.sendVerificationEmail(this.data); + return this.handleFollowup.bind(this); + } +}; // Handles the _Session class specialness. +// Does nothing if this isn't an _Session object. + + +RestWrite.prototype.handleSession = function () { + if (this.response || this.className !== '_Session') { + return; + } + + if (!this.auth.user && !this.auth.isMaster) { + throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Session token required.'); + } // TODO: Verify proper error to throw + + + if (this.data.ACL) { + throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'Cannot set ' + 'ACL on a Session.'); + } + + if (this.query) { + if (this.data.user && !this.auth.isMaster && this.data.user.objectId != this.auth.user.id) { + throw new Parse.Error(Parse.Error.INVALID_KEY_NAME); + } else if (this.data.installationId) { + throw new Parse.Error(Parse.Error.INVALID_KEY_NAME); + } else if (this.data.sessionToken) { + throw new Parse.Error(Parse.Error.INVALID_KEY_NAME); + } + } + + if (!this.query && !this.auth.isMaster) { + const additionalSessionData = {}; + + for (var key in this.data) { + if (key === 'objectId' || key === 'user') { + continue; + } + + additionalSessionData[key] = this.data[key]; + } + + const { + sessionData, + createSession + } = Auth.createSession(this.config, { + userId: this.auth.user.id, + createdWith: { + action: 'create' + }, + additionalSessionData + }); + return createSession().then(results => { + if (!results.response) { + throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Error creating session.'); + } + + sessionData['objectId'] = results.response['objectId']; + this.response = { + status: 201, + location: results.location, + response: sessionData + }; + }); + } +}; // Handles the _Installation class specialness. +// Does nothing if this isn't an installation object. +// If an installation is found, this can mutate this.query and turn a create +// into an update. +// Returns a promise for when we're done if it can't finish this tick. + + +RestWrite.prototype.handleInstallation = function () { + if (this.response || this.className !== '_Installation') { + return; + } + + if (!this.query && !this.data.deviceToken && !this.data.installationId && !this.auth.installationId) { + throw new Parse.Error(135, 'at least one ID field (deviceToken, installationId) ' + 'must be specified in this operation'); + } // If the device token is 64 characters long, we assume it is for iOS + // and lowercase it. + + + if (this.data.deviceToken && this.data.deviceToken.length == 64) { + this.data.deviceToken = this.data.deviceToken.toLowerCase(); + } // We lowercase the installationId if present + + + if (this.data.installationId) { + this.data.installationId = this.data.installationId.toLowerCase(); + } + + let installationId = this.data.installationId; // If data.installationId is not set and we're not master, we can lookup in auth + + if (!installationId && !this.auth.isMaster) { + installationId = this.auth.installationId; + } + + if (installationId) { + installationId = installationId.toLowerCase(); + } // Updating _Installation but not updating anything critical + + + if (this.query && !this.data.deviceToken && !installationId && !this.data.deviceType) { + return; + } + + var promise = Promise.resolve(); + var idMatch; // Will be a match on either objectId or installationId + + var objectIdMatch; + var installationIdMatch; + var deviceTokenMatches = []; // Instead of issuing 3 reads, let's do it with one OR. + + const orQueries = []; + + if (this.query && this.query.objectId) { + orQueries.push({ + objectId: this.query.objectId + }); + } + + if (installationId) { + orQueries.push({ + installationId: installationId + }); + } + + if (this.data.deviceToken) { + orQueries.push({ + deviceToken: this.data.deviceToken + }); + } + + if (orQueries.length == 0) { + return; + } + + promise = promise.then(() => { + return this.config.database.find('_Installation', { + $or: orQueries + }, {}); + }).then(results => { + results.forEach(result => { + if (this.query && this.query.objectId && result.objectId == this.query.objectId) { + objectIdMatch = result; + } + + if (result.installationId == installationId) { + installationIdMatch = result; + } + + if (result.deviceToken == this.data.deviceToken) { + deviceTokenMatches.push(result); + } + }); // Sanity checks when running a query + + if (this.query && this.query.objectId) { + if (!objectIdMatch) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found for update.'); + } + + if (this.data.installationId && objectIdMatch.installationId && this.data.installationId !== objectIdMatch.installationId) { + throw new Parse.Error(136, 'installationId may not be changed in this ' + 'operation'); + } + + if (this.data.deviceToken && objectIdMatch.deviceToken && this.data.deviceToken !== objectIdMatch.deviceToken && !this.data.installationId && !objectIdMatch.installationId) { + throw new Parse.Error(136, 'deviceToken may not be changed in this ' + 'operation'); + } + + if (this.data.deviceType && this.data.deviceType && this.data.deviceType !== objectIdMatch.deviceType) { + throw new Parse.Error(136, 'deviceType may not be changed in this ' + 'operation'); + } + } + + if (this.query && this.query.objectId && objectIdMatch) { + idMatch = objectIdMatch; + } + + if (installationId && installationIdMatch) { + idMatch = installationIdMatch; + } // need to specify deviceType only if it's new + + + if (!this.query && !this.data.deviceType && !idMatch) { + throw new Parse.Error(135, 'deviceType must be specified in this operation'); + } + }).then(() => { + if (!idMatch) { + if (!deviceTokenMatches.length) { + return; + } else if (deviceTokenMatches.length == 1 && (!deviceTokenMatches[0]['installationId'] || !installationId)) { + // Single match on device token but none on installationId, and either + // the passed object or the match is missing an installationId, so we + // can just return the match. + return deviceTokenMatches[0]['objectId']; + } else if (!this.data.installationId) { + throw new Parse.Error(132, 'Must specify installationId when deviceToken ' + 'matches multiple Installation objects'); + } else { + // Multiple device token matches and we specified an installation ID, + // or a single match where both the passed and matching objects have + // an installation ID. Try cleaning out old installations that match + // the deviceToken, and return nil to signal that a new object should + // be created. + var delQuery = { + deviceToken: this.data.deviceToken, + installationId: { + $ne: installationId + } + }; + + if (this.data.appIdentifier) { + delQuery['appIdentifier'] = this.data.appIdentifier; + } + + this.config.database.destroy('_Installation', delQuery).catch(err => { + if (err.code == Parse.Error.OBJECT_NOT_FOUND) { + // no deletions were made. Can be ignored. + return; + } // rethrow the error + + + throw err; + }); + return; + } + } else { + if (deviceTokenMatches.length == 1 && !deviceTokenMatches[0]['installationId']) { + // Exactly one device token match and it doesn't have an installation + // ID. This is the one case where we want to merge with the existing + // object. + const delQuery = { + objectId: idMatch.objectId + }; + return this.config.database.destroy('_Installation', delQuery).then(() => { + return deviceTokenMatches[0]['objectId']; + }).catch(err => { + if (err.code == Parse.Error.OBJECT_NOT_FOUND) { + // no deletions were made. Can be ignored + return; + } // rethrow the error + + + throw err; + }); + } else { + if (this.data.deviceToken && idMatch.deviceToken != this.data.deviceToken) { + // We're setting the device token on an existing installation, so + // we should try cleaning out old installations that match this + // device token. + const delQuery = { + deviceToken: this.data.deviceToken + }; // We have a unique install Id, use that to preserve + // the interesting installation + + if (this.data.installationId) { + delQuery['installationId'] = { + $ne: this.data.installationId + }; + } else if (idMatch.objectId && this.data.objectId && idMatch.objectId == this.data.objectId) { + // we passed an objectId, preserve that instalation + delQuery['objectId'] = { + $ne: idMatch.objectId + }; + } else { + // What to do here? can't really clean up everything... + return idMatch.objectId; + } + + if (this.data.appIdentifier) { + delQuery['appIdentifier'] = this.data.appIdentifier; + } + + this.config.database.destroy('_Installation', delQuery).catch(err => { + if (err.code == Parse.Error.OBJECT_NOT_FOUND) { + // no deletions were made. Can be ignored. + return; + } // rethrow the error + + + throw err; + }); + } // In non-merge scenarios, just return the installation match id + + + return idMatch.objectId; + } + } + }).then(objId => { + if (objId) { + this.query = { + objectId: objId + }; + delete this.data.objectId; + delete this.data.createdAt; + } // TODO: Validate ops (add/remove on channels, $inc on badge, etc.) + + }); + return promise; +}; // If we short-circuted the object response - then we need to make sure we expand all the files, +// since this might not have a query, meaning it won't return the full result back. +// TODO: (nlutsenko) This should die when we move to per-class based controllers on _Session/_User + + +RestWrite.prototype.expandFilesForExistingObjects = function () { + // Check whether we have a short-circuited response - only then run expansion. + if (this.response && this.response.response) { + this.config.filesController.expandFilesInObject(this.config, this.response.response); + } +}; + +RestWrite.prototype.runDatabaseOperation = function () { + if (this.response) { + return; + } + + if (this.className === '_Role') { + this.config.cacheController.role.clear(); + } + + if (this.className === '_User' && this.query && this.auth.isUnauthenticated()) { + throw new Parse.Error(Parse.Error.SESSION_MISSING, `Cannot modify user ${this.query.objectId}.`); + } + + if (this.className === '_Product' && this.data.download) { + this.data.downloadName = this.data.download.name; + } // TODO: Add better detection for ACL, ensuring a user can't be locked from + // their own user record. + + + if (this.data.ACL && this.data.ACL['*unresolved']) { + throw new Parse.Error(Parse.Error.INVALID_ACL, 'Invalid ACL.'); + } + + if (this.query) { + // Force the user to not lockout + // Matched with parse.com + if (this.className === '_User' && this.data.ACL && this.auth.isMaster !== true) { + this.data.ACL[this.query.objectId] = { + read: true, + write: true + }; + } // update password timestamp if user password is being changed + + + if (this.className === '_User' && this.data._hashed_password && this.config.passwordPolicy && this.config.passwordPolicy.maxPasswordAge) { + this.data._password_changed_at = Parse._encode(new Date()); + } // Ignore createdAt when update + + + delete this.data.createdAt; + let defer = Promise.resolve(); // if password history is enabled then save the current password to history + + if (this.className === '_User' && this.data._hashed_password && this.config.passwordPolicy && this.config.passwordPolicy.maxPasswordHistory) { + defer = this.config.database.find('_User', { + objectId: this.objectId() + }, { + keys: ['_password_history', '_hashed_password'] + }).then(results => { + if (results.length != 1) { + throw undefined; + } + + const user = results[0]; + let oldPasswords = []; + + if (user._password_history) { + oldPasswords = _lodash.default.take(user._password_history, this.config.passwordPolicy.maxPasswordHistory); + } //n-1 passwords go into history including last password + + + while (oldPasswords.length > Math.max(0, this.config.passwordPolicy.maxPasswordHistory - 2)) { + oldPasswords.shift(); + } + + oldPasswords.push(user.password); + this.data._password_history = oldPasswords; + }); + } + + return defer.then(() => { + // Run an update + return this.config.database.update(this.className, this.query, this.data, this.runOptions, false, false, this.validSchemaController).then(response => { + response.updatedAt = this.updatedAt; + + this._updateResponseWithData(response, this.data); + + this.response = { + response + }; + }); + }); + } else { + // Set the default ACL and password timestamp for the new _User + if (this.className === '_User') { + var ACL = this.data.ACL; // default public r/w ACL + + if (!ACL) { + ACL = {}; + ACL['*'] = { + read: true, + write: false + }; + } // make sure the user is not locked down + + + ACL[this.data.objectId] = { + read: true, + write: true + }; + this.data.ACL = ACL; // password timestamp to be used when password expiry policy is enforced + + if (this.config.passwordPolicy && this.config.passwordPolicy.maxPasswordAge) { + this.data._password_changed_at = Parse._encode(new Date()); + } + } // Run a create + + + return this.config.database.create(this.className, this.data, this.runOptions, false, this.validSchemaController).catch(error => { + if (this.className !== '_User' || error.code !== Parse.Error.DUPLICATE_VALUE) { + throw error; + } // Quick check, if we were able to infer the duplicated field name + + + if (error && error.userInfo && error.userInfo.duplicated_field === 'username') { + throw new Parse.Error(Parse.Error.USERNAME_TAKEN, 'Account already exists for this username.'); + } + + if (error && error.userInfo && error.userInfo.duplicated_field === 'email') { + throw new Parse.Error(Parse.Error.EMAIL_TAKEN, 'Account already exists for this email address.'); + } // If this was a failed user creation due to username or email already taken, we need to + // check whether it was username or email and return the appropriate error. + // Fallback to the original method + // TODO: See if we can later do this without additional queries by using named indexes. + + + return this.config.database.find(this.className, { + username: this.data.username, + objectId: { + $ne: this.objectId() + } + }, { + limit: 1 + }).then(results => { + if (results.length > 0) { + throw new Parse.Error(Parse.Error.USERNAME_TAKEN, 'Account already exists for this username.'); + } + + return this.config.database.find(this.className, { + email: this.data.email, + objectId: { + $ne: this.objectId() + } + }, { + limit: 1 + }); + }).then(results => { + if (results.length > 0) { + throw new Parse.Error(Parse.Error.EMAIL_TAKEN, 'Account already exists for this email address.'); + } + + throw new Parse.Error(Parse.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); + }); + }).then(response => { + response.objectId = this.data.objectId; + response.createdAt = this.data.createdAt; + + if (this.responseShouldHaveUsername) { + response.username = this.data.username; + } + + this._updateResponseWithData(response, this.data); + + this.response = { + status: 201, + response, + location: this.location() + }; + }); + } +}; // Returns nothing - doesn't wait for the trigger. + + +RestWrite.prototype.runAfterSaveTrigger = function () { + if (!this.response || !this.response.response) { + return; + } // Avoid doing any setup for triggers if there is no 'afterSave' trigger for this class. + + + const hasAfterSaveHook = triggers.triggerExists(this.className, triggers.Types.afterSave, this.config.applicationId); + const hasLiveQuery = this.config.liveQueryController.hasLiveQuery(this.className); + + if (!hasAfterSaveHook && !hasLiveQuery) { + return Promise.resolve(); + } + + var extraData = { + className: this.className + }; + + if (this.query && this.query.objectId) { + extraData.objectId = this.query.objectId; + } // Build the original object, we only do this for a update write. + + + let originalObject; + + if (this.query && this.query.objectId) { + originalObject = triggers.inflate(extraData, this.originalData); + } // Build the inflated object, different from beforeSave, originalData is not empty + // since developers can change data in the beforeSave. + + + const updatedObject = this.buildUpdatedObject(extraData); + + updatedObject._handleSaveResponse(this.response.response, this.response.status || 200); + + this.config.database.loadSchema().then(schemaController => { + // Notifiy LiveQueryServer if possible + const perms = schemaController.getClassLevelPermissions(updatedObject.className); + this.config.liveQueryController.onAfterSave(updatedObject.className, updatedObject, originalObject, perms); + }); // Run afterSave trigger + + return triggers.maybeRunTrigger(triggers.Types.afterSave, this.auth, updatedObject, originalObject, this.config, this.context).then(result => { + if (result && typeof result === 'object') { + this.response.response = result; + } + }).catch(function (err) { + _logger.default.warn('afterSave caught an error', err); + }); +}; // A helper to figure out what location this operation happens at. + + +RestWrite.prototype.location = function () { + var middle = this.className === '_User' ? '/users/' : '/classes/' + this.className + '/'; + const mount = this.config.mount || this.config.serverURL; + return mount + middle + this.data.objectId; +}; // A helper to get the object id for this operation. +// Because it could be either on the query or on the data + + +RestWrite.prototype.objectId = function () { + return this.data.objectId || this.query.objectId; +}; // Returns a copy of the data and delete bad keys (_auth_data, _hashed_password...) + + +RestWrite.prototype.sanitizedData = function () { + const data = Object.keys(this.data).reduce((data, key) => { + // Regexp comes from Parse.Object.prototype.validate + if (!/^[A-Za-z][0-9A-Za-z_]*$/.test(key)) { + delete data[key]; + } + + return data; + }, deepcopy(this.data)); + return Parse._decode(undefined, data); +}; // Returns an updated copy of the object + + +RestWrite.prototype.buildUpdatedObject = function (extraData) { + const updatedObject = triggers.inflate(extraData, this.originalData); + Object.keys(this.data).reduce(function (data, key) { + if (key.indexOf('.') > 0) { + if (typeof data[key].__op === 'string') { + updatedObject.set(key, data[key]); + } else { + // subdocument key with dot notation { 'x.y': v } => { 'x': { 'y' : v } }) + const splittedKey = key.split('.'); + const parentProp = splittedKey[0]; + let parentVal = updatedObject.get(parentProp); + + if (typeof parentVal !== 'object') { + parentVal = {}; + } + + parentVal[splittedKey[1]] = data[key]; + updatedObject.set(parentProp, parentVal); + } + + delete data[key]; + } + + return data; + }, deepcopy(this.data)); + updatedObject.set(this.sanitizedData()); + return updatedObject; +}; + +RestWrite.prototype.cleanUserAuthData = function () { + if (this.response && this.response.response && this.className === '_User') { + const user = this.response.response; + + if (user.authData) { + Object.keys(user.authData).forEach(provider => { + if (user.authData[provider] === null) { + delete user.authData[provider]; + } + }); + + if (Object.keys(user.authData).length == 0) { + delete user.authData; + } + } + } +}; + +RestWrite.prototype._updateResponseWithData = function (response, data) { + if (_lodash.default.isEmpty(this.storage.fieldsChangedByTrigger)) { + return response; + } + + const clientSupportsDelete = ClientSDK.supportsForwardDelete(this.clientSDK); + this.storage.fieldsChangedByTrigger.forEach(fieldName => { + const dataValue = data[fieldName]; + + if (!Object.prototype.hasOwnProperty.call(response, fieldName)) { + response[fieldName] = dataValue; + } // Strips operations from responses + + + if (response[fieldName] && response[fieldName].__op) { + delete response[fieldName]; + + if (clientSupportsDelete && dataValue.__op == 'Delete') { + response[fieldName] = dataValue; + } + } + }); + return response; +}; + +var _default = RestWrite; +exports.default = _default; +module.exports = RestWrite; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9SZXN0V3JpdGUuanMiXSwibmFtZXMiOlsiU2NoZW1hQ29udHJvbGxlciIsInJlcXVpcmUiLCJkZWVwY29weSIsIkF1dGgiLCJjcnlwdG9VdGlscyIsInBhc3N3b3JkQ3J5cHRvIiwiUGFyc2UiLCJ0cmlnZ2VycyIsIkNsaWVudFNESyIsIlJlc3RXcml0ZSIsImNvbmZpZyIsImF1dGgiLCJjbGFzc05hbWUiLCJxdWVyeSIsImRhdGEiLCJvcmlnaW5hbERhdGEiLCJjbGllbnRTREsiLCJjb250ZXh0IiwiYWN0aW9uIiwiaXNSZWFkT25seSIsIkVycm9yIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsInN0b3JhZ2UiLCJydW5PcHRpb25zIiwiYWxsb3dDdXN0b21PYmplY3RJZCIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIm9iamVjdElkIiwiTUlTU0lOR19PQkpFQ1RfSUQiLCJJTlZBTElEX0tFWV9OQU1FIiwiaWQiLCJyZXNwb25zZSIsInVwZGF0ZWRBdCIsIl9lbmNvZGUiLCJEYXRlIiwiaXNvIiwidmFsaWRTY2hlbWFDb250cm9sbGVyIiwiZXhlY3V0ZSIsIlByb21pc2UiLCJyZXNvbHZlIiwidGhlbiIsImdldFVzZXJBbmRSb2xlQUNMIiwidmFsaWRhdGVDbGllbnRDbGFzc0NyZWF0aW9uIiwiaGFuZGxlSW5zdGFsbGF0aW9uIiwiaGFuZGxlU2Vzc2lvbiIsInZhbGlkYXRlQXV0aERhdGEiLCJydW5CZWZvcmVTYXZlVHJpZ2dlciIsImRlbGV0ZUVtYWlsUmVzZXRUb2tlbklmTmVlZGVkIiwidmFsaWRhdGVTY2hlbWEiLCJzY2hlbWFDb250cm9sbGVyIiwic2V0UmVxdWlyZWRGaWVsZHNJZk5lZWRlZCIsInRyYW5zZm9ybVVzZXIiLCJleHBhbmRGaWxlc0ZvckV4aXN0aW5nT2JqZWN0cyIsImRlc3Ryb3lEdXBsaWNhdGVkU2Vzc2lvbnMiLCJydW5EYXRhYmFzZU9wZXJhdGlvbiIsImNyZWF0ZVNlc3Npb25Ub2tlbklmTmVlZGVkIiwiaGFuZGxlRm9sbG93dXAiLCJydW5BZnRlclNhdmVUcmlnZ2VyIiwiY2xlYW5Vc2VyQXV0aERhdGEiLCJpc01hc3RlciIsImFjbCIsInVzZXIiLCJnZXRVc2VyUm9sZXMiLCJyb2xlcyIsImNvbmNhdCIsImFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbiIsInN5c3RlbUNsYXNzZXMiLCJpbmRleE9mIiwiZGF0YWJhc2UiLCJsb2FkU2NoZW1hIiwiaGFzQ2xhc3MiLCJ2YWxpZGF0ZU9iamVjdCIsInRyaWdnZXJFeGlzdHMiLCJUeXBlcyIsImJlZm9yZVNhdmUiLCJhcHBsaWNhdGlvbklkIiwiZXh0cmFEYXRhIiwib3JpZ2luYWxPYmplY3QiLCJ1cGRhdGVkT2JqZWN0IiwiYnVpbGRVcGRhdGVkT2JqZWN0IiwiaW5mbGF0ZSIsImRhdGFiYXNlUHJvbWlzZSIsInVwZGF0ZSIsImNyZWF0ZSIsInJlc3VsdCIsImxlbmd0aCIsIk9CSkVDVF9OT1RfRk9VTkQiLCJtYXliZVJ1blRyaWdnZXIiLCJvYmplY3QiLCJmaWVsZHNDaGFuZ2VkQnlUcmlnZ2VyIiwiXyIsInJlZHVjZSIsInZhbHVlIiwia2V5IiwiaXNFcXVhbCIsInB1c2giLCJydW5CZWZvcmVMb2dpblRyaWdnZXIiLCJ1c2VyRGF0YSIsImJlZm9yZUxvZ2luIiwiZmlsZXNDb250cm9sbGVyIiwiZXhwYW5kRmlsZXNJbk9iamVjdCIsImdldEFsbENsYXNzZXMiLCJhbGxDbGFzc2VzIiwic2NoZW1hIiwiZmluZCIsIm9uZUNsYXNzIiwic2V0UmVxdWlyZWRGaWVsZElmTmVlZGVkIiwiZmllbGROYW1lIiwic2V0RGVmYXVsdCIsInVuZGVmaW5lZCIsIl9fb3AiLCJmaWVsZHMiLCJkZWZhdWx0VmFsdWUiLCJyZXF1aXJlZCIsIlZBTElEQVRJT05fRVJST1IiLCJjcmVhdGVkQXQiLCJuZXdPYmplY3RJZCIsIm9iamVjdElkU2l6ZSIsImtleXMiLCJmb3JFYWNoIiwiYXV0aERhdGEiLCJ1c2VybmFtZSIsImlzRW1wdHkiLCJVU0VSTkFNRV9NSVNTSU5HIiwicGFzc3dvcmQiLCJQQVNTV09SRF9NSVNTSU5HIiwiVU5TVVBQT1JURURfU0VSVklDRSIsInByb3ZpZGVycyIsImNhbkhhbmRsZUF1dGhEYXRhIiwiY2FuSGFuZGxlIiwicHJvdmlkZXIiLCJwcm92aWRlckF1dGhEYXRhIiwiaGFzVG9rZW4iLCJoYW5kbGVBdXRoRGF0YSIsImhhbmRsZUF1dGhEYXRhVmFsaWRhdGlvbiIsInZhbGlkYXRpb25zIiwibWFwIiwiYXV0aERhdGFNYW5hZ2VyIiwiZ2V0VmFsaWRhdG9yRm9yUHJvdmlkZXIiLCJhbGwiLCJmaW5kVXNlcnNXaXRoQXV0aERhdGEiLCJtZW1vIiwicXVlcnlLZXkiLCJmaWx0ZXIiLCJxIiwiZmluZFByb21pc2UiLCIkb3IiLCJmaWx0ZXJlZE9iamVjdHNCeUFDTCIsIm9iamVjdHMiLCJBQ0wiLCJyZXN1bHRzIiwiciIsImpvaW4iLCJ1c2VyUmVzdWx0IiwibXV0YXRlZEF1dGhEYXRhIiwicHJvdmlkZXJEYXRhIiwidXNlckF1dGhEYXRhIiwiaGFzTXV0YXRlZEF1dGhEYXRhIiwidXNlcklkIiwibG9jYXRpb24iLCJBQ0NPVU5UX0FMUkVBRFlfTElOS0VEIiwicHJvbWlzZSIsImVycm9yIiwiUmVzdFF1ZXJ5IiwibWFzdGVyIiwiX190eXBlIiwic2Vzc2lvbiIsImNhY2hlQ29udHJvbGxlciIsImRlbCIsInNlc3Npb25Ub2tlbiIsIl92YWxpZGF0ZVBhc3N3b3JkUG9saWN5IiwiaGFzaCIsImhhc2hlZFBhc3N3b3JkIiwiX2hhc2hlZF9wYXNzd29yZCIsIl92YWxpZGF0ZVVzZXJOYW1lIiwiX3ZhbGlkYXRlRW1haWwiLCJyYW5kb21TdHJpbmciLCJyZXNwb25zZVNob3VsZEhhdmVVc2VybmFtZSIsIiRuZSIsImxpbWl0IiwiY2FzZUluc2Vuc2l0aXZlIiwiVVNFUk5BTUVfVEFLRU4iLCJlbWFpbCIsIm1hdGNoIiwicmVqZWN0IiwiSU5WQUxJRF9FTUFJTF9BRERSRVNTIiwiRU1BSUxfVEFLRU4iLCJ1c2VyQ29udHJvbGxlciIsInNldEVtYWlsVmVyaWZ5VG9rZW4iLCJwYXNzd29yZFBvbGljeSIsIl92YWxpZGF0ZVBhc3N3b3JkUmVxdWlyZW1lbnRzIiwiX3ZhbGlkYXRlUGFzc3dvcmRIaXN0b3J5IiwicG9saWN5RXJyb3IiLCJ2YWxpZGF0aW9uRXJyb3IiLCJjb250YWluc1VzZXJuYW1lRXJyb3IiLCJwYXR0ZXJuVmFsaWRhdG9yIiwidmFsaWRhdG9yQ2FsbGJhY2siLCJkb05vdEFsbG93VXNlcm5hbWUiLCJtYXhQYXNzd29yZEhpc3RvcnkiLCJvbGRQYXNzd29yZHMiLCJfcGFzc3dvcmRfaGlzdG9yeSIsInRha2UiLCJuZXdQYXNzd29yZCIsInByb21pc2VzIiwiY29tcGFyZSIsImNhdGNoIiwiZXJyIiwicHJldmVudExvZ2luV2l0aFVudmVyaWZpZWRFbWFpbCIsInZlcmlmeVVzZXJFbWFpbHMiLCJjcmVhdGVTZXNzaW9uVG9rZW4iLCJpbnN0YWxsYXRpb25JZCIsInNlc3Npb25EYXRhIiwiY3JlYXRlU2Vzc2lvbiIsImNyZWF0ZWRXaXRoIiwiYXV0aFByb3ZpZGVyIiwiYWRkT3BzIiwiX3BlcmlzaGFibGVfdG9rZW4iLCJfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0IiwiYXNzaWduIiwiZGVzdHJveSIsInJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQiLCJzZXNzaW9uUXVlcnkiLCJiaW5kIiwic2VuZFZlcmlmaWNhdGlvbkVtYWlsIiwiSU5WQUxJRF9TRVNTSU9OX1RPS0VOIiwiYWRkaXRpb25hbFNlc3Npb25EYXRhIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwic3RhdHVzIiwiZGV2aWNlVG9rZW4iLCJ0b0xvd2VyQ2FzZSIsImRldmljZVR5cGUiLCJpZE1hdGNoIiwib2JqZWN0SWRNYXRjaCIsImluc3RhbGxhdGlvbklkTWF0Y2giLCJkZXZpY2VUb2tlbk1hdGNoZXMiLCJvclF1ZXJpZXMiLCJkZWxRdWVyeSIsImFwcElkZW50aWZpZXIiLCJjb2RlIiwib2JqSWQiLCJyb2xlIiwiY2xlYXIiLCJpc1VuYXV0aGVudGljYXRlZCIsIlNFU1NJT05fTUlTU0lORyIsImRvd25sb2FkIiwiZG93bmxvYWROYW1lIiwibmFtZSIsIklOVkFMSURfQUNMIiwicmVhZCIsIndyaXRlIiwibWF4UGFzc3dvcmRBZ2UiLCJfcGFzc3dvcmRfY2hhbmdlZF9hdCIsImRlZmVyIiwiTWF0aCIsIm1heCIsInNoaWZ0IiwiX3VwZGF0ZVJlc3BvbnNlV2l0aERhdGEiLCJEVVBMSUNBVEVfVkFMVUUiLCJ1c2VySW5mbyIsImR1cGxpY2F0ZWRfZmllbGQiLCJoYXNBZnRlclNhdmVIb29rIiwiYWZ0ZXJTYXZlIiwiaGFzTGl2ZVF1ZXJ5IiwibGl2ZVF1ZXJ5Q29udHJvbGxlciIsIl9oYW5kbGVTYXZlUmVzcG9uc2UiLCJwZXJtcyIsImdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsIm9uQWZ0ZXJTYXZlIiwibG9nZ2VyIiwid2FybiIsIm1pZGRsZSIsIm1vdW50Iiwic2VydmVyVVJMIiwic2FuaXRpemVkRGF0YSIsInRlc3QiLCJfZGVjb2RlIiwic2V0Iiwic3BsaXR0ZWRLZXkiLCJzcGxpdCIsInBhcmVudFByb3AiLCJwYXJlbnRWYWwiLCJnZXQiLCJjbGllbnRTdXBwb3J0c0RlbGV0ZSIsInN1cHBvcnRzRm9yd2FyZERlbGV0ZSIsImRhdGFWYWx1ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFhQTs7QUFDQTs7QUFDQTs7OztBQWZBO0FBQ0E7QUFDQTtBQUVBLElBQUlBLGdCQUFnQixHQUFHQyxPQUFPLENBQUMsZ0NBQUQsQ0FBOUI7O0FBQ0EsSUFBSUMsUUFBUSxHQUFHRCxPQUFPLENBQUMsVUFBRCxDQUF0Qjs7QUFFQSxNQUFNRSxJQUFJLEdBQUdGLE9BQU8sQ0FBQyxRQUFELENBQXBCOztBQUNBLElBQUlHLFdBQVcsR0FBR0gsT0FBTyxDQUFDLGVBQUQsQ0FBekI7O0FBQ0EsSUFBSUksY0FBYyxHQUFHSixPQUFPLENBQUMsWUFBRCxDQUE1Qjs7QUFDQSxJQUFJSyxLQUFLLEdBQUdMLE9BQU8sQ0FBQyxZQUFELENBQW5COztBQUNBLElBQUlNLFFBQVEsR0FBR04sT0FBTyxDQUFDLFlBQUQsQ0FBdEI7O0FBQ0EsSUFBSU8sU0FBUyxHQUFHUCxPQUFPLENBQUMsYUFBRCxDQUF2Qjs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTUSxTQUFULENBQW1CQyxNQUFuQixFQUEyQkMsSUFBM0IsRUFBaUNDLFNBQWpDLEVBQTRDQyxLQUE1QyxFQUFtREMsSUFBbkQsRUFBeURDLFlBQXpELEVBQXVFQyxTQUF2RSxFQUFrRkMsT0FBbEYsRUFBMkZDLE1BQTNGLEVBQW1HO0FBQ2pHLE1BQUlQLElBQUksQ0FBQ1EsVUFBVCxFQUFxQjtBQUNuQixVQUFNLElBQUliLEtBQUssQ0FBQ2MsS0FBVixDQUNKZCxLQUFLLENBQUNjLEtBQU4sQ0FBWUMsbUJBRFIsRUFFSiwrREFGSSxDQUFOO0FBSUQ7O0FBQ0QsT0FBS1gsTUFBTCxHQUFjQSxNQUFkO0FBQ0EsT0FBS0MsSUFBTCxHQUFZQSxJQUFaO0FBQ0EsT0FBS0MsU0FBTCxHQUFpQkEsU0FBakI7QUFDQSxPQUFLSSxTQUFMLEdBQWlCQSxTQUFqQjtBQUNBLE9BQUtNLE9BQUwsR0FBZSxFQUFmO0FBQ0EsT0FBS0MsVUFBTCxHQUFrQixFQUFsQjtBQUNBLE9BQUtOLE9BQUwsR0FBZUEsT0FBTyxJQUFJLEVBQTFCOztBQUVBLE1BQUlDLE1BQUosRUFBWTtBQUNWLFNBQUtLLFVBQUwsQ0FBZ0JMLE1BQWhCLEdBQXlCQSxNQUF6QjtBQUNEOztBQUVELE1BQUksQ0FBQ0wsS0FBTCxFQUFZO0FBQ1YsUUFBSSxLQUFLSCxNQUFMLENBQVljLG1CQUFoQixFQUFxQztBQUNuQyxVQUFJQyxNQUFNLENBQUNDLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUFxQ2QsSUFBckMsRUFBMkMsVUFBM0MsS0FBMEQsQ0FBQ0EsSUFBSSxDQUFDZSxRQUFwRSxFQUE4RTtBQUM1RSxjQUFNLElBQUl2QixLQUFLLENBQUNjLEtBQVYsQ0FDSmQsS0FBSyxDQUFDYyxLQUFOLENBQVlVLGlCQURSLEVBRUosK0NBRkksQ0FBTjtBQUlEO0FBQ0YsS0FQRCxNQU9PO0FBQ0wsVUFBSWhCLElBQUksQ0FBQ2UsUUFBVCxFQUFtQjtBQUNqQixjQUFNLElBQUl2QixLQUFLLENBQUNjLEtBQVYsQ0FBZ0JkLEtBQUssQ0FBQ2MsS0FBTixDQUFZVyxnQkFBNUIsRUFBOEMsb0NBQTlDLENBQU47QUFDRDs7QUFDRCxVQUFJakIsSUFBSSxDQUFDa0IsRUFBVCxFQUFhO0FBQ1gsY0FBTSxJQUFJMUIsS0FBSyxDQUFDYyxLQUFWLENBQWdCZCxLQUFLLENBQUNjLEtBQU4sQ0FBWVcsZ0JBQTVCLEVBQThDLDhCQUE5QyxDQUFOO0FBQ0Q7QUFDRjtBQUNGLEdBbkNnRyxDQXFDakc7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0EsT0FBS0UsUUFBTCxHQUFnQixJQUFoQixDQTFDaUcsQ0E0Q2pHO0FBQ0E7O0FBQ0EsT0FBS3BCLEtBQUwsR0FBYVgsUUFBUSxDQUFDVyxLQUFELENBQXJCO0FBQ0EsT0FBS0MsSUFBTCxHQUFZWixRQUFRLENBQUNZLElBQUQsQ0FBcEIsQ0EvQ2lHLENBZ0RqRzs7QUFDQSxPQUFLQyxZQUFMLEdBQW9CQSxZQUFwQixDQWpEaUcsQ0FtRGpHOztBQUNBLE9BQUttQixTQUFMLEdBQWlCNUIsS0FBSyxDQUFDNkIsT0FBTixDQUFjLElBQUlDLElBQUosRUFBZCxFQUEwQkMsR0FBM0MsQ0FwRGlHLENBc0RqRztBQUNBOztBQUNBLE9BQUtDLHFCQUFMLEdBQTZCLElBQTdCO0FBQ0QsQyxDQUVEO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQTdCLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0JhLE9BQXBCLEdBQThCLFlBQVk7QUFDeEMsU0FBT0MsT0FBTyxDQUFDQyxPQUFSLEdBQ0pDLElBREksQ0FDQyxNQUFNO0FBQ1YsV0FBTyxLQUFLQyxpQkFBTCxFQUFQO0FBQ0QsR0FISSxFQUlKRCxJQUpJLENBSUMsTUFBTTtBQUNWLFdBQU8sS0FBS0UsMkJBQUwsRUFBUDtBQUNELEdBTkksRUFPSkYsSUFQSSxDQU9DLE1BQU07QUFDVixXQUFPLEtBQUtHLGtCQUFMLEVBQVA7QUFDRCxHQVRJLEVBVUpILElBVkksQ0FVQyxNQUFNO0FBQ1YsV0FBTyxLQUFLSSxhQUFMLEVBQVA7QUFDRCxHQVpJLEVBYUpKLElBYkksQ0FhQyxNQUFNO0FBQ1YsV0FBTyxLQUFLSyxnQkFBTCxFQUFQO0FBQ0QsR0FmSSxFQWdCSkwsSUFoQkksQ0FnQkMsTUFBTTtBQUNWLFdBQU8sS0FBS00sb0JBQUwsRUFBUDtBQUNELEdBbEJJLEVBbUJKTixJQW5CSSxDQW1CQyxNQUFNO0FBQ1YsV0FBTyxLQUFLTyw2QkFBTCxFQUFQO0FBQ0QsR0FyQkksRUFzQkpQLElBdEJJLENBc0JDLE1BQU07QUFDVixXQUFPLEtBQUtRLGNBQUwsRUFBUDtBQUNELEdBeEJJLEVBeUJKUixJQXpCSSxDQXlCQ1MsZ0JBQWdCLElBQUk7QUFDeEIsU0FBS2IscUJBQUwsR0FBNkJhLGdCQUE3QjtBQUNBLFdBQU8sS0FBS0MseUJBQUwsRUFBUDtBQUNELEdBNUJJLEVBNkJKVixJQTdCSSxDQTZCQyxNQUFNO0FBQ1YsV0FBTyxLQUFLVyxhQUFMLEVBQVA7QUFDRCxHQS9CSSxFQWdDSlgsSUFoQ0ksQ0FnQ0MsTUFBTTtBQUNWLFdBQU8sS0FBS1ksNkJBQUwsRUFBUDtBQUNELEdBbENJLEVBbUNKWixJQW5DSSxDQW1DQyxNQUFNO0FBQ1YsV0FBTyxLQUFLYSx5QkFBTCxFQUFQO0FBQ0QsR0FyQ0ksRUFzQ0piLElBdENJLENBc0NDLE1BQU07QUFDVixXQUFPLEtBQUtjLG9CQUFMLEVBQVA7QUFDRCxHQXhDSSxFQXlDSmQsSUF6Q0ksQ0F5Q0MsTUFBTTtBQUNWLFdBQU8sS0FBS2UsMEJBQUwsRUFBUDtBQUNELEdBM0NJLEVBNENKZixJQTVDSSxDQTRDQyxNQUFNO0FBQ1YsV0FBTyxLQUFLZ0IsY0FBTCxFQUFQO0FBQ0QsR0E5Q0ksRUErQ0poQixJQS9DSSxDQStDQyxNQUFNO0FBQ1YsV0FBTyxLQUFLaUIsbUJBQUwsRUFBUDtBQUNELEdBakRJLEVBa0RKakIsSUFsREksQ0FrREMsTUFBTTtBQUNWLFdBQU8sS0FBS2tCLGlCQUFMLEVBQVA7QUFDRCxHQXBESSxFQXFESmxCLElBckRJLENBcURDLE1BQU07QUFDVixXQUFPLEtBQUtULFFBQVo7QUFDRCxHQXZESSxDQUFQO0FBd0RELENBekRELEMsQ0EyREE7OztBQUNBeEIsU0FBUyxDQUFDaUIsU0FBVixDQUFvQmlCLGlCQUFwQixHQUF3QyxZQUFZO0FBQ2xELE1BQUksS0FBS2hDLElBQUwsQ0FBVWtELFFBQWQsRUFBd0I7QUFDdEIsV0FBT3JCLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0Q7O0FBRUQsT0FBS2xCLFVBQUwsQ0FBZ0J1QyxHQUFoQixHQUFzQixDQUFDLEdBQUQsQ0FBdEI7O0FBRUEsTUFBSSxLQUFLbkQsSUFBTCxDQUFVb0QsSUFBZCxFQUFvQjtBQUNsQixXQUFPLEtBQUtwRCxJQUFMLENBQVVxRCxZQUFWLEdBQXlCdEIsSUFBekIsQ0FBOEJ1QixLQUFLLElBQUk7QUFDNUMsV0FBSzFDLFVBQUwsQ0FBZ0J1QyxHQUFoQixHQUFzQixLQUFLdkMsVUFBTCxDQUFnQnVDLEdBQWhCLENBQW9CSSxNQUFwQixDQUEyQkQsS0FBM0IsRUFBa0MsQ0FBQyxLQUFLdEQsSUFBTCxDQUFVb0QsSUFBVixDQUFlL0IsRUFBaEIsQ0FBbEMsQ0FBdEI7QUFDQTtBQUNELEtBSE0sQ0FBUDtBQUlELEdBTEQsTUFLTztBQUNMLFdBQU9RLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0Q7QUFDRixDQWZELEMsQ0FpQkE7OztBQUNBaEMsU0FBUyxDQUFDaUIsU0FBVixDQUFvQmtCLDJCQUFwQixHQUFrRCxZQUFZO0FBQzVELE1BQ0UsS0FBS2xDLE1BQUwsQ0FBWXlELHdCQUFaLEtBQXlDLEtBQXpDLElBQ0EsQ0FBQyxLQUFLeEQsSUFBTCxDQUFVa0QsUUFEWCxJQUVBN0QsZ0JBQWdCLENBQUNvRSxhQUFqQixDQUErQkMsT0FBL0IsQ0FBdUMsS0FBS3pELFNBQTVDLE1BQTJELENBQUMsQ0FIOUQsRUFJRTtBQUNBLFdBQU8sS0FBS0YsTUFBTCxDQUFZNEQsUUFBWixDQUNKQyxVQURJLEdBRUo3QixJQUZJLENBRUNTLGdCQUFnQixJQUFJQSxnQkFBZ0IsQ0FBQ3FCLFFBQWpCLENBQTBCLEtBQUs1RCxTQUEvQixDQUZyQixFQUdKOEIsSUFISSxDQUdDOEIsUUFBUSxJQUFJO0FBQ2hCLFVBQUlBLFFBQVEsS0FBSyxJQUFqQixFQUF1QjtBQUNyQixjQUFNLElBQUlsRSxLQUFLLENBQUNjLEtBQVYsQ0FDSmQsS0FBSyxDQUFDYyxLQUFOLENBQVlDLG1CQURSLEVBRUosd0NBQXdDLHNCQUF4QyxHQUFpRSxLQUFLVCxTQUZsRSxDQUFOO0FBSUQ7QUFDRixLQVZJLENBQVA7QUFXRCxHQWhCRCxNQWdCTztBQUNMLFdBQU80QixPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEO0FBQ0YsQ0FwQkQsQyxDQXNCQTs7O0FBQ0FoQyxTQUFTLENBQUNpQixTQUFWLENBQW9Cd0IsY0FBcEIsR0FBcUMsWUFBWTtBQUMvQyxTQUFPLEtBQUt4QyxNQUFMLENBQVk0RCxRQUFaLENBQXFCRyxjQUFyQixDQUNMLEtBQUs3RCxTQURBLEVBRUwsS0FBS0UsSUFGQSxFQUdMLEtBQUtELEtBSEEsRUFJTCxLQUFLVSxVQUpBLENBQVA7QUFNRCxDQVBELEMsQ0FTQTtBQUNBOzs7QUFDQWQsU0FBUyxDQUFDaUIsU0FBVixDQUFvQnNCLG9CQUFwQixHQUEyQyxZQUFZO0FBQ3JELE1BQUksS0FBS2YsUUFBVCxFQUFtQjtBQUNqQjtBQUNELEdBSG9ELENBS3JEOzs7QUFDQSxNQUNFLENBQUMxQixRQUFRLENBQUNtRSxhQUFULENBQXVCLEtBQUs5RCxTQUE1QixFQUF1Q0wsUUFBUSxDQUFDb0UsS0FBVCxDQUFlQyxVQUF0RCxFQUFrRSxLQUFLbEUsTUFBTCxDQUFZbUUsYUFBOUUsQ0FESCxFQUVFO0FBQ0EsV0FBT3JDLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsR0FWb0QsQ0FZckQ7OztBQUNBLE1BQUlxQyxTQUFTLEdBQUc7QUFBRWxFLElBQUFBLFNBQVMsRUFBRSxLQUFLQTtBQUFsQixHQUFoQjs7QUFDQSxNQUFJLEtBQUtDLEtBQUwsSUFBYyxLQUFLQSxLQUFMLENBQVdnQixRQUE3QixFQUF1QztBQUNyQ2lELElBQUFBLFNBQVMsQ0FBQ2pELFFBQVYsR0FBcUIsS0FBS2hCLEtBQUwsQ0FBV2dCLFFBQWhDO0FBQ0Q7O0FBRUQsTUFBSWtELGNBQWMsR0FBRyxJQUFyQjtBQUNBLFFBQU1DLGFBQWEsR0FBRyxLQUFLQyxrQkFBTCxDQUF3QkgsU0FBeEIsQ0FBdEI7O0FBQ0EsTUFBSSxLQUFLakUsS0FBTCxJQUFjLEtBQUtBLEtBQUwsQ0FBV2dCLFFBQTdCLEVBQXVDO0FBQ3JDO0FBQ0FrRCxJQUFBQSxjQUFjLEdBQUd4RSxRQUFRLENBQUMyRSxPQUFULENBQWlCSixTQUFqQixFQUE0QixLQUFLL0QsWUFBakMsQ0FBakI7QUFDRDs7QUFFRCxTQUFPeUIsT0FBTyxDQUFDQyxPQUFSLEdBQ0pDLElBREksQ0FDQyxNQUFNO0FBQ1Y7QUFDQSxRQUFJeUMsZUFBZSxHQUFHLElBQXRCOztBQUNBLFFBQUksS0FBS3RFLEtBQVQsRUFBZ0I7QUFDZDtBQUNBc0UsTUFBQUEsZUFBZSxHQUFHLEtBQUt6RSxNQUFMLENBQVk0RCxRQUFaLENBQXFCYyxNQUFyQixDQUNoQixLQUFLeEUsU0FEVyxFQUVoQixLQUFLQyxLQUZXLEVBR2hCLEtBQUtDLElBSFcsRUFJaEIsS0FBS1MsVUFKVyxFQUtoQixJQUxnQixFQU1oQixJQU5nQixDQUFsQjtBQVFELEtBVkQsTUFVTztBQUNMO0FBQ0E0RCxNQUFBQSxlQUFlLEdBQUcsS0FBS3pFLE1BQUwsQ0FBWTRELFFBQVosQ0FBcUJlLE1BQXJCLENBQ2hCLEtBQUt6RSxTQURXLEVBRWhCLEtBQUtFLElBRlcsRUFHaEIsS0FBS1MsVUFIVyxFQUloQixJQUpnQixDQUFsQjtBQU1ELEtBckJTLENBc0JWOzs7QUFDQSxXQUFPNEQsZUFBZSxDQUFDekMsSUFBaEIsQ0FBcUI0QyxNQUFNLElBQUk7QUFDcEMsVUFBSSxDQUFDQSxNQUFELElBQVdBLE1BQU0sQ0FBQ0MsTUFBUCxJQUFpQixDQUFoQyxFQUFtQztBQUNqQyxjQUFNLElBQUlqRixLQUFLLENBQUNjLEtBQVYsQ0FBZ0JkLEtBQUssQ0FBQ2MsS0FBTixDQUFZb0UsZ0JBQTVCLEVBQThDLG1CQUE5QyxDQUFOO0FBQ0Q7QUFDRixLQUpNLENBQVA7QUFLRCxHQTdCSSxFQThCSjlDLElBOUJJLENBOEJDLE1BQU07QUFDVixXQUFPbkMsUUFBUSxDQUFDa0YsZUFBVCxDQUNMbEYsUUFBUSxDQUFDb0UsS0FBVCxDQUFlQyxVQURWLEVBRUwsS0FBS2pFLElBRkEsRUFHTHFFLGFBSEssRUFJTEQsY0FKSyxFQUtMLEtBQUtyRSxNQUxBLEVBTUwsS0FBS08sT0FOQSxDQUFQO0FBUUQsR0F2Q0ksRUF3Q0p5QixJQXhDSSxDQXdDQ1QsUUFBUSxJQUFJO0FBQ2hCLFFBQUlBLFFBQVEsSUFBSUEsUUFBUSxDQUFDeUQsTUFBekIsRUFBaUM7QUFDL0IsV0FBS3BFLE9BQUwsQ0FBYXFFLHNCQUFiLEdBQXNDQyxnQkFBRUMsTUFBRixDQUNwQzVELFFBQVEsQ0FBQ3lELE1BRDJCLEVBRXBDLENBQUNKLE1BQUQsRUFBU1EsS0FBVCxFQUFnQkMsR0FBaEIsS0FBd0I7QUFDdEIsWUFBSSxDQUFDSCxnQkFBRUksT0FBRixDQUFVLEtBQUtsRixJQUFMLENBQVVpRixHQUFWLENBQVYsRUFBMEJELEtBQTFCLENBQUwsRUFBdUM7QUFDckNSLFVBQUFBLE1BQU0sQ0FBQ1csSUFBUCxDQUFZRixHQUFaO0FBQ0Q7O0FBQ0QsZUFBT1QsTUFBUDtBQUNELE9BUG1DLEVBUXBDLEVBUm9DLENBQXRDO0FBVUEsV0FBS3hFLElBQUwsR0FBWW1CLFFBQVEsQ0FBQ3lELE1BQXJCLENBWCtCLENBWS9COztBQUNBLFVBQUksS0FBSzdFLEtBQUwsSUFBYyxLQUFLQSxLQUFMLENBQVdnQixRQUE3QixFQUF1QztBQUNyQyxlQUFPLEtBQUtmLElBQUwsQ0FBVWUsUUFBakI7QUFDRDtBQUNGO0FBQ0YsR0ExREksQ0FBUDtBQTJERCxDQXBGRDs7QUFzRkFwQixTQUFTLENBQUNpQixTQUFWLENBQW9Cd0UscUJBQXBCLEdBQTRDLGdCQUFnQkMsUUFBaEIsRUFBMEI7QUFDcEU7QUFDQSxNQUNFLENBQUM1RixRQUFRLENBQUNtRSxhQUFULENBQXVCLEtBQUs5RCxTQUE1QixFQUF1Q0wsUUFBUSxDQUFDb0UsS0FBVCxDQUFleUIsV0FBdEQsRUFBbUUsS0FBSzFGLE1BQUwsQ0FBWW1FLGFBQS9FLENBREgsRUFFRTtBQUNBO0FBQ0QsR0FObUUsQ0FRcEU7OztBQUNBLFFBQU1DLFNBQVMsR0FBRztBQUFFbEUsSUFBQUEsU0FBUyxFQUFFLEtBQUtBO0FBQWxCLEdBQWxCLENBVG9FLENBV3BFOztBQUNBLE9BQUtGLE1BQUwsQ0FBWTJGLGVBQVosQ0FBNEJDLG1CQUE1QixDQUFnRCxLQUFLNUYsTUFBckQsRUFBNkR5RixRQUE3RDtBQUVBLFFBQU1wQyxJQUFJLEdBQUd4RCxRQUFRLENBQUMyRSxPQUFULENBQWlCSixTQUFqQixFQUE0QnFCLFFBQTVCLENBQWIsQ0Fkb0UsQ0FnQnBFOztBQUNBLFFBQU01RixRQUFRLENBQUNrRixlQUFULENBQ0psRixRQUFRLENBQUNvRSxLQUFULENBQWV5QixXQURYLEVBRUosS0FBS3pGLElBRkQsRUFHSm9ELElBSEksRUFJSixJQUpJLEVBS0osS0FBS3JELE1BTEQsRUFNSixLQUFLTyxPQU5ELENBQU47QUFRRCxDQXpCRDs7QUEyQkFSLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0IwQix5QkFBcEIsR0FBZ0QsWUFBWTtBQUMxRCxNQUFJLEtBQUt0QyxJQUFULEVBQWU7QUFDYixXQUFPLEtBQUt3QixxQkFBTCxDQUEyQmlFLGFBQTNCLEdBQTJDN0QsSUFBM0MsQ0FBZ0Q4RCxVQUFVLElBQUk7QUFDbkUsWUFBTUMsTUFBTSxHQUFHRCxVQUFVLENBQUNFLElBQVgsQ0FBZ0JDLFFBQVEsSUFBSUEsUUFBUSxDQUFDL0YsU0FBVCxLQUF1QixLQUFLQSxTQUF4RCxDQUFmOztBQUNBLFlBQU1nRyx3QkFBd0IsR0FBRyxDQUFDQyxTQUFELEVBQVlDLFVBQVosS0FBMkI7QUFDMUQsWUFDRSxLQUFLaEcsSUFBTCxDQUFVK0YsU0FBVixNQUF5QkUsU0FBekIsSUFDQSxLQUFLakcsSUFBTCxDQUFVK0YsU0FBVixNQUF5QixJQUR6QixJQUVBLEtBQUsvRixJQUFMLENBQVUrRixTQUFWLE1BQXlCLEVBRnpCLElBR0MsT0FBTyxLQUFLL0YsSUFBTCxDQUFVK0YsU0FBVixDQUFQLEtBQWdDLFFBQWhDLElBQTRDLEtBQUsvRixJQUFMLENBQVUrRixTQUFWLEVBQXFCRyxJQUFyQixLQUE4QixRQUo3RSxFQUtFO0FBQ0EsY0FDRUYsVUFBVSxJQUNWTCxNQUFNLENBQUNRLE1BQVAsQ0FBY0osU0FBZCxDQURBLElBRUFKLE1BQU0sQ0FBQ1EsTUFBUCxDQUFjSixTQUFkLEVBQXlCSyxZQUF6QixLQUEwQyxJQUYxQyxJQUdBVCxNQUFNLENBQUNRLE1BQVAsQ0FBY0osU0FBZCxFQUF5QkssWUFBekIsS0FBMENILFNBSDFDLEtBSUMsS0FBS2pHLElBQUwsQ0FBVStGLFNBQVYsTUFBeUJFLFNBQXpCLElBQ0UsT0FBTyxLQUFLakcsSUFBTCxDQUFVK0YsU0FBVixDQUFQLEtBQWdDLFFBQWhDLElBQTRDLEtBQUsvRixJQUFMLENBQVUrRixTQUFWLEVBQXFCRyxJQUFyQixLQUE4QixRQUw3RSxDQURGLEVBT0U7QUFDQSxpQkFBS2xHLElBQUwsQ0FBVStGLFNBQVYsSUFBdUJKLE1BQU0sQ0FBQ1EsTUFBUCxDQUFjSixTQUFkLEVBQXlCSyxZQUFoRDtBQUNBLGlCQUFLNUYsT0FBTCxDQUFhcUUsc0JBQWIsR0FBc0MsS0FBS3JFLE9BQUwsQ0FBYXFFLHNCQUFiLElBQXVDLEVBQTdFOztBQUNBLGdCQUFJLEtBQUtyRSxPQUFMLENBQWFxRSxzQkFBYixDQUFvQ3RCLE9BQXBDLENBQTRDd0MsU0FBNUMsSUFBeUQsQ0FBN0QsRUFBZ0U7QUFDOUQsbUJBQUt2RixPQUFMLENBQWFxRSxzQkFBYixDQUFvQ00sSUFBcEMsQ0FBeUNZLFNBQXpDO0FBQ0Q7QUFDRixXQWJELE1BYU8sSUFBSUosTUFBTSxDQUFDUSxNQUFQLENBQWNKLFNBQWQsS0FBNEJKLE1BQU0sQ0FBQ1EsTUFBUCxDQUFjSixTQUFkLEVBQXlCTSxRQUF6QixLQUFzQyxJQUF0RSxFQUE0RTtBQUNqRixrQkFBTSxJQUFJN0csS0FBSyxDQUFDYyxLQUFWLENBQWdCZCxLQUFLLENBQUNjLEtBQU4sQ0FBWWdHLGdCQUE1QixFQUErQyxHQUFFUCxTQUFVLGNBQTNELENBQU47QUFDRDtBQUNGO0FBQ0YsT0F4QkQsQ0FGbUUsQ0E0Qm5FOzs7QUFDQSxXQUFLL0YsSUFBTCxDQUFVb0IsU0FBVixHQUFzQixLQUFLQSxTQUEzQjs7QUFDQSxVQUFJLENBQUMsS0FBS3JCLEtBQVYsRUFBaUI7QUFDZixhQUFLQyxJQUFMLENBQVV1RyxTQUFWLEdBQXNCLEtBQUtuRixTQUEzQixDQURlLENBR2Y7O0FBQ0EsWUFBSSxDQUFDLEtBQUtwQixJQUFMLENBQVVlLFFBQWYsRUFBeUI7QUFDdkIsZUFBS2YsSUFBTCxDQUFVZSxRQUFWLEdBQXFCekIsV0FBVyxDQUFDa0gsV0FBWixDQUF3QixLQUFLNUcsTUFBTCxDQUFZNkcsWUFBcEMsQ0FBckI7QUFDRDs7QUFDRCxZQUFJZCxNQUFKLEVBQVk7QUFDVmhGLFVBQUFBLE1BQU0sQ0FBQytGLElBQVAsQ0FBWWYsTUFBTSxDQUFDUSxNQUFuQixFQUEyQlEsT0FBM0IsQ0FBbUNaLFNBQVMsSUFBSTtBQUM5Q0QsWUFBQUEsd0JBQXdCLENBQUNDLFNBQUQsRUFBWSxJQUFaLENBQXhCO0FBQ0QsV0FGRDtBQUdEO0FBQ0YsT0FaRCxNQVlPLElBQUlKLE1BQUosRUFBWTtBQUNqQmhGLFFBQUFBLE1BQU0sQ0FBQytGLElBQVAsQ0FBWSxLQUFLMUcsSUFBakIsRUFBdUIyRyxPQUF2QixDQUErQlosU0FBUyxJQUFJO0FBQzFDRCxVQUFBQSx3QkFBd0IsQ0FBQ0MsU0FBRCxFQUFZLEtBQVosQ0FBeEI7QUFDRCxTQUZEO0FBR0Q7QUFDRixLQS9DTSxDQUFQO0FBZ0REOztBQUNELFNBQU9yRSxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELENBcERELEMsQ0FzREE7QUFDQTtBQUNBOzs7QUFDQWhDLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0JxQixnQkFBcEIsR0FBdUMsWUFBWTtBQUNqRCxNQUFJLEtBQUtuQyxTQUFMLEtBQW1CLE9BQXZCLEVBQWdDO0FBQzlCO0FBQ0Q7O0FBRUQsTUFBSSxDQUFDLEtBQUtDLEtBQU4sSUFBZSxDQUFDLEtBQUtDLElBQUwsQ0FBVTRHLFFBQTlCLEVBQXdDO0FBQ3RDLFFBQUksT0FBTyxLQUFLNUcsSUFBTCxDQUFVNkcsUUFBakIsS0FBOEIsUUFBOUIsSUFBMEMvQixnQkFBRWdDLE9BQUYsQ0FBVSxLQUFLOUcsSUFBTCxDQUFVNkcsUUFBcEIsQ0FBOUMsRUFBNkU7QUFDM0UsWUFBTSxJQUFJckgsS0FBSyxDQUFDYyxLQUFWLENBQWdCZCxLQUFLLENBQUNjLEtBQU4sQ0FBWXlHLGdCQUE1QixFQUE4Qyx5QkFBOUMsQ0FBTjtBQUNEOztBQUNELFFBQUksT0FBTyxLQUFLL0csSUFBTCxDQUFVZ0gsUUFBakIsS0FBOEIsUUFBOUIsSUFBMENsQyxnQkFBRWdDLE9BQUYsQ0FBVSxLQUFLOUcsSUFBTCxDQUFVZ0gsUUFBcEIsQ0FBOUMsRUFBNkU7QUFDM0UsWUFBTSxJQUFJeEgsS0FBSyxDQUFDYyxLQUFWLENBQWdCZCxLQUFLLENBQUNjLEtBQU4sQ0FBWTJHLGdCQUE1QixFQUE4QyxzQkFBOUMsQ0FBTjtBQUNEO0FBQ0Y7O0FBRUQsTUFDRyxLQUFLakgsSUFBTCxDQUFVNEcsUUFBVixJQUFzQixDQUFDakcsTUFBTSxDQUFDK0YsSUFBUCxDQUFZLEtBQUsxRyxJQUFMLENBQVU0RyxRQUF0QixFQUFnQ25DLE1BQXhELElBQ0EsQ0FBQzlELE1BQU0sQ0FBQ0MsU0FBUCxDQUFpQkMsY0FBakIsQ0FBZ0NDLElBQWhDLENBQXFDLEtBQUtkLElBQTFDLEVBQWdELFVBQWhELENBRkgsRUFHRTtBQUNBO0FBQ0E7QUFDRCxHQU5ELE1BTU8sSUFBSVcsTUFBTSxDQUFDQyxTQUFQLENBQWlCQyxjQUFqQixDQUFnQ0MsSUFBaEMsQ0FBcUMsS0FBS2QsSUFBMUMsRUFBZ0QsVUFBaEQsS0FBK0QsQ0FBQyxLQUFLQSxJQUFMLENBQVU0RyxRQUE5RSxFQUF3RjtBQUM3RjtBQUNBLFVBQU0sSUFBSXBILEtBQUssQ0FBQ2MsS0FBVixDQUNKZCxLQUFLLENBQUNjLEtBQU4sQ0FBWTRHLG1CQURSLEVBRUosNENBRkksQ0FBTjtBQUlEOztBQUVELE1BQUlOLFFBQVEsR0FBRyxLQUFLNUcsSUFBTCxDQUFVNEcsUUFBekI7QUFDQSxNQUFJTyxTQUFTLEdBQUd4RyxNQUFNLENBQUMrRixJQUFQLENBQVlFLFFBQVosQ0FBaEI7O0FBQ0EsTUFBSU8sU0FBUyxDQUFDMUMsTUFBVixHQUFtQixDQUF2QixFQUEwQjtBQUN4QixVQUFNMkMsaUJBQWlCLEdBQUdELFNBQVMsQ0FBQ3BDLE1BQVYsQ0FBaUIsQ0FBQ3NDLFNBQUQsRUFBWUMsUUFBWixLQUF5QjtBQUNsRSxVQUFJQyxnQkFBZ0IsR0FBR1gsUUFBUSxDQUFDVSxRQUFELENBQS9CO0FBQ0EsVUFBSUUsUUFBUSxHQUFHRCxnQkFBZ0IsSUFBSUEsZ0JBQWdCLENBQUNyRyxFQUFwRDtBQUNBLGFBQU9tRyxTQUFTLEtBQUtHLFFBQVEsSUFBSUQsZ0JBQWdCLElBQUksSUFBckMsQ0FBaEI7QUFDRCxLQUp5QixFQUl2QixJQUp1QixDQUExQjs7QUFLQSxRQUFJSCxpQkFBSixFQUF1QjtBQUNyQixhQUFPLEtBQUtLLGNBQUwsQ0FBb0JiLFFBQXBCLENBQVA7QUFDRDtBQUNGOztBQUNELFFBQU0sSUFBSXBILEtBQUssQ0FBQ2MsS0FBVixDQUNKZCxLQUFLLENBQUNjLEtBQU4sQ0FBWTRHLG1CQURSLEVBRUosNENBRkksQ0FBTjtBQUlELENBNUNEOztBQThDQXZILFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0I4Ryx3QkFBcEIsR0FBK0MsVUFBVWQsUUFBVixFQUFvQjtBQUNqRSxRQUFNZSxXQUFXLEdBQUdoSCxNQUFNLENBQUMrRixJQUFQLENBQVlFLFFBQVosRUFBc0JnQixHQUF0QixDQUEwQk4sUUFBUSxJQUFJO0FBQ3hELFFBQUlWLFFBQVEsQ0FBQ1UsUUFBRCxDQUFSLEtBQXVCLElBQTNCLEVBQWlDO0FBQy9CLGFBQU81RixPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUNELFVBQU1NLGdCQUFnQixHQUFHLEtBQUtyQyxNQUFMLENBQVlpSSxlQUFaLENBQTRCQyx1QkFBNUIsQ0FBb0RSLFFBQXBELENBQXpCOztBQUNBLFFBQUksQ0FBQ3JGLGdCQUFMLEVBQXVCO0FBQ3JCLFlBQU0sSUFBSXpDLEtBQUssQ0FBQ2MsS0FBVixDQUNKZCxLQUFLLENBQUNjLEtBQU4sQ0FBWTRHLG1CQURSLEVBRUosNENBRkksQ0FBTjtBQUlEOztBQUNELFdBQU9qRixnQkFBZ0IsQ0FBQzJFLFFBQVEsQ0FBQ1UsUUFBRCxDQUFULENBQXZCO0FBQ0QsR0FabUIsQ0FBcEI7QUFhQSxTQUFPNUYsT0FBTyxDQUFDcUcsR0FBUixDQUFZSixXQUFaLENBQVA7QUFDRCxDQWZEOztBQWlCQWhJLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0JvSCxxQkFBcEIsR0FBNEMsVUFBVXBCLFFBQVYsRUFBb0I7QUFDOUQsUUFBTU8sU0FBUyxHQUFHeEcsTUFBTSxDQUFDK0YsSUFBUCxDQUFZRSxRQUFaLENBQWxCO0FBQ0EsUUFBTTdHLEtBQUssR0FBR29ILFNBQVMsQ0FDcEJwQyxNQURXLENBQ0osQ0FBQ2tELElBQUQsRUFBT1gsUUFBUCxLQUFvQjtBQUMxQixRQUFJLENBQUNWLFFBQVEsQ0FBQ1UsUUFBRCxDQUFiLEVBQXlCO0FBQ3ZCLGFBQU9XLElBQVA7QUFDRDs7QUFDRCxVQUFNQyxRQUFRLEdBQUksWUFBV1osUUFBUyxLQUF0QztBQUNBLFVBQU12SCxLQUFLLEdBQUcsRUFBZDtBQUNBQSxJQUFBQSxLQUFLLENBQUNtSSxRQUFELENBQUwsR0FBa0J0QixRQUFRLENBQUNVLFFBQUQsQ0FBUixDQUFtQnBHLEVBQXJDO0FBQ0ErRyxJQUFBQSxJQUFJLENBQUM5QyxJQUFMLENBQVVwRixLQUFWO0FBQ0EsV0FBT2tJLElBQVA7QUFDRCxHQVZXLEVBVVQsRUFWUyxFQVdYRSxNQVhXLENBV0pDLENBQUMsSUFBSTtBQUNYLFdBQU8sT0FBT0EsQ0FBUCxLQUFhLFdBQXBCO0FBQ0QsR0FiVyxDQUFkO0FBZUEsTUFBSUMsV0FBVyxHQUFHM0csT0FBTyxDQUFDQyxPQUFSLENBQWdCLEVBQWhCLENBQWxCOztBQUNBLE1BQUk1QixLQUFLLENBQUMwRSxNQUFOLEdBQWUsQ0FBbkIsRUFBc0I7QUFDcEI0RCxJQUFBQSxXQUFXLEdBQUcsS0FBS3pJLE1BQUwsQ0FBWTRELFFBQVosQ0FBcUJvQyxJQUFyQixDQUEwQixLQUFLOUYsU0FBL0IsRUFBMEM7QUFBRXdJLE1BQUFBLEdBQUcsRUFBRXZJO0FBQVAsS0FBMUMsRUFBMEQsRUFBMUQsQ0FBZDtBQUNEOztBQUVELFNBQU9zSSxXQUFQO0FBQ0QsQ0F2QkQ7O0FBeUJBMUksU0FBUyxDQUFDaUIsU0FBVixDQUFvQjJILG9CQUFwQixHQUEyQyxVQUFVQyxPQUFWLEVBQW1CO0FBQzVELE1BQUksS0FBSzNJLElBQUwsQ0FBVWtELFFBQWQsRUFBd0I7QUFDdEIsV0FBT3lGLE9BQVA7QUFDRDs7QUFDRCxTQUFPQSxPQUFPLENBQUNMLE1BQVIsQ0FBZXZELE1BQU0sSUFBSTtBQUM5QixRQUFJLENBQUNBLE1BQU0sQ0FBQzZELEdBQVosRUFBaUI7QUFDZixhQUFPLElBQVAsQ0FEZSxDQUNGO0FBQ2QsS0FINkIsQ0FJOUI7OztBQUNBLFdBQU83RCxNQUFNLENBQUM2RCxHQUFQLElBQWM5SCxNQUFNLENBQUMrRixJQUFQLENBQVk5QixNQUFNLENBQUM2RCxHQUFuQixFQUF3QmhFLE1BQXhCLEdBQWlDLENBQXREO0FBQ0QsR0FOTSxDQUFQO0FBT0QsQ0FYRDs7QUFhQTlFLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0I2RyxjQUFwQixHQUFxQyxVQUFVYixRQUFWLEVBQW9CO0FBQ3ZELE1BQUk4QixPQUFKO0FBQ0EsU0FBTyxLQUFLVixxQkFBTCxDQUEyQnBCLFFBQTNCLEVBQXFDaEYsSUFBckMsQ0FBMEMsTUFBTStHLENBQU4sSUFBVztBQUMxREQsSUFBQUEsT0FBTyxHQUFHLEtBQUtILG9CQUFMLENBQTBCSSxDQUExQixDQUFWOztBQUVBLFFBQUlELE9BQU8sQ0FBQ2pFLE1BQVIsSUFBa0IsQ0FBdEIsRUFBeUI7QUFDdkIsV0FBS2pFLE9BQUwsQ0FBYSxjQUFiLElBQStCRyxNQUFNLENBQUMrRixJQUFQLENBQVlFLFFBQVosRUFBc0JnQyxJQUF0QixDQUEyQixHQUEzQixDQUEvQjtBQUVBLFlBQU1DLFVBQVUsR0FBR0gsT0FBTyxDQUFDLENBQUQsQ0FBMUI7QUFDQSxZQUFNSSxlQUFlLEdBQUcsRUFBeEI7QUFDQW5JLE1BQUFBLE1BQU0sQ0FBQytGLElBQVAsQ0FBWUUsUUFBWixFQUFzQkQsT0FBdEIsQ0FBOEJXLFFBQVEsSUFBSTtBQUN4QyxjQUFNeUIsWUFBWSxHQUFHbkMsUUFBUSxDQUFDVSxRQUFELENBQTdCO0FBQ0EsY0FBTTBCLFlBQVksR0FBR0gsVUFBVSxDQUFDakMsUUFBWCxDQUFvQlUsUUFBcEIsQ0FBckI7O0FBQ0EsWUFBSSxDQUFDeEMsZ0JBQUVJLE9BQUYsQ0FBVTZELFlBQVYsRUFBd0JDLFlBQXhCLENBQUwsRUFBNEM7QUFDMUNGLFVBQUFBLGVBQWUsQ0FBQ3hCLFFBQUQsQ0FBZixHQUE0QnlCLFlBQTVCO0FBQ0Q7QUFDRixPQU5EO0FBT0EsWUFBTUUsa0JBQWtCLEdBQUd0SSxNQUFNLENBQUMrRixJQUFQLENBQVlvQyxlQUFaLEVBQTZCckUsTUFBN0IsS0FBd0MsQ0FBbkU7QUFDQSxVQUFJeUUsTUFBSjs7QUFDQSxVQUFJLEtBQUtuSixLQUFMLElBQWMsS0FBS0EsS0FBTCxDQUFXZ0IsUUFBN0IsRUFBdUM7QUFDckNtSSxRQUFBQSxNQUFNLEdBQUcsS0FBS25KLEtBQUwsQ0FBV2dCLFFBQXBCO0FBQ0QsT0FGRCxNQUVPLElBQUksS0FBS2xCLElBQUwsSUFBYSxLQUFLQSxJQUFMLENBQVVvRCxJQUF2QixJQUErQixLQUFLcEQsSUFBTCxDQUFVb0QsSUFBVixDQUFlL0IsRUFBbEQsRUFBc0Q7QUFDM0RnSSxRQUFBQSxNQUFNLEdBQUcsS0FBS3JKLElBQUwsQ0FBVW9ELElBQVYsQ0FBZS9CLEVBQXhCO0FBQ0Q7O0FBQ0QsVUFBSSxDQUFDZ0ksTUFBRCxJQUFXQSxNQUFNLEtBQUtMLFVBQVUsQ0FBQzlILFFBQXJDLEVBQStDO0FBQzdDO0FBQ0E7QUFDQTtBQUNBLGVBQU8ySCxPQUFPLENBQUMsQ0FBRCxDQUFQLENBQVcxQixRQUFsQixDQUo2QyxDQU03Qzs7QUFDQSxhQUFLaEgsSUFBTCxDQUFVZSxRQUFWLEdBQXFCOEgsVUFBVSxDQUFDOUgsUUFBaEM7O0FBRUEsWUFBSSxDQUFDLEtBQUtoQixLQUFOLElBQWUsQ0FBQyxLQUFLQSxLQUFMLENBQVdnQixRQUEvQixFQUF5QztBQUN2QztBQUNBLGVBQUtJLFFBQUwsR0FBZ0I7QUFDZEEsWUFBQUEsUUFBUSxFQUFFMEgsVUFESTtBQUVkTSxZQUFBQSxRQUFRLEVBQUUsS0FBS0EsUUFBTDtBQUZJLFdBQWhCLENBRnVDLENBTXZDO0FBQ0E7QUFDQTs7QUFDQSxnQkFBTSxLQUFLL0QscUJBQUwsQ0FBMkJoRyxRQUFRLENBQUN5SixVQUFELENBQW5DLENBQU47QUFDRCxTQW5CNEMsQ0FxQjdDOzs7QUFDQSxZQUFJLENBQUNJLGtCQUFMLEVBQXlCO0FBQ3ZCO0FBQ0QsU0F4QjRDLENBeUI3QztBQUNBO0FBQ0E7QUFDQTs7O0FBQ0EsZUFBTyxLQUFLdkIsd0JBQUwsQ0FBOEJvQixlQUE5QixFQUErQ2xILElBQS9DLENBQW9ELFlBQVk7QUFDckU7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFJLEtBQUtULFFBQVQsRUFBbUI7QUFDakI7QUFDQVIsWUFBQUEsTUFBTSxDQUFDK0YsSUFBUCxDQUFZb0MsZUFBWixFQUE2Qm5DLE9BQTdCLENBQXFDVyxRQUFRLElBQUk7QUFDL0MsbUJBQUtuRyxRQUFMLENBQWNBLFFBQWQsQ0FBdUJ5RixRQUF2QixDQUFnQ1UsUUFBaEMsSUFBNEN3QixlQUFlLENBQUN4QixRQUFELENBQTNEO0FBQ0QsYUFGRCxFQUZpQixDQU1qQjtBQUNBO0FBQ0E7O0FBQ0EsbUJBQU8sS0FBSzFILE1BQUwsQ0FBWTRELFFBQVosQ0FBcUJjLE1BQXJCLENBQ0wsS0FBS3hFLFNBREEsRUFFTDtBQUFFaUIsY0FBQUEsUUFBUSxFQUFFLEtBQUtmLElBQUwsQ0FBVWU7QUFBdEIsYUFGSyxFQUdMO0FBQUU2RixjQUFBQSxRQUFRLEVBQUVrQztBQUFaLGFBSEssRUFJTCxFQUpLLENBQVA7QUFNRDtBQUNGLFNBckJNLENBQVA7QUFzQkQsT0FuREQsTUFtRE8sSUFBSUksTUFBSixFQUFZO0FBQ2pCO0FBQ0E7QUFDQSxZQUFJTCxVQUFVLENBQUM5SCxRQUFYLEtBQXdCbUksTUFBNUIsRUFBb0M7QUFDbEMsZ0JBQU0sSUFBSTFKLEtBQUssQ0FBQ2MsS0FBVixDQUFnQmQsS0FBSyxDQUFDYyxLQUFOLENBQVk4SSxzQkFBNUIsRUFBb0QsMkJBQXBELENBQU47QUFDRCxTQUxnQixDQU1qQjs7O0FBQ0EsWUFBSSxDQUFDSCxrQkFBTCxFQUF5QjtBQUN2QjtBQUNEO0FBQ0Y7QUFDRjs7QUFDRCxXQUFPLEtBQUt2Qix3QkFBTCxDQUE4QmQsUUFBOUIsRUFBd0NoRixJQUF4QyxDQUE2QyxNQUFNO0FBQ3hELFVBQUk4RyxPQUFPLENBQUNqRSxNQUFSLEdBQWlCLENBQXJCLEVBQXdCO0FBQ3RCO0FBQ0EsY0FBTSxJQUFJakYsS0FBSyxDQUFDYyxLQUFWLENBQWdCZCxLQUFLLENBQUNjLEtBQU4sQ0FBWThJLHNCQUE1QixFQUFvRCwyQkFBcEQsQ0FBTjtBQUNEO0FBQ0YsS0FMTSxDQUFQO0FBTUQsR0EzRk0sQ0FBUDtBQTRGRCxDQTlGRCxDLENBZ0dBOzs7QUFDQXpKLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0IyQixhQUFwQixHQUFvQyxZQUFZO0FBQzlDLE1BQUk4RyxPQUFPLEdBQUczSCxPQUFPLENBQUNDLE9BQVIsRUFBZDs7QUFFQSxNQUFJLEtBQUs3QixTQUFMLEtBQW1CLE9BQXZCLEVBQWdDO0FBQzlCLFdBQU91SixPQUFQO0FBQ0Q7O0FBRUQsTUFBSSxDQUFDLEtBQUt4SixJQUFMLENBQVVrRCxRQUFYLElBQXVCLG1CQUFtQixLQUFLL0MsSUFBbkQsRUFBeUQ7QUFDdkQsVUFBTXNKLEtBQUssR0FBSSwrREFBZjtBQUNBLFVBQU0sSUFBSTlKLEtBQUssQ0FBQ2MsS0FBVixDQUFnQmQsS0FBSyxDQUFDYyxLQUFOLENBQVlDLG1CQUE1QixFQUFpRCtJLEtBQWpELENBQU47QUFDRCxHQVY2QyxDQVk5Qzs7O0FBQ0EsTUFBSSxLQUFLdkosS0FBTCxJQUFjLEtBQUtnQixRQUFMLEVBQWxCLEVBQW1DO0FBQ2pDO0FBQ0E7QUFDQXNJLElBQUFBLE9BQU8sR0FBRyxJQUFJRSxrQkFBSixDQUFjLEtBQUszSixNQUFuQixFQUEyQlAsSUFBSSxDQUFDbUssTUFBTCxDQUFZLEtBQUs1SixNQUFqQixDQUEzQixFQUFxRCxVQUFyRCxFQUFpRTtBQUN6RXFELE1BQUFBLElBQUksRUFBRTtBQUNKd0csUUFBQUEsTUFBTSxFQUFFLFNBREo7QUFFSjNKLFFBQUFBLFNBQVMsRUFBRSxPQUZQO0FBR0ppQixRQUFBQSxRQUFRLEVBQUUsS0FBS0EsUUFBTDtBQUhOO0FBRG1FLEtBQWpFLEVBT1BVLE9BUE8sR0FRUEcsSUFSTyxDQVFGOEcsT0FBTyxJQUFJO0FBQ2ZBLE1BQUFBLE9BQU8sQ0FBQ0EsT0FBUixDQUFnQi9CLE9BQWhCLENBQXdCK0MsT0FBTyxJQUM3QixLQUFLOUosTUFBTCxDQUFZK0osZUFBWixDQUE0QjFHLElBQTVCLENBQWlDMkcsR0FBakMsQ0FBcUNGLE9BQU8sQ0FBQ0csWUFBN0MsQ0FERjtBQUdELEtBWk8sQ0FBVjtBQWFEOztBQUVELFNBQU9SLE9BQU8sQ0FDWHpILElBREksQ0FDQyxNQUFNO0FBQ1Y7QUFDQSxRQUFJLEtBQUs1QixJQUFMLENBQVVnSCxRQUFWLEtBQXVCZixTQUEzQixFQUFzQztBQUNwQztBQUNBLGFBQU92RSxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVELFFBQUksS0FBSzVCLEtBQVQsRUFBZ0I7QUFDZCxXQUFLUyxPQUFMLENBQWEsZUFBYixJQUFnQyxJQUFoQyxDQURjLENBRWQ7O0FBQ0EsVUFBSSxDQUFDLEtBQUtYLElBQUwsQ0FBVWtELFFBQWYsRUFBeUI7QUFDdkIsYUFBS3ZDLE9BQUwsQ0FBYSxvQkFBYixJQUFxQyxJQUFyQztBQUNEO0FBQ0Y7O0FBRUQsV0FBTyxLQUFLc0osdUJBQUwsR0FBK0JsSSxJQUEvQixDQUFvQyxNQUFNO0FBQy9DLGFBQU9yQyxjQUFjLENBQUN3SyxJQUFmLENBQW9CLEtBQUsvSixJQUFMLENBQVVnSCxRQUE5QixFQUF3Q3BGLElBQXhDLENBQTZDb0ksY0FBYyxJQUFJO0FBQ3BFLGFBQUtoSyxJQUFMLENBQVVpSyxnQkFBVixHQUE2QkQsY0FBN0I7QUFDQSxlQUFPLEtBQUtoSyxJQUFMLENBQVVnSCxRQUFqQjtBQUNELE9BSE0sQ0FBUDtBQUlELEtBTE0sQ0FBUDtBQU1ELEdBdEJJLEVBdUJKcEYsSUF2QkksQ0F1QkMsTUFBTTtBQUNWLFdBQU8sS0FBS3NJLGlCQUFMLEVBQVA7QUFDRCxHQXpCSSxFQTBCSnRJLElBMUJJLENBMEJDLE1BQU07QUFDVixXQUFPLEtBQUt1SSxjQUFMLEVBQVA7QUFDRCxHQTVCSSxDQUFQO0FBNkJELENBNUREOztBQThEQXhLLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0JzSixpQkFBcEIsR0FBd0MsWUFBWTtBQUNsRDtBQUNBLE1BQUksQ0FBQyxLQUFLbEssSUFBTCxDQUFVNkcsUUFBZixFQUF5QjtBQUN2QixRQUFJLENBQUMsS0FBSzlHLEtBQVYsRUFBaUI7QUFDZixXQUFLQyxJQUFMLENBQVU2RyxRQUFWLEdBQXFCdkgsV0FBVyxDQUFDOEssWUFBWixDQUF5QixFQUF6QixDQUFyQjtBQUNBLFdBQUtDLDBCQUFMLEdBQWtDLElBQWxDO0FBQ0Q7O0FBQ0QsV0FBTzNJLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0Q7QUFDRDtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUVFLFNBQU8sS0FBSy9CLE1BQUwsQ0FBWTRELFFBQVosQ0FDSm9DLElBREksQ0FFSCxLQUFLOUYsU0FGRixFQUdIO0FBQ0UrRyxJQUFBQSxRQUFRLEVBQUUsS0FBSzdHLElBQUwsQ0FBVTZHLFFBRHRCO0FBRUU5RixJQUFBQSxRQUFRLEVBQUU7QUFBRXVKLE1BQUFBLEdBQUcsRUFBRSxLQUFLdkosUUFBTDtBQUFQO0FBRlosR0FIRyxFQU9IO0FBQUV3SixJQUFBQSxLQUFLLEVBQUUsQ0FBVDtBQUFZQyxJQUFBQSxlQUFlLEVBQUU7QUFBN0IsR0FQRyxFQVFILEVBUkcsRUFTSCxLQUFLaEoscUJBVEYsRUFXSkksSUFYSSxDQVdDOEcsT0FBTyxJQUFJO0FBQ2YsUUFBSUEsT0FBTyxDQUFDakUsTUFBUixHQUFpQixDQUFyQixFQUF3QjtBQUN0QixZQUFNLElBQUlqRixLQUFLLENBQUNjLEtBQVYsQ0FDSmQsS0FBSyxDQUFDYyxLQUFOLENBQVltSyxjQURSLEVBRUosMkNBRkksQ0FBTjtBQUlEOztBQUNEO0FBQ0QsR0FuQkksQ0FBUDtBQW9CRCxDQXBDRDtBQXNDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNBOUssU0FBUyxDQUFDaUIsU0FBVixDQUFvQnVKLGNBQXBCLEdBQXFDLFlBQVk7QUFDL0MsTUFBSSxDQUFDLEtBQUtuSyxJQUFMLENBQVUwSyxLQUFYLElBQW9CLEtBQUsxSyxJQUFMLENBQVUwSyxLQUFWLENBQWdCeEUsSUFBaEIsS0FBeUIsUUFBakQsRUFBMkQ7QUFDekQsV0FBT3hFLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsR0FIOEMsQ0FJL0M7OztBQUNBLE1BQUksQ0FBQyxLQUFLM0IsSUFBTCxDQUFVMEssS0FBVixDQUFnQkMsS0FBaEIsQ0FBc0IsU0FBdEIsQ0FBTCxFQUF1QztBQUNyQyxXQUFPakosT0FBTyxDQUFDa0osTUFBUixDQUNMLElBQUlwTCxLQUFLLENBQUNjLEtBQVYsQ0FBZ0JkLEtBQUssQ0FBQ2MsS0FBTixDQUFZdUsscUJBQTVCLEVBQW1ELGtDQUFuRCxDQURLLENBQVA7QUFHRCxHQVQ4QyxDQVUvQzs7O0FBQ0EsU0FBTyxLQUFLakwsTUFBTCxDQUFZNEQsUUFBWixDQUNKb0MsSUFESSxDQUVILEtBQUs5RixTQUZGLEVBR0g7QUFDRTRLLElBQUFBLEtBQUssRUFBRSxLQUFLMUssSUFBTCxDQUFVMEssS0FEbkI7QUFFRTNKLElBQUFBLFFBQVEsRUFBRTtBQUFFdUosTUFBQUEsR0FBRyxFQUFFLEtBQUt2SixRQUFMO0FBQVA7QUFGWixHQUhHLEVBT0g7QUFBRXdKLElBQUFBLEtBQUssRUFBRSxDQUFUO0FBQVlDLElBQUFBLGVBQWUsRUFBRTtBQUE3QixHQVBHLEVBUUgsRUFSRyxFQVNILEtBQUtoSixxQkFURixFQVdKSSxJQVhJLENBV0M4RyxPQUFPLElBQUk7QUFDZixRQUFJQSxPQUFPLENBQUNqRSxNQUFSLEdBQWlCLENBQXJCLEVBQXdCO0FBQ3RCLFlBQU0sSUFBSWpGLEtBQUssQ0FBQ2MsS0FBVixDQUNKZCxLQUFLLENBQUNjLEtBQU4sQ0FBWXdLLFdBRFIsRUFFSixnREFGSSxDQUFOO0FBSUQ7O0FBQ0QsUUFDRSxDQUFDLEtBQUs5SyxJQUFMLENBQVU0RyxRQUFYLElBQ0EsQ0FBQ2pHLE1BQU0sQ0FBQytGLElBQVAsQ0FBWSxLQUFLMUcsSUFBTCxDQUFVNEcsUUFBdEIsRUFBZ0NuQyxNQURqQyxJQUVDOUQsTUFBTSxDQUFDK0YsSUFBUCxDQUFZLEtBQUsxRyxJQUFMLENBQVU0RyxRQUF0QixFQUFnQ25DLE1BQWhDLEtBQTJDLENBQTNDLElBQ0M5RCxNQUFNLENBQUMrRixJQUFQLENBQVksS0FBSzFHLElBQUwsQ0FBVTRHLFFBQXRCLEVBQWdDLENBQWhDLE1BQXVDLFdBSjNDLEVBS0U7QUFDQTtBQUNBLFdBQUtwRyxPQUFMLENBQWEsdUJBQWIsSUFBd0MsSUFBeEM7QUFDQSxXQUFLWixNQUFMLENBQVltTCxjQUFaLENBQTJCQyxtQkFBM0IsQ0FBK0MsS0FBS2hMLElBQXBEO0FBQ0Q7QUFDRixHQTVCSSxDQUFQO0FBNkJELENBeENEOztBQTBDQUwsU0FBUyxDQUFDaUIsU0FBVixDQUFvQmtKLHVCQUFwQixHQUE4QyxZQUFZO0FBQ3hELE1BQUksQ0FBQyxLQUFLbEssTUFBTCxDQUFZcUwsY0FBakIsRUFBaUMsT0FBT3ZKLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ2pDLFNBQU8sS0FBS3VKLDZCQUFMLEdBQXFDdEosSUFBckMsQ0FBMEMsTUFBTTtBQUNyRCxXQUFPLEtBQUt1Six3QkFBTCxFQUFQO0FBQ0QsR0FGTSxDQUFQO0FBR0QsQ0FMRDs7QUFPQXhMLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0JzSyw2QkFBcEIsR0FBb0QsWUFBWTtBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBTUUsV0FBVyxHQUFHLEtBQUt4TCxNQUFMLENBQVlxTCxjQUFaLENBQTJCSSxlQUEzQixHQUNoQixLQUFLekwsTUFBTCxDQUFZcUwsY0FBWixDQUEyQkksZUFEWCxHQUVoQiwwREFGSjtBQUdBLFFBQU1DLHFCQUFxQixHQUFHLHdDQUE5QixDQVo4RCxDQWM5RDs7QUFDQSxNQUNHLEtBQUsxTCxNQUFMLENBQVlxTCxjQUFaLENBQTJCTSxnQkFBM0IsSUFDQyxDQUFDLEtBQUszTCxNQUFMLENBQVlxTCxjQUFaLENBQTJCTSxnQkFBM0IsQ0FBNEMsS0FBS3ZMLElBQUwsQ0FBVWdILFFBQXRELENBREgsSUFFQyxLQUFLcEgsTUFBTCxDQUFZcUwsY0FBWixDQUEyQk8saUJBQTNCLElBQ0MsQ0FBQyxLQUFLNUwsTUFBTCxDQUFZcUwsY0FBWixDQUEyQk8saUJBQTNCLENBQTZDLEtBQUt4TCxJQUFMLENBQVVnSCxRQUF2RCxDQUpMLEVBS0U7QUFDQSxXQUFPdEYsT0FBTyxDQUFDa0osTUFBUixDQUFlLElBQUlwTCxLQUFLLENBQUNjLEtBQVYsQ0FBZ0JkLEtBQUssQ0FBQ2MsS0FBTixDQUFZZ0csZ0JBQTVCLEVBQThDOEUsV0FBOUMsQ0FBZixDQUFQO0FBQ0QsR0F0QjZELENBd0I5RDs7O0FBQ0EsTUFBSSxLQUFLeEwsTUFBTCxDQUFZcUwsY0FBWixDQUEyQlEsa0JBQTNCLEtBQWtELElBQXRELEVBQTREO0FBQzFELFFBQUksS0FBS3pMLElBQUwsQ0FBVTZHLFFBQWQsRUFBd0I7QUFDdEI7QUFDQSxVQUFJLEtBQUs3RyxJQUFMLENBQVVnSCxRQUFWLENBQW1CekQsT0FBbkIsQ0FBMkIsS0FBS3ZELElBQUwsQ0FBVTZHLFFBQXJDLEtBQWtELENBQXRELEVBQ0UsT0FBT25GLE9BQU8sQ0FBQ2tKLE1BQVIsQ0FBZSxJQUFJcEwsS0FBSyxDQUFDYyxLQUFWLENBQWdCZCxLQUFLLENBQUNjLEtBQU4sQ0FBWWdHLGdCQUE1QixFQUE4Q2dGLHFCQUE5QyxDQUFmLENBQVA7QUFDSCxLQUpELE1BSU87QUFDTDtBQUNBLGFBQU8sS0FBSzFMLE1BQUwsQ0FBWTRELFFBQVosQ0FBcUJvQyxJQUFyQixDQUEwQixPQUExQixFQUFtQztBQUFFN0UsUUFBQUEsUUFBUSxFQUFFLEtBQUtBLFFBQUw7QUFBWixPQUFuQyxFQUFrRWEsSUFBbEUsQ0FBdUU4RyxPQUFPLElBQUk7QUFDdkYsWUFBSUEsT0FBTyxDQUFDakUsTUFBUixJQUFrQixDQUF0QixFQUF5QjtBQUN2QixnQkFBTXdCLFNBQU47QUFDRDs7QUFDRCxZQUFJLEtBQUtqRyxJQUFMLENBQVVnSCxRQUFWLENBQW1CekQsT0FBbkIsQ0FBMkJtRixPQUFPLENBQUMsQ0FBRCxDQUFQLENBQVc3QixRQUF0QyxLQUFtRCxDQUF2RCxFQUNFLE9BQU9uRixPQUFPLENBQUNrSixNQUFSLENBQ0wsSUFBSXBMLEtBQUssQ0FBQ2MsS0FBVixDQUFnQmQsS0FBSyxDQUFDYyxLQUFOLENBQVlnRyxnQkFBNUIsRUFBOENnRixxQkFBOUMsQ0FESyxDQUFQO0FBR0YsZUFBTzVKLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsT0FUTSxDQUFQO0FBVUQ7QUFDRjs7QUFDRCxTQUFPRCxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELENBN0NEOztBQStDQWhDLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0J1Syx3QkFBcEIsR0FBK0MsWUFBWTtBQUN6RDtBQUNBLE1BQUksS0FBS3BMLEtBQUwsSUFBYyxLQUFLSCxNQUFMLENBQVlxTCxjQUFaLENBQTJCUyxrQkFBN0MsRUFBaUU7QUFDL0QsV0FBTyxLQUFLOUwsTUFBTCxDQUFZNEQsUUFBWixDQUNKb0MsSUFESSxDQUVILE9BRkcsRUFHSDtBQUFFN0UsTUFBQUEsUUFBUSxFQUFFLEtBQUtBLFFBQUw7QUFBWixLQUhHLEVBSUg7QUFBRTJGLE1BQUFBLElBQUksRUFBRSxDQUFDLG1CQUFELEVBQXNCLGtCQUF0QjtBQUFSLEtBSkcsRUFNSjlFLElBTkksQ0FNQzhHLE9BQU8sSUFBSTtBQUNmLFVBQUlBLE9BQU8sQ0FBQ2pFLE1BQVIsSUFBa0IsQ0FBdEIsRUFBeUI7QUFDdkIsY0FBTXdCLFNBQU47QUFDRDs7QUFDRCxZQUFNaEQsSUFBSSxHQUFHeUYsT0FBTyxDQUFDLENBQUQsQ0FBcEI7QUFDQSxVQUFJaUQsWUFBWSxHQUFHLEVBQW5CO0FBQ0EsVUFBSTFJLElBQUksQ0FBQzJJLGlCQUFULEVBQ0VELFlBQVksR0FBRzdHLGdCQUFFK0csSUFBRixDQUNiNUksSUFBSSxDQUFDMkksaUJBRFEsRUFFYixLQUFLaE0sTUFBTCxDQUFZcUwsY0FBWixDQUEyQlMsa0JBQTNCLEdBQWdELENBRm5DLENBQWY7QUFJRkMsTUFBQUEsWUFBWSxDQUFDeEcsSUFBYixDQUFrQmxDLElBQUksQ0FBQytELFFBQXZCO0FBQ0EsWUFBTThFLFdBQVcsR0FBRyxLQUFLOUwsSUFBTCxDQUFVZ0gsUUFBOUIsQ0FaZSxDQWFmOztBQUNBLFlBQU0rRSxRQUFRLEdBQUdKLFlBQVksQ0FBQy9ELEdBQWIsQ0FBaUIsVUFBVW1DLElBQVYsRUFBZ0I7QUFDaEQsZUFBT3hLLGNBQWMsQ0FBQ3lNLE9BQWYsQ0FBdUJGLFdBQXZCLEVBQW9DL0IsSUFBcEMsRUFBMENuSSxJQUExQyxDQUErQzRDLE1BQU0sSUFBSTtBQUM5RCxjQUFJQSxNQUFKLEVBQ0U7QUFDQSxtQkFBTzlDLE9BQU8sQ0FBQ2tKLE1BQVIsQ0FBZSxpQkFBZixDQUFQO0FBQ0YsaUJBQU9sSixPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELFNBTE0sQ0FBUDtBQU1ELE9BUGdCLENBQWpCLENBZGUsQ0FzQmY7O0FBQ0EsYUFBT0QsT0FBTyxDQUFDcUcsR0FBUixDQUFZZ0UsUUFBWixFQUNKbkssSUFESSxDQUNDLE1BQU07QUFDVixlQUFPRixPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELE9BSEksRUFJSnNLLEtBSkksQ0FJRUMsR0FBRyxJQUFJO0FBQ1osWUFBSUEsR0FBRyxLQUFLLGlCQUFaLEVBQ0U7QUFDQSxpQkFBT3hLLE9BQU8sQ0FBQ2tKLE1BQVIsQ0FDTCxJQUFJcEwsS0FBSyxDQUFDYyxLQUFWLENBQ0VkLEtBQUssQ0FBQ2MsS0FBTixDQUFZZ0csZ0JBRGQsRUFFRywrQ0FBOEMsS0FBSzFHLE1BQUwsQ0FBWXFMLGNBQVosQ0FBMkJTLGtCQUFtQixhQUYvRixDQURLLENBQVA7QUFNRixjQUFNUSxHQUFOO0FBQ0QsT0FkSSxDQUFQO0FBZUQsS0E1Q0ksQ0FBUDtBQTZDRDs7QUFDRCxTQUFPeEssT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxDQWxERDs7QUFvREFoQyxTQUFTLENBQUNpQixTQUFWLENBQW9CK0IsMEJBQXBCLEdBQWlELFlBQVk7QUFDM0QsTUFBSSxLQUFLN0MsU0FBTCxLQUFtQixPQUF2QixFQUFnQztBQUM5QjtBQUNELEdBSDBELENBSTNEOzs7QUFDQSxNQUFJLEtBQUtDLEtBQUwsSUFBYyxDQUFDLEtBQUtDLElBQUwsQ0FBVTRHLFFBQTdCLEVBQXVDO0FBQ3JDO0FBQ0QsR0FQMEQsQ0FRM0Q7OztBQUNBLE1BQUksS0FBSy9HLElBQUwsQ0FBVW9ELElBQVYsSUFBa0IsS0FBS2pELElBQUwsQ0FBVTRHLFFBQWhDLEVBQTBDO0FBQ3hDO0FBQ0Q7O0FBQ0QsTUFDRSxDQUFDLEtBQUtwRyxPQUFMLENBQWEsY0FBYixDQUFELElBQWlDO0FBQ2pDLE9BQUtaLE1BQUwsQ0FBWXVNLCtCQURaLElBQytDO0FBQy9DLE9BQUt2TSxNQUFMLENBQVl3TSxnQkFIZCxFQUlFO0FBQ0E7QUFDQSxXQUZBLENBRVE7QUFDVDs7QUFDRCxTQUFPLEtBQUtDLGtCQUFMLEVBQVA7QUFDRCxDQXJCRDs7QUF1QkExTSxTQUFTLENBQUNpQixTQUFWLENBQW9CeUwsa0JBQXBCLEdBQXlDLGtCQUFrQjtBQUN6RDtBQUNBO0FBQ0EsTUFBSSxLQUFLeE0sSUFBTCxDQUFVeU0sY0FBVixJQUE0QixLQUFLek0sSUFBTCxDQUFVeU0sY0FBVixLQUE2QixPQUE3RCxFQUFzRTtBQUNwRTtBQUNEOztBQUVELFFBQU07QUFBRUMsSUFBQUEsV0FBRjtBQUFlQyxJQUFBQTtBQUFmLE1BQWlDbk4sSUFBSSxDQUFDbU4sYUFBTCxDQUFtQixLQUFLNU0sTUFBeEIsRUFBZ0M7QUFDckVzSixJQUFBQSxNQUFNLEVBQUUsS0FBS25JLFFBQUwsRUFENkQ7QUFFckUwTCxJQUFBQSxXQUFXLEVBQUU7QUFDWHJNLE1BQUFBLE1BQU0sRUFBRSxLQUFLSSxPQUFMLENBQWEsY0FBYixJQUErQixPQUEvQixHQUF5QyxRQUR0QztBQUVYa00sTUFBQUEsWUFBWSxFQUFFLEtBQUtsTSxPQUFMLENBQWEsY0FBYixLQUFnQztBQUZuQyxLQUZ3RDtBQU1yRThMLElBQUFBLGNBQWMsRUFBRSxLQUFLek0sSUFBTCxDQUFVeU07QUFOMkMsR0FBaEMsQ0FBdkM7O0FBU0EsTUFBSSxLQUFLbkwsUUFBTCxJQUFpQixLQUFLQSxRQUFMLENBQWNBLFFBQW5DLEVBQTZDO0FBQzNDLFNBQUtBLFFBQUwsQ0FBY0EsUUFBZCxDQUF1QjBJLFlBQXZCLEdBQXNDMEMsV0FBVyxDQUFDMUMsWUFBbEQ7QUFDRDs7QUFFRCxTQUFPMkMsYUFBYSxFQUFwQjtBQUNELENBckJELEMsQ0F1QkE7OztBQUNBN00sU0FBUyxDQUFDaUIsU0FBVixDQUFvQnVCLDZCQUFwQixHQUFvRCxZQUFZO0FBQzlELE1BQUksS0FBS3JDLFNBQUwsS0FBbUIsT0FBbkIsSUFBOEIsS0FBS0MsS0FBTCxLQUFlLElBQWpELEVBQXVEO0FBQ3JEO0FBQ0E7QUFDRDs7QUFFRCxNQUFJLGNBQWMsS0FBS0MsSUFBbkIsSUFBMkIsV0FBVyxLQUFLQSxJQUEvQyxFQUFxRDtBQUNuRCxVQUFNMk0sTUFBTSxHQUFHO0FBQ2JDLE1BQUFBLGlCQUFpQixFQUFFO0FBQUUxRyxRQUFBQSxJQUFJLEVBQUU7QUFBUixPQUROO0FBRWIyRyxNQUFBQSw0QkFBNEIsRUFBRTtBQUFFM0csUUFBQUEsSUFBSSxFQUFFO0FBQVI7QUFGakIsS0FBZjtBQUlBLFNBQUtsRyxJQUFMLEdBQVlXLE1BQU0sQ0FBQ21NLE1BQVAsQ0FBYyxLQUFLOU0sSUFBbkIsRUFBeUIyTSxNQUF6QixDQUFaO0FBQ0Q7QUFDRixDQWJEOztBQWVBaE4sU0FBUyxDQUFDaUIsU0FBVixDQUFvQjZCLHlCQUFwQixHQUFnRCxZQUFZO0FBQzFEO0FBQ0EsTUFBSSxLQUFLM0MsU0FBTCxJQUFrQixVQUFsQixJQUFnQyxLQUFLQyxLQUF6QyxFQUFnRDtBQUM5QztBQUNELEdBSnlELENBSzFEOzs7QUFDQSxRQUFNO0FBQUVrRCxJQUFBQSxJQUFGO0FBQVFxSixJQUFBQSxjQUFSO0FBQXdCekMsSUFBQUE7QUFBeEIsTUFBeUMsS0FBSzdKLElBQXBEOztBQUNBLE1BQUksQ0FBQ2lELElBQUQsSUFBUyxDQUFDcUosY0FBZCxFQUE4QjtBQUM1QjtBQUNEOztBQUNELE1BQUksQ0FBQ3JKLElBQUksQ0FBQ2xDLFFBQVYsRUFBb0I7QUFDbEI7QUFDRDs7QUFDRCxPQUFLbkIsTUFBTCxDQUFZNEQsUUFBWixDQUFxQnVKLE9BQXJCLENBQ0UsVUFERixFQUVFO0FBQ0U5SixJQUFBQSxJQURGO0FBRUVxSixJQUFBQSxjQUZGO0FBR0V6QyxJQUFBQSxZQUFZLEVBQUU7QUFBRVMsTUFBQUEsR0FBRyxFQUFFVDtBQUFQO0FBSGhCLEdBRkYsRUFPRSxFQVBGLEVBUUUsS0FBS3JJLHFCQVJQO0FBVUQsQ0F2QkQsQyxDQXlCQTs7O0FBQ0E3QixTQUFTLENBQUNpQixTQUFWLENBQW9CZ0MsY0FBcEIsR0FBcUMsWUFBWTtBQUMvQyxNQUFJLEtBQUtwQyxPQUFMLElBQWdCLEtBQUtBLE9BQUwsQ0FBYSxlQUFiLENBQWhCLElBQWlELEtBQUtaLE1BQUwsQ0FBWW9OLDRCQUFqRSxFQUErRjtBQUM3RixRQUFJQyxZQUFZLEdBQUc7QUFDakJoSyxNQUFBQSxJQUFJLEVBQUU7QUFDSndHLFFBQUFBLE1BQU0sRUFBRSxTQURKO0FBRUozSixRQUFBQSxTQUFTLEVBQUUsT0FGUDtBQUdKaUIsUUFBQUEsUUFBUSxFQUFFLEtBQUtBLFFBQUw7QUFITjtBQURXLEtBQW5CO0FBT0EsV0FBTyxLQUFLUCxPQUFMLENBQWEsZUFBYixDQUFQO0FBQ0EsV0FBTyxLQUFLWixNQUFMLENBQVk0RCxRQUFaLENBQ0p1SixPQURJLENBQ0ksVUFESixFQUNnQkUsWUFEaEIsRUFFSnJMLElBRkksQ0FFQyxLQUFLZ0IsY0FBTCxDQUFvQnNLLElBQXBCLENBQXlCLElBQXpCLENBRkQsQ0FBUDtBQUdEOztBQUVELE1BQUksS0FBSzFNLE9BQUwsSUFBZ0IsS0FBS0EsT0FBTCxDQUFhLG9CQUFiLENBQXBCLEVBQXdEO0FBQ3RELFdBQU8sS0FBS0EsT0FBTCxDQUFhLG9CQUFiLENBQVA7QUFDQSxXQUFPLEtBQUs2TCxrQkFBTCxHQUEwQnpLLElBQTFCLENBQStCLEtBQUtnQixjQUFMLENBQW9Cc0ssSUFBcEIsQ0FBeUIsSUFBekIsQ0FBL0IsQ0FBUDtBQUNEOztBQUVELE1BQUksS0FBSzFNLE9BQUwsSUFBZ0IsS0FBS0EsT0FBTCxDQUFhLHVCQUFiLENBQXBCLEVBQTJEO0FBQ3pELFdBQU8sS0FBS0EsT0FBTCxDQUFhLHVCQUFiLENBQVAsQ0FEeUQsQ0FFekQ7O0FBQ0EsU0FBS1osTUFBTCxDQUFZbUwsY0FBWixDQUEyQm9DLHFCQUEzQixDQUFpRCxLQUFLbk4sSUFBdEQ7QUFDQSxXQUFPLEtBQUs0QyxjQUFMLENBQW9Cc0ssSUFBcEIsQ0FBeUIsSUFBekIsQ0FBUDtBQUNEO0FBQ0YsQ0ExQkQsQyxDQTRCQTtBQUNBOzs7QUFDQXZOLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0JvQixhQUFwQixHQUFvQyxZQUFZO0FBQzlDLE1BQUksS0FBS2IsUUFBTCxJQUFpQixLQUFLckIsU0FBTCxLQUFtQixVQUF4QyxFQUFvRDtBQUNsRDtBQUNEOztBQUVELE1BQUksQ0FBQyxLQUFLRCxJQUFMLENBQVVvRCxJQUFYLElBQW1CLENBQUMsS0FBS3BELElBQUwsQ0FBVWtELFFBQWxDLEVBQTRDO0FBQzFDLFVBQU0sSUFBSXZELEtBQUssQ0FBQ2MsS0FBVixDQUFnQmQsS0FBSyxDQUFDYyxLQUFOLENBQVk4TSxxQkFBNUIsRUFBbUQseUJBQW5ELENBQU47QUFDRCxHQVA2QyxDQVM5Qzs7O0FBQ0EsTUFBSSxLQUFLcE4sSUFBTCxDQUFVeUksR0FBZCxFQUFtQjtBQUNqQixVQUFNLElBQUlqSixLQUFLLENBQUNjLEtBQVYsQ0FBZ0JkLEtBQUssQ0FBQ2MsS0FBTixDQUFZVyxnQkFBNUIsRUFBOEMsZ0JBQWdCLG1CQUE5RCxDQUFOO0FBQ0Q7O0FBRUQsTUFBSSxLQUFLbEIsS0FBVCxFQUFnQjtBQUNkLFFBQUksS0FBS0MsSUFBTCxDQUFVaUQsSUFBVixJQUFrQixDQUFDLEtBQUtwRCxJQUFMLENBQVVrRCxRQUE3QixJQUF5QyxLQUFLL0MsSUFBTCxDQUFVaUQsSUFBVixDQUFlbEMsUUFBZixJQUEyQixLQUFLbEIsSUFBTCxDQUFVb0QsSUFBVixDQUFlL0IsRUFBdkYsRUFBMkY7QUFDekYsWUFBTSxJQUFJMUIsS0FBSyxDQUFDYyxLQUFWLENBQWdCZCxLQUFLLENBQUNjLEtBQU4sQ0FBWVcsZ0JBQTVCLENBQU47QUFDRCxLQUZELE1BRU8sSUFBSSxLQUFLakIsSUFBTCxDQUFVc00sY0FBZCxFQUE4QjtBQUNuQyxZQUFNLElBQUk5TSxLQUFLLENBQUNjLEtBQVYsQ0FBZ0JkLEtBQUssQ0FBQ2MsS0FBTixDQUFZVyxnQkFBNUIsQ0FBTjtBQUNELEtBRk0sTUFFQSxJQUFJLEtBQUtqQixJQUFMLENBQVU2SixZQUFkLEVBQTRCO0FBQ2pDLFlBQU0sSUFBSXJLLEtBQUssQ0FBQ2MsS0FBVixDQUFnQmQsS0FBSyxDQUFDYyxLQUFOLENBQVlXLGdCQUE1QixDQUFOO0FBQ0Q7QUFDRjs7QUFFRCxNQUFJLENBQUMsS0FBS2xCLEtBQU4sSUFBZSxDQUFDLEtBQUtGLElBQUwsQ0FBVWtELFFBQTlCLEVBQXdDO0FBQ3RDLFVBQU1zSyxxQkFBcUIsR0FBRyxFQUE5Qjs7QUFDQSxTQUFLLElBQUlwSSxHQUFULElBQWdCLEtBQUtqRixJQUFyQixFQUEyQjtBQUN6QixVQUFJaUYsR0FBRyxLQUFLLFVBQVIsSUFBc0JBLEdBQUcsS0FBSyxNQUFsQyxFQUEwQztBQUN4QztBQUNEOztBQUNEb0ksTUFBQUEscUJBQXFCLENBQUNwSSxHQUFELENBQXJCLEdBQTZCLEtBQUtqRixJQUFMLENBQVVpRixHQUFWLENBQTdCO0FBQ0Q7O0FBRUQsVUFBTTtBQUFFc0gsTUFBQUEsV0FBRjtBQUFlQyxNQUFBQTtBQUFmLFFBQWlDbk4sSUFBSSxDQUFDbU4sYUFBTCxDQUFtQixLQUFLNU0sTUFBeEIsRUFBZ0M7QUFDckVzSixNQUFBQSxNQUFNLEVBQUUsS0FBS3JKLElBQUwsQ0FBVW9ELElBQVYsQ0FBZS9CLEVBRDhDO0FBRXJFdUwsTUFBQUEsV0FBVyxFQUFFO0FBQ1hyTSxRQUFBQSxNQUFNLEVBQUU7QUFERyxPQUZ3RDtBQUtyRWlOLE1BQUFBO0FBTHFFLEtBQWhDLENBQXZDO0FBUUEsV0FBT2IsYUFBYSxHQUFHNUssSUFBaEIsQ0FBcUI4RyxPQUFPLElBQUk7QUFDckMsVUFBSSxDQUFDQSxPQUFPLENBQUN2SCxRQUFiLEVBQXVCO0FBQ3JCLGNBQU0sSUFBSTNCLEtBQUssQ0FBQ2MsS0FBVixDQUFnQmQsS0FBSyxDQUFDYyxLQUFOLENBQVlnTixxQkFBNUIsRUFBbUQseUJBQW5ELENBQU47QUFDRDs7QUFDRGYsTUFBQUEsV0FBVyxDQUFDLFVBQUQsQ0FBWCxHQUEwQjdELE9BQU8sQ0FBQ3ZILFFBQVIsQ0FBaUIsVUFBakIsQ0FBMUI7QUFDQSxXQUFLQSxRQUFMLEdBQWdCO0FBQ2RvTSxRQUFBQSxNQUFNLEVBQUUsR0FETTtBQUVkcEUsUUFBQUEsUUFBUSxFQUFFVCxPQUFPLENBQUNTLFFBRko7QUFHZGhJLFFBQUFBLFFBQVEsRUFBRW9MO0FBSEksT0FBaEI7QUFLRCxLQVZNLENBQVA7QUFXRDtBQUNGLENBckRELEMsQ0F1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0E1TSxTQUFTLENBQUNpQixTQUFWLENBQW9CbUIsa0JBQXBCLEdBQXlDLFlBQVk7QUFDbkQsTUFBSSxLQUFLWixRQUFMLElBQWlCLEtBQUtyQixTQUFMLEtBQW1CLGVBQXhDLEVBQXlEO0FBQ3ZEO0FBQ0Q7O0FBRUQsTUFDRSxDQUFDLEtBQUtDLEtBQU4sSUFDQSxDQUFDLEtBQUtDLElBQUwsQ0FBVXdOLFdBRFgsSUFFQSxDQUFDLEtBQUt4TixJQUFMLENBQVVzTSxjQUZYLElBR0EsQ0FBQyxLQUFLek0sSUFBTCxDQUFVeU0sY0FKYixFQUtFO0FBQ0EsVUFBTSxJQUFJOU0sS0FBSyxDQUFDYyxLQUFWLENBQ0osR0FESSxFQUVKLHlEQUF5RCxxQ0FGckQsQ0FBTjtBQUlELEdBZmtELENBaUJuRDtBQUNBOzs7QUFDQSxNQUFJLEtBQUtOLElBQUwsQ0FBVXdOLFdBQVYsSUFBeUIsS0FBS3hOLElBQUwsQ0FBVXdOLFdBQVYsQ0FBc0IvSSxNQUF0QixJQUFnQyxFQUE3RCxFQUFpRTtBQUMvRCxTQUFLekUsSUFBTCxDQUFVd04sV0FBVixHQUF3QixLQUFLeE4sSUFBTCxDQUFVd04sV0FBVixDQUFzQkMsV0FBdEIsRUFBeEI7QUFDRCxHQXJCa0QsQ0F1Qm5EOzs7QUFDQSxNQUFJLEtBQUt6TixJQUFMLENBQVVzTSxjQUFkLEVBQThCO0FBQzVCLFNBQUt0TSxJQUFMLENBQVVzTSxjQUFWLEdBQTJCLEtBQUt0TSxJQUFMLENBQVVzTSxjQUFWLENBQXlCbUIsV0FBekIsRUFBM0I7QUFDRDs7QUFFRCxNQUFJbkIsY0FBYyxHQUFHLEtBQUt0TSxJQUFMLENBQVVzTSxjQUEvQixDQTVCbUQsQ0E4Qm5EOztBQUNBLE1BQUksQ0FBQ0EsY0FBRCxJQUFtQixDQUFDLEtBQUt6TSxJQUFMLENBQVVrRCxRQUFsQyxFQUE0QztBQUMxQ3VKLElBQUFBLGNBQWMsR0FBRyxLQUFLek0sSUFBTCxDQUFVeU0sY0FBM0I7QUFDRDs7QUFFRCxNQUFJQSxjQUFKLEVBQW9CO0FBQ2xCQSxJQUFBQSxjQUFjLEdBQUdBLGNBQWMsQ0FBQ21CLFdBQWYsRUFBakI7QUFDRCxHQXJDa0QsQ0F1Q25EOzs7QUFDQSxNQUFJLEtBQUsxTixLQUFMLElBQWMsQ0FBQyxLQUFLQyxJQUFMLENBQVV3TixXQUF6QixJQUF3QyxDQUFDbEIsY0FBekMsSUFBMkQsQ0FBQyxLQUFLdE0sSUFBTCxDQUFVME4sVUFBMUUsRUFBc0Y7QUFDcEY7QUFDRDs7QUFFRCxNQUFJckUsT0FBTyxHQUFHM0gsT0FBTyxDQUFDQyxPQUFSLEVBQWQ7QUFFQSxNQUFJZ00sT0FBSixDQTlDbUQsQ0E4Q3RDOztBQUNiLE1BQUlDLGFBQUo7QUFDQSxNQUFJQyxtQkFBSjtBQUNBLE1BQUlDLGtCQUFrQixHQUFHLEVBQXpCLENBakRtRCxDQW1EbkQ7O0FBQ0EsUUFBTUMsU0FBUyxHQUFHLEVBQWxCOztBQUNBLE1BQUksS0FBS2hPLEtBQUwsSUFBYyxLQUFLQSxLQUFMLENBQVdnQixRQUE3QixFQUF1QztBQUNyQ2dOLElBQUFBLFNBQVMsQ0FBQzVJLElBQVYsQ0FBZTtBQUNicEUsTUFBQUEsUUFBUSxFQUFFLEtBQUtoQixLQUFMLENBQVdnQjtBQURSLEtBQWY7QUFHRDs7QUFDRCxNQUFJdUwsY0FBSixFQUFvQjtBQUNsQnlCLElBQUFBLFNBQVMsQ0FBQzVJLElBQVYsQ0FBZTtBQUNibUgsTUFBQUEsY0FBYyxFQUFFQTtBQURILEtBQWY7QUFHRDs7QUFDRCxNQUFJLEtBQUt0TSxJQUFMLENBQVV3TixXQUFkLEVBQTJCO0FBQ3pCTyxJQUFBQSxTQUFTLENBQUM1SSxJQUFWLENBQWU7QUFBRXFJLE1BQUFBLFdBQVcsRUFBRSxLQUFLeE4sSUFBTCxDQUFVd047QUFBekIsS0FBZjtBQUNEOztBQUVELE1BQUlPLFNBQVMsQ0FBQ3RKLE1BQVYsSUFBb0IsQ0FBeEIsRUFBMkI7QUFDekI7QUFDRDs7QUFFRDRFLEVBQUFBLE9BQU8sR0FBR0EsT0FBTyxDQUNkekgsSUFETyxDQUNGLE1BQU07QUFDVixXQUFPLEtBQUtoQyxNQUFMLENBQVk0RCxRQUFaLENBQXFCb0MsSUFBckIsQ0FDTCxlQURLLEVBRUw7QUFDRTBDLE1BQUFBLEdBQUcsRUFBRXlGO0FBRFAsS0FGSyxFQUtMLEVBTEssQ0FBUDtBQU9ELEdBVE8sRUFVUG5NLElBVk8sQ0FVRjhHLE9BQU8sSUFBSTtBQUNmQSxJQUFBQSxPQUFPLENBQUMvQixPQUFSLENBQWdCbkMsTUFBTSxJQUFJO0FBQ3hCLFVBQUksS0FBS3pFLEtBQUwsSUFBYyxLQUFLQSxLQUFMLENBQVdnQixRQUF6QixJQUFxQ3lELE1BQU0sQ0FBQ3pELFFBQVAsSUFBbUIsS0FBS2hCLEtBQUwsQ0FBV2dCLFFBQXZFLEVBQWlGO0FBQy9FNk0sUUFBQUEsYUFBYSxHQUFHcEosTUFBaEI7QUFDRDs7QUFDRCxVQUFJQSxNQUFNLENBQUM4SCxjQUFQLElBQXlCQSxjQUE3QixFQUE2QztBQUMzQ3VCLFFBQUFBLG1CQUFtQixHQUFHckosTUFBdEI7QUFDRDs7QUFDRCxVQUFJQSxNQUFNLENBQUNnSixXQUFQLElBQXNCLEtBQUt4TixJQUFMLENBQVV3TixXQUFwQyxFQUFpRDtBQUMvQ00sUUFBQUEsa0JBQWtCLENBQUMzSSxJQUFuQixDQUF3QlgsTUFBeEI7QUFDRDtBQUNGLEtBVkQsRUFEZSxDQWFmOztBQUNBLFFBQUksS0FBS3pFLEtBQUwsSUFBYyxLQUFLQSxLQUFMLENBQVdnQixRQUE3QixFQUF1QztBQUNyQyxVQUFJLENBQUM2TSxhQUFMLEVBQW9CO0FBQ2xCLGNBQU0sSUFBSXBPLEtBQUssQ0FBQ2MsS0FBVixDQUFnQmQsS0FBSyxDQUFDYyxLQUFOLENBQVlvRSxnQkFBNUIsRUFBOEMsOEJBQTlDLENBQU47QUFDRDs7QUFDRCxVQUNFLEtBQUsxRSxJQUFMLENBQVVzTSxjQUFWLElBQ0FzQixhQUFhLENBQUN0QixjQURkLElBRUEsS0FBS3RNLElBQUwsQ0FBVXNNLGNBQVYsS0FBNkJzQixhQUFhLENBQUN0QixjQUg3QyxFQUlFO0FBQ0EsY0FBTSxJQUFJOU0sS0FBSyxDQUFDYyxLQUFWLENBQWdCLEdBQWhCLEVBQXFCLCtDQUErQyxXQUFwRSxDQUFOO0FBQ0Q7O0FBQ0QsVUFDRSxLQUFLTixJQUFMLENBQVV3TixXQUFWLElBQ0FJLGFBQWEsQ0FBQ0osV0FEZCxJQUVBLEtBQUt4TixJQUFMLENBQVV3TixXQUFWLEtBQTBCSSxhQUFhLENBQUNKLFdBRnhDLElBR0EsQ0FBQyxLQUFLeE4sSUFBTCxDQUFVc00sY0FIWCxJQUlBLENBQUNzQixhQUFhLENBQUN0QixjQUxqQixFQU1FO0FBQ0EsY0FBTSxJQUFJOU0sS0FBSyxDQUFDYyxLQUFWLENBQWdCLEdBQWhCLEVBQXFCLDRDQUE0QyxXQUFqRSxDQUFOO0FBQ0Q7O0FBQ0QsVUFDRSxLQUFLTixJQUFMLENBQVUwTixVQUFWLElBQ0EsS0FBSzFOLElBQUwsQ0FBVTBOLFVBRFYsSUFFQSxLQUFLMU4sSUFBTCxDQUFVME4sVUFBVixLQUF5QkUsYUFBYSxDQUFDRixVQUh6QyxFQUlFO0FBQ0EsY0FBTSxJQUFJbE8sS0FBSyxDQUFDYyxLQUFWLENBQWdCLEdBQWhCLEVBQXFCLDJDQUEyQyxXQUFoRSxDQUFOO0FBQ0Q7QUFDRjs7QUFFRCxRQUFJLEtBQUtQLEtBQUwsSUFBYyxLQUFLQSxLQUFMLENBQVdnQixRQUF6QixJQUFxQzZNLGFBQXpDLEVBQXdEO0FBQ3RERCxNQUFBQSxPQUFPLEdBQUdDLGFBQVY7QUFDRDs7QUFFRCxRQUFJdEIsY0FBYyxJQUFJdUIsbUJBQXRCLEVBQTJDO0FBQ3pDRixNQUFBQSxPQUFPLEdBQUdFLG1CQUFWO0FBQ0QsS0FqRGMsQ0FrRGY7OztBQUNBLFFBQUksQ0FBQyxLQUFLOU4sS0FBTixJQUFlLENBQUMsS0FBS0MsSUFBTCxDQUFVME4sVUFBMUIsSUFBd0MsQ0FBQ0MsT0FBN0MsRUFBc0Q7QUFDcEQsWUFBTSxJQUFJbk8sS0FBSyxDQUFDYyxLQUFWLENBQWdCLEdBQWhCLEVBQXFCLGdEQUFyQixDQUFOO0FBQ0Q7QUFDRixHQWhFTyxFQWlFUHNCLElBakVPLENBaUVGLE1BQU07QUFDVixRQUFJLENBQUMrTCxPQUFMLEVBQWM7QUFDWixVQUFJLENBQUNHLGtCQUFrQixDQUFDckosTUFBeEIsRUFBZ0M7QUFDOUI7QUFDRCxPQUZELE1BRU8sSUFDTHFKLGtCQUFrQixDQUFDckosTUFBbkIsSUFBNkIsQ0FBN0IsS0FDQyxDQUFDcUosa0JBQWtCLENBQUMsQ0FBRCxDQUFsQixDQUFzQixnQkFBdEIsQ0FBRCxJQUE0QyxDQUFDeEIsY0FEOUMsQ0FESyxFQUdMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBT3dCLGtCQUFrQixDQUFDLENBQUQsQ0FBbEIsQ0FBc0IsVUFBdEIsQ0FBUDtBQUNELE9BUk0sTUFRQSxJQUFJLENBQUMsS0FBSzlOLElBQUwsQ0FBVXNNLGNBQWYsRUFBK0I7QUFDcEMsY0FBTSxJQUFJOU0sS0FBSyxDQUFDYyxLQUFWLENBQ0osR0FESSxFQUVKLGtEQUNFLHVDQUhFLENBQU47QUFLRCxPQU5NLE1BTUE7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBSTBOLFFBQVEsR0FBRztBQUNiUixVQUFBQSxXQUFXLEVBQUUsS0FBS3hOLElBQUwsQ0FBVXdOLFdBRFY7QUFFYmxCLFVBQUFBLGNBQWMsRUFBRTtBQUNkaEMsWUFBQUEsR0FBRyxFQUFFZ0M7QUFEUztBQUZILFNBQWY7O0FBTUEsWUFBSSxLQUFLdE0sSUFBTCxDQUFVaU8sYUFBZCxFQUE2QjtBQUMzQkQsVUFBQUEsUUFBUSxDQUFDLGVBQUQsQ0FBUixHQUE0QixLQUFLaE8sSUFBTCxDQUFVaU8sYUFBdEM7QUFDRDs7QUFDRCxhQUFLck8sTUFBTCxDQUFZNEQsUUFBWixDQUFxQnVKLE9BQXJCLENBQTZCLGVBQTdCLEVBQThDaUIsUUFBOUMsRUFBd0QvQixLQUF4RCxDQUE4REMsR0FBRyxJQUFJO0FBQ25FLGNBQUlBLEdBQUcsQ0FBQ2dDLElBQUosSUFBWTFPLEtBQUssQ0FBQ2MsS0FBTixDQUFZb0UsZ0JBQTVCLEVBQThDO0FBQzVDO0FBQ0E7QUFDRCxXQUprRSxDQUtuRTs7O0FBQ0EsZ0JBQU13SCxHQUFOO0FBQ0QsU0FQRDtBQVFBO0FBQ0Q7QUFDRixLQTFDRCxNQTBDTztBQUNMLFVBQUk0QixrQkFBa0IsQ0FBQ3JKLE1BQW5CLElBQTZCLENBQTdCLElBQWtDLENBQUNxSixrQkFBa0IsQ0FBQyxDQUFELENBQWxCLENBQXNCLGdCQUF0QixDQUF2QyxFQUFnRjtBQUM5RTtBQUNBO0FBQ0E7QUFDQSxjQUFNRSxRQUFRLEdBQUc7QUFBRWpOLFVBQUFBLFFBQVEsRUFBRTRNLE9BQU8sQ0FBQzVNO0FBQXBCLFNBQWpCO0FBQ0EsZUFBTyxLQUFLbkIsTUFBTCxDQUFZNEQsUUFBWixDQUNKdUosT0FESSxDQUNJLGVBREosRUFDcUJpQixRQURyQixFQUVKcE0sSUFGSSxDQUVDLE1BQU07QUFDVixpQkFBT2tNLGtCQUFrQixDQUFDLENBQUQsQ0FBbEIsQ0FBc0IsVUFBdEIsQ0FBUDtBQUNELFNBSkksRUFLSjdCLEtBTEksQ0FLRUMsR0FBRyxJQUFJO0FBQ1osY0FBSUEsR0FBRyxDQUFDZ0MsSUFBSixJQUFZMU8sS0FBSyxDQUFDYyxLQUFOLENBQVlvRSxnQkFBNUIsRUFBOEM7QUFDNUM7QUFDQTtBQUNELFdBSlcsQ0FLWjs7O0FBQ0EsZ0JBQU13SCxHQUFOO0FBQ0QsU0FaSSxDQUFQO0FBYUQsT0FsQkQsTUFrQk87QUFDTCxZQUFJLEtBQUtsTSxJQUFMLENBQVV3TixXQUFWLElBQXlCRyxPQUFPLENBQUNILFdBQVIsSUFBdUIsS0FBS3hOLElBQUwsQ0FBVXdOLFdBQTlELEVBQTJFO0FBQ3pFO0FBQ0E7QUFDQTtBQUNBLGdCQUFNUSxRQUFRLEdBQUc7QUFDZlIsWUFBQUEsV0FBVyxFQUFFLEtBQUt4TixJQUFMLENBQVV3TjtBQURSLFdBQWpCLENBSnlFLENBT3pFO0FBQ0E7O0FBQ0EsY0FBSSxLQUFLeE4sSUFBTCxDQUFVc00sY0FBZCxFQUE4QjtBQUM1QjBCLFlBQUFBLFFBQVEsQ0FBQyxnQkFBRCxDQUFSLEdBQTZCO0FBQzNCMUQsY0FBQUEsR0FBRyxFQUFFLEtBQUt0SyxJQUFMLENBQVVzTTtBQURZLGFBQTdCO0FBR0QsV0FKRCxNQUlPLElBQ0xxQixPQUFPLENBQUM1TSxRQUFSLElBQ0EsS0FBS2YsSUFBTCxDQUFVZSxRQURWLElBRUE0TSxPQUFPLENBQUM1TSxRQUFSLElBQW9CLEtBQUtmLElBQUwsQ0FBVWUsUUFIekIsRUFJTDtBQUNBO0FBQ0FpTixZQUFBQSxRQUFRLENBQUMsVUFBRCxDQUFSLEdBQXVCO0FBQ3JCMUQsY0FBQUEsR0FBRyxFQUFFcUQsT0FBTyxDQUFDNU07QUFEUSxhQUF2QjtBQUdELFdBVE0sTUFTQTtBQUNMO0FBQ0EsbUJBQU80TSxPQUFPLENBQUM1TSxRQUFmO0FBQ0Q7O0FBQ0QsY0FBSSxLQUFLZixJQUFMLENBQVVpTyxhQUFkLEVBQTZCO0FBQzNCRCxZQUFBQSxRQUFRLENBQUMsZUFBRCxDQUFSLEdBQTRCLEtBQUtoTyxJQUFMLENBQVVpTyxhQUF0QztBQUNEOztBQUNELGVBQUtyTyxNQUFMLENBQVk0RCxRQUFaLENBQXFCdUosT0FBckIsQ0FBNkIsZUFBN0IsRUFBOENpQixRQUE5QyxFQUF3RC9CLEtBQXhELENBQThEQyxHQUFHLElBQUk7QUFDbkUsZ0JBQUlBLEdBQUcsQ0FBQ2dDLElBQUosSUFBWTFPLEtBQUssQ0FBQ2MsS0FBTixDQUFZb0UsZ0JBQTVCLEVBQThDO0FBQzVDO0FBQ0E7QUFDRCxhQUprRSxDQUtuRTs7O0FBQ0Esa0JBQU13SCxHQUFOO0FBQ0QsV0FQRDtBQVFELFNBdENJLENBdUNMOzs7QUFDQSxlQUFPeUIsT0FBTyxDQUFDNU0sUUFBZjtBQUNEO0FBQ0Y7QUFDRixHQTFLTyxFQTJLUGEsSUEzS08sQ0EyS0Z1TSxLQUFLLElBQUk7QUFDYixRQUFJQSxLQUFKLEVBQVc7QUFDVCxXQUFLcE8sS0FBTCxHQUFhO0FBQUVnQixRQUFBQSxRQUFRLEVBQUVvTjtBQUFaLE9BQWI7QUFDQSxhQUFPLEtBQUtuTyxJQUFMLENBQVVlLFFBQWpCO0FBQ0EsYUFBTyxLQUFLZixJQUFMLENBQVV1RyxTQUFqQjtBQUNELEtBTFksQ0FNYjs7QUFDRCxHQWxMTyxDQUFWO0FBbUxBLFNBQU84QyxPQUFQO0FBQ0QsQ0EzUEQsQyxDQTZQQTtBQUNBO0FBQ0E7OztBQUNBMUosU0FBUyxDQUFDaUIsU0FBVixDQUFvQjRCLDZCQUFwQixHQUFvRCxZQUFZO0FBQzlEO0FBQ0EsTUFBSSxLQUFLckIsUUFBTCxJQUFpQixLQUFLQSxRQUFMLENBQWNBLFFBQW5DLEVBQTZDO0FBQzNDLFNBQUt2QixNQUFMLENBQVkyRixlQUFaLENBQTRCQyxtQkFBNUIsQ0FBZ0QsS0FBSzVGLE1BQXJELEVBQTZELEtBQUt1QixRQUFMLENBQWNBLFFBQTNFO0FBQ0Q7QUFDRixDQUxEOztBQU9BeEIsU0FBUyxDQUFDaUIsU0FBVixDQUFvQjhCLG9CQUFwQixHQUEyQyxZQUFZO0FBQ3JELE1BQUksS0FBS3ZCLFFBQVQsRUFBbUI7QUFDakI7QUFDRDs7QUFFRCxNQUFJLEtBQUtyQixTQUFMLEtBQW1CLE9BQXZCLEVBQWdDO0FBQzlCLFNBQUtGLE1BQUwsQ0FBWStKLGVBQVosQ0FBNEJ5RSxJQUE1QixDQUFpQ0MsS0FBakM7QUFDRDs7QUFFRCxNQUFJLEtBQUt2TyxTQUFMLEtBQW1CLE9BQW5CLElBQThCLEtBQUtDLEtBQW5DLElBQTRDLEtBQUtGLElBQUwsQ0FBVXlPLGlCQUFWLEVBQWhELEVBQStFO0FBQzdFLFVBQU0sSUFBSTlPLEtBQUssQ0FBQ2MsS0FBVixDQUNKZCxLQUFLLENBQUNjLEtBQU4sQ0FBWWlPLGVBRFIsRUFFSCxzQkFBcUIsS0FBS3hPLEtBQUwsQ0FBV2dCLFFBQVMsR0FGdEMsQ0FBTjtBQUlEOztBQUVELE1BQUksS0FBS2pCLFNBQUwsS0FBbUIsVUFBbkIsSUFBaUMsS0FBS0UsSUFBTCxDQUFVd08sUUFBL0MsRUFBeUQ7QUFDdkQsU0FBS3hPLElBQUwsQ0FBVXlPLFlBQVYsR0FBeUIsS0FBS3pPLElBQUwsQ0FBVXdPLFFBQVYsQ0FBbUJFLElBQTVDO0FBQ0QsR0FsQm9ELENBb0JyRDtBQUNBOzs7QUFDQSxNQUFJLEtBQUsxTyxJQUFMLENBQVV5SSxHQUFWLElBQWlCLEtBQUt6SSxJQUFMLENBQVV5SSxHQUFWLENBQWMsYUFBZCxDQUFyQixFQUFtRDtBQUNqRCxVQUFNLElBQUlqSixLQUFLLENBQUNjLEtBQVYsQ0FBZ0JkLEtBQUssQ0FBQ2MsS0FBTixDQUFZcU8sV0FBNUIsRUFBeUMsY0FBekMsQ0FBTjtBQUNEOztBQUVELE1BQUksS0FBSzVPLEtBQVQsRUFBZ0I7QUFDZDtBQUNBO0FBQ0EsUUFBSSxLQUFLRCxTQUFMLEtBQW1CLE9BQW5CLElBQThCLEtBQUtFLElBQUwsQ0FBVXlJLEdBQXhDLElBQStDLEtBQUs1SSxJQUFMLENBQVVrRCxRQUFWLEtBQXVCLElBQTFFLEVBQWdGO0FBQzlFLFdBQUsvQyxJQUFMLENBQVV5SSxHQUFWLENBQWMsS0FBSzFJLEtBQUwsQ0FBV2dCLFFBQXpCLElBQXFDO0FBQUU2TixRQUFBQSxJQUFJLEVBQUUsSUFBUjtBQUFjQyxRQUFBQSxLQUFLLEVBQUU7QUFBckIsT0FBckM7QUFDRCxLQUxhLENBTWQ7OztBQUNBLFFBQ0UsS0FBSy9PLFNBQUwsS0FBbUIsT0FBbkIsSUFDQSxLQUFLRSxJQUFMLENBQVVpSyxnQkFEVixJQUVBLEtBQUtySyxNQUFMLENBQVlxTCxjQUZaLElBR0EsS0FBS3JMLE1BQUwsQ0FBWXFMLGNBQVosQ0FBMkI2RCxjQUo3QixFQUtFO0FBQ0EsV0FBSzlPLElBQUwsQ0FBVStPLG9CQUFWLEdBQWlDdlAsS0FBSyxDQUFDNkIsT0FBTixDQUFjLElBQUlDLElBQUosRUFBZCxDQUFqQztBQUNELEtBZGEsQ0FlZDs7O0FBQ0EsV0FBTyxLQUFLdEIsSUFBTCxDQUFVdUcsU0FBakI7QUFFQSxRQUFJeUksS0FBSyxHQUFHdE4sT0FBTyxDQUFDQyxPQUFSLEVBQVosQ0FsQmMsQ0FtQmQ7O0FBQ0EsUUFDRSxLQUFLN0IsU0FBTCxLQUFtQixPQUFuQixJQUNBLEtBQUtFLElBQUwsQ0FBVWlLLGdCQURWLElBRUEsS0FBS3JLLE1BQUwsQ0FBWXFMLGNBRlosSUFHQSxLQUFLckwsTUFBTCxDQUFZcUwsY0FBWixDQUEyQlMsa0JBSjdCLEVBS0U7QUFDQXNELE1BQUFBLEtBQUssR0FBRyxLQUFLcFAsTUFBTCxDQUFZNEQsUUFBWixDQUNMb0MsSUFESyxDQUVKLE9BRkksRUFHSjtBQUFFN0UsUUFBQUEsUUFBUSxFQUFFLEtBQUtBLFFBQUw7QUFBWixPQUhJLEVBSUo7QUFBRTJGLFFBQUFBLElBQUksRUFBRSxDQUFDLG1CQUFELEVBQXNCLGtCQUF0QjtBQUFSLE9BSkksRUFNTDlFLElBTkssQ0FNQThHLE9BQU8sSUFBSTtBQUNmLFlBQUlBLE9BQU8sQ0FBQ2pFLE1BQVIsSUFBa0IsQ0FBdEIsRUFBeUI7QUFDdkIsZ0JBQU13QixTQUFOO0FBQ0Q7O0FBQ0QsY0FBTWhELElBQUksR0FBR3lGLE9BQU8sQ0FBQyxDQUFELENBQXBCO0FBQ0EsWUFBSWlELFlBQVksR0FBRyxFQUFuQjs7QUFDQSxZQUFJMUksSUFBSSxDQUFDMkksaUJBQVQsRUFBNEI7QUFDMUJELFVBQUFBLFlBQVksR0FBRzdHLGdCQUFFK0csSUFBRixDQUNiNUksSUFBSSxDQUFDMkksaUJBRFEsRUFFYixLQUFLaE0sTUFBTCxDQUFZcUwsY0FBWixDQUEyQlMsa0JBRmQsQ0FBZjtBQUlELFNBWGMsQ0FZZjs7O0FBQ0EsZUFDRUMsWUFBWSxDQUFDbEgsTUFBYixHQUFzQndLLElBQUksQ0FBQ0MsR0FBTCxDQUFTLENBQVQsRUFBWSxLQUFLdFAsTUFBTCxDQUFZcUwsY0FBWixDQUEyQlMsa0JBQTNCLEdBQWdELENBQTVELENBRHhCLEVBRUU7QUFDQUMsVUFBQUEsWUFBWSxDQUFDd0QsS0FBYjtBQUNEOztBQUNEeEQsUUFBQUEsWUFBWSxDQUFDeEcsSUFBYixDQUFrQmxDLElBQUksQ0FBQytELFFBQXZCO0FBQ0EsYUFBS2hILElBQUwsQ0FBVTRMLGlCQUFWLEdBQThCRCxZQUE5QjtBQUNELE9BMUJLLENBQVI7QUEyQkQ7O0FBRUQsV0FBT3FELEtBQUssQ0FBQ3BOLElBQU4sQ0FBVyxNQUFNO0FBQ3RCO0FBQ0EsYUFBTyxLQUFLaEMsTUFBTCxDQUFZNEQsUUFBWixDQUNKYyxNQURJLENBRUgsS0FBS3hFLFNBRkYsRUFHSCxLQUFLQyxLQUhGLEVBSUgsS0FBS0MsSUFKRixFQUtILEtBQUtTLFVBTEYsRUFNSCxLQU5HLEVBT0gsS0FQRyxFQVFILEtBQUtlLHFCQVJGLEVBVUpJLElBVkksQ0FVQ1QsUUFBUSxJQUFJO0FBQ2hCQSxRQUFBQSxRQUFRLENBQUNDLFNBQVQsR0FBcUIsS0FBS0EsU0FBMUI7O0FBQ0EsYUFBS2dPLHVCQUFMLENBQTZCak8sUUFBN0IsRUFBdUMsS0FBS25CLElBQTVDOztBQUNBLGFBQUttQixRQUFMLEdBQWdCO0FBQUVBLFVBQUFBO0FBQUYsU0FBaEI7QUFDRCxPQWRJLENBQVA7QUFlRCxLQWpCTSxDQUFQO0FBa0JELEdBekVELE1BeUVPO0FBQ0w7QUFDQSxRQUFJLEtBQUtyQixTQUFMLEtBQW1CLE9BQXZCLEVBQWdDO0FBQzlCLFVBQUkySSxHQUFHLEdBQUcsS0FBS3pJLElBQUwsQ0FBVXlJLEdBQXBCLENBRDhCLENBRTlCOztBQUNBLFVBQUksQ0FBQ0EsR0FBTCxFQUFVO0FBQ1JBLFFBQUFBLEdBQUcsR0FBRyxFQUFOO0FBQ0FBLFFBQUFBLEdBQUcsQ0FBQyxHQUFELENBQUgsR0FBVztBQUFFbUcsVUFBQUEsSUFBSSxFQUFFLElBQVI7QUFBY0MsVUFBQUEsS0FBSyxFQUFFO0FBQXJCLFNBQVg7QUFDRCxPQU42QixDQU85Qjs7O0FBQ0FwRyxNQUFBQSxHQUFHLENBQUMsS0FBS3pJLElBQUwsQ0FBVWUsUUFBWCxDQUFILEdBQTBCO0FBQUU2TixRQUFBQSxJQUFJLEVBQUUsSUFBUjtBQUFjQyxRQUFBQSxLQUFLLEVBQUU7QUFBckIsT0FBMUI7QUFDQSxXQUFLN08sSUFBTCxDQUFVeUksR0FBVixHQUFnQkEsR0FBaEIsQ0FUOEIsQ0FVOUI7O0FBQ0EsVUFBSSxLQUFLN0ksTUFBTCxDQUFZcUwsY0FBWixJQUE4QixLQUFLckwsTUFBTCxDQUFZcUwsY0FBWixDQUEyQjZELGNBQTdELEVBQTZFO0FBQzNFLGFBQUs5TyxJQUFMLENBQVUrTyxvQkFBVixHQUFpQ3ZQLEtBQUssQ0FBQzZCLE9BQU4sQ0FBYyxJQUFJQyxJQUFKLEVBQWQsQ0FBakM7QUFDRDtBQUNGLEtBaEJJLENBa0JMOzs7QUFDQSxXQUFPLEtBQUsxQixNQUFMLENBQVk0RCxRQUFaLENBQ0plLE1BREksQ0FDRyxLQUFLekUsU0FEUixFQUNtQixLQUFLRSxJQUR4QixFQUM4QixLQUFLUyxVQURuQyxFQUMrQyxLQUQvQyxFQUNzRCxLQUFLZSxxQkFEM0QsRUFFSnlLLEtBRkksQ0FFRTNDLEtBQUssSUFBSTtBQUNkLFVBQUksS0FBS3hKLFNBQUwsS0FBbUIsT0FBbkIsSUFBOEJ3SixLQUFLLENBQUM0RSxJQUFOLEtBQWUxTyxLQUFLLENBQUNjLEtBQU4sQ0FBWStPLGVBQTdELEVBQThFO0FBQzVFLGNBQU0vRixLQUFOO0FBQ0QsT0FIYSxDQUtkOzs7QUFDQSxVQUFJQSxLQUFLLElBQUlBLEtBQUssQ0FBQ2dHLFFBQWYsSUFBMkJoRyxLQUFLLENBQUNnRyxRQUFOLENBQWVDLGdCQUFmLEtBQW9DLFVBQW5FLEVBQStFO0FBQzdFLGNBQU0sSUFBSS9QLEtBQUssQ0FBQ2MsS0FBVixDQUNKZCxLQUFLLENBQUNjLEtBQU4sQ0FBWW1LLGNBRFIsRUFFSiwyQ0FGSSxDQUFOO0FBSUQ7O0FBRUQsVUFBSW5CLEtBQUssSUFBSUEsS0FBSyxDQUFDZ0csUUFBZixJQUEyQmhHLEtBQUssQ0FBQ2dHLFFBQU4sQ0FBZUMsZ0JBQWYsS0FBb0MsT0FBbkUsRUFBNEU7QUFDMUUsY0FBTSxJQUFJL1AsS0FBSyxDQUFDYyxLQUFWLENBQ0pkLEtBQUssQ0FBQ2MsS0FBTixDQUFZd0ssV0FEUixFQUVKLGdEQUZJLENBQU47QUFJRCxPQWxCYSxDQW9CZDtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0EsYUFBTyxLQUFLbEwsTUFBTCxDQUFZNEQsUUFBWixDQUNKb0MsSUFESSxDQUVILEtBQUs5RixTQUZGLEVBR0g7QUFDRStHLFFBQUFBLFFBQVEsRUFBRSxLQUFLN0csSUFBTCxDQUFVNkcsUUFEdEI7QUFFRTlGLFFBQUFBLFFBQVEsRUFBRTtBQUFFdUosVUFBQUEsR0FBRyxFQUFFLEtBQUt2SixRQUFMO0FBQVA7QUFGWixPQUhHLEVBT0g7QUFBRXdKLFFBQUFBLEtBQUssRUFBRTtBQUFULE9BUEcsRUFTSjNJLElBVEksQ0FTQzhHLE9BQU8sSUFBSTtBQUNmLFlBQUlBLE9BQU8sQ0FBQ2pFLE1BQVIsR0FBaUIsQ0FBckIsRUFBd0I7QUFDdEIsZ0JBQU0sSUFBSWpGLEtBQUssQ0FBQ2MsS0FBVixDQUNKZCxLQUFLLENBQUNjLEtBQU4sQ0FBWW1LLGNBRFIsRUFFSiwyQ0FGSSxDQUFOO0FBSUQ7O0FBQ0QsZUFBTyxLQUFLN0ssTUFBTCxDQUFZNEQsUUFBWixDQUFxQm9DLElBQXJCLENBQ0wsS0FBSzlGLFNBREEsRUFFTDtBQUFFNEssVUFBQUEsS0FBSyxFQUFFLEtBQUsxSyxJQUFMLENBQVUwSyxLQUFuQjtBQUEwQjNKLFVBQUFBLFFBQVEsRUFBRTtBQUFFdUosWUFBQUEsR0FBRyxFQUFFLEtBQUt2SixRQUFMO0FBQVA7QUFBcEMsU0FGSyxFQUdMO0FBQUV3SixVQUFBQSxLQUFLLEVBQUU7QUFBVCxTQUhLLENBQVA7QUFLRCxPQXJCSSxFQXNCSjNJLElBdEJJLENBc0JDOEcsT0FBTyxJQUFJO0FBQ2YsWUFBSUEsT0FBTyxDQUFDakUsTUFBUixHQUFpQixDQUFyQixFQUF3QjtBQUN0QixnQkFBTSxJQUFJakYsS0FBSyxDQUFDYyxLQUFWLENBQ0pkLEtBQUssQ0FBQ2MsS0FBTixDQUFZd0ssV0FEUixFQUVKLGdEQUZJLENBQU47QUFJRDs7QUFDRCxjQUFNLElBQUl0TCxLQUFLLENBQUNjLEtBQVYsQ0FDSmQsS0FBSyxDQUFDYyxLQUFOLENBQVkrTyxlQURSLEVBRUosK0RBRkksQ0FBTjtBQUlELE9BakNJLENBQVA7QUFrQ0QsS0E1REksRUE2REp6TixJQTdESSxDQTZEQ1QsUUFBUSxJQUFJO0FBQ2hCQSxNQUFBQSxRQUFRLENBQUNKLFFBQVQsR0FBb0IsS0FBS2YsSUFBTCxDQUFVZSxRQUE5QjtBQUNBSSxNQUFBQSxRQUFRLENBQUNvRixTQUFULEdBQXFCLEtBQUt2RyxJQUFMLENBQVV1RyxTQUEvQjs7QUFFQSxVQUFJLEtBQUs4RCwwQkFBVCxFQUFxQztBQUNuQ2xKLFFBQUFBLFFBQVEsQ0FBQzBGLFFBQVQsR0FBb0IsS0FBSzdHLElBQUwsQ0FBVTZHLFFBQTlCO0FBQ0Q7O0FBQ0QsV0FBS3VJLHVCQUFMLENBQTZCak8sUUFBN0IsRUFBdUMsS0FBS25CLElBQTVDOztBQUNBLFdBQUttQixRQUFMLEdBQWdCO0FBQ2RvTSxRQUFBQSxNQUFNLEVBQUUsR0FETTtBQUVkcE0sUUFBQUEsUUFGYztBQUdkZ0ksUUFBQUEsUUFBUSxFQUFFLEtBQUtBLFFBQUw7QUFISSxPQUFoQjtBQUtELEtBMUVJLENBQVA7QUEyRUQ7QUFDRixDQWxNRCxDLENBb01BOzs7QUFDQXhKLFNBQVMsQ0FBQ2lCLFNBQVYsQ0FBb0JpQyxtQkFBcEIsR0FBMEMsWUFBWTtBQUNwRCxNQUFJLENBQUMsS0FBSzFCLFFBQU4sSUFBa0IsQ0FBQyxLQUFLQSxRQUFMLENBQWNBLFFBQXJDLEVBQStDO0FBQzdDO0FBQ0QsR0FIbUQsQ0FLcEQ7OztBQUNBLFFBQU1xTyxnQkFBZ0IsR0FBRy9QLFFBQVEsQ0FBQ21FLGFBQVQsQ0FDdkIsS0FBSzlELFNBRGtCLEVBRXZCTCxRQUFRLENBQUNvRSxLQUFULENBQWU0TCxTQUZRLEVBR3ZCLEtBQUs3UCxNQUFMLENBQVltRSxhQUhXLENBQXpCO0FBS0EsUUFBTTJMLFlBQVksR0FBRyxLQUFLOVAsTUFBTCxDQUFZK1AsbUJBQVosQ0FBZ0NELFlBQWhDLENBQTZDLEtBQUs1UCxTQUFsRCxDQUFyQjs7QUFDQSxNQUFJLENBQUMwUCxnQkFBRCxJQUFxQixDQUFDRSxZQUExQixFQUF3QztBQUN0QyxXQUFPaE8sT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFRCxNQUFJcUMsU0FBUyxHQUFHO0FBQUVsRSxJQUFBQSxTQUFTLEVBQUUsS0FBS0E7QUFBbEIsR0FBaEI7O0FBQ0EsTUFBSSxLQUFLQyxLQUFMLElBQWMsS0FBS0EsS0FBTCxDQUFXZ0IsUUFBN0IsRUFBdUM7QUFDckNpRCxJQUFBQSxTQUFTLENBQUNqRCxRQUFWLEdBQXFCLEtBQUtoQixLQUFMLENBQVdnQixRQUFoQztBQUNELEdBbkJtRCxDQXFCcEQ7OztBQUNBLE1BQUlrRCxjQUFKOztBQUNBLE1BQUksS0FBS2xFLEtBQUwsSUFBYyxLQUFLQSxLQUFMLENBQVdnQixRQUE3QixFQUF1QztBQUNyQ2tELElBQUFBLGNBQWMsR0FBR3hFLFFBQVEsQ0FBQzJFLE9BQVQsQ0FBaUJKLFNBQWpCLEVBQTRCLEtBQUsvRCxZQUFqQyxDQUFqQjtBQUNELEdBekJtRCxDQTJCcEQ7QUFDQTs7O0FBQ0EsUUFBTWlFLGFBQWEsR0FBRyxLQUFLQyxrQkFBTCxDQUF3QkgsU0FBeEIsQ0FBdEI7O0FBQ0FFLEVBQUFBLGFBQWEsQ0FBQzBMLG1CQUFkLENBQWtDLEtBQUt6TyxRQUFMLENBQWNBLFFBQWhELEVBQTBELEtBQUtBLFFBQUwsQ0FBY29NLE1BQWQsSUFBd0IsR0FBbEY7O0FBRUEsT0FBSzNOLE1BQUwsQ0FBWTRELFFBQVosQ0FBcUJDLFVBQXJCLEdBQWtDN0IsSUFBbEMsQ0FBdUNTLGdCQUFnQixJQUFJO0FBQ3pEO0FBQ0EsVUFBTXdOLEtBQUssR0FBR3hOLGdCQUFnQixDQUFDeU4sd0JBQWpCLENBQTBDNUwsYUFBYSxDQUFDcEUsU0FBeEQsQ0FBZDtBQUNBLFNBQUtGLE1BQUwsQ0FBWStQLG1CQUFaLENBQWdDSSxXQUFoQyxDQUNFN0wsYUFBYSxDQUFDcEUsU0FEaEIsRUFFRW9FLGFBRkYsRUFHRUQsY0FIRixFQUlFNEwsS0FKRjtBQU1ELEdBVEQsRUFoQ29ELENBMkNwRDs7QUFDQSxTQUFPcFEsUUFBUSxDQUNaa0YsZUFESSxDQUVIbEYsUUFBUSxDQUFDb0UsS0FBVCxDQUFlNEwsU0FGWixFQUdILEtBQUs1UCxJQUhGLEVBSUhxRSxhQUpHLEVBS0hELGNBTEcsRUFNSCxLQUFLckUsTUFORixFQU9ILEtBQUtPLE9BUEYsRUFTSnlCLElBVEksQ0FTQzRDLE1BQU0sSUFBSTtBQUNkLFFBQUlBLE1BQU0sSUFBSSxPQUFPQSxNQUFQLEtBQWtCLFFBQWhDLEVBQTBDO0FBQ3hDLFdBQUtyRCxRQUFMLENBQWNBLFFBQWQsR0FBeUJxRCxNQUF6QjtBQUNEO0FBQ0YsR0FiSSxFQWNKeUgsS0FkSSxDQWNFLFVBQVVDLEdBQVYsRUFBZTtBQUNwQjhELG9CQUFPQyxJQUFQLENBQVksMkJBQVosRUFBeUMvRCxHQUF6QztBQUNELEdBaEJJLENBQVA7QUFpQkQsQ0E3REQsQyxDQStEQTs7O0FBQ0F2TSxTQUFTLENBQUNpQixTQUFWLENBQW9CdUksUUFBcEIsR0FBK0IsWUFBWTtBQUN6QyxNQUFJK0csTUFBTSxHQUFHLEtBQUtwUSxTQUFMLEtBQW1CLE9BQW5CLEdBQTZCLFNBQTdCLEdBQXlDLGNBQWMsS0FBS0EsU0FBbkIsR0FBK0IsR0FBckY7QUFDQSxRQUFNcVEsS0FBSyxHQUFHLEtBQUt2USxNQUFMLENBQVl1USxLQUFaLElBQXFCLEtBQUt2USxNQUFMLENBQVl3USxTQUEvQztBQUNBLFNBQU9ELEtBQUssR0FBR0QsTUFBUixHQUFpQixLQUFLbFEsSUFBTCxDQUFVZSxRQUFsQztBQUNELENBSkQsQyxDQU1BO0FBQ0E7OztBQUNBcEIsU0FBUyxDQUFDaUIsU0FBVixDQUFvQkcsUUFBcEIsR0FBK0IsWUFBWTtBQUN6QyxTQUFPLEtBQUtmLElBQUwsQ0FBVWUsUUFBVixJQUFzQixLQUFLaEIsS0FBTCxDQUFXZ0IsUUFBeEM7QUFDRCxDQUZELEMsQ0FJQTs7O0FBQ0FwQixTQUFTLENBQUNpQixTQUFWLENBQW9CeVAsYUFBcEIsR0FBb0MsWUFBWTtBQUM5QyxRQUFNclEsSUFBSSxHQUFHVyxNQUFNLENBQUMrRixJQUFQLENBQVksS0FBSzFHLElBQWpCLEVBQXVCK0UsTUFBdkIsQ0FBOEIsQ0FBQy9FLElBQUQsRUFBT2lGLEdBQVAsS0FBZTtBQUN4RDtBQUNBLFFBQUksQ0FBQywwQkFBMEJxTCxJQUExQixDQUErQnJMLEdBQS9CLENBQUwsRUFBMEM7QUFDeEMsYUFBT2pGLElBQUksQ0FBQ2lGLEdBQUQsQ0FBWDtBQUNEOztBQUNELFdBQU9qRixJQUFQO0FBQ0QsR0FOWSxFQU1WWixRQUFRLENBQUMsS0FBS1ksSUFBTixDQU5FLENBQWI7QUFPQSxTQUFPUixLQUFLLENBQUMrUSxPQUFOLENBQWN0SyxTQUFkLEVBQXlCakcsSUFBekIsQ0FBUDtBQUNELENBVEQsQyxDQVdBOzs7QUFDQUwsU0FBUyxDQUFDaUIsU0FBVixDQUFvQnVELGtCQUFwQixHQUF5QyxVQUFVSCxTQUFWLEVBQXFCO0FBQzVELFFBQU1FLGFBQWEsR0FBR3pFLFFBQVEsQ0FBQzJFLE9BQVQsQ0FBaUJKLFNBQWpCLEVBQTRCLEtBQUsvRCxZQUFqQyxDQUF0QjtBQUNBVSxFQUFBQSxNQUFNLENBQUMrRixJQUFQLENBQVksS0FBSzFHLElBQWpCLEVBQXVCK0UsTUFBdkIsQ0FBOEIsVUFBVS9FLElBQVYsRUFBZ0JpRixHQUFoQixFQUFxQjtBQUNqRCxRQUFJQSxHQUFHLENBQUMxQixPQUFKLENBQVksR0FBWixJQUFtQixDQUF2QixFQUEwQjtBQUN4QixVQUFJLE9BQU92RCxJQUFJLENBQUNpRixHQUFELENBQUosQ0FBVWlCLElBQWpCLEtBQTBCLFFBQTlCLEVBQXdDO0FBQ3RDaEMsUUFBQUEsYUFBYSxDQUFDc00sR0FBZCxDQUFrQnZMLEdBQWxCLEVBQXVCakYsSUFBSSxDQUFDaUYsR0FBRCxDQUEzQjtBQUNELE9BRkQsTUFFTztBQUNMO0FBQ0EsY0FBTXdMLFdBQVcsR0FBR3hMLEdBQUcsQ0FBQ3lMLEtBQUosQ0FBVSxHQUFWLENBQXBCO0FBQ0EsY0FBTUMsVUFBVSxHQUFHRixXQUFXLENBQUMsQ0FBRCxDQUE5QjtBQUNBLFlBQUlHLFNBQVMsR0FBRzFNLGFBQWEsQ0FBQzJNLEdBQWQsQ0FBa0JGLFVBQWxCLENBQWhCOztBQUNBLFlBQUksT0FBT0MsU0FBUCxLQUFxQixRQUF6QixFQUFtQztBQUNqQ0EsVUFBQUEsU0FBUyxHQUFHLEVBQVo7QUFDRDs7QUFDREEsUUFBQUEsU0FBUyxDQUFDSCxXQUFXLENBQUMsQ0FBRCxDQUFaLENBQVQsR0FBNEJ6USxJQUFJLENBQUNpRixHQUFELENBQWhDO0FBQ0FmLFFBQUFBLGFBQWEsQ0FBQ3NNLEdBQWQsQ0FBa0JHLFVBQWxCLEVBQThCQyxTQUE5QjtBQUNEOztBQUNELGFBQU81USxJQUFJLENBQUNpRixHQUFELENBQVg7QUFDRDs7QUFDRCxXQUFPakYsSUFBUDtBQUNELEdBbEJELEVBa0JHWixRQUFRLENBQUMsS0FBS1ksSUFBTixDQWxCWDtBQW9CQWtFLEVBQUFBLGFBQWEsQ0FBQ3NNLEdBQWQsQ0FBa0IsS0FBS0gsYUFBTCxFQUFsQjtBQUNBLFNBQU9uTSxhQUFQO0FBQ0QsQ0F4QkQ7O0FBMEJBdkUsU0FBUyxDQUFDaUIsU0FBVixDQUFvQmtDLGlCQUFwQixHQUF3QyxZQUFZO0FBQ2xELE1BQUksS0FBSzNCLFFBQUwsSUFBaUIsS0FBS0EsUUFBTCxDQUFjQSxRQUEvQixJQUEyQyxLQUFLckIsU0FBTCxLQUFtQixPQUFsRSxFQUEyRTtBQUN6RSxVQUFNbUQsSUFBSSxHQUFHLEtBQUs5QixRQUFMLENBQWNBLFFBQTNCOztBQUNBLFFBQUk4QixJQUFJLENBQUMyRCxRQUFULEVBQW1CO0FBQ2pCakcsTUFBQUEsTUFBTSxDQUFDK0YsSUFBUCxDQUFZekQsSUFBSSxDQUFDMkQsUUFBakIsRUFBMkJELE9BQTNCLENBQW1DVyxRQUFRLElBQUk7QUFDN0MsWUFBSXJFLElBQUksQ0FBQzJELFFBQUwsQ0FBY1UsUUFBZCxNQUE0QixJQUFoQyxFQUFzQztBQUNwQyxpQkFBT3JFLElBQUksQ0FBQzJELFFBQUwsQ0FBY1UsUUFBZCxDQUFQO0FBQ0Q7QUFDRixPQUpEOztBQUtBLFVBQUkzRyxNQUFNLENBQUMrRixJQUFQLENBQVl6RCxJQUFJLENBQUMyRCxRQUFqQixFQUEyQm5DLE1BQTNCLElBQXFDLENBQXpDLEVBQTRDO0FBQzFDLGVBQU94QixJQUFJLENBQUMyRCxRQUFaO0FBQ0Q7QUFDRjtBQUNGO0FBQ0YsQ0FkRDs7QUFnQkFqSCxTQUFTLENBQUNpQixTQUFWLENBQW9Cd08sdUJBQXBCLEdBQThDLFVBQVVqTyxRQUFWLEVBQW9CbkIsSUFBcEIsRUFBMEI7QUFDdEUsTUFBSThFLGdCQUFFZ0MsT0FBRixDQUFVLEtBQUt0RyxPQUFMLENBQWFxRSxzQkFBdkIsQ0FBSixFQUFvRDtBQUNsRCxXQUFPMUQsUUFBUDtBQUNEOztBQUNELFFBQU0yUCxvQkFBb0IsR0FBR3BSLFNBQVMsQ0FBQ3FSLHFCQUFWLENBQWdDLEtBQUs3USxTQUFyQyxDQUE3QjtBQUNBLE9BQUtNLE9BQUwsQ0FBYXFFLHNCQUFiLENBQW9DOEIsT0FBcEMsQ0FBNENaLFNBQVMsSUFBSTtBQUN2RCxVQUFNaUwsU0FBUyxHQUFHaFIsSUFBSSxDQUFDK0YsU0FBRCxDQUF0Qjs7QUFFQSxRQUFJLENBQUNwRixNQUFNLENBQUNDLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUFxQ0ssUUFBckMsRUFBK0M0RSxTQUEvQyxDQUFMLEVBQWdFO0FBQzlENUUsTUFBQUEsUUFBUSxDQUFDNEUsU0FBRCxDQUFSLEdBQXNCaUwsU0FBdEI7QUFDRCxLQUxzRCxDQU92RDs7O0FBQ0EsUUFBSTdQLFFBQVEsQ0FBQzRFLFNBQUQsQ0FBUixJQUF1QjVFLFFBQVEsQ0FBQzRFLFNBQUQsQ0FBUixDQUFvQkcsSUFBL0MsRUFBcUQ7QUFDbkQsYUFBTy9FLFFBQVEsQ0FBQzRFLFNBQUQsQ0FBZjs7QUFDQSxVQUFJK0ssb0JBQW9CLElBQUlFLFNBQVMsQ0FBQzlLLElBQVYsSUFBa0IsUUFBOUMsRUFBd0Q7QUFDdEQvRSxRQUFBQSxRQUFRLENBQUM0RSxTQUFELENBQVIsR0FBc0JpTCxTQUF0QjtBQUNEO0FBQ0Y7QUFDRixHQWREO0FBZUEsU0FBTzdQLFFBQVA7QUFDRCxDQXJCRDs7ZUF1QmV4QixTOztBQUNmc1IsTUFBTSxDQUFDQyxPQUFQLEdBQWlCdlIsU0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBBIFJlc3RXcml0ZSBlbmNhcHN1bGF0ZXMgZXZlcnl0aGluZyB3ZSBuZWVkIHRvIHJ1biBhbiBvcGVyYXRpb25cbi8vIHRoYXQgd3JpdGVzIHRvIHRoZSBkYXRhYmFzZS5cbi8vIFRoaXMgY291bGQgYmUgZWl0aGVyIGEgXCJjcmVhdGVcIiBvciBhbiBcInVwZGF0ZVwiLlxuXG52YXIgU2NoZW1hQ29udHJvbGxlciA9IHJlcXVpcmUoJy4vQ29udHJvbGxlcnMvU2NoZW1hQ29udHJvbGxlcicpO1xudmFyIGRlZXBjb3B5ID0gcmVxdWlyZSgnZGVlcGNvcHknKTtcblxuY29uc3QgQXV0aCA9IHJlcXVpcmUoJy4vQXV0aCcpO1xudmFyIGNyeXB0b1V0aWxzID0gcmVxdWlyZSgnLi9jcnlwdG9VdGlscycpO1xudmFyIHBhc3N3b3JkQ3J5cHRvID0gcmVxdWlyZSgnLi9wYXNzd29yZCcpO1xudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpO1xudmFyIHRyaWdnZXJzID0gcmVxdWlyZSgnLi90cmlnZ2VycycpO1xudmFyIENsaWVudFNESyA9IHJlcXVpcmUoJy4vQ2xpZW50U0RLJyk7XG5pbXBvcnQgUmVzdFF1ZXJ5IGZyb20gJy4vUmVzdFF1ZXJ5JztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4vbG9nZ2VyJztcblxuLy8gcXVlcnkgYW5kIGRhdGEgYXJlIGJvdGggcHJvdmlkZWQgaW4gUkVTVCBBUEkgZm9ybWF0LiBTbyBkYXRhXG4vLyB0eXBlcyBhcmUgZW5jb2RlZCBieSBwbGFpbiBvbGQgb2JqZWN0cy5cbi8vIElmIHF1ZXJ5IGlzIG51bGwsIHRoaXMgaXMgYSBcImNyZWF0ZVwiIGFuZCB0aGUgZGF0YSBpbiBkYXRhIHNob3VsZCBiZVxuLy8gY3JlYXRlZC5cbi8vIE90aGVyd2lzZSB0aGlzIGlzIGFuIFwidXBkYXRlXCIgLSB0aGUgb2JqZWN0IG1hdGNoaW5nIHRoZSBxdWVyeVxuLy8gc2hvdWxkIGdldCB1cGRhdGVkIHdpdGggZGF0YS5cbi8vIFJlc3RXcml0ZSB3aWxsIGhhbmRsZSBvYmplY3RJZCwgY3JlYXRlZEF0LCBhbmQgdXBkYXRlZEF0IGZvclxuLy8gZXZlcnl0aGluZy4gSXQgYWxzbyBrbm93cyB0byB1c2UgdHJpZ2dlcnMgYW5kIHNwZWNpYWwgbW9kaWZpY2F0aW9uc1xuLy8gZm9yIHRoZSBfVXNlciBjbGFzcy5cbmZ1bmN0aW9uIFJlc3RXcml0ZShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgcXVlcnksIGRhdGEsIG9yaWdpbmFsRGF0YSwgY2xpZW50U0RLLCBjb250ZXh0LCBhY3Rpb24pIHtcbiAgaWYgKGF1dGguaXNSZWFkT25seSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sXG4gICAgICAnQ2Fubm90IHBlcmZvcm0gYSB3cml0ZSBvcGVyYXRpb24gd2hlbiB1c2luZyByZWFkT25seU1hc3RlcktleSdcbiAgICApO1xuICB9XG4gIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICB0aGlzLmF1dGggPSBhdXRoO1xuICB0aGlzLmNsYXNzTmFtZSA9IGNsYXNzTmFtZTtcbiAgdGhpcy5jbGllbnRTREsgPSBjbGllbnRTREs7XG4gIHRoaXMuc3RvcmFnZSA9IHt9O1xuICB0aGlzLnJ1bk9wdGlvbnMgPSB7fTtcbiAgdGhpcy5jb250ZXh0ID0gY29udGV4dCB8fCB7fTtcblxuICBpZiAoYWN0aW9uKSB7XG4gICAgdGhpcy5ydW5PcHRpb25zLmFjdGlvbiA9IGFjdGlvbjtcbiAgfVxuXG4gIGlmICghcXVlcnkpIHtcbiAgICBpZiAodGhpcy5jb25maWcuYWxsb3dDdXN0b21PYmplY3RJZCkge1xuICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChkYXRhLCAnb2JqZWN0SWQnKSAmJiAhZGF0YS5vYmplY3RJZCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuTUlTU0lOR19PQkpFQ1RfSUQsXG4gICAgICAgICAgJ29iamVjdElkIG11c3Qgbm90IGJlIGVtcHR5LCBudWxsIG9yIHVuZGVmaW5lZCdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGRhdGEub2JqZWN0SWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUsICdvYmplY3RJZCBpcyBhbiBpbnZhbGlkIGZpZWxkIG5hbWUuJyk7XG4gICAgICB9XG4gICAgICBpZiAoZGF0YS5pZCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSwgJ2lkIGlzIGFuIGludmFsaWQgZmllbGQgbmFtZS4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBXaGVuIHRoZSBvcGVyYXRpb24gaXMgY29tcGxldGUsIHRoaXMucmVzcG9uc2UgbWF5IGhhdmUgc2V2ZXJhbFxuICAvLyBmaWVsZHMuXG4gIC8vIHJlc3BvbnNlOiB0aGUgYWN0dWFsIGRhdGEgdG8gYmUgcmV0dXJuZWRcbiAgLy8gc3RhdHVzOiB0aGUgaHR0cCBzdGF0dXMgY29kZS4gaWYgbm90IHByZXNlbnQsIHRyZWF0ZWQgbGlrZSBhIDIwMFxuICAvLyBsb2NhdGlvbjogdGhlIGxvY2F0aW9uIGhlYWRlci4gaWYgbm90IHByZXNlbnQsIG5vIGxvY2F0aW9uIGhlYWRlclxuICB0aGlzLnJlc3BvbnNlID0gbnVsbDtcblxuICAvLyBQcm9jZXNzaW5nIHRoaXMgb3BlcmF0aW9uIG1heSBtdXRhdGUgb3VyIGRhdGEsIHNvIHdlIG9wZXJhdGUgb24gYVxuICAvLyBjb3B5XG4gIHRoaXMucXVlcnkgPSBkZWVwY29weShxdWVyeSk7XG4gIHRoaXMuZGF0YSA9IGRlZXBjb3B5KGRhdGEpO1xuICAvLyBXZSBuZXZlciBjaGFuZ2Ugb3JpZ2luYWxEYXRhLCBzbyB3ZSBkbyBub3QgbmVlZCBhIGRlZXAgY29weVxuICB0aGlzLm9yaWdpbmFsRGF0YSA9IG9yaWdpbmFsRGF0YTtcblxuICAvLyBUaGUgdGltZXN0YW1wIHdlJ2xsIHVzZSBmb3IgdGhpcyB3aG9sZSBvcGVyYXRpb25cbiAgdGhpcy51cGRhdGVkQXQgPSBQYXJzZS5fZW5jb2RlKG5ldyBEYXRlKCkpLmlzbztcblxuICAvLyBTaGFyZWQgU2NoZW1hQ29udHJvbGxlciB0byBiZSByZXVzZWQgdG8gcmVkdWNlIHRoZSBudW1iZXIgb2YgbG9hZFNjaGVtYSgpIGNhbGxzIHBlciByZXF1ZXN0XG4gIC8vIE9uY2Ugc2V0IHRoZSBzY2hlbWFEYXRhIHNob3VsZCBiZSBpbW11dGFibGVcbiAgdGhpcy52YWxpZFNjaGVtYUNvbnRyb2xsZXIgPSBudWxsO1xufVxuXG4vLyBBIGNvbnZlbmllbnQgbWV0aG9kIHRvIHBlcmZvcm0gYWxsIHRoZSBzdGVwcyBvZiBwcm9jZXNzaW5nIHRoZVxuLy8gd3JpdGUsIGluIG9yZGVyLlxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGEge3Jlc3BvbnNlLCBzdGF0dXMsIGxvY2F0aW9ufSBvYmplY3QuXG4vLyBzdGF0dXMgYW5kIGxvY2F0aW9uIGFyZSBvcHRpb25hbC5cblJlc3RXcml0ZS5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0VXNlckFuZFJvbGVBQ0woKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlQ2xpZW50Q2xhc3NDcmVhdGlvbigpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlSW5zdGFsbGF0aW9uKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVTZXNzaW9uKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZUF1dGhEYXRhKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5ydW5CZWZvcmVTYXZlVHJpZ2dlcigpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZGVsZXRlRW1haWxSZXNldFRva2VuSWZOZWVkZWQoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlU2NoZW1hKCk7XG4gICAgfSlcbiAgICAudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHtcbiAgICAgIHRoaXMudmFsaWRTY2hlbWFDb250cm9sbGVyID0gc2NoZW1hQ29udHJvbGxlcjtcbiAgICAgIHJldHVybiB0aGlzLnNldFJlcXVpcmVkRmllbGRzSWZOZWVkZWQoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybVVzZXIoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmV4cGFuZEZpbGVzRm9yRXhpc3RpbmdPYmplY3RzKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5kZXN0cm95RHVwbGljYXRlZFNlc3Npb25zKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5ydW5EYXRhYmFzZU9wZXJhdGlvbigpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlU2Vzc2lvblRva2VuSWZOZWVkZWQoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZvbGxvd3VwKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5ydW5BZnRlclNhdmVUcmlnZ2VyKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5jbGVhblVzZXJBdXRoRGF0YSgpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMucmVzcG9uc2U7XG4gICAgfSk7XG59O1xuXG4vLyBVc2VzIHRoZSBBdXRoIG9iamVjdCB0byBnZXQgdGhlIGxpc3Qgb2Ygcm9sZXMsIGFkZHMgdGhlIHVzZXIgaWRcblJlc3RXcml0ZS5wcm90b3R5cGUuZ2V0VXNlckFuZFJvbGVBQ0wgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmF1dGguaXNNYXN0ZXIpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICB0aGlzLnJ1bk9wdGlvbnMuYWNsID0gWycqJ107XG5cbiAgaWYgKHRoaXMuYXV0aC51c2VyKSB7XG4gICAgcmV0dXJuIHRoaXMuYXV0aC5nZXRVc2VyUm9sZXMoKS50aGVuKHJvbGVzID0+IHtcbiAgICAgIHRoaXMucnVuT3B0aW9ucy5hY2wgPSB0aGlzLnJ1bk9wdGlvbnMuYWNsLmNvbmNhdChyb2xlcywgW3RoaXMuYXV0aC51c2VyLmlkXSk7XG4gICAgICByZXR1cm47XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG59O1xuXG4vLyBWYWxpZGF0ZXMgdGhpcyBvcGVyYXRpb24gYWdhaW5zdCB0aGUgYWxsb3dDbGllbnRDbGFzc0NyZWF0aW9uIGNvbmZpZy5cblJlc3RXcml0ZS5wcm90b3R5cGUudmFsaWRhdGVDbGllbnRDbGFzc0NyZWF0aW9uID0gZnVuY3Rpb24gKCkge1xuICBpZiAoXG4gICAgdGhpcy5jb25maWcuYWxsb3dDbGllbnRDbGFzc0NyZWF0aW9uID09PSBmYWxzZSAmJlxuICAgICF0aGlzLmF1dGguaXNNYXN0ZXIgJiZcbiAgICBTY2hlbWFDb250cm9sbGVyLnN5c3RlbUNsYXNzZXMuaW5kZXhPZih0aGlzLmNsYXNzTmFtZSkgPT09IC0xXG4gICkge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgICAgLmxvYWRTY2hlbWEoKVxuICAgICAgLnRoZW4oc2NoZW1hQ29udHJvbGxlciA9PiBzY2hlbWFDb250cm9sbGVyLmhhc0NsYXNzKHRoaXMuY2xhc3NOYW1lKSlcbiAgICAgIC50aGVuKGhhc0NsYXNzID0+IHtcbiAgICAgICAgaWYgKGhhc0NsYXNzICE9PSB0cnVlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgICAgICAgICdUaGlzIHVzZXIgaXMgbm90IGFsbG93ZWQgdG8gYWNjZXNzICcgKyAnbm9uLWV4aXN0ZW50IGNsYXNzOiAnICsgdGhpcy5jbGFzc05hbWVcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbn07XG5cbi8vIFZhbGlkYXRlcyB0aGlzIG9wZXJhdGlvbiBhZ2FpbnN0IHRoZSBzY2hlbWEuXG5SZXN0V3JpdGUucHJvdG90eXBlLnZhbGlkYXRlU2NoZW1hID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UudmFsaWRhdGVPYmplY3QoXG4gICAgdGhpcy5jbGFzc05hbWUsXG4gICAgdGhpcy5kYXRhLFxuICAgIHRoaXMucXVlcnksXG4gICAgdGhpcy5ydW5PcHRpb25zXG4gICk7XG59O1xuXG4vLyBSdW5zIGFueSBiZWZvcmVTYXZlIHRyaWdnZXJzIGFnYWluc3QgdGhpcyBvcGVyYXRpb24uXG4vLyBBbnkgY2hhbmdlIGxlYWRzIHRvIG91ciBkYXRhIGJlaW5nIG11dGF0ZWQuXG5SZXN0V3JpdGUucHJvdG90eXBlLnJ1bkJlZm9yZVNhdmVUcmlnZ2VyID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5yZXNwb25zZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEF2b2lkIGRvaW5nIGFueSBzZXR1cCBmb3IgdHJpZ2dlcnMgaWYgdGhlcmUgaXMgbm8gJ2JlZm9yZVNhdmUnIHRyaWdnZXIgZm9yIHRoaXMgY2xhc3MuXG4gIGlmIChcbiAgICAhdHJpZ2dlcnMudHJpZ2dlckV4aXN0cyh0aGlzLmNsYXNzTmFtZSwgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlU2F2ZSwgdGhpcy5jb25maWcuYXBwbGljYXRpb25JZClcbiAgKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgLy8gQ2xvdWQgY29kZSBnZXRzIGEgYml0IG9mIGV4dHJhIGRhdGEgZm9yIGl0cyBvYmplY3RzXG4gIHZhciBleHRyYURhdGEgPSB7IGNsYXNzTmFtZTogdGhpcy5jbGFzc05hbWUgfTtcbiAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgIGV4dHJhRGF0YS5vYmplY3RJZCA9IHRoaXMucXVlcnkub2JqZWN0SWQ7XG4gIH1cblxuICBsZXQgb3JpZ2luYWxPYmplY3QgPSBudWxsO1xuICBjb25zdCB1cGRhdGVkT2JqZWN0ID0gdGhpcy5idWlsZFVwZGF0ZWRPYmplY3QoZXh0cmFEYXRhKTtcbiAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgIC8vIFRoaXMgaXMgYW4gdXBkYXRlIGZvciBleGlzdGluZyBvYmplY3QuXG4gICAgb3JpZ2luYWxPYmplY3QgPSB0cmlnZ2Vycy5pbmZsYXRlKGV4dHJhRGF0YSwgdGhpcy5vcmlnaW5hbERhdGEpO1xuICB9XG5cbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgLy8gQmVmb3JlIGNhbGxpbmcgdGhlIHRyaWdnZXIsIHZhbGlkYXRlIHRoZSBwZXJtaXNzaW9ucyBmb3IgdGhlIHNhdmUgb3BlcmF0aW9uXG4gICAgICBsZXQgZGF0YWJhc2VQcm9taXNlID0gbnVsbDtcbiAgICAgIGlmICh0aGlzLnF1ZXJ5KSB7XG4gICAgICAgIC8vIFZhbGlkYXRlIGZvciB1cGRhdGluZ1xuICAgICAgICBkYXRhYmFzZVByb21pc2UgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS51cGRhdGUoXG4gICAgICAgICAgdGhpcy5jbGFzc05hbWUsXG4gICAgICAgICAgdGhpcy5xdWVyeSxcbiAgICAgICAgICB0aGlzLmRhdGEsXG4gICAgICAgICAgdGhpcy5ydW5PcHRpb25zLFxuICAgICAgICAgIHRydWUsXG4gICAgICAgICAgdHJ1ZVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVmFsaWRhdGUgZm9yIGNyZWF0aW5nXG4gICAgICAgIGRhdGFiYXNlUHJvbWlzZSA9IHRoaXMuY29uZmlnLmRhdGFiYXNlLmNyZWF0ZShcbiAgICAgICAgICB0aGlzLmNsYXNzTmFtZSxcbiAgICAgICAgICB0aGlzLmRhdGEsXG4gICAgICAgICAgdGhpcy5ydW5PcHRpb25zLFxuICAgICAgICAgIHRydWVcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIC8vIEluIHRoZSBjYXNlIHRoYXQgdGhlcmUgaXMgbm8gcGVybWlzc2lvbiBmb3IgdGhlIG9wZXJhdGlvbiwgaXQgdGhyb3dzIGFuIGVycm9yXG4gICAgICByZXR1cm4gZGF0YWJhc2VQcm9taXNlLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKCFyZXN1bHQgfHwgcmVzdWx0Lmxlbmd0aCA8PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kLicpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0cmlnZ2Vycy5tYXliZVJ1blRyaWdnZXIoXG4gICAgICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZVNhdmUsXG4gICAgICAgIHRoaXMuYXV0aCxcbiAgICAgICAgdXBkYXRlZE9iamVjdCxcbiAgICAgICAgb3JpZ2luYWxPYmplY3QsXG4gICAgICAgIHRoaXMuY29uZmlnLFxuICAgICAgICB0aGlzLmNvbnRleHRcbiAgICAgICk7XG4gICAgfSlcbiAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICBpZiAocmVzcG9uc2UgJiYgcmVzcG9uc2Uub2JqZWN0KSB7XG4gICAgICAgIHRoaXMuc3RvcmFnZS5maWVsZHNDaGFuZ2VkQnlUcmlnZ2VyID0gXy5yZWR1Y2UoXG4gICAgICAgICAgcmVzcG9uc2Uub2JqZWN0LFxuICAgICAgICAgIChyZXN1bHQsIHZhbHVlLCBrZXkpID0+IHtcbiAgICAgICAgICAgIGlmICghXy5pc0VxdWFsKHRoaXMuZGF0YVtrZXldLCB2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgcmVzdWx0LnB1c2goa2V5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBbXVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmRhdGEgPSByZXNwb25zZS5vYmplY3Q7XG4gICAgICAgIC8vIFdlIHNob3VsZCBkZWxldGUgdGhlIG9iamVjdElkIGZvciBhbiB1cGRhdGUgd3JpdGVcbiAgICAgICAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgICAgICAgIGRlbGV0ZSB0aGlzLmRhdGEub2JqZWN0SWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUucnVuQmVmb3JlTG9naW5UcmlnZ2VyID0gYXN5bmMgZnVuY3Rpb24gKHVzZXJEYXRhKSB7XG4gIC8vIEF2b2lkIGRvaW5nIGFueSBzZXR1cCBmb3IgdHJpZ2dlcnMgaWYgdGhlcmUgaXMgbm8gJ2JlZm9yZUxvZ2luJyB0cmlnZ2VyXG4gIGlmIChcbiAgICAhdHJpZ2dlcnMudHJpZ2dlckV4aXN0cyh0aGlzLmNsYXNzTmFtZSwgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlTG9naW4sIHRoaXMuY29uZmlnLmFwcGxpY2F0aW9uSWQpXG4gICkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIENsb3VkIGNvZGUgZ2V0cyBhIGJpdCBvZiBleHRyYSBkYXRhIGZvciBpdHMgb2JqZWN0c1xuICBjb25zdCBleHRyYURhdGEgPSB7IGNsYXNzTmFtZTogdGhpcy5jbGFzc05hbWUgfTtcblxuICAvLyBFeHBhbmQgZmlsZSBvYmplY3RzXG4gIHRoaXMuY29uZmlnLmZpbGVzQ29udHJvbGxlci5leHBhbmRGaWxlc0luT2JqZWN0KHRoaXMuY29uZmlnLCB1c2VyRGF0YSk7XG5cbiAgY29uc3QgdXNlciA9IHRyaWdnZXJzLmluZmxhdGUoZXh0cmFEYXRhLCB1c2VyRGF0YSk7XG5cbiAgLy8gbm8gbmVlZCB0byByZXR1cm4gYSByZXNwb25zZVxuICBhd2FpdCB0cmlnZ2Vycy5tYXliZVJ1blRyaWdnZXIoXG4gICAgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlTG9naW4sXG4gICAgdGhpcy5hdXRoLFxuICAgIHVzZXIsXG4gICAgbnVsbCxcbiAgICB0aGlzLmNvbmZpZyxcbiAgICB0aGlzLmNvbnRleHRcbiAgKTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuc2V0UmVxdWlyZWRGaWVsZHNJZk5lZWRlZCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuZGF0YSkge1xuICAgIHJldHVybiB0aGlzLnZhbGlkU2NoZW1hQ29udHJvbGxlci5nZXRBbGxDbGFzc2VzKCkudGhlbihhbGxDbGFzc2VzID0+IHtcbiAgICAgIGNvbnN0IHNjaGVtYSA9IGFsbENsYXNzZXMuZmluZChvbmVDbGFzcyA9PiBvbmVDbGFzcy5jbGFzc05hbWUgPT09IHRoaXMuY2xhc3NOYW1lKTtcbiAgICAgIGNvbnN0IHNldFJlcXVpcmVkRmllbGRJZk5lZWRlZCA9IChmaWVsZE5hbWUsIHNldERlZmF1bHQpID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRoaXMuZGF0YVtmaWVsZE5hbWVdID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgICB0aGlzLmRhdGFbZmllbGROYW1lXSA9PT0gbnVsbCB8fFxuICAgICAgICAgIHRoaXMuZGF0YVtmaWVsZE5hbWVdID09PSAnJyB8fFxuICAgICAgICAgICh0eXBlb2YgdGhpcy5kYXRhW2ZpZWxkTmFtZV0gPT09ICdvYmplY3QnICYmIHRoaXMuZGF0YVtmaWVsZE5hbWVdLl9fb3AgPT09ICdEZWxldGUnKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBzZXREZWZhdWx0ICYmXG4gICAgICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiZcbiAgICAgICAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS5kZWZhdWx0VmFsdWUgIT09IG51bGwgJiZcbiAgICAgICAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS5kZWZhdWx0VmFsdWUgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgKHRoaXMuZGF0YVtmaWVsZE5hbWVdID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgICAgICAgKHR5cGVvZiB0aGlzLmRhdGFbZmllbGROYW1lXSA9PT0gJ29iamVjdCcgJiYgdGhpcy5kYXRhW2ZpZWxkTmFtZV0uX19vcCA9PT0gJ0RlbGV0ZScpKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy5kYXRhW2ZpZWxkTmFtZV0gPSBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0uZGVmYXVsdFZhbHVlO1xuICAgICAgICAgICAgdGhpcy5zdG9yYWdlLmZpZWxkc0NoYW5nZWRCeVRyaWdnZXIgPSB0aGlzLnN0b3JhZ2UuZmllbGRzQ2hhbmdlZEJ5VHJpZ2dlciB8fCBbXTtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0b3JhZ2UuZmllbGRzQ2hhbmdlZEJ5VHJpZ2dlci5pbmRleE9mKGZpZWxkTmFtZSkgPCAwKSB7XG4gICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5maWVsZHNDaGFuZ2VkQnlUcmlnZ2VyLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0ucmVxdWlyZWQgPT09IHRydWUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5WQUxJREFUSU9OX0VSUk9SLCBgJHtmaWVsZE5hbWV9IGlzIHJlcXVpcmVkYCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICAvLyBBZGQgZGVmYXVsdCBmaWVsZHNcbiAgICAgIHRoaXMuZGF0YS51cGRhdGVkQXQgPSB0aGlzLnVwZGF0ZWRBdDtcbiAgICAgIGlmICghdGhpcy5xdWVyeSkge1xuICAgICAgICB0aGlzLmRhdGEuY3JlYXRlZEF0ID0gdGhpcy51cGRhdGVkQXQ7XG5cbiAgICAgICAgLy8gT25seSBhc3NpZ24gbmV3IG9iamVjdElkIGlmIHdlIGFyZSBjcmVhdGluZyBuZXcgb2JqZWN0XG4gICAgICAgIGlmICghdGhpcy5kYXRhLm9iamVjdElkKSB7XG4gICAgICAgICAgdGhpcy5kYXRhLm9iamVjdElkID0gY3J5cHRvVXRpbHMubmV3T2JqZWN0SWQodGhpcy5jb25maWcub2JqZWN0SWRTaXplKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2NoZW1hKSB7XG4gICAgICAgICAgT2JqZWN0LmtleXMoc2NoZW1hLmZpZWxkcykuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgICAgICAgc2V0UmVxdWlyZWRGaWVsZElmTmVlZGVkKGZpZWxkTmFtZSwgdHJ1ZSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoc2NoZW1hKSB7XG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMuZGF0YSkuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgICAgIHNldFJlcXVpcmVkRmllbGRJZk5lZWRlZChmaWVsZE5hbWUsIGZhbHNlKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufTtcblxuLy8gVHJhbnNmb3JtcyBhdXRoIGRhdGEgZm9yIGEgdXNlciBvYmplY3QuXG4vLyBEb2VzIG5vdGhpbmcgaWYgdGhpcyBpc24ndCBhIHVzZXIgb2JqZWN0LlxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIHdoZW4gd2UncmUgZG9uZSBpZiBpdCBjYW4ndCBmaW5pc2ggdGhpcyB0aWNrLlxuUmVzdFdyaXRlLnByb3RvdHlwZS52YWxpZGF0ZUF1dGhEYXRhID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jbGFzc05hbWUgIT09ICdfVXNlcicpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoIXRoaXMucXVlcnkgJiYgIXRoaXMuZGF0YS5hdXRoRGF0YSkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5kYXRhLnVzZXJuYW1lICE9PSAnc3RyaW5nJyB8fCBfLmlzRW1wdHkodGhpcy5kYXRhLnVzZXJuYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlVTRVJOQU1FX01JU1NJTkcsICdiYWQgb3IgbWlzc2luZyB1c2VybmFtZScpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHRoaXMuZGF0YS5wYXNzd29yZCAhPT0gJ3N0cmluZycgfHwgXy5pc0VtcHR5KHRoaXMuZGF0YS5wYXNzd29yZCkpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5QQVNTV09SRF9NSVNTSU5HLCAncGFzc3dvcmQgaXMgcmVxdWlyZWQnKTtcbiAgICB9XG4gIH1cblxuICBpZiAoXG4gICAgKHRoaXMuZGF0YS5hdXRoRGF0YSAmJiAhT2JqZWN0LmtleXModGhpcy5kYXRhLmF1dGhEYXRhKS5sZW5ndGgpIHx8XG4gICAgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLmRhdGEsICdhdXRoRGF0YScpXG4gICkge1xuICAgIC8vIEhhbmRsZSBzYXZpbmcgYXV0aERhdGEgdG8ge30gb3IgaWYgYXV0aERhdGEgZG9lc24ndCBleGlzdFxuICAgIHJldHVybjtcbiAgfSBlbHNlIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5kYXRhLCAnYXV0aERhdGEnKSAmJiAhdGhpcy5kYXRhLmF1dGhEYXRhKSB7XG4gICAgLy8gSGFuZGxlIHNhdmluZyBhdXRoRGF0YSB0byBudWxsXG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuVU5TVVBQT1JURURfU0VSVklDRSxcbiAgICAgICdUaGlzIGF1dGhlbnRpY2F0aW9uIG1ldGhvZCBpcyB1bnN1cHBvcnRlZC4nXG4gICAgKTtcbiAgfVxuXG4gIHZhciBhdXRoRGF0YSA9IHRoaXMuZGF0YS5hdXRoRGF0YTtcbiAgdmFyIHByb3ZpZGVycyA9IE9iamVjdC5rZXlzKGF1dGhEYXRhKTtcbiAgaWYgKHByb3ZpZGVycy5sZW5ndGggPiAwKSB7XG4gICAgY29uc3QgY2FuSGFuZGxlQXV0aERhdGEgPSBwcm92aWRlcnMucmVkdWNlKChjYW5IYW5kbGUsIHByb3ZpZGVyKSA9PiB7XG4gICAgICB2YXIgcHJvdmlkZXJBdXRoRGF0YSA9IGF1dGhEYXRhW3Byb3ZpZGVyXTtcbiAgICAgIHZhciBoYXNUb2tlbiA9IHByb3ZpZGVyQXV0aERhdGEgJiYgcHJvdmlkZXJBdXRoRGF0YS5pZDtcbiAgICAgIHJldHVybiBjYW5IYW5kbGUgJiYgKGhhc1Rva2VuIHx8IHByb3ZpZGVyQXV0aERhdGEgPT0gbnVsbCk7XG4gICAgfSwgdHJ1ZSk7XG4gICAgaWYgKGNhbkhhbmRsZUF1dGhEYXRhKSB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVBdXRoRGF0YShhdXRoRGF0YSk7XG4gICAgfVxuICB9XG4gIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICBQYXJzZS5FcnJvci5VTlNVUFBPUlRFRF9TRVJWSUNFLFxuICAgICdUaGlzIGF1dGhlbnRpY2F0aW9uIG1ldGhvZCBpcyB1bnN1cHBvcnRlZC4nXG4gICk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLmhhbmRsZUF1dGhEYXRhVmFsaWRhdGlvbiA9IGZ1bmN0aW9uIChhdXRoRGF0YSkge1xuICBjb25zdCB2YWxpZGF0aW9ucyA9IE9iamVjdC5rZXlzKGF1dGhEYXRhKS5tYXAocHJvdmlkZXIgPT4ge1xuICAgIGlmIChhdXRoRGF0YVtwcm92aWRlcl0gPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgY29uc3QgdmFsaWRhdGVBdXRoRGF0YSA9IHRoaXMuY29uZmlnLmF1dGhEYXRhTWFuYWdlci5nZXRWYWxpZGF0b3JGb3JQcm92aWRlcihwcm92aWRlcik7XG4gICAgaWYgKCF2YWxpZGF0ZUF1dGhEYXRhKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlVOU1VQUE9SVEVEX1NFUlZJQ0UsXG4gICAgICAgICdUaGlzIGF1dGhlbnRpY2F0aW9uIG1ldGhvZCBpcyB1bnN1cHBvcnRlZC4nXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YVtwcm92aWRlcl0pO1xuICB9KTtcbiAgcmV0dXJuIFByb21pc2UuYWxsKHZhbGlkYXRpb25zKTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuZmluZFVzZXJzV2l0aEF1dGhEYXRhID0gZnVuY3Rpb24gKGF1dGhEYXRhKSB7XG4gIGNvbnN0IHByb3ZpZGVycyA9IE9iamVjdC5rZXlzKGF1dGhEYXRhKTtcbiAgY29uc3QgcXVlcnkgPSBwcm92aWRlcnNcbiAgICAucmVkdWNlKChtZW1vLCBwcm92aWRlcikgPT4ge1xuICAgICAgaWYgKCFhdXRoRGF0YVtwcm92aWRlcl0pIHtcbiAgICAgICAgcmV0dXJuIG1lbW87XG4gICAgICB9XG4gICAgICBjb25zdCBxdWVyeUtleSA9IGBhdXRoRGF0YS4ke3Byb3ZpZGVyfS5pZGA7XG4gICAgICBjb25zdCBxdWVyeSA9IHt9O1xuICAgICAgcXVlcnlbcXVlcnlLZXldID0gYXV0aERhdGFbcHJvdmlkZXJdLmlkO1xuICAgICAgbWVtby5wdXNoKHF1ZXJ5KTtcbiAgICAgIHJldHVybiBtZW1vO1xuICAgIH0sIFtdKVxuICAgIC5maWx0ZXIocSA9PiB7XG4gICAgICByZXR1cm4gdHlwZW9mIHEgIT09ICd1bmRlZmluZWQnO1xuICAgIH0pO1xuXG4gIGxldCBmaW5kUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZShbXSk7XG4gIGlmIChxdWVyeS5sZW5ndGggPiAwKSB7XG4gICAgZmluZFByb21pc2UgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS5maW5kKHRoaXMuY2xhc3NOYW1lLCB7ICRvcjogcXVlcnkgfSwge30pO1xuICB9XG5cbiAgcmV0dXJuIGZpbmRQcm9taXNlO1xufTtcblxuUmVzdFdyaXRlLnByb3RvdHlwZS5maWx0ZXJlZE9iamVjdHNCeUFDTCA9IGZ1bmN0aW9uIChvYmplY3RzKSB7XG4gIGlmICh0aGlzLmF1dGguaXNNYXN0ZXIpIHtcbiAgICByZXR1cm4gb2JqZWN0cztcbiAgfVxuICByZXR1cm4gb2JqZWN0cy5maWx0ZXIob2JqZWN0ID0+IHtcbiAgICBpZiAoIW9iamVjdC5BQ0wpIHtcbiAgICAgIHJldHVybiB0cnVlOyAvLyBsZWdhY3kgdXNlcnMgdGhhdCBoYXZlIG5vIEFDTCBmaWVsZCBvbiB0aGVtXG4gICAgfVxuICAgIC8vIFJlZ3VsYXIgdXNlcnMgdGhhdCBoYXZlIGJlZW4gbG9ja2VkIG91dC5cbiAgICByZXR1cm4gb2JqZWN0LkFDTCAmJiBPYmplY3Qua2V5cyhvYmplY3QuQUNMKS5sZW5ndGggPiAwO1xuICB9KTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuaGFuZGxlQXV0aERhdGEgPSBmdW5jdGlvbiAoYXV0aERhdGEpIHtcbiAgbGV0IHJlc3VsdHM7XG4gIHJldHVybiB0aGlzLmZpbmRVc2Vyc1dpdGhBdXRoRGF0YShhdXRoRGF0YSkudGhlbihhc3luYyByID0+IHtcbiAgICByZXN1bHRzID0gdGhpcy5maWx0ZXJlZE9iamVjdHNCeUFDTChyKTtcblxuICAgIGlmIChyZXN1bHRzLmxlbmd0aCA9PSAxKSB7XG4gICAgICB0aGlzLnN0b3JhZ2VbJ2F1dGhQcm92aWRlciddID0gT2JqZWN0LmtleXMoYXV0aERhdGEpLmpvaW4oJywnKTtcblxuICAgICAgY29uc3QgdXNlclJlc3VsdCA9IHJlc3VsdHNbMF07XG4gICAgICBjb25zdCBtdXRhdGVkQXV0aERhdGEgPSB7fTtcbiAgICAgIE9iamVjdC5rZXlzKGF1dGhEYXRhKS5mb3JFYWNoKHByb3ZpZGVyID0+IHtcbiAgICAgICAgY29uc3QgcHJvdmlkZXJEYXRhID0gYXV0aERhdGFbcHJvdmlkZXJdO1xuICAgICAgICBjb25zdCB1c2VyQXV0aERhdGEgPSB1c2VyUmVzdWx0LmF1dGhEYXRhW3Byb3ZpZGVyXTtcbiAgICAgICAgaWYgKCFfLmlzRXF1YWwocHJvdmlkZXJEYXRhLCB1c2VyQXV0aERhdGEpKSB7XG4gICAgICAgICAgbXV0YXRlZEF1dGhEYXRhW3Byb3ZpZGVyXSA9IHByb3ZpZGVyRGF0YTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjb25zdCBoYXNNdXRhdGVkQXV0aERhdGEgPSBPYmplY3Qua2V5cyhtdXRhdGVkQXV0aERhdGEpLmxlbmd0aCAhPT0gMDtcbiAgICAgIGxldCB1c2VySWQ7XG4gICAgICBpZiAodGhpcy5xdWVyeSAmJiB0aGlzLnF1ZXJ5Lm9iamVjdElkKSB7XG4gICAgICAgIHVzZXJJZCA9IHRoaXMucXVlcnkub2JqZWN0SWQ7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuYXV0aCAmJiB0aGlzLmF1dGgudXNlciAmJiB0aGlzLmF1dGgudXNlci5pZCkge1xuICAgICAgICB1c2VySWQgPSB0aGlzLmF1dGgudXNlci5pZDtcbiAgICAgIH1cbiAgICAgIGlmICghdXNlcklkIHx8IHVzZXJJZCA9PT0gdXNlclJlc3VsdC5vYmplY3RJZCkge1xuICAgICAgICAvLyBubyB1c2VyIG1ha2luZyB0aGUgY2FsbFxuICAgICAgICAvLyBPUiB0aGUgdXNlciBtYWtpbmcgdGhlIGNhbGwgaXMgdGhlIHJpZ2h0IG9uZVxuICAgICAgICAvLyBMb2dpbiB3aXRoIGF1dGggZGF0YVxuICAgICAgICBkZWxldGUgcmVzdWx0c1swXS5wYXNzd29yZDtcblxuICAgICAgICAvLyBuZWVkIHRvIHNldCB0aGUgb2JqZWN0SWQgZmlyc3Qgb3RoZXJ3aXNlIGxvY2F0aW9uIGhhcyB0cmFpbGluZyB1bmRlZmluZWRcbiAgICAgICAgdGhpcy5kYXRhLm9iamVjdElkID0gdXNlclJlc3VsdC5vYmplY3RJZDtcblxuICAgICAgICBpZiAoIXRoaXMucXVlcnkgfHwgIXRoaXMucXVlcnkub2JqZWN0SWQpIHtcbiAgICAgICAgICAvLyB0aGlzIGEgbG9naW4gY2FsbCwgbm8gdXNlcklkIHBhc3NlZFxuICAgICAgICAgIHRoaXMucmVzcG9uc2UgPSB7XG4gICAgICAgICAgICByZXNwb25zZTogdXNlclJlc3VsdCxcbiAgICAgICAgICAgIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKCksXG4gICAgICAgICAgfTtcbiAgICAgICAgICAvLyBSdW4gYmVmb3JlTG9naW4gaG9vayBiZWZvcmUgc3RvcmluZyBhbnkgdXBkYXRlc1xuICAgICAgICAgIC8vIHRvIGF1dGhEYXRhIG9uIHRoZSBkYjsgY2hhbmdlcyB0byB1c2VyUmVzdWx0XG4gICAgICAgICAgLy8gd2lsbCBiZSBpZ25vcmVkLlxuICAgICAgICAgIGF3YWl0IHRoaXMucnVuQmVmb3JlTG9naW5UcmlnZ2VyKGRlZXBjb3B5KHVzZXJSZXN1bHQpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIHdlIGRpZG4ndCBjaGFuZ2UgdGhlIGF1dGggZGF0YSwganVzdCBrZWVwIGdvaW5nXG4gICAgICAgIGlmICghaGFzTXV0YXRlZEF1dGhEYXRhKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIFdlIGhhdmUgYXV0aERhdGEgdGhhdCBpcyB1cGRhdGVkIG9uIGxvZ2luXG4gICAgICAgIC8vIHRoYXQgY2FuIGhhcHBlbiB3aGVuIHRva2VuIGFyZSByZWZyZXNoZWQsXG4gICAgICAgIC8vIFdlIHNob3VsZCB1cGRhdGUgdGhlIHRva2VuIGFuZCBsZXQgdGhlIHVzZXIgaW5cbiAgICAgICAgLy8gV2Ugc2hvdWxkIG9ubHkgY2hlY2sgdGhlIG11dGF0ZWQga2V5c1xuICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVBdXRoRGF0YVZhbGlkYXRpb24obXV0YXRlZEF1dGhEYXRhKS50aGVuKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAvLyBJRiB3ZSBoYXZlIGEgcmVzcG9uc2UsIHdlJ2xsIHNraXAgdGhlIGRhdGFiYXNlIG9wZXJhdGlvbiAvIGJlZm9yZVNhdmUgLyBhZnRlclNhdmUgZXRjLi4uXG4gICAgICAgICAgLy8gd2UgbmVlZCB0byBzZXQgaXQgdXAgdGhlcmUuXG4gICAgICAgICAgLy8gV2UgYXJlIHN1cHBvc2VkIHRvIGhhdmUgYSByZXNwb25zZSBvbmx5IG9uIExPR0lOIHdpdGggYXV0aERhdGEsIHNvIHdlIHNraXAgdGhvc2VcbiAgICAgICAgICAvLyBJZiB3ZSdyZSBub3QgbG9nZ2luZyBpbiwgYnV0IGp1c3QgdXBkYXRpbmcgdGhlIGN1cnJlbnQgdXNlciwgd2UgY2FuIHNhZmVseSBza2lwIHRoYXQgcGFydFxuICAgICAgICAgIGlmICh0aGlzLnJlc3BvbnNlKSB7XG4gICAgICAgICAgICAvLyBBc3NpZ24gdGhlIG5ldyBhdXRoRGF0YSBpbiB0aGUgcmVzcG9uc2VcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKG11dGF0ZWRBdXRoRGF0YSkuZm9yRWFjaChwcm92aWRlciA9PiB7XG4gICAgICAgICAgICAgIHRoaXMucmVzcG9uc2UucmVzcG9uc2UuYXV0aERhdGFbcHJvdmlkZXJdID0gbXV0YXRlZEF1dGhEYXRhW3Byb3ZpZGVyXTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBSdW4gdGhlIERCIHVwZGF0ZSBkaXJlY3RseSwgYXMgJ21hc3RlcidcbiAgICAgICAgICAgIC8vIEp1c3QgdXBkYXRlIHRoZSBhdXRoRGF0YSBwYXJ0XG4gICAgICAgICAgICAvLyBUaGVuIHdlJ3JlIGdvb2QgZm9yIHRoZSB1c2VyLCBlYXJseSBleGl0IG9mIHNvcnRzXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UudXBkYXRlKFxuICAgICAgICAgICAgICB0aGlzLmNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgeyBvYmplY3RJZDogdGhpcy5kYXRhLm9iamVjdElkIH0sXG4gICAgICAgICAgICAgIHsgYXV0aERhdGE6IG11dGF0ZWRBdXRoRGF0YSB9LFxuICAgICAgICAgICAgICB7fVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmICh1c2VySWQpIHtcbiAgICAgICAgLy8gVHJ5aW5nIHRvIHVwZGF0ZSBhdXRoIGRhdGEgYnV0IHVzZXJzXG4gICAgICAgIC8vIGFyZSBkaWZmZXJlbnRcbiAgICAgICAgaWYgKHVzZXJSZXN1bHQub2JqZWN0SWQgIT09IHVzZXJJZCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5BQ0NPVU5UX0FMUkVBRFlfTElOS0VELCAndGhpcyBhdXRoIGlzIGFscmVhZHkgdXNlZCcpO1xuICAgICAgICB9XG4gICAgICAgIC8vIE5vIGF1dGggZGF0YSB3YXMgbXV0YXRlZCwganVzdCBrZWVwIGdvaW5nXG4gICAgICAgIGlmICghaGFzTXV0YXRlZEF1dGhEYXRhKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmhhbmRsZUF1dGhEYXRhVmFsaWRhdGlvbihhdXRoRGF0YSkudGhlbigoKSA9PiB7XG4gICAgICBpZiAocmVzdWx0cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIC8vIE1vcmUgdGhhbiAxIHVzZXIgd2l0aCB0aGUgcGFzc2VkIGlkJ3NcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkFDQ09VTlRfQUxSRUFEWV9MSU5LRUQsICd0aGlzIGF1dGggaXMgYWxyZWFkeSB1c2VkJyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufTtcblxuLy8gVGhlIG5vbi10aGlyZC1wYXJ0eSBwYXJ0cyBvZiBVc2VyIHRyYW5zZm9ybWF0aW9uXG5SZXN0V3JpdGUucHJvdG90eXBlLnRyYW5zZm9ybVVzZXIgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBwcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG5cbiAgaWYgKHRoaXMuY2xhc3NOYW1lICE9PSAnX1VzZXInKSB7XG4gICAgcmV0dXJuIHByb21pc2U7XG4gIH1cblxuICBpZiAoIXRoaXMuYXV0aC5pc01hc3RlciAmJiAnZW1haWxWZXJpZmllZCcgaW4gdGhpcy5kYXRhKSB7XG4gICAgY29uc3QgZXJyb3IgPSBgQ2xpZW50cyBhcmVuJ3QgYWxsb3dlZCB0byBtYW51YWxseSB1cGRhdGUgZW1haWwgdmVyaWZpY2F0aW9uLmA7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sIGVycm9yKTtcbiAgfVxuXG4gIC8vIERvIG5vdCBjbGVhbnVwIHNlc3Npb24gaWYgb2JqZWN0SWQgaXMgbm90IHNldFxuICBpZiAodGhpcy5xdWVyeSAmJiB0aGlzLm9iamVjdElkKCkpIHtcbiAgICAvLyBJZiB3ZSdyZSB1cGRhdGluZyBhIF9Vc2VyIG9iamVjdCwgd2UgbmVlZCB0byBjbGVhciBvdXQgdGhlIGNhY2hlIGZvciB0aGF0IHVzZXIuIEZpbmQgYWxsIHRoZWlyXG4gICAgLy8gc2Vzc2lvbiB0b2tlbnMsIGFuZCByZW1vdmUgdGhlbSBmcm9tIHRoZSBjYWNoZS5cbiAgICBwcm9taXNlID0gbmV3IFJlc3RRdWVyeSh0aGlzLmNvbmZpZywgQXV0aC5tYXN0ZXIodGhpcy5jb25maWcpLCAnX1Nlc3Npb24nLCB7XG4gICAgICB1c2VyOiB7XG4gICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICBjbGFzc05hbWU6ICdfVXNlcicsXG4gICAgICAgIG9iamVjdElkOiB0aGlzLm9iamVjdElkKCksXG4gICAgICB9LFxuICAgIH0pXG4gICAgICAuZXhlY3V0ZSgpXG4gICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgcmVzdWx0cy5yZXN1bHRzLmZvckVhY2goc2Vzc2lvbiA9PlxuICAgICAgICAgIHRoaXMuY29uZmlnLmNhY2hlQ29udHJvbGxlci51c2VyLmRlbChzZXNzaW9uLnNlc3Npb25Ub2tlbilcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHByb21pc2VcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICAvLyBUcmFuc2Zvcm0gdGhlIHBhc3N3b3JkXG4gICAgICBpZiAodGhpcy5kYXRhLnBhc3N3b3JkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gaWdub3JlIG9ubHkgaWYgdW5kZWZpbmVkLiBzaG91bGQgcHJvY2VlZCBpZiBlbXB0eSAoJycpXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMucXVlcnkpIHtcbiAgICAgICAgdGhpcy5zdG9yYWdlWydjbGVhclNlc3Npb25zJ10gPSB0cnVlO1xuICAgICAgICAvLyBHZW5lcmF0ZSBhIG5ldyBzZXNzaW9uIG9ubHkgaWYgdGhlIHVzZXIgcmVxdWVzdGVkXG4gICAgICAgIGlmICghdGhpcy5hdXRoLmlzTWFzdGVyKSB7XG4gICAgICAgICAgdGhpcy5zdG9yYWdlWydnZW5lcmF0ZU5ld1Nlc3Npb24nXSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlUGFzc3dvcmRQb2xpY3koKS50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHBhc3N3b3JkQ3J5cHRvLmhhc2godGhpcy5kYXRhLnBhc3N3b3JkKS50aGVuKGhhc2hlZFBhc3N3b3JkID0+IHtcbiAgICAgICAgICB0aGlzLmRhdGEuX2hhc2hlZF9wYXNzd29yZCA9IGhhc2hlZFBhc3N3b3JkO1xuICAgICAgICAgIGRlbGV0ZSB0aGlzLmRhdGEucGFzc3dvcmQ7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5fdmFsaWRhdGVVc2VyTmFtZSgpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlRW1haWwoKTtcbiAgICB9KTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuX3ZhbGlkYXRlVXNlck5hbWUgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIENoZWNrIGZvciB1c2VybmFtZSB1bmlxdWVuZXNzXG4gIGlmICghdGhpcy5kYXRhLnVzZXJuYW1lKSB7XG4gICAgaWYgKCF0aGlzLnF1ZXJ5KSB7XG4gICAgICB0aGlzLmRhdGEudXNlcm5hbWUgPSBjcnlwdG9VdGlscy5yYW5kb21TdHJpbmcoMjUpO1xuICAgICAgdGhpcy5yZXNwb25zZVNob3VsZEhhdmVVc2VybmFtZSA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuICAvKlxuICAgIFVzZXJuYW1lcyBzaG91bGQgYmUgdW5pcXVlIHdoZW4gY29tcGFyZWQgY2FzZSBpbnNlbnNpdGl2ZWx5XG5cbiAgICBVc2VycyBzaG91bGQgYmUgYWJsZSB0byBtYWtlIGNhc2Ugc2Vuc2l0aXZlIHVzZXJuYW1lcyBhbmRcbiAgICBsb2dpbiB1c2luZyB0aGUgY2FzZSB0aGV5IGVudGVyZWQuICBJLmUuICdTbm9vcHknIHNob3VsZCBwcmVjbHVkZVxuICAgICdzbm9vcHknIGFzIGEgdmFsaWQgdXNlcm5hbWUuXG4gICovXG4gIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgIC5maW5kKFxuICAgICAgdGhpcy5jbGFzc05hbWUsXG4gICAgICB7XG4gICAgICAgIHVzZXJuYW1lOiB0aGlzLmRhdGEudXNlcm5hbWUsXG4gICAgICAgIG9iamVjdElkOiB7ICRuZTogdGhpcy5vYmplY3RJZCgpIH0sXG4gICAgICB9LFxuICAgICAgeyBsaW1pdDogMSwgY2FzZUluc2Vuc2l0aXZlOiB0cnVlIH0sXG4gICAgICB7fSxcbiAgICAgIHRoaXMudmFsaWRTY2hlbWFDb250cm9sbGVyXG4gICAgKVxuICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID4gMCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuVVNFUk5BTUVfVEFLRU4sXG4gICAgICAgICAgJ0FjY291bnQgYWxyZWFkeSBleGlzdHMgZm9yIHRoaXMgdXNlcm5hbWUuJ1xuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH0pO1xufTtcblxuLypcbiAgQXMgd2l0aCB1c2VybmFtZXMsIFBhcnNlIHNob3VsZCBub3QgYWxsb3cgY2FzZSBpbnNlbnNpdGl2ZSBjb2xsaXNpb25zIG9mIGVtYWlsLlxuICB1bmxpa2Ugd2l0aCB1c2VybmFtZXMgKHdoaWNoIGNhbiBoYXZlIGNhc2UgaW5zZW5zaXRpdmUgY29sbGlzaW9ucyBpbiB0aGUgY2FzZSBvZlxuICBhdXRoIGFkYXB0ZXJzKSwgZW1haWxzIHNob3VsZCBuZXZlciBoYXZlIGEgY2FzZSBpbnNlbnNpdGl2ZSBjb2xsaXNpb24uXG5cbiAgVGhpcyBiZWhhdmlvciBjYW4gYmUgZW5mb3JjZWQgdGhyb3VnaCBhIHByb3Blcmx5IGNvbmZpZ3VyZWQgaW5kZXggc2VlOlxuICBodHRwczovL2RvY3MubW9uZ29kYi5jb20vbWFudWFsL2NvcmUvaW5kZXgtY2FzZS1pbnNlbnNpdGl2ZS8jY3JlYXRlLWEtY2FzZS1pbnNlbnNpdGl2ZS1pbmRleFxuICB3aGljaCBjb3VsZCBiZSBpbXBsZW1lbnRlZCBpbnN0ZWFkIG9mIHRoaXMgY29kZSBiYXNlZCB2YWxpZGF0aW9uLlxuXG4gIEdpdmVuIHRoYXQgdGhpcyBsb29rdXAgc2hvdWxkIGJlIGEgcmVsYXRpdmVseSBsb3cgdXNlIGNhc2UgYW5kIHRoYXQgdGhlIGNhc2Ugc2Vuc2l0aXZlXG4gIHVuaXF1ZSBpbmRleCB3aWxsIGJlIHVzZWQgYnkgdGhlIGRiIGZvciB0aGUgcXVlcnksIHRoaXMgaXMgYW4gYWRlcXVhdGUgc29sdXRpb24uXG4qL1xuUmVzdFdyaXRlLnByb3RvdHlwZS5fdmFsaWRhdGVFbWFpbCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCF0aGlzLmRhdGEuZW1haWwgfHwgdGhpcy5kYXRhLmVtYWlsLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG4gIC8vIFZhbGlkYXRlIGJhc2ljIGVtYWlsIGFkZHJlc3MgZm9ybWF0XG4gIGlmICghdGhpcy5kYXRhLmVtYWlsLm1hdGNoKC9eLitALiskLykpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9FTUFJTF9BRERSRVNTLCAnRW1haWwgYWRkcmVzcyBmb3JtYXQgaXMgaW52YWxpZC4nKVxuICAgICk7XG4gIH1cbiAgLy8gQ2FzZSBpbnNlbnNpdGl2ZSBtYXRjaCwgc2VlIG5vdGUgYWJvdmUgZnVuY3Rpb24uXG4gIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgIC5maW5kKFxuICAgICAgdGhpcy5jbGFzc05hbWUsXG4gICAgICB7XG4gICAgICAgIGVtYWlsOiB0aGlzLmRhdGEuZW1haWwsXG4gICAgICAgIG9iamVjdElkOiB7ICRuZTogdGhpcy5vYmplY3RJZCgpIH0sXG4gICAgICB9LFxuICAgICAgeyBsaW1pdDogMSwgY2FzZUluc2Vuc2l0aXZlOiB0cnVlIH0sXG4gICAgICB7fSxcbiAgICAgIHRoaXMudmFsaWRTY2hlbWFDb250cm9sbGVyXG4gICAgKVxuICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID4gMCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuRU1BSUxfVEFLRU4sXG4gICAgICAgICAgJ0FjY291bnQgYWxyZWFkeSBleGlzdHMgZm9yIHRoaXMgZW1haWwgYWRkcmVzcy4nXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoXG4gICAgICAgICF0aGlzLmRhdGEuYXV0aERhdGEgfHxcbiAgICAgICAgIU9iamVjdC5rZXlzKHRoaXMuZGF0YS5hdXRoRGF0YSkubGVuZ3RoIHx8XG4gICAgICAgIChPYmplY3Qua2V5cyh0aGlzLmRhdGEuYXV0aERhdGEpLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICAgIE9iamVjdC5rZXlzKHRoaXMuZGF0YS5hdXRoRGF0YSlbMF0gPT09ICdhbm9ueW1vdXMnKVxuICAgICAgKSB7XG4gICAgICAgIC8vIFdlIHVwZGF0ZWQgdGhlIGVtYWlsLCBzZW5kIGEgbmV3IHZhbGlkYXRpb25cbiAgICAgICAgdGhpcy5zdG9yYWdlWydzZW5kVmVyaWZpY2F0aW9uRW1haWwnXSA9IHRydWU7XG4gICAgICAgIHRoaXMuY29uZmlnLnVzZXJDb250cm9sbGVyLnNldEVtYWlsVmVyaWZ5VG9rZW4odGhpcy5kYXRhKTtcbiAgICAgIH1cbiAgICB9KTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuX3ZhbGlkYXRlUGFzc3dvcmRQb2xpY3kgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kpIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlUGFzc3dvcmRSZXF1aXJlbWVudHMoKS50aGVuKCgpID0+IHtcbiAgICByZXR1cm4gdGhpcy5fdmFsaWRhdGVQYXNzd29yZEhpc3RvcnkoKTtcbiAgfSk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLl92YWxpZGF0ZVBhc3N3b3JkUmVxdWlyZW1lbnRzID0gZnVuY3Rpb24gKCkge1xuICAvLyBjaGVjayBpZiB0aGUgcGFzc3dvcmQgY29uZm9ybXMgdG8gdGhlIGRlZmluZWQgcGFzc3dvcmQgcG9saWN5IGlmIGNvbmZpZ3VyZWRcbiAgLy8gSWYgd2Ugc3BlY2lmaWVkIGEgY3VzdG9tIGVycm9yIGluIG91ciBjb25maWd1cmF0aW9uIHVzZSBpdC5cbiAgLy8gRXhhbXBsZTogXCJQYXNzd29yZHMgbXVzdCBpbmNsdWRlIGEgQ2FwaXRhbCBMZXR0ZXIsIExvd2VyY2FzZSBMZXR0ZXIsIGFuZCBhIG51bWJlci5cIlxuICAvL1xuICAvLyBUaGlzIGlzIGVzcGVjaWFsbHkgdXNlZnVsIG9uIHRoZSBnZW5lcmljIFwicGFzc3dvcmQgcmVzZXRcIiBwYWdlLFxuICAvLyBhcyBpdCBhbGxvd3MgdGhlIHByb2dyYW1tZXIgdG8gY29tbXVuaWNhdGUgc3BlY2lmaWMgcmVxdWlyZW1lbnRzIGluc3RlYWQgb2Y6XG4gIC8vIGEuIG1ha2luZyB0aGUgdXNlciBndWVzcyB3aGF0cyB3cm9uZ1xuICAvLyBiLiBtYWtpbmcgYSBjdXN0b20gcGFzc3dvcmQgcmVzZXQgcGFnZSB0aGF0IHNob3dzIHRoZSByZXF1aXJlbWVudHNcbiAgY29uc3QgcG9saWN5RXJyb3IgPSB0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS52YWxpZGF0aW9uRXJyb3JcbiAgICA/IHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LnZhbGlkYXRpb25FcnJvclxuICAgIDogJ1Bhc3N3b3JkIGRvZXMgbm90IG1lZXQgdGhlIFBhc3N3b3JkIFBvbGljeSByZXF1aXJlbWVudHMuJztcbiAgY29uc3QgY29udGFpbnNVc2VybmFtZUVycm9yID0gJ1Bhc3N3b3JkIGNhbm5vdCBjb250YWluIHlvdXIgdXNlcm5hbWUuJztcblxuICAvLyBjaGVjayB3aGV0aGVyIHRoZSBwYXNzd29yZCBtZWV0cyB0aGUgcGFzc3dvcmQgc3RyZW5ndGggcmVxdWlyZW1lbnRzXG4gIGlmIChcbiAgICAodGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kucGF0dGVyblZhbGlkYXRvciAmJlxuICAgICAgIXRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LnBhdHRlcm5WYWxpZGF0b3IodGhpcy5kYXRhLnBhc3N3b3JkKSkgfHxcbiAgICAodGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yQ2FsbGJhY2sgJiZcbiAgICAgICF0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS52YWxpZGF0b3JDYWxsYmFjayh0aGlzLmRhdGEucGFzc3dvcmQpKVxuICApIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlZBTElEQVRJT05fRVJST1IsIHBvbGljeUVycm9yKSk7XG4gIH1cblxuICAvLyBjaGVjayB3aGV0aGVyIHBhc3N3b3JkIGNvbnRhaW4gdXNlcm5hbWVcbiAgaWYgKHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LmRvTm90QWxsb3dVc2VybmFtZSA9PT0gdHJ1ZSkge1xuICAgIGlmICh0aGlzLmRhdGEudXNlcm5hbWUpIHtcbiAgICAgIC8vIHVzZXJuYW1lIGlzIG5vdCBwYXNzZWQgZHVyaW5nIHBhc3N3b3JkIHJlc2V0XG4gICAgICBpZiAodGhpcy5kYXRhLnBhc3N3b3JkLmluZGV4T2YodGhpcy5kYXRhLnVzZXJuYW1lKSA+PSAwKVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlZBTElEQVRJT05fRVJST1IsIGNvbnRhaW5zVXNlcm5hbWVFcnJvcikpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyByZXRyaWV2ZSB0aGUgVXNlciBvYmplY3QgdXNpbmcgb2JqZWN0SWQgZHVyaW5nIHBhc3N3b3JkIHJlc2V0XG4gICAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UuZmluZCgnX1VzZXInLCB7IG9iamVjdElkOiB0aGlzLm9iamVjdElkKCkgfSkudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoICE9IDEpIHtcbiAgICAgICAgICB0aHJvdyB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZGF0YS5wYXNzd29yZC5pbmRleE9mKHJlc3VsdHNbMF0udXNlcm5hbWUpID49IDApXG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KFxuICAgICAgICAgICAgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlZBTElEQVRJT05fRVJST1IsIGNvbnRhaW5zVXNlcm5hbWVFcnJvcilcbiAgICAgICAgICApO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufTtcblxuUmVzdFdyaXRlLnByb3RvdHlwZS5fdmFsaWRhdGVQYXNzd29yZEhpc3RvcnkgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIGNoZWNrIHdoZXRoZXIgcGFzc3dvcmQgaXMgcmVwZWF0aW5nIGZyb20gc3BlY2lmaWVkIGhpc3RvcnlcbiAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRIaXN0b3J5KSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgICAuZmluZChcbiAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAgeyBvYmplY3RJZDogdGhpcy5vYmplY3RJZCgpIH0sXG4gICAgICAgIHsga2V5czogWydfcGFzc3dvcmRfaGlzdG9yeScsICdfaGFzaGVkX3Bhc3N3b3JkJ10gfVxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCAhPSAxKSB7XG4gICAgICAgICAgdGhyb3cgdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHVzZXIgPSByZXN1bHRzWzBdO1xuICAgICAgICBsZXQgb2xkUGFzc3dvcmRzID0gW107XG4gICAgICAgIGlmICh1c2VyLl9wYXNzd29yZF9oaXN0b3J5KVxuICAgICAgICAgIG9sZFBhc3N3b3JkcyA9IF8udGFrZShcbiAgICAgICAgICAgIHVzZXIuX3Bhc3N3b3JkX2hpc3RvcnksXG4gICAgICAgICAgICB0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEhpc3RvcnkgLSAxXG4gICAgICAgICAgKTtcbiAgICAgICAgb2xkUGFzc3dvcmRzLnB1c2godXNlci5wYXNzd29yZCk7XG4gICAgICAgIGNvbnN0IG5ld1Bhc3N3b3JkID0gdGhpcy5kYXRhLnBhc3N3b3JkO1xuICAgICAgICAvLyBjb21wYXJlIHRoZSBuZXcgcGFzc3dvcmQgaGFzaCB3aXRoIGFsbCBvbGQgcGFzc3dvcmQgaGFzaGVzXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gb2xkUGFzc3dvcmRzLm1hcChmdW5jdGlvbiAoaGFzaCkge1xuICAgICAgICAgIHJldHVybiBwYXNzd29yZENyeXB0by5jb21wYXJlKG5ld1Bhc3N3b3JkLCBoYXNoKS50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgICBpZiAocmVzdWx0KVxuICAgICAgICAgICAgICAvLyByZWplY3QgaWYgdGhlcmUgaXMgYSBtYXRjaFxuICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ1JFUEVBVF9QQVNTV09SRCcpO1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gd2FpdCBmb3IgYWxsIGNvbXBhcmlzb25zIHRvIGNvbXBsZXRlXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcylcbiAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICAgIGlmIChlcnIgPT09ICdSRVBFQVRfUEFTU1dPUkQnKVxuICAgICAgICAgICAgICAvLyBhIG1hdGNoIHdhcyBmb3VuZFxuICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICAgICAgICAgICAgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuVkFMSURBVElPTl9FUlJPUixcbiAgICAgICAgICAgICAgICAgIGBOZXcgcGFzc3dvcmQgc2hvdWxkIG5vdCBiZSB0aGUgc2FtZSBhcyBsYXN0ICR7dGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRIaXN0b3J5fSBwYXNzd29yZHMuYFxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICB9KTtcbiAgICAgIH0pO1xuICB9XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuY3JlYXRlU2Vzc2lvblRva2VuSWZOZWVkZWQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmNsYXNzTmFtZSAhPT0gJ19Vc2VyJykge1xuICAgIHJldHVybjtcbiAgfVxuICAvLyBEb24ndCBnZW5lcmF0ZSBzZXNzaW9uIGZvciB1cGRhdGluZyB1c2VyICh0aGlzLnF1ZXJ5IGlzIHNldCkgdW5sZXNzIGF1dGhEYXRhIGV4aXN0c1xuICBpZiAodGhpcy5xdWVyeSAmJiAhdGhpcy5kYXRhLmF1dGhEYXRhKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIERvbid0IGdlbmVyYXRlIG5ldyBzZXNzaW9uVG9rZW4gaWYgbGlua2luZyB2aWEgc2Vzc2lvblRva2VuXG4gIGlmICh0aGlzLmF1dGgudXNlciAmJiB0aGlzLmRhdGEuYXV0aERhdGEpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKFxuICAgICF0aGlzLnN0b3JhZ2VbJ2F1dGhQcm92aWRlciddICYmIC8vIHNpZ251cCBjYWxsLCB3aXRoXG4gICAgdGhpcy5jb25maWcucHJldmVudExvZ2luV2l0aFVudmVyaWZpZWRFbWFpbCAmJiAvLyBubyBsb2dpbiB3aXRob3V0IHZlcmlmaWNhdGlvblxuICAgIHRoaXMuY29uZmlnLnZlcmlmeVVzZXJFbWFpbHNcbiAgKSB7XG4gICAgLy8gdmVyaWZpY2F0aW9uIGlzIG9uXG4gICAgcmV0dXJuOyAvLyBkbyBub3QgY3JlYXRlIHRoZSBzZXNzaW9uIHRva2VuIGluIHRoYXQgY2FzZSFcbiAgfVxuICByZXR1cm4gdGhpcy5jcmVhdGVTZXNzaW9uVG9rZW4oKTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuY3JlYXRlU2Vzc2lvblRva2VuID0gYXN5bmMgZnVuY3Rpb24gKCkge1xuICAvLyBjbG91ZCBpbnN0YWxsYXRpb25JZCBmcm9tIENsb3VkIENvZGUsXG4gIC8vIG5ldmVyIGNyZWF0ZSBzZXNzaW9uIHRva2VucyBmcm9tIHRoZXJlLlxuICBpZiAodGhpcy5hdXRoLmluc3RhbGxhdGlvbklkICYmIHRoaXMuYXV0aC5pbnN0YWxsYXRpb25JZCA9PT0gJ2Nsb3VkJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHsgc2Vzc2lvbkRhdGEsIGNyZWF0ZVNlc3Npb24gfSA9IEF1dGguY3JlYXRlU2Vzc2lvbih0aGlzLmNvbmZpZywge1xuICAgIHVzZXJJZDogdGhpcy5vYmplY3RJZCgpLFxuICAgIGNyZWF0ZWRXaXRoOiB7XG4gICAgICBhY3Rpb246IHRoaXMuc3RvcmFnZVsnYXV0aFByb3ZpZGVyJ10gPyAnbG9naW4nIDogJ3NpZ251cCcsXG4gICAgICBhdXRoUHJvdmlkZXI6IHRoaXMuc3RvcmFnZVsnYXV0aFByb3ZpZGVyJ10gfHwgJ3Bhc3N3b3JkJyxcbiAgICB9LFxuICAgIGluc3RhbGxhdGlvbklkOiB0aGlzLmF1dGguaW5zdGFsbGF0aW9uSWQsXG4gIH0pO1xuXG4gIGlmICh0aGlzLnJlc3BvbnNlICYmIHRoaXMucmVzcG9uc2UucmVzcG9uc2UpIHtcbiAgICB0aGlzLnJlc3BvbnNlLnJlc3BvbnNlLnNlc3Npb25Ub2tlbiA9IHNlc3Npb25EYXRhLnNlc3Npb25Ub2tlbjtcbiAgfVxuXG4gIHJldHVybiBjcmVhdGVTZXNzaW9uKCk7XG59O1xuXG4vLyBEZWxldGUgZW1haWwgcmVzZXQgdG9rZW5zIGlmIHVzZXIgaXMgY2hhbmdpbmcgcGFzc3dvcmQgb3IgZW1haWwuXG5SZXN0V3JpdGUucHJvdG90eXBlLmRlbGV0ZUVtYWlsUmVzZXRUb2tlbklmTmVlZGVkID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jbGFzc05hbWUgIT09ICdfVXNlcicgfHwgdGhpcy5xdWVyeSA9PT0gbnVsbCkge1xuICAgIC8vIG51bGwgcXVlcnkgbWVhbnMgY3JlYXRlXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKCdwYXNzd29yZCcgaW4gdGhpcy5kYXRhIHx8ICdlbWFpbCcgaW4gdGhpcy5kYXRhKSB7XG4gICAgY29uc3QgYWRkT3BzID0ge1xuICAgICAgX3BlcmlzaGFibGVfdG9rZW46IHsgX19vcDogJ0RlbGV0ZScgfSxcbiAgICAgIF9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQ6IHsgX19vcDogJ0RlbGV0ZScgfSxcbiAgICB9O1xuICAgIHRoaXMuZGF0YSA9IE9iamVjdC5hc3NpZ24odGhpcy5kYXRhLCBhZGRPcHMpO1xuICB9XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLmRlc3Ryb3lEdXBsaWNhdGVkU2Vzc2lvbnMgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIE9ubHkgZm9yIF9TZXNzaW9uLCBhbmQgYXQgY3JlYXRpb24gdGltZVxuICBpZiAodGhpcy5jbGFzc05hbWUgIT0gJ19TZXNzaW9uJyB8fCB0aGlzLnF1ZXJ5KSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIERlc3Ryb3kgdGhlIHNlc3Npb25zIGluICdCYWNrZ3JvdW5kJ1xuICBjb25zdCB7IHVzZXIsIGluc3RhbGxhdGlvbklkLCBzZXNzaW9uVG9rZW4gfSA9IHRoaXMuZGF0YTtcbiAgaWYgKCF1c2VyIHx8ICFpbnN0YWxsYXRpb25JZCkge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoIXVzZXIub2JqZWN0SWQpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdGhpcy5jb25maWcuZGF0YWJhc2UuZGVzdHJveShcbiAgICAnX1Nlc3Npb24nLFxuICAgIHtcbiAgICAgIHVzZXIsXG4gICAgICBpbnN0YWxsYXRpb25JZCxcbiAgICAgIHNlc3Npb25Ub2tlbjogeyAkbmU6IHNlc3Npb25Ub2tlbiB9LFxuICAgIH0sXG4gICAge30sXG4gICAgdGhpcy52YWxpZFNjaGVtYUNvbnRyb2xsZXJcbiAgKTtcbn07XG5cbi8vIEhhbmRsZXMgYW55IGZvbGxvd3VwIGxvZ2ljXG5SZXN0V3JpdGUucHJvdG90eXBlLmhhbmRsZUZvbGxvd3VwID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5zdG9yYWdlICYmIHRoaXMuc3RvcmFnZVsnY2xlYXJTZXNzaW9ucyddICYmIHRoaXMuY29uZmlnLnJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQpIHtcbiAgICB2YXIgc2Vzc2lvblF1ZXJ5ID0ge1xuICAgICAgdXNlcjoge1xuICAgICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgY2xhc3NOYW1lOiAnX1VzZXInLFxuICAgICAgICBvYmplY3RJZDogdGhpcy5vYmplY3RJZCgpLFxuICAgICAgfSxcbiAgICB9O1xuICAgIGRlbGV0ZSB0aGlzLnN0b3JhZ2VbJ2NsZWFyU2Vzc2lvbnMnXTtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAgIC5kZXN0cm95KCdfU2Vzc2lvbicsIHNlc3Npb25RdWVyeSlcbiAgICAgIC50aGVuKHRoaXMuaGFuZGxlRm9sbG93dXAuYmluZCh0aGlzKSk7XG4gIH1cblxuICBpZiAodGhpcy5zdG9yYWdlICYmIHRoaXMuc3RvcmFnZVsnZ2VuZXJhdGVOZXdTZXNzaW9uJ10pIHtcbiAgICBkZWxldGUgdGhpcy5zdG9yYWdlWydnZW5lcmF0ZU5ld1Nlc3Npb24nXTtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVTZXNzaW9uVG9rZW4oKS50aGVuKHRoaXMuaGFuZGxlRm9sbG93dXAuYmluZCh0aGlzKSk7XG4gIH1cblxuICBpZiAodGhpcy5zdG9yYWdlICYmIHRoaXMuc3RvcmFnZVsnc2VuZFZlcmlmaWNhdGlvbkVtYWlsJ10pIHtcbiAgICBkZWxldGUgdGhpcy5zdG9yYWdlWydzZW5kVmVyaWZpY2F0aW9uRW1haWwnXTtcbiAgICAvLyBGaXJlIGFuZCBmb3JnZXQhXG4gICAgdGhpcy5jb25maWcudXNlckNvbnRyb2xsZXIuc2VuZFZlcmlmaWNhdGlvbkVtYWlsKHRoaXMuZGF0YSk7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlRm9sbG93dXAuYmluZCh0aGlzKTtcbiAgfVxufTtcblxuLy8gSGFuZGxlcyB0aGUgX1Nlc3Npb24gY2xhc3Mgc3BlY2lhbG5lc3MuXG4vLyBEb2VzIG5vdGhpbmcgaWYgdGhpcyBpc24ndCBhbiBfU2Vzc2lvbiBvYmplY3QuXG5SZXN0V3JpdGUucHJvdG90eXBlLmhhbmRsZVNlc3Npb24gPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnJlc3BvbnNlIHx8IHRoaXMuY2xhc3NOYW1lICE9PSAnX1Nlc3Npb24nKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKCF0aGlzLmF1dGgudXNlciAmJiAhdGhpcy5hdXRoLmlzTWFzdGVyKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTiwgJ1Nlc3Npb24gdG9rZW4gcmVxdWlyZWQuJyk7XG4gIH1cblxuICAvLyBUT0RPOiBWZXJpZnkgcHJvcGVyIGVycm9yIHRvIHRocm93XG4gIGlmICh0aGlzLmRhdGEuQUNMKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUsICdDYW5ub3Qgc2V0ICcgKyAnQUNMIG9uIGEgU2Vzc2lvbi4nKTtcbiAgfVxuXG4gIGlmICh0aGlzLnF1ZXJ5KSB7XG4gICAgaWYgKHRoaXMuZGF0YS51c2VyICYmICF0aGlzLmF1dGguaXNNYXN0ZXIgJiYgdGhpcy5kYXRhLnVzZXIub2JqZWN0SWQgIT0gdGhpcy5hdXRoLnVzZXIuaWQpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5kYXRhLnNlc3Npb25Ub2tlbikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUpO1xuICAgIH1cbiAgfVxuXG4gIGlmICghdGhpcy5xdWVyeSAmJiAhdGhpcy5hdXRoLmlzTWFzdGVyKSB7XG4gICAgY29uc3QgYWRkaXRpb25hbFNlc3Npb25EYXRhID0ge307XG4gICAgZm9yICh2YXIga2V5IGluIHRoaXMuZGF0YSkge1xuICAgICAgaWYgKGtleSA9PT0gJ29iamVjdElkJyB8fCBrZXkgPT09ICd1c2VyJykge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGFkZGl0aW9uYWxTZXNzaW9uRGF0YVtrZXldID0gdGhpcy5kYXRhW2tleV07XG4gICAgfVxuXG4gICAgY29uc3QgeyBzZXNzaW9uRGF0YSwgY3JlYXRlU2Vzc2lvbiB9ID0gQXV0aC5jcmVhdGVTZXNzaW9uKHRoaXMuY29uZmlnLCB7XG4gICAgICB1c2VySWQ6IHRoaXMuYXV0aC51c2VyLmlkLFxuICAgICAgY3JlYXRlZFdpdGg6IHtcbiAgICAgICAgYWN0aW9uOiAnY3JlYXRlJyxcbiAgICAgIH0sXG4gICAgICBhZGRpdGlvbmFsU2Vzc2lvbkRhdGEsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gY3JlYXRlU2Vzc2lvbigpLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICBpZiAoIXJlc3VsdHMucmVzcG9uc2UpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUiwgJ0Vycm9yIGNyZWF0aW5nIHNlc3Npb24uJyk7XG4gICAgICB9XG4gICAgICBzZXNzaW9uRGF0YVsnb2JqZWN0SWQnXSA9IHJlc3VsdHMucmVzcG9uc2VbJ29iamVjdElkJ107XG4gICAgICB0aGlzLnJlc3BvbnNlID0ge1xuICAgICAgICBzdGF0dXM6IDIwMSxcbiAgICAgICAgbG9jYXRpb246IHJlc3VsdHMubG9jYXRpb24sXG4gICAgICAgIHJlc3BvbnNlOiBzZXNzaW9uRGF0YSxcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cbn07XG5cbi8vIEhhbmRsZXMgdGhlIF9JbnN0YWxsYXRpb24gY2xhc3Mgc3BlY2lhbG5lc3MuXG4vLyBEb2VzIG5vdGhpbmcgaWYgdGhpcyBpc24ndCBhbiBpbnN0YWxsYXRpb24gb2JqZWN0LlxuLy8gSWYgYW4gaW5zdGFsbGF0aW9uIGlzIGZvdW5kLCB0aGlzIGNhbiBtdXRhdGUgdGhpcy5xdWVyeSBhbmQgdHVybiBhIGNyZWF0ZVxuLy8gaW50byBhbiB1cGRhdGUuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3Igd2hlbiB3ZSdyZSBkb25lIGlmIGl0IGNhbid0IGZpbmlzaCB0aGlzIHRpY2suXG5SZXN0V3JpdGUucHJvdG90eXBlLmhhbmRsZUluc3RhbGxhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMucmVzcG9uc2UgfHwgdGhpcy5jbGFzc05hbWUgIT09ICdfSW5zdGFsbGF0aW9uJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChcbiAgICAhdGhpcy5xdWVyeSAmJlxuICAgICF0aGlzLmRhdGEuZGV2aWNlVG9rZW4gJiZcbiAgICAhdGhpcy5kYXRhLmluc3RhbGxhdGlvbklkICYmXG4gICAgIXRoaXMuYXV0aC5pbnN0YWxsYXRpb25JZFxuICApIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAxMzUsXG4gICAgICAnYXQgbGVhc3Qgb25lIElEIGZpZWxkIChkZXZpY2VUb2tlbiwgaW5zdGFsbGF0aW9uSWQpICcgKyAnbXVzdCBiZSBzcGVjaWZpZWQgaW4gdGhpcyBvcGVyYXRpb24nXG4gICAgKTtcbiAgfVxuXG4gIC8vIElmIHRoZSBkZXZpY2UgdG9rZW4gaXMgNjQgY2hhcmFjdGVycyBsb25nLCB3ZSBhc3N1bWUgaXQgaXMgZm9yIGlPU1xuICAvLyBhbmQgbG93ZXJjYXNlIGl0LlxuICBpZiAodGhpcy5kYXRhLmRldmljZVRva2VuICYmIHRoaXMuZGF0YS5kZXZpY2VUb2tlbi5sZW5ndGggPT0gNjQpIHtcbiAgICB0aGlzLmRhdGEuZGV2aWNlVG9rZW4gPSB0aGlzLmRhdGEuZGV2aWNlVG9rZW4udG9Mb3dlckNhc2UoKTtcbiAgfVxuXG4gIC8vIFdlIGxvd2VyY2FzZSB0aGUgaW5zdGFsbGF0aW9uSWQgaWYgcHJlc2VudFxuICBpZiAodGhpcy5kYXRhLmluc3RhbGxhdGlvbklkKSB7XG4gICAgdGhpcy5kYXRhLmluc3RhbGxhdGlvbklkID0gdGhpcy5kYXRhLmluc3RhbGxhdGlvbklkLnRvTG93ZXJDYXNlKCk7XG4gIH1cblxuICBsZXQgaW5zdGFsbGF0aW9uSWQgPSB0aGlzLmRhdGEuaW5zdGFsbGF0aW9uSWQ7XG5cbiAgLy8gSWYgZGF0YS5pbnN0YWxsYXRpb25JZCBpcyBub3Qgc2V0IGFuZCB3ZSdyZSBub3QgbWFzdGVyLCB3ZSBjYW4gbG9va3VwIGluIGF1dGhcbiAgaWYgKCFpbnN0YWxsYXRpb25JZCAmJiAhdGhpcy5hdXRoLmlzTWFzdGVyKSB7XG4gICAgaW5zdGFsbGF0aW9uSWQgPSB0aGlzLmF1dGguaW5zdGFsbGF0aW9uSWQ7XG4gIH1cblxuICBpZiAoaW5zdGFsbGF0aW9uSWQpIHtcbiAgICBpbnN0YWxsYXRpb25JZCA9IGluc3RhbGxhdGlvbklkLnRvTG93ZXJDYXNlKCk7XG4gIH1cblxuICAvLyBVcGRhdGluZyBfSW5zdGFsbGF0aW9uIGJ1dCBub3QgdXBkYXRpbmcgYW55dGhpbmcgY3JpdGljYWxcbiAgaWYgKHRoaXMucXVlcnkgJiYgIXRoaXMuZGF0YS5kZXZpY2VUb2tlbiAmJiAhaW5zdGFsbGF0aW9uSWQgJiYgIXRoaXMuZGF0YS5kZXZpY2VUeXBlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcblxuICB2YXIgaWRNYXRjaDsgLy8gV2lsbCBiZSBhIG1hdGNoIG9uIGVpdGhlciBvYmplY3RJZCBvciBpbnN0YWxsYXRpb25JZFxuICB2YXIgb2JqZWN0SWRNYXRjaDtcbiAgdmFyIGluc3RhbGxhdGlvbklkTWF0Y2g7XG4gIHZhciBkZXZpY2VUb2tlbk1hdGNoZXMgPSBbXTtcblxuICAvLyBJbnN0ZWFkIG9mIGlzc3VpbmcgMyByZWFkcywgbGV0J3MgZG8gaXQgd2l0aCBvbmUgT1IuXG4gIGNvbnN0IG9yUXVlcmllcyA9IFtdO1xuICBpZiAodGhpcy5xdWVyeSAmJiB0aGlzLnF1ZXJ5Lm9iamVjdElkKSB7XG4gICAgb3JRdWVyaWVzLnB1c2goe1xuICAgICAgb2JqZWN0SWQ6IHRoaXMucXVlcnkub2JqZWN0SWQsXG4gICAgfSk7XG4gIH1cbiAgaWYgKGluc3RhbGxhdGlvbklkKSB7XG4gICAgb3JRdWVyaWVzLnB1c2goe1xuICAgICAgaW5zdGFsbGF0aW9uSWQ6IGluc3RhbGxhdGlvbklkLFxuICAgIH0pO1xuICB9XG4gIGlmICh0aGlzLmRhdGEuZGV2aWNlVG9rZW4pIHtcbiAgICBvclF1ZXJpZXMucHVzaCh7IGRldmljZVRva2VuOiB0aGlzLmRhdGEuZGV2aWNlVG9rZW4gfSk7XG4gIH1cblxuICBpZiAob3JRdWVyaWVzLmxlbmd0aCA9PSAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcHJvbWlzZSA9IHByb21pc2VcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UuZmluZChcbiAgICAgICAgJ19JbnN0YWxsYXRpb24nLFxuICAgICAgICB7XG4gICAgICAgICAgJG9yOiBvclF1ZXJpZXMsXG4gICAgICAgIH0sXG4gICAgICAgIHt9XG4gICAgICApO1xuICAgIH0pXG4gICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICByZXN1bHRzLmZvckVhY2gocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCAmJiByZXN1bHQub2JqZWN0SWQgPT0gdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgICAgICAgIG9iamVjdElkTWF0Y2ggPSByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlc3VsdC5pbnN0YWxsYXRpb25JZCA9PSBpbnN0YWxsYXRpb25JZCkge1xuICAgICAgICAgIGluc3RhbGxhdGlvbklkTWF0Y2ggPSByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlc3VsdC5kZXZpY2VUb2tlbiA9PSB0aGlzLmRhdGEuZGV2aWNlVG9rZW4pIHtcbiAgICAgICAgICBkZXZpY2VUb2tlbk1hdGNoZXMucHVzaChyZXN1bHQpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLy8gU2FuaXR5IGNoZWNrcyB3aGVuIHJ1bm5pbmcgYSBxdWVyeVxuICAgICAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgICAgICBpZiAoIW9iamVjdElkTWF0Y2gpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ09iamVjdCBub3QgZm91bmQgZm9yIHVwZGF0ZS4nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoXG4gICAgICAgICAgdGhpcy5kYXRhLmluc3RhbGxhdGlvbklkICYmXG4gICAgICAgICAgb2JqZWN0SWRNYXRjaC5pbnN0YWxsYXRpb25JZCAmJlxuICAgICAgICAgIHRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZCAhPT0gb2JqZWN0SWRNYXRjaC5pbnN0YWxsYXRpb25JZFxuICAgICAgICApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTM2LCAnaW5zdGFsbGF0aW9uSWQgbWF5IG5vdCBiZSBjaGFuZ2VkIGluIHRoaXMgJyArICdvcGVyYXRpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoXG4gICAgICAgICAgdGhpcy5kYXRhLmRldmljZVRva2VuICYmXG4gICAgICAgICAgb2JqZWN0SWRNYXRjaC5kZXZpY2VUb2tlbiAmJlxuICAgICAgICAgIHRoaXMuZGF0YS5kZXZpY2VUb2tlbiAhPT0gb2JqZWN0SWRNYXRjaC5kZXZpY2VUb2tlbiAmJlxuICAgICAgICAgICF0aGlzLmRhdGEuaW5zdGFsbGF0aW9uSWQgJiZcbiAgICAgICAgICAhb2JqZWN0SWRNYXRjaC5pbnN0YWxsYXRpb25JZFxuICAgICAgICApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTM2LCAnZGV2aWNlVG9rZW4gbWF5IG5vdCBiZSBjaGFuZ2VkIGluIHRoaXMgJyArICdvcGVyYXRpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoXG4gICAgICAgICAgdGhpcy5kYXRhLmRldmljZVR5cGUgJiZcbiAgICAgICAgICB0aGlzLmRhdGEuZGV2aWNlVHlwZSAmJlxuICAgICAgICAgIHRoaXMuZGF0YS5kZXZpY2VUeXBlICE9PSBvYmplY3RJZE1hdGNoLmRldmljZVR5cGVcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDEzNiwgJ2RldmljZVR5cGUgbWF5IG5vdCBiZSBjaGFuZ2VkIGluIHRoaXMgJyArICdvcGVyYXRpb24nKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5xdWVyeSAmJiB0aGlzLnF1ZXJ5Lm9iamVjdElkICYmIG9iamVjdElkTWF0Y2gpIHtcbiAgICAgICAgaWRNYXRjaCA9IG9iamVjdElkTWF0Y2g7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbnN0YWxsYXRpb25JZCAmJiBpbnN0YWxsYXRpb25JZE1hdGNoKSB7XG4gICAgICAgIGlkTWF0Y2ggPSBpbnN0YWxsYXRpb25JZE1hdGNoO1xuICAgICAgfVxuICAgICAgLy8gbmVlZCB0byBzcGVjaWZ5IGRldmljZVR5cGUgb25seSBpZiBpdCdzIG5ld1xuICAgICAgaWYgKCF0aGlzLnF1ZXJ5ICYmICF0aGlzLmRhdGEuZGV2aWNlVHlwZSAmJiAhaWRNYXRjaCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTM1LCAnZGV2aWNlVHlwZSBtdXN0IGJlIHNwZWNpZmllZCBpbiB0aGlzIG9wZXJhdGlvbicpO1xuICAgICAgfVxuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgaWYgKCFpZE1hdGNoKSB7XG4gICAgICAgIGlmICghZGV2aWNlVG9rZW5NYXRjaGVzLmxlbmd0aCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBkZXZpY2VUb2tlbk1hdGNoZXMubGVuZ3RoID09IDEgJiZcbiAgICAgICAgICAoIWRldmljZVRva2VuTWF0Y2hlc1swXVsnaW5zdGFsbGF0aW9uSWQnXSB8fCAhaW5zdGFsbGF0aW9uSWQpXG4gICAgICAgICkge1xuICAgICAgICAgIC8vIFNpbmdsZSBtYXRjaCBvbiBkZXZpY2UgdG9rZW4gYnV0IG5vbmUgb24gaW5zdGFsbGF0aW9uSWQsIGFuZCBlaXRoZXJcbiAgICAgICAgICAvLyB0aGUgcGFzc2VkIG9iamVjdCBvciB0aGUgbWF0Y2ggaXMgbWlzc2luZyBhbiBpbnN0YWxsYXRpb25JZCwgc28gd2VcbiAgICAgICAgICAvLyBjYW4ganVzdCByZXR1cm4gdGhlIG1hdGNoLlxuICAgICAgICAgIHJldHVybiBkZXZpY2VUb2tlbk1hdGNoZXNbMF1bJ29iamVjdElkJ107XG4gICAgICAgIH0gZWxzZSBpZiAoIXRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIDEzMixcbiAgICAgICAgICAgICdNdXN0IHNwZWNpZnkgaW5zdGFsbGF0aW9uSWQgd2hlbiBkZXZpY2VUb2tlbiAnICtcbiAgICAgICAgICAgICAgJ21hdGNoZXMgbXVsdGlwbGUgSW5zdGFsbGF0aW9uIG9iamVjdHMnXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBNdWx0aXBsZSBkZXZpY2UgdG9rZW4gbWF0Y2hlcyBhbmQgd2Ugc3BlY2lmaWVkIGFuIGluc3RhbGxhdGlvbiBJRCxcbiAgICAgICAgICAvLyBvciBhIHNpbmdsZSBtYXRjaCB3aGVyZSBib3RoIHRoZSBwYXNzZWQgYW5kIG1hdGNoaW5nIG9iamVjdHMgaGF2ZVxuICAgICAgICAgIC8vIGFuIGluc3RhbGxhdGlvbiBJRC4gVHJ5IGNsZWFuaW5nIG91dCBvbGQgaW5zdGFsbGF0aW9ucyB0aGF0IG1hdGNoXG4gICAgICAgICAgLy8gdGhlIGRldmljZVRva2VuLCBhbmQgcmV0dXJuIG5pbCB0byBzaWduYWwgdGhhdCBhIG5ldyBvYmplY3Qgc2hvdWxkXG4gICAgICAgICAgLy8gYmUgY3JlYXRlZC5cbiAgICAgICAgICB2YXIgZGVsUXVlcnkgPSB7XG4gICAgICAgICAgICBkZXZpY2VUb2tlbjogdGhpcy5kYXRhLmRldmljZVRva2VuLFxuICAgICAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IHtcbiAgICAgICAgICAgICAgJG5lOiBpbnN0YWxsYXRpb25JZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgICBpZiAodGhpcy5kYXRhLmFwcElkZW50aWZpZXIpIHtcbiAgICAgICAgICAgIGRlbFF1ZXJ5WydhcHBJZGVudGlmaWVyJ10gPSB0aGlzLmRhdGEuYXBwSWRlbnRpZmllcjtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5jb25maWcuZGF0YWJhc2UuZGVzdHJveSgnX0luc3RhbGxhdGlvbicsIGRlbFF1ZXJ5KS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgaWYgKGVyci5jb2RlID09IFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQpIHtcbiAgICAgICAgICAgICAgLy8gbm8gZGVsZXRpb25zIHdlcmUgbWFkZS4gQ2FuIGJlIGlnbm9yZWQuXG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHJldGhyb3cgdGhlIGVycm9yXG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZGV2aWNlVG9rZW5NYXRjaGVzLmxlbmd0aCA9PSAxICYmICFkZXZpY2VUb2tlbk1hdGNoZXNbMF1bJ2luc3RhbGxhdGlvbklkJ10pIHtcbiAgICAgICAgICAvLyBFeGFjdGx5IG9uZSBkZXZpY2UgdG9rZW4gbWF0Y2ggYW5kIGl0IGRvZXNuJ3QgaGF2ZSBhbiBpbnN0YWxsYXRpb25cbiAgICAgICAgICAvLyBJRC4gVGhpcyBpcyB0aGUgb25lIGNhc2Ugd2hlcmUgd2Ugd2FudCB0byBtZXJnZSB3aXRoIHRoZSBleGlzdGluZ1xuICAgICAgICAgIC8vIG9iamVjdC5cbiAgICAgICAgICBjb25zdCBkZWxRdWVyeSA9IHsgb2JqZWN0SWQ6IGlkTWF0Y2gub2JqZWN0SWQgfTtcbiAgICAgICAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAgICAgICAgIC5kZXN0cm95KCdfSW5zdGFsbGF0aW9uJywgZGVsUXVlcnkpXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBkZXZpY2VUb2tlbk1hdGNoZXNbMF1bJ29iamVjdElkJ107XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PSBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5EKSB7XG4gICAgICAgICAgICAgICAgLy8gbm8gZGVsZXRpb25zIHdlcmUgbWFkZS4gQ2FuIGJlIGlnbm9yZWRcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy8gcmV0aHJvdyB0aGUgZXJyb3JcbiAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKHRoaXMuZGF0YS5kZXZpY2VUb2tlbiAmJiBpZE1hdGNoLmRldmljZVRva2VuICE9IHRoaXMuZGF0YS5kZXZpY2VUb2tlbikge1xuICAgICAgICAgICAgLy8gV2UncmUgc2V0dGluZyB0aGUgZGV2aWNlIHRva2VuIG9uIGFuIGV4aXN0aW5nIGluc3RhbGxhdGlvbiwgc29cbiAgICAgICAgICAgIC8vIHdlIHNob3VsZCB0cnkgY2xlYW5pbmcgb3V0IG9sZCBpbnN0YWxsYXRpb25zIHRoYXQgbWF0Y2ggdGhpc1xuICAgICAgICAgICAgLy8gZGV2aWNlIHRva2VuLlxuICAgICAgICAgICAgY29uc3QgZGVsUXVlcnkgPSB7XG4gICAgICAgICAgICAgIGRldmljZVRva2VuOiB0aGlzLmRhdGEuZGV2aWNlVG9rZW4sXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy8gV2UgaGF2ZSBhIHVuaXF1ZSBpbnN0YWxsIElkLCB1c2UgdGhhdCB0byBwcmVzZXJ2ZVxuICAgICAgICAgICAgLy8gdGhlIGludGVyZXN0aW5nIGluc3RhbGxhdGlvblxuICAgICAgICAgICAgaWYgKHRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZCkge1xuICAgICAgICAgICAgICBkZWxRdWVyeVsnaW5zdGFsbGF0aW9uSWQnXSA9IHtcbiAgICAgICAgICAgICAgICAkbmU6IHRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgIGlkTWF0Y2gub2JqZWN0SWQgJiZcbiAgICAgICAgICAgICAgdGhpcy5kYXRhLm9iamVjdElkICYmXG4gICAgICAgICAgICAgIGlkTWF0Y2gub2JqZWN0SWQgPT0gdGhpcy5kYXRhLm9iamVjdElkXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgLy8gd2UgcGFzc2VkIGFuIG9iamVjdElkLCBwcmVzZXJ2ZSB0aGF0IGluc3RhbGF0aW9uXG4gICAgICAgICAgICAgIGRlbFF1ZXJ5WydvYmplY3RJZCddID0ge1xuICAgICAgICAgICAgICAgICRuZTogaWRNYXRjaC5vYmplY3RJZCxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIFdoYXQgdG8gZG8gaGVyZT8gY2FuJ3QgcmVhbGx5IGNsZWFuIHVwIGV2ZXJ5dGhpbmcuLi5cbiAgICAgICAgICAgICAgcmV0dXJuIGlkTWF0Y2gub2JqZWN0SWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5kYXRhLmFwcElkZW50aWZpZXIpIHtcbiAgICAgICAgICAgICAgZGVsUXVlcnlbJ2FwcElkZW50aWZpZXInXSA9IHRoaXMuZGF0YS5hcHBJZGVudGlmaWVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jb25maWcuZGF0YWJhc2UuZGVzdHJveSgnX0luc3RhbGxhdGlvbicsIGRlbFF1ZXJ5KS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT0gUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCkge1xuICAgICAgICAgICAgICAgIC8vIG5vIGRlbGV0aW9ucyB3ZXJlIG1hZGUuIENhbiBiZSBpZ25vcmVkLlxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAvLyByZXRocm93IHRoZSBlcnJvclxuICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gSW4gbm9uLW1lcmdlIHNjZW5hcmlvcywganVzdCByZXR1cm4gdGhlIGluc3RhbGxhdGlvbiBtYXRjaCBpZFxuICAgICAgICAgIHJldHVybiBpZE1hdGNoLm9iamVjdElkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSlcbiAgICAudGhlbihvYmpJZCA9PiB7XG4gICAgICBpZiAob2JqSWQpIHtcbiAgICAgICAgdGhpcy5xdWVyeSA9IHsgb2JqZWN0SWQ6IG9iaklkIH07XG4gICAgICAgIGRlbGV0ZSB0aGlzLmRhdGEub2JqZWN0SWQ7XG4gICAgICAgIGRlbGV0ZSB0aGlzLmRhdGEuY3JlYXRlZEF0O1xuICAgICAgfVxuICAgICAgLy8gVE9ETzogVmFsaWRhdGUgb3BzIChhZGQvcmVtb3ZlIG9uIGNoYW5uZWxzLCAkaW5jIG9uIGJhZGdlLCBldGMuKVxuICAgIH0pO1xuICByZXR1cm4gcHJvbWlzZTtcbn07XG5cbi8vIElmIHdlIHNob3J0LWNpcmN1dGVkIHRoZSBvYmplY3QgcmVzcG9uc2UgLSB0aGVuIHdlIG5lZWQgdG8gbWFrZSBzdXJlIHdlIGV4cGFuZCBhbGwgdGhlIGZpbGVzLFxuLy8gc2luY2UgdGhpcyBtaWdodCBub3QgaGF2ZSBhIHF1ZXJ5LCBtZWFuaW5nIGl0IHdvbid0IHJldHVybiB0aGUgZnVsbCByZXN1bHQgYmFjay5cbi8vIFRPRE86IChubHV0c2Vua28pIFRoaXMgc2hvdWxkIGRpZSB3aGVuIHdlIG1vdmUgdG8gcGVyLWNsYXNzIGJhc2VkIGNvbnRyb2xsZXJzIG9uIF9TZXNzaW9uL19Vc2VyXG5SZXN0V3JpdGUucHJvdG90eXBlLmV4cGFuZEZpbGVzRm9yRXhpc3RpbmdPYmplY3RzID0gZnVuY3Rpb24gKCkge1xuICAvLyBDaGVjayB3aGV0aGVyIHdlIGhhdmUgYSBzaG9ydC1jaXJjdWl0ZWQgcmVzcG9uc2UgLSBvbmx5IHRoZW4gcnVuIGV4cGFuc2lvbi5cbiAgaWYgKHRoaXMucmVzcG9uc2UgJiYgdGhpcy5yZXNwb25zZS5yZXNwb25zZSkge1xuICAgIHRoaXMuY29uZmlnLmZpbGVzQ29udHJvbGxlci5leHBhbmRGaWxlc0luT2JqZWN0KHRoaXMuY29uZmlnLCB0aGlzLnJlc3BvbnNlLnJlc3BvbnNlKTtcbiAgfVxufTtcblxuUmVzdFdyaXRlLnByb3RvdHlwZS5ydW5EYXRhYmFzZU9wZXJhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMucmVzcG9uc2UpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAodGhpcy5jbGFzc05hbWUgPT09ICdfUm9sZScpIHtcbiAgICB0aGlzLmNvbmZpZy5jYWNoZUNvbnRyb2xsZXIucm9sZS5jbGVhcigpO1xuICB9XG5cbiAgaWYgKHRoaXMuY2xhc3NOYW1lID09PSAnX1VzZXInICYmIHRoaXMucXVlcnkgJiYgdGhpcy5hdXRoLmlzVW5hdXRoZW50aWNhdGVkKCkpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5TRVNTSU9OX01JU1NJTkcsXG4gICAgICBgQ2Fubm90IG1vZGlmeSB1c2VyICR7dGhpcy5xdWVyeS5vYmplY3RJZH0uYFxuICAgICk7XG4gIH1cblxuICBpZiAodGhpcy5jbGFzc05hbWUgPT09ICdfUHJvZHVjdCcgJiYgdGhpcy5kYXRhLmRvd25sb2FkKSB7XG4gICAgdGhpcy5kYXRhLmRvd25sb2FkTmFtZSA9IHRoaXMuZGF0YS5kb3dubG9hZC5uYW1lO1xuICB9XG5cbiAgLy8gVE9ETzogQWRkIGJldHRlciBkZXRlY3Rpb24gZm9yIEFDTCwgZW5zdXJpbmcgYSB1c2VyIGNhbid0IGJlIGxvY2tlZCBmcm9tXG4gIC8vICAgICAgIHRoZWlyIG93biB1c2VyIHJlY29yZC5cbiAgaWYgKHRoaXMuZGF0YS5BQ0wgJiYgdGhpcy5kYXRhLkFDTFsnKnVucmVzb2x2ZWQnXSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0FDTCwgJ0ludmFsaWQgQUNMLicpO1xuICB9XG5cbiAgaWYgKHRoaXMucXVlcnkpIHtcbiAgICAvLyBGb3JjZSB0aGUgdXNlciB0byBub3QgbG9ja291dFxuICAgIC8vIE1hdGNoZWQgd2l0aCBwYXJzZS5jb21cbiAgICBpZiAodGhpcy5jbGFzc05hbWUgPT09ICdfVXNlcicgJiYgdGhpcy5kYXRhLkFDTCAmJiB0aGlzLmF1dGguaXNNYXN0ZXIgIT09IHRydWUpIHtcbiAgICAgIHRoaXMuZGF0YS5BQ0xbdGhpcy5xdWVyeS5vYmplY3RJZF0gPSB7IHJlYWQ6IHRydWUsIHdyaXRlOiB0cnVlIH07XG4gICAgfVxuICAgIC8vIHVwZGF0ZSBwYXNzd29yZCB0aW1lc3RhbXAgaWYgdXNlciBwYXNzd29yZCBpcyBiZWluZyBjaGFuZ2VkXG4gICAgaWYgKFxuICAgICAgdGhpcy5jbGFzc05hbWUgPT09ICdfVXNlcicgJiZcbiAgICAgIHRoaXMuZGF0YS5faGFzaGVkX3Bhc3N3b3JkICYmXG4gICAgICB0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeSAmJlxuICAgICAgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRBZ2VcbiAgICApIHtcbiAgICAgIHRoaXMuZGF0YS5fcGFzc3dvcmRfY2hhbmdlZF9hdCA9IFBhcnNlLl9lbmNvZGUobmV3IERhdGUoKSk7XG4gICAgfVxuICAgIC8vIElnbm9yZSBjcmVhdGVkQXQgd2hlbiB1cGRhdGVcbiAgICBkZWxldGUgdGhpcy5kYXRhLmNyZWF0ZWRBdDtcblxuICAgIGxldCBkZWZlciA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIC8vIGlmIHBhc3N3b3JkIGhpc3RvcnkgaXMgZW5hYmxlZCB0aGVuIHNhdmUgdGhlIGN1cnJlbnQgcGFzc3dvcmQgdG8gaGlzdG9yeVxuICAgIGlmIChcbiAgICAgIHRoaXMuY2xhc3NOYW1lID09PSAnX1VzZXInICYmXG4gICAgICB0aGlzLmRhdGEuX2hhc2hlZF9wYXNzd29yZCAmJlxuICAgICAgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kgJiZcbiAgICAgIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeVxuICAgICkge1xuICAgICAgZGVmZXIgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgICAgICAuZmluZChcbiAgICAgICAgICAnX1VzZXInLFxuICAgICAgICAgIHsgb2JqZWN0SWQ6IHRoaXMub2JqZWN0SWQoKSB9LFxuICAgICAgICAgIHsga2V5czogWydfcGFzc3dvcmRfaGlzdG9yeScsICdfaGFzaGVkX3Bhc3N3b3JkJ10gfVxuICAgICAgICApXG4gICAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCAhPSAxKSB7XG4gICAgICAgICAgICB0aHJvdyB1bmRlZmluZWQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHVzZXIgPSByZXN1bHRzWzBdO1xuICAgICAgICAgIGxldCBvbGRQYXNzd29yZHMgPSBbXTtcbiAgICAgICAgICBpZiAodXNlci5fcGFzc3dvcmRfaGlzdG9yeSkge1xuICAgICAgICAgICAgb2xkUGFzc3dvcmRzID0gXy50YWtlKFxuICAgICAgICAgICAgICB1c2VyLl9wYXNzd29yZF9oaXN0b3J5LFxuICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEhpc3RvcnlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vbi0xIHBhc3N3b3JkcyBnbyBpbnRvIGhpc3RvcnkgaW5jbHVkaW5nIGxhc3QgcGFzc3dvcmRcbiAgICAgICAgICB3aGlsZSAoXG4gICAgICAgICAgICBvbGRQYXNzd29yZHMubGVuZ3RoID4gTWF0aC5tYXgoMCwgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRIaXN0b3J5IC0gMilcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIG9sZFBhc3N3b3Jkcy5zaGlmdCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBvbGRQYXNzd29yZHMucHVzaCh1c2VyLnBhc3N3b3JkKTtcbiAgICAgICAgICB0aGlzLmRhdGEuX3Bhc3N3b3JkX2hpc3RvcnkgPSBvbGRQYXNzd29yZHM7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBkZWZlci50aGVuKCgpID0+IHtcbiAgICAgIC8vIFJ1biBhbiB1cGRhdGVcbiAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgICAgICAudXBkYXRlKFxuICAgICAgICAgIHRoaXMuY2xhc3NOYW1lLFxuICAgICAgICAgIHRoaXMucXVlcnksXG4gICAgICAgICAgdGhpcy5kYXRhLFxuICAgICAgICAgIHRoaXMucnVuT3B0aW9ucyxcbiAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICB0aGlzLnZhbGlkU2NoZW1hQ29udHJvbGxlclxuICAgICAgICApXG4gICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICByZXNwb25zZS51cGRhdGVkQXQgPSB0aGlzLnVwZGF0ZWRBdDtcbiAgICAgICAgICB0aGlzLl91cGRhdGVSZXNwb25zZVdpdGhEYXRhKHJlc3BvbnNlLCB0aGlzLmRhdGEpO1xuICAgICAgICAgIHRoaXMucmVzcG9uc2UgPSB7IHJlc3BvbnNlIH07XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIC8vIFNldCB0aGUgZGVmYXVsdCBBQ0wgYW5kIHBhc3N3b3JkIHRpbWVzdGFtcCBmb3IgdGhlIG5ldyBfVXNlclxuICAgIGlmICh0aGlzLmNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgICAgdmFyIEFDTCA9IHRoaXMuZGF0YS5BQ0w7XG4gICAgICAvLyBkZWZhdWx0IHB1YmxpYyByL3cgQUNMXG4gICAgICBpZiAoIUFDTCkge1xuICAgICAgICBBQ0wgPSB7fTtcbiAgICAgICAgQUNMWycqJ10gPSB7IHJlYWQ6IHRydWUsIHdyaXRlOiBmYWxzZSB9O1xuICAgICAgfVxuICAgICAgLy8gbWFrZSBzdXJlIHRoZSB1c2VyIGlzIG5vdCBsb2NrZWQgZG93blxuICAgICAgQUNMW3RoaXMuZGF0YS5vYmplY3RJZF0gPSB7IHJlYWQ6IHRydWUsIHdyaXRlOiB0cnVlIH07XG4gICAgICB0aGlzLmRhdGEuQUNMID0gQUNMO1xuICAgICAgLy8gcGFzc3dvcmQgdGltZXN0YW1wIHRvIGJlIHVzZWQgd2hlbiBwYXNzd29yZCBleHBpcnkgcG9saWN5IGlzIGVuZm9yY2VkXG4gICAgICBpZiAodGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kgJiYgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRBZ2UpIHtcbiAgICAgICAgdGhpcy5kYXRhLl9wYXNzd29yZF9jaGFuZ2VkX2F0ID0gUGFyc2UuX2VuY29kZShuZXcgRGF0ZSgpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSdW4gYSBjcmVhdGVcbiAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAgIC5jcmVhdGUodGhpcy5jbGFzc05hbWUsIHRoaXMuZGF0YSwgdGhpcy5ydW5PcHRpb25zLCBmYWxzZSwgdGhpcy52YWxpZFNjaGVtYUNvbnRyb2xsZXIpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAodGhpcy5jbGFzc05hbWUgIT09ICdfVXNlcicgfHwgZXJyb3IuY29kZSAhPT0gUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFKSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBRdWljayBjaGVjaywgaWYgd2Ugd2VyZSBhYmxlIHRvIGluZmVyIHRoZSBkdXBsaWNhdGVkIGZpZWxkIG5hbWVcbiAgICAgICAgaWYgKGVycm9yICYmIGVycm9yLnVzZXJJbmZvICYmIGVycm9yLnVzZXJJbmZvLmR1cGxpY2F0ZWRfZmllbGQgPT09ICd1c2VybmFtZScpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5VU0VSTkFNRV9UQUtFTixcbiAgICAgICAgICAgICdBY2NvdW50IGFscmVhZHkgZXhpc3RzIGZvciB0aGlzIHVzZXJuYW1lLidcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVycm9yICYmIGVycm9yLnVzZXJJbmZvICYmIGVycm9yLnVzZXJJbmZvLmR1cGxpY2F0ZWRfZmllbGQgPT09ICdlbWFpbCcpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5FTUFJTF9UQUtFTixcbiAgICAgICAgICAgICdBY2NvdW50IGFscmVhZHkgZXhpc3RzIGZvciB0aGlzIGVtYWlsIGFkZHJlc3MuJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB0aGlzIHdhcyBhIGZhaWxlZCB1c2VyIGNyZWF0aW9uIGR1ZSB0byB1c2VybmFtZSBvciBlbWFpbCBhbHJlYWR5IHRha2VuLCB3ZSBuZWVkIHRvXG4gICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgaXQgd2FzIHVzZXJuYW1lIG9yIGVtYWlsIGFuZCByZXR1cm4gdGhlIGFwcHJvcHJpYXRlIGVycm9yLlxuICAgICAgICAvLyBGYWxsYmFjayB0byB0aGUgb3JpZ2luYWwgbWV0aG9kXG4gICAgICAgIC8vIFRPRE86IFNlZSBpZiB3ZSBjYW4gbGF0ZXIgZG8gdGhpcyB3aXRob3V0IGFkZGl0aW9uYWwgcXVlcmllcyBieSB1c2luZyBuYW1lZCBpbmRleGVzLlxuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAgICAgICAuZmluZChcbiAgICAgICAgICAgIHRoaXMuY2xhc3NOYW1lLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB1c2VybmFtZTogdGhpcy5kYXRhLnVzZXJuYW1lLFxuICAgICAgICAgICAgICBvYmplY3RJZDogeyAkbmU6IHRoaXMub2JqZWN0SWQoKSB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHsgbGltaXQ6IDEgfVxuICAgICAgICAgIClcbiAgICAgICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLlVTRVJOQU1FX1RBS0VOLFxuICAgICAgICAgICAgICAgICdBY2NvdW50IGFscmVhZHkgZXhpc3RzIGZvciB0aGlzIHVzZXJuYW1lLidcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZS5maW5kKFxuICAgICAgICAgICAgICB0aGlzLmNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgeyBlbWFpbDogdGhpcy5kYXRhLmVtYWlsLCBvYmplY3RJZDogeyAkbmU6IHRoaXMub2JqZWN0SWQoKSB9IH0sXG4gICAgICAgICAgICAgIHsgbGltaXQ6IDEgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuRU1BSUxfVEFLRU4sXG4gICAgICAgICAgICAgICAgJ0FjY291bnQgYWxyZWFkeSBleGlzdHMgZm9yIHRoaXMgZW1haWwgYWRkcmVzcy4nXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLkRVUExJQ0FURV9WQUxVRSxcbiAgICAgICAgICAgICAgJ0EgZHVwbGljYXRlIHZhbHVlIGZvciBhIGZpZWxkIHdpdGggdW5pcXVlIHZhbHVlcyB3YXMgcHJvdmlkZWQnXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgcmVzcG9uc2Uub2JqZWN0SWQgPSB0aGlzLmRhdGEub2JqZWN0SWQ7XG4gICAgICAgIHJlc3BvbnNlLmNyZWF0ZWRBdCA9IHRoaXMuZGF0YS5jcmVhdGVkQXQ7XG5cbiAgICAgICAgaWYgKHRoaXMucmVzcG9uc2VTaG91bGRIYXZlVXNlcm5hbWUpIHtcbiAgICAgICAgICByZXNwb25zZS51c2VybmFtZSA9IHRoaXMuZGF0YS51c2VybmFtZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl91cGRhdGVSZXNwb25zZVdpdGhEYXRhKHJlc3BvbnNlLCB0aGlzLmRhdGEpO1xuICAgICAgICB0aGlzLnJlc3BvbnNlID0ge1xuICAgICAgICAgIHN0YXR1czogMjAxLFxuICAgICAgICAgIHJlc3BvbnNlLFxuICAgICAgICAgIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKCksXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgfVxufTtcblxuLy8gUmV0dXJucyBub3RoaW5nIC0gZG9lc24ndCB3YWl0IGZvciB0aGUgdHJpZ2dlci5cblJlc3RXcml0ZS5wcm90b3R5cGUucnVuQWZ0ZXJTYXZlVHJpZ2dlciA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCF0aGlzLnJlc3BvbnNlIHx8ICF0aGlzLnJlc3BvbnNlLnJlc3BvbnNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gQXZvaWQgZG9pbmcgYW55IHNldHVwIGZvciB0cmlnZ2VycyBpZiB0aGVyZSBpcyBubyAnYWZ0ZXJTYXZlJyB0cmlnZ2VyIGZvciB0aGlzIGNsYXNzLlxuICBjb25zdCBoYXNBZnRlclNhdmVIb29rID0gdHJpZ2dlcnMudHJpZ2dlckV4aXN0cyhcbiAgICB0aGlzLmNsYXNzTmFtZSxcbiAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlclNhdmUsXG4gICAgdGhpcy5jb25maWcuYXBwbGljYXRpb25JZFxuICApO1xuICBjb25zdCBoYXNMaXZlUXVlcnkgPSB0aGlzLmNvbmZpZy5saXZlUXVlcnlDb250cm9sbGVyLmhhc0xpdmVRdWVyeSh0aGlzLmNsYXNzTmFtZSk7XG4gIGlmICghaGFzQWZ0ZXJTYXZlSG9vayAmJiAhaGFzTGl2ZVF1ZXJ5KSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgdmFyIGV4dHJhRGF0YSA9IHsgY2xhc3NOYW1lOiB0aGlzLmNsYXNzTmFtZSB9O1xuICBpZiAodGhpcy5xdWVyeSAmJiB0aGlzLnF1ZXJ5Lm9iamVjdElkKSB7XG4gICAgZXh0cmFEYXRhLm9iamVjdElkID0gdGhpcy5xdWVyeS5vYmplY3RJZDtcbiAgfVxuXG4gIC8vIEJ1aWxkIHRoZSBvcmlnaW5hbCBvYmplY3QsIHdlIG9ubHkgZG8gdGhpcyBmb3IgYSB1cGRhdGUgd3JpdGUuXG4gIGxldCBvcmlnaW5hbE9iamVjdDtcbiAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgIG9yaWdpbmFsT2JqZWN0ID0gdHJpZ2dlcnMuaW5mbGF0ZShleHRyYURhdGEsIHRoaXMub3JpZ2luYWxEYXRhKTtcbiAgfVxuXG4gIC8vIEJ1aWxkIHRoZSBpbmZsYXRlZCBvYmplY3QsIGRpZmZlcmVudCBmcm9tIGJlZm9yZVNhdmUsIG9yaWdpbmFsRGF0YSBpcyBub3QgZW1wdHlcbiAgLy8gc2luY2UgZGV2ZWxvcGVycyBjYW4gY2hhbmdlIGRhdGEgaW4gdGhlIGJlZm9yZVNhdmUuXG4gIGNvbnN0IHVwZGF0ZWRPYmplY3QgPSB0aGlzLmJ1aWxkVXBkYXRlZE9iamVjdChleHRyYURhdGEpO1xuICB1cGRhdGVkT2JqZWN0Ll9oYW5kbGVTYXZlUmVzcG9uc2UodGhpcy5yZXNwb25zZS5yZXNwb25zZSwgdGhpcy5yZXNwb25zZS5zdGF0dXMgfHwgMjAwKTtcblxuICB0aGlzLmNvbmZpZy5kYXRhYmFzZS5sb2FkU2NoZW1hKCkudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHtcbiAgICAvLyBOb3RpZml5IExpdmVRdWVyeVNlcnZlciBpZiBwb3NzaWJsZVxuICAgIGNvbnN0IHBlcm1zID0gc2NoZW1hQ29udHJvbGxlci5nZXRDbGFzc0xldmVsUGVybWlzc2lvbnModXBkYXRlZE9iamVjdC5jbGFzc05hbWUpO1xuICAgIHRoaXMuY29uZmlnLmxpdmVRdWVyeUNvbnRyb2xsZXIub25BZnRlclNhdmUoXG4gICAgICB1cGRhdGVkT2JqZWN0LmNsYXNzTmFtZSxcbiAgICAgIHVwZGF0ZWRPYmplY3QsXG4gICAgICBvcmlnaW5hbE9iamVjdCxcbiAgICAgIHBlcm1zXG4gICAgKTtcbiAgfSk7XG5cbiAgLy8gUnVuIGFmdGVyU2F2ZSB0cmlnZ2VyXG4gIHJldHVybiB0cmlnZ2Vyc1xuICAgIC5tYXliZVJ1blRyaWdnZXIoXG4gICAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlclNhdmUsXG4gICAgICB0aGlzLmF1dGgsXG4gICAgICB1cGRhdGVkT2JqZWN0LFxuICAgICAgb3JpZ2luYWxPYmplY3QsXG4gICAgICB0aGlzLmNvbmZpZyxcbiAgICAgIHRoaXMuY29udGV4dFxuICAgIClcbiAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgaWYgKHJlc3VsdCAmJiB0eXBlb2YgcmVzdWx0ID09PSAnb2JqZWN0Jykge1xuICAgICAgICB0aGlzLnJlc3BvbnNlLnJlc3BvbnNlID0gcmVzdWx0O1xuICAgICAgfVxuICAgIH0pXG4gICAgLmNhdGNoKGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgIGxvZ2dlci53YXJuKCdhZnRlclNhdmUgY2F1Z2h0IGFuIGVycm9yJywgZXJyKTtcbiAgICB9KTtcbn07XG5cbi8vIEEgaGVscGVyIHRvIGZpZ3VyZSBvdXQgd2hhdCBsb2NhdGlvbiB0aGlzIG9wZXJhdGlvbiBoYXBwZW5zIGF0LlxuUmVzdFdyaXRlLnByb3RvdHlwZS5sb2NhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG1pZGRsZSA9IHRoaXMuY2xhc3NOYW1lID09PSAnX1VzZXInID8gJy91c2Vycy8nIDogJy9jbGFzc2VzLycgKyB0aGlzLmNsYXNzTmFtZSArICcvJztcbiAgY29uc3QgbW91bnQgPSB0aGlzLmNvbmZpZy5tb3VudCB8fCB0aGlzLmNvbmZpZy5zZXJ2ZXJVUkw7XG4gIHJldHVybiBtb3VudCArIG1pZGRsZSArIHRoaXMuZGF0YS5vYmplY3RJZDtcbn07XG5cbi8vIEEgaGVscGVyIHRvIGdldCB0aGUgb2JqZWN0IGlkIGZvciB0aGlzIG9wZXJhdGlvbi5cbi8vIEJlY2F1c2UgaXQgY291bGQgYmUgZWl0aGVyIG9uIHRoZSBxdWVyeSBvciBvbiB0aGUgZGF0YVxuUmVzdFdyaXRlLnByb3RvdHlwZS5vYmplY3RJZCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMuZGF0YS5vYmplY3RJZCB8fCB0aGlzLnF1ZXJ5Lm9iamVjdElkO1xufTtcblxuLy8gUmV0dXJucyBhIGNvcHkgb2YgdGhlIGRhdGEgYW5kIGRlbGV0ZSBiYWQga2V5cyAoX2F1dGhfZGF0YSwgX2hhc2hlZF9wYXNzd29yZC4uLilcblJlc3RXcml0ZS5wcm90b3R5cGUuc2FuaXRpemVkRGF0YSA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgZGF0YSA9IE9iamVjdC5rZXlzKHRoaXMuZGF0YSkucmVkdWNlKChkYXRhLCBrZXkpID0+IHtcbiAgICAvLyBSZWdleHAgY29tZXMgZnJvbSBQYXJzZS5PYmplY3QucHJvdG90eXBlLnZhbGlkYXRlXG4gICAgaWYgKCEvXltBLVphLXpdWzAtOUEtWmEtel9dKiQvLnRlc3Qoa2V5KSkge1xuICAgICAgZGVsZXRlIGRhdGFba2V5XTtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGE7XG4gIH0sIGRlZXBjb3B5KHRoaXMuZGF0YSkpO1xuICByZXR1cm4gUGFyc2UuX2RlY29kZSh1bmRlZmluZWQsIGRhdGEpO1xufTtcblxuLy8gUmV0dXJucyBhbiB1cGRhdGVkIGNvcHkgb2YgdGhlIG9iamVjdFxuUmVzdFdyaXRlLnByb3RvdHlwZS5idWlsZFVwZGF0ZWRPYmplY3QgPSBmdW5jdGlvbiAoZXh0cmFEYXRhKSB7XG4gIGNvbnN0IHVwZGF0ZWRPYmplY3QgPSB0cmlnZ2Vycy5pbmZsYXRlKGV4dHJhRGF0YSwgdGhpcy5vcmlnaW5hbERhdGEpO1xuICBPYmplY3Qua2V5cyh0aGlzLmRhdGEpLnJlZHVjZShmdW5jdGlvbiAoZGF0YSwga2V5KSB7XG4gICAgaWYgKGtleS5pbmRleE9mKCcuJykgPiAwKSB7XG4gICAgICBpZiAodHlwZW9mIGRhdGFba2V5XS5fX29wID09PSAnc3RyaW5nJykge1xuICAgICAgICB1cGRhdGVkT2JqZWN0LnNldChrZXksIGRhdGFba2V5XSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBzdWJkb2N1bWVudCBrZXkgd2l0aCBkb3Qgbm90YXRpb24geyAneC55JzogdiB9ID0+IHsgJ3gnOiB7ICd5JyA6IHYgfSB9KVxuICAgICAgICBjb25zdCBzcGxpdHRlZEtleSA9IGtleS5zcGxpdCgnLicpO1xuICAgICAgICBjb25zdCBwYXJlbnRQcm9wID0gc3BsaXR0ZWRLZXlbMF07XG4gICAgICAgIGxldCBwYXJlbnRWYWwgPSB1cGRhdGVkT2JqZWN0LmdldChwYXJlbnRQcm9wKTtcbiAgICAgICAgaWYgKHR5cGVvZiBwYXJlbnRWYWwgIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgcGFyZW50VmFsID0ge307XG4gICAgICAgIH1cbiAgICAgICAgcGFyZW50VmFsW3NwbGl0dGVkS2V5WzFdXSA9IGRhdGFba2V5XTtcbiAgICAgICAgdXBkYXRlZE9iamVjdC5zZXQocGFyZW50UHJvcCwgcGFyZW50VmFsKTtcbiAgICAgIH1cbiAgICAgIGRlbGV0ZSBkYXRhW2tleV07XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9LCBkZWVwY29weSh0aGlzLmRhdGEpKTtcblxuICB1cGRhdGVkT2JqZWN0LnNldCh0aGlzLnNhbml0aXplZERhdGEoKSk7XG4gIHJldHVybiB1cGRhdGVkT2JqZWN0O1xufTtcblxuUmVzdFdyaXRlLnByb3RvdHlwZS5jbGVhblVzZXJBdXRoRGF0YSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMucmVzcG9uc2UgJiYgdGhpcy5yZXNwb25zZS5yZXNwb25zZSAmJiB0aGlzLmNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIGNvbnN0IHVzZXIgPSB0aGlzLnJlc3BvbnNlLnJlc3BvbnNlO1xuICAgIGlmICh1c2VyLmF1dGhEYXRhKSB7XG4gICAgICBPYmplY3Qua2V5cyh1c2VyLmF1dGhEYXRhKS5mb3JFYWNoKHByb3ZpZGVyID0+IHtcbiAgICAgICAgaWYgKHVzZXIuYXV0aERhdGFbcHJvdmlkZXJdID09PSBudWxsKSB7XG4gICAgICAgICAgZGVsZXRlIHVzZXIuYXV0aERhdGFbcHJvdmlkZXJdO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGlmIChPYmplY3Qua2V5cyh1c2VyLmF1dGhEYXRhKS5sZW5ndGggPT0gMCkge1xuICAgICAgICBkZWxldGUgdXNlci5hdXRoRGF0YTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuX3VwZGF0ZVJlc3BvbnNlV2l0aERhdGEgPSBmdW5jdGlvbiAocmVzcG9uc2UsIGRhdGEpIHtcbiAgaWYgKF8uaXNFbXB0eSh0aGlzLnN0b3JhZ2UuZmllbGRzQ2hhbmdlZEJ5VHJpZ2dlcikpIHtcbiAgICByZXR1cm4gcmVzcG9uc2U7XG4gIH1cbiAgY29uc3QgY2xpZW50U3VwcG9ydHNEZWxldGUgPSBDbGllbnRTREsuc3VwcG9ydHNGb3J3YXJkRGVsZXRlKHRoaXMuY2xpZW50U0RLKTtcbiAgdGhpcy5zdG9yYWdlLmZpZWxkc0NoYW5nZWRCeVRyaWdnZXIuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgIGNvbnN0IGRhdGFWYWx1ZSA9IGRhdGFbZmllbGROYW1lXTtcblxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3BvbnNlLCBmaWVsZE5hbWUpKSB7XG4gICAgICByZXNwb25zZVtmaWVsZE5hbWVdID0gZGF0YVZhbHVlO1xuICAgIH1cblxuICAgIC8vIFN0cmlwcyBvcGVyYXRpb25zIGZyb20gcmVzcG9uc2VzXG4gICAgaWYgKHJlc3BvbnNlW2ZpZWxkTmFtZV0gJiYgcmVzcG9uc2VbZmllbGROYW1lXS5fX29wKSB7XG4gICAgICBkZWxldGUgcmVzcG9uc2VbZmllbGROYW1lXTtcbiAgICAgIGlmIChjbGllbnRTdXBwb3J0c0RlbGV0ZSAmJiBkYXRhVmFsdWUuX19vcCA9PSAnRGVsZXRlJykge1xuICAgICAgICByZXNwb25zZVtmaWVsZE5hbWVdID0gZGF0YVZhbHVlO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHJldHVybiByZXNwb25zZTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFJlc3RXcml0ZTtcbm1vZHVsZS5leHBvcnRzID0gUmVzdFdyaXRlO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/AggregateRouter.js b/lib/Routers/AggregateRouter.js new file mode 100644 index 0000000000..8529b49ea8 --- /dev/null +++ b/lib/Routers/AggregateRouter.js @@ -0,0 +1,153 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.AggregateRouter = void 0; + +var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); + +var _rest = _interopRequireDefault(require("../rest")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +var _node = _interopRequireDefault(require("parse/node")); + +var _UsersRouter = _interopRequireDefault(require("./UsersRouter")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const BASE_KEYS = ['where', 'distinct', 'pipeline', 'hint', 'explain']; +const PIPELINE_KEYS = ['addFields', 'bucket', 'bucketAuto', 'collStats', 'count', 'currentOp', 'facet', 'geoNear', 'graphLookup', 'group', 'indexStats', 'limit', 'listLocalSessions', 'listSessions', 'lookup', 'match', 'out', 'project', 'redact', 'replaceRoot', 'sample', 'skip', 'sort', 'sortByCount', 'unwind']; +const ALLOWED_KEYS = [...BASE_KEYS, ...PIPELINE_KEYS]; + +class AggregateRouter extends _ClassesRouter.default { + handleFind(req) { + const body = Object.assign(req.body, _ClassesRouter.default.JSONFromQuery(req.query)); + const options = {}; + + if (body.distinct) { + options.distinct = String(body.distinct); + } + + if (body.hint) { + options.hint = body.hint; + delete body.hint; + } + + if (body.explain) { + options.explain = body.explain; + delete body.explain; + } + + if (body.readPreference) { + options.readPreference = body.readPreference; + delete body.readPreference; + } + + options.pipeline = AggregateRouter.getPipeline(body); + + if (typeof body.where === 'string') { + body.where = JSON.parse(body.where); + } + + return _rest.default.find(req.config, req.auth, this.className(req), body.where, options, req.info.clientSDK, req.info.context).then(response => { + for (const result of response.results) { + if (typeof result === 'object') { + _UsersRouter.default.removeHiddenProperties(result); + } + } + + return { + response + }; + }); + } + /* Builds a pipeline from the body. Originally the body could be passed as a single object, + * and now we support many options + * + * Array + * + * body: [{ + * group: { objectId: '$name' }, + * }] + * + * Object + * + * body: { + * group: { objectId: '$name' }, + * } + * + * + * Pipeline Operator with an Array or an Object + * + * body: { + * pipeline: { + * group: { objectId: '$name' }, + * } + * } + * + */ + + + static getPipeline(body) { + let pipeline = body.pipeline || body; + + if (!Array.isArray(pipeline)) { + pipeline = Object.keys(pipeline).map(key => { + return { + [key]: pipeline[key] + }; + }); + } + + return pipeline.map(stage => { + const keys = Object.keys(stage); + + if (keys.length != 1) { + throw new Error(`Pipeline stages should only have one key found ${keys.join(', ')}`); + } + + return AggregateRouter.transformStage(keys[0], stage); + }); + } + + static transformStage(stageName, stage) { + if (ALLOWED_KEYS.indexOf(stageName) === -1) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Invalid parameter for query: ${stageName}`); + } + + if (stageName === 'group') { + if (Object.prototype.hasOwnProperty.call(stage[stageName], '_id')) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Invalid parameter for query: group. Please use objectId instead of _id`); + } + + if (!Object.prototype.hasOwnProperty.call(stage[stageName], 'objectId')) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Invalid parameter for query: group. objectId is required`); + } + + stage[stageName]._id = stage[stageName].objectId; + delete stage[stageName].objectId; + } + + return { + [`$${stageName}`]: stage[stageName] + }; + } + + mountRoutes() { + this.route('GET', '/aggregate/:className', middleware.promiseEnforceMasterKeyAccess, req => { + return this.handleFind(req); + }); + } + +} + +exports.AggregateRouter = AggregateRouter; +var _default = AggregateRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0FnZ3JlZ2F0ZVJvdXRlci5qcyJdLCJuYW1lcyI6WyJCQVNFX0tFWVMiLCJQSVBFTElORV9LRVlTIiwiQUxMT1dFRF9LRVlTIiwiQWdncmVnYXRlUm91dGVyIiwiQ2xhc3Nlc1JvdXRlciIsImhhbmRsZUZpbmQiLCJyZXEiLCJib2R5IiwiT2JqZWN0IiwiYXNzaWduIiwiSlNPTkZyb21RdWVyeSIsInF1ZXJ5Iiwib3B0aW9ucyIsImRpc3RpbmN0IiwiU3RyaW5nIiwiaGludCIsImV4cGxhaW4iLCJyZWFkUHJlZmVyZW5jZSIsInBpcGVsaW5lIiwiZ2V0UGlwZWxpbmUiLCJ3aGVyZSIsIkpTT04iLCJwYXJzZSIsInJlc3QiLCJmaW5kIiwiY29uZmlnIiwiYXV0aCIsImNsYXNzTmFtZSIsImluZm8iLCJjbGllbnRTREsiLCJjb250ZXh0IiwidGhlbiIsInJlc3BvbnNlIiwicmVzdWx0IiwicmVzdWx0cyIsIlVzZXJzUm91dGVyIiwicmVtb3ZlSGlkZGVuUHJvcGVydGllcyIsIkFycmF5IiwiaXNBcnJheSIsImtleXMiLCJtYXAiLCJrZXkiLCJzdGFnZSIsImxlbmd0aCIsIkVycm9yIiwiam9pbiIsInRyYW5zZm9ybVN0YWdlIiwic3RhZ2VOYW1lIiwiaW5kZXhPZiIsIlBhcnNlIiwiSU5WQUxJRF9RVUVSWSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIl9pZCIsIm9iamVjdElkIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsIm1pZGRsZXdhcmUiLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVBLE1BQU1BLFNBQVMsR0FBRyxDQUFDLE9BQUQsRUFBVSxVQUFWLEVBQXNCLFVBQXRCLEVBQWtDLE1BQWxDLEVBQTBDLFNBQTFDLENBQWxCO0FBRUEsTUFBTUMsYUFBYSxHQUFHLENBQ3BCLFdBRG9C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dkMsTUFBTSxDQUFDMkMsU0FBUCxDQUFpQkMsY0FBakIsQ0FBZ0NDLElBQWhDLENBQXFDWCxLQUFLLENBQUNLLFNBQUQsQ0FBMUMsRUFBdUQsS0FBdkQsQ0FBSixFQUFtRTtBQUNqRSxjQUFNLElBQUlFLGNBQU1MLEtBQVYsQ0FDSkssY0FBTUwsS0FBTixDQUFZTSxhQURSLEVBRUgsd0VBRkcsQ0FBTjtBQUlEOztBQUNELFVBQUksQ0FBQzFDLE1BQU0sQ0FBQzJDLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUFxQ1gsS0FBSyxDQUFDSyxTQUFELENBQTFDLEVBQXVELFVBQXZELENBQUwsRUFBeUU7QUFDdkUsY0FBTSxJQUFJRSxjQUFNTCxLQUFWLENBQ0pLLGNBQU1MLEtBQU4sQ0FBWU0sYUFEUixFQUVILDBEQUZHLENBQU47QUFJRDs7QUFDRFIsTUFBQUEsS0FBSyxDQUFDSyxTQUFELENBQUwsQ0FBaUJPLEdBQWpCLEdBQXVCWixLQUFLLENBQUNLLFNBQUQsQ0FBTCxDQUFpQlEsUUFBeEM7QUFDQSxhQUFPYixLQUFLLENBQUNLLFNBQUQsQ0FBTCxDQUFpQlEsUUFBeEI7QUFDRDs7QUFDRCxXQUFPO0FBQUUsT0FBRSxJQUFHUixTQUFVLEVBQWYsR0FBbUJMLEtBQUssQ0FBQ0ssU0FBRDtBQUExQixLQUFQO0FBQ0Q7O0FBRURTLEVBQUFBLFdBQVcsR0FBRztBQUNaLFNBQUtDLEtBQUwsQ0FBVyxLQUFYLEVBQWtCLHVCQUFsQixFQUEyQ0MsVUFBVSxDQUFDQyw2QkFBdEQsRUFBcUZyRCxHQUFHLElBQUk7QUFDMUYsYUFBTyxLQUFLRCxVQUFMLENBQWdCQyxHQUFoQixDQUFQO0FBQ0QsS0FGRDtBQUdEOztBQWhIZ0Q7OztlQW1IcENILGUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQ2xhc3Nlc1JvdXRlciBmcm9tICcuL0NsYXNzZXNSb3V0ZXInO1xuaW1wb3J0IHJlc3QgZnJvbSAnLi4vcmVzdCc7XG5pbXBvcnQgKiBhcyBtaWRkbGV3YXJlIGZyb20gJy4uL21pZGRsZXdhcmVzJztcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBVc2Vyc1JvdXRlciBmcm9tICcuL1VzZXJzUm91dGVyJztcblxuY29uc3QgQkFTRV9LRVlTID0gWyd3aGVyZScsICdkaXN0aW5jdCcsICdwaXBlbGluZScsICdoaW50JywgJ2V4cGxhaW4nXTtcblxuY29uc3QgUElQRUxJTkVfS0VZUyA9IFtcbiAgJ2FkZEZpZWxkcycsXG4gICdidWNrZXQnLFxuICAnYnVja2V0QXV0bycsXG4gICdjb2xsU3RhdHMnLFxuICAnY291bnQnLFxuICAnY3VycmVudE9wJyxcbiAgJ2ZhY2V0JyxcbiAgJ2dlb05lYXInLFxuICAnZ3JhcGhMb29rdXAnLFxuICAnZ3JvdXAnLFxuICAnaW5kZXhTdGF0cycsXG4gICdsaW1pdCcsXG4gICdsaXN0TG9jYWxTZXNzaW9ucycsXG4gICdsaXN0U2Vzc2lvbnMnLFxuICAnbG9va3VwJyxcbiAgJ21hdGNoJyxcbiAgJ291dCcsXG4gICdwcm9qZWN0JyxcbiAgJ3JlZGFjdCcsXG4gICdyZXBsYWNlUm9vdCcsXG4gICdzYW1wbGUnLFxuICAnc2tpcCcsXG4gICdzb3J0JyxcbiAgJ3NvcnRCeUNvdW50JyxcbiAgJ3Vud2luZCcsXG5dO1xuXG5jb25zdCBBTExPV0VEX0tFWVMgPSBbLi4uQkFTRV9LRVlTLCAuLi5QSVBFTElORV9LRVlTXTtcblxuZXhwb3J0IGNsYXNzIEFnZ3JlZ2F0ZVJvdXRlciBleHRlbmRzIENsYXNzZXNSb3V0ZXIge1xuICBoYW5kbGVGaW5kKHJlcSkge1xuICAgIGNvbnN0IGJvZHkgPSBPYmplY3QuYXNzaWduKHJlcS5ib2R5LCBDbGFzc2VzUm91dGVyLkpTT05Gcm9tUXVlcnkocmVxLnF1ZXJ5KSk7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHt9O1xuICAgIGlmIChib2R5LmRpc3RpbmN0KSB7XG4gICAgICBvcHRpb25zLmRpc3RpbmN0ID0gU3RyaW5nKGJvZHkuZGlzdGluY3QpO1xuICAgIH1cbiAgICBpZiAoYm9keS5oaW50KSB7XG4gICAgICBvcHRpb25zLmhpbnQgPSBib2R5LmhpbnQ7XG4gICAgICBkZWxldGUgYm9keS5oaW50O1xuICAgIH1cbiAgICBpZiAoYm9keS5leHBsYWluKSB7XG4gICAgICBvcHRpb25zLmV4cGxhaW4gPSBib2R5LmV4cGxhaW47XG4gICAgICBkZWxldGUgYm9keS5leHBsYWluO1xuICAgIH1cbiAgICBpZiAoYm9keS5yZWFkUHJlZmVyZW5jZSkge1xuICAgICAgb3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IGJvZHkucmVhZFByZWZlcmVuY2U7XG4gICAgICBkZWxldGUgYm9keS5yZWFkUHJlZmVyZW5jZTtcbiAgICB9XG4gICAgb3B0aW9ucy5waXBlbGluZSA9IEFnZ3JlZ2F0ZVJvdXRlci5nZXRQaXBlbGluZShib2R5KTtcbiAgICBpZiAodHlwZW9mIGJvZHkud2hlcmUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBib2R5LndoZXJlID0gSlNPTi5wYXJzZShib2R5LndoZXJlKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3RcbiAgICAgIC5maW5kKFxuICAgICAgICByZXEuY29uZmlnLFxuICAgICAgICByZXEuYXV0aCxcbiAgICAgICAgdGhpcy5jbGFzc05hbWUocmVxKSxcbiAgICAgICAgYm9keS53aGVyZSxcbiAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgcmVxLmluZm8uY2xpZW50U0RLLFxuICAgICAgICByZXEuaW5mby5jb250ZXh0XG4gICAgICApXG4gICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIHJlc3BvbnNlLnJlc3VsdHMpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIHJlc3VsdCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIFVzZXJzUm91dGVyLnJlbW92ZUhpZGRlblByb3BlcnRpZXMocmVzdWx0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2UgfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyogQnVpbGRzIGEgcGlwZWxpbmUgZnJvbSB0aGUgYm9keS4gT3JpZ2luYWxseSB0aGUgYm9keSBjb3VsZCBiZSBwYXNzZWQgYXMgYSBzaW5nbGUgb2JqZWN0LFxuICAgKiBhbmQgbm93IHdlIHN1cHBvcnQgbWFueSBvcHRpb25zXG4gICAqXG4gICAqIEFycmF5XG4gICAqXG4gICAqIGJvZHk6IFt7XG4gICAqICAgZ3JvdXA6IHsgb2JqZWN0SWQ6ICckbmFtZScgfSxcbiAgICogfV1cbiAgICpcbiAgICogT2JqZWN0XG4gICAqXG4gICAqIGJvZHk6IHtcbiAgICogICBncm91cDogeyBvYmplY3RJZDogJyRuYW1lJyB9LFxuICAgKiB9XG4gICAqXG4gICAqXG4gICAqIFBpcGVsaW5lIE9wZXJhdG9yIHdpdGggYW4gQXJyYXkgb3IgYW4gT2JqZWN0XG4gICAqXG4gICAqIGJvZHk6IHtcbiAgICogICBwaXBlbGluZToge1xuICAgKiAgICAgZ3JvdXA6IHsgb2JqZWN0SWQ6ICckbmFtZScgfSxcbiAgICogICB9XG4gICAqIH1cbiAgICpcbiAgICovXG4gIHN0YXRpYyBnZXRQaXBlbGluZShib2R5KSB7XG4gICAgbGV0IHBpcGVsaW5lID0gYm9keS5waXBlbGluZSB8fCBib2R5O1xuICAgIGlmICghQXJyYXkuaXNBcnJheShwaXBlbGluZSkpIHtcbiAgICAgIHBpcGVsaW5lID0gT2JqZWN0LmtleXMocGlwZWxpbmUpLm1hcChrZXkgPT4ge1xuICAgICAgICByZXR1cm4geyBba2V5XTogcGlwZWxpbmVba2V5XSB9O1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBpcGVsaW5lLm1hcChzdGFnZSA9PiB7XG4gICAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoc3RhZ2UpO1xuICAgICAgaWYgKGtleXMubGVuZ3RoICE9IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBQaXBlbGluZSBzdGFnZXMgc2hvdWxkIG9ubHkgaGF2ZSBvbmUga2V5IGZvdW5kICR7a2V5cy5qb2luKCcsICcpfWApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIEFnZ3JlZ2F0ZVJvdXRlci50cmFuc2Zvcm1TdGFnZShrZXlzWzBdLCBzdGFnZSk7XG4gICAgfSk7XG4gIH1cblxuICBzdGF0aWMgdHJhbnNmb3JtU3RhZ2Uoc3RhZ2VOYW1lLCBzdGFnZSkge1xuICAgIGlmIChBTExPV0VEX0tFWVMuaW5kZXhPZihzdGFnZU5hbWUpID09PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksIGBJbnZhbGlkIHBhcmFtZXRlciBmb3IgcXVlcnk6ICR7c3RhZ2VOYW1lfWApO1xuICAgIH1cbiAgICBpZiAoc3RhZ2VOYW1lID09PSAnZ3JvdXAnKSB7XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHN0YWdlW3N0YWdlTmFtZV0sICdfaWQnKSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSxcbiAgICAgICAgICBgSW52YWxpZCBwYXJhbWV0ZXIgZm9yIHF1ZXJ5OiBncm91cC4gUGxlYXNlIHVzZSBvYmplY3RJZCBpbnN0ZWFkIG9mIF9pZGBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHN0YWdlW3N0YWdlTmFtZV0sICdvYmplY3RJZCcpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAgIGBJbnZhbGlkIHBhcmFtZXRlciBmb3IgcXVlcnk6IGdyb3VwLiBvYmplY3RJZCBpcyByZXF1aXJlZGBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHN0YWdlW3N0YWdlTmFtZV0uX2lkID0gc3RhZ2Vbc3RhZ2VOYW1lXS5vYmplY3RJZDtcbiAgICAgIGRlbGV0ZSBzdGFnZVtzdGFnZU5hbWVdLm9iamVjdElkO1xuICAgIH1cbiAgICByZXR1cm4geyBbYCQke3N0YWdlTmFtZX1gXTogc3RhZ2Vbc3RhZ2VOYW1lXSB9O1xuICB9XG5cbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9hZ2dyZWdhdGUvOmNsYXNzTmFtZScsIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVGaW5kKHJlcSk7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQWdncmVnYXRlUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/AnalyticsRouter.js b/lib/Routers/AnalyticsRouter.js new file mode 100644 index 0000000000..d37290b37f --- /dev/null +++ b/lib/Routers/AnalyticsRouter.js @@ -0,0 +1,32 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.AnalyticsRouter = void 0; + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// AnalyticsRouter.js +function appOpened(req) { + const analyticsController = req.config.analyticsController; + return analyticsController.appOpened(req); +} + +function trackEvent(req) { + const analyticsController = req.config.analyticsController; + return analyticsController.trackEvent(req); +} + +class AnalyticsRouter extends _PromiseRouter.default { + mountRoutes() { + this.route('POST', '/events/AppOpened', appOpened); + this.route('POST', '/events/:eventName', trackEvent); + } + +} + +exports.AnalyticsRouter = AnalyticsRouter; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0FuYWx5dGljc1JvdXRlci5qcyJdLCJuYW1lcyI6WyJhcHBPcGVuZWQiLCJyZXEiLCJhbmFseXRpY3NDb250cm9sbGVyIiwiY29uZmlnIiwidHJhY2tFdmVudCIsIkFuYWx5dGljc1JvdXRlciIsIlByb21pc2VSb3V0ZXIiLCJtb3VudFJvdXRlcyIsInJvdXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7Ozs7QUFEQTtBQUdBLFNBQVNBLFNBQVQsQ0FBbUJDLEdBQW5CLEVBQXdCO0FBQ3RCLFFBQU1DLG1CQUFtQixHQUFHRCxHQUFHLENBQUNFLE1BQUosQ0FBV0QsbUJBQXZDO0FBQ0EsU0FBT0EsbUJBQW1CLENBQUNGLFNBQXBCLENBQThCQyxHQUE5QixDQUFQO0FBQ0Q7O0FBRUQsU0FBU0csVUFBVCxDQUFvQkgsR0FBcEIsRUFBeUI7QUFDdkIsUUFBTUMsbUJBQW1CLEdBQUdELEdBQUcsQ0FBQ0UsTUFBSixDQUFXRCxtQkFBdkM7QUFDQSxTQUFPQSxtQkFBbUIsQ0FBQ0UsVUFBcEIsQ0FBK0JILEdBQS9CLENBQVA7QUFDRDs7QUFFTSxNQUFNSSxlQUFOLFNBQThCQyxzQkFBOUIsQ0FBNEM7QUFDakRDLEVBQUFBLFdBQVcsR0FBRztBQUNaLFNBQUtDLEtBQUwsQ0FBVyxNQUFYLEVBQW1CLG1CQUFuQixFQUF3Q1IsU0FBeEM7QUFDQSxTQUFLUSxLQUFMLENBQVcsTUFBWCxFQUFtQixvQkFBbkIsRUFBeUNKLFVBQXpDO0FBQ0Q7O0FBSmdEIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQW5hbHl0aWNzUm91dGVyLmpzXG5pbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuLi9Qcm9taXNlUm91dGVyJztcblxuZnVuY3Rpb24gYXBwT3BlbmVkKHJlcSkge1xuICBjb25zdCBhbmFseXRpY3NDb250cm9sbGVyID0gcmVxLmNvbmZpZy5hbmFseXRpY3NDb250cm9sbGVyO1xuICByZXR1cm4gYW5hbHl0aWNzQ29udHJvbGxlci5hcHBPcGVuZWQocmVxKTtcbn1cblxuZnVuY3Rpb24gdHJhY2tFdmVudChyZXEpIHtcbiAgY29uc3QgYW5hbHl0aWNzQ29udHJvbGxlciA9IHJlcS5jb25maWcuYW5hbHl0aWNzQ29udHJvbGxlcjtcbiAgcmV0dXJuIGFuYWx5dGljc0NvbnRyb2xsZXIudHJhY2tFdmVudChyZXEpO1xufVxuXG5leHBvcnQgY2xhc3MgQW5hbHl0aWNzUm91dGVyIGV4dGVuZHMgUHJvbWlzZVJvdXRlciB7XG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL2V2ZW50cy9BcHBPcGVuZWQnLCBhcHBPcGVuZWQpO1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL2V2ZW50cy86ZXZlbnROYW1lJywgdHJhY2tFdmVudCk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/AudiencesRouter.js b/lib/Routers/AudiencesRouter.js new file mode 100644 index 0000000000..684d3e42a2 --- /dev/null +++ b/lib/Routers/AudiencesRouter.js @@ -0,0 +1,70 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.AudiencesRouter = void 0; + +var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); + +var _rest = _interopRequireDefault(require("../rest")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class AudiencesRouter extends _ClassesRouter.default { + className() { + return '_Audience'; + } + + handleFind(req) { + const body = Object.assign(req.body, _ClassesRouter.default.JSONFromQuery(req.query)); + + const options = _ClassesRouter.default.optionsFromBody(body); + + return _rest.default.find(req.config, req.auth, '_Audience', body.where, options, req.info.clientSDK, req.info.context).then(response => { + response.results.forEach(item => { + item.query = JSON.parse(item.query); + }); + return { + response: response + }; + }); + } + + handleGet(req) { + return super.handleGet(req).then(data => { + data.response.query = JSON.parse(data.response.query); + return data; + }); + } + + mountRoutes() { + this.route('GET', '/push_audiences', middleware.promiseEnforceMasterKeyAccess, req => { + return this.handleFind(req); + }); + this.route('GET', '/push_audiences/:objectId', middleware.promiseEnforceMasterKeyAccess, req => { + return this.handleGet(req); + }); + this.route('POST', '/push_audiences', middleware.promiseEnforceMasterKeyAccess, req => { + return this.handleCreate(req); + }); + this.route('PUT', '/push_audiences/:objectId', middleware.promiseEnforceMasterKeyAccess, req => { + return this.handleUpdate(req); + }); + this.route('DELETE', '/push_audiences/:objectId', middleware.promiseEnforceMasterKeyAccess, req => { + return this.handleDelete(req); + }); + } + +} + +exports.AudiencesRouter = AudiencesRouter; +var _default = AudiencesRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0F1ZGllbmNlc1JvdXRlci5qcyJdLCJuYW1lcyI6WyJBdWRpZW5jZXNSb3V0ZXIiLCJDbGFzc2VzUm91dGVyIiwiY2xhc3NOYW1lIiwiaGFuZGxlRmluZCIsInJlcSIsImJvZHkiLCJPYmplY3QiLCJhc3NpZ24iLCJKU09ORnJvbVF1ZXJ5IiwicXVlcnkiLCJvcHRpb25zIiwib3B0aW9uc0Zyb21Cb2R5IiwicmVzdCIsImZpbmQiLCJjb25maWciLCJhdXRoIiwid2hlcmUiLCJpbmZvIiwiY2xpZW50U0RLIiwiY29udGV4dCIsInRoZW4iLCJyZXNwb25zZSIsInJlc3VsdHMiLCJmb3JFYWNoIiwiaXRlbSIsIkpTT04iLCJwYXJzZSIsImhhbmRsZUdldCIsImRhdGEiLCJtb3VudFJvdXRlcyIsInJvdXRlIiwibWlkZGxld2FyZSIsInByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzIiwiaGFuZGxlQ3JlYXRlIiwiaGFuZGxlVXBkYXRlIiwiaGFuZGxlRGVsZXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBRU8sTUFBTUEsZUFBTixTQUE4QkMsc0JBQTlCLENBQTRDO0FBQ2pEQyxFQUFBQSxTQUFTLEdBQUc7QUFDVixXQUFPLFdBQVA7QUFDRDs7QUFFREMsRUFBQUEsVUFBVSxDQUFDQyxHQUFELEVBQU07QUFDZCxVQUFNQyxJQUFJLEdBQUdDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjSCxHQUFHLENBQUNDLElBQWxCLEVBQXdCSix1QkFBY08sYUFBZCxDQUE0QkosR0FBRyxDQUFDSyxLQUFoQyxDQUF4QixDQUFiOztBQUNBLFVBQU1DLE9BQU8sR0FBR1QsdUJBQWNVLGVBQWQsQ0FBOEJOLElBQTlCLENBQWhCOztBQUVBLFdBQU9PLGNBQ0pDLElBREksQ0FFSFQsR0FBRyxDQUFDVSxNQUZELEVBR0hWLEdBQUcsQ0FBQ1csSUFIRCxFQUlILFdBSkcsRUFLSFYsSUFBSSxDQUFDVyxLQUxGLEVBTUhOLE9BTkcsRUFPSE4sR0FBRyxDQUFDYSxJQUFKLENBQVNDLFNBUE4sRUFRSGQsR0FBRyxDQUFDYSxJQUFKLENBQVNFLE9BUk4sRUFVSkMsSUFWSSxDQVVDQyxRQUFRLElBQUk7QUFDaEJBLE1BQUFBLFFBQVEsQ0FBQ0MsT0FBVCxDQUFpQkMsT0FBakIsQ0FBeUJDLElBQUksSUFBSTtBQUMvQkEsUUFBQUEsSUFBSSxDQUFDZixLQUFMLEdBQWFnQixJQUFJLENBQUNDLEtBQUwsQ0FBV0YsSUFBSSxDQUFDZixLQUFoQixDQUFiO0FBQ0QsT0FGRDtBQUlBLGFBQU87QUFBRVksUUFBQUEsUUFBUSxFQUFFQTtBQUFaLE9BQVA7QUFDRCxLQWhCSSxDQUFQO0FBaUJEOztBQUVETSxFQUFBQSxTQUFTLENBQUN2QixHQUFELEVBQU07QUFDYixXQUFPLE1BQU11QixTQUFOLENBQWdCdkIsR0FBaEIsRUFBcUJnQixJQUFyQixDQUEwQlEsSUFBSSxJQUFJO0FBQ3ZDQSxNQUFBQSxJQUFJLENBQUNQLFFBQUwsQ0FBY1osS0FBZCxHQUFzQmdCLElBQUksQ0FBQ0MsS0FBTCxDQUFXRSxJQUFJLENBQUNQLFFBQUwsQ0FBY1osS0FBekIsQ0FBdEI7QUFFQSxhQUFPbUIsSUFBUDtBQUNELEtBSk0sQ0FBUDtBQUtEOztBQUVEQyxFQUFBQSxXQUFXLEdBQUc7QUFDWixTQUFLQyxLQUFMLENBQVcsS0FBWCxFQUFrQixpQkFBbEIsRUFBcUNDLFVBQVUsQ0FBQ0MsNkJBQWhELEVBQStFNUIsR0FBRyxJQUFJO0FBQ3BGLGFBQU8sS0FBS0QsVUFBTCxDQUFnQkMsR0FBaEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLMEIsS0FBTCxDQUNFLEtBREYsRUFFRSwyQkFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUU1QixHQUFHLElBQUk7QUFDTCxhQUFPLEtBQUt1QixTQUFMLENBQWV2QixHQUFmLENBQVA7QUFDRCxLQU5IO0FBUUEsU0FBSzBCLEtBQUwsQ0FBVyxNQUFYLEVBQW1CLGlCQUFuQixFQUFzQ0MsVUFBVSxDQUFDQyw2QkFBakQsRUFBZ0Y1QixHQUFHLElBQUk7QUFDckYsYUFBTyxLQUFLNkIsWUFBTCxDQUFrQjdCLEdBQWxCLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBSzBCLEtBQUwsQ0FDRSxLQURGLEVBRUUsMkJBRkYsRUFHRUMsVUFBVSxDQUFDQyw2QkFIYixFQUlFNUIsR0FBRyxJQUFJO0FBQ0wsYUFBTyxLQUFLOEIsWUFBTCxDQUFrQjlCLEdBQWxCLENBQVA7QUFDRCxLQU5IO0FBUUEsU0FBSzBCLEtBQUwsQ0FDRSxRQURGLEVBRUUsMkJBRkYsRUFHRUMsVUFBVSxDQUFDQyw2QkFIYixFQUlFNUIsR0FBRyxJQUFJO0FBQ0wsYUFBTyxLQUFLK0IsWUFBTCxDQUFrQi9CLEdBQWxCLENBQVA7QUFDRCxLQU5IO0FBUUQ7O0FBbkVnRDs7O2VBc0VwQ0osZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBDbGFzc2VzUm91dGVyIGZyb20gJy4vQ2xhc3Nlc1JvdXRlcic7XG5pbXBvcnQgcmVzdCBmcm9tICcuLi9yZXN0JztcbmltcG9ydCAqIGFzIG1pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5leHBvcnQgY2xhc3MgQXVkaWVuY2VzUm91dGVyIGV4dGVuZHMgQ2xhc3Nlc1JvdXRlciB7XG4gIGNsYXNzTmFtZSgpIHtcbiAgICByZXR1cm4gJ19BdWRpZW5jZSc7XG4gIH1cblxuICBoYW5kbGVGaW5kKHJlcSkge1xuICAgIGNvbnN0IGJvZHkgPSBPYmplY3QuYXNzaWduKHJlcS5ib2R5LCBDbGFzc2VzUm91dGVyLkpTT05Gcm9tUXVlcnkocmVxLnF1ZXJ5KSk7XG4gICAgY29uc3Qgb3B0aW9ucyA9IENsYXNzZXNSb3V0ZXIub3B0aW9uc0Zyb21Cb2R5KGJvZHkpO1xuXG4gICAgcmV0dXJuIHJlc3RcbiAgICAgIC5maW5kKFxuICAgICAgICByZXEuY29uZmlnLFxuICAgICAgICByZXEuYXV0aCxcbiAgICAgICAgJ19BdWRpZW5jZScsXG4gICAgICAgIGJvZHkud2hlcmUsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICByZXNwb25zZS5yZXN1bHRzLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgaXRlbS5xdWVyeSA9IEpTT04ucGFyc2UoaXRlbS5xdWVyeSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiByZXNwb25zZSB9O1xuICAgICAgfSk7XG4gIH1cblxuICBoYW5kbGVHZXQocmVxKSB7XG4gICAgcmV0dXJuIHN1cGVyLmhhbmRsZUdldChyZXEpLnRoZW4oZGF0YSA9PiB7XG4gICAgICBkYXRhLnJlc3BvbnNlLnF1ZXJ5ID0gSlNPTi5wYXJzZShkYXRhLnJlc3BvbnNlLnF1ZXJ5KTtcblxuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfSk7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3B1c2hfYXVkaWVuY2VzJywgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZpbmQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL3B1c2hfYXVkaWVuY2VzLzpvYmplY3RJZCcsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlR2V0KHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9wdXNoX2F1ZGllbmNlcycsIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVDcmVhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ1BVVCcsXG4gICAgICAnL3B1c2hfYXVkaWVuY2VzLzpvYmplY3RJZCcsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlVXBkYXRlKHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0RFTEVURScsXG4gICAgICAnL3B1c2hfYXVkaWVuY2VzLzpvYmplY3RJZCcsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRGVsZXRlKHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBBdWRpZW5jZXNSb3V0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/ClassesRouter.js b/lib/Routers/ClassesRouter.js new file mode 100644 index 0000000000..e3b3e93fd2 --- /dev/null +++ b/lib/Routers/ClassesRouter.js @@ -0,0 +1,231 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.ClassesRouter = void 0; + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var _rest = _interopRequireDefault(require("../rest")); + +var _lodash = _interopRequireDefault(require("lodash")); + +var _node = _interopRequireDefault(require("parse/node")); + +var _middlewares = require("../middlewares"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const ALLOWED_GET_QUERY_KEYS = ['keys', 'include', 'excludeKeys', 'readPreference', 'includeReadPreference', 'subqueryReadPreference']; + +class ClassesRouter extends _PromiseRouter.default { + className(req) { + return req.params.className; + } + + handleFind(req) { + const body = Object.assign(req.body, ClassesRouter.JSONFromQuery(req.query)); + const options = ClassesRouter.optionsFromBody(body); + + if (req.config.maxLimit && body.limit > req.config.maxLimit) { + // Silently replace the limit on the query with the max configured + options.limit = Number(req.config.maxLimit); + } + + if (body.redirectClassNameForKey) { + options.redirectClassNameForKey = String(body.redirectClassNameForKey); + } + + if (typeof body.where === 'string') { + body.where = JSON.parse(body.where); + } + + return _rest.default.find(req.config, req.auth, this.className(req), body.where, options, req.info.clientSDK, req.info.context).then(response => { + return { + response: response + }; + }); + } // Returns a promise for a {response} object. + + + handleGet(req) { + const body = Object.assign(req.body, ClassesRouter.JSONFromQuery(req.query)); + const options = {}; + + for (const key of Object.keys(body)) { + if (ALLOWED_GET_QUERY_KEYS.indexOf(key) === -1) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Improper encode of parameter'); + } + } + + if (typeof body.keys === 'string') { + options.keys = body.keys; + } + + if (body.include) { + options.include = String(body.include); + } + + if (typeof body.excludeKeys == 'string') { + options.excludeKeys = body.excludeKeys; + } + + if (typeof body.readPreference === 'string') { + options.readPreference = body.readPreference; + } + + if (typeof body.includeReadPreference === 'string') { + options.includeReadPreference = body.includeReadPreference; + } + + if (typeof body.subqueryReadPreference === 'string') { + options.subqueryReadPreference = body.subqueryReadPreference; + } + + return _rest.default.get(req.config, req.auth, this.className(req), req.params.objectId, options, req.info.clientSDK).then(response => { + if (!response.results || response.results.length == 0) { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } + + if (this.className(req) === '_User') { + delete response.results[0].sessionToken; + const user = response.results[0]; + + if (req.auth.user && user.objectId == req.auth.user.id) { + // Force the session token + response.results[0].sessionToken = req.info.sessionToken; + } + } + + return { + response: response.results[0] + }; + }); + } + + handleCreate(req) { + return _rest.default.create(req.config, req.auth, this.className(req), req.body, req.info.clientSDK, req.info.context); + } + + handleUpdate(req) { + const where = { + objectId: req.params.objectId + }; + return _rest.default.update(req.config, req.auth, this.className(req), where, req.body, req.info.clientSDK, req.info.context); + } + + handleDelete(req) { + return _rest.default.del(req.config, req.auth, this.className(req), req.params.objectId, req.info.context).then(() => { + return { + response: {} + }; + }); + } + + static JSONFromQuery(query) { + const json = {}; + + for (const [key, value] of _lodash.default.entries(query)) { + try { + json[key] = JSON.parse(value); + } catch (e) { + json[key] = value; + } + } + + return json; + } + + static optionsFromBody(body) { + const allowConstraints = ['skip', 'limit', 'order', 'count', 'keys', 'excludeKeys', 'include', 'includeAll', 'redirectClassNameForKey', 'where', 'readPreference', 'includeReadPreference', 'subqueryReadPreference', 'hint', 'explain']; + + for (const key of Object.keys(body)) { + if (allowConstraints.indexOf(key) === -1) { + throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Invalid parameter for query: ${key}`); + } + } + + const options = {}; + + if (body.skip) { + options.skip = Number(body.skip); + } + + if (body.limit || body.limit === 0) { + options.limit = Number(body.limit); + } else { + options.limit = Number(100); + } + + if (body.order) { + options.order = String(body.order); + } + + if (body.count) { + options.count = true; + } + + if (typeof body.keys == 'string') { + options.keys = body.keys; + } + + if (typeof body.excludeKeys == 'string') { + options.excludeKeys = body.excludeKeys; + } + + if (body.include) { + options.include = String(body.include); + } + + if (body.includeAll) { + options.includeAll = true; + } + + if (typeof body.readPreference === 'string') { + options.readPreference = body.readPreference; + } + + if (typeof body.includeReadPreference === 'string') { + options.includeReadPreference = body.includeReadPreference; + } + + if (typeof body.subqueryReadPreference === 'string') { + options.subqueryReadPreference = body.subqueryReadPreference; + } + + if (body.hint && (typeof body.hint === 'string' || typeof body.hint === 'object')) { + options.hint = body.hint; + } + + if (body.explain) { + options.explain = body.explain; + } + + return options; + } + + mountRoutes() { + this.route('GET', '/classes/:className', req => { + return this.handleFind(req); + }); + this.route('GET', '/classes/:className/:objectId', req => { + return this.handleGet(req); + }); + this.route('POST', '/classes/:className', _middlewares.promiseEnsureIdempotency, req => { + return this.handleCreate(req); + }); + this.route('PUT', '/classes/:className/:objectId', _middlewares.promiseEnsureIdempotency, req => { + return this.handleUpdate(req); + }); + this.route('DELETE', '/classes/:className/:objectId', req => { + return this.handleDelete(req); + }); + } + +} + +exports.ClassesRouter = ClassesRouter; +var _default = ClassesRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0NsYXNzZXNSb3V0ZXIuanMiXSwibmFtZXMiOlsiQUxMT1dFRF9HRVRfUVVFUllfS0VZUyIsIkNsYXNzZXNSb3V0ZXIiLCJQcm9taXNlUm91dGVyIiwiY2xhc3NOYW1lIiwicmVxIiwicGFyYW1zIiwiaGFuZGxlRmluZCIsImJvZHkiLCJPYmplY3QiLCJhc3NpZ24iLCJKU09ORnJvbVF1ZXJ5IiwicXVlcnkiLCJvcHRpb25zIiwib3B0aW9uc0Zyb21Cb2R5IiwiY29uZmlnIiwibWF4TGltaXQiLCJsaW1pdCIsIk51bWJlciIsInJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5IiwiU3RyaW5nIiwid2hlcmUiLCJKU09OIiwicGFyc2UiLCJyZXN0IiwiZmluZCIsImF1dGgiLCJpbmZvIiwiY2xpZW50U0RLIiwiY29udGV4dCIsInRoZW4iLCJyZXNwb25zZSIsImhhbmRsZUdldCIsImtleSIsImtleXMiLCJpbmRleE9mIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfUVVFUlkiLCJpbmNsdWRlIiwiZXhjbHVkZUtleXMiLCJyZWFkUHJlZmVyZW5jZSIsImluY2x1ZGVSZWFkUHJlZmVyZW5jZSIsInN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UiLCJnZXQiLCJvYmplY3RJZCIsInJlc3VsdHMiLCJsZW5ndGgiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwic2Vzc2lvblRva2VuIiwidXNlciIsImlkIiwiaGFuZGxlQ3JlYXRlIiwiY3JlYXRlIiwiaGFuZGxlVXBkYXRlIiwidXBkYXRlIiwiaGFuZGxlRGVsZXRlIiwiZGVsIiwianNvbiIsInZhbHVlIiwiXyIsImVudHJpZXMiLCJlIiwiYWxsb3dDb25zdHJhaW50cyIsInNraXAiLCJvcmRlciIsImNvdW50IiwiaW5jbHVkZUFsbCIsImhpbnQiLCJleHBsYWluIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsInByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNB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cG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCB7IHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSB9IGZyb20gJy4uL21pZGRsZXdhcmVzJztcblxuY29uc3QgQUxMT1dFRF9HRVRfUVVFUllfS0VZUyA9IFtcbiAgJ2tleXMnLFxuICAnaW5jbHVkZScsXG4gICdleGNsdWRlS2V5cycsXG4gICdyZWFkUHJlZmVyZW5jZScsXG4gICdpbmNsdWRlUmVhZFByZWZlcmVuY2UnLFxuICAnc3VicXVlcnlSZWFkUHJlZmVyZW5jZScsXG5dO1xuXG5leHBvcnQgY2xhc3MgQ2xhc3Nlc1JvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBjbGFzc05hbWUocmVxKSB7XG4gICAgcmV0dXJuIHJlcS5wYXJhbXMuY2xhc3NOYW1lO1xuICB9XG5cbiAgaGFuZGxlRmluZChyZXEpIHtcbiAgICBjb25zdCBib2R5ID0gT2JqZWN0LmFzc2lnbihyZXEuYm9keSwgQ2xhc3Nlc1JvdXRlci5KU09ORnJvbVF1ZXJ5KHJlcS5xdWVyeSkpO1xuICAgIGNvbnN0IG9wdGlvbnMgPSBDbGFzc2VzUm91dGVyLm9wdGlvbnNGcm9tQm9keShib2R5KTtcbiAgICBpZiAocmVxLmNvbmZpZy5tYXhMaW1pdCAmJiBib2R5LmxpbWl0ID4gcmVxLmNvbmZpZy5tYXhMaW1pdCkge1xuICAgICAgLy8gU2lsZW50bHkgcmVwbGFjZSB0aGUgbGltaXQgb24gdGhlIHF1ZXJ5IHdpdGggdGhlIG1heCBjb25maWd1cmVkXG4gICAgICBvcHRpb25zLmxpbWl0ID0gTnVtYmVyKHJlcS5jb25maWcubWF4TGltaXQpO1xuICAgIH1cbiAgICBpZiAoYm9keS5yZWRpcmVjdENsYXNzTmFtZUZvcktleSkge1xuICAgICAgb3B0aW9ucy5yZWRpcmVjdENsYXNzTmFtZUZvcktleSA9IFN0cmluZyhib2R5LnJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5KTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LndoZXJlID09PSAnc3RyaW5nJykge1xuICAgICAgYm9keS53aGVyZSA9IEpTT04ucGFyc2UoYm9keS53aGVyZSk7XG4gICAgfVxuICAgIHJldHVybiByZXN0XG4gICAgICAuZmluZChcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgcmVxLmF1dGgsXG4gICAgICAgIHRoaXMuY2xhc3NOYW1lKHJlcSksXG4gICAgICAgIGJvZHkud2hlcmUsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICByZXR1cm4geyByZXNwb25zZTogcmVzcG9uc2UgfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGEge3Jlc3BvbnNlfSBvYmplY3QuXG4gIGhhbmRsZUdldChyZXEpIHtcbiAgICBjb25zdCBib2R5ID0gT2JqZWN0LmFzc2lnbihyZXEuYm9keSwgQ2xhc3Nlc1JvdXRlci5KU09ORnJvbVF1ZXJ5KHJlcS5xdWVyeSkpO1xuICAgIGNvbnN0IG9wdGlvbnMgPSB7fTtcblxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGJvZHkpKSB7XG4gICAgICBpZiAoQUxMT1dFRF9HRVRfUVVFUllfS0VZUy5pbmRleE9mKGtleSkgPT09IC0xKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnSW1wcm9wZXIgZW5jb2RlIG9mIHBhcmFtZXRlcicpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgYm9keS5rZXlzID09PSAnc3RyaW5nJykge1xuICAgICAgb3B0aW9ucy5rZXlzID0gYm9keS5rZXlzO1xuICAgIH1cbiAgICBpZiAoYm9keS5pbmNsdWRlKSB7XG4gICAgICBvcHRpb25zLmluY2x1ZGUgPSBTdHJpbmcoYm9keS5pbmNsdWRlKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LmV4Y2x1ZGVLZXlzID09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zLmV4Y2x1ZGVLZXlzID0gYm9keS5leGNsdWRlS2V5cztcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LnJlYWRQcmVmZXJlbmNlID09PSAnc3RyaW5nJykge1xuICAgICAgb3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IGJvZHkucmVhZFByZWZlcmVuY2U7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgYm9keS5pbmNsdWRlUmVhZFByZWZlcmVuY2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zLmluY2x1ZGVSZWFkUHJlZmVyZW5jZSA9IGJvZHkuaW5jbHVkZVJlYWRQcmVmZXJlbmNlO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGJvZHkuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSA9IGJvZHkuc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdFxuICAgICAgLmdldChcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgcmVxLmF1dGgsXG4gICAgICAgIHRoaXMuY2xhc3NOYW1lKHJlcSksXG4gICAgICAgIHJlcS5wYXJhbXMub2JqZWN0SWQsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIHJlcS5pbmZvLmNsaWVudFNES1xuICAgICAgKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICBpZiAoIXJlc3BvbnNlLnJlc3VsdHMgfHwgcmVzcG9uc2UucmVzdWx0cy5sZW5ndGggPT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnT2JqZWN0IG5vdCBmb3VuZC4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmNsYXNzTmFtZShyZXEpID09PSAnX1VzZXInKSB7XG4gICAgICAgICAgZGVsZXRlIHJlc3BvbnNlLnJlc3VsdHNbMF0uc2Vzc2lvblRva2VuO1xuXG4gICAgICAgICAgY29uc3QgdXNlciA9IHJlc3BvbnNlLnJlc3VsdHNbMF07XG5cbiAgICAgICAgICBpZiAocmVxLmF1dGgudXNlciAmJiB1c2VyLm9iamVjdElkID09IHJlcS5hdXRoLnVzZXIuaWQpIHtcbiAgICAgICAgICAgIC8vIEZvcmNlIHRoZSBzZXNzaW9uIHRva2VuXG4gICAgICAgICAgICByZXNwb25zZS5yZXN1bHRzWzBdLnNlc3Npb25Ub2tlbiA9IHJlcS5pbmZvLnNlc3Npb25Ub2tlbjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHJlc3BvbnNlLnJlc3VsdHNbMF0gfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgaGFuZGxlQ3JlYXRlKHJlcSkge1xuICAgIHJldHVybiByZXN0LmNyZWF0ZShcbiAgICAgIHJlcS5jb25maWcsXG4gICAgICByZXEuYXV0aCxcbiAgICAgIHRoaXMuY2xhc3NOYW1lKHJlcSksXG4gICAgICByZXEuYm9keSxcbiAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICApO1xuICB9XG5cbiAgaGFuZGxlVXBkYXRlKHJlcSkge1xuICAgIGNvbnN0IHdoZXJlID0geyBvYmplY3RJZDogcmVxLnBhcmFtcy5vYmplY3RJZCB9O1xuICAgIHJldHVybiByZXN0LnVwZGF0ZShcbiAgICAgIHJlcS5jb25maWcsXG4gICAgICByZXEuYXV0aCxcbiAgICAgIHRoaXMuY2xhc3NOYW1lKHJlcSksXG4gICAgICB3aGVyZSxcbiAgICAgIHJlcS5ib2R5LFxuICAgICAgcmVxLmluZm8uY2xpZW50U0RLLFxuICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICk7XG4gIH1cblxuICBoYW5kbGVEZWxldGUocmVxKSB7XG4gICAgcmV0dXJuIHJlc3RcbiAgICAgIC5kZWwocmVxLmNvbmZpZywgcmVxLmF1dGgsIHRoaXMuY2xhc3NOYW1lKHJlcSksIHJlcS5wYXJhbXMub2JqZWN0SWQsIHJlcS5pbmZvLmNvbnRleHQpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7fSB9O1xuICAgICAgfSk7XG4gIH1cblxuICBzdGF0aWMgSlNPTkZyb21RdWVyeShxdWVyeSkge1xuICAgIGNvbnN0IGpzb24gPSB7fTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBfLmVudHJpZXMocXVlcnkpKSB7XG4gICAgICB0cnkge1xuICAgICAgICBqc29uW2tleV0gPSBKU09OLnBhcnNlKHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAganNvbltrZXldID0gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBqc29uO1xuICB9XG5cbiAgc3RhdGljIG9wdGlvbnNGcm9tQm9keShib2R5KSB7XG4gICAgY29uc3QgYWxsb3dDb25zdHJhaW50cyA9IFtcbiAgICAgICdza2lwJyxcbiAgICAgICdsaW1pdCcsXG4gICAgICAnb3JkZXInLFxuICAgICAgJ2NvdW50JyxcbiAgICAgICdrZXlzJyxcbiAgICAgICdleGNsdWRlS2V5cycsXG4gICAgICAnaW5jbHVkZScsXG4gICAgICAnaW5jbHVkZUFsbCcsXG4gICAgICAncmVkaXJlY3RDbGFzc05hbWVGb3JLZXknLFxuICAgICAgJ3doZXJlJyxcbiAgICAgICdyZWFkUHJlZmVyZW5jZScsXG4gICAgICAnaW5jbHVkZVJlYWRQcmVmZXJlbmNlJyxcbiAgICAgICdzdWJxdWVyeVJlYWRQcmVmZXJlbmNlJyxcbiAgICAgICdoaW50JyxcbiAgICAgICdleHBsYWluJyxcbiAgICBdO1xuXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoYm9keSkpIHtcbiAgICAgIGlmIChhbGxvd0NvbnN0cmFpbnRzLmluZGV4T2Yoa2V5KSA9PT0gLTEpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksIGBJbnZhbGlkIHBhcmFtZXRlciBmb3IgcXVlcnk6ICR7a2V5fWApO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBvcHRpb25zID0ge307XG4gICAgaWYgKGJvZHkuc2tpcCkge1xuICAgICAgb3B0aW9ucy5za2lwID0gTnVtYmVyKGJvZHkuc2tpcCk7XG4gICAgfVxuICAgIGlmIChib2R5LmxpbWl0IHx8IGJvZHkubGltaXQgPT09IDApIHtcbiAgICAgIG9wdGlvbnMubGltaXQgPSBOdW1iZXIoYm9keS5saW1pdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9wdGlvbnMubGltaXQgPSBOdW1iZXIoMTAwKTtcbiAgICB9XG4gICAgaWYgKGJvZHkub3JkZXIpIHtcbiAgICAgIG9wdGlvbnMub3JkZXIgPSBTdHJpbmcoYm9keS5vcmRlcik7XG4gICAgfVxuICAgIGlmIChib2R5LmNvdW50KSB7XG4gICAgICBvcHRpb25zLmNvdW50ID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LmtleXMgPT0gJ3N0cmluZycpIHtcbiAgICAgIG9wdGlvbnMua2V5cyA9IGJvZHkua2V5cztcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LmV4Y2x1ZGVLZXlzID09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zLmV4Y2x1ZGVLZXlzID0gYm9keS5leGNsdWRlS2V5cztcbiAgICB9XG4gICAgaWYgKGJvZHkuaW5jbHVkZSkge1xuICAgICAgb3B0aW9ucy5pbmNsdWRlID0gU3RyaW5nKGJvZHkuaW5jbHVkZSk7XG4gICAgfVxuICAgIGlmIChib2R5LmluY2x1ZGVBbGwpIHtcbiAgICAgIG9wdGlvbnMuaW5jbHVkZUFsbCA9IHRydWU7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgYm9keS5yZWFkUHJlZmVyZW5jZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSBib2R5LnJlYWRQcmVmZXJlbmNlO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGJvZHkuaW5jbHVkZVJlYWRQcmVmZXJlbmNlID09PSAnc3RyaW5nJykge1xuICAgICAgb3B0aW9ucy5pbmNsdWRlUmVhZFByZWZlcmVuY2UgPSBib2R5LmluY2x1ZGVSZWFkUHJlZmVyZW5jZTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UgPSBib2R5LnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U7XG4gICAgfVxuICAgIGlmIChib2R5LmhpbnQgJiYgKHR5cGVvZiBib2R5LmhpbnQgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBib2R5LmhpbnQgPT09ICdvYmplY3QnKSkge1xuICAgICAgb3B0aW9ucy5oaW50ID0gYm9keS5oaW50O1xuICAgIH1cbiAgICBpZiAoYm9keS5leHBsYWluKSB7XG4gICAgICBvcHRpb25zLmV4cGxhaW4gPSBib2R5LmV4cGxhaW47XG4gICAgfVxuICAgIHJldHVybiBvcHRpb25zO1xuICB9XG5cbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9jbGFzc2VzLzpjbGFzc05hbWUnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRmluZChyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvY2xhc3Nlcy86Y2xhc3NOYW1lLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9jbGFzc2VzLzpjbGFzc05hbWUnLCBwcm9taXNlRW5zdXJlSWRlbXBvdGVuY3ksIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVDcmVhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQVVQnLCAnL2NsYXNzZXMvOmNsYXNzTmFtZS86b2JqZWN0SWQnLCBwcm9taXNlRW5zdXJlSWRlbXBvdGVuY3ksIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVVcGRhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdERUxFVEUnLCAnL2NsYXNzZXMvOmNsYXNzTmFtZS86b2JqZWN0SWQnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRGVsZXRlKHJlcSk7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ2xhc3Nlc1JvdXRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/CloudCodeRouter.js b/lib/Routers/CloudCodeRouter.js new file mode 100644 index 0000000000..423ee10a50 --- /dev/null +++ b/lib/Routers/CloudCodeRouter.js @@ -0,0 +1,105 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.CloudCodeRouter = void 0; + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var _node = _interopRequireDefault(require("parse/node")); + +var _rest = _interopRequireDefault(require("../rest")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const triggers = require('../triggers'); + +const middleware = require('../middlewares'); + +function formatJobSchedule(job_schedule) { + if (typeof job_schedule.startAfter === 'undefined') { + job_schedule.startAfter = new Date().toISOString(); + } + + return job_schedule; +} + +function validateJobSchedule(config, job_schedule) { + const jobs = triggers.getJobs(config.applicationId) || {}; + + if (job_schedule.jobName && !jobs[job_schedule.jobName]) { + throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'Cannot Schedule a job that is not deployed'); + } +} + +class CloudCodeRouter extends _PromiseRouter.default { + mountRoutes() { + this.route('GET', '/cloud_code/jobs', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.getJobs); + this.route('GET', '/cloud_code/jobs/data', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.getJobsData); + this.route('POST', '/cloud_code/jobs', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.createJob); + this.route('PUT', '/cloud_code/jobs/:objectId', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.editJob); + this.route('DELETE', '/cloud_code/jobs/:objectId', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.deleteJob); + } + + static getJobs(req) { + return _rest.default.find(req.config, req.auth, '_JobSchedule', {}, {}).then(scheduledJobs => { + return { + response: scheduledJobs.results + }; + }); + } + + static getJobsData(req) { + const config = req.config; + const jobs = triggers.getJobs(config.applicationId) || {}; + return _rest.default.find(req.config, req.auth, '_JobSchedule', {}, {}).then(scheduledJobs => { + return { + response: { + in_use: scheduledJobs.results.map(job => job.jobName), + jobs: Object.keys(jobs) + } + }; + }); + } + + static createJob(req) { + const { + job_schedule + } = req.body; + validateJobSchedule(req.config, job_schedule); + return _rest.default.create(req.config, req.auth, '_JobSchedule', formatJobSchedule(job_schedule), req.client, req.info.context); + } + + static editJob(req) { + const { + objectId + } = req.params; + const { + job_schedule + } = req.body; + validateJobSchedule(req.config, job_schedule); + return _rest.default.update(req.config, req.auth, '_JobSchedule', { + objectId + }, formatJobSchedule(job_schedule), undefined, req.info.context).then(response => { + return { + response + }; + }); + } + + static deleteJob(req) { + const { + objectId + } = req.params; + return _rest.default.del(req.config, req.auth, '_JobSchedule', objectId, req.info.context).then(response => { + return { + response + }; + }); + } + +} + +exports.CloudCodeRouter = CloudCodeRouter; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0Nsb3VkQ29kZVJvdXRlci5qcyJdLCJuYW1lcyI6WyJ0cmlnZ2VycyIsInJlcXVpcmUiLCJtaWRkbGV3YXJlIiwiZm9ybWF0Sm9iU2NoZWR1bGUiLCJqb2Jfc2NoZWR1bGUiLCJzdGFydEFmdGVyIiwiRGF0ZSIsInRvSVNPU3RyaW5nIiwidmFsaWRhdGVKb2JTY2hlZHVsZSIsImNvbmZpZyIsImpvYnMiLCJnZXRKb2JzIiwiYXBwbGljYXRpb25JZCIsImpvYk5hbWUiLCJQYXJzZSIsIkVycm9yIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiQ2xvdWRDb2RlUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsIm1vdW50Um91dGVzIiwicm91dGUiLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyIsImdldEpvYnNEYXRhIiwiY3JlYXRlSm9iIiwiZWRpdEpvYiIsImRlbGV0ZUpvYiIsInJlcSIsInJlc3QiLCJmaW5kIiwiYXV0aCIsInRoZW4iLCJzY2hlZHVsZWRKb2JzIiwicmVzcG9uc2UiLCJyZXN1bHRzIiwiaW5fdXNlIiwibWFwIiwiam9iIiwiT2JqZWN0Iiwia2V5cyIsImJvZHkiLCJjcmVhdGUiLCJjbGllbnQiLCJpbmZvIiwiY29udGV4dCIsIm9iamVjdElkIiwicGFyYW1zIiwidXBkYXRlIiwidW5kZWZpbmVkIiwiZGVsIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7QUFDQSxNQUFNQSxRQUFRLEdBQUdDLE9BQU8sQ0FBQyxhQUFELENBQXhCOztBQUNBLE1BQU1DLFVBQVUsR0FBR0QsT0FBTyxDQUFDLGdCQUFELENBQTFCOztBQUVBLFNBQVNFLGlCQUFULENBQTJCQyxZQUEzQixFQUF5QztBQUN2QyxNQUFJLE9BQU9BLFlBQVksQ0FBQ0MsVUFBcEIsS0FBbUMsV0FBdkMsRUFBb0Q7QUFDbERELElBQUFBLFlBQVksQ0FBQ0MsVUFBYixHQUEwQixJQUFJQyxJQUFKLEdBQVdDLFdBQVgsRUFB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dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IHJlc3QgZnJvbSAnLi4vcmVzdCc7XG5jb25zdCB0cmlnZ2VycyA9IHJlcXVpcmUoJy4uL3RyaWdnZXJzJyk7XG5jb25zdCBtaWRkbGV3YXJlID0gcmVxdWlyZSgnLi4vbWlkZGxld2FyZXMnKTtcblxuZnVuY3Rpb24gZm9ybWF0Sm9iU2NoZWR1bGUoam9iX3NjaGVkdWxlKSB7XG4gIGlmICh0eXBlb2Ygam9iX3NjaGVkdWxlLnN0YXJ0QWZ0ZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgam9iX3NjaGVkdWxlLnN0YXJ0QWZ0ZXIgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gIH1cbiAgcmV0dXJuIGpvYl9zY2hlZHVsZTtcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVKb2JTY2hlZHVsZShjb25maWcsIGpvYl9zY2hlZHVsZSkge1xuICBjb25zdCBqb2JzID0gdHJpZ2dlcnMuZ2V0Sm9icyhjb25maWcuYXBwbGljYXRpb25JZCkgfHwge307XG4gIGlmIChqb2Jfc2NoZWR1bGUuam9iTmFtZSAmJiAham9ic1tqb2Jfc2NoZWR1bGUuam9iTmFtZV0pIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsXG4gICAgICAnQ2Fubm90IFNjaGVkdWxlIGEgam9iIHRoYXQgaXMgbm90IGRlcGxveWVkJ1xuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIENsb3VkQ29kZVJvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2Nsb3VkX2NvZGUvam9icycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgQ2xvdWRDb2RlUm91dGVyLmdldEpvYnNcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnR0VUJyxcbiAgICAgICcvY2xvdWRfY29kZS9qb2JzL2RhdGEnLFxuICAgICAgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyxcbiAgICAgIENsb3VkQ29kZVJvdXRlci5nZXRKb2JzRGF0YVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdQT1NUJyxcbiAgICAgICcvY2xvdWRfY29kZS9qb2JzJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICBDbG91ZENvZGVSb3V0ZXIuY3JlYXRlSm9iXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ1BVVCcsXG4gICAgICAnL2Nsb3VkX2NvZGUvam9icy86b2JqZWN0SWQnLFxuICAgICAgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyxcbiAgICAgIENsb3VkQ29kZVJvdXRlci5lZGl0Sm9iXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0RFTEVURScsXG4gICAgICAnL2Nsb3VkX2NvZGUvam9icy86b2JqZWN0SWQnLFxuICAgICAgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyxcbiAgICAgIENsb3VkQ29kZVJvdXRlci5kZWxldGVKb2JcbiAgICApO1xuICB9XG5cbiAgc3RhdGljIGdldEpvYnMocmVxKSB7XG4gICAgcmV0dXJuIHJlc3QuZmluZChyZXEuY29uZmlnLCByZXEuYXV0aCwgJ19Kb2JTY2hlZHVsZScsIHt9LCB7fSkudGhlbihzY2hlZHVsZWRKb2JzID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJlc3BvbnNlOiBzY2hlZHVsZWRKb2JzLnJlc3VsdHMsXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGdldEpvYnNEYXRhKHJlcSkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHJlcS5jb25maWc7XG4gICAgY29uc3Qgam9icyA9IHRyaWdnZXJzLmdldEpvYnMoY29uZmlnLmFwcGxpY2F0aW9uSWQpIHx8IHt9O1xuICAgIHJldHVybiByZXN0LmZpbmQocmVxLmNvbmZpZywgcmVxLmF1dGgsICdfSm9iU2NoZWR1bGUnLCB7fSwge30pLnRoZW4oc2NoZWR1bGVkSm9icyA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgIGluX3VzZTogc2NoZWR1bGVkSm9icy5yZXN1bHRzLm1hcChqb2IgPT4gam9iLmpvYk5hbWUpLFxuICAgICAgICAgIGpvYnM6IE9iamVjdC5rZXlzKGpvYnMpLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVKb2IocmVxKSB7XG4gICAgY29uc3QgeyBqb2Jfc2NoZWR1bGUgfSA9IHJlcS5ib2R5O1xuICAgIHZhbGlkYXRlSm9iU2NoZWR1bGUocmVxLmNvbmZpZywgam9iX3NjaGVkdWxlKTtcbiAgICByZXR1cm4gcmVzdC5jcmVhdGUoXG4gICAgICByZXEuY29uZmlnLFxuICAgICAgcmVxLmF1dGgsXG4gICAgICAnX0pvYlNjaGVkdWxlJyxcbiAgICAgIGZvcm1hdEpvYlNjaGVkdWxlKGpvYl9zY2hlZHVsZSksXG4gICAgICByZXEuY2xpZW50LFxuICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICk7XG4gIH1cblxuICBzdGF0aWMgZWRpdEpvYihyZXEpIHtcbiAgICBjb25zdCB7IG9iamVjdElkIH0gPSByZXEucGFyYW1zO1xuICAgIGNvbnN0IHsgam9iX3NjaGVkdWxlIH0gPSByZXEuYm9keTtcbiAgICB2YWxpZGF0ZUpvYlNjaGVkdWxlKHJlcS5jb25maWcsIGpvYl9zY2hlZHVsZSk7XG4gICAgcmV0dXJuIHJlc3RcbiAgICAgIC51cGRhdGUoXG4gICAgICAgIHJlcS5jb25maWcsXG4gICAgICAgIHJlcS5hdXRoLFxuICAgICAgICAnX0pvYlNjaGVkdWxlJyxcbiAgICAgICAgeyBvYmplY3RJZCB9LFxuICAgICAgICBmb3JtYXRKb2JTY2hlZHVsZShqb2Jfc2NoZWR1bGUpLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICByZXNwb25zZSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGRlbGV0ZUpvYihyZXEpIHtcbiAgICBjb25zdCB7IG9iamVjdElkIH0gPSByZXEucGFyYW1zO1xuICAgIHJldHVybiByZXN0XG4gICAgICAuZGVsKHJlcS5jb25maWcsIHJlcS5hdXRoLCAnX0pvYlNjaGVkdWxlJywgb2JqZWN0SWQsIHJlcS5pbmZvLmNvbnRleHQpXG4gICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcmVzcG9uc2UsXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgfVxufVxuIl19 \ No newline at end of file diff --git a/lib/Routers/FeaturesRouter.js b/lib/Routers/FeaturesRouter.js new file mode 100644 index 0000000000..51c3c26849 --- /dev/null +++ b/lib/Routers/FeaturesRouter.js @@ -0,0 +1,79 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.FeaturesRouter = void 0; + +var _package = require("../../package.json"); + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class FeaturesRouter extends _PromiseRouter.default { + mountRoutes() { + this.route('GET', '/serverInfo', middleware.promiseEnforceMasterKeyAccess, req => { + const { + config + } = req; + const features = { + globalConfig: { + create: true, + read: true, + update: true, + delete: true + }, + hooks: { + create: true, + read: true, + update: true, + delete: true + }, + cloudCode: { + jobs: true + }, + logs: { + level: true, + size: true, + order: true, + until: true, + from: true + }, + push: { + immediatePush: config.hasPushSupport, + scheduledPush: config.hasPushScheduledSupport, + storedPushData: config.hasPushSupport, + pushAudiences: true, + localization: true + }, + schemas: { + addField: true, + removeField: true, + addClass: true, + removeClass: true, + clearAllDataFromClass: true, + exportClass: false, + editClassLevelPermissions: true, + editPointerPermissions: true + } + }; + return { + response: { + features: features, + parseServerVersion: _package.version + } + }; + }); + } + +} + +exports.FeaturesRouter = FeaturesRouter; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0ZlYXR1cmVzUm91dGVyLmpzIl0sIm5hbWVzIjpbIkZlYXR1cmVzUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsIm1vdW50Um91dGVzIiwicm91dGUiLCJtaWRkbGV3YXJlIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiLCJyZXEiLCJjb25maWciLCJmZWF0dXJlcyIsImdsb2JhbENvbmZpZyIsImNyZWF0ZSIsInJlYWQiLCJ1cGRhdGUiLCJkZWxldGUiLCJob29rcyIsImNsb3VkQ29kZSIsImpvYnMiLCJsb2dzIiwibGV2ZWwiLCJzaXplIiwib3JkZXIiLCJ1bnRpbCIsImZyb20iLCJwdXNoIiwiaW1tZWRpYXRlUHVzaCIsImhhc1B1c2hTdXBwb3J0Iiwic2NoZWR1bGVkUHVzaCIsImhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0Iiwic3RvcmVkUHVzaERhdGEiLCJwdXNoQXVkaWVuY2VzIiwibG9jYWxpemF0aW9uIiwic2NoZW1hcyIsImFkZEZpZWxkIiwicmVtb3ZlRmllbGQiLCJhZGRDbGFzcyIsInJlbW92ZUNsYXNzIiwiY2xlYXJBbGxEYXRhRnJvbUNsYXNzIiwiZXhwb3J0Q2xhc3MiLCJlZGl0Q2xhc3NMZXZlbFBlcm1pc3Npb25zIiwiZWRpdFBvaW50ZXJQZXJtaXNzaW9ucyIsInJlc3BvbnNlIiwicGFyc2VTZXJ2ZXJWZXJzaW9uIiwidmVyc2lvbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVPLE1BQU1BLGNBQU4sU0FBNkJDLHNCQUE3QixDQUEyQztBQUNoREMsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxDQUFXLEtBQVgsRUFBa0IsYUFBbEIsRUFBaUNDLFVBQVUsQ0FBQ0MsNkJBQTVDLEVBQTJFQyxHQUFHLElBQUk7QUFDaEYsWUFBTTtBQUFFQyxRQUFBQTtBQUFGLFVBQWFELEdBQW5CO0FBQ0EsWUFBTUUsUUFBUSxHQUFHO0FBQ2ZDLFFBQUFBLFlBQVksRUFBRTtBQUNaQyxVQUFBQSxNQUFNLEVBQUUsSUFESTtBQUVaQyxVQUFBQSxJQUFJLEVBQUUsSUFGTTtBQUdaQyxVQUFBQSxNQUFNLEVBQUUsSUFISTtBQUlaQyxVQUFBQSxNQUFNLEVBQUU7QUFKSSxTQURDO0FBT2ZDLFFBQUFBLEtBQUssRUFBRTtBQUNMSixVQUFBQSxNQUFNLEVBQUUsSUFESDtBQUVMQyxVQUFBQSxJQUFJLEVBQUUsSUFGRDtBQUdMQyxVQUFBQSxNQUFNLEVBQUUsSUFISDtBQUlMQyxVQUFBQSxNQUFNLEVBQUU7QUFKSCxTQVBRO0FBYWZFLFFBQUFBLFNBQVMsRUFBRTtBQUNUQyxVQUFBQSxJQUFJLEVBQUU7QUFERyxTQWJJO0FBZ0JmQyxRQUFBQSxJQUFJLEVBQUU7QUFDSkMsVUFBQUEsS0FBSyxFQUFFLElBREg7QUFFSkMsVUFBQUEsSUFBSSxFQUFFLElBRkY7QUFHSkMsVUFBQUEsS0FBSyxFQUFFLElBSEg7QUFJSkMsVUFBQUEsS0FBSyxFQUFFLElBSkg7QUFLSkMsVUFBQUEsSUFBSSxFQUFFO0FBTEYsU0FoQlM7QUF1QmZDLFFBQUFBLElBQUksRUFBRTtBQUNKQyxVQUFBQSxhQUFhLEVBQUVqQixNQUFNLENBQUNrQixjQURsQjtBQUVKQyxVQUFBQSxhQUFhLEVBQUVuQixNQUFNLENBQUNvQix1QkFGbEI7QUFHSkMsVUFBQUEsY0FBYyxFQUFFckIsTUFBTSxDQUFDa0IsY0FIbkI7QUFJSkksVUFBQUEsYUFBYSxFQUFFLElBSlg7QUFLSkMsVUFBQUEsWUFBWSxFQUFFO0FBTFYsU0F2QlM7QUE4QmZDLFFBQUFBLE9BQU8sRUFBRTtBQUNQQyxVQUFBQSxRQUFRLEVBQUUsSUFESDtBQUVQQyxVQUFBQSxXQUFXLEVBQUUsSUFGTjtBQUdQQyxVQUFBQSxRQUFRLEVBQUUsSUFISDtBQUlQQyxVQUFBQSxXQUFXLEVBQUUsSUFKTjtBQUtQQyxVQUFBQSxxQkFBcUIsRUFBRSxJQUxoQjtBQU1QQyxVQUFBQSxXQUFXLEVBQUUsS0FOTjtBQU9QQyxVQUFBQSx5QkFBeUIsRUFBRSxJQVBwQjtBQVFQQyxVQUFBQSxzQkFBc0IsRUFBRTtBQVJqQjtBQTlCTSxPQUFqQjtBQTBDQSxhQUFPO0FBQ0xDLFFBQUFBLFFBQVEsRUFBRTtBQUNSaEMsVUFBQUEsUUFBUSxFQUFFQSxRQURGO0FBRVJpQyxVQUFBQSxrQkFBa0IsRUFBRUM7QUFGWjtBQURMLE9BQVA7QUFNRCxLQWxERDtBQW1ERDs7QUFyRCtDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgdmVyc2lvbiB9IGZyb20gJy4uLy4uL3BhY2thZ2UuanNvbic7XG5pbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuLi9Qcm9taXNlUm91dGVyJztcbmltcG9ydCAqIGFzIG1pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5leHBvcnQgY2xhc3MgRmVhdHVyZXNSb3V0ZXIgZXh0ZW5kcyBQcm9taXNlUm91dGVyIHtcbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9zZXJ2ZXJJbmZvJywgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcywgcmVxID0+IHtcbiAgICAgIGNvbnN0IHsgY29uZmlnIH0gPSByZXE7XG4gICAgICBjb25zdCBmZWF0dXJlcyA9IHtcbiAgICAgICAgZ2xvYmFsQ29uZmlnOiB7XG4gICAgICAgICAgY3JlYXRlOiB0cnVlLFxuICAgICAgICAgIHJlYWQ6IHRydWUsXG4gICAgICAgICAgdXBkYXRlOiB0cnVlLFxuICAgICAgICAgIGRlbGV0ZTogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAgaG9va3M6IHtcbiAgICAgICAgICBjcmVhdGU6IHRydWUsXG4gICAgICAgICAgcmVhZDogdHJ1ZSxcbiAgICAgICAgICB1cGRhdGU6IHRydWUsXG4gICAgICAgICAgZGVsZXRlOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBjbG91ZENvZGU6IHtcbiAgICAgICAgICBqb2JzOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBsb2dzOiB7XG4gICAgICAgICAgbGV2ZWw6IHRydWUsXG4gICAgICAgICAgc2l6ZTogdHJ1ZSxcbiAgICAgICAgICBvcmRlcjogdHJ1ZSxcbiAgICAgICAgICB1bnRpbDogdHJ1ZSxcbiAgICAgICAgICBmcm9tOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBwdXNoOiB7XG4gICAgICAgICAgaW1tZWRpYXRlUHVzaDogY29uZmlnLmhhc1B1c2hTdXBwb3J0LFxuICAgICAgICAgIHNjaGVkdWxlZFB1c2g6IGNvbmZpZy5oYXNQdXNoU2NoZWR1bGVkU3VwcG9ydCxcbiAgICAgICAgICBzdG9yZWRQdXNoRGF0YTogY29uZmlnLmhhc1B1c2hTdXBwb3J0LFxuICAgICAgICAgIHB1c2hBdWRpZW5jZXM6IHRydWUsXG4gICAgICAgICAgbG9jYWxpemF0aW9uOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBzY2hlbWFzOiB7XG4gICAgICAgICAgYWRkRmllbGQ6IHRydWUsXG4gICAgICAgICAgcmVtb3ZlRmllbGQ6IHRydWUsXG4gICAgICAgICAgYWRkQ2xhc3M6IHRydWUsXG4gICAgICAgICAgcmVtb3ZlQ2xhc3M6IHRydWUsXG4gICAgICAgICAgY2xlYXJBbGxEYXRhRnJvbUNsYXNzOiB0cnVlLFxuICAgICAgICAgIGV4cG9ydENsYXNzOiBmYWxzZSxcbiAgICAgICAgICBlZGl0Q2xhc3NMZXZlbFBlcm1pc3Npb25zOiB0cnVlLFxuICAgICAgICAgIGVkaXRQb2ludGVyUGVybWlzc2lvbnM6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgIGZlYXR1cmVzOiBmZWF0dXJlcyxcbiAgICAgICAgICBwYXJzZVNlcnZlclZlcnNpb246IHZlcnNpb24sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/FilesRouter.js b/lib/Routers/FilesRouter.js new file mode 100644 index 0000000000..009dc3db69 --- /dev/null +++ b/lib/Routers/FilesRouter.js @@ -0,0 +1,280 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.FilesRouter = void 0; + +var _express = _interopRequireDefault(require("express")); + +var _bodyParser = _interopRequireDefault(require("body-parser")); + +var Middlewares = _interopRequireWildcard(require("../middlewares")); + +var _node = _interopRequireDefault(require("parse/node")); + +var _Config = _interopRequireDefault(require("../Config")); + +var _mime = _interopRequireDefault(require("mime")); + +var _logger = _interopRequireDefault(require("../logger")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const triggers = require('../triggers'); + +const http = require('http'); + +const downloadFileFromURI = uri => { + return new Promise((res, rej) => { + http.get(uri, response => { + response.setDefaultEncoding('base64'); + let body = `data:${response.headers['content-type']};base64,`; + response.on('data', data => body += data); + response.on('end', () => res(body)); + }).on('error', e => { + rej(`Error downloading file from ${uri}: ${e.message}`); + }); + }); +}; + +const addFileDataIfNeeded = async file => { + if (file._source.format === 'uri') { + const base64 = await downloadFileFromURI(file._source.uri); + file._previousSave = file; + file._data = base64; + file._requestTask = null; + } + + return file; +}; + +class FilesRouter { + expressRouter({ + maxUploadSize = '20Mb' + } = {}) { + var router = _express.default.Router(); + + router.get('/files/:appId/:filename', this.getHandler); + router.get('/files/:appId/metadata/:filename', this.metadataHandler); + router.post('/files', function (req, res, next) { + next(new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename not provided.')); + }); + router.post('/files/:filename', _bodyParser.default.raw({ + type: () => { + return true; + }, + limit: maxUploadSize + }), // Allow uploads without Content-Type, or with any Content-Type. + Middlewares.handleParseHeaders, this.createHandler); + router.delete('/files/:filename', Middlewares.handleParseHeaders, Middlewares.enforceMasterKeyAccess, this.deleteHandler); + return router; + } + + getHandler(req, res) { + const config = _Config.default.get(req.params.appId); + + const filesController = config.filesController; + const filename = req.params.filename; + + const contentType = _mime.default.getType(filename); + + if (isFileStreamable(req, filesController)) { + filesController.handleFileStream(config, filename, req, res, contentType).catch(() => { + res.status(404); + res.set('Content-Type', 'text/plain'); + res.end('File not found.'); + }); + } else { + filesController.getFileData(config, filename).then(data => { + res.status(200); + res.set('Content-Type', contentType); + res.set('Content-Length', data.length); + res.end(data); + }).catch(() => { + res.status(404); + res.set('Content-Type', 'text/plain'); + res.end('File not found.'); + }); + } + } + + async createHandler(req, res, next) { + const config = req.config; + const user = req.auth.user; + const isMaster = req.auth.isMaster; + + const isLinked = user && _node.default.AnonymousUtils.isLinked(user); + + if (!isMaster && !config.fileUpload.enableForAnonymousUser && isLinked) { + next(new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, 'File upload by anonymous user is disabled.')); + return; + } + + if (!isMaster && !config.fileUpload.enableForAuthenticatedUser && !isLinked && user) { + next(new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, 'File upload by authenticated user is disabled.')); + return; + } + + if (!isMaster && !config.fileUpload.enableForPublic && !user) { + next(new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, 'File upload by public is disabled.')); + return; + } + + const filesController = config.filesController; + const { + filename + } = req.params; + const contentType = req.get('Content-type'); + + if (!req.body || !req.body.length) { + next(new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, 'Invalid file upload.')); + return; + } + + const error = filesController.validateFilename(filename); + + if (error) { + next(error); + return; + } + + const base64 = req.body.toString('base64'); + const file = new _node.default.File(filename, { + base64 + }, contentType); + const { + metadata = {}, + tags = {} + } = req.fileData || {}; + file.setTags(tags); + file.setMetadata(metadata); + const fileSize = Buffer.byteLength(req.body); + const fileObject = { + file, + fileSize + }; + + try { + // run beforeSaveFile trigger + const triggerResult = await triggers.maybeRunFileTrigger(triggers.Types.beforeSaveFile, fileObject, config, req.auth); + let saveResult; // if a new ParseFile is returned check if it's an already saved file + + if (triggerResult instanceof _node.default.File) { + fileObject.file = triggerResult; + + if (triggerResult.url()) { + // set fileSize to null because we wont know how big it is here + fileObject.fileSize = null; + saveResult = { + url: triggerResult.url(), + name: triggerResult._name + }; + } + } // if the file returned by the trigger has already been saved skip saving anything + + + if (!saveResult) { + // if the ParseFile returned is type uri, download the file before saving it + await addFileDataIfNeeded(fileObject.file); // update fileSize + + const bufferData = Buffer.from(fileObject.file._data, 'base64'); + fileObject.fileSize = Buffer.byteLength(bufferData); // save file + + const createFileResult = await filesController.createFile(config, fileObject.file._name, bufferData, fileObject.file._source.type, { + tags: fileObject.file._tags, + metadata: fileObject.file._metadata + }); // update file with new data + + fileObject.file._name = createFileResult.name; + fileObject.file._url = createFileResult.url; + fileObject.file._requestTask = null; + fileObject.file._previousSave = Promise.resolve(fileObject.file); + saveResult = { + url: createFileResult.url, + name: createFileResult.name + }; + } // run afterSaveFile trigger + + + await triggers.maybeRunFileTrigger(triggers.Types.afterSaveFile, fileObject, config, req.auth); + res.status(201); + res.set('Location', saveResult.url); + res.json(saveResult); + } catch (e) { + _logger.default.error('Error creating a file: ', e); + + const error = triggers.resolveError(e, { + code: _node.default.Error.FILE_SAVE_ERROR, + message: `Could not store file: ${fileObject.file._name}.` + }); + next(error); + } + } + + async deleteHandler(req, res, next) { + try { + const { + filesController + } = req.config; + const { + filename + } = req.params; // run beforeDeleteFile trigger + + const file = new _node.default.File(filename); + file._url = filesController.adapter.getFileLocation(req.config, filename); + const fileObject = { + file, + fileSize: null + }; + await triggers.maybeRunFileTrigger(triggers.Types.beforeDeleteFile, fileObject, req.config, req.auth); // delete file + + await filesController.deleteFile(req.config, filename); // run afterDeleteFile trigger + + await triggers.maybeRunFileTrigger(triggers.Types.afterDeleteFile, fileObject, req.config, req.auth); + res.status(200); // TODO: return useful JSON here? + + res.end(); + } catch (e) { + _logger.default.error('Error deleting a file: ', e); + + const error = triggers.resolveError(e, { + code: _node.default.Error.FILE_DELETE_ERROR, + message: 'Could not delete file.' + }); + next(error); + } + } + + async metadataHandler(req, res) { + const config = _Config.default.get(req.params.appId); + + const { + filesController + } = config; + const { + filename + } = req.params; + + try { + const data = await filesController.getMetadata(filename); + res.status(200); + res.json(data); + } catch (e) { + res.status(200); + res.json({}); + } + } + +} + +exports.FilesRouter = FilesRouter; + +function isFileStreamable(req, filesController) { + return req.get('Range') && typeof filesController.adapter.handleFileStream === 'function'; +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0ZpbGVzUm91dGVyLmpzIl0sIm5hbWVzIjpbInRyaWdnZXJzIiwicmVxdWlyZSIsImh0dHAiLCJkb3dubG9hZEZpbGVGcm9tVVJJIiwidXJpIiwiUHJvbWlzZSIsInJlcyIsInJlaiIsImdldCIsInJlc3BvbnNlIiwic2V0RGVmYXVsdEVuY29kaW5nIiwiYm9keSIsImhlYWRlcnMiLCJvbiIsImRhdGEiLCJlIiwibWVzc2FnZSIsImFkZEZpbGVEYXRhSWZOZWVkZWQiLCJmaWxlIiwiX3NvdXJjZSIsImZvcm1hdCIsImJhc2U2NCIsIl9wcmV2aW91c1NhdmUiLCJfZGF0YSIsIl9yZXF1ZXN0VGFzayIsIkZpbGVzUm91dGVyIiwiZXhwcmVzc1JvdXRlciIsIm1heFVwbG9hZFNpemUiLCJyb3V0ZXIiLCJleHByZXNzIiwiUm91dGVyIiwiZ2V0SGFuZGxlciIsIm1ldGFkYXRhSGFuZGxlciIsInBvc3QiLCJyZXEiLCJuZXh0IiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfRklMRV9OQU1FIiwiQm9keVBhcnNlciIsInJhdyIsInR5cGUiLCJsaW1pdCIsIk1pZGRsZXdhcmVzIiwiaGFuZGxlUGFyc2VIZWFkZXJzIiwiY3JlYXRlSGFuZGxlciIsImRlbGV0ZSIsImVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiLCJkZWxldGVIYW5kbGVyIiwiY29uZmlnIiwiQ29uZmlnIiwicGFyYW1zIiwiYXBwSWQiLCJmaWxlc0NvbnRyb2xsZXIiLCJmaWxlbmFtZSIsImNvbnRlbnRUeXBlIiwibWltZSIsImdldFR5cGUiLCJpc0ZpbGVTdHJlYW1hYmxlIiwiaGFuZGxlRmlsZVN0cmVhbSIsImNhdGNoIiwic3RhdHVzIiwic2V0IiwiZW5kIiwiZ2V0RmlsZURhdGEiLCJ0aGVuIiwibGVuZ3RoIiwidXNlciIsImF1dGgiLCJpc01hc3RlciIsImlzTGlua2VkIiwiQW5vbnltb3VzVXRpbHMiLCJmaWxlVXBsb2FkIiwiZW5hYmxlRm9yQW5vbnltb3VzVXNlciIsIkZJTEVfU0FWRV9FUlJPUiIsImVuYWJsZUZvckF1dGhlbnRpY2F0ZWRVc2VyIiwiZW5hYmxlRm9yUHVibGljIiwiZXJyb3IiLCJ2YWxpZGF0ZUZpbGVuYW1lIiwidG9TdHJpbmciLCJGaWxlIiwibWV0YWRhdGEiLCJ0YWdzIiwiZmlsZURhdGEiLCJzZXRUYWdzIiwic2V0TWV0YWRhdGEiLCJmaWxlU2l6ZSIsIkJ1ZmZlciIsImJ5dGVMZW5ndGgiLCJmaWxlT2JqZWN0IiwidHJpZ2dlclJlc3VsdCIsIm1heWJlUnVuRmlsZVRyaWdnZXIiLCJUeXBlcyIsImJlZm9yZVNhdmVGaWxlIiwic2F2ZVJlc3VsdCIsInVybCIsIm5hbWUiLCJfbmFtZSIsImJ1ZmZlckRhdGEiLCJmcm9tIiwiY3JlYXRlRmlsZVJlc3VsdCIsImNyZWF0ZUZpbGUiLCJfdGFncyIsIl9tZXRhZGF0YSIsIl91cmwiLCJyZXNvbHZlIiwiYWZ0ZXJTYXZlRmlsZSIsImpzb24iLCJsb2dnZXIiLCJyZXNvbHZlRXJyb3IiLCJjb2RlIiwiYWRhcHRlciIsImdldEZpbGVMb2NhdGlvbiIsImJlZm9yZURlbGV0ZUZpbGUiLCJkZWxldGVGaWxlIiwiYWZ0ZXJEZWxldGVGaWxlIiwiRklMRV9ERUxFVEVfRVJST1IiLCJnZXRNZXRhZGF0YSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7OztBQUNBLE1BQU1BLFFBQVEsR0FBR0MsT0FBTyxDQUFDLGFBQUQsQ0FBeEI7O0FBQ0EsTUFBTUMsSUFBSSxHQUFHRCxPQUFPLENBQUMsTUFBRCxDQUFwQjs7QUFFQSxNQUFNRSxtQkFBbUIsR0FBR0MsR0FBRyxJQUFJO0FBQ2pDLFNBQU8sSUFBSUMsT0FBSixDQUFZLENBQUNDLEdBQUQsRUFBTUMsR0FBTixLQUFjO0FBQy9CTCxJQUFBQSxJQUFJLENBQ0RNLEdBREgsQ0FDT0osR0FEUCxFQUNZSyxRQUFRLElBQUk7QUFDcEJBLE1BQUFBLFFBQVEsQ0FBQ0Msa0JBQVQsQ0FBNEIs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Z0JBQVQsQ0FBMEJ4QixHQUExQixFQUErQm1CLGVBQS9CLEVBQWdEO0FBQzlDLFNBQU9uQixHQUFHLENBQUMxQixHQUFKLENBQVEsT0FBUixLQUFvQixPQUFPNkMsZUFBZSxDQUFDMEQsT0FBaEIsQ0FBd0JwRCxnQkFBL0IsS0FBb0QsVUFBL0U7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBleHByZXNzIGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IEJvZHlQYXJzZXIgZnJvbSAnYm9keS1wYXJzZXInO1xuaW1wb3J0ICogYXMgTWlkZGxld2FyZXMgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuLi9Db25maWcnO1xuaW1wb3J0IG1pbWUgZnJvbSAnbWltZSc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5jb25zdCB0cmlnZ2VycyA9IHJlcXVpcmUoJy4uL3RyaWdnZXJzJyk7XG5jb25zdCBodHRwID0gcmVxdWlyZSgnaHR0cCcpO1xuXG5jb25zdCBkb3dubG9hZEZpbGVGcm9tVVJJID0gdXJpID0+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXMsIHJlaikgPT4ge1xuICAgIGh0dHBcbiAgICAgIC5nZXQodXJpLCByZXNwb25zZSA9PiB7XG4gICAgICAgIHJlc3BvbnNlLnNldERlZmF1bHRFbmNvZGluZygnYmFzZTY0Jyk7XG4gICAgICAgIGxldCBib2R5ID0gYGRhdGE6JHtyZXNwb25zZS5oZWFkZXJzWydjb250ZW50LXR5cGUnXX07YmFzZTY0LGA7XG4gICAgICAgIHJlc3BvbnNlLm9uKCdkYXRhJywgZGF0YSA9PiAoYm9keSArPSBkYXRhKSk7XG4gICAgICAgIHJlc3BvbnNlLm9uKCdlbmQnLCAoKSA9PiByZXMoYm9keSkpO1xuICAgICAgfSlcbiAgICAgIC5vbignZXJyb3InLCBlID0+IHtcbiAgICAgICAgcmVqKGBFcnJvciBkb3dubG9hZGluZyBmaWxlIGZyb20gJHt1cml9OiAke2UubWVzc2FnZX1gKTtcbiAgICAgIH0pO1xuICB9KTtcbn07XG5cbmNvbnN0IGFkZEZpbGVEYXRhSWZOZWVkZWQgPSBhc3luYyBmaWxlID0+IHtcbiAgaWYgKGZpbGUuX3NvdXJjZS5mb3JtYXQgPT09ICd1cmknKSB7XG4gICAgY29uc3QgYmFzZTY0ID0gYXdhaXQgZG93bmxvYWRGaWxlRnJvbVVSSShmaWxlLl9zb3VyY2UudXJpKTtcbiAgICBmaWxlLl9wcmV2aW91c1NhdmUgPSBmaWxlO1xuICAgIGZpbGUuX2RhdGEgPSBiYXNlNjQ7XG4gICAgZmlsZS5fcmVxdWVzdFRhc2sgPSBudWxsO1xuICB9XG4gIHJldHVybiBmaWxlO1xufTtcblxuZXhwb3J0IGNsYXNzIEZpbGVzUm91dGVyIHtcbiAgZXhwcmVzc1JvdXRlcih7IG1heFVwbG9hZFNpemUgPSAnMjBNYicgfSA9IHt9KSB7XG4gICAgdmFyIHJvdXRlciA9IGV4cHJlc3MuUm91dGVyKCk7XG4gICAgcm91dGVyLmdldCgnL2ZpbGVzLzphcHBJZC86ZmlsZW5hbWUnLCB0aGlzLmdldEhhbmRsZXIpO1xuICAgIHJvdXRlci5nZXQoJy9maWxlcy86YXBwSWQvbWV0YWRhdGEvOmZpbGVuYW1lJywgdGhpcy5tZXRhZGF0YUhhbmRsZXIpO1xuXG4gICAgcm91dGVyLnBvc3QoJy9maWxlcycsIGZ1bmN0aW9uIChyZXEsIHJlcywgbmV4dCkge1xuICAgICAgbmV4dChuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9GSUxFX05BTUUsICdGaWxlbmFtZSBub3QgcHJvdmlkZWQuJykpO1xuICAgIH0pO1xuXG4gICAgcm91dGVyLnBvc3QoXG4gICAgICAnL2ZpbGVzLzpmaWxlbmFtZScsXG4gICAgICBCb2R5UGFyc2VyLnJhdyh7XG4gICAgICAgIHR5cGU6ICgpID0+IHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSxcbiAgICAgICAgbGltaXQ6IG1heFVwbG9hZFNpemUsXG4gICAgICB9KSwgLy8gQWxsb3cgdXBsb2FkcyB3aXRob3V0IENvbnRlbnQtVHlwZSwgb3Igd2l0aCBhbnkgQ29udGVudC1UeXBlLlxuICAgICAgTWlkZGxld2FyZXMuaGFuZGxlUGFyc2VIZWFkZXJzLFxuICAgICAgdGhpcy5jcmVhdGVIYW5kbGVyXG4gICAgKTtcblxuICAgIHJvdXRlci5kZWxldGUoXG4gICAgICAnL2ZpbGVzLzpmaWxlbmFtZScsXG4gICAgICBNaWRkbGV3YXJlcy5oYW5kbGVQYXJzZUhlYWRlcnMsXG4gICAgICBNaWRkbGV3YXJlcy5lbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5kZWxldGVIYW5kbGVyXG4gICAgKTtcbiAgICByZXR1cm4gcm91dGVyO1xuICB9XG5cbiAgZ2V0SGFuZGxlcihyZXEsIHJlcykge1xuICAgIGNvbnN0IGNvbmZpZyA9IENvbmZpZy5nZXQocmVxLnBhcmFtcy5hcHBJZCk7XG4gICAgY29uc3QgZmlsZXNDb250cm9sbGVyID0gY29uZmlnLmZpbGVzQ29udHJvbGxlcjtcbiAgICBjb25zdCBmaWxlbmFtZSA9IHJlcS5wYXJhbXMuZmlsZW5hbWU7XG4gICAgY29uc3QgY29udGVudFR5cGUgPSBtaW1lLmdldFR5cGUoZmlsZW5hbWUpO1xuICAgIGlmIChpc0ZpbGVTdHJlYW1hYmxlKHJlcSwgZmlsZXNDb250cm9sbGVyKSkge1xuICAgICAgZmlsZXNDb250cm9sbGVyLmhhbmRsZUZpbGVTdHJlYW0oY29uZmlnLCBmaWxlbmFtZSwgcmVxLCByZXMsIGNvbnRlbnRUeXBlKS5jYXRjaCgoKSA9PiB7XG4gICAgICAgIHJlcy5zdGF0dXMoNDA0KTtcbiAgICAgICAgcmVzLnNldCgnQ29udGVudC1UeXBlJywgJ3RleHQvcGxhaW4nKTtcbiAgICAgICAgcmVzLmVuZCgnRmlsZSBub3QgZm91bmQuJyk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZmlsZXNDb250cm9sbGVyXG4gICAgICAgIC5nZXRGaWxlRGF0YShjb25maWcsIGZpbGVuYW1lKVxuICAgICAgICAudGhlbihkYXRhID0+IHtcbiAgICAgICAgICByZXMuc3RhdHVzKDIwMCk7XG4gICAgICAgICAgcmVzLnNldCgnQ29udGVudC1UeXBlJywgY29udGVudFR5cGUpO1xuICAgICAgICAgIHJlcy5zZXQoJ0NvbnRlbnQtTGVuZ3RoJywgZGF0YS5sZW5ndGgpO1xuICAgICAgICAgIHJlcy5lbmQoZGF0YSk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgcmVzLnN0YXR1cyg0MDQpO1xuICAgICAgICAgIHJlcy5zZXQoJ0NvbnRlbnQtVHlwZScsICd0ZXh0L3BsYWluJyk7XG4gICAgICAgICAgcmVzLmVuZCgnRmlsZSBub3QgZm91bmQuJyk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZUhhbmRsZXIocmVxLCByZXMsIG5leHQpIHtcbiAgICBjb25zdCBjb25maWcgPSByZXEuY29uZmlnO1xuICAgIGNvbnN0IHVzZXIgPSByZXEuYXV0aC51c2VyO1xuICAgIGNvbnN0IGlzTWFzdGVyID0gcmVxLmF1dGguaXNNYXN0ZXI7XG4gICAgY29uc3QgaXNMaW5rZWQgPSB1c2VyICYmIFBhcnNlLkFub255bW91c1V0aWxzLmlzTGlua2VkKHVzZXIpO1xuICAgIGlmICghaXNNYXN0ZXIgJiYgIWNvbmZpZy5maWxlVXBsb2FkLmVuYWJsZUZvckFub255bW91c1VzZXIgJiYgaXNMaW5rZWQpIHtcbiAgICAgIG5leHQobmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5GSUxFX1NBVkVfRVJST1IsXG4gICAgICAgICdGaWxlIHVwbG9hZCBieSBhbm9ueW1vdXMgdXNlciBpcyBkaXNhYmxlZC4nXG4gICAgICApKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCFpc01hc3RlciAmJiAhY29uZmlnLmZpbGVVcGxvYWQuZW5hYmxlRm9yQXV0aGVudGljYXRlZFVzZXIgJiYgIWlzTGlua2VkICYmIHVzZXIpIHtcbiAgICAgIG5leHQobmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5GSUxFX1NBVkVfRVJST1IsXG4gICAgICAgICdGaWxlIHVwbG9hZCBieSBhdXRoZW50aWNhdGVkIHVzZXIgaXMgZGlzYWJsZWQuJ1xuICAgICAgKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghaXNNYXN0ZXIgJiYgIWNvbmZpZy5maWxlVXBsb2FkLmVuYWJsZUZvclB1YmxpYyAmJiAhdXNlcikge1xuICAgICAgbmV4dChuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRklMRV9TQVZFX0VSUk9SLCAnRmlsZSB1cGxvYWQgYnkgcHVibGljIGlzIGRpc2FibGVkLicpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZmlsZXNDb250cm9sbGVyID0gY29uZmlnLmZpbGVzQ29udHJvbGxlcjtcbiAgICBjb25zdCB7IGZpbGVuYW1lIH0gPSByZXEucGFyYW1zO1xuICAgIGNvbnN0IGNvbnRlbnRUeXBlID0gcmVxLmdldCgnQ29udGVudC10eXBlJyk7XG5cbiAgICBpZiAoIXJlcS5ib2R5IHx8ICFyZXEuYm9keS5sZW5ndGgpIHtcbiAgICAgIG5leHQobmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkZJTEVfU0FWRV9FUlJPUiwgJ0ludmFsaWQgZmlsZSB1cGxvYWQuJykpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGVycm9yID0gZmlsZXNDb250cm9sbGVyLnZhbGlkYXRlRmlsZW5hbWUoZmlsZW5hbWUpO1xuICAgIGlmIChlcnJvcikge1xuICAgICAgbmV4dChlcnJvcik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgYmFzZTY0ID0gcmVxLmJvZHkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgIGNvbnN0IGZpbGUgPSBuZXcgUGFyc2UuRmlsZShmaWxlbmFtZSwgeyBiYXNlNjQgfSwgY29udGVudFR5cGUpO1xuICAgIGNvbnN0IHsgbWV0YWRhdGEgPSB7fSwgdGFncyA9IHt9IH0gPSByZXEuZmlsZURhdGEgfHwge307XG4gICAgZmlsZS5zZXRUYWdzKHRhZ3MpO1xuICAgIGZpbGUuc2V0TWV0YWRhdGEobWV0YWRhdGEpO1xuICAgIGNvbnN0IGZpbGVTaXplID0gQnVmZmVyLmJ5dGVMZW5ndGgocmVxLmJvZHkpO1xuICAgIGNvbnN0IGZpbGVPYmplY3QgPSB7IGZpbGUsIGZpbGVTaXplIH07XG4gICAgdHJ5IHtcbiAgICAgIC8vIHJ1biBiZWZvcmVTYXZlRmlsZSB0cmlnZ2VyXG4gICAgICBjb25zdCB0cmlnZ2VyUmVzdWx0ID0gYXdhaXQgdHJpZ2dlcnMubWF5YmVSdW5GaWxlVHJpZ2dlcihcbiAgICAgICAgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlU2F2ZUZpbGUsXG4gICAgICAgIGZpbGVPYmplY3QsXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgcmVxLmF1dGhcbiAgICAgICk7XG4gICAgICBsZXQgc2F2ZVJlc3VsdDtcbiAgICAgIC8vIGlmIGEgbmV3IFBhcnNlRmlsZSBpcyByZXR1cm5lZCBjaGVjayBpZiBpdCdzIGFuIGFscmVhZHkgc2F2ZWQgZmlsZVxuICAgICAgaWYgKHRyaWdnZXJSZXN1bHQgaW5zdGFuY2VvZiBQYXJzZS5GaWxlKSB7XG4gICAgICAgIGZpbGVPYmplY3QuZmlsZSA9IHRyaWdnZXJSZXN1bHQ7XG4gICAgICAgIGlmICh0cmlnZ2VyUmVzdWx0LnVybCgpKSB7XG4gICAgICAgICAgLy8gc2V0IGZpbGVTaXplIHRvIG51bGwgYmVjYXVzZSB3ZSB3b250IGtub3cgaG93IGJpZyBpdCBpcyBoZXJlXG4gICAgICAgICAgZmlsZU9iamVjdC5maWxlU2l6ZSA9IG51bGw7XG4gICAgICAgICAgc2F2ZVJlc3VsdCA9IHtcbiAgICAgICAgICAgIHVybDogdHJpZ2dlclJlc3VsdC51cmwoKSxcbiAgICAgICAgICAgIG5hbWU6IHRyaWdnZXJSZXN1bHQuX25hbWUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gaWYgdGhlIGZpbGUgcmV0dXJuZWQgYnkgdGhlIHRyaWdnZXIgaGFzIGFscmVhZHkgYmVlbiBzYXZlZCBza2lwIHNhdmluZyBhbnl0aGluZ1xuICAgICAgaWYgKCFzYXZlUmVzdWx0KSB7XG4gICAgICAgIC8vIGlmIHRoZSBQYXJzZUZpbGUgcmV0dXJuZWQgaXMgdHlwZSB1cmksIGRvd25sb2FkIHRoZSBmaWxlIGJlZm9yZSBzYXZpbmcgaXRcbiAgICAgICAgYXdhaXQgYWRkRmlsZURhdGFJZk5lZWRlZChmaWxlT2JqZWN0LmZpbGUpO1xuICAgICAgICAvLyB1cGRhdGUgZmlsZVNpemVcbiAgICAgICAgY29uc3QgYnVmZmVyRGF0YSA9IEJ1ZmZlci5mcm9tKGZpbGVPYmplY3QuZmlsZS5fZGF0YSwgJ2Jhc2U2NCcpO1xuICAgICAgICBmaWxlT2JqZWN0LmZpbGVTaXplID0gQnVmZmVyLmJ5dGVMZW5ndGgoYnVmZmVyRGF0YSk7XG4gICAgICAgIC8vIHNhdmUgZmlsZVxuICAgICAgICBjb25zdCBjcmVhdGVGaWxlUmVzdWx0ID0gYXdhaXQgZmlsZXNDb250cm9sbGVyLmNyZWF0ZUZpbGUoXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIGZpbGVPYmplY3QuZmlsZS5fbmFtZSxcbiAgICAgICAgICBidWZmZXJEYXRhLFxuICAgICAgICAgIGZpbGVPYmplY3QuZmlsZS5fc291cmNlLnR5cGUsXG4gICAgICAgICAge1xuICAgICAgICAgICAgdGFnczogZmlsZU9iamVjdC5maWxlLl90YWdzLFxuICAgICAgICAgICAgbWV0YWRhdGE6IGZpbGVPYmplY3QuZmlsZS5fbWV0YWRhdGEsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICAvLyB1cGRhdGUgZmlsZSB3aXRoIG5ldyBkYXRhXG4gICAgICAgIGZpbGVPYmplY3QuZmlsZS5fbmFtZSA9IGNyZWF0ZUZpbGVSZXN1bHQubmFtZTtcbiAgICAgICAgZmlsZU9iamVjdC5maWxlLl91cmwgPSBjcmVhdGVGaWxlUmVzdWx0LnVybDtcbiAgICAgICAgZmlsZU9iamVjdC5maWxlLl9yZXF1ZXN0VGFzayA9IG51bGw7XG4gICAgICAgIGZpbGVPYmplY3QuZmlsZS5fcHJldmlvdXNTYXZlID0gUHJvbWlzZS5yZXNvbHZlKGZpbGVPYmplY3QuZmlsZSk7XG4gICAgICAgIHNhdmVSZXN1bHQgPSB7XG4gICAgICAgICAgdXJsOiBjcmVhdGVGaWxlUmVzdWx0LnVybCxcbiAgICAgICAgICBuYW1lOiBjcmVhdGVGaWxlUmVzdWx0Lm5hbWUsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICAvLyBydW4gYWZ0ZXJTYXZlRmlsZSB0cmlnZ2VyXG4gICAgICBhd2FpdCB0cmlnZ2Vycy5tYXliZVJ1bkZpbGVUcmlnZ2VyKFxuICAgICAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlclNhdmVGaWxlLFxuICAgICAgICBmaWxlT2JqZWN0LFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHJlcS5hdXRoXG4gICAgICApO1xuICAgICAgcmVzLnN0YXR1cygyMDEpO1xuICAgICAgcmVzLnNldCgnTG9jYXRpb24nLCBzYXZlUmVzdWx0LnVybCk7XG4gICAgICByZXMuanNvbihzYXZlUmVzdWx0KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIGNyZWF0aW5nIGEgZmlsZTogJywgZSk7XG4gICAgICBjb25zdCBlcnJvciA9IHRyaWdnZXJzLnJlc29sdmVFcnJvcihlLCB7XG4gICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLkZJTEVfU0FWRV9FUlJPUixcbiAgICAgICAgbWVzc2FnZTogYENvdWxkIG5vdCBzdG9yZSBmaWxlOiAke2ZpbGVPYmplY3QuZmlsZS5fbmFtZX0uYCxcbiAgICAgIH0pO1xuICAgICAgbmV4dChlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZGVsZXRlSGFuZGxlcihyZXEsIHJlcywgbmV4dCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IGZpbGVzQ29udHJvbGxlciB9ID0gcmVxLmNvbmZpZztcbiAgICAgIGNvbnN0IHsgZmlsZW5hbWUgfSA9IHJlcS5wYXJhbXM7XG4gICAgICAvLyBydW4gYmVmb3JlRGVsZXRlRmlsZSB0cmlnZ2VyXG4gICAgICBjb25zdCBmaWxlID0gbmV3IFBhcnNlLkZpbGUoZmlsZW5hbWUpO1xuICAgICAgZmlsZS5fdXJsID0gZmlsZXNDb250cm9sbGVyLmFkYXB0ZXIuZ2V0RmlsZUxvY2F0aW9uKHJlcS5jb25maWcsIGZpbGVuYW1lKTtcbiAgICAgIGNvbnN0IGZpbGVPYmplY3QgPSB7IGZpbGUsIGZpbGVTaXplOiBudWxsIH07XG4gICAgICBhd2FpdCB0cmlnZ2Vycy5tYXliZVJ1bkZpbGVUcmlnZ2VyKFxuICAgICAgICB0cmlnZ2Vycy5UeXBlcy5iZWZvcmVEZWxldGVGaWxlLFxuICAgICAgICBmaWxlT2JqZWN0LFxuICAgICAgICByZXEuY29uZmlnLFxuICAgICAgICByZXEuYXV0aFxuICAgICAgKTtcbiAgICAgIC8vIGRlbGV0ZSBmaWxlXG4gICAgICBhd2FpdCBmaWxlc0NvbnRyb2xsZXIuZGVsZXRlRmlsZShyZXEuY29uZmlnLCBmaWxlbmFtZSk7XG4gICAgICAvLyBydW4gYWZ0ZXJEZWxldGVGaWxlIHRyaWdnZXJcbiAgICAgIGF3YWl0IHRyaWdnZXJzLm1heWJlUnVuRmlsZVRyaWdnZXIoXG4gICAgICAgIHRyaWdnZXJzLlR5cGVzLmFmdGVyRGVsZXRlRmlsZSxcbiAgICAgICAgZmlsZU9iamVjdCxcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgcmVxLmF1dGhcbiAgICAgICk7XG4gICAgICByZXMuc3RhdHVzKDIwMCk7XG4gICAgICAvLyBUT0RPOiByZXR1cm4gdXNlZnVsIEpTT04gaGVyZT9cbiAgICAgIHJlcy5lbmQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIGRlbGV0aW5nIGEgZmlsZTogJywgZSk7XG4gICAgICBjb25zdCBlcnJvciA9IHRyaWdnZXJzLnJlc29sdmVFcnJvcihlLCB7XG4gICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLkZJTEVfREVMRVRFX0VSUk9SLFxuICAgICAgICBtZXNzYWdlOiAnQ291bGQgbm90IGRlbGV0ZSBmaWxlLicsXG4gICAgICB9KTtcbiAgICAgIG5leHQoZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIG1ldGFkYXRhSGFuZGxlcihyZXEsIHJlcykge1xuICAgIGNvbnN0IGNvbmZpZyA9IENvbmZpZy5nZXQocmVxLnBhcmFtcy5hcHBJZCk7XG4gICAgY29uc3QgeyBmaWxlc0NvbnRyb2xsZXIgfSA9IGNvbmZpZztcbiAgICBjb25zdCB7IGZpbGVuYW1lIH0gPSByZXEucGFyYW1zO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgZmlsZXNDb250cm9sbGVyLmdldE1ldGFkYXRhKGZpbGVuYW1lKTtcbiAgICAgIHJlcy5zdGF0dXMoMjAwKTtcbiAgICAgIHJlcy5qc29uKGRhdGEpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJlcy5zdGF0dXMoMjAwKTtcbiAgICAgIHJlcy5qc29uKHt9KTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNGaWxlU3RyZWFtYWJsZShyZXEsIGZpbGVzQ29udHJvbGxlcikge1xuICByZXR1cm4gcmVxLmdldCgnUmFuZ2UnKSAmJiB0eXBlb2YgZmlsZXNDb250cm9sbGVyLmFkYXB0ZXIuaGFuZGxlRmlsZVN0cmVhbSA9PT0gJ2Z1bmN0aW9uJztcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/FunctionsRouter.js b/lib/Routers/FunctionsRouter.js new file mode 100644 index 0000000000..0e5c6b67d3 --- /dev/null +++ b/lib/Routers/FunctionsRouter.js @@ -0,0 +1,181 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.FunctionsRouter = void 0; + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var _middlewares = require("../middlewares"); + +var _StatusHandler = require("../StatusHandler"); + +var _lodash = _interopRequireDefault(require("lodash")); + +var _logger = require("../logger"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// FunctionsRouter.js +var Parse = require('parse/node').Parse, + triggers = require('../triggers'); + +function parseObject(obj) { + if (Array.isArray(obj)) { + return obj.map(item => { + return parseObject(item); + }); + } else if (obj && obj.__type == 'Date') { + return Object.assign(new Date(obj.iso), obj); + } else if (obj && obj.__type == 'File') { + return Parse.File.fromJSON(obj); + } else if (obj && typeof obj === 'object') { + return parseParams(obj); + } else { + return obj; + } +} + +function parseParams(params) { + return _lodash.default.mapValues(params, parseObject); +} + +class FunctionsRouter extends _PromiseRouter.default { + mountRoutes() { + this.route('POST', '/functions/:functionName', _middlewares.promiseEnsureIdempotency, FunctionsRouter.handleCloudFunction); + this.route('POST', '/jobs/:jobName', _middlewares.promiseEnsureIdempotency, _middlewares.promiseEnforceMasterKeyAccess, function (req) { + return FunctionsRouter.handleCloudJob(req); + }); + this.route('POST', '/jobs', _middlewares.promiseEnforceMasterKeyAccess, function (req) { + return FunctionsRouter.handleCloudJob(req); + }); + } + + static handleCloudJob(req) { + const jobName = req.params.jobName || req.body.jobName; + const applicationId = req.config.applicationId; + const jobHandler = (0, _StatusHandler.jobStatusHandler)(req.config); + const jobFunction = triggers.getJob(jobName, applicationId); + + if (!jobFunction) { + throw new Parse.Error(Parse.Error.SCRIPT_FAILED, 'Invalid job.'); + } + + let params = Object.assign({}, req.body, req.query); + params = parseParams(params); + const request = { + params: params, + log: req.config.loggerController, + headers: req.config.headers, + ip: req.config.ip, + jobName, + message: jobHandler.setMessage.bind(jobHandler) + }; + return jobHandler.setRunning(jobName, params).then(jobStatus => { + request.jobId = jobStatus.objectId; // run the function async + + process.nextTick(() => { + Promise.resolve().then(() => { + return jobFunction(request); + }).then(result => { + jobHandler.setSucceeded(result); + }, error => { + jobHandler.setFailed(error); + }); + }); + return { + headers: { + 'X-Parse-Job-Status-Id': jobStatus.objectId + }, + response: {} + }; + }); + } + + static createResponseObject(resolve, reject) { + return { + success: function (result) { + resolve({ + response: { + result: Parse._encode(result) + } + }); + }, + error: function (message) { + const error = triggers.resolveError(message); + reject(error); + } + }; + } + + static handleCloudFunction(req) { + const functionName = req.params.functionName; + const applicationId = req.config.applicationId; + const theFunction = triggers.getFunction(functionName, applicationId); + + if (!theFunction) { + throw new Parse.Error(Parse.Error.SCRIPT_FAILED, `Invalid function: "${functionName}"`); + } + + let params = Object.assign({}, req.body, req.query); + params = parseParams(params); + const request = { + params: params, + master: req.auth && req.auth.isMaster, + user: req.auth && req.auth.user, + installationId: req.info.installationId, + log: req.config.loggerController, + headers: req.config.headers, + ip: req.config.ip, + functionName, + context: req.info.context + }; + return new Promise(function (resolve, reject) { + const userString = req.auth && req.auth.user ? req.auth.user.id : undefined; + + const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(params)); + + const { + success, + error + } = FunctionsRouter.createResponseObject(result => { + try { + const cleanResult = _logger.logger.truncateLogMessage(JSON.stringify(result.response.result)); + + _logger.logger.info(`Ran cloud function ${functionName} for user ${userString} with:\n Input: ${cleanInput}\n Result: ${cleanResult}`, { + functionName, + params, + user: userString + }); + + resolve(result); + } catch (e) { + reject(e); + } + }, error => { + try { + _logger.logger.error(`Failed running cloud function ${functionName} for user ${userString} with:\n Input: ${cleanInput}\n Error: ` + JSON.stringify(error), { + functionName, + error, + params, + user: userString + }); + + reject(error); + } catch (e) { + reject(e); + } + }); + return Promise.resolve().then(() => { + return triggers.maybeRunValidator(request, functionName); + }).then(() => { + return theFunction(request); + }).then(success, error); + }); + } + +} + +exports.FunctionsRouter = FunctionsRouter; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0Z1bmN0aW9uc1JvdXRlci5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJ0cmlnZ2VycyIsInBhcnNlT2JqZWN0Iiwib2JqIiwiQXJyYXkiLCJpc0FycmF5IiwibWFwIiwiaXRlbSIsIl9fdHlwZSIsIk9iamVjdCIsImFzc2lnbiIsIkRhdGUiLCJpc28iLCJGaWxlIiwiZnJvbUpTT04iLCJwYXJzZVBhcmFtcyIsInBhcmFtcyIsIl8iLCJtYXBWYWx1ZXMiLCJGdW5jdGlvbnNSb3V0ZXIiLCJQcm9taXNlUm91dGVyIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsInByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSIsImhhbmRsZUNsb3VkRnVuY3Rpb24iLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyIsInJlcSIsImhhbmRsZUNsb3VkSm9iIiwiam9iTmFtZSIsImJvZHkiLCJhcHBsaWNhdGlvbklkIiwiY29uZmlnIiwiam9iSGFuZGxlciIsImpvYkZ1bmN0aW9uIiwiZ2V0Sm9iIiwiRXJyb3IiLCJTQ1JJUFRfRkFJTEVEIiwicXVlcnkiLCJyZXF1ZXN0IiwibG9nIiwibG9nZ2VyQ29udHJvbGxlciIsImhlYWRlcnMiLCJpcCIsIm1lc3NhZ2UiLCJzZXRNZXNzYWdlIiwiYmluZCIsInNldFJ1bm5pbmciLCJ0aGVuIiwiam9iU3RhdHVzIiwiam9iSWQiLCJvYmplY3RJZCIsInByb2Nlc3MiLCJuZXh0VGljayIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVzdWx0Iiwic2V0U3VjY2VlZGVkIiwiZXJyb3IiLCJzZXRGYWlsZWQiLCJyZXNwb25zZSIsImNyZWF0ZVJlc3BvbnNlT2JqZWN0IiwicmVqZWN0Iiwic3VjY2VzcyIsIl9lbmNvZGUiLCJyZXNvbHZlRXJyb3IiLCJmdW5jdGlvbk5hbWUiLCJ0aGVGdW5jdGlvbiIsImdldEZ1bmN0aW9uIiwibWFzdGVyIiwiYXV0aCIsImlzTWFzdGVyIiwidXNlciIsImluc3RhbGxhdGlvbklkIiwiaW5mbyIsImNvbnRleHQiLCJ1c2VyU3RyaW5nIiwiaWQiLCJ1bmRlZmluZWQiLCJjbGVhbklucHV0IiwibG9nZ2VyIiwidHJ1bmNhdGVMb2dNZXNzYWdlIiwiSlNPTiIsInN0cmluZ2lmeSIsImNsZWFuUmVzdWx0IiwiZSIsIm1heWJlUnVuVmFsaWRhdG9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBS0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFUQTtBQUVBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBbEM7QUFBQSxJQUNFRSxRQUFRLEdBQUdELE9BQU8sQ0FBQyxhQUFELENBRHBCOztBQVNBLFNBQVNFLFdBQVQsQ0FBcUJDLEdBQXJCLEVBQTBCO0FBQ3hCLE1BQUlDLEtBQUssQ0FBQ0MsT0FBTixDQUFjRixHQUFkLENBQUosRUFBd0I7QUFDdEIsV0FBT0EsR0FBRyxDQUFDRyxHQUFKLENBQVFDLElBQUksSUFBSTtBQUNyQixhQUFPTCxXQUFXLENBQUNLLElBQUQsQ0FBbEI7QUFDRCxLQUZNLENBQVA7QUFHRCxHQUpELE1BSU8sSUFBSUosR0FBRyxJQUFJQSxHQUFHLENBQUNLLE1BQUosSUFBYyxNQUF6QixFQUFpQztBQUN0QyxXQUFPQyxNQUFNLENBQUNDLE1BQVAsQ0FBYyxJQUFJQyxJQUFKLENBQVNSLEdBQUcsQ0FBQ1MsR0FBYixDQUFkLEVBQWlDVCxHQUFqQyxDQUFQO0FBQ0QsR0FGTSxNQUVBLElBQUlBLEdBQUcsSUFBSUEsR0FBRyxDQUFDSyxNQUFKLElBQWMsTUFBekIsRUFBaUM7QUFDdEMsV0FBT1QsS0FBSyxDQUFDYyxJQUFOLENBQVdDLFFBQVgsQ0FBb0JYLEdBQXBCLENBQVA7QUFDRCxHQUZNLE1BRUEsSUFBSUEsR0FBRyxJQUFJLE9BQU9BLEdBQVAsS0FBZSxRQUExQixFQUFvQztBQUN6QyxXQUFPWSxXQUFXLENBQUNaLEdBQUQsQ0FBbEI7QUFDRCxHQUZNLE1BRUE7QUFDTCxXQUFPQSxHQUFQO0FBQ0Q7QUFDRjs7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LEVBQW9DMkIsWUFBcEMsQ0FBUDtBQUNELE9BSEksRUFJSmxCLElBSkksQ0FJQyxNQUFNO0FBQ1YsZUFBT21CLFdBQVcsQ0FBQzVCLE9BQUQsQ0FBbEI7QUFDRCxPQU5JLEVBT0pTLElBUEksQ0FPQ2UsT0FQRCxFQU9VTCxLQVBWLENBQVA7QUFRRCxLQTlDTSxDQUFQO0FBK0NEOztBQXZKZ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBGdW5jdGlvbnNSb3V0ZXIuanNcblxudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlLFxuICB0cmlnZ2VycyA9IHJlcXVpcmUoJy4uL3RyaWdnZXJzJyk7XG5cbmltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0IHsgcHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSB9IGZyb20gJy4uL21pZGRsZXdhcmVzJztcbmltcG9ydCB7IGpvYlN0YXR1c0hhbmRsZXIgfSBmcm9tICcuLi9TdGF0dXNIYW5kbGVyJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi9sb2dnZXInO1xuXG5mdW5jdGlvbiBwYXJzZU9iamVjdChvYmopIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgIHJldHVybiBvYmoubWFwKGl0ZW0gPT4ge1xuICAgICAgcmV0dXJuIHBhcnNlT2JqZWN0KGl0ZW0pO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKG9iaiAmJiBvYmouX190eXBlID09ICdEYXRlJykge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKG5ldyBEYXRlKG9iai5pc28pLCBvYmopO1xuICB9IGVsc2UgaWYgKG9iaiAmJiBvYmouX190eXBlID09ICdGaWxlJykge1xuICAgIHJldHVybiBQYXJzZS5GaWxlLmZyb21KU09OKG9iaik7XG4gIH0gZWxzZSBpZiAob2JqICYmIHR5cGVvZiBvYmogPT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIHBhcnNlUGFyYW1zKG9iaik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG9iajtcbiAgfVxufVxuXG5mdW5jdGlvbiBwYXJzZVBhcmFtcyhwYXJhbXMpIHtcbiAgcmV0dXJuIF8ubWFwVmFsdWVzKHBhcmFtcywgcGFyc2VPYmplY3QpO1xufVxuXG5leHBvcnQgY2xhc3MgRnVuY3Rpb25zUm91dGVyIGV4dGVuZHMgUHJvbWlzZVJvdXRlciB7XG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnUE9TVCcsXG4gICAgICAnL2Z1bmN0aW9ucy86ZnVuY3Rpb25OYW1lJyxcbiAgICAgIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSxcbiAgICAgIEZ1bmN0aW9uc1JvdXRlci5oYW5kbGVDbG91ZEZ1bmN0aW9uXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ1BPU1QnLFxuICAgICAgJy9qb2JzLzpqb2JOYW1lJyxcbiAgICAgIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSxcbiAgICAgIHByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgZnVuY3Rpb24gKHJlcSkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25zUm91dGVyLmhhbmRsZUNsb3VkSm9iKHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9qb2JzJywgcHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICAgIHJldHVybiBGdW5jdGlvbnNSb3V0ZXIuaGFuZGxlQ2xvdWRKb2IocmVxKTtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBoYW5kbGVDbG91ZEpvYihyZXEpIHtcbiAgICBjb25zdCBqb2JOYW1lID0gcmVxLnBhcmFtcy5qb2JOYW1lIHx8IHJlcS5ib2R5LmpvYk5hbWU7XG4gICAgY29uc3QgYXBwbGljYXRpb25JZCA9IHJlcS5jb25maWcuYXBwbGljYXRpb25JZDtcbiAgICBjb25zdCBqb2JIYW5kbGVyID0gam9iU3RhdHVzSGFuZGxlcihyZXEuY29uZmlnKTtcbiAgICBjb25zdCBqb2JGdW5jdGlvbiA9IHRyaWdnZXJzLmdldEpvYihqb2JOYW1lLCBhcHBsaWNhdGlvbklkKTtcbiAgICBpZiAoIWpvYkZ1bmN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuU0NSSVBUX0ZBSUxFRCwgJ0ludmFsaWQgam9iLicpO1xuICAgIH1cbiAgICBsZXQgcGFyYW1zID0gT2JqZWN0LmFzc2lnbih7fSwgcmVxLmJvZHksIHJlcS5xdWVyeSk7XG4gICAgcGFyYW1zID0gcGFyc2VQYXJhbXMocGFyYW1zKTtcbiAgICBjb25zdCByZXF1ZXN0ID0ge1xuICAgICAgcGFyYW1zOiBwYXJhbXMsXG4gICAgICBsb2c6IHJlcS5jb25maWcubG9nZ2VyQ29udHJvbGxlcixcbiAgICAgIGhlYWRlcnM6IHJlcS5jb25maWcuaGVhZGVycyxcbiAgICAgIGlwOiByZXEuY29uZmlnLmlwLFxuICAgICAgam9iTmFtZSxcbiAgICAgIG1lc3NhZ2U6IGpvYkhhbmRsZXIuc2V0TWVzc2FnZS5iaW5kKGpvYkhhbmRsZXIpLFxuICAgIH07XG5cbiAgICByZXR1cm4gam9iSGFuZGxlci5zZXRSdW5uaW5nKGpvYk5hbWUsIHBhcmFtcykudGhlbihqb2JTdGF0dXMgPT4ge1xuICAgICAgcmVxdWVzdC5qb2JJZCA9IGpvYlN0YXR1cy5vYmplY3RJZDtcbiAgICAgIC8vIHJ1biB0aGUgZnVuY3Rpb24gYXN5bmNcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soKCkgPT4ge1xuICAgICAgICBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBqb2JGdW5jdGlvbihyZXF1ZXN0KTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgcmVzdWx0ID0+IHtcbiAgICAgICAgICAgICAgam9iSGFuZGxlci5zZXRTdWNjZWVkZWQocmVzdWx0KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvciA9PiB7XG4gICAgICAgICAgICAgIGpvYkhhbmRsZXIuc2V0RmFpbGVkKGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgJ1gtUGFyc2UtSm9iLVN0YXR1cy1JZCc6IGpvYlN0YXR1cy5vYmplY3RJZCxcbiAgICAgICAgfSxcbiAgICAgICAgcmVzcG9uc2U6IHt9LFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVSZXNwb25zZU9iamVjdChyZXNvbHZlLCByZWplY3QpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgICAgcmVzdWx0OiBQYXJzZS5fZW5jb2RlKHJlc3VsdCksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgZXJyb3I6IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgICAgIGNvbnN0IGVycm9yID0gdHJpZ2dlcnMucmVzb2x2ZUVycm9yKG1lc3NhZ2UpO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSxcbiAgICB9O1xuICB9XG4gIHN0YXRpYyBoYW5kbGVDbG91ZEZ1bmN0aW9uKHJlcSkge1xuICAgIGNvbnN0IGZ1bmN0aW9uTmFtZSA9IHJlcS5wYXJhbXMuZnVuY3Rpb25OYW1lO1xuICAgIGNvbnN0IGFwcGxpY2F0aW9uSWQgPSByZXEuY29uZmlnLmFwcGxpY2F0aW9uSWQ7XG4gICAgY29uc3QgdGhlRnVuY3Rpb24gPSB0cmlnZ2Vycy5nZXRGdW5jdGlvbihmdW5jdGlvbk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xuXG4gICAgaWYgKCF0aGVGdW5jdGlvbikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlNDUklQVF9GQUlMRUQsIGBJbnZhbGlkIGZ1bmN0aW9uOiBcIiR7ZnVuY3Rpb25OYW1lfVwiYCk7XG4gICAgfVxuICAgIGxldCBwYXJhbXMgPSBPYmplY3QuYXNzaWduKHt9LCByZXEuYm9keSwgcmVxLnF1ZXJ5KTtcbiAgICBwYXJhbXMgPSBwYXJzZVBhcmFtcyhwYXJhbXMpO1xuICAgIGNvbnN0IHJlcXVlc3QgPSB7XG4gICAgICBwYXJhbXM6IHBhcmFtcyxcbiAgICAgIG1hc3RlcjogcmVxLmF1dGggJiYgcmVxLmF1dGguaXNNYXN0ZXIsXG4gICAgICB1c2VyOiByZXEuYXV0aCAmJiByZXEuYXV0aC51c2VyLFxuICAgICAgaW5zdGFsbGF0aW9uSWQ6IHJlcS5pbmZvLmluc3RhbGxhdGlvbklkLFxuICAgICAgbG9nOiByZXEuY29uZmlnLmxvZ2dlckNvbnRyb2xsZXIsXG4gICAgICBoZWFkZXJzOiByZXEuY29uZmlnLmhlYWRlcnMsXG4gICAgICBpcDogcmVxLmNvbmZpZy5pcCxcbiAgICAgIGZ1bmN0aW9uTmFtZSxcbiAgICAgIGNvbnRleHQ6IHJlcS5pbmZvLmNvbnRleHQsXG4gICAgfTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBjb25zdCB1c2VyU3RyaW5nID0gcmVxLmF1dGggJiYgcmVxLmF1dGgudXNlciA/IHJlcS5hdXRoLnVzZXIuaWQgOiB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBjbGVhbklucHV0ID0gbG9nZ2VyLnRydW5jYXRlTG9nTWVzc2FnZShKU09OLnN0cmluZ2lmeShwYXJhbXMpKTtcbiAgICAgIGNvbnN0IHsgc3VjY2VzcywgZXJyb3IgfSA9IEZ1bmN0aW9uc1JvdXRlci5jcmVhdGVSZXNwb25zZU9iamVjdChcbiAgICAgICAgcmVzdWx0ID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgY2xlYW5SZXN1bHQgPSBsb2dnZXIudHJ1bmNhdGVMb2dNZXNzYWdlKEpTT04uc3RyaW5naWZ5KHJlc3VsdC5yZXNwb25zZS5yZXN1bHQpKTtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgICBgUmFuIGNsb3VkIGZ1bmN0aW9uICR7ZnVuY3Rpb25OYW1lfSBmb3IgdXNlciAke3VzZXJTdHJpbmd9IHdpdGg6XFxuICBJbnB1dDogJHtjbGVhbklucHV0fVxcbiAgUmVzdWx0OiAke2NsZWFuUmVzdWx0fWAsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmdW5jdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgICAgICAgIHVzZXI6IHVzZXJTdHJpbmcsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3IgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICAgIGBGYWlsZWQgcnVubmluZyBjbG91ZCBmdW5jdGlvbiAke2Z1bmN0aW9uTmFtZX0gZm9yIHVzZXIgJHt1c2VyU3RyaW5nfSB3aXRoOlxcbiAgSW5wdXQ6ICR7Y2xlYW5JbnB1dH1cXG4gIEVycm9yOiBgICtcbiAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShlcnJvciksXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmdW5jdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgICAgICAgIHVzZXI6IHVzZXJTdHJpbmcsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIHJldHVybiB0cmlnZ2Vycy5tYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0LCBmdW5jdGlvbk5hbWUpO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHRoZUZ1bmN0aW9uKHJlcXVlc3QpO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihzdWNjZXNzLCBlcnJvcik7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/GlobalConfigRouter.js b/lib/Routers/GlobalConfigRouter.js new file mode 100644 index 0000000000..7156f27974 --- /dev/null +++ b/lib/Routers/GlobalConfigRouter.js @@ -0,0 +1,95 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.GlobalConfigRouter = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// global_config.js +class GlobalConfigRouter extends _PromiseRouter.default { + getGlobalConfig(req) { + return req.config.database.find('_GlobalConfig', { + objectId: '1' + }, { + limit: 1 + }).then(results => { + if (results.length != 1) { + // If there is no config in the database - return empty config. + return { + response: { + params: {} + } + }; + } + + const globalConfig = results[0]; + + if (!req.auth.isMaster && globalConfig.masterKeyOnly !== undefined) { + for (const param in globalConfig.params) { + if (globalConfig.masterKeyOnly[param]) { + delete globalConfig.params[param]; + delete globalConfig.masterKeyOnly[param]; + } + } + } + + return { + response: { + params: globalConfig.params, + masterKeyOnly: globalConfig.masterKeyOnly + } + }; + }); + } + + updateGlobalConfig(req) { + if (req.auth.isReadOnly) { + throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to update the config."); + } + + const params = req.body.params; + const masterKeyOnly = req.body.masterKeyOnly || {}; // Transform in dot notation to make sure it works + + const update = Object.keys(params).reduce((acc, key) => { + acc[`params.${key}`] = params[key]; + acc[`masterKeyOnly.${key}`] = masterKeyOnly[key] || false; + return acc; + }, {}); + return req.config.database.update('_GlobalConfig', { + objectId: '1' + }, update, { + upsert: true + }).then(() => ({ + response: { + result: true + } + })); + } + + mountRoutes() { + this.route('GET', '/config', req => { + return this.getGlobalConfig(req); + }); + this.route('PUT', '/config', middleware.promiseEnforceMasterKeyAccess, req => { + return this.updateGlobalConfig(req); + }); + } + +} + +exports.GlobalConfigRouter = GlobalConfigRouter; +var _default = GlobalConfigRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0dsb2JhbENvbmZpZ1JvdXRlci5qcyJdLCJuYW1lcyI6WyJHbG9iYWxDb25maWdSb3V0ZXIiLCJQcm9taXNlUm91dGVyIiwiZ2V0R2xvYmFsQ29uZmlnIiwicmVxIiwiY29uZmlnIiwiZGF0YWJhc2UiLCJmaW5kIiwib2JqZWN0SWQiLCJsaW1pdCIsInRoZW4iLCJyZXN1bHRzIiwibGVuZ3RoIiwicmVzcG9uc2UiLCJwYXJhbXMiLCJnbG9iYWxDb25maWciLCJhdXRoIiwiaXNNYXN0ZXIiLCJtYXN0ZXJLZXlPbmx5IiwidW5kZWZpbmVkIiwicGFyYW0iLCJ1cGRhdGVHbG9iYWxDb25maWciLCJpc1JlYWRPbmx5IiwiUGFyc2UiLCJFcnJvciIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJib2R5IiwidXBkYXRlIiwiT2JqZWN0Iiwia2V5cyIsInJlZHVjZSIsImFjYyIsImtleSIsInVwc2VydCIsInJlc3VsdCIsIm1vdW50Um91dGVzIiwicm91dGUiLCJtaWRkbGV3YXJlIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFIQTtBQUtPLE1BQU1BLGtCQUFOLFNBQWlDQyxzQkFBakMsQ0FBK0M7QUFDcERDLEVBQUFBLGVBQWUsQ0FBQ0MsR0FBRCxFQUFNO0FBQ25CLFdBQU9BLEdBQUcsQ0FBQ0MsTUFBSixDQUFXQyxRQUFYLENBQ0pDLElBREksQ0FDQyxlQURELEVBQ2tCO0FBQUVDLE1BQUFBLFFBQVEsRUFBRTtBQUFaLEtBRGxCLEVBQ3FDO0FBQUVDLE1BQUFBLEtBQUssRUFBRTtBQUFULEtBRHJDLEVBRUpDLElBRkksQ0FFQ0MsT0FBTyxJQUFJO0FBQ2YsVUFBSUEsT0FBTyxDQUFDQyxNQUFSLElBQWtCLENBQXRCLEVBQXlCO0FBQ3ZCO0FBQ0EsZUFBTztBQUFFQyxVQUFBQSxRQUFRLEVBQUU7QUFBRUMsWUFBQUEsTUFBTSxFQUFFO0FBQVY7QUFBWixTQUFQO0FBQ0Q7O0FBQ0QsWUFBTUMsWUFBWSxHQUFHSixPQUFPLENBQUMsQ0FBRCxDQUE1Qjs7QUFDQSxVQUFJLENBQUNQLEdBQUcsQ0FBQ1ksSUFBSixDQUFTQyxRQUFWLElBQXNCRixZQUFZLENBQUNHLGFBQWIsS0FBK0JDLFNBQXpELEVBQW9FO0FBQ2xFLGFBQUssTUFBTUMsS0FBWCxJQUFvQkwsWUFBWSxDQUFDRCxNQUFqQyxFQUF5QztBQUN2QyxjQUFJQyxZQUFZLENBQUNHLGFBQWIsQ0FBMkJFLEtBQTNCLENBQUosRUFBdUM7QUFDckMsbUJBQU9MLFlBQVksQ0FBQ0QsTUFBYixDQUFvQk0sS0FBcEIsQ0FBUDtBQUNBLG1CQUFPTCxZQUFZLENBQUNHLGFBQWIsQ0FBMkJFLEtBQTNCLENBQVA7QUFDRDtBQUNGO0FBQ0Y7O0FBQ0QsYUFBTztBQUNMUCxRQUFBQSxRQUFRLEVBQUU7QUFDUkMsVUFBQUEsTUFBTSxFQUFFQyxZQUFZLENBQUNELE1BRGI7QUFFUkksVUFBQUEsYUFBYSxFQUFFSCxZQUFZLENBQUNHO0FBRnBCO0FBREwsT0FBUDtBQU1ELEtBdEJJLENBQVA7QUF1QkQ7O0FBRURHLEVBQUFBLGtCQUFrQixDQUFDakIsR0FBRCxFQUFNO0FBQ3RCLFFBQUlBLEdBQUcsQ0FBQ1ksSUFBSixDQUFTTSxVQUFiLEVBQXlCO0FBQ3ZCLFlBQU0sSUFBSUMsY0FBTUMsS0FBVixDQUNKRCxjQUFNQyxLQUFOLENBQVlDLG1CQURSLEVBRUoseURBRkksQ0FBTjtBQUlEOztBQUNELFVBQU1YLE1BQU0sR0FBR1YsR0FBRyxDQUFDc0IsSUFBSixDQUFTWixNQUF4QjtBQUNBLFVBQU1JLGFBQWEsR0FBR2QsR0FBRyxDQUFDc0IsSUFBSixDQUFTUixhQUFULElBQTBCLEVBQWhELENBUnNCLENBU3RCOztBQUNBLFVBQU1TLE1BQU0sR0FBR0MsTUFBTSxDQUFDQyxJQUFQLENBQVlmLE1BQVosRUFBb0JnQixNQUFwQixDQUEyQixDQUFDQyxHQUFELEVBQU1DLEdBQU4sS0FBYztBQUN0REQsTUFBQUEsR0FBRyxDQUFFLFVBQVNDLEdBQUksRUFBZixDQUFILEdBQXVCbEIsTUFBTSxDQUFDa0IsR0FBRCxDQUE3QjtBQUNBRCxNQUFBQSxHQUFHLENBQUUsaUJBQWdCQyxHQUFJLEVBQXRCLENBQUgsR0FBOEJkLGFBQWEsQ0FBQ2MsR0FBRCxDQUFiLElBQXNCLEtBQXBEO0FBQ0EsYUFBT0QsR0FBUDtBQUNELEtBSmMsRUFJWixFQUpZLENBQWY7QUFLQSxXQUFPM0IsR0FBRyxDQUFDQyxNQUFKLENBQVdDLFFBQVgsQ0FDSnFCLE1BREksQ0FDRyxlQURILEVBQ29CO0FBQUVuQixNQUFBQSxRQUFRLEVBQUU7QUFBWixLQURwQixFQUN1Q21CLE1BRHZDLEVBQytDO0FBQUVNLE1BQUFBLE1BQU0sRUFBRTtBQUFWLEtBRC9DLEVBRUp2QixJQUZJLENBRUMsT0FBTztBQUFFRyxNQUFBQSxRQUFRLEVBQUU7QUFBRXFCLFFBQUFBLE1BQU0sRUFBRTtBQUFWO0FBQVosS0FBUCxDQUZELENBQVA7QUFHRDs7QUFFREMsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxDQUFXLEtBQVgsRUFBa0IsU0FBbEIsRUFBNkJoQyxHQUFHLElBQUk7QUFDbEMsYUFBTyxLQUFLRCxlQUFMLENBQXFCQyxHQUFyQixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUtnQyxLQUFMLENBQVcsS0FBWCxFQUFrQixTQUFsQixFQUE2QkMsVUFBVSxDQUFDQyw2QkFBeEMsRUFBdUVsQyxHQUFHLElBQUk7QUFDNUUsYUFBTyxLQUFLaUIsa0JBQUwsQ0FBd0JqQixHQUF4QixDQUFQO0FBQ0QsS0FGRDtBQUdEOztBQXREbUQ7OztlQXlEdkNILGtCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gZ2xvYmFsX2NvbmZpZy5qc1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IFByb21pc2VSb3V0ZXIgZnJvbSAnLi4vUHJvbWlzZVJvdXRlcic7XG5pbXBvcnQgKiBhcyBtaWRkbGV3YXJlIGZyb20gJy4uL21pZGRsZXdhcmVzJztcblxuZXhwb3J0IGNsYXNzIEdsb2JhbENvbmZpZ1JvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBnZXRHbG9iYWxDb25maWcocmVxKSB7XG4gICAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2VcbiAgICAgIC5maW5kKCdfR2xvYmFsQ29uZmlnJywgeyBvYmplY3RJZDogJzEnIH0sIHsgbGltaXQ6IDEgfSlcbiAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggIT0gMSkge1xuICAgICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIGNvbmZpZyBpbiB0aGUgZGF0YWJhc2UgLSByZXR1cm4gZW1wdHkgY29uZmlnLlxuICAgICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7IHBhcmFtczoge30gfSB9O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGdsb2JhbENvbmZpZyA9IHJlc3VsdHNbMF07XG4gICAgICAgIGlmICghcmVxLmF1dGguaXNNYXN0ZXIgJiYgZ2xvYmFsQ29uZmlnLm1hc3RlcktleU9ubHkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGZvciAoY29uc3QgcGFyYW0gaW4gZ2xvYmFsQ29uZmlnLnBhcmFtcykge1xuICAgICAgICAgICAgaWYgKGdsb2JhbENvbmZpZy5tYXN0ZXJLZXlPbmx5W3BhcmFtXSkge1xuICAgICAgICAgICAgICBkZWxldGUgZ2xvYmFsQ29uZmlnLnBhcmFtc1twYXJhbV07XG4gICAgICAgICAgICAgIGRlbGV0ZSBnbG9iYWxDb25maWcubWFzdGVyS2V5T25seVtwYXJhbV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICAgIHBhcmFtczogZ2xvYmFsQ29uZmlnLnBhcmFtcyxcbiAgICAgICAgICAgIG1hc3RlcktleU9ubHk6IGdsb2JhbENvbmZpZy5tYXN0ZXJLZXlPbmx5LFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgfVxuXG4gIHVwZGF0ZUdsb2JhbENvbmZpZyhyZXEpIHtcbiAgICBpZiAocmVxLmF1dGguaXNSZWFkT25seSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICBcInJlYWQtb25seSBtYXN0ZXJLZXkgaXNuJ3QgYWxsb3dlZCB0byB1cGRhdGUgdGhlIGNvbmZpZy5cIlxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgcGFyYW1zID0gcmVxLmJvZHkucGFyYW1zO1xuICAgIGNvbnN0IG1hc3RlcktleU9ubHkgPSByZXEuYm9keS5tYXN0ZXJLZXlPbmx5IHx8IHt9O1xuICAgIC8vIFRyYW5zZm9ybSBpbiBkb3Qgbm90YXRpb24gdG8gbWFrZSBzdXJlIGl0IHdvcmtzXG4gICAgY29uc3QgdXBkYXRlID0gT2JqZWN0LmtleXMocGFyYW1zKS5yZWR1Y2UoKGFjYywga2V5KSA9PiB7XG4gICAgICBhY2NbYHBhcmFtcy4ke2tleX1gXSA9IHBhcmFtc1trZXldO1xuICAgICAgYWNjW2BtYXN0ZXJLZXlPbmx5LiR7a2V5fWBdID0gbWFzdGVyS2V5T25seVtrZXldIHx8IGZhbHNlO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSk7XG4gICAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2VcbiAgICAgIC51cGRhdGUoJ19HbG9iYWxDb25maWcnLCB7IG9iamVjdElkOiAnMScgfSwgdXBkYXRlLCB7IHVwc2VydDogdHJ1ZSB9KVxuICAgICAgLnRoZW4oKCkgPT4gKHsgcmVzcG9uc2U6IHsgcmVzdWx0OiB0cnVlIH0gfSkpO1xuICB9XG5cbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9jb25maWcnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0R2xvYmFsQ29uZmlnKHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnUFVUJywgJy9jb25maWcnLCBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMudXBkYXRlR2xvYmFsQ29uZmlnKHJlcSk7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgR2xvYmFsQ29uZmlnUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/GraphQLRouter.js b/lib/Routers/GraphQLRouter.js new file mode 100644 index 0000000000..67a92b3032 --- /dev/null +++ b/lib/Routers/GraphQLRouter.js @@ -0,0 +1,55 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.GraphQLRouter = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const GraphQLConfigPath = '/graphql-config'; + +class GraphQLRouter extends _PromiseRouter.default { + async getGraphQLConfig(req) { + const result = await req.config.parseGraphQLController.getGraphQLConfig(); + return { + response: result + }; + } + + async updateGraphQLConfig(req) { + if (req.auth.isReadOnly) { + throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to update the GraphQL config."); + } + + const data = await req.config.parseGraphQLController.updateGraphQLConfig(req.body.params); + return { + response: data + }; + } + + mountRoutes() { + this.route('GET', GraphQLConfigPath, middleware.promiseEnforceMasterKeyAccess, req => { + return this.getGraphQLConfig(req); + }); + this.route('PUT', GraphQLConfigPath, middleware.promiseEnforceMasterKeyAccess, req => { + return this.updateGraphQLConfig(req); + }); + } + +} + +exports.GraphQLRouter = GraphQLRouter; +var _default = GraphQLRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0dyYXBoUUxSb3V0ZXIuanMiXSwibmFtZXMiOlsiR3JhcGhRTENvbmZpZ1BhdGgiLCJHcmFwaFFMUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsImdldEdyYXBoUUxDb25maWciLCJyZXEiLCJyZXN1bHQiLCJjb25maWciLCJwYXJzZUdyYXBoUUxDb250cm9sbGVyIiwicmVzcG9uc2UiLCJ1cGRhdGVHcmFwaFFMQ29uZmlnIiwiYXV0aCIsImlzUmVhZE9ubHkiLCJQYXJzZSIsIkVycm9yIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsImRhdGEiLCJib2R5IiwicGFyYW1zIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsIm1pZGRsZXdhcmUiLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVBLE1BQU1BLGlCQUFpQixHQUFHLGlCQUExQjs7QUFFTyxNQUFNQyxhQUFOLFNBQTRCQyxzQkFBNUIsQ0FBMEM7QUFDL0MsUUFBTUMsZ0JBQU4sQ0FBdUJDLEdBQXZCLEVBQTRCO0FBQzFCLFVBQU1DLE1BQU0sR0FBRyxNQUFNRCxHQUFHLENBQUNFLE1BQUosQ0FBV0Msc0JBQVgsQ0FBa0NKLGdCQUFsQyxFQUFyQjtBQUNBLFdBQU87QUFDTEssTUFBQUEsUUFBUSxFQUFFSDtBQURMLEtBQVA7QUFHRDs7QUFFRCxRQUFNSSxtQkFBTixDQUEwQkwsR0FBMUIsRUFBK0I7QUFDN0IsUUFBSUEsR0FBRyxDQUFDTSxJQUFKLENBQVNDLFVBQWIsRUFBeUI7QUFDdkIsWUFBTSxJQUFJQyxjQUFNQyxLQUFWLENBQ0pELGNBQU1DLEtBQU4sQ0FBWUMsbUJBRFIsRUFFSixpRUFGSSxDQUFOO0FBSUQ7O0FBQ0QsVUFBTUMsSUFBSSxHQUFHLE1BQU1YLEdBQUcsQ0FBQ0UsTUFBSixDQUFXQyxzQkFBWCxDQUFrQ0UsbUJBQWxDLENBQXNETCxHQUFHLENBQUNZLElBQUosQ0FBU0MsTUFBL0QsQ0FBbkI7QUFDQSxXQUFPO0FBQ0xULE1BQUFBLFFBQVEsRUFBRU87QUFETCxLQUFQO0FBR0Q7O0FBRURHLEVBQUFBLFdBQVcsR0FBRztBQUNaLFNBQUtDLEtBQUwsQ0FBVyxLQUFYLEVBQWtCbkIsaUJBQWxCLEVBQXFDb0IsVUFBVSxDQUFDQyw2QkFBaEQsRUFBK0VqQixHQUFHLElBQUk7QUFDcEYsYUFBTyxLQUFLRCxnQkFBTCxDQUFzQkMsR0FBdEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLZSxLQUFMLENBQVcsS0FBWCxFQUFrQm5CLGlCQUFsQixFQUFxQ29CLFVBQVUsQ0FBQ0MsNkJBQWhELEVBQStFakIsR0FBRyxJQUFJO0FBQ3BGLGFBQU8sS0FBS0ssbUJBQUwsQ0FBeUJMLEdBQXpCLENBQVA7QUFDRCxLQUZEO0FBR0Q7O0FBNUI4Qzs7O2VBK0JsQ0gsYSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0ICogYXMgbWlkZGxld2FyZSBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5cbmNvbnN0IEdyYXBoUUxDb25maWdQYXRoID0gJy9ncmFwaHFsLWNvbmZpZyc7XG5cbmV4cG9ydCBjbGFzcyBHcmFwaFFMUm91dGVyIGV4dGVuZHMgUHJvbWlzZVJvdXRlciB7XG4gIGFzeW5jIGdldEdyYXBoUUxDb25maWcocmVxKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVxLmNvbmZpZy5wYXJzZUdyYXBoUUxDb250cm9sbGVyLmdldEdyYXBoUUxDb25maWcoKTtcbiAgICByZXR1cm4ge1xuICAgICAgcmVzcG9uc2U6IHJlc3VsdCxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlR3JhcGhRTENvbmZpZyhyZXEpIHtcbiAgICBpZiAocmVxLmF1dGguaXNSZWFkT25seSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICBcInJlYWQtb25seSBtYXN0ZXJLZXkgaXNuJ3QgYWxsb3dlZCB0byB1cGRhdGUgdGhlIEdyYXBoUUwgY29uZmlnLlwiXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVxLmNvbmZpZy5wYXJzZUdyYXBoUUxDb250cm9sbGVyLnVwZGF0ZUdyYXBoUUxDb25maWcocmVxLmJvZHkucGFyYW1zKTtcbiAgICByZXR1cm4ge1xuICAgICAgcmVzcG9uc2U6IGRhdGEsXG4gICAgfTtcbiAgfVxuXG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ0dFVCcsIEdyYXBoUUxDb25maWdQYXRoLCBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0R3JhcGhRTENvbmZpZyhyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ1BVVCcsIEdyYXBoUUxDb25maWdQYXRoLCBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMudXBkYXRlR3JhcGhRTENvbmZpZyhyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEdyYXBoUUxSb3V0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/HooksRouter.js b/lib/Routers/HooksRouter.js new file mode 100644 index 0000000000..b93d5e0543 --- /dev/null +++ b/lib/Routers/HooksRouter.js @@ -0,0 +1,144 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.HooksRouter = void 0; + +var _node = require("parse/node"); + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class HooksRouter extends _PromiseRouter.default { + createHook(aHook, config) { + return config.hooksController.createHook(aHook).then(hook => ({ + response: hook + })); + } + + updateHook(aHook, config) { + return config.hooksController.updateHook(aHook).then(hook => ({ + response: hook + })); + } + + handlePost(req) { + return this.createHook(req.body, req.config); + } + + handleGetFunctions(req) { + var hooksController = req.config.hooksController; + + if (req.params.functionName) { + return hooksController.getFunction(req.params.functionName).then(foundFunction => { + if (!foundFunction) { + throw new _node.Parse.Error(143, `no function named: ${req.params.functionName} is defined`); + } + + return Promise.resolve({ + response: foundFunction + }); + }); + } + + return hooksController.getFunctions().then(functions => { + return { + response: functions || [] + }; + }, err => { + throw err; + }); + } + + handleGetTriggers(req) { + var hooksController = req.config.hooksController; + + if (req.params.className && req.params.triggerName) { + return hooksController.getTrigger(req.params.className, req.params.triggerName).then(foundTrigger => { + if (!foundTrigger) { + throw new _node.Parse.Error(143, `class ${req.params.className} does not exist`); + } + + return Promise.resolve({ + response: foundTrigger + }); + }); + } + + return hooksController.getTriggers().then(triggers => ({ + response: triggers || [] + })); + } + + handleDelete(req) { + var hooksController = req.config.hooksController; + + if (req.params.functionName) { + return hooksController.deleteFunction(req.params.functionName).then(() => ({ + response: {} + })); + } else if (req.params.className && req.params.triggerName) { + return hooksController.deleteTrigger(req.params.className, req.params.triggerName).then(() => ({ + response: {} + })); + } + + return Promise.resolve({ + response: {} + }); + } + + handleUpdate(req) { + var hook; + + if (req.params.functionName && req.body.url) { + hook = {}; + hook.functionName = req.params.functionName; + hook.url = req.body.url; + } else if (req.params.className && req.params.triggerName && req.body.url) { + hook = {}; + hook.className = req.params.className; + hook.triggerName = req.params.triggerName; + hook.url = req.body.url; + } else { + throw new _node.Parse.Error(143, 'invalid hook declaration'); + } + + return this.updateHook(hook, req.config); + } + + handlePut(req) { + var body = req.body; + + if (body.__op == 'Delete') { + return this.handleDelete(req); + } else { + return this.handleUpdate(req); + } + } + + mountRoutes() { + this.route('GET', '/hooks/functions', middleware.promiseEnforceMasterKeyAccess, this.handleGetFunctions.bind(this)); + this.route('GET', '/hooks/triggers', middleware.promiseEnforceMasterKeyAccess, this.handleGetTriggers.bind(this)); + this.route('GET', '/hooks/functions/:functionName', middleware.promiseEnforceMasterKeyAccess, this.handleGetFunctions.bind(this)); + this.route('GET', '/hooks/triggers/:className/:triggerName', middleware.promiseEnforceMasterKeyAccess, this.handleGetTriggers.bind(this)); + this.route('POST', '/hooks/functions', middleware.promiseEnforceMasterKeyAccess, this.handlePost.bind(this)); + this.route('POST', '/hooks/triggers', middleware.promiseEnforceMasterKeyAccess, this.handlePost.bind(this)); + this.route('PUT', '/hooks/functions/:functionName', middleware.promiseEnforceMasterKeyAccess, this.handlePut.bind(this)); + this.route('PUT', '/hooks/triggers/:className/:triggerName', middleware.promiseEnforceMasterKeyAccess, this.handlePut.bind(this)); + } + +} + +exports.HooksRouter = HooksRouter; +var _default = HooksRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0hvb2tzUm91dGVyLmpzIl0sIm5hbWVzIjpbIkhvb2tzUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsImNyZWF0ZUhvb2siLCJhSG9vayIsImNvbmZpZyIsImhvb2tzQ29udHJvbGxlciIsInRoZW4iLCJob29rIiwicmVzcG9uc2UiLCJ1cGRhdGVIb29rIiwiaGFuZGxlUG9zdCIsInJlcSIsImJvZHkiLCJoYW5kbGVHZXRGdW5jdGlvbnMiLCJwYXJhbXMiLCJmdW5jdGlvbk5hbWUiLCJnZXRGdW5jdGlvbiIsImZvdW5kRnVuY3Rpb24iLCJQYXJzZSIsIkVycm9yIiwiUHJvbWlzZSIsInJlc29sdmUiLCJnZXRGdW5jdGlvbnMiLCJmdW5jdGlvbnMiLCJlcnIiLCJoYW5kbGVHZXRUcmlnZ2VycyIsImNsYXNzTmFtZSIsInRyaWdnZXJOYW1lIiwiZ2V0VHJpZ2dlciIsImZvdW5kVHJpZ2dlciIsImdldFRyaWdnZXJzIiwidHJpZ2dlcnMiLCJoYW5kbGVEZWxldGUiLCJkZWxldGVGdW5jdGlvbiIsImRlbGV0ZVRyaWdnZXIiLCJoYW5kbGVVcGRhdGUiLCJ1cmwiLCJoYW5kbGVQdXQiLCJfX29wIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsIm1pZGRsZXdhcmUiLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyIsImJpbmQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFTyxNQUFNQSxXQUFOLFNBQTBCQyxzQkFBMUIsQ0FBd0M7QUFDN0NDLEVBQUFBLFVBQVUsQ0FBQ0MsS0FBRCxFQUFRQyxNQUFSLEVBQWdCO0FBQ3hCLFdBQU9BLE1BQU0sQ0FBQ0MsZUFBUCxDQUF1QkgsVUFBdkIsQ0FBa0NDLEtBQWxDLEVBQXlDRyxJQUF6QyxDQUE4Q0MsSUFBSSxLQUFLO0FBQUVDLE1BQUFBLFFBQVEsRUFBRUQ7QUFBWixLQUFMLENBQWxELENBQVA7QUFDRDs7QUFFREUsRUFBQUEsVUFBVSxDQUFDTixL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QixDQUpGO0FBTUEsU0FBS0gsS0FBTCxDQUNFLE1BREYsRUFFRSxrQkFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUUsS0FBS2hDLFVBQUwsQ0FBZ0JpQyxJQUFoQixDQUFxQixJQUFyQixDQUpGO0FBTUEsU0FBS0gsS0FBTCxDQUNFLE1BREYsRUFFRSxpQkFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUUsS0FBS2hDLFVBQUwsQ0FBZ0JpQyxJQUFoQixDQUFxQixJQUFyQixDQUpGO0FBTUEsU0FBS0gsS0FBTCxDQUNFLEtBREYsRUFFRSxnQ0FGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUUsS0FBS0wsU0FBTCxDQUFlTSxJQUFmLENBQW9CLElBQXBCLENBSkY7QUFNQSxTQUFLSCxLQUFMLENBQ0UsS0FERixFQUVFLHlDQUZGLEVBR0VDLFVBQVUsQ0FBQ0MsNkJBSGIsRUFJRSxLQUFLTCxTQUFMLENBQWVNLElBQWYsQ0FBb0IsSUFBcEIsQ0FKRjtBQU1EOztBQXpJNEM7OztlQTRJaEMzQyxXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUGFyc2UgfSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0ICogYXMgbWlkZGxld2FyZSBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5cbmV4cG9ydCBjbGFzcyBIb29rc1JvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBjcmVhdGVIb29rKGFIb29rLCBjb25maWcpIHtcbiAgICByZXR1cm4gY29uZmlnLmhvb2tzQ29udHJvbGxlci5jcmVhdGVIb29rKGFIb29rKS50aGVuKGhvb2sgPT4gKHsgcmVzcG9uc2U6IGhvb2sgfSkpO1xuICB9XG5cbiAgdXBkYXRlSG9vayhhSG9vaywgY29uZmlnKSB7XG4gICAgcmV0dXJuIGNvbmZpZy5ob29rc0NvbnRyb2xsZXIudXBkYXRlSG9vayhhSG9vaykudGhlbihob29rID0+ICh7IHJlc3BvbnNlOiBob29rIH0pKTtcbiAgfVxuXG4gIGhhbmRsZVBvc3QocmVxKSB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlSG9vayhyZXEuYm9keSwgcmVxLmNvbmZpZyk7XG4gIH1cblxuICBoYW5kbGVHZXRGdW5jdGlvbnMocmVxKSB7XG4gICAgdmFyIGhvb2tzQ29udHJvbGxlciA9IHJlcS5jb25maWcuaG9va3NDb250cm9sbGVyO1xuICAgIGlmIChyZXEucGFyYW1zLmZ1bmN0aW9uTmFtZSkge1xuICAgICAgcmV0dXJuIGhvb2tzQ29udHJvbGxlci5nZXRGdW5jdGlvbihyZXEucGFyYW1zLmZ1bmN0aW9uTmFtZSkudGhlbihmb3VuZEZ1bmN0aW9uID0+IHtcbiAgICAgICAgaWYgKCFmb3VuZEZ1bmN0aW9uKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDE0MywgYG5vIGZ1bmN0aW9uIG5hbWVkOiAke3JlcS5wYXJhbXMuZnVuY3Rpb25OYW1lfSBpcyBkZWZpbmVkYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHJlc3BvbnNlOiBmb3VuZEZ1bmN0aW9uIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGhvb2tzQ29udHJvbGxlci5nZXRGdW5jdGlvbnMoKS50aGVuKFxuICAgICAgZnVuY3Rpb25zID0+IHtcbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IGZ1bmN0aW9ucyB8fCBbXSB9O1xuICAgICAgfSxcbiAgICAgIGVyciA9PiB7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgaGFuZGxlR2V0VHJpZ2dlcnMocmVxKSB7XG4gICAgdmFyIGhvb2tzQ29udHJvbGxlciA9IHJlcS5jb25maWcuaG9va3NDb250cm9sbGVyO1xuICAgIGlmIChyZXEucGFyYW1zLmNsYXNzTmFtZSAmJiByZXEucGFyYW1zLnRyaWdnZXJOYW1lKSB7XG4gICAgICByZXR1cm4gaG9va3NDb250cm9sbGVyXG4gICAgICAgIC5nZXRUcmlnZ2VyKHJlcS5wYXJhbXMuY2xhc3NOYW1lLCByZXEucGFyYW1zLnRyaWdnZXJOYW1lKVxuICAgICAgICAudGhlbihmb3VuZFRyaWdnZXIgPT4ge1xuICAgICAgICAgIGlmICghZm91bmRUcmlnZ2VyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTQzLCBgY2xhc3MgJHtyZXEucGFyYW1zLmNsYXNzTmFtZX0gZG9lcyBub3QgZXhpc3RgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHJlc3BvbnNlOiBmb3VuZFRyaWdnZXIgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBob29rc0NvbnRyb2xsZXIuZ2V0VHJpZ2dlcnMoKS50aGVuKHRyaWdnZXJzID0+ICh7IHJlc3BvbnNlOiB0cmlnZ2VycyB8fCBbXSB9KSk7XG4gIH1cblxuICBoYW5kbGVEZWxldGUocmVxKSB7XG4gICAgdmFyIGhvb2tzQ29udHJvbGxlciA9IHJlcS5jb25maWcuaG9va3NDb250cm9sbGVyO1xuICAgIGlmIChyZXEucGFyYW1zLmZ1bmN0aW9uTmFtZSkge1xuICAgICAgcmV0dXJuIGhvb2tzQ29udHJvbGxlci5kZWxldGVGdW5jdGlvbihyZXEucGFyYW1zLmZ1bmN0aW9uTmFtZSkudGhlbigoKSA9PiAoeyByZXNwb25zZToge30gfSkpO1xuICAgIH0gZWxzZSBpZiAocmVxLnBhcmFtcy5jbGFzc05hbWUgJiYgcmVxLnBhcmFtcy50cmlnZ2VyTmFtZSkge1xuICAgICAgcmV0dXJuIGhvb2tzQ29udHJvbGxlclxuICAgICAgICAuZGVsZXRlVHJpZ2dlcihyZXEucGFyYW1zLmNsYXNzTmFtZSwgcmVxLnBhcmFtcy50cmlnZ2VyTmFtZSlcbiAgICAgICAgLnRoZW4oKCkgPT4gKHsgcmVzcG9uc2U6IHt9IH0pKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHJlc3BvbnNlOiB7fSB9KTtcbiAgfVxuXG4gIGhhbmRsZVVwZGF0ZShyZXEpIHtcbiAgICB2YXIgaG9vaztcbiAgICBpZiAocmVxLnBhcmFtcy5mdW5jdGlvbk5hbWUgJiYgcmVxLmJvZHkudXJsKSB7XG4gICAgICBob29rID0ge307XG4gICAgICBob29rLmZ1bmN0aW9uTmFtZSA9IHJlcS5wYXJhbXMuZnVuY3Rpb25OYW1lO1xuICAgICAgaG9vay51cmwgPSByZXEuYm9keS51cmw7XG4gICAgfSBlbHNlIGlmIChyZXEucGFyYW1zLmNsYXNzTmFtZSAmJiByZXEucGFyYW1zLnRyaWdnZXJOYW1lICYmIHJlcS5ib2R5LnVybCkge1xuICAgICAgaG9vayA9IHt9O1xuICAgICAgaG9vay5jbGFzc05hbWUgPSByZXEucGFyYW1zLmNsYXNzTmFtZTtcbiAgICAgIGhvb2sudHJpZ2dlck5hbWUgPSByZXEucGFyYW1zLnRyaWdnZXJOYW1lO1xuICAgICAgaG9vay51cmwgPSByZXEuYm9keS51cmw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigxNDMsICdpbnZhbGlkIGhvb2sgZGVjbGFyYXRpb24nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlSG9vayhob29rLCByZXEuY29uZmlnKTtcbiAgfVxuXG4gIGhhbmRsZVB1dChyZXEpIHtcbiAgICB2YXIgYm9keSA9IHJlcS5ib2R5O1xuICAgIGlmIChib2R5Ll9fb3AgPT0gJ0RlbGV0ZScpIHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZURlbGV0ZShyZXEpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVVcGRhdGUocmVxKTtcbiAgICB9XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2hvb2tzL2Z1bmN0aW9ucycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVHZXRGdW5jdGlvbnMuYmluZCh0aGlzKVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdHRVQnLFxuICAgICAgJy9ob29rcy90cmlnZ2VycycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVHZXRUcmlnZ2Vycy5iaW5kKHRoaXMpXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2hvb2tzL2Z1bmN0aW9ucy86ZnVuY3Rpb25OYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICB0aGlzLmhhbmRsZUdldEZ1bmN0aW9ucy5iaW5kKHRoaXMpXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2hvb2tzL3RyaWdnZXJzLzpjbGFzc05hbWUvOnRyaWdnZXJOYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICB0aGlzLmhhbmRsZUdldFRyaWdnZXJzLmJpbmQodGhpcylcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnUE9TVCcsXG4gICAgICAnL2hvb2tzL2Z1bmN0aW9ucycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVQb3N0LmJpbmQodGhpcylcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnUE9TVCcsXG4gICAgICAnL2hvb2tzL3RyaWdnZXJzJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICB0aGlzLmhhbmRsZVBvc3QuYmluZCh0aGlzKVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdQVVQnLFxuICAgICAgJy9ob29rcy9mdW5jdGlvbnMvOmZ1bmN0aW9uTmFtZScsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVQdXQuYmluZCh0aGlzKVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdQVVQnLFxuICAgICAgJy9ob29rcy90cmlnZ2Vycy86Y2xhc3NOYW1lLzp0cmlnZ2VyTmFtZScsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVQdXQuYmluZCh0aGlzKVxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSG9va3NSb3V0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/IAPValidationRouter.js b/lib/Routers/IAPValidationRouter.js new file mode 100644 index 0000000000..f0ba814941 --- /dev/null +++ b/lib/Routers/IAPValidationRouter.js @@ -0,0 +1,136 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.IAPValidationRouter = void 0; + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var _node = _interopRequireDefault(require("parse/node")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const request = require('../request'); + +const rest = require('../rest'); + +// TODO move validation logic in IAPValidationController +const IAP_SANDBOX_URL = 'https://sandbox.itunes.apple.com/verifyReceipt'; +const IAP_PRODUCTION_URL = 'https://buy.itunes.apple.com/verifyReceipt'; +const APP_STORE_ERRORS = { + 21000: 'The App Store could not read the JSON object you provided.', + 21002: 'The data in the receipt-data property was malformed or missing.', + 21003: 'The receipt could not be authenticated.', + 21004: 'The shared secret you provided does not match the shared secret on file for your account.', + 21005: 'The receipt server is not currently available.', + 21006: 'This receipt is valid but the subscription has expired.', + 21007: 'This receipt is from the test environment, but it was sent to the production environment for verification. Send it to the test environment instead.', + 21008: 'This receipt is from the production environment, but it was sent to the test environment for verification. Send it to the production environment instead.' +}; + +function appStoreError(status) { + status = parseInt(status); + var errorString = APP_STORE_ERRORS[status] || 'unknown error.'; + return { + status: status, + error: errorString + }; +} + +function validateWithAppStore(url, receipt) { + return request({ + url: url, + method: 'POST', + body: { + 'receipt-data': receipt + }, + headers: { + 'Content-Type': 'application/json' + } + }).then(httpResponse => { + const body = httpResponse.data; + + if (body && body.status === 0) { + // No need to pass anything, status is OK + return; + } // receipt is from test and should go to test + + + throw body; + }); +} + +function getFileForProductIdentifier(productIdentifier, req) { + return rest.find(req.config, req.auth, '_Product', { + productIdentifier: productIdentifier + }, undefined, req.info.clientSDK, req.info.context).then(function (result) { + const products = result.results; + + if (!products || products.length != 1) { + // Error not found or too many + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); + } + + var download = products[0].download; + return Promise.resolve({ + response: download + }); + }); +} + +class IAPValidationRouter extends _PromiseRouter.default { + handleRequest(req) { + let receipt = req.body.receipt; + const productIdentifier = req.body.productIdentifier; + + if (!receipt || !productIdentifier) { + // TODO: Error, malformed request + throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'missing receipt or productIdentifier'); + } // Transform the object if there + // otherwise assume it's in Base64 already + + + if (typeof receipt == 'object') { + if (receipt['__type'] == 'Bytes') { + receipt = receipt.base64; + } + } + + if (process.env.TESTING == '1' && req.body.bypassAppStoreValidation) { + return getFileForProductIdentifier(productIdentifier, req); + } + + function successCallback() { + return getFileForProductIdentifier(productIdentifier, req); + } + + function errorCallback(error) { + return Promise.resolve({ + response: appStoreError(error.status) + }); + } + + return validateWithAppStore(IAP_PRODUCTION_URL, receipt).then(() => { + return successCallback(); + }, error => { + if (error.status == 21007) { + return validateWithAppStore(IAP_SANDBOX_URL, receipt).then(() => { + return successCallback(); + }, error => { + return errorCallback(error); + }); + } + + return errorCallback(error); + }); + } + + mountRoutes() { + this.route('POST', '/validate_purchase', this.handleRequest); + } + +} + +exports.IAPValidationRouter = IAPValidationRouter; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0lBUFZhbGlkYXRpb25Sb3V0ZXIuanMiXSwibmFtZXMiOlsicmVxdWVzdCIsInJlcXVpcmUiLCJyZXN0IiwiSUFQX1NBTkRCT1hfVVJMIiwiSUFQX1BST0RVQ1RJT05fVVJMIiwiQVBQX1NUT1JFX0VSUk9SUyIsImFwcFN0b3JlRXJyb3IiLCJzdGF0dXMiLCJwYXJzZUludCIsImVycm9yU3RyaW5nIiwiZXJyb3IiLCJ2YWxpZGF0ZVdpdGhBcHBTdG9yZSIsInVybCIsInJlY2VpcHQiLCJtZXRob2QiLCJib2R5IiwiaGVhZGVycyIsInRoZW4iLCJodHRwUmVzcG9uc2UiLCJkYXRhIiwiZ2V0RmlsZUZvclByb2R1Y3RJZGVudGlmaWVyIiwicHJvZHVjdElkZW50aWZpZXIiLCJyZXEiLCJmaW5kIiwiY29uZmlnIiwiYXV0aCIsInVuZGVmaW5lZCIsImluZm8iLCJjbGllbnRTREsiLCJjb250ZXh0IiwicmVzdWx0IiwicHJvZHVjdHMiLCJyZXN1bHRzIiwibGVuZ3RoIiwiUGFyc2UiLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJkb3dubG9hZCIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVzcG9uc2UiLCJJQVBWYWxpZGF0aW9uUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsImhhbmRsZVJlcXVlc3QiLCJJTlZBTElEX0pTT04iLCJiYXNlNjQiLCJwcm9jZXNzIiwiZW52IiwiVEVTVElORyIsImJ5cGFzc0FwcFN0b3JlVmFsaWRhdGlvbiIsInN1Y2Nlc3NDYWxsYmFjayIsImVycm9yQ2FsbGJhY2siLCJtb3VudFJvdXRlcyIsInJvdXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBR0E7Ozs7QUFGQSxNQUFNQSxPQUFPLEdBQUdDLE9BQU8sQ0FBQyxZQUFELENBQXZCOztBQUNBLE1BQU1DLElBQUksR0FBR0QsT0FBTyxDQUFDLFNBQUQsQ0FBcEI7O0FBR0E7QUFDQSxNQUFNRSxlQUFlLEdBQUcsZ0RBQXhCO0FBQ0EsTUFB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O0FBbUJEOztBQUVEMEMsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxDQUFXLE1BQVgsRUFBbUIsb0JBQW5CLEVBQXlDLEtBQUtWLGFBQTlDO0FBQ0Q7O0FBckRvRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuY29uc3QgcmVxdWVzdCA9IHJlcXVpcmUoJy4uL3JlcXVlc3QnKTtcbmNvbnN0IHJlc3QgPSByZXF1aXJlKCcuLi9yZXN0Jyk7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5cbi8vIFRPRE8gbW92ZSB2YWxpZGF0aW9uIGxvZ2ljIGluIElBUFZhbGlkYXRpb25Db250cm9sbGVyXG5jb25zdCBJQVBfU0FOREJPWF9VUkwgPSAnaHR0cHM6Ly9zYW5kYm94Lml0dW5lcy5hcHBsZS5jb20vdmVyaWZ5UmVjZWlwdCc7XG5jb25zdCBJQVBfUFJPRFVDVElPTl9VUkwgPSAnaHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS92ZXJpZnlSZWNlaXB0JztcblxuY29uc3QgQVBQX1NUT1JFX0VSUk9SUyA9IHtcbiAgMjEwMDA6ICdUaGUgQXBwIFN0b3JlIGNvdWxkIG5vdCByZWFkIHRoZSBKU09OIG9iamVjdCB5b3UgcHJvdmlkZWQuJyxcbiAgMjEwMDI6ICdUaGUgZGF0YSBpbiB0aGUgcmVjZWlwdC1kYXRhIHByb3BlcnR5IHdhcyBtYWxmb3JtZWQgb3IgbWlzc2luZy4nLFxuICAyMTAwMzogJ1RoZSByZWNlaXB0IGNvdWxkIG5vdCBiZSBhdXRoZW50aWNhdGVkLicsXG4gIDIxMDA0OiAnVGhlIHNoYXJlZCBzZWNyZXQgeW91IHByb3ZpZGVkIGRvZXMgbm90IG1hdGNoIHRoZSBzaGFyZWQgc2VjcmV0IG9uIGZpbGUgZm9yIHlvdXIgYWNjb3VudC4nLFxuICAyMTAwNTogJ1RoZSByZWNlaXB0IHNlcnZlciBpcyBub3QgY3VycmVudGx5IGF2YWlsYWJsZS4nLFxuICAyMTAwNjogJ1RoaXMgcmVjZWlwdCBpcyB2YWxpZCBidXQgdGhlIHN1YnNjcmlwdGlvbiBoYXMgZXhwaXJlZC4nLFxuICAyMTAwNzogJ1RoaXMgcmVjZWlwdCBpcyBmcm9tIHRoZSB0ZXN0IGVudmlyb25tZW50LCBidXQgaXQgd2FzIHNlbnQgdG8gdGhlIHByb2R1Y3Rpb24gZW52aXJvbm1lbnQgZm9yIHZlcmlmaWNhdGlvbi4gU2VuZCBpdCB0byB0aGUgdGVzdCBlbnZpcm9ubWVudCBpbnN0ZWFkLicsXG4gIDIxMDA4OiAnVGhpcyByZWNlaXB0IGlzIGZyb20gdGhlIHByb2R1Y3Rpb24gZW52aXJvbm1lbnQsIGJ1dCBpdCB3YXMgc2VudCB0byB0aGUgdGVzdCBlbnZpcm9ubWVudCBmb3IgdmVyaWZpY2F0aW9uLiBTZW5kIGl0IHRvIHRoZSBwcm9kdWN0aW9uIGVudmlyb25tZW50IGluc3RlYWQuJyxcbn07XG5cbmZ1bmN0aW9uIGFwcFN0b3JlRXJyb3Ioc3RhdHVzKSB7XG4gIHN0YXR1cyA9IHBhcnNlSW50KHN0YXR1cyk7XG4gIHZhciBlcnJvclN0cmluZyA9IEFQUF9TVE9SRV9FUlJPUlNbc3RhdHVzXSB8fCAndW5rbm93biBlcnJvci4nO1xuICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cywgZXJyb3I6IGVycm9yU3RyaW5nIH07XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlV2l0aEFwcFN0b3JlKHVybCwgcmVjZWlwdCkge1xuICByZXR1cm4gcmVxdWVzdCh7XG4gICAgdXJsOiB1cmwsXG4gICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgYm9keTogeyAncmVjZWlwdC1kYXRhJzogcmVjZWlwdCB9LFxuICAgIGhlYWRlcnM6IHtcbiAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgfSxcbiAgfSkudGhlbihodHRwUmVzcG9uc2UgPT4ge1xuICAgIGNvbnN0IGJvZHkgPSBodHRwUmVzcG9uc2UuZGF0YTtcbiAgICBpZiAoYm9keSAmJiBib2R5LnN0YXR1cyA9PT0gMCkge1xuICAgICAgLy8gTm8gbmVlZCB0byBwYXNzIGFueXRoaW5nLCBzdGF0dXMgaXMgT0tcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gcmVjZWlwdCBpcyBmcm9tIHRlc3QgYW5kIHNob3VsZCBnbyB0byB0ZXN0XG4gICAgdGhyb3cgYm9keTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldEZpbGVGb3JQcm9kdWN0SWRlbnRpZmllcihwcm9kdWN0SWRlbnRpZmllciwgcmVxKSB7XG4gIHJldHVybiByZXN0XG4gICAgLmZpbmQoXG4gICAgICByZXEuY29uZmlnLFxuICAgICAgcmVxLmF1dGgsXG4gICAgICAnX1Byb2R1Y3QnLFxuICAgICAgeyBwcm9kdWN0SWRlbnRpZmllcjogcHJvZHVjdElkZW50aWZpZXIgfSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICApXG4gICAgLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgY29uc3QgcHJvZHVjdHMgPSByZXN1bHQucmVzdWx0cztcbiAgICAgIGlmICghcHJvZHVjdHMgfHwgcHJvZHVjdHMubGVuZ3RoICE9IDEpIHtcbiAgICAgICAgLy8gRXJyb3Igbm90IGZvdW5kIG9yIHRvbyBtYW55XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnT2JqZWN0IG5vdCBmb3VuZC4nKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGRvd25sb2FkID0gcHJvZHVjdHNbMF0uZG93bmxvYWQ7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHsgcmVzcG9uc2U6IGRvd25sb2FkIH0pO1xuICAgIH0pO1xufVxuXG5leHBvcnQgY2xhc3MgSUFQVmFsaWRhdGlvblJvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBoYW5kbGVSZXF1ZXN0KHJlcSkge1xuICAgIGxldCByZWNlaXB0ID0gcmVxLmJvZHkucmVjZWlwdDtcbiAgICBjb25zdCBwcm9kdWN0SWRlbnRpZmllciA9IHJlcS5ib2R5LnByb2R1Y3RJZGVudGlmaWVyO1xuXG4gICAgaWYgKCFyZWNlaXB0IHx8ICFwcm9kdWN0SWRlbnRpZmllcikge1xuICAgICAgLy8gVE9ETzogRXJyb3IsIG1hbGZvcm1lZCByZXF1ZXN0XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnbWlzc2luZyByZWNlaXB0IG9yIHByb2R1Y3RJZGVudGlmaWVyJyk7XG4gICAgfVxuXG4gICAgLy8gVHJhbnNmb3JtIHRoZSBvYmplY3QgaWYgdGhlcmVcbiAgICAvLyBvdGhlcndpc2UgYXNzdW1lIGl0J3MgaW4gQmFzZTY0IGFscmVhZHlcbiAgICBpZiAodHlwZW9mIHJlY2VpcHQgPT0gJ29iamVjdCcpIHtcbiAgICAgIGlmIChyZWNlaXB0WydfX3R5cGUnXSA9PSAnQnl0ZXMnKSB7XG4gICAgICAgIHJlY2VpcHQgPSByZWNlaXB0LmJhc2U2NDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocHJvY2Vzcy5lbnYuVEVTVElORyA9PSAnMScgJiYgcmVxLmJvZHkuYnlwYXNzQXBwU3RvcmVWYWxpZGF0aW9uKSB7XG4gICAgICByZXR1cm4gZ2V0RmlsZUZvclByb2R1Y3RJZGVudGlmaWVyKHByb2R1Y3RJZGVudGlmaWVyLCByZXEpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN1Y2Nlc3NDYWxsYmFjaygpIHtcbiAgICAgIHJldHVybiBnZXRGaWxlRm9yUHJvZHVjdElkZW50aWZpZXIocHJvZHVjdElkZW50aWZpZXIsIHJlcSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXJyb3JDYWxsYmFjayhlcnJvcikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHJlc3BvbnNlOiBhcHBTdG9yZUVycm9yKGVycm9yLnN0YXR1cykgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbGlkYXRlV2l0aEFwcFN0b3JlKElBUF9QUk9EVUNUSU9OX1VSTCwgcmVjZWlwdCkudGhlbihcbiAgICAgICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHN1Y2Nlc3NDYWxsYmFjaygpO1xuICAgICAgfSxcbiAgICAgIGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLnN0YXR1cyA9PSAyMTAwNykge1xuICAgICAgICAgIHJldHVybiB2YWxpZGF0ZVdpdGhBcHBTdG9yZShJQVBfU0FOREJPWF9VUkwsIHJlY2VpcHQpLnRoZW4oXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBzdWNjZXNzQ2FsbGJhY2soKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvciA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBlcnJvckNhbGxiYWNrKGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy92YWxpZGF0ZV9wdXJjaGFzZScsIHRoaXMuaGFuZGxlUmVxdWVzdCk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/InstallationsRouter.js b/lib/Routers/InstallationsRouter.js new file mode 100644 index 0000000000..62b677126a --- /dev/null +++ b/lib/Routers/InstallationsRouter.js @@ -0,0 +1,57 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.InstallationsRouter = void 0; + +var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); + +var _rest = _interopRequireDefault(require("../rest")); + +var _middlewares = require("../middlewares"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// InstallationsRouter.js +class InstallationsRouter extends _ClassesRouter.default { + className() { + return '_Installation'; + } + + handleFind(req) { + const body = Object.assign(req.body, _ClassesRouter.default.JSONFromQuery(req.query)); + + const options = _ClassesRouter.default.optionsFromBody(body); + + return _rest.default.find(req.config, req.auth, '_Installation', body.where, options, req.info.clientSDK, req.info.context).then(response => { + return { + response: response + }; + }); + } + + mountRoutes() { + this.route('GET', '/installations', req => { + return this.handleFind(req); + }); + this.route('GET', '/installations/:objectId', req => { + return this.handleGet(req); + }); + this.route('POST', '/installations', _middlewares.promiseEnsureIdempotency, req => { + return this.handleCreate(req); + }); + this.route('PUT', '/installations/:objectId', _middlewares.promiseEnsureIdempotency, req => { + return this.handleUpdate(req); + }); + this.route('DELETE', '/installations/:objectId', req => { + return this.handleDelete(req); + }); + } + +} + +exports.InstallationsRouter = InstallationsRouter; +var _default = InstallationsRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0luc3RhbGxhdGlvbnNSb3V0ZXIuanMiXSwibmFtZXMiOlsiSW5zdGFsbGF0aW9uc1JvdXRlciIsIkNsYXNzZXNSb3V0ZXIiLCJjbGFzc05hbWUiLCJoYW5kbGVGaW5kIiwicmVxIiwiYm9keSIsIk9iamVjdCIsImFzc2lnbiIsIkpTT05Gcm9tUXVlcnkiLCJxdWVyeSIsIm9wdGlvbnMiLCJvcHRpb25zRnJvbUJvZHkiLCJyZXN0IiwiZmluZCIsImNvbmZpZyIsImF1dGgiLCJ3aGVyZSIsImluZm8iLCJjbGllbnRTREsiLCJjb250ZXh0IiwidGhlbiIsInJlc3BvbnNlIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsImhhbmRsZUdldCIsInByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSIsImhhbmRsZUNyZWF0ZSIsImhhbmRsZVVwZGF0ZSIsImhhbmRsZURlbGV0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUVBOztBQUNBOztBQUNBOzs7O0FBSkE7QUFNTyxNQUFNQSxtQkFBTixTQUFrQ0Msc0JBQWxDLENBQWdEO0FBQ3JEQyxFQUFBQSxTQUFTLEdBQUc7QUFDVixXQUFPLGVBQVA7QUFDRDs7QUFFREMsRUFBQUEsVUFBVSxDQUFDQyxHQUFELEVBQU07QUFDZCxVQUFNQyxJQUFJLEdBQUdDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjSCxHQUFHLENBQUNDLElBQWxCLEVBQXdCSix1QkFBY08sYUFBZCxDQUE0QkosR0FBRyxDQUFDSyxLQUFoQyxDQUF4QixDQUFiOztBQUNBLFVBQU1DLE9BQU8sR0FBR1QsdUJBQWNVLGVBQWQsQ0FBOEJOLElBQTlCLENBQWhCOztBQUNBLFdBQU9PLGNBQ0pDLElBREksQ0FFSFQsR0FBRyxDQUFDVSxNQUZELEVBR0hWLEdBQUcsQ0FBQ1csSUFIRCxFQUlILGVBSkcsRUFLSFYsSUFBSSxDQUFDVyxLQUxGLEVBTUhOLE9BTkcsRUFPSE4sR0FBRyxDQUFDYSxJQUFKLENBQVNDLFNBUE4sRUFRSGQsR0FBRyxDQUFDYSxJQUFKLENBQVNFLE9BUk4sRUFVSkMsSUFWSSxDQVVDQyxRQUFRLElBQUk7QUFDaEIsYUFBTztBQUFFQSxRQUFBQSxRQUFRLEVBQUVBO0FBQVosT0FBUDtBQUNELEtBWkksQ0FBUDtBQWFEOztBQUVEQyxFQUFBQSxXQUFXLEdBQUc7QUFDWixTQUFLQyxLQUFMLENBQVcsS0FBWCxFQUFrQixnQkFBbEIsRUFBb0NuQixHQUFHLElBQUk7QUFDekMsYUFBTyxLQUFLRCxVQUFMLENBQWdCQyxHQUFoQixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUttQixLQUFMLENBQVcsS0FBWCxFQUFrQiwwQkFBbEIsRUFBOENuQixHQUFHLElBQUk7QUFDbkQsYUFBTyxLQUFLb0IsU0FBTCxDQUFlcEIsR0FBZixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUttQixLQUFMLENBQVcsTUFBWCxFQUFtQixnQkFBbkIsRUFBcUNFLHFDQUFyQyxFQUErRHJCLEdBQUcsSUFBSTtBQUNwRSxhQUFPLEtBQUtzQixZQUFMLENBQWtCdEIsR0FBbEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLbUIsS0FBTCxDQUFXLEtBQVgsRUFBa0IsMEJBQWxCLEVBQThDRSxxQ0FBOUMsRUFBd0VyQixHQUFHLElBQUk7QUFDN0UsYUFBTyxLQUFLdUIsWUFBTCxDQUFrQnZCLEdBQWxCLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBS21CLEtBQUwsQ0FBVyxRQUFYLEVBQXFCLDBCQUFyQixFQUFpRG5CLEdBQUcsSUFBSTtBQUN0RCxhQUFPLEtBQUt3QixZQUFMLENBQWtCeEIsR0FBbEIsQ0FBUDtBQUNELEtBRkQ7QUFHRDs7QUF2Q29EOzs7ZUEwQ3hDSixtQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEluc3RhbGxhdGlvbnNSb3V0ZXIuanNcblxuaW1wb3J0IENsYXNzZXNSb3V0ZXIgZnJvbSAnLi9DbGFzc2VzUm91dGVyJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IHsgcHJvbWlzZUVuc3VyZUlkZW1wb3RlbmN5IH0gZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5leHBvcnQgY2xhc3MgSW5zdGFsbGF0aW9uc1JvdXRlciBleHRlbmRzIENsYXNzZXNSb3V0ZXIge1xuICBjbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICdfSW5zdGFsbGF0aW9uJztcbiAgfVxuXG4gIGhhbmRsZUZpbmQocmVxKSB7XG4gICAgY29uc3QgYm9keSA9IE9iamVjdC5hc3NpZ24ocmVxLmJvZHksIENsYXNzZXNSb3V0ZXIuSlNPTkZyb21RdWVyeShyZXEucXVlcnkpKTtcbiAgICBjb25zdCBvcHRpb25zID0gQ2xhc3Nlc1JvdXRlci5vcHRpb25zRnJvbUJvZHkoYm9keSk7XG4gICAgcmV0dXJuIHJlc3RcbiAgICAgIC5maW5kKFxuICAgICAgICByZXEuY29uZmlnLFxuICAgICAgICByZXEuYXV0aCxcbiAgICAgICAgJ19JbnN0YWxsYXRpb24nLFxuICAgICAgICBib2R5LndoZXJlLFxuICAgICAgICBvcHRpb25zLFxuICAgICAgICByZXEuaW5mby5jbGllbnRTREssXG4gICAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHJlc3BvbnNlIH07XG4gICAgICB9KTtcbiAgfVxuXG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvaW5zdGFsbGF0aW9ucycsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVGaW5kKHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9pbnN0YWxsYXRpb25zLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9pbnN0YWxsYXRpb25zJywgcHJvbWlzZUVuc3VyZUlkZW1wb3RlbmN5LCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlQ3JlYXRlKHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnUFVUJywgJy9pbnN0YWxsYXRpb25zLzpvYmplY3RJZCcsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSwgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZVVwZGF0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0RFTEVURScsICcvaW5zdGFsbGF0aW9ucy86b2JqZWN0SWQnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRGVsZXRlKHJlcSk7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSW5zdGFsbGF0aW9uc1JvdXRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/LogsRouter.js b/lib/Routers/LogsRouter.js new file mode 100644 index 0000000000..4399b717f5 --- /dev/null +++ b/lib/Routers/LogsRouter.js @@ -0,0 +1,71 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.LogsRouter = void 0; + +var _node = require("parse/node"); + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class LogsRouter extends _PromiseRouter.default { + mountRoutes() { + this.route('GET', '/scriptlog', middleware.promiseEnforceMasterKeyAccess, this.validateRequest, req => { + return this.handleGET(req); + }); + } + + validateRequest(req) { + if (!req.config || !req.config.loggerController) { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Logger adapter is not available'); + } + } // Returns a promise for a {response} object. + // query params: + // level (optional) Level of logging you want to query for (info || error) + // from (optional) Start time for the search. Defaults to 1 week ago. + // until (optional) End time for the search. Defaults to current time. + // order (optional) Direction of results returned, either “asc” or “desc”. Defaults to “desc”. + // size (optional) Number of rows returned by search. Defaults to 10 + // n same as size, overrides size if set + + + handleGET(req) { + const from = req.query.from; + const until = req.query.until; + let size = req.query.size; + + if (req.query.n) { + size = req.query.n; + } + + const order = req.query.order; + const level = req.query.level; + const options = { + from, + until, + size, + order, + level + }; + return req.config.loggerController.getLogs(options).then(result => { + return Promise.resolve({ + response: result + }); + }); + } + +} + +exports.LogsRouter = LogsRouter; +var _default = LogsRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0xvZ3NSb3V0ZXIuanMiXSwibmFtZXMiOlsiTG9nc1JvdXRlciIsIlByb21pc2VSb3V0ZXIiLCJtb3VudFJvdXRlcyIsInJvdXRlIiwibWlkZGxld2FyZSIsInByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzIiwidmFsaWRhdGVSZXF1ZXN0IiwicmVxIiwiaGFuZGxlR0VUIiwiY29uZmlnIiwibG9nZ2VyQ29udHJvbGxlciIsIlBhcnNlIiwiRXJyb3IiLCJQVVNIX01JU0NPTkZJR1VSRUQiLCJmcm9tIiwicXVlcnkiLCJ1bnRpbCIsInNpemUiLCJuIiwib3JkZXIiLCJsZXZlbCIsIm9wdGlvbnMiLCJnZXRMb2dzIiwidGhlbiIsInJlc3VsdCIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVzcG9uc2UiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFTyxNQUFNQSxVQUFOLFNBQXlCQyxzQkFBekIsQ0FBdUM7QUFDNUNDLEVBQUFBLFdBQVcsR0FBRztBQUNaLFNBQUtDLEtBQUwsQ0FDRSxLQURGLEVBRUUsWUFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUUsS0FBS0MsZUFKUCxFQUtFQyxHQUFHLElBQUk7QUFDTCxhQUFPLEtBQUtDLFNBQUwsQ0FBZUQsR0FBZixDQUFQO0FBQ0QsS0FQSDtBQVNEOztBQUVERCxFQUFBQSxlQUFlLENBQUNDLEdBQUQsRUFBTTtBQUNuQixRQUFJLENBQUNBLEdBQUcsQ0FBQ0UsTUFBTCxJQUFlLENBQUNGLEdBQUcsQ0FBQ0UsTUFBSixDQUFXQyxnQkFBL0IsRUFBaUQ7QUFDL0MsWUFBTSxJQUFJQyxZQUFNQyxLQUFWLENBQWdCRCxZQUFNQyxLQUFOLENBQVlDLGtCQUE1QixFQUFnRCxpQ0FBaEQsQ0FBTjtBQUNEO0FBQ0YsR0FqQjJDLENBbUI1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQUwsRUFBQUEsU0FBUyxDQUFDRCxHQUFELEVBQU07QUFDYixVQUFNTyxJQUFJLEdBQUdQLEdBQUcsQ0FBQ1EsS0FBSixDQUFVRCxJQUF2QjtBQUNBLFVBQU1FLEtBQUssR0FBR1QsR0FBRyxDQUFDUSxLQUFKLENBQVVDLEtBQXhCO0FBQ0EsUUFBSUMsSUFBSSxHQUFHVixHQUFHLENBQUNRLEtBQUosQ0FBVUUsSUFBckI7O0FBQ0EsUUFBSVYsR0FBRyxDQUFDUSxLQUFKLENBQVVHLENBQWQsRUFBaUI7QUFDZkQsTUFBQUEsSUFBSSxHQUFHVixHQUFHLENBQUNRLEtBQUosQ0FBVUcsQ0FBakI7QUFDRDs7QUFFRCxVQUFNQyxLQUFLLEdBQUdaLEdBQUcsQ0FBQ1EsS0FBSixDQUFVSSxLQUF4QjtBQUNBLFVBQU1DLEtBQUssR0FBR2IsR0FBRyxDQUFDUSxLQUFKLENBQVVLLEtBQXhCO0FBQ0EsVUFBTUMsT0FBTyxHQUFHO0FBQ2RQLE1BQUFBLElBRGM7QUFFZEUsTUFBQUEsS0FGYztBQUdkQyxNQUFBQSxJQUhjO0FBSWRFLE1BQUFBLEtBSmM7QUFLZEMsTUFBQUE7QUFMYyxLQUFoQjtBQVFBLFdBQU9iLEdBQUcsQ0FBQ0UsTUFBSixDQUFXQyxnQkFBWCxDQUE0QlksT0FBNUIsQ0FBb0NELE9BQXBDLEVBQTZDRSxJQUE3QyxDQUFrREMsTUFBTSxJQUFJO0FBQ2pFLGFBQU9DLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQjtBQUNyQkMsUUFBQUEsUUFBUSxFQUFFSDtBQURXLE9BQWhCLENBQVA7QUFHRCxLQUpNLENBQVA7QUFLRDs7QUFsRDJDOzs7ZUFxRC9CeEIsVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBhcnNlIH0gZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuLi9Qcm9taXNlUm91dGVyJztcbmltcG9ydCAqIGFzIG1pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5leHBvcnQgY2xhc3MgTG9nc1JvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL3NjcmlwdGxvZycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy52YWxpZGF0ZVJlcXVlc3QsXG4gICAgICByZXEgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVHRVQocmVxKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgdmFsaWRhdGVSZXF1ZXN0KHJlcSkge1xuICAgIGlmICghcmVxLmNvbmZpZyB8fCAhcmVxLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELCAnTG9nZ2VyIGFkYXB0ZXIgaXMgbm90IGF2YWlsYWJsZScpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIGZvciBhIHtyZXNwb25zZX0gb2JqZWN0LlxuICAvLyBxdWVyeSBwYXJhbXM6XG4gIC8vIGxldmVsIChvcHRpb25hbCkgTGV2ZWwgb2YgbG9nZ2luZyB5b3Ugd2FudCB0byBxdWVyeSBmb3IgKGluZm8gfHwgZXJyb3IpXG4gIC8vIGZyb20gKG9wdGlvbmFsKSBTdGFydCB0aW1lIGZvciB0aGUgc2VhcmNoLiBEZWZhdWx0cyB0byAxIHdlZWsgYWdvLlxuICAvLyB1bnRpbCAob3B0aW9uYWwpIEVuZCB0aW1lIGZvciB0aGUgc2VhcmNoLiBEZWZhdWx0cyB0byBjdXJyZW50IHRpbWUuXG4gIC8vIG9yZGVyIChvcHRpb25hbCkgRGlyZWN0aW9uIG9mIHJlc3VsdHMgcmV0dXJuZWQsIGVpdGhlciDigJxhc2PigJ0gb3Ig4oCcZGVzY+KAnS4gRGVmYXVsdHMgdG8g4oCcZGVzY+KAnS5cbiAgLy8gc2l6ZSAob3B0aW9uYWwpIE51bWJlciBvZiByb3dzIHJldHVybmVkIGJ5IHNlYXJjaC4gRGVmYXVsdHMgdG8gMTBcbiAgLy8gbiBzYW1lIGFzIHNpemUsIG92ZXJyaWRlcyBzaXplIGlmIHNldFxuICBoYW5kbGVHRVQocmVxKSB7XG4gICAgY29uc3QgZnJvbSA9IHJlcS5xdWVyeS5mcm9tO1xuICAgIGNvbnN0IHVudGlsID0gcmVxLnF1ZXJ5LnVudGlsO1xuICAgIGxldCBzaXplID0gcmVxLnF1ZXJ5LnNpemU7XG4gICAgaWYgKHJlcS5xdWVyeS5uKSB7XG4gICAgICBzaXplID0gcmVxLnF1ZXJ5Lm47XG4gICAgfVxuXG4gICAgY29uc3Qgb3JkZXIgPSByZXEucXVlcnkub3JkZXI7XG4gICAgY29uc3QgbGV2ZWwgPSByZXEucXVlcnkubGV2ZWw7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgIGZyb20sXG4gICAgICB1bnRpbCxcbiAgICAgIHNpemUsXG4gICAgICBvcmRlcixcbiAgICAgIGxldmVsLFxuICAgIH07XG5cbiAgICByZXR1cm4gcmVxLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyLmdldExvZ3Mob3B0aW9ucykudGhlbihyZXN1bHQgPT4ge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgIHJlc3BvbnNlOiByZXN1bHQsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBMb2dzUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/PagesRouter.js b/lib/Routers/PagesRouter.js new file mode 100644 index 0000000000..815a3566b1 --- /dev/null +++ b/lib/Routers/PagesRouter.js @@ -0,0 +1,693 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.PagesRouter = void 0; + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var _Config = _interopRequireDefault(require("../Config")); + +var _express = _interopRequireDefault(require("express")); + +var _path = _interopRequireDefault(require("path")); + +var _fs = require("fs"); + +var _node = require("parse/node"); + +var _Utils = _interopRequireDefault(require("../Utils")); + +var _mustache = _interopRequireDefault(require("mustache")); + +var _Page = _interopRequireDefault(require("../Page")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// All pages with custom page key for reference and file name +const pages = Object.freeze({ + passwordReset: new _Page.default({ + id: 'passwordReset', + defaultFile: 'password_reset.html' + }), + passwordResetSuccess: new _Page.default({ + id: 'passwordResetSuccess', + defaultFile: 'password_reset_success.html' + }), + passwordResetLinkInvalid: new _Page.default({ + id: 'passwordResetLinkInvalid', + defaultFile: 'password_reset_link_invalid.html' + }), + emailVerificationSuccess: new _Page.default({ + id: 'emailVerificationSuccess', + defaultFile: 'email_verification_success.html' + }), + emailVerificationSendFail: new _Page.default({ + id: 'emailVerificationSendFail', + defaultFile: 'email_verification_send_fail.html' + }), + emailVerificationSendSuccess: new _Page.default({ + id: 'emailVerificationSendSuccess', + defaultFile: 'email_verification_send_success.html' + }), + emailVerificationLinkInvalid: new _Page.default({ + id: 'emailVerificationLinkInvalid', + defaultFile: 'email_verification_link_invalid.html' + }), + emailVerificationLinkExpired: new _Page.default({ + id: 'emailVerificationLinkExpired', + defaultFile: 'email_verification_link_expired.html' + }) +}); // All page parameters for reference to be used as template placeholders or query params + +const pageParams = Object.freeze({ + appName: 'appName', + appId: 'appId', + token: 'token', + username: 'username', + error: 'error', + locale: 'locale', + publicServerUrl: 'publicServerUrl' +}); // The header prefix to add page params as response headers + +const pageParamHeaderPrefix = 'x-parse-page-param-'; // The errors being thrown + +const errors = Object.freeze({ + jsonFailedFileLoading: 'failed to load JSON file', + fileOutsideAllowedScope: 'not allowed to read file outside of pages directory' +}); + +class PagesRouter extends _PromiseRouter.default { + /** + * Constructs a PagesRouter. + * @param {Object} pages The pages options from the Parse Server configuration. + */ + constructor(pages = {}) { + super(); // Set instance properties + + this.pagesConfig = pages; + this.pagesEndpoint = pages.pagesEndpoint ? pages.pagesEndpoint : 'apps'; + this.pagesPath = pages.pagesPath ? _path.default.resolve('./', pages.pagesPath) : _path.default.resolve(__dirname, '../../public'); + this.loadJsonResource(); + this.mountPagesRoutes(); + } + + verifyEmail(req) { + const config = req.config; + const { + username, + token: rawToken + } = req.query; + const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken; + + if (!config) { + this.invalidRequest(); + } + + if (!token || !username) { + return this.goToPage(req, pages.emailVerificationLinkInvalid); + } + + const userController = config.userController; + return userController.verifyEmail(username, token).then(() => { + const params = { + [pageParams.username]: username + }; + return this.goToPage(req, pages.emailVerificationSuccess, params); + }, () => { + const params = { + [pageParams.username]: username + }; + return this.goToPage(req, pages.emailVerificationLinkExpired, params); + }); + } + + resendVerificationEmail(req) { + const config = req.config; + const username = req.body.username; + + if (!config) { + this.invalidRequest(); + } + + if (!username) { + return this.goToPage(req, pages.emailVerificationLinkInvalid); + } + + const userController = config.userController; + return userController.resendVerificationEmail(username).then(() => { + return this.goToPage(req, pages.emailVerificationSendSuccess); + }, () => { + return this.goToPage(req, pages.emailVerificationSendFail); + }); + } + + passwordReset(req) { + const config = req.config; + const params = { + [pageParams.appId]: req.params.appId, + [pageParams.appName]: config.appName, + [pageParams.token]: req.query.token, + [pageParams.username]: req.query.username, + [pageParams.publicServerUrl]: config.publicServerURL + }; + return this.goToPage(req, pages.passwordReset, params); + } + + requestResetPassword(req) { + const config = req.config; + + if (!config) { + this.invalidRequest(); + } + + const { + username, + token: rawToken + } = req.query; + const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken; + + if (!username || !token) { + return this.goToPage(req, pages.passwordResetLinkInvalid); + } + + return config.userController.checkResetTokenValidity(username, token).then(() => { + const params = { + [pageParams.token]: token, + [pageParams.username]: username, + [pageParams.appId]: config.applicationId, + [pageParams.appName]: config.appName + }; + return this.goToPage(req, pages.passwordReset, params); + }, () => { + const params = { + [pageParams.username]: username + }; + return this.goToPage(req, pages.passwordResetLinkInvalid, params); + }); + } + + resetPassword(req) { + const config = req.config; + + if (!config) { + this.invalidRequest(); + } + + const { + username, + new_password, + token: rawToken + } = req.body; + const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken; + + if ((!username || !token || !new_password) && req.xhr === false) { + return this.goToPage(req, pages.passwordResetLinkInvalid); + } + + if (!username) { + throw new _node.Parse.Error(_node.Parse.Error.USERNAME_MISSING, 'Missing username'); + } + + if (!token) { + throw new _node.Parse.Error(_node.Parse.Error.OTHER_CAUSE, 'Missing token'); + } + + if (!new_password) { + throw new _node.Parse.Error(_node.Parse.Error.PASSWORD_MISSING, 'Missing password'); + } + + return config.userController.updatePassword(username, token, new_password).then(() => { + return Promise.resolve({ + success: true + }); + }, err => { + return Promise.resolve({ + success: false, + err + }); + }).then(result => { + if (req.xhr) { + if (result.success) { + return Promise.resolve({ + status: 200, + response: 'Password successfully reset' + }); + } + + if (result.err) { + throw new _node.Parse.Error(_node.Parse.Error.OTHER_CAUSE, `${result.err}`); + } + } + + const query = result.success ? { + [pageParams.username]: username + } : { + [pageParams.username]: username, + [pageParams.token]: token, + [pageParams.appId]: config.applicationId, + [pageParams.error]: result.err, + [pageParams.appName]: config.appName + }; + const page = result.success ? pages.passwordResetSuccess : pages.passwordReset; + return this.goToPage(req, page, query, false); + }); + } + /** + * Returns page content if the page is a local file or returns a + * redirect to a custom page. + * @param {Object} req The express request. + * @param {Page} page The page to go to. + * @param {Object} [params={}] The query parameters to attach to the URL in case of + * HTTP redirect responses for POST requests, or the placeholders to fill into + * the response content in case of HTTP content responses for GET requests. + * @param {Boolean} [responseType] Is true if a redirect response should be forced, + * false if a content response should be forced, undefined if the response type + * should depend on the request type by default: + * - GET request -> content response + * - POST request -> redirect response (PRG pattern) + * @returns {Promise} The PromiseRouter response. + */ + + + goToPage(req, page, params = {}, responseType) { + const config = req.config; // Determine redirect either by force, response setting or request method + + const redirect = config.pages.forceRedirect ? true : responseType !== undefined ? responseType : req.method == 'POST'; // Include default parameters + + const defaultParams = this.getDefaultParams(config); + + if (Object.values(defaultParams).includes(undefined)) { + return this.notFound(); + } + + params = Object.assign(params, defaultParams); // Add locale to params to ensure it is passed on with every request; + // that means, once a locale is set, it is passed on to any follow-up page, + // e.g. request_password_reset -> password_reset -> passwort_reset_success + + const locale = this.getLocale(req); + params[pageParams.locale] = locale; // Compose paths and URLs + + const defaultFile = page.defaultFile; + const defaultPath = this.defaultPagePath(defaultFile); + const defaultUrl = this.composePageUrl(defaultFile, config.publicServerURL); // If custom URL is set redirect to it without localization + + const customUrl = config.pages.customUrls[page.id]; + + if (customUrl && !_Utils.default.isPath(customUrl)) { + return this.redirectResponse(customUrl, params); + } // Get JSON placeholders + + + let placeholders = {}; + + if (config.pages.enableLocalization && config.pages.localizationJsonPath) { + placeholders = this.getJsonPlaceholders(locale, params); + } // Send response + + + if (config.pages.enableLocalization && locale) { + return _Utils.default.getLocalizedPath(defaultPath, locale).then(({ + path, + subdir + }) => redirect ? this.redirectResponse(this.composePageUrl(defaultFile, config.publicServerURL, subdir), params) : this.pageResponse(path, params, placeholders)); + } else { + return redirect ? this.redirectResponse(defaultUrl, params) : this.pageResponse(defaultPath, params, placeholders); + } + } + /** + * Serves a request to a static resource and localizes the resource if it + * is a HTML file. + * @param {Object} req The request object. + * @returns {Promise} The response. + */ + + + staticRoute(req) { + // Get requested path + const relativePath = req.params[0]; // Resolve requested path to absolute path + + const absolutePath = _path.default.resolve(this.pagesPath, relativePath); // If the requested file is not a HTML file send its raw content + + + if (!absolutePath || !absolutePath.endsWith('.html')) { + return this.fileResponse(absolutePath); + } // Get parameters + + + const params = this.getDefaultParams(req.config); + const locale = this.getLocale(req); + + if (locale) { + params.locale = locale; + } // Get JSON placeholders + + + const placeholders = this.getJsonPlaceholders(locale, params); + return this.pageResponse(absolutePath, params, placeholders); + } + /** + * Returns a translation from the JSON resource for a given locale. The JSON + * resource is parsed according to i18next syntax. + * + * Example JSON content: + * ```js + * { + * "en": { // resource for language `en` (English) + * "translation": { + * "greeting": "Hello!" + * } + * }, + * "de": { // resource for language `de` (German) + * "translation": { + * "greeting": "Hallo!" + * } + * } + * "de-CH": { // resource for locale `de-CH` (Swiss German) + * "translation": { + * "greeting": "Grüezi!" + * } + * } + * } + * ``` + * @param {String} locale The locale to translate to. + * @returns {Object} The translation or an empty object if no matching + * translation was found. + */ + + + getJsonTranslation(locale) { + // If there is no JSON resource + if (this.jsonParameters === undefined) { + return {}; + } // If locale is not set use the fallback locale + + + locale = locale || this.pagesConfig.localizationFallbackLocale; // Get matching translation by locale, language or fallback locale + + const language = locale.split('-')[0]; + const resource = this.jsonParameters[locale] || this.jsonParameters[language] || this.jsonParameters[this.pagesConfig.localizationFallbackLocale] || {}; + const translation = resource.translation || {}; + return translation; + } + /** + * Returns a translation from the JSON resource for a given locale with + * placeholders filled in by given parameters. + * @param {String} locale The locale to translate to. + * @param {Object} params The parameters to fill into any placeholders + * within the translations. + * @returns {Object} The translation or an empty object if no matching + * translation was found. + */ + + + getJsonPlaceholders(locale, params = {}) { + // If localization is disabled or there is no JSON resource + if (!this.pagesConfig.enableLocalization || !this.pagesConfig.localizationJsonPath) { + return {}; + } // Get JSON placeholders + + + let placeholders = this.getJsonTranslation(locale); // Fill in any placeholders in the translation; this allows a translation + // to contain default placeholders like {{appName}} which are filled here + + placeholders = JSON.stringify(placeholders); + placeholders = _mustache.default.render(placeholders, params); + placeholders = JSON.parse(placeholders); + return placeholders; + } + /** + * Creates a response with file content. + * @param {String} path The path of the file to return. + * @param {Object} [params={}] The parameters to be included in the response + * header. These will also be used to fill placeholders. + * @param {Object} [placeholders={}] The placeholders to fill in the content. + * These will not be included in the response header. + * @returns {Object} The Promise Router response. + */ + + + async pageResponse(path, params = {}, placeholders = {}) { + // Get file content + let data; + + try { + data = await this.readFile(path); + } catch (e) { + return this.notFound(); + } // Get config placeholders; can be an object, a function or an async function + + + let configPlaceholders = typeof this.pagesConfig.placeholders === 'function' ? this.pagesConfig.placeholders(params) : Object.prototype.toString.call(this.pagesConfig.placeholders) === '[object Object]' ? this.pagesConfig.placeholders : {}; + + if (configPlaceholders instanceof Promise) { + configPlaceholders = await configPlaceholders; + } // Fill placeholders + + + const allPlaceholders = Object.assign({}, configPlaceholders, placeholders); + const paramsAndPlaceholders = Object.assign({}, params, allPlaceholders); + data = _mustache.default.render(data, paramsAndPlaceholders); // Add placeholders in header to allow parsing for programmatic use + // of response, instead of having to parse the HTML content. + + const headers = Object.entries(params).reduce((m, p) => { + if (p[1] !== undefined) { + m[`${pageParamHeaderPrefix}${p[0].toLowerCase()}`] = p[1]; + } + + return m; + }, {}); + return { + text: data, + headers: headers + }; + } + /** + * Creates a response with file content. + * @param {String} path The path of the file to return. + * @returns {Object} The PromiseRouter response. + */ + + + async fileResponse(path) { + // Get file content + let data; + + try { + data = await this.readFile(path); + } catch (e) { + return this.notFound(); + } + + return { + text: data + }; + } + /** + * Reads and returns the content of a file at a given path. File reading to + * serve content on the static route is only allowed from the pages + * directory on downwards. + * ----------------------------------------------------------------------- + * **WARNING:** All file reads in the PagesRouter must be executed by this + * wrapper because it also detects and prevents common exploits. + * ----------------------------------------------------------------------- + * @param {String} filePath The path to the file to read. + * @returns {Promise} The file content. + */ + + + async readFile(filePath) { + // Normalize path to prevent it from containing any directory changing + // UNIX patterns which could expose the whole file system, e.g. + // `http://example.com/parse/apps/../file.txt` requests a file outside + // of the pages directory scope. + const normalizedPath = _path.default.normalize(filePath); // Abort if the path is outside of the path directory scope + + + if (!normalizedPath.startsWith(this.pagesPath)) { + throw errors.fileOutsideAllowedScope; + } + + return await _fs.promises.readFile(normalizedPath, 'utf-8'); + } + /** + * Loads a language resource JSON file that is used for translations. + */ + + + loadJsonResource() { + if (this.pagesConfig.localizationJsonPath === undefined) { + return; + } + + try { + const json = require(_path.default.resolve('./', this.pagesConfig.localizationJsonPath)); + + this.jsonParameters = json; + } catch (e) { + throw errors.jsonFailedFileLoading; + } + } + /** + * Extracts and returns the page default parameters from the Parse Server + * configuration. These parameters are made accessible in every page served + * by this router. + * @param {Object} config The Parse Server configuration. + * @returns {Object} The default parameters. + */ + + + getDefaultParams(config) { + return config ? { + [pageParams.appId]: config.appId, + [pageParams.appName]: config.appName, + [pageParams.publicServerUrl]: config.publicServerURL + } : {}; + } + /** + * Extracts and returns the locale from an express request. + * @param {Object} req The express request. + * @returns {String|undefined} The locale, or undefined if no locale was set. + */ + + + getLocale(req) { + const locale = (req.query || {})[pageParams.locale] || (req.body || {})[pageParams.locale] || (req.params || {})[pageParams.locale] || (req.headers || {})[pageParamHeaderPrefix + pageParams.locale]; + return locale; + } + /** + * Creates a response with http rediret. + * @param {Object} req The express request. + * @param {String} path The path of the file to return. + * @param {Object} params The query parameters to include. + * @returns {Object} The Promise Router response. + */ + + + async redirectResponse(url, params) { + // Remove any parameters with undefined value + params = Object.entries(params).reduce((m, p) => { + if (p[1] !== undefined) { + m[p[0]] = p[1]; + } + + return m; + }, {}); // Compose URL with parameters in query + + const location = new URL(url); + Object.entries(params).forEach(p => location.searchParams.set(p[0], p[1])); + const locationString = location.toString(); // Add parameters to header to allow parsing for programmatic use + // of response, instead of having to parse the HTML content. + + const headers = Object.entries(params).reduce((m, p) => { + if (p[1] !== undefined) { + m[`${pageParamHeaderPrefix}${p[0].toLowerCase()}`] = p[1]; + } + + return m; + }, {}); + return { + status: 303, + location: locationString, + headers: headers + }; + } + + defaultPagePath(file) { + return _path.default.join(this.pagesPath, file); + } + + composePageUrl(file, publicServerUrl, locale) { + let url = publicServerUrl; + url += url.endsWith('/') ? '' : '/'; + url += this.pagesEndpoint + '/'; + url += locale === undefined ? '' : locale + '/'; + url += file; + return url; + } + + notFound() { + return { + text: 'Not found.', + status: 404 + }; + } + + invalidRequest() { + const error = new Error(); + error.status = 403; + error.message = 'unauthorized'; + throw error; + } + /** + * Sets the Parse Server configuration in the request object to make it + * easily accessible throughtout request processing. + * @param {Object} req The request. + * @param {Boolean} failGracefully Is true if failing to set the config should + * not result in an invalid request response. Default is `false`. + */ + + + setConfig(req, failGracefully = false) { + req.config = _Config.default.get(req.params.appId || req.query.appId); + + if (!req.config && !failGracefully) { + this.invalidRequest(); + } + + return Promise.resolve(); + } + + mountPagesRoutes() { + this.route('GET', `/${this.pagesEndpoint}/:appId/verify_email`, req => { + this.setConfig(req); + }, req => { + return this.verifyEmail(req); + }); + this.route('POST', `/${this.pagesEndpoint}/:appId/resend_verification_email`, req => { + this.setConfig(req); + }, req => { + return this.resendVerificationEmail(req); + }); + this.route('GET', `/${this.pagesEndpoint}/choose_password`, req => { + this.setConfig(req); + }, req => { + return this.passwordReset(req); + }); + this.route('POST', `/${this.pagesEndpoint}/:appId/request_password_reset`, req => { + this.setConfig(req); + }, req => { + return this.resetPassword(req); + }); + this.route('GET', `/${this.pagesEndpoint}/:appId/request_password_reset`, req => { + this.setConfig(req); + }, req => { + return this.requestResetPassword(req); + }); + this.route('GET', `/${this.pagesEndpoint}/(*)?`, req => { + this.setConfig(req, true); + }, req => { + return this.staticRoute(req); + }); + } + + expressRouter() { + const router = _express.default.Router(); + + router.use('/', super.expressRouter()); + return router; + } + +} + +exports.PagesRouter = PagesRouter; +var _default = PagesRouter; +exports.default = _default; +module.exports = { + PagesRouter, + pageParamHeaderPrefix, + pageParams, + pages +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1BhZ2VzUm91dGVyLmpzIl0sIm5hbWVzIjpbInBhZ2VzIiwiT2JqZWN0IiwiZnJlZXplIiwicGFzc3dvcmRSZXNldCIsIlBhZ2UiLCJpZCIsImRlZmF1bHRGaWxlIiwicGFzc3dvcmRSZXNldFN1Y2Nlc3MiLCJwYXNzd29yZFJlc2V0TGlua0ludmFsaWQiLCJlbWFpbFZlcmlmaWNhdGlvblN1Y2Nlc3MiLCJlbWFpbFZlcmlmaWNhdGlvblNlbmRGYWlsIiwiZW1haWxWZXJpZmljYXRpb25TZW5kU3VjY2VzcyIsImVtYWlsVmVyaWZpY2F0aW9uTGlua0ludmFsaWQiLCJlbWFpbFZlcmlmaWNhdGlvbkxpbmtFeHBpcmVkIiwicGFnZVBhcmFtcyIsImFwcE5hbWUiLCJhcHBJZCIsInRva2VuIiwidXNlcm5hbWUiLCJlcnJvciIsImxvY2FsZSIsInB1YmxpY1NlcnZlclVybCIsInBhZ2VQYXJhbUhlYWRlclByZWZpeCIsImVycm9ycyIsImpzb25GYWlsZWRGaWxlTG9hZGluZyIsImZpbGVPdXRzaWRlQWxsb3dlZFNjb3BlIiwiUGFnZXNSb3V0ZXIiLCJQcm9taXNlUm91dGVyIiwiY29uc3RydWN0b3IiLCJwYWdlc0NvbmZpZyIsInBhZ2VzRW5kcG9pbnQiLCJwYWdlc1BhdGgiLCJwYXRoIiwicmVzb2x2ZSIsIl9fZGlybmFtZSIsImxvYWRKc29uUmVzb3VyY2UiLCJtb3VudFBhZ2VzUm91dGVzIiwidmVyaWZ5RW1haWwiLCJyZXEiLCJjb25maWciLCJyYXdUb2tlbiIsInF1ZXJ5IiwidG9TdHJpbmciLCJpbnZhbGlkUmVxdWVzdCIsImdvVG9QYWdlIiwidXNlckNvbnRyb2xsZXIiLCJ0aGVuIiwicGFyYW1zIiwicmVzZW5kVmVyaWZpY2F0aW9uRW1haWwiLCJib2R5IiwicHVibGljU2VydmVyVVJMIiwicmVxdWVzdFJlc2V0UGFzc3dvcmQiLCJjaGVja1Jlc2V0VG9rZW5WYWxpZGl0eSIsImFwcGxpY2F0aW9uSWQiLCJyZXNldFBhc3N3b3JkIiwibmV3X3Bhc3N3b3JkIiwieGhyIiwiUGFyc2UiLCJFcnJvciIsIlVTRVJOQU1FX01JU1NJTkciLCJPVEhFUl9DQVVTRSIsIlBBU1NXT1JEX01JU1NJTkciLCJ1cGRhdGVQYXNzd29yZCIsIlByb21pc2UiLCJzdWNjZXNzIiwiZXJyIiwicmVzdWx0Iiwic3RhdHVzIiwicmVzcG9uc2UiLCJwYWdlIiwicmVzcG9uc2VUeXBlIiwicmVkaXJlY3QiLCJmb3JjZVJlZGlyZWN0IiwidW5kZWZpbmVkIiwibWV0aG9kIiwiZGVmYXVsdFBhcmFtcyIsImdldERlZmF1bHRQYXJhbXMiLCJ2YWx1ZXMiLCJpbmNsdWRlcyIsIm5vdEZvdW5kIiwiYXNzaWduIiwiZ2V0TG9jYWxlIiwiZGVmYXVsdFBhdGgiLCJkZWZhdWx0UGFnZVBhdGgiLCJkZWZhdWx0VXJsIiwiY29tcG9zZVBhZ2VVcmwiLCJjdXN0b21VcmwiLCJjdXN0b21VcmxzIiwiVXRpbHMiLCJpc1BhdGgiLCJyZWRpcmVjdFJlc3BvbnNlIiwicGxhY2Vob2xkZXJzIiwiZW5hYmxlTG9jYWxpemF0aW9uIiwibG9jYWxpemF0aW9uSnNvblBhdGgiLCJnZXRKc29uUGxhY2Vob2xkZXJzIiwiZ2V0TG9jYWxpemVkUGF0aCIsInN1YmRpciIsInBhZ2VSZXNwb25zZSIsInN0YXRpY1JvdXRlIiwicmVsYXRpdmVQYXRoIiwiYWJzb2x1dGVQYXRoIiwiZW5kc1dpdGgiLCJmaWxlUmVzcG9uc2UiLCJnZXRKc29uVHJhbnNsYXRpb24iLCJqc29uUGFyYW1ldGVycyIsImxvY2FsaXphdGlvbkZhbGxiYWNrTG9jYWxlIiwibGFuZ3VhZ2UiLCJzcGxpdCIsInJlc291cmNlIiwidHJhbnNsYXRpb24iLCJKU09OIiwic3RyaW5naWZ5IiwibXVzdGFjaGUiLCJyZW5kZXIiLCJwYXJzZSIsImRhdGEiLCJyZWFkRmlsZSIsImUiLCJjb25maWdQbGFjZWhvbGRlcnMiLCJwcm90b3R5cGUiLCJjYWxsIiwiYWxsUGxhY2Vob2xkZXJzIiwicGFyYW1zQW5kUGxhY2Vob2xkZXJzIiwiaGVhZGVycyIsImVudHJpZXMiLCJyZWR1Y2UiLCJtIiwicCIsInRvTG93ZXJDYXNlIiwidGV4dCIsImZpbGVQYXRoIiwibm9ybWFsaXplZFBhdGgiLCJub3JtYWxpemUiLCJzdGFydHNXaXRoIiwiZnMiLCJqc29uIiwicmVxdWlyZSIsInVybCIsImxvY2F0aW9uIiwiVVJMIiwiZm9yRWFjaCIsInNlYXJjaFBhcmFtcyIsInNldCIsImxvY2F0aW9uU3RyaW5nIiwiZmlsZSIsImpvaW4iLCJtZXNzYWdlIiwic2V0Q29uZmlnIiwiZmFpbEdyYWNlZnVsbHkiLCJDb25maWciLCJnZXQiLCJyb3V0ZSIsImV4cHJlc3NSb3V0ZXIiLCJyb3V0ZXIiLCJleHByZXNzIiwiUm91dGVyIiwidXNlIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRUE7QUFDQSxNQUFNQSxLQUFLLEdBQUdDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjO0FBQzFCQyxFQUFBQSxhQUFhLEVBQUUsSUFBSUMsYUFBSixDQUFTO0FBQUVDLElBQUFBLEVBQUUsRUFBRSxlQUFOO0FBQXVCQyxJQUFBQSxXQUFXLEVBQUU7QUFBcEMsR0FBVCxDQURXO0FBRTFCQyxFQUFBQSxvQkFBb0IsRUFBRSxJQUFJSCxhQUFKLENBQVM7QUFDN0JDLElBQUFBLEVBQUUsRUFBRSxzQkFEeUI7QUFFN0JDLElBQUFBLFdBQVcsRUFBRTtBQUZnQixHQUFULENBRkk7QUFNMUJFLEVBQUFBLHdCQUF3QixFQUFFLElBQUlKLGFBQUosQ0FBUztBQUNqQ0MsSUFBQUEsRUFBRSxFQUFFLDBCQUQ2QjtBQUVqQ0MsSUFBQUEsV0FBVyxFQUFFO0FBRm9CLEdBQVQsQ0FOQTtBQVUxQkcsRUFBQUEsd0JBQXdCLEVBQUUsSUFBSUwsYUFBSixDQUFTO0FBQ2pDQyxJQUFBQSxFQUFFLEVBQUUsMEJBRDZCO0FBRWpDQyxJQUFBQSxXQUFXLEVBQUU7QUFG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Qy9ILFc7O0FBQ2ZtSSxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZnBJLEVBQUFBLFdBRGU7QUFFZkosRUFBQUEscUJBRmU7QUFHZlIsRUFBQUEsVUFIZTtBQUlmZCxFQUFBQTtBQUplLENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFByb21pc2VSb3V0ZXIgZnJvbSAnLi4vUHJvbWlzZVJvdXRlcic7XG5pbXBvcnQgQ29uZmlnIGZyb20gJy4uL0NvbmZpZyc7XG5pbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgcHJvbWlzZXMgYXMgZnMgfSBmcm9tICdmcyc7XG5pbXBvcnQgeyBQYXJzZSB9IGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IFV0aWxzIGZyb20gJy4uL1V0aWxzJztcbmltcG9ydCBtdXN0YWNoZSBmcm9tICdtdXN0YWNoZSc7XG5pbXBvcnQgUGFnZSBmcm9tICcuLi9QYWdlJztcblxuLy8gQWxsIHBhZ2VzIHdpdGggY3VzdG9tIHBhZ2Uga2V5IGZvciByZWZlcmVuY2UgYW5kIGZpbGUgbmFtZVxuY29uc3QgcGFnZXMgPSBPYmplY3QuZnJlZXplKHtcbiAgcGFzc3dvcmRSZXNldDogbmV3IFBhZ2UoeyBpZDogJ3Bhc3N3b3JkUmVzZXQnLCBkZWZhdWx0RmlsZTogJ3Bhc3N3b3JkX3Jlc2V0Lmh0bWwnIH0pLFxuICBwYXNzd29yZFJlc2V0U3VjY2VzczogbmV3IFBhZ2Uoe1xuICAgIGlkOiAncGFzc3dvcmRSZXNldFN1Y2Nlc3MnLFxuICAgIGRlZmF1bHRGaWxlOiAncGFzc3dvcmRfcmVzZXRfc3VjY2Vzcy5odG1sJyxcbiAgfSksXG4gIHBhc3N3b3JkUmVzZXRMaW5rSW52YWxpZDogbmV3IFBhZ2Uoe1xuICAgIGlkOiAncGFzc3dvcmRSZXNldExpbmtJbnZhbGlkJyxcbiAgICBkZWZhdWx0RmlsZTogJ3Bhc3N3b3JkX3Jlc2V0X2xpbmtfaW52YWxpZC5odG1sJyxcbiAgfSksXG4gIGVtYWlsVmVyaWZpY2F0aW9uU3VjY2VzczogbmV3IFBhZ2Uoe1xuICAgIGlkOiAnZW1haWxWZXJpZmljYXRpb25TdWNjZXNzJyxcbiAgICBkZWZhdWx0RmlsZTogJ2VtYWlsX3ZlcmlmaWNhdGlvbl9zdWNjZXNzLmh0bWwnLFxuICB9KSxcbiAgZW1haWxWZXJpZmljYXRpb25TZW5kRmFpbDogbmV3IFBhZ2Uoe1xuICAgIGlkOiAnZW1haWxWZXJpZmljYXRpb25TZW5kRmFpbCcsXG4gICAgZGVmYXVsdEZpbGU6ICdlbWFpbF92ZXJpZmljYXRpb25fc2VuZF9mYWlsLmh0bWwnLFxuICB9KSxcbiAgZW1haWxWZXJpZmljYXRpb25TZW5kU3VjY2VzczogbmV3IFBhZ2Uoe1xuICAgIGlkOiAnZW1haWxWZXJpZmljYXRpb25TZW5kU3VjY2VzcycsXG4gICAgZGVmYXVsdEZpbGU6ICdlbWFpbF92ZXJpZmljYXRpb25fc2VuZF9zdWNjZXNzLmh0bWwnLFxuICB9KSxcbiAgZW1haWxWZXJpZmljYXRpb25MaW5rSW52YWxpZDogbmV3IFBhZ2Uoe1xuICAgIGlkOiAnZW1haWxWZXJpZmljYXRpb25MaW5rSW52YWxpZCcsXG4gICAgZGVmYXVsdEZpbGU6ICdlbWFpbF92ZXJpZmljYXRpb25fbGlua19pbnZhbGlkLmh0bWwnLFxuICB9KSxcbiAgZW1haWxWZXJpZmljYXRpb25MaW5rRXhwaXJlZDogbmV3IFBhZ2Uoe1xuICAgIGlkOiAnZW1haWxWZXJpZmljYXRpb25MaW5rRXhwaXJlZCcsXG4gICAgZGVmYXVsdEZpbGU6ICdlbWFpbF92ZXJpZmljYXRpb25fbGlua19leHBpcmVkLmh0bWwnLFxuICB9KSxcbn0pO1xuXG4vLyBBbGwgcGFnZSBwYXJhbWV0ZXJzIGZvciByZWZlcmVuY2UgdG8gYmUgdXNlZCBhcyB0ZW1wbGF0ZSBwbGFjZWhvbGRlcnMgb3IgcXVlcnkgcGFyYW1zXG5jb25zdCBwYWdlUGFyYW1zID0gT2JqZWN0LmZyZWV6ZSh7XG4gIGFwcE5hbWU6ICdhcHBOYW1lJyxcbiAgYXBwSWQ6ICdhcHBJZCcsXG4gIHRva2VuOiAndG9rZW4nLFxuICB1c2VybmFtZTogJ3VzZXJuYW1lJyxcbiAgZXJyb3I6ICdlcnJvcicsXG4gIGxvY2FsZTogJ2xvY2FsZScsXG4gIHB1YmxpY1NlcnZlclVybDogJ3B1YmxpY1NlcnZlclVybCcsXG59KTtcblxuLy8gVGhlIGhlYWRlciBwcmVmaXggdG8gYWRkIHBhZ2UgcGFyYW1zIGFzIHJlc3BvbnNlIGhlYWRlcnNcbmNvbnN0IHBhZ2VQYXJhbUhlYWRlclByZWZpeCA9ICd4LXBhcnNlLXBhZ2UtcGFyYW0tJztcblxuLy8gVGhlIGVycm9ycyBiZWluZyB0aHJvd25cbmNvbnN0IGVycm9ycyA9IE9iamVjdC5mcmVlemUoe1xuICBqc29uRmFpbGVkRmlsZUxvYWRpbmc6ICdmYWlsZWQgdG8gbG9hZCBKU09OIGZpbGUnLFxuICBmaWxlT3V0c2lkZUFsbG93ZWRTY29wZTogJ25vdCBhbGxvd2VkIHRvIHJlYWQgZmlsZSBvdXRzaWRlIG9mIHBhZ2VzIGRpcmVjdG9yeScsXG59KTtcblxuZXhwb3J0IGNsYXNzIFBhZ2VzUm91dGVyIGV4dGVuZHMgUHJvbWlzZVJvdXRlciB7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RzIGEgUGFnZXNSb3V0ZXIuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwYWdlcyBUaGUgcGFnZXMgb3B0aW9ucyBmcm9tIHRoZSBQYXJzZSBTZXJ2ZXIgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHBhZ2VzID0ge30pIHtcbiAgICBzdXBlcigpO1xuXG4gICAgLy8gU2V0IGluc3RhbmNlIHByb3BlcnRpZXNcbiAgICB0aGlzLnBhZ2VzQ29uZmlnID0gcGFnZXM7XG4gICAgdGhpcy5wYWdlc0VuZHBvaW50ID0gcGFnZXMucGFnZXNFbmRwb2ludCA/IHBhZ2VzLnBhZ2VzRW5kcG9pbnQgOiAnYXBwcyc7XG4gICAgdGhpcy5wYWdlc1BhdGggPSBwYWdlcy5wYWdlc1BhdGhcbiAgICAgID8gcGF0aC5yZXNvbHZlKCcuLycsIHBhZ2VzLnBhZ2VzUGF0aClcbiAgICAgIDogcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4uLy4uL3B1YmxpYycpO1xuICAgIHRoaXMubG9hZEpzb25SZXNvdXJjZSgpO1xuICAgIHRoaXMubW91bnRQYWdlc1JvdXRlcygpO1xuICB9XG5cbiAgdmVyaWZ5RW1haWwocmVxKSB7XG4gICAgY29uc3QgY29uZmlnID0gcmVxLmNvbmZpZztcbiAgICBjb25zdCB7IHVzZXJuYW1lLCB0b2tlbjogcmF3VG9rZW4gfSA9IHJlcS5xdWVyeTtcbiAgICBjb25zdCB0b2tlbiA9IHJhd1Rva2VuICYmIHR5cGVvZiByYXdUb2tlbiAhPT0gJ3N0cmluZycgPyByYXdUb2tlbi50b1N0cmluZygpIDogcmF3VG9rZW47XG5cbiAgICBpZiAoIWNvbmZpZykge1xuICAgICAgdGhpcy5pbnZhbGlkUmVxdWVzdCgpO1xuICAgIH1cblxuICAgIGlmICghdG9rZW4gfHwgIXVzZXJuYW1lKSB7XG4gICAgICByZXR1cm4gdGhpcy5nb1RvUGFnZShyZXEsIHBhZ2VzLmVtYWlsVmVyaWZpY2F0aW9uTGlua0ludmFsaWQpO1xuICAgIH1cblxuICAgIGNvbnN0IHVzZXJDb250cm9sbGVyID0gY29uZmlnLnVzZXJDb250cm9sbGVyO1xuICAgIHJldHVybiB1c2VyQ29udHJvbGxlci52ZXJpZnlFbWFpbCh1c2VybmFtZSwgdG9rZW4pLnRoZW4oXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBbcGFnZVBhcmFtcy51c2VybmFtZV06IHVzZXJuYW1lLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gdGhpcy5nb1RvUGFnZShyZXEsIHBhZ2VzLmVtYWlsVmVyaWZpY2F0aW9uU3VjY2VzcywgcGFyYW1zKTtcbiAgICAgIH0sXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBbcGFnZVBhcmFtcy51c2VybmFtZV06IHVzZXJuYW1lLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gdGhpcy5nb1RvUGFnZShyZXEsIHBhZ2VzLmVtYWlsVmVyaWZpY2F0aW9uTGlua0V4cGlyZWQsIHBhcmFtcyk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHJlc2VuZFZlcmlmaWNhdGlvbkVtYWlsKHJlcSkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHJlcS5jb25maWc7XG4gICAgY29uc3QgdXNlcm5hbWUgPSByZXEuYm9keS51c2VybmFtZTtcblxuICAgIGlmICghY29uZmlnKSB7XG4gICAgICB0aGlzLmludmFsaWRSZXF1ZXN0KCk7XG4gICAgfVxuXG4gICAgaWYgKCF1c2VybmFtZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ29Ub1BhZ2UocmVxLCBwYWdlcy5lbWFpbFZlcmlmaWNhdGlvbkxpbmtJbnZhbGlkKTtcbiAgICB9XG5cbiAgICBjb25zdCB1c2VyQ29udHJvbGxlciA9IGNvbmZpZy51c2VyQ29udHJvbGxlcjtcblxuICAgIHJldHVybiB1c2VyQ29udHJvbGxlci5yZXNlbmRWZXJpZmljYXRpb25FbWFpbCh1c2VybmFtZSkudGhlbihcbiAgICAgICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ29Ub1BhZ2UocmVxLCBwYWdlcy5lbWFpbFZlcmlmaWNhdGlvblNlbmRTdWNjZXNzKTtcbiAgICAgIH0sXG4gICAgICAoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmdvVG9QYWdlKHJlcSwgcGFnZXMuZW1haWxWZXJpZmljYXRpb25TZW5kRmFpbCk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHBhc3N3b3JkUmVzZXQocmVxKSB7XG4gICAgY29uc3QgY29uZmlnID0gcmVxLmNvbmZpZztcbiAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICBbcGFnZVBhcmFtcy5hcHBJZF06IHJlcS5wYXJhbXMuYXBwSWQsXG4gICAgICBbcGFnZVBhcmFtcy5hcHBOYW1lXTogY29uZmlnLmFwcE5hbWUsXG4gICAgICBbcGFnZVBhcmFtcy50b2tlbl06IHJlcS5xdWVyeS50b2tlbixcbiAgICAgIFtwYWdlUGFyYW1zLnVzZXJuYW1lXTogcmVxLnF1ZXJ5LnVzZXJuYW1lLFxuICAgICAgW3BhZ2VQYXJhbXMucHVibGljU2VydmVyVXJsXTogY29uZmlnLnB1YmxpY1NlcnZlclVSTCxcbiAgICB9O1xuICAgIHJldHVybiB0aGlzLmdvVG9QYWdlKHJlcSwgcGFnZXMucGFzc3dvcmRSZXNldCwgcGFyYW1zKTtcbiAgfVxuXG4gIHJlcXVlc3RSZXNldFBhc3N3b3JkKHJlcSkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHJlcS5jb25maWc7XG5cbiAgICBpZiAoIWNvbmZpZykge1xuICAgICAgdGhpcy5pbnZhbGlkUmVxdWVzdCgpO1xuICAgIH1cblxuICAgIGNvbnN0IHsgdXNlcm5hbWUsIHRva2VuOiByYXdUb2tlbiB9ID0gcmVxLnF1ZXJ5O1xuICAgIGNvbnN0IHRva2VuID0gcmF3VG9rZW4gJiYgdHlwZW9mIHJhd1Rva2VuICE9PSAnc3RyaW5nJyA/IHJhd1Rva2VuLnRvU3RyaW5nKCkgOiByYXdUb2tlbjtcblxuICAgIGlmICghdXNlcm5hbWUgfHwgIXRva2VuKSB7XG4gICAgICByZXR1cm4gdGhpcy5nb1RvUGFnZShyZXEsIHBhZ2VzLnBhc3N3b3JkUmVzZXRMaW5rSW52YWxpZCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbmZpZy51c2VyQ29udHJvbGxlci5jaGVja1Jlc2V0VG9rZW5WYWxpZGl0eSh1c2VybmFtZSwgdG9rZW4pLnRoZW4oXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBbcGFnZVBhcmFtcy50b2tlbl06IHRva2VuLFxuICAgICAgICAgIFtwYWdlUGFyYW1zLnVzZXJuYW1lXTogdXNlcm5hbWUsXG4gICAgICAgICAgW3BhZ2VQYXJhbXMuYXBwSWRdOiBjb25maWcuYXBwbGljYXRpb25JZCxcbiAgICAgICAgICBbcGFnZVBhcmFtcy5hcHBOYW1lXTogY29uZmlnLmFwcE5hbWUsXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB0aGlzLmdvVG9QYWdlKHJlcSwgcGFnZXMucGFzc3dvcmRSZXNldCwgcGFyYW1zKTtcbiAgICAgIH0sXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBbcGFnZVBhcmFtcy51c2VybmFtZV06IHVzZXJuYW1lLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gdGhpcy5nb1RvUGFnZShyZXEsIHBhZ2VzLnBhc3N3b3JkUmVzZXRMaW5rSW52YWxpZCwgcGFyYW1zKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgcmVzZXRQYXNzd29yZChyZXEpIHtcbiAgICBjb25zdCBjb25maWcgPSByZXEuY29uZmlnO1xuXG4gICAgaWYgKCFjb25maWcpIHtcbiAgICAgIHRoaXMuaW52YWxpZFJlcXVlc3QoKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IHVzZXJuYW1lLCBuZXdfcGFzc3dvcmQsIHRva2VuOiByYXdUb2tlbiB9ID0gcmVxLmJvZHk7XG4gICAgY29uc3QgdG9rZW4gPSByYXdUb2tlbiAmJiB0eXBlb2YgcmF3VG9rZW4gIT09ICdzdHJpbmcnID8gcmF3VG9rZW4udG9TdHJpbmcoKSA6IHJhd1Rva2VuO1xuXG4gICAgaWYgKCghdXNlcm5hbWUgfHwgIXRva2VuIHx8ICFuZXdfcGFzc3dvcmQpICYmIHJlcS54aHIgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm4gdGhpcy5nb1RvUGFnZShyZXEsIHBhZ2VzLnBhc3N3b3JkUmVzZXRMaW5rSW52YWxpZCk7XG4gICAgfVxuXG4gICAgaWYgKCF1c2VybmFtZSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlVTRVJOQU1FX01JU1NJTkcsICdNaXNzaW5nIHVzZXJuYW1lJyk7XG4gICAgfVxuXG4gICAgaWYgKCF0b2tlbikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9USEVSX0NBVVNFLCAnTWlzc2luZyB0b2tlbicpO1xuICAgIH1cblxuICAgIGlmICghbmV3X3Bhc3N3b3JkKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuUEFTU1dPUkRfTUlTU0lORywgJ01pc3NpbmcgcGFzc3dvcmQnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29uZmlnLnVzZXJDb250cm9sbGVyXG4gICAgICAudXBkYXRlUGFzc3dvcmQodXNlcm5hbWUsIHRva2VuLCBuZXdfcGFzc3dvcmQpXG4gICAgICAudGhlbihcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyID0+IHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgZXJyLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICApXG4gICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICBpZiAocmVxLnhocikge1xuICAgICAgICAgIGlmIChyZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgICAgIHN0YXR1czogMjAwLFxuICAgICAgICAgICAgICByZXNwb25zZTogJ1Bhc3N3b3JkIHN1Y2Nlc3NmdWxseSByZXNldCcsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHJlc3VsdC5lcnIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PVEhFUl9DQVVTRSwgYCR7cmVzdWx0LmVycn1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBxdWVyeSA9IHJlc3VsdC5zdWNjZXNzXG4gICAgICAgICAgPyB7XG4gICAgICAgICAgICBbcGFnZVBhcmFtcy51c2VybmFtZV06IHVzZXJuYW1lLFxuICAgICAgICAgIH1cbiAgICAgICAgICA6IHtcbiAgICAgICAgICAgIFtwYWdlUGFyYW1zLnVzZXJuYW1lXTogdXNlcm5hbWUsXG4gICAgICAgICAgICBbcGFnZVBhcmFtcy50b2tlbl06IHRva2VuLFxuICAgICAgICAgICAgW3BhZ2VQYXJhbXMuYXBwSWRdOiBjb25maWcuYXBwbGljYXRpb25JZCxcbiAgICAgICAgICAgIFtwYWdlUGFyYW1zLmVycm9yXTogcmVzdWx0LmVycixcbiAgICAgICAgICAgIFtwYWdlUGFyYW1zLmFwcE5hbWVdOiBjb25maWcuYXBwTmFtZSxcbiAgICAgICAgICB9O1xuICAgICAgICBjb25zdCBwYWdlID0gcmVzdWx0LnN1Y2Nlc3MgPyBwYWdlcy5wYXNzd29yZFJlc2V0U3VjY2VzcyA6IHBhZ2VzLnBhc3N3b3JkUmVzZXQ7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZ29Ub1BhZ2UocmVxLCBwYWdlLCBxdWVyeSwgZmFsc2UpO1xuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBwYWdlIGNvbnRlbnQgaWYgdGhlIHBhZ2UgaXMgYSBsb2NhbCBmaWxlIG9yIHJldHVybnMgYVxuICAgKiByZWRpcmVjdCB0byBhIGN1c3RvbSBwYWdlLlxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxIFRoZSBleHByZXNzIHJlcXVlc3QuXG4gICAqIEBwYXJhbSB7UGFnZX0gcGFnZSBUaGUgcGFnZSB0byBnbyB0by5cbiAgICogQHBhcmFtIHtPYmplY3R9IFtwYXJhbXM9e31dIFRoZSBxdWVyeSBwYXJhbWV0ZXJzIHRvIGF0dGFjaCB0byB0aGUgVVJMIGluIGNhc2Ugb2ZcbiAgICogSFRUUCByZWRpcmVjdCByZXNwb25zZXMgZm9yIFBPU1QgcmVxdWVzdHMsIG9yIHRoZSBwbGFjZWhvbGRlcnMgdG8gZmlsbCBpbnRvXG4gICAqIHRoZSByZXNwb25zZSBjb250ZW50IGluIGNhc2Ugb2YgSFRUUCBjb250ZW50IHJlc3BvbnNlcyBmb3IgR0VUIHJlcXVlc3RzLlxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IFtyZXNwb25zZVR5cGVdIElzIHRydWUgaWYgYSByZWRpcmVjdCByZXNwb25zZSBzaG91bGQgYmUgZm9yY2VkLFxuICAgKiBmYWxzZSBpZiBhIGNvbnRlbnQgcmVzcG9uc2Ugc2hvdWxkIGJlIGZvcmNlZCwgdW5kZWZpbmVkIGlmIHRoZSByZXNwb25zZSB0eXBlXG4gICAqIHNob3VsZCBkZXBlbmQgb24gdGhlIHJlcXVlc3QgdHlwZSBieSBkZWZhdWx0OlxuICAgKiAtIEdFVCByZXF1ZXN0IC0+IGNvbnRlbnQgcmVzcG9uc2VcbiAgICogLSBQT1NUIHJlcXVlc3QgLT4gcmVkaXJlY3QgcmVzcG9uc2UgKFBSRyBwYXR0ZXJuKVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxPYmplY3Q+fSBUaGUgUHJvbWlzZVJvdXRlciByZXNwb25zZS5cbiAgICovXG4gIGdvVG9QYWdlKHJlcSwgcGFnZSwgcGFyYW1zID0ge30sIHJlc3BvbnNlVHlwZSkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHJlcS5jb25maWc7XG5cbiAgICAvLyBEZXRlcm1pbmUgcmVkaXJlY3QgZWl0aGVyIGJ5IGZvcmNlLCByZXNwb25zZSBzZXR0aW5nIG9yIHJlcXVlc3QgbWV0aG9kXG4gICAgY29uc3QgcmVkaXJlY3QgPSBjb25maWcucGFnZXMuZm9yY2VSZWRpcmVjdFxuICAgICAgPyB0cnVlXG4gICAgICA6IHJlc3BvbnNlVHlwZSAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8gcmVzcG9uc2VUeXBlXG4gICAgICAgIDogcmVxLm1ldGhvZCA9PSAnUE9TVCc7XG5cbiAgICAvLyBJbmNsdWRlIGRlZmF1bHQgcGFyYW1ldGVyc1xuICAgIGNvbnN0IGRlZmF1bHRQYXJhbXMgPSB0aGlzLmdldERlZmF1bHRQYXJhbXMoY29uZmlnKTtcbiAgICBpZiAoT2JqZWN0LnZhbHVlcyhkZWZhdWx0UGFyYW1zKS5pbmNsdWRlcyh1bmRlZmluZWQpKSB7XG4gICAgICByZXR1cm4gdGhpcy5ub3RGb3VuZCgpO1xuICAgIH1cbiAgICBwYXJhbXMgPSBPYmplY3QuYXNzaWduKHBhcmFtcywgZGVmYXVsdFBhcmFtcyk7XG5cbiAgICAvLyBBZGQgbG9jYWxlIHRvIHBhcmFtcyB0byBlbnN1cmUgaXQgaXMgcGFzc2VkIG9uIHdpdGggZXZlcnkgcmVxdWVzdDtcbiAgICAvLyB0aGF0IG1lYW5zLCBvbmNlIGEgbG9jYWxlIGlzIHNldCwgaXQgaXMgcGFzc2VkIG9uIHRvIGFueSBmb2xsb3ctdXAgcGFnZSxcbiAgICAvLyBlLmcuIHJlcXVlc3RfcGFzc3dvcmRfcmVzZXQgLT4gcGFzc3dvcmRfcmVzZXQgLT4gcGFzc3dvcnRfcmVzZXRfc3VjY2Vzc1xuICAgIGNvbnN0IGxvY2FsZSA9IHRoaXMuZ2V0TG9jYWxlKHJlcSk7XG4gICAgcGFyYW1zW3BhZ2VQYXJhbXMubG9jYWxlXSA9IGxvY2FsZTtcblxuICAgIC8vIENvbXBvc2UgcGF0aHMgYW5kIFVSTHNcbiAgICBjb25zdCBkZWZhdWx0RmlsZSA9IHBhZ2UuZGVmYXVsdEZpbGU7XG4gICAgY29uc3QgZGVmYXVsdFBhdGggPSB0aGlzLmRlZmF1bHRQYWdlUGF0aChkZWZhdWx0RmlsZSk7XG4gICAgY29uc3QgZGVmYXVsdFVybCA9IHRoaXMuY29tcG9zZVBhZ2VVcmwoZGVmYXVsdEZpbGUsIGNvbmZpZy5wdWJsaWNTZXJ2ZXJVUkwpO1xuXG4gICAgLy8gSWYgY3VzdG9tIFVSTCBpcyBzZXQgcmVkaXJlY3QgdG8gaXQgd2l0aG91dCBsb2NhbGl6YXRpb25cbiAgICBjb25zdCBjdXN0b21VcmwgPSBjb25maWcucGFnZXMuY3VzdG9tVXJsc1twYWdlLmlkXTtcbiAgICBpZiAoY3VzdG9tVXJsICYmICFVdGlscy5pc1BhdGgoY3VzdG9tVXJsKSkge1xuICAgICAgcmV0dXJuIHRoaXMucmVkaXJlY3RSZXNwb25zZShjdXN0b21VcmwsIHBhcmFtcyk7XG4gICAgfVxuXG4gICAgLy8gR2V0IEpTT04gcGxhY2Vob2xkZXJzXG4gICAgbGV0IHBsYWNlaG9sZGVycyA9IHt9O1xuICAgIGlmIChjb25maWcucGFnZXMuZW5hYmxlTG9jYWxpemF0aW9uICYmIGNvbmZpZy5wYWdlcy5sb2NhbGl6YXRpb25Kc29uUGF0aCkge1xuICAgICAgcGxhY2Vob2xkZXJzID0gdGhpcy5nZXRKc29uUGxhY2Vob2xkZXJzKGxvY2FsZSwgcGFyYW1zKTtcbiAgICB9XG5cbiAgICAvLyBTZW5kIHJlc3BvbnNlXG4gICAgaWYgKGNvbmZpZy5wYWdlcy5lbmFibGVMb2NhbGl6YXRpb24gJiYgbG9jYWxlKSB7XG4gICAgICByZXR1cm4gVXRpbHMuZ2V0TG9jYWxpemVkUGF0aChkZWZhdWx0UGF0aCwgbG9jYWxlKS50aGVuKCh7IHBhdGgsIHN1YmRpciB9KSA9PlxuICAgICAgICByZWRpcmVjdFxuICAgICAgICAgID8gdGhpcy5yZWRpcmVjdFJlc3BvbnNlKFxuICAgICAgICAgICAgdGhpcy5jb21wb3NlUGFnZVVybChkZWZhdWx0RmlsZSwgY29uZmlnLnB1YmxpY1NlcnZlclVSTCwgc3ViZGlyKSxcbiAgICAgICAgICAgIHBhcmFtc1xuICAgICAgICAgIClcbiAgICAgICAgICA6IHRoaXMucGFnZVJlc3BvbnNlKHBhdGgsIHBhcmFtcywgcGxhY2Vob2xkZXJzKVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJlZGlyZWN0XG4gICAgICAgID8gdGhpcy5yZWRpcmVjdFJlc3BvbnNlKGRlZmF1bHRVcmwsIHBhcmFtcylcbiAgICAgICAgOiB0aGlzLnBhZ2VSZXNwb25zZShkZWZhdWx0UGF0aCwgcGFyYW1zLCBwbGFjZWhvbGRlcnMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXJ2ZXMgYSByZXF1ZXN0IHRvIGEgc3RhdGljIHJlc291cmNlIGFuZCBsb2NhbGl6ZXMgdGhlIHJlc291cmNlIGlmIGl0XG4gICAqIGlzIGEgSFRNTCBmaWxlLlxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxIFRoZSByZXF1ZXN0IG9iamVjdC5cbiAgICogQHJldHVybnMge1Byb21pc2U8T2JqZWN0Pn0gVGhlIHJlc3BvbnNlLlxuICAgKi9cbiAgc3RhdGljUm91dGUocmVxKSB7XG4gICAgLy8gR2V0IHJlcXVlc3RlZCBwYXRoXG4gICAgY29uc3QgcmVsYXRpdmVQYXRoID0gcmVxLnBhcmFtc1swXTtcblxuICAgIC8vIFJlc29sdmUgcmVxdWVzdGVkIHBhdGggdG8gYWJzb2x1dGUgcGF0aFxuICAgIGNvbnN0IGFic29sdXRlUGF0aCA9IHBhdGgucmVzb2x2ZSh0aGlzLnBhZ2VzUGF0aCwgcmVsYXRpdmVQYXRoKTtcblxuICAgIC8vIElmIHRoZSByZXF1ZXN0ZWQgZmlsZSBpcyBub3QgYSBIVE1MIGZpbGUgc2VuZCBpdHMgcmF3IGNvbnRlbnRcbiAgICBpZiAoIWFic29sdXRlUGF0aCB8fCAhYWJzb2x1dGVQYXRoLmVuZHNXaXRoKCcuaHRtbCcpKSB7XG4gICAgICByZXR1cm4gdGhpcy5maWxlUmVzcG9uc2UoYWJzb2x1dGVQYXRoKTtcbiAgICB9XG5cbiAgICAvLyBHZXQgcGFyYW1ldGVyc1xuICAgIGNvbnN0IHBhcmFtcyA9IHRoaXMuZ2V0RGVmYXVsdFBhcmFtcyhyZXEuY29uZmlnKTtcbiAgICBjb25zdCBsb2NhbGUgPSB0aGlzLmdldExvY2FsZShyZXEpO1xuICAgIGlmIChsb2NhbGUpIHtcbiAgICAgIHBhcmFtcy5sb2NhbGUgPSBsb2NhbGU7XG4gICAgfVxuXG4gICAgLy8gR2V0IEpTT04gcGxhY2Vob2xkZXJzXG4gICAgY29uc3QgcGxhY2Vob2xkZXJzID0gdGhpcy5nZXRKc29uUGxhY2Vob2xkZXJzKGxvY2FsZSwgcGFyYW1zKTtcblxuICAgIHJldHVybiB0aGlzLnBhZ2VSZXNwb25zZShhYnNvbHV0ZVBhdGgsIHBhcmFtcywgcGxhY2Vob2xkZXJzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgdHJhbnNsYXRpb24gZnJvbSB0aGUgSlNPTiByZXNvdXJjZSBmb3IgYSBnaXZlbiBsb2NhbGUuIFRoZSBKU09OXG4gICAqIHJlc291cmNlIGlzIHBhcnNlZCBhY2NvcmRpbmcgdG8gaTE4bmV4dCBzeW50YXguXG4gICAqXG4gICAqIEV4YW1wbGUgSlNPTiBjb250ZW50OlxuICAgKiBgYGBqc1xuICAgKiAge1xuICAgKiAgICBcImVuXCI6IHsgICAgICAgICAgICAgICAvLyByZXNvdXJjZSBmb3IgbGFuZ3VhZ2UgYGVuYCAoRW5nbGlzaClcbiAgICogICAgICBcInRyYW5zbGF0aW9uXCI6IHtcbiAgICogICAgICAgIFwiZ3JlZXRpbmdcIjogXCJIZWxsbyFcIlxuICAgKiAgICAgIH1cbiAgICogICAgfSxcbiAgICogICAgXCJkZVwiOiB7ICAgICAgICAgICAgICAgLy8gcmVzb3VyY2UgZm9yIGxhbmd1YWdlIGBkZWAgKEdlcm1hbilcbiAgICogICAgICBcInRyYW5zbGF0aW9uXCI6IHtcbiAgICogICAgICAgIFwiZ3JlZXRpbmdcIjogXCJIYWxsbyFcIlxuICAgKiAgICAgIH1cbiAgICogICAgfVxuICAgKiAgICBcImRlLUNIXCI6IHsgICAgICAgICAgICAvLyByZXNvdXJjZSBmb3IgbG9jYWxlIGBkZS1DSGAgKFN3aXNzIEdlcm1hbilcbiAgICogICAgICBcInRyYW5zbGF0aW9uXCI6IHtcbiAgICogICAgICAgIFwiZ3JlZXRpbmdcIjogXCJHcsO8ZXppIVwiXG4gICAqICAgICAgfVxuICAgKiAgICB9XG4gICAqICB9XG4gICAqIGBgYFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbG9jYWxlIFRoZSBsb2NhbGUgdG8gdHJhbnNsYXRlIHRvLlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBUaGUgdHJhbnNsYXRpb24gb3IgYW4gZW1wdHkgb2JqZWN0IGlmIG5vIG1hdGNoaW5nXG4gICAqIHRyYW5zbGF0aW9uIHdhcyBmb3VuZC5cbiAgICovXG4gIGdldEpzb25UcmFuc2xhdGlvbihsb2NhbGUpIHtcbiAgICAvLyBJZiB0aGVyZSBpcyBubyBKU09OIHJlc291cmNlXG4gICAgaWYgKHRoaXMuanNvblBhcmFtZXRlcnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cblxuICAgIC8vIElmIGxvY2FsZSBpcyBub3Qgc2V0IHVzZSB0aGUgZmFsbGJhY2sgbG9jYWxlXG4gICAgbG9jYWxlID0gbG9jYWxlIHx8IHRoaXMucGFnZXNDb25maWcubG9jYWxpemF0aW9uRmFsbGJhY2tMb2NhbGU7XG5cbiAgICAvLyBHZXQgbWF0Y2hpbmcgdHJhbnNsYXRpb24gYnkgbG9jYWxlLCBsYW5ndWFnZSBvciBmYWxsYmFjayBsb2NhbGVcbiAgICBjb25zdCBsYW5ndWFnZSA9IGxvY2FsZS5zcGxpdCgnLScpWzBdO1xuICAgIGNvbnN0IHJlc291cmNlID1cbiAgICAgIHRoaXMuanNvblBhcmFtZXRlcnNbbG9jYWxlXSB8fFxuICAgICAgdGhpcy5qc29uUGFyYW1ldGVyc1tsYW5ndWFnZV0gfHxcbiAgICAgIHRoaXMuanNvblBhcmFtZXRlcnNbdGhpcy5wYWdlc0NvbmZpZy5sb2NhbGl6YXRpb25GYWxsYmFja0xvY2FsZV0gfHxcbiAgICAgIHt9O1xuICAgIGNvbnN0IHRyYW5zbGF0aW9uID0gcmVzb3VyY2UudHJhbnNsYXRpb24gfHwge307XG4gICAgcmV0dXJuIHRyYW5zbGF0aW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSB0cmFuc2xhdGlvbiBmcm9tIHRoZSBKU09OIHJlc291cmNlIGZvciBhIGdpdmVuIGxvY2FsZSB3aXRoXG4gICAqIHBsYWNlaG9sZGVycyBmaWxsZWQgaW4gYnkgZ2l2ZW4gcGFyYW1ldGVycy5cbiAgICogQHBhcmFtIHtTdHJpbmd9IGxvY2FsZSBUaGUgbG9jYWxlIHRvIHRyYW5zbGF0ZSB0by5cbiAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyBUaGUgcGFyYW1ldGVycyB0byBmaWxsIGludG8gYW55IHBsYWNlaG9sZGVyc1xuICAgKiB3aXRoaW4gdGhlIHRyYW5zbGF0aW9ucy5cbiAgICogQHJldHVybnMge09iamVjdH0gVGhlIHRyYW5zbGF0aW9uIG9yIGFuIGVtcHR5IG9iamVjdCBpZiBubyBtYXRjaGluZ1xuICAgKiB0cmFuc2xhdGlvbiB3YXMgZm91bmQuXG4gICAqL1xuICBnZXRKc29uUGxhY2Vob2xkZXJzKGxvY2FsZSwgcGFyYW1zID0ge30pIHtcbiAgICAvLyBJZiBsb2NhbGl6YXRpb24gaXMgZGlzYWJsZWQgb3IgdGhlcmUgaXMgbm8gSlNPTiByZXNvdXJjZVxuICAgIGlmICghdGhpcy5wYWdlc0NvbmZpZy5lbmFibGVMb2NhbGl6YXRpb24gfHwgIXRoaXMucGFnZXNDb25maWcubG9jYWxpemF0aW9uSnNvblBhdGgpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG5cbiAgICAvLyBHZXQgSlNPTiBwbGFjZWhvbGRlcnNcbiAgICBsZXQgcGxhY2Vob2xkZXJzID0gdGhpcy5nZXRKc29uVHJhbnNsYXRpb24obG9jYWxlKTtcblxuICAgIC8vIEZpbGwgaW4gYW55IHBsYWNlaG9sZGVycyBpbiB0aGUgdHJhbnNsYXRpb247IHRoaXMgYWxsb3dzIGEgdHJhbnNsYXRpb25cbiAgICAvLyB0byBjb250YWluIGRlZmF1bHQgcGxhY2Vob2xkZXJzIGxpa2Uge3thcHBOYW1lfX0gd2hpY2ggYXJlIGZpbGxlZCBoZXJlXG4gICAgcGxhY2Vob2xkZXJzID0gSlNPTi5zdHJpbmdpZnkocGxhY2Vob2xkZXJzKTtcbiAgICBwbGFjZWhvbGRlcnMgPSBtdXN0YWNoZS5yZW5kZXIocGxhY2Vob2xkZXJzLCBwYXJhbXMpO1xuICAgIHBsYWNlaG9sZGVycyA9IEpTT04ucGFyc2UocGxhY2Vob2xkZXJzKTtcblxuICAgIHJldHVybiBwbGFjZWhvbGRlcnM7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHJlc3BvbnNlIHdpdGggZmlsZSBjb250ZW50LlxuICAgKiBAcGFyYW0ge1N0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgZmlsZSB0byByZXR1cm4uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbcGFyYW1zPXt9XSBUaGUgcGFyYW1ldGVycyB0byBiZSBpbmNsdWRlZCBpbiB0aGUgcmVzcG9uc2VcbiAgICogaGVhZGVyLiBUaGVzZSB3aWxsIGFsc28gYmUgdXNlZCB0byBmaWxsIHBsYWNlaG9sZGVycy5cbiAgICogQHBhcmFtIHtPYmplY3R9IFtwbGFjZWhvbGRlcnM9e31dIFRoZSBwbGFjZWhvbGRlcnMgdG8gZmlsbCBpbiB0aGUgY29udGVudC5cbiAgICogVGhlc2Ugd2lsbCBub3QgYmUgaW5jbHVkZWQgaW4gdGhlIHJlc3BvbnNlIGhlYWRlci5cbiAgICogQHJldHVybnMge09iamVjdH0gVGhlIFByb21pc2UgUm91dGVyIHJlc3BvbnNlLlxuICAgKi9cbiAgYXN5bmMgcGFnZVJlc3BvbnNlKHBhdGgsIHBhcmFtcyA9IHt9LCBwbGFjZWhvbGRlcnMgPSB7fSkge1xuICAgIC8vIEdldCBmaWxlIGNvbnRlbnRcbiAgICBsZXQgZGF0YTtcbiAgICB0cnkge1xuICAgICAgZGF0YSA9IGF3YWl0IHRoaXMucmVhZEZpbGUocGF0aCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIHRoaXMubm90Rm91bmQoKTtcbiAgICB9XG5cbiAgICAvLyBHZXQgY29uZmlnIHBsYWNlaG9sZGVyczsgY2FuIGJlIGFuIG9iamVjdCwgYSBmdW5jdGlvbiBvciBhbiBhc3luYyBmdW5jdGlvblxuICAgIGxldCBjb25maWdQbGFjZWhvbGRlcnMgPVxuICAgICAgdHlwZW9mIHRoaXMucGFnZXNDb25maWcucGxhY2Vob2xkZXJzID09PSAnZnVuY3Rpb24nXG4gICAgICAgID8gdGhpcy5wYWdlc0NvbmZpZy5wbGFjZWhvbGRlcnMocGFyYW1zKVxuICAgICAgICA6IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0aGlzLnBhZ2VzQ29uZmlnLnBsYWNlaG9sZGVycykgPT09ICdbb2JqZWN0IE9iamVjdF0nXG4gICAgICAgICAgPyB0aGlzLnBhZ2VzQ29uZmlnLnBsYWNlaG9sZGVyc1xuICAgICAgICAgIDoge307XG4gICAgaWYgKGNvbmZpZ1BsYWNlaG9sZGVycyBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgIGNvbmZpZ1BsYWNlaG9sZGVycyA9IGF3YWl0IGNvbmZpZ1BsYWNlaG9sZGVycztcbiAgICB9XG5cbiAgICAvLyBGaWxsIHBsYWNlaG9sZGVyc1xuICAgIGNvbnN0IGFsbFBsYWNlaG9sZGVycyA9IE9iamVjdC5hc3NpZ24oe30sIGNvbmZpZ1BsYWNlaG9sZGVycywgcGxhY2Vob2xkZXJzKTtcbiAgICBjb25zdCBwYXJhbXNBbmRQbGFjZWhvbGRlcnMgPSBPYmplY3QuYXNzaWduKHt9LCBwYXJhbXMsIGFsbFBsYWNlaG9sZGVycyk7XG4gICAgZGF0YSA9IG11c3RhY2hlLnJlbmRlcihkYXRhLCBwYXJhbXNBbmRQbGFjZWhvbGRlcnMpO1xuXG4gICAgLy8gQWRkIHBsYWNlaG9sZGVycyBpbiBoZWFkZXIgdG8gYWxsb3cgcGFyc2luZyBmb3IgcHJvZ3JhbW1hdGljIHVzZVxuICAgIC8vIG9mIHJlc3BvbnNlLCBpbnN0ZWFkIG9mIGhhdmluZyB0byBwYXJzZSB0aGUgSFRNTCBjb250ZW50LlxuICAgIGNvbnN0IGhlYWRlcnMgPSBPYmplY3QuZW50cmllcyhwYXJhbXMpLnJlZHVjZSgobSwgcCkgPT4ge1xuICAgICAgaWYgKHBbMV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBtW2Ake3BhZ2VQYXJhbUhlYWRlclByZWZpeH0ke3BbMF0udG9Mb3dlckNhc2UoKX1gXSA9IHBbMV07XG4gICAgICB9XG4gICAgICByZXR1cm4gbTtcbiAgICB9LCB7fSk7XG5cbiAgICByZXR1cm4geyB0ZXh0OiBkYXRhLCBoZWFkZXJzOiBoZWFkZXJzIH07XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHJlc3BvbnNlIHdpdGggZmlsZSBjb250ZW50LlxuICAgKiBAcGFyYW0ge1N0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgZmlsZSB0byByZXR1cm4uXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFRoZSBQcm9taXNlUm91dGVyIHJlc3BvbnNlLlxuICAgKi9cbiAgYXN5bmMgZmlsZVJlc3BvbnNlKHBhdGgpIHtcbiAgICAvLyBHZXQgZmlsZSBjb250ZW50XG4gICAgbGV0IGRhdGE7XG4gICAgdHJ5IHtcbiAgICAgIGRhdGEgPSBhd2FpdCB0aGlzLnJlYWRGaWxlKHBhdGgpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiB0aGlzLm5vdEZvdW5kKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgdGV4dDogZGF0YSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYWRzIGFuZCByZXR1cm5zIHRoZSBjb250ZW50IG9mIGEgZmlsZSBhdCBhIGdpdmVuIHBhdGguIEZpbGUgcmVhZGluZyB0b1xuICAgKiBzZXJ2ZSBjb250ZW50IG9uIHRoZSBzdGF0aWMgcm91dGUgaXMgb25seSBhbGxvd2VkIGZyb20gdGhlIHBhZ2VzXG4gICAqIGRpcmVjdG9yeSBvbiBkb3dud2FyZHMuXG4gICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAqICoqV0FSTklORzoqKiBBbGwgZmlsZSByZWFkcyBpbiB0aGUgUGFnZXNSb3V0ZXIgbXVzdCBiZSBleGVjdXRlZCBieSB0aGlzXG4gICAqIHdyYXBwZXIgYmVjYXVzZSBpdCBhbHNvIGRldGVjdHMgYW5kIHByZXZlbnRzIGNvbW1vbiBleHBsb2l0cy5cbiAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICogQHBhcmFtIHtTdHJpbmd9IGZpbGVQYXRoIFRoZSBwYXRoIHRvIHRoZSBmaWxlIHRvIHJlYWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFN0cmluZz59IFRoZSBmaWxlIGNvbnRlbnQuXG4gICAqL1xuICBhc3luYyByZWFkRmlsZShmaWxlUGF0aCkge1xuICAgIC8vIE5vcm1hbGl6ZSBwYXRoIHRvIHByZXZlbnQgaXQgZnJvbSBjb250YWluaW5nIGFueSBkaXJlY3RvcnkgY2hhbmdpbmdcbiAgICAvLyBVTklYIHBhdHRlcm5zIHdoaWNoIGNvdWxkIGV4cG9zZSB0aGUgd2hvbGUgZmlsZSBzeXN0ZW0sIGUuZy5cbiAgICAvLyBgaHR0cDovL2V4YW1wbGUuY29tL3BhcnNlL2FwcHMvLi4vZmlsZS50eHRgIHJlcXVlc3RzIGEgZmlsZSBvdXRzaWRlXG4gICAgLy8gb2YgdGhlIHBhZ2VzIGRpcmVjdG9yeSBzY29wZS5cbiAgICBjb25zdCBub3JtYWxpemVkUGF0aCA9IHBhdGgubm9ybWFsaXplKGZpbGVQYXRoKTtcblxuICAgIC8vIEFib3J0IGlmIHRoZSBwYXRoIGlzIG91dHNpZGUgb2YgdGhlIHBhdGggZGlyZWN0b3J5IHNjb3BlXG4gICAgaWYgKCFub3JtYWxpemVkUGF0aC5zdGFydHNXaXRoKHRoaXMucGFnZXNQYXRoKSkge1xuICAgICAgdGhyb3cgZXJyb3JzLmZpbGVPdXRzaWRlQWxsb3dlZFNjb3BlO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCBmcy5yZWFkRmlsZShub3JtYWxpemVkUGF0aCwgJ3V0Zi04Jyk7XG4gIH1cblxuICAvKipcbiAgICogTG9hZHMgYSBsYW5ndWFnZSByZXNvdXJjZSBKU09OIGZpbGUgdGhhdCBpcyB1c2VkIGZvciB0cmFuc2xhdGlvbnMuXG4gICAqL1xuICBsb2FkSnNvblJlc291cmNlKCkge1xuICAgIGlmICh0aGlzLnBhZ2VzQ29uZmlnLmxvY2FsaXphdGlvbkpzb25QYXRoID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGpzb24gPSByZXF1aXJlKHBhdGgucmVzb2x2ZSgnLi8nLCB0aGlzLnBhZ2VzQ29uZmlnLmxvY2FsaXphdGlvbkpzb25QYXRoKSk7XG4gICAgICB0aGlzLmpzb25QYXJhbWV0ZXJzID0ganNvbjtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBlcnJvcnMuanNvbkZhaWxlZEZpbGVMb2FkaW5nO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBFeHRyYWN0cyBhbmQgcmV0dXJucyB0aGUgcGFnZSBkZWZhdWx0IHBhcmFtZXRlcnMgZnJvbSB0aGUgUGFyc2UgU2VydmVyXG4gICAqIGNvbmZpZ3VyYXRpb24uIFRoZXNlIHBhcmFtZXRlcnMgYXJlIG1hZGUgYWNjZXNzaWJsZSBpbiBldmVyeSBwYWdlIHNlcnZlZFxuICAgKiBieSB0aGlzIHJvdXRlci5cbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyBUaGUgUGFyc2UgU2VydmVyIGNvbmZpZ3VyYXRpb24uXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFRoZSBkZWZhdWx0IHBhcmFtZXRlcnMuXG4gICAqL1xuICBnZXREZWZhdWx0UGFyYW1zKGNvbmZpZykge1xuICAgIHJldHVybiBjb25maWdcbiAgICAgID8ge1xuICAgICAgICBbcGFnZVBhcmFtcy5hcHBJZF06IGNvbmZpZy5hcHBJZCxcbiAgICAgICAgW3BhZ2VQYXJhbXMuYXBwTmFtZV06IGNvbmZpZy5hcHBOYW1lLFxuICAgICAgICBbcGFnZVBhcmFtcy5wdWJsaWNTZXJ2ZXJVcmxdOiBjb25maWcucHVibGljU2VydmVyVVJMLFxuICAgICAgfVxuICAgICAgOiB7fTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHRyYWN0cyBhbmQgcmV0dXJucyB0aGUgbG9jYWxlIGZyb20gYW4gZXhwcmVzcyByZXF1ZXN0LlxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxIFRoZSBleHByZXNzIHJlcXVlc3QuXG4gICAqIEByZXR1cm5zIHtTdHJpbmd8dW5kZWZpbmVkfSBUaGUgbG9jYWxlLCBvciB1bmRlZmluZWQgaWYgbm8gbG9jYWxlIHdhcyBzZXQuXG4gICAqL1xuICBnZXRMb2NhbGUocmVxKSB7XG4gICAgY29uc3QgbG9jYWxlID1cbiAgICAgIChyZXEucXVlcnkgfHwge30pW3BhZ2VQYXJhbXMubG9jYWxlXSB8fFxuICAgICAgKHJlcS5ib2R5IHx8IHt9KVtwYWdlUGFyYW1zLmxvY2FsZV0gfHxcbiAgICAgIChyZXEucGFyYW1zIHx8IHt9KVtwYWdlUGFyYW1zLmxvY2FsZV0gfHxcbiAgICAgIChyZXEuaGVhZGVycyB8fCB7fSlbcGFnZVBhcmFtSGVhZGVyUHJlZml4ICsgcGFnZVBhcmFtcy5sb2NhbGVdO1xuICAgIHJldHVybiBsb2NhbGU7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHJlc3BvbnNlIHdpdGggaHR0cCByZWRpcmV0LlxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxIFRoZSBleHByZXNzIHJlcXVlc3QuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBmaWxlIHRvIHJldHVybi5cbiAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyBUaGUgcXVlcnkgcGFyYW1ldGVycyB0byBpbmNsdWRlLlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBUaGUgUHJvbWlzZSBSb3V0ZXIgcmVzcG9uc2UuXG4gICAqL1xuICBhc3luYyByZWRpcmVjdFJlc3BvbnNlKHVybCwgcGFyYW1zKSB7XG4gICAgLy8gUmVtb3ZlIGFueSBwYXJhbWV0ZXJzIHdpdGggdW5kZWZpbmVkIHZhbHVlXG4gICAgcGFyYW1zID0gT2JqZWN0LmVudHJpZXMocGFyYW1zKS5yZWR1Y2UoKG0sIHApID0+IHtcbiAgICAgIGlmIChwWzFdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbVtwWzBdXSA9IHBbMV07XG4gICAgICB9XG4gICAgICByZXR1cm4gbTtcbiAgICB9LCB7fSk7XG5cbiAgICAvLyBDb21wb3NlIFVSTCB3aXRoIHBhcmFtZXRlcnMgaW4gcXVlcnlcbiAgICBjb25zdCBsb2NhdGlvbiA9IG5ldyBVUkwodXJsKTtcbiAgICBPYmplY3QuZW50cmllcyhwYXJhbXMpLmZvckVhY2gocCA9PiBsb2NhdGlvbi5zZWFyY2hQYXJhbXMuc2V0KHBbMF0sIHBbMV0pKTtcbiAgICBjb25zdCBsb2NhdGlvblN0cmluZyA9IGxvY2F0aW9uLnRvU3RyaW5nKCk7XG5cbiAgICAvLyBBZGQgcGFyYW1ldGVycyB0byBoZWFkZXIgdG8gYWxsb3cgcGFyc2luZyBmb3IgcHJvZ3JhbW1hdGljIHVzZVxuICAgIC8vIG9mIHJlc3BvbnNlLCBpbnN0ZWFkIG9mIGhhdmluZyB0byBwYXJzZSB0aGUgSFRNTCBjb250ZW50LlxuICAgIGNvbnN0IGhlYWRlcnMgPSBPYmplY3QuZW50cmllcyhwYXJhbXMpLnJlZHVjZSgobSwgcCkgPT4ge1xuICAgICAgaWYgKHBbMV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBtW2Ake3BhZ2VQYXJhbUhlYWRlclByZWZpeH0ke3BbMF0udG9Mb3dlckNhc2UoKX1gXSA9IHBbMV07XG4gICAgICB9XG4gICAgICByZXR1cm4gbTtcbiAgICB9LCB7fSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiAzMDMsXG4gICAgICBsb2NhdGlvbjogbG9jYXRpb25TdHJpbmcsXG4gICAgICBoZWFkZXJzOiBoZWFkZXJzLFxuICAgIH07XG4gIH1cblxuICBkZWZhdWx0UGFnZVBhdGgoZmlsZSkge1xuICAgIHJldHVybiBwYXRoLmpvaW4odGhpcy5wYWdlc1BhdGgsIGZpbGUpO1xuICB9XG5cbiAgY29tcG9zZVBhZ2VVcmwoZmlsZSwgcHVibGljU2VydmVyVXJsLCBsb2NhbGUpIHtcbiAgICBsZXQgdXJsID0gcHVibGljU2VydmVyVXJsO1xuICAgIHVybCArPSB1cmwuZW5kc1dpdGgoJy8nKSA/ICcnIDogJy8nO1xuICAgIHVybCArPSB0aGlzLnBhZ2VzRW5kcG9pbnQgKyAnLyc7XG4gICAgdXJsICs9IGxvY2FsZSA9PT0gdW5kZWZpbmVkID8gJycgOiBsb2NhbGUgKyAnLyc7XG4gICAgdXJsICs9IGZpbGU7XG4gICAgcmV0dXJuIHVybDtcbiAgfVxuXG4gIG5vdEZvdW5kKCkge1xuICAgIHJldHVybiB7XG4gICAgICB0ZXh0OiAnTm90IGZvdW5kLicsXG4gICAgICBzdGF0dXM6IDQwNCxcbiAgICB9O1xuICB9XG5cbiAgaW52YWxpZFJlcXVlc3QoKSB7XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoKTtcbiAgICBlcnJvci5zdGF0dXMgPSA0MDM7XG4gICAgZXJyb3IubWVzc2FnZSA9ICd1bmF1dGhvcml6ZWQnO1xuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIFBhcnNlIFNlcnZlciBjb25maWd1cmF0aW9uIGluIHRoZSByZXF1ZXN0IG9iamVjdCB0byBtYWtlIGl0XG4gICAqIGVhc2lseSBhY2Nlc3NpYmxlIHRocm91Z2h0b3V0IHJlcXVlc3QgcHJvY2Vzc2luZy5cbiAgICogQHBhcmFtIHtPYmplY3R9IHJlcSBUaGUgcmVxdWVzdC5cbiAgICogQHBhcmFtIHtCb29sZWFufSBmYWlsR3JhY2VmdWxseSBJcyB0cnVlIGlmIGZhaWxpbmcgdG8gc2V0IHRoZSBjb25maWcgc2hvdWxkXG4gICAqIG5vdCByZXN1bHQgaW4gYW4gaW52YWxpZCByZXF1ZXN0IHJlc3BvbnNlLiBEZWZhdWx0IGlzIGBmYWxzZWAuXG4gICAqL1xuICBzZXRDb25maWcocmVxLCBmYWlsR3JhY2VmdWxseSA9IGZhbHNlKSB7XG4gICAgcmVxLmNvbmZpZyA9IENvbmZpZy5nZXQocmVxLnBhcmFtcy5hcHBJZCB8fCByZXEucXVlcnkuYXBwSWQpO1xuICAgIGlmICghcmVxLmNvbmZpZyAmJiAhZmFpbEdyYWNlZnVsbHkpIHtcbiAgICAgIHRoaXMuaW52YWxpZFJlcXVlc3QoKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgbW91bnRQYWdlc1JvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICBgLyR7dGhpcy5wYWdlc0VuZHBvaW50fS86YXBwSWQvdmVyaWZ5X2VtYWlsYCxcbiAgICAgIHJlcSA9PiB7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKHJlcSk7XG4gICAgICB9LFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmVyaWZ5RW1haWwocmVxKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdQT1NUJyxcbiAgICAgIGAvJHt0aGlzLnBhZ2VzRW5kcG9pbnR9LzphcHBJZC9yZXNlbmRfdmVyaWZpY2F0aW9uX2VtYWlsYCxcbiAgICAgIHJlcSA9PiB7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKHJlcSk7XG4gICAgICB9LFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVzZW5kVmVyaWZpY2F0aW9uRW1haWwocmVxKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdHRVQnLFxuICAgICAgYC8ke3RoaXMucGFnZXNFbmRwb2ludH0vY2hvb3NlX3Bhc3N3b3JkYCxcbiAgICAgIHJlcSA9PiB7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKHJlcSk7XG4gICAgICB9LFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFzc3dvcmRSZXNldChyZXEpO1xuICAgICAgfVxuICAgICk7XG5cbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ1BPU1QnLFxuICAgICAgYC8ke3RoaXMucGFnZXNFbmRwb2ludH0vOmFwcElkL3JlcXVlc3RfcGFzc3dvcmRfcmVzZXRgLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgdGhpcy5zZXRDb25maWcocmVxKTtcbiAgICAgIH0sXG4gICAgICByZXEgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXNldFBhc3N3b3JkKHJlcSk7XG4gICAgICB9XG4gICAgKTtcblxuICAgIHRoaXMucm91dGUoXG4gICAgICAnR0VUJyxcbiAgICAgIGAvJHt0aGlzLnBhZ2VzRW5kcG9pbnR9LzphcHBJZC9yZXF1ZXN0X3Bhc3N3b3JkX3Jlc2V0YCxcbiAgICAgIHJlcSA9PiB7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKHJlcSk7XG4gICAgICB9LFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdFJlc2V0UGFzc3dvcmQocmVxKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdHRVQnLFxuICAgICAgYC8ke3RoaXMucGFnZXNFbmRwb2ludH0vKCopP2AsXG4gICAgICByZXEgPT4ge1xuICAgICAgICB0aGlzLnNldENvbmZpZyhyZXEsIHRydWUpO1xuICAgICAgfSxcbiAgICAgIHJlcSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXRpY1JvdXRlKHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIGV4cHJlc3NSb3V0ZXIoKSB7XG4gICAgY29uc3Qgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcbiAgICByb3V0ZXIudXNlKCcvJywgc3VwZXIuZXhwcmVzc1JvdXRlcigpKTtcbiAgICByZXR1cm4gcm91dGVyO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBhZ2VzUm91dGVyO1xubW9kdWxlLmV4cG9ydHMgPSB7XG4gIFBhZ2VzUm91dGVyLFxuICBwYWdlUGFyYW1IZWFkZXJQcmVmaXgsXG4gIHBhZ2VQYXJhbXMsXG4gIHBhZ2VzLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/PublicAPIRouter.js b/lib/Routers/PublicAPIRouter.js new file mode 100644 index 0000000000..1ee21b99b2 --- /dev/null +++ b/lib/Routers/PublicAPIRouter.js @@ -0,0 +1,322 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.PublicAPIRouter = void 0; + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var _Config = _interopRequireDefault(require("../Config")); + +var _express = _interopRequireDefault(require("express")); + +var _path = _interopRequireDefault(require("path")); + +var _fs = _interopRequireDefault(require("fs")); + +var _querystring = _interopRequireDefault(require("querystring")); + +var _node = require("parse/node"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const public_html = _path.default.resolve(__dirname, '../../public_html'); + +const views = _path.default.resolve(__dirname, '../../views'); + +class PublicAPIRouter extends _PromiseRouter.default { + verifyEmail(req) { + const { + username, + token: rawToken + } = req.query; + const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken; + const appId = req.params.appId; + + const config = _Config.default.get(appId); + + if (!config) { + this.invalidRequest(); + } + + if (!config.publicServerURL) { + return this.missingPublicServerURL(); + } + + if (!token || !username) { + return this.invalidLink(req); + } + + const userController = config.userController; + return userController.verifyEmail(username, token).then(() => { + const params = _querystring.default.stringify({ + username + }); + + return Promise.resolve({ + status: 302, + location: `${config.verifyEmailSuccessURL}?${params}` + }); + }, () => { + return this.invalidVerificationLink(req); + }); + } + + resendVerificationEmail(req) { + const username = req.body.username; + const appId = req.params.appId; + + const config = _Config.default.get(appId); + + if (!config) { + this.invalidRequest(); + } + + if (!config.publicServerURL) { + return this.missingPublicServerURL(); + } + + if (!username) { + return this.invalidLink(req); + } + + const userController = config.userController; + return userController.resendVerificationEmail(username).then(() => { + return Promise.resolve({ + status: 302, + location: `${config.linkSendSuccessURL}` + }); + }, () => { + return Promise.resolve({ + status: 302, + location: `${config.linkSendFailURL}` + }); + }); + } + + changePassword(req) { + return new Promise((resolve, reject) => { + const config = _Config.default.get(req.query.id); + + if (!config) { + this.invalidRequest(); + } + + if (!config.publicServerURL) { + return resolve({ + status: 404, + text: 'Not found.' + }); + } // Should we keep the file in memory or leave like that? + + + _fs.default.readFile(_path.default.resolve(views, 'choose_password'), 'utf-8', (err, data) => { + if (err) { + return reject(err); + } + + data = data.replace('PARSE_SERVER_URL', `'${config.publicServerURL}'`); + resolve({ + text: data + }); + }); + }); + } + + requestResetPassword(req) { + const config = req.config; + + if (!config) { + this.invalidRequest(); + } + + if (!config.publicServerURL) { + return this.missingPublicServerURL(); + } + + const { + username, + token: rawToken + } = req.query; + const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken; + + if (!username || !token) { + return this.invalidLink(req); + } + + return config.userController.checkResetTokenValidity(username, token).then(() => { + const params = _querystring.default.stringify({ + token, + id: config.applicationId, + username, + app: config.appName + }); + + return Promise.resolve({ + status: 302, + location: `${config.choosePasswordURL}?${params}` + }); + }, () => { + return this.invalidLink(req); + }); + } + + resetPassword(req) { + const config = req.config; + + if (!config) { + this.invalidRequest(); + } + + if (!config.publicServerURL) { + return this.missingPublicServerURL(); + } + + const { + username, + new_password, + token: rawToken + } = req.body; + const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken; + + if ((!username || !token || !new_password) && req.xhr === false) { + return this.invalidLink(req); + } + + if (!username) { + throw new _node.Parse.Error(_node.Parse.Error.USERNAME_MISSING, 'Missing username'); + } + + if (!token) { + throw new _node.Parse.Error(_node.Parse.Error.OTHER_CAUSE, 'Missing token'); + } + + if (!new_password) { + throw new _node.Parse.Error(_node.Parse.Error.PASSWORD_MISSING, 'Missing password'); + } + + return config.userController.updatePassword(username, token, new_password).then(() => { + return Promise.resolve({ + success: true + }); + }, err => { + return Promise.resolve({ + success: false, + err + }); + }).then(result => { + const params = _querystring.default.stringify({ + username: username, + token: token, + id: config.applicationId, + error: result.err, + app: config.appName + }); + + if (req.xhr) { + if (result.success) { + return Promise.resolve({ + status: 200, + response: 'Password successfully reset' + }); + } + + if (result.err) { + throw new _node.Parse.Error(_node.Parse.Error.OTHER_CAUSE, `${result.err}`); + } + } + + const encodedUsername = encodeURIComponent(username); + const location = result.success ? `${config.passwordResetSuccessURL}?username=${encodedUsername}` : `${config.choosePasswordURL}?${params}`; + return Promise.resolve({ + status: 302, + location + }); + }); + } + + invalidLink(req) { + return Promise.resolve({ + status: 302, + location: req.config.invalidLinkURL + }); + } + + invalidVerificationLink(req) { + const config = req.config; + + if (req.query.username && req.params.appId) { + const params = _querystring.default.stringify({ + username: req.query.username, + appId: req.params.appId + }); + + return Promise.resolve({ + status: 302, + location: `${config.invalidVerificationLinkURL}?${params}` + }); + } else { + return this.invalidLink(req); + } + } + + missingPublicServerURL() { + return Promise.resolve({ + text: 'Not found.', + status: 404 + }); + } + + invalidRequest() { + const error = new Error(); + error.status = 403; + error.message = 'unauthorized'; + throw error; + } + + setConfig(req) { + req.config = _Config.default.get(req.params.appId); + return Promise.resolve(); + } + + mountRoutes() { + this.route('GET', '/apps/:appId/verify_email', req => { + this.setConfig(req); + }, req => { + return this.verifyEmail(req); + }); + this.route('POST', '/apps/:appId/resend_verification_email', req => { + this.setConfig(req); + }, req => { + return this.resendVerificationEmail(req); + }); + this.route('GET', '/apps/choose_password', req => { + return this.changePassword(req); + }); + this.route('POST', '/apps/:appId/request_password_reset', req => { + this.setConfig(req); + }, req => { + return this.resetPassword(req); + }); + this.route('GET', '/apps/:appId/request_password_reset', req => { + this.setConfig(req); + }, req => { + return this.requestResetPassword(req); + }); + } + + expressRouter() { + const router = _express.default.Router(); + + router.use('/apps', _express.default.static(public_html)); + router.use('/', super.expressRouter()); + return router; + } + +} + +exports.PublicAPIRouter = PublicAPIRouter; +var _default = PublicAPIRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1B1YmxpY0FQSVJvdXRlci5qcyJdLCJuYW1lcyI6WyJwdWJsaWNfaHRtbCIsInBhdGgiLCJyZXNvbHZlIiwiX19kaXJuYW1lIiwidmlld3MiLCJQdWJsaWNBUElSb3V0ZXIiLCJQcm9taXNlUm91dGVyIiwidmVyaWZ5RW1haWwiLCJyZXEiLCJ1c2VybmFtZSIsInRva2VuIiwicmF3VG9rZW4iLCJxdWVyeSIsInRvU3RyaW5nIiwiYXBwSWQiLCJwYXJhbXMiLCJjb25maWciLCJDb25maWciLCJnZXQiLCJpbnZhbGlkUmVxdWVzdCIsInB1YmxpY1NlcnZlclVSTCIsIm1pc3NpbmdQdWJsaWNTZXJ2ZXJVUkwiLCJpbnZhbGlkTGluayIsInVzZXJDb250cm9sbGVyIiwidGhlbiIsInFzIiwic3RyaW5naWZ5IiwiUHJvbWlzZSIsInN0YXR1cyIsImxvY2F0aW9uIiwidmVyaWZ5RW1haWxTdWNjZXNzVVJMIiwiaW52YWxpZFZlcmlmaWNhdGlvbkxpbmsiLCJyZXNlbmRWZXJpZmljYXRpb25FbWFpbCIsImJvZHkiLCJsaW5rU2VuZFN1Y2Nlc3NVUkwiLCJsaW5rU2VuZEZhaWxVUkwiLCJjaGFuZ2VQYXNzd29yZCIsInJlamVjdCIsImlkIiwidGV4dCIsImZzIiwicmVhZEZpbGUiLCJlcnIiLCJkYXRhIiwicmVwbGFjZSIsInJlcXVlc3RSZXNldFBhc3N3b3JkIiwiY2hlY2tSZXNldFRva2VuVmFsaWRpdHkiLCJhcHBsaWNhdGlvbklkIiwiYXBwIiwiYXBwTmFtZSIsImNob29zZVBhc3N3b3JkVVJMIiwicmVzZXRQYXNzd29yZCIsIm5ld19wYXNzd29yZCIsInhociIsIlBhcnNlIiwiRXJyb3IiLCJVU0VSTkFNRV9NSVNTSU5HIiwiT1RIRVJfQ0FVU0UiLCJQQVNTV09SRF9NSVNTSU5HIiwidXBkYXRlUGFzc3dvcmQiLCJzdWNjZXNzIiwicmVzdWx0IiwiZXJyb3IiLCJyZXNwb25zZSIsImVuY29kZWRVc2VybmFtZSIsImVuY29kZVVSSUNvbXBvbmVudCIsInBhc3N3b3JkUmVzZXRTdWNjZXNzVVJMIiwiaW52YWxpZExpbmtVUkwiLCJpbnZhbGlkVmVyaWZpY2F0aW9uTGlua1VSTCIsIm1lc3NhZ2UiLCJzZXRDb25maWciLCJtb3VudFJvdXRlcyIsInJvdXRlIiwiZXhwcmVzc1JvdXRlciIsInJvdXRlciIsImV4cHJlc3MiLCJSb3V0ZXIiLCJ1c2UiLCJzdGF0aWMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUVBLE1BQU1BLFdBQVcsR0FBR0MsY0FBS0MsT0FBTCxDQUFhQyxTQUFiLEVBQXdCLG1CQUF4QixDQUFwQjs7QUFDQSxNQUFNQyxLQUFLLEdBQUdILGNBQUtDLE9BQUwsQ0FBYUMsU0FBYixFQUF3QixhQUF4QixDQUFkOztBQUVPLE1BQU1FLGVBQU4sU0FBOEJDLHNCQUE5QixDQUE0QztBQUNqREMsRUFBQUEsV0FBVyxDQUFDQyxHQUFELEVBQU07QUFDZixVQUFNO0FBQUVDLE1BQUFBLFFBQUY7QUFBWUMsTUFBQUEsS0FBSyxFQUFFQztBQUFuQixRQUFnQ0gsR0FBRyxDQUFDSSxLQUExQztBQUNBLFVBQU1GLEtBQUssR0FBR0MsUUFBUSxJQUFJLE9BQU9BLFFBQVAsS0FBb0IsUUFBaEMsR0FBMkNBLFFBQVEsQ0FBQ0UsUUFBVCxFQUEzQyxHQUFpRUYsUUFBL0U7QUFFQSxVQUFNRyxLQUFLLEdBQUdOLEdBQUcsQ0FBQ08sTUFBSixDQUFXRCxLQUF6Qjs7QUFDQSxVQUFNRSxNQUFNLEdBQUdDLGdCQUFPQyxHQUFQLENBQVdKLEtBQVgsQ0FBZjs7QUFFQSxRQUFJLENBQUNFLE1BQUwsRUFBYTtBQUNYLFdBQUtHLGNBQUw7QUFDRDs7QUFFRCxRQUFJLENBQUNILE1BQU0sQ0FBQ0ksZUFBWixFQUE2QjtBQUMzQixhQUFPLEtBQUtDLHNCQUFMLEVBQVA7QUFDRDs7QUFFRCxRQUFJLENBQUNYLEtBQUQsSUFBVSxDQUFDRCxRQUFmLEVBQXlCO0FBQ3ZCLGFBQU8s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cnQgQ29uZmlnIGZyb20gJy4uL0NvbmZpZyc7XG5pbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IGZzIGZyb20gJ2ZzJztcbmltcG9ydCBxcyBmcm9tICdxdWVyeXN0cmluZyc7XG5pbXBvcnQgeyBQYXJzZSB9IGZyb20gJ3BhcnNlL25vZGUnO1xuXG5jb25zdCBwdWJsaWNfaHRtbCA9IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuLi8uLi9wdWJsaWNfaHRtbCcpO1xuY29uc3Qgdmlld3MgPSBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4vLi4vdmlld3MnKTtcblxuZXhwb3J0IGNsYXNzIFB1YmxpY0FQSVJvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICB2ZXJpZnlFbWFpbChyZXEpIHtcbiAgICBjb25zdCB7IHVzZXJuYW1lLCB0b2tlbjogcmF3VG9rZW4gfSA9IHJlcS5xdWVyeTtcbiAgICBjb25zdCB0b2tlbiA9IHJhd1Rva2VuICYmIHR5cGVvZiByYXdUb2tlbiAhPT0gJ3N0cmluZycgPyByYXdUb2tlbi50b1N0cmluZygpIDogcmF3VG9rZW47XG5cbiAgICBjb25zdCBhcHBJZCA9IHJlcS5wYXJhbXMuYXBwSWQ7XG4gICAgY29uc3QgY29uZmlnID0gQ29uZmlnLmdldChhcHBJZCk7XG5cbiAgICBpZiAoIWNvbmZpZykge1xuICAgICAgdGhpcy5pbnZhbGlkUmVxdWVzdCgpO1xuICAgIH1cblxuICAgIGlmICghY29uZmlnLnB1YmxpY1NlcnZlclVSTCkge1xuICAgICAgcmV0dXJuIHRoaXMubWlzc2luZ1B1YmxpY1NlcnZlclVSTCgpO1xuICAgIH1cblxuICAgIGlmICghdG9rZW4gfHwgIXVzZXJuYW1lKSB7XG4gICAgICByZXR1cm4gdGhpcy5pbnZhbGlkTGluayhyZXEpO1xuICAgIH1cblxuICAgIGNvbnN0IHVzZXJDb250cm9sbGVyID0gY29uZmlnLnVzZXJDb250cm9sbGVyO1xuICAgIHJldHVybiB1c2VyQ29udHJvbGxlci52ZXJpZnlFbWFpbCh1c2VybmFtZSwgdG9rZW4pLnRoZW4oXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHFzLnN0cmluZ2lmeSh7IHVzZXJuYW1lIH0pO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICBzdGF0dXM6IDMwMixcbiAgICAgICAgICBsb2NhdGlvbjogYCR7Y29uZmlnLnZlcmlmeUVtYWlsU3VjY2Vzc1VSTH0/JHtwYXJhbXN9YCxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgKCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pbnZhbGlkVmVyaWZpY2F0aW9uTGluayhyZXEpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICByZXNlbmRWZXJpZmljYXRpb25FbWFpbChyZXEpIHtcbiAgICBjb25zdCB1c2VybmFtZSA9IHJlcS5ib2R5LnVzZXJuYW1lO1xuICAgIGNvbnN0IGFwcElkID0gcmVxLnBhcmFtcy5hcHBJZDtcbiAgICBjb25zdCBjb25maWcgPSBDb25maWcuZ2V0KGFwcElkKTtcblxuICAgIGlmICghY29uZmlnKSB7XG4gICAgICB0aGlzLmludmFsaWRSZXF1ZXN0KCk7XG4gICAgfVxuXG4gICAgaWYgKCFjb25maWcucHVibGljU2VydmVyVVJMKSB7XG4gICAgICByZXR1cm4gdGhpcy5taXNzaW5nUHVibGljU2VydmVyVVJMKCk7XG4gICAgfVxuXG4gICAgaWYgKCF1c2VybmFtZSkge1xuICAgICAgcmV0dXJuIHRoaXMuaW52YWxpZExpbmsocmVxKTtcbiAgICB9XG5cbiAgICBjb25zdCB1c2VyQ29udHJvbGxlciA9IGNvbmZpZy51c2VyQ29udHJvbGxlcjtcblxuICAgIHJldHVybiB1c2VyQ29udHJvbGxlci5yZXNlbmRWZXJpZmljYXRpb25FbWFpbCh1c2VybmFtZSkudGhlbihcbiAgICAgICgpID0+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgc3RhdHVzOiAzMDIsXG4gICAgICAgICAgbG9jYXRpb246IGAke2NvbmZpZy5saW5rU2VuZFN1Y2Nlc3NVUkx9YCxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgKCkgPT4ge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICBzdGF0dXM6IDMwMixcbiAgICAgICAgICBsb2NhdGlvbjogYCR7Y29uZmlnLmxpbmtTZW5kRmFpbFVSTH1gLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgY2hhbmdlUGFzc3dvcmQocmVxKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IENvbmZpZy5nZXQocmVxLnF1ZXJ5LmlkKTtcblxuICAgICAgaWYgKCFjb25maWcpIHtcbiAgICAgICAgdGhpcy5pbnZhbGlkUmVxdWVzdCgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWNvbmZpZy5wdWJsaWNTZXJ2ZXJVUkwpIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUoe1xuICAgICAgICAgIHN0YXR1czogNDA0LFxuICAgICAgICAgIHRleHQ6ICdOb3QgZm91bmQuJyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICAvLyBTaG91bGQgd2Uga2VlcCB0aGUgZmlsZSBpbiBtZW1vcnkgb3IgbGVhdmUgbGlrZSB0aGF0P1xuICAgICAgZnMucmVhZEZpbGUocGF0aC5yZXNvbHZlKHZpZXdzLCAnY2hvb3NlX3Bhc3N3b3JkJyksICd1dGYtOCcsIChlcnIsIGRhdGEpID0+IHtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gZGF0YS5yZXBsYWNlKCdQQVJTRV9TRVJWRVJfVVJMJywgYCcke2NvbmZpZy5wdWJsaWNTZXJ2ZXJVUkx9J2ApO1xuICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICB0ZXh0OiBkYXRhLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcmVxdWVzdFJlc2V0UGFzc3dvcmQocmVxKSB7XG4gICAgY29uc3QgY29uZmlnID0gcmVxLmNvbmZpZztcblxuICAgIGlmICghY29uZmlnKSB7XG4gICAgICB0aGlzLmludmFsaWRSZXF1ZXN0KCk7XG4gICAgfVxuXG4gICAgaWYgKCFjb25maWcucHVibGljU2VydmVyVVJMKSB7XG4gICAgICByZXR1cm4gdGhpcy5taXNzaW5nUHVibGljU2VydmVyVVJMKCk7XG4gICAgfVxuXG4gICAgY29uc3QgeyB1c2VybmFtZSwgdG9rZW46IHJhd1Rva2VuIH0gPSByZXEucXVlcnk7XG4gICAgY29uc3QgdG9rZW4gPSByYXdUb2tlbiAmJiB0eXBlb2YgcmF3VG9rZW4gIT09ICdzdHJpbmcnID8gcmF3VG9rZW4udG9TdHJpbmcoKSA6IHJhd1Rva2VuO1xuXG4gICAgaWYgKCF1c2VybmFtZSB8fCAhdG9rZW4pIHtcbiAgICAgIHJldHVybiB0aGlzLmludmFsaWRMaW5rKHJlcSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbmZpZy51c2VyQ29udHJvbGxlci5jaGVja1Jlc2V0VG9rZW5WYWxpZGl0eSh1c2VybmFtZSwgdG9rZW4pLnRoZW4oXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHFzLnN0cmluZ2lmeSh7XG4gICAgICAgICAgdG9rZW4sXG4gICAgICAgICAgaWQ6IGNvbmZpZy5hcHBsaWNhdGlvbklkLFxuICAgICAgICAgIHVzZXJuYW1lLFxuICAgICAgICAgIGFwcDogY29uZmlnLmFwcE5hbWUsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICBzdGF0dXM6IDMwMixcbiAgICAgICAgICBsb2NhdGlvbjogYCR7Y29uZmlnLmNob29zZVBhc3N3b3JkVVJMfT8ke3BhcmFtc31gLFxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICAoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmludmFsaWRMaW5rKHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHJlc2V0UGFzc3dvcmQocmVxKSB7XG4gICAgY29uc3QgY29uZmlnID0gcmVxLmNvbmZpZztcblxuICAgIGlmICghY29uZmlnKSB7XG4gICAgICB0aGlzLmludmFsaWRSZXF1ZXN0KCk7XG4gICAgfVxuXG4gICAgaWYgKCFjb25maWcucHVibGljU2VydmVyVVJMKSB7XG4gICAgICByZXR1cm4gdGhpcy5taXNzaW5nUHVibGljU2VydmVyVVJMKCk7XG4gICAgfVxuXG4gICAgY29uc3QgeyB1c2VybmFtZSwgbmV3X3Bhc3N3b3JkLCB0b2tlbjogcmF3VG9rZW4gfSA9IHJlcS5ib2R5O1xuICAgIGNvbnN0IHRva2VuID0gcmF3VG9rZW4gJiYgdHlwZW9mIHJhd1Rva2VuICE9PSAnc3RyaW5nJyA/IHJhd1Rva2VuLnRvU3RyaW5nKCkgOiByYXdUb2tlbjtcblxuICAgIGlmICgoIXVzZXJuYW1lIHx8ICF0b2tlbiB8fCAhbmV3X3Bhc3N3b3JkKSAmJiByZXEueGhyID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuIHRoaXMuaW52YWxpZExpbmsocmVxKTtcbiAgICB9XG5cbiAgICBpZiAoIXVzZXJuYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuVVNFUk5BTUVfTUlTU0lORywgJ01pc3NpbmcgdXNlcm5hbWUnKTtcbiAgICB9XG5cbiAgICBpZiAoIXRva2VuKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT1RIRVJfQ0FVU0UsICdNaXNzaW5nIHRva2VuJyk7XG4gICAgfVxuXG4gICAgaWYgKCFuZXdfcGFzc3dvcmQpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5QQVNTV09SRF9NSVNTSU5HLCAnTWlzc2luZyBwYXNzd29yZCcpO1xuICAgIH1cblxuICAgIHJldHVybiBjb25maWcudXNlckNvbnRyb2xsZXJcbiAgICAgIC51cGRhdGVQYXNzd29yZCh1c2VybmFtZSwgdG9rZW4sIG5ld19wYXNzd29yZClcbiAgICAgIC50aGVuKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgICBlcnIgPT4ge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICBlcnIsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHFzLnN0cmluZ2lmeSh7XG4gICAgICAgICAgdXNlcm5hbWU6IHVzZXJuYW1lLFxuICAgICAgICAgIHRva2VuOiB0b2tlbixcbiAgICAgICAgICBpZDogY29uZmlnLmFwcGxpY2F0aW9uSWQsXG4gICAgICAgICAgZXJyb3I6IHJlc3VsdC5lcnIsXG4gICAgICAgICAgYXBwOiBjb25maWcuYXBwTmFtZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHJlcS54aHIpIHtcbiAgICAgICAgICBpZiAocmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgICAgICBzdGF0dXM6IDIwMCxcbiAgICAgICAgICAgICAgcmVzcG9uc2U6ICdQYXNzd29yZCBzdWNjZXNzZnVsbHkgcmVzZXQnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChyZXN1bHQuZXJyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT1RIRVJfQ0FVU0UsIGAke3Jlc3VsdC5lcnJ9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZW5jb2RlZFVzZXJuYW1lID0gZW5jb2RlVVJJQ29tcG9uZW50KHVzZXJuYW1lKTtcbiAgICAgICAgY29uc3QgbG9jYXRpb24gPSByZXN1bHQuc3VjY2Vzc1xuICAgICAgICAgID8gYCR7Y29uZmlnLnBhc3N3b3JkUmVzZXRTdWNjZXNzVVJMfT91c2VybmFtZT0ke2VuY29kZWRVc2VybmFtZX1gXG4gICAgICAgICAgOiBgJHtjb25maWcuY2hvb3NlUGFzc3dvcmRVUkx9PyR7cGFyYW1zfWA7XG5cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgc3RhdHVzOiAzMDIsXG4gICAgICAgICAgbG9jYXRpb24sXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gIH1cblxuICBpbnZhbGlkTGluayhyZXEpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgIHN0YXR1czogMzAyLFxuICAgICAgbG9jYXRpb246IHJlcS5jb25maWcuaW52YWxpZExpbmtVUkwsXG4gICAgfSk7XG4gIH1cblxuICBpbnZhbGlkVmVyaWZpY2F0aW9uTGluayhyZXEpIHtcbiAgICBjb25zdCBjb25maWcgPSByZXEuY29uZmlnO1xuICAgIGlmIChyZXEucXVlcnkudXNlcm5hbWUgJiYgcmVxLnBhcmFtcy5hcHBJZCkge1xuICAgICAgY29uc3QgcGFyYW1zID0gcXMuc3RyaW5naWZ5KHtcbiAgICAgICAgdXNlcm5hbWU6IHJlcS5xdWVyeS51c2VybmFtZSxcbiAgICAgICAgYXBwSWQ6IHJlcS5wYXJhbXMuYXBwSWQsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICBzdGF0dXM6IDMwMixcbiAgICAgICAgbG9jYXRpb246IGAke2NvbmZpZy5pbnZhbGlkVmVyaWZpY2F0aW9uTGlua1VSTH0/JHtwYXJhbXN9YCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5pbnZhbGlkTGluayhyZXEpO1xuICAgIH1cbiAgfVxuXG4gIG1pc3NpbmdQdWJsaWNTZXJ2ZXJVUkwoKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICB0ZXh0OiAnTm90IGZvdW5kLicsXG4gICAgICBzdGF0dXM6IDQwNCxcbiAgICB9KTtcbiAgfVxuXG4gIGludmFsaWRSZXF1ZXN0KCkge1xuICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKCk7XG4gICAgZXJyb3Iuc3RhdHVzID0gNDAzO1xuICAgIGVycm9yLm1lc3NhZ2UgPSAndW5hdXRob3JpemVkJztcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuXG4gIHNldENvbmZpZyhyZXEpIHtcbiAgICByZXEuY29uZmlnID0gQ29uZmlnLmdldChyZXEucGFyYW1zLmFwcElkKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2FwcHMvOmFwcElkL3ZlcmlmeV9lbWFpbCcsXG4gICAgICByZXEgPT4ge1xuICAgICAgICB0aGlzLnNldENvbmZpZyhyZXEpO1xuICAgICAgfSxcbiAgICAgIHJlcSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnZlcmlmeUVtYWlsKHJlcSk7XG4gICAgICB9XG4gICAgKTtcblxuICAgIHRoaXMucm91dGUoXG4gICAgICAnUE9TVCcsXG4gICAgICAnL2FwcHMvOmFwcElkL3Jlc2VuZF92ZXJpZmljYXRpb25fZW1haWwnLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgdGhpcy5zZXRDb25maWcocmVxKTtcbiAgICAgIH0sXG4gICAgICByZXEgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXNlbmRWZXJpZmljYXRpb25FbWFpbChyZXEpO1xuICAgICAgfVxuICAgICk7XG5cbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL2FwcHMvY2hvb3NlX3Bhc3N3b3JkJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmNoYW5nZVBhc3N3b3JkKHJlcSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ1BPU1QnLFxuICAgICAgJy9hcHBzLzphcHBJZC9yZXF1ZXN0X3Bhc3N3b3JkX3Jlc2V0JyxcbiAgICAgIHJlcSA9PiB7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKHJlcSk7XG4gICAgICB9LFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVzZXRQYXNzd29yZChyZXEpO1xuICAgICAgfVxuICAgICk7XG5cbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2FwcHMvOmFwcElkL3JlcXVlc3RfcGFzc3dvcmRfcmVzZXQnLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgdGhpcy5zZXRDb25maWcocmVxKTtcbiAgICAgIH0sXG4gICAgICByZXEgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0UmVzZXRQYXNzd29yZChyZXEpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBleHByZXNzUm91dGVyKCkge1xuICAgIGNvbnN0IHJvdXRlciA9IGV4cHJlc3MuUm91dGVyKCk7XG4gICAgcm91dGVyLnVzZSgnL2FwcHMnLCBleHByZXNzLnN0YXRpYyhwdWJsaWNfaHRtbCkpO1xuICAgIHJvdXRlci51c2UoJy8nLCBzdXBlci5leHByZXNzUm91dGVyKCkpO1xuICAgIHJldHVybiByb3V0ZXI7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUHVibGljQVBJUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/PurgeRouter.js b/lib/Routers/PurgeRouter.js new file mode 100644 index 0000000000..503d9eb543 --- /dev/null +++ b/lib/Routers/PurgeRouter.js @@ -0,0 +1,60 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.PurgeRouter = void 0; + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +var _node = _interopRequireDefault(require("parse/node")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class PurgeRouter extends _PromiseRouter.default { + handlePurge(req) { + if (req.auth.isReadOnly) { + throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to purge a schema."); + } + + return req.config.database.purgeCollection(req.params.className).then(() => { + var cacheAdapter = req.config.cacheController; + + if (req.params.className == '_Session') { + cacheAdapter.user.clear(); + } else if (req.params.className == '_Role') { + cacheAdapter.role.clear(); + } + + return { + response: {} + }; + }).catch(error => { + if (!error || error && error.code === _node.default.Error.OBJECT_NOT_FOUND) { + return { + response: {} + }; + } + + throw error; + }); + } + + mountRoutes() { + this.route('DELETE', '/purge/:className', middleware.promiseEnforceMasterKeyAccess, req => { + return this.handlePurge(req); + }); + } + +} + +exports.PurgeRouter = PurgeRouter; +var _default = PurgeRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1B1cmdlUm91dGVyLmpzIl0sIm5hbWVzIjpbIlB1cmdlUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsImhhbmRsZVB1cmdlIiwicmVxIiwiYXV0aCIsImlzUmVhZE9ubHkiLCJQYXJzZSIsIkVycm9yIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsImNvbmZpZyIsImRhdGFiYXNlIiwicHVyZ2VDb2xsZWN0aW9uIiwicGFyYW1zIiwiY2xhc3NOYW1lIiwidGhlbiIsImNhY2hlQWRhcHRlciIsImNhY2hlQ29udHJvbGxlciIsInVzZXIiLCJjbGVhciIsInJvbGUiLCJyZXNwb25zZSIsImNhdGNoIiwiZXJyb3IiLCJjb2RlIiwiT0JKRUNUX05PVF9GT1VORCIsIm1vdW50Um91dGVzIiwicm91dGUiLCJtaWRkbGV3YXJlIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFTyxNQUFNQSxXQUFOLFNBQTBCQyxzQkFBMUIsQ0FBd0M7QUFDN0NDLEVBQUFBLFdBQVcsQ0FBQ0MsR0FBRCxFQUFNO0FBQ2YsUUFBSUEsR0FBRyxDQUFDQyxJQUFKLENBQVNDLFVBQWIsRUFBeUI7QUFDdkIsWUFBTSxJQUFJQyxjQUFNQyxLQUFWLENBQ0pELGNBQU1DLEtBQU4sQ0FBWUMsbUJBRFIsRUFFSixzREFGSSxDQUFOO0FBSUQ7O0FBQ0QsV0FBT0wsR0FBRyxDQUFDTSxNQUFKLENBQVdDLFFBQVgsQ0FDSkMsZUFESSxDQUNZUixHQUFHLENBQUNTLE1BQUosQ0FBV0MsU0FEdkIsRUFFSkMsSUFGSSxDQUVDLE1BQU07QUFDVixVQUFJQyxZQUFZLEdBQUdaLEdBQUcsQ0FBQ00sTUFBSixDQUFXTyxlQUE5Qjs7QUFDQSxVQUFJYixHQUFHLENBQUNTLE1BQUosQ0FBV0MsU0FBWCxJQUF3QixVQUE1QixFQUF3QztBQUN0Q0UsUUFBQUEsWUFBWSxDQUFDRSxJQUFiLENBQWtCQyxLQUFsQjtBQUNELE9BRkQsTUFFTyxJQUFJZixHQUFHLENBQUNTLE1BQUosQ0FBV0MsU0FBWCxJQUF3QixPQUE1QixFQUFxQztBQUMxQ0UsUUFBQUEsWUFBWSxDQUFDSSxJQUFiLENBQWtCRCxLQUFsQjtBQUNEOztBQUNELGFBQU87QUFBRUUsUUFBQUEsUUFBUSxFQUFFO0FBQVosT0FBUDtBQUNELEtBVkksRUFXSkMsS0FYSSxDQVdFQyxLQUFLLElBQUk7QUFDZCxVQUFJLENBQUNBLEtBQUQsSUFBV0EsS0FBSyxJQUFJQSxLQUFLLENBQUNDLElBQU4sS0FBZWpCLGNBQU1DLEtBQU4sQ0FBWWlCLGdCQUFuRCxFQUFzRTtBQUNwRSxlQUFPO0FBQUVKLFVBQUFBLFFBQVEsRUFBRTtBQUFaLFNBQVA7QUFDRDs7QUFDRCxZQUFNRSxLQUFOO0FBQ0QsS0FoQkksQ0FBUDtBQWlCRDs7QUFFREcsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxDQUFXLFFBQVgsRUFBcUIsbUJBQXJCLEVBQTBDQyxVQUFVLENBQUNDLDZCQUFyRCxFQUFvRnpCLEdBQUcsSUFBSTtBQUN6RixhQUFPLEtBQUtELFdBQUwsQ0FBaUJDLEdBQWpCLENBQVA7QUFDRCxLQUZEO0FBR0Q7O0FBL0I0Qzs7O2VBa0NoQ0gsVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0ICogYXMgbWlkZGxld2FyZSBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5cbmV4cG9ydCBjbGFzcyBQdXJnZVJvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBoYW5kbGVQdXJnZShyZXEpIHtcbiAgICBpZiAocmVxLmF1dGguaXNSZWFkT25seSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICBcInJlYWQtb25seSBtYXN0ZXJLZXkgaXNuJ3QgYWxsb3dlZCB0byBwdXJnZSBhIHNjaGVtYS5cIlxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2VcbiAgICAgIC5wdXJnZUNvbGxlY3Rpb24ocmVxLnBhcmFtcy5jbGFzc05hbWUpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHZhciBjYWNoZUFkYXB0ZXIgPSByZXEuY29uZmlnLmNhY2hlQ29udHJvbGxlcjtcbiAgICAgICAgaWYgKHJlcS5wYXJhbXMuY2xhc3NOYW1lID09ICdfU2Vzc2lvbicpIHtcbiAgICAgICAgICBjYWNoZUFkYXB0ZXIudXNlci5jbGVhcigpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlcS5wYXJhbXMuY2xhc3NOYW1lID09ICdfUm9sZScpIHtcbiAgICAgICAgICBjYWNoZUFkYXB0ZXIucm9sZS5jbGVhcigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7fSB9O1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmICghZXJyb3IgfHwgKGVycm9yICYmIGVycm9yLmNvZGUgPT09IFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQpKSB7XG4gICAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHt9IH07XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcbiAgfVxuXG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ0RFTEVURScsICcvcHVyZ2UvOmNsYXNzTmFtZScsIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVQdXJnZShyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1cmdlUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/PushRouter.js b/lib/Routers/PushRouter.js new file mode 100644 index 0000000000..93eda269af --- /dev/null +++ b/lib/Routers/PushRouter.js @@ -0,0 +1,92 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.PushRouter = void 0; + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +var _node = require("parse/node"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class PushRouter extends _PromiseRouter.default { + mountRoutes() { + this.route('POST', '/push', middleware.promiseEnforceMasterKeyAccess, PushRouter.handlePOST); + } + + static handlePOST(req) { + if (req.auth.isReadOnly) { + throw new _node.Parse.Error(_node.Parse.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to send push notifications."); + } + + const pushController = req.config.pushController; + + if (!pushController) { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Push controller is not set'); + } + + const where = PushRouter.getQueryCondition(req); + let resolve; + const promise = new Promise(_resolve => { + resolve = _resolve; + }); + let pushStatusId; + pushController.sendPush(req.body, where, req.config, req.auth, objectId => { + pushStatusId = objectId; + resolve({ + headers: { + 'X-Parse-Push-Status-Id': pushStatusId + }, + response: { + result: true + } + }); + }).catch(err => { + req.config.loggerController.error(`_PushStatus ${pushStatusId}: error while sending push`, err); + }); + return promise; + } + /** + * Get query condition from the request body. + * @param {Object} req A request object + * @returns {Object} The query condition, the where field in a query api call + */ + + + static getQueryCondition(req) { + const body = req.body || {}; + const hasWhere = typeof body.where !== 'undefined'; + const hasChannels = typeof body.channels !== 'undefined'; + let where; + + if (hasWhere && hasChannels) { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Channels and query can not be set at the same time.'); + } else if (hasWhere) { + where = body.where; + } else if (hasChannels) { + where = { + channels: { + $in: body.channels + } + }; + } else { + throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Sending a push requires either "channels" or a "where" query.'); + } + + return where; + } + +} + +exports.PushRouter = PushRouter; +var _default = PushRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1B1c2hSb3V0ZXIuanMiXSwibmFtZXMiOlsiUHVzaFJvdXRlciIsIlByb21pc2VSb3V0ZXIiLCJtb3VudFJvdXRlcyIsInJvdXRlIiwibWlkZGxld2FyZSIsInByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzIiwiaGFuZGxlUE9TVCIsInJlcSIsImF1dGgiLCJpc1JlYWRPbmx5IiwiUGFyc2UiLCJFcnJvciIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJwdXNoQ29udHJvbGxlciIsImNvbmZpZyIsIlBVU0hfTUlTQ09ORklHVVJFRCIsIndoZXJlIiwiZ2V0UXVlcnlDb25kaXRpb24iLCJyZXNvbHZlIiwicHJvbWlzZSIsIlByb21pc2UiLCJfcmVzb2x2ZSIsInB1c2hTdGF0dXNJZCIsInNlbmRQdXNoIiwiYm9keSIsIm9iamVjdElkIiwiaGVhZGVycyIsInJlc3BvbnNlIiwicmVzdWx0IiwiY2F0Y2giLCJlcnIiLCJsb2dnZXJDb250cm9sbGVyIiwiZXJyb3IiLCJoYXNXaGVyZSIsImhhc0NoYW5uZWxzIiwiY2hhbm5lbHMiLCIkaW4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFTyxNQUFNQSxVQUFOLFNBQXlCQyxzQkFBekIsQ0FBdUM7QUFDNUNDLEVBQUFBLFdBQVcsR0FBRztBQUNaLFNBQUtDLEtBQUwsQ0FBVyxNQUFYLEVBQW1CLE9BQW5CLEVBQTRCQyxVQUFVLENBQUNDLDZCQUF2QyxFQUFzRUwsVUFBVSxDQUFDTSxVQUFqRjtBQUNEOztBQUVELFNBQU9BLFVBQVAsQ0FBa0JDLEdBQWxCLEVBQXVCO0FBQ3JCLFFBQUlBLEdBQUcsQ0FBQ0MsSUFBSixDQUFTQyxVQUFiLEVBQXlCO0FBQ3ZCLFlBQU0sSUFBSUMsWUFBTUMsS0FBVixDQUNKRCxZQUFNQyxLQUFOLENBQVlDLG1CQURSLEVBRUosK0RBRkksQ0FBTjtBQUlEOztBQUNELFVBQU1DLGNBQWMsR0FBR04sR0FBRyxDQUFDTyxNQUFKLENBQVdELGNBQWxDOztBQUNBLFFBQUksQ0FBQ0EsY0FBTCxFQUFxQjtBQUNuQixZQUFNLElBQUlILFlBQU1DLEtBQVYsQ0FBZ0JELFlBQU1DLEtBQU4sQ0FBWUksa0JBQTVCLEVBQWdELDRCQUFoRCxDQUFOO0FBQ0Q7O0FBRUQsVUFBTUMsS0FBSyxHQUFHaEIsVUFBVSxDQUFDaUIsaUJBQVgsQ0FBNkJWLEdBQTdCLENBQWQ7QUFDQSxRQUFJVyxPQUFKO0FBQ0EsVUFBTUMsT0FBTyxHQUFHLElBQUlDLE9BQUosQ0FBWUMsUUFBUSxJQUFJO0FBQ3RDSCxNQUFBQSxPQUFPLEdBQUdHLFFBQVY7QUFDRCxLQUZlLENBQWhCO0FBR0EsUUFBSUMsWUFBSjtBQUNBVCxJQUFBQSxjQUFjLENBQ1hVLFFBREgsQ0FDWWhCLEdBQUcsQ0FBQ2lCLElBRGhCLEVBQ3NCUixLQUR0QixFQUM2QlQsR0FBRyxDQUFDTyxNQURqQyxFQUN5Q1AsR0FBRyxDQUFDQyxJQUQ3QyxFQUNtRGlCLFFBQVEsSUFBSTtBQUMzREgsTUFBQUEsWUFBWSxHQUFHRyxRQUFmO0FBQ0FQLE1BQUFBLE9BQU8sQ0FBQztBQUNOUSxRQUFBQSxPQUFPLEVBQUU7QUFDUCxvQ0FBMEJKO0FBRG5CLFNBREg7QUFJTkssUUFBQUEsUUFBUSxFQUFFO0FBQ1JDLFVBQUFBLE1BQU0sRUFBRTtBQURBO0FBSkosT0FBRCxDQUFQO0FBUUQsS0FYSCxFQVlHQyxLQVpILENBWVNDLEdBQUcsSUFBSTtBQUNadkIsTUFBQUEsR0FBRyxDQUFDTyxNQUFKLENBQVdpQixnQkFBWCxDQUE0QkMsS0FBNUIsQ0FDRyxlQUFjVixZQUFhLDRCQUQ5QixFQUVFUSxHQUZGO0FBSUQsS0FqQkg7QUFrQkEsV0FBT1gsT0FBUDtBQUNEO0FBRUQ7QUFDRjtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0UsU0FBT0YsaUJBQVAsQ0FBeUJWLEdBQXpCLEVBQThCO0FBQzVCLFVBQU1pQixJQUFJLEdBQUdqQixHQUFHLENBQUNpQixJQUFKLElBQVksRUFBekI7QUFDQSxVQUFNUyxRQUFRLEdBQUcsT0FBT1QsSUFBSSxDQUFDUixLQUFaLEtBQXNCLFdBQXZDO0FBQ0EsVUFBTWtCLFdBQVcsR0FBRyxPQUFPVixJQUFJLENBQUNXLFFBQVosS0FBeUIsV0FBN0M7QUFFQSxRQUFJbkIsS0FBSjs7QUFDQSxRQUFJaUIsUUFBUSxJQUFJQyxXQUFoQixFQUE2QjtBQUMzQixZQUFNLElBQUl4QixZQUFNQyxLQUFWLENBQ0pELFlBQU1DLEtBQU4sQ0FBWUksa0JBRFIsRUFFSixxREFGSSxDQUFOO0FBSUQsS0FMRCxNQUtPLElBQUlrQixRQUFKLEVBQWM7QUFDbkJqQixNQUFBQSxLQUFLLEdBQUdRLElBQUksQ0FBQ1IsS0FBYjtBQUNELEtBRk0sTUFFQSxJQUFJa0IsV0FBSixFQUFpQjtBQUN0QmxCLE1BQUFBLEtBQUssR0FBRztBQUNObUIsUUFBQUEsUUFBUSxFQUFFO0FBQ1JDLFVBQUFBLEdBQUcsRUFBRVosSUFBSSxDQUFDVztBQURGO0FBREosT0FBUjtBQUtELEtBTk0sTUFNQTtBQUNMLFlBQU0sSUFBSXpCLFlBQU1DLEtBQVYsQ0FDSkQsWUFBTUMsS0FBTixDQUFZSSxrQkFEUixFQUVKLCtEQUZJLENBQU47QUFJRDs7QUFDRCxXQUFPQyxLQUFQO0FBQ0Q7O0FBM0UyQzs7O2VBOEUvQmhCLFUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuLi9Qcm9taXNlUm91dGVyJztcbmltcG9ydCAqIGFzIG1pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuaW1wb3J0IHsgUGFyc2UgfSBmcm9tICdwYXJzZS9ub2RlJztcblxuZXhwb3J0IGNsYXNzIFB1c2hSb3V0ZXIgZXh0ZW5kcyBQcm9taXNlUm91dGVyIHtcbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnUE9TVCcsICcvcHVzaCcsIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIFB1c2hSb3V0ZXIuaGFuZGxlUE9TVCk7XG4gIH1cblxuICBzdGF0aWMgaGFuZGxlUE9TVChyZXEpIHtcbiAgICBpZiAocmVxLmF1dGguaXNSZWFkT25seSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICBcInJlYWQtb25seSBtYXN0ZXJLZXkgaXNuJ3QgYWxsb3dlZCB0byBzZW5kIHB1c2ggbm90aWZpY2F0aW9ucy5cIlxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgcHVzaENvbnRyb2xsZXIgPSByZXEuY29uZmlnLnB1c2hDb250cm9sbGVyO1xuICAgIGlmICghcHVzaENvbnRyb2xsZXIpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5QVVNIX01JU0NPTkZJR1VSRUQsICdQdXNoIGNvbnRyb2xsZXIgaXMgbm90IHNldCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHdoZXJlID0gUHVzaFJvdXRlci5nZXRRdWVyeUNvbmRpdGlvbihyZXEpO1xuICAgIGxldCByZXNvbHZlO1xuICAgIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZShfcmVzb2x2ZSA9PiB7XG4gICAgICByZXNvbHZlID0gX3Jlc29sdmU7XG4gICAgfSk7XG4gICAgbGV0IHB1c2hTdGF0dXNJZDtcbiAgICBwdXNoQ29udHJvbGxlclxuICAgICAgLnNlbmRQdXNoKHJlcS5ib2R5LCB3aGVyZSwgcmVxLmNvbmZpZywgcmVxLmF1dGgsIG9iamVjdElkID0+IHtcbiAgICAgICAgcHVzaFN0YXR1c0lkID0gb2JqZWN0SWQ7XG4gICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICdYLVBhcnNlLVB1c2gtU3RhdHVzLUlkJzogcHVzaFN0YXR1c0lkLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICAgIHJlc3VsdDogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgcmVxLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyLmVycm9yKFxuICAgICAgICAgIGBfUHVzaFN0YXR1cyAke3B1c2hTdGF0dXNJZH06IGVycm9yIHdoaWxlIHNlbmRpbmcgcHVzaGAsXG4gICAgICAgICAgZXJyXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgcXVlcnkgY29uZGl0aW9uIGZyb20gdGhlIHJlcXVlc3QgYm9keS5cbiAgICogQHBhcmFtIHtPYmplY3R9IHJlcSBBIHJlcXVlc3Qgb2JqZWN0XG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFRoZSBxdWVyeSBjb25kaXRpb24sIHRoZSB3aGVyZSBmaWVsZCBpbiBhIHF1ZXJ5IGFwaSBjYWxsXG4gICAqL1xuICBzdGF0aWMgZ2V0UXVlcnlDb25kaXRpb24ocmVxKSB7XG4gICAgY29uc3QgYm9keSA9IHJlcS5ib2R5IHx8IHt9O1xuICAgIGNvbnN0IGhhc1doZXJlID0gdHlwZW9mIGJvZHkud2hlcmUgIT09ICd1bmRlZmluZWQnO1xuICAgIGNvbnN0IGhhc0NoYW5uZWxzID0gdHlwZW9mIGJvZHkuY2hhbm5lbHMgIT09ICd1bmRlZmluZWQnO1xuXG4gICAgbGV0IHdoZXJlO1xuICAgIGlmIChoYXNXaGVyZSAmJiBoYXNDaGFubmVscykge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5QVVNIX01JU0NPTkZJR1VSRUQsXG4gICAgICAgICdDaGFubmVscyBhbmQgcXVlcnkgY2FuIG5vdCBiZSBzZXQgYXQgdGhlIHNhbWUgdGltZS4nXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAoaGFzV2hlcmUpIHtcbiAgICAgIHdoZXJlID0gYm9keS53aGVyZTtcbiAgICB9IGVsc2UgaWYgKGhhc0NoYW5uZWxzKSB7XG4gICAgICB3aGVyZSA9IHtcbiAgICAgICAgY2hhbm5lbHM6IHtcbiAgICAgICAgICAkaW46IGJvZHkuY2hhbm5lbHMsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgJ1NlbmRpbmcgYSBwdXNoIHJlcXVpcmVzIGVpdGhlciBcImNoYW5uZWxzXCIgb3IgYSBcIndoZXJlXCIgcXVlcnkuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHdoZXJlO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1c2hSb3V0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/RolesRouter.js b/lib/Routers/RolesRouter.js new file mode 100644 index 0000000000..10fd6e7942 --- /dev/null +++ b/lib/Routers/RolesRouter.js @@ -0,0 +1,40 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.RolesRouter = void 0; + +var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class RolesRouter extends _ClassesRouter.default { + className() { + return '_Role'; + } + + mountRoutes() { + this.route('GET', '/roles', req => { + return this.handleFind(req); + }); + this.route('GET', '/roles/:objectId', req => { + return this.handleGet(req); + }); + this.route('POST', '/roles', req => { + return this.handleCreate(req); + }); + this.route('PUT', '/roles/:objectId', req => { + return this.handleUpdate(req); + }); + this.route('DELETE', '/roles/:objectId', req => { + return this.handleDelete(req); + }); + } + +} + +exports.RolesRouter = RolesRouter; +var _default = RolesRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1JvbGVzUm91dGVyLmpzIl0sIm5hbWVzIjpbIlJvbGVzUm91dGVyIiwiQ2xhc3Nlc1JvdXRlciIsImNsYXNzTmFtZSIsIm1vdW50Um91dGVzIiwicm91dGUiLCJyZXEiLCJoYW5kbGVGaW5kIiwiaGFuZGxlR2V0IiwiaGFuZGxlQ3JlYXRlIiwiaGFuZGxlVXBkYXRlIiwiaGFuZGxlRGVsZXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7Ozs7QUFFTyxNQUFNQSxXQUFOLFNBQTBCQyxzQkFBMUIsQ0FBd0M7QUFDN0NDLEVBQUFBLFNBQVMsR0FBRztBQUNWLFdBQU8sT0FBUDtBQUNEOztBQUVEQyxFQUFBQSxXQUFXLEdBQUc7QUFDWixTQUFLQyxLQUFMLENBQVcsS0FBWCxFQUFrQixRQUFsQixFQUE0QkMsR0FBRyxJQUFJO0FBQ2pDLGFBQU8sS0FBS0MsVUFBTCxDQUFnQkQsR0FBaEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLRCxLQUFMLENBQVcsS0FBWCxFQUFrQixrQkFBbEIsRUFBc0NDLEdBQUcsSUFBSTtBQUMzQyxhQUFPLEtBQUtFLFNBQUwsQ0FBZUYsR0FBZixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUtELEtBQUwsQ0FBVyxNQUFYLEVBQW1CLFFBQW5CLEVBQTZCQyxHQUFHLElBQUk7QUFDbEMsYUFBTyxLQUFLRyxZQUFMLENBQWtCSCxHQUFsQixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUtELEtBQUwsQ0FBVyxLQUFYLEVBQWtCLGtCQUFsQixFQUFzQ0MsR0FBRyxJQUFJO0FBQzNDLGFBQU8sS0FBS0ksWUFBTCxDQUFrQkosR0FBbEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLRCxLQUFMLENBQVcsUUFBWCxFQUFxQixrQkFBckIsRUFBeUNDLEdBQUcsSUFBSTtBQUM5QyxhQUFPLEtBQUtLLFlBQUwsQ0FBa0JMLEdBQWxCLENBQVA7QUFDRCxLQUZEO0FBR0Q7O0FBckI0Qzs7O2VBd0JoQ0wsVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBDbGFzc2VzUm91dGVyIGZyb20gJy4vQ2xhc3Nlc1JvdXRlcic7XG5cbmV4cG9ydCBjbGFzcyBSb2xlc1JvdXRlciBleHRlbmRzIENsYXNzZXNSb3V0ZXIge1xuICBjbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICdfUm9sZSc7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3JvbGVzJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZpbmQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3JvbGVzLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9yb2xlcycsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVDcmVhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQVVQnLCAnL3JvbGVzLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVVcGRhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdERUxFVEUnLCAnL3JvbGVzLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVEZWxldGUocmVxKTtcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBSb2xlc1JvdXRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/SchemasRouter.js b/lib/Routers/SchemasRouter.js new file mode 100644 index 0000000000..04681476df --- /dev/null +++ b/lib/Routers/SchemasRouter.js @@ -0,0 +1,120 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.SchemasRouter = void 0; + +var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); + +var middleware = _interopRequireWildcard(require("../middlewares")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// schemas.js +var Parse = require('parse/node').Parse, + SchemaController = require('../Controllers/SchemaController'); + +function classNameMismatchResponse(bodyClass, pathClass) { + throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class name mismatch between ${bodyClass} and ${pathClass}.`); +} + +function getAllSchemas(req) { + return req.config.database.loadSchema({ + clearCache: true + }).then(schemaController => schemaController.getAllClasses(true)).then(schemas => ({ + response: { + results: schemas + } + })); +} + +function getOneSchema(req) { + const className = req.params.className; + return req.config.database.loadSchema({ + clearCache: true + }).then(schemaController => schemaController.getOneSchema(className, true)).then(schema => ({ + response: schema + })).catch(error => { + if (error === undefined) { + throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} does not exist.`); + } else { + throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Database adapter error.'); + } + }); +} + +function createSchema(req) { + if (req.auth.isReadOnly) { + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to create a schema."); + } + + if (req.params.className && req.body.className) { + if (req.params.className != req.body.className) { + return classNameMismatchResponse(req.body.className, req.params.className); + } + } + + const className = req.params.className || req.body.className; + + if (!className) { + throw new Parse.Error(135, `POST ${req.path} needs a class name.`); + } + + return req.config.database.loadSchema({ + clearCache: true + }).then(schema => schema.addClassIfNotExists(className, req.body.fields, req.body.classLevelPermissions, req.body.indexes)).then(schema => ({ + response: schema + })); +} + +function modifySchema(req) { + if (req.auth.isReadOnly) { + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to update a schema."); + } + + if (req.body.className && req.body.className != req.params.className) { + return classNameMismatchResponse(req.body.className, req.params.className); + } + + const submittedFields = req.body.fields || {}; + const className = req.params.className; + return req.config.database.loadSchema({ + clearCache: true + }).then(schema => schema.updateClass(className, submittedFields, req.body.classLevelPermissions, req.body.indexes, req.config.database)).then(result => ({ + response: result + })); +} + +const deleteSchema = req => { + if (req.auth.isReadOnly) { + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to delete a schema."); + } + + if (!SchemaController.classNameIsValid(req.params.className)) { + throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, SchemaController.invalidClassNameMessage(req.params.className)); + } + + return req.config.database.deleteSchema(req.params.className).then(() => ({ + response: {} + })); +}; + +class SchemasRouter extends _PromiseRouter.default { + mountRoutes() { + this.route('GET', '/schemas', middleware.promiseEnforceMasterKeyAccess, getAllSchemas); + this.route('GET', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, getOneSchema); + this.route('POST', '/schemas', middleware.promiseEnforceMasterKeyAccess, createSchema); + this.route('POST', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, createSchema); + this.route('PUT', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, modifySchema); + this.route('DELETE', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, deleteSchema); + } + +} + +exports.SchemasRouter = SchemasRouter; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1NjaGVtYXNSb3V0ZXIuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwiU2NoZW1hQ29udHJvbGxlciIsImNsYXNzTmFtZU1pc21hdGNoUmVzcG9uc2UiLCJib2R5Q2xhc3MiLCJwYXRoQ2xhc3MiLCJFcnJvciIsIklOVkFMSURfQ0xBU1NfTkFNRSIsImdldEFsbFNjaGVtYXMiLCJyZXEiLCJjb25maWciLCJkYXRhYmFzZSIsImxvYWRTY2hlbWEiLCJjbGVhckNhY2hlIiwidGhlbiIsInNjaGVtYUNvbnRyb2xsZXIiLCJnZXRBbGxDbGFzc2VzIiwic2NoZW1hcyIsInJlc3BvbnNlIiwicmVzdWx0cyIsImdldE9uZVNjaGVtYSIsImNsYXNzTmFtZSIsInBhcmFtcyIsInNjaGVtYSIsImNhdGNoIiwiZXJyb3IiLCJ1bmRlZmluZWQiLCJJTlRFUk5BTF9TRVJWRVJfRVJST1IiLCJjcmVhdGVTY2hlbWEiLCJhdXRoIiwiaXNSZWFkT25seSIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJib2R5IiwicGF0aCIsImFkZENsYXNzSWZOb3RFeGlzdHMiLCJmaWVsZHMiLCJjbGFzc0xldmVsUGVybWlzc2lvbnMiLCJpbmRleGVzIiwibW9kaWZ5U2NoZW1hIiwic3VibWl0dGVkRmllbGRzIiwidXBkYXRlQ2xhc3MiLCJyZXN1bHQiLCJkZWxldGVTY2hlbWEiLCJjbGFzc05hbWVJc1ZhbGlkIiwiaW52YWxpZENsYXNzTmFtZU1lc3NhZ2UiLCJTY2hlbWFzUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsIm1vdW50Um91dGVzIiwicm91dGUiLCJtaWRkbGV3YXJlIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFLQTs7QUFDQTs7Ozs7Ozs7QUFOQTtBQUVBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBbEM7QUFBQSxJQUNFRSxnQkFBZ0IsR0FBR0Qs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QXdFMUMsYUFBeEU7QUFDQSxTQUFLd0MsS0FBTCxDQUNFLEtBREYsRUFFRSxxQkFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUU5QixZQUpGO0FBTUEsU0FBSzRCLEtBQUwsQ0FBVyxNQUFYLEVBQW1CLFVBQW5CLEVBQStCQyxVQUFVLENBQUNDLDZCQUExQyxFQUF5RXRCLFlBQXpFO0FBQ0EsU0FBS29CLEtBQUwsQ0FDRSxNQURGLEVBRUUscUJBRkYsRUFHRUMsVUFBVSxDQUFDQyw2QkFIYixFQUlFdEIsWUFKRjtBQU1BLFNBQUtvQixLQUFMLENBQ0UsS0FERixFQUVFLHFCQUZGLEVBR0VDLFVBQVUsQ0FBQ0MsNkJBSGIsRUFJRVosWUFKRjtBQU1BLFNBQUtVLEtBQUwsQ0FDRSxRQURGLEVBRUUscUJBRkYsRUFHRUMsVUFBVSxDQUFDQyw2QkFIYixFQUlFUixZQUpGO0FBTUQ7O0FBNUI4QyIsInNvdXJjZXNDb250ZW50IjpbIi8vIHNjaGVtYXMuanNcblxudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlLFxuICBTY2hlbWFDb250cm9sbGVyID0gcmVxdWlyZSgnLi4vQ29udHJvbGxlcnMvU2NoZW1hQ29udHJvbGxlcicpO1xuXG5pbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuLi9Qcm9taXNlUm91dGVyJztcbmltcG9ydCAqIGFzIG1pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5mdW5jdGlvbiBjbGFzc05hbWVNaXNtYXRjaFJlc3BvbnNlKGJvZHlDbGFzcywgcGF0aENsYXNzKSB7XG4gIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICBQYXJzZS5FcnJvci5JTlZBTElEX0NMQVNTX05BTUUsXG4gICAgYENsYXNzIG5hbWUgbWlzbWF0Y2ggYmV0d2VlbiAke2JvZHlDbGFzc30gYW5kICR7cGF0aENsYXNzfS5gXG4gICk7XG59XG5cbmZ1bmN0aW9uIGdldEFsbFNjaGVtYXMocmVxKSB7XG4gIHJldHVybiByZXEuY29uZmlnLmRhdGFiYXNlXG4gICAgLmxvYWRTY2hlbWEoeyBjbGVhckNhY2hlOiB0cnVlIH0pXG4gICAgLnRoZW4oc2NoZW1hQ29udHJvbGxlciA9PiBzY2hlbWFDb250cm9sbGVyLmdldEFsbENsYXNzZXModHJ1ZSkpXG4gICAgLnRoZW4oc2NoZW1hcyA9PiAoeyByZXNwb25zZTogeyByZXN1bHRzOiBzY2hlbWFzIH0gfSkpO1xufVxuXG5mdW5jdGlvbiBnZXRPbmVTY2hlbWEocmVxKSB7XG4gIGNvbnN0IGNsYXNzTmFtZSA9IHJlcS5wYXJhbXMuY2xhc3NOYW1lO1xuICByZXR1cm4gcmVxLmNvbmZpZy5kYXRhYmFzZVxuICAgIC5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KVxuICAgIC50aGVuKHNjaGVtYUNvbnRyb2xsZXIgPT4gc2NoZW1hQ29udHJvbGxlci5nZXRPbmVTY2hlbWEoY2xhc3NOYW1lLCB0cnVlKSlcbiAgICAudGhlbihzY2hlbWEgPT4gKHsgcmVzcG9uc2U6IHNjaGVtYSB9KSlcbiAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgaWYgKGVycm9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSwgYENsYXNzICR7Y2xhc3NOYW1lfSBkb2VzIG5vdCBleGlzdC5gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsICdEYXRhYmFzZSBhZGFwdGVyIGVycm9yLicpO1xuICAgICAgfVxuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVTY2hlbWEocmVxKSB7XG4gIGlmIChyZXEuYXV0aC5pc1JlYWRPbmx5KSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgIFwicmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIGNyZWF0ZSBhIHNjaGVtYS5cIlxuICAgICk7XG4gIH1cbiAgaWYgKHJlcS5wYXJhbXMuY2xhc3NOYW1lICYmIHJlcS5ib2R5LmNsYXNzTmFtZSkge1xuICAgIGlmIChyZXEucGFyYW1zLmNsYXNzTmFtZSAhPSByZXEuYm9keS5jbGFzc05hbWUpIHtcbiAgICAgIHJldHVybiBjbGFzc05hbWVNaXNtYXRjaFJlc3BvbnNlKHJlcS5ib2R5LmNsYXNzTmFtZSwgcmVxLnBhcmFtcy5jbGFzc05hbWUpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGNsYXNzTmFtZSA9IHJlcS5wYXJhbXMuY2xhc3NOYW1lIHx8IHJlcS5ib2R5LmNsYXNzTmFtZTtcbiAgaWYgKCFjbGFzc05hbWUpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTM1LCBgUE9TVCAke3JlcS5wYXRofSBuZWVkcyBhIGNsYXNzIG5hbWUuYCk7XG4gIH1cblxuICByZXR1cm4gcmVxLmNvbmZpZy5kYXRhYmFzZVxuICAgIC5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KVxuICAgIC50aGVuKHNjaGVtYSA9PlxuICAgICAgc2NoZW1hLmFkZENsYXNzSWZOb3RFeGlzdHMoXG4gICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgcmVxLmJvZHkuZmllbGRzLFxuICAgICAgICByZXEuYm9keS5jbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gICAgICAgIHJlcS5ib2R5LmluZGV4ZXNcbiAgICAgIClcbiAgICApXG4gICAgLnRoZW4oc2NoZW1hID0+ICh7IHJlc3BvbnNlOiBzY2hlbWEgfSkpO1xufVxuXG5mdW5jdGlvbiBtb2RpZnlTY2hlbWEocmVxKSB7XG4gIGlmIChyZXEuYXV0aC5pc1JlYWRPbmx5KSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgIFwicmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIHVwZGF0ZSBhIHNjaGVtYS5cIlxuICAgICk7XG4gIH1cbiAgaWYgKHJlcS5ib2R5LmNsYXNzTmFtZSAmJiByZXEuYm9keS5jbGFzc05hbWUgIT0gcmVxLnBhcmFtcy5jbGFzc05hbWUpIHtcbiAgICByZXR1cm4gY2xhc3NOYW1lTWlzbWF0Y2hSZXNwb25zZShyZXEuYm9keS5jbGFzc05hbWUsIHJlcS5wYXJhbXMuY2xhc3NOYW1lKTtcbiAgfVxuXG4gIGNvbnN0IHN1Ym1pdHRlZEZpZWxkcyA9IHJlcS5ib2R5LmZpZWxkcyB8fCB7fTtcbiAgY29uc3QgY2xhc3NOYW1lID0gcmVxLnBhcmFtcy5jbGFzc05hbWU7XG5cbiAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2VcbiAgICAubG9hZFNjaGVtYSh7IGNsZWFyQ2FjaGU6IHRydWUgfSlcbiAgICAudGhlbihzY2hlbWEgPT5cbiAgICAgIHNjaGVtYS51cGRhdGVDbGFzcyhcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICBzdWJtaXR0ZWRGaWVsZHMsXG4gICAgICAgIHJlcS5ib2R5LmNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgICAgcmVxLmJvZHkuaW5kZXhlcyxcbiAgICAgICAgcmVxLmNvbmZpZy5kYXRhYmFzZVxuICAgICAgKVxuICAgIClcbiAgICAudGhlbihyZXN1bHQgPT4gKHsgcmVzcG9uc2U6IHJlc3VsdCB9KSk7XG59XG5cbmNvbnN0IGRlbGV0ZVNjaGVtYSA9IHJlcSA9PiB7XG4gIGlmIChyZXEuYXV0aC5pc1JlYWRPbmx5KSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgIFwicmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIGRlbGV0ZSBhIHNjaGVtYS5cIlxuICAgICk7XG4gIH1cbiAgaWYgKCFTY2hlbWFDb250cm9sbGVyLmNsYXNzTmFtZUlzVmFsaWQocmVxLnBhcmFtcy5jbGFzc05hbWUpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLFxuICAgICAgU2NoZW1hQ29udHJvbGxlci5pbnZhbGlkQ2xhc3NOYW1lTWVzc2FnZShyZXEucGFyYW1zLmNsYXNzTmFtZSlcbiAgICApO1xuICB9XG4gIHJldHVybiByZXEuY29uZmlnLmRhdGFiYXNlLmRlbGV0ZVNjaGVtYShyZXEucGFyYW1zLmNsYXNzTmFtZSkudGhlbigoKSA9PiAoeyByZXNwb25zZToge30gfSkpO1xufTtcblxuZXhwb3J0IGNsYXNzIFNjaGVtYXNSb3V0ZXIgZXh0ZW5kcyBQcm9taXNlUm91dGVyIHtcbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9zY2hlbWFzJywgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcywgZ2V0QWxsU2NoZW1hcyk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdHRVQnLFxuICAgICAgJy9zY2hlbWFzLzpjbGFzc05hbWUnLFxuICAgICAgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyxcbiAgICAgIGdldE9uZVNjaGVtYVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZSgnUE9TVCcsICcvc2NoZW1hcycsIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIGNyZWF0ZVNjaGVtYSk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdQT1NUJyxcbiAgICAgICcvc2NoZW1hcy86Y2xhc3NOYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICBjcmVhdGVTY2hlbWFcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnUFVUJyxcbiAgICAgICcvc2NoZW1hcy86Y2xhc3NOYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICBtb2RpZnlTY2hlbWFcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnREVMRVRFJyxcbiAgICAgICcvc2NoZW1hcy86Y2xhc3NOYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICBkZWxldGVTY2hlbWFcbiAgICApO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/SessionsRouter.js b/lib/Routers/SessionsRouter.js new file mode 100644 index 0000000000..de4bdcd2e0 --- /dev/null +++ b/lib/Routers/SessionsRouter.js @@ -0,0 +1,107 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.SessionsRouter = void 0; + +var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); + +var _node = _interopRequireDefault(require("parse/node")); + +var _rest = _interopRequireDefault(require("../rest")); + +var _Auth = _interopRequireDefault(require("../Auth")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +class SessionsRouter extends _ClassesRouter.default { + className() { + return '_Session'; + } + + handleMe(req) { + // TODO: Verify correct behavior + if (!req.info || !req.info.sessionToken) { + throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Session token required.'); + } + + return _rest.default.find(req.config, _Auth.default.master(req.config), '_Session', { + sessionToken: req.info.sessionToken + }, undefined, req.info.clientSDK, req.info.context).then(response => { + if (!response.results || response.results.length == 0) { + throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Session token not found.'); + } + + return { + response: response.results[0] + }; + }); + } + + handleUpdateToRevocableSession(req) { + const config = req.config; + const user = req.auth.user; // Issue #2720 + // Calling without a session token would result in a not found user + + if (!user) { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'invalid session'); + } + + const { + sessionData, + createSession + } = _Auth.default.createSession(config, { + userId: user.id, + createdWith: { + action: 'upgrade' + }, + installationId: req.auth.installationId + }); + + return createSession().then(() => { + // delete the session token, use the db to skip beforeSave + return config.database.update('_User', { + objectId: user.id + }, { + sessionToken: { + __op: 'Delete' + } + }); + }).then(() => { + return Promise.resolve({ + response: sessionData + }); + }); + } + + mountRoutes() { + this.route('GET', '/sessions/me', req => { + return this.handleMe(req); + }); + this.route('GET', '/sessions', req => { + return this.handleFind(req); + }); + this.route('GET', '/sessions/:objectId', req => { + return this.handleGet(req); + }); + this.route('POST', '/sessions', req => { + return this.handleCreate(req); + }); + this.route('PUT', '/sessions/:objectId', req => { + return this.handleUpdate(req); + }); + this.route('DELETE', '/sessions/:objectId', req => { + return this.handleDelete(req); + }); + this.route('POST', '/upgradeToRevocableSession', req => { + return this.handleUpdateToRevocableSession(req); + }); + } + +} + +exports.SessionsRouter = SessionsRouter; +var _default = SessionsRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1Nlc3Npb25zUm91dGVyLmpzIl0sIm5hbWVzIjpbIlNlc3Npb25zUm91dGVyIiwiQ2xhc3Nlc1JvdXRlciIsImNsYXNzTmFtZSIsImhhbmRsZU1lIiwicmVxIiwiaW5mbyIsInNlc3Npb25Ub2tlbiIsIlBhcnNlIiwiRXJyb3IiLCJJTlZBTElEX1NFU1NJT05fVE9LRU4iLCJyZXN0IiwiZmluZCIsImNvbmZpZyIsIkF1dGgiLCJtYXN0ZXIiLCJ1bmRlZmluZWQiLCJjbGllbnRTREsiLCJjb250ZXh0IiwidGhlbiIsInJlc3BvbnNlIiwicmVzdWx0cyIsImxlbmd0aCIsImhhbmRsZVVwZGF0ZVRvUmV2b2NhYmxlU2Vzc2lvbiIsInVzZXIiLCJhdXRoIiwiT0JKRUNUX05PVF9GT1VORCIsInNlc3Npb25EYXRhIiwiY3JlYXRlU2Vzc2lvbiIsInVzZXJJZCIsImlkIiwiY3JlYXRlZFdpdGgiLCJhY3Rpb24iLCJpbnN0YWxsYXRpb25JZCIsImRhdGFiYXNlIiwidXBkYXRlIiwib2JqZWN0SWQiLCJfX29wIiwiUHJvbWlzZSIsInJlc29sdmUiLCJtb3VudFJvdXRlcyIsInJvdXRlIiwiaGFuZGxlRmluZCIsImhhbmRsZUdldCIsImhhbmRsZUNyZWF0ZSIsImhhbmRsZVVwZGF0ZSIsImhhbmRsZURlbGV0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRU8sTUFBTUEsY0FBTixTQUE2QkMsc0JBQTdCLENBQTJDO0FBQ2hEQyxFQUFBQSxTQUFTLEdBQUc7QUFDVixXQUFPLFVBQVA7QUFDRDs7QUFFREMsRUFBQUEsUUFBUSxDQUFDQyxHQUFELEVBQU07QUFDWjtBQUNBLFFBQUksQ0FBQ0EsR0FBRyxDQUFDQyxJQUFMLElBQWEsQ0FBQ0QsR0FBRyxDQUFDQyxJQUFKLENBQVNDLFlBQTNCLEVBQXlDO0FBQ3ZDLFlBQU0sSUFBSUMsY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZQyxx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QUFJO0FBQ3JDLGFBQU8sS0FBS3VDLFlBQUwsQ0FBa0J2QyxHQUFsQixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUtvQyxLQUFMLENBQVcsS0FBWCxFQUFrQixxQkFBbEIsRUFBeUNwQyxHQUFHLElBQUk7QUFDOUMsYUFBTyxLQUFLd0MsWUFBTCxDQUFrQnhDLEdBQWxCLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBS29DLEtBQUwsQ0FBVyxRQUFYLEVBQXFCLHFCQUFyQixFQUE0Q3BDLEdBQUcsSUFBSTtBQUNqRCxhQUFPLEtBQUt5QyxZQUFMLENBQWtCekMsR0FBbEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLb0MsS0FBTCxDQUFXLE1BQVgsRUFBbUIsNEJBQW5CLEVBQWlEcEMsR0FBRyxJQUFJO0FBQ3RELGFBQU8sS0FBS2tCLDhCQUFMLENBQW9DbEIsR0FBcEMsQ0FBUDtBQUNELEtBRkQ7QUFHRDs7QUF0RitDOzs7ZUF5Rm5DSixjIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IENsYXNzZXNSb3V0ZXIgZnJvbSAnLi9DbGFzc2VzUm91dGVyJztcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IEF1dGggZnJvbSAnLi4vQXV0aCc7XG5cbmV4cG9ydCBjbGFzcyBTZXNzaW9uc1JvdXRlciBleHRlbmRzIENsYXNzZXNSb3V0ZXIge1xuICBjbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICdfU2Vzc2lvbic7XG4gIH1cblxuICBoYW5kbGVNZShyZXEpIHtcbiAgICAvLyBUT0RPOiBWZXJpZnkgY29ycmVjdCBiZWhhdmlvclxuICAgIGlmICghcmVxLmluZm8gfHwgIXJlcS5pbmZvLnNlc3Npb25Ub2tlbikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTiwgJ1Nlc3Npb24gdG9rZW4gcmVxdWlyZWQuJyk7XG4gICAgfVxuICAgIHJldHVybiByZXN0XG4gICAgICAuZmluZChcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgQXV0aC5tYXN0ZXIocmVxLmNvbmZpZyksXG4gICAgICAgICdfU2Vzc2lvbicsXG4gICAgICAgIHsgc2Vzc2lvblRva2VuOiByZXEuaW5mby5zZXNzaW9uVG9rZW4gfSxcbiAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICByZXEuaW5mby5jbGllbnRTREssXG4gICAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgaWYgKCFyZXNwb25zZS5yZXN1bHRzIHx8IHJlc3BvbnNlLnJlc3VsdHMubGVuZ3RoID09IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOLCAnU2Vzc2lvbiB0b2tlbiBub3QgZm91bmQuJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICByZXNwb25zZTogcmVzcG9uc2UucmVzdWx0c1swXSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgaGFuZGxlVXBkYXRlVG9SZXZvY2FibGVTZXNzaW9uKHJlcSkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHJlcS5jb25maWc7XG4gICAgY29uc3QgdXNlciA9IHJlcS5hdXRoLnVzZXI7XG4gICAgLy8gSXNzdWUgIzI3MjBcbiAgICAvLyBDYWxsaW5nIHdpdGhvdXQgYSBzZXNzaW9uIHRva2VuIHdvdWxkIHJlc3VsdCBpbiBhIG5vdCBmb3VuZCB1c2VyXG4gICAgaWYgKCF1c2VyKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ2ludmFsaWQgc2Vzc2lvbicpO1xuICAgIH1cbiAgICBjb25zdCB7IHNlc3Npb25EYXRhLCBjcmVhdGVTZXNzaW9uIH0gPSBBdXRoLmNyZWF0ZVNlc3Npb24oY29uZmlnLCB7XG4gICAgICB1c2VySWQ6IHVzZXIuaWQsXG4gICAgICBjcmVhdGVkV2l0aDoge1xuICAgICAgICBhY3Rpb246ICd1cGdyYWRlJyxcbiAgICAgIH0sXG4gICAgICBpbnN0YWxsYXRpb25JZDogcmVxLmF1dGguaW5zdGFsbGF0aW9uSWQsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gY3JlYXRlU2Vzc2lvbigpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIC8vIGRlbGV0ZSB0aGUgc2Vzc2lvbiB0b2tlbiwgdXNlIHRoZSBkYiB0byBza2lwIGJlZm9yZVNhdmVcbiAgICAgICAgcmV0dXJuIGNvbmZpZy5kYXRhYmFzZS51cGRhdGUoXG4gICAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBvYmplY3RJZDogdXNlci5pZCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNlc3Npb25Ub2tlbjogeyBfX29wOiAnRGVsZXRlJyB9LFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoeyByZXNwb25zZTogc2Vzc2lvbkRhdGEgfSk7XG4gICAgICB9KTtcbiAgfVxuXG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvc2Vzc2lvbnMvbWUnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTWUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3Nlc3Npb25zJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZpbmQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3Nlc3Npb25zLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9zZXNzaW9ucycsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVDcmVhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQVVQnLCAnL3Nlc3Npb25zLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVVcGRhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdERUxFVEUnLCAnL3Nlc3Npb25zLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVEZWxldGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy91cGdyYWRlVG9SZXZvY2FibGVTZXNzaW9uJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZVVwZGF0ZVRvUmV2b2NhYmxlU2Vzc2lvbihyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFNlc3Npb25zUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/UsersRouter.js b/lib/Routers/UsersRouter.js new file mode 100644 index 0000000000..c37fdc404f --- /dev/null +++ b/lib/Routers/UsersRouter.js @@ -0,0 +1,470 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.UsersRouter = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _Config = _interopRequireDefault(require("../Config")); + +var _AccountLockout = _interopRequireDefault(require("../AccountLockout")); + +var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); + +var _rest = _interopRequireDefault(require("../rest")); + +var _Auth = _interopRequireDefault(require("../Auth")); + +var _password = _interopRequireDefault(require("../password")); + +var _triggers = require("../triggers"); + +var _middlewares = require("../middlewares"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +class UsersRouter extends _ClassesRouter.default { + className() { + return '_User'; + } + /** + * Removes all "_" prefixed properties from an object, except "__type" + * @param {Object} obj An object. + */ + + + static removeHiddenProperties(obj) { + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + // Regexp comes from Parse.Object.prototype.validate + if (key !== '__type' && !/^[A-Za-z][0-9A-Za-z_]*$/.test(key)) { + delete obj[key]; + } + } + } + } + /** + * Validates a password request in login and verifyPassword + * @param {Object} req The request + * @returns {Object} User object + * @private + */ + + + _authenticateUserFromRequest(req) { + return new Promise((resolve, reject) => { + // Use query parameters instead if provided in url + let payload = req.body; + + if (!payload.username && req.query && req.query.username || !payload.email && req.query && req.query.email) { + payload = req.query; + } + + const { + username, + email, + password + } = payload; // TODO: use the right error codes / descriptions. + + if (!username && !email) { + throw new _node.default.Error(_node.default.Error.USERNAME_MISSING, 'username/email is required.'); + } + + if (!password) { + throw new _node.default.Error(_node.default.Error.PASSWORD_MISSING, 'password is required.'); + } + + if (typeof password !== 'string' || email && typeof email !== 'string' || username && typeof username !== 'string') { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); + } + + let user; + let isValidPassword = false; + let query; + + if (email && username) { + query = { + email, + username + }; + } else if (email) { + query = { + email + }; + } else { + query = { + $or: [{ + username + }, { + email: username + }] + }; + } + + return req.config.database.find('_User', query).then(results => { + if (!results.length) { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); + } + + if (results.length > 1) { + // corner case where user1 has username == user2 email + req.config.loggerController.warn("There is a user which email is the same as another user's username, logging in based on username"); + user = results.filter(user => user.username === username)[0]; + } else { + user = results[0]; + } + + return _password.default.compare(password, user.password); + }).then(correct => { + isValidPassword = correct; + const accountLockoutPolicy = new _AccountLockout.default(user, req.config); + return accountLockoutPolicy.handleLoginAttempt(isValidPassword); + }).then(() => { + if (!isValidPassword) { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); + } // Ensure the user isn't locked out + // A locked out user won't be able to login + // To lock a user out, just set the ACL to `masterKey` only ({}). + // Empty ACL is OK + + + if (!req.auth.isMaster && user.ACL && Object.keys(user.ACL).length == 0) { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); + } + + if (req.config.verifyUserEmails && req.config.preventLoginWithUnverifiedEmail && !user.emailVerified) { + throw new _node.default.Error(_node.default.Error.EMAIL_NOT_FOUND, 'User email is not verified.'); + } + + delete user.password; // Sometimes the authData still has null on that keys + // https://github.com/parse-community/parse-server/issues/935 + + if (user.authData) { + Object.keys(user.authData).forEach(provider => { + if (user.authData[provider] === null) { + delete user.authData[provider]; + } + }); + + if (Object.keys(user.authData).length == 0) { + delete user.authData; + } + } + + return resolve(user); + }).catch(error => { + return reject(error); + }); + }); + } + /** + * Validates JWT bearer token and looks up user `req.userFromJWT`. CRITICALLY IMPORTANT that the JWT has already been validated by this point (eg: express middleware, AWS API Gateway Authorizer) + * @param {Object} req The request + * @returns {Object} User object + */ + + + _authenticateUserFromRequestWithJwt(req) { + return new Promise((resolve, reject) => { + if (!req.userFromJWT) { + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid credentials.'); + } + + const query = { + objectId: req.userFromJWT.id + }; + return req.config.database.find('_User', query).then(results => { + if (!results.length) throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid credentials.'); + const user = results[0]; + resolve(user); + }).catch(error => { + return reject(error); + }); + }); + } + + handleMe(req) { + if (!req.info || !req.info.sessionToken) { + throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); + } + + const sessionToken = req.info.sessionToken; + return _rest.default.find(req.config, _Auth.default.master(req.config), '_Session', { + sessionToken + }, { + include: 'user' + }, req.info.clientSDK, req.info.context).then(response => { + if (!response.results || response.results.length == 0 || !response.results[0].user) { + throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); + } else { + const user = response.results[0].user; // Send token back on the login, because SDKs expect that. + + user.sessionToken = sessionToken; // Remove hidden properties. + + UsersRouter.removeHiddenProperties(user); + return { + response: user + }; + } + }); + } + + async handleLogIn(req) { + let userFromJWT; + + if (req.userFromJWT) { + // Could be just used `req.userFromJWT`, but the forced lookup + // Ensures the user hasn't been deleted since the the JWT was granted + userFromJWT = await this._authenticateUserFromRequestWithJwt(req); + } + + const user = userFromJWT || (await this._authenticateUserFromRequest(req)); // handle password expiry policy - ignore if user is managed in SSO (provided by JWT) + + if (!userFromJWT && req.config.passwordPolicy && req.config.passwordPolicy.maxPasswordAge) { + let changedAt = user._password_changed_at; + + if (!changedAt) { + // password was created before expiry policy was enabled. + // simply update _User object so that it will start enforcing from now + changedAt = new Date(); + req.config.database.update('_User', { + username: user.username + }, { + _password_changed_at: _node.default._encode(changedAt) + }); + } else { + // check whether the password has expired + if (changedAt.__type == 'Date') { + changedAt = new Date(changedAt.iso); + } // Calculate the expiry time. + + + const expiresAt = new Date(changedAt.getTime() + 86400000 * req.config.passwordPolicy.maxPasswordAge); + if (expiresAt < new Date()) // fail of current time is past password expiry time + throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Your password has expired. Please reset your password.'); + } + } // Remove hidden properties. + + + UsersRouter.removeHiddenProperties(user); + req.config.filesController.expandFilesInObject(req.config, user); // Before login trigger; throws if failure + + await (0, _triggers.maybeRunTrigger)(_triggers.Types.beforeLogin, req.auth, _node.default.User.fromJSON(Object.assign({ + className: '_User' + }, user)), null, req.config); + + const { + sessionData, + createSession + } = _Auth.default.createSession(req.config, { + userId: user.objectId, + createdWith: { + action: 'login', + authProvider: 'password' + }, + installationId: req.info.installationId + }); + + user.sessionToken = sessionData.sessionToken; + await createSession(); + + const afterLoginUser = _node.default.User.fromJSON(Object.assign({ + className: '_User' + }, user)); + + (0, _triggers.maybeRunTrigger)(_triggers.Types.afterLogin, _objectSpread(_objectSpread({}, req.auth), {}, { + user: afterLoginUser + }), afterLoginUser, null, req.config); + return { + response: user + }; + } + + handleVerifyPassword(req) { + return this._authenticateUserFromRequest(req).then(user => { + // Remove hidden properties. + UsersRouter.removeHiddenProperties(user); + return { + response: user + }; + }).catch(error => { + throw error; + }); + } + + handleLogOut(req) { + const success = { + response: {} + }; + + if (req.info && req.info.sessionToken) { + return _rest.default.find(req.config, _Auth.default.master(req.config), '_Session', { + sessionToken: req.info.sessionToken + }, undefined, req.info.clientSDK, req.info.context).then(records => { + if (records.results && records.results.length) { + return _rest.default.del(req.config, _Auth.default.master(req.config), '_Session', records.results[0].objectId, req.info.context).then(() => { + this._runAfterLogoutTrigger(req, records.results[0]); + + return Promise.resolve(success); + }); + } + + return Promise.resolve(success); + }); + } + + return Promise.resolve(success); + } + + _runAfterLogoutTrigger(req, session) { + // After logout trigger + (0, _triggers.maybeRunTrigger)(_triggers.Types.afterLogout, req.auth, _node.default.Session.fromJSON(Object.assign({ + className: '_Session' + }, session)), null, req.config); + } + + _throwOnBadEmailConfig(req) { + try { + _Config.default.validateEmailConfiguration({ + emailAdapter: req.config.userController.adapter, + appName: req.config.appName, + publicServerURL: req.config.publicServerURL, + emailVerifyTokenValidityDuration: req.config.emailVerifyTokenValidityDuration, + emailVerifyTokenReuseIfValid: req.config.emailVerifyTokenReuseIfValid + }); + } catch (e) { + if (typeof e === 'string') { + // Maybe we need a Bad Configuration error, but the SDKs won't understand it. For now, Internal Server Error. + throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'An appName, publicServerURL, and emailAdapter are required for password reset and email verification functionality.'); + } else { + throw e; + } + } + } + + handleResetRequest(req) { + this._throwOnBadEmailConfig(req); + + const { + email + } = req.body; + + if (!email) { + throw new _node.default.Error(_node.default.Error.EMAIL_MISSING, 'you must provide an email'); + } + + if (typeof email !== 'string') { + throw new _node.default.Error(_node.default.Error.INVALID_EMAIL_ADDRESS, 'you must provide a valid email string'); + } + + const userController = req.config.userController; + return userController.sendPasswordResetEmail(email).then(() => { + return Promise.resolve({ + response: {} + }); + }, err => { + if (err.code === _node.default.Error.OBJECT_NOT_FOUND) { + // Return success so that this endpoint can't + // be used to enumerate valid emails + return Promise.resolve({ + response: {} + }); + } else { + throw err; + } + }); + } + + handleVerificationEmailRequest(req) { + this._throwOnBadEmailConfig(req); + + const { + email + } = req.body; + + if (!email) { + throw new _node.default.Error(_node.default.Error.EMAIL_MISSING, 'you must provide an email'); + } + + if (typeof email !== 'string') { + throw new _node.default.Error(_node.default.Error.INVALID_EMAIL_ADDRESS, 'you must provide a valid email string'); + } + + return req.config.database.find('_User', { + email: email + }).then(results => { + if (!results.length || results.length < 1) { + throw new _node.default.Error(_node.default.Error.EMAIL_NOT_FOUND, `No user found with email ${email}`); + } + + const user = results[0]; // remove password field, messes with saving on postgres + + delete user.password; + + if (user.emailVerified) { + throw new _node.default.Error(_node.default.Error.OTHER_CAUSE, `Email ${email} is already verified.`); + } + + const userController = req.config.userController; + return userController.regenerateEmailVerifyToken(user).then(() => { + userController.sendVerificationEmail(user); + return { + response: {} + }; + }); + }); + } + + mountRoutes() { + this.route('GET', '/users', req => { + return this.handleFind(req); + }); + this.route('POST', '/users', _middlewares.promiseEnsureIdempotency, req => { + return this.handleCreate(req); + }); + this.route('GET', '/users/me', req => { + return this.handleMe(req); + }); + this.route('GET', '/users/:objectId', req => { + return this.handleGet(req); + }); + this.route('PUT', '/users/:objectId', _middlewares.promiseEnsureIdempotency, req => { + return this.handleUpdate(req); + }); + this.route('DELETE', '/users/:objectId', req => { + return this.handleDelete(req); + }); + this.route('GET', '/login', req => { + return this.handleLogIn(req); + }); + this.route('POST', '/login', req => { + return this.handleLogIn(req); + }); + this.route('POST', '/logout', req => { + return this.handleLogOut(req); + }); + this.route('POST', '/requestPasswordReset', req => { + return this.handleResetRequest(req); + }); + this.route('POST', '/verificationEmailRequest', req => { + return this.handleVerificationEmailRequest(req); + }); + this.route('GET', '/verifyPassword', req => { + return this.handleVerifyPassword(req); + }); + } + +} + +exports.UsersRouter = UsersRouter; +var _default = UsersRouter; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1VzZXJzUm91dGVyLmpzIl0sIm5hbWVzIjpbIlVzZXJzUm91dGVyIiwiQ2xhc3Nlc1JvdXRlciIsImNsYXNzTmFtZSIsInJlbW92ZUhpZGRlblByb3BlcnRpZXMiLCJvYmoiLCJrZXkiLCJPYmplY3QiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJ0ZXN0IiwiX2F1dGhlbnRpY2F0ZVVzZXJGcm9tUmVxdWVzdCIsInJlcSIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwicGF5bG9hZCIsImJvZHkiLCJ1c2VybmFtZSIsInF1ZXJ5IiwiZW1haWwiLCJwYXNzd29yZCIsIlBhcnNlIiwiRXJyb3IiLCJVU0VSTkFNRV9NSVNTSU5HIiwiUEFTU1dPUkRfTUlTU0lORyIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ1c2VyIiwiaXNWYWxpZFBhc3N3b3JkIiwiJG9yIiwiY29uZmlnIiwiZGF0YWJhc2UiLCJmaW5kIiwidGhlbiIsInJlc3VsdHMiLCJsZW5ndGgiLCJsb2dnZXJDb250cm9sbGVyIiwid2FybiIsImZpbHRlciIsInBhc3N3b3JkQ3J5cHRvIiwiY29tcGFyZSIsImNvcnJlY3QiLCJhY2NvdW50TG9ja291dFBvbGljeSIsIkFjY291bnRMb2Nrb3V0IiwiaGFuZGxlTG9naW5BdHRlbXB0IiwiYXV0aCIsImlzTWFzdGVyIiwiQUNMIiwia2V5cyIsInZlcmlmeVVzZXJFbWFpbHMiLCJwcmV2ZW50TG9naW5XaXRoVW52ZXJpZmllZEVtYWlsIiwiZW1haWxWZXJpZmllZCIsIkVNQUlMX05PVF9GT1VORCIsImF1dGhEYXRhIiwiZm9yRWFjaCIsInByb3ZpZGVyIiwiY2F0Y2giLCJlcnJvciIsIl9hdXRoZW50aWNhdGVVc2VyRnJvbVJlcXVlc3RXaXRoSnd0IiwidXNlckZyb21KV1QiLCJvYmplY3RJZCIsImlkIiwiaGFuZGxlTWUiLCJpbmZvIiwic2Vzc2lvblRva2VuIiwiSU5WQUxJRF9TRVNTSU9OX1RPS0VOIiwicmVzdCIsIkF1dGgiLCJtYXN0ZXIiLCJpbmNsdWRlIiwiY2xpZW50U0RLIiwiY29udGV4dCIsInJlc3BvbnNlIiwiaGFuZGxlTG9nSW4iLCJwYXNzd29yZFBvbGljeSIsIm1heFBhc3N3b3JkQWdlIiwiY2hhbmdlZEF0IiwiX3Bhc3N3b3JkX2NoYW5nZWRfYXQiLCJEYXRlIiwidXBkYXRlIiwiX2VuY29kZSIsIl9fdHlwZSIsImlzbyIsImV4cGlyZXNBdCIsImdldFRpbWUiLCJmaWxlc0NvbnRyb2xsZXIiLCJleHBhbmRGaWxlc0luT2JqZWN0IiwiVHJpZ2dlclR5cGVzIiwiYmVmb3JlTG9naW4iLCJVc2VyIiwiZnJvbUpTT04iLCJhc3NpZ24iLCJzZXNzaW9uRGF0YSIsImNyZWF0ZVNlc3Npb24iLCJ1c2VySWQiLCJjcmVhdGVkV2l0aCIsImFjdGlvbiIsImF1dGhQcm92aWRlciIsImluc3RhbGxhdGlvbklkIiwiYWZ0ZXJMb2dpblVzZXIiLCJhZnRlckxvZ2luIiwiaGFuZGxlVmVyaWZ5UGFzc3dvcmQiLCJoYW5kbGVMb2dPdXQiLCJzdWNjZXNzIiwidW5kZWZpbmVkIiwicmVjb3JkcyIsImRlbCIsIl9ydW5BZnRlckxvZ291dFRyaWdnZXIiLCJzZXNzaW9uIiwiYWZ0ZXJMb2dvdXQiLCJTZXNzaW9uIiwiX3Rocm93T25CYWRFbWFpbENvbmZpZyIsIkNvbmZpZyIsInZhbGlkYXRlRW1haWxDb25maWd1cmF0aW9uIiwiZW1haWxBZGFwdGVyIiwidXNlckNvbnRyb2xsZXIiLCJhZGFwdGVyIiwiYXBwTmFtZSIsInB1YmxpY1NlcnZlclVSTCIsImVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uIiwiZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZCIsImUiLCJJTlRFUk5BTF9TRVJWRVJfRVJST1IiLCJoYW5kbGVSZXNldFJlcXVlc3QiLCJFTUFJTF9NSVNTSU5HIiwiSU5WQUxJRF9FTUFJTF9BRERSRVNTIiwic2VuZFBhc3N3b3JkUmVzZXRFbWFpbCIsImVyciIsImNvZGUiLCJoYW5kbGVWZXJpZmljYXRpb25FbWFpbFJlcXVlc3QiLCJPVEhFUl9DQVVTRSIsInJlZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuIiwic2VuZFZlcmlmaWNhdGlvbkVtYWlsIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsImhhbmRsZUZpbmQiLCJwcm9taXNlRW5zdXJlSWRlbXBvdGVuY3kiLCJoYW5kbGVDcmVhdGUiLCJoYW5kbGVHZXQiLCJoYW5kbGVVcGRhdGUiLCJoYW5kbGVEZWxldGUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7OztBQUVPLE1BQU1BLFdBQU4sU0FBMEJDLHNCQUExQixDQUF3QztBQUM3Q0MsRUFBQUEsU0FBUyxHQUFHO0FBQ1YsV0FBTyxPQUFQO0FBQ0Q7QUFFRDtBQUNGO0FBQ0E7QUFDQTs7O0FBQ0UsU0FBT0Msc0JBQVAsQ0FBOEJDLEdBQTlCLEVBQW1DO0FBQ2pDLFNBQUssSUFBSUMsR0FBVCxJQUFnQkQsR0FBaEIsRUFBcUI7QUFDbkIsVUFBSUUsTUFBTSxDQUFDQyxTQUFQLENBQWlCQyxjQUFqQixDQUFnQ0MsSUFBaEMsQ0FBcUNMLEdBQXJDLEVBQTBDQyxHQUExQyxDQUFKLEVBQW9EO0FBQ2xEO0FBQ0EsWUFBSUEsR0FBRyxLQUFLLFFBQVIsSUFBb0IsQ0FBQywwQkFBMEJLLElBQTFCLENBQStCTCxHQUEvQixDQUF6QixFQUE4RDtBQUM1RCxpQkFBT0QsR0FBRyxDQUFDQyxHQUFELENBQVY7QUFDRDtBQUNGO0FBQ0Y7QUFDRjtBQUVEO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0VNLEVBQUFBLDRCQUE0QixDQUFDQyxHQUFELEVBQU07QUFDaEMsV0FBTyxJQUFJQyxPQUFKLENBQVksQ0FBQ0MsT0FBRCxFQUFVQyxNQUFWLEtBQXFCO0FBQ3RDO0FBQ0EsVUFBSUMsT0FBTyxHQUFHSixHQUFHLENBQUNLLElBQWxCOztBQUNBLFVBQ0csQ0FBQ0QsT0FBTyxDQUFDRSxRQUFU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RUFBbUIsUUFBbkIsRUFBNkIxSCxHQUFHLElBQUk7QUFDbEMsYUFBTyxLQUFLNkQsV0FBTCxDQUFpQjdELEdBQWpCLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBSzBILEtBQUwsQ0FBVyxNQUFYLEVBQW1CLFNBQW5CLEVBQThCMUgsR0FBRyxJQUFJO0FBQ25DLGFBQU8sS0FBSzBGLFlBQUwsQ0FBa0IxRixHQUFsQixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUswSCxLQUFMLENBQVcsTUFBWCxFQUFtQix1QkFBbkIsRUFBNEMxSCxHQUFHLElBQUk7QUFDakQsYUFBTyxLQUFLK0csa0JBQUwsQ0FBd0IvRyxHQUF4QixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUswSCxLQUFMLENBQVcsTUFBWCxFQUFtQiwyQkFBbkIsRUFBZ0QxSCxHQUFHLElBQUk7QUFDckQsYUFBTyxLQUFLcUgsOEJBQUwsQ0FBb0NySCxHQUFwQyxDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUswSCxLQUFMLENBQVcsS0FBWCxFQUFrQixpQkFBbEIsRUFBcUMxSCxHQUFHLElBQUk7QUFDMUMsYUFBTyxLQUFLeUYsb0JBQUwsQ0FBMEJ6RixHQUExQixDQUFQO0FBQ0QsS0FGRDtBQUdEOztBQXRjNEM7OztlQXljaENaLFciLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGVzZSBtZXRob2RzIGhhbmRsZSB0aGUgVXNlci1yZWxhdGVkIHJvdXRlcy5cblxuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuLi9Db25maWcnO1xuaW1wb3J0IEFjY291bnRMb2Nrb3V0IGZyb20gJy4uL0FjY291bnRMb2Nrb3V0JztcbmltcG9ydCBDbGFzc2VzUm91dGVyIGZyb20gJy4vQ2xhc3Nlc1JvdXRlcic7XG5pbXBvcnQgcmVzdCBmcm9tICcuLi9yZXN0JztcbmltcG9ydCBBdXRoIGZyb20gJy4uL0F1dGgnO1xuaW1wb3J0IHBhc3N3b3JkQ3J5cHRvIGZyb20gJy4uL3Bhc3N3b3JkJztcbmltcG9ydCB7IG1heWJlUnVuVHJpZ2dlciwgVHlwZXMgYXMgVHJpZ2dlclR5cGVzIH0gZnJvbSAnLi4vdHJpZ2dlcnMnO1xuaW1wb3J0IHsgcHJvbWlzZUVuc3VyZUlkZW1wb3RlbmN5IH0gZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5leHBvcnQgY2xhc3MgVXNlcnNSb3V0ZXIgZXh0ZW5kcyBDbGFzc2VzUm91dGVyIHtcbiAgY2xhc3NOYW1lKCkge1xuICAgIHJldHVybiAnX1VzZXInO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYWxsIFwiX1wiIHByZWZpeGVkIHByb3BlcnRpZXMgZnJvbSBhbiBvYmplY3QsIGV4Y2VwdCBcIl9fdHlwZVwiXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmogQW4gb2JqZWN0LlxuICAgKi9cbiAgc3RhdGljIHJlbW92ZUhpZGRlblByb3BlcnRpZXMob2JqKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpIHtcbiAgICAgICAgLy8gUmVnZXhwIGNvbWVzIGZyb20gUGFyc2UuT2JqZWN0LnByb3RvdHlwZS52YWxpZGF0ZVxuICAgICAgICBpZiAoa2V5ICE9PSAnX190eXBlJyAmJiAhL15bQS1aYS16XVswLTlBLVphLXpfXSokLy50ZXN0KGtleSkpIHtcbiAgICAgICAgICBkZWxldGUgb2JqW2tleV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIGEgcGFzc3dvcmQgcmVxdWVzdCBpbiBsb2dpbiBhbmQgdmVyaWZ5UGFzc3dvcmRcbiAgICogQHBhcmFtIHtPYmplY3R9IHJlcSBUaGUgcmVxdWVzdFxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBVc2VyIG9iamVjdFxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgX2F1dGhlbnRpY2F0ZVVzZXJGcm9tUmVxdWVzdChyZXEpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgLy8gVXNlIHF1ZXJ5IHBhcmFtZXRlcnMgaW5zdGVhZCBpZiBwcm92aWRlZCBpbiB1cmxcbiAgICAgIGxldCBwYXlsb2FkID0gcmVxLmJvZHk7XG4gICAgICBpZiAoXG4gICAgICAgICghcGF5bG9hZC51c2VybmFtZSAmJiByZXEucXVlcnkgJiYgcmVxLnF1ZXJ5LnVzZXJuYW1lKSB8fFxuICAgICAgICAoIXBheWxvYWQuZW1haWwgJiYgcmVxLnF1ZXJ5ICYmIHJlcS5xdWVyeS5lbWFpbClcbiAgICAgICkge1xuICAgICAgICBwYXlsb2FkID0gcmVxLnF1ZXJ5O1xuICAgICAgfVxuICAgICAgY29uc3QgeyB1c2VybmFtZSwgZW1haWwsIHBhc3N3b3JkIH0gPSBwYXlsb2FkO1xuXG4gICAgICAvLyBUT0RPOiB1c2UgdGhlIHJpZ2h0IGVycm9yIGNvZGVzIC8gZGVzY3JpcHRpb25zLlxuICAgICAgaWYgKCF1c2VybmFtZSAmJiAhZW1haWwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlVTRVJOQU1FX01JU1NJTkcsICd1c2VybmFtZS9lbWFpbCBpcyByZXF1aXJlZC4nKTtcbiAgICAgIH1cbiAgICAgIGlmICghcGFzc3dvcmQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlBBU1NXT1JEX01JU1NJTkcsICdwYXNzd29yZCBpcyByZXF1aXJlZC4nKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgdHlwZW9mIHBhc3N3b3JkICE9PSAnc3RyaW5nJyB8fFxuICAgICAgICAoZW1haWwgJiYgdHlwZW9mIGVtYWlsICE9PSAnc3RyaW5nJykgfHxcbiAgICAgICAgKHVzZXJuYW1lICYmIHR5cGVvZiB1c2VybmFtZSAhPT0gJ3N0cmluZycpXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdJbnZhbGlkIHVzZXJuYW1lL3Bhc3N3b3JkLicpO1xuICAgICAgfVxuXG4gICAgICBsZXQgdXNlcjtcbiAgICAgIGxldCBpc1ZhbGlkUGFzc3dvcmQgPSBmYWxzZTtcbiAgICAgIGxldCBxdWVyeTtcbiAgICAgIGlmIChlbWFpbCAmJiB1c2VybmFtZSkge1xuICAgICAgICBxdWVyeSA9IHsgZW1haWwsIHVzZXJuYW1lIH07XG4gICAgICB9IGVsc2UgaWYgKGVtYWlsKSB7XG4gICAgICAgIHF1ZXJ5ID0geyBlbWFpbCB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcXVlcnkgPSB7ICRvcjogW3sgdXNlcm5hbWUgfSwgeyBlbWFpbDogdXNlcm5hbWUgfV0gfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXEuY29uZmlnLmRhdGFiYXNlXG4gICAgICAgIC5maW5kKCdfVXNlcicsIHF1ZXJ5KVxuICAgICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgICBpZiAoIXJlc3VsdHMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0ludmFsaWQgdXNlcm5hbWUvcGFzc3dvcmQuJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgLy8gY29ybmVyIGNhc2Ugd2hlcmUgdXNlcjEgaGFzIHVzZXJuYW1lID09IHVzZXIyIGVtYWlsXG4gICAgICAgICAgICByZXEuY29uZmlnLmxvZ2dlckNvbnRyb2xsZXIud2FybihcbiAgICAgICAgICAgICAgXCJUaGVyZSBpcyBhIHVzZXIgd2hpY2ggZW1haWwgaXMgdGhlIHNhbWUgYXMgYW5vdGhlciB1c2VyJ3MgdXNlcm5hbWUsIGxvZ2dpbmcgaW4gYmFzZWQgb24gdXNlcm5hbWVcIlxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHVzZXIgPSByZXN1bHRzLmZpbHRlcih1c2VyID0+IHVzZXIudXNlcm5hbWUgPT09IHVzZXJuYW1lKVswXTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdXNlciA9IHJlc3VsdHNbMF07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHBhc3N3b3JkQ3J5cHRvLmNvbXBhcmUocGFzc3dvcmQsIHVzZXIucGFzc3dvcmQpO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihjb3JyZWN0ID0+IHtcbiAgICAgICAgICBpc1ZhbGlkUGFzc3dvcmQgPSBjb3JyZWN0O1xuICAgICAgICAgIGNvbnN0IGFjY291bnRMb2Nrb3V0UG9saWN5ID0gbmV3IEFjY291bnRMb2Nrb3V0KHVzZXIsIHJlcS5jb25maWcpO1xuICAgICAgICAgIHJldHVybiBhY2NvdW50TG9ja291dFBvbGljeS5oYW5kbGVMb2dpbkF0dGVtcHQoaXNWYWxpZFBhc3N3b3JkKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIGlmICghaXNWYWxpZFBhc3N3b3JkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0ludmFsaWQgdXNlcm5hbWUvcGFzc3dvcmQuJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIEVuc3VyZSB0aGUgdXNlciBpc24ndCBsb2NrZWQgb3V0XG4gICAgICAgICAgLy8gQSBsb2NrZWQgb3V0IHVzZXIgd29uJ3QgYmUgYWJsZSB0byBsb2dpblxuICAgICAgICAgIC8vIFRvIGxvY2sgYSB1c2VyIG91dCwganVzdCBzZXQgdGhlIEFDTCB0byBgbWFzdGVyS2V5YCBvbmx5ICAoe30pLlxuICAgICAgICAgIC8vIEVtcHR5IEFDTCBpcyBPS1xuICAgICAgICAgIGlmICghcmVxLmF1dGguaXNNYXN0ZXIgJiYgdXNlci5BQ0wgJiYgT2JqZWN0LmtleXModXNlci5BQ0wpLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0ludmFsaWQgdXNlcm5hbWUvcGFzc3dvcmQuJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHJlcS5jb25maWcudmVyaWZ5VXNlckVtYWlscyAmJlxuICAgICAgICAgICAgcmVxLmNvbmZpZy5wcmV2ZW50TG9naW5XaXRoVW52ZXJpZmllZEVtYWlsICYmXG4gICAgICAgICAgICAhdXNlci5lbWFpbFZlcmlmaWVkXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRU1BSUxfTk9UX0ZPVU5ELCAnVXNlciBlbWFpbCBpcyBub3QgdmVyaWZpZWQuJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZGVsZXRlIHVzZXIucGFzc3dvcmQ7XG5cbiAgICAgICAgICAvLyBTb21ldGltZXMgdGhlIGF1dGhEYXRhIHN0aWxsIGhhcyBudWxsIG9uIHRoYXQga2V5c1xuICAgICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9wYXJzZS1jb21tdW5pdHkvcGFyc2Utc2VydmVyL2lzc3Vlcy85MzVcbiAgICAgICAgICBpZiAodXNlci5hdXRoRGF0YSkge1xuICAgICAgICAgICAgT2JqZWN0LmtleXModXNlci5hdXRoRGF0YSkuZm9yRWFjaChwcm92aWRlciA9PiB7XG4gICAgICAgICAgICAgIGlmICh1c2VyLmF1dGhEYXRhW3Byb3ZpZGVyXSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB1c2VyLmF1dGhEYXRhW3Byb3ZpZGVyXTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModXNlci5hdXRoRGF0YSkubGVuZ3RoID09IDApIHtcbiAgICAgICAgICAgICAgZGVsZXRlIHVzZXIuYXV0aERhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHJlc29sdmUodXNlcik7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBKV1QgYmVhcmVyIHRva2VuIGFuZCBsb29rcyB1cCB1c2VyIGByZXEudXNlckZyb21KV1RgLiBDUklUSUNBTExZIElNUE9SVEFOVCB0aGF0IHRoZSBKV1QgaGFzIGFscmVhZHkgYmVlbiB2YWxpZGF0ZWQgYnkgdGhpcyBwb2ludCAoZWc6IGV4cHJlc3MgbWlkZGxld2FyZSwgQVdTIEFQSSBHYXRld2F5IEF1dGhvcml6ZXIpXG4gICAqIEBwYXJhbSB7T2JqZWN0fSByZXEgVGhlIHJlcXVlc3RcbiAgICogQHJldHVybnMge09iamVjdH0gVXNlciBvYmplY3RcbiAgICovXG4gIF9hdXRoZW50aWNhdGVVc2VyRnJvbVJlcXVlc3RXaXRoSnd0KHJlcSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBpZiAoIXJlcS51c2VyRnJvbUpXVCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0ludmFsaWQgY3JlZGVudGlhbHMuJyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHF1ZXJ5ID0ge1xuICAgICAgICBvYmplY3RJZDogcmVxLnVzZXJGcm9tSldULmlkLFxuICAgICAgfTtcbiAgICAgIHJldHVybiByZXEuY29uZmlnLmRhdGFiYXNlXG4gICAgICAgIC5maW5kKCdfVXNlcicsIHF1ZXJ5KVxuICAgICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgICBpZiAoIXJlc3VsdHMubGVuZ3RoKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdJbnZhbGlkIGNyZWRlbnRpYWxzLicpO1xuICAgICAgICAgIGNvbnN0IHVzZXIgPSByZXN1bHRzWzBdO1xuICAgICAgICAgIHJlc29sdmUodXNlcik7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgaGFuZGxlTWUocmVxKSB7XG4gICAgaWYgKCFyZXEuaW5mbyB8fCAhcmVxLmluZm8uc2Vzc2lvblRva2VuKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOLCAnSW52YWxpZCBzZXNzaW9uIHRva2VuJyk7XG4gICAgfVxuICAgIGNvbnN0IHNlc3Npb25Ub2tlbiA9IHJlcS5pbmZvLnNlc3Npb25Ub2tlbjtcbiAgICByZXR1cm4gcmVzdFxuICAgICAgLmZpbmQoXG4gICAgICAgIHJlcS5jb25maWcsXG4gICAgICAgIEF1dGgubWFzdGVyKHJlcS5jb25maWcpLFxuICAgICAgICAnX1Nlc3Npb24nLFxuICAgICAgICB7IHNlc3Npb25Ub2tlbiB9LFxuICAgICAgICB7IGluY2x1ZGU6ICd1c2VyJyB9LFxuICAgICAgICByZXEuaW5mby5jbGllbnRTREssXG4gICAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgaWYgKCFyZXNwb25zZS5yZXN1bHRzIHx8IHJlc3BvbnNlLnJlc3VsdHMubGVuZ3RoID09IDAgfHwgIXJlc3BvbnNlLnJlc3VsdHNbMF0udXNlcikge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdJbnZhbGlkIHNlc3Npb24gdG9rZW4nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCB1c2VyID0gcmVzcG9uc2UucmVzdWx0c1swXS51c2VyO1xuICAgICAgICAgIC8vIFNlbmQgdG9rZW4gYmFjayBvbiB0aGUgbG9naW4sIGJlY2F1c2UgU0RLcyBleHBlY3QgdGhhdC5cbiAgICAgICAgICB1c2VyLnNlc3Npb25Ub2tlbiA9IHNlc3Npb25Ub2tlbjtcblxuICAgICAgICAgIC8vIFJlbW92ZSBoaWRkZW4gcHJvcGVydGllcy5cbiAgICAgICAgICBVc2Vyc1JvdXRlci5yZW1vdmVIaWRkZW5Qcm9wZXJ0aWVzKHVzZXIpO1xuXG4gICAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHVzZXIgfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVMb2dJbihyZXEpIHtcbiAgICBsZXQgdXNlckZyb21KV1Q7XG4gICAgaWYgKHJlcS51c2VyRnJvbUpXVCkge1xuICAgICAgLy8gQ291bGQgYmUganVzdCB1c2VkIGByZXEudXNlckZyb21KV1RgLCBidXQgdGhlIGZvcmNlZCBsb29rdXBcbiAgICAgIC8vIEVuc3VyZXMgdGhlIHVzZXIgaGFzbid0IGJlZW4gZGVsZXRlZCBzaW5jZSB0aGUgdGhlIEpXVCB3YXMgZ3JhbnRlZFxuICAgICAgdXNlckZyb21KV1QgPSBhd2FpdCB0aGlzLl9hdXRoZW50aWNhdGVVc2VyRnJvbVJlcXVlc3RXaXRoSnd0KHJlcSk7XG4gICAgfVxuXG4gICAgY29uc3QgdXNlciA9IHVzZXJGcm9tSldUIHx8IChhd2FpdCB0aGlzLl9hdXRoZW50aWNhdGVVc2VyRnJvbVJlcXVlc3QocmVxKSk7XG5cbiAgICAvLyBoYW5kbGUgcGFzc3dvcmQgZXhwaXJ5IHBvbGljeSAtIGlnbm9yZSBpZiB1c2VyIGlzIG1hbmFnZWQgaW4gU1NPIChwcm92aWRlZCBieSBKV1QpXG4gICAgaWYgKCF1c2VyRnJvbUpXVCAmJiByZXEuY29uZmlnLnBhc3N3b3JkUG9saWN5ICYmIHJlcS5jb25maWcucGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRBZ2UpIHtcbiAgICAgIGxldCBjaGFuZ2VkQXQgPSB1c2VyLl9wYXNzd29yZF9jaGFuZ2VkX2F0O1xuXG4gICAgICBpZiAoIWNoYW5nZWRBdCkge1xuICAgICAgICAvLyBwYXNzd29yZCB3YXMgY3JlYXRlZCBiZWZvcmUgZXhwaXJ5IHBvbGljeSB3YXMgZW5hYmxlZC5cbiAgICAgICAgLy8gc2ltcGx5IHVwZGF0ZSBfVXNlciBvYmplY3Qgc28gdGhhdCBpdCB3aWxsIHN0YXJ0IGVuZm9yY2luZyBmcm9tIG5vd1xuICAgICAgICBjaGFuZ2VkQXQgPSBuZXcgRGF0ZSgpO1xuICAgICAgICByZXEuY29uZmlnLmRhdGFiYXNlLnVwZGF0ZShcbiAgICAgICAgICAnX1VzZXInLFxuICAgICAgICAgIHsgdXNlcm5hbWU6IHVzZXIudXNlcm5hbWUgfSxcbiAgICAgICAgICB7IF9wYXNzd29yZF9jaGFuZ2VkX2F0OiBQYXJzZS5fZW5jb2RlKGNoYW5nZWRBdCkgfVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGUgcGFzc3dvcmQgaGFzIGV4cGlyZWRcbiAgICAgICAgaWYgKGNoYW5nZWRBdC5fX3R5cGUgPT0gJ0RhdGUnKSB7XG4gICAgICAgICAgY2hhbmdlZEF0ID0gbmV3IERhdGUoY2hhbmdlZEF0Lmlzbyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBleHBpcnkgdGltZS5cbiAgICAgICAgY29uc3QgZXhwaXJlc0F0ID0gbmV3IERhdGUoXG4gICAgICAgICAgY2hhbmdlZEF0LmdldFRpbWUoKSArIDg2NDAwMDAwICogcmVxLmNvbmZpZy5wYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEFnZVxuICAgICAgICApO1xuICAgICAgICBpZiAoZXhwaXJlc0F0IDwgbmV3IERhdGUoKSlcbiAgICAgICAgICAvLyBmYWlsIG9mIGN1cnJlbnQgdGltZSBpcyBwYXN0IHBhc3N3b3JkIGV4cGlyeSB0aW1lXG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICAgICAgICdZb3VyIHBhc3N3b3JkIGhhcyBleHBpcmVkLiBQbGVhc2UgcmVzZXQgeW91ciBwYXNzd29yZC4nXG4gICAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZW1vdmUgaGlkZGVuIHByb3BlcnRpZXMuXG4gICAgVXNlcnNSb3V0ZXIucmVtb3ZlSGlkZGVuUHJvcGVydGllcyh1c2VyKTtcblxuICAgIHJlcS5jb25maWcuZmlsZXNDb250cm9sbGVyLmV4cGFuZEZpbGVzSW5PYmplY3QocmVxLmNvbmZpZywgdXNlcik7XG5cbiAgICAvLyBCZWZvcmUgbG9naW4gdHJpZ2dlcjsgdGhyb3dzIGlmIGZhaWx1cmVcbiAgICBhd2FpdCBtYXliZVJ1blRyaWdnZXIoXG4gICAgICBUcmlnZ2VyVHlwZXMuYmVmb3JlTG9naW4sXG4gICAgICByZXEuYXV0aCxcbiAgICAgIFBhcnNlLlVzZXIuZnJvbUpTT04oT2JqZWN0LmFzc2lnbih7IGNsYXNzTmFtZTogJ19Vc2VyJyB9LCB1c2VyKSksXG4gICAgICBudWxsLFxuICAgICAgcmVxLmNvbmZpZ1xuICAgICk7XG5cbiAgICBjb25zdCB7IHNlc3Npb25EYXRhLCBjcmVhdGVTZXNzaW9uIH0gPSBBdXRoLmNyZWF0ZVNlc3Npb24ocmVxLmNvbmZpZywge1xuICAgICAgdXNlcklkOiB1c2VyLm9iamVjdElkLFxuICAgICAgY3JlYXRlZFdpdGg6IHtcbiAgICAgICAgYWN0aW9uOiAnbG9naW4nLFxuICAgICAgICBhdXRoUHJvdmlkZXI6ICdwYXNzd29yZCcsXG4gICAgICB9LFxuICAgICAgaW5zdGFsbGF0aW9uSWQ6IHJlcS5pbmZvLmluc3RhbGxhdGlvbklkLFxuICAgIH0pO1xuXG4gICAgdXNlci5zZXNzaW9uVG9rZW4gPSBzZXNzaW9uRGF0YS5zZXNzaW9uVG9rZW47XG5cbiAgICBhd2FpdCBjcmVhdGVTZXNzaW9uKCk7XG5cbiAgICBjb25zdCBhZnRlckxvZ2luVXNlciA9IFBhcnNlLlVzZXIuZnJvbUpTT04oT2JqZWN0LmFzc2lnbih7IGNsYXNzTmFtZTogJ19Vc2VyJyB9LCB1c2VyKSk7XG4gICAgbWF5YmVSdW5UcmlnZ2VyKFxuICAgICAgVHJpZ2dlclR5cGVzLmFmdGVyTG9naW4sXG4gICAgICB7IC4uLnJlcS5hdXRoLCB1c2VyOiBhZnRlckxvZ2luVXNlciB9LFxuICAgICAgYWZ0ZXJMb2dpblVzZXIsXG4gICAgICBudWxsLFxuICAgICAgcmVxLmNvbmZpZ1xuICAgICk7XG5cbiAgICByZXR1cm4geyByZXNwb25zZTogdXNlciB9O1xuICB9XG5cbiAgaGFuZGxlVmVyaWZ5UGFzc3dvcmQocmVxKSB7XG4gICAgcmV0dXJuIHRoaXMuX2F1dGhlbnRpY2F0ZVVzZXJGcm9tUmVxdWVzdChyZXEpXG4gICAgICAudGhlbih1c2VyID0+IHtcbiAgICAgICAgLy8gUmVtb3ZlIGhpZGRlbiBwcm9wZXJ0aWVzLlxuICAgICAgICBVc2Vyc1JvdXRlci5yZW1vdmVIaWRkZW5Qcm9wZXJ0aWVzKHVzZXIpO1xuXG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB1c2VyIH07XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcbiAgfVxuXG4gIGhhbmRsZUxvZ091dChyZXEpIHtcbiAgICBjb25zdCBzdWNjZXNzID0geyByZXNwb25zZToge30gfTtcbiAgICBpZiAocmVxLmluZm8gJiYgcmVxLmluZm8uc2Vzc2lvblRva2VuKSB7XG4gICAgICByZXR1cm4gcmVzdFxuICAgICAgICAuZmluZChcbiAgICAgICAgICByZXEuY29uZmlnLFxuICAgICAgICAgIEF1dGgubWFzdGVyKHJlcS5jb25maWcpLFxuICAgICAgICAgICdfU2Vzc2lvbicsXG4gICAgICAgICAgeyBzZXNzaW9uVG9rZW46IHJlcS5pbmZvLnNlc3Npb25Ub2tlbiB9LFxuICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICByZXEuaW5mby5jbGllbnRTREssXG4gICAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgICApXG4gICAgICAgIC50aGVuKHJlY29yZHMgPT4ge1xuICAgICAgICAgIGlmIChyZWNvcmRzLnJlc3VsdHMgJiYgcmVjb3Jkcy5yZXN1bHRzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3RcbiAgICAgICAgICAgICAgLmRlbChcbiAgICAgICAgICAgICAgICByZXEuY29uZmlnLFxuICAgICAgICAgICAgICAgIEF1dGgubWFzdGVyKHJlcS5jb25maWcpLFxuICAgICAgICAgICAgICAgICdfU2Vzc2lvbicsXG4gICAgICAgICAgICAgICAgcmVjb3Jkcy5yZXN1bHRzWzBdLm9iamVjdElkLFxuICAgICAgICAgICAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcnVuQWZ0ZXJMb2dvdXRUcmlnZ2VyKHJlcSwgcmVjb3Jkcy5yZXN1bHRzWzBdKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHN1Y2Nlc3MpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShzdWNjZXNzKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoc3VjY2Vzcyk7XG4gIH1cblxuICBfcnVuQWZ0ZXJMb2dvdXRUcmlnZ2VyKHJlcSwgc2Vzc2lvbikge1xuICAgIC8vIEFmdGVyIGxvZ291dCB0cmlnZ2VyXG4gICAgbWF5YmVSdW5UcmlnZ2VyKFxuICAgICAgVHJpZ2dlclR5cGVzLmFmdGVyTG9nb3V0LFxuICAgICAgcmVxLmF1dGgsXG4gICAgICBQYXJzZS5TZXNzaW9uLmZyb21KU09OKE9iamVjdC5hc3NpZ24oeyBjbGFzc05hbWU6ICdfU2Vzc2lvbicgfSwgc2Vzc2lvbikpLFxuICAgICAgbnVsbCxcbiAgICAgIHJlcS5jb25maWdcbiAgICApO1xuICB9XG5cbiAgX3Rocm93T25CYWRFbWFpbENvbmZpZyhyZXEpIHtcbiAgICB0cnkge1xuICAgICAgQ29uZmlnLnZhbGlkYXRlRW1haWxDb25maWd1cmF0aW9uKHtcbiAgICAgICAgZW1haWxBZGFwdGVyOiByZXEuY29uZmlnLnVzZXJDb250cm9sbGVyLmFkYXB0ZXIsXG4gICAgICAgIGFwcE5hbWU6IHJlcS5jb25maWcuYXBwTmFtZSxcbiAgICAgICAgcHVibGljU2VydmVyVVJMOiByZXEuY29uZmlnLnB1YmxpY1NlcnZlclVSTCxcbiAgICAgICAgZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb246IHJlcS5jb25maWcuZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24sXG4gICAgICAgIGVtYWlsVmVyaWZ5VG9rZW5SZXVzZUlmVmFsaWQ6IHJlcS5jb25maWcuZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZCxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmICh0eXBlb2YgZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgLy8gTWF5YmUgd2UgbmVlZCBhIEJhZCBDb25maWd1cmF0aW9uIGVycm9yLCBidXQgdGhlIFNES3Mgd29uJ3QgdW5kZXJzdGFuZCBpdC4gRm9yIG5vdywgSW50ZXJuYWwgU2VydmVyIEVycm9yLlxuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgICAgICdBbiBhcHBOYW1lLCBwdWJsaWNTZXJ2ZXJVUkwsIGFuZCBlbWFpbEFkYXB0ZXIgYXJlIHJlcXVpcmVkIGZvciBwYXNzd29yZCByZXNldCBhbmQgZW1haWwgdmVyaWZpY2F0aW9uIGZ1bmN0aW9uYWxpdHkuJ1xuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBoYW5kbGVSZXNldFJlcXVlc3QocmVxKSB7XG4gICAgdGhpcy5fdGhyb3dPbkJhZEVtYWlsQ29uZmlnKHJlcSk7XG5cbiAgICBjb25zdCB7IGVtYWlsIH0gPSByZXEuYm9keTtcbiAgICBpZiAoIWVtYWlsKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRU1BSUxfTUlTU0lORywgJ3lvdSBtdXN0IHByb3ZpZGUgYW4gZW1haWwnKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBlbWFpbCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9FTUFJTF9BRERSRVNTLFxuICAgICAgICAneW91IG11c3QgcHJvdmlkZSBhIHZhbGlkIGVtYWlsIHN0cmluZydcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IHVzZXJDb250cm9sbGVyID0gcmVxLmNvbmZpZy51c2VyQ29udHJvbGxlcjtcbiAgICByZXR1cm4gdXNlckNvbnRyb2xsZXIuc2VuZFBhc3N3b3JkUmVzZXRFbWFpbChlbWFpbCkudGhlbihcbiAgICAgICgpID0+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgcmVzcG9uc2U6IHt9LFxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICBlcnIgPT4ge1xuICAgICAgICBpZiAoZXJyLmNvZGUgPT09IFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQpIHtcbiAgICAgICAgICAvLyBSZXR1cm4gc3VjY2VzcyBzbyB0aGF0IHRoaXMgZW5kcG9pbnQgY2FuJ3RcbiAgICAgICAgICAvLyBiZSB1c2VkIHRvIGVudW1lcmF0ZSB2YWxpZCBlbWFpbHNcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICAgIHJlc3BvbnNlOiB7fSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgaGFuZGxlVmVyaWZpY2F0aW9uRW1haWxSZXF1ZXN0KHJlcSkge1xuICAgIHRoaXMuX3Rocm93T25CYWRFbWFpbENvbmZpZyhyZXEpO1xuXG4gICAgY29uc3QgeyBlbWFpbCB9ID0gcmVxLmJvZHk7XG4gICAgaWYgKCFlbWFpbCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkVNQUlMX01JU1NJTkcsICd5b3UgbXVzdCBwcm92aWRlIGFuIGVtYWlsJyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZW1haWwgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfRU1BSUxfQUREUkVTUyxcbiAgICAgICAgJ3lvdSBtdXN0IHByb3ZpZGUgYSB2YWxpZCBlbWFpbCBzdHJpbmcnXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiByZXEuY29uZmlnLmRhdGFiYXNlLmZpbmQoJ19Vc2VyJywgeyBlbWFpbDogZW1haWwgfSkudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIGlmICghcmVzdWx0cy5sZW5ndGggfHwgcmVzdWx0cy5sZW5ndGggPCAxKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5FTUFJTF9OT1RfRk9VTkQsIGBObyB1c2VyIGZvdW5kIHdpdGggZW1haWwgJHtlbWFpbH1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHVzZXIgPSByZXN1bHRzWzBdO1xuXG4gICAgICAvLyByZW1vdmUgcGFzc3dvcmQgZmllbGQsIG1lc3NlcyB3aXRoIHNhdmluZyBvbiBwb3N0Z3Jlc1xuICAgICAgZGVsZXRlIHVzZXIucGFzc3dvcmQ7XG5cbiAgICAgIGlmICh1c2VyLmVtYWlsVmVyaWZpZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9USEVSX0NBVVNFLCBgRW1haWwgJHtlbWFpbH0gaXMgYWxyZWFkeSB2ZXJpZmllZC5gKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdXNlckNvbnRyb2xsZXIgPSByZXEuY29uZmlnLnVzZXJDb250cm9sbGVyO1xuICAgICAgcmV0dXJuIHVzZXJDb250cm9sbGVyLnJlZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuKHVzZXIpLnRoZW4oKCkgPT4ge1xuICAgICAgICB1c2VyQ29udHJvbGxlci5zZW5kVmVyaWZpY2F0aW9uRW1haWwodXNlcik7XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7fSB9O1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3VzZXJzJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZpbmQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy91c2VycycsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSwgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUNyZWF0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvdXNlcnMvbWUnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTWUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3VzZXJzLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQVVQnLCAnL3VzZXJzLzpvYmplY3RJZCcsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSwgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZVVwZGF0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0RFTEVURScsICcvdXNlcnMvOm9iamVjdElkJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZURlbGV0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvbG9naW4nLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTG9nSW4ocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9sb2dpbicsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVMb2dJbihyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL2xvZ291dCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVMb2dPdXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9yZXF1ZXN0UGFzc3dvcmRSZXNldCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVSZXNldFJlcXVlc3QocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy92ZXJpZmljYXRpb25FbWFpbFJlcXVlc3QnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlVmVyaWZpY2F0aW9uRW1haWxSZXF1ZXN0KHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy92ZXJpZnlQYXNzd29yZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVWZXJpZnlQYXNzd29yZChyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFVzZXJzUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/StatusHandler.js b/lib/StatusHandler.js new file mode 100644 index 0000000000..708d04b1b0 --- /dev/null +++ b/lib/StatusHandler.js @@ -0,0 +1,386 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.flatten = flatten; +exports.jobStatusHandler = jobStatusHandler; +exports.pushStatusHandler = pushStatusHandler; + +var _cryptoUtils = require("./cryptoUtils"); + +var _logger = require("./logger"); + +var _rest = _interopRequireDefault(require("./rest")); + +var _Auth = _interopRequireDefault(require("./Auth")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const PUSH_STATUS_COLLECTION = '_PushStatus'; +const JOB_STATUS_COLLECTION = '_JobStatus'; + +const incrementOp = function (object = {}, key, amount = 1) { + if (!object[key]) { + object[key] = { + __op: 'Increment', + amount: amount + }; + } else { + object[key].amount += amount; + } + + return object[key]; +}; + +function flatten(array) { + var flattened = []; + + for (var i = 0; i < array.length; i++) { + if (Array.isArray(array[i])) { + flattened = flattened.concat(flatten(array[i])); + } else { + flattened.push(array[i]); + } + } + + return flattened; +} + +function statusHandler(className, database) { + let lastPromise = Promise.resolve(); + + function create(object) { + lastPromise = lastPromise.then(() => { + return database.create(className, object).then(() => { + return Promise.resolve(object); + }); + }); + return lastPromise; + } + + function update(where, object) { + lastPromise = lastPromise.then(() => { + return database.update(className, where, object); + }); + return lastPromise; + } + + return Object.freeze({ + create, + update + }); +} + +function restStatusHandler(className, config) { + let lastPromise = Promise.resolve(); + + const auth = _Auth.default.master(config); + + function create(object) { + lastPromise = lastPromise.then(() => { + return _rest.default.create(config, auth, className, object).then(({ + response + }) => { + // merge the objects + return Promise.resolve(Object.assign({}, object, response)); + }); + }); + return lastPromise; + } + + function update(where, object) { + // TODO: when we have updateWhere, use that for proper interfacing + lastPromise = lastPromise.then(() => { + return _rest.default.update(config, auth, className, { + objectId: where.objectId + }, object).then(({ + response + }) => { + // merge the objects + return Promise.resolve(Object.assign({}, object, response)); + }); + }); + return lastPromise; + } + + return Object.freeze({ + create, + update + }); +} + +function jobStatusHandler(config) { + let jobStatus; + const objectId = (0, _cryptoUtils.newObjectId)(config.objectIdSize); + const database = config.database; + const handler = statusHandler(JOB_STATUS_COLLECTION, database); + + const setRunning = function (jobName, params) { + const now = new Date(); + jobStatus = { + objectId, + jobName, + params, + status: 'running', + source: 'api', + createdAt: now, + // lockdown! + ACL: {} + }; + return handler.create(jobStatus); + }; + + const setMessage = function (message) { + if (!message || typeof message !== 'string') { + return Promise.resolve(); + } + + return handler.update({ + objectId + }, { + message + }); + }; + + const setSucceeded = function (message) { + return setFinalStatus('succeeded', message); + }; + + const setFailed = function (message) { + return setFinalStatus('failed', message); + }; + + const setFinalStatus = function (status, message = undefined) { + const finishedAt = new Date(); + const update = { + status, + finishedAt + }; + + if (message && typeof message === 'string') { + update.message = message; + } + + if (message instanceof Error && typeof message.message === 'string') { + update.message = message.message; + } + + return handler.update({ + objectId + }, update); + }; + + return Object.freeze({ + setRunning, + setSucceeded, + setMessage, + setFailed + }); +} + +function pushStatusHandler(config, existingObjectId) { + let pushStatus; + const database = config.database; + const handler = restStatusHandler(PUSH_STATUS_COLLECTION, config); + let objectId = existingObjectId; + + const setInitial = function (body = {}, where, options = { + source: 'rest' + }) { + const now = new Date(); + let pushTime = now.toISOString(); + let status = 'pending'; + + if (Object.prototype.hasOwnProperty.call(body, 'push_time')) { + if (config.hasPushScheduledSupport) { + pushTime = body.push_time; + status = 'scheduled'; + } else { + _logger.logger.warn('Trying to schedule a push while server is not configured.'); + + _logger.logger.warn('Push will be sent immediately'); + } + } + + const data = body.data || {}; + const payloadString = JSON.stringify(data); + let pushHash; + + if (typeof data.alert === 'string') { + pushHash = (0, _cryptoUtils.md5Hash)(data.alert); + } else if (typeof data.alert === 'object') { + pushHash = (0, _cryptoUtils.md5Hash)(JSON.stringify(data.alert)); + } else { + pushHash = 'd41d8cd98f00b204e9800998ecf8427e'; + } + + const object = { + pushTime, + query: JSON.stringify(where), + payload: payloadString, + source: options.source, + title: options.title, + expiry: body.expiration_time, + expiration_interval: body.expiration_interval, + status: status, + numSent: 0, + pushHash, + // lockdown! + ACL: {} + }; + return handler.create(object).then(result => { + objectId = result.objectId; + pushStatus = { + objectId + }; + return Promise.resolve(pushStatus); + }); + }; + + const setRunning = function (batches) { + _logger.logger.verbose(`_PushStatus ${objectId}: sending push to installations with %d batches`, batches); + + return handler.update({ + status: 'pending', + objectId: objectId + }, { + status: 'running', + count: batches + }); + }; + + const trackSent = function (results, UTCOffset, cleanupInstallations = process.env.PARSE_SERVER_CLEANUP_INVALID_INSTALLATIONS) { + const update = { + numSent: 0, + numFailed: 0 + }; + const devicesToRemove = []; + + if (Array.isArray(results)) { + results = flatten(results); + results.reduce((memo, result) => { + // Cannot handle that + if (!result || !result.device || !result.device.deviceType) { + return memo; + } + + const deviceType = result.device.deviceType; + const key = result.transmitted ? `sentPerType.${deviceType}` : `failedPerType.${deviceType}`; + memo[key] = incrementOp(memo, key); + + if (typeof UTCOffset !== 'undefined') { + const offsetKey = result.transmitted ? `sentPerUTCOffset.${UTCOffset}` : `failedPerUTCOffset.${UTCOffset}`; + memo[offsetKey] = incrementOp(memo, offsetKey); + } + + if (result.transmitted) { + memo.numSent++; + } else { + if (result && result.response && result.response.error && result.device && result.device.deviceToken) { + const token = result.device.deviceToken; + const error = result.response.error; // GCM errors + + if (error === 'NotRegistered' || error === 'InvalidRegistration') { + devicesToRemove.push(token); + } // APNS errors + + + if (error === 'Unregistered' || error === 'BadDeviceToken') { + devicesToRemove.push(token); + } + } + + memo.numFailed++; + } + + return memo; + }, update); + } + + _logger.logger.verbose(`_PushStatus ${objectId}: sent push! %d success, %d failures`, update.numSent, update.numFailed); + + _logger.logger.verbose(`_PushStatus ${objectId}: needs cleanup`, { + devicesToRemove + }); + + ['numSent', 'numFailed'].forEach(key => { + if (update[key] > 0) { + update[key] = { + __op: 'Increment', + amount: update[key] + }; + } else { + delete update[key]; + } + }); + + if (devicesToRemove.length > 0 && cleanupInstallations) { + _logger.logger.info(`Removing device tokens on ${devicesToRemove.length} _Installations`); + + database.update('_Installation', { + deviceToken: { + $in: devicesToRemove + } + }, { + deviceToken: { + __op: 'Delete' + } + }, { + acl: undefined, + many: true + }); + } // indicate this batch is complete + + + incrementOp(update, 'count', -1); + return handler.update({ + objectId + }, update).then(res => { + if (res && res.count === 0) { + return this.complete(); + } + }); + }; + + const complete = function () { + return handler.update({ + objectId + }, { + status: 'succeeded', + count: { + __op: 'Delete' + } + }); + }; + + const fail = function (err) { + if (typeof err === 'string') { + err = { + message: err + }; + } + + const update = { + errorMessage: err, + status: 'failed' + }; + return handler.update({ + objectId + }, update); + }; + + const rval = { + setInitial, + setRunning, + trackSent, + complete, + fail + }; // define objectId to be dynamic + + Object.defineProperty(rval, 'objectId', { + get: () => objectId + }); + return Object.freeze(rval); +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9TdGF0dXNIYW5kbGVyLmpzIl0sIm5hbWVzIjpbIlBVU0hfU1RBVFVTX0NPTExFQ1RJT04iLCJKT0JfU1RBVFVTX0NPTExFQ1RJT04iLCJpbmNyZW1lbnRPcCIsIm9iamVjdCIsImtleSIsImFtb3VudCIsIl9fb3AiLCJmbGF0dGVuIiwiYXJyYXkiLCJmbGF0dGVuZWQiLCJpIiwibGVuZ3RoIiwiQXJyYXkiLCJpc0FycmF5IiwiY29uY2F0IiwicHVzaCIsInN0YXR1c0hhbmRsZXIiLCJjbGFzc05hbWUiLCJkYXRhYmFzZSIsImxhc3RQcm9taXNlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJjcmVhdGUiLCJ0aGVuIiwidXBkYXRlIiwid2hlcmUiLCJPYmplY3QiLCJmcmVlemUiLCJyZXN0U3RhdHVzSGFuZGxlciIsImNvbmZpZyIsImF1dGgiLCJBdXRoIiwibWFzdGVyIiwicmVzdCIsInJlc3BvbnNlIiwiYXNzaWduIiwib2JqZWN0SWQiLCJqb2JTdGF0dXNIYW5kbGVyIiwiam9iU3RhdHVzIiwib2JqZWN0SWRTaXplIiwiaGFuZGxlciIsInNldFJ1bm5pbmciLCJqb2JOYW1lIiwicGFyYW1zIiwibm93IiwiRGF0ZSIsInN0YXR1cyIsInNvdXJjZSIsImNyZWF0ZWRBdCIsIkFDTCIsInNldE1lc3NhZ2UiLCJtZXNzYWdlIiwic2V0U3VjY2VlZGVkIiwic2V0RmluYWxTdGF0dXMiLCJzZXRGYWlsZWQiLCJ1bmRlZmluZWQiLCJmaW5pc2hlZEF0IiwiRXJyb3IiLCJwdXNoU3RhdHVzSGFuZGxlciIsImV4aXN0aW5nT2JqZWN0SWQiLCJwdXNoU3RhdHVzIiwic2V0SW5pdGlhbCIsImJvZHkiLCJvcHRpb25zIiwicHVzaFRpbWUiLCJ0b0lTT1N0cmluZyIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0IiwicHVzaF90aW1lIiwibG9nZ2VyIiwid2FybiIsImRhdGEiLCJwYXlsb2FkU3RyaW5nIiwiSlNPTiIsInN0cmluZ2lmeSIsInB1c2hIYXNoIiwiYWxlcnQiLCJxdWVyeSIsInBheWxvYWQiLCJ0aXRsZSIsImV4cGlyeSIsImV4cGlyYXRpb25fdGltZSIsImV4cGlyYXRpb25faW50ZXJ2YWwiLCJudW1TZW50IiwicmVzdWx0IiwiYmF0Y2hlcyIsInZlcmJvc2UiLCJjb3VudCIsInRyYWNrU2VudCIsInJlc3VsdHMiLCJVVENPZmZzZXQiLCJjbGVhbnVwSW5zdGFsbGF0aW9ucyIsInByb2Nlc3MiLCJlbnYiLCJQQVJTRV9TRVJWRVJfQ0xFQU5VUF9JTlZBTElEX0lOU1RBTExBVElPTlMiLCJudW1GYWlsZWQiLCJkZXZpY2VzVG9SZW1vdmUiLCJyZWR1Y2UiLCJtZW1vIiwiZGV2aWNlIiwiZGV2aWNlVHlwZSIsInRyYW5zbWl0dGVkIiwib2Zmc2V0S2V5IiwiZXJyb3IiLCJkZXZpY2VUb2tlbiIsInRva2VuIiwiZm9yRWFjaCIsImluZm8iLCIkaW4iLCJhY2wiLCJtYW55IiwicmVzIiwiY29tcGxldGUiLCJmYWlsIiwiZXJyIiwiZXJyb3JNZXNzYWdlIiwicnZhbCIsImRlZmluZVByb3BlcnR5IiwiZ2V0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUVBLE1BQU1BLHNCQUFzQixHQUFHLGFBQS9CO0FBQ0EsTUFBTUMscUJBQXFCLEdBQUcsWUFBOUI7O0FBRUEsTUFBTUMsV0FBVyxHQUFHLFVBQVVDLE1BQU0sR0FBRyxFQUFuQixFQUF1QkMsR0FBdkIsRUFBNEJDLE1BQU0sR0FBRyxDQUFyQyxFQUF3QztBQUMxRCxNQUFJLENBQUNGLE1BQU0sQ0FBQ0MsR0FBRCxDQUFYLEVBQWtCO0FBQ2hCRCxJQUFBQSxNQUFNLENBQUNDLEdBQUQsQ0FBTixHQUFjO0FBQUVFLE1BQUFBLElBQUksRUFBRSxXQUFSO0FBQXFCRCxNQUFBQSxNQUFNLEVBQUVBO0FBQTdCLEtBQWQ7QUFDRCxHQUZELE1BRU87QUFDTEYsSUFBQUEsTUFBTSxDQUFDQyxHQUFELENBQU4s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QUFNOEYsSUFBSSxHQUFHO0FBQ1h6RCxJQUFBQSxVQURXO0FBRVhwQixJQUFBQSxVQUZXO0FBR1hpRCxJQUFBQSxTQUhXO0FBSVh3QixJQUFBQSxRQUpXO0FBS1hDLElBQUFBO0FBTFcsR0FBYixDQTNMMEQsQ0FtTTFEOztBQUNBekYsRUFBQUEsTUFBTSxDQUFDNkYsY0FBUCxDQUFzQkQsSUFBdEIsRUFBNEIsVUFBNUIsRUFBd0M7QUFDdENFLElBQUFBLEdBQUcsRUFBRSxNQUFNcEY7QUFEMkIsR0FBeEM7QUFJQSxTQUFPVixNQUFNLENBQUNDLE1BQVAsQ0FBYzJGLElBQWQsQ0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbWQ1SGFzaCwgbmV3T2JqZWN0SWQgfSBmcm9tICcuL2NyeXB0b1V0aWxzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4vbG9nZ2VyJztcbmltcG9ydCByZXN0IGZyb20gJy4vcmVzdCc7XG5pbXBvcnQgQXV0aCBmcm9tICcuL0F1dGgnO1xuXG5jb25zdCBQVVNIX1NUQVRVU19DT0xMRUNUSU9OID0gJ19QdXNoU3RhdHVzJztcbmNvbnN0IEpPQl9TVEFUVVNfQ09MTEVDVElPTiA9ICdfSm9iU3RhdHVzJztcblxuY29uc3QgaW5jcmVtZW50T3AgPSBmdW5jdGlvbiAob2JqZWN0ID0ge30sIGtleSwgYW1vdW50ID0gMSkge1xuICBpZiAoIW9iamVjdFtrZXldKSB7XG4gICAgb2JqZWN0W2tleV0gPSB7IF9fb3A6ICdJbmNyZW1lbnQnLCBhbW91bnQ6IGFtb3VudCB9O1xuICB9IGVsc2Uge1xuICAgIG9iamVjdFtrZXldLmFtb3VudCArPSBhbW91bnQ7XG4gIH1cbiAgcmV0dXJuIG9iamVjdFtrZXldO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGZsYXR0ZW4oYXJyYXkpIHtcbiAgdmFyIGZsYXR0ZW5lZCA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYXJyYXlbaV0pKSB7XG4gICAgICBmbGF0dGVuZWQgPSBmbGF0dGVuZWQuY29uY2F0KGZsYXR0ZW4oYXJyYXlbaV0pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZmxhdHRlbmVkLnB1c2goYXJyYXlbaV0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmxhdHRlbmVkO1xufVxuXG5mdW5jdGlvbiBzdGF0dXNIYW5kbGVyKGNsYXNzTmFtZSwgZGF0YWJhc2UpIHtcbiAgbGV0IGxhc3RQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG5cbiAgZnVuY3Rpb24gY3JlYXRlKG9iamVjdCkge1xuICAgIGxhc3RQcm9taXNlID0gbGFzdFByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gZGF0YWJhc2UuY3JlYXRlKGNsYXNzTmFtZSwgb2JqZWN0KS50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShvYmplY3QpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGxhc3RQcm9taXNlO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlKHdoZXJlLCBvYmplY3QpIHtcbiAgICBsYXN0UHJvbWlzZSA9IGxhc3RQcm9taXNlLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIGRhdGFiYXNlLnVwZGF0ZShjbGFzc05hbWUsIHdoZXJlLCBvYmplY3QpO1xuICAgIH0pO1xuICAgIHJldHVybiBsYXN0UHJvbWlzZTtcbiAgfVxuXG4gIHJldHVybiBPYmplY3QuZnJlZXplKHtcbiAgICBjcmVhdGUsXG4gICAgdXBkYXRlLFxuICB9KTtcbn1cblxuZnVuY3Rpb24gcmVzdFN0YXR1c0hhbmRsZXIoY2xhc3NOYW1lLCBjb25maWcpIHtcbiAgbGV0IGxhc3RQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIGNvbnN0IGF1dGggPSBBdXRoLm1hc3Rlcihjb25maWcpO1xuICBmdW5jdGlvbiBjcmVhdGUob2JqZWN0KSB7XG4gICAgbGFzdFByb21pc2UgPSBsYXN0UHJvbWlzZS50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiByZXN0LmNyZWF0ZShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgb2JqZWN0KS50aGVuKCh7IHJlc3BvbnNlIH0pID0+IHtcbiAgICAgICAgLy8gbWVyZ2UgdGhlIG9iamVjdHNcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShPYmplY3QuYXNzaWduKHt9LCBvYmplY3QsIHJlc3BvbnNlKSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICByZXR1cm4gbGFzdFByb21pc2U7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGUod2hlcmUsIG9iamVjdCkge1xuICAgIC8vIFRPRE86IHdoZW4gd2UgaGF2ZSB1cGRhdGVXaGVyZSwgdXNlIHRoYXQgZm9yIHByb3BlciBpbnRlcmZhY2luZ1xuICAgIGxhc3RQcm9taXNlID0gbGFzdFByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gcmVzdFxuICAgICAgICAudXBkYXRlKGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCB7IG9iamVjdElkOiB3aGVyZS5vYmplY3RJZCB9LCBvYmplY3QpXG4gICAgICAgIC50aGVuKCh7IHJlc3BvbnNlIH0pID0+IHtcbiAgICAgICAgICAvLyBtZXJnZSB0aGUgb2JqZWN0c1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoT2JqZWN0LmFzc2lnbih7fSwgb2JqZWN0LCByZXNwb25zZSkpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICByZXR1cm4gbGFzdFByb21pc2U7XG4gIH1cblxuICByZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG4gICAgY3JlYXRlLFxuICAgIHVwZGF0ZSxcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBqb2JTdGF0dXNIYW5kbGVyKGNvbmZpZykge1xuICBsZXQgam9iU3RhdHVzO1xuICBjb25zdCBvYmplY3RJZCA9IG5ld09iamVjdElkKGNvbmZpZy5vYmplY3RJZFNpemUpO1xuICBjb25zdCBkYXRhYmFzZSA9IGNvbmZpZy5kYXRhYmFzZTtcbiAgY29uc3QgaGFuZGxlciA9IHN0YXR1c0hhbmRsZXIoSk9CX1NUQVRVU19DT0xMRUNUSU9OLCBkYXRhYmFzZSk7XG4gIGNvbnN0IHNldFJ1bm5pbmcgPSBmdW5jdGlvbiAoam9iTmFtZSwgcGFyYW1zKSB7XG4gICAgY29uc3Qgbm93ID0gbmV3IERhdGUoKTtcbiAgICBqb2JTdGF0dXMgPSB7XG4gICAgICBvYmplY3RJZCxcbiAgICAgIGpvYk5hbWUsXG4gICAgICBwYXJhbXMsXG4gICAgICBzdGF0dXM6ICdydW5uaW5nJyxcbiAgICAgIHNvdXJjZTogJ2FwaScsXG4gICAgICBjcmVhdGVkQXQ6IG5vdyxcbiAgICAgIC8vIGxvY2tkb3duIVxuICAgICAgQUNMOiB7fSxcbiAgICB9O1xuXG4gICAgcmV0dXJuIGhhbmRsZXIuY3JlYXRlKGpvYlN0YXR1cyk7XG4gIH07XG5cbiAgY29uc3Qgc2V0TWVzc2FnZSA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgaWYgKCFtZXNzYWdlIHx8IHR5cGVvZiBtZXNzYWdlICE9PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICByZXR1cm4gaGFuZGxlci51cGRhdGUoeyBvYmplY3RJZCB9LCB7IG1lc3NhZ2UgfSk7XG4gIH07XG5cbiAgY29uc3Qgc2V0U3VjY2VlZGVkID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gc2V0RmluYWxTdGF0dXMoJ3N1Y2NlZWRlZCcsIG1lc3NhZ2UpO1xuICB9O1xuXG4gIGNvbnN0IHNldEZhaWxlZCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgcmV0dXJuIHNldEZpbmFsU3RhdHVzKCdmYWlsZWQnLCBtZXNzYWdlKTtcbiAgfTtcblxuICBjb25zdCBzZXRGaW5hbFN0YXR1cyA9IGZ1bmN0aW9uIChzdGF0dXMsIG1lc3NhZ2UgPSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBmaW5pc2hlZEF0ID0gbmV3IERhdGUoKTtcbiAgICBjb25zdCB1cGRhdGUgPSB7IHN0YXR1cywgZmluaXNoZWRBdCB9O1xuICAgIGlmIChtZXNzYWdlICYmIHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgICAgdXBkYXRlLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIH1cbiAgICBpZiAobWVzc2FnZSBpbnN0YW5jZW9mIEVycm9yICYmIHR5cGVvZiBtZXNzYWdlLm1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICB1cGRhdGUubWVzc2FnZSA9IG1lc3NhZ2UubWVzc2FnZTtcbiAgICB9XG4gICAgcmV0dXJuIGhhbmRsZXIudXBkYXRlKHsgb2JqZWN0SWQgfSwgdXBkYXRlKTtcbiAgfTtcblxuICByZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG4gICAgc2V0UnVubmluZyxcbiAgICBzZXRTdWNjZWVkZWQsXG4gICAgc2V0TWVzc2FnZSxcbiAgICBzZXRGYWlsZWQsXG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHVzaFN0YXR1c0hhbmRsZXIoY29uZmlnLCBleGlzdGluZ09iamVjdElkKSB7XG4gIGxldCBwdXNoU3RhdHVzO1xuICBjb25zdCBkYXRhYmFzZSA9IGNvbmZpZy5kYXRhYmFzZTtcbiAgY29uc3QgaGFuZGxlciA9IHJlc3RTdGF0dXNIYW5kbGVyKFBVU0hfU1RBVFVTX0NPTExFQ1RJT04sIGNvbmZpZyk7XG4gIGxldCBvYmplY3RJZCA9IGV4aXN0aW5nT2JqZWN0SWQ7XG4gIGNvbnN0IHNldEluaXRpYWwgPSBmdW5jdGlvbiAoYm9keSA9IHt9LCB3aGVyZSwgb3B0aW9ucyA9IHsgc291cmNlOiAncmVzdCcgfSkge1xuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgbGV0IHB1c2hUaW1lID0gbm93LnRvSVNPU3RyaW5nKCk7XG4gICAgbGV0IHN0YXR1cyA9ICdwZW5kaW5nJztcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGJvZHksICdwdXNoX3RpbWUnKSkge1xuICAgICAgaWYgKGNvbmZpZy5oYXNQdXNoU2NoZWR1bGVkU3VwcG9ydCkge1xuICAgICAgICBwdXNoVGltZSA9IGJvZHkucHVzaF90aW1lO1xuICAgICAgICBzdGF0dXMgPSAnc2NoZWR1bGVkJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdUcnlpbmcgdG8gc2NoZWR1bGUgYSBwdXNoIHdoaWxlIHNlcnZlciBpcyBub3QgY29uZmlndXJlZC4nKTtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1B1c2ggd2lsbCBiZSBzZW50IGltbWVkaWF0ZWx5Jyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YSA9IGJvZHkuZGF0YSB8fCB7fTtcbiAgICBjb25zdCBwYXlsb2FkU3RyaW5nID0gSlNPTi5zdHJpbmdpZnkoZGF0YSk7XG4gICAgbGV0IHB1c2hIYXNoO1xuICAgIGlmICh0eXBlb2YgZGF0YS5hbGVydCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHB1c2hIYXNoID0gbWQ1SGFzaChkYXRhLmFsZXJ0KTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLmFsZXJ0ID09PSAnb2JqZWN0Jykge1xuICAgICAgcHVzaEhhc2ggPSBtZDVIYXNoKEpTT04uc3RyaW5naWZ5KGRhdGEuYWxlcnQpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHVzaEhhc2ggPSAnZDQxZDhjZDk4ZjAwYjIwNGU5ODAwOTk4ZWNmODQyN2UnO1xuICAgIH1cbiAgICBjb25zdCBvYmplY3QgPSB7XG4gICAgICBwdXNoVGltZSxcbiAgICAgIHF1ZXJ5OiBKU09OLnN0cmluZ2lmeSh3aGVyZSksXG4gICAgICBwYXlsb2FkOiBwYXlsb2FkU3RyaW5nLFxuICAgICAgc291cmNlOiBvcHRpb25zLnNvdXJjZSxcbiAgICAgIHRpdGxlOiBvcHRpb25zLnRpdGxlLFxuICAgICAgZXhwaXJ5OiBib2R5LmV4cGlyYXRpb25fdGltZSxcbiAgICAgIGV4cGlyYXRpb25faW50ZXJ2YWw6IGJvZHkuZXhwaXJhdGlvbl9pbnRlcnZhbCxcbiAgICAgIHN0YXR1czogc3RhdHVzLFxuICAgICAgbnVtU2VudDogMCxcbiAgICAgIHB1c2hIYXNoLFxuICAgICAgLy8gbG9ja2Rvd24hXG4gICAgICBBQ0w6IHt9LFxuICAgIH07XG4gICAgcmV0dXJuIGhhbmRsZXIuY3JlYXRlKG9iamVjdCkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgb2JqZWN0SWQgPSByZXN1bHQub2JqZWN0SWQ7XG4gICAgICBwdXNoU3RhdHVzID0ge1xuICAgICAgICBvYmplY3RJZCxcbiAgICAgIH07XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHB1c2hTdGF0dXMpO1xuICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IHNldFJ1bm5pbmcgPSBmdW5jdGlvbiAoYmF0Y2hlcykge1xuICAgIGxvZ2dlci52ZXJib3NlKFxuICAgICAgYF9QdXNoU3RhdHVzICR7b2JqZWN0SWR9OiBzZW5kaW5nIHB1c2ggdG8gaW5zdGFsbGF0aW9ucyB3aXRoICVkIGJhdGNoZXNgLFxuICAgICAgYmF0Y2hlc1xuICAgICk7XG4gICAgcmV0dXJuIGhhbmRsZXIudXBkYXRlKFxuICAgICAge1xuICAgICAgICBzdGF0dXM6ICdwZW5kaW5nJyxcbiAgICAgICAgb2JqZWN0SWQ6IG9iamVjdElkLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgc3RhdHVzOiAncnVubmluZycsXG4gICAgICAgIGNvdW50OiBiYXRjaGVzLFxuICAgICAgfVxuICAgICk7XG4gIH07XG5cbiAgY29uc3QgdHJhY2tTZW50ID0gZnVuY3Rpb24gKFxuICAgIHJlc3VsdHMsXG4gICAgVVRDT2Zmc2V0LFxuICAgIGNsZWFudXBJbnN0YWxsYXRpb25zID0gcHJvY2Vzcy5lbnYuUEFSU0VfU0VSVkVSX0NMRUFOVVBfSU5WQUxJRF9JTlNUQUxMQVRJT05TXG4gICkge1xuICAgIGNvbnN0IHVwZGF0ZSA9IHtcbiAgICAgIG51bVNlbnQ6IDAsXG4gICAgICBudW1GYWlsZWQ6IDAsXG4gICAgfTtcbiAgICBjb25zdCBkZXZpY2VzVG9SZW1vdmUgPSBbXTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHRzKSkge1xuICAgICAgcmVzdWx0cyA9IGZsYXR0ZW4ocmVzdWx0cyk7XG4gICAgICByZXN1bHRzLnJlZHVjZSgobWVtbywgcmVzdWx0KSA9PiB7XG4gICAgICAgIC8vIENhbm5vdCBoYW5kbGUgdGhhdFxuICAgICAgICBpZiAoIXJlc3VsdCB8fCAhcmVzdWx0LmRldmljZSB8fCAhcmVzdWx0LmRldmljZS5kZXZpY2VUeXBlKSB7XG4gICAgICAgICAgcmV0dXJuIG1lbW87XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGV2aWNlVHlwZSA9IHJlc3VsdC5kZXZpY2UuZGV2aWNlVHlwZTtcbiAgICAgICAgY29uc3Qga2V5ID0gcmVzdWx0LnRyYW5zbWl0dGVkXG4gICAgICAgICAgPyBgc2VudFBlclR5cGUuJHtkZXZpY2VUeXBlfWBcbiAgICAgICAgICA6IGBmYWlsZWRQZXJUeXBlLiR7ZGV2aWNlVHlwZX1gO1xuICAgICAgICBtZW1vW2tleV0gPSBpbmNyZW1lbnRPcChtZW1vLCBrZXkpO1xuICAgICAgICBpZiAodHlwZW9mIFVUQ09mZnNldCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBjb25zdCBvZmZzZXRLZXkgPSByZXN1bHQudHJhbnNtaXR0ZWRcbiAgICAgICAgICAgID8gYHNlbnRQZXJVVENPZmZzZXQuJHtVVENPZmZzZXR9YFxuICAgICAgICAgICAgOiBgZmFpbGVkUGVyVVRDT2Zmc2V0LiR7VVRDT2Zmc2V0fWA7XG4gICAgICAgICAgbWVtb1tvZmZzZXRLZXldID0gaW5jcmVtZW50T3AobWVtbywgb2Zmc2V0S2V5KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzdWx0LnRyYW5zbWl0dGVkKSB7XG4gICAgICAgICAgbWVtby5udW1TZW50Kys7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgcmVzdWx0ICYmXG4gICAgICAgICAgICByZXN1bHQucmVzcG9uc2UgJiZcbiAgICAgICAgICAgIHJlc3VsdC5yZXNwb25zZS5lcnJvciAmJlxuICAgICAgICAgICAgcmVzdWx0LmRldmljZSAmJlxuICAgICAgICAgICAgcmVzdWx0LmRldmljZS5kZXZpY2VUb2tlblxuICAgICAgICAgICkge1xuICAgICAgICAgICAgY29uc3QgdG9rZW4gPSByZXN1bHQuZGV2aWNlLmRldmljZVRva2VuO1xuICAgICAgICAgICAgY29uc3QgZXJyb3IgPSByZXN1bHQucmVzcG9uc2UuZXJyb3I7XG4gICAgICAgICAgICAvLyBHQ00gZXJyb3JzXG4gICAgICAgICAgICBpZiAoZXJyb3IgPT09ICdOb3RSZWdpc3RlcmVkJyB8fCBlcnJvciA9PT0gJ0ludmFsaWRSZWdpc3RyYXRpb24nKSB7XG4gICAgICAgICAgICAgIGRldmljZXNUb1JlbW92ZS5wdXNoKHRva2VuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEFQTlMgZXJyb3JzXG4gICAgICAgICAgICBpZiAoZXJyb3IgPT09ICdVbnJlZ2lzdGVyZWQnIHx8IGVycm9yID09PSAnQmFkRGV2aWNlVG9rZW4nKSB7XG4gICAgICAgICAgICAgIGRldmljZXNUb1JlbW92ZS5wdXNoKHRva2VuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgbWVtby5udW1GYWlsZWQrKztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVtbztcbiAgICAgIH0sIHVwZGF0ZSk7XG4gICAgfVxuXG4gICAgbG9nZ2VyLnZlcmJvc2UoXG4gICAgICBgX1B1c2hTdGF0dXMgJHtvYmplY3RJZH06IHNlbnQgcHVzaCEgJWQgc3VjY2VzcywgJWQgZmFpbHVyZXNgLFxuICAgICAgdXBkYXRlLm51bVNlbnQsXG4gICAgICB1cGRhdGUubnVtRmFpbGVkXG4gICAgKTtcbiAgICBsb2dnZXIudmVyYm9zZShgX1B1c2hTdGF0dXMgJHtvYmplY3RJZH06IG5lZWRzIGNsZWFudXBgLCB7XG4gICAgICBkZXZpY2VzVG9SZW1vdmUsXG4gICAgfSk7XG4gICAgWydudW1TZW50JywgJ251bUZhaWxlZCddLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGlmICh1cGRhdGVba2V5XSA+IDApIHtcbiAgICAgICAgdXBkYXRlW2tleV0gPSB7XG4gICAgICAgICAgX19vcDogJ0luY3JlbWVudCcsXG4gICAgICAgICAgYW1vdW50OiB1cGRhdGVba2V5XSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlbGV0ZSB1cGRhdGVba2V5XTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChkZXZpY2VzVG9SZW1vdmUubGVuZ3RoID4gMCAmJiBjbGVhbnVwSW5zdGFsbGF0aW9ucykge1xuICAgICAgbG9nZ2VyLmluZm8oYFJlbW92aW5nIGRldmljZSB0b2tlbnMgb24gJHtkZXZpY2VzVG9SZW1vdmUubGVuZ3RofSBfSW5zdGFsbGF0aW9uc2ApO1xuICAgICAgZGF0YWJhc2UudXBkYXRlKFxuICAgICAgICAnX0luc3RhbGxhdGlvbicsXG4gICAgICAgIHsgZGV2aWNlVG9rZW46IHsgJGluOiBkZXZpY2VzVG9SZW1vdmUgfSB9LFxuICAgICAgICB7IGRldmljZVRva2VuOiB7IF9fb3A6ICdEZWxldGUnIH0gfSxcbiAgICAgICAge1xuICAgICAgICAgIGFjbDogdW5kZWZpbmVkLFxuICAgICAgICAgIG1hbnk6IHRydWUsXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gaW5kaWNhdGUgdGhpcyBiYXRjaCBpcyBjb21wbGV0ZVxuICAgIGluY3JlbWVudE9wKHVwZGF0ZSwgJ2NvdW50JywgLTEpO1xuXG4gICAgcmV0dXJuIGhhbmRsZXIudXBkYXRlKHsgb2JqZWN0SWQgfSwgdXBkYXRlKS50aGVuKHJlcyA9PiB7XG4gICAgICBpZiAocmVzICYmIHJlcy5jb3VudCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb21wbGV0ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IGNvbXBsZXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBoYW5kbGVyLnVwZGF0ZShcbiAgICAgIHsgb2JqZWN0SWQgfSxcbiAgICAgIHtcbiAgICAgICAgc3RhdHVzOiAnc3VjY2VlZGVkJyxcbiAgICAgICAgY291bnQ6IHsgX19vcDogJ0RlbGV0ZScgfSxcbiAgICAgIH1cbiAgICApO1xuICB9O1xuXG4gIGNvbnN0IGZhaWwgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgaWYgKHR5cGVvZiBlcnIgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlcnIgPSB7IG1lc3NhZ2U6IGVyciB9O1xuICAgIH1cbiAgICBjb25zdCB1cGRhdGUgPSB7XG4gICAgICBlcnJvck1lc3NhZ2U6IGVycixcbiAgICAgIHN0YXR1czogJ2ZhaWxlZCcsXG4gICAgfTtcbiAgICByZXR1cm4gaGFuZGxlci51cGRhdGUoeyBvYmplY3RJZCB9LCB1cGRhdGUpO1xuICB9O1xuXG4gIGNvbnN0IHJ2YWwgPSB7XG4gICAgc2V0SW5pdGlhbCxcbiAgICBzZXRSdW5uaW5nLFxuICAgIHRyYWNrU2VudCxcbiAgICBjb21wbGV0ZSxcbiAgICBmYWlsLFxuICB9O1xuXG4gIC8vIGRlZmluZSBvYmplY3RJZCB0byBiZSBkeW5hbWljXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShydmFsLCAnb2JqZWN0SWQnLCB7XG4gICAgZ2V0OiAoKSA9PiBvYmplY3RJZCxcbiAgfSk7XG5cbiAgcmV0dXJuIE9iamVjdC5mcmVlemUocnZhbCk7XG59XG4iXX0= \ No newline at end of file diff --git a/lib/TestUtils.js b/lib/TestUtils.js new file mode 100644 index 0000000000..9aaccbe172 --- /dev/null +++ b/lib/TestUtils.js @@ -0,0 +1,31 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.destroyAllDataPermanently = destroyAllDataPermanently; + +var _cache = _interopRequireDefault(require("./cache")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Destroys all data in the database + * @param {boolean} fast set to true if it's ok to just drop objects and not indexes. + */ +function destroyAllDataPermanently(fast) { + if (!process.env.TESTING) { + throw 'Only supported in test environment'; + } + + return Promise.all(Object.keys(_cache.default.cache).map(appId => { + const app = _cache.default.get(appId); + + if (app.databaseController) { + return app.databaseController.deleteEverything(fast); + } else { + return Promise.resolve(); + } + })); +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9UZXN0VXRpbHMuanMiXSwibmFtZXMiOlsiZGVzdHJveUFsbERhdGFQZXJtYW5lbnRseSIsImZhc3QiLCJwcm9jZXNzIiwiZW52IiwiVEVTVElORyIsIlByb21pc2UiLCJhbGwiLCJPYmplY3QiLCJrZXlzIiwiQXBwQ2FjaGUiLCJjYWNoZSIsIm1hcCIsImFwcElkIiwiYXBwIiwiZ2V0IiwiZGF0YWJhc2VDb250cm9sbGVyIiwiZGVsZXRlRXZlcnl0aGluZyIsInJlc29sdmUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7OztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0EseUJBQVQsQ0FBbUNDLElBQW5DLEVBQXlDO0FBQzlDLE1BQUksQ0FBQ0MsT0FBTyxDQUFDQyxHQUFSLENBQVlDLE9BQWpCLEVBQTBCO0FBQ3hCLFVBQU0sb0NBQU47QUFDRDs7QUFDRCxTQUFPQyxPQUFPLENBQUNDLEdBQVIsQ0FDTEMsTUFBTSxDQUFDQyxJQUFQLENBQVlDLGVBQVNDLEtBQXJCLEVBQTRCQyxHQUE1QixDQUFnQ0MsS0FBSyxJQUFJO0FBQ3ZDLFVBQU1DLEdBQUcsR0FBR0osZUFBU0ssR0FBVCxDQUFhRixLQUFiLENBQVo7O0FBQ0EsUUFBSUMsR0FBRyxDQUFDRSxrQkFBUixFQUE0QjtBQUMxQixhQUFPRixHQUFHLENBQUNFLGtCQUFKLENBQXVCQyxnQkFBdkIsQ0FBd0NmLElBQXhDLENBQVA7QUFDRCxLQUZELE1BRU87QUFDTCxhQUFPSSxPQUFPLENBQUNZLE9BQVIsRUFBUDtBQUNEO0FBQ0YsR0FQRCxDQURLLENBQVA7QUFVRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBBcHBDYWNoZSBmcm9tICcuL2NhY2hlJztcblxuLyoqXG4gKiBEZXN0cm95cyBhbGwgZGF0YSBpbiB0aGUgZGF0YWJhc2VcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gZmFzdCBzZXQgdG8gdHJ1ZSBpZiBpdCdzIG9rIHRvIGp1c3QgZHJvcCBvYmplY3RzIGFuZCBub3QgaW5kZXhlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlc3Ryb3lBbGxEYXRhUGVybWFuZW50bHkoZmFzdCkge1xuICBpZiAoIXByb2Nlc3MuZW52LlRFU1RJTkcpIHtcbiAgICB0aHJvdyAnT25seSBzdXBwb3J0ZWQgaW4gdGVzdCBlbnZpcm9ubWVudCc7XG4gIH1cbiAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgIE9iamVjdC5rZXlzKEFwcENhY2hlLmNhY2hlKS5tYXAoYXBwSWQgPT4ge1xuICAgICAgY29uc3QgYXBwID0gQXBwQ2FjaGUuZ2V0KGFwcElkKTtcbiAgICAgIGlmIChhcHAuZGF0YWJhc2VDb250cm9sbGVyKSB7XG4gICAgICAgIHJldHVybiBhcHAuZGF0YWJhc2VDb250cm9sbGVyLmRlbGV0ZUV2ZXJ5dGhpbmcoZmFzdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfSlcbiAgKTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Utils.js b/lib/Utils.js new file mode 100644 index 0000000000..387a6e5564 --- /dev/null +++ b/lib/Utils.js @@ -0,0 +1,139 @@ +"use strict"; + +/** + * utils.js + * @file General purpose utilities + * @description General purpose utilities. + */ +const path = require('path'); + +const fs = require('fs').promises; +/** + * The general purpose utilities. + */ + + +class Utils { + /** + * @function getLocalizedPath + * @description Returns a localized file path accoring to the locale. + * + * Localized files are searched in subfolders of a given path, e.g. + * + * root/ + * ├── base/ // base path to files + * │ ├── example.html // default file + * │ └── de/ // de language folder + * │ │ └── example.html // de localized file + * │ └── de-AT/ // de-AT locale folder + * │ │ └── example.html // de-AT localized file + * + * Files are matched with the locale in the following order: + * 1. Locale match, e.g. locale `de-AT` matches file in folder `de-AT`. + * 2. Language match, e.g. locale `de-AT` matches file in folder `de`. + * 3. Default; file in base folder is returned. + * + * @param {String} defaultPath The absolute file path, which is also + * the default path returned if localization is not available. + * @param {String} locale The locale. + * @returns {Promise} The object contains: + * - `path`: The path to the localized file, or the original path if + * localization is not available. + * - `subdir`: The subdirectory of the localized file, or undefined if + * there is no matching localized file. + */ + static async getLocalizedPath(defaultPath, locale) { + // Get file name and paths + const file = path.basename(defaultPath); + const basePath = path.dirname(defaultPath); // If locale is not set return default file + + if (!locale) { + return { + path: defaultPath + }; + } // Check file for locale exists + + + const localePath = path.join(basePath, locale, file); + const localeFileExists = await Utils.fileExists(localePath); // If file for locale exists return file + + if (localeFileExists) { + return { + path: localePath, + subdir: locale + }; + } // Check file for language exists + + + const language = locale.split('-')[0]; + const languagePath = path.join(basePath, language, file); + const languageFileExists = await Utils.fileExists(languagePath); // If file for language exists return file + + if (languageFileExists) { + return { + path: languagePath, + subdir: language + }; + } // Return default file + + + return { + path: defaultPath + }; + } + /** + * @function fileExists + * @description Checks whether a file exists. + * @param {String} path The file path. + * @returns {Promise} Is true if the file can be accessed, false otherwise. + */ + + + static async fileExists(path) { + try { + await fs.access(path); + return true; + } catch (e) { + return false; + } + } + /** + * @function isPath + * @description Evaluates whether a string is a file path (as opposed to a URL for example). + * @param {String} s The string to evaluate. + * @returns {Boolean} Returns true if the evaluated string is a path. + */ + + + static isPath(s) { + return /(^\/)|(^\.\/)|(^\.\.\/)/.test(s); + } + /** + * Flattens an object and crates new keys with custom delimiters. + * @param {Object} obj The object to flatten. + * @param {String} [delimiter='.'] The delimiter of the newly generated keys. + * @param {Object} result + * @returns {Object} The flattened object. + **/ + + + static flattenObject(obj, parentKey, delimiter = '.', result = {}) { + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + const newKey = parentKey ? parentKey + delimiter + key : key; + + if (typeof obj[key] === 'object' && obj[key] !== null) { + this.flattenObject(obj[key], newKey, delimiter, result); + } else { + result[newKey] = obj[key]; + } + } + } + + return result; + } + +} + +module.exports = Utils; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9VdGlscy5qcyJdLCJuYW1lcyI6WyJwYXRoIiwicmVxdWlyZSIsImZzIiwicHJvbWlzZXMiLCJVdGlscyIsImdldExvY2FsaXplZFBhdGgiLCJkZWZhdWx0UGF0aCIsImxvY2FsZSIsImZpbGUiLCJiYXNlbmFtZSIsImJhc2VQYXRoIiwiZGlybmFtZSIsImxvY2FsZVBhdGgiLCJqb2luIiwibG9jYWxlRmlsZUV4aXN0cyIsImZpbGVFeGlzdHMiLCJzdWJkaXIiLCJsYW5ndWFnZSIsInNwbGl0IiwibGFuZ3VhZ2VQYXRoIiwibGFuZ3VhZ2VGaWxlRXhpc3RzIiwiYWNjZXNzIiwiZSIsImlzUGF0aCIsInMiLCJ0ZXN0IiwiZmxhdHRlbk9iamVjdCIsIm9iaiIsInBhcmVudEtleSIsImRlbGltaXRlciIsInJlc3VsdCIsImtleSIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIm5ld0tleSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBLE1BQU1BLElBQUksR0FBR0MsT0FBTyxDQUFDLE1BQUQsQ0FBcEI7O0FBQ0EsTUFBTUMsRUFBRSxHQUFHRCxPQUFPLENBQUMsSUFBRCxDQUFQLENBQWNFLFFBQXpCO0FBRUE7QUFDQTtBQUNBOzs7QUFDQSxNQUFNQyxLQUFOLENBQVk7QUFDVjtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNFLGVBQWFDLGdCQUFiLENBQThCQyxXQUE5QixFQUEyQ0MsTUFBM0MsRUFBbUQ7QUFDakQ7QUFDQSxVQUFNQyxJQUFJLEdBQUdSLElBQUksQ0FBQ1MsUUFBTCxDQUFjSCxXQUFkLENBQWI7QUFDQSxVQUFNSSxRQUFRLEdB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dXJjZXNDb250ZW50IjpbIi8qKlxuICogdXRpbHMuanNcbiAqIEBmaWxlIEdlbmVyYWwgcHVycG9zZSB1dGlsaXRpZXNcbiAqIEBkZXNjcmlwdGlvbiBHZW5lcmFsIHB1cnBvc2UgdXRpbGl0aWVzLlxuICovXG5cbmNvbnN0IHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG5jb25zdCBmcyA9IHJlcXVpcmUoJ2ZzJykucHJvbWlzZXM7XG5cbi8qKlxuICogVGhlIGdlbmVyYWwgcHVycG9zZSB1dGlsaXRpZXMuXG4gKi9cbmNsYXNzIFV0aWxzIHtcbiAgLyoqXG4gICAqIEBmdW5jdGlvbiBnZXRMb2NhbGl6ZWRQYXRoXG4gICAqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIGEgbG9jYWxpemVkIGZpbGUgcGF0aCBhY2NvcmluZyB0byB0aGUgbG9jYWxlLlxuICAgKlxuICAgKiBMb2NhbGl6ZWQgZmlsZXMgYXJlIHNlYXJjaGVkIGluIHN1YmZvbGRlcnMgb2YgYSBnaXZlbiBwYXRoLCBlLmcuXG4gICAqXG4gICAqIHJvb3QvXG4gICAqIOKUnOKUgOKUgCBiYXNlLyAgICAgICAgICAgICAgICAgICAgLy8gYmFzZSBwYXRoIHRvIGZpbGVzXG4gICAqIOKUgiAgIOKUnOKUgOKUgCBleGFtcGxlLmh0bWwgICAgICAgICAvLyBkZWZhdWx0IGZpbGVcbiAgICog4pSCICAg4pSU4pSA4pSAIGRlLyAgICAgICAgICAgICAgICAgIC8vIGRlIGxhbmd1YWdlIGZvbGRlclxuICAgKiDilIIgICDilIIgICDilJTilIDilIAgZXhhbXBsZS5odG1sICAgICAvLyBkZSBsb2NhbGl6ZWQgZmlsZVxuICAgKiDilIIgICDilJTilIDilIAgZGUtQVQvICAgICAgICAgICAgICAgLy8gZGUtQVQgbG9jYWxlIGZvbGRlclxuICAgKiDilIIgICDilIIgICDilJTilIDilIAgZXhhbXBsZS5odG1sICAgICAvLyBkZS1BVCBsb2NhbGl6ZWQgZmlsZVxuICAgKlxuICAgKiBGaWxlcyBhcmUgbWF0Y2hlZCB3aXRoIHRoZSBsb2NhbGUgaW4gdGhlIGZvbGxvd2luZyBvcmRlcjpcbiAgICogMS4gTG9jYWxlIG1hdGNoLCBlLmcuIGxvY2FsZSBgZGUtQVRgIG1hdGNoZXMgZmlsZSBpbiBmb2xkZXIgYGRlLUFUYC5cbiAgICogMi4gTGFuZ3VhZ2UgbWF0Y2gsIGUuZy4gbG9jYWxlIGBkZS1BVGAgbWF0Y2hlcyBmaWxlIGluIGZvbGRlciBgZGVgLlxuICAgKiAzLiBEZWZhdWx0OyBmaWxlIGluIGJhc2UgZm9sZGVyIGlzIHJldHVybmVkLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gZGVmYXVsdFBhdGggVGhlIGFic29sdXRlIGZpbGUgcGF0aCwgd2hpY2ggaXMgYWxzb1xuICAgKiB0aGUgZGVmYXVsdCBwYXRoIHJldHVybmVkIGlmIGxvY2FsaXphdGlvbiBpcyBub3QgYXZhaWxhYmxlLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbG9jYWxlIFRoZSBsb2NhbGUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPE9iamVjdD59IFRoZSBvYmplY3QgY29udGFpbnM6XG4gICAqIC0gYHBhdGhgOiBUaGUgcGF0aCB0byB0aGUgbG9jYWxpemVkIGZpbGUsIG9yIHRoZSBvcmlnaW5hbCBwYXRoIGlmXG4gICAqICAgbG9jYWxpemF0aW9uIGlzIG5vdCBhdmFpbGFibGUuXG4gICAqIC0gYHN1YmRpcmA6IFRoZSBzdWJkaXJlY3Rvcnkgb2YgdGhlIGxvY2FsaXplZCBmaWxlLCBvciB1bmRlZmluZWQgaWZcbiAgICogICB0aGVyZSBpcyBubyBtYXRjaGluZyBsb2NhbGl6ZWQgZmlsZS5cbiAgICovXG4gIHN0YXRpYyBhc3luYyBnZXRMb2NhbGl6ZWRQYXRoKGRlZmF1bHRQYXRoLCBsb2NhbGUpIHtcbiAgICAvLyBHZXQgZmlsZSBuYW1lIGFuZCBwYXRoc1xuICAgIGNvbnN0IGZpbGUgPSBwYXRoLmJhc2VuYW1lKGRlZmF1bHRQYXRoKTtcbiAgICBjb25zdCBiYXNlUGF0aCA9IHBhdGguZGlybmFtZShkZWZhdWx0UGF0aCk7XG5cbiAgICAvLyBJZiBsb2NhbGUgaXMgbm90IHNldCByZXR1cm4gZGVmYXVsdCBmaWxlXG4gICAgaWYgKCFsb2NhbGUpIHtcbiAgICAgIHJldHVybiB7IHBhdGg6IGRlZmF1bHRQYXRoIH07XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZmlsZSBmb3IgbG9jYWxlIGV4aXN0c1xuICAgIGNvbnN0IGxvY2FsZVBhdGggPSBwYXRoLmpvaW4oYmFzZVBhdGgsIGxvY2FsZSwgZmlsZSk7XG4gICAgY29uc3QgbG9jYWxlRmlsZUV4aXN0cyA9IGF3YWl0IFV0aWxzLmZpbGVFeGlzdHMobG9jYWxlUGF0aCk7XG5cbiAgICAvLyBJZiBmaWxlIGZvciBsb2NhbGUgZXhpc3RzIHJldHVybiBmaWxlXG4gICAgaWYgKGxvY2FsZUZpbGVFeGlzdHMpIHtcbiAgICAgIHJldHVybiB7IHBhdGg6IGxvY2FsZVBhdGgsIHN1YmRpcjogbG9jYWxlIH07XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZmlsZSBmb3IgbGFuZ3VhZ2UgZXhpc3RzXG4gICAgY29uc3QgbGFuZ3VhZ2UgPSBsb2NhbGUuc3BsaXQoJy0nKVswXTtcbiAgICBjb25zdCBsYW5ndWFnZVBhdGggPSBwYXRoLmpvaW4oYmFzZVBhdGgsIGxhbmd1YWdlLCBmaWxlKTtcbiAgICBjb25zdCBsYW5ndWFnZUZpbGVFeGlzdHMgPSBhd2FpdCBVdGlscy5maWxlRXhpc3RzKGxhbmd1YWdlUGF0aCk7XG5cbiAgICAvLyBJZiBmaWxlIGZvciBsYW5ndWFnZSBleGlzdHMgcmV0dXJuIGZpbGVcbiAgICBpZiAobGFuZ3VhZ2VGaWxlRXhpc3RzKSB7XG4gICAgICByZXR1cm4geyBwYXRoOiBsYW5ndWFnZVBhdGgsIHN1YmRpcjogbGFuZ3VhZ2UgfTtcbiAgICB9XG5cbiAgICAvLyBSZXR1cm4gZGVmYXVsdCBmaWxlXG4gICAgcmV0dXJuIHsgcGF0aDogZGVmYXVsdFBhdGggfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZnVuY3Rpb24gZmlsZUV4aXN0c1xuICAgKiBAZGVzY3JpcHRpb24gQ2hlY2tzIHdoZXRoZXIgYSBmaWxlIGV4aXN0cy5cbiAgICogQHBhcmFtIHtTdHJpbmd9IHBhdGggVGhlIGZpbGUgcGF0aC5cbiAgICogQHJldHVybnMge1Byb21pc2U8Qm9vbGVhbj59IElzIHRydWUgaWYgdGhlIGZpbGUgY2FuIGJlIGFjY2Vzc2VkLCBmYWxzZSBvdGhlcndpc2UuXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgZmlsZUV4aXN0cyhwYXRoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGZzLmFjY2VzcyhwYXRoKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGZ1bmN0aW9uIGlzUGF0aFxuICAgKiBAZGVzY3JpcHRpb24gRXZhbHVhdGVzIHdoZXRoZXIgYSBzdHJpbmcgaXMgYSBmaWxlIHBhdGggKGFzIG9wcG9zZWQgdG8gYSBVUkwgZm9yIGV4YW1wbGUpLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gcyBUaGUgc3RyaW5nIHRvIGV2YWx1YXRlLlxuICAgKiBAcmV0dXJucyB7Qm9vbGVhbn0gUmV0dXJucyB0cnVlIGlmIHRoZSBldmFsdWF0ZWQgc3RyaW5nIGlzIGEgcGF0aC5cbiAgICovXG4gIHN0YXRpYyBpc1BhdGgocykge1xuICAgIHJldHVybiAvKF5cXC8pfCheXFwuXFwvKXwoXlxcLlxcLlxcLykvLnRlc3Qocyk7XG4gIH1cblxuICAvKipcbiAgICogRmxhdHRlbnMgYW4gb2JqZWN0IGFuZCBjcmF0ZXMgbmV3IGtleXMgd2l0aCBjdXN0b20gZGVsaW1pdGVycy5cbiAgICogQHBhcmFtIHtPYmplY3R9IG9iaiBUaGUgb2JqZWN0IHRvIGZsYXR0ZW4uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbZGVsaW1pdGVyPScuJ10gVGhlIGRlbGltaXRlciBvZiB0aGUgbmV3bHkgZ2VuZXJhdGVkIGtleXMuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSByZXN1bHRcbiAgICogQHJldHVybnMge09iamVjdH0gVGhlIGZsYXR0ZW5lZCBvYmplY3QuXG4gICAqKi9cbiAgc3RhdGljIGZsYXR0ZW5PYmplY3Qob2JqLCBwYXJlbnRLZXksIGRlbGltaXRlciA9ICcuJywgcmVzdWx0ID0ge30pIHtcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBvYmopIHtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSB7XG4gICAgICAgIGNvbnN0IG5ld0tleSA9IHBhcmVudEtleSA/IHBhcmVudEtleSArIGRlbGltaXRlciArIGtleSA6IGtleTtcblxuICAgICAgICBpZiAodHlwZW9mIG9ialtrZXldID09PSAnb2JqZWN0JyAmJiBvYmpba2V5XSAhPT0gbnVsbCkge1xuICAgICAgICAgIHRoaXMuZmxhdHRlbk9iamVjdChvYmpba2V5XSwgbmV3S2V5LCBkZWxpbWl0ZXIsIHJlc3VsdCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdWx0W25ld0tleV0gPSBvYmpba2V5XTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gVXRpbHM7XG4iXX0= \ No newline at end of file diff --git a/lib/batch.js b/lib/batch.js new file mode 100644 index 0000000000..1e8ede10ab --- /dev/null +++ b/lib/batch.js @@ -0,0 +1,135 @@ +"use strict"; + +const Parse = require('parse/node').Parse; + +const url = require('url'); + +const path = require('path'); // These methods handle batch requests. + + +const batchPath = '/batch'; // Mounts a batch-handler onto a PromiseRouter. + +function mountOnto(router) { + router.route('POST', batchPath, req => { + return handleBatch(router, req); + }); +} + +function parseURL(URL) { + if (typeof URL === 'string') { + return url.parse(URL); + } + + return undefined; +} + +function makeBatchRoutingPathFunction(originalUrl, serverURL, publicServerURL) { + serverURL = serverURL ? parseURL(serverURL) : undefined; + publicServerURL = publicServerURL ? parseURL(publicServerURL) : undefined; + const apiPrefixLength = originalUrl.length - batchPath.length; + let apiPrefix = originalUrl.slice(0, apiPrefixLength); + + const makeRoutablePath = function (requestPath) { + // The routablePath is the path minus the api prefix + if (requestPath.slice(0, apiPrefix.length) != apiPrefix) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'cannot route batch path ' + requestPath); + } + + return path.posix.join('/', requestPath.slice(apiPrefix.length)); + }; + + if (serverURL && publicServerURL && serverURL.path != publicServerURL.path) { + const localPath = serverURL.path; + const publicPath = publicServerURL.path; // Override the api prefix + + apiPrefix = localPath; + return function (requestPath) { + // Figure out which server url was used by figuring out which + // path more closely matches requestPath + const startsWithLocal = requestPath.startsWith(localPath); + const startsWithPublic = requestPath.startsWith(publicPath); + const pathLengthToUse = startsWithLocal && startsWithPublic ? Math.max(localPath.length, publicPath.length) : startsWithLocal ? localPath.length : publicPath.length; + const newPath = path.posix.join('/', localPath, '/', requestPath.slice(pathLengthToUse)); // Use the method for local routing + + return makeRoutablePath(newPath); + }; + } + + return makeRoutablePath; +} // Returns a promise for a {response} object. +// TODO: pass along auth correctly + + +function handleBatch(router, req) { + if (!Array.isArray(req.body.requests)) { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'requests must be an array'); + } // The batch paths are all from the root of our domain. + // That means they include the API prefix, that the API is mounted + // to. However, our promise router does not route the api prefix. So + // we need to figure out the API prefix, so that we can strip it + // from all the subrequests. + + + if (!req.originalUrl.endsWith(batchPath)) { + throw 'internal routing problem - expected url to end with batch'; + } + + const makeRoutablePath = makeBatchRoutingPathFunction(req.originalUrl, req.config.serverURL, req.config.publicServerURL); + let initialPromise = Promise.resolve(); + + if (req.body.transaction === true) { + initialPromise = req.config.database.createTransactionalSession(); + } + + return initialPromise.then(() => { + const promises = req.body.requests.map(restRequest => { + const routablePath = makeRoutablePath(restRequest.path); // Construct a request that we can send to a handler + + const request = { + body: restRequest.body, + config: req.config, + auth: req.auth, + info: req.info + }; + return router.tryRouteRequest(restRequest.method, routablePath, request).then(response => { + return { + success: response.response + }; + }, error => { + return { + error: { + code: error.code, + error: error.message + } + }; + }); + }); + return Promise.all(promises).then(results => { + if (req.body.transaction === true) { + if (results.find(result => typeof result.error === 'object')) { + return req.config.database.abortTransactionalSession().then(() => { + return Promise.reject({ + response: results + }); + }); + } else { + return req.config.database.commitTransactionalSession().then(() => { + return { + response: results + }; + }); + } + } else { + return { + response: results + }; + } + }); + }); +} + +module.exports = { + mountOnto, + makeBatchRoutingPathFunction +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9iYXRjaC5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJ1cmwiLCJwYXRoIiwiYmF0Y2hQYXRoIiwibW91bnRPbnRvIiwicm91dGVyIiwicm91dGUiLCJyZXEiLCJoYW5kbGVCYXRjaCIsInBhcnNlVVJMIiwiVVJMIiwicGFyc2UiLCJ1bmRlZmluZWQiLCJtYWtlQmF0Y2hSb3V0aW5nUGF0aEZ1bmN0aW9uIiwib3JpZ2luYWxVcmwiLCJzZXJ2ZXJVUkwiLCJwdWJsaWNTZXJ2ZXJVUkwiLCJhcGlQcmVmaXhMZW5ndGgiLCJsZW5ndGgiLCJhcGlQcmVmaXgiLCJzbGljZSIsIm1ha2VSb3V0YWJsZVBhdGgiLCJyZXF1ZXN0UGF0aCIsIkVycm9yIiwiSU5WQUxJRF9KU09OIiwicG9zaXgiLCJqb2luIiwibG9jYWxQYXRoIiwicHVibGljUGF0aCIsInN0YXJ0c1dpdGhMb2NhbCIsInN0YXJ0c1dpdGgiLCJzdGFydHNXaXRoUHVibGljIiwicGF0aExlbmd0aFRvVXNlIiwiTWF0aCIsIm1heCIsIm5ld1BhdGgiLCJBcnJheSIsImlzQXJyYXkiLCJib2R5IiwicmVxdWVzdHMiLCJlbmRzV2l0aCIsImNvbmZpZyIsImluaXRpYWxQcm9taXNlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ0cmFuc2FjdGlvbiIsImRhdGFiYXNlIiwiY3JlYXRlVHJhbnNhY3Rpb25hbFNlc3Npb24iLCJ0aGVuIiwicHJvbWlzZXMiLCJtYXAiLCJyZXN0UmVxdWVzdCIsInJvdXRhYmxlUGF0aCIsInJlcXVlc3QiLCJhdXRoIiwiaW5mbyIsInRyeVJvdXRlUmVxdWVzdCIsIm1ldGhvZCIsInJlc3BvbnNlIiwic3VjY2VzcyIsImVycm9yIiwiY29kZSIsIm1lc3NhZ2UiLCJhbGwiLCJyZXN1bHRzIiwiZmluZCIsInJlc3VsdCIsImFib3J0VHJhbnNhY3Rpb25hbFNlc3Npb24iLCJyZWplY3QiLCJjb21taXRUcmFuc2FjdGlvbmFsU2Vzc2lvbiIsIm1vZHVsZSIsImV4cG9y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RCxHQUFHLENBQUNrQyxNQUFKLENBQVdLLFFBQVgsQ0FBb0JxQix5QkFBcEIsR0FBZ0RuQixJQUFoRCxDQUFxRCxNQUFNO0FBQ2hFLG1CQUFPTCxPQUFPLENBQUN5QixNQUFSLENBQWU7QUFBRVYsY0FBQUEsUUFBUSxFQUFFTTtBQUFaLGFBQWYsQ0FBUDtBQUNELFdBRk0sQ0FBUDtBQUdELFNBSkQsTUFJTztBQUNMLGlCQUFPekQsR0FBRyxDQUFDa0MsTUFBSixDQUFXSyxRQUFYLENBQW9CdUIsMEJBQXBCLEdBQWlEckIsSUFBakQsQ0FBc0QsTUFBTTtBQUNqRSxtQkFBTztBQUFFVSxjQUFBQSxRQUFRLEVBQUVNO0FBQVosYUFBUDtBQUNELFdBRk0sQ0FBUDtBQUdEO0FBQ0YsT0FWRCxNQVVPO0FBQ0wsZUFBTztBQUFFTixVQUFBQSxRQUFRLEVBQUVNO0FBQVosU0FBUDtBQUNEO0FBQ0YsS0FkTSxDQUFQO0FBZUQsR0FyQ00sQ0FBUDtBQXNDRDs7QUFFRE0sTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZuRSxFQUFBQSxTQURlO0FBRWZTLEVBQUFBO0FBRmUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IHVybCA9IHJlcXVpcmUoJ3VybCcpO1xuY29uc3QgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcbi8vIFRoZXNlIG1ldGhvZHMgaGFuZGxlIGJhdGNoIHJlcXVlc3RzLlxuY29uc3QgYmF0Y2hQYXRoID0gJy9iYXRjaCc7XG5cbi8vIE1vdW50cyBhIGJhdGNoLWhhbmRsZXIgb250byBhIFByb21pc2VSb3V0ZXIuXG5mdW5jdGlvbiBtb3VudE9udG8ocm91dGVyKSB7XG4gIHJvdXRlci5yb3V0ZSgnUE9TVCcsIGJhdGNoUGF0aCwgcmVxID0+IHtcbiAgICByZXR1cm4gaGFuZGxlQmF0Y2gocm91dGVyLCByZXEpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gcGFyc2VVUkwoVVJMKSB7XG4gIGlmICh0eXBlb2YgVVJMID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB1cmwucGFyc2UoVVJMKTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBtYWtlQmF0Y2hSb3V0aW5nUGF0aEZ1bmN0aW9uKG9yaWdpbmFsVXJsLCBzZXJ2ZXJVUkwsIHB1YmxpY1NlcnZlclVSTCkge1xuICBzZXJ2ZXJVUkwgPSBzZXJ2ZXJVUkwgPyBwYXJzZVVSTChzZXJ2ZXJVUkwpIDogdW5kZWZpbmVkO1xuICBwdWJsaWNTZXJ2ZXJVUkwgPSBwdWJsaWNTZXJ2ZXJVUkwgPyBwYXJzZVVSTChwdWJsaWNTZXJ2ZXJVUkwpIDogdW5kZWZpbmVkO1xuXG4gIGNvbnN0IGFwaVByZWZpeExlbmd0aCA9IG9yaWdpbmFsVXJsLmxlbmd0aCAtIGJhdGNoUGF0aC5sZW5ndGg7XG4gIGxldCBhcGlQcmVmaXggPSBvcmlnaW5hbFVybC5zbGljZSgwLCBhcGlQcmVmaXhMZW5ndGgpO1xuXG4gIGNvbnN0IG1ha2VSb3V0YWJsZVBhdGggPSBmdW5jdGlvbiAocmVxdWVzdFBhdGgpIHtcbiAgICAvLyBUaGUgcm91dGFibGVQYXRoIGlzIHRoZSBwYXRoIG1pbnVzIHRoZSBhcGkgcHJlZml4XG4gICAgaWYgKHJlcXVlc3RQYXRoLnNsaWNlKDAsIGFwaVByZWZpeC5sZW5ndGgpICE9IGFwaVByZWZpeCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2Nhbm5vdCByb3V0ZSBiYXRjaCBwYXRoICcgKyByZXF1ZXN0UGF0aCk7XG4gICAgfVxuICAgIHJldHVybiBwYXRoLnBvc2l4LmpvaW4oJy8nLCByZXF1ZXN0UGF0aC5zbGljZShhcGlQcmVmaXgubGVuZ3RoKSk7XG4gIH07XG5cbiAgaWYgKHNlcnZlclVSTCAmJiBwdWJsaWNTZXJ2ZXJVUkwgJiYgc2VydmVyVVJMLnBhdGggIT0gcHVibGljU2VydmVyVVJMLnBhdGgpIHtcbiAgICBjb25zdCBsb2NhbFBhdGggPSBzZXJ2ZXJVUkwucGF0aDtcbiAgICBjb25zdCBwdWJsaWNQYXRoID0gcHVibGljU2VydmVyVVJMLnBhdGg7XG5cbiAgICAvLyBPdmVycmlkZSB0aGUgYXBpIHByZWZpeFxuICAgIGFwaVByZWZpeCA9IGxvY2FsUGF0aDtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHJlcXVlc3RQYXRoKSB7XG4gICAgICAvLyBGaWd1cmUgb3V0IHdoaWNoIHNlcnZlciB1cmwgd2FzIHVzZWQgYnkgZmlndXJpbmcgb3V0IHdoaWNoXG4gICAgICAvLyBwYXRoIG1vcmUgY2xvc2VseSBtYXRjaGVzIHJlcXVlc3RQYXRoXG4gICAgICBjb25zdCBzdGFydHNXaXRoTG9jYWwgPSByZXF1ZXN0UGF0aC5zdGFydHNXaXRoKGxvY2FsUGF0aCk7XG4gICAgICBjb25zdCBzdGFydHNXaXRoUHVibGljID0gcmVxdWVzdFBhdGguc3RhcnRzV2l0aChwdWJsaWNQYXRoKTtcbiAgICAgIGNvbnN0IHBhdGhMZW5ndGhUb1VzZSA9XG4gICAgICAgIHN0YXJ0c1dpdGhMb2NhbCAmJiBzdGFydHNXaXRoUHVibGljXG4gICAgICAgICAgPyBNYXRoLm1heChsb2NhbFBhdGgubGVuZ3RoLCBwdWJsaWNQYXRoLmxlbmd0aClcbiAgICAgICAgICA6IHN0YXJ0c1dpdGhMb2NhbFxuICAgICAgICAgICAgPyBsb2NhbFBhdGgubGVuZ3RoXG4gICAgICAgICAgICA6IHB1YmxpY1BhdGgubGVuZ3RoO1xuXG4gICAgICBjb25zdCBuZXdQYXRoID0gcGF0aC5wb3NpeC5qb2luKCcvJywgbG9jYWxQYXRoLCAnLycsIHJlcXVlc3RQYXRoLnNsaWNlKHBhdGhMZW5ndGhUb1VzZSkpO1xuXG4gICAgICAvLyBVc2UgdGhlIG1ldGhvZCBmb3IgbG9jYWwgcm91dGluZ1xuICAgICAgcmV0dXJuIG1ha2VSb3V0YWJsZVBhdGgobmV3UGF0aCk7XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBtYWtlUm91dGFibGVQYXRoO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYSB7cmVzcG9uc2V9IG9iamVjdC5cbi8vIFRPRE86IHBhc3MgYWxvbmcgYXV0aCBjb3JyZWN0bHlcbmZ1bmN0aW9uIGhhbmRsZUJhdGNoKHJvdXRlciwgcmVxKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShyZXEuYm9keS5yZXF1ZXN0cykpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAncmVxdWVzdHMgbXVzdCBiZSBhbiBhcnJheScpO1xuICB9XG5cbiAgLy8gVGhlIGJhdGNoIHBhdGhzIGFyZSBhbGwgZnJvbSB0aGUgcm9vdCBvZiBvdXIgZG9tYWluLlxuICAvLyBUaGF0IG1lYW5zIHRoZXkgaW5jbHVkZSB0aGUgQVBJIHByZWZpeCwgdGhhdCB0aGUgQVBJIGlzIG1vdW50ZWRcbiAgLy8gdG8uIEhvd2V2ZXIsIG91ciBwcm9taXNlIHJvdXRlciBkb2VzIG5vdCByb3V0ZSB0aGUgYXBpIHByZWZpeC4gU29cbiAgLy8gd2UgbmVlZCB0byBmaWd1cmUgb3V0IHRoZSBBUEkgcHJlZml4LCBzbyB0aGF0IHdlIGNhbiBzdHJpcCBpdFxuICAvLyBmcm9tIGFsbCB0aGUgc3VicmVxdWVzdHMuXG4gIGlmICghcmVxLm9yaWdpbmFsVXJsLmVuZHNXaXRoKGJhdGNoUGF0aCkpIHtcbiAgICB0aHJvdyAnaW50ZXJuYWwgcm91dGluZyBwcm9ibGVtIC0gZXhwZWN0ZWQgdXJsIHRvIGVuZCB3aXRoIGJhdGNoJztcbiAgfVxuXG4gIGNvbnN0IG1ha2VSb3V0YWJsZVBhdGggPSBtYWtlQmF0Y2hSb3V0aW5nUGF0aEZ1bmN0aW9uKFxuICAgIHJlcS5vcmlnaW5hbFVybCxcbiAgICByZXEuY29uZmlnLnNlcnZlclVSTCxcbiAgICByZXEuY29uZmlnLnB1YmxpY1NlcnZlclVSTFxuICApO1xuXG4gIGxldCBpbml0aWFsUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSgpO1xuICBpZiAocmVxLmJvZHkudHJhbnNhY3Rpb24gPT09IHRydWUpIHtcbiAgICBpbml0aWFsUHJvbWlzZSA9IHJlcS5jb25maWcuZGF0YWJhc2UuY3JlYXRlVHJhbnNhY3Rpb25hbFNlc3Npb24oKTtcbiAgfVxuXG4gIHJldHVybiBpbml0aWFsUHJvbWlzZS50aGVuKCgpID0+IHtcbiAgICBjb25zdCBwcm9taXNlcyA9IHJlcS5ib2R5LnJlcXVlc3RzLm1hcChyZXN0UmVxdWVzdCA9PiB7XG4gICAgICBjb25zdCByb3V0YWJsZVBhdGggPSBtYWtlUm91dGFibGVQYXRoKHJlc3RSZXF1ZXN0LnBhdGgpO1xuXG4gICAgICAvLyBDb25zdHJ1Y3QgYSByZXF1ZXN0IHRoYXQgd2UgY2FuIHNlbmQgdG8gYSBoYW5kbGVyXG4gICAgICBjb25zdCByZXF1ZXN0ID0ge1xuICAgICAgICBib2R5OiByZXN0UmVxdWVzdC5ib2R5LFxuICAgICAgICBjb25maWc6IHJlcS5jb25maWcsXG4gICAgICAgIGF1dGg6IHJlcS5hdXRoLFxuICAgICAgICBpbmZvOiByZXEuaW5mbyxcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiByb3V0ZXIudHJ5Um91dGVSZXF1ZXN0KHJlc3RSZXF1ZXN0Lm1ldGhvZCwgcm91dGFibGVQYXRoLCByZXF1ZXN0KS50aGVuKFxuICAgICAgICByZXNwb25zZSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogcmVzcG9uc2UucmVzcG9uc2UgfTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3IgPT4ge1xuICAgICAgICAgIHJldHVybiB7IGVycm9yOiB7IGNvZGU6IGVycm9yLmNvZGUsIGVycm9yOiBlcnJvci5tZXNzYWdlIH0gfTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIGlmIChyZXEuYm9keS50cmFuc2FjdGlvbiA9PT0gdHJ1ZSkge1xuICAgICAgICBpZiAocmVzdWx0cy5maW5kKHJlc3VsdCA9PiB0eXBlb2YgcmVzdWx0LmVycm9yID09PSAnb2JqZWN0JykpIHtcbiAgICAgICAgICByZXR1cm4gcmVxLmNvbmZpZy5kYXRhYmFzZS5hYm9ydFRyYW5zYWN0aW9uYWxTZXNzaW9uKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoeyByZXNwb25zZTogcmVzdWx0cyB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gcmVxLmNvbmZpZy5kYXRhYmFzZS5jb21taXRUcmFuc2FjdGlvbmFsU2Vzc2lvbigpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHJlc3VsdHMgfTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHJlc3VsdHMgfTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBtb3VudE9udG8sXG4gIG1ha2VCYXRjaFJvdXRpbmdQYXRoRnVuY3Rpb24sXG59O1xuIl19 \ No newline at end of file diff --git a/lib/cache.js b/lib/cache.js new file mode 100644 index 0000000000..ddeda818f9 --- /dev/null +++ b/lib/cache.js @@ -0,0 +1,16 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.AppCache = void 0; + +var _InMemoryCache = require("./Adapters/Cache/InMemoryCache"); + +var AppCache = new _InMemoryCache.InMemoryCache({ + ttl: NaN +}); +exports.AppCache = AppCache; +var _default = AppCache; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jYWNoZS5qcyJdLCJuYW1lcyI6WyJBcHBDYWNoZSIsIkluTWVtb3J5Q2FjaGUiLCJ0dGwiLCJOYU4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFFTyxJQUFJQSxRQUFRLEdBQUcsSUFBSUMsNEJBQUosQ0FBa0I7QUFBRUMsRUFBQUEsR0FBRyxFQUFFQztBQUFQLENBQWxCLENBQWY7O2VBQ1FILFEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbk1lbW9yeUNhY2hlIH0gZnJvbSAnLi9BZGFwdGVycy9DYWNoZS9Jbk1lbW9yeUNhY2hlJztcblxuZXhwb3J0IHZhciBBcHBDYWNoZSA9IG5ldyBJbk1lbW9yeUNhY2hlKHsgdHRsOiBOYU4gfSk7XG5leHBvcnQgZGVmYXVsdCBBcHBDYWNoZTtcbiJdfQ== \ No newline at end of file diff --git a/lib/cli/definitions/parse-live-query-server.js b/lib/cli/definitions/parse-live-query-server.js new file mode 100644 index 0000000000..cc12de8412 --- /dev/null +++ b/lib/cli/definitions/parse-live-query-server.js @@ -0,0 +1,12 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +const LiveQueryServerOptions = require('../../Options/Definitions').LiveQueryServerOptions; + +var _default = LiveQueryServerOptions; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGkvZGVmaW5pdGlvbnMvcGFyc2UtbGl2ZS1xdWVyeS1zZXJ2ZXIuanMiXSwibmFtZXMiOlsiTGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucyIsInJlcXVpcmUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQSxNQUFNQSxzQkFBc0IsR0FBR0MsT0FBTyxDQUFDLDJCQUFELENBQVAsQ0FBcUNELHNCQUFwRTs7ZUFDZUEsc0IiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBMaXZlUXVlcnlTZXJ2ZXJPcHRpb25zID0gcmVxdWlyZSgnLi4vLi4vT3B0aW9ucy9EZWZpbml0aW9ucycpLkxpdmVRdWVyeVNlcnZlck9wdGlvbnM7XG5leHBvcnQgZGVmYXVsdCBMaXZlUXVlcnlTZXJ2ZXJPcHRpb25zO1xuIl19 \ No newline at end of file diff --git a/lib/cli/definitions/parse-server.js b/lib/cli/definitions/parse-server.js new file mode 100644 index 0000000000..0bd5a64da5 --- /dev/null +++ b/lib/cli/definitions/parse-server.js @@ -0,0 +1,12 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +const ParseServerDefinitions = require('../../Options/Definitions').ParseServerOptions; + +var _default = ParseServerDefinitions; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGkvZGVmaW5pdGlvbnMvcGFyc2Utc2VydmVyLmpzIl0sIm5hbWVzIjpbIlBhcnNlU2VydmVyRGVmaW5pdGlvbnMiLCJyZXF1aXJlIiwiUGFyc2VTZXJ2ZXJPcHRpb25zIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUEsTUFBTUEsc0JBQXNCLEdBQUdDLE9BQU8sQ0FBQywyQkFBRCxDQUFQLENBQXFDQyxrQkFBcEU7O2VBQ2VGLHNCIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgUGFyc2VTZXJ2ZXJEZWZpbml0aW9ucyA9IHJlcXVpcmUoJy4uLy4uL09wdGlvbnMvRGVmaW5pdGlvbnMnKS5QYXJzZVNlcnZlck9wdGlvbnM7XG5leHBvcnQgZGVmYXVsdCBQYXJzZVNlcnZlckRlZmluaXRpb25zO1xuIl19 \ No newline at end of file diff --git a/lib/cli/parse-live-query-server.js b/lib/cli/parse-live-query-server.js new file mode 100644 index 0000000000..346727035d --- /dev/null +++ b/lib/cli/parse-live-query-server.js @@ -0,0 +1,19 @@ +"use strict"; + +var _parseLiveQueryServer = _interopRequireDefault(require("./definitions/parse-live-query-server")); + +var _runner = _interopRequireDefault(require("./utils/runner")); + +var _index = require("../index"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +(0, _runner.default)({ + definitions: _parseLiveQueryServer.default, + start: function (program, options, logOptions) { + logOptions(); + + _index.ParseServer.createLiveQueryServer(undefined, options); + } +}); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGkvcGFyc2UtbGl2ZS1xdWVyeS1zZXJ2ZXIuanMiXSwibmFtZXMiOlsiZGVmaW5pdGlvbnMiLCJzdGFydCIsInByb2dyYW0iLCJvcHRpb25zIiwibG9nT3B0aW9ucyIsIlBhcnNlU2VydmVyIiwiY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyIiwidW5kZWZpbmVkIl0sIm1hcHBpbmdzIjoiOztBQUFBOztBQUNBOztBQUNBOzs7O0FBRUEscUJBQU87QUFDTEEsRUFBQUEsV0FBVyxFQUFYQSw2QkFESztBQUVMQyxFQUFBQSxLQUFLLEVBQUUsVUFBVUMsT0FBVixFQUFtQkMsT0FBbkIsRUFBNEJDLFVBQTVCLEVBQXdDO0FBQzdDQSxJQUFBQSxVQUFVOztBQUNWQyx1QkFBWUMscUJBQVosQ0FBa0NDLFNBQWxDLEVBQTZDSixPQUE3QztBQUNEO0FBTEksQ0FBUCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBkZWZpbml0aW9ucyBmcm9tICcuL2RlZmluaXRpb25zL3BhcnNlLWxpdmUtcXVlcnktc2VydmVyJztcbmltcG9ydCBydW5uZXIgZnJvbSAnLi91dGlscy9ydW5uZXInO1xuaW1wb3J0IHsgUGFyc2VTZXJ2ZXIgfSBmcm9tICcuLi9pbmRleCc7XG5cbnJ1bm5lcih7XG4gIGRlZmluaXRpb25zLFxuICBzdGFydDogZnVuY3Rpb24gKHByb2dyYW0sIG9wdGlvbnMsIGxvZ09wdGlvbnMpIHtcbiAgICBsb2dPcHRpb25zKCk7XG4gICAgUGFyc2VTZXJ2ZXIuY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyKHVuZGVmaW5lZCwgb3B0aW9ucyk7XG4gIH0sXG59KTtcbiJdfQ== \ No newline at end of file diff --git a/lib/cli/parse-server.js b/lib/cli/parse-server.js new file mode 100755 index 0000000000..188991e3fe --- /dev/null +++ b/lib/cli/parse-server.js @@ -0,0 +1,111 @@ +"use strict"; + +var _index = _interopRequireDefault(require("../index")); + +var _parseServer = _interopRequireDefault(require("./definitions/parse-server")); + +var _cluster = _interopRequireDefault(require("cluster")); + +var _os = _interopRequireDefault(require("os")); + +var _runner = _interopRequireDefault(require("./utils/runner")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/* eslint-disable no-console */ +const help = function () { + console.log(' Get Started guide:'); + console.log(''); + console.log(' Please have a look at the get started guide!'); + console.log(' http://docs.parseplatform.org/parse-server/guide/'); + console.log(''); + console.log(''); + console.log(' Usage with npm start'); + console.log(''); + console.log(' $ npm start -- path/to/config.json'); + console.log(' $ npm start -- --appId APP_ID --masterKey MASTER_KEY --serverURL serverURL'); + console.log(' $ npm start -- --appId APP_ID --masterKey MASTER_KEY --serverURL serverURL'); + console.log(''); + console.log(''); + console.log(' Usage:'); + console.log(''); + console.log(' $ parse-server path/to/config.json'); + console.log(' $ parse-server -- --appId APP_ID --masterKey MASTER_KEY --serverURL serverURL'); + console.log(' $ parse-server -- --appId APP_ID --masterKey MASTER_KEY --serverURL serverURL'); + console.log(''); +}; + +(0, _runner.default)({ + definitions: _parseServer.default, + help, + usage: '[options] ', + start: function (program, options, logOptions) { + if (!options.appId || !options.masterKey) { + program.outputHelp(); + console.error(''); + console.error('\u001b[31mERROR: appId and masterKey are required\u001b[0m'); + console.error(''); + process.exit(1); + } + + if (options['liveQuery.classNames']) { + options.liveQuery = options.liveQuery || {}; + options.liveQuery.classNames = options['liveQuery.classNames']; + delete options['liveQuery.classNames']; + } + + if (options['liveQuery.redisURL']) { + options.liveQuery = options.liveQuery || {}; + options.liveQuery.redisURL = options['liveQuery.redisURL']; + delete options['liveQuery.redisURL']; + } + + if (options['liveQuery.redisOptions']) { + options.liveQuery = options.liveQuery || {}; + options.liveQuery.redisOptions = options['liveQuery.redisOptions']; + delete options['liveQuery.redisOptions']; + } + + if (options.cluster) { + const numCPUs = typeof options.cluster === 'number' ? options.cluster : _os.default.cpus().length; + + if (_cluster.default.isMaster) { + logOptions(); + + for (let i = 0; i < numCPUs; i++) { + _cluster.default.fork(); + } + + _cluster.default.on('exit', (worker, code) => { + console.log(`worker ${worker.process.pid} died (${code})... Restarting`); + + _cluster.default.fork(); + }); + } else { + _index.default.start(options, () => { + printSuccessMessage(); + }); + } + } else { + _index.default.start(options, () => { + logOptions(); + console.log(''); + printSuccessMessage(); + }); + } + + function printSuccessMessage() { + console.log('[' + process.pid + '] parse-server running on ' + options.serverURL); + + if (options.mountGraphQL) { + console.log('[' + process.pid + '] GraphQL running on http://localhost:' + options.port + options.graphQLPath); + } + + if (options.mountPlayground) { + console.log('[' + process.pid + '] Playground running on http://localhost:' + options.port + options.playgroundPath); + } + } + } +}); +/* eslint-enable no-console */ +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGkvcGFyc2Utc2VydmVyLmpzIl0sIm5hbWVzIjpbImhlbHAiLCJjb25zb2xlIiwibG9nIiwiZGVmaW5pdGlvbnMiLCJ1c2FnZSIsInN0YXJ0IiwicHJvZ3JhbSIsIm9wdGlvbnMiLCJsb2dPcHRpb25zIiwiYXBwSWQiLCJtYXN0ZXJLZXkiLCJvdXRwdXRIZWxwIiwiZXJyb3IiLCJwcm9jZXNzIiwiZXhpdCIsImxpdmVRdWVyeSIsImNsYXNzTmFtZXMiLCJyZWRpc1VSTCIsInJlZGlzT3B0aW9ucyIsImNsdXN0ZXIiLCJudW1DUFVzIiwib3MiLCJjcHVzIiwibGVuZ3RoIiwiaXNNYXN0ZXIiLCJpIiwiZm9yayIsIm9uIiwid29ya2VyIiwiY29kZSIsInBpZCIsIlBhcnNlU2VydmVyIiwicHJpbnRTdWNjZXNzTWVzc2FnZSIsInNlcnZlclVSTCIsIm1vdW50R3JhcGhRTCIsInBvcnQiLCJncmFwaFFMUGF0aCIsIm1vdW50UGxheWdyb3VuZCIsInBsYXlncm91bmRQYXRoIl0sIm1hcHBpbmdzIjoiOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBTEE7QUFPQSxNQUFNQSxJQUFJLEdBQUcsWUFBWTtBQUN2QkMsRUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksc0JBQVo7QUFDQUQsRUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksRUFBWjtBQUNBRCxFQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSxrREFBWjtBQUNBRCxFQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSx1REFBWjtBQUNBRCxFQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSxFQUFaO0FBQ0FELEVBQUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFZLEVBQVo7QUFDQUQsRUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksd0JBQVo7QUFDQUQsRUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksRUFBWjtBQUNBRCxFQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSx3Q0FBWjtBQUNB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QUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFhLFVBQVMwQixNQUFNLENBQUNmLE9BQVAsQ0FBZWlCLEdBQUksVUFBU0QsSUFBSyxpQkFBdkQ7O0FBQ0FWLDJCQUFRTyxJQUFSO0FBQ0QsU0FIRDtBQUlELE9BVEQsTUFTTztBQUNMSyx1QkFBWTFCLEtBQVosQ0FBa0JFLE9BQWxCLEVBQTJCLE1BQU07QUFDL0J5QixVQUFBQSxtQkFBbUI7QUFDcEIsU0FGRDtBQUdEO0FBQ0YsS0FoQkQsTUFnQk87QUFDTEQscUJBQVkxQixLQUFaLENBQWtCRSxPQUFsQixFQUEyQixNQUFNO0FBQy9CQyxRQUFBQSxVQUFVO0FBQ1ZQLFFBQUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFZLEVBQVo7QUFDQThCLFFBQUFBLG1CQUFtQjtBQUNwQixPQUpEO0FBS0Q7O0FBRUQsYUFBU0EsbUJBQVQsR0FBK0I7QUFDN0IvQixNQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSxNQUFNVyxPQUFPLENBQUNpQixHQUFkLEdBQW9CLDRCQUFwQixHQUFtRHZCLE9BQU8sQ0FBQzBCLFNBQXZFOztBQUNBLFVBQUkxQixPQUFPLENBQUMyQixZQUFaLEVBQTBCO0FBQ3hCakMsUUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQ0UsTUFDRVcsT0FBTyxDQUFDaUIsR0FEVixHQUVFLHdDQUZGLEdBR0V2QixPQUFPLENBQUM0QixJQUhWLEdBSUU1QixPQUFPLENBQUM2QixXQUxaO0FBT0Q7O0FBQ0QsVUFBSTdCLE9BQU8sQ0FBQzhCLGVBQVosRUFBNkI7QUFDM0JwQyxRQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FDRSxNQUNFVyxPQUFPLENBQUNpQixHQURWLEdBRUUsMkNBRkYsR0FHRXZCLE9BQU8sQ0FBQzRCLElBSFYsR0FJRTVCLE9BQU8sQ0FBQytCLGNBTFo7QUFPRDtBQUNGO0FBQ0Y7QUExRUksQ0FBUDtBQTZFQSIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbmltcG9ydCBQYXJzZVNlcnZlciBmcm9tICcuLi9pbmRleCc7XG5pbXBvcnQgZGVmaW5pdGlvbnMgZnJvbSAnLi9kZWZpbml0aW9ucy9wYXJzZS1zZXJ2ZXInO1xuaW1wb3J0IGNsdXN0ZXIgZnJvbSAnY2x1c3Rlcic7XG5pbXBvcnQgb3MgZnJvbSAnb3MnO1xuaW1wb3J0IHJ1bm5lciBmcm9tICcuL3V0aWxzL3J1bm5lcic7XG5cbmNvbnN0IGhlbHAgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnNvbGUubG9nKCcgIEdldCBTdGFydGVkIGd1aWRlOicpO1xuICBjb25zb2xlLmxvZygnJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgUGxlYXNlIGhhdmUgYSBsb29rIGF0IHRoZSBnZXQgc3RhcnRlZCBndWlkZSEnKTtcbiAgY29uc29sZS5sb2coJyAgICBodHRwOi8vZG9jcy5wYXJzZXBsYXRmb3JtLm9yZy9wYXJzZS1zZXJ2ZXIvZ3VpZGUvJyk7XG4gIGNvbnNvbGUubG9nKCcnKTtcbiAgY29uc29sZS5sb2coJycpO1xuICBjb25zb2xlLmxvZygnICBVc2FnZSB3aXRoIG5wbSBzdGFydCcpO1xuICBjb25zb2xlLmxvZygnJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgJCBucG0gc3RhcnQgLS0gcGF0aC90by9jb25maWcuanNvbicpO1xuICBjb25zb2xlLmxvZygnICAgICQgbnBtIHN0YXJ0IC0tIC0tYXBwSWQgQVBQX0lEIC0tbWFzdGVyS2V5IE1BU1RFUl9LRVkgLS1zZXJ2ZXJVUkwgc2VydmVyVVJMJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgJCBucG0gc3RhcnQgLS0gLS1hcHBJZCBBUFBfSUQgLS1tYXN0ZXJLZXkgTUFTVEVSX0tFWSAtLXNlcnZlclVSTCBzZXJ2ZXJVUkwnKTtcbiAgY29uc29sZS5sb2coJycpO1xuICBjb25zb2xlLmxvZygnJyk7XG4gIGNvbnNvbGUubG9nKCcgIFVzYWdlOicpO1xuICBjb25zb2xlLmxvZygnJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgJCBwYXJzZS1zZXJ2ZXIgcGF0aC90by9jb25maWcuanNvbicpO1xuICBjb25zb2xlLmxvZygnICAgICQgcGFyc2Utc2VydmVyIC0tIC0tYXBwSWQgQVBQX0lEIC0tbWFzdGVyS2V5IE1BU1RFUl9LRVkgLS1zZXJ2ZXJVUkwgc2VydmVyVVJMJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgJCBwYXJzZS1zZXJ2ZXIgLS0gLS1hcHBJZCBBUFBfSUQgLS1tYXN0ZXJLZXkgTUFTVEVSX0tFWSAtLXNlcnZlclVSTCBzZXJ2ZXJVUkwnKTtcbiAgY29uc29sZS5sb2coJycpO1xufTtcblxucnVubmVyKHtcbiAgZGVmaW5pdGlvbnMsXG4gIGhlbHAsXG4gIHVzYWdlOiAnW29wdGlvbnNdIDxwYXRoL3RvL2NvbmZpZ3VyYXRpb24uanNvbj4nLFxuICBzdGFydDogZnVuY3Rpb24gKHByb2dyYW0sIG9wdGlvbnMsIGxvZ09wdGlvbnMpIHtcbiAgICBpZiAoIW9wdGlvbnMuYXBwSWQgfHwgIW9wdGlvbnMubWFzdGVyS2V5KSB7XG4gICAgICBwcm9ncmFtLm91dHB1dEhlbHAoKTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJycpO1xuICAgICAgY29uc29sZS5lcnJvcignXFx1MDAxYlszMW1FUlJPUjogYXBwSWQgYW5kIG1hc3RlcktleSBhcmUgcmVxdWlyZWRcXHUwMDFiWzBtJyk7XG4gICAgICBjb25zb2xlLmVycm9yKCcnKTtcbiAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9uc1snbGl2ZVF1ZXJ5LmNsYXNzTmFtZXMnXSkge1xuICAgICAgb3B0aW9ucy5saXZlUXVlcnkgPSBvcHRpb25zLmxpdmVRdWVyeSB8fCB7fTtcbiAgICAgIG9wdGlvbnMubGl2ZVF1ZXJ5LmNsYXNzTmFtZXMgPSBvcHRpb25zWydsaXZlUXVlcnkuY2xhc3NOYW1lcyddO1xuICAgICAgZGVsZXRlIG9wdGlvbnNbJ2xpdmVRdWVyeS5jbGFzc05hbWVzJ107XG4gICAgfVxuICAgIGlmIChvcHRpb25zWydsaXZlUXVlcnkucmVkaXNVUkwnXSkge1xuICAgICAgb3B0aW9ucy5saXZlUXVlcnkgPSBvcHRpb25zLmxpdmVRdWVyeSB8fCB7fTtcbiAgICAgIG9wdGlvbnMubGl2ZVF1ZXJ5LnJlZGlzVVJMID0gb3B0aW9uc1snbGl2ZVF1ZXJ5LnJlZGlzVVJMJ107XG4gICAgICBkZWxldGUgb3B0aW9uc1snbGl2ZVF1ZXJ5LnJlZGlzVVJMJ107XG4gICAgfVxuICAgIGlmIChvcHRpb25zWydsaXZlUXVlcnkucmVkaXNPcHRpb25zJ10pIHtcbiAgICAgIG9wdGlvbnMubGl2ZVF1ZXJ5ID0gb3B0aW9ucy5saXZlUXVlcnkgfHwge307XG4gICAgICBvcHRpb25zLmxpdmVRdWVyeS5yZWRpc09wdGlvbnMgPSBvcHRpb25zWydsaXZlUXVlcnkucmVkaXNPcHRpb25zJ107XG4gICAgICBkZWxldGUgb3B0aW9uc1snbGl2ZVF1ZXJ5LnJlZGlzT3B0aW9ucyddO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmNsdXN0ZXIpIHtcbiAgICAgIGNvbnN0IG51bUNQVXMgPSB0eXBlb2Ygb3B0aW9ucy5jbHVzdGVyID09PSAnbnVtYmVyJyA/IG9wdGlvbnMuY2x1c3RlciA6IG9zLmNwdXMoKS5sZW5ndGg7XG4gICAgICBpZiAoY2x1c3Rlci5pc01hc3Rlcikge1xuICAgICAgICBsb2dPcHRpb25zKCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtQ1BVczsgaSsrKSB7XG4gICAgICAgICAgY2x1c3Rlci5mb3JrKCk7XG4gICAgICAgIH1cbiAgICAgICAgY2x1c3Rlci5vbignZXhpdCcsICh3b3JrZXIsIGNvZGUpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgd29ya2VyICR7d29ya2VyLnByb2Nlc3MucGlkfSBkaWVkICgke2NvZGV9KS4uLiBSZXN0YXJ0aW5nYCk7XG4gICAgICAgICAgY2x1c3Rlci5mb3JrKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgUGFyc2VTZXJ2ZXIuc3RhcnQob3B0aW9ucywgKCkgPT4ge1xuICAgICAgICAgIHByaW50U3VjY2Vzc01lc3NhZ2UoKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIFBhcnNlU2VydmVyLnN0YXJ0KG9wdGlvbnMsICgpID0+IHtcbiAgICAgICAgbG9nT3B0aW9ucygpO1xuICAgICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICAgIHByaW50U3VjY2Vzc01lc3NhZ2UoKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHByaW50U3VjY2Vzc01lc3NhZ2UoKSB7XG4gICAgICBjb25zb2xlLmxvZygnWycgKyBwcm9jZXNzLnBpZCArICddIHBhcnNlLXNlcnZlciBydW5uaW5nIG9uICcgKyBvcHRpb25zLnNlcnZlclVSTCk7XG4gICAgICBpZiAob3B0aW9ucy5tb3VudEdyYXBoUUwpIHtcbiAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgJ1snICtcbiAgICAgICAgICAgIHByb2Nlc3MucGlkICtcbiAgICAgICAgICAgICddIEdyYXBoUUwgcnVubmluZyBvbiBodHRwOi8vbG9jYWxob3N0OicgK1xuICAgICAgICAgICAgb3B0aW9ucy5wb3J0ICtcbiAgICAgICAgICAgIG9wdGlvbnMuZ3JhcGhRTFBhdGhcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLm1vdW50UGxheWdyb3VuZCkge1xuICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAnWycgK1xuICAgICAgICAgICAgcHJvY2Vzcy5waWQgK1xuICAgICAgICAgICAgJ10gUGxheWdyb3VuZCBydW5uaW5nIG9uIGh0dHA6Ly9sb2NhbGhvc3Q6JyArXG4gICAgICAgICAgICBvcHRpb25zLnBvcnQgK1xuICAgICAgICAgICAgb3B0aW9ucy5wbGF5Z3JvdW5kUGF0aFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbn0pO1xuXG4vKiBlc2xpbnQtZW5hYmxlIG5vLWNvbnNvbGUgKi9cbiJdfQ== \ No newline at end of file diff --git a/lib/cli/utils/commander.js b/lib/cli/utils/commander.js new file mode 100644 index 0000000000..d1164c5c63 --- /dev/null +++ b/lib/cli/utils/commander.js @@ -0,0 +1,163 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _commander = require("commander"); + +var _path = _interopRequireDefault(require("path")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/* eslint-disable no-console */ +let _definitions; + +let _reverseDefinitions; + +let _defaults; + +_commander.Command.prototype.loadDefinitions = function (definitions) { + _definitions = definitions; + Object.keys(definitions).reduce((program, opt) => { + if (typeof definitions[opt] == 'object') { + const additionalOptions = definitions[opt]; + + if (additionalOptions.required === true) { + return program.option(`--${opt} <${opt}>`, additionalOptions.help, additionalOptions.action); + } else { + return program.option(`--${opt} [${opt}]`, additionalOptions.help, additionalOptions.action); + } + } + + return program.option(`--${opt} [${opt}]`); + }, this); + _reverseDefinitions = Object.keys(definitions).reduce((object, key) => { + let value = definitions[key]; + + if (typeof value == 'object') { + value = value.env; + } + + if (value) { + object[value] = key; + } + + return object; + }, {}); + _defaults = Object.keys(definitions).reduce((defs, opt) => { + if (_definitions[opt].default) { + defs[opt] = _definitions[opt].default; + } + + return defs; + }, {}); + /* istanbul ignore next */ + + this.on('--help', function () { + console.log(' Configure From Environment:'); + console.log(''); + Object.keys(_reverseDefinitions).forEach(key => { + console.log(` $ ${key}='${_reverseDefinitions[key]}'`); + }); + console.log(''); + }); +}; + +function parseEnvironment(env = {}) { + return Object.keys(_reverseDefinitions).reduce((options, key) => { + if (env[key]) { + const originalKey = _reverseDefinitions[key]; + + let action = option => option; + + if (typeof _definitions[originalKey] === 'object') { + action = _definitions[originalKey].action || action; + } + + options[_reverseDefinitions[key]] = action(env[key]); + } + + return options; + }, {}); +} + +function parseConfigFile(program) { + let options = {}; + + if (program.args.length > 0) { + let jsonPath = program.args[0]; + jsonPath = _path.default.resolve(jsonPath); + + const jsonConfig = require(jsonPath); + + if (jsonConfig.apps) { + if (jsonConfig.apps.length > 1) { + throw 'Multiple apps are not supported'; + } + + options = jsonConfig.apps[0]; + } else { + options = jsonConfig; + } + + Object.keys(options).forEach(key => { + const value = options[key]; + + if (!_definitions[key]) { + throw `error: unknown option ${key}`; + } + + const action = _definitions[key].action; + + if (action) { + options[key] = action(value); + } + }); + console.log(`Configuration loaded from ${jsonPath}`); + } + + return options; +} + +_commander.Command.prototype.setValuesIfNeeded = function (options) { + Object.keys(options).forEach(key => { + if (!Object.prototype.hasOwnProperty.call(this, key)) { + this[key] = options[key]; + } + }); +}; + +_commander.Command.prototype._parse = _commander.Command.prototype.parse; + +_commander.Command.prototype.parse = function (args, env) { + this._parse(args); // Parse the environment first + + + const envOptions = parseEnvironment(env); + const fromFile = parseConfigFile(this); // Load the env if not passed from command line + + this.setValuesIfNeeded(envOptions); // Load from file to override + + this.setValuesIfNeeded(fromFile); // Last set the defaults + + this.setValuesIfNeeded(_defaults); +}; + +_commander.Command.prototype.getOptions = function () { + return Object.keys(_definitions).reduce((options, key) => { + if (typeof this[key] !== 'undefined') { + options[key] = this[key]; + } + + return options; + }, {}); +}; + +var _default = new _commander.Command(); +/* eslint-enable no-console */ + + +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGkvdXRpbHMvY29tbWFuZGVyLmpzIl0sIm5hbWVzIjpbIl9kZWZpbml0aW9ucyIsIl9yZXZlcnNlRGVmaW5pdGlvbnMiLCJfZGVmYXVsdHMiLCJDb21tYW5kIiwicHJvdG90eXBlIiwibG9hZERlZmluaXRpb25zIiwiZGVmaW5pdGlvbnMiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwicHJvZ3JhbSIsIm9wdCIsImFkZGl0aW9uYWxPcHRpb25zIiwicmVxdWlyZWQiLCJvcHRpb24iLCJoZWxwIiwiYWN0aW9uIiwib2JqZWN0Iiwia2V5IiwidmFsdWUiLCJlbnYiLCJkZWZzIiwiZGVmYXVsdCIsIm9uIiwiY29uc29sZSIsImxvZyIsImZvckVhY2giLCJwYXJzZUVudmlyb25tZW50Iiwib3B0aW9ucyIsIm9yaWdpbmFsS2V5IiwicGFyc2VDb25maWdGaWxlIiwiYXJncyIsImxlbmd0aCIsImpzb25QYXRoIiwicGF0aCIsInJlc29sdmUiLCJqc29uQ29uZmlnIiwicmVxdWlyZSIsImFwcHMiLCJzZXRWYWx1ZXNJZk5lZWRlZCIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIl9wYXJzZSIsInBhcnNlIiwiZW52T3B0aW9ucyIsImZyb21GaWxlIiwiZ2V0T3B0aW9ucyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUNBOztBQUNBOzs7O0FBRkE7QUFHQSxJQUFJQSxZQUFKOztBQUNBLElBQUlDLG1CQUFKOztBQUNBLElBQUlDLFNBQUo7O0FBRUFDLG1CQUFRQyxTQUFSLENBQWtCQyxlQUFsQixHQUFvQyxVQUFVQyxXQUFWLEVBQXVCO0FBQ3pETixFQUFBQSxZQUFZLEdBQUdNLFdBQWY7QUFFQUMsRUFBQUEsTUFBTSxDQUFDQyxJQUFQLENBQVlGLFdBQVosRUFBeUJHLE1BQXpCLENBQWdDLENBQUNDLE9BQUQsRUFBVUMsR0FBVixLQUFrQjtBQUNoRCxRQUFJLE9BQU9MLFdBQVcsQ0FBQ0ssR0FBRCxDQUFsQixJQUEyQixRQUEvQixFQUF5QztB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QUFSLENBQWtCMEMsVUFBbEIsR0FBK0IsWUFBWTtBQUN6QyxTQUFPdkMsTUFBTSxDQUFDQyxJQUFQLENBQVlSLFlBQVosRUFBMEJTLE1BQTFCLENBQWlDLENBQUNtQixPQUFELEVBQVVWLEdBQVYsS0FBa0I7QUFDeEQsUUFBSSxPQUFPLEtBQUtBLEdBQUwsQ0FBUCxLQUFxQixXQUF6QixFQUFzQztBQUNwQ1UsTUFBQUEsT0FBTyxDQUFDVixHQUFELENBQVAsR0FBZSxLQUFLQSxHQUFMLENBQWY7QUFDRDs7QUFDRCxXQUFPVSxPQUFQO0FBQ0QsR0FMTSxFQUtKLEVBTEksQ0FBUDtBQU1ELENBUEQ7O2VBU2UsSUFBSXpCLGtCQUFKLEU7QUFDZiIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbmltcG9ydCB7IENvbW1hbmQgfSBmcm9tICdjb21tYW5kZXInO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5sZXQgX2RlZmluaXRpb25zO1xubGV0IF9yZXZlcnNlRGVmaW5pdGlvbnM7XG5sZXQgX2RlZmF1bHRzO1xuXG5Db21tYW5kLnByb3RvdHlwZS5sb2FkRGVmaW5pdGlvbnMgPSBmdW5jdGlvbiAoZGVmaW5pdGlvbnMpIHtcbiAgX2RlZmluaXRpb25zID0gZGVmaW5pdGlvbnM7XG5cbiAgT2JqZWN0LmtleXMoZGVmaW5pdGlvbnMpLnJlZHVjZSgocHJvZ3JhbSwgb3B0KSA9PiB7XG4gICAgaWYgKHR5cGVvZiBkZWZpbml0aW9uc1tvcHRdID09ICdvYmplY3QnKSB7XG4gICAgICBjb25zdCBhZGRpdGlvbmFsT3B0aW9ucyA9IGRlZmluaXRpb25zW29wdF07XG4gICAgICBpZiAoYWRkaXRpb25hbE9wdGlvbnMucmVxdWlyZWQgPT09IHRydWUpIHtcbiAgICAgICAgcmV0dXJuIHByb2dyYW0ub3B0aW9uKFxuICAgICAgICAgIGAtLSR7b3B0fSA8JHtvcHR9PmAsXG4gICAgICAgICAgYWRkaXRpb25hbE9wdGlvbnMuaGVscCxcbiAgICAgICAgICBhZGRpdGlvbmFsT3B0aW9ucy5hY3Rpb25cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBwcm9ncmFtLm9wdGlvbihcbiAgICAgICAgICBgLS0ke29wdH0gWyR7b3B0fV1gLFxuICAgICAgICAgIGFkZGl0aW9uYWxPcHRpb25zLmhlbHAsXG4gICAgICAgICAgYWRkaXRpb25hbE9wdGlvbnMuYWN0aW9uXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwcm9ncmFtLm9wdGlvbihgLS0ke29wdH0gWyR7b3B0fV1gKTtcbiAgfSwgdGhpcyk7XG5cbiAgX3JldmVyc2VEZWZpbml0aW9ucyA9IE9iamVjdC5rZXlzKGRlZmluaXRpb25zKS5yZWR1Y2UoKG9iamVjdCwga2V5KSA9PiB7XG4gICAgbGV0IHZhbHVlID0gZGVmaW5pdGlvbnNba2V5XTtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09ICdvYmplY3QnKSB7XG4gICAgICB2YWx1ZSA9IHZhbHVlLmVudjtcbiAgICB9XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICBvYmplY3RbdmFsdWVdID0ga2V5O1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0O1xuICB9LCB7fSk7XG5cbiAgX2RlZmF1bHRzID0gT2JqZWN0LmtleXMoZGVmaW5pdGlvbnMpLnJlZHVjZSgoZGVmcywgb3B0KSA9PiB7XG4gICAgaWYgKF9kZWZpbml0aW9uc1tvcHRdLmRlZmF1bHQpIHtcbiAgICAgIGRlZnNbb3B0XSA9IF9kZWZpbml0aW9uc1tvcHRdLmRlZmF1bHQ7XG4gICAgfVxuICAgIHJldHVybiBkZWZzO1xuICB9LCB7fSk7XG5cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgdGhpcy5vbignLS1oZWxwJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnNvbGUubG9nKCcgIENvbmZpZ3VyZSBGcm9tIEVudmlyb25tZW50OicpO1xuICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICBPYmplY3Qua2V5cyhfcmV2ZXJzZURlZmluaXRpb25zKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBjb25zb2xlLmxvZyhgICAgICQgJHtrZXl9PScke19yZXZlcnNlRGVmaW5pdGlvbnNba2V5XX0nYCk7XG4gICAgfSk7XG4gICAgY29uc29sZS5sb2coJycpO1xuICB9KTtcbn07XG5cbmZ1bmN0aW9uIHBhcnNlRW52aXJvbm1lbnQoZW52ID0ge30pIHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKF9yZXZlcnNlRGVmaW5pdGlvbnMpLnJlZHVjZSgob3B0aW9ucywga2V5KSA9PiB7XG4gICAgaWYgKGVudltrZXldKSB7XG4gICAgICBjb25zdCBvcmlnaW5hbEtleSA9IF9yZXZlcnNlRGVmaW5pdGlvbnNba2V5XTtcbiAgICAgIGxldCBhY3Rpb24gPSBvcHRpb24gPT4gb3B0aW9uO1xuICAgICAgaWYgKHR5cGVvZiBfZGVmaW5pdGlvbnNbb3JpZ2luYWxLZXldID09PSAnb2JqZWN0Jykge1xuICAgICAgICBhY3Rpb24gPSBfZGVmaW5pdGlvbnNbb3JpZ2luYWxLZXldLmFjdGlvbiB8fCBhY3Rpb247XG4gICAgICB9XG4gICAgICBvcHRpb25zW19yZXZlcnNlRGVmaW5pdGlvbnNba2V5XV0gPSBhY3Rpb24oZW52W2tleV0pO1xuICAgIH1cbiAgICByZXR1cm4gb3B0aW9ucztcbiAgfSwge30pO1xufVxuXG5mdW5jdGlvbiBwYXJzZUNvbmZpZ0ZpbGUocHJvZ3JhbSkge1xuICBsZXQgb3B0aW9ucyA9IHt9O1xuICBpZiAocHJvZ3JhbS5hcmdzLmxlbmd0aCA+IDApIHtcbiAgICBsZXQganNvblBhdGggPSBwcm9ncmFtLmFyZ3NbMF07XG4gICAganNvblBhdGggPSBwYXRoLnJlc29sdmUoanNvblBhdGgpO1xuICAgIGNvbnN0IGpzb25Db25maWcgPSByZXF1aXJlKGpzb25QYXRoKTtcbiAgICBpZiAoanNvbkNvbmZpZy5hcHBzKSB7XG4gICAgICBpZiAoanNvbkNvbmZpZy5hcHBzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgdGhyb3cgJ011bHRpcGxlIGFwcHMgYXJlIG5vdCBzdXBwb3J0ZWQnO1xuICAgICAgfVxuICAgICAgb3B0aW9ucyA9IGpzb25Db25maWcuYXBwc1swXTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3B0aW9ucyA9IGpzb25Db25maWc7XG4gICAgfVxuICAgIE9iamVjdC5rZXlzKG9wdGlvbnMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gb3B0aW9uc1trZXldO1xuICAgICAgaWYgKCFfZGVmaW5pdGlvbnNba2V5XSkge1xuICAgICAgICB0aHJvdyBgZXJyb3I6IHVua25vd24gb3B0aW9uICR7a2V5fWA7XG4gICAgICB9XG4gICAgICBjb25zdCBhY3Rpb24gPSBfZGVmaW5pdGlvbnNba2V5XS5hY3Rpb247XG4gICAgICBpZiAoYWN0aW9uKSB7XG4gICAgICAgIG9wdGlvbnNba2V5XSA9IGFjdGlvbih2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc29sZS5sb2coYENvbmZpZ3VyYXRpb24gbG9hZGVkIGZyb20gJHtqc29uUGF0aH1gKTtcbiAgfVxuICByZXR1cm4gb3B0aW9ucztcbn1cblxuQ29tbWFuZC5wcm90b3R5cGUuc2V0VmFsdWVzSWZOZWVkZWQgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICBPYmplY3Qua2V5cyhvcHRpb25zKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcywga2V5KSkge1xuICAgICAgdGhpc1trZXldID0gb3B0aW9uc1trZXldO1xuICAgIH1cbiAgfSk7XG59O1xuXG5Db21tYW5kLnByb3RvdHlwZS5fcGFyc2UgPSBDb21tYW5kLnByb3RvdHlwZS5wYXJzZTtcblxuQ29tbWFuZC5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbiAoYXJncywgZW52KSB7XG4gIHRoaXMuX3BhcnNlKGFyZ3MpO1xuICAvLyBQYXJzZSB0aGUgZW52aXJvbm1lbnQgZmlyc3RcbiAgY29uc3QgZW52T3B0aW9ucyA9IHBhcnNlRW52aXJvbm1lbnQoZW52KTtcbiAgY29uc3QgZnJvbUZpbGUgPSBwYXJzZUNvbmZpZ0ZpbGUodGhpcyk7XG4gIC8vIExvYWQgdGhlIGVudiBpZiBub3QgcGFzc2VkIGZyb20gY29tbWFuZCBsaW5lXG4gIHRoaXMuc2V0VmFsdWVzSWZOZWVkZWQoZW52T3B0aW9ucyk7XG4gIC8vIExvYWQgZnJvbSBmaWxlIHRvIG92ZXJyaWRlXG4gIHRoaXMuc2V0VmFsdWVzSWZOZWVkZWQoZnJvbUZpbGUpO1xuICAvLyBMYXN0IHNldCB0aGUgZGVmYXVsdHNcbiAgdGhpcy5zZXRWYWx1ZXNJZk5lZWRlZChfZGVmYXVsdHMpO1xufTtcblxuQ29tbWFuZC5wcm90b3R5cGUuZ2V0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKF9kZWZpbml0aW9ucykucmVkdWNlKChvcHRpb25zLCBrZXkpID0+IHtcbiAgICBpZiAodHlwZW9mIHRoaXNba2V5XSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIG9wdGlvbnNba2V5XSA9IHRoaXNba2V5XTtcbiAgICB9XG4gICAgcmV0dXJuIG9wdGlvbnM7XG4gIH0sIHt9KTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IG5ldyBDb21tYW5kKCk7XG4vKiBlc2xpbnQtZW5hYmxlIG5vLWNvbnNvbGUgKi9cbiJdfQ== \ No newline at end of file diff --git a/lib/cli/utils/runner.js b/lib/cli/utils/runner.js new file mode 100644 index 0000000000..38d680d58e --- /dev/null +++ b/lib/cli/utils/runner.js @@ -0,0 +1,65 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = _default; + +var _commander = _interopRequireDefault(require("./commander")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function logStartupOptions(options) { + for (const key in options) { + let value = options[key]; + + if (key == 'masterKey') { + value = '***REDACTED***'; + } + + if (key == 'push' && options.verbose != true) { + value = '***REDACTED***'; + } + + if (typeof value === 'object') { + try { + value = JSON.stringify(value); + } catch (e) { + if (value && value.constructor && value.constructor.name) { + value = value.constructor.name; + } + } + } + /* eslint-disable no-console */ + + + console.log(`${key}: ${value}`); + /* eslint-enable no-console */ + } +} + +function _default({ + definitions, + help, + usage, + start +}) { + _commander.default.loadDefinitions(definitions); + + if (usage) { + _commander.default.usage(usage); + } + + if (help) { + _commander.default.on('--help', help); + } + + _commander.default.parse(process.argv, process.env); + + const options = _commander.default.getOptions(); + + start(_commander.default, options, function () { + logStartupOptions(options); + }); +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGkvdXRpbHMvcnVubmVyLmpzIl0sIm5hbWVzIjpbImxvZ1N0YXJ0dXBPcHRpb25zIiwib3B0aW9ucyIsImtleSIsInZhbHVlIiwidmVyYm9zZSIsIkpTT04iLCJzdHJpbmdpZnkiLCJlIiwiY29uc3RydWN0b3IiLCJuYW1lIiwiY29uc29sZSIsImxvZyIsImRlZmluaXRpb25zIiwiaGVscCIsInVzYWdlIiwic3RhcnQiLCJwcm9ncmFtIiwibG9hZERlZmluaXRpb25zIiwib24iLCJwYXJzZSIsInByb2Nlc3MiLCJhcmd2IiwiZW52IiwiZ2V0T3B0aW9ucyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7O0FBRUEsU0FBU0EsaUJBQVQsQ0FBMkJDLE9BQTNCLEVBQW9DO0FBQ2xDLE9BQUssTUFBTUMsR0FBWCxJQUFrQkQsT0FBbEIsRUFBMkI7QUFDekIsUUFBSUUsS0FBSyxHQUFHRixPQUFPLENBQUNDLEdBQUQsQ0FBbkI7O0FBQ0EsUUFBSUEsR0FBRyxJQUFJLFdBQVgsRUFBd0I7QUFDdEJDLE1BQUFBLEtBQUssR0FBRyxnQkFBUjtBQUNEOztBQUNELFFBQUlELEdBQUcsSUFBSSxNQUFQLElBQWlCRCxPQUFPLENBQUNHLE9BQVIsSUFBbUIsSUFBeEMsRUFBOEM7QUFDNUNELE1BQUFBLEtBQUssR0FBRyxnQkFBUjtBQUNEOztBQUNELFFBQUksT0FBT0EsS0FBUCxLQUFpQixRQUFyQixFQUErQjtBQUM3QixVQUFJO0FBQ0ZBLFFBQUFBLEtBQUssR0FBR0UsSUFBSSxDQUFDQyxTQUFMLENBQWVILEtBQWYsQ0FBUjtBQUNELE9BRkQsQ0FFRSxPQUFPSSxDQUFQLEVBQVU7QUFDVixZQUFJSixLQUFLLElBQUlBLEtBQUssQ0FBQ0ssV0FBZixJQUE4QkwsS0FBSyxDQUFDSyxXQUFOLENBQWtCQyxJQUFwRCxFQUEwRDtBQUN4RE4sVUFBQUEsS0FBSyxHQUFHQSxLQUFLLENBQUNLLFdBQU4sQ0FBa0JDLElBQTFCO0FBQ0Q7QUFDRjtBQUNGO0FBQ0Q7OztBQUNBQyxJQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBYSxHQUFFVCxHQUFJLEtBQUlDLEtBQU0sRUFBN0I7QUFDQTtBQUNEO0FBQ0Y7O0FBRWMsa0JBQVU7QUFBRVMsRUFBQUEsV0FBRjtBQUFlQyxFQUFBQSxJQUFmO0FBQXFCQyxFQUFBQSxLQUFyQjtBQUE0QkMsRUFBQUE7QUFBNUIsQ0FBVixFQUErQztBQUM1REMscUJBQVFDLGVBQVIsQ0FBd0JMLFdBQXhCOztBQUNBLE1BQUlFLEtBQUosRUFBVztBQUNURSx1QkFBUUYsS0FBUixDQUFjQSxLQUFkO0FBQ0Q7O0FBQ0QsTUFBSUQsSUFBSixFQUFVO0FBQ1JHLHVCQUFRRSxFQUFSLENBQVcsUUFBWCxFQUFxQkwsSUFBckI7QUFDRDs7QUFDREcscUJBQVFHLEtBQVIsQ0FBY0MsT0FBTyxDQUFDQyxJQUF0QixFQUE0QkQsT0FBTyxDQUFDRSxHQUFwQzs7QUFFQSxRQUFNckIsT0FBTyxHQUFHZSxtQkFBUU8sVUFBUixFQUFoQjs7QUFDQVIsRUFBQUEsS0FBSyxDQUFDQyxrQkFBRCxFQUFVZixPQUFWLEVBQW1CLFlBQVk7QUFDbENELElBQUFBLGlCQUFpQixDQUFDQyxPQUFELENBQWpCO0FBQ0QsR0FGSSxDQUFMO0FBR0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcHJvZ3JhbSBmcm9tICcuL2NvbW1hbmRlcic7XG5cbmZ1bmN0aW9uIGxvZ1N0YXJ0dXBPcHRpb25zKG9wdGlvbnMpIHtcbiAgZm9yIChjb25zdCBrZXkgaW4gb3B0aW9ucykge1xuICAgIGxldCB2YWx1ZSA9IG9wdGlvbnNba2V5XTtcbiAgICBpZiAoa2V5ID09ICdtYXN0ZXJLZXknKSB7XG4gICAgICB2YWx1ZSA9ICcqKipSRURBQ1RFRCoqKic7XG4gICAgfVxuICAgIGlmIChrZXkgPT0gJ3B1c2gnICYmIG9wdGlvbnMudmVyYm9zZSAhPSB0cnVlKSB7XG4gICAgICB2YWx1ZSA9ICcqKipSRURBQ1RFRCoqKic7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICB0cnkge1xuICAgICAgICB2YWx1ZSA9IEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKHZhbHVlICYmIHZhbHVlLmNvbnN0cnVjdG9yICYmIHZhbHVlLmNvbnN0cnVjdG9yLm5hbWUpIHtcbiAgICAgICAgICB2YWx1ZSA9IHZhbHVlLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuICAgIGNvbnNvbGUubG9nKGAke2tleX06ICR7dmFsdWV9YCk7XG4gICAgLyogZXNsaW50LWVuYWJsZSBuby1jb25zb2xlICovXG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHsgZGVmaW5pdGlvbnMsIGhlbHAsIHVzYWdlLCBzdGFydCB9KSB7XG4gIHByb2dyYW0ubG9hZERlZmluaXRpb25zKGRlZmluaXRpb25zKTtcbiAgaWYgKHVzYWdlKSB7XG4gICAgcHJvZ3JhbS51c2FnZSh1c2FnZSk7XG4gIH1cbiAgaWYgKGhlbHApIHtcbiAgICBwcm9ncmFtLm9uKCctLWhlbHAnLCBoZWxwKTtcbiAgfVxuICBwcm9ncmFtLnBhcnNlKHByb2Nlc3MuYXJndiwgcHJvY2Vzcy5lbnYpO1xuXG4gIGNvbnN0IG9wdGlvbnMgPSBwcm9ncmFtLmdldE9wdGlvbnMoKTtcbiAgc3RhcnQocHJvZ3JhbSwgb3B0aW9ucywgZnVuY3Rpb24gKCkge1xuICAgIGxvZ1N0YXJ0dXBPcHRpb25zKG9wdGlvbnMpO1xuICB9KTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/cloud-code/HTTPResponse.js b/lib/cloud-code/HTTPResponse.js new file mode 100644 index 0000000000..0bcf174da1 --- /dev/null +++ b/lib/cloud-code/HTTPResponse.js @@ -0,0 +1,73 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +/** + * @typedef Parse.Cloud.HTTPResponse + * @property {Buffer} buffer The raw byte representation of the response body. Use this to receive binary data. See Buffer for more details. + * @property {Object} cookies The cookies sent by the server. The keys in this object are the names of the cookies. The values are Parse.Cloud.Cookie objects. + * @property {Object} data The parsed response body as a JavaScript object. This is only available when the response Content-Type is application/x-www-form-urlencoded or application/json. + * @property {Object} headers The headers sent by the server. The keys in this object are the names of the headers. We do not support multiple response headers with the same name. In the common case of Set-Cookie headers, please use the cookies field instead. + * @property {Number} status The status code. + * @property {String} text The raw text representation of the response body. + */ +class HTTPResponse { + constructor(response, body) { + let _text, _data; + + this.status = response.statusCode; + this.headers = response.headers || {}; + this.cookies = this.headers['set-cookie']; + + if (typeof body == 'string') { + _text = body; + } else if (Buffer.isBuffer(body)) { + this.buffer = body; + } else if (typeof body == 'object') { + _data = body; + } + + const getText = () => { + if (!_text && this.buffer) { + _text = this.buffer.toString('utf-8'); + } else if (!_text && _data) { + _text = JSON.stringify(_data); + } + + return _text; + }; + + const getData = () => { + if (!_data) { + try { + _data = JSON.parse(getText()); + } catch (e) { + /* */ + } + } + + return _data; + }; + + Object.defineProperty(this, 'body', { + get: () => { + return body; + } + }); + Object.defineProperty(this, 'text', { + enumerable: true, + get: getText + }); + Object.defineProperty(this, 'data', { + enumerable: true, + get: getData + }); + } + +} + +exports.default = HTTPResponse; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbG91ZC1jb2RlL0hUVFBSZXNwb25zZS5qcyJdLCJuYW1lcyI6WyJIVFRQUmVzcG9uc2UiLCJjb25zdHJ1Y3RvciIsInJlc3BvbnNlIiwiYm9keSIsIl90ZXh0IiwiX2RhdGEiLCJzdGF0dXMiLCJzdGF0dXNDb2RlIiwiaGVhZGVycyIsImNvb2tpZXMiLCJCdWZmZXIiLCJpc0J1ZmZlciIsImJ1ZmZlciIsImdldFRleHQiLCJ0b1N0cmluZyIsIkpTT04iLCJzdHJpbmdpZnkiLCJnZXREYXRhIiwicGFyc2UiLCJlIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXQiLCJlbnVtZXJhYmxlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2UsTUFBTUEsWUFBTixDQUFtQjtBQUNoQ0MsRUFBQUEsV0FBVyxDQUFDQyxRQUFELEVBQVdDLElBQVgsRUFBaUI7QUFDMUIsUUFBSUMsS0FBSixFQUFXQyxLQUFYOztBQUNBLFNBQUtDLE1BQUwsR0FBY0osUUFBUSxDQUFDSyxVQUF2QjtBQUNBLFNBQUtDLE9BQUwsR0FBZU4sUUFBUSxDQUFDTSxPQUFULElBQW9CLEVBQW5DO0FBQ0EsU0FBS0MsT0FBTCxHQUFlLEtBQUtELE9BQUwsQ0FBYSxZQUFiLENBQWY7O0FBRUEsUUFBSSxPQUFPTCxJQUFQLElBQWUsUUFBbkIsRUFBNkI7QUFDM0JDLE1BQUFBLEtBQUssR0FBR0QsSUFBUjtBQUNELEtBRkQsTUFFTyxJQUFJTyxNQUFNLENBQUNDLFFBQVAsQ0FBZ0JSLElBQWhCLENBQUosRUFBMkI7QUFDaEMsV0FBS1MsTUFBTCxHQUFjVCxJQUFkO0FBQ0QsS0FGTSxNQUVBLElBQUksT0FBT0EsSUFBUCxJQUFlLFFBQW5CLEVBQTZCO0FBQ2xDRSxNQUFBQSxLQUFLLEdBQUdGLElBQVI7QUFDRDs7QUFFRCxVQUFNVSxPQUFPLEdBQUcsTUFBTTtBQUNwQixVQUFJLENBQUNULEtBQUQsSUFBVSxLQUFLUSxNQUFuQixFQUEyQjtBQUN6QlIsUUFBQUEsS0FBSyxHQUFHLEtBQUtRLE1BQUwsQ0FBWUUsUUFBWixDQUFxQixPQUFyQixDQUFSO0FBQ0QsT0FGRCxNQUVPLElBQUksQ0FBQ1YsS0FBRCxJQUFVQyxLQUFkLEVBQXFCO0FBQzFCRCxRQUFBQSxLQUFLLEdBQUdXLElBQUksQ0FBQ0MsU0FBTCxDQUFlWCxLQUFmLENBQVI7QUFDRDs7QUFDRCxhQUFPRCxLQUFQO0FBQ0QsS0FQRDs7QUFTQSxVQUFNYSxPQUFPLEdBQUcsTUFBTTtBQUNwQixVQUFJLENBQUNaLEtBQUwsRUFBWTtBQUNWLFlBQUk7QUFDRkEsVUFBQUEsS0FBSyxHQUFHVSxJQUFJLENBQUNHLEtBQUwsQ0FBV0wsT0FBTyxFQUFsQixDQUFSO0FBQ0QsU0FGRCxDQUVFLE9BQU9NLENBQVAsRUFBVTtBQUNWO0FBQ0Q7QUFDRjs7QUFDRCxhQUFPZCxLQUFQO0FBQ0QsS0FURDs7QUFXQWUsSUFBQUEsTUFBTSxDQUFDQyxjQUFQLENBQXNCLElBQXRCLEVBQTRCLE1BQTVCLEVBQW9DO0FBQ2xDQyxNQUFBQSxHQUFHLEVBQUUsTUFBTTtBQUNULGVBQU9uQixJQUFQO0FBQ0Q7QUFIaUMsS0FBcEM7QUFNQWlCLElBQUFBLE1BQU0sQ0FBQ0MsY0FBUCxDQUFzQixJQUF0QixFQUE0QixNQUE1QixFQUFvQztBQUNsQ0UsTUFBQUEsVUFBVSxFQUFFLElBRHNCO0FBRWxDRCxNQUFBQSxHQUFHLEVBQUVUO0FBRjZCLEtBQXBDO0FBS0FPLElBQUFBLE1BQU0sQ0FBQ0MsY0FBUCxDQUFzQixJQUF0QixFQUE0QixNQUE1QixFQUFvQztBQUNsQ0UsTUFBQUEsVUFBVSxFQUFFLElBRHNCO0FBRWxDRCxNQUFBQSxHQUFHLEVBQUVMO0FBRjZCLEtBQXBDO0FBSUQ7O0FBbEQrQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQHR5cGVkZWYgUGFyc2UuQ2xvdWQuSFRUUFJlc3BvbnNlXG4gKiBAcHJvcGVydHkge0J1ZmZlcn0gYnVmZmVyIFRoZSByYXcgYnl0ZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgcmVzcG9uc2UgYm9keS4gVXNlIHRoaXMgdG8gcmVjZWl2ZSBiaW5hcnkgZGF0YS4gU2VlIEJ1ZmZlciBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHByb3BlcnR5IHtPYmplY3R9IGNvb2tpZXMgVGhlIGNvb2tpZXMgc2VudCBieSB0aGUgc2VydmVyLiBUaGUga2V5cyBpbiB0aGlzIG9iamVjdCBhcmUgdGhlIG5hbWVzIG9mIHRoZSBjb29raWVzLiBUaGUgdmFsdWVzIGFyZSBQYXJzZS5DbG91ZC5Db29raWUgb2JqZWN0cy5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBkYXRhIFRoZSBwYXJzZWQgcmVzcG9uc2UgYm9keSBhcyBhIEphdmFTY3JpcHQgb2JqZWN0LiBUaGlzIGlzIG9ubHkgYXZhaWxhYmxlIHdoZW4gdGhlIHJlc3BvbnNlIENvbnRlbnQtVHlwZSBpcyBhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQgb3IgYXBwbGljYXRpb24vanNvbi5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBoZWFkZXJzIFRoZSBoZWFkZXJzIHNlbnQgYnkgdGhlIHNlcnZlci4gVGhlIGtleXMgaW4gdGhpcyBvYmplY3QgYXJlIHRoZSBuYW1lcyBvZiB0aGUgaGVhZGVycy4gV2UgZG8gbm90IHN1cHBvcnQgbXVsdGlwbGUgcmVzcG9uc2UgaGVhZGVycyB3aXRoIHRoZSBzYW1lIG5hbWUuIEluIHRoZSBjb21tb24gY2FzZSBvZiBTZXQtQ29va2llIGhlYWRlcnMsIHBsZWFzZSB1c2UgdGhlIGNvb2tpZXMgZmllbGQgaW5zdGVhZC5cbiAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBzdGF0dXMgVGhlIHN0YXR1cyBjb2RlLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IHRleHQgVGhlIHJhdyB0ZXh0IHJlcHJlc2VudGF0aW9uIG9mIHRoZSByZXNwb25zZSBib2R5LlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBIVFRQUmVzcG9uc2Uge1xuICBjb25zdHJ1Y3RvcihyZXNwb25zZSwgYm9keSkge1xuICAgIGxldCBfdGV4dCwgX2RhdGE7XG4gICAgdGhpcy5zdGF0dXMgPSByZXNwb25zZS5zdGF0dXNDb2RlO1xuICAgIHRoaXMuaGVhZGVycyA9IHJlc3BvbnNlLmhlYWRlcnMgfHwge307XG4gICAgdGhpcy5jb29raWVzID0gdGhpcy5oZWFkZXJzWydzZXQtY29va2llJ107XG5cbiAgICBpZiAodHlwZW9mIGJvZHkgPT0gJ3N0cmluZycpIHtcbiAgICAgIF90ZXh0ID0gYm9keTtcbiAgICB9IGVsc2UgaWYgKEJ1ZmZlci5pc0J1ZmZlcihib2R5KSkge1xuICAgICAgdGhpcy5idWZmZXIgPSBib2R5O1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGJvZHkgPT0gJ29iamVjdCcpIHtcbiAgICAgIF9kYXRhID0gYm9keTtcbiAgICB9XG5cbiAgICBjb25zdCBnZXRUZXh0ID0gKCkgPT4ge1xuICAgICAgaWYgKCFfdGV4dCAmJiB0aGlzLmJ1ZmZlcikge1xuICAgICAgICBfdGV4dCA9IHRoaXMuYnVmZmVyLnRvU3RyaW5nKCd1dGYtOCcpO1xuICAgICAgfSBlbHNlIGlmICghX3RleHQgJiYgX2RhdGEpIHtcbiAgICAgICAgX3RleHQgPSBKU09OLnN0cmluZ2lmeShfZGF0YSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gX3RleHQ7XG4gICAgfTtcblxuICAgIGNvbnN0IGdldERhdGEgPSAoKSA9PiB7XG4gICAgICBpZiAoIV9kYXRhKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgX2RhdGEgPSBKU09OLnBhcnNlKGdldFRleHQoKSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAvKiAqL1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gX2RhdGE7XG4gICAgfTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnYm9keScsIHtcbiAgICAgIGdldDogKCkgPT4ge1xuICAgICAgICByZXR1cm4gYm9keTtcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3RleHQnLCB7XG4gICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgZ2V0OiBnZXRUZXh0LFxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdkYXRhJywge1xuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIGdldDogZ2V0RGF0YSxcbiAgICB9KTtcbiAgfVxufVxuIl19 \ No newline at end of file diff --git a/lib/cloud-code/Parse.Cloud.js b/lib/cloud-code/Parse.Cloud.js new file mode 100644 index 0000000000..11bf1def54 --- /dev/null +++ b/lib/cloud-code/Parse.Cloud.js @@ -0,0 +1,719 @@ +"use strict"; + +var _node = require("parse/node"); + +var triggers = _interopRequireWildcard(require("../triggers")); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +const Config = require('../Config'); + +function isParseObjectConstructor(object) { + return typeof object === 'function' && Object.prototype.hasOwnProperty.call(object, 'className'); +} + +function getClassName(parseClass) { + if (parseClass && parseClass.className) { + return parseClass.className; + } + + return parseClass; +} +/** @namespace + * @name Parse + * @description The Parse SDK. + * see [api docs](https://docs.parseplatform.org/js/api) and [guide](https://docs.parseplatform.org/js/guide) + */ + +/** @namespace + * @name Parse.Cloud + * @memberof Parse + * @description The Parse Cloud Code SDK. + */ + + +var ParseCloud = {}; +/** + * Defines a Cloud Function. + * + * **Available in Cloud Code only.** + * + * ``` + * Parse.Cloud.define('functionName', (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.define('functionName', (request) => { + * // code here + * }, { ...validationObject }); + * ``` + * + * @static + * @memberof Parse.Cloud + * @param {String} name The name of the Cloud Function + * @param {Function} data The Cloud Function to register. This function can be an async function and should take one parameter a {@link Parse.Cloud.FunctionRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FunctionRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + +ParseCloud.define = function (functionName, handler, validationHandler) { + triggers.addFunction(functionName, handler, validationHandler, _node.Parse.applicationId); +}; +/** + * Defines a Background Job. + * + * **Available in Cloud Code only.** + * + * @method job + * @name Parse.Cloud.job + * @param {String} name The name of the Background Job + * @param {Function} func The Background Job to register. This function can be async should take a single parameters a {@link Parse.Cloud.JobRequest} + * + */ + + +ParseCloud.job = function (functionName, handler) { + triggers.addJob(functionName, handler, _node.Parse.applicationId); +}; +/** + * + * Registers a before save function. + * + * **Available in Cloud Code only.** + * + * If you want to use beforeSave for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. + * + * ``` + * Parse.Cloud.beforeSave('MyCustomClass', (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.beforeSave(Parse.User, (request) => { + * // code here + * }, { ...validationObject }) + * ``` + * + * @method beforeSave + * @name Parse.Cloud.beforeSave + * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after save function for. This can instead be a String that is the className of the subclass. + * @param {Function} func The function to run before a save. This function can be async and should take one parameter a {@link Parse.Cloud.TriggerRequest}; + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.beforeSave = function (parseClass, handler, validationHandler) { + var className = getClassName(parseClass); + triggers.addTrigger(triggers.Types.beforeSave, className, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Registers a before delete function. + * + * **Available in Cloud Code only.** + * + * If you want to use beforeDelete for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. + * ``` + * Parse.Cloud.beforeDelete('MyCustomClass', (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.beforeDelete(Parse.User, (request) => { + * // code here + * }, { ...validationObject }) + *``` + * + * @method beforeDelete + * @name Parse.Cloud.beforeDelete + * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the before delete function for. This can instead be a String that is the className of the subclass. + * @param {Function} func The function to run before a delete. This function can be async and should take one parameter, a {@link Parse.Cloud.TriggerRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.beforeDelete = function (parseClass, handler, validationHandler) { + var className = getClassName(parseClass); + triggers.addTrigger(triggers.Types.beforeDelete, className, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * + * Registers the before login function. + * + * **Available in Cloud Code only.** + * + * This function provides further control + * in validating a login attempt. Specifically, + * it is triggered after a user enters + * correct credentials (or other valid authData), + * but prior to a session being generated. + * + * ``` + * Parse.Cloud.beforeLogin((request) => { + * // code here + * }) + * + * ``` + * + * @method beforeLogin + * @name Parse.Cloud.beforeLogin + * @param {Function} func The function to run before a login. This function can be async and should take one parameter a {@link Parse.Cloud.TriggerRequest}; + */ + + +ParseCloud.beforeLogin = function (handler) { + let className = '_User'; + + if (typeof handler === 'string' || isParseObjectConstructor(handler)) { + // validation will occur downstream, this is to maintain internal + // code consistency with the other hook types. + className = getClassName(handler); + handler = arguments[1]; + } + + triggers.addTrigger(triggers.Types.beforeLogin, className, handler, _node.Parse.applicationId); +}; +/** + * + * Registers the after login function. + * + * **Available in Cloud Code only.** + * + * This function is triggered after a user logs in successfully, + * and after a _Session object has been created. + * + * ``` + * Parse.Cloud.afterLogin((request) => { + * // code here + * }); + * ``` + * + * @method afterLogin + * @name Parse.Cloud.afterLogin + * @param {Function} func The function to run after a login. This function can be async and should take one parameter a {@link Parse.Cloud.TriggerRequest}; + */ + + +ParseCloud.afterLogin = function (handler) { + let className = '_User'; + + if (typeof handler === 'string' || isParseObjectConstructor(handler)) { + // validation will occur downstream, this is to maintain internal + // code consistency with the other hook types. + className = getClassName(handler); + handler = arguments[1]; + } + + triggers.addTrigger(triggers.Types.afterLogin, className, handler, _node.Parse.applicationId); +}; +/** + * + * Registers the after logout function. + * + * **Available in Cloud Code only.** + * + * This function is triggered after a user logs out. + * + * ``` + * Parse.Cloud.afterLogout((request) => { + * // code here + * }); + * ``` + * + * @method afterLogout + * @name Parse.Cloud.afterLogout + * @param {Function} func The function to run after a logout. This function can be async and should take one parameter a {@link Parse.Cloud.TriggerRequest}; + */ + + +ParseCloud.afterLogout = function (handler) { + let className = '_Session'; + + if (typeof handler === 'string' || isParseObjectConstructor(handler)) { + // validation will occur downstream, this is to maintain internal + // code consistency with the other hook types. + className = getClassName(handler); + handler = arguments[1]; + } + + triggers.addTrigger(triggers.Types.afterLogout, className, handler, _node.Parse.applicationId); +}; +/** + * Registers an after save function. + * + * **Available in Cloud Code only.** + * + * If you want to use afterSave for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. + * + * ``` + * Parse.Cloud.afterSave('MyCustomClass', async function(request) { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.afterSave(Parse.User, async function(request) { + * // code here + * }, { ...validationObject }); + * ``` + * + * @method afterSave + * @name Parse.Cloud.afterSave + * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after save function for. This can instead be a String that is the className of the subclass. + * @param {Function} func The function to run after a save. This function can be an async function and should take just one parameter, {@link Parse.Cloud.TriggerRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.afterSave = function (parseClass, handler, validationHandler) { + var className = getClassName(parseClass); + triggers.addTrigger(triggers.Types.afterSave, className, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Registers an after delete function. + * + * **Available in Cloud Code only.** + * + * If you want to use afterDelete for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. + * ``` + * Parse.Cloud.afterDelete('MyCustomClass', async (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.afterDelete(Parse.User, async (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method afterDelete + * @name Parse.Cloud.afterDelete + * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after delete function for. This can instead be a String that is the className of the subclass. + * @param {Function} func The function to run after a delete. This function can be async and should take just one parameter, {@link Parse.Cloud.TriggerRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.afterDelete = function (parseClass, handler, validationHandler) { + var className = getClassName(parseClass); + triggers.addTrigger(triggers.Types.afterDelete, className, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Registers a before find function. + * + * **Available in Cloud Code only.** + * + * If you want to use beforeFind for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. + * ``` + * Parse.Cloud.beforeFind('MyCustomClass', async (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.beforeFind(Parse.User, async (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method beforeFind + * @name Parse.Cloud.beforeFind + * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the before find function for. This can instead be a String that is the className of the subclass. + * @param {Function} func The function to run before a find. This function can be async and should take just one parameter, {@link Parse.Cloud.BeforeFindRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.BeforeFindRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.beforeFind = function (parseClass, handler, validationHandler) { + var className = getClassName(parseClass); + triggers.addTrigger(triggers.Types.beforeFind, className, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Registers an after find function. + * + * **Available in Cloud Code only.** + * + * If you want to use afterFind for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. + * ``` + * Parse.Cloud.afterFind('MyCustomClass', async (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.afterFind(Parse.User, async (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method afterFind + * @name Parse.Cloud.afterFind + * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after find function for. This can instead be a String that is the className of the subclass. + * @param {Function} func The function to run before a find. This function can be async and should take just one parameter, {@link Parse.Cloud.AfterFindRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.AfterFindRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.afterFind = function (parseClass, handler, validationHandler) { + const className = getClassName(parseClass); + triggers.addTrigger(triggers.Types.afterFind, className, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Registers a before save file function. + * + * **Available in Cloud Code only.** + * + * ``` + * Parse.Cloud.beforeSaveFile(async (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.beforeSaveFile(async (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method beforeSaveFile + * @name Parse.Cloud.beforeSaveFile + * @param {Function} func The function to run before saving a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.beforeSaveFile = function (handler, validationHandler) { + triggers.addFileTrigger(triggers.Types.beforeSaveFile, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Registers an after save file function. + * + * **Available in Cloud Code only.** + * + * ``` + * Parse.Cloud.afterSaveFile(async (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.afterSaveFile(async (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method afterSaveFile + * @name Parse.Cloud.afterSaveFile + * @param {Function} func The function to run after saving a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.afterSaveFile = function (handler, validationHandler) { + triggers.addFileTrigger(triggers.Types.afterSaveFile, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Registers a before delete file function. + * + * **Available in Cloud Code only.** + * + * ``` + * Parse.Cloud.beforeDeleteFile(async (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.beforeDeleteFile(async (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method beforeDeleteFile + * @name Parse.Cloud.beforeDeleteFile + * @param {Function} func The function to run before deleting a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.beforeDeleteFile = function (handler, validationHandler) { + triggers.addFileTrigger(triggers.Types.beforeDeleteFile, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Registers an after delete file function. + * + * **Available in Cloud Code only.** + * + * ``` + * Parse.Cloud.afterDeleteFile(async (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.afterDeleteFile(async (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method afterDeleteFile + * @name Parse.Cloud.afterDeleteFile + * @param {Function} func The function to after before deleting a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.afterDeleteFile = function (handler, validationHandler) { + triggers.addFileTrigger(triggers.Types.afterDeleteFile, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Registers a before live query server connect function. + * + * **Available in Cloud Code only.** + * + * ``` + * Parse.Cloud.beforeConnect(async (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.beforeConnect(async (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method beforeConnect + * @name Parse.Cloud.beforeConnect + * @param {Function} func The function to before connection is made. This function can be async and should take just one parameter, {@link Parse.Cloud.ConnectTriggerRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.ConnectTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.beforeConnect = function (handler, validationHandler) { + triggers.addConnectTrigger(triggers.Types.beforeConnect, handler, _node.Parse.applicationId, validationHandler); +}; +/** + * Sends an email through the Parse Server mail adapter. + * + * **Available in Cloud Code only.** + * **Requires a mail adapter to be configured for Parse Server.** + * + * ``` + * Parse.Cloud.sendEmail({ + * from: 'Example ', + * to: 'contact@example.com', + * subject: 'Test email', + * text: 'This email is a test.' + * }); + *``` + * + * @method sendEmail + * @name Parse.Cloud.sendEmail + * @param {Object} data The object of the mail data to send. + */ + + +ParseCloud.sendEmail = function (data) { + const config = Config.get(_node.Parse.applicationId); + const emailAdapter = config.userController.adapter; + + if (!emailAdapter) { + config.loggerController.error('Failed to send email because no mail adapter is configured for Parse Server.'); + return; + } + + return emailAdapter.sendMail(data); +}; +/** + * Registers a before live query subscription function. + * + * **Available in Cloud Code only.** + * + * If you want to use beforeSubscribe for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. + * ``` + * Parse.Cloud.beforeSubscribe('MyCustomClass', (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.beforeSubscribe(Parse.User, (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method beforeSubscribe + * @name Parse.Cloud.beforeSubscribe + * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the before subscription function for. This can instead be a String that is the className of the subclass. + * @param {Function} func The function to run before a subscription. This function can be async and should take one parameter, a {@link Parse.Cloud.TriggerRequest}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.beforeSubscribe = function (parseClass, handler, validationHandler) { + var className = getClassName(parseClass); + triggers.addTrigger(triggers.Types.beforeSubscribe, className, handler, _node.Parse.applicationId, validationHandler); +}; + +ParseCloud.onLiveQueryEvent = function (handler) { + triggers.addLiveQueryEventHandler(handler, _node.Parse.applicationId); +}; +/** + * Registers an after live query server event function. + * + * **Available in Cloud Code only.** + * + * ``` + * Parse.Cloud.afterLiveQueryEvent('MyCustomClass', (request) => { + * // code here + * }, (request) => { + * // validation code here + * }); + * + * Parse.Cloud.afterLiveQueryEvent('MyCustomClass', (request) => { + * // code here + * }, { ...validationObject }); + *``` + * + * @method afterLiveQueryEvent + * @name Parse.Cloud.afterLiveQueryEvent + * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after live query event function for. This can instead be a String that is the className of the subclass. + * @param {Function} func The function to run after a live query event. This function can be async and should take one parameter, a {@link Parse.Cloud.LiveQueryEventTrigger}. + * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.LiveQueryEventTrigger}, or a {@link Parse.Cloud.ValidatorObject}. + */ + + +ParseCloud.afterLiveQueryEvent = function (parseClass, handler, validationHandler) { + const className = getClassName(parseClass); + triggers.addTrigger(triggers.Types.afterEvent, className, handler, _node.Parse.applicationId, validationHandler); +}; + +ParseCloud._removeAllHooks = () => { + triggers._unregisterAll(); +}; + +ParseCloud.useMasterKey = () => { + // eslint-disable-next-line + console.warn('Parse.Cloud.useMasterKey is deprecated (and has no effect anymore) on parse-server, please refer to the cloud code migration notes: http://docs.parseplatform.org/parse-server/guide/#master-key-must-be-passed-explicitly'); +}; + +ParseCloud.httpRequest = require('./httpRequest'); +module.exports = ParseCloud; +/** + * @interface Parse.Cloud.TriggerRequest + * @property {String} installationId If set, the installationId triggering the request. + * @property {Boolean} master If true, means the master key was used. + * @property {Parse.User} user If set, the user that made the request. + * @property {Parse.Object} object The object triggering the hook. + * @property {String} ip The IP address of the client making the request. + * @property {Object} headers The original HTTP headers for the request. + * @property {String} triggerName The name of the trigger (`beforeSave`, `afterSave`, ...) + * @property {Object} log The current logger inside Parse Server. + * @property {Parse.Object} original If set, the object, as currently stored. + */ + +/** + * @interface Parse.Cloud.FileTriggerRequest + * @property {String} installationId If set, the installationId triggering the request. + * @property {Boolean} master If true, means the master key was used. + * @property {Parse.User} user If set, the user that made the request. + * @property {Parse.File} file The file that triggered the hook. + * @property {Integer} fileSize The size of the file in bytes. + * @property {Integer} contentLength The value from Content-Length header + * @property {String} ip The IP address of the client making the request. + * @property {Object} headers The original HTTP headers for the request. + * @property {String} triggerName The name of the trigger (`beforeSaveFile`, `afterSaveFile`) + * @property {Object} log The current logger inside Parse Server. + */ + +/** + * @interface Parse.Cloud.ConnectTriggerRequest + * @property {String} installationId If set, the installationId triggering the request. + * @property {Boolean} useMasterKey If true, means the master key was used. + * @property {Parse.User} user If set, the user that made the request. + * @property {Integer} clients The number of clients connected. + * @property {Integer} subscriptions The number of subscriptions connected. + * @property {String} sessionToken If set, the session of the user that made the request. + */ + +/** + * @interface Parse.Cloud.LiveQueryEventTrigger + * @property {String} installationId If set, the installationId triggering the request. + * @property {Boolean} useMasterKey If true, means the master key was used. + * @property {Parse.User} user If set, the user that made the request. + * @property {String} sessionToken If set, the session of the user that made the request. + * @property {String} event The live query event that triggered the request. + * @property {Parse.Object} object The object triggering the hook. + * @property {Parse.Object} original If set, the object, as currently stored. + * @property {Integer} clients The number of clients connected. + * @property {Integer} subscriptions The number of subscriptions connected. + * @property {Boolean} sendEvent If the LiveQuery event should be sent to the client. Set to false to prevent LiveQuery from pushing to the client. + */ + +/** + * @interface Parse.Cloud.BeforeFindRequest + * @property {String} installationId If set, the installationId triggering the request. + * @property {Boolean} master If true, means the master key was used. + * @property {Parse.User} user If set, the user that made the request. + * @property {Parse.Query} query The query triggering the hook. + * @property {String} ip The IP address of the client making the request. + * @property {Object} headers The original HTTP headers for the request. + * @property {String} triggerName The name of the trigger (`beforeSave`, `afterSave`, ...) + * @property {Object} log The current logger inside Parse Server. + * @property {Boolean} isGet wether the query a `get` or a `find` + */ + +/** + * @interface Parse.Cloud.AfterFindRequest + * @property {String} installationId If set, the installationId triggering the request. + * @property {Boolean} master If true, means the master key was used. + * @property {Parse.User} user If set, the user that made the request. + * @property {Parse.Query} query The query triggering the hook. + * @property {Array} results The results the query yielded. + * @property {String} ip The IP address of the client making the request. + * @property {Object} headers The original HTTP headers for the request. + * @property {String} triggerName The name of the trigger (`beforeSave`, `afterSave`, ...) + * @property {Object} log The current logger inside Parse Server. + */ + +/** + * @interface Parse.Cloud.FunctionRequest + * @property {String} installationId If set, the installationId triggering the request. + * @property {Boolean} master If true, means the master key was used. + * @property {Parse.User} user If set, the user that made the request. + * @property {Object} params The params passed to the cloud function. + */ + +/** + * @interface Parse.Cloud.JobRequest + * @property {Object} params The params passed to the background job. + * @property {function} message If message is called with a string argument, will update the current message to be stored in the job status. + */ + +/** + * @interface Parse.Cloud.ValidatorObject + * @property {Boolean} requireUser whether the cloud trigger requires a user. + * @property {Boolean} requireMaster whether the cloud trigger requires a master key. + * @property {Boolean} validateMasterKey whether the validator should run if masterKey is provided. Defaults to false. + * @property {Boolean} skipWithMasterKey whether the cloud code function should be ignored using a masterKey. + * + * @property {Array|Object} requireUserKeys If set, keys required on request.user to make the request. + * @property {String} requireUserKeys.field If requireUserKeys is an object, name of field to validate on request user + * @property {Array|function|Any} requireUserKeys.field.options array of options that the field can be, function to validate field, or single value. Throw an error if value is invalid. + * @property {String} requireUserKeys.field.error custom error message if field is invalid. + * + * @property {Object|Array} fields if an array of strings, validator will look for keys in request.params, and throw if not provided. If Object, fields to validate. If the trigger is a cloud function, `request.params` will be validated, otherwise `request.object`. + * @property {String} fields.field name of field to validate. + * @property {String} fields.field.type expected type of data for field. + * @property {Boolean} fields.field.constant whether the field can be modified on the object. + * @property {Any} fields.field.default default value if field is `null`, or initial value `constant` is `true`. + * @property {Array|function|Any} fields.field.options array of options that the field can be, function to validate field, or single value. Throw an error if value is invalid. + * @property {String} fields.field.error custom error message if field is invalid. + */ +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbG91ZC1jb2RlL1BhcnNlLkNsb3VkLmpzIl0sIm5hbWVzIjpbIkNvbmZpZyIsInJlcXVpcmUiLCJpc1BhcnNlT2JqZWN0Q29uc3RydWN0b3IiLCJvYmplY3QiLCJPYmplY3QiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJnZXRDbGFzc05hbWUiLCJwYXJzZUNsYXNzIiwiY2xhc3NOYW1lIiwiUGFyc2VDbG91ZCIsImRlZmluZSIsImZ1bmN0aW9uTmFtZSIsImhhbmRsZXIiLCJ2YWxpZGF0aW9uSGFuZGxlciIsInRyaWdnZXJzIiwiYWRkRnVuY3Rpb24iLCJQYXJzZSIsImFwcGxpY2F0aW9uSWQiLCJqb2IiLCJhZGRKb2IiLCJiZWZvcmVTYXZlIiwiYWRkVHJpZ2dlciIsIlR5cGVzIiwiYmVmb3JlRGVsZXRlIiwiYmVmb3JlTG9naW4iLCJhcmd1bWVudHMiLCJhZnRlckxvZ2luIiwiYWZ0ZXJMb2dvdXQiLCJhZnRlclNhdmUiLCJhZnRlckRlbGV0ZSIsImJlZm9yZUZpbmQiLCJhZnRlckZpbmQiLCJiZWZvcmVTYXZlRmlsZSIsImFkZEZpbGVUcmlnZ2VyIiwiYWZ0ZXJTYXZlRmlsZSIsImJlZm9yZURlbGV0ZUZpbGUiLCJhZnRlckRlbGV0ZUZpbGUiLCJiZWZvcmVDb25uZWN0IiwiYWRkQ29ubmVjdFRyaWdnZXIiLCJzZW5kRW1haWwiLCJkYXRhIiwiY29uZmlnIiwiZ2V0IiwiZW1haWxBZGFwdGVyIiwidXNlckNvbnRyb2xsZXIiLCJhZGFwdGVyIiwibG9nZ2VyQ29udHJvbGxlciIsImVycm9yIiwic2VuZE1haWwiLCJiZWZvcmVTdWJzY3JpYmUiLCJvbkxpdmVRdWVyeUV2ZW50IiwiYWRkTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVyIiwiYWZ0ZXJMaXZlUXVlcnlFdmVudCIsImFmdGVyRXZlbnQiLCJfcmVtb3ZlQWxsSG9va3MiLCJfdW5yZWdpc3RlckFsbCIsInVzZU1hc3RlcktleSIsImNvbnNvbGUiLCJ3YXJuIiwi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cnNlIH0gZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgKiBhcyB0cmlnZ2VycyBmcm9tICcuLi90cmlnZ2Vycyc7XG5jb25zdCBDb25maWcgPSByZXF1aXJlKCcuLi9Db25maWcnKTtcblxuZnVuY3Rpb24gaXNQYXJzZU9iamVjdENvbnN0cnVjdG9yKG9iamVjdCkge1xuICByZXR1cm4gdHlwZW9mIG9iamVjdCA9PT0gJ2Z1bmN0aW9uJyAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCAnY2xhc3NOYW1lJyk7XG59XG5cbmZ1bmN0aW9uIGdldENsYXNzTmFtZShwYXJzZUNsYXNzKSB7XG4gIGlmIChwYXJzZUNsYXNzICYmIHBhcnNlQ2xhc3MuY2xhc3NOYW1lKSB7XG4gICAgcmV0dXJuIHBhcnNlQ2xhc3MuY2xhc3NOYW1lO1xuICB9XG4gIHJldHVybiBwYXJzZUNsYXNzO1xufVxuXG4vKiogQG5hbWVzcGFjZVxuICogQG5hbWUgUGFyc2VcbiAqIEBkZXNjcmlwdGlvbiBUaGUgUGFyc2UgU0RLLlxuICogIHNlZSBbYXBpIGRvY3NdKGh0dHBzOi8vZG9jcy5wYXJzZXBsYXRmb3JtLm9yZy9qcy9hcGkpIGFuZCBbZ3VpZGVdKGh0dHBzOi8vZG9jcy5wYXJzZXBsYXRmb3JtLm9yZy9qcy9ndWlkZSlcbiAqL1xuXG4vKiogQG5hbWVzcGFjZVxuICogQG5hbWUgUGFyc2UuQ2xvdWRcbiAqIEBtZW1iZXJvZiBQYXJzZVxuICogQGRlc2NyaXB0aW9uIFRoZSBQYXJzZSBDbG91ZCBDb2RlIFNESy5cbiAqL1xuXG52YXIgUGFyc2VDbG91ZCA9IHt9O1xuLyoqXG4gKiBEZWZpbmVzIGEgQ2xvdWQgRnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogYGBgXG4gKiBQYXJzZS5DbG91ZC5kZWZpbmUoJ2Z1bmN0aW9uTmFtZScsIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gdmFsaWRhdGlvbiBjb2RlIGhlcmVcbiAqIH0pO1xuICpcbiAqIFBhcnNlLkNsb3VkLmRlZmluZSgnZnVuY3Rpb25OYW1lJywgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCB7IC4uLnZhbGlkYXRpb25PYmplY3QgfSk7XG4gKiBgYGBcbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyb2YgUGFyc2UuQ2xvdWRcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBDbG91ZCBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZGF0YSBUaGUgQ2xvdWQgRnVuY3Rpb24gdG8gcmVnaXN0ZXIuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFuIGFzeW5jIGZ1bmN0aW9uIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLkZ1bmN0aW9uUmVxdWVzdH0uXG4gKiBAcGFyYW0geyhPYmplY3R8RnVuY3Rpb24pfSB2YWxpZGF0b3IgQW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gaGVscCB2YWxpZGF0aW5nIGNsb3VkIGNvZGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFuIGFzeW5jIGZ1bmN0aW9uIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLkZ1bmN0aW9uUmVxdWVzdH0sIG9yIGEge0BsaW5rIFBhcnNlLkNsb3VkLlZhbGlkYXRvck9iamVjdH0uXG4gKi9cblBhcnNlQ2xvdWQuZGVmaW5lID0gZnVuY3Rpb24gKGZ1bmN0aW9uTmFtZSwgaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgdHJpZ2dlcnMuYWRkRnVuY3Rpb24oZnVuY3Rpb25OYW1lLCBoYW5kbGVyLCB2YWxpZGF0aW9uSGFuZGxlciwgUGFyc2UuYXBwbGljYXRpb25JZCk7XG59O1xuXG4vKipcbiAqIERlZmluZXMgYSBCYWNrZ3JvdW5kIEpvYi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBAbWV0aG9kIGpvYlxuICogQG5hbWUgUGFyc2UuQ2xvdWQuam9iXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgQmFja2dyb3VuZCBKb2JcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIEJhY2tncm91bmQgSm9iIHRvIHJlZ2lzdGVyLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBzaG91bGQgdGFrZSBhIHNpbmdsZSBwYXJhbWV0ZXJzIGEge0BsaW5rIFBhcnNlLkNsb3VkLkpvYlJlcXVlc3R9XG4gKlxuICovXG5QYXJzZUNsb3VkLmpvYiA9IGZ1bmN0aW9uIChmdW5jdGlvbk5hbWUsIGhhbmRsZXIpIHtcbiAgdHJpZ2dlcnMuYWRkSm9iKGZ1bmN0aW9uTmFtZSwgaGFuZGxlciwgUGFyc2UuYXBwbGljYXRpb25JZCk7XG59O1xuXG4vKipcbiAqXG4gKiBSZWdpc3RlcnMgYSBiZWZvcmUgc2F2ZSBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBJZiB5b3Ugd2FudCB0byB1c2UgYmVmb3JlU2F2ZSBmb3IgYSBwcmVkZWZpbmVkIGNsYXNzIGluIHRoZSBQYXJzZSBKYXZhU2NyaXB0IFNESyAoZS5nLiB7QGxpbmsgUGFyc2UuVXNlcn0pLCB5b3Ugc2hvdWxkIHBhc3MgdGhlIGNsYXNzIGl0c2VsZiBhbmQgbm90IHRoZSBTdHJpbmcgZm9yIGFyZzEuXG4gKlxuICogYGBgXG4gKiBQYXJzZS5DbG91ZC5iZWZvcmVTYXZlKCdNeUN1c3RvbUNsYXNzJywgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYmVmb3JlU2F2ZShQYXJzZS5Vc2VyLCAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIHsgLi4udmFsaWRhdGlvbk9iamVjdCB9KVxuICogYGBgXG4gKlxuICogQG1ldGhvZCBiZWZvcmVTYXZlXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5iZWZvcmVTYXZlXG4gKiBAcGFyYW0geyhTdHJpbmd8UGFyc2UuT2JqZWN0KX0gYXJnMSBUaGUgUGFyc2UuT2JqZWN0IHN1YmNsYXNzIHRvIHJlZ2lzdGVyIHRoZSBhZnRlciBzYXZlIGZ1bmN0aW9uIGZvci4gVGhpcyBjYW4gaW5zdGVhZCBiZSBhIFN0cmluZyB0aGF0IGlzIHRoZSBjbGFzc05hbWUgb2YgdGhlIHN1YmNsYXNzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcnVuIGJlZm9yZSBhIHNhdmUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fTtcbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVHJpZ2dlclJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmJlZm9yZVNhdmUgPSBmdW5jdGlvbiAocGFyc2VDbGFzcywgaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgdmFyIGNsYXNzTmFtZSA9IGdldENsYXNzTmFtZShwYXJzZUNsYXNzKTtcbiAgdHJpZ2dlcnMuYWRkVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5iZWZvcmVTYXZlLFxuICAgIGNsYXNzTmFtZSxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgYmVmb3JlIGRlbGV0ZSBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBJZiB5b3Ugd2FudCB0byB1c2UgYmVmb3JlRGVsZXRlIGZvciBhIHByZWRlZmluZWQgY2xhc3MgaW4gdGhlIFBhcnNlIEphdmFTY3JpcHQgU0RLIChlLmcuIHtAbGluayBQYXJzZS5Vc2VyfSksIHlvdSBzaG91bGQgcGFzcyB0aGUgY2xhc3MgaXRzZWxmIGFuZCBub3QgdGhlIFN0cmluZyBmb3IgYXJnMS5cbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYmVmb3JlRGVsZXRlKCdNeUN1c3RvbUNsYXNzJywgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYmVmb3JlRGVsZXRlKFBhcnNlLlVzZXIsIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pXG4gKmBgYFxuICpcbiAqIEBtZXRob2QgYmVmb3JlRGVsZXRlXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5iZWZvcmVEZWxldGVcbiAqIEBwYXJhbSB7KFN0cmluZ3xQYXJzZS5PYmplY3QpfSBhcmcxIFRoZSBQYXJzZS5PYmplY3Qgc3ViY2xhc3MgdG8gcmVnaXN0ZXIgdGhlIGJlZm9yZSBkZWxldGUgZnVuY3Rpb24gZm9yLiBUaGlzIGNhbiBpbnN0ZWFkIGJlIGEgU3RyaW5nIHRoYXQgaXMgdGhlIGNsYXNzTmFtZSBvZiB0aGUgc3ViY2xhc3MuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYmVmb3JlIGEgZGVsZXRlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciwgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVHJpZ2dlclJlcXVlc3R9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5UcmlnZ2VyUmVxdWVzdH0sIG9yIGEge0BsaW5rIFBhcnNlLkNsb3VkLlZhbGlkYXRvck9iamVjdH0uXG4gKi9cblBhcnNlQ2xvdWQuYmVmb3JlRGVsZXRlID0gZnVuY3Rpb24gKHBhcnNlQ2xhc3MsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIHZhciBjbGFzc05hbWUgPSBnZXRDbGFzc05hbWUocGFyc2VDbGFzcyk7XG4gIHRyaWdnZXJzLmFkZFRyaWdnZXIoXG4gICAgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlRGVsZXRlLFxuICAgIGNsYXNzTmFtZSxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cbi8qKlxuICpcbiAqIFJlZ2lzdGVycyB0aGUgYmVmb3JlIGxvZ2luIGZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gcHJvdmlkZXMgZnVydGhlciBjb250cm9sXG4gKiBpbiB2YWxpZGF0aW5nIGEgbG9naW4gYXR0ZW1wdC4gU3BlY2lmaWNhbGx5LFxuICogaXQgaXMgdHJpZ2dlcmVkIGFmdGVyIGEgdXNlciBlbnRlcnNcbiAqIGNvcnJlY3QgY3JlZGVudGlhbHMgKG9yIG90aGVyIHZhbGlkIGF1dGhEYXRhKSxcbiAqIGJ1dCBwcmlvciB0byBhIHNlc3Npb24gYmVpbmcgZ2VuZXJhdGVkLlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYmVmb3JlTG9naW4oKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9KVxuICpcbiAqIGBgYFxuICpcbiAqIEBtZXRob2QgYmVmb3JlTG9naW5cbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmJlZm9yZUxvZ2luXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYmVmb3JlIGEgbG9naW4uIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fTtcbiAqL1xuUGFyc2VDbG91ZC5iZWZvcmVMb2dpbiA9IGZ1bmN0aW9uIChoYW5kbGVyKSB7XG4gIGxldCBjbGFzc05hbWUgPSAnX1VzZXInO1xuICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdzdHJpbmcnIHx8IGlzUGFyc2VPYmplY3RDb25zdHJ1Y3RvcihoYW5kbGVyKSkge1xuICAgIC8vIHZhbGlkYXRpb24gd2lsbCBvY2N1ciBkb3duc3RyZWFtLCB0aGlzIGlzIHRvIG1haW50YWluIGludGVybmFsXG4gICAgLy8gY29kZSBjb25zaXN0ZW5jeSB3aXRoIHRoZSBvdGhlciBob29rIHR5cGVzLlxuICAgIGNsYXNzTmFtZSA9IGdldENsYXNzTmFtZShoYW5kbGVyKTtcbiAgICBoYW5kbGVyID0gYXJndW1lbnRzWzFdO1xuICB9XG4gIHRyaWdnZXJzLmFkZFRyaWdnZXIodHJpZ2dlcnMuVHlwZXMuYmVmb3JlTG9naW4sIGNsYXNzTmFtZSwgaGFuZGxlciwgUGFyc2UuYXBwbGljYXRpb25JZCk7XG59O1xuXG4vKipcbiAqXG4gKiBSZWdpc3RlcnMgdGhlIGFmdGVyIGxvZ2luIGZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gaXMgdHJpZ2dlcmVkIGFmdGVyIGEgdXNlciBsb2dzIGluIHN1Y2Nlc3NmdWxseSxcbiAqIGFuZCBhZnRlciBhIF9TZXNzaW9uIG9iamVjdCBoYXMgYmVlbiBjcmVhdGVkLlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJMb2dpbigocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0pO1xuICogYGBgXG4gKlxuICogQG1ldGhvZCBhZnRlckxvZ2luXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5hZnRlckxvZ2luXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYWZ0ZXIgYSBsb2dpbi4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYXN5bmMgYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVHJpZ2dlclJlcXVlc3R9O1xuICovXG5QYXJzZUNsb3VkLmFmdGVyTG9naW4gPSBmdW5jdGlvbiAoaGFuZGxlcikge1xuICBsZXQgY2xhc3NOYW1lID0gJ19Vc2VyJztcbiAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSAnc3RyaW5nJyB8fCBpc1BhcnNlT2JqZWN0Q29uc3RydWN0b3IoaGFuZGxlcikpIHtcbiAgICAvLyB2YWxpZGF0aW9uIHdpbGwgb2NjdXIgZG93bnN0cmVhbSwgdGhpcyBpcyB0byBtYWludGFpbiBpbnRlcm5hbFxuICAgIC8vIGNvZGUgY29uc2lzdGVuY3kgd2l0aCB0aGUgb3RoZXIgaG9vayB0eXBlcy5cbiAgICBjbGFzc05hbWUgPSBnZXRDbGFzc05hbWUoaGFuZGxlcik7XG4gICAgaGFuZGxlciA9IGFyZ3VtZW50c1sxXTtcbiAgfVxuICB0cmlnZ2Vycy5hZGRUcmlnZ2VyKHRyaWdnZXJzLlR5cGVzLmFmdGVyTG9naW4sIGNsYXNzTmFtZSwgaGFuZGxlciwgUGFyc2UuYXBwbGljYXRpb25JZCk7XG59O1xuXG4vKipcbiAqXG4gKiBSZWdpc3RlcnMgdGhlIGFmdGVyIGxvZ291dCBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIHRyaWdnZXJlZCBhZnRlciBhIHVzZXIgbG9ncyBvdXQuXG4gKlxuICogYGBgXG4gKiBQYXJzZS5DbG91ZC5hZnRlckxvZ291dCgocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0pO1xuICogYGBgXG4gKlxuICogQG1ldGhvZCBhZnRlckxvZ291dFxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYWZ0ZXJMb2dvdXRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJ1biBhZnRlciBhIGxvZ291dC4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYXN5bmMgYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVHJpZ2dlclJlcXVlc3R9O1xuICovXG5QYXJzZUNsb3VkLmFmdGVyTG9nb3V0ID0gZnVuY3Rpb24gKGhhbmRsZXIpIHtcbiAgbGV0IGNsYXNzTmFtZSA9ICdfU2Vzc2lvbic7XG4gIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gJ3N0cmluZycgfHwgaXNQYXJzZU9iamVjdENvbnN0cnVjdG9yKGhhbmRsZXIpKSB7XG4gICAgLy8gdmFsaWRhdGlvbiB3aWxsIG9jY3VyIGRvd25zdHJlYW0sIHRoaXMgaXMgdG8gbWFpbnRhaW4gaW50ZXJuYWxcbiAgICAvLyBjb2RlIGNvbnNpc3RlbmN5IHdpdGggdGhlIG90aGVyIGhvb2sgdHlwZXMuXG4gICAgY2xhc3NOYW1lID0gZ2V0Q2xhc3NOYW1lKGhhbmRsZXIpO1xuICAgIGhhbmRsZXIgPSBhcmd1bWVudHNbMV07XG4gIH1cbiAgdHJpZ2dlcnMuYWRkVHJpZ2dlcih0cmlnZ2Vycy5UeXBlcy5hZnRlckxvZ291dCwgY2xhc3NOYW1lLCBoYW5kbGVyLCBQYXJzZS5hcHBsaWNhdGlvbklkKTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGFuIGFmdGVyIHNhdmUgZnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogSWYgeW91IHdhbnQgdG8gdXNlIGFmdGVyU2F2ZSBmb3IgYSBwcmVkZWZpbmVkIGNsYXNzIGluIHRoZSBQYXJzZSBKYXZhU2NyaXB0IFNESyAoZS5nLiB7QGxpbmsgUGFyc2UuVXNlcn0pLCB5b3Ugc2hvdWxkIHBhc3MgdGhlIGNsYXNzIGl0c2VsZiBhbmQgbm90IHRoZSBTdHJpbmcgZm9yIGFyZzEuXG4gKlxuICogYGBgXG4gKiBQYXJzZS5DbG91ZC5hZnRlclNhdmUoJ015Q3VzdG9tQ2xhc3MnLCBhc3luYyBmdW5jdGlvbihyZXF1ZXN0KSB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gdmFsaWRhdGlvbiBjb2RlIGhlcmVcbiAqIH0pO1xuICpcbiAqIFBhcnNlLkNsb3VkLmFmdGVyU2F2ZShQYXJzZS5Vc2VyLCBhc3luYyBmdW5jdGlvbihyZXF1ZXN0KSB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICogYGBgXG4gKlxuICogQG1ldGhvZCBhZnRlclNhdmVcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmFmdGVyU2F2ZVxuICogQHBhcmFtIHsoU3RyaW5nfFBhcnNlLk9iamVjdCl9IGFyZzEgVGhlIFBhcnNlLk9iamVjdCBzdWJjbGFzcyB0byByZWdpc3RlciB0aGUgYWZ0ZXIgc2F2ZSBmdW5jdGlvbiBmb3IuIFRoaXMgY2FuIGluc3RlYWQgYmUgYSBTdHJpbmcgdGhhdCBpcyB0aGUgY2xhc3NOYW1lIG9mIHRoZSBzdWJjbGFzcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJ1biBhZnRlciBhIHNhdmUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFuIGFzeW5jIGZ1bmN0aW9uIGFuZCBzaG91bGQgdGFrZSBqdXN0IG9uZSBwYXJhbWV0ZXIsIHtAbGluayBQYXJzZS5DbG91ZC5UcmlnZ2VyUmVxdWVzdH0uXG4gKiBAcGFyYW0geyhPYmplY3R8RnVuY3Rpb24pfSB2YWxpZGF0b3IgQW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gaGVscCB2YWxpZGF0aW5nIGNsb3VkIGNvZGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFuIGFzeW5jIGZ1bmN0aW9uIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5hZnRlclNhdmUgPSBmdW5jdGlvbiAocGFyc2VDbGFzcywgaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgdmFyIGNsYXNzTmFtZSA9IGdldENsYXNzTmFtZShwYXJzZUNsYXNzKTtcbiAgdHJpZ2dlcnMuYWRkVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlclNhdmUsXG4gICAgY2xhc3NOYW1lLFxuICAgIGhhbmRsZXIsXG4gICAgUGFyc2UuYXBwbGljYXRpb25JZCxcbiAgICB2YWxpZGF0aW9uSGFuZGxlclxuICApO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYW4gYWZ0ZXIgZGVsZXRlIGZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIElmIHlvdSB3YW50IHRvIHVzZSBhZnRlckRlbGV0ZSBmb3IgYSBwcmVkZWZpbmVkIGNsYXNzIGluIHRoZSBQYXJzZSBKYXZhU2NyaXB0IFNESyAoZS5nLiB7QGxpbmsgUGFyc2UuVXNlcn0pLCB5b3Ugc2hvdWxkIHBhc3MgdGhlIGNsYXNzIGl0c2VsZiBhbmQgbm90IHRoZSBTdHJpbmcgZm9yIGFyZzEuXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmFmdGVyRGVsZXRlKCdNeUN1c3RvbUNsYXNzJywgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJEZWxldGUoUGFyc2UuVXNlciwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCB7IC4uLnZhbGlkYXRpb25PYmplY3QgfSk7XG4gKmBgYFxuICpcbiAqIEBtZXRob2QgYWZ0ZXJEZWxldGVcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmFmdGVyRGVsZXRlXG4gKiBAcGFyYW0geyhTdHJpbmd8UGFyc2UuT2JqZWN0KX0gYXJnMSBUaGUgUGFyc2UuT2JqZWN0IHN1YmNsYXNzIHRvIHJlZ2lzdGVyIHRoZSBhZnRlciBkZWxldGUgZnVuY3Rpb24gZm9yLiBUaGlzIGNhbiBpbnN0ZWFkIGJlIGEgU3RyaW5nIHRoYXQgaXMgdGhlIGNsYXNzTmFtZSBvZiB0aGUgc3ViY2xhc3MuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYWZ0ZXIgYSBkZWxldGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBqdXN0IG9uZSBwYXJhbWV0ZXIsIHtAbGluayBQYXJzZS5DbG91ZC5UcmlnZ2VyUmVxdWVzdH0uXG4gKiBAcGFyYW0geyhPYmplY3R8RnVuY3Rpb24pfSB2YWxpZGF0b3IgQW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gaGVscCB2YWxpZGF0aW5nIGNsb3VkIGNvZGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFuIGFzeW5jIGZ1bmN0aW9uIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5hZnRlckRlbGV0ZSA9IGZ1bmN0aW9uIChwYXJzZUNsYXNzLCBoYW5kbGVyLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB2YXIgY2xhc3NOYW1lID0gZ2V0Q2xhc3NOYW1lKHBhcnNlQ2xhc3MpO1xuICB0cmlnZ2Vycy5hZGRUcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmFmdGVyRGVsZXRlLFxuICAgIGNsYXNzTmFtZSxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgYmVmb3JlIGZpbmQgZnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogSWYgeW91IHdhbnQgdG8gdXNlIGJlZm9yZUZpbmQgZm9yIGEgcHJlZGVmaW5lZCBjbGFzcyBpbiB0aGUgUGFyc2UgSmF2YVNjcmlwdCBTREsgKGUuZy4ge0BsaW5rIFBhcnNlLlVzZXJ9KSwgeW91IHNob3VsZCBwYXNzIHRoZSBjbGFzcyBpdHNlbGYgYW5kIG5vdCB0aGUgU3RyaW5nIGZvciBhcmcxLlxuICogYGBgXG4gKiBQYXJzZS5DbG91ZC5iZWZvcmVGaW5kKCdNeUN1c3RvbUNsYXNzJywgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYmVmb3JlRmluZChQYXJzZS5Vc2VyLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIHsgLi4udmFsaWRhdGlvbk9iamVjdCB9KTtcbiAqYGBgXG4gKlxuICogQG1ldGhvZCBiZWZvcmVGaW5kXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5iZWZvcmVGaW5kXG4gKiBAcGFyYW0geyhTdHJpbmd8UGFyc2UuT2JqZWN0KX0gYXJnMSBUaGUgUGFyc2UuT2JqZWN0IHN1YmNsYXNzIHRvIHJlZ2lzdGVyIHRoZSBiZWZvcmUgZmluZCBmdW5jdGlvbiBmb3IuIFRoaXMgY2FuIGluc3RlYWQgYmUgYSBTdHJpbmcgdGhhdCBpcyB0aGUgY2xhc3NOYW1lIG9mIHRoZSBzdWJjbGFzcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJ1biBiZWZvcmUgYSBmaW5kLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2UganVzdCBvbmUgcGFyYW1ldGVyLCB7QGxpbmsgUGFyc2UuQ2xvdWQuQmVmb3JlRmluZFJlcXVlc3R9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5CZWZvcmVGaW5kUmVxdWVzdH0sIG9yIGEge0BsaW5rIFBhcnNlLkNsb3VkLlZhbGlkYXRvck9iamVjdH0uXG4gKi9cblBhcnNlQ2xvdWQuYmVmb3JlRmluZCA9IGZ1bmN0aW9uIChwYXJzZUNsYXNzLCBoYW5kbGVyLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB2YXIgY2xhc3NOYW1lID0gZ2V0Q2xhc3NOYW1lKHBhcnNlQ2xhc3MpO1xuICB0cmlnZ2Vycy5hZGRUcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZUZpbmQsXG4gICAgY2xhc3NOYW1lLFxuICAgIGhhbmRsZXIsXG4gICAgUGFyc2UuYXBwbGljYXRpb25JZCxcbiAgICB2YWxpZGF0aW9uSGFuZGxlclxuICApO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYW4gYWZ0ZXIgZmluZCBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBJZiB5b3Ugd2FudCB0byB1c2UgYWZ0ZXJGaW5kIGZvciBhIHByZWRlZmluZWQgY2xhc3MgaW4gdGhlIFBhcnNlIEphdmFTY3JpcHQgU0RLIChlLmcuIHtAbGluayBQYXJzZS5Vc2VyfSksIHlvdSBzaG91bGQgcGFzcyB0aGUgY2xhc3MgaXRzZWxmIGFuZCBub3QgdGhlIFN0cmluZyBmb3IgYXJnMS5cbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJGaW5kKCdNeUN1c3RvbUNsYXNzJywgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJGaW5kKFBhcnNlLlVzZXIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGFmdGVyRmluZFxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYWZ0ZXJGaW5kXG4gKiBAcGFyYW0geyhTdHJpbmd8UGFyc2UuT2JqZWN0KX0gYXJnMSBUaGUgUGFyc2UuT2JqZWN0IHN1YmNsYXNzIHRvIHJlZ2lzdGVyIHRoZSBhZnRlciBmaW5kIGZ1bmN0aW9uIGZvci4gVGhpcyBjYW4gaW5zdGVhZCBiZSBhIFN0cmluZyB0aGF0IGlzIHRoZSBjbGFzc05hbWUgb2YgdGhlIHN1YmNsYXNzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcnVuIGJlZm9yZSBhIGZpbmQuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBqdXN0IG9uZSBwYXJhbWV0ZXIsIHtAbGluayBQYXJzZS5DbG91ZC5BZnRlckZpbmRSZXF1ZXN0fS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuQWZ0ZXJGaW5kUmVxdWVzdH0sIG9yIGEge0BsaW5rIFBhcnNlLkNsb3VkLlZhbGlkYXRvck9iamVjdH0uXG4gKi9cblBhcnNlQ2xvdWQuYWZ0ZXJGaW5kID0gZnVuY3Rpb24gKHBhcnNlQ2xhc3MsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIGNvbnN0IGNsYXNzTmFtZSA9IGdldENsYXNzTmFtZShwYXJzZUNsYXNzKTtcbiAgdHJpZ2dlcnMuYWRkVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlckZpbmQsXG4gICAgY2xhc3NOYW1lLFxuICAgIGhhbmRsZXIsXG4gICAgUGFyc2UuYXBwbGljYXRpb25JZCxcbiAgICB2YWxpZGF0aW9uSGFuZGxlclxuICApO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYSBiZWZvcmUgc2F2ZSBmaWxlIGZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYmVmb3JlU2F2ZUZpbGUoYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYmVmb3JlU2F2ZUZpbGUoYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCB7IC4uLnZhbGlkYXRpb25PYmplY3QgfSk7XG4gKmBgYFxuICpcbiAqIEBtZXRob2QgYmVmb3JlU2F2ZUZpbGVcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmJlZm9yZVNhdmVGaWxlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYmVmb3JlIHNhdmluZyBhIGZpbGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBqdXN0IG9uZSBwYXJhbWV0ZXIsIHtAbGluayBQYXJzZS5DbG91ZC5GaWxlVHJpZ2dlclJlcXVlc3R9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5GaWxlVHJpZ2dlclJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmJlZm9yZVNhdmVGaWxlID0gZnVuY3Rpb24gKGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIHRyaWdnZXJzLmFkZEZpbGVUcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZVNhdmVGaWxlLFxuICAgIGhhbmRsZXIsXG4gICAgUGFyc2UuYXBwbGljYXRpb25JZCxcbiAgICB2YWxpZGF0aW9uSGFuZGxlclxuICApO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYW4gYWZ0ZXIgc2F2ZSBmaWxlIGZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJTYXZlRmlsZShhc3luYyAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIHZhbGlkYXRpb24gY29kZSBoZXJlXG4gKiB9KTtcbiAqXG4gKiBQYXJzZS5DbG91ZC5hZnRlclNhdmVGaWxlKGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgLy8gY29kZSBoZXJlXG4gKiB9LCB7IC4uLnZhbGlkYXRpb25PYmplY3QgfSk7XG4gKmBgYFxuICpcbiAqIEBtZXRob2QgYWZ0ZXJTYXZlRmlsZVxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYWZ0ZXJTYXZlRmlsZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcnVuIGFmdGVyIHNhdmluZyBhIGZpbGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBqdXN0IG9uZSBwYXJhbWV0ZXIsIHtAbGluayBQYXJzZS5DbG91ZC5GaWxlVHJpZ2dlclJlcXVlc3R9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5GaWxlVHJpZ2dlclJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmFmdGVyU2F2ZUZpbGUgPSBmdW5jdGlvbiAoaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgdHJpZ2dlcnMuYWRkRmlsZVRyaWdnZXIoXG4gICAgdHJpZ2dlcnMuVHlwZXMuYWZ0ZXJTYXZlRmlsZSxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgYmVmb3JlIGRlbGV0ZSBmaWxlIGZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYmVmb3JlRGVsZXRlRmlsZShhc3luYyAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIHZhbGlkYXRpb24gY29kZSBoZXJlXG4gKiB9KTtcbiAqXG4gKiBQYXJzZS5DbG91ZC5iZWZvcmVEZWxldGVGaWxlKGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGJlZm9yZURlbGV0ZUZpbGVcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmJlZm9yZURlbGV0ZUZpbGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJ1biBiZWZvcmUgZGVsZXRpbmcgYSBmaWxlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2UganVzdCBvbmUgcGFyYW1ldGVyLCB7QGxpbmsgUGFyc2UuQ2xvdWQuRmlsZVRyaWdnZXJSZXF1ZXN0fS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuRmlsZVRyaWdnZXJSZXF1ZXN0fSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5iZWZvcmVEZWxldGVGaWxlID0gZnVuY3Rpb24gKGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIHRyaWdnZXJzLmFkZEZpbGVUcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZURlbGV0ZUZpbGUsXG4gICAgaGFuZGxlcixcbiAgICBQYXJzZS5hcHBsaWNhdGlvbklkLFxuICAgIHZhbGlkYXRpb25IYW5kbGVyXG4gICk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBhZnRlciBkZWxldGUgZmlsZSBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmFmdGVyRGVsZXRlRmlsZShhc3luYyAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIHZhbGlkYXRpb24gY29kZSBoZXJlXG4gKiB9KTtcbiAqXG4gKiBQYXJzZS5DbG91ZC5hZnRlckRlbGV0ZUZpbGUoYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCB7IC4uLnZhbGlkYXRpb25PYmplY3QgfSk7XG4gKmBgYFxuICpcbiAqIEBtZXRob2QgYWZ0ZXJEZWxldGVGaWxlXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5hZnRlckRlbGV0ZUZpbGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFmdGVyIGJlZm9yZSBkZWxldGluZyBhIGZpbGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBqdXN0IG9uZSBwYXJhbWV0ZXIsIHtAbGluayBQYXJzZS5DbG91ZC5GaWxlVHJpZ2dlclJlcXVlc3R9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5GaWxlVHJpZ2dlclJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmFmdGVyRGVsZXRlRmlsZSA9IGZ1bmN0aW9uIChoYW5kbGVyLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB0cmlnZ2Vycy5hZGRGaWxlVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlckRlbGV0ZUZpbGUsXG4gICAgaGFuZGxlcixcbiAgICBQYXJzZS5hcHBsaWNhdGlvbklkLFxuICAgIHZhbGlkYXRpb25IYW5kbGVyXG4gICk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGJlZm9yZSBsaXZlIHF1ZXJ5IHNlcnZlciBjb25uZWN0IGZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYmVmb3JlQ29ubmVjdChhc3luYyAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIHZhbGlkYXRpb24gY29kZSBoZXJlXG4gKiB9KTtcbiAqXG4gKiBQYXJzZS5DbG91ZC5iZWZvcmVDb25uZWN0KGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGJlZm9yZUNvbm5lY3RcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmJlZm9yZUNvbm5lY3RcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJlZm9yZSBjb25uZWN0aW9uIGlzIG1hZGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBqdXN0IG9uZSBwYXJhbWV0ZXIsIHtAbGluayBQYXJzZS5DbG91ZC5Db25uZWN0VHJpZ2dlclJlcXVlc3R9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5Db25uZWN0VHJpZ2dlclJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmJlZm9yZUNvbm5lY3QgPSBmdW5jdGlvbiAoaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgdHJpZ2dlcnMuYWRkQ29ubmVjdFRyaWdnZXIoXG4gICAgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlQ29ubmVjdCxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cbi8qKlxuICogU2VuZHMgYW4gZW1haWwgdGhyb3VnaCB0aGUgUGFyc2UgU2VydmVyIG1haWwgYWRhcHRlci5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqICoqUmVxdWlyZXMgYSBtYWlsIGFkYXB0ZXIgdG8gYmUgY29uZmlndXJlZCBmb3IgUGFyc2UgU2VydmVyLioqXG4gKlxuICogYGBgXG4gKiBQYXJzZS5DbG91ZC5zZW5kRW1haWwoe1xuICogICBmcm9tOiAnRXhhbXBsZSA8dGVzdEBleGFtcGxlLmNvbT4nLFxuICogICB0bzogJ2NvbnRhY3RAZXhhbXBsZS5jb20nLFxuICogICBzdWJqZWN0OiAnVGVzdCBlbWFpbCcsXG4gKiAgIHRleHQ6ICdUaGlzIGVtYWlsIGlzIGEgdGVzdC4nXG4gKiB9KTtcbiAqYGBgXG4gKlxuICogQG1ldGhvZCBzZW5kRW1haWxcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLnNlbmRFbWFpbFxuICogQHBhcmFtIHtPYmplY3R9IGRhdGEgVGhlIG9iamVjdCBvZiB0aGUgbWFpbCBkYXRhIHRvIHNlbmQuXG4gKi9cblBhcnNlQ2xvdWQuc2VuZEVtYWlsID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgY29uc3QgY29uZmlnID0gQ29uZmlnLmdldChQYXJzZS5hcHBsaWNhdGlvbklkKTtcbiAgY29uc3QgZW1haWxBZGFwdGVyID0gY29uZmlnLnVzZXJDb250cm9sbGVyLmFkYXB0ZXI7XG4gIGlmICghZW1haWxBZGFwdGVyKSB7XG4gICAgY29uZmlnLmxvZ2dlckNvbnRyb2xsZXIuZXJyb3IoXG4gICAgICAnRmFpbGVkIHRvIHNlbmQgZW1haWwgYmVjYXVzZSBubyBtYWlsIGFkYXB0ZXIgaXMgY29uZmlndXJlZCBmb3IgUGFyc2UgU2VydmVyLidcbiAgICApO1xuICAgIHJldHVybjtcbiAgfVxuICByZXR1cm4gZW1haWxBZGFwdGVyLnNlbmRNYWlsKGRhdGEpO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYSBiZWZvcmUgbGl2ZSBxdWVyeSBzdWJzY3JpcHRpb24gZnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogSWYgeW91IHdhbnQgdG8gdXNlIGJlZm9yZVN1YnNjcmliZSBmb3IgYSBwcmVkZWZpbmVkIGNsYXNzIGluIHRoZSBQYXJzZSBKYXZhU2NyaXB0IFNESyAoZS5nLiB7QGxpbmsgUGFyc2UuVXNlcn0pLCB5b3Ugc2hvdWxkIHBhc3MgdGhlIGNsYXNzIGl0c2VsZiBhbmQgbm90IHRoZSBTdHJpbmcgZm9yIGFyZzEuXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZVN1YnNjcmliZSgnTXlDdXN0b21DbGFzcycsIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gdmFsaWRhdGlvbiBjb2RlIGhlcmVcbiAqIH0pO1xuICpcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZVN1YnNjcmliZShQYXJzZS5Vc2VyLCAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIHsgLi4udmFsaWRhdGlvbk9iamVjdCB9KTtcbiAqYGBgXG4gKlxuICogQG1ldGhvZCBiZWZvcmVTdWJzY3JpYmVcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmJlZm9yZVN1YnNjcmliZVxuICogQHBhcmFtIHsoU3RyaW5nfFBhcnNlLk9iamVjdCl9IGFyZzEgVGhlIFBhcnNlLk9iamVjdCBzdWJjbGFzcyB0byByZWdpc3RlciB0aGUgYmVmb3JlIHN1YnNjcmlwdGlvbiBmdW5jdGlvbiBmb3IuIFRoaXMgY2FuIGluc3RlYWQgYmUgYSBTdHJpbmcgdGhhdCBpcyB0aGUgY2xhc3NOYW1lIG9mIHRoZSBzdWJjbGFzcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJ1biBiZWZvcmUgYSBzdWJzY3JpcHRpb24uIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyLCBhIHtAbGluayBQYXJzZS5DbG91ZC5UcmlnZ2VyUmVxdWVzdH0uXG4gKiBAcGFyYW0geyhPYmplY3R8RnVuY3Rpb24pfSB2YWxpZGF0b3IgQW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gaGVscCB2YWxpZGF0aW5nIGNsb3VkIGNvZGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFuIGFzeW5jIGZ1bmN0aW9uIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5iZWZvcmVTdWJzY3JpYmUgPSBmdW5jdGlvbiAocGFyc2VDbGFzcywgaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgdmFyIGNsYXNzTmFtZSA9IGdldENsYXNzTmFtZShwYXJzZUNsYXNzKTtcbiAgdHJpZ2dlcnMuYWRkVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5iZWZvcmVTdWJzY3JpYmUsXG4gICAgY2xhc3NOYW1lLFxuICAgIGhhbmRsZXIsXG4gICAgUGFyc2UuYXBwbGljYXRpb25JZCxcbiAgICB2YWxpZGF0aW9uSGFuZGxlclxuICApO1xufTtcblxuUGFyc2VDbG91ZC5vbkxpdmVRdWVyeUV2ZW50ID0gZnVuY3Rpb24gKGhhbmRsZXIpIHtcbiAgdHJpZ2dlcnMuYWRkTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVyKGhhbmRsZXIsIFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYW4gYWZ0ZXIgbGl2ZSBxdWVyeSBzZXJ2ZXIgZXZlbnQgZnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogYGBgXG4gKiBQYXJzZS5DbG91ZC5hZnRlckxpdmVRdWVyeUV2ZW50KCdNeUN1c3RvbUNsYXNzJywgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJMaXZlUXVlcnlFdmVudCgnTXlDdXN0b21DbGFzcycsIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGFmdGVyTGl2ZVF1ZXJ5RXZlbnRcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmFmdGVyTGl2ZVF1ZXJ5RXZlbnRcbiAqIEBwYXJhbSB7KFN0cmluZ3xQYXJzZS5PYmplY3QpfSBhcmcxIFRoZSBQYXJzZS5PYmplY3Qgc3ViY2xhc3MgdG8gcmVnaXN0ZXIgdGhlIGFmdGVyIGxpdmUgcXVlcnkgZXZlbnQgZnVuY3Rpb24gZm9yLiBUaGlzIGNhbiBpbnN0ZWFkIGJlIGEgU3RyaW5nIHRoYXQgaXMgdGhlIGNsYXNzTmFtZSBvZiB0aGUgc3ViY2xhc3MuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYWZ0ZXIgYSBsaXZlIHF1ZXJ5IGV2ZW50LiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciwgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuTGl2ZVF1ZXJ5RXZlbnRUcmlnZ2VyfS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuTGl2ZVF1ZXJ5RXZlbnRUcmlnZ2VyfSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5hZnRlckxpdmVRdWVyeUV2ZW50ID0gZnVuY3Rpb24gKHBhcnNlQ2xhc3MsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIGNvbnN0IGNsYXNzTmFtZSA9IGdldENsYXNzTmFtZShwYXJzZUNsYXNzKTtcbiAgdHJpZ2dlcnMuYWRkVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlckV2ZW50LFxuICAgIGNsYXNzTmFtZSxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cblBhcnNlQ2xvdWQuX3JlbW92ZUFsbEhvb2tzID0gKCkgPT4ge1xuICB0cmlnZ2Vycy5fdW5yZWdpc3RlckFsbCgpO1xufTtcblxuUGFyc2VDbG91ZC51c2VNYXN0ZXJLZXkgPSAoKSA9PiB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICBjb25zb2xlLndhcm4oXG4gICAgJ1BhcnNlLkNsb3VkLnVzZU1hc3RlcktleSBpcyBkZXByZWNhdGVkIChhbmQgaGFzIG5vIGVmZmVjdCBhbnltb3JlKSBvbiBwYXJzZS1zZXJ2ZXIsIHBsZWFzZSByZWZlciB0byB0aGUgY2xvdWQgY29kZSBtaWdyYXRpb24gbm90ZXM6IGh0dHA6Ly9kb2NzLnBhcnNlcGxhdGZvcm0ub3JnL3BhcnNlLXNlcnZlci9ndWlkZS8jbWFzdGVyLWtleS1tdXN0LWJlLXBhc3NlZC1leHBsaWNpdGx5J1xuICApO1xufTtcblxuUGFyc2VDbG91ZC5odHRwUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cFJlcXVlc3QnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBQYXJzZUNsb3VkO1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgUGFyc2UuQ2xvdWQuVHJpZ2dlclJlcXVlc3RcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpbnN0YWxsYXRpb25JZCBJZiBzZXQsIHRoZSBpbnN0YWxsYXRpb25JZCB0cmlnZ2VyaW5nIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtCb29sZWFufSBtYXN0ZXIgSWYgdHJ1ZSwgbWVhbnMgdGhlIG1hc3RlciBrZXkgd2FzIHVzZWQuXG4gKiBAcHJvcGVydHkge1BhcnNlLlVzZXJ9IHVzZXIgSWYgc2V0LCB0aGUgdXNlciB0aGF0IG1hZGUgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1BhcnNlLk9iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdHJpZ2dlcmluZyB0aGUgaG9vay5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpcCBUaGUgSVAgYWRkcmVzcyBvZiB0aGUgY2xpZW50IG1ha2luZyB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBoZWFkZXJzIFRoZSBvcmlnaW5hbCBIVFRQIGhlYWRlcnMgZm9yIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtTdHJpbmd9IHRyaWdnZXJOYW1lIFRoZSBuYW1lIG9mIHRoZSB0cmlnZ2VyIChgYmVmb3JlU2F2ZWAsIGBhZnRlclNhdmVgLCAuLi4pXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nIFRoZSBjdXJyZW50IGxvZ2dlciBpbnNpZGUgUGFyc2UgU2VydmVyLlxuICogQHByb3BlcnR5IHtQYXJzZS5PYmplY3R9IG9yaWdpbmFsIElmIHNldCwgdGhlIG9iamVjdCwgYXMgY3VycmVudGx5IHN0b3JlZC5cbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgUGFyc2UuQ2xvdWQuRmlsZVRyaWdnZXJSZXF1ZXN0XG4gKiBAcHJvcGVydHkge1N0cmluZ30gaW5zdGFsbGF0aW9uSWQgSWYgc2V0LCB0aGUgaW5zdGFsbGF0aW9uSWQgdHJpZ2dlcmluZyB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gbWFzdGVyIElmIHRydWUsIG1lYW5zIHRoZSBtYXN0ZXIga2V5IHdhcyB1c2VkLlxuICogQHByb3BlcnR5IHtQYXJzZS5Vc2VyfSB1c2VyIElmIHNldCwgdGhlIHVzZXIgdGhhdCBtYWRlIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtQYXJzZS5GaWxlfSBmaWxlIFRoZSBmaWxlIHRoYXQgdHJpZ2dlcmVkIHRoZSBob29rLlxuICogQHByb3BlcnR5IHtJbnRlZ2VyfSBmaWxlU2l6ZSBUaGUgc2l6ZSBvZiB0aGUgZmlsZSBpbiBieXRlcy5cbiAqIEBwcm9wZXJ0eSB7SW50ZWdlcn0gY29udGVudExlbmd0aCBUaGUgdmFsdWUgZnJvbSBDb250ZW50LUxlbmd0aCBoZWFkZXJcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpcCBUaGUgSVAgYWRkcmVzcyBvZiB0aGUgY2xpZW50IG1ha2luZyB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBoZWFkZXJzIFRoZSBvcmlnaW5hbCBIVFRQIGhlYWRlcnMgZm9yIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtTdHJpbmd9IHRyaWdnZXJOYW1lIFRoZSBuYW1lIG9mIHRoZSB0cmlnZ2VyIChgYmVmb3JlU2F2ZUZpbGVgLCBgYWZ0ZXJTYXZlRmlsZWApXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nIFRoZSBjdXJyZW50IGxvZ2dlciBpbnNpZGUgUGFyc2UgU2VydmVyLlxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBQYXJzZS5DbG91ZC5Db25uZWN0VHJpZ2dlclJlcXVlc3RcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpbnN0YWxsYXRpb25JZCBJZiBzZXQsIHRoZSBpbnN0YWxsYXRpb25JZCB0cmlnZ2VyaW5nIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtCb29sZWFufSB1c2VNYXN0ZXJLZXkgSWYgdHJ1ZSwgbWVhbnMgdGhlIG1hc3RlciBrZXkgd2FzIHVzZWQuXG4gKiBAcHJvcGVydHkge1BhcnNlLlVzZXJ9IHVzZXIgSWYgc2V0LCB0aGUgdXNlciB0aGF0IG1hZGUgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge0ludGVnZXJ9IGNsaWVudHMgVGhlIG51bWJlciBvZiBjbGllbnRzIGNvbm5lY3RlZC5cbiAqIEBwcm9wZXJ0eSB7SW50ZWdlcn0gc3Vic2NyaXB0aW9ucyBUaGUgbnVtYmVyIG9mIHN1YnNjcmlwdGlvbnMgY29ubmVjdGVkLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IHNlc3Npb25Ub2tlbiBJZiBzZXQsIHRoZSBzZXNzaW9uIG9mIHRoZSB1c2VyIHRoYXQgbWFkZSB0aGUgcmVxdWVzdC5cbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgUGFyc2UuQ2xvdWQuTGl2ZVF1ZXJ5RXZlbnRUcmlnZ2VyXG4gKiBAcHJvcGVydHkge1N0cmluZ30gaW5zdGFsbGF0aW9uSWQgSWYgc2V0LCB0aGUgaW5zdGFsbGF0aW9uSWQgdHJpZ2dlcmluZyB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gdXNlTWFzdGVyS2V5IElmIHRydWUsIG1lYW5zIHRoZSBtYXN0ZXIga2V5IHdhcyB1c2VkLlxuICogQHByb3BlcnR5IHtQYXJzZS5Vc2VyfSB1c2VyIElmIHNldCwgdGhlIHVzZXIgdGhhdCBtYWRlIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtTdHJpbmd9IHNlc3Npb25Ub2tlbiBJZiBzZXQsIHRoZSBzZXNzaW9uIG9mIHRoZSB1c2VyIHRoYXQgbWFkZSB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBldmVudCBUaGUgbGl2ZSBxdWVyeSBldmVudCB0aGF0IHRyaWdnZXJlZCB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7UGFyc2UuT2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0cmlnZ2VyaW5nIHRoZSBob29rLlxuICogQHByb3BlcnR5IHtQYXJzZS5PYmplY3R9IG9yaWdpbmFsIElmIHNldCwgdGhlIG9iamVjdCwgYXMgY3VycmVudGx5IHN0b3JlZC5cbiAqIEBwcm9wZXJ0eSB7SW50ZWdlcn0gY2xpZW50cyBUaGUgbnVtYmVyIG9mIGNsaWVudHMgY29ubmVjdGVkLlxuICogQHByb3BlcnR5IHtJbnRlZ2VyfSBzdWJzY3JpcHRpb25zIFRoZSBudW1iZXIgb2Ygc3Vic2NyaXB0aW9ucyBjb25uZWN0ZWQuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHNlbmRFdmVudCBJZiB0aGUgTGl2ZVF1ZXJ5IGV2ZW50IHNob3VsZCBiZSBzZW50IHRvIHRoZSBjbGllbnQuIFNldCB0byBmYWxzZSB0byBwcmV2ZW50IExpdmVRdWVyeSBmcm9tIHB1c2hpbmcgdG8gdGhlIGNsaWVudC5cbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgUGFyc2UuQ2xvdWQuQmVmb3JlRmluZFJlcXVlc3RcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpbnN0YWxsYXRpb25JZCBJZiBzZXQsIHRoZSBpbnN0YWxsYXRpb25JZCB0cmlnZ2VyaW5nIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtCb29sZWFufSBtYXN0ZXIgSWYgdHJ1ZSwgbWVhbnMgdGhlIG1hc3RlciBrZXkgd2FzIHVzZWQuXG4gKiBAcHJvcGVydHkge1BhcnNlLlVzZXJ9IHVzZXIgSWYgc2V0LCB0aGUgdXNlciB0aGF0IG1hZGUgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1BhcnNlLlF1ZXJ5fSBxdWVyeSBUaGUgcXVlcnkgdHJpZ2dlcmluZyB0aGUgaG9vay5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpcCBUaGUgSVAgYWRkcmVzcyBvZiB0aGUgY2xpZW50IG1ha2luZyB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBoZWFkZXJzIFRoZSBvcmlnaW5hbCBIVFRQIGhlYWRlcnMgZm9yIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtTdHJpbmd9IHRyaWdnZXJOYW1lIFRoZSBuYW1lIG9mIHRoZSB0cmlnZ2VyIChgYmVmb3JlU2F2ZWAsIGBhZnRlclNhdmVgLCAuLi4pXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nIFRoZSBjdXJyZW50IGxvZ2dlciBpbnNpZGUgUGFyc2UgU2VydmVyLlxuICogQHByb3BlcnR5IHtCb29sZWFufSBpc0dldCB3ZXRoZXIgdGhlIHF1ZXJ5IGEgYGdldGAgb3IgYSBgZmluZGBcbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgUGFyc2UuQ2xvdWQuQWZ0ZXJGaW5kUmVxdWVzdFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGluc3RhbGxhdGlvbklkIElmIHNldCwgdGhlIGluc3RhbGxhdGlvbklkIHRyaWdnZXJpbmcgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IG1hc3RlciBJZiB0cnVlLCBtZWFucyB0aGUgbWFzdGVyIGtleSB3YXMgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7UGFyc2UuVXNlcn0gdXNlciBJZiBzZXQsIHRoZSB1c2VyIHRoYXQgbWFkZSB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7UGFyc2UuUXVlcnl9IHF1ZXJ5IFRoZSBxdWVyeSB0cmlnZ2VyaW5nIHRoZSBob29rLlxuICogQHByb3BlcnR5IHtBcnJheTxQYXJzZS5PYmplY3Q+fSByZXN1bHRzIFRoZSByZXN1bHRzIHRoZSBxdWVyeSB5aWVsZGVkLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGlwIFRoZSBJUCBhZGRyZXNzIG9mIHRoZSBjbGllbnQgbWFraW5nIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtPYmplY3R9IGhlYWRlcnMgVGhlIG9yaWdpbmFsIEhUVFAgaGVhZGVycyBmb3IgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gdHJpZ2dlck5hbWUgVGhlIG5hbWUgb2YgdGhlIHRyaWdnZXIgKGBiZWZvcmVTYXZlYCwgYGFmdGVyU2F2ZWAsIC4uLilcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2cgVGhlIGN1cnJlbnQgbG9nZ2VyIGluc2lkZSBQYXJzZSBTZXJ2ZXIuXG4gKi9cblxuLyoqXG4gKiBAaW50ZXJmYWNlIFBhcnNlLkNsb3VkLkZ1bmN0aW9uUmVxdWVzdFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGluc3RhbGxhdGlvbklkIElmIHNldCwgdGhlIGluc3RhbGxhdGlvbklkIHRyaWdnZXJpbmcgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IG1hc3RlciBJZiB0cnVlLCBtZWFucyB0aGUgbWFzdGVyIGtleSB3YXMgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7UGFyc2UuVXNlcn0gdXNlciBJZiBzZXQsIHRoZSB1c2VyIHRoYXQgbWFkZSB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBwYXJhbXMgVGhlIHBhcmFtcyBwYXNzZWQgdG8gdGhlIGNsb3VkIGZ1bmN0aW9uLlxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBQYXJzZS5DbG91ZC5Kb2JSZXF1ZXN0XG4gKiBAcHJvcGVydHkge09iamVjdH0gcGFyYW1zIFRoZSBwYXJhbXMgcGFzc2VkIHRvIHRoZSBiYWNrZ3JvdW5kIGpvYi5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IG1lc3NhZ2UgSWYgbWVzc2FnZSBpcyBjYWxsZWQgd2l0aCBhIHN0cmluZyBhcmd1bWVudCwgd2lsbCB1cGRhdGUgdGhlIGN1cnJlbnQgbWVzc2FnZSB0byBiZSBzdG9yZWQgaW4gdGhlIGpvYiBzdGF0dXMuXG4gKi9cblxuLyoqXG4gKiBAaW50ZXJmYWNlIFBhcnNlLkNsb3VkLlZhbGlkYXRvck9iamVjdFxuICogQHByb3BlcnR5IHtCb29sZWFufSByZXF1aXJlVXNlciB3aGV0aGVyIHRoZSBjbG91ZCB0cmlnZ2VyIHJlcXVpcmVzIGEgdXNlci5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gcmVxdWlyZU1hc3RlciB3aGV0aGVyIHRoZSBjbG91ZCB0cmlnZ2VyIHJlcXVpcmVzIGEgbWFzdGVyIGtleS5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gdmFsaWRhdGVNYXN0ZXJLZXkgd2hldGhlciB0aGUgdmFsaWRhdG9yIHNob3VsZCBydW4gaWYgbWFzdGVyS2V5IGlzIHByb3ZpZGVkLiBEZWZhdWx0cyB0byBmYWxzZS5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gc2tpcFdpdGhNYXN0ZXJLZXkgd2hldGhlciB0aGUgY2xvdWQgY29kZSBmdW5jdGlvbiBzaG91bGQgYmUgaWdub3JlZCB1c2luZyBhIG1hc3RlcktleS5cbiAqXG4gKiBAcHJvcGVydHkge0FycmF5PFN0cmluZz58T2JqZWN0fSByZXF1aXJlVXNlcktleXMgSWYgc2V0LCBrZXlzIHJlcXVpcmVkIG9uIHJlcXVlc3QudXNlciB0byBtYWtlIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtTdHJpbmd9IHJlcXVpcmVVc2VyS2V5cy5maWVsZCBJZiByZXF1aXJlVXNlcktleXMgaXMgYW4gb2JqZWN0LCBuYW1lIG9mIGZpZWxkIHRvIHZhbGlkYXRlIG9uIHJlcXVlc3QgdXNlclxuICogQHByb3BlcnR5IHtBcnJheXxmdW5jdGlvbnxBbnl9IHJlcXVpcmVVc2VyS2V5cy5maWVsZC5vcHRpb25zIGFycmF5IG9mIG9wdGlvbnMgdGhhdCB0aGUgZmllbGQgY2FuIGJlLCBmdW5jdGlvbiB0byB2YWxpZGF0ZSBmaWVsZCwgb3Igc2luZ2xlIHZhbHVlLiBUaHJvdyBhbiBlcnJvciBpZiB2YWx1ZSBpcyBpbnZhbGlkLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IHJlcXVpcmVVc2VyS2V5cy5maWVsZC5lcnJvciBjdXN0b20gZXJyb3IgbWVzc2FnZSBpZiBmaWVsZCBpcyBpbnZhbGlkLlxuICpcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fEFycmF5PFN0cmluZz59IGZpZWxkcyBpZiBhbiBhcnJheSBvZiBzdHJpbmdzLCB2YWxpZGF0b3Igd2lsbCBsb29rIGZvciBrZXlzIGluIHJlcXVlc3QucGFyYW1zLCBhbmQgdGhyb3cgaWYgbm90IHByb3ZpZGVkLiBJZiBPYmplY3QsIGZpZWxkcyB0byB2YWxpZGF0ZS4gSWYgdGhlIHRyaWdnZXIgaXMgYSBjbG91ZCBmdW5jdGlvbiwgYHJlcXVlc3QucGFyYW1zYCB3aWxsIGJlIHZhbGlkYXRlZCwgb3RoZXJ3aXNlIGByZXF1ZXN0Lm9iamVjdGAuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gZmllbGRzLmZpZWxkIG5hbWUgb2YgZmllbGQgdG8gdmFsaWRhdGUuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gZmllbGRzLmZpZWxkLnR5cGUgZXhwZWN0ZWQgdHlwZSBvZiBkYXRhIGZvciBmaWVsZC5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gZmllbGRzLmZpZWxkLmNvbnN0YW50IHdoZXRoZXIgdGhlIGZpZWxkIGNhbiBiZSBtb2RpZmllZCBvbiB0aGUgb2JqZWN0LlxuICogQHByb3BlcnR5IHtBbnl9IGZpZWxkcy5maWVsZC5kZWZhdWx0IGRlZmF1bHQgdmFsdWUgaWYgZmllbGQgaXMgYG51bGxgLCBvciBpbml0aWFsIHZhbHVlIGBjb25zdGFudGAgaXMgYHRydWVgLlxuICogQHByb3BlcnR5IHtBcnJheXxmdW5jdGlvbnxBbnl9IGZpZWxkcy5maWVsZC5vcHRpb25zIGFycmF5IG9mIG9wdGlvbnMgdGhhdCB0aGUgZmllbGQgY2FuIGJlLCBmdW5jdGlvbiB0byB2YWxpZGF0ZSBmaWVsZCwgb3Igc2luZ2xlIHZhbHVlLiBUaHJvdyBhbiBlcnJvciBpZiB2YWx1ZSBpcyBpbnZhbGlkLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGZpZWxkcy5maWVsZC5lcnJvciBjdXN0b20gZXJyb3IgbWVzc2FnZSBpZiBmaWVsZCBpcyBpbnZhbGlkLlxuICovXG4iXX0= \ No newline at end of file diff --git a/lib/cloud-code/httpRequest.js b/lib/cloud-code/httpRequest.js new file mode 100644 index 0000000000..fc4f62a517 --- /dev/null +++ b/lib/cloud-code/httpRequest.js @@ -0,0 +1,192 @@ +"use strict"; + +var _HTTPResponse = _interopRequireDefault(require("./HTTPResponse")); + +var _querystring = _interopRequireDefault(require("querystring")); + +var _logger = _interopRequireDefault(require("../logger")); + +var _followRedirects = require("follow-redirects"); + +var _url = require("url"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const clients = { + 'http:': _followRedirects.http, + 'https:': _followRedirects.https +}; + +function makeCallback(resolve, reject) { + return function (response) { + const chunks = []; + response.on('data', chunk => { + chunks.push(chunk); + }); + response.on('end', () => { + const body = Buffer.concat(chunks); + const httpResponse = new _HTTPResponse.default(response, body); // Consider <200 && >= 400 as errors + + if (httpResponse.status < 200 || httpResponse.status >= 400) { + return reject(httpResponse); + } else { + return resolve(httpResponse); + } + }); + response.on('error', reject); + }; +} + +const encodeBody = function ({ + body, + headers = {} +}) { + if (typeof body !== 'object') { + return { + body, + headers + }; + } + + var contentTypeKeys = Object.keys(headers).filter(key => { + return key.match(/content-type/i) != null; + }); + + if (contentTypeKeys.length == 0) { + // no content type + // As per https://parse.com/docs/cloudcode/guide#cloud-code-advanced-sending-a-post-request the default encoding is supposedly x-www-form-urlencoded + body = _querystring.default.stringify(body); + headers['Content-Type'] = 'application/x-www-form-urlencoded'; + } else { + /* istanbul ignore next */ + if (contentTypeKeys.length > 1) { + _logger.default.error('Parse.Cloud.httpRequest', 'multiple content-type headers are set.'); + } // There maybe many, we'll just take the 1st one + + + var contentType = contentTypeKeys[0]; + + if (headers[contentType].match(/application\/json/i)) { + body = JSON.stringify(body); + } else if (headers[contentType].match(/application\/x-www-form-urlencoded/i)) { + body = _querystring.default.stringify(body); + } + } + + return { + body, + headers + }; +}; +/** + * Makes an HTTP Request. + * + * **Available in Cloud Code only.** + * + * By default, Parse.Cloud.httpRequest does not follow redirects caused by HTTP 3xx response codes. You can use the followRedirects option in the {@link Parse.Cloud.HTTPOptions} object to change this behavior. + * + * Sample request: + * ``` + * Parse.Cloud.httpRequest({ + * url: 'http://www.parse.com/' + * }).then(function(httpResponse) { + * // success + * console.log(httpResponse.text); + * },function(httpResponse) { + * // error + * console.error('Request failed with response code ' + httpResponse.status); + * }); + * ``` + * + * @method httpRequest + * @name Parse.Cloud.httpRequest + * @param {Parse.Cloud.HTTPOptions} options The Parse.Cloud.HTTPOptions object that makes the request. + * @return {Promise} A promise that will be resolved with a {@link Parse.Cloud.HTTPResponse} object when the request completes. + */ + + +module.exports = function httpRequest(options) { + let url; + + try { + url = (0, _url.parse)(options.url); + } catch (e) { + return Promise.reject(e); + } + + options = Object.assign(options, encodeBody(options)); // support params options + + if (typeof options.params === 'object') { + options.qs = options.params; + } else if (typeof options.params === 'string') { + options.qs = _querystring.default.parse(options.params); + } + + const client = clients[url.protocol]; + + if (!client) { + return Promise.reject(`Unsupported protocol ${url.protocol}`); + } + + const requestOptions = { + method: options.method, + port: Number(url.port), + path: url.pathname, + hostname: url.hostname, + headers: options.headers, + encoding: null, + followRedirects: options.followRedirects === true + }; + + if (requestOptions.headers) { + Object.keys(requestOptions.headers).forEach(key => { + if (typeof requestOptions.headers[key] === 'undefined') { + delete requestOptions.headers[key]; + } + }); + } + + if (url.search) { + options.qs = Object.assign({}, options.qs, _querystring.default.parse(url.query)); + } + + if (url.auth) { + requestOptions.auth = url.auth; + } + + if (options.qs) { + requestOptions.path += `?${_querystring.default.stringify(options.qs)}`; + } + + if (options.agent) { + requestOptions.agent = options.agent; + } + + return new Promise((resolve, reject) => { + const req = client.request(requestOptions, makeCallback(resolve, reject, options)); + + if (options.body) { + req.write(options.body); + } + + req.on('error', error => { + reject(error); + }); + req.end(); + }); +}; +/** + * @typedef Parse.Cloud.HTTPOptions + * @property {String|Object} body The body of the request. If it is a JSON object, then the Content-Type set in the headers must be application/x-www-form-urlencoded or application/json. You can also set this to a {@link Buffer} object to send raw bytes. If you use a Buffer, you should also set the Content-Type header explicitly to describe what these bytes represent. + * @property {function} error The function that is called when the request fails. It will be passed a Parse.Cloud.HTTPResponse object. + * @property {Boolean} followRedirects Whether to follow redirects caused by HTTP 3xx responses. Defaults to false. + * @property {Object} headers The headers for the request. + * @property {String} method The method of the request. GET, POST, PUT, DELETE, HEAD, and OPTIONS are supported. Will default to GET if not specified. + * @property {String|Object} params The query portion of the url. You can pass a JSON object of key value pairs like params: {q : 'Sean Plott'} or a raw string like params:q=Sean Plott. + * @property {function} success The function that is called when the request successfully completes. It will be passed a Parse.Cloud.HTTPResponse object. + * @property {string} url The url to send the request to. + */ + + +module.exports.encodeBody = encodeBody; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbG91ZC1jb2RlL2h0dHBSZXF1ZXN0LmpzIl0sIm5hbWVzIjpbImNsaWVudHMiLCJodHRwIiwiaHR0cHMiLCJtYWtlQ2FsbGJhY2siLCJyZXNvbHZlIiwicmVqZWN0IiwicmVzcG9uc2UiLCJjaHVua3MiLCJvbiIsImNodW5rIiwicHVzaCIsImJvZHkiLCJCdWZmZXIiLCJjb25jYXQiLCJodHRwUmVzcG9uc2UiLCJIVFRQUmVzcG9uc2UiLCJzdGF0dXMiLCJlbmNvZGVCb2R5IiwiaGVhZGVycyIsImNvbnRlbnRUeXBlS2V5cyIsIk9iamVjdCIsImtleXMiLCJmaWx0ZXIiLCJrZXkiLCJtYXRjaCIsImxlbmd0aCIsInF1ZXJ5c3RyaW5nIiwic3RyaW5naWZ5IiwibG9nIiwiZXJyb3IiLCJjb250ZW50VHlwZSIsIkpTT04iLCJtb2R1bGUiLCJleHBvcnRzIiwiaHR0cFJlcXVlc3QiLCJvcHRpb25zIiwidXJsIiwiZSIsIlByb21pc2UiLCJhc3NpZ24iLCJwYXJhbXMiLCJxcyIsInBhcnNlIiwiY2xpZW50IiwicHJvdG9jb2wiLCJyZXF1ZXN0T3B0aW9ucyIsIm1ldGhvZCIsInBvcnQiLCJOdW1iZXIiLCJwYXRoIiwicGF0aG5hbWUiLCJob3N0bmFtZSIsImVuY29kaW5nIiwiZm9sbG93UmVkaXJlY3RzIiwiZm9yRWFjaCIsInNlYXJjaCIsInF1ZXJ5IiwiYXV0aCIsImFnZW50IiwicmVxIiwicmVxdWVzdCIsIndyaXRlIiwiZW5kIl0sIm1hcHBpbmdzIjoiOztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRUEsTUFBTUEsT0FBTyxHQUFHO0FBQ2QsV0FBU0MscUJBREs7QUFFZCxZQUFVQztBQUZJLENBQWhCOztBQUtBLFNBQVNDLFlBQVQsQ0FBc0JDLE9BQXRCLEVBQStCQyxNQUEvQixFQUF1QztBQUNyQyxTQUFPLFVBQVVDLFFBQVYsRUFBb0I7QUFDekIsVUFBTUMsTUFBTSxHQUFHLEVBQWY7QUFDQUQsSUFBQUEsUUFBUSxD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M0MsQ0FBWjs7QUFDQSxRQUFJQSxPQUFPLENBQUN4QixJQUFaLEVBQWtCO0FBQ2hCZ0QsTUFBQUEsR0FBRyxDQUFDRSxLQUFKLENBQVUxQixPQUFPLENBQUN4QixJQUFsQjtBQUNEOztBQUNEZ0QsSUFBQUEsR0FBRyxDQUFDbkQsRUFBSixDQUFPLE9BQVAsRUFBZ0JxQixLQUFLLElBQUk7QUFDdkJ4QixNQUFBQSxNQUFNLENBQUN3QixLQUFELENBQU47QUFDRCxLQUZEO0FBR0E4QixJQUFBQSxHQUFHLENBQUNHLEdBQUo7QUFDRCxHQVRNLENBQVA7QUFVRCxDQXhERDtBQTBEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFFQTlCLE1BQU0sQ0FBQ0MsT0FBUCxDQUFlaEIsVUFBZixHQUE0QkEsVUFBNUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgSFRUUFJlc3BvbnNlIGZyb20gJy4vSFRUUFJlc3BvbnNlJztcbmltcG9ydCBxdWVyeXN0cmluZyBmcm9tICdxdWVyeXN0cmluZyc7XG5pbXBvcnQgbG9nIGZyb20gJy4uL2xvZ2dlcic7XG5pbXBvcnQgeyBodHRwLCBodHRwcyB9IGZyb20gJ2ZvbGxvdy1yZWRpcmVjdHMnO1xuaW1wb3J0IHsgcGFyc2UgfSBmcm9tICd1cmwnO1xuXG5jb25zdCBjbGllbnRzID0ge1xuICAnaHR0cDonOiBodHRwLFxuICAnaHR0cHM6JzogaHR0cHMsXG59O1xuXG5mdW5jdGlvbiBtYWtlQ2FsbGJhY2socmVzb2x2ZSwgcmVqZWN0KSB7XG4gIHJldHVybiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICBjb25zdCBjaHVua3MgPSBbXTtcbiAgICByZXNwb25zZS5vbignZGF0YScsIGNodW5rID0+IHtcbiAgICAgIGNodW5rcy5wdXNoKGNodW5rKTtcbiAgICB9KTtcbiAgICByZXNwb25zZS5vbignZW5kJywgKCkgPT4ge1xuICAgICAgY29uc3QgYm9keSA9IEJ1ZmZlci5jb25jYXQoY2h1bmtzKTtcbiAgICAgIGNvbnN0IGh0dHBSZXNwb25zZSA9IG5ldyBIVFRQUmVzcG9uc2UocmVzcG9uc2UsIGJvZHkpO1xuXG4gICAgICAvLyBDb25zaWRlciA8MjAwICYmID49IDQwMCBhcyBlcnJvcnNcbiAgICAgIGlmIChodHRwUmVzcG9uc2Uuc3RhdHVzIDwgMjAwIHx8IGh0dHBSZXNwb25zZS5zdGF0dXMgPj0gNDAwKSB7XG4gICAgICAgIHJldHVybiByZWplY3QoaHR0cFJlc3BvbnNlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlKGh0dHBSZXNwb25zZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmVzcG9uc2Uub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgfTtcbn1cblxuY29uc3QgZW5jb2RlQm9keSA9IGZ1bmN0aW9uICh7IGJvZHksIGhlYWRlcnMgPSB7fSB9KSB7XG4gIGlmICh0eXBlb2YgYm9keSAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4geyBib2R5LCBoZWFkZXJzIH07XG4gIH1cbiAgdmFyIGNvbnRlbnRUeXBlS2V5cyA9IE9iamVjdC5rZXlzKGhlYWRlcnMpLmZpbHRlcihrZXkgPT4ge1xuICAgIHJldHVybiBrZXkubWF0Y2goL2NvbnRlbnQtdHlwZS9pKSAhPSBudWxsO1xuICB9KTtcblxuICBpZiAoY29udGVudFR5cGVLZXlzLmxlbmd0aCA9PSAwKSB7XG4gICAgLy8gbm8gY29udGVudCB0eXBlXG4gICAgLy8gIEFzIHBlciBodHRwczovL3BhcnNlLmNvbS9kb2NzL2Nsb3VkY29kZS9ndWlkZSNjbG91ZC1jb2RlLWFkdmFuY2VkLXNlbmRpbmctYS1wb3N0LXJlcXVlc3QgdGhlIGRlZmF1bHQgZW5jb2RpbmcgaXMgc3VwcG9zZWRseSB4LXd3dy1mb3JtLXVybGVuY29kZWRcblxuICAgIGJvZHkgPSBxdWVyeXN0cmluZy5zdHJpbmdpZnkoYm9keSk7XG4gICAgaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJztcbiAgfSBlbHNlIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIGlmIChjb250ZW50VHlwZUtleXMubGVuZ3RoID4gMSkge1xuICAgICAgbG9nLmVycm9yKCdQYXJzZS5DbG91ZC5odHRwUmVxdWVzdCcsICdtdWx0aXBsZSBjb250ZW50LXR5cGUgaGVhZGVycyBhcmUgc2V0LicpO1xuICAgIH1cbiAgICAvLyBUaGVyZSBtYXliZSBtYW55LCB3ZSdsbCBqdXN0IHRha2UgdGhlIDFzdCBvbmVcbiAgICB2YXIgY29udGVudFR5cGUgPSBjb250ZW50VHlwZUtleXNbMF07XG4gICAgaWYgKGhlYWRlcnNbY29udGVudFR5cGVdLm1hdGNoKC9hcHBsaWNhdGlvblxcL2pzb24vaSkpIHtcbiAgICAgIGJvZHkgPSBKU09OLnN0cmluZ2lmeShib2R5KTtcbiAgICB9IGVsc2UgaWYgKGhlYWRlcnNbY29udGVudFR5cGVdLm1hdGNoKC9hcHBsaWNhdGlvblxcL3gtd3d3LWZvcm0tdXJsZW5jb2RlZC9pKSkge1xuICAgICAgYm9keSA9IHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeShib2R5KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHsgYm9keSwgaGVhZGVycyB9O1xufTtcblxuLyoqXG4gKiBNYWtlcyBhbiBIVFRQIFJlcXVlc3QuXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogQnkgZGVmYXVsdCwgUGFyc2UuQ2xvdWQuaHR0cFJlcXVlc3QgZG9lcyBub3QgZm9sbG93IHJlZGlyZWN0cyBjYXVzZWQgYnkgSFRUUCAzeHggcmVzcG9uc2UgY29kZXMuIFlvdSBjYW4gdXNlIHRoZSBmb2xsb3dSZWRpcmVjdHMgb3B0aW9uIGluIHRoZSB7QGxpbmsgUGFyc2UuQ2xvdWQuSFRUUE9wdGlvbnN9IG9iamVjdCB0byBjaGFuZ2UgdGhpcyBiZWhhdmlvci5cbiAqXG4gKiBTYW1wbGUgcmVxdWVzdDpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuaHR0cFJlcXVlc3Qoe1xuICogICB1cmw6ICdodHRwOi8vd3d3LnBhcnNlLmNvbS8nXG4gKiB9KS50aGVuKGZ1bmN0aW9uKGh0dHBSZXNwb25zZSkge1xuICogICAvLyBzdWNjZXNzXG4gKiAgIGNvbnNvbGUubG9nKGh0dHBSZXNwb25zZS50ZXh0KTtcbiAqIH0sZnVuY3Rpb24oaHR0cFJlc3BvbnNlKSB7XG4gKiAgIC8vIGVycm9yXG4gKiAgIGNvbnNvbGUuZXJyb3IoJ1JlcXVlc3QgZmFpbGVkIHdpdGggcmVzcG9uc2UgY29kZSAnICsgaHR0cFJlc3BvbnNlLnN0YXR1cyk7XG4gKiB9KTtcbiAqIGBgYFxuICpcbiAqIEBtZXRob2QgaHR0cFJlcXVlc3RcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmh0dHBSZXF1ZXN0XG4gKiBAcGFyYW0ge1BhcnNlLkNsb3VkLkhUVFBPcHRpb25zfSBvcHRpb25zIFRoZSBQYXJzZS5DbG91ZC5IVFRQT3B0aW9ucyBvYmplY3QgdGhhdCBtYWtlcyB0aGUgcmVxdWVzdC5cbiAqIEByZXR1cm4ge1Byb21pc2U8UGFyc2UuQ2xvdWQuSFRUUFJlc3BvbnNlPn0gQSBwcm9taXNlIHRoYXQgd2lsbCBiZSByZXNvbHZlZCB3aXRoIGEge0BsaW5rIFBhcnNlLkNsb3VkLkhUVFBSZXNwb25zZX0gb2JqZWN0IHdoZW4gdGhlIHJlcXVlc3QgY29tcGxldGVzLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGh0dHBSZXF1ZXN0KG9wdGlvbnMpIHtcbiAgbGV0IHVybDtcbiAgdHJ5IHtcbiAgICB1cmwgPSBwYXJzZShvcHRpb25zLnVybCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZSk7XG4gIH1cbiAgb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24ob3B0aW9ucywgZW5jb2RlQm9keShvcHRpb25zKSk7XG4gIC8vIHN1cHBvcnQgcGFyYW1zIG9wdGlvbnNcbiAgaWYgKHR5cGVvZiBvcHRpb25zLnBhcmFtcyA9PT0gJ29iamVjdCcpIHtcbiAgICBvcHRpb25zLnFzID0gb3B0aW9ucy5wYXJhbXM7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG9wdGlvbnMucGFyYW1zID09PSAnc3RyaW5nJykge1xuICAgIG9wdGlvbnMucXMgPSBxdWVyeXN0cmluZy5wYXJzZShvcHRpb25zLnBhcmFtcyk7XG4gIH1cbiAgY29uc3QgY2xpZW50ID0gY2xpZW50c1t1cmwucHJvdG9jb2xdO1xuICBpZiAoIWNsaWVudCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlamVjdChgVW5zdXBwb3J0ZWQgcHJvdG9jb2wgJHt1cmwucHJvdG9jb2x9YCk7XG4gIH1cbiAgY29uc3QgcmVxdWVzdE9wdGlvbnMgPSB7XG4gICAgbWV0aG9kOiBvcHRpb25zLm1ldGhvZCxcbiAgICBwb3J0OiBOdW1iZXIodXJsLnBvcnQpLFxuICAgIHBhdGg6IHVybC5wYXRobmFtZSxcbiAgICBob3N0bmFtZTogdXJsLmhvc3RuYW1lLFxuICAgIGhlYWRlcnM6IG9wdGlvbnMuaGVhZGVycyxcbiAgICBlbmNvZGluZzogbnVsbCxcbiAgICBmb2xsb3dSZWRpcmVjdHM6IG9wdGlvbnMuZm9sbG93UmVkaXJlY3RzID09PSB0cnVlLFxuICB9O1xuICBpZiAocmVxdWVzdE9wdGlvbnMuaGVhZGVycykge1xuICAgIE9iamVjdC5rZXlzKHJlcXVlc3RPcHRpb25zLmhlYWRlcnMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGlmICh0eXBlb2YgcmVxdWVzdE9wdGlvbnMuaGVhZGVyc1trZXldID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBkZWxldGUgcmVxdWVzdE9wdGlvbnMuaGVhZGVyc1trZXldO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIGlmICh1cmwuc2VhcmNoKSB7XG4gICAgb3B0aW9ucy5xcyA9IE9iamVjdC5hc3NpZ24oe30sIG9wdGlvbnMucXMsIHF1ZXJ5c3RyaW5nLnBhcnNlKHVybC5xdWVyeSkpO1xuICB9XG4gIGlmICh1cmwuYXV0aCkge1xuICAgIHJlcXVlc3RPcHRpb25zLmF1dGggPSB1cmwuYXV0aDtcbiAgfVxuICBpZiAob3B0aW9ucy5xcykge1xuICAgIHJlcXVlc3RPcHRpb25zLnBhdGggKz0gYD8ke3F1ZXJ5c3RyaW5nLnN0cmluZ2lmeShvcHRpb25zLnFzKX1gO1xuICB9XG4gIGlmIChvcHRpb25zLmFnZW50KSB7XG4gICAgcmVxdWVzdE9wdGlvbnMuYWdlbnQgPSBvcHRpb25zLmFnZW50O1xuICB9XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgcmVxID0gY2xpZW50LnJlcXVlc3QocmVxdWVzdE9wdGlvbnMsIG1ha2VDYWxsYmFjayhyZXNvbHZlLCByZWplY3QsIG9wdGlvbnMpKTtcbiAgICBpZiAob3B0aW9ucy5ib2R5KSB7XG4gICAgICByZXEud3JpdGUob3B0aW9ucy5ib2R5KTtcbiAgICB9XG4gICAgcmVxLm9uKCdlcnJvcicsIGVycm9yID0+IHtcbiAgICAgIHJlamVjdChlcnJvcik7XG4gICAgfSk7XG4gICAgcmVxLmVuZCgpO1xuICB9KTtcbn07XG5cbi8qKlxuICogQHR5cGVkZWYgUGFyc2UuQ2xvdWQuSFRUUE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfE9iamVjdH0gYm9keSBUaGUgYm9keSBvZiB0aGUgcmVxdWVzdC4gSWYgaXQgaXMgYSBKU09OIG9iamVjdCwgdGhlbiB0aGUgQ29udGVudC1UeXBlIHNldCBpbiB0aGUgaGVhZGVycyBtdXN0IGJlIGFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCBvciBhcHBsaWNhdGlvbi9qc29uLiBZb3UgY2FuIGFsc28gc2V0IHRoaXMgdG8gYSB7QGxpbmsgQnVmZmVyfSBvYmplY3QgdG8gc2VuZCByYXcgYnl0ZXMuIElmIHlvdSB1c2UgYSBCdWZmZXIsIHlvdSBzaG91bGQgYWxzbyBzZXQgdGhlIENvbnRlbnQtVHlwZSBoZWFkZXIgZXhwbGljaXRseSB0byBkZXNjcmliZSB3aGF0IHRoZXNlIGJ5dGVzIHJlcHJlc2VudC5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IGVycm9yIFRoZSBmdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSByZXF1ZXN0IGZhaWxzLiBJdCB3aWxsIGJlIHBhc3NlZCBhIFBhcnNlLkNsb3VkLkhUVFBSZXNwb25zZSBvYmplY3QuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGZvbGxvd1JlZGlyZWN0cyBXaGV0aGVyIHRvIGZvbGxvdyByZWRpcmVjdHMgY2F1c2VkIGJ5IEhUVFAgM3h4IHJlc3BvbnNlcy4gRGVmYXVsdHMgdG8gZmFsc2UuXG4gKiBAcHJvcGVydHkge09iamVjdH0gaGVhZGVycyBUaGUgaGVhZGVycyBmb3IgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gbWV0aG9kIFRoZSBtZXRob2Qgb2YgdGhlIHJlcXVlc3QuIEdFVCwgUE9TVCwgUFVULCBERUxFVEUsIEhFQUQsIGFuZCBPUFRJT05TIGFyZSBzdXBwb3J0ZWQuIFdpbGwgZGVmYXVsdCB0byBHRVQgaWYgbm90IHNwZWNpZmllZC5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfE9iamVjdH0gcGFyYW1zIFRoZSBxdWVyeSBwb3J0aW9uIG9mIHRoZSB1cmwuIFlvdSBjYW4gcGFzcyBhIEpTT04gb2JqZWN0IG9mIGtleSB2YWx1ZSBwYWlycyBsaWtlIHBhcmFtczoge3EgOiAnU2VhbiBQbG90dCd9IG9yIGEgcmF3IHN0cmluZyBsaWtlIHBhcmFtczpxPVNlYW4gUGxvdHQuXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBzdWNjZXNzIFRoZSBmdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSByZXF1ZXN0IHN1Y2Nlc3NmdWxseSBjb21wbGV0ZXMuIEl0IHdpbGwgYmUgcGFzc2VkIGEgUGFyc2UuQ2xvdWQuSFRUUFJlc3BvbnNlIG9iamVjdC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB1cmwgVGhlIHVybCB0byBzZW5kIHRoZSByZXF1ZXN0IHRvLlxuICovXG5cbm1vZHVsZS5leHBvcnRzLmVuY29kZUJvZHkgPSBlbmNvZGVCb2R5O1xuIl19 \ No newline at end of file diff --git a/lib/cryptoUtils.js b/lib/cryptoUtils.js new file mode 100644 index 0000000000..5267fc1838 --- /dev/null +++ b/lib/cryptoUtils.js @@ -0,0 +1,62 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.randomHexString = randomHexString; +exports.randomString = randomString; +exports.newObjectId = newObjectId; +exports.newToken = newToken; +exports.md5Hash = md5Hash; + +var _crypto = require("crypto"); + +// Returns a new random hex string of the given even size. +function randomHexString(size) { + if (size === 0) { + throw new Error('Zero-length randomHexString is useless.'); + } + + if (size % 2 !== 0) { + throw new Error('randomHexString size must be divisible by 2.'); + } + + return (0, _crypto.randomBytes)(size / 2).toString('hex'); +} // Returns a new random alphanumeric string of the given size. +// +// Note: to simplify implementation, the result has slight modulo bias, +// because chars length of 62 doesn't divide the number of all bytes +// (256) evenly. Such bias is acceptable for most cases when the output +// length is long enough and doesn't need to be uniform. + + +function randomString(size) { + if (size === 0) { + throw new Error('Zero-length randomString is useless.'); + } + + const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789'; + let objectId = ''; + const bytes = (0, _crypto.randomBytes)(size); + + for (let i = 0; i < bytes.length; ++i) { + objectId += chars[bytes.readUInt8(i) % chars.length]; + } + + return objectId; +} // Returns a new random alphanumeric string suitable for object ID. + + +function newObjectId(size = 10) { + return randomString(size); +} // Returns a new random hex string suitable for secure tokens. + + +function newToken() { + return randomHexString(32); +} + +function md5Hash(string) { + return (0, _crypto.createHash)('md5').update(string).digest('hex'); +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jcnlwdG9VdGlscy5qcyJdLCJuYW1lcyI6WyJyYW5kb21IZXhTdHJpbmciLCJzaXplIiwiRXJyb3IiLCJ0b1N0cmluZyIsInJhbmRvbVN0cmluZyIsImNoYXJzIiwib2JqZWN0SWQiLCJieXRlcyIsImkiLCJsZW5ndGgiLCJyZWFkVUludDgiLCJuZXdPYmplY3RJZCIsIm5ld1Rva2VuIiwibWQ1SGFzaCIsInN0cmluZyIsInVwZGF0ZSIsImRpZ2VzdCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFFQTs7QUFFQTtBQUNPLFNBQVNBLGVBQVQsQ0FBeUJDLElBQXpCLEVBQStDO0FBQ3BELE1BQUlBLElBQUksS0FBSyxDQUFiLEVBQWdCO0FBQ2QsVUFBTSxJQUFJQyxLQUFKLENBQVUseUNBQVYsQ0FBTjtBQUNEOztBQUNELE1BQUlELElBQUksR0FBRyxDQUFQLEtBQWEsQ0FBakIsRUFBb0I7QUFDbEIsVUFBTSxJQUFJQyxLQUFKLENBQVUsOENBQVYsQ0FBTjtBQUNEOztBQUNELFNBQU8seUJBQVlELElBQUksR0FBRyxDQUFuQixFQUFzQkUsUUFBdEIsQ0FBK0IsS0FBL0IsQ0FBUDtBQUNELEMsQ0FFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNPLFNBQVNDLFlBQVQsQ0FBc0JILElBQXRCLEVBQTRDO0FBQ2pELE1BQUlBLElBQUksS0FBSyxDQUFiLEVBQWdCO0FBQ2QsVUFBTSxJQUFJQyxLQUFKLENBQVUsc0NBQVYsQ0FBTjtBQUNEOztBQUNELFFBQU1HLEtBQUssR0FBRywrQkFBK0IsNEJBQS9CLEdBQThELFlBQTVFO0FBQ0EsTUFBSUMsUUFBUSxHQUFHLEVBQWY7QUFDQSxRQUFNQyxLQUFLLEdBQUcseUJBQVlOLElBQVosQ0FBZDs7QUFDQSxPQUFLLElBQUlPLENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUdELEtBQUssQ0FBQ0UsTUFBMUIsRUFBa0MsRUFBRUQsQ0FBcEMsRUFBdUM7QUFDckNGLElBQUFBLFFBQVEsSUFBSUQsS0FBSyxDQUFDRSxLQUFLLENBQUNHLFNBQU4sQ0FBZ0JGLENBQWhCLElBQXFCSCxLQUFLLENBQUNJLE1BQTVCLENBQWpCO0FBQ0Q7O0FBQ0QsU0FBT0gsUUFBUDtBQUNELEMsQ0FFRDs7O0FBQ08sU0FBU0ssV0FBVCxDQUFxQlYsSUFBWSxHQUFHLEVBQXBDLEVBQWdEO0FBQ3JELFNBQU9HLFlBQVksQ0FBQ0gsSUFBRCxDQUFuQjtBQUNELEMsQ0FFRDs7O0FBQ08sU0FBU1csUUFBVCxHQUE0QjtBQUNqQyxTQUFPWixlQUFlLENBQUMsRUFBRCxDQUF0QjtBQUNEOztBQUVNLFNBQVNhLE9BQVQsQ0FBaUJDLE1BQWpCLEVBQXlDO0FBQzlDLFNBQU8sd0JBQVcsS0FBWCxFQUFrQkMsTUFBbEIsQ0FBeUJELE1BQXpCLEVBQWlDRSxNQUFqQyxDQUF3QyxLQUF4QyxDQUFQO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBAZmxvdyAqL1xuXG5pbXBvcnQgeyByYW5kb21CeXRlcywgY3JlYXRlSGFzaCB9IGZyb20gJ2NyeXB0byc7XG5cbi8vIFJldHVybnMgYSBuZXcgcmFuZG9tIGhleCBzdHJpbmcgb2YgdGhlIGdpdmVuIGV2ZW4gc2l6ZS5cbmV4cG9ydCBmdW5jdGlvbiByYW5kb21IZXhTdHJpbmcoc2l6ZTogbnVtYmVyKTogc3RyaW5nIHtcbiAgaWYgKHNpemUgPT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1plcm8tbGVuZ3RoIHJhbmRvbUhleFN0cmluZyBpcyB1c2VsZXNzLicpO1xuICB9XG4gIGlmIChzaXplICUgMiAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcigncmFuZG9tSGV4U3RyaW5nIHNpemUgbXVzdCBiZSBkaXZpc2libGUgYnkgMi4nKTtcbiAgfVxuICByZXR1cm4gcmFuZG9tQnl0ZXMoc2l6ZSAvIDIpLnRvU3RyaW5nKCdoZXgnKTtcbn1cblxuLy8gUmV0dXJucyBhIG5ldyByYW5kb20gYWxwaGFudW1lcmljIHN0cmluZyBvZiB0aGUgZ2l2ZW4gc2l6ZS5cbi8vXG4vLyBOb3RlOiB0byBzaW1wbGlmeSBpbXBsZW1lbnRhdGlvbiwgdGhlIHJlc3VsdCBoYXMgc2xpZ2h0IG1vZHVsbyBiaWFzLFxuLy8gYmVjYXVzZSBjaGFycyBsZW5ndGggb2YgNjIgZG9lc24ndCBkaXZpZGUgdGhlIG51bWJlciBvZiBhbGwgYnl0ZXNcbi8vICgyNTYpIGV2ZW5seS4gU3VjaCBiaWFzIGlzIGFjY2VwdGFibGUgZm9yIG1vc3QgY2FzZXMgd2hlbiB0aGUgb3V0cHV0XG4vLyBsZW5ndGggaXMgbG9uZyBlbm91Z2ggYW5kIGRvZXNuJ3QgbmVlZCB0byBiZSB1bmlmb3JtLlxuZXhwb3J0IGZ1bmN0aW9uIHJhbmRvbVN0cmluZyhzaXplOiBudW1iZXIpOiBzdHJpbmcge1xuICBpZiAoc2l6ZSA9PT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignWmVyby1sZW5ndGggcmFuZG9tU3RyaW5nIGlzIHVzZWxlc3MuJyk7XG4gIH1cbiAgY29uc3QgY2hhcnMgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVonICsgJ2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6JyArICcwMTIzNDU2Nzg5JztcbiAgbGV0IG9iamVjdElkID0gJyc7XG4gIGNvbnN0IGJ5dGVzID0gcmFuZG9tQnl0ZXMoc2l6ZSk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyArK2kpIHtcbiAgICBvYmplY3RJZCArPSBjaGFyc1tieXRlcy5yZWFkVUludDgoaSkgJSBjaGFycy5sZW5ndGhdO1xuICB9XG4gIHJldHVybiBvYmplY3RJZDtcbn1cblxuLy8gUmV0dXJucyBhIG5ldyByYW5kb20gYWxwaGFudW1lcmljIHN0cmluZyBzdWl0YWJsZSBmb3Igb2JqZWN0IElELlxuZXhwb3J0IGZ1bmN0aW9uIG5ld09iamVjdElkKHNpemU6IG51bWJlciA9IDEwKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJhbmRvbVN0cmluZyhzaXplKTtcbn1cblxuLy8gUmV0dXJucyBhIG5ldyByYW5kb20gaGV4IHN0cmluZyBzdWl0YWJsZSBmb3Igc2VjdXJlIHRva2Vucy5cbmV4cG9ydCBmdW5jdGlvbiBuZXdUb2tlbigpOiBzdHJpbmcge1xuICByZXR1cm4gcmFuZG9tSGV4U3RyaW5nKDMyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1kNUhhc2goc3RyaW5nOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gY3JlYXRlSGFzaCgnbWQ1JykudXBkYXRlKHN0cmluZykuZGlnZXN0KCdoZXgnKTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/defaults.js b/lib/defaults.js new file mode 100644 index 0000000000..d824d3ba1d --- /dev/null +++ b/lib/defaults.js @@ -0,0 +1,60 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.DefaultMongoURI = exports.default = void 0; + +var _parsers = require("./Options/parsers"); + +const { + ParseServerOptions +} = require('./Options/Definitions'); + +const logsFolder = (() => { + let folder = './logs/'; + + if (typeof process !== 'undefined' && process.env.TESTING === '1') { + folder = './test_logs/'; + } + + if (process.env.PARSE_SERVER_LOGS_FOLDER) { + folder = (0, _parsers.nullParser)(process.env.PARSE_SERVER_LOGS_FOLDER); + } + + return folder; +})(); + +const { + verbose, + level +} = (() => { + const verbose = process.env.VERBOSE ? true : false; + return { + verbose, + level: verbose ? 'verbose' : undefined + }; +})(); + +const DefinitionDefaults = Object.keys(ParseServerOptions).reduce((memo, key) => { + const def = ParseServerOptions[key]; + + if (Object.prototype.hasOwnProperty.call(def, 'default')) { + memo[key] = def.default; + } + + return memo; +}, {}); +const computedDefaults = { + jsonLogs: process.env.JSON_LOGS || false, + logsFolder, + verbose, + level +}; + +var _default = Object.assign({}, DefinitionDefaults, computedDefaults); + +exports.default = _default; +const DefaultMongoURI = DefinitionDefaults.databaseURI; +exports.DefaultMongoURI = DefaultMongoURI; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9kZWZhdWx0cy5qcyJdLCJuYW1lcyI6WyJQYXJzZVNlcnZlck9wdGlvbnMiLCJyZXF1aXJlIiwibG9nc0ZvbGRlciIsImZvbGRlciIsInByb2Nlc3MiLCJlbnYiLCJURVNUSU5HIiwiUEFSU0VfU0VSVkVSX0xPR1NfRk9MREVSIiwidmVyYm9zZSIsImxldmVsIiwiVkVSQk9TRSIsInVuZGVmaW5lZCIsIkRlZmluaXRpb25EZWZhdWx0cyIsIk9iamVjdCIsImtleXMiLCJyZWR1Y2UiLCJtZW1vIiwia2V5IiwiZGVmIiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiZGVmYXVsdCIsImNvbXB1dGVkRGVmYXVsdHMiLCJqc29uTG9ncyIsIkpTT05fTE9HUyIsImFzc2lnbiIsIkRlZmF1bHRNb25nb1VSSSIsImRhdGFiYXNlVVJJIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0EsTUFBTTtBQUFFQSxFQUFBQTtBQUFGLElBQXlCQyxPQUFPLENBQUMsdUJBQUQsQ0FBdEM7O0FBQ0EsTUFBTUMsVUFBVSxHQUFHLENBQUMsTUFBTTtBQUN4QixNQUFJQyxNQUFNLEdBQUcsU0FBYjs7QUFDQSxNQUFJLE9BQU9DLE9BQVAsS0FBbUIsV0FBbkIsSUFBa0NBLE9BQU8sQ0FBQ0MsR0FBUixDQUFZQyxPQUFaLEtBQXdCLEdBQTlELEVBQW1FO0FBQ2pFSCxJQUFBQSxNQUFNLEdBQUcsY0FBVDtBQUNEOztBQUNELE1BQUlDLE9BQU8sQ0FBQ0MsR0FBUixDQUFZRSx3QkFBaEIsRUFBMEM7QUFDeENKLElBQUFBLE1BQU0sR0FBRyx5QkFBV0MsT0FBTyxDQUFDQyxHQUFSLENBQVlFLHdCQUF2QixDQUFUO0FBQ0Q7O0FBQ0QsU0FBT0osTUFBUDtBQUNELENBVGtCLEdBQW5COztBQVdBLE1BQU07QUFBRUssRUFBQUEsT0FBRjtBQUFXQyxFQUFBQTtBQUFYLElBQXFCLENBQUMsTUFBTTtBQUNoQyxRQUFNRCxPQUFPLEdBQUdKLE9BQU8sQ0FBQ0MsR0FBUixDQUFZSyxPQUFaLEdBQXNCLElBQXRCLEdBQTZCLEtBQTdDO0FBQ0EsU0FBTztBQUFFRixJQUFBQSxPQUFGO0FBQVdDLElBQUFBLEtBQUssRUFBRUQsT0FBTyxHQUFHLFNBQUgsR0FBZUc7QUFBeEMsR0FBUDtBQUNELENBSDBCLEdBQTNCOztBQUtBLE1BQU1DLGtCQUFrQixHQUFHQyxNQUFNLENBQUNDLElBQVAsQ0FBWWQsa0JBQVosRUFBZ0NlLE1BQWhDLENBQXVDLENBQUNDLElBQUQsRUFBT0MsR0FBUCxLQUFlO0FBQy9FLFFBQU1DLEdBQUcsR0FBR2xCLGtCQUFrQixDQUFDaUIsR0FBRCxDQUE5Qjs7QUFDQSxNQUFJSixNQUFNLENBQUNNLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUFxQ0gsR0FBckMsRUFBMEMsU0FBMUMsQ0FBSixFQUEwRDtBQUN4REYsSUFBQUEsSUFBSSxDQUFDQyxHQUFELENBQUosR0FBWUMsR0FBRyxDQUFDSSxPQUFoQjtBQUNEOztBQUNELFNBQU9OLElBQVA7QUFDRCxDQU4wQixFQU14QixFQU53QixDQUEzQjtBQVFBLE1BQU1PLGdCQUFnQixHQUFHO0FBQ3ZCQyxFQUFBQSxRQUFRLEVBQUVwQixPQUFPLENBQUNDLEdBQVIsQ0FBWW9CLFNBQVosSUFBeUIsS0FEWjtBQUV2QnZCLEVBQUFBLFVBRnVCO0FBR3ZCTSxFQUFBQSxPQUh1QjtBQUl2QkMsRUFBQUE7QUFKdUIsQ0FBekI7O2VBT2VJLE1BQU0sQ0FBQ2EsTUFBUCxDQUFjLEVBQWQsRUFBa0JkLGtCQUFsQixFQUFzQ1csZ0JBQXRDLEM7OztBQUNSLE1BQU1JLGVBQWUsR0FBR2Ysa0JBQWtCLENBQUNnQixXQUEzQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IG51bGxQYXJzZXIgfSBmcm9tICcuL09wdGlvbnMvcGFyc2Vycyc7XG5jb25zdCB7IFBhcnNlU2VydmVyT3B0aW9ucyB9ID0gcmVxdWlyZSgnLi9PcHRpb25zL0RlZmluaXRpb25zJyk7XG5jb25zdCBsb2dzRm9sZGVyID0gKCgpID0+IHtcbiAgbGV0IGZvbGRlciA9ICcuL2xvZ3MvJztcbiAgaWYgKHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLmVudi5URVNUSU5HID09PSAnMScpIHtcbiAgICBmb2xkZXIgPSAnLi90ZXN0X2xvZ3MvJztcbiAgfVxuICBpZiAocHJvY2Vzcy5lbnYuUEFSU0VfU0VSVkVSX0xPR1NfRk9MREVSKSB7XG4gICAgZm9sZGVyID0gbnVsbFBhcnNlcihwcm9jZXNzLmVudi5QQVJTRV9TRVJWRVJfTE9HU19GT0xERVIpO1xuICB9XG4gIHJldHVybiBmb2xkZXI7XG59KSgpO1xuXG5jb25zdCB7IHZlcmJvc2UsIGxldmVsIH0gPSAoKCkgPT4ge1xuICBjb25zdCB2ZXJib3NlID0gcHJvY2Vzcy5lbnYuVkVSQk9TRSA/IHRydWUgOiBmYWxzZTtcbiAgcmV0dXJuIHsgdmVyYm9zZSwgbGV2ZWw6IHZlcmJvc2UgPyAndmVyYm9zZScgOiB1bmRlZmluZWQgfTtcbn0pKCk7XG5cbmNvbnN0IERlZmluaXRpb25EZWZhdWx0cyA9IE9iamVjdC5rZXlzKFBhcnNlU2VydmVyT3B0aW9ucykucmVkdWNlKChtZW1vLCBrZXkpID0+IHtcbiAgY29uc3QgZGVmID0gUGFyc2VTZXJ2ZXJPcHRpb25zW2tleV07XG4gIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZGVmLCAnZGVmYXVsdCcpKSB7XG4gICAgbWVtb1trZXldID0gZGVmLmRlZmF1bHQ7XG4gIH1cbiAgcmV0dXJuIG1lbW87XG59LCB7fSk7XG5cbmNvbnN0IGNvbXB1dGVkRGVmYXVsdHMgPSB7XG4gIGpzb25Mb2dzOiBwcm9jZXNzLmVudi5KU09OX0xPR1MgfHwgZmFsc2UsXG4gIGxvZ3NGb2xkZXIsXG4gIHZlcmJvc2UsXG4gIGxldmVsLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgT2JqZWN0LmFzc2lnbih7fSwgRGVmaW5pdGlvbkRlZmF1bHRzLCBjb21wdXRlZERlZmF1bHRzKTtcbmV4cG9ydCBjb25zdCBEZWZhdWx0TW9uZ29VUkkgPSBEZWZpbml0aW9uRGVmYXVsdHMuZGF0YWJhc2VVUkk7XG4iXX0= \ No newline at end of file diff --git a/lib/deprecated.js b/lib/deprecated.js new file mode 100644 index 0000000000..ea008a18d6 --- /dev/null +++ b/lib/deprecated.js @@ -0,0 +1,13 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.useExternal = useExternal; + +function useExternal(name, moduleName) { + return function () { + throw `${name} is not provided by parse-server anymore; please install ${moduleName}`; + }; +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9kZXByZWNhdGVkLmpzIl0sIm5hbWVzIjpbInVzZUV4dGVybmFsIiwibmFtZSIsIm1vZHVsZU5hbWUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBTyxTQUFTQSxXQUFULENBQXFCQyxJQUFyQixFQUEyQkMsVUFBM0IsRUFBdUM7QUFDNUMsU0FBTyxZQUFZO0FBQ2pCLFVBQU8sR0FBRUQsSUFBSyw0REFBMkRDLFVBQVcsRUFBcEY7QUFDRCxHQUZEO0FBR0QiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZnVuY3Rpb24gdXNlRXh0ZXJuYWwobmFtZSwgbW9kdWxlTmFtZSkge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHRocm93IGAke25hbWV9IGlzIG5vdCBwcm92aWRlZCBieSBwYXJzZS1zZXJ2ZXIgYW55bW9yZTsgcGxlYXNlIGluc3RhbGwgJHttb2R1bGVOYW1lfWA7XG4gIH07XG59XG4iXX0= \ No newline at end of file diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000000..e34f529164 --- /dev/null +++ b/lib/index.js @@ -0,0 +1,107 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +Object.defineProperty(exports, "S3Adapter", { + enumerable: true, + get: function () { + return _s3FilesAdapter.default; + } +}); +Object.defineProperty(exports, "FileSystemAdapter", { + enumerable: true, + get: function () { + return _fsFilesAdapter.default; + } +}); +Object.defineProperty(exports, "InMemoryCacheAdapter", { + enumerable: true, + get: function () { + return _InMemoryCacheAdapter.default; + } +}); +Object.defineProperty(exports, "NullCacheAdapter", { + enumerable: true, + get: function () { + return _NullCacheAdapter.default; + } +}); +Object.defineProperty(exports, "RedisCacheAdapter", { + enumerable: true, + get: function () { + return _RedisCacheAdapter.default; + } +}); +Object.defineProperty(exports, "LRUCacheAdapter", { + enumerable: true, + get: function () { + return _LRUCache.default; + } +}); +Object.defineProperty(exports, "PushWorker", { + enumerable: true, + get: function () { + return _PushWorker.PushWorker; + } +}); +Object.defineProperty(exports, "ParseGraphQLServer", { + enumerable: true, + get: function () { + return _ParseGraphQLServer.ParseGraphQLServer; + } +}); +exports.TestUtils = exports.ParseServer = exports.GCSAdapter = exports.default = void 0; + +var _ParseServer2 = _interopRequireDefault(require("./ParseServer")); + +var _s3FilesAdapter = _interopRequireDefault(require("@parse/s3-files-adapter")); + +var _fsFilesAdapter = _interopRequireDefault(require("@parse/fs-files-adapter")); + +var _InMemoryCacheAdapter = _interopRequireDefault(require("./Adapters/Cache/InMemoryCacheAdapter")); + +var _NullCacheAdapter = _interopRequireDefault(require("./Adapters/Cache/NullCacheAdapter")); + +var _RedisCacheAdapter = _interopRequireDefault(require("./Adapters/Cache/RedisCacheAdapter")); + +var _LRUCache = _interopRequireDefault(require("./Adapters/Cache/LRUCache.js")); + +var TestUtils = _interopRequireWildcard(require("./TestUtils")); + +exports.TestUtils = TestUtils; + +var _deprecated = require("./deprecated"); + +var _logger = require("./logger"); + +var _PushWorker = require("./Push/PushWorker"); + +var _Options = require("./Options"); + +var _ParseGraphQLServer = require("./GraphQL/ParseGraphQLServer"); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// Factory function +const _ParseServer = function (options) { + const server = new _ParseServer2.default(options); + return server.app; +}; // Mount the create liveQueryServer + + +exports.ParseServer = _ParseServer; +_ParseServer.createLiveQueryServer = _ParseServer2.default.createLiveQueryServer; +_ParseServer.start = _ParseServer2.default.start; +const GCSAdapter = (0, _deprecated.useExternal)('GCSAdapter', '@parse/gcs-files-adapter'); +exports.GCSAdapter = GCSAdapter; +Object.defineProperty(module.exports, 'logger', { + get: _logger.getLogger +}); +var _default = _ParseServer2.default; +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC5qcyJdLCJuYW1lcyI6WyJfUGFyc2VTZXJ2ZXIiLCJvcHRpb25zIiwic2VydmVyIiwiUGFyc2VTZXJ2ZXIiLCJhcHAiLCJjcmVhdGVMaXZlUXVlcnlTZXJ2ZXIiLCJzdGFydCIsIkdDU0FkYXB0ZXIiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsIm1vZHVsZSIsImV4cG9ydHMiLCJnZXQiLCJnZXRMb2dnZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVBO0FBQ0EsTUFBTUEsWUFBWSxHQUFHLFVBQVVDLE9BQVYsRUFBdUM7QUFDMUQsUUFBTUMsTUFBTSxHQUFHLElBQUlDLHFCQUFKLENBQWdCRixPQUFoQixDQUFmO0FBQ0EsU0FBT0MsTUFBTSxDQUFDRSxHQUFkO0FBQ0QsQ0FIRCxDLENBSUE7Ozs7QUFDQUosWUFBWSxDQUFDSyxxQkFBYixHQUFxQ0Ysc0JBQVlFLHFCQUFqRDtBQUNBTCxZQUFZLENBQUNNLEtBQWIsR0FBcUJILHNCQUFZRyxLQUFqQztBQUVBLE1BQU1DLFVBQVUsR0FBRyw2QkFBWSxZQUFaLEVBQTBCLDBCQUExQixDQUFuQjs7QUFFQUMsTUFBTSxDQUFDQyxjQUFQLENBQXNCQyxNQUFNLENBQUNDLE9BQTdCLEVBQXNDLFFBQXRDLEVBQWdEO0FBQzlDQyxFQUFBQSxHQUFHLEVBQUVDO0FBRHlDLENBQWhEO2VBSWVWLHFCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFBhcnNlU2VydmVyIGZyb20gJy4vUGFyc2VTZXJ2ZXInO1xuaW1wb3J0IFMzQWRhcHRlciBmcm9tICdAcGFyc2UvczMtZmlsZXMtYWRhcHRlcic7XG5pbXBvcnQgRmlsZVN5c3RlbUFkYXB0ZXIgZnJvbSAnQHBhcnNlL2ZzLWZpbGVzLWFkYXB0ZXInO1xuaW1wb3J0IEluTWVtb3J5Q2FjaGVBZGFwdGVyIGZyb20gJy4vQWRhcHRlcnMvQ2FjaGUvSW5NZW1vcnlDYWNoZUFkYXB0ZXInO1xuaW1wb3J0IE51bGxDYWNoZUFkYXB0ZXIgZnJvbSAnLi9BZGFwdGVycy9DYWNoZS9OdWxsQ2FjaGVBZGFwdGVyJztcbmltcG9ydCBSZWRpc0NhY2hlQWRhcHRlciBmcm9tICcuL0FkYXB0ZXJzL0NhY2hlL1JlZGlzQ2FjaGVBZGFwdGVyJztcbmltcG9ydCBMUlVDYWNoZUFkYXB0ZXIgZnJvbSAnLi9BZGFwdGVycy9DYWNoZS9MUlVDYWNoZS5qcyc7XG5pbXBvcnQgKiBhcyBUZXN0VXRpbHMgZnJvbSAnLi9UZXN0VXRpbHMnO1xuaW1wb3J0IHsgdXNlRXh0ZXJuYWwgfSBmcm9tICcuL2RlcHJlY2F0ZWQnO1xuaW1wb3J0IHsgZ2V0TG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXInO1xuaW1wb3J0IHsgUHVzaFdvcmtlciB9IGZyb20gJy4vUHVzaC9QdXNoV29ya2VyJztcbmltcG9ydCB7IFBhcnNlU2VydmVyT3B0aW9ucyB9IGZyb20gJy4vT3B0aW9ucyc7XG5pbXBvcnQgeyBQYXJzZUdyYXBoUUxTZXJ2ZXIgfSBmcm9tICcuL0dyYXBoUUwvUGFyc2VHcmFwaFFMU2VydmVyJztcblxuLy8gRmFjdG9yeSBmdW5jdGlvblxuY29uc3QgX1BhcnNlU2VydmVyID0gZnVuY3Rpb24gKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucykge1xuICBjb25zdCBzZXJ2ZXIgPSBuZXcgUGFyc2VTZXJ2ZXIob3B0aW9ucyk7XG4gIHJldHVybiBzZXJ2ZXIuYXBwO1xufTtcbi8vIE1vdW50IHRoZSBjcmVhdGUgbGl2ZVF1ZXJ5U2VydmVyXG5fUGFyc2VTZXJ2ZXIuY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyID0gUGFyc2VTZXJ2ZXIuY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyO1xuX1BhcnNlU2VydmVyLnN0YXJ0ID0gUGFyc2VTZXJ2ZXIuc3RhcnQ7XG5cbmNvbnN0IEdDU0FkYXB0ZXIgPSB1c2VFeHRlcm5hbCgnR0NTQWRhcHRlcicsICdAcGFyc2UvZ2NzLWZpbGVzLWFkYXB0ZXInKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnbG9nZ2VyJywge1xuICBnZXQ6IGdldExvZ2dlcixcbn0pO1xuXG5leHBvcnQgZGVmYXVsdCBQYXJzZVNlcnZlcjtcbmV4cG9ydCB7XG4gIFMzQWRhcHRlcixcbiAgR0NTQWRhcHRlcixcbiAgRmlsZVN5c3RlbUFkYXB0ZXIsXG4gIEluTWVtb3J5Q2FjaGVBZGFwdGVyLFxuICBOdWxsQ2FjaGVBZGFwdGVyLFxuICBSZWRpc0NhY2hlQWRhcHRlcixcbiAgTFJVQ2FjaGVBZGFwdGVyLFxuICBUZXN0VXRpbHMsXG4gIFB1c2hXb3JrZXIsXG4gIFBhcnNlR3JhcGhRTFNlcnZlcixcbiAgX1BhcnNlU2VydmVyIGFzIFBhcnNlU2VydmVyLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/logger.js b/lib/logger.js new file mode 100644 index 0000000000..bd58e6bce9 --- /dev/null +++ b/lib/logger.js @@ -0,0 +1,47 @@ +'use strict'; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.setLogger = setLogger; +exports.getLogger = getLogger; + +var _defaults = _interopRequireDefault(require("./defaults")); + +var _WinstonLoggerAdapter = require("./Adapters/Logger/WinstonLoggerAdapter"); + +var _LoggerController = require("./Controllers/LoggerController"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// Used for Separate Live Query Server +function defaultLogger() { + const options = { + logsFolder: _defaults.default.logsFolder, + jsonLogs: _defaults.default.jsonLogs, + verbose: _defaults.default.verbose, + silent: _defaults.default.silent + }; + const adapter = new _WinstonLoggerAdapter.WinstonLoggerAdapter(options); + return new _LoggerController.LoggerController(adapter, null, options); +} + +let logger = defaultLogger(); + +function setLogger(aLogger) { + logger = aLogger; +} + +function getLogger() { + return logger; +} // for: `import logger from './logger'` + + +Object.defineProperty(module.exports, 'default', { + get: getLogger +}); // for: `import { logger } from './logger'` + +Object.defineProperty(module.exports, 'logger', { + get: getLogger +}); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9sb2dnZXIuanMiXSwibmFtZXMiOlsiZGVmYXVsdExvZ2dlciIsIm9wdGlvbnMiLCJsb2dzRm9sZGVyIiwiZGVmYXVsdHMiLCJqc29uTG9ncyIsInZlcmJvc2UiLCJzaWxlbnQiLCJhZGFwdGVyIiwiV2luc3RvbkxvZ2dlckFkYXB0ZXIiLCJMb2dnZXJDb250cm9sbGVyIiwibG9nZ2VyIiwic2V0TG9nZ2VyIiwiYUxvZ2dlciIsImdldExvZ2dlciIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwibW9kdWxlIiwiZXhwb3J0cyIsImdldCJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFFQTtBQUNBLFNBQVNBLGFBQVQsR0FBeUI7QUFDdkIsUUFBTUMsT0FBTyxHQUFHO0FBQ2RDLElBQUFBLFVBQVUsRUFBRUMsa0JBQVNELFVBRFA7QUFFZEUsSUFBQUEsUUFBUSxFQUFFRCxrQkFBU0MsUUFGTDtBQUdkQyxJQUFBQSxPQUFPLEVBQUVGLGtCQUFTRSxPQUhKO0FBSWRDLElBQUFBLE1BQU0sRUFBRUgsa0JBQVNHO0FBSkgsR0FBaEI7QUFNQSxRQUFNQyxPQUFPLEdBQUcsSUFBSUMsMENBQUosQ0FBeUJQLE9BQXpCLENBQWhCO0FBQ0EsU0FBTyxJQUFJUSxrQ0FBSixDQUFxQkYsT0FBckIsRUFBOEIsSUFBOUIsRUFBb0NOLE9BQXBDLENBQVA7QUFDRDs7QUFFRCxJQUFJUyxNQUFNLEdBQUdWLGFBQWEsRUFBMUI7O0FBRU8sU0FBU1csU0FBVCxDQUFtQkMsT0FBbkIsRUFBNEI7QUFDakNGLEVBQUFBLE1BQU0sR0FBR0UsT0FBVDtBQUNEOztBQUVNLFNBQVNDLFNBQVQsR0FBcUI7QUFDMUIsU0FBT0gsTUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0FJLE1BQU0sQ0FBQ0MsY0FBUCxDQUFzQkMsTUFBTSxDQUFDQyxPQUE3QixFQUFzQyxTQUF0QyxFQUFpRDtBQUMvQ0MsRUFBQUEsR0FBRyxFQUFFTDtBQUQwQyxDQUFqRCxFLENBSUE7O0FBQ0FDLE1BQU0sQ0FBQ0MsY0FBUCxDQUFzQkMsTUFBTSxDQUFDQyxPQUE3QixFQUFzQyxRQUF0QyxFQUFnRDtBQUM5Q0MsRUFBQUEsR0FBRyxFQUFFTDtBQUR5QyxDQUFoRCIsInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbmltcG9ydCBkZWZhdWx0cyBmcm9tICcuL2RlZmF1bHRzJztcbmltcG9ydCB7IFdpbnN0b25Mb2dnZXJBZGFwdGVyIH0gZnJvbSAnLi9BZGFwdGVycy9Mb2dnZXIvV2luc3RvbkxvZ2dlckFkYXB0ZXInO1xuaW1wb3J0IHsgTG9nZ2VyQ29udHJvbGxlciB9IGZyb20gJy4vQ29udHJvbGxlcnMvTG9nZ2VyQ29udHJvbGxlcic7XG5cbi8vIFVzZWQgZm9yIFNlcGFyYXRlIExpdmUgUXVlcnkgU2VydmVyXG5mdW5jdGlvbiBkZWZhdWx0TG9nZ2VyKCkge1xuICBjb25zdCBvcHRpb25zID0ge1xuICAgIGxvZ3NGb2xkZXI6IGRlZmF1bHRzLmxvZ3NGb2xkZXIsXG4gICAganNvbkxvZ3M6IGRlZmF1bHRzLmpzb25Mb2dzLFxuICAgIHZlcmJvc2U6IGRlZmF1bHRzLnZlcmJvc2UsXG4gICAgc2lsZW50OiBkZWZhdWx0cy5zaWxlbnQsXG4gIH07XG4gIGNvbnN0IGFkYXB0ZXIgPSBuZXcgV2luc3RvbkxvZ2dlckFkYXB0ZXIob3B0aW9ucyk7XG4gIHJldHVybiBuZXcgTG9nZ2VyQ29udHJvbGxlcihhZGFwdGVyLCBudWxsLCBvcHRpb25zKTtcbn1cblxubGV0IGxvZ2dlciA9IGRlZmF1bHRMb2dnZXIoKTtcblxuZXhwb3J0IGZ1bmN0aW9uIHNldExvZ2dlcihhTG9nZ2VyKSB7XG4gIGxvZ2dlciA9IGFMb2dnZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRMb2dnZXIoKSB7XG4gIHJldHVybiBsb2dnZXI7XG59XG5cbi8vIGZvcjogYGltcG9ydCBsb2dnZXIgZnJvbSAnLi9sb2dnZXInYFxuT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnZGVmYXVsdCcsIHtcbiAgZ2V0OiBnZXRMb2dnZXIsXG59KTtcblxuLy8gZm9yOiBgaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXInYFxuT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnbG9nZ2VyJywge1xuICBnZXQ6IGdldExvZ2dlcixcbn0pO1xuIl19 \ No newline at end of file diff --git a/lib/middlewares.js b/lib/middlewares.js new file mode 100644 index 0000000000..ccaadd2ddc --- /dev/null +++ b/lib/middlewares.js @@ -0,0 +1,492 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.handleParseHeaders = handleParseHeaders; +exports.allowCrossDomain = allowCrossDomain; +exports.allowMethodOverride = allowMethodOverride; +exports.handleParseErrors = handleParseErrors; +exports.enforceMasterKeyAccess = enforceMasterKeyAccess; +exports.promiseEnforceMasterKeyAccess = promiseEnforceMasterKeyAccess; +exports.promiseEnsureIdempotency = promiseEnsureIdempotency; +exports.DEFAULT_ALLOWED_HEADERS = void 0; + +var _cache = _interopRequireDefault(require("./cache")); + +var _node = _interopRequireDefault(require("parse/node")); + +var _Auth = _interopRequireDefault(require("./Auth")); + +var _Config = _interopRequireDefault(require("./Config")); + +var _ClientSDK = _interopRequireDefault(require("./ClientSDK")); + +var _logger = _interopRequireDefault(require("./logger")); + +var _rest = _interopRequireDefault(require("./rest")); + +var _MongoStorageAdapter = _interopRequireDefault(require("./Adapters/Storage/Mongo/MongoStorageAdapter")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const DEFAULT_ALLOWED_HEADERS = 'X-Parse-Master-Key, X-Parse-REST-API-Key, X-Parse-Javascript-Key, X-Parse-Application-Id, X-Parse-Client-Version, X-Parse-Session-Token, X-Requested-With, X-Parse-Revocable-Session, X-Parse-Request-Id, Content-Type, Pragma, Cache-Control'; +exports.DEFAULT_ALLOWED_HEADERS = DEFAULT_ALLOWED_HEADERS; + +const getMountForRequest = function (req) { + const mountPathLength = req.originalUrl.length - req.url.length; + const mountPath = req.originalUrl.slice(0, mountPathLength); + return req.protocol + '://' + req.get('host') + mountPath; +}; // Checks that the request is authorized for this app and checks user +// auth too. +// The bodyparser should run before this middleware. +// Adds info to the request: +// req.config - the Config for this app +// req.auth - the Auth for this request + + +function handleParseHeaders(req, res, next) { + var mount = getMountForRequest(req); + var info = { + appId: req.get('X-Parse-Application-Id'), + sessionToken: req.get('X-Parse-Session-Token'), + masterKey: req.get('X-Parse-Master-Key'), + installationId: req.get('X-Parse-Installation-Id'), + clientKey: req.get('X-Parse-Client-Key'), + javascriptKey: req.get('X-Parse-Javascript-Key'), + dotNetKey: req.get('X-Parse-Windows-Key'), + restAPIKey: req.get('X-Parse-REST-API-Key'), + clientVersion: req.get('X-Parse-Client-Version'), + context: {} + }; + var basicAuth = httpAuth(req); + + if (basicAuth) { + var basicAuthAppId = basicAuth.appId; + + if (_cache.default.get(basicAuthAppId)) { + info.appId = basicAuthAppId; + info.masterKey = basicAuth.masterKey || info.masterKey; + info.javascriptKey = basicAuth.javascriptKey || info.javascriptKey; + } + } + + if (req.body) { + // Unity SDK sends a _noBody key which needs to be removed. + // Unclear at this point if action needs to be taken. + delete req.body._noBody; + } + + var fileViaJSON = false; + + if (!info.appId || !_cache.default.get(info.appId)) { + // See if we can find the app id on the body. + if (req.body instanceof Buffer) { + // The only chance to find the app id is if this is a file + // upload that actually is a JSON body. So try to parse it. + // https://github.com/parse-community/parse-server/issues/6589 + // It is also possible that the client is trying to upload a file but forgot + // to provide x-parse-app-id in header and parse a binary file will fail + try { + req.body = JSON.parse(req.body); + } catch (e) { + return invalidRequest(req, res); + } + + fileViaJSON = true; + } + + if (req.body) { + delete req.body._RevocableSession; + } + + if (req.body && req.body._ApplicationId && _cache.default.get(req.body._ApplicationId) && (!info.masterKey || _cache.default.get(req.body._ApplicationId).masterKey === info.masterKey)) { + info.appId = req.body._ApplicationId; + info.javascriptKey = req.body._JavaScriptKey || ''; + delete req.body._ApplicationId; + delete req.body._JavaScriptKey; // TODO: test that the REST API formats generated by the other + // SDKs are handled ok + + if (req.body._ClientVersion) { + info.clientVersion = req.body._ClientVersion; + delete req.body._ClientVersion; + } + + if (req.body._InstallationId) { + info.installationId = req.body._InstallationId; + delete req.body._InstallationId; + } + + if (req.body._SessionToken) { + info.sessionToken = req.body._SessionToken; + delete req.body._SessionToken; + } + + if (req.body._MasterKey) { + info.masterKey = req.body._MasterKey; + delete req.body._MasterKey; + } + + if (req.body._context && req.body._context instanceof Object) { + info.context = req.body._context; + delete req.body._context; + } + + if (req.body._ContentType) { + req.headers['content-type'] = req.body._ContentType; + delete req.body._ContentType; + } + } else { + return invalidRequest(req, res); + } + } + + if (info.sessionToken && typeof info.sessionToken !== 'string') { + info.sessionToken = info.sessionToken.toString(); + } + + if (info.clientVersion) { + info.clientSDK = _ClientSDK.default.fromString(info.clientVersion); + } + + if (fileViaJSON) { + req.fileData = req.body.fileData; // We need to repopulate req.body with a buffer + + var base64 = req.body.base64; + req.body = Buffer.from(base64, 'base64'); + } + + const clientIp = getClientIp(req); + info.app = _cache.default.get(info.appId); + req.config = _Config.default.get(info.appId, mount); + req.config.headers = req.headers || {}; + req.config.ip = clientIp; + req.info = info; + + if (info.masterKey && req.config.masterKeyIps && req.config.masterKeyIps.length !== 0 && req.config.masterKeyIps.indexOf(clientIp) === -1) { + return invalidRequest(req, res); + } + + var isMaster = info.masterKey === req.config.masterKey; + + if (isMaster) { + req.auth = new _Auth.default.Auth({ + config: req.config, + installationId: info.installationId, + isMaster: true + }); + next(); + return; + } + + var isReadOnlyMaster = info.masterKey === req.config.readOnlyMasterKey; + + if (typeof req.config.readOnlyMasterKey != 'undefined' && req.config.readOnlyMasterKey && isReadOnlyMaster) { + req.auth = new _Auth.default.Auth({ + config: req.config, + installationId: info.installationId, + isMaster: true, + isReadOnly: true + }); + next(); + return; + } // Client keys are not required in parse-server, but if any have been configured in the server, validate them + // to preserve original behavior. + + + const keys = ['clientKey', 'javascriptKey', 'dotNetKey', 'restAPIKey']; + const oneKeyConfigured = keys.some(function (key) { + return req.config[key] !== undefined; + }); + const oneKeyMatches = keys.some(function (key) { + return req.config[key] !== undefined && info[key] === req.config[key]; + }); + + if (oneKeyConfigured && !oneKeyMatches) { + return invalidRequest(req, res); + } + + if (req.url == '/login') { + delete info.sessionToken; + } + + if (req.userFromJWT) { + req.auth = new _Auth.default.Auth({ + config: req.config, + installationId: info.installationId, + isMaster: false, + user: req.userFromJWT + }); + next(); + return; + } + + if (!info.sessionToken) { + req.auth = new _Auth.default.Auth({ + config: req.config, + installationId: info.installationId, + isMaster: false + }); + next(); + return; + } + + return Promise.resolve().then(() => { + // handle the upgradeToRevocableSession path on it's own + if (info.sessionToken && req.url === '/upgradeToRevocableSession' && info.sessionToken.indexOf('r:') != 0) { + return _Auth.default.getAuthForLegacySessionToken({ + config: req.config, + installationId: info.installationId, + sessionToken: info.sessionToken + }); + } else { + return _Auth.default.getAuthForSessionToken({ + config: req.config, + installationId: info.installationId, + sessionToken: info.sessionToken + }); + } + }).then(auth => { + if (auth) { + req.auth = auth; + next(); + } + }).catch(error => { + if (error instanceof _node.default.Error) { + next(error); + return; + } else { + // TODO: Determine the correct error scenario. + req.config.loggerController.error('error getting auth for sessionToken', error); + throw new _node.default.Error(_node.default.Error.UNKNOWN_ERROR, error); + } + }); +} + +function getClientIp(req) { + if (req.headers['x-forwarded-for']) { + // try to get from x-forwared-for if it set (behind reverse proxy) + return req.headers['x-forwarded-for'].split(',')[0]; + } else if (req.connection && req.connection.remoteAddress) { + // no proxy, try getting from connection.remoteAddress + return req.connection.remoteAddress; + } else if (req.socket) { + // try to get it from req.socket + return req.socket.remoteAddress; + } else if (req.connection && req.connection.socket) { + // try to get it form the connection.socket + return req.connection.socket.remoteAddress; + } else { + // if non above, fallback. + return req.ip; + } +} + +function httpAuth(req) { + if (!(req.req || req).headers.authorization) return; + var header = (req.req || req).headers.authorization; + var appId, masterKey, javascriptKey; // parse header + + var authPrefix = 'basic '; + var match = header.toLowerCase().indexOf(authPrefix); + + if (match == 0) { + var encodedAuth = header.substring(authPrefix.length, header.length); + var credentials = decodeBase64(encodedAuth).split(':'); + + if (credentials.length == 2) { + appId = credentials[0]; + var key = credentials[1]; + var jsKeyPrefix = 'javascript-key='; + var matchKey = key.indexOf(jsKeyPrefix); + + if (matchKey == 0) { + javascriptKey = key.substring(jsKeyPrefix.length, key.length); + } else { + masterKey = key; + } + } + } + + return { + appId: appId, + masterKey: masterKey, + javascriptKey: javascriptKey + }; +} + +function decodeBase64(str) { + return Buffer.from(str, 'base64').toString(); +} + +function allowCrossDomain(appId) { + return (req, res, next) => { + const config = _Config.default.get(appId, getMountForRequest(req)); + + let allowHeaders = DEFAULT_ALLOWED_HEADERS; + + if (config && config.allowHeaders) { + allowHeaders += `, ${config.allowHeaders.join(', ')}`; + } + + const allowOrigin = config && config.allowOrigin || '*'; + res.header('Access-Control-Allow-Origin', allowOrigin); + res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'); + res.header('Access-Control-Allow-Headers', allowHeaders); + res.header('Access-Control-Expose-Headers', 'X-Parse-Job-Status-Id, X-Parse-Push-Status-Id'); // intercept OPTIONS method + + if ('OPTIONS' == req.method) { + res.sendStatus(200); + } else { + next(); + } + }; +} + +function allowMethodOverride(req, res, next) { + if (req.method === 'POST' && req.body._method) { + req.originalMethod = req.method; + req.method = req.body._method; + delete req.body._method; + } + + next(); +} + +function handleParseErrors(err, req, res, next) { + const log = req.config && req.config.loggerController || _logger.default; + + if (err instanceof _node.default.Error) { + if (req.config && req.config.enableExpressErrorHandler) { + return next(err); + } + + let httpStatus; // TODO: fill out this mapping + + switch (err.code) { + case _node.default.Error.INTERNAL_SERVER_ERROR: + httpStatus = 500; + break; + + case _node.default.Error.OBJECT_NOT_FOUND: + httpStatus = 404; + break; + + default: + httpStatus = 400; + } + + res.status(httpStatus); + res.json({ + code: err.code, + error: err.message + }); + log.error('Parse error: ', err); + } else if (err.status && err.message) { + res.status(err.status); + res.json({ + error: err.message + }); + + if (!(process && process.env.TESTING)) { + next(err); + } + } else { + log.error('Uncaught internal server error.', err, err.stack); + res.status(500); + res.json({ + code: _node.default.Error.INTERNAL_SERVER_ERROR, + message: 'Internal server error.' + }); + + if (!(process && process.env.TESTING)) { + next(err); + } + } +} + +function enforceMasterKeyAccess(req, res, next) { + if (!req.auth.isMaster) { + res.status(403); + res.end('{"error":"unauthorized: master key is required"}'); + return; + } + + next(); +} + +function promiseEnforceMasterKeyAccess(request) { + if (!request.auth.isMaster) { + const error = new Error(); + error.status = 403; + error.message = 'unauthorized: master key is required'; + throw error; + } + + return Promise.resolve(); +} +/** + * Deduplicates a request to ensure idempotency. Duplicates are determined by the request ID + * in the request header. If a request has no request ID, it is executed anyway. + * @param {*} req The request to evaluate. + * @returns Promise<{}> + */ + + +function promiseEnsureIdempotency(req) { + // Enable feature only for MongoDB + if (!(req.config.database.adapter instanceof _MongoStorageAdapter.default)) { + return Promise.resolve(); + } // Get parameters + + + const config = req.config; + const requestId = ((req || {}).headers || {})['x-parse-request-id']; + const { + paths, + ttl + } = config.idempotencyOptions; + + if (!requestId || !config.idempotencyOptions) { + return Promise.resolve(); + } // Request path may contain trailing slashes, depending on the original request, so remove + // leading and trailing slashes to make it easier to specify paths in the configuration + + + const reqPath = req.path.replace(/^\/|\/$/, ''); // Determine whether idempotency is enabled for current request path + + let match = false; + + for (const path of paths) { + // Assume one wants a path to always match from the beginning to prevent any mistakes + const regex = new RegExp(path.charAt(0) === '^' ? path : '^' + path); + + if (reqPath.match(regex)) { + match = true; + break; + } + } + + if (!match) { + return Promise.resolve(); + } // Try to store request + + + const expiryDate = new Date(new Date().setSeconds(new Date().getSeconds() + ttl)); + return _rest.default.create(config, _Auth.default.master(config), '_Idempotency', { + reqId: requestId, + expire: _node.default._encode(expiryDate) + }).catch(e => { + if (e.code == _node.default.Error.DUPLICATE_VALUE) { + throw new _node.default.Error(_node.default.Error.DUPLICATE_REQUEST, 'Duplicate request'); + } + + throw e; + }); +} + +function invalidRequest(req, res) { + res.status(403); + res.end('{"error":"unauthorized"}'); +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9taWRkbGV3YXJlcy5qcyJdLCJuYW1lcyI6WyJERUZBVUxUX0FMTE9XRURfSEVBREVSUyIsImdldE1vdW50Rm9yUmVxdWVzdCIsInJlcSIsIm1vdW50UGF0aExlbmd0aCIsIm9yaWdpbmFsVXJsIiwibGVuZ3RoIiwidXJsIiwibW91bnRQYXRoIiwic2xpY2UiLCJwcm90b2NvbCIsImdldCIsImhhbmRsZVBhcnNlSGVhZGVycyIsInJlcyIsIm5leHQiLCJtb3VudCIsImluZm8iLCJhcHBJZCIsInNlc3Npb25Ub2tlbiIsIm1hc3RlcktleSIsImluc3RhbGxhdGlvbklkIiwiY2xpZW50S2V5IiwiamF2YXNjcmlwdEtleSIsImRvdE5ldEtleSIsInJlc3RBUElLZXkiLCJjbGllbnRWZXJzaW9uIiwiY29udGV4dCIsImJhc2ljQXV0aCIsImh0dHBBdXRoIiwiYmFzaWNBdXRoQXBwSWQiLCJBcHBDYWNoZSIsImJvZHkiLCJfbm9Cb2R5IiwiZmlsZVZpYUpTT04iLCJCdWZmZXIiLCJKU09OIiwicGFyc2UiLCJlIiwiaW52YWxpZFJlcXVlc3QiLCJfUmV2b2NhYmxlU2Vzc2lvbiIsIl9BcHBsaWNhdGlvbklkIiwiX0phdmFTY3JpcHRLZXkiLCJfQ2xpZW50VmVyc2lvbiIsIl9JbnN0YWxsYXRpb25JZCIsIl9TZXNzaW9uVG9rZW4iLCJfTWFzdGVyS2V5IiwiX2NvbnRleHQiLCJPYmplY3QiLCJfQ29udGVudFR5cGUiLCJoZWFkZXJzIiwidG9TdHJpbmciLCJjbGllbnRTREsiLCJDbGllbnRTREsiLCJmcm9tU3RyaW5nIiwiZmlsZURhdGEiLCJiYXNlNjQiLCJmcm9tIiwiY2xpZW50SXAiLCJnZXRDbGllbnRJcCIsImFwcCIsImNvbmZpZyIsIkNvbmZpZyIsImlwIiwibWFzdGVyS2V5SXBzIiwiaW5kZXhPZiIsImlzTWFzdGVyIiwiYXV0aCIsIkF1dGgiLCJpc1JlYWRPbmx5TWFzdGVyIiwicmVhZE9ubHlNYXN0ZXJLZXkiLCJpc1JlYWRPbmx5Iiwia2V5cyIsIm9uZUtleUNvbmZpZ3VyZWQiLCJzb21lIiwia2V5IiwidW5kZWZpbmVkIiwib25lS2V5TWF0Y2hlcyIsInVzZXJGcm9tSldUIiwidXNlciIsIlByb21pc2UiLCJyZXNvbHZlIiwidGhlbiIsImdldEF1dGhGb3JMZWdhY3lTZXNzaW9uVG9rZW4iLCJnZXRBdXRoRm9yU2Vzc2lvblRva2VuIiwiY2F0Y2giLCJlcnJvciIsIlBhcnNlIiwiRXJyb3IiLCJsb2dnZXJDb250cm9sbGVyIiwiVU5LTk9XTl9FUlJPUiIsInNwbGl0IiwiY29ubmVjdGlvbiIsInJlbW90ZUFkZHJlc3MiLCJzb2NrZXQiLCJhdXRob3JpemF0aW9uIiwiaGVhZGVyIiwiYXV0aFByZWZpeCIsIm1hdGNoIiwidG9Mb3dlckNhc2UiLCJlbmNvZGVkQXV0aCIsInN1YnN0cmluZyIsImNyZWRlbnRpYWxzIiwiZGVjb2RlQmFzZTY0IiwianNLZXlQcmVmaXgiLCJtYXRjaEtleSIsInN0ciIsImFsbG93Q3Jvc3NEb21haW4iLCJhbGxvd0hlYWRlcnMiLCJqb2luIiwiYWxsb3dPcmlnaW4iLCJtZXRob2QiLCJzZW5kU3RhdHVzIiwiYWxsb3dNZXRob2RPdmVycmlkZSIsIl9tZXRob2QiLCJvcmlnaW5hbE1ldGhvZCIsImhhbmRsZVBhcnNlRXJyb3JzIiwiZXJyIiwibG9nIiwiZGVmYXVsdExvZ2dlciIsImVuYWJsZUV4cHJlc3NFcnJvckhhbmRsZXIiLCJodHRwU3RhdHVzIiwiY29kZSIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsIk9CSkVDVF9OT1RfRk9VTkQiLCJzdGF0dXMiLCJqc29uIiwibWVzc2FnZSIsInByb2Nlc3MiLCJlbnYiLCJURVNUSU5HIiwic3RhY2siLCJlbmZvcmNlTWFzdGVyS2V5QWNjZXNzIiwiZW5kIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiLCJyZXF1ZXN0IiwicHJvbWlzZUVuc3VyZUlkZW1wb3RlbmN5IiwiZGF0YWJhc2UiLCJhZGFwdGVyIiwiTW9uZ29TdG9yYWdlQWRhcHRlciIsInJlcXVlc3RJZCIsInBhdGhzIiwidHRsIiwiaWRlbXBvdGVuY3lPcHRpb25zIiwicmVxUGF0aCIsInBhdGgiLCJyZXBsYWNlIiwicmVnZXgiLCJSZWdFeHAiLCJjaGFyQXQiLCJleHBpcnlEYXRlIiwiRGF0ZSIsInNldFNlY29uZHMiLCJnZXRTZWNvbmRzIiwicmVzdCIsImNyZWF0ZSIsIm1hc3RlciIsInJlcUlkIiwiZXhwaXJlIiwiX2VuY29kZSIsIkRVUExJQ0FURV9WQUxVRSIsIkRVUExJQ0FURV9SRVFVRVNUIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRU8sTUFBTUEsdUJBQXVCLEdBQ2xDLCtPQURLOzs7QUFHUCxNQUFNQyxrQkFBa0IsR0FBRyxVQUFVQyxHQUFWLEVBQWU7QUFDeEMsUUFBTUMsZUFBZSxHQUFHRCxHQUFHLENBQUNFLFdBQUosQ0FBZ0JDLE1BQWhCLEdBQXlCSCxHQUFHLENBQUNJLEdBQUosQ0FBUUQsTUFBekQ7QUFDQSxRQUFNRSxTQUFTLEdBQUdMLEdBQUcsQ0FBQ0UsV0FBSixDQUFnQkksS0FBaEIsQ0FBc0IsQ0FBdEIsRUFBeUJMLGVBQXpCLENBQWxCO0FBQ0EsU0FBT0QsR0FBRyxDQUFDTyxRQUFKLEdBQWUsS0FBZixHQUF1QlAsR0FBRyxDQUFDUSxHQUFKLENBQVEsTUFBUixDQUF2QixHQUF5Q0gsU0FBaEQ7QUFDRCxDQUpELEMsQ0FNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNPLFNBQVNJLGtCQUFULENBQTRCVCxHQUE1QixFQUFpQ1UsR0FBakMsRUFBc0NDLElBQXRDLEVBQTRDO0FBQ2pELE1BQUlDLEtBQUssR0FBR2Isa0JBQWtCLENBQUNDLEdBQUQsQ0FBOUI7QUFFQSxNQUFJYSxJQUFJLEdBQUc7QUFDVEMsSUFBQUEsS0FBSyxFQUFFZCxHQUFHLENBQUNRLEdBQUosQ0FBUSx3QkFBUixDQURFO0FBRVRPLElBQUFBLFlBQVksRUFBRWYsR0FBRyxDQUFDUSxH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QXBwQ2FjaGUgZnJvbSAnLi9jYWNoZSc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgYXV0aCBmcm9tICcuL0F1dGgnO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuL0NvbmZpZyc7XG5pbXBvcnQgQ2xpZW50U0RLIGZyb20gJy4vQ2xpZW50U0RLJztcbmltcG9ydCBkZWZhdWx0TG9nZ2VyIGZyb20gJy4vbG9nZ2VyJztcbmltcG9ydCByZXN0IGZyb20gJy4vcmVzdCc7XG5pbXBvcnQgTW9uZ29TdG9yYWdlQWRhcHRlciBmcm9tICcuL0FkYXB0ZXJzL1N0b3JhZ2UvTW9uZ28vTW9uZ29TdG9yYWdlQWRhcHRlcic7XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX0FMTE9XRURfSEVBREVSUyA9XG4gICdYLVBhcnNlLU1hc3Rlci1LZXksIFgtUGFyc2UtUkVTVC1BUEktS2V5LCBYLVBhcnNlLUphdmFzY3JpcHQtS2V5LCBYLVBhcnNlLUFwcGxpY2F0aW9uLUlkLCBYLVBhcnNlLUNsaWVudC1WZXJzaW9uLCBYLVBhcnNlLVNlc3Npb24tVG9rZW4sIFgtUmVxdWVzdGVkLVdpdGgsIFgtUGFyc2UtUmV2b2NhYmxlLVNlc3Npb24sIFgtUGFyc2UtUmVxdWVzdC1JZCwgQ29udGVudC1UeXBlLCBQcmFnbWEsIENhY2hlLUNvbnRyb2wnO1xuXG5jb25zdCBnZXRNb3VudEZvclJlcXVlc3QgPSBmdW5jdGlvbiAocmVxKSB7XG4gIGNvbnN0IG1vdW50UGF0aExlbmd0aCA9IHJlcS5vcmlnaW5hbFVybC5sZW5ndGggLSByZXEudXJsLmxlbmd0aDtcbiAgY29uc3QgbW91bnRQYXRoID0gcmVxLm9yaWdpbmFsVXJsLnNsaWNlKDAsIG1vdW50UGF0aExlbmd0aCk7XG4gIHJldHVybiByZXEucHJvdG9jb2wgKyAnOi8vJyArIHJlcS5nZXQoJ2hvc3QnKSArIG1vdW50UGF0aDtcbn07XG5cbi8vIENoZWNrcyB0aGF0IHRoZSByZXF1ZXN0IGlzIGF1dGhvcml6ZWQgZm9yIHRoaXMgYXBwIGFuZCBjaGVja3MgdXNlclxuLy8gYXV0aCB0b28uXG4vLyBUaGUgYm9keXBhcnNlciBzaG91bGQgcnVuIGJlZm9yZSB0aGlzIG1pZGRsZXdhcmUuXG4vLyBBZGRzIGluZm8gdG8gdGhlIHJlcXVlc3Q6XG4vLyByZXEuY29uZmlnIC0gdGhlIENvbmZpZyBmb3IgdGhpcyBhcHBcbi8vIHJlcS5hdXRoIC0gdGhlIEF1dGggZm9yIHRoaXMgcmVxdWVzdFxuZXhwb3J0IGZ1bmN0aW9uIGhhbmRsZVBhcnNlSGVhZGVycyhyZXEsIHJlcywgbmV4dCkge1xuICB2YXIgbW91bnQgPSBnZXRNb3VudEZvclJlcXVlc3QocmVxKTtcblxuICB2YXIgaW5mbyA9IHtcbiAgICBhcHBJZDogcmVxLmdldCgnWC1QYXJzZS1BcHBsaWNhdGlvbi1JZCcpLFxuICAgIHNlc3Npb25Ub2tlbjogcmVxLmdldCgnWC1QYXJzZS1TZXNzaW9uLVRva2VuJyksXG4gICAgbWFzdGVyS2V5OiByZXEuZ2V0KCdYLVBhcnNlLU1hc3Rlci1LZXknKSxcbiAgICBpbnN0YWxsYXRpb25JZDogcmVxLmdldCgnWC1QYXJzZS1JbnN0YWxsYXRpb24tSWQnKSxcbiAgICBjbGllbnRLZXk6IHJlcS5nZXQoJ1gtUGFyc2UtQ2xpZW50LUtleScpLFxuICAgIGphdmFzY3JpcHRLZXk6IHJlcS5nZXQoJ1gtUGFyc2UtSmF2YXNjcmlwdC1LZXknKSxcbiAgICBkb3ROZXRLZXk6IHJlcS5nZXQoJ1gtUGFyc2UtV2luZG93cy1LZXknKSxcbiAgICByZXN0QVBJS2V5OiByZXEuZ2V0KCdYLVBhcnNlLVJFU1QtQVBJLUtleScpLFxuICAgIGNsaWVudFZlcnNpb246IHJlcS5nZXQoJ1gtUGFyc2UtQ2xpZW50LVZlcnNpb24nKSxcbiAgICBjb250ZXh0OiB7fSxcbiAgfTtcblxuICB2YXIgYmFzaWNBdXRoID0gaHR0cEF1dGgocmVxKTtcblxuICBpZiAoYmFzaWNBdXRoKSB7XG4gICAgdmFyIGJhc2ljQXV0aEFwcElkID0gYmFzaWNBdXRoLmFwcElkO1xuICAgIGlmIChBcHBDYWNoZS5nZXQoYmFzaWNBdXRoQXBwSWQpKSB7XG4gICAgICBpbmZvLmFwcElkID0gYmFzaWNBdXRoQXBwSWQ7XG4gICAgICBpbmZvLm1hc3RlcktleSA9IGJhc2ljQXV0aC5tYXN0ZXJLZXkgfHwgaW5mby5tYXN0ZXJLZXk7XG4gICAgICBpbmZvLmphdmFzY3JpcHRLZXkgPSBiYXNpY0F1dGguamF2YXNjcmlwdEtleSB8fCBpbmZvLmphdmFzY3JpcHRLZXk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHJlcS5ib2R5KSB7XG4gICAgLy8gVW5pdHkgU0RLIHNlbmRzIGEgX25vQm9keSBrZXkgd2hpY2ggbmVlZHMgdG8gYmUgcmVtb3ZlZC5cbiAgICAvLyBVbmNsZWFyIGF0IHRoaXMgcG9pbnQgaWYgYWN0aW9uIG5lZWRzIHRvIGJlIHRha2VuLlxuICAgIGRlbGV0ZSByZXEuYm9keS5fbm9Cb2R5O1xuICB9XG5cbiAgdmFyIGZpbGVWaWFKU09OID0gZmFsc2U7XG5cbiAgaWYgKCFpbmZvLmFwcElkIHx8ICFBcHBDYWNoZS5nZXQoaW5mby5hcHBJZCkpIHtcbiAgICAvLyBTZWUgaWYgd2UgY2FuIGZpbmQgdGhlIGFwcCBpZCBvbiB0aGUgYm9keS5cbiAgICBpZiAocmVxLmJvZHkgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICAgIC8vIFRoZSBvbmx5IGNoYW5jZSB0byBmaW5kIHRoZSBhcHAgaWQgaXMgaWYgdGhpcyBpcyBhIGZpbGVcbiAgICAgIC8vIHVwbG9hZCB0aGF0IGFjdHVhbGx5IGlzIGEgSlNPTiBib2R5LiBTbyB0cnkgdG8gcGFyc2UgaXQuXG4gICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vcGFyc2UtY29tbXVuaXR5L3BhcnNlLXNlcnZlci9pc3N1ZXMvNjU4OVxuICAgICAgLy8gSXQgaXMgYWxzbyBwb3NzaWJsZSB0aGF0IHRoZSBjbGllbnQgaXMgdHJ5aW5nIHRvIHVwbG9hZCBhIGZpbGUgYnV0IGZvcmdvdFxuICAgICAgLy8gdG8gcHJvdmlkZSB4LXBhcnNlLWFwcC1pZCBpbiBoZWFkZXIgYW5kIHBhcnNlIGEgYmluYXJ5IGZpbGUgd2lsbCBmYWlsXG4gICAgICB0cnkge1xuICAgICAgICByZXEuYm9keSA9IEpTT04ucGFyc2UocmVxLmJvZHkpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gaW52YWxpZFJlcXVlc3QocmVxLCByZXMpO1xuICAgICAgfVxuICAgICAgZmlsZVZpYUpTT04gPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChyZXEuYm9keSkge1xuICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9SZXZvY2FibGVTZXNzaW9uO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHJlcS5ib2R5ICYmXG4gICAgICByZXEuYm9keS5fQXBwbGljYXRpb25JZCAmJlxuICAgICAgQXBwQ2FjaGUuZ2V0KHJlcS5ib2R5Ll9BcHBsaWNhdGlvbklkKSAmJlxuICAgICAgKCFpbmZvLm1hc3RlcktleSB8fCBBcHBDYWNoZS5nZXQocmVxLmJvZHkuX0FwcGxpY2F0aW9uSWQpLm1hc3RlcktleSA9PT0gaW5mby5tYXN0ZXJLZXkpXG4gICAgKSB7XG4gICAgICBpbmZvLmFwcElkID0gcmVxLmJvZHkuX0FwcGxpY2F0aW9uSWQ7XG4gICAgICBpbmZvLmphdmFzY3JpcHRLZXkgPSByZXEuYm9keS5fSmF2YVNjcmlwdEtleSB8fCAnJztcbiAgICAgIGRlbGV0ZSByZXEuYm9keS5fQXBwbGljYXRpb25JZDtcbiAgICAgIGRlbGV0ZSByZXEuYm9keS5fSmF2YVNjcmlwdEtleTtcbiAgICAgIC8vIFRPRE86IHRlc3QgdGhhdCB0aGUgUkVTVCBBUEkgZm9ybWF0cyBnZW5lcmF0ZWQgYnkgdGhlIG90aGVyXG4gICAgICAvLyBTREtzIGFyZSBoYW5kbGVkIG9rXG4gICAgICBpZiAocmVxLmJvZHkuX0NsaWVudFZlcnNpb24pIHtcbiAgICAgICAgaW5mby5jbGllbnRWZXJzaW9uID0gcmVxLmJvZHkuX0NsaWVudFZlcnNpb247XG4gICAgICAgIGRlbGV0ZSByZXEuYm9keS5fQ2xpZW50VmVyc2lvbjtcbiAgICAgIH1cbiAgICAgIGlmIChyZXEuYm9keS5fSW5zdGFsbGF0aW9uSWQpIHtcbiAgICAgICAgaW5mby5pbnN0YWxsYXRpb25JZCA9IHJlcS5ib2R5Ll9JbnN0YWxsYXRpb25JZDtcbiAgICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9JbnN0YWxsYXRpb25JZDtcbiAgICAgIH1cbiAgICAgIGlmIChyZXEuYm9keS5fU2Vzc2lvblRva2VuKSB7XG4gICAgICAgIGluZm8uc2Vzc2lvblRva2VuID0gcmVxLmJvZHkuX1Nlc3Npb25Ub2tlbjtcbiAgICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9TZXNzaW9uVG9rZW47XG4gICAgICB9XG4gICAgICBpZiAocmVxLmJvZHkuX01hc3RlcktleSkge1xuICAgICAgICBpbmZvLm1hc3RlcktleSA9IHJlcS5ib2R5Ll9NYXN0ZXJLZXk7XG4gICAgICAgIGRlbGV0ZSByZXEuYm9keS5fTWFzdGVyS2V5O1xuICAgICAgfVxuICAgICAgaWYgKHJlcS5ib2R5Ll9jb250ZXh0ICYmIHJlcS5ib2R5Ll9jb250ZXh0IGluc3RhbmNlb2YgT2JqZWN0KSB7XG4gICAgICAgIGluZm8uY29udGV4dCA9IHJlcS5ib2R5Ll9jb250ZXh0O1xuICAgICAgICBkZWxldGUgcmVxLmJvZHkuX2NvbnRleHQ7XG4gICAgICB9XG4gICAgICBpZiAocmVxLmJvZHkuX0NvbnRlbnRUeXBlKSB7XG4gICAgICAgIHJlcS5oZWFkZXJzWydjb250ZW50LXR5cGUnXSA9IHJlcS5ib2R5Ll9Db250ZW50VHlwZTtcbiAgICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9Db250ZW50VHlwZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGludmFsaWRSZXF1ZXN0KHJlcSwgcmVzKTtcbiAgICB9XG4gIH1cblxuICBpZiAoaW5mby5zZXNzaW9uVG9rZW4gJiYgdHlwZW9mIGluZm8uc2Vzc2lvblRva2VuICE9PSAnc3RyaW5nJykge1xuICAgIGluZm8uc2Vzc2lvblRva2VuID0gaW5mby5zZXNzaW9uVG9rZW4udG9TdHJpbmcoKTtcbiAgfVxuXG4gIGlmIChpbmZvLmNsaWVudFZlcnNpb24pIHtcbiAgICBpbmZvLmNsaWVudFNESyA9IENsaWVudFNESy5mcm9tU3RyaW5nKGluZm8uY2xpZW50VmVyc2lvbik7XG4gIH1cblxuICBpZiAoZmlsZVZpYUpTT04pIHtcbiAgICByZXEuZmlsZURhdGEgPSByZXEuYm9keS5maWxlRGF0YTtcbiAgICAvLyBXZSBuZWVkIHRvIHJlcG9wdWxhdGUgcmVxLmJvZHkgd2l0aCBhIGJ1ZmZlclxuICAgIHZhciBiYXNlNjQgPSByZXEuYm9keS5iYXNlNjQ7XG4gICAgcmVxLmJvZHkgPSBCdWZmZXIuZnJvbShiYXNlNjQsICdiYXNlNjQnKTtcbiAgfVxuXG4gIGNvbnN0IGNsaWVudElwID0gZ2V0Q2xpZW50SXAocmVxKTtcblxuICBpbmZvLmFwcCA9IEFwcENhY2hlLmdldChpbmZvLmFwcElkKTtcbiAgcmVxLmNvbmZpZyA9IENvbmZpZy5nZXQoaW5mby5hcHBJZCwgbW91bnQpO1xuICByZXEuY29uZmlnLmhlYWRlcnMgPSByZXEuaGVhZGVycyB8fCB7fTtcbiAgcmVxLmNvbmZpZy5pcCA9IGNsaWVudElwO1xuICByZXEuaW5mbyA9IGluZm87XG5cbiAgaWYgKFxuICAgIGluZm8ubWFzdGVyS2V5ICYmXG4gICAgcmVxLmNvbmZpZy5tYXN0ZXJLZXlJcHMgJiZcbiAgICByZXEuY29uZmlnLm1hc3RlcktleUlwcy5sZW5ndGggIT09IDAgJiZcbiAgICByZXEuY29uZmlnLm1hc3RlcktleUlwcy5pbmRleE9mKGNsaWVudElwKSA9PT0gLTFcbiAgKSB7XG4gICAgcmV0dXJuIGludmFsaWRSZXF1ZXN0KHJlcSwgcmVzKTtcbiAgfVxuXG4gIHZhciBpc01hc3RlciA9IGluZm8ubWFzdGVyS2V5ID09PSByZXEuY29uZmlnLm1hc3RlcktleTtcblxuICBpZiAoaXNNYXN0ZXIpIHtcbiAgICByZXEuYXV0aCA9IG5ldyBhdXRoLkF1dGgoe1xuICAgICAgY29uZmlnOiByZXEuY29uZmlnLFxuICAgICAgaW5zdGFsbGF0aW9uSWQ6IGluZm8uaW5zdGFsbGF0aW9uSWQsXG4gICAgICBpc01hc3RlcjogdHJ1ZSxcbiAgICB9KTtcbiAgICBuZXh0KCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGlzUmVhZE9ubHlNYXN0ZXIgPSBpbmZvLm1hc3RlcktleSA9PT0gcmVxLmNvbmZpZy5yZWFkT25seU1hc3RlcktleTtcbiAgaWYgKFxuICAgIHR5cGVvZiByZXEuY29uZmlnLnJlYWRPbmx5TWFzdGVyS2V5ICE9ICd1bmRlZmluZWQnICYmXG4gICAgcmVxLmNvbmZpZy5yZWFkT25seU1hc3RlcktleSAmJlxuICAgIGlzUmVhZE9ubHlNYXN0ZXJcbiAgKSB7XG4gICAgcmVxLmF1dGggPSBuZXcgYXV0aC5BdXRoKHtcbiAgICAgIGNvbmZpZzogcmVxLmNvbmZpZyxcbiAgICAgIGluc3RhbGxhdGlvbklkOiBpbmZvLmluc3RhbGxhdGlvbklkLFxuICAgICAgaXNNYXN0ZXI6IHRydWUsXG4gICAgICBpc1JlYWRPbmx5OiB0cnVlLFxuICAgIH0pO1xuICAgIG5leHQoKTtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBDbGllbnQga2V5cyBhcmUgbm90IHJlcXVpcmVkIGluIHBhcnNlLXNlcnZlciwgYnV0IGlmIGFueSBoYXZlIGJlZW4gY29uZmlndXJlZCBpbiB0aGUgc2VydmVyLCB2YWxpZGF0ZSB0aGVtXG4gIC8vICB0byBwcmVzZXJ2ZSBvcmlnaW5hbCBiZWhhdmlvci5cbiAgY29uc3Qga2V5cyA9IFsnY2xpZW50S2V5JywgJ2phdmFzY3JpcHRLZXknLCAnZG90TmV0S2V5JywgJ3Jlc3RBUElLZXknXTtcbiAgY29uc3Qgb25lS2V5Q29uZmlndXJlZCA9IGtleXMuc29tZShmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIHJlcS5jb25maWdba2V5XSAhPT0gdW5kZWZpbmVkO1xuICB9KTtcbiAgY29uc3Qgb25lS2V5TWF0Y2hlcyA9IGtleXMuc29tZShmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIHJlcS5jb25maWdba2V5XSAhPT0gdW5kZWZpbmVkICYmIGluZm9ba2V5XSA9PT0gcmVxLmNvbmZpZ1trZXldO1xuICB9KTtcblxuICBpZiAob25lS2V5Q29uZmlndXJlZCAmJiAhb25lS2V5TWF0Y2hlcykge1xuICAgIHJldHVybiBpbnZhbGlkUmVxdWVzdChyZXEsIHJlcyk7XG4gIH1cblxuICBpZiAocmVxLnVybCA9PSAnL2xvZ2luJykge1xuICAgIGRlbGV0ZSBpbmZvLnNlc3Npb25Ub2tlbjtcbiAgfVxuXG4gIGlmIChyZXEudXNlckZyb21KV1QpIHtcbiAgICByZXEuYXV0aCA9IG5ldyBhdXRoLkF1dGgoe1xuICAgICAgY29uZmlnOiByZXEuY29uZmlnLFxuICAgICAgaW5zdGFsbGF0aW9uSWQ6IGluZm8uaW5zdGFsbGF0aW9uSWQsXG4gICAgICBpc01hc3RlcjogZmFsc2UsXG4gICAgICB1c2VyOiByZXEudXNlckZyb21KV1QsXG4gICAgfSk7XG4gICAgbmV4dCgpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICghaW5mby5zZXNzaW9uVG9rZW4pIHtcbiAgICByZXEuYXV0aCA9IG5ldyBhdXRoLkF1dGgoe1xuICAgICAgY29uZmlnOiByZXEuY29uZmlnLFxuICAgICAgaW5zdGFsbGF0aW9uSWQ6IGluZm8uaW5zdGFsbGF0aW9uSWQsXG4gICAgICBpc01hc3RlcjogZmFsc2UsXG4gICAgfSk7XG4gICAgbmV4dCgpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIC8vIGhhbmRsZSB0aGUgdXBncmFkZVRvUmV2b2NhYmxlU2Vzc2lvbiBwYXRoIG9uIGl0J3Mgb3duXG4gICAgICBpZiAoXG4gICAgICAgIGluZm8uc2Vzc2lvblRva2VuICYmXG4gICAgICAgIHJlcS51cmwgPT09ICcvdXBncmFkZVRvUmV2b2NhYmxlU2Vzc2lvbicgJiZcbiAgICAgICAgaW5mby5zZXNzaW9uVG9rZW4uaW5kZXhPZigncjonKSAhPSAwXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIGF1dGguZ2V0QXV0aEZvckxlZ2FjeVNlc3Npb25Ub2tlbih7XG4gICAgICAgICAgY29uZmlnOiByZXEuY29uZmlnLFxuICAgICAgICAgIGluc3RhbGxhdGlvbklkOiBpbmZvLmluc3RhbGxhdGlvbklkLFxuICAgICAgICAgIHNlc3Npb25Ub2tlbjogaW5mby5zZXNzaW9uVG9rZW4sXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGF1dGguZ2V0QXV0aEZvclNlc3Npb25Ub2tlbih7XG4gICAgICAgICAgY29uZmlnOiByZXEuY29uZmlnLFxuICAgICAgICAgIGluc3RhbGxhdGlvbklkOiBpbmZvLmluc3RhbGxhdGlvbklkLFxuICAgICAgICAgIHNlc3Npb25Ub2tlbjogaW5mby5zZXNzaW9uVG9rZW4sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pXG4gICAgLnRoZW4oYXV0aCA9PiB7XG4gICAgICBpZiAoYXV0aCkge1xuICAgICAgICByZXEuYXV0aCA9IGF1dGg7XG4gICAgICAgIG5leHQoKTtcbiAgICAgIH1cbiAgICB9KVxuICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBQYXJzZS5FcnJvcikge1xuICAgICAgICBuZXh0KGVycm9yKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVE9ETzogRGV0ZXJtaW5lIHRoZSBjb3JyZWN0IGVycm9yIHNjZW5hcmlvLlxuICAgICAgICByZXEuY29uZmlnLmxvZ2dlckNvbnRyb2xsZXIuZXJyb3IoJ2Vycm9yIGdldHRpbmcgYXV0aCBmb3Igc2Vzc2lvblRva2VuJywgZXJyb3IpO1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuVU5LTk9XTl9FUlJPUiwgZXJyb3IpO1xuICAgICAgfVxuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBnZXRDbGllbnRJcChyZXEpIHtcbiAgaWYgKHJlcS5oZWFkZXJzWyd4LWZvcndhcmRlZC1mb3InXSkge1xuICAgIC8vIHRyeSB0byBnZXQgZnJvbSB4LWZvcndhcmVkLWZvciBpZiBpdCBzZXQgKGJlaGluZCByZXZlcnNlIHByb3h5KVxuICAgIHJldHVybiByZXEuaGVhZGVyc1sneC1mb3J3YXJkZWQtZm9yJ10uc3BsaXQoJywnKVswXTtcbiAgfSBlbHNlIGlmIChyZXEuY29ubmVjdGlvbiAmJiByZXEuY29ubmVjdGlvbi5yZW1vdGVBZGRyZXNzKSB7XG4gICAgLy8gbm8gcHJveHksIHRyeSBnZXR0aW5nIGZyb20gY29ubmVjdGlvbi5yZW1vdGVBZGRyZXNzXG4gICAgcmV0dXJuIHJlcS5jb25uZWN0aW9uLnJlbW90ZUFkZHJlc3M7XG4gIH0gZWxzZSBpZiAocmVxLnNvY2tldCkge1xuICAgIC8vIHRyeSB0byBnZXQgaXQgZnJvbSByZXEuc29ja2V0XG4gICAgcmV0dXJuIHJlcS5zb2NrZXQucmVtb3RlQWRkcmVzcztcbiAgfSBlbHNlIGlmIChyZXEuY29ubmVjdGlvbiAmJiByZXEuY29ubmVjdGlvbi5zb2NrZXQpIHtcbiAgICAvLyB0cnkgdG8gZ2V0IGl0IGZvcm0gdGhlIGNvbm5lY3Rpb24uc29ja2V0XG4gICAgcmV0dXJuIHJlcS5jb25uZWN0aW9uLnNvY2tldC5yZW1vdGVBZGRyZXNzO1xuICB9IGVsc2Uge1xuICAgIC8vIGlmIG5vbiBhYm92ZSwgZmFsbGJhY2suXG4gICAgcmV0dXJuIHJlcS5pcDtcbiAgfVxufVxuXG5mdW5jdGlvbiBodHRwQXV0aChyZXEpIHtcbiAgaWYgKCEocmVxLnJlcSB8fCByZXEpLmhlYWRlcnMuYXV0aG9yaXphdGlvbikgcmV0dXJuO1xuXG4gIHZhciBoZWFkZXIgPSAocmVxLnJlcSB8fCByZXEpLmhlYWRlcnMuYXV0aG9yaXphdGlvbjtcbiAgdmFyIGFwcElkLCBtYXN0ZXJLZXksIGphdmFzY3JpcHRLZXk7XG5cbiAgLy8gcGFyc2UgaGVhZGVyXG4gIHZhciBhdXRoUHJlZml4ID0gJ2Jhc2ljICc7XG5cbiAgdmFyIG1hdGNoID0gaGVhZGVyLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihhdXRoUHJlZml4KTtcblxuICBpZiAobWF0Y2ggPT0gMCkge1xuICAgIHZhciBlbmNvZGVkQXV0aCA9IGhlYWRlci5zdWJzdHJpbmcoYXV0aFByZWZpeC5sZW5ndGgsIGhlYWRlci5sZW5ndGgpO1xuICAgIHZhciBjcmVkZW50aWFscyA9IGRlY29kZUJhc2U2NChlbmNvZGVkQXV0aCkuc3BsaXQoJzonKTtcblxuICAgIGlmIChjcmVkZW50aWFscy5sZW5ndGggPT0gMikge1xuICAgICAgYXBwSWQgPSBjcmVkZW50aWFsc1swXTtcbiAgICAgIHZhciBrZXkgPSBjcmVkZW50aWFsc1sxXTtcblxuICAgICAgdmFyIGpzS2V5UHJlZml4ID0gJ2phdmFzY3JpcHQta2V5PSc7XG5cbiAgICAgIHZhciBtYXRjaEtleSA9IGtleS5pbmRleE9mKGpzS2V5UHJlZml4KTtcbiAgICAgIGlmIChtYXRjaEtleSA9PSAwKSB7XG4gICAgICAgIGphdmFzY3JpcHRLZXkgPSBrZXkuc3Vic3RyaW5nKGpzS2V5UHJlZml4Lmxlbmd0aCwga2V5Lmxlbmd0aCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtYXN0ZXJLZXkgPSBrZXk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgYXBwSWQ6IGFwcElkLCBtYXN0ZXJLZXk6IG1hc3RlcktleSwgamF2YXNjcmlwdEtleTogamF2YXNjcmlwdEtleSB9O1xufVxuXG5mdW5jdGlvbiBkZWNvZGVCYXNlNjQoc3RyKSB7XG4gIHJldHVybiBCdWZmZXIuZnJvbShzdHIsICdiYXNlNjQnKS50b1N0cmluZygpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYWxsb3dDcm9zc0RvbWFpbihhcHBJZCkge1xuICByZXR1cm4gKHJlcSwgcmVzLCBuZXh0KSA9PiB7XG4gICAgY29uc3QgY29uZmlnID0gQ29uZmlnLmdldChhcHBJZCwgZ2V0TW91bnRGb3JSZXF1ZXN0KHJlcSkpO1xuICAgIGxldCBhbGxvd0hlYWRlcnMgPSBERUZBVUxUX0FMTE9XRURfSEVBREVSUztcbiAgICBpZiAoY29uZmlnICYmIGNvbmZpZy5hbGxvd0hlYWRlcnMpIHtcbiAgICAgIGFsbG93SGVhZGVycyArPSBgLCAke2NvbmZpZy5hbGxvd0hlYWRlcnMuam9pbignLCAnKX1gO1xuICAgIH1cbiAgICBjb25zdCBhbGxvd09yaWdpbiA9IChjb25maWcgJiYgY29uZmlnLmFsbG93T3JpZ2luKSB8fCAnKic7XG4gICAgcmVzLmhlYWRlcignQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luJywgYWxsb3dPcmlnaW4pO1xuICAgIHJlcy5oZWFkZXIoJ0FjY2Vzcy1Db250cm9sLUFsbG93LU1ldGhvZHMnLCAnR0VULFBVVCxQT1NULERFTEVURSxPUFRJT05TJyk7XG4gICAgcmVzLmhlYWRlcignQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycycsIGFsbG93SGVhZGVycyk7XG4gICAgcmVzLmhlYWRlcignQWNjZXNzLUNvbnRyb2wtRXhwb3NlLUhlYWRlcnMnLCAnWC1QYXJzZS1Kb2ItU3RhdHVzLUlkLCBYLVBhcnNlLVB1c2gtU3RhdHVzLUlkJyk7XG4gICAgLy8gaW50ZXJjZXB0IE9QVElPTlMgbWV0aG9kXG4gICAgaWYgKCdPUFRJT05TJyA9PSByZXEubWV0aG9kKSB7XG4gICAgICByZXMuc2VuZFN0YXR1cygyMDApO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXh0KCk7XG4gICAgfVxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYWxsb3dNZXRob2RPdmVycmlkZShyZXEsIHJlcywgbmV4dCkge1xuICBpZiAocmVxLm1ldGhvZCA9PT0gJ1BPU1QnICYmIHJlcS5ib2R5Ll9tZXRob2QpIHtcbiAgICByZXEub3JpZ2luYWxNZXRob2QgPSByZXEubWV0aG9kO1xuICAgIHJlcS5tZXRob2QgPSByZXEuYm9keS5fbWV0aG9kO1xuICAgIGRlbGV0ZSByZXEuYm9keS5fbWV0aG9kO1xuICB9XG4gIG5leHQoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhbmRsZVBhcnNlRXJyb3JzKGVyciwgcmVxLCByZXMsIG5leHQpIHtcbiAgY29uc3QgbG9nID0gKHJlcS5jb25maWcgJiYgcmVxLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyKSB8fCBkZWZhdWx0TG9nZ2VyO1xuICBpZiAoZXJyIGluc3RhbmNlb2YgUGFyc2UuRXJyb3IpIHtcbiAgICBpZiAocmVxLmNvbmZpZyAmJiByZXEuY29uZmlnLmVuYWJsZUV4cHJlc3NFcnJvckhhbmRsZXIpIHtcbiAgICAgIHJldHVybiBuZXh0KGVycik7XG4gICAgfVxuICAgIGxldCBodHRwU3RhdHVzO1xuICAgIC8vIFRPRE86IGZpbGwgb3V0IHRoaXMgbWFwcGluZ1xuICAgIHN3aXRjaCAoZXJyLmNvZGUpIHtcbiAgICAgIGNhc2UgUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SOlxuICAgICAgICBodHRwU3RhdHVzID0gNTAwO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORDpcbiAgICAgICAgaHR0cFN0YXR1cyA9IDQwNDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBodHRwU3RhdHVzID0gNDAwO1xuICAgIH1cbiAgICByZXMuc3RhdHVzKGh0dHBTdGF0dXMpO1xuICAgIHJlcy5qc29uKHsgY29kZTogZXJyLmNvZGUsIGVycm9yOiBlcnIubWVzc2FnZSB9KTtcbiAgICBsb2cuZXJyb3IoJ1BhcnNlIGVycm9yOiAnLCBlcnIpO1xuICB9IGVsc2UgaWYgKGVyci5zdGF0dXMgJiYgZXJyLm1lc3NhZ2UpIHtcbiAgICByZXMuc3RhdHVzKGVyci5zdGF0dXMpO1xuICAgIHJlcy5qc29uKHsgZXJyb3I6IGVyci5tZXNzYWdlIH0pO1xuICAgIGlmICghKHByb2Nlc3MgJiYgcHJvY2Vzcy5lbnYuVEVTVElORykpIHtcbiAgICAgIG5leHQoZXJyKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgbG9nLmVycm9yKCdVbmNhdWdodCBpbnRlcm5hbCBzZXJ2ZXIgZXJyb3IuJywgZXJyLCBlcnIuc3RhY2spO1xuICAgIHJlcy5zdGF0dXMoNTAwKTtcbiAgICByZXMuanNvbih7XG4gICAgICBjb2RlOiBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsXG4gICAgICBtZXNzYWdlOiAnSW50ZXJuYWwgc2VydmVyIGVycm9yLicsXG4gICAgfSk7XG4gICAgaWYgKCEocHJvY2VzcyAmJiBwcm9jZXNzLmVudi5URVNUSU5HKSkge1xuICAgICAgbmV4dChlcnIpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZW5mb3JjZU1hc3RlcktleUFjY2VzcyhyZXEsIHJlcywgbmV4dCkge1xuICBpZiAoIXJlcS5hdXRoLmlzTWFzdGVyKSB7XG4gICAgcmVzLnN0YXR1cyg0MDMpO1xuICAgIHJlcy5lbmQoJ3tcImVycm9yXCI6XCJ1bmF1dGhvcml6ZWQ6IG1hc3RlciBrZXkgaXMgcmVxdWlyZWRcIn0nKTtcbiAgICByZXR1cm47XG4gIH1cbiAgbmV4dCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MocmVxdWVzdCkge1xuICBpZiAoIXJlcXVlc3QuYXV0aC5pc01hc3Rlcikge1xuICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKCk7XG4gICAgZXJyb3Iuc3RhdHVzID0gNDAzO1xuICAgIGVycm9yLm1lc3NhZ2UgPSAndW5hdXRob3JpemVkOiBtYXN0ZXIga2V5IGlzIHJlcXVpcmVkJztcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbi8qKlxuICogRGVkdXBsaWNhdGVzIGEgcmVxdWVzdCB0byBlbnN1cmUgaWRlbXBvdGVuY3kuIER1cGxpY2F0ZXMgYXJlIGRldGVybWluZWQgYnkgdGhlIHJlcXVlc3QgSURcbiAqIGluIHRoZSByZXF1ZXN0IGhlYWRlci4gSWYgYSByZXF1ZXN0IGhhcyBubyByZXF1ZXN0IElELCBpdCBpcyBleGVjdXRlZCBhbnl3YXkuXG4gKiBAcGFyYW0geyp9IHJlcSBUaGUgcmVxdWVzdCB0byBldmFsdWF0ZS5cbiAqIEByZXR1cm5zIFByb21pc2U8e30+XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcm9taXNlRW5zdXJlSWRlbXBvdGVuY3kocmVxKSB7XG4gIC8vIEVuYWJsZSBmZWF0dXJlIG9ubHkgZm9yIE1vbmdvREJcbiAgaWYgKCEocmVxLmNvbmZpZy5kYXRhYmFzZS5hZGFwdGVyIGluc3RhbmNlb2YgTW9uZ29TdG9yYWdlQWRhcHRlcikpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbiAgLy8gR2V0IHBhcmFtZXRlcnNcbiAgY29uc3QgY29uZmlnID0gcmVxLmNvbmZpZztcbiAgY29uc3QgcmVxdWVzdElkID0gKChyZXEgfHwge30pLmhlYWRlcnMgfHwge30pWyd4LXBhcnNlLXJlcXVlc3QtaWQnXTtcbiAgY29uc3QgeyBwYXRocywgdHRsIH0gPSBjb25maWcuaWRlbXBvdGVuY3lPcHRpb25zO1xuICBpZiAoIXJlcXVlc3RJZCB8fCAhY29uZmlnLmlkZW1wb3RlbmN5T3B0aW9ucykge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuICAvLyBSZXF1ZXN0IHBhdGggbWF5IGNvbnRhaW4gdHJhaWxpbmcgc2xhc2hlcywgZGVwZW5kaW5nIG9uIHRoZSBvcmlnaW5hbCByZXF1ZXN0LCBzbyByZW1vdmVcbiAgLy8gbGVhZGluZyBhbmQgdHJhaWxpbmcgc2xhc2hlcyB0byBtYWtlIGl0IGVhc2llciB0byBzcGVjaWZ5IHBhdGhzIGluIHRoZSBjb25maWd1cmF0aW9uXG4gIGNvbnN0IHJlcVBhdGggPSByZXEucGF0aC5yZXBsYWNlKC9eXFwvfFxcLyQvLCAnJyk7XG4gIC8vIERldGVybWluZSB3aGV0aGVyIGlkZW1wb3RlbmN5IGlzIGVuYWJsZWQgZm9yIGN1cnJlbnQgcmVxdWVzdCBwYXRoXG4gIGxldCBtYXRjaCA9IGZhbHNlO1xuICBmb3IgKGNvbnN0IHBhdGggb2YgcGF0aHMpIHtcbiAgICAvLyBBc3N1bWUgb25lIHdhbnRzIGEgcGF0aCB0byBhbHdheXMgbWF0Y2ggZnJvbSB0aGUgYmVnaW5uaW5nIHRvIHByZXZlbnQgYW55IG1pc3Rha2VzXG4gICAgY29uc3QgcmVnZXggPSBuZXcgUmVnRXhwKHBhdGguY2hhckF0KDApID09PSAnXicgPyBwYXRoIDogJ14nICsgcGF0aCk7XG4gICAgaWYgKHJlcVBhdGgubWF0Y2gocmVnZXgpKSB7XG4gICAgICBtYXRjaCA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgaWYgKCFtYXRjaCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuICAvLyBUcnkgdG8gc3RvcmUgcmVxdWVzdFxuICBjb25zdCBleHBpcnlEYXRlID0gbmV3IERhdGUobmV3IERhdGUoKS5zZXRTZWNvbmRzKG5ldyBEYXRlKCkuZ2V0U2Vjb25kcygpICsgdHRsKSk7XG4gIHJldHVybiByZXN0XG4gICAgLmNyZWF0ZShjb25maWcsIGF1dGgubWFzdGVyKGNvbmZpZyksICdfSWRlbXBvdGVuY3knLCB7XG4gICAgICByZXFJZDogcmVxdWVzdElkLFxuICAgICAgZXhwaXJlOiBQYXJzZS5fZW5jb2RlKGV4cGlyeURhdGUpLFxuICAgIH0pXG4gICAgLmNhdGNoKGUgPT4ge1xuICAgICAgaWYgKGUuY29kZSA9PSBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkRVUExJQ0FURV9SRVFVRVNULCAnRHVwbGljYXRlIHJlcXVlc3QnKTtcbiAgICAgIH1cbiAgICAgIHRocm93IGU7XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGludmFsaWRSZXF1ZXN0KHJlcSwgcmVzKSB7XG4gIHJlcy5zdGF0dXMoNDAzKTtcbiAgcmVzLmVuZCgne1wiZXJyb3JcIjpcInVuYXV0aG9yaXplZFwifScpO1xufVxuIl19 \ No newline at end of file diff --git a/lib/password.js b/lib/password.js new file mode 100644 index 0000000000..6091ae5d2d --- /dev/null +++ b/lib/password.js @@ -0,0 +1,38 @@ +"use strict"; + +// Tools for encrypting and decrypting passwords. +// Basically promise-friendly wrappers for bcrypt. +var bcrypt = require('bcryptjs'); + +try { + const _bcrypt = require('@node-rs/bcrypt'); + + bcrypt = { + hash: _bcrypt.hash, + compare: _bcrypt.verify + }; +} catch (e) { + /* */ +} // Returns a promise for a hashed password string. + + +function hash(password) { + return bcrypt.hash(password, 10); +} // Returns a promise for whether this password compares to equal this +// hashed password. + + +function compare(password, hashedPassword) { + // Cannot bcrypt compare when one is undefined + if (!password || !hashedPassword) { + return Promise.resolve(false); + } + + return bcrypt.compare(password, hashedPassword); +} + +module.exports = { + hash: hash, + compare: compare +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9wYXNzd29yZC5qcyJdLCJuYW1lcyI6WyJiY3J5cHQiLCJyZXF1aXJlIiwiX2JjcnlwdCIsImhhc2giLCJjb21wYXJlIiwidmVyaWZ5IiwiZSIsInBhc3N3b3JkIiwiaGFzaGVkUGFzc3dvcmQiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUNBLElBQUlBLE1BQU0sR0FBR0MsT0FBTyxDQUFDLFVBQUQsQ0FBcEI7O0FBRUEsSUFBSTtBQUNGLFFBQU1DLE9BQU8sR0FBR0QsT0FBTyxDQUFDLGlCQUFELENBQXZCOztBQUNBRCxFQUFBQSxNQUFNLEdBQUc7QUFDUEcsSUFBQUEsSUFBSSxFQUFFRCxPQUFPLENBQUNDLElBRFA7QUFFUEMsSUFBQUEsT0FBTyxFQUFFRixPQUFPLENBQUNHO0FBRlYsR0FBVDtBQUlELENBTkQsQ0FNRSxPQUFPQyxDQUFQLEVBQVU7QUFDVjtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU0gsSUFBVCxDQUFjSSxRQUFkLEVBQXdCO0FBQ3RCLFNBQU9QLE1BQU0sQ0FBQ0csSUFBUCxDQUFZSSxRQUFaLEVBQXNCLEVBQXRCLENBQVA7QUFDRCxDLENBRUQ7QUFDQTs7O0FBQ0EsU0FBU0gsT0FBVCxDQUFpQkcsUUFBakIsRUFBMkJDLGNBQTNCLEVBQTJDO0FBQ3pDO0FBQ0EsTUFBSSxDQUFDRCxRQUFELElBQWEsQ0FBQ0MsY0FBbEIsRUFBa0M7QUFDaEMsV0FBT0MsT0FBTyxDQUFDQyxPQUFSLENBQWdCLEtBQWhCLENBQVA7QUFDRDs7QUFDRCxTQUFPVixNQUFNLENBQUNJLE9BQVAsQ0FBZUcsUUFBZixFQUF5QkMsY0FBekIsQ0FBUDtBQUNEOztBQUVERyxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZlQsRUFBQUEsSUFBSSxFQUFFQSxJQURTO0FBRWZDLEVBQUFBLE9BQU8sRUFBRUE7QUFGTSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIFRvb2xzIGZvciBlbmNyeXB0aW5nIGFuZCBkZWNyeXB0aW5nIHBhc3N3b3Jkcy5cbi8vIEJhc2ljYWxseSBwcm9taXNlLWZyaWVuZGx5IHdyYXBwZXJzIGZvciBiY3J5cHQuXG52YXIgYmNyeXB0ID0gcmVxdWlyZSgnYmNyeXB0anMnKTtcblxudHJ5IHtcbiAgY29uc3QgX2JjcnlwdCA9IHJlcXVpcmUoJ0Bub2RlLXJzL2JjcnlwdCcpO1xuICBiY3J5cHQgPSB7XG4gICAgaGFzaDogX2JjcnlwdC5oYXNoLFxuICAgIGNvbXBhcmU6IF9iY3J5cHQudmVyaWZ5LFxuICB9O1xufSBjYXRjaCAoZSkge1xuICAvKiAqL1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYSBoYXNoZWQgcGFzc3dvcmQgc3RyaW5nLlxuZnVuY3Rpb24gaGFzaChwYXNzd29yZCkge1xuICByZXR1cm4gYmNyeXB0Lmhhc2gocGFzc3dvcmQsIDEwKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIHdoZXRoZXIgdGhpcyBwYXNzd29yZCBjb21wYXJlcyB0byBlcXVhbCB0aGlzXG4vLyBoYXNoZWQgcGFzc3dvcmQuXG5mdW5jdGlvbiBjb21wYXJlKHBhc3N3b3JkLCBoYXNoZWRQYXNzd29yZCkge1xuICAvLyBDYW5ub3QgYmNyeXB0IGNvbXBhcmUgd2hlbiBvbmUgaXMgdW5kZWZpbmVkXG4gIGlmICghcGFzc3dvcmQgfHwgIWhhc2hlZFBhc3N3b3JkKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG4gIH1cbiAgcmV0dXJuIGJjcnlwdC5jb21wYXJlKHBhc3N3b3JkLCBoYXNoZWRQYXNzd29yZCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBoYXNoOiBoYXNoLFxuICBjb21wYXJlOiBjb21wYXJlLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/request.js b/lib/request.js new file mode 100644 index 0000000000..47dae80852 --- /dev/null +++ b/lib/request.js @@ -0,0 +1,4 @@ +"use strict"; + +module.exports = require('./cloud-code/httpRequest'); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9yZXF1ZXN0LmpzIl0sIm5hbWVzIjpbIm1vZHVsZSIsImV4cG9ydHMiLCJyZXF1aXJlIl0sIm1hcHBpbmdzIjoiOztBQUFBQSxNQUFNLENBQUNDLE9BQVAsR0FBaUJDLE9BQU8sQ0FBQywwQkFBRCxDQUF4QiIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9jbG91ZC1jb2RlL2h0dHBSZXF1ZXN0Jyk7XG4iXX0= \ No newline at end of file diff --git a/lib/requiredParameter.js b/lib/requiredParameter.js new file mode 100644 index 0000000000..2a657ca91b --- /dev/null +++ b/lib/requiredParameter.js @@ -0,0 +1,13 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _default = errorMessage => { + throw errorMessage; +}; + +exports.default = _default; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9yZXF1aXJlZFBhcmFtZXRlci5qcyJdLCJuYW1lcyI6WyJlcnJvck1lc3NhZ2UiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7ZUFDZ0JBLFlBQUQsSUFBK0I7QUFDNUMsUUFBTUEsWUFBTjtBQUNELEMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiogQGZsb3cgKi9cbmV4cG9ydCBkZWZhdWx0IChlcnJvck1lc3NhZ2U6IHN0cmluZyk6IGFueSA9PiB7XG4gIHRocm93IGVycm9yTWVzc2FnZTtcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/rest.js b/lib/rest.js new file mode 100644 index 0000000000..1d822db8d3 --- /dev/null +++ b/lib/rest.js @@ -0,0 +1,208 @@ +"use strict"; + +// This file contains helpers for running operations in REST format. +// The goal is that handlers that explicitly handle an express route +// should just be shallow wrappers around things in this file, but +// these functions should not explicitly depend on the request +// object. +// This means that one of these handlers can support multiple +// routes. That's useful for the routes that do really similar +// things. +var Parse = require('parse/node').Parse; + +var RestQuery = require('./RestQuery'); + +var RestWrite = require('./RestWrite'); + +var triggers = require('./triggers'); + +function checkTriggers(className, config, types) { + return types.some(triggerType => { + return triggers.getTrigger(className, triggers.Types[triggerType], config.applicationId); + }); +} + +function checkLiveQuery(className, config) { + return config.liveQueryController && config.liveQueryController.hasLiveQuery(className); +} // Returns a promise for an object with optional keys 'results' and 'count'. + + +function find(config, auth, className, restWhere, restOptions, clientSDK, context) { + enforceRoleSecurity('find', className, auth); + return triggers.maybeRunQueryTrigger(triggers.Types.beforeFind, className, restWhere, restOptions, config, auth, context).then(result => { + restWhere = result.restWhere || restWhere; + restOptions = result.restOptions || restOptions; + const query = new RestQuery(config, auth, className, restWhere, restOptions, clientSDK, true, context); + return query.execute(); + }); +} // get is just like find but only queries an objectId. + + +const get = (config, auth, className, objectId, restOptions, clientSDK, context) => { + var restWhere = { + objectId + }; + enforceRoleSecurity('get', className, auth); + return triggers.maybeRunQueryTrigger(triggers.Types.beforeFind, className, restWhere, restOptions, config, auth, context, true).then(result => { + restWhere = result.restWhere || restWhere; + restOptions = result.restOptions || restOptions; + const query = new RestQuery(config, auth, className, restWhere, restOptions, clientSDK, true, context); + return query.execute(); + }); +}; // Returns a promise that doesn't resolve to any useful value. + + +function del(config, auth, className, objectId, context) { + if (typeof objectId !== 'string') { + throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad objectId'); + } + + if (className === '_User' && auth.isUnauthenticated()) { + throw new Parse.Error(Parse.Error.SESSION_MISSING, 'Insufficient auth to delete user'); + } + + enforceRoleSecurity('delete', className, auth); + let inflatedObject; + let schemaController; + return Promise.resolve().then(() => { + const hasTriggers = checkTriggers(className, config, ['beforeDelete', 'afterDelete']); + const hasLiveQuery = checkLiveQuery(className, config); + + if (hasTriggers || hasLiveQuery || className == '_Session') { + return new RestQuery(config, auth, className, { + objectId + }).execute({ + op: 'delete' + }).then(response => { + if (response && response.results && response.results.length) { + const firstResult = response.results[0]; + firstResult.className = className; + + if (className === '_Session' && !auth.isMaster) { + if (!auth.user || firstResult.user.objectId !== auth.user.id) { + throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); + } + } + + var cacheAdapter = config.cacheController; + cacheAdapter.user.del(firstResult.sessionToken); + inflatedObject = Parse.Object.fromJSON(firstResult); + return triggers.maybeRunTrigger(triggers.Types.beforeDelete, auth, inflatedObject, null, config, context); + } + + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found for delete.'); + }); + } + + return Promise.resolve({}); + }).then(() => { + if (!auth.isMaster) { + return auth.getUserRoles(); + } else { + return; + } + }).then(() => config.database.loadSchema()).then(s => { + schemaController = s; + const options = {}; + + if (!auth.isMaster) { + options.acl = ['*']; + + if (auth.user) { + options.acl.push(auth.user.id); + options.acl = options.acl.concat(auth.userRoles); + } + } + + return config.database.destroy(className, { + objectId: objectId + }, options, schemaController); + }).then(() => { + // Notify LiveQuery server if possible + const perms = schemaController.getClassLevelPermissions(className); + config.liveQueryController.onAfterDelete(className, inflatedObject, null, perms); + return triggers.maybeRunTrigger(triggers.Types.afterDelete, auth, inflatedObject, null, config, context); + }).catch(error => { + handleSessionMissingError(error, className, auth); + }); +} // Returns a promise for a {response, status, location} object. + + +function create(config, auth, className, restObject, clientSDK, context) { + enforceRoleSecurity('create', className, auth); + var write = new RestWrite(config, auth, className, null, restObject, null, clientSDK, context); + return write.execute(); +} // Returns a promise that contains the fields of the update that the +// REST API is supposed to return. +// Usually, this is just updatedAt. + + +function update(config, auth, className, restWhere, restObject, clientSDK, context) { + enforceRoleSecurity('update', className, auth); + return Promise.resolve().then(() => { + const hasTriggers = checkTriggers(className, config, ['beforeSave', 'afterSave']); + const hasLiveQuery = checkLiveQuery(className, config); + + if (hasTriggers || hasLiveQuery) { + // Do not use find, as it runs the before finds + return new RestQuery(config, auth, className, restWhere, undefined, undefined, false, context).execute({ + op: 'update' + }); + } + + return Promise.resolve({}); + }).then(({ + results + }) => { + var originalRestObject; + + if (results && results.length) { + originalRestObject = results[0]; + } + + return new RestWrite(config, auth, className, restWhere, restObject, originalRestObject, clientSDK, context, 'update').execute(); + }).catch(error => { + handleSessionMissingError(error, className, auth); + }); +} + +function handleSessionMissingError(error, className, auth) { + // If we're trying to update a user without / with bad session token + if (className === '_User' && error.code === Parse.Error.OBJECT_NOT_FOUND && !auth.isMaster) { + throw new Parse.Error(Parse.Error.SESSION_MISSING, 'Insufficient auth.'); + } + + throw error; +} + +const classesWithMasterOnlyAccess = ['_JobStatus', '_PushStatus', '_Hooks', '_GlobalConfig', '_JobSchedule', '_Idempotency']; // Disallowing access to the _Role collection except by master key + +function enforceRoleSecurity(method, className, auth) { + if (className === '_Installation' && !auth.isMaster) { + if (method === 'delete' || method === 'find') { + const error = `Clients aren't allowed to perform the ${method} operation on the installation collection.`; + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); + } + } //all volatileClasses are masterKey only + + + if (classesWithMasterOnlyAccess.indexOf(className) >= 0 && !auth.isMaster) { + const error = `Clients aren't allowed to perform the ${method} operation on the ${className} collection.`; + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); + } // readOnly masterKey is not allowed + + + if (auth.isReadOnly && (method === 'delete' || method === 'create' || method === 'update')) { + const error = `read-only masterKey isn't allowed to perform the ${method} operation.`; + throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); + } +} + +module.exports = { + create, + del, + find, + get, + update +}; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9yZXN0LmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsIlJlc3RRdWVyeSIsIlJlc3RXcml0ZSIsInRyaWdnZXJzIiwiY2hlY2tUcmlnZ2VycyIsImNsYXNzTmFtZSIsImNvbmZpZyIsInR5cGVzIiwic29tZSIsInRyaWdnZXJUeXBlIiwiZ2V0VHJpZ2dlciIsIlR5cGVzIiwiYXBwbGljYXRpb25JZCIsImNoZWNrTGl2ZVF1ZXJ5IiwibGl2ZVF1ZXJ5Q29udHJvbGxlciIsImhhc0xpdmVRdWVyeSIsImZpbmQiLCJhdXRoIiwicmVzdFdoZXJlIiwicmVzdE9wdGlvbnMiLCJjbGllbnRTREsiLCJjb250ZXh0IiwiZW5mb3JjZVJvbGVTZWN1cml0eSIsIm1heWJlUnVuUXVlcnlUcmlnZ2VyIiwiYmVmb3JlRmluZCIsInRoZW4iLCJyZXN1bHQiLCJxdWVyeSIsImV4ZWN1dGUiLCJnZXQiLCJvYmplY3RJZCIsImRlbCIsIkVycm9yIiwiSU5WQUxJRF9KU09OIiwiaXNVbmF1dGhlbnRpY2F0ZWQiLCJTRVNTSU9OX01JU1NJTkciLCJpbmZsYXRlZE9iamVjdCIsInNjaGVtYUNvbnRyb2xsZXIiLCJQcm9taXNlIiwicmVzb2x2ZSIsImhhc1RyaWdnZXJzIiwib3AiLCJyZXNwb25zZSIsInJlc3VsdHMiLCJsZW5ndGgiLCJmaXJzdFJlc3VsdCIsImlzTWFzdGVyIiwidXNlciIsImlkIiwiSU5WQUxJRF9TRVNTSU9OX1RPS0VOIiwiY2FjaGVBZGFwdGVyIiwiY2FjaGVDb250cm9sbGVyIiwic2Vzc2lvblRva2VuIiwiT2JqZWN0IiwiZnJvbUpTT04iLCJtYXliZVJ1blRyaWdnZXIiLCJiZWZvcmVEZWxldGUiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiZ2V0VXNlclJvbGVzIiwiZGF0YWJhc2UiLCJsb2FkU2NoZW1hIiwicyIsIm9wdGlvbnMiLCJhY2wiLCJwdXNoIiwiY29uY2F0IiwidXNlclJvbGVzIiwiZGVzdHJveSIsInBlcm1zIiwiZ2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zIiwib25BZnRlckRlbGV0ZSIsImFmdGVyRGVsZXRlIiwiY2F0Y2giLCJlcnJvciIsImhhbmRsZVNlc3Npb25NaXNzaW5nRXJyb3IiLCJjcmVhdGUiLCJyZXN0T2JqZWN0Iiwid3JpdGUiLCJ1cGRhdGUiLCJ1bmRlZmluZWQiLCJvcmlnaW5hbFJlc3RPYmplY3QiLCJjb2RlIiwiY2xhc3Nlc1dpdGhNYXN0ZXJPbmx5QWNjZXNzIiwibWV0aG9kIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsImluZGV4T2YiLCJpc1JlYWRPbmx5IiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUEsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFFQSxJQUFJRSxTQUFTLEdBQUdELE9BQU8sQ0FBQyxhQUFELENBQXZCOztBQUNBLElBQUlFLFNBQVMsR0FBR0YsT0FBTyxDQUFDLGFBQUQsQ0FBdkI7O0FBQ0EsSUFBSUcsUUFBUSxHQUFHSCxPQUFPLENBQUMsWUFBRCxDQUF0Qjs7QUFFQSxTQUFTSSxhQUFULENBQXVCQyxTQUF2QixFQUFrQ0MsTUFBbEMsRUFBMENDLEtBQTFDLEVBQWlEO0FBQy9DLFNBQU9BLEtBQUssQ0FBQ0MsSUFBTixDQUFXQyxXQUFXLElBQUk7QUFDL0IsV0FBT04sUUFBUSxDQUFDTyxVQUFULENBQW9CTCxTQUFwQixFQUErQkYsUUFBUSxDQUFDUSxLQUFULENBQWVGLFdBQWYsQ0FBL0IsRUFBNERILE1BQU0sQ0FBQ00sYUFBbkUsQ0FBUDtBQUNELEdBRk0sQ0FBUDtBQUdEOztBQUVELFNBQVNDLGNBQVQsQ0FBd0JSLFNBQXhCLEVBQW1DQyxNQUFuQyxFQUEyQztBQUN6QyxTQUFPQSxNQUFNLENBQUNRLG1CQUFQLElBQThCUixNQUFNLENBQUNRLG1CQUFQLENBQTJCQyxZQUEzQixDQUF3Q1YsU0FBeEMsQ0FBckM7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNXLElBQVQsQ0FBY1YsTUFBZCxFQUFzQlcsSUFBdEIsRUFBNEJaLFNBQTVCLEVBQXVDYSxTQUF2QyxFQUFrREMsV0FBbEQsRUFBK0RDLFNBQS9ELEVBQTBFQyxPQUExRSxFQUFtRjtBQUNqRkMsRUFBQUEsbUJBQW1CLENBQUMsTUFBRCxFQUFTakIsU0FBVCxFQUFvQlksSUFBcEIsQ0FBbkI7QUFDQSxTQUFPZCxRQUFRLENBQ1pvQixvQkFESSxDQUVIcEIsUUFBUSxDQUFDUSxLQUFULENBQWVhLFVBRlosRUFHSG5CLFNBSEcsRUFJSGEsU0FKRyxFQUtIQyxXQUxHLEVBTUhiLE1BTkcsRUFPSFcsSUFQRyxFQVFISSxPQVJHLEVBVUpJLElBVkksQ0FVQ0MsTUFBTSxJQUFJO0FBQ2RSLElBQUFBLFNBQVMsR0FBR1EsTUFBTSxDQUFDUixTQUFQLElBQW9CQSxTQUFoQztBQUNBQyxJQUFBQSxXQUFXLEdBQUdPLE1BQU0sQ0FBQ1AsV0FBUCxJQUFzQkEsV0FBcEM7QUFDQSxVQUFNUSxLQUFLLEdBQUcsSUFBSTFCLFNBQUosQ0FDWkssTUFEWSxFQUVaVyxJQUZZLEVBR1paLFNBSFksRUFJWmEsU0FKWSxFQUtaQyxXQUxZLEVBTVpDLFNBTlksRUFPWixJQVBZLEVBUVpDLE9BUlksQ0FBZDtBQVVBLFdBQU9NLEtBQUssQ0FBQ0MsT0FBTixFQUFQO0FBQ0QsR0F4QkksQ0FBUDtBQXlCRCxDLENBRUQ7OztBQUNBLE1BQU1DLEdBQUcsR0FBRyxDQUFDdkIsTUFBRCxFQUFTVyxJQUFULEVBQWVaLFNBQWYsRUFBMEJ5QixRQUExQixFQUFvQ1gsV0FBcEMsRUFBaURDLFNBQWpELEVBQTREQyxPQUE1RCxLQUF3RTtBQUNsRixNQUFJSCxTQUFTLEdBQUc7QUFBRVksSUFBQUE7QUFBRixHQUFoQjtBQUNBUixFQUFBQSxtQkFBbUIsQ0FBQyxLQUFELEVBQVFqQixTQUFSLEVBQW1CWSxJQUFuQixDQUFuQjtBQUNBLFNBQU9kLFFBQVEsQ0FDWm9CLG9CQURJLENBRUhwQixRQUFRLENBQUNRLEtBQVQsQ0FBZWEsVUFGWixFQUdIbkIsU0FIRyxFQUlIYSxTQUpHLEVBS0hDLFdBTEcsRUFNSGIsTUFORyxFQU9IVyxJQVBHLEVBUUhJLE9BUkcsRUFTSCxJQVRHLEVBV0pJLElBWEksQ0FXQ0MsTUFBTSxJQUFJO0FBQ2RSLElBQUFBLFNBQVMsR0FBR1EsTUFBTSxDQUFDUixTQUFQLElBQW9CQSxTQUFoQztBQUNBQyxJQUFBQSxXQUFXLEdBQUdPLE1BQU0sQ0FBQ1AsV0FBUCxJQUFzQkEsV0FBcEM7QUFDQSxVQUFNUSxLQUFLLEdBQUcsSUFBSTFCLFNBQUosQ0FDWkssTUFEWSxFQUVaVyxJQUZZLEVBR1paLFNBSFksRUFJWmEsU0FKWSxFQUtaQyxXQUxZLEVBTVpDLFNBTlksRUFPWixJQVBZLEVBUVpDLE9BUlksQ0FBZDtBQVVBLFdBQU9NLEtBQUssQ0FBQ0MsT0FBTixFQUFQO0FBQ0QsR0F6QkksQ0FBUDtBQTBCRCxDQTdCRCxDLENBK0JBOzs7QUFDQSxTQUFTRyxHQUFULENBQWF6QixNQUFiLEVBQXFCVyxJQUFyQixFQUEyQlosU0FBM0IsRUFBc0N5QixRQUF0QyxFQUFnRFQsT0FBaEQsRUFBeUQ7QUFDdkQsTUFBSSxPQUFPUyxRQUFQLEtBQW9CLFFBQXhCLEVBQWtDO0FBQ2hDLFVBQU0sSUFBSS9CLEtBQUssQ0FBQ2lDLEtBQVYsQ0FBZ0JqQyxLQUFLLENBQUNpQyxLQUFOLENBQVlDLFlBQTVCLEVBQTBDLGNBQTFDLENBQU47QUFDRDs7QUFFRCxNQUFJNUIsU0FBUyxLQUFLLE9BQWQsSUFBeUJZLElBQUksQ0FBQ2lCLGlCQUFMLEVBQTdCLEVBQXVEO0FBQ3JELFVBQU0sSUFBSW5DLEtBQUssQ0FBQ2lDLEtBQVYsQ0FBZ0JqQyxLQUFLLENBQUNpQyxLQUFOLENBQVlHLGVBQTVCLEVBQTZDLGtDQUE3QyxDQUFOO0FBQ0Q7O0FBRURiLEVBQUFBLG1CQUFtQixDQUFDLFFBQUQsRUFBV2pCLFNBQVgsRUFBc0JZLElBQXRCLENBQW5CO0FBRUEsTUFBSW1CLGNBQUo7QUFDQSxNQUFJQyxnQkFBSjtBQUVBLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixHQUNKZCxJQURJLENBQ0MsTUFBTTtBQUNWLFVBQU1lLFdBQVcsR0FBR3BDLGFBQWEsQ0FBQ0MsU0FBRCxFQUFZQyxNQUFaLEVBQW9CLENBQUMsY0FBRCxFQUFpQixhQUFqQixDQUFwQixDQUFqQztBQUNBLFVBQU1TLFlBQVksR0FBR0YsY0FBYyxDQUFDUixTQUFELEVBQVlDLE1BQVosQ0FBbkM7O0FBQ0EsUUFBSWtDLFdBQVcsSUFBSXpCLFlBQWYsSUFBK0JWLFNBQVMsSUFBSSxVQUFoRCxFQUE0RDtBQUMxRCxhQUFPLElBQUlKLFNBQUosQ0FBY0ssTUFBZCxFQUFzQlcsSUFBdEIsRUFBNEJaLFNBQTVCLEVBQXVDO0FBQUV5QixRQUFBQTtBQUFGLE9BQXZDLEVBQ0pGLE9BREksQ0FDSTtBQUFFYSxRQUFBQSxFQUFFLEVBQUU7QUFBTixPQURKLEVBRUpoQixJQUZJLENBRUNpQixRQUFRLElBQUk7QUFDaEIsWUFBSUEsUUFBUSxJQUFJQSxRQUFRLENBQUNDLE9BQXJCLElBQWdDRCxRQUFRLENBQUNDLE9BQVQsQ0FBaUJDLE1BQXJELEVBQTZEO0FBQzNELGdCQUFNQyxXQUFXLEdBQUdILFFBQVEsQ0FBQ0MsT0FBVCxDQUFpQixDQUFqQixDQUFwQjtBQUNBRSxVQUFBQSxXQUFXLENBQUN4QyxTQUFaLEdBQXdCQSxTQUF4Qjs7QUFDQSxjQUFJQSxTQUFTLEtBQUssVUFBZCxJQUE0QixDQUFDWSxJQUFJLENBQUM2QixRQUF0QyxFQUFnRDtBQUM5QyxnQkFBSSxDQUFDN0IsSUFBSSxDQUFDOEIsSUFBTixJQUFjRixXQUFXLENBQUNFLElBQVosQ0FBaUJqQixRQUFqQixLQUE4QmIsSUFBSSxDQUFDOEIsSUFBTCxDQUFVQyxFQUExRCxFQUE4RDtBQUM1RCxvQkFBTSxJQUFJakQsS0FBSyxDQUFDaUMsS0FBVixDQUFnQmpDLEtBQUssQ0FBQ2lDLEtBQU4sQ0FBWWlCLHFCQUE1QixFQUFtRCx1QkFBbkQsQ0FBTjtBQUNEO0FBQ0Y7O0FBQ0QsY0FBSUMsWUFBWSxHQUFHNUMsTUFBTSxDQUFDNkMsZUFBMUI7QUFDQUQsVUFBQUEsWUFBWSxDQUFDSCxJQUFiLENBQWtCaEIsR0FBbEIsQ0FBc0JjLFdBQVcsQ0FBQ08sWUFBbEM7QUFDQWhCLFVBQUFBLGNBQWMsR0FBR3JDLEtBQUssQ0FBQ3NELE1BQU4sQ0FBYUMsUUFBYixDQUFzQlQsV0FBdEIsQ0FBakI7QUFDQSxpQkFBTzFDLFFBQVEsQ0FBQ29ELGVBQVQsQ0FDTHBELFFBQVEsQ0FBQ1EsS0FBVCxDQUFlNkMsWUFEVixFQUVMdkMsSUFGSyxFQUdMbUIsY0FISyxFQUlMLElBSkssRUFLTDlCLE1BTEssRUFNTGUsT0FOSyxDQUFQO0FBUUQ7O0FBQ0QsY0FBTSxJQUFJdEIsS0FBSyxDQUFDaUMsS0FBVixDQUFnQmpDLEtBQUssQ0FBQ2lDLEtBQU4sQ0FBWXlCLGdCQUE1QixFQUE4Qyw4QkFBOUMsQ0FBTjtBQUNELE9BeEJJLENBQVA7QUF5QkQ7O0FBQ0QsV0FBT25CLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQixFQUFoQixDQUFQO0FBQ0QsR0FoQ0ksRUFpQ0pkLElBakNJLENBaUNDLE1BQU07QUFDVixRQUFJLENBQUNSLElBQUksQ0FBQzZCLFFBQVYsRUFBb0I7QUFDbEIsYUFBTzdCLElBQUksQ0FBQ3lDLFlBQUwsRUFBUDtBQUNELEtBRkQsTUFFTztBQUNMO0FBQ0Q7QUFDRixHQXZDSSxFQXdDSmpDLElBeENJLENBd0NDLE1BQU1uQixNQUFNLENBQUNxRCxRQUFQLENBQWdCQyxVQUFoQixFQXhDUCxFQXlDSm5DLElBekNJLENBeUNDb0MsQ0FBQyxJQUFJO0FBQ1R4QixJQUFBQSxnQkFBZ0IsR0FBR3dCLENBQW5CO0FBQ0EsVUFBTUMsT0FBTyxHQUFHLEVBQWhCOztBQUNBLFFBQUksQ0FBQzdDLElBQUksQ0FBQzZCLFFBQVYsRUFBb0I7QUFDbEJnQixNQUFBQSxPQUFPLENBQUNDLEdBQVIsR0FBYyxDQUFDLEdBQUQsQ0FBZDs7QUFDQSxVQUFJOUMsSUFBSSxDQUFDOEIsSUFBVCxFQUFlO0FBQ2JlLFFBQUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFZQyxJQUFaLENBQWlCL0MsSUFBSSxDQUFDOEIsSUFBTCxDQUFVQyxFQUEzQjtBQUNBYyxRQUFBQSxPQUFPLENBQUNDLEdBQVIsR0FBY0QsT0FBTyxDQUFDQyxHQUFSLENBQVlFLE1BQVosQ0FBbUJoRCxJQUFJLENBQUNpRCxTQUF4QixDQUFkO0FBQ0Q7QUFDRjs7QUFFRCxXQUFPNUQsTUFBTSxDQUFDcUQsUUFBUCxDQUFnQlEsT0FBaEIsQ0FDTDlELFNBREssRUFFTDtBQUNFeUIsTUFBQUEsUUFBUSxFQUFFQTtBQURaLEtBRkssRUFLTGdDLE9BTEssRUFNTHpCLGdCQU5LLENBQVA7QUFRRCxHQTVESSxFQTZESlosSUE3REksQ0E2REMsTUFBTTtBQUNWO0FBQ0EsVUFBTTJDLEtBQUssR0FBRy9CLGdCQUFnQixDQUFDZ0Msd0JBQWpCLENBQTBDaEUsU0FBMUMsQ0FBZDtBQUNBQyxJQUFBQSxNQUFNLENBQUNRLG1CQUFQLENBQTJCd0QsYUFBM0IsQ0FBeUNqRSxTQUF6QyxFQUFvRCtCLGNBQXBELEVBQW9FLElBQXBFLEVBQTBFZ0MsS0FBMUU7QUFDQSxXQUFPakUsUUFBUSxDQUFDb0QsZUFBVCxDQUNMcEQsUUFBUSxDQUFDUSxLQUFULENBQWU0RCxXQURWLEVBRUx0RCxJQUZLLEVBR0xtQixjQUhLLEVBSUwsSUFKSyxFQUtMOUIsTUFMSyxFQU1MZSxPQU5LLENBQVA7QUFRRCxHQXpFSSxFQTBFSm1ELEtBMUVJLENBMEVFQyxLQUFLLElBQUk7QUFDZEMsSUFBQUEseUJBQXlCLENBQUNELEtBQUQsRUFBUXBFLFNBQVIsRUFBbUJZLElBQW5CLENBQXpCO0FBQ0QsR0E1RUksQ0FBUDtBQTZFRCxDLENBRUQ7OztBQUNBLFNBQVMwRCxNQUFULENBQWdCckUsTUFBaEIsRUFBd0JXLElBQXhCLEVBQThCWixTQUE5QixFQUF5Q3VFLFVBQXpDLEVBQXFEeEQsU0FBckQsRUFBZ0VDLE9BQWhFLEVBQXlFO0FBQ3ZFQyxFQUFBQSxtQkFBbUIsQ0FBQyxRQUFELEVBQVdqQixTQUFYLEVBQXNCWSxJQUF0QixDQUFuQjtBQUNBLE1BQUk0RCxLQUFLLEdBQUcsSUFBSTNFLFNBQUosQ0FBY0ksTUFBZCxFQUFzQlcsSUFBdEIsRUFBNEJaLFNBQTVCLEVBQXVDLElBQXZDLEVBQTZDdUUsVUFBN0MsRUFBeUQsSUFBekQsRUFBK0R4RCxTQUEvRCxFQUEwRUMsT0FBMUUsQ0FBWjtBQUNBLFNBQU93RCxLQUFLLENBQUNqRCxPQUFOLEVBQVA7QUFDRCxDLENBRUQ7QUFDQTtBQUNBOzs7QUFDQSxTQUFTa0QsTUFBVCxDQUFnQnhFLE1BQWhCLEVBQXdCVyxJQUF4QixFQUE4QlosU0FBOUIsRUFBeUNhLFNBQXpDLEVBQW9EMEQsVUFBcEQsRUFBZ0V4RCxTQUFoRSxFQUEyRUMsT0FBM0UsRUFBb0Y7QUFDbEZDLEVBQUFBLG1CQUFtQixDQUFDLFFBQUQsRUFBV2pCLFNBQVgsRUFBc0JZLElBQXRCLENBQW5CO0FBRUEsU0FBT3FCLE9BQU8sQ0FBQ0MsT0FBUixHQUNKZCxJQURJLENBQ0MsTUFBTTtBQUNWLFVBQU1lLFdBQVcsR0FBR3BDLGFBQWEsQ0FBQ0MsU0FBRCxFQUFZQyxNQUFaLEVBQW9CLENBQUMsWUFBRCxFQUFlLFdBQWYsQ0FBcEIsQ0FBakM7QUFDQSxVQUFNUyxZQUFZLEdBQUdGLGNBQWMsQ0FBQ1IsU0FBRCxFQUFZQyxNQUFaLENBQW5DOztBQUNBLFFBQUlrQyxXQUFXLElBQUl6QixZQUFuQixFQUFpQztBQUMvQjtBQUNBLGFBQU8sSUFBSWQsU0FBSixDQUNMSyxNQURLLEVBRUxXLElBRkssRUFHTFosU0FISyxFQUlMYSxTQUpLLEVBS0w2RCxTQUxLLEVBTUxBLFNBTkssRUFPTCxLQVBLLEVBUUwxRCxPQVJLLEVBU0xPLE9BVEssQ0FTRztBQUNSYSxRQUFBQSxFQUFFLEVBQUU7QUFESSxPQVRILENBQVA7QUFZRDs7QUFDRCxXQUFPSCxPQUFPLENBQUNDLE9BQVIsQ0FBZ0IsRUFBaEIsQ0FBUDtBQUNELEdBcEJJLEVBcUJKZCxJQXJCSSxDQXFCQyxDQUFDO0FBQUVrQixJQUFBQTtBQUFGLEdBQUQsS0FBaUI7QUFDckIsUUFBSXFDLGtCQUFKOztBQUNBLFFBQUlyQyxPQUFPLElBQUlBLE9BQU8sQ0FBQ0MsTUFBdkIsRUFBK0I7QUFDN0JvQyxNQUFBQSxrQkFBa0IsR0FBR3JDLE9BQU8sQ0FBQyxDQUFELENBQTVCO0FBQ0Q7O0FBQ0QsV0FBTyxJQUFJekMsU0FBSixDQUNMSSxNQURLLEVBRUxXLElBRkssRUFHTFosU0FISyxFQUlMYSxTQUpLLEVBS0wwRCxVQUxLLEVBTUxJLGtCQU5LLEVBT0w1RCxTQVBLLEVBUUxDLE9BUkssRUFTTCxRQVRLLEVBVUxPLE9BVkssRUFBUDtBQVdELEdBckNJLEVBc0NKNEMsS0F0Q0ksQ0FzQ0VDLEtBQUssSUFBSTtBQUNkQyxJQUFBQSx5QkFBeUIsQ0FBQ0QsS0FBRCxFQUFRcEUsU0FBUixFQUFtQlksSUFBbkIsQ0FBekI7QUFDRCxHQXhDSSxDQUFQO0FBeUNEOztBQUVELFNBQVN5RCx5QkFBVCxDQUFtQ0QsS0FBbkMsRUFBMENwRSxTQUExQyxFQUFxRFksSUFBckQsRUFBMkQ7QUFDekQ7QUFDQSxNQUFJWixTQUFTLEtBQUssT0FBZCxJQUF5Qm9FLEtBQUssQ0FBQ1EsSUFBTixLQUFlbEYsS0FBSyxDQUFDaUMsS0FBTixDQUFZeUIsZ0JBQXBELElBQXdFLENBQUN4QyxJQUFJLENBQUM2QixRQUFsRixFQUE0RjtBQUMxRixVQUFNLElBQUkvQyxLQUFLLENBQUNpQyxLQUFWLENBQWdCakMsS0FBSyxDQUFDaUMsS0FBTixDQUFZRyxlQUE1QixFQUE2QyxvQkFBN0MsQ0FBTjtBQUNEOztBQUNELFFBQU1zQyxLQUFOO0FBQ0Q7O0FBRUQsTUFBTVMsMkJBQTJCLEdBQUcsQ0FDbEMsWUFEa0MsRUFFbEMsYUFGa0MsRUFHbEMsUUFIa0MsRUFJbEMsZUFKa0MsRUFLbEMsY0FMa0MsRUFNbEMsY0FOa0MsQ0FBcEMsQyxDQVFBOztBQUNBLFNBQVM1RCxtQkFBVCxDQUE2QjZELE1BQTdCLEVBQXFDOUUsU0FBckMsRUFBZ0RZLElBQWhELEVBQXNEO0FBQ3BELE1BQUlaLFNBQVMsS0FBSyxlQUFkLElBQWlDLENBQUNZLElBQUksQ0FBQzZCLFFBQTNDLEVBQXFEO0FBQ25ELFFBQUlxQyxNQUFNLEtBQUssUUFBWCxJQUF1QkEsTUFBTSxLQUFLLE1BQXRDLEVBQThDO0FBQzVDLFlBQU1WLEtBQUssR0FBSSx5Q0FBd0NVLE1BQU8sNENBQTlEO0FBQ0EsWUFBTSxJQUFJcEYsS0FBSyxDQUFDaUMsS0FBVixDQUFnQmpDLEtBQUssQ0FBQ2lDLEtBQU4sQ0FBWW9ELG1CQUE1QixFQUFpRFgsS0FBakQsQ0FBTjtBQUNEO0FBQ0YsR0FObUQsQ0FRcEQ7OztBQUNBLE1BQUlTLDJCQUEyQixDQUFDRyxPQUE1QixDQUFvQ2hGLFNBQXBDLEtBQWtELENBQWxELElBQXVELENBQUNZLElBQUksQ0FBQzZCLFFBQWpFLEVBQTJFO0FBQ3pFLFVBQU0yQixLQUFLLEdBQUkseUNBQXdDVSxNQUFPLHFCQUFvQjlFLFNBQVUsY0FBNUY7QUFDQSxVQUFNLElBQUlOLEtBQUssQ0FBQ2lDLEtBQVYsQ0FBZ0JqQyxLQUFLLENBQUNpQyxLQUFOLENBQVlvRCxtQkFBNUIsRUFBaURYLEtBQWpELENBQU47QUFDRCxHQVptRCxDQWNwRDs7O0FBQ0EsTUFBSXhELElBQUksQ0FBQ3FFLFVBQUwsS0FBb0JILE1BQU0sS0FBSyxRQUFYLElBQXVCQSxNQUFNLEtBQUssUUFBbEMsSUFBOENBLE1BQU0sS0FBSyxRQUE3RSxDQUFKLEVBQTRGO0FBQzFGLFVBQU1WLEtBQUssR0FBSSxvREFBbURVLE1BQU8sYUFBekU7QUFDQSxVQUFNLElBQUlwRixLQUFLLENBQUNpQyxLQUFWLENBQWdCakMsS0FBSyxDQUFDaUMsS0FBTixDQUFZb0QsbUJBQTVCLEVBQWlEWCxLQUFqRCxDQUFOO0FBQ0Q7QUFDRjs7QUFFRGMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZiLEVBQUFBLE1BRGU7QUFFZjVDLEVBQUFBLEdBRmU7QUFHZmYsRUFBQUEsSUFIZTtBQUlmYSxFQUFBQSxHQUplO0FBS2ZpRCxFQUFBQTtBQUxlLENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gVGhpcyBmaWxlIGNvbnRhaW5zIGhlbHBlcnMgZm9yIHJ1bm5pbmcgb3BlcmF0aW9ucyBpbiBSRVNUIGZvcm1hdC5cbi8vIFRoZSBnb2FsIGlzIHRoYXQgaGFuZGxlcnMgdGhhdCBleHBsaWNpdGx5IGhhbmRsZSBhbiBleHByZXNzIHJvdXRlXG4vLyBzaG91bGQganVzdCBiZSBzaGFsbG93IHdyYXBwZXJzIGFyb3VuZCB0aGluZ3MgaW4gdGhpcyBmaWxlLCBidXRcbi8vIHRoZXNlIGZ1bmN0aW9ucyBzaG91bGQgbm90IGV4cGxpY2l0bHkgZGVwZW5kIG9uIHRoZSByZXF1ZXN0XG4vLyBvYmplY3QuXG4vLyBUaGlzIG1lYW5zIHRoYXQgb25lIG9mIHRoZXNlIGhhbmRsZXJzIGNhbiBzdXBwb3J0IG11bHRpcGxlXG4vLyByb3V0ZXMuIFRoYXQncyB1c2VmdWwgZm9yIHRoZSByb3V0ZXMgdGhhdCBkbyByZWFsbHkgc2ltaWxhclxuLy8gdGhpbmdzLlxuXG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbnZhciBSZXN0UXVlcnkgPSByZXF1aXJlKCcuL1Jlc3RRdWVyeScpO1xudmFyIFJlc3RXcml0ZSA9IHJlcXVpcmUoJy4vUmVzdFdyaXRlJyk7XG52YXIgdHJpZ2dlcnMgPSByZXF1aXJlKCcuL3RyaWdnZXJzJyk7XG5cbmZ1bmN0aW9uIGNoZWNrVHJpZ2dlcnMoY2xhc3NOYW1lLCBjb25maWcsIHR5cGVzKSB7XG4gIHJldHVybiB0eXBlcy5zb21lKHRyaWdnZXJUeXBlID0+IHtcbiAgICByZXR1cm4gdHJpZ2dlcnMuZ2V0VHJpZ2dlcihjbGFzc05hbWUsIHRyaWdnZXJzLlR5cGVzW3RyaWdnZXJUeXBlXSwgY29uZmlnLmFwcGxpY2F0aW9uSWQpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gY2hlY2tMaXZlUXVlcnkoY2xhc3NOYW1lLCBjb25maWcpIHtcbiAgcmV0dXJuIGNvbmZpZy5saXZlUXVlcnlDb250cm9sbGVyICYmIGNvbmZpZy5saXZlUXVlcnlDb250cm9sbGVyLmhhc0xpdmVRdWVyeShjbGFzc05hbWUpO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYW4gb2JqZWN0IHdpdGggb3B0aW9uYWwga2V5cyAncmVzdWx0cycgYW5kICdjb3VudCcuXG5mdW5jdGlvbiBmaW5kKGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCByZXN0V2hlcmUsIHJlc3RPcHRpb25zLCBjbGllbnRTREssIGNvbnRleHQpIHtcbiAgZW5mb3JjZVJvbGVTZWN1cml0eSgnZmluZCcsIGNsYXNzTmFtZSwgYXV0aCk7XG4gIHJldHVybiB0cmlnZ2Vyc1xuICAgIC5tYXliZVJ1blF1ZXJ5VHJpZ2dlcihcbiAgICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZUZpbmQsXG4gICAgICBjbGFzc05hbWUsXG4gICAgICByZXN0V2hlcmUsXG4gICAgICByZXN0T3B0aW9ucyxcbiAgICAgIGNvbmZpZyxcbiAgICAgIGF1dGgsXG4gICAgICBjb250ZXh0XG4gICAgKVxuICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICByZXN0V2hlcmUgPSByZXN1bHQucmVzdFdoZXJlIHx8IHJlc3RXaGVyZTtcbiAgICAgIHJlc3RPcHRpb25zID0gcmVzdWx0LnJlc3RPcHRpb25zIHx8IHJlc3RPcHRpb25zO1xuICAgICAgY29uc3QgcXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KFxuICAgICAgICBjb25maWcsXG4gICAgICAgIGF1dGgsXG4gICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgcmVzdFdoZXJlLFxuICAgICAgICByZXN0T3B0aW9ucyxcbiAgICAgICAgY2xpZW50U0RLLFxuICAgICAgICB0cnVlLFxuICAgICAgICBjb250ZXh0XG4gICAgICApO1xuICAgICAgcmV0dXJuIHF1ZXJ5LmV4ZWN1dGUoKTtcbiAgICB9KTtcbn1cblxuLy8gZ2V0IGlzIGp1c3QgbGlrZSBmaW5kIGJ1dCBvbmx5IHF1ZXJpZXMgYW4gb2JqZWN0SWQuXG5jb25zdCBnZXQgPSAoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIG9iamVjdElkLCByZXN0T3B0aW9ucywgY2xpZW50U0RLLCBjb250ZXh0KSA9PiB7XG4gIHZhciByZXN0V2hlcmUgPSB7IG9iamVjdElkIH07XG4gIGVuZm9yY2VSb2xlU2VjdXJpdHkoJ2dldCcsIGNsYXNzTmFtZSwgYXV0aCk7XG4gIHJldHVybiB0cmlnZ2Vyc1xuICAgIC5tYXliZVJ1blF1ZXJ5VHJpZ2dlcihcbiAgICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZUZpbmQsXG4gICAgICBjbGFzc05hbWUsXG4gICAgICByZXN0V2hlcmUsXG4gICAgICByZXN0T3B0aW9ucyxcbiAgICAgIGNvbmZpZyxcbiAgICAgIGF1dGgsXG4gICAgICBjb250ZXh0LFxuICAgICAgdHJ1ZVxuICAgIClcbiAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgcmVzdFdoZXJlID0gcmVzdWx0LnJlc3RXaGVyZSB8fCByZXN0V2hlcmU7XG4gICAgICByZXN0T3B0aW9ucyA9IHJlc3VsdC5yZXN0T3B0aW9ucyB8fCByZXN0T3B0aW9ucztcbiAgICAgIGNvbnN0IHF1ZXJ5ID0gbmV3IFJlc3RRdWVyeShcbiAgICAgICAgY29uZmlnLFxuICAgICAgICBhdXRoLFxuICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgIHJlc3RXaGVyZSxcbiAgICAgICAgcmVzdE9wdGlvbnMsXG4gICAgICAgIGNsaWVudFNESyxcbiAgICAgICAgdHJ1ZSxcbiAgICAgICAgY29udGV4dFxuICAgICAgKTtcbiAgICAgIHJldHVybiBxdWVyeS5leGVjdXRlKCk7XG4gICAgfSk7XG59O1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGRvZXNuJ3QgcmVzb2x2ZSB0byBhbnkgdXNlZnVsIHZhbHVlLlxuZnVuY3Rpb24gZGVsKGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCBvYmplY3RJZCwgY29udGV4dCkge1xuICBpZiAodHlwZW9mIG9iamVjdElkICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sICdiYWQgb2JqZWN0SWQnKTtcbiAgfVxuXG4gIGlmIChjbGFzc05hbWUgPT09ICdfVXNlcicgJiYgYXV0aC5pc1VuYXV0aGVudGljYXRlZCgpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlNFU1NJT05fTUlTU0lORywgJ0luc3VmZmljaWVudCBhdXRoIHRvIGRlbGV0ZSB1c2VyJyk7XG4gIH1cblxuICBlbmZvcmNlUm9sZVNlY3VyaXR5KCdkZWxldGUnLCBjbGFzc05hbWUsIGF1dGgpO1xuXG4gIGxldCBpbmZsYXRlZE9iamVjdDtcbiAgbGV0IHNjaGVtYUNvbnRyb2xsZXI7XG5cbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgY29uc3QgaGFzVHJpZ2dlcnMgPSBjaGVja1RyaWdnZXJzKGNsYXNzTmFtZSwgY29uZmlnLCBbJ2JlZm9yZURlbGV0ZScsICdhZnRlckRlbGV0ZSddKTtcbiAgICAgIGNvbnN0IGhhc0xpdmVRdWVyeSA9IGNoZWNrTGl2ZVF1ZXJ5KGNsYXNzTmFtZSwgY29uZmlnKTtcbiAgICAgIGlmIChoYXNUcmlnZ2VycyB8fCBoYXNMaXZlUXVlcnkgfHwgY2xhc3NOYW1lID09ICdfU2Vzc2lvbicpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXN0UXVlcnkoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIHsgb2JqZWN0SWQgfSlcbiAgICAgICAgICAuZXhlY3V0ZSh7IG9wOiAnZGVsZXRlJyB9KVxuICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgIGlmIChyZXNwb25zZSAmJiByZXNwb25zZS5yZXN1bHRzICYmIHJlc3BvbnNlLnJlc3VsdHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGZpcnN0UmVzdWx0ID0gcmVzcG9uc2UucmVzdWx0c1swXTtcbiAgICAgICAgICAgICAgZmlyc3RSZXN1bHQuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xuICAgICAgICAgICAgICBpZiAoY2xhc3NOYW1lID09PSAnX1Nlc3Npb24nICYmICFhdXRoLmlzTWFzdGVyKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFhdXRoLnVzZXIgfHwgZmlyc3RSZXN1bHQudXNlci5vYmplY3RJZCAhPT0gYXV0aC51c2VyLmlkKSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOLCAnSW52YWxpZCBzZXNzaW9uIHRva2VuJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHZhciBjYWNoZUFkYXB0ZXIgPSBjb25maWcuY2FjaGVDb250cm9sbGVyO1xuICAgICAgICAgICAgICBjYWNoZUFkYXB0ZXIudXNlci5kZWwoZmlyc3RSZXN1bHQuc2Vzc2lvblRva2VuKTtcbiAgICAgICAgICAgICAgaW5mbGF0ZWRPYmplY3QgPSBQYXJzZS5PYmplY3QuZnJvbUpTT04oZmlyc3RSZXN1bHQpO1xuICAgICAgICAgICAgICByZXR1cm4gdHJpZ2dlcnMubWF5YmVSdW5UcmlnZ2VyKFxuICAgICAgICAgICAgICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZURlbGV0ZSxcbiAgICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICAgIGluZmxhdGVkT2JqZWN0LFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgICAgIGNvbnRleHRcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnT2JqZWN0IG5vdCBmb3VuZCBmb3IgZGVsZXRlLicpO1xuICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICBpZiAoIWF1dGguaXNNYXN0ZXIpIHtcbiAgICAgICAgcmV0dXJuIGF1dGguZ2V0VXNlclJvbGVzKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiBjb25maWcuZGF0YWJhc2UubG9hZFNjaGVtYSgpKVxuICAgIC50aGVuKHMgPT4ge1xuICAgICAgc2NoZW1hQ29udHJvbGxlciA9IHM7XG4gICAgICBjb25zdCBvcHRpb25zID0ge307XG4gICAgICBpZiAoIWF1dGguaXNNYXN0ZXIpIHtcbiAgICAgICAgb3B0aW9ucy5hY2wgPSBbJyonXTtcbiAgICAgICAgaWYgKGF1dGgudXNlcikge1xuICAgICAgICAgIG9wdGlvbnMuYWNsLnB1c2goYXV0aC51c2VyLmlkKTtcbiAgICAgICAgICBvcHRpb25zLmFjbCA9IG9wdGlvbnMuYWNsLmNvbmNhdChhdXRoLnVzZXJSb2xlcyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNvbmZpZy5kYXRhYmFzZS5kZXN0cm95KFxuICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgIHtcbiAgICAgICAgICBvYmplY3RJZDogb2JqZWN0SWQsXG4gICAgICAgIH0sXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIHNjaGVtYUNvbnRyb2xsZXJcbiAgICAgICk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICAvLyBOb3RpZnkgTGl2ZVF1ZXJ5IHNlcnZlciBpZiBwb3NzaWJsZVxuICAgICAgY29uc3QgcGVybXMgPSBzY2hlbWFDb250cm9sbGVyLmdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyhjbGFzc05hbWUpO1xuICAgICAgY29uZmlnLmxpdmVRdWVyeUNvbnRyb2xsZXIub25BZnRlckRlbGV0ZShjbGFzc05hbWUsIGluZmxhdGVkT2JqZWN0LCBudWxsLCBwZXJtcyk7XG4gICAgICByZXR1cm4gdHJpZ2dlcnMubWF5YmVSdW5UcmlnZ2VyKFxuICAgICAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlckRlbGV0ZSxcbiAgICAgICAgYXV0aCxcbiAgICAgICAgaW5mbGF0ZWRPYmplY3QsXG4gICAgICAgIG51bGwsXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgY29udGV4dFxuICAgICAgKTtcbiAgICB9KVxuICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICBoYW5kbGVTZXNzaW9uTWlzc2luZ0Vycm9yKGVycm9yLCBjbGFzc05hbWUsIGF1dGgpO1xuICAgIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYSB7cmVzcG9uc2UsIHN0YXR1cywgbG9jYXRpb259IG9iamVjdC5cbmZ1bmN0aW9uIGNyZWF0ZShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgcmVzdE9iamVjdCwgY2xpZW50U0RLLCBjb250ZXh0KSB7XG4gIGVuZm9yY2VSb2xlU2VjdXJpdHkoJ2NyZWF0ZScsIGNsYXNzTmFtZSwgYXV0aCk7XG4gIHZhciB3cml0ZSA9IG5ldyBSZXN0V3JpdGUoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIG51bGwsIHJlc3RPYmplY3QsIG51bGwsIGNsaWVudFNESywgY29udGV4dCk7XG4gIHJldHVybiB3cml0ZS5leGVjdXRlKCk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgY29udGFpbnMgdGhlIGZpZWxkcyBvZiB0aGUgdXBkYXRlIHRoYXQgdGhlXG4vLyBSRVNUIEFQSSBpcyBzdXBwb3NlZCB0byByZXR1cm4uXG4vLyBVc3VhbGx5LCB0aGlzIGlzIGp1c3QgdXBkYXRlZEF0LlxuZnVuY3Rpb24gdXBkYXRlKGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCByZXN0V2hlcmUsIHJlc3RPYmplY3QsIGNsaWVudFNESywgY29udGV4dCkge1xuICBlbmZvcmNlUm9sZVNlY3VyaXR5KCd1cGRhdGUnLCBjbGFzc05hbWUsIGF1dGgpO1xuXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIGNvbnN0IGhhc1RyaWdnZXJzID0gY2hlY2tUcmlnZ2VycyhjbGFzc05hbWUsIGNvbmZpZywgWydiZWZvcmVTYXZlJywgJ2FmdGVyU2F2ZSddKTtcbiAgICAgIGNvbnN0IGhhc0xpdmVRdWVyeSA9IGNoZWNrTGl2ZVF1ZXJ5KGNsYXNzTmFtZSwgY29uZmlnKTtcbiAgICAgIGlmIChoYXNUcmlnZ2VycyB8fCBoYXNMaXZlUXVlcnkpIHtcbiAgICAgICAgLy8gRG8gbm90IHVzZSBmaW5kLCBhcyBpdCBydW5zIHRoZSBiZWZvcmUgZmluZHNcbiAgICAgICAgcmV0dXJuIG5ldyBSZXN0UXVlcnkoXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIGF1dGgsXG4gICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgIHJlc3RXaGVyZSxcbiAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgIGNvbnRleHRcbiAgICAgICAgKS5leGVjdXRlKHtcbiAgICAgICAgICBvcDogJ3VwZGF0ZScsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gICAgfSlcbiAgICAudGhlbigoeyByZXN1bHRzIH0pID0+IHtcbiAgICAgIHZhciBvcmlnaW5hbFJlc3RPYmplY3Q7XG4gICAgICBpZiAocmVzdWx0cyAmJiByZXN1bHRzLmxlbmd0aCkge1xuICAgICAgICBvcmlnaW5hbFJlc3RPYmplY3QgPSByZXN1bHRzWzBdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBSZXN0V3JpdGUoXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgYXV0aCxcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICByZXN0V2hlcmUsXG4gICAgICAgIHJlc3RPYmplY3QsXG4gICAgICAgIG9yaWdpbmFsUmVzdE9iamVjdCxcbiAgICAgICAgY2xpZW50U0RLLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgICAndXBkYXRlJ1xuICAgICAgKS5leGVjdXRlKCk7XG4gICAgfSlcbiAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgaGFuZGxlU2Vzc2lvbk1pc3NpbmdFcnJvcihlcnJvciwgY2xhc3NOYW1lLCBhdXRoKTtcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gaGFuZGxlU2Vzc2lvbk1pc3NpbmdFcnJvcihlcnJvciwgY2xhc3NOYW1lLCBhdXRoKSB7XG4gIC8vIElmIHdlJ3JlIHRyeWluZyB0byB1cGRhdGUgYSB1c2VyIHdpdGhvdXQgLyB3aXRoIGJhZCBzZXNzaW9uIHRva2VuXG4gIGlmIChjbGFzc05hbWUgPT09ICdfVXNlcicgJiYgZXJyb3IuY29kZSA9PT0gUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCAmJiAhYXV0aC5pc01hc3Rlcikge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5TRVNTSU9OX01JU1NJTkcsICdJbnN1ZmZpY2llbnQgYXV0aC4nKTtcbiAgfVxuICB0aHJvdyBlcnJvcjtcbn1cblxuY29uc3QgY2xhc3Nlc1dpdGhNYXN0ZXJPbmx5QWNjZXNzID0gW1xuICAnX0pvYlN0YXR1cycsXG4gICdfUHVzaFN0YXR1cycsXG4gICdfSG9va3MnLFxuICAnX0dsb2JhbENvbmZpZycsXG4gICdfSm9iU2NoZWR1bGUnLFxuICAnX0lkZW1wb3RlbmN5Jyxcbl07XG4vLyBEaXNhbGxvd2luZyBhY2Nlc3MgdG8gdGhlIF9Sb2xlIGNvbGxlY3Rpb24gZXhjZXB0IGJ5IG1hc3RlciBrZXlcbmZ1bmN0aW9uIGVuZm9yY2VSb2xlU2VjdXJpdHkobWV0aG9kLCBjbGFzc05hbWUsIGF1dGgpIHtcbiAgaWYgKGNsYXNzTmFtZSA9PT0gJ19JbnN0YWxsYXRpb24nICYmICFhdXRoLmlzTWFzdGVyKSB7XG4gICAgaWYgKG1ldGhvZCA9PT0gJ2RlbGV0ZScgfHwgbWV0aG9kID09PSAnZmluZCcpIHtcbiAgICAgIGNvbnN0IGVycm9yID0gYENsaWVudHMgYXJlbid0IGFsbG93ZWQgdG8gcGVyZm9ybSB0aGUgJHttZXRob2R9IG9wZXJhdGlvbiBvbiB0aGUgaW5zdGFsbGF0aW9uIGNvbGxlY3Rpb24uYDtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLCBlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgLy9hbGwgdm9sYXRpbGVDbGFzc2VzIGFyZSBtYXN0ZXJLZXkgb25seVxuICBpZiAoY2xhc3Nlc1dpdGhNYXN0ZXJPbmx5QWNjZXNzLmluZGV4T2YoY2xhc3NOYW1lKSA+PSAwICYmICFhdXRoLmlzTWFzdGVyKSB7XG4gICAgY29uc3QgZXJyb3IgPSBgQ2xpZW50cyBhcmVuJ3QgYWxsb3dlZCB0byBwZXJmb3JtIHRoZSAke21ldGhvZH0gb3BlcmF0aW9uIG9uIHRoZSAke2NsYXNzTmFtZX0gY29sbGVjdGlvbi5gO1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLCBlcnJvcik7XG4gIH1cblxuICAvLyByZWFkT25seSBtYXN0ZXJLZXkgaXMgbm90IGFsbG93ZWRcbiAgaWYgKGF1dGguaXNSZWFkT25seSAmJiAobWV0aG9kID09PSAnZGVsZXRlJyB8fCBtZXRob2QgPT09ICdjcmVhdGUnIHx8IG1ldGhvZCA9PT0gJ3VwZGF0ZScpKSB7XG4gICAgY29uc3QgZXJyb3IgPSBgcmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIHBlcmZvcm0gdGhlICR7bWV0aG9kfSBvcGVyYXRpb24uYDtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTiwgZXJyb3IpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBjcmVhdGUsXG4gIGRlbCxcbiAgZmluZCxcbiAgZ2V0LFxuICB1cGRhdGUsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/triggers.js b/lib/triggers.js new file mode 100644 index 0000000000..094d75346c --- /dev/null +++ b/lib/triggers.js @@ -0,0 +1,1032 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.addFunction = addFunction; +exports.addJob = addJob; +exports.addTrigger = addTrigger; +exports.addFileTrigger = addFileTrigger; +exports.addConnectTrigger = addConnectTrigger; +exports.addLiveQueryEventHandler = addLiveQueryEventHandler; +exports.removeFunction = removeFunction; +exports.removeTrigger = removeTrigger; +exports._unregisterAll = _unregisterAll; +exports.getTrigger = getTrigger; +exports.getFileTrigger = getFileTrigger; +exports.triggerExists = triggerExists; +exports.getFunction = getFunction; +exports.getFunctionNames = getFunctionNames; +exports.getJob = getJob; +exports.getJobs = getJobs; +exports.getValidator = getValidator; +exports.getRequestObject = getRequestObject; +exports.getRequestQueryObject = getRequestQueryObject; +exports.getResponseObject = getResponseObject; +exports.maybeRunAfterFindTrigger = maybeRunAfterFindTrigger; +exports.maybeRunQueryTrigger = maybeRunQueryTrigger; +exports.resolveError = resolveError; +exports.maybeRunValidator = maybeRunValidator; +exports.maybeRunTrigger = maybeRunTrigger; +exports.inflate = inflate; +exports.runLiveQueryEventHandlers = runLiveQueryEventHandlers; +exports.getRequestFileObject = getRequestFileObject; +exports.maybeRunFileTrigger = maybeRunFileTrigger; +exports.maybeRunConnectTrigger = maybeRunConnectTrigger; +exports.maybeRunSubscribeTrigger = maybeRunSubscribeTrigger; +exports.maybeRunAfterEventTrigger = maybeRunAfterEventTrigger; +exports.Types = void 0; + +var _node = _interopRequireDefault(require("parse/node")); + +var _logger = require("./logger"); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +const Types = { + beforeLogin: 'beforeLogin', + afterLogin: 'afterLogin', + afterLogout: 'afterLogout', + beforeSave: 'beforeSave', + afterSave: 'afterSave', + beforeDelete: 'beforeDelete', + afterDelete: 'afterDelete', + beforeFind: 'beforeFind', + afterFind: 'afterFind', + beforeSaveFile: 'beforeSaveFile', + afterSaveFile: 'afterSaveFile', + beforeDeleteFile: 'beforeDeleteFile', + afterDeleteFile: 'afterDeleteFile', + beforeConnect: 'beforeConnect', + beforeSubscribe: 'beforeSubscribe', + afterEvent: 'afterEvent' +}; +exports.Types = Types; +const FileClassName = '@File'; +const ConnectClassName = '@Connect'; + +const baseStore = function () { + const Validators = Object.keys(Types).reduce(function (base, key) { + base[key] = {}; + return base; + }, {}); + const Functions = {}; + const Jobs = {}; + const LiveQuery = []; + const Triggers = Object.keys(Types).reduce(function (base, key) { + base[key] = {}; + return base; + }, {}); + return Object.freeze({ + Functions, + Jobs, + Validators, + Triggers, + LiveQuery + }); +}; + +function validateClassNameForTriggers(className, type) { + if (type == Types.beforeSave && className === '_PushStatus') { + // _PushStatus uses undocumented nested key increment ops + // allowing beforeSave would mess up the objects big time + // TODO: Allow proper documented way of using nested increment ops + throw 'Only afterSave is allowed on _PushStatus'; + } + + if ((type === Types.beforeLogin || type === Types.afterLogin) && className !== '_User') { + // TODO: check if upstream code will handle `Error` instance rather + // than this anti-pattern of throwing strings + throw 'Only the _User class is allowed for the beforeLogin and afterLogin triggers'; + } + + if (type === Types.afterLogout && className !== '_Session') { + // TODO: check if upstream code will handle `Error` instance rather + // than this anti-pattern of throwing strings + throw 'Only the _Session class is allowed for the afterLogout trigger.'; + } + + if (className === '_Session' && type !== Types.afterLogout) { + // TODO: check if upstream code will handle `Error` instance rather + // than this anti-pattern of throwing strings + throw 'Only the afterLogout trigger is allowed for the _Session class.'; + } + + return className; +} + +const _triggerStore = {}; +const Category = { + Functions: 'Functions', + Validators: 'Validators', + Jobs: 'Jobs', + Triggers: 'Triggers' +}; + +function getStore(category, name, applicationId) { + const path = name.split('.'); + path.splice(-1); // remove last component + + applicationId = applicationId || _node.default.applicationId; + _triggerStore[applicationId] = _triggerStore[applicationId] || baseStore(); + let store = _triggerStore[applicationId][category]; + + for (const component of path) { + store = store[component]; + + if (!store) { + return undefined; + } + } + + return store; +} + +function add(category, name, handler, applicationId) { + const lastComponent = name.split('.').splice(-1); + const store = getStore(category, name, applicationId); + + if (store[lastComponent]) { + _logger.logger.warn(`Warning: Duplicate cloud functions exist for ${lastComponent}. Only the last one will be used and the others will be ignored.`); + } + + store[lastComponent] = handler; +} + +function remove(category, name, applicationId) { + const lastComponent = name.split('.').splice(-1); + const store = getStore(category, name, applicationId); + delete store[lastComponent]; +} + +function get(category, name, applicationId) { + const lastComponent = name.split('.').splice(-1); + const store = getStore(category, name, applicationId); + return store[lastComponent]; +} + +function addFunction(functionName, handler, validationHandler, applicationId) { + add(Category.Functions, functionName, handler, applicationId); + add(Category.Validators, functionName, validationHandler, applicationId); +} + +function addJob(jobName, handler, applicationId) { + add(Category.Jobs, jobName, handler, applicationId); +} + +function addTrigger(type, className, handler, applicationId, validationHandler) { + validateClassNameForTriggers(className, type); + add(Category.Triggers, `${type}.${className}`, handler, applicationId); + add(Category.Validators, `${type}.${className}`, validationHandler, applicationId); +} + +function addFileTrigger(type, handler, applicationId, validationHandler) { + add(Category.Triggers, `${type}.${FileClassName}`, handler, applicationId); + add(Category.Validators, `${type}.${FileClassName}`, validationHandler, applicationId); +} + +function addConnectTrigger(type, handler, applicationId, validationHandler) { + add(Category.Triggers, `${type}.${ConnectClassName}`, handler, applicationId); + add(Category.Validators, `${type}.${ConnectClassName}`, validationHandler, applicationId); +} + +function addLiveQueryEventHandler(handler, applicationId) { + applicationId = applicationId || _node.default.applicationId; + _triggerStore[applicationId] = _triggerStore[applicationId] || baseStore(); + + _triggerStore[applicationId].LiveQuery.push(handler); +} + +function removeFunction(functionName, applicationId) { + remove(Category.Functions, functionName, applicationId); +} + +function removeTrigger(type, className, applicationId) { + remove(Category.Triggers, `${type}.${className}`, applicationId); +} + +function _unregisterAll() { + Object.keys(_triggerStore).forEach(appId => delete _triggerStore[appId]); +} + +function getTrigger(className, triggerType, applicationId) { + if (!applicationId) { + throw 'Missing ApplicationID'; + } + + return get(Category.Triggers, `${triggerType}.${className}`, applicationId); +} + +function getFileTrigger(type, applicationId) { + return getTrigger(FileClassName, type, applicationId); +} + +function triggerExists(className, type, applicationId) { + return getTrigger(className, type, applicationId) != undefined; +} + +function getFunction(functionName, applicationId) { + return get(Category.Functions, functionName, applicationId); +} + +function getFunctionNames(applicationId) { + const store = _triggerStore[applicationId] && _triggerStore[applicationId][Category.Functions] || {}; + const functionNames = []; + + const extractFunctionNames = (namespace, store) => { + Object.keys(store).forEach(name => { + const value = store[name]; + + if (namespace) { + name = `${namespace}.${name}`; + } + + if (typeof value === 'function') { + functionNames.push(name); + } else { + extractFunctionNames(name, value); + } + }); + }; + + extractFunctionNames(null, store); + return functionNames; +} + +function getJob(jobName, applicationId) { + return get(Category.Jobs, jobName, applicationId); +} + +function getJobs(applicationId) { + var manager = _triggerStore[applicationId]; + + if (manager && manager.Jobs) { + return manager.Jobs; + } + + return undefined; +} + +function getValidator(functionName, applicationId) { + return get(Category.Validators, functionName, applicationId); +} + +function getRequestObject(triggerType, auth, parseObject, originalParseObject, config, context) { + const request = { + triggerName: triggerType, + object: parseObject, + master: false, + log: config.loggerController, + headers: config.headers, + ip: config.ip + }; + + if (originalParseObject) { + request.original = originalParseObject; + } + + if (triggerType === Types.beforeSave || triggerType === Types.afterSave || triggerType === Types.beforeDelete || triggerType === Types.afterDelete || triggerType === Types.afterFind) { + // Set a copy of the context on the request object. + request.context = Object.assign({}, context); + } + + if (!auth) { + return request; + } + + if (auth.isMaster) { + request['master'] = true; + } + + if (auth.user) { + request['user'] = auth.user; + } + + if (auth.installationId) { + request['installationId'] = auth.installationId; + } + + return request; +} + +function getRequestQueryObject(triggerType, auth, query, count, config, context, isGet) { + isGet = !!isGet; + var request = { + triggerName: triggerType, + query, + master: false, + count, + log: config.loggerController, + isGet, + headers: config.headers, + ip: config.ip, + context: context || {} + }; + + if (!auth) { + return request; + } + + if (auth.isMaster) { + request['master'] = true; + } + + if (auth.user) { + request['user'] = auth.user; + } + + if (auth.installationId) { + request['installationId'] = auth.installationId; + } + + return request; +} // Creates the response object, and uses the request object to pass data +// The API will call this with REST API formatted objects, this will +// transform them to Parse.Object instances expected by Cloud Code. +// Any changes made to the object in a beforeSave will be included. + + +function getResponseObject(request, resolve, reject) { + return { + success: function (response) { + if (request.triggerName === Types.afterFind) { + if (!response) { + response = request.objects; + } + + response = response.map(object => { + return object.toJSON(); + }); + return resolve(response); + } // Use the JSON response + + + if (response && typeof response === 'object' && !request.object.equals(response) && request.triggerName === Types.beforeSave) { + return resolve(response); + } + + if (response && typeof response === 'object' && request.triggerName === Types.afterSave) { + return resolve(response); + } + + if (request.triggerName === Types.afterSave) { + return resolve(); + } + + response = {}; + + if (request.triggerName === Types.beforeSave) { + response['object'] = request.object._getSaveJSON(); + } + + return resolve(response); + }, + error: function (error) { + const e = resolveError(error, { + code: _node.default.Error.SCRIPT_FAILED, + message: 'Script failed. Unknown error.' + }); + reject(e); + } + }; +} + +function userIdForLog(auth) { + return auth && auth.user ? auth.user.id : undefined; +} + +function logTriggerAfterHook(triggerType, className, input, auth) { + const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(input)); + + _logger.logger.info(`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}`, { + className, + triggerType, + user: userIdForLog(auth) + }); +} + +function logTriggerSuccessBeforeHook(triggerType, className, input, result, auth) { + const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(input)); + + const cleanResult = _logger.logger.truncateLogMessage(JSON.stringify(result)); + + _logger.logger.info(`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Result: ${cleanResult}`, { + className, + triggerType, + user: userIdForLog(auth) + }); +} + +function logTriggerErrorBeforeHook(triggerType, className, input, auth, error) { + const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(input)); + + _logger.logger.error(`${triggerType} failed for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Error: ${JSON.stringify(error)}`, { + className, + triggerType, + error, + user: userIdForLog(auth) + }); +} + +function maybeRunAfterFindTrigger(triggerType, auth, className, objects, config, query, context) { + return new Promise((resolve, reject) => { + const trigger = getTrigger(className, triggerType, config.applicationId); + + if (!trigger) { + return resolve(); + } + + const request = getRequestObject(triggerType, auth, null, null, config, context); + + if (query) { + request.query = query; + } + + const { + success, + error + } = getResponseObject(request, object => { + resolve(object); + }, error => { + reject(error); + }); + logTriggerSuccessBeforeHook(triggerType, className, 'AfterFind', JSON.stringify(objects), auth); + request.objects = objects.map(object => { + //setting the class name to transform into parse object + object.className = className; + return _node.default.Object.fromJSON(object); + }); + return Promise.resolve().then(() => { + return maybeRunValidator(request, `${triggerType}.${className}`); + }).then(() => { + if (request.skipWithMasterKey) { + return request.objects; + } + + const response = trigger(request); + + if (response && typeof response.then === 'function') { + return response.then(results => { + if (!results) { + throw new _node.default.Error(_node.default.Error.SCRIPT_FAILED, 'AfterFind expect results to be returned in the promise'); + } + + return results; + }); + } + + return response; + }).then(success, error); + }).then(results => { + logTriggerAfterHook(triggerType, className, JSON.stringify(results), auth); + return results; + }); +} + +function maybeRunQueryTrigger(triggerType, className, restWhere, restOptions, config, auth, context, isGet) { + const trigger = getTrigger(className, triggerType, config.applicationId); + + if (!trigger) { + return Promise.resolve({ + restWhere, + restOptions + }); + } + + const json = Object.assign({}, restOptions); + json.where = restWhere; + const parseQuery = new _node.default.Query(className); + parseQuery.withJSON(json); + let count = false; + + if (restOptions) { + count = !!restOptions.count; + } + + const requestObject = getRequestQueryObject(triggerType, auth, parseQuery, count, config, context, isGet); + return Promise.resolve().then(() => { + return maybeRunValidator(requestObject, `${triggerType}.${className}`); + }).then(() => { + if (requestObject.skipWithMasterKey) { + return requestObject.query; + } + + return trigger(requestObject); + }).then(result => { + let queryResult = parseQuery; + + if (result && result instanceof _node.default.Query) { + queryResult = result; + } + + const jsonQuery = queryResult.toJSON(); + + if (jsonQuery.where) { + restWhere = jsonQuery.where; + } + + if (jsonQuery.limit) { + restOptions = restOptions || {}; + restOptions.limit = jsonQuery.limit; + } + + if (jsonQuery.skip) { + restOptions = restOptions || {}; + restOptions.skip = jsonQuery.skip; + } + + if (jsonQuery.include) { + restOptions = restOptions || {}; + restOptions.include = jsonQuery.include; + } + + if (jsonQuery.excludeKeys) { + restOptions = restOptions || {}; + restOptions.excludeKeys = jsonQuery.excludeKeys; + } + + if (jsonQuery.explain) { + restOptions = restOptions || {}; + restOptions.explain = jsonQuery.explain; + } + + if (jsonQuery.keys) { + restOptions = restOptions || {}; + restOptions.keys = jsonQuery.keys; + } + + if (jsonQuery.order) { + restOptions = restOptions || {}; + restOptions.order = jsonQuery.order; + } + + if (jsonQuery.hint) { + restOptions = restOptions || {}; + restOptions.hint = jsonQuery.hint; + } + + if (requestObject.readPreference) { + restOptions = restOptions || {}; + restOptions.readPreference = requestObject.readPreference; + } + + if (requestObject.includeReadPreference) { + restOptions = restOptions || {}; + restOptions.includeReadPreference = requestObject.includeReadPreference; + } + + if (requestObject.subqueryReadPreference) { + restOptions = restOptions || {}; + restOptions.subqueryReadPreference = requestObject.subqueryReadPreference; + } + + return { + restWhere, + restOptions + }; + }, err => { + const error = resolveError(err, { + code: _node.default.Error.SCRIPT_FAILED, + message: 'Script failed. Unknown error.' + }); + throw error; + }); +} + +function resolveError(message, defaultOpts) { + if (!defaultOpts) { + defaultOpts = {}; + } + + if (!message) { + return new _node.default.Error(defaultOpts.code || _node.default.Error.SCRIPT_FAILED, defaultOpts.message || 'Script failed.'); + } + + if (message instanceof _node.default.Error) { + return message; + } + + const code = defaultOpts.code || _node.default.Error.SCRIPT_FAILED; // If it's an error, mark it as a script failed + + if (typeof message === 'string') { + return new _node.default.Error(code, message); + } + + const error = new _node.default.Error(code, message.message || message); + + if (message instanceof Error) { + error.stack = message.stack; + } + + return error; +} + +function maybeRunValidator(request, functionName) { + const theValidator = getValidator(functionName, _node.default.applicationId); + + if (!theValidator) { + return; + } + + if (typeof theValidator === 'object' && theValidator.skipWithMasterKey && request.master) { + request.skipWithMasterKey = true; + } + + return new Promise((resolve, reject) => { + return Promise.resolve().then(() => { + return typeof theValidator === 'object' ? builtInTriggerValidator(theValidator, request) : theValidator(request); + }).then(() => { + resolve(); + }).catch(e => { + const error = resolveError(e, { + code: _node.default.Error.VALIDATION_ERROR, + message: 'Validation failed.' + }); + reject(error); + }); + }); +} + +function builtInTriggerValidator(options, request) { + if (request.master && !options.validateMasterKey) { + return; + } + + let reqUser = request.user; + + if (!reqUser && request.object && request.object.className === '_User' && !request.object.existed()) { + reqUser = request.object; + } + + if (options.requireUser && !reqUser) { + throw 'Validation failed. Please login to continue.'; + } + + if (options.requireMaster && !request.master) { + throw 'Validation failed. Master key is required to complete this request.'; + } + + let params = request.params || {}; + + if (request.object) { + params = request.object.toJSON(); + } + + const requiredParam = key => { + const value = params[key]; + + if (value == null) { + throw `Validation failed. Please specify data for ${key}.`; + } + }; + + const validateOptions = (opt, key, val) => { + let opts = opt.options; + + if (typeof opts === 'function') { + try { + const result = opts(val); + + if (!result && result != null) { + throw opt.error || `Validation failed. Invalid value for ${key}.`; + } + } catch (e) { + if (!e) { + throw opt.error || `Validation failed. Invalid value for ${key}.`; + } + + throw opt.error || e.message || e; + } + + return; + } + + if (!Array.isArray(opts)) { + opts = [opt.options]; + } + + if (!opts.includes(val)) { + throw opt.error || `Validation failed. Invalid option for ${key}. Expected: ${opts.join(', ')}`; + } + }; + + const getType = fn => { + const match = fn && fn.toString().match(/^\s*function (\w+)/); + return (match ? match[1] : '').toLowerCase(); + }; + + if (Array.isArray(options.fields)) { + for (const key of options.fields) { + requiredParam(key); + } + } else { + for (const key in options.fields) { + const opt = options.fields[key]; + let val = params[key]; + + if (typeof opt === 'string') { + requiredParam(opt); + } + + if (typeof opt === 'object') { + if (opt.default != null && val == null) { + val = opt.default; + params[key] = val; + + if (request.object) { + request.object.set(key, val); + } + } + + if (opt.constant && request.object) { + if (request.original) { + request.object.set(key, request.original.get(key)); + } else if (opt.default != null) { + request.object.set(key, opt.default); + } + } + + if (opt.required) { + requiredParam(key); + } + + if (opt.type) { + const type = getType(opt.type); + + if (type == 'array' && !Array.isArray(val)) { + throw `Validation failed. Invalid type for ${key}. Expected: array`; + } else if (typeof val !== type) { + throw `Validation failed. Invalid type for ${key}. Expected: ${type}`; + } + } + + if (opt.options) { + validateOptions(opt, key, val); + } + } + } + } + + const userKeys = options.requireUserKeys || []; + + if (Array.isArray(userKeys)) { + for (const key of userKeys) { + if (!reqUser) { + throw 'Please login to make this request.'; + } + + if (reqUser.get(key) == null) { + throw `Validation failed. Please set data for ${key} on your account.`; + } + } + } else if (typeof userKeys === 'object') { + for (const key in options.requireUserKeys) { + const opt = options.requireUserKeys[key]; + + if (opt.options) { + validateOptions(opt, key, reqUser.get(key)); + } + } + } +} // To be used as part of the promise chain when saving/deleting an object +// Will resolve successfully if no trigger is configured +// Resolves to an object, empty or containing an object key. A beforeSave +// trigger will set the object key to the rest format object to save. +// originalParseObject is optional, we only need that for before/afterSave functions + + +function maybeRunTrigger(triggerType, auth, parseObject, originalParseObject, config, context) { + if (!parseObject) { + return Promise.resolve({}); + } + + return new Promise(function (resolve, reject) { + var trigger = getTrigger(parseObject.className, triggerType, config.applicationId); + if (!trigger) return resolve(); + var request = getRequestObject(triggerType, auth, parseObject, originalParseObject, config, context); + var { + success, + error + } = getResponseObject(request, object => { + logTriggerSuccessBeforeHook(triggerType, parseObject.className, parseObject.toJSON(), object, auth); + + if (triggerType === Types.beforeSave || triggerType === Types.afterSave || triggerType === Types.beforeDelete || triggerType === Types.afterDelete) { + Object.assign(context, request.context); + } + + resolve(object); + }, error => { + logTriggerErrorBeforeHook(triggerType, parseObject.className, parseObject.toJSON(), auth, error); + reject(error); + }); // AfterSave and afterDelete triggers can return a promise, which if they + // do, needs to be resolved before this promise is resolved, + // so trigger execution is synced with RestWrite.execute() call. + // If triggers do not return a promise, they can run async code parallel + // to the RestWrite.execute() call. + + return Promise.resolve().then(() => { + return maybeRunValidator(request, `${triggerType}.${parseObject.className}`); + }).then(() => { + if (request.skipWithMasterKey) { + return Promise.resolve(); + } + + const promise = trigger(request); + + if (triggerType === Types.afterSave || triggerType === Types.afterDelete || triggerType === Types.afterLogin) { + logTriggerAfterHook(triggerType, parseObject.className, parseObject.toJSON(), auth); + } // beforeSave is expected to return null (nothing) + + + if (triggerType === Types.beforeSave) { + if (promise && typeof promise.then === 'function') { + return promise.then(response => { + // response.object may come from express routing before hook + if (response && response.object) { + return response; + } + + return null; + }); + } + + return null; + } + + return promise; + }).then(success, error); + }); +} // Converts a REST-format object to a Parse.Object +// data is either className or an object + + +function inflate(data, restObject) { + var copy = typeof data == 'object' ? data : { + className: data + }; + + for (var key in restObject) { + copy[key] = restObject[key]; + } + + return _node.default.Object.fromJSON(copy); +} + +function runLiveQueryEventHandlers(data, applicationId = _node.default.applicationId) { + if (!_triggerStore || !_triggerStore[applicationId] || !_triggerStore[applicationId].LiveQuery) { + return; + } + + _triggerStore[applicationId].LiveQuery.forEach(handler => handler(data)); +} + +function getRequestFileObject(triggerType, auth, fileObject, config) { + const request = _objectSpread(_objectSpread({}, fileObject), {}, { + triggerName: triggerType, + master: false, + log: config.loggerController, + headers: config.headers, + ip: config.ip + }); + + if (!auth) { + return request; + } + + if (auth.isMaster) { + request['master'] = true; + } + + if (auth.user) { + request['user'] = auth.user; + } + + if (auth.installationId) { + request['installationId'] = auth.installationId; + } + + return request; +} + +async function maybeRunFileTrigger(triggerType, fileObject, config, auth) { + const fileTrigger = getFileTrigger(triggerType, config.applicationId); + + if (typeof fileTrigger === 'function') { + try { + const request = getRequestFileObject(triggerType, auth, fileObject, config); + await maybeRunValidator(request, `${triggerType}.${FileClassName}`); + + if (request.skipWithMasterKey) { + return fileObject; + } + + const result = await fileTrigger(request); + logTriggerSuccessBeforeHook(triggerType, 'Parse.File', _objectSpread(_objectSpread({}, fileObject.file.toJSON()), {}, { + fileSize: fileObject.fileSize + }), result, auth); + return result || fileObject; + } catch (error) { + logTriggerErrorBeforeHook(triggerType, 'Parse.File', _objectSpread(_objectSpread({}, fileObject.file.toJSON()), {}, { + fileSize: fileObject.fileSize + }), auth, error); + throw error; + } + } + + return fileObject; +} + +async function maybeRunConnectTrigger(triggerType, request) { + const trigger = getTrigger(ConnectClassName, triggerType, _node.default.applicationId); + + if (!trigger) { + return; + } + + request.user = await userForSessionToken(request.sessionToken); + await maybeRunValidator(request, `${triggerType}.${ConnectClassName}`); + + if (request.skipWithMasterKey) { + return; + } + + return trigger(request); +} + +async function maybeRunSubscribeTrigger(triggerType, className, request) { + const trigger = getTrigger(className, triggerType, _node.default.applicationId); + + if (!trigger) { + return; + } + + const parseQuery = new _node.default.Query(className); + parseQuery.withJSON(request.query); + request.query = parseQuery; + request.user = await userForSessionToken(request.sessionToken); + await maybeRunValidator(request, `${triggerType}.${className}`); + + if (request.skipWithMasterKey) { + return; + } + + await trigger(request); + const query = request.query.toJSON(); + + if (query.keys) { + query.fields = query.keys.split(','); + } + + request.query = query; +} + +async function maybeRunAfterEventTrigger(triggerType, className, request) { + const trigger = getTrigger(className, triggerType, _node.default.applicationId); + + if (!trigger) { + return; + } + + if (request.object) { + request.object = _node.default.Object.fromJSON(request.object); + } + + if (request.original) { + request.original = _node.default.Object.fromJSON(request.original); + } + + request.user = await userForSessionToken(request.sessionToken); + await maybeRunValidator(request, `${triggerType}.${className}`); + + if (request.skipWithMasterKey) { + return; + } + + return trigger(request); +} + +async function userForSessionToken(sessionToken) { + if (!sessionToken) { + return; + } + + const q = new _node.default.Query('_Session'); + q.equalTo('sessionToken', sessionToken); + q.include('user'); + const session = await q.first({ + useMasterKey: true + }); + + if (!session) { + return; + } + + return session.get('user'); +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy90cmlnZ2Vycy5qcyJdLCJuYW1lcyI6WyJUeXBlcyIsImJlZm9yZUxvZ2luIiwiYWZ0ZXJMb2dpbiIsImFmdGVyTG9nb3V0IiwiYmVmb3JlU2F2ZSIsImFmdGVyU2F2ZSIsImJlZm9yZURlbGV0ZSIsImFmdGVyRGVsZXRlIiwiYmVmb3JlRmluZCIsImFmdGVyRmluZCIsImJlZm9yZVNhdmVGaWxlIiwiYWZ0ZXJTYXZlRmlsZSIsImJlZm9yZURlbGV0ZUZpbGUiLCJhZnRlckRlbGV0ZUZpbGUiLCJiZWZvcmVDb25uZWN0IiwiYmVmb3JlU3Vic2NyaWJlIiwiYWZ0ZXJFdmVudCIsIkZpbGVDbGFzc05hbWUiLCJDb25uZWN0Q2xhc3NOYW1lIiwiYmFzZVN0b3JlIiwiVmFsaWRhdG9ycyIsIk9iamVjdCIsImtleXMiLCJyZWR1Y2UiLCJiYXNlIiwia2V5IiwiRnVuY3Rpb25zIiwiSm9icyIsIkxpdmVRdWVyeSIsIlRyaWdnZXJzIiwiZnJlZXplIiwidmFsaWRhdGVDbGFzc05hbWVGb3JUcmlnZ2VycyIsImNsYXNzTmFtZSIsInR5cGUiLCJfdHJpZ2dlclN0b3JlIiwiQ2F0ZWdvcnkiLCJnZXRTdG9yZSIsImNhdGVnb3J5IiwibmFtZSIsImFwcGxpY2F0aW9uSWQiLCJwYXRoIiwic3BsaXQiLCJzcGxpY2UiLCJQYXJzZSIsInN0b3JlIiwiY29tcG9uZW50IiwidW5kZWZpbmVkIiwiYWRkIiwiaGFuZGxlciIsImxhc3RDb21wb25lbnQiLCJsb2dnZXIiLCJ3YXJuIiwicmVtb3ZlIiwiZ2V0IiwiYWRkRnVuY3Rpb24iLCJmdW5jdGlvbk5hbWUiLCJ2YWxpZGF0aW9uSGFuZGxlciIsImFkZEpvYiIsImpvYk5hbWUiLCJhZGRUcmlnZ2VyIiwiYWRkRmlsZVRyaWdnZXIiLCJhZGRDb25uZWN0VHJpZ2dlciIsImFkZExpdmVRdWVyeUV2ZW50SGFuZGxlciIsInB1c2giLCJyZW1vdmVGdW5jdGlvbiIsInJlbW92ZVRyaWdnZXIiLCJfdW5yZWdpc3RlckFsbCIsImZvckVhY2giLCJhcHBJZCIsImdldFRyaWdnZXIiLCJ0cmlnZ2VyVHlwZSIsImdldEZpbGVUcmlnZ2VyIiwidHJpZ2dlckV4aXN0cyIsImdldEZ1bmN0aW9uIiwiZ2V0RnVuY3Rpb25OYW1lcyIsImZ1bmN0aW9uTmFtZXMiLCJleHRyYWN0RnVuY3Rpb25OYW1lcyIsIm5hbWVzcGFjZSIsInZhbHVlIiwiZ2V0Sm9iIiwiZ2V0Sm9icyIsIm1hbmFnZXIiLCJnZXRWYWxpZGF0b3IiLCJnZXRSZXF1ZXN0T2JqZWN0IiwiYXV0aCIsInBhcnNlT2JqZWN0Iiwib3JpZ2luYWxQYXJzZU9iamVjdCIsImNvbmZpZyIsImNvbnRleHQiLCJyZXF1ZXN0IiwidHJpZ2dlck5hbWUiLCJvYmplY3QiLCJtYXN0ZXIiLCJsb2ciLCJsb2dnZXJDb250cm9sbGVyIiwiaGVhZGVycyIsImlwIiwib3JpZ2luYWwiLCJhc3NpZ24iLCJpc01hc3RlciIsInVzZXIiLCJpbnN0YWxsYXRpb25JZCIsImdldFJlcXVlc3RRdWVyeU9iamVjdCIsInF1ZXJ5IiwiY291bnQiLCJpc0dldCIsImdldFJlc3BvbnNlT2JqZWN0IiwicmVzb2x2ZSIsInJlamVjdCIsInN1Y2Nlc3MiLCJyZXNwb25zZSIsIm9iamVjdHMiLCJtYXAiLCJ0b0pTT04iLCJlcXVhbHMiLCJfZ2V0U2F2ZUpTT04iLCJlcnJvciIsImUiLCJyZXNvbHZlRXJyb3IiLCJjb2RlIiwiRXJyb3IiLCJTQ1JJUFRfRkFJTEVEIiwibWVzc2FnZSIsInVzZXJJZEZvckxvZyIsImlkIiwibG9nVHJpZ2dlckFmdGVySG9vayIsImlucHV0IiwiY2xlYW5JbnB1dCIsInRydW5jYXRlTG9nTWVzc2FnZSIsIkpTT04iLCJzdHJpbmdpZnkiLCJpbmZvIiwibG9nVHJpZ2dlclN1Y2Nlc3NCZWZvcmVIb29rIiwicmVzdWx0IiwiY2xlYW5SZXN1bHQiLCJsb2dUcmlnZ2VyRXJyb3JCZWZvcmVIb29rIiwibWF5YmVSdW5BZnRlckZpbmRUcmlnZ2VyIiwiUHJvbWlzZSIsInRyaWdnZXIiLCJmcm9tSlNPTiIsInRoZW4iLCJtYXliZVJ1blZhbGlkYXRvciIsInNraXBXaXRoTWFzdGVyS2V5IiwicmVzdWx0cyIsIm1heWJlUnVuUXVlcnlUcmlnZ2VyIiwicmVzdFdoZXJlIiwicmVzdE9wdGlvbnMiLCJqc29uIiwid2hlcmUiLCJwYXJzZVF1ZXJ5IiwiUXVlcnkiLCJ3aXRoSlNPTiIsInJlcXVlc3RPYmplY3QiLCJxdWVyeVJlc3VsdCIsImpzb25RdWVyeSIsImxpbWl0Iiwic2tpcCIsImluY2x1ZGUiLCJleGNsdWRlS2V5cyIsImV4cGxhaW4iLCJvcmRlciIsImhpbnQiLCJyZWFkUHJlZmVyZW5jZSIsImluY2x1ZGVSZWFkUHJlZmVyZW5jZSIsInN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UiLCJlcnIiLCJkZWZhdWx0T3B0cyIsInN0YWNrIiwidGhlVmFsaWRhdG9yIiwiYnVpbHRJblRyaWdnZXJWYWxpZGF0b3IiLCJjYXRjaCIsIlZBTElEQVRJT05fRVJST1IiLCJvcHRpb25zIiwidmFsaWRhdGVNYXN0ZXJLZXkiLCJyZXFVc2VyIiwiZXhpc3RlZCIsInJlcXVpcmVVc2VyIiwicmVxdWlyZU1hc3RlciIsInBhcmFtcyIsInJlcXVpcmVkUGFyYW0iLCJ2YWxpZGF0ZU9wdGlvbnMiLCJvcHQiLCJ2YWwiLCJvcHRzIiwiQXJyYXkiLCJpc0FycmF5IiwiaW5jbHVkZXMiLCJqb2luIiwiZ2V0VHlwZSIsImZuIiwibWF0Y2giLCJ0b1N0cmluZyIsInRvTG93ZXJDYXNlIiwiZmllbGRzIiwiZGVmYXVsdCIsInNldCIsImNvbnN0YW50IiwicmVxdWlyZWQiLCJ1c2VyS2V5cyIsInJlcXVpcmVVc2VyS2V5cyIsIm1heWJlUnVuVHJpZ2dlciIsInByb21pc2UiLCJpbmZsYXRlIiwiZGF0YSIsInJlc3RPYmplY3QiLCJjb3B5IiwicnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyIsImdldFJlcXVlc3RGaWxlT2JqZWN0IiwiZmlsZU9iamVjdCIsIm1heWJlUnVuRmlsZVRyaWdnZXIiLCJmaWxlVHJpZ2dlciIsImZpbGUiLCJmaWxlU2l6ZSIsIm1heWJlUnVuQ29ubmVjdFRyaWdnZXIiLCJ1c2VyRm9yU2Vzc2lvblRva2VuIiwic2Vzc2lvblRva2VuIiwibWF5YmVSdW5TdWJzY3JpYmVUcmlnZ2VyIiwibWF5YmVSdW5BZnRlckV2ZW50VHJpZ2dlciIsInEiLCJlcXVhbFRvIiwic2Vzc2lvbiIsImZpcnN0IiwidXNlTWFzdGVyS2V5Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFDQTs7QUFDQTs7Ozs7Ozs7OztBQUVPLE1BQU1BLEtBQUssR0FBRztBQUNuQkMsRUFBQUEsV0FBVyxFQUFFLGFBRE07QUFFbkJDLEVBQUFBLFVBQVUsRUFBRSxZQUZPO0FBR25CQyxFQUFBQSxXQUFXLEVBQUUsYUFITTtBQUluQkMsRUFBQUEsVUFBVSxFQUFFLFlBSk87QUFLbkJDLEVBQUFBLFNBQVMsRUFBRSxXQUxRO0FBTW5CQyxFQUFBQSxZQUFZLEVBQUUsY0FOSztBQU9uQkMsRUFBQUEsV0FBVyxFQUFFLGFBUE07QUFRbkJDLEVBQUFBLFVBQVUsRUFBRSxZQVJPO0FBU25CQyxFQUFBQSxTQUFTLEVBQUUsV0FUUTtBQVVuQkMsRUFBQUEsY0FBYyxFQUFFLGdCQVZHO0FBV25CQyxFQUFBQSxhQUFhLEVBQUUsZUFYSTtBQVluQkMsRUFBQUEsZ0JBQWdCLEVBQUUsa0JBWkM7QUFhbkJDLEVBQUFBLGVBQWUsRUFBRSxpQkFiRTtBQWNuQkMsRUFBQUEsYUFBYSxFQUFFLGVBZEk7QUFlbkJDLEVBQUFBLGVBQWUsRUFBRSxpQkFmRTtBQWdCbkJDLEVBQUFBLFVBQVUsRUFBRTtBQWhCTyxDQUFkOztBQW1CUCxNQUFNQyxhQUFhLEdBQUcsT0FBdEI7QUFDQSxNQUFNQyxnQkFBZ0IsR0FBRyxVQUF6Qjs7QUFFQSxNQUFNQyxTQUFTLEdBQUcsWUFBWTtBQUM1QixRQUFNQyxVQUFVLEdBQUdDLE1BQU0sQ0FBQ0MsSUFBUCxDQUFZdEIsS0FBWixFQUFtQnVCLE1BQW5CLENBQTBCLFVBQVVDLElBQVYsRUFB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IjpbIi8vIHRyaWdnZXJzLmpzXG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuL2xvZ2dlcic7XG5cbmV4cG9ydCBjb25zdCBUeXBlcyA9IHtcbiAgYmVmb3JlTG9naW46ICdiZWZvcmVMb2dpbicsXG4gIGFmdGVyTG9naW46ICdhZnRlckxvZ2luJyxcbiAgYWZ0ZXJMb2dvdXQ6ICdhZnRlckxvZ291dCcsXG4gIGJlZm9yZVNhdmU6ICdiZWZvcmVTYXZlJyxcbiAgYWZ0ZXJTYXZlOiAnYWZ0ZXJTYXZlJyxcbiAgYmVmb3JlRGVsZXRlOiAnYmVmb3JlRGVsZXRlJyxcbiAgYWZ0ZXJEZWxldGU6ICdhZnRlckRlbGV0ZScsXG4gIGJlZm9yZUZpbmQ6ICdiZWZvcmVGaW5kJyxcbiAgYWZ0ZXJGaW5kOiAnYWZ0ZXJGaW5kJyxcbiAgYmVmb3JlU2F2ZUZpbGU6ICdiZWZvcmVTYXZlRmlsZScsXG4gIGFmdGVyU2F2ZUZpbGU6ICdhZnRlclNhdmVGaWxlJyxcbiAgYmVmb3JlRGVsZXRlRmlsZTogJ2JlZm9yZURlbGV0ZUZpbGUnLFxuICBhZnRlckRlbGV0ZUZpbGU6ICdhZnRlckRlbGV0ZUZpbGUnLFxuICBiZWZvcmVDb25uZWN0OiAnYmVmb3JlQ29ubmVjdCcsXG4gIGJlZm9yZVN1YnNjcmliZTogJ2JlZm9yZVN1YnNjcmliZScsXG4gIGFmdGVyRXZlbnQ6ICdhZnRlckV2ZW50Jyxcbn07XG5cbmNvbnN0IEZpbGVDbGFzc05hbWUgPSAnQEZpbGUnO1xuY29uc3QgQ29ubmVjdENsYXNzTmFtZSA9ICdAQ29ubmVjdCc7XG5cbmNvbnN0IGJhc2VTdG9yZSA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgVmFsaWRhdG9ycyA9IE9iamVjdC5rZXlzKFR5cGVzKS5yZWR1Y2UoZnVuY3Rpb24gKGJhc2UsIGtleSkge1xuICAgIGJhc2Vba2V5XSA9IHt9O1xuICAgIHJldHVybiBiYXNlO1xuICB9LCB7fSk7XG4gIGNvbnN0IEZ1bmN0aW9ucyA9IHt9O1xuICBjb25zdCBKb2JzID0ge307XG4gIGNvbnN0IExpdmVRdWVyeSA9IFtdO1xuICBjb25zdCBUcmlnZ2VycyA9IE9iamVjdC5rZXlzKFR5cGVzKS5yZWR1Y2UoZnVuY3Rpb24gKGJhc2UsIGtleSkge1xuICAgIGJhc2Vba2V5XSA9IHt9O1xuICAgIHJldHVybiBiYXNlO1xuICB9LCB7fSk7XG5cbiAgcmV0dXJuIE9iamVjdC5mcmVlemUoe1xuICAgIEZ1bmN0aW9ucyxcbiAgICBKb2JzLFxuICAgIFZhbGlkYXRvcnMsXG4gICAgVHJpZ2dlcnMsXG4gICAgTGl2ZVF1ZXJ5LFxuICB9KTtcbn07XG5cbmZ1bmN0aW9uIHZhbGlkYXRlQ2xhc3NOYW1lRm9yVHJpZ2dlcnMoY2xhc3NOYW1lLCB0eXBlKSB7XG4gIGlmICh0eXBlID09IFR5cGVzLmJlZm9yZVNhdmUgJiYgY2xhc3NOYW1lID09PSAnX1B1c2hTdGF0dXMnKSB7XG4gICAgLy8gX1B1c2hTdGF0dXMgdXNlcyB1bmRvY3VtZW50ZWQgbmVzdGVkIGtleSBpbmNyZW1lbnQgb3BzXG4gICAgLy8gYWxsb3dpbmcgYmVmb3JlU2F2ZSB3b3VsZCBtZXNzIHVwIHRoZSBvYmplY3RzIGJpZyB0aW1lXG4gICAgLy8gVE9ETzogQWxsb3cgcHJvcGVyIGRvY3VtZW50ZWQgd2F5IG9mIHVzaW5nIG5lc3RlZCBpbmNyZW1lbnQgb3BzXG4gICAgdGhyb3cgJ09ubHkgYWZ0ZXJTYXZlIGlzIGFsbG93ZWQgb24gX1B1c2hTdGF0dXMnO1xuICB9XG4gIGlmICgodHlwZSA9PT0gVHlwZXMuYmVmb3JlTG9naW4gfHwgdHlwZSA9PT0gVHlwZXMuYWZ0ZXJMb2dpbikgJiYgY2xhc3NOYW1lICE9PSAnX1VzZXInKSB7XG4gICAgLy8gVE9ETzogY2hlY2sgaWYgdXBzdHJlYW0gY29kZSB3aWxsIGhhbmRsZSBgRXJyb3JgIGluc3RhbmNlIHJhdGhlclxuICAgIC8vIHRoYW4gdGhpcyBhbnRpLXBhdHRlcm4gb2YgdGhyb3dpbmcgc3RyaW5nc1xuICAgIHRocm93ICdPbmx5IHRoZSBfVXNlciBjbGFzcyBpcyBhbGxvd2VkIGZvciB0aGUgYmVmb3JlTG9naW4gYW5kIGFmdGVyTG9naW4gdHJpZ2dlcnMnO1xuICB9XG4gIGlmICh0eXBlID09PSBUeXBlcy5hZnRlckxvZ291dCAmJiBjbGFzc05hbWUgIT09ICdfU2Vzc2lvbicpIHtcbiAgICAvLyBUT0RPOiBjaGVjayBpZiB1cHN0cmVhbSBjb2RlIHdpbGwgaGFuZGxlIGBFcnJvcmAgaW5zdGFuY2UgcmF0aGVyXG4gICAgLy8gdGhhbiB0aGlzIGFudGktcGF0dGVybiBvZiB0aHJvd2luZyBzdHJpbmdzXG4gICAgdGhyb3cgJ09ubHkgdGhlIF9TZXNzaW9uIGNsYXNzIGlzIGFsbG93ZWQgZm9yIHRoZSBhZnRlckxvZ291dCB0cmlnZ2VyLic7XG4gIH1cbiAgaWYgKGNsYXNzTmFtZSA9PT0gJ19TZXNzaW9uJyAmJiB0eXBlICE9PSBUeXBlcy5hZnRlckxvZ291dCkge1xuICAgIC8vIFRPRE86IGNoZWNrIGlmIHVwc3RyZWFtIGNvZGUgd2lsbCBoYW5kbGUgYEVycm9yYCBpbnN0YW5jZSByYXRoZXJcbiAgICAvLyB0aGFuIHRoaXMgYW50aS1wYXR0ZXJuIG9mIHRocm93aW5nIHN0cmluZ3NcbiAgICB0aHJvdyAnT25seSB0aGUgYWZ0ZXJMb2dvdXQgdHJpZ2dlciBpcyBhbGxvd2VkIGZvciB0aGUgX1Nlc3Npb24gY2xhc3MuJztcbiAgfVxuICByZXR1cm4gY2xhc3NOYW1lO1xufVxuXG5jb25zdCBfdHJpZ2dlclN0b3JlID0ge307XG5cbmNvbnN0IENhdGVnb3J5ID0ge1xuICBGdW5jdGlvbnM6ICdGdW5jdGlvbnMnLFxuICBWYWxpZGF0b3JzOiAnVmFsaWRhdG9ycycsXG4gIEpvYnM6ICdKb2JzJyxcbiAgVHJpZ2dlcnM6ICdUcmlnZ2VycycsXG59O1xuXG5mdW5jdGlvbiBnZXRTdG9yZShjYXRlZ29yeSwgbmFtZSwgYXBwbGljYXRpb25JZCkge1xuICBjb25zdCBwYXRoID0gbmFtZS5zcGxpdCgnLicpO1xuICBwYXRoLnNwbGljZSgtMSk7IC8vIHJlbW92ZSBsYXN0IGNvbXBvbmVudFxuICBhcHBsaWNhdGlvbklkID0gYXBwbGljYXRpb25JZCB8fCBQYXJzZS5hcHBsaWNhdGlvbklkO1xuICBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCBiYXNlU3RvcmUoKTtcbiAgbGV0IHN0b3JlID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXVtjYXRlZ29yeV07XG4gIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGgpIHtcbiAgICBzdG9yZSA9IHN0b3JlW2NvbXBvbmVudF07XG4gICAgaWYgKCFzdG9yZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0b3JlO1xufVxuXG5mdW5jdGlvbiBhZGQoY2F0ZWdvcnksIG5hbWUsIGhhbmRsZXIsIGFwcGxpY2F0aW9uSWQpIHtcbiAgY29uc3QgbGFzdENvbXBvbmVudCA9IG5hbWUuc3BsaXQoJy4nKS5zcGxpY2UoLTEpO1xuICBjb25zdCBzdG9yZSA9IGdldFN0b3JlKGNhdGVnb3J5LCBuYW1lLCBhcHBsaWNhdGlvbklkKTtcbiAgaWYgKHN0b3JlW2xhc3RDb21wb25lbnRdKSB7XG4gICAgbG9nZ2VyLndhcm4oXG4gICAgICBgV2FybmluZzogRHVwbGljYXRlIGNsb3VkIGZ1bmN0aW9ucyBleGlzdCBmb3IgJHtsYXN0Q29tcG9uZW50fS4gT25seSB0aGUgbGFzdCBvbmUgd2lsbCBiZSB1c2VkIGFuZCB0aGUgb3RoZXJzIHdpbGwgYmUgaWdub3JlZC5gXG4gICAgKTtcbiAgfVxuICBzdG9yZVtsYXN0Q29tcG9uZW50XSA9IGhhbmRsZXI7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZShjYXRlZ29yeSwgbmFtZSwgYXBwbGljYXRpb25JZCkge1xuICBjb25zdCBsYXN0Q29tcG9uZW50ID0gbmFtZS5zcGxpdCgnLicpLnNwbGljZSgtMSk7XG4gIGNvbnN0IHN0b3JlID0gZ2V0U3RvcmUoY2F0ZWdvcnksIG5hbWUsIGFwcGxpY2F0aW9uSWQpO1xuICBkZWxldGUgc3RvcmVbbGFzdENvbXBvbmVudF07XG59XG5cbmZ1bmN0aW9uIGdldChjYXRlZ29yeSwgbmFtZSwgYXBwbGljYXRpb25JZCkge1xuICBjb25zdCBsYXN0Q29tcG9uZW50ID0gbmFtZS5zcGxpdCgnLicpLnNwbGljZSgtMSk7XG4gIGNvbnN0IHN0b3JlID0gZ2V0U3RvcmUoY2F0ZWdvcnksIG5hbWUsIGFwcGxpY2F0aW9uSWQpO1xuICByZXR1cm4gc3RvcmVbbGFzdENvbXBvbmVudF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRGdW5jdGlvbihmdW5jdGlvbk5hbWUsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyLCBhcHBsaWNhdGlvbklkKSB7XG4gIGFkZChDYXRlZ29yeS5GdW5jdGlvbnMsIGZ1bmN0aW9uTmFtZSwgaGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG4gIGFkZChDYXRlZ29yeS5WYWxpZGF0b3JzLCBmdW5jdGlvbk5hbWUsIHZhbGlkYXRpb25IYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZEpvYihqb2JOYW1lLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKSB7XG4gIGFkZChDYXRlZ29yeS5Kb2JzLCBqb2JOYW1lLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFRyaWdnZXIodHlwZSwgY2xhc3NOYW1lLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB2YWxpZGF0ZUNsYXNzTmFtZUZvclRyaWdnZXJzKGNsYXNzTmFtZSwgdHlwZSk7XG4gIGFkZChDYXRlZ29yeS5UcmlnZ2VycywgYCR7dHlwZX0uJHtjbGFzc05hbWV9YCwgaGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG4gIGFkZChDYXRlZ29yeS5WYWxpZGF0b3JzLCBgJHt0eXBlfS4ke2NsYXNzTmFtZX1gLCB2YWxpZGF0aW9uSGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRGaWxlVHJpZ2dlcih0eXBlLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICBhZGQoQ2F0ZWdvcnkuVHJpZ2dlcnMsIGAke3R5cGV9LiR7RmlsZUNsYXNzTmFtZX1gLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbiAgYWRkKENhdGVnb3J5LlZhbGlkYXRvcnMsIGAke3R5cGV9LiR7RmlsZUNsYXNzTmFtZX1gLCB2YWxpZGF0aW9uSGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRDb25uZWN0VHJpZ2dlcih0eXBlLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICBhZGQoQ2F0ZWdvcnkuVHJpZ2dlcnMsIGAke3R5cGV9LiR7Q29ubmVjdENsYXNzTmFtZX1gLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbiAgYWRkKENhdGVnb3J5LlZhbGlkYXRvcnMsIGAke3R5cGV9LiR7Q29ubmVjdENsYXNzTmFtZX1gLCB2YWxpZGF0aW9uSGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRMaXZlUXVlcnlFdmVudEhhbmRsZXIoaGFuZGxlciwgYXBwbGljYXRpb25JZCkge1xuICBhcHBsaWNhdGlvbklkID0gYXBwbGljYXRpb25JZCB8fCBQYXJzZS5hcHBsaWNhdGlvbklkO1xuICBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCBiYXNlU3RvcmUoKTtcbiAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5MaXZlUXVlcnkucHVzaChoYW5kbGVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICByZW1vdmUoQ2F0ZWdvcnkuRnVuY3Rpb25zLCBmdW5jdGlvbk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlVHJpZ2dlcih0eXBlLCBjbGFzc05hbWUsIGFwcGxpY2F0aW9uSWQpIHtcbiAgcmVtb3ZlKENhdGVnb3J5LlRyaWdnZXJzLCBgJHt0eXBlfS4ke2NsYXNzTmFtZX1gLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF91bnJlZ2lzdGVyQWxsKCkge1xuICBPYmplY3Qua2V5cyhfdHJpZ2dlclN0b3JlKS5mb3JFYWNoKGFwcElkID0+IGRlbGV0ZSBfdHJpZ2dlclN0b3JlW2FwcElkXSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHJpZ2dlclR5cGUsIGFwcGxpY2F0aW9uSWQpIHtcbiAgaWYgKCFhcHBsaWNhdGlvbklkKSB7XG4gICAgdGhyb3cgJ01pc3NpbmcgQXBwbGljYXRpb25JRCc7XG4gIH1cbiAgcmV0dXJuIGdldChDYXRlZ29yeS5UcmlnZ2VycywgYCR7dHJpZ2dlclR5cGV9LiR7Y2xhc3NOYW1lfWAsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmlsZVRyaWdnZXIodHlwZSwgYXBwbGljYXRpb25JZCkge1xuICByZXR1cm4gZ2V0VHJpZ2dlcihGaWxlQ2xhc3NOYW1lLCB0eXBlLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRyaWdnZXJFeGlzdHMoY2xhc3NOYW1lOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgYXBwbGljYXRpb25JZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHlwZSwgYXBwbGljYXRpb25JZCkgIT0gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RnVuY3Rpb24oZnVuY3Rpb25OYW1lLCBhcHBsaWNhdGlvbklkKSB7XG4gIHJldHVybiBnZXQoQ2F0ZWdvcnkuRnVuY3Rpb25zLCBmdW5jdGlvbk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RnVuY3Rpb25OYW1lcyhhcHBsaWNhdGlvbklkKSB7XG4gIGNvbnN0IHN0b3JlID1cbiAgICAoX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSAmJiBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdW0NhdGVnb3J5LkZ1bmN0aW9uc10pIHx8IHt9O1xuICBjb25zdCBmdW5jdGlvbk5hbWVzID0gW107XG4gIGNvbnN0IGV4dHJhY3RGdW5jdGlvbk5hbWVzID0gKG5hbWVzcGFjZSwgc3RvcmUpID0+IHtcbiAgICBPYmplY3Qua2V5cyhzdG9yZSkuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gc3RvcmVbbmFtZV07XG4gICAgICBpZiAobmFtZXNwYWNlKSB7XG4gICAgICAgIG5hbWUgPSBgJHtuYW1lc3BhY2V9LiR7bmFtZX1gO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmdW5jdGlvbk5hbWVzLnB1c2gobmFtZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleHRyYWN0RnVuY3Rpb25OYW1lcyhuYW1lLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG4gIGV4dHJhY3RGdW5jdGlvbk5hbWVzKG51bGwsIHN0b3JlKTtcbiAgcmV0dXJuIGZ1bmN0aW9uTmFtZXM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRKb2Ioam9iTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICByZXR1cm4gZ2V0KENhdGVnb3J5LkpvYnMsIGpvYk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Sm9icyhhcHBsaWNhdGlvbklkKSB7XG4gIHZhciBtYW5hZ2VyID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXTtcbiAgaWYgKG1hbmFnZXIgJiYgbWFuYWdlci5Kb2JzKSB7XG4gICAgcmV0dXJuIG1hbmFnZXIuSm9icztcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmFsaWRhdG9yKGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICByZXR1cm4gZ2V0KENhdGVnb3J5LlZhbGlkYXRvcnMsIGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXF1ZXN0T2JqZWN0KFxuICB0cmlnZ2VyVHlwZSxcbiAgYXV0aCxcbiAgcGFyc2VPYmplY3QsXG4gIG9yaWdpbmFsUGFyc2VPYmplY3QsXG4gIGNvbmZpZyxcbiAgY29udGV4dFxuKSB7XG4gIGNvbnN0IHJlcXVlc3QgPSB7XG4gICAgdHJpZ2dlck5hbWU6IHRyaWdnZXJUeXBlLFxuICAgIG9iamVjdDogcGFyc2VPYmplY3QsXG4gICAgbWFzdGVyOiBmYWxzZSxcbiAgICBsb2c6IGNvbmZpZy5sb2dnZXJDb250cm9sbGVyLFxuICAgIGhlYWRlcnM6IGNvbmZpZy5oZWFkZXJzLFxuICAgIGlwOiBjb25maWcuaXAsXG4gIH07XG5cbiAgaWYgKG9yaWdpbmFsUGFyc2VPYmplY3QpIHtcbiAgICByZXF1ZXN0Lm9yaWdpbmFsID0gb3JpZ2luYWxQYXJzZU9iamVjdDtcbiAgfVxuICBpZiAoXG4gICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmJlZm9yZVNhdmUgfHxcbiAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYWZ0ZXJTYXZlIHx8XG4gICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmJlZm9yZURlbGV0ZSB8fFxuICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlckRlbGV0ZSB8fFxuICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlckZpbmRcbiAgKSB7XG4gICAgLy8gU2V0IGEgY29weSBvZiB0aGUgY29udGV4dCBvbiB0aGUgcmVxdWVzdCBvYmplY3QuXG4gICAgcmVxdWVzdC5jb250ZXh0ID0gT2JqZWN0LmFzc2lnbih7fSwgY29udGV4dCk7XG4gIH1cblxuICBpZiAoIWF1dGgpIHtcbiAgICByZXR1cm4gcmVxdWVzdDtcbiAgfVxuICBpZiAoYXV0aC5pc01hc3Rlcikge1xuICAgIHJlcXVlc3RbJ21hc3RlciddID0gdHJ1ZTtcbiAgfVxuICBpZiAoYXV0aC51c2VyKSB7XG4gICAgcmVxdWVzdFsndXNlciddID0gYXV0aC51c2VyO1xuICB9XG4gIGlmIChhdXRoLmluc3RhbGxhdGlvbklkKSB7XG4gICAgcmVxdWVzdFsnaW5zdGFsbGF0aW9uSWQnXSA9IGF1dGguaW5zdGFsbGF0aW9uSWQ7XG4gIH1cbiAgcmV0dXJuIHJlcXVlc3Q7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXF1ZXN0UXVlcnlPYmplY3QodHJpZ2dlclR5cGUsIGF1dGgsIHF1ZXJ5LCBjb3VudCwgY29uZmlnLCBjb250ZXh0LCBpc0dldCkge1xuICBpc0dldCA9ICEhaXNHZXQ7XG5cbiAgdmFyIHJlcXVlc3QgPSB7XG4gICAgdHJpZ2dlck5hbWU6IHRyaWdnZXJUeXBlLFxuICAgIHF1ZXJ5LFxuICAgIG1hc3RlcjogZmFsc2UsXG4gICAgY291bnQsXG4gICAgbG9nOiBjb25maWcubG9nZ2VyQ29udHJvbGxlcixcbiAgICBpc0dldCxcbiAgICBoZWFkZXJzOiBjb25maWcuaGVhZGVycyxcbiAgICBpcDogY29uZmlnLmlwLFxuICAgIGNvbnRleHQ6IGNvbnRleHQgfHwge30sXG4gIH07XG5cbiAgaWYgKCFhdXRoKSB7XG4gICAgcmV0dXJuIHJlcXVlc3Q7XG4gIH1cbiAgaWYgKGF1dGguaXNNYXN0ZXIpIHtcbiAgICByZXF1ZXN0WydtYXN0ZXInXSA9IHRydWU7XG4gIH1cbiAgaWYgKGF1dGgudXNlcikge1xuICAgIHJlcXVlc3RbJ3VzZXInXSA9IGF1dGgudXNlcjtcbiAgfVxuICBpZiAoYXV0aC5pbnN0YWxsYXRpb25JZCkge1xuICAgIHJlcXVlc3RbJ2luc3RhbGxhdGlvbklkJ10gPSBhdXRoLmluc3RhbGxhdGlvbklkO1xuICB9XG4gIHJldHVybiByZXF1ZXN0O1xufVxuXG4vLyBDcmVhdGVzIHRoZSByZXNwb25zZSBvYmplY3QsIGFuZCB1c2VzIHRoZSByZXF1ZXN0IG9iamVjdCB0byBwYXNzIGRhdGFcbi8vIFRoZSBBUEkgd2lsbCBjYWxsIHRoaXMgd2l0aCBSRVNUIEFQSSBmb3JtYXR0ZWQgb2JqZWN0cywgdGhpcyB3aWxsXG4vLyB0cmFuc2Zvcm0gdGhlbSB0byBQYXJzZS5PYmplY3QgaW5zdGFuY2VzIGV4cGVjdGVkIGJ5IENsb3VkIENvZGUuXG4vLyBBbnkgY2hhbmdlcyBtYWRlIHRvIHRoZSBvYmplY3QgaW4gYSBiZWZvcmVTYXZlIHdpbGwgYmUgaW5jbHVkZWQuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVzcG9uc2VPYmplY3QocmVxdWVzdCwgcmVzb2x2ZSwgcmVqZWN0KSB7XG4gIHJldHVybiB7XG4gICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICBpZiAocmVxdWVzdC50cmlnZ2VyTmFtZSA9PT0gVHlwZXMuYWZ0ZXJGaW5kKSB7XG4gICAgICAgIGlmICghcmVzcG9uc2UpIHtcbiAgICAgICAgICByZXNwb25zZSA9IHJlcXVlc3Qub2JqZWN0cztcbiAgICAgICAgfVxuICAgICAgICByZXNwb25zZSA9IHJlc3BvbnNlLm1hcChvYmplY3QgPT4ge1xuICAgICAgICAgIHJldHVybiBvYmplY3QudG9KU09OKCk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcmVzb2x2ZShyZXNwb25zZSk7XG4gICAgICB9XG4gICAgICAvLyBVc2UgdGhlIEpTT04gcmVzcG9uc2VcbiAgICAgIGlmIChcbiAgICAgICAgcmVzcG9uc2UgJiZcbiAgICAgICAgdHlwZW9mIHJlc3BvbnNlID09PSAnb2JqZWN0JyAmJlxuICAgICAgICAhcmVxdWVzdC5vYmplY3QuZXF1YWxzKHJlc3BvbnNlKSAmJlxuICAgICAgICByZXF1ZXN0LnRyaWdnZXJOYW1lID09PSBUeXBlcy5iZWZvcmVTYXZlXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgfVxuICAgICAgaWYgKHJlc3BvbnNlICYmIHR5cGVvZiByZXNwb25zZSA9PT0gJ29iamVjdCcgJiYgcmVxdWVzdC50cmlnZ2VyTmFtZSA9PT0gVHlwZXMuYWZ0ZXJTYXZlKSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICAgIH1cbiAgICAgIGlmIChyZXF1ZXN0LnRyaWdnZXJOYW1lID09PSBUeXBlcy5hZnRlclNhdmUpIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgIH1cbiAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICBpZiAocmVxdWVzdC50cmlnZ2VyTmFtZSA9PT0gVHlwZXMuYmVmb3JlU2F2ZSkge1xuICAgICAgICByZXNwb25zZVsnb2JqZWN0J10gPSByZXF1ZXN0Lm9iamVjdC5fZ2V0U2F2ZUpTT04oKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICB9LFxuICAgIGVycm9yOiBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIGNvbnN0IGUgPSByZXNvbHZlRXJyb3IoZXJyb3IsIHtcbiAgICAgICAgY29kZTogUGFyc2UuRXJyb3IuU0NSSVBUX0ZBSUxFRCxcbiAgICAgICAgbWVzc2FnZTogJ1NjcmlwdCBmYWlsZWQuIFVua25vd24gZXJyb3IuJyxcbiAgICAgIH0pO1xuICAgICAgcmVqZWN0KGUpO1xuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIHVzZXJJZEZvckxvZyhhdXRoKSB7XG4gIHJldHVybiBhdXRoICYmIGF1dGgudXNlciA/IGF1dGgudXNlci5pZCA6IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gbG9nVHJpZ2dlckFmdGVySG9vayh0cmlnZ2VyVHlwZSwgY2xhc3NOYW1lLCBpbnB1dCwgYXV0aCkge1xuICBjb25zdCBjbGVhbklucHV0ID0gbG9nZ2VyLnRydW5jYXRlTG9nTWVzc2FnZShKU09OLnN0cmluZ2lmeShpbnB1dCkpO1xuICBsb2dnZXIuaW5mbyhcbiAgICBgJHt0cmlnZ2VyVHlwZX0gdHJpZ2dlcmVkIGZvciAke2NsYXNzTmFtZX0gZm9yIHVzZXIgJHt1c2VySWRGb3JMb2coXG4gICAgICBhdXRoXG4gICAgKX06XFxuICBJbnB1dDogJHtjbGVhbklucHV0fWAsXG4gICAge1xuICAgICAgY2xhc3NOYW1lLFxuICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICB1c2VyOiB1c2VySWRGb3JMb2coYXV0aCksXG4gICAgfVxuICApO1xufVxuXG5mdW5jdGlvbiBsb2dUcmlnZ2VyU3VjY2Vzc0JlZm9yZUhvb2sodHJpZ2dlclR5cGUsIGNsYXNzTmFtZSwgaW5wdXQsIHJlc3VsdCwgYXV0aCkge1xuICBjb25zdCBjbGVhbklucHV0ID0gbG9nZ2VyLnRydW5jYXRlTG9nTWVzc2FnZShKU09OLnN0cmluZ2lmeShpbnB1dCkpO1xuICBjb25zdCBjbGVhblJlc3VsdCA9IGxvZ2dlci50cnVuY2F0ZUxvZ01lc3NhZ2UoSlNPTi5zdHJpbmdpZnkocmVzdWx0KSk7XG4gIGxvZ2dlci5pbmZvKFxuICAgIGAke3RyaWdnZXJUeXBlfSB0cmlnZ2VyZWQgZm9yICR7Y2xhc3NOYW1lfSBmb3IgdXNlciAke3VzZXJJZEZvckxvZyhcbiAgICAgIGF1dGhcbiAgICApfTpcXG4gIElucHV0OiAke2NsZWFuSW5wdXR9XFxuICBSZXN1bHQ6ICR7Y2xlYW5SZXN1bHR9YCxcbiAgICB7XG4gICAgICBjbGFzc05hbWUsXG4gICAgICB0cmlnZ2VyVHlwZSxcbiAgICAgIHVzZXI6IHVzZXJJZEZvckxvZyhhdXRoKSxcbiAgICB9XG4gICk7XG59XG5cbmZ1bmN0aW9uIGxvZ1RyaWdnZXJFcnJvckJlZm9yZUhvb2sodHJpZ2dlclR5cGUsIGNsYXNzTmFtZSwgaW5wdXQsIGF1dGgsIGVycm9yKSB7XG4gIGNvbnN0IGNsZWFuSW5wdXQgPSBsb2dnZXIudHJ1bmNhdGVMb2dNZXNzYWdlKEpTT04uc3RyaW5naWZ5KGlucHV0KSk7XG4gIGxvZ2dlci5lcnJvcihcbiAgICBgJHt0cmlnZ2VyVHlwZX0gZmFpbGVkIGZvciAke2NsYXNzTmFtZX0gZm9yIHVzZXIgJHt1c2VySWRGb3JMb2coXG4gICAgICBhdXRoXG4gICAgKX06XFxuICBJbnB1dDogJHtjbGVhbklucHV0fVxcbiAgRXJyb3I6ICR7SlNPTi5zdHJpbmdpZnkoZXJyb3IpfWAsXG4gICAge1xuICAgICAgY2xhc3NOYW1lLFxuICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICBlcnJvcixcbiAgICAgIHVzZXI6IHVzZXJJZEZvckxvZyhhdXRoKSxcbiAgICB9XG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtYXliZVJ1bkFmdGVyRmluZFRyaWdnZXIoXG4gIHRyaWdnZXJUeXBlLFxuICBhdXRoLFxuICBjbGFzc05hbWUsXG4gIG9iamVjdHMsXG4gIGNvbmZpZyxcbiAgcXVlcnksXG4gIGNvbnRleHRcbikge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHRyaWdnZXIgPSBnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHJpZ2dlclR5cGUsIGNvbmZpZy5hcHBsaWNhdGlvbklkKTtcbiAgICBpZiAoIXRyaWdnZXIpIHtcbiAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgfVxuICAgIGNvbnN0IHJlcXVlc3QgPSBnZXRSZXF1ZXN0T2JqZWN0KHRyaWdnZXJUeXBlLCBhdXRoLCBudWxsLCBudWxsLCBjb25maWcsIGNvbnRleHQpO1xuICAgIGlmIChxdWVyeSkge1xuICAgICAgcmVxdWVzdC5xdWVyeSA9IHF1ZXJ5O1xuICAgIH1cbiAgICBjb25zdCB7IHN1Y2Nlc3MsIGVycm9yIH0gPSBnZXRSZXNwb25zZU9iamVjdChcbiAgICAgIHJlcXVlc3QsXG4gICAgICBvYmplY3QgPT4ge1xuICAgICAgICByZXNvbHZlKG9iamVjdCk7XG4gICAgICB9LFxuICAgICAgZXJyb3IgPT4ge1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfVxuICAgICk7XG4gICAgbG9nVHJpZ2dlclN1Y2Nlc3NCZWZvcmVIb29rKHRyaWdnZXJUeXBlLCBjbGFzc05hbWUsICdBZnRlckZpbmQnLCBKU09OLnN0cmluZ2lmeShvYmplY3RzKSwgYXV0aCk7XG4gICAgcmVxdWVzdC5vYmplY3RzID0gb2JqZWN0cy5tYXAob2JqZWN0ID0+IHtcbiAgICAgIC8vc2V0dGluZyB0aGUgY2xhc3MgbmFtZSB0byB0cmFuc2Zvcm0gaW50byBwYXJzZSBvYmplY3RcbiAgICAgIG9iamVjdC5jbGFzc05hbWUgPSBjbGFzc05hbWU7XG4gICAgICByZXR1cm4gUGFyc2UuT2JqZWN0LmZyb21KU09OKG9iamVjdCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiBtYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0LCBgJHt0cmlnZ2VyVHlwZX0uJHtjbGFzc05hbWV9YCk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBpZiAocmVxdWVzdC5za2lwV2l0aE1hc3RlcktleSkge1xuICAgICAgICAgIHJldHVybiByZXF1ZXN0Lm9iamVjdHM7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSB0cmlnZ2VyKHJlcXVlc3QpO1xuICAgICAgICBpZiAocmVzcG9uc2UgJiYgdHlwZW9mIHJlc3BvbnNlLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICByZXR1cm4gcmVzcG9uc2UudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgICAgIGlmICghcmVzdWx0cykge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuU0NSSVBUX0ZBSUxFRCxcbiAgICAgICAgICAgICAgICAnQWZ0ZXJGaW5kIGV4cGVjdCByZXN1bHRzIHRvIGJlIHJldHVybmVkIGluIHRoZSBwcm9taXNlJ1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgfSlcbiAgICAgIC50aGVuKHN1Y2Nlc3MsIGVycm9yKTtcbiAgfSkudGhlbihyZXN1bHRzID0+IHtcbiAgICBsb2dUcmlnZ2VyQWZ0ZXJIb29rKHRyaWdnZXJUeXBlLCBjbGFzc05hbWUsIEpTT04uc3RyaW5naWZ5KHJlc3VsdHMpLCBhdXRoKTtcbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtYXliZVJ1blF1ZXJ5VHJpZ2dlcihcbiAgdHJpZ2dlclR5cGUsXG4gIGNsYXNzTmFtZSxcbiAgcmVzdFdoZXJlLFxuICByZXN0T3B0aW9ucyxcbiAgY29uZmlnLFxuICBhdXRoLFxuICBjb250ZXh0LFxuICBpc0dldFxuKSB7XG4gIGNvbnN0IHRyaWdnZXIgPSBnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHJpZ2dlclR5cGUsIGNvbmZpZy5hcHBsaWNhdGlvbklkKTtcbiAgaWYgKCF0cmlnZ2VyKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICByZXN0V2hlcmUsXG4gICAgICByZXN0T3B0aW9ucyxcbiAgICB9KTtcbiAgfVxuICBjb25zdCBqc29uID0gT2JqZWN0LmFzc2lnbih7fSwgcmVzdE9wdGlvbnMpO1xuICBqc29uLndoZXJlID0gcmVzdFdoZXJlO1xuXG4gIGNvbnN0IHBhcnNlUXVlcnkgPSBuZXcgUGFyc2UuUXVlcnkoY2xhc3NOYW1lKTtcbiAgcGFyc2VRdWVyeS53aXRoSlNPTihqc29uKTtcblxuICBsZXQgY291bnQgPSBmYWxzZTtcbiAgaWYgKHJlc3RPcHRpb25zKSB7XG4gICAgY291bnQgPSAhIXJlc3RPcHRpb25zLmNvdW50O1xuICB9XG4gIGNvbnN0IHJlcXVlc3RPYmplY3QgPSBnZXRSZXF1ZXN0UXVlcnlPYmplY3QoXG4gICAgdHJpZ2dlclR5cGUsXG4gICAgYXV0aCxcbiAgICBwYXJzZVF1ZXJ5LFxuICAgIGNvdW50LFxuICAgIGNvbmZpZyxcbiAgICBjb250ZXh0LFxuICAgIGlzR2V0XG4gICk7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiBtYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0T2JqZWN0LCBgJHt0cmlnZ2VyVHlwZX0uJHtjbGFzc05hbWV9YCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICBpZiAocmVxdWVzdE9iamVjdC5za2lwV2l0aE1hc3RlcktleSkge1xuICAgICAgICByZXR1cm4gcmVxdWVzdE9iamVjdC5xdWVyeTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cmlnZ2VyKHJlcXVlc3RPYmplY3QpO1xuICAgIH0pXG4gICAgLnRoZW4oXG4gICAgICByZXN1bHQgPT4ge1xuICAgICAgICBsZXQgcXVlcnlSZXN1bHQgPSBwYXJzZVF1ZXJ5O1xuICAgICAgICBpZiAocmVzdWx0ICYmIHJlc3VsdCBpbnN0YW5jZW9mIFBhcnNlLlF1ZXJ5KSB7XG4gICAgICAgICAgcXVlcnlSZXN1bHQgPSByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QganNvblF1ZXJ5ID0gcXVlcnlSZXN1bHQudG9KU09OKCk7XG4gICAgICAgIGlmIChqc29uUXVlcnkud2hlcmUpIHtcbiAgICAgICAgICByZXN0V2hlcmUgPSBqc29uUXVlcnkud2hlcmU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGpzb25RdWVyeS5saW1pdCkge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMubGltaXQgPSBqc29uUXVlcnkubGltaXQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGpzb25RdWVyeS5za2lwKSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5za2lwID0ganNvblF1ZXJ5LnNraXA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGpzb25RdWVyeS5pbmNsdWRlKSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5pbmNsdWRlID0ganNvblF1ZXJ5LmluY2x1ZGU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGpzb25RdWVyeS5leGNsdWRlS2V5cykge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMuZXhjbHVkZUtleXMgPSBqc29uUXVlcnkuZXhjbHVkZUtleXM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGpzb25RdWVyeS5leHBsYWluKSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5leHBsYWluID0ganNvblF1ZXJ5LmV4cGxhaW47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGpzb25RdWVyeS5rZXlzKSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5rZXlzID0ganNvblF1ZXJ5LmtleXM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGpzb25RdWVyeS5vcmRlcikge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMub3JkZXIgPSBqc29uUXVlcnkub3JkZXI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGpzb25RdWVyeS5oaW50KSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5oaW50ID0ganNvblF1ZXJ5LmhpbnQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlcXVlc3RPYmplY3QucmVhZFByZWZlcmVuY2UpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gcmVxdWVzdE9iamVjdC5yZWFkUHJlZmVyZW5jZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVxdWVzdE9iamVjdC5pbmNsdWRlUmVhZFByZWZlcmVuY2UpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLmluY2x1ZGVSZWFkUHJlZmVyZW5jZSA9IHJlcXVlc3RPYmplY3QuaW5jbHVkZVJlYWRQcmVmZXJlbmNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXF1ZXN0T2JqZWN0LnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UgPSByZXF1ZXN0T2JqZWN0LnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICByZXN0V2hlcmUsXG4gICAgICAgICAgcmVzdE9wdGlvbnMsXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgICAgZXJyID0+IHtcbiAgICAgICAgY29uc3QgZXJyb3IgPSByZXNvbHZlRXJyb3IoZXJyLCB7XG4gICAgICAgICAgY29kZTogUGFyc2UuRXJyb3IuU0NSSVBUX0ZBSUxFRCxcbiAgICAgICAgICBtZXNzYWdlOiAnU2NyaXB0IGZhaWxlZC4gVW5rbm93biBlcnJvci4nLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVFcnJvcihtZXNzYWdlLCBkZWZhdWx0T3B0cykge1xuICBpZiAoIWRlZmF1bHRPcHRzKSB7XG4gICAgZGVmYXVsdE9wdHMgPSB7fTtcbiAgfVxuICBpZiAoIW1lc3NhZ2UpIHtcbiAgICByZXR1cm4gbmV3IFBhcnNlLkVycm9yKFxuICAgICAgZGVmYXVsdE9wdHMuY29kZSB8fCBQYXJzZS5FcnJvci5TQ1JJUFRfRkFJTEVELFxuICAgICAgZGVmYXVsdE9wdHMubWVzc2FnZSB8fCAnU2NyaXB0IGZhaWxlZC4nXG4gICAgKTtcbiAgfVxuICBpZiAobWVzc2FnZSBpbnN0YW5jZW9mIFBhcnNlLkVycm9yKSB7XG4gICAgcmV0dXJuIG1lc3NhZ2U7XG4gIH1cblxuICBjb25zdCBjb2RlID0gZGVmYXVsdE9wdHMuY29kZSB8fCBQYXJzZS5FcnJvci5TQ1JJUFRfRkFJTEVEO1xuICAvLyBJZiBpdCdzIGFuIGVycm9yLCBtYXJrIGl0IGFzIGEgc2NyaXB0IGZhaWxlZFxuICBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIG5ldyBQYXJzZS5FcnJvcihjb2RlLCBtZXNzYWdlKTtcbiAgfVxuICBjb25zdCBlcnJvciA9IG5ldyBQYXJzZS5FcnJvcihjb2RlLCBtZXNzYWdlLm1lc3NhZ2UgfHwgbWVzc2FnZSk7XG4gIGlmIChtZXNzYWdlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICBlcnJvci5zdGFjayA9IG1lc3NhZ2Uuc3RhY2s7XG4gIH1cbiAgcmV0dXJuIGVycm9yO1xufVxuZXhwb3J0IGZ1bmN0aW9uIG1heWJlUnVuVmFsaWRhdG9yKHJlcXVlc3QsIGZ1bmN0aW9uTmFtZSkge1xuICBjb25zdCB0aGVWYWxpZGF0b3IgPSBnZXRWYWxpZGF0b3IoZnVuY3Rpb25OYW1lLCBQYXJzZS5hcHBsaWNhdGlvbklkKTtcbiAgaWYgKCF0aGVWYWxpZGF0b3IpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHR5cGVvZiB0aGVWYWxpZGF0b3IgPT09ICdvYmplY3QnICYmIHRoZVZhbGlkYXRvci5za2lwV2l0aE1hc3RlcktleSAmJiByZXF1ZXN0Lm1hc3Rlcikge1xuICAgIHJlcXVlc3Quc2tpcFdpdGhNYXN0ZXJLZXkgPSB0cnVlO1xuICB9XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdGhlVmFsaWRhdG9yID09PSAnb2JqZWN0J1xuICAgICAgICAgID8gYnVpbHRJblRyaWdnZXJWYWxpZGF0b3IodGhlVmFsaWRhdG9yLCByZXF1ZXN0KVxuICAgICAgICAgIDogdGhlVmFsaWRhdG9yKHJlcXVlc3QpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlID0+IHtcbiAgICAgICAgY29uc3QgZXJyb3IgPSByZXNvbHZlRXJyb3IoZSwge1xuICAgICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLlZBTElEQVRJT05fRVJST1IsXG4gICAgICAgICAgbWVzc2FnZTogJ1ZhbGlkYXRpb24gZmFpbGVkLicsXG4gICAgICAgIH0pO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gIH0pO1xufVxuZnVuY3Rpb24gYnVpbHRJblRyaWdnZXJWYWxpZGF0b3Iob3B0aW9ucywgcmVxdWVzdCkge1xuICBpZiAocmVxdWVzdC5tYXN0ZXIgJiYgIW9wdGlvbnMudmFsaWRhdGVNYXN0ZXJLZXkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgbGV0IHJlcVVzZXIgPSByZXF1ZXN0LnVzZXI7XG4gIGlmIChcbiAgICAhcmVxVXNlciAmJlxuICAgIHJlcXVlc3Qub2JqZWN0ICYmXG4gICAgcmVxdWVzdC5vYmplY3QuY2xhc3NOYW1lID09PSAnX1VzZXInICYmXG4gICAgIXJlcXVlc3Qub2JqZWN0LmV4aXN0ZWQoKVxuICApIHtcbiAgICByZXFVc2VyID0gcmVxdWVzdC5vYmplY3Q7XG4gIH1cbiAgaWYgKG9wdGlvbnMucmVxdWlyZVVzZXIgJiYgIXJlcVVzZXIpIHtcbiAgICB0aHJvdyAnVmFsaWRhdGlvbiBmYWlsZWQuIFBsZWFzZSBsb2dpbiB0byBjb250aW51ZS4nO1xuICB9XG4gIGlmIChvcHRpb25zLnJlcXVpcmVNYXN0ZXIgJiYgIXJlcXVlc3QubWFzdGVyKSB7XG4gICAgdGhyb3cgJ1ZhbGlkYXRpb24gZmFpbGVkLiBNYXN0ZXIga2V5IGlzIHJlcXVpcmVkIHRvIGNvbXBsZXRlIHRoaXMgcmVxdWVzdC4nO1xuICB9XG4gIGxldCBwYXJhbXMgPSByZXF1ZXN0LnBhcmFtcyB8fCB7fTtcbiAgaWYgKHJlcXVlc3Qub2JqZWN0KSB7XG4gICAgcGFyYW1zID0gcmVxdWVzdC5vYmplY3QudG9KU09OKCk7XG4gIH1cbiAgY29uc3QgcmVxdWlyZWRQYXJhbSA9IGtleSA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBwYXJhbXNba2V5XTtcbiAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgYFZhbGlkYXRpb24gZmFpbGVkLiBQbGVhc2Ugc3BlY2lmeSBkYXRhIGZvciAke2tleX0uYDtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgdmFsaWRhdGVPcHRpb25zID0gKG9wdCwga2V5LCB2YWwpID0+IHtcbiAgICBsZXQgb3B0cyA9IG9wdC5vcHRpb25zO1xuICAgIGlmICh0eXBlb2Ygb3B0cyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gb3B0cyh2YWwpO1xuICAgICAgICBpZiAoIXJlc3VsdCAmJiByZXN1bHQgIT0gbnVsbCkge1xuICAgICAgICAgIHRocm93IG9wdC5lcnJvciB8fCBgVmFsaWRhdGlvbiBmYWlsZWQuIEludmFsaWQgdmFsdWUgZm9yICR7a2V5fS5gO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmICghZSkge1xuICAgICAgICAgIHRocm93IG9wdC5lcnJvciB8fCBgVmFsaWRhdGlvbiBmYWlsZWQuIEludmFsaWQgdmFsdWUgZm9yICR7a2V5fS5gO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhyb3cgb3B0LmVycm9yIHx8IGUubWVzc2FnZSB8fCBlO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkob3B0cykpIHtcbiAgICAgIG9wdHMgPSBbb3B0Lm9wdGlvbnNdO1xuICAgIH1cblxuICAgIGlmICghb3B0cy5pbmNsdWRlcyh2YWwpKSB7XG4gICAgICB0aHJvdyAoXG4gICAgICAgIG9wdC5lcnJvciB8fCBgVmFsaWRhdGlvbiBmYWlsZWQuIEludmFsaWQgb3B0aW9uIGZvciAke2tleX0uIEV4cGVjdGVkOiAke29wdHMuam9pbignLCAnKX1gXG4gICAgICApO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBnZXRUeXBlID0gZm4gPT4ge1xuICAgIGNvbnN0IG1hdGNoID0gZm4gJiYgZm4udG9TdHJpbmcoKS5tYXRjaCgvXlxccypmdW5jdGlvbiAoXFx3KykvKTtcbiAgICByZXR1cm4gKG1hdGNoID8gbWF0Y2hbMV0gOiAnJykudG9Mb3dlckNhc2UoKTtcbiAgfTtcbiAgaWYgKEFycmF5LmlzQXJyYXkob3B0aW9ucy5maWVsZHMpKSB7XG4gICAgZm9yIChjb25zdCBrZXkgb2Ygb3B0aW9ucy5maWVsZHMpIHtcbiAgICAgIHJlcXVpcmVkUGFyYW0oa2V5KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gb3B0aW9ucy5maWVsZHMpIHtcbiAgICAgIGNvbnN0IG9wdCA9IG9wdGlvbnMuZmllbGRzW2tleV07XG4gICAgICBsZXQgdmFsID0gcGFyYW1zW2tleV07XG4gICAgICBpZiAodHlwZW9mIG9wdCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmVxdWlyZWRQYXJhbShvcHQpO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBvcHQgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGlmIChvcHQuZGVmYXVsdCAhPSBudWxsICYmIHZhbCA9PSBudWxsKSB7XG4gICAgICAgICAgdmFsID0gb3B0LmRlZmF1bHQ7XG4gICAgICAgICAgcGFyYW1zW2tleV0gPSB2YWw7XG4gICAgICAgICAgaWYgKHJlcXVlc3Qub2JqZWN0KSB7XG4gICAgICAgICAgICByZXF1ZXN0Lm9iamVjdC5zZXQoa2V5LCB2YWwpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0LmNvbnN0YW50ICYmIHJlcXVlc3Qub2JqZWN0KSB7XG4gICAgICAgICAgaWYgKHJlcXVlc3Qub3JpZ2luYWwpIHtcbiAgICAgICAgICAgIHJlcXVlc3Qub2JqZWN0LnNldChrZXksIHJlcXVlc3Qub3JpZ2luYWwuZ2V0KGtleSkpO1xuICAgICAgICAgIH0gZWxzZSBpZiAob3B0LmRlZmF1bHQgIT0gbnVsbCkge1xuICAgICAgICAgICAgcmVxdWVzdC5vYmplY3Quc2V0KGtleSwgb3B0LmRlZmF1bHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0LnJlcXVpcmVkKSB7XG4gICAgICAgICAgcmVxdWlyZWRQYXJhbShrZXkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcHQudHlwZSkge1xuICAgICAgICAgIGNvbnN0IHR5cGUgPSBnZXRUeXBlKG9wdC50eXBlKTtcbiAgICAgICAgICBpZiAodHlwZSA9PSAnYXJyYXknICYmICFBcnJheS5pc0FycmF5KHZhbCkpIHtcbiAgICAgICAgICAgIHRocm93IGBWYWxpZGF0aW9uIGZhaWxlZC4gSW52YWxpZCB0eXBlIGZvciAke2tleX0uIEV4cGVjdGVkOiBhcnJheWA7XG4gICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsICE9PSB0eXBlKSB7XG4gICAgICAgICAgICB0aHJvdyBgVmFsaWRhdGlvbiBmYWlsZWQuIEludmFsaWQgdHlwZSBmb3IgJHtrZXl9LiBFeHBlY3RlZDogJHt0eXBlfWA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChvcHQub3B0aW9ucykge1xuICAgICAgICAgIHZhbGlkYXRlT3B0aW9ucyhvcHQsIGtleSwgdmFsKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICBjb25zdCB1c2VyS2V5cyA9IG9wdGlvbnMucmVxdWlyZVVzZXJLZXlzIHx8IFtdO1xuICBpZiAoQXJyYXkuaXNBcnJheSh1c2VyS2V5cykpIHtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiB1c2VyS2V5cykge1xuICAgICAgaWYgKCFyZXFVc2VyKSB7XG4gICAgICAgIHRocm93ICdQbGVhc2UgbG9naW4gdG8gbWFrZSB0aGlzIHJlcXVlc3QuJztcbiAgICAgIH1cblxuICAgICAgaWYgKHJlcVVzZXIuZ2V0KGtleSkgPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBgVmFsaWRhdGlvbiBmYWlsZWQuIFBsZWFzZSBzZXQgZGF0YSBmb3IgJHtrZXl9IG9uIHlvdXIgYWNjb3VudC5gO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgdXNlcktleXMgPT09ICdvYmplY3QnKSB7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gb3B0aW9ucy5yZXF1aXJlVXNlcktleXMpIHtcbiAgICAgIGNvbnN0IG9wdCA9IG9wdGlvbnMucmVxdWlyZVVzZXJLZXlzW2tleV07XG4gICAgICBpZiAob3B0Lm9wdGlvbnMpIHtcbiAgICAgICAgdmFsaWRhdGVPcHRpb25zKG9wdCwga2V5LCByZXFVc2VyLmdldChrZXkpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLy8gVG8gYmUgdXNlZCBhcyBwYXJ0IG9mIHRoZSBwcm9taXNlIGNoYWluIHdoZW4gc2F2aW5nL2RlbGV0aW5nIGFuIG9iamVjdFxuLy8gV2lsbCByZXNvbHZlIHN1Y2Nlc3NmdWxseSBpZiBubyB0cmlnZ2VyIGlzIGNvbmZpZ3VyZWRcbi8vIFJlc29sdmVzIHRvIGFuIG9iamVjdCwgZW1wdHkgb3IgY29udGFpbmluZyBhbiBvYmplY3Qga2V5LiBBIGJlZm9yZVNhdmVcbi8vIHRyaWdnZXIgd2lsbCBzZXQgdGhlIG9iamVjdCBrZXkgdG8gdGhlIHJlc3QgZm9ybWF0IG9iamVjdCB0byBzYXZlLlxuLy8gb3JpZ2luYWxQYXJzZU9iamVjdCBpcyBvcHRpb25hbCwgd2Ugb25seSBuZWVkIHRoYXQgZm9yIGJlZm9yZS9hZnRlclNhdmUgZnVuY3Rpb25zXG5leHBvcnQgZnVuY3Rpb24gbWF5YmVSdW5UcmlnZ2VyKFxuICB0cmlnZ2VyVHlwZSxcbiAgYXV0aCxcbiAgcGFyc2VPYmplY3QsXG4gIG9yaWdpbmFsUGFyc2VPYmplY3QsXG4gIGNvbmZpZyxcbiAgY29udGV4dFxuKSB7XG4gIGlmICghcGFyc2VPYmplY3QpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgfVxuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIHZhciB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihwYXJzZU9iamVjdC5jbGFzc05hbWUsIHRyaWdnZXJUeXBlLCBjb25maWcuYXBwbGljYXRpb25JZCk7XG4gICAgaWYgKCF0cmlnZ2VyKSByZXR1cm4gcmVzb2x2ZSgpO1xuICAgIHZhciByZXF1ZXN0ID0gZ2V0UmVxdWVzdE9iamVjdChcbiAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgYXV0aCxcbiAgICAgIHBhcnNlT2JqZWN0LFxuICAgICAgb3JpZ2luYWxQYXJzZU9iamVjdCxcbiAgICAgIGNvbmZpZyxcbiAgICAgIGNvbnRleHRcbiAgICApO1xuICAgIHZhciB7IHN1Y2Nlc3MsIGVycm9yIH0gPSBnZXRSZXNwb25zZU9iamVjdChcbiAgICAgIHJlcXVlc3QsXG4gICAgICBvYmplY3QgPT4ge1xuICAgICAgICBsb2dUcmlnZ2VyU3VjY2Vzc0JlZm9yZUhvb2soXG4gICAgICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICAgICAgcGFyc2VPYmplY3QuY2xhc3NOYW1lLFxuICAgICAgICAgIHBhcnNlT2JqZWN0LnRvSlNPTigpLFxuICAgICAgICAgIG9iamVjdCxcbiAgICAgICAgICBhdXRoXG4gICAgICAgICk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYmVmb3JlU2F2ZSB8fFxuICAgICAgICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlclNhdmUgfHxcbiAgICAgICAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYmVmb3JlRGVsZXRlIHx8XG4gICAgICAgICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmFmdGVyRGVsZXRlXG4gICAgICAgICkge1xuICAgICAgICAgIE9iamVjdC5hc3NpZ24oY29udGV4dCwgcmVxdWVzdC5jb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICByZXNvbHZlKG9iamVjdCk7XG4gICAgICB9LFxuICAgICAgZXJyb3IgPT4ge1xuICAgICAgICBsb2dUcmlnZ2VyRXJyb3JCZWZvcmVIb29rKFxuICAgICAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgICAgIHBhcnNlT2JqZWN0LmNsYXNzTmFtZSxcbiAgICAgICAgICBwYXJzZU9iamVjdC50b0pTT04oKSxcbiAgICAgICAgICBhdXRoLFxuICAgICAgICAgIGVycm9yXG4gICAgICAgICk7XG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICB9XG4gICAgKTtcblxuICAgIC8vIEFmdGVyU2F2ZSBhbmQgYWZ0ZXJEZWxldGUgdHJpZ2dlcnMgY2FuIHJldHVybiBhIHByb21pc2UsIHdoaWNoIGlmIHRoZXlcbiAgICAvLyBkbywgbmVlZHMgdG8gYmUgcmVzb2x2ZWQgYmVmb3JlIHRoaXMgcHJvbWlzZSBpcyByZXNvbHZlZCxcbiAgICAvLyBzbyB0cmlnZ2VyIGV4ZWN1dGlvbiBpcyBzeW5jZWQgd2l0aCBSZXN0V3JpdGUuZXhlY3V0ZSgpIGNhbGwuXG4gICAgLy8gSWYgdHJpZ2dlcnMgZG8gbm90IHJldHVybiBhIHByb21pc2UsIHRoZXkgY2FuIHJ1biBhc3luYyBjb2RlIHBhcmFsbGVsXG4gICAgLy8gdG8gdGhlIFJlc3RXcml0ZS5leGVjdXRlKCkgY2FsbC5cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIG1heWJlUnVuVmFsaWRhdG9yKHJlcXVlc3QsIGAke3RyaWdnZXJUeXBlfS4ke3BhcnNlT2JqZWN0LmNsYXNzTmFtZX1gKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIGlmIChyZXF1ZXN0LnNraXBXaXRoTWFzdGVyS2V5KSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSB0cmlnZ2VyKHJlcXVlc3QpO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmFmdGVyU2F2ZSB8fFxuICAgICAgICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlckRlbGV0ZSB8fFxuICAgICAgICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlckxvZ2luXG4gICAgICAgICkge1xuICAgICAgICAgIGxvZ1RyaWdnZXJBZnRlckhvb2sodHJpZ2dlclR5cGUsIHBhcnNlT2JqZWN0LmNsYXNzTmFtZSwgcGFyc2VPYmplY3QudG9KU09OKCksIGF1dGgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGJlZm9yZVNhdmUgaXMgZXhwZWN0ZWQgdG8gcmV0dXJuIG51bGwgKG5vdGhpbmcpXG4gICAgICAgIGlmICh0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYmVmb3JlU2F2ZSkge1xuICAgICAgICAgIGlmIChwcm9taXNlICYmIHR5cGVvZiBwcm9taXNlLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAvLyByZXNwb25zZS5vYmplY3QgbWF5IGNvbWUgZnJvbSBleHByZXNzIHJvdXRpbmcgYmVmb3JlIGhvb2tcbiAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLm9iamVjdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgICAgfSlcbiAgICAgIC50aGVuKHN1Y2Nlc3MsIGVycm9yKTtcbiAgfSk7XG59XG5cbi8vIENvbnZlcnRzIGEgUkVTVC1mb3JtYXQgb2JqZWN0IHRvIGEgUGFyc2UuT2JqZWN0XG4vLyBkYXRhIGlzIGVpdGhlciBjbGFzc05hbWUgb3IgYW4gb2JqZWN0XG5leHBvcnQgZnVuY3Rpb24gaW5mbGF0ZShkYXRhLCByZXN0T2JqZWN0KSB7XG4gIHZhciBjb3B5ID0gdHlwZW9mIGRhdGEgPT0gJ29iamVjdCcgPyBkYXRhIDogeyBjbGFzc05hbWU6IGRhdGEgfTtcbiAgZm9yICh2YXIga2V5IGluIHJlc3RPYmplY3QpIHtcbiAgICBjb3B5W2tleV0gPSByZXN0T2JqZWN0W2tleV07XG4gIH1cbiAgcmV0dXJuIFBhcnNlLk9iamVjdC5mcm9tSlNPTihjb3B5KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJ1bkxpdmVRdWVyeUV2ZW50SGFuZGxlcnMoZGF0YSwgYXBwbGljYXRpb25JZCA9IFBhcnNlLmFwcGxpY2F0aW9uSWQpIHtcbiAgaWYgKCFfdHJpZ2dlclN0b3JlIHx8ICFfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdIHx8ICFfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdLkxpdmVRdWVyeSkge1xuICAgIHJldHVybjtcbiAgfVxuICBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdLkxpdmVRdWVyeS5mb3JFYWNoKGhhbmRsZXIgPT4gaGFuZGxlcihkYXRhKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXF1ZXN0RmlsZU9iamVjdCh0cmlnZ2VyVHlwZSwgYXV0aCwgZmlsZU9iamVjdCwgY29uZmlnKSB7XG4gIGNvbnN0IHJlcXVlc3QgPSB7XG4gICAgLi4uZmlsZU9iamVjdCxcbiAgICB0cmlnZ2VyTmFtZTogdHJpZ2dlclR5cGUsXG4gICAgbWFzdGVyOiBmYWxzZSxcbiAgICBsb2c6IGNvbmZpZy5sb2dnZXJDb250cm9sbGVyLFxuICAgIGhlYWRlcnM6IGNvbmZpZy5oZWFkZXJzLFxuICAgIGlwOiBjb25maWcuaXAsXG4gIH07XG5cbiAgaWYgKCFhdXRoKSB7XG4gICAgcmV0dXJuIHJlcXVlc3Q7XG4gIH1cbiAgaWYgKGF1dGguaXNNYXN0ZXIpIHtcbiAgICByZXF1ZXN0WydtYXN0ZXInXSA9IHRydWU7XG4gIH1cbiAgaWYgKGF1dGgudXNlcikge1xuICAgIHJlcXVlc3RbJ3VzZXInXSA9IGF1dGgudXNlcjtcbiAgfVxuICBpZiAoYXV0aC5pbnN0YWxsYXRpb25JZCkge1xuICAgIHJlcXVlc3RbJ2luc3RhbGxhdGlvbklkJ10gPSBhdXRoLmluc3RhbGxhdGlvbklkO1xuICB9XG4gIHJldHVybiByZXF1ZXN0O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbWF5YmVSdW5GaWxlVHJpZ2dlcih0cmlnZ2VyVHlwZSwgZmlsZU9iamVjdCwgY29uZmlnLCBhdXRoKSB7XG4gIGNvbnN0IGZpbGVUcmlnZ2VyID0gZ2V0RmlsZVRyaWdnZXIodHJpZ2dlclR5cGUsIGNvbmZpZy5hcHBsaWNhdGlvbklkKTtcbiAgaWYgKHR5cGVvZiBmaWxlVHJpZ2dlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXF1ZXN0ID0gZ2V0UmVxdWVzdEZpbGVPYmplY3QodHJpZ2dlclR5cGUsIGF1dGgsIGZpbGVPYmplY3QsIGNvbmZpZyk7XG4gICAgICBhd2FpdCBtYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0LCBgJHt0cmlnZ2VyVHlwZX0uJHtGaWxlQ2xhc3NOYW1lfWApO1xuICAgICAgaWYgKHJlcXVlc3Quc2tpcFdpdGhNYXN0ZXJLZXkpIHtcbiAgICAgICAgcmV0dXJuIGZpbGVPYmplY3Q7XG4gICAgICB9XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBmaWxlVHJpZ2dlcihyZXF1ZXN0KTtcbiAgICAgIGxvZ1RyaWdnZXJTdWNjZXNzQmVmb3JlSG9vayhcbiAgICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICAgICdQYXJzZS5GaWxlJyxcbiAgICAgICAgeyAuLi5maWxlT2JqZWN0LmZpbGUudG9KU09OKCksIGZpbGVTaXplOiBmaWxlT2JqZWN0LmZpbGVTaXplIH0sXG4gICAgICAgIHJlc3VsdCxcbiAgICAgICAgYXV0aFxuICAgICAgKTtcbiAgICAgIHJldHVybiByZXN1bHQgfHwgZmlsZU9iamVjdDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nVHJpZ2dlckVycm9yQmVmb3JlSG9vayhcbiAgICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICAgICdQYXJzZS5GaWxlJyxcbiAgICAgICAgeyAuLi5maWxlT2JqZWN0LmZpbGUudG9KU09OKCksIGZpbGVTaXplOiBmaWxlT2JqZWN0LmZpbGVTaXplIH0sXG4gICAgICAgIGF1dGgsXG4gICAgICAgIGVycm9yXG4gICAgICApO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG4gIHJldHVybiBmaWxlT2JqZWN0O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbWF5YmVSdW5Db25uZWN0VHJpZ2dlcih0cmlnZ2VyVHlwZSwgcmVxdWVzdCkge1xuICBjb25zdCB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihDb25uZWN0Q2xhc3NOYW1lLCB0cmlnZ2VyVHlwZSwgUGFyc2UuYXBwbGljYXRpb25JZCk7XG4gIGlmICghdHJpZ2dlcikge1xuICAgIHJldHVybjtcbiAgfVxuICByZXF1ZXN0LnVzZXIgPSBhd2FpdCB1c2VyRm9yU2Vzc2lvblRva2VuKHJlcXVlc3Quc2Vzc2lvblRva2VuKTtcbiAgYXdhaXQgbWF5YmVSdW5WYWxpZGF0b3IocmVxdWVzdCwgYCR7dHJpZ2dlclR5cGV9LiR7Q29ubmVjdENsYXNzTmFtZX1gKTtcbiAgaWYgKHJlcXVlc3Quc2tpcFdpdGhNYXN0ZXJLZXkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgcmV0dXJuIHRyaWdnZXIocmVxdWVzdCk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBtYXliZVJ1blN1YnNjcmliZVRyaWdnZXIodHJpZ2dlclR5cGUsIGNsYXNzTmFtZSwgcmVxdWVzdCkge1xuICBjb25zdCB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihjbGFzc05hbWUsIHRyaWdnZXJUeXBlLCBQYXJzZS5hcHBsaWNhdGlvbklkKTtcbiAgaWYgKCF0cmlnZ2VyKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnN0IHBhcnNlUXVlcnkgPSBuZXcgUGFyc2UuUXVlcnkoY2xhc3NOYW1lKTtcbiAgcGFyc2VRdWVyeS53aXRoSlNPTihyZXF1ZXN0LnF1ZXJ5KTtcbiAgcmVxdWVzdC5xdWVyeSA9IHBhcnNlUXVlcnk7XG4gIHJlcXVlc3QudXNlciA9IGF3YWl0IHVzZXJGb3JTZXNzaW9uVG9rZW4ocmVxdWVzdC5zZXNzaW9uVG9rZW4pO1xuICBhd2FpdCBtYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0LCBgJHt0cmlnZ2VyVHlwZX0uJHtjbGFzc05hbWV9YCk7XG4gIGlmIChyZXF1ZXN0LnNraXBXaXRoTWFzdGVyS2V5KSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGF3YWl0IHRyaWdnZXIocmVxdWVzdCk7XG4gIGNvbnN0IHF1ZXJ5ID0gcmVxdWVzdC5xdWVyeS50b0pTT04oKTtcbiAgaWYgKHF1ZXJ5LmtleXMpIHtcbiAgICBxdWVyeS5maWVsZHMgPSBxdWVyeS5rZXlzLnNwbGl0KCcsJyk7XG4gIH1cbiAgcmVxdWVzdC5xdWVyeSA9IHF1ZXJ5O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbWF5YmVSdW5BZnRlckV2ZW50VHJpZ2dlcih0cmlnZ2VyVHlwZSwgY2xhc3NOYW1lLCByZXF1ZXN0KSB7XG4gIGNvbnN0IHRyaWdnZXIgPSBnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHJpZ2dlclR5cGUsIFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xuICBpZiAoIXRyaWdnZXIpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHJlcXVlc3Qub2JqZWN0KSB7XG4gICAgcmVxdWVzdC5vYmplY3QgPSBQYXJzZS5PYmplY3QuZnJvbUpTT04ocmVxdWVzdC5vYmplY3QpO1xuICB9XG4gIGlmIChyZXF1ZXN0Lm9yaWdpbmFsKSB7XG4gICAgcmVxdWVzdC5vcmlnaW5hbCA9IFBhcnNlLk9iamVjdC5mcm9tSlNPTihyZXF1ZXN0Lm9yaWdpbmFsKTtcbiAgfVxuICByZXF1ZXN0LnVzZXIgPSBhd2FpdCB1c2VyRm9yU2Vzc2lvblRva2VuKHJlcXVlc3Quc2Vzc2lvblRva2VuKTtcbiAgYXdhaXQgbWF5YmVSdW5WYWxpZGF0b3IocmVxdWVzdCwgYCR7dHJpZ2dlclR5cGV9LiR7Y2xhc3NOYW1lfWApO1xuICBpZiAocmVxdWVzdC5za2lwV2l0aE1hc3RlcktleSkge1xuICAgIHJldHVybjtcbiAgfVxuICByZXR1cm4gdHJpZ2dlcihyZXF1ZXN0KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gdXNlckZvclNlc3Npb25Ub2tlbihzZXNzaW9uVG9rZW4pIHtcbiAgaWYgKCFzZXNzaW9uVG9rZW4pIHtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3QgcSA9IG5ldyBQYXJzZS5RdWVyeSgnX1Nlc3Npb24nKTtcbiAgcS5lcXVhbFRvKCdzZXNzaW9uVG9rZW4nLCBzZXNzaW9uVG9rZW4pO1xuICBxLmluY2x1ZGUoJ3VzZXInKTtcbiAgY29uc3Qgc2Vzc2lvbiA9IGF3YWl0IHEuZmlyc3QoeyB1c2VNYXN0ZXJLZXk6IHRydWUgfSk7XG4gIGlmICghc2Vzc2lvbikge1xuICAgIHJldHVybjtcbiAgfVxuICByZXR1cm4gc2Vzc2lvbi5nZXQoJ3VzZXInKTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/vendor/README.md b/lib/vendor/README.md new file mode 100644 index 0000000000..04e3256f72 --- /dev/null +++ b/lib/vendor/README.md @@ -0,0 +1,8 @@ +# mongoUrl + +A fork of node's `url` module, with the modification that commas and colons are +allowed in hostnames. While this results in a slightly incorrect parsed result, +as the hostname field for a mongodb should be an array of replica sets, it's +good enough to let us pull out and escape the auth portion of the URL. + +https://github.com/parse-community/parse-server/pull/986 diff --git a/lib/vendor/mongodbUrl.js b/lib/vendor/mongodbUrl.js new file mode 100644 index 0000000000..6b95552f05 --- /dev/null +++ b/lib/vendor/mongodbUrl.js @@ -0,0 +1,1064 @@ +// A slightly patched version of node's url module, with support for mongodb:// +// uris. +// +// See https://github.com/nodejs/node/blob/master/LICENSE for licensing +// information +'use strict'; + +const punycode = require('punycode'); + +exports.parse = urlParse; +exports.resolve = urlResolve; +exports.resolveObject = urlResolveObject; +exports.format = urlFormat; +exports.Url = Url; + +function Url() { + this.protocol = null; + this.slashes = null; + this.auth = null; + this.host = null; + this.port = null; + this.hostname = null; + this.hash = null; + this.search = null; + this.query = null; + this.pathname = null; + this.path = null; + this.href = null; +} // Reference: RFC 3986, RFC 1808, RFC 2396 +// define these here so at least they only have to be +// compiled once on the first module load. + + +const protocolPattern = /^([a-z0-9.+-]+:)/i; +const portPattern = /:[0-9]*$/; // Special case for a simple path URL + +const simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/; // protocols that can allow "unsafe" and "unwise" chars. + +const unsafeProtocol = { + javascript: true, + 'javascript:': true +}; // protocols that never have a hostname. + +const hostlessProtocol = { + javascript: true, + 'javascript:': true +}; // protocols that always contain a // bit. + +const slashedProtocol = { + http: true, + 'http:': true, + https: true, + 'https:': true, + ftp: true, + 'ftp:': true, + gopher: true, + 'gopher:': true, + file: true, + 'file:': true +}; + +const querystring = require('querystring'); +/* istanbul ignore next: improve coverage */ + + +function urlParse(url, parseQueryString, slashesDenoteHost) { + if (url instanceof Url) return url; + var u = new Url(); + u.parse(url, parseQueryString, slashesDenoteHost); + return u; +} +/* istanbul ignore next: improve coverage */ + + +Url.prototype.parse = function (url, parseQueryString, slashesDenoteHost) { + if (typeof url !== 'string') { + throw new TypeError('Parameter "url" must be a string, not ' + typeof url); + } // Copy chrome, IE, opera backslash-handling behavior. + // Back slashes before the query string get converted to forward slashes + // See: https://code.google.com/p/chromium/issues/detail?id=25916 + + + var hasHash = false; + var start = -1; + var end = -1; + var rest = ''; + var lastPos = 0; + var i = 0; + + for (var inWs = false, split = false; i < url.length; ++i) { + const code = url.charCodeAt(i); // Find first and last non-whitespace characters for trimming + + const isWs = code === 32 + /* */ + || code === 9 + /*\t*/ + || code === 13 + /*\r*/ + || code === 10 + /*\n*/ + || code === 12 + /*\f*/ + || code === 160 + /*\u00A0*/ + || code === 65279; + /*\uFEFF*/ + + if (start === -1) { + if (isWs) continue; + lastPos = start = i; + } else { + if (inWs) { + if (!isWs) { + end = -1; + inWs = false; + } + } else if (isWs) { + end = i; + inWs = true; + } + } // Only convert backslashes while we haven't seen a split character + + + if (!split) { + switch (code) { + case 35: + // '#' + hasHash = true; + // Fall through + + case 63: + // '?' + split = true; + break; + + case 92: + // '\\' + if (i - lastPos > 0) rest += url.slice(lastPos, i); + rest += '/'; + lastPos = i + 1; + break; + } + } else if (!hasHash && code === 35 + /*#*/ + ) { + hasHash = true; + } + } // Check if string was non-empty (including strings with only whitespace) + + + if (start !== -1) { + if (lastPos === start) { + // We didn't convert any backslashes + if (end === -1) { + if (start === 0) rest = url;else rest = url.slice(start); + } else { + rest = url.slice(start, end); + } + } else if (end === -1 && lastPos < url.length) { + // We converted some backslashes and have only part of the entire string + rest += url.slice(lastPos); + } else if (end !== -1 && lastPos < end) { + // We converted some backslashes and have only part of the entire string + rest += url.slice(lastPos, end); + } + } + + if (!slashesDenoteHost && !hasHash) { + // Try fast path regexp + const simplePath = simplePathPattern.exec(rest); + + if (simplePath) { + this.path = rest; + this.href = rest; + this.pathname = simplePath[1]; + + if (simplePath[2]) { + this.search = simplePath[2]; + + if (parseQueryString) { + this.query = querystring.parse(this.search.slice(1)); + } else { + this.query = this.search.slice(1); + } + } else if (parseQueryString) { + this.search = ''; + this.query = {}; + } + + return this; + } + } + + var proto = protocolPattern.exec(rest); + + if (proto) { + proto = proto[0]; + var lowerProto = proto.toLowerCase(); + this.protocol = lowerProto; + rest = rest.slice(proto.length); + } // figure out if it's got a host + // user@server is *always* interpreted as a hostname, and url + // resolution will treat //foo/bar as host=foo,path=bar because that's + // how the browser resolves relative URLs. + + + if (slashesDenoteHost || proto || /^\/\/[^@\/]+@[^@\/]+/.test(rest)) { + var slashes = rest.charCodeAt(0) === 47 + /*/*/ + && rest.charCodeAt(1) === 47; + /*/*/ + + if (slashes && !(proto && hostlessProtocol[proto])) { + rest = rest.slice(2); + this.slashes = true; + } + } + + if (!hostlessProtocol[proto] && (slashes || proto && !slashedProtocol[proto])) { + // there's a hostname. + // the first instance of /, ?, ;, or # ends the host. + // + // If there is an @ in the hostname, then non-host chars *are* allowed + // to the left of the last @ sign, unless some host-ending character + // comes *before* the @-sign. + // URLs are obnoxious. + // + // ex: + // http://a@b@c/ => user:a@b host:c + // http://a@b?@c => user:a host:b path:/?@c + // v0.12 TODO(isaacs): This is not quite how Chrome does things. + // Review our test case against browsers more comprehensively. + var hostEnd = -1; + var atSign = -1; + var nonHost = -1; + + for (i = 0; i < rest.length; ++i) { + switch (rest.charCodeAt(i)) { + case 9: // '\t' + + case 10: // '\n' + + case 13: // '\r' + + case 32: // ' ' + + case 34: // '"' + + case 37: // '%' + + case 39: // '\'' + + case 59: // ';' + + case 60: // '<' + + case 62: // '>' + + case 92: // '\\' + + case 94: // '^' + + case 96: // '`' + + case 123: // '{' + + case 124: // '|' + + case 125: + // '}' + // Characters that are never ever allowed in a hostname from RFC 2396 + if (nonHost === -1) nonHost = i; + break; + + case 35: // '#' + + case 47: // '/' + + case 63: + // '?' + // Find the first instance of any host-ending characters + if (nonHost === -1) nonHost = i; + hostEnd = i; + break; + + case 64: + // '@' + // At this point, either we have an explicit point where the + // auth portion cannot go past, or the last @ char is the decider. + atSign = i; + nonHost = -1; + break; + } + + if (hostEnd !== -1) break; + } + + start = 0; + + if (atSign !== -1) { + this.auth = decodeURIComponent(rest.slice(0, atSign)); + start = atSign + 1; + } + + if (nonHost === -1) { + this.host = rest.slice(start); + rest = ''; + } else { + this.host = rest.slice(start, nonHost); + rest = rest.slice(nonHost); + } // pull out port. + + + this.parseHost(); // we've indicated that there is a hostname, + // so even if it's empty, it has to be present. + + if (typeof this.hostname !== 'string') this.hostname = ''; + var hostname = this.hostname; // if hostname begins with [ and ends with ] + // assume that it's an IPv6 address. + + var ipv6Hostname = hostname.charCodeAt(0) === 91 + /*[*/ + && hostname.charCodeAt(hostname.length - 1) === 93; + /*]*/ + // validate a little. + + if (!ipv6Hostname) { + const result = validateHostname(this, rest, hostname); + if (result !== undefined) rest = result; + } // hostnames are always lower case. + + + this.hostname = this.hostname.toLowerCase(); + + if (!ipv6Hostname) { + // IDNA Support: Returns a punycoded representation of "domain". + // It only converts parts of the domain name that + // have non-ASCII characters, i.e. it doesn't matter if + // you call it with a domain that already is ASCII-only. + this.hostname = punycode.toASCII(this.hostname); + } + + var p = this.port ? ':' + this.port : ''; + var h = this.hostname || ''; + this.host = h + p; // strip [ and ] from the hostname + // the host field still retains them, though + + if (ipv6Hostname) { + this.hostname = this.hostname.slice(1, -1); + + if (rest[0] !== '/') { + rest = '/' + rest; + } + } + } // now rest is set to the post-host stuff. + // chop off any delim chars. + + + if (!unsafeProtocol[lowerProto]) { + // First, make 100% sure that any "autoEscape" chars get + // escaped, even if encodeURIComponent doesn't think they + // need to be. + const result = autoEscapeStr(rest); + if (result !== undefined) rest = result; + } + + var questionIdx = -1; + var hashIdx = -1; + + for (i = 0; i < rest.length; ++i) { + const code = rest.charCodeAt(i); + + if (code === 35 + /*#*/ + ) { + this.hash = rest.slice(i); + hashIdx = i; + break; + } else if (code === 63 + /*?*/ + && questionIdx === -1) { + questionIdx = i; + } + } + + if (questionIdx !== -1) { + if (hashIdx === -1) { + this.search = rest.slice(questionIdx); + this.query = rest.slice(questionIdx + 1); + } else { + this.search = rest.slice(questionIdx, hashIdx); + this.query = rest.slice(questionIdx + 1, hashIdx); + } + + if (parseQueryString) { + this.query = querystring.parse(this.query); + } + } else if (parseQueryString) { + // no query string, but parseQueryString still requested + this.search = ''; + this.query = {}; + } + + var firstIdx = questionIdx !== -1 && (hashIdx === -1 || questionIdx < hashIdx) ? questionIdx : hashIdx; + + if (firstIdx === -1) { + if (rest.length > 0) this.pathname = rest; + } else if (firstIdx > 0) { + this.pathname = rest.slice(0, firstIdx); + } + + if (slashedProtocol[lowerProto] && this.hostname && !this.pathname) { + this.pathname = '/'; + } // to support http.request + + + if (this.pathname || this.search) { + const p = this.pathname || ''; + const s = this.search || ''; + this.path = p + s; + } // finally, reconstruct the href based on what has been validated. + + + this.href = this.format(); + return this; +}; +/* istanbul ignore next: improve coverage */ + + +function validateHostname(self, rest, hostname) { + for (var i = 0, lastPos; i <= hostname.length; ++i) { + var code; + if (i < hostname.length) code = hostname.charCodeAt(i); + + if (code === 46 + /*.*/ + || i === hostname.length) { + if (i - lastPos > 0) { + if (i - lastPos > 63) { + self.hostname = hostname.slice(0, lastPos + 63); + return '/' + hostname.slice(lastPos + 63) + rest; + } + } + + lastPos = i + 1; + continue; + } else if (code >= 48 + /*0*/ + && code <= 57 || + /*9*/ + code >= 97 + /*a*/ + && code <= 122 + /*z*/ + || code === 45 + /*-*/ + || code >= 65 + /*A*/ + && code <= 90 + /*Z*/ + || code === 43 + /*+*/ + || code === 95 + /*_*/ + || + /* BEGIN MONGO URI PATCH */ + code === 44 + /*,*/ + || code === 58 + /*:*/ + || + /* END MONGO URI PATCH */ + code > 127) { + continue; + } // Invalid host character + + + self.hostname = hostname.slice(0, i); + if (i < hostname.length) return '/' + hostname.slice(i) + rest; + break; + } +} +/* istanbul ignore next: improve coverage */ + + +function autoEscapeStr(rest) { + var newRest = ''; + var lastPos = 0; + + for (var i = 0; i < rest.length; ++i) { + // Automatically escape all delimiters and unwise characters from RFC 2396 + // Also escape single quotes in case of an XSS attack + switch (rest.charCodeAt(i)) { + case 9: + // '\t' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%09'; + lastPos = i + 1; + break; + + case 10: + // '\n' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%0A'; + lastPos = i + 1; + break; + + case 13: + // '\r' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%0D'; + lastPos = i + 1; + break; + + case 32: + // ' ' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%20'; + lastPos = i + 1; + break; + + case 34: + // '"' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%22'; + lastPos = i + 1; + break; + + case 39: + // '\'' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%27'; + lastPos = i + 1; + break; + + case 60: + // '<' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%3C'; + lastPos = i + 1; + break; + + case 62: + // '>' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%3E'; + lastPos = i + 1; + break; + + case 92: + // '\\' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%5C'; + lastPos = i + 1; + break; + + case 94: + // '^' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%5E'; + lastPos = i + 1; + break; + + case 96: + // '`' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%60'; + lastPos = i + 1; + break; + + case 123: + // '{' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%7B'; + lastPos = i + 1; + break; + + case 124: + // '|' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%7C'; + lastPos = i + 1; + break; + + case 125: + // '}' + if (i - lastPos > 0) newRest += rest.slice(lastPos, i); + newRest += '%7D'; + lastPos = i + 1; + break; + } + } + + if (lastPos === 0) return; + if (lastPos < rest.length) return newRest + rest.slice(lastPos);else return newRest; +} // format a parsed object into a url string + +/* istanbul ignore next: improve coverage */ + + +function urlFormat(obj) { + // ensure it's an object, and not a string url. + // If it's an obj, this is a no-op. + // this way, you can call url_format() on strings + // to clean up potentially wonky urls. + if (typeof obj === 'string') obj = urlParse(obj);else if (typeof obj !== 'object' || obj === null) throw new TypeError('Parameter "urlObj" must be an object, not ' + obj === null ? 'null' : typeof obj);else if (!(obj instanceof Url)) return Url.prototype.format.call(obj); + return obj.format(); +} +/* istanbul ignore next: improve coverage */ + + +Url.prototype.format = function () { + var auth = this.auth || ''; + + if (auth) { + auth = encodeAuth(auth); + auth += '@'; + } + + var protocol = this.protocol || ''; + var pathname = this.pathname || ''; + var hash = this.hash || ''; + var host = false; + var query = ''; + + if (this.host) { + host = auth + this.host; + } else if (this.hostname) { + host = auth + (this.hostname.indexOf(':') === -1 ? this.hostname : '[' + this.hostname + ']'); + + if (this.port) { + host += ':' + this.port; + } + } + + if (this.query !== null && typeof this.query === 'object') query = querystring.stringify(this.query); + var search = this.search || query && '?' + query || ''; + if (protocol && protocol.charCodeAt(protocol.length - 1) !== 58 + /*:*/ + ) protocol += ':'; + var newPathname = ''; + var lastPos = 0; + + for (var i = 0; i < pathname.length; ++i) { + switch (pathname.charCodeAt(i)) { + case 35: + // '#' + if (i - lastPos > 0) newPathname += pathname.slice(lastPos, i); + newPathname += '%23'; + lastPos = i + 1; + break; + + case 63: + // '?' + if (i - lastPos > 0) newPathname += pathname.slice(lastPos, i); + newPathname += '%3F'; + lastPos = i + 1; + break; + } + } + + if (lastPos > 0) { + if (lastPos !== pathname.length) pathname = newPathname + pathname.slice(lastPos);else pathname = newPathname; + } // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. + // unless they had them to begin with. + + + if (this.slashes || (!protocol || slashedProtocol[protocol]) && host !== false) { + host = '//' + (host || ''); + if (pathname && pathname.charCodeAt(0) !== 47 + /*/*/ + ) pathname = '/' + pathname; + } else if (!host) { + host = ''; + } + + search = search.replace('#', '%23'); + if (hash && hash.charCodeAt(0) !== 35 + /*#*/ + ) hash = '#' + hash; + if (search && search.charCodeAt(0) !== 63 + /*?*/ + ) search = '?' + search; + return protocol + host + pathname + search + hash; +}; +/* istanbul ignore next: improve coverage */ + + +function urlResolve(source, relative) { + return urlParse(source, false, true).resolve(relative); +} +/* istanbul ignore next: improve coverage */ + + +Url.prototype.resolve = function (relative) { + return this.resolveObject(urlParse(relative, false, true)).format(); +}; +/* istanbul ignore next: improve coverage */ + + +function urlResolveObject(source, relative) { + if (!source) return relative; + return urlParse(source, false, true).resolveObject(relative); +} +/* istanbul ignore next: improve coverage */ + + +Url.prototype.resolveObject = function (relative) { + if (typeof relative === 'string') { + var rel = new Url(); + rel.parse(relative, false, true); + relative = rel; + } + + var result = new Url(); + var tkeys = Object.keys(this); + + for (var tk = 0; tk < tkeys.length; tk++) { + var tkey = tkeys[tk]; + result[tkey] = this[tkey]; + } // hash is always overridden, no matter what. + // even href="" will remove it. + + + result.hash = relative.hash; // if the relative url is empty, then there's nothing left to do here. + + if (relative.href === '') { + result.href = result.format(); + return result; + } // hrefs like //foo/bar always cut to the protocol. + + + if (relative.slashes && !relative.protocol) { + // take everything except the protocol from relative + var rkeys = Object.keys(relative); + + for (var rk = 0; rk < rkeys.length; rk++) { + var rkey = rkeys[rk]; + if (rkey !== 'protocol') result[rkey] = relative[rkey]; + } //urlParse appends trailing / to urls like http://www.example.com + + + if (slashedProtocol[result.protocol] && result.hostname && !result.pathname) { + result.path = result.pathname = '/'; + } + + result.href = result.format(); + return result; + } + + if (relative.protocol && relative.protocol !== result.protocol) { + // if it's a known url protocol, then changing + // the protocol does weird things + // first, if it's not file:, then we MUST have a host, + // and if there was a path + // to begin with, then we MUST have a path. + // if it is file:, then the host is dropped, + // because that's known to be hostless. + // anything else is assumed to be absolute. + if (!slashedProtocol[relative.protocol]) { + var keys = Object.keys(relative); + + for (var v = 0; v < keys.length; v++) { + var k = keys[v]; + result[k] = relative[k]; + } + + result.href = result.format(); + return result; + } + + result.protocol = relative.protocol; + + if (!relative.host && !/^file:?$/.test(relative.protocol) && !hostlessProtocol[relative.protocol]) { + const relPath = (relative.pathname || '').split('/'); + + while (relPath.length && !(relative.host = relPath.shift())); + + if (!relative.host) relative.host = ''; + if (!relative.hostname) relative.hostname = ''; + if (relPath[0] !== '') relPath.unshift(''); + if (relPath.length < 2) relPath.unshift(''); + result.pathname = relPath.join('/'); + } else { + result.pathname = relative.pathname; + } + + result.search = relative.search; + result.query = relative.query; + result.host = relative.host || ''; + result.auth = relative.auth; + result.hostname = relative.hostname || relative.host; + result.port = relative.port; // to support http.request + + if (result.pathname || result.search) { + var p = result.pathname || ''; + var s = result.search || ''; + result.path = p + s; + } + + result.slashes = result.slashes || relative.slashes; + result.href = result.format(); + return result; + } + + var isSourceAbs = result.pathname && result.pathname.charAt(0) === '/'; + var isRelAbs = relative.host || relative.pathname && relative.pathname.charAt(0) === '/'; + var mustEndAbs = isRelAbs || isSourceAbs || result.host && relative.pathname; + var removeAllDots = mustEndAbs; + var srcPath = result.pathname && result.pathname.split('/') || []; + var relPath = relative.pathname && relative.pathname.split('/') || []; + var psychotic = result.protocol && !slashedProtocol[result.protocol]; // if the url is a non-slashed url, then relative + // links like ../.. should be able + // to crawl up to the hostname, as well. This is strange. + // result.protocol has already been set by now. + // Later on, put the first path part into the host field. + + if (psychotic) { + result.hostname = ''; + result.port = null; + + if (result.host) { + if (srcPath[0] === '') srcPath[0] = result.host;else srcPath.unshift(result.host); + } + + result.host = ''; + + if (relative.protocol) { + relative.hostname = null; + relative.port = null; + + if (relative.host) { + if (relPath[0] === '') relPath[0] = relative.host;else relPath.unshift(relative.host); + } + + relative.host = null; + } + + mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); + } + + if (isRelAbs) { + // it's absolute. + result.host = relative.host || relative.host === '' ? relative.host : result.host; + result.hostname = relative.hostname || relative.hostname === '' ? relative.hostname : result.hostname; + result.search = relative.search; + result.query = relative.query; + srcPath = relPath; // fall through to the dot-handling below. + } else if (relPath.length) { + // it's relative + // throw away the existing file, and take the new path instead. + if (!srcPath) srcPath = []; + srcPath.pop(); + srcPath = srcPath.concat(relPath); + result.search = relative.search; + result.query = relative.query; + } else if (relative.search !== null && relative.search !== undefined) { + // just pull out the search. + // like href='?foo'. + // Put this after the other two cases because it simplifies the booleans + if (psychotic) { + result.hostname = result.host = srcPath.shift(); //occasionally the auth can get stuck only in host + //this especially happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + + const authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; + + if (authInHost) { + result.auth = authInHost.shift(); + result.host = result.hostname = authInHost.shift(); + } + } + + result.search = relative.search; + result.query = relative.query; //to support http.request + + if (result.pathname !== null || result.search !== null) { + result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); + } + + result.href = result.format(); + return result; + } + + if (!srcPath.length) { + // no path at all. easy. + // we've already handled the other stuff above. + result.pathname = null; //to support http.request + + if (result.search) { + result.path = '/' + result.search; + } else { + result.path = null; + } + + result.href = result.format(); + return result; + } // if a url ENDs in . or .., then it must get a trailing slash. + // however, if it ends in anything else non-slashy, + // then it must NOT get a trailing slash. + + + var last = srcPath.slice(-1)[0]; + var hasTrailingSlash = (result.host || relative.host || srcPath.length > 1) && (last === '.' || last === '..') || last === ''; // strip single dots, resolve double dots to parent dir + // if the path tries to go above the root, `up` ends up > 0 + + var up = 0; + + for (var i = srcPath.length; i >= 0; i--) { + last = srcPath[i]; + + if (last === '.') { + spliceOne(srcPath, i); + } else if (last === '..') { + spliceOne(srcPath, i); + up++; + } else if (up) { + spliceOne(srcPath, i); + up--; + } + } // if the path is allowed to go above the root, restore leading ..s + + + if (!mustEndAbs && !removeAllDots) { + for (; up--; up) { + srcPath.unshift('..'); + } + } + + if (mustEndAbs && srcPath[0] !== '' && (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { + srcPath.unshift(''); + } + + if (hasTrailingSlash && srcPath.join('/').substr(-1) !== '/') { + srcPath.push(''); + } + + var isAbsolute = srcPath[0] === '' || srcPath[0] && srcPath[0].charAt(0) === '/'; // put the host back + + if (psychotic) { + if (isAbsolute) { + result.hostname = result.host = ''; + } else { + result.hostname = result.host = srcPath.length ? srcPath.shift() : ''; + } //occasionally the auth can get stuck only in host + //this especially happens in cases like + //url.resolveObject('mailto:local1@domain1', 'local2@domain2') + + + const authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; + + if (authInHost) { + result.auth = authInHost.shift(); + result.host = result.hostname = authInHost.shift(); + } + } + + mustEndAbs = mustEndAbs || result.host && srcPath.length; + + if (mustEndAbs && !isAbsolute) { + srcPath.unshift(''); + } + + if (!srcPath.length) { + result.pathname = null; + result.path = null; + } else { + result.pathname = srcPath.join('/'); + } //to support request.http + + + if (result.pathname !== null || result.search !== null) { + result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); + } + + result.auth = relative.auth || result.auth; + result.slashes = result.slashes || relative.slashes; + result.href = result.format(); + return result; +}; +/* istanbul ignore next: improve coverage */ + + +Url.prototype.parseHost = function () { + var host = this.host; + var port = portPattern.exec(host); + + if (port) { + port = port[0]; + + if (port !== ':') { + this.port = port.slice(1); + } + + host = host.slice(0, host.length - port.length); + } + + if (host) this.hostname = host; +}; // About 1.5x faster than the two-arg version of Array#splice(). + +/* istanbul ignore next: improve coverage */ + + +function spliceOne(list, index) { + for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) list[i] = list[k]; + + list.pop(); +} + +var hexTable = new Array(256); + +for (var i = 0; i < 256; ++i) hexTable[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase(); +/* istanbul ignore next: improve coverage */ + + +function encodeAuth(str) { + // faster encodeURIComponent alternative for encoding auth uri components + var out = ''; + var lastPos = 0; + + for (var i = 0; i < str.length; ++i) { + var c = str.charCodeAt(i); // These characters do not need escaping: + // ! - . _ ~ + // ' ( ) * : + // digits + // alpha (uppercase) + // alpha (lowercase) + + if (c === 0x21 || c === 0x2d || c === 0x2e || c === 0x5f || c === 0x7e || c >= 0x27 && c <= 0x2a || c >= 0x30 && c <= 0x3a || c >= 0x41 && c <= 0x5a || c >= 0x61 && c <= 0x7a) { + continue; + } + + if (i - lastPos > 0) out += str.slice(lastPos, i); + lastPos = i + 1; // Other ASCII characters + + if (c < 0x80) { + out += hexTable[c]; + continue; + } // Multi-byte characters ... + + + if (c < 0x800) { + out += hexTable[0xc0 | c >> 6] + hexTable[0x80 | c & 0x3f]; + continue; + } + + if (c < 0xd800 || c >= 0xe000) { + out += hexTable[0xe0 | c >> 12] + hexTable[0x80 | c >> 6 & 0x3f] + hexTable[0x80 | c & 0x3f]; + continue; + } // Surrogate pair + + + ++i; + var c2; + if (i < str.length) c2 = str.charCodeAt(i) & 0x3ff;else c2 = 0; + c = 0x10000 + ((c & 0x3ff) << 10 | c2); + out += hexTable[0xf0 | c >> 18] + hexTable[0x80 | c >> 12 & 0x3f] + hexTable[0x80 | c >> 6 & 0x3f] + hexTable[0x80 | c & 0x3f]; + } + + if (lastPos === 0) return str; + if (lastPos < str.length) return out + str.slice(lastPos); + return out; +} +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92ZW5kb3IvbW9uZ29kYlVybC5qcyJdLCJuYW1lcyI6WyJwdW55Y29kZSIsInJlcXVpcmUiLCJleHBvcnRzIiwicGFyc2UiLCJ1cmxQYXJzZSIsInJlc29sdmUiLCJ1cmxSZXNvbHZlIiwicmVzb2x2ZU9iamVjdCIsInVybFJlc29sdmVPYmplY3QiLCJmb3JtYXQiLCJ1cmxGb3JtYXQiLCJVcmwiLCJwcm90b2NvbCIsInNsYXNoZXMiLCJhdXRoIiwiaG9zdCIsInBvcnQiLCJob3N0bmFtZSIsImhhc2giLCJzZWFyY2giLCJxdWVyeSIsInBhdGhuYW1lIiwicGF0aCIsImhyZWYiLCJwcm90b2NvbFBhdHRlcm4iLCJwb3J0UGF0dGVybiIsInNpbXBsZVBhdGhQYXR0ZXJuIiwidW5zYWZlUHJvdG9jb2wiLCJqYXZhc2NyaXB0IiwiaG9zdGxlc3NQcm90b2NvbCIsInNsYXNoZWRQcm90b2NvbCIsImh0dHAiLCJodHRwcyIsImZ0cCIsImdvcGhlciIsImZpbGUiLCJxdWVyeXN0cmluZyIsInVybCIsInBhcnNlUXVlcnlTdHJpbmciLCJzbGFzaGVzRGVub3RlSG9zdCIsInUiLCJwcm90b3R5cGUiLCJUeXBlRXJyb3IiLCJoYXNIYXNoIiwic3RhcnQiLCJlbmQiLCJyZXN0IiwibGFzdFBvcyIsImkiLCJpbldzIiwic3BsaXQiLCJsZW5ndGgiLCJjb2RlIiwiY2hhckNvZGVBdCIsImlzV3MiLCJzbGljZSIsInNpbXBsZVBhdGgiLCJleGVjIiwicHJvdG8iLCJsb3dlclByb3RvIiwidG9Mb3dlckNhc2UiLCJ0ZXN0IiwiaG9zdEVuZCIsImF0U2lnbiIsIm5vbkhvc3QiLCJkZWNvZGVVUklDb21wb25lbnQiLCJwYXJzZUhvc3QiLCJpcHY2SG9zdG5hbWUiLCJyZXN1bHQiLCJ2YWxpZGF0ZUhvc3RuYW1lIiwidW5kZWZpbmVkIiwidG9BU0NJSSIsInAiLCJoIiwiYXV0b0VzY2FwZVN0ciIsInF1ZXN0aW9uSWR4IiwiaGFzaElkeCIsImZpcnN0SWR4IiwicyIsInNlbGYiLCJuZXdSZXN0Iiwib2JqIiwiY2FsbCIsImVuY29kZUF1dGgiLCJpbmRleE9mIiwic3RyaW5naWZ5IiwibmV3UGF0aG5hbWUiLCJyZXBsYWNlIiwic291cmNlIiwicmVsYXRpdmUiLCJyZWwiLCJ0a2V5cyIsIk9iamVjdCIsImtleXMiLCJ0ayIsInRrZXkiLCJya2V5cyIsInJrIiwicmtleSIsInYiLCJrIiwicmVsUGF0aCIsInNoaWZ0IiwidW5zaGlmdCIsImpvaW4iLCJpc1NvdXJjZUFicyIsImNoYXJBdCIsImlzUmVsQWJzIiwibXVzdEVuZEFicyIsInJlbW92ZUFsbERvdHMiLCJzcmNQYXRoIiwicHN5Y2hvdGljIiwicG9wIiwiY29uY2F0IiwiYXV0aEluSG9zdCIsImxhc3QiLCJoYXNUcmFpbGluZ1NsYXNoIiwidXAiLCJzcGxpY2VPbmUiLCJzdWJzdHIiLCJwdXNoIiwiaXNBYnNvbHV0ZSIsImxpc3QiLCJpbmRleCIsIm4iLCJoZXhUYWJsZSIsIkFycmF5IiwidG9TdHJpbmciLCJ0b1VwcGVyQ2FzZSIsInN0ciIsIm91dCIsImMiLCJjMiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBLE1BQU1BLFFBQVEsR0FBR0MsT0FBTyxDQUFDLFVBQUQsQ0FBeEI7O0FBRUFDLE9BQU8sQ0FBQ0MsS0FBUixHQUFnQkMsUUFBaEI7QUFDQUYsT0FBTyxDQUFDRyxPQUFSLEdBQWtCQyxVQUFsQjtBQUNBSixPQUFPLENBQUNLLGFBQVIsR0FBd0JDLGdCQUF4QjtBQUNBTixPQUFPLENBQUNPLE1BQVIsR0FBaUJDLFNBQWpCO0FBRUFSLE9BQU8sQ0FBQ1MsR0FBUixHQUFjQSxHQUFkOztBQUVBLFNBQVNBLEdBQVQsR0FBZTtBQUNiLE9BQUtDLFFBQUwsR0FBZ0IsSUFBaEI7QUFDQSxPQUFLQyxPQUFMLEdBQWUsSUFBZjtBQUNBLE9BQUtDLElBQUwsR0FBWSxJQUFaO0FBQ0EsT0FBS0MsSUFBTCxHQUFZLElBQVo7QUFDQSxPQUFLQyxJQUFMLEdBQVksSUFB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QUFZLENBQUNBLENBQUMsR0FBRyxLQUFMLEtBQWUsRUFBaEIsR0FBc0JDLEVBQWpDLENBQUo7QUFDQUYsSUFBQUEsR0FBRyxJQUNETCxRQUFRLENBQUMsT0FBUU0sQ0FBQyxJQUFJLEVBQWQsQ0FBUixHQUNBTixRQUFRLENBQUMsT0FBU00sQ0FBQyxJQUFJLEVBQU4sR0FBWSxJQUFyQixDQURSLEdBRUFOLFFBQVEsQ0FBQyxPQUFTTSxDQUFDLElBQUksQ0FBTixHQUFXLElBQXBCLENBRlIsR0FHQU4sUUFBUSxDQUFDLE9BQVFNLENBQUMsR0FBRyxJQUFiLENBSlY7QUFLRDs7QUFDRCxNQUFJcEYsT0FBTyxLQUFLLENBQWhCLEVBQW1CLE9BQU9rRixHQUFQO0FBQ25CLE1BQUlsRixPQUFPLEdBQUdrRixHQUFHLENBQUM5RSxNQUFsQixFQUEwQixPQUFPK0UsR0FBRyxHQUFHRCxHQUFHLENBQUMxRSxLQUFKLENBQVVSLE9BQVYsQ0FBYjtBQUMxQixTQUFPbUYsR0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQSBzbGlnaHRseSBwYXRjaGVkIHZlcnNpb24gb2Ygbm9kZSdzIHVybCBtb2R1bGUsIHdpdGggc3VwcG9ydCBmb3IgbW9uZ29kYjovL1xuLy8gdXJpcy5cbi8vXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL25vZGVqcy9ub2RlL2Jsb2IvbWFzdGVyL0xJQ0VOU0UgZm9yIGxpY2Vuc2luZ1xuLy8gaW5mb3JtYXRpb25cblxuJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBwdW55Y29kZSA9IHJlcXVpcmUoJ3B1bnljb2RlJyk7XG5cbmV4cG9ydHMucGFyc2UgPSB1cmxQYXJzZTtcbmV4cG9ydHMucmVzb2x2ZSA9IHVybFJlc29sdmU7XG5leHBvcnRzLnJlc29sdmVPYmplY3QgPSB1cmxSZXNvbHZlT2JqZWN0O1xuZXhwb3J0cy5mb3JtYXQgPSB1cmxGb3JtYXQ7XG5cbmV4cG9ydHMuVXJsID0gVXJsO1xuXG5mdW5jdGlvbiBVcmwoKSB7XG4gIHRoaXMucHJvdG9jb2wgPSBudWxsO1xuICB0aGlzLnNsYXNoZXMgPSBudWxsO1xuICB0aGlzLmF1dGggPSBudWxsO1xuICB0aGlzLmhvc3QgPSBudWxsO1xuICB0aGlzLnBvcnQgPSBudWxsO1xuICB0aGlzLmhvc3RuYW1lID0gbnVsbDtcbiAgdGhpcy5oYXNoID0gbnVsbDtcbiAgdGhpcy5zZWFyY2ggPSBudWxsO1xuICB0aGlzLnF1ZXJ5ID0gbnVsbDtcbiAgdGhpcy5wYXRobmFtZSA9IG51bGw7XG4gIHRoaXMucGF0aCA9IG51bGw7XG4gIHRoaXMuaHJlZiA9IG51bGw7XG59XG5cbi8vIFJlZmVyZW5jZTogUkZDIDM5ODYsIFJGQyAxODA4LCBSRkMgMjM5NlxuXG4vLyBkZWZpbmUgdGhlc2UgaGVyZSBzbyBhdCBsZWFzdCB0aGV5IG9ubHkgaGF2ZSB0byBiZVxuLy8gY29tcGlsZWQgb25jZSBvbiB0aGUgZmlyc3QgbW9kdWxlIGxvYWQuXG5jb25zdCBwcm90b2NvbFBhdHRlcm4gPSAvXihbYS16MC05ListXSs6KS9pO1xuY29uc3QgcG9ydFBhdHRlcm4gPSAvOlswLTldKiQvO1xuXG4vLyBTcGVjaWFsIGNhc2UgZm9yIGEgc2ltcGxlIHBhdGggVVJMXG5jb25zdCBzaW1wbGVQYXRoUGF0dGVybiA9IC9eKFxcL1xcLz8oPyFcXC8pW15cXD9cXHNdKikoXFw/W15cXHNdKik/JC87XG5cbi8vIHByb3RvY29scyB0aGF0IGNhbiBhbGxvdyBcInVuc2FmZVwiIGFuZCBcInVud2lzZVwiIGNoYXJzLlxuY29uc3QgdW5zYWZlUHJvdG9jb2wgPSB7XG4gIGphdmFzY3JpcHQ6IHRydWUsXG4gICdqYXZhc2NyaXB0Oic6IHRydWUsXG59O1xuLy8gcHJvdG9jb2xzIHRoYXQgbmV2ZXIgaGF2ZSBhIGhvc3RuYW1lLlxuY29uc3QgaG9zdGxlc3NQcm90b2NvbCA9IHtcbiAgamF2YXNjcmlwdDogdHJ1ZSxcbiAgJ2phdmFzY3JpcHQ6JzogdHJ1ZSxcbn07XG4vLyBwcm90b2NvbHMgdGhhdCBhbHdheXMgY29udGFpbiBhIC8vIGJpdC5cbmNvbnN0IHNsYXNoZWRQcm90b2NvbCA9IHtcbiAgaHR0cDogdHJ1ZSxcbiAgJ2h0dHA6JzogdHJ1ZSxcbiAgaHR0cHM6IHRydWUsXG4gICdodHRwczonOiB0cnVlLFxuICBmdHA6IHRydWUsXG4gICdmdHA6JzogdHJ1ZSxcbiAgZ29waGVyOiB0cnVlLFxuICAnZ29waGVyOic6IHRydWUsXG4gIGZpbGU6IHRydWUsXG4gICdmaWxlOic6IHRydWUsXG59O1xuY29uc3QgcXVlcnlzdHJpbmcgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpO1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogaW1wcm92ZSBjb3ZlcmFnZSAqL1xuZnVuY3Rpb24gdXJsUGFyc2UodXJsLCBwYXJzZVF1ZXJ5U3RyaW5nLCBzbGFzaGVzRGVub3RlSG9zdCkge1xuICBpZiAodXJsIGluc3RhbmNlb2YgVXJsKSByZXR1cm4gdXJsO1xuXG4gIHZhciB1ID0gbmV3IFVybCgpO1xuICB1LnBhcnNlKHVybCwgcGFyc2VRdWVyeVN0cmluZywgc2xhc2hlc0Rlbm90ZUhvc3QpO1xuICByZXR1cm4gdTtcbn1cblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cblVybC5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbiAodXJsLCBwYXJzZVF1ZXJ5U3RyaW5nLCBzbGFzaGVzRGVub3RlSG9zdCkge1xuICBpZiAodHlwZW9mIHVybCAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdQYXJhbWV0ZXIgXCJ1cmxcIiBtdXN0IGJlIGEgc3RyaW5nLCBub3QgJyArIHR5cGVvZiB1cmwpO1xuICB9XG5cbiAgLy8gQ29weSBjaHJvbWUsIElFLCBvcGVyYSBiYWNrc2xhc2gtaGFuZGxpbmcgYmVoYXZpb3IuXG4gIC8vIEJhY2sgc2xhc2hlcyBiZWZvcmUgdGhlIHF1ZXJ5IHN0cmluZyBnZXQgY29udmVydGVkIHRvIGZvcndhcmQgc2xhc2hlc1xuICAvLyBTZWU6IGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD0yNTkxNlxuICB2YXIgaGFzSGFzaCA9IGZhbHNlO1xuICB2YXIgc3RhcnQgPSAtMTtcbiAgdmFyIGVuZCA9IC0xO1xuICB2YXIgcmVzdCA9ICcnO1xuICB2YXIgbGFzdFBvcyA9IDA7XG4gIHZhciBpID0gMDtcbiAgZm9yICh2YXIgaW5XcyA9IGZhbHNlLCBzcGxpdCA9IGZhbHNlOyBpIDwgdXJsLmxlbmd0aDsgKytpKSB7XG4gICAgY29uc3QgY29kZSA9IHVybC5jaGFyQ29kZUF0KGkpO1xuXG4gICAgLy8gRmluZCBmaXJzdCBhbmQgbGFzdCBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXJzIGZvciB0cmltbWluZ1xuICAgIGNvbnN0IGlzV3MgPVxuICAgICAgY29kZSA9PT0gMzIgLyogKi8gfHxcbiAgICAgIGNvZGUgPT09IDkgLypcXHQqLyB8fFxuICAgICAgY29kZSA9PT0gMTMgLypcXHIqLyB8fFxuICAgICAgY29kZSA9PT0gMTAgLypcXG4qLyB8fFxuICAgICAgY29kZSA9PT0gMTIgLypcXGYqLyB8fFxuICAgICAgY29kZSA9PT0gMTYwIC8qXFx1MDBBMCovIHx8XG4gICAgICBjb2RlID09PSA2NTI3OTsgLypcXHVGRUZGKi9cbiAgICBpZiAoc3RhcnQgPT09IC0xKSB7XG4gICAgICBpZiAoaXNXcykgY29udGludWU7XG4gICAgICBsYXN0UG9zID0gc3RhcnQgPSBpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaW5Xcykge1xuICAgICAgICBpZiAoIWlzV3MpIHtcbiAgICAgICAgICBlbmQgPSAtMTtcbiAgICAgICAgICBpbldzID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoaXNXcykge1xuICAgICAgICBlbmQgPSBpO1xuICAgICAgICBpbldzID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBPbmx5IGNvbnZlcnQgYmFja3NsYXNoZXMgd2hpbGUgd2UgaGF2ZW4ndCBzZWVuIGEgc3BsaXQgY2hhcmFjdGVyXG4gICAgaWYgKCFzcGxpdCkge1xuICAgICAgc3dpdGNoIChjb2RlKSB7XG4gICAgICAgIGNhc2UgMzU6IC8vICcjJ1xuICAgICAgICAgIGhhc0hhc2ggPSB0cnVlO1xuICAgICAgICAvLyBGYWxsIHRocm91Z2hcbiAgICAgICAgY2FzZSA2MzogLy8gJz8nXG4gICAgICAgICAgc3BsaXQgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDkyOiAvLyAnXFxcXCdcbiAgICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSByZXN0ICs9IHVybC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgICByZXN0ICs9ICcvJztcbiAgICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghaGFzSGFzaCAmJiBjb2RlID09PSAzNSAvKiMqLykge1xuICAgICAgaGFzSGFzaCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgLy8gQ2hlY2sgaWYgc3RyaW5nIHdhcyBub24tZW1wdHkgKGluY2x1ZGluZyBzdHJpbmdzIHdpdGggb25seSB3aGl0ZXNwYWNlKVxuICBpZiAoc3RhcnQgIT09IC0xKSB7XG4gICAgaWYgKGxhc3RQb3MgPT09IHN0YXJ0KSB7XG4gICAgICAvLyBXZSBkaWRuJ3QgY29udmVydCBhbnkgYmFja3NsYXNoZXNcblxuICAgICAgaWYgKGVuZCA9PT0gLTEpIHtcbiAgICAgICAgaWYgKHN0YXJ0ID09PSAwKSByZXN0ID0gdXJsO1xuICAgICAgICBlbHNlIHJlc3QgPSB1cmwuc2xpY2Uoc3RhcnQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdCA9IHVybC5zbGljZShzdGFydCwgZW5kKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGVuZCA9PT0gLTEgJiYgbGFzdFBvcyA8IHVybC5sZW5ndGgpIHtcbiAgICAgIC8vIFdlIGNvbnZlcnRlZCBzb21lIGJhY2tzbGFzaGVzIGFuZCBoYXZlIG9ubHkgcGFydCBvZiB0aGUgZW50aXJlIHN0cmluZ1xuICAgICAgcmVzdCArPSB1cmwuc2xpY2UobGFzdFBvcyk7XG4gICAgfSBlbHNlIGlmIChlbmQgIT09IC0xICYmIGxhc3RQb3MgPCBlbmQpIHtcbiAgICAgIC8vIFdlIGNvbnZlcnRlZCBzb21lIGJhY2tzbGFzaGVzIGFuZCBoYXZlIG9ubHkgcGFydCBvZiB0aGUgZW50aXJlIHN0cmluZ1xuICAgICAgcmVzdCArPSB1cmwuc2xpY2UobGFzdFBvcywgZW5kKTtcbiAgICB9XG4gIH1cblxuICBpZiAoIXNsYXNoZXNEZW5vdGVIb3N0ICYmICFoYXNIYXNoKSB7XG4gICAgLy8gVHJ5IGZhc3QgcGF0aCByZWdleHBcbiAgICBjb25zdCBzaW1wbGVQYXRoID0gc2ltcGxlUGF0aFBhdHRlcm4uZXhlYyhyZXN0KTtcbiAgICBpZiAoc2ltcGxlUGF0aCkge1xuICAgICAgdGhpcy5wYXRoID0gcmVzdDtcbiAgICAgIHRoaXMuaHJlZiA9IHJlc3Q7XG4gICAgICB0aGlzLnBhdGhuYW1lID0gc2ltcGxlUGF0aFsxXTtcbiAgICAgIGlmIChzaW1wbGVQYXRoWzJdKSB7XG4gICAgICAgIHRoaXMuc2VhcmNoID0gc2ltcGxlUGF0aFsyXTtcbiAgICAgICAgaWYgKHBhcnNlUXVlcnlTdHJpbmcpIHtcbiAgICAgICAgICB0aGlzLnF1ZXJ5ID0gcXVlcnlzdHJpbmcucGFyc2UodGhpcy5zZWFyY2guc2xpY2UoMSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMucXVlcnkgPSB0aGlzLnNlYXJjaC5zbGljZSgxKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChwYXJzZVF1ZXJ5U3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc2VhcmNoID0gJyc7XG4gICAgICAgIHRoaXMucXVlcnkgPSB7fTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgfVxuXG4gIHZhciBwcm90byA9IHByb3RvY29sUGF0dGVybi5leGVjKHJlc3QpO1xuICBpZiAocHJvdG8pIHtcbiAgICBwcm90byA9IHByb3RvWzBdO1xuICAgIHZhciBsb3dlclByb3RvID0gcHJvdG8udG9Mb3dlckNhc2UoKTtcbiAgICB0aGlzLnByb3RvY29sID0gbG93ZXJQcm90bztcbiAgICByZXN0ID0gcmVzdC5zbGljZShwcm90by5sZW5ndGgpO1xuICB9XG5cbiAgLy8gZmlndXJlIG91dCBpZiBpdCdzIGdvdCBhIGhvc3RcbiAgLy8gdXNlckBzZXJ2ZXIgaXMgKmFsd2F5cyogaW50ZXJwcmV0ZWQgYXMgYSBob3N0bmFtZSwgYW5kIHVybFxuICAvLyByZXNvbHV0aW9uIHdpbGwgdHJlYXQgLy9mb28vYmFyIGFzIGhvc3Q9Zm9vLHBhdGg9YmFyIGJlY2F1c2UgdGhhdCdzXG4gIC8vIGhvdyB0aGUgYnJvd3NlciByZXNvbHZlcyByZWxhdGl2ZSBVUkxzLlxuICBpZiAoc2xhc2hlc0Rlbm90ZUhvc3QgfHwgcHJvdG8gfHwgL15cXC9cXC9bXkBcXC9dK0BbXkBcXC9dKy8udGVzdChyZXN0KSkge1xuICAgIHZhciBzbGFzaGVzID0gcmVzdC5jaGFyQ29kZUF0KDApID09PSA0NyAvKi8qLyAmJiByZXN0LmNoYXJDb2RlQXQoMSkgPT09IDQ3OyAvKi8qL1xuICAgIGlmIChzbGFzaGVzICYmICEocHJvdG8gJiYgaG9zdGxlc3NQcm90b2NvbFtwcm90b10pKSB7XG4gICAgICByZXN0ID0gcmVzdC5zbGljZSgyKTtcbiAgICAgIHRoaXMuc2xhc2hlcyA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgaWYgKCFob3N0bGVzc1Byb3RvY29sW3Byb3RvXSAmJiAoc2xhc2hlcyB8fCAocHJvdG8gJiYgIXNsYXNoZWRQcm90b2NvbFtwcm90b10pKSkge1xuICAgIC8vIHRoZXJlJ3MgYSBob3N0bmFtZS5cbiAgICAvLyB0aGUgZmlyc3QgaW5zdGFuY2Ugb2YgLywgPywgOywgb3IgIyBlbmRzIHRoZSBob3N0LlxuICAgIC8vXG4gICAgLy8gSWYgdGhlcmUgaXMgYW4gQCBpbiB0aGUgaG9zdG5hbWUsIHRoZW4gbm9uLWhvc3QgY2hhcnMgKmFyZSogYWxsb3dlZFxuICAgIC8vIHRvIHRoZSBsZWZ0IG9mIHRoZSBsYXN0IEAgc2lnbiwgdW5sZXNzIHNvbWUgaG9zdC1lbmRpbmcgY2hhcmFjdGVyXG4gICAgLy8gY29tZXMgKmJlZm9yZSogdGhlIEAtc2lnbi5cbiAgICAvLyBVUkxzIGFyZSBvYm5veGlvdXMuXG4gICAgLy9cbiAgICAvLyBleDpcbiAgICAvLyBodHRwOi8vYUBiQGMvID0+IHVzZXI6YUBiIGhvc3Q6Y1xuICAgIC8vIGh0dHA6Ly9hQGI/QGMgPT4gdXNlcjphIGhvc3Q6YiBwYXRoOi8/QGNcblxuICAgIC8vIHYwLjEyIFRPRE8oaXNhYWNzKTogVGhpcyBpcyBub3QgcXVpdGUgaG93IENocm9tZSBkb2VzIHRoaW5ncy5cbiAgICAvLyBSZXZpZXcgb3VyIHRlc3QgY2FzZSBhZ2FpbnN0IGJyb3dzZXJzIG1vcmUgY29tcHJlaGVuc2l2ZWx5LlxuXG4gICAgdmFyIGhvc3RFbmQgPSAtMTtcbiAgICB2YXIgYXRTaWduID0gLTE7XG4gICAgdmFyIG5vbkhvc3QgPSAtMTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgcmVzdC5sZW5ndGg7ICsraSkge1xuICAgICAgc3dpdGNoIChyZXN0LmNoYXJDb2RlQXQoaSkpIHtcbiAgICAgICAgY2FzZSA5OiAvLyAnXFx0J1xuICAgICAgICBjYXNlIDEwOiAvLyAnXFxuJ1xuICAgICAgICBjYXNlIDEzOiAvLyAnXFxyJ1xuICAgICAgICBjYXNlIDMyOiAvLyAnICdcbiAgICAgICAgY2FzZSAzNDogLy8gJ1wiJ1xuICAgICAgICBjYXNlIDM3OiAvLyAnJSdcbiAgICAgICAgY2FzZSAzOTogLy8gJ1xcJydcbiAgICAgICAgY2FzZSA1OTogLy8gJzsnXG4gICAgICAgIGNhc2UgNjA6IC8vICc8J1xuICAgICAgICBjYXNlIDYyOiAvLyAnPidcbiAgICAgICAgY2FzZSA5MjogLy8gJ1xcXFwnXG4gICAgICAgIGNhc2UgOTQ6IC8vICdeJ1xuICAgICAgICBjYXNlIDk2OiAvLyAnYCdcbiAgICAgICAgY2FzZSAxMjM6IC8vICd7J1xuICAgICAgICBjYXNlIDEyNDogLy8gJ3wnXG4gICAgICAgIGNhc2UgMTI1OiAvLyAnfSdcbiAgICAgICAgICAvLyBDaGFyYWN0ZXJzIHRoYXQgYXJlIG5ldmVyIGV2ZXIgYWxsb3dlZCBpbiBhIGhvc3RuYW1lIGZyb20gUkZDIDIzOTZcbiAgICAgICAgICBpZiAobm9uSG9zdCA9PT0gLTEpIG5vbkhvc3QgPSBpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDM1OiAvLyAnIydcbiAgICAgICAgY2FzZSA0NzogLy8gJy8nXG4gICAgICAgIGNhc2UgNjM6IC8vICc/J1xuICAgICAgICAgIC8vIEZpbmQgdGhlIGZpcnN0IGluc3RhbmNlIG9mIGFueSBob3N0LWVuZGluZyBjaGFyYWN0ZXJzXG4gICAgICAgICAgaWYgKG5vbkhvc3QgPT09IC0xKSBub25Ib3N0ID0gaTtcbiAgICAgICAgICBob3N0RW5kID0gaTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSA2NDogLy8gJ0AnXG4gICAgICAgICAgLy8gQXQgdGhpcyBwb2ludCwgZWl0aGVyIHdlIGhhdmUgYW4gZXhwbGljaXQgcG9pbnQgd2hlcmUgdGhlXG4gICAgICAgICAgLy8gYXV0aCBwb3J0aW9uIGNhbm5vdCBnbyBwYXN0LCBvciB0aGUgbGFzdCBAIGNoYXIgaXMgdGhlIGRlY2lkZXIuXG4gICAgICAgICAgYXRTaWduID0gaTtcbiAgICAgICAgICBub25Ib3N0ID0gLTE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAoaG9zdEVuZCAhPT0gLTEpIGJyZWFrO1xuICAgIH1cbiAgICBzdGFydCA9IDA7XG4gICAgaWYgKGF0U2lnbiAhPT0gLTEpIHtcbiAgICAgIHRoaXMuYXV0aCA9IGRlY29kZVVSSUNvbXBvbmVudChyZXN0LnNsaWNlKDAsIGF0U2lnbikpO1xuICAgICAgc3RhcnQgPSBhdFNpZ24gKyAxO1xuICAgIH1cbiAgICBpZiAobm9uSG9zdCA9PT0gLTEpIHtcbiAgICAgIHRoaXMuaG9zdCA9IHJlc3Quc2xpY2Uoc3RhcnQpO1xuICAgICAgcmVzdCA9ICcnO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmhvc3QgPSByZXN0LnNsaWNlKHN0YXJ0LCBub25Ib3N0KTtcbiAgICAgIHJlc3QgPSByZXN0LnNsaWNlKG5vbkhvc3QpO1xuICAgIH1cblxuICAgIC8vIHB1bGwgb3V0IHBvcnQuXG4gICAgdGhpcy5wYXJzZUhvc3QoKTtcblxuICAgIC8vIHdlJ3ZlIGluZGljYXRlZCB0aGF0IHRoZXJlIGlzIGEgaG9zdG5hbWUsXG4gICAgLy8gc28gZXZlbiBpZiBpdCdzIGVtcHR5LCBpdCBoYXMgdG8gYmUgcHJlc2VudC5cbiAgICBpZiAodHlwZW9mIHRoaXMuaG9zdG5hbWUgIT09ICdzdHJpbmcnKSB0aGlzLmhvc3RuYW1lID0gJyc7XG5cbiAgICB2YXIgaG9zdG5hbWUgPSB0aGlzLmhvc3RuYW1lO1xuXG4gICAgLy8gaWYgaG9zdG5hbWUgYmVnaW5zIHdpdGggWyBhbmQgZW5kcyB3aXRoIF1cbiAgICAvLyBhc3N1bWUgdGhhdCBpdCdzIGFuIElQdjYgYWRkcmVzcy5cbiAgICB2YXIgaXB2Nkhvc3RuYW1lID1cbiAgICAgIGhvc3RuYW1lLmNoYXJDb2RlQXQoMCkgPT09IDkxIC8qWyovICYmIGhvc3RuYW1lLmNoYXJDb2RlQXQoaG9zdG5hbWUubGVuZ3RoIC0gMSkgPT09IDkzOyAvKl0qL1xuXG4gICAgLy8gdmFsaWRhdGUgYSBsaXR0bGUuXG4gICAgaWYgKCFpcHY2SG9zdG5hbWUpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHZhbGlkYXRlSG9zdG5hbWUodGhpcywgcmVzdCwgaG9zdG5hbWUpO1xuICAgICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSByZXN0ID0gcmVzdWx0O1xuICAgIH1cblxuICAgIC8vIGhvc3RuYW1lcyBhcmUgYWx3YXlzIGxvd2VyIGNhc2UuXG4gICAgdGhpcy5ob3N0bmFtZSA9IHRoaXMuaG9zdG5hbWUudG9Mb3dlckNhc2UoKTtcblxuICAgIGlmICghaXB2Nkhvc3RuYW1lKSB7XG4gICAgICAvLyBJRE5BIFN1cHBvcnQ6IFJldHVybnMgYSBwdW55Y29kZWQgcmVwcmVzZW50YXRpb24gb2YgXCJkb21haW5cIi5cbiAgICAgIC8vIEl0IG9ubHkgY29udmVydHMgcGFydHMgb2YgdGhlIGRvbWFpbiBuYW1lIHRoYXRcbiAgICAgIC8vIGhhdmUgbm9uLUFTQ0lJIGNoYXJhY3RlcnMsIGkuZS4gaXQgZG9lc24ndCBtYXR0ZXIgaWZcbiAgICAgIC8vIHlvdSBjYWxsIGl0IHdpdGggYSBkb21haW4gdGhhdCBhbHJlYWR5IGlzIEFTQ0lJLW9ubHkuXG4gICAgICB0aGlzLmhvc3RuYW1lID0gcHVueWNvZGUudG9BU0NJSSh0aGlzLmhvc3RuYW1lKTtcbiAgICB9XG5cbiAgICB2YXIgcCA9IHRoaXMucG9ydCA/ICc6JyArIHRoaXMucG9ydCA6ICcnO1xuICAgIHZhciBoID0gdGhpcy5ob3N0bmFtZSB8fCAnJztcbiAgICB0aGlzLmhvc3QgPSBoICsgcDtcblxuICAgIC8vIHN0cmlwIFsgYW5kIF0gZnJvbSB0aGUgaG9zdG5hbWVcbiAgICAvLyB0aGUgaG9zdCBmaWVsZCBzdGlsbCByZXRhaW5zIHRoZW0sIHRob3VnaFxuICAgIGlmIChpcHY2SG9zdG5hbWUpIHtcbiAgICAgIHRoaXMuaG9zdG5hbWUgPSB0aGlzLmhvc3RuYW1lLnNsaWNlKDEsIC0xKTtcbiAgICAgIGlmIChyZXN0WzBdICE9PSAnLycpIHtcbiAgICAgICAgcmVzdCA9ICcvJyArIHJlc3Q7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gbm93IHJlc3QgaXMgc2V0IHRvIHRoZSBwb3N0LWhvc3Qgc3R1ZmYuXG4gIC8vIGNob3Agb2ZmIGFueSBkZWxpbSBjaGFycy5cbiAgaWYgKCF1bnNhZmVQcm90b2NvbFtsb3dlclByb3RvXSkge1xuICAgIC8vIEZpcnN0LCBtYWtlIDEwMCUgc3VyZSB0aGF0IGFueSBcImF1dG9Fc2NhcGVcIiBjaGFycyBnZXRcbiAgICAvLyBlc2NhcGVkLCBldmVuIGlmIGVuY29kZVVSSUNvbXBvbmVudCBkb2Vzbid0IHRoaW5rIHRoZXlcbiAgICAvLyBuZWVkIHRvIGJlLlxuICAgIGNvbnN0IHJlc3VsdCA9IGF1dG9Fc2NhcGVTdHIocmVzdCk7XG4gICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSByZXN0ID0gcmVzdWx0O1xuICB9XG5cbiAgdmFyIHF1ZXN0aW9uSWR4ID0gLTE7XG4gIHZhciBoYXNoSWR4ID0gLTE7XG4gIGZvciAoaSA9IDA7IGkgPCByZXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgY29uc3QgY29kZSA9IHJlc3QuY2hhckNvZGVBdChpKTtcbiAgICBpZiAoY29kZSA9PT0gMzUgLyojKi8pIHtcbiAgICAgIHRoaXMuaGFzaCA9IHJlc3Quc2xpY2UoaSk7XG4gICAgICBoYXNoSWR4ID0gaTtcbiAgICAgIGJyZWFrO1xuICAgIH0gZWxzZSBpZiAoY29kZSA9PT0gNjMgLyo/Ki8gJiYgcXVlc3Rpb25JZHggPT09IC0xKSB7XG4gICAgICBxdWVzdGlvbklkeCA9IGk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHF1ZXN0aW9uSWR4ICE9PSAtMSkge1xuICAgIGlmIChoYXNoSWR4ID09PSAtMSkge1xuICAgICAgdGhpcy5zZWFyY2ggPSByZXN0LnNsaWNlKHF1ZXN0aW9uSWR4KTtcbiAgICAgIHRoaXMucXVlcnkgPSByZXN0LnNsaWNlKHF1ZXN0aW9uSWR4ICsgMSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2VhcmNoID0gcmVzdC5zbGljZShxdWVzdGlvbklkeCwgaGFzaElkeCk7XG4gICAgICB0aGlzLnF1ZXJ5ID0gcmVzdC5zbGljZShxdWVzdGlvbklkeCArIDEsIGhhc2hJZHgpO1xuICAgIH1cbiAgICBpZiAocGFyc2VRdWVyeVN0cmluZykge1xuICAgICAgdGhpcy5xdWVyeSA9IHF1ZXJ5c3RyaW5nLnBhcnNlKHRoaXMucXVlcnkpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChwYXJzZVF1ZXJ5U3RyaW5nKSB7XG4gICAgLy8gbm8gcXVlcnkgc3RyaW5nLCBidXQgcGFyc2VRdWVyeVN0cmluZyBzdGlsbCByZXF1ZXN0ZWRcbiAgICB0aGlzLnNlYXJjaCA9ICcnO1xuICAgIHRoaXMucXVlcnkgPSB7fTtcbiAgfVxuXG4gIHZhciBmaXJzdElkeCA9XG4gICAgcXVlc3Rpb25JZHggIT09IC0xICYmIChoYXNoSWR4ID09PSAtMSB8fCBxdWVzdGlvbklkeCA8IGhhc2hJZHgpID8gcXVlc3Rpb25JZHggOiBoYXNoSWR4O1xuICBpZiAoZmlyc3RJZHggPT09IC0xKSB7XG4gICAgaWYgKHJlc3QubGVuZ3RoID4gMCkgdGhpcy5wYXRobmFtZSA9IHJlc3Q7XG4gIH0gZWxzZSBpZiAoZmlyc3RJZHggPiAwKSB7XG4gICAgdGhpcy5wYXRobmFtZSA9IHJlc3Quc2xpY2UoMCwgZmlyc3RJZHgpO1xuICB9XG4gIGlmIChzbGFzaGVkUHJvdG9jb2xbbG93ZXJQcm90b10gJiYgdGhpcy5ob3N0bmFtZSAmJiAhdGhpcy5wYXRobmFtZSkge1xuICAgIHRoaXMucGF0aG5hbWUgPSAnLyc7XG4gIH1cblxuICAvLyB0byBzdXBwb3J0IGh0dHAucmVxdWVzdFxuICBpZiAodGhpcy5wYXRobmFtZSB8fCB0aGlzLnNlYXJjaCkge1xuICAgIGNvbnN0IHAgPSB0aGlzLnBhdGhuYW1lIHx8ICcnO1xuICAgIGNvbnN0IHMgPSB0aGlzLnNlYXJjaCB8fCAnJztcbiAgICB0aGlzLnBhdGggPSBwICsgcztcbiAgfVxuXG4gIC8vIGZpbmFsbHksIHJlY29uc3RydWN0IHRoZSBocmVmIGJhc2VkIG9uIHdoYXQgaGFzIGJlZW4gdmFsaWRhdGVkLlxuICB0aGlzLmhyZWYgPSB0aGlzLmZvcm1hdCgpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5mdW5jdGlvbiB2YWxpZGF0ZUhvc3RuYW1lKHNlbGYsIHJlc3QsIGhvc3RuYW1lKSB7XG4gIGZvciAodmFyIGkgPSAwLCBsYXN0UG9zOyBpIDw9IGhvc3RuYW1lLmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIGNvZGU7XG4gICAgaWYgKGkgPCBob3N0bmFtZS5sZW5ndGgpIGNvZGUgPSBob3N0bmFtZS5jaGFyQ29kZUF0KGkpO1xuICAgIGlmIChjb2RlID09PSA0NiAvKi4qLyB8fCBpID09PSBob3N0bmFtZS5sZW5ndGgpIHtcbiAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIHtcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gNjMpIHtcbiAgICAgICAgICBzZWxmLmhvc3RuYW1lID0gaG9zdG5hbWUuc2xpY2UoMCwgbGFzdFBvcyArIDYzKTtcbiAgICAgICAgICByZXR1cm4gJy8nICsgaG9zdG5hbWUuc2xpY2UobGFzdFBvcyArIDYzKSArIHJlc3Q7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICAoY29kZSA+PSA0OCAvKjAqLyAmJiBjb2RlIDw9IDU3KSAvKjkqLyB8fFxuICAgICAgKGNvZGUgPj0gOTcgLyphKi8gJiYgY29kZSA8PSAxMjIpIC8qeiovIHx8XG4gICAgICBjb2RlID09PSA0NSAvKi0qLyB8fFxuICAgICAgKGNvZGUgPj0gNjUgLypBKi8gJiYgY29kZSA8PSA5MCkgLypaKi8gfHxcbiAgICAgIGNvZGUgPT09IDQzIC8qKyovIHx8XG4gICAgICBjb2RlID09PSA5NSAvKl8qLyB8fFxuICAgICAgLyogQkVHSU4gTU9OR08gVVJJIFBBVENIICovXG4gICAgICBjb2RlID09PSA0NCAvKiwqLyB8fFxuICAgICAgY29kZSA9PT0gNTggLyo6Ki8gfHxcbiAgICAgIC8qIEVORCBNT05HTyBVUkkgUEFUQ0ggKi9cbiAgICAgIGNvZGUgPiAxMjdcbiAgICApIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICAvLyBJbnZhbGlkIGhvc3QgY2hhcmFjdGVyXG4gICAgc2VsZi5ob3N0bmFtZSA9IGhvc3RuYW1lLnNsaWNlKDAsIGkpO1xuICAgIGlmIChpIDwgaG9zdG5hbWUubGVuZ3RoKSByZXR1cm4gJy8nICsgaG9zdG5hbWUuc2xpY2UoaSkgKyByZXN0O1xuICAgIGJyZWFrO1xuICB9XG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5mdW5jdGlvbiBhdXRvRXNjYXBlU3RyKHJlc3QpIHtcbiAgdmFyIG5ld1Jlc3QgPSAnJztcbiAgdmFyIGxhc3RQb3MgPSAwO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHJlc3QubGVuZ3RoOyArK2kpIHtcbiAgICAvLyBBdXRvbWF0aWNhbGx5IGVzY2FwZSBhbGwgZGVsaW1pdGVycyBhbmQgdW53aXNlIGNoYXJhY3RlcnMgZnJvbSBSRkMgMjM5NlxuICAgIC8vIEFsc28gZXNjYXBlIHNpbmdsZSBxdW90ZXMgaW4gY2FzZSBvZiBhbiBYU1MgYXR0YWNrXG4gICAgc3dpdGNoIChyZXN0LmNoYXJDb2RlQXQoaSkpIHtcbiAgICAgIGNhc2UgOTogLy8gJ1xcdCdcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMDknO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxMDogLy8gJ1xcbidcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMEEnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxMzogLy8gJ1xccidcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMEQnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzMjogLy8gJyAnXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1Jlc3QgKz0gcmVzdC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UmVzdCArPSAnJTIwJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzQ6IC8vICdcIidcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMjInO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOTogLy8gJ1xcJydcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMjcnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA2MDogLy8gJzwnXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1Jlc3QgKz0gcmVzdC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UmVzdCArPSAnJTNDJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNjI6IC8vICc+J1xuICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBuZXdSZXN0ICs9IHJlc3Quc2xpY2UobGFzdFBvcywgaSk7XG4gICAgICAgIG5ld1Jlc3QgKz0gJyUzRSc7XG4gICAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDkyOiAvLyAnXFxcXCdcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclNUMnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA5NDogLy8gJ14nXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1Jlc3QgKz0gcmVzdC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UmVzdCArPSAnJTVFJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgOTY6IC8vICdgJ1xuICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBuZXdSZXN0ICs9IHJlc3Quc2xpY2UobGFzdFBvcywgaSk7XG4gICAgICAgIG5ld1Jlc3QgKz0gJyU2MCc7XG4gICAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDEyMzogLy8gJ3snXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1Jlc3QgKz0gcmVzdC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UmVzdCArPSAnJTdCJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTI0OiAvLyAnfCdcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclN0MnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxMjU6IC8vICd9J1xuICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBuZXdSZXN0ICs9IHJlc3Quc2xpY2UobGFzdFBvcywgaSk7XG4gICAgICAgIG5ld1Jlc3QgKz0gJyU3RCc7XG4gICAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmIChsYXN0UG9zID09PSAwKSByZXR1cm47XG4gIGlmIChsYXN0UG9zIDwgcmVzdC5sZW5ndGgpIHJldHVybiBuZXdSZXN0ICsgcmVzdC5zbGljZShsYXN0UG9zKTtcbiAgZWxzZSByZXR1cm4gbmV3UmVzdDtcbn1cblxuLy8gZm9ybWF0IGEgcGFyc2VkIG9iamVjdCBpbnRvIGEgdXJsIHN0cmluZ1xuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cbmZ1bmN0aW9uIHVybEZvcm1hdChvYmopIHtcbiAgLy8gZW5zdXJlIGl0J3MgYW4gb2JqZWN0LCBhbmQgbm90IGEgc3RyaW5nIHVybC5cbiAgLy8gSWYgaXQncyBhbiBvYmosIHRoaXMgaXMgYSBuby1vcC5cbiAgLy8gdGhpcyB3YXksIHlvdSBjYW4gY2FsbCB1cmxfZm9ybWF0KCkgb24gc3RyaW5nc1xuICAvLyB0byBjbGVhbiB1cCBwb3RlbnRpYWxseSB3b25reSB1cmxzLlxuICBpZiAodHlwZW9mIG9iaiA9PT0gJ3N0cmluZycpIG9iaiA9IHVybFBhcnNlKG9iaik7XG4gIGVsc2UgaWYgKHR5cGVvZiBvYmogIT09ICdvYmplY3QnIHx8IG9iaiA9PT0gbnVsbClcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgJ1BhcmFtZXRlciBcInVybE9ialwiIG11c3QgYmUgYW4gb2JqZWN0LCBub3QgJyArIG9iaiA9PT0gbnVsbCA/ICdudWxsJyA6IHR5cGVvZiBvYmpcbiAgICApO1xuICBlbHNlIGlmICghKG9iaiBpbnN0YW5jZW9mIFVybCkpIHJldHVybiBVcmwucHJvdG90eXBlLmZvcm1hdC5jYWxsKG9iaik7XG5cbiAgcmV0dXJuIG9iai5mb3JtYXQoKTtcbn1cblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cblVybC5wcm90b3R5cGUuZm9ybWF0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgYXV0aCA9IHRoaXMuYXV0aCB8fCAnJztcbiAgaWYgKGF1dGgpIHtcbiAgICBhdXRoID0gZW5jb2RlQXV0aChhdXRoKTtcbiAgICBhdXRoICs9ICdAJztcbiAgfVxuXG4gIHZhciBwcm90b2NvbCA9IHRoaXMucHJvdG9jb2wgfHwgJyc7XG4gIHZhciBwYXRobmFtZSA9IHRoaXMucGF0aG5hbWUgfHwgJyc7XG4gIHZhciBoYXNoID0gdGhpcy5oYXNoIHx8ICcnO1xuICB2YXIgaG9zdCA9IGZhbHNlO1xuICB2YXIgcXVlcnkgPSAnJztcblxuICBpZiAodGhpcy5ob3N0KSB7XG4gICAgaG9zdCA9IGF1dGggKyB0aGlzLmhvc3Q7XG4gIH0gZWxzZSBpZiAodGhpcy5ob3N0bmFtZSkge1xuICAgIGhvc3QgPSBhdXRoICsgKHRoaXMuaG9zdG5hbWUuaW5kZXhPZignOicpID09PSAtMSA/IHRoaXMuaG9zdG5hbWUgOiAnWycgKyB0aGlzLmhvc3RuYW1lICsgJ10nKTtcbiAgICBpZiAodGhpcy5wb3J0KSB7XG4gICAgICBob3N0ICs9ICc6JyArIHRoaXMucG9ydDtcbiAgICB9XG4gIH1cblxuICBpZiAodGhpcy5xdWVyeSAhPT0gbnVsbCAmJiB0eXBlb2YgdGhpcy5xdWVyeSA9PT0gJ29iamVjdCcpXG4gICAgcXVlcnkgPSBxdWVyeXN0cmluZy5zdHJpbmdpZnkodGhpcy5xdWVyeSk7XG5cbiAgdmFyIHNlYXJjaCA9IHRoaXMuc2VhcmNoIHx8IChxdWVyeSAmJiAnPycgKyBxdWVyeSkgfHwgJyc7XG5cbiAgaWYgKHByb3RvY29sICYmIHByb3RvY29sLmNoYXJDb2RlQXQocHJvdG9jb2wubGVuZ3RoIC0gMSkgIT09IDU4IC8qOiovKSBwcm90b2NvbCArPSAnOic7XG5cbiAgdmFyIG5ld1BhdGhuYW1lID0gJyc7XG4gIHZhciBsYXN0UG9zID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYXRobmFtZS5sZW5ndGg7ICsraSkge1xuICAgIHN3aXRjaCAocGF0aG5hbWUuY2hhckNvZGVBdChpKSkge1xuICAgICAgY2FzZSAzNTogLy8gJyMnXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1BhdGhuYW1lICs9IHBhdGhuYW1lLnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdQYXRobmFtZSArPSAnJTIzJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNjM6IC8vICc/J1xuICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBuZXdQYXRobmFtZSArPSBwYXRobmFtZS5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UGF0aG5hbWUgKz0gJyUzRic7XG4gICAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmIChsYXN0UG9zID4gMCkge1xuICAgIGlmIChsYXN0UG9zICE9PSBwYXRobmFtZS5sZW5ndGgpIHBhdGhuYW1lID0gbmV3UGF0aG5hbWUgKyBwYXRobmFtZS5zbGljZShsYXN0UG9zKTtcbiAgICBlbHNlIHBhdGhuYW1lID0gbmV3UGF0aG5hbWU7XG4gIH1cblxuICAvLyBvbmx5IHRoZSBzbGFzaGVkUHJvdG9jb2xzIGdldCB0aGUgLy8uICBOb3QgbWFpbHRvOiwgeG1wcDosIGV0Yy5cbiAgLy8gdW5sZXNzIHRoZXkgaGFkIHRoZW0gdG8gYmVnaW4gd2l0aC5cbiAgaWYgKHRoaXMuc2xhc2hlcyB8fCAoKCFwcm90b2NvbCB8fCBzbGFzaGVkUHJvdG9jb2xbcHJvdG9jb2xdKSAmJiBob3N0ICE9PSBmYWxzZSkpIHtcbiAgICBob3N0ID0gJy8vJyArIChob3N0IHx8ICcnKTtcbiAgICBpZiAocGF0aG5hbWUgJiYgcGF0aG5hbWUuY2hhckNvZGVBdCgwKSAhPT0gNDcgLyovKi8pIHBhdGhuYW1lID0gJy8nICsgcGF0aG5hbWU7XG4gIH0gZWxzZSBpZiAoIWhvc3QpIHtcbiAgICBob3N0ID0gJyc7XG4gIH1cblxuICBzZWFyY2ggPSBzZWFyY2gucmVwbGFjZSgnIycsICclMjMnKTtcblxuICBpZiAoaGFzaCAmJiBoYXNoLmNoYXJDb2RlQXQoMCkgIT09IDM1IC8qIyovKSBoYXNoID0gJyMnICsgaGFzaDtcbiAgaWYgKHNlYXJjaCAmJiBzZWFyY2guY2hhckNvZGVBdCgwKSAhPT0gNjMgLyo/Ki8pIHNlYXJjaCA9ICc/JyArIHNlYXJjaDtcblxuICByZXR1cm4gcHJvdG9jb2wgKyBob3N0ICsgcGF0aG5hbWUgKyBzZWFyY2ggKyBoYXNoO1xufTtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cbmZ1bmN0aW9uIHVybFJlc29sdmUoc291cmNlLCByZWxhdGl2ZSkge1xuICByZXR1cm4gdXJsUGFyc2Uoc291cmNlLCBmYWxzZSwgdHJ1ZSkucmVzb2x2ZShyZWxhdGl2ZSk7XG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5VcmwucHJvdG90eXBlLnJlc29sdmUgPSBmdW5jdGlvbiAocmVsYXRpdmUpIHtcbiAgcmV0dXJuIHRoaXMucmVzb2x2ZU9iamVjdCh1cmxQYXJzZShyZWxhdGl2ZSwgZmFsc2UsIHRydWUpKS5mb3JtYXQoKTtcbn07XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5mdW5jdGlvbiB1cmxSZXNvbHZlT2JqZWN0KHNvdXJjZSwgcmVsYXRpdmUpIHtcbiAgaWYgKCFzb3VyY2UpIHJldHVybiByZWxhdGl2ZTtcbiAgcmV0dXJuIHVybFBhcnNlKHNvdXJjZSwgZmFsc2UsIHRydWUpLnJlc29sdmVPYmplY3QocmVsYXRpdmUpO1xufVxuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogaW1wcm92ZSBjb3ZlcmFnZSAqL1xuVXJsLnByb3RvdHlwZS5yZXNvbHZlT2JqZWN0ID0gZnVuY3Rpb24gKHJlbGF0aXZlKSB7XG4gIGlmICh0eXBlb2YgcmVsYXRpdmUgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFyIHJlbCA9IG5ldyBVcmwoKTtcbiAgICByZWwucGFyc2UocmVsYXRpdmUsIGZhbHNlLCB0cnVlKTtcbiAgICByZWxhdGl2ZSA9IHJlbDtcbiAgfVxuXG4gIHZhciByZXN1bHQgPSBuZXcgVXJsKCk7XG4gIHZhciB0a2V5cyA9IE9iamVjdC5rZXlzKHRoaXMpO1xuICBmb3IgKHZhciB0ayA9IDA7IHRrIDwgdGtleXMubGVuZ3RoOyB0aysrKSB7XG4gICAgdmFyIHRrZXkgPSB0a2V5c1t0a107XG4gICAgcmVzdWx0W3RrZXldID0gdGhpc1t0a2V5XTtcbiAgfVxuXG4gIC8vIGhhc2ggaXMgYWx3YXlzIG92ZXJyaWRkZW4sIG5vIG1hdHRlciB3aGF0LlxuICAvLyBldmVuIGhyZWY9XCJcIiB3aWxsIHJlbW92ZSBpdC5cbiAgcmVzdWx0Lmhhc2ggPSByZWxhdGl2ZS5oYXNoO1xuXG4gIC8vIGlmIHRoZSByZWxhdGl2ZSB1cmwgaXMgZW1wdHksIHRoZW4gdGhlcmUncyBub3RoaW5nIGxlZnQgdG8gZG8gaGVyZS5cbiAgaWYgKHJlbGF0aXZlLmhyZWYgPT09ICcnKSB7XG4gICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8vIGhyZWZzIGxpa2UgLy9mb28vYmFyIGFsd2F5cyBjdXQgdG8gdGhlIHByb3RvY29sLlxuICBpZiAocmVsYXRpdmUuc2xhc2hlcyAmJiAhcmVsYXRpdmUucHJvdG9jb2wpIHtcbiAgICAvLyB0YWtlIGV2ZXJ5dGhpbmcgZXhjZXB0IHRoZSBwcm90b2NvbCBmcm9tIHJlbGF0aXZlXG4gICAgdmFyIHJrZXlzID0gT2JqZWN0LmtleXMocmVsYXRpdmUpO1xuICAgIGZvciAodmFyIHJrID0gMDsgcmsgPCBya2V5cy5sZW5ndGg7IHJrKyspIHtcbiAgICAgIHZhciBya2V5ID0gcmtleXNbcmtdO1xuICAgICAgaWYgKHJrZXkgIT09ICdwcm90b2NvbCcpIHJlc3VsdFtya2V5XSA9IHJlbGF0aXZlW3JrZXldO1xuICAgIH1cblxuICAgIC8vdXJsUGFyc2UgYXBwZW5kcyB0cmFpbGluZyAvIHRvIHVybHMgbGlrZSBodHRwOi8vd3d3LmV4YW1wbGUuY29tXG4gICAgaWYgKHNsYXNoZWRQcm90b2NvbFtyZXN1bHQucHJvdG9jb2xdICYmIHJlc3VsdC5ob3N0bmFtZSAmJiAhcmVzdWx0LnBhdGhuYW1lKSB7XG4gICAgICByZXN1bHQucGF0aCA9IHJlc3VsdC5wYXRobmFtZSA9ICcvJztcbiAgICB9XG5cbiAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgaWYgKHJlbGF0aXZlLnByb3RvY29sICYmIHJlbGF0aXZlLnByb3RvY29sICE9PSByZXN1bHQucHJvdG9jb2wpIHtcbiAgICAvLyBpZiBpdCdzIGEga25vd24gdXJsIHByb3RvY29sLCB0aGVuIGNoYW5naW5nXG4gICAgLy8gdGhlIHByb3RvY29sIGRvZXMgd2VpcmQgdGhpbmdzXG4gICAgLy8gZmlyc3QsIGlmIGl0J3Mgbm90IGZpbGU6LCB0aGVuIHdlIE1VU1QgaGF2ZSBhIGhvc3QsXG4gICAgLy8gYW5kIGlmIHRoZXJlIHdhcyBhIHBhdGhcbiAgICAvLyB0byBiZWdpbiB3aXRoLCB0aGVuIHdlIE1VU1QgaGF2ZSBhIHBhdGguXG4gICAgLy8gaWYgaXQgaXMgZmlsZTosIHRoZW4gdGhlIGhvc3QgaXMgZHJvcHBlZCxcbiAgICAvLyBiZWNhdXNlIHRoYXQncyBrbm93biB0byBiZSBob3N0bGVzcy5cbiAgICAvLyBhbnl0aGluZyBlbHNlIGlzIGFzc3VtZWQgdG8gYmUgYWJzb2x1dGUuXG4gICAgaWYgKCFzbGFzaGVkUHJvdG9jb2xbcmVsYXRpdmUucHJvdG9jb2xdKSB7XG4gICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHJlbGF0aXZlKTtcbiAgICAgIGZvciAodmFyIHYgPSAwOyB2IDwga2V5cy5sZW5ndGg7IHYrKykge1xuICAgICAgICB2YXIgayA9IGtleXNbdl07XG4gICAgICAgIHJlc3VsdFtrXSA9IHJlbGF0aXZlW2tdO1xuICAgICAgfVxuICAgICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHJlc3VsdC5wcm90b2NvbCA9IHJlbGF0aXZlLnByb3RvY29sO1xuICAgIGlmIChcbiAgICAgICFyZWxhdGl2ZS5ob3N0ICYmXG4gICAgICAhL15maWxlOj8kLy50ZXN0KHJlbGF0aXZlLnByb3RvY29sKSAmJlxuICAgICAgIWhvc3RsZXNzUHJvdG9jb2xbcmVsYXRpdmUucHJvdG9jb2xdXG4gICAgKSB7XG4gICAgICBjb25zdCByZWxQYXRoID0gKHJlbGF0aXZlLnBhdGhuYW1lIHx8ICcnKS5zcGxpdCgnLycpO1xuICAgICAgd2hpbGUgKHJlbFBhdGgubGVuZ3RoICYmICEocmVsYXRpdmUuaG9zdCA9IHJlbFBhdGguc2hpZnQoKSkpO1xuICAgICAgaWYgKCFyZWxhdGl2ZS5ob3N0KSByZWxhdGl2ZS5ob3N0ID0gJyc7XG4gICAgICBpZiAoIXJlbGF0aXZlLmhvc3RuYW1lKSByZWxhdGl2ZS5ob3N0bmFtZSA9ICcnO1xuICAgICAgaWYgKHJlbFBhdGhbMF0gIT09ICcnKSByZWxQYXRoLnVuc2hpZnQoJycpO1xuICAgICAgaWYgKHJlbFBhdGgubGVuZ3RoIDwgMikgcmVsUGF0aC51bnNoaWZ0KCcnKTtcbiAgICAgIHJlc3VsdC5wYXRobmFtZSA9IHJlbFBhdGguam9pbignLycpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQucGF0aG5hbWUgPSByZWxhdGl2ZS5wYXRobmFtZTtcbiAgICB9XG4gICAgcmVzdWx0LnNlYXJjaCA9IHJlbGF0aXZlLnNlYXJjaDtcbiAgICByZXN1bHQucXVlcnkgPSByZWxhdGl2ZS5xdWVyeTtcbiAgICByZXN1bHQuaG9zdCA9IHJlbGF0aXZlLmhvc3QgfHwgJyc7XG4gICAgcmVzdWx0LmF1dGggPSByZWxhdGl2ZS5hdXRoO1xuICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlbGF0aXZlLmhvc3RuYW1lIHx8IHJlbGF0aXZlLmhvc3Q7XG4gICAgcmVzdWx0LnBvcnQgPSByZWxhdGl2ZS5wb3J0O1xuICAgIC8vIHRvIHN1cHBvcnQgaHR0cC5yZXF1ZXN0XG4gICAgaWYgKHJlc3VsdC5wYXRobmFtZSB8fCByZXN1bHQuc2VhcmNoKSB7XG4gICAgICB2YXIgcCA9IHJlc3VsdC5wYXRobmFtZSB8fCAnJztcbiAgICAgIHZhciBzID0gcmVzdWx0LnNlYXJjaCB8fCAnJztcbiAgICAgIHJlc3VsdC5wYXRoID0gcCArIHM7XG4gICAgfVxuICAgIHJlc3VsdC5zbGFzaGVzID0gcmVzdWx0LnNsYXNoZXMgfHwgcmVsYXRpdmUuc2xhc2hlcztcbiAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgdmFyIGlzU291cmNlQWJzID0gcmVzdWx0LnBhdGhuYW1lICYmIHJlc3VsdC5wYXRobmFtZS5jaGFyQXQoMCkgPT09ICcvJztcbiAgdmFyIGlzUmVsQWJzID0gcmVsYXRpdmUuaG9zdCB8fCAocmVsYXRpdmUucGF0aG5hbWUgJiYgcmVsYXRpdmUucGF0aG5hbWUuY2hhckF0KDApID09PSAnLycpO1xuICB2YXIgbXVzdEVuZEFicyA9IGlzUmVsQWJzIHx8IGlzU291cmNlQWJzIHx8IChyZXN1bHQuaG9zdCAmJiByZWxhdGl2ZS5wYXRobmFtZSk7XG4gIHZhciByZW1vdmVBbGxEb3RzID0gbXVzdEVuZEFicztcbiAgdmFyIHNyY1BhdGggPSAocmVzdWx0LnBhdGhuYW1lICYmIHJlc3VsdC5wYXRobmFtZS5zcGxpdCgnLycpKSB8fCBbXTtcbiAgdmFyIHJlbFBhdGggPSAocmVsYXRpdmUucGF0aG5hbWUgJiYgcmVsYXRpdmUucGF0aG5hbWUuc3BsaXQoJy8nKSkgfHwgW107XG4gIHZhciBwc3ljaG90aWMgPSByZXN1bHQucHJvdG9jb2wgJiYgIXNsYXNoZWRQcm90b2NvbFtyZXN1bHQucHJvdG9jb2xdO1xuXG4gIC8vIGlmIHRoZSB1cmwgaXMgYSBub24tc2xhc2hlZCB1cmwsIHRoZW4gcmVsYXRpdmVcbiAgLy8gbGlua3MgbGlrZSAuLi8uLiBzaG91bGQgYmUgYWJsZVxuICAvLyB0byBjcmF3bCB1cCB0byB0aGUgaG9zdG5hbWUsIGFzIHdlbGwuICBUaGlzIGlzIHN0cmFuZ2UuXG4gIC8vIHJlc3VsdC5wcm90b2NvbCBoYXMgYWxyZWFkeSBiZWVuIHNldCBieSBub3cuXG4gIC8vIExhdGVyIG9uLCBwdXQgdGhlIGZpcnN0IHBhdGggcGFydCBpbnRvIHRoZSBob3N0IGZpZWxkLlxuICBpZiAocHN5Y2hvdGljKSB7XG4gICAgcmVzdWx0Lmhvc3RuYW1lID0gJyc7XG4gICAgcmVzdWx0LnBvcnQgPSBudWxsO1xuICAgIGlmIChyZXN1bHQuaG9zdCkge1xuICAgICAgaWYgKHNyY1BhdGhbMF0gPT09ICcnKSBzcmNQYXRoWzBdID0gcmVzdWx0Lmhvc3Q7XG4gICAgICBlbHNlIHNyY1BhdGgudW5zaGlmdChyZXN1bHQuaG9zdCk7XG4gICAgfVxuICAgIHJlc3VsdC5ob3N0ID0gJyc7XG4gICAgaWYgKHJlbGF0aXZlLnByb3RvY29sKSB7XG4gICAgICByZWxhdGl2ZS5ob3N0bmFtZSA9IG51bGw7XG4gICAgICByZWxhdGl2ZS5wb3J0ID0gbnVsbDtcbiAgICAgIGlmIChyZWxhdGl2ZS5ob3N0KSB7XG4gICAgICAgIGlmIChyZWxQYXRoWzBdID09PSAnJykgcmVsUGF0aFswXSA9IHJlbGF0aXZlLmhvc3Q7XG4gICAgICAgIGVsc2UgcmVsUGF0aC51bnNoaWZ0KHJlbGF0aXZlLmhvc3QpO1xuICAgICAgfVxuICAgICAgcmVsYXRpdmUuaG9zdCA9IG51bGw7XG4gICAgfVxuICAgIG11c3RFbmRBYnMgPSBtdXN0RW5kQWJzICYmIChyZWxQYXRoWzBdID09PSAnJyB8fCBzcmNQYXRoWzBdID09PSAnJyk7XG4gIH1cblxuICBpZiAoaXNSZWxBYnMpIHtcbiAgICAvLyBpdCdzIGFic29sdXRlLlxuICAgIHJlc3VsdC5ob3N0ID0gcmVsYXRpdmUuaG9zdCB8fCByZWxhdGl2ZS5ob3N0ID09PSAnJyA/IHJlbGF0aXZlLmhvc3QgOiByZXN1bHQuaG9zdDtcbiAgICByZXN1bHQuaG9zdG5hbWUgPVxuICAgICAgcmVsYXRpdmUuaG9zdG5hbWUgfHwgcmVsYXRpdmUuaG9zdG5hbWUgPT09ICcnID8gcmVsYXRpdmUuaG9zdG5hbWUgOiByZXN1bHQuaG9zdG5hbWU7XG4gICAgcmVzdWx0LnNlYXJjaCA9IHJlbGF0aXZlLnNlYXJjaDtcbiAgICByZXN1bHQucXVlcnkgPSByZWxhdGl2ZS5xdWVyeTtcbiAgICBzcmNQYXRoID0gcmVsUGF0aDtcbiAgICAvLyBmYWxsIHRocm91Z2ggdG8gdGhlIGRvdC1oYW5kbGluZyBiZWxvdy5cbiAgfSBlbHNlIGlmIChyZWxQYXRoLmxlbmd0aCkge1xuICAgIC8vIGl0J3MgcmVsYXRpdmVcbiAgICAvLyB0aHJvdyBhd2F5IHRoZSBleGlzdGluZyBmaWxlLCBhbmQgdGFrZSB0aGUgbmV3IHBhdGggaW5zdGVhZC5cbiAgICBpZiAoIXNyY1BhdGgpIHNyY1BhdGggPSBbXTtcbiAgICBzcmNQYXRoLnBvcCgpO1xuICAgIHNyY1BhdGggPSBzcmNQYXRoLmNvbmNhdChyZWxQYXRoKTtcbiAgICByZXN1bHQuc2VhcmNoID0gcmVsYXRpdmUuc2VhcmNoO1xuICAgIHJlc3VsdC5xdWVyeSA9IHJlbGF0aXZlLnF1ZXJ5O1xuICB9IGVsc2UgaWYgKHJlbGF0aXZlLnNlYXJjaCAhPT0gbnVsbCAmJiByZWxhdGl2ZS5zZWFyY2ggIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIGp1c3QgcHVsbCBvdXQgdGhlIHNlYXJjaC5cbiAgICAvLyBsaWtlIGhyZWY9Jz9mb28nLlxuICAgIC8vIFB1dCB0aGlzIGFmdGVyIHRoZSBvdGhlciB0d28gY2FzZXMgYmVjYXVzZSBpdCBzaW1wbGlmaWVzIHRoZSBib29sZWFuc1xuICAgIGlmIChwc3ljaG90aWMpIHtcbiAgICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlc3VsdC5ob3N0ID0gc3JjUGF0aC5zaGlmdCgpO1xuICAgICAgLy9vY2Nhc2lvbmFsbHkgdGhlIGF1dGggY2FuIGdldCBzdHVjayBvbmx5IGluIGhvc3RcbiAgICAgIC8vdGhpcyBlc3BlY2lhbGx5IGhhcHBlbnMgaW4gY2FzZXMgbGlrZVxuICAgICAgLy91cmwucmVzb2x2ZU9iamVjdCgnbWFpbHRvOmxvY2FsMUBkb21haW4xJywgJ2xvY2FsMkBkb21haW4yJylcbiAgICAgIGNvbnN0IGF1dGhJbkhvc3QgPVxuICAgICAgICByZXN1bHQuaG9zdCAmJiByZXN1bHQuaG9zdC5pbmRleE9mKCdAJykgPiAwID8gcmVzdWx0Lmhvc3Quc3BsaXQoJ0AnKSA6IGZhbHNlO1xuICAgICAgaWYgKGF1dGhJbkhvc3QpIHtcbiAgICAgICAgcmVzdWx0LmF1dGggPSBhdXRoSW5Ib3N0LnNoaWZ0KCk7XG4gICAgICAgIHJlc3VsdC5ob3N0ID0gcmVzdWx0Lmhvc3RuYW1lID0gYXV0aEluSG9zdC5zaGlmdCgpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXN1bHQuc2VhcmNoID0gcmVsYXRpdmUuc2VhcmNoO1xuICAgIHJlc3VsdC5xdWVyeSA9IHJlbGF0aXZlLnF1ZXJ5O1xuICAgIC8vdG8gc3VwcG9ydCBodHRwLnJlcXVlc3RcbiAgICBpZiAocmVzdWx0LnBhdGhuYW1lICE9PSBudWxsIHx8IHJlc3VsdC5zZWFyY2ggIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdC5wYXRoID0gKHJlc3VsdC5wYXRobmFtZSA/IHJlc3VsdC5wYXRobmFtZSA6ICcnKSArIChyZXN1bHQuc2VhcmNoID8gcmVzdWx0LnNlYXJjaCA6ICcnKTtcbiAgICB9XG4gICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGlmICghc3JjUGF0aC5sZW5ndGgpIHtcbiAgICAvLyBubyBwYXRoIGF0IGFsbC4gIGVhc3kuXG4gICAgLy8gd2UndmUgYWxyZWFkeSBoYW5kbGVkIHRoZSBvdGhlciBzdHVmZiBhYm92ZS5cbiAgICByZXN1bHQucGF0aG5hbWUgPSBudWxsO1xuICAgIC8vdG8gc3VwcG9ydCBodHRwLnJlcXVlc3RcbiAgICBpZiAocmVzdWx0LnNlYXJjaCkge1xuICAgICAgcmVzdWx0LnBhdGggPSAnLycgKyByZXN1bHQuc2VhcmNoO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQucGF0aCA9IG51bGw7XG4gICAgfVxuICAgIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvLyBpZiBhIHVybCBFTkRzIGluIC4gb3IgLi4sIHRoZW4gaXQgbXVzdCBnZXQgYSB0cmFpbGluZyBzbGFzaC5cbiAgLy8gaG93ZXZlciwgaWYgaXQgZW5kcyBpbiBhbnl0aGluZyBlbHNlIG5vbi1zbGFzaHksXG4gIC8vIHRoZW4gaXQgbXVzdCBOT1QgZ2V0IGEgdHJhaWxpbmcgc2xhc2guXG4gIHZhciBsYXN0ID0gc3JjUGF0aC5zbGljZSgtMSlbMF07XG4gIHZhciBoYXNUcmFpbGluZ1NsYXNoID1cbiAgICAoKHJlc3VsdC5ob3N0IHx8IHJlbGF0aXZlLmhvc3QgfHwgc3JjUGF0aC5sZW5ndGggPiAxKSAmJiAobGFzdCA9PT0gJy4nIHx8IGxhc3QgPT09ICcuLicpKSB8fFxuICAgIGxhc3QgPT09ICcnO1xuXG4gIC8vIHN0cmlwIHNpbmdsZSBkb3RzLCByZXNvbHZlIGRvdWJsZSBkb3RzIHRvIHBhcmVudCBkaXJcbiAgLy8gaWYgdGhlIHBhdGggdHJpZXMgdG8gZ28gYWJvdmUgdGhlIHJvb3QsIGB1cGAgZW5kcyB1cCA+IDBcbiAgdmFyIHVwID0gMDtcbiAgZm9yICh2YXIgaSA9IHNyY1BhdGgubGVuZ3RoOyBpID49IDA7IGktLSkge1xuICAgIGxhc3QgPSBzcmNQYXRoW2ldO1xuICAgIGlmIChsYXN0ID09PSAnLicpIHtcbiAgICAgIHNwbGljZU9uZShzcmNQYXRoLCBpKTtcbiAgICB9IGVsc2UgaWYgKGxhc3QgPT09ICcuLicpIHtcbiAgICAgIHNwbGljZU9uZShzcmNQYXRoLCBpKTtcbiAgICAgIHVwKys7XG4gICAgfSBlbHNlIGlmICh1cCkge1xuICAgICAgc3BsaWNlT25lKHNyY1BhdGgsIGkpO1xuICAgICAgdXAtLTtcbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGUgcGF0aCBpcyBhbGxvd2VkIHRvIGdvIGFib3ZlIHRoZSByb290LCByZXN0b3JlIGxlYWRpbmcgLi5zXG4gIGlmICghbXVzdEVuZEFicyAmJiAhcmVtb3ZlQWxsRG90cykge1xuICAgIGZvciAoOyB1cC0tOyB1cCkge1xuICAgICAgc3JjUGF0aC51bnNoaWZ0KCcuLicpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChtdXN0RW5kQWJzICYmIHNyY1BhdGhbMF0gIT09ICcnICYmICghc3JjUGF0aFswXSB8fCBzcmNQYXRoWzBdLmNoYXJBdCgwKSAhPT0gJy8nKSkge1xuICAgIHNyY1BhdGgudW5zaGlmdCgnJyk7XG4gIH1cblxuICBpZiAoaGFzVHJhaWxpbmdTbGFzaCAmJiBzcmNQYXRoLmpvaW4oJy8nKS5zdWJzdHIoLTEpICE9PSAnLycpIHtcbiAgICBzcmNQYXRoLnB1c2goJycpO1xuICB9XG5cbiAgdmFyIGlzQWJzb2x1dGUgPSBzcmNQYXRoWzBdID09PSAnJyB8fCAoc3JjUGF0aFswXSAmJiBzcmNQYXRoWzBdLmNoYXJBdCgwKSA9PT0gJy8nKTtcblxuICAvLyBwdXQgdGhlIGhvc3QgYmFja1xuICBpZiAocHN5Y2hvdGljKSB7XG4gICAgaWYgKGlzQWJzb2x1dGUpIHtcbiAgICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlc3VsdC5ob3N0ID0gJyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlc3VsdC5ob3N0ID0gc3JjUGF0aC5sZW5ndGggPyBzcmNQYXRoLnNoaWZ0KCkgOiAnJztcbiAgICB9XG4gICAgLy9vY2Nhc2lvbmFsbHkgdGhlIGF1dGggY2FuIGdldCBzdHVjayBvbmx5IGluIGhvc3RcbiAgICAvL3RoaXMgZXNwZWNpYWxseSBoYXBwZW5zIGluIGNhc2VzIGxpa2VcbiAgICAvL3VybC5yZXNvbHZlT2JqZWN0KCdtYWlsdG86bG9jYWwxQGRvbWFpbjEnLCAnbG9jYWwyQGRvbWFpbjInKVxuICAgIGNvbnN0IGF1dGhJbkhvc3QgPSByZXN1bHQuaG9zdCAmJiByZXN1bHQuaG9zdC5pbmRleE9mKCdAJykgPiAwID8gcmVzdWx0Lmhvc3Quc3BsaXQoJ0AnKSA6IGZhbHNlO1xuICAgIGlmIChhdXRoSW5Ib3N0KSB7XG4gICAgICByZXN1bHQuYXV0aCA9IGF1dGhJbkhvc3Quc2hpZnQoKTtcbiAgICAgIHJlc3VsdC5ob3N0ID0gcmVzdWx0Lmhvc3RuYW1lID0gYXV0aEluSG9zdC5zaGlmdCgpO1xuICAgIH1cbiAgfVxuXG4gIG11c3RFbmRBYnMgPSBtdXN0RW5kQWJzIHx8IChyZXN1bHQuaG9zdCAmJiBzcmNQYXRoLmxlbmd0aCk7XG5cbiAgaWYgKG11c3RFbmRBYnMgJiYgIWlzQWJzb2x1dGUpIHtcbiAgICBzcmNQYXRoLnVuc2hpZnQoJycpO1xuICB9XG5cbiAgaWYgKCFzcmNQYXRoLmxlbmd0aCkge1xuICAgIHJlc3VsdC5wYXRobmFtZSA9IG51bGw7XG4gICAgcmVzdWx0LnBhdGggPSBudWxsO1xuICB9IGVsc2Uge1xuICAgIHJlc3VsdC5wYXRobmFtZSA9IHNyY1BhdGguam9pbignLycpO1xuICB9XG5cbiAgLy90byBzdXBwb3J0IHJlcXVlc3QuaHR0cFxuICBpZiAocmVzdWx0LnBhdGhuYW1lICE9PSBudWxsIHx8IHJlc3VsdC5zZWFyY2ggIT09IG51bGwpIHtcbiAgICByZXN1bHQucGF0aCA9IChyZXN1bHQucGF0aG5hbWUgPyByZXN1bHQucGF0aG5hbWUgOiAnJykgKyAocmVzdWx0LnNlYXJjaCA/IHJlc3VsdC5zZWFyY2ggOiAnJyk7XG4gIH1cbiAgcmVzdWx0LmF1dGggPSByZWxhdGl2ZS5hdXRoIHx8IHJlc3VsdC5hdXRoO1xuICByZXN1bHQuc2xhc2hlcyA9IHJlc3VsdC5zbGFzaGVzIHx8IHJlbGF0aXZlLnNsYXNoZXM7XG4gIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICByZXR1cm4gcmVzdWx0O1xufTtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cblVybC5wcm90b3R5cGUucGFyc2VIb3N0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaG9zdCA9IHRoaXMuaG9zdDtcbiAgdmFyIHBvcnQgPSBwb3J0UGF0dGVybi5leGVjKGhvc3QpO1xuICBpZiAocG9ydCkge1xuICAgIHBvcnQgPSBwb3J0WzBdO1xuICAgIGlmIChwb3J0ICE9PSAnOicpIHtcbiAgICAgIHRoaXMucG9ydCA9IHBvcnQuc2xpY2UoMSk7XG4gICAgfVxuICAgIGhvc3QgPSBob3N0LnNsaWNlKDAsIGhvc3QubGVuZ3RoIC0gcG9ydC5sZW5ndGgpO1xuICB9XG4gIGlmIChob3N0KSB0aGlzLmhvc3RuYW1lID0gaG9zdDtcbn07XG5cbi8vIEFib3V0IDEuNXggZmFzdGVyIHRoYW4gdGhlIHR3by1hcmcgdmVyc2lvbiBvZiBBcnJheSNzcGxpY2UoKS5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5mdW5jdGlvbiBzcGxpY2VPbmUobGlzdCwgaW5kZXgpIHtcbiAgZm9yICh2YXIgaSA9IGluZGV4LCBrID0gaSArIDEsIG4gPSBsaXN0Lmxlbmd0aDsgayA8IG47IGkgKz0gMSwgayArPSAxKSBsaXN0W2ldID0gbGlzdFtrXTtcbiAgbGlzdC5wb3AoKTtcbn1cblxudmFyIGhleFRhYmxlID0gbmV3IEFycmF5KDI1Nik7XG5mb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgKytpKVxuICBoZXhUYWJsZVtpXSA9ICclJyArICgoaSA8IDE2ID8gJzAnIDogJycpICsgaS50b1N0cmluZygxNikpLnRvVXBwZXJDYXNlKCk7XG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogaW1wcm92ZSBjb3ZlcmFnZSAqL1xuZnVuY3Rpb24gZW5jb2RlQXV0aChzdHIpIHtcbiAgLy8gZmFzdGVyIGVuY29kZVVSSUNvbXBvbmVudCBhbHRlcm5hdGl2ZSBmb3IgZW5jb2RpbmcgYXV0aCB1cmkgY29tcG9uZW50c1xuICB2YXIgb3V0ID0gJyc7XG4gIHZhciBsYXN0UG9zID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgYyA9IHN0ci5jaGFyQ29kZUF0KGkpO1xuXG4gICAgLy8gVGhlc2UgY2hhcmFjdGVycyBkbyBub3QgbmVlZCBlc2NhcGluZzpcbiAgICAvLyAhIC0gLiBfIH5cbiAgICAvLyAnICggKSAqIDpcbiAgICAvLyBkaWdpdHNcbiAgICAvLyBhbHBoYSAodXBwZXJjYXNlKVxuICAgIC8vIGFscGhhIChsb3dlcmNhc2UpXG4gICAgaWYgKFxuICAgICAgYyA9PT0gMHgyMSB8fFxuICAgICAgYyA9PT0gMHgyZCB8fFxuICAgICAgYyA9PT0gMHgyZSB8fFxuICAgICAgYyA9PT0gMHg1ZiB8fFxuICAgICAgYyA9PT0gMHg3ZSB8fFxuICAgICAgKGMgPj0gMHgyNyAmJiBjIDw9IDB4MmEpIHx8XG4gICAgICAoYyA+PSAweDMwICYmIGMgPD0gMHgzYSkgfHxcbiAgICAgIChjID49IDB4NDEgJiYgYyA8PSAweDVhKSB8fFxuICAgICAgKGMgPj0gMHg2MSAmJiBjIDw9IDB4N2EpXG4gICAgKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBvdXQgKz0gc3RyLnNsaWNlKGxhc3RQb3MsIGkpO1xuXG4gICAgbGFzdFBvcyA9IGkgKyAxO1xuXG4gICAgLy8gT3RoZXIgQVNDSUkgY2hhcmFjdGVyc1xuICAgIGlmIChjIDwgMHg4MCkge1xuICAgICAgb3V0ICs9IGhleFRhYmxlW2NdO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gTXVsdGktYnl0ZSBjaGFyYWN0ZXJzIC4uLlxuICAgIGlmIChjIDwgMHg4MDApIHtcbiAgICAgIG91dCArPSBoZXhUYWJsZVsweGMwIHwgKGMgPj4gNildICsgaGV4VGFibGVbMHg4MCB8IChjICYgMHgzZildO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChjIDwgMHhkODAwIHx8IGMgPj0gMHhlMDAwKSB7XG4gICAgICBvdXQgKz1cbiAgICAgICAgaGV4VGFibGVbMHhlMCB8IChjID4+IDEyKV0gK1xuICAgICAgICBoZXhUYWJsZVsweDgwIHwgKChjID4+IDYpICYgMHgzZildICtcbiAgICAgICAgaGV4VGFibGVbMHg4MCB8IChjICYgMHgzZildO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIC8vIFN1cnJvZ2F0ZSBwYWlyXG4gICAgKytpO1xuICAgIHZhciBjMjtcbiAgICBpZiAoaSA8IHN0ci5sZW5ndGgpIGMyID0gc3RyLmNoYXJDb2RlQXQoaSkgJiAweDNmZjtcbiAgICBlbHNlIGMyID0gMDtcbiAgICBjID0gMHgxMDAwMCArICgoKGMgJiAweDNmZikgPDwgMTApIHwgYzIpO1xuICAgIG91dCArPVxuICAgICAgaGV4VGFibGVbMHhmMCB8IChjID4+IDE4KV0gK1xuICAgICAgaGV4VGFibGVbMHg4MCB8ICgoYyA+PiAxMikgJiAweDNmKV0gK1xuICAgICAgaGV4VGFibGVbMHg4MCB8ICgoYyA+PiA2KSAmIDB4M2YpXSArXG4gICAgICBoZXhUYWJsZVsweDgwIHwgKGMgJiAweDNmKV07XG4gIH1cbiAgaWYgKGxhc3RQb3MgPT09IDApIHJldHVybiBzdHI7XG4gIGlmIChsYXN0UG9zIDwgc3RyLmxlbmd0aCkgcmV0dXJuIG91dCArIHN0ci5zbGljZShsYXN0UG9zKTtcbiAgcmV0dXJuIG91dDtcbn1cbiJdfQ== \ No newline at end of file From e4e926c833d253552fe8a99c0f72101a2e101154 Mon Sep 17 00:00:00 2001 From: Jason Posthuma Date: Wed, 24 Feb 2021 17:07:29 +0100 Subject: [PATCH 5/6] Revert "Added built version" This reverts commit b49eb69e9c2af7e1b7698340976dece0ab9a1448. --- .gitignore | 2 +- lib/AccountLockout.js | 193 -- lib/Adapters/AdapterLoader.js | 63 - lib/Adapters/Analytics/AnalyticsAdapter.js | 41 - lib/Adapters/Auth/AuthAdapter.js | 34 - lib/Adapters/Auth/OAuth1Client.js | 227 -- lib/Adapters/Auth/apple.js | 105 - lib/Adapters/Auth/facebook.js | 62 - lib/Adapters/Auth/gcenter.js | 126 - lib/Adapters/Auth/github.js | 40 - lib/Adapters/Auth/google.js | 167 -- lib/Adapters/Auth/gpgames.js | 35 - lib/Adapters/Auth/httpsRequest.js | 47 - lib/Adapters/Auth/index.js | 173 -- lib/Adapters/Auth/instagram.js | 31 - lib/Adapters/Auth/janraincapture.js | 46 - lib/Adapters/Auth/janrainengage.js | 52 - lib/Adapters/Auth/keycloak.js | 125 - lib/Adapters/Auth/ldap.js | 105 - lib/Adapters/Auth/line.js | 41 - lib/Adapters/Auth/linkedin.js | 46 - lib/Adapters/Auth/meetup.js | 39 - lib/Adapters/Auth/microsoft.js | 39 - lib/Adapters/Auth/oauth2.js | 142 - lib/Adapters/Auth/phantauth.js | 47 - lib/Adapters/Auth/qq.js | 48 - lib/Adapters/Auth/spotify.js | 51 - lib/Adapters/Auth/twitter.js | 60 - lib/Adapters/Auth/vkontakte.js | 54 - lib/Adapters/Auth/wechat.js | 33 - lib/Adapters/Auth/weibo.js | 47 - lib/Adapters/Cache/CacheAdapter.js | 50 - lib/Adapters/Cache/InMemoryCache.js | 76 - lib/Adapters/Cache/InMemoryCacheAdapter.js | 45 - lib/Adapters/Cache/LRUCache.js | 46 - lib/Adapters/Cache/NullCacheAdapter.js | 34 - .../RedisCacheAdapter/KeyPromiseQueue.js | 59 - lib/Adapters/Cache/RedisCacheAdapter/index.js | 130 - lib/Adapters/Email/MailAdapter.js | 40 - lib/Adapters/Files/FilesAdapter.js | 136 - lib/Adapters/Files/GridFSBucketAdapter.js | 273 -- lib/Adapters/Files/GridStoreAdapter.js | 182 -- lib/Adapters/Logger/LoggerAdapter.js | 39 - lib/Adapters/Logger/WinstonLogger.js | 137 - lib/Adapters/Logger/WinstonLoggerAdapter.js | 75 - lib/Adapters/MessageQueue/EventEmitterMQ.js | 73 - lib/Adapters/PubSub/EventEmitterPubSub.js | 69 - lib/Adapters/PubSub/PubSubAdapter.js | 39 - lib/Adapters/PubSub/RedisPubSub.js | 33 - lib/Adapters/Push/PushAdapter.js | 50 - lib/Adapters/Storage/Mongo/MongoCollection.js | 229 -- .../Storage/Mongo/MongoSchemaCollection.js | 365 --- .../Storage/Mongo/MongoStorageAdapter.js | 957 ------- lib/Adapters/Storage/Mongo/MongoTransform.js | 1795 ------------ .../Storage/Postgres/PostgresClient.js | 40 - .../Storage/Postgres/PostgresConfigParser.js | 95 - .../Postgres/PostgresStorageAdapter.js | 2494 ----------------- .../Storage/Postgres/sql/array/add-unique.sql | 11 - .../Storage/Postgres/sql/array/add.sql | 11 - .../Postgres/sql/array/contains-all-regex.sql | 14 - .../Postgres/sql/array/contains-all.sql | 14 - .../Storage/Postgres/sql/array/contains.sql | 11 - .../Storage/Postgres/sql/array/remove.sql | 11 - lib/Adapters/Storage/Postgres/sql/index.js | 35 - .../sql/misc/json-object-set-keys.sql | 19 - lib/Adapters/Storage/StorageAdapter.js | 2 - lib/Adapters/WebSocketServer/WSAdapter.js | 45 - lib/Adapters/WebSocketServer/WSSAdapter.js | 74 - lib/Auth.js | 373 --- lib/ClientSDK.js | 47 - lib/Config.js | 471 ---- lib/Controllers/AdaptableController.js | 88 - lib/Controllers/AnalyticsController.js | 52 - lib/Controllers/CacheController.js | 92 - lib/Controllers/DatabaseController.js | 1568 ----------- lib/Controllers/FilesController.js | 136 - lib/Controllers/HooksController.js | 302 -- lib/Controllers/LiveQueryController.js | 78 - lib/Controllers/LoggerController.js | 265 -- lib/Controllers/ParseGraphQLController.js | 358 --- lib/Controllers/PushController.js | 257 -- lib/Controllers/SchemaCache.js | 75 - lib/Controllers/SchemaController.js | 1670 ----------- lib/Controllers/UserController.js | 375 --- lib/Controllers/index.js | 312 --- lib/Controllers/types.js | 2 - lib/GraphQL/ParseGraphQLSchema.js | 446 --- lib/GraphQL/ParseGraphQLServer.js | 140 - lib/GraphQL/helpers/objectsMutations.js | 40 - lib/GraphQL/helpers/objectsQueries.js | 309 -- .../loaders/defaultGraphQLMutations.js | 28 - lib/GraphQL/loaders/defaultGraphQLQueries.js | 29 - lib/GraphQL/loaders/defaultGraphQLTypes.js | 1271 --------- lib/GraphQL/loaders/defaultRelaySchema.js | 71 - lib/GraphQL/loaders/filesMutations.js | 103 - lib/GraphQL/loaders/functionsMutations.js | 90 - lib/GraphQL/loaders/parseClassMutations.js | 288 -- lib/GraphQL/loaders/parseClassQueries.js | 150 - lib/GraphQL/loaders/parseClassTypes.js | 531 ---- lib/GraphQL/loaders/schemaDirectives.js | 72 - lib/GraphQL/loaders/schemaMutations.js | 179 -- lib/GraphQL/loaders/schemaQueries.js | 93 - lib/GraphQL/loaders/schemaTypes.js | 376 --- lib/GraphQL/loaders/usersMutations.js | 332 --- lib/GraphQL/loaders/usersQueries.js | 111 - lib/GraphQL/parseGraphQLUtils.js | 69 - lib/GraphQL/transformers/className.js | 17 - lib/GraphQL/transformers/constraintType.js | 73 - lib/GraphQL/transformers/inputType.js | 71 - lib/GraphQL/transformers/mutation.js | 275 -- lib/GraphQL/transformers/outputType.js | 71 - lib/GraphQL/transformers/query.js | 273 -- lib/GraphQL/transformers/schemaFields.js | 128 - lib/LiveQuery/Client.js | 114 - lib/LiveQuery/Id.js | 26 - lib/LiveQuery/ParseCloudCodePublisher.js | 50 - lib/LiveQuery/ParseLiveQueryServer.js | 848 ------ lib/LiveQuery/ParsePubSub.js | 49 - lib/LiveQuery/ParseWebSocketServer.js | 80 - lib/LiveQuery/QueryTools.js | 452 --- lib/LiveQuery/RequestSchema.js | 146 - lib/LiveQuery/SessionTokenCache.js | 67 - lib/LiveQuery/Subscription.js | 61 - lib/LiveQuery/equalObjects.js | 62 - lib/Options/Definitions.js | 715 ----- lib/Options/docs.js | 178 -- lib/Options/index.js | 18 - lib/Options/parsers.js | 90 - lib/Page.js | 53 - lib/ParseMessageQueue.js | 34 - lib/ParseServer.js | 499 ---- lib/ParseServerRESTController.js | 184 -- lib/PromiseRouter.js | 255 -- lib/Push/PushQueue.js | 79 - lib/Push/PushWorker.js | 130 - lib/Push/utils.js | 159 -- lib/RestQuery.js | 979 ------- lib/RestWrite.js | 1485 ---------- lib/Routers/AggregateRouter.js | 153 - lib/Routers/AnalyticsRouter.js | 32 - lib/Routers/AudiencesRouter.js | 70 - lib/Routers/ClassesRouter.js | 231 -- lib/Routers/CloudCodeRouter.js | 105 - lib/Routers/FeaturesRouter.js | 79 - lib/Routers/FilesRouter.js | 280 -- lib/Routers/FunctionsRouter.js | 181 -- lib/Routers/GlobalConfigRouter.js | 95 - lib/Routers/GraphQLRouter.js | 55 - lib/Routers/HooksRouter.js | 144 - lib/Routers/IAPValidationRouter.js | 136 - lib/Routers/InstallationsRouter.js | 57 - lib/Routers/LogsRouter.js | 71 - lib/Routers/PagesRouter.js | 693 ----- lib/Routers/PublicAPIRouter.js | 322 --- lib/Routers/PurgeRouter.js | 60 - lib/Routers/PushRouter.js | 92 - lib/Routers/RolesRouter.js | 40 - lib/Routers/SchemasRouter.js | 120 - lib/Routers/SessionsRouter.js | 107 - lib/Routers/UsersRouter.js | 470 ---- lib/StatusHandler.js | 386 --- lib/TestUtils.js | 31 - lib/Utils.js | 139 - lib/batch.js | 135 - lib/cache.js | 16 - .../definitions/parse-live-query-server.js | 12 - lib/cli/definitions/parse-server.js | 12 - lib/cli/parse-live-query-server.js | 19 - lib/cli/parse-server.js | 111 - lib/cli/utils/commander.js | 163 -- lib/cli/utils/runner.js | 65 - lib/cloud-code/HTTPResponse.js | 73 - lib/cloud-code/Parse.Cloud.js | 719 ----- lib/cloud-code/httpRequest.js | 192 -- lib/cryptoUtils.js | 62 - lib/defaults.js | 60 - lib/deprecated.js | 13 - lib/index.js | 107 - lib/logger.js | 47 - lib/middlewares.js | 492 ---- lib/password.js | 38 - lib/request.js | 4 - lib/requiredParameter.js | 13 - lib/rest.js | 208 -- lib/triggers.js | 1032 ------- lib/vendor/README.md | 8 - lib/vendor/mongodbUrl.js | 1064 ------- 187 files changed, 1 insertion(+), 37912 deletions(-) delete mode 100644 lib/AccountLockout.js delete mode 100644 lib/Adapters/AdapterLoader.js delete mode 100644 lib/Adapters/Analytics/AnalyticsAdapter.js delete mode 100644 lib/Adapters/Auth/AuthAdapter.js delete mode 100644 lib/Adapters/Auth/OAuth1Client.js delete mode 100644 lib/Adapters/Auth/apple.js delete mode 100644 lib/Adapters/Auth/facebook.js delete mode 100644 lib/Adapters/Auth/gcenter.js delete mode 100644 lib/Adapters/Auth/github.js delete mode 100644 lib/Adapters/Auth/google.js delete mode 100644 lib/Adapters/Auth/gpgames.js delete mode 100644 lib/Adapters/Auth/httpsRequest.js delete mode 100755 lib/Adapters/Auth/index.js delete mode 100644 lib/Adapters/Auth/instagram.js delete mode 100644 lib/Adapters/Auth/janraincapture.js delete mode 100644 lib/Adapters/Auth/janrainengage.js delete mode 100644 lib/Adapters/Auth/keycloak.js delete mode 100644 lib/Adapters/Auth/ldap.js delete mode 100644 lib/Adapters/Auth/line.js delete mode 100644 lib/Adapters/Auth/linkedin.js delete mode 100644 lib/Adapters/Auth/meetup.js delete mode 100644 lib/Adapters/Auth/microsoft.js delete mode 100644 lib/Adapters/Auth/oauth2.js delete mode 100644 lib/Adapters/Auth/phantauth.js delete mode 100644 lib/Adapters/Auth/qq.js delete mode 100644 lib/Adapters/Auth/spotify.js delete mode 100644 lib/Adapters/Auth/twitter.js delete mode 100644 lib/Adapters/Auth/vkontakte.js delete mode 100644 lib/Adapters/Auth/wechat.js delete mode 100644 lib/Adapters/Auth/weibo.js delete mode 100644 lib/Adapters/Cache/CacheAdapter.js delete mode 100644 lib/Adapters/Cache/InMemoryCache.js delete mode 100644 lib/Adapters/Cache/InMemoryCacheAdapter.js delete mode 100644 lib/Adapters/Cache/LRUCache.js delete mode 100644 lib/Adapters/Cache/NullCacheAdapter.js delete mode 100644 lib/Adapters/Cache/RedisCacheAdapter/KeyPromiseQueue.js delete mode 100644 lib/Adapters/Cache/RedisCacheAdapter/index.js delete mode 100644 lib/Adapters/Email/MailAdapter.js delete mode 100644 lib/Adapters/Files/FilesAdapter.js delete mode 100644 lib/Adapters/Files/GridFSBucketAdapter.js delete mode 100644 lib/Adapters/Files/GridStoreAdapter.js delete mode 100644 lib/Adapters/Logger/LoggerAdapter.js delete mode 100644 lib/Adapters/Logger/WinstonLogger.js delete mode 100644 lib/Adapters/Logger/WinstonLoggerAdapter.js delete mode 100644 lib/Adapters/MessageQueue/EventEmitterMQ.js delete mode 100644 lib/Adapters/PubSub/EventEmitterPubSub.js delete mode 100644 lib/Adapters/PubSub/PubSubAdapter.js delete mode 100644 lib/Adapters/PubSub/RedisPubSub.js delete mode 100644 lib/Adapters/Push/PushAdapter.js delete mode 100644 lib/Adapters/Storage/Mongo/MongoCollection.js delete mode 100644 lib/Adapters/Storage/Mongo/MongoSchemaCollection.js delete mode 100644 lib/Adapters/Storage/Mongo/MongoStorageAdapter.js delete mode 100644 lib/Adapters/Storage/Mongo/MongoTransform.js delete mode 100644 lib/Adapters/Storage/Postgres/PostgresClient.js delete mode 100644 lib/Adapters/Storage/Postgres/PostgresConfigParser.js delete mode 100644 lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js delete mode 100644 lib/Adapters/Storage/Postgres/sql/array/add-unique.sql delete mode 100644 lib/Adapters/Storage/Postgres/sql/array/add.sql delete mode 100644 lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql delete mode 100644 lib/Adapters/Storage/Postgres/sql/array/contains-all.sql delete mode 100644 lib/Adapters/Storage/Postgres/sql/array/contains.sql delete mode 100644 lib/Adapters/Storage/Postgres/sql/array/remove.sql delete mode 100644 lib/Adapters/Storage/Postgres/sql/index.js delete mode 100644 lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql delete mode 100644 lib/Adapters/Storage/StorageAdapter.js delete mode 100644 lib/Adapters/WebSocketServer/WSAdapter.js delete mode 100644 lib/Adapters/WebSocketServer/WSSAdapter.js delete mode 100644 lib/Auth.js delete mode 100644 lib/ClientSDK.js delete mode 100644 lib/Config.js delete mode 100644 lib/Controllers/AdaptableController.js delete mode 100644 lib/Controllers/AnalyticsController.js delete mode 100644 lib/Controllers/CacheController.js delete mode 100644 lib/Controllers/DatabaseController.js delete mode 100644 lib/Controllers/FilesController.js delete mode 100644 lib/Controllers/HooksController.js delete mode 100644 lib/Controllers/LiveQueryController.js delete mode 100644 lib/Controllers/LoggerController.js delete mode 100644 lib/Controllers/ParseGraphQLController.js delete mode 100644 lib/Controllers/PushController.js delete mode 100644 lib/Controllers/SchemaCache.js delete mode 100644 lib/Controllers/SchemaController.js delete mode 100644 lib/Controllers/UserController.js delete mode 100644 lib/Controllers/index.js delete mode 100644 lib/Controllers/types.js delete mode 100644 lib/GraphQL/ParseGraphQLSchema.js delete mode 100644 lib/GraphQL/ParseGraphQLServer.js delete mode 100644 lib/GraphQL/helpers/objectsMutations.js delete mode 100644 lib/GraphQL/helpers/objectsQueries.js delete mode 100644 lib/GraphQL/loaders/defaultGraphQLMutations.js delete mode 100644 lib/GraphQL/loaders/defaultGraphQLQueries.js delete mode 100644 lib/GraphQL/loaders/defaultGraphQLTypes.js delete mode 100644 lib/GraphQL/loaders/defaultRelaySchema.js delete mode 100644 lib/GraphQL/loaders/filesMutations.js delete mode 100644 lib/GraphQL/loaders/functionsMutations.js delete mode 100644 lib/GraphQL/loaders/parseClassMutations.js delete mode 100644 lib/GraphQL/loaders/parseClassQueries.js delete mode 100644 lib/GraphQL/loaders/parseClassTypes.js delete mode 100644 lib/GraphQL/loaders/schemaDirectives.js delete mode 100644 lib/GraphQL/loaders/schemaMutations.js delete mode 100644 lib/GraphQL/loaders/schemaQueries.js delete mode 100644 lib/GraphQL/loaders/schemaTypes.js delete mode 100644 lib/GraphQL/loaders/usersMutations.js delete mode 100644 lib/GraphQL/loaders/usersQueries.js delete mode 100644 lib/GraphQL/parseGraphQLUtils.js delete mode 100644 lib/GraphQL/transformers/className.js delete mode 100644 lib/GraphQL/transformers/constraintType.js delete mode 100644 lib/GraphQL/transformers/inputType.js delete mode 100644 lib/GraphQL/transformers/mutation.js delete mode 100644 lib/GraphQL/transformers/outputType.js delete mode 100644 lib/GraphQL/transformers/query.js delete mode 100644 lib/GraphQL/transformers/schemaFields.js delete mode 100644 lib/LiveQuery/Client.js delete mode 100644 lib/LiveQuery/Id.js delete mode 100644 lib/LiveQuery/ParseCloudCodePublisher.js delete mode 100644 lib/LiveQuery/ParseLiveQueryServer.js delete mode 100644 lib/LiveQuery/ParsePubSub.js delete mode 100644 lib/LiveQuery/ParseWebSocketServer.js delete mode 100644 lib/LiveQuery/QueryTools.js delete mode 100644 lib/LiveQuery/RequestSchema.js delete mode 100644 lib/LiveQuery/SessionTokenCache.js delete mode 100644 lib/LiveQuery/Subscription.js delete mode 100644 lib/LiveQuery/equalObjects.js delete mode 100644 lib/Options/Definitions.js delete mode 100644 lib/Options/docs.js delete mode 100644 lib/Options/index.js delete mode 100644 lib/Options/parsers.js delete mode 100644 lib/Page.js delete mode 100644 lib/ParseMessageQueue.js delete mode 100644 lib/ParseServer.js delete mode 100644 lib/ParseServerRESTController.js delete mode 100644 lib/PromiseRouter.js delete mode 100644 lib/Push/PushQueue.js delete mode 100644 lib/Push/PushWorker.js delete mode 100644 lib/Push/utils.js delete mode 100644 lib/RestQuery.js delete mode 100644 lib/RestWrite.js delete mode 100644 lib/Routers/AggregateRouter.js delete mode 100644 lib/Routers/AnalyticsRouter.js delete mode 100644 lib/Routers/AudiencesRouter.js delete mode 100644 lib/Routers/ClassesRouter.js delete mode 100644 lib/Routers/CloudCodeRouter.js delete mode 100644 lib/Routers/FeaturesRouter.js delete mode 100644 lib/Routers/FilesRouter.js delete mode 100644 lib/Routers/FunctionsRouter.js delete mode 100644 lib/Routers/GlobalConfigRouter.js delete mode 100644 lib/Routers/GraphQLRouter.js delete mode 100644 lib/Routers/HooksRouter.js delete mode 100644 lib/Routers/IAPValidationRouter.js delete mode 100644 lib/Routers/InstallationsRouter.js delete mode 100644 lib/Routers/LogsRouter.js delete mode 100644 lib/Routers/PagesRouter.js delete mode 100644 lib/Routers/PublicAPIRouter.js delete mode 100644 lib/Routers/PurgeRouter.js delete mode 100644 lib/Routers/PushRouter.js delete mode 100644 lib/Routers/RolesRouter.js delete mode 100644 lib/Routers/SchemasRouter.js delete mode 100644 lib/Routers/SessionsRouter.js delete mode 100644 lib/Routers/UsersRouter.js delete mode 100644 lib/StatusHandler.js delete mode 100644 lib/TestUtils.js delete mode 100644 lib/Utils.js delete mode 100644 lib/batch.js delete mode 100644 lib/cache.js delete mode 100644 lib/cli/definitions/parse-live-query-server.js delete mode 100644 lib/cli/definitions/parse-server.js delete mode 100644 lib/cli/parse-live-query-server.js delete mode 100755 lib/cli/parse-server.js delete mode 100644 lib/cli/utils/commander.js delete mode 100644 lib/cli/utils/runner.js delete mode 100644 lib/cloud-code/HTTPResponse.js delete mode 100644 lib/cloud-code/Parse.Cloud.js delete mode 100644 lib/cloud-code/httpRequest.js delete mode 100644 lib/cryptoUtils.js delete mode 100644 lib/defaults.js delete mode 100644 lib/deprecated.js delete mode 100644 lib/index.js delete mode 100644 lib/logger.js delete mode 100644 lib/middlewares.js delete mode 100644 lib/password.js delete mode 100644 lib/request.js delete mode 100644 lib/requiredParameter.js delete mode 100644 lib/rest.js delete mode 100644 lib/triggers.js delete mode 100644 lib/vendor/README.md delete mode 100644 lib/vendor/mongodbUrl.js diff --git a/.gitignore b/.gitignore index 60fbcf9a3d..e4e19156c2 100644 --- a/.gitignore +++ b/.gitignore @@ -45,7 +45,7 @@ node_modules .vscode # Babel.js -# lib/ - Inlcuded built version +lib/ # cache folder .cache diff --git a/lib/AccountLockout.js b/lib/AccountLockout.js deleted file mode 100644 index 34087024bb..0000000000 --- a/lib/AccountLockout.js +++ /dev/null @@ -1,193 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.AccountLockout = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// This class handles the Account Lockout Policy settings. -class AccountLockout { - constructor(user, config) { - this._user = user; - this._config = config; - } - /** - * set _failed_login_count to value - */ - - - _setFailedLoginCount(value) { - const query = { - username: this._user.username - }; - const updateFields = { - _failed_login_count: value - }; - return this._config.database.update('_User', query, updateFields); - } - /** - * check if the _failed_login_count field has been set - */ - - - _isFailedLoginCountSet() { - const query = { - username: this._user.username, - _failed_login_count: { - $exists: true - } - }; - return this._config.database.find('_User', query).then(users => { - if (Array.isArray(users) && users.length > 0) { - return true; - } else { - return false; - } - }); - } - /** - * if _failed_login_count is NOT set then set it to 0 - * else do nothing - */ - - - _initFailedLoginCount() { - return this._isFailedLoginCountSet().then(failedLoginCountIsSet => { - if (!failedLoginCountIsSet) { - return this._setFailedLoginCount(0); - } - }); - } - /** - * increment _failed_login_count by 1 - */ - - - _incrementFailedLoginCount() { - const query = { - username: this._user.username - }; - const updateFields = { - _failed_login_count: { - __op: 'Increment', - amount: 1 - } - }; - return this._config.database.update('_User', query, updateFields); - } - /** - * if the failed login count is greater than the threshold - * then sets lockout expiration to 'currenttime + accountPolicy.duration', i.e., account is locked out for the next 'accountPolicy.duration' minutes - * else do nothing - */ - - - _setLockoutExpiration() { - const query = { - username: this._user.username, - _failed_login_count: { - $gte: this._config.accountLockout.threshold - } - }; - const now = new Date(); - const updateFields = { - _account_lockout_expires_at: _node.default._encode(new Date(now.getTime() + this._config.accountLockout.duration * 60 * 1000)) - }; - return this._config.database.update('_User', query, updateFields).catch(err => { - if (err && err.code && err.message && err.code === 101 && err.message === 'Object not found.') { - return; // nothing to update so we are good - } else { - throw err; // unknown error - } - }); - } - /** - * if _account_lockout_expires_at > current_time and _failed_login_count > threshold - * reject with account locked error - * else - * resolve - */ - - - _notLocked() { - const query = { - username: this._user.username, - _account_lockout_expires_at: { - $gt: _node.default._encode(new Date()) - }, - _failed_login_count: { - $gte: this._config.accountLockout.threshold - } - }; - return this._config.database.find('_User', query).then(users => { - if (Array.isArray(users) && users.length > 0) { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Your account is locked due to multiple failed login attempts. Please try again after ' + this._config.accountLockout.duration + ' minute(s)'); - } - }); - } - /** - * set and/or increment _failed_login_count - * if _failed_login_count > threshold - * set the _account_lockout_expires_at to current_time + accountPolicy.duration - * else - * do nothing - */ - - - _handleFailedLoginAttempt() { - return this._initFailedLoginCount().then(() => { - return this._incrementFailedLoginCount(); - }).then(() => { - return this._setLockoutExpiration(); - }); - } - /** - * handle login attempt if the Account Lockout Policy is enabled - */ - - - handleLoginAttempt(loginSuccessful) { - if (!this._config.accountLockout) { - return Promise.resolve(); - } - - return this._notLocked().then(() => { - if (loginSuccessful) { - return this._setFailedLoginCount(0); - } else { - return this._handleFailedLoginAttempt(); - } - }); - } - /** - * Removes the account lockout. - */ - - - unlockAccount() { - if (!this._config.accountLockout || !this._config.accountLockout.unlockOnPasswordReset) { - return Promise.resolve(); - } - - return this._config.database.update('_User', { - username: this._user.username - }, { - _failed_login_count: { - __op: 'Delete' - }, - _account_lockout_expires_at: { - __op: 'Delete' - } - }); - } - -} - -exports.AccountLockout = AccountLockout; -var _default = AccountLockout; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9BY2NvdW50TG9ja291dC5qcyJdLCJuYW1lcyI6WyJBY2NvdW50TG9ja291dCIsImNvbnN0cnVjdG9yIiwidXNlciIsImNvbmZpZyIsIl91c2VyIiwiX2NvbmZpZyIsIl9zZXRGYWlsZWRMb2dpbkNvdW50IiwidmFsdWUiLCJxdWVyeSIsInVzZXJuYW1lIiwidXBkYXRlRmllbGRzIiwiX2ZhaWxlZF9sb2dpbl9jb3VudCIsImRhdGFiYXNlIiwidXBkYXRlIiwiX2lzRmFpbGVkTG9naW5Db3VudFNldCIsIiRleGlzdHMiLCJmaW5kIiwidGhlbiIsInVzZXJzIiwiQXJyYXkiLCJpc0FycmF5IiwibGVuZ3RoIiwiX2luaXRGYWlsZWRMb2dpbkNvdW50IiwiZmFpbGVkTG9naW5Db3VudElzU2V0IiwiX2luY3JlbWVudEZhaWxlZExvZ2luQ291bnQiLCJfX29wIiwiYW1vdW50IiwiX3NldExvY2tvdXRFeHBpcmF0aW9uIiwiJGd0ZSIsImFjY291bnRMb2Nrb3V0IiwidGhyZXNob2xkIiwibm93IiwiRGF0ZSIsIl9hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCIsIlBhcnNlIiwiX2VuY29kZSIsImdldFRpbWUiLCJkdXJhdGlvbiIsImNhdGNoIiwiZXJyIiwiY29kZSIsIm1lc3NhZ2UiLCJfbm90TG9ja2VkIiwiJGd0IiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiX2hhbmRsZUZhaWxlZExvZ2luQXR0ZW1wdCIsImhhbmRsZUxvZ2luQXR0ZW1wdCIsImxvZ2luU3VjY2Vzc2Z1bCIsIlByb21pc2UiLCJyZXNvbHZlIiwidW5sb2NrQWNjb3VudCIsInVubG9ja09uUGFzc3dvcmRSZXNldCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUNBOzs7O0FBREE7QUFHTyxNQUFNQSxjQUFOLENBQXFCO0FBQzFCQyxFQUFBQSxXQUFXLENBQUNDLElBQUQsRUFBT0MsTUFBUCxFQUFlO0FBQ3hCLFNBQUtDLEtBQUwsR0FBYUYsSUFBYjtBQUNBLFNBQUtHLE9BQUws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ZW50IjpbIi8vIFRoaXMgY2xhc3MgaGFuZGxlcyB0aGUgQWNjb3VudCBMb2Nrb3V0IFBvbGljeSBzZXR0aW5ncy5cbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcblxuZXhwb3J0IGNsYXNzIEFjY291bnRMb2Nrb3V0IHtcbiAgY29uc3RydWN0b3IodXNlciwgY29uZmlnKSB7XG4gICAgdGhpcy5fdXNlciA9IHVzZXI7XG4gICAgdGhpcy5fY29uZmlnID0gY29uZmlnO1xuICB9XG5cbiAgLyoqXG4gICAqIHNldCBfZmFpbGVkX2xvZ2luX2NvdW50IHRvIHZhbHVlXG4gICAqL1xuICBfc2V0RmFpbGVkTG9naW5Db3VudCh2YWx1ZSkge1xuICAgIGNvbnN0IHF1ZXJ5ID0ge1xuICAgICAgdXNlcm5hbWU6IHRoaXMuX3VzZXIudXNlcm5hbWUsXG4gICAgfTtcblxuICAgIGNvbnN0IHVwZGF0ZUZpZWxkcyA9IHtcbiAgICAgIF9mYWlsZWRfbG9naW5fY291bnQ6IHZhbHVlLFxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy5fY29uZmlnLmRhdGFiYXNlLnVwZGF0ZSgnX1VzZXInLCBxdWVyeSwgdXBkYXRlRmllbGRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBjaGVjayBpZiB0aGUgX2ZhaWxlZF9sb2dpbl9jb3VudCBmaWVsZCBoYXMgYmVlbiBzZXRcbiAgICovXG4gIF9pc0ZhaWxlZExvZ2luQ291bnRTZXQoKSB7XG4gICAgY29uc3QgcXVlcnkgPSB7XG4gICAgICB1c2VybmFtZTogdGhpcy5fdXNlci51c2VybmFtZSxcbiAgICAgIF9mYWlsZWRfbG9naW5fY291bnQ6IHsgJGV4aXN0czogdHJ1ZSB9LFxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy5fY29uZmlnLmRhdGFiYXNlLmZpbmQoJ19Vc2VyJywgcXVlcnkpLnRoZW4odXNlcnMgPT4ge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodXNlcnMpICYmIHVzZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogaWYgX2ZhaWxlZF9sb2dpbl9jb3VudCBpcyBOT1Qgc2V0IHRoZW4gc2V0IGl0IHRvIDBcbiAgICogZWxzZSBkbyBub3RoaW5nXG4gICAqL1xuICBfaW5pdEZhaWxlZExvZ2luQ291bnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2lzRmFpbGVkTG9naW5Db3VudFNldCgpLnRoZW4oZmFpbGVkTG9naW5Db3VudElzU2V0ID0+IHtcbiAgICAgIGlmICghZmFpbGVkTG9naW5Db3VudElzU2V0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zZXRGYWlsZWRMb2dpbkNvdW50KDApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIGluY3JlbWVudCBfZmFpbGVkX2xvZ2luX2NvdW50IGJ5IDFcbiAgICovXG4gIF9pbmNyZW1lbnRGYWlsZWRMb2dpbkNvdW50KCkge1xuICAgIGNvbnN0IHF1ZXJ5ID0ge1xuICAgICAgdXNlcm5hbWU6IHRoaXMuX3VzZXIudXNlcm5hbWUsXG4gICAgfTtcblxuICAgIGNvbnN0IHVwZGF0ZUZpZWxkcyA9IHtcbiAgICAgIF9mYWlsZWRfbG9naW5fY291bnQ6IHsgX19vcDogJ0luY3JlbWVudCcsIGFtb3VudDogMSB9LFxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy5fY29uZmlnLmRhdGFiYXNlLnVwZGF0ZSgnX1VzZXInLCBxdWVyeSwgdXBkYXRlRmllbGRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBpZiB0aGUgZmFpbGVkIGxvZ2luIGNvdW50IGlzIGdyZWF0ZXIgdGhhbiB0aGUgdGhyZXNob2xkXG4gICAqIHRoZW4gc2V0cyBsb2Nrb3V0IGV4cGlyYXRpb24gdG8gJ2N1cnJlbnR0aW1lICsgYWNjb3VudFBvbGljeS5kdXJhdGlvbicsIGkuZS4sIGFjY291bnQgaXMgbG9ja2VkIG91dCBmb3IgdGhlIG5leHQgJ2FjY291bnRQb2xpY3kuZHVyYXRpb24nIG1pbnV0ZXNcbiAgICogZWxzZSBkbyBub3RoaW5nXG4gICAqL1xuICBfc2V0TG9ja291dEV4cGlyYXRpb24oKSB7XG4gICAgY29uc3QgcXVlcnkgPSB7XG4gICAgICB1c2VybmFtZTogdGhpcy5fdXNlci51c2VybmFtZSxcbiAgICAgIF9mYWlsZWRfbG9naW5fY291bnQ6IHsgJGd0ZTogdGhpcy5fY29uZmlnLmFjY291bnRMb2Nrb3V0LnRocmVzaG9sZCB9LFxuICAgIH07XG5cbiAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuXG4gICAgY29uc3QgdXBkYXRlRmllbGRzID0ge1xuICAgICAgX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0OiBQYXJzZS5fZW5jb2RlKFxuICAgICAgICBuZXcgRGF0ZShub3cuZ2V0VGltZSgpICsgdGhpcy5fY29uZmlnLmFjY291bnRMb2Nrb3V0LmR1cmF0aW9uICogNjAgKiAxMDAwKVxuICAgICAgKSxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHRoaXMuX2NvbmZpZy5kYXRhYmFzZS51cGRhdGUoJ19Vc2VyJywgcXVlcnksIHVwZGF0ZUZpZWxkcykuY2F0Y2goZXJyID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgZXJyICYmXG4gICAgICAgIGVyci5jb2RlICYmXG4gICAgICAgIGVyci5tZXNzYWdlICYmXG4gICAgICAgIGVyci5jb2RlID09PSAxMDEgJiZcbiAgICAgICAgZXJyLm1lc3NhZ2UgPT09ICdPYmplY3Qgbm90IGZvdW5kLidcbiAgICAgICkge1xuICAgICAgICByZXR1cm47IC8vIG5vdGhpbmcgdG8gdXBkYXRlIHNvIHdlIGFyZSBnb29kXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlcnI7IC8vIHVua25vd24gZXJyb3JcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBpZiBfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQgPiBjdXJyZW50X3RpbWUgYW5kIF9mYWlsZWRfbG9naW5fY291bnQgPiB0aHJlc2hvbGRcbiAgICogICByZWplY3Qgd2l0aCBhY2NvdW50IGxvY2tlZCBlcnJvclxuICAgKiBlbHNlXG4gICAqICAgcmVzb2x2ZVxuICAgKi9cbiAgX25vdExvY2tlZCgpIHtcbiAgICBjb25zdCBxdWVyeSA9IHtcbiAgICAgIHVzZXJuYW1lOiB0aGlzLl91c2VyLnVzZXJuYW1lLFxuICAgICAgX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0OiB7ICRndDogUGFyc2UuX2VuY29kZShuZXcgRGF0ZSgpKSB9LFxuICAgICAgX2ZhaWxlZF9sb2dpbl9jb3VudDogeyAkZ3RlOiB0aGlzLl9jb25maWcuYWNjb3VudExvY2tvdXQudGhyZXNob2xkIH0sXG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLl9jb25maWcuZGF0YWJhc2UuZmluZCgnX1VzZXInLCBxdWVyeSkudGhlbih1c2VycyA9PiB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheSh1c2VycykgJiYgdXNlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICAgICAnWW91ciBhY2NvdW50IGlzIGxvY2tlZCBkdWUgdG8gbXVsdGlwbGUgZmFpbGVkIGxvZ2luIGF0dGVtcHRzLiBQbGVhc2UgdHJ5IGFnYWluIGFmdGVyICcgK1xuICAgICAgICAgICAgdGhpcy5fY29uZmlnLmFjY291bnRMb2Nrb3V0LmR1cmF0aW9uICtcbiAgICAgICAgICAgICcgbWludXRlKHMpJ1xuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIHNldCBhbmQvb3IgaW5jcmVtZW50IF9mYWlsZWRfbG9naW5fY291bnRcbiAgICogaWYgX2ZhaWxlZF9sb2dpbl9jb3VudCA+IHRocmVzaG9sZFxuICAgKiAgIHNldCB0aGUgX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0IHRvIGN1cnJlbnRfdGltZSArIGFjY291bnRQb2xpY3kuZHVyYXRpb25cbiAgICogZWxzZVxuICAgKiAgIGRvIG5vdGhpbmdcbiAgICovXG4gIF9oYW5kbGVGYWlsZWRMb2dpbkF0dGVtcHQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2luaXRGYWlsZWRMb2dpbkNvdW50KClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2luY3JlbWVudEZhaWxlZExvZ2luQ291bnQoKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zZXRMb2Nrb3V0RXhwaXJhdGlvbigpO1xuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogaGFuZGxlIGxvZ2luIGF0dGVtcHQgaWYgdGhlIEFjY291bnQgTG9ja291dCBQb2xpY3kgaXMgZW5hYmxlZFxuICAgKi9cbiAgaGFuZGxlTG9naW5BdHRlbXB0KGxvZ2luU3VjY2Vzc2Z1bCkge1xuICAgIGlmICghdGhpcy5fY29uZmlnLmFjY291bnRMb2Nrb3V0KSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9ub3RMb2NrZWQoKS50aGVuKCgpID0+IHtcbiAgICAgIGlmIChsb2dpblN1Y2Nlc3NmdWwpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3NldEZhaWxlZExvZ2luQ291bnQoMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gdGhpcy5faGFuZGxlRmFpbGVkTG9naW5BdHRlbXB0KCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyB0aGUgYWNjb3VudCBsb2Nrb3V0LlxuICAgKi9cbiAgdW5sb2NrQWNjb3VudCgpIHtcbiAgICBpZiAoIXRoaXMuX2NvbmZpZy5hY2NvdW50TG9ja291dCB8fCAhdGhpcy5fY29uZmlnLmFjY291bnRMb2Nrb3V0LnVubG9ja09uUGFzc3dvcmRSZXNldCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY29uZmlnLmRhdGFiYXNlLnVwZGF0ZShcbiAgICAgICdfVXNlcicsXG4gICAgICB7IHVzZXJuYW1lOiB0aGlzLl91c2VyLnVzZXJuYW1lIH0sXG4gICAgICB7XG4gICAgICAgIF9mYWlsZWRfbG9naW5fY291bnQ6IHsgX19vcDogJ0RlbGV0ZScgfSxcbiAgICAgICAgX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0OiB7IF9fb3A6ICdEZWxldGUnIH0sXG4gICAgICB9XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBBY2NvdW50TG9ja291dDtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/AdapterLoader.js b/lib/Adapters/AdapterLoader.js deleted file mode 100644 index f295afe333..0000000000 --- a/lib/Adapters/AdapterLoader.js +++ /dev/null @@ -1,63 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.loadAdapter = loadAdapter; -exports.default = void 0; - -/** - * @module AdapterLoader - */ - -/** - * @static - * Attempt to load an adapter or fallback to the default. - * @param {Adapter} adapter an adapter - * @param {Adapter} defaultAdapter the default adapter to load - * @param {any} options options to pass to the contstructor - * @returns {Object} the loaded adapter - */ -function loadAdapter(adapter, defaultAdapter, options) { - if (!adapter) { - if (!defaultAdapter) { - return options; - } // Load from the default adapter when no adapter is set - - - return loadAdapter(defaultAdapter, undefined, options); - } else if (typeof adapter === 'function') { - try { - return adapter(options); - } catch (e) { - if (e.name === 'TypeError') { - var Adapter = adapter; - return new Adapter(options); - } else { - throw e; - } - } - } else if (typeof adapter === 'string') { - /* eslint-disable */ - adapter = require(adapter); // If it's define as a module, get the default - - if (adapter.default) { - adapter = adapter.default; - } - - return loadAdapter(adapter, undefined, options); - } else if (adapter.module) { - return loadAdapter(adapter.module, undefined, adapter.options); - } else if (adapter.class) { - return loadAdapter(adapter.class, undefined, adapter.options); - } else if (adapter.adapter) { - return loadAdapter(adapter.adapter, undefined, adapter.options); - } // return the adapter as provided - - - return adapter; -} - -var _default = loadAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9BZGFwdGVycy9BZGFwdGVyTG9hZGVyLmpzIl0sIm5hbWVzIjpbImxvYWRBZGFwdGVyIiwiYWRhcHRlciIsImRlZmF1bHRBZGFwdGVyIiwib3B0aW9ucyIsInVuZGVmaW5lZCIsImUiLCJuYW1lIiwiQWRhcHRlciIsInJlcXVpcmUiLCJkZWZhdWx0IiwibW9kdWxlIiwiY2xhc3MiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQSxXQUFULENBQXdCQyxPQUF4QixFQUFpQ0MsY0FBakMsRUFBaURDLE9BQWpELEVBQTZEO0FBQ2xFLE1BQUksQ0FBQ0YsT0FBTCxFQUFjO0FBQ1osUUFBSSxDQUFDQyxjQUFMLEVBQXFCO0FBQ25CLGFBQU9DLE9BQVA7QUFDRCxLQUhXLENBSVo7OztBQUNBLFdBQU9ILFdBQVcsQ0FBQ0UsY0FBRCxFQUFpQkUsU0FBakIsRUFBNEJELE9BQTVCLENBQWxCO0FBQ0QsR0FORCxNQU1PLElBQUksT0FBT0YsT0FBUCxLQUFtQixVQUF2QixFQUFtQztBQUN4QyxRQUFJO0FBQ0YsYUFBT0EsT0FBTyxDQUFDRSxPQUFELENBQWQ7QUFDRCxLQUZELENBRUUsT0FBT0UsQ0FBUCxFQUFVO0FBQ1YsVUFBSUEsQ0FBQyxDQUFDQyxJQUFGLEtBQVcsV0FBZixFQUE0QjtBQUMxQixZQUFJQyxPQUFPLEdBQUdOLE9BQWQ7QUFDQSxlQUFPLElBQUlNLE9BQUosQ0FBWUosT0FBWixDQUFQO0FBQ0QsT0FIRCxNQUdPO0FBQ0wsY0FBTUUsQ0FBTjtBQUNEO0FBQ0Y7QUFDRixHQVhNLE1BV0EsSUFBSSxPQUFPSixPQUFQLEtBQW1CLFFBQXZCLEVBQWlDO0FBQ3RDO0FBQ0FBLElBQUFBLE9BQU8sR0FBR08sT0FBTyxDQUFDUCxPQUFELENBQWpCLENBRnNDLENBR3RDOztBQUNBLFFBQUlBLE9BQU8sQ0FBQ1EsT0FBWixFQUFxQjtBQUNuQlIsTUFBQUEsT0FBTyxHQUFHQSxPQUFPLENBQUNRLE9BQWxCO0FBQ0Q7O0FBQ0QsV0FBT1QsV0FBVyxDQUFDQyxPQUFELEVBQVVHLFNBQVYsRUFBcUJELE9BQXJCLENBQWxCO0FBQ0QsR0FSTSxNQVFBLElBQUlGLE9BQU8sQ0FBQ1MsTUFBWixFQUFvQjtBQUN6QixXQUFPVixXQUFXLENBQUNDLE9BQU8sQ0FBQ1MsTUFBVCxFQUFpQk4sU0FBakIsRUFBNEJILE9BQU8sQ0FBQ0UsT0FBcEMsQ0FBbEI7QUFDRCxHQUZNLE1BRUEsSUFBSUYsT0FBTyxDQUFDVSxLQUFaLEVBQW1CO0FBQ3hCLFdBQU9YLFdBQVcsQ0FBQ0MsT0FBTyxDQUFDVSxLQUFULEVBQWdCUCxTQUFoQixFQUEyQkgsT0FBTyxDQUFDRSxPQUFuQyxDQUFsQjtBQUNELEdBRk0sTUFFQSxJQUFJRixPQUFPLENBQUNBLE9BQVosRUFBcUI7QUFDMUIsV0FBT0QsV0FBVyxDQUFDQyxPQUFPLENBQUNBLE9BQVQsRUFBa0JHLFNBQWxCLEVBQTZCSCxPQUFPLENBQUNFLE9BQXJDLENBQWxCO0FBQ0QsR0FoQ2lFLENBaUNsRTs7O0FBQ0EsU0FBT0YsT0FBUDtBQUNEOztlQUVjRCxXIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbW9kdWxlIEFkYXB0ZXJMb2FkZXJcbiAqL1xuLyoqXG4gKiBAc3RhdGljXG4gKiBBdHRlbXB0IHRvIGxvYWQgYW4gYWRhcHRlciBvciBmYWxsYmFjayB0byB0aGUgZGVmYXVsdC5cbiAqIEBwYXJhbSB7QWRhcHRlcn0gYWRhcHRlciBhbiBhZGFwdGVyXG4gKiBAcGFyYW0ge0FkYXB0ZXJ9IGRlZmF1bHRBZGFwdGVyIHRoZSBkZWZhdWx0IGFkYXB0ZXIgdG8gbG9hZFxuICogQHBhcmFtIHthbnl9IG9wdGlvbnMgb3B0aW9ucyB0byBwYXNzIHRvIHRoZSBjb250c3RydWN0b3JcbiAqIEByZXR1cm5zIHtPYmplY3R9IHRoZSBsb2FkZWQgYWRhcHRlclxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9hZEFkYXB0ZXI8VD4oYWRhcHRlciwgZGVmYXVsdEFkYXB0ZXIsIG9wdGlvbnMpOiBUIHtcbiAgaWYgKCFhZGFwdGVyKSB7XG4gICAgaWYgKCFkZWZhdWx0QWRhcHRlcikge1xuICAgICAgcmV0dXJuIG9wdGlvbnM7XG4gICAgfVxuICAgIC8vIExvYWQgZnJvbSB0aGUgZGVmYXVsdCBhZGFwdGVyIHdoZW4gbm8gYWRhcHRlciBpcyBzZXRcbiAgICByZXR1cm4gbG9hZEFkYXB0ZXIoZGVmYXVsdEFkYXB0ZXIsIHVuZGVmaW5lZCwgb3B0aW9ucyk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGFkYXB0ZXIgPT09ICdmdW5jdGlvbicpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGFkYXB0ZXIob3B0aW9ucyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKGUubmFtZSA9PT0gJ1R5cGVFcnJvcicpIHtcbiAgICAgICAgdmFyIEFkYXB0ZXIgPSBhZGFwdGVyO1xuICAgICAgICByZXR1cm4gbmV3IEFkYXB0ZXIob3B0aW9ucyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgYWRhcHRlciA9PT0gJ3N0cmluZycpIHtcbiAgICAvKiBlc2xpbnQtZGlzYWJsZSAqL1xuICAgIGFkYXB0ZXIgPSByZXF1aXJlKGFkYXB0ZXIpO1xuICAgIC8vIElmIGl0J3MgZGVmaW5lIGFzIGEgbW9kdWxlLCBnZXQgdGhlIGRlZmF1bHRcbiAgICBpZiAoYWRhcHRlci5kZWZhdWx0KSB7XG4gICAgICBhZGFwdGVyID0gYWRhcHRlci5kZWZhdWx0O1xuICAgIH1cbiAgICByZXR1cm4gbG9hZEFkYXB0ZXIoYWRhcHRlciwgdW5kZWZpbmVkLCBvcHRpb25zKTtcbiAgfSBlbHNlIGlmIChhZGFwdGVyLm1vZHVsZSkge1xuICAgIHJldHVybiBsb2FkQWRhcHRlcihhZGFwdGVyLm1vZHVsZSwgdW5kZWZpbmVkLCBhZGFwdGVyLm9wdGlvbnMpO1xuICB9IGVsc2UgaWYgKGFkYXB0ZXIuY2xhc3MpIHtcbiAgICByZXR1cm4gbG9hZEFkYXB0ZXIoYWRhcHRlci5jbGFzcywgdW5kZWZpbmVkLCBhZGFwdGVyLm9wdGlvbnMpO1xuICB9IGVsc2UgaWYgKGFkYXB0ZXIuYWRhcHRlcikge1xuICAgIHJldHVybiBsb2FkQWRhcHRlcihhZGFwdGVyLmFkYXB0ZXIsIHVuZGVmaW5lZCwgYWRhcHRlci5vcHRpb25zKTtcbiAgfVxuICAvLyByZXR1cm4gdGhlIGFkYXB0ZXIgYXMgcHJvdmlkZWRcbiAgcmV0dXJuIGFkYXB0ZXI7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGxvYWRBZGFwdGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Analytics/AnalyticsAdapter.js b/lib/Adapters/Analytics/AnalyticsAdapter.js deleted file mode 100644 index 32559338b1..0000000000 --- a/lib/Adapters/Analytics/AnalyticsAdapter.js +++ /dev/null @@ -1,41 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.AnalyticsAdapter = void 0; - -/*eslint no-unused-vars: "off"*/ - -/** - * @module Adapters - */ - -/** - * @interface AnalyticsAdapter - */ -class AnalyticsAdapter { - /** - @param {any} parameters: the analytics request body, analytics info will be in the dimensions property - @param {Request} req: the original http request - */ - appOpened(parameters, req) { - return Promise.resolve({}); - } - /** - @param {String} eventName: the name of the custom eventName - @param {any} parameters: the analytics request body, analytics info will be in the dimensions property - @param {Request} req: the original http request - */ - - - trackEvent(eventName, parameters, req) { - return Promise.resolve({}); - } - -} - -exports.AnalyticsAdapter = AnalyticsAdapter; -var _default = AnalyticsAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BbmFseXRpY3MvQW5hbHl0aWNzQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJBbmFseXRpY3NBZGFwdGVyIiwiYXBwT3BlbmVkIiwicGFyYW1ldGVycyIsInJlcSIsIlByb21pc2UiLCJyZXNvbHZlIiwidHJhY2tFdmVudCIsImV2ZW50TmFtZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBO0FBQ0E7QUFDQTs7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNQSxnQkFBTixDQUF1QjtBQUM1QjtBQUNGO0FBQ0E7QUFDQTtBQUNFQyxFQUFBQSxTQUFTLENBQUNDLFVBQUQsRUFBYUMsR0FBYixFQUFrQjtBQUN6QixXQUFPQyxPQUFPLENBQUNDLE9BQVIsQ0FBZ0IsRUFBaEIsQ0FBUDtBQUNEO0FBRUQ7QUFDRjtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0VDLEVBQUFBLFVBQVUsQ0FBQ0MsU0FBRCxFQUFZTCxVQUFaLEVBQXdCQyxHQUF4QixFQUE2QjtBQUNyQyxXQUFPQyxPQUFPLENBQUNDLE9BQVIsQ0FBZ0IsRUFBaEIsQ0FBUDtBQUNEOztBQWhCMkI7OztlQW1CZkwsZ0IiLCJzb3VyY2VzQ29udGVudCI6WyIvKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG4vKipcbiAqIEBtb2R1bGUgQWRhcHRlcnNcbiAqL1xuLyoqXG4gKiBAaW50ZXJmYWNlIEFuYWx5dGljc0FkYXB0ZXJcbiAqL1xuZXhwb3J0IGNsYXNzIEFuYWx5dGljc0FkYXB0ZXIge1xuICAvKipcbiAgQHBhcmFtIHthbnl9IHBhcmFtZXRlcnM6IHRoZSBhbmFseXRpY3MgcmVxdWVzdCBib2R5LCBhbmFseXRpY3MgaW5mbyB3aWxsIGJlIGluIHRoZSBkaW1lbnNpb25zIHByb3BlcnR5XG4gIEBwYXJhbSB7UmVxdWVzdH0gcmVxOiB0aGUgb3JpZ2luYWwgaHR0cCByZXF1ZXN0XG4gICAqL1xuICBhcHBPcGVuZWQocGFyYW1ldGVycywgcmVxKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gIH1cblxuICAvKipcbiAgQHBhcmFtIHtTdHJpbmd9IGV2ZW50TmFtZTogdGhlIG5hbWUgb2YgdGhlIGN1c3RvbSBldmVudE5hbWVcbiAgQHBhcmFtIHthbnl9IHBhcmFtZXRlcnM6IHRoZSBhbmFseXRpY3MgcmVxdWVzdCBib2R5LCBhbmFseXRpY3MgaW5mbyB3aWxsIGJlIGluIHRoZSBkaW1lbnNpb25zIHByb3BlcnR5XG4gIEBwYXJhbSB7UmVxdWVzdH0gcmVxOiB0aGUgb3JpZ2luYWwgaHR0cCByZXF1ZXN0XG4gICAqL1xuICB0cmFja0V2ZW50KGV2ZW50TmFtZSwgcGFyYW1ldGVycywgcmVxKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQW5hbHl0aWNzQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/AuthAdapter.js b/lib/Adapters/Auth/AuthAdapter.js deleted file mode 100644 index 5a5c4d8d52..0000000000 --- a/lib/Adapters/Auth/AuthAdapter.js +++ /dev/null @@ -1,34 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.AuthAdapter = void 0; - -/*eslint no-unused-vars: "off"*/ -class AuthAdapter { - /* - @param appIds: the specified app ids in the configuration - @param authData: the client provided authData - @param options: additional options - @returns a promise that resolves if the applicationId is valid - */ - validateAppId(appIds, authData, options) { - return Promise.resolve({}); - } - /* - @param authData: the client provided authData - @param options: additional options - */ - - - validateAuthData(authData, options) { - return Promise.resolve({}); - } - -} - -exports.AuthAdapter = AuthAdapter; -var _default = AuthAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL0F1dGhBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIkF1dGhBZGFwdGVyIiwidmFsaWRhdGVBcHBJZCIsImFwcElkcyIsImF1dGhEYXRhIiwib3B0aW9ucyIsIlByb21pc2UiLCJyZXNvbHZlIiwidmFsaWRhdGVBdXRoRGF0YSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBO0FBQ08sTUFBTUEsV0FBTixDQUFrQjtBQUN2QjtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDRUMsRUFBQUEsYUFBYSxDQUFDQyxNQUFELEVBQVNDLFFBQVQsRUFBbUJDLE9BQW5CLEVBQTRCO0FBQ3ZDLFdBQU9DLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQixFQUFoQixDQUFQO0FBQ0Q7QUFFRDtBQUNGO0FBQ0E7QUFDQTs7O0FBQ0VDLEVBQUFBLGdCQUFnQixDQUFDSixRQUFELEVBQVdDLE9BQVgsRUFBb0I7QUFDbEMsV0FBT0MsT0FBTyxDQUFDQyxPQUFSLENBQWdCLEVBQWhCLENBQVA7QUFDRDs7QUFqQnNCOzs7ZUFvQlZOLFciLCJzb3VyY2VzQ29udGVudCI6WyIvKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG5leHBvcnQgY2xhc3MgQXV0aEFkYXB0ZXIge1xuICAvKlxuICBAcGFyYW0gYXBwSWRzOiB0aGUgc3BlY2lmaWVkIGFwcCBpZHMgaW4gdGhlIGNvbmZpZ3VyYXRpb25cbiAgQHBhcmFtIGF1dGhEYXRhOiB0aGUgY2xpZW50IHByb3ZpZGVkIGF1dGhEYXRhXG4gIEBwYXJhbSBvcHRpb25zOiBhZGRpdGlvbmFsIG9wdGlvbnNcbiAgQHJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgaWYgdGhlIGFwcGxpY2F0aW9uSWQgaXMgdmFsaWRcbiAgICovXG4gIHZhbGlkYXRlQXBwSWQoYXBwSWRzLCBhdXRoRGF0YSwgb3B0aW9ucykge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe30pO1xuICB9XG5cbiAgLypcbiAgQHBhcmFtIGF1dGhEYXRhOiB0aGUgY2xpZW50IHByb3ZpZGVkIGF1dGhEYXRhXG4gIEBwYXJhbSBvcHRpb25zOiBhZGRpdGlvbmFsIG9wdGlvbnNcbiAgICovXG4gIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIG9wdGlvbnMpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBBdXRoQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/OAuth1Client.js b/lib/Adapters/Auth/OAuth1Client.js deleted file mode 100644 index a3350db5d2..0000000000 --- a/lib/Adapters/Auth/OAuth1Client.js +++ /dev/null @@ -1,227 +0,0 @@ -"use strict"; - -var https = require('https'), - crypto = require('crypto'); - -var Parse = require('parse/node').Parse; - -var OAuth = function (options) { - if (!options) { - throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'No options passed to OAuth'); - } - - this.consumer_key = options.consumer_key; - this.consumer_secret = options.consumer_secret; - this.auth_token = options.auth_token; - this.auth_token_secret = options.auth_token_secret; - this.host = options.host; - this.oauth_params = options.oauth_params || {}; -}; - -OAuth.prototype.send = function (method, path, params, body) { - var request = this.buildRequest(method, path, params, body); // Encode the body properly, the current Parse Implementation don't do it properly - - return new Promise(function (resolve, reject) { - var httpRequest = https.request(request, function (res) { - var data = ''; - res.on('data', function (chunk) { - data += chunk; - }); - res.on('end', function () { - data = JSON.parse(data); - resolve(data); - }); - }).on('error', function () { - reject('Failed to make an OAuth request'); - }); - - if (request.body) { - httpRequest.write(request.body); - } - - httpRequest.end(); - }); -}; - -OAuth.prototype.buildRequest = function (method, path, params, body) { - if (path.indexOf('/') != 0) { - path = '/' + path; - } - - if (params && Object.keys(params).length > 0) { - path += '?' + OAuth.buildParameterString(params); - } - - var request = { - host: this.host, - path: path, - method: method.toUpperCase() - }; - var oauth_params = this.oauth_params || {}; - oauth_params.oauth_consumer_key = this.consumer_key; - - if (this.auth_token) { - oauth_params['oauth_token'] = this.auth_token; - } - - request = OAuth.signRequest(request, oauth_params, this.consumer_secret, this.auth_token_secret); - - if (body && Object.keys(body).length > 0) { - request.body = OAuth.buildParameterString(body); - } - - return request; -}; - -OAuth.prototype.get = function (path, params) { - return this.send('GET', path, params); -}; - -OAuth.prototype.post = function (path, params, body) { - return this.send('POST', path, params, body); -}; -/* - Proper string %escape encoding -*/ - - -OAuth.encode = function (str) { - // discuss at: http://phpjs.org/functions/rawurlencode/ - // original by: Brett Zamir (http://brett-zamir.me) - // input by: travc - // input by: Brett Zamir (http://brett-zamir.me) - // input by: Michael Grier - // input by: Ratheous - // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // bugfixed by: Brett Zamir (http://brett-zamir.me) - // bugfixed by: Joris - // reimplemented by: Brett Zamir (http://brett-zamir.me) - // reimplemented by: Brett Zamir (http://brett-zamir.me) - // note: This reflects PHP 5.3/6.0+ behavior - // note: Please be aware that this function expects to encode into UTF-8 encoded strings, as found on - // note: pages served as UTF-8 - // example 1: rawurlencode('Kevin van Zonneveld!'); - // returns 1: 'Kevin%20van%20Zonneveld%21' - // example 2: rawurlencode('http://kevin.vanzonneveld.net/'); - // returns 2: 'http%3A%2F%2Fkevin.vanzonneveld.net%2F' - // example 3: rawurlencode('http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a'); - // returns 3: 'http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a' - str = (str + '').toString(); // Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current - // PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following. - - return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A'); -}; - -OAuth.signatureMethod = 'HMAC-SHA1'; -OAuth.version = '1.0'; -/* - Generate a nonce -*/ - -OAuth.nonce = function () { - var text = ''; - var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - - for (var i = 0; i < 30; i++) text += possible.charAt(Math.floor(Math.random() * possible.length)); - - return text; -}; - -OAuth.buildParameterString = function (obj) { - // Sort keys and encode values - if (obj) { - var keys = Object.keys(obj).sort(); // Map key=value, join them by & - - return keys.map(function (key) { - return key + '=' + OAuth.encode(obj[key]); - }).join('&'); - } - - return ''; -}; -/* - Build the signature string from the object -*/ - - -OAuth.buildSignatureString = function (method, url, parameters) { - return [method.toUpperCase(), OAuth.encode(url), OAuth.encode(parameters)].join('&'); -}; -/* - Retuns encoded HMAC-SHA1 from key and text -*/ - - -OAuth.signature = function (text, key) { - crypto = require('crypto'); - return OAuth.encode(crypto.createHmac('sha1', key).update(text).digest('base64')); -}; - -OAuth.signRequest = function (request, oauth_parameters, consumer_secret, auth_token_secret) { - oauth_parameters = oauth_parameters || {}; // Set default values - - if (!oauth_parameters.oauth_nonce) { - oauth_parameters.oauth_nonce = OAuth.nonce(); - } - - if (!oauth_parameters.oauth_timestamp) { - oauth_parameters.oauth_timestamp = Math.floor(new Date().getTime() / 1000); - } - - if (!oauth_parameters.oauth_signature_method) { - oauth_parameters.oauth_signature_method = OAuth.signatureMethod; - } - - if (!oauth_parameters.oauth_version) { - oauth_parameters.oauth_version = OAuth.version; - } - - if (!auth_token_secret) { - auth_token_secret = ''; - } // Force GET method if unset - - - if (!request.method) { - request.method = 'GET'; - } // Collect all the parameters in one signatureParameters object - - - var signatureParams = {}; - var parametersToMerge = [request.params, request.body, oauth_parameters]; - - for (var i in parametersToMerge) { - var parameters = parametersToMerge[i]; - - for (var k in parameters) { - signatureParams[k] = parameters[k]; - } - } // Create a string based on the parameters - - - var parameterString = OAuth.buildParameterString(signatureParams); // Build the signature string - - var url = 'https://' + request.host + '' + request.path; - var signatureString = OAuth.buildSignatureString(request.method, url, parameterString); // Hash the signature string - - var signatureKey = [OAuth.encode(consumer_secret), OAuth.encode(auth_token_secret)].join('&'); - var signature = OAuth.signature(signatureString, signatureKey); // Set the signature in the params - - oauth_parameters.oauth_signature = signature; - - if (!request.headers) { - request.headers = {}; - } // Set the authorization header - - - var authHeader = Object.keys(oauth_parameters).sort().map(function (key) { - var value = oauth_parameters[key]; - return key + '="' + value + '"'; - }).join(', '); - request.headers.Authorization = 'OAuth ' + authHeader; // Set the content type header - - request.headers['Content-Type'] = 'application/x-www-form-urlencoded'; - return request; -}; - -module.exports = OAuth; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL09BdXRoMUNsaWVudC5qcyJdLCJuYW1lcyI6WyJodHRwcyIsInJlcXVpcmUiLCJjcnlwdG8iLCJQYXJzZSIsIk9BdXRoIiwib3B0aW9ucyIsIkVycm9yIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiY29uc3VtZXJfa2V5IiwiY29uc3VtZXJfc2VjcmV0IiwiYXV0aF90b2tlbiIsImF1dGhfdG9rZW5fc2VjcmV0IiwiaG9zdCIsIm9hdXRoX3BhcmFtcyIsInByb3RvdHlwZSIsInNlbmQiLCJtZXRob2QiLCJwYXRoIiwicGFyYW1zIiwiYm9keSIsInJlcXVlc3QiLCJidWlsZFJlcXVlc3QiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsImh0dHBSZXF1ZXN0IiwicmVzIiwiZGF0YSIsIm9uIiwiY2h1bmsiLCJKU09OIiwicGFyc2UiLCJ3cml0ZSIsImVuZCIsImluZGV4T2YiLCJPYmplY3QiLCJrZXlzIiwibGVuZ3RoIiwiYnVpbGRQYXJhbWV0ZXJTdHJpbmciLCJ0b1VwcGVyQ2FzZSIsIm9hdXRoX2NvbnN1bWVyX2tleSIsInNpZ25SZXF1ZXN0IiwiZ2V0IiwicG9zdCIsImVuY29kZSIsInN0ciIsInRvU3RyaW5nIiwiZW5jb2RlVVJJQ29tcG9uZW50IiwicmVwbGFjZSIsInNpZ25hdHVyZU1ldGhvZCIsInZlcnNpb24iLCJub25jZSIsInRleHQiLCJwb3NzaWJsZSIsImkiLCJjaGFyQXQiLCJNYXRoIiwiZmxvb3IiLCJyYW5kb20iLCJvYmoiLCJzb3J0IiwibWFwIiwia2V5Iiwiam9pbiIsImJ1aWxkU2lnbmF0dXJlU3RyaW5nIiwidXJsIiwicGFyYW1ldGVycyIsInNpZ25hdHVyZSIsImNyZWF0ZUhtYWMiLCJ1cGRhdGUiLCJkaWdlc3QiLCJvYXV0aF9wYXJhbWV0ZXJzIiwib2F1dGhfbm9uY2UiLCJvYXV0aF90aW1lc3RhbXAiLCJEYXRlIiwiZ2V0VGltZSIsIm9hdXRoX3NpZ25hdHVyZV9tZXRob2QiLCJvYXV0aF92ZXJzaW9uIiwic2lnbmF0dXJlUGFyYW1zIiwicGFyYW1ldGVyc1RvTWVyZ2UiLCJrIiwicGFyYW1ldGVyU3RyaW5nIiwic2lnbmF0dXJlU3RyaW5nIiwic2lnbmF0dXJlS2V5Iiwib2F1dGhfc2lnbmF0dXJlIiwiaGVhZGVycyIsImF1dGhIZWFkZXIiLCJ2YWx1ZSIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLE9BQUQsQ0FBbkI7QUFBQSxJQUNFQyxNQUFNLEdBQUdELE9BQU8sQ0FBQyxRQUFELENBRGxCOztBQUVBLElBQUlFLEtBQUssR0FBR0YsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkUsS0FBbEM7O0FBRUEsSUFBSUMsS0FBSyxHQUFHLFVBQVVDLE9BQVYsRUFBbUI7QUFDN0IsTUFBSSxDQUFDQSxPQUFMLEVBQWM7QUFDWixVQUFNLElBQUlGLEtBQUssQ0FBQ0csS0FBVixDQUFnQkgsS0FBSyxDQUFDRyxLQUFOLENBQVlDLHFCQUE1QixFQUFtRCw0QkFBbkQsQ0FBTjtBQUNEOztBQUNELE9BQUtDLFlBQUwsR0FBb0JILE9BQU8sQ0FBQ0csWUFBNUI7QUFDQSxPQUFLQyxlQUFMLEdBQXVCSixPQUFPLENBQUNJLGVBQS9CO0FBQ0EsT0FBS0MsVUFBTCxHQUFrQkwsT0FBTyxDQUFDSyxVQUExQjtBQUNBLE9BQUtDLGlCQUFMLEdBQXlCTixPQUFPLENBQUNNLGlCQUFqQztBQUNBLE9BQUtDLElBQUwsR0FBWVAsT0FBTyxDQUFDTyxJQUFwQjtBQUNBLE9BQUtDLFlBQUwsR0FBb0JSLE9BQU8sQ0FBQ1EsWUFBUixJQUF3QixFQUE1QztBQUNELENBVkQ7O0FBWUFULEtBQUssQ0FBQ1UsU0FBTixDQUFnQkMsSUFBaEIsR0FBdUIsVUFBVUMsTUFBVixFQUFrQkMsSUFBbEIsRUFBd0JDLE1BQXhCLEVBQWdDQyxJQUFoQyxFQUFzQztBQUMzRCxNQUFJQyxPQUFPLEdBQUcsS0FBS0MsWUFBTCxDQUFrQkwsTUFBbEIsRUFBMEJDLElBQTFCLEVBQWdDQyxNQUFoQyxFQUF3Q0MsSUFBeEMsQ0FBZCxDQUQyRCxDQUUzRDs7QUFDQSxTQUFPLElBQUlHLE9BQUosQ0FBWSxVQUFVQyxPQUFWLEVBQW1CQyxNQUFuQixFQUEyQjtBQUM1QyxRQUFJQyxXQUFXLEdBQUd6QixLQUFLLENBQ3BCb0IsT0FEZSxDQUNQQSxPQURPLEVBQ0UsVUFBVU0sR0FBVixFQUFlO0FBQy9CLFVBQUlDLElBQUksR0FBRyxFQUFYO0FBQ0FELE1BQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLE1BQVAsRUFBZSxVQUFVQyxLQUFWLEVBQWlCO0FBQzlCRixRQUFBQSxJQUFJLElBQUlFLEtBQVI7QUFDRCxPQUZEO0FBR0FILE1BQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLEtBQVAsRUFBYyxZQUFZO0FBQ3hCRCxRQUFBQSxJQUFJLEdBQUdHLElBQUksQ0FBQ0MsS0FBTCxDQUFXSixJQUFYLENBQVA7QUFDQUosUUFBQUEsT0FBTyxDQUFDSSxJQUFELENBQVA7QUFDRCxPQUhEO0FBSUQsS0FWZSxFQVdmQyxFQVhlLENBV1osT0FYWSxFQVdILFlBQVk7QUFDdkJKLE1BQUFBLE1BQU0sQ0FBQyxpQ0FBRCxDQUFOO0FBQ0QsS0FiZSxDQUFsQjs7QUFjQSxRQUFJSixPQUFPLENBQUNELElBQVosRUFBa0I7QUFDaEJNLE1BQUFBLFdBQVcsQ0FBQ08sS0FBWixDQUFrQlosT0FBTyxDQUFDRCxJQUExQjtBQUNEOztBQUNETSxJQUFBQSxXQUFXLENBQUNRLEdBQVo7QUFDRCxHQW5CTSxDQUFQO0FBb0JELENBdkJEOztBQXlCQTdCLEtBQUssQ0FBQ1UsU0FBTixDQUFnQk8sWUFBaEIsR0FBK0IsVUFBVUwsTUFBVixFQUFrQkMsSUFBbEIsRUFBd0JDLE1BQXhCLEVBQWdDQyxJQUFoQyxFQUFzQztBQUNuRSxNQUFJRixJQUFJLENBQUNpQixPQUFMLENBQWEsR0FBYixLQUFxQixDQUF6QixFQUE0QjtBQUMxQmpCLElBQUFBLElBQUksR0FBRyxNQUFNQSxJQUFiO0FBQ0Q7O0FBQ0QsTUFBSUMsTUFBTSxJQUFJaUIsTUFBTSxDQUFDQyxJQUFQLENBQVlsQixNQUFaLEVBQW9CbUIsTUFBcEIsR0FBNkIsQ0FBM0MsRUFBOEM7QUFDNUNwQixJQUFBQSxJQUFJLElBQUksTUFBTWIsS0FBSyxDQUFDa0Msb0JBQU4sQ0FBMkJwQixNQUEzQixDQUFkO0FBQ0Q7O0FBRUQsTUFBSUUsT0FBTyxHQUFHO0FBQ1pSLElBQUFBLElBQUksRUFBRSxLQUFLQSxJQURDO0FBRVpLLElBQUFBLElBQUksRUFBRUEsSUFGTTtBQUdaRCxJQUFBQSxNQUFNLEVBQUVBLE1BQU0sQ0FBQ3VCLFdBQVA7QUFISSxHQUFkO0FBTUEsTUFBSTFCLFlBQVksR0FBRyxLQUFLQSxZQUFMLElBQXFCLEVBQXhDO0FBQ0FBLEVBQUFBLFlBQVksQ0FBQzJCLGtCQUFiLEdBQWtDLEtBQUtoQyxZQUF2Qzs7QUFDQSxNQUFJLEtBQUtFLFVBQVQsRUFBcUI7QUFDbkJHLElBQUFBLFlBQVksQ0FBQyxhQUFELENBQVosR0FBOEIsS0FBS0gsVUFBbkM7QUFDRDs7QUFFRFUsRUFBQUEsT0FBTyxHQUFHaEIsS0FBSyxDQUFDcUMsV0FBTixDQUFrQnJCLE9BQWxCLEVBQTJCUCxZQUEzQixFQUF5QyxLQUFLSixlQUE5QyxFQUErRCxLQUFLRSxpQkFBcEUsQ0FBVjs7QUFFQSxNQUFJUSxJQUFJLElBQUlnQixNQUFNLENBQUNDLElBQVAsQ0FBWWpCLElBQVosRUFBa0JrQixNQUFsQixHQUEyQixDQUF2QyxFQUEwQztBQUN4Q2pCLElBQUFBLE9BQU8sQ0FBQ0QsSUFBUixHQUFlZixLQUFLLENBQUNrQyxvQkFBTixDQUEyQm5CLElBQTNCLENBQWY7QUFDRDs7QUFDRCxTQUFPQyxPQUFQO0FBQ0QsQ0ExQkQ7O0FBNEJBaEIsS0FBSyxDQUFDVSxTQUFOLENBQWdCNEIsR0FBaEIsR0FBc0IsVUFBVXpCLElBQVYsRUFBZ0JDLE1BQWhCLEVBQXdCO0FBQzVDLFNBQU8sS0FBS0gsSUFBTCxDQUFVLEtBQVYsRUFBaUJFLElBQWpCLEVBQXVCQyxNQUF2QixDQUFQO0FBQ0QsQ0FGRDs7QUFJQWQsS0FBSyxDQUFDVSxTQUFOLENBQWdCNkIsSUFBaEIsR0FBdUIsVUFBVTFCLElBQVYsRUFBZ0JDLE1BQWhCLEVBQXdCQyxJQUF4QixFQUE4QjtBQUNuRCxTQUFPLEtBQUtKLElBQUwsQ0FBVSxNQUFWLEVBQWtCRSxJQUFsQixFQUF3QkMsTUFBeEIsRUFBZ0NDLElBQWhDLENBQVA7QUFDRCxDQUZEO0FBSUE7QUFDQTtBQUNBOzs7QUFDQWYsS0FBSyxDQUFDd0MsTUFBTixHQUFlLFVBQVVDLEdBQVYsRUFBZTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUFBLEVBQUFBLEdBQUcsR0FBRyxDQUFDQSxHQUFHLEdBQUcsRUFBUCxFQUFXQyxRQUFYLEVBQU4sQ0F0QjRCLENBd0I1QjtBQUNBOztBQUNBLFNBQU9DLGtCQUFrQixDQUFDRixHQUFELENBQWxCLENBQ0pHLE9BREksQ0FDSSxJQURKLEVBQ1UsS0FEVixFQUVKQSxPQUZJLENBRUksSUFGSixFQUVVLEtBRlYsRUFHSkEsT0FISSxDQUdJLEtBSEosRUFHVyxLQUhYLEVBSUpBLE9BSkksQ0FJSSxLQUpKLEVBSVcsS0FKWCxFQUtKQSxPQUxJLENBS0ksS0FMSixFQUtXLEtBTFgsQ0FBUDtBQU1ELENBaENEOztBQWtDQTVDLEtBQUssQ0FBQzZDLGVBQU4sR0FBd0IsV0FBeEI7QUFDQTdDLEtBQUssQ0FBQzhDLE9BQU4sR0FBZ0IsS0FBaEI7QUFFQTtBQUNBO0FBQ0E7O0FBQ0E5QyxLQUFLLENBQUMrQyxLQUFOLEdBQWMsWUFBWTtBQUN4QixNQUFJQyxJQUFJLEdBQUcsRUFBWDtBQUNBLE1BQUlDLFFBQVEsR0FBRyxnRUFBZjs7QUFFQSxPQUFLLElBQUlDLENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUcsRUFBcEIsRUFBd0JBLENBQUMsRUFBekIsRUFBNkJGLElBQUksSUFBSUMsUUFBUSxDQUFDRSxNQUFULENBQWdCQyxJQUFJLENBQUNDLEtBQUwsQ0FBV0QsSUFBSSxDQUFDRSxNQUFMLEtBQWdCTCxRQUFRLENBQUNoQixNQUFwQyxDQUFoQixDQUFSOztBQUU3QixTQUFPZSxJQUFQO0FBQ0QsQ0FQRDs7QUFTQWhELEtBQUssQ0FBQ2tDLG9CQUFOLEdBQTZCLFVBQVVxQixHQUFWLEVBQWU7QUFDMUM7QUFDQSxNQUFJQSxHQUFKLEVBQVM7QUFDUCxRQUFJdkIsSUFBSSxHQUFHRCxNQUFNLENBQUNDLElBQVAsQ0FBWXVCLEdBQVosRUFBaUJDLElBQWpCLEVBQVgsQ0FETyxDQUdQOztBQUNBLFdBQU94QixJQUFJLENBQ1J5QixHQURJLENBQ0EsVUFBVUMsR0FBVixFQUFlO0FBQ2xCLGFBQU9BLEdBQUcsR0FBRyxHQUFOLEdBQVkxRCxLQUFLLENBQUN3QyxNQUFOLENBQWFlLEdBQUcsQ0FBQ0csR0FBRCxDQUFoQixDQUFuQjtBQUNELEtBSEksRUFJSkMsSUFKSSxDQUlDLEdBSkQsQ0FBUDtBQUtEOztBQUVELFNBQU8sRUFBUDtBQUNELENBZEQ7QUFnQkE7QUFDQTtBQUNBOzs7QUFFQTNELEtBQUssQ0FBQzRELG9CQUFOLEdBQTZCLFVBQVVoRCxNQUFWLEVBQWtCaUQsR0FBbEIsRUFBdUJDLFVBQXZCLEVBQW1DO0FBQzlELFNBQU8sQ0FBQ2xELE1BQU0sQ0FBQ3VCLFdBQVAsRUFBRCxFQUF1Qm5DLEtBQUssQ0FBQ3dDLE1BQU4sQ0FBYXFCLEdBQWIsQ0FBdkIsRUFBMEM3RCxLQUFLLENBQUN3QyxNQUFOLENBQWFzQixVQUFiLENBQTFDLEVBQW9FSCxJQUFwRSxDQUF5RSxHQUF6RSxDQUFQO0FBQ0QsQ0FGRDtBQUlBO0FBQ0E7QUFDQTs7O0FBQ0EzRCxLQUFLLENBQUMrRCxTQUFOLEdBQWtCLFVBQVVmLElBQVYsRUFBZ0JVLEdBQWhCLEVBQXFCO0FBQ3JDNUQsRUFBQUEsTUFBTSxHQUFHRCxPQUFPLENBQUMsUUFBRCxDQUFoQjtBQUNBLFNBQU9HLEtBQUssQ0FBQ3dDLE1BQU4sQ0FBYTFDLE1BQU0sQ0FBQ2tFLFVBQVAsQ0FBa0IsTUFBbEIsRUFBMEJOLEdBQTFCLEVBQStCTyxNQUEvQixDQUFzQ2pCLElBQXRDLEVBQTRDa0IsTUFBNUMsQ0FBbUQsUUFBbkQsQ0FBYixDQUFQO0FBQ0QsQ0FIRDs7QUFLQWxFLEtBQUssQ0FBQ3FDLFdBQU4sR0FBb0IsVUFBVXJCLE9BQVYsRUFBbUJtRCxnQkFBbkIsRUFBcUM5RCxlQUFyQyxFQUFzREUsaUJBQXRELEVBQXlFO0FBQzNGNEQsRUFBQUEsZ0JBQWdCLEdBQUdBLGdCQUFnQixJQUFJLEVBQXZDLENBRDJGLENBRzNGOztBQUNBLE1BQUksQ0FBQ0EsZ0JBQWdCLENBQUNDLFdBQXRCLEVBQW1DO0FBQ2pDRCxJQUFBQSxnQkFBZ0IsQ0FBQ0MsV0FBakIsR0FBK0JwRSxLQUFLLENBQUMrQyxLQUFOLEVBQS9CO0FBQ0Q7O0FBQ0QsTUFBSSxDQUFDb0IsZ0JBQWdCLENBQUNFLGVBQXRCLEVBQXVDO0FBQ3JDRixJQUFBQSxnQkFBZ0IsQ0FBQ0UsZUFBakIsR0FBbUNqQixJQUFJLENBQUNDLEtBQUwsQ0FBVyxJQUFJaUIsSUFBSixHQUFXQyxPQUFYLEtBQXVCLElBQWxDLENBQW5DO0FBQ0Q7O0FBQ0QsTUFBSSxDQUFDSixnQkFBZ0IsQ0FBQ0ssc0JBQXRCLEVBQThDO0FBQzVDTCxJQUFBQSxnQkFBZ0IsQ0FBQ0ssc0JBQWpCLEdBQTBDeEUsS0FBSyxDQUFDNkMsZUFBaEQ7QUFDRDs7QUFDRCxNQUFJLENBQUNzQixnQkFBZ0IsQ0FBQ00sYUFBdEIsRUFBcUM7QUFDbkNOLElBQUFBLGdCQUFnQixDQUFDTSxhQUFqQixHQUFpQ3pFLEtBQUssQ0FBQzhDLE9BQXZDO0FBQ0Q7O0FBRUQsTUFBSSxDQUFDdkMsaUJBQUwsRUFBd0I7QUFDdEJBLElBQUFBLGlCQUFpQixHQUFHLEVBQXBCO0FBQ0QsR0FuQjBGLENBb0IzRjs7O0FBQ0EsTUFBSSxDQUFDUyxPQUFPLENBQUNKLE1BQWIsRUFBcUI7QUFDbkJJLElBQUFBLE9BQU8sQ0FBQ0osTUFBUixHQUFpQixLQUFqQjtBQUNELEdBdkIwRixDQXlCM0Y7OztBQUNBLE1BQUk4RCxlQUFlLEdBQUcsRUFBdEI7QUFDQSxNQUFJQyxpQkFBaUIsR0FBRyxDQUFDM0QsT0FBTyxDQUFDRixNQUFULEVBQWlCRSxPQUFPLENBQUNELElBQXpCLEVBQStCb0QsZ0JBQS9CLENBQXhCOztBQUNBLE9BQUssSUFBSWpCLENBQVQsSUFBY3lCLGlCQUFkLEVBQWlDO0FBQy9CLFFBQUliLFVBQVUsR0FBR2EsaUJBQWlCLENBQUN6QixDQUFELENBQWxDOztBQUNBLFNBQUssSUFBSTBCLENBQVQsSUFBY2QsVUFBZCxFQUEwQjtBQUN4QlksTUFBQUEsZUFBZSxDQUFDRSxDQUFELENBQWYsR0FBcUJkLFVBQVUsQ0FBQ2MsQ0FBRCxDQUEvQjtBQUNEO0FBQ0YsR0FqQzBGLENBbUMzRjs7O0FBQ0EsTUFBSUMsZUFBZSxHQUFHN0UsS0FBSyxDQUFDa0Msb0JBQU4sQ0FBMkJ3QyxlQUEzQixDQUF0QixDQXBDMkYsQ0FzQzNGOztBQUNBLE1BQUliLEdBQUcsR0FBRyxhQUFhN0MsT0FBTyxDQUFDUixJQUFyQixHQUE0QixFQUE1QixHQUFpQ1EsT0FBTyxDQUFDSCxJQUFuRDtBQUVBLE1BQUlpRSxlQUFlLEdBQUc5RSxLQUFLLENBQUM0RCxvQkFBTixDQUEyQjVDLE9BQU8sQ0FBQ0osTUFBbkMsRUFBMkNpRCxHQUEzQyxFQUFnRGdCLGVBQWhELENBQXRCLENBekMyRixDQTBDM0Y7O0FBQ0EsTUFBSUUsWUFBWSxHQUFHLENBQUMvRSxLQUFLLENBQUN3QyxNQUFOLENBQWFuQyxlQUFiLENBQUQsRUFBZ0NMLEtBQUssQ0FBQ3dDLE1BQU4sQ0FBYWpDLGlCQUFiLENBQWhDLEVBQWlFb0QsSUFBakUsQ0FBc0UsR0FBdEUsQ0FBbkI7QUFFQSxNQUFJSSxTQUFTLEdBQUcvRCxLQUFLLENBQUMrRCxTQUFOLENBQWdCZSxlQUFoQixFQUFpQ0MsWUFBakMsQ0FBaEIsQ0E3QzJGLENBK0MzRjs7QUFDQVosRUFBQUEsZ0JBQWdCLENBQUNhLGVBQWpCLEdBQW1DakIsU0FBbkM7O0FBQ0EsTUFBSSxDQUFDL0MsT0FBTyxDQUFDaUUsT0FBYixFQUFzQjtBQUNwQmpFLElBQUFBLE9BQU8sQ0FBQ2lFLE9BQVIsR0FBa0IsRUFBbEI7QUFDRCxHQW5EMEYsQ0FxRDNGOzs7QUFDQSxNQUFJQyxVQUFVLEdBQUduRCxNQUFNLENBQUNDLElBQVAsQ0FBWW1DLGdCQUFaLEVBQ2RYLElBRGMsR0FFZEMsR0FGYyxDQUVWLFVBQVVDLEdBQVYsRUFBZTtBQUNsQixRQUFJeUIsS0FBSyxHQUFHaEIsZ0JBQWdCLENBQUNULEdBQUQsQ0FBNUI7QUFDQSxXQUFPQSxHQUFHLEdBQUcsSUFBTixHQUFheUIsS0FBYixHQUFxQixHQUE1QjtBQUNELEdBTGMsRUFNZHhCLElBTmMsQ0FNVCxJQU5TLENBQWpCO0FBUUEzQyxFQUFBQSxPQUFPLENBQUNpRSxPQUFSLENBQWdCRyxhQUFoQixHQUFnQyxXQUFXRixVQUEzQyxDQTlEMkYsQ0FnRTNGOztBQUNBbEUsRUFBQUEsT0FBTyxDQUFDaUUsT0FBUixDQUFnQixjQUFoQixJQUFrQyxtQ0FBbEM7QUFDQSxTQUFPakUsT0FBUDtBQUNELENBbkVEOztBQXFFQXFFLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQnRGLEtBQWpCIiwic291cmNlc0NvbnRlbnQiOlsidmFyIGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKSxcbiAgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbnZhciBPQXV0aCA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gIGlmICghb3B0aW9ucykge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsICdObyBvcHRpb25zIHBhc3NlZCB0byBPQXV0aCcpO1xuICB9XG4gIHRoaXMuY29uc3VtZXJfa2V5ID0gb3B0aW9ucy5jb25zdW1lcl9rZXk7XG4gIHRoaXMuY29uc3VtZXJfc2VjcmV0ID0gb3B0aW9ucy5jb25zdW1lcl9zZWNyZXQ7XG4gIHRoaXMuYXV0aF90b2tlbiA9IG9wdGlvbnMuYXV0aF90b2tlbjtcbiAgdGhpcy5hdXRoX3Rva2VuX3NlY3JldCA9IG9wdGlvbnMuYXV0aF90b2tlbl9zZWNyZXQ7XG4gIHRoaXMuaG9zdCA9IG9wdGlvbnMuaG9zdDtcbiAgdGhpcy5vYXV0aF9wYXJhbXMgPSBvcHRpb25zLm9hdXRoX3BhcmFtcyB8fCB7fTtcbn07XG5cbk9BdXRoLnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24gKG1ldGhvZCwgcGF0aCwgcGFyYW1zLCBib2R5KSB7XG4gIHZhciByZXF1ZXN0ID0gdGhpcy5idWlsZFJlcXVlc3QobWV0aG9kLCBwYXRoLCBwYXJhbXMsIGJvZHkpO1xuICAvLyBFbmNvZGUgdGhlIGJvZHkgcHJvcGVybHksIHRoZSBjdXJyZW50IFBhcnNlIEltcGxlbWVudGF0aW9uIGRvbid0IGRvIGl0IHByb3Blcmx5XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgdmFyIGh0dHBSZXF1ZXN0ID0gaHR0cHNcbiAgICAgIC5yZXF1ZXN0KHJlcXVlc3QsIGZ1bmN0aW9uIChyZXMpIHtcbiAgICAgICAgdmFyIGRhdGEgPSAnJztcbiAgICAgICAgcmVzLm9uKCdkYXRhJywgZnVuY3Rpb24gKGNodW5rKSB7XG4gICAgICAgICAgZGF0YSArPSBjaHVuaztcbiAgICAgICAgfSk7XG4gICAgICAgIHJlcy5vbignZW5kJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGRhdGEgPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgICAgICAgIHJlc29sdmUoZGF0YSk7XG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC5vbignZXJyb3InLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJlamVjdCgnRmFpbGVkIHRvIG1ha2UgYW4gT0F1dGggcmVxdWVzdCcpO1xuICAgICAgfSk7XG4gICAgaWYgKHJlcXVlc3QuYm9keSkge1xuICAgICAgaHR0cFJlcXVlc3Qud3JpdGUocmVxdWVzdC5ib2R5KTtcbiAgICB9XG4gICAgaHR0cFJlcXVlc3QuZW5kKCk7XG4gIH0pO1xufTtcblxuT0F1dGgucHJvdG90eXBlLmJ1aWxkUmVxdWVzdCA9IGZ1bmN0aW9uIChtZXRob2QsIHBhdGgsIHBhcmFtcywgYm9keSkge1xuICBpZiAocGF0aC5pbmRleE9mKCcvJykgIT0gMCkge1xuICAgIHBhdGggPSAnLycgKyBwYXRoO1xuICB9XG4gIGlmIChwYXJhbXMgJiYgT2JqZWN0LmtleXMocGFyYW1zKS5sZW5ndGggPiAwKSB7XG4gICAgcGF0aCArPSAnPycgKyBPQXV0aC5idWlsZFBhcmFtZXRlclN0cmluZyhwYXJhbXMpO1xuICB9XG5cbiAgdmFyIHJlcXVlc3QgPSB7XG4gICAgaG9zdDogdGhpcy5ob3N0LFxuICAgIHBhdGg6IHBhdGgsXG4gICAgbWV0aG9kOiBtZXRob2QudG9VcHBlckNhc2UoKSxcbiAgfTtcblxuICB2YXIgb2F1dGhfcGFyYW1zID0gdGhpcy5vYXV0aF9wYXJhbXMgfHwge307XG4gIG9hdXRoX3BhcmFtcy5vYXV0aF9jb25zdW1lcl9rZXkgPSB0aGlzLmNvbnN1bWVyX2tleTtcbiAgaWYgKHRoaXMuYXV0aF90b2tlbikge1xuICAgIG9hdXRoX3BhcmFtc1snb2F1dGhfdG9rZW4nXSA9IHRoaXMuYXV0aF90b2tlbjtcbiAgfVxuXG4gIHJlcXVlc3QgPSBPQXV0aC5zaWduUmVxdWVzdChyZXF1ZXN0LCBvYXV0aF9wYXJhbXMsIHRoaXMuY29uc3VtZXJfc2VjcmV0LCB0aGlzLmF1dGhfdG9rZW5fc2VjcmV0KTtcblxuICBpZiAoYm9keSAmJiBPYmplY3Qua2V5cyhib2R5KS5sZW5ndGggPiAwKSB7XG4gICAgcmVxdWVzdC5ib2R5ID0gT0F1dGguYnVpbGRQYXJhbWV0ZXJTdHJpbmcoYm9keSk7XG4gIH1cbiAgcmV0dXJuIHJlcXVlc3Q7XG59O1xuXG5PQXV0aC5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKHBhdGgsIHBhcmFtcykge1xuICByZXR1cm4gdGhpcy5zZW5kKCdHRVQnLCBwYXRoLCBwYXJhbXMpO1xufTtcblxuT0F1dGgucHJvdG90eXBlLnBvc3QgPSBmdW5jdGlvbiAocGF0aCwgcGFyYW1zLCBib2R5KSB7XG4gIHJldHVybiB0aGlzLnNlbmQoJ1BPU1QnLCBwYXRoLCBwYXJhbXMsIGJvZHkpO1xufTtcblxuLypcblx0UHJvcGVyIHN0cmluZyAlZXNjYXBlIGVuY29kaW5nXG4qL1xuT0F1dGguZW5jb2RlID0gZnVuY3Rpb24gKHN0cikge1xuICAvLyAgICAgICBkaXNjdXNzIGF0OiBodHRwOi8vcGhwanMub3JnL2Z1bmN0aW9ucy9yYXd1cmxlbmNvZGUvXG4gIC8vICAgICAgb3JpZ2luYWwgYnk6IEJyZXR0IFphbWlyIChodHRwOi8vYnJldHQtemFtaXIubWUpXG4gIC8vICAgICAgICAgaW5wdXQgYnk6IHRyYXZjXG4gIC8vICAgICAgICAgaW5wdXQgYnk6IEJyZXR0IFphbWlyIChodHRwOi8vYnJldHQtemFtaXIubWUpXG4gIC8vICAgICAgICAgaW5wdXQgYnk6IE1pY2hhZWwgR3JpZXJcbiAgLy8gICAgICAgICBpbnB1dCBieTogUmF0aGVvdXNcbiAgLy8gICAgICBidWdmaXhlZCBieTogS2V2aW4gdmFuIFpvbm5ldmVsZCAoaHR0cDovL2tldmluLnZhbnpvbm5ldmVsZC5uZXQpXG4gIC8vICAgICAgYnVnZml4ZWQgYnk6IEJyZXR0IFphbWlyIChodHRwOi8vYnJldHQtemFtaXIubWUpXG4gIC8vICAgICAgYnVnZml4ZWQgYnk6IEpvcmlzXG4gIC8vIHJlaW1wbGVtZW50ZWQgYnk6IEJyZXR0IFphbWlyIChodHRwOi8vYnJldHQtemFtaXIubWUpXG4gIC8vIHJlaW1wbGVtZW50ZWQgYnk6IEJyZXR0IFphbWlyIChodHRwOi8vYnJldHQtemFtaXIubWUpXG4gIC8vICAgICAgICAgICAgIG5vdGU6IFRoaXMgcmVmbGVjdHMgUEhQIDUuMy82LjArIGJlaGF2aW9yXG4gIC8vICAgICAgICAgICAgIG5vdGU6IFBsZWFzZSBiZSBhd2FyZSB0aGF0IHRoaXMgZnVuY3Rpb24gZXhwZWN0cyB0byBlbmNvZGUgaW50byBVVEYtOCBlbmNvZGVkIHN0cmluZ3MsIGFzIGZvdW5kIG9uXG4gIC8vICAgICAgICAgICAgIG5vdGU6IHBhZ2VzIHNlcnZlZCBhcyBVVEYtOFxuICAvLyAgICAgICAgZXhhbXBsZSAxOiByYXd1cmxlbmNvZGUoJ0tldmluIHZhbiBab25uZXZlbGQhJyk7XG4gIC8vICAgICAgICByZXR1cm5zIDE6ICdLZXZpbiUyMHZhbiUyMFpvbm5ldmVsZCUyMSdcbiAgLy8gICAgICAgIGV4YW1wbGUgMjogcmF3dXJsZW5jb2RlKCdodHRwOi8va2V2aW4udmFuem9ubmV2ZWxkLm5ldC8nKTtcbiAgLy8gICAgICAgIHJldHVybnMgMjogJ2h0dHAlM0ElMkYlMkZrZXZpbi52YW56b25uZXZlbGQubmV0JTJGJ1xuICAvLyAgICAgICAgZXhhbXBsZSAzOiByYXd1cmxlbmNvZGUoJ2h0dHA6Ly93d3cuZ29vZ2xlLm5sL3NlYXJjaD9xPXBocC5qcyZpZT11dGYtOCZvZT11dGYtOCZhcT10JnJscz1jb20udWJ1bnR1OmVuLVVTOnVub2ZmaWNpYWwmY2xpZW50PWZpcmVmb3gtYScpO1xuICAvLyAgICAgICAgcmV0dXJucyAzOiAnaHR0cCUzQSUyRiUyRnd3dy5nb29nbGUubmwlMkZzZWFyY2glM0ZxJTNEcGhwLmpzJTI2aWUlM0R1dGYtOCUyNm9lJTNEdXRmLTglMjZhcSUzRHQlMjZybHMlM0Rjb20udWJ1bnR1JTNBZW4tVVMlM0F1bm9mZmljaWFsJTI2Y2xpZW50JTNEZmlyZWZveC1hJ1xuXG4gIHN0ciA9IChzdHIgKyAnJykudG9TdHJpbmcoKTtcblxuICAvLyBUaWxkZSBzaG91bGQgYmUgYWxsb3dlZCB1bmVzY2FwZWQgaW4gZnV0dXJlIHZlcnNpb25zIG9mIFBIUCAoYXMgcmVmbGVjdGVkIGJlbG93KSwgYnV0IGlmIHlvdSB3YW50IHRvIHJlZmxlY3QgY3VycmVudFxuICAvLyBQSFAgYmVoYXZpb3IsIHlvdSB3b3VsZCBuZWVkIHRvIGFkZCBcIi5yZXBsYWNlKC9+L2csICclN0UnKTtcIiB0byB0aGUgZm9sbG93aW5nLlxuICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KHN0cilcbiAgICAucmVwbGFjZSgvIS9nLCAnJTIxJylcbiAgICAucmVwbGFjZSgvJy9nLCAnJTI3JylcbiAgICAucmVwbGFjZSgvXFwoL2csICclMjgnKVxuICAgIC5yZXBsYWNlKC9cXCkvZywgJyUyOScpXG4gICAgLnJlcGxhY2UoL1xcKi9nLCAnJTJBJyk7XG59O1xuXG5PQXV0aC5zaWduYXR1cmVNZXRob2QgPSAnSE1BQy1TSEExJztcbk9BdXRoLnZlcnNpb24gPSAnMS4wJztcblxuLypcblx0R2VuZXJhdGUgYSBub25jZVxuKi9cbk9BdXRoLm5vbmNlID0gZnVuY3Rpb24gKCkge1xuICB2YXIgdGV4dCA9ICcnO1xuICB2YXIgcG9zc2libGUgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODknO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgMzA7IGkrKykgdGV4dCArPSBwb3NzaWJsZS5jaGFyQXQoTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogcG9zc2libGUubGVuZ3RoKSk7XG5cbiAgcmV0dXJuIHRleHQ7XG59O1xuXG5PQXV0aC5idWlsZFBhcmFtZXRlclN0cmluZyA9IGZ1bmN0aW9uIChvYmopIHtcbiAgLy8gU29ydCBrZXlzIGFuZCBlbmNvZGUgdmFsdWVzXG4gIGlmIChvYmopIHtcbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG9iaikuc29ydCgpO1xuXG4gICAgLy8gTWFwIGtleT12YWx1ZSwgam9pbiB0aGVtIGJ5ICZcbiAgICByZXR1cm4ga2V5c1xuICAgICAgLm1hcChmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgIHJldHVybiBrZXkgKyAnPScgKyBPQXV0aC5lbmNvZGUob2JqW2tleV0pO1xuICAgICAgfSlcbiAgICAgIC5qb2luKCcmJyk7XG4gIH1cblxuICByZXR1cm4gJyc7XG59O1xuXG4vKlxuXHRCdWlsZCB0aGUgc2lnbmF0dXJlIHN0cmluZyBmcm9tIHRoZSBvYmplY3RcbiovXG5cbk9BdXRoLmJ1aWxkU2lnbmF0dXJlU3RyaW5nID0gZnVuY3Rpb24gKG1ldGhvZCwgdXJsLCBwYXJhbWV0ZXJzKSB7XG4gIHJldHVybiBbbWV0aG9kLnRvVXBwZXJDYXNlKCksIE9BdXRoLmVuY29kZSh1cmwpLCBPQXV0aC5lbmNvZGUocGFyYW1ldGVycyldLmpvaW4oJyYnKTtcbn07XG5cbi8qXG5cdFJldHVucyBlbmNvZGVkIEhNQUMtU0hBMSBmcm9tIGtleSBhbmQgdGV4dFxuKi9cbk9BdXRoLnNpZ25hdHVyZSA9IGZ1bmN0aW9uICh0ZXh0LCBrZXkpIHtcbiAgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG4gIHJldHVybiBPQXV0aC5lbmNvZGUoY3J5cHRvLmNyZWF0ZUhtYWMoJ3NoYTEnLCBrZXkpLnVwZGF0ZSh0ZXh0KS5kaWdlc3QoJ2Jhc2U2NCcpKTtcbn07XG5cbk9BdXRoLnNpZ25SZXF1ZXN0ID0gZnVuY3Rpb24gKHJlcXVlc3QsIG9hdXRoX3BhcmFtZXRlcnMsIGNvbnN1bWVyX3NlY3JldCwgYXV0aF90b2tlbl9zZWNyZXQpIHtcbiAgb2F1dGhfcGFyYW1ldGVycyA9IG9hdXRoX3BhcmFtZXRlcnMgfHwge307XG5cbiAgLy8gU2V0IGRlZmF1bHQgdmFsdWVzXG4gIGlmICghb2F1dGhfcGFyYW1ldGVycy5vYXV0aF9ub25jZSkge1xuICAgIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfbm9uY2UgPSBPQXV0aC5ub25jZSgpO1xuICB9XG4gIGlmICghb2F1dGhfcGFyYW1ldGVycy5vYXV0aF90aW1lc3RhbXApIHtcbiAgICBvYXV0aF9wYXJhbWV0ZXJzLm9hdXRoX3RpbWVzdGFtcCA9IE1hdGguZmxvb3IobmV3IERhdGUoKS5nZXRUaW1lKCkgLyAxMDAwKTtcbiAgfVxuICBpZiAoIW9hdXRoX3BhcmFtZXRlcnMub2F1dGhfc2lnbmF0dXJlX21ldGhvZCkge1xuICAgIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfc2lnbmF0dXJlX21ldGhvZCA9IE9BdXRoLnNpZ25hdHVyZU1ldGhvZDtcbiAgfVxuICBpZiAoIW9hdXRoX3BhcmFtZXRlcnMub2F1dGhfdmVyc2lvbikge1xuICAgIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfdmVyc2lvbiA9IE9BdXRoLnZlcnNpb247XG4gIH1cblxuICBpZiAoIWF1dGhfdG9rZW5fc2VjcmV0KSB7XG4gICAgYXV0aF90b2tlbl9zZWNyZXQgPSAnJztcbiAgfVxuICAvLyBGb3JjZSBHRVQgbWV0aG9kIGlmIHVuc2V0XG4gIGlmICghcmVxdWVzdC5tZXRob2QpIHtcbiAgICByZXF1ZXN0Lm1ldGhvZCA9ICdHRVQnO1xuICB9XG5cbiAgLy8gQ29sbGVjdCAgYWxsIHRoZSBwYXJhbWV0ZXJzIGluIG9uZSBzaWduYXR1cmVQYXJhbWV0ZXJzIG9iamVjdFxuICB2YXIgc2lnbmF0dXJlUGFyYW1zID0ge307XG4gIHZhciBwYXJhbWV0ZXJzVG9NZXJnZSA9IFtyZXF1ZXN0LnBhcmFtcywgcmVxdWVzdC5ib2R5LCBvYXV0aF9wYXJhbWV0ZXJzXTtcbiAgZm9yICh2YXIgaSBpbiBwYXJhbWV0ZXJzVG9NZXJnZSkge1xuICAgIHZhciBwYXJhbWV0ZXJzID0gcGFyYW1ldGVyc1RvTWVyZ2VbaV07XG4gICAgZm9yICh2YXIgayBpbiBwYXJhbWV0ZXJzKSB7XG4gICAgICBzaWduYXR1cmVQYXJhbXNba10gPSBwYXJhbWV0ZXJzW2tdO1xuICAgIH1cbiAgfVxuXG4gIC8vIENyZWF0ZSBhIHN0cmluZyBiYXNlZCBvbiB0aGUgcGFyYW1ldGVyc1xuICB2YXIgcGFyYW1ldGVyU3RyaW5nID0gT0F1dGguYnVpbGRQYXJhbWV0ZXJTdHJpbmcoc2lnbmF0dXJlUGFyYW1zKTtcblxuICAvLyBCdWlsZCB0aGUgc2lnbmF0dXJlIHN0cmluZ1xuICB2YXIgdXJsID0gJ2h0dHBzOi8vJyArIHJlcXVlc3QuaG9zdCArICcnICsgcmVxdWVzdC5wYXRoO1xuXG4gIHZhciBzaWduYXR1cmVTdHJpbmcgPSBPQXV0aC5idWlsZFNpZ25hdHVyZVN0cmluZyhyZXF1ZXN0Lm1ldGhvZCwgdXJsLCBwYXJhbWV0ZXJTdHJpbmcpO1xuICAvLyBIYXNoIHRoZSBzaWduYXR1cmUgc3RyaW5nXG4gIHZhciBzaWduYXR1cmVLZXkgPSBbT0F1dGguZW5jb2RlKGNvbnN1bWVyX3NlY3JldCksIE9BdXRoLmVuY29kZShhdXRoX3Rva2VuX3NlY3JldCldLmpvaW4oJyYnKTtcblxuICB2YXIgc2lnbmF0dXJlID0gT0F1dGguc2lnbmF0dXJlKHNpZ25hdHVyZVN0cmluZywgc2lnbmF0dXJlS2V5KTtcblxuICAvLyBTZXQgdGhlIHNpZ25hdHVyZSBpbiB0aGUgcGFyYW1zXG4gIG9hdXRoX3BhcmFtZXRlcnMub2F1dGhfc2lnbmF0dXJlID0gc2lnbmF0dXJlO1xuICBpZiAoIXJlcXVlc3QuaGVhZGVycykge1xuICAgIHJlcXVlc3QuaGVhZGVycyA9IHt9O1xuICB9XG5cbiAgLy8gU2V0IHRoZSBhdXRob3JpemF0aW9uIGhlYWRlclxuICB2YXIgYXV0aEhlYWRlciA9IE9iamVjdC5rZXlzKG9hdXRoX3BhcmFtZXRlcnMpXG4gICAgLnNvcnQoKVxuICAgIC5tYXAoZnVuY3Rpb24gKGtleSkge1xuICAgICAgdmFyIHZhbHVlID0gb2F1dGhfcGFyYW1ldGVyc1trZXldO1xuICAgICAgcmV0dXJuIGtleSArICc9XCInICsgdmFsdWUgKyAnXCInO1xuICAgIH0pXG4gICAgLmpvaW4oJywgJyk7XG5cbiAgcmVxdWVzdC5oZWFkZXJzLkF1dGhvcml6YXRpb24gPSAnT0F1dGggJyArIGF1dGhIZWFkZXI7XG5cbiAgLy8gU2V0IHRoZSBjb250ZW50IHR5cGUgaGVhZGVyXG4gIHJlcXVlc3QuaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJztcbiAgcmV0dXJuIHJlcXVlc3Q7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE9BdXRoO1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/apple.js b/lib/Adapters/Auth/apple.js deleted file mode 100644 index 86ed2e216e..0000000000 --- a/lib/Adapters/Auth/apple.js +++ /dev/null @@ -1,105 +0,0 @@ -"use strict"; - -// Apple SignIn Auth -// https://developer.apple.com/documentation/signinwithapplerestapi -const Parse = require('parse/node').Parse; - -const jwksClient = require('jwks-rsa'); - -const util = require('util'); - -const jwt = require('jsonwebtoken'); - -const TOKEN_ISSUER = 'https://appleid.apple.com'; - -const getAppleKeyByKeyId = async (keyId, cacheMaxEntries, cacheMaxAge) => { - const client = jwksClient({ - jwksUri: `${TOKEN_ISSUER}/auth/keys`, - cache: true, - cacheMaxEntries, - cacheMaxAge - }); - const asyncGetSigningKeyFunction = util.promisify(client.getSigningKey); - let key; - - try { - key = await asyncGetSigningKeyFunction(keyId); - } catch (error) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Unable to find matching key for Key ID: ${keyId}`); - } - - return key; -}; - -const getHeaderFromToken = token => { - const decodedToken = jwt.decode(token, { - complete: true - }); - - if (!decodedToken) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `provided token does not decode as JWT`); - } - - return decodedToken.header; -}; - -const verifyIdToken = async ({ - token, - id -}, { - clientId, - cacheMaxEntries, - cacheMaxAge -}) => { - if (!token) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token is invalid for this user.`); - } - - const { - kid: keyId, - alg: algorithm - } = getHeaderFromToken(token); - const ONE_HOUR_IN_MS = 3600000; - let jwtClaims; - cacheMaxAge = cacheMaxAge || ONE_HOUR_IN_MS; - cacheMaxEntries = cacheMaxEntries || 5; - const appleKey = await getAppleKeyByKeyId(keyId, cacheMaxEntries, cacheMaxAge); - const signingKey = appleKey.publicKey || appleKey.rsaPublicKey; - - try { - jwtClaims = jwt.verify(token, signingKey, { - algorithms: algorithm, - // the audience can be checked against a string, a regular expression or a list of strings and/or regular expressions. - audience: clientId - }); - } catch (exception) { - const message = exception.message; - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `${message}`); - } - - if (jwtClaims.iss !== TOKEN_ISSUER) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token not issued by correct OpenID provider - expected: ${TOKEN_ISSUER} | from: ${jwtClaims.iss}`); - } - - if (jwtClaims.sub !== id) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `auth data is invalid for this user.`); - } - - return jwtClaims; -}; // Returns a promise that fulfills if this id token is valid - - -function validateAuthData(authData, options = {}) { - return verifyIdToken(authData, options); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} - -module.exports = { - validateAppId, - validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2FwcGxlLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsImp3a3NDbGllbnQiLCJ1dGlsIiwiand0IiwiVE9LRU5fSVNTVUVSIiwiZ2V0QXBwbGVLZXlCeUtleUlkIiwia2V5SWQiLCJjYWNoZU1heEVudHJpZXMiLCJjYWNoZU1heEFnZSIsImNsaWVudCIsImp3a3NVcmkiLCJjYWNoZSIsImFzeW5jR2V0U2lnbmluZ0tleUZ1bmN0aW9uIiwicHJvbWlzaWZ5IiwiZ2V0U2lnbmluZ0tleSIsImtleSIsImVycm9yIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiZ2V0SGVhZGVyRnJvbVRva2VuIiwidG9rZW4iLCJkZWNvZGVkVG9rZW4iLCJkZWNvZGUiLCJjb21wbGV0ZSIsImhlYWRlciIsInZlcmlmeUlkVG9rZW4iLCJpZCIsImNsaWVudElkIiwia2lkIiwiYWxnIiwiYWxnb3JpdGhtIiwiT05FX0hPVVJfSU5fTVMiLCJqd3RDbGFpbXMiLCJhcHBsZUtleSIsInNpZ25pbmdLZXkiLCJwdWJsaWNLZXkiLCJyc2FQdWJsaWNLZXkiLCJ2ZXJpZnkiLCJhbGdvcml0aG1zIiwiYXVkaWVuY2UiLCJleGNlcHRpb24iLCJtZXNzYWdlIiwiaXNzIiwic3ViIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUVBLE1BQU1BLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBcEM7O0FBQ0EsTUFBTUUsVUFBVSxHQUFHRCxPQUFPLENBQUMsVUFBRCxDQUExQjs7QUFDQSxNQUFNRSxJQUFJLEdBQUdGLE9BQU8sQ0FBQyxNQUFELENBQXBCOztBQUNBLE1BQU1HLEdBQUcsR0FBR0gsT0FBTyxDQUFDLGNBQUQsQ0FBbkI7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QXpELENBQU47QUFDRDs7QUFFRCxNQUFJVCxTQUFTLENBQUNVLEdBQVYsS0FBa0J0QyxZQUF0QixFQUFvQztBQUNsQyxVQUFNLElBQUlMLEtBQUssQ0FBQ2tCLEtBQVYsQ0FDSmxCLEtBQUssQ0FBQ2tCLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSCw4REFBNkRkLFlBQWEsWUFBVzRCLFNBQVMsQ0FBQ1UsR0FBSSxFQUZoRyxDQUFOO0FBSUQ7O0FBRUQsTUFBSVYsU0FBUyxDQUFDVyxHQUFWLEtBQWtCakIsRUFBdEIsRUFBMEI7QUFDeEIsVUFBTSxJQUFJM0IsS0FBSyxDQUFDa0IsS0FBVixDQUFnQmxCLEtBQUssQ0FBQ2tCLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQStDLHFDQUEvQyxDQUFOO0FBQ0Q7O0FBQ0QsU0FBT2MsU0FBUDtBQUNELENBdENELEMsQ0F3Q0E7OztBQUNBLFNBQVNZLGdCQUFULENBQTBCQyxRQUExQixFQUFvQ0MsT0FBTyxHQUFHLEVBQTlDLEVBQWtEO0FBQ2hELFNBQU9yQixhQUFhLENBQUNvQixRQUFELEVBQVdDLE9BQVgsQ0FBcEI7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNDLGFBQVQsR0FBeUI7QUFDdkIsU0FBT0MsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFREMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZKLEVBQUFBLGFBRGU7QUFFZkgsRUFBQUE7QUFGZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEFwcGxlIFNpZ25JbiBBdXRoXG4vLyBodHRwczovL2RldmVsb3Blci5hcHBsZS5jb20vZG9jdW1lbnRhdGlvbi9zaWduaW53aXRoYXBwbGVyZXN0YXBpXG5cbmNvbnN0IFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuY29uc3Qgandrc0NsaWVudCA9IHJlcXVpcmUoJ2p3a3MtcnNhJyk7XG5jb25zdCB1dGlsID0gcmVxdWlyZSgndXRpbCcpO1xuY29uc3Qgand0ID0gcmVxdWlyZSgnanNvbndlYnRva2VuJyk7XG5cbmNvbnN0IFRPS0VOX0lTU1VFUiA9ICdodHRwczovL2FwcGxlaWQuYXBwbGUuY29tJztcblxuY29uc3QgZ2V0QXBwbGVLZXlCeUtleUlkID0gYXN5bmMgKGtleUlkLCBjYWNoZU1heEVudHJpZXMsIGNhY2hlTWF4QWdlKSA9PiB7XG4gIGNvbnN0IGNsaWVudCA9IGp3a3NDbGllbnQoe1xuICAgIGp3a3NVcmk6IGAke1RPS0VOX0lTU1VFUn0vYXV0aC9rZXlzYCxcbiAgICBjYWNoZTogdHJ1ZSxcbiAgICBjYWNoZU1heEVudHJpZXMsXG4gICAgY2FjaGVNYXhBZ2UsXG4gIH0pO1xuXG4gIGNvbnN0IGFzeW5jR2V0U2lnbmluZ0tleUZ1bmN0aW9uID0gdXRpbC5wcm9taXNpZnkoY2xpZW50LmdldFNpZ25pbmdLZXkpO1xuXG4gIGxldCBrZXk7XG4gIHRyeSB7XG4gICAga2V5ID0gYXdhaXQgYXN5bmNHZXRTaWduaW5nS2V5RnVuY3Rpb24oa2V5SWQpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICBgVW5hYmxlIHRvIGZpbmQgbWF0Y2hpbmcga2V5IGZvciBLZXkgSUQ6ICR7a2V5SWR9YFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIGtleTtcbn07XG5cbmNvbnN0IGdldEhlYWRlckZyb21Ub2tlbiA9IHRva2VuID0+IHtcbiAgY29uc3QgZGVjb2RlZFRva2VuID0gand0LmRlY29kZSh0b2tlbiwgeyBjb21wbGV0ZTogdHJ1ZSB9KTtcbiAgaWYgKCFkZWNvZGVkVG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgYHByb3ZpZGVkIHRva2VuIGRvZXMgbm90IGRlY29kZSBhcyBKV1RgKTtcbiAgfVxuXG4gIHJldHVybiBkZWNvZGVkVG9rZW4uaGVhZGVyO1xufTtcblxuY29uc3QgdmVyaWZ5SWRUb2tlbiA9IGFzeW5jICh7IHRva2VuLCBpZCB9LCB7IGNsaWVudElkLCBjYWNoZU1heEVudHJpZXMsIGNhY2hlTWF4QWdlIH0pID0+IHtcbiAgaWYgKCF0b2tlbikge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBgaWQgdG9rZW4gaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLmApO1xuICB9XG5cbiAgY29uc3QgeyBraWQ6IGtleUlkLCBhbGc6IGFsZ29yaXRobSB9ID0gZ2V0SGVhZGVyRnJvbVRva2VuKHRva2VuKTtcbiAgY29uc3QgT05FX0hPVVJfSU5fTVMgPSAzNjAwMDAwO1xuICBsZXQgand0Q2xhaW1zO1xuXG4gIGNhY2hlTWF4QWdlID0gY2FjaGVNYXhBZ2UgfHwgT05FX0hPVVJfSU5fTVM7XG4gIGNhY2hlTWF4RW50cmllcyA9IGNhY2hlTWF4RW50cmllcyB8fCA1O1xuXG4gIGNvbnN0IGFwcGxlS2V5ID0gYXdhaXQgZ2V0QXBwbGVLZXlCeUtleUlkKGtleUlkLCBjYWNoZU1heEVudHJpZXMsIGNhY2hlTWF4QWdlKTtcbiAgY29uc3Qgc2lnbmluZ0tleSA9IGFwcGxlS2V5LnB1YmxpY0tleSB8fCBhcHBsZUtleS5yc2FQdWJsaWNLZXk7XG5cbiAgdHJ5IHtcbiAgICBqd3RDbGFpbXMgPSBqd3QudmVyaWZ5KHRva2VuLCBzaWduaW5nS2V5LCB7XG4gICAgICBhbGdvcml0aG1zOiBhbGdvcml0aG0sXG4gICAgICAvLyB0aGUgYXVkaWVuY2UgY2FuIGJlIGNoZWNrZWQgYWdhaW5zdCBhIHN0cmluZywgYSByZWd1bGFyIGV4cHJlc3Npb24gb3IgYSBsaXN0IG9mIHN0cmluZ3MgYW5kL29yIHJlZ3VsYXIgZXhwcmVzc2lvbnMuXG4gICAgICBhdWRpZW5jZTogY2xpZW50SWQsXG4gICAgfSk7XG4gIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBleGNlcHRpb24ubWVzc2FnZTtcblxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBgJHttZXNzYWdlfWApO1xuICB9XG5cbiAgaWYgKGp3dENsYWltcy5pc3MgIT09IFRPS0VOX0lTU1VFUikge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICBgaWQgdG9rZW4gbm90IGlzc3VlZCBieSBjb3JyZWN0IE9wZW5JRCBwcm92aWRlciAtIGV4cGVjdGVkOiAke1RPS0VOX0lTU1VFUn0gfCBmcm9tOiAke2p3dENsYWltcy5pc3N9YFxuICAgICk7XG4gIH1cblxuICBpZiAoand0Q2xhaW1zLnN1YiAhPT0gaWQpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgYGF1dGggZGF0YSBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuYCk7XG4gIH1cbiAgcmV0dXJuIGp3dENsYWltcztcbn07XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyBpZCB0b2tlbiBpcyB2YWxpZFxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSwgb3B0aW9ucyA9IHt9KSB7XG4gIHJldHVybiB2ZXJpZnlJZFRva2VuKGF1dGhEYXRhLCBvcHRpb25zKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/facebook.js b/lib/Adapters/Auth/facebook.js deleted file mode 100644 index 63ba4005ad..0000000000 --- a/lib/Adapters/Auth/facebook.js +++ /dev/null @@ -1,62 +0,0 @@ -"use strict"; - -// Helper functions for accessing the Facebook Graph API. -const httpsRequest = require('./httpsRequest'); - -var Parse = require('parse/node').Parse; - -const crypto = require('crypto'); - -function getAppSecretPath(authData, options = {}) { - const appSecret = options.appSecret; - - if (!appSecret) { - return ''; - } - - const appsecret_proof = crypto.createHmac('sha256', appSecret).update(authData.access_token).digest('hex'); - return `&appsecret_proof=${appsecret_proof}`; -} // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData, options) { - return graphRequest('me?fields=id&access_token=' + authData.access_token + getAppSecretPath(authData, options)).then(data => { - if (data && data.id == authData.id || process.env.TESTING && authData.id === 'test') { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is invalid for this user.'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId(appIds, authData, options) { - var access_token = authData.access_token; - - if (process.env.TESTING && access_token === 'test') { - return Promise.resolve(); - } - - if (!appIds.length) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is not configured.'); - } - - return graphRequest('app?access_token=' + access_token + getAppSecretPath(authData, options)).then(data => { - if (data && appIds.indexOf(data.id) != -1) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Facebook auth is invalid for this user.'); - }); -} // A promisey wrapper for FB graph requests. - - -function graphRequest(path) { - return httpsRequest.get('https://graph.facebook.com/' + path); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2ZhY2Vib29rLmpzIl0sIm5hbWVzIjpbImh0dHBzUmVxdWVzdCIsInJlcXVpcmUiLCJQYXJzZSIsImNyeXB0byIsImdldEFwcFNlY3JldFBhdGgiLCJhdXRoRGF0YSIsIm9wdGlvbnMiLCJhcHBTZWNyZXQiLCJhcHBzZWNyZXRfcHJvb2YiLCJjcmVhdGVIbWFjIiwidXBkYXRlIiwiYWNjZXNzX3Rva2VuIiwiZGlnZXN0IiwidmFsaWRhdGVBdXRoRGF0YSIsImdyYXBoUmVxdWVzdCIsInRoZW4iLCJkYXRhIiwiaWQiLCJwcm9jZXNzIiwiZW52IiwiVEVTVElORyIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJhcHBJZHMiLCJQcm9taXNlIiwicmVzb2x2ZSIsImxlbmd0aCIsImluZGV4T2YiLCJwYXRoIiwiZ2V0IiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBLE1BQU1BLFlBQVksR0FBR0MsT0FBTyxDQUFDLGdCQUFELENBQTVCOztBQUNBLElBQUlDLEtBQUssR0FBR0QsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkMsS0FBbEM7O0FBQ0EsTUFBTUMsTUFBTSxHQUFHRixPQUFPLENBQUMsUUFBRCxDQUF0Qjs7QUFFQSxTQUFTRyxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0NDLE9BQU8sR0FBRyxFQUE5QyxFQUFrRDtBQUNoRCxRQUFNQyxTQUFTLEdBQUdELE9BQU8sQ0FBQ0MsU0FBMUI7O0FBQ0EsTUFBSSxDQUFDQSxTQUFMLEVBQWdCO0FBQ2QsV0FBTyxFQUFQO0FBQ0Q7O0FBQ0QsUUFBTUMsZUFBZSxHQUFHTCxNQUFNLENBQzNCTSxVQURxQixDQUNWLFFBRFUsRUFDQUYsU0FEQSxFQUVyQkcsTUFGcUIsQ0FFZEwsUUFBUSxDQUFDTSxZQUZLLEVBR3JCQyxNQUhxQixDQUdkLEtBSGMsQ0FBeEI7QUFLQSxTQUFRLG9CQUFtQkosZUFBZ0IsRUFBM0M7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNLLGdCQUFULENBQTBCUixRQUExQixFQUFvQ0MsT0FBcEMsRUFBNkM7QUFDM0MsU0FBT1EsWUFBWSxDQUNqQiwrQkFBK0JULFFBQVEsQ0FBQ00sWUFBeEMsR0FBdURQLGdCQUFnQixDQUFDQyxRQUFELEVBQVdDLE9BQVgsQ0FEdEQsQ0FBWixDQUVMUyxJQUZLLENBRUFDLElBQUksSUFBSTtBQUNiLFFBQUtBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxFQUFMLElBQVdaLFFBQVEsQ0FBQ1ksRUFBN0IsSUFBcUNDLE9BQU8sQ0FBQ0MsR0FBUixDQUFZQyxPQUFaLElBQXVCZixRQUFRLENBQUNZLEVBQVQsS0FBZ0IsTUFBaEYsRUFBeUY7QUFDdkY7QUFDRDs7QUFDRCxVQUFNLElBQUlmLEtBQUssQ0FBQ21CLEtBQVYsQ0FBZ0JuQixLQUFLLENBQUNtQixLQUFOLENBQVlDLGdCQUE1QixFQUE4Qyx5Q0FBOUMsQ0FBTjtBQUNELEdBUE0sQ0FBUDtBQVFELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxDQUF1QkMsTUFBdkIsRUFBK0JuQixRQUEvQixFQUF5Q0MsT0FBekMsRUFBa0Q7QUFDaEQsTUFBSUssWUFBWSxHQUFHTixRQUFRLENBQUNNLFlBQTVCOztBQUNBLE1BQUlPLE9BQU8sQ0FBQ0MsR0FBUixDQUFZQyxPQUFaLElBQXVCVCxZQUFZLEtBQUssTUFBNUMsRUFBb0Q7QUFDbEQsV0FBT2MsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFDRCxNQUFJLENBQUNGLE1BQU0sQ0FBQ0csTUFBWixFQUFvQjtBQUNsQixVQUFNLElBQUl6QixLQUFLLENBQUNtQixLQUFWLENBQWdCbkIsS0FBSyxDQUFDbUIsS0FBTixDQUFZQyxnQkFBNUIsRUFBOEMsa0NBQTlDLENBQU47QUFDRDs7QUFDRCxTQUFPUixZQUFZLENBQ2pCLHNCQUFzQkgsWUFBdEIsR0FBcUNQLGdCQUFnQixDQUFDQyxRQUFELEVBQVdDLE9BQVgsQ0FEcEMsQ0FBWixDQUVMUyxJQUZLLENBRUFDLElBQUksSUFBSTtBQUNiLFFBQUlBLElBQUksSUFBSVEsTUFBTSxDQUFDSSxPQUFQLENBQWVaLElBQUksQ0FBQ0MsRUFBcEIsS0FBMkIsQ0FBQyxDQUF4QyxFQUEyQztBQUN6QztBQUNEOztBQUNELFVBQU0sSUFBSWYsS0FBSyxDQUFDbUIsS0FBVixDQUFnQm5CLEtBQUssQ0FBQ21CLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLHlDQUE5QyxDQUFOO0FBQ0QsR0FQTSxDQUFQO0FBUUQsQyxDQUVEOzs7QUFDQSxTQUFTUixZQUFULENBQXNCZSxJQUF0QixFQUE0QjtBQUMxQixTQUFPN0IsWUFBWSxDQUFDOEIsR0FBYixDQUFpQixnQ0FBZ0NELElBQWpELENBQVA7QUFDRDs7QUFFREUsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZULEVBQUFBLGFBQWEsRUFBRUEsYUFEQTtBQUVmVixFQUFBQSxnQkFBZ0IsRUFBRUE7QUFGSCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgRmFjZWJvb2sgR3JhcGggQVBJLlxuY29uc3QgaHR0cHNSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwc1JlcXVlc3QnKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGNyeXB0byA9IHJlcXVpcmUoJ2NyeXB0bycpO1xuXG5mdW5jdGlvbiBnZXRBcHBTZWNyZXRQYXRoKGF1dGhEYXRhLCBvcHRpb25zID0ge30pIHtcbiAgY29uc3QgYXBwU2VjcmV0ID0gb3B0aW9ucy5hcHBTZWNyZXQ7XG4gIGlmICghYXBwU2VjcmV0KSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG4gIGNvbnN0IGFwcHNlY3JldF9wcm9vZiA9IGNyeXB0b1xuICAgIC5jcmVhdGVIbWFjKCdzaGEyNTYnLCBhcHBTZWNyZXQpXG4gICAgLnVwZGF0ZShhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pXG4gICAgLmRpZ2VzdCgnaGV4Jyk7XG5cbiAgcmV0dXJuIGAmYXBwc2VjcmV0X3Byb29mPSR7YXBwc2VjcmV0X3Byb29mfWA7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIGdyYXBoUmVxdWVzdChcbiAgICAnbWU/ZmllbGRzPWlkJmFjY2Vzc190b2tlbj0nICsgYXV0aERhdGEuYWNjZXNzX3Rva2VuICsgZ2V0QXBwU2VjcmV0UGF0aChhdXRoRGF0YSwgb3B0aW9ucylcbiAgKS50aGVuKGRhdGEgPT4ge1xuICAgIGlmICgoZGF0YSAmJiBkYXRhLmlkID09IGF1dGhEYXRhLmlkKSB8fCAocHJvY2Vzcy5lbnYuVEVTVElORyAmJiBhdXRoRGF0YS5pZCA9PT0gJ3Rlc3QnKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0ZhY2Vib29rIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLicpO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKGFwcElkcywgYXV0aERhdGEsIG9wdGlvbnMpIHtcbiAgdmFyIGFjY2Vzc190b2tlbiA9IGF1dGhEYXRhLmFjY2Vzc190b2tlbjtcbiAgaWYgKHByb2Nlc3MuZW52LlRFU1RJTkcgJiYgYWNjZXNzX3Rva2VuID09PSAndGVzdCcpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbiAgaWYgKCFhcHBJZHMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdGYWNlYm9vayBhdXRoIGlzIG5vdCBjb25maWd1cmVkLicpO1xuICB9XG4gIHJldHVybiBncmFwaFJlcXVlc3QoXG4gICAgJ2FwcD9hY2Nlc3NfdG9rZW49JyArIGFjY2Vzc190b2tlbiArIGdldEFwcFNlY3JldFBhdGgoYXV0aERhdGEsIG9wdGlvbnMpXG4gICkudGhlbihkYXRhID0+IHtcbiAgICBpZiAoZGF0YSAmJiBhcHBJZHMuaW5kZXhPZihkYXRhLmlkKSAhPSAtMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0ZhY2Vib29rIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLicpO1xuICB9KTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBGQiBncmFwaCByZXF1ZXN0cy5cbmZ1bmN0aW9uIGdyYXBoUmVxdWVzdChwYXRoKSB7XG4gIHJldHVybiBodHRwc1JlcXVlc3QuZ2V0KCdodHRwczovL2dyYXBoLmZhY2Vib29rLmNvbS8nICsgcGF0aCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/gcenter.js b/lib/Adapters/Auth/gcenter.js deleted file mode 100644 index bc44150cef..0000000000 --- a/lib/Adapters/Auth/gcenter.js +++ /dev/null @@ -1,126 +0,0 @@ -"use strict"; - -/* Apple Game Center Auth -https://developer.apple.com/documentation/gamekit/gklocalplayer/1515407-generateidentityverificationsign#discussion - -const authData = { - publicKeyUrl: 'https://valid.apple.com/public/timeout.cer', - timestamp: 1460981421303, - signature: 'PoDwf39DCN464B49jJCU0d9Y0J', - salt: 'saltST==', - bundleId: 'com.valid.app' - id: 'playerId', -}; -*/ -const { - Parse -} = require('parse/node'); - -const crypto = require('crypto'); - -const https = require('https'); - -const url = require('url'); - -const cache = {}; // (publicKey -> cert) cache - -function verifyPublicKeyUrl(publicKeyUrl) { - const parsedUrl = url.parse(publicKeyUrl); - - if (parsedUrl.protocol !== 'https:') { - return false; - } - - const hostnameParts = parsedUrl.hostname.split('.'); - const length = hostnameParts.length; - const domainParts = hostnameParts.slice(length - 2, length); - const domain = domainParts.join('.'); - return domain === 'apple.com'; -} - -function convertX509CertToPEM(X509Cert) { - const pemPreFix = '-----BEGIN CERTIFICATE-----\n'; - const pemPostFix = '-----END CERTIFICATE-----'; - const base64 = X509Cert; - const certBody = base64.match(new RegExp('.{0,64}', 'g')).join('\n'); - return pemPreFix + certBody + pemPostFix; -} - -function getAppleCertificate(publicKeyUrl) { - if (!verifyPublicKeyUrl(publicKeyUrl)) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `Apple Game Center - invalid publicKeyUrl: ${publicKeyUrl}`); - } - - if (cache[publicKeyUrl]) { - return cache[publicKeyUrl]; - } - - return new Promise((resolve, reject) => { - https.get(publicKeyUrl, res => { - let data = ''; - res.on('data', chunk => { - data += chunk.toString('base64'); - }); - res.on('end', () => { - const cert = convertX509CertToPEM(data); - - if (res.headers['cache-control']) { - var expire = res.headers['cache-control'].match(/max-age=([0-9]+)/); - - if (expire) { - cache[publicKeyUrl] = cert; // we'll expire the cache entry later, as per max-age - - setTimeout(() => { - delete cache[publicKeyUrl]; - }, parseInt(expire[1], 10) * 1000); - } - } - - resolve(cert); - }); - }).on('error', reject); - }); -} - -function convertTimestampToBigEndian(timestamp) { - const buffer = Buffer.alloc(8); - const high = ~~(timestamp / 0xffffffff); - const low = timestamp % (0xffffffff + 0x1); - buffer.writeUInt32BE(parseInt(high, 10), 0); - buffer.writeUInt32BE(parseInt(low, 10), 4); - return buffer; -} - -function verifySignature(publicKey, authData) { - const verifier = crypto.createVerify('sha256'); - verifier.update(authData.playerId, 'utf8'); - verifier.update(authData.bundleId, 'utf8'); - verifier.update(convertTimestampToBigEndian(authData.timestamp)); - verifier.update(authData.salt, 'base64'); - - if (!verifier.verify(publicKey, authData.signature, 'base64')) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Apple Game Center - invalid signature'); - } -} // Returns a promise that fulfills if this user id is valid. - - -async function validateAuthData(authData) { - if (!authData.id) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Apple Game Center - authData id missing'); - } - - authData.playerId = authData.id; - const publicKey = await getAppleCertificate(authData.publicKeyUrl); - return verifySignature(publicKey, authData); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} - -module.exports = { - validateAppId, - validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2djZW50ZXIuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwiY3J5cHRvIiwiaHR0cHMiLCJ1cmwiLCJjYWNoZSIsInZlcmlmeVB1YmxpY0tleVVybCIsInB1YmxpY0tleVVybCIsInBhcnNlZFVybCIsInBhcnNlIiwicHJvdG9jb2wiLCJob3N0bmFtZVBhcnRzIiwiaG9zdG5hbWUiLCJzcGxpdCIsImxlbmd0aCIsImRvbWFpblBhcnRzIiwic2xpY2UiLCJkb21haW4iLCJqb2luIiwiY29udmVydFg1MDlDZXJ0VG9QRU0iLCJYNTA5Q2VydCIsInBlbVByZUZpeCIsInBlbVBvc3RGaXgiLCJiYXNlNjQiLCJjZXJ0Qm9keSIsIm1hdGNoIiwiUmVnRXhwIiwiZ2V0QXBwbGVDZXJ0aWZpY2F0ZSIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiZ2V0IiwicmVzIiwiZGF0YSIsIm9uIiwiY2h1bmsiLCJ0b1N0cmluZyIsImNlcnQiLCJoZWFkZXJzIiwiZXhwaXJlIiwic2V0VGltZW91dCIsInBhcnNlSW50IiwiY29udmVydFRpbWVzdGFtcFRvQmlnRW5kaWFuIiwidGltZXN0YW1wIiwiYnVmZmVyIiwiQnVmZmVyIiwiYWxsb2MiLCJoaWdoIiwibG93Iiwid3JpdGVVSW50MzJCRSIsInZlcmlmeVNpZ25hdHVyZSIsInB1YmxpY0tleSIsImF1dGhEYXRhIiwidmVyaWZpZXIiLCJjcmVhdGVWZXJpZnkiLCJ1cGRhdGUiLCJwbGF5ZXJJZCIsImJ1bmRsZUlkIiwic2FsdCIsInZlcmlmeSIsInNpZ25hdHVyZSIsInZhbGlkYXRlQXV0aERhdGEiLCJpZCIsInZhbGlkYXRlQXBwSWQiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVB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Q1QsU0FBVixDQUEzQztBQUNBVSxFQUFBQSxRQUFRLENBQUNFLE1BQVQsQ0FBZ0JILFFBQVEsQ0FBQ00sSUFBekIsRUFBK0IsUUFBL0I7O0FBRUEsTUFBSSxDQUFDTCxRQUFRLENBQUNNLE1BQVQsQ0FBZ0JSLFNBQWhCLEVBQTJCQyxRQUFRLENBQUNRLFNBQXBDLEVBQStDLFFBQS9DLENBQUwsRUFBK0Q7QUFDN0QsVUFBTSxJQUFJOUQsS0FBSyxDQUFDNEIsS0FBVixDQUFnQjVCLEtBQUssQ0FBQzRCLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLHVDQUE5QyxDQUFOO0FBQ0Q7QUFDRixDLENBRUQ7OztBQUNBLGVBQWVrQyxnQkFBZixDQUFnQ1QsUUFBaEMsRUFBMEM7QUFDeEMsTUFBSSxDQUFDQSxRQUFRLENBQUNVLEVBQWQsRUFBa0I7QUFDaEIsVUFBTSxJQUFJaEUsS0FBSyxDQUFDNEIsS0FBVixDQUFnQjVCLEtBQUssQ0FBQzRCLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLHlDQUE5QyxDQUFOO0FBQ0Q7O0FBQ0R5QixFQUFBQSxRQUFRLENBQUNJLFFBQVQsR0FBb0JKLFFBQVEsQ0FBQ1UsRUFBN0I7QUFDQSxRQUFNWCxTQUFTLEdBQUcsTUFBTTFCLG1CQUFtQixDQUFDMkIsUUFBUSxDQUFDL0MsWUFBVixDQUEzQztBQUNBLFNBQU82QyxlQUFlLENBQUNDLFNBQUQsRUFBWUMsUUFBWixDQUF0QjtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU1csYUFBVCxHQUF5QjtBQUN2QixTQUFPbkMsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFRG1DLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmRixFQUFBQSxhQURlO0FBRWZGLEVBQUFBO0FBRmUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBBcHBsZSBHYW1lIENlbnRlciBBdXRoXG5odHRwczovL2RldmVsb3Blci5hcHBsZS5jb20vZG9jdW1lbnRhdGlvbi9nYW1la2l0L2drbG9jYWxwbGF5ZXIvMTUxNTQwNy1nZW5lcmF0ZWlkZW50aXR5dmVyaWZpY2F0aW9uc2lnbiNkaXNjdXNzaW9uXG5cbmNvbnN0IGF1dGhEYXRhID0ge1xuICBwdWJsaWNLZXlVcmw6ICdodHRwczovL3ZhbGlkLmFwcGxlLmNvbS9wdWJsaWMvdGltZW91dC5jZXInLFxuICB0aW1lc3RhbXA6IDE0NjA5ODE0MjEzMDMsXG4gIHNpZ25hdHVyZTogJ1BvRHdmMzlEQ040NjRCNDlqSkNVMGQ5WTBKJyxcbiAgc2FsdDogJ3NhbHRTVD09JyxcbiAgYnVuZGxlSWQ6ICdjb20udmFsaWQuYXBwJ1xuICBpZDogJ3BsYXllcklkJyxcbn07XG4qL1xuXG5jb25zdCB7IFBhcnNlIH0gPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5jb25zdCBjcnlwdG8gPSByZXF1aXJlKCdjcnlwdG8nKTtcbmNvbnN0IGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKTtcbmNvbnN0IHVybCA9IHJlcXVpcmUoJ3VybCcpO1xuXG5jb25zdCBjYWNoZSA9IHt9OyAvLyAocHVibGljS2V5IC0+IGNlcnQpIGNhY2hlXG5cbmZ1bmN0aW9uIHZlcmlmeVB1YmxpY0tleVVybChwdWJsaWNLZXlVcmwpIHtcbiAgY29uc3QgcGFyc2VkVXJsID0gdXJsLnBhcnNlKHB1YmxpY0tleVVybCk7XG4gIGlmIChwYXJzZWRVcmwucHJvdG9jb2wgIT09ICdodHRwczonKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGNvbnN0IGhvc3RuYW1lUGFydHMgPSBwYXJzZWRVcmwuaG9zdG5hbWUuc3BsaXQoJy4nKTtcbiAgY29uc3QgbGVuZ3RoID0gaG9zdG5hbWVQYXJ0cy5sZW5ndGg7XG4gIGNvbnN0IGRvbWFpblBhcnRzID0gaG9zdG5hbWVQYXJ0cy5zbGljZShsZW5ndGggLSAyLCBsZW5ndGgpO1xuICBjb25zdCBkb21haW4gPSBkb21haW5QYXJ0cy5qb2luKCcuJyk7XG4gIHJldHVybiBkb21haW4gPT09ICdhcHBsZS5jb20nO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0WDUwOUNlcnRUb1BFTShYNTA5Q2VydCkge1xuICBjb25zdCBwZW1QcmVGaXggPSAnLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXFxuJztcbiAgY29uc3QgcGVtUG9zdEZpeCA9ICctLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tJztcblxuICBjb25zdCBiYXNlNjQgPSBYNTA5Q2VydDtcbiAgY29uc3QgY2VydEJvZHkgPSBiYXNlNjQubWF0Y2gobmV3IFJlZ0V4cCgnLnswLDY0fScsICdnJykpLmpvaW4oJ1xcbicpO1xuXG4gIHJldHVybiBwZW1QcmVGaXggKyBjZXJ0Qm9keSArIHBlbVBvc3RGaXg7XG59XG5cbmZ1bmN0aW9uIGdldEFwcGxlQ2VydGlmaWNhdGUocHVibGljS2V5VXJsKSB7XG4gIGlmICghdmVyaWZ5UHVibGljS2V5VXJsKHB1YmxpY0tleVVybCkpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgYEFwcGxlIEdhbWUgQ2VudGVyIC0gaW52YWxpZCBwdWJsaWNLZXlVcmw6ICR7cHVibGljS2V5VXJsfWBcbiAgICApO1xuICB9XG4gIGlmIChjYWNoZVtwdWJsaWNLZXlVcmxdKSB7XG4gICAgcmV0dXJuIGNhY2hlW3B1YmxpY0tleVVybF07XG4gIH1cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBodHRwc1xuICAgICAgLmdldChwdWJsaWNLZXlVcmwsIHJlcyA9PiB7XG4gICAgICAgIGxldCBkYXRhID0gJyc7XG4gICAgICAgIHJlcy5vbignZGF0YScsIGNodW5rID0+IHtcbiAgICAgICAgICBkYXRhICs9IGNodW5rLnRvU3RyaW5nKCdiYXNlNjQnKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJlcy5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNlcnQgPSBjb252ZXJ0WDUwOUNlcnRUb1BFTShkYXRhKTtcbiAgICAgICAgICBpZiAocmVzLmhlYWRlcnNbJ2NhY2hlLWNvbnRyb2wnXSkge1xuICAgICAgICAgICAgdmFyIGV4cGlyZSA9IHJlcy5oZWFkZXJzWydjYWNoZS1jb250cm9sJ10ubWF0Y2goL21heC1hZ2U9KFswLTldKykvKTtcbiAgICAgICAgICAgIGlmIChleHBpcmUpIHtcbiAgICAgICAgICAgICAgY2FjaGVbcHVibGljS2V5VXJsXSA9IGNlcnQ7XG4gICAgICAgICAgICAgIC8vIHdlJ2xsIGV4cGlyZSB0aGUgY2FjaGUgZW50cnkgbGF0ZXIsIGFzIHBlciBtYXgtYWdlXG4gICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBjYWNoZVtwdWJsaWNLZXlVcmxdO1xuICAgICAgICAgICAgICB9LCBwYXJzZUludChleHBpcmVbMV0sIDEwKSAqIDEwMDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXNvbHZlKGNlcnQpO1xuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRUaW1lc3RhbXBUb0JpZ0VuZGlhbih0aW1lc3RhbXApIHtcbiAgY29uc3QgYnVmZmVyID0gQnVmZmVyLmFsbG9jKDgpO1xuXG4gIGNvbnN0IGhpZ2ggPSB+fih0aW1lc3RhbXAgLyAweGZmZmZmZmZmKTtcbiAgY29uc3QgbG93ID0gdGltZXN0YW1wICUgKDB4ZmZmZmZmZmYgKyAweDEpO1xuXG4gIGJ1ZmZlci53cml0ZVVJbnQzMkJFKHBhcnNlSW50KGhpZ2gsIDEwKSwgMCk7XG4gIGJ1ZmZlci53cml0ZVVJbnQzMkJFKHBhcnNlSW50KGxvdywgMTApLCA0KTtcblxuICByZXR1cm4gYnVmZmVyO1xufVxuXG5mdW5jdGlvbiB2ZXJpZnlTaWduYXR1cmUocHVibGljS2V5LCBhdXRoRGF0YSkge1xuICBjb25zdCB2ZXJpZmllciA9IGNyeXB0by5jcmVhdGVWZXJpZnkoJ3NoYTI1NicpO1xuICB2ZXJpZmllci51cGRhdGUoYXV0aERhdGEucGxheWVySWQsICd1dGY4Jyk7XG4gIHZlcmlmaWVyLnVwZGF0ZShhdXRoRGF0YS5idW5kbGVJZCwgJ3V0ZjgnKTtcbiAgdmVyaWZpZXIudXBkYXRlKGNvbnZlcnRUaW1lc3RhbXBUb0JpZ0VuZGlhbihhdXRoRGF0YS50aW1lc3RhbXApKTtcbiAgdmVyaWZpZXIudXBkYXRlKGF1dGhEYXRhLnNhbHQsICdiYXNlNjQnKTtcblxuICBpZiAoIXZlcmlmaWVyLnZlcmlmeShwdWJsaWNLZXksIGF1dGhEYXRhLnNpZ25hdHVyZSwgJ2Jhc2U2NCcpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdBcHBsZSBHYW1lIENlbnRlciAtIGludmFsaWQgc2lnbmF0dXJlJyk7XG4gIH1cbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5hc3luYyBmdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG4gIGlmICghYXV0aERhdGEuaWQpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0FwcGxlIEdhbWUgQ2VudGVyIC0gYXV0aERhdGEgaWQgbWlzc2luZycpO1xuICB9XG4gIGF1dGhEYXRhLnBsYXllcklkID0gYXV0aERhdGEuaWQ7XG4gIGNvbnN0IHB1YmxpY0tleSA9IGF3YWl0IGdldEFwcGxlQ2VydGlmaWNhdGUoYXV0aERhdGEucHVibGljS2V5VXJsKTtcbiAgcmV0dXJuIHZlcmlmeVNpZ25hdHVyZShwdWJsaWNLZXksIGF1dGhEYXRhKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/github.js b/lib/Adapters/Auth/github.js deleted file mode 100644 index 42601db410..0000000000 --- a/lib/Adapters/Auth/github.js +++ /dev/null @@ -1,40 +0,0 @@ -"use strict"; - -// Helper functions for accessing the github API. -var Parse = require('parse/node').Parse; - -const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData) { - return request('user', authData.access_token).then(data => { - if (data && data.id == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Github auth is invalid for this user.'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for api requests - - -function request(path, access_token) { - return httpsRequest.get({ - host: 'api.github.com', - path: '/' + path, - headers: { - Authorization: 'bearer ' + access_token, - 'User-Agent': 'parse-server' - } - }); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2dpdGh1Yi5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJyZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsImRhdGEiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJnZXQiLCJob3N0IiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFDQSxNQUFNRSxZQUFZLEdBQUdELE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNFLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsTUFBRCxFQUFTRCxRQUFRLENBQUNFLFlBQWxCLENBQVAsQ0FBdUNDLElBQXZDLENBQTRDQyxJQUFJLElBQUk7QUFDekQsUUFBSUEsSUFBSSxJQUFJQSxJQUFJLENBQUNDLEVBQUwsSUFBV0wsUUFBUSxDQUFDSyxFQUFoQyxFQUFvQztBQUNsQztBQUNEOztBQUNELFVBQU0sSUFBSVQsS0FBSyxDQUFDVSxLQUFWLENBQWdCVixLQUFLLENBQUNVLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLHVDQUE5QyxDQUFOO0FBQ0QsR0FMTSxDQUFQO0FBTUQsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTVCxPQUFULENBQWlCVSxJQUFqQixFQUF1QlQsWUFBdkIsRUFBcUM7QUFDbkMsU0FBT0osWUFBWSxDQUFDYyxHQUFiLENBQWlCO0FBQ3RCQyxJQUFBQSxJQUFJLEVBQUUsZ0JBRGdCO0FBRXRCRixJQUFBQSxJQUFJLEVBQUUsTUFBTUEsSUFGVTtBQUd0QkcsSUFBQUEsT0FBTyxFQUFFO0FBQ1BDLE1BQUFBLGFBQWEsRUFBRSxZQUFZYixZQURwQjtBQUVQLG9CQUFjO0FBRlA7QUFIYSxHQUFqQixDQUFQO0FBUUQ7O0FBRURjLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVCxFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlQsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIGdpdGh1YiBBUEkuXG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG4gIHJldHVybiByZXF1ZXN0KCd1c2VyJywgYXV0aERhdGEuYWNjZXNzX3Rva2VuKS50aGVuKGRhdGEgPT4ge1xuICAgIGlmIChkYXRhICYmIGRhdGEuaWQgPT0gYXV0aERhdGEuaWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdHaXRodWIgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBhcGkgcmVxdWVzdHNcbmZ1bmN0aW9uIHJlcXVlc3QocGF0aCwgYWNjZXNzX3Rva2VuKSB7XG4gIHJldHVybiBodHRwc1JlcXVlc3QuZ2V0KHtcbiAgICBob3N0OiAnYXBpLmdpdGh1Yi5jb20nLFxuICAgIHBhdGg6ICcvJyArIHBhdGgsXG4gICAgaGVhZGVyczoge1xuICAgICAgQXV0aG9yaXphdGlvbjogJ2JlYXJlciAnICsgYWNjZXNzX3Rva2VuLFxuICAgICAgJ1VzZXItQWdlbnQnOiAncGFyc2Utc2VydmVyJyxcbiAgICB9LFxuICB9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQ6IHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGE6IHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/google.js b/lib/Adapters/Auth/google.js deleted file mode 100644 index 5d02b17870..0000000000 --- a/lib/Adapters/Auth/google.js +++ /dev/null @@ -1,167 +0,0 @@ -'use strict'; // Helper functions for accessing the google API. - -var Parse = require('parse/node').Parse; - -const https = require('https'); - -const jwt = require('jsonwebtoken'); - -const TOKEN_ISSUER = 'accounts.google.com'; -const HTTPS_TOKEN_ISSUER = 'https://accounts.google.com'; -let cache = {}; // Retrieve Google Signin Keys (with cache control) - -function getGoogleKeyByKeyId(keyId) { - if (cache[keyId] && cache.expiresAt > new Date()) { - return cache[keyId]; - } - - return new Promise((resolve, reject) => { - https.get(`https://www.googleapis.com/oauth2/v3/certs`, res => { - let data = ''; - res.on('data', chunk => { - data += chunk.toString('utf8'); - }); - res.on('end', () => { - const { - keys - } = JSON.parse(data); - const pems = keys.reduce((pems, { - n: modulus, - e: exposant, - kid - }) => Object.assign(pems, { - [kid]: rsaPublicKeyToPEM(modulus, exposant) - }), {}); - - if (res.headers['cache-control']) { - var expire = res.headers['cache-control'].match(/max-age=([0-9]+)/); - - if (expire) { - cache = Object.assign({}, pems, { - expiresAt: new Date(new Date().getTime() + Number(expire[1]) * 1000) - }); - } - } - - resolve(pems[keyId]); - }); - }).on('error', reject); - }); -} - -function getHeaderFromToken(token) { - const decodedToken = jwt.decode(token, { - complete: true - }); - - if (!decodedToken) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `provided token does not decode as JWT`); - } - - return decodedToken.header; -} - -async function verifyIdToken({ - id_token: token, - id -}, { - clientId -}) { - if (!token) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token is invalid for this user.`); - } - - const { - kid: keyId, - alg: algorithm - } = getHeaderFromToken(token); - let jwtClaims; - const googleKey = await getGoogleKeyByKeyId(keyId); - - try { - jwtClaims = jwt.verify(token, googleKey, { - algorithms: algorithm, - audience: clientId - }); - } catch (exception) { - const message = exception.message; - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `${message}`); - } - - if (jwtClaims.iss !== TOKEN_ISSUER && jwtClaims.iss !== HTTPS_TOKEN_ISSUER) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token not issued by correct provider - expected: ${TOKEN_ISSUER} or ${HTTPS_TOKEN_ISSUER} | from: ${jwtClaims.iss}`); - } - - if (jwtClaims.sub !== id) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `auth data is invalid for this user.`); - } - - if (clientId && jwtClaims.aud !== clientId) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token not authorized for this clientId.`); - } - - return jwtClaims; -} // Returns a promise that fulfills if this user id is valid. - - -function validateAuthData(authData, options = {}) { - return verifyIdToken(authData, options); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; // Helpers functions to convert the RSA certs to PEM (from jwks-rsa) - -function rsaPublicKeyToPEM(modulusB64, exponentB64) { - const modulus = new Buffer(modulusB64, 'base64'); - const exponent = new Buffer(exponentB64, 'base64'); - const modulusHex = prepadSigned(modulus.toString('hex')); - const exponentHex = prepadSigned(exponent.toString('hex')); - const modlen = modulusHex.length / 2; - const explen = exponentHex.length / 2; - const encodedModlen = encodeLengthHex(modlen); - const encodedExplen = encodeLengthHex(explen); - const encodedPubkey = '30' + encodeLengthHex(modlen + explen + encodedModlen.length / 2 + encodedExplen.length / 2 + 2) + '02' + encodedModlen + modulusHex + '02' + encodedExplen + exponentHex; - const der = new Buffer(encodedPubkey, 'hex').toString('base64'); - let pem = '-----BEGIN RSA PUBLIC KEY-----\n'; - pem += `${der.match(/.{1,64}/g).join('\n')}`; - pem += '\n-----END RSA PUBLIC KEY-----\n'; - return pem; -} - -function prepadSigned(hexStr) { - const msb = hexStr[0]; - - if (msb < '0' || msb > '7') { - return `00${hexStr}`; - } - - return hexStr; -} - -function toHex(number) { - const nstr = number.toString(16); - - if (nstr.length % 2) { - return `0${nstr}`; - } - - return nstr; -} - -function encodeLengthHex(n) { - if (n <= 127) { - return toHex(n); - } - - const nHex = toHex(n); - const lengthOfLengthByte = 128 + nHex.length / 2; - return toHex(lengthOfLengthByte) + nHex; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2dvb2dsZS5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwcyIsImp3dCIsIlRPS0VOX0lTU1VFUiIsIkhUVFBTX1RPS0VOX0lTU1VFUiIsImNhY2hlIiwiZ2V0R29vZ2xlS2V5QnlLZXlJZCIsImtleUlkIiwiZXhwaXJlc0F0IiwiRGF0ZSIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiZ2V0IiwicmVzIiwiZGF0YSIsIm9uIiwiY2h1bmsiLCJ0b1N0cmluZyIsImtleXMiLCJKU09OIiwicGFyc2UiLCJwZW1zIiwicmVkdWNlIiwibiIsIm1vZHVsdXMiLCJlIiwiZXhwb3NhbnQiLCJraWQiLCJPYmplY3QiLCJhc3NpZ24iLCJyc2FQdWJsaWNLZXlUb1BFTSIsImhlYWRlcnMiLCJleHBpcmUiLCJtYXRjaCIsImdldFRpbWUiLCJOdW1iZXIiLCJnZXRIZWFkZXJGcm9tVG9rZW4iLCJ0b2tlbiIsImRlY29kZWRUb2tlbiIsImRlY29kZSIsImNvbXBsZXRlIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiaGVhZGVyIiwidmVyaWZ5SWRUb2tlbiIsImlkX3Rva2VuIiwiaWQiLCJjbGllbnRJZCIsImFsZyIsImFsZ29yaXRobSIsImp3dENsYWltcyIsImdvb2dsZUtleSIsInZlcmlmeSIsImFsZ29yaXRobXMiLCJhdWRpZW5jZSIsImV4Y2VwdGlvbiIsIm1lc3NhZ2UiLCJpc3MiLCJzdWIiLCJhdWQiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJvcHRpb25zIiwidmFsaWRhdGVBcHBJZCIsIm1vZHVsZSIsImV4cG9ydHMiLCJtb2R1bHVzQjY0IiwiZXhwb25lbnRCNjQiLCJCdWZmZXIiLCJleHBvbmVudCIsIm1vZHVsdXNIZXgiLCJwcmVwYWRTaWduZWQiLCJleHBvbmVudEhleCIsIm1vZGxlbiIsImxlbmd0aCIsImV4cGxlbiIsImVuY29kZWRNb2RsZW4iLCJlbmNvZGVMZW5ndGhIZXgiLCJlbmNvZGVkRXhwbGVuIiwiZW5jb2RlZFB1YmtleSIsImRlciIsInBlbSIsImpvaW4iLCJoZXhTdHIiLCJtc2IiLCJ0b0hleCIsIm51bWJlciIsIm5zdHIiLCJuSGV4IiwibGVuZ3RoT2ZMZW5ndGhCeXRlIl0sIm1hcHBpbmdzIjoiQUFBQSxhLENBRUE7O0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFFQSxNQUFNRSxLQUFLLEdBQUdELE9BQU8sQ0FBQyxPQUFELENBQXJCOztBQUNBLE1BQU1FLEdBQUcsR0FBR0YsT0FBTyxDQUFDLGNBQUQsQ0FBbkI7O0FBRUEsTUFBTUcsWUFBWSxHQUFHLHFCQUFyQjtBQUNBLE1BQU1DLGtCQUFrQixHQUFHLDZCQUEzQjtBQUVBLElBQUlDLEtBQUssR0FBRyxFQUFaLEMsQ0FFQTs7QUFDQSxTQUFTQyxtQkFBVCxDQUE2QkMsS0FBN0IsRUFBb0M7QUFDbEMsTUFBSUYsS0FBSyxDQUFDRSxLQUFELENBQUwsSUFBZ0JGLEtBQUssQ0FBQ0csU0FBTixHQUFrQixJQUFJQyxJQUFKLEVBQXRDLEVBQWtEO0FBQ2hELFdBQU9KLEtBQUssQ0FBQ0UsS0FBRCxDQUFaO0FBQ0Q7O0FBRUQsU0FBTyxJQUFJRyxPQUFKLENBQVksQ0FBQ0MsT0FBRCxFQUFVQyxNQUFWLEtBQXFCO0FBQ3RDWCxJQUFBQSxLQUFLLENBQ0ZZLEdBREgsQ0FDUSw0Q0FEUixFQUNxREMsR0FBRyxJQUFJO0FBQ3hELFVBQUlDLElBQUksR0FBRyxFQUFYO0FBQ0FELE1BQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLE1BQVAsRUFBZUMsS0FBSyxJQUFJO0FBQ3RCRixRQUFBQSxJQUFJLElBQUlFLEtBQUssQ0FBQ0MsUUFBTixDQUFlLE1BQWYsQ0FBUjtBQUNELE9BRkQ7QUFHQUosTUFBQUEsR0FBRyxDQUFDRSxFQUFKLENBQU8sS0FBUCxFQUFjLE1BQU07QUFDbEIsY0FBTTtBQUFFRyxVQUFBQTtBQUFGLFlBQVdDLElBQUksQ0FBQ0Ms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O0FBQ0EsU0FBT0EsR0FBUDtBQUNEOztBQUVELFNBQVNWLFlBQVQsQ0FBc0JZLE1BQXRCLEVBQThCO0FBQzVCLFFBQU1DLEdBQUcsR0FBR0QsTUFBTSxDQUFDLENBQUQsQ0FBbEI7O0FBQ0EsTUFBSUMsR0FBRyxHQUFHLEdBQU4sSUFBYUEsR0FBRyxHQUFHLEdBQXZCLEVBQTRCO0FBQzFCLFdBQVEsS0FBSUQsTUFBTyxFQUFuQjtBQUNEOztBQUNELFNBQU9BLE1BQVA7QUFDRDs7QUFFRCxTQUFTRSxLQUFULENBQWVDLE1BQWYsRUFBdUI7QUFDckIsUUFBTUMsSUFBSSxHQUFHRCxNQUFNLENBQUNyRSxRQUFQLENBQWdCLEVBQWhCLENBQWI7O0FBQ0EsTUFBSXNFLElBQUksQ0FBQ2IsTUFBTCxHQUFjLENBQWxCLEVBQXFCO0FBQ25CLFdBQVEsSUFBR2EsSUFBSyxFQUFoQjtBQUNEOztBQUNELFNBQU9BLElBQVA7QUFDRDs7QUFFRCxTQUFTVixlQUFULENBQXlCdEQsQ0FBekIsRUFBNEI7QUFDMUIsTUFBSUEsQ0FBQyxJQUFJLEdBQVQsRUFBYztBQUNaLFdBQU84RCxLQUFLLENBQUM5RCxDQUFELENBQVo7QUFDRDs7QUFDRCxRQUFNaUUsSUFBSSxHQUFHSCxLQUFLLENBQUM5RCxDQUFELENBQWxCO0FBQ0EsUUFBTWtFLGtCQUFrQixHQUFHLE1BQU1ELElBQUksQ0FBQ2QsTUFBTCxHQUFjLENBQS9DO0FBQ0EsU0FBT1csS0FBSyxDQUFDSSxrQkFBRCxDQUFMLEdBQTRCRCxJQUFuQztBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIGdvb2dsZSBBUEkuXG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbmNvbnN0IGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKTtcbmNvbnN0IGp3dCA9IHJlcXVpcmUoJ2pzb253ZWJ0b2tlbicpO1xuXG5jb25zdCBUT0tFTl9JU1NVRVIgPSAnYWNjb3VudHMuZ29vZ2xlLmNvbSc7XG5jb25zdCBIVFRQU19UT0tFTl9JU1NVRVIgPSAnaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tJztcblxubGV0IGNhY2hlID0ge307XG5cbi8vIFJldHJpZXZlIEdvb2dsZSBTaWduaW4gS2V5cyAod2l0aCBjYWNoZSBjb250cm9sKVxuZnVuY3Rpb24gZ2V0R29vZ2xlS2V5QnlLZXlJZChrZXlJZCkge1xuICBpZiAoY2FjaGVba2V5SWRdICYmIGNhY2hlLmV4cGlyZXNBdCA+IG5ldyBEYXRlKCkpIHtcbiAgICByZXR1cm4gY2FjaGVba2V5SWRdO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBodHRwc1xuICAgICAgLmdldChgaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vb2F1dGgyL3YzL2NlcnRzYCwgcmVzID0+IHtcbiAgICAgICAgbGV0IGRhdGEgPSAnJztcbiAgICAgICAgcmVzLm9uKCdkYXRhJywgY2h1bmsgPT4ge1xuICAgICAgICAgIGRhdGEgKz0gY2h1bmsudG9TdHJpbmcoJ3V0ZjgnKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJlcy5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsga2V5cyB9ID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgICAgICBjb25zdCBwZW1zID0ga2V5cy5yZWR1Y2UoXG4gICAgICAgICAgICAocGVtcywgeyBuOiBtb2R1bHVzLCBlOiBleHBvc2FudCwga2lkIH0pID0+XG4gICAgICAgICAgICAgIE9iamVjdC5hc3NpZ24ocGVtcywge1xuICAgICAgICAgICAgICAgIFtraWRdOiByc2FQdWJsaWNLZXlUb1BFTShtb2R1bHVzLCBleHBvc2FudCksXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAge31cbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKHJlcy5oZWFkZXJzWydjYWNoZS1jb250cm9sJ10pIHtcbiAgICAgICAgICAgIHZhciBleHBpcmUgPSByZXMuaGVhZGVyc1snY2FjaGUtY29udHJvbCddLm1hdGNoKC9tYXgtYWdlPShbMC05XSspLyk7XG5cbiAgICAgICAgICAgIGlmIChleHBpcmUpIHtcbiAgICAgICAgICAgICAgY2FjaGUgPSBPYmplY3QuYXNzaWduKHt9LCBwZW1zLCB7XG4gICAgICAgICAgICAgICAgZXhwaXJlc0F0OiBuZXcgRGF0ZShuZXcgRGF0ZSgpLmdldFRpbWUoKSArIE51bWJlcihleHBpcmVbMV0pICogMTAwMCksXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJlc29sdmUocGVtc1trZXlJZF0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldEhlYWRlckZyb21Ub2tlbih0b2tlbikge1xuICBjb25zdCBkZWNvZGVkVG9rZW4gPSBqd3QuZGVjb2RlKHRva2VuLCB7IGNvbXBsZXRlOiB0cnVlIH0pO1xuXG4gIGlmICghZGVjb2RlZFRva2VuKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsIGBwcm92aWRlZCB0b2tlbiBkb2VzIG5vdCBkZWNvZGUgYXMgSldUYCk7XG4gIH1cblxuICByZXR1cm4gZGVjb2RlZFRva2VuLmhlYWRlcjtcbn1cblxuYXN5bmMgZnVuY3Rpb24gdmVyaWZ5SWRUb2tlbih7IGlkX3Rva2VuOiB0b2tlbiwgaWQgfSwgeyBjbGllbnRJZCB9KSB7XG4gIGlmICghdG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgYGlkIHRva2VuIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci5gKTtcbiAgfVxuXG4gIGNvbnN0IHsga2lkOiBrZXlJZCwgYWxnOiBhbGdvcml0aG0gfSA9IGdldEhlYWRlckZyb21Ub2tlbih0b2tlbik7XG4gIGxldCBqd3RDbGFpbXM7XG4gIGNvbnN0IGdvb2dsZUtleSA9IGF3YWl0IGdldEdvb2dsZUtleUJ5S2V5SWQoa2V5SWQpO1xuXG4gIHRyeSB7XG4gICAgand0Q2xhaW1zID0gand0LnZlcmlmeSh0b2tlbiwgZ29vZ2xlS2V5LCB7XG4gICAgICBhbGdvcml0aG1zOiBhbGdvcml0aG0sXG4gICAgICBhdWRpZW5jZTogY2xpZW50SWQsXG4gICAgfSk7XG4gIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBleGNlcHRpb24ubWVzc2FnZTtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgYCR7bWVzc2FnZX1gKTtcbiAgfVxuXG4gIGlmIChqd3RDbGFpbXMuaXNzICE9PSBUT0tFTl9JU1NVRVIgJiYgand0Q2xhaW1zLmlzcyAhPT0gSFRUUFNfVE9LRU5fSVNTVUVSKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgIGBpZCB0b2tlbiBub3QgaXNzdWVkIGJ5IGNvcnJlY3QgcHJvdmlkZXIgLSBleHBlY3RlZDogJHtUT0tFTl9JU1NVRVJ9IG9yICR7SFRUUFNfVE9LRU5fSVNTVUVSfSB8IGZyb206ICR7and0Q2xhaW1zLmlzc31gXG4gICAgKTtcbiAgfVxuXG4gIGlmIChqd3RDbGFpbXMuc3ViICE9PSBpZCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBgYXV0aCBkYXRhIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci5gKTtcbiAgfVxuXG4gIGlmIChjbGllbnRJZCAmJiBqd3RDbGFpbXMuYXVkICE9PSBjbGllbnRJZCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICBgaWQgdG9rZW4gbm90IGF1dGhvcml6ZWQgZm9yIHRoaXMgY2xpZW50SWQuYFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gand0Q2xhaW1zO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIG9wdGlvbnMgPSB7fSkge1xuICByZXR1cm4gdmVyaWZ5SWRUb2tlbihhdXRoRGF0YSwgb3B0aW9ucyk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcblxuLy8gSGVscGVycyBmdW5jdGlvbnMgdG8gY29udmVydCB0aGUgUlNBIGNlcnRzIHRvIFBFTSAoZnJvbSBqd2tzLXJzYSlcbmZ1bmN0aW9uIHJzYVB1YmxpY0tleVRvUEVNKG1vZHVsdXNCNjQsIGV4cG9uZW50QjY0KSB7XG4gIGNvbnN0IG1vZHVsdXMgPSBuZXcgQnVmZmVyKG1vZHVsdXNCNjQsICdiYXNlNjQnKTtcbiAgY29uc3QgZXhwb25lbnQgPSBuZXcgQnVmZmVyKGV4cG9uZW50QjY0LCAnYmFzZTY0Jyk7XG4gIGNvbnN0IG1vZHVsdXNIZXggPSBwcmVwYWRTaWduZWQobW9kdWx1cy50b1N0cmluZygnaGV4JykpO1xuICBjb25zdCBleHBvbmVudEhleCA9IHByZXBhZFNpZ25lZChleHBvbmVudC50b1N0cmluZygnaGV4JykpO1xuICBjb25zdCBtb2RsZW4gPSBtb2R1bHVzSGV4Lmxlbmd0aCAvIDI7XG4gIGNvbnN0IGV4cGxlbiA9IGV4cG9uZW50SGV4Lmxlbmd0aCAvIDI7XG5cbiAgY29uc3QgZW5jb2RlZE1vZGxlbiA9IGVuY29kZUxlbmd0aEhleChtb2RsZW4pO1xuICBjb25zdCBlbmNvZGVkRXhwbGVuID0gZW5jb2RlTGVuZ3RoSGV4KGV4cGxlbik7XG4gIGNvbnN0IGVuY29kZWRQdWJrZXkgPVxuICAgICczMCcgK1xuICAgIGVuY29kZUxlbmd0aEhleChtb2RsZW4gKyBleHBsZW4gKyBlbmNvZGVkTW9kbGVuLmxlbmd0aCAvIDIgKyBlbmNvZGVkRXhwbGVuLmxlbmd0aCAvIDIgKyAyKSArXG4gICAgJzAyJyArXG4gICAgZW5jb2RlZE1vZGxlbiArXG4gICAgbW9kdWx1c0hleCArXG4gICAgJzAyJyArXG4gICAgZW5jb2RlZEV4cGxlbiArXG4gICAgZXhwb25lbnRIZXg7XG5cbiAgY29uc3QgZGVyID0gbmV3IEJ1ZmZlcihlbmNvZGVkUHVia2V5LCAnaGV4JykudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuXG4gIGxldCBwZW0gPSAnLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tXFxuJztcbiAgcGVtICs9IGAke2Rlci5tYXRjaCgvLnsxLDY0fS9nKS5qb2luKCdcXG4nKX1gO1xuICBwZW0gKz0gJ1xcbi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS1cXG4nO1xuICByZXR1cm4gcGVtO1xufVxuXG5mdW5jdGlvbiBwcmVwYWRTaWduZWQoaGV4U3RyKSB7XG4gIGNvbnN0IG1zYiA9IGhleFN0clswXTtcbiAgaWYgKG1zYiA8ICcwJyB8fCBtc2IgPiAnNycpIHtcbiAgICByZXR1cm4gYDAwJHtoZXhTdHJ9YDtcbiAgfVxuICByZXR1cm4gaGV4U3RyO1xufVxuXG5mdW5jdGlvbiB0b0hleChudW1iZXIpIHtcbiAgY29uc3QgbnN0ciA9IG51bWJlci50b1N0cmluZygxNik7XG4gIGlmIChuc3RyLmxlbmd0aCAlIDIpIHtcbiAgICByZXR1cm4gYDAke25zdHJ9YDtcbiAgfVxuICByZXR1cm4gbnN0cjtcbn1cblxuZnVuY3Rpb24gZW5jb2RlTGVuZ3RoSGV4KG4pIHtcbiAgaWYgKG4gPD0gMTI3KSB7XG4gICAgcmV0dXJuIHRvSGV4KG4pO1xuICB9XG4gIGNvbnN0IG5IZXggPSB0b0hleChuKTtcbiAgY29uc3QgbGVuZ3RoT2ZMZW5ndGhCeXRlID0gMTI4ICsgbkhleC5sZW5ndGggLyAyO1xuICByZXR1cm4gdG9IZXgobGVuZ3RoT2ZMZW5ndGhCeXRlKSArIG5IZXg7XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/gpgames.js b/lib/Adapters/Auth/gpgames.js deleted file mode 100644 index 9030748d39..0000000000 --- a/lib/Adapters/Auth/gpgames.js +++ /dev/null @@ -1,35 +0,0 @@ -"use strict"; - -/* Google Play Game Services -https://developers.google.com/games/services/web/api/players/get - -const authData = { - id: 'playerId', - access_token: 'token', -}; -*/ -const { - Parse -} = require('parse/node'); - -const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills if this user id is valid. - - -async function validateAuthData(authData) { - const response = await httpsRequest.get(`https://www.googleapis.com/games/v1/players/${authData.id}?access_token=${authData.access_token}`); - - if (!(response && response.playerId === authData.id)) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Google Play Games Services - authData is invalid for this user.'); - } -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} - -module.exports = { - validateAppId, - validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2dwZ2FtZXMuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwiaHR0cHNSZXF1ZXN0IiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwicmVzcG9uc2UiLCJnZXQiLCJpZCIsImFjY2Vzc190b2tlbiIsInBsYXllcklkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsIlByb21pc2UiLCJyZXNvbHZlIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUFFQSxFQUFBQTtBQUFGLElBQVlDLE9BQU8sQ0FBQyxZQUFELENBQXpCOztBQUNBLE1BQU1DLFlBQVksR0FBR0QsT0FBTyxDQUFDLGdCQUFELENBQTVCLEMsQ0FFQTs7O0FBQ0EsZUFBZUUsZ0JBQWYsQ0FBZ0NDLFFBQWhDLEVBQTBDO0FBQ3hDLFFBQU1DLFFBQVEsR0FBRyxNQUFNSCxZQUFZLENBQUNJLEdBQWIsQ0FDcEIsK0NBQThDRixRQUFRLENBQUNHLEVBQUcsaUJBQWdCSCxRQUFRLENBQUNJLFlBQWEsRUFENUUsQ0FBdkI7O0FBR0EsTUFBSSxFQUFFSCxRQUFRLElBQUlBLFFBQVEsQ0FBQ0ksUUFBVCxLQUFzQkwsUUFBUSxDQUFDRyxFQUE3QyxDQUFKLEVBQXNEO0FBQ3BELFVBQU0sSUFBSVAsS0FBSyxDQUFDVSxLQUFWLENBQ0pWLEtBQUssQ0FBQ1UsS0FBTixDQUFZQyxnQkFEUixFQUVKLGlFQUZJLENBQU47QUFJRDtBQUNGLEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVEQyxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZkosRUFBQUEsYUFEZTtBQUVmVCxFQUFBQTtBQUZlLENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLyogR29vZ2xlIFBsYXkgR2FtZSBTZXJ2aWNlc1xuaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vZ2FtZXMvc2VydmljZXMvd2ViL2FwaS9wbGF5ZXJzL2dldFxuXG5jb25zdCBhdXRoRGF0YSA9IHtcbiAgaWQ6ICdwbGF5ZXJJZCcsXG4gIGFjY2Vzc190b2tlbjogJ3Rva2VuJyxcbn07XG4qL1xuY29uc3QgeyBQYXJzZSB9ID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpO1xuY29uc3QgaHR0cHNSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwc1JlcXVlc3QnKTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5hc3luYyBmdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgaHR0cHNSZXF1ZXN0LmdldChcbiAgICBgaHR0cHM6Ly93d3cuZ29vZ2xlYXBpcy5jb20vZ2FtZXMvdjEvcGxheWVycy8ke2F1dGhEYXRhLmlkfT9hY2Nlc3NfdG9rZW49JHthdXRoRGF0YS5hY2Nlc3NfdG9rZW59YFxuICApO1xuICBpZiAoIShyZXNwb25zZSAmJiByZXNwb25zZS5wbGF5ZXJJZCA9PT0gYXV0aERhdGEuaWQpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICdHb29nbGUgUGxheSBHYW1lcyBTZXJ2aWNlcyAtIGF1dGhEYXRhIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nXG4gICAgKTtcbiAgfVxufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/httpsRequest.js b/lib/Adapters/Auth/httpsRequest.js deleted file mode 100644 index d6dd47a969..0000000000 --- a/lib/Adapters/Auth/httpsRequest.js +++ /dev/null @@ -1,47 +0,0 @@ -"use strict"; - -const https = require('https'); - -function makeCallback(resolve, reject, noJSON) { - return function (res) { - let data = ''; - res.on('data', chunk => { - data += chunk; - }); - res.on('end', () => { - if (noJSON) { - return resolve(data); - } - - try { - data = JSON.parse(data); - } catch (e) { - return reject(e); - } - - resolve(data); - }); - res.on('error', reject); - }; -} - -function get(options, noJSON = false) { - return new Promise((resolve, reject) => { - https.get(options, makeCallback(resolve, reject, noJSON)).on('error', reject); - }); -} - -function request(options, postData) { - return new Promise((resolve, reject) => { - const req = https.request(options, makeCallback(resolve, reject)); - req.on('error', reject); - req.write(postData); - req.end(); - }); -} - -module.exports = { - get, - request -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2h0dHBzUmVxdWVzdC5qcyJdLCJuYW1lcyI6WyJodHRwcyIsInJlcXVpcmUiLCJtYWtlQ2FsbGJhY2siLCJyZXNvbHZlIiwicmVqZWN0Iiwibm9KU09OIiwicmVzIiwiZGF0YSIsIm9uIiwiY2h1bmsiLCJKU09OIiwicGFyc2UiLCJlIiwiZ2V0Iiwib3B0aW9ucyIsIlByb21pc2UiLCJyZXF1ZXN0IiwicG9zdERhdGEiLCJyZXEiLCJ3cml0ZSIsImVuZCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUEsTUFBTUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsT0FBRCxDQUFyQjs7QUFFQSxTQUFTQyxZQUFULENBQXNCQyxPQUF0QixFQUErQkMsTUFBL0IsRUFBdUNDLE1BQXZDLEVBQStDO0FBQzdDLFNBQU8sVUFBVUMsR0FBVixFQUFlO0FBQ3BCLFFBQUlDLElBQUksR0FBRyxFQUFYO0FBQ0FELElBQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLE1BQVAsRUFBZUMsS0FBSyxJQUFJO0FBQ3RCRixNQUFBQSxJQUFJLElBQUlFLEtBQVI7QUFDRCxLQUZEO0FBR0FILElBQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLEtBQVAsRUFBYyxNQUFNO0FBQ2xCLFVBQUlILE1BQUosRUFBWTtBQUNWLGVBQU9GLE9BQU8sQ0FBQ0ksSUFBRCxDQUFkO0FBQ0Q7O0FBQ0QsVUFBSTtBQUNGQSxRQUFBQSxJQUFJLEdBQUdHLElBQUksQ0FBQ0MsS0FBTCxDQUFXSixJQUFYLENBQVA7QUFDRCxPQUZELENBRUUsT0FBT0ssQ0FBUCxFQUFVO0FBQ1YsZUFBT1IsTUFBTSxDQUFDUSxDQUFELENBQWI7QUFDRDs7QUFDRFQsTUFBQUEsT0FBTyxDQUFDSSxJQUFELENBQVA7QUFDRCxLQVZEO0FBV0FELElBQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLE9BQVAsRUFBZ0JKLE1BQWhCO0FBQ0QsR0FqQkQ7QUFrQkQ7O0FBRUQsU0FBU1MsR0FBVCxDQUFhQyxPQUFiLEVBQXNCVCxNQUFNLEdBQUcsS0FBL0IsRUFBc0M7QUFDcEMsU0FBTyxJQUFJVSxPQUFKLENBQVksQ0FBQ1osT0FBRCxFQUFVQyxNQUFWLEtBQXFCO0FBQ3RDSixJQUFBQSxLQUFLLENBQUNhLEdBQU4sQ0FBVUMsT0FBVixFQUFtQlosWUFBWSxDQUFDQyxPQUFELEVBQVVDLE1BQVYsRUFBa0JDLE1BQWxCLENBQS9CLEVBQTBERyxFQUExRCxDQUE2RCxPQUE3RCxFQUFzRUosTUFBdEU7QUFDRCxHQUZNLENBQVA7QUFHRDs7QUFFRCxTQUFTWSxPQUFULENBQWlCRixPQUFqQixFQUEwQkcsUUFBMUIsRUFBb0M7QUFDbEMsU0FBTyxJQUFJRixPQUFKLENBQVksQ0FBQ1osT0FBRCxFQUFVQyxNQUFWLEtBQXFCO0FBQ3RDLFVBQU1jLEdBQUcsR0FBR2xCLEtBQUssQ0FBQ2dCLE9BQU4sQ0FBY0YsT0FBZCxFQUF1QlosWUFBWSxDQUFDQyxPQUFELEVBQVVDLE1BQVYsQ0FBbkMsQ0FBWjtBQUNBYyxJQUFBQSxHQUFHLENBQUNWLEVBQUosQ0FBTyxPQUFQLEVBQWdCSixNQUFoQjtBQUNBYyxJQUFBQSxHQUFHLENBQUNDLEtBQUosQ0FBVUYsUUFBVjtBQUNBQyxJQUFBQSxHQUFHLENBQUNFLEdBQUo7QUFDRCxHQUxNLENBQVA7QUFNRDs7QUFFREMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQUVULEVBQUFBLEdBQUY7QUFBT0csRUFBQUE7QUFBUCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGh0dHBzID0gcmVxdWlyZSgnaHR0cHMnKTtcblxuZnVuY3Rpb24gbWFrZUNhbGxiYWNrKHJlc29sdmUsIHJlamVjdCwgbm9KU09OKSB7XG4gIHJldHVybiBmdW5jdGlvbiAocmVzKSB7XG4gICAgbGV0IGRhdGEgPSAnJztcbiAgICByZXMub24oJ2RhdGEnLCBjaHVuayA9PiB7XG4gICAgICBkYXRhICs9IGNodW5rO1xuICAgIH0pO1xuICAgIHJlcy5vbignZW5kJywgKCkgPT4ge1xuICAgICAgaWYgKG5vSlNPTikge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZShkYXRhKTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIGRhdGEgPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gcmVqZWN0KGUpO1xuICAgICAgfVxuICAgICAgcmVzb2x2ZShkYXRhKTtcbiAgICB9KTtcbiAgICByZXMub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0KG9wdGlvbnMsIG5vSlNPTiA9IGZhbHNlKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgaHR0cHMuZ2V0KG9wdGlvbnMsIG1ha2VDYWxsYmFjayhyZXNvbHZlLCByZWplY3QsIG5vSlNPTikpLm9uKCdlcnJvcicsIHJlamVjdCk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiByZXF1ZXN0KG9wdGlvbnMsIHBvc3REYXRhKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgcmVxID0gaHR0cHMucmVxdWVzdChvcHRpb25zLCBtYWtlQ2FsbGJhY2socmVzb2x2ZSwgcmVqZWN0KSk7XG4gICAgcmVxLm9uKCdlcnJvcicsIHJlamVjdCk7XG4gICAgcmVxLndyaXRlKHBvc3REYXRhKTtcbiAgICByZXEuZW5kKCk7XG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHsgZ2V0LCByZXF1ZXN0IH07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/index.js b/lib/Adapters/Auth/index.js deleted file mode 100755 index a2ab7b7442..0000000000 --- a/lib/Adapters/Auth/index.js +++ /dev/null @@ -1,173 +0,0 @@ -"use strict"; - -var _AdapterLoader = _interopRequireDefault(require("../AdapterLoader")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const apple = require('./apple'); - -const gcenter = require('./gcenter'); - -const gpgames = require('./gpgames'); - -const facebook = require('./facebook'); - -const instagram = require('./instagram'); - -const linkedin = require('./linkedin'); - -const meetup = require('./meetup'); - -const google = require('./google'); - -const github = require('./github'); - -const twitter = require('./twitter'); - -const spotify = require('./spotify'); - -const digits = require('./twitter'); // digits tokens are validated by twitter - - -const janrainengage = require('./janrainengage'); - -const janraincapture = require('./janraincapture'); - -const line = require('./line'); - -const vkontakte = require('./vkontakte'); - -const qq = require('./qq'); - -const wechat = require('./wechat'); - -const weibo = require('./weibo'); - -const oauth2 = require('./oauth2'); - -const phantauth = require('./phantauth'); - -const microsoft = require('./microsoft'); - -const keycloak = require('./keycloak'); - -const ldap = require('./ldap'); - -const anonymous = { - validateAuthData: () => { - return Promise.resolve(); - }, - validateAppId: () => { - return Promise.resolve(); - } -}; -const providers = { - apple, - gcenter, - gpgames, - facebook, - instagram, - linkedin, - meetup, - google, - github, - twitter, - spotify, - anonymous, - digits, - janrainengage, - janraincapture, - line, - vkontakte, - qq, - wechat, - weibo, - phantauth, - microsoft, - keycloak, - ldap -}; - -function authDataValidator(adapter, appIds, options) { - return function (authData) { - return adapter.validateAuthData(authData, options).then(() => { - if (appIds) { - return adapter.validateAppId(appIds, authData, options); - } - - return Promise.resolve(); - }); - }; -} - -function loadAuthAdapter(provider, authOptions) { - let defaultAdapter = providers[provider]; - const providerOptions = authOptions[provider]; - - if (providerOptions && Object.prototype.hasOwnProperty.call(providerOptions, 'oauth2') && providerOptions['oauth2'] === true) { - defaultAdapter = oauth2; - } - - if (!defaultAdapter && !providerOptions) { - return; - } - - const adapter = Object.assign({}, defaultAdapter); - const appIds = providerOptions ? providerOptions.appIds : undefined; // Try the configuration methods - - if (providerOptions) { - const optionalAdapter = (0, _AdapterLoader.default)(providerOptions, undefined, providerOptions); - - if (optionalAdapter) { - ['validateAuthData', 'validateAppId'].forEach(key => { - if (optionalAdapter[key]) { - adapter[key] = optionalAdapter[key]; - } - }); - } - } // TODO: create a new module from validateAdapter() in - // src/Controllers/AdaptableController.js so we can use it here for adapter - // validation based on the src/Adapters/Auth/AuthAdapter.js expected class - // signature. - - - if (!adapter.validateAuthData || !adapter.validateAppId) { - return; - } - - return { - adapter, - appIds, - providerOptions - }; -} - -module.exports = function (authOptions = {}, enableAnonymousUsers = true) { - let _enableAnonymousUsers = enableAnonymousUsers; - - const setEnableAnonymousUsers = function (enable) { - _enableAnonymousUsers = enable; - }; // To handle the test cases on configuration - - - const getValidatorForProvider = function (provider) { - if (provider === 'anonymous' && !_enableAnonymousUsers) { - return; - } - - const { - adapter, - appIds, - providerOptions - } = loadAuthAdapter(provider, authOptions); - return authDataValidator(adapter, appIds, providerOptions); - }; - - return Object.freeze({ - getValidatorForProvider, - setEnableAnonymousUsers - }); -}; - -module.exports.loadAuthAdapter = loadAuthAdapter; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2luZGV4LmpzIl0sIm5hbWVzIjpbImFwcGxlIiwicmVxdWlyZSIsImdjZW50ZXIiLCJncGdhbWVzIiwiZmFjZWJvb2siLCJpbnN0YWdyYW0iLCJsaW5rZWRpbiIsIm1lZXR1cCIsImdvb2dsZSIsImdpdGh1YiIsInR3aXR0ZXIiLCJzcG90aWZ5IiwiZGlnaXRzIiwiamFucmFpbmVuZ2FnZSIsImphbnJhaW5jYXB0dXJlIiwibGluZSIsInZrb250YWt0ZSIsInFxIiwid2VjaGF0Iiwid2VpYm8iLCJvYXV0aDIiLCJwaGFudGF1dGgiLCJtaWNyb3NvZnQiLCJrZXljbG9hayIsImxkYXAiLCJhbm9ueW1vdXMiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ2YWxpZGF0ZUFwcElkIiwicHJvdmlkZXJzIiwiYXV0aERhdGFWYWxpZGF0b3IiLCJhZGFwdGVyIiwiYXBwSWRzIiwib3B0aW9ucyIsImF1dGhEYXRhIiwidGhlbiIsImxvYWRBdXRoQWRhcHRlciIsInByb3ZpZGVyIiwiYXV0aE9wdGlvbnMiLCJkZWZhdWx0QWRhcHRlciIsInByb3ZpZGVyT3B0aW9ucyIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImFzc2lnbiIsInVuZGVmaW5lZCIsIm9wdGlvbmFsQWRhcHRlciIsImZvckVhY2giLCJrZXkiLCJtb2R1bGUiLCJleHBvcnRzIiwiZW5hYmxlQW5vbnltb3VzVXNlcnMiLCJfZW5hYmxlQW5vbnltb3VzVXNlcnMiLCJzZXRFbmFibGVBbm9ueW1vdXNVc2VycyIsImVuYWJsZSIsImdldFZhbGlkYXRvckZvclByb3ZpZGVyIiwiZnJlZXplIl0sIm1hcHBpbmdzIjoiOztBQUFBOzs7O0FBRUEsTUFBTUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsU0FBRCxDQUFyQjs7QUFDQSxNQUFNQyxPQUFPLEdBQUdELE9BQU8sQ0FBQyxXQUFELENBQXZCOztBQUNB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T0FBUCxDQUFlZixlQUFmLEdBQWlDQSxlQUFqQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBsb2FkQWRhcHRlciBmcm9tICcuLi9BZGFwdGVyTG9hZGVyJztcblxuY29uc3QgYXBwbGUgPSByZXF1aXJlKCcuL2FwcGxlJyk7XG5jb25zdCBnY2VudGVyID0gcmVxdWlyZSgnLi9nY2VudGVyJyk7XG5jb25zdCBncGdhbWVzID0gcmVxdWlyZSgnLi9ncGdhbWVzJyk7XG5jb25zdCBmYWNlYm9vayA9IHJlcXVpcmUoJy4vZmFjZWJvb2snKTtcbmNvbnN0IGluc3RhZ3JhbSA9IHJlcXVpcmUoJy4vaW5zdGFncmFtJyk7XG5jb25zdCBsaW5rZWRpbiA9IHJlcXVpcmUoJy4vbGlua2VkaW4nKTtcbmNvbnN0IG1lZXR1cCA9IHJlcXVpcmUoJy4vbWVldHVwJyk7XG5jb25zdCBnb29nbGUgPSByZXF1aXJlKCcuL2dvb2dsZScpO1xuY29uc3QgZ2l0aHViID0gcmVxdWlyZSgnLi9naXRodWInKTtcbmNvbnN0IHR3aXR0ZXIgPSByZXF1aXJlKCcuL3R3aXR0ZXInKTtcbmNvbnN0IHNwb3RpZnkgPSByZXF1aXJlKCcuL3Nwb3RpZnknKTtcbmNvbnN0IGRpZ2l0cyA9IHJlcXVpcmUoJy4vdHdpdHRlcicpOyAvLyBkaWdpdHMgdG9rZW5zIGFyZSB2YWxpZGF0ZWQgYnkgdHdpdHRlclxuY29uc3QgamFucmFpbmVuZ2FnZSA9IHJlcXVpcmUoJy4vamFucmFpbmVuZ2FnZScpO1xuY29uc3QgamFucmFpbmNhcHR1cmUgPSByZXF1aXJlKCcuL2phbnJhaW5jYXB0dXJlJyk7XG5jb25zdCBsaW5lID0gcmVxdWlyZSgnLi9saW5lJyk7XG5jb25zdCB2a29udGFrdGUgPSByZXF1aXJlKCcuL3Zrb250YWt0ZScpO1xuY29uc3QgcXEgPSByZXF1aXJlKCcuL3FxJyk7XG5jb25zdCB3ZWNoYXQgPSByZXF1aXJlKCcuL3dlY2hhdCcpO1xuY29uc3Qgd2VpYm8gPSByZXF1aXJlKCcuL3dlaWJvJyk7XG5jb25zdCBvYXV0aDIgPSByZXF1aXJlKCcuL29hdXRoMicpO1xuY29uc3QgcGhhbnRhdXRoID0gcmVxdWlyZSgnLi9waGFudGF1dGgnKTtcbmNvbnN0IG1pY3Jvc29mdCA9IHJlcXVpcmUoJy4vbWljcm9zb2Z0Jyk7XG5jb25zdCBrZXljbG9hayA9IHJlcXVpcmUoJy4va2V5Y2xvYWsnKTtcbmNvbnN0IGxkYXAgPSByZXF1aXJlKCcuL2xkYXAnKTtcblxuY29uc3QgYW5vbnltb3VzID0ge1xuICB2YWxpZGF0ZUF1dGhEYXRhOiAoKSA9PiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9LFxuICB2YWxpZGF0ZUFwcElkOiAoKSA9PiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9LFxufTtcblxuY29uc3QgcHJvdmlkZXJzID0ge1xuICBhcHBsZSxcbiAgZ2NlbnRlcixcbiAgZ3BnYW1lcyxcbiAgZmFjZWJvb2ssXG4gIGluc3RhZ3JhbSxcbiAgbGlua2VkaW4sXG4gIG1lZXR1cCxcbiAgZ29vZ2xlLFxuICBnaXRodWIsXG4gIHR3aXR0ZXIsXG4gIHNwb3RpZnksXG4gIGFub255bW91cyxcbiAgZGlnaXRzLFxuICBqYW5yYWluZW5nYWdlLFxuICBqYW5yYWluY2FwdHVyZSxcbiAgbGluZSxcbiAgdmtvbnRha3RlLFxuICBxcSxcbiAgd2VjaGF0LFxuICB3ZWlibyxcbiAgcGhhbnRhdXRoLFxuICBtaWNyb3NvZnQsXG4gIGtleWNsb2FrLFxuICBsZGFwLFxufTtcblxuZnVuY3Rpb24gYXV0aERhdGFWYWxpZGF0b3IoYWRhcHRlciwgYXBwSWRzLCBvcHRpb25zKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoYXV0aERhdGEpIHtcbiAgICByZXR1cm4gYWRhcHRlci52YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhLCBvcHRpb25zKS50aGVuKCgpID0+IHtcbiAgICAgIGlmIChhcHBJZHMpIHtcbiAgICAgICAgcmV0dXJuIGFkYXB0ZXIudmFsaWRhdGVBcHBJZChhcHBJZHMsIGF1dGhEYXRhLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9KTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gbG9hZEF1dGhBZGFwdGVyKHByb3ZpZGVyLCBhdXRoT3B0aW9ucykge1xuICBsZXQgZGVmYXVsdEFkYXB0ZXIgPSBwcm92aWRlcnNbcHJvdmlkZXJdO1xuICBjb25zdCBwcm92aWRlck9wdGlvbnMgPSBhdXRoT3B0aW9uc1twcm92aWRlcl07XG4gIGlmIChcbiAgICBwcm92aWRlck9wdGlvbnMgJiZcbiAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocHJvdmlkZXJPcHRpb25zLCAnb2F1dGgyJykgJiZcbiAgICBwcm92aWRlck9wdGlvbnNbJ29hdXRoMiddID09PSB0cnVlXG4gICkge1xuICAgIGRlZmF1bHRBZGFwdGVyID0gb2F1dGgyO1xuICB9XG5cbiAgaWYgKCFkZWZhdWx0QWRhcHRlciAmJiAhcHJvdmlkZXJPcHRpb25zKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgYWRhcHRlciA9IE9iamVjdC5hc3NpZ24oe30sIGRlZmF1bHRBZGFwdGVyKTtcbiAgY29uc3QgYXBwSWRzID0gcHJvdmlkZXJPcHRpb25zID8gcHJvdmlkZXJPcHRpb25zLmFwcElkcyA6IHVuZGVmaW5lZDtcblxuICAvLyBUcnkgdGhlIGNvbmZpZ3VyYXRpb24gbWV0aG9kc1xuICBpZiAocHJvdmlkZXJPcHRpb25zKSB7XG4gICAgY29uc3Qgb3B0aW9uYWxBZGFwdGVyID0gbG9hZEFkYXB0ZXIocHJvdmlkZXJPcHRpb25zLCB1bmRlZmluZWQsIHByb3ZpZGVyT3B0aW9ucyk7XG4gICAgaWYgKG9wdGlvbmFsQWRhcHRlcikge1xuICAgICAgWyd2YWxpZGF0ZUF1dGhEYXRhJywgJ3ZhbGlkYXRlQXBwSWQnXS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgIGlmIChvcHRpb25hbEFkYXB0ZXJba2V5XSkge1xuICAgICAgICAgIGFkYXB0ZXJba2V5XSA9IG9wdGlvbmFsQWRhcHRlcltrZXldO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvLyBUT0RPOiBjcmVhdGUgYSBuZXcgbW9kdWxlIGZyb20gdmFsaWRhdGVBZGFwdGVyKCkgaW5cbiAgLy8gc3JjL0NvbnRyb2xsZXJzL0FkYXB0YWJsZUNvbnRyb2xsZXIuanMgc28gd2UgY2FuIHVzZSBpdCBoZXJlIGZvciBhZGFwdGVyXG4gIC8vIHZhbGlkYXRpb24gYmFzZWQgb24gdGhlIHNyYy9BZGFwdGVycy9BdXRoL0F1dGhBZGFwdGVyLmpzIGV4cGVjdGVkIGNsYXNzXG4gIC8vIHNpZ25hdHVyZS5cbiAgaWYgKCFhZGFwdGVyLnZhbGlkYXRlQXV0aERhdGEgfHwgIWFkYXB0ZXIudmFsaWRhdGVBcHBJZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHJldHVybiB7IGFkYXB0ZXIsIGFwcElkcywgcHJvdmlkZXJPcHRpb25zIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGF1dGhPcHRpb25zID0ge30sIGVuYWJsZUFub255bW91c1VzZXJzID0gdHJ1ZSkge1xuICBsZXQgX2VuYWJsZUFub255bW91c1VzZXJzID0gZW5hYmxlQW5vbnltb3VzVXNlcnM7XG4gIGNvbnN0IHNldEVuYWJsZUFub255bW91c1VzZXJzID0gZnVuY3Rpb24gKGVuYWJsZSkge1xuICAgIF9lbmFibGVBbm9ueW1vdXNVc2VycyA9IGVuYWJsZTtcbiAgfTtcbiAgLy8gVG8gaGFuZGxlIHRoZSB0ZXN0IGNhc2VzIG9uIGNvbmZpZ3VyYXRpb25cbiAgY29uc3QgZ2V0VmFsaWRhdG9yRm9yUHJvdmlkZXIgPSBmdW5jdGlvbiAocHJvdmlkZXIpIHtcbiAgICBpZiAocHJvdmlkZXIgPT09ICdhbm9ueW1vdXMnICYmICFfZW5hYmxlQW5vbnltb3VzVXNlcnMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB7IGFkYXB0ZXIsIGFwcElkcywgcHJvdmlkZXJPcHRpb25zIH0gPSBsb2FkQXV0aEFkYXB0ZXIocHJvdmlkZXIsIGF1dGhPcHRpb25zKTtcblxuICAgIHJldHVybiBhdXRoRGF0YVZhbGlkYXRvcihhZGFwdGVyLCBhcHBJZHMsIHByb3ZpZGVyT3B0aW9ucyk7XG4gIH07XG5cbiAgcmV0dXJuIE9iamVjdC5mcmVlemUoe1xuICAgIGdldFZhbGlkYXRvckZvclByb3ZpZGVyLFxuICAgIHNldEVuYWJsZUFub255bW91c1VzZXJzLFxuICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzLmxvYWRBdXRoQWRhcHRlciA9IGxvYWRBdXRoQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/instagram.js b/lib/Adapters/Auth/instagram.js deleted file mode 100644 index a6a888efb5..0000000000 --- a/lib/Adapters/Auth/instagram.js +++ /dev/null @@ -1,31 +0,0 @@ -"use strict"; - -// Helper functions for accessing the instagram API. -var Parse = require('parse/node').Parse; - -const httpsRequest = require('./httpsRequest'); - -const defaultURL = 'https://graph.instagram.com/'; // Returns a promise that fulfills if this user id is valid. - -function validateAuthData(authData) { - const apiURL = authData.apiURL || defaultURL; - const path = `${apiURL}me?fields=id&access_token=${authData.access_token}`; - return httpsRequest.get(path).then(response => { - if (response && response.data && response.data.id == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Instagram auth is invalid for this user.'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} - -module.exports = { - validateAppId, - validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2luc3RhZ3JhbS5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJkZWZhdWx0VVJMIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwiYXBpVVJMIiwicGF0aCIsImFjY2Vzc190b2tlbiIsImdldCIsInRoZW4iLCJyZXNwb25zZSIsImRhdGEiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQSxJQUFJQSxLQUFLLEdBQUdDLE9BQU8sQ0FBQyxZQUFELENBQVAsQ0FBc0JELEtBQWxDOztBQUNBLE1BQU1FLFlBQVksR0FBR0QsT0FBTyxDQUFDLGdCQUFELENBQTVCOztBQUNBLE1BQU1FLFVBQVUsR0FBRyw4QkFBbkIsQyxDQUVBOztBQUNBLFNBQVNDLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxRQUFNQyxNQUFNLEdBQUdELFFBQVEsQ0FBQ0MsTUFBVCxJQUFtQkgsVUFBbEM7QUFDQSxRQUFNSSxJQUFJLEdBQUksR0FBRUQsTUFBTyw2QkFBNEJELFFBQVEsQ0FBQ0csWUFBYSxFQUF6RTtBQUNBLFNBQU9OLFlBQVksQ0FBQ08sR0FBYixDQUFpQkYsSUFBakIsRUFBdUJHLElBQXZCLENBQTRCQyxRQUFRLElBQUk7QUFDN0MsUUFBSUEsUUFBUSxJQUFJQSxRQUFRLENBQUNDLElBQXJCLElBQTZCRCxRQUFRLENBQUNDLElBQVQsQ0FBY0MsRUFBZCxJQUFvQlIsUUFBUSxDQUFDUSxFQUE5RCxFQUFrRTtBQUNoRTtBQUNEOztBQUNELFVBQU0sSUFBSWIsS0FBSyxDQUFDYyxLQUFWLENBQWdCZCxLQUFLLENBQUNjLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLDBDQUE5QyxDQUFOO0FBQ0QsR0FMTSxDQUFQO0FBTUQsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0Q7O0FBRURDLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmSixFQUFBQSxhQURlO0FBRWZaLEVBQUFBO0FBRmUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIGluc3RhZ3JhbSBBUEkuXG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuY29uc3QgZGVmYXVsdFVSTCA9ICdodHRwczovL2dyYXBoLmluc3RhZ3JhbS5jb20vJztcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG4gIGNvbnN0IGFwaVVSTCA9IGF1dGhEYXRhLmFwaVVSTCB8fCBkZWZhdWx0VVJMO1xuICBjb25zdCBwYXRoID0gYCR7YXBpVVJMfW1lP2ZpZWxkcz1pZCZhY2Nlc3NfdG9rZW49JHthdXRoRGF0YS5hY2Nlc3NfdG9rZW59YDtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQocGF0aCkudGhlbihyZXNwb25zZSA9PiB7XG4gICAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLmRhdGEgJiYgcmVzcG9uc2UuZGF0YS5pZCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0luc3RhZ3JhbSBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nKTtcbiAgfSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/janraincapture.js b/lib/Adapters/Auth/janraincapture.js deleted file mode 100644 index 7ac024882f..0000000000 --- a/lib/Adapters/Auth/janraincapture.js +++ /dev/null @@ -1,46 +0,0 @@ -"use strict"; - -// Helper functions for accessing the Janrain Capture API. -var Parse = require('parse/node').Parse; - -var querystring = require('querystring'); - -const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData, options) { - return request(options.janrain_capture_host, authData.access_token).then(data => { - //successful response will have a "stat" (status) of 'ok' and a result node that stores the uuid, because that's all we asked for - //see: https://docs.janrain.com/api/registration/entity/#entity - if (data && data.stat == 'ok' && data.result == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Janrain capture auth is invalid for this user.'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId() { - //no-op - return Promise.resolve(); -} // A promisey wrapper for api requests - - -function request(host, access_token) { - var query_string_data = querystring.stringify({ - access_token: access_token, - attribute_name: 'uuid' // we only need to pull the uuid for this access token to make sure it matches - - }); - return httpsRequest.get({ - host: host, - path: '/entity?' + query_string_data - }); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2phbnJhaW5jYXB0dXJlLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsInF1ZXJ5c3RyaW5nIiwiaHR0cHNSZXF1ZXN0IiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsInJlcXVlc3QiLCJqYW5yYWluX2NhcHR1cmVfaG9zdCIsImFjY2Vzc190b2tlbiIsInRoZW4iLCJkYXRhIiwic3RhdCIsInJlc3VsdCIsImlkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsIlByb21pc2UiLCJyZXNvbHZlIiwiaG9zdCIsInF1ZXJ5X3N0cmluZ19kYXRhIiwic3RyaW5naWZ5IiwiYXR0cmlidXRlX25hbWUiLCJnZXQiLCJwYXRoIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBbEM7O0FBQ0EsSUFBSUUsV0FBVyxHQUFHRCxPQUFPLENBQUMsYUFBRCxDQUF6Qjs7QUFDQSxNQUFNRSxZQUFZLEdBQUdGLE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNHLGdCQUFULENBQTBCQyxRQUExQixFQUFvQ0MsT0FBcEMsRUFBNkM7QUFDM0MsU0FBT0MsT0FBTyxDQUFDRCxPQUFPLENBQUNFLG9CQUFULEVBQStCSCxRQUFRLENBQUNJLFlBQXhDLENBQVAsQ0FBNkRDLElBQTdELENBQWtFQyxJQUFJLElBQUk7QUFDL0U7QUFDQTtBQUNBLFFBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxJQUFMLElBQWEsSUFBckIsSUFBNkJELElBQUksQ0FBQ0UsTUFBTCxJQUFlUixRQUFRLENBQUNTLEVBQXpELEVBQTZEO0FBQzNEO0FBQ0Q7O0FBQ0QsVUFBTSxJQUFJZCxLQUFLLENBQUNlLEtBQVYsQ0FDSmYsS0FBSyxDQUFDZSxLQUFOLENBQVlDLGdCQURSLEVBRUosZ0RBRkksQ0FBTjtBQUlELEdBVk0sQ0FBUDtBQVdELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QjtBQUNBLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTWixPQUFULENBQWlCYSxJQUFqQixFQUF1QlgsWUFBdkIsRUFBcUM7QUFDbkMsTUFBSVksaUJBQWlCLEdBQUduQixXQUFXLENBQUNvQixTQUFaLENBQXNCO0FBQzVDYixJQUFBQSxZQUFZLEVBQUVBLFlBRDhCO0FBRTVDYyxJQUFBQSxjQUFjLEVBQUUsTUFGNEIsQ0FFcEI7O0FBRm9CLEdBQXRCLENBQXhCO0FBS0EsU0FBT3BCLFlBQVksQ0FBQ3FCLEdBQWIsQ0FBaUI7QUFBRUosSUFBQUEsSUFBSSxFQUFFQSxJQUFSO0FBQWNLLElBQUFBLElBQUksRUFBRSxhQUFhSjtBQUFqQyxHQUFqQixDQUFQO0FBQ0Q7O0FBRURLLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVixFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZmIsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIEphbnJhaW4gQ2FwdHVyZSBBUEkuXG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG52YXIgcXVlcnlzdHJpbmcgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpO1xuY29uc3QgaHR0cHNSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwc1JlcXVlc3QnKTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyB1c2VyIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSwgb3B0aW9ucykge1xuICByZXR1cm4gcmVxdWVzdChvcHRpb25zLmphbnJhaW5fY2FwdHVyZV9ob3N0LCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oZGF0YSA9PiB7XG4gICAgLy9zdWNjZXNzZnVsIHJlc3BvbnNlIHdpbGwgaGF2ZSBhIFwic3RhdFwiIChzdGF0dXMpIG9mICdvaycgYW5kIGEgcmVzdWx0IG5vZGUgdGhhdCBzdG9yZXMgdGhlIHV1aWQsIGJlY2F1c2UgdGhhdCdzIGFsbCB3ZSBhc2tlZCBmb3JcbiAgICAvL3NlZTogaHR0cHM6Ly9kb2NzLmphbnJhaW4uY29tL2FwaS9yZWdpc3RyYXRpb24vZW50aXR5LyNlbnRpdHlcbiAgICBpZiAoZGF0YSAmJiBkYXRhLnN0YXQgPT0gJ29rJyAmJiBkYXRhLnJlc3VsdCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ0phbnJhaW4gY2FwdHVyZSBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nXG4gICAgKTtcbiAgfSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgLy9uby1vcFxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbi8vIEEgcHJvbWlzZXkgd3JhcHBlciBmb3IgYXBpIHJlcXVlc3RzXG5mdW5jdGlvbiByZXF1ZXN0KGhvc3QsIGFjY2Vzc190b2tlbikge1xuICB2YXIgcXVlcnlfc3RyaW5nX2RhdGEgPSBxdWVyeXN0cmluZy5zdHJpbmdpZnkoe1xuICAgIGFjY2Vzc190b2tlbjogYWNjZXNzX3Rva2VuLFxuICAgIGF0dHJpYnV0ZV9uYW1lOiAndXVpZCcsIC8vIHdlIG9ubHkgbmVlZCB0byBwdWxsIHRoZSB1dWlkIGZvciB0aGlzIGFjY2VzcyB0b2tlbiB0byBtYWtlIHN1cmUgaXQgbWF0Y2hlc1xuICB9KTtcblxuICByZXR1cm4gaHR0cHNSZXF1ZXN0LmdldCh7IGhvc3Q6IGhvc3QsIHBhdGg6ICcvZW50aXR5PycgKyBxdWVyeV9zdHJpbmdfZGF0YSB9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQ6IHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGE6IHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/janrainengage.js b/lib/Adapters/Auth/janrainengage.js deleted file mode 100644 index d7c4774377..0000000000 --- a/lib/Adapters/Auth/janrainengage.js +++ /dev/null @@ -1,52 +0,0 @@ -"use strict"; - -// Helper functions for accessing the Janrain Engage API. -var httpsRequest = require('./httpsRequest'); - -var Parse = require('parse/node').Parse; - -var querystring = require('querystring'); // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData, options) { - return apiRequest(options.api_key, authData.auth_token).then(data => { - //successful response will have a "stat" (status) of 'ok' and a profile node with an identifier - //see: http://developers.janrain.com/overview/social-login/identity-providers/user-profile-data/#normalized-user-profile-data - if (data && data.stat == 'ok' && data.profile.identifier == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Janrain engage auth is invalid for this user.'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId() { - //no-op - return Promise.resolve(); -} // A promisey wrapper for api requests - - -function apiRequest(api_key, auth_token) { - var post_data = querystring.stringify({ - token: auth_token, - apiKey: api_key, - format: 'json' - }); - var post_options = { - host: 'rpxnow.com', - path: '/api/v2/auth_info', - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Content-Length': post_data.length - } - }; - return httpsRequest.request(post_options, post_data); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2phbnJhaW5lbmdhZ2UuanMiXSwibmFtZXMiOlsiaHR0cHNSZXF1ZXN0IiwicmVxdWlyZSIsIlBhcnNlIiwicXVlcnlzdHJpbmciLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJvcHRpb25zIiwiYXBpUmVxdWVzdCIsImFwaV9rZXkiLCJhdXRoX3Rva2VuIiwidGhlbiIsImRhdGEiLCJzdGF0IiwicHJvZmlsZSIsImlkZW50aWZpZXIiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBvc3RfZGF0YSIsInN0cmluZ2lmeSIsInRva2VuIiwiYXBpS2V5IiwiZm9ybWF0IiwicG9zdF9vcHRpb25zIiwiaG9zdCIsInBhdGgiLCJtZXRob2QiLCJoZWFkZXJzIiwibGVuZ3RoIiwicmVxdWVzdCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQSxJQUFJQSxZQUFZLEdBQUdDLE9BQU8sQ0FBQyxnQkFBRCxDQUExQjs7QUFDQSxJQUFJQyxLQUFLLEdBQUdELE9BQU8sQ0FBQyxZQUFELENBQVAsQ0FBc0JDLEtBQWxDOztBQUNBLElBQUlDLFdBQVcsR0FBR0YsT0FBTyxDQUFDLGFBQUQsQ0FBekIsQyxDQUVBOzs7QUFDQSxTQUFTRyxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0NDLE9BQXBDLEVBQTZDO0FBQzNDLFNBQU9DLFVBQVUsQ0FBQ0QsT0FBTyxDQUFDRSxPQUFULEVBQWtCSCxRQUFRLENBQUNJLFVBQTNCLENBQVYsQ0FBaURDLElBQWpELENBQXNEQyxJQUFJLElBQUk7QUFDbkU7QUFDQTtBQUNBLFFBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxJQUFMLElBQWEsSUFBckIsSUFBNkJELElBQUksQ0FBQ0UsT0FBTCxDQUFhQyxVQUFiLElBQTJCVCxRQUFRLENBQUNVLEVBQXJFLEVBQXlFO0FBQ3ZFO0FBQ0Q7O0FBQ0QsVUFBTSxJQUFJYixLQUFLLENBQUNjLEtBQVYsQ0FDSmQsS0FBSyxDQUFDYyxLQUFOLENBQVlDLGdCQURSLEVBRUosK0NBRkksQ0FBTjtBQUlELEdBVk0sQ0FBUDtBQVdELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QjtBQUNBLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTYixVQUFULENBQW9CQyxPQUFwQixFQUE2QkMsVUFBN0IsRUFBeUM7QUFDdkMsTUFBSVksU0FBUyxHQUFHbEIsV0FBVyxDQUFDbUIsU0FBWixDQUFzQjtBQUNwQ0MsSUFBQUEsS0FBSyxFQUFFZCxVQUQ2QjtBQUVwQ2UsSUFBQUEsTUFBTSxFQUFFaEIsT0FGNEI7QUFHcENpQixJQUFBQSxNQUFNLEVBQUU7QUFINEIsR0FBdEIsQ0FBaEI7QUFNQSxNQUFJQyxZQUFZLEdBQUc7QUFDakJDLElBQUFBLElBQUksRUFBRSxZQURXO0FBRWpCQyxJQUFBQSxJQUFJLEVBQUUsbUJBRlc7QUFHakJDLElBQUFBLE1BQU0sRUFBRSxNQUhTO0FBSWpCQyxJQUFBQSxPQUFPLEVBQUU7QUFDUCxzQkFBZ0IsbUNBRFQ7QUFFUCx3QkFBa0JULFNBQVMsQ0FBQ1U7QUFGckI7QUFKUSxHQUFuQjtBQVVBLFNBQU8vQixZQUFZLENBQUNnQyxPQUFiLENBQXFCTixZQUFyQixFQUFtQ0wsU0FBbkMsQ0FBUDtBQUNEOztBQUVEWSxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZmhCLEVBQUFBLGFBQWEsRUFBRUEsYUFEQTtBQUVmZCxFQUFBQSxnQkFBZ0IsRUFBRUE7QUFGSCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgSmFucmFpbiBFbmdhZ2UgQVBJLlxudmFyIGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG52YXIgcXVlcnlzdHJpbmcgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhLCBvcHRpb25zKSB7XG4gIHJldHVybiBhcGlSZXF1ZXN0KG9wdGlvbnMuYXBpX2tleSwgYXV0aERhdGEuYXV0aF90b2tlbikudGhlbihkYXRhID0+IHtcbiAgICAvL3N1Y2Nlc3NmdWwgcmVzcG9uc2Ugd2lsbCBoYXZlIGEgXCJzdGF0XCIgKHN0YXR1cykgb2YgJ29rJyBhbmQgYSBwcm9maWxlIG5vZGUgd2l0aCBhbiBpZGVudGlmaWVyXG4gICAgLy9zZWU6IGh0dHA6Ly9kZXZlbG9wZXJzLmphbnJhaW4uY29tL292ZXJ2aWV3L3NvY2lhbC1sb2dpbi9pZGVudGl0eS1wcm92aWRlcnMvdXNlci1wcm9maWxlLWRhdGEvI25vcm1hbGl6ZWQtdXNlci1wcm9maWxlLWRhdGFcbiAgICBpZiAoZGF0YSAmJiBkYXRhLnN0YXQgPT0gJ29rJyAmJiBkYXRhLnByb2ZpbGUuaWRlbnRpZmllciA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgJ0phbnJhaW4gZW5nYWdlIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICApO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICAvL25vLW9wXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBhcGkgcmVxdWVzdHNcbmZ1bmN0aW9uIGFwaVJlcXVlc3QoYXBpX2tleSwgYXV0aF90b2tlbikge1xuICB2YXIgcG9zdF9kYXRhID0gcXVlcnlzdHJpbmcuc3RyaW5naWZ5KHtcbiAgICB0b2tlbjogYXV0aF90b2tlbixcbiAgICBhcGlLZXk6IGFwaV9rZXksXG4gICAgZm9ybWF0OiAnanNvbicsXG4gIH0pO1xuXG4gIHZhciBwb3N0X29wdGlvbnMgPSB7XG4gICAgaG9zdDogJ3JweG5vdy5jb20nLFxuICAgIHBhdGg6ICcvYXBpL3YyL2F1dGhfaW5mbycsXG4gICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgaGVhZGVyczoge1xuICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAgICAgJ0NvbnRlbnQtTGVuZ3RoJzogcG9zdF9kYXRhLmxlbmd0aCxcbiAgICB9LFxuICB9O1xuXG4gIHJldHVybiBodHRwc1JlcXVlc3QucmVxdWVzdChwb3N0X29wdGlvbnMsIHBvc3RfZGF0YSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/keycloak.js b/lib/Adapters/Auth/keycloak.js deleted file mode 100644 index 6f022c8e9c..0000000000 --- a/lib/Adapters/Auth/keycloak.js +++ /dev/null @@ -1,125 +0,0 @@ -"use strict"; - -/* - # Parse Server Keycloak Authentication - - ## Keycloak `authData` - - ``` - { - "keycloak": { - "access_token": "access token you got from keycloak JS client authentication", - "id": "the id retrieved from client authentication in Keycloak", - "roles": ["the roles retrieved from client authentication in Keycloak"], - "groups": ["the groups retrieved from client authentication in Keycloak"] - } - } - ``` - - The authentication module will test if the authData is the same as the - userinfo oauth call, comparing the attributes - - Copy the JSON config file generated on Keycloak (https://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter) - and paste it inside of a folder (Ex.: `auth/keycloak.json`) in your server. - - The options passed to Parse server: - - ``` - { - auth: { - keycloak: { - config: require(`./auth/keycloak.json`) - } - } - } - ``` -*/ -const { - Parse -} = require('parse/node'); - -const httpsRequest = require('./httpsRequest'); - -const arraysEqual = (_arr1, _arr2) => { - if (!Array.isArray(_arr1) || !Array.isArray(_arr2) || _arr1.length !== _arr2.length) return false; - - var arr1 = _arr1.concat().sort(); - - var arr2 = _arr2.concat().sort(); - - for (var i = 0; i < arr1.length; i++) { - if (arr1[i] !== arr2[i]) return false; - } - - return true; -}; - -const handleAuth = async ({ - access_token, - id, - roles, - groups -} = {}, { - config -} = {}) => { - if (!(access_token && id)) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Missing access token and/or User id'); - } - - if (!config || !(config['auth-server-url'] && config['realm'])) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Missing keycloak configuration'); - } - - try { - const response = await httpsRequest.get({ - host: config['auth-server-url'], - path: `/realms/${config['realm']}/protocol/openid-connect/userinfo`, - headers: { - Authorization: 'Bearer ' + access_token - } - }); - - if (response && response.data && response.data.sub == id && arraysEqual(response.data.roles, roles) && arraysEqual(response.data.groups, groups)) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid authentication'); - } catch (e) { - if (e instanceof Parse.Error) { - throw e; - } - - const error = JSON.parse(e.text); - - if (error.error_description) { - throw new Parse.Error(Parse.Error.HOSTING_ERROR, error.error_description); - } else { - throw new Parse.Error(Parse.Error.HOSTING_ERROR, 'Could not connect to the authentication server'); - } - } -}; -/* - @param {Object} authData: the client provided authData - @param {string} authData.access_token: the access_token retrieved from client authentication in Keycloak - @param {string} authData.id: the id retrieved from client authentication in Keycloak - @param {Array} authData.roles: the roles retrieved from client authentication in Keycloak - @param {Array} authData.groups: the groups retrieved from client authentication in Keycloak - @param {Object} options: additional options - @param {Object} options.config: the config object passed during Parse Server instantiation -*/ - - -function validateAuthData(authData, options = {}) { - return handleAuth(authData, options); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} - -module.exports = { - validateAppId, - validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2tleWNsb2FrLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsImh0dHBzUmVxdWVzdCIsImFycmF5c0VxdWFsIiwiX2FycjEiLCJfYXJyMiIsIkFycmF5IiwiaXNBcnJheSIsImxlbmd0aCIsImFycjEiLCJjb25jYXQiLCJzb3J0IiwiYXJyMiIsImkiLCJoYW5kbGVBdXRoIiwiYWNjZXNzX3Rva2VuIiwiaWQiLCJyb2xlcyIsImdyb3VwcyIsImNvbmZpZyIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInJlc3BvbnNlIiwiZ2V0IiwiaG9zdCIsInBhdGgiLCJoZWFkZXJzIiwiQXV0aG9yaXphdGlvbiIsImRhdGEiLCJzdWIiLCJlIiwiZXJyb3IiLCJKU09OIiwicGFyc2UiLCJ0ZXh0IiwiZXJyb3JfZGVzY3JpcHRpb24iLCJIT1NUSU5HX0VSUk9SIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFFQSxNQUFNO0FBQUVBLEVBQUFBO0FBQUYsSUFBWUMsT0FBTyxDQUFDLFlBQUQsQ0FBekI7O0FBQ0EsTUFBTUMsWUFBWSxHQUFHRCxPQUFPLENBQUMsZ0JBQUQsQ0FBNUI7O0FBRUEsTUFBTUUsV0FBVyxHQUFHLENBQUNDLEtBQUQsRUFBUUMsS0FBUixLQUFrQjtBQUNwQyxNQUFJLENBQUNDLEtBQUssQ0FBQ0MsT0FBTixDQUFjSCxLQUFkLENB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QUssQ0FBQ29CLEtBQVYsQ0FDSnBCLEtBQUssQ0FBQ29CLEtBQU4sQ0FBWWdCLGFBRFIsRUFFSixnREFGSSxDQUFOO0FBSUQ7QUFDRjtBQUNGLENBdkNEO0FBeUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0EsU0FBU0MsZ0JBQVQsQ0FBMEJDLFFBQTFCLEVBQW9DQyxPQUFPLEdBQUcsRUFBOUMsRUFBa0Q7QUFDaEQsU0FBT3pCLFVBQVUsQ0FBQ3dCLFFBQUQsRUFBV0MsT0FBWCxDQUFqQjtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVEQyxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZkosRUFBQUEsYUFEZTtBQUVmSCxFQUFBQTtBQUZlLENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAgIyBQYXJzZSBTZXJ2ZXIgS2V5Y2xvYWsgQXV0aGVudGljYXRpb25cblxuICAjIyBLZXljbG9hayBgYXV0aERhdGFgXG5cbiAgYGBgXG4gICAge1xuICAgICAgXCJrZXljbG9ha1wiOiB7XG4gICAgICAgIFwiYWNjZXNzX3Rva2VuXCI6IFwiYWNjZXNzIHRva2VuIHlvdSBnb3QgZnJvbSBrZXljbG9hayBKUyBjbGllbnQgYXV0aGVudGljYXRpb25cIixcbiAgICAgICAgXCJpZFwiOiBcInRoZSBpZCByZXRyaWV2ZWQgZnJvbSBjbGllbnQgYXV0aGVudGljYXRpb24gaW4gS2V5Y2xvYWtcIixcbiAgICAgICAgXCJyb2xlc1wiOiBbXCJ0aGUgcm9sZXMgcmV0cmlldmVkIGZyb20gY2xpZW50IGF1dGhlbnRpY2F0aW9uIGluIEtleWNsb2FrXCJdLFxuICAgICAgICBcImdyb3Vwc1wiOiBbXCJ0aGUgZ3JvdXBzIHJldHJpZXZlZCBmcm9tIGNsaWVudCBhdXRoZW50aWNhdGlvbiBpbiBLZXljbG9ha1wiXVxuICAgICAgfVxuICAgIH1cbiAgYGBgXG5cbiAgVGhlIGF1dGhlbnRpY2F0aW9uIG1vZHVsZSB3aWxsIHRlc3QgaWYgdGhlIGF1dGhEYXRhIGlzIHRoZSBzYW1lIGFzIHRoZVxuICB1c2VyaW5mbyBvYXV0aCBjYWxsLCBjb21wYXJpbmcgdGhlIGF0dHJpYnV0ZXNcblxuICBDb3B5IHRoZSBKU09OIGNvbmZpZyBmaWxlIGdlbmVyYXRlZCBvbiBLZXljbG9hayAoaHR0cHM6Ly93d3cua2V5Y2xvYWsub3JnL2RvY3MvbGF0ZXN0L3NlY3VyaW5nX2FwcHMvaW5kZXguaHRtbCNfamF2YXNjcmlwdF9hZGFwdGVyKVxuICBhbmQgcGFzdGUgaXQgaW5zaWRlIG9mIGEgZm9sZGVyIChFeC46IGBhdXRoL2tleWNsb2FrLmpzb25gKSBpbiB5b3VyIHNlcnZlci5cblxuICBUaGUgb3B0aW9ucyBwYXNzZWQgdG8gUGFyc2Ugc2VydmVyOlxuXG4gIGBgYFxuICAgIHtcbiAgICAgIGF1dGg6IHtcbiAgICAgICAga2V5Y2xvYWs6IHtcbiAgICAgICAgICBjb25maWc6IHJlcXVpcmUoYC4vYXV0aC9rZXljbG9hay5qc29uYClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgYGBgXG4qL1xuXG5jb25zdCB7IFBhcnNlIH0gPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG5jb25zdCBhcnJheXNFcXVhbCA9IChfYXJyMSwgX2FycjIpID0+IHtcbiAgaWYgKCFBcnJheS5pc0FycmF5KF9hcnIxKSB8fCAhQXJyYXkuaXNBcnJheShfYXJyMikgfHwgX2FycjEubGVuZ3RoICE9PSBfYXJyMi5sZW5ndGgpIHJldHVybiBmYWxzZTtcblxuICB2YXIgYXJyMSA9IF9hcnIxLmNvbmNhdCgpLnNvcnQoKTtcbiAgdmFyIGFycjIgPSBfYXJyMi5jb25jYXQoKS5zb3J0KCk7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIxLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGFycjFbaV0gIT09IGFycjJbaV0pIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuY29uc3QgaGFuZGxlQXV0aCA9IGFzeW5jICh7IGFjY2Vzc190b2tlbiwgaWQsIHJvbGVzLCBncm91cHMgfSA9IHt9LCB7IGNvbmZpZyB9ID0ge30pID0+IHtcbiAgaWYgKCEoYWNjZXNzX3Rva2VuICYmIGlkKSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnTWlzc2luZyBhY2Nlc3MgdG9rZW4gYW5kL29yIFVzZXIgaWQnKTtcbiAgfVxuICBpZiAoIWNvbmZpZyB8fCAhKGNvbmZpZ1snYXV0aC1zZXJ2ZXItdXJsJ10gJiYgY29uZmlnWydyZWFsbSddKSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnTWlzc2luZyBrZXljbG9hayBjb25maWd1cmF0aW9uJyk7XG4gIH1cbiAgdHJ5IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGh0dHBzUmVxdWVzdC5nZXQoe1xuICAgICAgaG9zdDogY29uZmlnWydhdXRoLXNlcnZlci11cmwnXSxcbiAgICAgIHBhdGg6IGAvcmVhbG1zLyR7Y29uZmlnWydyZWFsbSddfS9wcm90b2NvbC9vcGVuaWQtY29ubmVjdC91c2VyaW5mb2AsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgIEF1dGhvcml6YXRpb246ICdCZWFyZXIgJyArIGFjY2Vzc190b2tlbixcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgaWYgKFxuICAgICAgcmVzcG9uc2UgJiZcbiAgICAgIHJlc3BvbnNlLmRhdGEgJiZcbiAgICAgIHJlc3BvbnNlLmRhdGEuc3ViID09IGlkICYmXG4gICAgICBhcnJheXNFcXVhbChyZXNwb25zZS5kYXRhLnJvbGVzLCByb2xlcykgJiZcbiAgICAgIGFycmF5c0VxdWFsKHJlc3BvbnNlLmRhdGEuZ3JvdXBzLCBncm91cHMpXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnSW52YWxpZCBhdXRoZW50aWNhdGlvbicpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKGUgaW5zdGFuY2VvZiBQYXJzZS5FcnJvcikge1xuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gICAgY29uc3QgZXJyb3IgPSBKU09OLnBhcnNlKGUudGV4dCk7XG4gICAgaWYgKGVycm9yLmVycm9yX2Rlc2NyaXB0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSE9TVElOR19FUlJPUiwgZXJyb3IuZXJyb3JfZGVzY3JpcHRpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLkhPU1RJTkdfRVJST1IsXG4gICAgICAgICdDb3VsZCBub3QgY29ubmVjdCB0byB0aGUgYXV0aGVudGljYXRpb24gc2VydmVyJ1xuICAgICAgKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qXG4gIEBwYXJhbSB7T2JqZWN0fSBhdXRoRGF0YTogdGhlIGNsaWVudCBwcm92aWRlZCBhdXRoRGF0YVxuICBAcGFyYW0ge3N0cmluZ30gYXV0aERhdGEuYWNjZXNzX3Rva2VuOiB0aGUgYWNjZXNzX3Rva2VuIHJldHJpZXZlZCBmcm9tIGNsaWVudCBhdXRoZW50aWNhdGlvbiBpbiBLZXljbG9ha1xuICBAcGFyYW0ge3N0cmluZ30gYXV0aERhdGEuaWQ6IHRoZSBpZCByZXRyaWV2ZWQgZnJvbSBjbGllbnQgYXV0aGVudGljYXRpb24gaW4gS2V5Y2xvYWtcbiAgQHBhcmFtIHtBcnJheX0gIGF1dGhEYXRhLnJvbGVzOiB0aGUgcm9sZXMgcmV0cmlldmVkIGZyb20gY2xpZW50IGF1dGhlbnRpY2F0aW9uIGluIEtleWNsb2FrXG4gIEBwYXJhbSB7QXJyYXl9ICBhdXRoRGF0YS5ncm91cHM6IHRoZSBncm91cHMgcmV0cmlldmVkIGZyb20gY2xpZW50IGF1dGhlbnRpY2F0aW9uIGluIEtleWNsb2FrXG4gIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zOiBhZGRpdGlvbmFsIG9wdGlvbnNcbiAgQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMuY29uZmlnOiB0aGUgY29uZmlnIG9iamVjdCBwYXNzZWQgZHVyaW5nIFBhcnNlIFNlcnZlciBpbnN0YW50aWF0aW9uXG4qL1xuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSwgb3B0aW9ucyA9IHt9KSB7XG4gIHJldHVybiBoYW5kbGVBdXRoKGF1dGhEYXRhLCBvcHRpb25zKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/ldap.js b/lib/Adapters/Auth/ldap.js deleted file mode 100644 index ac2f99257d..0000000000 --- a/lib/Adapters/Auth/ldap.js +++ /dev/null @@ -1,105 +0,0 @@ -"use strict"; - -const ldapjs = require('ldapjs'); - -const Parse = require('parse/node').Parse; - -function validateAuthData(authData, options) { - if (!optionsAreValid(options)) { - return new Promise((_, reject) => { - reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP auth configuration missing')); - }); - } - - const clientOptions = options.url.startsWith('ldaps://') ? { - url: options.url, - tlsOptions: options.tlsOptions - } : { - url: options.url - }; - const client = ldapjs.createClient(clientOptions); - const userCn = typeof options.dn === 'string' ? options.dn.replace('{{id}}', authData.id) : `uid=${authData.id},${options.suffix}`; - return new Promise((resolve, reject) => { - client.bind(userCn, authData.password, ldapError => { - delete authData.password; - - if (ldapError) { - let error; - - switch (ldapError.code) { - case 49: - error = new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'LDAP: Wrong username or password'); - break; - - case 'DEPTH_ZERO_SELF_SIGNED_CERT': - error = new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'LDAPS: Certificate mismatch'); - break; - - default: - error = new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'LDAP: Somthing went wrong (' + ldapError.code + ')'); - } - - reject(error); - client.destroy(ldapError); - return; - } - - if (typeof options.groupCn === 'string' && typeof options.groupFilter === 'string') { - searchForGroup(client, options, authData.id, resolve, reject); - } else { - client.unbind(); - client.destroy(); - resolve(); - } - }); - }); -} - -function optionsAreValid(options) { - return typeof options === 'object' && typeof options.suffix === 'string' && typeof options.url === 'string' && (options.url.startsWith('ldap://') || options.url.startsWith('ldaps://') && typeof options.tlsOptions === 'object'); -} - -function searchForGroup(client, options, id, resolve, reject) { - const filter = options.groupFilter.replace(/{{id}}/gi, id); - const opts = { - scope: 'sub', - filter: filter - }; - let found = false; - client.search(options.suffix, opts, (searchError, res) => { - if (searchError) { - client.unbind(); - client.destroy(); - return reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP group search failed')); - } - - res.on('searchEntry', entry => { - if (entry.object.cn === options.groupCn) { - found = true; - client.unbind(); - client.destroy(); - return resolve(); - } - }); - res.on('end', () => { - if (!found) { - client.unbind(); - client.destroy(); - return reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP: User not in group')); - } - }); - res.on('error', () => { - return reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP group search failed')); - }); - }); -} - -function validateAppId() { - return Promise.resolve(); -} - -module.exports = { - validateAppId, - validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2xkYXAuanMiXSwibmFtZXMiOlsibGRhcGpzIiwicmVxdWlyZSIsIlBhcnNlIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsIm9wdGlvbnNBcmVWYWxpZCIsIlByb21pc2UiLCJfIiwicmVqZWN0IiwiRXJyb3IiLCJJTlRFUk5BTF9TRVJWRVJfRVJST1IiLCJjbGllbnRPcHRpb25zIiwidXJsIiwic3RhcnRzV2l0aCIsInRsc09wdGlvbnMiLCJjbGllbnQiLCJjcmVhdGVDbGllbnQiLCJ1c2VyQ24iLCJkbiIsInJlcGxhY2UiLCJpZCIsInN1ZmZpeCIsInJlc29sdmUiLCJiaW5kIiwicGFzc3dvcmQiLCJsZGFwRXJyb3IiLCJlcnJvciIsImNvZGUiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiZGVzdHJveSIsImdyb3VwQ24iLCJncm91cEZpbHRlciIsInNlYXJjaEZvckdyb3VwIiwidW5iaW5kIiwiZmlsdGVyIiwib3B0cyIsInNjb3BlIiwiZm91bmQiLCJzZWFyY2giLCJzZWFyY2hFcnJvciIsInJlcyIsIm9uIiwiZW50cnkiLCJvYmplY3QiLCJjbiIsInZhbGlkYXRlQXBwSWQiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLE1BQU1BLE1BQU0sR0FBR0MsT0FBTyxDQUFDLFFBQUQsQ0FBdEI7O0FBQ0EsTUFBTUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCQyxLQUFwQzs7QUFFQSxTQUFTQyxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0NDLE9BQXBDLEVBQTZDO0FBQzNDLE1BQUksQ0FBQ0MsZUFBZSxDQUFDRCxPQUFELENBQXBCLEVBQStCO0FBQzdCLFdBQU8sSUFBSUUsT0FBSixDQUFZLENBQUNDLENBQUQsRUFBSUMsTUFBSixLQUFlO0FBQ2hDQSxNQUFBQSxNQUFNLENBQUMsSUFBSVAsS0FBSyxDQUFDUSxLQUFWLENBQWdCUixLQUFLLENB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TTtBQUNsQixVQUFJLENBQUNKLEtBQUwsRUFBWTtBQUNWdEIsUUFBQUEsTUFBTSxDQUFDa0IsTUFBUDtBQUNBbEIsUUFBQUEsTUFBTSxDQUFDYyxPQUFQO0FBQ0EsZUFBT3JCLE1BQU0sQ0FDWCxJQUFJUCxLQUFLLENBQUNRLEtBQVYsQ0FBZ0JSLEtBQUssQ0FBQ1EsS0FBTixDQUFZQyxxQkFBNUIsRUFBbUQseUJBQW5ELENBRFcsQ0FBYjtBQUdEO0FBQ0YsS0FSRDtBQVNBOEIsSUFBQUEsR0FBRyxDQUFDQyxFQUFKLENBQU8sT0FBUCxFQUFnQixNQUFNO0FBQ3BCLGFBQU9qQyxNQUFNLENBQUMsSUFBSVAsS0FBSyxDQUFDUSxLQUFWLENBQWdCUixLQUFLLENBQUNRLEtBQU4sQ0FBWUMscUJBQTVCLEVBQW1ELDBCQUFuRCxDQUFELENBQWI7QUFDRCxLQUZEO0FBR0QsR0ExQkQ7QUEyQkQ7O0FBRUQsU0FBU21DLGFBQVQsR0FBeUI7QUFDdkIsU0FBT3ZDLE9BQU8sQ0FBQ2dCLE9BQVIsRUFBUDtBQUNEOztBQUVEd0IsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZGLEVBQUFBLGFBRGU7QUFFZjNDLEVBQUFBO0FBRmUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBsZGFwanMgPSByZXF1aXJlKCdsZGFwanMnKTtcbmNvbnN0IFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhLCBvcHRpb25zKSB7XG4gIGlmICghb3B0aW9uc0FyZVZhbGlkKG9wdGlvbnMpKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChfLCByZWplY3QpID0+IHtcbiAgICAgIHJlamVjdChuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLCAnTERBUCBhdXRoIGNvbmZpZ3VyYXRpb24gbWlzc2luZycpKTtcbiAgICB9KTtcbiAgfVxuICBjb25zdCBjbGllbnRPcHRpb25zID0gb3B0aW9ucy51cmwuc3RhcnRzV2l0aCgnbGRhcHM6Ly8nKVxuICAgID8geyB1cmw6IG9wdGlvbnMudXJsLCB0bHNPcHRpb25zOiBvcHRpb25zLnRsc09wdGlvbnMgfVxuICAgIDogeyB1cmw6IG9wdGlvbnMudXJsIH07XG5cbiAgY29uc3QgY2xpZW50ID0gbGRhcGpzLmNyZWF0ZUNsaWVudChjbGllbnRPcHRpb25zKTtcbiAgY29uc3QgdXNlckNuID1cbiAgICB0eXBlb2Ygb3B0aW9ucy5kbiA9PT0gJ3N0cmluZydcbiAgICAgID8gb3B0aW9ucy5kbi5yZXBsYWNlKCd7e2lkfX0nLCBhdXRoRGF0YS5pZClcbiAgICAgIDogYHVpZD0ke2F1dGhEYXRhLmlkfSwke29wdGlvbnMuc3VmZml4fWA7XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjbGllbnQuYmluZCh1c2VyQ24sIGF1dGhEYXRhLnBhc3N3b3JkLCBsZGFwRXJyb3IgPT4ge1xuICAgICAgZGVsZXRlIGF1dGhEYXRhLnBhc3N3b3JkO1xuICAgICAgaWYgKGxkYXBFcnJvcikge1xuICAgICAgICBsZXQgZXJyb3I7XG4gICAgICAgIHN3aXRjaCAobGRhcEVycm9yLmNvZGUpIHtcbiAgICAgICAgICBjYXNlIDQ5OlxuICAgICAgICAgICAgZXJyb3IgPSBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICAgICAgICdMREFQOiBXcm9uZyB1c2VybmFtZSBvciBwYXNzd29yZCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdERVBUSF9aRVJPX1NFTEZfU0lHTkVEX0NFUlQnOlxuICAgICAgICAgICAgZXJyb3IgPSBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0xEQVBTOiBDZXJ0aWZpY2F0ZSBtaXNtYXRjaCcpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGVycm9yID0gbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgICAgICAgICAnTERBUDogU29tdGhpbmcgd2VudCB3cm9uZyAoJyArIGxkYXBFcnJvci5jb2RlICsgJyknXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIGNsaWVudC5kZXN0cm95KGxkYXBFcnJvcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLmdyb3VwQ24gPT09ICdzdHJpbmcnICYmIHR5cGVvZiBvcHRpb25zLmdyb3VwRmlsdGVyID09PSAnc3RyaW5nJykge1xuICAgICAgICBzZWFyY2hGb3JHcm91cChjbGllbnQsIG9wdGlvbnMsIGF1dGhEYXRhLmlkLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2xpZW50LnVuYmluZCgpO1xuICAgICAgICBjbGllbnQuZGVzdHJveSgpO1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBvcHRpb25zQXJlVmFsaWQob3B0aW9ucykge1xuICByZXR1cm4gKFxuICAgIHR5cGVvZiBvcHRpb25zID09PSAnb2JqZWN0JyAmJlxuICAgIHR5cGVvZiBvcHRpb25zLnN1ZmZpeCA9PT0gJ3N0cmluZycgJiZcbiAgICB0eXBlb2Ygb3B0aW9ucy51cmwgPT09ICdzdHJpbmcnICYmXG4gICAgKG9wdGlvbnMudXJsLnN0YXJ0c1dpdGgoJ2xkYXA6Ly8nKSB8fFxuICAgICAgKG9wdGlvbnMudXJsLnN0YXJ0c1dpdGgoJ2xkYXBzOi8vJykgJiYgdHlwZW9mIG9wdGlvbnMudGxzT3B0aW9ucyA9PT0gJ29iamVjdCcpKVxuICApO1xufVxuXG5mdW5jdGlvbiBzZWFyY2hGb3JHcm91cChjbGllbnQsIG9wdGlvbnMsIGlkLCByZXNvbHZlLCByZWplY3QpIHtcbiAgY29uc3QgZmlsdGVyID0gb3B0aW9ucy5ncm91cEZpbHRlci5yZXBsYWNlKC97e2lkfX0vZ2ksIGlkKTtcbiAgY29uc3Qgb3B0cyA9IHtcbiAgICBzY29wZTogJ3N1YicsXG4gICAgZmlsdGVyOiBmaWx0ZXIsXG4gIH07XG4gIGxldCBmb3VuZCA9IGZhbHNlO1xuICBjbGllbnQuc2VhcmNoKG9wdGlvbnMuc3VmZml4LCBvcHRzLCAoc2VhcmNoRXJyb3IsIHJlcykgPT4ge1xuICAgIGlmIChzZWFyY2hFcnJvcikge1xuICAgICAgY2xpZW50LnVuYmluZCgpO1xuICAgICAgY2xpZW50LmRlc3Ryb3koKTtcbiAgICAgIHJldHVybiByZWplY3QobmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUiwgJ0xEQVAgZ3JvdXAgc2VhcmNoIGZhaWxlZCcpKTtcbiAgICB9XG4gICAgcmVzLm9uKCdzZWFyY2hFbnRyeScsIGVudHJ5ID0+IHtcbiAgICAgIGlmIChlbnRyeS5vYmplY3QuY24gPT09IG9wdGlvbnMuZ3JvdXBDbikge1xuICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgIGNsaWVudC51bmJpbmQoKTtcbiAgICAgICAgY2xpZW50LmRlc3Ryb3koKTtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXMub24oJ2VuZCcsICgpID0+IHtcbiAgICAgIGlmICghZm91bmQpIHtcbiAgICAgICAgY2xpZW50LnVuYmluZCgpO1xuICAgICAgICBjbGllbnQuZGVzdHJveSgpO1xuICAgICAgICByZXR1cm4gcmVqZWN0KFxuICAgICAgICAgIG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsICdMREFQOiBVc2VyIG5vdCBpbiBncm91cCcpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmVzLm9uKCdlcnJvcicsICgpID0+IHtcbiAgICAgIHJldHVybiByZWplY3QobmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUiwgJ0xEQVAgZ3JvdXAgc2VhcmNoIGZhaWxlZCcpKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/line.js b/lib/Adapters/Auth/line.js deleted file mode 100644 index 7d346a0bcf..0000000000 --- a/lib/Adapters/Auth/line.js +++ /dev/null @@ -1,41 +0,0 @@ -"use strict"; - -// Helper functions for accessing the line API. -var Parse = require('parse/node').Parse; - -const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills if this user id is valid. - - -function validateAuthData(authData) { - return request('profile', authData.access_token).then(response => { - if (response && response.userId && response.userId === authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Line auth is invalid for this user.'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for api requests - - -function request(path, access_token) { - var options = { - host: 'api.line.me', - path: '/v2/' + path, - method: 'GET', - headers: { - Authorization: 'Bearer ' + access_token - } - }; - return httpsRequest.get(options); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2xpbmUuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwiaHR0cHNSZXF1ZXN0IiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwicmVxdWVzdCIsImFjY2Vzc190b2tlbiIsInRoZW4iLCJyZXNwb25zZSIsInVzZXJJZCIsImlkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsIlByb21pc2UiLCJyZXNvbHZlIiwicGF0aCIsIm9wdGlvbnMiLCJob3N0IiwibWV0aG9kIiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJnZXQiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFDQSxNQUFNRSxZQUFZLEdBQUdELE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNFLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsU0FBRCxFQUFZRCxRQUFRLENBQUNFLFlBQXJCLENBQVAsQ0FBMENDLElBQTFDLENBQStDQyxRQUFRLElBQUk7QUFDaEUsUUFBSUEsUUFBUSxJQUFJQSxRQUFRLENBQUNDLE1BQXJCLElBQStCRCxRQUFRLENBQUNDLE1BQVQsS0FBb0JMLFFBQVEsQ0FBQ00sRUFBaEUsRUFBb0U7QUFDbEU7QUFDRDs7QUFDRCxVQUFNLElBQUlWLEtBQUssQ0FBQ1csS0FBVixDQUFnQlgsS0FBSyxDQUFDVyxLQUFOLENBQVlDLGdCQUE1QixFQUE4QyxxQ0FBOUMsQ0FBTjtBQUNELEdBTE0sQ0FBUDtBQU1ELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU1YsT0FBVCxDQUFpQlcsSUFBakIsRUFBdUJWLFlBQXZCLEVBQXFDO0FBQ25DLE1BQUlXLE9BQU8sR0FBRztBQUNaQyxJQUFBQSxJQUFJLEVBQUUsYUFETTtBQUVaRixJQUFBQSxJQUFJLEVBQUUsU0FBU0EsSUFGSDtBQUdaRyxJQUFBQSxNQUFNLEVBQUUsS0FISTtBQUlaQyxJQUFBQSxPQUFPLEVBQUU7QUFDUEMsTUFBQUEsYUFBYSxFQUFFLFlBQVlmO0FBRHBCO0FBSkcsR0FBZDtBQVFBLFNBQU9KLFlBQVksQ0FBQ29CLEdBQWIsQ0FBaUJMLE9BQWpCLENBQVA7QUFDRDs7QUFFRE0sTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZYLEVBQUFBLGFBQWEsRUFBRUEsYUFEQTtBQUVmVixFQUFBQSxnQkFBZ0IsRUFBRUE7QUFGSCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgbGluZSBBUEkuXG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIHJlcXVlc3QoJ3Byb2ZpbGUnLCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgIGlmIChyZXNwb25zZSAmJiByZXNwb25zZS51c2VySWQgJiYgcmVzcG9uc2UudXNlcklkID09PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0xpbmUgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBhcGkgcmVxdWVzdHNcbmZ1bmN0aW9uIHJlcXVlc3QocGF0aCwgYWNjZXNzX3Rva2VuKSB7XG4gIHZhciBvcHRpb25zID0ge1xuICAgIGhvc3Q6ICdhcGkubGluZS5tZScsXG4gICAgcGF0aDogJy92Mi8nICsgcGF0aCxcbiAgICBtZXRob2Q6ICdHRVQnLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgIEF1dGhvcml6YXRpb246ICdCZWFyZXIgJyArIGFjY2Vzc190b2tlbixcbiAgICB9LFxuICB9O1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LmdldChvcHRpb25zKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQ6IHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGE6IHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/linkedin.js b/lib/Adapters/Auth/linkedin.js deleted file mode 100644 index 6876cb4b0c..0000000000 --- a/lib/Adapters/Auth/linkedin.js +++ /dev/null @@ -1,46 +0,0 @@ -"use strict"; - -// Helper functions for accessing the linkedin API. -var Parse = require('parse/node').Parse; - -const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData) { - return request('me', authData.access_token, authData.is_mobile_sdk).then(data => { - if (data && data.id == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Linkedin auth is invalid for this user.'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for api requests - - -function request(path, access_token, is_mobile_sdk) { - var headers = { - Authorization: 'Bearer ' + access_token, - 'x-li-format': 'json' - }; - - if (is_mobile_sdk) { - headers['x-li-src'] = 'msdk'; - } - - return httpsRequest.get({ - host: 'api.linkedin.com', - path: '/v2/' + path, - headers: headers - }); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL2xpbmtlZGluLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsImh0dHBzUmVxdWVzdCIsInZhbGlkYXRlQXV0aERhdGEiLCJhdXRoRGF0YSIsInJlcXVlc3QiLCJhY2Nlc3NfdG9rZW4iLCJpc19tb2JpbGVfc2RrIiwidGhlbiIsImRhdGEiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJoZWFkZXJzIiwiQXV0aG9yaXphdGlvbiIsImdldCIsImhvc3QiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFDQSxNQUFNRSxZQUFZLEdBQUdELE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNFLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsSUFBRCxFQUFPRCxRQUFRLENBQUNFLFlBQWhCLEVBQThCRixRQUFRLENBQUNHLGFBQXZDLENBQVAsQ0FBNkRDLElBQTdELENBQWtFQyxJQUFJLElBQUk7QUFDL0UsUUFBSUEsSUFBSSxJQUFJQSxJQUFJLENBQUNDLEVBQUwsSUFBV04sUUFBUSxDQUFDTSxFQUFoQyxFQUFvQztBQUNsQztBQUNEOztBQUNELFVBQU0sSUFBSVYsS0FBSyxDQUFDVyxLQUFWLENBQWdCWCxLQUFLLENBQUNXLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLHlDQUE5QyxDQUFOO0FBQ0QsR0FMTSxDQUFQO0FBTUQsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTVixPQUFULENBQWlCVyxJQUFqQixFQUF1QlYsWUFBdkIsRUFBcUNDLGFBQXJDLEVBQW9EO0FBQ2xELE1BQUlVLE9BQU8sR0FBRztBQUNaQyxJQUFBQSxhQUFhLEVBQUUsWUFBWVosWUFEZjtBQUVaLG1CQUFlO0FBRkgsR0FBZDs7QUFLQSxNQUFJQyxhQUFKLEVBQW1CO0FBQ2pCVSxJQUFBQSxPQUFPLENBQUMsVUFBRCxDQUFQLEdBQXNCLE1BQXRCO0FBQ0Q7O0FBQ0QsU0FBT2YsWUFBWSxDQUFDaUIsR0FBYixDQUFpQjtBQUN0QkMsSUFBQUEsSUFBSSxFQUFFLGtCQURnQjtBQUV0QkosSUFBQUEsSUFBSSxFQUFFLFNBQVNBLElBRk87QUFHdEJDLElBQUFBLE9BQU8sRUFBRUE7QUFIYSxHQUFqQixDQUFQO0FBS0Q7O0FBRURJLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVCxFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlYsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIGxpbmtlZGluIEFQSS5cbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIHJlcXVlc3QoJ21lJywgYXV0aERhdGEuYWNjZXNzX3Rva2VuLCBhdXRoRGF0YS5pc19tb2JpbGVfc2RrKS50aGVuKGRhdGEgPT4ge1xuICAgIGlmIChkYXRhICYmIGRhdGEuaWQgPT0gYXV0aERhdGEuaWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdMaW5rZWRpbiBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nKTtcbiAgfSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIGFwaSByZXF1ZXN0c1xuZnVuY3Rpb24gcmVxdWVzdChwYXRoLCBhY2Nlc3NfdG9rZW4sIGlzX21vYmlsZV9zZGspIHtcbiAgdmFyIGhlYWRlcnMgPSB7XG4gICAgQXV0aG9yaXphdGlvbjogJ0JlYXJlciAnICsgYWNjZXNzX3Rva2VuLFxuICAgICd4LWxpLWZvcm1hdCc6ICdqc29uJyxcbiAgfTtcblxuICBpZiAoaXNfbW9iaWxlX3Nkaykge1xuICAgIGhlYWRlcnNbJ3gtbGktc3JjJ10gPSAnbXNkayc7XG4gIH1cbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoe1xuICAgIGhvc3Q6ICdhcGkubGlua2VkaW4uY29tJyxcbiAgICBwYXRoOiAnL3YyLycgKyBwYXRoLFxuICAgIGhlYWRlcnM6IGhlYWRlcnMsXG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZDogdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YTogdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/meetup.js b/lib/Adapters/Auth/meetup.js deleted file mode 100644 index 18eb5e0b20..0000000000 --- a/lib/Adapters/Auth/meetup.js +++ /dev/null @@ -1,39 +0,0 @@ -"use strict"; - -// Helper functions for accessing the meetup API. -var Parse = require('parse/node').Parse; - -const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData) { - return request('member/self', authData.access_token).then(data => { - if (data && data.id == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Meetup auth is invalid for this user.'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for api requests - - -function request(path, access_token) { - return httpsRequest.get({ - host: 'api.meetup.com', - path: '/2/' + path, - headers: { - Authorization: 'bearer ' + access_token - } - }); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL21lZXR1cC5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJyZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsImRhdGEiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJnZXQiLCJob3N0IiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFDQSxNQUFNRSxZQUFZLEdBQUdELE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNFLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsYUFBRCxFQUFnQkQsUUFBUSxDQUFDRSxZQUF6QixDQUFQLENBQThDQyxJQUE5QyxDQUFtREMsSUFBSSxJQUFJO0FBQ2hFLFFBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxFQUFMLElBQVdMLFFBQVEsQ0FBQ0ssRUFBaEMsRUFBb0M7QUFDbEM7QUFDRDs7QUFDRCxVQUFNLElBQUlULEtBQUssQ0FBQ1UsS0FBVixDQUFnQlYsS0FBSyxDQUFDVSxLQUFOLENBQVlDLGdCQUE1QixFQUE4Qyx1Q0FBOUMsQ0FBTjtBQUNELEdBTE0sQ0FBUDtBQU1ELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU1QsT0FBVCxDQUFpQlUsSUFBakIsRUFBdUJULFlBQXZCLEVBQXFDO0FBQ25DLFNBQU9KLFlBQVksQ0FBQ2MsR0FBYixDQUFpQjtBQUN0QkMsSUFBQUEsSUFBSSxFQUFFLGdCQURnQjtBQUV0QkYsSUFBQUEsSUFBSSxFQUFFLFFBQVFBLElBRlE7QUFHdEJHLElBQUFBLE9BQU8sRUFBRTtBQUNQQyxNQUFBQSxhQUFhLEVBQUUsWUFBWWI7QUFEcEI7QUFIYSxHQUFqQixDQUFQO0FBT0Q7O0FBRURjLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVCxFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlQsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIG1lZXR1cCBBUEkuXG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIHVzZXIgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG4gIHJldHVybiByZXF1ZXN0KCdtZW1iZXIvc2VsZicsIGF1dGhEYXRhLmFjY2Vzc190b2tlbikudGhlbihkYXRhID0+IHtcbiAgICBpZiAoZGF0YSAmJiBkYXRhLmlkID09IGF1dGhEYXRhLmlkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnTWVldHVwIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLicpO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyBhcHAgaWQgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbi8vIEEgcHJvbWlzZXkgd3JhcHBlciBmb3IgYXBpIHJlcXVlc3RzXG5mdW5jdGlvbiByZXF1ZXN0KHBhdGgsIGFjY2Vzc190b2tlbikge1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LmdldCh7XG4gICAgaG9zdDogJ2FwaS5tZWV0dXAuY29tJyxcbiAgICBwYXRoOiAnLzIvJyArIHBhdGgsXG4gICAgaGVhZGVyczoge1xuICAgICAgQXV0aG9yaXphdGlvbjogJ2JlYXJlciAnICsgYWNjZXNzX3Rva2VuLFxuICAgIH0sXG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZDogdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YTogdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/microsoft.js b/lib/Adapters/Auth/microsoft.js deleted file mode 100644 index 47a79ffe2c..0000000000 --- a/lib/Adapters/Auth/microsoft.js +++ /dev/null @@ -1,39 +0,0 @@ -"use strict"; - -// Helper functions for accessing the microsoft graph API. -var Parse = require('parse/node').Parse; - -const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills if this user mail is valid. - - -function validateAuthData(authData) { - return request('me', authData.access_token).then(response => { - if (response && response.id && response.id == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Microsoft Graph auth is invalid for this user.'); - }); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for api requests - - -function request(path, access_token) { - return httpsRequest.get({ - host: 'graph.microsoft.com', - path: '/v1.0/' + path, - headers: { - Authorization: 'Bearer ' + access_token - } - }); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL21pY3Jvc29mdC5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJyZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsInJlc3BvbnNlIiwiaWQiLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ2YWxpZGF0ZUFwcElkIiwiUHJvbWlzZSIsInJlc29sdmUiLCJwYXRoIiwiZ2V0IiwiaG9zdCIsImhlYWRlcnMiLCJBdXRob3JpemF0aW9uIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBbEM7O0FBQ0EsTUFBTUUsWUFBWSxHQUFHRCxPQUFPLENBQUMsZ0JBQUQsQ0FBNUIsQyxDQUVBOzs7QUFDQSxTQUFTRSxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0M7QUFDbEMsU0FBT0MsT0FBTyxDQUFDLElBQUQsRUFBT0QsUUFBUSxDQUFDRSxZQUFoQixDQUFQLENBQXFDQyxJQUFyQyxDQUEwQ0MsUUFBUSxJQUFJO0FBQzNELFFBQUlBLFFBQVEsSUFBSUEsUUFBUSxDQUFDQyxFQUFyQixJQUEyQkQsUUFBUSxDQUFDQyxFQUFULElBQWVMLFFBQVEsQ0FBQ0ssRUFBdkQsRUFBMkQ7QUFDekQ7QUFDRDs7QUFDRCxVQUFNLElBQUlULEtBQUssQ0FBQ1UsS0FBVixDQUNKVixLQUFLLENBQUNVLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSixnREFGSSxDQUFOO0FBSUQsR0FSTSxDQUFQO0FBU0QsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTVCxPQUFULENBQWlCVSxJQUFqQixFQUF1QlQsWUFBdkIsRUFBcUM7QUFDbkMsU0FBT0osWUFBWSxDQUFDYyxHQUFiLENBQWlCO0FBQ3RCQyxJQUFBQSxJQUFJLEVBQUUscUJBRGdCO0FBRXRCRixJQUFBQSxJQUFJLEVBQUUsV0FBV0EsSUFGSztBQUd0QkcsSUFBQUEsT0FBTyxFQUFFO0FBQ1BDLE1BQUFBLGFBQWEsRUFBRSxZQUFZYjtBQURwQjtBQUhhLEdBQWpCLENBQVA7QUFPRDs7QUFFRGMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZULEVBQUFBLGFBQWEsRUFBRUEsYUFEQTtBQUVmVCxFQUFBQSxnQkFBZ0IsRUFBRUE7QUFGSCxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgbWljcm9zb2Z0IGdyYXBoIEFQSS5cbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyB1c2VyIG1haWwgaXMgdmFsaWQuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhKSB7XG4gIHJldHVybiByZXF1ZXN0KCdtZScsIGF1dGhEYXRhLmFjY2Vzc190b2tlbikudGhlbihyZXNwb25zZSA9PiB7XG4gICAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLmlkICYmIHJlc3BvbnNlLmlkID09IGF1dGhEYXRhLmlkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAnTWljcm9zb2Z0IEdyYXBoIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLidcbiAgICApO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBhcGkgcmVxdWVzdHNcbmZ1bmN0aW9uIHJlcXVlc3QocGF0aCwgYWNjZXNzX3Rva2VuKSB7XG4gIHJldHVybiBodHRwc1JlcXVlc3QuZ2V0KHtcbiAgICBob3N0OiAnZ3JhcGgubWljcm9zb2Z0LmNvbScsXG4gICAgcGF0aDogJy92MS4wLycgKyBwYXRoLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgIEF1dGhvcml6YXRpb246ICdCZWFyZXIgJyArIGFjY2Vzc190b2tlbixcbiAgICB9LFxuICB9KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQ6IHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGE6IHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/oauth2.js b/lib/Adapters/Auth/oauth2.js deleted file mode 100644 index b830be60ff..0000000000 --- a/lib/Adapters/Auth/oauth2.js +++ /dev/null @@ -1,142 +0,0 @@ -"use strict"; - -/* - * This auth adapter is based on the OAuth 2.0 Token Introspection specification. - * See RFC 7662 for details (https://tools.ietf.org/html/rfc7662). - * It's purpose is to validate OAuth2 access tokens using the OAuth2 provider's - * token introspection endpoint (if implemented by the provider). - * - * The adapter accepts the following config parameters: - * - * 1. "tokenIntrospectionEndpointUrl" (string, required) - * The URL of the token introspection endpoint of the OAuth2 provider that - * issued the access token to the client that is to be validated. - * - * 2. "useridField" (string, optional) - * The name of the field in the token introspection response that contains - * the userid. If specified, it will be used to verify the value of the "id" - * field in the "authData" JSON that is coming from the client. - * This can be the "aud" (i.e. audience), the "sub" (i.e. subject) or the - * "username" field in the introspection response, but since only the - * "active" field is required and all other reponse fields are optional - * in the RFC, it has to be optional in this adapter as well. - * Default: - (undefined) - * - * 3. "appidField" (string, optional) - * The name of the field in the token introspection response that contains - * the appId of the client. If specified, it will be used to verify it's - * value against the set of appIds in the adapter config. The concept of - * appIds comes from the two major social login providers - * (Google and Facebook). They have not yet implemented the token - * introspection endpoint, but the concept can be valid for any OAuth2 - * provider. - * Default: - (undefined) - * - * 4. "appIds" (array of strings, required if appidField is defined) - * A set of appIds that are used to restrict accepted access tokens based - * on a specific field's value in the token introspection response. - * Default: - (undefined) - * - * 5. "authorizationHeader" (string, optional) - * The value of the "Authorization" HTTP header in requests sent to the - * introspection endpoint. It must contain the raw value. - * Thus if HTTP Basic authorization is to be used, it must contain the - * "Basic" string, followed by whitespace, then by the base64 encoded - * version of the concatenated + ":" + string. - * Eg. "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" - * - * The adapter expects requests with the following authData JSON: - * - * { - * "someadapter": { - * "id": "user's OAuth2 provider-specific id as a string", - * "access_token": "an authorized OAuth2 access token for the user", - * } - * } - */ -const Parse = require('parse/node').Parse; - -const url = require('url'); - -const querystring = require('querystring'); - -const httpsRequest = require('./httpsRequest'); - -const INVALID_ACCESS = 'OAuth2 access token is invalid for this user.'; -const INVALID_ACCESS_APPID = "OAuth2: the access_token's appID is empty or is not in the list of permitted appIDs in the auth configuration."; -const MISSING_APPIDS = 'OAuth2 configuration is missing the client app IDs ("appIds" config parameter).'; -const MISSING_URL = 'OAuth2 token introspection endpoint URL is missing from configuration!'; // Returns a promise that fulfills if this user id is valid. - -function validateAuthData(authData, options) { - return requestTokenInfo(options, authData.access_token).then(response => { - if (!response || !response.active || options.useridField && authData.id !== response[options.useridField]) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, INVALID_ACCESS); - } - }); -} - -function validateAppId(appIds, authData, options) { - if (!options || !options.appidField) { - return Promise.resolve(); - } - - if (!appIds || appIds.length === 0) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, MISSING_APPIDS); - } - - return requestTokenInfo(options, authData.access_token).then(response => { - if (!response || !response.active) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, INVALID_ACCESS); - } - - const appidField = options.appidField; - - if (!response[appidField]) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, INVALID_ACCESS_APPID); - } - - const responseValue = response[appidField]; - - if (!Array.isArray(responseValue) && appIds.includes(responseValue)) { - return; - } else if (Array.isArray(responseValue) && responseValue.some(appId => appIds.includes(appId))) { - return; - } else { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, INVALID_ACCESS_APPID); - } - }); -} // A promise wrapper for requests to the OAuth2 token introspection endpoint. - - -function requestTokenInfo(options, access_token) { - if (!options || !options.tokenIntrospectionEndpointUrl) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, MISSING_URL); - } - - const parsedUrl = url.parse(options.tokenIntrospectionEndpointUrl); - const postData = querystring.stringify({ - token: access_token - }); - const headers = { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Content-Length': Buffer.byteLength(postData) - }; - - if (options.authorizationHeader) { - headers['Authorization'] = options.authorizationHeader; - } - - const postOptions = { - hostname: parsedUrl.hostname, - path: parsedUrl.pathname, - method: 'POST', - headers: headers - }; - return httpsRequest.request(postOptions, postData); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL29hdXRoMi5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJ1cmwiLCJxdWVyeXN0cmluZyIsImh0dHBzUmVxdWVzdCIsIklOVkFMSURfQUNDRVNTIiwiSU5WQUxJRF9BQ0NFU1NfQVBQSUQiLCJNSVNTSU5HX0FQUElEUyIsIk1JU1NJTkdfVVJMIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwib3B0aW9ucyIsInJlcXVlc3RUb2tlbkluZm8iLCJhY2Nlc3NfdG9rZW4iLCJ0aGVuIiwicmVzcG9uc2UiLCJhY3RpdmUiLCJ1c2VyaWRGaWVsZCIsImlkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsImFwcElkcyIsImFwcGlkRmllbGQiLCJQcm9taXNlIiwicmVzb2x2ZSIsImxlbmd0aCIsInJlc3BvbnNlVmFsdWUiLCJBcnJheSIsImlzQXJyYXkiLCJpbmNsdWRlcyIsInNvbWUiLCJhcHBJZCIsInRva2VuSW50cm9zcGVjdGlvbkVuZHBvaW50VXJsIiwicGFyc2VkVXJsIiwicGFyc2UiLCJwb3N0RGF0YSIsInN0cmluZ2lmeSIsInRva2VuIiwiaGVhZGVycyIsIkJ1ZmZlciIsImJ5dGVMZW5ndGgiLCJhdXRob3JpemF0aW9uSGVhZGVyIiwicG9zdE9wdGlvbnMiLCJob3N0bmFtZSIsInBhdGgiLCJwYXRobmFtZSIsIm1ldGhvZCIsInJlcXVlc3QiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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QUFxQkwsV0FBckIsRUFBa0NQLFFBQWxDLENBQVA7QUFDRDs7QUFFRGEsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2Y3QixFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlosRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogVGhpcyBhdXRoIGFkYXB0ZXIgaXMgYmFzZWQgb24gdGhlIE9BdXRoIDIuMCBUb2tlbiBJbnRyb3NwZWN0aW9uIHNwZWNpZmljYXRpb24uXG4gKiBTZWUgUkZDIDc2NjIgZm9yIGRldGFpbHMgKGh0dHBzOi8vdG9vbHMuaWV0Zi5vcmcvaHRtbC9yZmM3NjYyKS5cbiAqIEl0J3MgcHVycG9zZSBpcyB0byB2YWxpZGF0ZSBPQXV0aDIgYWNjZXNzIHRva2VucyB1c2luZyB0aGUgT0F1dGgyIHByb3ZpZGVyJ3NcbiAqIHRva2VuIGludHJvc3BlY3Rpb24gZW5kcG9pbnQgKGlmIGltcGxlbWVudGVkIGJ5IHRoZSBwcm92aWRlcikuXG4gKlxuICogVGhlIGFkYXB0ZXIgYWNjZXB0cyB0aGUgZm9sbG93aW5nIGNvbmZpZyBwYXJhbWV0ZXJzOlxuICpcbiAqIDEuIFwidG9rZW5JbnRyb3NwZWN0aW9uRW5kcG9pbnRVcmxcIiAoc3RyaW5nLCByZXF1aXJlZClcbiAqICAgICAgVGhlIFVSTCBvZiB0aGUgdG9rZW4gaW50cm9zcGVjdGlvbiBlbmRwb2ludCBvZiB0aGUgT0F1dGgyIHByb3ZpZGVyIHRoYXRcbiAqICAgICAgaXNzdWVkIHRoZSBhY2Nlc3MgdG9rZW4gdG8gdGhlIGNsaWVudCB0aGF0IGlzIHRvIGJlIHZhbGlkYXRlZC5cbiAqXG4gKiAyLiBcInVzZXJpZEZpZWxkXCIgKHN0cmluZywgb3B0aW9uYWwpXG4gKiAgICAgIFRoZSBuYW1lIG9mIHRoZSBmaWVsZCBpbiB0aGUgdG9rZW4gaW50cm9zcGVjdGlvbiByZXNwb25zZSB0aGF0IGNvbnRhaW5zXG4gKiAgICAgIHRoZSB1c2VyaWQuIElmIHNwZWNpZmllZCwgaXQgd2lsbCBiZSB1c2VkIHRvIHZlcmlmeSB0aGUgdmFsdWUgb2YgdGhlIFwiaWRcIlxuICogICAgICBmaWVsZCBpbiB0aGUgXCJhdXRoRGF0YVwiIEpTT04gdGhhdCBpcyBjb21pbmcgZnJvbSB0aGUgY2xpZW50LlxuICogICAgICBUaGlzIGNhbiBiZSB0aGUgXCJhdWRcIiAoaS5lLiBhdWRpZW5jZSksIHRoZSBcInN1YlwiIChpLmUuIHN1YmplY3QpIG9yIHRoZVxuICogICAgICBcInVzZXJuYW1lXCIgZmllbGQgaW4gdGhlIGludHJvc3BlY3Rpb24gcmVzcG9uc2UsIGJ1dCBzaW5jZSBvbmx5IHRoZVxuICogICAgICBcImFjdGl2ZVwiIGZpZWxkIGlzIHJlcXVpcmVkIGFuZCBhbGwgb3RoZXIgcmVwb25zZSBmaWVsZHMgYXJlIG9wdGlvbmFsXG4gKiAgICAgIGluIHRoZSBSRkMsIGl0IGhhcyB0byBiZSBvcHRpb25hbCBpbiB0aGlzIGFkYXB0ZXIgYXMgd2VsbC5cbiAqICAgICAgRGVmYXVsdDogLSAodW5kZWZpbmVkKVxuICpcbiAqIDMuIFwiYXBwaWRGaWVsZFwiIChzdHJpbmcsIG9wdGlvbmFsKVxuICogICAgICBUaGUgbmFtZSBvZiB0aGUgZmllbGQgaW4gdGhlIHRva2VuIGludHJvc3BlY3Rpb24gcmVzcG9uc2UgdGhhdCBjb250YWluc1xuICogICAgICB0aGUgYXBwSWQgb2YgdGhlIGNsaWVudC4gSWYgc3BlY2lmaWVkLCBpdCB3aWxsIGJlIHVzZWQgdG8gdmVyaWZ5IGl0J3NcbiAqICAgICAgdmFsdWUgYWdhaW5zdCB0aGUgc2V0IG9mIGFwcElkcyBpbiB0aGUgYWRhcHRlciBjb25maWcuIFRoZSBjb25jZXB0IG9mXG4gKiAgICAgIGFwcElkcyBjb21lcyBmcm9tIHRoZSB0d28gbWFqb3Igc29jaWFsIGxvZ2luIHByb3ZpZGVyc1xuICogICAgICAoR29vZ2xlIGFuZCBGYWNlYm9vaykuIFRoZXkgaGF2ZSBub3QgeWV0IGltcGxlbWVudGVkIHRoZSB0b2tlblxuICogICAgICBpbnRyb3NwZWN0aW9uIGVuZHBvaW50LCBidXQgdGhlIGNvbmNlcHQgY2FuIGJlIHZhbGlkIGZvciBhbnkgT0F1dGgyXG4gKiAgICAgIHByb3ZpZGVyLlxuICogICAgICBEZWZhdWx0OiAtICh1bmRlZmluZWQpXG4gKlxuICogNC4gXCJhcHBJZHNcIiAoYXJyYXkgb2Ygc3RyaW5ncywgcmVxdWlyZWQgaWYgYXBwaWRGaWVsZCBpcyBkZWZpbmVkKVxuICogICAgICBBIHNldCBvZiBhcHBJZHMgdGhhdCBhcmUgdXNlZCB0byByZXN0cmljdCBhY2NlcHRlZCBhY2Nlc3MgdG9rZW5zIGJhc2VkXG4gKiAgICAgIG9uIGEgc3BlY2lmaWMgZmllbGQncyB2YWx1ZSBpbiB0aGUgdG9rZW4gaW50cm9zcGVjdGlvbiByZXNwb25zZS5cbiAqICAgICAgRGVmYXVsdDogLSAodW5kZWZpbmVkKVxuICpcbiAqIDUuIFwiYXV0aG9yaXphdGlvbkhlYWRlclwiIChzdHJpbmcsIG9wdGlvbmFsKVxuICogICAgICBUaGUgdmFsdWUgb2YgdGhlIFwiQXV0aG9yaXphdGlvblwiIEhUVFAgaGVhZGVyIGluIHJlcXVlc3RzIHNlbnQgdG8gdGhlXG4gKiAgICAgIGludHJvc3BlY3Rpb24gZW5kcG9pbnQuIEl0IG11c3QgY29udGFpbiB0aGUgcmF3IHZhbHVlLlxuICogICAgICBUaHVzIGlmIEhUVFAgQmFzaWMgYXV0aG9yaXphdGlvbiBpcyB0byBiZSB1c2VkLCBpdCBtdXN0IGNvbnRhaW4gdGhlXG4gKiAgICAgIFwiQmFzaWNcIiBzdHJpbmcsIGZvbGxvd2VkIGJ5IHdoaXRlc3BhY2UsIHRoZW4gYnkgdGhlIGJhc2U2NCBlbmNvZGVkXG4gKiAgICAgIHZlcnNpb24gb2YgdGhlIGNvbmNhdGVuYXRlZCA8dXNlcm5hbWU+ICsgXCI6XCIgKyA8cGFzc3dvcmQ+IHN0cmluZy5cbiAqICAgICAgRWcuIFwiQmFzaWMgZFhObGNtNWhiV1U2Y0dGemMzZHZjbVE9XCJcbiAqXG4gKiBUaGUgYWRhcHRlciBleHBlY3RzIHJlcXVlc3RzIHdpdGggdGhlIGZvbGxvd2luZyBhdXRoRGF0YSBKU09OOlxuICpcbiAqIHtcbiAqICAgXCJzb21lYWRhcHRlclwiOiB7XG4gKiAgICAgXCJpZFwiOiBcInVzZXIncyBPQXV0aDIgcHJvdmlkZXItc3BlY2lmaWMgaWQgYXMgYSBzdHJpbmdcIixcbiAqICAgICBcImFjY2Vzc190b2tlblwiOiBcImFuIGF1dGhvcml6ZWQgT0F1dGgyIGFjY2VzcyB0b2tlbiBmb3IgdGhlIHVzZXJcIixcbiAqICAgfVxuICogfVxuICovXG5cbmNvbnN0IFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuY29uc3QgdXJsID0gcmVxdWlyZSgndXJsJyk7XG5jb25zdCBxdWVyeXN0cmluZyA9IHJlcXVpcmUoJ3F1ZXJ5c3RyaW5nJyk7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG5jb25zdCBJTlZBTElEX0FDQ0VTUyA9ICdPQXV0aDIgYWNjZXNzIHRva2VuIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nO1xuY29uc3QgSU5WQUxJRF9BQ0NFU1NfQVBQSUQgPVxuICBcIk9BdXRoMjogdGhlIGFjY2Vzc190b2tlbidzIGFwcElEIGlzIGVtcHR5IG9yIGlzIG5vdCBpbiB0aGUgbGlzdCBvZiBwZXJtaXR0ZWQgYXBwSURzIGluIHRoZSBhdXRoIGNvbmZpZ3VyYXRpb24uXCI7XG5jb25zdCBNSVNTSU5HX0FQUElEUyA9XG4gICdPQXV0aDIgY29uZmlndXJhdGlvbiBpcyBtaXNzaW5nIHRoZSBjbGllbnQgYXBwIElEcyAoXCJhcHBJZHNcIiBjb25maWcgcGFyYW1ldGVyKS4nO1xuY29uc3QgTUlTU0lOR19VUkwgPSAnT0F1dGgyIHRva2VuIGludHJvc3BlY3Rpb24gZW5kcG9pbnQgVVJMIGlzIG1pc3NpbmcgZnJvbSBjb25maWd1cmF0aW9uISc7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWYgdGhpcyB1c2VyIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSwgb3B0aW9ucykge1xuICByZXR1cm4gcmVxdWVzdFRva2VuSW5mbyhvcHRpb25zLCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgIGlmIChcbiAgICAgICFyZXNwb25zZSB8fFxuICAgICAgIXJlc3BvbnNlLmFjdGl2ZSB8fFxuICAgICAgKG9wdGlvbnMudXNlcmlkRmllbGQgJiYgYXV0aERhdGEuaWQgIT09IHJlc3BvbnNlW29wdGlvbnMudXNlcmlkRmllbGRdKVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsIElOVkFMSURfQUNDRVNTKTtcbiAgICB9XG4gIH0pO1xufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZUFwcElkKGFwcElkcywgYXV0aERhdGEsIG9wdGlvbnMpIHtcbiAgaWYgKCFvcHRpb25zIHx8ICFvcHRpb25zLmFwcGlkRmllbGQpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbiAgaWYgKCFhcHBJZHMgfHwgYXBwSWRzLmxlbmd0aCA9PT0gMCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBNSVNTSU5HX0FQUElEUyk7XG4gIH1cbiAgcmV0dXJuIHJlcXVlc3RUb2tlbkluZm8ob3B0aW9ucywgYXV0aERhdGEuYWNjZXNzX3Rva2VuKS50aGVuKHJlc3BvbnNlID0+IHtcbiAgICBpZiAoIXJlc3BvbnNlIHx8ICFyZXNwb25zZS5hY3RpdmUpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBJTlZBTElEX0FDQ0VTUyk7XG4gICAgfVxuICAgIGNvbnN0IGFwcGlkRmllbGQgPSBvcHRpb25zLmFwcGlkRmllbGQ7XG4gICAgaWYgKCFyZXNwb25zZVthcHBpZEZpZWxkXSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsIElOVkFMSURfQUNDRVNTX0FQUElEKTtcbiAgICB9XG4gICAgY29uc3QgcmVzcG9uc2VWYWx1ZSA9IHJlc3BvbnNlW2FwcGlkRmllbGRdO1xuICAgIGlmICghQXJyYXkuaXNBcnJheShyZXNwb25zZVZhbHVlKSAmJiBhcHBJZHMuaW5jbHVkZXMocmVzcG9uc2VWYWx1ZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgQXJyYXkuaXNBcnJheShyZXNwb25zZVZhbHVlKSAmJlxuICAgICAgcmVzcG9uc2VWYWx1ZS5zb21lKGFwcElkID0+IGFwcElkcy5pbmNsdWRlcyhhcHBJZCkpXG4gICAgKSB7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBJTlZBTElEX0FDQ0VTU19BUFBJRCk7XG4gICAgfVxuICB9KTtcbn1cblxuLy8gQSBwcm9taXNlIHdyYXBwZXIgZm9yIHJlcXVlc3RzIHRvIHRoZSBPQXV0aDIgdG9rZW4gaW50cm9zcGVjdGlvbiBlbmRwb2ludC5cbmZ1bmN0aW9uIHJlcXVlc3RUb2tlbkluZm8ob3B0aW9ucywgYWNjZXNzX3Rva2VuKSB7XG4gIGlmICghb3B0aW9ucyB8fCAhb3B0aW9ucy50b2tlbkludHJvc3BlY3Rpb25FbmRwb2ludFVybCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCBNSVNTSU5HX1VSTCk7XG4gIH1cbiAgY29uc3QgcGFyc2VkVXJsID0gdXJsLnBhcnNlKG9wdGlvbnMudG9rZW5JbnRyb3NwZWN0aW9uRW5kcG9pbnRVcmwpO1xuICBjb25zdCBwb3N0RGF0YSA9IHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeSh7XG4gICAgdG9rZW46IGFjY2Vzc190b2tlbixcbiAgfSk7XG4gIGNvbnN0IGhlYWRlcnMgPSB7XG4gICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAgICdDb250ZW50LUxlbmd0aCc6IEJ1ZmZlci5ieXRlTGVuZ3RoKHBvc3REYXRhKSxcbiAgfTtcbiAgaWYgKG9wdGlvbnMuYXV0aG9yaXphdGlvbkhlYWRlcikge1xuICAgIGhlYWRlcnNbJ0F1dGhvcml6YXRpb24nXSA9IG9wdGlvbnMuYXV0aG9yaXphdGlvbkhlYWRlcjtcbiAgfVxuICBjb25zdCBwb3N0T3B0aW9ucyA9IHtcbiAgICBob3N0bmFtZTogcGFyc2VkVXJsLmhvc3RuYW1lLFxuICAgIHBhdGg6IHBhcnNlZFVybC5wYXRobmFtZSxcbiAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICBoZWFkZXJzOiBoZWFkZXJzLFxuICB9O1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LnJlcXVlc3QocG9zdE9wdGlvbnMsIHBvc3REYXRhKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQ6IHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGE6IHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/Auth/phantauth.js b/lib/Adapters/Auth/phantauth.js deleted file mode 100644 index 5c8774bbd7..0000000000 --- a/lib/Adapters/Auth/phantauth.js +++ /dev/null @@ -1,47 +0,0 @@ -"use strict"; - -/* - * PhantAuth was designed to simplify testing for applications using OpenID Connect - * authentication by making use of random generated users. - * - * To learn more, please go to: https://www.phantauth.net - */ -const { - Parse -} = require('parse/node'); - -const httpsRequest = require('./httpsRequest'); // Returns a promise that fulfills if this user id is valid. - - -function validateAuthData(authData) { - return request('auth/userinfo', authData.access_token).then(data => { - if (data && data.sub == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'PhantAuth auth is invalid for this user.'); - }); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for api requests - - -function request(path, access_token) { - return httpsRequest.get({ - host: 'phantauth.net', - path: '/' + path, - headers: { - Authorization: 'bearer ' + access_token, - 'User-Agent': 'parse-server' - } - }); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3BoYW50YXV0aC5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJodHRwc1JlcXVlc3QiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJyZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsImRhdGEiLCJzdWIiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJnZXQiLCJob3N0IiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBLE1BQU07QUFBRUEsRUFBQUE7QUFBRixJQUFZQyxPQUFPLENBQUMsWUFBRCxDQUF6Qjs7QUFDQSxNQUFNQyxZQUFZLEdBQUdELE9BQU8sQ0FBQyxnQkFBRCxDQUE1QixDLENBRUE7OztBQUNBLFNBQVNFLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsZUFBRCxFQUFrQkQsUUFBUSxDQUFDRSxZQUEzQixDQUFQLENBQWdEQyxJQUFoRCxDQUFxREMsSUFBSSxJQUFJO0FBQ2xFLFFBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxHQUFMLElBQVlMLFFBQVEsQ0FBQ00sRUFBakMsRUFBcUM7QUFDbkM7QUFDRDs7QUFDRCxVQUFNLElBQUlWLEtBQUssQ0FBQ1csS0FBVixDQUFnQlgsS0FBSyxDQUFDVyxLQUFOLENBQVlDLGdCQUE1QixFQUE4QywwQ0FBOUMsQ0FBTjtBQUNELEdBTE0sQ0FBUDtBQU1ELEMsQ0FFRDs7O0FBQ0EsU0FBU0MsYUFBVCxHQUF5QjtBQUN2QixTQUFPQyxPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU1YsT0FBVCxDQUFpQlcsSUFBakIsRUFBdUJWLFlBQXZCLEVBQXFDO0FBQ25DLFNBQU9KLFlBQVksQ0FBQ2UsR0FBYixDQUFpQjtBQUN0QkMsSUFBQUEsSUFBSSxFQUFFLGVBRGdCO0FBRXRCRixJQUFBQSxJQUFJLEVBQUUsTUFBTUEsSUFGVTtBQUd0QkcsSUFBQUEsT0FBTyxFQUFFO0FBQ1BDLE1BQUFBLGFBQWEsRUFBRSxZQUFZZCxZQURwQjtBQUVQLG9CQUFjO0FBRlA7QUFIYSxHQUFqQixDQUFQO0FBUUQ7O0FBRURlLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVCxFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlYsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogUGhhbnRBdXRoIHdhcyBkZXNpZ25lZCB0byBzaW1wbGlmeSB0ZXN0aW5nIGZvciBhcHBsaWNhdGlvbnMgdXNpbmcgT3BlbklEIENvbm5lY3RcbiAqIGF1dGhlbnRpY2F0aW9uIGJ5IG1ha2luZyB1c2Ugb2YgcmFuZG9tIGdlbmVyYXRlZCB1c2Vycy5cbiAqXG4gKiBUbyBsZWFybiBtb3JlLCBwbGVhc2UgZ28gdG86IGh0dHBzOi8vd3d3LnBoYW50YXV0aC5uZXRcbiAqL1xuXG5jb25zdCB7IFBhcnNlIH0gPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5jb25zdCBodHRwc1JlcXVlc3QgPSByZXF1aXJlKCcuL2h0dHBzUmVxdWVzdCcpO1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIHJlcXVlc3QoJ2F1dGgvdXNlcmluZm8nLCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oZGF0YSA9PiB7XG4gICAgaWYgKGRhdGEgJiYgZGF0YS5zdWIgPT0gYXV0aERhdGEuaWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdQaGFudEF1dGggYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIGFwaSByZXF1ZXN0c1xuZnVuY3Rpb24gcmVxdWVzdChwYXRoLCBhY2Nlc3NfdG9rZW4pIHtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoe1xuICAgIGhvc3Q6ICdwaGFudGF1dGgubmV0JyxcbiAgICBwYXRoOiAnLycgKyBwYXRoLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgIEF1dGhvcml6YXRpb246ICdiZWFyZXIgJyArIGFjY2Vzc190b2tlbixcbiAgICAgICdVc2VyLUFnZW50JzogJ3BhcnNlLXNlcnZlcicsXG4gICAgfSxcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkOiB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhOiB2YWxpZGF0ZUF1dGhEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/qq.js b/lib/Adapters/Auth/qq.js deleted file mode 100644 index 9191ef36da..0000000000 --- a/lib/Adapters/Auth/qq.js +++ /dev/null @@ -1,48 +0,0 @@ -"use strict"; - -// Helper functions for accessing the qq Graph API. -const httpsRequest = require('./httpsRequest'); - -var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData) { - return graphRequest('me?access_token=' + authData.access_token).then(function (data) { - if (data && data.openid == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'qq auth is invalid for this user.'); - }); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for qq graph requests. - - -function graphRequest(path) { - return httpsRequest.get('https://graph.qq.com/oauth2.0/' + path, true).then(data => { - return parseResponseData(data); - }); -} - -function parseResponseData(data) { - const starPos = data.indexOf('('); - const endPos = data.indexOf(')'); - - if (starPos == -1 || endPos == -1) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'qq auth is invalid for this user.'); - } - - data = data.substring(starPos + 1, endPos - 1); - return JSON.parse(data); -} - -module.exports = { - validateAppId, - validateAuthData, - parseResponseData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3FxLmpzIl0sIm5hbWVzIjpbImh0dHBzUmVxdWVzdCIsInJlcXVpcmUiLCJQYXJzZSIsInZhbGlkYXRlQXV0aERhdGEiLCJhdXRoRGF0YSIsImdyYXBoUmVxdWVzdCIsImFjY2Vzc190b2tlbiIsInRoZW4iLCJkYXRhIiwib3BlbmlkIiwiaWQiLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ2YWxpZGF0ZUFwcElkIiwiUHJvbWlzZSIsInJlc29sdmUiLCJwYXRoIiwiZ2V0IiwicGFyc2VSZXNwb25zZURhdGEiLCJzdGFyUG9zIiwiaW5kZXhPZiIsImVuZFBvcyIsInN1YnN0cmluZyIsIkpTT04iLCJwYXJzZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQSxNQUFNQSxZQUFZLEdBQUdDLE9BQU8sQ0FBQyxnQkFBRCxDQUE1Qjs7QUFDQSxJQUFJQyxLQUFLLEdBQUdELE9BQU8sQ0FBQyxZQUFELENBQVAsQ0FBc0JDLEtBQWxDLEMsQ0FFQTs7O0FBQ0EsU0FBU0MsZ0JBQVQsQ0FBMEJDLFFBQTFCLEVBQW9DO0FBQ2xDLFNBQU9DLFlBQVksQ0FBQyxxQkFBcUJELFFBQVEsQ0FBQ0UsWUFBL0IsQ0FBWixDQUF5REMsSUFBekQsQ0FBOEQsVUFBVUMsSUFBVixFQUFnQjtBQUNuRixRQUFJQSxJQUFJLElBQUlBLElBQUksQ0FBQ0MsTUFBTCxJQUFlTCxRQUFRLENBQUNNLEVBQXBDLEVBQXdDO0FBQ3RDO0FBQ0Q7O0FBQ0QsVUFBTSxJQUFJUixLQUFLLENBQUNTLEtBQVYsQ0FBZ0JULEtBQUssQ0FBQ1MsS0FBTixDQUFZQyxnQkFBNUIsRUFBOEMsbUNBQTlDLENBQU47QUFDRCxHQUxNLENBQVA7QUFNRCxDLENBRUQ7OztBQUNBLFNBQVNDLGFBQVQsR0FBeUI7QUFDdkIsU0FBT0MsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNWLFlBQVQsQ0FBc0JXLElBQXRCLEVBQTRCO0FBQzFCLFNBQU9oQixZQUFZLENBQUNpQixHQUFiLENBQWlCLG1DQUFtQ0QsSUFBcEQsRUFBMEQsSUFBMUQsRUFBZ0VULElBQWhFLENBQXFFQyxJQUFJLElBQUk7QUFDbEYsV0FBT1UsaUJBQWlCLENBQUNWLElBQUQsQ0FBeEI7QUFDRCxHQUZNLENBQVA7QUFHRDs7QUFFRCxTQUFTVSxpQkFBVCxDQUEyQlYsSUFBM0IsRUFBaUM7QUFDL0IsUUFBTVcsT0FBTyxHQUFHWCxJQUFJLENBQUNZLE9BQUwsQ0FBYSxHQUFiLENBQWhCO0FBQ0EsUUFBTUMsTUFBTSxHQUFHYixJQUFJLENBQUNZLE9BQUwsQ0FBYSxHQUFiLENBQWY7O0FBQ0EsTUFBSUQsT0FBTyxJQUFJLENBQUMsQ0FBWixJQUFpQkUsTUFBTSxJQUFJLENBQUMsQ0FBaEMsRUFBbUM7QUFDakMsVUFBTSxJQUFJbkIsS0FBSyxDQUFDUyxLQUFWLENBQWdCVCxLQUFLLENBQUNTLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLG1DQUE5QyxDQUFOO0FBQ0Q7O0FBQ0RKLEVBQUFBLElBQUksR0FBR0EsSUFBSSxDQUFDYyxTQUFMLENBQWVILE9BQU8sR0FBRyxDQUF6QixFQUE0QkUsTUFBTSxHQUFHLENBQXJDLENBQVA7QUFDQSxTQUFPRSxJQUFJLENBQUNDLEtBQUwsQ0FBV2hCLElBQVgsQ0FBUDtBQUNEOztBQUVEaUIsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZiLEVBQUFBLGFBRGU7QUFFZlYsRUFBQUEsZ0JBRmU7QUFHZmUsRUFBQUE7QUFIZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgcXEgR3JhcGggQVBJLlxuY29uc3QgaHR0cHNSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwc1JlcXVlc3QnKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyB1c2VyIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSkge1xuICByZXR1cm4gZ3JhcGhSZXF1ZXN0KCdtZT9hY2Nlc3NfdG9rZW49JyArIGF1dGhEYXRhLmFjY2Vzc190b2tlbikudGhlbihmdW5jdGlvbiAoZGF0YSkge1xuICAgIGlmIChkYXRhICYmIGRhdGEub3BlbmlkID09IGF1dGhEYXRhLmlkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAncXEgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIHFxIGdyYXBoIHJlcXVlc3RzLlxuZnVuY3Rpb24gZ3JhcGhSZXF1ZXN0KHBhdGgpIHtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoJ2h0dHBzOi8vZ3JhcGgucXEuY29tL29hdXRoMi4wLycgKyBwYXRoLCB0cnVlKS50aGVuKGRhdGEgPT4ge1xuICAgIHJldHVybiBwYXJzZVJlc3BvbnNlRGF0YShkYXRhKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlUmVzcG9uc2VEYXRhKGRhdGEpIHtcbiAgY29uc3Qgc3RhclBvcyA9IGRhdGEuaW5kZXhPZignKCcpO1xuICBjb25zdCBlbmRQb3MgPSBkYXRhLmluZGV4T2YoJyknKTtcbiAgaWYgKHN0YXJQb3MgPT0gLTEgfHwgZW5kUG9zID09IC0xKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdxcSBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nKTtcbiAgfVxuICBkYXRhID0gZGF0YS5zdWJzdHJpbmcoc3RhclBvcyArIDEsIGVuZFBvcyAtIDEpO1xuICByZXR1cm4gSlNPTi5wYXJzZShkYXRhKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGEsXG4gIHBhcnNlUmVzcG9uc2VEYXRhLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/spotify.js b/lib/Adapters/Auth/spotify.js deleted file mode 100644 index 154d3ad6d6..0000000000 --- a/lib/Adapters/Auth/spotify.js +++ /dev/null @@ -1,51 +0,0 @@ -"use strict"; - -// Helper functions for accessing the Spotify API. -const httpsRequest = require('./httpsRequest'); - -var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData) { - return request('me', authData.access_token).then(data => { - if (data && data.id == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify auth is invalid for this user.'); - }); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId(appIds, authData) { - var access_token = authData.access_token; - - if (!appIds.length) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify auth is not configured.'); - } - - return request('me', access_token).then(data => { - if (data && appIds.indexOf(data.id) != -1) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Spotify auth is invalid for this user.'); - }); -} // A promisey wrapper for Spotify API requests. - - -function request(path, access_token) { - return httpsRequest.get({ - host: 'api.spotify.com', - path: '/v1/' + path, - headers: { - Authorization: 'Bearer ' + access_token - } - }); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3Nwb3RpZnkuanMiXSwibmFtZXMiOlsiaHR0cHNSZXF1ZXN0IiwicmVxdWlyZSIsIlBhcnNlIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwicmVxdWVzdCIsImFjY2Vzc190b2tlbiIsInRoZW4iLCJkYXRhIiwiaWQiLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ2YWxpZGF0ZUFwcElkIiwiYXBwSWRzIiwibGVuZ3RoIiwiaW5kZXhPZiIsInBhdGgiLCJnZXQiLCJob3N0IiwiaGVhZGVycyIsIkF1dGhvcml6YXRpb24iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsTUFBTUEsWUFBWSxHQUFHQyxPQUFPLENBQUMsZ0JBQUQsQ0FBNUI7O0FBQ0EsSUFBSUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCQyxLQUFsQyxDLENBRUE7OztBQUNBLFNBQVNDLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxPQUFPLENBQUMsSUFBRCxFQUFPRCxRQUFRLENBQUNFLFlBQWhCLENBQVAsQ0FBcUNDLElBQXJDLENBQTBDQyxJQUFJLElBQUk7QUFDdkQsUUFBSUEsSUFBSSxJQUFJQSxJQUFJLENBQUNDLEVBQUwsSUFBV0wsUUFBUSxDQUFDSyxFQUFoQyxFQUFvQztBQUNsQztBQUNEOztBQUNELFVBQU0sSUFBSVAsS0FBSyxDQUFDUSxLQUFWLENBQWdCUixLQUFLLENBQUNRLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLHdDQUE5QyxDQUFOO0FBQ0QsR0FMTSxDQUFQO0FBTUQsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULENBQXVCQyxNQUF2QixFQUErQlQsUUFBL0IsRUFBeUM7QUFDdkMsTUFBSUUsWUFBWSxHQUFHRixRQUFRLENBQUNFLFlBQTVCOztBQUNBLE1BQUksQ0FBQ08sTUFBTSxDQUFDQyxNQUFaLEVBQW9CO0FBQ2xCLFVBQU0sSUFBSVosS0FBSyxDQUFDUSxLQUFWLENBQWdCUixLQUFLLENBQUNRLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLGlDQUE5QyxDQUFOO0FBQ0Q7O0FBQ0QsU0FBT04sT0FBTyxDQUFDLElBQUQsRUFBT0MsWUFBUCxDQUFQLENBQTRCQyxJQUE1QixDQUFpQ0MsSUFBSSxJQUFJO0FBQzlDLFFBQUlBLElBQUksSUFBSUssTUFBTSxDQUFDRSxPQUFQLENBQWVQLElBQUksQ0FBQ0MsRUFBcEIsS0FBMkIsQ0FBQyxDQUF4QyxFQUEyQztBQUN6QztBQUNEOztBQUNELFVBQU0sSUFBSVAsS0FBSyxDQUFDUSxLQUFWLENBQWdCUixLQUFLLENBQUNRLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLHdDQUE5QyxDQUFOO0FBQ0QsR0FMTSxDQUFQO0FBTUQsQyxDQUVEOzs7QUFDQSxTQUFTTixPQUFULENBQWlCVyxJQUFqQixFQUF1QlYsWUFBdkIsRUFBcUM7QUFDbkMsU0FBT04sWUFBWSxDQUFDaUIsR0FBYixDQUFpQjtBQUN0QkMsSUFBQUEsSUFBSSxFQUFFLGlCQURnQjtBQUV0QkYsSUFBQUEsSUFBSSxFQUFFLFNBQVNBLElBRk87QUFHdEJHLElBQUFBLE9BQU8sRUFBRTtBQUNQQyxNQUFBQSxhQUFhLEVBQUUsWUFBWWQ7QUFEcEI7QUFIYSxHQUFqQixDQUFQO0FBT0Q7O0FBRURlLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmVixFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZlQsRUFBQUEsZ0JBQWdCLEVBQUVBO0FBRkgsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIFNwb3RpZnkgQVBJLlxuY29uc3QgaHR0cHNSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwc1JlcXVlc3QnKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyB1c2VyIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSkge1xuICByZXR1cm4gcmVxdWVzdCgnbWUnLCBhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oZGF0YSA9PiB7XG4gICAgaWYgKGRhdGEgJiYgZGF0YS5pZCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ1Nwb3RpZnkgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZChhcHBJZHMsIGF1dGhEYXRhKSB7XG4gIHZhciBhY2Nlc3NfdG9rZW4gPSBhdXRoRGF0YS5hY2Nlc3NfdG9rZW47XG4gIGlmICghYXBwSWRzLmxlbmd0aCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnU3BvdGlmeSBhdXRoIGlzIG5vdCBjb25maWd1cmVkLicpO1xuICB9XG4gIHJldHVybiByZXF1ZXN0KCdtZScsIGFjY2Vzc190b2tlbikudGhlbihkYXRhID0+IHtcbiAgICBpZiAoZGF0YSAmJiBhcHBJZHMuaW5kZXhPZihkYXRhLmlkKSAhPSAtMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ1Nwb3RpZnkgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gIH0pO1xufVxuXG4vLyBBIHByb21pc2V5IHdyYXBwZXIgZm9yIFNwb3RpZnkgQVBJIHJlcXVlc3RzLlxuZnVuY3Rpb24gcmVxdWVzdChwYXRoLCBhY2Nlc3NfdG9rZW4pIHtcbiAgcmV0dXJuIGh0dHBzUmVxdWVzdC5nZXQoe1xuICAgIGhvc3Q6ICdhcGkuc3BvdGlmeS5jb20nLFxuICAgIHBhdGg6ICcvdjEvJyArIHBhdGgsXG4gICAgaGVhZGVyczoge1xuICAgICAgQXV0aG9yaXphdGlvbjogJ0JlYXJlciAnICsgYWNjZXNzX3Rva2VuLFxuICAgIH0sXG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZDogdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YTogdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/twitter.js b/lib/Adapters/Auth/twitter.js deleted file mode 100644 index ce9cd4666b..0000000000 --- a/lib/Adapters/Auth/twitter.js +++ /dev/null @@ -1,60 +0,0 @@ -"use strict"; - -// Helper functions for accessing the twitter API. -var OAuth = require('./OAuth1Client'); - -var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData, options) { - if (!options) { - throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Twitter auth configuration missing'); - } - - options = handleMultipleConfigurations(authData, options); - var client = new OAuth(options); - client.host = 'api.twitter.com'; - client.auth_token = authData.auth_token; - client.auth_token_secret = authData.auth_token_secret; - return client.get('/1.1/account/verify_credentials.json').then(data => { - if (data && data.id_str == '' + authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} - -function handleMultipleConfigurations(authData, options) { - if (Array.isArray(options)) { - const consumer_key = authData.consumer_key; - - if (!consumer_key) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.'); - } - - options = options.filter(option => { - return option.consumer_key == consumer_key; - }); - - if (options.length == 0) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.'); - } - - options = options[0]; - } - - return options; -} - -module.exports = { - validateAppId, - validateAuthData, - handleMultipleConfigurations -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3R3aXR0ZXIuanMiXSwibmFtZXMiOlsiT0F1dGgiLCJyZXF1aXJlIiwiUGFyc2UiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJvcHRpb25zIiwiRXJyb3IiLCJJTlRFUk5BTF9TRVJWRVJfRVJST1IiLCJoYW5kbGVNdWx0aXBsZUNvbmZpZ3VyYXRpb25zIiwiY2xpZW50IiwiaG9zdCIsImF1dGhfdG9rZW4iLCJhdXRoX3Rva2VuX3NlY3JldCIsImdldCIsInRoZW4iLCJkYXRhIiwiaWRfc3RyIiwiaWQiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwidmFsaWRhdGVBcHBJZCIsIlByb21pc2UiLCJyZXNvbHZlIiwiQXJyYXkiLCJpc0FycmF5IiwiY29uc3VtZXJfa2V5IiwiZmlsdGVyIiwib3B0aW9uIiwibGVuZ3RoIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLGdCQUFELENBQW5COztBQUNBLElBQUlDLEtBQUssR0FBR0QsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkMsS0FBbEMsQyxDQUVBOzs7QUFDQSxTQUFTQyxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0NDLE9BQXBDLEVBQTZDO0FBQzNDLE1BQUksQ0FBQ0EsT0FBTCxFQUFjO0FBQ1osVUFBTSxJQUFJSCxLQUFLLENBQUNJLEtBQVYsQ0FBZ0JKLEtBQUssQ0FBQ0ksS0FBTixDQUFZQyxxQkFBNUIsRUFBbUQsb0NBQW5ELENBQU47QUFDRDs7QUFDREYsRUFBQUEsT0FBTyxHQUFHRyw0QkFBNEIsQ0FBQ0osUUFBRCxFQUFXQyxPQUFYLENBQXRDO0FBQ0EsTUFBSUksTUFBTSxHQUFHLElBQUlULEtBQUosQ0FBVUssT0FBVixDQUFiO0FBQ0FJLEVBQUFBLE1BQU0sQ0FBQ0MsSUFBUCxHQUFjLGlCQUFkO0FBQ0FELEVBQUFBLE1BQU0sQ0FBQ0UsVUFBUCxHQUFvQlAsUUFBUSxDQUFDTyxVQUE3QjtBQUNBRixFQUFBQSxNQUFNLENBQUNHLGlCQUFQLEdBQTJCUixRQUFRLENBQUNRLGlCQUFwQztBQUVBLFNBQU9ILE1BQU0sQ0FBQ0ksR0FBUCxDQUFXLHNDQUFYLEVBQW1EQyxJQUFuRCxDQUF3REMsSUFBSSxJQUFJO0FBQ3JFLFFBQUlBLElBQUksSUFBSUEsSUFBSSxDQUFDQyxNQUFMLElBQWUsS0FBS1osUUFBUSxDQUFDYSxFQUF6QyxFQUE2QztBQUMzQztBQUNEOztBQUNELFVBQU0sSUFBSWYsS0FBSyxDQUFDSSxLQUFWLENBQWdCSixLQUFLLENBQUNJLEtBQU4sQ0FBWVksZ0JBQTVCLEVBQThDLHdDQUE5QyxDQUFOO0FBQ0QsR0FMTSxDQUFQO0FBTUQsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0Q7O0FBRUQsU0FBU2IsNEJBQVQsQ0FBc0NKLFFBQXRDLEVBQWdEQyxPQUFoRCxFQUF5RDtBQUN2RCxNQUFJaUIsS0FBSyxDQUFDQyxPQUFOLENBQWNsQixPQUFkLENBQUosRUFBNEI7QUFDMUIsVUFBTW1CLFlBQVksR0FBR3BCLFFBQVEsQ0FBQ29CLFlBQTlCOztBQUNBLFFBQUksQ0FBQ0EsWUFBTCxFQUFtQjtBQUNqQixZQUFNLElBQUl0QixLQUFLLENBQUNJLEtBQVYsQ0FBZ0JKLEtBQUssQ0FBQ0ksS0FBTixDQUFZWSxnQkFBNUIsRUFBOEMsd0NBQTlDLENBQU47QUFDRDs7QUFDRGIsSUFBQUEsT0FBTyxHQUFHQSxPQUFPLENBQUNvQixNQUFSLENBQWVDLE1BQU0sSUFBSTtBQUNqQyxhQUFPQSxNQUFNLENBQUNGLFlBQVAsSUFBdUJBLFlBQTlCO0FBQ0QsS0FGUyxDQUFWOztBQUlBLFFBQUluQixPQUFPLENBQUNzQixNQUFSLElBQWtCLENBQXRCLEVBQXlCO0FBQ3ZCLFlBQU0sSUFBSXpCLEtBQUssQ0FBQ0ksS0FBVixDQUFnQkosS0FBSyxDQUFDSSxLQUFOLENBQVlZLGdCQUE1QixFQUE4Qyx3Q0FBOUMsQ0FBTjtBQUNEOztBQUNEYixJQUFBQSxPQUFPLEdBQUdBLE9BQU8sQ0FBQyxDQUFELENBQWpCO0FBQ0Q7O0FBQ0QsU0FBT0EsT0FBUDtBQUNEOztBQUVEdUIsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZWLEVBQUFBLGFBRGU7QUFFZmhCLEVBQUFBLGdCQUZlO0FBR2ZLLEVBQUFBO0FBSGUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIHR3aXR0ZXIgQVBJLlxudmFyIE9BdXRoID0gcmVxdWlyZSgnLi9PQXV0aDFDbGllbnQnKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZmYgdGhpcyB1c2VyIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YSwgb3B0aW9ucykge1xuICBpZiAoIW9wdGlvbnMpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLCAnVHdpdHRlciBhdXRoIGNvbmZpZ3VyYXRpb24gbWlzc2luZycpO1xuICB9XG4gIG9wdGlvbnMgPSBoYW5kbGVNdWx0aXBsZUNvbmZpZ3VyYXRpb25zKGF1dGhEYXRhLCBvcHRpb25zKTtcbiAgdmFyIGNsaWVudCA9IG5ldyBPQXV0aChvcHRpb25zKTtcbiAgY2xpZW50Lmhvc3QgPSAnYXBpLnR3aXR0ZXIuY29tJztcbiAgY2xpZW50LmF1dGhfdG9rZW4gPSBhdXRoRGF0YS5hdXRoX3Rva2VuO1xuICBjbGllbnQuYXV0aF90b2tlbl9zZWNyZXQgPSBhdXRoRGF0YS5hdXRoX3Rva2VuX3NlY3JldDtcblxuICByZXR1cm4gY2xpZW50LmdldCgnLzEuMS9hY2NvdW50L3ZlcmlmeV9jcmVkZW50aWFscy5qc29uJykudGhlbihkYXRhID0+IHtcbiAgICBpZiAoZGF0YSAmJiBkYXRhLmlkX3N0ciA9PSAnJyArIGF1dGhEYXRhLmlkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnVHdpdHRlciBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nKTtcbiAgfSk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgYXBwIGlkIGlzIHZhbGlkLlxuZnVuY3Rpb24gdmFsaWRhdGVBcHBJZCgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufVxuXG5mdW5jdGlvbiBoYW5kbGVNdWx0aXBsZUNvbmZpZ3VyYXRpb25zKGF1dGhEYXRhLCBvcHRpb25zKSB7XG4gIGlmIChBcnJheS5pc0FycmF5KG9wdGlvbnMpKSB7XG4gICAgY29uc3QgY29uc3VtZXJfa2V5ID0gYXV0aERhdGEuY29uc3VtZXJfa2V5O1xuICAgIGlmICghY29uc3VtZXJfa2V5KSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ1R3aXR0ZXIgYXV0aCBpcyBpbnZhbGlkIGZvciB0aGlzIHVzZXIuJyk7XG4gICAgfVxuICAgIG9wdGlvbnMgPSBvcHRpb25zLmZpbHRlcihvcHRpb24gPT4ge1xuICAgICAgcmV0dXJuIG9wdGlvbi5jb25zdW1lcl9rZXkgPT0gY29uc3VtZXJfa2V5O1xuICAgIH0pO1xuXG4gICAgaWYgKG9wdGlvbnMubGVuZ3RoID09IDApIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnVHdpdHRlciBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nKTtcbiAgICB9XG4gICAgb3B0aW9ucyA9IG9wdGlvbnNbMF07XG4gIH1cbiAgcmV0dXJuIG9wdGlvbnM7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB2YWxpZGF0ZUFwcElkLFxuICB2YWxpZGF0ZUF1dGhEYXRhLFxuICBoYW5kbGVNdWx0aXBsZUNvbmZpZ3VyYXRpb25zLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Auth/vkontakte.js b/lib/Adapters/Auth/vkontakte.js deleted file mode 100644 index 1e952c1d3d..0000000000 --- a/lib/Adapters/Auth/vkontakte.js +++ /dev/null @@ -1,54 +0,0 @@ -'use strict'; // Helper functions for accessing the vkontakte API. - -const httpsRequest = require('./httpsRequest'); - -var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData, params) { - return vkOAuth2Request(params).then(function (response) { - if (response && response.access_token) { - return request('api.vk.com', 'method/users.get?access_token=' + authData.access_token + '&v=' + params.apiVersion).then(function (response) { - if (response && response.response && response.response.length && response.response[0].id == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Vk auth is invalid for this user.'); - }); - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Vk appIds or appSecret is incorrect.'); - }); -} - -function vkOAuth2Request(params) { - return new Promise(function (resolve) { - if (!params || !params.appIds || !params.appIds.length || !params.appSecret || !params.appSecret.length) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Vk auth is not configured. Missing appIds or appSecret.'); - } - - if (!params.apiVersion) { - params.apiVersion = '5.124'; - } - - resolve(); - }).then(function () { - return request('oauth.vk.com', 'access_token?client_id=' + params.appIds + '&client_secret=' + params.appSecret + '&v=' + params.apiVersion + '&grant_type=client_credentials'); - }); -} // Returns a promise that fulfills iff this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for api requests - - -function request(host, path) { - return httpsRequest.get('https://' + host + '/' + path); -} - -module.exports = { - validateAppId: validateAppId, - validateAuthData: validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3Zrb250YWt0ZS5qcyJdLCJuYW1lcyI6WyJodHRwc1JlcXVlc3QiLCJyZXF1aXJlIiwiUGFyc2UiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJwYXJhbXMiLCJ2a09BdXRoMlJlcXVlc3QiLCJ0aGVuIiwicmVzcG9uc2UiLCJhY2Nlc3NfdG9rZW4iLCJyZXF1ZXN0IiwiYXBpVmVyc2lvbiIsImxlbmd0aCIsImlkIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiUHJvbWlzZSIsInJlc29sdmUiLCJhcHBJZHMiLCJhcHBTZWNyZXQiLCJ2YWxpZGF0ZUFwcElkIiwiaG9zdCIsInBhdGgiLCJnZXQiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiQUFBQSxhLENBRUE7O0FBRUEsTUFBTUEsWUFBWSxHQUFHQyxPQUFPLENBQUMsZ0JBQUQsQ0FBNUI7O0FBQ0EsSUFBSUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCQyxLQUFsQyxDLENBRUE7OztBQUNBLFNBQVNDLGdCQUFULENBQTBCQyxRQUExQixFQUFvQ0MsTUFBcEMsRUFBNEM7QUFDMUMsU0FBT0MsZUFBZSxDQUFDRCxNQUFELENBQWYsQ0FBd0JFLElBQXhCLENBQTZCLFVBQVVDLFFBQVYsRUFBb0I7QUFDdEQsUUFBSUEsUUFBUSxJQUFJQSxRQUFRLENBQUNDLFlBQXpCLEVBQXVDO0FBQ3JDLGFBQU9DLE9BQU8sQ0FDWixZQURZLEVBRVosbUNBQW1DTixRQUFRLENBQUNLLFlBQTVDLEdBQTJELEtBQTNELEdBQW1FSixNQUFNLENBQUNNLFVBRjlELENBQVAsQ0FHTEosSUFISyxDQUdBLFVBQVVDLFFBQVYsRUFBb0I7QUFDekIsWUFDRUEsUUFBUSxJQUNSQSxRQUFRLENBQUNBLFFBRFQsSUFFQUEsUUFBUSxDQUFDQSxRQUFULENBQWtCSSxNQUZsQixJQUdBSixRQUFRLENBQUNBLFFBQVQsQ0FBa0IsQ0FBbEIsRUFBcUJLLEVBQXJCLElBQTJCVCxRQUFRLENBQUNTLEVBSnRDLEVBS0U7QUFDQTtBQUNEOztBQUNELGNBQU0sSUFBSVgsS0FBSyxDQUFDWSxLQUFWLENBQWdCWixLQUFLLENBQUNZLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLG1DQUE5QyxDQUFOO0FBQ0QsT0FiTSxDQUFQO0FBY0Q7O0FBQ0QsVUFBTSxJQUFJYixLQUFLLENBQUNZLEtBQVYsQ0FBZ0JaLEtBQUssQ0FBQ1ksS0FBTixDQUFZQyxnQkFBNUIsRUFBOEMsc0NBQTlDLENBQU47QUFDRCxHQWxCTSxDQUFQO0FBbUJEOztBQUVELFNBQVNULGVBQVQsQ0FBeUJELE1BQXpCLEVBQWlDO0FBQy9CLFNBQU8sSUFBSVcsT0FBSixDQUFZLFVBQVVDLE9BQVYsRUFBbUI7QUFDcEMsUUFDRSxDQUFDWixNQUFELElBQ0EsQ0FBQ0EsTUFBTSxDQUFDYSxNQURSLElBRUEsQ0FBQ2IsTUFBTSxDQUFDYSxNQUFQLENBQWNOLE1BRmYsSUFHQSxDQUFDUCxNQUFNLENBQUNjLFNBSFIsSUFJQSxDQUFDZCxNQUFNLENBQUNjLFNBQVAsQ0FBaUJQLE1BTHBCLEVBTUU7QUFDQSxZQUFNLElBQUlWLEtBQUssQ0FBQ1ksS0FBVixDQUNKWixLQUFLLENBQUNZLEtBQU4sQ0FBWUMsZ0JBRFIsRUFFSix5REFGSSxDQUFOO0FBSUQ7O0FBQ0QsUUFBSSxDQUFDVixNQUFNLENBQUNNLFVBQVosRUFBd0I7QUFDdEJOLE1BQUFBLE1BQU0sQ0FBQ00sVUFBUCxHQUFvQixPQUFwQjtBQUNEOztBQUNETSxJQUFBQSxPQUFPO0FBQ1IsR0FqQk0sRUFpQkpWLElBakJJLENBaUJDLFlBQVk7QUFDbEIsV0FBT0csT0FBTyxDQUNaLGNBRFksRUFFWiw0QkFDRUwsTUFBTSxDQUFDYSxNQURULEdBRUUsaUJBRkYsR0FHRWIsTUFBTSxDQUFDYyxTQUhULEdBSUUsS0FKRixHQUtFZCxNQUFNLENBQUNNLFVBTFQsR0FNRSxnQ0FSVSxDQUFkO0FBVUQsR0E1Qk0sQ0FBUDtBQTZCRCxDLENBRUQ7OztBQUNBLFNBQVNTLGFBQVQsR0FBeUI7QUFDdkIsU0FBT0osT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNQLE9BQVQsQ0FBaUJXLElBQWpCLEVBQXVCQyxJQUF2QixFQUE2QjtBQUMzQixTQUFPdEIsWUFBWSxDQUFDdUIsR0FBYixDQUFpQixhQUFhRixJQUFiLEdBQW9CLEdBQXBCLEdBQTBCQyxJQUEzQyxDQUFQO0FBQ0Q7O0FBRURFLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjtBQUNmTCxFQUFBQSxhQUFhLEVBQUVBLGFBREE7QUFFZmpCLEVBQUFBLGdCQUFnQixFQUFFQTtBQUZILENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vLyBIZWxwZXIgZnVuY3Rpb25zIGZvciBhY2Nlc3NpbmcgdGhlIHZrb250YWt0ZSBBUEkuXG5cbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEsIHBhcmFtcykge1xuICByZXR1cm4gdmtPQXV0aDJSZXF1ZXN0KHBhcmFtcykudGhlbihmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICBpZiAocmVzcG9uc2UgJiYgcmVzcG9uc2UuYWNjZXNzX3Rva2VuKSB7XG4gICAgICByZXR1cm4gcmVxdWVzdChcbiAgICAgICAgJ2FwaS52ay5jb20nLFxuICAgICAgICAnbWV0aG9kL3VzZXJzLmdldD9hY2Nlc3NfdG9rZW49JyArIGF1dGhEYXRhLmFjY2Vzc190b2tlbiArICcmdj0nICsgcGFyYW1zLmFwaVZlcnNpb25cbiAgICAgICkudGhlbihmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHJlc3BvbnNlICYmXG4gICAgICAgICAgcmVzcG9uc2UucmVzcG9uc2UgJiZcbiAgICAgICAgICByZXNwb25zZS5yZXNwb25zZS5sZW5ndGggJiZcbiAgICAgICAgICByZXNwb25zZS5yZXNwb25zZVswXS5pZCA9PSBhdXRoRGF0YS5pZFxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdWayBhdXRoIGlzIGludmFsaWQgZm9yIHRoaXMgdXNlci4nKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ1ZrIGFwcElkcyBvciBhcHBTZWNyZXQgaXMgaW5jb3JyZWN0LicpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gdmtPQXV0aDJSZXF1ZXN0KHBhcmFtcykge1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICBpZiAoXG4gICAgICAhcGFyYW1zIHx8XG4gICAgICAhcGFyYW1zLmFwcElkcyB8fFxuICAgICAgIXBhcmFtcy5hcHBJZHMubGVuZ3RoIHx8XG4gICAgICAhcGFyYW1zLmFwcFNlY3JldCB8fFxuICAgICAgIXBhcmFtcy5hcHBTZWNyZXQubGVuZ3RoXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICdWayBhdXRoIGlzIG5vdCBjb25maWd1cmVkLiBNaXNzaW5nIGFwcElkcyBvciBhcHBTZWNyZXQuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKCFwYXJhbXMuYXBpVmVyc2lvbikge1xuICAgICAgcGFyYW1zLmFwaVZlcnNpb24gPSAnNS4xMjQnO1xuICAgIH1cbiAgICByZXNvbHZlKCk7XG4gIH0pLnRoZW4oZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiByZXF1ZXN0KFxuICAgICAgJ29hdXRoLnZrLmNvbScsXG4gICAgICAnYWNjZXNzX3Rva2VuP2NsaWVudF9pZD0nICtcbiAgICAgICAgcGFyYW1zLmFwcElkcyArXG4gICAgICAgICcmY2xpZW50X3NlY3JldD0nICtcbiAgICAgICAgcGFyYW1zLmFwcFNlY3JldCArXG4gICAgICAgICcmdj0nICtcbiAgICAgICAgcGFyYW1zLmFwaVZlcnNpb24gK1xuICAgICAgICAnJmdyYW50X3R5cGU9Y2xpZW50X2NyZWRlbnRpYWxzJ1xuICAgICk7XG4gIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGZ1bGZpbGxzIGlmZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBhcGkgcmVxdWVzdHNcbmZ1bmN0aW9uIHJlcXVlc3QoaG9zdCwgcGF0aCkge1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LmdldCgnaHR0cHM6Ly8nICsgaG9zdCArICcvJyArIHBhdGgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZDogdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YTogdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/wechat.js b/lib/Adapters/Auth/wechat.js deleted file mode 100644 index 7ac39e029c..0000000000 --- a/lib/Adapters/Auth/wechat.js +++ /dev/null @@ -1,33 +0,0 @@ -"use strict"; - -// Helper functions for accessing the WeChat Graph API. -const httpsRequest = require('./httpsRequest'); - -var Parse = require('parse/node').Parse; // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData) { - return graphRequest('auth?access_token=' + authData.access_token + '&openid=' + authData.id).then(function (data) { - if (data.errcode == 0) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'wechat auth is invalid for this user.'); - }); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for WeChat graph requests. - - -function graphRequest(path) { - return httpsRequest.get('https://api.weixin.qq.com/sns/' + path); -} - -module.exports = { - validateAppId, - validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3dlY2hhdC5qcyJdLCJuYW1lcyI6WyJodHRwc1JlcXVlc3QiLCJyZXF1aXJlIiwiUGFyc2UiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJncmFwaFJlcXVlc3QiLCJhY2Nlc3NfdG9rZW4iLCJpZCIsInRoZW4iLCJkYXRhIiwiZXJyY29kZSIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBhdGgiLCJnZXQiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0EsTUFBTUEsWUFBWSxHQUFHQyxPQUFPLENBQUMsZ0JBQUQsQ0FBNUI7O0FBQ0EsSUFBSUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCQyxLQUFsQyxDLENBRUE7OztBQUNBLFNBQVNDLGdCQUFULENBQTBCQyxRQUExQixFQUFvQztBQUNsQyxTQUFPQyxZQUFZLENBQUMsdUJBQXVCRCxRQUFRLENBQUNFLFlBQWhDLEdBQStDLFVBQS9DLEdBQTRERixRQUFRLENBQUNHLEVBQXRFLENBQVosQ0FBc0ZDLElBQXRGLENBQ0wsVUFBVUMsSUFBVixFQUFnQjtBQUNkLFFBQUlBLElBQUksQ0FBQ0MsT0FBTCxJQUFnQixDQUFwQixFQUF1QjtBQUNyQjtBQUNEOztBQUNELFVBQU0sSUFBSVIsS0FBSyxDQUFDUyxLQUFWLENBQWdCVCxLQUFLLENBQUNTLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLHVDQUE5QyxDQUFOO0FBQ0QsR0FOSSxDQUFQO0FBUUQsQyxDQUVEOzs7QUFDQSxTQUFTQyxhQUFULEdBQXlCO0FBQ3ZCLFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixFQUFQO0FBQ0QsQyxDQUVEOzs7QUFDQSxTQUFTVixZQUFULENBQXNCVyxJQUF0QixFQUE0QjtBQUMxQixTQUFPaEIsWUFBWSxDQUFDaUIsR0FBYixDQUFpQixtQ0FBbUNELElBQXBELENBQVA7QUFDRDs7QUFFREUsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZOLEVBQUFBLGFBRGU7QUFFZlYsRUFBQUE7QUFGZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEhlbHBlciBmdW5jdGlvbnMgZm9yIGFjY2Vzc2luZyB0aGUgV2VDaGF0IEdyYXBoIEFQSS5cbmNvbnN0IGh0dHBzUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cHNSZXF1ZXN0Jyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIGdyYXBoUmVxdWVzdCgnYXV0aD9hY2Nlc3NfdG9rZW49JyArIGF1dGhEYXRhLmFjY2Vzc190b2tlbiArICcmb3BlbmlkPScgKyBhdXRoRGF0YS5pZCkudGhlbihcbiAgICBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgaWYgKGRhdGEuZXJyY29kZSA9PSAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnd2VjaGF0IGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLicpO1xuICAgIH1cbiAgKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciBXZUNoYXQgZ3JhcGggcmVxdWVzdHMuXG5mdW5jdGlvbiBncmFwaFJlcXVlc3QocGF0aCkge1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LmdldCgnaHR0cHM6Ly9hcGkud2VpeGluLnFxLmNvbS9zbnMvJyArIHBhdGgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Auth/weibo.js b/lib/Adapters/Auth/weibo.js deleted file mode 100644 index 4e02a25ade..0000000000 --- a/lib/Adapters/Auth/weibo.js +++ /dev/null @@ -1,47 +0,0 @@ -"use strict"; - -// Helper functions for accessing the weibo Graph API. -var httpsRequest = require('./httpsRequest'); - -var Parse = require('parse/node').Parse; - -var querystring = require('querystring'); // Returns a promise that fulfills iff this user id is valid. - - -function validateAuthData(authData) { - return graphRequest(authData.access_token).then(function (data) { - if (data && data.uid == authData.id) { - return; - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'weibo auth is invalid for this user.'); - }); -} // Returns a promise that fulfills if this app id is valid. - - -function validateAppId() { - return Promise.resolve(); -} // A promisey wrapper for weibo graph requests. - - -function graphRequest(access_token) { - var postData = querystring.stringify({ - access_token: access_token - }); - var options = { - hostname: 'api.weibo.com', - path: '/oauth2/get_token_info', - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Content-Length': Buffer.byteLength(postData) - } - }; - return httpsRequest.request(options, postData); -} - -module.exports = { - validateAppId, - validateAuthData -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9BdXRoL3dlaWJvLmpzIl0sIm5hbWVzIjpbImh0dHBzUmVxdWVzdCIsInJlcXVpcmUiLCJQYXJzZSIsInF1ZXJ5c3RyaW5nIiwidmFsaWRhdGVBdXRoRGF0YSIsImF1dGhEYXRhIiwiZ3JhcGhSZXF1ZXN0IiwiYWNjZXNzX3Rva2VuIiwidGhlbiIsImRhdGEiLCJ1aWQiLCJpZCIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsInZhbGlkYXRlQXBwSWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInBvc3REYXRhIiwic3RyaW5naWZ5Iiwib3B0aW9ucyIsImhvc3RuYW1lIiwicGF0aCIsIm1ldGhvZCIsImhlYWRlcnMiLCJCdWZmZXIiLCJieXRlTGVuZ3RoIiwicmVxdWVzdCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQSxJQUFJQSxZQUFZLEdBQUdDLE9BQU8sQ0FBQyxnQkFBRCxDQUExQjs7QUFDQSxJQUFJQyxLQUFLLEdBQUdELE9BQU8sQ0FBQyxZQUFELENBQVAsQ0FBc0JDLEtBQWxDOztBQUNBLElBQUlDLFdBQVcsR0FBR0YsT0FBTyxDQUFDLGFBQUQsQ0FBekIsQyxDQUVBOzs7QUFDQSxTQUFTRyxnQkFBVCxDQUEwQkMsUUFBMUIsRUFBb0M7QUFDbEMsU0FBT0MsWUFBWSxDQUFDRCxRQUFRLENBQUNFLFlBQVYsQ0FBWixDQUFvQ0MsSUFBcEMsQ0FBeUMsVUFBVUMsSUFBVixFQUFnQjtBQUM5RCxRQUFJQSxJQUFJLElBQUlBLElBQUksQ0FBQ0MsR0FBTCxJQUFZTCxRQUFRLENBQUNNLEVBQWpDLEVBQXFDO0FBQ25DO0FBQ0Q7O0FBQ0QsVUFBTSxJQUFJVCxLQUFLLENBQUNVLEtBQVYsQ0FBZ0JWLEtBQUssQ0FBQ1UsS0FBTixDQUFZQyxnQkFBNUIsRUFBOEMsc0NBQTlDLENBQU47QUFDRCxHQUxNLENBQVA7QUFNRCxDLENBRUQ7OztBQUNBLFNBQVNDLGFBQVQsR0FBeUI7QUFDdkIsU0FBT0MsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRCxDLENBRUQ7OztBQUNBLFNBQVNWLFlBQVQsQ0FBc0JDLFlBQXRCLEVBQW9DO0FBQ2xDLE1BQUlVLFFBQVEsR0FBR2QsV0FBVyxDQUFDZSxTQUFaLENBQXNCO0FBQ25DWCxJQUFBQSxZQUFZLEVBQUVBO0FBRHFCLEdBQXRCLENBQWY7QUFHQSxNQUFJWSxPQUFPLEdBQUc7QUFDWkMsSUFBQUEsUUFBUSxFQUFFLGVBREU7QUFFWkMsSUFBQUEsSUFBSSxFQUFFLHdCQUZNO0FBR1pDLElBQUFBLE1BQU0sRUFBRSxNQUhJO0FBSVpDLElBQUFBLE9BQU8sRUFBRTtBQUNQLHNCQUFnQixtQ0FEVDtBQUVQLHdCQUFrQkMsTUFBTSxDQUFDQyxVQUFQLENBQWtCUixRQUFsQjtBQUZYO0FBSkcsR0FBZDtBQVNBLFNBQU9qQixZQUFZLENBQUMwQixPQUFiLENBQXFCUCxPQUFyQixFQUE4QkYsUUFBOUIsQ0FBUDtBQUNEOztBQUVEVSxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZmQsRUFBQUEsYUFEZTtBQUVmVixFQUFBQTtBQUZlLENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gSGVscGVyIGZ1bmN0aW9ucyBmb3IgYWNjZXNzaW5nIHRoZSB3ZWlibyBHcmFwaCBBUEkuXG52YXIgaHR0cHNSZXF1ZXN0ID0gcmVxdWlyZSgnLi9odHRwc1JlcXVlc3QnKTtcbnZhciBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbnZhciBxdWVyeXN0cmluZyA9IHJlcXVpcmUoJ3F1ZXJ5c3RyaW5nJyk7XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgZnVsZmlsbHMgaWZmIHRoaXMgdXNlciBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXV0aERhdGEoYXV0aERhdGEpIHtcbiAgcmV0dXJuIGdyYXBoUmVxdWVzdChhdXRoRGF0YS5hY2Nlc3NfdG9rZW4pLnRoZW4oZnVuY3Rpb24gKGRhdGEpIHtcbiAgICBpZiAoZGF0YSAmJiBkYXRhLnVpZCA9PSBhdXRoRGF0YS5pZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ3dlaWJvIGF1dGggaXMgaW52YWxpZCBmb3IgdGhpcyB1c2VyLicpO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCBmdWxmaWxscyBpZiB0aGlzIGFwcCBpZCBpcyB2YWxpZC5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxuLy8gQSBwcm9taXNleSB3cmFwcGVyIGZvciB3ZWlibyBncmFwaCByZXF1ZXN0cy5cbmZ1bmN0aW9uIGdyYXBoUmVxdWVzdChhY2Nlc3NfdG9rZW4pIHtcbiAgdmFyIHBvc3REYXRhID0gcXVlcnlzdHJpbmcuc3RyaW5naWZ5KHtcbiAgICBhY2Nlc3NfdG9rZW46IGFjY2Vzc190b2tlbixcbiAgfSk7XG4gIHZhciBvcHRpb25zID0ge1xuICAgIGhvc3RuYW1lOiAnYXBpLndlaWJvLmNvbScsXG4gICAgcGF0aDogJy9vYXV0aDIvZ2V0X3Rva2VuX2luZm8nLFxuICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgIGhlYWRlcnM6IHtcbiAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJyxcbiAgICAgICdDb250ZW50LUxlbmd0aCc6IEJ1ZmZlci5ieXRlTGVuZ3RoKHBvc3REYXRhKSxcbiAgICB9LFxuICB9O1xuICByZXR1cm4gaHR0cHNSZXF1ZXN0LnJlcXVlc3Qob3B0aW9ucywgcG9zdERhdGEpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdmFsaWRhdGVBcHBJZCxcbiAgdmFsaWRhdGVBdXRoRGF0YSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Cache/CacheAdapter.js b/lib/Adapters/Cache/CacheAdapter.js deleted file mode 100644 index 90a616c493..0000000000 --- a/lib/Adapters/Cache/CacheAdapter.js +++ /dev/null @@ -1,50 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.CacheAdapter = void 0; - -/*eslint no-unused-vars: "off"*/ - -/** - * @module Adapters - */ - -/** - * @interface CacheAdapter - */ -class CacheAdapter { - /** - * Get a value in the cache - * @param {String} key Cache key to get - * @return {Promise} that will eventually resolve to the value in the cache. - */ - get(key) {} - /** - * Set a value in the cache - * @param {String} key Cache key to set - * @param {String} value Value to set the key - * @param {String} ttl Optional TTL - */ - - - put(key, value, ttl) {} - /** - * Remove a value from the cache. - * @param {String} key Cache key to remove - */ - - - del(key) {} - /** - * Empty a cache - */ - - - clear() {} - -} - -exports.CacheAdapter = CacheAdapter; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9DYWNoZUFkYXB0ZXIuanMiXSwibmFtZXMiOlsiQ2FjaGVBZGFwdGVyIiwiZ2V0Iiwia2V5IiwicHV0IiwidmFsdWUiLCJ0dGwiLCJkZWwiLCJjbGVhciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBO0FBQ0E7QUFDQTs7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNQSxZQUFOLENBQW1CO0FBQ3hCO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDRUMsRUFBQUEsR0FBRyxDQUFDQyxHQUFELEVBQU0sQ0FBRTtBQUVYO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0VDLEVBQUFBLEdBQUcsQ0FBQ0QsR0FBRCxFQUFNRSxLQUFOLEVBQWFDLEdBQWIsRUFBa0IsQ0FBRTtBQUV2QjtBQUNGO0FBQ0E7QUFDQTs7O0FBQ0VDLEVBQUFBLEdBQUcsQ0FBQ0osR0FBRCxFQUFNLENBQUU7QUFFWDtBQUNGO0FBQ0E7OztBQUNFSyxFQUFBQSxLQUFLLEdBQUcsQ0FBRTs7QUF6QmMiLCJzb3VyY2VzQ29udGVudCI6WyIvKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG4vKipcbiAqIEBtb2R1bGUgQWRhcHRlcnNcbiAqL1xuLyoqXG4gKiBAaW50ZXJmYWNlIENhY2hlQWRhcHRlclxuICovXG5leHBvcnQgY2xhc3MgQ2FjaGVBZGFwdGVyIHtcbiAgLyoqXG4gICAqIEdldCBhIHZhbHVlIGluIHRoZSBjYWNoZVxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5IENhY2hlIGtleSB0byBnZXRcbiAgICogQHJldHVybiB7UHJvbWlzZX0gdGhhdCB3aWxsIGV2ZW50dWFsbHkgcmVzb2x2ZSB0byB0aGUgdmFsdWUgaW4gdGhlIGNhY2hlLlxuICAgKi9cbiAgZ2V0KGtleSkge31cblxuICAvKipcbiAgICogU2V0IGEgdmFsdWUgaW4gdGhlIGNhY2hlXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgQ2FjaGUga2V5IHRvIHNldFxuICAgKiBAcGFyYW0ge1N0cmluZ30gdmFsdWUgVmFsdWUgdG8gc2V0IHRoZSBrZXlcbiAgICogQHBhcmFtIHtTdHJpbmd9IHR0bCBPcHRpb25hbCBUVExcbiAgICovXG4gIHB1dChrZXksIHZhbHVlLCB0dGwpIHt9XG5cbiAgLyoqXG4gICAqIFJlbW92ZSBhIHZhbHVlIGZyb20gdGhlIGNhY2hlLlxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5IENhY2hlIGtleSB0byByZW1vdmVcbiAgICovXG4gIGRlbChrZXkpIHt9XG5cbiAgLyoqXG4gICAqIEVtcHR5IGEgY2FjaGVcbiAgICovXG4gIGNsZWFyKCkge31cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Cache/InMemoryCache.js b/lib/Adapters/Cache/InMemoryCache.js deleted file mode 100644 index b9a6543504..0000000000 --- a/lib/Adapters/Cache/InMemoryCache.js +++ /dev/null @@ -1,76 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.InMemoryCache = void 0; -const DEFAULT_CACHE_TTL = 5 * 1000; - -class InMemoryCache { - constructor({ - ttl = DEFAULT_CACHE_TTL - }) { - this.ttl = ttl; - this.cache = Object.create(null); - } - - get(key) { - const record = this.cache[key]; - - if (record == null) { - return null; - } // Has Record and isnt expired - - - if (isNaN(record.expire) || record.expire >= Date.now()) { - return record.value; - } // Record has expired - - - delete this.cache[key]; - return null; - } - - put(key, value, ttl = this.ttl) { - if (ttl < 0 || isNaN(ttl)) { - ttl = NaN; - } - - var record = { - value: value, - expire: ttl + Date.now() - }; - - if (!isNaN(record.expire)) { - record.timeout = setTimeout(() => { - this.del(key); - }, ttl); - } - - this.cache[key] = record; - } - - del(key) { - var record = this.cache[key]; - - if (record == null) { - return; - } - - if (record.timeout) { - clearTimeout(record.timeout); - } - - delete this.cache[key]; - } - - clear() { - this.cache = Object.create(null); - } - -} - -exports.InMemoryCache = InMemoryCache; -var _default = InMemoryCache; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9Jbk1lbW9yeUNhY2hlLmpzIl0sIm5hbWVzIjpbIkRFRkFVTFRfQ0FDSEVfVFRMIiwiSW5NZW1vcnlDYWNoZSIsImNvbnN0cnVjdG9yIiwidHRsIiwiY2FjaGUiLCJPYmplY3QiLCJjcmVhdGUiLCJnZXQiLCJrZXkiLCJyZWNvcmQiLCJpc05hTiIsImV4cGlyZSIsIkRhdGUiLCJub3ciLCJ2YWx1ZSIsInB1dCIsIk5hTiIsInRpbWVvdXQiLCJzZXRUaW1lb3V0IiwiZGVsIiwiY2xlYXJUaW1lb3V0IiwiY2xlYXIiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLE1BQU1BLGlCQUFpQixHQUFHLElBQUksSUFBOUI7O0FBRU8sTUFBTUMsYUFBTixDQUFvQjtBQUN6QkMsRUFBQUEsV0FBVyxDQUFDO0FBQUVDLElBQUFBLEdBQUcsR0FBR0g7QUFBUixHQUFELEVBQThCO0FBQ3ZDLFNBQUtHLEdBQUwsR0FBV0EsR0FBWDtBQUNBLFNBQUtDLEtBQUwsR0FBYUMsTUFBTSxDQUFDQyxNQUFQLENBQWMsSUFBZCxDQUFiO0FBQ0Q7O0FBRURDLEVBQUFBLEdBQUcsQ0FBQ0MsR0FBRCxFQUFNO0FBQ1AsVUFBTUMsTUFBTSxHQUFHLEtBQUtMLEtBQUwsQ0FBV0ksR0FBWCxDQUFmOztBQUNBLFFBQUlDLE1BQU0sSUFBSSxJQUFkLEVBQW9CO0FBQ2xCLGFBQU8sSUFBUDtBQUNELEtBSk0sQ0FNUDs7O0FBQ0EsUUFBSUMsS0FBSyxDQUFDRCxNQUFNLENBQUNFLE1BQVIsQ0FBTCxJQUF3QkYsTUFBTSxDQUFDRSxNQUFQLElBQWlCQyxJQUFJLENBQUNDLEdBQUwsRUFBN0MsRUFBeUQ7QUFDdkQsYUFBT0osTUFBTSxDQUFDSyxLQUFkO0FBQ0QsS0FUTSxDQVdQOzs7QUFDQSxXQUFPLEtBQUtWLEtBQUwsQ0FBV0ksR0FBWCxDQUFQO0FBQ0EsV0FBTyxJQUFQO0FBQ0Q7O0FBRURPLEVBQUFBLEdBQUcsQ0FBQ1AsR0FBRCxFQUFNTSxLQUFOLEVBQWFYLEdBQUcsR0FBRyxLQUFLQSxHQUF4QixFQUE2QjtBQUM5QixRQUFJQSxHQUFHLEdBQUcsQ0FBTixJQUFXTyxLQUFLLENBQUNQLEdBQUQsQ0FBcEIsRUFBMkI7QUFDekJBLE1BQUFBLEdBQUcsR0FBR2EsR0FBTjtBQUNEOztBQUVELFFBQUlQLE1BQU0sR0FBRztBQUNYSyxNQUFBQSxLQUFLLEVBQUVBLEtBREk7QUFFWEgsTUFBQUEsTUFBTSxFQUFFUixHQUFHLEdBQUdTLElBQUksQ0FBQ0MsR0FBTDtBQUZILEtBQWI7O0FBS0EsUUFBSSxDQUFDSCxLQUFLLENBQUNELE1BQU0sQ0FBQ0UsTUFBUixDQUFWLEVBQTJCO0FBQ3pCRixNQUFBQSxNQUFNLENBQUNRLE9BQVAsR0FBaUJDLFVBQVUsQ0FBQyxNQUFNO0FBQ2hDLGFBQUtDLEdBQUwsQ0FBU1gsR0FBVDtBQUNELE9BRjBCLEVBRXhCTCxHQUZ3QixDQUEzQjtBQUdEOztBQUVELFNBQUtDLEtBQUwsQ0FBV0ksR0FBWCxJQUFrQkMsTUFBbEI7QUFDRDs7QUFFRFUsRUFBQUEsR0FBRyxDQUFDWCxHQUFELEVBQU07QUFDUCxRQUFJQyxNQUFNLEdBQUcsS0FBS0wsS0FBTCxDQUFXSSxHQUFYLENBQWI7O0FBQ0EsUUFBSUMsTUFBTSxJQUFJLElBQWQsRUFBb0I7QUFDbEI7QUFDRDs7QUFFRCxRQUFJQSxNQUFNLENBQUNRLE9BQVgsRUFBb0I7QUFDbEJHLE1BQUFBLFlBQVksQ0FBQ1gsTUFBTSxDQUFDUSxPQUFSLENBQVo7QUFDRDs7QUFDRCxXQUFPLEtBQUtiLEtBQUwsQ0FBV0ksR0FBWCxDQUFQO0FBQ0Q7O0FBRURhLEVBQUFBLEtBQUssR0FBRztBQUNOLFNBQUtqQixLQUFMLEdBQWFDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjLElBQWQsQ0FBYjtBQUNEOztBQXZEd0I7OztlQTBEWkwsYSIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IERFRkFVTFRfQ0FDSEVfVFRMID0gNSAqIDEwMDA7XG5cbmV4cG9ydCBjbGFzcyBJbk1lbW9yeUNhY2hlIHtcbiAgY29uc3RydWN0b3IoeyB0dGwgPSBERUZBVUxUX0NBQ0hFX1RUTCB9KSB7XG4gICAgdGhpcy50dGwgPSB0dGw7XG4gICAgdGhpcy5jYWNoZSA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gIH1cblxuICBnZXQoa2V5KSB7XG4gICAgY29uc3QgcmVjb3JkID0gdGhpcy5jYWNoZVtrZXldO1xuICAgIGlmIChyZWNvcmQgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gSGFzIFJlY29yZCBhbmQgaXNudCBleHBpcmVkXG4gICAgaWYgKGlzTmFOKHJlY29yZC5leHBpcmUpIHx8IHJlY29yZC5leHBpcmUgPj0gRGF0ZS5ub3coKSkge1xuICAgICAgcmV0dXJuIHJlY29yZC52YWx1ZTtcbiAgICB9XG5cbiAgICAvLyBSZWNvcmQgaGFzIGV4cGlyZWRcbiAgICBkZWxldGUgdGhpcy5jYWNoZVtrZXldO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHV0KGtleSwgdmFsdWUsIHR0bCA9IHRoaXMudHRsKSB7XG4gICAgaWYgKHR0bCA8IDAgfHwgaXNOYU4odHRsKSkge1xuICAgICAgdHRsID0gTmFOO1xuICAgIH1cblxuICAgIHZhciByZWNvcmQgPSB7XG4gICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICBleHBpcmU6IHR0bCArIERhdGUubm93KCksXG4gICAgfTtcblxuICAgIGlmICghaXNOYU4ocmVjb3JkLmV4cGlyZSkpIHtcbiAgICAgIHJlY29yZC50aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuZGVsKGtleSk7XG4gICAgICB9LCB0dGwpO1xuICAgIH1cblxuICAgIHRoaXMuY2FjaGVba2V5XSA9IHJlY29yZDtcbiAgfVxuXG4gIGRlbChrZXkpIHtcbiAgICB2YXIgcmVjb3JkID0gdGhpcy5jYWNoZVtrZXldO1xuICAgIGlmIChyZWNvcmQgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChyZWNvcmQudGltZW91dCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHJlY29yZC50aW1lb3V0KTtcbiAgICB9XG4gICAgZGVsZXRlIHRoaXMuY2FjaGVba2V5XTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIHRoaXMuY2FjaGUgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEluTWVtb3J5Q2FjaGU7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Cache/InMemoryCacheAdapter.js b/lib/Adapters/Cache/InMemoryCacheAdapter.js deleted file mode 100644 index ffc38ce5ec..0000000000 --- a/lib/Adapters/Cache/InMemoryCacheAdapter.js +++ /dev/null @@ -1,45 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.InMemoryCacheAdapter = void 0; - -var _LRUCache = require("./LRUCache"); - -class InMemoryCacheAdapter { - constructor(ctx) { - this.cache = new _LRUCache.LRUCache(ctx); - } - - get(key) { - const record = this.cache.get(key); - - if (record === null) { - return Promise.resolve(null); - } - - return Promise.resolve(record); - } - - put(key, value, ttl) { - this.cache.put(key, value, ttl); - return Promise.resolve(); - } - - del(key) { - this.cache.del(key); - return Promise.resolve(); - } - - clear() { - this.cache.clear(); - return Promise.resolve(); - } - -} - -exports.InMemoryCacheAdapter = InMemoryCacheAdapter; -var _default = InMemoryCacheAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9Jbk1lbW9yeUNhY2hlQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJJbk1lbW9yeUNhY2hlQWRhcHRlciIsImNvbnN0cnVjdG9yIiwiY3R4IiwiY2FjaGUiLCJMUlVDYWNoZSIsImdldCIsImtleSIsInJlY29yZCIsIlByb21pc2UiLCJyZXNvbHZlIiwicHV0IiwidmFsdWUiLCJ0dGwiLCJkZWwiLCJjbGVhciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUVPLE1BQU1BLG9CQUFOLENBQTJCO0FBQ2hDQyxFQUFBQSxXQUFXLENBQUNDLEdBQUQsRUFBTTtBQUNmLFNBQUtDLEtBQUwsR0FBYSxJQUFJQyxrQkFBSixDQUFhRixHQUFiLENBQWI7QUFDRDs7QUFFREcsRUFBQUEsR0FBRyxDQUFDQyxHQUFELEVBQU07QUFDUCxVQUFNQyxNQUFNLEdBQUcsS0FBS0osS0FBTCxDQUFXRSxHQUFYLENBQWVDLEdBQWYsQ0FBZjs7QUFDQSxRQUFJQyxNQUFNLEtBQUssSUFBZixFQUFxQjtBQUNuQixhQUFPQyxPQUFPLENBQUNDLE9BQVIsQ0FBZ0IsSUFBaEIsQ0FBUDtBQUNEOztBQUNELFdBQU9ELE9BQU8sQ0FBQ0MsT0FBUixDQUFnQkYsTUFBaEIsQ0FBUDtBQUNEOztBQUVERyxFQUFBQSxHQUFHLENBQUNKLEdBQUQsRUFBTUssS0FBTixFQUFhQyxHQUFiLEVBQWtCO0FBQ25CLFNBQUtULEtBQUwsQ0FBV08sR0FBWCxDQUFlSixHQUFmLEVBQW9CSyxLQUFwQixFQUEyQkMsR0FBM0I7QUFDQSxXQUFPSixPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUVESSxFQUFBQSxHQUFHLENBQUNQLEdBQUQsRUFBTTtBQUNQLFNBQUtILEtBQUwsQ0FBV1UsR0FBWCxDQUFlUCxHQUFmO0FBQ0EsV0FBT0UsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFREssRUFBQUEsS0FBSyxHQUFHO0FBQ04sU0FBS1gsS0FBTCxDQUFXVyxLQUFYO0FBQ0EsV0FBT04sT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUExQitCOzs7ZUE2Qm5CVCxvQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExSVUNhY2hlIH0gZnJvbSAnLi9MUlVDYWNoZSc7XG5cbmV4cG9ydCBjbGFzcyBJbk1lbW9yeUNhY2hlQWRhcHRlciB7XG4gIGNvbnN0cnVjdG9yKGN0eCkge1xuICAgIHRoaXMuY2FjaGUgPSBuZXcgTFJVQ2FjaGUoY3R4KTtcbiAgfVxuXG4gIGdldChrZXkpIHtcbiAgICBjb25zdCByZWNvcmQgPSB0aGlzLmNhY2hlLmdldChrZXkpO1xuICAgIGlmIChyZWNvcmQgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobnVsbCk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVjb3JkKTtcbiAgfVxuXG4gIHB1dChrZXksIHZhbHVlLCB0dGwpIHtcbiAgICB0aGlzLmNhY2hlLnB1dChrZXksIHZhbHVlLCB0dGwpO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGRlbChrZXkpIHtcbiAgICB0aGlzLmNhY2hlLmRlbChrZXkpO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIHRoaXMuY2FjaGUuY2xlYXIoKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSW5NZW1vcnlDYWNoZUFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Cache/LRUCache.js b/lib/Adapters/Cache/LRUCache.js deleted file mode 100644 index 9781621ecf..0000000000 --- a/lib/Adapters/Cache/LRUCache.js +++ /dev/null @@ -1,46 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.LRUCache = void 0; - -var _lruCache = _interopRequireDefault(require("lru-cache")); - -var _defaults = _interopRequireDefault(require("../../defaults")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class LRUCache { - constructor({ - ttl = _defaults.default.cacheTTL, - maxSize = _defaults.default.cacheMaxSize - }) { - this.cache = new _lruCache.default({ - max: maxSize, - maxAge: ttl - }); - } - - get(key) { - return this.cache.get(key) || null; - } - - put(key, value, ttl = this.ttl) { - this.cache.set(key, value, ttl); - } - - del(key) { - this.cache.del(key); - } - - clear() { - this.cache.reset(); - } - -} - -exports.LRUCache = LRUCache; -var _default = LRUCache; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9MUlVDYWNoZS5qcyJdLCJuYW1lcyI6WyJMUlVDYWNoZSIsImNvbnN0cnVjdG9yIiwidHRsIiwiZGVmYXVsdHMiLCJjYWNoZVRUTCIsIm1heFNpemUiLCJjYWNoZU1heFNpemUiLCJjYWNoZSIsIkxSVSIsIm1heCIsIm1heEFnZSIsImdldCIsImtleSIsInB1dCIsInZhbHVlIiwic2V0IiwiZGVsIiwiY2xlYXIiLCJyZXNldCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7O0FBRU8sTUFBTUEsUUFBTixDQUFlO0FBQ3BCQyxFQUFBQSxXQUFXLENBQUM7QUFBRUMsSUFBQUEsR0FBRyxHQUFHQyxrQkFBU0MsUUFBakI7QUFBMkJDLElBQUFBLE9BQU8sR0FBR0Ysa0JBQVNHO0FBQTlDLEdBQUQsRUFBK0Q7QUFDeEUsU0FBS0MsS0FBTCxHQUFhLElBQUlDLGlCQUFKLENBQVE7QUFDbkJDLE1BQUFBLEdBQUcsRUFBRUosT0FEYztBQUVuQkssTUFBQUEsTUFBTSxFQUFFUjtBQUZXLEtBQVIsQ0FBYjtBQUlEOztBQUVEUyxFQUFBQSxHQUFHLENBQUNDLEdBQUQsRUFBTTtBQUNQLFdBQU8sS0FBS0wsS0FBTCxDQUFXSSxHQUFYLENBQWVDLEdBQWYsS0FBdUIsSUFBOUI7QUFDRDs7QUFFREMsRUFBQUEsR0FBRyxDQUFDRCxHQUFELEVBQU1FLEtBQU4sRUFBYVosR0FBRyxHQUFHLEtBQUtBLEdBQXhCLEVBQTZCO0FBQzlCLFNBQUtLLEtBQUwsQ0FBV1EsR0FBWCxDQUFlSCxHQUFmLEVBQW9CRSxLQUFwQixFQUEyQlosR0FBM0I7QUFDRDs7QUFFRGMsRUFBQUEsR0FBRyxDQUFDSixHQUFELEVBQU07QUFDUCxTQUFLTCxLQUFMLENBQVdTLEdBQVgsQ0FBZUosR0FBZjtBQUNEOztBQUVESyxFQUFBQSxLQUFLLEdBQUc7QUFDTixTQUFLVixLQUFMLENBQVdXLEtBQVg7QUFDRDs7QUF0Qm1COzs7ZUF5QlBsQixRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IExSVSBmcm9tICdscnUtY2FjaGUnO1xuaW1wb3J0IGRlZmF1bHRzIGZyb20gJy4uLy4uL2RlZmF1bHRzJztcblxuZXhwb3J0IGNsYXNzIExSVUNhY2hlIHtcbiAgY29uc3RydWN0b3IoeyB0dGwgPSBkZWZhdWx0cy5jYWNoZVRUTCwgbWF4U2l6ZSA9IGRlZmF1bHRzLmNhY2hlTWF4U2l6ZSB9KSB7XG4gICAgdGhpcy5jYWNoZSA9IG5ldyBMUlUoe1xuICAgICAgbWF4OiBtYXhTaXplLFxuICAgICAgbWF4QWdlOiB0dGwsXG4gICAgfSk7XG4gIH1cblxuICBnZXQoa2V5KSB7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0KGtleSkgfHwgbnVsbDtcbiAgfVxuXG4gIHB1dChrZXksIHZhbHVlLCB0dGwgPSB0aGlzLnR0bCkge1xuICAgIHRoaXMuY2FjaGUuc2V0KGtleSwgdmFsdWUsIHR0bCk7XG4gIH1cblxuICBkZWwoa2V5KSB7XG4gICAgdGhpcy5jYWNoZS5kZWwoa2V5KTtcbiAgfVxuXG4gIGNsZWFyKCkge1xuICAgIHRoaXMuY2FjaGUucmVzZXQoKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBMUlVDYWNoZTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Cache/NullCacheAdapter.js b/lib/Adapters/Cache/NullCacheAdapter.js deleted file mode 100644 index 639c544c94..0000000000 --- a/lib/Adapters/Cache/NullCacheAdapter.js +++ /dev/null @@ -1,34 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.NullCacheAdapter = void 0; - -class NullCacheAdapter { - constructor() {} - - get() { - return new Promise(resolve => { - return resolve(null); - }); - } - - put() { - return Promise.resolve(); - } - - del() { - return Promise.resolve(); - } - - clear() { - return Promise.resolve(); - } - -} - -exports.NullCacheAdapter = NullCacheAdapter; -var _default = NullCacheAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9OdWxsQ2FjaGVBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIk51bGxDYWNoZUFkYXB0ZXIiLCJjb25zdHJ1Y3RvciIsImdldCIsIlByb21pc2UiLCJyZXNvbHZlIiwicHV0IiwiZGVsIiwiY2xlYXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBTyxNQUFNQSxnQkFBTixDQUF1QjtBQUM1QkMsRUFBQUEsV0FBVyxHQUFHLENBQUU7O0FBRWhCQyxFQUFBQSxHQUFHLEdBQUc7QUFDSixXQUFPLElBQUlDLE9BQUosQ0FBWUMsT0FBTyxJQUFJO0FBQzVCLGFBQU9BLE9BQU8sQ0FBQyxJQUFELENBQWQ7QUFDRCxLQUZNLENBQVA7QUFHRDs7QUFFREMsRUFBQUEsR0FBRyxHQUFHO0FBQ0osV0FBT0YsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFREUsRUFBQUEsR0FBRyxHQUFHO0FBQ0osV0FBT0gsT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFFREcsRUFBQUEsS0FBSyxHQUFHO0FBQ04sV0FBT0osT0FBTyxDQUFDQyxPQUFSLEVBQVA7QUFDRDs7QUFuQjJCOzs7ZUFzQmZKLGdCIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNsYXNzIE51bGxDYWNoZUFkYXB0ZXIge1xuICBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgZ2V0KCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgIH0pO1xuICB9XG5cbiAgcHV0KCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGRlbCgpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTnVsbENhY2hlQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Cache/RedisCacheAdapter/KeyPromiseQueue.js b/lib/Adapters/Cache/RedisCacheAdapter/KeyPromiseQueue.js deleted file mode 100644 index d4303d8803..0000000000 --- a/lib/Adapters/Cache/RedisCacheAdapter/KeyPromiseQueue.js +++ /dev/null @@ -1,59 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.KeyPromiseQueue = void 0; - -// KeyPromiseQueue is a simple promise queue -// used to queue operations per key basis. -// Once the tail promise in the key-queue fulfills, -// the chain on that key will be cleared. -class KeyPromiseQueue { - constructor() { - this.queue = {}; - } - - enqueue(key, operation) { - const tuple = this.beforeOp(key); - const toAwait = tuple[1]; - const nextOperation = toAwait.then(operation); - const wrappedOperation = nextOperation.then(result => { - this.afterOp(key); - return result; - }); - tuple[1] = wrappedOperation; - return wrappedOperation; - } - - beforeOp(key) { - let tuple = this.queue[key]; - - if (!tuple) { - tuple = [0, Promise.resolve()]; - this.queue[key] = tuple; - } - - tuple[0]++; - return tuple; - } - - afterOp(key) { - const tuple = this.queue[key]; - - if (!tuple) { - return; - } - - tuple[0]--; - - if (tuple[0] <= 0) { - delete this.queue[key]; - return; - } - } - -} - -exports.KeyPromiseQueue = KeyPromiseQueue; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9SZWRpc0NhY2hlQWRhcHRlci9LZXlQcm9taXNlUXVldWUuanMiXSwibmFtZXMiOlsiS2V5UHJvbWlzZVF1ZXVlIiwiY29uc3RydWN0b3IiLCJxdWV1ZSIsImVucXVldWUiLCJrZXkiLCJvcGVyYXRpb24iLCJ0dXBsZSIsImJlZm9yZU9wIiwidG9Bd2FpdCIsIm5leHRPcGVyYXRpb24iLCJ0aGVuIiwid3JhcHBlZE9wZXJhdGlvbiIsInJlc3VsdCIsImFmdGVyT3AiLCJQcm9taXNlIiwicmVzb2x2ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTUEsZUFBTixDQUFzQjtBQUMzQkMsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxHQUFhLEVBQWI7QUFDRDs7QUFFREMsRUFBQUEsT0FBTyxDQUFDQyxHQUFELEVBQU1DLFNBQU4sRUFBaUI7QUFDdEIsVUFBTUMsS0FBSyxHQUFHLEtBQUtDLFFBQUwsQ0FBY0gsR0FBZCxDQUFkO0FBQ0EsVUFBTUksT0FBTyxHQUFHRixLQUFLLENBQUMsQ0FBRCxDQUFyQjtBQUNBLFVBQU1HLGFBQWEsR0FBR0QsT0FBTyxDQUFDRSxJQUFSLENBQWFMLFNBQWIsQ0FBdEI7QUFDQSxVQUFNTSxnQkFBZ0IsR0FBR0YsYUFBYSxDQUFDQyxJQUFkLENBQW1CRSxNQUFNLElBQUk7QUFDcEQsV0FBS0MsT0FBTCxDQUFhVCxHQUFiO0FBQ0EsYUFBT1EsTUFBUDtBQUNELEtBSHdCLENBQXpCO0FBSUFOLElBQUFBLEtBQUssQ0FBQyxDQUFELENBQUwsR0FBV0ssZ0JBQVg7QUFDQSxXQUFPQSxnQkFBUDtBQUNEOztBQUVESixFQUFBQSxRQUFRLENBQUNILEdBQUQsRUFBTTtBQUNaLFFBQUlFLEtBQUssR0FBRyxLQUFLSixLQUFMLENBQVdFLEdBQVgsQ0FBWjs7QUFDQSxRQUFJLENBQUNFLEtBQUwsRUFBWTtBQUNWQSxNQUFBQSxLQUFLLEdBQUcsQ0FBQyxDQUFELEVBQUlRLE9BQU8sQ0FBQ0MsT0FBUixFQUFKLENBQVI7QUFDQSxXQUFLYixLQUFMLENBQVdFLEdBQVgsSUFBa0JFLEtBQWxCO0FBQ0Q7O0FBQ0RBLElBQUFBLEtBQUssQ0FBQyxDQUFELENBQUw7QUFDQSxXQUFPQSxLQUFQO0FBQ0Q7O0FBRURPLEVBQUFBLE9BQU8sQ0FBQ1QsR0FBRCxFQUFNO0FBQ1gsVUFBTUUsS0FBSyxHQUFHLEtBQUtKLEtBQUwsQ0FBV0UsR0FBWCxDQUFkOztBQUNBLFFBQUksQ0FBQ0UsS0FBTCxFQUFZO0FBQ1Y7QUFDRDs7QUFDREEsSUFBQUEsS0FBSyxDQUFDLENBQUQsQ0FBTDs7QUFDQSxRQUFJQSxLQUFLLENBQUMsQ0FBRCxDQUFMLElBQVksQ0FBaEIsRUFBbUI7QUFDakIsYUFBTyxLQUFLSixLQUFMLENBQVdFLEdBQVgsQ0FBUDtBQUNBO0FBQ0Q7QUFDRjs7QUFyQzBCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gS2V5UHJvbWlzZVF1ZXVlIGlzIGEgc2ltcGxlIHByb21pc2UgcXVldWVcbi8vIHVzZWQgdG8gcXVldWUgb3BlcmF0aW9ucyBwZXIga2V5IGJhc2lzLlxuLy8gT25jZSB0aGUgdGFpbCBwcm9taXNlIGluIHRoZSBrZXktcXVldWUgZnVsZmlsbHMsXG4vLyB0aGUgY2hhaW4gb24gdGhhdCBrZXkgd2lsbCBiZSBjbGVhcmVkLlxuZXhwb3J0IGNsYXNzIEtleVByb21pc2VRdWV1ZSB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMucXVldWUgPSB7fTtcbiAgfVxuXG4gIGVucXVldWUoa2V5LCBvcGVyYXRpb24pIHtcbiAgICBjb25zdCB0dXBsZSA9IHRoaXMuYmVmb3JlT3Aoa2V5KTtcbiAgICBjb25zdCB0b0F3YWl0ID0gdHVwbGVbMV07XG4gICAgY29uc3QgbmV4dE9wZXJhdGlvbiA9IHRvQXdhaXQudGhlbihvcGVyYXRpb24pO1xuICAgIGNvbnN0IHdyYXBwZWRPcGVyYXRpb24gPSBuZXh0T3BlcmF0aW9uLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgIHRoaXMuYWZ0ZXJPcChrZXkpO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KTtcbiAgICB0dXBsZVsxXSA9IHdyYXBwZWRPcGVyYXRpb247XG4gICAgcmV0dXJuIHdyYXBwZWRPcGVyYXRpb247XG4gIH1cblxuICBiZWZvcmVPcChrZXkpIHtcbiAgICBsZXQgdHVwbGUgPSB0aGlzLnF1ZXVlW2tleV07XG4gICAgaWYgKCF0dXBsZSkge1xuICAgICAgdHVwbGUgPSBbMCwgUHJvbWlzZS5yZXNvbHZlKCldO1xuICAgICAgdGhpcy5xdWV1ZVtrZXldID0gdHVwbGU7XG4gICAgfVxuICAgIHR1cGxlWzBdKys7XG4gICAgcmV0dXJuIHR1cGxlO1xuICB9XG5cbiAgYWZ0ZXJPcChrZXkpIHtcbiAgICBjb25zdCB0dXBsZSA9IHRoaXMucXVldWVba2V5XTtcbiAgICBpZiAoIXR1cGxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHR1cGxlWzBdLS07XG4gICAgaWYgKHR1cGxlWzBdIDw9IDApIHtcbiAgICAgIGRlbGV0ZSB0aGlzLnF1ZXVlW2tleV07XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Cache/RedisCacheAdapter/index.js b/lib/Adapters/Cache/RedisCacheAdapter/index.js deleted file mode 100644 index 7cf7f4e3e1..0000000000 --- a/lib/Adapters/Cache/RedisCacheAdapter/index.js +++ /dev/null @@ -1,130 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.RedisCacheAdapter = void 0; - -var _redis = _interopRequireDefault(require("redis")); - -var _logger = _interopRequireDefault(require("../../../logger")); - -var _KeyPromiseQueue = require("./KeyPromiseQueue"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const DEFAULT_REDIS_TTL = 30 * 1000; // 30 seconds in milliseconds - -const FLUSH_DB_KEY = '__flush_db__'; - -function debug() { - _logger.default.debug.apply(_logger.default, ['RedisCacheAdapter', ...arguments]); -} - -const isValidTTL = ttl => typeof ttl === 'number' && ttl > 0; - -class RedisCacheAdapter { - constructor(redisCtx, ttl = DEFAULT_REDIS_TTL) { - this.ttl = isValidTTL(ttl) ? ttl : DEFAULT_REDIS_TTL; - this.client = _redis.default.createClient(redisCtx); - this.queue = new _KeyPromiseQueue.KeyPromiseQueue(); - } - - handleShutdown() { - if (!this.client) { - return Promise.resolve(); - } - - return new Promise(resolve => { - this.client.quit(err => { - if (err) { - _logger.default.error('RedisCacheAdapter error on shutdown', { - error: err - }); - } - - resolve(); - }); - }); - } - - get(key) { - debug('get', key); - return this.queue.enqueue(key, () => new Promise(resolve => { - this.client.get(key, function (err, res) { - debug('-> get', key, res); - - if (!res) { - return resolve(null); - } - - resolve(JSON.parse(res)); - }); - })); - } - - put(key, value, ttl = this.ttl) { - value = JSON.stringify(value); - debug('put', key, value, ttl); - - if (ttl === 0) { - // ttl of zero is a logical no-op, but redis cannot set expire time of zero - return this.queue.enqueue(key, () => Promise.resolve()); - } - - if (ttl === Infinity) { - return this.queue.enqueue(key, () => new Promise(resolve => { - this.client.set(key, value, function () { - resolve(); - }); - })); - } - - if (!isValidTTL(ttl)) { - ttl = this.ttl; - } - - return this.queue.enqueue(key, () => new Promise(resolve => { - this.client.psetex(key, ttl, value, function () { - resolve(); - }); - })); - } - - del(key) { - debug('del', key); - return this.queue.enqueue(key, () => new Promise(resolve => { - this.client.del(key, function () { - resolve(); - }); - })); - } - - clear() { - debug('clear'); - return this.queue.enqueue(FLUSH_DB_KEY, () => new Promise(resolve => { - this.client.flushdb(function () { - resolve(); - }); - })); - } // Used for testing - - - async getAllKeys() { - return new Promise((resolve, reject) => { - this.client.keys('*', (err, keys) => { - if (err) { - reject(err); - } else { - resolve(keys); - } - }); - }); - } - -} - -exports.RedisCacheAdapter = RedisCacheAdapter; -var _default = RedisCacheAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9DYWNoZS9SZWRpc0NhY2hlQWRhcHRlci9pbmRleC5qcyJdLCJuYW1lcyI6WyJERUZBVUxUX1JFRElTX1RUTCIsIkZMVVNIX0RCX0tFWSIsImRlYnVnIiwibG9nZ2VyIiwiYXBwbHkiLCJhcmd1bWVudHMiLCJpc1ZhbGlkVFRMIiwidHRsIiwiUmVkaXNDYWNoZUFkYXB0ZXIiLCJjb25zdHJ1Y3RvciIsInJlZGlzQ3R4IiwiY2xpZW50IiwicmVkaXMiLCJjcmVhdGVDbGllbnQiLCJxdWV1ZSIsIktleVByb21pc2VRdWV1ZSIsImhhbmRsZVNodXRkb3duIiwiUHJvbWlzZSIsInJlc29sdmUiLCJxdWl0IiwiZXJyIiwiZXJyb3IiLCJnZXQiLCJrZXkiLCJlbnF1ZXVlIiwicmVzIiwiSlNPTiIsInBhcnNlIiwicHV0IiwidmFsdWUiLCJzdHJpbmdpZnkiLCJJbmZpbml0eSIsInNldCIsInBzZXRleCIsImRlbCIsImNsZWFyIiwiZmx1c2hkYiIsImdldEFsbEtleXMiLCJyZWplY3QiLCJrZXlzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxNQUFNQSxpQkFBaUIsR0FBRyxLQUFLLElBQS9CLEMsQ0FBcUM7O0FBQ3JDLE1BQU1DLFlBQVksR0FBRyxjQUFyQjs7QUFFQSxTQUFTQyxLQUFULEdBQWlCO0FBQ2ZDLGtCQUFPRCxLQUFQLENBQWFFLEtBQWIsQ0FBbUJELGVBQW5CLEVBQTJCLENBQUMsbUJBQUQsRUFBc0IsR0FBR0UsU0FBekIsQ0FBM0I7QUFDRDs7QUFFRCxNQUFNQyxVQUFVLEdBQUdDLEdBQUcsSUFBSSxPQUFPQSxHQUFQLEtBQWUsUUFBZixJQUEyQkEsR0FBRyxHQUFHLENBQTNEOztBQUVPLE1BQU1DLGlCQUFOLENBQXdCO0FBQzdCQyxFQUFBQSxXQUFXLENBQUNDLFFBQUQsRUFBV0gsR0FBRyxHQUFHUCxpQkFBakIsRUFBb0M7QUFDN0MsU0FBS08sR0FBTCxHQUFXRCxV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Q1gsR0FBRCxFQUFNO0FBQ1ByQixJQUFBQSxLQUFLLENBQUMsS0FBRCxFQUFRcUIsR0FBUixDQUFMO0FBQ0EsV0FBTyxLQUFLVCxLQUFMLENBQVdVLE9BQVgsQ0FDTEQsR0FESyxFQUVMLE1BQ0UsSUFBSU4sT0FBSixDQUFZQyxPQUFPLElBQUk7QUFDckIsV0FBS1AsTUFBTCxDQUFZdUIsR0FBWixDQUFnQlgsR0FBaEIsRUFBcUIsWUFBWTtBQUMvQkwsUUFBQUEsT0FBTztBQUNSLE9BRkQ7QUFHRCxLQUpELENBSEcsQ0FBUDtBQVNEOztBQUVEaUIsRUFBQUEsS0FBSyxHQUFHO0FBQ05qQyxJQUFBQSxLQUFLLENBQUMsT0FBRCxDQUFMO0FBQ0EsV0FBTyxLQUFLWSxLQUFMLENBQVdVLE9BQVgsQ0FDTHZCLFlBREssRUFFTCxNQUNFLElBQUlnQixPQUFKLENBQVlDLE9BQU8sSUFBSTtBQUNyQixXQUFLUCxNQUFMLENBQVl5QixPQUFaLENBQW9CLFlBQVk7QUFDOUJsQixRQUFBQSxPQUFPO0FBQ1IsT0FGRDtBQUdELEtBSkQsQ0FIRyxDQUFQO0FBU0QsR0FsRzRCLENBb0c3Qjs7O0FBQ0EsUUFBTW1CLFVBQU4sR0FBbUI7QUFDakIsV0FBTyxJQUFJcEIsT0FBSixDQUFZLENBQUNDLE9BQUQsRUFBVW9CLE1BQVYsS0FBcUI7QUFDdEMsV0FBSzNCLE1BQUwsQ0FBWTRCLElBQVosQ0FBaUIsR0FBakIsRUFBc0IsQ0FBQ25CLEdBQUQsRUFBTW1CLElBQU4sS0FBZTtBQUNuQyxZQUFJbkIsR0FBSixFQUFTO0FBQ1BrQixVQUFBQSxNQUFNLENBQUNsQixHQUFELENBQU47QUFDRCxTQUZELE1BRU87QUFDTEYsVUFBQUEsT0FBTyxDQUFDcUIsSUFBRCxDQUFQO0FBQ0Q7QUFDRixPQU5EO0FBT0QsS0FSTSxDQUFQO0FBU0Q7O0FBL0c0Qjs7O2VBa0hoQi9CLGlCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHJlZGlzIGZyb20gJ3JlZGlzJztcbmltcG9ydCBsb2dnZXIgZnJvbSAnLi4vLi4vLi4vbG9nZ2VyJztcbmltcG9ydCB7IEtleVByb21pc2VRdWV1ZSB9IGZyb20gJy4vS2V5UHJvbWlzZVF1ZXVlJztcblxuY29uc3QgREVGQVVMVF9SRURJU19UVEwgPSAzMCAqIDEwMDA7IC8vIDMwIHNlY29uZHMgaW4gbWlsbGlzZWNvbmRzXG5jb25zdCBGTFVTSF9EQl9LRVkgPSAnX19mbHVzaF9kYl9fJztcblxuZnVuY3Rpb24gZGVidWcoKSB7XG4gIGxvZ2dlci5kZWJ1Zy5hcHBseShsb2dnZXIsIFsnUmVkaXNDYWNoZUFkYXB0ZXInLCAuLi5hcmd1bWVudHNdKTtcbn1cblxuY29uc3QgaXNWYWxpZFRUTCA9IHR0bCA9PiB0eXBlb2YgdHRsID09PSAnbnVtYmVyJyAmJiB0dGwgPiAwO1xuXG5leHBvcnQgY2xhc3MgUmVkaXNDYWNoZUFkYXB0ZXIge1xuICBjb25zdHJ1Y3RvcihyZWRpc0N0eCwgdHRsID0gREVGQVVMVF9SRURJU19UVEwpIHtcbiAgICB0aGlzLnR0bCA9IGlzVmFsaWRUVEwodHRsKSA/IHR0bCA6IERFRkFVTFRfUkVESVNfVFRMO1xuICAgIHRoaXMuY2xpZW50ID0gcmVkaXMuY3JlYXRlQ2xpZW50KHJlZGlzQ3R4KTtcbiAgICB0aGlzLnF1ZXVlID0gbmV3IEtleVByb21pc2VRdWV1ZSgpO1xuICB9XG5cbiAgaGFuZGxlU2h1dGRvd24oKSB7XG4gICAgaWYgKCF0aGlzLmNsaWVudCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICB0aGlzLmNsaWVudC5xdWl0KGVyciA9PiB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoJ1JlZGlzQ2FjaGVBZGFwdGVyIGVycm9yIG9uIHNodXRkb3duJywgeyBlcnJvcjogZXJyIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0KGtleSkge1xuICAgIGRlYnVnKCdnZXQnLCBrZXkpO1xuICAgIHJldHVybiB0aGlzLnF1ZXVlLmVucXVldWUoXG4gICAgICBrZXksXG4gICAgICAoKSA9PlxuICAgICAgICBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgICAgICB0aGlzLmNsaWVudC5nZXQoa2V5LCBmdW5jdGlvbiAoZXJyLCByZXMpIHtcbiAgICAgICAgICAgIGRlYnVnKCctPiBnZXQnLCBrZXksIHJlcyk7XG4gICAgICAgICAgICBpZiAoIXJlcykge1xuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShudWxsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc29sdmUoSlNPTi5wYXJzZShyZXMpKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgcHV0KGtleSwgdmFsdWUsIHR0bCA9IHRoaXMudHRsKSB7XG4gICAgdmFsdWUgPSBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG4gICAgZGVidWcoJ3B1dCcsIGtleSwgdmFsdWUsIHR0bCk7XG5cbiAgICBpZiAodHRsID09PSAwKSB7XG4gICAgICAvLyB0dGwgb2YgemVybyBpcyBhIGxvZ2ljYWwgbm8tb3AsIGJ1dCByZWRpcyBjYW5ub3Qgc2V0IGV4cGlyZSB0aW1lIG9mIHplcm9cbiAgICAgIHJldHVybiB0aGlzLnF1ZXVlLmVucXVldWUoa2V5LCAoKSA9PiBQcm9taXNlLnJlc29sdmUoKSk7XG4gICAgfVxuXG4gICAgaWYgKHR0bCA9PT0gSW5maW5pdHkpIHtcbiAgICAgIHJldHVybiB0aGlzLnF1ZXVlLmVucXVldWUoXG4gICAgICAgIGtleSxcbiAgICAgICAgKCkgPT5cbiAgICAgICAgICBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2xpZW50LnNldChrZXksIHZhbHVlLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghaXNWYWxpZFRUTCh0dGwpKSB7XG4gICAgICB0dGwgPSB0aGlzLnR0bDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5xdWV1ZS5lbnF1ZXVlKFxuICAgICAga2V5LFxuICAgICAgKCkgPT5cbiAgICAgICAgbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgdGhpcy5jbGllbnQucHNldGV4KGtleSwgdHRsLCB2YWx1ZSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cblxuICBkZWwoa2V5KSB7XG4gICAgZGVidWcoJ2RlbCcsIGtleSk7XG4gICAgcmV0dXJuIHRoaXMucXVldWUuZW5xdWV1ZShcbiAgICAgIGtleSxcbiAgICAgICgpID0+XG4gICAgICAgIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICAgIHRoaXMuY2xpZW50LmRlbChrZXksIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgY2xlYXIoKSB7XG4gICAgZGVidWcoJ2NsZWFyJyk7XG4gICAgcmV0dXJuIHRoaXMucXVldWUuZW5xdWV1ZShcbiAgICAgIEZMVVNIX0RCX0tFWSxcbiAgICAgICgpID0+XG4gICAgICAgIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICAgIHRoaXMuY2xpZW50LmZsdXNoZGIoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvLyBVc2VkIGZvciB0ZXN0aW5nXG4gIGFzeW5jIGdldEFsbEtleXMoKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50LmtleXMoJyonLCAoZXJyLCBrZXlzKSA9PiB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXNvbHZlKGtleXMpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBSZWRpc0NhY2hlQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Email/MailAdapter.js b/lib/Adapters/Email/MailAdapter.js deleted file mode 100644 index a1b3044451..0000000000 --- a/lib/Adapters/Email/MailAdapter.js +++ /dev/null @@ -1,40 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.MailAdapter = void 0; - -/*eslint no-unused-vars: "off"*/ - -/** - * @module Adapters - */ - -/** - * @interface MailAdapter - * Mail Adapter prototype - * A MailAdapter should implement at least sendMail() - */ -class MailAdapter { - /** - * A method for sending mail - * @param options would have the parameters - * - to: the recipient - * - text: the raw text of the message - * - subject: the subject of the email - */ - sendMail(options) {} - /* You can implement those methods if you want - * to provide HTML templates etc... - */ - // sendVerificationEmail({ link, appName, user }) {} - // sendPasswordResetEmail({ link, appName, user }) {} - - -} - -exports.MailAdapter = MailAdapter; -var _default = MailAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9FbWFpbC9NYWlsQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJNYWlsQWRhcHRlciIsInNlbmRNYWlsIiwib3B0aW9ucyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBO0FBQ0E7QUFDQTs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTUEsV0FBTixDQUFrQjtBQUN2QjtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNFQyxFQUFBQSxRQUFRLENBQUNDLE9BQUQsRUFBVSxDQUFFO0FBRXBCO0FBQ0Y7QUFDQTtBQUNFO0FBQ0E7OztBQWR1Qjs7O2VBaUJWRixXIiwic291cmNlc0NvbnRlbnQiOlsiLyplc2xpbnQgbm8tdW51c2VkLXZhcnM6IFwib2ZmXCIqL1xuLyoqXG4gKiBAbW9kdWxlIEFkYXB0ZXJzXG4gKi9cbi8qKlxuICogQGludGVyZmFjZSBNYWlsQWRhcHRlclxuICogTWFpbCBBZGFwdGVyIHByb3RvdHlwZVxuICogQSBNYWlsQWRhcHRlciBzaG91bGQgaW1wbGVtZW50IGF0IGxlYXN0IHNlbmRNYWlsKClcbiAqL1xuZXhwb3J0IGNsYXNzIE1haWxBZGFwdGVyIHtcbiAgLyoqXG4gICAqIEEgbWV0aG9kIGZvciBzZW5kaW5nIG1haWxcbiAgICogQHBhcmFtIG9wdGlvbnMgd291bGQgaGF2ZSB0aGUgcGFyYW1ldGVyc1xuICAgKiAtIHRvOiB0aGUgcmVjaXBpZW50XG4gICAqIC0gdGV4dDogdGhlIHJhdyB0ZXh0IG9mIHRoZSBtZXNzYWdlXG4gICAqIC0gc3ViamVjdDogdGhlIHN1YmplY3Qgb2YgdGhlIGVtYWlsXG4gICAqL1xuICBzZW5kTWFpbChvcHRpb25zKSB7fVxuXG4gIC8qIFlvdSBjYW4gaW1wbGVtZW50IHRob3NlIG1ldGhvZHMgaWYgeW91IHdhbnRcbiAgICogdG8gcHJvdmlkZSBIVE1MIHRlbXBsYXRlcyBldGMuLi5cbiAgICovXG4gIC8vIHNlbmRWZXJpZmljYXRpb25FbWFpbCh7IGxpbmssIGFwcE5hbWUsIHVzZXIgfSkge31cbiAgLy8gc2VuZFBhc3N3b3JkUmVzZXRFbWFpbCh7IGxpbmssIGFwcE5hbWUsIHVzZXIgfSkge31cbn1cblxuZXhwb3J0IGRlZmF1bHQgTWFpbEFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Files/FilesAdapter.js b/lib/Adapters/Files/FilesAdapter.js deleted file mode 100644 index 112ca8202e..0000000000 --- a/lib/Adapters/Files/FilesAdapter.js +++ /dev/null @@ -1,136 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.validateFilename = validateFilename; -exports.default = exports.FilesAdapter = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/*eslint no-unused-vars: "off"*/ -// Files Adapter -// -// Allows you to change the file storage mechanism. -// -// Adapter classes must implement the following functions: -// * createFile(filename, data, contentType) -// * deleteFile(filename) -// * getFileData(filename) -// * getFileLocation(config, filename) -// Adapter classes should implement the following functions: -// * validateFilename(filename) -// * handleFileStream(filename, req, res, contentType) -// -// Default is GridFSBucketAdapter, which requires mongo -// and for the API server to be using the DatabaseController with Mongo -// database adapter. - -/** - * @module Adapters - */ - -/** - * @interface FilesAdapter - */ -class FilesAdapter { - /** Responsible for storing the file in order to be retrieved later by its filename - * - * @param {string} filename - the filename to save - * @param {*} data - the buffer of data from the file - * @param {string} contentType - the supposed contentType - * @discussion the contentType can be undefined if the controller was not able to determine it - * @param {object} options - (Optional) options to be passed to file adapter (S3 File Adapter Only) - * - tags: object containing key value pairs that will be stored with file - * - metadata: object containing key value pairs that will be sotred with file (https://docs.aws.amazon.com/AmazonS3/latest/user-guide/add-object-metadata.html) - * @discussion options are not supported by all file adapters. Check the your adapter's documentation for compatibility - * - * @return {Promise} a promise that should fail if the storage didn't succeed - */ - createFile(filename, data, contentType, options) {} - /** Responsible for deleting the specified file - * - * @param {string} filename - the filename to delete - * - * @return {Promise} a promise that should fail if the deletion didn't succeed - */ - - - deleteFile(filename) {} - /** Responsible for retrieving the data of the specified file - * - * @param {string} filename - the name of file to retrieve - * - * @return {Promise} a promise that should pass with the file data or fail on error - */ - - - getFileData(filename) {} - /** Returns an absolute URL where the file can be accessed - * - * @param {Config} config - server configuration - * @param {string} filename - * - * @return {string} Absolute URL - */ - - - getFileLocation(config, filename) {} - /** Validate a filename for this adapter type - * - * @param {string} filename - * - * @returns {null|Parse.Error} null if there are no errors - */ - // validateFilename(filename: string): ?Parse.Error {} - - /** Handles Byte-Range Requests for Streaming - * - * @param {string} filename - * @param {object} req - * @param {object} res - * @param {string} contentType - * - * @returns {Promise} Data for byte range - */ - // handleFileStream(filename: string, res: any, req: any, contentType: string): Promise - - /** Responsible for retrieving metadata and tags - * - * @param {string} filename - the filename to retrieve metadata - * - * @return {Promise} a promise that should pass with metadata - */ - // getMetadata(filename: string): Promise {} - - -} -/** - * Simple filename validation - * - * @param filename - * @returns {null|Parse.Error} - */ - - -exports.FilesAdapter = FilesAdapter; - -function validateFilename(filename) { - if (filename.length > 128) { - return new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename too long.'); - } - - const regx = /^[_a-zA-Z0-9][a-zA-Z0-9@. ~_-]*$/; - - if (!filename.match(regx)) { - return new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename contains invalid characters.'); - } - - return null; -} - -var _default = FilesAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9GaWxlcy9GaWxlc0FkYXB0ZXIuanMiXSwibmFtZXMiOlsiRmlsZXNBZGFwdGVyIiwiY3JlYXRlRmlsZSIsImZpbGVuYW1lIiwiZGF0YSIsImNvbnRlbnRUeXBlIiwib3B0aW9ucyIsImRlbGV0ZUZpbGUiLCJnZXRGaWxlRGF0YSIsImdldEZpbGVMb2NhdGlvbiIsImNvbmZpZyIsInZhbGlkYXRlRmlsZW5hbWUiLCJsZW5ndGgiLCJQYXJzZSIsIkVycm9yIiwiSU5WQUxJRF9GSUxFX05BTUUiLCJyZWd4IiwibWF0Y2giXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBbUJBOzs7O0FBbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBSUE7QUFDQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU1BLFlBQU4sQ0FBbUI7QUFDeEI7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDRUMsRUFBQUEsVUFBVSxDQUFDQyxRQUFELEVBQW1CQyxJQUFuQixFQUF5QkMsV0FBekIsRUFBOENDLE9BQTlDLEVBQXdFLENBQUU7QUFFcEY7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDRUMsRUFBQUEsVUFBVSxDQUFDSixRQUFELEVBQTRCLENBQUU7QUFFeEM7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDRUssRUFBQUEsV0FBVyxDQUFDTCxRQUFELEVBQWlDLENBQUU7QUFFOUM7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNFTSxFQUFBQSxlQUFlLENBQUNDLE1BQUQsRUFBaUJQLFFBQWpCLEVBQTJDLENBQUU7QUFFNUQ7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0U7O0FBRUE7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0U7O0FBRUE7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0U7OztBQWxFd0I7QUFxRTFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFDTyxTQUFTUSxnQkFBVCxDQUEwQlIsUUFBMUIsRUFBa0Q7QUFDdkQsTUFBSUEsUUFBUSxDQUFDUyxNQUFULEdBQWtCLEdBQXRCLEVBQTJCO0FBQ3pCLFdBQU8sSUFBSUMsY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZQyxpQkFBNUIsRUFBK0Msb0JBQS9DLENBQVA7QUFDRDs7QUFFRCxRQUFNQyxJQUFJLEdBQUcsa0NBQWI7O0FBQ0EsTUFBSSxDQUFDYixRQUFRLENBQUNjLEtBQVQsQ0FBZUQsSUFBZixDQUFMLEVBQTJCO0FBQ3pCLFdBQU8sSUFBSUgsY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZQyxpQkFBNUIsRUFBK0MsdUNBQS9DLENBQVA7QUFDRDs7QUFDRCxTQUFPLElBQVA7QUFDRDs7ZUFFY2QsWSIsInNvdXJjZXNDb250ZW50IjpbIi8qZXNsaW50IG5vLXVudXNlZC12YXJzOiBcIm9mZlwiKi9cbi8vIEZpbGVzIEFkYXB0ZXJcbi8vXG4vLyBBbGxvd3MgeW91IHRvIGNoYW5nZSB0aGUgZmlsZSBzdG9yYWdlIG1lY2hhbmlzbS5cbi8vXG4vLyBBZGFwdGVyIGNsYXNzZXMgbXVzdCBpbXBsZW1lbnQgdGhlIGZvbGxvd2luZyBmdW5jdGlvbnM6XG4vLyAqIGNyZWF0ZUZpbGUoZmlsZW5hbWUsIGRhdGEsIGNvbnRlbnRUeXBlKVxuLy8gKiBkZWxldGVGaWxlKGZpbGVuYW1lKVxuLy8gKiBnZXRGaWxlRGF0YShmaWxlbmFtZSlcbi8vICogZ2V0RmlsZUxvY2F0aW9uKGNvbmZpZywgZmlsZW5hbWUpXG4vLyBBZGFwdGVyIGNsYXNzZXMgc2hvdWxkIGltcGxlbWVudCB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uczpcbi8vICogdmFsaWRhdGVGaWxlbmFtZShmaWxlbmFtZSlcbi8vICogaGFuZGxlRmlsZVN0cmVhbShmaWxlbmFtZSwgcmVxLCByZXMsIGNvbnRlbnRUeXBlKVxuLy9cbi8vIERlZmF1bHQgaXMgR3JpZEZTQnVja2V0QWRhcHRlciwgd2hpY2ggcmVxdWlyZXMgbW9uZ29cbi8vIGFuZCBmb3IgdGhlIEFQSSBzZXJ2ZXIgdG8gYmUgdXNpbmcgdGhlIERhdGFiYXNlQ29udHJvbGxlciB3aXRoIE1vbmdvXG4vLyBkYXRhYmFzZSBhZGFwdGVyLlxuXG5pbXBvcnQgdHlwZSB7IENvbmZpZyB9IGZyb20gJy4uLy4uL0NvbmZpZyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG4vKipcbiAqIEBtb2R1bGUgQWRhcHRlcnNcbiAqL1xuLyoqXG4gKiBAaW50ZXJmYWNlIEZpbGVzQWRhcHRlclxuICovXG5leHBvcnQgY2xhc3MgRmlsZXNBZGFwdGVyIHtcbiAgLyoqIFJlc3BvbnNpYmxlIGZvciBzdG9yaW5nIHRoZSBmaWxlIGluIG9yZGVyIHRvIGJlIHJldHJpZXZlZCBsYXRlciBieSBpdHMgZmlsZW5hbWVcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gdGhlIGZpbGVuYW1lIHRvIHNhdmVcbiAgICogQHBhcmFtIHsqfSBkYXRhIC0gdGhlIGJ1ZmZlciBvZiBkYXRhIGZyb20gdGhlIGZpbGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNvbnRlbnRUeXBlIC0gdGhlIHN1cHBvc2VkIGNvbnRlbnRUeXBlXG4gICAqIEBkaXNjdXNzaW9uIHRoZSBjb250ZW50VHlwZSBjYW4gYmUgdW5kZWZpbmVkIGlmIHRoZSBjb250cm9sbGVyIHdhcyBub3QgYWJsZSB0byBkZXRlcm1pbmUgaXRcbiAgICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnMgLSAoT3B0aW9uYWwpIG9wdGlvbnMgdG8gYmUgcGFzc2VkIHRvIGZpbGUgYWRhcHRlciAoUzMgRmlsZSBBZGFwdGVyIE9ubHkpXG4gICAqIC0gdGFnczogb2JqZWN0IGNvbnRhaW5pbmcga2V5IHZhbHVlIHBhaXJzIHRoYXQgd2lsbCBiZSBzdG9yZWQgd2l0aCBmaWxlXG4gICAqIC0gbWV0YWRhdGE6IG9iamVjdCBjb250YWluaW5nIGtleSB2YWx1ZSBwYWlycyB0aGF0IHdpbGwgYmUgc290cmVkIHdpdGggZmlsZSAoaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvblMzL2xhdGVzdC91c2VyLWd1aWRlL2FkZC1vYmplY3QtbWV0YWRhdGEuaHRtbClcbiAgICogQGRpc2N1c3Npb24gb3B0aW9ucyBhcmUgbm90IHN1cHBvcnRlZCBieSBhbGwgZmlsZSBhZGFwdGVycy4gQ2hlY2sgdGhlIHlvdXIgYWRhcHRlcidzIGRvY3VtZW50YXRpb24gZm9yIGNvbXBhdGliaWxpdHlcbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZX0gYSBwcm9taXNlIHRoYXQgc2hvdWxkIGZhaWwgaWYgdGhlIHN0b3JhZ2UgZGlkbid0IHN1Y2NlZWRcbiAgICovXG4gIGNyZWF0ZUZpbGUoZmlsZW5hbWU6IHN0cmluZywgZGF0YSwgY29udGVudFR5cGU6IHN0cmluZywgb3B0aW9uczogT2JqZWN0KTogUHJvbWlzZSB7fVxuXG4gIC8qKiBSZXNwb25zaWJsZSBmb3IgZGVsZXRpbmcgdGhlIHNwZWNpZmllZCBmaWxlXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIHRoZSBmaWxlbmFtZSB0byBkZWxldGVcbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZX0gYSBwcm9taXNlIHRoYXQgc2hvdWxkIGZhaWwgaWYgdGhlIGRlbGV0aW9uIGRpZG4ndCBzdWNjZWVkXG4gICAqL1xuICBkZWxldGVGaWxlKGZpbGVuYW1lOiBzdHJpbmcpOiBQcm9taXNlIHt9XG5cbiAgLyoqIFJlc3BvbnNpYmxlIGZvciByZXRyaWV2aW5nIHRoZSBkYXRhIG9mIHRoZSBzcGVjaWZpZWQgZmlsZVxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSB0aGUgbmFtZSBvZiBmaWxlIHRvIHJldHJpZXZlXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IGEgcHJvbWlzZSB0aGF0IHNob3VsZCBwYXNzIHdpdGggdGhlIGZpbGUgZGF0YSBvciBmYWlsIG9uIGVycm9yXG4gICAqL1xuICBnZXRGaWxlRGF0YShmaWxlbmFtZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHt9XG5cbiAgLyoqIFJldHVybnMgYW4gYWJzb2x1dGUgVVJMIHdoZXJlIHRoZSBmaWxlIGNhbiBiZSBhY2Nlc3NlZFxuICAgKlxuICAgKiBAcGFyYW0ge0NvbmZpZ30gY29uZmlnIC0gc2VydmVyIGNvbmZpZ3VyYXRpb25cbiAgICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lXG4gICAqXG4gICAqIEByZXR1cm4ge3N0cmluZ30gQWJzb2x1dGUgVVJMXG4gICAqL1xuICBnZXRGaWxlTG9jYXRpb24oY29uZmlnOiBDb25maWcsIGZpbGVuYW1lOiBzdHJpbmcpOiBzdHJpbmcge31cblxuICAvKiogVmFsaWRhdGUgYSBmaWxlbmFtZSBmb3IgdGhpcyBhZGFwdGVyIHR5cGVcbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lXG4gICAqXG4gICAqIEByZXR1cm5zIHtudWxsfFBhcnNlLkVycm9yfSBudWxsIGlmIHRoZXJlIGFyZSBubyBlcnJvcnNcbiAgICovXG4gIC8vIHZhbGlkYXRlRmlsZW5hbWUoZmlsZW5hbWU6IHN0cmluZyk6ID9QYXJzZS5FcnJvciB7fVxuXG4gIC8qKiBIYW5kbGVzIEJ5dGUtUmFuZ2UgUmVxdWVzdHMgZm9yIFN0cmVhbWluZ1xuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWVcbiAgICogQHBhcmFtIHtvYmplY3R9IHJlcVxuICAgKiBAcGFyYW0ge29iamVjdH0gcmVzXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZW50VHlwZVxuICAgKlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gRGF0YSBmb3IgYnl0ZSByYW5nZVxuICAgKi9cbiAgLy8gaGFuZGxlRmlsZVN0cmVhbShmaWxlbmFtZTogc3RyaW5nLCByZXM6IGFueSwgcmVxOiBhbnksIGNvbnRlbnRUeXBlOiBzdHJpbmcpOiBQcm9taXNlXG5cbiAgLyoqIFJlc3BvbnNpYmxlIGZvciByZXRyaWV2aW5nIG1ldGFkYXRhIGFuZCB0YWdzXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIHRoZSBmaWxlbmFtZSB0byByZXRyaWV2ZSBtZXRhZGF0YVxuICAgKlxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBhIHByb21pc2UgdGhhdCBzaG91bGQgcGFzcyB3aXRoIG1ldGFkYXRhXG4gICAqL1xuICAvLyBnZXRNZXRhZGF0YShmaWxlbmFtZTogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHt9XG59XG5cbi8qKlxuICogU2ltcGxlIGZpbGVuYW1lIHZhbGlkYXRpb25cbiAqXG4gKiBAcGFyYW0gZmlsZW5hbWVcbiAqIEByZXR1cm5zIHtudWxsfFBhcnNlLkVycm9yfVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVGaWxlbmFtZShmaWxlbmFtZSk6ID9QYXJzZS5FcnJvciB7XG4gIGlmIChmaWxlbmFtZS5sZW5ndGggPiAxMjgpIHtcbiAgICByZXR1cm4gbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfRklMRV9OQU1FLCAnRmlsZW5hbWUgdG9vIGxvbmcuJyk7XG4gIH1cblxuICBjb25zdCByZWd4ID0gL15bX2EtekEtWjAtOV1bYS16QS1aMC05QC4gfl8tXSokLztcbiAgaWYgKCFmaWxlbmFtZS5tYXRjaChyZWd4KSkge1xuICAgIHJldHVybiBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9GSUxFX05BTUUsICdGaWxlbmFtZSBjb250YWlucyBpbnZhbGlkIGNoYXJhY3RlcnMuJyk7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbmV4cG9ydCBkZWZhdWx0IEZpbGVzQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Files/GridFSBucketAdapter.js b/lib/Adapters/Files/GridFSBucketAdapter.js deleted file mode 100644 index 352922c2e0..0000000000 --- a/lib/Adapters/Files/GridFSBucketAdapter.js +++ /dev/null @@ -1,273 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.GridFSBucketAdapter = void 0; - -var _mongodb = require("mongodb"); - -var _FilesAdapter = require("./FilesAdapter"); - -var _defaults = _interopRequireDefault(require("../../defaults")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - GridFSBucketAdapter - Stores files in Mongo using GridStore - Requires the database adapter to be based on mongoclient - - - */ -// -disable-next -const crypto = require('crypto'); - -class GridFSBucketAdapter extends _FilesAdapter.FilesAdapter { - constructor(mongoDatabaseURI = _defaults.default.DefaultMongoURI, mongoOptions = {}, encryptionKey = undefined) { - super(); - this._databaseURI = mongoDatabaseURI; - this._algorithm = 'aes-256-gcm'; - this._encryptionKey = encryptionKey !== undefined ? crypto.createHash('sha256').update(String(encryptionKey)).digest('base64').substr(0, 32) : null; - const defaultMongoOptions = { - useNewUrlParser: true, - useUnifiedTopology: true - }; - this._mongoOptions = Object.assign(defaultMongoOptions, mongoOptions); - } - - _connect() { - if (!this._connectionPromise) { - this._connectionPromise = _mongodb.MongoClient.connect(this._databaseURI, this._mongoOptions).then(client => { - this._client = client; - return client.db(client.s.options.dbName); - }); - } - - return this._connectionPromise; - } - - _getBucket() { - return this._connect().then(database => new _mongodb.GridFSBucket(database)); - } // For a given config object, filename, and data, store a file - // Returns a promise - - - async createFile(filename, data, contentType, options = {}) { - const bucket = await this._getBucket(); - const stream = await bucket.openUploadStream(filename, { - metadata: options.metadata - }); - - if (this._encryptionKey !== null) { - try { - const iv = crypto.randomBytes(16); - const cipher = crypto.createCipheriv(this._algorithm, this._encryptionKey, iv); - const encryptedResult = Buffer.concat([cipher.update(data), cipher.final(), iv, cipher.getAuthTag()]); - await stream.write(encryptedResult); - } catch (err) { - return new Promise((resolve, reject) => { - return reject(err); - }); - } - } else { - await stream.write(data); - } - - stream.end(); - return new Promise((resolve, reject) => { - stream.on('finish', resolve); - stream.on('error', reject); - }); - } - - async deleteFile(filename) { - const bucket = await this._getBucket(); - const documents = await bucket.find({ - filename - }).toArray(); - - if (documents.length === 0) { - throw new Error('FileNotFound'); - } - - return Promise.all(documents.map(doc => { - return bucket.delete(doc._id); - })); - } - - async getFileData(filename) { - const bucket = await this._getBucket(); - const stream = bucket.openDownloadStreamByName(filename); - stream.read(); - return new Promise((resolve, reject) => { - const chunks = []; - stream.on('data', data => { - chunks.push(data); - }); - stream.on('end', () => { - const data = Buffer.concat(chunks); - - if (this._encryptionKey !== null) { - try { - const authTagLocation = data.length - 16; - const ivLocation = data.length - 32; - const authTag = data.slice(authTagLocation); - const iv = data.slice(ivLocation, authTagLocation); - const encrypted = data.slice(0, ivLocation); - const decipher = crypto.createDecipheriv(this._algorithm, this._encryptionKey, iv); - decipher.setAuthTag(authTag); - const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]); - return resolve(decrypted); - } catch (err) { - return reject(err); - } - } - - resolve(data); - }); - stream.on('error', err => { - reject(err); - }); - }); - } - - async rotateEncryptionKey(options = {}) { - var fileNames = []; - var oldKeyFileAdapter = {}; - const bucket = await this._getBucket(); - - if (options.oldKey !== undefined) { - oldKeyFileAdapter = new GridFSBucketAdapter(this._databaseURI, this._mongoOptions, options.oldKey); - } else { - oldKeyFileAdapter = new GridFSBucketAdapter(this._databaseURI, this._mongoOptions); - } - - if (options.fileNames !== undefined) { - fileNames = options.fileNames; - } else { - const fileNamesIterator = await bucket.find().toArray(); - fileNamesIterator.forEach(file => { - fileNames.push(file.filename); - }); - } - - return new Promise(resolve => { - var fileNamesNotRotated = fileNames; - var fileNamesRotated = []; - var fileNameTotal = fileNames.length; - var fileNameIndex = 0; - fileNames.forEach(fileName => { - oldKeyFileAdapter.getFileData(fileName).then(plainTextData => { - //Overwrite file with data encrypted with new key - this.createFile(fileName, plainTextData).then(() => { - fileNamesRotated.push(fileName); - fileNamesNotRotated = fileNamesNotRotated.filter(function (value) { - return value !== fileName; - }); - fileNameIndex += 1; - - if (fileNameIndex == fileNameTotal) { - resolve({ - rotated: fileNamesRotated, - notRotated: fileNamesNotRotated - }); - } - }).catch(() => { - fileNameIndex += 1; - - if (fileNameIndex == fileNameTotal) { - resolve({ - rotated: fileNamesRotated, - notRotated: fileNamesNotRotated - }); - } - }); - }).catch(() => { - fileNameIndex += 1; - - if (fileNameIndex == fileNameTotal) { - resolve({ - rotated: fileNamesRotated, - notRotated: fileNamesNotRotated - }); - } - }); - }); - }); - } - - getFileLocation(config, filename) { - return config.mount + '/files/' + config.applicationId + '/' + encodeURIComponent(filename); - } - - async getMetadata(filename) { - const bucket = await this._getBucket(); - const files = await bucket.find({ - filename - }).toArray(); - - if (files.length === 0) { - return {}; - } - - const { - metadata - } = files[0]; - return { - metadata - }; - } - - async handleFileStream(filename, req, res, contentType) { - const bucket = await this._getBucket(); - const files = await bucket.find({ - filename - }).toArray(); - - if (files.length === 0) { - throw new Error('FileNotFound'); - } - - const parts = req.get('Range').replace(/bytes=/, '').split('-'); - const partialstart = parts[0]; - const partialend = parts[1]; - const start = parseInt(partialstart, 10); - const end = partialend ? parseInt(partialend, 10) : files[0].length - 1; - res.writeHead(206, { - 'Accept-Ranges': 'bytes', - 'Content-Length': end - start + 1, - 'Content-Range': 'bytes ' + start + '-' + end + '/' + files[0].length, - 'Content-Type': contentType - }); - const stream = bucket.openDownloadStreamByName(filename); - stream.start(start); - stream.on('data', chunk => { - res.write(chunk); - }); - stream.on('error', () => { - res.sendStatus(404); - }); - stream.on('end', () => { - res.end(); - }); - } - - handleShutdown() { - if (!this._client) { - return Promise.resolve(); - } - - return this._client.close(false); - } - - validateFilename(filename) { - return (0, _FilesAdapter.validateFilename)(filename); - } - -} - -exports.GridFSBucketAdapter = GridFSBucketAdapter; -var _default = GridFSBucketAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9GaWxlcy9HcmlkRlNCdWNrZXRBZGFwdGVyLmpzIl0sIm5hbWVzIjpbImNyeXB0byIsInJlcXVpcmUiLCJHcmlkRlNCdWNrZXRBZGFwdGVyIiwiRmlsZXNBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJtb25nb0RhdGFiYXNlVVJJIiwiZGVmYXVsdHMiLCJEZWZhdWx0TW9uZ29VUkkiLCJtb25nb09wdGlvbnMiLCJlbmNyeXB0aW9uS2V5IiwidW5kZWZpbmVkIiwiX2RhdGFiYXNlVVJJIiwiX2FsZ29yaXRobSIsIl9lbmNyeXB0aW9uS2V5IiwiY3JlYXRlSGFzaCIsInVwZGF0ZSIsIlN0cmluZyIsImRpZ2VzdCIsInN1YnN0ciIsImRlZmF1bHRNb25nb09wdGlvbnMiLCJ1c2VOZXdVcmxQYXJzZXIiLCJ1c2VVbmlmaWVkVG9wb2xvZ3kiLCJfbW9uZ29PcHRpb25zIiwiT2JqZWN0IiwiYXNzaWduIiwiX2Nvbm5lY3QiLCJfY29ubmVjdGlvblByb21pc2UiLCJNb25nb0NsaWVudCIsImNvbm5lY3QiLCJ0aGVuIiwiY2xpZW50IiwiX2NsaWVudCIsImRiIiwicyIsIm9wdGlvbnMiLCJkYk5hbWUiLCJfZ2V0QnVja2V0IiwiZGF0YWJhc2UiLCJHcmlkRlNCdWNrZXQiLCJjcmVhdGVGaWxlIiwiZmlsZW5hbWUiLCJkYXRhIiwiY29udGVudFR5cGUiLCJidWNrZXQiLCJzdHJlYW0iLCJvcGVuVXBsb2FkU3RyZWFtIiwibWV0YWRhdGEiLCJpdiIsInJhbmRvbUJ5dGVzIiwiY2lwaGVyIiwiY3JlYXRlQ2lwaGVyaXYiLCJlbmNyeXB0ZWRSZXN1bHQiLCJCdWZmZXIiLCJjb25jYXQiLCJmaW5hbCIsImdldEF1dGhUYWciLCJ3cml0ZSIsImVyciIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiZW5kIiwib24iLCJkZWxldGVGaWxlIiwiZG9jdW1lbnRzIiwiZmluZCIsInRvQXJyYXkiLCJsZW5ndGgiLCJFcnJvciIsImFsbCIsIm1hcCIsImRvYyIsImRlbGV0ZSIsIl9pZCIsImdldEZpbGVEYXRhIiwib3BlbkRvd25sb2FkU3RyZWFtQnlOYW1lIiwicmVhZCIsImNodW5rcyIsInB1c2giLCJhdXRoVGFnTG9jYXRpb24iLCJpdkxvY2F0aW9uIiwiYXV0aFRhZyIsInNsaWNlIiwiZW5jcnlwdGVkIiwiZGVjaXBoZXIiLCJjcmVhdGVEZWNpcGhlcml2Iiwic2V0QXV0aFRhZyIsImRlY3J5cHRlZCIsInJvdGF0ZUVuY3J5cHRpb25LZXkiLCJmaWxlTmFtZXMiLCJvbGRLZXlGaWxlQWRhcHRlciIsIm9sZEtleSIsImZpbGVOYW1lc0l0ZXJhdG9yIiwiZm9yRWFjaCIsImZpbGUiLCJmaWxlTmFtZXNOb3RSb3RhdGVkIiwiZmlsZU5hbWVzUm90YXRlZCIsImZpbGVOYW1lVG90YWwiLCJmaWxlTmFtZUluZGV4IiwiZmlsZU5hbWUiLCJwbGFpblRleHREYXRhIiwiZmlsdGVyIiwidmFsdWUiLCJyb3RhdGVkIiwibm90Um90YXRlZCIsImNhdGNoIiwiZ2V0RmlsZUxvY2F0aW9uIiwiY29uZmlnIiwibW91bnQiLCJhcHBsaWNhdGlvbklkIiwiZW5jb2RlVVJJQ29tcG9uZW50IiwiZ2V0TWV0YWRhdGEiLCJmaWxlcyIsImhhbmRsZUZpbGVTdHJlYW0iLCJyZXEiLCJyZXMiLCJwYXJ0cyIsImdldCIsInJlcGxhY2UiLCJzcGxpdCIsInBhcnRpYWxzdGFydCIsInBhcnRpYWxlbmQiLCJzdGFydCIsInBhcnNlSW50Iiwid3JpdGVIZWFkIiwiY2h1bmsiLCJzZW5kU3RhdHVzIiwiaGFuZGxlU2h1dGRvd24iLCJjbG9zZSIsInZhbGlkYXRlRmlsZW5hbWUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFTQTs7QUFDQTs7QUFDQTs7OztBQVhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUE7QUFJQSxNQUFNQSxNQUFNLEdBQUdDLE9BQU8sQ0FBQyxRQUFELENBQXRCOztBQUVPLE1BQU1DLG1CQUFOLFNBQWtDQywwQkFBbEMsQ0FBK0M7QUFN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QUk7QUFDekJWLE1BQUFBLEdBQUcsQ0FBQzNELEtBQUosQ0FBVXFFLEtBQVY7QUFDRCxLQUZEO0FBR0FqRixJQUFBQSxNQUFNLENBQUNrQixFQUFQLENBQVUsT0FBVixFQUFtQixNQUFNO0FBQ3ZCcUQsTUFBQUEsR0FBRyxDQUFDVyxVQUFKLENBQWUsR0FBZjtBQUNELEtBRkQ7QUFHQWxGLElBQUFBLE1BQU0sQ0FBQ2tCLEVBQVAsQ0FBVSxLQUFWLEVBQWlCLE1BQU07QUFDckJxRCxNQUFBQSxHQUFHLENBQUN0RCxHQUFKO0FBQ0QsS0FGRDtBQUdEOztBQUVEa0UsRUFBQUEsY0FBYyxHQUFHO0FBQ2YsUUFBSSxDQUFDLEtBQUtoRyxPQUFWLEVBQW1CO0FBQ2pCLGFBQU8yQixPQUFPLENBQUNDLE9BQVIsRUFBUDtBQUNEOztBQUNELFdBQU8sS0FBSzVCLE9BQUwsQ0FBYWlHLEtBQWIsQ0FBbUIsS0FBbkIsQ0FBUDtBQUNEOztBQUVEQyxFQUFBQSxnQkFBZ0IsQ0FBQ3pGLFFBQUQsRUFBVztBQUN6QixXQUFPLG9DQUFpQkEsUUFBakIsQ0FBUDtBQUNEOztBQXZQbUQ7OztlQTBQdkN0QyxtQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuIEdyaWRGU0J1Y2tldEFkYXB0ZXJcbiBTdG9yZXMgZmlsZXMgaW4gTW9uZ28gdXNpbmcgR3JpZFN0b3JlXG4gUmVxdWlyZXMgdGhlIGRhdGFiYXNlIGFkYXB0ZXIgdG8gYmUgYmFzZWQgb24gbW9uZ29jbGllbnRcblxuIEBmbG93IHdlYWtcbiAqL1xuXG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCB7IE1vbmdvQ2xpZW50LCBHcmlkRlNCdWNrZXQsIERiIH0gZnJvbSAnbW9uZ29kYic7XG5pbXBvcnQgeyBGaWxlc0FkYXB0ZXIsIHZhbGlkYXRlRmlsZW5hbWUgfSBmcm9tICcuL0ZpbGVzQWRhcHRlcic7XG5pbXBvcnQgZGVmYXVsdHMgZnJvbSAnLi4vLi4vZGVmYXVsdHMnO1xuY29uc3QgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7XG5cbmV4cG9ydCBjbGFzcyBHcmlkRlNCdWNrZXRBZGFwdGVyIGV4dGVuZHMgRmlsZXNBZGFwdGVyIHtcbiAgX2RhdGFiYXNlVVJJOiBzdHJpbmc7XG4gIF9jb25uZWN0aW9uUHJvbWlzZTogUHJvbWlzZTxEYj47XG4gIF9tb25nb09wdGlvbnM6IE9iamVjdDtcbiAgX2FsZ29yaXRobTogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIG1vbmdvRGF0YWJhc2VVUkkgPSBkZWZhdWx0cy5EZWZhdWx0TW9uZ29VUkksXG4gICAgbW9uZ29PcHRpb25zID0ge30sXG4gICAgZW5jcnlwdGlvbktleSA9IHVuZGVmaW5lZFxuICApIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX2RhdGFiYXNlVVJJID0gbW9uZ29EYXRhYmFzZVVSSTtcbiAgICB0aGlzLl9hbGdvcml0aG0gPSAnYWVzLTI1Ni1nY20nO1xuICAgIHRoaXMuX2VuY3J5cHRpb25LZXkgPVxuICAgICAgZW5jcnlwdGlvbktleSAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8gY3J5cHRvLmNyZWF0ZUhhc2goJ3NoYTI1NicpLnVwZGF0ZShTdHJpbmcoZW5jcnlwdGlvbktleSkpLmRpZ2VzdCgnYmFzZTY0Jykuc3Vic3RyKDAsIDMyKVxuICAgICAgICA6IG51bGw7XG4gICAgY29uc3QgZGVmYXVsdE1vbmdvT3B0aW9ucyA9IHtcbiAgICAgIHVzZU5ld1VybFBhcnNlcjogdHJ1ZSxcbiAgICAgIHVzZVVuaWZpZWRUb3BvbG9neTogdHJ1ZSxcbiAgICB9O1xuICAgIHRoaXMuX21vbmdvT3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oZGVmYXVsdE1vbmdvT3B0aW9ucywgbW9uZ29PcHRpb25zKTtcbiAgfVxuXG4gIF9jb25uZWN0KCkge1xuICAgIGlmICghdGhpcy5fY29ubmVjdGlvblByb21pc2UpIHtcbiAgICAgIHRoaXMuX2Nvbm5lY3Rpb25Qcm9taXNlID0gTW9uZ29DbGllbnQuY29ubmVjdCh0aGlzLl9kYXRhYmFzZVVSSSwgdGhpcy5fbW9uZ29PcHRpb25zKS50aGVuKFxuICAgICAgICBjbGllbnQgPT4ge1xuICAgICAgICAgIHRoaXMuX2NsaWVudCA9IGNsaWVudDtcbiAgICAgICAgICByZXR1cm4gY2xpZW50LmRiKGNsaWVudC5zLm9wdGlvbnMuZGJOYW1lKTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2Nvbm5lY3Rpb25Qcm9taXNlO1xuICB9XG5cbiAgX2dldEJ1Y2tldCgpIHtcbiAgICByZXR1cm4gdGhpcy5fY29ubmVjdCgpLnRoZW4oZGF0YWJhc2UgPT4gbmV3IEdyaWRGU0J1Y2tldChkYXRhYmFzZSkpO1xuICB9XG5cbiAgLy8gRm9yIGEgZ2l2ZW4gY29uZmlnIG9iamVjdCwgZmlsZW5hbWUsIGFuZCBkYXRhLCBzdG9yZSBhIGZpbGVcbiAgLy8gUmV0dXJucyBhIHByb21pc2VcbiAgYXN5bmMgY3JlYXRlRmlsZShmaWxlbmFtZTogc3RyaW5nLCBkYXRhLCBjb250ZW50VHlwZSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgYnVja2V0ID0gYXdhaXQgdGhpcy5fZ2V0QnVja2V0KCk7XG4gICAgY29uc3Qgc3RyZWFtID0gYXdhaXQgYnVja2V0Lm9wZW5VcGxvYWRTdHJlYW0oZmlsZW5hbWUsIHtcbiAgICAgIG1ldGFkYXRhOiBvcHRpb25zLm1ldGFkYXRhLFxuICAgIH0pO1xuICAgIGlmICh0aGlzLl9lbmNyeXB0aW9uS2V5ICE9PSBudWxsKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBpdiA9IGNyeXB0by5yYW5kb21CeXRlcygxNik7XG4gICAgICAgIGNvbnN0IGNpcGhlciA9IGNyeXB0by5jcmVhdGVDaXBoZXJpdih0aGlzLl9hbGdvcml0aG0sIHRoaXMuX2VuY3J5cHRpb25LZXksIGl2KTtcbiAgICAgICAgY29uc3QgZW5jcnlwdGVkUmVzdWx0ID0gQnVmZmVyLmNvbmNhdChbXG4gICAgICAgICAgY2lwaGVyLnVwZGF0ZShkYXRhKSxcbiAgICAgICAgICBjaXBoZXIuZmluYWwoKSxcbiAgICAgICAgICBpdixcbiAgICAgICAgICBjaXBoZXIuZ2V0QXV0aFRhZygpLFxuICAgICAgICBdKTtcbiAgICAgICAgYXdhaXQgc3RyZWFtLndyaXRlKGVuY3J5cHRlZFJlc3VsdCk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBhd2FpdCBzdHJlYW0ud3JpdGUoZGF0YSk7XG4gICAgfVxuICAgIHN0cmVhbS5lbmQoKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgc3RyZWFtLm9uKCdmaW5pc2gnLCByZXNvbHZlKTtcbiAgICAgIHN0cmVhbS5vbignZXJyb3InLCByZWplY3QpO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgZGVsZXRlRmlsZShmaWxlbmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3QgYnVja2V0ID0gYXdhaXQgdGhpcy5fZ2V0QnVja2V0KCk7XG4gICAgY29uc3QgZG9jdW1lbnRzID0gYXdhaXQgYnVja2V0LmZpbmQoeyBmaWxlbmFtZSB9KS50b0FycmF5KCk7XG4gICAgaWYgKGRvY3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRmlsZU5vdEZvdW5kJyk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLmFsbChcbiAgICAgIGRvY3VtZW50cy5tYXAoZG9jID0+IHtcbiAgICAgICAgcmV0dXJuIGJ1Y2tldC5kZWxldGUoZG9jLl9pZCk7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBhc3luYyBnZXRGaWxlRGF0YShmaWxlbmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3QgYnVja2V0ID0gYXdhaXQgdGhpcy5fZ2V0QnVja2V0KCk7XG4gICAgY29uc3Qgc3RyZWFtID0gYnVja2V0Lm9wZW5Eb3dubG9hZFN0cmVhbUJ5TmFtZShmaWxlbmFtZSk7XG4gICAgc3RyZWFtLnJlYWQoKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3QgY2h1bmtzID0gW107XG4gICAgICBzdHJlYW0ub24oJ2RhdGEnLCBkYXRhID0+IHtcbiAgICAgICAgY2h1bmtzLnB1c2goZGF0YSk7XG4gICAgICB9KTtcbiAgICAgIHN0cmVhbS5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBkYXRhID0gQnVmZmVyLmNvbmNhdChjaHVua3MpO1xuICAgICAgICBpZiAodGhpcy5fZW5jcnlwdGlvbktleSAhPT0gbnVsbCkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBhdXRoVGFnTG9jYXRpb24gPSBkYXRhLmxlbmd0aCAtIDE2O1xuICAgICAgICAgICAgY29uc3QgaXZMb2NhdGlvbiA9IGRhdGEubGVuZ3RoIC0gMzI7XG4gICAgICAgICAgICBjb25zdCBhdXRoVGFnID0gZGF0YS5zbGljZShhdXRoVGFnTG9jYXRpb24pO1xuICAgICAgICAgICAgY29uc3QgaXYgPSBkYXRhLnNsaWNlKGl2TG9jYXRpb24sIGF1dGhUYWdMb2NhdGlvbik7XG4gICAgICAgICAgICBjb25zdCBlbmNyeXB0ZWQgPSBkYXRhLnNsaWNlKDAsIGl2TG9jYXRpb24pO1xuICAgICAgICAgICAgY29uc3QgZGVjaXBoZXIgPSBjcnlwdG8uY3JlYXRlRGVjaXBoZXJpdih0aGlzLl9hbGdvcml0aG0sIHRoaXMuX2VuY3J5cHRpb25LZXksIGl2KTtcbiAgICAgICAgICAgIGRlY2lwaGVyLnNldEF1dGhUYWcoYXV0aFRhZyk7XG4gICAgICAgICAgICBjb25zdCBkZWNyeXB0ZWQgPSBCdWZmZXIuY29uY2F0KFtkZWNpcGhlci51cGRhdGUoZW5jcnlwdGVkKSwgZGVjaXBoZXIuZmluYWwoKV0pO1xuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoZGVjcnlwdGVkKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmVzb2x2ZShkYXRhKTtcbiAgICAgIH0pO1xuICAgICAgc3RyZWFtLm9uKCdlcnJvcicsIGVyciA9PiB7XG4gICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyByb3RhdGVFbmNyeXB0aW9uS2V5KG9wdGlvbnMgPSB7fSkge1xuICAgIHZhciBmaWxlTmFtZXMgPSBbXTtcbiAgICB2YXIgb2xkS2V5RmlsZUFkYXB0ZXIgPSB7fTtcbiAgICBjb25zdCBidWNrZXQgPSBhd2FpdCB0aGlzLl9nZXRCdWNrZXQoKTtcbiAgICBpZiAob3B0aW9ucy5vbGRLZXkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgb2xkS2V5RmlsZUFkYXB0ZXIgPSBuZXcgR3JpZEZTQnVja2V0QWRhcHRlcihcbiAgICAgICAgdGhpcy5fZGF0YWJhc2VVUkksXG4gICAgICAgIHRoaXMuX21vbmdvT3B0aW9ucyxcbiAgICAgICAgb3B0aW9ucy5vbGRLZXlcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9sZEtleUZpbGVBZGFwdGVyID0gbmV3IEdyaWRGU0J1Y2tldEFkYXB0ZXIodGhpcy5fZGF0YWJhc2VVUkksIHRoaXMuX21vbmdvT3B0aW9ucyk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmZpbGVOYW1lcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBmaWxlTmFtZXMgPSBvcHRpb25zLmZpbGVOYW1lcztcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgZmlsZU5hbWVzSXRlcmF0b3IgPSBhd2FpdCBidWNrZXQuZmluZCgpLnRvQXJyYXkoKTtcbiAgICAgIGZpbGVOYW1lc0l0ZXJhdG9yLmZvckVhY2goZmlsZSA9PiB7XG4gICAgICAgIGZpbGVOYW1lcy5wdXNoKGZpbGUuZmlsZW5hbWUpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgIHZhciBmaWxlTmFtZXNOb3RSb3RhdGVkID0gZmlsZU5hbWVzO1xuICAgICAgdmFyIGZpbGVOYW1lc1JvdGF0ZWQgPSBbXTtcbiAgICAgIHZhciBmaWxlTmFtZVRvdGFsID0gZmlsZU5hbWVzLmxlbmd0aDtcbiAgICAgIHZhciBmaWxlTmFtZUluZGV4ID0gMDtcbiAgICAgIGZpbGVOYW1lcy5mb3JFYWNoKGZpbGVOYW1lID0+IHtcbiAgICAgICAgb2xkS2V5RmlsZUFkYXB0ZXJcbiAgICAgICAgICAuZ2V0RmlsZURhdGEoZmlsZU5hbWUpXG4gICAgICAgICAgLnRoZW4ocGxhaW5UZXh0RGF0YSA9PiB7XG4gICAgICAgICAgICAvL092ZXJ3cml0ZSBmaWxlIHdpdGggZGF0YSBlbmNyeXB0ZWQgd2l0aCBuZXcga2V5XG4gICAgICAgICAgICB0aGlzLmNyZWF0ZUZpbGUoZmlsZU5hbWUsIHBsYWluVGV4dERhdGEpXG4gICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBmaWxlTmFtZXNSb3RhdGVkLnB1c2goZmlsZU5hbWUpO1xuICAgICAgICAgICAgICAgIGZpbGVOYW1lc05vdFJvdGF0ZWQgPSBmaWxlTmFtZXNOb3RSb3RhdGVkLmZpbHRlcihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZSAhPT0gZmlsZU5hbWU7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgZmlsZU5hbWVJbmRleCArPSAxO1xuICAgICAgICAgICAgICAgIGlmIChmaWxlTmFtZUluZGV4ID09IGZpbGVOYW1lVG90YWwpIHtcbiAgICAgICAgICAgICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgICAgICAgICAgICByb3RhdGVkOiBmaWxlTmFtZXNSb3RhdGVkLFxuICAgICAgICAgICAgICAgICAgICBub3RSb3RhdGVkOiBmaWxlTmFtZXNOb3RSb3RhdGVkLFxuICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgICAgIGZpbGVOYW1lSW5kZXggKz0gMTtcbiAgICAgICAgICAgICAgICBpZiAoZmlsZU5hbWVJbmRleCA9PSBmaWxlTmFtZVRvdGFsKSB7XG4gICAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgcm90YXRlZDogZmlsZU5hbWVzUm90YXRlZCxcbiAgICAgICAgICAgICAgICAgICAgbm90Um90YXRlZDogZmlsZU5hbWVzTm90Um90YXRlZCxcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgZmlsZU5hbWVJbmRleCArPSAxO1xuICAgICAgICAgICAgaWYgKGZpbGVOYW1lSW5kZXggPT0gZmlsZU5hbWVUb3RhbCkge1xuICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICByb3RhdGVkOiBmaWxlTmFtZXNSb3RhdGVkLFxuICAgICAgICAgICAgICAgIG5vdFJvdGF0ZWQ6IGZpbGVOYW1lc05vdFJvdGF0ZWQsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBnZXRGaWxlTG9jYXRpb24oY29uZmlnLCBmaWxlbmFtZSkge1xuICAgIHJldHVybiBjb25maWcubW91bnQgKyAnL2ZpbGVzLycgKyBjb25maWcuYXBwbGljYXRpb25JZCArICcvJyArIGVuY29kZVVSSUNvbXBvbmVudChmaWxlbmFtZSk7XG4gIH1cblxuICBhc3luYyBnZXRNZXRhZGF0YShmaWxlbmFtZSkge1xuICAgIGNvbnN0IGJ1Y2tldCA9IGF3YWl0IHRoaXMuX2dldEJ1Y2tldCgpO1xuICAgIGNvbnN0IGZpbGVzID0gYXdhaXQgYnVja2V0LmZpbmQoeyBmaWxlbmFtZSB9KS50b0FycmF5KCk7XG4gICAgaWYgKGZpbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbiAgICBjb25zdCB7IG1ldGFkYXRhIH0gPSBmaWxlc1swXTtcbiAgICByZXR1cm4geyBtZXRhZGF0YSB9O1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlRmlsZVN0cmVhbShmaWxlbmFtZTogc3RyaW5nLCByZXEsIHJlcywgY29udGVudFR5cGUpIHtcbiAgICBjb25zdCBidWNrZXQgPSBhd2FpdCB0aGlzLl9nZXRCdWNrZXQoKTtcbiAgICBjb25zdCBmaWxlcyA9IGF3YWl0IGJ1Y2tldC5maW5kKHsgZmlsZW5hbWUgfSkudG9BcnJheSgpO1xuICAgIGlmIChmaWxlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRmlsZU5vdEZvdW5kJyk7XG4gICAgfVxuICAgIGNvbnN0IHBhcnRzID0gcmVxXG4gICAgICAuZ2V0KCdSYW5nZScpXG4gICAgICAucmVwbGFjZSgvYnl0ZXM9LywgJycpXG4gICAgICAuc3BsaXQoJy0nKTtcbiAgICBjb25zdCBwYXJ0aWFsc3RhcnQgPSBwYXJ0c1swXTtcbiAgICBjb25zdCBwYXJ0aWFsZW5kID0gcGFydHNbMV07XG5cbiAgICBjb25zdCBzdGFydCA9IHBhcnNlSW50KHBhcnRpYWxzdGFydCwgMTApO1xuICAgIGNvbnN0IGVuZCA9IHBhcnRpYWxlbmQgPyBwYXJzZUludChwYXJ0aWFsZW5kLCAxMCkgOiBmaWxlc1swXS5sZW5ndGggLSAxO1xuXG4gICAgcmVzLndyaXRlSGVhZCgyMDYsIHtcbiAgICAgICdBY2NlcHQtUmFuZ2VzJzogJ2J5dGVzJyxcbiAgICAgICdDb250ZW50LUxlbmd0aCc6IGVuZCAtIHN0YXJ0ICsgMSxcbiAgICAgICdDb250ZW50LVJhbmdlJzogJ2J5dGVzICcgKyBzdGFydCArICctJyArIGVuZCArICcvJyArIGZpbGVzWzBdLmxlbmd0aCxcbiAgICAgICdDb250ZW50LVR5cGUnOiBjb250ZW50VHlwZSxcbiAgICB9KTtcbiAgICBjb25zdCBzdHJlYW0gPSBidWNrZXQub3BlbkRvd25sb2FkU3RyZWFtQnlOYW1lKGZpbGVuYW1lKTtcbiAgICBzdHJlYW0uc3RhcnQoc3RhcnQpO1xuICAgIHN0cmVhbS5vbignZGF0YScsIGNodW5rID0+IHtcbiAgICAgIHJlcy53cml0ZShjaHVuayk7XG4gICAgfSk7XG4gICAgc3RyZWFtLm9uKCdlcnJvcicsICgpID0+IHtcbiAgICAgIHJlcy5zZW5kU3RhdHVzKDQwNCk7XG4gICAgfSk7XG4gICAgc3RyZWFtLm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICByZXMuZW5kKCk7XG4gICAgfSk7XG4gIH1cblxuICBoYW5kbGVTaHV0ZG93bigpIHtcbiAgICBpZiAoIXRoaXMuX2NsaWVudCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY2xpZW50LmNsb3NlKGZhbHNlKTtcbiAgfVxuXG4gIHZhbGlkYXRlRmlsZW5hbWUoZmlsZW5hbWUpIHtcbiAgICByZXR1cm4gdmFsaWRhdGVGaWxlbmFtZShmaWxlbmFtZSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgR3JpZEZTQnVja2V0QWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Files/GridStoreAdapter.js b/lib/Adapters/Files/GridStoreAdapter.js deleted file mode 100644 index b3286a27e5..0000000000 --- a/lib/Adapters/Files/GridStoreAdapter.js +++ /dev/null @@ -1,182 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.GridStoreAdapter = void 0; - -var _mongodb = require("mongodb"); - -var _FilesAdapter = require("./FilesAdapter"); - -var _defaults = _interopRequireDefault(require("../../defaults")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - GridStoreAdapter - Stores files in Mongo using GridStore - Requires the database adapter to be based on mongoclient - (GridStore is deprecated, Please use GridFSBucket instead) - - - */ -// -disable-next -class GridStoreAdapter extends _FilesAdapter.FilesAdapter { - constructor(mongoDatabaseURI = _defaults.default.DefaultMongoURI, mongoOptions = {}) { - super(); - this._databaseURI = mongoDatabaseURI; - const defaultMongoOptions = { - useNewUrlParser: true, - useUnifiedTopology: true - }; - this._mongoOptions = Object.assign(defaultMongoOptions, mongoOptions); - } - - _connect() { - if (!this._connectionPromise) { - this._connectionPromise = _mongodb.MongoClient.connect(this._databaseURI, this._mongoOptions).then(client => { - this._client = client; - return client.db(client.s.options.dbName); - }); - } - - return this._connectionPromise; - } // For a given config object, filename, and data, store a file - // Returns a promise - - - createFile(filename, data) { - return this._connect().then(database => { - const gridStore = new _mongodb.GridStore(database, filename, 'w'); - return gridStore.open(); - }).then(gridStore => { - return gridStore.write(data); - }).then(gridStore => { - return gridStore.close(); - }); - } - - deleteFile(filename) { - return this._connect().then(database => { - const gridStore = new _mongodb.GridStore(database, filename, 'r'); - return gridStore.open(); - }).then(gridStore => { - return gridStore.unlink(); - }).then(gridStore => { - return gridStore.close(); - }); - } - - getFileData(filename) { - return this._connect().then(database => { - return _mongodb.GridStore.exist(database, filename).then(() => { - const gridStore = new _mongodb.GridStore(database, filename, 'r'); - return gridStore.open(); - }); - }).then(gridStore => { - return gridStore.read(); - }); - } - - getFileLocation(config, filename) { - return config.mount + '/files/' + config.applicationId + '/' + encodeURIComponent(filename); - } - - async handleFileStream(filename, req, res, contentType) { - const stream = await this._connect().then(database => { - return _mongodb.GridStore.exist(database, filename).then(() => { - const gridStore = new _mongodb.GridStore(database, filename, 'r'); - return gridStore.open(); - }); - }); - handleRangeRequest(stream, req, res, contentType); - } - - handleShutdown() { - if (!this._client) { - return Promise.resolve(); - } - - return this._client.close(false); - } - - validateFilename(filename) { - return (0, _FilesAdapter.validateFilename)(filename); - } - -} // handleRangeRequest is licensed under Creative Commons Attribution 4.0 International License (https://creativecommons.org/licenses/by/4.0/). -// Author: LEROIB at weightingformypizza (https://weightingformypizza.wordpress.com/2015/06/24/stream-html5-media-content-like-video-audio-from-mongodb-using-express-and-gridstore/). - - -exports.GridStoreAdapter = GridStoreAdapter; - -function handleRangeRequest(stream, req, res, contentType) { - const buffer_size = 1024 * 1024; //1024Kb - // Range request, partial stream the file - - const parts = req.get('Range').replace(/bytes=/, '').split('-'); - let [start, end] = parts; - const notEnded = !end && end !== 0; - const notStarted = !start && start !== 0; // No end provided, we want all bytes - - if (notEnded) { - end = stream.length - 1; - } // No start provided, we're reading backwards - - - if (notStarted) { - start = stream.length - end; - end = start + end - 1; - } // Data exceeds the buffer_size, cap - - - if (end - start >= buffer_size) { - end = start + buffer_size - 1; - } - - const contentLength = end - start + 1; - res.writeHead(206, { - 'Content-Range': 'bytes ' + start + '-' + end + '/' + stream.length, - 'Accept-Ranges': 'bytes', - 'Content-Length': contentLength, - 'Content-Type': contentType - }); - stream.seek(start, function () { - // Get gridFile stream - const gridFileStream = stream.stream(true); - let bufferAvail = 0; - let remainingBytesToWrite = contentLength; - let totalBytesWritten = 0; // Write to response - - gridFileStream.on('data', function (data) { - bufferAvail += data.length; - - if (bufferAvail > 0) { - // slice returns the same buffer if overflowing - // safe to call in any case - const buffer = data.slice(0, remainingBytesToWrite); // Write the buffer - - res.write(buffer); // Increment total - - totalBytesWritten += buffer.length; // Decrement remaining - - remainingBytesToWrite -= data.length; // Decrement the available buffer - - bufferAvail -= buffer.length; - } // In case of small slices, all values will be good at that point - // we've written enough, end... - - - if (totalBytesWritten >= contentLength) { - stream.close(); - res.end(); - this.destroy(); - } - }); - }); -} - -var _default = GridStoreAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9GaWxlcy9HcmlkU3RvcmVBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIkdyaWRTdG9yZUFkYXB0ZXIiLCJGaWxlc0FkYXB0ZXIiLCJjb25zdHJ1Y3RvciIsIm1vbmdvRGF0YWJhc2VVUkkiLCJkZWZhdWx0cyIsIkRlZmF1bHRNb25nb1VSSSIsIm1vbmdvT3B0aW9ucyIsIl9kYXRhYmFzZVVSSSIsImRlZmF1bHRNb25nb09wdGlvbnMiLCJ1c2VOZXdVcmxQYXJzZXIiLCJ1c2VVbmlmaWVkVG9wb2xvZ3kiLCJfbW9uZ29PcHRpb25zIiwiT2JqZWN0IiwiYXNzaWduIiwiX2Nvbm5lY3QiLCJfY29ubmVjdGlvblByb21pc2UiLCJNb25nb0NsaWVudCIsImNvbm5lY3QiLCJ0aGVuIiwiY2xpZW50IiwiX2NsaWVudCIsImRiIiwicyIsIm9wdGlvbnMiLCJkYk5hbWUiLCJjcmVhdGVGaWxlIiwiZmlsZW5hbWUiLCJkYXRhIiwiZGF0YWJhc2UiLCJncmlkU3RvcmUiLCJHcmlkU3RvcmUiLCJvcGVuIiwid3JpdGUiLCJjbG9zZSIsImRlbGV0ZUZpbGUiLCJ1bmxpbmsiLCJnZXRGaWxlRGF0YSIsImV4aXN0IiwicmVhZCIsImdldEZpbGVMb2NhdGlvbiIsImNvbmZpZyIsIm1vdW50IiwiYXBwbGljYXRpb25JZCIsImVuY29kZVVSSUNvbXBvbmVudCIsImhhbmRsZUZpbGVTdHJlYW0iLCJyZXEiLCJyZXMiLCJjb250ZW50VHlwZSIsInN0cmVhbSIsImhhbmRsZVJhbmdlUmVxdWVzdCIsImhhbmRsZVNodXRkb3duIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ2YWxpZGF0ZUZpbGVuYW1lIiwiYnVmZmVyX3NpemUiLCJwYXJ0cyIsImdldCIsInJlcGxhY2UiLCJzcGxpdCIsInN0YXJ0IiwiZW5kIiwibm90RW5kZWQiLCJub3RTdGFydGVkIiwibGVuZ3RoIiwiY29udGVudExlbmd0aCIsIndyaXRlSGVhZCIsInNlZWsiLCJncmlkRmlsZVN0cmVhbSIsImJ1ZmZlckF2YWlsIiwicmVtYWluaW5nQnl0ZXNUb1dyaXRlIiwidG90YWxCeXRlc1dyaXR0ZW4iLCJvbiIsImJ1ZmZlciIsInNsaWNlIiwiZGVzdHJveSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQVVBOztBQUNBOztBQUNBOzs7O0FBWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBS08sTUFBTUEsZ0JBQU4sU0FBK0JDLDBCQUEvQixDQUE0QztBQUtqREMsRUFBQUEsV0FBVyxDQUFDQyxnQkFBZ0IsR0FBR0Msa0JBQVNDLGVBQTdCLEVBQThDQyxZQUFZLEdBQUcsRUFBN0QsRUFBaUU7QUFDMUU7QUFDQSxTQUFLQyxZQUFMLEdBQW9CSixnQkFBcEI7QUFFQSxVQUFNSyxtQkFBbUIsR0FBRztBQUMxQkMsTUFBQUEsZUFBZSxFQUFFLElBRFM7QUFFMUJDLE1BQUFBLGtCQUFrQixFQUFFO0FBRk0sS0FBNUI7QUFJQSxTQUFLQyxhQUFMLEdBQXFCQyxNQUFNLENBQUNDLE1BQVAsQ0FBY0wsbUJBQWQsRUFBbUNGLFlBQW5DLENBQXJCO0FBQ0Q7O0FBRURRLEVBQUFBLFFBQVEsR0FBRztBQUNULFFBQUksQ0FBQyxLQUFLQyxrQkFBVixFQUE4QjtBQUM1QixXQUFLQSxrQkFBTCxHQUEwQkMscUJBQVlDLE9BQVosQ0FBb0IsS0FBS1YsWUFBekIsRUFBdUMsS0FBS0ksYUFBNUMsRUFBMkRPLElBQTNELENBQ3hCQyxNQUFNLElBQUk7QUFDUixhQUFLQyxPQUFMLEdBQWVELE1BQWY7QUFDQSxlQUFPQSxNQUFNLENBQUNFLEVBQVAsQ0FBVUYsTUFBTSxDQUFDRyxDQUFQLENBQVNDLE9BQVQsQ0FBaUJDLE1BQTNCLENBQVA7QUFDRCxPQUp1QixDQUExQjtBQU1EOztBQUNELFdBQU8sS0FBS1Qsa0JBQVo7QUFDRCxHQTFCZ0QsQ0E0QmpEO0FBQ0E7OztBQUNBVSxFQUFBQSxVQUFVLENBQUNDLFFBQUQsRUFBbUJDLElBQW5CLEVBQXlCO0FBQ2pDLFdBQU8sS0FBS2IsUUFBTCxHQUNK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UUFBQUEsR0FBRyxDQUFDYyxHQUFKO0FBQ0EsYUFBS2MsT0FBTDtBQUNEO0FBQ0YsS0F0QkQ7QUF1QkQsR0E5QkQ7QUErQkQ7O2VBRWMxRSxnQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuIEdyaWRTdG9yZUFkYXB0ZXJcbiBTdG9yZXMgZmlsZXMgaW4gTW9uZ28gdXNpbmcgR3JpZFN0b3JlXG4gUmVxdWlyZXMgdGhlIGRhdGFiYXNlIGFkYXB0ZXIgdG8gYmUgYmFzZWQgb24gbW9uZ29jbGllbnRcbiAoR3JpZFN0b3JlIGlzIGRlcHJlY2F0ZWQsIFBsZWFzZSB1c2UgR3JpZEZTQnVja2V0IGluc3RlYWQpXG5cbiBAZmxvdyB3ZWFrXG4gKi9cblxuLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG5pbXBvcnQgeyBNb25nb0NsaWVudCwgR3JpZFN0b3JlLCBEYiB9IGZyb20gJ21vbmdvZGInO1xuaW1wb3J0IHsgRmlsZXNBZGFwdGVyLCB2YWxpZGF0ZUZpbGVuYW1lIH0gZnJvbSAnLi9GaWxlc0FkYXB0ZXInO1xuaW1wb3J0IGRlZmF1bHRzIGZyb20gJy4uLy4uL2RlZmF1bHRzJztcblxuZXhwb3J0IGNsYXNzIEdyaWRTdG9yZUFkYXB0ZXIgZXh0ZW5kcyBGaWxlc0FkYXB0ZXIge1xuICBfZGF0YWJhc2VVUkk6IHN0cmluZztcbiAgX2Nvbm5lY3Rpb25Qcm9taXNlOiBQcm9taXNlPERiPjtcbiAgX21vbmdvT3B0aW9uczogT2JqZWN0O1xuXG4gIGNvbnN0cnVjdG9yKG1vbmdvRGF0YWJhc2VVUkkgPSBkZWZhdWx0cy5EZWZhdWx0TW9uZ29VUkksIG1vbmdvT3B0aW9ucyA9IHt9KSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLl9kYXRhYmFzZVVSSSA9IG1vbmdvRGF0YWJhc2VVUkk7XG5cbiAgICBjb25zdCBkZWZhdWx0TW9uZ29PcHRpb25zID0ge1xuICAgICAgdXNlTmV3VXJsUGFyc2VyOiB0cnVlLFxuICAgICAgdXNlVW5pZmllZFRvcG9sb2d5OiB0cnVlLFxuICAgIH07XG4gICAgdGhpcy5fbW9uZ29PcHRpb25zID0gT2JqZWN0LmFzc2lnbihkZWZhdWx0TW9uZ29PcHRpb25zLCBtb25nb09wdGlvbnMpO1xuICB9XG5cbiAgX2Nvbm5lY3QoKSB7XG4gICAgaWYgKCF0aGlzLl9jb25uZWN0aW9uUHJvbWlzZSkge1xuICAgICAgdGhpcy5fY29ubmVjdGlvblByb21pc2UgPSBNb25nb0NsaWVudC5jb25uZWN0KHRoaXMuX2RhdGFiYXNlVVJJLCB0aGlzLl9tb25nb09wdGlvbnMpLnRoZW4oXG4gICAgICAgIGNsaWVudCA9PiB7XG4gICAgICAgICAgdGhpcy5fY2xpZW50ID0gY2xpZW50O1xuICAgICAgICAgIHJldHVybiBjbGllbnQuZGIoY2xpZW50LnMub3B0aW9ucy5kYk5hbWUpO1xuICAgICAgICB9XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY29ubmVjdGlvblByb21pc2U7XG4gIH1cblxuICAvLyBGb3IgYSBnaXZlbiBjb25maWcgb2JqZWN0LCBmaWxlbmFtZSwgYW5kIGRhdGEsIHN0b3JlIGEgZmlsZVxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZVxuICBjcmVhdGVGaWxlKGZpbGVuYW1lOiBzdHJpbmcsIGRhdGEpIHtcbiAgICByZXR1cm4gdGhpcy5fY29ubmVjdCgpXG4gICAgICAudGhlbihkYXRhYmFzZSA9PiB7XG4gICAgICAgIGNvbnN0IGdyaWRTdG9yZSA9IG5ldyBHcmlkU3RvcmUoZGF0YWJhc2UsIGZpbGVuYW1lLCAndycpO1xuICAgICAgICByZXR1cm4gZ3JpZFN0b3JlLm9wZW4oKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihncmlkU3RvcmUgPT4ge1xuICAgICAgICByZXR1cm4gZ3JpZFN0b3JlLndyaXRlKGRhdGEpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKGdyaWRTdG9yZSA9PiB7XG4gICAgICAgIHJldHVybiBncmlkU3RvcmUuY2xvc2UoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgZGVsZXRlRmlsZShmaWxlbmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuX2Nvbm5lY3QoKVxuICAgICAgLnRoZW4oZGF0YWJhc2UgPT4ge1xuICAgICAgICBjb25zdCBncmlkU3RvcmUgPSBuZXcgR3JpZFN0b3JlKGRhdGFiYXNlLCBmaWxlbmFtZSwgJ3InKTtcbiAgICAgICAgcmV0dXJuIGdyaWRTdG9yZS5vcGVuKCk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oZ3JpZFN0b3JlID0+IHtcbiAgICAgICAgcmV0dXJuIGdyaWRTdG9yZS51bmxpbmsoKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihncmlkU3RvcmUgPT4ge1xuICAgICAgICByZXR1cm4gZ3JpZFN0b3JlLmNsb3NlKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIGdldEZpbGVEYXRhKGZpbGVuYW1lOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5fY29ubmVjdCgpXG4gICAgICAudGhlbihkYXRhYmFzZSA9PiB7XG4gICAgICAgIHJldHVybiBHcmlkU3RvcmUuZXhpc3QoZGF0YWJhc2UsIGZpbGVuYW1lKS50aGVuKCgpID0+IHtcbiAgICAgICAgICBjb25zdCBncmlkU3RvcmUgPSBuZXcgR3JpZFN0b3JlKGRhdGFiYXNlLCBmaWxlbmFtZSwgJ3InKTtcbiAgICAgICAgICByZXR1cm4gZ3JpZFN0b3JlLm9wZW4oKTtcbiAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oZ3JpZFN0b3JlID0+IHtcbiAgICAgICAgcmV0dXJuIGdyaWRTdG9yZS5yZWFkKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIGdldEZpbGVMb2NhdGlvbihjb25maWcsIGZpbGVuYW1lKSB7XG4gICAgcmV0dXJuIGNvbmZpZy5tb3VudCArICcvZmlsZXMvJyArIGNvbmZpZy5hcHBsaWNhdGlvbklkICsgJy8nICsgZW5jb2RlVVJJQ29tcG9uZW50KGZpbGVuYW1lKTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUZpbGVTdHJlYW0oZmlsZW5hbWU6IHN0cmluZywgcmVxLCByZXMsIGNvbnRlbnRUeXBlKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gYXdhaXQgdGhpcy5fY29ubmVjdCgpLnRoZW4oZGF0YWJhc2UgPT4ge1xuICAgICAgcmV0dXJuIEdyaWRTdG9yZS5leGlzdChkYXRhYmFzZSwgZmlsZW5hbWUpLnRoZW4oKCkgPT4ge1xuICAgICAgICBjb25zdCBncmlkU3RvcmUgPSBuZXcgR3JpZFN0b3JlKGRhdGFiYXNlLCBmaWxlbmFtZSwgJ3InKTtcbiAgICAgICAgcmV0dXJuIGdyaWRTdG9yZS5vcGVuKCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICBoYW5kbGVSYW5nZVJlcXVlc3Qoc3RyZWFtLCByZXEsIHJlcywgY29udGVudFR5cGUpO1xuICB9XG5cbiAgaGFuZGxlU2h1dGRvd24oKSB7XG4gICAgaWYgKCF0aGlzLl9jbGllbnQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudC5jbG9zZShmYWxzZSk7XG4gIH1cblxuICB2YWxpZGF0ZUZpbGVuYW1lKGZpbGVuYW1lKSB7XG4gICAgcmV0dXJuIHZhbGlkYXRlRmlsZW5hbWUoZmlsZW5hbWUpO1xuICB9XG59XG5cbi8vIGhhbmRsZVJhbmdlUmVxdWVzdCBpcyBsaWNlbnNlZCB1bmRlciBDcmVhdGl2ZSBDb21tb25zIEF0dHJpYnV0aW9uIDQuMCBJbnRlcm5hdGlvbmFsIExpY2Vuc2UgKGh0dHBzOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9ieS80LjAvKS5cbi8vIEF1dGhvcjogTEVST0lCIGF0IHdlaWdodGluZ2Zvcm15cGl6emEgKGh0dHBzOi8vd2VpZ2h0aW5nZm9ybXlwaXp6YS53b3JkcHJlc3MuY29tLzIwMTUvMDYvMjQvc3RyZWFtLWh0bWw1LW1lZGlhLWNvbnRlbnQtbGlrZS12aWRlby1hdWRpby1mcm9tLW1vbmdvZGItdXNpbmctZXhwcmVzcy1hbmQtZ3JpZHN0b3JlLykuXG5mdW5jdGlvbiBoYW5kbGVSYW5nZVJlcXVlc3Qoc3RyZWFtLCByZXEsIHJlcywgY29udGVudFR5cGUpIHtcbiAgY29uc3QgYnVmZmVyX3NpemUgPSAxMDI0ICogMTAyNDsgLy8xMDI0S2JcbiAgLy8gUmFuZ2UgcmVxdWVzdCwgcGFydGlhbCBzdHJlYW0gdGhlIGZpbGVcbiAgY29uc3QgcGFydHMgPSByZXFcbiAgICAuZ2V0KCdSYW5nZScpXG4gICAgLnJlcGxhY2UoL2J5dGVzPS8sICcnKVxuICAgIC5zcGxpdCgnLScpO1xuICBsZXQgW3N0YXJ0LCBlbmRdID0gcGFydHM7XG4gIGNvbnN0IG5vdEVuZGVkID0gIWVuZCAmJiBlbmQgIT09IDA7XG4gIGNvbnN0IG5vdFN0YXJ0ZWQgPSAhc3RhcnQgJiYgc3RhcnQgIT09IDA7XG4gIC8vIE5vIGVuZCBwcm92aWRlZCwgd2Ugd2FudCBhbGwgYnl0ZXNcbiAgaWYgKG5vdEVuZGVkKSB7XG4gICAgZW5kID0gc3RyZWFtLmxlbmd0aCAtIDE7XG4gIH1cbiAgLy8gTm8gc3RhcnQgcHJvdmlkZWQsIHdlJ3JlIHJlYWRpbmcgYmFja3dhcmRzXG4gIGlmIChub3RTdGFydGVkKSB7XG4gICAgc3RhcnQgPSBzdHJlYW0ubGVuZ3RoIC0gZW5kO1xuICAgIGVuZCA9IHN0YXJ0ICsgZW5kIC0gMTtcbiAgfVxuXG4gIC8vIERhdGEgZXhjZWVkcyB0aGUgYnVmZmVyX3NpemUsIGNhcFxuICBpZiAoZW5kIC0gc3RhcnQgPj0gYnVmZmVyX3NpemUpIHtcbiAgICBlbmQgPSBzdGFydCArIGJ1ZmZlcl9zaXplIC0gMTtcbiAgfVxuXG4gIGNvbnN0IGNvbnRlbnRMZW5ndGggPSBlbmQgLSBzdGFydCArIDE7XG5cbiAgcmVzLndyaXRlSGVhZCgyMDYsIHtcbiAgICAnQ29udGVudC1SYW5nZSc6ICdieXRlcyAnICsgc3RhcnQgKyAnLScgKyBlbmQgKyAnLycgKyBzdHJlYW0ubGVuZ3RoLFxuICAgICdBY2NlcHQtUmFuZ2VzJzogJ2J5dGVzJyxcbiAgICAnQ29udGVudC1MZW5ndGgnOiBjb250ZW50TGVuZ3RoLFxuICAgICdDb250ZW50LVR5cGUnOiBjb250ZW50VHlwZSxcbiAgfSk7XG5cbiAgc3RyZWFtLnNlZWsoc3RhcnQsIGZ1bmN0aW9uICgpIHtcbiAgICAvLyBHZXQgZ3JpZEZpbGUgc3RyZWFtXG4gICAgY29uc3QgZ3JpZEZpbGVTdHJlYW0gPSBzdHJlYW0uc3RyZWFtKHRydWUpO1xuICAgIGxldCBidWZmZXJBdmFpbCA9IDA7XG4gICAgbGV0IHJlbWFpbmluZ0J5dGVzVG9Xcml0ZSA9IGNvbnRlbnRMZW5ndGg7XG4gICAgbGV0IHRvdGFsQnl0ZXNXcml0dGVuID0gMDtcbiAgICAvLyBXcml0ZSB0byByZXNwb25zZVxuICAgIGdyaWRGaWxlU3RyZWFtLm9uKCdkYXRhJywgZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgIGJ1ZmZlckF2YWlsICs9IGRhdGEubGVuZ3RoO1xuICAgICAgaWYgKGJ1ZmZlckF2YWlsID4gMCkge1xuICAgICAgICAvLyBzbGljZSByZXR1cm5zIHRoZSBzYW1lIGJ1ZmZlciBpZiBvdmVyZmxvd2luZ1xuICAgICAgICAvLyBzYWZlIHRvIGNhbGwgaW4gYW55IGNhc2VcbiAgICAgICAgY29uc3QgYnVmZmVyID0gZGF0YS5zbGljZSgwLCByZW1haW5pbmdCeXRlc1RvV3JpdGUpO1xuICAgICAgICAvLyBXcml0ZSB0aGUgYnVmZmVyXG4gICAgICAgIHJlcy53cml0ZShidWZmZXIpO1xuICAgICAgICAvLyBJbmNyZW1lbnQgdG90YWxcbiAgICAgICAgdG90YWxCeXRlc1dyaXR0ZW4gKz0gYnVmZmVyLmxlbmd0aDtcbiAgICAgICAgLy8gRGVjcmVtZW50IHJlbWFpbmluZ1xuICAgICAgICByZW1haW5pbmdCeXRlc1RvV3JpdGUgLT0gZGF0YS5sZW5ndGg7XG4gICAgICAgIC8vIERlY3JlbWVudCB0aGUgYXZhaWxhYmxlIGJ1ZmZlclxuICAgICAgICBidWZmZXJBdmFpbCAtPSBidWZmZXIubGVuZ3RoO1xuICAgICAgfVxuICAgICAgLy8gSW4gY2FzZSBvZiBzbWFsbCBzbGljZXMsIGFsbCB2YWx1ZXMgd2lsbCBiZSBnb29kIGF0IHRoYXQgcG9pbnRcbiAgICAgIC8vIHdlJ3ZlIHdyaXR0ZW4gZW5vdWdoLCBlbmQuLi5cbiAgICAgIGlmICh0b3RhbEJ5dGVzV3JpdHRlbiA+PSBjb250ZW50TGVuZ3RoKSB7XG4gICAgICAgIHN0cmVhbS5jbG9zZSgpO1xuICAgICAgICByZXMuZW5kKCk7XG4gICAgICAgIHRoaXMuZGVzdHJveSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgR3JpZFN0b3JlQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Logger/LoggerAdapter.js b/lib/Adapters/Logger/LoggerAdapter.js deleted file mode 100644 index 5d3d26d1a1..0000000000 --- a/lib/Adapters/Logger/LoggerAdapter.js +++ /dev/null @@ -1,39 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.LoggerAdapter = void 0; - -/*eslint no-unused-vars: "off"*/ - -/** - * @module Adapters - */ - -/** - * @interface LoggerAdapter - * Logger Adapter - * Allows you to change the logger mechanism - * Default is WinstonLoggerAdapter.js - */ -class LoggerAdapter { - constructor(options) {} - /** - * log - * @param {String} level - * @param {String} message - * @param {Object} metadata - */ - - - log(level, message - /* meta */ - ) {} - -} - -exports.LoggerAdapter = LoggerAdapter; -var _default = LoggerAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9Mb2dnZXIvTG9nZ2VyQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJMb2dnZXJBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJvcHRpb25zIiwibG9nIiwibGV2ZWwiLCJtZXNzYWdlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7QUFDQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU1BLGFBQU4sQ0FBb0I7QUFDekJDLEVBQUFBLFdBQVcsQ0FBQ0MsT0FBRCxFQUFVLENBQUU7QUFDdkI7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDRUMsRUFBQUEsR0FBRyxDQUFDQyxLQUFELEVBQVFDO0FBQVE7QUFBaEIsSUFBNEIsQ0FBRTs7QUFSUjs7O2VBV1pMLGEiLCJzb3VyY2VzQ29udGVudCI6WyIvKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG4vKipcbiAqIEBtb2R1bGUgQWRhcHRlcnNcbiAqL1xuLyoqXG4gKiBAaW50ZXJmYWNlIExvZ2dlckFkYXB0ZXJcbiAqIExvZ2dlciBBZGFwdGVyXG4gKiBBbGxvd3MgeW91IHRvIGNoYW5nZSB0aGUgbG9nZ2VyIG1lY2hhbmlzbVxuICogRGVmYXVsdCBpcyBXaW5zdG9uTG9nZ2VyQWRhcHRlci5qc1xuICovXG5leHBvcnQgY2xhc3MgTG9nZ2VyQWRhcHRlciB7XG4gIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHt9XG4gIC8qKlxuICAgKiBsb2dcbiAgICogQHBhcmFtIHtTdHJpbmd9IGxldmVsXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBtZXRhZGF0YVxuICAgKi9cbiAgbG9nKGxldmVsLCBtZXNzYWdlIC8qIG1ldGEgKi8pIHt9XG59XG5cbmV4cG9ydCBkZWZhdWx0IExvZ2dlckFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Logger/WinstonLogger.js b/lib/Adapters/Logger/WinstonLogger.js deleted file mode 100644 index 9980d08868..0000000000 --- a/lib/Adapters/Logger/WinstonLogger.js +++ /dev/null @@ -1,137 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.configureLogger = configureLogger; -exports.addTransport = addTransport; -exports.removeTransport = removeTransport; -exports.default = exports.logger = void 0; - -var _winston = _interopRequireWildcard(require("winston")); - -var _fs = _interopRequireDefault(require("fs")); - -var _path = _interopRequireDefault(require("path")); - -var _winstonDailyRotateFile = _interopRequireDefault(require("winston-daily-rotate-file")); - -var _lodash = _interopRequireDefault(require("lodash")); - -var _defaults = _interopRequireDefault(require("../../defaults")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -const logger = _winston.default.createLogger(); - -exports.logger = logger; - -function configureTransports(options) { - const transports = []; - - if (options) { - const silent = options.silent; - delete options.silent; - - try { - if (!_lodash.default.isNil(options.dirname)) { - const parseServer = new _winstonDailyRotateFile.default(Object.assign({ - filename: 'parse-server.info', - json: true, - format: _winston.format.combine(_winston.format.timestamp(), _winston.format.splat(), _winston.format.json()) - }, options)); - parseServer.name = 'parse-server'; - transports.push(parseServer); - const parseServerError = new _winstonDailyRotateFile.default(Object.assign({ - filename: 'parse-server.err', - json: true, - format: _winston.format.combine(_winston.format.timestamp(), _winston.format.splat(), _winston.format.json()) - }, options, { - level: 'error' - })); - parseServerError.name = 'parse-server-error'; - transports.push(parseServerError); - } - } catch (e) { - /* */ - } - - const consoleFormat = options.json ? _winston.format.json() : _winston.format.simple(); - const consoleOptions = Object.assign({ - colorize: true, - name: 'console', - silent, - format: _winston.format.combine(_winston.format.splat(), consoleFormat) - }, options); - transports.push(new _winston.default.transports.Console(consoleOptions)); - } - - logger.configure({ - transports - }); -} - -function configureLogger({ - logsFolder = _defaults.default.logsFolder, - jsonLogs = _defaults.default.jsonLogs, - logLevel = _winston.default.level, - verbose = _defaults.default.verbose, - silent = _defaults.default.silent, - maxLogFiles -} = {}) { - if (verbose) { - logLevel = 'verbose'; - } - - _winston.default.level = logLevel; - const options = {}; - - if (logsFolder) { - if (!_path.default.isAbsolute(logsFolder)) { - logsFolder = _path.default.resolve(process.cwd(), logsFolder); - } - - try { - _fs.default.mkdirSync(logsFolder); - } catch (e) { - /* */ - } - } - - options.dirname = logsFolder; - options.level = logLevel; - options.silent = silent; - options.maxFiles = maxLogFiles; - - if (jsonLogs) { - options.json = true; - options.stringify = true; - } - - configureTransports(options); -} - -function addTransport(transport) { - // we will remove the existing transport - // before replacing it with a new one - removeTransport(transport.name); - logger.add(transport); -} - -function removeTransport(transport) { - const matchingTransport = logger.transports.find(t1 => { - return typeof transport === 'string' ? t1.name === transport : t1 === transport; - }); - - if (matchingTransport) { - logger.remove(matchingTransport); - } -} - -var _default = logger; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9Mb2dnZXIvV2luc3RvbkxvZ2dlci5qcyJdLCJuYW1lcyI6WyJsb2dnZXIiLCJ3aW5zdG9uIiwiY3JlYXRlTG9nZ2VyIiwiY29uZmlndXJlVHJhbnNwb3J0cyIsIm9wdGlvbnMiLCJ0cmFuc3BvcnRzIiwic2lsZW50IiwiXyIsImlzTmlsIiwiZGlybmFtZSIsInBhcnNlU2VydmVyIiwiRGFpbHlSb3RhdGVGaWxlIiwiT2JqZWN0IiwiYXNzaWduIiwiZmlsZW5hbWUiLCJqc29uIiwiZm9ybWF0IiwiY29tYmluZSIsInRpbWVzdGFtcCIsInNwbGF0IiwibmFtZSIsInB1c2giLCJwYXJzZVNlcnZlckVycm9yIiwibGV2ZWwiLCJlIiwiY29uc29sZUZvcm1hdCIsInNpbXBsZSIsImNvbnNvbGVPcHRpb25zIiwiY29sb3JpemUiLCJDb25zb2xlIiwiY29uZmlndXJlIiwiY29uZmlndXJlTG9nZ2VyIiwibG9nc0ZvbGRlciIsImRlZmF1bHRzIiwianNvbkxvZ3MiLCJsb2dMZXZlbCIsInZlcmJvc2UiLCJtYXhMb2dGaWxlcyIsInBhdGgiLCJpc0Fic29sdXRlIiwicmVzb2x2ZSIsInByb2Nlc3MiLCJjd2QiLCJmcyIsIm1rZGlyU3luYyIsIm1heEZpbGVzIiwic3RyaW5naWZ5IiwiYWRkVHJhbnNwb3J0IiwidHJhbnNwb3J0IiwicmVtb3ZlVHJhbnNwb3J0IiwiYWRkIiwibWF0Y2hpbmdUcmFuc3BvcnQiLCJmaW5kIiwidDEiLCJyZW1vdmUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFQSxNQUFNQSxNQUFNLEdBQUdDLGlCQUFRQyxZQUFSLEVBQWY7Ozs7QUFFQSxTQUFTQyxtQkFBVCxDQUE2QkMsT0FBN0IsRUFBc0M7QUFDcEMsUUFBTUMsVUFBVSxHQUFHLEVBQW5COztBQUNBLE1BQUlELE9BQUosRUFBYTtBQUNYLFVBQU1FLE1BQU0sR0FBR0Ys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aUJBQWQ7QUFDRDtBQUNGOztlQUdjbkQsTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB3aW5zdG9uLCB7IGZvcm1hdCB9IGZyb20gJ3dpbnN0b24nO1xuaW1wb3J0IGZzIGZyb20gJ2ZzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IERhaWx5Um90YXRlRmlsZSBmcm9tICd3aW5zdG9uLWRhaWx5LXJvdGF0ZS1maWxlJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgZGVmYXVsdHMgZnJvbSAnLi4vLi4vZGVmYXVsdHMnO1xuXG5jb25zdCBsb2dnZXIgPSB3aW5zdG9uLmNyZWF0ZUxvZ2dlcigpO1xuXG5mdW5jdGlvbiBjb25maWd1cmVUcmFuc3BvcnRzKG9wdGlvbnMpIHtcbiAgY29uc3QgdHJhbnNwb3J0cyA9IFtdO1xuICBpZiAob3B0aW9ucykge1xuICAgIGNvbnN0IHNpbGVudCA9IG9wdGlvbnMuc2lsZW50O1xuICAgIGRlbGV0ZSBvcHRpb25zLnNpbGVudDtcblxuICAgIHRyeSB7XG4gICAgICBpZiAoIV8uaXNOaWwob3B0aW9ucy5kaXJuYW1lKSkge1xuICAgICAgICBjb25zdCBwYXJzZVNlcnZlciA9IG5ldyBEYWlseVJvdGF0ZUZpbGUoXG4gICAgICAgICAgT2JqZWN0LmFzc2lnbihcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZmlsZW5hbWU6ICdwYXJzZS1zZXJ2ZXIuaW5mbycsXG4gICAgICAgICAgICAgIGpzb246IHRydWUsXG4gICAgICAgICAgICAgIGZvcm1hdDogZm9ybWF0LmNvbWJpbmUoZm9ybWF0LnRpbWVzdGFtcCgpLCBmb3JtYXQuc3BsYXQoKSwgZm9ybWF0Lmpzb24oKSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3B0aW9uc1xuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgICAgcGFyc2VTZXJ2ZXIubmFtZSA9ICdwYXJzZS1zZXJ2ZXInO1xuICAgICAgICB0cmFuc3BvcnRzLnB1c2gocGFyc2VTZXJ2ZXIpO1xuXG4gICAgICAgIGNvbnN0IHBhcnNlU2VydmVyRXJyb3IgPSBuZXcgRGFpbHlSb3RhdGVGaWxlKFxuICAgICAgICAgIE9iamVjdC5hc3NpZ24oXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGZpbGVuYW1lOiAncGFyc2Utc2VydmVyLmVycicsXG4gICAgICAgICAgICAgIGpzb246IHRydWUsXG4gICAgICAgICAgICAgIGZvcm1hdDogZm9ybWF0LmNvbWJpbmUoZm9ybWF0LnRpbWVzdGFtcCgpLCBmb3JtYXQuc3BsYXQoKSwgZm9ybWF0Lmpzb24oKSksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICAgIHsgbGV2ZWw6ICdlcnJvcicgfVxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgICAgcGFyc2VTZXJ2ZXJFcnJvci5uYW1lID0gJ3BhcnNlLXNlcnZlci1lcnJvcic7XG4gICAgICAgIHRyYW5zcG9ydHMucHVzaChwYXJzZVNlcnZlckVycm9yKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvKiAqL1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnNvbGVGb3JtYXQgPSBvcHRpb25zLmpzb24gPyBmb3JtYXQuanNvbigpIDogZm9ybWF0LnNpbXBsZSgpO1xuICAgIGNvbnN0IGNvbnNvbGVPcHRpb25zID0gT2JqZWN0LmFzc2lnbihcbiAgICAgIHtcbiAgICAgICAgY29sb3JpemU6IHRydWUsXG4gICAgICAgIG5hbWU6ICdjb25zb2xlJyxcbiAgICAgICAgc2lsZW50LFxuICAgICAgICBmb3JtYXQ6IGZvcm1hdC5jb21iaW5lKGZvcm1hdC5zcGxhdCgpLCBjb25zb2xlRm9ybWF0KSxcbiAgICAgIH0sXG4gICAgICBvcHRpb25zXG4gICAgKTtcblxuICAgIHRyYW5zcG9ydHMucHVzaChuZXcgd2luc3Rvbi50cmFuc3BvcnRzLkNvbnNvbGUoY29uc29sZU9wdGlvbnMpKTtcbiAgfVxuXG4gIGxvZ2dlci5jb25maWd1cmUoe1xuICAgIHRyYW5zcG9ydHMsXG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29uZmlndXJlTG9nZ2VyKHtcbiAgbG9nc0ZvbGRlciA9IGRlZmF1bHRzLmxvZ3NGb2xkZXIsXG4gIGpzb25Mb2dzID0gZGVmYXVsdHMuanNvbkxvZ3MsXG4gIGxvZ0xldmVsID0gd2luc3Rvbi5sZXZlbCxcbiAgdmVyYm9zZSA9IGRlZmF1bHRzLnZlcmJvc2UsXG4gIHNpbGVudCA9IGRlZmF1bHRzLnNpbGVudCxcbiAgbWF4TG9nRmlsZXMsXG59ID0ge30pIHtcbiAgaWYgKHZlcmJvc2UpIHtcbiAgICBsb2dMZXZlbCA9ICd2ZXJib3NlJztcbiAgfVxuXG4gIHdpbnN0b24ubGV2ZWwgPSBsb2dMZXZlbDtcbiAgY29uc3Qgb3B0aW9ucyA9IHt9O1xuXG4gIGlmIChsb2dzRm9sZGVyKSB7XG4gICAgaWYgKCFwYXRoLmlzQWJzb2x1dGUobG9nc0ZvbGRlcikpIHtcbiAgICAgIGxvZ3NGb2xkZXIgPSBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSwgbG9nc0ZvbGRlcik7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBmcy5ta2RpclN5bmMobG9nc0ZvbGRlcik7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLyogKi9cbiAgICB9XG4gIH1cbiAgb3B0aW9ucy5kaXJuYW1lID0gbG9nc0ZvbGRlcjtcbiAgb3B0aW9ucy5sZXZlbCA9IGxvZ0xldmVsO1xuICBvcHRpb25zLnNpbGVudCA9IHNpbGVudDtcbiAgb3B0aW9ucy5tYXhGaWxlcyA9IG1heExvZ0ZpbGVzO1xuXG4gIGlmIChqc29uTG9ncykge1xuICAgIG9wdGlvbnMuanNvbiA9IHRydWU7XG4gICAgb3B0aW9ucy5zdHJpbmdpZnkgPSB0cnVlO1xuICB9XG4gIGNvbmZpZ3VyZVRyYW5zcG9ydHMob3B0aW9ucyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRUcmFuc3BvcnQodHJhbnNwb3J0KSB7XG4gIC8vIHdlIHdpbGwgcmVtb3ZlIHRoZSBleGlzdGluZyB0cmFuc3BvcnRcbiAgLy8gYmVmb3JlIHJlcGxhY2luZyBpdCB3aXRoIGEgbmV3IG9uZVxuICByZW1vdmVUcmFuc3BvcnQodHJhbnNwb3J0Lm5hbWUpO1xuXG4gIGxvZ2dlci5hZGQodHJhbnNwb3J0KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZVRyYW5zcG9ydCh0cmFuc3BvcnQpIHtcbiAgY29uc3QgbWF0Y2hpbmdUcmFuc3BvcnQgPSBsb2dnZXIudHJhbnNwb3J0cy5maW5kKHQxID0+IHtcbiAgICByZXR1cm4gdHlwZW9mIHRyYW5zcG9ydCA9PT0gJ3N0cmluZycgPyB0MS5uYW1lID09PSB0cmFuc3BvcnQgOiB0MSA9PT0gdHJhbnNwb3J0O1xuICB9KTtcblxuICBpZiAobWF0Y2hpbmdUcmFuc3BvcnQpIHtcbiAgICBsb2dnZXIucmVtb3ZlKG1hdGNoaW5nVHJhbnNwb3J0KTtcbiAgfVxufVxuXG5leHBvcnQgeyBsb2dnZXIgfTtcbmV4cG9ydCBkZWZhdWx0IGxvZ2dlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Logger/WinstonLoggerAdapter.js b/lib/Adapters/Logger/WinstonLoggerAdapter.js deleted file mode 100644 index d953c2865e..0000000000 --- a/lib/Adapters/Logger/WinstonLoggerAdapter.js +++ /dev/null @@ -1,75 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.WinstonLoggerAdapter = void 0; - -var _LoggerAdapter = require("./LoggerAdapter"); - -var _WinstonLogger = require("./WinstonLogger"); - -const MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000; - -class WinstonLoggerAdapter extends _LoggerAdapter.LoggerAdapter { - constructor(options) { - super(); - - if (options) { - (0, _WinstonLogger.configureLogger)(options); - } - } - - log() { - return _WinstonLogger.logger.log.apply(_WinstonLogger.logger, arguments); - } - - addTransport(transport) { - // Note that this is calling addTransport - // from logger. See import - confusing. - // but this is not recursive. - (0, _WinstonLogger.addTransport)(transport); - } // custom query as winston is currently limited - - - query(options, callback = () => {}) { - if (!options) { - options = {}; - } // defaults to 7 days prior - - - const from = options.from || new Date(Date.now() - 7 * MILLISECONDS_IN_A_DAY); - const until = options.until || new Date(); - const limit = options.size || 10; - const order = options.order || 'desc'; - const level = options.level || 'info'; - const queryOptions = { - from, - until, - limit, - order - }; - return new Promise((resolve, reject) => { - _WinstonLogger.logger.query(queryOptions, (err, res) => { - if (err) { - callback(err); - return reject(err); - } - - if (level === 'error') { - callback(res['parse-server-error']); - resolve(res['parse-server-error']); - } else { - callback(res['parse-server']); - resolve(res['parse-server']); - } - }); - }); - } - -} - -exports.WinstonLoggerAdapter = WinstonLoggerAdapter; -var _default = WinstonLoggerAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9Mb2dnZXIvV2luc3RvbkxvZ2dlckFkYXB0ZXIuanMiXSwibmFtZXMiOlsiTUlMTElTRUNPTkRTX0lOX0FfREFZIiwiV2luc3RvbkxvZ2dlckFkYXB0ZXIiLCJMb2dnZXJBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJvcHRpb25zIiwibG9nIiwibG9nZ2VyIiwiYXBwbHkiLCJhcmd1bWVudHMiLCJhZGRUcmFuc3BvcnQiLCJ0cmFuc3BvcnQiLCJxdWVyeSIsImNhbGxiYWNrIiwiZnJvbSIsIkRhdGUiLCJub3ciLCJ1bnRpbCIsImxpbWl0Iiwic2l6ZSIsIm9yZGVyIiwibGV2ZWwiLCJxdWVyeU9wdGlvbnMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsImVyciIsInJlcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUVBLE1BQU1BLHFCQUFxQixHQUFHLEtBQUssRUFBTCxHQUFVLEVBQVYsR0FBZSxJQUE3Qzs7QUFFTyxNQUFNQyxvQkFBTixTQUFtQ0MsNEJBQW5DLENBQWlEO0FBQ3REQyxFQUFBQSxXQUFXLENBQUNDLE9BQUQsRUFBVTtBQUNuQjs7QUFDQSxRQUFJQSxPQUFKLEVBQWE7QUFDWCwwQ0FBZ0JBLE9BQWhCO0FBQ0Q7QUFDRjs7QUFFREMsRUFBQUEsR0FBRyxHQUFHO0FBQ0osV0FBT0Msc0JBQU9ELEdBQVAsQ0FBV0UsS0FBWCxDQUFpQkQscUJBQWpCLEVBQXlCRSxTQUF6QixDQUFQO0FBQ0Q7O0FBRURDLEVBQUFBLFlBQVksQ0FBQ0MsU0FBRCxFQUFZO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBLHFDQUFhQSxTQUFiO0FBQ0QsR0FqQnFELENBbUJ0RDs7O0FBQ0FDLEVBQUFBLEtBQUssQ0FBQ1AsT0FBRCxFQUFVUSxRQUFRLEdBQUcsTUFBTSxDQUFFLENBQTdCLEVBQStCO0FBQ2xDLFFBQUksQ0FBQ1IsT0FBTCxFQUFjO0FBQ1pBLE1BQUFBLE9BQU8sR0FBRyxFQUFWO0FBQ0QsS0FIaUMsQ0FJbEM7OztBQUNBLFVBQU1TLElBQUksR0FBR1QsT0FBTyxDQUFDUyxJQUFSLElBQWdCLElBQUlDLElBQUosQ0FBU0EsSUFBSSxDQUFDQyxHQUFMLEtBQWEsSUFBSWYscUJBQTFCLENBQTdCO0FBQ0EsVUFBTWdCLEtBQUssR0FBR1osT0FBTyxDQUFDWSxLQUFSLElBQWlCLElBQUlGLElBQUosRUFBL0I7QUFDQSxVQUFNRyxLQUFLLEdBQUdiLE9BQU8sQ0FBQ2MsSUFBUixJQUFnQixFQUE5QjtBQUNBLFVBQU1DLEtBQUssR0FBR2YsT0FBTyxDQUFDZSxLQUFSLElBQWlCLE1BQS9CO0FBQ0EsVUFBTUMsS0FBSyxHQUFHaEIsT0FBTyxDQUFDZ0IsS0FBUixJQUFpQixNQUEvQjtBQUVBLFVBQU1DLFlBQVksR0FBRztBQUNuQlIsTUFBQUEsSUFEbUI7QUFFbkJHLE1BQUFBLEtBRm1CO0FBR25CQyxNQUFBQSxLQUhtQjtBQUluQkUsTUFBQUE7QUFKbUIsS0FBckI7QUFPQSxXQUFPLElBQUlHLE9BQUosQ0FBWSxDQUFDQyxPQUFELEVBQVVDLE1BQVYsS0FBcUI7QUFDdENsQiw0QkFBT0ssS0FBUCxDQUFhVSxZQUFiLEVBQTJCLENBQUNJLEdBQUQsRUFBTUMsR0FBTixLQUFjO0FBQ3ZDLFlBQUlELEdBQUosRUFBUztBQUNQYixVQUFBQSxRQUFRLENBQUNhLEdBQUQsQ0FBUjtBQUNBLGlCQUFPRCxNQUFNLENBQUNDLEdBQUQsQ0FBYjtBQUNEOztBQUVELFlBQUlMLEtBQUssS0FBSyxPQUFkLEVBQXVCO0FBQ3JCUixVQUFBQSxRQUFRLENBQUNjLEdBQUcsQ0FBQyxvQkFBRCxDQUFKLENBQVI7QUFDQUgsVUFBQUEsT0FBTyxDQUFDRyxHQUFHLENBQUMsb0JBQUQsQ0FBSixDQUFQO0FBQ0QsU0FIRCxNQUdPO0FBQ0xkLFVBQUFBLFFBQVEsQ0FBQ2MsR0FBRyxDQUFDLGNBQUQsQ0FBSixDQUFSO0FBQ0FILFVBQUFBLE9BQU8sQ0FBQ0csR0FBRyxDQUFDLGNBQUQsQ0FBSixDQUFQO0FBQ0Q7QUFDRixPQWJEO0FBY0QsS0FmTSxDQUFQO0FBZ0JEOztBQXREcUQ7OztlQXlEekN6QixvQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExvZ2dlckFkYXB0ZXIgfSBmcm9tICcuL0xvZ2dlckFkYXB0ZXInO1xuaW1wb3J0IHsgbG9nZ2VyLCBhZGRUcmFuc3BvcnQsIGNvbmZpZ3VyZUxvZ2dlciB9IGZyb20gJy4vV2luc3RvbkxvZ2dlcic7XG5cbmNvbnN0IE1JTExJU0VDT05EU19JTl9BX0RBWSA9IDI0ICogNjAgKiA2MCAqIDEwMDA7XG5cbmV4cG9ydCBjbGFzcyBXaW5zdG9uTG9nZ2VyQWRhcHRlciBleHRlbmRzIExvZ2dlckFkYXB0ZXIge1xuICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7XG4gICAgc3VwZXIoKTtcbiAgICBpZiAob3B0aW9ucykge1xuICAgICAgY29uZmlndXJlTG9nZ2VyKG9wdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIGxvZygpIHtcbiAgICByZXR1cm4gbG9nZ2VyLmxvZy5hcHBseShsb2dnZXIsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBhZGRUcmFuc3BvcnQodHJhbnNwb3J0KSB7XG4gICAgLy8gTm90ZSB0aGF0IHRoaXMgaXMgY2FsbGluZyBhZGRUcmFuc3BvcnRcbiAgICAvLyBmcm9tIGxvZ2dlci4gIFNlZSBpbXBvcnQgLSBjb25mdXNpbmcuXG4gICAgLy8gYnV0IHRoaXMgaXMgbm90IHJlY3Vyc2l2ZS5cbiAgICBhZGRUcmFuc3BvcnQodHJhbnNwb3J0KTtcbiAgfVxuXG4gIC8vIGN1c3RvbSBxdWVyeSBhcyB3aW5zdG9uIGlzIGN1cnJlbnRseSBsaW1pdGVkXG4gIHF1ZXJ5KG9wdGlvbnMsIGNhbGxiYWNrID0gKCkgPT4ge30pIHtcbiAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICB9XG4gICAgLy8gZGVmYXVsdHMgdG8gNyBkYXlzIHByaW9yXG4gICAgY29uc3QgZnJvbSA9IG9wdGlvbnMuZnJvbSB8fCBuZXcgRGF0ZShEYXRlLm5vdygpIC0gNyAqIE1JTExJU0VDT05EU19JTl9BX0RBWSk7XG4gICAgY29uc3QgdW50aWwgPSBvcHRpb25zLnVudGlsIHx8IG5ldyBEYXRlKCk7XG4gICAgY29uc3QgbGltaXQgPSBvcHRpb25zLnNpemUgfHwgMTA7XG4gICAgY29uc3Qgb3JkZXIgPSBvcHRpb25zLm9yZGVyIHx8ICdkZXNjJztcbiAgICBjb25zdCBsZXZlbCA9IG9wdGlvbnMubGV2ZWwgfHwgJ2luZm8nO1xuXG4gICAgY29uc3QgcXVlcnlPcHRpb25zID0ge1xuICAgICAgZnJvbSxcbiAgICAgIHVudGlsLFxuICAgICAgbGltaXQsXG4gICAgICBvcmRlcixcbiAgICB9O1xuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGxvZ2dlci5xdWVyeShxdWVyeU9wdGlvbnMsIChlcnIsIHJlcykgPT4ge1xuICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgY2FsbGJhY2soZXJyKTtcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobGV2ZWwgPT09ICdlcnJvcicpIHtcbiAgICAgICAgICBjYWxsYmFjayhyZXNbJ3BhcnNlLXNlcnZlci1lcnJvciddKTtcbiAgICAgICAgICByZXNvbHZlKHJlc1sncGFyc2Utc2VydmVyLWVycm9yJ10pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNhbGxiYWNrKHJlc1sncGFyc2Utc2VydmVyJ10pO1xuICAgICAgICAgIHJlc29sdmUocmVzWydwYXJzZS1zZXJ2ZXInXSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFdpbnN0b25Mb2dnZXJBZGFwdGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/MessageQueue/EventEmitterMQ.js b/lib/Adapters/MessageQueue/EventEmitterMQ.js deleted file mode 100644 index ddf372cd6d..0000000000 --- a/lib/Adapters/MessageQueue/EventEmitterMQ.js +++ /dev/null @@ -1,73 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.EventEmitterMQ = void 0; - -var _events = _interopRequireDefault(require("events")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const emitter = new _events.default.EventEmitter(); -const subscriptions = new Map(); - -function unsubscribe(channel) { - if (!subscriptions.has(channel)) { - //console.log('No channel to unsub from'); - return; - } //console.log('unsub ', channel); - - - emitter.removeListener(channel, subscriptions.get(channel)); - subscriptions.delete(channel); -} - -class Publisher { - constructor(emitter) { - this.emitter = emitter; - } - - publish(channel, message) { - this.emitter.emit(channel, message); - } - -} - -class Consumer extends _events.default.EventEmitter { - constructor(emitter) { - super(); - this.emitter = emitter; - } - - subscribe(channel) { - unsubscribe(channel); - - const handler = message => { - this.emit('message', channel, message); - }; - - subscriptions.set(channel, handler); - this.emitter.on(channel, handler); - } - - unsubscribe(channel) { - unsubscribe(channel); - } - -} - -function createPublisher() { - return new Publisher(emitter); -} - -function createSubscriber() { - return new Consumer(emitter); -} - -const EventEmitterMQ = { - createPublisher, - createSubscriber -}; -exports.EventEmitterMQ = EventEmitterMQ; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9NZXNzYWdlUXVldWUvRXZlbnRFbWl0dGVyTVEuanMiXSwibmFtZXMiOlsiZW1pdHRlciIsImV2ZW50cyIsIkV2ZW50RW1pdHRlciIsInN1YnNjcmlwdGlvbnMiLCJNYXAiLCJ1bnN1YnNjcmliZSIsImNoYW5uZWwiLCJoYXMiLCJyZW1vdmVMaXN0ZW5lciIsImdldCIsImRlbGV0ZSIsIlB1Ymxpc2hlciIsImNvbnN0cnVjdG9yIiwicHVibGlzaCIsIm1lc3NhZ2UiLCJlbWl0IiwiQ29uc3VtZXIiLCJzdWJzY3JpYmUiLCJoYW5kbGVyIiwic2V0Iiwib24iLCJjcmVhdGVQdWJsaXNoZXIiLCJjcmVhdGVTdWJzY3JpYmVyIiwiRXZlbnRFbWl0dGVyTVEiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7OztBQUVBLE1BQU1BLE9BQU8sR0FBRyxJQUFJQyxnQkFBT0MsWUFBWCxFQUFoQjtBQUNBLE1BQU1DLGFBQWEsR0FBRyxJQUFJQyxHQUFKLEVBQXRCOztBQUVBLFNBQVNDLFdBQVQsQ0FBcUJDLE9BQXJCLEVBQXNDO0FBQ3BDLE1BQUksQ0FBQ0gsYUFBYSxDQUFDSSxHQUFkLENBQWtCRCxPQUFsQixDQUFMLEVBQWlDO0FBQy9CO0FBQ0E7QUFDRCxHQUptQyxDQUtwQzs7O0FBQ0FOLEVBQUFBLE9BQU8sQ0FBQ1EsY0FBUixDQUF1QkYsT0FBdkIsRUFBZ0NILGFBQWEsQ0FBQ00sR0FBZCxDQUFrQkgsT0FBbEIsQ0FBaEM7QUFDQUgsRUFBQUEsYUFBYSxDQUFDTyxNQUFkLENBQXFCSixPQUFyQjtBQUNEOztBQUVELE1BQU1LLFNBQU4sQ0FBZ0I7QUFHZEMsRUFBQUEsV0FBVyxDQUFDWixPQUFELEVBQWU7QUFDeEIsU0FBS0EsT0FBTCxHQUFlQSxPQUFmO0FBQ0Q7O0FBRURhLEVBQUFBLE9BQU8sQ0FBQ1AsT0FBRCxFQUFrQlEsT0FBbEIsRUFBeUM7QUFDOUMsU0FBS2QsT0FBTCxDQUFhZSxJQUFiLENBQWtCVCxPQUFsQixFQUEyQlEsT0FBM0I7QUFDRDs7QUFUYTs7QUFZaEIsTUFBTUUsUUFBTixTQUF1QmYsZ0JBQU9DLFlBQTlCLENBQTJDO0FBR3pDVSxFQUFBQSxXQUFXLENBQUNaLE9BQUQsRUFBZTtBQUN4QjtBQUNBLFNBQUtBLE9BQUwsR0FBZUEsT0FBZjtBQUNEOztBQUVEaUIsRUFBQUEsU0FBUyxDQUFDWCxPQUFELEVBQXdCO0FBQy9CRCxJQUFBQSxXQUFXLENBQUNDLE9BQUQsQ0FBWDs7QUFDQSxVQUFNWSxPQUFPLEdBQUdKLE9BQU8sSUFBSTtBQUN6QixXQUFLQyxJQUFMLENBQVUsU0FBVixFQUFxQlQsT0FBckIsRUFBOEJRLE9BQTlCO0FBQ0QsS0FGRDs7QUFHQVgsSUFBQUEsYUFBYSxDQUFDZ0IsR0FBZCxDQUFrQmIsT0FBbEIsRUFBMkJZLE9BQTNCO0FBQ0EsU0FBS2xCLE9BQUwsQ0FBYW9CLEVBQWIsQ0FBZ0JkLE9BQWhCLEVBQXlCWSxPQUF6QjtBQUNEOztBQUVEYixFQUFBQSxXQUFXLENBQUNDLE9BQUQsRUFBd0I7QUFDakNELElBQUFBLFdBQVcsQ0FBQ0MsT0FBRCxDQUFYO0FBQ0Q7O0FBbkJ3Qzs7QUFzQjNDLFNBQVNlLGVBQVQsR0FBZ0M7QUFDOUIsU0FBTyxJQUFJVixTQUFKLENBQWNYLE9BQWQsQ0FBUDtBQUNEOztBQUVELFNBQVNzQixnQkFBVCxHQUFpQztBQUMvQixTQUFPLElBQUlOLFFBQUosQ0FBYWhCLE9BQWIsQ0FBUDtBQUNEOztBQUVELE1BQU11QixjQUFjLEdBQUc7QUFDckJGLEVBQUFBLGVBRHFCO0FBRXJCQyxFQUFBQTtBQUZxQixDQUF2QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBldmVudHMgZnJvbSAnZXZlbnRzJztcblxuY29uc3QgZW1pdHRlciA9IG5ldyBldmVudHMuRXZlbnRFbWl0dGVyKCk7XG5jb25zdCBzdWJzY3JpcHRpb25zID0gbmV3IE1hcCgpO1xuXG5mdW5jdGlvbiB1bnN1YnNjcmliZShjaGFubmVsOiBzdHJpbmcpIHtcbiAgaWYgKCFzdWJzY3JpcHRpb25zLmhhcyhjaGFubmVsKSkge1xuICAgIC8vY29uc29sZS5sb2coJ05vIGNoYW5uZWwgdG8gdW5zdWIgZnJvbScpO1xuICAgIHJldHVybjtcbiAgfVxuICAvL2NvbnNvbGUubG9nKCd1bnN1YiAnLCBjaGFubmVsKTtcbiAgZW1pdHRlci5yZW1vdmVMaXN0ZW5lcihjaGFubmVsLCBzdWJzY3JpcHRpb25zLmdldChjaGFubmVsKSk7XG4gIHN1YnNjcmlwdGlvbnMuZGVsZXRlKGNoYW5uZWwpO1xufVxuXG5jbGFzcyBQdWJsaXNoZXIge1xuICBlbWl0dGVyOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoZW1pdHRlcjogYW55KSB7XG4gICAgdGhpcy5lbWl0dGVyID0gZW1pdHRlcjtcbiAgfVxuXG4gIHB1Ymxpc2goY2hhbm5lbDogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmVtaXR0ZXIuZW1pdChjaGFubmVsLCBtZXNzYWdlKTtcbiAgfVxufVxuXG5jbGFzcyBDb25zdW1lciBleHRlbmRzIGV2ZW50cy5FdmVudEVtaXR0ZXIge1xuICBlbWl0dGVyOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoZW1pdHRlcjogYW55KSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmVtaXR0ZXIgPSBlbWl0dGVyO1xuICB9XG5cbiAgc3Vic2NyaWJlKGNoYW5uZWw6IHN0cmluZyk6IHZvaWQge1xuICAgIHVuc3Vic2NyaWJlKGNoYW5uZWwpO1xuICAgIGNvbnN0IGhhbmRsZXIgPSBtZXNzYWdlID0+IHtcbiAgICAgIHRoaXMuZW1pdCgnbWVzc2FnZScsIGNoYW5uZWwsIG1lc3NhZ2UpO1xuICAgIH07XG4gICAgc3Vic2NyaXB0aW9ucy5zZXQoY2hhbm5lbCwgaGFuZGxlcik7XG4gICAgdGhpcy5lbWl0dGVyLm9uKGNoYW5uZWwsIGhhbmRsZXIpO1xuICB9XG5cbiAgdW5zdWJzY3JpYmUoY2hhbm5lbDogc3RyaW5nKTogdm9pZCB7XG4gICAgdW5zdWJzY3JpYmUoY2hhbm5lbCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlUHVibGlzaGVyKCk6IGFueSB7XG4gIHJldHVybiBuZXcgUHVibGlzaGVyKGVtaXR0ZXIpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVTdWJzY3JpYmVyKCk6IGFueSB7XG4gIHJldHVybiBuZXcgQ29uc3VtZXIoZW1pdHRlcik7XG59XG5cbmNvbnN0IEV2ZW50RW1pdHRlck1RID0ge1xuICBjcmVhdGVQdWJsaXNoZXIsXG4gIGNyZWF0ZVN1YnNjcmliZXIsXG59O1xuXG5leHBvcnQgeyBFdmVudEVtaXR0ZXJNUSB9O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/PubSub/EventEmitterPubSub.js b/lib/Adapters/PubSub/EventEmitterPubSub.js deleted file mode 100644 index 8c3c66ff90..0000000000 --- a/lib/Adapters/PubSub/EventEmitterPubSub.js +++ /dev/null @@ -1,69 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.EventEmitterPubSub = void 0; - -var _events = _interopRequireDefault(require("events")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const emitter = new _events.default.EventEmitter(); - -class Publisher { - constructor(emitter) { - this.emitter = emitter; - } - - publish(channel, message) { - this.emitter.emit(channel, message); - } - -} - -class Subscriber extends _events.default.EventEmitter { - constructor(emitter) { - super(); - this.emitter = emitter; - this.subscriptions = new Map(); - } - - subscribe(channel) { - const handler = message => { - this.emit('message', channel, message); - }; - - this.subscriptions.set(channel, handler); - this.emitter.on(channel, handler); - } - - unsubscribe(channel) { - if (!this.subscriptions.has(channel)) { - return; - } - - this.emitter.removeListener(channel, this.subscriptions.get(channel)); - this.subscriptions.delete(channel); - } - -} - -function createPublisher() { - return new Publisher(emitter); -} - -function createSubscriber() { - // createSubscriber is called once at live query server start - // to avoid max listeners warning, we should clean up the event emitter - // each time this function is called - emitter.removeAllListeners(); - return new Subscriber(emitter); -} - -const EventEmitterPubSub = { - createPublisher, - createSubscriber -}; -exports.EventEmitterPubSub = EventEmitterPubSub; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9QdWJTdWIvRXZlbnRFbWl0dGVyUHViU3ViLmpzIl0sIm5hbWVzIjpbImVtaXR0ZXIiLCJldmVudHMiLCJFdmVudEVtaXR0ZXIiLCJQdWJsaXNoZXIiLCJjb25zdHJ1Y3RvciIsInB1Ymxpc2giLCJjaGFubmVsIiwibWVzc2FnZSIsImVtaXQiLCJTdWJzY3JpYmVyIiwic3Vic2NyaXB0aW9ucyIsIk1hcCIsInN1YnNjcmliZSIsImhhbmRsZXIiLCJzZXQiLCJvbiIsInVuc3Vic2NyaWJlIiwiaGFzIiwicmVtb3ZlTGlzdGVuZXIiLCJnZXQiLCJkZWxldGUiLCJjcmVhdGVQdWJsaXNoZXIiLCJjcmVhdGVTdWJzY3JpYmVyIiwicmVtb3ZlQWxsTGlzdGVuZXJzIiwiRXZlbnRFbWl0dGVyUHViU3ViIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7Ozs7QUFFQSxNQUFNQSxPQUFPLEdBQUcsSUFBSUMsZ0JBQU9DLFlBQVgsRUFBaEI7O0FBRUEsTUFBTUMsU0FBTixDQUFnQjtBQUdkQyxFQUFBQSxXQUFXLENBQUNKLE9BQUQsRUFBZTtBQUN4QixTQUFLQSxPQUFMLEdBQWVBLE9BQWY7QUFDRDs7QUFFREssRUFBQUEsT0FBTyxDQUFDQyxPQUFELEVBQWtCQyxPQUFsQixFQUF5QztBQUM5QyxTQUFLUCxPQUFMLENBQWFRLElBQWIsQ0FBa0JGLE9BQWxCLEVBQTJCQyxPQUEzQjtBQUNEOztBQVRhOztBQVloQixNQUFNRSxVQUFOLFNBQXlCUixnQkFBT0MsWUFBaEMsQ0FBNkM7QUFJM0NFLEVBQUFBLFdBQVcsQ0FBQ0osT0FBRCxFQUFlO0FBQ3hCO0FBQ0EsU0FBS0EsT0FBTCxHQUFlQSxPQUFmO0FBQ0EsU0FBS1UsYUFBTCxHQUFxQixJQUFJQyxHQUFKLEVBQXJCO0FBQ0Q7O0FBRURDLEVBQUFBLFNBQVMsQ0FBQ04sT0FBRCxFQUF3QjtBQUMvQixVQUFNTyxPQUFPLEdBQUdOLE9BQU8sSUFBSTtBQUN6QixXQUFLQyxJQUFMLENBQVUsU0FBVixFQUFxQkYsT0FBckIsRUFBOEJDLE9BQTlCO0FBQ0QsS0FGRDs7QUFHQSxTQUFLRyxhQUFMLENBQW1CSSxHQUFuQixDQUF1QlIsT0FBdkIsRUFBZ0NPLE9BQWhDO0FBQ0EsU0FBS2IsT0FBTCxDQUFhZSxFQUFiLENBQWdCVCxPQUFoQixFQUF5Qk8sT0FBekI7QUFDRDs7QUFFREcsRUFBQUEsV0FBVyxDQUFDVixPQUFELEVBQXdCO0FBQ2pDLFFBQUksQ0FBQyxLQUFLSSxhQUFMLENBQW1CTyxHQUFuQixDQUF1QlgsT0FBdkIsQ0FBTCxFQUFzQztBQUNwQztBQUNEOztBQUNELFNBQUtOLE9BQUwsQ0FBYWtCLGNBQWIsQ0FBNEJaLE9BQTVCLEVBQXFDLEtBQUtJLGFBQUwsQ0FBbUJTLEdBQW5CLENBQXVCYixPQUF2QixDQUFyQztBQUNBLFNBQUtJLGFBQUwsQ0FBbUJVLE1BQW5CLENBQTBCZCxPQUExQjtBQUNEOztBQXhCMEM7O0FBMkI3QyxTQUFTZSxlQUFULEdBQWdDO0FBQzlCLFNBQU8sSUFBSWxCLFNBQUosQ0FBY0gsT0FBZCxDQUFQO0FBQ0Q7O0FBRUQsU0FBU3NCLGdCQUFULEdBQWlDO0FBQy9CO0FBQ0E7QUFDQTtBQUNBdEIsRUFBQUEsT0FBTyxDQUFDdUIsa0JBQVI7QUFDQSxTQUFPLElBQUlkLFVBQUosQ0FBZVQsT0FBZixDQUFQO0FBQ0Q7O0FBRUQsTUFBTXdCLGtCQUFrQixHQUFHO0FBQ3pCSCxFQUFBQSxlQUR5QjtBQUV6QkMsRUFBQUE7QUFGeUIsQ0FBM0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZXZlbnRzIGZyb20gJ2V2ZW50cyc7XG5cbmNvbnN0IGVtaXR0ZXIgPSBuZXcgZXZlbnRzLkV2ZW50RW1pdHRlcigpO1xuXG5jbGFzcyBQdWJsaXNoZXIge1xuICBlbWl0dGVyOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoZW1pdHRlcjogYW55KSB7XG4gICAgdGhpcy5lbWl0dGVyID0gZW1pdHRlcjtcbiAgfVxuXG4gIHB1Ymxpc2goY2hhbm5lbDogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmVtaXR0ZXIuZW1pdChjaGFubmVsLCBtZXNzYWdlKTtcbiAgfVxufVxuXG5jbGFzcyBTdWJzY3JpYmVyIGV4dGVuZHMgZXZlbnRzLkV2ZW50RW1pdHRlciB7XG4gIGVtaXR0ZXI6IGFueTtcbiAgc3Vic2NyaXB0aW9uczogYW55O1xuXG4gIGNvbnN0cnVjdG9yKGVtaXR0ZXI6IGFueSkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5lbWl0dGVyID0gZW1pdHRlcjtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMgPSBuZXcgTWFwKCk7XG4gIH1cblxuICBzdWJzY3JpYmUoY2hhbm5lbDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgaGFuZGxlciA9IG1lc3NhZ2UgPT4ge1xuICAgICAgdGhpcy5lbWl0KCdtZXNzYWdlJywgY2hhbm5lbCwgbWVzc2FnZSk7XG4gICAgfTtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuc2V0KGNoYW5uZWwsIGhhbmRsZXIpO1xuICAgIHRoaXMuZW1pdHRlci5vbihjaGFubmVsLCBoYW5kbGVyKTtcbiAgfVxuXG4gIHVuc3Vic2NyaWJlKGNoYW5uZWw6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghdGhpcy5zdWJzY3JpcHRpb25zLmhhcyhjaGFubmVsKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmVtaXR0ZXIucmVtb3ZlTGlzdGVuZXIoY2hhbm5lbCwgdGhpcy5zdWJzY3JpcHRpb25zLmdldChjaGFubmVsKSk7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmRlbGV0ZShjaGFubmVsKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVQdWJsaXNoZXIoKTogYW55IHtcbiAgcmV0dXJuIG5ldyBQdWJsaXNoZXIoZW1pdHRlcik7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVN1YnNjcmliZXIoKTogYW55IHtcbiAgLy8gY3JlYXRlU3Vic2NyaWJlciBpcyBjYWxsZWQgb25jZSBhdCBsaXZlIHF1ZXJ5IHNlcnZlciBzdGFydFxuICAvLyB0byBhdm9pZCBtYXggbGlzdGVuZXJzIHdhcm5pbmcsIHdlIHNob3VsZCBjbGVhbiB1cCB0aGUgZXZlbnQgZW1pdHRlclxuICAvLyBlYWNoIHRpbWUgdGhpcyBmdW5jdGlvbiBpcyBjYWxsZWRcbiAgZW1pdHRlci5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcbiAgcmV0dXJuIG5ldyBTdWJzY3JpYmVyKGVtaXR0ZXIpO1xufVxuXG5jb25zdCBFdmVudEVtaXR0ZXJQdWJTdWIgPSB7XG4gIGNyZWF0ZVB1Ymxpc2hlcixcbiAgY3JlYXRlU3Vic2NyaWJlcixcbn07XG5cbmV4cG9ydCB7IEV2ZW50RW1pdHRlclB1YlN1YiB9O1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/PubSub/PubSubAdapter.js b/lib/Adapters/PubSub/PubSubAdapter.js deleted file mode 100644 index 13ad87a701..0000000000 --- a/lib/Adapters/PubSub/PubSubAdapter.js +++ /dev/null @@ -1,39 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.PubSubAdapter = void 0; - -/*eslint no-unused-vars: "off"*/ - -/** - * @module Adapters - */ - -/** - * @interface PubSubAdapter - */ -class PubSubAdapter { - /** - * @returns {PubSubAdapter.Publisher} - */ - static createPublisher() {} - /** - * @returns {PubSubAdapter.Subscriber} - */ - - - static createSubscriber() {} - -} -/** - * @interface Publisher - * @memberof PubSubAdapter - */ - - -exports.PubSubAdapter = PubSubAdapter; -var _default = PubSubAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9QdWJTdWIvUHViU3ViQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJQdWJTdWJBZGFwdGVyIiwiY3JlYXRlUHVibGlzaGVyIiwiY3JlYXRlU3Vic2NyaWJlciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBO0FBQ0E7QUFDQTs7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNQSxhQUFOLENBQW9CO0FBQ3pCO0FBQ0Y7QUFDQTtBQUNFLFNBQU9DLGVBQVAsR0FBeUIsQ0FBRTtBQUMzQjtBQUNGO0FBQ0E7OztBQUNFLFNBQU9DLGdCQUFQLEdBQTBCLENBQUU7O0FBUkg7QUFXM0I7QUFDQTtBQUNBO0FBQ0E7Ozs7ZUEyQmVGLGEiLCJzb3VyY2VzQ29udGVudCI6WyIvKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG4vKipcbiAqIEBtb2R1bGUgQWRhcHRlcnNcbiAqL1xuLyoqXG4gKiBAaW50ZXJmYWNlIFB1YlN1YkFkYXB0ZXJcbiAqL1xuZXhwb3J0IGNsYXNzIFB1YlN1YkFkYXB0ZXIge1xuICAvKipcbiAgICogQHJldHVybnMge1B1YlN1YkFkYXB0ZXIuUHVibGlzaGVyfVxuICAgKi9cbiAgc3RhdGljIGNyZWF0ZVB1Ymxpc2hlcigpIHt9XG4gIC8qKlxuICAgKiBAcmV0dXJucyB7UHViU3ViQWRhcHRlci5TdWJzY3JpYmVyfVxuICAgKi9cbiAgc3RhdGljIGNyZWF0ZVN1YnNjcmliZXIoKSB7fVxufVxuXG4vKipcbiAqIEBpbnRlcmZhY2UgUHVibGlzaGVyXG4gKiBAbWVtYmVyb2YgUHViU3ViQWRhcHRlclxuICovXG5pbnRlcmZhY2UgUHVibGlzaGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBjaGFubmVsIHRoZSBjaGFubmVsIGluIHdoaWNoIHRvIHB1Ymxpc2hcbiAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2UgdGhlIG1lc3NhZ2UgdG8gcHVibGlzaFxuICAgKi9cbiAgcHVibGlzaChjaGFubmVsOiBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZyk6IHZvaWQ7XG59XG5cbi8qKlxuICogQGludGVyZmFjZSBTdWJzY3JpYmVyXG4gKiBAbWVtYmVyb2YgUHViU3ViQWRhcHRlclxuICovXG5pbnRlcmZhY2UgU3Vic2NyaWJlciB7XG4gIC8qKlxuICAgKiBjYWxsZWQgd2hlbiBhIG5ldyBzdWJzY3JpcHRpb24gdGhlIGNoYW5uZWwgaXMgcmVxdWlyZWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IGNoYW5uZWwgdGhlIGNoYW5uZWwgdG8gc3Vic2NyaWJlXG4gICAqL1xuICBzdWJzY3JpYmUoY2hhbm5lbDogc3RyaW5nKTogdm9pZDtcblxuICAvKipcbiAgICogY2FsbGVkIHdoZW4gdGhlIHN1YnNjcmlwdGlvbiBmcm9tIHRoZSBjaGFubmVsIHNob3VsZCBiZSBzdG9wcGVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBjaGFubmVsXG4gICAqL1xuICB1bnN1YnNjcmliZShjaGFubmVsOiBzdHJpbmcpOiB2b2lkO1xufVxuXG5leHBvcnQgZGVmYXVsdCBQdWJTdWJBZGFwdGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/PubSub/RedisPubSub.js b/lib/Adapters/PubSub/RedisPubSub.js deleted file mode 100644 index cb4a03c10a..0000000000 --- a/lib/Adapters/PubSub/RedisPubSub.js +++ /dev/null @@ -1,33 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.RedisPubSub = void 0; - -var _redis = _interopRequireDefault(require("redis")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function createPublisher({ - redisURL, - redisOptions = {} -}) { - redisOptions.no_ready_check = true; - return _redis.default.createClient(redisURL, redisOptions); -} - -function createSubscriber({ - redisURL, - redisOptions = {} -}) { - redisOptions.no_ready_check = true; - return _redis.default.createClient(redisURL, redisOptions); -} - -const RedisPubSub = { - createPublisher, - createSubscriber -}; -exports.RedisPubSub = RedisPubSub; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9QdWJTdWIvUmVkaXNQdWJTdWIuanMiXSwibmFtZXMiOlsiY3JlYXRlUHVibGlzaGVyIiwicmVkaXNVUkwiLCJyZWRpc09wdGlvbnMiLCJub19yZWFkeV9jaGVjayIsInJlZGlzIiwiY3JlYXRlQ2xpZW50IiwiY3JlYXRlU3Vic2NyaWJlciIsIlJlZGlzUHViU3ViIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7Ozs7QUFFQSxTQUFTQSxlQUFULENBQXlCO0FBQUVDLEVBQUFBLFFBQUY7QUFBWUMsRUFBQUEsWUFBWSxHQUFHO0FBQTNCLENBQXpCLEVBQStEO0FBQzdEQSxFQUFBQSxZQUFZLENBQUNDLGNBQWIsR0FBOEIsSUFBOUI7QUFDQSxTQUFPQyxlQUFNQyxZQUFOLENBQW1CSixRQUFuQixFQUE2QkMsWUFBN0IsQ0FBUDtBQUNEOztBQUVELFNBQVNJLGdCQUFULENBQTBCO0FBQUVMLEVBQUFBLFFBQUY7QUFBWUMsRUFBQUEsWUFBWSxHQUFHO0FBQTNCLENBQTFCLEVBQWdFO0FBQzlEQSxFQUFBQSxZQUFZLENBQUNDLGNBQWIsR0FBOEIsSUFBOUI7QUFDQSxTQUFPQyxlQUFNQyxZQUFOLENBQW1CSixRQUFuQixFQUE2QkMsWUFBN0IsQ0FBUDtBQUNEOztBQUVELE1BQU1LLFdBQVcsR0FBRztBQUNsQlAsRUFBQUEsZUFEa0I7QUFFbEJNLEVBQUFBO0FBRmtCLENBQXBCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHJlZGlzIGZyb20gJ3JlZGlzJztcblxuZnVuY3Rpb24gY3JlYXRlUHVibGlzaGVyKHsgcmVkaXNVUkwsIHJlZGlzT3B0aW9ucyA9IHt9IH0pOiBhbnkge1xuICByZWRpc09wdGlvbnMubm9fcmVhZHlfY2hlY2sgPSB0cnVlO1xuICByZXR1cm4gcmVkaXMuY3JlYXRlQ2xpZW50KHJlZGlzVVJMLCByZWRpc09wdGlvbnMpO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVTdWJzY3JpYmVyKHsgcmVkaXNVUkwsIHJlZGlzT3B0aW9ucyA9IHt9IH0pOiBhbnkge1xuICByZWRpc09wdGlvbnMubm9fcmVhZHlfY2hlY2sgPSB0cnVlO1xuICByZXR1cm4gcmVkaXMuY3JlYXRlQ2xpZW50KHJlZGlzVVJMLCByZWRpc09wdGlvbnMpO1xufVxuXG5jb25zdCBSZWRpc1B1YlN1YiA9IHtcbiAgY3JlYXRlUHVibGlzaGVyLFxuICBjcmVhdGVTdWJzY3JpYmVyLFxufTtcblxuZXhwb3J0IHsgUmVkaXNQdWJTdWIgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Push/PushAdapter.js b/lib/Adapters/Push/PushAdapter.js deleted file mode 100644 index 72fd17e1bf..0000000000 --- a/lib/Adapters/Push/PushAdapter.js +++ /dev/null @@ -1,50 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.PushAdapter = void 0; - -/*eslint no-unused-vars: "off"*/ -// Push Adapter -// -// Allows you to change the push notification mechanism. -// -// Adapter classes must implement the following functions: -// * getValidPushTypes() -// * send(devices, installations, pushStatus) -// -// Default is ParsePushAdapter, which uses GCM for -// android push and APNS for ios push. - -/** - * @module Adapters - */ - -/** - * @interface PushAdapter - */ -class PushAdapter { - /** - * @param {any} body - * @param {Parse.Installation[]} installations - * @param {any} pushStatus - * @returns {Promise} - */ - send(body, installations, pushStatus) {} - /** - * Get an array of valid push types. - * @returns {Array} An array of valid push types - */ - - - getValidPushTypes() { - return []; - } - -} - -exports.PushAdapter = PushAdapter; -var _default = PushAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9QdXNoL1B1c2hBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIlB1c2hBZGFwdGVyIiwic2VuZCIsImJvZHkiLCJpbnN0YWxsYXRpb25zIiwicHVzaFN0YXR1cyIsImdldFZhbGlkUHVzaFR5cGVzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBQ0E7QUFDQTtBQUNBO0FBQ08sTUFBTUEsV0FBTixDQUFrQjtBQUN2QjtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDRUMsRUFBQUEsSUFBSSxDQUFDQyxJQUFELEVBQVlDLGFBQVosRUFBa0NDLFVBQWxDLEVBQWdFLENBQUU7QUFFdEU7QUFDRjtBQUNBO0FBQ0E7OztBQUNFQyxFQUFBQSxpQkFBaUIsR0FBYTtBQUM1QixXQUFPLEVBQVA7QUFDRDs7QUFmc0I7OztlQWtCVkwsVyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG4vKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG4vLyBQdXNoIEFkYXB0ZXJcbi8vXG4vLyBBbGxvd3MgeW91IHRvIGNoYW5nZSB0aGUgcHVzaCBub3RpZmljYXRpb24gbWVjaGFuaXNtLlxuLy9cbi8vIEFkYXB0ZXIgY2xhc3NlcyBtdXN0IGltcGxlbWVudCB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uczpcbi8vICogZ2V0VmFsaWRQdXNoVHlwZXMoKVxuLy8gKiBzZW5kKGRldmljZXMsIGluc3RhbGxhdGlvbnMsIHB1c2hTdGF0dXMpXG4vL1xuLy8gRGVmYXVsdCBpcyBQYXJzZVB1c2hBZGFwdGVyLCB3aGljaCB1c2VzIEdDTSBmb3Jcbi8vIGFuZHJvaWQgcHVzaCBhbmQgQVBOUyBmb3IgaW9zIHB1c2guXG5cbi8qKlxuICogQG1vZHVsZSBBZGFwdGVyc1xuICovXG4vKipcbiAqIEBpbnRlcmZhY2UgUHVzaEFkYXB0ZXJcbiAqL1xuZXhwb3J0IGNsYXNzIFB1c2hBZGFwdGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSB7YW55fSBib2R5XG4gICAqIEBwYXJhbSB7UGFyc2UuSW5zdGFsbGF0aW9uW119IGluc3RhbGxhdGlvbnNcbiAgICogQHBhcmFtIHthbnl9IHB1c2hTdGF0dXNcbiAgICogQHJldHVybnMge1Byb21pc2V9XG4gICAqL1xuICBzZW5kKGJvZHk6IGFueSwgaW5zdGFsbGF0aW9uczogYW55W10sIHB1c2hTdGF0dXM6IGFueSk6ID9Qcm9taXNlPCo+IHt9XG5cbiAgLyoqXG4gICAqIEdldCBhbiBhcnJheSBvZiB2YWxpZCBwdXNoIHR5cGVzLlxuICAgKiBAcmV0dXJucyB7QXJyYXl9IEFuIGFycmF5IG9mIHZhbGlkIHB1c2ggdHlwZXNcbiAgICovXG4gIGdldFZhbGlkUHVzaFR5cGVzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gW107XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUHVzaEFkYXB0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Storage/Mongo/MongoCollection.js b/lib/Adapters/Storage/Mongo/MongoCollection.js deleted file mode 100644 index 3845114bc5..0000000000 --- a/lib/Adapters/Storage/Mongo/MongoCollection.js +++ /dev/null @@ -1,229 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -const mongodb = require('mongodb'); - -const Collection = mongodb.Collection; - -class MongoCollection { - constructor(mongoCollection) { - this._mongoCollection = mongoCollection; - } // Does a find with "smart indexing". - // Currently this just means, if it needs a geoindex and there is - // none, then build the geoindex. - // This could be improved a lot but it's not clear if that's a good - // idea. Or even if this behavior is a good idea. - - - find(query, { - skip, - limit, - sort, - keys, - maxTimeMS, - readPreference, - hint, - caseInsensitive, - explain - } = {}) { - // Support for Full Text Search - $text - if (keys && keys.$score) { - delete keys.$score; - keys.score = { - $meta: 'textScore' - }; - } - - return this._rawFind(query, { - skip, - limit, - sort, - keys, - maxTimeMS, - readPreference, - hint, - caseInsensitive, - explain - }).catch(error => { - // Check for "no geoindex" error - if (error.code != 17007 && !error.message.match(/unable to find index for .geoNear/)) { - throw error; - } // Figure out what key needs an index - - - const key = error.message.match(/field=([A-Za-z_0-9]+) /)[1]; - - if (!key) { - throw error; - } - - var index = {}; - index[key] = '2d'; - return this._mongoCollection.createIndex(index) // Retry, but just once. - .then(() => this._rawFind(query, { - skip, - limit, - sort, - keys, - maxTimeMS, - readPreference, - hint, - caseInsensitive, - explain - })); - }); - } - /** - * Collation to support case insensitive queries - */ - - - static caseInsensitiveCollation() { - return { - locale: 'en_US', - strength: 2 - }; - } - - _rawFind(query, { - skip, - limit, - sort, - keys, - maxTimeMS, - readPreference, - hint, - caseInsensitive, - explain - } = {}) { - let findOperation = this._mongoCollection.find(query, { - skip, - limit, - sort, - readPreference, - hint - }); - - if (keys) { - findOperation = findOperation.project(keys); - } - - if (caseInsensitive) { - findOperation = findOperation.collation(MongoCollection.caseInsensitiveCollation()); - } - - if (maxTimeMS) { - findOperation = findOperation.maxTimeMS(maxTimeMS); - } - - return explain ? findOperation.explain(explain) : findOperation.toArray(); - } - - count(query, { - skip, - limit, - sort, - maxTimeMS, - readPreference, - hint - } = {}) { - // If query is empty, then use estimatedDocumentCount instead. - // This is due to countDocuments performing a scan, - // which greatly increases execution time when being run on large collections. - // See https://github.com/Automattic/mongoose/issues/6713 for more info regarding this problem. - if (typeof query !== 'object' || !Object.keys(query).length) { - return this._mongoCollection.estimatedDocumentCount({ - maxTimeMS - }); - } - - const countOperation = this._mongoCollection.countDocuments(query, { - skip, - limit, - sort, - maxTimeMS, - readPreference, - hint - }); - - return countOperation; - } - - distinct(field, query) { - return this._mongoCollection.distinct(field, query); - } - - aggregate(pipeline, { - maxTimeMS, - readPreference, - hint, - explain - } = {}) { - return this._mongoCollection.aggregate(pipeline, { - maxTimeMS, - readPreference, - hint, - explain - }).toArray(); - } - - insertOne(object, session) { - return this._mongoCollection.insertOne(object, { - session - }); - } // Atomically updates data in the database for a single (first) object that matched the query - // If there is nothing that matches the query - does insert - // Postgres Note: `INSERT ... ON CONFLICT UPDATE` that is available since 9.5. - - - upsertOne(query, update, session) { - return this._mongoCollection.updateOne(query, update, { - upsert: true, - session - }); - } - - updateOne(query, update) { - return this._mongoCollection.updateOne(query, update); - } - - updateMany(query, update, session) { - return this._mongoCollection.updateMany(query, update, { - session - }); - } - - deleteMany(query, session) { - return this._mongoCollection.deleteMany(query, { - session - }); - } - - _ensureSparseUniqueIndexInBackground(indexRequest) { - return new Promise((resolve, reject) => { - this._mongoCollection.createIndex(indexRequest, { - unique: true, - background: true, - sparse: true - }, error => { - if (error) { - reject(error); - } else { - resolve(); - } - }); - }); - } - - drop() { - return this._mongoCollection.drop(); - } - -} - -exports.default = MongoCollection; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvQ29sbGVjdGlvbi5qcyJdLCJuYW1lcyI6WyJtb25nb2RiIiwicmVxdWlyZSIsIkNvbGxlY3Rpb24iLCJNb25nb0NvbGxlY3Rpb24iLCJjb25zdHJ1Y3RvciIsIm1vbmdvQ29sbGVjdGlvbiIsIl9tb25nb0NvbGxlY3Rpb24iLCJmaW5kIiwicXVlcnkiLCJza2lwIiwibGltaXQiLCJzb3J0Iiwia2V5cyIsIm1heFRpbWVNUyIsInJlYWRQcmVmZXJlbmNlIiwiaGludCIsImNhc2VJbnNlbnNpdGl2ZSIsImV4cGxhaW4iLCIkc2NvcmUiLCJzY29yZSIsIiRtZXRhIiwiX3Jhd0ZpbmQiLCJjYXRjaCIsImVycm9yIiwiY29kZSIsIm1lc3NhZ2UiLCJtYXRjaCIsImtleSIsImluZGV4IiwiY3JlYXRlSW5kZXgiLCJ0aGVuIiwiY2FzZUluc2Vuc2l0aXZlQ29sbGF0aW9uIiwibG9jYWxlIiwic3RyZW5ndGgiLCJmaW5kT3BlcmF0aW9uIiwicHJvamVjdCIsImNvbGxhdGlvbiIsInRvQXJyYXkiLCJjb3VudCIsIk9iamVjdCIsImxlbmd0aCIsImVzdGltYXRlZERvY3VtZW50Q291bnQiLCJjb3VudE9wZXJhdGlvbiIsImNvdW50RG9jdW1lbnRzIiwiZGlzdGluY3QiLCJmaWVsZCIsImFnZ3JlZ2F0ZSIsInBpcGVsaW5lIiwiaW5zZXJ0T25lIiwib2JqZWN0Iiwic2Vzc2lvbiIsInVwc2VydE9uZSIsInVwZGF0ZSIsInVwZGF0ZU9uZSIsInVwc2VydCIsInVwZGF0ZU1hbnkiLCJkZWxldGVNYW55IiwiX2Vuc3VyZVNwYXJzZVVuaXF1ZUluZGV4SW5CYWNrZ3JvdW5kIiwiaW5kZXhSZXF1ZXN0IiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJ1bmlxdWUiLCJiYWNrZ3JvdW5kIiwic3BhcnNlIiwiZHJvcCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBLE1BQU1BLE9BQU8sR0FBR0Ms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LEtBQUszRCxnQkFBTCxDQUFzQjJELElBQXRCLEVBQVA7QUFDRDs7QUFoTGtDIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgbW9uZ29kYiA9IHJlcXVpcmUoJ21vbmdvZGInKTtcbmNvbnN0IENvbGxlY3Rpb24gPSBtb25nb2RiLkNvbGxlY3Rpb247XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1vbmdvQ29sbGVjdGlvbiB7XG4gIF9tb25nb0NvbGxlY3Rpb246IENvbGxlY3Rpb247XG5cbiAgY29uc3RydWN0b3IobW9uZ29Db2xsZWN0aW9uOiBDb2xsZWN0aW9uKSB7XG4gICAgdGhpcy5fbW9uZ29Db2xsZWN0aW9uID0gbW9uZ29Db2xsZWN0aW9uO1xuICB9XG5cbiAgLy8gRG9lcyBhIGZpbmQgd2l0aCBcInNtYXJ0IGluZGV4aW5nXCIuXG4gIC8vIEN1cnJlbnRseSB0aGlzIGp1c3QgbWVhbnMsIGlmIGl0IG5lZWRzIGEgZ2VvaW5kZXggYW5kIHRoZXJlIGlzXG4gIC8vIG5vbmUsIHRoZW4gYnVpbGQgdGhlIGdlb2luZGV4LlxuICAvLyBUaGlzIGNvdWxkIGJlIGltcHJvdmVkIGEgbG90IGJ1dCBpdCdzIG5vdCBjbGVhciBpZiB0aGF0J3MgYSBnb29kXG4gIC8vIGlkZWEuIE9yIGV2ZW4gaWYgdGhpcyBiZWhhdmlvciBpcyBhIGdvb2QgaWRlYS5cbiAgZmluZChcbiAgICBxdWVyeSxcbiAgICB7IHNraXAsIGxpbWl0LCBzb3J0LCBrZXlzLCBtYXhUaW1lTVMsIHJlYWRQcmVmZXJlbmNlLCBoaW50LCBjYXNlSW5zZW5zaXRpdmUsIGV4cGxhaW4gfSA9IHt9XG4gICkge1xuICAgIC8vIFN1cHBvcnQgZm9yIEZ1bGwgVGV4dCBTZWFyY2ggLSAkdGV4dFxuICAgIGlmIChrZXlzICYmIGtleXMuJHNjb3JlKSB7XG4gICAgICBkZWxldGUga2V5cy4kc2NvcmU7XG4gICAgICBrZXlzLnNjb3JlID0geyAkbWV0YTogJ3RleHRTY29yZScgfTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3Jhd0ZpbmQocXVlcnksIHtcbiAgICAgIHNraXAsXG4gICAgICBsaW1pdCxcbiAgICAgIHNvcnQsXG4gICAgICBrZXlzLFxuICAgICAgbWF4VGltZU1TLFxuICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICBoaW50LFxuICAgICAgY2FzZUluc2Vuc2l0aXZlLFxuICAgICAgZXhwbGFpbixcbiAgICB9KS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAvLyBDaGVjayBmb3IgXCJubyBnZW9pbmRleFwiIGVycm9yXG4gICAgICBpZiAoZXJyb3IuY29kZSAhPSAxNzAwNyAmJiAhZXJyb3IubWVzc2FnZS5tYXRjaCgvdW5hYmxlIHRvIGZpbmQgaW5kZXggZm9yIC5nZW9OZWFyLykpIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgICAvLyBGaWd1cmUgb3V0IHdoYXQga2V5IG5lZWRzIGFuIGluZGV4XG4gICAgICBjb25zdCBrZXkgPSBlcnJvci5tZXNzYWdlLm1hdGNoKC9maWVsZD0oW0EtWmEtel8wLTldKykgLylbMV07XG4gICAgICBpZiAoIWtleSkge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cblxuICAgICAgdmFyIGluZGV4ID0ge307XG4gICAgICBpbmRleFtrZXldID0gJzJkJztcbiAgICAgIHJldHVybiAoXG4gICAgICAgIHRoaXMuX21vbmdvQ29sbGVjdGlvblxuICAgICAgICAgIC5jcmVhdGVJbmRleChpbmRleClcbiAgICAgICAgICAvLyBSZXRyeSwgYnV0IGp1c3Qgb25jZS5cbiAgICAgICAgICAudGhlbigoKSA9PlxuICAgICAgICAgICAgdGhpcy5fcmF3RmluZChxdWVyeSwge1xuICAgICAgICAgICAgICBza2lwLFxuICAgICAgICAgICAgICBsaW1pdCxcbiAgICAgICAgICAgICAgc29ydCxcbiAgICAgICAgICAgICAga2V5cyxcbiAgICAgICAgICAgICAgbWF4VGltZU1TLFxuICAgICAgICAgICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICAgICAgaGludCxcbiAgICAgICAgICAgICAgY2FzZUluc2Vuc2l0aXZlLFxuICAgICAgICAgICAgICBleHBsYWluLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICApXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbGxhdGlvbiB0byBzdXBwb3J0IGNhc2UgaW5zZW5zaXRpdmUgcXVlcmllc1xuICAgKi9cbiAgc3RhdGljIGNhc2VJbnNlbnNpdGl2ZUNvbGxhdGlvbigpIHtcbiAgICByZXR1cm4geyBsb2NhbGU6ICdlbl9VUycsIHN0cmVuZ3RoOiAyIH07XG4gIH1cblxuICBfcmF3RmluZChcbiAgICBxdWVyeSxcbiAgICB7IHNraXAsIGxpbWl0LCBzb3J0LCBrZXlzLCBtYXhUaW1lTVMsIHJlYWRQcmVmZXJlbmNlLCBoaW50LCBjYXNlSW5zZW5zaXRpdmUsIGV4cGxhaW4gfSA9IHt9XG4gICkge1xuICAgIGxldCBmaW5kT3BlcmF0aW9uID0gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLmZpbmQocXVlcnksIHtcbiAgICAgIHNraXAsXG4gICAgICBsaW1pdCxcbiAgICAgIHNvcnQsXG4gICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgIGhpbnQsXG4gICAgfSk7XG5cbiAgICBpZiAoa2V5cykge1xuICAgICAgZmluZE9wZXJhdGlvbiA9IGZpbmRPcGVyYXRpb24ucHJvamVjdChrZXlzKTtcbiAgICB9XG5cbiAgICBpZiAoY2FzZUluc2Vuc2l0aXZlKSB7XG4gICAgICBmaW5kT3BlcmF0aW9uID0gZmluZE9wZXJhdGlvbi5jb2xsYXRpb24oTW9uZ29Db2xsZWN0aW9uLmNhc2VJbnNlbnNpdGl2ZUNvbGxhdGlvbigpKTtcbiAgICB9XG5cbiAgICBpZiAobWF4VGltZU1TKSB7XG4gICAgICBmaW5kT3BlcmF0aW9uID0gZmluZE9wZXJhdGlvbi5tYXhUaW1lTVMobWF4VGltZU1TKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXhwbGFpbiA/IGZpbmRPcGVyYXRpb24uZXhwbGFpbihleHBsYWluKSA6IGZpbmRPcGVyYXRpb24udG9BcnJheSgpO1xuICB9XG5cbiAgY291bnQocXVlcnksIHsgc2tpcCwgbGltaXQsIHNvcnQsIG1heFRpbWVNUywgcmVhZFByZWZlcmVuY2UsIGhpbnQgfSA9IHt9KSB7XG4gICAgLy8gSWYgcXVlcnkgaXMgZW1wdHksIHRoZW4gdXNlIGVzdGltYXRlZERvY3VtZW50Q291bnQgaW5zdGVhZC5cbiAgICAvLyBUaGlzIGlzIGR1ZSB0byBjb3VudERvY3VtZW50cyBwZXJmb3JtaW5nIGEgc2NhbixcbiAgICAvLyB3aGljaCBncmVhdGx5IGluY3JlYXNlcyBleGVjdXRpb24gdGltZSB3aGVuIGJlaW5nIHJ1biBvbiBsYXJnZSBjb2xsZWN0aW9ucy5cbiAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL0F1dG9tYXR0aWMvbW9uZ29vc2UvaXNzdWVzLzY3MTMgZm9yIG1vcmUgaW5mbyByZWdhcmRpbmcgdGhpcyBwcm9ibGVtLlxuICAgIGlmICh0eXBlb2YgcXVlcnkgIT09ICdvYmplY3QnIHx8ICFPYmplY3Qua2V5cyhxdWVyeSkubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLmVzdGltYXRlZERvY3VtZW50Q291bnQoe1xuICAgICAgICBtYXhUaW1lTVMsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBjb3VudE9wZXJhdGlvbiA9IHRoaXMuX21vbmdvQ29sbGVjdGlvbi5jb3VudERvY3VtZW50cyhxdWVyeSwge1xuICAgICAgc2tpcCxcbiAgICAgIGxpbWl0LFxuICAgICAgc29ydCxcbiAgICAgIG1heFRpbWVNUyxcbiAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgaGludCxcbiAgICB9KTtcblxuICAgIHJldHVybiBjb3VudE9wZXJhdGlvbjtcbiAgfVxuXG4gIGRpc3RpbmN0KGZpZWxkLCBxdWVyeSkge1xuICAgIHJldHVybiB0aGlzLl9tb25nb0NvbGxlY3Rpb24uZGlzdGluY3QoZmllbGQsIHF1ZXJ5KTtcbiAgfVxuXG4gIGFnZ3JlZ2F0ZShwaXBlbGluZSwgeyBtYXhUaW1lTVMsIHJlYWRQcmVmZXJlbmNlLCBoaW50LCBleHBsYWluIH0gPSB7fSkge1xuICAgIHJldHVybiB0aGlzLl9tb25nb0NvbGxlY3Rpb25cbiAgICAgIC5hZ2dyZWdhdGUocGlwZWxpbmUsIHsgbWF4VGltZU1TLCByZWFkUHJlZmVyZW5jZSwgaGludCwgZXhwbGFpbiB9KVxuICAgICAgLnRvQXJyYXkoKTtcbiAgfVxuXG4gIGluc2VydE9uZShvYmplY3QsIHNlc3Npb24pIHtcbiAgICByZXR1cm4gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLmluc2VydE9uZShvYmplY3QsIHsgc2Vzc2lvbiB9KTtcbiAgfVxuXG4gIC8vIEF0b21pY2FsbHkgdXBkYXRlcyBkYXRhIGluIHRoZSBkYXRhYmFzZSBmb3IgYSBzaW5nbGUgKGZpcnN0KSBvYmplY3QgdGhhdCBtYXRjaGVkIHRoZSBxdWVyeVxuICAvLyBJZiB0aGVyZSBpcyBub3RoaW5nIHRoYXQgbWF0Y2hlcyB0aGUgcXVlcnkgLSBkb2VzIGluc2VydFxuICAvLyBQb3N0Z3JlcyBOb3RlOiBgSU5TRVJUIC4uLiBPTiBDT05GTElDVCBVUERBVEVgIHRoYXQgaXMgYXZhaWxhYmxlIHNpbmNlIDkuNS5cbiAgdXBzZXJ0T25lKHF1ZXJ5LCB1cGRhdGUsIHNlc3Npb24pIHtcbiAgICByZXR1cm4gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLnVwZGF0ZU9uZShxdWVyeSwgdXBkYXRlLCB7XG4gICAgICB1cHNlcnQ6IHRydWUsXG4gICAgICBzZXNzaW9uLFxuICAgIH0pO1xuICB9XG5cbiAgdXBkYXRlT25lKHF1ZXJ5LCB1cGRhdGUpIHtcbiAgICByZXR1cm4gdGhpcy5fbW9uZ29Db2xsZWN0aW9uLnVwZGF0ZU9uZShxdWVyeSwgdXBkYXRlKTtcbiAgfVxuXG4gIHVwZGF0ZU1hbnkocXVlcnksIHVwZGF0ZSwgc2Vzc2lvbikge1xuICAgIHJldHVybiB0aGlzLl9tb25nb0NvbGxlY3Rpb24udXBkYXRlTWFueShxdWVyeSwgdXBkYXRlLCB7IHNlc3Npb24gfSk7XG4gIH1cblxuICBkZWxldGVNYW55KHF1ZXJ5LCBzZXNzaW9uKSB7XG4gICAgcmV0dXJuIHRoaXMuX21vbmdvQ29sbGVjdGlvbi5kZWxldGVNYW55KHF1ZXJ5LCB7IHNlc3Npb24gfSk7XG4gIH1cblxuICBfZW5zdXJlU3BhcnNlVW5pcXVlSW5kZXhJbkJhY2tncm91bmQoaW5kZXhSZXF1ZXN0KSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuX21vbmdvQ29sbGVjdGlvbi5jcmVhdGVJbmRleChcbiAgICAgICAgaW5kZXhSZXF1ZXN0LFxuICAgICAgICB7IHVuaXF1ZTogdHJ1ZSwgYmFja2dyb3VuZDogdHJ1ZSwgc3BhcnNlOiB0cnVlIH0sXG4gICAgICAgIGVycm9yID0+IHtcbiAgICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBkcm9wKCkge1xuICAgIHJldHVybiB0aGlzLl9tb25nb0NvbGxlY3Rpb24uZHJvcCgpO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js b/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js deleted file mode 100644 index 15075a09ed..0000000000 --- a/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js +++ /dev/null @@ -1,365 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _MongoCollection = _interopRequireDefault(require("./MongoCollection")); - -var _node = _interopRequireDefault(require("parse/node")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } - -function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function mongoFieldToParseSchemaField(type) { - if (type[0] === '*') { - return { - type: 'Pointer', - targetClass: type.slice(1) - }; - } - - if (type.startsWith('relation<')) { - return { - type: 'Relation', - targetClass: type.slice('relation<'.length, type.length - 1) - }; - } - - switch (type) { - case 'number': - return { - type: 'Number' - }; - - case 'string': - return { - type: 'String' - }; - - case 'boolean': - return { - type: 'Boolean' - }; - - case 'date': - return { - type: 'Date' - }; - - case 'map': - case 'object': - return { - type: 'Object' - }; - - case 'array': - return { - type: 'Array' - }; - - case 'geopoint': - return { - type: 'GeoPoint' - }; - - case 'file': - return { - type: 'File' - }; - - case 'bytes': - return { - type: 'Bytes' - }; - - case 'polygon': - return { - type: 'Polygon' - }; - } -} - -const nonFieldSchemaKeys = ['_id', '_metadata', '_client_permissions']; - -function mongoSchemaFieldsToParseSchemaFields(schema) { - var fieldNames = Object.keys(schema).filter(key => nonFieldSchemaKeys.indexOf(key) === -1); - var response = fieldNames.reduce((obj, fieldName) => { - obj[fieldName] = mongoFieldToParseSchemaField(schema[fieldName]); - - if (schema._metadata && schema._metadata.fields_options && schema._metadata.fields_options[fieldName]) { - obj[fieldName] = Object.assign({}, obj[fieldName], schema._metadata.fields_options[fieldName]); - } - - return obj; - }, {}); - response.ACL = { - type: 'ACL' - }; - response.createdAt = { - type: 'Date' - }; - response.updatedAt = { - type: 'Date' - }; - response.objectId = { - type: 'String' - }; - return response; -} - -const emptyCLPS = Object.freeze({ - find: {}, - count: {}, - get: {}, - create: {}, - update: {}, - delete: {}, - addField: {}, - protectedFields: {} -}); -const defaultCLPS = Object.freeze({ - find: { - '*': true - }, - count: { - '*': true - }, - get: { - '*': true - }, - create: { - '*': true - }, - update: { - '*': true - }, - delete: { - '*': true - }, - addField: { - '*': true - }, - protectedFields: { - '*': [] - } -}); - -function mongoSchemaToParseSchema(mongoSchema) { - let clps = defaultCLPS; - let indexes = {}; - - if (mongoSchema._metadata) { - if (mongoSchema._metadata.class_permissions) { - clps = _objectSpread(_objectSpread({}, emptyCLPS), mongoSchema._metadata.class_permissions); - } - - if (mongoSchema._metadata.indexes) { - indexes = _objectSpread({}, mongoSchema._metadata.indexes); - } - } - - return { - className: mongoSchema._id, - fields: mongoSchemaFieldsToParseSchemaFields(mongoSchema), - classLevelPermissions: clps, - indexes: indexes - }; -} - -function _mongoSchemaQueryFromNameQuery(name, query) { - const object = { - _id: name - }; - - if (query) { - Object.keys(query).forEach(key => { - object[key] = query[key]; - }); - } - - return object; -} // Returns a type suitable for inserting into mongo _SCHEMA collection. -// Does no validation. That is expected to be done in Parse Server. - - -function parseFieldTypeToMongoFieldType({ - type, - targetClass -}) { - switch (type) { - case 'Pointer': - return `*${targetClass}`; - - case 'Relation': - return `relation<${targetClass}>`; - - case 'Number': - return 'number'; - - case 'String': - return 'string'; - - case 'Boolean': - return 'boolean'; - - case 'Date': - return 'date'; - - case 'Object': - return 'object'; - - case 'Array': - return 'array'; - - case 'GeoPoint': - return 'geopoint'; - - case 'File': - return 'file'; - - case 'Bytes': - return 'bytes'; - - case 'Polygon': - return 'polygon'; - } -} - -class MongoSchemaCollection { - constructor(collection) { - this._collection = collection; - } - - _fetchAllSchemasFrom_SCHEMA() { - return this._collection._rawFind({}).then(schemas => schemas.map(mongoSchemaToParseSchema)); - } - - _fetchOneSchemaFrom_SCHEMA(name) { - return this._collection._rawFind(_mongoSchemaQueryFromNameQuery(name), { - limit: 1 - }).then(results => { - if (results.length === 1) { - return mongoSchemaToParseSchema(results[0]); - } else { - throw undefined; - } - }); - } // Atomically find and delete an object based on query. - - - findAndDeleteSchema(name) { - return this._collection._mongoCollection.findOneAndDelete(_mongoSchemaQueryFromNameQuery(name)); - } - - insertSchema(schema) { - return this._collection.insertOne(schema).then(result => mongoSchemaToParseSchema(result.ops[0])).catch(error => { - if (error.code === 11000) { - //Mongo's duplicate key error - throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'Class already exists.'); - } else { - throw error; - } - }); - } - - updateSchema(name, update) { - return this._collection.updateOne(_mongoSchemaQueryFromNameQuery(name), update); - } - - upsertSchema(name, query, update) { - return this._collection.upsertOne(_mongoSchemaQueryFromNameQuery(name, query), update); - } // Add a field to the schema. If database does not support the field - // type (e.g. mongo doesn't support more than one GeoPoint in a class) reject with an "Incorrect Type" - // Parse error with a desciptive message. If the field already exists, this function must - // not modify the schema, and must reject with DUPLICATE_VALUE error. - // If this is called for a class that doesn't exist, this function must create that class. - // TODO: throw an error if an unsupported field type is passed. Deciding whether a type is supported - // should be the job of the adapter. Some adapters may not support GeoPoint at all. Others may - // Support additional types that Mongo doesn't, like Money, or something. - // TODO: don't spend an extra query on finding the schema if the type we are trying to add isn't a GeoPoint. - - - addFieldIfNotExists(className, fieldName, fieldType) { - return this._fetchOneSchemaFrom_SCHEMA(className).then(schema => { - // If a field with this name already exists, it will be handled elsewhere. - if (schema.fields[fieldName] != undefined) { - return; - } // The schema exists. Check for existing GeoPoints. - - - if (fieldType.type === 'GeoPoint') { - // Make sure there are not other geopoint fields - if (Object.keys(schema.fields).some(existingField => schema.fields[existingField].type === 'GeoPoint')) { - throw new _node.default.Error(_node.default.Error.INCORRECT_TYPE, 'MongoDB only supports one GeoPoint field in a class.'); - } - } - - return; - }, error => { - // If error is undefined, the schema doesn't exist, and we can create the schema with the field. - // If some other error, reject with it. - if (error === undefined) { - return; - } - - throw error; - }).then(() => { - const { - type, - targetClass - } = fieldType, - fieldOptions = _objectWithoutProperties(fieldType, ["type", "targetClass"]); // We use $exists and $set to avoid overwriting the field type if it - // already exists. (it could have added inbetween the last query and the update) - - - if (fieldOptions && Object.keys(fieldOptions).length > 0) { - return this.upsertSchema(className, { - [fieldName]: { - $exists: false - } - }, { - $set: { - [fieldName]: parseFieldTypeToMongoFieldType({ - type, - targetClass - }), - [`_metadata.fields_options.${fieldName}`]: fieldOptions - } - }); - } else { - return this.upsertSchema(className, { - [fieldName]: { - $exists: false - } - }, { - $set: { - [fieldName]: parseFieldTypeToMongoFieldType({ - type, - targetClass - }) - } - }); - } - }); - } - -} // Exported for testing reasons and because we haven't moved all mongo schema format -// related logic into the database adapter yet. - - -MongoSchemaCollection._TESTmongoSchemaToParseSchema = mongoSchemaToParseSchema; -MongoSchemaCollection.parseFieldTypeToMongoFieldType = parseFieldTypeToMongoFieldType; -var _default = MongoSchemaCollection; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvU2NoZW1hQ29sbGVjdGlvbi5qcyJdLCJuYW1lcyI6WyJtb25nb0ZpZWxkVG9QYXJzZVNjaGVtYUZpZWxkIiwidHlwZSIsInRhcmdldENsYXNzIiwic2xpY2UiLCJzdGFydHNXaXRoIiwibGVuZ3RoIiwibm9uRmllbGRTY2hlbWFLZXlzIiwibW9uZ29TY2hlbWFGaWVsZHNUb1BhcnNlU2NoZW1hRmllbGRzIiwic2NoZW1hIiwiZmllbGROYW1lcyIsIk9iamVjdCIsImtleXMiLCJmaWx0ZXIiLCJrZXkiLCJpbmRleE9mIiwicmVzcG9uc2UiLCJyZWR1Y2UiLCJvYmoiLCJmaWVsZE5hbWUiLCJfbWV0YWRhdGEiLCJmaWVsZHNfb3B0aW9ucyIsImFzc2lnbiIsIkFDTCIsImNyZWF0ZWRBdCIsInVwZGF0ZWRBdCIsIm9iamVjdElkIiwiZW1wdHlDTFBTIiwiZnJlZXplIiwiZmluZCIsImNvdW50IiwiZ2V0IiwiY3JlYXRlIiwidXBkYXRlIiwiZGVsZXRlIiwiYWRkRmllbGQiLCJwcm90ZWN0ZWRGaWVsZHMiLCJkZWZhdWx0Q0xQUyIsIm1vbmdvU2NoZW1hVG9QYXJzZVNjaGVtYSIsIm1vbmdvU2NoZW1hIiwiY2xwcyIsImluZGV4ZXMiLCJjbGFzc19wZXJtaXNzaW9ucyIsImNsYXNzTmFtZSIsIl9pZCIsImZpZWxkcyIsImNsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsIl9tb25nb1NjaGVtYVF1ZXJ5RnJvbU5hbWVRdWVyeSIsIm5hbWUiLCJxdWVyeSIsIm9iamVjdCIsImZvckVhY2giLCJwYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUiLCJNb25nb1NjaGVtYUNvbGxlY3Rpb24iLCJjb25zdHJ1Y3RvciIsImNvbGxlY3Rpb24iLCJfY29sbGVjdGlvbiIsIl9mZXRjaEFsbFNjaGVtYXNGcm9tX1NDSEVNQSIsIl9yYXdGaW5kIiwidGhlbiIsInNjaGVtYXMiLCJtYXAiLCJfZmV0Y2hPbmVTY2hlbWFGcm9tX1NDSEVNQSIsImxpbWl0IiwicmVzdWx0cyIsInVuZGVmaW5lZCIsImZpbmRBbmREZWxldGVTY2hlbWEiLCJfbW9uZ29Db2xsZWN0aW9uIiwiZmluZE9uZUFuZERlbGV0ZSIsImluc2VydFNjaGVtYSIsImluc2VydE9uZSIsInJlc3VsdCIsIm9wcyIsImNhdGNoIiwiZXJyb3IiLCJjb2RlIiwiUGFyc2UiLCJFcnJvciIsIkRVUExJQ0FURV9WQUxVRSIsInVwZGF0ZVNjaGVtYSIsInVwZGF0ZU9uZSIsInVwc2VydFNjaGVtYSIsInVwc2VydE9uZSIsImFkZEZpZWxkSWZOb3RFeGlzdHMiLCJmaWVsZFR5cGUiLCJzb21lIiwiZXhpc3RpbmdGaWVsZCIsIklOQ09SUkVDVF9UWVBFIiwiZmllbGRPcHRpb25zIiwiJGV4aXN0cyIsIiRzZXQiLCJfVEVTVG1vbmdvU2NoZW1hVG9QYXJzZVNjaGVtYSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7Ozs7Ozs7Ozs7OztBQUVBLFNBQVNBLDRCQUFULENBQXNDQyxJQUF0QyxFQUE0QztBQUMxQyxNQUFJQSxJQUFJLENBQUMsQ0FBRCxDQUFKLEtBQVksR0FBaEIsRUFBcUI7QUFDbkIsV0FBTztBQUNMQSxNQUFBQSxJQUFJLEVBQUUsU0FERDtBQUVMQyxNQUFBQSxXQUFXLEVBQUVELElBQUksQ0FBQ0UsS0FBTCxDQUFXLENBQVg7QUFGUixLQUFQO0FBSUQ7O0FBQ0QsTUFBSUYsSUFBSSxDQUFDRyxVQUFMLENBQWdCLFdBQWhCLENBQUosRUFBa0M7QUFDaEMsV0FBTztBQUNMSCxNQUFBQSxJQUFJLEVBQUUsVUFERDtBQUVMQyxNQUFBQSxXQUFXLEVBQUVELElBQUksQ0FBQ0UsS0FBTCxDQUFXLFlBQVlFLE1BQXZCLEVBQStCSixJQUFJLENBQUNJLE1BQUwsR0FBYyxDQUE3QztBQUZSLEtBQVA7QUFJRDs7QUFDRCxVQUFRSixJQUFSO0FBQ0UsU0FBSyxRQUFMO0FBQ0UsYUFBTztBQUFFQSxRQUFBQSxJQUFJLEVBQUU7QUFBUixPQUFQ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Q3ZFLFNBQUQsR0FBYWlDLDhCQUE4QixDQUFDO0FBQzFDbEQsY0FBQUEsSUFEMEM7QUFFMUNDLGNBQUFBO0FBRjBDLGFBQUQ7QUFEdkM7QUFEUixTQUhLLENBQVA7QUFZRDtBQUNGLEtBaEVJLENBQVA7QUFpRUQ7O0FBL0h5QixDLENBa0k1QjtBQUNBOzs7QUFDQWtELHFCQUFxQixDQUFDc0MsNkJBQXRCLEdBQXNEckQsd0JBQXREO0FBQ0FlLHFCQUFxQixDQUFDRCw4QkFBdEIsR0FBdURBLDhCQUF2RDtlQUVlQyxxQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBNb25nb0NvbGxlY3Rpb24gZnJvbSAnLi9Nb25nb0NvbGxlY3Rpb24nO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuXG5mdW5jdGlvbiBtb25nb0ZpZWxkVG9QYXJzZVNjaGVtYUZpZWxkKHR5cGUpIHtcbiAgaWYgKHR5cGVbMF0gPT09ICcqJykge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiAnUG9pbnRlcicsXG4gICAgICB0YXJnZXRDbGFzczogdHlwZS5zbGljZSgxKSxcbiAgICB9O1xuICB9XG4gIGlmICh0eXBlLnN0YXJ0c1dpdGgoJ3JlbGF0aW9uPCcpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdSZWxhdGlvbicsXG4gICAgICB0YXJnZXRDbGFzczogdHlwZS5zbGljZSgncmVsYXRpb248Jy5sZW5ndGgsIHR5cGUubGVuZ3RoIC0gMSksXG4gICAgfTtcbiAgfVxuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdudW1iZXInOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ051bWJlcicgfTtcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ1N0cmluZycgfTtcbiAgICBjYXNlICdib29sZWFuJzpcbiAgICAgIHJldHVybiB7IHR5cGU6ICdCb29sZWFuJyB9O1xuICAgIGNhc2UgJ2RhdGUnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ0RhdGUnIH07XG4gICAgY2FzZSAnbWFwJzpcbiAgICBjYXNlICdvYmplY3QnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ09iamVjdCcgfTtcbiAgICBjYXNlICdhcnJheSc6XG4gICAgICByZXR1cm4geyB0eXBlOiAnQXJyYXknIH07XG4gICAgY2FzZSAnZ2VvcG9pbnQnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ0dlb1BvaW50JyB9O1xuICAgIGNhc2UgJ2ZpbGUnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ0ZpbGUnIH07XG4gICAgY2FzZSAnYnl0ZXMnOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ0J5dGVzJyB9O1xuICAgIGNhc2UgJ3BvbHlnb24nOlxuICAgICAgcmV0dXJuIHsgdHlwZTogJ1BvbHlnb24nIH07XG4gIH1cbn1cblxuY29uc3Qgbm9uRmllbGRTY2hlbWFLZXlzID0gWydfaWQnLCAnX21ldGFkYXRhJywgJ19jbGllbnRfcGVybWlzc2lvbnMnXTtcbmZ1bmN0aW9uIG1vbmdvU2NoZW1hRmllbGRzVG9QYXJzZVNjaGVtYUZpZWxkcyhzY2hlbWEpIHtcbiAgdmFyIGZpZWxkTmFtZXMgPSBPYmplY3Qua2V5cyhzY2hlbWEpLmZpbHRlcihrZXkgPT4gbm9uRmllbGRTY2hlbWFLZXlzLmluZGV4T2Yoa2V5KSA9PT0gLTEpO1xuICB2YXIgcmVzcG9uc2UgPSBmaWVsZE5hbWVzLnJlZHVjZSgob2JqLCBmaWVsZE5hbWUpID0+IHtcbiAgICBvYmpbZmllbGROYW1lXSA9IG1vbmdvRmllbGRUb1BhcnNlU2NoZW1hRmllbGQoc2NoZW1hW2ZpZWxkTmFtZV0pO1xuICAgIGlmIChcbiAgICAgIHNjaGVtYS5fbWV0YWRhdGEgJiZcbiAgICAgIHNjaGVtYS5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnMgJiZcbiAgICAgIHNjaGVtYS5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnNbZmllbGROYW1lXVxuICAgICkge1xuICAgICAgb2JqW2ZpZWxkTmFtZV0gPSBPYmplY3QuYXNzaWduKFxuICAgICAgICB7fSxcbiAgICAgICAgb2JqW2ZpZWxkTmFtZV0sXG4gICAgICAgIHNjaGVtYS5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnNbZmllbGROYW1lXVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIG9iajtcbiAgfSwge30pO1xuICByZXNwb25zZS5BQ0wgPSB7IHR5cGU6ICdBQ0wnIH07XG4gIHJlc3BvbnNlLmNyZWF0ZWRBdCA9IHsgdHlwZTogJ0RhdGUnIH07XG4gIHJlc3BvbnNlLnVwZGF0ZWRBdCA9IHsgdHlwZTogJ0RhdGUnIH07XG4gIHJlc3BvbnNlLm9iamVjdElkID0geyB0eXBlOiAnU3RyaW5nJyB9O1xuICByZXR1cm4gcmVzcG9uc2U7XG59XG5cbmNvbnN0IGVtcHR5Q0xQUyA9IE9iamVjdC5mcmVlemUoe1xuICBmaW5kOiB7fSxcbiAgY291bnQ6IHt9LFxuICBnZXQ6IHt9LFxuICBjcmVhdGU6IHt9LFxuICB1cGRhdGU6IHt9LFxuICBkZWxldGU6IHt9LFxuICBhZGRGaWVsZDoge30sXG4gIHByb3RlY3RlZEZpZWxkczoge30sXG59KTtcblxuY29uc3QgZGVmYXVsdENMUFMgPSBPYmplY3QuZnJlZXplKHtcbiAgZmluZDogeyAnKic6IHRydWUgfSxcbiAgY291bnQ6IHsgJyonOiB0cnVlIH0sXG4gIGdldDogeyAnKic6IHRydWUgfSxcbiAgY3JlYXRlOiB7ICcqJzogdHJ1ZSB9LFxuICB1cGRhdGU6IHsgJyonOiB0cnVlIH0sXG4gIGRlbGV0ZTogeyAnKic6IHRydWUgfSxcbiAgYWRkRmllbGQ6IHsgJyonOiB0cnVlIH0sXG4gIHByb3RlY3RlZEZpZWxkczogeyAnKic6IFtdIH0sXG59KTtcblxuZnVuY3Rpb24gbW9uZ29TY2hlbWFUb1BhcnNlU2NoZW1hKG1vbmdvU2NoZW1hKSB7XG4gIGxldCBjbHBzID0gZGVmYXVsdENMUFM7XG4gIGxldCBpbmRleGVzID0ge307XG4gIGlmIChtb25nb1NjaGVtYS5fbWV0YWRhdGEpIHtcbiAgICBpZiAobW9uZ29TY2hlbWEuX21ldGFkYXRhLmNsYXNzX3Blcm1pc3Npb25zKSB7XG4gICAgICBjbHBzID0geyAuLi5lbXB0eUNMUFMsIC4uLm1vbmdvU2NoZW1hLl9tZXRhZGF0YS5jbGFzc19wZXJtaXNzaW9ucyB9O1xuICAgIH1cbiAgICBpZiAobW9uZ29TY2hlbWEuX21ldGFkYXRhLmluZGV4ZXMpIHtcbiAgICAgIGluZGV4ZXMgPSB7IC4uLm1vbmdvU2NoZW1hLl9tZXRhZGF0YS5pbmRleGVzIH07XG4gICAgfVxuICB9XG4gIHJldHVybiB7XG4gICAgY2xhc3NOYW1lOiBtb25nb1NjaGVtYS5faWQsXG4gICAgZmllbGRzOiBtb25nb1NjaGVtYUZpZWxkc1RvUGFyc2VTY2hlbWFGaWVsZHMobW9uZ29TY2hlbWEpLFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogY2xwcyxcbiAgICBpbmRleGVzOiBpbmRleGVzLFxuICB9O1xufVxuXG5mdW5jdGlvbiBfbW9uZ29TY2hlbWFRdWVyeUZyb21OYW1lUXVlcnkobmFtZTogc3RyaW5nLCBxdWVyeSkge1xuICBjb25zdCBvYmplY3QgPSB7IF9pZDogbmFtZSB9O1xuICBpZiAocXVlcnkpIHtcbiAgICBPYmplY3Qua2V5cyhxdWVyeSkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgb2JqZWN0W2tleV0gPSBxdWVyeVtrZXldO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBvYmplY3Q7XG59XG5cbi8vIFJldHVybnMgYSB0eXBlIHN1aXRhYmxlIGZvciBpbnNlcnRpbmcgaW50byBtb25nbyBfU0NIRU1BIGNvbGxlY3Rpb24uXG4vLyBEb2VzIG5vIHZhbGlkYXRpb24uIFRoYXQgaXMgZXhwZWN0ZWQgdG8gYmUgZG9uZSBpbiBQYXJzZSBTZXJ2ZXIuXG5mdW5jdGlvbiBwYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUoeyB0eXBlLCB0YXJnZXRDbGFzcyB9KSB7XG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgJ1BvaW50ZXInOlxuICAgICAgcmV0dXJuIGAqJHt0YXJnZXRDbGFzc31gO1xuICAgIGNhc2UgJ1JlbGF0aW9uJzpcbiAgICAgIHJldHVybiBgcmVsYXRpb248JHt0YXJnZXRDbGFzc30+YDtcbiAgICBjYXNlICdOdW1iZXInOlxuICAgICAgcmV0dXJuICdudW1iZXInO1xuICAgIGNhc2UgJ1N0cmluZyc6XG4gICAgICByZXR1cm4gJ3N0cmluZyc7XG4gICAgY2FzZSAnQm9vbGVhbic6XG4gICAgICByZXR1cm4gJ2Jvb2xlYW4nO1xuICAgIGNhc2UgJ0RhdGUnOlxuICAgICAgcmV0dXJuICdkYXRlJztcbiAgICBjYXNlICdPYmplY3QnOlxuICAgICAgcmV0dXJuICdvYmplY3QnO1xuICAgIGNhc2UgJ0FycmF5JzpcbiAgICAgIHJldHVybiAnYXJyYXknO1xuICAgIGNhc2UgJ0dlb1BvaW50JzpcbiAgICAgIHJldHVybiAnZ2VvcG9pbnQnO1xuICAgIGNhc2UgJ0ZpbGUnOlxuICAgICAgcmV0dXJuICdmaWxlJztcbiAgICBjYXNlICdCeXRlcyc6XG4gICAgICByZXR1cm4gJ2J5dGVzJztcbiAgICBjYXNlICdQb2x5Z29uJzpcbiAgICAgIHJldHVybiAncG9seWdvbic7XG4gIH1cbn1cblxuY2xhc3MgTW9uZ29TY2hlbWFDb2xsZWN0aW9uIHtcbiAgX2NvbGxlY3Rpb246IE1vbmdvQ29sbGVjdGlvbjtcblxuICBjb25zdHJ1Y3Rvcihjb2xsZWN0aW9uOiBNb25nb0NvbGxlY3Rpb24pIHtcbiAgICB0aGlzLl9jb2xsZWN0aW9uID0gY29sbGVjdGlvbjtcbiAgfVxuXG4gIF9mZXRjaEFsbFNjaGVtYXNGcm9tX1NDSEVNQSgpIHtcbiAgICByZXR1cm4gdGhpcy5fY29sbGVjdGlvbi5fcmF3RmluZCh7fSkudGhlbihzY2hlbWFzID0+IHNjaGVtYXMubWFwKG1vbmdvU2NoZW1hVG9QYXJzZVNjaGVtYSkpO1xuICB9XG5cbiAgX2ZldGNoT25lU2NoZW1hRnJvbV9TQ0hFTUEobmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbGxlY3Rpb25cbiAgICAgIC5fcmF3RmluZChfbW9uZ29TY2hlbWFRdWVyeUZyb21OYW1lUXVlcnkobmFtZSksIHsgbGltaXQ6IDEgfSlcbiAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICByZXR1cm4gbW9uZ29TY2hlbWFUb1BhcnNlU2NoZW1hKHJlc3VsdHNbMF0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICAvLyBBdG9taWNhbGx5IGZpbmQgYW5kIGRlbGV0ZSBhbiBvYmplY3QgYmFzZWQgb24gcXVlcnkuXG4gIGZpbmRBbmREZWxldGVTY2hlbWEobmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbGxlY3Rpb24uX21vbmdvQ29sbGVjdGlvbi5maW5kT25lQW5kRGVsZXRlKF9tb25nb1NjaGVtYVF1ZXJ5RnJvbU5hbWVRdWVyeShuYW1lKSk7XG4gIH1cblxuICBpbnNlcnRTY2hlbWEoc2NoZW1hOiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5fY29sbGVjdGlvblxuICAgICAgLmluc2VydE9uZShzY2hlbWEpXG4gICAgICAudGhlbihyZXN1bHQgPT4gbW9uZ29TY2hlbWFUb1BhcnNlU2NoZW1hKHJlc3VsdC5vcHNbMF0pKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDExMDAwKSB7XG4gICAgICAgICAgLy9Nb25nbydzIGR1cGxpY2F0ZSBrZXkgZXJyb3JcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFLCAnQ2xhc3MgYWxyZWFkeSBleGlzdHMuJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgdXBkYXRlU2NoZW1hKG5hbWU6IHN0cmluZywgdXBkYXRlKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbGxlY3Rpb24udXBkYXRlT25lKF9tb25nb1NjaGVtYVF1ZXJ5RnJvbU5hbWVRdWVyeShuYW1lKSwgdXBkYXRlKTtcbiAgfVxuXG4gIHVwc2VydFNjaGVtYShuYW1lOiBzdHJpbmcsIHF1ZXJ5OiBzdHJpbmcsIHVwZGF0ZSkge1xuICAgIHJldHVybiB0aGlzLl9jb2xsZWN0aW9uLnVwc2VydE9uZShfbW9uZ29TY2hlbWFRdWVyeUZyb21OYW1lUXVlcnkobmFtZSwgcXVlcnkpLCB1cGRhdGUpO1xuICB9XG5cbiAgLy8gQWRkIGEgZmllbGQgdG8gdGhlIHNjaGVtYS4gSWYgZGF0YWJhc2UgZG9lcyBub3Qgc3VwcG9ydCB0aGUgZmllbGRcbiAgLy8gdHlwZSAoZS5nLiBtb25nbyBkb2Vzbid0IHN1cHBvcnQgbW9yZSB0aGFuIG9uZSBHZW9Qb2ludCBpbiBhIGNsYXNzKSByZWplY3Qgd2l0aCBhbiBcIkluY29ycmVjdCBUeXBlXCJcbiAgLy8gUGFyc2UgZXJyb3Igd2l0aCBhIGRlc2NpcHRpdmUgbWVzc2FnZS4gSWYgdGhlIGZpZWxkIGFscmVhZHkgZXhpc3RzLCB0aGlzIGZ1bmN0aW9uIG11c3RcbiAgLy8gbm90IG1vZGlmeSB0aGUgc2NoZW1hLCBhbmQgbXVzdCByZWplY3Qgd2l0aCBEVVBMSUNBVEVfVkFMVUUgZXJyb3IuXG4gIC8vIElmIHRoaXMgaXMgY2FsbGVkIGZvciBhIGNsYXNzIHRoYXQgZG9lc24ndCBleGlzdCwgdGhpcyBmdW5jdGlvbiBtdXN0IGNyZWF0ZSB0aGF0IGNsYXNzLlxuXG4gIC8vIFRPRE86IHRocm93IGFuIGVycm9yIGlmIGFuIHVuc3VwcG9ydGVkIGZpZWxkIHR5cGUgaXMgcGFzc2VkLiBEZWNpZGluZyB3aGV0aGVyIGEgdHlwZSBpcyBzdXBwb3J0ZWRcbiAgLy8gc2hvdWxkIGJlIHRoZSBqb2Igb2YgdGhlIGFkYXB0ZXIuIFNvbWUgYWRhcHRlcnMgbWF5IG5vdCBzdXBwb3J0IEdlb1BvaW50IGF0IGFsbC4gT3RoZXJzIG1heVxuICAvLyBTdXBwb3J0IGFkZGl0aW9uYWwgdHlwZXMgdGhhdCBNb25nbyBkb2Vzbid0LCBsaWtlIE1vbmV5LCBvciBzb21ldGhpbmcuXG5cbiAgLy8gVE9ETzogZG9uJ3Qgc3BlbmQgYW4gZXh0cmEgcXVlcnkgb24gZmluZGluZyB0aGUgc2NoZW1hIGlmIHRoZSB0eXBlIHdlIGFyZSB0cnlpbmcgdG8gYWRkIGlzbid0IGEgR2VvUG9pbnQuXG4gIGFkZEZpZWxkSWZOb3RFeGlzdHMoY2xhc3NOYW1lOiBzdHJpbmcsIGZpZWxkTmFtZTogc3RyaW5nLCBmaWVsZFR5cGU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLl9mZXRjaE9uZVNjaGVtYUZyb21fU0NIRU1BKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKFxuICAgICAgICBzY2hlbWEgPT4ge1xuICAgICAgICAgIC8vIElmIGEgZmllbGQgd2l0aCB0aGlzIG5hbWUgYWxyZWFkeSBleGlzdHMsIGl0IHdpbGwgYmUgaGFuZGxlZCBlbHNld2hlcmUuXG4gICAgICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAhPSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gVGhlIHNjaGVtYSBleGlzdHMuIENoZWNrIGZvciBleGlzdGluZyBHZW9Qb2ludHMuXG4gICAgICAgICAgaWYgKGZpZWxkVHlwZS50eXBlID09PSAnR2VvUG9pbnQnKSB7XG4gICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhlcmUgYXJlIG5vdCBvdGhlciBnZW9wb2ludCBmaWVsZHNcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgT2JqZWN0LmtleXMoc2NoZW1hLmZpZWxkcykuc29tZShcbiAgICAgICAgICAgICAgICBleGlzdGluZ0ZpZWxkID0+IHNjaGVtYS5maWVsZHNbZXhpc3RpbmdGaWVsZF0udHlwZSA9PT0gJ0dlb1BvaW50J1xuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLFxuICAgICAgICAgICAgICAgICdNb25nb0RCIG9ubHkgc3VwcG9ydHMgb25lIEdlb1BvaW50IGZpZWxkIGluIGEgY2xhc3MuJ1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yID0+IHtcbiAgICAgICAgICAvLyBJZiBlcnJvciBpcyB1bmRlZmluZWQsIHRoZSBzY2hlbWEgZG9lc24ndCBleGlzdCwgYW5kIHdlIGNhbiBjcmVhdGUgdGhlIHNjaGVtYSB3aXRoIHRoZSBmaWVsZC5cbiAgICAgICAgICAvLyBJZiBzb21lIG90aGVyIGVycm9yLCByZWplY3Qgd2l0aCBpdC5cbiAgICAgICAgICBpZiAoZXJyb3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBjb25zdCB7IHR5cGUsIHRhcmdldENsYXNzLCAuLi5maWVsZE9wdGlvbnMgfSA9IGZpZWxkVHlwZTtcbiAgICAgICAgLy8gV2UgdXNlICRleGlzdHMgYW5kICRzZXQgdG8gYXZvaWQgb3ZlcndyaXRpbmcgdGhlIGZpZWxkIHR5cGUgaWYgaXRcbiAgICAgICAgLy8gYWxyZWFkeSBleGlzdHMuIChpdCBjb3VsZCBoYXZlIGFkZGVkIGluYmV0d2VlbiB0aGUgbGFzdCBxdWVyeSBhbmQgdGhlIHVwZGF0ZSlcbiAgICAgICAgaWYgKGZpZWxkT3B0aW9ucyAmJiBPYmplY3Qua2V5cyhmaWVsZE9wdGlvbnMpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy51cHNlcnRTY2hlbWEoXG4gICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICB7IFtmaWVsZE5hbWVdOiB7ICRleGlzdHM6IGZhbHNlIH0gfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgJHNldDoge1xuICAgICAgICAgICAgICAgIFtmaWVsZE5hbWVdOiBwYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUoe1xuICAgICAgICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgICAgICAgIHRhcmdldENsYXNzLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIFtgX21ldGFkYXRhLmZpZWxkc19vcHRpb25zLiR7ZmllbGROYW1lfWBdOiBmaWVsZE9wdGlvbnMsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy51cHNlcnRTY2hlbWEoXG4gICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICB7IFtmaWVsZE5hbWVdOiB7ICRleGlzdHM6IGZhbHNlIH0gfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgJHNldDoge1xuICAgICAgICAgICAgICAgIFtmaWVsZE5hbWVdOiBwYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUoe1xuICAgICAgICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgICAgICAgIHRhcmdldENsYXNzLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG59XG5cbi8vIEV4cG9ydGVkIGZvciB0ZXN0aW5nIHJlYXNvbnMgYW5kIGJlY2F1c2Ugd2UgaGF2ZW4ndCBtb3ZlZCBhbGwgbW9uZ28gc2NoZW1hIGZvcm1hdFxuLy8gcmVsYXRlZCBsb2dpYyBpbnRvIHRoZSBkYXRhYmFzZSBhZGFwdGVyIHlldC5cbk1vbmdvU2NoZW1hQ29sbGVjdGlvbi5fVEVTVG1vbmdvU2NoZW1hVG9QYXJzZVNjaGVtYSA9IG1vbmdvU2NoZW1hVG9QYXJzZVNjaGVtYTtcbk1vbmdvU2NoZW1hQ29sbGVjdGlvbi5wYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUgPSBwYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGU7XG5cbmV4cG9ydCBkZWZhdWx0IE1vbmdvU2NoZW1hQ29sbGVjdGlvbjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js b/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js deleted file mode 100644 index 79bb74789f..0000000000 --- a/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ /dev/null @@ -1,957 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.MongoStorageAdapter = void 0; - -var _MongoCollection = _interopRequireDefault(require("./MongoCollection")); - -var _MongoSchemaCollection = _interopRequireDefault(require("./MongoSchemaCollection")); - -var _StorageAdapter = require("../StorageAdapter"); - -var _mongodbUrl = require("../../../vendor/mongodbUrl"); - -var _MongoTransform = require("./MongoTransform"); - -var _node = _interopRequireDefault(require("parse/node")); - -var _lodash = _interopRequireDefault(require("lodash")); - -var _defaults = _interopRequireDefault(require("../../../defaults")); - -var _logger = _interopRequireDefault(require("../../../logger")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } - -function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } - -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } - -// -disable-next -const mongodb = require('mongodb'); - -const MongoClient = mongodb.MongoClient; -const ReadPreference = mongodb.ReadPreference; -const MongoSchemaCollectionName = '_SCHEMA'; - -const storageAdapterAllCollections = mongoAdapter => { - return mongoAdapter.connect().then(() => mongoAdapter.database.collections()).then(collections => { - return collections.filter(collection => { - if (collection.namespace.match(/\.system\./)) { - return false; - } // TODO: If you have one app with a collection prefix that happens to be a prefix of another - // apps prefix, this will go very very badly. We should fix that somehow. - - - return collection.collectionName.indexOf(mongoAdapter._collectionPrefix) == 0; - }); - }); -}; - -const convertParseSchemaToMongoSchema = (_ref) => { - let schema = _extends({}, _ref); - - delete schema.fields._rperm; - delete schema.fields._wperm; - - if (schema.className === '_User') { - // Legacy mongo adapter knows about the difference between password and _hashed_password. - // Future database adapters will only know about _hashed_password. - // Note: Parse Server will bring back password with injectDefaultSchema, so we don't need - // to add _hashed_password back ever. - delete schema.fields._hashed_password; - } - - return schema; -}; // Returns { code, error } if invalid, or { result }, an object -// suitable for inserting into _SCHEMA collection, otherwise. - - -const mongoSchemaFromFieldsAndClassNameAndCLP = (fields, className, classLevelPermissions, indexes) => { - const mongoObject = { - _id: className, - objectId: 'string', - updatedAt: 'string', - createdAt: 'string', - _metadata: undefined - }; - - for (const fieldName in fields) { - const _fields$fieldName = fields[fieldName], - { - type, - targetClass - } = _fields$fieldName, - fieldOptions = _objectWithoutProperties(_fields$fieldName, ["type", "targetClass"]); - - mongoObject[fieldName] = _MongoSchemaCollection.default.parseFieldTypeToMongoFieldType({ - type, - targetClass - }); - - if (fieldOptions && Object.keys(fieldOptions).length > 0) { - mongoObject._metadata = mongoObject._metadata || {}; - mongoObject._metadata.fields_options = mongoObject._metadata.fields_options || {}; - mongoObject._metadata.fields_options[fieldName] = fieldOptions; - } - } - - if (typeof classLevelPermissions !== 'undefined') { - mongoObject._metadata = mongoObject._metadata || {}; - - if (!classLevelPermissions) { - delete mongoObject._metadata.class_permissions; - } else { - mongoObject._metadata.class_permissions = classLevelPermissions; - } - } - - if (indexes && typeof indexes === 'object' && Object.keys(indexes).length > 0) { - mongoObject._metadata = mongoObject._metadata || {}; - mongoObject._metadata.indexes = indexes; - } - - if (!mongoObject._metadata) { - // cleanup the unused _metadata - delete mongoObject._metadata; - } - - return mongoObject; -}; - -class MongoStorageAdapter { - // Private - // Public - constructor({ - uri = _defaults.default.DefaultMongoURI, - collectionPrefix = '', - mongoOptions = {} - }) { - this._uri = uri; - this._collectionPrefix = collectionPrefix; - this._mongoOptions = mongoOptions; - this._mongoOptions.useNewUrlParser = true; - this._mongoOptions.useUnifiedTopology = true; // MaxTimeMS is not a global MongoDB client option, it is applied per operation. - - this._maxTimeMS = mongoOptions.maxTimeMS; - this.canSortOnJoinTables = true; - delete mongoOptions.maxTimeMS; - } - - connect() { - if (this.connectionPromise) { - return this.connectionPromise; - } // parsing and re-formatting causes the auth value (if there) to get URI - // encoded - - - const encodedUri = (0, _mongodbUrl.format)((0, _mongodbUrl.parse)(this._uri)); - this.connectionPromise = MongoClient.connect(encodedUri, this._mongoOptions).then(client => { - // Starting mongoDB 3.0, the MongoClient.connect don't return a DB anymore but a client - // Fortunately, we can get back the options and use them to select the proper DB. - // https://github.com/mongodb/node-mongodb-native/blob/2c35d76f08574225b8db02d7bef687123e6bb018/lib/mongo_client.js#L885 - const options = client.s.options; - const database = client.db(options.dbName); - - if (!database) { - delete this.connectionPromise; - return; - } - - database.on('error', () => { - delete this.connectionPromise; - }); - database.on('close', () => { - delete this.connectionPromise; - }); - this.client = client; - this.database = database; - }).catch(err => { - delete this.connectionPromise; - return Promise.reject(err); - }); - return this.connectionPromise; - } - - handleError(error) { - if (error && error.code === 13) { - // Unauthorized error - delete this.client; - delete this.database; - delete this.connectionPromise; - - _logger.default.error('Received unauthorized error', { - error: error - }); - } - - throw error; - } - - handleShutdown() { - if (!this.client) { - return Promise.resolve(); - } - - return this.client.close(false); - } - - _adaptiveCollection(name) { - return this.connect().then(() => this.database.collection(this._collectionPrefix + name)).then(rawCollection => new _MongoCollection.default(rawCollection)).catch(err => this.handleError(err)); - } - - _schemaCollection() { - return this.connect().then(() => this._adaptiveCollection(MongoSchemaCollectionName)).then(collection => new _MongoSchemaCollection.default(collection)); - } - - classExists(name) { - return this.connect().then(() => { - return this.database.listCollections({ - name: this._collectionPrefix + name - }).toArray(); - }).then(collections => { - return collections.length > 0; - }).catch(err => this.handleError(err)); - } - - setClassLevelPermissions(className, CLPs) { - return this._schemaCollection().then(schemaCollection => schemaCollection.updateSchema(className, { - $set: { - '_metadata.class_permissions': CLPs - } - })).catch(err => this.handleError(err)); - } - - setIndexesWithSchemaFormat(className, submittedIndexes, existingIndexes = {}, fields) { - if (submittedIndexes === undefined) { - return Promise.resolve(); - } - - if (Object.keys(existingIndexes).length === 0) { - existingIndexes = { - _id_: { - _id: 1 - } - }; - } - - const deletePromises = []; - const insertedIndexes = []; - Object.keys(submittedIndexes).forEach(name => { - const field = submittedIndexes[name]; - - if (existingIndexes[name] && field.__op !== 'Delete') { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Index ${name} exists, cannot update.`); - } - - if (!existingIndexes[name] && field.__op === 'Delete') { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Index ${name} does not exist, cannot delete.`); - } - - if (field.__op === 'Delete') { - const promise = this.dropIndex(className, name); - deletePromises.push(promise); - delete existingIndexes[name]; - } else { - Object.keys(field).forEach(key => { - if (!Object.prototype.hasOwnProperty.call(fields, key.indexOf('_p_') === 0 ? key.replace('_p_', '') : key)) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Field ${key} does not exist, cannot add index.`); - } - }); - existingIndexes[name] = field; - insertedIndexes.push({ - key: field, - name - }); - } - }); - let insertPromise = Promise.resolve(); - - if (insertedIndexes.length > 0) { - insertPromise = this.createIndexes(className, insertedIndexes); - } - - return Promise.all(deletePromises).then(() => insertPromise).then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.updateSchema(className, { - $set: { - '_metadata.indexes': existingIndexes - } - })).catch(err => this.handleError(err)); - } - - setIndexesFromMongo(className) { - return this.getIndexes(className).then(indexes => { - indexes = indexes.reduce((obj, index) => { - if (index.key._fts) { - delete index.key._fts; - delete index.key._ftsx; - - for (const field in index.weights) { - index.key[field] = 'text'; - } - } - - obj[index.name] = index.key; - return obj; - }, {}); - return this._schemaCollection().then(schemaCollection => schemaCollection.updateSchema(className, { - $set: { - '_metadata.indexes': indexes - } - })); - }).catch(err => this.handleError(err)).catch(() => { - // Ignore if collection not found - return Promise.resolve(); - }); - } - - createClass(className, schema) { - schema = convertParseSchemaToMongoSchema(schema); - const mongoObject = mongoSchemaFromFieldsAndClassNameAndCLP(schema.fields, className, schema.classLevelPermissions, schema.indexes); - mongoObject._id = className; - return this.setIndexesWithSchemaFormat(className, schema.indexes, {}, schema.fields).then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.insertSchema(mongoObject)).catch(err => this.handleError(err)); - } - - addFieldIfNotExists(className, fieldName, type) { - return this._schemaCollection().then(schemaCollection => schemaCollection.addFieldIfNotExists(className, fieldName, type)).then(() => this.createIndexesIfNeeded(className, fieldName, type)).catch(err => this.handleError(err)); - } // Drops a collection. Resolves with true if it was a Parse Schema (eg. _User, Custom, etc.) - // and resolves with false if it wasn't (eg. a join table). Rejects if deletion was impossible. - - - deleteClass(className) { - return this._adaptiveCollection(className).then(collection => collection.drop()).catch(error => { - // 'ns not found' means collection was already gone. Ignore deletion attempt. - if (error.message == 'ns not found') { - return; - } - - throw error; - }) // We've dropped the collection, now remove the _SCHEMA document - .then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.findAndDeleteSchema(className)).catch(err => this.handleError(err)); - } - - deleteAllClasses(fast) { - return storageAdapterAllCollections(this).then(collections => Promise.all(collections.map(collection => fast ? collection.deleteMany({}) : collection.drop()))); - } // Remove the column and all the data. For Relations, the _Join collection is handled - // specially, this function does not delete _Join columns. It should, however, indicate - // that the relation fields does not exist anymore. In mongo, this means removing it from - // the _SCHEMA collection. There should be no actual data in the collection under the same name - // as the relation column, so it's fine to attempt to delete it. If the fields listed to be - // deleted do not exist, this function should return successfully anyways. Checking for - // attempts to delete non-existent fields is the responsibility of Parse Server. - // Pointer field names are passed for legacy reasons: the original mongo - // format stored pointer field names differently in the database, and therefore - // needed to know the type of the field before it could delete it. Future database - // adapters should ignore the pointerFieldNames argument. All the field names are in - // fieldNames, they show up additionally in the pointerFieldNames database for use - // by the mongo adapter, which deals with the legacy mongo format. - // This function is not obligated to delete fields atomically. It is given the field - // names in a list so that databases that are capable of deleting fields atomically - // may do so. - // Returns a Promise. - - - deleteFields(className, schema, fieldNames) { - const mongoFormatNames = fieldNames.map(fieldName => { - if (schema.fields[fieldName].type === 'Pointer') { - return `_p_${fieldName}`; - } else { - return fieldName; - } - }); - const collectionUpdate = { - $unset: {} - }; - mongoFormatNames.forEach(name => { - collectionUpdate['$unset'][name] = null; - }); - const collectionFilter = { - $or: [] - }; - mongoFormatNames.forEach(name => { - collectionFilter['$or'].push({ - [name]: { - $exists: true - } - }); - }); - const schemaUpdate = { - $unset: {} - }; - fieldNames.forEach(name => { - schemaUpdate['$unset'][name] = null; - schemaUpdate['$unset'][`_metadata.fields_options.${name}`] = null; - }); - return this._adaptiveCollection(className).then(collection => collection.updateMany(collectionFilter, collectionUpdate)).then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.updateSchema(className, schemaUpdate)).catch(err => this.handleError(err)); - } // Return a promise for all schemas known to this adapter, in Parse format. In case the - // schemas cannot be retrieved, returns a promise that rejects. Requirements for the - // rejection reason are TBD. - - - getAllClasses() { - return this._schemaCollection().then(schemasCollection => schemasCollection._fetchAllSchemasFrom_SCHEMA()).catch(err => this.handleError(err)); - } // Return a promise for the schema with the given name, in Parse format. If - // this adapter doesn't know about the schema, return a promise that rejects with - // undefined as the reason. - - - getClass(className) { - return this._schemaCollection().then(schemasCollection => schemasCollection._fetchOneSchemaFrom_SCHEMA(className)).catch(err => this.handleError(err)); - } // TODO: As yet not particularly well specified. Creates an object. Maybe shouldn't even need the schema, - // and should infer from the type. Or maybe does need the schema for validations. Or maybe needs - // the schema only for the legacy mongo format. We'll figure that out later. - - - createObject(className, schema, object, transactionalSession) { - schema = convertParseSchemaToMongoSchema(schema); - const mongoObject = (0, _MongoTransform.parseObjectToMongoObjectForCreate)(className, object, schema); - return this._adaptiveCollection(className).then(collection => collection.insertOne(mongoObject, transactionalSession)).catch(error => { - if (error.code === 11000) { - // Duplicate value - const err = new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); - err.underlyingError = error; - - if (error.message) { - const matches = error.message.match(/index:[\sa-zA-Z0-9_\-\.]+\$?([a-zA-Z_-]+)_1/); - - if (matches && Array.isArray(matches)) { - err.userInfo = { - duplicated_field: matches[1] - }; - } - } - - throw err; - } - - throw error; - }).catch(err => this.handleError(err)); - } // Remove all objects that match the given Parse Query. - // If no objects match, reject with OBJECT_NOT_FOUND. If objects are found and deleted, resolve with undefined. - // If there is some other error, reject with INTERNAL_SERVER_ERROR. - - - deleteObjectsByQuery(className, schema, query, transactionalSession) { - schema = convertParseSchemaToMongoSchema(schema); - return this._adaptiveCollection(className).then(collection => { - const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); - return collection.deleteMany(mongoWhere, transactionalSession); - }).catch(err => this.handleError(err)).then(({ - result - }) => { - if (result.n === 0) { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } - - return Promise.resolve(); - }, () => { - throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'Database adapter error'); - }); - } // Apply the update to all objects that match the given Parse Query. - - - updateObjectsByQuery(className, schema, query, update, transactionalSession) { - schema = convertParseSchemaToMongoSchema(schema); - const mongoUpdate = (0, _MongoTransform.transformUpdate)(className, update, schema); - const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); - return this._adaptiveCollection(className).then(collection => collection.updateMany(mongoWhere, mongoUpdate, transactionalSession)).catch(err => this.handleError(err)); - } // Atomically finds and updates an object based on query. - // Return value not currently well specified. - - - findOneAndUpdate(className, schema, query, update, transactionalSession) { - schema = convertParseSchemaToMongoSchema(schema); - const mongoUpdate = (0, _MongoTransform.transformUpdate)(className, update, schema); - const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); - return this._adaptiveCollection(className).then(collection => collection._mongoCollection.findOneAndUpdate(mongoWhere, mongoUpdate, { - returnOriginal: false, - session: transactionalSession || undefined - })).then(result => (0, _MongoTransform.mongoObjectToParseObject)(className, result.value, schema)).catch(error => { - if (error.code === 11000) { - throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); - } - - throw error; - }).catch(err => this.handleError(err)); - } // Hopefully we can get rid of this. It's only used for config and hooks. - - - upsertOneObject(className, schema, query, update, transactionalSession) { - schema = convertParseSchemaToMongoSchema(schema); - const mongoUpdate = (0, _MongoTransform.transformUpdate)(className, update, schema); - const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); - return this._adaptiveCollection(className).then(collection => collection.upsertOne(mongoWhere, mongoUpdate, transactionalSession)).catch(err => this.handleError(err)); - } // Executes a find. Accepts: className, query in Parse format, and { skip, limit, sort }. - - - find(className, schema, query, { - skip, - limit, - sort, - keys, - readPreference, - hint, - caseInsensitive, - explain - }) { - schema = convertParseSchemaToMongoSchema(schema); - const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema); - - const mongoSort = _lodash.default.mapKeys(sort, (value, fieldName) => (0, _MongoTransform.transformKey)(className, fieldName, schema)); - - const mongoKeys = _lodash.default.reduce(keys, (memo, key) => { - if (key === 'ACL') { - memo['_rperm'] = 1; - memo['_wperm'] = 1; - } else { - memo[(0, _MongoTransform.transformKey)(className, key, schema)] = 1; - } - - return memo; - }, {}); // If we aren't requesting the `_id` field, we need to explicitly opt out - // of it. Doing so in parse-server is unusual, but it can allow us to - // optimize some queries with covering indexes. - - - if (keys && !mongoKeys._id) { - mongoKeys._id = 0; - } - - readPreference = this._parseReadPreference(readPreference); - return this.createTextIndexesIfNeeded(className, query, schema).then(() => this._adaptiveCollection(className)).then(collection => collection.find(mongoWhere, { - skip, - limit, - sort: mongoSort, - keys: mongoKeys, - maxTimeMS: this._maxTimeMS, - readPreference, - hint, - caseInsensitive, - explain - })).then(objects => { - if (explain) { - return objects; - } - - return objects.map(object => (0, _MongoTransform.mongoObjectToParseObject)(className, object, schema)); - }).catch(err => this.handleError(err)); - } - - ensureIndex(className, schema, fieldNames, indexName, caseInsensitive = false, options = {}) { - schema = convertParseSchemaToMongoSchema(schema); - const indexCreationRequest = {}; - const mongoFieldNames = fieldNames.map(fieldName => (0, _MongoTransform.transformKey)(className, fieldName, schema)); - mongoFieldNames.forEach(fieldName => { - indexCreationRequest[fieldName] = options.indexType !== undefined ? options.indexType : 1; - }); - const defaultOptions = { - background: true, - sparse: true - }; - const indexNameOptions = indexName ? { - name: indexName - } : {}; - const ttlOptions = options.ttl !== undefined ? { - expireAfterSeconds: options.ttl - } : {}; - const caseInsensitiveOptions = caseInsensitive ? { - collation: _MongoCollection.default.caseInsensitiveCollation() - } : {}; - - const indexOptions = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, defaultOptions), caseInsensitiveOptions), indexNameOptions), ttlOptions); - - return this._adaptiveCollection(className).then(collection => new Promise((resolve, reject) => collection._mongoCollection.createIndex(indexCreationRequest, indexOptions, error => error ? reject(error) : resolve()))).catch(err => this.handleError(err)); - } // Create a unique index. Unique indexes on nullable fields are not allowed. Since we don't - // currently know which fields are nullable and which aren't, we ignore that criteria. - // As such, we shouldn't expose this function to users of parse until we have an out-of-band - // Way of determining if a field is nullable. Undefined doesn't count against uniqueness, - // which is why we use sparse indexes. - - - ensureUniqueness(className, schema, fieldNames) { - schema = convertParseSchemaToMongoSchema(schema); - const indexCreationRequest = {}; - const mongoFieldNames = fieldNames.map(fieldName => (0, _MongoTransform.transformKey)(className, fieldName, schema)); - mongoFieldNames.forEach(fieldName => { - indexCreationRequest[fieldName] = 1; - }); - return this._adaptiveCollection(className).then(collection => collection._ensureSparseUniqueIndexInBackground(indexCreationRequest)).catch(error => { - if (error.code === 11000) { - throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'Tried to ensure field uniqueness for a class that already has duplicates.'); - } - - throw error; - }).catch(err => this.handleError(err)); - } // Used in tests - - - _rawFind(className, query) { - return this._adaptiveCollection(className).then(collection => collection.find(query, { - maxTimeMS: this._maxTimeMS - })).catch(err => this.handleError(err)); - } // Executes a count. - - - count(className, schema, query, readPreference, hint) { - schema = convertParseSchemaToMongoSchema(schema); - readPreference = this._parseReadPreference(readPreference); - return this._adaptiveCollection(className).then(collection => collection.count((0, _MongoTransform.transformWhere)(className, query, schema, true), { - maxTimeMS: this._maxTimeMS, - readPreference, - hint - })).catch(err => this.handleError(err)); - } - - distinct(className, schema, query, fieldName) { - schema = convertParseSchemaToMongoSchema(schema); - const isPointerField = schema.fields[fieldName] && schema.fields[fieldName].type === 'Pointer'; - const transformField = (0, _MongoTransform.transformKey)(className, fieldName, schema); - return this._adaptiveCollection(className).then(collection => collection.distinct(transformField, (0, _MongoTransform.transformWhere)(className, query, schema))).then(objects => { - objects = objects.filter(obj => obj != null); - return objects.map(object => { - if (isPointerField) { - return (0, _MongoTransform.transformPointerString)(schema, fieldName, object); - } - - return (0, _MongoTransform.mongoObjectToParseObject)(className, object, schema); - }); - }).catch(err => this.handleError(err)); - } - - aggregate(className, schema, pipeline, readPreference, hint, explain) { - let isPointerField = false; - pipeline = pipeline.map(stage => { - if (stage.$group) { - stage.$group = this._parseAggregateGroupArgs(schema, stage.$group); - - if (stage.$group._id && typeof stage.$group._id === 'string' && stage.$group._id.indexOf('$_p_') >= 0) { - isPointerField = true; - } - } - - if (stage.$match) { - stage.$match = this._parseAggregateArgs(schema, stage.$match); - } - - if (stage.$project) { - stage.$project = this._parseAggregateProjectArgs(schema, stage.$project); - } - - if (stage.$geoNear && stage.$geoNear.query) { - stage.$geoNear.query = this._parseAggregateArgs(schema, stage.$geoNear.query); - } - - return stage; - }); - readPreference = this._parseReadPreference(readPreference); - return this._adaptiveCollection(className).then(collection => collection.aggregate(pipeline, { - readPreference, - maxTimeMS: this._maxTimeMS, - hint, - explain - })).then(results => { - results.forEach(result => { - if (Object.prototype.hasOwnProperty.call(result, '_id')) { - if (isPointerField && result._id) { - result._id = result._id.split('$')[1]; - } - - if (result._id == null || result._id == undefined || ['object', 'string'].includes(typeof result._id) && _lodash.default.isEmpty(result._id)) { - result._id = null; - } - - result.objectId = result._id; - delete result._id; - } - }); - return results; - }).then(objects => objects.map(object => (0, _MongoTransform.mongoObjectToParseObject)(className, object, schema))).catch(err => this.handleError(err)); - } // This function will recursively traverse the pipeline and convert any Pointer or Date columns. - // If we detect a pointer column we will rename the column being queried for to match the column - // in the database. We also modify the value to what we expect the value to be in the database - // as well. - // For dates, the driver expects a Date object, but we have a string coming in. So we'll convert - // the string to a Date so the driver can perform the necessary comparison. - // - // The goal of this method is to look for the "leaves" of the pipeline and determine if it needs - // to be converted. The pipeline can have a few different forms. For more details, see: - // https://docs.mongodb.com/manual/reference/operator/aggregation/ - // - // If the pipeline is an array, it means we are probably parsing an '$and' or '$or' operator. In - // that case we need to loop through all of it's children to find the columns being operated on. - // If the pipeline is an object, then we'll loop through the keys checking to see if the key name - // matches one of the schema columns. If it does match a column and the column is a Pointer or - // a Date, then we'll convert the value as described above. - // - // As much as I hate recursion...this seemed like a good fit for it. We're essentially traversing - // down a tree to find a "leaf node" and checking to see if it needs to be converted. - - - _parseAggregateArgs(schema, pipeline) { - if (pipeline === null) { - return null; - } else if (Array.isArray(pipeline)) { - return pipeline.map(value => this._parseAggregateArgs(schema, value)); - } else if (typeof pipeline === 'object') { - const returnValue = {}; - - for (const field in pipeline) { - if (schema.fields[field] && schema.fields[field].type === 'Pointer') { - if (typeof pipeline[field] === 'object') { - // Pass objects down to MongoDB...this is more than likely an $exists operator. - returnValue[`_p_${field}`] = pipeline[field]; - } else { - returnValue[`_p_${field}`] = `${schema.fields[field].targetClass}$${pipeline[field]}`; - } - } else if (schema.fields[field] && schema.fields[field].type === 'Date') { - returnValue[field] = this._convertToDate(pipeline[field]); - } else { - returnValue[field] = this._parseAggregateArgs(schema, pipeline[field]); - } - - if (field === 'objectId') { - returnValue['_id'] = returnValue[field]; - delete returnValue[field]; - } else if (field === 'createdAt') { - returnValue['_created_at'] = returnValue[field]; - delete returnValue[field]; - } else if (field === 'updatedAt') { - returnValue['_updated_at'] = returnValue[field]; - delete returnValue[field]; - } - } - - return returnValue; - } - - return pipeline; - } // This function is slightly different than the one above. Rather than trying to combine these - // two functions and making the code even harder to understand, I decided to split it up. The - // difference with this function is we are not transforming the values, only the keys of the - // pipeline. - - - _parseAggregateProjectArgs(schema, pipeline) { - const returnValue = {}; - - for (const field in pipeline) { - if (schema.fields[field] && schema.fields[field].type === 'Pointer') { - returnValue[`_p_${field}`] = pipeline[field]; - } else { - returnValue[field] = this._parseAggregateArgs(schema, pipeline[field]); - } - - if (field === 'objectId') { - returnValue['_id'] = returnValue[field]; - delete returnValue[field]; - } else if (field === 'createdAt') { - returnValue['_created_at'] = returnValue[field]; - delete returnValue[field]; - } else if (field === 'updatedAt') { - returnValue['_updated_at'] = returnValue[field]; - delete returnValue[field]; - } - } - - return returnValue; - } // This function is slightly different than the two above. MongoDB $group aggregate looks like: - // { $group: { _id: , : { : }, ... } } - // The could be a column name, prefixed with the '$' character. We'll look for - // these and check to see if it is a 'Pointer' or if it's one of createdAt, - // updatedAt or objectId and change it accordingly. - - - _parseAggregateGroupArgs(schema, pipeline) { - if (Array.isArray(pipeline)) { - return pipeline.map(value => this._parseAggregateGroupArgs(schema, value)); - } else if (typeof pipeline === 'object') { - const returnValue = {}; - - for (const field in pipeline) { - returnValue[field] = this._parseAggregateGroupArgs(schema, pipeline[field]); - } - - return returnValue; - } else if (typeof pipeline === 'string') { - const field = pipeline.substring(1); - - if (schema.fields[field] && schema.fields[field].type === 'Pointer') { - return `$_p_${field}`; - } else if (field == 'createdAt') { - return '$_created_at'; - } else if (field == 'updatedAt') { - return '$_updated_at'; - } - } - - return pipeline; - } // This function will attempt to convert the provided value to a Date object. Since this is part - // of an aggregation pipeline, the value can either be a string or it can be another object with - // an operator in it (like $gt, $lt, etc). Because of this I felt it was easier to make this a - // recursive method to traverse down to the "leaf node" which is going to be the string. - - - _convertToDate(value) { - if (typeof value === 'string') { - return new Date(value); - } - - const returnValue = {}; - - for (const field in value) { - returnValue[field] = this._convertToDate(value[field]); - } - - return returnValue; - } - - _parseReadPreference(readPreference) { - if (readPreference) { - readPreference = readPreference.toUpperCase(); - } - - switch (readPreference) { - case 'PRIMARY': - readPreference = ReadPreference.PRIMARY; - break; - - case 'PRIMARY_PREFERRED': - readPreference = ReadPreference.PRIMARY_PREFERRED; - break; - - case 'SECONDARY': - readPreference = ReadPreference.SECONDARY; - break; - - case 'SECONDARY_PREFERRED': - readPreference = ReadPreference.SECONDARY_PREFERRED; - break; - - case 'NEAREST': - readPreference = ReadPreference.NEAREST; - break; - - case undefined: - case null: - case '': - break; - - default: - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Not supported read preference.'); - } - - return readPreference; - } - - performInitialization() { - return Promise.resolve(); - } - - createIndex(className, index) { - return this._adaptiveCollection(className).then(collection => collection._mongoCollection.createIndex(index)).catch(err => this.handleError(err)); - } - - createIndexes(className, indexes) { - return this._adaptiveCollection(className).then(collection => collection._mongoCollection.createIndexes(indexes)).catch(err => this.handleError(err)); - } - - createIndexesIfNeeded(className, fieldName, type) { - if (type && type.type === 'Polygon') { - const index = { - [fieldName]: '2dsphere' - }; - return this.createIndex(className, index); - } - - return Promise.resolve(); - } - - createTextIndexesIfNeeded(className, query, schema) { - for (const fieldName in query) { - if (!query[fieldName] || !query[fieldName].$text) { - continue; - } - - const existingIndexes = schema.indexes; - - for (const key in existingIndexes) { - const index = existingIndexes[key]; - - if (Object.prototype.hasOwnProperty.call(index, fieldName)) { - return Promise.resolve(); - } - } - - const indexName = `${fieldName}_text`; - const textIndex = { - [indexName]: { - [fieldName]: 'text' - } - }; - return this.setIndexesWithSchemaFormat(className, textIndex, existingIndexes, schema.fields).catch(error => { - if (error.code === 85) { - // Index exist with different options - return this.setIndexesFromMongo(className); - } - - throw error; - }); - } - - return Promise.resolve(); - } - - getIndexes(className) { - return this._adaptiveCollection(className).then(collection => collection._mongoCollection.indexes()).catch(err => this.handleError(err)); - } - - dropIndex(className, index) { - return this._adaptiveCollection(className).then(collection => collection._mongoCollection.dropIndex(index)).catch(err => this.handleError(err)); - } - - dropAllIndexes(className) { - return this._adaptiveCollection(className).then(collection => collection._mongoCollection.dropIndexes()).catch(err => this.handleError(err)); - } - - updateSchemaWithIndexes() { - return this.getAllClasses().then(classes => { - const promises = classes.map(schema => { - return this.setIndexesFromMongo(schema.className); - }); - return Promise.all(promises); - }).catch(err => this.handleError(err)); - } - - createTransactionalSession() { - const transactionalSection = this.client.startSession(); - transactionalSection.startTransaction(); - return Promise.resolve(transactionalSection); - } - - commitTransactionalSession(transactionalSection) { - return transactionalSection.commitTransaction().then(() => { - transactionalSection.endSession(); - }); - } - - abortTransactionalSession(transactionalSection) { - return transactionalSection.abortTransaction().then(() => { - transactionalSection.endSession(); - }); - } - -} - -exports.MongoStorageAdapter = MongoStorageAdapter; -var _default = MongoStorageAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvU3RvcmFnZUFkYXB0ZXIuanMiXSwibmFtZXMiOlsibW9uZ29kYiIsInJlcXVpcmUiLCJNb25nb0NsaWVudCIsIlJlYWRQcmVmZXJlbmNlIiwiTW9uZ29TY2hlbWFDb2xsZWN0aW9uTmFtZSIsInN0b3JhZ2VBZGFwdGVyQWxsQ29sbGVjdGlvbnMiLCJtb25nb0FkYXB0ZXIiLCJjb25uZWN0IiwidGhlbiIsImRhdGFiYXNlIiwiY29sbGVjdGlvbnMiLCJmaWx0ZXIiLCJjb2xsZWN0aW9uIiwibmFtZXNwYWNlIiwibWF0Y2giLCJjb2xsZWN0aW9uTmFtZSIsImluZGV4T2YiLCJfY29sbGVjdGlvblByZWZpeCIsImNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEiLCJzY2hlbWEiLCJmaWVsZHMiLCJfcnBlcm0iLCJfd3Blcm0iLCJjbGFzc05hbWUiLCJfaGFzaGVkX3Bhc3N3b3JkIiwibW9uZ29TY2hlbWFGcm9tRmllbGRzQW5kQ2xhc3NOYW1lQW5kQ0xQIiwiY2xhc3NMZXZlbFBlcm1pc3Npb25zIiwiaW5kZXhlcyIsIm1vbmdvT2JqZWN0IiwiX2lkIiwib2JqZWN0SWQiLCJ1cGRhdGVkQXQiLCJjcmVhdGVkQXQiLCJfbWV0YWRhdGEiLCJ1bmRlZmluZWQiLCJmaWVsZE5hbWUiLCJ0eXBlIiwidGFyZ2V0Q2xhc3MiLCJmaWVsZE9wdGlvbnMiLCJNb25nb1NjaGVtYUNvbGxlY3Rpb24iLCJwYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUiLCJPYmplY3QiLCJrZXlzIiwibGVuZ3RoIiwiZmllbGRzX29wdGlvbnMiLCJjbGFzc19wZXJtaXNzaW9ucyIsIk1vbmdvU3RvcmFnZUFkYXB0ZXIiLCJjb25zdHJ1Y3RvciIsInVyaSIsImRlZmF1bHRzIiwiRGVmYXVsdE1vbmdvVVJJIiwiY29sbGVjdGlvblByZWZpeCIsIm1vbmdvT3B0aW9ucyIsIl91cmkiLCJfbW9uZ29PcHRpb25zIiwidXNlTmV3VXJsUGFyc2VyIiwidXNlVW5pZmllZFRvcG9sb2d5IiwiX21heFRpbWVNUyIsIm1heFRpbWVNUyIsImNhblNvcnRPbkpvaW5UYWJsZXMiLCJjb25uZWN0aW9uUHJvbWlzZSIsImVuY29kZWRVcmkiLCJjbGllbnQiLCJvcHRpb25zIiwicyIsImRiIiwiZGJOYW1lIiwib24iLCJjYXRjaCIsImVyciIsIlByb21pc2UiLCJyZWplY3QiLCJoYW5kbGVFcnJvciIsImVycm9yIiwiY29kZSIsImxvZ2dlciIsImhhbmRsZVNodXRkb3duIiwicmVzb2x2ZSIsImNsb3NlIiwiX2FkYXB0aXZlQ29sbGVjdGlvbiIsIm5hbWUiLCJyYXdDb2xsZWN0aW9uIiwiTW9uZ29Db2xsZWN0aW9uIiwiX3NjaGVtYUNvbGxlY3Rpb24iLCJjbGFzc0V4aXN0cyIsImxpc3RDb2xsZWN0aW9ucyIsInRvQXJyYXkiLCJzZXRDbGFzc0xldmVsUGVybWlzc2lvbnMiLCJDTFBzIiwic2NoZW1hQ29sbGVjdGlvbiIsInVwZGF0ZVNjaGVtYSIsIiRzZXQiLCJzZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdCIsInN1Ym1pdHRlZEluZGV4ZXMiLCJleGlzdGluZ0luZGV4ZXMiLCJfaWRfIiwiZGVsZXRlUHJvbWlzZXMiLCJpbnNlcnRlZEluZGV4ZXMiLCJmb3JFYWNoIiwiZmllbGQiLCJfX29wIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfUVVFUlkiLCJwcm9taXNlIiwiZHJvcEluZGV4IiwicHVzaCIsImtleSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInJlcGxhY2UiLCJpbnNlcnRQcm9taXNlIiwiY3JlYXRlSW5kZXhlcyIsImFsbCIsInNldEluZGV4ZXNGcm9tTW9uZ28iLCJnZXRJbmRleGVzIiwicmVkdWNlIiwib2JqIiwiaW5kZXgiLCJfZnRzIiwiX2Z0c3giLCJ3ZWlnaHRzIiwiY3JlYXRlQ2xhc3MiLCJpbnNlcnRTY2hlbWEiLCJhZGRGaWVsZElmTm90RXhpc3RzIiwiY3JlYXRlSW5kZXhlc0lmTmVlZGVkIiwiZGVsZXRlQ2xhc3MiLCJkcm9wIiwibWVzc2FnZSIsImZpbmRBbmREZWxldGVTY2hlbWEiLCJkZWxldGVBbGxDbGFzc2VzIiwiZmFzdCIsIm1hcCIsImRlbGV0ZU1hbnkiLCJkZWxldGVGaWVsZHMiLCJmaWVsZE5hbWVzIiwibW9uZ29Gb3JtYXROYW1lcyIsImNvbGxlY3Rpb25VcGRhdGUiLCIkdW5zZXQiLCJjb2xsZWN0aW9uRmlsdGVyIiwiJG9yIiwiJGV4aXN0cyIsInNjaGVtYVVwZGF0ZSIsInVwZGF0ZU1hbnkiLCJnZXRBbGxDbGFzc2VzIiwic2NoZW1hc0NvbGxlY3Rpb24iLCJfZmV0Y2hBbGxTY2hlbWFzRnJvbV9TQ0hFTUEiLCJnZXRDbGFzcyIsIl9mZXRjaE9uZVNjaGVtYUZyb21fU0NIRU1BIiwiY3JlYXRlT2JqZWN0Iiwib2JqZWN0IiwidHJhbnNhY3Rpb25hbFNlc3Npb24iLCJpbnNlcnRPbmUiLCJEVVBMSUNBVEVfVkFMVUUiLCJ1bmRlcmx5aW5nRXJyb3IiLCJtYXRjaGVzIiwiQXJyYXkiLCJpc0FycmF5IiwidXNlckluZm8iLCJkdXBsaWNhdGVkX2ZpZWxkIiwiZGVsZXRlT2JqZWN0c0J5UXVlcnkiLCJxdWVyeSIsIm1vbmdvV2hlcmUiLCJyZXN1bHQiLCJuIiwiT0JKRUNUX05PVF9GT1VORCIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsInVwZGF0ZU9iamVjdHNCeVF1ZXJ5IiwidXBkYXRlIiwibW9uZ29VcGRhdGUiLCJmaW5kT25lQW5kVXBkYXRlIiwiX21vbmdvQ29sbGVjdGlvbiIsInJldHVybk9yaWdpbmFsIiwic2Vzc2lvbiIsInZhbHVlIiwidXBzZXJ0T25lT2JqZWN0IiwidXBzZXJ0T25lIiwiZmluZCIsInNraXAiLCJsaW1pdCIsInNvcnQiLCJyZWFkUHJlZmVyZW5jZSIsImhpbnQiLCJjYXNlSW5zZW5zaXRpdmUiLCJleHBsYWluIiwibW9uZ29Tb3J0IiwiXyIsIm1hcEtleXMiLCJtb25nb0tleXMiLCJtZW1vIiwiX3BhcnNlUmVhZFByZWZlcmVuY2UiLCJjcmVhdGVUZXh0SW5kZXhlc0lmTmVlZGVkIiwib2JqZWN0cyIsImVuc3VyZUluZGV4IiwiaW5kZXhOYW1lIiwiaW5kZXhDcmVhdGlvblJlcXVlc3QiLCJtb25nb0ZpZWxkTmFtZXMiLCJpbmRleFR5cGUiLCJkZWZhdWx0T3B0aW9ucyIsImJhY2tncm91bmQiLCJzcGFyc2UiLCJpbmRleE5hbWVPcHRpb25zIiwidHRsT3B0aW9ucyIsInR0bCIsImV4cGlyZUFmdGVyU2Vjb25kcyIsImNhc2VJbnNlbnNpdGl2ZU9wdGlvbnMiLCJjb2xsYXRpb24iLCJjYXNlSW5zZW5zaXRpdmVDb2xsYXRpb24iLCJpbmRleE9wdGlvbnMiLCJjcmVhdGVJbmRleCIsImVuc3VyZVVuaXF1ZW5lc3MiLCJfZW5zdXJlU3BhcnNlVW5pcXVlSW5kZXhJbkJhY2tncm91bmQiLCJfcmF3RmluZCIsImNvdW50IiwiZGlzdGluY3QiLCJpc1BvaW50ZXJGaWVsZCIsInRyYW5zZm9ybUZpZWxkIiwiYWdncmVnYXRlIiwicGlwZWxpbmUiLCJzdGFnZSIsIiRncm91cCIsIl9wYXJzZUFnZ3JlZ2F0ZUdyb3VwQXJncyIsIiRtYXRjaCIsIl9wYXJzZUFnZ3JlZ2F0ZUFyZ3MiLCIkcHJvamVjdCIsIl9wYXJzZUFnZ3JlZ2F0ZVByb2plY3RBcmdzIiwiJGdlb05lYXIiLCJyZXN1bHRzIiwic3BsaXQiLCJpbmNsdWRlcyIsImlzRW1wdHkiLCJyZXR1cm5WYWx1ZSIsIl9jb252ZXJ0VG9EYXRlIiwic3Vic3RyaW5nIiwiRGF0ZSIsInRvVXBwZXJDYXNlIiwiUFJJTUFSWSIsIlBSSU1BUllfUFJFRkVSUkVEIiwiU0VDT05EQVJZIiwiU0VDT05EQVJZX1BSRUZFUlJFRCIsIk5FQVJFU1QiLCJwZXJmb3JtSW5pdGlhbGl6YXRpb24iLCIkdGV4dCIsInRleHRJbmRleCIsImRyb3BBbGxJbmRleGVzIiwiZHJvcEluZGV4ZXMiLCJ1cGRhdGVTY2hlbWFXaXRoSW5kZXhlcyIsImNsYXNzZXMiLCJwcm9taXNlcyIsImNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uIiwidHJhbnNhY3Rpb25hbFNlY3Rpb24iLCJzdGFydFNlc3Npb24iLCJzdGFydFRyYW5zYWN0aW9uIiwiY29tbWl0VHJhbnNhY3Rpb25hbFNlc3Npb24iLCJjb21taXRUcmFuc2FjdGlvbiIsImVuZFNlc3Npb24iLCJhYm9ydFRyYW5zYWN0aW9uYWxTZXNzaW9uIiwiYWJvcnRUcmFuc2FjdGlvbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUNBOztBQUNBOztBQUNBOztBQUVBOztBQUNBOztBQVNBOztBQUVBOztBQUNBOztBQUNBOzs7Ozs7Ozs7Ozs7Ozs7O0FBRUE7QUFDQSxNQUFNQSxPQUFPLEdBQUdDLE9BQU8sQ0FBQyxTQUFELENBQXZCOztBQUNBLE1BQU1DLFdBQVcsR0FBR0YsT0FBTyxDQUFDRSxXQUE1QjtBQUNBLE1BQU1DLGNBQWMsR0FBR0gsT0FBTyxDQUFDRyxjQUEvQjtBQUVBLE1BQU1DLHlCQUF5QixHQUFHLFNBQWxDOztBQUVBLE1BQU1DLDRCQUE0QixHQUFHQyxZQUFZLElBQUk7QUFDbkQsU0FBT0EsWUFBWSxDQUNoQkMsT0FESSxHQUVKQyxJQUZJLENBRUMsTUFBTUYsWUFBWSxDQUFDRyxRQUFiLENBQXNCQyxXQUF0QixFQUZQLEVBR0pGLElBSEksQ0FHQ0UsV0FBVyxJQUFJO0FBQ25CLFdBQU9BLFdBQVcsQ0FBQ0MsTUFBWixDQUFtQkMsVUFBVSxJQUFJO0FBQ3RDLFVBQUlBLFVBQVUsQ0FBQ0MsU0FBWCxDQUFxQkMsS0FBckIsQ0FBMkIsWUFBM0IsQ0FBSixFQUE4QztBQUM1QyxlQUFPLEtBQVA7QUFDRCxPQUhxQyxDQUl0QztBQUNBOzs7QUFDQSxhQUFPRixVQUFVLENBQUNHLGNBQVgsQ0FBMEJDLE9BQTFCLENBQWtDVixZQUFZLENBQUNXLGlCQUEvQyxLQUFxRSxDQUE1RTtBQUNELEtBUE0sQ0FBUDtBQVFELEdBWkksQ0FBUDtBQWFELENBZEQ7O0FBZ0JBLE1BQU1DLCtCQUErQixHQUFHLFVBQW1CO0FBQUEsTUFBYkMsTUFBYTs7QUFDekQsU0FBT0EsTUFB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TCxNQUFMLENBQVk4TCxZQUFaLEVBQTdCO0FBQ0FELElBQUFBLG9CQUFvQixDQUFDRSxnQkFBckI7QUFDQSxXQUFPdkwsT0FBTyxDQUFDTyxPQUFSLENBQWdCOEssb0JBQWhCLENBQVA7QUFDRDs7QUFFREcsRUFBQUEsMEJBQTBCLENBQUNILG9CQUFELEVBQTJDO0FBQ25FLFdBQU9BLG9CQUFvQixDQUFDSSxpQkFBckIsR0FBeUN2UCxJQUF6QyxDQUE4QyxNQUFNO0FBQ3pEbVAsTUFBQUEsb0JBQW9CLENBQUNLLFVBQXJCO0FBQ0QsS0FGTSxDQUFQO0FBR0Q7O0FBRURDLEVBQUFBLHlCQUF5QixDQUFDTixvQkFBRCxFQUEyQztBQUNsRSxXQUFPQSxvQkFBb0IsQ0FBQ08sZ0JBQXJCLEdBQXdDMVAsSUFBeEMsQ0FBNkMsTUFBTTtBQUN4RG1QLE1BQUFBLG9CQUFvQixDQUFDSyxVQUFyQjtBQUNELEtBRk0sQ0FBUDtBQUdEOztBQW43QndEOzs7ZUFzN0I1Q2xOLG1CIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCBNb25nb0NvbGxlY3Rpb24gZnJvbSAnLi9Nb25nb0NvbGxlY3Rpb24nO1xuaW1wb3J0IE1vbmdvU2NoZW1hQ29sbGVjdGlvbiBmcm9tICcuL01vbmdvU2NoZW1hQ29sbGVjdGlvbic7XG5pbXBvcnQgeyBTdG9yYWdlQWRhcHRlciB9IGZyb20gJy4uL1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCB0eXBlIHsgU2NoZW1hVHlwZSwgUXVlcnlUeXBlLCBTdG9yYWdlQ2xhc3MsIFF1ZXJ5T3B0aW9ucyB9IGZyb20gJy4uL1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCB7IHBhcnNlIGFzIHBhcnNlVXJsLCBmb3JtYXQgYXMgZm9ybWF0VXJsIH0gZnJvbSAnLi4vLi4vLi4vdmVuZG9yL21vbmdvZGJVcmwnO1xuaW1wb3J0IHtcbiAgcGFyc2VPYmplY3RUb01vbmdvT2JqZWN0Rm9yQ3JlYXRlLFxuICBtb25nb09iamVjdFRvUGFyc2VPYmplY3QsXG4gIHRyYW5zZm9ybUtleSxcbiAgdHJhbnNmb3JtV2hlcmUsXG4gIHRyYW5zZm9ybVVwZGF0ZSxcbiAgdHJhbnNmb3JtUG9pbnRlclN0cmluZyxcbn0gZnJvbSAnLi9Nb25nb1RyYW5zZm9ybSc7XG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBkZWZhdWx0cyBmcm9tICcuLi8uLi8uLi9kZWZhdWx0cyc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uLy4uLy4uL2xvZ2dlcic7XG5cbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuY29uc3QgbW9uZ29kYiA9IHJlcXVpcmUoJ21vbmdvZGInKTtcbmNvbnN0IE1vbmdvQ2xpZW50ID0gbW9uZ29kYi5Nb25nb0NsaWVudDtcbmNvbnN0IFJlYWRQcmVmZXJlbmNlID0gbW9uZ29kYi5SZWFkUHJlZmVyZW5jZTtcblxuY29uc3QgTW9uZ29TY2hlbWFDb2xsZWN0aW9uTmFtZSA9ICdfU0NIRU1BJztcblxuY29uc3Qgc3RvcmFnZUFkYXB0ZXJBbGxDb2xsZWN0aW9ucyA9IG1vbmdvQWRhcHRlciA9PiB7XG4gIHJldHVybiBtb25nb0FkYXB0ZXJcbiAgICAuY29ubmVjdCgpXG4gICAgLnRoZW4oKCkgPT4gbW9uZ29BZGFwdGVyLmRhdGFiYXNlLmNvbGxlY3Rpb25zKCkpXG4gICAgLnRoZW4oY29sbGVjdGlvbnMgPT4ge1xuICAgICAgcmV0dXJuIGNvbGxlY3Rpb25zLmZpbHRlcihjb2xsZWN0aW9uID0+IHtcbiAgICAgICAgaWYgKGNvbGxlY3Rpb24ubmFtZXNwYWNlLm1hdGNoKC9cXC5zeXN0ZW1cXC4vKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBUT0RPOiBJZiB5b3UgaGF2ZSBvbmUgYXBwIHdpdGggYSBjb2xsZWN0aW9uIHByZWZpeCB0aGF0IGhhcHBlbnMgdG8gYmUgYSBwcmVmaXggb2YgYW5vdGhlclxuICAgICAgICAvLyBhcHBzIHByZWZpeCwgdGhpcyB3aWxsIGdvIHZlcnkgdmVyeSBiYWRseS4gV2Ugc2hvdWxkIGZpeCB0aGF0IHNvbWVob3cuXG4gICAgICAgIHJldHVybiBjb2xsZWN0aW9uLmNvbGxlY3Rpb25OYW1lLmluZGV4T2YobW9uZ29BZGFwdGVyLl9jb2xsZWN0aW9uUHJlZml4KSA9PSAwO1xuICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG5jb25zdCBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hID0gKHsgLi4uc2NoZW1hIH0pID0+IHtcbiAgZGVsZXRlIHNjaGVtYS5maWVsZHMuX3JwZXJtO1xuICBkZWxldGUgc2NoZW1hLmZpZWxkcy5fd3Blcm07XG5cbiAgaWYgKHNjaGVtYS5jbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICAvLyBMZWdhY3kgbW9uZ28gYWRhcHRlciBrbm93cyBhYm91dCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHBhc3N3b3JkIGFuZCBfaGFzaGVkX3Bhc3N3b3JkLlxuICAgIC8vIEZ1dHVyZSBkYXRhYmFzZSBhZGFwdGVycyB3aWxsIG9ubHkga25vdyBhYm91dCBfaGFzaGVkX3Bhc3N3b3JkLlxuICAgIC8vIE5vdGU6IFBhcnNlIFNlcnZlciB3aWxsIGJyaW5nIGJhY2sgcGFzc3dvcmQgd2l0aCBpbmplY3REZWZhdWx0U2NoZW1hLCBzbyB3ZSBkb24ndCBuZWVkXG4gICAgLy8gdG8gYWRkIF9oYXNoZWRfcGFzc3dvcmQgYmFjayBldmVyLlxuICAgIGRlbGV0ZSBzY2hlbWEuZmllbGRzLl9oYXNoZWRfcGFzc3dvcmQ7XG4gIH1cblxuICByZXR1cm4gc2NoZW1hO1xufTtcblxuLy8gUmV0dXJucyB7IGNvZGUsIGVycm9yIH0gaWYgaW52YWxpZCwgb3IgeyByZXN1bHQgfSwgYW4gb2JqZWN0XG4vLyBzdWl0YWJsZSBmb3IgaW5zZXJ0aW5nIGludG8gX1NDSEVNQSBjb2xsZWN0aW9uLCBvdGhlcndpc2UuXG5jb25zdCBtb25nb1NjaGVtYUZyb21GaWVsZHNBbmRDbGFzc05hbWVBbmRDTFAgPSAoXG4gIGZpZWxkcyxcbiAgY2xhc3NOYW1lLFxuICBjbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gIGluZGV4ZXNcbikgPT4ge1xuICBjb25zdCBtb25nb09iamVjdCA9IHtcbiAgICBfaWQ6IGNsYXNzTmFtZSxcbiAgICBvYmplY3RJZDogJ3N0cmluZycsXG4gICAgdXBkYXRlZEF0OiAnc3RyaW5nJyxcbiAgICBjcmVhdGVkQXQ6ICdzdHJpbmcnLFxuICAgIF9tZXRhZGF0YTogdW5kZWZpbmVkLFxuICB9O1xuXG4gIGZvciAoY29uc3QgZmllbGROYW1lIGluIGZpZWxkcykge1xuICAgIGNvbnN0IHsgdHlwZSwgdGFyZ2V0Q2xhc3MsIC4uLmZpZWxkT3B0aW9ucyB9ID0gZmllbGRzW2ZpZWxkTmFtZV07XG4gICAgbW9uZ29PYmplY3RbZmllbGROYW1lXSA9IE1vbmdvU2NoZW1hQ29sbGVjdGlvbi5wYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUoe1xuICAgICAgdHlwZSxcbiAgICAgIHRhcmdldENsYXNzLFxuICAgIH0pO1xuICAgIGlmIChmaWVsZE9wdGlvbnMgJiYgT2JqZWN0LmtleXMoZmllbGRPcHRpb25zKS5sZW5ndGggPiAwKSB7XG4gICAgICBtb25nb09iamVjdC5fbWV0YWRhdGEgPSBtb25nb09iamVjdC5fbWV0YWRhdGEgfHwge307XG4gICAgICBtb25nb09iamVjdC5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnMgPSBtb25nb09iamVjdC5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnMgfHwge307XG4gICAgICBtb25nb09iamVjdC5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnNbZmllbGROYW1lXSA9IGZpZWxkT3B0aW9ucztcbiAgICB9XG4gIH1cblxuICBpZiAodHlwZW9mIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBtb25nb09iamVjdC5fbWV0YWRhdGEgPSBtb25nb09iamVjdC5fbWV0YWRhdGEgfHwge307XG4gICAgaWYgKCFjbGFzc0xldmVsUGVybWlzc2lvbnMpIHtcbiAgICAgIGRlbGV0ZSBtb25nb09iamVjdC5fbWV0YWRhdGEuY2xhc3NfcGVybWlzc2lvbnM7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1vbmdvT2JqZWN0Ll9tZXRhZGF0YS5jbGFzc19wZXJtaXNzaW9ucyA9IGNsYXNzTGV2ZWxQZXJtaXNzaW9ucztcbiAgICB9XG4gIH1cblxuICBpZiAoaW5kZXhlcyAmJiB0eXBlb2YgaW5kZXhlcyA9PT0gJ29iamVjdCcgJiYgT2JqZWN0LmtleXMoaW5kZXhlcykubGVuZ3RoID4gMCkge1xuICAgIG1vbmdvT2JqZWN0Ll9tZXRhZGF0YSA9IG1vbmdvT2JqZWN0Ll9tZXRhZGF0YSB8fCB7fTtcbiAgICBtb25nb09iamVjdC5fbWV0YWRhdGEuaW5kZXhlcyA9IGluZGV4ZXM7XG4gIH1cblxuICBpZiAoIW1vbmdvT2JqZWN0Ll9tZXRhZGF0YSkge1xuICAgIC8vIGNsZWFudXAgdGhlIHVudXNlZCBfbWV0YWRhdGFcbiAgICBkZWxldGUgbW9uZ29PYmplY3QuX21ldGFkYXRhO1xuICB9XG5cbiAgcmV0dXJuIG1vbmdvT2JqZWN0O1xufTtcblxuZXhwb3J0IGNsYXNzIE1vbmdvU3RvcmFnZUFkYXB0ZXIgaW1wbGVtZW50cyBTdG9yYWdlQWRhcHRlciB7XG4gIC8vIFByaXZhdGVcbiAgX3VyaTogc3RyaW5nO1xuICBfY29sbGVjdGlvblByZWZpeDogc3RyaW5nO1xuICBfbW9uZ29PcHRpb25zOiBPYmplY3Q7XG4gIC8vIFB1YmxpY1xuICBjb25uZWN0aW9uUHJvbWlzZTogP1Byb21pc2U8YW55PjtcbiAgZGF0YWJhc2U6IGFueTtcbiAgY2xpZW50OiBNb25nb0NsaWVudDtcbiAgX21heFRpbWVNUzogP251bWJlcjtcbiAgY2FuU29ydE9uSm9pblRhYmxlczogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3Rvcih7IHVyaSA9IGRlZmF1bHRzLkRlZmF1bHRNb25nb1VSSSwgY29sbGVjdGlvblByZWZpeCA9ICcnLCBtb25nb09wdGlvbnMgPSB7fSB9OiBhbnkpIHtcbiAgICB0aGlzLl91cmkgPSB1cmk7XG4gICAgdGhpcy5fY29sbGVjdGlvblByZWZpeCA9IGNvbGxlY3Rpb25QcmVmaXg7XG4gICAgdGhpcy5fbW9uZ29PcHRpb25zID0gbW9uZ29PcHRpb25zO1xuICAgIHRoaXMuX21vbmdvT3B0aW9ucy51c2VOZXdVcmxQYXJzZXIgPSB0cnVlO1xuICAgIHRoaXMuX21vbmdvT3B0aW9ucy51c2VVbmlmaWVkVG9wb2xvZ3kgPSB0cnVlO1xuXG4gICAgLy8gTWF4VGltZU1TIGlzIG5vdCBhIGdsb2JhbCBNb25nb0RCIGNsaWVudCBvcHRpb24sIGl0IGlzIGFwcGxpZWQgcGVyIG9wZXJhdGlvbi5cbiAgICB0aGlzLl9tYXhUaW1lTVMgPSBtb25nb09wdGlvbnMubWF4VGltZU1TO1xuICAgIHRoaXMuY2FuU29ydE9uSm9pblRhYmxlcyA9IHRydWU7XG4gICAgZGVsZXRlIG1vbmdvT3B0aW9ucy5tYXhUaW1lTVM7XG4gIH1cblxuICBjb25uZWN0KCkge1xuICAgIGlmICh0aGlzLmNvbm5lY3Rpb25Qcm9taXNlKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9uUHJvbWlzZTtcbiAgICB9XG5cbiAgICAvLyBwYXJzaW5nIGFuZCByZS1mb3JtYXR0aW5nIGNhdXNlcyB0aGUgYXV0aCB2YWx1ZSAoaWYgdGhlcmUpIHRvIGdldCBVUklcbiAgICAvLyBlbmNvZGVkXG4gICAgY29uc3QgZW5jb2RlZFVyaSA9IGZvcm1hdFVybChwYXJzZVVybCh0aGlzLl91cmkpKTtcblxuICAgIHRoaXMuY29ubmVjdGlvblByb21pc2UgPSBNb25nb0NsaWVudC5jb25uZWN0KGVuY29kZWRVcmksIHRoaXMuX21vbmdvT3B0aW9ucylcbiAgICAgIC50aGVuKGNsaWVudCA9PiB7XG4gICAgICAgIC8vIFN0YXJ0aW5nIG1vbmdvREIgMy4wLCB0aGUgTW9uZ29DbGllbnQuY29ubmVjdCBkb24ndCByZXR1cm4gYSBEQiBhbnltb3JlIGJ1dCBhIGNsaWVudFxuICAgICAgICAvLyBGb3J0dW5hdGVseSwgd2UgY2FuIGdldCBiYWNrIHRoZSBvcHRpb25zIGFuZCB1c2UgdGhlbSB0byBzZWxlY3QgdGhlIHByb3BlciBEQi5cbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21vbmdvZGIvbm9kZS1tb25nb2RiLW5hdGl2ZS9ibG9iLzJjMzVkNzZmMDg1NzQyMjViOGRiMDJkN2JlZjY4NzEyM2U2YmIwMTgvbGliL21vbmdvX2NsaWVudC5qcyNMODg1XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBjbGllbnQucy5vcHRpb25zO1xuICAgICAgICBjb25zdCBkYXRhYmFzZSA9IGNsaWVudC5kYihvcHRpb25zLmRiTmFtZSk7XG4gICAgICAgIGlmICghZGF0YWJhc2UpIHtcbiAgICAgICAgICBkZWxldGUgdGhpcy5jb25uZWN0aW9uUHJvbWlzZTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgZGF0YWJhc2Uub24oJ2Vycm9yJywgKCkgPT4ge1xuICAgICAgICAgIGRlbGV0ZSB0aGlzLmNvbm5lY3Rpb25Qcm9taXNlO1xuICAgICAgICB9KTtcbiAgICAgICAgZGF0YWJhc2Uub24oJ2Nsb3NlJywgKCkgPT4ge1xuICAgICAgICAgIGRlbGV0ZSB0aGlzLmNvbm5lY3Rpb25Qcm9taXNlO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5jbGllbnQgPSBjbGllbnQ7XG4gICAgICAgIHRoaXMuZGF0YWJhc2UgPSBkYXRhYmFzZTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgZGVsZXRlIHRoaXMuY29ubmVjdGlvblByb21pc2U7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnIpO1xuICAgICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9uUHJvbWlzZTtcbiAgfVxuXG4gIGhhbmRsZUVycm9yPFQ+KGVycm9yOiA/KEVycm9yIHwgUGFyc2UuRXJyb3IpKTogUHJvbWlzZTxUPiB7XG4gICAgaWYgKGVycm9yICYmIGVycm9yLmNvZGUgPT09IDEzKSB7XG4gICAgICAvLyBVbmF1dGhvcml6ZWQgZXJyb3JcbiAgICAgIGRlbGV0ZSB0aGlzLmNsaWVudDtcbiAgICAgIGRlbGV0ZSB0aGlzLmRhdGFiYXNlO1xuICAgICAgZGVsZXRlIHRoaXMuY29ubmVjdGlvblByb21pc2U7XG4gICAgICBsb2dnZXIuZXJyb3IoJ1JlY2VpdmVkIHVuYXV0aG9yaXplZCBlcnJvcicsIHsgZXJyb3I6IGVycm9yIH0pO1xuICAgIH1cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuXG4gIGhhbmRsZVNodXRkb3duKCkge1xuICAgIGlmICghdGhpcy5jbGllbnQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY2xpZW50LmNsb3NlKGZhbHNlKTtcbiAgfVxuXG4gIF9hZGFwdGl2ZUNvbGxlY3Rpb24obmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdCgpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLmRhdGFiYXNlLmNvbGxlY3Rpb24odGhpcy5fY29sbGVjdGlvblByZWZpeCArIG5hbWUpKVxuICAgICAgLnRoZW4ocmF3Q29sbGVjdGlvbiA9PiBuZXcgTW9uZ29Db2xsZWN0aW9uKHJhd0NvbGxlY3Rpb24pKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgX3NjaGVtYUNvbGxlY3Rpb24oKTogUHJvbWlzZTxNb25nb1NjaGVtYUNvbGxlY3Rpb24+IHtcbiAgICByZXR1cm4gdGhpcy5jb25uZWN0KClcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihNb25nb1NjaGVtYUNvbGxlY3Rpb25OYW1lKSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gbmV3IE1vbmdvU2NoZW1hQ29sbGVjdGlvbihjb2xsZWN0aW9uKSk7XG4gIH1cblxuICBjbGFzc0V4aXN0cyhuYW1lOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5jb25uZWN0KClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YWJhc2UubGlzdENvbGxlY3Rpb25zKHsgbmFtZTogdGhpcy5fY29sbGVjdGlvblByZWZpeCArIG5hbWUgfSkudG9BcnJheSgpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb25zID0+IHtcbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25zLmxlbmd0aCA+IDA7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgc2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zKGNsYXNzTmFtZTogc3RyaW5nLCBDTFBzOiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpXG4gICAgICAudGhlbihzY2hlbWFDb2xsZWN0aW9uID0+XG4gICAgICAgIHNjaGVtYUNvbGxlY3Rpb24udXBkYXRlU2NoZW1hKGNsYXNzTmFtZSwge1xuICAgICAgICAgICRzZXQ6IHsgJ19tZXRhZGF0YS5jbGFzc19wZXJtaXNzaW9ucyc6IENMUHMgfSxcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIHNldEluZGV4ZXNXaXRoU2NoZW1hRm9ybWF0KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHN1Ym1pdHRlZEluZGV4ZXM6IGFueSxcbiAgICBleGlzdGluZ0luZGV4ZXM6IGFueSA9IHt9LFxuICAgIGZpZWxkczogYW55XG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmIChzdWJtaXR0ZWRJbmRleGVzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgaWYgKE9iamVjdC5rZXlzKGV4aXN0aW5nSW5kZXhlcykubGVuZ3RoID09PSAwKSB7XG4gICAgICBleGlzdGluZ0luZGV4ZXMgPSB7IF9pZF86IHsgX2lkOiAxIH0gfTtcbiAgICB9XG4gICAgY29uc3QgZGVsZXRlUHJvbWlzZXMgPSBbXTtcbiAgICBjb25zdCBpbnNlcnRlZEluZGV4ZXMgPSBbXTtcbiAgICBPYmplY3Qua2V5cyhzdWJtaXR0ZWRJbmRleGVzKS5mb3JFYWNoKG5hbWUgPT4ge1xuICAgICAgY29uc3QgZmllbGQgPSBzdWJtaXR0ZWRJbmRleGVzW25hbWVdO1xuICAgICAgaWYgKGV4aXN0aW5nSW5kZXhlc1tuYW1lXSAmJiBmaWVsZC5fX29wICE9PSAnRGVsZXRlJykge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSwgYEluZGV4ICR7bmFtZX0gZXhpc3RzLCBjYW5ub3QgdXBkYXRlLmApO1xuICAgICAgfVxuICAgICAgaWYgKCFleGlzdGluZ0luZGV4ZXNbbmFtZV0gJiYgZmllbGQuX19vcCA9PT0gJ0RlbGV0ZScpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksXG4gICAgICAgICAgYEluZGV4ICR7bmFtZX0gZG9lcyBub3QgZXhpc3QsIGNhbm5vdCBkZWxldGUuYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKGZpZWxkLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLmRyb3BJbmRleChjbGFzc05hbWUsIG5hbWUpO1xuICAgICAgICBkZWxldGVQcm9taXNlcy5wdXNoKHByb21pc2UpO1xuICAgICAgICBkZWxldGUgZXhpc3RpbmdJbmRleGVzW25hbWVdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgT2JqZWN0LmtleXMoZmllbGQpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKFxuICAgICAgICAgICAgICBmaWVsZHMsXG4gICAgICAgICAgICAgIGtleS5pbmRleE9mKCdfcF8nKSA9PT0gMCA/IGtleS5yZXBsYWNlKCdfcF8nLCAnJykgOiBrZXlcbiAgICAgICAgICAgIClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSxcbiAgICAgICAgICAgICAgYEZpZWxkICR7a2V5fSBkb2VzIG5vdCBleGlzdCwgY2Fubm90IGFkZCBpbmRleC5gXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGV4aXN0aW5nSW5kZXhlc1tuYW1lXSA9IGZpZWxkO1xuICAgICAgICBpbnNlcnRlZEluZGV4ZXMucHVzaCh7XG4gICAgICAgICAga2V5OiBmaWVsZCxcbiAgICAgICAgICBuYW1lLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBsZXQgaW5zZXJ0UHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIGlmIChpbnNlcnRlZEluZGV4ZXMubGVuZ3RoID4gMCkge1xuICAgICAgaW5zZXJ0UHJvbWlzZSA9IHRoaXMuY3JlYXRlSW5kZXhlcyhjbGFzc05hbWUsIGluc2VydGVkSW5kZXhlcyk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLmFsbChkZWxldGVQcm9taXNlcylcbiAgICAgIC50aGVuKCgpID0+IGluc2VydFByb21pc2UpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKCkpXG4gICAgICAudGhlbihzY2hlbWFDb2xsZWN0aW9uID0+XG4gICAgICAgIHNjaGVtYUNvbGxlY3Rpb24udXBkYXRlU2NoZW1hKGNsYXNzTmFtZSwge1xuICAgICAgICAgICRzZXQ6IHsgJ19tZXRhZGF0YS5pbmRleGVzJzogZXhpc3RpbmdJbmRleGVzIH0sXG4gICAgICAgIH0pXG4gICAgICApXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBzZXRJbmRleGVzRnJvbU1vbmdvKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0SW5kZXhlcyhjbGFzc05hbWUpXG4gICAgICAudGhlbihpbmRleGVzID0+IHtcbiAgICAgICAgaW5kZXhlcyA9IGluZGV4ZXMucmVkdWNlKChvYmosIGluZGV4KSA9PiB7XG4gICAgICAgICAgaWYgKGluZGV4LmtleS5fZnRzKSB7XG4gICAgICAgICAgICBkZWxldGUgaW5kZXgua2V5Ll9mdHM7XG4gICAgICAgICAgICBkZWxldGUgaW5kZXgua2V5Ll9mdHN4O1xuICAgICAgICAgICAgZm9yIChjb25zdCBmaWVsZCBpbiBpbmRleC53ZWlnaHRzKSB7XG4gICAgICAgICAgICAgIGluZGV4LmtleVtmaWVsZF0gPSAndGV4dCc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIG9ialtpbmRleC5uYW1lXSA9IGluZGV4LmtleTtcbiAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICB9LCB7fSk7XG4gICAgICAgIHJldHVybiB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKCkudGhlbihzY2hlbWFDb2xsZWN0aW9uID0+XG4gICAgICAgICAgc2NoZW1hQ29sbGVjdGlvbi51cGRhdGVTY2hlbWEoY2xhc3NOYW1lLCB7XG4gICAgICAgICAgICAkc2V0OiB7ICdfbWV0YWRhdGEuaW5kZXhlcyc6IGluZGV4ZXMgfSxcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKVxuICAgICAgLmNhdGNoKCgpID0+IHtcbiAgICAgICAgLy8gSWdub3JlIGlmIGNvbGxlY3Rpb24gbm90IGZvdW5kXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgY3JlYXRlQ2xhc3MoY2xhc3NOYW1lOiBzdHJpbmcsIHNjaGVtYTogU2NoZW1hVHlwZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb09iamVjdCA9IG1vbmdvU2NoZW1hRnJvbUZpZWxkc0FuZENsYXNzTmFtZUFuZENMUChcbiAgICAgIHNjaGVtYS5maWVsZHMsXG4gICAgICBjbGFzc05hbWUsXG4gICAgICBzY2hlbWEuY2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICAgICAgc2NoZW1hLmluZGV4ZXNcbiAgICApO1xuICAgIG1vbmdvT2JqZWN0Ll9pZCA9IGNsYXNzTmFtZTtcbiAgICByZXR1cm4gdGhpcy5zZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdChjbGFzc05hbWUsIHNjaGVtYS5pbmRleGVzLCB7fSwgc2NoZW1hLmZpZWxkcylcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuX3NjaGVtYUNvbGxlY3Rpb24oKSlcbiAgICAgIC50aGVuKHNjaGVtYUNvbGxlY3Rpb24gPT4gc2NoZW1hQ29sbGVjdGlvbi5pbnNlcnRTY2hlbWEobW9uZ29PYmplY3QpKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgYWRkRmllbGRJZk5vdEV4aXN0cyhjbGFzc05hbWU6IHN0cmluZywgZmllbGROYW1lOiBzdHJpbmcsIHR5cGU6IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKClcbiAgICAgIC50aGVuKHNjaGVtYUNvbGxlY3Rpb24gPT4gc2NoZW1hQ29sbGVjdGlvbi5hZGRGaWVsZElmTm90RXhpc3RzKGNsYXNzTmFtZSwgZmllbGROYW1lLCB0eXBlKSlcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuY3JlYXRlSW5kZXhlc0lmTmVlZGVkKGNsYXNzTmFtZSwgZmllbGROYW1lLCB0eXBlKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIERyb3BzIGEgY29sbGVjdGlvbi4gUmVzb2x2ZXMgd2l0aCB0cnVlIGlmIGl0IHdhcyBhIFBhcnNlIFNjaGVtYSAoZWcuIF9Vc2VyLCBDdXN0b20sIGV0Yy4pXG4gIC8vIGFuZCByZXNvbHZlcyB3aXRoIGZhbHNlIGlmIGl0IHdhc24ndCAoZWcuIGEgam9pbiB0YWJsZSkuIFJlamVjdHMgaWYgZGVsZXRpb24gd2FzIGltcG9zc2libGUuXG4gIGRlbGV0ZUNsYXNzKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5kcm9wKCkpXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgLy8gJ25zIG5vdCBmb3VuZCcgbWVhbnMgY29sbGVjdGlvbiB3YXMgYWxyZWFkeSBnb25lLiBJZ25vcmUgZGVsZXRpb24gYXR0ZW1wdC5cbiAgICAgICAgICBpZiAoZXJyb3IubWVzc2FnZSA9PSAnbnMgbm90IGZvdW5kJykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfSlcbiAgICAgICAgLy8gV2UndmUgZHJvcHBlZCB0aGUgY29sbGVjdGlvbiwgbm93IHJlbW92ZSB0aGUgX1NDSEVNQSBkb2N1bWVudFxuICAgICAgICAudGhlbigoKSA9PiB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKCkpXG4gICAgICAgIC50aGVuKHNjaGVtYUNvbGxlY3Rpb24gPT4gc2NoZW1hQ29sbGVjdGlvbi5maW5kQW5kRGVsZXRlU2NoZW1hKGNsYXNzTmFtZSkpXG4gICAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKVxuICAgICk7XG4gIH1cblxuICBkZWxldGVBbGxDbGFzc2VzKGZhc3Q6IGJvb2xlYW4pIHtcbiAgICByZXR1cm4gc3RvcmFnZUFkYXB0ZXJBbGxDb2xsZWN0aW9ucyh0aGlzKS50aGVuKGNvbGxlY3Rpb25zID0+XG4gICAgICBQcm9taXNlLmFsbChcbiAgICAgICAgY29sbGVjdGlvbnMubWFwKGNvbGxlY3Rpb24gPT4gKGZhc3QgPyBjb2xsZWN0aW9uLmRlbGV0ZU1hbnkoe30pIDogY29sbGVjdGlvbi5kcm9wKCkpKVxuICAgICAgKVxuICAgICk7XG4gIH1cblxuICAvLyBSZW1vdmUgdGhlIGNvbHVtbiBhbmQgYWxsIHRoZSBkYXRhLiBGb3IgUmVsYXRpb25zLCB0aGUgX0pvaW4gY29sbGVjdGlvbiBpcyBoYW5kbGVkXG4gIC8vIHNwZWNpYWxseSwgdGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBkZWxldGUgX0pvaW4gY29sdW1ucy4gSXQgc2hvdWxkLCBob3dldmVyLCBpbmRpY2F0ZVxuICAvLyB0aGF0IHRoZSByZWxhdGlvbiBmaWVsZHMgZG9lcyBub3QgZXhpc3QgYW55bW9yZS4gSW4gbW9uZ28sIHRoaXMgbWVhbnMgcmVtb3ZpbmcgaXQgZnJvbVxuICAvLyB0aGUgX1NDSEVNQSBjb2xsZWN0aW9uLiAgVGhlcmUgc2hvdWxkIGJlIG5vIGFjdHVhbCBkYXRhIGluIHRoZSBjb2xsZWN0aW9uIHVuZGVyIHRoZSBzYW1lIG5hbWVcbiAgLy8gYXMgdGhlIHJlbGF0aW9uIGNvbHVtbiwgc28gaXQncyBmaW5lIHRvIGF0dGVtcHQgdG8gZGVsZXRlIGl0LiBJZiB0aGUgZmllbGRzIGxpc3RlZCB0byBiZVxuICAvLyBkZWxldGVkIGRvIG5vdCBleGlzdCwgdGhpcyBmdW5jdGlvbiBzaG91bGQgcmV0dXJuIHN1Y2Nlc3NmdWxseSBhbnl3YXlzLiBDaGVja2luZyBmb3JcbiAgLy8gYXR0ZW1wdHMgdG8gZGVsZXRlIG5vbi1leGlzdGVudCBmaWVsZHMgaXMgdGhlIHJlc3BvbnNpYmlsaXR5IG9mIFBhcnNlIFNlcnZlci5cblxuICAvLyBQb2ludGVyIGZpZWxkIG5hbWVzIGFyZSBwYXNzZWQgZm9yIGxlZ2FjeSByZWFzb25zOiB0aGUgb3JpZ2luYWwgbW9uZ29cbiAgLy8gZm9ybWF0IHN0b3JlZCBwb2ludGVyIGZpZWxkIG5hbWVzIGRpZmZlcmVudGx5IGluIHRoZSBkYXRhYmFzZSwgYW5kIHRoZXJlZm9yZVxuICAvLyBuZWVkZWQgdG8ga25vdyB0aGUgdHlwZSBvZiB0aGUgZmllbGQgYmVmb3JlIGl0IGNvdWxkIGRlbGV0ZSBpdC4gRnV0dXJlIGRhdGFiYXNlXG4gIC8vIGFkYXB0ZXJzIHNob3VsZCBpZ25vcmUgdGhlIHBvaW50ZXJGaWVsZE5hbWVzIGFyZ3VtZW50LiBBbGwgdGhlIGZpZWxkIG5hbWVzIGFyZSBpblxuICAvLyBmaWVsZE5hbWVzLCB0aGV5IHNob3cgdXAgYWRkaXRpb25hbGx5IGluIHRoZSBwb2ludGVyRmllbGROYW1lcyBkYXRhYmFzZSBmb3IgdXNlXG4gIC8vIGJ5IHRoZSBtb25nbyBhZGFwdGVyLCB3aGljaCBkZWFscyB3aXRoIHRoZSBsZWdhY3kgbW9uZ28gZm9ybWF0LlxuXG4gIC8vIFRoaXMgZnVuY3Rpb24gaXMgbm90IG9ibGlnYXRlZCB0byBkZWxldGUgZmllbGRzIGF0b21pY2FsbHkuIEl0IGlzIGdpdmVuIHRoZSBmaWVsZFxuICAvLyBuYW1lcyBpbiBhIGxpc3Qgc28gdGhhdCBkYXRhYmFzZXMgdGhhdCBhcmUgY2FwYWJsZSBvZiBkZWxldGluZyBmaWVsZHMgYXRvbWljYWxseVxuICAvLyBtYXkgZG8gc28uXG5cbiAgLy8gUmV0dXJucyBhIFByb21pc2UuXG4gIGRlbGV0ZUZpZWxkcyhjbGFzc05hbWU6IHN0cmluZywgc2NoZW1hOiBTY2hlbWFUeXBlLCBmaWVsZE5hbWVzOiBzdHJpbmdbXSkge1xuICAgIGNvbnN0IG1vbmdvRm9ybWF0TmFtZXMgPSBmaWVsZE5hbWVzLm1hcChmaWVsZE5hbWUgPT4ge1xuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgICAgcmV0dXJuIGBfcF8ke2ZpZWxkTmFtZX1gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZpZWxkTmFtZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBjb2xsZWN0aW9uVXBkYXRlID0geyAkdW5zZXQ6IHt9IH07XG4gICAgbW9uZ29Gb3JtYXROYW1lcy5mb3JFYWNoKG5hbWUgPT4ge1xuICAgICAgY29sbGVjdGlvblVwZGF0ZVsnJHVuc2V0J11bbmFtZV0gPSBudWxsO1xuICAgIH0pO1xuXG4gICAgY29uc3QgY29sbGVjdGlvbkZpbHRlciA9IHsgJG9yOiBbXSB9O1xuICAgIG1vbmdvRm9ybWF0TmFtZXMuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgIGNvbGxlY3Rpb25GaWx0ZXJbJyRvciddLnB1c2goeyBbbmFtZV06IHsgJGV4aXN0czogdHJ1ZSB9IH0pO1xuICAgIH0pO1xuXG4gICAgY29uc3Qgc2NoZW1hVXBkYXRlID0geyAkdW5zZXQ6IHt9IH07XG4gICAgZmllbGROYW1lcy5mb3JFYWNoKG5hbWUgPT4ge1xuICAgICAgc2NoZW1hVXBkYXRlWyckdW5zZXQnXVtuYW1lXSA9IG51bGw7XG4gICAgICBzY2hlbWFVcGRhdGVbJyR1bnNldCddW2BfbWV0YWRhdGEuZmllbGRzX29wdGlvbnMuJHtuYW1lfWBdID0gbnVsbDtcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLnVwZGF0ZU1hbnkoY29sbGVjdGlvbkZpbHRlciwgY29sbGVjdGlvblVwZGF0ZSkpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKCkpXG4gICAgICAudGhlbihzY2hlbWFDb2xsZWN0aW9uID0+IHNjaGVtYUNvbGxlY3Rpb24udXBkYXRlU2NoZW1hKGNsYXNzTmFtZSwgc2NoZW1hVXBkYXRlKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIFJldHVybiBhIHByb21pc2UgZm9yIGFsbCBzY2hlbWFzIGtub3duIHRvIHRoaXMgYWRhcHRlciwgaW4gUGFyc2UgZm9ybWF0LiBJbiBjYXNlIHRoZVxuICAvLyBzY2hlbWFzIGNhbm5vdCBiZSByZXRyaWV2ZWQsIHJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVqZWN0cy4gUmVxdWlyZW1lbnRzIGZvciB0aGVcbiAgLy8gcmVqZWN0aW9uIHJlYXNvbiBhcmUgVEJELlxuICBnZXRBbGxDbGFzc2VzKCk6IFByb21pc2U8U3RvcmFnZUNsYXNzW10+IHtcbiAgICByZXR1cm4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpXG4gICAgICAudGhlbihzY2hlbWFzQ29sbGVjdGlvbiA9PiBzY2hlbWFzQ29sbGVjdGlvbi5fZmV0Y2hBbGxTY2hlbWFzRnJvbV9TQ0hFTUEoKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIFJldHVybiBhIHByb21pc2UgZm9yIHRoZSBzY2hlbWEgd2l0aCB0aGUgZ2l2ZW4gbmFtZSwgaW4gUGFyc2UgZm9ybWF0LiBJZlxuICAvLyB0aGlzIGFkYXB0ZXIgZG9lc24ndCBrbm93IGFib3V0IHRoZSBzY2hlbWEsIHJldHVybiBhIHByb21pc2UgdGhhdCByZWplY3RzIHdpdGhcbiAgLy8gdW5kZWZpbmVkIGFzIHRoZSByZWFzb24uXG4gIGdldENsYXNzKGNsYXNzTmFtZTogc3RyaW5nKTogUHJvbWlzZTxTdG9yYWdlQ2xhc3M+IHtcbiAgICByZXR1cm4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpXG4gICAgICAudGhlbihzY2hlbWFzQ29sbGVjdGlvbiA9PiBzY2hlbWFzQ29sbGVjdGlvbi5fZmV0Y2hPbmVTY2hlbWFGcm9tX1NDSEVNQShjbGFzc05hbWUpKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gVE9ETzogQXMgeWV0IG5vdCBwYXJ0aWN1bGFybHkgd2VsbCBzcGVjaWZpZWQuIENyZWF0ZXMgYW4gb2JqZWN0LiBNYXliZSBzaG91bGRuJ3QgZXZlbiBuZWVkIHRoZSBzY2hlbWEsXG4gIC8vIGFuZCBzaG91bGQgaW5mZXIgZnJvbSB0aGUgdHlwZS4gT3IgbWF5YmUgZG9lcyBuZWVkIHRoZSBzY2hlbWEgZm9yIHZhbGlkYXRpb25zLiBPciBtYXliZSBuZWVkc1xuICAvLyB0aGUgc2NoZW1hIG9ubHkgZm9yIHRoZSBsZWdhY3kgbW9uZ28gZm9ybWF0LiBXZSdsbCBmaWd1cmUgdGhhdCBvdXQgbGF0ZXIuXG4gIGNyZWF0ZU9iamVjdChjbGFzc05hbWU6IHN0cmluZywgc2NoZW1hOiBTY2hlbWFUeXBlLCBvYmplY3Q6IGFueSwgdHJhbnNhY3Rpb25hbFNlc3Npb246ID9hbnkpIHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29PYmplY3QgPSBwYXJzZU9iamVjdFRvTW9uZ29PYmplY3RGb3JDcmVhdGUoY2xhc3NOYW1lLCBvYmplY3QsIHNjaGVtYSk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24uaW5zZXJ0T25lKG1vbmdvT2JqZWN0LCB0cmFuc2FjdGlvbmFsU2Vzc2lvbikpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gMTEwMDApIHtcbiAgICAgICAgICAvLyBEdXBsaWNhdGUgdmFsdWVcbiAgICAgICAgICBjb25zdCBlcnIgPSBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUsXG4gICAgICAgICAgICAnQSBkdXBsaWNhdGUgdmFsdWUgZm9yIGEgZmllbGQgd2l0aCB1bmlxdWUgdmFsdWVzIHdhcyBwcm92aWRlZCdcbiAgICAgICAgICApO1xuICAgICAgICAgIGVyci51bmRlcmx5aW5nRXJyb3IgPSBlcnJvcjtcbiAgICAgICAgICBpZiAoZXJyb3IubWVzc2FnZSkge1xuICAgICAgICAgICAgY29uc3QgbWF0Y2hlcyA9IGVycm9yLm1lc3NhZ2UubWF0Y2goL2luZGV4OltcXHNhLXpBLVowLTlfXFwtXFwuXStcXCQ/KFthLXpBLVpfLV0rKV8xLyk7XG4gICAgICAgICAgICBpZiAobWF0Y2hlcyAmJiBBcnJheS5pc0FycmF5KG1hdGNoZXMpKSB7XG4gICAgICAgICAgICAgIGVyci51c2VySW5mbyA9IHsgZHVwbGljYXRlZF9maWVsZDogbWF0Y2hlc1sxXSB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gUmVtb3ZlIGFsbCBvYmplY3RzIHRoYXQgbWF0Y2ggdGhlIGdpdmVuIFBhcnNlIFF1ZXJ5LlxuICAvLyBJZiBubyBvYmplY3RzIG1hdGNoLCByZWplY3Qgd2l0aCBPQkpFQ1RfTk9UX0ZPVU5ELiBJZiBvYmplY3RzIGFyZSBmb3VuZCBhbmQgZGVsZXRlZCwgcmVzb2x2ZSB3aXRoIHVuZGVmaW5lZC5cbiAgLy8gSWYgdGhlcmUgaXMgc29tZSBvdGhlciBlcnJvciwgcmVqZWN0IHdpdGggSU5URVJOQUxfU0VSVkVSX0VSUk9SLlxuICBkZWxldGVPYmplY3RzQnlRdWVyeShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbjogP2FueVxuICApIHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IHtcbiAgICAgICAgY29uc3QgbW9uZ29XaGVyZSA9IHRyYW5zZm9ybVdoZXJlKGNsYXNzTmFtZSwgcXVlcnksIHNjaGVtYSk7XG4gICAgICAgIHJldHVybiBjb2xsZWN0aW9uLmRlbGV0ZU1hbnkobW9uZ29XaGVyZSwgdHJhbnNhY3Rpb25hbFNlc3Npb24pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKVxuICAgICAgLnRoZW4oXG4gICAgICAgICh7IHJlc3VsdCB9KSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3VsdC5uID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ09iamVjdCBub3QgZm91bmQuJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfSxcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsICdEYXRhYmFzZSBhZGFwdGVyIGVycm9yJyk7XG4gICAgICAgIH1cbiAgICAgICk7XG4gIH1cblxuICAvLyBBcHBseSB0aGUgdXBkYXRlIHRvIGFsbCBvYmplY3RzIHRoYXQgbWF0Y2ggdGhlIGdpdmVuIFBhcnNlIFF1ZXJ5LlxuICB1cGRhdGVPYmplY3RzQnlRdWVyeShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICB1cGRhdGU6IGFueSxcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbjogP2FueVxuICApIHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29VcGRhdGUgPSB0cmFuc2Zvcm1VcGRhdGUoY2xhc3NOYW1lLCB1cGRhdGUsIHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29XaGVyZSA9IHRyYW5zZm9ybVdoZXJlKGNsYXNzTmFtZSwgcXVlcnksIHNjaGVtYSk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24udXBkYXRlTWFueShtb25nb1doZXJlLCBtb25nb1VwZGF0ZSwgdHJhbnNhY3Rpb25hbFNlc3Npb24pKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gQXRvbWljYWxseSBmaW5kcyBhbmQgdXBkYXRlcyBhbiBvYmplY3QgYmFzZWQgb24gcXVlcnkuXG4gIC8vIFJldHVybiB2YWx1ZSBub3QgY3VycmVudGx5IHdlbGwgc3BlY2lmaWVkLlxuICBmaW5kT25lQW5kVXBkYXRlKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHVwZGF0ZTogYW55LFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb1VwZGF0ZSA9IHRyYW5zZm9ybVVwZGF0ZShjbGFzc05hbWUsIHVwZGF0ZSwgc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb1doZXJlID0gdHJhbnNmb3JtV2hlcmUoY2xhc3NOYW1lLCBxdWVyeSwgc2NoZW1hKTtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT5cbiAgICAgICAgY29sbGVjdGlvbi5fbW9uZ29Db2xsZWN0aW9uLmZpbmRPbmVBbmRVcGRhdGUobW9uZ29XaGVyZSwgbW9uZ29VcGRhdGUsIHtcbiAgICAgICAgICByZXR1cm5PcmlnaW5hbDogZmFsc2UsXG4gICAgICAgICAgc2Vzc2lvbjogdHJhbnNhY3Rpb25hbFNlc3Npb24gfHwgdW5kZWZpbmVkLFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzdWx0ID0+IG1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdChjbGFzc05hbWUsIHJlc3VsdC52YWx1ZSwgc2NoZW1hKSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvci5jb2RlID09PSAxMTAwMCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLkRVUExJQ0FURV9WQUxVRSxcbiAgICAgICAgICAgICdBIGR1cGxpY2F0ZSB2YWx1ZSBmb3IgYSBmaWVsZCB3aXRoIHVuaXF1ZSB2YWx1ZXMgd2FzIHByb3ZpZGVkJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gSG9wZWZ1bGx5IHdlIGNhbiBnZXQgcmlkIG9mIHRoaXMuIEl0J3Mgb25seSB1c2VkIGZvciBjb25maWcgYW5kIGhvb2tzLlxuICB1cHNlcnRPbmVPYmplY3QoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIHF1ZXJ5OiBRdWVyeVR5cGUsXG4gICAgdXBkYXRlOiBhbnksXG4gICAgdHJhbnNhY3Rpb25hbFNlc3Npb246ID9hbnlcbiAgKSB7XG4gICAgc2NoZW1hID0gY29udmVydFBhcnNlU2NoZW1hVG9Nb25nb1NjaGVtYShzY2hlbWEpO1xuICAgIGNvbnN0IG1vbmdvVXBkYXRlID0gdHJhbnNmb3JtVXBkYXRlKGNsYXNzTmFtZSwgdXBkYXRlLCBzY2hlbWEpO1xuICAgIGNvbnN0IG1vbmdvV2hlcmUgPSB0cmFuc2Zvcm1XaGVyZShjbGFzc05hbWUsIHF1ZXJ5LCBzY2hlbWEpO1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLnVwc2VydE9uZShtb25nb1doZXJlLCBtb25nb1VwZGF0ZSwgdHJhbnNhY3Rpb25hbFNlc3Npb24pKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gRXhlY3V0ZXMgYSBmaW5kLiBBY2NlcHRzOiBjbGFzc05hbWUsIHF1ZXJ5IGluIFBhcnNlIGZvcm1hdCwgYW5kIHsgc2tpcCwgbGltaXQsIHNvcnQgfS5cbiAgZmluZChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICB7IHNraXAsIGxpbWl0LCBzb3J0LCBrZXlzLCByZWFkUHJlZmVyZW5jZSwgaGludCwgY2FzZUluc2Vuc2l0aXZlLCBleHBsYWluIH06IFF1ZXJ5T3B0aW9uc1xuICApOiBQcm9taXNlPGFueT4ge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb1doZXJlID0gdHJhbnNmb3JtV2hlcmUoY2xhc3NOYW1lLCBxdWVyeSwgc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb1NvcnQgPSBfLm1hcEtleXMoc29ydCwgKHZhbHVlLCBmaWVsZE5hbWUpID0+XG4gICAgICB0cmFuc2Zvcm1LZXkoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHNjaGVtYSlcbiAgICApO1xuICAgIGNvbnN0IG1vbmdvS2V5cyA9IF8ucmVkdWNlKFxuICAgICAga2V5cyxcbiAgICAgIChtZW1vLCBrZXkpID0+IHtcbiAgICAgICAgaWYgKGtleSA9PT0gJ0FDTCcpIHtcbiAgICAgICAgICBtZW1vWydfcnBlcm0nXSA9IDE7XG4gICAgICAgICAgbWVtb1snX3dwZXJtJ10gPSAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG1lbW9bdHJhbnNmb3JtS2V5KGNsYXNzTmFtZSwga2V5LCBzY2hlbWEpXSA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lbW87XG4gICAgICB9LFxuICAgICAge31cbiAgICApO1xuXG4gICAgLy8gSWYgd2UgYXJlbid0IHJlcXVlc3RpbmcgdGhlIGBfaWRgIGZpZWxkLCB3ZSBuZWVkIHRvIGV4cGxpY2l0bHkgb3B0IG91dFxuICAgIC8vIG9mIGl0LiBEb2luZyBzbyBpbiBwYXJzZS1zZXJ2ZXIgaXMgdW51c3VhbCwgYnV0IGl0IGNhbiBhbGxvdyB1cyB0b1xuICAgIC8vIG9wdGltaXplIHNvbWUgcXVlcmllcyB3aXRoIGNvdmVyaW5nIGluZGV4ZXMuXG4gICAgaWYgKGtleXMgJiYgIW1vbmdvS2V5cy5faWQpIHtcbiAgICAgIG1vbmdvS2V5cy5faWQgPSAwO1xuICAgIH1cblxuICAgIHJlYWRQcmVmZXJlbmNlID0gdGhpcy5fcGFyc2VSZWFkUHJlZmVyZW5jZShyZWFkUHJlZmVyZW5jZSk7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlVGV4dEluZGV4ZXNJZk5lZWRlZChjbGFzc05hbWUsIHF1ZXJ5LCBzY2hlbWEpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT5cbiAgICAgICAgY29sbGVjdGlvbi5maW5kKG1vbmdvV2hlcmUsIHtcbiAgICAgICAgICBza2lwLFxuICAgICAgICAgIGxpbWl0LFxuICAgICAgICAgIHNvcnQ6IG1vbmdvU29ydCxcbiAgICAgICAgICBrZXlzOiBtb25nb0tleXMsXG4gICAgICAgICAgbWF4VGltZU1TOiB0aGlzLl9tYXhUaW1lTVMsXG4gICAgICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgaGludCxcbiAgICAgICAgICBjYXNlSW5zZW5zaXRpdmUsXG4gICAgICAgICAgZXhwbGFpbixcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC50aGVuKG9iamVjdHMgPT4ge1xuICAgICAgICBpZiAoZXhwbGFpbikge1xuICAgICAgICAgIHJldHVybiBvYmplY3RzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmplY3RzLm1hcChvYmplY3QgPT4gbW9uZ29PYmplY3RUb1BhcnNlT2JqZWN0KGNsYXNzTmFtZSwgb2JqZWN0LCBzY2hlbWEpKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBlbnN1cmVJbmRleChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgZmllbGROYW1lczogc3RyaW5nW10sXG4gICAgaW5kZXhOYW1lOiA/c3RyaW5nLFxuICAgIGNhc2VJbnNlbnNpdGl2ZTogYm9vbGVhbiA9IGZhbHNlLFxuICAgIG9wdGlvbnM/OiBPYmplY3QgPSB7fVxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBpbmRleENyZWF0aW9uUmVxdWVzdCA9IHt9O1xuICAgIGNvbnN0IG1vbmdvRmllbGROYW1lcyA9IGZpZWxkTmFtZXMubWFwKGZpZWxkTmFtZSA9PiB0cmFuc2Zvcm1LZXkoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHNjaGVtYSkpO1xuICAgIG1vbmdvRmllbGROYW1lcy5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICBpbmRleENyZWF0aW9uUmVxdWVzdFtmaWVsZE5hbWVdID0gb3B0aW9ucy5pbmRleFR5cGUgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMuaW5kZXhUeXBlIDogMTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGRlZmF1bHRPcHRpb25zOiBPYmplY3QgPSB7IGJhY2tncm91bmQ6IHRydWUsIHNwYXJzZTogdHJ1ZSB9O1xuICAgIGNvbnN0IGluZGV4TmFtZU9wdGlvbnM6IE9iamVjdCA9IGluZGV4TmFtZSA/IHsgbmFtZTogaW5kZXhOYW1lIH0gOiB7fTtcbiAgICBjb25zdCB0dGxPcHRpb25zOiBPYmplY3QgPSBvcHRpb25zLnR0bCAhPT0gdW5kZWZpbmVkID8geyBleHBpcmVBZnRlclNlY29uZHM6IG9wdGlvbnMudHRsIH0gOiB7fTtcbiAgICBjb25zdCBjYXNlSW5zZW5zaXRpdmVPcHRpb25zOiBPYmplY3QgPSBjYXNlSW5zZW5zaXRpdmVcbiAgICAgID8geyBjb2xsYXRpb246IE1vbmdvQ29sbGVjdGlvbi5jYXNlSW5zZW5zaXRpdmVDb2xsYXRpb24oKSB9XG4gICAgICA6IHt9O1xuICAgIGNvbnN0IGluZGV4T3B0aW9uczogT2JqZWN0ID0ge1xuICAgICAgLi4uZGVmYXVsdE9wdGlvbnMsXG4gICAgICAuLi5jYXNlSW5zZW5zaXRpdmVPcHRpb25zLFxuICAgICAgLi4uaW5kZXhOYW1lT3B0aW9ucyxcbiAgICAgIC4uLnR0bE9wdGlvbnMsXG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oXG4gICAgICAgIGNvbGxlY3Rpb24gPT5cbiAgICAgICAgICBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PlxuICAgICAgICAgICAgY29sbGVjdGlvbi5fbW9uZ29Db2xsZWN0aW9uLmNyZWF0ZUluZGV4KGluZGV4Q3JlYXRpb25SZXF1ZXN0LCBpbmRleE9wdGlvbnMsIGVycm9yID0+XG4gICAgICAgICAgICAgIGVycm9yID8gcmVqZWN0KGVycm9yKSA6IHJlc29sdmUoKVxuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgIClcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIENyZWF0ZSBhIHVuaXF1ZSBpbmRleC4gVW5pcXVlIGluZGV4ZXMgb24gbnVsbGFibGUgZmllbGRzIGFyZSBub3QgYWxsb3dlZC4gU2luY2Ugd2UgZG9uJ3RcbiAgLy8gY3VycmVudGx5IGtub3cgd2hpY2ggZmllbGRzIGFyZSBudWxsYWJsZSBhbmQgd2hpY2ggYXJlbid0LCB3ZSBpZ25vcmUgdGhhdCBjcml0ZXJpYS5cbiAgLy8gQXMgc3VjaCwgd2Ugc2hvdWxkbid0IGV4cG9zZSB0aGlzIGZ1bmN0aW9uIHRvIHVzZXJzIG9mIHBhcnNlIHVudGlsIHdlIGhhdmUgYW4gb3V0LW9mLWJhbmRcbiAgLy8gV2F5IG9mIGRldGVybWluaW5nIGlmIGEgZmllbGQgaXMgbnVsbGFibGUuIFVuZGVmaW5lZCBkb2Vzbid0IGNvdW50IGFnYWluc3QgdW5pcXVlbmVzcyxcbiAgLy8gd2hpY2ggaXMgd2h5IHdlIHVzZSBzcGFyc2UgaW5kZXhlcy5cbiAgZW5zdXJlVW5pcXVlbmVzcyhjbGFzc05hbWU6IHN0cmluZywgc2NoZW1hOiBTY2hlbWFUeXBlLCBmaWVsZE5hbWVzOiBzdHJpbmdbXSkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBpbmRleENyZWF0aW9uUmVxdWVzdCA9IHt9O1xuICAgIGNvbnN0IG1vbmdvRmllbGROYW1lcyA9IGZpZWxkTmFtZXMubWFwKGZpZWxkTmFtZSA9PiB0cmFuc2Zvcm1LZXkoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHNjaGVtYSkpO1xuICAgIG1vbmdvRmllbGROYW1lcy5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICBpbmRleENyZWF0aW9uUmVxdWVzdFtmaWVsZE5hbWVdID0gMTtcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5fZW5zdXJlU3BhcnNlVW5pcXVlSW5kZXhJbkJhY2tncm91bmQoaW5kZXhDcmVhdGlvblJlcXVlc3QpKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDExMDAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFLFxuICAgICAgICAgICAgJ1RyaWVkIHRvIGVuc3VyZSBmaWVsZCB1bmlxdWVuZXNzIGZvciBhIGNsYXNzIHRoYXQgYWxyZWFkeSBoYXMgZHVwbGljYXRlcy4nXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICAvLyBVc2VkIGluIHRlc3RzXG4gIF9yYXdGaW5kKGNsYXNzTmFtZTogc3RyaW5nLCBxdWVyeTogUXVlcnlUeXBlKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+XG4gICAgICAgIGNvbGxlY3Rpb24uZmluZChxdWVyeSwge1xuICAgICAgICAgIG1heFRpbWVNUzogdGhpcy5fbWF4VGltZU1TLFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gRXhlY3V0ZXMgYSBjb3VudC5cbiAgY291bnQoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIHF1ZXJ5OiBRdWVyeVR5cGUsXG4gICAgcmVhZFByZWZlcmVuY2U6ID9zdHJpbmcsXG4gICAgaGludDogP21peGVkXG4gICkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICByZWFkUHJlZmVyZW5jZSA9IHRoaXMuX3BhcnNlUmVhZFByZWZlcmVuY2UocmVhZFByZWZlcmVuY2UpO1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PlxuICAgICAgICBjb2xsZWN0aW9uLmNvdW50KHRyYW5zZm9ybVdoZXJlKGNsYXNzTmFtZSwgcXVlcnksIHNjaGVtYSwgdHJ1ZSksIHtcbiAgICAgICAgICBtYXhUaW1lTVM6IHRoaXMuX21heFRpbWVNUyxcbiAgICAgICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICBoaW50LFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgZGlzdGluY3QoY2xhc3NOYW1lOiBzdHJpbmcsIHNjaGVtYTogU2NoZW1hVHlwZSwgcXVlcnk6IFF1ZXJ5VHlwZSwgZmllbGROYW1lOiBzdHJpbmcpIHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgY29uc3QgaXNQb2ludGVyRmllbGQgPSBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiYgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdQb2ludGVyJztcbiAgICBjb25zdCB0cmFuc2Zvcm1GaWVsZCA9IHRyYW5zZm9ybUtleShjbGFzc05hbWUsIGZpZWxkTmFtZSwgc2NoZW1hKTtcblxuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PlxuICAgICAgICBjb2xsZWN0aW9uLmRpc3RpbmN0KHRyYW5zZm9ybUZpZWxkLCB0cmFuc2Zvcm1XaGVyZShjbGFzc05hbWUsIHF1ZXJ5LCBzY2hlbWEpKVxuICAgICAgKVxuICAgICAgLnRoZW4ob2JqZWN0cyA9PiB7XG4gICAgICAgIG9iamVjdHMgPSBvYmplY3RzLmZpbHRlcihvYmogPT4gb2JqICE9IG51bGwpO1xuICAgICAgICByZXR1cm4gb2JqZWN0cy5tYXAob2JqZWN0ID0+IHtcbiAgICAgICAgICBpZiAoaXNQb2ludGVyRmllbGQpIHtcbiAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1Qb2ludGVyU3RyaW5nKHNjaGVtYSwgZmllbGROYW1lLCBvYmplY3QpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbW9uZ29PYmplY3RUb1BhcnNlT2JqZWN0KGNsYXNzTmFtZSwgb2JqZWN0LCBzY2hlbWEpO1xuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBhZ2dyZWdhdGUoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBhbnksXG4gICAgcGlwZWxpbmU6IGFueSxcbiAgICByZWFkUHJlZmVyZW5jZTogP3N0cmluZyxcbiAgICBoaW50OiA/bWl4ZWQsXG4gICAgZXhwbGFpbj86IGJvb2xlYW5cbiAgKSB7XG4gICAgbGV0IGlzUG9pbnRlckZpZWxkID0gZmFsc2U7XG4gICAgcGlwZWxpbmUgPSBwaXBlbGluZS5tYXAoc3RhZ2UgPT4ge1xuICAgICAgaWYgKHN0YWdlLiRncm91cCkge1xuICAgICAgICBzdGFnZS4kZ3JvdXAgPSB0aGlzLl9wYXJzZUFnZ3JlZ2F0ZUdyb3VwQXJncyhzY2hlbWEsIHN0YWdlLiRncm91cCk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBzdGFnZS4kZ3JvdXAuX2lkICYmXG4gICAgICAgICAgdHlwZW9mIHN0YWdlLiRncm91cC5faWQgPT09ICdzdHJpbmcnICYmXG4gICAgICAgICAgc3RhZ2UuJGdyb3VwLl9pZC5pbmRleE9mKCckX3BfJykgPj0gMFxuICAgICAgICApIHtcbiAgICAgICAgICBpc1BvaW50ZXJGaWVsZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChzdGFnZS4kbWF0Y2gpIHtcbiAgICAgICAgc3RhZ2UuJG1hdGNoID0gdGhpcy5fcGFyc2VBZ2dyZWdhdGVBcmdzKHNjaGVtYSwgc3RhZ2UuJG1hdGNoKTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFnZS4kcHJvamVjdCkge1xuICAgICAgICBzdGFnZS4kcHJvamVjdCA9IHRoaXMuX3BhcnNlQWdncmVnYXRlUHJvamVjdEFyZ3Moc2NoZW1hLCBzdGFnZS4kcHJvamVjdCk7XG4gICAgICB9XG4gICAgICBpZiAoc3RhZ2UuJGdlb05lYXIgJiYgc3RhZ2UuJGdlb05lYXIucXVlcnkpIHtcbiAgICAgICAgc3RhZ2UuJGdlb05lYXIucXVlcnkgPSB0aGlzLl9wYXJzZUFnZ3JlZ2F0ZUFyZ3Moc2NoZW1hLCBzdGFnZS4kZ2VvTmVhci5xdWVyeSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gc3RhZ2U7XG4gICAgfSk7XG4gICAgcmVhZFByZWZlcmVuY2UgPSB0aGlzLl9wYXJzZVJlYWRQcmVmZXJlbmNlKHJlYWRQcmVmZXJlbmNlKTtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT5cbiAgICAgICAgY29sbGVjdGlvbi5hZ2dyZWdhdGUocGlwZWxpbmUsIHtcbiAgICAgICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICBtYXhUaW1lTVM6IHRoaXMuX21heFRpbWVNUyxcbiAgICAgICAgICBoaW50LFxuICAgICAgICAgIGV4cGxhaW4sXG4gICAgICAgIH0pXG4gICAgICApXG4gICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgcmVzdWx0cy5mb3JFYWNoKHJlc3VsdCA9PiB7XG4gICAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChyZXN1bHQsICdfaWQnKSkge1xuICAgICAgICAgICAgaWYgKGlzUG9pbnRlckZpZWxkICYmIHJlc3VsdC5faWQpIHtcbiAgICAgICAgICAgICAgcmVzdWx0Ll9pZCA9IHJlc3VsdC5faWQuc3BsaXQoJyQnKVsxXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgcmVzdWx0Ll9pZCA9PSBudWxsIHx8XG4gICAgICAgICAgICAgIHJlc3VsdC5faWQgPT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgICAgIChbJ29iamVjdCcsICdzdHJpbmcnXS5pbmNsdWRlcyh0eXBlb2YgcmVzdWx0Ll9pZCkgJiYgXy5pc0VtcHR5KHJlc3VsdC5faWQpKVxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5faWQgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzdWx0Lm9iamVjdElkID0gcmVzdWx0Ll9pZDtcbiAgICAgICAgICAgIGRlbGV0ZSByZXN1bHQuX2lkO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgfSlcbiAgICAgIC50aGVuKG9iamVjdHMgPT4gb2JqZWN0cy5tYXAob2JqZWN0ID0+IG1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdChjbGFzc05hbWUsIG9iamVjdCwgc2NoZW1hKSkpXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICAvLyBUaGlzIGZ1bmN0aW9uIHdpbGwgcmVjdXJzaXZlbHkgdHJhdmVyc2UgdGhlIHBpcGVsaW5lIGFuZCBjb252ZXJ0IGFueSBQb2ludGVyIG9yIERhdGUgY29sdW1ucy5cbiAgLy8gSWYgd2UgZGV0ZWN0IGEgcG9pbnRlciBjb2x1bW4gd2Ugd2lsbCByZW5hbWUgdGhlIGNvbHVtbiBiZWluZyBxdWVyaWVkIGZvciB0byBtYXRjaCB0aGUgY29sdW1uXG4gIC8vIGluIHRoZSBkYXRhYmFzZS4gV2UgYWxzbyBtb2RpZnkgdGhlIHZhbHVlIHRvIHdoYXQgd2UgZXhwZWN0IHRoZSB2YWx1ZSB0byBiZSBpbiB0aGUgZGF0YWJhc2VcbiAgLy8gYXMgd2VsbC5cbiAgLy8gRm9yIGRhdGVzLCB0aGUgZHJpdmVyIGV4cGVjdHMgYSBEYXRlIG9iamVjdCwgYnV0IHdlIGhhdmUgYSBzdHJpbmcgY29taW5nIGluLiBTbyB3ZSdsbCBjb252ZXJ0XG4gIC8vIHRoZSBzdHJpbmcgdG8gYSBEYXRlIHNvIHRoZSBkcml2ZXIgY2FuIHBlcmZvcm0gdGhlIG5lY2Vzc2FyeSBjb21wYXJpc29uLlxuICAvL1xuICAvLyBUaGUgZ29hbCBvZiB0aGlzIG1ldGhvZCBpcyB0byBsb29rIGZvciB0aGUgXCJsZWF2ZXNcIiBvZiB0aGUgcGlwZWxpbmUgYW5kIGRldGVybWluZSBpZiBpdCBuZWVkc1xuICAvLyB0byBiZSBjb252ZXJ0ZWQuIFRoZSBwaXBlbGluZSBjYW4gaGF2ZSBhIGZldyBkaWZmZXJlbnQgZm9ybXMuIEZvciBtb3JlIGRldGFpbHMsIHNlZTpcbiAgLy8gICAgIGh0dHBzOi8vZG9jcy5tb25nb2RiLmNvbS9tYW51YWwvcmVmZXJlbmNlL29wZXJhdG9yL2FnZ3JlZ2F0aW9uL1xuICAvL1xuICAvLyBJZiB0aGUgcGlwZWxpbmUgaXMgYW4gYXJyYXksIGl0IG1lYW5zIHdlIGFyZSBwcm9iYWJseSBwYXJzaW5nIGFuICckYW5kJyBvciAnJG9yJyBvcGVyYXRvci4gSW5cbiAgLy8gdGhhdCBjYXNlIHdlIG5lZWQgdG8gbG9vcCB0aHJvdWdoIGFsbCBvZiBpdCdzIGNoaWxkcmVuIHRvIGZpbmQgdGhlIGNvbHVtbnMgYmVpbmcgb3BlcmF0ZWQgb24uXG4gIC8vIElmIHRoZSBwaXBlbGluZSBpcyBhbiBvYmplY3QsIHRoZW4gd2UnbGwgbG9vcCB0aHJvdWdoIHRoZSBrZXlzIGNoZWNraW5nIHRvIHNlZSBpZiB0aGUga2V5IG5hbWVcbiAgLy8gbWF0Y2hlcyBvbmUgb2YgdGhlIHNjaGVtYSBjb2x1bW5zLiBJZiBpdCBkb2VzIG1hdGNoIGEgY29sdW1uIGFuZCB0aGUgY29sdW1uIGlzIGEgUG9pbnRlciBvclxuICAvLyBhIERhdGUsIHRoZW4gd2UnbGwgY29udmVydCB0aGUgdmFsdWUgYXMgZGVzY3JpYmVkIGFib3ZlLlxuICAvL1xuICAvLyBBcyBtdWNoIGFzIEkgaGF0ZSByZWN1cnNpb24uLi50aGlzIHNlZW1lZCBsaWtlIGEgZ29vZCBmaXQgZm9yIGl0LiBXZSdyZSBlc3NlbnRpYWxseSB0cmF2ZXJzaW5nXG4gIC8vIGRvd24gYSB0cmVlIHRvIGZpbmQgYSBcImxlYWYgbm9kZVwiIGFuZCBjaGVja2luZyB0byBzZWUgaWYgaXQgbmVlZHMgdG8gYmUgY29udmVydGVkLlxuICBfcGFyc2VBZ2dyZWdhdGVBcmdzKHNjaGVtYTogYW55LCBwaXBlbGluZTogYW55KTogYW55IHtcbiAgICBpZiAocGlwZWxpbmUgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShwaXBlbGluZSkpIHtcbiAgICAgIHJldHVybiBwaXBlbGluZS5tYXAodmFsdWUgPT4gdGhpcy5fcGFyc2VBZ2dyZWdhdGVBcmdzKHNjaGVtYSwgdmFsdWUpKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBwaXBlbGluZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGNvbnN0IHJldHVyblZhbHVlID0ge307XG4gICAgICBmb3IgKGNvbnN0IGZpZWxkIGluIHBpcGVsaW5lKSB7XG4gICAgICAgIGlmIChzY2hlbWEuZmllbGRzW2ZpZWxkXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIHBpcGVsaW5lW2ZpZWxkXSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIC8vIFBhc3Mgb2JqZWN0cyBkb3duIHRvIE1vbmdvREIuLi50aGlzIGlzIG1vcmUgdGhhbiBsaWtlbHkgYW4gJGV4aXN0cyBvcGVyYXRvci5cbiAgICAgICAgICAgIHJldHVyblZhbHVlW2BfcF8ke2ZpZWxkfWBdID0gcGlwZWxpbmVbZmllbGRdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm5WYWx1ZVtgX3BfJHtmaWVsZH1gXSA9IGAke3NjaGVtYS5maWVsZHNbZmllbGRdLnRhcmdldENsYXNzfSQke3BpcGVsaW5lW2ZpZWxkXX1gO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChzY2hlbWEuZmllbGRzW2ZpZWxkXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnRGF0ZScpIHtcbiAgICAgICAgICByZXR1cm5WYWx1ZVtmaWVsZF0gPSB0aGlzLl9jb252ZXJ0VG9EYXRlKHBpcGVsaW5lW2ZpZWxkXSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuVmFsdWVbZmllbGRdID0gdGhpcy5fcGFyc2VBZ2dyZWdhdGVBcmdzKHNjaGVtYSwgcGlwZWxpbmVbZmllbGRdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmaWVsZCA9PT0gJ29iamVjdElkJykge1xuICAgICAgICAgIHJldHVyblZhbHVlWydfaWQnXSA9IHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgICAgICBkZWxldGUgcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgICB9IGVsc2UgaWYgKGZpZWxkID09PSAnY3JlYXRlZEF0Jykge1xuICAgICAgICAgIHJldHVyblZhbHVlWydfY3JlYXRlZF9hdCddID0gcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgICAgIGRlbGV0ZSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICAgIH0gZWxzZSBpZiAoZmllbGQgPT09ICd1cGRhdGVkQXQnKSB7XG4gICAgICAgICAgcmV0dXJuVmFsdWVbJ191cGRhdGVkX2F0J10gPSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICAgICAgZGVsZXRlIHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gcGlwZWxpbmU7XG4gIH1cblxuICAvLyBUaGlzIGZ1bmN0aW9uIGlzIHNsaWdodGx5IGRpZmZlcmVudCB0aGFuIHRoZSBvbmUgYWJvdmUuIFJhdGhlciB0aGFuIHRyeWluZyB0byBjb21iaW5lIHRoZXNlXG4gIC8vIHR3byBmdW5jdGlvbnMgYW5kIG1ha2luZyB0aGUgY29kZSBldmVuIGhhcmRlciB0byB1bmRlcnN0YW5kLCBJIGRlY2lkZWQgdG8gc3BsaXQgaXQgdXAuIFRoZVxuICAvLyBkaWZmZXJlbmNlIHdpdGggdGhpcyBmdW5jdGlvbiBpcyB3ZSBhcmUgbm90IHRyYW5zZm9ybWluZyB0aGUgdmFsdWVzLCBvbmx5IHRoZSBrZXlzIG9mIHRoZVxuICAvLyBwaXBlbGluZS5cbiAgX3BhcnNlQWdncmVnYXRlUHJvamVjdEFyZ3Moc2NoZW1hOiBhbnksIHBpcGVsaW5lOiBhbnkpOiBhbnkge1xuICAgIGNvbnN0IHJldHVyblZhbHVlID0ge307XG4gICAgZm9yIChjb25zdCBmaWVsZCBpbiBwaXBlbGluZSkge1xuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGRdICYmIHNjaGVtYS5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgICByZXR1cm5WYWx1ZVtgX3BfJHtmaWVsZH1gXSA9IHBpcGVsaW5lW2ZpZWxkXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVyblZhbHVlW2ZpZWxkXSA9IHRoaXMuX3BhcnNlQWdncmVnYXRlQXJncyhzY2hlbWEsIHBpcGVsaW5lW2ZpZWxkXSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChmaWVsZCA9PT0gJ29iamVjdElkJykge1xuICAgICAgICByZXR1cm5WYWx1ZVsnX2lkJ10gPSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICAgIGRlbGV0ZSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkID09PSAnY3JlYXRlZEF0Jykge1xuICAgICAgICByZXR1cm5WYWx1ZVsnX2NyZWF0ZWRfYXQnXSA9IHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgICAgZGVsZXRlIHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGQgPT09ICd1cGRhdGVkQXQnKSB7XG4gICAgICAgIHJldHVyblZhbHVlWydfdXBkYXRlZF9hdCddID0gcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgICBkZWxldGUgcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gIH1cblxuICAvLyBUaGlzIGZ1bmN0aW9uIGlzIHNsaWdodGx5IGRpZmZlcmVudCB0aGFuIHRoZSB0d28gYWJvdmUuIE1vbmdvREIgJGdyb3VwIGFnZ3JlZ2F0ZSBsb29rcyBsaWtlOlxuICAvLyAgICAgeyAkZ3JvdXA6IHsgX2lkOiA8ZXhwcmVzc2lvbj4sIDxmaWVsZDE+OiB7IDxhY2N1bXVsYXRvcjE+IDogPGV4cHJlc3Npb24xPiB9LCAuLi4gfSB9XG4gIC8vIFRoZSA8ZXhwcmVzc2lvbj4gY291bGQgYmUgYSBjb2x1bW4gbmFtZSwgcHJlZml4ZWQgd2l0aCB0aGUgJyQnIGNoYXJhY3Rlci4gV2UnbGwgbG9vayBmb3JcbiAgLy8gdGhlc2UgPGV4cHJlc3Npb24+IGFuZCBjaGVjayB0byBzZWUgaWYgaXQgaXMgYSAnUG9pbnRlcicgb3IgaWYgaXQncyBvbmUgb2YgY3JlYXRlZEF0LFxuICAvLyB1cGRhdGVkQXQgb3Igb2JqZWN0SWQgYW5kIGNoYW5nZSBpdCBhY2NvcmRpbmdseS5cbiAgX3BhcnNlQWdncmVnYXRlR3JvdXBBcmdzKHNjaGVtYTogYW55LCBwaXBlbGluZTogYW55KTogYW55IHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShwaXBlbGluZSkpIHtcbiAgICAgIHJldHVybiBwaXBlbGluZS5tYXAodmFsdWUgPT4gdGhpcy5fcGFyc2VBZ2dyZWdhdGVHcm91cEFyZ3Moc2NoZW1hLCB2YWx1ZSkpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHBpcGVsaW5lID09PSAnb2JqZWN0Jykge1xuICAgICAgY29uc3QgcmV0dXJuVmFsdWUgPSB7fTtcbiAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gcGlwZWxpbmUpIHtcbiAgICAgICAgcmV0dXJuVmFsdWVbZmllbGRdID0gdGhpcy5fcGFyc2VBZ2dyZWdhdGVHcm91cEFyZ3Moc2NoZW1hLCBwaXBlbGluZVtmaWVsZF0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHBpcGVsaW5lID09PSAnc3RyaW5nJykge1xuICAgICAgY29uc3QgZmllbGQgPSBwaXBlbGluZS5zdWJzdHJpbmcoMSk7XG4gICAgICBpZiAoc2NoZW1hLmZpZWxkc1tmaWVsZF0gJiYgc2NoZW1hLmZpZWxkc1tmaWVsZF0udHlwZSA9PT0gJ1BvaW50ZXInKSB7XG4gICAgICAgIHJldHVybiBgJF9wXyR7ZmllbGR9YDtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGQgPT0gJ2NyZWF0ZWRBdCcpIHtcbiAgICAgICAgcmV0dXJuICckX2NyZWF0ZWRfYXQnO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZCA9PSAndXBkYXRlZEF0Jykge1xuICAgICAgICByZXR1cm4gJyRfdXBkYXRlZF9hdCc7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwaXBlbGluZTtcbiAgfVxuXG4gIC8vIFRoaXMgZnVuY3Rpb24gd2lsbCBhdHRlbXB0IHRvIGNvbnZlcnQgdGhlIHByb3ZpZGVkIHZhbHVlIHRvIGEgRGF0ZSBvYmplY3QuIFNpbmNlIHRoaXMgaXMgcGFydFxuICAvLyBvZiBhbiBhZ2dyZWdhdGlvbiBwaXBlbGluZSwgdGhlIHZhbHVlIGNhbiBlaXRoZXIgYmUgYSBzdHJpbmcgb3IgaXQgY2FuIGJlIGFub3RoZXIgb2JqZWN0IHdpdGhcbiAgLy8gYW4gb3BlcmF0b3IgaW4gaXQgKGxpa2UgJGd0LCAkbHQsIGV0YykuIEJlY2F1c2Ugb2YgdGhpcyBJIGZlbHQgaXQgd2FzIGVhc2llciB0byBtYWtlIHRoaXMgYVxuICAvLyByZWN1cnNpdmUgbWV0aG9kIHRvIHRyYXZlcnNlIGRvd24gdG8gdGhlIFwibGVhZiBub2RlXCIgd2hpY2ggaXMgZ29pbmcgdG8gYmUgdGhlIHN0cmluZy5cbiAgX2NvbnZlcnRUb0RhdGUodmFsdWU6IGFueSk6IGFueSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgY29uc3QgcmV0dXJuVmFsdWUgPSB7fTtcbiAgICBmb3IgKGNvbnN0IGZpZWxkIGluIHZhbHVlKSB7XG4gICAgICByZXR1cm5WYWx1ZVtmaWVsZF0gPSB0aGlzLl9jb252ZXJ0VG9EYXRlKHZhbHVlW2ZpZWxkXSk7XG4gICAgfVxuICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgfVxuXG4gIF9wYXJzZVJlYWRQcmVmZXJlbmNlKHJlYWRQcmVmZXJlbmNlOiA/c3RyaW5nKTogP3N0cmluZyB7XG4gICAgaWYgKHJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICByZWFkUHJlZmVyZW5jZSA9IHJlYWRQcmVmZXJlbmNlLnRvVXBwZXJDYXNlKCk7XG4gICAgfVxuICAgIHN3aXRjaCAocmVhZFByZWZlcmVuY2UpIHtcbiAgICAgIGNhc2UgJ1BSSU1BUlknOlxuICAgICAgICByZWFkUHJlZmVyZW5jZSA9IFJlYWRQcmVmZXJlbmNlLlBSSU1BUlk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnUFJJTUFSWV9QUkVGRVJSRUQnOlxuICAgICAgICByZWFkUHJlZmVyZW5jZSA9IFJlYWRQcmVmZXJlbmNlLlBSSU1BUllfUFJFRkVSUkVEO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ1NFQ09OREFSWSc6XG4gICAgICAgIHJlYWRQcmVmZXJlbmNlID0gUmVhZFByZWZlcmVuY2UuU0VDT05EQVJZO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ1NFQ09OREFSWV9QUkVGRVJSRUQnOlxuICAgICAgICByZWFkUHJlZmVyZW5jZSA9IFJlYWRQcmVmZXJlbmNlLlNFQ09OREFSWV9QUkVGRVJSRUQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnTkVBUkVTVCc6XG4gICAgICAgIHJlYWRQcmVmZXJlbmNlID0gUmVhZFByZWZlcmVuY2UuTkVBUkVTVDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIHVuZGVmaW5lZDpcbiAgICAgIGNhc2UgbnVsbDpcbiAgICAgIGNhc2UgJyc6XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksICdOb3Qgc3VwcG9ydGVkIHJlYWQgcHJlZmVyZW5jZS4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlYWRQcmVmZXJlbmNlO1xuICB9XG5cbiAgcGVyZm9ybUluaXRpYWxpemF0aW9uKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGNyZWF0ZUluZGV4KGNsYXNzTmFtZTogc3RyaW5nLCBpbmRleDogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24uX21vbmdvQ29sbGVjdGlvbi5jcmVhdGVJbmRleChpbmRleCkpXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBjcmVhdGVJbmRleGVzKGNsYXNzTmFtZTogc3RyaW5nLCBpbmRleGVzOiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5fbW9uZ29Db2xsZWN0aW9uLmNyZWF0ZUluZGV4ZXMoaW5kZXhlcykpXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBjcmVhdGVJbmRleGVzSWZOZWVkZWQoY2xhc3NOYW1lOiBzdHJpbmcsIGZpZWxkTmFtZTogc3RyaW5nLCB0eXBlOiBhbnkpIHtcbiAgICBpZiAodHlwZSAmJiB0eXBlLnR5cGUgPT09ICdQb2x5Z29uJykge1xuICAgICAgY29uc3QgaW5kZXggPSB7XG4gICAgICAgIFtmaWVsZE5hbWVdOiAnMmRzcGhlcmUnLFxuICAgICAgfTtcbiAgICAgIHJldHVybiB0aGlzLmNyZWF0ZUluZGV4KGNsYXNzTmFtZSwgaW5kZXgpO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBjcmVhdGVUZXh0SW5kZXhlc0lmTmVlZGVkKGNsYXNzTmFtZTogc3RyaW5nLCBxdWVyeTogUXVlcnlUeXBlLCBzY2hlbWE6IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGZvciAoY29uc3QgZmllbGROYW1lIGluIHF1ZXJ5KSB7XG4gICAgICBpZiAoIXF1ZXJ5W2ZpZWxkTmFtZV0gfHwgIXF1ZXJ5W2ZpZWxkTmFtZV0uJHRleHQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBleGlzdGluZ0luZGV4ZXMgPSBzY2hlbWEuaW5kZXhlcztcbiAgICAgIGZvciAoY29uc3Qga2V5IGluIGV4aXN0aW5nSW5kZXhlcykge1xuICAgICAgICBjb25zdCBpbmRleCA9IGV4aXN0aW5nSW5kZXhlc1trZXldO1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGluZGV4LCBmaWVsZE5hbWUpKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCBpbmRleE5hbWUgPSBgJHtmaWVsZE5hbWV9X3RleHRgO1xuICAgICAgY29uc3QgdGV4dEluZGV4ID0ge1xuICAgICAgICBbaW5kZXhOYW1lXTogeyBbZmllbGROYW1lXTogJ3RleHQnIH0sXG4gICAgICB9O1xuICAgICAgcmV0dXJuIHRoaXMuc2V0SW5kZXhlc1dpdGhTY2hlbWFGb3JtYXQoXG4gICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgdGV4dEluZGV4LFxuICAgICAgICBleGlzdGluZ0luZGV4ZXMsXG4gICAgICAgIHNjaGVtYS5maWVsZHNcbiAgICAgICkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gODUpIHtcbiAgICAgICAgICAvLyBJbmRleCBleGlzdCB3aXRoIGRpZmZlcmVudCBvcHRpb25zXG4gICAgICAgICAgcmV0dXJuIHRoaXMuc2V0SW5kZXhlc0Zyb21Nb25nbyhjbGFzc05hbWUpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGdldEluZGV4ZXMoY2xhc3NOYW1lOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5fbW9uZ29Db2xsZWN0aW9uLmluZGV4ZXMoKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIGRyb3BJbmRleChjbGFzc05hbWU6IHN0cmluZywgaW5kZXg6IGFueSkge1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLl9tb25nb0NvbGxlY3Rpb24uZHJvcEluZGV4KGluZGV4KSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIGRyb3BBbGxJbmRleGVzKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24uX21vbmdvQ29sbGVjdGlvbi5kcm9wSW5kZXhlcygpKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgdXBkYXRlU2NoZW1hV2l0aEluZGV4ZXMoKTogUHJvbWlzZTxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy5nZXRBbGxDbGFzc2VzKClcbiAgICAgIC50aGVuKGNsYXNzZXMgPT4ge1xuICAgICAgICBjb25zdCBwcm9taXNlcyA9IGNsYXNzZXMubWFwKHNjaGVtYSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuc2V0SW5kZXhlc0Zyb21Nb25nbyhzY2hlbWEuY2xhc3NOYW1lKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgY3JlYXRlVHJhbnNhY3Rpb25hbFNlc3Npb24oKTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCB0cmFuc2FjdGlvbmFsU2VjdGlvbiA9IHRoaXMuY2xpZW50LnN0YXJ0U2Vzc2lvbigpO1xuICAgIHRyYW5zYWN0aW9uYWxTZWN0aW9uLnN0YXJ0VHJhbnNhY3Rpb24oKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRyYW5zYWN0aW9uYWxTZWN0aW9uKTtcbiAgfVxuXG4gIGNvbW1pdFRyYW5zYWN0aW9uYWxTZXNzaW9uKHRyYW5zYWN0aW9uYWxTZWN0aW9uOiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdHJhbnNhY3Rpb25hbFNlY3Rpb24uY29tbWl0VHJhbnNhY3Rpb24oKS50aGVuKCgpID0+IHtcbiAgICAgIHRyYW5zYWN0aW9uYWxTZWN0aW9uLmVuZFNlc3Npb24oKTtcbiAgICB9KTtcbiAgfVxuXG4gIGFib3J0VHJhbnNhY3Rpb25hbFNlc3Npb24odHJhbnNhY3Rpb25hbFNlY3Rpb246IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0cmFuc2FjdGlvbmFsU2VjdGlvbi5hYm9ydFRyYW5zYWN0aW9uKCkudGhlbigoKSA9PiB7XG4gICAgICB0cmFuc2FjdGlvbmFsU2VjdGlvbi5lbmRTZXNzaW9uKCk7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTW9uZ29TdG9yYWdlQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Storage/Mongo/MongoTransform.js b/lib/Adapters/Storage/Mongo/MongoTransform.js deleted file mode 100644 index 1c9a5dd201..0000000000 --- a/lib/Adapters/Storage/Mongo/MongoTransform.js +++ /dev/null @@ -1,1795 +0,0 @@ -"use strict"; - -var _logger = _interopRequireDefault(require("../../../logger")); - -var _lodash = _interopRequireDefault(require("lodash")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var mongodb = require('mongodb'); - -var Parse = require('parse/node').Parse; - -const transformKey = (className, fieldName, schema) => { - // Check if the schema is known since it's a built-in field. - switch (fieldName) { - case 'objectId': - return '_id'; - - case 'createdAt': - return '_created_at'; - - case 'updatedAt': - return '_updated_at'; - - case 'sessionToken': - return '_session_token'; - - case 'lastUsed': - return '_last_used'; - - case 'timesUsed': - return 'times_used'; - } - - if (schema.fields[fieldName] && schema.fields[fieldName].__type == 'Pointer') { - fieldName = '_p_' + fieldName; - } else if (schema.fields[fieldName] && schema.fields[fieldName].type == 'Pointer') { - fieldName = '_p_' + fieldName; - } - - return fieldName; -}; - -const transformKeyValueForUpdate = (className, restKey, restValue, parseFormatSchema) => { - // Check if the schema is known since it's a built-in field. - var key = restKey; - var timeField = false; - - switch (key) { - case 'objectId': - case '_id': - if (['_GlobalConfig', '_GraphQLConfig'].includes(className)) { - return { - key: key, - value: parseInt(restValue) - }; - } - - key = '_id'; - break; - - case 'createdAt': - case '_created_at': - key = '_created_at'; - timeField = true; - break; - - case 'updatedAt': - case '_updated_at': - key = '_updated_at'; - timeField = true; - break; - - case 'sessionToken': - case '_session_token': - key = '_session_token'; - break; - - case 'expiresAt': - case '_expiresAt': - key = 'expiresAt'; - timeField = true; - break; - - case '_email_verify_token_expires_at': - key = '_email_verify_token_expires_at'; - timeField = true; - break; - - case '_account_lockout_expires_at': - key = '_account_lockout_expires_at'; - timeField = true; - break; - - case '_failed_login_count': - key = '_failed_login_count'; - break; - - case '_perishable_token_expires_at': - key = '_perishable_token_expires_at'; - timeField = true; - break; - - case '_password_changed_at': - key = '_password_changed_at'; - timeField = true; - break; - - case '_rperm': - case '_wperm': - return { - key: key, - value: restValue - }; - - case 'lastUsed': - case '_last_used': - key = '_last_used'; - timeField = true; - break; - - case 'timesUsed': - case 'times_used': - key = 'times_used'; - timeField = true; - break; - } - - if (parseFormatSchema.fields[key] && parseFormatSchema.fields[key].type === 'Pointer' || !parseFormatSchema.fields[key] && restValue && restValue.__type == 'Pointer') { - key = '_p_' + key; - } // Handle atomic values - - - var value = transformTopLevelAtom(restValue); - - if (value !== CannotTransform) { - if (timeField && typeof value === 'string') { - value = new Date(value); - } - - if (restKey.indexOf('.') > 0) { - return { - key, - value: restValue - }; - } - - return { - key, - value - }; - } // Handle arrays - - - if (restValue instanceof Array) { - value = restValue.map(transformInteriorValue); - return { - key, - value - }; - } // Handle update operators - - - if (typeof restValue === 'object' && '__op' in restValue) { - return { - key, - value: transformUpdateOperator(restValue, false) - }; - } // Handle normal objects by recursing - - - value = mapValues(restValue, transformInteriorValue); - return { - key, - value - }; -}; - -const isRegex = value => { - return value && value instanceof RegExp; -}; - -const isStartsWithRegex = value => { - if (!isRegex(value)) { - return false; - } - - const matches = value.toString().match(/\/\^\\Q.*\\E\//); - return !!matches; -}; - -const isAllValuesRegexOrNone = values => { - if (!values || !Array.isArray(values) || values.length === 0) { - return true; - } - - const firstValuesIsRegex = isStartsWithRegex(values[0]); - - if (values.length === 1) { - return firstValuesIsRegex; - } - - for (let i = 1, length = values.length; i < length; ++i) { - if (firstValuesIsRegex !== isStartsWithRegex(values[i])) { - return false; - } - } - - return true; -}; - -const isAnyValueRegex = values => { - return values.some(function (value) { - return isRegex(value); - }); -}; - -const transformInteriorValue = restValue => { - if (restValue !== null && typeof restValue === 'object' && Object.keys(restValue).some(key => key.includes('$') || key.includes('.'))) { - throw new Parse.Error(Parse.Error.INVALID_NESTED_KEY, "Nested keys should not contain the '$' or '.' characters"); - } // Handle atomic values - - - var value = transformInteriorAtom(restValue); - - if (value !== CannotTransform) { - return value; - } // Handle arrays - - - if (restValue instanceof Array) { - return restValue.map(transformInteriorValue); - } // Handle update operators - - - if (typeof restValue === 'object' && '__op' in restValue) { - return transformUpdateOperator(restValue, true); - } // Handle normal objects by recursing - - - return mapValues(restValue, transformInteriorValue); -}; - -const valueAsDate = value => { - if (typeof value === 'string') { - return new Date(value); - } else if (value instanceof Date) { - return value; - } - - return false; -}; - -function transformQueryKeyValue(className, key, value, schema, count = false) { - switch (key) { - case 'createdAt': - if (valueAsDate(value)) { - return { - key: '_created_at', - value: valueAsDate(value) - }; - } - - key = '_created_at'; - break; - - case 'updatedAt': - if (valueAsDate(value)) { - return { - key: '_updated_at', - value: valueAsDate(value) - }; - } - - key = '_updated_at'; - break; - - case 'expiresAt': - if (valueAsDate(value)) { - return { - key: 'expiresAt', - value: valueAsDate(value) - }; - } - - break; - - case '_email_verify_token_expires_at': - if (valueAsDate(value)) { - return { - key: '_email_verify_token_expires_at', - value: valueAsDate(value) - }; - } - - break; - - case 'objectId': - { - if (['_GlobalConfig', '_GraphQLConfig'].includes(className)) { - value = parseInt(value); - } - - return { - key: '_id', - value - }; - } - - case '_account_lockout_expires_at': - if (valueAsDate(value)) { - return { - key: '_account_lockout_expires_at', - value: valueAsDate(value) - }; - } - - break; - - case '_failed_login_count': - return { - key, - value - }; - - case 'sessionToken': - return { - key: '_session_token', - value - }; - - case '_perishable_token_expires_at': - if (valueAsDate(value)) { - return { - key: '_perishable_token_expires_at', - value: valueAsDate(value) - }; - } - - break; - - case '_password_changed_at': - if (valueAsDate(value)) { - return { - key: '_password_changed_at', - value: valueAsDate(value) - }; - } - - break; - - case '_rperm': - case '_wperm': - case '_perishable_token': - case '_email_verify_token': - return { - key, - value - }; - - case '$or': - case '$and': - case '$nor': - return { - key: key, - value: value.map(subQuery => transformWhere(className, subQuery, schema, count)) - }; - - case 'lastUsed': - if (valueAsDate(value)) { - return { - key: '_last_used', - value: valueAsDate(value) - }; - } - - key = '_last_used'; - break; - - case 'timesUsed': - return { - key: 'times_used', - value: value - }; - - default: - { - // Other auth data - const authDataMatch = key.match(/^authData\.([a-zA-Z0-9_]+)\.id$/); - - if (authDataMatch) { - const provider = authDataMatch[1]; // Special-case auth data. - - return { - key: `_auth_data_${provider}.id`, - value - }; - } - } - } - - const expectedTypeIsArray = schema && schema.fields[key] && schema.fields[key].type === 'Array'; - const expectedTypeIsPointer = schema && schema.fields[key] && schema.fields[key].type === 'Pointer'; - const field = schema && schema.fields[key]; - - if (expectedTypeIsPointer || !schema && value && value.__type === 'Pointer') { - key = '_p_' + key; - } // Handle query constraints - - - const transformedConstraint = transformConstraint(value, field, count); - - if (transformedConstraint !== CannotTransform) { - if (transformedConstraint.$text) { - return { - key: '$text', - value: transformedConstraint.$text - }; - } - - if (transformedConstraint.$elemMatch) { - return { - key: '$nor', - value: [{ - [key]: transformedConstraint - }] - }; - } - - return { - key, - value: transformedConstraint - }; - } - - if (expectedTypeIsArray && !(value instanceof Array)) { - return { - key, - value: { - $all: [transformInteriorAtom(value)] - } - }; - } // Handle atomic values - - - if (transformTopLevelAtom(value) !== CannotTransform) { - return { - key, - value: transformTopLevelAtom(value) - }; - } else { - throw new Parse.Error(Parse.Error.INVALID_JSON, `You cannot use ${value} as a query parameter.`); - } -} // Main exposed method to help run queries. -// restWhere is the "where" clause in REST API form. -// Returns the mongo form of the query. - - -function transformWhere(className, restWhere, schema, count = false) { - const mongoWhere = {}; - - for (const restKey in restWhere) { - const out = transformQueryKeyValue(className, restKey, restWhere[restKey], schema, count); - mongoWhere[out.key] = out.value; - } - - return mongoWhere; -} - -const parseObjectKeyValueToMongoObjectKeyValue = (restKey, restValue, schema) => { - // Check if the schema is known since it's a built-in field. - let transformedValue; - let coercedToDate; - - switch (restKey) { - case 'objectId': - return { - key: '_id', - value: restValue - }; - - case 'expiresAt': - transformedValue = transformTopLevelAtom(restValue); - coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; - return { - key: 'expiresAt', - value: coercedToDate - }; - - case '_email_verify_token_expires_at': - transformedValue = transformTopLevelAtom(restValue); - coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; - return { - key: '_email_verify_token_expires_at', - value: coercedToDate - }; - - case '_account_lockout_expires_at': - transformedValue = transformTopLevelAtom(restValue); - coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; - return { - key: '_account_lockout_expires_at', - value: coercedToDate - }; - - case '_perishable_token_expires_at': - transformedValue = transformTopLevelAtom(restValue); - coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; - return { - key: '_perishable_token_expires_at', - value: coercedToDate - }; - - case '_password_changed_at': - transformedValue = transformTopLevelAtom(restValue); - coercedToDate = typeof transformedValue === 'string' ? new Date(transformedValue) : transformedValue; - return { - key: '_password_changed_at', - value: coercedToDate - }; - - case '_failed_login_count': - case '_rperm': - case '_wperm': - case '_email_verify_token': - case '_hashed_password': - case '_perishable_token': - return { - key: restKey, - value: restValue - }; - - case 'sessionToken': - return { - key: '_session_token', - value: restValue - }; - - default: - // Auth data should have been transformed already - if (restKey.match(/^authData\.([a-zA-Z0-9_]+)\.id$/)) { - throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'can only query on ' + restKey); - } // Trust that the auth data has been transformed and save it directly - - - if (restKey.match(/^_auth_data_[a-zA-Z0-9_]+$/)) { - return { - key: restKey, - value: restValue - }; - } - - } //skip straight to transformTopLevelAtom for Bytes, they don't show up in the schema for some reason - - - if (restValue && restValue.__type !== 'Bytes') { - //Note: We may not know the type of a field here, as the user could be saving (null) to a field - //That never existed before, meaning we can't infer the type. - if (schema.fields[restKey] && schema.fields[restKey].type == 'Pointer' || restValue.__type == 'Pointer') { - restKey = '_p_' + restKey; - } - } // Handle atomic values - - - var value = transformTopLevelAtom(restValue); - - if (value !== CannotTransform) { - return { - key: restKey, - value: value - }; - } // ACLs are handled before this method is called - // If an ACL key still exists here, something is wrong. - - - if (restKey === 'ACL') { - throw 'There was a problem transforming an ACL.'; - } // Handle arrays - - - if (restValue instanceof Array) { - value = restValue.map(transformInteriorValue); - return { - key: restKey, - value: value - }; - } // Handle normal objects by recursing - - - if (Object.keys(restValue).some(key => key.includes('$') || key.includes('.'))) { - throw new Parse.Error(Parse.Error.INVALID_NESTED_KEY, "Nested keys should not contain the '$' or '.' characters"); - } - - value = mapValues(restValue, transformInteriorValue); - return { - key: restKey, - value - }; -}; - -const parseObjectToMongoObjectForCreate = (className, restCreate, schema) => { - restCreate = addLegacyACL(restCreate); - const mongoCreate = {}; - - for (const restKey in restCreate) { - if (restCreate[restKey] && restCreate[restKey].__type === 'Relation') { - continue; - } - - const { - key, - value - } = parseObjectKeyValueToMongoObjectKeyValue(restKey, restCreate[restKey], schema); - - if (value !== undefined) { - mongoCreate[key] = value; - } - } // Use the legacy mongo format for createdAt and updatedAt - - - if (mongoCreate.createdAt) { - mongoCreate._created_at = new Date(mongoCreate.createdAt.iso || mongoCreate.createdAt); - delete mongoCreate.createdAt; - } - - if (mongoCreate.updatedAt) { - mongoCreate._updated_at = new Date(mongoCreate.updatedAt.iso || mongoCreate.updatedAt); - delete mongoCreate.updatedAt; - } - - return mongoCreate; -}; // Main exposed method to help update old objects. - - -const transformUpdate = (className, restUpdate, parseFormatSchema) => { - const mongoUpdate = {}; - const acl = addLegacyACL(restUpdate); - - if (acl._rperm || acl._wperm || acl._acl) { - mongoUpdate.$set = {}; - - if (acl._rperm) { - mongoUpdate.$set._rperm = acl._rperm; - } - - if (acl._wperm) { - mongoUpdate.$set._wperm = acl._wperm; - } - - if (acl._acl) { - mongoUpdate.$set._acl = acl._acl; - } - } - - for (var restKey in restUpdate) { - if (restUpdate[restKey] && restUpdate[restKey].__type === 'Relation') { - continue; - } - - var out = transformKeyValueForUpdate(className, restKey, restUpdate[restKey], parseFormatSchema); // If the output value is an object with any $ keys, it's an - // operator that needs to be lifted onto the top level update - // object. - - if (typeof out.value === 'object' && out.value !== null && out.value.__op) { - mongoUpdate[out.value.__op] = mongoUpdate[out.value.__op] || {}; - mongoUpdate[out.value.__op][out.key] = out.value.arg; - } else { - mongoUpdate['$set'] = mongoUpdate['$set'] || {}; - mongoUpdate['$set'][out.key] = out.value; - } - } - - return mongoUpdate; -}; // Add the legacy _acl format. - - -const addLegacyACL = restObject => { - const restObjectCopy = _objectSpread({}, restObject); - - const _acl = {}; - - if (restObject._wperm) { - restObject._wperm.forEach(entry => { - _acl[entry] = { - w: true - }; - }); - - restObjectCopy._acl = _acl; - } - - if (restObject._rperm) { - restObject._rperm.forEach(entry => { - if (!(entry in _acl)) { - _acl[entry] = { - r: true - }; - } else { - _acl[entry].r = true; - } - }); - - restObjectCopy._acl = _acl; - } - - return restObjectCopy; -}; // A sentinel value that helper transformations return when they -// cannot perform a transformation - - -function CannotTransform() {} - -const transformInteriorAtom = atom => { - // TODO: check validity harder for the __type-defined types - if (typeof atom === 'object' && atom && !(atom instanceof Date) && atom.__type === 'Pointer') { - return { - __type: 'Pointer', - className: atom.className, - objectId: atom.objectId - }; - } else if (typeof atom === 'function' || typeof atom === 'symbol') { - throw new Parse.Error(Parse.Error.INVALID_JSON, `cannot transform value: ${atom}`); - } else if (DateCoder.isValidJSON(atom)) { - return DateCoder.JSONToDatabase(atom); - } else if (BytesCoder.isValidJSON(atom)) { - return BytesCoder.JSONToDatabase(atom); - } else if (typeof atom === 'object' && atom && atom.$regex !== undefined) { - return new RegExp(atom.$regex); - } else { - return atom; - } -}; // Helper function to transform an atom from REST format to Mongo format. -// An atom is anything that can't contain other expressions. So it -// includes things where objects are used to represent other -// datatypes, like pointers and dates, but it does not include objects -// or arrays with generic stuff inside. -// Raises an error if this cannot possibly be valid REST format. -// Returns CannotTransform if it's just not an atom - - -function transformTopLevelAtom(atom, field) { - switch (typeof atom) { - case 'number': - case 'boolean': - case 'undefined': - return atom; - - case 'string': - if (field && field.type === 'Pointer') { - return `${field.targetClass}$${atom}`; - } - - return atom; - - case 'symbol': - case 'function': - throw new Parse.Error(Parse.Error.INVALID_JSON, `cannot transform value: ${atom}`); - - case 'object': - if (atom instanceof Date) { - // Technically dates are not rest format, but, it seems pretty - // clear what they should be transformed to, so let's just do it. - return atom; - } - - if (atom === null) { - return atom; - } // TODO: check validity harder for the __type-defined types - - - if (atom.__type == 'Pointer') { - return `${atom.className}$${atom.objectId}`; - } - - if (DateCoder.isValidJSON(atom)) { - return DateCoder.JSONToDatabase(atom); - } - - if (BytesCoder.isValidJSON(atom)) { - return BytesCoder.JSONToDatabase(atom); - } - - if (GeoPointCoder.isValidJSON(atom)) { - return GeoPointCoder.JSONToDatabase(atom); - } - - if (PolygonCoder.isValidJSON(atom)) { - return PolygonCoder.JSONToDatabase(atom); - } - - if (FileCoder.isValidJSON(atom)) { - return FileCoder.JSONToDatabase(atom); - } - - return CannotTransform; - - default: - // I don't think typeof can ever let us get here - throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, `really did not expect value: ${atom}`); - } -} - -function relativeTimeToDate(text, now = new Date()) { - text = text.toLowerCase(); - let parts = text.split(' '); // Filter out whitespace - - parts = parts.filter(part => part !== ''); - const future = parts[0] === 'in'; - const past = parts[parts.length - 1] === 'ago'; - - if (!future && !past && text !== 'now') { - return { - status: 'error', - info: "Time should either start with 'in' or end with 'ago'" - }; - } - - if (future && past) { - return { - status: 'error', - info: "Time cannot have both 'in' and 'ago'" - }; - } // strip the 'ago' or 'in' - - - if (future) { - parts = parts.slice(1); - } else { - // past - parts = parts.slice(0, parts.length - 1); - } - - if (parts.length % 2 !== 0 && text !== 'now') { - return { - status: 'error', - info: 'Invalid time string. Dangling unit or number.' - }; - } - - const pairs = []; - - while (parts.length) { - pairs.push([parts.shift(), parts.shift()]); - } - - let seconds = 0; - - for (const [num, interval] of pairs) { - const val = Number(num); - - if (!Number.isInteger(val)) { - return { - status: 'error', - info: `'${num}' is not an integer.` - }; - } - - switch (interval) { - case 'yr': - case 'yrs': - case 'year': - case 'years': - seconds += val * 31536000; // 365 * 24 * 60 * 60 - - break; - - case 'wk': - case 'wks': - case 'week': - case 'weeks': - seconds += val * 604800; // 7 * 24 * 60 * 60 - - break; - - case 'd': - case 'day': - case 'days': - seconds += val * 86400; // 24 * 60 * 60 - - break; - - case 'hr': - case 'hrs': - case 'hour': - case 'hours': - seconds += val * 3600; // 60 * 60 - - break; - - case 'min': - case 'mins': - case 'minute': - case 'minutes': - seconds += val * 60; - break; - - case 'sec': - case 'secs': - case 'second': - case 'seconds': - seconds += val; - break; - - default: - return { - status: 'error', - info: `Invalid interval: '${interval}'` - }; - } - } - - const milliseconds = seconds * 1000; - - if (future) { - return { - status: 'success', - info: 'future', - result: new Date(now.valueOf() + milliseconds) - }; - } else if (past) { - return { - status: 'success', - info: 'past', - result: new Date(now.valueOf() - milliseconds) - }; - } else { - return { - status: 'success', - info: 'present', - result: new Date(now.valueOf()) - }; - } -} // Transforms a query constraint from REST API format to Mongo format. -// A constraint is something with fields like $lt. -// If it is not a valid constraint but it could be a valid something -// else, return CannotTransform. -// inArray is whether this is an array field. - - -function transformConstraint(constraint, field, count = false) { - const inArray = field && field.type && field.type === 'Array'; - - if (typeof constraint !== 'object' || !constraint) { - return CannotTransform; - } - - const transformFunction = inArray ? transformInteriorAtom : transformTopLevelAtom; - - const transformer = atom => { - const result = transformFunction(atom, field); - - if (result === CannotTransform) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `bad atom: ${JSON.stringify(atom)}`); - } - - return result; - }; // keys is the constraints in reverse alphabetical order. - // This is a hack so that: - // $regex is handled before $options - // $nearSphere is handled before $maxDistance - - - var keys = Object.keys(constraint).sort().reverse(); - var answer = {}; - - for (var key of keys) { - switch (key) { - case '$lt': - case '$lte': - case '$gt': - case '$gte': - case '$exists': - case '$ne': - case '$eq': - { - const val = constraint[key]; - - if (val && typeof val === 'object' && val.$relativeTime) { - if (field && field.type !== 'Date') { - throw new Parse.Error(Parse.Error.INVALID_JSON, '$relativeTime can only be used with Date field'); - } - - switch (key) { - case '$exists': - case '$ne': - case '$eq': - throw new Parse.Error(Parse.Error.INVALID_JSON, '$relativeTime can only be used with the $lt, $lte, $gt, and $gte operators'); - } - - const parserResult = relativeTimeToDate(val.$relativeTime); - - if (parserResult.status === 'success') { - answer[key] = parserResult.result; - break; - } - - _logger.default.info('Error while parsing relative date', parserResult); - - throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $relativeTime (${key}) value. ${parserResult.info}`); - } - - answer[key] = transformer(val); - break; - } - - case '$in': - case '$nin': - { - const arr = constraint[key]; - - if (!(arr instanceof Array)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad ' + key + ' value'); - } - - answer[key] = _lodash.default.flatMap(arr, value => { - return (atom => { - if (Array.isArray(atom)) { - return value.map(transformer); - } else { - return transformer(atom); - } - })(value); - }); - break; - } - - case '$all': - { - const arr = constraint[key]; - - if (!(arr instanceof Array)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad ' + key + ' value'); - } - - answer[key] = arr.map(transformInteriorAtom); - const values = answer[key]; - - if (isAnyValueRegex(values) && !isAllValuesRegexOrNone(values)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'All $all values must be of regex type or none: ' + values); - } - - break; - } - - case '$regex': - var s = constraint[key]; - - if (typeof s !== 'string') { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad regex: ' + s); - } - - answer[key] = s; - break; - - case '$containedBy': - { - const arr = constraint[key]; - - if (!(arr instanceof Array)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $containedBy: should be an array`); - } - - answer.$elemMatch = { - $nin: arr.map(transformer) - }; - break; - } - - case '$options': - answer[key] = constraint[key]; - break; - - case '$text': - { - const search = constraint[key].$search; - - if (typeof search !== 'object') { - throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $search, should be object`); - } - - if (!search.$term || typeof search.$term !== 'string') { - throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $term, should be string`); - } else { - answer[key] = { - $search: search.$term - }; - } - - if (search.$language && typeof search.$language !== 'string') { - throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $language, should be string`); - } else if (search.$language) { - answer[key].$language = search.$language; - } - - if (search.$caseSensitive && typeof search.$caseSensitive !== 'boolean') { - throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $caseSensitive, should be boolean`); - } else if (search.$caseSensitive) { - answer[key].$caseSensitive = search.$caseSensitive; - } - - if (search.$diacriticSensitive && typeof search.$diacriticSensitive !== 'boolean') { - throw new Parse.Error(Parse.Error.INVALID_JSON, `bad $text: $diacriticSensitive, should be boolean`); - } else if (search.$diacriticSensitive) { - answer[key].$diacriticSensitive = search.$diacriticSensitive; - } - - break; - } - - case '$nearSphere': - { - const point = constraint[key]; - - if (count) { - answer.$geoWithin = { - $centerSphere: [[point.longitude, point.latitude], constraint.$maxDistance] - }; - } else { - answer[key] = [point.longitude, point.latitude]; - } - - break; - } - - case '$maxDistance': - { - if (count) { - break; - } - - answer[key] = constraint[key]; - break; - } - // The SDKs don't seem to use these but they are documented in the - // REST API docs. - - case '$maxDistanceInRadians': - answer['$maxDistance'] = constraint[key]; - break; - - case '$maxDistanceInMiles': - answer['$maxDistance'] = constraint[key] / 3959; - break; - - case '$maxDistanceInKilometers': - answer['$maxDistance'] = constraint[key] / 6371; - break; - - case '$select': - case '$dontSelect': - throw new Parse.Error(Parse.Error.COMMAND_UNAVAILABLE, 'the ' + key + ' constraint is not supported yet'); - - case '$within': - var box = constraint[key]['$box']; - - if (!box || box.length != 2) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'malformatted $within arg'); - } - - answer[key] = { - $box: [[box[0].longitude, box[0].latitude], [box[1].longitude, box[1].latitude]] - }; - break; - - case '$geoWithin': - { - const polygon = constraint[key]['$polygon']; - const centerSphere = constraint[key]['$centerSphere']; - - if (polygon !== undefined) { - let points; - - if (typeof polygon === 'object' && polygon.__type === 'Polygon') { - if (!polygon.coordinates || polygon.coordinates.length < 3) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; Polygon.coordinates should contain at least 3 lon/lat pairs'); - } - - points = polygon.coordinates; - } else if (polygon instanceof Array) { - if (polygon.length < 3) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; $polygon should contain at least 3 GeoPoints'); - } - - points = polygon; - } else { - throw new Parse.Error(Parse.Error.INVALID_JSON, "bad $geoWithin value; $polygon should be Polygon object or Array of Parse.GeoPoint's"); - } - - points = points.map(point => { - if (point instanceof Array && point.length === 2) { - Parse.GeoPoint._validate(point[1], point[0]); - - return point; - } - - if (!GeoPointCoder.isValidJSON(point)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value'); - } else { - Parse.GeoPoint._validate(point.latitude, point.longitude); - } - - return [point.longitude, point.latitude]; - }); - answer[key] = { - $polygon: points - }; - } else if (centerSphere !== undefined) { - if (!(centerSphere instanceof Array) || centerSphere.length < 2) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere should be an array of Parse.GeoPoint and distance'); - } // Get point, convert to geo point if necessary and validate - - - let point = centerSphere[0]; - - if (point instanceof Array && point.length === 2) { - point = new Parse.GeoPoint(point[1], point[0]); - } else if (!GeoPointCoder.isValidJSON(point)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere geo point invalid'); - } - - Parse.GeoPoint._validate(point.latitude, point.longitude); // Get distance and validate - - - const distance = centerSphere[1]; - - if (isNaN(distance) || distance < 0) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere distance invalid'); - } - - answer[key] = { - $centerSphere: [[point.longitude, point.latitude], distance] - }; - } - - break; - } - - case '$geoIntersects': - { - const point = constraint[key]['$point']; - - if (!GeoPointCoder.isValidJSON(point)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad $geoIntersect value; $point should be GeoPoint'); - } else { - Parse.GeoPoint._validate(point.latitude, point.longitude); - } - - answer[key] = { - $geometry: { - type: 'Point', - coordinates: [point.longitude, point.latitude] - } - }; - break; - } - - default: - if (key.match(/^\$+/)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad constraint: ' + key); - } - - return CannotTransform; - } - } - - return answer; -} // Transforms an update operator from REST format to mongo format. -// To be transformed, the input should have an __op field. -// If flatten is true, this will flatten operators to their static -// data format. For example, an increment of 2 would simply become a -// 2. -// The output for a non-flattened operator is a hash with __op being -// the mongo op, and arg being the argument. -// The output for a flattened operator is just a value. -// Returns undefined if this should be a no-op. - - -function transformUpdateOperator({ - __op, - amount, - objects -}, flatten) { - switch (__op) { - case 'Delete': - if (flatten) { - return undefined; - } else { - return { - __op: '$unset', - arg: '' - }; - } - - case 'Increment': - if (typeof amount !== 'number') { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'incrementing must provide a number'); - } - - if (flatten) { - return amount; - } else { - return { - __op: '$inc', - arg: amount - }; - } - - case 'Add': - case 'AddUnique': - if (!(objects instanceof Array)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'objects to add must be an array'); - } - - var toAdd = objects.map(transformInteriorAtom); - - if (flatten) { - return toAdd; - } else { - var mongoOp = { - Add: '$push', - AddUnique: '$addToSet' - }[__op]; - return { - __op: mongoOp, - arg: { - $each: toAdd - } - }; - } - - case 'Remove': - if (!(objects instanceof Array)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'objects to remove must be an array'); - } - - var toRemove = objects.map(transformInteriorAtom); - - if (flatten) { - return []; - } else { - return { - __op: '$pullAll', - arg: toRemove - }; - } - - default: - throw new Parse.Error(Parse.Error.COMMAND_UNAVAILABLE, `The ${__op} operator is not supported yet.`); - } -} - -function mapValues(object, iterator) { - const result = {}; - Object.keys(object).forEach(key => { - result[key] = iterator(object[key]); - }); - return result; -} - -const nestedMongoObjectToNestedParseObject = mongoObject => { - switch (typeof mongoObject) { - case 'string': - case 'number': - case 'boolean': - case 'undefined': - return mongoObject; - - case 'symbol': - case 'function': - throw 'bad value in nestedMongoObjectToNestedParseObject'; - - case 'object': - if (mongoObject === null) { - return null; - } - - if (mongoObject instanceof Array) { - return mongoObject.map(nestedMongoObjectToNestedParseObject); - } - - if (mongoObject instanceof Date) { - return Parse._encode(mongoObject); - } - - if (mongoObject instanceof mongodb.Long) { - return mongoObject.toNumber(); - } - - if (mongoObject instanceof mongodb.Double) { - return mongoObject.value; - } - - if (BytesCoder.isValidDatabaseObject(mongoObject)) { - return BytesCoder.databaseToJSON(mongoObject); - } - - if (Object.prototype.hasOwnProperty.call(mongoObject, '__type') && mongoObject.__type == 'Date' && mongoObject.iso instanceof Date) { - mongoObject.iso = mongoObject.iso.toJSON(); - return mongoObject; - } - - return mapValues(mongoObject, nestedMongoObjectToNestedParseObject); - - default: - throw 'unknown js type'; - } -}; - -const transformPointerString = (schema, field, pointerString) => { - const objData = pointerString.split('$'); - - if (objData[0] !== schema.fields[field].targetClass) { - throw 'pointer to incorrect className'; - } - - return { - __type: 'Pointer', - className: objData[0], - objectId: objData[1] - }; -}; // Converts from a mongo-format object to a REST-format object. -// Does not strip out anything based on a lack of authentication. - - -const mongoObjectToParseObject = (className, mongoObject, schema) => { - switch (typeof mongoObject) { - case 'string': - case 'number': - case 'boolean': - case 'undefined': - return mongoObject; - - case 'symbol': - case 'function': - throw 'bad value in mongoObjectToParseObject'; - - case 'object': - { - if (mongoObject === null) { - return null; - } - - if (mongoObject instanceof Array) { - return mongoObject.map(nestedMongoObjectToNestedParseObject); - } - - if (mongoObject instanceof Date) { - return Parse._encode(mongoObject); - } - - if (mongoObject instanceof mongodb.Long) { - return mongoObject.toNumber(); - } - - if (mongoObject instanceof mongodb.Double) { - return mongoObject.value; - } - - if (BytesCoder.isValidDatabaseObject(mongoObject)) { - return BytesCoder.databaseToJSON(mongoObject); - } - - const restObject = {}; - - if (mongoObject._rperm || mongoObject._wperm) { - restObject._rperm = mongoObject._rperm || []; - restObject._wperm = mongoObject._wperm || []; - delete mongoObject._rperm; - delete mongoObject._wperm; - } - - for (var key in mongoObject) { - switch (key) { - case '_id': - restObject['objectId'] = '' + mongoObject[key]; - break; - - case '_hashed_password': - restObject._hashed_password = mongoObject[key]; - break; - - case '_acl': - break; - - case '_email_verify_token': - case '_perishable_token': - case '_perishable_token_expires_at': - case '_password_changed_at': - case '_tombstone': - case '_email_verify_token_expires_at': - case '_account_lockout_expires_at': - case '_failed_login_count': - case '_password_history': - // Those keys will be deleted if needed in the DB Controller - restObject[key] = mongoObject[key]; - break; - - case '_session_token': - restObject['sessionToken'] = mongoObject[key]; - break; - - case 'updatedAt': - case '_updated_at': - restObject['updatedAt'] = Parse._encode(new Date(mongoObject[key])).iso; - break; - - case 'createdAt': - case '_created_at': - restObject['createdAt'] = Parse._encode(new Date(mongoObject[key])).iso; - break; - - case 'expiresAt': - case '_expiresAt': - restObject['expiresAt'] = Parse._encode(new Date(mongoObject[key])); - break; - - case 'lastUsed': - case '_last_used': - restObject['lastUsed'] = Parse._encode(new Date(mongoObject[key])).iso; - break; - - case 'timesUsed': - case 'times_used': - restObject['timesUsed'] = mongoObject[key]; - break; - - case 'authData': - if (className === '_User') { - _logger.default.warn('ignoring authData in _User as this key is reserved to be synthesized of `_auth_data_*` keys'); - } else { - restObject['authData'] = mongoObject[key]; - } - - break; - - default: - // Check other auth data keys - var authDataMatch = key.match(/^_auth_data_([a-zA-Z0-9_]+)$/); - - if (authDataMatch && className === '_User') { - var provider = authDataMatch[1]; - restObject['authData'] = restObject['authData'] || {}; - restObject['authData'][provider] = mongoObject[key]; - break; - } - - if (key.indexOf('_p_') == 0) { - var newKey = key.substring(3); - - if (!schema.fields[newKey]) { - _logger.default.info('transform.js', 'Found a pointer column not in the schema, dropping it.', className, newKey); - - break; - } - - if (schema.fields[newKey].type !== 'Pointer') { - _logger.default.info('transform.js', 'Found a pointer in a non-pointer column, dropping it.', className, key); - - break; - } - - if (mongoObject[key] === null) { - break; - } - - restObject[newKey] = transformPointerString(schema, newKey, mongoObject[key]); - break; - } else if (key[0] == '_' && key != '__type') { - throw 'bad key in untransform: ' + key; - } else { - var value = mongoObject[key]; - - if (schema.fields[key] && schema.fields[key].type === 'File' && FileCoder.isValidDatabaseObject(value)) { - restObject[key] = FileCoder.databaseToJSON(value); - break; - } - - if (schema.fields[key] && schema.fields[key].type === 'GeoPoint' && GeoPointCoder.isValidDatabaseObject(value)) { - restObject[key] = GeoPointCoder.databaseToJSON(value); - break; - } - - if (schema.fields[key] && schema.fields[key].type === 'Polygon' && PolygonCoder.isValidDatabaseObject(value)) { - restObject[key] = PolygonCoder.databaseToJSON(value); - break; - } - - if (schema.fields[key] && schema.fields[key].type === 'Bytes' && BytesCoder.isValidDatabaseObject(value)) { - restObject[key] = BytesCoder.databaseToJSON(value); - break; - } - } - - restObject[key] = nestedMongoObjectToNestedParseObject(mongoObject[key]); - } - } - - const relationFieldNames = Object.keys(schema.fields).filter(fieldName => schema.fields[fieldName].type === 'Relation'); - const relationFields = {}; - relationFieldNames.forEach(relationFieldName => { - relationFields[relationFieldName] = { - __type: 'Relation', - className: schema.fields[relationFieldName].targetClass - }; - }); - return _objectSpread(_objectSpread({}, restObject), relationFields); - } - - default: - throw 'unknown js type'; - } -}; - -var DateCoder = { - JSONToDatabase(json) { - return new Date(json.iso); - }, - - isValidJSON(value) { - return typeof value === 'object' && value !== null && value.__type === 'Date'; - } - -}; -var BytesCoder = { - base64Pattern: new RegExp('^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$'), - - isBase64Value(object) { - if (typeof object !== 'string') { - return false; - } - - return this.base64Pattern.test(object); - }, - - databaseToJSON(object) { - let value; - - if (this.isBase64Value(object)) { - value = object; - } else { - value = object.buffer.toString('base64'); - } - - return { - __type: 'Bytes', - base64: value - }; - }, - - isValidDatabaseObject(object) { - return object instanceof mongodb.Binary || this.isBase64Value(object); - }, - - JSONToDatabase(json) { - return new mongodb.Binary(Buffer.from(json.base64, 'base64')); - }, - - isValidJSON(value) { - return typeof value === 'object' && value !== null && value.__type === 'Bytes'; - } - -}; -var GeoPointCoder = { - databaseToJSON(object) { - return { - __type: 'GeoPoint', - latitude: object[1], - longitude: object[0] - }; - }, - - isValidDatabaseObject(object) { - return object instanceof Array && object.length == 2; - }, - - JSONToDatabase(json) { - return [json.longitude, json.latitude]; - }, - - isValidJSON(value) { - return typeof value === 'object' && value !== null && value.__type === 'GeoPoint'; - } - -}; -var PolygonCoder = { - databaseToJSON(object) { - // Convert lng/lat -> lat/lng - const coords = object.coordinates[0].map(coord => { - return [coord[1], coord[0]]; - }); - return { - __type: 'Polygon', - coordinates: coords - }; - }, - - isValidDatabaseObject(object) { - const coords = object.coordinates[0]; - - if (object.type !== 'Polygon' || !(coords instanceof Array)) { - return false; - } - - for (let i = 0; i < coords.length; i++) { - const point = coords[i]; - - if (!GeoPointCoder.isValidDatabaseObject(point)) { - return false; - } - - Parse.GeoPoint._validate(parseFloat(point[1]), parseFloat(point[0])); - } - - return true; - }, - - JSONToDatabase(json) { - let coords = json.coordinates; // Add first point to the end to close polygon - - if (coords[0][0] !== coords[coords.length - 1][0] || coords[0][1] !== coords[coords.length - 1][1]) { - coords.push(coords[0]); - } - - const unique = coords.filter((item, index, ar) => { - let foundIndex = -1; - - for (let i = 0; i < ar.length; i += 1) { - const pt = ar[i]; - - if (pt[0] === item[0] && pt[1] === item[1]) { - foundIndex = i; - break; - } - } - - return foundIndex === index; - }); - - if (unique.length < 3) { - throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'GeoJSON: Loop must have at least 3 different vertices'); - } // Convert lat/long -> long/lat - - - coords = coords.map(coord => { - return [coord[1], coord[0]]; - }); - return { - type: 'Polygon', - coordinates: [coords] - }; - }, - - isValidJSON(value) { - return typeof value === 'object' && value !== null && value.__type === 'Polygon'; - } - -}; -var FileCoder = { - databaseToJSON(object) { - return { - __type: 'File', - name: object - }; - }, - - isValidDatabaseObject(object) { - return typeof object === 'string'; - }, - - JSONToDatabase(json) { - return json.name; - }, - - isValidJSON(value) { - return typeof value === 'object' && value !== null && value.__type === 'File'; - } - -}; -module.exports = { - transformKey, - parseObjectToMongoObjectForCreate, - transformUpdate, - transformWhere, - mongoObjectToParseObject, - relativeTimeToDate, - transformConstraint, - transformPointerString -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvVHJhbnNmb3JtLmpzIl0sIm5hbWVzIjpbIm1vbmdvZGIiLCJyZXF1aXJlIiwiUGFyc2UiLCJ0cmFuc2Zvcm1LZXkiLCJjbGFzc05hbWUiLCJmaWVsZE5hbWUiLCJzY2hlbWEiLCJmaWVsZHMiLCJfX3R5cGUiLCJ0eXBlIiwidHJhbnNmb3JtS2V5VmFsdWVGb3JVcGRhdGUiLCJyZXN0S2V5IiwicmVzdFZhbHVlIiwicGFyc2VGb3JtYXRTY2hlbWEiLCJrZXkiLCJ0aW1lRmllbGQiLCJpbmNsdWRlcyIsInZhbHVlIiwicGFyc2VJbnQiLCJ0cmFuc2Zvcm1Ub3BMZXZlbEF0b20iLCJDYW5ub3RUcmFuc2Zvcm0iLCJEYXRlIiwiaW5kZXhPZiIsIkFycmF5IiwibWFwIiwidHJhbnNmb3JtSW50ZXJpb3JWYWx1ZSIsInRyYW5zZm9ybVVwZGF0ZU9wZXJhdG9yIiwibWFwVmFsdWVzIiwiaXNSZWdleCIsIlJlZ0V4cCIsImlzU3RhcnRzV2l0aFJlZ2V4IiwibWF0Y2hlcyIsInRvU3RyaW5nIiwibWF0Y2giLCJpc0FsbFZhbHVlc1JlZ2V4T3JOb25lIiwidmFsdWVzIiwiaXNBcnJheSIsImxlbmd0aCIsImZpcnN0VmFsdWVzSXNSZWdleCIsImkiLCJpc0FueVZhbHVlUmVnZXgiLCJzb21lIiwiT2JqZWN0Iiwia2V5cyIsIkVycm9yIiwiSU5WQUxJRF9ORVNURURfS0VZIiwidHJhbnNmb3JtSW50ZXJpb3JBdG9tIiwidmFsdWVBc0RhdGUiLCJ0cmFuc2Zvcm1RdWVyeUtleVZhbHVlIiwiY291bnQiLCJzdWJRdWVyeSIsInRyYW5zZm9ybVdoZXJlIiwiYXV0aERhdGFNYXRjaCIsInByb3ZpZGVyIiwiZXhwZWN0ZWRUeXBlSXNBcnJheSIsImV4cGVjdGVkVHlwZUlzUG9pbnRlciIsImZpZWxkIiwidHJhbnNmb3JtZWRDb25zdHJhaW50IiwidHJhbnNmb3JtQ29uc3RyYWludCIsIiR0ZXh0IiwiJGVsZW1NYXRjaCIsIiRhbGwiLCJJTlZBTElEX0pTT04iLCJyZXN0V2hlcmUiLCJtb25nb1doZXJlIiwib3V0IiwicGFyc2VPYmplY3RLZXlWYWx1ZVRvTW9uZ29PYmplY3RLZXlWYWx1ZSIsInRyYW5zZm9ybWVkVmFsdWUiLCJjb2VyY2VkVG9EYXRlIiwiSU5WQUxJRF9LRVlfTkFNRSIsInBhcnNlT2JqZWN0VG9Nb25nb09iamVjdEZvckNyZWF0ZSIsInJlc3RDcmVhdGUiLCJhZGRMZWdhY3lBQ0wiLCJtb25nb0NyZWF0ZSIsInVuZGVmaW5lZCIsImNyZWF0ZWRBdCIsIl9jcmVhdGVkX2F0IiwiaXNvIiwidXBkYXRlZEF0IiwiX3VwZGF0ZWRfYXQiLCJ0cmFuc2Zvcm1VcGRhdGUiLCJyZXN0VXBkYXRlIiwibW9uZ29VcGRhdGUiLCJhY2wiLCJfcnBlcm0iLCJfd3Blcm0iLCJfYWNsIiwiJHNldCIsIl9fb3AiLCJhcmciLCJyZXN0T2JqZWN0IiwicmVzdE9iamVjdENvcHkiLCJmb3JFYWNoIiwiZW50cnkiLCJ3IiwiciIsImF0b20iLCJvYmplY3RJZCIsIkRhdGVDb2RlciIsImlzVmFsaWRKU09OIiwiSlNPTlRvRGF0YWJhc2UiLCJCeXRlc0NvZGVyIiwiJHJlZ2V4IiwidGFyZ2V0Q2xhc3MiLCJHZW9Qb2ludENvZGVyIiwiUG9seWdvbkNvZGVyIiwiRmlsZUNvZGVyIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwicmVsYXRpdmVUaW1lVG9EYXRlIiwidGV4dCIsIm5vdyIsInRvTG93ZXJDYXNlIiwicGFydHMiLCJzcGxpdCIsImZpbHRlciIsInBhcnQiLCJmdXR1cmUiLCJwYXN0Iiwic3RhdHVzIiwiaW5mbyIsInNsaWNlIiwicGFpcnMiLCJwdXNoIiwic2hpZnQiLCJzZWNvbmRzIiwibnVtIiwiaW50ZXJ2YWwiLCJ2YWwiLCJOdW1iZXIiLCJpc0ludGVnZXIiLCJtaWxsaXNlY29uZHMiLCJyZXN1bHQiLCJ2YWx1ZU9mIiwiY29uc3RyYWludCIsImluQXJyYXkiLCJ0cmFuc2Zvcm1GdW5jdGlvbiIsInRyYW5zZm9ybWVyIiwiSlNPTiIsInN0cmluZ2lmeSIsInNvcnQiLCJyZXZlcnNlIiwiYW5zd2VyIiwiJHJlbGF0aXZlVGltZSIsInBhcnNlclJlc3VsdCIsImxvZyIsImFyciIsIl8iLCJmbGF0TWFwIiwicyIsIiRuaW4iLCJzZWFyY2giLCIkc2VhcmNoIiwiJHRlcm0iLCIkbGFuZ3VhZ2UiLCIkY2FzZVNlbnNpdGl2ZSIsIiRkaWFjcml0aWNTZW5zaXRpdmUiLCJwb2ludCIsIiRnZW9XaXRoaW4iLCIkY2VudGVyU3BoZXJlIiwibG9uZ2l0dWRlIiwibGF0aXR1ZGUiLCIkbWF4RGlzdGFuY2UiLCJDT01NQU5EX1VOQVZBSUxBQkxFIiwiYm94IiwiJGJveCIsInBvbHlnb24iLCJjZW50ZXJTcGhlcmUiLCJwb2ludHMiLCJjb29yZGluYXRlcyIsIkdlb1BvaW50IiwiX3ZhbGlkYXRlIiwiJHBvbHlnb24iLCJkaXN0YW5jZSIsImlzTmFOIiwiJGdlb21ldHJ5IiwiYW1vdW50Iiwib2JqZWN0cyIsImZsYXR0ZW4iLCJ0b0FkZCIsIm1vbmdvT3AiLCJBZGQiLCJBZGRVbmlxdWUiLCIkZWFjaCIsInRvUmVtb3ZlIiwib2JqZWN0IiwiaXRlcmF0b3IiLCJuZXN0ZWRNb25nb09iamVjdFRvTmVzdGVkUGFyc2VPYmplY3QiLCJtb25nb09iamVjdCIsIl9lbmNvZGUiLCJMb25nIiwidG9OdW1iZXIiLCJEb3VibGUiLCJpc1ZhbGlkRGF0YWJhc2VPYmplY3QiLCJkYXRhYmFzZVRvSlNPTiIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInRvSlNPTiIsInRyYW5zZm9ybVBvaW50ZXJTdHJpbmciLCJwb2ludGVyU3RyaW5nIiwib2JqRGF0YSIsIm1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdCIsIl9oYXNoZWRfcGFzc3dvcmQiLCJ3YXJuIiwibmV3S2V5Iiwic3Vic3RyaW5nIiwicmVsYXRpb25GaWVsZE5hbWVzIiwicmVsYXRpb25GaWVsZHMiLCJyZWxhdGlvbkZpZWxkTmFtZSIsImpzb24iLCJiYXNlNjRQYXR0ZXJuIiwiaXNCYXNlNjRWYWx1ZSIsInRlc3QiLCJidWZmZXIiLCJiYXNlNjQiLCJCaW5hcnkiLCJCdWZmZXIiLCJmcm9tIiwiY29vcmRzIiwiY29vcmQiLCJwYXJzZUZsb2F0IiwidW5pcXVlIiwiaXRlbSIsImluZGV4IiwiYXIiLCJmb3VuZEluZGV4IiwicHQiLCJuYW1lIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTs7QUFDQTs7Ozs7Ozs7OztBQUNBLElBQUlBLE9BQU8sR0FBR0MsT0FBTyxDQUFDLFNBQUQsQ0FBckI7O0FBQ0EsSUFBSUMsS0FBSyxHQUFHRCxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCQyxLQUFsQzs7QUFFQSxNQUFNQyxZQUFZLEdBQUcsQ0FBQ0MsU0FBRCxFQUFZQyxTQUFaLEVBQXVCQyxNQUF2QixLQUFrQztBQUNyRDtBQUNBLFVBQVFELFNBQVI7QUFDRSxTQUFLLFVBQUw7QUFDRSxhQUFPLEtBQVA7O0FBQ0YsU0FBSyxXQUFMO0FBQ0UsYUFBTyxhQUFQOztBQUNGLFNBQUssV0FBTDtBQUNFLGFBQU8sYUFBUDs7QUFDRixTQUFLLGNBQUw7QUFDRSxhQUFPLGdCQUFQOztBQUNGLFNBQUssVUFBTDtBQUNFLGFBQU8sWUFBUDs7QUFDRixTQUFLLFdBQUw7QUFDRSxhQUFPLFlBQVA7QUFaSjs7QUFlQSxNQUFJQyxNQUFNLENBQUNDLE1BQVAsQ0FBY0YsU0FBZCxLQUE0QkMsTUFBTSxDQUFDQyxNQUFQLENBQWNGLFNBQWQsRUFBeUJHLE1BQXpCLElBQW1DLFNBQW5FLEVBQThFO0FBQzVFSCxJQUFBQSxTQUFTLEdBQUcsUUFBUUEsU0FBcEI7QUFDRCxHQUZELE1BRU8sSUFBSUMsTUFBTSxDQUFDQyxNQUFQLENBQWNGLFNBQWQsS0FBNEJDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjRixTQUFkLEVBQXlCSSxJQUF6QixJQUFpQyxTQUFqRSxFQUE0RTtBQUNqRkosSUFBQUEsU0FBUyxHQUFHLFFBQVFBLFNBQXBCO0FBQ0Q7O0FBRUQsU0FBT0EsU0FB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QUFDa0IsSUFBWjtBQUNELEdBZGE7O0FBZ0JkaEksRUFBQUEsV0FBVyxDQUFDbEYsS0FBRCxFQUFRO0FBQ2pCLFdBQU8sT0FBT0EsS0FBUCxLQUFpQixRQUFqQixJQUE2QkEsS0FBSyxLQUFLLElBQXZDLElBQStDQSxLQUFLLENBQUNULE1BQU4sS0FBaUIsTUFBdkU7QUFDRDs7QUFsQmEsQ0FBaEI7QUFxQkE0TixNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZmxPLEVBQUFBLFlBRGU7QUFFZm1FLEVBQUFBLGlDQUZlO0FBR2ZVLEVBQUFBLGVBSGU7QUFJZjdCLEVBQUFBLGNBSmU7QUFLZnNKLEVBQUFBLHdCQUxlO0FBTWY3RixFQUFBQSxrQkFOZTtBQU9mbEQsRUFBQUEsbUJBUGU7QUFRZjRJLEVBQUFBO0FBUmUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgbG9nIGZyb20gJy4uLy4uLy4uL2xvZ2dlcic7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xudmFyIG1vbmdvZGIgPSByZXF1aXJlKCdtb25nb2RiJyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbmNvbnN0IHRyYW5zZm9ybUtleSA9IChjbGFzc05hbWUsIGZpZWxkTmFtZSwgc2NoZW1hKSA9PiB7XG4gIC8vIENoZWNrIGlmIHRoZSBzY2hlbWEgaXMga25vd24gc2luY2UgaXQncyBhIGJ1aWx0LWluIGZpZWxkLlxuICBzd2l0Y2ggKGZpZWxkTmFtZSkge1xuICAgIGNhc2UgJ29iamVjdElkJzpcbiAgICAgIHJldHVybiAnX2lkJztcbiAgICBjYXNlICdjcmVhdGVkQXQnOlxuICAgICAgcmV0dXJuICdfY3JlYXRlZF9hdCc7XG4gICAgY2FzZSAndXBkYXRlZEF0JzpcbiAgICAgIHJldHVybiAnX3VwZGF0ZWRfYXQnO1xuICAgIGNhc2UgJ3Nlc3Npb25Ub2tlbic6XG4gICAgICByZXR1cm4gJ19zZXNzaW9uX3Rva2VuJztcbiAgICBjYXNlICdsYXN0VXNlZCc6XG4gICAgICByZXR1cm4gJ19sYXN0X3VzZWQnO1xuICAgIGNhc2UgJ3RpbWVzVXNlZCc6XG4gICAgICByZXR1cm4gJ3RpbWVzX3VzZWQnO1xuICB9XG5cbiAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0uX190eXBlID09ICdQb2ludGVyJykge1xuICAgIGZpZWxkTmFtZSA9ICdfcF8nICsgZmllbGROYW1lO1xuICB9IGVsc2UgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PSAnUG9pbnRlcicpIHtcbiAgICBmaWVsZE5hbWUgPSAnX3BfJyArIGZpZWxkTmFtZTtcbiAgfVxuXG4gIHJldHVybiBmaWVsZE5hbWU7XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1LZXlWYWx1ZUZvclVwZGF0ZSA9IChjbGFzc05hbWUsIHJlc3RLZXksIHJlc3RWYWx1ZSwgcGFyc2VGb3JtYXRTY2hlbWEpID0+IHtcbiAgLy8gQ2hlY2sgaWYgdGhlIHNjaGVtYSBpcyBrbm93biBzaW5jZSBpdCdzIGEgYnVpbHQtaW4gZmllbGQuXG4gIHZhciBrZXkgPSByZXN0S2V5O1xuICB2YXIgdGltZUZpZWxkID0gZmFsc2U7XG4gIHN3aXRjaCAoa2V5KSB7XG4gICAgY2FzZSAnb2JqZWN0SWQnOlxuICAgIGNhc2UgJ19pZCc6XG4gICAgICBpZiAoWydfR2xvYmFsQ29uZmlnJywgJ19HcmFwaFFMQ29uZmlnJ10uaW5jbHVkZXMoY2xhc3NOYW1lKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgIHZhbHVlOiBwYXJzZUludChyZXN0VmFsdWUpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAga2V5ID0gJ19pZCc7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdjcmVhdGVkQXQnOlxuICAgIGNhc2UgJ19jcmVhdGVkX2F0JzpcbiAgICAgIGtleSA9ICdfY3JlYXRlZF9hdCc7XG4gICAgICB0aW1lRmllbGQgPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndXBkYXRlZEF0JzpcbiAgICBjYXNlICdfdXBkYXRlZF9hdCc6XG4gICAgICBrZXkgPSAnX3VwZGF0ZWRfYXQnO1xuICAgICAgdGltZUZpZWxkID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3Nlc3Npb25Ub2tlbic6XG4gICAgY2FzZSAnX3Nlc3Npb25fdG9rZW4nOlxuICAgICAga2V5ID0gJ19zZXNzaW9uX3Rva2VuJztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2V4cGlyZXNBdCc6XG4gICAgY2FzZSAnX2V4cGlyZXNBdCc6XG4gICAgICBrZXkgPSAnZXhwaXJlc0F0JztcbiAgICAgIHRpbWVGaWVsZCA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnOlxuICAgICAga2V5ID0gJ19lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCc7XG4gICAgICB0aW1lRmllbGQgPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JzpcbiAgICAgIGtleSA9ICdfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQnO1xuICAgICAgdGltZUZpZWxkID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ19mYWlsZWRfbG9naW5fY291bnQnOlxuICAgICAga2V5ID0gJ19mYWlsZWRfbG9naW5fY291bnQnO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCc6XG4gICAgICBrZXkgPSAnX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCc7XG4gICAgICB0aW1lRmllbGQgPSB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX3Bhc3N3b3JkX2NoYW5nZWRfYXQnOlxuICAgICAga2V5ID0gJ19wYXNzd29yZF9jaGFuZ2VkX2F0JztcbiAgICAgIHRpbWVGaWVsZCA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdfcnBlcm0nOlxuICAgIGNhc2UgJ193cGVybSc6XG4gICAgICByZXR1cm4geyBrZXk6IGtleSwgdmFsdWU6IHJlc3RWYWx1ZSB9O1xuICAgIGNhc2UgJ2xhc3RVc2VkJzpcbiAgICBjYXNlICdfbGFzdF91c2VkJzpcbiAgICAgIGtleSA9ICdfbGFzdF91c2VkJztcbiAgICAgIHRpbWVGaWVsZCA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd0aW1lc1VzZWQnOlxuICAgIGNhc2UgJ3RpbWVzX3VzZWQnOlxuICAgICAga2V5ID0gJ3RpbWVzX3VzZWQnO1xuICAgICAgdGltZUZpZWxkID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgaWYgKFxuICAgIChwYXJzZUZvcm1hdFNjaGVtYS5maWVsZHNba2V5XSAmJiBwYXJzZUZvcm1hdFNjaGVtYS5maWVsZHNba2V5XS50eXBlID09PSAnUG9pbnRlcicpIHx8XG4gICAgKCFwYXJzZUZvcm1hdFNjaGVtYS5maWVsZHNba2V5XSAmJiByZXN0VmFsdWUgJiYgcmVzdFZhbHVlLl9fdHlwZSA9PSAnUG9pbnRlcicpXG4gICkge1xuICAgIGtleSA9ICdfcF8nICsga2V5O1xuICB9XG5cbiAgLy8gSGFuZGxlIGF0b21pYyB2YWx1ZXNcbiAgdmFyIHZhbHVlID0gdHJhbnNmb3JtVG9wTGV2ZWxBdG9tKHJlc3RWYWx1ZSk7XG4gIGlmICh2YWx1ZSAhPT0gQ2Fubm90VHJhbnNmb3JtKSB7XG4gICAgaWYgKHRpbWVGaWVsZCAmJiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICB2YWx1ZSA9IG5ldyBEYXRlKHZhbHVlKTtcbiAgICB9XG4gICAgaWYgKHJlc3RLZXkuaW5kZXhPZignLicpID4gMCkge1xuICAgICAgcmV0dXJuIHsga2V5LCB2YWx1ZTogcmVzdFZhbHVlIH07XG4gICAgfVxuICAgIHJldHVybiB7IGtleSwgdmFsdWUgfTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBhcnJheXNcbiAgaWYgKHJlc3RWYWx1ZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgdmFsdWUgPSByZXN0VmFsdWUubWFwKHRyYW5zZm9ybUludGVyaW9yVmFsdWUpO1xuICAgIHJldHVybiB7IGtleSwgdmFsdWUgfTtcbiAgfVxuXG4gIC8vIEhhbmRsZSB1cGRhdGUgb3BlcmF0b3JzXG4gIGlmICh0eXBlb2YgcmVzdFZhbHVlID09PSAnb2JqZWN0JyAmJiAnX19vcCcgaW4gcmVzdFZhbHVlKSB7XG4gICAgcmV0dXJuIHsga2V5LCB2YWx1ZTogdHJhbnNmb3JtVXBkYXRlT3BlcmF0b3IocmVzdFZhbHVlLCBmYWxzZSkgfTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBub3JtYWwgb2JqZWN0cyBieSByZWN1cnNpbmdcbiAgdmFsdWUgPSBtYXBWYWx1ZXMocmVzdFZhbHVlLCB0cmFuc2Zvcm1JbnRlcmlvclZhbHVlKTtcbiAgcmV0dXJuIHsga2V5LCB2YWx1ZSB9O1xufTtcblxuY29uc3QgaXNSZWdleCA9IHZhbHVlID0+IHtcbiAgcmV0dXJuIHZhbHVlICYmIHZhbHVlIGluc3RhbmNlb2YgUmVnRXhwO1xufTtcblxuY29uc3QgaXNTdGFydHNXaXRoUmVnZXggPSB2YWx1ZSA9PiB7XG4gIGlmICghaXNSZWdleCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBtYXRjaGVzID0gdmFsdWUudG9TdHJpbmcoKS5tYXRjaCgvXFwvXFxeXFxcXFEuKlxcXFxFXFwvLyk7XG4gIHJldHVybiAhIW1hdGNoZXM7XG59O1xuXG5jb25zdCBpc0FsbFZhbHVlc1JlZ2V4T3JOb25lID0gdmFsdWVzID0+IHtcbiAgaWYgKCF2YWx1ZXMgfHwgIUFycmF5LmlzQXJyYXkodmFsdWVzKSB8fCB2YWx1ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBjb25zdCBmaXJzdFZhbHVlc0lzUmVnZXggPSBpc1N0YXJ0c1dpdGhSZWdleCh2YWx1ZXNbMF0pO1xuICBpZiAodmFsdWVzLmxlbmd0aCA9PT0gMSkge1xuICAgIHJldHVybiBmaXJzdFZhbHVlc0lzUmVnZXg7XG4gIH1cblxuICBmb3IgKGxldCBpID0gMSwgbGVuZ3RoID0gdmFsdWVzLmxlbmd0aDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGZpcnN0VmFsdWVzSXNSZWdleCAhPT0gaXNTdGFydHNXaXRoUmVnZXgodmFsdWVzW2ldKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuY29uc3QgaXNBbnlWYWx1ZVJlZ2V4ID0gdmFsdWVzID0+IHtcbiAgcmV0dXJuIHZhbHVlcy5zb21lKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiBpc1JlZ2V4KHZhbHVlKTtcbiAgfSk7XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1JbnRlcmlvclZhbHVlID0gcmVzdFZhbHVlID0+IHtcbiAgaWYgKFxuICAgIHJlc3RWYWx1ZSAhPT0gbnVsbCAmJlxuICAgIHR5cGVvZiByZXN0VmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgT2JqZWN0LmtleXMocmVzdFZhbHVlKS5zb21lKGtleSA9PiBrZXkuaW5jbHVkZXMoJyQnKSB8fCBrZXkuaW5jbHVkZXMoJy4nKSlcbiAgKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9ORVNURURfS0VZLFxuICAgICAgXCJOZXN0ZWQga2V5cyBzaG91bGQgbm90IGNvbnRhaW4gdGhlICckJyBvciAnLicgY2hhcmFjdGVyc1wiXG4gICAgKTtcbiAgfVxuICAvLyBIYW5kbGUgYXRvbWljIHZhbHVlc1xuICB2YXIgdmFsdWUgPSB0cmFuc2Zvcm1JbnRlcmlvckF0b20ocmVzdFZhbHVlKTtcbiAgaWYgKHZhbHVlICE9PSBDYW5ub3RUcmFuc2Zvcm0pIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICAvLyBIYW5kbGUgYXJyYXlzXG4gIGlmIChyZXN0VmFsdWUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgIHJldHVybiByZXN0VmFsdWUubWFwKHRyYW5zZm9ybUludGVyaW9yVmFsdWUpO1xuICB9XG5cbiAgLy8gSGFuZGxlIHVwZGF0ZSBvcGVyYXRvcnNcbiAgaWYgKHR5cGVvZiByZXN0VmFsdWUgPT09ICdvYmplY3QnICYmICdfX29wJyBpbiByZXN0VmFsdWUpIHtcbiAgICByZXR1cm4gdHJhbnNmb3JtVXBkYXRlT3BlcmF0b3IocmVzdFZhbHVlLCB0cnVlKTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBub3JtYWwgb2JqZWN0cyBieSByZWN1cnNpbmdcbiAgcmV0dXJuIG1hcFZhbHVlcyhyZXN0VmFsdWUsIHRyYW5zZm9ybUludGVyaW9yVmFsdWUpO1xufTtcblxuY29uc3QgdmFsdWVBc0RhdGUgPSB2YWx1ZSA9PiB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKHZhbHVlKTtcbiAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuZnVuY3Rpb24gdHJhbnNmb3JtUXVlcnlLZXlWYWx1ZShjbGFzc05hbWUsIGtleSwgdmFsdWUsIHNjaGVtYSwgY291bnQgPSBmYWxzZSkge1xuICBzd2l0Y2ggKGtleSkge1xuICAgIGNhc2UgJ2NyZWF0ZWRBdCc6XG4gICAgICBpZiAodmFsdWVBc0RhdGUodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB7IGtleTogJ19jcmVhdGVkX2F0JywgdmFsdWU6IHZhbHVlQXNEYXRlKHZhbHVlKSB9O1xuICAgICAgfVxuICAgICAga2V5ID0gJ19jcmVhdGVkX2F0JztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3VwZGF0ZWRBdCc6XG4gICAgICBpZiAodmFsdWVBc0RhdGUodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB7IGtleTogJ191cGRhdGVkX2F0JywgdmFsdWU6IHZhbHVlQXNEYXRlKHZhbHVlKSB9O1xuICAgICAgfVxuICAgICAga2V5ID0gJ191cGRhdGVkX2F0JztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2V4cGlyZXNBdCc6XG4gICAgICBpZiAodmFsdWVBc0RhdGUodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB7IGtleTogJ2V4cGlyZXNBdCcsIHZhbHVlOiB2YWx1ZUFzRGF0ZSh2YWx1ZSkgfTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ19lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCc6XG4gICAgICBpZiAodmFsdWVBc0RhdGUodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAga2V5OiAnX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0JyxcbiAgICAgICAgICB2YWx1ZTogdmFsdWVBc0RhdGUodmFsdWUpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnb2JqZWN0SWQnOiB7XG4gICAgICBpZiAoWydfR2xvYmFsQ29uZmlnJywgJ19HcmFwaFFMQ29uZmlnJ10uaW5jbHVkZXMoY2xhc3NOYW1lKSkge1xuICAgICAgICB2YWx1ZSA9IHBhcnNlSW50KHZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7IGtleTogJ19pZCcsIHZhbHVlIH07XG4gICAgfVxuICAgIGNhc2UgJ19hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCc6XG4gICAgICBpZiAodmFsdWVBc0RhdGUodmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAga2V5OiAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JyxcbiAgICAgICAgICB2YWx1ZTogdmFsdWVBc0RhdGUodmFsdWUpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX2ZhaWxlZF9sb2dpbl9jb3VudCc6XG4gICAgICByZXR1cm4geyBrZXksIHZhbHVlIH07XG4gICAgY2FzZSAnc2Vzc2lvblRva2VuJzpcbiAgICAgIHJldHVybiB7IGtleTogJ19zZXNzaW9uX3Rva2VuJywgdmFsdWUgfTtcbiAgICBjYXNlICdfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0JzpcbiAgICAgIGlmICh2YWx1ZUFzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBrZXk6ICdfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0JyxcbiAgICAgICAgICB2YWx1ZTogdmFsdWVBc0RhdGUodmFsdWUpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnX3Bhc3N3b3JkX2NoYW5nZWRfYXQnOlxuICAgICAgaWYgKHZhbHVlQXNEYXRlKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4geyBrZXk6ICdfcGFzc3dvcmRfY2hhbmdlZF9hdCcsIHZhbHVlOiB2YWx1ZUFzRGF0ZSh2YWx1ZSkgfTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ19ycGVybSc6XG4gICAgY2FzZSAnX3dwZXJtJzpcbiAgICBjYXNlICdfcGVyaXNoYWJsZV90b2tlbic6XG4gICAgY2FzZSAnX2VtYWlsX3ZlcmlmeV90b2tlbic6XG4gICAgICByZXR1cm4geyBrZXksIHZhbHVlIH07XG4gICAgY2FzZSAnJG9yJzpcbiAgICBjYXNlICckYW5kJzpcbiAgICBjYXNlICckbm9yJzpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGtleToga2V5LFxuICAgICAgICB2YWx1ZTogdmFsdWUubWFwKHN1YlF1ZXJ5ID0+IHRyYW5zZm9ybVdoZXJlKGNsYXNzTmFtZSwgc3ViUXVlcnksIHNjaGVtYSwgY291bnQpKSxcbiAgICAgIH07XG4gICAgY2FzZSAnbGFzdFVzZWQnOlxuICAgICAgaWYgKHZhbHVlQXNEYXRlKHZhbHVlKSkge1xuICAgICAgICByZXR1cm4geyBrZXk6ICdfbGFzdF91c2VkJywgdmFsdWU6IHZhbHVlQXNEYXRlKHZhbHVlKSB9O1xuICAgICAgfVxuICAgICAga2V5ID0gJ19sYXN0X3VzZWQnO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndGltZXNVc2VkJzpcbiAgICAgIHJldHVybiB7IGtleTogJ3RpbWVzX3VzZWQnLCB2YWx1ZTogdmFsdWUgfTtcbiAgICBkZWZhdWx0OiB7XG4gICAgICAvLyBPdGhlciBhdXRoIGRhdGFcbiAgICAgIGNvbnN0IGF1dGhEYXRhTWF0Y2ggPSBrZXkubWF0Y2goL15hdXRoRGF0YVxcLihbYS16QS1aMC05X10rKVxcLmlkJC8pO1xuICAgICAgaWYgKGF1dGhEYXRhTWF0Y2gpIHtcbiAgICAgICAgY29uc3QgcHJvdmlkZXIgPSBhdXRoRGF0YU1hdGNoWzFdO1xuICAgICAgICAvLyBTcGVjaWFsLWNhc2UgYXV0aCBkYXRhLlxuICAgICAgICByZXR1cm4geyBrZXk6IGBfYXV0aF9kYXRhXyR7cHJvdmlkZXJ9LmlkYCwgdmFsdWUgfTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBleHBlY3RlZFR5cGVJc0FycmF5ID0gc2NoZW1hICYmIHNjaGVtYS5maWVsZHNba2V5XSAmJiBzY2hlbWEuZmllbGRzW2tleV0udHlwZSA9PT0gJ0FycmF5JztcblxuICBjb25zdCBleHBlY3RlZFR5cGVJc1BvaW50ZXIgPVxuICAgIHNjaGVtYSAmJiBzY2hlbWEuZmllbGRzW2tleV0gJiYgc2NoZW1hLmZpZWxkc1trZXldLnR5cGUgPT09ICdQb2ludGVyJztcblxuICBjb25zdCBmaWVsZCA9IHNjaGVtYSAmJiBzY2hlbWEuZmllbGRzW2tleV07XG4gIGlmIChleHBlY3RlZFR5cGVJc1BvaW50ZXIgfHwgKCFzY2hlbWEgJiYgdmFsdWUgJiYgdmFsdWUuX190eXBlID09PSAnUG9pbnRlcicpKSB7XG4gICAga2V5ID0gJ19wXycgKyBrZXk7XG4gIH1cblxuICAvLyBIYW5kbGUgcXVlcnkgY29uc3RyYWludHNcbiAgY29uc3QgdHJhbnNmb3JtZWRDb25zdHJhaW50ID0gdHJhbnNmb3JtQ29uc3RyYWludCh2YWx1ZSwgZmllbGQsIGNvdW50KTtcbiAgaWYgKHRyYW5zZm9ybWVkQ29uc3RyYWludCAhPT0gQ2Fubm90VHJhbnNmb3JtKSB7XG4gICAgaWYgKHRyYW5zZm9ybWVkQ29uc3RyYWludC4kdGV4dCkge1xuICAgICAgcmV0dXJuIHsga2V5OiAnJHRleHQnLCB2YWx1ZTogdHJhbnNmb3JtZWRDb25zdHJhaW50LiR0ZXh0IH07XG4gICAgfVxuICAgIGlmICh0cmFuc2Zvcm1lZENvbnN0cmFpbnQuJGVsZW1NYXRjaCkge1xuICAgICAgcmV0dXJuIHsga2V5OiAnJG5vcicsIHZhbHVlOiBbeyBba2V5XTogdHJhbnNmb3JtZWRDb25zdHJhaW50IH1dIH07XG4gICAgfVxuICAgIHJldHVybiB7IGtleSwgdmFsdWU6IHRyYW5zZm9ybWVkQ29uc3RyYWludCB9O1xuICB9XG5cbiAgaWYgKGV4cGVjdGVkVHlwZUlzQXJyYXkgJiYgISh2YWx1ZSBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgIHJldHVybiB7IGtleSwgdmFsdWU6IHsgJGFsbDogW3RyYW5zZm9ybUludGVyaW9yQXRvbSh2YWx1ZSldIH0gfTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBhdG9taWMgdmFsdWVzXG4gIGlmICh0cmFuc2Zvcm1Ub3BMZXZlbEF0b20odmFsdWUpICE9PSBDYW5ub3RUcmFuc2Zvcm0pIHtcbiAgICByZXR1cm4geyBrZXksIHZhbHVlOiB0cmFuc2Zvcm1Ub3BMZXZlbEF0b20odmFsdWUpIH07XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgYFlvdSBjYW5ub3QgdXNlICR7dmFsdWV9IGFzIGEgcXVlcnkgcGFyYW1ldGVyLmBcbiAgICApO1xuICB9XG59XG5cbi8vIE1haW4gZXhwb3NlZCBtZXRob2QgdG8gaGVscCBydW4gcXVlcmllcy5cbi8vIHJlc3RXaGVyZSBpcyB0aGUgXCJ3aGVyZVwiIGNsYXVzZSBpbiBSRVNUIEFQSSBmb3JtLlxuLy8gUmV0dXJucyB0aGUgbW9uZ28gZm9ybSBvZiB0aGUgcXVlcnkuXG5mdW5jdGlvbiB0cmFuc2Zvcm1XaGVyZShjbGFzc05hbWUsIHJlc3RXaGVyZSwgc2NoZW1hLCBjb3VudCA9IGZhbHNlKSB7XG4gIGNvbnN0IG1vbmdvV2hlcmUgPSB7fTtcbiAgZm9yIChjb25zdCByZXN0S2V5IGluIHJlc3RXaGVyZSkge1xuICAgIGNvbnN0IG91dCA9IHRyYW5zZm9ybVF1ZXJ5S2V5VmFsdWUoY2xhc3NOYW1lLCByZXN0S2V5LCByZXN0V2hlcmVbcmVzdEtleV0sIHNjaGVtYSwgY291bnQpO1xuICAgIG1vbmdvV2hlcmVbb3V0LmtleV0gPSBvdXQudmFsdWU7XG4gIH1cbiAgcmV0dXJuIG1vbmdvV2hlcmU7XG59XG5cbmNvbnN0IHBhcnNlT2JqZWN0S2V5VmFsdWVUb01vbmdvT2JqZWN0S2V5VmFsdWUgPSAocmVzdEtleSwgcmVzdFZhbHVlLCBzY2hlbWEpID0+IHtcbiAgLy8gQ2hlY2sgaWYgdGhlIHNjaGVtYSBpcyBrbm93biBzaW5jZSBpdCdzIGEgYnVpbHQtaW4gZmllbGQuXG4gIGxldCB0cmFuc2Zvcm1lZFZhbHVlO1xuICBsZXQgY29lcmNlZFRvRGF0ZTtcbiAgc3dpdGNoIChyZXN0S2V5KSB7XG4gICAgY2FzZSAnb2JqZWN0SWQnOlxuICAgICAgcmV0dXJuIHsga2V5OiAnX2lkJywgdmFsdWU6IHJlc3RWYWx1ZSB9O1xuICAgIGNhc2UgJ2V4cGlyZXNBdCc6XG4gICAgICB0cmFuc2Zvcm1lZFZhbHVlID0gdHJhbnNmb3JtVG9wTGV2ZWxBdG9tKHJlc3RWYWx1ZSk7XG4gICAgICBjb2VyY2VkVG9EYXRlID1cbiAgICAgICAgdHlwZW9mIHRyYW5zZm9ybWVkVmFsdWUgPT09ICdzdHJpbmcnID8gbmV3IERhdGUodHJhbnNmb3JtZWRWYWx1ZSkgOiB0cmFuc2Zvcm1lZFZhbHVlO1xuICAgICAgcmV0dXJuIHsga2V5OiAnZXhwaXJlc0F0JywgdmFsdWU6IGNvZXJjZWRUb0RhdGUgfTtcbiAgICBjYXNlICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnOlxuICAgICAgdHJhbnNmb3JtZWRWYWx1ZSA9IHRyYW5zZm9ybVRvcExldmVsQXRvbShyZXN0VmFsdWUpO1xuICAgICAgY29lcmNlZFRvRGF0ZSA9XG4gICAgICAgIHR5cGVvZiB0cmFuc2Zvcm1lZFZhbHVlID09PSAnc3RyaW5nJyA/IG5ldyBEYXRlKHRyYW5zZm9ybWVkVmFsdWUpIDogdHJhbnNmb3JtZWRWYWx1ZTtcbiAgICAgIHJldHVybiB7IGtleTogJ19lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCcsIHZhbHVlOiBjb2VyY2VkVG9EYXRlIH07XG4gICAgY2FzZSAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JzpcbiAgICAgIHRyYW5zZm9ybWVkVmFsdWUgPSB0cmFuc2Zvcm1Ub3BMZXZlbEF0b20ocmVzdFZhbHVlKTtcbiAgICAgIGNvZXJjZWRUb0RhdGUgPVxuICAgICAgICB0eXBlb2YgdHJhbnNmb3JtZWRWYWx1ZSA9PT0gJ3N0cmluZycgPyBuZXcgRGF0ZSh0cmFuc2Zvcm1lZFZhbHVlKSA6IHRyYW5zZm9ybWVkVmFsdWU7XG4gICAgICByZXR1cm4geyBrZXk6ICdfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQnLCB2YWx1ZTogY29lcmNlZFRvRGF0ZSB9O1xuICAgIGNhc2UgJ19wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQnOlxuICAgICAgdHJhbnNmb3JtZWRWYWx1ZSA9IHRyYW5zZm9ybVRvcExldmVsQXRvbShyZXN0VmFsdWUpO1xuICAgICAgY29lcmNlZFRvRGF0ZSA9XG4gICAgICAgIHR5cGVvZiB0cmFuc2Zvcm1lZFZhbHVlID09PSAnc3RyaW5nJyA/IG5ldyBEYXRlKHRyYW5zZm9ybWVkVmFsdWUpIDogdHJhbnNmb3JtZWRWYWx1ZTtcbiAgICAgIHJldHVybiB7IGtleTogJ19wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQnLCB2YWx1ZTogY29lcmNlZFRvRGF0ZSB9O1xuICAgIGNhc2UgJ19wYXNzd29yZF9jaGFuZ2VkX2F0JzpcbiAgICAgIHRyYW5zZm9ybWVkVmFsdWUgPSB0cmFuc2Zvcm1Ub3BMZXZlbEF0b20ocmVzdFZhbHVlKTtcbiAgICAgIGNvZXJjZWRUb0RhdGUgPVxuICAgICAgICB0eXBlb2YgdHJhbnNmb3JtZWRWYWx1ZSA9PT0gJ3N0cmluZycgPyBuZXcgRGF0ZSh0cmFuc2Zvcm1lZFZhbHVlKSA6IHRyYW5zZm9ybWVkVmFsdWU7XG4gICAgICByZXR1cm4geyBrZXk6ICdfcGFzc3dvcmRfY2hhbmdlZF9hdCcsIHZhbHVlOiBjb2VyY2VkVG9EYXRlIH07XG4gICAgY2FzZSAnX2ZhaWxlZF9sb2dpbl9jb3VudCc6XG4gICAgY2FzZSAnX3JwZXJtJzpcbiAgICBjYXNlICdfd3Blcm0nOlxuICAgIGNhc2UgJ19lbWFpbF92ZXJpZnlfdG9rZW4nOlxuICAgIGNhc2UgJ19oYXNoZWRfcGFzc3dvcmQnOlxuICAgIGNhc2UgJ19wZXJpc2hhYmxlX3Rva2VuJzpcbiAgICAgIHJldHVybiB7IGtleTogcmVzdEtleSwgdmFsdWU6IHJlc3RWYWx1ZSB9O1xuICAgIGNhc2UgJ3Nlc3Npb25Ub2tlbic6XG4gICAgICByZXR1cm4geyBrZXk6ICdfc2Vzc2lvbl90b2tlbicsIHZhbHVlOiByZXN0VmFsdWUgfTtcbiAgICBkZWZhdWx0OlxuICAgICAgLy8gQXV0aCBkYXRhIHNob3VsZCBoYXZlIGJlZW4gdHJhbnNmb3JtZWQgYWxyZWFkeVxuICAgICAgaWYgKHJlc3RLZXkubWF0Y2goL15hdXRoRGF0YVxcLihbYS16QS1aMC05X10rKVxcLmlkJC8pKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FLCAnY2FuIG9ubHkgcXVlcnkgb24gJyArIHJlc3RLZXkpO1xuICAgICAgfVxuICAgICAgLy8gVHJ1c3QgdGhhdCB0aGUgYXV0aCBkYXRhIGhhcyBiZWVuIHRyYW5zZm9ybWVkIGFuZCBzYXZlIGl0IGRpcmVjdGx5XG4gICAgICBpZiAocmVzdEtleS5tYXRjaCgvXl9hdXRoX2RhdGFfW2EtekEtWjAtOV9dKyQvKSkge1xuICAgICAgICByZXR1cm4geyBrZXk6IHJlc3RLZXksIHZhbHVlOiByZXN0VmFsdWUgfTtcbiAgICAgIH1cbiAgfVxuICAvL3NraXAgc3RyYWlnaHQgdG8gdHJhbnNmb3JtVG9wTGV2ZWxBdG9tIGZvciBCeXRlcywgdGhleSBkb24ndCBzaG93IHVwIGluIHRoZSBzY2hlbWEgZm9yIHNvbWUgcmVhc29uXG4gIGlmIChyZXN0VmFsdWUgJiYgcmVzdFZhbHVlLl9fdHlwZSAhPT0gJ0J5dGVzJykge1xuICAgIC8vTm90ZTogV2UgbWF5IG5vdCBrbm93IHRoZSB0eXBlIG9mIGEgZmllbGQgaGVyZSwgYXMgdGhlIHVzZXIgY291bGQgYmUgc2F2aW5nIChudWxsKSB0byBhIGZpZWxkXG4gICAgLy9UaGF0IG5ldmVyIGV4aXN0ZWQgYmVmb3JlLCBtZWFuaW5nIHdlIGNhbid0IGluZmVyIHRoZSB0eXBlLlxuICAgIGlmIChcbiAgICAgIChzY2hlbWEuZmllbGRzW3Jlc3RLZXldICYmIHNjaGVtYS5maWVsZHNbcmVzdEtleV0udHlwZSA9PSAnUG9pbnRlcicpIHx8XG4gICAgICByZXN0VmFsdWUuX190eXBlID09ICdQb2ludGVyJ1xuICAgICkge1xuICAgICAgcmVzdEtleSA9ICdfcF8nICsgcmVzdEtleTtcbiAgICB9XG4gIH1cblxuICAvLyBIYW5kbGUgYXRvbWljIHZhbHVlc1xuICB2YXIgdmFsdWUgPSB0cmFuc2Zvcm1Ub3BMZXZlbEF0b20ocmVzdFZhbHVlKTtcbiAgaWYgKHZhbHVlICE9PSBDYW5ub3RUcmFuc2Zvcm0pIHtcbiAgICByZXR1cm4geyBrZXk6IHJlc3RLZXksIHZhbHVlOiB2YWx1ZSB9O1xuICB9XG5cbiAgLy8gQUNMcyBhcmUgaGFuZGxlZCBiZWZvcmUgdGhpcyBtZXRob2QgaXMgY2FsbGVkXG4gIC8vIElmIGFuIEFDTCBrZXkgc3RpbGwgZXhpc3RzIGhlcmUsIHNvbWV0aGluZyBpcyB3cm9uZy5cbiAgaWYgKHJlc3RLZXkgPT09ICdBQ0wnKSB7XG4gICAgdGhyb3cgJ1RoZXJlIHdhcyBhIHByb2JsZW0gdHJhbnNmb3JtaW5nIGFuIEFDTC4nO1xuICB9XG5cbiAgLy8gSGFuZGxlIGFycmF5c1xuICBpZiAocmVzdFZhbHVlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICB2YWx1ZSA9IHJlc3RWYWx1ZS5tYXAodHJhbnNmb3JtSW50ZXJpb3JWYWx1ZSk7XG4gICAgcmV0dXJuIHsga2V5OiByZXN0S2V5LCB2YWx1ZTogdmFsdWUgfTtcbiAgfVxuXG4gIC8vIEhhbmRsZSBub3JtYWwgb2JqZWN0cyBieSByZWN1cnNpbmdcbiAgaWYgKE9iamVjdC5rZXlzKHJlc3RWYWx1ZSkuc29tZShrZXkgPT4ga2V5LmluY2x1ZGVzKCckJykgfHwga2V5LmluY2x1ZGVzKCcuJykpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9ORVNURURfS0VZLFxuICAgICAgXCJOZXN0ZWQga2V5cyBzaG91bGQgbm90IGNvbnRhaW4gdGhlICckJyBvciAnLicgY2hhcmFjdGVyc1wiXG4gICAgKTtcbiAgfVxuICB2YWx1ZSA9IG1hcFZhbHVlcyhyZXN0VmFsdWUsIHRyYW5zZm9ybUludGVyaW9yVmFsdWUpO1xuICByZXR1cm4geyBrZXk6IHJlc3RLZXksIHZhbHVlIH07XG59O1xuXG5jb25zdCBwYXJzZU9iamVjdFRvTW9uZ29PYmplY3RGb3JDcmVhdGUgPSAoY2xhc3NOYW1lLCByZXN0Q3JlYXRlLCBzY2hlbWEpID0+IHtcbiAgcmVzdENyZWF0ZSA9IGFkZExlZ2FjeUFDTChyZXN0Q3JlYXRlKTtcbiAgY29uc3QgbW9uZ29DcmVhdGUgPSB7fTtcbiAgZm9yIChjb25zdCByZXN0S2V5IGluIHJlc3RDcmVhdGUpIHtcbiAgICBpZiAocmVzdENyZWF0ZVtyZXN0S2V5XSAmJiByZXN0Q3JlYXRlW3Jlc3RLZXldLl9fdHlwZSA9PT0gJ1JlbGF0aW9uJykge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IHsga2V5LCB2YWx1ZSB9ID0gcGFyc2VPYmplY3RLZXlWYWx1ZVRvTW9uZ29PYmplY3RLZXlWYWx1ZShcbiAgICAgIHJlc3RLZXksXG4gICAgICByZXN0Q3JlYXRlW3Jlc3RLZXldLFxuICAgICAgc2NoZW1hXG4gICAgKTtcbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgbW9uZ29DcmVhdGVba2V5XSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIC8vIFVzZSB0aGUgbGVnYWN5IG1vbmdvIGZvcm1hdCBmb3IgY3JlYXRlZEF0IGFuZCB1cGRhdGVkQXRcbiAgaWYgKG1vbmdvQ3JlYXRlLmNyZWF0ZWRBdCkge1xuICAgIG1vbmdvQ3JlYXRlLl9jcmVhdGVkX2F0ID0gbmV3IERhdGUobW9uZ29DcmVhdGUuY3JlYXRlZEF0LmlzbyB8fCBtb25nb0NyZWF0ZS5jcmVhdGVkQXQpO1xuICAgIGRlbGV0ZSBtb25nb0NyZWF0ZS5jcmVhdGVkQXQ7XG4gIH1cbiAgaWYgKG1vbmdvQ3JlYXRlLnVwZGF0ZWRBdCkge1xuICAgIG1vbmdvQ3JlYXRlLl91cGRhdGVkX2F0ID0gbmV3IERhdGUobW9uZ29DcmVhdGUudXBkYXRlZEF0LmlzbyB8fCBtb25nb0NyZWF0ZS51cGRhdGVkQXQpO1xuICAgIGRlbGV0ZSBtb25nb0NyZWF0ZS51cGRhdGVkQXQ7XG4gIH1cblxuICByZXR1cm4gbW9uZ29DcmVhdGU7XG59O1xuXG4vLyBNYWluIGV4cG9zZWQgbWV0aG9kIHRvIGhlbHAgdXBkYXRlIG9sZCBvYmplY3RzLlxuY29uc3QgdHJhbnNmb3JtVXBkYXRlID0gKGNsYXNzTmFtZSwgcmVzdFVwZGF0ZSwgcGFyc2VGb3JtYXRTY2hlbWEpID0+IHtcbiAgY29uc3QgbW9uZ29VcGRhdGUgPSB7fTtcbiAgY29uc3QgYWNsID0gYWRkTGVnYWN5QUNMKHJlc3RVcGRhdGUpO1xuICBpZiAoYWNsLl9ycGVybSB8fCBhY2wuX3dwZXJtIHx8IGFjbC5fYWNsKSB7XG4gICAgbW9uZ29VcGRhdGUuJHNldCA9IHt9O1xuICAgIGlmIChhY2wuX3JwZXJtKSB7XG4gICAgICBtb25nb1VwZGF0ZS4kc2V0Ll9ycGVybSA9IGFjbC5fcnBlcm07XG4gICAgfVxuICAgIGlmIChhY2wuX3dwZXJtKSB7XG4gICAgICBtb25nb1VwZGF0ZS4kc2V0Ll93cGVybSA9IGFjbC5fd3Blcm07XG4gICAgfVxuICAgIGlmIChhY2wuX2FjbCkge1xuICAgICAgbW9uZ29VcGRhdGUuJHNldC5fYWNsID0gYWNsLl9hY2w7XG4gICAgfVxuICB9XG4gIGZvciAodmFyIHJlc3RLZXkgaW4gcmVzdFVwZGF0ZSkge1xuICAgIGlmIChyZXN0VXBkYXRlW3Jlc3RLZXldICYmIHJlc3RVcGRhdGVbcmVzdEtleV0uX190eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgdmFyIG91dCA9IHRyYW5zZm9ybUtleVZhbHVlRm9yVXBkYXRlKFxuICAgICAgY2xhc3NOYW1lLFxuICAgICAgcmVzdEtleSxcbiAgICAgIHJlc3RVcGRhdGVbcmVzdEtleV0sXG4gICAgICBwYXJzZUZvcm1hdFNjaGVtYVxuICAgICk7XG5cbiAgICAvLyBJZiB0aGUgb3V0cHV0IHZhbHVlIGlzIGFuIG9iamVjdCB3aXRoIGFueSAkIGtleXMsIGl0J3MgYW5cbiAgICAvLyBvcGVyYXRvciB0aGF0IG5lZWRzIHRvIGJlIGxpZnRlZCBvbnRvIHRoZSB0b3AgbGV2ZWwgdXBkYXRlXG4gICAgLy8gb2JqZWN0LlxuICAgIGlmICh0eXBlb2Ygb3V0LnZhbHVlID09PSAnb2JqZWN0JyAmJiBvdXQudmFsdWUgIT09IG51bGwgJiYgb3V0LnZhbHVlLl9fb3ApIHtcbiAgICAgIG1vbmdvVXBkYXRlW291dC52YWx1ZS5fX29wXSA9IG1vbmdvVXBkYXRlW291dC52YWx1ZS5fX29wXSB8fCB7fTtcbiAgICAgIG1vbmdvVXBkYXRlW291dC52YWx1ZS5fX29wXVtvdXQua2V5XSA9IG91dC52YWx1ZS5hcmc7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1vbmdvVXBkYXRlWyckc2V0J10gPSBtb25nb1VwZGF0ZVsnJHNldCddIHx8IHt9O1xuICAgICAgbW9uZ29VcGRhdGVbJyRzZXQnXVtvdXQua2V5XSA9IG91dC52YWx1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbW9uZ29VcGRhdGU7XG59O1xuXG4vLyBBZGQgdGhlIGxlZ2FjeSBfYWNsIGZvcm1hdC5cbmNvbnN0IGFkZExlZ2FjeUFDTCA9IHJlc3RPYmplY3QgPT4ge1xuICBjb25zdCByZXN0T2JqZWN0Q29weSA9IHsgLi4ucmVzdE9iamVjdCB9O1xuICBjb25zdCBfYWNsID0ge307XG5cbiAgaWYgKHJlc3RPYmplY3QuX3dwZXJtKSB7XG4gICAgcmVzdE9iamVjdC5fd3Blcm0uZm9yRWFjaChlbnRyeSA9PiB7XG4gICAgICBfYWNsW2VudHJ5XSA9IHsgdzogdHJ1ZSB9O1xuICAgIH0pO1xuICAgIHJlc3RPYmplY3RDb3B5Ll9hY2wgPSBfYWNsO1xuICB9XG5cbiAgaWYgKHJlc3RPYmplY3QuX3JwZXJtKSB7XG4gICAgcmVzdE9iamVjdC5fcnBlcm0uZm9yRWFjaChlbnRyeSA9PiB7XG4gICAgICBpZiAoIShlbnRyeSBpbiBfYWNsKSkge1xuICAgICAgICBfYWNsW2VudHJ5XSA9IHsgcjogdHJ1ZSB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgX2FjbFtlbnRyeV0uciA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmVzdE9iamVjdENvcHkuX2FjbCA9IF9hY2w7XG4gIH1cblxuICByZXR1cm4gcmVzdE9iamVjdENvcHk7XG59O1xuXG4vLyBBIHNlbnRpbmVsIHZhbHVlIHRoYXQgaGVscGVyIHRyYW5zZm9ybWF0aW9ucyByZXR1cm4gd2hlbiB0aGV5XG4vLyBjYW5ub3QgcGVyZm9ybSBhIHRyYW5zZm9ybWF0aW9uXG5mdW5jdGlvbiBDYW5ub3RUcmFuc2Zvcm0oKSB7fVxuXG5jb25zdCB0cmFuc2Zvcm1JbnRlcmlvckF0b20gPSBhdG9tID0+IHtcbiAgLy8gVE9ETzogY2hlY2sgdmFsaWRpdHkgaGFyZGVyIGZvciB0aGUgX190eXBlLWRlZmluZWQgdHlwZXNcbiAgaWYgKHR5cGVvZiBhdG9tID09PSAnb2JqZWN0JyAmJiBhdG9tICYmICEoYXRvbSBpbnN0YW5jZW9mIERhdGUpICYmIGF0b20uX190eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICByZXR1cm4ge1xuICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICBjbGFzc05hbWU6IGF0b20uY2xhc3NOYW1lLFxuICAgICAgb2JqZWN0SWQ6IGF0b20ub2JqZWN0SWQsXG4gICAgfTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgYXRvbSA9PT0gJ2Z1bmN0aW9uJyB8fCB0eXBlb2YgYXRvbSA9PT0gJ3N5bWJvbCcpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCBgY2Fubm90IHRyYW5zZm9ybSB2YWx1ZTogJHthdG9tfWApO1xuICB9IGVsc2UgaWYgKERhdGVDb2Rlci5pc1ZhbGlkSlNPTihhdG9tKSkge1xuICAgIHJldHVybiBEYXRlQ29kZXIuSlNPTlRvRGF0YWJhc2UoYXRvbSk7XG4gIH0gZWxzZSBpZiAoQnl0ZXNDb2Rlci5pc1ZhbGlkSlNPTihhdG9tKSkge1xuICAgIHJldHVybiBCeXRlc0NvZGVyLkpTT05Ub0RhdGFiYXNlKGF0b20pO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBhdG9tID09PSAnb2JqZWN0JyAmJiBhdG9tICYmIGF0b20uJHJlZ2V4ICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gbmV3IFJlZ0V4cChhdG9tLiRyZWdleCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGF0b207XG4gIH1cbn07XG5cbi8vIEhlbHBlciBmdW5jdGlvbiB0byB0cmFuc2Zvcm0gYW4gYXRvbSBmcm9tIFJFU1QgZm9ybWF0IHRvIE1vbmdvIGZvcm1hdC5cbi8vIEFuIGF0b20gaXMgYW55dGhpbmcgdGhhdCBjYW4ndCBjb250YWluIG90aGVyIGV4cHJlc3Npb25zLiBTbyBpdFxuLy8gaW5jbHVkZXMgdGhpbmdzIHdoZXJlIG9iamVjdHMgYXJlIHVzZWQgdG8gcmVwcmVzZW50IG90aGVyXG4vLyBkYXRhdHlwZXMsIGxpa2UgcG9pbnRlcnMgYW5kIGRhdGVzLCBidXQgaXQgZG9lcyBub3QgaW5jbHVkZSBvYmplY3RzXG4vLyBvciBhcnJheXMgd2l0aCBnZW5lcmljIHN0dWZmIGluc2lkZS5cbi8vIFJhaXNlcyBhbiBlcnJvciBpZiB0aGlzIGNhbm5vdCBwb3NzaWJseSBiZSB2YWxpZCBSRVNUIGZvcm1hdC5cbi8vIFJldHVybnMgQ2Fubm90VHJhbnNmb3JtIGlmIGl0J3MganVzdCBub3QgYW4gYXRvbVxuZnVuY3Rpb24gdHJhbnNmb3JtVG9wTGV2ZWxBdG9tKGF0b20sIGZpZWxkKSB7XG4gIHN3aXRjaCAodHlwZW9mIGF0b20pIHtcbiAgICBjYXNlICdudW1iZXInOlxuICAgIGNhc2UgJ2Jvb2xlYW4nOlxuICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgICByZXR1cm4gYXRvbTtcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgaWYgKGZpZWxkICYmIGZpZWxkLnR5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgICByZXR1cm4gYCR7ZmllbGQudGFyZ2V0Q2xhc3N9JCR7YXRvbX1gO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGF0b207XG4gICAgY2FzZSAnc3ltYm9sJzpcbiAgICBjYXNlICdmdW5jdGlvbic6XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCBgY2Fubm90IHRyYW5zZm9ybSB2YWx1ZTogJHthdG9tfWApO1xuICAgIGNhc2UgJ29iamVjdCc6XG4gICAgICBpZiAoYXRvbSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgLy8gVGVjaG5pY2FsbHkgZGF0ZXMgYXJlIG5vdCByZXN0IGZvcm1hdCwgYnV0LCBpdCBzZWVtcyBwcmV0dHlcbiAgICAgICAgLy8gY2xlYXIgd2hhdCB0aGV5IHNob3VsZCBiZSB0cmFuc2Zvcm1lZCB0bywgc28gbGV0J3MganVzdCBkbyBpdC5cbiAgICAgICAgcmV0dXJuIGF0b207XG4gICAgICB9XG5cbiAgICAgIGlmIChhdG9tID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiBhdG9tO1xuICAgICAgfVxuXG4gICAgICAvLyBUT0RPOiBjaGVjayB2YWxpZGl0eSBoYXJkZXIgZm9yIHRoZSBfX3R5cGUtZGVmaW5lZCB0eXBlc1xuICAgICAgaWYgKGF0b20uX190eXBlID09ICdQb2ludGVyJykge1xuICAgICAgICByZXR1cm4gYCR7YXRvbS5jbGFzc05hbWV9JCR7YXRvbS5vYmplY3RJZH1gO1xuICAgICAgfVxuICAgICAgaWYgKERhdGVDb2Rlci5pc1ZhbGlkSlNPTihhdG9tKSkge1xuICAgICAgICByZXR1cm4gRGF0ZUNvZGVyLkpTT05Ub0RhdGFiYXNlKGF0b20pO1xuICAgICAgfVxuICAgICAgaWYgKEJ5dGVzQ29kZXIuaXNWYWxpZEpTT04oYXRvbSkpIHtcbiAgICAgICAgcmV0dXJuIEJ5dGVzQ29kZXIuSlNPTlRvRGF0YWJhc2UoYXRvbSk7XG4gICAgICB9XG4gICAgICBpZiAoR2VvUG9pbnRDb2Rlci5pc1ZhbGlkSlNPTihhdG9tKSkge1xuICAgICAgICByZXR1cm4gR2VvUG9pbnRDb2Rlci5KU09OVG9EYXRhYmFzZShhdG9tKTtcbiAgICAgIH1cbiAgICAgIGlmIChQb2x5Z29uQ29kZXIuaXNWYWxpZEpTT04oYXRvbSkpIHtcbiAgICAgICAgcmV0dXJuIFBvbHlnb25Db2Rlci5KU09OVG9EYXRhYmFzZShhdG9tKTtcbiAgICAgIH1cbiAgICAgIGlmIChGaWxlQ29kZXIuaXNWYWxpZEpTT04oYXRvbSkpIHtcbiAgICAgICAgcmV0dXJuIEZpbGVDb2Rlci5KU09OVG9EYXRhYmFzZShhdG9tKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBDYW5ub3RUcmFuc2Zvcm07XG5cbiAgICBkZWZhdWx0OlxuICAgICAgLy8gSSBkb24ndCB0aGluayB0eXBlb2YgY2FuIGV2ZXIgbGV0IHVzIGdldCBoZXJlXG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUixcbiAgICAgICAgYHJlYWxseSBkaWQgbm90IGV4cGVjdCB2YWx1ZTogJHthdG9tfWBcbiAgICAgICk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVsYXRpdmVUaW1lVG9EYXRlKHRleHQsIG5vdyA9IG5ldyBEYXRlKCkpIHtcbiAgdGV4dCA9IHRleHQudG9Mb3dlckNhc2UoKTtcblxuICBsZXQgcGFydHMgPSB0ZXh0LnNwbGl0KCcgJyk7XG5cbiAgLy8gRmlsdGVyIG91dCB3aGl0ZXNwYWNlXG4gIHBhcnRzID0gcGFydHMuZmlsdGVyKHBhcnQgPT4gcGFydCAhPT0gJycpO1xuXG4gIGNvbnN0IGZ1dHVyZSA9IHBhcnRzWzBdID09PSAnaW4nO1xuICBjb25zdCBwYXN0ID0gcGFydHNbcGFydHMubGVuZ3RoIC0gMV0gPT09ICdhZ28nO1xuXG4gIGlmICghZnV0dXJlICYmICFwYXN0ICYmIHRleHQgIT09ICdub3cnKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXR1czogJ2Vycm9yJyxcbiAgICAgIGluZm86IFwiVGltZSBzaG91bGQgZWl0aGVyIHN0YXJ0IHdpdGggJ2luJyBvciBlbmQgd2l0aCAnYWdvJ1wiLFxuICAgIH07XG4gIH1cblxuICBpZiAoZnV0dXJlICYmIHBhc3QpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiAnZXJyb3InLFxuICAgICAgaW5mbzogXCJUaW1lIGNhbm5vdCBoYXZlIGJvdGggJ2luJyBhbmQgJ2FnbydcIixcbiAgICB9O1xuICB9XG5cbiAgLy8gc3RyaXAgdGhlICdhZ28nIG9yICdpbidcbiAgaWYgKGZ1dHVyZSkge1xuICAgIHBhcnRzID0gcGFydHMuc2xpY2UoMSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gcGFzdFxuICAgIHBhcnRzID0gcGFydHMuc2xpY2UoMCwgcGFydHMubGVuZ3RoIC0gMSk7XG4gIH1cblxuICBpZiAocGFydHMubGVuZ3RoICUgMiAhPT0gMCAmJiB0ZXh0ICE9PSAnbm93Jykge1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXM6ICdlcnJvcicsXG4gICAgICBpbmZvOiAnSW52YWxpZCB0aW1lIHN0cmluZy4gRGFuZ2xpbmcgdW5pdCBvciBudW1iZXIuJyxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgcGFpcnMgPSBbXTtcbiAgd2hpbGUgKHBhcnRzLmxlbmd0aCkge1xuICAgIHBhaXJzLnB1c2goW3BhcnRzLnNoaWZ0KCksIHBhcnRzLnNoaWZ0KCldKTtcbiAgfVxuXG4gIGxldCBzZWNvbmRzID0gMDtcbiAgZm9yIChjb25zdCBbbnVtLCBpbnRlcnZhbF0gb2YgcGFpcnMpIHtcbiAgICBjb25zdCB2YWwgPSBOdW1iZXIobnVtKTtcbiAgICBpZiAoIU51bWJlci5pc0ludGVnZXIodmFsKSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc3RhdHVzOiAnZXJyb3InLFxuICAgICAgICBpbmZvOiBgJyR7bnVtfScgaXMgbm90IGFuIGludGVnZXIuYCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgc3dpdGNoIChpbnRlcnZhbCkge1xuICAgICAgY2FzZSAneXInOlxuICAgICAgY2FzZSAneXJzJzpcbiAgICAgIGNhc2UgJ3llYXInOlxuICAgICAgY2FzZSAneWVhcnMnOlxuICAgICAgICBzZWNvbmRzICs9IHZhbCAqIDMxNTM2MDAwOyAvLyAzNjUgKiAyNCAqIDYwICogNjBcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3drJzpcbiAgICAgIGNhc2UgJ3drcyc6XG4gICAgICBjYXNlICd3ZWVrJzpcbiAgICAgIGNhc2UgJ3dlZWtzJzpcbiAgICAgICAgc2Vjb25kcyArPSB2YWwgKiA2MDQ4MDA7IC8vIDcgKiAyNCAqIDYwICogNjBcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2QnOlxuICAgICAgY2FzZSAnZGF5JzpcbiAgICAgIGNhc2UgJ2RheXMnOlxuICAgICAgICBzZWNvbmRzICs9IHZhbCAqIDg2NDAwOyAvLyAyNCAqIDYwICogNjBcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ2hyJzpcbiAgICAgIGNhc2UgJ2hycyc6XG4gICAgICBjYXNlICdob3VyJzpcbiAgICAgIGNhc2UgJ2hvdXJzJzpcbiAgICAgICAgc2Vjb25kcyArPSB2YWwgKiAzNjAwOyAvLyA2MCAqIDYwXG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdtaW4nOlxuICAgICAgY2FzZSAnbWlucyc6XG4gICAgICBjYXNlICdtaW51dGUnOlxuICAgICAgY2FzZSAnbWludXRlcyc6XG4gICAgICAgIHNlY29uZHMgKz0gdmFsICogNjA7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdzZWMnOlxuICAgICAgY2FzZSAnc2Vjcyc6XG4gICAgICBjYXNlICdzZWNvbmQnOlxuICAgICAgY2FzZSAnc2Vjb25kcyc6XG4gICAgICAgIHNlY29uZHMgKz0gdmFsO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdGF0dXM6ICdlcnJvcicsXG4gICAgICAgICAgaW5mbzogYEludmFsaWQgaW50ZXJ2YWw6ICcke2ludGVydmFsfSdgLFxuICAgICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG1pbGxpc2Vjb25kcyA9IHNlY29uZHMgKiAxMDAwO1xuICBpZiAoZnV0dXJlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXR1czogJ3N1Y2Nlc3MnLFxuICAgICAgaW5mbzogJ2Z1dHVyZScsXG4gICAgICByZXN1bHQ6IG5ldyBEYXRlKG5vdy52YWx1ZU9mKCkgKyBtaWxsaXNlY29uZHMpLFxuICAgIH07XG4gIH0gZWxzZSBpZiAocGFzdCkge1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXM6ICdzdWNjZXNzJyxcbiAgICAgIGluZm86ICdwYXN0JyxcbiAgICAgIHJlc3VsdDogbmV3IERhdGUobm93LnZhbHVlT2YoKSAtIG1pbGxpc2Vjb25kcyksXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiAnc3VjY2VzcycsXG4gICAgICBpbmZvOiAncHJlc2VudCcsXG4gICAgICByZXN1bHQ6IG5ldyBEYXRlKG5vdy52YWx1ZU9mKCkpLFxuICAgIH07XG4gIH1cbn1cblxuLy8gVHJhbnNmb3JtcyBhIHF1ZXJ5IGNvbnN0cmFpbnQgZnJvbSBSRVNUIEFQSSBmb3JtYXQgdG8gTW9uZ28gZm9ybWF0LlxuLy8gQSBjb25zdHJhaW50IGlzIHNvbWV0aGluZyB3aXRoIGZpZWxkcyBsaWtlICRsdC5cbi8vIElmIGl0IGlzIG5vdCBhIHZhbGlkIGNvbnN0cmFpbnQgYnV0IGl0IGNvdWxkIGJlIGEgdmFsaWQgc29tZXRoaW5nXG4vLyBlbHNlLCByZXR1cm4gQ2Fubm90VHJhbnNmb3JtLlxuLy8gaW5BcnJheSBpcyB3aGV0aGVyIHRoaXMgaXMgYW4gYXJyYXkgZmllbGQuXG5mdW5jdGlvbiB0cmFuc2Zvcm1Db25zdHJhaW50KGNvbnN0cmFpbnQsIGZpZWxkLCBjb3VudCA9IGZhbHNlKSB7XG4gIGNvbnN0IGluQXJyYXkgPSBmaWVsZCAmJiBmaWVsZC50eXBlICYmIGZpZWxkLnR5cGUgPT09ICdBcnJheSc7XG4gIGlmICh0eXBlb2YgY29uc3RyYWludCAhPT0gJ29iamVjdCcgfHwgIWNvbnN0cmFpbnQpIHtcbiAgICByZXR1cm4gQ2Fubm90VHJhbnNmb3JtO1xuICB9XG4gIGNvbnN0IHRyYW5zZm9ybUZ1bmN0aW9uID0gaW5BcnJheSA/IHRyYW5zZm9ybUludGVyaW9yQXRvbSA6IHRyYW5zZm9ybVRvcExldmVsQXRvbTtcbiAgY29uc3QgdHJhbnNmb3JtZXIgPSBhdG9tID0+IHtcbiAgICBjb25zdCByZXN1bHQgPSB0cmFuc2Zvcm1GdW5jdGlvbihhdG9tLCBmaWVsZCk7XG4gICAgaWYgKHJlc3VsdCA9PT0gQ2Fubm90VHJhbnNmb3JtKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCBgYmFkIGF0b206ICR7SlNPTi5zdHJpbmdpZnkoYXRvbSl9YCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG4gIC8vIGtleXMgaXMgdGhlIGNvbnN0cmFpbnRzIGluIHJldmVyc2UgYWxwaGFiZXRpY2FsIG9yZGVyLlxuICAvLyBUaGlzIGlzIGEgaGFjayBzbyB0aGF0OlxuICAvLyAgICRyZWdleCBpcyBoYW5kbGVkIGJlZm9yZSAkb3B0aW9uc1xuICAvLyAgICRuZWFyU3BoZXJlIGlzIGhhbmRsZWQgYmVmb3JlICRtYXhEaXN0YW5jZVxuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKGNvbnN0cmFpbnQpLnNvcnQoKS5yZXZlcnNlKCk7XG4gIHZhciBhbnN3ZXIgPSB7fTtcbiAgZm9yICh2YXIga2V5IG9mIGtleXMpIHtcbiAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgY2FzZSAnJGx0JzpcbiAgICAgIGNhc2UgJyRsdGUnOlxuICAgICAgY2FzZSAnJGd0JzpcbiAgICAgIGNhc2UgJyRndGUnOlxuICAgICAgY2FzZSAnJGV4aXN0cyc6XG4gICAgICBjYXNlICckbmUnOlxuICAgICAgY2FzZSAnJGVxJzoge1xuICAgICAgICBjb25zdCB2YWwgPSBjb25zdHJhaW50W2tleV07XG4gICAgICAgIGlmICh2YWwgJiYgdHlwZW9mIHZhbCA9PT0gJ29iamVjdCcgJiYgdmFsLiRyZWxhdGl2ZVRpbWUpIHtcbiAgICAgICAgICBpZiAoZmllbGQgJiYgZmllbGQudHlwZSAhPT0gJ0RhdGUnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgJyRyZWxhdGl2ZVRpbWUgY2FuIG9ubHkgYmUgdXNlZCB3aXRoIERhdGUgZmllbGQnXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHN3aXRjaCAoa2V5KSB7XG4gICAgICAgICAgICBjYXNlICckZXhpc3RzJzpcbiAgICAgICAgICAgIGNhc2UgJyRuZSc6XG4gICAgICAgICAgICBjYXNlICckZXEnOlxuICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgICAgICckcmVsYXRpdmVUaW1lIGNhbiBvbmx5IGJlIHVzZWQgd2l0aCB0aGUgJGx0LCAkbHRlLCAkZ3QsIGFuZCAkZ3RlIG9wZXJhdG9ycydcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBwYXJzZXJSZXN1bHQgPSByZWxhdGl2ZVRpbWVUb0RhdGUodmFsLiRyZWxhdGl2ZVRpbWUpO1xuICAgICAgICAgIGlmIChwYXJzZXJSZXN1bHQuc3RhdHVzID09PSAnc3VjY2VzcycpIHtcbiAgICAgICAgICAgIGFuc3dlcltrZXldID0gcGFyc2VyUmVzdWx0LnJlc3VsdDtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGxvZy5pbmZvKCdFcnJvciB3aGlsZSBwYXJzaW5nIHJlbGF0aXZlIGRhdGUnLCBwYXJzZXJSZXN1bHQpO1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgIGBiYWQgJHJlbGF0aXZlVGltZSAoJHtrZXl9KSB2YWx1ZS4gJHtwYXJzZXJSZXN1bHQuaW5mb31gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGFuc3dlcltrZXldID0gdHJhbnNmb3JtZXIodmFsKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJyRpbic6XG4gICAgICBjYXNlICckbmluJzoge1xuICAgICAgICBjb25zdCBhcnIgPSBjb25zdHJhaW50W2tleV07XG4gICAgICAgIGlmICghKGFyciBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sICdiYWQgJyArIGtleSArICcgdmFsdWUnKTtcbiAgICAgICAgfVxuICAgICAgICBhbnN3ZXJba2V5XSA9IF8uZmxhdE1hcChhcnIsIHZhbHVlID0+IHtcbiAgICAgICAgICByZXR1cm4gKGF0b20gPT4ge1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYXRvbSkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlLm1hcCh0cmFuc2Zvcm1lcik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gdHJhbnNmb3JtZXIoYXRvbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSkodmFsdWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICckYWxsJzoge1xuICAgICAgICBjb25zdCBhcnIgPSBjb25zdHJhaW50W2tleV07XG4gICAgICAgIGlmICghKGFyciBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sICdiYWQgJyArIGtleSArICcgdmFsdWUnKTtcbiAgICAgICAgfVxuICAgICAgICBhbnN3ZXJba2V5XSA9IGFyci5tYXAodHJhbnNmb3JtSW50ZXJpb3JBdG9tKTtcblxuICAgICAgICBjb25zdCB2YWx1ZXMgPSBhbnN3ZXJba2V5XTtcbiAgICAgICAgaWYgKGlzQW55VmFsdWVSZWdleCh2YWx1ZXMpICYmICFpc0FsbFZhbHVlc1JlZ2V4T3JOb25lKHZhbHVlcykpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAnQWxsICRhbGwgdmFsdWVzIG11c3QgYmUgb2YgcmVnZXggdHlwZSBvciBub25lOiAnICsgdmFsdWVzXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnJHJlZ2V4JzpcbiAgICAgICAgdmFyIHMgPSBjb25zdHJhaW50W2tleV07XG4gICAgICAgIGlmICh0eXBlb2YgcyAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnYmFkIHJlZ2V4OiAnICsgcyk7XG4gICAgICAgIH1cbiAgICAgICAgYW5zd2VyW2tleV0gPSBzO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnJGNvbnRhaW5lZEJ5Jzoge1xuICAgICAgICBjb25zdCBhcnIgPSBjb25zdHJhaW50W2tleV07XG4gICAgICAgIGlmICghKGFyciBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sIGBiYWQgJGNvbnRhaW5lZEJ5OiBzaG91bGQgYmUgYW4gYXJyYXlgKTtcbiAgICAgICAgfVxuICAgICAgICBhbnN3ZXIuJGVsZW1NYXRjaCA9IHtcbiAgICAgICAgICAkbmluOiBhcnIubWFwKHRyYW5zZm9ybWVyKSxcbiAgICAgICAgfTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICckb3B0aW9ucyc6XG4gICAgICAgIGFuc3dlcltrZXldID0gY29uc3RyYWludFtrZXldO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnJHRleHQnOiB7XG4gICAgICAgIGNvbnN0IHNlYXJjaCA9IGNvbnN0cmFpbnRba2V5XS4kc2VhcmNoO1xuICAgICAgICBpZiAodHlwZW9mIHNlYXJjaCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCBgYmFkICR0ZXh0OiAkc2VhcmNoLCBzaG91bGQgYmUgb2JqZWN0YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFzZWFyY2guJHRlcm0gfHwgdHlwZW9mIHNlYXJjaC4kdGVybSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCBgYmFkICR0ZXh0OiAkdGVybSwgc2hvdWxkIGJlIHN0cmluZ2ApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGFuc3dlcltrZXldID0ge1xuICAgICAgICAgICAgJHNlYXJjaDogc2VhcmNoLiR0ZXJtLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNlYXJjaC4kbGFuZ3VhZ2UgJiYgdHlwZW9mIHNlYXJjaC4kbGFuZ3VhZ2UgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgYGJhZCAkdGV4dDogJGxhbmd1YWdlLCBzaG91bGQgYmUgc3RyaW5nYCk7XG4gICAgICAgIH0gZWxzZSBpZiAoc2VhcmNoLiRsYW5ndWFnZSkge1xuICAgICAgICAgIGFuc3dlcltrZXldLiRsYW5ndWFnZSA9IHNlYXJjaC4kbGFuZ3VhZ2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNlYXJjaC4kY2FzZVNlbnNpdGl2ZSAmJiB0eXBlb2Ygc2VhcmNoLiRjYXNlU2Vuc2l0aXZlICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICBgYmFkICR0ZXh0OiAkY2FzZVNlbnNpdGl2ZSwgc2hvdWxkIGJlIGJvb2xlYW5gXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIGlmIChzZWFyY2guJGNhc2VTZW5zaXRpdmUpIHtcbiAgICAgICAgICBhbnN3ZXJba2V5XS4kY2FzZVNlbnNpdGl2ZSA9IHNlYXJjaC4kY2FzZVNlbnNpdGl2ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2VhcmNoLiRkaWFjcml0aWNTZW5zaXRpdmUgJiYgdHlwZW9mIHNlYXJjaC4kZGlhY3JpdGljU2Vuc2l0aXZlICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICBgYmFkICR0ZXh0OiAkZGlhY3JpdGljU2Vuc2l0aXZlLCBzaG91bGQgYmUgYm9vbGVhbmBcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2UgaWYgKHNlYXJjaC4kZGlhY3JpdGljU2Vuc2l0aXZlKSB7XG4gICAgICAgICAgYW5zd2VyW2tleV0uJGRpYWNyaXRpY1NlbnNpdGl2ZSA9IHNlYXJjaC4kZGlhY3JpdGljU2Vuc2l0aXZlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnJG5lYXJTcGhlcmUnOiB7XG4gICAgICAgIGNvbnN0IHBvaW50ID0gY29uc3RyYWludFtrZXldO1xuICAgICAgICBpZiAoY291bnQpIHtcbiAgICAgICAgICBhbnN3ZXIuJGdlb1dpdGhpbiA9IHtcbiAgICAgICAgICAgICRjZW50ZXJTcGhlcmU6IFtbcG9pbnQubG9uZ2l0dWRlLCBwb2ludC5sYXRpdHVkZV0sIGNvbnN0cmFpbnQuJG1heERpc3RhbmNlXSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGFuc3dlcltrZXldID0gW3BvaW50LmxvbmdpdHVkZSwgcG9pbnQubGF0aXR1ZGVdO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnJG1heERpc3RhbmNlJzoge1xuICAgICAgICBpZiAoY291bnQpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBhbnN3ZXJba2V5XSA9IGNvbnN0cmFpbnRba2V5XTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICAvLyBUaGUgU0RLcyBkb24ndCBzZWVtIHRvIHVzZSB0aGVzZSBidXQgdGhleSBhcmUgZG9jdW1lbnRlZCBpbiB0aGVcbiAgICAgIC8vIFJFU1QgQVBJIGRvY3MuXG4gICAgICBjYXNlICckbWF4RGlzdGFuY2VJblJhZGlhbnMnOlxuICAgICAgICBhbnN3ZXJbJyRtYXhEaXN0YW5jZSddID0gY29uc3RyYWludFtrZXldO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRtYXhEaXN0YW5jZUluTWlsZXMnOlxuICAgICAgICBhbnN3ZXJbJyRtYXhEaXN0YW5jZSddID0gY29uc3RyYWludFtrZXldIC8gMzk1OTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICckbWF4RGlzdGFuY2VJbktpbG9tZXRlcnMnOlxuICAgICAgICBhbnN3ZXJbJyRtYXhEaXN0YW5jZSddID0gY29uc3RyYWludFtrZXldIC8gNjM3MTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJyRzZWxlY3QnOlxuICAgICAgY2FzZSAnJGRvbnRTZWxlY3QnOlxuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuQ09NTUFORF9VTkFWQUlMQUJMRSxcbiAgICAgICAgICAndGhlICcgKyBrZXkgKyAnIGNvbnN0cmFpbnQgaXMgbm90IHN1cHBvcnRlZCB5ZXQnXG4gICAgICAgICk7XG5cbiAgICAgIGNhc2UgJyR3aXRoaW4nOlxuICAgICAgICB2YXIgYm94ID0gY29uc3RyYWludFtrZXldWyckYm94J107XG4gICAgICAgIGlmICghYm94IHx8IGJveC5sZW5ndGggIT0gMikge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sICdtYWxmb3JtYXR0ZWQgJHdpdGhpbiBhcmcnKTtcbiAgICAgICAgfVxuICAgICAgICBhbnN3ZXJba2V5XSA9IHtcbiAgICAgICAgICAkYm94OiBbXG4gICAgICAgICAgICBbYm94WzBdLmxvbmdpdHVkZSwgYm94WzBdLmxhdGl0dWRlXSxcbiAgICAgICAgICAgIFtib3hbMV0ubG9uZ2l0dWRlLCBib3hbMV0ubGF0aXR1ZGVdLFxuICAgICAgICAgIF0sXG4gICAgICAgIH07XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICckZ2VvV2l0aGluJzoge1xuICAgICAgICBjb25zdCBwb2x5Z29uID0gY29uc3RyYWludFtrZXldWyckcG9seWdvbiddO1xuICAgICAgICBjb25zdCBjZW50ZXJTcGhlcmUgPSBjb25zdHJhaW50W2tleV1bJyRjZW50ZXJTcGhlcmUnXTtcbiAgICAgICAgaWYgKHBvbHlnb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGxldCBwb2ludHM7XG4gICAgICAgICAgaWYgKHR5cGVvZiBwb2x5Z29uID09PSAnb2JqZWN0JyAmJiBwb2x5Z29uLl9fdHlwZSA9PT0gJ1BvbHlnb24nKSB7XG4gICAgICAgICAgICBpZiAoIXBvbHlnb24uY29vcmRpbmF0ZXMgfHwgcG9seWdvbi5jb29yZGluYXRlcy5sZW5ndGggPCAzKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAgICAgJ2JhZCAkZ2VvV2l0aGluIHZhbHVlOyBQb2x5Z29uLmNvb3JkaW5hdGVzIHNob3VsZCBjb250YWluIGF0IGxlYXN0IDMgbG9uL2xhdCBwYWlycydcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBvaW50cyA9IHBvbHlnb24uY29vcmRpbmF0ZXM7XG4gICAgICAgICAgfSBlbHNlIGlmIChwb2x5Z29uIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgICAgIGlmIChwb2x5Z29uLmxlbmd0aCA8IDMpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7ICRwb2x5Z29uIHNob3VsZCBjb250YWluIGF0IGxlYXN0IDMgR2VvUG9pbnRzJ1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcG9pbnRzID0gcG9seWdvbjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAgIFwiYmFkICRnZW9XaXRoaW4gdmFsdWU7ICRwb2x5Z29uIHNob3VsZCBiZSBQb2x5Z29uIG9iamVjdCBvciBBcnJheSBvZiBQYXJzZS5HZW9Qb2ludCdzXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHBvaW50cyA9IHBvaW50cy5tYXAocG9pbnQgPT4ge1xuICAgICAgICAgICAgaWYgKHBvaW50IGluc3RhbmNlb2YgQXJyYXkgJiYgcG9pbnQubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgICAgIFBhcnNlLkdlb1BvaW50Ll92YWxpZGF0ZShwb2ludFsxXSwgcG9pbnRbMF0pO1xuICAgICAgICAgICAgICByZXR1cm4gcG9pbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIUdlb1BvaW50Q29kZXIuaXNWYWxpZEpTT04ocG9pbnQpKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sICdiYWQgJGdlb1dpdGhpbiB2YWx1ZScpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50LmxhdGl0dWRlLCBwb2ludC5sb25naXR1ZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFtwb2ludC5sb25naXR1ZGUsIHBvaW50LmxhdGl0dWRlXTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICBhbnN3ZXJba2V5XSA9IHtcbiAgICAgICAgICAgICRwb2x5Z29uOiBwb2ludHMsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIGlmIChjZW50ZXJTcGhlcmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGlmICghKGNlbnRlclNwaGVyZSBpbnN0YW5jZW9mIEFycmF5KSB8fCBjZW50ZXJTcGhlcmUubGVuZ3RoIDwgMikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAgICdiYWQgJGdlb1dpdGhpbiB2YWx1ZTsgJGNlbnRlclNwaGVyZSBzaG91bGQgYmUgYW4gYXJyYXkgb2YgUGFyc2UuR2VvUG9pbnQgYW5kIGRpc3RhbmNlJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gR2V0IHBvaW50LCBjb252ZXJ0IHRvIGdlbyBwb2ludCBpZiBuZWNlc3NhcnkgYW5kIHZhbGlkYXRlXG4gICAgICAgICAgbGV0IHBvaW50ID0gY2VudGVyU3BoZXJlWzBdO1xuICAgICAgICAgIGlmIChwb2ludCBpbnN0YW5jZW9mIEFycmF5ICYmIHBvaW50Lmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgcG9pbnQgPSBuZXcgUGFyc2UuR2VvUG9pbnQocG9pbnRbMV0sIHBvaW50WzBdKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKCFHZW9Qb2ludENvZGVyLmlzVmFsaWRKU09OKHBvaW50KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAgICdiYWQgJGdlb1dpdGhpbiB2YWx1ZTsgJGNlbnRlclNwaGVyZSBnZW8gcG9pbnQgaW52YWxpZCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIFBhcnNlLkdlb1BvaW50Ll92YWxpZGF0ZShwb2ludC5sYXRpdHVkZSwgcG9pbnQubG9uZ2l0dWRlKTtcbiAgICAgICAgICAvLyBHZXQgZGlzdGFuY2UgYW5kIHZhbGlkYXRlXG4gICAgICAgICAgY29uc3QgZGlzdGFuY2UgPSBjZW50ZXJTcGhlcmVbMV07XG4gICAgICAgICAgaWYgKGlzTmFOKGRpc3RhbmNlKSB8fCBkaXN0YW5jZSA8IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7ICRjZW50ZXJTcGhlcmUgZGlzdGFuY2UgaW52YWxpZCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGFuc3dlcltrZXldID0ge1xuICAgICAgICAgICAgJGNlbnRlclNwaGVyZTogW1twb2ludC5sb25naXR1ZGUsIHBvaW50LmxhdGl0dWRlXSwgZGlzdGFuY2VdLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICckZ2VvSW50ZXJzZWN0cyc6IHtcbiAgICAgICAgY29uc3QgcG9pbnQgPSBjb25zdHJhaW50W2tleV1bJyRwb2ludCddO1xuICAgICAgICBpZiAoIUdlb1BvaW50Q29kZXIuaXNWYWxpZEpTT04ocG9pbnQpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgJ2JhZCAkZ2VvSW50ZXJzZWN0IHZhbHVlOyAkcG9pbnQgc2hvdWxkIGJlIEdlb1BvaW50J1xuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50LmxhdGl0dWRlLCBwb2ludC5sb25naXR1ZGUpO1xuICAgICAgICB9XG4gICAgICAgIGFuc3dlcltrZXldID0ge1xuICAgICAgICAgICRnZW9tZXRyeToge1xuICAgICAgICAgICAgdHlwZTogJ1BvaW50JyxcbiAgICAgICAgICAgIGNvb3JkaW5hdGVzOiBbcG9pbnQubG9uZ2l0dWRlLCBwb2ludC5sYXRpdHVkZV0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBpZiAoa2V5Lm1hdGNoKC9eXFwkKy8pKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2JhZCBjb25zdHJhaW50OiAnICsga2V5KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gQ2Fubm90VHJhbnNmb3JtO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYW5zd2VyO1xufVxuXG4vLyBUcmFuc2Zvcm1zIGFuIHVwZGF0ZSBvcGVyYXRvciBmcm9tIFJFU1QgZm9ybWF0IHRvIG1vbmdvIGZvcm1hdC5cbi8vIFRvIGJlIHRyYW5zZm9ybWVkLCB0aGUgaW5wdXQgc2hvdWxkIGhhdmUgYW4gX19vcCBmaWVsZC5cbi8vIElmIGZsYXR0ZW4gaXMgdHJ1ZSwgdGhpcyB3aWxsIGZsYXR0ZW4gb3BlcmF0b3JzIHRvIHRoZWlyIHN0YXRpY1xuLy8gZGF0YSBmb3JtYXQuIEZvciBleGFtcGxlLCBhbiBpbmNyZW1lbnQgb2YgMiB3b3VsZCBzaW1wbHkgYmVjb21lIGFcbi8vIDIuXG4vLyBUaGUgb3V0cHV0IGZvciBhIG5vbi1mbGF0dGVuZWQgb3BlcmF0b3IgaXMgYSBoYXNoIHdpdGggX19vcCBiZWluZ1xuLy8gdGhlIG1vbmdvIG9wLCBhbmQgYXJnIGJlaW5nIHRoZSBhcmd1bWVudC5cbi8vIFRoZSBvdXRwdXQgZm9yIGEgZmxhdHRlbmVkIG9wZXJhdG9yIGlzIGp1c3QgYSB2YWx1ZS5cbi8vIFJldHVybnMgdW5kZWZpbmVkIGlmIHRoaXMgc2hvdWxkIGJlIGEgbm8tb3AuXG5cbmZ1bmN0aW9uIHRyYW5zZm9ybVVwZGF0ZU9wZXJhdG9yKHsgX19vcCwgYW1vdW50LCBvYmplY3RzIH0sIGZsYXR0ZW4pIHtcbiAgc3dpdGNoIChfX29wKSB7XG4gICAgY2FzZSAnRGVsZXRlJzpcbiAgICAgIGlmIChmbGF0dGVuKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4geyBfX29wOiAnJHVuc2V0JywgYXJnOiAnJyB9O1xuICAgICAgfVxuXG4gICAgY2FzZSAnSW5jcmVtZW50JzpcbiAgICAgIGlmICh0eXBlb2YgYW1vdW50ICE9PSAnbnVtYmVyJykge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnaW5jcmVtZW50aW5nIG11c3QgcHJvdmlkZSBhIG51bWJlcicpO1xuICAgICAgfVxuICAgICAgaWYgKGZsYXR0ZW4pIHtcbiAgICAgICAgcmV0dXJuIGFtb3VudDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB7IF9fb3A6ICckaW5jJywgYXJnOiBhbW91bnQgfTtcbiAgICAgIH1cblxuICAgIGNhc2UgJ0FkZCc6XG4gICAgY2FzZSAnQWRkVW5pcXVlJzpcbiAgICAgIGlmICghKG9iamVjdHMgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ29iamVjdHMgdG8gYWRkIG11c3QgYmUgYW4gYXJyYXknKTtcbiAgICAgIH1cbiAgICAgIHZhciB0b0FkZCA9IG9iamVjdHMubWFwKHRyYW5zZm9ybUludGVyaW9yQXRvbSk7XG4gICAgICBpZiAoZmxhdHRlbikge1xuICAgICAgICByZXR1cm4gdG9BZGQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgbW9uZ29PcCA9IHtcbiAgICAgICAgICBBZGQ6ICckcHVzaCcsXG4gICAgICAgICAgQWRkVW5pcXVlOiAnJGFkZFRvU2V0JyxcbiAgICAgICAgfVtfX29wXTtcbiAgICAgICAgcmV0dXJuIHsgX19vcDogbW9uZ29PcCwgYXJnOiB7ICRlYWNoOiB0b0FkZCB9IH07XG4gICAgICB9XG5cbiAgICBjYXNlICdSZW1vdmUnOlxuICAgICAgaWYgKCEob2JqZWN0cyBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnb2JqZWN0cyB0byByZW1vdmUgbXVzdCBiZSBhbiBhcnJheScpO1xuICAgICAgfVxuICAgICAgdmFyIHRvUmVtb3ZlID0gb2JqZWN0cy5tYXAodHJhbnNmb3JtSW50ZXJpb3JBdG9tKTtcbiAgICAgIGlmIChmbGF0dGVuKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB7IF9fb3A6ICckcHVsbEFsbCcsIGFyZzogdG9SZW1vdmUgfTtcbiAgICAgIH1cblxuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLkNPTU1BTkRfVU5BVkFJTEFCTEUsXG4gICAgICAgIGBUaGUgJHtfX29wfSBvcGVyYXRvciBpcyBub3Qgc3VwcG9ydGVkIHlldC5gXG4gICAgICApO1xuICB9XG59XG5mdW5jdGlvbiBtYXBWYWx1ZXMob2JqZWN0LCBpdGVyYXRvcikge1xuICBjb25zdCByZXN1bHQgPSB7fTtcbiAgT2JqZWN0LmtleXMob2JqZWN0KS5mb3JFYWNoKGtleSA9PiB7XG4gICAgcmVzdWx0W2tleV0gPSBpdGVyYXRvcihvYmplY3Rba2V5XSk7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5jb25zdCBuZXN0ZWRNb25nb09iamVjdFRvTmVzdGVkUGFyc2VPYmplY3QgPSBtb25nb09iamVjdCA9PiB7XG4gIHN3aXRjaCAodHlwZW9mIG1vbmdvT2JqZWN0KSB7XG4gICAgY2FzZSAnc3RyaW5nJzpcbiAgICBjYXNlICdudW1iZXInOlxuICAgIGNhc2UgJ2Jvb2xlYW4nOlxuICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgICByZXR1cm4gbW9uZ29PYmplY3Q7XG4gICAgY2FzZSAnc3ltYm9sJzpcbiAgICBjYXNlICdmdW5jdGlvbic6XG4gICAgICB0aHJvdyAnYmFkIHZhbHVlIGluIG5lc3RlZE1vbmdvT2JqZWN0VG9OZXN0ZWRQYXJzZU9iamVjdCc7XG4gICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgIGlmIChtb25nb09iamVjdCA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChtb25nb09iamVjdCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgIHJldHVybiBtb25nb09iamVjdC5tYXAobmVzdGVkTW9uZ29PYmplY3RUb05lc3RlZFBhcnNlT2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1vbmdvT2JqZWN0IGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICByZXR1cm4gUGFyc2UuX2VuY29kZShtb25nb09iamVjdCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChtb25nb09iamVjdCBpbnN0YW5jZW9mIG1vbmdvZGIuTG9uZykge1xuICAgICAgICByZXR1cm4gbW9uZ29PYmplY3QudG9OdW1iZXIoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1vbmdvT2JqZWN0IGluc3RhbmNlb2YgbW9uZ29kYi5Eb3VibGUpIHtcbiAgICAgICAgcmV0dXJuIG1vbmdvT2JqZWN0LnZhbHVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoQnl0ZXNDb2Rlci5pc1ZhbGlkRGF0YWJhc2VPYmplY3QobW9uZ29PYmplY3QpKSB7XG4gICAgICAgIHJldHVybiBCeXRlc0NvZGVyLmRhdGFiYXNlVG9KU09OKG1vbmdvT2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobW9uZ29PYmplY3QsICdfX3R5cGUnKSAmJlxuICAgICAgICBtb25nb09iamVjdC5fX3R5cGUgPT0gJ0RhdGUnICYmXG4gICAgICAgIG1vbmdvT2JqZWN0LmlzbyBpbnN0YW5jZW9mIERhdGVcbiAgICAgICkge1xuICAgICAgICBtb25nb09iamVjdC5pc28gPSBtb25nb09iamVjdC5pc28udG9KU09OKCk7XG4gICAgICAgIHJldHVybiBtb25nb09iamVjdDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG1hcFZhbHVlcyhtb25nb09iamVjdCwgbmVzdGVkTW9uZ29PYmplY3RUb05lc3RlZFBhcnNlT2JqZWN0KTtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgJ3Vua25vd24ganMgdHlwZSc7XG4gIH1cbn07XG5cbmNvbnN0IHRyYW5zZm9ybVBvaW50ZXJTdHJpbmcgPSAoc2NoZW1hLCBmaWVsZCwgcG9pbnRlclN0cmluZykgPT4ge1xuICBjb25zdCBvYmpEYXRhID0gcG9pbnRlclN0cmluZy5zcGxpdCgnJCcpO1xuICBpZiAob2JqRGF0YVswXSAhPT0gc2NoZW1hLmZpZWxkc1tmaWVsZF0udGFyZ2V0Q2xhc3MpIHtcbiAgICB0aHJvdyAncG9pbnRlciB0byBpbmNvcnJlY3QgY2xhc3NOYW1lJztcbiAgfVxuICByZXR1cm4ge1xuICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgIGNsYXNzTmFtZTogb2JqRGF0YVswXSxcbiAgICBvYmplY3RJZDogb2JqRGF0YVsxXSxcbiAgfTtcbn07XG5cbi8vIENvbnZlcnRzIGZyb20gYSBtb25nby1mb3JtYXQgb2JqZWN0IHRvIGEgUkVTVC1mb3JtYXQgb2JqZWN0LlxuLy8gRG9lcyBub3Qgc3RyaXAgb3V0IGFueXRoaW5nIGJhc2VkIG9uIGEgbGFjayBvZiBhdXRoZW50aWNhdGlvbi5cbmNvbnN0IG1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdCA9IChjbGFzc05hbWUsIG1vbmdvT2JqZWN0LCBzY2hlbWEpID0+IHtcbiAgc3dpdGNoICh0eXBlb2YgbW9uZ29PYmplY3QpIHtcbiAgICBjYXNlICdzdHJpbmcnOlxuICAgIGNhc2UgJ251bWJlcic6XG4gICAgY2FzZSAnYm9vbGVhbic6XG4gICAgY2FzZSAndW5kZWZpbmVkJzpcbiAgICAgIHJldHVybiBtb25nb09iamVjdDtcbiAgICBjYXNlICdzeW1ib2wnOlxuICAgIGNhc2UgJ2Z1bmN0aW9uJzpcbiAgICAgIHRocm93ICdiYWQgdmFsdWUgaW4gbW9uZ29PYmplY3RUb1BhcnNlT2JqZWN0JztcbiAgICBjYXNlICdvYmplY3QnOiB7XG4gICAgICBpZiAobW9uZ29PYmplY3QgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICBpZiAobW9uZ29PYmplY3QgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICByZXR1cm4gbW9uZ29PYmplY3QubWFwKG5lc3RlZE1vbmdvT2JqZWN0VG9OZXN0ZWRQYXJzZU9iamVjdCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChtb25nb09iamVjdCBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgcmV0dXJuIFBhcnNlLl9lbmNvZGUobW9uZ29PYmplY3QpO1xuICAgICAgfVxuXG4gICAgICBpZiAobW9uZ29PYmplY3QgaW5zdGFuY2VvZiBtb25nb2RiLkxvbmcpIHtcbiAgICAgICAgcmV0dXJuIG1vbmdvT2JqZWN0LnRvTnVtYmVyKCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChtb25nb09iamVjdCBpbnN0YW5jZW9mIG1vbmdvZGIuRG91YmxlKSB7XG4gICAgICAgIHJldHVybiBtb25nb09iamVjdC52YWx1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKEJ5dGVzQ29kZXIuaXNWYWxpZERhdGFiYXNlT2JqZWN0KG1vbmdvT2JqZWN0KSkge1xuICAgICAgICByZXR1cm4gQnl0ZXNDb2Rlci5kYXRhYmFzZVRvSlNPTihtb25nb09iamVjdCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlc3RPYmplY3QgPSB7fTtcbiAgICAgIGlmIChtb25nb09iamVjdC5fcnBlcm0gfHwgbW9uZ29PYmplY3QuX3dwZXJtKSB7XG4gICAgICAgIHJlc3RPYmplY3QuX3JwZXJtID0gbW9uZ29PYmplY3QuX3JwZXJtIHx8IFtdO1xuICAgICAgICByZXN0T2JqZWN0Ll93cGVybSA9IG1vbmdvT2JqZWN0Ll93cGVybSB8fCBbXTtcbiAgICAgICAgZGVsZXRlIG1vbmdvT2JqZWN0Ll9ycGVybTtcbiAgICAgICAgZGVsZXRlIG1vbmdvT2JqZWN0Ll93cGVybTtcbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIga2V5IGluIG1vbmdvT2JqZWN0KSB7XG4gICAgICAgIHN3aXRjaCAoa2V5KSB7XG4gICAgICAgICAgY2FzZSAnX2lkJzpcbiAgICAgICAgICAgIHJlc3RPYmplY3RbJ29iamVjdElkJ10gPSAnJyArIG1vbmdvT2JqZWN0W2tleV07XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdfaGFzaGVkX3Bhc3N3b3JkJzpcbiAgICAgICAgICAgIHJlc3RPYmplY3QuX2hhc2hlZF9wYXNzd29yZCA9IG1vbmdvT2JqZWN0W2tleV07XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdfYWNsJzpcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ19lbWFpbF92ZXJpZnlfdG9rZW4nOlxuICAgICAgICAgIGNhc2UgJ19wZXJpc2hhYmxlX3Rva2VuJzpcbiAgICAgICAgICBjYXNlICdfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0JzpcbiAgICAgICAgICBjYXNlICdfcGFzc3dvcmRfY2hhbmdlZF9hdCc6XG4gICAgICAgICAgY2FzZSAnX3RvbWJzdG9uZSc6XG4gICAgICAgICAgY2FzZSAnX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0JzpcbiAgICAgICAgICBjYXNlICdfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQnOlxuICAgICAgICAgIGNhc2UgJ19mYWlsZWRfbG9naW5fY291bnQnOlxuICAgICAgICAgIGNhc2UgJ19wYXNzd29yZF9oaXN0b3J5JzpcbiAgICAgICAgICAgIC8vIFRob3NlIGtleXMgd2lsbCBiZSBkZWxldGVkIGlmIG5lZWRlZCBpbiB0aGUgREIgQ29udHJvbGxlclxuICAgICAgICAgICAgcmVzdE9iamVjdFtrZXldID0gbW9uZ29PYmplY3Rba2V5XTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ19zZXNzaW9uX3Rva2VuJzpcbiAgICAgICAgICAgIHJlc3RPYmplY3RbJ3Nlc3Npb25Ub2tlbiddID0gbW9uZ29PYmplY3Rba2V5XTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ3VwZGF0ZWRBdCc6XG4gICAgICAgICAgY2FzZSAnX3VwZGF0ZWRfYXQnOlxuICAgICAgICAgICAgcmVzdE9iamVjdFsndXBkYXRlZEF0J10gPSBQYXJzZS5fZW5jb2RlKG5ldyBEYXRlKG1vbmdvT2JqZWN0W2tleV0pKS5pc287XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdjcmVhdGVkQXQnOlxuICAgICAgICAgIGNhc2UgJ19jcmVhdGVkX2F0JzpcbiAgICAgICAgICAgIHJlc3RPYmplY3RbJ2NyZWF0ZWRBdCddID0gUGFyc2UuX2VuY29kZShuZXcgRGF0ZShtb25nb09iamVjdFtrZXldKSkuaXNvO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZXhwaXJlc0F0JzpcbiAgICAgICAgICBjYXNlICdfZXhwaXJlc0F0JzpcbiAgICAgICAgICAgIHJlc3RPYmplY3RbJ2V4cGlyZXNBdCddID0gUGFyc2UuX2VuY29kZShuZXcgRGF0ZShtb25nb09iamVjdFtrZXldKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdsYXN0VXNlZCc6XG4gICAgICAgICAgY2FzZSAnX2xhc3RfdXNlZCc6XG4gICAgICAgICAgICByZXN0T2JqZWN0WydsYXN0VXNlZCddID0gUGFyc2UuX2VuY29kZShuZXcgRGF0ZShtb25nb09iamVjdFtrZXldKSkuaXNvO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAndGltZXNVc2VkJzpcbiAgICAgICAgICBjYXNlICd0aW1lc191c2VkJzpcbiAgICAgICAgICAgIHJlc3RPYmplY3RbJ3RpbWVzVXNlZCddID0gbW9uZ29PYmplY3Rba2V5XTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ2F1dGhEYXRhJzpcbiAgICAgICAgICAgIGlmIChjbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICAgICAgICAgICAgbG9nLndhcm4oXG4gICAgICAgICAgICAgICAgJ2lnbm9yaW5nIGF1dGhEYXRhIGluIF9Vc2VyIGFzIHRoaXMga2V5IGlzIHJlc2VydmVkIHRvIGJlIHN5bnRoZXNpemVkIG9mIGBfYXV0aF9kYXRhXypgIGtleXMnXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXN0T2JqZWN0WydhdXRoRGF0YSddID0gbW9uZ29PYmplY3Rba2V5XTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAvLyBDaGVjayBvdGhlciBhdXRoIGRhdGEga2V5c1xuICAgICAgICAgICAgdmFyIGF1dGhEYXRhTWF0Y2ggPSBrZXkubWF0Y2goL15fYXV0aF9kYXRhXyhbYS16QS1aMC05X10rKSQvKTtcbiAgICAgICAgICAgIGlmIChhdXRoRGF0YU1hdGNoICYmIGNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgICAgICAgICAgICB2YXIgcHJvdmlkZXIgPSBhdXRoRGF0YU1hdGNoWzFdO1xuICAgICAgICAgICAgICByZXN0T2JqZWN0WydhdXRoRGF0YSddID0gcmVzdE9iamVjdFsnYXV0aERhdGEnXSB8fCB7fTtcbiAgICAgICAgICAgICAgcmVzdE9iamVjdFsnYXV0aERhdGEnXVtwcm92aWRlcl0gPSBtb25nb09iamVjdFtrZXldO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGtleS5pbmRleE9mKCdfcF8nKSA9PSAwKSB7XG4gICAgICAgICAgICAgIHZhciBuZXdLZXkgPSBrZXkuc3Vic3RyaW5nKDMpO1xuICAgICAgICAgICAgICBpZiAoIXNjaGVtYS5maWVsZHNbbmV3S2V5XSkge1xuICAgICAgICAgICAgICAgIGxvZy5pbmZvKFxuICAgICAgICAgICAgICAgICAgJ3RyYW5zZm9ybS5qcycsXG4gICAgICAgICAgICAgICAgICAnRm91bmQgYSBwb2ludGVyIGNvbHVtbiBub3QgaW4gdGhlIHNjaGVtYSwgZHJvcHBpbmcgaXQuJyxcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgIG5ld0tleVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKHNjaGVtYS5maWVsZHNbbmV3S2V5XS50eXBlICE9PSAnUG9pbnRlcicpIHtcbiAgICAgICAgICAgICAgICBsb2cuaW5mbyhcbiAgICAgICAgICAgICAgICAgICd0cmFuc2Zvcm0uanMnLFxuICAgICAgICAgICAgICAgICAgJ0ZvdW5kIGEgcG9pbnRlciBpbiBhIG5vbi1wb2ludGVyIGNvbHVtbiwgZHJvcHBpbmcgaXQuJyxcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgIGtleVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKG1vbmdvT2JqZWN0W2tleV0gPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXN0T2JqZWN0W25ld0tleV0gPSB0cmFuc2Zvcm1Qb2ludGVyU3RyaW5nKHNjaGVtYSwgbmV3S2V5LCBtb25nb09iamVjdFtrZXldKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGtleVswXSA9PSAnXycgJiYga2V5ICE9ICdfX3R5cGUnKSB7XG4gICAgICAgICAgICAgIHRocm93ICdiYWQga2V5IGluIHVudHJhbnNmb3JtOiAnICsga2V5O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdmFyIHZhbHVlID0gbW9uZ29PYmplY3Rba2V5XTtcbiAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHNjaGVtYS5maWVsZHNba2V5XSAmJlxuICAgICAgICAgICAgICAgIHNjaGVtYS5maWVsZHNba2V5XS50eXBlID09PSAnRmlsZScgJiZcbiAgICAgICAgICAgICAgICBGaWxlQ29kZXIuaXNWYWxpZERhdGFiYXNlT2JqZWN0KHZhbHVlKVxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICByZXN0T2JqZWN0W2tleV0gPSBGaWxlQ29kZXIuZGF0YWJhc2VUb0pTT04odmFsdWUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBzY2hlbWEuZmllbGRzW2tleV0gJiZcbiAgICAgICAgICAgICAgICBzY2hlbWEuZmllbGRzW2tleV0udHlwZSA9PT0gJ0dlb1BvaW50JyAmJlxuICAgICAgICAgICAgICAgIEdlb1BvaW50Q29kZXIuaXNWYWxpZERhdGFiYXNlT2JqZWN0KHZhbHVlKVxuICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICByZXN0T2JqZWN0W2tleV0gPSBHZW9Qb2ludENvZGVyLmRhdGFiYXNlVG9KU09OKHZhbHVlKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgc2NoZW1hLmZpZWxkc1trZXldICYmXG4gICAgICAgICAgICAgICAgc2NoZW1hLmZpZWxkc1trZXldLnR5cGUgPT09ICdQb2x5Z29uJyAmJlxuICAgICAgICAgICAgICAgIFBvbHlnb25Db2Rlci5pc1ZhbGlkRGF0YWJhc2VPYmplY3QodmFsdWUpXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHJlc3RPYmplY3Rba2V5XSA9IFBvbHlnb25Db2Rlci5kYXRhYmFzZVRvSlNPTih2YWx1ZSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHNjaGVtYS5maWVsZHNba2V5XSAmJlxuICAgICAgICAgICAgICAgIHNjaGVtYS5maWVsZHNba2V5XS50eXBlID09PSAnQnl0ZXMnICYmXG4gICAgICAgICAgICAgICAgQnl0ZXNDb2Rlci5pc1ZhbGlkRGF0YWJhc2VPYmplY3QodmFsdWUpXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIHJlc3RPYmplY3Rba2V5XSA9IEJ5dGVzQ29kZXIuZGF0YWJhc2VUb0pTT04odmFsdWUpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXN0T2JqZWN0W2tleV0gPSBuZXN0ZWRNb25nb09iamVjdFRvTmVzdGVkUGFyc2VPYmplY3QobW9uZ29PYmplY3Rba2V5XSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVsYXRpb25GaWVsZE5hbWVzID0gT2JqZWN0LmtleXMoc2NoZW1hLmZpZWxkcykuZmlsdGVyKFxuICAgICAgICBmaWVsZE5hbWUgPT4gc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdSZWxhdGlvbidcbiAgICAgICk7XG4gICAgICBjb25zdCByZWxhdGlvbkZpZWxkcyA9IHt9O1xuICAgICAgcmVsYXRpb25GaWVsZE5hbWVzLmZvckVhY2gocmVsYXRpb25GaWVsZE5hbWUgPT4ge1xuICAgICAgICByZWxhdGlvbkZpZWxkc1tyZWxhdGlvbkZpZWxkTmFtZV0gPSB7XG4gICAgICAgICAgX190eXBlOiAnUmVsYXRpb24nLFxuICAgICAgICAgIGNsYXNzTmFtZTogc2NoZW1hLmZpZWxkc1tyZWxhdGlvbkZpZWxkTmFtZV0udGFyZ2V0Q2xhc3MsXG4gICAgICAgIH07XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHsgLi4ucmVzdE9iamVjdCwgLi4ucmVsYXRpb25GaWVsZHMgfTtcbiAgICB9XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93ICd1bmtub3duIGpzIHR5cGUnO1xuICB9XG59O1xuXG52YXIgRGF0ZUNvZGVyID0ge1xuICBKU09OVG9EYXRhYmFzZShqc29uKSB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKGpzb24uaXNvKTtcbiAgfSxcblxuICBpc1ZhbGlkSlNPTih2YWx1ZSkge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmIHZhbHVlLl9fdHlwZSA9PT0gJ0RhdGUnO1xuICB9LFxufTtcblxudmFyIEJ5dGVzQ29kZXIgPSB7XG4gIGJhc2U2NFBhdHRlcm46IG5ldyBSZWdFeHAoJ14oPzpbQS1aYS16MC05Ky9dezR9KSooPzpbQS1aYS16MC05Ky9dezJ9PT18W0EtWmEtejAtOSsvXXszfT0pPyQnKSxcbiAgaXNCYXNlNjRWYWx1ZShvYmplY3QpIHtcbiAgICBpZiAodHlwZW9mIG9iamVjdCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYmFzZTY0UGF0dGVybi50ZXN0KG9iamVjdCk7XG4gIH0sXG5cbiAgZGF0YWJhc2VUb0pTT04ob2JqZWN0KSB7XG4gICAgbGV0IHZhbHVlO1xuICAgIGlmICh0aGlzLmlzQmFzZTY0VmFsdWUob2JqZWN0KSkge1xuICAgICAgdmFsdWUgPSBvYmplY3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlID0gb2JqZWN0LmJ1ZmZlci50b1N0cmluZygnYmFzZTY0Jyk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBfX3R5cGU6ICdCeXRlcycsXG4gICAgICBiYXNlNjQ6IHZhbHVlLFxuICAgIH07XG4gIH0sXG5cbiAgaXNWYWxpZERhdGFiYXNlT2JqZWN0KG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBtb25nb2RiLkJpbmFyeSB8fCB0aGlzLmlzQmFzZTY0VmFsdWUob2JqZWN0KTtcbiAgfSxcblxuICBKU09OVG9EYXRhYmFzZShqc29uKSB7XG4gICAgcmV0dXJuIG5ldyBtb25nb2RiLkJpbmFyeShCdWZmZXIuZnJvbShqc29uLmJhc2U2NCwgJ2Jhc2U2NCcpKTtcbiAgfSxcblxuICBpc1ZhbGlkSlNPTih2YWx1ZSkge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmIHZhbHVlLl9fdHlwZSA9PT0gJ0J5dGVzJztcbiAgfSxcbn07XG5cbnZhciBHZW9Qb2ludENvZGVyID0ge1xuICBkYXRhYmFzZVRvSlNPTihvYmplY3QpIHtcbiAgICByZXR1cm4ge1xuICAgICAgX190eXBlOiAnR2VvUG9pbnQnLFxuICAgICAgbGF0aXR1ZGU6IG9iamVjdFsxXSxcbiAgICAgIGxvbmdpdHVkZTogb2JqZWN0WzBdLFxuICAgIH07XG4gIH0sXG5cbiAgaXNWYWxpZERhdGFiYXNlT2JqZWN0KG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBBcnJheSAmJiBvYmplY3QubGVuZ3RoID09IDI7XG4gIH0sXG5cbiAgSlNPTlRvRGF0YWJhc2UoanNvbikge1xuICAgIHJldHVybiBbanNvbi5sb25naXR1ZGUsIGpzb24ubGF0aXR1ZGVdO1xuICB9LFxuXG4gIGlzVmFsaWRKU09OKHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgdmFsdWUuX190eXBlID09PSAnR2VvUG9pbnQnO1xuICB9LFxufTtcblxudmFyIFBvbHlnb25Db2RlciA9IHtcbiAgZGF0YWJhc2VUb0pTT04ob2JqZWN0KSB7XG4gICAgLy8gQ29udmVydCBsbmcvbGF0IC0+IGxhdC9sbmdcbiAgICBjb25zdCBjb29yZHMgPSBvYmplY3QuY29vcmRpbmF0ZXNbMF0ubWFwKGNvb3JkID0+IHtcbiAgICAgIHJldHVybiBbY29vcmRbMV0sIGNvb3JkWzBdXTtcbiAgICB9KTtcbiAgICByZXR1cm4ge1xuICAgICAgX190eXBlOiAnUG9seWdvbicsXG4gICAgICBjb29yZGluYXRlczogY29vcmRzLFxuICAgIH07XG4gIH0sXG5cbiAgaXNWYWxpZERhdGFiYXNlT2JqZWN0KG9iamVjdCkge1xuICAgIGNvbnN0IGNvb3JkcyA9IG9iamVjdC5jb29yZGluYXRlc1swXTtcbiAgICBpZiAob2JqZWN0LnR5cGUgIT09ICdQb2x5Z29uJyB8fCAhKGNvb3JkcyBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvb3Jkcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgcG9pbnQgPSBjb29yZHNbaV07XG4gICAgICBpZiAoIUdlb1BvaW50Q29kZXIuaXNWYWxpZERhdGFiYXNlT2JqZWN0KHBvaW50KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICBQYXJzZS5HZW9Qb2ludC5fdmFsaWRhdGUocGFyc2VGbG9hdChwb2ludFsxXSksIHBhcnNlRmxvYXQocG9pbnRbMF0pKTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH0sXG5cbiAgSlNPTlRvRGF0YWJhc2UoanNvbikge1xuICAgIGxldCBjb29yZHMgPSBqc29uLmNvb3JkaW5hdGVzO1xuICAgIC8vIEFkZCBmaXJzdCBwb2ludCB0byB0aGUgZW5kIHRvIGNsb3NlIHBvbHlnb25cbiAgICBpZiAoXG4gICAgICBjb29yZHNbMF1bMF0gIT09IGNvb3Jkc1tjb29yZHMubGVuZ3RoIC0gMV1bMF0gfHxcbiAgICAgIGNvb3Jkc1swXVsxXSAhPT0gY29vcmRzW2Nvb3Jkcy5sZW5ndGggLSAxXVsxXVxuICAgICkge1xuICAgICAgY29vcmRzLnB1c2goY29vcmRzWzBdKTtcbiAgICB9XG4gICAgY29uc3QgdW5pcXVlID0gY29vcmRzLmZpbHRlcigoaXRlbSwgaW5kZXgsIGFyKSA9PiB7XG4gICAgICBsZXQgZm91bmRJbmRleCA9IC0xO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhci5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBjb25zdCBwdCA9IGFyW2ldO1xuICAgICAgICBpZiAocHRbMF0gPT09IGl0ZW1bMF0gJiYgcHRbMV0gPT09IGl0ZW1bMV0pIHtcbiAgICAgICAgICBmb3VuZEluZGV4ID0gaTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZvdW5kSW5kZXggPT09IGluZGV4O1xuICAgIH0pO1xuICAgIGlmICh1bmlxdWUubGVuZ3RoIDwgMykge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsXG4gICAgICAgICdHZW9KU09OOiBMb29wIG11c3QgaGF2ZSBhdCBsZWFzdCAzIGRpZmZlcmVudCB2ZXJ0aWNlcydcbiAgICAgICk7XG4gICAgfVxuICAgIC8vIENvbnZlcnQgbGF0L2xvbmcgLT4gbG9uZy9sYXRcbiAgICBjb29yZHMgPSBjb29yZHMubWFwKGNvb3JkID0+IHtcbiAgICAgIHJldHVybiBbY29vcmRbMV0sIGNvb3JkWzBdXTtcbiAgICB9KTtcbiAgICByZXR1cm4geyB0eXBlOiAnUG9seWdvbicsIGNvb3JkaW5hdGVzOiBbY29vcmRzXSB9O1xuICB9LFxuXG4gIGlzVmFsaWRKU09OKHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgdmFsdWUuX190eXBlID09PSAnUG9seWdvbic7XG4gIH0sXG59O1xuXG52YXIgRmlsZUNvZGVyID0ge1xuICBkYXRhYmFzZVRvSlNPTihvYmplY3QpIHtcbiAgICByZXR1cm4ge1xuICAgICAgX190eXBlOiAnRmlsZScsXG4gICAgICBuYW1lOiBvYmplY3QsXG4gICAgfTtcbiAgfSxcblxuICBpc1ZhbGlkRGF0YWJhc2VPYmplY3Qob2JqZWN0KSB7XG4gICAgcmV0dXJuIHR5cGVvZiBvYmplY3QgPT09ICdzdHJpbmcnO1xuICB9LFxuXG4gIEpTT05Ub0RhdGFiYXNlKGpzb24pIHtcbiAgICByZXR1cm4ganNvbi5uYW1lO1xuICB9LFxuXG4gIGlzVmFsaWRKU09OKHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgdmFsdWUuX190eXBlID09PSAnRmlsZSc7XG4gIH0sXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdHJhbnNmb3JtS2V5LFxuICBwYXJzZU9iamVjdFRvTW9uZ29PYmplY3RGb3JDcmVhdGUsXG4gIHRyYW5zZm9ybVVwZGF0ZSxcbiAgdHJhbnNmb3JtV2hlcmUsXG4gIG1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdCxcbiAgcmVsYXRpdmVUaW1lVG9EYXRlLFxuICB0cmFuc2Zvcm1Db25zdHJhaW50LFxuICB0cmFuc2Zvcm1Qb2ludGVyU3RyaW5nLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/PostgresClient.js b/lib/Adapters/Storage/Postgres/PostgresClient.js deleted file mode 100644 index 9c2899b4d5..0000000000 --- a/lib/Adapters/Storage/Postgres/PostgresClient.js +++ /dev/null @@ -1,40 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.createClient = createClient; - -const parser = require('./PostgresConfigParser'); - -function createClient(uri, databaseOptions) { - let dbOptions = {}; - databaseOptions = databaseOptions || {}; - - if (uri) { - dbOptions = parser.getDatabaseOptionsFromURI(uri); - } - - for (const key in databaseOptions) { - dbOptions[key] = databaseOptions[key]; - } - - const initOptions = dbOptions.initOptions || {}; - initOptions.noWarnings = process && process.env.TESTING; - - const pgp = require('pg-promise')(initOptions); - - const client = pgp(dbOptions); - - if (dbOptions.pgOptions) { - for (const key in dbOptions.pgOptions) { - pgp.pg.defaults[key] = dbOptions.pgOptions[key]; - } - } - - return { - client, - pgp - }; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL1Bvc3RncmVzL1Bvc3RncmVzQ2xpZW50LmpzIl0sIm5hbWVzIjpbInBhcnNlciIsInJlcXVpcmUiLCJjcmVhdGVDbGllbnQiLCJ1cmkiLCJkYXRhYmFzZU9wdGlvbnMiLCJkYk9wdGlvbnMiLCJnZXREYXRhYmFzZU9wdGlvbnNGcm9tVVJJIiwia2V5IiwiaW5pdE9wdGlvbnMiLCJub1dhcm5pbmdzIiwicHJvY2VzcyIsImVudiIsIlRFU1RJTkciLCJwZ3AiLCJjbGllbnQiLCJwZ09wdGlvbnMiLCJwZyIsImRlZmF1bHRzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUEsTUFBTUEsTUFBTSxHQUFHQyxPQUFPLENBQUMsd0JBQUQsQ0FBdEI7O0FBRU8sU0FBU0MsWUFBVCxDQUFzQkMsR0FBdEIsRUFBMkJDLGVBQTNCLEVBQTRDO0FBQ2pELE1BQUlDLFNBQVMsR0FBRyxFQUFoQjtBQUNBRCxFQUFBQSxlQUFlLEdBQUdBLGVBQWUsSUFBSSxFQUFyQzs7QUFFQSxNQUFJRCxHQUFKLEVBQVM7QUFDUEUsSUFBQUEsU0FBUyxHQUFHTCxNQUFNLENBQUNNLHlCQUFQLENBQWlDSCxHQUFqQyxDQUFaO0FBQ0Q7O0FBRUQsT0FBSyxNQUFNSSxHQUFYLElBQWtCSCxlQUFsQixFQUFtQztBQUNqQ0MsSUFBQUEsU0FBUyxDQUFDRSxHQUFELENBQVQsR0FBaUJILGVBQWUsQ0FBQ0csR0FBRCxDQUFoQztBQUNEOztBQUVELFFBQU1DLFdBQVcsR0FBR0gsU0FBUyxDQUFDRyxXQUFWLElBQXlCLEVBQTdDO0FBQ0FBLEVBQUFBLFdBQVcsQ0FBQ0MsVUFBWixHQUF5QkMsT0FBTyxJQUFJQSxPQUFPLENBQUNDLEdBQVIsQ0FBWUMsT0FBaEQ7O0FBRUEsUUFBTUMsR0FBRyxHQUFHWixPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCTyxXQUF0QixDQUFaOztBQUNBLFFBQU1NLE1BQU0sR0FBR0QsR0FBRyxDQUFDUixTQUFELENBQWxCOztBQUVBLE1BQUlBLFNBQVMsQ0FBQ1UsU0FBZCxFQUF5QjtBQUN2QixTQUFLLE1BQU1SLEdBQVgsSUFBa0JGLFNBQVMsQ0FBQ1UsU0FBNUIsRUFBdUM7QUFDckNGLE1BQUFBLEdBQUcsQ0FBQ0csRUFBSixDQUFPQyxRQUFQLENBQWdCVixHQUFoQixJQUF1QkYsU0FBUyxDQUFDVSxTQUFWLENBQW9CUixHQUFwQixDQUF2QjtBQUNEO0FBQ0Y7O0FBRUQsU0FBTztBQUFFTyxJQUFBQSxNQUFGO0FBQVVELElBQUFBO0FBQVYsR0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgcGFyc2VyID0gcmVxdWlyZSgnLi9Qb3N0Z3Jlc0NvbmZpZ1BhcnNlcicpO1xuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ2xpZW50KHVyaSwgZGF0YWJhc2VPcHRpb25zKSB7XG4gIGxldCBkYk9wdGlvbnMgPSB7fTtcbiAgZGF0YWJhc2VPcHRpb25zID0gZGF0YWJhc2VPcHRpb25zIHx8IHt9O1xuXG4gIGlmICh1cmkpIHtcbiAgICBkYk9wdGlvbnMgPSBwYXJzZXIuZ2V0RGF0YWJhc2VPcHRpb25zRnJvbVVSSSh1cmkpO1xuICB9XG5cbiAgZm9yIChjb25zdCBrZXkgaW4gZGF0YWJhc2VPcHRpb25zKSB7XG4gICAgZGJPcHRpb25zW2tleV0gPSBkYXRhYmFzZU9wdGlvbnNba2V5XTtcbiAgfVxuXG4gIGNvbnN0IGluaXRPcHRpb25zID0gZGJPcHRpb25zLmluaXRPcHRpb25zIHx8IHt9O1xuICBpbml0T3B0aW9ucy5ub1dhcm5pbmdzID0gcHJvY2VzcyAmJiBwcm9jZXNzLmVudi5URVNUSU5HO1xuXG4gIGNvbnN0IHBncCA9IHJlcXVpcmUoJ3BnLXByb21pc2UnKShpbml0T3B0aW9ucyk7XG4gIGNvbnN0IGNsaWVudCA9IHBncChkYk9wdGlvbnMpO1xuXG4gIGlmIChkYk9wdGlvbnMucGdPcHRpb25zKSB7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gZGJPcHRpb25zLnBnT3B0aW9ucykge1xuICAgICAgcGdwLnBnLmRlZmF1bHRzW2tleV0gPSBkYk9wdGlvbnMucGdPcHRpb25zW2tleV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgY2xpZW50LCBwZ3AgfTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/PostgresConfigParser.js b/lib/Adapters/Storage/Postgres/PostgresConfigParser.js deleted file mode 100644 index 2bd5b7fa6c..0000000000 --- a/lib/Adapters/Storage/Postgres/PostgresConfigParser.js +++ /dev/null @@ -1,95 +0,0 @@ -"use strict"; - -const url = require('url'); - -const fs = require('fs'); - -function getDatabaseOptionsFromURI(uri) { - const databaseOptions = {}; - const parsedURI = url.parse(uri); - const queryParams = parseQueryParams(parsedURI.query); - const authParts = parsedURI.auth ? parsedURI.auth.split(':') : []; - databaseOptions.host = parsedURI.hostname || 'localhost'; - databaseOptions.port = parsedURI.port ? parseInt(parsedURI.port) : 5432; - databaseOptions.database = parsedURI.pathname ? parsedURI.pathname.substr(1) : undefined; - databaseOptions.user = authParts.length > 0 ? authParts[0] : ''; - databaseOptions.password = authParts.length > 1 ? authParts[1] : ''; - - if (queryParams.ssl && queryParams.ssl.toLowerCase() === 'true') { - databaseOptions.ssl = true; - } - - if (queryParams.ca || queryParams.pfx || queryParams.cert || queryParams.key || queryParams.passphrase || queryParams.rejectUnauthorized || queryParams.secureOptions) { - databaseOptions.ssl = {}; - - if (queryParams.ca) { - databaseOptions.ssl.ca = fs.readFileSync(queryParams.ca).toString(); - } - - if (queryParams.pfx) { - databaseOptions.ssl.pfx = fs.readFileSync(queryParams.pfx).toString(); - } - - if (queryParams.cert) { - databaseOptions.ssl.cert = fs.readFileSync(queryParams.cert).toString(); - } - - if (queryParams.key) { - databaseOptions.ssl.key = fs.readFileSync(queryParams.key).toString(); - } - - if (queryParams.passphrase) { - databaseOptions.ssl.passphrase = queryParams.passphrase; - } - - if (queryParams.rejectUnauthorized) { - databaseOptions.ssl.rejectUnauthorized = queryParams.rejectUnauthorized.toLowerCase() === 'true' ? true : false; - } - - if (queryParams.secureOptions) { - databaseOptions.ssl.secureOptions = parseInt(queryParams.secureOptions); - } - } - - databaseOptions.binary = queryParams.binary && queryParams.binary.toLowerCase() === 'true' ? true : false; - databaseOptions.client_encoding = queryParams.client_encoding; - databaseOptions.application_name = queryParams.application_name; - databaseOptions.fallback_application_name = queryParams.fallback_application_name; - - if (queryParams.poolSize) { - databaseOptions.poolSize = parseInt(queryParams.poolSize) || 10; - } - - if (queryParams.max) { - databaseOptions.max = parseInt(queryParams.max) || 10; - } - - if (queryParams.query_timeout) { - databaseOptions.query_timeout = parseInt(queryParams.query_timeout); - } - - if (queryParams.idleTimeoutMillis) { - databaseOptions.idleTimeoutMillis = parseInt(queryParams.idleTimeoutMillis); - } - - if (queryParams.keepAlive) { - databaseOptions.keepAlive = queryParams.keepAlive.toLowerCase() === 'true' ? true : false; - } - - return databaseOptions; -} - -function parseQueryParams(queryString) { - queryString = queryString || ''; - return queryString.split('&').reduce((p, c) => { - const parts = c.split('='); - p[decodeURIComponent(parts[0])] = parts.length > 1 ? decodeURIComponent(parts.slice(1).join('=')) : ''; - return p; - }, {}); -} - -module.exports = { - parseQueryParams: parseQueryParams, - getDatabaseOptionsFromURI: getDatabaseOptionsFromURI -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL1Bvc3RncmVzL1Bvc3RncmVzQ29uZmlnUGFyc2VyLmpzIl0sIm5hbWVzIjpbInVybCIsInJlcXVpcmUiLCJmcyIsImdldERhdGFiYXNlT3B0aW9uc0Zyb21VUkkiLCJ1cmkiLCJkYXRhYmFzZU9wdGlvbnMiLCJwYXJzZWRVUkkiLCJwYXJzZSIsInF1ZXJ5UGFyYW1zIiwicGFyc2VRdWVyeVBhcmFtcyIsInF1ZXJ5IiwiYXV0aFBhcnRzIiwiYXV0aCIsInNwbGl0IiwiaG9zdCIsImhvc3RuYW1lIiwicG9ydCIsInBhcnNlSW50IiwiZGF0YWJhc2UiLCJwYXRobmFtZSIsInN1YnN0ciIsInVuZGVmaW5lZCIsInVzZXIiLCJsZW5ndGgiLCJwYXNzd29yZCIsInNzbCIsInRvTG93ZXJDYXNlIiwiY2EiLCJwZngiLCJjZXJ0Iiwia2V5IiwicGFzc3BocmFzZSIsInJlamVjdFVuYXV0aG9yaXplZCIsInNlY3VyZU9wdGlvbnMiLCJyZWFkRmlsZVN5bmMiLCJ0b1N0cmluZyIsImJpbmFyeSIsImNsaWVudF9lbmNvZGluZyIsImFwcGxpY2F0aW9uX25hbWUiLCJmYWxsYmFja19hcHBsaWNhdGlvbl9uYW1lIiwicG9vbFNpemUiLCJtYXgiLCJxdWVyeV90aW1lb3V0IiwiaWRsZVRpbWVvdXRNaWxsaXMiLCJrZWVwQWxpdmUiLCJxdWVyeVN0cmluZyIsInJlZHVjZSIsInAiLCJjIiwicGFydHMiLCJkZWNvZGVVUklDb21wb25lbnQiLCJzbGljZSIsImpvaW4iLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLE1BQU1BLEdBQUcsR0FBR0MsT0FBTyxDQUFDLEtBQUQsQ0FBbkI7O0FBQ0EsTUFBTUMsRUFBRSxHQUFHRCxPQUFPLENBQUMsSUFBRCxDQUFsQjs7QUFDQSxTQUFTRSx5QkFBVCxDQUFtQ0MsR0FBbkMsRUFBd0M7QUFDdEMsUUFBTUMsZUFBZSxHQUFHLEVBQXhCO0FBRUEsUUFBTUMs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QixFQUFFQTtBQUZaLENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgdXJsID0gcmVxdWlyZSgndXJsJyk7XG5jb25zdCBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG5mdW5jdGlvbiBnZXREYXRhYmFzZU9wdGlvbnNGcm9tVVJJKHVyaSkge1xuICBjb25zdCBkYXRhYmFzZU9wdGlvbnMgPSB7fTtcblxuICBjb25zdCBwYXJzZWRVUkkgPSB1cmwucGFyc2UodXJpKTtcbiAgY29uc3QgcXVlcnlQYXJhbXMgPSBwYXJzZVF1ZXJ5UGFyYW1zKHBhcnNlZFVSSS5xdWVyeSk7XG4gIGNvbnN0IGF1dGhQYXJ0cyA9IHBhcnNlZFVSSS5hdXRoID8gcGFyc2VkVVJJLmF1dGguc3BsaXQoJzonKSA6IFtdO1xuXG4gIGRhdGFiYXNlT3B0aW9ucy5ob3N0ID0gcGFyc2VkVVJJLmhvc3RuYW1lIHx8ICdsb2NhbGhvc3QnO1xuICBkYXRhYmFzZU9wdGlvbnMucG9ydCA9IHBhcnNlZFVSSS5wb3J0ID8gcGFyc2VJbnQocGFyc2VkVVJJLnBvcnQpIDogNTQzMjtcbiAgZGF0YWJhc2VPcHRpb25zLmRhdGFiYXNlID0gcGFyc2VkVVJJLnBhdGhuYW1lID8gcGFyc2VkVVJJLnBhdGhuYW1lLnN1YnN0cigxKSA6IHVuZGVmaW5lZDtcblxuICBkYXRhYmFzZU9wdGlvbnMudXNlciA9IGF1dGhQYXJ0cy5sZW5ndGggPiAwID8gYXV0aFBhcnRzWzBdIDogJyc7XG4gIGRhdGFiYXNlT3B0aW9ucy5wYXNzd29yZCA9IGF1dGhQYXJ0cy5sZW5ndGggPiAxID8gYXV0aFBhcnRzWzFdIDogJyc7XG5cbiAgaWYgKHF1ZXJ5UGFyYW1zLnNzbCAmJiBxdWVyeVBhcmFtcy5zc2wudG9Mb3dlckNhc2UoKSA9PT0gJ3RydWUnKSB7XG4gICAgZGF0YWJhc2VPcHRpb25zLnNzbCA9IHRydWU7XG4gIH1cblxuICBpZiAoXG4gICAgcXVlcnlQYXJhbXMuY2EgfHxcbiAgICBxdWVyeVBhcmFtcy5wZnggfHxcbiAgICBxdWVyeVBhcmFtcy5jZXJ0IHx8XG4gICAgcXVlcnlQYXJhbXMua2V5IHx8XG4gICAgcXVlcnlQYXJhbXMucGFzc3BocmFzZSB8fFxuICAgIHF1ZXJ5UGFyYW1zLnJlamVjdFVuYXV0aG9yaXplZCB8fFxuICAgIHF1ZXJ5UGFyYW1zLnNlY3VyZU9wdGlvbnNcbiAgKSB7XG4gICAgZGF0YWJhc2VPcHRpb25zLnNzbCA9IHt9O1xuICAgIGlmIChxdWVyeVBhcmFtcy5jYSkge1xuICAgICAgZGF0YWJhc2VPcHRpb25zLnNzbC5jYSA9IGZzLnJlYWRGaWxlU3luYyhxdWVyeVBhcmFtcy5jYSkudG9TdHJpbmcoKTtcbiAgICB9XG4gICAgaWYgKHF1ZXJ5UGFyYW1zLnBmeCkge1xuICAgICAgZGF0YWJhc2VPcHRpb25zLnNzbC5wZnggPSBmcy5yZWFkRmlsZVN5bmMocXVlcnlQYXJhbXMucGZ4KS50b1N0cmluZygpO1xuICAgIH1cbiAgICBpZiAocXVlcnlQYXJhbXMuY2VydCkge1xuICAgICAgZGF0YWJhc2VPcHRpb25zLnNzbC5jZXJ0ID0gZnMucmVhZEZpbGVTeW5jKHF1ZXJ5UGFyYW1zLmNlcnQpLnRvU3RyaW5nKCk7XG4gICAgfVxuICAgIGlmIChxdWVyeVBhcmFtcy5rZXkpIHtcbiAgICAgIGRhdGFiYXNlT3B0aW9ucy5zc2wua2V5ID0gZnMucmVhZEZpbGVTeW5jKHF1ZXJ5UGFyYW1zLmtleSkudG9TdHJpbmcoKTtcbiAgICB9XG4gICAgaWYgKHF1ZXJ5UGFyYW1zLnBhc3NwaHJhc2UpIHtcbiAgICAgIGRhdGFiYXNlT3B0aW9ucy5zc2wucGFzc3BocmFzZSA9IHF1ZXJ5UGFyYW1zLnBhc3NwaHJhc2U7XG4gICAgfVxuICAgIGlmIChxdWVyeVBhcmFtcy5yZWplY3RVbmF1dGhvcml6ZWQpIHtcbiAgICAgIGRhdGFiYXNlT3B0aW9ucy5zc2wucmVqZWN0VW5hdXRob3JpemVkID1cbiAgICAgICAgcXVlcnlQYXJhbXMucmVqZWN0VW5hdXRob3JpemVkLnRvTG93ZXJDYXNlKCkgPT09ICd0cnVlJyA/IHRydWUgOiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHF1ZXJ5UGFyYW1zLnNlY3VyZU9wdGlvbnMpIHtcbiAgICAgIGRhdGFiYXNlT3B0aW9ucy5zc2wuc2VjdXJlT3B0aW9ucyA9IHBhcnNlSW50KHF1ZXJ5UGFyYW1zLnNlY3VyZU9wdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIGRhdGFiYXNlT3B0aW9ucy5iaW5hcnkgPVxuICAgIHF1ZXJ5UGFyYW1zLmJpbmFyeSAmJiBxdWVyeVBhcmFtcy5iaW5hcnkudG9Mb3dlckNhc2UoKSA9PT0gJ3RydWUnID8gdHJ1ZSA6IGZhbHNlO1xuXG4gIGRhdGFiYXNlT3B0aW9ucy5jbGllbnRfZW5jb2RpbmcgPSBxdWVyeVBhcmFtcy5jbGllbnRfZW5jb2Rpbmc7XG4gIGRhdGFiYXNlT3B0aW9ucy5hcHBsaWNhdGlvbl9uYW1lID0gcXVlcnlQYXJhbXMuYXBwbGljYXRpb25fbmFtZTtcbiAgZGF0YWJhc2VPcHRpb25zLmZhbGxiYWNrX2FwcGxpY2F0aW9uX25hbWUgPSBxdWVyeVBhcmFtcy5mYWxsYmFja19hcHBsaWNhdGlvbl9uYW1lO1xuXG4gIGlmIChxdWVyeVBhcmFtcy5wb29sU2l6ZSkge1xuICAgIGRhdGFiYXNlT3B0aW9ucy5wb29sU2l6ZSA9IHBhcnNlSW50KHF1ZXJ5UGFyYW1zLnBvb2xTaXplKSB8fCAxMDtcbiAgfVxuICBpZiAocXVlcnlQYXJhbXMubWF4KSB7XG4gICAgZGF0YWJhc2VPcHRpb25zLm1heCA9IHBhcnNlSW50KHF1ZXJ5UGFyYW1zLm1heCkgfHwgMTA7XG4gIH1cbiAgaWYgKHF1ZXJ5UGFyYW1zLnF1ZXJ5X3RpbWVvdXQpIHtcbiAgICBkYXRhYmFzZU9wdGlvbnMucXVlcnlfdGltZW91dCA9IHBhcnNlSW50KHF1ZXJ5UGFyYW1zLnF1ZXJ5X3RpbWVvdXQpO1xuICB9XG4gIGlmIChxdWVyeVBhcmFtcy5pZGxlVGltZW91dE1pbGxpcykge1xuICAgIGRhdGFiYXNlT3B0aW9ucy5pZGxlVGltZW91dE1pbGxpcyA9IHBhcnNlSW50KHF1ZXJ5UGFyYW1zLmlkbGVUaW1lb3V0TWlsbGlzKTtcbiAgfVxuICBpZiAocXVlcnlQYXJhbXMua2VlcEFsaXZlKSB7XG4gICAgZGF0YWJhc2VPcHRpb25zLmtlZXBBbGl2ZSA9IHF1ZXJ5UGFyYW1zLmtlZXBBbGl2ZS50b0xvd2VyQ2FzZSgpID09PSAndHJ1ZScgPyB0cnVlIDogZmFsc2U7XG4gIH1cblxuICByZXR1cm4gZGF0YWJhc2VPcHRpb25zO1xufVxuXG5mdW5jdGlvbiBwYXJzZVF1ZXJ5UGFyYW1zKHF1ZXJ5U3RyaW5nKSB7XG4gIHF1ZXJ5U3RyaW5nID0gcXVlcnlTdHJpbmcgfHwgJyc7XG5cbiAgcmV0dXJuIHF1ZXJ5U3RyaW5nLnNwbGl0KCcmJykucmVkdWNlKChwLCBjKSA9PiB7XG4gICAgY29uc3QgcGFydHMgPSBjLnNwbGl0KCc9Jyk7XG4gICAgcFtkZWNvZGVVUklDb21wb25lbnQocGFydHNbMF0pXSA9XG4gICAgICBwYXJ0cy5sZW5ndGggPiAxID8gZGVjb2RlVVJJQ29tcG9uZW50KHBhcnRzLnNsaWNlKDEpLmpvaW4oJz0nKSkgOiAnJztcbiAgICByZXR1cm4gcDtcbiAgfSwge30pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgcGFyc2VRdWVyeVBhcmFtczogcGFyc2VRdWVyeVBhcmFtcyxcbiAgZ2V0RGF0YWJhc2VPcHRpb25zRnJvbVVSSTogZ2V0RGF0YWJhc2VPcHRpb25zRnJvbVVSSSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js deleted file mode 100644 index 3b200835e7..0000000000 --- a/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js +++ /dev/null @@ -1,2494 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.PostgresStorageAdapter = void 0; - -var _PostgresClient = require("./PostgresClient"); - -var _node = _interopRequireDefault(require("parse/node")); - -var _lodash = _interopRequireDefault(require("lodash")); - -var _sql = _interopRequireDefault(require("./sql")); - -var _StorageAdapter = require("../StorageAdapter"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const PostgresRelationDoesNotExistError = '42P01'; -const PostgresDuplicateRelationError = '42P07'; -const PostgresDuplicateColumnError = '42701'; -const PostgresMissingColumnError = '42703'; -const PostgresDuplicateObjectError = '42710'; -const PostgresUniqueIndexViolationError = '23505'; - -const logger = require('../../../logger'); - -const debug = function (...args) { - args = ['PG: ' + arguments[0]].concat(args.slice(1, args.length)); - const log = logger.getLogger(); - log.debug.apply(log, args); -}; - -const parseTypeToPostgresType = type => { - switch (type.type) { - case 'String': - return 'text'; - - case 'Date': - return 'timestamp with time zone'; - - case 'Object': - return 'jsonb'; - - case 'File': - return 'text'; - - case 'Boolean': - return 'boolean'; - - case 'Pointer': - return 'text'; - - case 'Number': - return 'double precision'; - - case 'GeoPoint': - return 'point'; - - case 'Bytes': - return 'jsonb'; - - case 'Polygon': - return 'polygon'; - - case 'Array': - if (type.contents && type.contents.type === 'String') { - return 'text[]'; - } else { - return 'jsonb'; - } - - default: - throw `no type for ${JSON.stringify(type)} yet`; - } -}; - -const ParseToPosgresComparator = { - $gt: '>', - $lt: '<', - $gte: '>=', - $lte: '<=' -}; -const mongoAggregateToPostgres = { - $dayOfMonth: 'DAY', - $dayOfWeek: 'DOW', - $dayOfYear: 'DOY', - $isoDayOfWeek: 'ISODOW', - $isoWeekYear: 'ISOYEAR', - $hour: 'HOUR', - $minute: 'MINUTE', - $second: 'SECOND', - $millisecond: 'MILLISECONDS', - $month: 'MONTH', - $week: 'WEEK', - $year: 'YEAR' -}; - -const toPostgresValue = value => { - if (typeof value === 'object') { - if (value.__type === 'Date') { - return value.iso; - } - - if (value.__type === 'File') { - return value.name; - } - } - - return value; -}; - -const transformValue = value => { - if (typeof value === 'object' && value.__type === 'Pointer') { - return value.objectId; - } - - return value; -}; // Duplicate from then mongo adapter... - - -const emptyCLPS = Object.freeze({ - find: {}, - get: {}, - count: {}, - create: {}, - update: {}, - delete: {}, - addField: {}, - protectedFields: {} -}); -const defaultCLPS = Object.freeze({ - find: { - '*': true - }, - get: { - '*': true - }, - count: { - '*': true - }, - create: { - '*': true - }, - update: { - '*': true - }, - delete: { - '*': true - }, - addField: { - '*': true - }, - protectedFields: { - '*': [] - } -}); - -const toParseSchema = schema => { - if (schema.className === '_User') { - delete schema.fields._hashed_password; - } - - if (schema.fields) { - delete schema.fields._wperm; - delete schema.fields._rperm; - } - - let clps = defaultCLPS; - - if (schema.classLevelPermissions) { - clps = _objectSpread(_objectSpread({}, emptyCLPS), schema.classLevelPermissions); - } - - let indexes = {}; - - if (schema.indexes) { - indexes = _objectSpread({}, schema.indexes); - } - - return { - className: schema.className, - fields: schema.fields, - classLevelPermissions: clps, - indexes - }; -}; - -const toPostgresSchema = schema => { - if (!schema) { - return schema; - } - - schema.fields = schema.fields || {}; - schema.fields._wperm = { - type: 'Array', - contents: { - type: 'String' - } - }; - schema.fields._rperm = { - type: 'Array', - contents: { - type: 'String' - } - }; - - if (schema.className === '_User') { - schema.fields._hashed_password = { - type: 'String' - }; - schema.fields._password_history = { - type: 'Array' - }; - } - - return schema; -}; - -const handleDotFields = object => { - Object.keys(object).forEach(fieldName => { - if (fieldName.indexOf('.') > -1) { - const components = fieldName.split('.'); - const first = components.shift(); - object[first] = object[first] || {}; - let currentObj = object[first]; - let next; - let value = object[fieldName]; - - if (value && value.__op === 'Delete') { - value = undefined; - } - /* eslint-disable no-cond-assign */ - - - while (next = components.shift()) { - /* eslint-enable no-cond-assign */ - currentObj[next] = currentObj[next] || {}; - - if (components.length === 0) { - currentObj[next] = value; - } - - currentObj = currentObj[next]; - } - - delete object[fieldName]; - } - }); - return object; -}; - -const transformDotFieldToComponents = fieldName => { - return fieldName.split('.').map((cmpt, index) => { - if (index === 0) { - return `"${cmpt}"`; - } - - return `'${cmpt}'`; - }); -}; - -const transformDotField = fieldName => { - if (fieldName.indexOf('.') === -1) { - return `"${fieldName}"`; - } - - const components = transformDotFieldToComponents(fieldName); - let name = components.slice(0, components.length - 1).join('->'); - name += '->>' + components[components.length - 1]; - return name; -}; - -const transformAggregateField = fieldName => { - if (typeof fieldName !== 'string') { - return fieldName; - } - - if (fieldName === '$_created_at') { - return 'createdAt'; - } - - if (fieldName === '$_updated_at') { - return 'updatedAt'; - } - - return fieldName.substr(1); -}; - -const validateKeys = object => { - if (typeof object == 'object') { - for (const key in object) { - if (typeof object[key] == 'object') { - validateKeys(object[key]); - } - - if (key.includes('$') || key.includes('.')) { - throw new _node.default.Error(_node.default.Error.INVALID_NESTED_KEY, "Nested keys should not contain the '$' or '.' characters"); - } - } - } -}; // Returns the list of join tables on a schema - - -const joinTablesForSchema = schema => { - const list = []; - - if (schema) { - Object.keys(schema.fields).forEach(field => { - if (schema.fields[field].type === 'Relation') { - list.push(`_Join:${field}:${schema.className}`); - } - }); - } - - return list; -}; - -const buildWhereClause = ({ - schema, - query, - index, - caseInsensitive -}) => { - const patterns = []; - let values = []; - const sorts = []; - schema = toPostgresSchema(schema); - - for (const fieldName in query) { - const isArrayField = schema.fields && schema.fields[fieldName] && schema.fields[fieldName].type === 'Array'; - const initialPatternsLength = patterns.length; - const fieldValue = query[fieldName]; // nothing in the schema, it's gonna blow up - - if (!schema.fields[fieldName]) { - // as it won't exist - if (fieldValue && fieldValue.$exists === false) { - continue; - } - } - - const authDataMatch = fieldName.match(/^_auth_data_([a-zA-Z0-9_]+)$/); - - if (authDataMatch) { - // TODO: Handle querying by _auth_data_provider, authData is stored in authData field - continue; - } else if (caseInsensitive && (fieldName === 'username' || fieldName === 'email')) { - patterns.push(`LOWER($${index}:name) = LOWER($${index + 1})`); - values.push(fieldName, fieldValue); - index += 2; - } else if (fieldName.indexOf('.') >= 0) { - let name = transformDotField(fieldName); - - if (fieldValue === null) { - patterns.push(`$${index}:raw IS NULL`); - values.push(name); - index += 1; - continue; - } else { - if (fieldValue.$in) { - name = transformDotFieldToComponents(fieldName).join('->'); - patterns.push(`($${index}:raw)::jsonb @> $${index + 1}::jsonb`); - values.push(name, JSON.stringify(fieldValue.$in)); - index += 2; - } else if (fieldValue.$regex) {// Handle later - } else if (typeof fieldValue !== 'object') { - patterns.push(`$${index}:raw = $${index + 1}::text`); - values.push(name, fieldValue); - index += 2; - } - } - } else if (fieldValue === null || fieldValue === undefined) { - patterns.push(`$${index}:name IS NULL`); - values.push(fieldName); - index += 1; - continue; - } else if (typeof fieldValue === 'string') { - patterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue); - index += 2; - } else if (typeof fieldValue === 'boolean') { - patterns.push(`$${index}:name = $${index + 1}`); // Can't cast boolean to double precision - - if (schema.fields[fieldName] && schema.fields[fieldName].type === 'Number') { - // Should always return zero results - const MAX_INT_PLUS_ONE = 9223372036854775808; - values.push(fieldName, MAX_INT_PLUS_ONE); - } else { - values.push(fieldName, fieldValue); - } - - index += 2; - } else if (typeof fieldValue === 'number') { - patterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue); - index += 2; - } else if (['$or', '$nor', '$and'].includes(fieldName)) { - const clauses = []; - const clauseValues = []; - fieldValue.forEach(subQuery => { - const clause = buildWhereClause({ - schema, - query: subQuery, - index, - caseInsensitive - }); - - if (clause.pattern.length > 0) { - clauses.push(clause.pattern); - clauseValues.push(...clause.values); - index += clause.values.length; - } - }); - const orOrAnd = fieldName === '$and' ? ' AND ' : ' OR '; - const not = fieldName === '$nor' ? ' NOT ' : ''; - patterns.push(`${not}(${clauses.join(orOrAnd)})`); - values.push(...clauseValues); - } - - if (fieldValue.$ne !== undefined) { - if (isArrayField) { - fieldValue.$ne = JSON.stringify([fieldValue.$ne]); - patterns.push(`NOT array_contains($${index}:name, $${index + 1})`); - } else { - if (fieldValue.$ne === null) { - patterns.push(`$${index}:name IS NOT NULL`); - values.push(fieldName); - index += 1; - continue; - } else { - // if not null, we need to manually exclude null - if (fieldValue.$ne.__type === 'GeoPoint') { - patterns.push(`($${index}:name <> POINT($${index + 1}, $${index + 2}) OR $${index}:name IS NULL)`); - } else { - if (fieldName.indexOf('.') >= 0) { - const constraintFieldName = transformDotField(fieldName); - patterns.push(`(${constraintFieldName} <> $${index} OR ${constraintFieldName} IS NULL)`); - } else { - patterns.push(`($${index}:name <> $${index + 1} OR $${index}:name IS NULL)`); - } - } - } - } - - if (fieldValue.$ne.__type === 'GeoPoint') { - const point = fieldValue.$ne; - values.push(fieldName, point.longitude, point.latitude); - index += 3; - } else { - // TODO: support arrays - values.push(fieldName, fieldValue.$ne); - index += 2; - } - } - - if (fieldValue.$eq !== undefined) { - if (fieldValue.$eq === null) { - patterns.push(`$${index}:name IS NULL`); - values.push(fieldName); - index += 1; - } else { - if (fieldName.indexOf('.') >= 0) { - values.push(fieldValue.$eq); - patterns.push(`${transformDotField(fieldName)} = $${index++}`); - } else { - values.push(fieldName, fieldValue.$eq); - patterns.push(`$${index}:name = $${index + 1}`); - index += 2; - } - } - } - - const isInOrNin = Array.isArray(fieldValue.$in) || Array.isArray(fieldValue.$nin); - - if (Array.isArray(fieldValue.$in) && isArrayField && schema.fields[fieldName].contents && schema.fields[fieldName].contents.type === 'String') { - const inPatterns = []; - let allowNull = false; - values.push(fieldName); - fieldValue.$in.forEach((listElem, listIndex) => { - if (listElem === null) { - allowNull = true; - } else { - values.push(listElem); - inPatterns.push(`$${index + 1 + listIndex - (allowNull ? 1 : 0)}`); - } - }); - - if (allowNull) { - patterns.push(`($${index}:name IS NULL OR $${index}:name && ARRAY[${inPatterns.join()}])`); - } else { - patterns.push(`$${index}:name && ARRAY[${inPatterns.join()}]`); - } - - index = index + 1 + inPatterns.length; - } else if (isInOrNin) { - var createConstraint = (baseArray, notIn) => { - const not = notIn ? ' NOT ' : ''; - - if (baseArray.length > 0) { - if (isArrayField) { - patterns.push(`${not} array_contains($${index}:name, $${index + 1})`); - values.push(fieldName, JSON.stringify(baseArray)); - index += 2; - } else { - // Handle Nested Dot Notation Above - if (fieldName.indexOf('.') >= 0) { - return; - } - - const inPatterns = []; - values.push(fieldName); - baseArray.forEach((listElem, listIndex) => { - if (listElem != null) { - values.push(listElem); - inPatterns.push(`$${index + 1 + listIndex}`); - } - }); - patterns.push(`$${index}:name ${not} IN (${inPatterns.join()})`); - index = index + 1 + inPatterns.length; - } - } else if (!notIn) { - values.push(fieldName); - patterns.push(`$${index}:name IS NULL`); - index = index + 1; - } else { - // Handle empty array - if (notIn) { - patterns.push('1 = 1'); // Return all values - } else { - patterns.push('1 = 2'); // Return no values - } - } - }; - - if (fieldValue.$in) { - createConstraint(_lodash.default.flatMap(fieldValue.$in, elt => elt), false); - } - - if (fieldValue.$nin) { - createConstraint(_lodash.default.flatMap(fieldValue.$nin, elt => elt), true); - } - } else if (typeof fieldValue.$in !== 'undefined') { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $in value'); - } else if (typeof fieldValue.$nin !== 'undefined') { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $nin value'); - } - - if (Array.isArray(fieldValue.$all) && isArrayField) { - if (isAnyValueRegexStartsWith(fieldValue.$all)) { - if (!isAllValuesRegexOrNone(fieldValue.$all)) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'All $all values must be of regex type or none: ' + fieldValue.$all); - } - - for (let i = 0; i < fieldValue.$all.length; i += 1) { - const value = processRegexPattern(fieldValue.$all[i].$regex); - fieldValue.$all[i] = value.substring(1) + '%'; - } - - patterns.push(`array_contains_all_regex($${index}:name, $${index + 1}::jsonb)`); - } else { - patterns.push(`array_contains_all($${index}:name, $${index + 1}::jsonb)`); - } - - values.push(fieldName, JSON.stringify(fieldValue.$all)); - index += 2; - } else if (Array.isArray(fieldValue.$all)) { - if (fieldValue.$all.length === 1) { - patterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue.$all[0].objectId); - index += 2; - } - } - - if (typeof fieldValue.$exists !== 'undefined') { - if (fieldValue.$exists) { - patterns.push(`$${index}:name IS NOT NULL`); - } else { - patterns.push(`$${index}:name IS NULL`); - } - - values.push(fieldName); - index += 1; - } - - if (fieldValue.$containedBy) { - const arr = fieldValue.$containedBy; - - if (!(arr instanceof Array)) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $containedBy: should be an array`); - } - - patterns.push(`$${index}:name <@ $${index + 1}::jsonb`); - values.push(fieldName, JSON.stringify(arr)); - index += 2; - } - - if (fieldValue.$text) { - const search = fieldValue.$text.$search; - let language = 'english'; - - if (typeof search !== 'object') { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $search, should be object`); - } - - if (!search.$term || typeof search.$term !== 'string') { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $term, should be string`); - } - - if (search.$language && typeof search.$language !== 'string') { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $language, should be string`); - } else if (search.$language) { - language = search.$language; - } - - if (search.$caseSensitive && typeof search.$caseSensitive !== 'boolean') { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $caseSensitive, should be boolean`); - } else if (search.$caseSensitive) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $caseSensitive not supported, please use $regex or create a separate lower case column.`); - } - - if (search.$diacriticSensitive && typeof search.$diacriticSensitive !== 'boolean') { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $diacriticSensitive, should be boolean`); - } else if (search.$diacriticSensitive === false) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, `bad $text: $diacriticSensitive - false not supported, install Postgres Unaccent Extension`); - } - - patterns.push(`to_tsvector($${index}, $${index + 1}:name) @@ to_tsquery($${index + 2}, $${index + 3})`); - values.push(language, fieldName, language, search.$term); - index += 4; - } - - if (fieldValue.$nearSphere) { - const point = fieldValue.$nearSphere; - const distance = fieldValue.$maxDistance; - const distanceInKM = distance * 6371 * 1000; - patterns.push(`ST_DistanceSphere($${index}:name::geometry, POINT($${index + 1}, $${index + 2})::geometry) <= $${index + 3}`); - sorts.push(`ST_DistanceSphere($${index}:name::geometry, POINT($${index + 1}, $${index + 2})::geometry) ASC`); - values.push(fieldName, point.longitude, point.latitude, distanceInKM); - index += 4; - } - - if (fieldValue.$within && fieldValue.$within.$box) { - const box = fieldValue.$within.$box; - const left = box[0].longitude; - const bottom = box[0].latitude; - const right = box[1].longitude; - const top = box[1].latitude; - patterns.push(`$${index}:name::point <@ $${index + 1}::box`); - values.push(fieldName, `((${left}, ${bottom}), (${right}, ${top}))`); - index += 2; - } - - if (fieldValue.$geoWithin && fieldValue.$geoWithin.$centerSphere) { - const centerSphere = fieldValue.$geoWithin.$centerSphere; - - if (!(centerSphere instanceof Array) || centerSphere.length < 2) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere should be an array of Parse.GeoPoint and distance'); - } // Get point, convert to geo point if necessary and validate - - - let point = centerSphere[0]; - - if (point instanceof Array && point.length === 2) { - point = new _node.default.GeoPoint(point[1], point[0]); - } else if (!GeoPointCoder.isValidJSON(point)) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere geo point invalid'); - } - - _node.default.GeoPoint._validate(point.latitude, point.longitude); // Get distance and validate - - - const distance = centerSphere[1]; - - if (isNaN(distance) || distance < 0) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; $centerSphere distance invalid'); - } - - const distanceInKM = distance * 6371 * 1000; - patterns.push(`ST_DistanceSphere($${index}:name::geometry, POINT($${index + 1}, $${index + 2})::geometry) <= $${index + 3}`); - values.push(fieldName, point.longitude, point.latitude, distanceInKM); - index += 4; - } - - if (fieldValue.$geoWithin && fieldValue.$geoWithin.$polygon) { - const polygon = fieldValue.$geoWithin.$polygon; - let points; - - if (typeof polygon === 'object' && polygon.__type === 'Polygon') { - if (!polygon.coordinates || polygon.coordinates.length < 3) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; Polygon.coordinates should contain at least 3 lon/lat pairs'); - } - - points = polygon.coordinates; - } else if (polygon instanceof Array) { - if (polygon.length < 3) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value; $polygon should contain at least 3 GeoPoints'); - } - - points = polygon; - } else { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, "bad $geoWithin value; $polygon should be Polygon object or Array of Parse.GeoPoint's"); - } - - points = points.map(point => { - if (point instanceof Array && point.length === 2) { - _node.default.GeoPoint._validate(point[1], point[0]); - - return `(${point[0]}, ${point[1]})`; - } - - if (typeof point !== 'object' || point.__type !== 'GeoPoint') { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoWithin value'); - } else { - _node.default.GeoPoint._validate(point.latitude, point.longitude); - } - - return `(${point.longitude}, ${point.latitude})`; - }).join(', '); - patterns.push(`$${index}:name::point <@ $${index + 1}::polygon`); - values.push(fieldName, `(${points})`); - index += 2; - } - - if (fieldValue.$geoIntersects && fieldValue.$geoIntersects.$point) { - const point = fieldValue.$geoIntersects.$point; - - if (typeof point !== 'object' || point.__type !== 'GeoPoint') { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'bad $geoIntersect value; $point should be GeoPoint'); - } else { - _node.default.GeoPoint._validate(point.latitude, point.longitude); - } - - patterns.push(`$${index}:name::polygon @> $${index + 1}::point`); - values.push(fieldName, `(${point.longitude}, ${point.latitude})`); - index += 2; - } - - if (fieldValue.$regex) { - let regex = fieldValue.$regex; - let operator = '~'; - const opts = fieldValue.$options; - - if (opts) { - if (opts.indexOf('i') >= 0) { - operator = '~*'; - } - - if (opts.indexOf('x') >= 0) { - regex = removeWhiteSpace(regex); - } - } - - const name = transformDotField(fieldName); - regex = processRegexPattern(regex); - patterns.push(`$${index}:raw ${operator} '$${index + 1}:raw'`); - values.push(name, regex); - index += 2; - } - - if (fieldValue.__type === 'Pointer') { - if (isArrayField) { - patterns.push(`array_contains($${index}:name, $${index + 1})`); - values.push(fieldName, JSON.stringify([fieldValue])); - index += 2; - } else { - patterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue.objectId); - index += 2; - } - } - - if (fieldValue.__type === 'Date') { - patterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue.iso); - index += 2; - } - - if (fieldValue.__type === 'GeoPoint') { - patterns.push(`$${index}:name ~= POINT($${index + 1}, $${index + 2})`); - values.push(fieldName, fieldValue.longitude, fieldValue.latitude); - index += 3; - } - - if (fieldValue.__type === 'Polygon') { - const value = convertPolygonToSQL(fieldValue.coordinates); - patterns.push(`$${index}:name ~= $${index + 1}::polygon`); - values.push(fieldName, value); - index += 2; - } - - Object.keys(ParseToPosgresComparator).forEach(cmp => { - if (fieldValue[cmp] || fieldValue[cmp] === 0) { - const pgComparator = ParseToPosgresComparator[cmp]; - const postgresValue = toPostgresValue(fieldValue[cmp]); - let constraintFieldName; - - if (fieldName.indexOf('.') >= 0) { - let castType; - - switch (typeof postgresValue) { - case 'number': - castType = 'double precision'; - break; - - case 'boolean': - castType = 'boolean'; - break; - - default: - castType = undefined; - } - - constraintFieldName = castType ? `CAST ((${transformDotField(fieldName)}) AS ${castType})` : transformDotField(fieldName); - } else { - constraintFieldName = `$${index++}:name`; - values.push(fieldName); - } - - values.push(postgresValue); - patterns.push(`${constraintFieldName} ${pgComparator} $${index++}`); - } - }); - - if (initialPatternsLength === patterns.length) { - throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, `Postgres doesn't support this query type yet ${JSON.stringify(fieldValue)}`); - } - } - - values = values.map(transformValue); - return { - pattern: patterns.join(' AND '), - values, - sorts - }; -}; - -class PostgresStorageAdapter { - // Private - constructor({ - uri, - collectionPrefix = '', - databaseOptions - }) { - this._collectionPrefix = collectionPrefix; - const { - client, - pgp - } = (0, _PostgresClient.createClient)(uri, databaseOptions); - this._client = client; - this._pgp = pgp; - this.canSortOnJoinTables = false; - } //Note that analyze=true will run the query, executing INSERTS, DELETES, etc. - - - createExplainableQuery(query, analyze = false) { - if (analyze) { - return 'EXPLAIN (ANALYZE, FORMAT JSON) ' + query; - } else { - return 'EXPLAIN (FORMAT JSON) ' + query; - } - } - - handleShutdown() { - if (!this._client) { - return; - } - - this._client.$pool.end(); - } - - async _ensureSchemaCollectionExists(conn) { - conn = conn || this._client; - await conn.none('CREATE TABLE IF NOT EXISTS "_SCHEMA" ( "className" varChar(120), "schema" jsonb, "isParseClass" bool, PRIMARY KEY ("className") )').catch(error => { - if (error.code === PostgresDuplicateRelationError || error.code === PostgresUniqueIndexViolationError || error.code === PostgresDuplicateObjectError) {// Table already exists, must have been created by a different request. Ignore error. - } else { - throw error; - } - }); - } - - async classExists(name) { - return this._client.one('SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = $1)', [name], a => a.exists); - } - - async setClassLevelPermissions(className, CLPs) { - const self = this; - await this._client.task('set-class-level-permissions', async t => { - await self._ensureSchemaCollectionExists(t); - const values = [className, 'schema', 'classLevelPermissions', JSON.stringify(CLPs)]; - await t.none(`UPDATE "_SCHEMA" SET $2:name = json_object_set_key($2:name, $3::text, $4::jsonb) WHERE "className" = $1`, values); - }); - } - - async setIndexesWithSchemaFormat(className, submittedIndexes, existingIndexes = {}, fields, conn) { - conn = conn || this._client; - const self = this; - - if (submittedIndexes === undefined) { - return Promise.resolve(); - } - - if (Object.keys(existingIndexes).length === 0) { - existingIndexes = { - _id_: { - _id: 1 - } - }; - } - - const deletedIndexes = []; - const insertedIndexes = []; - Object.keys(submittedIndexes).forEach(name => { - const field = submittedIndexes[name]; - - if (existingIndexes[name] && field.__op !== 'Delete') { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Index ${name} exists, cannot update.`); - } - - if (!existingIndexes[name] && field.__op === 'Delete') { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Index ${name} does not exist, cannot delete.`); - } - - if (field.__op === 'Delete') { - deletedIndexes.push(name); - delete existingIndexes[name]; - } else { - Object.keys(field).forEach(key => { - if (!Object.prototype.hasOwnProperty.call(fields, key)) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Field ${key} does not exist, cannot add index.`); - } - }); - existingIndexes[name] = field; - insertedIndexes.push({ - key: field, - name - }); - } - }); - await conn.tx('set-indexes-with-schema-format', async t => { - if (insertedIndexes.length > 0) { - await self.createIndexes(className, insertedIndexes, t); - } - - if (deletedIndexes.length > 0) { - await self.dropIndexes(className, deletedIndexes, t); - } - - await self._ensureSchemaCollectionExists(t); - await t.none('UPDATE "_SCHEMA" SET $2:name = json_object_set_key($2:name, $3::text, $4::jsonb) WHERE "className" = $1', [className, 'schema', 'indexes', JSON.stringify(existingIndexes)]); - }); - } - - async createClass(className, schema, conn) { - conn = conn || this._client; - return conn.tx('create-class', async t => { - await this.createTable(className, schema, t); - await t.none('INSERT INTO "_SCHEMA" ("className", "schema", "isParseClass") VALUES ($, $, true)', { - className, - schema - }); - await this.setIndexesWithSchemaFormat(className, schema.indexes, {}, schema.fields, t); - return toParseSchema(schema); - }).catch(err => { - if (err.code === PostgresUniqueIndexViolationError && err.detail.includes(className)) { - throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, `Class ${className} already exists.`); - } - - throw err; - }); - } // Just create a table, do not insert in schema - - - async createTable(className, schema, conn) { - conn = conn || this._client; - const self = this; - debug('createTable', className, schema); - const valuesArray = []; - const patternsArray = []; - const fields = Object.assign({}, schema.fields); - - if (className === '_User') { - fields._email_verify_token_expires_at = { - type: 'Date' - }; - fields._email_verify_token = { - type: 'String' - }; - fields._account_lockout_expires_at = { - type: 'Date' - }; - fields._failed_login_count = { - type: 'Number' - }; - fields._perishable_token = { - type: 'String' - }; - fields._perishable_token_expires_at = { - type: 'Date' - }; - fields._password_changed_at = { - type: 'Date' - }; - fields._password_history = { - type: 'Array' - }; - } - - let index = 2; - const relations = []; - Object.keys(fields).forEach(fieldName => { - const parseType = fields[fieldName]; // Skip when it's a relation - // We'll create the tables later - - if (parseType.type === 'Relation') { - relations.push(fieldName); - return; - } - - if (['_rperm', '_wperm'].indexOf(fieldName) >= 0) { - parseType.contents = { - type: 'String' - }; - } - - valuesArray.push(fieldName); - valuesArray.push(parseTypeToPostgresType(parseType)); - patternsArray.push(`$${index}:name $${index + 1}:raw`); - - if (fieldName === 'objectId') { - patternsArray.push(`PRIMARY KEY ($${index}:name)`); - } - - index = index + 2; - }); - const qs = `CREATE TABLE IF NOT EXISTS $1:name (${patternsArray.join()})`; - const values = [className, ...valuesArray]; - debug(qs, values); - return conn.task('create-table', async t => { - try { - await self._ensureSchemaCollectionExists(t); - await t.none(qs, values); - } catch (error) { - if (error.code !== PostgresDuplicateRelationError) { - throw error; - } // ELSE: Table already exists, must have been created by a different request. Ignore the error. - - } - - await t.tx('create-table-tx', tx => { - return tx.batch(relations.map(fieldName => { - return tx.none('CREATE TABLE IF NOT EXISTS $ ("relatedId" varChar(120), "owningId" varChar(120), PRIMARY KEY("relatedId", "owningId") )', { - joinTable: `_Join:${fieldName}:${className}` - }); - })); - }); - }); - } - - async schemaUpgrade(className, schema, conn) { - debug('schemaUpgrade', { - className, - schema - }); - conn = conn || this._client; - const self = this; - await conn.tx('schema-upgrade', async t => { - const columns = await t.map('SELECT column_name FROM information_schema.columns WHERE table_name = $', { - className - }, a => a.column_name); - const newColumns = Object.keys(schema.fields).filter(item => columns.indexOf(item) === -1).map(fieldName => self.addFieldIfNotExists(className, fieldName, schema.fields[fieldName], t)); - await t.batch(newColumns); - }); - } - - async addFieldIfNotExists(className, fieldName, type, conn) { - // TODO: Must be revised for invalid logic... - debug('addFieldIfNotExists', { - className, - fieldName, - type - }); - conn = conn || this._client; - const self = this; - await conn.tx('add-field-if-not-exists', async t => { - if (type.type !== 'Relation') { - try { - await t.none('ALTER TABLE $ ADD COLUMN IF NOT EXISTS $ $', { - className, - fieldName, - postgresType: parseTypeToPostgresType(type) - }); - } catch (error) { - if (error.code === PostgresRelationDoesNotExistError) { - return self.createClass(className, { - fields: { - [fieldName]: type - } - }, t); - } - - if (error.code !== PostgresDuplicateColumnError) { - throw error; - } // Column already exists, created by other request. Carry on to see if it's the right type. - - } - } else { - await t.none('CREATE TABLE IF NOT EXISTS $ ("relatedId" varChar(120), "owningId" varChar(120), PRIMARY KEY("relatedId", "owningId") )', { - joinTable: `_Join:${fieldName}:${className}` - }); - } - - const result = await t.any('SELECT "schema" FROM "_SCHEMA" WHERE "className" = $ and ("schema"::json->\'fields\'->$) is not null', { - className, - fieldName - }); - - if (result[0]) { - throw 'Attempted to add a field that already exists'; - } else { - const path = `{fields,${fieldName}}`; - await t.none('UPDATE "_SCHEMA" SET "schema"=jsonb_set("schema", $, $) WHERE "className"=$', { - path, - type, - className - }); - } - }); - } // Drops a collection. Resolves with true if it was a Parse Schema (eg. _User, Custom, etc.) - // and resolves with false if it wasn't (eg. a join table). Rejects if deletion was impossible. - - - async deleteClass(className) { - const operations = [{ - query: `DROP TABLE IF EXISTS $1:name`, - values: [className] - }, { - query: `DELETE FROM "_SCHEMA" WHERE "className" = $1`, - values: [className] - }]; - return this._client.tx(t => t.none(this._pgp.helpers.concat(operations))).then(() => className.indexOf('_Join:') != 0); // resolves with false when _Join table - } // Delete all data known to this adapter. Used for testing. - - - async deleteAllClasses() { - const now = new Date().getTime(); - const helpers = this._pgp.helpers; - debug('deleteAllClasses'); - await this._client.task('delete-all-classes', async t => { - try { - const results = await t.any('SELECT * FROM "_SCHEMA"'); - const joins = results.reduce((list, schema) => { - return list.concat(joinTablesForSchema(schema.schema)); - }, []); - const classes = ['_SCHEMA', '_PushStatus', '_JobStatus', '_JobSchedule', '_Hooks', '_GlobalConfig', '_GraphQLConfig', '_Audience', '_Idempotency', ...results.map(result => result.className), ...joins]; - const queries = classes.map(className => ({ - query: 'DROP TABLE IF EXISTS $', - values: { - className - } - })); - await t.tx(tx => tx.none(helpers.concat(queries))); - } catch (error) { - if (error.code !== PostgresRelationDoesNotExistError) { - throw error; - } // No _SCHEMA collection. Don't delete anything. - - } - }).then(() => { - debug(`deleteAllClasses done in ${new Date().getTime() - now}`); - }); - } // Remove the column and all the data. For Relations, the _Join collection is handled - // specially, this function does not delete _Join columns. It should, however, indicate - // that the relation fields does not exist anymore. In mongo, this means removing it from - // the _SCHEMA collection. There should be no actual data in the collection under the same name - // as the relation column, so it's fine to attempt to delete it. If the fields listed to be - // deleted do not exist, this function should return successfully anyways. Checking for - // attempts to delete non-existent fields is the responsibility of Parse Server. - // This function is not obligated to delete fields atomically. It is given the field - // names in a list so that databases that are capable of deleting fields atomically - // may do so. - // Returns a Promise. - - - async deleteFields(className, schema, fieldNames) { - debug('deleteFields', className, fieldNames); - fieldNames = fieldNames.reduce((list, fieldName) => { - const field = schema.fields[fieldName]; - - if (field.type !== 'Relation') { - list.push(fieldName); - } - - delete schema.fields[fieldName]; - return list; - }, []); - const values = [className, ...fieldNames]; - const columns = fieldNames.map((name, idx) => { - return `$${idx + 2}:name`; - }).join(', DROP COLUMN'); - await this._client.tx('delete-fields', async t => { - await t.none('UPDATE "_SCHEMA" SET "schema" = $ WHERE "className" = $', { - schema, - className - }); - - if (values.length > 1) { - await t.none(`ALTER TABLE $1:name DROP COLUMN IF EXISTS ${columns}`, values); - } - }); - } // Return a promise for all schemas known to this adapter, in Parse format. In case the - // schemas cannot be retrieved, returns a promise that rejects. Requirements for the - // rejection reason are TBD. - - - async getAllClasses() { - const self = this; - return this._client.task('get-all-classes', async t => { - await self._ensureSchemaCollectionExists(t); - return await t.map('SELECT * FROM "_SCHEMA"', null, row => toParseSchema(_objectSpread({ - className: row.className - }, row.schema))); - }); - } // Return a promise for the schema with the given name, in Parse format. If - // this adapter doesn't know about the schema, return a promise that rejects with - // undefined as the reason. - - - async getClass(className) { - debug('getClass', className); - return this._client.any('SELECT * FROM "_SCHEMA" WHERE "className" = $', { - className - }).then(result => { - if (result.length !== 1) { - throw undefined; - } - - return result[0].schema; - }).then(toParseSchema); - } // TODO: remove the mongo format dependency in the return value - - - async createObject(className, schema, object, transactionalSession) { - debug('createObject', className, object); - let columnsArray = []; - const valuesArray = []; - schema = toPostgresSchema(schema); - const geoPoints = {}; - object = handleDotFields(object); - validateKeys(object); - Object.keys(object).forEach(fieldName => { - if (object[fieldName] === null) { - return; - } - - var authDataMatch = fieldName.match(/^_auth_data_([a-zA-Z0-9_]+)$/); - - if (authDataMatch) { - var provider = authDataMatch[1]; - object['authData'] = object['authData'] || {}; - object['authData'][provider] = object[fieldName]; - delete object[fieldName]; - fieldName = 'authData'; - } - - columnsArray.push(fieldName); - - if (!schema.fields[fieldName] && className === '_User') { - if (fieldName === '_email_verify_token' || fieldName === '_failed_login_count' || fieldName === '_perishable_token' || fieldName === '_password_history') { - valuesArray.push(object[fieldName]); - } - - if (fieldName === '_email_verify_token_expires_at') { - if (object[fieldName]) { - valuesArray.push(object[fieldName].iso); - } else { - valuesArray.push(null); - } - } - - if (fieldName === '_account_lockout_expires_at' || fieldName === '_perishable_token_expires_at' || fieldName === '_password_changed_at') { - if (object[fieldName]) { - valuesArray.push(object[fieldName].iso); - } else { - valuesArray.push(null); - } - } - - return; - } - - switch (schema.fields[fieldName].type) { - case 'Date': - if (object[fieldName]) { - valuesArray.push(object[fieldName].iso); - } else { - valuesArray.push(null); - } - - break; - - case 'Pointer': - valuesArray.push(object[fieldName].objectId); - break; - - case 'Array': - if (['_rperm', '_wperm'].indexOf(fieldName) >= 0) { - valuesArray.push(object[fieldName]); - } else { - valuesArray.push(JSON.stringify(object[fieldName])); - } - - break; - - case 'Object': - case 'Bytes': - case 'String': - case 'Number': - case 'Boolean': - valuesArray.push(object[fieldName]); - break; - - case 'File': - valuesArray.push(object[fieldName].name); - break; - - case 'Polygon': - { - const value = convertPolygonToSQL(object[fieldName].coordinates); - valuesArray.push(value); - break; - } - - case 'GeoPoint': - // pop the point and process later - geoPoints[fieldName] = object[fieldName]; - columnsArray.pop(); - break; - - default: - throw `Type ${schema.fields[fieldName].type} not supported yet`; - } - }); - columnsArray = columnsArray.concat(Object.keys(geoPoints)); - const initialValues = valuesArray.map((val, index) => { - let termination = ''; - const fieldName = columnsArray[index]; - - if (['_rperm', '_wperm'].indexOf(fieldName) >= 0) { - termination = '::text[]'; - } else if (schema.fields[fieldName] && schema.fields[fieldName].type === 'Array') { - termination = '::jsonb'; - } - - return `$${index + 2 + columnsArray.length}${termination}`; - }); - const geoPointsInjects = Object.keys(geoPoints).map(key => { - const value = geoPoints[key]; - valuesArray.push(value.longitude, value.latitude); - const l = valuesArray.length + columnsArray.length; - return `POINT($${l}, $${l + 1})`; - }); - const columnsPattern = columnsArray.map((col, index) => `$${index + 2}:name`).join(); - const valuesPattern = initialValues.concat(geoPointsInjects).join(); - const qs = `INSERT INTO $1:name (${columnsPattern}) VALUES (${valuesPattern})`; - const values = [className, ...columnsArray, ...valuesArray]; - debug(qs, values); - const promise = (transactionalSession ? transactionalSession.t : this._client).none(qs, values).then(() => ({ - ops: [object] - })).catch(error => { - if (error.code === PostgresUniqueIndexViolationError) { - const err = new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); - err.underlyingError = error; - - if (error.constraint) { - const matches = error.constraint.match(/unique_([a-zA-Z]+)/); - - if (matches && Array.isArray(matches)) { - err.userInfo = { - duplicated_field: matches[1] - }; - } - } - - error = err; - } - - throw error; - }); - - if (transactionalSession) { - transactionalSession.batch.push(promise); - } - - return promise; - } // Remove all objects that match the given Parse Query. - // If no objects match, reject with OBJECT_NOT_FOUND. If objects are found and deleted, resolve with undefined. - // If there is some other error, reject with INTERNAL_SERVER_ERROR. - - - async deleteObjectsByQuery(className, schema, query, transactionalSession) { - debug('deleteObjectsByQuery', className, query); - const values = [className]; - const index = 2; - const where = buildWhereClause({ - schema, - index, - query, - caseInsensitive: false - }); - values.push(...where.values); - - if (Object.keys(query).length === 0) { - where.pattern = 'TRUE'; - } - - const qs = `WITH deleted AS (DELETE FROM $1:name WHERE ${where.pattern} RETURNING *) SELECT count(*) FROM deleted`; - debug(qs, values); - const promise = (transactionalSession ? transactionalSession.t : this._client).one(qs, values, a => +a.count).then(count => { - if (count === 0) { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } else { - return count; - } - }).catch(error => { - if (error.code !== PostgresRelationDoesNotExistError) { - throw error; - } // ELSE: Don't delete anything if doesn't exist - - }); - - if (transactionalSession) { - transactionalSession.batch.push(promise); - } - - return promise; - } // Return value not currently well specified. - - - async findOneAndUpdate(className, schema, query, update, transactionalSession) { - debug('findOneAndUpdate', className, query, update); - return this.updateObjectsByQuery(className, schema, query, update, transactionalSession).then(val => val[0]); - } // Apply the update to all objects that match the given Parse Query. - - - async updateObjectsByQuery(className, schema, query, update, transactionalSession) { - debug('updateObjectsByQuery', className, query, update); - const updatePatterns = []; - const values = [className]; - let index = 2; - schema = toPostgresSchema(schema); - - const originalUpdate = _objectSpread({}, update); // Set flag for dot notation fields - - - const dotNotationOptions = {}; - Object.keys(update).forEach(fieldName => { - if (fieldName.indexOf('.') > -1) { - const components = fieldName.split('.'); - const first = components.shift(); - dotNotationOptions[first] = true; - } else { - dotNotationOptions[fieldName] = false; - } - }); - update = handleDotFields(update); // Resolve authData first, - // So we don't end up with multiple key updates - - for (const fieldName in update) { - const authDataMatch = fieldName.match(/^_auth_data_([a-zA-Z0-9_]+)$/); - - if (authDataMatch) { - var provider = authDataMatch[1]; - const value = update[fieldName]; - delete update[fieldName]; - update['authData'] = update['authData'] || {}; - update['authData'][provider] = value; - } - } - - for (const fieldName in update) { - const fieldValue = update[fieldName]; // Drop any undefined values. - - if (typeof fieldValue === 'undefined') { - delete update[fieldName]; - } else if (fieldValue === null) { - updatePatterns.push(`$${index}:name = NULL`); - values.push(fieldName); - index += 1; - } else if (fieldName == 'authData') { - // This recursively sets the json_object - // Only 1 level deep - const generate = (jsonb, key, value) => { - return `json_object_set_key(COALESCE(${jsonb}, '{}'::jsonb), ${key}, ${value})::jsonb`; - }; - - const lastKey = `$${index}:name`; - const fieldNameIndex = index; - index += 1; - values.push(fieldName); - const update = Object.keys(fieldValue).reduce((lastKey, key) => { - const str = generate(lastKey, `$${index}::text`, `$${index + 1}::jsonb`); - index += 2; - let value = fieldValue[key]; - - if (value) { - if (value.__op === 'Delete') { - value = null; - } else { - value = JSON.stringify(value); - } - } - - values.push(key, value); - return str; - }, lastKey); - updatePatterns.push(`$${fieldNameIndex}:name = ${update}`); - } else if (fieldValue.__op === 'Increment') { - updatePatterns.push(`$${index}:name = COALESCE($${index}:name, 0) + $${index + 1}`); - values.push(fieldName, fieldValue.amount); - index += 2; - } else if (fieldValue.__op === 'Add') { - updatePatterns.push(`$${index}:name = array_add(COALESCE($${index}:name, '[]'::jsonb), $${index + 1}::jsonb)`); - values.push(fieldName, JSON.stringify(fieldValue.objects)); - index += 2; - } else if (fieldValue.__op === 'Delete') { - updatePatterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, null); - index += 2; - } else if (fieldValue.__op === 'Remove') { - updatePatterns.push(`$${index}:name = array_remove(COALESCE($${index}:name, '[]'::jsonb), $${index + 1}::jsonb)`); - values.push(fieldName, JSON.stringify(fieldValue.objects)); - index += 2; - } else if (fieldValue.__op === 'AddUnique') { - updatePatterns.push(`$${index}:name = array_add_unique(COALESCE($${index}:name, '[]'::jsonb), $${index + 1}::jsonb)`); - values.push(fieldName, JSON.stringify(fieldValue.objects)); - index += 2; - } else if (fieldName === 'updatedAt') { - //TODO: stop special casing this. It should check for __type === 'Date' and use .iso - updatePatterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue); - index += 2; - } else if (typeof fieldValue === 'string') { - updatePatterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue); - index += 2; - } else if (typeof fieldValue === 'boolean') { - updatePatterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue); - index += 2; - } else if (fieldValue.__type === 'Pointer') { - updatePatterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue.objectId); - index += 2; - } else if (fieldValue.__type === 'Date') { - updatePatterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, toPostgresValue(fieldValue)); - index += 2; - } else if (fieldValue instanceof Date) { - updatePatterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue); - index += 2; - } else if (fieldValue.__type === 'File') { - updatePatterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, toPostgresValue(fieldValue)); - index += 2; - } else if (fieldValue.__type === 'GeoPoint') { - updatePatterns.push(`$${index}:name = POINT($${index + 1}, $${index + 2})`); - values.push(fieldName, fieldValue.longitude, fieldValue.latitude); - index += 3; - } else if (fieldValue.__type === 'Polygon') { - const value = convertPolygonToSQL(fieldValue.coordinates); - updatePatterns.push(`$${index}:name = $${index + 1}::polygon`); - values.push(fieldName, value); - index += 2; - } else if (fieldValue.__type === 'Relation') {// noop - } else if (typeof fieldValue === 'number') { - updatePatterns.push(`$${index}:name = $${index + 1}`); - values.push(fieldName, fieldValue); - index += 2; - } else if (typeof fieldValue === 'object' && schema.fields[fieldName] && schema.fields[fieldName].type === 'Object') { - // Gather keys to increment - const keysToIncrement = Object.keys(originalUpdate).filter(k => { - // choose top level fields that have a delete operation set - // Note that Object.keys is iterating over the **original** update object - // and that some of the keys of the original update could be null or undefined: - // (See the above check `if (fieldValue === null || typeof fieldValue == "undefined")`) - const value = originalUpdate[k]; - return value && value.__op === 'Increment' && k.split('.').length === 2 && k.split('.')[0] === fieldName; - }).map(k => k.split('.')[1]); - let incrementPatterns = ''; - - if (keysToIncrement.length > 0) { - incrementPatterns = ' || ' + keysToIncrement.map(c => { - const amount = fieldValue[c].amount; - return `CONCAT('{"${c}":', COALESCE($${index}:name->>'${c}','0')::int + ${amount}, '}')::jsonb`; - }).join(' || '); // Strip the keys - - keysToIncrement.forEach(key => { - delete fieldValue[key]; - }); - } - - const keysToDelete = Object.keys(originalUpdate).filter(k => { - // choose top level fields that have a delete operation set. - const value = originalUpdate[k]; - return value && value.__op === 'Delete' && k.split('.').length === 2 && k.split('.')[0] === fieldName; - }).map(k => k.split('.')[1]); - const deletePatterns = keysToDelete.reduce((p, c, i) => { - return p + ` - '$${index + 1 + i}:value'`; - }, ''); // Override Object - - let updateObject = "'{}'::jsonb"; - - if (dotNotationOptions[fieldName]) { - // Merge Object - updateObject = `COALESCE($${index}:name, '{}'::jsonb)`; - } - - updatePatterns.push(`$${index}:name = (${updateObject} ${deletePatterns} ${incrementPatterns} || $${index + 1 + keysToDelete.length}::jsonb )`); - values.push(fieldName, ...keysToDelete, JSON.stringify(fieldValue)); - index += 2 + keysToDelete.length; - } else if (Array.isArray(fieldValue) && schema.fields[fieldName] && schema.fields[fieldName].type === 'Array') { - const expectedType = parseTypeToPostgresType(schema.fields[fieldName]); - - if (expectedType === 'text[]') { - updatePatterns.push(`$${index}:name = $${index + 1}::text[]`); - values.push(fieldName, fieldValue); - index += 2; - } else { - updatePatterns.push(`$${index}:name = $${index + 1}::jsonb`); - values.push(fieldName, JSON.stringify(fieldValue)); - index += 2; - } - } else { - debug('Not supported update', fieldName, fieldValue); - return Promise.reject(new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, `Postgres doesn't support update ${JSON.stringify(fieldValue)} yet`)); - } - } - - const where = buildWhereClause({ - schema, - index, - query, - caseInsensitive: false - }); - values.push(...where.values); - const whereClause = where.pattern.length > 0 ? `WHERE ${where.pattern}` : ''; - const qs = `UPDATE $1:name SET ${updatePatterns.join()} ${whereClause} RETURNING *`; - debug('update: ', qs, values); - const promise = (transactionalSession ? transactionalSession.t : this._client).any(qs, values); - - if (transactionalSession) { - transactionalSession.batch.push(promise); - } - - return promise; - } // Hopefully, we can get rid of this. It's only used for config and hooks. - - - upsertOneObject(className, schema, query, update, transactionalSession) { - debug('upsertOneObject', { - className, - query, - update - }); - const createValue = Object.assign({}, query, update); - return this.createObject(className, schema, createValue, transactionalSession).catch(error => { - // ignore duplicate value errors as it's upsert - if (error.code !== _node.default.Error.DUPLICATE_VALUE) { - throw error; - } - - return this.findOneAndUpdate(className, schema, query, update, transactionalSession); - }); - } - - find(className, schema, query, { - skip, - limit, - sort, - keys, - caseInsensitive, - explain - }) { - debug('find', className, query, { - skip, - limit, - sort, - keys, - caseInsensitive, - explain - }); - const hasLimit = limit !== undefined; - const hasSkip = skip !== undefined; - let values = [className]; - const where = buildWhereClause({ - schema, - query, - index: 2, - caseInsensitive - }); - values.push(...where.values); - const wherePattern = where.pattern.length > 0 ? `WHERE ${where.pattern}` : ''; - const limitPattern = hasLimit ? `LIMIT $${values.length + 1}` : ''; - - if (hasLimit) { - values.push(limit); - } - - const skipPattern = hasSkip ? `OFFSET $${values.length + 1}` : ''; - - if (hasSkip) { - values.push(skip); - } - - let sortPattern = ''; - - if (sort) { - const sortCopy = sort; - const sorting = Object.keys(sort).map(key => { - const transformKey = transformDotFieldToComponents(key).join('->'); // Using $idx pattern gives: non-integer constant in ORDER BY - - if (sortCopy[key] === 1) { - return `${transformKey} ASC`; - } - - return `${transformKey} DESC`; - }).join(); - sortPattern = sort !== undefined && Object.keys(sort).length > 0 ? `ORDER BY ${sorting}` : ''; - } - - if (where.sorts && Object.keys(where.sorts).length > 0) { - sortPattern = `ORDER BY ${where.sorts.join()}`; - } - - let columns = '*'; - - if (keys) { - // Exclude empty keys - // Replace ACL by it's keys - keys = keys.reduce((memo, key) => { - if (key === 'ACL') { - memo.push('_rperm'); - memo.push('_wperm'); - } else if (key.length > 0) { - memo.push(key); - } - - return memo; - }, []); - columns = keys.map((key, index) => { - if (key === '$score') { - return `ts_rank_cd(to_tsvector($${2}, $${3}:name), to_tsquery($${4}, $${5}), 32) as score`; - } - - return `$${index + values.length + 1}:name`; - }).join(); - values = values.concat(keys); - } - - const originalQuery = `SELECT ${columns} FROM $1:name ${wherePattern} ${sortPattern} ${limitPattern} ${skipPattern}`; - const qs = explain ? this.createExplainableQuery(originalQuery) : originalQuery; - debug(qs, values); - return this._client.any(qs, values).catch(error => { - // Query on non existing table, don't crash - if (error.code !== PostgresRelationDoesNotExistError) { - throw error; - } - - return []; - }).then(results => { - if (explain) { - return results; - } - - return results.map(object => this.postgresObjectToParseObject(className, object, schema)); - }); - } // Converts from a postgres-format object to a REST-format object. - // Does not strip out anything based on a lack of authentication. - - - postgresObjectToParseObject(className, object, schema) { - Object.keys(schema.fields).forEach(fieldName => { - if (schema.fields[fieldName].type === 'Pointer' && object[fieldName]) { - object[fieldName] = { - objectId: object[fieldName], - __type: 'Pointer', - className: schema.fields[fieldName].targetClass - }; - } - - if (schema.fields[fieldName].type === 'Relation') { - object[fieldName] = { - __type: 'Relation', - className: schema.fields[fieldName].targetClass - }; - } - - if (object[fieldName] && schema.fields[fieldName].type === 'GeoPoint') { - object[fieldName] = { - __type: 'GeoPoint', - latitude: object[fieldName].y, - longitude: object[fieldName].x - }; - } - - if (object[fieldName] && schema.fields[fieldName].type === 'Polygon') { - let coords = object[fieldName]; - coords = coords.substr(2, coords.length - 4).split('),('); - coords = coords.map(point => { - return [parseFloat(point.split(',')[1]), parseFloat(point.split(',')[0])]; - }); - object[fieldName] = { - __type: 'Polygon', - coordinates: coords - }; - } - - if (object[fieldName] && schema.fields[fieldName].type === 'File') { - object[fieldName] = { - __type: 'File', - name: object[fieldName] - }; - } - }); //TODO: remove this reliance on the mongo format. DB adapter shouldn't know there is a difference between created at and any other date field. - - if (object.createdAt) { - object.createdAt = object.createdAt.toISOString(); - } - - if (object.updatedAt) { - object.updatedAt = object.updatedAt.toISOString(); - } - - if (object.expiresAt) { - object.expiresAt = { - __type: 'Date', - iso: object.expiresAt.toISOString() - }; - } - - if (object._email_verify_token_expires_at) { - object._email_verify_token_expires_at = { - __type: 'Date', - iso: object._email_verify_token_expires_at.toISOString() - }; - } - - if (object._account_lockout_expires_at) { - object._account_lockout_expires_at = { - __type: 'Date', - iso: object._account_lockout_expires_at.toISOString() - }; - } - - if (object._perishable_token_expires_at) { - object._perishable_token_expires_at = { - __type: 'Date', - iso: object._perishable_token_expires_at.toISOString() - }; - } - - if (object._password_changed_at) { - object._password_changed_at = { - __type: 'Date', - iso: object._password_changed_at.toISOString() - }; - } - - for (const fieldName in object) { - if (object[fieldName] === null) { - delete object[fieldName]; - } - - if (object[fieldName] instanceof Date) { - object[fieldName] = { - __type: 'Date', - iso: object[fieldName].toISOString() - }; - } - } - - return object; - } // Create a unique index. Unique indexes on nullable fields are not allowed. Since we don't - // currently know which fields are nullable and which aren't, we ignore that criteria. - // As such, we shouldn't expose this function to users of parse until we have an out-of-band - // Way of determining if a field is nullable. Undefined doesn't count against uniqueness, - // which is why we use sparse indexes. - - - async ensureUniqueness(className, schema, fieldNames) { - const constraintName = `${className}_unique_${fieldNames.sort().join('_')}`; - const constraintPatterns = fieldNames.map((fieldName, index) => `$${index + 3}:name`); - const qs = `CREATE UNIQUE INDEX IF NOT EXISTS $2:name ON $1:name(${constraintPatterns.join()})`; - return this._client.none(qs, [className, constraintName, ...fieldNames]).catch(error => { - if (error.code === PostgresDuplicateRelationError && error.message.includes(constraintName)) {// Index already exists. Ignore error. - } else if (error.code === PostgresUniqueIndexViolationError && error.message.includes(constraintName)) { - // Cast the error into the proper parse error - throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); - } else { - throw error; - } - }); - } // Executes a count. - - - async count(className, schema, query, readPreference, estimate = true) { - debug('count', className, query, readPreference, estimate); - const values = [className]; - const where = buildWhereClause({ - schema, - query, - index: 2, - caseInsensitive: false - }); - values.push(...where.values); - const wherePattern = where.pattern.length > 0 ? `WHERE ${where.pattern}` : ''; - let qs = ''; - - if (where.pattern.length > 0 || !estimate) { - qs = `SELECT count(*) FROM $1:name ${wherePattern}`; - } else { - qs = 'SELECT reltuples AS approximate_row_count FROM pg_class WHERE relname = $1'; - } - - return this._client.one(qs, values, a => { - if (a.approximate_row_count != null) { - return +a.approximate_row_count; - } else { - return +a.count; - } - }).catch(error => { - if (error.code !== PostgresRelationDoesNotExistError) { - throw error; - } - - return 0; - }); - } - - async distinct(className, schema, query, fieldName) { - debug('distinct', className, query); - let field = fieldName; - let column = fieldName; - const isNested = fieldName.indexOf('.') >= 0; - - if (isNested) { - field = transformDotFieldToComponents(fieldName).join('->'); - column = fieldName.split('.')[0]; - } - - const isArrayField = schema.fields && schema.fields[fieldName] && schema.fields[fieldName].type === 'Array'; - const isPointerField = schema.fields && schema.fields[fieldName] && schema.fields[fieldName].type === 'Pointer'; - const values = [field, column, className]; - const where = buildWhereClause({ - schema, - query, - index: 4, - caseInsensitive: false - }); - values.push(...where.values); - const wherePattern = where.pattern.length > 0 ? `WHERE ${where.pattern}` : ''; - const transformer = isArrayField ? 'jsonb_array_elements' : 'ON'; - let qs = `SELECT DISTINCT ${transformer}($1:name) $2:name FROM $3:name ${wherePattern}`; - - if (isNested) { - qs = `SELECT DISTINCT ${transformer}($1:raw) $2:raw FROM $3:name ${wherePattern}`; - } - - debug(qs, values); - return this._client.any(qs, values).catch(error => { - if (error.code === PostgresMissingColumnError) { - return []; - } - - throw error; - }).then(results => { - if (!isNested) { - results = results.filter(object => object[field] !== null); - return results.map(object => { - if (!isPointerField) { - return object[field]; - } - - return { - __type: 'Pointer', - className: schema.fields[fieldName].targetClass, - objectId: object[field] - }; - }); - } - - const child = fieldName.split('.')[1]; - return results.map(object => object[column][child]); - }).then(results => results.map(object => this.postgresObjectToParseObject(className, object, schema))); - } - - async aggregate(className, schema, pipeline, readPreference, hint, explain) { - debug('aggregate', className, pipeline, readPreference, hint, explain); - const values = [className]; - let index = 2; - let columns = []; - let countField = null; - let groupValues = null; - let wherePattern = ''; - let limitPattern = ''; - let skipPattern = ''; - let sortPattern = ''; - let groupPattern = ''; - - for (let i = 0; i < pipeline.length; i += 1) { - const stage = pipeline[i]; - - if (stage.$group) { - for (const field in stage.$group) { - const value = stage.$group[field]; - - if (value === null || value === undefined) { - continue; - } - - if (field === '_id' && typeof value === 'string' && value !== '') { - columns.push(`$${index}:name AS "objectId"`); - groupPattern = `GROUP BY $${index}:name`; - values.push(transformAggregateField(value)); - index += 1; - continue; - } - - if (field === '_id' && typeof value === 'object' && Object.keys(value).length !== 0) { - groupValues = value; - const groupByFields = []; - - for (const alias in value) { - if (typeof value[alias] === 'string' && value[alias]) { - const source = transformAggregateField(value[alias]); - - if (!groupByFields.includes(`"${source}"`)) { - groupByFields.push(`"${source}"`); - } - - values.push(source, alias); - columns.push(`$${index}:name AS $${index + 1}:name`); - index += 2; - } else { - const operation = Object.keys(value[alias])[0]; - const source = transformAggregateField(value[alias][operation]); - - if (mongoAggregateToPostgres[operation]) { - if (!groupByFields.includes(`"${source}"`)) { - groupByFields.push(`"${source}"`); - } - - columns.push(`EXTRACT(${mongoAggregateToPostgres[operation]} FROM $${index}:name AT TIME ZONE 'UTC') AS $${index + 1}:name`); - values.push(source, alias); - index += 2; - } - } - } - - groupPattern = `GROUP BY $${index}:raw`; - values.push(groupByFields.join()); - index += 1; - continue; - } - - if (typeof value === 'object') { - if (value.$sum) { - if (typeof value.$sum === 'string') { - columns.push(`SUM($${index}:name) AS $${index + 1}:name`); - values.push(transformAggregateField(value.$sum), field); - index += 2; - } else { - countField = field; - columns.push(`COUNT(*) AS $${index}:name`); - values.push(field); - index += 1; - } - } - - if (value.$max) { - columns.push(`MAX($${index}:name) AS $${index + 1}:name`); - values.push(transformAggregateField(value.$max), field); - index += 2; - } - - if (value.$min) { - columns.push(`MIN($${index}:name) AS $${index + 1}:name`); - values.push(transformAggregateField(value.$min), field); - index += 2; - } - - if (value.$avg) { - columns.push(`AVG($${index}:name) AS $${index + 1}:name`); - values.push(transformAggregateField(value.$avg), field); - index += 2; - } - } - } - } else { - columns.push('*'); - } - - if (stage.$project) { - if (columns.includes('*')) { - columns = []; - } - - for (const field in stage.$project) { - const value = stage.$project[field]; - - if (value === 1 || value === true) { - columns.push(`$${index}:name`); - values.push(field); - index += 1; - } - } - } - - if (stage.$match) { - const patterns = []; - const orOrAnd = Object.prototype.hasOwnProperty.call(stage.$match, '$or') ? ' OR ' : ' AND '; - - if (stage.$match.$or) { - const collapse = {}; - stage.$match.$or.forEach(element => { - for (const key in element) { - collapse[key] = element[key]; - } - }); - stage.$match = collapse; - } - - for (const field in stage.$match) { - const value = stage.$match[field]; - const matchPatterns = []; - Object.keys(ParseToPosgresComparator).forEach(cmp => { - if (value[cmp]) { - const pgComparator = ParseToPosgresComparator[cmp]; - matchPatterns.push(`$${index}:name ${pgComparator} $${index + 1}`); - values.push(field, toPostgresValue(value[cmp])); - index += 2; - } - }); - - if (matchPatterns.length > 0) { - patterns.push(`(${matchPatterns.join(' AND ')})`); - } - - if (schema.fields[field] && schema.fields[field].type && matchPatterns.length === 0) { - patterns.push(`$${index}:name = $${index + 1}`); - values.push(field, value); - index += 2; - } - } - - wherePattern = patterns.length > 0 ? `WHERE ${patterns.join(` ${orOrAnd} `)}` : ''; - } - - if (stage.$limit) { - limitPattern = `LIMIT $${index}`; - values.push(stage.$limit); - index += 1; - } - - if (stage.$skip) { - skipPattern = `OFFSET $${index}`; - values.push(stage.$skip); - index += 1; - } - - if (stage.$sort) { - const sort = stage.$sort; - const keys = Object.keys(sort); - const sorting = keys.map(key => { - const transformer = sort[key] === 1 ? 'ASC' : 'DESC'; - const order = `$${index}:name ${transformer}`; - index += 1; - return order; - }).join(); - values.push(...keys); - sortPattern = sort !== undefined && sorting.length > 0 ? `ORDER BY ${sorting}` : ''; - } - } - - if (groupPattern) { - columns.forEach((e, i, a) => { - if (e && e.trim() === '*') { - a[i] = ''; - } - }); - } - - const originalQuery = `SELECT ${columns.filter(Boolean).join()} FROM $1:name ${wherePattern} ${skipPattern} ${groupPattern} ${sortPattern} ${limitPattern}`; - const qs = explain ? this.createExplainableQuery(originalQuery) : originalQuery; - debug(qs, values); - return this._client.any(qs, values).then(a => { - if (explain) { - return a; - } - - const results = a.map(object => this.postgresObjectToParseObject(className, object, schema)); - results.forEach(result => { - if (!Object.prototype.hasOwnProperty.call(result, 'objectId')) { - result.objectId = null; - } - - if (groupValues) { - result.objectId = {}; - - for (const key in groupValues) { - result.objectId[key] = result[key]; - delete result[key]; - } - } - - if (countField) { - result[countField] = parseInt(result[countField], 10); - } - }); - return results; - }); - } - - async performInitialization({ - VolatileClassesSchemas - }) { - // TODO: This method needs to be rewritten to make proper use of connections (@vitaly-t) - debug('performInitialization'); - const promises = VolatileClassesSchemas.map(schema => { - return this.createTable(schema.className, schema).catch(err => { - if (err.code === PostgresDuplicateRelationError || err.code === _node.default.Error.INVALID_CLASS_NAME) { - return Promise.resolve(); - } - - throw err; - }).then(() => this.schemaUpgrade(schema.className, schema)); - }); - return Promise.all(promises).then(() => { - return this._client.tx('perform-initialization', async t => { - await t.none(_sql.default.misc.jsonObjectSetKeys); - await t.none(_sql.default.array.add); - await t.none(_sql.default.array.addUnique); - await t.none(_sql.default.array.remove); - await t.none(_sql.default.array.containsAll); - await t.none(_sql.default.array.containsAllRegex); - await t.none(_sql.default.array.contains); - return t.ctx; - }); - }).then(ctx => { - debug(`initializationDone in ${ctx.duration}`); - }).catch(error => { - /* eslint-disable no-console */ - console.error(error); - }); - } - - async createIndexes(className, indexes, conn) { - return (conn || this._client).tx(t => t.batch(indexes.map(i => { - return t.none('CREATE INDEX IF NOT EXISTS $1:name ON $2:name ($3:name)', [i.name, className, i.key]); - }))); - } - - async createIndexesIfNeeded(className, fieldName, type, conn) { - await (conn || this._client).none('CREATE INDEX IF NOT EXISTS $1:name ON $2:name ($3:name)', [fieldName, className, type]); - } - - async dropIndexes(className, indexes, conn) { - const queries = indexes.map(i => ({ - query: 'DROP INDEX $1:name', - values: i - })); - await (conn || this._client).tx(t => t.none(this._pgp.helpers.concat(queries))); - } - - async getIndexes(className) { - const qs = 'SELECT * FROM pg_indexes WHERE tablename = ${className}'; - return this._client.any(qs, { - className - }); - } - - async updateSchemaWithIndexes() { - return Promise.resolve(); - } // Used for testing purposes - - - async updateEstimatedCount(className) { - return this._client.none('ANALYZE $1:name', [className]); - } - - async createTransactionalSession() { - return new Promise(resolve => { - const transactionalSession = {}; - transactionalSession.result = this._client.tx(t => { - transactionalSession.t = t; - transactionalSession.promise = new Promise(resolve => { - transactionalSession.resolve = resolve; - }); - transactionalSession.batch = []; - resolve(transactionalSession); - return transactionalSession.promise; - }); - }); - } - - commitTransactionalSession(transactionalSession) { - transactionalSession.resolve(transactionalSession.t.batch(transactionalSession.batch)); - return transactionalSession.result; - } - - abortTransactionalSession(transactionalSession) { - const result = transactionalSession.result.catch(); - transactionalSession.batch.push(Promise.reject()); - transactionalSession.resolve(transactionalSession.t.batch(transactionalSession.batch)); - return result; - } - - async ensureIndex(className, schema, fieldNames, indexName, caseInsensitive = false, options = {}) { - const conn = options.conn !== undefined ? options.conn : this._client; - const defaultIndexName = `parse_default_${fieldNames.sort().join('_')}`; - const indexNameOptions = indexName != null ? { - name: indexName - } : { - name: defaultIndexName - }; - const constraintPatterns = caseInsensitive ? fieldNames.map((fieldName, index) => `lower($${index + 3}:name) varchar_pattern_ops`) : fieldNames.map((fieldName, index) => `$${index + 3}:name`); - const qs = `CREATE INDEX IF NOT EXISTS $1:name ON $2:name (${constraintPatterns.join()})`; - await conn.none(qs, [indexNameOptions.name, className, ...fieldNames]).catch(error => { - if (error.code === PostgresDuplicateRelationError && error.message.includes(indexNameOptions.name)) {// Index already exists. Ignore error. - } else if (error.code === PostgresUniqueIndexViolationError && error.message.includes(indexNameOptions.name)) { - // Cast the error into the proper parse error - throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); - } else { - throw error; - } - }); - } - -} - -exports.PostgresStorageAdapter = PostgresStorageAdapter; - -function convertPolygonToSQL(polygon) { - if (polygon.length < 3) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, `Polygon must have at least 3 values`); - } - - if (polygon[0][0] !== polygon[polygon.length - 1][0] || polygon[0][1] !== polygon[polygon.length - 1][1]) { - polygon.push(polygon[0]); - } - - const unique = polygon.filter((item, index, ar) => { - let foundIndex = -1; - - for (let i = 0; i < ar.length; i += 1) { - const pt = ar[i]; - - if (pt[0] === item[0] && pt[1] === item[1]) { - foundIndex = i; - break; - } - } - - return foundIndex === index; - }); - - if (unique.length < 3) { - throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'GeoJSON: Loop must have at least 3 different vertices'); - } - - const points = polygon.map(point => { - _node.default.GeoPoint._validate(parseFloat(point[1]), parseFloat(point[0])); - - return `(${point[1]}, ${point[0]})`; - }).join(', '); - return `(${points})`; -} - -function removeWhiteSpace(regex) { - if (!regex.endsWith('\n')) { - regex += '\n'; - } // remove non escaped comments - - - return regex.replace(/([^\\])#.*\n/gim, '$1') // remove lines starting with a comment - .replace(/^#.*\n/gim, '') // remove non escaped whitespace - .replace(/([^\\])\s+/gim, '$1') // remove whitespace at the beginning of a line - .replace(/^\s+/, '').trim(); -} - -function processRegexPattern(s) { - if (s && s.startsWith('^')) { - // regex for startsWith - return '^' + literalizeRegexPart(s.slice(1)); - } else if (s && s.endsWith('$')) { - // regex for endsWith - return literalizeRegexPart(s.slice(0, s.length - 1)) + '$'; - } // regex for contains - - - return literalizeRegexPart(s); -} - -function isStartsWithRegex(value) { - if (!value || typeof value !== 'string' || !value.startsWith('^')) { - return false; - } - - const matches = value.match(/\^\\Q.*\\E/); - return !!matches; -} - -function isAllValuesRegexOrNone(values) { - if (!values || !Array.isArray(values) || values.length === 0) { - return true; - } - - const firstValuesIsRegex = isStartsWithRegex(values[0].$regex); - - if (values.length === 1) { - return firstValuesIsRegex; - } - - for (let i = 1, length = values.length; i < length; ++i) { - if (firstValuesIsRegex !== isStartsWithRegex(values[i].$regex)) { - return false; - } - } - - return true; -} - -function isAnyValueRegexStartsWith(values) { - return values.some(function (value) { - return isStartsWithRegex(value.$regex); - }); -} - -function createLiteralRegex(remaining) { - return remaining.split('').map(c => { - const regex = RegExp('[0-9 ]|\\p{L}', 'u'); // Support all unicode letter chars - - if (c.match(regex) !== null) { - // don't escape alphanumeric characters - return c; - } // escape everything else (single quotes with single quotes, everything else with a backslash) - - - return c === `'` ? `''` : `\\${c}`; - }).join(''); -} - -function literalizeRegexPart(s) { - const matcher1 = /\\Q((?!\\E).*)\\E$/; - const result1 = s.match(matcher1); - - if (result1 && result1.length > 1 && result1.index > -1) { - // process regex that has a beginning and an end specified for the literal text - const prefix = s.substr(0, result1.index); - const remaining = result1[1]; - return literalizeRegexPart(prefix) + createLiteralRegex(remaining); - } // process regex that has a beginning specified for the literal text - - - const matcher2 = /\\Q((?!\\E).*)$/; - const result2 = s.match(matcher2); - - if (result2 && result2.length > 1 && result2.index > -1) { - const prefix = s.substr(0, result2.index); - const remaining = result2[1]; - return literalizeRegexPart(prefix) + createLiteralRegex(remaining); - } // remove all instances of \Q and \E from the remaining text & escape single quotes - - - return s.replace(/([^\\])(\\E)/, '$1').replace(/([^\\])(\\Q)/, '$1').replace(/^\\E/, '').replace(/^\\Q/, '').replace(/([^'])'/, `$1''`).replace(/^'([^'])/, `''$1`); -} - -var GeoPointCoder = { - isValidJSON(value) { - return typeof value === 'object' && value !== null && value.__type === 'GeoPoint'; - } - -}; -var _default = PostgresStorageAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL1Bvc3RncmVzL1Bvc3RncmVzU3RvcmFnZUFkYXB0ZXIuanMiXSwibmFtZXMiOlsiUG9zdGdyZXNSZWxhdGlvbkRvZXNOb3RFeGlzdEVycm9yIiwiUG9zdGdyZXNEdXBsaWNhdGVSZWxhdGlvbkVycm9yIiwiUG9zdGdyZXNEdXBsaWNhdGVDb2x1bW5FcnJvciIsIlBvc3RncmVzTWlzc2luZ0NvbHVtbkVycm9yIiwiUG9zdGdyZXNEdXBsaWNhdGVPYmplY3RFcnJvciIsIlBvc3RncmVzVW5pcXVlSW5kZXhWaW9sYXRpb25FcnJvciIsImxvZ2dlciIsInJlcXVpcmUiLCJkZWJ1ZyIsImFyZ3MiLCJhcmd1bWVudHMiLCJjb25jYXQiLCJzbGljZSIsImxlbmd0aCIsImxvZyIsImdldExvZ2dlciIsImFwcGx5IiwicGFyc2VUeXBlVG9Qb3N0Z3Jlc1R5cGUiLCJ0eXBlIiwiY29udGVudHMiLCJKU09OIiwic3RyaW5naWZ5IiwiUGFyc2VUb1Bvc2dyZXNDb21wYXJhdG9yIiwiJGd0IiwiJGx0IiwiJGd0ZSIsIiRsdGUiLCJtb25nb0FnZ3JlZ2F0ZVRvUG9zdGdyZXMiLCIkZGF5T2ZNb250aCIsIiRkYXlPZldlZWsiLCIkZGF5T2ZZZWFyIiwiJGlzb0RheU9mV2VlayIsIiRpc29XZWVrWWVhciIsIiRob3VyIiwiJG1pbnV0ZSIsIiRzZWNvbmQiLCIkbWlsbGlzZWNvbmQiLCIkbW9udGgiLCIkd2VlayIsIiR5ZWFyIiwidG9Qb3N0Z3Jlc1ZhbHVlIiwidmFsdWUiLCJfX3R5cGUiLCJpc28iLCJuYW1lIiwidHJhbnNmb3JtVmFsdWUiLCJvYmplY3RJZCIsImVtcHR5Q0xQUyIsIk9iamVjdCIsImZyZWV6ZSIsImZpbmQiLCJnZXQiLCJjb3VudCIsImNyZWF0ZSIsInVwZGF0ZSIsImRlbGV0ZSIsImFkZEZpZWxkIiwicHJvdGVjdGVkRmllbGRzIiwiZGVmYXVsdENMUFMiLCJ0b1BhcnNlU2NoZW1hIiwic2NoZW1hIiwiY2xhc3NOYW1lIiwiZmllbGRzIiwiX2hhc2hlZF9wYXNzd29yZCIsIl93cGVybSIsIl9ycGVybSIsImNscHMiLCJjbGFzc0xldmVsUGVybWlzc2lvbnMiLCJpbmRleGVzIiwidG9Qb3N0Z3Jlc1NjaGVtYSIsIl9wYXNzd29yZF9oaXN0b3J5IiwiaGFuZGxlRG90RmllbGRzIiwib2JqZWN0Iiwia2V5cyIsImZvckVhY2giLCJmaWVsZE5hbWUiLCJpbmRleE9mIiwiY29tcG9uZW50cyIsInNwbGl0IiwiZmlyc3QiLCJzaGlmdCIsImN1cnJlbnRPYmoiLCJuZXh0IiwiX19vcCIsInVuZGVmaW5lZCIsInRyYW5zZm9ybURvdEZpZWxkVG9Db21wb25lbnRzIiwibWFwIiwiY21wdCIsImluZGV4IiwidHJhbnNmb3JtRG90RmllbGQiLCJqb2luIiwidHJhbnNmb3JtQWdncmVnYXRlRmllbGQiLCJzdWJzdHIiLCJ2YWxpZGF0ZUtleXMiLCJrZXkiLCJpbmNsdWRlcyIsIlBhcnNlIiwiRXJyb3IiLCJJTlZBTElEX05FU1RFRF9LRVkiLCJqb2luVGFibGVzRm9yU2NoZW1hIiwibGlzdCIsImZpZWxkIiwicHVzaCIsImJ1aWxkV2hlcmVDbGF1c2UiLCJxdWVyeSIsImNhc2VJbnNlbnNpdGl2ZSIsInBhdHRlcm5zIiwidmFsdWVzIiwic29ydHMiLCJpc0FycmF5RmllbGQiLCJpbml0aWFsUGF0dGVybnNMZW5ndGgiLCJmaWVsZFZhbHVlIiwiJGV4aXN0cyIsImF1dGhEYXRhTWF0Y2giLCJtYXRjaCIsIiRpbiIsIiRyZWdleCIsIk1BWF9JTlRfUExVU19PTkUiLCJjbGF1c2VzIiwiY2xhdXNlVmFsdWVzIiwic3ViUXVlcnkiLCJjbGF1c2UiLCJwYXR0ZXJuIiwib3JPckFuZCIsIm5vdCIsIiRuZSIsImNvbnN0cmFpbnRGaWVsZE5hbWUiLCJwb2ludCIsImxvbmdpdHVkZSIsImxhdGl0dWRlIiwiJGVxIiwiaXNJbk9yTmluIiwiQXJyYXkiLCJpc0FycmF5IiwiJG5pbiIsImluUGF0dGVybnMiLCJhbGxvd051bGwiLCJsaXN0RWxlbSIsImxpc3RJbmRleCIsImNyZWF0ZUNvbnN0cmFpbnQiLCJiYXNlQXJyYXkiLCJub3RJbiIsIl8iLCJmbGF0TWFwIiwiZWx0IiwiSU5WQUxJRF9KU09OIiwiJGFsbCIsImlzQW55VmFsdWVSZWdleFN0YXJ0c1dpdGgiLCJpc0FsbFZhbHVlc1JlZ2V4T3JOb25lIiwiaSIsInByb2Nlc3NSZWdleFBhdHRlcm4iLCJzdWJzdHJpbmciLCIkY29udGFpbmVkQnkiLCJhcnIiLCIkdGV4dCIsInNlYXJjaCIsIiRzZWFyY2giLCJsYW5ndWFnZSIsIiR0ZXJtIiwiJGxhbmd1YWdlIiwiJGNhc2VTZW5zaXRpdmUiLCIkZGlhY3JpdGljU2Vuc2l0aXZlIiwiJG5lYXJTcGhlcmUiLCJkaXN0YW5jZSIsIiRtYXhEaXN0YW5jZSIsImRpc3RhbmNlSW5LTSIsIiR3aXRoaW4iLCIkYm94IiwiYm94IiwibGVmdCIsImJvdHRvbSIsInJpZ2h0IiwidG9wIiwiJGdlb1dpdGhpbiIsIiRjZW50ZXJTcGhlcmUiLCJjZW50ZXJTcGhlcmUiLCJHZW9Qb2ludCIsIkdlb1BvaW50Q29kZXIiLCJpc1ZhbGlkSlNPTiIsIl92YWxpZGF0ZSIsImlzTmFOIiwiJHBvbHlnb24iLCJwb2x5Z29uIiwicG9pbnRzIiwiY29vcmRpbmF0ZXMiLCIkZ2VvSW50ZXJzZWN0cyIsIiRwb2ludCIsInJlZ2V4Iiwib3BlcmF0b3IiLCJvcHRzIiwiJG9wdGlvbnMiLCJyZW1vdmVXaGl0ZVNwYWNlIiwiY29udmVydFBvbHlnb25Ub1NRTCIsImNtcCIsInBnQ29tcGFyYXRvciIsInBvc3RncmVzVmFsdWUiLCJjYXN0VHlwZSIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJQb3N0Z3Jlc1N0b3JhZ2VBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJ1cmkiLCJjb2xsZWN0aW9uUHJlZml4IiwiZGF0YWJhc2VPcHRpb25zIiwiX2NvbGxlY3Rpb25QcmVmaXgiLCJjbGllbnQiLCJwZ3AiLCJfY2xpZW50IiwiX3BncCIsImNhblNvcnRPbkpvaW5UYWJsZXMiLCJjcmVhdGVFeHBsYWluYWJsZVF1ZXJ5IiwiYW5hbHl6ZSIsImhhbmRsZVNodXRkb3duIiwiJHBvb2wiLCJlbmQiLCJfZW5zdXJlU2NoZW1hQ29sbGVjdGlvbkV4aXN0cyIsImNvbm4iLCJub25lIiwiY2F0Y2giLCJlcnJvciIsImNvZGUiLCJjbGFzc0V4aXN0cyIsIm9uZSIsImEiLCJleGlzdHMiLCJzZXRDbGFzc0xldmVsUGVybWlzc2lvbnMiLCJDTFBzIiwic2VsZiIsInRhc2siLCJ0Iiwic2V0SW5kZXhlc1dpdGhTY2hlbWFGb3JtYXQiLCJzdWJtaXR0ZWRJbmRleGVzIiwiZXhpc3RpbmdJbmRleGVzIiwiUHJvbWlzZSIsInJlc29sdmUiLCJfaWRfIiwiX2lkIiwiZGVsZXRlZEluZGV4ZXMiLCJpbnNlcnRlZEluZGV4ZXMiLCJJTlZBTElEX1FVRVJZIiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwidHgiLCJjcmVhdGVJbmRleGVzIiwiZHJvcEluZGV4ZXMiLCJjcmVhdGVDbGFzcyIsImNyZWF0ZVRhYmxlIiwiZXJyIiwiZGV0YWlsIiwiRFVQTElDQVRFX1ZBTFVFIiwidmFsdWVzQXJyYXkiLCJwYXR0ZXJuc0FycmF5IiwiYXNzaWduIiwiX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0IiwiX2VtYWlsX3ZlcmlmeV90b2tlbiIsIl9hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCIsIl9mYWlsZWRfbG9naW5fY291bnQiLCJfcGVyaXNoYWJsZV90b2tlbiIsIl9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQiLCJfcGFzc3dvcmRfY2hhbmdlZF9hdCIsInJlbGF0aW9ucyIsInBhcnNlVHlwZSIsInFzIiwiYmF0Y2giLCJqb2luVGFibGUiLCJzY2hlbWFVcGdyYWRlIiwiY29sdW1ucyIsImNvbHVtbl9uYW1lIiwibmV3Q29sdW1ucyIsImZpbHRlciIsIml0ZW0iLCJhZGRGaWVsZElmTm90RXhpc3RzIiwicG9zdGdyZXNUeXBlIiwicmVzdWx0IiwiYW55IiwicGF0aCIsImRlbGV0ZUNsYXNzIiwib3BlcmF0aW9ucyIsImhlbHBlcnMiLCJ0aGVuIiwiZGVsZXRlQWxsQ2xhc3NlcyIsIm5vdyIsIkRhdGUiLCJnZXRUaW1lIiwicmVzdWx0cyIsImpvaW5zIiwicmVkdWNlIiwiY2xhc3NlcyIsInF1ZXJpZXMiLCJkZWxldGVGaWVsZHMiLCJmaWVsZE5hbWVzIiwiaWR4IiwiZ2V0QWxsQ2xhc3NlcyIsInJvdyIsImdldENsYXNzIiwiY3JlYXRlT2JqZWN0IiwidHJhbnNhY3Rpb25hbFNlc3Npb24iLCJjb2x1bW5zQXJyYXkiLCJnZW9Qb2ludHMiLCJwcm92aWRlciIsInBvcCIsImluaXRpYWxWYWx1ZXMiLCJ2YWwiLCJ0ZXJtaW5hdGlvbiIsImdlb1BvaW50c0luamVjdHMiLCJsIiwiY29sdW1uc1BhdHRlcm4iLCJjb2wiLCJ2YWx1ZXNQYXR0ZXJuIiwicHJvbWlzZSIsIm9wcyIsInVuZGVybHlpbmdFcnJvciIsImNvbnN0cmFpbnQiLCJtYXRjaGVzIiwidXNlckluZm8iLCJkdXBsaWNhdGVkX2ZpZWxkIiwiZGVsZXRlT2JqZWN0c0J5UXVlcnkiLCJ3aGVyZSIsIk9CSkVDVF9OT1RfRk9VTkQiLCJmaW5kT25lQW5kVXBkYXRlIiwidXBkYXRlT2JqZWN0c0J5UXVlcnkiLCJ1cGRhdGVQYXR0ZXJucyIsIm9yaWdpbmFsVXBkYXRlIiwiZG90Tm90YXRpb25PcHRpb25zIiwiZ2VuZXJhdGUiLCJqc29uYiIsImxhc3RLZXkiLCJmaWVsZE5hbWVJbmRleCIsInN0ciIsImFtb3VudCIsIm9iamVjdHMiLCJrZXlzVG9JbmNyZW1lbnQiLCJrIiwiaW5jcmVtZW50UGF0dGVybnMiLCJjIiwia2V5c1RvRGVsZXRlIiwiZGVsZXRlUGF0dGVybnMiLCJwIiwidXBkYXRlT2JqZWN0IiwiZXhwZWN0ZWRUeXBlIiwicmVqZWN0Iiwid2hlcmVDbGF1c2UiLCJ1cHNlcnRPbmVPYmplY3QiLCJjcmVhdGVWYWx1ZSIsInNraXAiLCJsaW1pdCIsInNvcnQiLCJleHBsYWluIiwiaGFzTGltaXQiLCJoYXNTa2lwIiwid2hlcmVQYXR0ZXJuIiwibGltaXRQYXR0ZXJuIiwic2tpcFBhdHRlcm4iLCJzb3J0UGF0dGVybiIsInNvcnRDb3B5Iiwic29ydGluZyIsInRyYW5zZm9ybUtleSIsIm1lbW8iLCJvcmlnaW5hbFF1ZXJ5IiwicG9zdGdyZXNPYmplY3RUb1BhcnNlT2JqZWN0IiwidGFyZ2V0Q2xhc3MiLCJ5IiwieCIsImNvb3JkcyIsInBhcnNlRmxvYXQiLCJjcmVhdGVkQXQiLCJ0b0lTT1N0cmluZyIsInVwZGF0ZWRBdCIsImV4cGlyZXNBdCIsImVuc3VyZVVuaXF1ZW5lc3MiLCJjb25zdHJhaW50TmFtZSIsImNvbnN0cmFpbnRQYXR0ZXJucyIsIm1lc3NhZ2UiLCJyZWFkUHJlZmVyZW5jZSIsImVzdGltYXRlIiwiYXBwcm94aW1hdGVfcm93X2NvdW50IiwiZGlzdGluY3QiLCJjb2x1bW4iLCJpc05lc3RlZCIsImlzUG9pbnRlckZpZWxkIiwidHJhbnNmb3JtZXIiLCJjaGlsZCIsImFnZ3JlZ2F0ZSIsInBpcGVsaW5lIiwiaGludCIsImNvdW50RmllbGQiLCJncm91cFZhbHVlcyIsImdyb3VwUGF0dGVybiIsInN0YWdlIiwiJGdyb3VwIiwiZ3JvdXBCeUZpZWxkcyIsImFsaWFzIiwic291cmNlIiwib3BlcmF0aW9uIiwiJHN1bSIsIiRtYXgiLCIkbWluIiwiJGF2ZyIsIiRwcm9qZWN0IiwiJG1hdGNoIiwiJG9yIiwiY29sbGFwc2UiLCJlbGVtZW50IiwibWF0Y2hQYXR0ZXJucyIsIiRsaW1pdCIsIiRza2lwIiwiJHNvcnQiLCJvcmRlciIsImUiLCJ0cmltIiwiQm9vbGVhbiIsInBhcnNlSW50IiwicGVyZm9ybUluaXRpYWxpemF0aW9uIiwiVm9sYXRpbGVDbGFzc2VzU2NoZW1hcyIsInByb21pc2VzIiwiSU5WQUxJRF9DTEFTU19OQU1FIiwiYWxsIiwic3FsIiwibWlzYyIsImpzb25PYmplY3RTZXRLZXlzIiwiYXJyYXkiLCJhZGQiLCJhZGRVbmlxdWUiLCJyZW1vdmUiLCJjb250YWluc0FsbCIsImNvbnRhaW5zQWxsUmVnZXgiLCJjb250YWlucyIsImN0eCIsImR1cmF0aW9uIiwiY29uc29sZSIsImNyZWF0ZUluZGV4ZXNJZk5lZWRlZCIsImdldEluZGV4ZXMiLCJ1cGRhdGVTY2hlbWFXaXRoSW5kZXhlcyIsInVwZGF0ZUVzdGltYXRlZENvdW50IiwiY3JlYXRlVHJhbnNhY3Rpb25hbFNlc3Npb24iLCJjb21taXRUcmFuc2FjdGlvbmFsU2Vzc2lvbiIsImFib3J0VHJhbnNhY3Rpb25hbFNlc3Npb24iLCJlbnN1cmVJbmRleCIsImluZGV4TmFtZSIsIm9wdGlvbnMiLCJkZWZhdWx0SW5kZXhOYW1lIiwiaW5kZXhOYW1lT3B0aW9ucyIsInVuaXF1ZSIsImFyIiwiZm91bmRJbmRleCIsInB0IiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiZW5kc1dpdGgiLCJyZXBsYWNlIiwicyIsInN0YXJ0c1dpdGgiLCJsaXRlcmFsaXplUmVnZXhQYXJ0IiwiaXNTdGFydHNXaXRoUmVnZXgiLCJmaXJzdFZhbHVlc0lzUmVnZXgiLCJzb21lIiwiY3JlYXRlTGl0ZXJhbFJlZ2V4IiwicmVtYWluaW5nIiwiUmVnRXhwIiwibWF0Y2hlcjEiLCJyZXN1bHQxIiwicHJlZml4IiwibWF0Y2hlcjIiLCJyZXN1bHQyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7O0FBRUE7O0FBRUE7O0FBQ0E7O0FBZ0JBOzs7Ozs7Ozs7O0FBZEEsTUFBTUEsaUNBQWlDLEdBQUcsT0FBMUM7QUFDQSxNQUFNQyw4QkFBOEIsR0FBRyxPQUF2QztBQUNBLE1BQU1DLDRCQUE0QixHQUFHLE9BQXJDO0FBQ0EsTUFBTUMsMEJBQTBCLEdBQUcsT0FBbkM7QUFDQSxNQUFNQyw0QkFBNEIsR0FBRyxPQUFyQztBQUNBLE1BQU1DLGlDQUFpQyxHQUFHLE9BQTFDOztBQUNBLE1BQU1DLE1BQU0sR0FBR0MsT0FBTyxDQUFDLGlCQUFELENBQXRCOztBQUVBLE1BQU1DLEtBQUssR0FBRyxVQUFVLEdBQUdDLElBQWIsRUFBd0I7QUFDcENBLEVBQUFBLElBQUksR0FBRyxD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cUMsQ0FxQnRDOzs7QUFDQSxTQUFPUCxDQUFDLENBQ0xELE9BREksQ0FDSSxjQURKLEVBQ29CLElBRHBCLEVBRUpBLE9BRkksQ0FFSSxjQUZKLEVBRW9CLElBRnBCLEVBR0pBLE9BSEksQ0FHSSxNQUhKLEVBR1ksRUFIWixFQUlKQSxPQUpJLENBSUksTUFKSixFQUlZLEVBSlosRUFLSkEsT0FMSSxDQUtJLFNBTEosRUFLZ0IsTUFMaEIsRUFNSkEsT0FOSSxDQU1JLFVBTkosRUFNaUIsTUFOakIsQ0FBUDtBQU9EOztBQUVELElBQUkvUSxhQUFhLEdBQUc7QUFDbEJDLEVBQUFBLFdBQVcsQ0FBQ3pJLEtBQUQsRUFBUTtBQUNqQixXQUFPLE9BQU9BLEtBQVAsS0FBaUIsUUFBakIsSUFBNkJBLEtBQUssS0FBSyxJQUF2QyxJQUErQ0EsS0FBSyxDQUFDQyxNQUFOLEtBQWlCLFVBQXZFO0FBQ0Q7O0FBSGlCLENBQXBCO2VBTWU0SixzQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG5pbXBvcnQgeyBjcmVhdGVDbGllbnQgfSBmcm9tICcuL1Bvc3RncmVzQ2xpZW50Jztcbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHNxbCBmcm9tICcuL3NxbCc7XG5cbmNvbnN0IFBvc3RncmVzUmVsYXRpb25Eb2VzTm90RXhpc3RFcnJvciA9ICc0MlAwMSc7XG5jb25zdCBQb3N0Z3Jlc0R1cGxpY2F0ZVJlbGF0aW9uRXJyb3IgPSAnNDJQMDcnO1xuY29uc3QgUG9zdGdyZXNEdXBsaWNhdGVDb2x1bW5FcnJvciA9ICc0MjcwMSc7XG5jb25zdCBQb3N0Z3Jlc01pc3NpbmdDb2x1bW5FcnJvciA9ICc0MjcwMyc7XG5jb25zdCBQb3N0Z3Jlc0R1cGxpY2F0ZU9iamVjdEVycm9yID0gJzQyNzEwJztcbmNvbnN0IFBvc3RncmVzVW5pcXVlSW5kZXhWaW9sYXRpb25FcnJvciA9ICcyMzUwNSc7XG5jb25zdCBsb2dnZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9sb2dnZXInKTtcblxuY29uc3QgZGVidWcgPSBmdW5jdGlvbiAoLi4uYXJnczogYW55KSB7XG4gIGFyZ3MgPSBbJ1BHOiAnICsgYXJndW1lbnRzWzBdXS5jb25jYXQoYXJncy5zbGljZSgxLCBhcmdzLmxlbmd0aCkpO1xuICBjb25zdCBsb2cgPSBsb2dnZXIuZ2V0TG9nZ2VyKCk7XG4gIGxvZy5kZWJ1Zy5hcHBseShsb2csIGFyZ3MpO1xufTtcblxuaW1wb3J0IHsgU3RvcmFnZUFkYXB0ZXIgfSBmcm9tICcuLi9TdG9yYWdlQWRhcHRlcic7XG5pbXBvcnQgdHlwZSB7IFNjaGVtYVR5cGUsIFF1ZXJ5VHlwZSwgUXVlcnlPcHRpb25zIH0gZnJvbSAnLi4vU3RvcmFnZUFkYXB0ZXInO1xuXG5jb25zdCBwYXJzZVR5cGVUb1Bvc3RncmVzVHlwZSA9IHR5cGUgPT4ge1xuICBzd2l0Y2ggKHR5cGUudHlwZSkge1xuICAgIGNhc2UgJ1N0cmluZyc6XG4gICAgICByZXR1cm4gJ3RleHQnO1xuICAgIGNhc2UgJ0RhdGUnOlxuICAgICAgcmV0dXJuICd0aW1lc3RhbXAgd2l0aCB0aW1lIHpvbmUnO1xuICAgIGNhc2UgJ09iamVjdCc6XG4gICAgICByZXR1cm4gJ2pzb25iJztcbiAgICBjYXNlICdGaWxlJzpcbiAgICAgIHJldHVybiAndGV4dCc7XG4gICAgY2FzZSAnQm9vbGVhbic6XG4gICAgICByZXR1cm4gJ2Jvb2xlYW4nO1xuICAgIGNhc2UgJ1BvaW50ZXInOlxuICAgICAgcmV0dXJuICd0ZXh0JztcbiAgICBjYXNlICdOdW1iZXInOlxuICAgICAgcmV0dXJuICdkb3VibGUgcHJlY2lzaW9uJztcbiAgICBjYXNlICdHZW9Qb2ludCc6XG4gICAgICByZXR1cm4gJ3BvaW50JztcbiAgICBjYXNlICdCeXRlcyc6XG4gICAgICByZXR1cm4gJ2pzb25iJztcbiAgICBjYXNlICdQb2x5Z29uJzpcbiAgICAgIHJldHVybiAncG9seWdvbic7XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgaWYgKHR5cGUuY29udGVudHMgJiYgdHlwZS5jb250ZW50cy50eXBlID09PSAnU3RyaW5nJykge1xuICAgICAgICByZXR1cm4gJ3RleHRbXSc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gJ2pzb25iJztcbiAgICAgIH1cbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgYG5vIHR5cGUgZm9yICR7SlNPTi5zdHJpbmdpZnkodHlwZSl9IHlldGA7XG4gIH1cbn07XG5cbmNvbnN0IFBhcnNlVG9Qb3NncmVzQ29tcGFyYXRvciA9IHtcbiAgJGd0OiAnPicsXG4gICRsdDogJzwnLFxuICAkZ3RlOiAnPj0nLFxuICAkbHRlOiAnPD0nLFxufTtcblxuY29uc3QgbW9uZ29BZ2dyZWdhdGVUb1Bvc3RncmVzID0ge1xuICAkZGF5T2ZNb250aDogJ0RBWScsXG4gICRkYXlPZldlZWs6ICdET1cnLFxuICAkZGF5T2ZZZWFyOiAnRE9ZJyxcbiAgJGlzb0RheU9mV2VlazogJ0lTT0RPVycsXG4gICRpc29XZWVrWWVhcjogJ0lTT1lFQVInLFxuICAkaG91cjogJ0hPVVInLFxuICAkbWludXRlOiAnTUlOVVRFJyxcbiAgJHNlY29uZDogJ1NFQ09ORCcsXG4gICRtaWxsaXNlY29uZDogJ01JTExJU0VDT05EUycsXG4gICRtb250aDogJ01PTlRIJyxcbiAgJHdlZWs6ICdXRUVLJyxcbiAgJHllYXI6ICdZRUFSJyxcbn07XG5cbmNvbnN0IHRvUG9zdGdyZXNWYWx1ZSA9IHZhbHVlID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICBpZiAodmFsdWUuX190eXBlID09PSAnRGF0ZScpIHtcbiAgICAgIHJldHVybiB2YWx1ZS5pc287XG4gICAgfVxuICAgIGlmICh2YWx1ZS5fX3R5cGUgPT09ICdGaWxlJykge1xuICAgICAgcmV0dXJuIHZhbHVlLm5hbWU7XG4gICAgfVxuICB9XG4gIHJldHVybiB2YWx1ZTtcbn07XG5cbmNvbnN0IHRyYW5zZm9ybVZhbHVlID0gdmFsdWUgPT4ge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZS5fX3R5cGUgPT09ICdQb2ludGVyJykge1xuICAgIHJldHVybiB2YWx1ZS5vYmplY3RJZDtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59O1xuXG4vLyBEdXBsaWNhdGUgZnJvbSB0aGVuIG1vbmdvIGFkYXB0ZXIuLi5cbmNvbnN0IGVtcHR5Q0xQUyA9IE9iamVjdC5mcmVlemUoe1xuICBmaW5kOiB7fSxcbiAgZ2V0OiB7fSxcbiAgY291bnQ6IHt9LFxuICBjcmVhdGU6IHt9LFxuICB1cGRhdGU6IHt9LFxuICBkZWxldGU6IHt9LFxuICBhZGRGaWVsZDoge30sXG4gIHByb3RlY3RlZEZpZWxkczoge30sXG59KTtcblxuY29uc3QgZGVmYXVsdENMUFMgPSBPYmplY3QuZnJlZXplKHtcbiAgZmluZDogeyAnKic6IHRydWUgfSxcbiAgZ2V0OiB7ICcqJzogdHJ1ZSB9LFxuICBjb3VudDogeyAnKic6IHRydWUgfSxcbiAgY3JlYXRlOiB7ICcqJzogdHJ1ZSB9LFxuICB1cGRhdGU6IHsgJyonOiB0cnVlIH0sXG4gIGRlbGV0ZTogeyAnKic6IHRydWUgfSxcbiAgYWRkRmllbGQ6IHsgJyonOiB0cnVlIH0sXG4gIHByb3RlY3RlZEZpZWxkczogeyAnKic6IFtdIH0sXG59KTtcblxuY29uc3QgdG9QYXJzZVNjaGVtYSA9IHNjaGVtYSA9PiB7XG4gIGlmIChzY2hlbWEuY2xhc3NOYW1lID09PSAnX1VzZXInKSB7XG4gICAgZGVsZXRlIHNjaGVtYS5maWVsZHMuX2hhc2hlZF9wYXNzd29yZDtcbiAgfVxuICBpZiAoc2NoZW1hLmZpZWxkcykge1xuICAgIGRlbGV0ZSBzY2hlbWEuZmllbGRzLl93cGVybTtcbiAgICBkZWxldGUgc2NoZW1hLmZpZWxkcy5fcnBlcm07XG4gIH1cbiAgbGV0IGNscHMgPSBkZWZhdWx0Q0xQUztcbiAgaWYgKHNjaGVtYS5jbGFzc0xldmVsUGVybWlzc2lvbnMpIHtcbiAgICBjbHBzID0geyAuLi5lbXB0eUNMUFMsIC4uLnNjaGVtYS5jbGFzc0xldmVsUGVybWlzc2lvbnMgfTtcbiAgfVxuICBsZXQgaW5kZXhlcyA9IHt9O1xuICBpZiAoc2NoZW1hLmluZGV4ZXMpIHtcbiAgICBpbmRleGVzID0geyAuLi5zY2hlbWEuaW5kZXhlcyB9O1xuICB9XG4gIHJldHVybiB7XG4gICAgY2xhc3NOYW1lOiBzY2hlbWEuY2xhc3NOYW1lLFxuICAgIGZpZWxkczogc2NoZW1hLmZpZWxkcyxcbiAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IGNscHMsXG4gICAgaW5kZXhlcyxcbiAgfTtcbn07XG5cbmNvbnN0IHRvUG9zdGdyZXNTY2hlbWEgPSBzY2hlbWEgPT4ge1xuICBpZiAoIXNjaGVtYSkge1xuICAgIHJldHVybiBzY2hlbWE7XG4gIH1cbiAgc2NoZW1hLmZpZWxkcyA9IHNjaGVtYS5maWVsZHMgfHwge307XG4gIHNjaGVtYS5maWVsZHMuX3dwZXJtID0geyB0eXBlOiAnQXJyYXknLCBjb250ZW50czogeyB0eXBlOiAnU3RyaW5nJyB9IH07XG4gIHNjaGVtYS5maWVsZHMuX3JwZXJtID0geyB0eXBlOiAnQXJyYXknLCBjb250ZW50czogeyB0eXBlOiAnU3RyaW5nJyB9IH07XG4gIGlmIChzY2hlbWEuY2xhc3NOYW1lID09PSAnX1VzZXInKSB7XG4gICAgc2NoZW1hLmZpZWxkcy5faGFzaGVkX3Bhc3N3b3JkID0geyB0eXBlOiAnU3RyaW5nJyB9O1xuICAgIHNjaGVtYS5maWVsZHMuX3Bhc3N3b3JkX2hpc3RvcnkgPSB7IHR5cGU6ICdBcnJheScgfTtcbiAgfVxuICByZXR1cm4gc2NoZW1hO1xufTtcblxuY29uc3QgaGFuZGxlRG90RmllbGRzID0gb2JqZWN0ID0+IHtcbiAgT2JqZWN0LmtleXMob2JqZWN0KS5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPiAtMSkge1xuICAgICAgY29uc3QgY29tcG9uZW50cyA9IGZpZWxkTmFtZS5zcGxpdCgnLicpO1xuICAgICAgY29uc3QgZmlyc3QgPSBjb21wb25lbnRzLnNoaWZ0KCk7XG4gICAgICBvYmplY3RbZmlyc3RdID0gb2JqZWN0W2ZpcnN0XSB8fCB7fTtcbiAgICAgIGxldCBjdXJyZW50T2JqID0gb2JqZWN0W2ZpcnN0XTtcbiAgICAgIGxldCBuZXh0O1xuICAgICAgbGV0IHZhbHVlID0gb2JqZWN0W2ZpZWxkTmFtZV07XG4gICAgICBpZiAodmFsdWUgJiYgdmFsdWUuX19vcCA9PT0gJ0RlbGV0ZScpIHtcbiAgICAgICAgdmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25kLWFzc2lnbiAqL1xuICAgICAgd2hpbGUgKChuZXh0ID0gY29tcG9uZW50cy5zaGlmdCgpKSkge1xuICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIG5vLWNvbmQtYXNzaWduICovXG4gICAgICAgIGN1cnJlbnRPYmpbbmV4dF0gPSBjdXJyZW50T2JqW25leHRdIHx8IHt9O1xuICAgICAgICBpZiAoY29tcG9uZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICBjdXJyZW50T2JqW25leHRdID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudE9iaiA9IGN1cnJlbnRPYmpbbmV4dF07XG4gICAgICB9XG4gICAgICBkZWxldGUgb2JqZWN0W2ZpZWxkTmFtZV07XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIG9iamVjdDtcbn07XG5cbmNvbnN0IHRyYW5zZm9ybURvdEZpZWxkVG9Db21wb25lbnRzID0gZmllbGROYW1lID0+IHtcbiAgcmV0dXJuIGZpZWxkTmFtZS5zcGxpdCgnLicpLm1hcCgoY21wdCwgaW5kZXgpID0+IHtcbiAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgIHJldHVybiBgXCIke2NtcHR9XCJgO1xuICAgIH1cbiAgICByZXR1cm4gYCcke2NtcHR9J2A7XG4gIH0pO1xufTtcblxuY29uc3QgdHJhbnNmb3JtRG90RmllbGQgPSBmaWVsZE5hbWUgPT4ge1xuICBpZiAoZmllbGROYW1lLmluZGV4T2YoJy4nKSA9PT0gLTEpIHtcbiAgICByZXR1cm4gYFwiJHtmaWVsZE5hbWV9XCJgO1xuICB9XG4gIGNvbnN0IGNvbXBvbmVudHMgPSB0cmFuc2Zvcm1Eb3RGaWVsZFRvQ29tcG9uZW50cyhmaWVsZE5hbWUpO1xuICBsZXQgbmFtZSA9IGNvbXBvbmVudHMuc2xpY2UoMCwgY29tcG9uZW50cy5sZW5ndGggLSAxKS5qb2luKCctPicpO1xuICBuYW1lICs9ICctPj4nICsgY29tcG9uZW50c1tjb21wb25lbnRzLmxlbmd0aCAtIDFdO1xuICByZXR1cm4gbmFtZTtcbn07XG5cbmNvbnN0IHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkID0gZmllbGROYW1lID0+IHtcbiAgaWYgKHR5cGVvZiBmaWVsZE5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGZpZWxkTmFtZTtcbiAgfVxuICBpZiAoZmllbGROYW1lID09PSAnJF9jcmVhdGVkX2F0Jykge1xuICAgIHJldHVybiAnY3JlYXRlZEF0JztcbiAgfVxuICBpZiAoZmllbGROYW1lID09PSAnJF91cGRhdGVkX2F0Jykge1xuICAgIHJldHVybiAndXBkYXRlZEF0JztcbiAgfVxuICByZXR1cm4gZmllbGROYW1lLnN1YnN0cigxKTtcbn07XG5cbmNvbnN0IHZhbGlkYXRlS2V5cyA9IG9iamVjdCA9PiB7XG4gIGlmICh0eXBlb2Ygb2JqZWN0ID09ICdvYmplY3QnKSB7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gb2JqZWN0KSB7XG4gICAgICBpZiAodHlwZW9mIG9iamVjdFtrZXldID09ICdvYmplY3QnKSB7XG4gICAgICAgIHZhbGlkYXRlS2V5cyhvYmplY3Rba2V5XSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChrZXkuaW5jbHVkZXMoJyQnKSB8fCBrZXkuaW5jbHVkZXMoJy4nKSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9ORVNURURfS0VZLFxuICAgICAgICAgIFwiTmVzdGVkIGtleXMgc2hvdWxkIG5vdCBjb250YWluIHRoZSAnJCcgb3IgJy4nIGNoYXJhY3RlcnNcIlxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxuLy8gUmV0dXJucyB0aGUgbGlzdCBvZiBqb2luIHRhYmxlcyBvbiBhIHNjaGVtYVxuY29uc3Qgam9pblRhYmxlc0ZvclNjaGVtYSA9IHNjaGVtYSA9PiB7XG4gIGNvbnN0IGxpc3QgPSBbXTtcbiAgaWYgKHNjaGVtYSkge1xuICAgIE9iamVjdC5rZXlzKHNjaGVtYS5maWVsZHMpLmZvckVhY2goZmllbGQgPT4ge1xuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdSZWxhdGlvbicpIHtcbiAgICAgICAgbGlzdC5wdXNoKGBfSm9pbjoke2ZpZWxkfToke3NjaGVtYS5jbGFzc05hbWV9YCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIGxpc3Q7XG59O1xuXG5pbnRlcmZhY2UgV2hlcmVDbGF1c2Uge1xuICBwYXR0ZXJuOiBzdHJpbmc7XG4gIHZhbHVlczogQXJyYXk8YW55PjtcbiAgc29ydHM6IEFycmF5PGFueT47XG59XG5cbmNvbnN0IGJ1aWxkV2hlcmVDbGF1c2UgPSAoeyBzY2hlbWEsIHF1ZXJ5LCBpbmRleCwgY2FzZUluc2Vuc2l0aXZlIH0pOiBXaGVyZUNsYXVzZSA9PiB7XG4gIGNvbnN0IHBhdHRlcm5zID0gW107XG4gIGxldCB2YWx1ZXMgPSBbXTtcbiAgY29uc3Qgc29ydHMgPSBbXTtcblxuICBzY2hlbWEgPSB0b1Bvc3RncmVzU2NoZW1hKHNjaGVtYSk7XG4gIGZvciAoY29uc3QgZmllbGROYW1lIGluIHF1ZXJ5KSB7XG4gICAgY29uc3QgaXNBcnJheUZpZWxkID1cbiAgICAgIHNjaGVtYS5maWVsZHMgJiYgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdICYmIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnQXJyYXknO1xuICAgIGNvbnN0IGluaXRpYWxQYXR0ZXJuc0xlbmd0aCA9IHBhdHRlcm5zLmxlbmd0aDtcbiAgICBjb25zdCBmaWVsZFZhbHVlID0gcXVlcnlbZmllbGROYW1lXTtcblxuICAgIC8vIG5vdGhpbmcgaW4gdGhlIHNjaGVtYSwgaXQncyBnb25uYSBibG93IHVwXG4gICAgaWYgKCFzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0pIHtcbiAgICAgIC8vIGFzIGl0IHdvbid0IGV4aXN0XG4gICAgICBpZiAoZmllbGRWYWx1ZSAmJiBmaWVsZFZhbHVlLiRleGlzdHMgPT09IGZhbHNlKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGF1dGhEYXRhTWF0Y2ggPSBmaWVsZE5hbWUubWF0Y2goL15fYXV0aF9kYXRhXyhbYS16QS1aMC05X10rKSQvKTtcbiAgICBpZiAoYXV0aERhdGFNYXRjaCkge1xuICAgICAgLy8gVE9ETzogSGFuZGxlIHF1ZXJ5aW5nIGJ5IF9hdXRoX2RhdGFfcHJvdmlkZXIsIGF1dGhEYXRhIGlzIHN0b3JlZCBpbiBhdXRoRGF0YSBmaWVsZFxuICAgICAgY29udGludWU7XG4gICAgfSBlbHNlIGlmIChjYXNlSW5zZW5zaXRpdmUgJiYgKGZpZWxkTmFtZSA9PT0gJ3VzZXJuYW1lJyB8fCBmaWVsZE5hbWUgPT09ICdlbWFpbCcpKSB7XG4gICAgICBwYXR0ZXJucy5wdXNoKGBMT1dFUigkJHtpbmRleH06bmFtZSkgPSBMT1dFUigkJHtpbmRleCArIDF9KWApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfSBlbHNlIGlmIChmaWVsZE5hbWUuaW5kZXhPZignLicpID49IDApIHtcbiAgICAgIGxldCBuYW1lID0gdHJhbnNmb3JtRG90RmllbGQoZmllbGROYW1lKTtcbiAgICAgIGlmIChmaWVsZFZhbHVlID09PSBudWxsKSB7XG4gICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpyYXcgSVMgTlVMTGApO1xuICAgICAgICB2YWx1ZXMucHVzaChuYW1lKTtcbiAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZmllbGRWYWx1ZS4kaW4pIHtcbiAgICAgICAgICBuYW1lID0gdHJhbnNmb3JtRG90RmllbGRUb0NvbXBvbmVudHMoZmllbGROYW1lKS5qb2luKCctPicpO1xuICAgICAgICAgIHBhdHRlcm5zLnB1c2goYCgkJHtpbmRleH06cmF3KTo6anNvbmIgQD4gJCR7aW5kZXggKyAxfTo6anNvbmJgKTtcbiAgICAgICAgICB2YWx1ZXMucHVzaChuYW1lLCBKU09OLnN0cmluZ2lmeShmaWVsZFZhbHVlLiRpbikpO1xuICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS4kcmVnZXgpIHtcbiAgICAgICAgICAvLyBIYW5kbGUgbGF0ZXJcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZmllbGRWYWx1ZSAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06cmF3ID0gJCR7aW5kZXggKyAxfTo6dGV4dGApO1xuICAgICAgICAgIHZhbHVlcy5wdXNoKG5hbWUsIGZpZWxkVmFsdWUpO1xuICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGZpZWxkVmFsdWUgPT09IG51bGwgfHwgZmllbGRWYWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSBJUyBOVUxMYCk7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgaW5kZXggKz0gMTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGZpZWxkVmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgZmllbGRWYWx1ZSk7XG4gICAgICBpbmRleCArPSAyO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGZpZWxkVmFsdWUgPT09ICdib29sZWFuJykge1xuICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAvLyBDYW4ndCBjYXN0IGJvb2xlYW4gdG8gZG91YmxlIHByZWNpc2lvblxuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ051bWJlcicpIHtcbiAgICAgICAgLy8gU2hvdWxkIGFsd2F5cyByZXR1cm4gemVybyByZXN1bHRzXG4gICAgICAgIGNvbnN0IE1BWF9JTlRfUExVU19PTkUgPSA5MjIzMzcyMDM2ODU0Nzc1ODA4O1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIE1BWF9JTlRfUExVU19PTkUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlKTtcbiAgICAgIH1cbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lID0gJCR7aW5kZXggKyAxfWApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfSBlbHNlIGlmIChbJyRvcicsICckbm9yJywgJyRhbmQnXS5pbmNsdWRlcyhmaWVsZE5hbWUpKSB7XG4gICAgICBjb25zdCBjbGF1c2VzID0gW107XG4gICAgICBjb25zdCBjbGF1c2VWYWx1ZXMgPSBbXTtcbiAgICAgIGZpZWxkVmFsdWUuZm9yRWFjaChzdWJRdWVyeSA9PiB7XG4gICAgICAgIGNvbnN0IGNsYXVzZSA9IGJ1aWxkV2hlcmVDbGF1c2Uoe1xuICAgICAgICAgIHNjaGVtYSxcbiAgICAgICAgICBxdWVyeTogc3ViUXVlcnksXG4gICAgICAgICAgaW5kZXgsXG4gICAgICAgICAgY2FzZUluc2Vuc2l0aXZlLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGNsYXVzZS5wYXR0ZXJuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBjbGF1c2VzLnB1c2goY2xhdXNlLnBhdHRlcm4pO1xuICAgICAgICAgIGNsYXVzZVZhbHVlcy5wdXNoKC4uLmNsYXVzZS52YWx1ZXMpO1xuICAgICAgICAgIGluZGV4ICs9IGNsYXVzZS52YWx1ZXMubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgb3JPckFuZCA9IGZpZWxkTmFtZSA9PT0gJyRhbmQnID8gJyBBTkQgJyA6ICcgT1IgJztcbiAgICAgIGNvbnN0IG5vdCA9IGZpZWxkTmFtZSA9PT0gJyRub3InID8gJyBOT1QgJyA6ICcnO1xuXG4gICAgICBwYXR0ZXJucy5wdXNoKGAke25vdH0oJHtjbGF1c2VzLmpvaW4ob3JPckFuZCl9KWApO1xuICAgICAgdmFsdWVzLnB1c2goLi4uY2xhdXNlVmFsdWVzKTtcbiAgICB9XG5cbiAgICBpZiAoZmllbGRWYWx1ZS4kbmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGlzQXJyYXlGaWVsZCkge1xuICAgICAgICBmaWVsZFZhbHVlLiRuZSA9IEpTT04uc3RyaW5naWZ5KFtmaWVsZFZhbHVlLiRuZV0pO1xuICAgICAgICBwYXR0ZXJucy5wdXNoKGBOT1QgYXJyYXlfY29udGFpbnMoJCR7aW5kZXh9Om5hbWUsICQke2luZGV4ICsgMX0pYCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZmllbGRWYWx1ZS4kbmUgPT09IG51bGwpIHtcbiAgICAgICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSBJUyBOT1QgTlVMTGApO1xuICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBpZiBub3QgbnVsbCwgd2UgbmVlZCB0byBtYW51YWxseSBleGNsdWRlIG51bGxcbiAgICAgICAgICBpZiAoZmllbGRWYWx1ZS4kbmUuX190eXBlID09PSAnR2VvUG9pbnQnKSB7XG4gICAgICAgICAgICBwYXR0ZXJucy5wdXNoKFxuICAgICAgICAgICAgICBgKCQke2luZGV4fTpuYW1lIDw+IFBPSU5UKCQke2luZGV4ICsgMX0sICQke2luZGV4ICsgMn0pIE9SICQke2luZGV4fTpuYW1lIElTIE5VTEwpYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPj0gMCkge1xuICAgICAgICAgICAgICBjb25zdCBjb25zdHJhaW50RmllbGROYW1lID0gdHJhbnNmb3JtRG90RmllbGQoZmllbGROYW1lKTtcbiAgICAgICAgICAgICAgcGF0dGVybnMucHVzaChcbiAgICAgICAgICAgICAgICBgKCR7Y29uc3RyYWludEZpZWxkTmFtZX0gPD4gJCR7aW5kZXh9IE9SICR7Y29uc3RyYWludEZpZWxkTmFtZX0gSVMgTlVMTClgXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBwYXR0ZXJucy5wdXNoKGAoJCR7aW5kZXh9Om5hbWUgPD4gJCR7aW5kZXggKyAxfSBPUiAkJHtpbmRleH06bmFtZSBJUyBOVUxMKWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGZpZWxkVmFsdWUuJG5lLl9fdHlwZSA9PT0gJ0dlb1BvaW50Jykge1xuICAgICAgICBjb25zdCBwb2ludCA9IGZpZWxkVmFsdWUuJG5lO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIHBvaW50LmxvbmdpdHVkZSwgcG9pbnQubGF0aXR1ZGUpO1xuICAgICAgICBpbmRleCArPSAzO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVE9ETzogc3VwcG9ydCBhcnJheXNcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlLiRuZSk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChmaWVsZFZhbHVlLiRlcSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoZmllbGRWYWx1ZS4kZXEgPT09IG51bGwpIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgSVMgTlVMTGApO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgICBpbmRleCArPSAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPj0gMCkge1xuICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkVmFsdWUuJGVxKTtcbiAgICAgICAgICBwYXR0ZXJucy5wdXNoKGAke3RyYW5zZm9ybURvdEZpZWxkKGZpZWxkTmFtZSl9ID0gJCR7aW5kZXgrK31gKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUuJGVxKTtcbiAgICAgICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgICBpbmRleCArPSAyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IGlzSW5Pck5pbiA9IEFycmF5LmlzQXJyYXkoZmllbGRWYWx1ZS4kaW4pIHx8IEFycmF5LmlzQXJyYXkoZmllbGRWYWx1ZS4kbmluKTtcbiAgICBpZiAoXG4gICAgICBBcnJheS5pc0FycmF5KGZpZWxkVmFsdWUuJGluKSAmJlxuICAgICAgaXNBcnJheUZpZWxkICYmXG4gICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0uY29udGVudHMgJiZcbiAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS5jb250ZW50cy50eXBlID09PSAnU3RyaW5nJ1xuICAgICkge1xuICAgICAgY29uc3QgaW5QYXR0ZXJucyA9IFtdO1xuICAgICAgbGV0IGFsbG93TnVsbCA9IGZhbHNlO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lKTtcbiAgICAgIGZpZWxkVmFsdWUuJGluLmZvckVhY2goKGxpc3RFbGVtLCBsaXN0SW5kZXgpID0+IHtcbiAgICAgICAgaWYgKGxpc3RFbGVtID09PSBudWxsKSB7XG4gICAgICAgICAgYWxsb3dOdWxsID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWx1ZXMucHVzaChsaXN0RWxlbSk7XG4gICAgICAgICAgaW5QYXR0ZXJucy5wdXNoKGAkJHtpbmRleCArIDEgKyBsaXN0SW5kZXggLSAoYWxsb3dOdWxsID8gMSA6IDApfWApO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGlmIChhbGxvd051bGwpIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChgKCQke2luZGV4fTpuYW1lIElTIE5VTEwgT1IgJCR7aW5kZXh9Om5hbWUgJiYgQVJSQVlbJHtpblBhdHRlcm5zLmpvaW4oKX1dKWApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgJiYgQVJSQVlbJHtpblBhdHRlcm5zLmpvaW4oKX1dYCk7XG4gICAgICB9XG4gICAgICBpbmRleCA9IGluZGV4ICsgMSArIGluUGF0dGVybnMubGVuZ3RoO1xuICAgIH0gZWxzZSBpZiAoaXNJbk9yTmluKSB7XG4gICAgICB2YXIgY3JlYXRlQ29uc3RyYWludCA9IChiYXNlQXJyYXksIG5vdEluKSA9PiB7XG4gICAgICAgIGNvbnN0IG5vdCA9IG5vdEluID8gJyBOT1QgJyA6ICcnO1xuICAgICAgICBpZiAoYmFzZUFycmF5Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBpZiAoaXNBcnJheUZpZWxkKSB7XG4gICAgICAgICAgICBwYXR0ZXJucy5wdXNoKGAke25vdH0gYXJyYXlfY29udGFpbnMoJCR7aW5kZXh9Om5hbWUsICQke2luZGV4ICsgMX0pYCk7XG4gICAgICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIEpTT04uc3RyaW5naWZ5KGJhc2VBcnJheSkpO1xuICAgICAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gSGFuZGxlIE5lc3RlZCBEb3QgTm90YXRpb24gQWJvdmVcbiAgICAgICAgICAgIGlmIChmaWVsZE5hbWUuaW5kZXhPZignLicpID49IDApIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgaW5QYXR0ZXJucyA9IFtdO1xuICAgICAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgICAgIGJhc2VBcnJheS5mb3JFYWNoKChsaXN0RWxlbSwgbGlzdEluZGV4KSA9PiB7XG4gICAgICAgICAgICAgIGlmIChsaXN0RWxlbSAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdmFsdWVzLnB1c2gobGlzdEVsZW0pO1xuICAgICAgICAgICAgICAgIGluUGF0dGVybnMucHVzaChgJCR7aW5kZXggKyAxICsgbGlzdEluZGV4fWApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lICR7bm90fSBJTiAoJHtpblBhdHRlcm5zLmpvaW4oKX0pYCk7XG4gICAgICAgICAgICBpbmRleCA9IGluZGV4ICsgMSArIGluUGF0dGVybnMubGVuZ3RoO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICghbm90SW4pIHtcbiAgICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lIElTIE5VTExgKTtcbiAgICAgICAgICBpbmRleCA9IGluZGV4ICsgMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBIYW5kbGUgZW1wdHkgYXJyYXlcbiAgICAgICAgICBpZiAobm90SW4pIHtcbiAgICAgICAgICAgIHBhdHRlcm5zLnB1c2goJzEgPSAxJyk7IC8vIFJldHVybiBhbGwgdmFsdWVzXG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBhdHRlcm5zLnB1c2goJzEgPSAyJyk7IC8vIFJldHVybiBubyB2YWx1ZXNcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBpZiAoZmllbGRWYWx1ZS4kaW4pIHtcbiAgICAgICAgY3JlYXRlQ29uc3RyYWludChcbiAgICAgICAgICBfLmZsYXRNYXAoZmllbGRWYWx1ZS4kaW4sIGVsdCA9PiBlbHQpLFxuICAgICAgICAgIGZhbHNlXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoZmllbGRWYWx1ZS4kbmluKSB7XG4gICAgICAgIGNyZWF0ZUNvbnN0cmFpbnQoXG4gICAgICAgICAgXy5mbGF0TWFwKGZpZWxkVmFsdWUuJG5pbiwgZWx0ID0+IGVsdCksXG4gICAgICAgICAgdHJ1ZVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGZpZWxkVmFsdWUuJGluICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2JhZCAkaW4gdmFsdWUnKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBmaWVsZFZhbHVlLiRuaW4gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnYmFkICRuaW4gdmFsdWUnKTtcbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShmaWVsZFZhbHVlLiRhbGwpICYmIGlzQXJyYXlGaWVsZCkge1xuICAgICAgaWYgKGlzQW55VmFsdWVSZWdleFN0YXJ0c1dpdGgoZmllbGRWYWx1ZS4kYWxsKSkge1xuICAgICAgICBpZiAoIWlzQWxsVmFsdWVzUmVnZXhPck5vbmUoZmllbGRWYWx1ZS4kYWxsKSkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICdBbGwgJGFsbCB2YWx1ZXMgbXVzdCBiZSBvZiByZWdleCB0eXBlIG9yIG5vbmU6ICcgKyBmaWVsZFZhbHVlLiRhbGxcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmaWVsZFZhbHVlLiRhbGwubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IHByb2Nlc3NSZWdleFBhdHRlcm4oZmllbGRWYWx1ZS4kYWxsW2ldLiRyZWdleCk7XG4gICAgICAgICAgZmllbGRWYWx1ZS4kYWxsW2ldID0gdmFsdWUuc3Vic3RyaW5nKDEpICsgJyUnO1xuICAgICAgICB9XG4gICAgICAgIHBhdHRlcm5zLnB1c2goYGFycmF5X2NvbnRhaW5zX2FsbF9yZWdleCgkJHtpbmRleH06bmFtZSwgJCR7aW5kZXggKyAxfTo6anNvbmIpYCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYXR0ZXJucy5wdXNoKGBhcnJheV9jb250YWluc19hbGwoJCR7aW5kZXh9Om5hbWUsICQke2luZGV4ICsgMX06Ompzb25iKWApO1xuICAgICAgfVxuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBKU09OLnN0cmluZ2lmeShmaWVsZFZhbHVlLiRhbGwpKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGZpZWxkVmFsdWUuJGFsbCkpIHtcbiAgICAgIGlmIChmaWVsZFZhbHVlLiRhbGwubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lID0gJCR7aW5kZXggKyAxfWApO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUuJGFsbFswXS5vYmplY3RJZCk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBmaWVsZFZhbHVlLiRleGlzdHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBpZiAoZmllbGRWYWx1ZS4kZXhpc3RzKSB7XG4gICAgICAgIHBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lIElTIE5PVCBOVUxMYCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSBJUyBOVUxMYCk7XG4gICAgICB9XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgaW5kZXggKz0gMTtcbiAgICB9XG5cbiAgICBpZiAoZmllbGRWYWx1ZS4kY29udGFpbmVkQnkpIHtcbiAgICAgIGNvbnN0IGFyciA9IGZpZWxkVmFsdWUuJGNvbnRhaW5lZEJ5O1xuICAgICAgaWYgKCEoYXJyIGluc3RhbmNlb2YgQXJyYXkpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sIGBiYWQgJGNvbnRhaW5lZEJ5OiBzaG91bGQgYmUgYW4gYXJyYXlgKTtcbiAgICAgIH1cblxuICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPEAgJCR7aW5kZXggKyAxfTo6anNvbmJgKTtcbiAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgSlNPTi5zdHJpbmdpZnkoYXJyKSk7XG4gICAgICBpbmRleCArPSAyO1xuICAgIH1cblxuICAgIGlmIChmaWVsZFZhbHVlLiR0ZXh0KSB7XG4gICAgICBjb25zdCBzZWFyY2ggPSBmaWVsZFZhbHVlLiR0ZXh0LiRzZWFyY2g7XG4gICAgICBsZXQgbGFuZ3VhZ2UgPSAnZW5nbGlzaCc7XG4gICAgICBpZiAodHlwZW9mIHNlYXJjaCAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgYGJhZCAkdGV4dDogJHNlYXJjaCwgc2hvdWxkIGJlIG9iamVjdGApO1xuICAgICAgfVxuICAgICAgaWYgKCFzZWFyY2guJHRlcm0gfHwgdHlwZW9mIHNlYXJjaC4kdGVybSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgYGJhZCAkdGV4dDogJHRlcm0sIHNob3VsZCBiZSBzdHJpbmdgKTtcbiAgICAgIH1cbiAgICAgIGlmIChzZWFyY2guJGxhbmd1YWdlICYmIHR5cGVvZiBzZWFyY2guJGxhbmd1YWdlICE9PSAnc3RyaW5nJykge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCBgYmFkICR0ZXh0OiAkbGFuZ3VhZ2UsIHNob3VsZCBiZSBzdHJpbmdgKTtcbiAgICAgIH0gZWxzZSBpZiAoc2VhcmNoLiRsYW5ndWFnZSkge1xuICAgICAgICBsYW5ndWFnZSA9IHNlYXJjaC4kbGFuZ3VhZ2U7XG4gICAgICB9XG4gICAgICBpZiAoc2VhcmNoLiRjYXNlU2Vuc2l0aXZlICYmIHR5cGVvZiBzZWFyY2guJGNhc2VTZW5zaXRpdmUgIT09ICdib29sZWFuJykge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgIGBiYWQgJHRleHQ6ICRjYXNlU2Vuc2l0aXZlLCBzaG91bGQgYmUgYm9vbGVhbmBcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoc2VhcmNoLiRjYXNlU2Vuc2l0aXZlKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgYGJhZCAkdGV4dDogJGNhc2VTZW5zaXRpdmUgbm90IHN1cHBvcnRlZCwgcGxlYXNlIHVzZSAkcmVnZXggb3IgY3JlYXRlIGEgc2VwYXJhdGUgbG93ZXIgY2FzZSBjb2x1bW4uYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKHNlYXJjaC4kZGlhY3JpdGljU2Vuc2l0aXZlICYmIHR5cGVvZiBzZWFyY2guJGRpYWNyaXRpY1NlbnNpdGl2ZSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgYGJhZCAkdGV4dDogJGRpYWNyaXRpY1NlbnNpdGl2ZSwgc2hvdWxkIGJlIGJvb2xlYW5gXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKHNlYXJjaC4kZGlhY3JpdGljU2Vuc2l0aXZlID09PSBmYWxzZSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgIGBiYWQgJHRleHQ6ICRkaWFjcml0aWNTZW5zaXRpdmUgLSBmYWxzZSBub3Qgc3VwcG9ydGVkLCBpbnN0YWxsIFBvc3RncmVzIFVuYWNjZW50IEV4dGVuc2lvbmBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHBhdHRlcm5zLnB1c2goXG4gICAgICAgIGB0b190c3ZlY3RvcigkJHtpbmRleH0sICQke2luZGV4ICsgMX06bmFtZSkgQEAgdG9fdHNxdWVyeSgkJHtpbmRleCArIDJ9LCAkJHtpbmRleCArIDN9KWBcbiAgICAgICk7XG4gICAgICB2YWx1ZXMucHVzaChsYW5ndWFnZSwgZmllbGROYW1lLCBsYW5ndWFnZSwgc2VhcmNoLiR0ZXJtKTtcbiAgICAgIGluZGV4ICs9IDQ7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuJG5lYXJTcGhlcmUpIHtcbiAgICAgIGNvbnN0IHBvaW50ID0gZmllbGRWYWx1ZS4kbmVhclNwaGVyZTtcbiAgICAgIGNvbnN0IGRpc3RhbmNlID0gZmllbGRWYWx1ZS4kbWF4RGlzdGFuY2U7XG4gICAgICBjb25zdCBkaXN0YW5jZUluS00gPSBkaXN0YW5jZSAqIDYzNzEgKiAxMDAwO1xuICAgICAgcGF0dGVybnMucHVzaChcbiAgICAgICAgYFNUX0Rpc3RhbmNlU3BoZXJlKCQke2luZGV4fTpuYW1lOjpnZW9tZXRyeSwgUE9JTlQoJCR7aW5kZXggKyAxfSwgJCR7XG4gICAgICAgICAgaW5kZXggKyAyXG4gICAgICAgIH0pOjpnZW9tZXRyeSkgPD0gJCR7aW5kZXggKyAzfWBcbiAgICAgICk7XG4gICAgICBzb3J0cy5wdXNoKFxuICAgICAgICBgU1RfRGlzdGFuY2VTcGhlcmUoJCR7aW5kZXh9Om5hbWU6Omdlb21ldHJ5LCBQT0lOVCgkJHtpbmRleCArIDF9LCAkJHtcbiAgICAgICAgICBpbmRleCArIDJcbiAgICAgICAgfSk6Omdlb21ldHJ5KSBBU0NgXG4gICAgICApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBwb2ludC5sb25naXR1ZGUsIHBvaW50LmxhdGl0dWRlLCBkaXN0YW5jZUluS00pO1xuICAgICAgaW5kZXggKz0gNDtcbiAgICB9XG5cbiAgICBpZiAoZmllbGRWYWx1ZS4kd2l0aGluICYmIGZpZWxkVmFsdWUuJHdpdGhpbi4kYm94KSB7XG4gICAgICBjb25zdCBib3ggPSBmaWVsZFZhbHVlLiR3aXRoaW4uJGJveDtcbiAgICAgIGNvbnN0IGxlZnQgPSBib3hbMF0ubG9uZ2l0dWRlO1xuICAgICAgY29uc3QgYm90dG9tID0gYm94WzBdLmxhdGl0dWRlO1xuICAgICAgY29uc3QgcmlnaHQgPSBib3hbMV0ubG9uZ2l0dWRlO1xuICAgICAgY29uc3QgdG9wID0gYm94WzFdLmxhdGl0dWRlO1xuXG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZTo6cG9pbnQgPEAgJCR7aW5kZXggKyAxfTo6Ym94YCk7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGAoKCR7bGVmdH0sICR7Ym90dG9tfSksICgke3JpZ2h0fSwgJHt0b3B9KSlgKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuJGdlb1dpdGhpbiAmJiBmaWVsZFZhbHVlLiRnZW9XaXRoaW4uJGNlbnRlclNwaGVyZSkge1xuICAgICAgY29uc3QgY2VudGVyU3BoZXJlID0gZmllbGRWYWx1ZS4kZ2VvV2l0aGluLiRjZW50ZXJTcGhlcmU7XG4gICAgICBpZiAoIShjZW50ZXJTcGhlcmUgaW5zdGFuY2VvZiBBcnJheSkgfHwgY2VudGVyU3BoZXJlLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7ICRjZW50ZXJTcGhlcmUgc2hvdWxkIGJlIGFuIGFycmF5IG9mIFBhcnNlLkdlb1BvaW50IGFuZCBkaXN0YW5jZSdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIC8vIEdldCBwb2ludCwgY29udmVydCB0byBnZW8gcG9pbnQgaWYgbmVjZXNzYXJ5IGFuZCB2YWxpZGF0ZVxuICAgICAgbGV0IHBvaW50ID0gY2VudGVyU3BoZXJlWzBdO1xuICAgICAgaWYgKHBvaW50IGluc3RhbmNlb2YgQXJyYXkgJiYgcG9pbnQubGVuZ3RoID09PSAyKSB7XG4gICAgICAgIHBvaW50ID0gbmV3IFBhcnNlLkdlb1BvaW50KHBvaW50WzFdLCBwb2ludFswXSk7XG4gICAgICB9IGVsc2UgaWYgKCFHZW9Qb2ludENvZGVyLmlzVmFsaWRKU09OKHBvaW50KSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICdiYWQgJGdlb1dpdGhpbiB2YWx1ZTsgJGNlbnRlclNwaGVyZSBnZW8gcG9pbnQgaW52YWxpZCdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIFBhcnNlLkdlb1BvaW50Ll92YWxpZGF0ZShwb2ludC5sYXRpdHVkZSwgcG9pbnQubG9uZ2l0dWRlKTtcbiAgICAgIC8vIEdldCBkaXN0YW5jZSBhbmQgdmFsaWRhdGVcbiAgICAgIGNvbnN0IGRpc3RhbmNlID0gY2VudGVyU3BoZXJlWzFdO1xuICAgICAgaWYgKGlzTmFOKGRpc3RhbmNlKSB8fCBkaXN0YW5jZSA8IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7ICRjZW50ZXJTcGhlcmUgZGlzdGFuY2UgaW52YWxpZCdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRpc3RhbmNlSW5LTSA9IGRpc3RhbmNlICogNjM3MSAqIDEwMDA7XG4gICAgICBwYXR0ZXJucy5wdXNoKFxuICAgICAgICBgU1RfRGlzdGFuY2VTcGhlcmUoJCR7aW5kZXh9Om5hbWU6Omdlb21ldHJ5LCBQT0lOVCgkJHtpbmRleCArIDF9LCAkJHtcbiAgICAgICAgICBpbmRleCArIDJcbiAgICAgICAgfSk6Omdlb21ldHJ5KSA8PSAkJHtpbmRleCArIDN9YFxuICAgICAgKTtcbiAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgcG9pbnQubG9uZ2l0dWRlLCBwb2ludC5sYXRpdHVkZSwgZGlzdGFuY2VJbktNKTtcbiAgICAgIGluZGV4ICs9IDQ7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuJGdlb1dpdGhpbiAmJiBmaWVsZFZhbHVlLiRnZW9XaXRoaW4uJHBvbHlnb24pIHtcbiAgICAgIGNvbnN0IHBvbHlnb24gPSBmaWVsZFZhbHVlLiRnZW9XaXRoaW4uJHBvbHlnb247XG4gICAgICBsZXQgcG9pbnRzO1xuICAgICAgaWYgKHR5cGVvZiBwb2x5Z29uID09PSAnb2JqZWN0JyAmJiBwb2x5Z29uLl9fdHlwZSA9PT0gJ1BvbHlnb24nKSB7XG4gICAgICAgIGlmICghcG9seWdvbi5jb29yZGluYXRlcyB8fCBwb2x5Z29uLmNvb3JkaW5hdGVzLmxlbmd0aCA8IDMpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7IFBvbHlnb24uY29vcmRpbmF0ZXMgc2hvdWxkIGNvbnRhaW4gYXQgbGVhc3QgMyBsb24vbGF0IHBhaXJzJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcG9pbnRzID0gcG9seWdvbi5jb29yZGluYXRlcztcbiAgICAgIH0gZWxzZSBpZiAocG9seWdvbiBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgIGlmIChwb2x5Z29uLmxlbmd0aCA8IDMpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAnYmFkICRnZW9XaXRoaW4gdmFsdWU7ICRwb2x5Z29uIHNob3VsZCBjb250YWluIGF0IGxlYXN0IDMgR2VvUG9pbnRzJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcG9pbnRzID0gcG9seWdvbjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgXCJiYWQgJGdlb1dpdGhpbiB2YWx1ZTsgJHBvbHlnb24gc2hvdWxkIGJlIFBvbHlnb24gb2JqZWN0IG9yIEFycmF5IG9mIFBhcnNlLkdlb1BvaW50J3NcIlxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcG9pbnRzID0gcG9pbnRzXG4gICAgICAgIC5tYXAocG9pbnQgPT4ge1xuICAgICAgICAgIGlmIChwb2ludCBpbnN0YW5jZW9mIEFycmF5ICYmIHBvaW50Lmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50WzFdLCBwb2ludFswXSk7XG4gICAgICAgICAgICByZXR1cm4gYCgke3BvaW50WzBdfSwgJHtwb2ludFsxXX0pYDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHR5cGVvZiBwb2ludCAhPT0gJ29iamVjdCcgfHwgcG9pbnQuX190eXBlICE9PSAnR2VvUG9pbnQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnYmFkICRnZW9XaXRoaW4gdmFsdWUnKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50LmxhdGl0dWRlLCBwb2ludC5sb25naXR1ZGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gYCgke3BvaW50LmxvbmdpdHVkZX0sICR7cG9pbnQubGF0aXR1ZGV9KWA7XG4gICAgICAgIH0pXG4gICAgICAgIC5qb2luKCcsICcpO1xuXG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZTo6cG9pbnQgPEAgJCR7aW5kZXggKyAxfTo6cG9seWdvbmApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBgKCR7cG9pbnRzfSlgKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuICAgIGlmIChmaWVsZFZhbHVlLiRnZW9JbnRlcnNlY3RzICYmIGZpZWxkVmFsdWUuJGdlb0ludGVyc2VjdHMuJHBvaW50KSB7XG4gICAgICBjb25zdCBwb2ludCA9IGZpZWxkVmFsdWUuJGdlb0ludGVyc2VjdHMuJHBvaW50O1xuICAgICAgaWYgKHR5cGVvZiBwb2ludCAhPT0gJ29iamVjdCcgfHwgcG9pbnQuX190eXBlICE9PSAnR2VvUG9pbnQnKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgJ2JhZCAkZ2VvSW50ZXJzZWN0IHZhbHVlOyAkcG9pbnQgc2hvdWxkIGJlIEdlb1BvaW50J1xuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBvaW50LmxhdGl0dWRlLCBwb2ludC5sb25naXR1ZGUpO1xuICAgICAgfVxuICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWU6OnBvbHlnb24gQD4gJCR7aW5kZXggKyAxfTo6cG9pbnRgKTtcbiAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgYCgke3BvaW50LmxvbmdpdHVkZX0sICR7cG9pbnQubGF0aXR1ZGV9KWApO1xuICAgICAgaW5kZXggKz0gMjtcbiAgICB9XG5cbiAgICBpZiAoZmllbGRWYWx1ZS4kcmVnZXgpIHtcbiAgICAgIGxldCByZWdleCA9IGZpZWxkVmFsdWUuJHJlZ2V4O1xuICAgICAgbGV0IG9wZXJhdG9yID0gJ34nO1xuICAgICAgY29uc3Qgb3B0cyA9IGZpZWxkVmFsdWUuJG9wdGlvbnM7XG4gICAgICBpZiAob3B0cykge1xuICAgICAgICBpZiAob3B0cy5pbmRleE9mKCdpJykgPj0gMCkge1xuICAgICAgICAgIG9wZXJhdG9yID0gJ34qJztcbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0cy5pbmRleE9mKCd4JykgPj0gMCkge1xuICAgICAgICAgIHJlZ2V4ID0gcmVtb3ZlV2hpdGVTcGFjZShyZWdleCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgbmFtZSA9IHRyYW5zZm9ybURvdEZpZWxkKGZpZWxkTmFtZSk7XG4gICAgICByZWdleCA9IHByb2Nlc3NSZWdleFBhdHRlcm4ocmVnZXgpO1xuXG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06cmF3ICR7b3BlcmF0b3J9ICckJHtpbmRleCArIDF9OnJhdydgKTtcbiAgICAgIHZhbHVlcy5wdXNoKG5hbWUsIHJlZ2V4KTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuX190eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgIGlmIChpc0FycmF5RmllbGQpIHtcbiAgICAgICAgcGF0dGVybnMucHVzaChgYXJyYXlfY29udGFpbnMoJCR7aW5kZXh9Om5hbWUsICQke2luZGV4ICsgMX0pYCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgSlNPTi5zdHJpbmdpZnkoW2ZpZWxkVmFsdWVdKSk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlLm9iamVjdElkKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZmllbGRWYWx1ZS5fX3R5cGUgPT09ICdEYXRlJykge1xuICAgICAgcGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUuaXNvKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuXG4gICAgaWYgKGZpZWxkVmFsdWUuX190eXBlID09PSAnR2VvUG9pbnQnKSB7XG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSB+PSBQT0lOVCgkJHtpbmRleCArIDF9LCAkJHtpbmRleCArIDJ9KWApO1xuICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlLmxvbmdpdHVkZSwgZmllbGRWYWx1ZS5sYXRpdHVkZSk7XG4gICAgICBpbmRleCArPSAzO1xuICAgIH1cblxuICAgIGlmIChmaWVsZFZhbHVlLl9fdHlwZSA9PT0gJ1BvbHlnb24nKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGNvbnZlcnRQb2x5Z29uVG9TUUwoZmllbGRWYWx1ZS5jb29yZGluYXRlcyk7XG4gICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSB+PSAkJHtpbmRleCArIDF9Ojpwb2x5Z29uYCk7XG4gICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIHZhbHVlKTtcbiAgICAgIGluZGV4ICs9IDI7XG4gICAgfVxuXG4gICAgT2JqZWN0LmtleXMoUGFyc2VUb1Bvc2dyZXNDb21wYXJhdG9yKS5mb3JFYWNoKGNtcCA9PiB7XG4gICAgICBpZiAoZmllbGRWYWx1ZVtjbXBdIHx8IGZpZWxkVmFsdWVbY21wXSA9PT0gMCkge1xuICAgICAgICBjb25zdCBwZ0NvbXBhcmF0b3IgPSBQYXJzZVRvUG9zZ3Jlc0NvbXBhcmF0b3JbY21wXTtcbiAgICAgICAgY29uc3QgcG9zdGdyZXNWYWx1ZSA9IHRvUG9zdGdyZXNWYWx1ZShmaWVsZFZhbHVlW2NtcF0pO1xuICAgICAgICBsZXQgY29uc3RyYWludEZpZWxkTmFtZTtcbiAgICAgICAgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPj0gMCkge1xuICAgICAgICAgIGxldCBjYXN0VHlwZTtcbiAgICAgICAgICBzd2l0Y2ggKHR5cGVvZiBwb3N0Z3Jlc1ZhbHVlKSB7XG4gICAgICAgICAgICBjYXNlICdudW1iZXInOlxuICAgICAgICAgICAgICBjYXN0VHlwZSA9ICdkb3VibGUgcHJlY2lzaW9uJztcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdib29sZWFuJzpcbiAgICAgICAgICAgICAgY2FzdFR5cGUgPSAnYm9vbGVhbic7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgY2FzdFR5cGUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0cmFpbnRGaWVsZE5hbWUgPSBjYXN0VHlwZVxuICAgICAgICAgICAgPyBgQ0FTVCAoKCR7dHJhbnNmb3JtRG90RmllbGQoZmllbGROYW1lKX0pIEFTICR7Y2FzdFR5cGV9KWBcbiAgICAgICAgICAgIDogdHJhbnNmb3JtRG90RmllbGQoZmllbGROYW1lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdHJhaW50RmllbGROYW1lID0gYCQke2luZGV4Kyt9Om5hbWVgO1xuICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFsdWVzLnB1c2gocG9zdGdyZXNWYWx1ZSk7XG4gICAgICAgIHBhdHRlcm5zLnB1c2goYCR7Y29uc3RyYWludEZpZWxkTmFtZX0gJHtwZ0NvbXBhcmF0b3J9ICQke2luZGV4Kyt9YCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAoaW5pdGlhbFBhdHRlcm5zTGVuZ3RoID09PSBwYXR0ZXJucy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgICAgYFBvc3RncmVzIGRvZXNuJ3Qgc3VwcG9ydCB0aGlzIHF1ZXJ5IHR5cGUgeWV0ICR7SlNPTi5zdHJpbmdpZnkoZmllbGRWYWx1ZSl9YFxuICAgICAgKTtcbiAgICB9XG4gIH1cbiAgdmFsdWVzID0gdmFsdWVzLm1hcCh0cmFuc2Zvcm1WYWx1ZSk7XG4gIHJldHVybiB7IHBhdHRlcm46IHBhdHRlcm5zLmpvaW4oJyBBTkQgJyksIHZhbHVlcywgc29ydHMgfTtcbn07XG5cbmV4cG9ydCBjbGFzcyBQb3N0Z3Jlc1N0b3JhZ2VBZGFwdGVyIGltcGxlbWVudHMgU3RvcmFnZUFkYXB0ZXIge1xuICBjYW5Tb3J0T25Kb2luVGFibGVzOiBib29sZWFuO1xuXG4gIC8vIFByaXZhdGVcbiAgX2NvbGxlY3Rpb25QcmVmaXg6IHN0cmluZztcbiAgX2NsaWVudDogYW55O1xuICBfcGdwOiBhbnk7XG5cbiAgY29uc3RydWN0b3IoeyB1cmksIGNvbGxlY3Rpb25QcmVmaXggPSAnJywgZGF0YWJhc2VPcHRpb25zIH06IGFueSkge1xuICAgIHRoaXMuX2NvbGxlY3Rpb25QcmVmaXggPSBjb2xsZWN0aW9uUHJlZml4O1xuICAgIGNvbnN0IHsgY2xpZW50LCBwZ3AgfSA9IGNyZWF0ZUNsaWVudCh1cmksIGRhdGFiYXNlT3B0aW9ucyk7XG4gICAgdGhpcy5fY2xpZW50ID0gY2xpZW50O1xuICAgIHRoaXMuX3BncCA9IHBncDtcbiAgICB0aGlzLmNhblNvcnRPbkpvaW5UYWJsZXMgPSBmYWxzZTtcbiAgfVxuXG4gIC8vTm90ZSB0aGF0IGFuYWx5emU9dHJ1ZSB3aWxsIHJ1biB0aGUgcXVlcnksIGV4ZWN1dGluZyBJTlNFUlRTLCBERUxFVEVTLCBldGMuXG4gIGNyZWF0ZUV4cGxhaW5hYmxlUXVlcnkocXVlcnk6IHN0cmluZywgYW5hbHl6ZTogYm9vbGVhbiA9IGZhbHNlKSB7XG4gICAgaWYgKGFuYWx5emUpIHtcbiAgICAgIHJldHVybiAnRVhQTEFJTiAoQU5BTFlaRSwgRk9STUFUIEpTT04pICcgKyBxdWVyeTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuICdFWFBMQUlOIChGT1JNQVQgSlNPTikgJyArIHF1ZXJ5O1xuICAgIH1cbiAgfVxuXG4gIGhhbmRsZVNodXRkb3duKCkge1xuICAgIGlmICghdGhpcy5fY2xpZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX2NsaWVudC4kcG9vbC5lbmQoKTtcbiAgfVxuXG4gIGFzeW5jIF9lbnN1cmVTY2hlbWFDb2xsZWN0aW9uRXhpc3RzKGNvbm46IGFueSkge1xuICAgIGNvbm4gPSBjb25uIHx8IHRoaXMuX2NsaWVudDtcbiAgICBhd2FpdCBjb25uXG4gICAgICAubm9uZShcbiAgICAgICAgJ0NSRUFURSBUQUJMRSBJRiBOT1QgRVhJU1RTIFwiX1NDSEVNQVwiICggXCJjbGFzc05hbWVcIiB2YXJDaGFyKDEyMCksIFwic2NoZW1hXCIganNvbmIsIFwiaXNQYXJzZUNsYXNzXCIgYm9vbCwgUFJJTUFSWSBLRVkgKFwiY2xhc3NOYW1lXCIpICknXG4gICAgICApXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZXJyb3IuY29kZSA9PT0gUG9zdGdyZXNEdXBsaWNhdGVSZWxhdGlvbkVycm9yIHx8XG4gICAgICAgICAgZXJyb3IuY29kZSA9PT0gUG9zdGdyZXNVbmlxdWVJbmRleFZpb2xhdGlvbkVycm9yIHx8XG4gICAgICAgICAgZXJyb3IuY29kZSA9PT0gUG9zdGdyZXNEdXBsaWNhdGVPYmplY3RFcnJvclxuICAgICAgICApIHtcbiAgICAgICAgICAvLyBUYWJsZSBhbHJlYWR5IGV4aXN0cywgbXVzdCBoYXZlIGJlZW4gY3JlYXRlZCBieSBhIGRpZmZlcmVudCByZXF1ZXN0LiBJZ25vcmUgZXJyb3IuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgY2xhc3NFeGlzdHMobmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudC5vbmUoXG4gICAgICAnU0VMRUNUIEVYSVNUUyAoU0VMRUNUIDEgRlJPTSBpbmZvcm1hdGlvbl9zY2hlbWEudGFibGVzIFdIRVJFIHRhYmxlX25hbWUgPSAkMSknLFxuICAgICAgW25hbWVdLFxuICAgICAgYSA9PiBhLmV4aXN0c1xuICAgICk7XG4gIH1cblxuICBhc3luYyBzZXRDbGFzc0xldmVsUGVybWlzc2lvbnMoY2xhc3NOYW1lOiBzdHJpbmcsIENMUHM6IGFueSkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGF3YWl0IHRoaXMuX2NsaWVudC50YXNrKCdzZXQtY2xhc3MtbGV2ZWwtcGVybWlzc2lvbnMnLCBhc3luYyB0ID0+IHtcbiAgICAgIGF3YWl0IHNlbGYuX2Vuc3VyZVNjaGVtYUNvbGxlY3Rpb25FeGlzdHModCk7XG4gICAgICBjb25zdCB2YWx1ZXMgPSBbY2xhc3NOYW1lLCAnc2NoZW1hJywgJ2NsYXNzTGV2ZWxQZXJtaXNzaW9ucycsIEpTT04uc3RyaW5naWZ5KENMUHMpXTtcbiAgICAgIGF3YWl0IHQubm9uZShcbiAgICAgICAgYFVQREFURSBcIl9TQ0hFTUFcIiBTRVQgJDI6bmFtZSA9IGpzb25fb2JqZWN0X3NldF9rZXkoJDI6bmFtZSwgJDM6OnRleHQsICQ0Ojpqc29uYikgV0hFUkUgXCJjbGFzc05hbWVcIiA9ICQxYCxcbiAgICAgICAgdmFsdWVzXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgc2V0SW5kZXhlc1dpdGhTY2hlbWFGb3JtYXQoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc3VibWl0dGVkSW5kZXhlczogYW55LFxuICAgIGV4aXN0aW5nSW5kZXhlczogYW55ID0ge30sXG4gICAgZmllbGRzOiBhbnksXG4gICAgY29ubjogP2FueVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25uID0gY29ubiB8fCB0aGlzLl9jbGllbnQ7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgaWYgKHN1Ym1pdHRlZEluZGV4ZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICBpZiAoT2JqZWN0LmtleXMoZXhpc3RpbmdJbmRleGVzKS5sZW5ndGggPT09IDApIHtcbiAgICAgIGV4aXN0aW5nSW5kZXhlcyA9IHsgX2lkXzogeyBfaWQ6IDEgfSB9O1xuICAgIH1cbiAgICBjb25zdCBkZWxldGVkSW5kZXhlcyA9IFtdO1xuICAgIGNvbnN0IGluc2VydGVkSW5kZXhlcyA9IFtdO1xuICAgIE9iamVjdC5rZXlzKHN1Ym1pdHRlZEluZGV4ZXMpLmZvckVhY2gobmFtZSA9PiB7XG4gICAgICBjb25zdCBmaWVsZCA9IHN1Ym1pdHRlZEluZGV4ZXNbbmFtZV07XG4gICAgICBpZiAoZXhpc3RpbmdJbmRleGVzW25hbWVdICYmIGZpZWxkLl9fb3AgIT09ICdEZWxldGUnKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCBgSW5kZXggJHtuYW1lfSBleGlzdHMsIGNhbm5vdCB1cGRhdGUuYCk7XG4gICAgICB9XG4gICAgICBpZiAoIWV4aXN0aW5nSW5kZXhlc1tuYW1lXSAmJiBmaWVsZC5fX29wID09PSAnRGVsZXRlJykge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSxcbiAgICAgICAgICBgSW5kZXggJHtuYW1lfSBkb2VzIG5vdCBleGlzdCwgY2Fubm90IGRlbGV0ZS5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoZmllbGQuX19vcCA9PT0gJ0RlbGV0ZScpIHtcbiAgICAgICAgZGVsZXRlZEluZGV4ZXMucHVzaChuYW1lKTtcbiAgICAgICAgZGVsZXRlIGV4aXN0aW5nSW5kZXhlc1tuYW1lXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIE9iamVjdC5rZXlzKGZpZWxkKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZmllbGRzLCBrZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksXG4gICAgICAgICAgICAgIGBGaWVsZCAke2tleX0gZG9lcyBub3QgZXhpc3QsIGNhbm5vdCBhZGQgaW5kZXguYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBleGlzdGluZ0luZGV4ZXNbbmFtZV0gPSBmaWVsZDtcbiAgICAgICAgaW5zZXJ0ZWRJbmRleGVzLnB1c2goe1xuICAgICAgICAgIGtleTogZmllbGQsXG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgYXdhaXQgY29ubi50eCgnc2V0LWluZGV4ZXMtd2l0aC1zY2hlbWEtZm9ybWF0JywgYXN5bmMgdCA9PiB7XG4gICAgICBpZiAoaW5zZXJ0ZWRJbmRleGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgYXdhaXQgc2VsZi5jcmVhdGVJbmRleGVzKGNsYXNzTmFtZSwgaW5zZXJ0ZWRJbmRleGVzLCB0KTtcbiAgICAgIH1cbiAgICAgIGlmIChkZWxldGVkSW5kZXhlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGF3YWl0IHNlbGYuZHJvcEluZGV4ZXMoY2xhc3NOYW1lLCBkZWxldGVkSW5kZXhlcywgdCk7XG4gICAgICB9XG4gICAgICBhd2FpdCBzZWxmLl9lbnN1cmVTY2hlbWFDb2xsZWN0aW9uRXhpc3RzKHQpO1xuICAgICAgYXdhaXQgdC5ub25lKFxuICAgICAgICAnVVBEQVRFIFwiX1NDSEVNQVwiIFNFVCAkMjpuYW1lID0ganNvbl9vYmplY3Rfc2V0X2tleSgkMjpuYW1lLCAkMzo6dGV4dCwgJDQ6Ompzb25iKSBXSEVSRSBcImNsYXNzTmFtZVwiID0gJDEnLFxuICAgICAgICBbY2xhc3NOYW1lLCAnc2NoZW1hJywgJ2luZGV4ZXMnLCBKU09OLnN0cmluZ2lmeShleGlzdGluZ0luZGV4ZXMpXVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZUNsYXNzKGNsYXNzTmFtZTogc3RyaW5nLCBzY2hlbWE6IFNjaGVtYVR5cGUsIGNvbm46ID9hbnkpIHtcbiAgICBjb25uID0gY29ubiB8fCB0aGlzLl9jbGllbnQ7XG4gICAgcmV0dXJuIGNvbm5cbiAgICAgIC50eCgnY3JlYXRlLWNsYXNzJywgYXN5bmMgdCA9PiB7XG4gICAgICAgIGF3YWl0IHRoaXMuY3JlYXRlVGFibGUoY2xhc3NOYW1lLCBzY2hlbWEsIHQpO1xuICAgICAgICBhd2FpdCB0Lm5vbmUoXG4gICAgICAgICAgJ0lOU0VSVCBJTlRPIFwiX1NDSEVNQVwiIChcImNsYXNzTmFtZVwiLCBcInNjaGVtYVwiLCBcImlzUGFyc2VDbGFzc1wiKSBWQUxVRVMgKCQ8Y2xhc3NOYW1lPiwgJDxzY2hlbWE+LCB0cnVlKScsXG4gICAgICAgICAgeyBjbGFzc05hbWUsIHNjaGVtYSB9XG4gICAgICAgICk7XG4gICAgICAgIGF3YWl0IHRoaXMuc2V0SW5kZXhlc1dpdGhTY2hlbWFGb3JtYXQoY2xhc3NOYW1lLCBzY2hlbWEuaW5kZXhlcywge30sIHNjaGVtYS5maWVsZHMsIHQpO1xuICAgICAgICByZXR1cm4gdG9QYXJzZVNjaGVtYShzY2hlbWEpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4ge1xuICAgICAgICBpZiAoZXJyLmNvZGUgPT09IFBvc3RncmVzVW5pcXVlSW5kZXhWaW9sYXRpb25FcnJvciAmJiBlcnIuZGV0YWlsLmluY2x1ZGVzKGNsYXNzTmFtZSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFLCBgQ2xhc3MgJHtjbGFzc05hbWV9IGFscmVhZHkgZXhpc3RzLmApO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gSnVzdCBjcmVhdGUgYSB0YWJsZSwgZG8gbm90IGluc2VydCBpbiBzY2hlbWFcbiAgYXN5bmMgY3JlYXRlVGFibGUoY2xhc3NOYW1lOiBzdHJpbmcsIHNjaGVtYTogU2NoZW1hVHlwZSwgY29ubjogYW55KSB7XG4gICAgY29ubiA9IGNvbm4gfHwgdGhpcy5fY2xpZW50O1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGRlYnVnKCdjcmVhdGVUYWJsZScsIGNsYXNzTmFtZSwgc2NoZW1hKTtcbiAgICBjb25zdCB2YWx1ZXNBcnJheSA9IFtdO1xuICAgIGNvbnN0IHBhdHRlcm5zQXJyYXkgPSBbXTtcbiAgICBjb25zdCBmaWVsZHMgPSBPYmplY3QuYXNzaWduKHt9LCBzY2hlbWEuZmllbGRzKTtcbiAgICBpZiAoY2xhc3NOYW1lID09PSAnX1VzZXInKSB7XG4gICAgICBmaWVsZHMuX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0ID0geyB0eXBlOiAnRGF0ZScgfTtcbiAgICAgIGZpZWxkcy5fZW1haWxfdmVyaWZ5X3Rva2VuID0geyB0eXBlOiAnU3RyaW5nJyB9O1xuICAgICAgZmllbGRzLl9hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCA9IHsgdHlwZTogJ0RhdGUnIH07XG4gICAgICBmaWVsZHMuX2ZhaWxlZF9sb2dpbl9jb3VudCA9IHsgdHlwZTogJ051bWJlcicgfTtcbiAgICAgIGZpZWxkcy5fcGVyaXNoYWJsZV90b2tlbiA9IHsgdHlwZTogJ1N0cmluZycgfTtcbiAgICAgIGZpZWxkcy5fcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0ID0geyB0eXBlOiAnRGF0ZScgfTtcbiAgICAgIGZpZWxkcy5fcGFzc3dvcmRfY2hhbmdlZF9hdCA9IHsgdHlwZTogJ0RhdGUnIH07XG4gICAgICBmaWVsZHMuX3Bhc3N3b3JkX2hpc3RvcnkgPSB7IHR5cGU6ICdBcnJheScgfTtcbiAgICB9XG4gICAgbGV0IGluZGV4ID0gMjtcbiAgICBjb25zdCByZWxhdGlvbnMgPSBbXTtcbiAgICBPYmplY3Qua2V5cyhmaWVsZHMpLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgIGNvbnN0IHBhcnNlVHlwZSA9IGZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgLy8gU2tpcCB3aGVuIGl0J3MgYSByZWxhdGlvblxuICAgICAgLy8gV2UnbGwgY3JlYXRlIHRoZSB0YWJsZXMgbGF0ZXJcbiAgICAgIGlmIChwYXJzZVR5cGUudHlwZSA9PT0gJ1JlbGF0aW9uJykge1xuICAgICAgICByZWxhdGlvbnMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoWydfcnBlcm0nLCAnX3dwZXJtJ10uaW5kZXhPZihmaWVsZE5hbWUpID49IDApIHtcbiAgICAgICAgcGFyc2VUeXBlLmNvbnRlbnRzID0geyB0eXBlOiAnU3RyaW5nJyB9O1xuICAgICAgfVxuICAgICAgdmFsdWVzQXJyYXkucHVzaChmaWVsZE5hbWUpO1xuICAgICAgdmFsdWVzQXJyYXkucHVzaChwYXJzZVR5cGVUb1Bvc3RncmVzVHlwZShwYXJzZVR5cGUpKTtcbiAgICAgIHBhdHRlcm5zQXJyYXkucHVzaChgJCR7aW5kZXh9Om5hbWUgJCR7aW5kZXggKyAxfTpyYXdgKTtcbiAgICAgIGlmIChmaWVsZE5hbWUgPT09ICdvYmplY3RJZCcpIHtcbiAgICAgICAgcGF0dGVybnNBcnJheS5wdXNoKGBQUklNQVJZIEtFWSAoJCR7aW5kZXh9Om5hbWUpYCk7XG4gICAgICB9XG4gICAgICBpbmRleCA9IGluZGV4ICsgMjtcbiAgICB9KTtcbiAgICBjb25zdCBxcyA9IGBDUkVBVEUgVEFCTEUgSUYgTk9UIEVYSVNUUyAkMTpuYW1lICgke3BhdHRlcm5zQXJyYXkuam9pbigpfSlgO1xuICAgIGNvbnN0IHZhbHVlcyA9IFtjbGFzc05hbWUsIC4uLnZhbHVlc0FycmF5XTtcblxuICAgIGRlYnVnKHFzLCB2YWx1ZXMpO1xuICAgIHJldHVybiBjb25uLnRhc2soJ2NyZWF0ZS10YWJsZScsIGFzeW5jIHQgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgc2VsZi5fZW5zdXJlU2NoZW1hQ29sbGVjdGlvbkV4aXN0cyh0KTtcbiAgICAgICAgYXdhaXQgdC5ub25lKHFzLCB2YWx1ZXMpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgIT09IFBvc3RncmVzRHVwbGljYXRlUmVsYXRpb25FcnJvcikge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIC8vIEVMU0U6IFRhYmxlIGFscmVhZHkgZXhpc3RzLCBtdXN0IGhhdmUgYmVlbiBjcmVhdGVkIGJ5IGEgZGlmZmVyZW50IHJlcXVlc3QuIElnbm9yZSB0aGUgZXJyb3IuXG4gICAgICB9XG4gICAgICBhd2FpdCB0LnR4KCdjcmVhdGUtdGFibGUtdHgnLCB0eCA9PiB7XG4gICAgICAgIHJldHVybiB0eC5iYXRjaChcbiAgICAgICAgICByZWxhdGlvbnMubWFwKGZpZWxkTmFtZSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdHgubm9uZShcbiAgICAgICAgICAgICAgJ0NSRUFURSBUQUJMRSBJRiBOT1QgRVhJU1RTICQ8am9pblRhYmxlOm5hbWU+IChcInJlbGF0ZWRJZFwiIHZhckNoYXIoMTIwKSwgXCJvd25pbmdJZFwiIHZhckNoYXIoMTIwKSwgUFJJTUFSWSBLRVkoXCJyZWxhdGVkSWRcIiwgXCJvd25pbmdJZFwiKSApJyxcbiAgICAgICAgICAgICAgeyBqb2luVGFibGU6IGBfSm9pbjoke2ZpZWxkTmFtZX06JHtjbGFzc05hbWV9YCB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHNjaGVtYVVwZ3JhZGUoY2xhc3NOYW1lOiBzdHJpbmcsIHNjaGVtYTogU2NoZW1hVHlwZSwgY29ubjogYW55KSB7XG4gICAgZGVidWcoJ3NjaGVtYVVwZ3JhZGUnLCB7IGNsYXNzTmFtZSwgc2NoZW1hIH0pO1xuICAgIGNvbm4gPSBjb25uIHx8IHRoaXMuX2NsaWVudDtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcblxuICAgIGF3YWl0IGNvbm4udHgoJ3NjaGVtYS11cGdyYWRlJywgYXN5bmMgdCA9PiB7XG4gICAgICBjb25zdCBjb2x1bW5zID0gYXdhaXQgdC5tYXAoXG4gICAgICAgICdTRUxFQ1QgY29sdW1uX25hbWUgRlJPTSBpbmZvcm1hdGlvbl9zY2hlbWEuY29sdW1ucyBXSEVSRSB0YWJsZV9uYW1lID0gJDxjbGFzc05hbWU+JyxcbiAgICAgICAgeyBjbGFzc05hbWUgfSxcbiAgICAgICAgYSA9PiBhLmNvbHVtbl9uYW1lXG4gICAgICApO1xuICAgICAgY29uc3QgbmV3Q29sdW1ucyA9IE9iamVjdC5rZXlzKHNjaGVtYS5maWVsZHMpXG4gICAgICAgIC5maWx0ZXIoaXRlbSA9PiBjb2x1bW5zLmluZGV4T2YoaXRlbSkgPT09IC0xKVxuICAgICAgICAubWFwKGZpZWxkTmFtZSA9PlxuICAgICAgICAgIHNlbGYuYWRkRmllbGRJZk5vdEV4aXN0cyhjbGFzc05hbWUsIGZpZWxkTmFtZSwgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLCB0KVxuICAgICAgICApO1xuXG4gICAgICBhd2FpdCB0LmJhdGNoKG5ld0NvbHVtbnMpO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgYWRkRmllbGRJZk5vdEV4aXN0cyhjbGFzc05hbWU6IHN0cmluZywgZmllbGROYW1lOiBzdHJpbmcsIHR5cGU6IGFueSwgY29ubjogYW55KSB7XG4gICAgLy8gVE9ETzogTXVzdCBiZSByZXZpc2VkIGZvciBpbnZhbGlkIGxvZ2ljLi4uXG4gICAgZGVidWcoJ2FkZEZpZWxkSWZOb3RFeGlzdHMnLCB7IGNsYXNzTmFtZSwgZmllbGROYW1lLCB0eXBlIH0pO1xuICAgIGNvbm4gPSBjb25uIHx8IHRoaXMuX2NsaWVudDtcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBhd2FpdCBjb25uLnR4KCdhZGQtZmllbGQtaWYtbm90LWV4aXN0cycsIGFzeW5jIHQgPT4ge1xuICAgICAgaWYgKHR5cGUudHlwZSAhPT0gJ1JlbGF0aW9uJykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IHQubm9uZShcbiAgICAgICAgICAgICdBTFRFUiBUQUJMRSAkPGNsYXNzTmFtZTpuYW1lPiBBREQgQ09MVU1OIElGIE5PVCBFWElTVFMgJDxmaWVsZE5hbWU6bmFtZT4gJDxwb3N0Z3Jlc1R5cGU6cmF3PicsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgZmllbGROYW1lLFxuICAgICAgICAgICAgICBwb3N0Z3Jlc1R5cGU6IHBhcnNlVHlwZVRvUG9zdGdyZXNUeXBlKHR5cGUpLFxuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IFBvc3RncmVzUmVsYXRpb25Eb2VzTm90RXhpc3RFcnJvcikge1xuICAgICAgICAgICAgcmV0dXJuIHNlbGYuY3JlYXRlQ2xhc3MoY2xhc3NOYW1lLCB7IGZpZWxkczogeyBbZmllbGROYW1lXTogdHlwZSB9IH0sIHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZXJyb3IuY29kZSAhPT0gUG9zdGdyZXNEdXBsaWNhdGVDb2x1bW5FcnJvcikge1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIENvbHVtbiBhbHJlYWR5IGV4aXN0cywgY3JlYXRlZCBieSBvdGhlciByZXF1ZXN0LiBDYXJyeSBvbiB0byBzZWUgaWYgaXQncyB0aGUgcmlnaHQgdHlwZS5cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXdhaXQgdC5ub25lKFxuICAgICAgICAgICdDUkVBVEUgVEFCTEUgSUYgTk9UIEVYSVNUUyAkPGpvaW5UYWJsZTpuYW1lPiAoXCJyZWxhdGVkSWRcIiB2YXJDaGFyKDEyMCksIFwib3duaW5nSWRcIiB2YXJDaGFyKDEyMCksIFBSSU1BUlkgS0VZKFwicmVsYXRlZElkXCIsIFwib3duaW5nSWRcIikgKScsXG4gICAgICAgICAgeyBqb2luVGFibGU6IGBfSm9pbjoke2ZpZWxkTmFtZX06JHtjbGFzc05hbWV9YCB9XG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHQuYW55KFxuICAgICAgICAnU0VMRUNUIFwic2NoZW1hXCIgRlJPTSBcIl9TQ0hFTUFcIiBXSEVSRSBcImNsYXNzTmFtZVwiID0gJDxjbGFzc05hbWU+IGFuZCAoXCJzY2hlbWFcIjo6anNvbi0+XFwnZmllbGRzXFwnLT4kPGZpZWxkTmFtZT4pIGlzIG5vdCBudWxsJyxcbiAgICAgICAgeyBjbGFzc05hbWUsIGZpZWxkTmFtZSB9XG4gICAgICApO1xuXG4gICAgICBpZiAocmVzdWx0WzBdKSB7XG4gICAgICAgIHRocm93ICdBdHRlbXB0ZWQgdG8gYWRkIGEgZmllbGQgdGhhdCBhbHJlYWR5IGV4aXN0cyc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBwYXRoID0gYHtmaWVsZHMsJHtmaWVsZE5hbWV9fWA7XG4gICAgICAgIGF3YWl0IHQubm9uZShcbiAgICAgICAgICAnVVBEQVRFIFwiX1NDSEVNQVwiIFNFVCBcInNjaGVtYVwiPWpzb25iX3NldChcInNjaGVtYVwiLCAkPHBhdGg+LCAkPHR5cGU+KSAgV0hFUkUgXCJjbGFzc05hbWVcIj0kPGNsYXNzTmFtZT4nLFxuICAgICAgICAgIHsgcGF0aCwgdHlwZSwgY2xhc3NOYW1lIH1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIERyb3BzIGEgY29sbGVjdGlvbi4gUmVzb2x2ZXMgd2l0aCB0cnVlIGlmIGl0IHdhcyBhIFBhcnNlIFNjaGVtYSAoZWcuIF9Vc2VyLCBDdXN0b20sIGV0Yy4pXG4gIC8vIGFuZCByZXNvbHZlcyB3aXRoIGZhbHNlIGlmIGl0IHdhc24ndCAoZWcuIGEgam9pbiB0YWJsZSkuIFJlamVjdHMgaWYgZGVsZXRpb24gd2FzIGltcG9zc2libGUuXG4gIGFzeW5jIGRlbGV0ZUNsYXNzKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3Qgb3BlcmF0aW9ucyA9IFtcbiAgICAgIHsgcXVlcnk6IGBEUk9QIFRBQkxFIElGIEVYSVNUUyAkMTpuYW1lYCwgdmFsdWVzOiBbY2xhc3NOYW1lXSB9LFxuICAgICAge1xuICAgICAgICBxdWVyeTogYERFTEVURSBGUk9NIFwiX1NDSEVNQVwiIFdIRVJFIFwiY2xhc3NOYW1lXCIgPSAkMWAsXG4gICAgICAgIHZhbHVlczogW2NsYXNzTmFtZV0sXG4gICAgICB9LFxuICAgIF07XG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudFxuICAgICAgLnR4KHQgPT4gdC5ub25lKHRoaXMuX3BncC5oZWxwZXJzLmNvbmNhdChvcGVyYXRpb25zKSkpXG4gICAgICAudGhlbigoKSA9PiBjbGFzc05hbWUuaW5kZXhPZignX0pvaW46JykgIT0gMCk7IC8vIHJlc29sdmVzIHdpdGggZmFsc2Ugd2hlbiBfSm9pbiB0YWJsZVxuICB9XG5cbiAgLy8gRGVsZXRlIGFsbCBkYXRhIGtub3duIHRvIHRoaXMgYWRhcHRlci4gVXNlZCBmb3IgdGVzdGluZy5cbiAgYXN5bmMgZGVsZXRlQWxsQ2xhc3NlcygpIHtcbiAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICBjb25zdCBoZWxwZXJzID0gdGhpcy5fcGdwLmhlbHBlcnM7XG4gICAgZGVidWcoJ2RlbGV0ZUFsbENsYXNzZXMnKTtcblxuICAgIGF3YWl0IHRoaXMuX2NsaWVudFxuICAgICAgLnRhc2soJ2RlbGV0ZS1hbGwtY2xhc3NlcycsIGFzeW5jIHQgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0LmFueSgnU0VMRUNUICogRlJPTSBcIl9TQ0hFTUFcIicpO1xuICAgICAgICAgIGNvbnN0IGpvaW5zID0gcmVzdWx0cy5yZWR1Y2UoKGxpc3Q6IEFycmF5PHN0cmluZz4sIHNjaGVtYTogYW55KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gbGlzdC5jb25jYXQoam9pblRhYmxlc0ZvclNjaGVtYShzY2hlbWEuc2NoZW1hKSk7XG4gICAgICAgICAgfSwgW10pO1xuICAgICAgICAgIGNvbnN0IGNsYXNzZXMgPSBbXG4gICAgICAgICAgICAnX1NDSEVNQScsXG4gICAgICAgICAgICAnX1B1c2hTdGF0dXMnLFxuICAgICAgICAgICAgJ19Kb2JTdGF0dXMnLFxuICAgICAgICAgICAgJ19Kb2JTY2hlZHVsZScsXG4gICAgICAgICAgICAnX0hvb2tzJyxcbiAgICAgICAgICAgICdfR2xvYmFsQ29uZmlnJyxcbiAgICAgICAgICAgICdfR3JhcGhRTENvbmZpZycsXG4gICAgICAgICAgICAnX0F1ZGllbmNlJyxcbiAgICAgICAgICAgICdfSWRlbXBvdGVuY3knLFxuICAgICAgICAgICAgLi4ucmVzdWx0cy5tYXAocmVzdWx0ID0+IHJlc3VsdC5jbGFzc05hbWUpLFxuICAgICAgICAgICAgLi4uam9pbnMsXG4gICAgICAgICAgXTtcbiAgICAgICAgICBjb25zdCBxdWVyaWVzID0gY2xhc3Nlcy5tYXAoY2xhc3NOYW1lID0+ICh7XG4gICAgICAgICAgICBxdWVyeTogJ0RST1AgVEFCTEUgSUYgRVhJU1RTICQ8Y2xhc3NOYW1lOm5hbWU+JyxcbiAgICAgICAgICAgIHZhbHVlczogeyBjbGFzc05hbWUgfSxcbiAgICAgICAgICB9KSk7XG4gICAgICAgICAgYXdhaXQgdC50eCh0eCA9PiB0eC5ub25lKGhlbHBlcnMuY29uY2F0KHF1ZXJpZXMpKSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgaWYgKGVycm9yLmNvZGUgIT09IFBvc3RncmVzUmVsYXRpb25Eb2VzTm90RXhpc3RFcnJvcikge1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIE5vIF9TQ0hFTUEgY29sbGVjdGlvbi4gRG9uJ3QgZGVsZXRlIGFueXRoaW5nLlxuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBkZWJ1ZyhgZGVsZXRlQWxsQ2xhc3NlcyBkb25lIGluICR7bmV3IERhdGUoKS5nZXRUaW1lKCkgLSBub3d9YCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8vIFJlbW92ZSB0aGUgY29sdW1uIGFuZCBhbGwgdGhlIGRhdGEuIEZvciBSZWxhdGlvbnMsIHRoZSBfSm9pbiBjb2xsZWN0aW9uIGlzIGhhbmRsZWRcbiAgLy8gc3BlY2lhbGx5LCB0aGlzIGZ1bmN0aW9uIGRvZXMgbm90IGRlbGV0ZSBfSm9pbiBjb2x1bW5zLiBJdCBzaG91bGQsIGhvd2V2ZXIsIGluZGljYXRlXG4gIC8vIHRoYXQgdGhlIHJlbGF0aW9uIGZpZWxkcyBkb2VzIG5vdCBleGlzdCBhbnltb3JlLiBJbiBtb25nbywgdGhpcyBtZWFucyByZW1vdmluZyBpdCBmcm9tXG4gIC8vIHRoZSBfU0NIRU1BIGNvbGxlY3Rpb24uICBUaGVyZSBzaG91bGQgYmUgbm8gYWN0dWFsIGRhdGEgaW4gdGhlIGNvbGxlY3Rpb24gdW5kZXIgdGhlIHNhbWUgbmFtZVxuICAvLyBhcyB0aGUgcmVsYXRpb24gY29sdW1uLCBzbyBpdCdzIGZpbmUgdG8gYXR0ZW1wdCB0byBkZWxldGUgaXQuIElmIHRoZSBmaWVsZHMgbGlzdGVkIHRvIGJlXG4gIC8vIGRlbGV0ZWQgZG8gbm90IGV4aXN0LCB0aGlzIGZ1bmN0aW9uIHNob3VsZCByZXR1cm4gc3VjY2Vzc2Z1bGx5IGFueXdheXMuIENoZWNraW5nIGZvclxuICAvLyBhdHRlbXB0cyB0byBkZWxldGUgbm9uLWV4aXN0ZW50IGZpZWxkcyBpcyB0aGUgcmVzcG9uc2liaWxpdHkgb2YgUGFyc2UgU2VydmVyLlxuXG4gIC8vIFRoaXMgZnVuY3Rpb24gaXMgbm90IG9ibGlnYXRlZCB0byBkZWxldGUgZmllbGRzIGF0b21pY2FsbHkuIEl0IGlzIGdpdmVuIHRoZSBmaWVsZFxuICAvLyBuYW1lcyBpbiBhIGxpc3Qgc28gdGhhdCBkYXRhYmFzZXMgdGhhdCBhcmUgY2FwYWJsZSBvZiBkZWxldGluZyBmaWVsZHMgYXRvbWljYWxseVxuICAvLyBtYXkgZG8gc28uXG5cbiAgLy8gUmV0dXJucyBhIFByb21pc2UuXG4gIGFzeW5jIGRlbGV0ZUZpZWxkcyhjbGFzc05hbWU6IHN0cmluZywgc2NoZW1hOiBTY2hlbWFUeXBlLCBmaWVsZE5hbWVzOiBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGRlYnVnKCdkZWxldGVGaWVsZHMnLCBjbGFzc05hbWUsIGZpZWxkTmFtZXMpO1xuICAgIGZpZWxkTmFtZXMgPSBmaWVsZE5hbWVzLnJlZHVjZSgobGlzdDogQXJyYXk8c3RyaW5nPiwgZmllbGROYW1lOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IGZpZWxkID0gc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgaWYgKGZpZWxkLnR5cGUgIT09ICdSZWxhdGlvbicpIHtcbiAgICAgICAgbGlzdC5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICB9XG4gICAgICBkZWxldGUgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgcmV0dXJuIGxpc3Q7XG4gICAgfSwgW10pO1xuXG4gICAgY29uc3QgdmFsdWVzID0gW2NsYXNzTmFtZSwgLi4uZmllbGROYW1lc107XG4gICAgY29uc3QgY29sdW1ucyA9IGZpZWxkTmFtZXNcbiAgICAgIC5tYXAoKG5hbWUsIGlkeCkgPT4ge1xuICAgICAgICByZXR1cm4gYCQke2lkeCArIDJ9Om5hbWVgO1xuICAgICAgfSlcbiAgICAgIC5qb2luKCcsIERST1AgQ09MVU1OJyk7XG5cbiAgICBhd2FpdCB0aGlzLl9jbGllbnQudHgoJ2RlbGV0ZS1maWVsZHMnLCBhc3luYyB0ID0+IHtcbiAgICAgIGF3YWl0IHQubm9uZSgnVVBEQVRFIFwiX1NDSEVNQVwiIFNFVCBcInNjaGVtYVwiID0gJDxzY2hlbWE+IFdIRVJFIFwiY2xhc3NOYW1lXCIgPSAkPGNsYXNzTmFtZT4nLCB7XG4gICAgICAgIHNjaGVtYSxcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgfSk7XG4gICAgICBpZiAodmFsdWVzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgYXdhaXQgdC5ub25lKGBBTFRFUiBUQUJMRSAkMTpuYW1lIERST1AgQ09MVU1OIElGIEVYSVNUUyAke2NvbHVtbnN9YCwgdmFsdWVzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIFJldHVybiBhIHByb21pc2UgZm9yIGFsbCBzY2hlbWFzIGtub3duIHRvIHRoaXMgYWRhcHRlciwgaW4gUGFyc2UgZm9ybWF0LiBJbiBjYXNlIHRoZVxuICAvLyBzY2hlbWFzIGNhbm5vdCBiZSByZXRyaWV2ZWQsIHJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVqZWN0cy4gUmVxdWlyZW1lbnRzIGZvciB0aGVcbiAgLy8gcmVqZWN0aW9uIHJlYXNvbiBhcmUgVEJELlxuICBhc3luYyBnZXRBbGxDbGFzc2VzKCkge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIHJldHVybiB0aGlzLl9jbGllbnQudGFzaygnZ2V0LWFsbC1jbGFzc2VzJywgYXN5bmMgdCA9PiB7XG4gICAgICBhd2FpdCBzZWxmLl9lbnN1cmVTY2hlbWFDb2xsZWN0aW9uRXhpc3RzKHQpO1xuICAgICAgcmV0dXJuIGF3YWl0IHQubWFwKCdTRUxFQ1QgKiBGUk9NIFwiX1NDSEVNQVwiJywgbnVsbCwgcm93ID0+XG4gICAgICAgIHRvUGFyc2VTY2hlbWEoeyBjbGFzc05hbWU6IHJvdy5jbGFzc05hbWUsIC4uLnJvdy5zY2hlbWEgfSlcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBSZXR1cm4gYSBwcm9taXNlIGZvciB0aGUgc2NoZW1hIHdpdGggdGhlIGdpdmVuIG5hbWUsIGluIFBhcnNlIGZvcm1hdC4gSWZcbiAgLy8gdGhpcyBhZGFwdGVyIGRvZXNuJ3Qga25vdyBhYm91dCB0aGUgc2NoZW1hLCByZXR1cm4gYSBwcm9taXNlIHRoYXQgcmVqZWN0cyB3aXRoXG4gIC8vIHVuZGVmaW5lZCBhcyB0aGUgcmVhc29uLlxuICBhc3luYyBnZXRDbGFzcyhjbGFzc05hbWU6IHN0cmluZykge1xuICAgIGRlYnVnKCdnZXRDbGFzcycsIGNsYXNzTmFtZSk7XG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudFxuICAgICAgLmFueSgnU0VMRUNUICogRlJPTSBcIl9TQ0hFTUFcIiBXSEVSRSBcImNsYXNzTmFtZVwiID0gJDxjbGFzc05hbWU+Jywge1xuICAgICAgICBjbGFzc05hbWUsXG4gICAgICB9KVxuICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdC5sZW5ndGggIT09IDEpIHtcbiAgICAgICAgICB0aHJvdyB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdFswXS5zY2hlbWE7XG4gICAgICB9KVxuICAgICAgLnRoZW4odG9QYXJzZVNjaGVtYSk7XG4gIH1cblxuICAvLyBUT0RPOiByZW1vdmUgdGhlIG1vbmdvIGZvcm1hdCBkZXBlbmRlbmN5IGluIHRoZSByZXR1cm4gdmFsdWVcbiAgYXN5bmMgY3JlYXRlT2JqZWN0KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBvYmplY3Q6IGFueSxcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbjogP2FueVxuICApIHtcbiAgICBkZWJ1ZygnY3JlYXRlT2JqZWN0JywgY2xhc3NOYW1lLCBvYmplY3QpO1xuICAgIGxldCBjb2x1bW5zQXJyYXkgPSBbXTtcbiAgICBjb25zdCB2YWx1ZXNBcnJheSA9IFtdO1xuICAgIHNjaGVtYSA9IHRvUG9zdGdyZXNTY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBnZW9Qb2ludHMgPSB7fTtcblxuICAgIG9iamVjdCA9IGhhbmRsZURvdEZpZWxkcyhvYmplY3QpO1xuXG4gICAgdmFsaWRhdGVLZXlzKG9iamVjdCk7XG5cbiAgICBPYmplY3Qua2V5cyhvYmplY3QpLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSA9PT0gbnVsbCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB2YXIgYXV0aERhdGFNYXRjaCA9IGZpZWxkTmFtZS5tYXRjaCgvXl9hdXRoX2RhdGFfKFthLXpBLVowLTlfXSspJC8pO1xuICAgICAgaWYgKGF1dGhEYXRhTWF0Y2gpIHtcbiAgICAgICAgdmFyIHByb3ZpZGVyID0gYXV0aERhdGFNYXRjaFsxXTtcbiAgICAgICAgb2JqZWN0WydhdXRoRGF0YSddID0gb2JqZWN0WydhdXRoRGF0YSddIHx8IHt9O1xuICAgICAgICBvYmplY3RbJ2F1dGhEYXRhJ11bcHJvdmlkZXJdID0gb2JqZWN0W2ZpZWxkTmFtZV07XG4gICAgICAgIGRlbGV0ZSBvYmplY3RbZmllbGROYW1lXTtcbiAgICAgICAgZmllbGROYW1lID0gJ2F1dGhEYXRhJztcbiAgICAgIH1cblxuICAgICAgY29sdW1uc0FycmF5LnB1c2goZmllbGROYW1lKTtcbiAgICAgIGlmICghc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdICYmIGNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZmllbGROYW1lID09PSAnX2VtYWlsX3ZlcmlmeV90b2tlbicgfHxcbiAgICAgICAgICBmaWVsZE5hbWUgPT09ICdfZmFpbGVkX2xvZ2luX2NvdW50JyB8fFxuICAgICAgICAgIGZpZWxkTmFtZSA9PT0gJ19wZXJpc2hhYmxlX3Rva2VuJyB8fFxuICAgICAgICAgIGZpZWxkTmFtZSA9PT0gJ19wYXNzd29yZF9oaXN0b3J5J1xuICAgICAgICApIHtcbiAgICAgICAgICB2YWx1ZXNBcnJheS5wdXNoKG9iamVjdFtmaWVsZE5hbWVdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmaWVsZE5hbWUgPT09ICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnKSB7XG4gICAgICAgICAgaWYgKG9iamVjdFtmaWVsZE5hbWVdKSB7XG4gICAgICAgICAgICB2YWx1ZXNBcnJheS5wdXNoKG9iamVjdFtmaWVsZE5hbWVdLmlzbyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhbHVlc0FycmF5LnB1c2gobnVsbCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgIGZpZWxkTmFtZSA9PT0gJ19hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCcgfHxcbiAgICAgICAgICBmaWVsZE5hbWUgPT09ICdfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0JyB8fFxuICAgICAgICAgIGZpZWxkTmFtZSA9PT0gJ19wYXNzd29yZF9jaGFuZ2VkX2F0J1xuICAgICAgICApIHtcbiAgICAgICAgICBpZiAob2JqZWN0W2ZpZWxkTmFtZV0pIHtcbiAgICAgICAgICAgIHZhbHVlc0FycmF5LnB1c2gob2JqZWN0W2ZpZWxkTmFtZV0uaXNvKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsdWVzQXJyYXkucHVzaChudWxsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc3dpdGNoIChzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSkge1xuICAgICAgICBjYXNlICdEYXRlJzpcbiAgICAgICAgICBpZiAob2JqZWN0W2ZpZWxkTmFtZV0pIHtcbiAgICAgICAgICAgIHZhbHVlc0FycmF5LnB1c2gob2JqZWN0W2ZpZWxkTmFtZV0uaXNvKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsdWVzQXJyYXkucHVzaChudWxsKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1BvaW50ZXInOlxuICAgICAgICAgIHZhbHVlc0FycmF5LnB1c2gob2JqZWN0W2ZpZWxkTmFtZV0ub2JqZWN0SWQpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdBcnJheSc6XG4gICAgICAgICAgaWYgKFsnX3JwZXJtJywgJ193cGVybSddLmluZGV4T2YoZmllbGROYW1lKSA+PSAwKSB7XG4gICAgICAgICAgICB2YWx1ZXNBcnJheS5wdXNoKG9iamVjdFtmaWVsZE5hbWVdKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsdWVzQXJyYXkucHVzaChKU09OLnN0cmluZ2lmeShvYmplY3RbZmllbGROYW1lXSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnT2JqZWN0JzpcbiAgICAgICAgY2FzZSAnQnl0ZXMnOlxuICAgICAgICBjYXNlICdTdHJpbmcnOlxuICAgICAgICBjYXNlICdOdW1iZXInOlxuICAgICAgICBjYXNlICdCb29sZWFuJzpcbiAgICAgICAgICB2YWx1ZXNBcnJheS5wdXNoKG9iamVjdFtmaWVsZE5hbWVdKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnRmlsZSc6XG4gICAgICAgICAgdmFsdWVzQXJyYXkucHVzaChvYmplY3RbZmllbGROYW1lXS5uYW1lKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnUG9seWdvbic6IHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IGNvbnZlcnRQb2x5Z29uVG9TUUwob2JqZWN0W2ZpZWxkTmFtZV0uY29vcmRpbmF0ZXMpO1xuICAgICAgICAgIHZhbHVlc0FycmF5LnB1c2godmFsdWUpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgJ0dlb1BvaW50JzpcbiAgICAgICAgICAvLyBwb3AgdGhlIHBvaW50IGFuZCBwcm9jZXNzIGxhdGVyXG4gICAgICAgICAgZ2VvUG9pbnRzW2ZpZWxkTmFtZV0gPSBvYmplY3RbZmllbGROYW1lXTtcbiAgICAgICAgICBjb2x1bW5zQXJyYXkucG9wKCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgYFR5cGUgJHtzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZX0gbm90IHN1cHBvcnRlZCB5ZXRgO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29sdW1uc0FycmF5ID0gY29sdW1uc0FycmF5LmNvbmNhdChPYmplY3Qua2V5cyhnZW9Qb2ludHMpKTtcbiAgICBjb25zdCBpbml0aWFsVmFsdWVzID0gdmFsdWVzQXJyYXkubWFwKCh2YWwsIGluZGV4KSA9PiB7XG4gICAgICBsZXQgdGVybWluYXRpb24gPSAnJztcbiAgICAgIGNvbnN0IGZpZWxkTmFtZSA9IGNvbHVtbnNBcnJheVtpbmRleF07XG4gICAgICBpZiAoWydfcnBlcm0nLCAnX3dwZXJtJ10uaW5kZXhPZihmaWVsZE5hbWUpID49IDApIHtcbiAgICAgICAgdGVybWluYXRpb24gPSAnOjp0ZXh0W10nO1xuICAgICAgfSBlbHNlIGlmIChzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiYgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdBcnJheScpIHtcbiAgICAgICAgdGVybWluYXRpb24gPSAnOjpqc29uYic7XG4gICAgICB9XG4gICAgICByZXR1cm4gYCQke2luZGV4ICsgMiArIGNvbHVtbnNBcnJheS5sZW5ndGh9JHt0ZXJtaW5hdGlvbn1gO1xuICAgIH0pO1xuICAgIGNvbnN0IGdlb1BvaW50c0luamVjdHMgPSBPYmplY3Qua2V5cyhnZW9Qb2ludHMpLm1hcChrZXkgPT4ge1xuICAgICAgY29uc3QgdmFsdWUgPSBnZW9Qb2ludHNba2V5XTtcbiAgICAgIHZhbHVlc0FycmF5LnB1c2godmFsdWUubG9uZ2l0dWRlLCB2YWx1ZS5sYXRpdHVkZSk7XG4gICAgICBjb25zdCBsID0gdmFsdWVzQXJyYXkubGVuZ3RoICsgY29sdW1uc0FycmF5Lmxlbmd0aDtcbiAgICAgIHJldHVybiBgUE9JTlQoJCR7bH0sICQke2wgKyAxfSlgO1xuICAgIH0pO1xuXG4gICAgY29uc3QgY29sdW1uc1BhdHRlcm4gPSBjb2x1bW5zQXJyYXkubWFwKChjb2wsIGluZGV4KSA9PiBgJCR7aW5kZXggKyAyfTpuYW1lYCkuam9pbigpO1xuICAgIGNvbnN0IHZhbHVlc1BhdHRlcm4gPSBpbml0aWFsVmFsdWVzLmNvbmNhdChnZW9Qb2ludHNJbmplY3RzKS5qb2luKCk7XG5cbiAgICBjb25zdCBxcyA9IGBJTlNFUlQgSU5UTyAkMTpuYW1lICgke2NvbHVtbnNQYXR0ZXJufSkgVkFMVUVTICgke3ZhbHVlc1BhdHRlcm59KWA7XG4gICAgY29uc3QgdmFsdWVzID0gW2NsYXNzTmFtZSwgLi4uY29sdW1uc0FycmF5LCAuLi52YWx1ZXNBcnJheV07XG4gICAgZGVidWcocXMsIHZhbHVlcyk7XG4gICAgY29uc3QgcHJvbWlzZSA9ICh0cmFuc2FjdGlvbmFsU2Vzc2lvbiA/IHRyYW5zYWN0aW9uYWxTZXNzaW9uLnQgOiB0aGlzLl9jbGllbnQpXG4gICAgICAubm9uZShxcywgdmFsdWVzKVxuICAgICAgLnRoZW4oKCkgPT4gKHsgb3BzOiBbb2JqZWN0XSB9KSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvci5jb2RlID09PSBQb3N0Z3Jlc1VuaXF1ZUluZGV4VmlvbGF0aW9uRXJyb3IpIHtcbiAgICAgICAgICBjb25zdCBlcnIgPSBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUsXG4gICAgICAgICAgICAnQSBkdXBsaWNhdGUgdmFsdWUgZm9yIGEgZmllbGQgd2l0aCB1bmlxdWUgdmFsdWVzIHdhcyBwcm92aWRlZCdcbiAgICAgICAgICApO1xuICAgICAgICAgIGVyci51bmRlcmx5aW5nRXJyb3IgPSBlcnJvcjtcbiAgICAgICAgICBpZiAoZXJyb3IuY29uc3RyYWludCkge1xuICAgICAgICAgICAgY29uc3QgbWF0Y2hlcyA9IGVycm9yLmNvbnN0cmFpbnQubWF0Y2goL3VuaXF1ZV8oW2EtekEtWl0rKS8pO1xuICAgICAgICAgICAgaWYgKG1hdGNoZXMgJiYgQXJyYXkuaXNBcnJheShtYXRjaGVzKSkge1xuICAgICAgICAgICAgICBlcnIudXNlckluZm8gPSB7IGR1cGxpY2F0ZWRfZmllbGQ6IG1hdGNoZXNbMV0gfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgZXJyb3IgPSBlcnI7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcbiAgICBpZiAodHJhbnNhY3Rpb25hbFNlc3Npb24pIHtcbiAgICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uLmJhdGNoLnB1c2gocHJvbWlzZSk7XG4gICAgfVxuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgLy8gUmVtb3ZlIGFsbCBvYmplY3RzIHRoYXQgbWF0Y2ggdGhlIGdpdmVuIFBhcnNlIFF1ZXJ5LlxuICAvLyBJZiBubyBvYmplY3RzIG1hdGNoLCByZWplY3Qgd2l0aCBPQkpFQ1RfTk9UX0ZPVU5ELiBJZiBvYmplY3RzIGFyZSBmb3VuZCBhbmQgZGVsZXRlZCwgcmVzb2x2ZSB3aXRoIHVuZGVmaW5lZC5cbiAgLy8gSWYgdGhlcmUgaXMgc29tZSBvdGhlciBlcnJvciwgcmVqZWN0IHdpdGggSU5URVJOQUxfU0VSVkVSX0VSUk9SLlxuICBhc3luYyBkZWxldGVPYmplY3RzQnlRdWVyeShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbjogP2FueVxuICApIHtcbiAgICBkZWJ1ZygnZGVsZXRlT2JqZWN0c0J5UXVlcnknLCBjbGFzc05hbWUsIHF1ZXJ5KTtcbiAgICBjb25zdCB2YWx1ZXMgPSBbY2xhc3NOYW1lXTtcbiAgICBjb25zdCBpbmRleCA9IDI7XG4gICAgY29uc3Qgd2hlcmUgPSBidWlsZFdoZXJlQ2xhdXNlKHtcbiAgICAgIHNjaGVtYSxcbiAgICAgIGluZGV4LFxuICAgICAgcXVlcnksXG4gICAgICBjYXNlSW5zZW5zaXRpdmU6IGZhbHNlLFxuICAgIH0pO1xuICAgIHZhbHVlcy5wdXNoKC4uLndoZXJlLnZhbHVlcyk7XG4gICAgaWYgKE9iamVjdC5rZXlzKHF1ZXJ5KS5sZW5ndGggPT09IDApIHtcbiAgICAgIHdoZXJlLnBhdHRlcm4gPSAnVFJVRSc7XG4gICAgfVxuICAgIGNvbnN0IHFzID0gYFdJVEggZGVsZXRlZCBBUyAoREVMRVRFIEZST00gJDE6bmFtZSBXSEVSRSAke3doZXJlLnBhdHRlcm59IFJFVFVSTklORyAqKSBTRUxFQ1QgY291bnQoKikgRlJPTSBkZWxldGVkYDtcbiAgICBkZWJ1ZyhxcywgdmFsdWVzKTtcbiAgICBjb25zdCBwcm9taXNlID0gKHRyYW5zYWN0aW9uYWxTZXNzaW9uID8gdHJhbnNhY3Rpb25hbFNlc3Npb24udCA6IHRoaXMuX2NsaWVudClcbiAgICAgIC5vbmUocXMsIHZhbHVlcywgYSA9PiArYS5jb3VudClcbiAgICAgIC50aGVuKGNvdW50ID0+IHtcbiAgICAgICAgaWYgKGNvdW50ID09PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kLicpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBjb3VudDtcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvci5jb2RlICE9PSBQb3N0Z3Jlc1JlbGF0aW9uRG9lc05vdEV4aXN0RXJyb3IpIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICAvLyBFTFNFOiBEb24ndCBkZWxldGUgYW55dGhpbmcgaWYgZG9lc24ndCBleGlzdFxuICAgICAgfSk7XG4gICAgaWYgKHRyYW5zYWN0aW9uYWxTZXNzaW9uKSB7XG4gICAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbi5iYXRjaC5wdXNoKHByb21pc2UpO1xuICAgIH1cbiAgICByZXR1cm4gcHJvbWlzZTtcbiAgfVxuICAvLyBSZXR1cm4gdmFsdWUgbm90IGN1cnJlbnRseSB3ZWxsIHNwZWNpZmllZC5cbiAgYXN5bmMgZmluZE9uZUFuZFVwZGF0ZShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICB1cGRhdGU6IGFueSxcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbjogP2FueVxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIGRlYnVnKCdmaW5kT25lQW5kVXBkYXRlJywgY2xhc3NOYW1lLCBxdWVyeSwgdXBkYXRlKTtcbiAgICByZXR1cm4gdGhpcy51cGRhdGVPYmplY3RzQnlRdWVyeShjbGFzc05hbWUsIHNjaGVtYSwgcXVlcnksIHVwZGF0ZSwgdHJhbnNhY3Rpb25hbFNlc3Npb24pLnRoZW4oXG4gICAgICB2YWwgPT4gdmFsWzBdXG4gICAgKTtcbiAgfVxuXG4gIC8vIEFwcGx5IHRoZSB1cGRhdGUgdG8gYWxsIG9iamVjdHMgdGhhdCBtYXRjaCB0aGUgZ2l2ZW4gUGFyc2UgUXVlcnkuXG4gIGFzeW5jIHVwZGF0ZU9iamVjdHNCeVF1ZXJ5KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHVwZGF0ZTogYW55LFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICk6IFByb21pc2U8W2FueV0+IHtcbiAgICBkZWJ1ZygndXBkYXRlT2JqZWN0c0J5UXVlcnknLCBjbGFzc05hbWUsIHF1ZXJ5LCB1cGRhdGUpO1xuICAgIGNvbnN0IHVwZGF0ZVBhdHRlcm5zID0gW107XG4gICAgY29uc3QgdmFsdWVzID0gW2NsYXNzTmFtZV07XG4gICAgbGV0IGluZGV4ID0gMjtcbiAgICBzY2hlbWEgPSB0b1Bvc3RncmVzU2NoZW1hKHNjaGVtYSk7XG5cbiAgICBjb25zdCBvcmlnaW5hbFVwZGF0ZSA9IHsgLi4udXBkYXRlIH07XG5cbiAgICAvLyBTZXQgZmxhZyBmb3IgZG90IG5vdGF0aW9uIGZpZWxkc1xuICAgIGNvbnN0IGRvdE5vdGF0aW9uT3B0aW9ucyA9IHt9O1xuICAgIE9iamVjdC5rZXlzKHVwZGF0ZSkuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPiAtMSkge1xuICAgICAgICBjb25zdCBjb21wb25lbnRzID0gZmllbGROYW1lLnNwbGl0KCcuJyk7XG4gICAgICAgIGNvbnN0IGZpcnN0ID0gY29tcG9uZW50cy5zaGlmdCgpO1xuICAgICAgICBkb3ROb3RhdGlvbk9wdGlvbnNbZmlyc3RdID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRvdE5vdGF0aW9uT3B0aW9uc1tmaWVsZE5hbWVdID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdXBkYXRlID0gaGFuZGxlRG90RmllbGRzKHVwZGF0ZSk7XG4gICAgLy8gUmVzb2x2ZSBhdXRoRGF0YSBmaXJzdCxcbiAgICAvLyBTbyB3ZSBkb24ndCBlbmQgdXAgd2l0aCBtdWx0aXBsZSBrZXkgdXBkYXRlc1xuICAgIGZvciAoY29uc3QgZmllbGROYW1lIGluIHVwZGF0ZSkge1xuICAgICAgY29uc3QgYXV0aERhdGFNYXRjaCA9IGZpZWxkTmFtZS5tYXRjaCgvXl9hdXRoX2RhdGFfKFthLXpBLVowLTlfXSspJC8pO1xuICAgICAgaWYgKGF1dGhEYXRhTWF0Y2gpIHtcbiAgICAgICAgdmFyIHByb3ZpZGVyID0gYXV0aERhdGFNYXRjaFsxXTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB1cGRhdGVbZmllbGROYW1lXTtcbiAgICAgICAgZGVsZXRlIHVwZGF0ZVtmaWVsZE5hbWVdO1xuICAgICAgICB1cGRhdGVbJ2F1dGhEYXRhJ10gPSB1cGRhdGVbJ2F1dGhEYXRhJ10gfHwge307XG4gICAgICAgIHVwZGF0ZVsnYXV0aERhdGEnXVtwcm92aWRlcl0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBpbiB1cGRhdGUpIHtcbiAgICAgIGNvbnN0IGZpZWxkVmFsdWUgPSB1cGRhdGVbZmllbGROYW1lXTtcbiAgICAgIC8vIERyb3AgYW55IHVuZGVmaW5lZCB2YWx1ZXMuXG4gICAgICBpZiAodHlwZW9mIGZpZWxkVmFsdWUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGRlbGV0ZSB1cGRhdGVbZmllbGROYW1lXTtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9IE5VTExgKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGROYW1lID09ICdhdXRoRGF0YScpIHtcbiAgICAgICAgLy8gVGhpcyByZWN1cnNpdmVseSBzZXRzIHRoZSBqc29uX29iamVjdFxuICAgICAgICAvLyBPbmx5IDEgbGV2ZWwgZGVlcFxuICAgICAgICBjb25zdCBnZW5lcmF0ZSA9IChqc29uYjogc3RyaW5nLCBrZXk6IHN0cmluZywgdmFsdWU6IGFueSkgPT4ge1xuICAgICAgICAgIHJldHVybiBganNvbl9vYmplY3Rfc2V0X2tleShDT0FMRVNDRSgke2pzb25ifSwgJ3t9Jzo6anNvbmIpLCAke2tleX0sICR7dmFsdWV9KTo6anNvbmJgO1xuICAgICAgICB9O1xuICAgICAgICBjb25zdCBsYXN0S2V5ID0gYCQke2luZGV4fTpuYW1lYDtcbiAgICAgICAgY29uc3QgZmllbGROYW1lSW5kZXggPSBpbmRleDtcbiAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgY29uc3QgdXBkYXRlID0gT2JqZWN0LmtleXMoZmllbGRWYWx1ZSkucmVkdWNlKChsYXN0S2V5OiBzdHJpbmcsIGtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgY29uc3Qgc3RyID0gZ2VuZXJhdGUobGFzdEtleSwgYCQke2luZGV4fTo6dGV4dGAsIGAkJHtpbmRleCArIDF9Ojpqc29uYmApO1xuICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgbGV0IHZhbHVlID0gZmllbGRWYWx1ZVtrZXldO1xuICAgICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKHZhbHVlLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgICAgICAgIHZhbHVlID0gbnVsbDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHZhbHVlID0gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICB2YWx1ZXMucHVzaChrZXksIHZhbHVlKTtcbiAgICAgICAgICByZXR1cm4gc3RyO1xuICAgICAgICB9LCBsYXN0S2V5KTtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7ZmllbGROYW1lSW5kZXh9Om5hbWUgPSAke3VwZGF0ZX1gKTtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS5fX29wID09PSAnSW5jcmVtZW50Jykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9IENPQUxFU0NFKCQke2luZGV4fTpuYW1lLCAwKSArICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlLmFtb3VudCk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkVmFsdWUuX19vcCA9PT0gJ0FkZCcpIHtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChcbiAgICAgICAgICBgJCR7aW5kZXh9Om5hbWUgPSBhcnJheV9hZGQoQ09BTEVTQ0UoJCR7aW5kZXh9Om5hbWUsICdbXSc6Ompzb25iKSwgJCR7aW5kZXggKyAxfTo6anNvbmIpYFxuICAgICAgICApO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIEpTT04uc3RyaW5naWZ5KGZpZWxkVmFsdWUub2JqZWN0cykpO1xuICAgICAgICBpbmRleCArPSAyO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgIHVwZGF0ZVBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lID0gJCR7aW5kZXggKyAxfWApO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIG51bGwpO1xuICAgICAgICBpbmRleCArPSAyO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlLl9fb3AgPT09ICdSZW1vdmUnKSB7XG4gICAgICAgIHVwZGF0ZVBhdHRlcm5zLnB1c2goXG4gICAgICAgICAgYCQke2luZGV4fTpuYW1lID0gYXJyYXlfcmVtb3ZlKENPQUxFU0NFKCQke2luZGV4fTpuYW1lLCAnW10nOjpqc29uYiksICQke1xuICAgICAgICAgICAgaW5kZXggKyAxXG4gICAgICAgICAgfTo6anNvbmIpYFxuICAgICAgICApO1xuICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIEpTT04uc3RyaW5naWZ5KGZpZWxkVmFsdWUub2JqZWN0cykpO1xuICAgICAgICBpbmRleCArPSAyO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlLl9fb3AgPT09ICdBZGRVbmlxdWUnKSB7XG4gICAgICAgIHVwZGF0ZVBhdHRlcm5zLnB1c2goXG4gICAgICAgICAgYCQke2luZGV4fTpuYW1lID0gYXJyYXlfYWRkX3VuaXF1ZShDT0FMRVNDRSgkJHtpbmRleH06bmFtZSwgJ1tdJzo6anNvbmIpLCAkJHtcbiAgICAgICAgICAgIGluZGV4ICsgMVxuICAgICAgICAgIH06Ompzb25iKWBcbiAgICAgICAgKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBKU09OLnN0cmluZ2lmeShmaWVsZFZhbHVlLm9iamVjdHMpKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGROYW1lID09PSAndXBkYXRlZEF0Jykge1xuICAgICAgICAvL1RPRE86IHN0b3Agc3BlY2lhbCBjYXNpbmcgdGhpcy4gSXQgc2hvdWxkIGNoZWNrIGZvciBfX3R5cGUgPT09ICdEYXRlJyBhbmQgdXNlIC5pc29cbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgZmllbGRWYWx1ZSk7XG4gICAgICAgIGluZGV4ICs9IDI7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBmaWVsZFZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGZpZWxkVmFsdWUgPT09ICdib29sZWFuJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS5fX3R5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlLm9iamVjdElkKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS5fX3R5cGUgPT09ICdEYXRlJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCB0b1Bvc3RncmVzVmFsdWUoZmllbGRWYWx1ZSkpO1xuICAgICAgICBpbmRleCArPSAyO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGRWYWx1ZS5fX3R5cGUgPT09ICdGaWxlJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCB0b1Bvc3RncmVzVmFsdWUoZmllbGRWYWx1ZSkpO1xuICAgICAgICBpbmRleCArPSAyO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlLl9fdHlwZSA9PT0gJ0dlb1BvaW50Jykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9IFBPSU5UKCQke2luZGV4ICsgMX0sICQke2luZGV4ICsgMn0pYCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgZmllbGRWYWx1ZS5sb25naXR1ZGUsIGZpZWxkVmFsdWUubGF0aXR1ZGUpO1xuICAgICAgICBpbmRleCArPSAzO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlLl9fdHlwZSA9PT0gJ1BvbHlnb24nKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gY29udmVydFBvbHlnb25Ub1NRTChmaWVsZFZhbHVlLmNvb3JkaW5hdGVzKTtcbiAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9Ojpwb2x5Z29uYCk7XG4gICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgdmFsdWUpO1xuICAgICAgICBpbmRleCArPSAyO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZFZhbHVlLl9fdHlwZSA9PT0gJ1JlbGF0aW9uJykge1xuICAgICAgICAvLyBub29wXG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBmaWVsZFZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCBmaWVsZFZhbHVlKTtcbiAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIHR5cGVvZiBmaWVsZFZhbHVlID09PSAnb2JqZWN0JyAmJlxuICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiZcbiAgICAgICAgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdPYmplY3QnXG4gICAgICApIHtcbiAgICAgICAgLy8gR2F0aGVyIGtleXMgdG8gaW5jcmVtZW50XG4gICAgICAgIGNvbnN0IGtleXNUb0luY3JlbWVudCA9IE9iamVjdC5rZXlzKG9yaWdpbmFsVXBkYXRlKVxuICAgICAgICAgIC5maWx0ZXIoayA9PiB7XG4gICAgICAgICAgICAvLyBjaG9vc2UgdG9wIGxldmVsIGZpZWxkcyB0aGF0IGhhdmUgYSBkZWxldGUgb3BlcmF0aW9uIHNldFxuICAgICAgICAgICAgLy8gTm90ZSB0aGF0IE9iamVjdC5rZXlzIGlzIGl0ZXJhdGluZyBvdmVyIHRoZSAqKm9yaWdpbmFsKiogdXBkYXRlIG9iamVjdFxuICAgICAgICAgICAgLy8gYW5kIHRoYXQgc29tZSBvZiB0aGUga2V5cyBvZiB0aGUgb3JpZ2luYWwgdXBkYXRlIGNvdWxkIGJlIG51bGwgb3IgdW5kZWZpbmVkOlxuICAgICAgICAgICAgLy8gKFNlZSB0aGUgYWJvdmUgY2hlY2sgYGlmIChmaWVsZFZhbHVlID09PSBudWxsIHx8IHR5cGVvZiBmaWVsZFZhbHVlID09IFwidW5kZWZpbmVkXCIpYClcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gb3JpZ2luYWxVcGRhdGVba107XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICB2YWx1ZSAmJlxuICAgICAgICAgICAgICB2YWx1ZS5fX29wID09PSAnSW5jcmVtZW50JyAmJlxuICAgICAgICAgICAgICBrLnNwbGl0KCcuJykubGVuZ3RoID09PSAyICYmXG4gICAgICAgICAgICAgIGsuc3BsaXQoJy4nKVswXSA9PT0gZmllbGROYW1lXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLm1hcChrID0+IGsuc3BsaXQoJy4nKVsxXSk7XG5cbiAgICAgICAgbGV0IGluY3JlbWVudFBhdHRlcm5zID0gJyc7XG4gICAgICAgIGlmIChrZXlzVG9JbmNyZW1lbnQubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGluY3JlbWVudFBhdHRlcm5zID1cbiAgICAgICAgICAgICcgfHwgJyArXG4gICAgICAgICAgICBrZXlzVG9JbmNyZW1lbnRcbiAgICAgICAgICAgICAgLm1hcChjID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBhbW91bnQgPSBmaWVsZFZhbHVlW2NdLmFtb3VudDtcbiAgICAgICAgICAgICAgICByZXR1cm4gYENPTkNBVCgne1wiJHtjfVwiOicsIENPQUxFU0NFKCQke2luZGV4fTpuYW1lLT4+JyR7Y30nLCcwJyk6OmludCArICR7YW1vdW50fSwgJ30nKTo6anNvbmJgO1xuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAuam9pbignIHx8ICcpO1xuICAgICAgICAgIC8vIFN0cmlwIHRoZSBrZXlzXG4gICAgICAgICAga2V5c1RvSW5jcmVtZW50LmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgIGRlbGV0ZSBmaWVsZFZhbHVlW2tleV07XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBrZXlzVG9EZWxldGU6IEFycmF5PHN0cmluZz4gPSBPYmplY3Qua2V5cyhvcmlnaW5hbFVwZGF0ZSlcbiAgICAgICAgICAuZmlsdGVyKGsgPT4ge1xuICAgICAgICAgICAgLy8gY2hvb3NlIHRvcCBsZXZlbCBmaWVsZHMgdGhhdCBoYXZlIGEgZGVsZXRlIG9wZXJhdGlvbiBzZXQuXG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IG9yaWdpbmFsVXBkYXRlW2tdO1xuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgdmFsdWUgJiZcbiAgICAgICAgICAgICAgdmFsdWUuX19vcCA9PT0gJ0RlbGV0ZScgJiZcbiAgICAgICAgICAgICAgay5zcGxpdCgnLicpLmxlbmd0aCA9PT0gMiAmJlxuICAgICAgICAgICAgICBrLnNwbGl0KCcuJylbMF0gPT09IGZpZWxkTmFtZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5tYXAoayA9PiBrLnNwbGl0KCcuJylbMV0pO1xuXG4gICAgICAgIGNvbnN0IGRlbGV0ZVBhdHRlcm5zID0ga2V5c1RvRGVsZXRlLnJlZHVjZSgocDogc3RyaW5nLCBjOiBzdHJpbmcsIGk6IG51bWJlcikgPT4ge1xuICAgICAgICAgIHJldHVybiBwICsgYCAtICckJHtpbmRleCArIDEgKyBpfTp2YWx1ZSdgO1xuICAgICAgICB9LCAnJyk7XG4gICAgICAgIC8vIE92ZXJyaWRlIE9iamVjdFxuICAgICAgICBsZXQgdXBkYXRlT2JqZWN0ID0gXCIne30nOjpqc29uYlwiO1xuXG4gICAgICAgIGlmIChkb3ROb3RhdGlvbk9wdGlvbnNbZmllbGROYW1lXSkge1xuICAgICAgICAgIC8vIE1lcmdlIE9iamVjdFxuICAgICAgICAgIHVwZGF0ZU9iamVjdCA9IGBDT0FMRVNDRSgkJHtpbmRleH06bmFtZSwgJ3t9Jzo6anNvbmIpYDtcbiAgICAgICAgfVxuICAgICAgICB1cGRhdGVQYXR0ZXJucy5wdXNoKFxuICAgICAgICAgIGAkJHtpbmRleH06bmFtZSA9ICgke3VwZGF0ZU9iamVjdH0gJHtkZWxldGVQYXR0ZXJuc30gJHtpbmNyZW1lbnRQYXR0ZXJuc30gfHwgJCR7XG4gICAgICAgICAgICBpbmRleCArIDEgKyBrZXlzVG9EZWxldGUubGVuZ3RoXG4gICAgICAgICAgfTo6anNvbmIgKWBcbiAgICAgICAgKTtcbiAgICAgICAgdmFsdWVzLnB1c2goZmllbGROYW1lLCAuLi5rZXlzVG9EZWxldGUsIEpTT04uc3RyaW5naWZ5KGZpZWxkVmFsdWUpKTtcbiAgICAgICAgaW5kZXggKz0gMiArIGtleXNUb0RlbGV0ZS5sZW5ndGg7XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICBBcnJheS5pc0FycmF5KGZpZWxkVmFsdWUpICYmXG4gICAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJlxuICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ0FycmF5J1xuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IGV4cGVjdGVkVHlwZSA9IHBhcnNlVHlwZVRvUG9zdGdyZXNUeXBlKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSk7XG4gICAgICAgIGlmIChleHBlY3RlZFR5cGUgPT09ICd0ZXh0W10nKSB7XG4gICAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9Ojp0ZXh0W11gKTtcbiAgICAgICAgICB2YWx1ZXMucHVzaChmaWVsZE5hbWUsIGZpZWxkVmFsdWUpO1xuICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdXBkYXRlUGF0dGVybnMucHVzaChgJCR7aW5kZXh9Om5hbWUgPSAkJHtpbmRleCArIDF9Ojpqc29uYmApO1xuICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkTmFtZSwgSlNPTi5zdHJpbmdpZnkoZmllbGRWYWx1ZSkpO1xuICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlYnVnKCdOb3Qgc3VwcG9ydGVkIHVwZGF0ZScsIGZpZWxkTmFtZSwgZmllbGRWYWx1ZSk7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgICBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICAgICAgYFBvc3RncmVzIGRvZXNuJ3Qgc3VwcG9ydCB1cGRhdGUgJHtKU09OLnN0cmluZ2lmeShmaWVsZFZhbHVlKX0geWV0YFxuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB3aGVyZSA9IGJ1aWxkV2hlcmVDbGF1c2Uoe1xuICAgICAgc2NoZW1hLFxuICAgICAgaW5kZXgsXG4gICAgICBxdWVyeSxcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZTogZmFsc2UsXG4gICAgfSk7XG4gICAgdmFsdWVzLnB1c2goLi4ud2hlcmUudmFsdWVzKTtcblxuICAgIGNvbnN0IHdoZXJlQ2xhdXNlID0gd2hlcmUucGF0dGVybi5sZW5ndGggPiAwID8gYFdIRVJFICR7d2hlcmUucGF0dGVybn1gIDogJyc7XG4gICAgY29uc3QgcXMgPSBgVVBEQVRFICQxOm5hbWUgU0VUICR7dXBkYXRlUGF0dGVybnMuam9pbigpfSAke3doZXJlQ2xhdXNlfSBSRVRVUk5JTkcgKmA7XG4gICAgZGVidWcoJ3VwZGF0ZTogJywgcXMsIHZhbHVlcyk7XG4gICAgY29uc3QgcHJvbWlzZSA9ICh0cmFuc2FjdGlvbmFsU2Vzc2lvbiA/IHRyYW5zYWN0aW9uYWxTZXNzaW9uLnQgOiB0aGlzLl9jbGllbnQpLmFueShxcywgdmFsdWVzKTtcbiAgICBpZiAodHJhbnNhY3Rpb25hbFNlc3Npb24pIHtcbiAgICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uLmJhdGNoLnB1c2gocHJvbWlzZSk7XG4gICAgfVxuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgLy8gSG9wZWZ1bGx5LCB3ZSBjYW4gZ2V0IHJpZCBvZiB0aGlzLiBJdCdzIG9ubHkgdXNlZCBmb3IgY29uZmlnIGFuZCBob29rcy5cbiAgdXBzZXJ0T25lT2JqZWN0KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHVwZGF0ZTogYW55LFxuICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55XG4gICkge1xuICAgIGRlYnVnKCd1cHNlcnRPbmVPYmplY3QnLCB7IGNsYXNzTmFtZSwgcXVlcnksIHVwZGF0ZSB9KTtcbiAgICBjb25zdCBjcmVhdGVWYWx1ZSA9IE9iamVjdC5hc3NpZ24oe30sIHF1ZXJ5LCB1cGRhdGUpO1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZU9iamVjdChjbGFzc05hbWUsIHNjaGVtYSwgY3JlYXRlVmFsdWUsIHRyYW5zYWN0aW9uYWxTZXNzaW9uKS5jYXRjaChlcnJvciA9PiB7XG4gICAgICAvLyBpZ25vcmUgZHVwbGljYXRlIHZhbHVlIGVycm9ycyBhcyBpdCdzIHVwc2VydFxuICAgICAgaWYgKGVycm9yLmNvZGUgIT09IFBhcnNlLkVycm9yLkRVUExJQ0FURV9WQUxVRSkge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmZpbmRPbmVBbmRVcGRhdGUoY2xhc3NOYW1lLCBzY2hlbWEsIHF1ZXJ5LCB1cGRhdGUsIHRyYW5zYWN0aW9uYWxTZXNzaW9uKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZpbmQoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIHF1ZXJ5OiBRdWVyeVR5cGUsXG4gICAgeyBza2lwLCBsaW1pdCwgc29ydCwga2V5cywgY2FzZUluc2Vuc2l0aXZlLCBleHBsYWluIH06IFF1ZXJ5T3B0aW9uc1xuICApIHtcbiAgICBkZWJ1ZygnZmluZCcsIGNsYXNzTmFtZSwgcXVlcnksIHtcbiAgICAgIHNraXAsXG4gICAgICBsaW1pdCxcbiAgICAgIHNvcnQsXG4gICAgICBrZXlzLFxuICAgICAgY2FzZUluc2Vuc2l0aXZlLFxuICAgICAgZXhwbGFpbixcbiAgICB9KTtcbiAgICBjb25zdCBoYXNMaW1pdCA9IGxpbWl0ICE9PSB1bmRlZmluZWQ7XG4gICAgY29uc3QgaGFzU2tpcCA9IHNraXAgIT09IHVuZGVmaW5lZDtcbiAgICBsZXQgdmFsdWVzID0gW2NsYXNzTmFtZV07XG4gICAgY29uc3Qgd2hlcmUgPSBidWlsZFdoZXJlQ2xhdXNlKHtcbiAgICAgIHNjaGVtYSxcbiAgICAgIHF1ZXJ5LFxuICAgICAgaW5kZXg6IDIsXG4gICAgICBjYXNlSW5zZW5zaXRpdmUsXG4gICAgfSk7XG4gICAgdmFsdWVzLnB1c2goLi4ud2hlcmUudmFsdWVzKTtcblxuICAgIGNvbnN0IHdoZXJlUGF0dGVybiA9IHdoZXJlLnBhdHRlcm4ubGVuZ3RoID4gMCA/IGBXSEVSRSAke3doZXJlLnBhdHRlcm59YCA6ICcnO1xuICAgIGNvbnN0IGxpbWl0UGF0dGVybiA9IGhhc0xpbWl0ID8gYExJTUlUICQke3ZhbHVlcy5sZW5ndGggKyAxfWAgOiAnJztcbiAgICBpZiAoaGFzTGltaXQpIHtcbiAgICAgIHZhbHVlcy5wdXNoKGxpbWl0KTtcbiAgICB9XG4gICAgY29uc3Qgc2tpcFBhdHRlcm4gPSBoYXNTa2lwID8gYE9GRlNFVCAkJHt2YWx1ZXMubGVuZ3RoICsgMX1gIDogJyc7XG4gICAgaWYgKGhhc1NraXApIHtcbiAgICAgIHZhbHVlcy5wdXNoKHNraXApO1xuICAgIH1cblxuICAgIGxldCBzb3J0UGF0dGVybiA9ICcnO1xuICAgIGlmIChzb3J0KSB7XG4gICAgICBjb25zdCBzb3J0Q29weTogYW55ID0gc29ydDtcbiAgICAgIGNvbnN0IHNvcnRpbmcgPSBPYmplY3Qua2V5cyhzb3J0KVxuICAgICAgICAubWFwKGtleSA9PiB7XG4gICAgICAgICAgY29uc3QgdHJhbnNmb3JtS2V5ID0gdHJhbnNmb3JtRG90RmllbGRUb0NvbXBvbmVudHMoa2V5KS5qb2luKCctPicpO1xuICAgICAgICAgIC8vIFVzaW5nICRpZHggcGF0dGVybiBnaXZlczogIG5vbi1pbnRlZ2VyIGNvbnN0YW50IGluIE9SREVSIEJZXG4gICAgICAgICAgaWYgKHNvcnRDb3B5W2tleV0gPT09IDEpIHtcbiAgICAgICAgICAgIHJldHVybiBgJHt0cmFuc2Zvcm1LZXl9IEFTQ2A7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBgJHt0cmFuc2Zvcm1LZXl9IERFU0NgO1xuICAgICAgICB9KVxuICAgICAgICAuam9pbigpO1xuICAgICAgc29ydFBhdHRlcm4gPSBzb3J0ICE9PSB1bmRlZmluZWQgJiYgT2JqZWN0LmtleXMoc29ydCkubGVuZ3RoID4gMCA/IGBPUkRFUiBCWSAke3NvcnRpbmd9YCA6ICcnO1xuICAgIH1cbiAgICBpZiAod2hlcmUuc29ydHMgJiYgT2JqZWN0LmtleXMoKHdoZXJlLnNvcnRzOiBhbnkpKS5sZW5ndGggPiAwKSB7XG4gICAgICBzb3J0UGF0dGVybiA9IGBPUkRFUiBCWSAke3doZXJlLnNvcnRzLmpvaW4oKX1gO1xuICAgIH1cblxuICAgIGxldCBjb2x1bW5zID0gJyonO1xuICAgIGlmIChrZXlzKSB7XG4gICAgICAvLyBFeGNsdWRlIGVtcHR5IGtleXNcbiAgICAgIC8vIFJlcGxhY2UgQUNMIGJ5IGl0J3Mga2V5c1xuICAgICAga2V5cyA9IGtleXMucmVkdWNlKChtZW1vLCBrZXkpID0+IHtcbiAgICAgICAgaWYgKGtleSA9PT0gJ0FDTCcpIHtcbiAgICAgICAgICBtZW1vLnB1c2goJ19ycGVybScpO1xuICAgICAgICAgIG1lbW8ucHVzaCgnX3dwZXJtJyk7XG4gICAgICAgIH0gZWxzZSBpZiAoa2V5Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBtZW1vLnB1c2goa2V5KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVtbztcbiAgICAgIH0sIFtdKTtcbiAgICAgIGNvbHVtbnMgPSBrZXlzXG4gICAgICAgIC5tYXAoKGtleSwgaW5kZXgpID0+IHtcbiAgICAgICAgICBpZiAoa2V5ID09PSAnJHNjb3JlJykge1xuICAgICAgICAgICAgcmV0dXJuIGB0c19yYW5rX2NkKHRvX3RzdmVjdG9yKCQkezJ9LCAkJHszfTpuYW1lKSwgdG9fdHNxdWVyeSgkJHs0fSwgJCR7NX0pLCAzMikgYXMgc2NvcmVgO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gYCQke2luZGV4ICsgdmFsdWVzLmxlbmd0aCArIDF9Om5hbWVgO1xuICAgICAgICB9KVxuICAgICAgICAuam9pbigpO1xuICAgICAgdmFsdWVzID0gdmFsdWVzLmNvbmNhdChrZXlzKTtcbiAgICB9XG5cbiAgICBjb25zdCBvcmlnaW5hbFF1ZXJ5ID0gYFNFTEVDVCAke2NvbHVtbnN9IEZST00gJDE6bmFtZSAke3doZXJlUGF0dGVybn0gJHtzb3J0UGF0dGVybn0gJHtsaW1pdFBhdHRlcm59ICR7c2tpcFBhdHRlcm59YDtcbiAgICBjb25zdCBxcyA9IGV4cGxhaW4gPyB0aGlzLmNyZWF0ZUV4cGxhaW5hYmxlUXVlcnkob3JpZ2luYWxRdWVyeSkgOiBvcmlnaW5hbFF1ZXJ5O1xuICAgIGRlYnVnKHFzLCB2YWx1ZXMpO1xuICAgIHJldHVybiB0aGlzLl9jbGllbnRcbiAgICAgIC5hbnkocXMsIHZhbHVlcylcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIC8vIFF1ZXJ5IG9uIG5vbiBleGlzdGluZyB0YWJsZSwgZG9uJ3QgY3Jhc2hcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgIT09IFBvc3RncmVzUmVsYXRpb25Eb2VzTm90RXhpc3RFcnJvcikge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgaWYgKGV4cGxhaW4pIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0cy5tYXAob2JqZWN0ID0+IHRoaXMucG9zdGdyZXNPYmplY3RUb1BhcnNlT2JqZWN0KGNsYXNzTmFtZSwgb2JqZWN0LCBzY2hlbWEpKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gQ29udmVydHMgZnJvbSBhIHBvc3RncmVzLWZvcm1hdCBvYmplY3QgdG8gYSBSRVNULWZvcm1hdCBvYmplY3QuXG4gIC8vIERvZXMgbm90IHN0cmlwIG91dCBhbnl0aGluZyBiYXNlZCBvbiBhIGxhY2sgb2YgYXV0aGVudGljYXRpb24uXG4gIHBvc3RncmVzT2JqZWN0VG9QYXJzZU9iamVjdChjbGFzc05hbWU6IHN0cmluZywgb2JqZWN0OiBhbnksIHNjaGVtYTogYW55KSB7XG4gICAgT2JqZWN0LmtleXMoc2NoZW1hLmZpZWxkcykuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnUG9pbnRlcicgJiYgb2JqZWN0W2ZpZWxkTmFtZV0pIHtcbiAgICAgICAgb2JqZWN0W2ZpZWxkTmFtZV0gPSB7XG4gICAgICAgICAgb2JqZWN0SWQ6IG9iamVjdFtmaWVsZE5hbWVdLFxuICAgICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICAgIGNsYXNzTmFtZTogc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnRhcmdldENsYXNzLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIG9iamVjdFtmaWVsZE5hbWVdID0ge1xuICAgICAgICAgIF9fdHlwZTogJ1JlbGF0aW9uJyxcbiAgICAgICAgICBjbGFzc05hbWU6IHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50YXJnZXRDbGFzcyxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ0dlb1BvaW50Jykge1xuICAgICAgICBvYmplY3RbZmllbGROYW1lXSA9IHtcbiAgICAgICAgICBfX3R5cGU6ICdHZW9Qb2ludCcsXG4gICAgICAgICAgbGF0aXR1ZGU6IG9iamVjdFtmaWVsZE5hbWVdLnksXG4gICAgICAgICAgbG9uZ2l0dWRlOiBvYmplY3RbZmllbGROYW1lXS54LFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdFtmaWVsZE5hbWVdICYmIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnUG9seWdvbicpIHtcbiAgICAgICAgbGV0IGNvb3JkcyA9IG9iamVjdFtmaWVsZE5hbWVdO1xuICAgICAgICBjb29yZHMgPSBjb29yZHMuc3Vic3RyKDIsIGNvb3Jkcy5sZW5ndGggLSA0KS5zcGxpdCgnKSwoJyk7XG4gICAgICAgIGNvb3JkcyA9IGNvb3Jkcy5tYXAocG9pbnQgPT4ge1xuICAgICAgICAgIHJldHVybiBbcGFyc2VGbG9hdChwb2ludC5zcGxpdCgnLCcpWzFdKSwgcGFyc2VGbG9hdChwb2ludC5zcGxpdCgnLCcpWzBdKV07XG4gICAgICAgIH0pO1xuICAgICAgICBvYmplY3RbZmllbGROYW1lXSA9IHtcbiAgICAgICAgICBfX3R5cGU6ICdQb2x5Z29uJyxcbiAgICAgICAgICBjb29yZGluYXRlczogY29vcmRzLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgaWYgKG9iamVjdFtmaWVsZE5hbWVdICYmIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnRmlsZScpIHtcbiAgICAgICAgb2JqZWN0W2ZpZWxkTmFtZV0gPSB7XG4gICAgICAgICAgX190eXBlOiAnRmlsZScsXG4gICAgICAgICAgbmFtZTogb2JqZWN0W2ZpZWxkTmFtZV0sXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfSk7XG4gICAgLy9UT0RPOiByZW1vdmUgdGhpcyByZWxpYW5jZSBvbiB0aGUgbW9uZ28gZm9ybWF0LiBEQiBhZGFwdGVyIHNob3VsZG4ndCBrbm93IHRoZXJlIGlzIGEgZGlmZmVyZW5jZSBiZXR3ZWVuIGNyZWF0ZWQgYXQgYW5kIGFueSBvdGhlciBkYXRlIGZpZWxkLlxuICAgIGlmIChvYmplY3QuY3JlYXRlZEF0KSB7XG4gICAgICBvYmplY3QuY3JlYXRlZEF0ID0gb2JqZWN0LmNyZWF0ZWRBdC50b0lTT1N0cmluZygpO1xuICAgIH1cbiAgICBpZiAob2JqZWN0LnVwZGF0ZWRBdCkge1xuICAgICAgb2JqZWN0LnVwZGF0ZWRBdCA9IG9iamVjdC51cGRhdGVkQXQudG9JU09TdHJpbmcoKTtcbiAgICB9XG4gICAgaWYgKG9iamVjdC5leHBpcmVzQXQpIHtcbiAgICAgIG9iamVjdC5leHBpcmVzQXQgPSB7XG4gICAgICAgIF9fdHlwZTogJ0RhdGUnLFxuICAgICAgICBpc286IG9iamVjdC5leHBpcmVzQXQudG9JU09TdHJpbmcoKSxcbiAgICAgIH07XG4gICAgfVxuICAgIGlmIChvYmplY3QuX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0KSB7XG4gICAgICBvYmplY3QuX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0ID0ge1xuICAgICAgICBfX3R5cGU6ICdEYXRlJyxcbiAgICAgICAgaXNvOiBvYmplY3QuX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0LnRvSVNPU3RyaW5nKCksXG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAob2JqZWN0Ll9hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCkge1xuICAgICAgb2JqZWN0Ll9hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdCA9IHtcbiAgICAgICAgX190eXBlOiAnRGF0ZScsXG4gICAgICAgIGlzbzogb2JqZWN0Ll9hY2NvdW50X2xvY2tvdXRfZXhwaXJlc19hdC50b0lTT1N0cmluZygpLFxuICAgICAgfTtcbiAgICB9XG4gICAgaWYgKG9iamVjdC5fcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0KSB7XG4gICAgICBvYmplY3QuX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCA9IHtcbiAgICAgICAgX190eXBlOiAnRGF0ZScsXG4gICAgICAgIGlzbzogb2JqZWN0Ll9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQudG9JU09TdHJpbmcoKSxcbiAgICAgIH07XG4gICAgfVxuICAgIGlmIChvYmplY3QuX3Bhc3N3b3JkX2NoYW5nZWRfYXQpIHtcbiAgICAgIG9iamVjdC5fcGFzc3dvcmRfY2hhbmdlZF9hdCA9IHtcbiAgICAgICAgX190eXBlOiAnRGF0ZScsXG4gICAgICAgIGlzbzogb2JqZWN0Ll9wYXNzd29yZF9jaGFuZ2VkX2F0LnRvSVNPU3RyaW5nKCksXG4gICAgICB9O1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZmllbGROYW1lIGluIG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdFtmaWVsZE5hbWVdID09PSBudWxsKSB7XG4gICAgICAgIGRlbGV0ZSBvYmplY3RbZmllbGROYW1lXTtcbiAgICAgIH1cbiAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgb2JqZWN0W2ZpZWxkTmFtZV0gPSB7XG4gICAgICAgICAgX190eXBlOiAnRGF0ZScsXG4gICAgICAgICAgaXNvOiBvYmplY3RbZmllbGROYW1lXS50b0lTT1N0cmluZygpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvYmplY3Q7XG4gIH1cblxuICAvLyBDcmVhdGUgYSB1bmlxdWUgaW5kZXguIFVuaXF1ZSBpbmRleGVzIG9uIG51bGxhYmxlIGZpZWxkcyBhcmUgbm90IGFsbG93ZWQuIFNpbmNlIHdlIGRvbid0XG4gIC8vIGN1cnJlbnRseSBrbm93IHdoaWNoIGZpZWxkcyBhcmUgbnVsbGFibGUgYW5kIHdoaWNoIGFyZW4ndCwgd2UgaWdub3JlIHRoYXQgY3JpdGVyaWEuXG4gIC8vIEFzIHN1Y2gsIHdlIHNob3VsZG4ndCBleHBvc2UgdGhpcyBmdW5jdGlvbiB0byB1c2VycyBvZiBwYXJzZSB1bnRpbCB3ZSBoYXZlIGFuIG91dC1vZi1iYW5kXG4gIC8vIFdheSBvZiBkZXRlcm1pbmluZyBpZiBhIGZpZWxkIGlzIG51bGxhYmxlLiBVbmRlZmluZWQgZG9lc24ndCBjb3VudCBhZ2FpbnN0IHVuaXF1ZW5lc3MsXG4gIC8vIHdoaWNoIGlzIHdoeSB3ZSB1c2Ugc3BhcnNlIGluZGV4ZXMuXG4gIGFzeW5jIGVuc3VyZVVuaXF1ZW5lc3MoY2xhc3NOYW1lOiBzdHJpbmcsIHNjaGVtYTogU2NoZW1hVHlwZSwgZmllbGROYW1lczogc3RyaW5nW10pIHtcbiAgICBjb25zdCBjb25zdHJhaW50TmFtZSA9IGAke2NsYXNzTmFtZX1fdW5pcXVlXyR7ZmllbGROYW1lcy5zb3J0KCkuam9pbignXycpfWA7XG4gICAgY29uc3QgY29uc3RyYWludFBhdHRlcm5zID0gZmllbGROYW1lcy5tYXAoKGZpZWxkTmFtZSwgaW5kZXgpID0+IGAkJHtpbmRleCArIDN9Om5hbWVgKTtcbiAgICBjb25zdCBxcyA9IGBDUkVBVEUgVU5JUVVFIElOREVYIElGIE5PVCBFWElTVFMgJDI6bmFtZSBPTiAkMTpuYW1lKCR7Y29uc3RyYWludFBhdHRlcm5zLmpvaW4oKX0pYDtcbiAgICByZXR1cm4gdGhpcy5fY2xpZW50Lm5vbmUocXMsIFtjbGFzc05hbWUsIGNvbnN0cmFpbnROYW1lLCAuLi5maWVsZE5hbWVzXSkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgaWYgKGVycm9yLmNvZGUgPT09IFBvc3RncmVzRHVwbGljYXRlUmVsYXRpb25FcnJvciAmJiBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKGNvbnN0cmFpbnROYW1lKSkge1xuICAgICAgICAvLyBJbmRleCBhbHJlYWR5IGV4aXN0cy4gSWdub3JlIGVycm9yLlxuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgZXJyb3IuY29kZSA9PT0gUG9zdGdyZXNVbmlxdWVJbmRleFZpb2xhdGlvbkVycm9yICYmXG4gICAgICAgIGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoY29uc3RyYWludE5hbWUpXG4gICAgICApIHtcbiAgICAgICAgLy8gQ2FzdCB0aGUgZXJyb3IgaW50byB0aGUgcHJvcGVyIHBhcnNlIGVycm9yXG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUsXG4gICAgICAgICAgJ0EgZHVwbGljYXRlIHZhbHVlIGZvciBhIGZpZWxkIHdpdGggdW5pcXVlIHZhbHVlcyB3YXMgcHJvdmlkZWQnXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIEV4ZWN1dGVzIGEgY291bnQuXG4gIGFzeW5jIGNvdW50KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBxdWVyeTogUXVlcnlUeXBlLFxuICAgIHJlYWRQcmVmZXJlbmNlPzogc3RyaW5nLFxuICAgIGVzdGltYXRlPzogYm9vbGVhbiA9IHRydWVcbiAgKSB7XG4gICAgZGVidWcoJ2NvdW50JywgY2xhc3NOYW1lLCBxdWVyeSwgcmVhZFByZWZlcmVuY2UsIGVzdGltYXRlKTtcbiAgICBjb25zdCB2YWx1ZXMgPSBbY2xhc3NOYW1lXTtcbiAgICBjb25zdCB3aGVyZSA9IGJ1aWxkV2hlcmVDbGF1c2Uoe1xuICAgICAgc2NoZW1hLFxuICAgICAgcXVlcnksXG4gICAgICBpbmRleDogMixcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZTogZmFsc2UsXG4gICAgfSk7XG4gICAgdmFsdWVzLnB1c2goLi4ud2hlcmUudmFsdWVzKTtcblxuICAgIGNvbnN0IHdoZXJlUGF0dGVybiA9IHdoZXJlLnBhdHRlcm4ubGVuZ3RoID4gMCA/IGBXSEVSRSAke3doZXJlLnBhdHRlcm59YCA6ICcnO1xuICAgIGxldCBxcyA9ICcnO1xuXG4gICAgaWYgKHdoZXJlLnBhdHRlcm4ubGVuZ3RoID4gMCB8fCAhZXN0aW1hdGUpIHtcbiAgICAgIHFzID0gYFNFTEVDVCBjb3VudCgqKSBGUk9NICQxOm5hbWUgJHt3aGVyZVBhdHRlcm59YDtcbiAgICB9IGVsc2Uge1xuICAgICAgcXMgPSAnU0VMRUNUIHJlbHR1cGxlcyBBUyBhcHByb3hpbWF0ZV9yb3dfY291bnQgRlJPTSBwZ19jbGFzcyBXSEVSRSByZWxuYW1lID0gJDEnO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9jbGllbnRcbiAgICAgIC5vbmUocXMsIHZhbHVlcywgYSA9PiB7XG4gICAgICAgIGlmIChhLmFwcHJveGltYXRlX3Jvd19jb3VudCAhPSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuICthLmFwcHJveGltYXRlX3Jvd19jb3VudDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gK2EuY291bnQ7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSAhPT0gUG9zdGdyZXNSZWxhdGlvbkRvZXNOb3RFeGlzdEVycm9yKSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGRpc3RpbmN0KGNsYXNzTmFtZTogc3RyaW5nLCBzY2hlbWE6IFNjaGVtYVR5cGUsIHF1ZXJ5OiBRdWVyeVR5cGUsIGZpZWxkTmFtZTogc3RyaW5nKSB7XG4gICAgZGVidWcoJ2Rpc3RpbmN0JywgY2xhc3NOYW1lLCBxdWVyeSk7XG4gICAgbGV0IGZpZWxkID0gZmllbGROYW1lO1xuICAgIGxldCBjb2x1bW4gPSBmaWVsZE5hbWU7XG4gICAgY29uc3QgaXNOZXN0ZWQgPSBmaWVsZE5hbWUuaW5kZXhPZignLicpID49IDA7XG4gICAgaWYgKGlzTmVzdGVkKSB7XG4gICAgICBmaWVsZCA9IHRyYW5zZm9ybURvdEZpZWxkVG9Db21wb25lbnRzKGZpZWxkTmFtZSkuam9pbignLT4nKTtcbiAgICAgIGNvbHVtbiA9IGZpZWxkTmFtZS5zcGxpdCgnLicpWzBdO1xuICAgIH1cbiAgICBjb25zdCBpc0FycmF5RmllbGQgPVxuICAgICAgc2NoZW1hLmZpZWxkcyAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiYgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdBcnJheSc7XG4gICAgY29uc3QgaXNQb2ludGVyRmllbGQgPVxuICAgICAgc2NoZW1hLmZpZWxkcyAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiYgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdQb2ludGVyJztcbiAgICBjb25zdCB2YWx1ZXMgPSBbZmllbGQsIGNvbHVtbiwgY2xhc3NOYW1lXTtcbiAgICBjb25zdCB3aGVyZSA9IGJ1aWxkV2hlcmVDbGF1c2Uoe1xuICAgICAgc2NoZW1hLFxuICAgICAgcXVlcnksXG4gICAgICBpbmRleDogNCxcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZTogZmFsc2UsXG4gICAgfSk7XG4gICAgdmFsdWVzLnB1c2goLi4ud2hlcmUudmFsdWVzKTtcblxuICAgIGNvbnN0IHdoZXJlUGF0dGVybiA9IHdoZXJlLnBhdHRlcm4ubGVuZ3RoID4gMCA/IGBXSEVSRSAke3doZXJlLnBhdHRlcm59YCA6ICcnO1xuICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gaXNBcnJheUZpZWxkID8gJ2pzb25iX2FycmF5X2VsZW1lbnRzJyA6ICdPTic7XG4gICAgbGV0IHFzID0gYFNFTEVDVCBESVNUSU5DVCAke3RyYW5zZm9ybWVyfSgkMTpuYW1lKSAkMjpuYW1lIEZST00gJDM6bmFtZSAke3doZXJlUGF0dGVybn1gO1xuICAgIGlmIChpc05lc3RlZCkge1xuICAgICAgcXMgPSBgU0VMRUNUIERJU1RJTkNUICR7dHJhbnNmb3JtZXJ9KCQxOnJhdykgJDI6cmF3IEZST00gJDM6bmFtZSAke3doZXJlUGF0dGVybn1gO1xuICAgIH1cbiAgICBkZWJ1ZyhxcywgdmFsdWVzKTtcbiAgICByZXR1cm4gdGhpcy5fY2xpZW50XG4gICAgICAuYW55KHFzLCB2YWx1ZXMpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gUG9zdGdyZXNNaXNzaW5nQ29sdW1uRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KVxuICAgICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAgIGlmICghaXNOZXN0ZWQpIHtcbiAgICAgICAgICByZXN1bHRzID0gcmVzdWx0cy5maWx0ZXIob2JqZWN0ID0+IG9iamVjdFtmaWVsZF0gIT09IG51bGwpO1xuICAgICAgICAgIHJldHVybiByZXN1bHRzLm1hcChvYmplY3QgPT4ge1xuICAgICAgICAgICAgaWYgKCFpc1BvaW50ZXJGaWVsZCkge1xuICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0W2ZpZWxkXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICAgICAgICBjbGFzc05hbWU6IHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50YXJnZXRDbGFzcyxcbiAgICAgICAgICAgICAgb2JqZWN0SWQ6IG9iamVjdFtmaWVsZF0sXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNoaWxkID0gZmllbGROYW1lLnNwbGl0KCcuJylbMV07XG4gICAgICAgIHJldHVybiByZXN1bHRzLm1hcChvYmplY3QgPT4gb2JqZWN0W2NvbHVtbl1bY2hpbGRdKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXN1bHRzID0+XG4gICAgICAgIHJlc3VsdHMubWFwKG9iamVjdCA9PiB0aGlzLnBvc3RncmVzT2JqZWN0VG9QYXJzZU9iamVjdChjbGFzc05hbWUsIG9iamVjdCwgc2NoZW1hKSlcbiAgICAgICk7XG4gIH1cblxuICBhc3luYyBhZ2dyZWdhdGUoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBhbnksXG4gICAgcGlwZWxpbmU6IGFueSxcbiAgICByZWFkUHJlZmVyZW5jZTogP3N0cmluZyxcbiAgICBoaW50OiA/bWl4ZWQsXG4gICAgZXhwbGFpbj86IGJvb2xlYW5cbiAgKSB7XG4gICAgZGVidWcoJ2FnZ3JlZ2F0ZScsIGNsYXNzTmFtZSwgcGlwZWxpbmUsIHJlYWRQcmVmZXJlbmNlLCBoaW50LCBleHBsYWluKTtcbiAgICBjb25zdCB2YWx1ZXMgPSBbY2xhc3NOYW1lXTtcbiAgICBsZXQgaW5kZXg6IG51bWJlciA9IDI7XG4gICAgbGV0IGNvbHVtbnM6IHN0cmluZ1tdID0gW107XG4gICAgbGV0IGNvdW50RmllbGQgPSBudWxsO1xuICAgIGxldCBncm91cFZhbHVlcyA9IG51bGw7XG4gICAgbGV0IHdoZXJlUGF0dGVybiA9ICcnO1xuICAgIGxldCBsaW1pdFBhdHRlcm4gPSAnJztcbiAgICBsZXQgc2tpcFBhdHRlcm4gPSAnJztcbiAgICBsZXQgc29ydFBhdHRlcm4gPSAnJztcbiAgICBsZXQgZ3JvdXBQYXR0ZXJuID0gJyc7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwaXBlbGluZS5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgY29uc3Qgc3RhZ2UgPSBwaXBlbGluZVtpXTtcbiAgICAgIGlmIChzdGFnZS4kZ3JvdXApIHtcbiAgICAgICAgZm9yIChjb25zdCBmaWVsZCBpbiBzdGFnZS4kZ3JvdXApIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IHN0YWdlLiRncm91cFtmaWVsZF07XG4gICAgICAgICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZmllbGQgPT09ICdfaWQnICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWUgIT09ICcnKSB7XG4gICAgICAgICAgICBjb2x1bW5zLnB1c2goYCQke2luZGV4fTpuYW1lIEFTIFwib2JqZWN0SWRcImApO1xuICAgICAgICAgICAgZ3JvdXBQYXR0ZXJuID0gYEdST1VQIEJZICQke2luZGV4fTpuYW1lYDtcbiAgICAgICAgICAgIHZhbHVlcy5wdXNoKHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlKSk7XG4gICAgICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChmaWVsZCA9PT0gJ19pZCcgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiBPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoICE9PSAwKSB7XG4gICAgICAgICAgICBncm91cFZhbHVlcyA9IHZhbHVlO1xuICAgICAgICAgICAgY29uc3QgZ3JvdXBCeUZpZWxkcyA9IFtdO1xuICAgICAgICAgICAgZm9yIChjb25zdCBhbGlhcyBpbiB2YWx1ZSkge1xuICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlW2FsaWFzXSA9PT0gJ3N0cmluZycgJiYgdmFsdWVbYWxpYXNdKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc291cmNlID0gdHJhbnNmb3JtQWdncmVnYXRlRmllbGQodmFsdWVbYWxpYXNdKTtcbiAgICAgICAgICAgICAgICBpZiAoIWdyb3VwQnlGaWVsZHMuaW5jbHVkZXMoYFwiJHtzb3VyY2V9XCJgKSkge1xuICAgICAgICAgICAgICAgICAgZ3JvdXBCeUZpZWxkcy5wdXNoKGBcIiR7c291cmNlfVwiYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHNvdXJjZSwgYWxpYXMpO1xuICAgICAgICAgICAgICAgIGNvbHVtbnMucHVzaChgJCR7aW5kZXh9Om5hbWUgQVMgJCR7aW5kZXggKyAxfTpuYW1lYCk7XG4gICAgICAgICAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcGVyYXRpb24gPSBPYmplY3Qua2V5cyh2YWx1ZVthbGlhc10pWzBdO1xuICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZSA9IHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlW2FsaWFzXVtvcGVyYXRpb25dKTtcbiAgICAgICAgICAgICAgICBpZiAobW9uZ29BZ2dyZWdhdGVUb1Bvc3RncmVzW29wZXJhdGlvbl0pIHtcbiAgICAgICAgICAgICAgICAgIGlmICghZ3JvdXBCeUZpZWxkcy5pbmNsdWRlcyhgXCIke3NvdXJjZX1cImApKSB7XG4gICAgICAgICAgICAgICAgICAgIGdyb3VwQnlGaWVsZHMucHVzaChgXCIke3NvdXJjZX1cImApO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgY29sdW1ucy5wdXNoKFxuICAgICAgICAgICAgICAgICAgICBgRVhUUkFDVCgke1xuICAgICAgICAgICAgICAgICAgICAgIG1vbmdvQWdncmVnYXRlVG9Qb3N0Z3Jlc1tvcGVyYXRpb25dXG4gICAgICAgICAgICAgICAgICAgIH0gRlJPTSAkJHtpbmRleH06bmFtZSBBVCBUSU1FIFpPTkUgJ1VUQycpIEFTICQke2luZGV4ICsgMX06bmFtZWBcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICB2YWx1ZXMucHVzaChzb3VyY2UsIGFsaWFzKTtcbiAgICAgICAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBncm91cFBhdHRlcm4gPSBgR1JPVVAgQlkgJCR7aW5kZXh9OnJhd2A7XG4gICAgICAgICAgICB2YWx1ZXMucHVzaChncm91cEJ5RmllbGRzLmpvaW4oKSk7XG4gICAgICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBpZiAodmFsdWUuJHN1bSkge1xuICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlLiRzdW0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgY29sdW1ucy5wdXNoKGBTVU0oJCR7aW5kZXh9Om5hbWUpIEFTICQke2luZGV4ICsgMX06bmFtZWApO1xuICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlLiRzdW0pLCBmaWVsZCk7XG4gICAgICAgICAgICAgICAgaW5kZXggKz0gMjtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb3VudEZpZWxkID0gZmllbGQ7XG4gICAgICAgICAgICAgICAgY29sdW1ucy5wdXNoKGBDT1VOVCgqKSBBUyAkJHtpbmRleH06bmFtZWApO1xuICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkKTtcbiAgICAgICAgICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWUuJG1heCkge1xuICAgICAgICAgICAgICBjb2x1bW5zLnB1c2goYE1BWCgkJHtpbmRleH06bmFtZSkgQVMgJCR7aW5kZXggKyAxfTpuYW1lYCk7XG4gICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlLiRtYXgpLCBmaWVsZCk7XG4gICAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWUuJG1pbikge1xuICAgICAgICAgICAgICBjb2x1bW5zLnB1c2goYE1JTigkJHtpbmRleH06bmFtZSkgQVMgJCR7aW5kZXggKyAxfTpuYW1lYCk7XG4gICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlLiRtaW4pLCBmaWVsZCk7XG4gICAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodmFsdWUuJGF2Zykge1xuICAgICAgICAgICAgICBjb2x1bW5zLnB1c2goYEFWRygkJHtpbmRleH06bmFtZSkgQVMgJCR7aW5kZXggKyAxfTpuYW1lYCk7XG4gICAgICAgICAgICAgIHZhbHVlcy5wdXNoKHRyYW5zZm9ybUFnZ3JlZ2F0ZUZpZWxkKHZhbHVlLiRhdmcpLCBmaWVsZCk7XG4gICAgICAgICAgICAgIGluZGV4ICs9IDI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb2x1bW5zLnB1c2goJyonKTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFnZS4kcHJvamVjdCkge1xuICAgICAgICBpZiAoY29sdW1ucy5pbmNsdWRlcygnKicpKSB7XG4gICAgICAgICAgY29sdW1ucyA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gc3RhZ2UuJHByb2plY3QpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IHN0YWdlLiRwcm9qZWN0W2ZpZWxkXTtcbiAgICAgICAgICBpZiAodmFsdWUgPT09IDEgfHwgdmFsdWUgPT09IHRydWUpIHtcbiAgICAgICAgICAgIGNvbHVtbnMucHVzaChgJCR7aW5kZXh9Om5hbWVgKTtcbiAgICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkKTtcbiAgICAgICAgICAgIGluZGV4ICs9IDE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoc3RhZ2UuJG1hdGNoKSB7XG4gICAgICAgIGNvbnN0IHBhdHRlcm5zID0gW107XG4gICAgICAgIGNvbnN0IG9yT3JBbmQgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc3RhZ2UuJG1hdGNoLCAnJG9yJylcbiAgICAgICAgICA/ICcgT1IgJ1xuICAgICAgICAgIDogJyBBTkQgJztcblxuICAgICAgICBpZiAoc3RhZ2UuJG1hdGNoLiRvcikge1xuICAgICAgICAgIGNvbnN0IGNvbGxhcHNlID0ge307XG4gICAgICAgICAgc3RhZ2UuJG1hdGNoLiRvci5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZWxlbWVudCkge1xuICAgICAgICAgICAgICBjb2xsYXBzZVtrZXldID0gZWxlbWVudFtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHN0YWdlLiRtYXRjaCA9IGNvbGxhcHNlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gc3RhZ2UuJG1hdGNoKSB7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSBzdGFnZS4kbWF0Y2hbZmllbGRdO1xuICAgICAgICAgIGNvbnN0IG1hdGNoUGF0dGVybnMgPSBbXTtcbiAgICAgICAgICBPYmplY3Qua2V5cyhQYXJzZVRvUG9zZ3Jlc0NvbXBhcmF0b3IpLmZvckVhY2goY21wID0+IHtcbiAgICAgICAgICAgIGlmICh2YWx1ZVtjbXBdKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHBnQ29tcGFyYXRvciA9IFBhcnNlVG9Qb3NncmVzQ29tcGFyYXRvcltjbXBdO1xuICAgICAgICAgICAgICBtYXRjaFBhdHRlcm5zLnB1c2goYCQke2luZGV4fTpuYW1lICR7cGdDb21wYXJhdG9yfSAkJHtpbmRleCArIDF9YCk7XG4gICAgICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkLCB0b1Bvc3RncmVzVmFsdWUodmFsdWVbY21wXSkpO1xuICAgICAgICAgICAgICBpbmRleCArPSAyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmIChtYXRjaFBhdHRlcm5zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHBhdHRlcm5zLnB1c2goYCgke21hdGNoUGF0dGVybnMuam9pbignIEFORCAnKX0pYCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChzY2hlbWEuZmllbGRzW2ZpZWxkXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkXS50eXBlICYmIG1hdGNoUGF0dGVybnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBwYXR0ZXJucy5wdXNoKGAkJHtpbmRleH06bmFtZSA9ICQke2luZGV4ICsgMX1gKTtcbiAgICAgICAgICAgIHZhbHVlcy5wdXNoKGZpZWxkLCB2YWx1ZSk7XG4gICAgICAgICAgICBpbmRleCArPSAyO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB3aGVyZVBhdHRlcm4gPSBwYXR0ZXJucy5sZW5ndGggPiAwID8gYFdIRVJFICR7cGF0dGVybnMuam9pbihgICR7b3JPckFuZH0gYCl9YCA6ICcnO1xuICAgICAgfVxuICAgICAgaWYgKHN0YWdlLiRsaW1pdCkge1xuICAgICAgICBsaW1pdFBhdHRlcm4gPSBgTElNSVQgJCR7aW5kZXh9YDtcbiAgICAgICAgdmFsdWVzLnB1c2goc3RhZ2UuJGxpbWl0KTtcbiAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFnZS4kc2tpcCkge1xuICAgICAgICBza2lwUGF0dGVybiA9IGBPRkZTRVQgJCR7aW5kZXh9YDtcbiAgICAgICAgdmFsdWVzLnB1c2goc3RhZ2UuJHNraXApO1xuICAgICAgICBpbmRleCArPSAxO1xuICAgICAgfVxuICAgICAgaWYgKHN0YWdlLiRzb3J0KSB7XG4gICAgICAgIGNvbnN0IHNvcnQgPSBzdGFnZS4kc29ydDtcbiAgICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKHNvcnQpO1xuICAgICAgICBjb25zdCBzb3J0aW5nID0ga2V5c1xuICAgICAgICAgIC5tYXAoa2V5ID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gc29ydFtrZXldID09PSAxID8gJ0FTQycgOiAnREVTQyc7XG4gICAgICAgICAgICBjb25zdCBvcmRlciA9IGAkJHtpbmRleH06bmFtZSAke3RyYW5zZm9ybWVyfWA7XG4gICAgICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICAgICAgcmV0dXJuIG9yZGVyO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLmpvaW4oKTtcbiAgICAgICAgdmFsdWVzLnB1c2goLi4ua2V5cyk7XG4gICAgICAgIHNvcnRQYXR0ZXJuID0gc29ydCAhPT0gdW5kZWZpbmVkICYmIHNvcnRpbmcubGVuZ3RoID4gMCA/IGBPUkRFUiBCWSAke3NvcnRpbmd9YCA6ICcnO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChncm91cFBhdHRlcm4pIHtcbiAgICAgIGNvbHVtbnMuZm9yRWFjaCgoZSwgaSwgYSkgPT4ge1xuICAgICAgICBpZiAoZSAmJiBlLnRyaW0oKSA9PT0gJyonKSB7XG4gICAgICAgICAgYVtpXSA9ICcnO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBvcmlnaW5hbFF1ZXJ5ID0gYFNFTEVDVCAke2NvbHVtbnNcbiAgICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAgIC5qb2luKCl9IEZST00gJDE6bmFtZSAke3doZXJlUGF0dGVybn0gJHtza2lwUGF0dGVybn0gJHtncm91cFBhdHRlcm59ICR7c29ydFBhdHRlcm59ICR7bGltaXRQYXR0ZXJufWA7XG4gICAgY29uc3QgcXMgPSBleHBsYWluID8gdGhpcy5jcmVhdGVFeHBsYWluYWJsZVF1ZXJ5KG9yaWdpbmFsUXVlcnkpIDogb3JpZ2luYWxRdWVyeTtcbiAgICBkZWJ1ZyhxcywgdmFsdWVzKTtcbiAgICByZXR1cm4gdGhpcy5fY2xpZW50LmFueShxcywgdmFsdWVzKS50aGVuKGEgPT4ge1xuICAgICAgaWYgKGV4cGxhaW4pIHtcbiAgICAgICAgcmV0dXJuIGE7XG4gICAgICB9XG4gICAgICBjb25zdCByZXN1bHRzID0gYS5tYXAob2JqZWN0ID0+IHRoaXMucG9zdGdyZXNPYmplY3RUb1BhcnNlT2JqZWN0KGNsYXNzTmFtZSwgb2JqZWN0LCBzY2hlbWEpKTtcbiAgICAgIHJlc3VsdHMuZm9yRWFjaChyZXN1bHQgPT4ge1xuICAgICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChyZXN1bHQsICdvYmplY3RJZCcpKSB7XG4gICAgICAgICAgcmVzdWx0Lm9iamVjdElkID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZ3JvdXBWYWx1ZXMpIHtcbiAgICAgICAgICByZXN1bHQub2JqZWN0SWQgPSB7fTtcbiAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBncm91cFZhbHVlcykge1xuICAgICAgICAgICAgcmVzdWx0Lm9iamVjdElkW2tleV0gPSByZXN1bHRba2V5XTtcbiAgICAgICAgICAgIGRlbGV0ZSByZXN1bHRba2V5XTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvdW50RmllbGQpIHtcbiAgICAgICAgICByZXN1bHRbY291bnRGaWVsZF0gPSBwYXJzZUludChyZXN1bHRbY291bnRGaWVsZF0sIDEwKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzdWx0cztcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHBlcmZvcm1Jbml0aWFsaXphdGlvbih7IFZvbGF0aWxlQ2xhc3Nlc1NjaGVtYXMgfTogYW55KSB7XG4gICAgLy8gVE9ETzogVGhpcyBtZXRob2QgbmVlZHMgdG8gYmUgcmV3cml0dGVuIHRvIG1ha2UgcHJvcGVyIHVzZSBvZiBjb25uZWN0aW9ucyAoQHZpdGFseS10KVxuICAgIGRlYnVnKCdwZXJmb3JtSW5pdGlhbGl6YXRpb24nKTtcbiAgICBjb25zdCBwcm9taXNlcyA9IFZvbGF0aWxlQ2xhc3Nlc1NjaGVtYXMubWFwKHNjaGVtYSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5jcmVhdGVUYWJsZShzY2hlbWEuY2xhc3NOYW1lLCBzY2hlbWEpXG4gICAgICAgIC5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGVyci5jb2RlID09PSBQb3N0Z3Jlc0R1cGxpY2F0ZVJlbGF0aW9uRXJyb3IgfHxcbiAgICAgICAgICAgIGVyci5jb2RlID09PSBQYXJzZS5FcnJvci5JTlZBTElEX0NMQVNTX05BTUVcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoKSA9PiB0aGlzLnNjaGVtYVVwZ3JhZGUoc2NoZW1hLmNsYXNzTmFtZSwgc2NoZW1hKSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2xpZW50LnR4KCdwZXJmb3JtLWluaXRpYWxpemF0aW9uJywgYXN5bmMgdCA9PiB7XG4gICAgICAgICAgYXdhaXQgdC5ub25lKHNxbC5taXNjLmpzb25PYmplY3RTZXRLZXlzKTtcbiAgICAgICAgICBhd2FpdCB0Lm5vbmUoc3FsLmFycmF5LmFkZCk7XG4gICAgICAgICAgYXdhaXQgdC5ub25lKHNxbC5hcnJheS5hZGRVbmlxdWUpO1xuICAgICAgICAgIGF3YWl0IHQubm9uZShzcWwuYXJyYXkucmVtb3ZlKTtcbiAgICAgICAgICBhd2FpdCB0Lm5vbmUoc3FsLmFycmF5LmNvbnRhaW5zQWxsKTtcbiAgICAgICAgICBhd2FpdCB0Lm5vbmUoc3FsLmFycmF5LmNvbnRhaW5zQWxsUmVnZXgpO1xuICAgICAgICAgIGF3YWl0IHQubm9uZShzcWwuYXJyYXkuY29udGFpbnMpO1xuICAgICAgICAgIHJldHVybiB0LmN0eDtcbiAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oY3R4ID0+IHtcbiAgICAgICAgZGVidWcoYGluaXRpYWxpemF0aW9uRG9uZSBpbiAke2N0eC5kdXJhdGlvbn1gKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgfSk7XG4gIH1cblxuICBhc3luYyBjcmVhdGVJbmRleGVzKGNsYXNzTmFtZTogc3RyaW5nLCBpbmRleGVzOiBhbnksIGNvbm46ID9hbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gKGNvbm4gfHwgdGhpcy5fY2xpZW50KS50eCh0ID0+XG4gICAgICB0LmJhdGNoKFxuICAgICAgICBpbmRleGVzLm1hcChpID0+IHtcbiAgICAgICAgICByZXR1cm4gdC5ub25lKCdDUkVBVEUgSU5ERVggSUYgTk9UIEVYSVNUUyAkMTpuYW1lIE9OICQyOm5hbWUgKCQzOm5hbWUpJywgW1xuICAgICAgICAgICAgaS5uYW1lLFxuICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgaS5rZXksXG4gICAgICAgICAgXSk7XG4gICAgICAgIH0pXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZUluZGV4ZXNJZk5lZWRlZChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBmaWVsZE5hbWU6IHN0cmluZyxcbiAgICB0eXBlOiBhbnksXG4gICAgY29ubjogP2FueVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCAoY29ubiB8fCB0aGlzLl9jbGllbnQpLm5vbmUoJ0NSRUFURSBJTkRFWCBJRiBOT1QgRVhJU1RTICQxOm5hbWUgT04gJDI6bmFtZSAoJDM6bmFtZSknLCBbXG4gICAgICBmaWVsZE5hbWUsXG4gICAgICBjbGFzc05hbWUsXG4gICAgICB0eXBlLFxuICAgIF0pO1xuICB9XG5cbiAgYXN5bmMgZHJvcEluZGV4ZXMoY2xhc3NOYW1lOiBzdHJpbmcsIGluZGV4ZXM6IGFueSwgY29ubjogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcXVlcmllcyA9IGluZGV4ZXMubWFwKGkgPT4gKHtcbiAgICAgIHF1ZXJ5OiAnRFJPUCBJTkRFWCAkMTpuYW1lJyxcbiAgICAgIHZhbHVlczogaSxcbiAgICB9KSk7XG4gICAgYXdhaXQgKGNvbm4gfHwgdGhpcy5fY2xpZW50KS50eCh0ID0+IHQubm9uZSh0aGlzLl9wZ3AuaGVscGVycy5jb25jYXQocXVlcmllcykpKTtcbiAgfVxuXG4gIGFzeW5jIGdldEluZGV4ZXMoY2xhc3NOYW1lOiBzdHJpbmcpIHtcbiAgICBjb25zdCBxcyA9ICdTRUxFQ1QgKiBGUk9NIHBnX2luZGV4ZXMgV0hFUkUgdGFibGVuYW1lID0gJHtjbGFzc05hbWV9JztcbiAgICByZXR1cm4gdGhpcy5fY2xpZW50LmFueShxcywgeyBjbGFzc05hbWUgfSk7XG4gIH1cblxuICBhc3luYyB1cGRhdGVTY2hlbWFXaXRoSW5kZXhlcygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICAvLyBVc2VkIGZvciB0ZXN0aW5nIHB1cnBvc2VzXG4gIGFzeW5jIHVwZGF0ZUVzdGltYXRlZENvdW50KGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NsaWVudC5ub25lKCdBTkFMWVpFICQxOm5hbWUnLCBbY2xhc3NOYW1lXSk7XG4gIH1cblxuICBhc3luYyBjcmVhdGVUcmFuc2FjdGlvbmFsU2Vzc2lvbigpOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgIGNvbnN0IHRyYW5zYWN0aW9uYWxTZXNzaW9uID0ge307XG4gICAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbi5yZXN1bHQgPSB0aGlzLl9jbGllbnQudHgodCA9PiB7XG4gICAgICAgIHRyYW5zYWN0aW9uYWxTZXNzaW9uLnQgPSB0O1xuICAgICAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbi5wcm9taXNlID0gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgdHJhbnNhY3Rpb25hbFNlc3Npb24ucmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICAgIH0pO1xuICAgICAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbi5iYXRjaCA9IFtdO1xuICAgICAgICByZXNvbHZlKHRyYW5zYWN0aW9uYWxTZXNzaW9uKTtcbiAgICAgICAgcmV0dXJuIHRyYW5zYWN0aW9uYWxTZXNzaW9uLnByb21pc2U7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGNvbW1pdFRyYW5zYWN0aW9uYWxTZXNzaW9uKHRyYW5zYWN0aW9uYWxTZXNzaW9uOiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbi5yZXNvbHZlKHRyYW5zYWN0aW9uYWxTZXNzaW9uLnQuYmF0Y2godHJhbnNhY3Rpb25hbFNlc3Npb24uYmF0Y2gpKTtcbiAgICByZXR1cm4gdHJhbnNhY3Rpb25hbFNlc3Npb24ucmVzdWx0O1xuICB9XG5cbiAgYWJvcnRUcmFuc2FjdGlvbmFsU2Vzc2lvbih0cmFuc2FjdGlvbmFsU2Vzc2lvbjogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcmVzdWx0ID0gdHJhbnNhY3Rpb25hbFNlc3Npb24ucmVzdWx0LmNhdGNoKCk7XG4gICAgdHJhbnNhY3Rpb25hbFNlc3Npb24uYmF0Y2gucHVzaChQcm9taXNlLnJlamVjdCgpKTtcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbi5yZXNvbHZlKHRyYW5zYWN0aW9uYWxTZXNzaW9uLnQuYmF0Y2godHJhbnNhY3Rpb25hbFNlc3Npb24uYmF0Y2gpKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgYXN5bmMgZW5zdXJlSW5kZXgoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIGZpZWxkTmFtZXM6IHN0cmluZ1tdLFxuICAgIGluZGV4TmFtZTogP3N0cmluZyxcbiAgICBjYXNlSW5zZW5zaXRpdmU6IGJvb2xlYW4gPSBmYWxzZSxcbiAgICBvcHRpb25zPzogT2JqZWN0ID0ge31cbiAgKTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCBjb25uID0gb3B0aW9ucy5jb25uICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNvbm4gOiB0aGlzLl9jbGllbnQ7XG4gICAgY29uc3QgZGVmYXVsdEluZGV4TmFtZSA9IGBwYXJzZV9kZWZhdWx0XyR7ZmllbGROYW1lcy5zb3J0KCkuam9pbignXycpfWA7XG4gICAgY29uc3QgaW5kZXhOYW1lT3B0aW9uczogT2JqZWN0ID1cbiAgICAgIGluZGV4TmFtZSAhPSBudWxsID8geyBuYW1lOiBpbmRleE5hbWUgfSA6IHsgbmFtZTogZGVmYXVsdEluZGV4TmFtZSB9O1xuICAgIGNvbnN0IGNvbnN0cmFpbnRQYXR0ZXJucyA9IGNhc2VJbnNlbnNpdGl2ZVxuICAgICAgPyBmaWVsZE5hbWVzLm1hcCgoZmllbGROYW1lLCBpbmRleCkgPT4gYGxvd2VyKCQke2luZGV4ICsgM306bmFtZSkgdmFyY2hhcl9wYXR0ZXJuX29wc2ApXG4gICAgICA6IGZpZWxkTmFtZXMubWFwKChmaWVsZE5hbWUsIGluZGV4KSA9PiBgJCR7aW5kZXggKyAzfTpuYW1lYCk7XG4gICAgY29uc3QgcXMgPSBgQ1JFQVRFIElOREVYIElGIE5PVCBFWElTVFMgJDE6bmFtZSBPTiAkMjpuYW1lICgke2NvbnN0cmFpbnRQYXR0ZXJucy5qb2luKCl9KWA7XG4gICAgYXdhaXQgY29ubi5ub25lKHFzLCBbaW5kZXhOYW1lT3B0aW9ucy5uYW1lLCBjbGFzc05hbWUsIC4uLmZpZWxkTmFtZXNdKS5jYXRjaChlcnJvciA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIGVycm9yLmNvZGUgPT09IFBvc3RncmVzRHVwbGljYXRlUmVsYXRpb25FcnJvciAmJlxuICAgICAgICBlcnJvci5tZXNzYWdlLmluY2x1ZGVzKGluZGV4TmFtZU9wdGlvbnMubmFtZSlcbiAgICAgICkge1xuICAgICAgICAvLyBJbmRleCBhbHJlYWR5IGV4aXN0cy4gSWdub3JlIGVycm9yLlxuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgZXJyb3IuY29kZSA9PT0gUG9zdGdyZXNVbmlxdWVJbmRleFZpb2xhdGlvbkVycm9yICYmXG4gICAgICAgIGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoaW5kZXhOYW1lT3B0aW9ucy5uYW1lKVxuICAgICAgKSB7XG4gICAgICAgIC8vIENhc3QgdGhlIGVycm9yIGludG8gdGhlIHByb3BlciBwYXJzZSBlcnJvclxuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFLFxuICAgICAgICAgICdBIGR1cGxpY2F0ZSB2YWx1ZSBmb3IgYSBmaWVsZCB3aXRoIHVuaXF1ZSB2YWx1ZXMgd2FzIHByb3ZpZGVkJ1xuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29udmVydFBvbHlnb25Ub1NRTChwb2x5Z29uKSB7XG4gIGlmIChwb2x5Z29uLmxlbmd0aCA8IDMpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCBgUG9seWdvbiBtdXN0IGhhdmUgYXQgbGVhc3QgMyB2YWx1ZXNgKTtcbiAgfVxuICBpZiAoXG4gICAgcG9seWdvblswXVswXSAhPT0gcG9seWdvbltwb2x5Z29uLmxlbmd0aCAtIDFdWzBdIHx8XG4gICAgcG9seWdvblswXVsxXSAhPT0gcG9seWdvbltwb2x5Z29uLmxlbmd0aCAtIDFdWzFdXG4gICkge1xuICAgIHBvbHlnb24ucHVzaChwb2x5Z29uWzBdKTtcbiAgfVxuICBjb25zdCB1bmlxdWUgPSBwb2x5Z29uLmZpbHRlcigoaXRlbSwgaW5kZXgsIGFyKSA9PiB7XG4gICAgbGV0IGZvdW5kSW5kZXggPSAtMTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCBwdCA9IGFyW2ldO1xuICAgICAgaWYgKHB0WzBdID09PSBpdGVtWzBdICYmIHB0WzFdID09PSBpdGVtWzFdKSB7XG4gICAgICAgIGZvdW5kSW5kZXggPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZvdW5kSW5kZXggPT09IGluZGV4O1xuICB9KTtcbiAgaWYgKHVuaXF1ZS5sZW5ndGggPCAzKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgJ0dlb0pTT046IExvb3AgbXVzdCBoYXZlIGF0IGxlYXN0IDMgZGlmZmVyZW50IHZlcnRpY2VzJ1xuICAgICk7XG4gIH1cbiAgY29uc3QgcG9pbnRzID0gcG9seWdvblxuICAgIC5tYXAocG9pbnQgPT4ge1xuICAgICAgUGFyc2UuR2VvUG9pbnQuX3ZhbGlkYXRlKHBhcnNlRmxvYXQocG9pbnRbMV0pLCBwYXJzZUZsb2F0KHBvaW50WzBdKSk7XG4gICAgICByZXR1cm4gYCgke3BvaW50WzFdfSwgJHtwb2ludFswXX0pYDtcbiAgICB9KVxuICAgIC5qb2luKCcsICcpO1xuICByZXR1cm4gYCgke3BvaW50c30pYDtcbn1cblxuZnVuY3Rpb24gcmVtb3ZlV2hpdGVTcGFjZShyZWdleCkge1xuICBpZiAoIXJlZ2V4LmVuZHNXaXRoKCdcXG4nKSkge1xuICAgIHJlZ2V4ICs9ICdcXG4nO1xuICB9XG5cbiAgLy8gcmVtb3ZlIG5vbiBlc2NhcGVkIGNvbW1lbnRzXG4gIHJldHVybiAoXG4gICAgcmVnZXhcbiAgICAgIC5yZXBsYWNlKC8oW15cXFxcXSkjLipcXG4vZ2ltLCAnJDEnKVxuICAgICAgLy8gcmVtb3ZlIGxpbmVzIHN0YXJ0aW5nIHdpdGggYSBjb21tZW50XG4gICAgICAucmVwbGFjZSgvXiMuKlxcbi9naW0sICcnKVxuICAgICAgLy8gcmVtb3ZlIG5vbiBlc2NhcGVkIHdoaXRlc3BhY2VcbiAgICAgIC5yZXBsYWNlKC8oW15cXFxcXSlcXHMrL2dpbSwgJyQxJylcbiAgICAgIC8vIHJlbW92ZSB3aGl0ZXNwYWNlIGF0IHRoZSBiZWdpbm5pbmcgb2YgYSBsaW5lXG4gICAgICAucmVwbGFjZSgvXlxccysvLCAnJylcbiAgICAgIC50cmltKClcbiAgKTtcbn1cblxuZnVuY3Rpb24gcHJvY2Vzc1JlZ2V4UGF0dGVybihzKSB7XG4gIGlmIChzICYmIHMuc3RhcnRzV2l0aCgnXicpKSB7XG4gICAgLy8gcmVnZXggZm9yIHN0YXJ0c1dpdGhcbiAgICByZXR1cm4gJ14nICsgbGl0ZXJhbGl6ZVJlZ2V4UGFydChzLnNsaWNlKDEpKTtcbiAgfSBlbHNlIGlmIChzICYmIHMuZW5kc1dpdGgoJyQnKSkge1xuICAgIC8vIHJlZ2V4IGZvciBlbmRzV2l0aFxuICAgIHJldHVybiBsaXRlcmFsaXplUmVnZXhQYXJ0KHMuc2xpY2UoMCwgcy5sZW5ndGggLSAxKSkgKyAnJCc7XG4gIH1cblxuICAvLyByZWdleCBmb3IgY29udGFpbnNcbiAgcmV0dXJuIGxpdGVyYWxpemVSZWdleFBhcnQocyk7XG59XG5cbmZ1bmN0aW9uIGlzU3RhcnRzV2l0aFJlZ2V4KHZhbHVlKSB7XG4gIGlmICghdmFsdWUgfHwgdHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJyB8fCAhdmFsdWUuc3RhcnRzV2l0aCgnXicpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgbWF0Y2hlcyA9IHZhbHVlLm1hdGNoKC9cXF5cXFxcUS4qXFxcXEUvKTtcbiAgcmV0dXJuICEhbWF0Y2hlcztcbn1cblxuZnVuY3Rpb24gaXNBbGxWYWx1ZXNSZWdleE9yTm9uZSh2YWx1ZXMpIHtcbiAgaWYgKCF2YWx1ZXMgfHwgIUFycmF5LmlzQXJyYXkodmFsdWVzKSB8fCB2YWx1ZXMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBjb25zdCBmaXJzdFZhbHVlc0lzUmVnZXggPSBpc1N0YXJ0c1dpdGhSZWdleCh2YWx1ZXNbMF0uJHJlZ2V4KTtcbiAgaWYgKHZhbHVlcy5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gZmlyc3RWYWx1ZXNJc1JlZ2V4O1xuICB9XG5cbiAgZm9yIChsZXQgaSA9IDEsIGxlbmd0aCA9IHZhbHVlcy5sZW5ndGg7IGkgPCBsZW5ndGg7ICsraSkge1xuICAgIGlmIChmaXJzdFZhbHVlc0lzUmVnZXggIT09IGlzU3RhcnRzV2l0aFJlZ2V4KHZhbHVlc1tpXS4kcmVnZXgpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGlzQW55VmFsdWVSZWdleFN0YXJ0c1dpdGgodmFsdWVzKSB7XG4gIHJldHVybiB2YWx1ZXMuc29tZShmdW5jdGlvbiAodmFsdWUpIHtcbiAgICByZXR1cm4gaXNTdGFydHNXaXRoUmVnZXgodmFsdWUuJHJlZ2V4KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUxpdGVyYWxSZWdleChyZW1haW5pbmcpIHtcbiAgcmV0dXJuIHJlbWFpbmluZ1xuICAgIC5zcGxpdCgnJylcbiAgICAubWFwKGMgPT4ge1xuICAgICAgY29uc3QgcmVnZXggPSBSZWdFeHAoJ1swLTkgXXxcXFxccHtMfScsICd1Jyk7IC8vIFN1cHBvcnQgYWxsIHVuaWNvZGUgbGV0dGVyIGNoYXJzXG4gICAgICBpZiAoYy5tYXRjaChyZWdleCkgIT09IG51bGwpIHtcbiAgICAgICAgLy8gZG9uJ3QgZXNjYXBlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzXG4gICAgICAgIHJldHVybiBjO1xuICAgICAgfVxuICAgICAgLy8gZXNjYXBlIGV2ZXJ5dGhpbmcgZWxzZSAoc2luZ2xlIHF1b3RlcyB3aXRoIHNpbmdsZSBxdW90ZXMsIGV2ZXJ5dGhpbmcgZWxzZSB3aXRoIGEgYmFja3NsYXNoKVxuICAgICAgcmV0dXJuIGMgPT09IGAnYCA/IGAnJ2AgOiBgXFxcXCR7Y31gO1xuICAgIH0pXG4gICAgLmpvaW4oJycpO1xufVxuXG5mdW5jdGlvbiBsaXRlcmFsaXplUmVnZXhQYXJ0KHM6IHN0cmluZykge1xuICBjb25zdCBtYXRjaGVyMSA9IC9cXFxcUSgoPyFcXFxcRSkuKilcXFxcRSQvO1xuICBjb25zdCByZXN1bHQxOiBhbnkgPSBzLm1hdGNoKG1hdGNoZXIxKTtcbiAgaWYgKHJlc3VsdDEgJiYgcmVzdWx0MS5sZW5ndGggPiAxICYmIHJlc3VsdDEuaW5kZXggPiAtMSkge1xuICAgIC8vIHByb2Nlc3MgcmVnZXggdGhhdCBoYXMgYSBiZWdpbm5pbmcgYW5kIGFuIGVuZCBzcGVjaWZpZWQgZm9yIHRoZSBsaXRlcmFsIHRleHRcbiAgICBjb25zdCBwcmVmaXggPSBzLnN1YnN0cigwLCByZXN1bHQxLmluZGV4KTtcbiAgICBjb25zdCByZW1haW5pbmcgPSByZXN1bHQxWzFdO1xuXG4gICAgcmV0dXJuIGxpdGVyYWxpemVSZWdleFBhcnQocHJlZml4KSArIGNyZWF0ZUxpdGVyYWxSZWdleChyZW1haW5pbmcpO1xuICB9XG5cbiAgLy8gcHJvY2VzcyByZWdleCB0aGF0IGhhcyBhIGJlZ2lubmluZyBzcGVjaWZpZWQgZm9yIHRoZSBsaXRlcmFsIHRleHRcbiAgY29uc3QgbWF0Y2hlcjIgPSAvXFxcXFEoKD8hXFxcXEUpLiopJC87XG4gIGNvbnN0IHJlc3VsdDI6IGFueSA9IHMubWF0Y2gobWF0Y2hlcjIpO1xuICBpZiAocmVzdWx0MiAmJiByZXN1bHQyLmxlbmd0aCA+IDEgJiYgcmVzdWx0Mi5pbmRleCA+IC0xKSB7XG4gICAgY29uc3QgcHJlZml4ID0gcy5zdWJzdHIoMCwgcmVzdWx0Mi5pbmRleCk7XG4gICAgY29uc3QgcmVtYWluaW5nID0gcmVzdWx0MlsxXTtcblxuICAgIHJldHVybiBsaXRlcmFsaXplUmVnZXhQYXJ0KHByZWZpeCkgKyBjcmVhdGVMaXRlcmFsUmVnZXgocmVtYWluaW5nKTtcbiAgfVxuXG4gIC8vIHJlbW92ZSBhbGwgaW5zdGFuY2VzIG9mIFxcUSBhbmQgXFxFIGZyb20gdGhlIHJlbWFpbmluZyB0ZXh0ICYgZXNjYXBlIHNpbmdsZSBxdW90ZXNcbiAgcmV0dXJuIHNcbiAgICAucmVwbGFjZSgvKFteXFxcXF0pKFxcXFxFKS8sICckMScpXG4gICAgLnJlcGxhY2UoLyhbXlxcXFxdKShcXFxcUSkvLCAnJDEnKVxuICAgIC5yZXBsYWNlKC9eXFxcXEUvLCAnJylcbiAgICAucmVwbGFjZSgvXlxcXFxRLywgJycpXG4gICAgLnJlcGxhY2UoLyhbXiddKScvLCBgJDEnJ2ApXG4gICAgLnJlcGxhY2UoL14nKFteJ10pLywgYCcnJDFgKTtcbn1cblxudmFyIEdlb1BvaW50Q29kZXIgPSB7XG4gIGlzVmFsaWRKU09OKHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgIT09IG51bGwgJiYgdmFsdWUuX190eXBlID09PSAnR2VvUG9pbnQnO1xuICB9LFxufTtcblxuZXhwb3J0IGRlZmF1bHQgUG9zdGdyZXNTdG9yYWdlQWRhcHRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/sql/array/add-unique.sql b/lib/Adapters/Storage/Postgres/sql/array/add-unique.sql deleted file mode 100644 index aad90d45f5..0000000000 --- a/lib/Adapters/Storage/Postgres/sql/array/add-unique.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE OR REPLACE FUNCTION array_add_unique( - "array" jsonb, - "values" jsonb -) - RETURNS jsonb - LANGUAGE sql - IMMUTABLE - STRICT -AS $function$ - SELECT array_to_json(ARRAY(SELECT DISTINCT unnest(ARRAY(SELECT DISTINCT jsonb_array_elements("array")) || ARRAY(SELECT DISTINCT jsonb_array_elements("values")))))::jsonb; -$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/array/add.sql b/lib/Adapters/Storage/Postgres/sql/array/add.sql deleted file mode 100644 index a0b5859908..0000000000 --- a/lib/Adapters/Storage/Postgres/sql/array/add.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE OR REPLACE FUNCTION array_add( - "array" jsonb, - "values" jsonb -) - RETURNS jsonb - LANGUAGE sql - IMMUTABLE - STRICT -AS $function$ - SELECT array_to_json(ARRAY(SELECT unnest(ARRAY(SELECT DISTINCT jsonb_array_elements("array")) || ARRAY(SELECT jsonb_array_elements("values")))))::jsonb; -$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql b/lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql deleted file mode 100644 index 7ca5853a9f..0000000000 --- a/lib/Adapters/Storage/Postgres/sql/array/contains-all-regex.sql +++ /dev/null @@ -1,14 +0,0 @@ -CREATE OR REPLACE FUNCTION array_contains_all_regex( - "array" jsonb, - "values" jsonb -) - RETURNS boolean - LANGUAGE sql - IMMUTABLE - STRICT -AS $function$ - SELECT CASE - WHEN 0 = jsonb_array_length("values") THEN true = false - ELSE (SELECT RES.CNT = jsonb_array_length("values") FROM (SELECT COUNT(*) as CNT FROM jsonb_array_elements_text("array") as elt WHERE elt LIKE ANY (SELECT jsonb_array_elements_text("values"))) as RES) - END; -$function$; \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/sql/array/contains-all.sql b/lib/Adapters/Storage/Postgres/sql/array/contains-all.sql deleted file mode 100644 index 8db1ca0e7b..0000000000 --- a/lib/Adapters/Storage/Postgres/sql/array/contains-all.sql +++ /dev/null @@ -1,14 +0,0 @@ -CREATE OR REPLACE FUNCTION array_contains_all( - "array" jsonb, - "values" jsonb -) - RETURNS boolean - LANGUAGE sql - IMMUTABLE - STRICT -AS $function$ - SELECT CASE - WHEN 0 = jsonb_array_length("values") THEN true = false - ELSE (SELECT RES.CNT = jsonb_array_length("values") FROM (SELECT COUNT(*) as CNT FROM jsonb_array_elements_text("array") as elt WHERE elt IN (SELECT jsonb_array_elements_text("values"))) as RES) - END; -$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/array/contains.sql b/lib/Adapters/Storage/Postgres/sql/array/contains.sql deleted file mode 100644 index f7c458782e..0000000000 --- a/lib/Adapters/Storage/Postgres/sql/array/contains.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE OR REPLACE FUNCTION array_contains( - "array" jsonb, - "values" jsonb -) - RETURNS boolean - LANGUAGE sql - IMMUTABLE - STRICT -AS $function$ - SELECT RES.CNT >= 1 FROM (SELECT COUNT(*) as CNT FROM jsonb_array_elements("array") as elt WHERE elt IN (SELECT jsonb_array_elements("values"))) as RES; -$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/array/remove.sql b/lib/Adapters/Storage/Postgres/sql/array/remove.sql deleted file mode 100644 index 52895d2f46..0000000000 --- a/lib/Adapters/Storage/Postgres/sql/array/remove.sql +++ /dev/null @@ -1,11 +0,0 @@ -CREATE OR REPLACE FUNCTION array_remove( - "array" jsonb, - "values" jsonb -) - RETURNS jsonb - LANGUAGE sql - IMMUTABLE - STRICT -AS $function$ - SELECT array_to_json(ARRAY(SELECT * FROM jsonb_array_elements("array") as elt WHERE elt NOT IN (SELECT * FROM (SELECT jsonb_array_elements("values")) AS sub)))::jsonb; -$function$; diff --git a/lib/Adapters/Storage/Postgres/sql/index.js b/lib/Adapters/Storage/Postgres/sql/index.js deleted file mode 100644 index 2fc76f3ab1..0000000000 --- a/lib/Adapters/Storage/Postgres/sql/index.js +++ /dev/null @@ -1,35 +0,0 @@ -'use strict'; - -var QueryFile = require('pg-promise').QueryFile; - -var path = require('path'); - -module.exports = { - array: { - add: sql('array/add.sql'), - addUnique: sql('array/add-unique.sql'), - contains: sql('array/contains.sql'), - containsAll: sql('array/contains-all.sql'), - containsAllRegex: sql('array/contains-all-regex.sql'), - remove: sql('array/remove.sql') - }, - misc: { - jsonObjectSetKeys: sql('misc/json-object-set-keys.sql') - } -}; /////////////////////////////////////////////// -// Helper for linking to external query files; - -function sql(file) { - var fullPath = path.join(__dirname, file); // generating full path; - - var qf = new QueryFile(fullPath, { - minify: true - }); - - if (qf.error) { - throw qf.error; - } - - return qf; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL1Bvc3RncmVzL3NxbC9pbmRleC5qcyJdLCJuYW1lcyI6WyJRdWVyeUZpbGUiLCJyZXF1aXJlIiwicGF0aCIsIm1vZHVsZSIsImV4cG9ydHMiLCJhcnJheSIsImFkZCIsInNxbCIsImFkZFVuaXF1ZSIsImNvbnRhaW5zIiwiY29udGFpbnNBbGwiLCJjb250YWluc0FsbFJlZ2V4IiwicmVtb3ZlIiwibWlzYyIsImpzb25PYmplY3RTZXRLZXlzIiwiZmlsZSIsImZ1bGxQYXRoIiwiam9pbiIsIl9fZGlybmFtZSIsInFmIiwibWluaWZ5IiwiZXJyb3IiXSwibWFwcGluZ3MiOiJBQUFBOztBQUVBLElBQUlBLFNBQVMsR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsU0FBdEM7O0FBQ0EsSUFBSUUsSUFBSSxHQUFHRCxPQUFPLENBQUMsTUFBRCxDQUFsQjs7QUFFQUUsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZDLEVBQUFBLEtBQUssRUFBRTtBQUNMQyxJQUFBQSxHQUFHLEVBQUVDLEdBQUcsQ0FBQyxlQUFELENBREg7QUFFTEMsSUFBQUEsU0FBUyxFQUFFRCxHQUFHLENBQUMsc0JBQUQsQ0FGVDtBQUdMRSxJQUFBQSxRQUFRLEVBQUVGLEdBQUcsQ0FBQyxvQkFBRCxDQUhSO0FBSUxHLElBQUFBLFdBQVcsRUFBRUgsR0FBRyxDQUFDLHdCQUFELENBSlg7QUFLTEksSUFBQUEsZ0JBQWdCLEVBQUVKLEdBQUcsQ0FBQyw4QkFBRCxDQUxoQjtBQU1MSyxJQUFBQSxNQUFNLEVBQUVMLEdBQUcsQ0FBQyxrQkFBRDtBQU5OLEdBRFE7QUFTZk0sRUFBQUEsSUFBSSxFQUFFO0FBQ0pDLElBQUFBLGlCQUFpQixFQUFFUCxHQUFHLENBQUMsK0JBQUQ7QUFEbEI7QUFUUyxDQUFqQixDLENBY0E7QUFDQTs7QUFDQSxTQUFTQSxHQUFULENBQWFRLElBQWIsRUFBbUI7QUFDakIsTUFBSUMsUUFBUSxHQUFHZCxJQUFJLENBQUNlLElBQUwsQ0FBVUMsU0FBVixFQUFxQkgsSUFBckIsQ0FBZixDQURpQixDQUMwQjs7QUFFM0MsTUFBSUksRUFBRSxHQUFHLElBQUluQixTQUFKLENBQWNnQixRQUFkLEVBQXdCO0FBQUVJLElBQUFBLE1BQU0sRUFBRTtBQUFWLEdBQXhCLENBQVQ7O0FBRUEsTUFBSUQsRUFBRSxDQUFDRSxLQUFQLEVBQWM7QUFDWixVQUFNRixFQUFFLENBQUNFLEtBQVQ7QUFDRDs7QUFFRCxTQUFPRixFQUFQO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBRdWVyeUZpbGUgPSByZXF1aXJlKCdwZy1wcm9taXNlJykuUXVlcnlGaWxlO1xudmFyIHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBhcnJheToge1xuICAgIGFkZDogc3FsKCdhcnJheS9hZGQuc3FsJyksXG4gICAgYWRkVW5pcXVlOiBzcWwoJ2FycmF5L2FkZC11bmlxdWUuc3FsJyksXG4gICAgY29udGFpbnM6IHNxbCgnYXJyYXkvY29udGFpbnMuc3FsJyksXG4gICAgY29udGFpbnNBbGw6IHNxbCgnYXJyYXkvY29udGFpbnMtYWxsLnNxbCcpLFxuICAgIGNvbnRhaW5zQWxsUmVnZXg6IHNxbCgnYXJyYXkvY29udGFpbnMtYWxsLXJlZ2V4LnNxbCcpLFxuICAgIHJlbW92ZTogc3FsKCdhcnJheS9yZW1vdmUuc3FsJyksXG4gIH0sXG4gIG1pc2M6IHtcbiAgICBqc29uT2JqZWN0U2V0S2V5czogc3FsKCdtaXNjL2pzb24tb2JqZWN0LXNldC1rZXlzLnNxbCcpLFxuICB9LFxufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIEhlbHBlciBmb3IgbGlua2luZyB0byBleHRlcm5hbCBxdWVyeSBmaWxlcztcbmZ1bmN0aW9uIHNxbChmaWxlKSB7XG4gIHZhciBmdWxsUGF0aCA9IHBhdGguam9pbihfX2Rpcm5hbWUsIGZpbGUpOyAvLyBnZW5lcmF0aW5nIGZ1bGwgcGF0aDtcblxuICB2YXIgcWYgPSBuZXcgUXVlcnlGaWxlKGZ1bGxQYXRoLCB7IG1pbmlmeTogdHJ1ZSB9KTtcblxuICBpZiAocWYuZXJyb3IpIHtcbiAgICB0aHJvdyBxZi5lcnJvcjtcbiAgfVxuXG4gIHJldHVybiBxZjtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql b/lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql deleted file mode 100644 index eb28b36928..0000000000 --- a/lib/Adapters/Storage/Postgres/sql/misc/json-object-set-keys.sql +++ /dev/null @@ -1,19 +0,0 @@ --- Function to set a key on a nested JSON document - -CREATE OR REPLACE FUNCTION json_object_set_key( - "json" jsonb, - key_to_set TEXT, - value_to_set anyelement -) - RETURNS jsonb - LANGUAGE sql - IMMUTABLE - STRICT -AS $function$ -SELECT concat('{', string_agg(to_json("key") || ':' || "value", ','), '}')::jsonb - FROM (SELECT * - FROM jsonb_each("json") - WHERE key <> key_to_set - UNION ALL - SELECT key_to_set, to_json("value_to_set")::jsonb) AS fields -$function$; diff --git a/lib/Adapters/Storage/StorageAdapter.js b/lib/Adapters/Storage/StorageAdapter.js deleted file mode 100644 index 4310b4ffac..0000000000 --- a/lib/Adapters/Storage/StorageAdapter.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbXX0= \ No newline at end of file diff --git a/lib/Adapters/WebSocketServer/WSAdapter.js b/lib/Adapters/WebSocketServer/WSAdapter.js deleted file mode 100644 index bfd5224448..0000000000 --- a/lib/Adapters/WebSocketServer/WSAdapter.js +++ /dev/null @@ -1,45 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.WSAdapter = void 0; - -var _WSSAdapter = require("./WSSAdapter"); - -/*eslint no-unused-vars: "off"*/ -const WebSocketServer = require('ws').Server; -/** - * Wrapper for ws node module - */ - - -class WSAdapter extends _WSSAdapter.WSSAdapter { - constructor(options) { - super(options); - this.options = options; - } - - onListen() {} - - onConnection(ws) {} - - onError(error) {} - - start() { - const wss = new WebSocketServer({ - server: this.options.server - }); - wss.on('listening', this.onListen); - wss.on('connection', this.onConnection); - wss.on('error', this.onError); - } - - close() {} - -} - -exports.WSAdapter = WSAdapter; -var _default = WSAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9XZWJTb2NrZXRTZXJ2ZXIvV1NBZGFwdGVyLmpzIl0sIm5hbWVzIjpbIldlYlNvY2tldFNlcnZlciIsInJlcXVpcmUiLCJTZXJ2ZXIiLCJXU0FkYXB0ZXIiLCJXU1NBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJvcHRpb25zIiwib25MaXN0ZW4iLCJvbkNvbm5lY3Rpb24iLCJ3cyIsIm9uRXJyb3IiLCJlcnJvciIsInN0YXJ0Iiwid3NzIiwic2VydmVyIiwib24iLCJjbG9zZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUNBOztBQURBO0FBRUEsTUFBTUEsZUFBZSxHQUFHQyxPQUFPLENBQUMsSUFBRCxDQUFQLENBQWNDLE1BQXRDO0FBRUE7QUFDQTtBQUNBOzs7QUFDTyxNQUFNQyxTQUFOLFNBQXdCQyxzQkFBeEIsQ0FBbUM7QUFDeENDLEVBQUFBLFdBQVcsQ0FBQ0MsT0FBRCxFQUFlO0FBQ3hCLFVBQU1BLE9BQU47QUFDQSxTQUFLQSxPQUFMLEdBQWVBLE9BQWY7QUFDRDs7QUFFREMsRUFBQUEsUUFBUSxHQUFHLENBQUU7O0FBQ2JDLEVBQUFBLFlBQVksQ0FBQ0MsRUFBRCxFQUFLLENBQUU7O0FBQ25CQyxFQUFBQSxPQUFPLENBQUNDLEtBQUQsRUFBUSxDQUFFOztBQUNqQkMsRUFBQUEsS0FBSyxHQUFHO0FBQ04sVUFBTUMsR0FBRyxHQUFHLElBQUliLGVBQUosQ0FBb0I7QUFBRWMsTUFBQUEsTUFBTSxFQUFFLEtBQUtSLE9BQUwsQ0FBYVE7QUFBdkIsS0FBcEIsQ0FBWjtBQUNBRCxJQUFBQSxHQUFHLENBQUNFLEVBQUosQ0FBTyxXQUFQLEVBQW9CLEtBQUtSLFFBQXpCO0FBQ0FNLElBQUFBLEdBQUcsQ0FBQ0UsRUFBSixDQUFPLFlBQVAsRUFBcUIsS0FBS1AsWUFBMUI7QUFDQUssSUFBQUEsR0FBRyxDQUFDRSxFQUFKLENBQU8sT0FBUCxFQUFnQixLQUFLTCxPQUFyQjtBQUNEOztBQUNETSxFQUFBQSxLQUFLLEdBQUcsQ0FBRTs7QUFmOEI7OztlQWtCM0JiLFMiLCJzb3VyY2VzQ29udGVudCI6WyIvKmVzbGludCBuby11bnVzZWQtdmFyczogXCJvZmZcIiovXG5pbXBvcnQgeyBXU1NBZGFwdGVyIH0gZnJvbSAnLi9XU1NBZGFwdGVyJztcbmNvbnN0IFdlYlNvY2tldFNlcnZlciA9IHJlcXVpcmUoJ3dzJykuU2VydmVyO1xuXG4vKipcbiAqIFdyYXBwZXIgZm9yIHdzIG5vZGUgbW9kdWxlXG4gKi9cbmV4cG9ydCBjbGFzcyBXU0FkYXB0ZXIgZXh0ZW5kcyBXU1NBZGFwdGVyIHtcbiAgY29uc3RydWN0b3Iob3B0aW9uczogYW55KSB7XG4gICAgc3VwZXIob3B0aW9ucyk7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgfVxuXG4gIG9uTGlzdGVuKCkge31cbiAgb25Db25uZWN0aW9uKHdzKSB7fVxuICBvbkVycm9yKGVycm9yKSB7fVxuICBzdGFydCgpIHtcbiAgICBjb25zdCB3c3MgPSBuZXcgV2ViU29ja2V0U2VydmVyKHsgc2VydmVyOiB0aGlzLm9wdGlvbnMuc2VydmVyIH0pO1xuICAgIHdzcy5vbignbGlzdGVuaW5nJywgdGhpcy5vbkxpc3Rlbik7XG4gICAgd3NzLm9uKCdjb25uZWN0aW9uJywgdGhpcy5vbkNvbm5lY3Rpb24pO1xuICAgIHdzcy5vbignZXJyb3InLCB0aGlzLm9uRXJyb3IpO1xuICB9XG4gIGNsb3NlKCkge31cbn1cblxuZXhwb3J0IGRlZmF1bHQgV1NBZGFwdGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Adapters/WebSocketServer/WSSAdapter.js b/lib/Adapters/WebSocketServer/WSSAdapter.js deleted file mode 100644 index 1b29837db0..0000000000 --- a/lib/Adapters/WebSocketServer/WSSAdapter.js +++ /dev/null @@ -1,74 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.WSSAdapter = void 0; - -/*eslint no-unused-vars: "off"*/ -// WebSocketServer Adapter -// -// Adapter classes must implement the following functions: -// * onListen() -// * onConnection(ws) -// * onError(error) -// * start() -// * close() -// -// Default is WSAdapter. The above functions will be binded. - -/** - * @module Adapters - */ - -/** - * @interface WSSAdapter - */ -class WSSAdapter { - /** - * @param {Object} options - {http.Server|https.Server} server - */ - constructor(options) { - this.onListen = () => {}; - - this.onConnection = () => {}; - - this.onError = () => {}; - } // /** - // * Emitted when the underlying server has been bound. - // */ - // onListen() {} - // /** - // * Emitted when the handshake is complete. - // * - // * @param {WebSocket} ws - RFC 6455 WebSocket. - // */ - // onConnection(ws) {} - // /** - // * Emitted when error event is called. - // * - // * @param {Error} error - WebSocketServer error - // */ - // onError(error) {} - - /** - * Initialize Connection. - * - * @param {Object} options - */ - - - start(options) {} - /** - * Closes server. - */ - - - close() {} - -} - -exports.WSSAdapter = WSSAdapter; -var _default = WSSAdapter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9BZGFwdGVycy9XZWJTb2NrZXRTZXJ2ZXIvV1NTQWRhcHRlci5qcyJdLCJuYW1lcyI6WyJXU1NBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJvcHRpb25zIiwib25MaXN0ZW4iLCJvbkNvbm5lY3Rpb24iLCJvbkVycm9yIiwic3RhcnQiLCJjbG9zZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU1BLFVBQU4sQ0FBaUI7QUFDdEI7QUFDRjtBQUNBO0FBQ0VDLEVBQUFBLFdBQVcsQ0FBQ0MsT0FBRCxFQUFVO0FBQ25CLFNBQUtDLFFBQUwsR0FBZ0IsTUFBTSxDQUFFLENBQXhCOztBQUNBLFNBQUtDLFlBQUwsR0FBb0IsTUFBTSxDQUFFLENBQTVCOztBQUNBLFNBQUtDLE9BQUwsR0FBZSxNQUFNLENBQUUsQ0FBdkI7QUFDRCxHQVJxQixDQVV0QjtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNGO0FBQ0E7QUFDQTtBQUNBOzs7QUFDRUMsRUFBQUEsS0FBSyxDQUFDSixPQUFELEVBQVUsQ0FBRTtBQUVqQjtBQUNGO0FBQ0E7OztBQUNFSyxFQUFBQSxLQUFLLEdBQUcsQ0FBRTs7QUF2Q1k7OztlQTBDVFAsVSIsInNvdXJjZXNDb250ZW50IjpbIi8qZXNsaW50IG5vLXVudXNlZC12YXJzOiBcIm9mZlwiKi9cbi8vIFdlYlNvY2tldFNlcnZlciBBZGFwdGVyXG4vL1xuLy8gQWRhcHRlciBjbGFzc2VzIG11c3QgaW1wbGVtZW50IHRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zOlxuLy8gKiBvbkxpc3RlbigpXG4vLyAqIG9uQ29ubmVjdGlvbih3cylcbi8vICogb25FcnJvcihlcnJvcilcbi8vICogc3RhcnQoKVxuLy8gKiBjbG9zZSgpXG4vL1xuLy8gRGVmYXVsdCBpcyBXU0FkYXB0ZXIuIFRoZSBhYm92ZSBmdW5jdGlvbnMgd2lsbCBiZSBiaW5kZWQuXG5cbi8qKlxuICogQG1vZHVsZSBBZGFwdGVyc1xuICovXG4vKipcbiAqIEBpbnRlcmZhY2UgV1NTQWRhcHRlclxuICovXG5leHBvcnQgY2xhc3MgV1NTQWRhcHRlciB7XG4gIC8qKlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIHtodHRwLlNlcnZlcnxodHRwcy5TZXJ2ZXJ9IHNlcnZlclxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9ucykge1xuICAgIHRoaXMub25MaXN0ZW4gPSAoKSA9PiB7fTtcbiAgICB0aGlzLm9uQ29ubmVjdGlvbiA9ICgpID0+IHt9O1xuICAgIHRoaXMub25FcnJvciA9ICgpID0+IHt9O1xuICB9XG5cbiAgLy8gLyoqXG4gIC8vICAqIEVtaXR0ZWQgd2hlbiB0aGUgdW5kZXJseWluZyBzZXJ2ZXIgaGFzIGJlZW4gYm91bmQuXG4gIC8vICAqL1xuICAvLyBvbkxpc3RlbigpIHt9XG5cbiAgLy8gLyoqXG4gIC8vICAqIEVtaXR0ZWQgd2hlbiB0aGUgaGFuZHNoYWtlIGlzIGNvbXBsZXRlLlxuICAvLyAgKlxuICAvLyAgKiBAcGFyYW0ge1dlYlNvY2tldH0gd3MgLSBSRkMgNjQ1NSBXZWJTb2NrZXQuXG4gIC8vICAqL1xuICAvLyBvbkNvbm5lY3Rpb24od3MpIHt9XG5cbiAgLy8gLyoqXG4gIC8vICAqIEVtaXR0ZWQgd2hlbiBlcnJvciBldmVudCBpcyBjYWxsZWQuXG4gIC8vICAqXG4gIC8vICAqIEBwYXJhbSB7RXJyb3J9IGVycm9yIC0gV2ViU29ja2V0U2VydmVyIGVycm9yXG4gIC8vICAqL1xuICAvLyBvbkVycm9yKGVycm9yKSB7fVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplIENvbm5lY3Rpb24uXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAqL1xuICBzdGFydChvcHRpb25zKSB7fVxuXG4gIC8qKlxuICAgKiBDbG9zZXMgc2VydmVyLlxuICAgKi9cbiAgY2xvc2UoKSB7fVxufVxuXG5leHBvcnQgZGVmYXVsdCBXU1NBZGFwdGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Auth.js b/lib/Auth.js deleted file mode 100644 index 7fe33b66de..0000000000 --- a/lib/Auth.js +++ /dev/null @@ -1,373 +0,0 @@ -"use strict"; - -const cryptoUtils = require('./cryptoUtils'); - -const RestQuery = require('./RestQuery'); - -const Parse = require('parse/node'); // An Auth object tells you who is requesting something and whether -// the master key was used. -// userObject is a Parse.User and can be null if there's no user. - - -function Auth({ - config, - cacheController = undefined, - isMaster = false, - isReadOnly = false, - user, - installationId -}) { - this.config = config; - this.cacheController = cacheController || config && config.cacheController; - this.installationId = installationId; - this.isMaster = isMaster; - this.user = user; - this.isReadOnly = isReadOnly; // Assuming a users roles won't change during a single request, we'll - // only load them once. - - this.userRoles = []; - this.fetchedRoles = false; - this.rolePromise = null; -} // Whether this auth could possibly modify the given user id. -// It still could be forbidden via ACLs even if this returns true. - - -Auth.prototype.isUnauthenticated = function () { - if (this.isMaster) { - return false; - } - - if (this.user) { - return false; - } - - return true; -}; // A helper to get a master-level Auth object - - -function master(config) { - return new Auth({ - config, - isMaster: true - }); -} // A helper to get a master-level Auth object - - -function readOnly(config) { - return new Auth({ - config, - isMaster: true, - isReadOnly: true - }); -} // A helper to get a nobody-level Auth object - - -function nobody(config) { - return new Auth({ - config, - isMaster: false - }); -} // Returns a promise that resolves to an Auth object - - -const getAuthForSessionToken = async function ({ - config, - cacheController, - sessionToken, - installationId -}) { - cacheController = cacheController || config && config.cacheController; - - if (cacheController) { - const userJSON = await cacheController.user.get(sessionToken); - - if (userJSON) { - const cachedUser = Parse.Object.fromJSON(userJSON); - return Promise.resolve(new Auth({ - config, - cacheController, - isMaster: false, - installationId, - user: cachedUser - })); - } - } - - let results; - - if (config) { - const restOptions = { - limit: 1, - include: 'user' - }; - const query = new RestQuery(config, master(config), '_Session', { - sessionToken - }, restOptions); - results = (await query.execute()).results; - } else { - results = (await new Parse.Query(Parse.Session).limit(1).include('user').equalTo('sessionToken', sessionToken).find({ - useMasterKey: true - })).map(obj => obj.toJSON()); - } - - if (results.length !== 1 || !results[0]['user']) { - throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); - } - - const now = new Date(), - expiresAt = results[0].expiresAt ? new Date(results[0].expiresAt.iso) : undefined; - - if (expiresAt < now) { - throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Session token is expired.'); - } - - const obj = results[0]['user']; - delete obj.password; - obj['className'] = '_User'; - obj['sessionToken'] = sessionToken; - - if (cacheController) { - cacheController.user.put(sessionToken, obj); - } - - const userObject = Parse.Object.fromJSON(obj); - return new Auth({ - config, - cacheController, - isMaster: false, - installationId, - user: userObject - }); -}; - -var getAuthForLegacySessionToken = function ({ - config, - sessionToken, - installationId -}) { - var restOptions = { - limit: 1 - }; - var query = new RestQuery(config, master(config), '_User', { - sessionToken - }, restOptions); - return query.execute().then(response => { - var results = response.results; - - if (results.length !== 1) { - throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'invalid legacy session token'); - } - - const obj = results[0]; - obj.className = '_User'; - const userObject = Parse.Object.fromJSON(obj); - return new Auth({ - config, - isMaster: false, - installationId, - user: userObject - }); - }); -}; // Returns a promise that resolves to an array of role names - - -Auth.prototype.getUserRoles = function () { - if (this.isMaster || !this.user) { - return Promise.resolve([]); - } - - if (this.fetchedRoles) { - return Promise.resolve(this.userRoles); - } - - if (this.rolePromise) { - return this.rolePromise; - } - - this.rolePromise = this._loadRoles(); - return this.rolePromise; -}; - -Auth.prototype.getRolesForUser = async function () { - //Stack all Parse.Role - const results = []; - - if (this.config) { - const restWhere = { - users: { - __type: 'Pointer', - className: '_User', - objectId: this.user.id - } - }; - await new RestQuery(this.config, master(this.config), '_Role', restWhere, {}).each(result => results.push(result)); - } else { - await new Parse.Query(Parse.Role).equalTo('users', this.user).each(result => results.push(result.toJSON()), { - useMasterKey: true - }); - } - - return results; -}; // Iterates through the role tree and compiles a user's roles - - -Auth.prototype._loadRoles = async function () { - if (this.cacheController) { - const cachedRoles = await this.cacheController.role.get(this.user.id); - - if (cachedRoles != null) { - this.fetchedRoles = true; - this.userRoles = cachedRoles; - return cachedRoles; - } - } // First get the role ids this user is directly a member of - - - const results = await this.getRolesForUser(); - - if (!results.length) { - this.userRoles = []; - this.fetchedRoles = true; - this.rolePromise = null; - this.cacheRoles(); - return this.userRoles; - } - - const rolesMap = results.reduce((m, r) => { - m.names.push(r.name); - m.ids.push(r.objectId); - return m; - }, { - ids: [], - names: [] - }); // run the recursive finding - - const roleNames = await this._getAllRolesNamesForRoleIds(rolesMap.ids, rolesMap.names); - this.userRoles = roleNames.map(r => { - return 'role:' + r; - }); - this.fetchedRoles = true; - this.rolePromise = null; - this.cacheRoles(); - return this.userRoles; -}; - -Auth.prototype.cacheRoles = function () { - if (!this.cacheController) { - return false; - } - - this.cacheController.role.put(this.user.id, Array(...this.userRoles)); - return true; -}; - -Auth.prototype.getRolesByIds = async function (ins) { - const results = []; // Build an OR query across all parentRoles - - if (!this.config) { - await new Parse.Query(Parse.Role).containedIn('roles', ins.map(id => { - const role = new Parse.Object(Parse.Role); - role.id = id; - return role; - })).each(result => results.push(result.toJSON()), { - useMasterKey: true - }); - } else { - const roles = ins.map(id => { - return { - __type: 'Pointer', - className: '_Role', - objectId: id - }; - }); - const restWhere = { - roles: { - $in: roles - } - }; - await new RestQuery(this.config, master(this.config), '_Role', restWhere, {}).each(result => results.push(result)); - } - - return results; -}; // Given a list of roleIds, find all the parent roles, returns a promise with all names - - -Auth.prototype._getAllRolesNamesForRoleIds = function (roleIDs, names = [], queriedRoles = {}) { - const ins = roleIDs.filter(roleID => { - const wasQueried = queriedRoles[roleID] !== true; - queriedRoles[roleID] = true; - return wasQueried; - }); // all roles are accounted for, return the names - - if (ins.length == 0) { - return Promise.resolve([...new Set(names)]); - } - - return this.getRolesByIds(ins).then(results => { - // Nothing found - if (!results.length) { - return Promise.resolve(names); - } // Map the results with all Ids and names - - - const resultMap = results.reduce((memo, role) => { - memo.names.push(role.name); - memo.ids.push(role.objectId); - return memo; - }, { - ids: [], - names: [] - }); // store the new found names - - names = names.concat(resultMap.names); // find the next ones, circular roles will be cut - - return this._getAllRolesNamesForRoleIds(resultMap.ids, names, queriedRoles); - }).then(names => { - return Promise.resolve([...new Set(names)]); - }); -}; - -const createSession = function (config, { - userId, - createdWith, - installationId, - additionalSessionData -}) { - const token = 'r:' + cryptoUtils.newToken(); - const expiresAt = config.generateSessionExpiresAt(); - const sessionData = { - sessionToken: token, - user: { - __type: 'Pointer', - className: '_User', - objectId: userId - }, - createdWith, - restricted: false, - expiresAt: Parse._encode(expiresAt) - }; - - if (installationId) { - sessionData.installationId = installationId; - } - - Object.assign(sessionData, additionalSessionData); // We need to import RestWrite at this point for the cyclic dependency it has to it - - const RestWrite = require('./RestWrite'); - - return { - sessionData, - createSession: () => new RestWrite(config, master(config), '_Session', null, sessionData).execute() - }; -}; - -module.exports = { - Auth, - master, - nobody, - readOnly, - getAuthForSessionToken, - getAuthForLegacySessionToken, - createSession -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9BdXRoLmpzIl0sIm5hbWVzIjpbImNyeXB0b1V0aWxzIiwicmVxdWlyZSIsIlJlc3RRdWVyeSIsIlBhcnNlIiwiQXV0aCIsImNvbmZpZyIsImNhY2hlQ29udHJvbGxlciIsInVuZGVmaW5lZCIsImlzTWFzdGVyIiwiaXNSZWFkT25seSIsInVzZXIiLCJpbnN0YWxsYXRpb25JZCIsInVzZXJSb2xlcyIsImZldGNoZWRSb2xlcyIsInJvbGVQcm9taXNlIiwicHJvdG90eXBlIiwiaXNVbmF1dGhlbnRpY2F0ZWQiLCJtYXN0ZXIiLCJyZWFkT25seSIsIm5vYm9keSIsImdldEF1dGhGb3JTZXNzaW9uVG9rZW4iLCJzZXNzaW9uVG9rZW4iLCJ1c2VySlNPTiIsImdldCIsImNhY2hlZFVzZXIiLCJPYmplY3QiLCJmcm9tSlNPTiIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVzdWx0cyIsInJlc3RPcHRpb25zIiwibGltaXQiLCJpbmNsdWRlIiwicXVlcnkiLCJleGVjdXRlIiwiUXVlcnkiLCJTZXNzaW9uIiwiZXF1YWxUbyIsImZpbmQiLCJ1c2VNYXN0ZXJLZXkiLCJtYXAiLCJvYmoiLCJ0b0pTT04iLCJsZW5ndGgiLCJFcnJvciIsIklOVkFMSURfU0VTU0lPTl9UT0tFTiIsIm5vdyIsIkRhdGUiLCJleHBpcmVzQXQiLCJpc28iLCJwYXNzd29yZCIsInB1dCIsInVzZXJPYmplY3QiLCJnZXRBdXRoRm9yTGVnYWN5U2Vzc2lvblRva2VuIiwidGhlbiIsInJlc3BvbnNlIiwiY2xhc3NOYW1lIiwiZ2V0VXNlclJvbGVzIiwiX2xvYWRSb2xlcyIsImdldFJvbGVzRm9yVXNlciIsInJlc3RXaGVyZSIsInVzZXJzIiwiX190eXBlIiwib2JqZWN0SWQiLCJpZCIsImVhY2giLCJyZXN1bHQiLCJwdXNoIiwiUm9sZSIsImNhY2hlZFJvbGVzIiwicm9sZSIsImNhY2hlUm9sZXMiLCJyb2xlc01hcCIsInJlZHVjZSIsIm0iLCJyIiwibmFtZXMiLCJuYW1lIiwiaWRzIiwicm9sZU5hbWVzIiwiX2dldEFsbFJvbGVzTmFtZXNGb3JSb2xlSWRzIiwiQXJyYXkiLCJnZXRSb2xlc0J5SWRzIiwiaW5zIiwiY29udGFpbmVkSW4iLCJyb2xlcyIsIiRpbiIsInJvbGVJRHMiLCJxdWVyaWVkUm9sZXMiLCJmaWx0ZXIiLCJyb2xlSUQiLCJ3YXNRdWVyaWVkIiwiU2V0IiwicmVzdWx0TWFwIiwibWVtbyIsImNvbmNhdCIsImNyZWF0ZVNlc3Npb24iLCJ1c2VySWQiLCJjcmVhdGVkV2l0aCIsImFkZGl0aW9uYWxTZXNzaW9uRGF0YSIsInRva2VuIiwibmV3VG9rZW4iLCJnZW5lcmF0ZVNlc3Npb25FeHBpcmVzQXQiLCJzZXNzaW9uRGF0YSIsInJlc3RyaWN0ZWQiLCJfZW5jb2RlIiwiYXNzaWduIiwiUmVzdFdyaXRlIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQSxNQUFNQSxXQUFXLEdBQUdDLE9BQU8sQ0FBQyxlQUFELENBQTNCOztBQUNBLE1BQU1DLFNBQVMsR0FBR0QsT0FBTyxDQUFDLGFBQUQsQ0FBekI7O0FBQ0EsTUFBTUUsS0FBSyxHQUFHRixPQUFPLENBQUMsWUFBRCxDQUFyQixDLENBRUE7QUFDQTtBQUNBOzs7QUFDQSxTQUFTRyxJQUFULENBQWM7QUFDWkMsRUFBQUEsTUFEWTtBQUVaQyxFQUFBQSxlQUFlLEdBQUdDLFNBRk47QUFHWkMsRUFBQUEsUUFBUSxHQUFHLEtBSEM7QUFJWkMsRUFBQUEsVUFBVSxHQUFHLEtBSkQ7QUFLWkMsRUFBQUEsSUFMWTtBQU1aQyxFQUFBQTtBQU5ZLENBQWQsRUFPRztBQUNELE9BQUtOLE1BQUwsR0FBY0EsTUFBZDtBQUNBLE9BQUtDLGVBQUwsR0FBdUJBLGVBQWUsSUFBS0QsTUFBTSxJQUFJQSxNQUFNLENBQUNDLGVBQTVEO0FBQ0EsT0FBS0ssY0FBTCxHQUFzQkEsY0FBdEI7QUFDQSxPQUFLSCxRQUFMLEdBQWdCQSxRQUFoQjtBQUNBLE9BQUtFLElBQUwsR0FBWUEsSUFBWjtBQUNBLE9BQUtELFVBQUwsR0FBa0JB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LGNBQUosRUFBb0I7QUFDbEI0RixJQUFBQSxXQUFXLENBQUM1RixjQUFaLEdBQTZCQSxjQUE3QjtBQUNEOztBQUVEYyxFQUFBQSxNQUFNLENBQUNpRixNQUFQLENBQWNILFdBQWQsRUFBMkJKLHFCQUEzQixFQW5CQSxDQW9CQTs7QUFDQSxRQUFNUSxTQUFTLEdBQUcxRyxPQUFPLENBQUMsYUFBRCxDQUF6Qjs7QUFFQSxTQUFPO0FBQ0xzRyxJQUFBQSxXQURLO0FBRUxQLElBQUFBLGFBQWEsRUFBRSxNQUNiLElBQUlXLFNBQUosQ0FBY3RHLE1BQWQsRUFBc0JZLE1BQU0sQ0FBQ1osTUFBRCxDQUE1QixFQUFzQyxVQUF0QyxFQUFrRCxJQUFsRCxFQUF3RGtHLFdBQXhELEVBQXFFckUsT0FBckU7QUFIRyxHQUFQO0FBS0QsQ0EvQkQ7O0FBaUNBMEUsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2Z6RyxFQUFBQSxJQURlO0FBRWZhLEVBQUFBLE1BRmU7QUFHZkUsRUFBQUEsTUFIZTtBQUlmRCxFQUFBQSxRQUplO0FBS2ZFLEVBQUFBLHNCQUxlO0FBTWZpQyxFQUFBQSw0QkFOZTtBQU9mMkMsRUFBQUE7QUFQZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGNyeXB0b1V0aWxzID0gcmVxdWlyZSgnLi9jcnlwdG9VdGlscycpO1xuY29uc3QgUmVzdFF1ZXJ5ID0gcmVxdWlyZSgnLi9SZXN0UXVlcnknKTtcbmNvbnN0IFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpO1xuXG4vLyBBbiBBdXRoIG9iamVjdCB0ZWxscyB5b3Ugd2hvIGlzIHJlcXVlc3Rpbmcgc29tZXRoaW5nIGFuZCB3aGV0aGVyXG4vLyB0aGUgbWFzdGVyIGtleSB3YXMgdXNlZC5cbi8vIHVzZXJPYmplY3QgaXMgYSBQYXJzZS5Vc2VyIGFuZCBjYW4gYmUgbnVsbCBpZiB0aGVyZSdzIG5vIHVzZXIuXG5mdW5jdGlvbiBBdXRoKHtcbiAgY29uZmlnLFxuICBjYWNoZUNvbnRyb2xsZXIgPSB1bmRlZmluZWQsXG4gIGlzTWFzdGVyID0gZmFsc2UsXG4gIGlzUmVhZE9ubHkgPSBmYWxzZSxcbiAgdXNlcixcbiAgaW5zdGFsbGF0aW9uSWQsXG59KSB7XG4gIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICB0aGlzLmNhY2hlQ29udHJvbGxlciA9IGNhY2hlQ29udHJvbGxlciB8fCAoY29uZmlnICYmIGNvbmZpZy5jYWNoZUNvbnRyb2xsZXIpO1xuICB0aGlzLmluc3RhbGxhdGlvbklkID0gaW5zdGFsbGF0aW9uSWQ7XG4gIHRoaXMuaXNNYXN0ZXIgPSBpc01hc3RlcjtcbiAgdGhpcy51c2VyID0gdXNlcjtcbiAgdGhpcy5pc1JlYWRPbmx5ID0gaXNSZWFkT25seTtcblxuICAvLyBBc3N1bWluZyBhIHVzZXJzIHJvbGVzIHdvbid0IGNoYW5nZSBkdXJpbmcgYSBzaW5nbGUgcmVxdWVzdCwgd2UnbGxcbiAgLy8gb25seSBsb2FkIHRoZW0gb25jZS5cbiAgdGhpcy51c2VyUm9sZXMgPSBbXTtcbiAgdGhpcy5mZXRjaGVkUm9sZXMgPSBmYWxzZTtcbiAgdGhpcy5yb2xlUHJvbWlzZSA9IG51bGw7XG59XG5cbi8vIFdoZXRoZXIgdGhpcyBhdXRoIGNvdWxkIHBvc3NpYmx5IG1vZGlmeSB0aGUgZ2l2ZW4gdXNlciBpZC5cbi8vIEl0IHN0aWxsIGNvdWxkIGJlIGZvcmJpZGRlbiB2aWEgQUNMcyBldmVuIGlmIHRoaXMgcmV0dXJucyB0cnVlLlxuQXV0aC5wcm90b3R5cGUuaXNVbmF1dGhlbnRpY2F0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmlzTWFzdGVyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICh0aGlzLnVzZXIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59O1xuXG4vLyBBIGhlbHBlciB0byBnZXQgYSBtYXN0ZXItbGV2ZWwgQXV0aCBvYmplY3RcbmZ1bmN0aW9uIG1hc3Rlcihjb25maWcpIHtcbiAgcmV0dXJuIG5ldyBBdXRoKHsgY29uZmlnLCBpc01hc3RlcjogdHJ1ZSB9KTtcbn1cblxuLy8gQSBoZWxwZXIgdG8gZ2V0IGEgbWFzdGVyLWxldmVsIEF1dGggb2JqZWN0XG5mdW5jdGlvbiByZWFkT25seShjb25maWcpIHtcbiAgcmV0dXJuIG5ldyBBdXRoKHsgY29uZmlnLCBpc01hc3RlcjogdHJ1ZSwgaXNSZWFkT25seTogdHJ1ZSB9KTtcbn1cblxuLy8gQSBoZWxwZXIgdG8gZ2V0IGEgbm9ib2R5LWxldmVsIEF1dGggb2JqZWN0XG5mdW5jdGlvbiBub2JvZHkoY29uZmlnKSB7XG4gIHJldHVybiBuZXcgQXV0aCh7IGNvbmZpZywgaXNNYXN0ZXI6IGZhbHNlIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIEF1dGggb2JqZWN0XG5jb25zdCBnZXRBdXRoRm9yU2Vzc2lvblRva2VuID0gYXN5bmMgZnVuY3Rpb24gKHtcbiAgY29uZmlnLFxuICBjYWNoZUNvbnRyb2xsZXIsXG4gIHNlc3Npb25Ub2tlbixcbiAgaW5zdGFsbGF0aW9uSWQsXG59KSB7XG4gIGNhY2hlQ29udHJvbGxlciA9IGNhY2hlQ29udHJvbGxlciB8fCAoY29uZmlnICYmIGNvbmZpZy5jYWNoZUNvbnRyb2xsZXIpO1xuICBpZiAoY2FjaGVDb250cm9sbGVyKSB7XG4gICAgY29uc3QgdXNlckpTT04gPSBhd2FpdCBjYWNoZUNvbnRyb2xsZXIudXNlci5nZXQoc2Vzc2lvblRva2VuKTtcbiAgICBpZiAodXNlckpTT04pIHtcbiAgICAgIGNvbnN0IGNhY2hlZFVzZXIgPSBQYXJzZS5PYmplY3QuZnJvbUpTT04odXNlckpTT04pO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShcbiAgICAgICAgbmV3IEF1dGgoe1xuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICBjYWNoZUNvbnRyb2xsZXIsXG4gICAgICAgICAgaXNNYXN0ZXI6IGZhbHNlLFxuICAgICAgICAgIGluc3RhbGxhdGlvbklkLFxuICAgICAgICAgIHVzZXI6IGNhY2hlZFVzZXIsXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGxldCByZXN1bHRzO1xuICBpZiAoY29uZmlnKSB7XG4gICAgY29uc3QgcmVzdE9wdGlvbnMgPSB7XG4gICAgICBsaW1pdDogMSxcbiAgICAgIGluY2x1ZGU6ICd1c2VyJyxcbiAgICB9O1xuXG4gICAgY29uc3QgcXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KGNvbmZpZywgbWFzdGVyKGNvbmZpZyksICdfU2Vzc2lvbicsIHsgc2Vzc2lvblRva2VuIH0sIHJlc3RPcHRpb25zKTtcbiAgICByZXN1bHRzID0gKGF3YWl0IHF1ZXJ5LmV4ZWN1dGUoKSkucmVzdWx0cztcbiAgfSBlbHNlIHtcbiAgICByZXN1bHRzID0gKFxuICAgICAgYXdhaXQgbmV3IFBhcnNlLlF1ZXJ5KFBhcnNlLlNlc3Npb24pXG4gICAgICAgIC5saW1pdCgxKVxuICAgICAgICAuaW5jbHVkZSgndXNlcicpXG4gICAgICAgIC5lcXVhbFRvKCdzZXNzaW9uVG9rZW4nLCBzZXNzaW9uVG9rZW4pXG4gICAgICAgIC5maW5kKHsgdXNlTWFzdGVyS2V5OiB0cnVlIH0pXG4gICAgKS5tYXAob2JqID0+IG9iai50b0pTT04oKSk7XG4gIH1cblxuICBpZiAocmVzdWx0cy5sZW5ndGggIT09IDEgfHwgIXJlc3VsdHNbMF1bJ3VzZXInXSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdJbnZhbGlkIHNlc3Npb24gdG9rZW4nKTtcbiAgfVxuICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpLFxuICAgIGV4cGlyZXNBdCA9IHJlc3VsdHNbMF0uZXhwaXJlc0F0ID8gbmV3IERhdGUocmVzdWx0c1swXS5leHBpcmVzQXQuaXNvKSA6IHVuZGVmaW5lZDtcbiAgaWYgKGV4cGlyZXNBdCA8IG5vdykge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdTZXNzaW9uIHRva2VuIGlzIGV4cGlyZWQuJyk7XG4gIH1cbiAgY29uc3Qgb2JqID0gcmVzdWx0c1swXVsndXNlciddO1xuICBkZWxldGUgb2JqLnBhc3N3b3JkO1xuICBvYmpbJ2NsYXNzTmFtZSddID0gJ19Vc2VyJztcbiAgb2JqWydzZXNzaW9uVG9rZW4nXSA9IHNlc3Npb25Ub2tlbjtcbiAgaWYgKGNhY2hlQ29udHJvbGxlcikge1xuICAgIGNhY2hlQ29udHJvbGxlci51c2VyLnB1dChzZXNzaW9uVG9rZW4sIG9iaik7XG4gIH1cbiAgY29uc3QgdXNlck9iamVjdCA9IFBhcnNlLk9iamVjdC5mcm9tSlNPTihvYmopO1xuICByZXR1cm4gbmV3IEF1dGgoe1xuICAgIGNvbmZpZyxcbiAgICBjYWNoZUNvbnRyb2xsZXIsXG4gICAgaXNNYXN0ZXI6IGZhbHNlLFxuICAgIGluc3RhbGxhdGlvbklkLFxuICAgIHVzZXI6IHVzZXJPYmplY3QsXG4gIH0pO1xufTtcblxudmFyIGdldEF1dGhGb3JMZWdhY3lTZXNzaW9uVG9rZW4gPSBmdW5jdGlvbiAoeyBjb25maWcsIHNlc3Npb25Ub2tlbiwgaW5zdGFsbGF0aW9uSWQgfSkge1xuICB2YXIgcmVzdE9wdGlvbnMgPSB7XG4gICAgbGltaXQ6IDEsXG4gIH07XG4gIHZhciBxdWVyeSA9IG5ldyBSZXN0UXVlcnkoY29uZmlnLCBtYXN0ZXIoY29uZmlnKSwgJ19Vc2VyJywgeyBzZXNzaW9uVG9rZW4gfSwgcmVzdE9wdGlvbnMpO1xuICByZXR1cm4gcXVlcnkuZXhlY3V0ZSgpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgIHZhciByZXN1bHRzID0gcmVzcG9uc2UucmVzdWx0cztcbiAgICBpZiAocmVzdWx0cy5sZW5ndGggIT09IDEpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdpbnZhbGlkIGxlZ2FjeSBzZXNzaW9uIHRva2VuJyk7XG4gICAgfVxuICAgIGNvbnN0IG9iaiA9IHJlc3VsdHNbMF07XG4gICAgb2JqLmNsYXNzTmFtZSA9ICdfVXNlcic7XG4gICAgY29uc3QgdXNlck9iamVjdCA9IFBhcnNlLk9iamVjdC5mcm9tSlNPTihvYmopO1xuICAgIHJldHVybiBuZXcgQXV0aCh7XG4gICAgICBjb25maWcsXG4gICAgICBpc01hc3RlcjogZmFsc2UsXG4gICAgICBpbnN0YWxsYXRpb25JZCxcbiAgICAgIHVzZXI6IHVzZXJPYmplY3QsXG4gICAgfSk7XG4gIH0pO1xufTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBvZiByb2xlIG5hbWVzXG5BdXRoLnByb3RvdHlwZS5nZXRVc2VyUm9sZXMgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmlzTWFzdGVyIHx8ICF0aGlzLnVzZXIpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFtdKTtcbiAgfVxuICBpZiAodGhpcy5mZXRjaGVkUm9sZXMpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMudXNlclJvbGVzKTtcbiAgfVxuICBpZiAodGhpcy5yb2xlUHJvbWlzZSkge1xuICAgIHJldHVybiB0aGlzLnJvbGVQcm9taXNlO1xuICB9XG4gIHRoaXMucm9sZVByb21pc2UgPSB0aGlzLl9sb2FkUm9sZXMoKTtcbiAgcmV0dXJuIHRoaXMucm9sZVByb21pc2U7XG59O1xuXG5BdXRoLnByb3RvdHlwZS5nZXRSb2xlc0ZvclVzZXIgPSBhc3luYyBmdW5jdGlvbiAoKSB7XG4gIC8vU3RhY2sgYWxsIFBhcnNlLlJvbGVcbiAgY29uc3QgcmVzdWx0cyA9IFtdO1xuICBpZiAodGhpcy5jb25maWcpIHtcbiAgICBjb25zdCByZXN0V2hlcmUgPSB7XG4gICAgICB1c2Vyczoge1xuICAgICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgY2xhc3NOYW1lOiAnX1VzZXInLFxuICAgICAgICBvYmplY3RJZDogdGhpcy51c2VyLmlkLFxuICAgICAgfSxcbiAgICB9O1xuICAgIGF3YWl0IG5ldyBSZXN0UXVlcnkodGhpcy5jb25maWcsIG1hc3Rlcih0aGlzLmNvbmZpZyksICdfUm9sZScsIHJlc3RXaGVyZSwge30pLmVhY2gocmVzdWx0ID0+XG4gICAgICByZXN1bHRzLnB1c2gocmVzdWx0KVxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgYXdhaXQgbmV3IFBhcnNlLlF1ZXJ5KFBhcnNlLlJvbGUpXG4gICAgICAuZXF1YWxUbygndXNlcnMnLCB0aGlzLnVzZXIpXG4gICAgICAuZWFjaChyZXN1bHQgPT4gcmVzdWx0cy5wdXNoKHJlc3VsdC50b0pTT04oKSksIHsgdXNlTWFzdGVyS2V5OiB0cnVlIH0pO1xuICB9XG4gIHJldHVybiByZXN1bHRzO1xufTtcblxuLy8gSXRlcmF0ZXMgdGhyb3VnaCB0aGUgcm9sZSB0cmVlIGFuZCBjb21waWxlcyBhIHVzZXIncyByb2xlc1xuQXV0aC5wcm90b3R5cGUuX2xvYWRSb2xlcyA9IGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuY2FjaGVDb250cm9sbGVyKSB7XG4gICAgY29uc3QgY2FjaGVkUm9sZXMgPSBhd2FpdCB0aGlzLmNhY2hlQ29udHJvbGxlci5yb2xlLmdldCh0aGlzLnVzZXIuaWQpO1xuICAgIGlmIChjYWNoZWRSb2xlcyAhPSBudWxsKSB7XG4gICAgICB0aGlzLmZldGNoZWRSb2xlcyA9IHRydWU7XG4gICAgICB0aGlzLnVzZXJSb2xlcyA9IGNhY2hlZFJvbGVzO1xuICAgICAgcmV0dXJuIGNhY2hlZFJvbGVzO1xuICAgIH1cbiAgfVxuXG4gIC8vIEZpcnN0IGdldCB0aGUgcm9sZSBpZHMgdGhpcyB1c2VyIGlzIGRpcmVjdGx5IGEgbWVtYmVyIG9mXG4gIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCB0aGlzLmdldFJvbGVzRm9yVXNlcigpO1xuICBpZiAoIXJlc3VsdHMubGVuZ3RoKSB7XG4gICAgdGhpcy51c2VyUm9sZXMgPSBbXTtcbiAgICB0aGlzLmZldGNoZWRSb2xlcyA9IHRydWU7XG4gICAgdGhpcy5yb2xlUHJvbWlzZSA9IG51bGw7XG5cbiAgICB0aGlzLmNhY2hlUm9sZXMoKTtcbiAgICByZXR1cm4gdGhpcy51c2VyUm9sZXM7XG4gIH1cblxuICBjb25zdCByb2xlc01hcCA9IHJlc3VsdHMucmVkdWNlKFxuICAgIChtLCByKSA9PiB7XG4gICAgICBtLm5hbWVzLnB1c2goci5uYW1lKTtcbiAgICAgIG0uaWRzLnB1c2goci5vYmplY3RJZCk7XG4gICAgICByZXR1cm4gbTtcbiAgICB9LFxuICAgIHsgaWRzOiBbXSwgbmFtZXM6IFtdIH1cbiAgKTtcblxuICAvLyBydW4gdGhlIHJlY3Vyc2l2ZSBmaW5kaW5nXG4gIGNvbnN0IHJvbGVOYW1lcyA9IGF3YWl0IHRoaXMuX2dldEFsbFJvbGVzTmFtZXNGb3JSb2xlSWRzKHJvbGVzTWFwLmlkcywgcm9sZXNNYXAubmFtZXMpO1xuICB0aGlzLnVzZXJSb2xlcyA9IHJvbGVOYW1lcy5tYXAociA9PiB7XG4gICAgcmV0dXJuICdyb2xlOicgKyByO1xuICB9KTtcbiAgdGhpcy5mZXRjaGVkUm9sZXMgPSB0cnVlO1xuICB0aGlzLnJvbGVQcm9taXNlID0gbnVsbDtcbiAgdGhpcy5jYWNoZVJvbGVzKCk7XG4gIHJldHVybiB0aGlzLnVzZXJSb2xlcztcbn07XG5cbkF1dGgucHJvdG90eXBlLmNhY2hlUm9sZXMgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5jYWNoZUNvbnRyb2xsZXIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdGhpcy5jYWNoZUNvbnRyb2xsZXIucm9sZS5wdXQodGhpcy51c2VyLmlkLCBBcnJheSguLi50aGlzLnVzZXJSb2xlcykpO1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkF1dGgucHJvdG90eXBlLmdldFJvbGVzQnlJZHMgPSBhc3luYyBmdW5jdGlvbiAoaW5zKSB7XG4gIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgLy8gQnVpbGQgYW4gT1IgcXVlcnkgYWNyb3NzIGFsbCBwYXJlbnRSb2xlc1xuICBpZiAoIXRoaXMuY29uZmlnKSB7XG4gICAgYXdhaXQgbmV3IFBhcnNlLlF1ZXJ5KFBhcnNlLlJvbGUpXG4gICAgICAuY29udGFpbmVkSW4oXG4gICAgICAgICdyb2xlcycsXG4gICAgICAgIGlucy5tYXAoaWQgPT4ge1xuICAgICAgICAgIGNvbnN0IHJvbGUgPSBuZXcgUGFyc2UuT2JqZWN0KFBhcnNlLlJvbGUpO1xuICAgICAgICAgIHJvbGUuaWQgPSBpZDtcbiAgICAgICAgICByZXR1cm4gcm9sZTtcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC5lYWNoKHJlc3VsdCA9PiByZXN1bHRzLnB1c2gocmVzdWx0LnRvSlNPTigpKSwgeyB1c2VNYXN0ZXJLZXk6IHRydWUgfSk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3Qgcm9sZXMgPSBpbnMubWFwKGlkID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICBjbGFzc05hbWU6ICdfUm9sZScsXG4gICAgICAgIG9iamVjdElkOiBpZCxcbiAgICAgIH07XG4gICAgfSk7XG4gICAgY29uc3QgcmVzdFdoZXJlID0geyByb2xlczogeyAkaW46IHJvbGVzIH0gfTtcbiAgICBhd2FpdCBuZXcgUmVzdFF1ZXJ5KHRoaXMuY29uZmlnLCBtYXN0ZXIodGhpcy5jb25maWcpLCAnX1JvbGUnLCByZXN0V2hlcmUsIHt9KS5lYWNoKHJlc3VsdCA9PlxuICAgICAgcmVzdWx0cy5wdXNoKHJlc3VsdClcbiAgICApO1xuICB9XG4gIHJldHVybiByZXN1bHRzO1xufTtcblxuLy8gR2l2ZW4gYSBsaXN0IG9mIHJvbGVJZHMsIGZpbmQgYWxsIHRoZSBwYXJlbnQgcm9sZXMsIHJldHVybnMgYSBwcm9taXNlIHdpdGggYWxsIG5hbWVzXG5BdXRoLnByb3RvdHlwZS5fZ2V0QWxsUm9sZXNOYW1lc0ZvclJvbGVJZHMgPSBmdW5jdGlvbiAocm9sZUlEcywgbmFtZXMgPSBbXSwgcXVlcmllZFJvbGVzID0ge30pIHtcbiAgY29uc3QgaW5zID0gcm9sZUlEcy5maWx0ZXIocm9sZUlEID0+IHtcbiAgICBjb25zdCB3YXNRdWVyaWVkID0gcXVlcmllZFJvbGVzW3JvbGVJRF0gIT09IHRydWU7XG4gICAgcXVlcmllZFJvbGVzW3JvbGVJRF0gPSB0cnVlO1xuICAgIHJldHVybiB3YXNRdWVyaWVkO1xuICB9KTtcblxuICAvLyBhbGwgcm9sZXMgYXJlIGFjY291bnRlZCBmb3IsIHJldHVybiB0aGUgbmFtZXNcbiAgaWYgKGlucy5sZW5ndGggPT0gMCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoWy4uLm5ldyBTZXQobmFtZXMpXSk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5nZXRSb2xlc0J5SWRzKGlucylcbiAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIC8vIE5vdGhpbmcgZm91bmRcbiAgICAgIGlmICghcmVzdWx0cy5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuYW1lcyk7XG4gICAgICB9XG4gICAgICAvLyBNYXAgdGhlIHJlc3VsdHMgd2l0aCBhbGwgSWRzIGFuZCBuYW1lc1xuICAgICAgY29uc3QgcmVzdWx0TWFwID0gcmVzdWx0cy5yZWR1Y2UoXG4gICAgICAgIChtZW1vLCByb2xlKSA9PiB7XG4gICAgICAgICAgbWVtby5uYW1lcy5wdXNoKHJvbGUubmFtZSk7XG4gICAgICAgICAgbWVtby5pZHMucHVzaChyb2xlLm9iamVjdElkKTtcbiAgICAgICAgICByZXR1cm4gbWVtbztcbiAgICAgICAgfSxcbiAgICAgICAgeyBpZHM6IFtdLCBuYW1lczogW10gfVxuICAgICAgKTtcbiAgICAgIC8vIHN0b3JlIHRoZSBuZXcgZm91bmQgbmFtZXNcbiAgICAgIG5hbWVzID0gbmFtZXMuY29uY2F0KHJlc3VsdE1hcC5uYW1lcyk7XG4gICAgICAvLyBmaW5kIHRoZSBuZXh0IG9uZXMsIGNpcmN1bGFyIHJvbGVzIHdpbGwgYmUgY3V0XG4gICAgICByZXR1cm4gdGhpcy5fZ2V0QWxsUm9sZXNOYW1lc0ZvclJvbGVJZHMocmVzdWx0TWFwLmlkcywgbmFtZXMsIHF1ZXJpZWRSb2xlcyk7XG4gICAgfSlcbiAgICAudGhlbihuYW1lcyA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKFsuLi5uZXcgU2V0KG5hbWVzKV0pO1xuICAgIH0pO1xufTtcblxuY29uc3QgY3JlYXRlU2Vzc2lvbiA9IGZ1bmN0aW9uIChcbiAgY29uZmlnLFxuICB7IHVzZXJJZCwgY3JlYXRlZFdpdGgsIGluc3RhbGxhdGlvbklkLCBhZGRpdGlvbmFsU2Vzc2lvbkRhdGEgfVxuKSB7XG4gIGNvbnN0IHRva2VuID0gJ3I6JyArIGNyeXB0b1V0aWxzLm5ld1Rva2VuKCk7XG4gIGNvbnN0IGV4cGlyZXNBdCA9IGNvbmZpZy5nZW5lcmF0ZVNlc3Npb25FeHBpcmVzQXQoKTtcbiAgY29uc3Qgc2Vzc2lvbkRhdGEgPSB7XG4gICAgc2Vzc2lvblRva2VuOiB0b2tlbixcbiAgICB1c2VyOiB7XG4gICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgIGNsYXNzTmFtZTogJ19Vc2VyJyxcbiAgICAgIG9iamVjdElkOiB1c2VySWQsXG4gICAgfSxcbiAgICBjcmVhdGVkV2l0aCxcbiAgICByZXN0cmljdGVkOiBmYWxzZSxcbiAgICBleHBpcmVzQXQ6IFBhcnNlLl9lbmNvZGUoZXhwaXJlc0F0KSxcbiAgfTtcblxuICBpZiAoaW5zdGFsbGF0aW9uSWQpIHtcbiAgICBzZXNzaW9uRGF0YS5pbnN0YWxsYXRpb25JZCA9IGluc3RhbGxhdGlvbklkO1xuICB9XG5cbiAgT2JqZWN0LmFzc2lnbihzZXNzaW9uRGF0YSwgYWRkaXRpb25hbFNlc3Npb25EYXRhKTtcbiAgLy8gV2UgbmVlZCB0byBpbXBvcnQgUmVzdFdyaXRlIGF0IHRoaXMgcG9pbnQgZm9yIHRoZSBjeWNsaWMgZGVwZW5kZW5jeSBpdCBoYXMgdG8gaXRcbiAgY29uc3QgUmVzdFdyaXRlID0gcmVxdWlyZSgnLi9SZXN0V3JpdGUnKTtcblxuICByZXR1cm4ge1xuICAgIHNlc3Npb25EYXRhLFxuICAgIGNyZWF0ZVNlc3Npb246ICgpID0+XG4gICAgICBuZXcgUmVzdFdyaXRlKGNvbmZpZywgbWFzdGVyKGNvbmZpZyksICdfU2Vzc2lvbicsIG51bGwsIHNlc3Npb25EYXRhKS5leGVjdXRlKCksXG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgQXV0aCxcbiAgbWFzdGVyLFxuICBub2JvZHksXG4gIHJlYWRPbmx5LFxuICBnZXRBdXRoRm9yU2Vzc2lvblRva2VuLFxuICBnZXRBdXRoRm9yTGVnYWN5U2Vzc2lvblRva2VuLFxuICBjcmVhdGVTZXNzaW9uLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/ClientSDK.js b/lib/ClientSDK.js deleted file mode 100644 index ed5cf3beab..0000000000 --- a/lib/ClientSDK.js +++ /dev/null @@ -1,47 +0,0 @@ -"use strict"; - -var semver = require('semver'); - -function compatible(compatibleSDK) { - return function (clientSDK) { - if (typeof clientSDK === 'string') { - clientSDK = fromString(clientSDK); - } // REST API, or custom SDK - - - if (!clientSDK) { - return true; - } - - const clientVersion = clientSDK.version; - const compatiblityVersion = compatibleSDK[clientSDK.sdk]; - return semver.satisfies(clientVersion, compatiblityVersion); - }; -} - -function supportsForwardDelete(clientSDK) { - return compatible({ - js: '>=1.9.0' - })(clientSDK); -} - -function fromString(version) { - const versionRE = /([-a-zA-Z]+)([0-9\.]+)/; - const match = version.toLowerCase().match(versionRE); - - if (match && match.length === 3) { - return { - sdk: match[1], - version: match[2] - }; - } - - return undefined; -} - -module.exports = { - compatible, - supportsForwardDelete, - fromString -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9DbGllbnRTREsuanMiXSwibmFtZXMiOlsic2VtdmVyIiwicmVxdWlyZSIsImNvbXBhdGlibGUiLCJjb21wYXRpYmxlU0RLIiwiY2xpZW50U0RLIiwiZnJvbVN0cmluZyIsImNsaWVudFZlcnNpb24iLCJ2ZXJzaW9uIiwiY29tcGF0aWJsaXR5VmVyc2lvbiIsInNkayIsInNhdGlzZmllcyIsInN1cHBvcnRzRm9yd2FyZERlbGV0ZSIsImpzIiwidmVyc2lvblJFIiwibWF0Y2giLCJ0b0xvd2VyQ2FzZSIsImxlbmd0aCIsInVuZGVmaW5lZCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUEsSUFBSUEsTUFBTSxHQUFHQyxPQUFPLENBQUMsUUFBRCxDQUFwQjs7QUFFQSxTQUFTQyxVQUFULENBQW9CQyxhQUFwQixFQUFtQztBQUNqQyxTQUFPLFVBQVVDLFNBQVYsRUFBcUI7QUFDMUIsUUFBSSxPQUFPQSxTQUFQLEtBQXFCLFFBQXpCLEVBQW1DO0FBQ2pDQSxNQUFBQSxTQUFTLEdBQUdDLFVBQVUsQ0FBQ0QsU0FBRCxDQUF0QjtBQUNELEtBSHlCLENBSTFCOzs7QUFDQSxRQUFJLENBQUNBLFNBQUwsRUFBZ0I7QUFDZCxhQUFPLElBQVA7QUFDRDs7QUFDRCxVQUFNRSxhQUFhLEdBQUdGLFNBQVMsQ0FBQ0csT0FBaEM7QUFDQSxVQUFNQyxtQkFBbUIsR0FBR0wsYUFBYSxDQUFDQyxTQUFTLENBQUNLLEdBQVgsQ0FBekM7QUFDQSxXQUFPVCxNQUFNLENBQUNVLFNBQVAsQ0FBaUJKLGFBQWpCLEVBQWdDRSxtQkFBaEMsQ0FBUDtBQUNELEdBWEQ7QUFZRDs7QUFFRCxTQUFTRyxxQkFBVCxDQUErQlAsU0FBL0IsRUFBMEM7QUFDeEMsU0FBT0YsVUFBVSxDQUFDO0FBQ2hCVSxJQUFBQSxFQUFFLEVBQUU7QUFEWSxHQUFELENBQVYsQ0FFSlIsU0FGSSxDQUFQO0FBR0Q7O0FBRUQsU0FBU0MsVUFBVCxDQUFvQkUsT0FBcEIsRUFBNkI7QUFDM0IsUUFBTU0sU0FBUyxHQUFHLHdCQUFsQjtBQUNBLFFBQU1DLEtBQUssR0FBR1AsT0FBTyxDQUFDUSxXQUFSLEdBQXNCRCxLQUF0QixDQUE0QkQsU0FBNUIsQ0FBZDs7QUFDQSxNQUFJQyxLQUFLLElBQUlBLEtBQUssQ0FBQ0UsTUFBTixLQUFpQixDQUE5QixFQUFpQztBQUMvQixXQUFPO0FBQ0xQLE1BQUFBLEdBQUcsRUFBRUssS0FBSyxDQUFDLENBQUQsQ0FETDtBQUVMUCxNQUFBQSxPQUFPLEVBQUVPLEtBQUssQ0FBQyxDQUFEO0FBRlQsS0FBUDtBQUlEOztBQUNELFNBQU9HLFNBQVA7QUFDRDs7QUFFREMsTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZqQixFQUFBQSxVQURlO0FBRWZTLEVBQUFBLHFCQUZlO0FBR2ZOLEVBQUFBO0FBSGUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgc2VtdmVyID0gcmVxdWlyZSgnc2VtdmVyJyk7XG5cbmZ1bmN0aW9uIGNvbXBhdGlibGUoY29tcGF0aWJsZVNESykge1xuICByZXR1cm4gZnVuY3Rpb24gKGNsaWVudFNESykge1xuICAgIGlmICh0eXBlb2YgY2xpZW50U0RLID09PSAnc3RyaW5nJykge1xuICAgICAgY2xpZW50U0RLID0gZnJvbVN0cmluZyhjbGllbnRTREspO1xuICAgIH1cbiAgICAvLyBSRVNUIEFQSSwgb3IgY3VzdG9tIFNES1xuICAgIGlmICghY2xpZW50U0RLKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgY2xpZW50VmVyc2lvbiA9IGNsaWVudFNESy52ZXJzaW9uO1xuICAgIGNvbnN0IGNvbXBhdGlibGl0eVZlcnNpb24gPSBjb21wYXRpYmxlU0RLW2NsaWVudFNESy5zZGtdO1xuICAgIHJldHVybiBzZW12ZXIuc2F0aXNmaWVzKGNsaWVudFZlcnNpb24sIGNvbXBhdGlibGl0eVZlcnNpb24pO1xuICB9O1xufVxuXG5mdW5jdGlvbiBzdXBwb3J0c0ZvcndhcmREZWxldGUoY2xpZW50U0RLKSB7XG4gIHJldHVybiBjb21wYXRpYmxlKHtcbiAgICBqczogJz49MS45LjAnLFxuICB9KShjbGllbnRTREspO1xufVxuXG5mdW5jdGlvbiBmcm9tU3RyaW5nKHZlcnNpb24pIHtcbiAgY29uc3QgdmVyc2lvblJFID0gLyhbLWEtekEtWl0rKShbMC05XFwuXSspLztcbiAgY29uc3QgbWF0Y2ggPSB2ZXJzaW9uLnRvTG93ZXJDYXNlKCkubWF0Y2godmVyc2lvblJFKTtcbiAgaWYgKG1hdGNoICYmIG1hdGNoLmxlbmd0aCA9PT0gMykge1xuICAgIHJldHVybiB7XG4gICAgICBzZGs6IG1hdGNoWzFdLFxuICAgICAgdmVyc2lvbjogbWF0Y2hbMl0sXG4gICAgfTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgY29tcGF0aWJsZSxcbiAgc3VwcG9ydHNGb3J3YXJkRGVsZXRlLFxuICBmcm9tU3RyaW5nLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Config.js b/lib/Config.js deleted file mode 100644 index 359b191cc1..0000000000 --- a/lib/Config.js +++ /dev/null @@ -1,471 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.Config = void 0; - -var _cache = _interopRequireDefault(require("./cache")); - -var _SchemaCache = _interopRequireDefault(require("./Controllers/SchemaCache")); - -var _DatabaseController = _interopRequireDefault(require("./Controllers/DatabaseController")); - -var _net = _interopRequireDefault(require("net")); - -var _Definitions = require("./Options/Definitions"); - -var _lodash = require("lodash"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// A Config object provides information about how a specific app is -// configured. -// mount is the URL for the root of the API; includes http, domain, etc. -function removeTrailingSlash(str) { - if (!str) { - return str; - } - - if (str.endsWith('/')) { - str = str.substr(0, str.length - 1); - } - - return str; -} - -class Config { - static get(applicationId, mount) { - const cacheInfo = _cache.default.get(applicationId); - - if (!cacheInfo) { - return; - } - - const config = new Config(); - config.applicationId = applicationId; - Object.keys(cacheInfo).forEach(key => { - if (key == 'databaseController') { - const schemaCache = new _SchemaCache.default(cacheInfo.cacheController, cacheInfo.schemaCacheTTL, cacheInfo.enableSingleSchemaCache); - config.database = new _DatabaseController.default(cacheInfo.databaseController.adapter, schemaCache); - } else { - config[key] = cacheInfo[key]; - } - }); - config.mount = removeTrailingSlash(mount); - config.generateSessionExpiresAt = config.generateSessionExpiresAt.bind(config); - config.generateEmailVerifyTokenExpiresAt = config.generateEmailVerifyTokenExpiresAt.bind(config); - return config; - } - - static put(serverConfiguration) { - Config.validate(serverConfiguration); - - _cache.default.put(serverConfiguration.appId, serverConfiguration); - - Config.setupPasswordValidator(serverConfiguration.passwordPolicy); - return serverConfiguration; - } - - static validate({ - verifyUserEmails, - userController, - appName, - publicServerURL, - revokeSessionOnPasswordReset, - expireInactiveSessions, - sessionLength, - maxLimit, - emailVerifyTokenValidityDuration, - accountLockout, - passwordPolicy, - masterKeyIps, - masterKey, - readOnlyMasterKey, - allowHeaders, - idempotencyOptions, - emailVerifyTokenReuseIfValid, - fileUpload, - pages - }) { - if (masterKey === readOnlyMasterKey) { - throw new Error('masterKey and readOnlyMasterKey should be different'); - } - - const emailAdapter = userController.adapter; - - if (verifyUserEmails) { - this.validateEmailConfiguration({ - emailAdapter, - appName, - publicServerURL, - emailVerifyTokenValidityDuration, - emailVerifyTokenReuseIfValid - }); - } - - this.validateAccountLockoutPolicy(accountLockout); - this.validatePasswordPolicy(passwordPolicy); - this.validateFileUploadOptions(fileUpload); - - if (typeof revokeSessionOnPasswordReset !== 'boolean') { - throw 'revokeSessionOnPasswordReset must be a boolean value'; - } - - if (publicServerURL) { - if (!publicServerURL.startsWith('http://') && !publicServerURL.startsWith('https://')) { - throw 'publicServerURL should be a valid HTTPS URL starting with https://'; - } - } - - this.validateSessionConfiguration(sessionLength, expireInactiveSessions); - this.validateMasterKeyIps(masterKeyIps); - this.validateMaxLimit(maxLimit); - this.validateAllowHeaders(allowHeaders); - this.validateIdempotencyOptions(idempotencyOptions); - this.validatePagesOptions(pages); - } - - static validatePagesOptions(pages) { - if (Object.prototype.toString.call(pages) !== '[object Object]') { - throw 'Parse Server option pages must be an object.'; - } - - if (pages.enableRouter === undefined) { - pages.enableRouter = _Definitions.PagesOptions.enableRouter.default; - } else if (!(0, _lodash.isBoolean)(pages.enableRouter)) { - throw 'Parse Server option pages.enableRouter must be a boolean.'; - } - - if (pages.enableLocalization === undefined) { - pages.enableLocalization = _Definitions.PagesOptions.enableLocalization.default; - } else if (!(0, _lodash.isBoolean)(pages.enableLocalization)) { - throw 'Parse Server option pages.enableLocalization must be a boolean.'; - } - - if (pages.localizationJsonPath === undefined) { - pages.localizationJsonPath = _Definitions.PagesOptions.localizationJsonPath.default; - } else if (!(0, _lodash.isString)(pages.localizationJsonPath)) { - throw 'Parse Server option pages.localizationJsonPath must be a string.'; - } - - if (pages.localizationFallbackLocale === undefined) { - pages.localizationFallbackLocale = _Definitions.PagesOptions.localizationFallbackLocale.default; - } else if (!(0, _lodash.isString)(pages.localizationFallbackLocale)) { - throw 'Parse Server option pages.localizationFallbackLocale must be a string.'; - } - - if (pages.placeholders === undefined) { - pages.placeholders = _Definitions.PagesOptions.placeholders.default; - } else if (Object.prototype.toString.call(pages.placeholders) !== '[object Object]' && typeof pages.placeholders !== 'function') { - throw 'Parse Server option pages.placeholders must be an object or a function.'; - } - - if (pages.forceRedirect === undefined) { - pages.forceRedirect = _Definitions.PagesOptions.forceRedirect.default; - } else if (!(0, _lodash.isBoolean)(pages.forceRedirect)) { - throw 'Parse Server option pages.forceRedirect must be a boolean.'; - } - - if (pages.pagesPath === undefined) { - pages.pagesPath = _Definitions.PagesOptions.pagesPath.default; - } else if (!(0, _lodash.isString)(pages.pagesPath)) { - throw 'Parse Server option pages.pagesPath must be a string.'; - } - - if (pages.pagesEndpoint === undefined) { - pages.pagesEndpoint = _Definitions.PagesOptions.pagesEndpoint.default; - } else if (!(0, _lodash.isString)(pages.pagesEndpoint)) { - throw 'Parse Server option pages.pagesEndpoint must be a string.'; - } - - if (pages.customUrls === undefined) { - pages.customUrls = _Definitions.PagesOptions.customUrls.default; - } else if (Object.prototype.toString.call(pages.customUrls) !== '[object Object]') { - throw 'Parse Server option pages.customUrls must be an object.'; - } - } - - static validateIdempotencyOptions(idempotencyOptions) { - if (!idempotencyOptions) { - return; - } - - if (idempotencyOptions.ttl === undefined) { - idempotencyOptions.ttl = _Definitions.IdempotencyOptions.ttl.default; - } else if (!isNaN(idempotencyOptions.ttl) && idempotencyOptions.ttl <= 0) { - throw 'idempotency TTL value must be greater than 0 seconds'; - } else if (isNaN(idempotencyOptions.ttl)) { - throw 'idempotency TTL value must be a number'; - } - - if (!idempotencyOptions.paths) { - idempotencyOptions.paths = _Definitions.IdempotencyOptions.paths.default; - } else if (!(idempotencyOptions.paths instanceof Array)) { - throw 'idempotency paths must be of an array of strings'; - } - } - - static validateAccountLockoutPolicy(accountLockout) { - if (accountLockout) { - if (typeof accountLockout.duration !== 'number' || accountLockout.duration <= 0 || accountLockout.duration > 99999) { - throw 'Account lockout duration should be greater than 0 and less than 100000'; - } - - if (!Number.isInteger(accountLockout.threshold) || accountLockout.threshold < 1 || accountLockout.threshold > 999) { - throw 'Account lockout threshold should be an integer greater than 0 and less than 1000'; - } - - if (accountLockout.unlockOnPasswordReset === undefined) { - accountLockout.unlockOnPasswordReset = _Definitions.AccountLockoutOptions.unlockOnPasswordReset.default; - } else if (!(0, _lodash.isBoolean)(accountLockout.unlockOnPasswordReset)) { - throw 'Parse Server option accountLockout.unlockOnPasswordReset must be a boolean.'; - } - } - } - - static validatePasswordPolicy(passwordPolicy) { - if (passwordPolicy) { - if (passwordPolicy.maxPasswordAge !== undefined && (typeof passwordPolicy.maxPasswordAge !== 'number' || passwordPolicy.maxPasswordAge < 0)) { - throw 'passwordPolicy.maxPasswordAge must be a positive number'; - } - - if (passwordPolicy.resetTokenValidityDuration !== undefined && (typeof passwordPolicy.resetTokenValidityDuration !== 'number' || passwordPolicy.resetTokenValidityDuration <= 0)) { - throw 'passwordPolicy.resetTokenValidityDuration must be a positive number'; - } - - if (passwordPolicy.validatorPattern) { - if (typeof passwordPolicy.validatorPattern === 'string') { - passwordPolicy.validatorPattern = new RegExp(passwordPolicy.validatorPattern); - } else if (!(passwordPolicy.validatorPattern instanceof RegExp)) { - throw 'passwordPolicy.validatorPattern must be a regex string or RegExp object.'; - } - } - - if (passwordPolicy.validatorCallback && typeof passwordPolicy.validatorCallback !== 'function') { - throw 'passwordPolicy.validatorCallback must be a function.'; - } - - if (passwordPolicy.doNotAllowUsername && typeof passwordPolicy.doNotAllowUsername !== 'boolean') { - throw 'passwordPolicy.doNotAllowUsername must be a boolean value.'; - } - - if (passwordPolicy.maxPasswordHistory && (!Number.isInteger(passwordPolicy.maxPasswordHistory) || passwordPolicy.maxPasswordHistory <= 0 || passwordPolicy.maxPasswordHistory > 20)) { - throw 'passwordPolicy.maxPasswordHistory must be an integer ranging 0 - 20'; - } - - if (passwordPolicy.resetTokenReuseIfValid && typeof passwordPolicy.resetTokenReuseIfValid !== 'boolean') { - throw 'resetTokenReuseIfValid must be a boolean value'; - } - - if (passwordPolicy.resetTokenReuseIfValid && !passwordPolicy.resetTokenValidityDuration) { - throw 'You cannot use resetTokenReuseIfValid without resetTokenValidityDuration'; - } - } - } // if the passwordPolicy.validatorPattern is configured then setup a callback to process the pattern - - - static setupPasswordValidator(passwordPolicy) { - if (passwordPolicy && passwordPolicy.validatorPattern) { - passwordPolicy.patternValidator = value => { - return passwordPolicy.validatorPattern.test(value); - }; - } - } - - static validateEmailConfiguration({ - emailAdapter, - appName, - publicServerURL, - emailVerifyTokenValidityDuration, - emailVerifyTokenReuseIfValid - }) { - if (!emailAdapter) { - throw 'An emailAdapter is required for e-mail verification and password resets.'; - } - - if (typeof appName !== 'string') { - throw 'An app name is required for e-mail verification and password resets.'; - } - - if (typeof publicServerURL !== 'string') { - throw 'A public server url is required for e-mail verification and password resets.'; - } - - if (emailVerifyTokenValidityDuration) { - if (isNaN(emailVerifyTokenValidityDuration)) { - throw 'Email verify token validity duration must be a valid number.'; - } else if (emailVerifyTokenValidityDuration <= 0) { - throw 'Email verify token validity duration must be a value greater than 0.'; - } - } - - if (emailVerifyTokenReuseIfValid && typeof emailVerifyTokenReuseIfValid !== 'boolean') { - throw 'emailVerifyTokenReuseIfValid must be a boolean value'; - } - - if (emailVerifyTokenReuseIfValid && !emailVerifyTokenValidityDuration) { - throw 'You cannot use emailVerifyTokenReuseIfValid without emailVerifyTokenValidityDuration'; - } - } - - static validateFileUploadOptions(fileUpload) { - try { - if (fileUpload == null || typeof fileUpload !== 'object' || fileUpload instanceof Array) { - throw 'fileUpload must be an object value.'; - } - } catch (e) { - if (e instanceof ReferenceError) { - return; - } - - throw e; - } - - if (fileUpload.enableForAnonymousUser === undefined) { - fileUpload.enableForAnonymousUser = _Definitions.FileUploadOptions.enableForAnonymousUser.default; - } else if (typeof fileUpload.enableForAnonymousUser !== 'boolean') { - throw 'fileUpload.enableForAnonymousUser must be a boolean value.'; - } - - if (fileUpload.enableForPublic === undefined) { - fileUpload.enableForPublic = _Definitions.FileUploadOptions.enableForPublic.default; - } else if (typeof fileUpload.enableForPublic !== 'boolean') { - throw 'fileUpload.enableForPublic must be a boolean value.'; - } - - if (fileUpload.enableForAuthenticatedUser === undefined) { - fileUpload.enableForAuthenticatedUser = _Definitions.FileUploadOptions.enableForAuthenticatedUser.default; - } else if (typeof fileUpload.enableForAuthenticatedUser !== 'boolean') { - throw 'fileUpload.enableForAuthenticatedUser must be a boolean value.'; - } - } - - static validateMasterKeyIps(masterKeyIps) { - for (const ip of masterKeyIps) { - if (!_net.default.isIP(ip)) { - throw `Invalid ip in masterKeyIps: ${ip}`; - } - } - } - - get mount() { - var mount = this._mount; - - if (this.publicServerURL) { - mount = this.publicServerURL; - } - - return mount; - } - - set mount(newValue) { - this._mount = newValue; - } - - static validateSessionConfiguration(sessionLength, expireInactiveSessions) { - if (expireInactiveSessions) { - if (isNaN(sessionLength)) { - throw 'Session length must be a valid number.'; - } else if (sessionLength <= 0) { - throw 'Session length must be a value greater than 0.'; - } - } - } - - static validateMaxLimit(maxLimit) { - if (maxLimit <= 0) { - throw 'Max limit must be a value greater than 0.'; - } - } - - static validateAllowHeaders(allowHeaders) { - if (![null, undefined].includes(allowHeaders)) { - if (Array.isArray(allowHeaders)) { - allowHeaders.forEach(header => { - if (typeof header !== 'string') { - throw 'Allow headers must only contain strings'; - } else if (!header.trim().length) { - throw 'Allow headers must not contain empty strings'; - } - }); - } else { - throw 'Allow headers must be an array'; - } - } - } - - generateEmailVerifyTokenExpiresAt() { - if (!this.verifyUserEmails || !this.emailVerifyTokenValidityDuration) { - return undefined; - } - - var now = new Date(); - return new Date(now.getTime() + this.emailVerifyTokenValidityDuration * 1000); - } - - generatePasswordResetTokenExpiresAt() { - if (!this.passwordPolicy || !this.passwordPolicy.resetTokenValidityDuration) { - return undefined; - } - - const now = new Date(); - return new Date(now.getTime() + this.passwordPolicy.resetTokenValidityDuration * 1000); - } - - generateSessionExpiresAt() { - if (!this.expireInactiveSessions) { - return undefined; - } - - var now = new Date(); - return new Date(now.getTime() + this.sessionLength * 1000); - } - - get invalidLinkURL() { - return this.customPages.invalidLink || `${this.publicServerURL}/apps/invalid_link.html`; - } - - get invalidVerificationLinkURL() { - return this.customPages.invalidVerificationLink || `${this.publicServerURL}/apps/invalid_verification_link.html`; - } - - get linkSendSuccessURL() { - return this.customPages.linkSendSuccess || `${this.publicServerURL}/apps/link_send_success.html`; - } - - get linkSendFailURL() { - return this.customPages.linkSendFail || `${this.publicServerURL}/apps/link_send_fail.html`; - } - - get verifyEmailSuccessURL() { - return this.customPages.verifyEmailSuccess || `${this.publicServerURL}/apps/verify_email_success.html`; - } - - get choosePasswordURL() { - return this.customPages.choosePassword || `${this.publicServerURL}/apps/choose_password`; - } - - get requestResetPasswordURL() { - return `${this.publicServerURL}/apps/${this.applicationId}/request_password_reset`; - } - - get passwordResetSuccessURL() { - return this.customPages.passwordResetSuccess || `${this.publicServerURL}/apps/password_reset_success.html`; - } - - get parseFrameURL() { - return this.customPages.parseFrameURL; - } - - get verifyEmailURL() { - return `${this.publicServerURL}/apps/${this.applicationId}/verify_email`; - } - -} - -exports.Config = Config; -var _default = Config; -exports.default = _default; -module.exports = Config; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9Db25maWcuanMiXSwibmFtZXMiOlsicmVtb3ZlVHJhaWxpbmdTbGFzaCIsInN0ciIsImVuZHNXaXRoIiwic3Vic3RyIiwibGVuZ3RoIiwiQ29uZmlnIiwiZ2V0IiwiYXBwbGljYXRpb25JZCIsIm1vdW50IiwiY2FjaGVJbmZvIiwiQXBwQ2FjaGUiLCJjb25maWciLCJPYmplY3QiLCJrZXlzIiwiZm9yRWFjaCIsImtleSIsInNjaGVtYUNhY2hlIiwiU2NoZW1hQ2FjaGUiLCJjYWNoZUNvbnRyb2xsZXIiLCJzY2hlbWFDYWNoZVRUTCIsImVuYWJsZVNpbmdsZVNjaGVtYUNhY2hlIiwiZGF0YWJhc2UiLCJEYXRhYmFzZUNvbnRyb2xsZXIiLCJkYXRhYmFzZUNvbnRyb2xsZXIiLCJhZGFwdGVyIiwiZ2VuZXJhdGVTZXNzaW9uRXhwaXJlc0F0IiwiYmluZCIsImdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbkV4cGlyZXNBdCIsInB1dCIsInNlcnZlckNvbmZpZ3VyYXRpb24iLCJ2YWxpZGF0ZSIsImFwcElkIiwic2V0dXBQYXNzd29yZFZhbGlkYXRvciIsInBhc3N3b3JkUG9saWN5IiwidmVyaWZ5VXNlckVtYWlscyIsInVzZXJDb250cm9sbGVyIiwiYXBwTmFtZSIsInB1YmxpY1NlcnZlclVSTCIsInJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQiLCJleHBpcmVJbmFjdGl2ZVNlc3Npb25zIiwic2Vzc2lvbkxlbmd0aCIsIm1heExpbWl0IiwiZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJhY2NvdW50TG9ja291dCIsIm1hc3RlcktleUlwcyIsIm1hc3RlcktleSIsInJlYWRPbmx5TWFzdGVyS2V5IiwiYWxsb3dIZWFkZXJzIiwiaWRlbXBvdGVuY3lPcHRpb25zIiwiZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZCIsImZpbGVVcGxvYWQiLCJwYWdlcyIsIkVycm9yIiwiZW1haWxBZGFwdGVyIiwidmFsaWRhdGVFbWFpbENvbmZpZ3VyYXRpb24iLCJ2YWxpZGF0ZUFjY291bnRMb2Nrb3V0UG9saWN5IiwidmFsaWRhdGVQYXNzd29yZFBvbGljeSIsInZhbGlkYXRlRmlsZVVwbG9hZE9wdGlvbnMiLCJzdGFydHNXaXRoIiwidmFsaWRhdGVTZXNzaW9uQ29uZmlndXJhdGlvbiIsInZhbGlkYXRlTWFzdGVyS2V5SXBzIiwidmFsaWRhdGVNYXhMaW1pdCIsInZhbGlkYXRlQWxsb3dIZWFkZXJzIiwidmFsaWRhdGVJZGVtcG90ZW5jeU9wdGlvbnMiLCJ2YWxpZGF0ZVBhZ2VzT3B0aW9ucyIsInByb3RvdHlwZSIsInRvU3RyaW5nIiwiY2FsbCIsImVuYWJsZVJvdXRlciIsInVuZGVmaW5lZCIsIlBhZ2VzT3B0aW9ucyIsImRlZmF1bHQiLCJlbmFibGVMb2NhbGl6YXRpb24iLCJsb2NhbGl6YXRpb25Kc29uUGF0aCIsImxvY2FsaXphdGlvbkZhbGxiYWNrTG9jYWxlIiwicGxhY2Vob2xkZXJzIiwiZm9yY2VSZWRpcmVjdCIsInBhZ2VzUGF0aCIsInBhZ2VzRW5kcG9pbnQiLCJjdXN0b21VcmxzIiwidHRsIiwiSWRlbXBvdGVuY3lPcHRpb25zIiwiaXNOYU4iLCJwYXRocyIsIkFycmF5IiwiZHVyYXRpb24iLCJOdW1iZXIiLCJpc0ludGVnZXIiLCJ0aHJlc2hvbGQiLCJ1bmxvY2tPblBhc3N3b3JkUmVzZXQiLCJBY2NvdW50TG9ja291dE9wdGlvbnMiLCJtYXhQYXNzd29yZEFnZSIsInJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uIiwidmFsaWRhdG9yUGF0dGVybiIsIlJlZ0V4cCIsInZhbGlkYXRvckNhbGxiYWNrIiwiZG9Ob3RBbGxvd1VzZXJuYW1lIiwibWF4UGFzc3dvcmRIaXN0b3J5IiwicmVzZXRUb2tlblJldXNlSWZWYWxpZCIsInBhdHRlcm5WYWxpZGF0b3IiLCJ2YWx1ZSIsInRlc3QiLCJlIiwiUmVmZXJlbmNlRXJyb3IiLCJlbmFibGVGb3JBbm9ueW1vdXNVc2VyIiwiRmlsZVVwbG9hZE9wdGlvbnMiLCJlbmFibGVGb3JQdWJsaWMiLCJlbmFibGVGb3JBdXRoZW50aWNhdGVkVXNlciIsImlwIiwibmV0IiwiaXNJUCIsIl9tb3VudCIsIm5ld1ZhbHVlIiwiaW5jbHVkZXMiLCJpc0FycmF5IiwiaGVhZGVyIiwidHJpbSIsIm5vdyIsIkRhdGUiLCJnZXRUaW1lIiwiZ2VuZXJhdGVQYXNzd29yZFJlc2V0VG9rZW5FeHBpcmVzQXQiLCJpbnZhbGlkTGlua1VSTCIsImN1c3RvbVBhZ2VzIiwiaW52YWxpZExpbmsiLCJpbnZhbGlkVmVyaWZpY2F0aW9uTGlua1VSTCIsImludmFsaWRWZXJpZmljYXRpb25MaW5rIiwibGlua1NlbmRTdWNjZXNzVVJMIiwibGlua1NlbmRTdWNjZXNzIiwibGlua1NlbmRGYWlsVVJMIiwibGlua1NlbmRGYWlsIiwidmVyaWZ5RW1haWxTdWNjZXNzVVJMIiwidmVyaWZ5RW1haWxTdWNjZXNzIiwiY2hvb3NlUGFzc3dvcmRVUkwiLCJjaG9vc2VQYXNzd29yZCIsInJlcXVlc3RSZXNldFBhc3N3b3JkVVJMIiwicGFzc3dvcmRSZXNldFN1Y2Nlc3NVUkwiLCJwYXNzd29yZFJlc2V0U3VjY2VzcyIsInBhcnNlRnJhbWVVUkwiLCJ2ZXJpZnlFbWFpbFVSTCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFJQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFNQTs7OztBQWRBO0FBQ0E7QUFDQTtBQWNBLFNBQVNBLG1CQUFULENBQTZCQyxHQUE3QixFQUFrQztBQUNoQyxNQUFJLENBQUNBLEdBQUwsRUFBVTtBQUNSLFdBQU9BLEdBQVA7QUFDRDs7QUFDRCxNQUFJQSxHQUFHLENBQUNDLFFBQUosQ0FBYSxHQUFiLENBQUosRUFBdUI7QUFDckJELElBQUFBLEdBQUcsR0FBR0EsR0FBRyxDQUFDRSxNQUFKLENBQVcsQ0FBWCxFQUFjRixHQUFHLENBQUNHLE1BQUosR0FBYSxDQUEzQixDQUFOO0FBQ0Q7O0FBQ0QsU0FBT0gsR0FBUDtBQUNEOztBQUVNLE1BQU1JLE1BQU4sQ0FBYTtBQUNsQixT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V0FBTCxDQUFpQlcsY0FBakIsSUFBb0MsR0FBRSxLQUFLaEcsZUFBZ0IsdUJBQWxFO0FBQ0Q7O0FBRUQsTUFBSWlHLHVCQUFKLEdBQThCO0FBQzVCLFdBQVEsR0FBRSxLQUFLakcsZUFBZ0IsU0FBUSxLQUFLOUIsYUFBYyx5QkFBMUQ7QUFDRDs7QUFFRCxNQUFJZ0ksdUJBQUosR0FBOEI7QUFDNUIsV0FDRSxLQUFLYixXQUFMLENBQWlCYyxvQkFBakIsSUFDQyxHQUFFLEtBQUtuRyxlQUFnQixtQ0FGMUI7QUFJRDs7QUFFRCxNQUFJb0csYUFBSixHQUFvQjtBQUNsQixXQUFPLEtBQUtmLFdBQUwsQ0FBaUJlLGFBQXhCO0FBQ0Q7O0FBRUQsTUFBSUMsY0FBSixHQUFxQjtBQUNuQixXQUFRLEdBQUUsS0FBS3JHLGVBQWdCLFNBQVEsS0FBSzlCLGFBQWMsZUFBMUQ7QUFDRDs7QUEzYmlCOzs7ZUE4YkxGLE07O0FBQ2ZzSSxNQUFNLENBQUNDLE9BQVAsR0FBaUJ2SSxNQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEEgQ29uZmlnIG9iamVjdCBwcm92aWRlcyBpbmZvcm1hdGlvbiBhYm91dCBob3cgYSBzcGVjaWZpYyBhcHAgaXNcbi8vIGNvbmZpZ3VyZWQuXG4vLyBtb3VudCBpcyB0aGUgVVJMIGZvciB0aGUgcm9vdCBvZiB0aGUgQVBJOyBpbmNsdWRlcyBodHRwLCBkb21haW4sIGV0Yy5cblxuaW1wb3J0IEFwcENhY2hlIGZyb20gJy4vY2FjaGUnO1xuaW1wb3J0IFNjaGVtYUNhY2hlIGZyb20gJy4vQ29udHJvbGxlcnMvU2NoZW1hQ2FjaGUnO1xuaW1wb3J0IERhdGFiYXNlQ29udHJvbGxlciBmcm9tICcuL0NvbnRyb2xsZXJzL0RhdGFiYXNlQ29udHJvbGxlcic7XG5pbXBvcnQgbmV0IGZyb20gJ25ldCc7XG5pbXBvcnQge1xuICBJZGVtcG90ZW5jeU9wdGlvbnMsXG4gIEZpbGVVcGxvYWRPcHRpb25zLFxuICBBY2NvdW50TG9ja291dE9wdGlvbnMsXG4gIFBhZ2VzT3B0aW9ucyxcbn0gZnJvbSAnLi9PcHRpb25zL0RlZmluaXRpb25zJztcbmltcG9ydCB7IGlzQm9vbGVhbiwgaXNTdHJpbmcgfSBmcm9tICdsb2Rhc2gnO1xuXG5mdW5jdGlvbiByZW1vdmVUcmFpbGluZ1NsYXNoKHN0cikge1xuICBpZiAoIXN0cikge1xuICAgIHJldHVybiBzdHI7XG4gIH1cbiAgaWYgKHN0ci5lbmRzV2l0aCgnLycpKSB7XG4gICAgc3RyID0gc3RyLnN1YnN0cigwLCBzdHIubGVuZ3RoIC0gMSk7XG4gIH1cbiAgcmV0dXJuIHN0cjtcbn1cblxuZXhwb3J0IGNsYXNzIENvbmZpZyB7XG4gIHN0YXRpYyBnZXQoYXBwbGljYXRpb25JZDogc3RyaW5nLCBtb3VudDogc3RyaW5nKSB7XG4gICAgY29uc3QgY2FjaGVJbmZvID0gQXBwQ2FjaGUuZ2V0KGFwcGxpY2F0aW9uSWQpO1xuICAgIGlmICghY2FjaGVJbmZvKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBDb25maWcoKTtcbiAgICBjb25maWcuYXBwbGljYXRpb25JZCA9IGFwcGxpY2F0aW9uSWQ7XG4gICAgT2JqZWN0LmtleXMoY2FjaGVJbmZvKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBpZiAoa2V5ID09ICdkYXRhYmFzZUNvbnRyb2xsZXInKSB7XG4gICAgICAgIGNvbnN0IHNjaGVtYUNhY2hlID0gbmV3IFNjaGVtYUNhY2hlKFxuICAgICAgICAgIGNhY2hlSW5mby5jYWNoZUNvbnRyb2xsZXIsXG4gICAgICAgICAgY2FjaGVJbmZvLnNjaGVtYUNhY2hlVFRMLFxuICAgICAgICAgIGNhY2hlSW5mby5lbmFibGVTaW5nbGVTY2hlbWFDYWNoZVxuICAgICAgICApO1xuICAgICAgICBjb25maWcuZGF0YWJhc2UgPSBuZXcgRGF0YWJhc2VDb250cm9sbGVyKGNhY2hlSW5mby5kYXRhYmFzZUNvbnRyb2xsZXIuYWRhcHRlciwgc2NoZW1hQ2FjaGUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uZmlnW2tleV0gPSBjYWNoZUluZm9ba2V5XTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25maWcubW91bnQgPSByZW1vdmVUcmFpbGluZ1NsYXNoKG1vdW50KTtcbiAgICBjb25maWcuZ2VuZXJhdGVTZXNzaW9uRXhwaXJlc0F0ID0gY29uZmlnLmdlbmVyYXRlU2Vzc2lvbkV4cGlyZXNBdC5iaW5kKGNvbmZpZyk7XG4gICAgY29uZmlnLmdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbkV4cGlyZXNBdCA9IGNvbmZpZy5nZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW5FeHBpcmVzQXQuYmluZChcbiAgICAgIGNvbmZpZ1xuICAgICk7XG4gICAgcmV0dXJuIGNvbmZpZztcbiAgfVxuXG4gIHN0YXRpYyBwdXQoc2VydmVyQ29uZmlndXJhdGlvbikge1xuICAgIENvbmZpZy52YWxpZGF0ZShzZXJ2ZXJDb25maWd1cmF0aW9uKTtcbiAgICBBcHBDYWNoZS5wdXQoc2VydmVyQ29uZmlndXJhdGlvbi5hcHBJZCwgc2VydmVyQ29uZmlndXJhdGlvbik7XG4gICAgQ29uZmlnLnNldHVwUGFzc3dvcmRWYWxpZGF0b3Ioc2VydmVyQ29uZmlndXJhdGlvbi5wYXNzd29yZFBvbGljeSk7XG4gICAgcmV0dXJuIHNlcnZlckNvbmZpZ3VyYXRpb247XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGUoe1xuICAgIHZlcmlmeVVzZXJFbWFpbHMsXG4gICAgdXNlckNvbnRyb2xsZXIsXG4gICAgYXBwTmFtZSxcbiAgICBwdWJsaWNTZXJ2ZXJVUkwsXG4gICAgcmV2b2tlU2Vzc2lvbk9uUGFzc3dvcmRSZXNldCxcbiAgICBleHBpcmVJbmFjdGl2ZVNlc3Npb25zLFxuICAgIHNlc3Npb25MZW5ndGgsXG4gICAgbWF4TGltaXQsXG4gICAgZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24sXG4gICAgYWNjb3VudExvY2tvdXQsXG4gICAgcGFzc3dvcmRQb2xpY3ksXG4gICAgbWFzdGVyS2V5SXBzLFxuICAgIG1hc3RlcktleSxcbiAgICByZWFkT25seU1hc3RlcktleSxcbiAgICBhbGxvd0hlYWRlcnMsXG4gICAgaWRlbXBvdGVuY3lPcHRpb25zLFxuICAgIGVtYWlsVmVyaWZ5VG9rZW5SZXVzZUlmVmFsaWQsXG4gICAgZmlsZVVwbG9hZCxcbiAgICBwYWdlcyxcbiAgfSkge1xuICAgIGlmIChtYXN0ZXJLZXkgPT09IHJlYWRPbmx5TWFzdGVyS2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ21hc3RlcktleSBhbmQgcmVhZE9ubHlNYXN0ZXJLZXkgc2hvdWxkIGJlIGRpZmZlcmVudCcpO1xuICAgIH1cblxuICAgIGNvbnN0IGVtYWlsQWRhcHRlciA9IHVzZXJDb250cm9sbGVyLmFkYXB0ZXI7XG4gICAgaWYgKHZlcmlmeVVzZXJFbWFpbHMpIHtcbiAgICAgIHRoaXMudmFsaWRhdGVFbWFpbENvbmZpZ3VyYXRpb24oe1xuICAgICAgICBlbWFpbEFkYXB0ZXIsXG4gICAgICAgIGFwcE5hbWUsXG4gICAgICAgIHB1YmxpY1NlcnZlclVSTCxcbiAgICAgICAgZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24sXG4gICAgICAgIGVtYWlsVmVyaWZ5VG9rZW5SZXVzZUlmVmFsaWQsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLnZhbGlkYXRlQWNjb3VudExvY2tvdXRQb2xpY3koYWNjb3VudExvY2tvdXQpO1xuICAgIHRoaXMudmFsaWRhdGVQYXNzd29yZFBvbGljeShwYXNzd29yZFBvbGljeSk7XG4gICAgdGhpcy52YWxpZGF0ZUZpbGVVcGxvYWRPcHRpb25zKGZpbGVVcGxvYWQpO1xuXG4gICAgaWYgKHR5cGVvZiByZXZva2VTZXNzaW9uT25QYXNzd29yZFJlc2V0ICE9PSAnYm9vbGVhbicpIHtcbiAgICAgIHRocm93ICdyZXZva2VTZXNzaW9uT25QYXNzd29yZFJlc2V0IG11c3QgYmUgYSBib29sZWFuIHZhbHVlJztcbiAgICB9XG5cbiAgICBpZiAocHVibGljU2VydmVyVVJMKSB7XG4gICAgICBpZiAoIXB1YmxpY1NlcnZlclVSTC5zdGFydHNXaXRoKCdodHRwOi8vJykgJiYgIXB1YmxpY1NlcnZlclVSTC5zdGFydHNXaXRoKCdodHRwczovLycpKSB7XG4gICAgICAgIHRocm93ICdwdWJsaWNTZXJ2ZXJVUkwgc2hvdWxkIGJlIGEgdmFsaWQgSFRUUFMgVVJMIHN0YXJ0aW5nIHdpdGggaHR0cHM6Ly8nO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnZhbGlkYXRlU2Vzc2lvbkNvbmZpZ3VyYXRpb24oc2Vzc2lvbkxlbmd0aCwgZXhwaXJlSW5hY3RpdmVTZXNzaW9ucyk7XG4gICAgdGhpcy52YWxpZGF0ZU1hc3RlcktleUlwcyhtYXN0ZXJLZXlJcHMpO1xuICAgIHRoaXMudmFsaWRhdGVNYXhMaW1pdChtYXhMaW1pdCk7XG4gICAgdGhpcy52YWxpZGF0ZUFsbG93SGVhZGVycyhhbGxvd0hlYWRlcnMpO1xuICAgIHRoaXMudmFsaWRhdGVJZGVtcG90ZW5jeU9wdGlvbnMoaWRlbXBvdGVuY3lPcHRpb25zKTtcbiAgICB0aGlzLnZhbGlkYXRlUGFnZXNPcHRpb25zKHBhZ2VzKTtcbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZVBhZ2VzT3B0aW9ucyhwYWdlcykge1xuICAgIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwocGFnZXMpICE9PSAnW29iamVjdCBPYmplY3RdJykge1xuICAgICAgdGhyb3cgJ1BhcnNlIFNlcnZlciBvcHRpb24gcGFnZXMgbXVzdCBiZSBhbiBvYmplY3QuJztcbiAgICB9XG4gICAgaWYgKHBhZ2VzLmVuYWJsZVJvdXRlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBwYWdlcy5lbmFibGVSb3V0ZXIgPSBQYWdlc09wdGlvbnMuZW5hYmxlUm91dGVyLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICghaXNCb29sZWFuKHBhZ2VzLmVuYWJsZVJvdXRlcikpIHtcbiAgICAgIHRocm93ICdQYXJzZSBTZXJ2ZXIgb3B0aW9uIHBhZ2VzLmVuYWJsZVJvdXRlciBtdXN0IGJlIGEgYm9vbGVhbi4nO1xuICAgIH1cbiAgICBpZiAocGFnZXMuZW5hYmxlTG9jYWxpemF0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHBhZ2VzLmVuYWJsZUxvY2FsaXphdGlvbiA9IFBhZ2VzT3B0aW9ucy5lbmFibGVMb2NhbGl6YXRpb24uZGVmYXVsdDtcbiAgICB9IGVsc2UgaWYgKCFpc0Jvb2xlYW4ocGFnZXMuZW5hYmxlTG9jYWxpemF0aW9uKSkge1xuICAgICAgdGhyb3cgJ1BhcnNlIFNlcnZlciBvcHRpb24gcGFnZXMuZW5hYmxlTG9jYWxpemF0aW9uIG11c3QgYmUgYSBib29sZWFuLic7XG4gICAgfVxuICAgIGlmIChwYWdlcy5sb2NhbGl6YXRpb25Kc29uUGF0aCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBwYWdlcy5sb2NhbGl6YXRpb25Kc29uUGF0aCA9IFBhZ2VzT3B0aW9ucy5sb2NhbGl6YXRpb25Kc29uUGF0aC5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAoIWlzU3RyaW5nKHBhZ2VzLmxvY2FsaXphdGlvbkpzb25QYXRoKSkge1xuICAgICAgdGhyb3cgJ1BhcnNlIFNlcnZlciBvcHRpb24gcGFnZXMubG9jYWxpemF0aW9uSnNvblBhdGggbXVzdCBiZSBhIHN0cmluZy4nO1xuICAgIH1cbiAgICBpZiAocGFnZXMubG9jYWxpemF0aW9uRmFsbGJhY2tMb2NhbGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcGFnZXMubG9jYWxpemF0aW9uRmFsbGJhY2tMb2NhbGUgPSBQYWdlc09wdGlvbnMubG9jYWxpemF0aW9uRmFsbGJhY2tMb2NhbGUuZGVmYXVsdDtcbiAgICB9IGVsc2UgaWYgKCFpc1N0cmluZyhwYWdlcy5sb2NhbGl6YXRpb25GYWxsYmFja0xvY2FsZSkpIHtcbiAgICAgIHRocm93ICdQYXJzZSBTZXJ2ZXIgb3B0aW9uIHBhZ2VzLmxvY2FsaXphdGlvbkZhbGxiYWNrTG9jYWxlIG11c3QgYmUgYSBzdHJpbmcuJztcbiAgICB9XG4gICAgaWYgKHBhZ2VzLnBsYWNlaG9sZGVycyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBwYWdlcy5wbGFjZWhvbGRlcnMgPSBQYWdlc09wdGlvbnMucGxhY2Vob2xkZXJzLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChwYWdlcy5wbGFjZWhvbGRlcnMpICE9PSAnW29iamVjdCBPYmplY3RdJyAmJlxuICAgICAgdHlwZW9mIHBhZ2VzLnBsYWNlaG9sZGVycyAhPT0gJ2Z1bmN0aW9uJ1xuICAgICkge1xuICAgICAgdGhyb3cgJ1BhcnNlIFNlcnZlciBvcHRpb24gcGFnZXMucGxhY2Vob2xkZXJzIG11c3QgYmUgYW4gb2JqZWN0IG9yIGEgZnVuY3Rpb24uJztcbiAgICB9XG4gICAgaWYgKHBhZ2VzLmZvcmNlUmVkaXJlY3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcGFnZXMuZm9yY2VSZWRpcmVjdCA9IFBhZ2VzT3B0aW9ucy5mb3JjZVJlZGlyZWN0LmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICghaXNCb29sZWFuKHBhZ2VzLmZvcmNlUmVkaXJlY3QpKSB7XG4gICAgICB0aHJvdyAnUGFyc2UgU2VydmVyIG9wdGlvbiBwYWdlcy5mb3JjZVJlZGlyZWN0IG11c3QgYmUgYSBib29sZWFuLic7XG4gICAgfVxuICAgIGlmIChwYWdlcy5wYWdlc1BhdGggPT09IHVuZGVmaW5lZCkge1xuICAgICAgcGFnZXMucGFnZXNQYXRoID0gUGFnZXNPcHRpb25zLnBhZ2VzUGF0aC5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAoIWlzU3RyaW5nKHBhZ2VzLnBhZ2VzUGF0aCkpIHtcbiAgICAgIHRocm93ICdQYXJzZSBTZXJ2ZXIgb3B0aW9uIHBhZ2VzLnBhZ2VzUGF0aCBtdXN0IGJlIGEgc3RyaW5nLic7XG4gICAgfVxuICAgIGlmIChwYWdlcy5wYWdlc0VuZHBvaW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHBhZ2VzLnBhZ2VzRW5kcG9pbnQgPSBQYWdlc09wdGlvbnMucGFnZXNFbmRwb2ludC5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAoIWlzU3RyaW5nKHBhZ2VzLnBhZ2VzRW5kcG9pbnQpKSB7XG4gICAgICB0aHJvdyAnUGFyc2UgU2VydmVyIG9wdGlvbiBwYWdlcy5wYWdlc0VuZHBvaW50IG11c3QgYmUgYSBzdHJpbmcuJztcbiAgICB9XG4gICAgaWYgKHBhZ2VzLmN1c3RvbVVybHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcGFnZXMuY3VzdG9tVXJscyA9IFBhZ2VzT3B0aW9ucy5jdXN0b21VcmxzLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwocGFnZXMuY3VzdG9tVXJscykgIT09ICdbb2JqZWN0IE9iamVjdF0nKSB7XG4gICAgICB0aHJvdyAnUGFyc2UgU2VydmVyIG9wdGlvbiBwYWdlcy5jdXN0b21VcmxzIG11c3QgYmUgYW4gb2JqZWN0Lic7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlSWRlbXBvdGVuY3lPcHRpb25zKGlkZW1wb3RlbmN5T3B0aW9ucykge1xuICAgIGlmICghaWRlbXBvdGVuY3lPcHRpb25zKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChpZGVtcG90ZW5jeU9wdGlvbnMudHRsID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGlkZW1wb3RlbmN5T3B0aW9ucy50dGwgPSBJZGVtcG90ZW5jeU9wdGlvbnMudHRsLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICghaXNOYU4oaWRlbXBvdGVuY3lPcHRpb25zLnR0bCkgJiYgaWRlbXBvdGVuY3lPcHRpb25zLnR0bCA8PSAwKSB7XG4gICAgICB0aHJvdyAnaWRlbXBvdGVuY3kgVFRMIHZhbHVlIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAgc2Vjb25kcyc7XG4gICAgfSBlbHNlIGlmIChpc05hTihpZGVtcG90ZW5jeU9wdGlvbnMudHRsKSkge1xuICAgICAgdGhyb3cgJ2lkZW1wb3RlbmN5IFRUTCB2YWx1ZSBtdXN0IGJlIGEgbnVtYmVyJztcbiAgICB9XG4gICAgaWYgKCFpZGVtcG90ZW5jeU9wdGlvbnMucGF0aHMpIHtcbiAgICAgIGlkZW1wb3RlbmN5T3B0aW9ucy5wYXRocyA9IElkZW1wb3RlbmN5T3B0aW9ucy5wYXRocy5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAoIShpZGVtcG90ZW5jeU9wdGlvbnMucGF0aHMgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICAgIHRocm93ICdpZGVtcG90ZW5jeSBwYXRocyBtdXN0IGJlIG9mIGFuIGFycmF5IG9mIHN0cmluZ3MnO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZUFjY291bnRMb2Nrb3V0UG9saWN5KGFjY291bnRMb2Nrb3V0KSB7XG4gICAgaWYgKGFjY291bnRMb2Nrb3V0KSB7XG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiBhY2NvdW50TG9ja291dC5kdXJhdGlvbiAhPT0gJ251bWJlcicgfHxcbiAgICAgICAgYWNjb3VudExvY2tvdXQuZHVyYXRpb24gPD0gMCB8fFxuICAgICAgICBhY2NvdW50TG9ja291dC5kdXJhdGlvbiA+IDk5OTk5XG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgJ0FjY291bnQgbG9ja291dCBkdXJhdGlvbiBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIDAgYW5kIGxlc3MgdGhhbiAxMDAwMDAnO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgICFOdW1iZXIuaXNJbnRlZ2VyKGFjY291bnRMb2Nrb3V0LnRocmVzaG9sZCkgfHxcbiAgICAgICAgYWNjb3VudExvY2tvdXQudGhyZXNob2xkIDwgMSB8fFxuICAgICAgICBhY2NvdW50TG9ja291dC50aHJlc2hvbGQgPiA5OTlcbiAgICAgICkge1xuICAgICAgICB0aHJvdyAnQWNjb3VudCBsb2Nrb3V0IHRocmVzaG9sZCBzaG91bGQgYmUgYW4gaW50ZWdlciBncmVhdGVyIHRoYW4gMCBhbmQgbGVzcyB0aGFuIDEwMDAnO1xuICAgICAgfVxuXG4gICAgICBpZiAoYWNjb3VudExvY2tvdXQudW5sb2NrT25QYXNzd29yZFJlc2V0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYWNjb3VudExvY2tvdXQudW5sb2NrT25QYXNzd29yZFJlc2V0ID0gQWNjb3VudExvY2tvdXRPcHRpb25zLnVubG9ja09uUGFzc3dvcmRSZXNldC5kZWZhdWx0O1xuICAgICAgfSBlbHNlIGlmICghaXNCb29sZWFuKGFjY291bnRMb2Nrb3V0LnVubG9ja09uUGFzc3dvcmRSZXNldCkpIHtcbiAgICAgICAgdGhyb3cgJ1BhcnNlIFNlcnZlciBvcHRpb24gYWNjb3VudExvY2tvdXQudW5sb2NrT25QYXNzd29yZFJlc2V0IG11c3QgYmUgYSBib29sZWFuLic7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlUGFzc3dvcmRQb2xpY3kocGFzc3dvcmRQb2xpY3kpIHtcbiAgICBpZiAocGFzc3dvcmRQb2xpY3kpIHtcbiAgICAgIGlmIChcbiAgICAgICAgcGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRBZ2UgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAodHlwZW9mIHBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkQWdlICE9PSAnbnVtYmVyJyB8fCBwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEFnZSA8IDApXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgJ3Bhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkQWdlIG11c3QgYmUgYSBwb3NpdGl2ZSBudW1iZXInO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIHBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgKHR5cGVvZiBwYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbiAhPT0gJ251bWJlcicgfHxcbiAgICAgICAgICBwYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbiA8PSAwKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93ICdwYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbiBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJztcbiAgICAgIH1cblxuICAgICAgaWYgKHBhc3N3b3JkUG9saWN5LnZhbGlkYXRvclBhdHRlcm4pIHtcbiAgICAgICAgaWYgKHR5cGVvZiBwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIHBhc3N3b3JkUG9saWN5LnZhbGlkYXRvclBhdHRlcm4gPSBuZXcgUmVnRXhwKHBhc3N3b3JkUG9saWN5LnZhbGlkYXRvclBhdHRlcm4pO1xuICAgICAgICB9IGVsc2UgaWYgKCEocGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yUGF0dGVybiBpbnN0YW5jZW9mIFJlZ0V4cCkpIHtcbiAgICAgICAgICB0aHJvdyAncGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yUGF0dGVybiBtdXN0IGJlIGEgcmVnZXggc3RyaW5nIG9yIFJlZ0V4cCBvYmplY3QuJztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIHBhc3N3b3JkUG9saWN5LnZhbGlkYXRvckNhbGxiYWNrICYmXG4gICAgICAgIHR5cGVvZiBwYXNzd29yZFBvbGljeS52YWxpZGF0b3JDYWxsYmFjayAhPT0gJ2Z1bmN0aW9uJ1xuICAgICAgKSB7XG4gICAgICAgIHRocm93ICdwYXNzd29yZFBvbGljeS52YWxpZGF0b3JDYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24uJztcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBwYXNzd29yZFBvbGljeS5kb05vdEFsbG93VXNlcm5hbWUgJiZcbiAgICAgICAgdHlwZW9mIHBhc3N3b3JkUG9saWN5LmRvTm90QWxsb3dVc2VybmFtZSAhPT0gJ2Jvb2xlYW4nXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgJ3Bhc3N3b3JkUG9saWN5LmRvTm90QWxsb3dVc2VybmFtZSBtdXN0IGJlIGEgYm9vbGVhbiB2YWx1ZS4nO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIHBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeSAmJlxuICAgICAgICAoIU51bWJlci5pc0ludGVnZXIocGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRIaXN0b3J5KSB8fFxuICAgICAgICAgIHBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeSA8PSAwIHx8XG4gICAgICAgICAgcGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRIaXN0b3J5ID4gMjApXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgJ3Bhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeSBtdXN0IGJlIGFuIGludGVnZXIgcmFuZ2luZyAwIC0gMjAnO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIHBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5SZXVzZUlmVmFsaWQgJiZcbiAgICAgICAgdHlwZW9mIHBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5SZXVzZUlmVmFsaWQgIT09ICdib29sZWFuJ1xuICAgICAgKSB7XG4gICAgICAgIHRocm93ICdyZXNldFRva2VuUmV1c2VJZlZhbGlkIG11c3QgYmUgYSBib29sZWFuIHZhbHVlJztcbiAgICAgIH1cbiAgICAgIGlmIChwYXNzd29yZFBvbGljeS5yZXNldFRva2VuUmV1c2VJZlZhbGlkICYmICFwYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbikge1xuICAgICAgICB0aHJvdyAnWW91IGNhbm5vdCB1c2UgcmVzZXRUb2tlblJldXNlSWZWYWxpZCB3aXRob3V0IHJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uJztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGUgcGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yUGF0dGVybiBpcyBjb25maWd1cmVkIHRoZW4gc2V0dXAgYSBjYWxsYmFjayB0byBwcm9jZXNzIHRoZSBwYXR0ZXJuXG4gIHN0YXRpYyBzZXR1cFBhc3N3b3JkVmFsaWRhdG9yKHBhc3N3b3JkUG9saWN5KSB7XG4gICAgaWYgKHBhc3N3b3JkUG9saWN5ICYmIHBhc3N3b3JkUG9saWN5LnZhbGlkYXRvclBhdHRlcm4pIHtcbiAgICAgIHBhc3N3b3JkUG9saWN5LnBhdHRlcm5WYWxpZGF0b3IgPSB2YWx1ZSA9PiB7XG4gICAgICAgIHJldHVybiBwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuLnRlc3QodmFsdWUpO1xuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVFbWFpbENvbmZpZ3VyYXRpb24oe1xuICAgIGVtYWlsQWRhcHRlcixcbiAgICBhcHBOYW1lLFxuICAgIHB1YmxpY1NlcnZlclVSTCxcbiAgICBlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbixcbiAgICBlbWFpbFZlcmlmeVRva2VuUmV1c2VJZlZhbGlkLFxuICB9KSB7XG4gICAgaWYgKCFlbWFpbEFkYXB0ZXIpIHtcbiAgICAgIHRocm93ICdBbiBlbWFpbEFkYXB0ZXIgaXMgcmVxdWlyZWQgZm9yIGUtbWFpbCB2ZXJpZmljYXRpb24gYW5kIHBhc3N3b3JkIHJlc2V0cy4nO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGFwcE5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyAnQW4gYXBwIG5hbWUgaXMgcmVxdWlyZWQgZm9yIGUtbWFpbCB2ZXJpZmljYXRpb24gYW5kIHBhc3N3b3JkIHJlc2V0cy4nO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHB1YmxpY1NlcnZlclVSTCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93ICdBIHB1YmxpYyBzZXJ2ZXIgdXJsIGlzIHJlcXVpcmVkIGZvciBlLW1haWwgdmVyaWZpY2F0aW9uIGFuZCBwYXNzd29yZCByZXNldHMuJztcbiAgICB9XG4gICAgaWYgKGVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSB7XG4gICAgICBpZiAoaXNOYU4oZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24pKSB7XG4gICAgICAgIHRocm93ICdFbWFpbCB2ZXJpZnkgdG9rZW4gdmFsaWRpdHkgZHVyYXRpb24gbXVzdCBiZSBhIHZhbGlkIG51bWJlci4nO1xuICAgICAgfSBlbHNlIGlmIChlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbiA8PSAwKSB7XG4gICAgICAgIHRocm93ICdFbWFpbCB2ZXJpZnkgdG9rZW4gdmFsaWRpdHkgZHVyYXRpb24gbXVzdCBiZSBhIHZhbHVlIGdyZWF0ZXIgdGhhbiAwLic7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlbWFpbFZlcmlmeVRva2VuUmV1c2VJZlZhbGlkICYmIHR5cGVvZiBlbWFpbFZlcmlmeVRva2VuUmV1c2VJZlZhbGlkICE9PSAnYm9vbGVhbicpIHtcbiAgICAgIHRocm93ICdlbWFpbFZlcmlmeVRva2VuUmV1c2VJZlZhbGlkIG11c3QgYmUgYSBib29sZWFuIHZhbHVlJztcbiAgICB9XG4gICAgaWYgKGVtYWlsVmVyaWZ5VG9rZW5SZXVzZUlmVmFsaWQgJiYgIWVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSB7XG4gICAgICB0aHJvdyAnWW91IGNhbm5vdCB1c2UgZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZCB3aXRob3V0IGVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uJztcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVGaWxlVXBsb2FkT3B0aW9ucyhmaWxlVXBsb2FkKSB7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChmaWxlVXBsb2FkID09IG51bGwgfHwgdHlwZW9mIGZpbGVVcGxvYWQgIT09ICdvYmplY3QnIHx8IGZpbGVVcGxvYWQgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICB0aHJvdyAnZmlsZVVwbG9hZCBtdXN0IGJlIGFuIG9iamVjdCB2YWx1ZS4nO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChlIGluc3RhbmNlb2YgUmVmZXJlbmNlRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gICAgaWYgKGZpbGVVcGxvYWQuZW5hYmxlRm9yQW5vbnltb3VzVXNlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBmaWxlVXBsb2FkLmVuYWJsZUZvckFub255bW91c1VzZXIgPSBGaWxlVXBsb2FkT3B0aW9ucy5lbmFibGVGb3JBbm9ueW1vdXNVc2VyLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZmlsZVVwbG9hZC5lbmFibGVGb3JBbm9ueW1vdXNVc2VyICE9PSAnYm9vbGVhbicpIHtcbiAgICAgIHRocm93ICdmaWxlVXBsb2FkLmVuYWJsZUZvckFub255bW91c1VzZXIgbXVzdCBiZSBhIGJvb2xlYW4gdmFsdWUuJztcbiAgICB9XG4gICAgaWYgKGZpbGVVcGxvYWQuZW5hYmxlRm9yUHVibGljID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGZpbGVVcGxvYWQuZW5hYmxlRm9yUHVibGljID0gRmlsZVVwbG9hZE9wdGlvbnMuZW5hYmxlRm9yUHVibGljLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZmlsZVVwbG9hZC5lbmFibGVGb3JQdWJsaWMgIT09ICdib29sZWFuJykge1xuICAgICAgdGhyb3cgJ2ZpbGVVcGxvYWQuZW5hYmxlRm9yUHVibGljIG11c3QgYmUgYSBib29sZWFuIHZhbHVlLic7XG4gICAgfVxuICAgIGlmIChmaWxlVXBsb2FkLmVuYWJsZUZvckF1dGhlbnRpY2F0ZWRVc2VyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGZpbGVVcGxvYWQuZW5hYmxlRm9yQXV0aGVudGljYXRlZFVzZXIgPSBGaWxlVXBsb2FkT3B0aW9ucy5lbmFibGVGb3JBdXRoZW50aWNhdGVkVXNlci5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGZpbGVVcGxvYWQuZW5hYmxlRm9yQXV0aGVudGljYXRlZFVzZXIgIT09ICdib29sZWFuJykge1xuICAgICAgdGhyb3cgJ2ZpbGVVcGxvYWQuZW5hYmxlRm9yQXV0aGVudGljYXRlZFVzZXIgbXVzdCBiZSBhIGJvb2xlYW4gdmFsdWUuJztcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVNYXN0ZXJLZXlJcHMobWFzdGVyS2V5SXBzKSB7XG4gICAgZm9yIChjb25zdCBpcCBvZiBtYXN0ZXJLZXlJcHMpIHtcbiAgICAgIGlmICghbmV0LmlzSVAoaXApKSB7XG4gICAgICAgIHRocm93IGBJbnZhbGlkIGlwIGluIG1hc3RlcktleUlwczogJHtpcH1gO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGdldCBtb3VudCgpIHtcbiAgICB2YXIgbW91bnQgPSB0aGlzLl9tb3VudDtcbiAgICBpZiAodGhpcy5wdWJsaWNTZXJ2ZXJVUkwpIHtcbiAgICAgIG1vdW50ID0gdGhpcy5wdWJsaWNTZXJ2ZXJVUkw7XG4gICAgfVxuICAgIHJldHVybiBtb3VudDtcbiAgfVxuXG4gIHNldCBtb3VudChuZXdWYWx1ZSkge1xuICAgIHRoaXMuX21vdW50ID0gbmV3VmFsdWU7XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVTZXNzaW9uQ29uZmlndXJhdGlvbihzZXNzaW9uTGVuZ3RoLCBleHBpcmVJbmFjdGl2ZVNlc3Npb25zKSB7XG4gICAgaWYgKGV4cGlyZUluYWN0aXZlU2Vzc2lvbnMpIHtcbiAgICAgIGlmIChpc05hTihzZXNzaW9uTGVuZ3RoKSkge1xuICAgICAgICB0aHJvdyAnU2Vzc2lvbiBsZW5ndGggbXVzdCBiZSBhIHZhbGlkIG51bWJlci4nO1xuICAgICAgfSBlbHNlIGlmIChzZXNzaW9uTGVuZ3RoIDw9IDApIHtcbiAgICAgICAgdGhyb3cgJ1Nlc3Npb24gbGVuZ3RoIG11c3QgYmUgYSB2YWx1ZSBncmVhdGVyIHRoYW4gMC4nO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZU1heExpbWl0KG1heExpbWl0KSB7XG4gICAgaWYgKG1heExpbWl0IDw9IDApIHtcbiAgICAgIHRocm93ICdNYXggbGltaXQgbXVzdCBiZSBhIHZhbHVlIGdyZWF0ZXIgdGhhbiAwLic7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlQWxsb3dIZWFkZXJzKGFsbG93SGVhZGVycykge1xuICAgIGlmICghW251bGwsIHVuZGVmaW5lZF0uaW5jbHVkZXMoYWxsb3dIZWFkZXJzKSkge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYWxsb3dIZWFkZXJzKSkge1xuICAgICAgICBhbGxvd0hlYWRlcnMuZm9yRWFjaChoZWFkZXIgPT4ge1xuICAgICAgICAgIGlmICh0eXBlb2YgaGVhZGVyICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGhyb3cgJ0FsbG93IGhlYWRlcnMgbXVzdCBvbmx5IGNvbnRhaW4gc3RyaW5ncyc7XG4gICAgICAgICAgfSBlbHNlIGlmICghaGVhZGVyLnRyaW0oKS5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93ICdBbGxvdyBoZWFkZXJzIG11c3Qgbm90IGNvbnRhaW4gZW1wdHkgc3RyaW5ncyc7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93ICdBbGxvdyBoZWFkZXJzIG11c3QgYmUgYW4gYXJyYXknO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbkV4cGlyZXNBdCgpIHtcbiAgICBpZiAoIXRoaXMudmVyaWZ5VXNlckVtYWlscyB8fCAhdGhpcy5lbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbikge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgdmFyIG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgcmV0dXJuIG5ldyBEYXRlKG5vdy5nZXRUaW1lKCkgKyB0aGlzLmVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uICogMTAwMCk7XG4gIH1cblxuICBnZW5lcmF0ZVBhc3N3b3JkUmVzZXRUb2tlbkV4cGlyZXNBdCgpIHtcbiAgICBpZiAoIXRoaXMucGFzc3dvcmRQb2xpY3kgfHwgIXRoaXMucGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24pIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgcmV0dXJuIG5ldyBEYXRlKG5vdy5nZXRUaW1lKCkgKyB0aGlzLnBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uICogMTAwMCk7XG4gIH1cblxuICBnZW5lcmF0ZVNlc3Npb25FeHBpcmVzQXQoKSB7XG4gICAgaWYgKCF0aGlzLmV4cGlyZUluYWN0aXZlU2Vzc2lvbnMpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHZhciBub3cgPSBuZXcgRGF0ZSgpO1xuICAgIHJldHVybiBuZXcgRGF0ZShub3cuZ2V0VGltZSgpICsgdGhpcy5zZXNzaW9uTGVuZ3RoICogMTAwMCk7XG4gIH1cblxuICBnZXQgaW52YWxpZExpbmtVUkwoKSB7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tUGFnZXMuaW52YWxpZExpbmsgfHwgYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9L2FwcHMvaW52YWxpZF9saW5rLmh0bWxgO1xuICB9XG5cbiAgZ2V0IGludmFsaWRWZXJpZmljYXRpb25MaW5rVVJMKCkge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmN1c3RvbVBhZ2VzLmludmFsaWRWZXJpZmljYXRpb25MaW5rIHx8XG4gICAgICBgJHt0aGlzLnB1YmxpY1NlcnZlclVSTH0vYXBwcy9pbnZhbGlkX3ZlcmlmaWNhdGlvbl9saW5rLmh0bWxgXG4gICAgKTtcbiAgfVxuXG4gIGdldCBsaW5rU2VuZFN1Y2Nlc3NVUkwoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuY3VzdG9tUGFnZXMubGlua1NlbmRTdWNjZXNzIHx8IGAke3RoaXMucHVibGljU2VydmVyVVJMfS9hcHBzL2xpbmtfc2VuZF9zdWNjZXNzLmh0bWxgXG4gICAgKTtcbiAgfVxuXG4gIGdldCBsaW5rU2VuZEZhaWxVUkwoKSB7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tUGFnZXMubGlua1NlbmRGYWlsIHx8IGAke3RoaXMucHVibGljU2VydmVyVVJMfS9hcHBzL2xpbmtfc2VuZF9mYWlsLmh0bWxgO1xuICB9XG5cbiAgZ2V0IHZlcmlmeUVtYWlsU3VjY2Vzc1VSTCgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5jdXN0b21QYWdlcy52ZXJpZnlFbWFpbFN1Y2Nlc3MgfHxcbiAgICAgIGAke3RoaXMucHVibGljU2VydmVyVVJMfS9hcHBzL3ZlcmlmeV9lbWFpbF9zdWNjZXNzLmh0bWxgXG4gICAgKTtcbiAgfVxuXG4gIGdldCBjaG9vc2VQYXNzd29yZFVSTCgpIHtcbiAgICByZXR1cm4gdGhpcy5jdXN0b21QYWdlcy5jaG9vc2VQYXNzd29yZCB8fCBgJHt0aGlzLnB1YmxpY1NlcnZlclVSTH0vYXBwcy9jaG9vc2VfcGFzc3dvcmRgO1xuICB9XG5cbiAgZ2V0IHJlcXVlc3RSZXNldFBhc3N3b3JkVVJMKCkge1xuICAgIHJldHVybiBgJHt0aGlzLnB1YmxpY1NlcnZlclVSTH0vYXBwcy8ke3RoaXMuYXBwbGljYXRpb25JZH0vcmVxdWVzdF9wYXNzd29yZF9yZXNldGA7XG4gIH1cblxuICBnZXQgcGFzc3dvcmRSZXNldFN1Y2Nlc3NVUkwoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuY3VzdG9tUGFnZXMucGFzc3dvcmRSZXNldFN1Y2Nlc3MgfHxcbiAgICAgIGAke3RoaXMucHVibGljU2VydmVyVVJMfS9hcHBzL3Bhc3N3b3JkX3Jlc2V0X3N1Y2Nlc3MuaHRtbGBcbiAgICApO1xuICB9XG5cbiAgZ2V0IHBhcnNlRnJhbWVVUkwoKSB7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tUGFnZXMucGFyc2VGcmFtZVVSTDtcbiAgfVxuXG4gIGdldCB2ZXJpZnlFbWFpbFVSTCgpIHtcbiAgICByZXR1cm4gYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9L2FwcHMvJHt0aGlzLmFwcGxpY2F0aW9uSWR9L3ZlcmlmeV9lbWFpbGA7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ29uZmlnO1xubW9kdWxlLmV4cG9ydHMgPSBDb25maWc7XG4iXX0= \ No newline at end of file diff --git a/lib/Controllers/AdaptableController.js b/lib/Controllers/AdaptableController.js deleted file mode 100644 index fca1d5c819..0000000000 --- a/lib/Controllers/AdaptableController.js +++ /dev/null @@ -1,88 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.AdaptableController = void 0; - -var _Config = _interopRequireDefault(require("../Config")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/* -AdaptableController.js - -AdaptableController is the base class for all controllers -that support adapter, -The super class takes care of creating the right instance for the adapter -based on the parameters passed - - */ -// _adapter is private, use Symbol -var _adapter = Symbol(); - -class AdaptableController { - constructor(adapter, appId, options) { - this.options = options; - this.appId = appId; - this.adapter = adapter; - } - - set adapter(adapter) { - this.validateAdapter(adapter); - this[_adapter] = adapter; - } - - get adapter() { - return this[_adapter]; - } - - get config() { - return _Config.default.get(this.appId); - } - - expectedAdapterType() { - throw new Error('Subclasses should implement expectedAdapterType()'); - } - - validateAdapter(adapter) { - AdaptableController.validateAdapter(adapter, this); - } - - static validateAdapter(adapter, self, ExpectedType) { - if (!adapter) { - throw new Error(this.constructor.name + ' requires an adapter'); - } - - const Type = ExpectedType || self.expectedAdapterType(); // Allow skipping for testing - - if (!Type) { - return; - } // Makes sure the prototype matches - - - const mismatches = Object.getOwnPropertyNames(Type.prototype).reduce((obj, key) => { - const adapterType = typeof adapter[key]; - const expectedType = typeof Type.prototype[key]; - - if (adapterType !== expectedType) { - obj[key] = { - expected: expectedType, - actual: adapterType - }; - } - - return obj; - }, {}); - - if (Object.keys(mismatches).length > 0) { - throw new Error("Adapter prototype don't match expected prototype", adapter, mismatches); - } - } - -} - -exports.AdaptableController = AdaptableController; -var _default = AdaptableController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9BZGFwdGFibGVDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIl9hZGFwdGVyIiwiU3ltYm9sIiwiQWRhcHRhYmxlQ29udHJvbGxlciIsImNvbnN0cnVjdG9yIiwiYWRhcHRlciIsImFwcElkIiwib3B0aW9ucyIsInZhbGlkYXRlQWRhcHRlciIsImNvbmZpZyIsIkNvbmZpZyIsImdldCIsImV4cGVjdGVkQWRhcHRlclR5cGUiLCJFcnJvciIsInNlbGYiLCJFeHBlY3RlZFR5cGUiLCJuYW1lIiwiVHlwZSIsIm1pc21hdGNoZXMiLCJPYmplY3QiLCJnZXRPd25Qcm9wZXJ0eU5hbWVzIiwicHJvdG90eXBlIiwicmVkdWNlIiwib2JqIiwia2V5IiwiYWRhcHRlclR5cGUiLCJleHBlY3RlZFR5cGUiLCJleHBlY3RlZCIsImFjdHVhbCIsImtleXMiLCJsZW5ndGgiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFZQTs7OztBQVpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBO0FBQ0EsSUFBSUEsUUFBUSxHQUFHQyxNQUFNLEVBQXJCOztBQUdPLE1BQU1DLG1CQUFOLENBQTBCO0FBQy9CQyxFQUFBQSxXQUFXLENBQUNDLE9BQUQsRUFBVUMsS0FBVixFQUFpQkMsT0FBakIsRUFBMEI7QUFDbkMsU0FBS0EsT0FBTCxHQUFlQSxPQUFmO0FBQ0EsU0FBS0QsS0FBTCxHQUFhQSxLQUFiO0FBQ0EsU0FBS0QsT0FBTCxHQUFlQSxPQUFmO0FBQ0Q7O0FBRUQsTUFBSUEsT0FBSixDQUFZQSxPQUFaLEVBQXFCO0FBQ25CLFNBQUtHLGVBQUwsQ0FBcUJILE9BQXJCO0FBQ0EsU0FBS0osUUFBTCxJQUFpQkksT0FBakI7QUFDRDs7QUFFRCxNQUFJQSxPQUFKLEdBQWM7QUFDWixXQUFPLEtBQUtKLFFBQUwsQ0FBUDtBQUNEOztBQUVELE1BQUlRLE1BQUosR0FBYTtBQUNYLFdBQU9DLGdCQUFPQyxHQUFQLENBQVcsS0FBS0wsS0FBaEIsQ0FBUDtBQUNEOztBQUVETSxFQUFBQSxtQkFBbUIsR0FBRztBQUNwQixVQUFNLElBQUlDLEtBQUosQ0FBVSxtREFBVixDQUFOO0FBQ0Q7O0FBRURMLEVBQUFBLGVBQWUsQ0FBQ0gsT0FBRCxFQUFVO0FBQ3ZCRixJQUFBQSxtQkFBbUIsQ0FBQ0ssZUFBcEIsQ0FBb0NILE9BQXBDLEVBQTZDLElBQTdDO0FBQ0Q7O0FBRUQsU0FBT0csZUFBUCxDQUF1QkgsT0FBdkIsRUFBZ0NTLElBQWhDLEVBQXNDQyxZQUF0QyxFQUFvRDtBQUNsRCxRQUFJLENBQUNWLE9BQUwsRUFBYztBQUNaLFlBQU0sSUFBSVEsS0FBSixDQUFVLEtBQUtULFdBQUwsQ0FBaUJZLElBQWpCLEdBQXdCLHNCQUFsQyxDQUFOO0FBQ0Q7O0FBRUQsVUFBTUMsSUFBSSxHQUFHRixZQUFZLElBQUlELElBQUksQ0FBQ0YsbUJBQUwsRUFBN0IsQ0FMa0QsQ0FNbEQ7O0FBQ0EsUUFBSSxDQUFDSyxJQUFMLEVBQVc7QUFDVDtBQUNELEtBVGlELENBV2xEOzs7QUFDQSxVQUFNQyxVQUFVLEdBQUdDLE1BQU0sQ0FBQ0MsbUJBQVAsQ0FBMkJILElBQUksQ0FBQ0ksU0FBaEMsRUFBMkNDLE1BQTNDLENBQWtELENBQUNDLEdBQUQsRUFBTUMsR0FBTixLQUFjO0FBQ2pGLFlBQU1DLFdBQVcsR0FBRyxPQUFPcEIsT0FBTyxDQUFDbUIsR0FBRCxDQUFsQztBQUNBLFlBQU1FLFlBQVksR0FBRyxPQUFPVCxJQUFJLENBQUNJLFNBQUwsQ0FBZUcsR0FBZixDQUE1Qjs7QUFDQSxVQUFJQyxXQUFXLEtBQUtDLFlBQXBCLEVBQWtDO0FBQ2hDSCxRQUFBQSxHQUFHLENBQUNDLEdBQUQsQ0FBSCxHQUFXO0FBQ1RHLFVBQUFBLFFBQVEsRUFBRUQsWUFERDtBQUVURSxVQUFBQSxNQUFNLEVBQUVIO0FBRkMsU0FBWDtBQUlEOztBQUNELGFBQU9GLEdBQVA7QUFDRCxLQVZrQixFQVVoQixFQVZnQixDQUFuQjs7QUFZQSxRQUFJSixNQUFNLENBQUNVLElBQVAsQ0FBWVgsVUFBWixFQUF3QlksTUFBeEIsR0FBaUMsQ0FBckMsRUFBd0M7QUFDdEMsWUFBTSxJQUFJakIsS0FBSixDQUFVLGtEQUFWLEVBQThEUixPQUE5RCxFQUF1RWEsVUFBdkUsQ0FBTjtBQUNEO0FBQ0Y7O0FBdkQ4Qjs7O2VBMERsQmYsbUIiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuQWRhcHRhYmxlQ29udHJvbGxlci5qc1xuXG5BZGFwdGFibGVDb250cm9sbGVyIGlzIHRoZSBiYXNlIGNsYXNzIGZvciBhbGwgY29udHJvbGxlcnNcbnRoYXQgc3VwcG9ydCBhZGFwdGVyLFxuVGhlIHN1cGVyIGNsYXNzIHRha2VzIGNhcmUgb2YgY3JlYXRpbmcgdGhlIHJpZ2h0IGluc3RhbmNlIGZvciB0aGUgYWRhcHRlclxuYmFzZWQgb24gdGhlIHBhcmFtZXRlcnMgcGFzc2VkXG5cbiAqL1xuXG4vLyBfYWRhcHRlciBpcyBwcml2YXRlLCB1c2UgU3ltYm9sXG52YXIgX2FkYXB0ZXIgPSBTeW1ib2woKTtcbmltcG9ydCBDb25maWcgZnJvbSAnLi4vQ29uZmlnJztcblxuZXhwb3J0IGNsYXNzIEFkYXB0YWJsZUNvbnRyb2xsZXIge1xuICBjb25zdHJ1Y3RvcihhZGFwdGVyLCBhcHBJZCwgb3B0aW9ucykge1xuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgdGhpcy5hcHBJZCA9IGFwcElkO1xuICAgIHRoaXMuYWRhcHRlciA9IGFkYXB0ZXI7XG4gIH1cblxuICBzZXQgYWRhcHRlcihhZGFwdGVyKSB7XG4gICAgdGhpcy52YWxpZGF0ZUFkYXB0ZXIoYWRhcHRlcik7XG4gICAgdGhpc1tfYWRhcHRlcl0gPSBhZGFwdGVyO1xuICB9XG5cbiAgZ2V0IGFkYXB0ZXIoKSB7XG4gICAgcmV0dXJuIHRoaXNbX2FkYXB0ZXJdO1xuICB9XG5cbiAgZ2V0IGNvbmZpZygpIHtcbiAgICByZXR1cm4gQ29uZmlnLmdldCh0aGlzLmFwcElkKTtcbiAgfVxuXG4gIGV4cGVjdGVkQWRhcHRlclR5cGUoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTdWJjbGFzc2VzIHNob3VsZCBpbXBsZW1lbnQgZXhwZWN0ZWRBZGFwdGVyVHlwZSgpJyk7XG4gIH1cblxuICB2YWxpZGF0ZUFkYXB0ZXIoYWRhcHRlcikge1xuICAgIEFkYXB0YWJsZUNvbnRyb2xsZXIudmFsaWRhdGVBZGFwdGVyKGFkYXB0ZXIsIHRoaXMpO1xuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlQWRhcHRlcihhZGFwdGVyLCBzZWxmLCBFeHBlY3RlZFR5cGUpIHtcbiAgICBpZiAoIWFkYXB0ZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0aGlzLmNvbnN0cnVjdG9yLm5hbWUgKyAnIHJlcXVpcmVzIGFuIGFkYXB0ZXInKTtcbiAgICB9XG5cbiAgICBjb25zdCBUeXBlID0gRXhwZWN0ZWRUeXBlIHx8IHNlbGYuZXhwZWN0ZWRBZGFwdGVyVHlwZSgpO1xuICAgIC8vIEFsbG93IHNraXBwaW5nIGZvciB0ZXN0aW5nXG4gICAgaWYgKCFUeXBlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gTWFrZXMgc3VyZSB0aGUgcHJvdG90eXBlIG1hdGNoZXNcbiAgICBjb25zdCBtaXNtYXRjaGVzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoVHlwZS5wcm90b3R5cGUpLnJlZHVjZSgob2JqLCBrZXkpID0+IHtcbiAgICAgIGNvbnN0IGFkYXB0ZXJUeXBlID0gdHlwZW9mIGFkYXB0ZXJba2V5XTtcbiAgICAgIGNvbnN0IGV4cGVjdGVkVHlwZSA9IHR5cGVvZiBUeXBlLnByb3RvdHlwZVtrZXldO1xuICAgICAgaWYgKGFkYXB0ZXJUeXBlICE9PSBleHBlY3RlZFR5cGUpIHtcbiAgICAgICAgb2JqW2tleV0gPSB7XG4gICAgICAgICAgZXhwZWN0ZWQ6IGV4cGVjdGVkVHlwZSxcbiAgICAgICAgICBhY3R1YWw6IGFkYXB0ZXJUeXBlLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIG9iajtcbiAgICB9LCB7fSk7XG5cbiAgICBpZiAoT2JqZWN0LmtleXMobWlzbWF0Y2hlcykubGVuZ3RoID4gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQWRhcHRlciBwcm90b3R5cGUgZG9uJ3QgbWF0Y2ggZXhwZWN0ZWQgcHJvdG90eXBlXCIsIGFkYXB0ZXIsIG1pc21hdGNoZXMpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBBZGFwdGFibGVDb250cm9sbGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/AnalyticsController.js b/lib/Controllers/AnalyticsController.js deleted file mode 100644 index 1416558aca..0000000000 --- a/lib/Controllers/AnalyticsController.js +++ /dev/null @@ -1,52 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.AnalyticsController = void 0; - -var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); - -var _AnalyticsAdapter = require("../Adapters/Analytics/AnalyticsAdapter"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class AnalyticsController extends _AdaptableController.default { - appOpened(req) { - return Promise.resolve().then(() => { - return this.adapter.appOpened(req.body, req); - }).then(response => { - return { - response: response || {} - }; - }).catch(() => { - return { - response: {} - }; - }); - } - - trackEvent(req) { - return Promise.resolve().then(() => { - return this.adapter.trackEvent(req.params.eventName, req.body, req); - }).then(response => { - return { - response: response || {} - }; - }).catch(() => { - return { - response: {} - }; - }); - } - - expectedAdapterType() { - return _AnalyticsAdapter.AnalyticsAdapter; - } - -} - -exports.AnalyticsController = AnalyticsController; -var _default = AnalyticsController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9BbmFseXRpY3NDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIkFuYWx5dGljc0NvbnRyb2xsZXIiLCJBZGFwdGFibGVDb250cm9sbGVyIiwiYXBwT3BlbmVkIiwicmVxIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ0aGVuIiwiYWRhcHRlciIsImJvZHkiLCJyZXNwb25zZSIsImNhdGNoIiwidHJhY2tFdmVudCIsInBhcmFtcyIsImV2ZW50TmFtZSIsImV4cGVjdGVkQWRhcHRlclR5cGUiLCJBbmFseXRpY3NBZGFwdGVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7Ozs7QUFFTyxNQUFNQSxtQkFBTixTQUFrQ0MsNEJBQWxDLENBQXNEO0FBQzNEQyxFQUFBQSxTQUFTLENBQUNDLEdBQUQsRUFBTTtBQUNiLFdBQU9DLE9BQU8sQ0FBQ0MsT0FBUixHQUNKQyxJQURJLENBQ0MsTUFBTTtBQUNWLGFBQU8sS0FBS0MsT0FBTCxDQUFhTCxTQUFiLENBQXVCQyxHQUFHLENBQUNLLElBQTNCLEVBQWlDTCxHQUFqQyxDQUFQO0FBQ0QsS0FISSxFQUlKRyxJQUpJLENBSUNHLFFBQVEsSUFBSTtBQUNoQixhQUFPO0FBQUVBLFFBQUFBLFFBQVEsRUFBRUEsUUFBUSxJQUFJO0FBQXhCLE9BQVA7QUFDRCxLQU5JLEVBT0pDLEtBUEksQ0FPRSxNQUFNO0FBQ1gsYUFBTztBQUFFRCxRQUFBQSxRQUFRLEVBQUU7QUFBWixPQUFQO0FBQ0QsS0FUSSxDQUFQO0FBVUQ7O0FBRURFLEVBQUFBLFVBQVUsQ0FBQ1IsR0FBRCxFQUFNO0FBQ2QsV0FBT0MsT0FBTyxDQUFDQyxPQUFSLEdBQ0pDLElBREksQ0FDQyxNQUFNO0FBQ1YsYUFBTyxLQUFLQyxPQUFMLENBQWFJLFVBQWIsQ0FBd0JSLEdBQUcsQ0FBQ1MsTUFBSixDQUFXQyxTQUFuQyxFQUE4Q1YsR0FBRyxDQUFDSyxJQUFsRCxFQUF3REwsR0FBeEQsQ0FBUDtBQUNELEtBSEksRUFJSkcsSUFKSSxDQUlDRyxRQUFRLElBQUk7QUFDaEIsYUFBTztBQUFFQSxRQUFBQSxRQUFRLEVBQUVBLFFBQVEsSUFBSTtBQUF4QixPQUFQO0FBQ0QsS0FOSSxFQU9KQyxLQVBJLENBT0UsTUFBTTtBQUNYLGFBQU87QUFBRUQsUUFBQUEsUUFBUSxFQUFFO0FBQVosT0FBUDtBQUNELEtBVEksQ0FBUDtBQVVEOztBQUVESyxFQUFBQSxtQkFBbUIsR0FBRztBQUNwQixXQUFPQyxrQ0FBUDtBQUNEOztBQTdCMEQ7OztlQWdDOUNmLG1CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFkYXB0YWJsZUNvbnRyb2xsZXIgZnJvbSAnLi9BZGFwdGFibGVDb250cm9sbGVyJztcbmltcG9ydCB7IEFuYWx5dGljc0FkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9BbmFseXRpY3MvQW5hbHl0aWNzQWRhcHRlcic7XG5cbmV4cG9ydCBjbGFzcyBBbmFseXRpY3NDb250cm9sbGVyIGV4dGVuZHMgQWRhcHRhYmxlQ29udHJvbGxlciB7XG4gIGFwcE9wZW5lZChyZXEpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci5hcHBPcGVuZWQocmVxLmJvZHksIHJlcSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICByZXR1cm4geyByZXNwb25zZTogcmVzcG9uc2UgfHwge30gfTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKCkgPT4ge1xuICAgICAgICByZXR1cm4geyByZXNwb25zZToge30gfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgdHJhY2tFdmVudChyZXEpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci50cmFja0V2ZW50KHJlcS5wYXJhbXMuZXZlbnROYW1lLCByZXEuYm9keSwgcmVxKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiByZXNwb25zZSB8fCB7fSB9O1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7fSB9O1xuICAgICAgfSk7XG4gIH1cblxuICBleHBlY3RlZEFkYXB0ZXJUeXBlKCkge1xuICAgIHJldHVybiBBbmFseXRpY3NBZGFwdGVyO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEFuYWx5dGljc0NvbnRyb2xsZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Controllers/CacheController.js b/lib/Controllers/CacheController.js deleted file mode 100644 index 1369350df4..0000000000 --- a/lib/Controllers/CacheController.js +++ /dev/null @@ -1,92 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.CacheController = exports.SubCache = void 0; - -var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); - -var _CacheAdapter = _interopRequireDefault(require("../Adapters/Cache/CacheAdapter")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const KEY_SEPARATOR_CHAR = ':'; - -function joinKeys(...keys) { - return keys.join(KEY_SEPARATOR_CHAR); -} -/** - * Prefix all calls to the cache via a prefix string, useful when grouping Cache by object type. - * - * eg "Role" or "Session" - */ - - -class SubCache { - constructor(prefix, cacheController, ttl) { - this.prefix = prefix; - this.cache = cacheController; - this.ttl = ttl; - } - - get(key) { - const cacheKey = joinKeys(this.prefix, key); - return this.cache.get(cacheKey); - } - - put(key, value, ttl) { - const cacheKey = joinKeys(this.prefix, key); - return this.cache.put(cacheKey, value, ttl); - } - - del(key) { - const cacheKey = joinKeys(this.prefix, key); - return this.cache.del(cacheKey); - } - - clear() { - return this.cache.clear(); - } - -} - -exports.SubCache = SubCache; - -class CacheController extends _AdaptableController.default { - constructor(adapter, appId, options = {}) { - super(adapter, appId, options); - this.role = new SubCache('role', this); - this.user = new SubCache('user', this); - this.graphQL = new SubCache('graphQL', this); - } - - get(key) { - const cacheKey = joinKeys(this.appId, key); - return this.adapter.get(cacheKey).then(null, () => Promise.resolve(null)); - } - - put(key, value, ttl) { - const cacheKey = joinKeys(this.appId, key); - return this.adapter.put(cacheKey, value, ttl); - } - - del(key) { - const cacheKey = joinKeys(this.appId, key); - return this.adapter.del(cacheKey); - } - - clear() { - return this.adapter.clear(); - } - - expectedAdapterType() { - return _CacheAdapter.default; - } - -} - -exports.CacheController = CacheController; -var _default = CacheController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9DYWNoZUNvbnRyb2xsZXIuanMiXSwibmFtZXMiOlsiS0VZX1NFUEFSQVRPUl9DSEFSIiwiam9pbktleXMiLCJrZXlzIiwiam9pbiIsIlN1YkNhY2hlIiwiY29uc3RydWN0b3IiLCJwcmVmaXgiLCJjYWNoZUNvbnRyb2xsZXIiLCJ0dGwiLCJjYWNoZSIsImdldCIsImtleSIsImNhY2hlS2V5IiwicHV0IiwidmFsdWUiLCJkZWwiLCJjbGVhciIsIkNhY2hlQ29udHJvbGxlciIsIkFkYXB0YWJsZUNvbnRyb2xsZXIiLCJhZGFwdGVyIiwiYXBwSWQiLCJvcHRpb25zIiwicm9sZSIsInVzZXIiLCJncmFwaFFMIiwidGhlbiIsIlByb21pc2UiLCJyZXNvbHZlIiwiZXhwZWN0ZWRBZGFwdGVyVHlwZSIsIkNhY2hlQWRhcHRlciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7O0FBRUEsTUFBTUEsa0JBQWtCLEdBQUcsR0FBM0I7O0FBRUEsU0FBU0MsUUFBVCxDQUFrQixHQUFHQyxJQUFyQixFQUEyQjtBQUN6QixTQUFPQSxJQUFJLENBQUNDLElBQUwsQ0FBVUgsa0JBQVYsQ0FBUDtBQUNEO0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ08sTUFBTUksUUFBTixDQUFlO0FBQ3BCQyxFQUFBQSxXQUFXLENBQUNDLE1BQUQsRUFBU0MsZUFBVCxFQUEwQkMsR0FBMUIsRUFBK0I7QUFDeEMsU0FBS0YsTUFBTCxHQUFjQSxNQUFkO0FBQ0EsU0FBS0csS0FBTCxHQUFhRixlQUFiO0FBQ0EsU0FBS0MsR0FBTCxHQUFXQSxHQUFYO0FBQ0Q7O0FBRURFLEVBQUFBLEdBQUcsQ0FBQ0MsR0FBRCxFQUFNO0FBQ1AsVUFBTUMsUUFBUSxHQUFHWCxRQUFRLENBQUMsS0FBS0ssTUFBTixFQUFjSyxHQUFkLENBQXpCO0FBQ0EsV0FBTyxLQUFLRixLQUFMLENBQVdDLEdBQVgsQ0FBZUUsUUFBZixDQUFQO0FBQ0Q7O0FBRURDLEVBQUFBLEdBQUcsQ0FBQ0YsR0FBRCxFQUFNRyxLQUFOLEVBQWFOLEdBQWIsRUFBa0I7QUFDbkIsVUFBTUksUUFBUSxHQUFHWCxRQUFRLENBQUMsS0FBS0ssTUFBTixFQUFjSyxHQUFkLENBQXpCO0FBQ0EsV0FBTyxLQUFLRixLQUFMLENBQVdJLEdBQVgsQ0FBZUQsUUFBZixFQUF5QkUsS0FBekIsRUFBZ0NOLEdBQWhDLENBQVA7QUFDRDs7QUFFRE8sRUFBQUEsR0FBRyxDQUFDSixHQUFELEVBQU07QUFDUCxVQUFNQyxRQUFRLEdBQUdYLFFBQVEsQ0FBQyxLQUFLSyxNQUFOLEVBQWNLLEdBQWQsQ0FBekI7QUFDQSxXQUFPLEtBQUtGLEtBQUwsQ0FBV00sR0FBWCxDQUFlSCxRQUFmLENBQVA7QUFDRDs7QUFFREksRUFBQUEsS0FBSyxHQUFHO0FBQ04sV0FBTyxLQUFLUCxLQUFMLENBQVdPLEtBQVgsRUFBUDtBQUNEOztBQXhCbUI7Ozs7QUEyQmYsTUFBTUMsZUFBTixTQUE4QkMsNEJBQTlCLENBQWtEO0FBQ3ZEYixFQUFBQSxXQUFXLENBQUNjLE9BQUQsRUFBVUMsS0FBVixFQUFpQkMsT0FBTyxHQUFHLEVBQTNCLEVBQStCO0FBQ3hDLFVBQU1GLE9BQU4sRUFBZUMsS0FBZixFQUFzQkMsT0FBdEI7QUFFQSxTQUFLQyxJQUFMLEdBQVksSUFBSWxCLFFBQUosQ0FBYSxNQUFiLEVBQXFCLElBQXJCLENBQVo7QUFDQSxTQUFLbUIsSUFBTCxHQUFZLElBQUluQixRQUFKLENBQWEsTUFBYixFQUFxQixJQUFyQixDQUFaO0FBQ0EsU0FBS29CLE9BQUwsR0FBZSxJQUFJcEIsUUFBSixDQUFhLFNBQWIsRUFBd0IsSUFBeEIsQ0FBZjtBQUNEOztBQUVETSxFQUFBQSxHQUFHLENBQUNDLEdBQUQsRUFBTTtBQUNQLFVBQU1DLFFBQVEsR0FBR1gsUUFBUSxDQUFDLEtBQUttQixLQUFOLEVBQWFULEdBQWIsQ0FBekI7QUFDQSxXQUFPLEtBQUtRLE9BQUwsQ0FBYVQsR0FBYixDQUFpQkUsUUFBakIsRUFBMkJhLElBQTNCLENBQWdDLElBQWhDLEVBQXNDLE1BQU1DLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQixJQUFoQixDQUE1QyxDQUFQO0FBQ0Q7O0FBRURkLEVBQUFBLEdBQUcsQ0FBQ0YsR0FBRCxFQUFNRyxLQUFOLEVBQWFOLEdBQWIsRUFBa0I7QUFDbkIsVUFBTUksUUFBUSxHQUFHWCxRQUFRLENBQUMsS0FBS21CLEtBQU4sRUFBYVQsR0FBYixDQUF6QjtBQUNBLFdBQU8sS0FBS1EsT0FBTCxDQUFhTixHQUFiLENBQWlCRCxRQUFqQixFQUEyQkUsS0FBM0IsRUFBa0NOLEdBQWxDLENBQVA7QUFDRDs7QUFFRE8sRUFBQUEsR0FBRyxDQUFDSixHQUFELEVBQU07QUFDUCxVQUFNQyxRQUFRLEdBQUdYLFFBQVEsQ0FBQyxLQUFLbUIsS0FBTixFQUFhVCxHQUFiLENBQXpCO0FBQ0EsV0FBTyxLQUFLUSxPQUFMLENBQWFKLEdBQWIsQ0FBaUJILFFBQWpCLENBQVA7QUFDRDs7QUFFREksRUFBQUEsS0FBSyxHQUFHO0FBQ04sV0FBTyxLQUFLRyxPQUFMLENBQWFILEtBQWIsRUFBUDtBQUNEOztBQUVEWSxFQUFBQSxtQkFBbUIsR0FBRztBQUNwQixXQUFPQyxxQkFBUDtBQUNEOztBQTlCc0Q7OztlQWlDMUNaLGUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQWRhcHRhYmxlQ29udHJvbGxlciBmcm9tICcuL0FkYXB0YWJsZUNvbnRyb2xsZXInO1xuaW1wb3J0IENhY2hlQWRhcHRlciBmcm9tICcuLi9BZGFwdGVycy9DYWNoZS9DYWNoZUFkYXB0ZXInO1xuXG5jb25zdCBLRVlfU0VQQVJBVE9SX0NIQVIgPSAnOic7XG5cbmZ1bmN0aW9uIGpvaW5LZXlzKC4uLmtleXMpIHtcbiAgcmV0dXJuIGtleXMuam9pbihLRVlfU0VQQVJBVE9SX0NIQVIpO1xufVxuXG4vKipcbiAqIFByZWZpeCBhbGwgY2FsbHMgdG8gdGhlIGNhY2hlIHZpYSBhIHByZWZpeCBzdHJpbmcsIHVzZWZ1bCB3aGVuIGdyb3VwaW5nIENhY2hlIGJ5IG9iamVjdCB0eXBlLlxuICpcbiAqIGVnIFwiUm9sZVwiIG9yIFwiU2Vzc2lvblwiXG4gKi9cbmV4cG9ydCBjbGFzcyBTdWJDYWNoZSB7XG4gIGNvbnN0cnVjdG9yKHByZWZpeCwgY2FjaGVDb250cm9sbGVyLCB0dGwpIHtcbiAgICB0aGlzLnByZWZpeCA9IHByZWZpeDtcbiAgICB0aGlzLmNhY2hlID0gY2FjaGVDb250cm9sbGVyO1xuICAgIHRoaXMudHRsID0gdHRsO1xuICB9XG5cbiAgZ2V0KGtleSkge1xuICAgIGNvbnN0IGNhY2hlS2V5ID0gam9pbktleXModGhpcy5wcmVmaXgsIGtleSk7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0KGNhY2hlS2V5KTtcbiAgfVxuXG4gIHB1dChrZXksIHZhbHVlLCB0dGwpIHtcbiAgICBjb25zdCBjYWNoZUtleSA9IGpvaW5LZXlzKHRoaXMucHJlZml4LCBrZXkpO1xuICAgIHJldHVybiB0aGlzLmNhY2hlLnB1dChjYWNoZUtleSwgdmFsdWUsIHR0bCk7XG4gIH1cblxuICBkZWwoa2V5KSB7XG4gICAgY29uc3QgY2FjaGVLZXkgPSBqb2luS2V5cyh0aGlzLnByZWZpeCwga2V5KTtcbiAgICByZXR1cm4gdGhpcy5jYWNoZS5kZWwoY2FjaGVLZXkpO1xuICB9XG5cbiAgY2xlYXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGUuY2xlYXIoKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgQ2FjaGVDb250cm9sbGVyIGV4dGVuZHMgQWRhcHRhYmxlQ29udHJvbGxlciB7XG4gIGNvbnN0cnVjdG9yKGFkYXB0ZXIsIGFwcElkLCBvcHRpb25zID0ge30pIHtcbiAgICBzdXBlcihhZGFwdGVyLCBhcHBJZCwgb3B0aW9ucyk7XG5cbiAgICB0aGlzLnJvbGUgPSBuZXcgU3ViQ2FjaGUoJ3JvbGUnLCB0aGlzKTtcbiAgICB0aGlzLnVzZXIgPSBuZXcgU3ViQ2FjaGUoJ3VzZXInLCB0aGlzKTtcbiAgICB0aGlzLmdyYXBoUUwgPSBuZXcgU3ViQ2FjaGUoJ2dyYXBoUUwnLCB0aGlzKTtcbiAgfVxuXG4gIGdldChrZXkpIHtcbiAgICBjb25zdCBjYWNoZUtleSA9IGpvaW5LZXlzKHRoaXMuYXBwSWQsIGtleSk7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5nZXQoY2FjaGVLZXkpLnRoZW4obnVsbCwgKCkgPT4gUHJvbWlzZS5yZXNvbHZlKG51bGwpKTtcbiAgfVxuXG4gIHB1dChrZXksIHZhbHVlLCB0dGwpIHtcbiAgICBjb25zdCBjYWNoZUtleSA9IGpvaW5LZXlzKHRoaXMuYXBwSWQsIGtleSk7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5wdXQoY2FjaGVLZXksIHZhbHVlLCB0dGwpO1xuICB9XG5cbiAgZGVsKGtleSkge1xuICAgIGNvbnN0IGNhY2hlS2V5ID0gam9pbktleXModGhpcy5hcHBJZCwga2V5KTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmRlbChjYWNoZUtleSk7XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmNsZWFyKCk7XG4gIH1cblxuICBleHBlY3RlZEFkYXB0ZXJUeXBlKCkge1xuICAgIHJldHVybiBDYWNoZUFkYXB0ZXI7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ2FjaGVDb250cm9sbGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/DatabaseController.js b/lib/Controllers/DatabaseController.js deleted file mode 100644 index 9d1f68d6b1..0000000000 --- a/lib/Controllers/DatabaseController.js +++ /dev/null @@ -1,1568 +0,0 @@ -"use strict"; - -var _node = require("parse/node"); - -var _lodash = _interopRequireDefault(require("lodash")); - -var _intersect = _interopRequireDefault(require("intersect")); - -var _deepcopy = _interopRequireDefault(require("deepcopy")); - -var _logger = _interopRequireDefault(require("../logger")); - -var SchemaController = _interopRequireWildcard(require("./SchemaController")); - -var _StorageAdapter = require("../Adapters/Storage/StorageAdapter"); - -var _MongoStorageAdapter = _interopRequireDefault(require("../Adapters/Storage/Mongo/MongoStorageAdapter")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } - -function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } - -function addWriteACL(query, acl) { - const newQuery = _lodash.default.cloneDeep(query); //Can't be any existing '_wperm' query, we don't allow client queries on that, no need to $and - - - newQuery._wperm = { - $in: [null, ...acl] - }; - return newQuery; -} - -function addReadACL(query, acl) { - const newQuery = _lodash.default.cloneDeep(query); //Can't be any existing '_rperm' query, we don't allow client queries on that, no need to $and - - - newQuery._rperm = { - $in: [null, '*', ...acl] - }; - return newQuery; -} // Transforms a REST API formatted ACL object to our two-field mongo format. - - -const transformObjectACL = (_ref) => { - let { - ACL - } = _ref, - result = _objectWithoutProperties(_ref, ["ACL"]); - - if (!ACL) { - return result; - } - - result._wperm = []; - result._rperm = []; - - for (const entry in ACL) { - if (ACL[entry].read) { - result._rperm.push(entry); - } - - if (ACL[entry].write) { - result._wperm.push(entry); - } - } - - return result; -}; - -const specialQuerykeys = ['$and', '$or', '$nor', '_rperm', '_wperm', '_perishable_token', '_email_verify_token', '_email_verify_token_expires_at', '_account_lockout_expires_at', '_failed_login_count']; - -const isSpecialQueryKey = key => { - return specialQuerykeys.indexOf(key) >= 0; -}; - -const validateQuery = query => { - if (query.ACL) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, 'Cannot query on ACL.'); - } - - if (query.$or) { - if (query.$or instanceof Array) { - query.$or.forEach(validateQuery); - } else { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, 'Bad $or format - use an array value.'); - } - } - - if (query.$and) { - if (query.$and instanceof Array) { - query.$and.forEach(validateQuery); - } else { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, 'Bad $and format - use an array value.'); - } - } - - if (query.$nor) { - if (query.$nor instanceof Array && query.$nor.length > 0) { - query.$nor.forEach(validateQuery); - } else { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, 'Bad $nor format - use an array of at least 1 value.'); - } - } - - Object.keys(query).forEach(key => { - if (query && query[key] && query[key].$regex) { - if (typeof query[key].$options === 'string') { - if (!query[key].$options.match(/^[imxs]+$/)) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_QUERY, `Bad $options value for query: ${query[key].$options}`); - } - } - } - - if (!isSpecialQueryKey(key) && !key.match(/^[a-zA-Z][a-zA-Z0-9_\.]*$/)) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Invalid key name: ${key}`); - } - }); -}; // Filters out any data that shouldn't be on this REST-formatted object. - - -const filterSensitiveData = (isMaster, aclGroup, auth, operation, schema, className, protectedFields, object) => { - let userId = null; - if (auth && auth.user) userId = auth.user.id; // replace protectedFields when using pointer-permissions - - const perms = schema.getClassLevelPermissions(className); - - if (perms) { - const isReadOperation = ['get', 'find'].indexOf(operation) > -1; - - if (isReadOperation && perms.protectedFields) { - // extract protectedFields added with the pointer-permission prefix - const protectedFieldsPointerPerm = Object.keys(perms.protectedFields).filter(key => key.startsWith('userField:')).map(key => { - return { - key: key.substring(10), - value: perms.protectedFields[key] - }; - }); - const newProtectedFields = []; - let overrideProtectedFields = false; // check if the object grants the current user access based on the extracted fields - - protectedFieldsPointerPerm.forEach(pointerPerm => { - let pointerPermIncludesUser = false; - const readUserFieldValue = object[pointerPerm.key]; - - if (readUserFieldValue) { - if (Array.isArray(readUserFieldValue)) { - pointerPermIncludesUser = readUserFieldValue.some(user => user.objectId && user.objectId === userId); - } else { - pointerPermIncludesUser = readUserFieldValue.objectId && readUserFieldValue.objectId === userId; - } - } - - if (pointerPermIncludesUser) { - overrideProtectedFields = true; - newProtectedFields.push(pointerPerm.value); - } - }); // if at least one pointer-permission affected the current user - // intersect vs protectedFields from previous stage (@see addProtectedFields) - // Sets theory (intersections): A x (B x C) == (A x B) x C - - if (overrideProtectedFields && protectedFields) { - newProtectedFields.push(protectedFields); - } // intersect all sets of protectedFields - - - newProtectedFields.forEach(fields => { - if (fields) { - // if there're no protctedFields by other criteria ( id / role / auth) - // then we must intersect each set (per userField) - if (!protectedFields) { - protectedFields = fields; - } else { - protectedFields = protectedFields.filter(v => fields.includes(v)); - } - } - }); - } - } - - const isUserClass = className === '_User'; - /* special treat for the user class: don't filter protectedFields if currently loggedin user is - the retrieved user */ - - if (!(isUserClass && userId && object.objectId === userId)) { - protectedFields && protectedFields.forEach(k => delete object[k]); // fields not requested by client (excluded), - //but were needed to apply protecttedFields - - perms.protectedFields && perms.protectedFields.temporaryKeys && perms.protectedFields.temporaryKeys.forEach(k => delete object[k]); - } - - if (!isUserClass) { - return object; - } - - object.password = object._hashed_password; - delete object._hashed_password; - delete object.sessionToken; - - if (isMaster) { - return object; - } - - delete object._email_verify_token; - delete object._perishable_token; - delete object._perishable_token_expires_at; - delete object._tombstone; - delete object._email_verify_token_expires_at; - delete object._failed_login_count; - delete object._account_lockout_expires_at; - delete object._password_changed_at; - delete object._password_history; - - if (aclGroup.indexOf(object.objectId) > -1) { - return object; - } - - delete object.authData; - return object; -}; - -// Runs an update on the database. -// Returns a promise for an object with the new values for field -// modifications that don't know their results ahead of time, like -// 'increment'. -// Options: -// acl: a list of strings. If the object to be updated has an ACL, -// one of the provided strings must provide the caller with -// write permissions. -const specialKeysForUpdate = ['_hashed_password', '_perishable_token', '_email_verify_token', '_email_verify_token_expires_at', '_account_lockout_expires_at', '_failed_login_count', '_perishable_token_expires_at', '_password_changed_at', '_password_history']; - -const isSpecialUpdateKey = key => { - return specialKeysForUpdate.indexOf(key) >= 0; -}; - -function expandResultOnKeyPath(object, key, value) { - if (key.indexOf('.') < 0) { - object[key] = value[key]; - return object; - } - - const path = key.split('.'); - const firstKey = path[0]; - const nextPath = path.slice(1).join('.'); - object[firstKey] = expandResultOnKeyPath(object[firstKey] || {}, nextPath, value[firstKey]); - delete object[key]; - return object; -} - -function sanitizeDatabaseResult(originalObject, result) { - const response = {}; - - if (!result) { - return Promise.resolve(response); - } - - Object.keys(originalObject).forEach(key => { - const keyUpdate = originalObject[key]; // determine if that was an op - - if (keyUpdate && typeof keyUpdate === 'object' && keyUpdate.__op && ['Add', 'AddUnique', 'Remove', 'Increment'].indexOf(keyUpdate.__op) > -1) { - // only valid ops that produce an actionable result - // the op may have happend on a keypath - expandResultOnKeyPath(response, key, result); - } - }); - return Promise.resolve(response); -} - -function joinTableName(className, key) { - return `_Join:${key}:${className}`; -} - -const flattenUpdateOperatorsForCreate = object => { - for (const key in object) { - if (object[key] && object[key].__op) { - switch (object[key].__op) { - case 'Increment': - if (typeof object[key].amount !== 'number') { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_JSON, 'objects to add must be an array'); - } - - object[key] = object[key].amount; - break; - - case 'Add': - if (!(object[key].objects instanceof Array)) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_JSON, 'objects to add must be an array'); - } - - object[key] = object[key].objects; - break; - - case 'AddUnique': - if (!(object[key].objects instanceof Array)) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_JSON, 'objects to add must be an array'); - } - - object[key] = object[key].objects; - break; - - case 'Remove': - if (!(object[key].objects instanceof Array)) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_JSON, 'objects to add must be an array'); - } - - object[key] = []; - break; - - case 'Delete': - delete object[key]; - break; - - default: - throw new _node.Parse.Error(_node.Parse.Error.COMMAND_UNAVAILABLE, `The ${object[key].__op} operator is not supported yet.`); - } - } - } -}; - -const transformAuthData = (className, object, schema) => { - if (object.authData && className === '_User') { - Object.keys(object.authData).forEach(provider => { - const providerData = object.authData[provider]; - const fieldName = `_auth_data_${provider}`; - - if (providerData == null) { - object[fieldName] = { - __op: 'Delete' - }; - } else { - object[fieldName] = providerData; - schema.fields[fieldName] = { - type: 'Object' - }; - } - }); - delete object.authData; - } -}; // Transforms a Database format ACL to a REST API format ACL - - -const untransformObjectACL = (_ref2) => { - let { - _rperm, - _wperm - } = _ref2, - output = _objectWithoutProperties(_ref2, ["_rperm", "_wperm"]); - - if (_rperm || _wperm) { - output.ACL = {}; - - (_rperm || []).forEach(entry => { - if (!output.ACL[entry]) { - output.ACL[entry] = { - read: true - }; - } else { - output.ACL[entry]['read'] = true; - } - }); - - (_wperm || []).forEach(entry => { - if (!output.ACL[entry]) { - output.ACL[entry] = { - write: true - }; - } else { - output.ACL[entry]['write'] = true; - } - }); - } - - return output; -}; -/** - * When querying, the fieldName may be compound, extract the root fieldName - * `temperature.celsius` becomes `temperature` - * @param {string} fieldName that may be a compound field name - * @returns {string} the root name of the field - */ - - -const getRootFieldName = fieldName => { - return fieldName.split('.')[0]; -}; - -const relationSchema = { - fields: { - relatedId: { - type: 'String' - }, - owningId: { - type: 'String' - } - } -}; - -class DatabaseController { - constructor(adapter, schemaCache) { - this.adapter = adapter; - this.schemaCache = schemaCache; // We don't want a mutable this.schema, because then you could have - // one request that uses different schemas for different parts of - // it. Instead, use loadSchema to get a schema. - - this.schemaPromise = null; - this._transactionalSession = null; - } - - collectionExists(className) { - return this.adapter.classExists(className); - } - - purgeCollection(className) { - return this.loadSchema().then(schemaController => schemaController.getOneSchema(className)).then(schema => this.adapter.deleteObjectsByQuery(className, schema, {})); - } - - validateClassName(className) { - if (!SchemaController.classNameIsValid(className)) { - return Promise.reject(new _node.Parse.Error(_node.Parse.Error.INVALID_CLASS_NAME, 'invalid className: ' + className)); - } - - return Promise.resolve(); - } // Returns a promise for a schemaController. - - - loadSchema(options = { - clearCache: false - }) { - if (this.schemaPromise != null) { - return this.schemaPromise; - } - - this.schemaPromise = SchemaController.load(this.adapter, this.schemaCache, options); - this.schemaPromise.then(() => delete this.schemaPromise, () => delete this.schemaPromise); - return this.loadSchema(options); - } - - loadSchemaIfNeeded(schemaController, options = { - clearCache: false - }) { - return schemaController ? Promise.resolve(schemaController) : this.loadSchema(options); - } // Returns a promise for the classname that is related to the given - // classname through the key. - // TODO: make this not in the DatabaseController interface - - - redirectClassNameForKey(className, key) { - return this.loadSchema().then(schema => { - var t = schema.getExpectedType(className, key); - - if (t != null && typeof t !== 'string' && t.type === 'Relation') { - return t.targetClass; - } - - return className; - }); - } // Uses the schema to validate the object (REST API format). - // Returns a promise that resolves to the new schema. - // This does not update this.schema, because in a situation like a - // batch request, that could confuse other users of the schema. - - - validateObject(className, object, query, runOptions) { - let schema; - const acl = runOptions.acl; - const isMaster = acl === undefined; - var aclGroup = acl || []; - return this.loadSchema().then(s => { - schema = s; - - if (isMaster) { - return Promise.resolve(); - } - - return this.canAddField(schema, className, object, aclGroup, runOptions); - }).then(() => { - return schema.validateObject(className, object, query); - }); - } - - update(className, query, update, { - acl, - many, - upsert, - addsField - } = {}, skipSanitization = false, validateOnly = false, validSchemaController) { - const originalQuery = query; - const originalUpdate = update; // Make a copy of the object, so we don't mutate the incoming data. - - update = (0, _deepcopy.default)(update); - var relationUpdates = []; - var isMaster = acl === undefined; - var aclGroup = acl || []; - return this.loadSchemaIfNeeded(validSchemaController).then(schemaController => { - return (isMaster ? Promise.resolve() : schemaController.validatePermission(className, aclGroup, 'update')).then(() => { - relationUpdates = this.collectRelationUpdates(className, originalQuery.objectId, update); - - if (!isMaster) { - query = this.addPointerPermissions(schemaController, className, 'update', query, aclGroup); - - if (addsField) { - query = { - $and: [query, this.addPointerPermissions(schemaController, className, 'addField', query, aclGroup)] - }; - } - } - - if (!query) { - return Promise.resolve(); - } - - if (acl) { - query = addWriteACL(query, acl); - } - - validateQuery(query); - return schemaController.getOneSchema(className, true).catch(error => { - // If the schema doesn't exist, pretend it exists with no fields. This behavior - // will likely need revisiting. - if (error === undefined) { - return { - fields: {} - }; - } - - throw error; - }).then(schema => { - Object.keys(update).forEach(fieldName => { - if (fieldName.match(/^authData\.([a-zA-Z0-9_]+)\.id$/)) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Invalid field name for update: ${fieldName}`); - } - - const rootFieldName = getRootFieldName(fieldName); - - if (!SchemaController.fieldNameIsValid(rootFieldName, className) && !isSpecialUpdateKey(rootFieldName)) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Invalid field name for update: ${fieldName}`); - } - }); - - for (const updateOperation in update) { - if (update[updateOperation] && typeof update[updateOperation] === 'object' && Object.keys(update[updateOperation]).some(innerKey => innerKey.includes('$') || innerKey.includes('.'))) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_NESTED_KEY, "Nested keys should not contain the '$' or '.' characters"); - } - } - - update = transformObjectACL(update); - transformAuthData(className, update, schema); - - if (validateOnly) { - return this.adapter.find(className, schema, query, {}).then(result => { - if (!result || !result.length) { - throw new _node.Parse.Error(_node.Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } - - return {}; - }); - } - - if (many) { - return this.adapter.updateObjectsByQuery(className, schema, query, update, this._transactionalSession); - } else if (upsert) { - return this.adapter.upsertOneObject(className, schema, query, update, this._transactionalSession); - } else { - return this.adapter.findOneAndUpdate(className, schema, query, update, this._transactionalSession); - } - }); - }).then(result => { - if (!result) { - throw new _node.Parse.Error(_node.Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } - - if (validateOnly) { - return result; - } - - return this.handleRelationUpdates(className, originalQuery.objectId, update, relationUpdates).then(() => { - return result; - }); - }).then(result => { - if (skipSanitization) { - return Promise.resolve(result); - } - - return sanitizeDatabaseResult(originalUpdate, result); - }); - }); - } // Collect all relation-updating operations from a REST-format update. - // Returns a list of all relation updates to perform - // This mutates update. - - - collectRelationUpdates(className, objectId, update) { - var ops = []; - var deleteMe = []; - objectId = update.objectId || objectId; - - var process = (op, key) => { - if (!op) { - return; - } - - if (op.__op == 'AddRelation') { - ops.push({ - key, - op - }); - deleteMe.push(key); - } - - if (op.__op == 'RemoveRelation') { - ops.push({ - key, - op - }); - deleteMe.push(key); - } - - if (op.__op == 'Batch') { - for (var x of op.ops) { - process(x, key); - } - } - }; - - for (const key in update) { - process(update[key], key); - } - - for (const key of deleteMe) { - delete update[key]; - } - - return ops; - } // Processes relation-updating operations from a REST-format update. - // Returns a promise that resolves when all updates have been performed - - - handleRelationUpdates(className, objectId, update, ops) { - var pending = []; - objectId = update.objectId || objectId; - ops.forEach(({ - key, - op - }) => { - if (!op) { - return; - } - - if (op.__op == 'AddRelation') { - for (const object of op.objects) { - pending.push(this.addRelation(key, className, objectId, object.objectId)); - } - } - - if (op.__op == 'RemoveRelation') { - for (const object of op.objects) { - pending.push(this.removeRelation(key, className, objectId, object.objectId)); - } - } - }); - return Promise.all(pending); - } // Adds a relation. - // Returns a promise that resolves successfully iff the add was successful. - - - addRelation(key, fromClassName, fromId, toId) { - const doc = { - relatedId: toId, - owningId: fromId - }; - return this.adapter.upsertOneObject(`_Join:${key}:${fromClassName}`, relationSchema, doc, doc, this._transactionalSession); - } // Removes a relation. - // Returns a promise that resolves successfully iff the remove was - // successful. - - - removeRelation(key, fromClassName, fromId, toId) { - var doc = { - relatedId: toId, - owningId: fromId - }; - return this.adapter.deleteObjectsByQuery(`_Join:${key}:${fromClassName}`, relationSchema, doc, this._transactionalSession).catch(error => { - // We don't care if they try to delete a non-existent relation. - if (error.code == _node.Parse.Error.OBJECT_NOT_FOUND) { - return; - } - - throw error; - }); - } // Removes objects matches this query from the database. - // Returns a promise that resolves successfully iff the object was - // deleted. - // Options: - // acl: a list of strings. If the object to be updated has an ACL, - // one of the provided strings must provide the caller with - // write permissions. - - - destroy(className, query, { - acl - } = {}, validSchemaController) { - const isMaster = acl === undefined; - const aclGroup = acl || []; - return this.loadSchemaIfNeeded(validSchemaController).then(schemaController => { - return (isMaster ? Promise.resolve() : schemaController.validatePermission(className, aclGroup, 'delete')).then(() => { - if (!isMaster) { - query = this.addPointerPermissions(schemaController, className, 'delete', query, aclGroup); - - if (!query) { - throw new _node.Parse.Error(_node.Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } - } // delete by query - - - if (acl) { - query = addWriteACL(query, acl); - } - - validateQuery(query); - return schemaController.getOneSchema(className).catch(error => { - // If the schema doesn't exist, pretend it exists with no fields. This behavior - // will likely need revisiting. - if (error === undefined) { - return { - fields: {} - }; - } - - throw error; - }).then(parseFormatSchema => this.adapter.deleteObjectsByQuery(className, parseFormatSchema, query, this._transactionalSession)).catch(error => { - // When deleting sessions while changing passwords, don't throw an error if they don't have any sessions. - if (className === '_Session' && error.code === _node.Parse.Error.OBJECT_NOT_FOUND) { - return Promise.resolve({}); - } - - throw error; - }); - }); - }); - } // Inserts an object into the database. - // Returns a promise that resolves successfully iff the object saved. - - - create(className, object, { - acl - } = {}, validateOnly = false, validSchemaController) { - // Make a copy of the object, so we don't mutate the incoming data. - const originalObject = object; - object = transformObjectACL(object); - object.createdAt = { - iso: object.createdAt, - __type: 'Date' - }; - object.updatedAt = { - iso: object.updatedAt, - __type: 'Date' - }; - var isMaster = acl === undefined; - var aclGroup = acl || []; - const relationUpdates = this.collectRelationUpdates(className, null, object); - return this.validateClassName(className).then(() => this.loadSchemaIfNeeded(validSchemaController)).then(schemaController => { - return (isMaster ? Promise.resolve() : schemaController.validatePermission(className, aclGroup, 'create')).then(() => schemaController.enforceClassExists(className)).then(() => schemaController.getOneSchema(className, true)).then(schema => { - transformAuthData(className, object, schema); - flattenUpdateOperatorsForCreate(object); - - if (validateOnly) { - return {}; - } - - return this.adapter.createObject(className, SchemaController.convertSchemaToAdapterSchema(schema), object, this._transactionalSession); - }).then(result => { - if (validateOnly) { - return originalObject; - } - - return this.handleRelationUpdates(className, object.objectId, object, relationUpdates).then(() => { - return sanitizeDatabaseResult(originalObject, result.ops[0]); - }); - }); - }); - } - - canAddField(schema, className, object, aclGroup, runOptions) { - const classSchema = schema.schemaData[className]; - - if (!classSchema) { - return Promise.resolve(); - } - - const fields = Object.keys(object); - const schemaFields = Object.keys(classSchema.fields); - const newKeys = fields.filter(field => { - // Skip fields that are unset - if (object[field] && object[field].__op && object[field].__op === 'Delete') { - return false; - } - - return schemaFields.indexOf(field) < 0; - }); - - if (newKeys.length > 0) { - // adds a marker that new field is being adding during update - runOptions.addsField = true; - const action = runOptions.action; - return schema.validatePermission(className, aclGroup, 'addField', action); - } - - return Promise.resolve(); - } // Won't delete collections in the system namespace - - /** - * Delete all classes and clears the schema cache - * - * @param {boolean} fast set to true if it's ok to just delete rows and not indexes - * @returns {Promise} when the deletions completes - */ - - - deleteEverything(fast = false) { - this.schemaPromise = null; - return Promise.all([this.adapter.deleteAllClasses(fast), this.schemaCache.clear()]); - } // Returns a promise for a list of related ids given an owning id. - // className here is the owning className. - - - relatedIds(className, key, owningId, queryOptions) { - const { - skip, - limit, - sort - } = queryOptions; - const findOptions = {}; - - if (sort && sort.createdAt && this.adapter.canSortOnJoinTables) { - findOptions.sort = { - _id: sort.createdAt - }; - findOptions.limit = limit; - findOptions.skip = skip; - queryOptions.skip = 0; - } - - return this.adapter.find(joinTableName(className, key), relationSchema, { - owningId - }, findOptions).then(results => results.map(result => result.relatedId)); - } // Returns a promise for a list of owning ids given some related ids. - // className here is the owning className. - - - owningIds(className, key, relatedIds) { - return this.adapter.find(joinTableName(className, key), relationSchema, { - relatedId: { - $in: relatedIds - } - }, { - keys: ['owningId'] - }).then(results => results.map(result => result.owningId)); - } // Modifies query so that it no longer has $in on relation fields, or - // equal-to-pointer constraints on relation fields. - // Returns a promise that resolves when query is mutated - - - reduceInRelation(className, query, schema) { - // Search for an in-relation or equal-to-relation - // Make it sequential for now, not sure of paralleization side effects - if (query['$or']) { - const ors = query['$or']; - return Promise.all(ors.map((aQuery, index) => { - return this.reduceInRelation(className, aQuery, schema).then(aQuery => { - query['$or'][index] = aQuery; - }); - })).then(() => { - return Promise.resolve(query); - }); - } - - const promises = Object.keys(query).map(key => { - const t = schema.getExpectedType(className, key); - - if (!t || t.type !== 'Relation') { - return Promise.resolve(query); - } - - let queries = null; - - if (query[key] && (query[key]['$in'] || query[key]['$ne'] || query[key]['$nin'] || query[key].__type == 'Pointer')) { - // Build the list of queries - queries = Object.keys(query[key]).map(constraintKey => { - let relatedIds; - let isNegation = false; - - if (constraintKey === 'objectId') { - relatedIds = [query[key].objectId]; - } else if (constraintKey == '$in') { - relatedIds = query[key]['$in'].map(r => r.objectId); - } else if (constraintKey == '$nin') { - isNegation = true; - relatedIds = query[key]['$nin'].map(r => r.objectId); - } else if (constraintKey == '$ne') { - isNegation = true; - relatedIds = [query[key]['$ne'].objectId]; - } else { - return; - } - - return { - isNegation, - relatedIds - }; - }); - } else { - queries = [{ - isNegation: false, - relatedIds: [] - }]; - } // remove the current queryKey as we don,t need it anymore - - - delete query[key]; // execute each query independently to build the list of - // $in / $nin - - const promises = queries.map(q => { - if (!q) { - return Promise.resolve(); - } - - return this.owningIds(className, key, q.relatedIds).then(ids => { - if (q.isNegation) { - this.addNotInObjectIdsIds(ids, query); - } else { - this.addInObjectIdsIds(ids, query); - } - - return Promise.resolve(); - }); - }); - return Promise.all(promises).then(() => { - return Promise.resolve(); - }); - }); - return Promise.all(promises).then(() => { - return Promise.resolve(query); - }); - } // Modifies query so that it no longer has $relatedTo - // Returns a promise that resolves when query is mutated - - - reduceRelationKeys(className, query, queryOptions) { - if (query['$or']) { - return Promise.all(query['$or'].map(aQuery => { - return this.reduceRelationKeys(className, aQuery, queryOptions); - })); - } - - var relatedTo = query['$relatedTo']; - - if (relatedTo) { - return this.relatedIds(relatedTo.object.className, relatedTo.key, relatedTo.object.objectId, queryOptions).then(ids => { - delete query['$relatedTo']; - this.addInObjectIdsIds(ids, query); - return this.reduceRelationKeys(className, query, queryOptions); - }).then(() => {}); - } - } - - addInObjectIdsIds(ids = null, query) { - const idsFromString = typeof query.objectId === 'string' ? [query.objectId] : null; - const idsFromEq = query.objectId && query.objectId['$eq'] ? [query.objectId['$eq']] : null; - const idsFromIn = query.objectId && query.objectId['$in'] ? query.objectId['$in'] : null; // -disable-next - - const allIds = [idsFromString, idsFromEq, idsFromIn, ids].filter(list => list !== null); - const totalLength = allIds.reduce((memo, list) => memo + list.length, 0); - let idsIntersection = []; - - if (totalLength > 125) { - idsIntersection = _intersect.default.big(allIds); - } else { - idsIntersection = (0, _intersect.default)(allIds); - } // Need to make sure we don't clobber existing shorthand $eq constraints on objectId. - - - if (!('objectId' in query)) { - query.objectId = { - $in: undefined - }; - } else if (typeof query.objectId === 'string') { - query.objectId = { - $in: undefined, - $eq: query.objectId - }; - } - - query.objectId['$in'] = idsIntersection; - return query; - } - - addNotInObjectIdsIds(ids = [], query) { - const idsFromNin = query.objectId && query.objectId['$nin'] ? query.objectId['$nin'] : []; - let allIds = [...idsFromNin, ...ids].filter(list => list !== null); // make a set and spread to remove duplicates - - allIds = [...new Set(allIds)]; // Need to make sure we don't clobber existing shorthand $eq constraints on objectId. - - if (!('objectId' in query)) { - query.objectId = { - $nin: undefined - }; - } else if (typeof query.objectId === 'string') { - query.objectId = { - $nin: undefined, - $eq: query.objectId - }; - } - - query.objectId['$nin'] = allIds; - return query; - } // Runs a query on the database. - // Returns a promise that resolves to a list of items. - // Options: - // skip number of results to skip. - // limit limit to this number of results. - // sort an object where keys are the fields to sort by. - // the value is +1 for ascending, -1 for descending. - // count run a count instead of returning results. - // acl restrict this operation with an ACL for the provided array - // of user objectIds and roles. acl: null means no user. - // when this field is not present, don't do anything regarding ACLs. - // caseInsensitive make string comparisons case insensitive - // TODO: make userIds not needed here. The db adapter shouldn't know - // anything about users, ideally. Then, improve the format of the ACL - // arg to work like the others. - - - find(className, query, { - skip, - limit, - acl, - sort = {}, - count, - keys, - op, - distinct, - pipeline, - readPreference, - hint, - caseInsensitive = false, - explain - } = {}, auth = {}, validSchemaController) { - const isMaster = acl === undefined; - const aclGroup = acl || []; - op = op || (typeof query.objectId == 'string' && Object.keys(query).length === 1 ? 'get' : 'find'); // Count operation if counting - - op = count === true ? 'count' : op; - let classExists = true; - return this.loadSchemaIfNeeded(validSchemaController).then(schemaController => { - //Allow volatile classes if querying with Master (for _PushStatus) - //TODO: Move volatile classes concept into mongo adapter, postgres adapter shouldn't care - //that api.parse.com breaks when _PushStatus exists in mongo. - return schemaController.getOneSchema(className, isMaster).catch(error => { - // Behavior for non-existent classes is kinda weird on Parse.com. Probably doesn't matter too much. - // For now, pretend the class exists but has no objects, - if (error === undefined) { - classExists = false; - return { - fields: {} - }; - } - - throw error; - }).then(schema => { - // Parse.com treats queries on _created_at and _updated_at as if they were queries on createdAt and updatedAt, - // so duplicate that behavior here. If both are specified, the correct behavior to match Parse.com is to - // use the one that appears first in the sort list. - if (sort._created_at) { - sort.createdAt = sort._created_at; - delete sort._created_at; - } - - if (sort._updated_at) { - sort.updatedAt = sort._updated_at; - delete sort._updated_at; - } - - const queryOptions = { - skip, - limit, - sort, - keys, - readPreference, - hint, - caseInsensitive, - explain - }; - Object.keys(sort).forEach(fieldName => { - if (fieldName.match(/^authData\.([a-zA-Z0-9_]+)\.id$/)) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Cannot sort by ${fieldName}`); - } - - const rootFieldName = getRootFieldName(fieldName); - - if (!SchemaController.fieldNameIsValid(rootFieldName, className)) { - throw new _node.Parse.Error(_node.Parse.Error.INVALID_KEY_NAME, `Invalid field name: ${fieldName}.`); - } - }); - return (isMaster ? Promise.resolve() : schemaController.validatePermission(className, aclGroup, op)).then(() => this.reduceRelationKeys(className, query, queryOptions)).then(() => this.reduceInRelation(className, query, schemaController)).then(() => { - let protectedFields; - - if (!isMaster) { - query = this.addPointerPermissions(schemaController, className, op, query, aclGroup); - /* Don't use projections to optimize the protectedFields since the protectedFields - based on pointer-permissions are determined after querying. The filtering can - overwrite the protected fields. */ - - protectedFields = this.addProtectedFields(schemaController, className, query, aclGroup, auth, queryOptions); - } - - if (!query) { - if (op === 'get') { - throw new _node.Parse.Error(_node.Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } else { - return []; - } - } - - if (!isMaster) { - if (op === 'update' || op === 'delete') { - query = addWriteACL(query, aclGroup); - } else { - query = addReadACL(query, aclGroup); - } - } - - validateQuery(query); - - if (count) { - if (!classExists) { - return 0; - } else { - return this.adapter.count(className, schema, query, readPreference, undefined, hint); - } - } else if (distinct) { - if (!classExists) { - return []; - } else { - return this.adapter.distinct(className, schema, query, distinct); - } - } else if (pipeline) { - if (!classExists) { - return []; - } else { - return this.adapter.aggregate(className, schema, pipeline, readPreference, hint, explain); - } - } else if (explain) { - return this.adapter.find(className, schema, query, queryOptions); - } else { - return this.adapter.find(className, schema, query, queryOptions).then(objects => objects.map(object => { - object = untransformObjectACL(object); - return filterSensitiveData(isMaster, aclGroup, auth, op, schemaController, className, protectedFields, object); - })).catch(error => { - throw new _node.Parse.Error(_node.Parse.Error.INTERNAL_SERVER_ERROR, error); - }); - } - }); - }); - }); - } - - deleteSchema(className) { - return this.loadSchema({ - clearCache: true - }).then(schemaController => schemaController.getOneSchema(className, true)).catch(error => { - if (error === undefined) { - return { - fields: {} - }; - } else { - throw error; - } - }).then(schema => { - return this.collectionExists(className).then(() => this.adapter.count(className, { - fields: {} - }, null, '', false)).then(count => { - if (count > 0) { - throw new _node.Parse.Error(255, `Class ${className} is not empty, contains ${count} objects, cannot drop schema.`); - } - - return this.adapter.deleteClass(className); - }).then(wasParseCollection => { - if (wasParseCollection) { - const relationFieldNames = Object.keys(schema.fields).filter(fieldName => schema.fields[fieldName].type === 'Relation'); - return Promise.all(relationFieldNames.map(name => this.adapter.deleteClass(joinTableName(className, name)))).then(() => { - return; - }); - } else { - return Promise.resolve(); - } - }); - }); - } // This helps to create intermediate objects for simpler comparison of - // key value pairs used in query objects. Each key value pair will represented - // in a similar way to json - - - objectToEntriesStrings(query) { - return Object.entries(query).map(a => a.map(s => JSON.stringify(s)).join(':')); - } // Naive logic reducer for OR operations meant to be used only for pointer permissions. - - - reduceOrOperation(query) { - if (!query.$or) { - return query; - } - - const queries = query.$or.map(q => this.objectToEntriesStrings(q)); - let repeat = false; - - do { - repeat = false; - - for (let i = 0; i < queries.length - 1; i++) { - for (let j = i + 1; j < queries.length; j++) { - const [shorter, longer] = queries[i].length > queries[j].length ? [j, i] : [i, j]; - const foundEntries = queries[shorter].reduce((acc, entry) => acc + (queries[longer].includes(entry) ? 1 : 0), 0); - const shorterEntries = queries[shorter].length; - - if (foundEntries === shorterEntries) { - // If the shorter query is completely contained in the longer one, we can strike - // out the longer query. - query.$or.splice(longer, 1); - queries.splice(longer, 1); - repeat = true; - break; - } - } - } - } while (repeat); - - if (query.$or.length === 1) { - query = _objectSpread(_objectSpread({}, query), query.$or[0]); - delete query.$or; - } - - return query; - } // Naive logic reducer for AND operations meant to be used only for pointer permissions. - - - reduceAndOperation(query) { - if (!query.$and) { - return query; - } - - const queries = query.$and.map(q => this.objectToEntriesStrings(q)); - let repeat = false; - - do { - repeat = false; - - for (let i = 0; i < queries.length - 1; i++) { - for (let j = i + 1; j < queries.length; j++) { - const [shorter, longer] = queries[i].length > queries[j].length ? [j, i] : [i, j]; - const foundEntries = queries[shorter].reduce((acc, entry) => acc + (queries[longer].includes(entry) ? 1 : 0), 0); - const shorterEntries = queries[shorter].length; - - if (foundEntries === shorterEntries) { - // If the shorter query is completely contained in the longer one, we can strike - // out the shorter query. - query.$and.splice(shorter, 1); - queries.splice(shorter, 1); - repeat = true; - break; - } - } - } - } while (repeat); - - if (query.$and.length === 1) { - query = _objectSpread(_objectSpread({}, query), query.$and[0]); - delete query.$and; - } - - return query; - } // Constraints query using CLP's pointer permissions (PP) if any. - // 1. Etract the user id from caller's ACLgroup; - // 2. Exctract a list of field names that are PP for target collection and operation; - // 3. Constraint the original query so that each PP field must - // point to caller's id (or contain it in case of PP field being an array) - - - addPointerPermissions(schema, className, operation, query, aclGroup = []) { - // Check if class has public permission for operation - // If the BaseCLP pass, let go through - if (schema.testPermissionsForClassName(className, aclGroup, operation)) { - return query; - } - - const perms = schema.getClassLevelPermissions(className); - const userACL = aclGroup.filter(acl => { - return acl.indexOf('role:') != 0 && acl != '*'; - }); - const groupKey = ['get', 'find', 'count'].indexOf(operation) > -1 ? 'readUserFields' : 'writeUserFields'; - const permFields = []; - - if (perms[operation] && perms[operation].pointerFields) { - permFields.push(...perms[operation].pointerFields); - } - - if (perms[groupKey]) { - for (const field of perms[groupKey]) { - if (!permFields.includes(field)) { - permFields.push(field); - } - } - } // the ACL should have exactly 1 user - - - if (permFields.length > 0) { - // the ACL should have exactly 1 user - // No user set return undefined - // If the length is > 1, that means we didn't de-dupe users correctly - if (userACL.length != 1) { - return; - } - - const userId = userACL[0]; - const userPointer = { - __type: 'Pointer', - className: '_User', - objectId: userId - }; - const queries = permFields.map(key => { - const fieldDescriptor = schema.getExpectedType(className, key); - const fieldType = fieldDescriptor && typeof fieldDescriptor === 'object' && Object.prototype.hasOwnProperty.call(fieldDescriptor, 'type') ? fieldDescriptor.type : null; - let queryClause; - - if (fieldType === 'Pointer') { - // constraint for single pointer setup - queryClause = { - [key]: userPointer - }; - } else if (fieldType === 'Array') { - // constraint for users-array setup - queryClause = { - [key]: { - $all: [userPointer] - } - }; - } else if (fieldType === 'Object') { - // constraint for object setup - queryClause = { - [key]: userPointer - }; - } else { - // This means that there is a CLP field of an unexpected type. This condition should not happen, which is - // why is being treated as an error. - throw Error(`An unexpected condition occurred when resolving pointer permissions: ${className} ${key}`); - } // if we already have a constraint on the key, use the $and - - - if (Object.prototype.hasOwnProperty.call(query, key)) { - return this.reduceAndOperation({ - $and: [queryClause, query] - }); - } // otherwise just add the constaint - - - return Object.assign({}, query, queryClause); - }); - return queries.length === 1 ? queries[0] : this.reduceOrOperation({ - $or: queries - }); - } else { - return query; - } - } - - addProtectedFields(schema, className, query = {}, aclGroup = [], auth = {}, queryOptions = {}) { - const perms = schema.getClassLevelPermissions(className); - if (!perms) return null; - const protectedFields = perms.protectedFields; - if (!protectedFields) return null; - if (aclGroup.indexOf(query.objectId) > -1) return null; // for queries where "keys" are set and do not include all 'userField':{field}, - // we have to transparently include it, and then remove before returning to client - // Because if such key not projected the permission won't be enforced properly - // PS this is called when 'excludeKeys' already reduced to 'keys' - - const preserveKeys = queryOptions.keys; // these are keys that need to be included only - // to be able to apply protectedFields by pointer - // and then unset before returning to client (later in filterSensitiveFields) - - const serverOnlyKeys = []; - const authenticated = auth.user; // map to allow check without array search - - const roles = (auth.userRoles || []).reduce((acc, r) => { - acc[r] = protectedFields[r]; - return acc; - }, {}); // array of sets of protected fields. separate item for each applicable criteria - - const protectedKeysSets = []; - - for (const key in protectedFields) { - // skip userFields - if (key.startsWith('userField:')) { - if (preserveKeys) { - const fieldName = key.substring(10); - - if (!preserveKeys.includes(fieldName)) { - // 1. put it there temporarily - queryOptions.keys && queryOptions.keys.push(fieldName); // 2. preserve it delete later - - serverOnlyKeys.push(fieldName); - } - } - - continue; - } // add public tier - - - if (key === '*') { - protectedKeysSets.push(protectedFields[key]); - continue; - } - - if (authenticated) { - if (key === 'authenticated') { - // for logged in users - protectedKeysSets.push(protectedFields[key]); - continue; - } - - if (roles[key] && key.startsWith('role:')) { - // add applicable roles - protectedKeysSets.push(roles[key]); - } - } - } // check if there's a rule for current user's id - - - if (authenticated) { - const userId = auth.user.id; - - if (perms.protectedFields[userId]) { - protectedKeysSets.push(perms.protectedFields[userId]); - } - } // preserve fields to be removed before sending response to client - - - if (serverOnlyKeys.length > 0) { - perms.protectedFields.temporaryKeys = serverOnlyKeys; - } - - let protectedKeys = protectedKeysSets.reduce((acc, next) => { - if (next) { - acc.push(...next); - } - - return acc; - }, []); // intersect all sets of protectedFields - - protectedKeysSets.forEach(fields => { - if (fields) { - protectedKeys = protectedKeys.filter(v => fields.includes(v)); - } - }); - return protectedKeys; - } - - createTransactionalSession() { - return this.adapter.createTransactionalSession().then(transactionalSession => { - this._transactionalSession = transactionalSession; - }); - } - - commitTransactionalSession() { - if (!this._transactionalSession) { - throw new Error('There is no transactional session to commit'); - } - - return this.adapter.commitTransactionalSession(this._transactionalSession).then(() => { - this._transactionalSession = null; - }); - } - - abortTransactionalSession() { - if (!this._transactionalSession) { - throw new Error('There is no transactional session to abort'); - } - - return this.adapter.abortTransactionalSession(this._transactionalSession).then(() => { - this._transactionalSession = null; - }); - } // TODO: create indexes on first creation of a _User object. Otherwise it's impossible to - // have a Parse app without it having a _User collection. - - - performInitialization() { - const requiredUserFields = { - fields: _objectSpread(_objectSpread({}, SchemaController.defaultColumns._Default), SchemaController.defaultColumns._User) - }; - const requiredRoleFields = { - fields: _objectSpread(_objectSpread({}, SchemaController.defaultColumns._Default), SchemaController.defaultColumns._Role) - }; - const requiredIdempotencyFields = { - fields: _objectSpread(_objectSpread({}, SchemaController.defaultColumns._Default), SchemaController.defaultColumns._Idempotency) - }; - const userClassPromise = this.loadSchema().then(schema => schema.enforceClassExists('_User')); - const roleClassPromise = this.loadSchema().then(schema => schema.enforceClassExists('_Role')); - const idempotencyClassPromise = this.adapter instanceof _MongoStorageAdapter.default ? this.loadSchema().then(schema => schema.enforceClassExists('_Idempotency')) : Promise.resolve(); - const usernameUniqueness = userClassPromise.then(() => this.adapter.ensureUniqueness('_User', requiredUserFields, ['username'])).catch(error => { - _logger.default.warn('Unable to ensure uniqueness for usernames: ', error); - - throw error; - }); - const usernameCaseInsensitiveIndex = userClassPromise.then(() => this.adapter.ensureIndex('_User', requiredUserFields, ['username'], 'case_insensitive_username', true)).catch(error => { - _logger.default.warn('Unable to create case insensitive username index: ', error); - - throw error; - }); - const emailUniqueness = userClassPromise.then(() => this.adapter.ensureUniqueness('_User', requiredUserFields, ['email'])).catch(error => { - _logger.default.warn('Unable to ensure uniqueness for user email addresses: ', error); - - throw error; - }); - const emailCaseInsensitiveIndex = userClassPromise.then(() => this.adapter.ensureIndex('_User', requiredUserFields, ['email'], 'case_insensitive_email', true)).catch(error => { - _logger.default.warn('Unable to create case insensitive email index: ', error); - - throw error; - }); - const roleUniqueness = roleClassPromise.then(() => this.adapter.ensureUniqueness('_Role', requiredRoleFields, ['name'])).catch(error => { - _logger.default.warn('Unable to ensure uniqueness for role name: ', error); - - throw error; - }); - const idempotencyRequestIdIndex = this.adapter instanceof _MongoStorageAdapter.default ? idempotencyClassPromise.then(() => this.adapter.ensureUniqueness('_Idempotency', requiredIdempotencyFields, ['reqId'])).catch(error => { - _logger.default.warn('Unable to ensure uniqueness for idempotency request ID: ', error); - - throw error; - }) : Promise.resolve(); - const idempotencyExpireIndex = this.adapter instanceof _MongoStorageAdapter.default ? idempotencyClassPromise.then(() => this.adapter.ensureIndex('_Idempotency', requiredIdempotencyFields, ['expire'], 'ttl', false, { - ttl: 0 - })).catch(error => { - _logger.default.warn('Unable to create TTL index for idempotency expire date: ', error); - - throw error; - }) : Promise.resolve(); - const indexPromise = this.adapter.updateSchemaWithIndexes(); // Create tables for volatile classes - - const adapterInit = this.adapter.performInitialization({ - VolatileClassesSchemas: SchemaController.VolatileClassesSchemas - }); - return Promise.all([usernameUniqueness, usernameCaseInsensitiveIndex, emailUniqueness, emailCaseInsensitiveIndex, roleUniqueness, idempotencyRequestIdIndex, idempotencyExpireIndex, adapterInit, indexPromise]); - } - -} - -module.exports = DatabaseController; // Expose validateQuery for tests - -module.exports._validateQuery = validateQuery; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9EYXRhYmFzZUNvbnRyb2xsZXIuanMiXSwibmFtZXMiOlsiYWRkV3JpdGVBQ0wiLCJxdWVyeSIsImFjbCIsIm5ld1F1ZXJ5IiwiXyIsImNsb25lRGVlcCIsIl93cGVybSIsIiRpbiIsImFkZFJlYWRBQ0wiLCJfcnBlcm0iLCJ0cmFuc2Zvcm1PYmplY3RBQ0wiLCJBQ0wiLCJyZXN1bHQiLCJlbnRyeSIsInJlYWQiLCJwdXNoIiwid3JpdGUiLCJzcGVjaWFsUXVlcnlrZXlzIiwiaXNTcGVjaWFsUXVlcnlLZXkiLCJrZXkiLCJpbmRleE9mIiwidmFsaWRhdGVRdWVyeSIsIlBhcnNlIiwiRXJyb3IiLCJJTlZBTElEX1FVRVJZIiwiJG9yIiwiQXJyYXkiLCJmb3JFYWNoIiwiJGFuZCIsIiRub3IiLCJsZW5ndGgiLCJPYmplY3QiLCJrZXlzIiwiJHJlZ2V4IiwiJG9wdGlvbnMiLCJtYXRjaCIsIklOVkFMSURfS0VZX05BTUUiLCJmaWx0ZXJTZW5zaXRpdmVEYXRhIiwiaXNNYXN0ZXIiLCJhY2xHcm91cCIsImF1dGgiLCJvcGVyYXRpb24iLCJzY2hlbWEiLCJjbGFzc05hbWUiLCJwcm90ZWN0ZWRGaWVsZHMiLCJvYmplY3QiLCJ1c2VySWQiLCJ1c2VyIiwiaWQiLCJwZXJtcyIsImdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsImlzUmVhZE9wZXJhdGlvbiIsInByb3RlY3RlZEZpZWxkc1BvaW50ZXJQZXJtIiwiZmlsdGVyIiwic3RhcnRzV2l0aCIsIm1hcCIsInN1YnN0cmluZyIsInZhbHVlIiwibmV3UHJvdGVjdGVkRmllbGRzIiwib3ZlcnJpZGVQcm90ZWN0ZWRGaWVsZHMiLCJwb2ludGVyUGVybSIsInBvaW50ZXJQZXJtSW5jbHVkZXNVc2VyIiwicmVhZFVzZXJGaWVsZFZhbHVlIiwiaXNBcnJheSIsInNvbWUiLCJvYmplY3RJZCIsImZpZWxkcyIsInYiLCJpbmNsdWRlcyIsImlzVXNlckNsYXNzIiwiayIsInRlbXBvcmFyeUtleXMiLCJwYXNzd29yZCIsIl9oYXNoZWRfcGFzc3dvcmQiLCJzZXNzaW9uVG9rZW4iLCJfZW1haWxfdmVyaWZ5X3Rva2VuIiwiX3BlcmlzaGFibGVfdG9rZW4iLCJfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0IiwiX3RvbWJzdG9uZSIsIl9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCIsIl9mYWlsZWRfbG9naW5fY291bnQiLCJfYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQiLCJfcGFzc3dvcmRfY2hhbmdlZF9hdCIsIl9wYXNzd29yZF9oaXN0b3J5IiwiYXV0aERhdGEiLCJzcGVjaWFsS2V5c0ZvclVwZGF0ZSIsImlzU3BlY2lhbFVwZGF0ZUtleSIsImV4cGFuZFJlc3VsdE9uS2V5UGF0aCIsInBhdGgiLCJzcGxpdCIsImZpcnN0S2V5IiwibmV4dFBhdGgiLCJzbGljZSIsImpvaW4iLCJzYW5pdGl6ZURhdGFiYXNlUmVzdWx0Iiwib3JpZ2luYWxPYmplY3QiLCJyZXNwb25zZSIsIlByb21pc2UiLCJyZXNvbHZlIiwia2V5VXBkYXRlIiwiX19vcCIsImpvaW5UYWJsZU5hbWUiLCJmbGF0dGVuVXBkYXRlT3BlcmF0b3JzRm9yQ3JlYXRlIiwiYW1vdW50IiwiSU5WQUxJRF9KU09OIiwib2JqZWN0cyIsIkNPTU1BTkRfVU5BVkFJTEFCTEUiLCJ0cmFuc2Zvcm1BdXRoRGF0YSIsInByb3ZpZGVyIiwicHJvdmlkZXJEYXRhIiwiZmllbGROYW1lIiwidHlwZSIsInVudHJhbnNmb3JtT2JqZWN0QUNMIiwib3V0cHV0IiwiZ2V0Um9vdEZpZWxkTmFtZSIsInJlbGF0aW9uU2NoZW1hIiwicmVsYXRlZElkIiwib3duaW5nSWQiLCJEYXRhYmFzZUNvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImFkYXB0ZXIiLCJzY2hlbWFDYWNoZSIsInNjaGVtYVByb21pc2UiLCJfdHJhbnNhY3Rpb25hbFNlc3Npb24iLCJjb2xsZWN0aW9uRXhpc3RzIiwiY2xhc3NFeGlzdHMiLCJwdXJnZUNvbGxlY3Rpb24iLCJsb2FkU2NoZW1hIiwidGhlbiIsInNjaGVtYUNvbnRyb2xsZXIiLCJnZXRPbmVTY2hlbWEiLCJkZWxldGVPYmplY3RzQnlRdWVyeSIsInZhbGlkYXRlQ2xhc3NOYW1lIiwiU2NoZW1hQ29udHJvbGxlciIsImNsYXNzTmFtZUlzVmFsaWQiLCJyZWplY3QiLCJJTlZBTElEX0NMQVNTX05BTUUiLCJvcHRpb25zIiwiY2xlYXJDYWNoZSIsImxvYWQiLCJsb2FkU2NoZW1hSWZOZWVkZWQiLCJyZWRpcmVjdENsYXNzTmFtZUZvcktleSIsInQiLCJnZXRFeHBlY3RlZFR5cGUiLCJ0YXJnZXRDbGFzcyIsInZhbGlkYXRlT2JqZWN0IiwicnVuT3B0aW9ucyIsInVuZGVmaW5lZCIsInMiLCJjYW5BZGRGaWVsZCIsInVwZGF0ZSIsIm1hbnkiLCJ1cHNlcnQiLCJhZGRzRmllbGQiLCJza2lwU2FuaXRpemF0aW9uIiwidmFsaWRhdGVPbmx5IiwidmFsaWRTY2hlbWFDb250cm9sbGVyIiwib3JpZ2luYWxRdWVyeSIsIm9yaWdpbmFsVXBkYXRlIiwicmVsYXRpb25VcGRhdGVzIiwidmFsaWRhdGVQZXJtaXNzaW9uIiwiY29sbGVjdFJlbGF0aW9uVXBkYXRlcyIsImFkZFBvaW50ZXJQZXJtaXNzaW9ucyIsImNhdGNoIiwiZXJyb3IiLCJyb290RmllbGROYW1lIiwiZmllbGROYW1lSXNWYWxpZCIsInVwZGF0ZU9wZXJhdGlvbiIsImlubmVyS2V5IiwiSU5WQUxJRF9ORVNURURfS0VZIiwiZmluZCIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ1cGRhdGVPYmplY3RzQnlRdWVyeSIsInVwc2VydE9uZU9iamVjdCIsImZpbmRPbmVBbmRVcGRhdGUiLCJoYW5kbGVSZWxhdGlvblVwZGF0ZXMiLCJvcHMiLCJkZWxldGVNZSIsInByb2Nlc3MiLCJvcCIsIngiLCJwZW5kaW5nIiwiYWRkUmVsYXRpb24iLCJyZW1vdmVSZWxhdGlvbiIsImFsbCIsImZyb21DbGFzc05hbWUiLCJmcm9tSWQiLCJ0b0lkIiwiZG9jIiwiY29kZSIsImRlc3Ryb3kiLCJwYXJzZUZvcm1hdFNjaGVtYSIsImNyZWF0ZSIsImNyZWF0ZWRBdCIsImlzbyIsIl9fdHlwZSIsInVwZGF0ZWRBdCIsImVuZm9yY2VDbGFzc0V4aXN0cyIsImNyZWF0ZU9iamVjdCIsImNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEiLCJjbGFzc1NjaGVtYSIsInNjaGVtYURhdGEiLCJzY2hlbWFGaWVsZHMiLCJuZXdLZXlzIiwiZmllbGQiLCJhY3Rpb24iLCJkZWxldGVFdmVyeXRoaW5nIiwiZmFzdCIsImRlbGV0ZUFsbENsYXNzZXMiLCJjbGVhciIsInJlbGF0ZWRJZHMiLCJxdWVyeU9wdGlvbnMiLCJza2lwIiwibGltaXQiLCJzb3J0IiwiZmluZE9wdGlvbnMiLCJjYW5Tb3J0T25Kb2luVGFibGVzIiwiX2lkIiwicmVzdWx0cyIsIm93bmluZ0lkcyIsInJlZHVjZUluUmVsYXRpb24iLCJvcnMiLCJhUXVlcnkiLCJpbmRleCIsInByb21pc2VzIiwicXVlcmllcyIsImNvbnN0cmFpbnRLZXkiLCJpc05lZ2F0aW9uIiwiciIsInEiLCJpZHMiLCJhZGROb3RJbk9iamVjdElkc0lkcyIsImFkZEluT2JqZWN0SWRzSWRzIiwicmVkdWNlUmVsYXRpb25LZXlzIiwicmVsYXRlZFRvIiwiaWRzRnJvbVN0cmluZyIsImlkc0Zyb21FcSIsImlkc0Zyb21JbiIsImFsbElkcyIsImxpc3QiLCJ0b3RhbExlbmd0aCIsInJlZHVjZSIsIm1lbW8iLCJpZHNJbnRlcnNlY3Rpb24iLCJpbnRlcnNlY3QiLCJiaWciLCIkZXEiLCJpZHNGcm9tTmluIiwiU2V0IiwiJG5pbiIsImNvdW50IiwiZGlzdGluY3QiLCJwaXBlbGluZSIsInJlYWRQcmVmZXJlbmNlIiwiaGludCIsImNhc2VJbnNlbnNpdGl2ZSIsImV4cGxhaW4iLCJfY3JlYXRlZF9hdCIsIl91cGRhdGVkX2F0IiwiYWRkUHJvdGVjdGVkRmllbGRzIiwiYWdncmVnYXRlIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiZGVsZXRlU2NoZW1hIiwiZGVsZXRlQ2xhc3MiLCJ3YXNQYXJzZUNvbGxlY3Rpb24iLCJyZWxhdGlvbkZpZWxkTmFtZXMiLCJuYW1lIiwib2JqZWN0VG9FbnRyaWVzU3RyaW5ncyIsImVudHJpZXMiLCJhIiwiSlNPTiIsInN0cmluZ2lmeSIsInJlZHVjZU9yT3BlcmF0aW9uIiwicmVwZWF0IiwiaSIsImoiLCJzaG9ydGVyIiwibG9uZ2VyIiwiZm91bmRFbnRyaWVzIiwiYWNjIiwic2hvcnRlckVudHJpZXMiLCJzcGxpY2UiLCJyZWR1Y2VBbmRPcGVyYXRpb24iLCJ0ZXN0UGVybWlzc2lvbnNGb3JDbGFzc05hbWUiLCJ1c2VyQUNMIiwiZ3JvdXBLZXkiLCJwZXJtRmllbGRzIiwicG9pbnRlckZpZWxkcyIsInVzZXJQb2ludGVyIiwiZmllbGREZXNjcmlwdG9yIiwiZmllbGRUeXBlIiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwicXVlcnlDbGF1c2UiLCIkYWxsIiwiYXNzaWduIiwicHJlc2VydmVLZXlzIiwic2VydmVyT25seUtleXMiLCJhdXRoZW50aWNhdGVkIiwicm9sZXMiLCJ1c2VyUm9sZXMiLCJwcm90ZWN0ZWRLZXlzU2V0cyIsInByb3RlY3RlZEtleXMiLCJuZXh0IiwiY3JlYXRlVHJhbnNhY3Rpb25hbFNlc3Npb24iLCJ0cmFuc2FjdGlvbmFsU2Vzc2lvbiIsImNvbW1pdFRyYW5zYWN0aW9uYWxTZXNzaW9uIiwiYWJvcnRUcmFuc2FjdGlvbmFsU2Vzc2lvbiIsInBlcmZvcm1Jbml0aWFsaXphdGlvbiIsInJlcXVpcmVkVXNlckZpZWxkcyIsImRlZmF1bHRDb2x1bW5zIiwiX0RlZmF1bHQiLCJfVXNlciIsInJlcXVpcmVkUm9sZUZpZWxkcyIsIl9Sb2xlIiwicmVxdWlyZWRJZGVtcG90ZW5jeUZpZWxkcyIsIl9JZGVtcG90ZW5jeSIsInVzZXJDbGFzc1Byb21pc2UiLCJyb2xlQ2xhc3NQcm9taXNlIiwiaWRlbXBvdGVuY3lDbGFzc1Byb21pc2UiLCJNb25nb1N0b3JhZ2VBZGFwdGVyIiwidXNlcm5hbWVVbmlxdWVuZXNzIiwiZW5zdXJlVW5pcXVlbmVzcyIsImxvZ2dlciIsIndhcm4iLCJ1c2VybmFtZUNhc2VJbnNlbnNpdGl2ZUluZGV4IiwiZW5zdXJlSW5kZXgiLCJlbWFpbFVuaXF1ZW5lc3MiLCJlbWFpbENhc2VJbnNlbnNpdGl2ZUluZGV4Iiwicm9sZVVuaXF1ZW5lc3MiLCJpZGVtcG90ZW5jeVJlcXVlc3RJZEluZGV4IiwiaWRlbXBvdGVuY3lFeHBpcmVJbmRleCIsInR0bCIsImluZGV4UHJvbWlzZSIsInVwZGF0ZVNjaGVtYVdpdGhJbmRleGVzIiwiYWRhcHRlckluaXQiLCJWb2xhdGlsZUNsYXNzZXNTY2hlbWFzIiwibW9kdWxlIiwiZXhwb3J0cyIsIl92YWxpZGF0ZVF1ZXJ5Il0sIm1hcHBpbmdzIjoiOztBQUtBOztBQUVBOztBQUVBOztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQTJOQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBeE5BLFNBQVNBLFdBQVQsQ0FBcUJDLEtBQXJCLEVBQTRCQyxHQUE1QixFQUFpQztBQUMvQixRQUFNQyxRQUFRLEdBQUdDLGdCQUFFQyxTQUFGLENBQVlKLEtBQVosQ0FBakIsQ0FEK0IsQ0FFL0I7OztBQUNBRSxFQUFBQSxRQUFRLENBQUNHLE1BQVQsR0FBa0I7QUFBRUMsSUFBQUEsR0FBRyxFQUFFLENBQUMsSUFBRCxFQUFPLEdBQUdMLEdBQVY7QUFBUCxHQUFsQjtBQUNBLFNBQU9DLFFBQVA7QUFDRDs7QUFFRCxTQUFTSyxVQUFULENBQW9CUCxLQUFwQixFQUEyQkMsR0FBM0IsRUFBZ0M7QUFDOUIsUUFBTUMsUUFBUSxHQUFHQyxnQkFBRUMsU0FBRixDQUFZSixLQUFaLENBQWpCLENBRDhCLENBRTlCOzs7QUFDQUUsRUFBQUEsUUFBUSxDQUFDTSxNQUFULEdBQWtCO0FBQUVGLElBQUFBLEdBQUcsRUFBRSxDQUFDLElBQUQsRUFBTyxHQUFQLEVBQVksR0FBR0wsR0FBZjtBQUFQLEdBQWxCO0FBQ0EsU0FBT0MsUUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0EsTUFBTU8sa0JBQWtC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RUFNakJDLHlCQU5pQixFQU9qQkMsc0JBUGlCLEVBUWpCSSxXQVJpQixFQVNqQkYsWUFUaUIsQ0FBWixDQUFQO0FBV0Q7O0FBeDNDc0I7O0FBNjNDekJJLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQjdOLGtCQUFqQixDLENBQ0E7O0FBQ0E0TixNQUFNLENBQUNDLE9BQVAsQ0FBZUMsY0FBZixHQUFnQy9ULGFBQWhDIiwic291cmNlc0NvbnRlbnQiOlsi77u/Ly8gQGZsb3dcbi8vIEEgZGF0YWJhc2UgYWRhcHRlciB0aGF0IHdvcmtzIHdpdGggZGF0YSBleHBvcnRlZCBmcm9tIHRoZSBob3N0ZWRcbi8vIFBhcnNlIGRhdGFiYXNlLlxuXG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCB7IFBhcnNlIH0gZnJvbSAncGFyc2Uvbm9kZSc7XG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCBpbnRlcnNlY3QgZnJvbSAnaW50ZXJzZWN0Jztcbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuaW1wb3J0IGRlZXBjb3B5IGZyb20gJ2RlZXBjb3B5JztcbmltcG9ydCBsb2dnZXIgZnJvbSAnLi4vbG9nZ2VyJztcbmltcG9ydCAqIGFzIFNjaGVtYUNvbnRyb2xsZXIgZnJvbSAnLi9TY2hlbWFDb250cm9sbGVyJztcbmltcG9ydCB7IFN0b3JhZ2VBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvU3RvcmFnZS9TdG9yYWdlQWRhcHRlcic7XG5pbXBvcnQgdHlwZSB7IFF1ZXJ5T3B0aW9ucywgRnVsbFF1ZXJ5T3B0aW9ucyB9IGZyb20gJy4uL0FkYXB0ZXJzL1N0b3JhZ2UvU3RvcmFnZUFkYXB0ZXInO1xuXG5mdW5jdGlvbiBhZGRXcml0ZUFDTChxdWVyeSwgYWNsKSB7XG4gIGNvbnN0IG5ld1F1ZXJ5ID0gXy5jbG9uZURlZXAocXVlcnkpO1xuICAvL0Nhbid0IGJlIGFueSBleGlzdGluZyAnX3dwZXJtJyBxdWVyeSwgd2UgZG9uJ3QgYWxsb3cgY2xpZW50IHF1ZXJpZXMgb24gdGhhdCwgbm8gbmVlZCB0byAkYW5kXG4gIG5ld1F1ZXJ5Ll93cGVybSA9IHsgJGluOiBbbnVsbCwgLi4uYWNsXSB9O1xuICByZXR1cm4gbmV3UXVlcnk7XG59XG5cbmZ1bmN0aW9uIGFkZFJlYWRBQ0wocXVlcnksIGFjbCkge1xuICBjb25zdCBuZXdRdWVyeSA9IF8uY2xvbmVEZWVwKHF1ZXJ5KTtcbiAgLy9DYW4ndCBiZSBhbnkgZXhpc3RpbmcgJ19ycGVybScgcXVlcnksIHdlIGRvbid0IGFsbG93IGNsaWVudCBxdWVyaWVzIG9uIHRoYXQsIG5vIG5lZWQgdG8gJGFuZFxuICBuZXdRdWVyeS5fcnBlcm0gPSB7ICRpbjogW251bGwsICcqJywgLi4uYWNsXSB9O1xuICByZXR1cm4gbmV3UXVlcnk7XG59XG5cbi8vIFRyYW5zZm9ybXMgYSBSRVNUIEFQSSBmb3JtYXR0ZWQgQUNMIG9iamVjdCB0byBvdXIgdHdvLWZpZWxkIG1vbmdvIGZvcm1hdC5cbmNvbnN0IHRyYW5zZm9ybU9iamVjdEFDTCA9ICh7IEFDTCwgLi4ucmVzdWx0IH0pID0+IHtcbiAgaWYgKCFBQ0wpIHtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcmVzdWx0Ll93cGVybSA9IFtdO1xuICByZXN1bHQuX3JwZXJtID0gW107XG5cbiAgZm9yIChjb25zdCBlbnRyeSBpbiBBQ0wpIHtcbiAgICBpZiAoQUNMW2VudHJ5XS5yZWFkKSB7XG4gICAgICByZXN1bHQuX3JwZXJtLnB1c2goZW50cnkpO1xuICAgIH1cbiAgICBpZiAoQUNMW2VudHJ5XS53cml0ZSkge1xuICAgICAgcmVzdWx0Ll93cGVybS5wdXNoKGVudHJ5KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbmNvbnN0IHNwZWNpYWxRdWVyeWtleXMgPSBbXG4gICckYW5kJyxcbiAgJyRvcicsXG4gICckbm9yJyxcbiAgJ19ycGVybScsXG4gICdfd3Blcm0nLFxuICAnX3BlcmlzaGFibGVfdG9rZW4nLFxuICAnX2VtYWlsX3ZlcmlmeV90b2tlbicsXG4gICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnLFxuICAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JyxcbiAgJ19mYWlsZWRfbG9naW5fY291bnQnLFxuXTtcblxuY29uc3QgaXNTcGVjaWFsUXVlcnlLZXkgPSBrZXkgPT4ge1xuICByZXR1cm4gc3BlY2lhbFF1ZXJ5a2V5cy5pbmRleE9mKGtleSkgPj0gMDtcbn07XG5cbmNvbnN0IHZhbGlkYXRlUXVlcnkgPSAocXVlcnk6IGFueSk6IHZvaWQgPT4ge1xuICBpZiAocXVlcnkuQUNMKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksICdDYW5ub3QgcXVlcnkgb24gQUNMLicpO1xuICB9XG5cbiAgaWYgKHF1ZXJ5LiRvcikge1xuICAgIGlmIChxdWVyeS4kb3IgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgcXVlcnkuJG9yLmZvckVhY2godmFsaWRhdGVRdWVyeSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnQmFkICRvciBmb3JtYXQgLSB1c2UgYW4gYXJyYXkgdmFsdWUuJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHF1ZXJ5LiRhbmQpIHtcbiAgICBpZiAocXVlcnkuJGFuZCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICBxdWVyeS4kYW5kLmZvckVhY2godmFsaWRhdGVRdWVyeSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnQmFkICRhbmQgZm9ybWF0IC0gdXNlIGFuIGFycmF5IHZhbHVlLicpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChxdWVyeS4kbm9yKSB7XG4gICAgaWYgKHF1ZXJ5LiRub3IgaW5zdGFuY2VvZiBBcnJheSAmJiBxdWVyeS4kbm9yLmxlbmd0aCA+IDApIHtcbiAgICAgIHF1ZXJ5LiRub3IuZm9yRWFjaCh2YWxpZGF0ZVF1ZXJ5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAnQmFkICRub3IgZm9ybWF0IC0gdXNlIGFuIGFycmF5IG9mIGF0IGxlYXN0IDEgdmFsdWUuJ1xuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBPYmplY3Qua2V5cyhxdWVyeSkuZm9yRWFjaChrZXkgPT4ge1xuICAgIGlmIChxdWVyeSAmJiBxdWVyeVtrZXldICYmIHF1ZXJ5W2tleV0uJHJlZ2V4KSB7XG4gICAgICBpZiAodHlwZW9mIHF1ZXJ5W2tleV0uJG9wdGlvbnMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGlmICghcXVlcnlba2V5XS4kb3B0aW9ucy5tYXRjaCgvXltpbXhzXSskLykpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAgICAgYEJhZCAkb3B0aW9ucyB2YWx1ZSBmb3IgcXVlcnk6ICR7cXVlcnlba2V5XS4kb3B0aW9uc31gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWlzU3BlY2lhbFF1ZXJ5S2V5KGtleSkgJiYgIWtleS5tYXRjaCgvXlthLXpBLVpdW2EtekEtWjAtOV9cXC5dKiQvKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUsIGBJbnZhbGlkIGtleSBuYW1lOiAke2tleX1gKTtcbiAgICB9XG4gIH0pO1xufTtcblxuLy8gRmlsdGVycyBvdXQgYW55IGRhdGEgdGhhdCBzaG91bGRuJ3QgYmUgb24gdGhpcyBSRVNULWZvcm1hdHRlZCBvYmplY3QuXG5jb25zdCBmaWx0ZXJTZW5zaXRpdmVEYXRhID0gKFxuICBpc01hc3RlcjogYm9vbGVhbixcbiAgYWNsR3JvdXA6IGFueVtdLFxuICBhdXRoOiBhbnksXG4gIG9wZXJhdGlvbjogYW55LFxuICBzY2hlbWE6IFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlcixcbiAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gIHByb3RlY3RlZEZpZWxkczogbnVsbCB8IEFycmF5PGFueT4sXG4gIG9iamVjdDogYW55XG4pID0+IHtcbiAgbGV0IHVzZXJJZCA9IG51bGw7XG4gIGlmIChhdXRoICYmIGF1dGgudXNlcikgdXNlcklkID0gYXV0aC51c2VyLmlkO1xuXG4gIC8vIHJlcGxhY2UgcHJvdGVjdGVkRmllbGRzIHdoZW4gdXNpbmcgcG9pbnRlci1wZXJtaXNzaW9uc1xuICBjb25zdCBwZXJtcyA9IHNjaGVtYS5nZXRDbGFzc0xldmVsUGVybWlzc2lvbnMoY2xhc3NOYW1lKTtcbiAgaWYgKHBlcm1zKSB7XG4gICAgY29uc3QgaXNSZWFkT3BlcmF0aW9uID0gWydnZXQnLCAnZmluZCddLmluZGV4T2Yob3BlcmF0aW9uKSA+IC0xO1xuXG4gICAgaWYgKGlzUmVhZE9wZXJhdGlvbiAmJiBwZXJtcy5wcm90ZWN0ZWRGaWVsZHMpIHtcbiAgICAgIC8vIGV4dHJhY3QgcHJvdGVjdGVkRmllbGRzIGFkZGVkIHdpdGggdGhlIHBvaW50ZXItcGVybWlzc2lvbiBwcmVmaXhcbiAgICAgIGNvbnN0IHByb3RlY3RlZEZpZWxkc1BvaW50ZXJQZXJtID0gT2JqZWN0LmtleXMocGVybXMucHJvdGVjdGVkRmllbGRzKVxuICAgICAgICAuZmlsdGVyKGtleSA9PiBrZXkuc3RhcnRzV2l0aCgndXNlckZpZWxkOicpKVxuICAgICAgICAubWFwKGtleSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHsga2V5OiBrZXkuc3Vic3RyaW5nKDEwKSwgdmFsdWU6IHBlcm1zLnByb3RlY3RlZEZpZWxkc1trZXldIH07XG4gICAgICAgIH0pO1xuXG4gICAgICBjb25zdCBuZXdQcm90ZWN0ZWRGaWVsZHM6IEFycmF5PHN0cmluZz5bXSA9IFtdO1xuICAgICAgbGV0IG92ZXJyaWRlUHJvdGVjdGVkRmllbGRzID0gZmFsc2U7XG5cbiAgICAgIC8vIGNoZWNrIGlmIHRoZSBvYmplY3QgZ3JhbnRzIHRoZSBjdXJyZW50IHVzZXIgYWNjZXNzIGJhc2VkIG9uIHRoZSBleHRyYWN0ZWQgZmllbGRzXG4gICAgICBwcm90ZWN0ZWRGaWVsZHNQb2ludGVyUGVybS5mb3JFYWNoKHBvaW50ZXJQZXJtID0+IHtcbiAgICAgICAgbGV0IHBvaW50ZXJQZXJtSW5jbHVkZXNVc2VyID0gZmFsc2U7XG4gICAgICAgIGNvbnN0IHJlYWRVc2VyRmllbGRWYWx1ZSA9IG9iamVjdFtwb2ludGVyUGVybS5rZXldO1xuICAgICAgICBpZiAocmVhZFVzZXJGaWVsZFZhbHVlKSB7XG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmVhZFVzZXJGaWVsZFZhbHVlKSkge1xuICAgICAgICAgICAgcG9pbnRlclBlcm1JbmNsdWRlc1VzZXIgPSByZWFkVXNlckZpZWxkVmFsdWUuc29tZShcbiAgICAgICAgICAgICAgdXNlciA9PiB1c2VyLm9iamVjdElkICYmIHVzZXIub2JqZWN0SWQgPT09IHVzZXJJZFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcG9pbnRlclBlcm1JbmNsdWRlc1VzZXIgPVxuICAgICAgICAgICAgICByZWFkVXNlckZpZWxkVmFsdWUub2JqZWN0SWQgJiYgcmVhZFVzZXJGaWVsZFZhbHVlLm9iamVjdElkID09PSB1c2VySWQ7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBvaW50ZXJQZXJtSW5jbHVkZXNVc2VyKSB7XG4gICAgICAgICAgb3ZlcnJpZGVQcm90ZWN0ZWRGaWVsZHMgPSB0cnVlO1xuICAgICAgICAgIG5ld1Byb3RlY3RlZEZpZWxkcy5wdXNoKHBvaW50ZXJQZXJtLnZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8vIGlmIGF0IGxlYXN0IG9uZSBwb2ludGVyLXBlcm1pc3Npb24gYWZmZWN0ZWQgdGhlIGN1cnJlbnQgdXNlclxuICAgICAgLy8gaW50ZXJzZWN0IHZzIHByb3RlY3RlZEZpZWxkcyBmcm9tIHByZXZpb3VzIHN0YWdlIChAc2VlIGFkZFByb3RlY3RlZEZpZWxkcylcbiAgICAgIC8vIFNldHMgdGhlb3J5IChpbnRlcnNlY3Rpb25zKTogQSB4IChCIHggQykgPT0gKEEgeCBCKSB4IENcbiAgICAgIGlmIChvdmVycmlkZVByb3RlY3RlZEZpZWxkcyAmJiBwcm90ZWN0ZWRGaWVsZHMpIHtcbiAgICAgICAgbmV3UHJvdGVjdGVkRmllbGRzLnB1c2gocHJvdGVjdGVkRmllbGRzKTtcbiAgICAgIH1cbiAgICAgIC8vIGludGVyc2VjdCBhbGwgc2V0cyBvZiBwcm90ZWN0ZWRGaWVsZHNcbiAgICAgIG5ld1Byb3RlY3RlZEZpZWxkcy5mb3JFYWNoKGZpZWxkcyA9PiB7XG4gICAgICAgIGlmIChmaWVsZHMpIHtcbiAgICAgICAgICAvLyBpZiB0aGVyZSdyZSBubyBwcm90Y3RlZEZpZWxkcyBieSBvdGhlciBjcml0ZXJpYSAoIGlkIC8gcm9sZSAvIGF1dGgpXG4gICAgICAgICAgLy8gdGhlbiB3ZSBtdXN0IGludGVyc2VjdCBlYWNoIHNldCAocGVyIHVzZXJGaWVsZClcbiAgICAgICAgICBpZiAoIXByb3RlY3RlZEZpZWxkcykge1xuICAgICAgICAgICAgcHJvdGVjdGVkRmllbGRzID0gZmllbGRzO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm90ZWN0ZWRGaWVsZHMgPSBwcm90ZWN0ZWRGaWVsZHMuZmlsdGVyKHYgPT4gZmllbGRzLmluY2x1ZGVzKHYpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGlzVXNlckNsYXNzID0gY2xhc3NOYW1lID09PSAnX1VzZXInO1xuXG4gIC8qIHNwZWNpYWwgdHJlYXQgZm9yIHRoZSB1c2VyIGNsYXNzOiBkb24ndCBmaWx0ZXIgcHJvdGVjdGVkRmllbGRzIGlmIGN1cnJlbnRseSBsb2dnZWRpbiB1c2VyIGlzXG4gIHRoZSByZXRyaWV2ZWQgdXNlciAqL1xuICBpZiAoIShpc1VzZXJDbGFzcyAmJiB1c2VySWQgJiYgb2JqZWN0Lm9iamVjdElkID09PSB1c2VySWQpKSB7XG4gICAgcHJvdGVjdGVkRmllbGRzICYmIHByb3RlY3RlZEZpZWxkcy5mb3JFYWNoKGsgPT4gZGVsZXRlIG9iamVjdFtrXSk7XG5cbiAgICAvLyBmaWVsZHMgbm90IHJlcXVlc3RlZCBieSBjbGllbnQgKGV4Y2x1ZGVkKSxcbiAgICAvL2J1dCB3ZXJlIG5lZWRlZCB0byBhcHBseSBwcm90ZWN0dGVkRmllbGRzXG4gICAgcGVybXMucHJvdGVjdGVkRmllbGRzICYmXG4gICAgICBwZXJtcy5wcm90ZWN0ZWRGaWVsZHMudGVtcG9yYXJ5S2V5cyAmJlxuICAgICAgcGVybXMucHJvdGVjdGVkRmllbGRzLnRlbXBvcmFyeUtleXMuZm9yRWFjaChrID0+IGRlbGV0ZSBvYmplY3Rba10pO1xuICB9XG5cbiAgaWYgKCFpc1VzZXJDbGFzcykge1xuICAgIHJldHVybiBvYmplY3Q7XG4gIH1cblxuICBvYmplY3QucGFzc3dvcmQgPSBvYmplY3QuX2hhc2hlZF9wYXNzd29yZDtcbiAgZGVsZXRlIG9iamVjdC5faGFzaGVkX3Bhc3N3b3JkO1xuXG4gIGRlbGV0ZSBvYmplY3Quc2Vzc2lvblRva2VuO1xuXG4gIGlmIChpc01hc3Rlcikge1xuICAgIHJldHVybiBvYmplY3Q7XG4gIH1cbiAgZGVsZXRlIG9iamVjdC5fZW1haWxfdmVyaWZ5X3Rva2VuO1xuICBkZWxldGUgb2JqZWN0Ll9wZXJpc2hhYmxlX3Rva2VuO1xuICBkZWxldGUgb2JqZWN0Ll9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQ7XG4gIGRlbGV0ZSBvYmplY3QuX3RvbWJzdG9uZTtcbiAgZGVsZXRlIG9iamVjdC5fZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQ7XG4gIGRlbGV0ZSBvYmplY3QuX2ZhaWxlZF9sb2dpbl9jb3VudDtcbiAgZGVsZXRlIG9iamVjdC5fYWNjb3VudF9sb2Nrb3V0X2V4cGlyZXNfYXQ7XG4gIGRlbGV0ZSBvYmplY3QuX3Bhc3N3b3JkX2NoYW5nZWRfYXQ7XG4gIGRlbGV0ZSBvYmplY3QuX3Bhc3N3b3JkX2hpc3Rvcnk7XG5cbiAgaWYgKGFjbEdyb3VwLmluZGV4T2Yob2JqZWN0Lm9iamVjdElkKSA+IC0xKSB7XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfVxuICBkZWxldGUgb2JqZWN0LmF1dGhEYXRhO1xuICByZXR1cm4gb2JqZWN0O1xufTtcblxuaW1wb3J0IHR5cGUgeyBMb2FkU2NoZW1hT3B0aW9ucyB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IE1vbmdvU3RvcmFnZUFkYXB0ZXIgZnJvbSAnLi4vQWRhcHRlcnMvU3RvcmFnZS9Nb25nby9Nb25nb1N0b3JhZ2VBZGFwdGVyJztcblxuLy8gUnVucyBhbiB1cGRhdGUgb24gdGhlIGRhdGFiYXNlLlxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGFuIG9iamVjdCB3aXRoIHRoZSBuZXcgdmFsdWVzIGZvciBmaWVsZFxuLy8gbW9kaWZpY2F0aW9ucyB0aGF0IGRvbid0IGtub3cgdGhlaXIgcmVzdWx0cyBhaGVhZCBvZiB0aW1lLCBsaWtlXG4vLyAnaW5jcmVtZW50Jy5cbi8vIE9wdGlvbnM6XG4vLyAgIGFjbDogIGEgbGlzdCBvZiBzdHJpbmdzLiBJZiB0aGUgb2JqZWN0IHRvIGJlIHVwZGF0ZWQgaGFzIGFuIEFDTCxcbi8vICAgICAgICAgb25lIG9mIHRoZSBwcm92aWRlZCBzdHJpbmdzIG11c3QgcHJvdmlkZSB0aGUgY2FsbGVyIHdpdGhcbi8vICAgICAgICAgd3JpdGUgcGVybWlzc2lvbnMuXG5jb25zdCBzcGVjaWFsS2V5c0ZvclVwZGF0ZSA9IFtcbiAgJ19oYXNoZWRfcGFzc3dvcmQnLFxuICAnX3BlcmlzaGFibGVfdG9rZW4nLFxuICAnX2VtYWlsX3ZlcmlmeV90b2tlbicsXG4gICdfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQnLFxuICAnX2FjY291bnRfbG9ja291dF9leHBpcmVzX2F0JyxcbiAgJ19mYWlsZWRfbG9naW5fY291bnQnLFxuICAnX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdCcsXG4gICdfcGFzc3dvcmRfY2hhbmdlZF9hdCcsXG4gICdfcGFzc3dvcmRfaGlzdG9yeScsXG5dO1xuXG5jb25zdCBpc1NwZWNpYWxVcGRhdGVLZXkgPSBrZXkgPT4ge1xuICByZXR1cm4gc3BlY2lhbEtleXNGb3JVcGRhdGUuaW5kZXhPZihrZXkpID49IDA7XG59O1xuXG5mdW5jdGlvbiBleHBhbmRSZXN1bHRPbktleVBhdGgob2JqZWN0LCBrZXksIHZhbHVlKSB7XG4gIGlmIChrZXkuaW5kZXhPZignLicpIDwgMCkge1xuICAgIG9iamVjdFtrZXldID0gdmFsdWVba2V5XTtcbiAgICByZXR1cm4gb2JqZWN0O1xuICB9XG4gIGNvbnN0IHBhdGggPSBrZXkuc3BsaXQoJy4nKTtcbiAgY29uc3QgZmlyc3RLZXkgPSBwYXRoWzBdO1xuICBjb25zdCBuZXh0UGF0aCA9IHBhdGguc2xpY2UoMSkuam9pbignLicpO1xuICBvYmplY3RbZmlyc3RLZXldID0gZXhwYW5kUmVzdWx0T25LZXlQYXRoKG9iamVjdFtmaXJzdEtleV0gfHwge30sIG5leHRQYXRoLCB2YWx1ZVtmaXJzdEtleV0pO1xuICBkZWxldGUgb2JqZWN0W2tleV07XG4gIHJldHVybiBvYmplY3Q7XG59XG5cbmZ1bmN0aW9uIHNhbml0aXplRGF0YWJhc2VSZXN1bHQob3JpZ2luYWxPYmplY3QsIHJlc3VsdCk6IFByb21pc2U8YW55PiB7XG4gIGNvbnN0IHJlc3BvbnNlID0ge307XG4gIGlmICghcmVzdWx0KSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXNwb25zZSk7XG4gIH1cbiAgT2JqZWN0LmtleXMob3JpZ2luYWxPYmplY3QpLmZvckVhY2goa2V5ID0+IHtcbiAgICBjb25zdCBrZXlVcGRhdGUgPSBvcmlnaW5hbE9iamVjdFtrZXldO1xuICAgIC8vIGRldGVybWluZSBpZiB0aGF0IHdhcyBhbiBvcFxuICAgIGlmIChcbiAgICAgIGtleVVwZGF0ZSAmJlxuICAgICAgdHlwZW9mIGtleVVwZGF0ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgIGtleVVwZGF0ZS5fX29wICYmXG4gICAgICBbJ0FkZCcsICdBZGRVbmlxdWUnLCAnUmVtb3ZlJywgJ0luY3JlbWVudCddLmluZGV4T2Yoa2V5VXBkYXRlLl9fb3ApID4gLTFcbiAgICApIHtcbiAgICAgIC8vIG9ubHkgdmFsaWQgb3BzIHRoYXQgcHJvZHVjZSBhbiBhY3Rpb25hYmxlIHJlc3VsdFxuICAgICAgLy8gdGhlIG9wIG1heSBoYXZlIGhhcHBlbmQgb24gYSBrZXlwYXRoXG4gICAgICBleHBhbmRSZXN1bHRPbktleVBhdGgocmVzcG9uc2UsIGtleSwgcmVzdWx0KTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3BvbnNlKTtcbn1cblxuZnVuY3Rpb24gam9pblRhYmxlTmFtZShjbGFzc05hbWUsIGtleSkge1xuICByZXR1cm4gYF9Kb2luOiR7a2V5fToke2NsYXNzTmFtZX1gO1xufVxuXG5jb25zdCBmbGF0dGVuVXBkYXRlT3BlcmF0b3JzRm9yQ3JlYXRlID0gb2JqZWN0ID0+IHtcbiAgZm9yIChjb25zdCBrZXkgaW4gb2JqZWN0KSB7XG4gICAgaWYgKG9iamVjdFtrZXldICYmIG9iamVjdFtrZXldLl9fb3ApIHtcbiAgICAgIHN3aXRjaCAob2JqZWN0W2tleV0uX19vcCkge1xuICAgICAgICBjYXNlICdJbmNyZW1lbnQnOlxuICAgICAgICAgIGlmICh0eXBlb2Ygb2JqZWN0W2tleV0uYW1vdW50ICE9PSAnbnVtYmVyJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ29iamVjdHMgdG8gYWRkIG11c3QgYmUgYW4gYXJyYXknKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgb2JqZWN0W2tleV0gPSBvYmplY3Rba2V5XS5hbW91bnQ7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0FkZCc6XG4gICAgICAgICAgaWYgKCEob2JqZWN0W2tleV0ub2JqZWN0cyBpbnN0YW5jZW9mIEFycmF5KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ29iamVjdHMgdG8gYWRkIG11c3QgYmUgYW4gYXJyYXknKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgb2JqZWN0W2tleV0gPSBvYmplY3Rba2V5XS5vYmplY3RzO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdBZGRVbmlxdWUnOlxuICAgICAgICAgIGlmICghKG9iamVjdFtrZXldLm9iamVjdHMgaW5zdGFuY2VvZiBBcnJheSkpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sICdvYmplY3RzIHRvIGFkZCBtdXN0IGJlIGFuIGFycmF5Jyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIG9iamVjdFtrZXldID0gb2JqZWN0W2tleV0ub2JqZWN0cztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnUmVtb3ZlJzpcbiAgICAgICAgICBpZiAoIShvYmplY3Rba2V5XS5vYmplY3RzIGluc3RhbmNlb2YgQXJyYXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnb2JqZWN0cyB0byBhZGQgbXVzdCBiZSBhbiBhcnJheScpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBvYmplY3Rba2V5XSA9IFtdO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdEZWxldGUnOlxuICAgICAgICAgIGRlbGV0ZSBvYmplY3Rba2V5XTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5DT01NQU5EX1VOQVZBSUxBQkxFLFxuICAgICAgICAgICAgYFRoZSAke29iamVjdFtrZXldLl9fb3B9IG9wZXJhdG9yIGlzIG5vdCBzdXBwb3J0ZWQgeWV0LmBcbiAgICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcblxuY29uc3QgdHJhbnNmb3JtQXV0aERhdGEgPSAoY2xhc3NOYW1lLCBvYmplY3QsIHNjaGVtYSkgPT4ge1xuICBpZiAob2JqZWN0LmF1dGhEYXRhICYmIGNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIE9iamVjdC5rZXlzKG9iamVjdC5hdXRoRGF0YSkuZm9yRWFjaChwcm92aWRlciA9PiB7XG4gICAgICBjb25zdCBwcm92aWRlckRhdGEgPSBvYmplY3QuYXV0aERhdGFbcHJvdmlkZXJdO1xuICAgICAgY29uc3QgZmllbGROYW1lID0gYF9hdXRoX2RhdGFfJHtwcm92aWRlcn1gO1xuICAgICAgaWYgKHByb3ZpZGVyRGF0YSA9PSBudWxsKSB7XG4gICAgICAgIG9iamVjdFtmaWVsZE5hbWVdID0ge1xuICAgICAgICAgIF9fb3A6ICdEZWxldGUnLFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb2JqZWN0W2ZpZWxkTmFtZV0gPSBwcm92aWRlckRhdGE7XG4gICAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSA9IHsgdHlwZTogJ09iamVjdCcgfTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBkZWxldGUgb2JqZWN0LmF1dGhEYXRhO1xuICB9XG59O1xuLy8gVHJhbnNmb3JtcyBhIERhdGFiYXNlIGZvcm1hdCBBQ0wgdG8gYSBSRVNUIEFQSSBmb3JtYXQgQUNMXG5jb25zdCB1bnRyYW5zZm9ybU9iamVjdEFDTCA9ICh7IF9ycGVybSwgX3dwZXJtLCAuLi5vdXRwdXQgfSkgPT4ge1xuICBpZiAoX3JwZXJtIHx8IF93cGVybSkge1xuICAgIG91dHB1dC5BQ0wgPSB7fTtcblxuICAgIChfcnBlcm0gfHwgW10pLmZvckVhY2goZW50cnkgPT4ge1xuICAgICAgaWYgKCFvdXRwdXQuQUNMW2VudHJ5XSkge1xuICAgICAgICBvdXRwdXQuQUNMW2VudHJ5XSA9IHsgcmVhZDogdHJ1ZSB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0cHV0LkFDTFtlbnRyeV1bJ3JlYWQnXSA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAoX3dwZXJtIHx8IFtdKS5mb3JFYWNoKGVudHJ5ID0+IHtcbiAgICAgIGlmICghb3V0cHV0LkFDTFtlbnRyeV0pIHtcbiAgICAgICAgb3V0cHV0LkFDTFtlbnRyeV0gPSB7IHdyaXRlOiB0cnVlIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvdXRwdXQuQUNMW2VudHJ5XVsnd3JpdGUnXSA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIG91dHB1dDtcbn07XG5cbi8qKlxuICogV2hlbiBxdWVyeWluZywgdGhlIGZpZWxkTmFtZSBtYXkgYmUgY29tcG91bmQsIGV4dHJhY3QgdGhlIHJvb3QgZmllbGROYW1lXG4gKiAgICAgYHRlbXBlcmF0dXJlLmNlbHNpdXNgIGJlY29tZXMgYHRlbXBlcmF0dXJlYFxuICogQHBhcmFtIHtzdHJpbmd9IGZpZWxkTmFtZSB0aGF0IG1heSBiZSBhIGNvbXBvdW5kIGZpZWxkIG5hbWVcbiAqIEByZXR1cm5zIHtzdHJpbmd9IHRoZSByb290IG5hbWUgb2YgdGhlIGZpZWxkXG4gKi9cbmNvbnN0IGdldFJvb3RGaWVsZE5hbWUgPSAoZmllbGROYW1lOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICByZXR1cm4gZmllbGROYW1lLnNwbGl0KCcuJylbMF07XG59O1xuXG5jb25zdCByZWxhdGlvblNjaGVtYSA9IHtcbiAgZmllbGRzOiB7IHJlbGF0ZWRJZDogeyB0eXBlOiAnU3RyaW5nJyB9LCBvd25pbmdJZDogeyB0eXBlOiAnU3RyaW5nJyB9IH0sXG59O1xuXG5jbGFzcyBEYXRhYmFzZUNvbnRyb2xsZXIge1xuICBhZGFwdGVyOiBTdG9yYWdlQWRhcHRlcjtcbiAgc2NoZW1hQ2FjaGU6IGFueTtcbiAgc2NoZW1hUHJvbWlzZTogP1Byb21pc2U8U2NoZW1hQ29udHJvbGxlci5TY2hlbWFDb250cm9sbGVyPjtcbiAgX3RyYW5zYWN0aW9uYWxTZXNzaW9uOiA/YW55O1xuXG4gIGNvbnN0cnVjdG9yKGFkYXB0ZXI6IFN0b3JhZ2VBZGFwdGVyLCBzY2hlbWFDYWNoZTogYW55KSB7XG4gICAgdGhpcy5hZGFwdGVyID0gYWRhcHRlcjtcbiAgICB0aGlzLnNjaGVtYUNhY2hlID0gc2NoZW1hQ2FjaGU7XG4gICAgLy8gV2UgZG9uJ3Qgd2FudCBhIG11dGFibGUgdGhpcy5zY2hlbWEsIGJlY2F1c2UgdGhlbiB5b3UgY291bGQgaGF2ZVxuICAgIC8vIG9uZSByZXF1ZXN0IHRoYXQgdXNlcyBkaWZmZXJlbnQgc2NoZW1hcyBmb3IgZGlmZmVyZW50IHBhcnRzIG9mXG4gICAgLy8gaXQuIEluc3RlYWQsIHVzZSBsb2FkU2NoZW1hIHRvIGdldCBhIHNjaGVtYS5cbiAgICB0aGlzLnNjaGVtYVByb21pc2UgPSBudWxsO1xuICAgIHRoaXMuX3RyYW5zYWN0aW9uYWxTZXNzaW9uID0gbnVsbDtcbiAgfVxuXG4gIGNvbGxlY3Rpb25FeGlzdHMoY2xhc3NOYW1lOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmNsYXNzRXhpc3RzKGNsYXNzTmFtZSk7XG4gIH1cblxuICBwdXJnZUNvbGxlY3Rpb24oY2xhc3NOYW1lOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5sb2FkU2NoZW1hKClcbiAgICAgIC50aGVuKHNjaGVtYUNvbnRyb2xsZXIgPT4gc2NoZW1hQ29udHJvbGxlci5nZXRPbmVTY2hlbWEoY2xhc3NOYW1lKSlcbiAgICAgIC50aGVuKHNjaGVtYSA9PiB0aGlzLmFkYXB0ZXIuZGVsZXRlT2JqZWN0c0J5UXVlcnkoY2xhc3NOYW1lLCBzY2hlbWEsIHt9KSk7XG4gIH1cblxuICB2YWxpZGF0ZUNsYXNzTmFtZShjbGFzc05hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghU2NoZW1hQ29udHJvbGxlci5jbGFzc05hbWVJc1ZhbGlkKGNsYXNzTmFtZSkpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChcbiAgICAgICAgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSwgJ2ludmFsaWQgY2xhc3NOYW1lOiAnICsgY2xhc3NOYW1lKVxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGEgc2NoZW1hQ29udHJvbGxlci5cbiAgbG9hZFNjaGVtYShcbiAgICBvcHRpb25zOiBMb2FkU2NoZW1hT3B0aW9ucyA9IHsgY2xlYXJDYWNoZTogZmFsc2UgfVxuICApOiBQcm9taXNlPFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlcj4ge1xuICAgIGlmICh0aGlzLnNjaGVtYVByb21pc2UgIT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2NoZW1hUHJvbWlzZTtcbiAgICB9XG4gICAgdGhpcy5zY2hlbWFQcm9taXNlID0gU2NoZW1hQ29udHJvbGxlci5sb2FkKHRoaXMuYWRhcHRlciwgdGhpcy5zY2hlbWFDYWNoZSwgb3B0aW9ucyk7XG4gICAgdGhpcy5zY2hlbWFQcm9taXNlLnRoZW4oXG4gICAgICAoKSA9PiBkZWxldGUgdGhpcy5zY2hlbWFQcm9taXNlLFxuICAgICAgKCkgPT4gZGVsZXRlIHRoaXMuc2NoZW1hUHJvbWlzZVxuICAgICk7XG4gICAgcmV0dXJuIHRoaXMubG9hZFNjaGVtYShvcHRpb25zKTtcbiAgfVxuXG4gIGxvYWRTY2hlbWFJZk5lZWRlZChcbiAgICBzY2hlbWFDb250cm9sbGVyOiBTY2hlbWFDb250cm9sbGVyLlNjaGVtYUNvbnRyb2xsZXIsXG4gICAgb3B0aW9uczogTG9hZFNjaGVtYU9wdGlvbnMgPSB7IGNsZWFyQ2FjaGU6IGZhbHNlIH1cbiAgKTogUHJvbWlzZTxTY2hlbWFDb250cm9sbGVyLlNjaGVtYUNvbnRyb2xsZXI+IHtcbiAgICByZXR1cm4gc2NoZW1hQ29udHJvbGxlciA/IFByb21pc2UucmVzb2x2ZShzY2hlbWFDb250cm9sbGVyKSA6IHRoaXMubG9hZFNjaGVtYShvcHRpb25zKTtcbiAgfVxuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIGZvciB0aGUgY2xhc3NuYW1lIHRoYXQgaXMgcmVsYXRlZCB0byB0aGUgZ2l2ZW5cbiAgLy8gY2xhc3NuYW1lIHRocm91Z2ggdGhlIGtleS5cbiAgLy8gVE9ETzogbWFrZSB0aGlzIG5vdCBpbiB0aGUgRGF0YWJhc2VDb250cm9sbGVyIGludGVyZmFjZVxuICByZWRpcmVjdENsYXNzTmFtZUZvcktleShjbGFzc05hbWU6IHN0cmluZywga2V5OiBzdHJpbmcpOiBQcm9taXNlPD9zdHJpbmc+IHtcbiAgICByZXR1cm4gdGhpcy5sb2FkU2NoZW1hKCkudGhlbihzY2hlbWEgPT4ge1xuICAgICAgdmFyIHQgPSBzY2hlbWEuZ2V0RXhwZWN0ZWRUeXBlKGNsYXNzTmFtZSwga2V5KTtcbiAgICAgIGlmICh0ICE9IG51bGwgJiYgdHlwZW9mIHQgIT09ICdzdHJpbmcnICYmIHQudHlwZSA9PT0gJ1JlbGF0aW9uJykge1xuICAgICAgICByZXR1cm4gdC50YXJnZXRDbGFzcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBjbGFzc05hbWU7XG4gICAgfSk7XG4gIH1cblxuICAvLyBVc2VzIHRoZSBzY2hlbWEgdG8gdmFsaWRhdGUgdGhlIG9iamVjdCAoUkVTVCBBUEkgZm9ybWF0KS5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgbmV3IHNjaGVtYS5cbiAgLy8gVGhpcyBkb2VzIG5vdCB1cGRhdGUgdGhpcy5zY2hlbWEsIGJlY2F1c2UgaW4gYSBzaXR1YXRpb24gbGlrZSBhXG4gIC8vIGJhdGNoIHJlcXVlc3QsIHRoYXQgY291bGQgY29uZnVzZSBvdGhlciB1c2VycyBvZiB0aGUgc2NoZW1hLlxuICB2YWxpZGF0ZU9iamVjdChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBvYmplY3Q6IGFueSxcbiAgICBxdWVyeTogYW55LFxuICAgIHJ1bk9wdGlvbnM6IFF1ZXJ5T3B0aW9uc1xuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBsZXQgc2NoZW1hO1xuICAgIGNvbnN0IGFjbCA9IHJ1bk9wdGlvbnMuYWNsO1xuICAgIGNvbnN0IGlzTWFzdGVyID0gYWNsID09PSB1bmRlZmluZWQ7XG4gICAgdmFyIGFjbEdyb3VwOiBzdHJpbmdbXSA9IGFjbCB8fCBbXTtcbiAgICByZXR1cm4gdGhpcy5sb2FkU2NoZW1hKClcbiAgICAgIC50aGVuKHMgPT4ge1xuICAgICAgICBzY2hlbWEgPSBzO1xuICAgICAgICBpZiAoaXNNYXN0ZXIpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuY2FuQWRkRmllbGQoc2NoZW1hLCBjbGFzc05hbWUsIG9iamVjdCwgYWNsR3JvdXAsIHJ1bk9wdGlvbnMpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHNjaGVtYS52YWxpZGF0ZU9iamVjdChjbGFzc05hbWUsIG9iamVjdCwgcXVlcnkpO1xuICAgICAgfSk7XG4gIH1cblxuICB1cGRhdGUoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgcXVlcnk6IGFueSxcbiAgICB1cGRhdGU6IGFueSxcbiAgICB7IGFjbCwgbWFueSwgdXBzZXJ0LCBhZGRzRmllbGQgfTogRnVsbFF1ZXJ5T3B0aW9ucyA9IHt9LFxuICAgIHNraXBTYW5pdGl6YXRpb246IGJvb2xlYW4gPSBmYWxzZSxcbiAgICB2YWxpZGF0ZU9ubHk6IGJvb2xlYW4gPSBmYWxzZSxcbiAgICB2YWxpZFNjaGVtYUNvbnRyb2xsZXI6IFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlclxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IG9yaWdpbmFsUXVlcnkgPSBxdWVyeTtcbiAgICBjb25zdCBvcmlnaW5hbFVwZGF0ZSA9IHVwZGF0ZTtcbiAgICAvLyBNYWtlIGEgY29weSBvZiB0aGUgb2JqZWN0LCBzbyB3ZSBkb24ndCBtdXRhdGUgdGhlIGluY29taW5nIGRhdGEuXG4gICAgdXBkYXRlID0gZGVlcGNvcHkodXBkYXRlKTtcbiAgICB2YXIgcmVsYXRpb25VcGRhdGVzID0gW107XG4gICAgdmFyIGlzTWFzdGVyID0gYWNsID09PSB1bmRlZmluZWQ7XG4gICAgdmFyIGFjbEdyb3VwID0gYWNsIHx8IFtdO1xuXG4gICAgcmV0dXJuIHRoaXMubG9hZFNjaGVtYUlmTmVlZGVkKHZhbGlkU2NoZW1hQ29udHJvbGxlcikudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHtcbiAgICAgIHJldHVybiAoaXNNYXN0ZXJcbiAgICAgICAgPyBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICA6IHNjaGVtYUNvbnRyb2xsZXIudmFsaWRhdGVQZXJtaXNzaW9uKGNsYXNzTmFtZSwgYWNsR3JvdXAsICd1cGRhdGUnKVxuICAgICAgKVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgcmVsYXRpb25VcGRhdGVzID0gdGhpcy5jb2xsZWN0UmVsYXRpb25VcGRhdGVzKGNsYXNzTmFtZSwgb3JpZ2luYWxRdWVyeS5vYmplY3RJZCwgdXBkYXRlKTtcbiAgICAgICAgICBpZiAoIWlzTWFzdGVyKSB7XG4gICAgICAgICAgICBxdWVyeSA9IHRoaXMuYWRkUG9pbnRlclBlcm1pc3Npb25zKFxuICAgICAgICAgICAgICBzY2hlbWFDb250cm9sbGVyLFxuICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgICd1cGRhdGUnLFxuICAgICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgICAgYWNsR3JvdXBcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGlmIChhZGRzRmllbGQpIHtcbiAgICAgICAgICAgICAgcXVlcnkgPSB7XG4gICAgICAgICAgICAgICAgJGFuZDogW1xuICAgICAgICAgICAgICAgICAgcXVlcnksXG4gICAgICAgICAgICAgICAgICB0aGlzLmFkZFBvaW50ZXJQZXJtaXNzaW9ucyhcbiAgICAgICAgICAgICAgICAgICAgc2NoZW1hQ29udHJvbGxlcixcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgICAnYWRkRmllbGQnLFxuICAgICAgICAgICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgICAgICAgICAgYWNsR3JvdXBcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFxdWVyeSkge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoYWNsKSB7XG4gICAgICAgICAgICBxdWVyeSA9IGFkZFdyaXRlQUNMKHF1ZXJ5LCBhY2wpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB2YWxpZGF0ZVF1ZXJ5KHF1ZXJ5KTtcbiAgICAgICAgICByZXR1cm4gc2NoZW1hQ29udHJvbGxlclxuICAgICAgICAgICAgLmdldE9uZVNjaGVtYShjbGFzc05hbWUsIHRydWUpXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAvLyBJZiB0aGUgc2NoZW1hIGRvZXNuJ3QgZXhpc3QsIHByZXRlbmQgaXQgZXhpc3RzIHdpdGggbm8gZmllbGRzLiBUaGlzIGJlaGF2aW9yXG4gICAgICAgICAgICAgIC8vIHdpbGwgbGlrZWx5IG5lZWQgcmV2aXNpdGluZy5cbiAgICAgICAgICAgICAgaWYgKGVycm9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBmaWVsZHM6IHt9IH07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLnRoZW4oc2NoZW1hID0+IHtcbiAgICAgICAgICAgICAgT2JqZWN0LmtleXModXBkYXRlKS5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGZpZWxkTmFtZS5tYXRjaCgvXmF1dGhEYXRhXFwuKFthLXpBLVowLTlfXSspXFwuaWQkLykpIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSxcbiAgICAgICAgICAgICAgICAgICAgYEludmFsaWQgZmllbGQgbmFtZSBmb3IgdXBkYXRlOiAke2ZpZWxkTmFtZX1gXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb25zdCByb290RmllbGROYW1lID0gZ2V0Um9vdEZpZWxkTmFtZShmaWVsZE5hbWUpO1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICFTY2hlbWFDb250cm9sbGVyLmZpZWxkTmFtZUlzVmFsaWQocm9vdEZpZWxkTmFtZSwgY2xhc3NOYW1lKSAmJlxuICAgICAgICAgICAgICAgICAgIWlzU3BlY2lhbFVwZGF0ZUtleShyb290RmllbGROYW1lKVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FLFxuICAgICAgICAgICAgICAgICAgICBgSW52YWxpZCBmaWVsZCBuYW1lIGZvciB1cGRhdGU6ICR7ZmllbGROYW1lfWBcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgZm9yIChjb25zdCB1cGRhdGVPcGVyYXRpb24gaW4gdXBkYXRlKSB7XG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgdXBkYXRlW3VwZGF0ZU9wZXJhdGlvbl0gJiZcbiAgICAgICAgICAgICAgICAgIHR5cGVvZiB1cGRhdGVbdXBkYXRlT3BlcmF0aW9uXSA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgICAgICAgICAgIE9iamVjdC5rZXlzKHVwZGF0ZVt1cGRhdGVPcGVyYXRpb25dKS5zb21lKFxuICAgICAgICAgICAgICAgICAgICBpbm5lcktleSA9PiBpbm5lcktleS5pbmNsdWRlcygnJCcpIHx8IGlubmVyS2V5LmluY2x1ZGVzKCcuJylcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9ORVNURURfS0VZLFxuICAgICAgICAgICAgICAgICAgICBcIk5lc3RlZCBrZXlzIHNob3VsZCBub3QgY29udGFpbiB0aGUgJyQnIG9yICcuJyBjaGFyYWN0ZXJzXCJcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHVwZGF0ZSA9IHRyYW5zZm9ybU9iamVjdEFDTCh1cGRhdGUpO1xuICAgICAgICAgICAgICB0cmFuc2Zvcm1BdXRoRGF0YShjbGFzc05hbWUsIHVwZGF0ZSwgc2NoZW1hKTtcbiAgICAgICAgICAgICAgaWYgKHZhbGlkYXRlT25seSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuZmluZChjbGFzc05hbWUsIHNjaGVtYSwgcXVlcnksIHt9KS50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgICAgICAgICBpZiAoIXJlc3VsdCB8fCAhcmVzdWx0Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ09iamVjdCBub3QgZm91bmQuJyk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKG1hbnkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnVwZGF0ZU9iamVjdHNCeVF1ZXJ5KFxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgICAgICAgICAgcXVlcnksXG4gICAgICAgICAgICAgICAgICB1cGRhdGUsXG4gICAgICAgICAgICAgICAgICB0aGlzLl90cmFuc2FjdGlvbmFsU2Vzc2lvblxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAodXBzZXJ0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci51cHNlcnRPbmVPYmplY3QoXG4gICAgICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgICBzY2hlbWEsXG4gICAgICAgICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgICAgICAgIHVwZGF0ZSxcbiAgICAgICAgICAgICAgICAgIHRoaXMuX3RyYW5zYWN0aW9uYWxTZXNzaW9uXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmZpbmRPbmVBbmRVcGRhdGUoXG4gICAgICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgICBzY2hlbWEsXG4gICAgICAgICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgICAgICAgIHVwZGF0ZSxcbiAgICAgICAgICAgICAgICAgIHRoaXMuX3RyYW5zYWN0aW9uYWxTZXNzaW9uXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKChyZXN1bHQ6IGFueSkgPT4ge1xuICAgICAgICAgIGlmICghcmVzdWx0KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ09iamVjdCBub3QgZm91bmQuJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICh2YWxpZGF0ZU9ubHkpIHtcbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZVJlbGF0aW9uVXBkYXRlcyhcbiAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgIG9yaWdpbmFsUXVlcnkub2JqZWN0SWQsXG4gICAgICAgICAgICB1cGRhdGUsXG4gICAgICAgICAgICByZWxhdGlvblVwZGF0ZXNcbiAgICAgICAgICApLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICBpZiAoc2tpcFNhbml0aXphdGlvbikge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gc2FuaXRpemVEYXRhYmFzZVJlc3VsdChvcmlnaW5hbFVwZGF0ZSwgcmVzdWx0KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBDb2xsZWN0IGFsbCByZWxhdGlvbi11cGRhdGluZyBvcGVyYXRpb25zIGZyb20gYSBSRVNULWZvcm1hdCB1cGRhdGUuXG4gIC8vIFJldHVybnMgYSBsaXN0IG9mIGFsbCByZWxhdGlvbiB1cGRhdGVzIHRvIHBlcmZvcm1cbiAgLy8gVGhpcyBtdXRhdGVzIHVwZGF0ZS5cbiAgY29sbGVjdFJlbGF0aW9uVXBkYXRlcyhjbGFzc05hbWU6IHN0cmluZywgb2JqZWN0SWQ6ID9zdHJpbmcsIHVwZGF0ZTogYW55KSB7XG4gICAgdmFyIG9wcyA9IFtdO1xuICAgIHZhciBkZWxldGVNZSA9IFtdO1xuICAgIG9iamVjdElkID0gdXBkYXRlLm9iamVjdElkIHx8IG9iamVjdElkO1xuXG4gICAgdmFyIHByb2Nlc3MgPSAob3AsIGtleSkgPT4ge1xuICAgICAgaWYgKCFvcCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAob3AuX19vcCA9PSAnQWRkUmVsYXRpb24nKSB7XG4gICAgICAgIG9wcy5wdXNoKHsga2V5LCBvcCB9KTtcbiAgICAgICAgZGVsZXRlTWUucHVzaChrZXkpO1xuICAgICAgfVxuXG4gICAgICBpZiAob3AuX19vcCA9PSAnUmVtb3ZlUmVsYXRpb24nKSB7XG4gICAgICAgIG9wcy5wdXNoKHsga2V5LCBvcCB9KTtcbiAgICAgICAgZGVsZXRlTWUucHVzaChrZXkpO1xuICAgICAgfVxuXG4gICAgICBpZiAob3AuX19vcCA9PSAnQmF0Y2gnKSB7XG4gICAgICAgIGZvciAodmFyIHggb2Ygb3Aub3BzKSB7XG4gICAgICAgICAgcHJvY2Vzcyh4LCBrZXkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIGZvciAoY29uc3Qga2V5IGluIHVwZGF0ZSkge1xuICAgICAgcHJvY2Vzcyh1cGRhdGVba2V5XSwga2V5KTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBrZXkgb2YgZGVsZXRlTWUpIHtcbiAgICAgIGRlbGV0ZSB1cGRhdGVba2V5XTtcbiAgICB9XG4gICAgcmV0dXJuIG9wcztcbiAgfVxuXG4gIC8vIFByb2Nlc3NlcyByZWxhdGlvbi11cGRhdGluZyBvcGVyYXRpb25zIGZyb20gYSBSRVNULWZvcm1hdCB1cGRhdGUuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBhbGwgdXBkYXRlcyBoYXZlIGJlZW4gcGVyZm9ybWVkXG4gIGhhbmRsZVJlbGF0aW9uVXBkYXRlcyhjbGFzc05hbWU6IHN0cmluZywgb2JqZWN0SWQ6IHN0cmluZywgdXBkYXRlOiBhbnksIG9wczogYW55KSB7XG4gICAgdmFyIHBlbmRpbmcgPSBbXTtcbiAgICBvYmplY3RJZCA9IHVwZGF0ZS5vYmplY3RJZCB8fCBvYmplY3RJZDtcbiAgICBvcHMuZm9yRWFjaCgoeyBrZXksIG9wIH0pID0+IHtcbiAgICAgIGlmICghb3ApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKG9wLl9fb3AgPT0gJ0FkZFJlbGF0aW9uJykge1xuICAgICAgICBmb3IgKGNvbnN0IG9iamVjdCBvZiBvcC5vYmplY3RzKSB7XG4gICAgICAgICAgcGVuZGluZy5wdXNoKHRoaXMuYWRkUmVsYXRpb24oa2V5LCBjbGFzc05hbWUsIG9iamVjdElkLCBvYmplY3Qub2JqZWN0SWQpKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAob3AuX19vcCA9PSAnUmVtb3ZlUmVsYXRpb24nKSB7XG4gICAgICAgIGZvciAoY29uc3Qgb2JqZWN0IG9mIG9wLm9iamVjdHMpIHtcbiAgICAgICAgICBwZW5kaW5nLnB1c2godGhpcy5yZW1vdmVSZWxhdGlvbihrZXksIGNsYXNzTmFtZSwgb2JqZWN0SWQsIG9iamVjdC5vYmplY3RJZCkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwocGVuZGluZyk7XG4gIH1cblxuICAvLyBBZGRzIGEgcmVsYXRpb24uXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgc3VjY2Vzc2Z1bGx5IGlmZiB0aGUgYWRkIHdhcyBzdWNjZXNzZnVsLlxuICBhZGRSZWxhdGlvbihrZXk6IHN0cmluZywgZnJvbUNsYXNzTmFtZTogc3RyaW5nLCBmcm9tSWQ6IHN0cmluZywgdG9JZDogc3RyaW5nKSB7XG4gICAgY29uc3QgZG9jID0ge1xuICAgICAgcmVsYXRlZElkOiB0b0lkLFxuICAgICAgb3duaW5nSWQ6IGZyb21JZCxcbiAgICB9O1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIudXBzZXJ0T25lT2JqZWN0KFxuICAgICAgYF9Kb2luOiR7a2V5fToke2Zyb21DbGFzc05hbWV9YCxcbiAgICAgIHJlbGF0aW9uU2NoZW1hLFxuICAgICAgZG9jLFxuICAgICAgZG9jLFxuICAgICAgdGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb25cbiAgICApO1xuICB9XG5cbiAgLy8gUmVtb3ZlcyBhIHJlbGF0aW9uLlxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHN1Y2Nlc3NmdWxseSBpZmYgdGhlIHJlbW92ZSB3YXNcbiAgLy8gc3VjY2Vzc2Z1bC5cbiAgcmVtb3ZlUmVsYXRpb24oa2V5OiBzdHJpbmcsIGZyb21DbGFzc05hbWU6IHN0cmluZywgZnJvbUlkOiBzdHJpbmcsIHRvSWQ6IHN0cmluZykge1xuICAgIHZhciBkb2MgPSB7XG4gICAgICByZWxhdGVkSWQ6IHRvSWQsXG4gICAgICBvd25pbmdJZDogZnJvbUlkLFxuICAgIH07XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlclxuICAgICAgLmRlbGV0ZU9iamVjdHNCeVF1ZXJ5KFxuICAgICAgICBgX0pvaW46JHtrZXl9OiR7ZnJvbUNsYXNzTmFtZX1gLFxuICAgICAgICByZWxhdGlvblNjaGVtYSxcbiAgICAgICAgZG9jLFxuICAgICAgICB0aGlzLl90cmFuc2FjdGlvbmFsU2Vzc2lvblxuICAgICAgKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgLy8gV2UgZG9uJ3QgY2FyZSBpZiB0aGV5IHRyeSB0byBkZWxldGUgYSBub24tZXhpc3RlbnQgcmVsYXRpb24uXG4gICAgICAgIGlmIChlcnJvci5jb2RlID09IFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8vIFJlbW92ZXMgb2JqZWN0cyBtYXRjaGVzIHRoaXMgcXVlcnkgZnJvbSB0aGUgZGF0YWJhc2UuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgc3VjY2Vzc2Z1bGx5IGlmZiB0aGUgb2JqZWN0IHdhc1xuICAvLyBkZWxldGVkLlxuICAvLyBPcHRpb25zOlxuICAvLyAgIGFjbDogIGEgbGlzdCBvZiBzdHJpbmdzLiBJZiB0aGUgb2JqZWN0IHRvIGJlIHVwZGF0ZWQgaGFzIGFuIEFDTCxcbiAgLy8gICAgICAgICBvbmUgb2YgdGhlIHByb3ZpZGVkIHN0cmluZ3MgbXVzdCBwcm92aWRlIHRoZSBjYWxsZXIgd2l0aFxuICAvLyAgICAgICAgIHdyaXRlIHBlcm1pc3Npb25zLlxuICBkZXN0cm95KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHF1ZXJ5OiBhbnksXG4gICAgeyBhY2wgfTogUXVlcnlPcHRpb25zID0ge30sXG4gICAgdmFsaWRTY2hlbWFDb250cm9sbGVyOiBTY2hlbWFDb250cm9sbGVyLlNjaGVtYUNvbnRyb2xsZXJcbiAgKTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCBpc01hc3RlciA9IGFjbCA9PT0gdW5kZWZpbmVkO1xuICAgIGNvbnN0IGFjbEdyb3VwID0gYWNsIHx8IFtdO1xuXG4gICAgcmV0dXJuIHRoaXMubG9hZFNjaGVtYUlmTmVlZGVkKHZhbGlkU2NoZW1hQ29udHJvbGxlcikudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHtcbiAgICAgIHJldHVybiAoaXNNYXN0ZXJcbiAgICAgICAgPyBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICA6IHNjaGVtYUNvbnRyb2xsZXIudmFsaWRhdGVQZXJtaXNzaW9uKGNsYXNzTmFtZSwgYWNsR3JvdXAsICdkZWxldGUnKVxuICAgICAgKS50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKCFpc01hc3Rlcikge1xuICAgICAgICAgIHF1ZXJ5ID0gdGhpcy5hZGRQb2ludGVyUGVybWlzc2lvbnMoXG4gICAgICAgICAgICBzY2hlbWFDb250cm9sbGVyLFxuICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgJ2RlbGV0ZScsXG4gICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgIGFjbEdyb3VwXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoIXF1ZXJ5KSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ09iamVjdCBub3QgZm91bmQuJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIGRlbGV0ZSBieSBxdWVyeVxuICAgICAgICBpZiAoYWNsKSB7XG4gICAgICAgICAgcXVlcnkgPSBhZGRXcml0ZUFDTChxdWVyeSwgYWNsKTtcbiAgICAgICAgfVxuICAgICAgICB2YWxpZGF0ZVF1ZXJ5KHF1ZXJ5KTtcbiAgICAgICAgcmV0dXJuIHNjaGVtYUNvbnRyb2xsZXJcbiAgICAgICAgICAuZ2V0T25lU2NoZW1hKGNsYXNzTmFtZSlcbiAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgLy8gSWYgdGhlIHNjaGVtYSBkb2Vzbid0IGV4aXN0LCBwcmV0ZW5kIGl0IGV4aXN0cyB3aXRoIG5vIGZpZWxkcy4gVGhpcyBiZWhhdmlvclxuICAgICAgICAgICAgLy8gd2lsbCBsaWtlbHkgbmVlZCByZXZpc2l0aW5nLlxuICAgICAgICAgICAgaWYgKGVycm9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHsgZmllbGRzOiB7fSB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAudGhlbihwYXJzZUZvcm1hdFNjaGVtYSA9PlxuICAgICAgICAgICAgdGhpcy5hZGFwdGVyLmRlbGV0ZU9iamVjdHNCeVF1ZXJ5KFxuICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgIHBhcnNlRm9ybWF0U2NoZW1hLFxuICAgICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgICAgdGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb25cbiAgICAgICAgICAgIClcbiAgICAgICAgICApXG4gICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgIC8vIFdoZW4gZGVsZXRpbmcgc2Vzc2lvbnMgd2hpbGUgY2hhbmdpbmcgcGFzc3dvcmRzLCBkb24ndCB0aHJvdyBhbiBlcnJvciBpZiB0aGV5IGRvbid0IGhhdmUgYW55IHNlc3Npb25zLlxuICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PT0gJ19TZXNzaW9uJyAmJiBlcnJvci5jb2RlID09PSBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5EKSB7XG4gICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe30pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIEluc2VydHMgYW4gb2JqZWN0IGludG8gdGhlIGRhdGFiYXNlLlxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHN1Y2Nlc3NmdWxseSBpZmYgdGhlIG9iamVjdCBzYXZlZC5cbiAgY3JlYXRlKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIG9iamVjdDogYW55LFxuICAgIHsgYWNsIH06IFF1ZXJ5T3B0aW9ucyA9IHt9LFxuICAgIHZhbGlkYXRlT25seTogYm9vbGVhbiA9IGZhbHNlLFxuICAgIHZhbGlkU2NoZW1hQ29udHJvbGxlcjogU2NoZW1hQ29udHJvbGxlci5TY2hlbWFDb250cm9sbGVyXG4gICk6IFByb21pc2U8YW55PiB7XG4gICAgLy8gTWFrZSBhIGNvcHkgb2YgdGhlIG9iamVjdCwgc28gd2UgZG9uJ3QgbXV0YXRlIHRoZSBpbmNvbWluZyBkYXRhLlxuICAgIGNvbnN0IG9yaWdpbmFsT2JqZWN0ID0gb2JqZWN0O1xuICAgIG9iamVjdCA9IHRyYW5zZm9ybU9iamVjdEFDTChvYmplY3QpO1xuXG4gICAgb2JqZWN0LmNyZWF0ZWRBdCA9IHsgaXNvOiBvYmplY3QuY3JlYXRlZEF0LCBfX3R5cGU6ICdEYXRlJyB9O1xuICAgIG9iamVjdC51cGRhdGVkQXQgPSB7IGlzbzogb2JqZWN0LnVwZGF0ZWRBdCwgX190eXBlOiAnRGF0ZScgfTtcblxuICAgIHZhciBpc01hc3RlciA9IGFjbCA9PT0gdW5kZWZpbmVkO1xuICAgIHZhciBhY2xHcm91cCA9IGFjbCB8fCBbXTtcbiAgICBjb25zdCByZWxhdGlvblVwZGF0ZXMgPSB0aGlzLmNvbGxlY3RSZWxhdGlvblVwZGF0ZXMoY2xhc3NOYW1lLCBudWxsLCBvYmplY3QpO1xuXG4gICAgcmV0dXJuIHRoaXMudmFsaWRhdGVDbGFzc05hbWUoY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5sb2FkU2NoZW1hSWZOZWVkZWQodmFsaWRTY2hlbWFDb250cm9sbGVyKSlcbiAgICAgIC50aGVuKHNjaGVtYUNvbnRyb2xsZXIgPT4ge1xuICAgICAgICByZXR1cm4gKGlzTWFzdGVyXG4gICAgICAgICAgPyBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICAgIDogc2NoZW1hQ29udHJvbGxlci52YWxpZGF0ZVBlcm1pc3Npb24oY2xhc3NOYW1lLCBhY2xHcm91cCwgJ2NyZWF0ZScpXG4gICAgICAgIClcbiAgICAgICAgICAudGhlbigoKSA9PiBzY2hlbWFDb250cm9sbGVyLmVuZm9yY2VDbGFzc0V4aXN0cyhjbGFzc05hbWUpKVxuICAgICAgICAgIC50aGVuKCgpID0+IHNjaGVtYUNvbnRyb2xsZXIuZ2V0T25lU2NoZW1hKGNsYXNzTmFtZSwgdHJ1ZSkpXG4gICAgICAgICAgLnRoZW4oc2NoZW1hID0+IHtcbiAgICAgICAgICAgIHRyYW5zZm9ybUF1dGhEYXRhKGNsYXNzTmFtZSwgb2JqZWN0LCBzY2hlbWEpO1xuICAgICAgICAgICAgZmxhdHRlblVwZGF0ZU9wZXJhdG9yc0ZvckNyZWF0ZShvYmplY3QpO1xuICAgICAgICAgICAgaWYgKHZhbGlkYXRlT25seSkge1xuICAgICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmNyZWF0ZU9iamVjdChcbiAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICBTY2hlbWFDb250cm9sbGVyLmNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEoc2NoZW1hKSxcbiAgICAgICAgICAgICAgb2JqZWN0LFxuICAgICAgICAgICAgICB0aGlzLl90cmFuc2FjdGlvbmFsU2Vzc2lvblxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgICBpZiAodmFsaWRhdGVPbmx5KSB7XG4gICAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbE9iamVjdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZVJlbGF0aW9uVXBkYXRlcyhcbiAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICBvYmplY3Qub2JqZWN0SWQsXG4gICAgICAgICAgICAgIG9iamVjdCxcbiAgICAgICAgICAgICAgcmVsYXRpb25VcGRhdGVzXG4gICAgICAgICAgICApLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gc2FuaXRpemVEYXRhYmFzZVJlc3VsdChvcmlnaW5hbE9iamVjdCwgcmVzdWx0Lm9wc1swXSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgIH0pO1xuICB9XG5cbiAgY2FuQWRkRmllbGQoXG4gICAgc2NoZW1hOiBTY2hlbWFDb250cm9sbGVyLlNjaGVtYUNvbnRyb2xsZXIsXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgb2JqZWN0OiBhbnksXG4gICAgYWNsR3JvdXA6IHN0cmluZ1tdLFxuICAgIHJ1bk9wdGlvbnM6IFF1ZXJ5T3B0aW9uc1xuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBjbGFzc1NjaGVtYSA9IHNjaGVtYS5zY2hlbWFEYXRhW2NsYXNzTmFtZV07XG4gICAgaWYgKCFjbGFzc1NjaGVtYSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICBjb25zdCBmaWVsZHMgPSBPYmplY3Qua2V5cyhvYmplY3QpO1xuICAgIGNvbnN0IHNjaGVtYUZpZWxkcyA9IE9iamVjdC5rZXlzKGNsYXNzU2NoZW1hLmZpZWxkcyk7XG4gICAgY29uc3QgbmV3S2V5cyA9IGZpZWxkcy5maWx0ZXIoZmllbGQgPT4ge1xuICAgICAgLy8gU2tpcCBmaWVsZHMgdGhhdCBhcmUgdW5zZXRcbiAgICAgIGlmIChvYmplY3RbZmllbGRdICYmIG9iamVjdFtmaWVsZF0uX19vcCAmJiBvYmplY3RbZmllbGRdLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzY2hlbWFGaWVsZHMuaW5kZXhPZihmaWVsZCkgPCAwO1xuICAgIH0pO1xuICAgIGlmIChuZXdLZXlzLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIGFkZHMgYSBtYXJrZXIgdGhhdCBuZXcgZmllbGQgaXMgYmVpbmcgYWRkaW5nIGR1cmluZyB1cGRhdGVcbiAgICAgIHJ1bk9wdGlvbnMuYWRkc0ZpZWxkID0gdHJ1ZTtcblxuICAgICAgY29uc3QgYWN0aW9uID0gcnVuT3B0aW9ucy5hY3Rpb247XG4gICAgICByZXR1cm4gc2NoZW1hLnZhbGlkYXRlUGVybWlzc2lvbihjbGFzc05hbWUsIGFjbEdyb3VwLCAnYWRkRmllbGQnLCBhY3Rpb24pO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICAvLyBXb24ndCBkZWxldGUgY29sbGVjdGlvbnMgaW4gdGhlIHN5c3RlbSBuYW1lc3BhY2VcbiAgLyoqXG4gICAqIERlbGV0ZSBhbGwgY2xhc3NlcyBhbmQgY2xlYXJzIHRoZSBzY2hlbWEgY2FjaGVcbiAgICpcbiAgICogQHBhcmFtIHtib29sZWFufSBmYXN0IHNldCB0byB0cnVlIGlmIGl0J3Mgb2sgdG8ganVzdCBkZWxldGUgcm93cyBhbmQgbm90IGluZGV4ZXNcbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IHdoZW4gdGhlIGRlbGV0aW9ucyBjb21wbGV0ZXNcbiAgICovXG4gIGRlbGV0ZUV2ZXJ5dGhpbmcoZmFzdDogYm9vbGVhbiA9IGZhbHNlKTogUHJvbWlzZTxhbnk+IHtcbiAgICB0aGlzLnNjaGVtYVByb21pc2UgPSBudWxsO1xuICAgIHJldHVybiBQcm9taXNlLmFsbChbdGhpcy5hZGFwdGVyLmRlbGV0ZUFsbENsYXNzZXMoZmFzdCksIHRoaXMuc2NoZW1hQ2FjaGUuY2xlYXIoKV0pO1xuICB9XG5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGEgbGlzdCBvZiByZWxhdGVkIGlkcyBnaXZlbiBhbiBvd25pbmcgaWQuXG4gIC8vIGNsYXNzTmFtZSBoZXJlIGlzIHRoZSBvd25pbmcgY2xhc3NOYW1lLlxuICByZWxhdGVkSWRzKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIGtleTogc3RyaW5nLFxuICAgIG93bmluZ0lkOiBzdHJpbmcsXG4gICAgcXVlcnlPcHRpb25zOiBRdWVyeU9wdGlvbnNcbiAgKTogUHJvbWlzZTxBcnJheTxzdHJpbmc+PiB7XG4gICAgY29uc3QgeyBza2lwLCBsaW1pdCwgc29ydCB9ID0gcXVlcnlPcHRpb25zO1xuICAgIGNvbnN0IGZpbmRPcHRpb25zID0ge307XG4gICAgaWYgKHNvcnQgJiYgc29ydC5jcmVhdGVkQXQgJiYgdGhpcy5hZGFwdGVyLmNhblNvcnRPbkpvaW5UYWJsZXMpIHtcbiAgICAgIGZpbmRPcHRpb25zLnNvcnQgPSB7IF9pZDogc29ydC5jcmVhdGVkQXQgfTtcbiAgICAgIGZpbmRPcHRpb25zLmxpbWl0ID0gbGltaXQ7XG4gICAgICBmaW5kT3B0aW9ucy5za2lwID0gc2tpcDtcbiAgICAgIHF1ZXJ5T3B0aW9ucy5za2lwID0gMDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlclxuICAgICAgLmZpbmQoam9pblRhYmxlTmFtZShjbGFzc05hbWUsIGtleSksIHJlbGF0aW9uU2NoZW1hLCB7IG93bmluZ0lkIH0sIGZpbmRPcHRpb25zKVxuICAgICAgLnRoZW4ocmVzdWx0cyA9PiByZXN1bHRzLm1hcChyZXN1bHQgPT4gcmVzdWx0LnJlbGF0ZWRJZCkpO1xuICB9XG5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGEgbGlzdCBvZiBvd25pbmcgaWRzIGdpdmVuIHNvbWUgcmVsYXRlZCBpZHMuXG4gIC8vIGNsYXNzTmFtZSBoZXJlIGlzIHRoZSBvd25pbmcgY2xhc3NOYW1lLlxuICBvd25pbmdJZHMoY2xhc3NOYW1lOiBzdHJpbmcsIGtleTogc3RyaW5nLCByZWxhdGVkSWRzOiBzdHJpbmdbXSk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyXG4gICAgICAuZmluZChcbiAgICAgICAgam9pblRhYmxlTmFtZShjbGFzc05hbWUsIGtleSksXG4gICAgICAgIHJlbGF0aW9uU2NoZW1hLFxuICAgICAgICB7IHJlbGF0ZWRJZDogeyAkaW46IHJlbGF0ZWRJZHMgfSB9LFxuICAgICAgICB7IGtleXM6IFsnb3duaW5nSWQnXSB9XG4gICAgICApXG4gICAgICAudGhlbihyZXN1bHRzID0+IHJlc3VsdHMubWFwKHJlc3VsdCA9PiByZXN1bHQub3duaW5nSWQpKTtcbiAgfVxuXG4gIC8vIE1vZGlmaWVzIHF1ZXJ5IHNvIHRoYXQgaXQgbm8gbG9uZ2VyIGhhcyAkaW4gb24gcmVsYXRpb24gZmllbGRzLCBvclxuICAvLyBlcXVhbC10by1wb2ludGVyIGNvbnN0cmFpbnRzIG9uIHJlbGF0aW9uIGZpZWxkcy5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHF1ZXJ5IGlzIG11dGF0ZWRcbiAgcmVkdWNlSW5SZWxhdGlvbihjbGFzc05hbWU6IHN0cmluZywgcXVlcnk6IGFueSwgc2NoZW1hOiBhbnkpOiBQcm9taXNlPGFueT4ge1xuICAgIC8vIFNlYXJjaCBmb3IgYW4gaW4tcmVsYXRpb24gb3IgZXF1YWwtdG8tcmVsYXRpb25cbiAgICAvLyBNYWtlIGl0IHNlcXVlbnRpYWwgZm9yIG5vdywgbm90IHN1cmUgb2YgcGFyYWxsZWl6YXRpb24gc2lkZSBlZmZlY3RzXG4gICAgaWYgKHF1ZXJ5Wyckb3InXSkge1xuICAgICAgY29uc3Qgb3JzID0gcXVlcnlbJyRvciddO1xuICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgICAgICBvcnMubWFwKChhUXVlcnksIGluZGV4KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucmVkdWNlSW5SZWxhdGlvbihjbGFzc05hbWUsIGFRdWVyeSwgc2NoZW1hKS50aGVuKGFRdWVyeSA9PiB7XG4gICAgICAgICAgICBxdWVyeVsnJG9yJ11baW5kZXhdID0gYVF1ZXJ5O1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgKS50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShxdWVyeSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBwcm9taXNlcyA9IE9iamVjdC5rZXlzKHF1ZXJ5KS5tYXAoa2V5ID0+IHtcbiAgICAgIGNvbnN0IHQgPSBzY2hlbWEuZ2V0RXhwZWN0ZWRUeXBlKGNsYXNzTmFtZSwga2V5KTtcbiAgICAgIGlmICghdCB8fCB0LnR5cGUgIT09ICdSZWxhdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShxdWVyeSk7XG4gICAgICB9XG4gICAgICBsZXQgcXVlcmllczogPyhhbnlbXSkgPSBudWxsO1xuICAgICAgaWYgKFxuICAgICAgICBxdWVyeVtrZXldICYmXG4gICAgICAgIChxdWVyeVtrZXldWyckaW4nXSB8fFxuICAgICAgICAgIHF1ZXJ5W2tleV1bJyRuZSddIHx8XG4gICAgICAgICAgcXVlcnlba2V5XVsnJG5pbiddIHx8XG4gICAgICAgICAgcXVlcnlba2V5XS5fX3R5cGUgPT0gJ1BvaW50ZXInKVxuICAgICAgKSB7XG4gICAgICAgIC8vIEJ1aWxkIHRoZSBsaXN0IG9mIHF1ZXJpZXNcbiAgICAgICAgcXVlcmllcyA9IE9iamVjdC5rZXlzKHF1ZXJ5W2tleV0pLm1hcChjb25zdHJhaW50S2V5ID0+IHtcbiAgICAgICAgICBsZXQgcmVsYXRlZElkcztcbiAgICAgICAgICBsZXQgaXNOZWdhdGlvbiA9IGZhbHNlO1xuICAgICAgICAgIGlmIChjb25zdHJhaW50S2V5ID09PSAnb2JqZWN0SWQnKSB7XG4gICAgICAgICAgICByZWxhdGVkSWRzID0gW3F1ZXJ5W2tleV0ub2JqZWN0SWRdO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY29uc3RyYWludEtleSA9PSAnJGluJykge1xuICAgICAgICAgICAgcmVsYXRlZElkcyA9IHF1ZXJ5W2tleV1bJyRpbiddLm1hcChyID0+IHIub2JqZWN0SWQpO1xuICAgICAgICAgIH0gZWxzZSBpZiAoY29uc3RyYWludEtleSA9PSAnJG5pbicpIHtcbiAgICAgICAgICAgIGlzTmVnYXRpb24gPSB0cnVlO1xuICAgICAgICAgICAgcmVsYXRlZElkcyA9IHF1ZXJ5W2tleV1bJyRuaW4nXS5tYXAociA9PiByLm9iamVjdElkKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGNvbnN0cmFpbnRLZXkgPT0gJyRuZScpIHtcbiAgICAgICAgICAgIGlzTmVnYXRpb24gPSB0cnVlO1xuICAgICAgICAgICAgcmVsYXRlZElkcyA9IFtxdWVyeVtrZXldWyckbmUnXS5vYmplY3RJZF07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGlzTmVnYXRpb24sXG4gICAgICAgICAgICByZWxhdGVkSWRzLFxuICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcXVlcmllcyA9IFt7IGlzTmVnYXRpb246IGZhbHNlLCByZWxhdGVkSWRzOiBbXSB9XTtcbiAgICAgIH1cblxuICAgICAgLy8gcmVtb3ZlIHRoZSBjdXJyZW50IHF1ZXJ5S2V5IGFzIHdlIGRvbix0IG5lZWQgaXQgYW55bW9yZVxuICAgICAgZGVsZXRlIHF1ZXJ5W2tleV07XG4gICAgICAvLyBleGVjdXRlIGVhY2ggcXVlcnkgaW5kZXBlbmRlbnRseSB0byBidWlsZCB0aGUgbGlzdCBvZlxuICAgICAgLy8gJGluIC8gJG5pblxuICAgICAgY29uc3QgcHJvbWlzZXMgPSBxdWVyaWVzLm1hcChxID0+IHtcbiAgICAgICAgaWYgKCFxKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLm93bmluZ0lkcyhjbGFzc05hbWUsIGtleSwgcS5yZWxhdGVkSWRzKS50aGVuKGlkcyA9PiB7XG4gICAgICAgICAgaWYgKHEuaXNOZWdhdGlvbikge1xuICAgICAgICAgICAgdGhpcy5hZGROb3RJbk9iamVjdElkc0lkcyhpZHMsIHF1ZXJ5KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hZGRJbk9iamVjdElkc0lkcyhpZHMsIHF1ZXJ5KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHF1ZXJ5KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIE1vZGlmaWVzIHF1ZXJ5IHNvIHRoYXQgaXQgbm8gbG9uZ2VyIGhhcyAkcmVsYXRlZFRvXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBxdWVyeSBpcyBtdXRhdGVkXG4gIHJlZHVjZVJlbGF0aW9uS2V5cyhjbGFzc05hbWU6IHN0cmluZywgcXVlcnk6IGFueSwgcXVlcnlPcHRpb25zOiBhbnkpOiA/UHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHF1ZXJ5Wyckb3InXSkge1xuICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgICAgICBxdWVyeVsnJG9yJ10ubWFwKGFRdWVyeSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucmVkdWNlUmVsYXRpb25LZXlzKGNsYXNzTmFtZSwgYVF1ZXJ5LCBxdWVyeU9wdGlvbnMpO1xuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9XG5cbiAgICB2YXIgcmVsYXRlZFRvID0gcXVlcnlbJyRyZWxhdGVkVG8nXTtcbiAgICBpZiAocmVsYXRlZFRvKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZWxhdGVkSWRzKFxuICAgICAgICByZWxhdGVkVG8ub2JqZWN0LmNsYXNzTmFtZSxcbiAgICAgICAgcmVsYXRlZFRvLmtleSxcbiAgICAgICAgcmVsYXRlZFRvLm9iamVjdC5vYmplY3RJZCxcbiAgICAgICAgcXVlcnlPcHRpb25zXG4gICAgICApXG4gICAgICAgIC50aGVuKGlkcyA9PiB7XG4gICAgICAgICAgZGVsZXRlIHF1ZXJ5WyckcmVsYXRlZFRvJ107XG4gICAgICAgICAgdGhpcy5hZGRJbk9iamVjdElkc0lkcyhpZHMsIHF1ZXJ5KTtcbiAgICAgICAgICByZXR1cm4gdGhpcy5yZWR1Y2VSZWxhdGlvbktleXMoY2xhc3NOYW1lLCBxdWVyeSwgcXVlcnlPcHRpb25zKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKCkgPT4ge30pO1xuICAgIH1cbiAgfVxuXG4gIGFkZEluT2JqZWN0SWRzSWRzKGlkczogP0FycmF5PHN0cmluZz4gPSBudWxsLCBxdWVyeTogYW55KSB7XG4gICAgY29uc3QgaWRzRnJvbVN0cmluZzogP0FycmF5PHN0cmluZz4gPVxuICAgICAgdHlwZW9mIHF1ZXJ5Lm9iamVjdElkID09PSAnc3RyaW5nJyA/IFtxdWVyeS5vYmplY3RJZF0gOiBudWxsO1xuICAgIGNvbnN0IGlkc0Zyb21FcTogP0FycmF5PHN0cmluZz4gPVxuICAgICAgcXVlcnkub2JqZWN0SWQgJiYgcXVlcnkub2JqZWN0SWRbJyRlcSddID8gW3F1ZXJ5Lm9iamVjdElkWyckZXEnXV0gOiBudWxsO1xuICAgIGNvbnN0IGlkc0Zyb21JbjogP0FycmF5PHN0cmluZz4gPVxuICAgICAgcXVlcnkub2JqZWN0SWQgJiYgcXVlcnkub2JqZWN0SWRbJyRpbiddID8gcXVlcnkub2JqZWN0SWRbJyRpbiddIDogbnVsbDtcblxuICAgIC8vIEBmbG93LWRpc2FibGUtbmV4dFxuICAgIGNvbnN0IGFsbElkczogQXJyYXk8QXJyYXk8c3RyaW5nPj4gPSBbaWRzRnJvbVN0cmluZywgaWRzRnJvbUVxLCBpZHNGcm9tSW4sIGlkc10uZmlsdGVyKFxuICAgICAgbGlzdCA9PiBsaXN0ICE9PSBudWxsXG4gICAgKTtcbiAgICBjb25zdCB0b3RhbExlbmd0aCA9IGFsbElkcy5yZWR1Y2UoKG1lbW8sIGxpc3QpID0+IG1lbW8gKyBsaXN0Lmxlbmd0aCwgMCk7XG5cbiAgICBsZXQgaWRzSW50ZXJzZWN0aW9uID0gW107XG4gICAgaWYgKHRvdGFsTGVuZ3RoID4gMTI1KSB7XG4gICAgICBpZHNJbnRlcnNlY3Rpb24gPSBpbnRlcnNlY3QuYmlnKGFsbElkcyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlkc0ludGVyc2VjdGlvbiA9IGludGVyc2VjdChhbGxJZHMpO1xuICAgIH1cblxuICAgIC8vIE5lZWQgdG8gbWFrZSBzdXJlIHdlIGRvbid0IGNsb2JiZXIgZXhpc3Rpbmcgc2hvcnRoYW5kICRlcSBjb25zdHJhaW50cyBvbiBvYmplY3RJZC5cbiAgICBpZiAoISgnb2JqZWN0SWQnIGluIHF1ZXJ5KSkge1xuICAgICAgcXVlcnkub2JqZWN0SWQgPSB7XG4gICAgICAgICRpbjogdW5kZWZpbmVkLFxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBxdWVyeS5vYmplY3RJZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHF1ZXJ5Lm9iamVjdElkID0ge1xuICAgICAgICAkaW46IHVuZGVmaW5lZCxcbiAgICAgICAgJGVxOiBxdWVyeS5vYmplY3RJZCxcbiAgICAgIH07XG4gICAgfVxuICAgIHF1ZXJ5Lm9iamVjdElkWyckaW4nXSA9IGlkc0ludGVyc2VjdGlvbjtcblxuICAgIHJldHVybiBxdWVyeTtcbiAgfVxuXG4gIGFkZE5vdEluT2JqZWN0SWRzSWRzKGlkczogc3RyaW5nW10gPSBbXSwgcXVlcnk6IGFueSkge1xuICAgIGNvbnN0IGlkc0Zyb21OaW4gPSBxdWVyeS5vYmplY3RJZCAmJiBxdWVyeS5vYmplY3RJZFsnJG5pbiddID8gcXVlcnkub2JqZWN0SWRbJyRuaW4nXSA6IFtdO1xuICAgIGxldCBhbGxJZHMgPSBbLi4uaWRzRnJvbU5pbiwgLi4uaWRzXS5maWx0ZXIobGlzdCA9PiBsaXN0ICE9PSBudWxsKTtcblxuICAgIC8vIG1ha2UgYSBzZXQgYW5kIHNwcmVhZCB0byByZW1vdmUgZHVwbGljYXRlc1xuICAgIGFsbElkcyA9IFsuLi5uZXcgU2V0KGFsbElkcyldO1xuXG4gICAgLy8gTmVlZCB0byBtYWtlIHN1cmUgd2UgZG9uJ3QgY2xvYmJlciBleGlzdGluZyBzaG9ydGhhbmQgJGVxIGNvbnN0cmFpbnRzIG9uIG9iamVjdElkLlxuICAgIGlmICghKCdvYmplY3RJZCcgaW4gcXVlcnkpKSB7XG4gICAgICBxdWVyeS5vYmplY3RJZCA9IHtcbiAgICAgICAgJG5pbjogdW5kZWZpbmVkLFxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBxdWVyeS5vYmplY3RJZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHF1ZXJ5Lm9iamVjdElkID0ge1xuICAgICAgICAkbmluOiB1bmRlZmluZWQsXG4gICAgICAgICRlcTogcXVlcnkub2JqZWN0SWQsXG4gICAgICB9O1xuICAgIH1cblxuICAgIHF1ZXJ5Lm9iamVjdElkWyckbmluJ10gPSBhbGxJZHM7XG4gICAgcmV0dXJuIHF1ZXJ5O1xuICB9XG5cbiAgLy8gUnVucyBhIHF1ZXJ5IG9uIHRoZSBkYXRhYmFzZS5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIGxpc3Qgb2YgaXRlbXMuXG4gIC8vIE9wdGlvbnM6XG4gIC8vICAgc2tpcCAgICBudW1iZXIgb2YgcmVzdWx0cyB0byBza2lwLlxuICAvLyAgIGxpbWl0ICAgbGltaXQgdG8gdGhpcyBudW1iZXIgb2YgcmVzdWx0cy5cbiAgLy8gICBzb3J0ICAgIGFuIG9iamVjdCB3aGVyZSBrZXlzIGFyZSB0aGUgZmllbGRzIHRvIHNvcnQgYnkuXG4gIC8vICAgICAgICAgICB0aGUgdmFsdWUgaXMgKzEgZm9yIGFzY2VuZGluZywgLTEgZm9yIGRlc2NlbmRpbmcuXG4gIC8vICAgY291bnQgICBydW4gYSBjb3VudCBpbnN0ZWFkIG9mIHJldHVybmluZyByZXN1bHRzLlxuICAvLyAgIGFjbCAgICAgcmVzdHJpY3QgdGhpcyBvcGVyYXRpb24gd2l0aCBhbiBBQ0wgZm9yIHRoZSBwcm92aWRlZCBhcnJheVxuICAvLyAgICAgICAgICAgb2YgdXNlciBvYmplY3RJZHMgYW5kIHJvbGVzLiBhY2w6IG51bGwgbWVhbnMgbm8gdXNlci5cbiAgLy8gICAgICAgICAgIHdoZW4gdGhpcyBmaWVsZCBpcyBub3QgcHJlc2VudCwgZG9uJ3QgZG8gYW55dGhpbmcgcmVnYXJkaW5nIEFDTHMuXG4gIC8vICBjYXNlSW5zZW5zaXRpdmUgbWFrZSBzdHJpbmcgY29tcGFyaXNvbnMgY2FzZSBpbnNlbnNpdGl2ZVxuICAvLyBUT0RPOiBtYWtlIHVzZXJJZHMgbm90IG5lZWRlZCBoZXJlLiBUaGUgZGIgYWRhcHRlciBzaG91bGRuJ3Qga25vd1xuICAvLyBhbnl0aGluZyBhYm91dCB1c2VycywgaWRlYWxseS4gVGhlbiwgaW1wcm92ZSB0aGUgZm9ybWF0IG9mIHRoZSBBQ0xcbiAgLy8gYXJnIHRvIHdvcmsgbGlrZSB0aGUgb3RoZXJzLlxuICBmaW5kKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHF1ZXJ5OiBhbnksXG4gICAge1xuICAgICAgc2tpcCxcbiAgICAgIGxpbWl0LFxuICAgICAgYWNsLFxuICAgICAgc29ydCA9IHt9LFxuICAgICAgY291bnQsXG4gICAgICBrZXlzLFxuICAgICAgb3AsXG4gICAgICBkaXN0aW5jdCxcbiAgICAgIHBpcGVsaW5lLFxuICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICBoaW50LFxuICAgICAgY2FzZUluc2Vuc2l0aXZlID0gZmFsc2UsXG4gICAgICBleHBsYWluLFxuICAgIH06IGFueSA9IHt9LFxuICAgIGF1dGg6IGFueSA9IHt9LFxuICAgIHZhbGlkU2NoZW1hQ29udHJvbGxlcjogU2NoZW1hQ29udHJvbGxlci5TY2hlbWFDb250cm9sbGVyXG4gICk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3QgaXNNYXN0ZXIgPSBhY2wgPT09IHVuZGVmaW5lZDtcbiAgICBjb25zdCBhY2xHcm91cCA9IGFjbCB8fCBbXTtcbiAgICBvcCA9XG4gICAgICBvcCB8fCAodHlwZW9mIHF1ZXJ5Lm9iamVjdElkID09ICdzdHJpbmcnICYmIE9iamVjdC5rZXlzKHF1ZXJ5KS5sZW5ndGggPT09IDEgPyAnZ2V0JyA6ICdmaW5kJyk7XG4gICAgLy8gQ291bnQgb3BlcmF0aW9uIGlmIGNvdW50aW5nXG4gICAgb3AgPSBjb3VudCA9PT0gdHJ1ZSA/ICdjb3VudCcgOiBvcDtcblxuICAgIGxldCBjbGFzc0V4aXN0cyA9IHRydWU7XG4gICAgcmV0dXJuIHRoaXMubG9hZFNjaGVtYUlmTmVlZGVkKHZhbGlkU2NoZW1hQ29udHJvbGxlcikudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHtcbiAgICAgIC8vQWxsb3cgdm9sYXRpbGUgY2xhc3NlcyBpZiBxdWVyeWluZyB3aXRoIE1hc3RlciAoZm9yIF9QdXNoU3RhdHVzKVxuICAgICAgLy9UT0RPOiBNb3ZlIHZvbGF0aWxlIGNsYXNzZXMgY29uY2VwdCBpbnRvIG1vbmdvIGFkYXB0ZXIsIHBvc3RncmVzIGFkYXB0ZXIgc2hvdWxkbid0IGNhcmVcbiAgICAgIC8vdGhhdCBhcGkucGFyc2UuY29tIGJyZWFrcyB3aGVuIF9QdXNoU3RhdHVzIGV4aXN0cyBpbiBtb25nby5cbiAgICAgIHJldHVybiBzY2hlbWFDb250cm9sbGVyXG4gICAgICAgIC5nZXRPbmVTY2hlbWEoY2xhc3NOYW1lLCBpc01hc3RlcilcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAvLyBCZWhhdmlvciBmb3Igbm9uLWV4aXN0ZW50IGNsYXNzZXMgaXMga2luZGEgd2VpcmQgb24gUGFyc2UuY29tLiBQcm9iYWJseSBkb2Vzbid0IG1hdHRlciB0b28gbXVjaC5cbiAgICAgICAgICAvLyBGb3Igbm93LCBwcmV0ZW5kIHRoZSBjbGFzcyBleGlzdHMgYnV0IGhhcyBubyBvYmplY3RzLFxuICAgICAgICAgIGlmIChlcnJvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBjbGFzc0V4aXN0cyA9IGZhbHNlO1xuICAgICAgICAgICAgcmV0dXJuIHsgZmllbGRzOiB7fSB9O1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oc2NoZW1hID0+IHtcbiAgICAgICAgICAvLyBQYXJzZS5jb20gdHJlYXRzIHF1ZXJpZXMgb24gX2NyZWF0ZWRfYXQgYW5kIF91cGRhdGVkX2F0IGFzIGlmIHRoZXkgd2VyZSBxdWVyaWVzIG9uIGNyZWF0ZWRBdCBhbmQgdXBkYXRlZEF0LFxuICAgICAgICAgIC8vIHNvIGR1cGxpY2F0ZSB0aGF0IGJlaGF2aW9yIGhlcmUuIElmIGJvdGggYXJlIHNwZWNpZmllZCwgdGhlIGNvcnJlY3QgYmVoYXZpb3IgdG8gbWF0Y2ggUGFyc2UuY29tIGlzIHRvXG4gICAgICAgICAgLy8gdXNlIHRoZSBvbmUgdGhhdCBhcHBlYXJzIGZpcnN0IGluIHRoZSBzb3J0IGxpc3QuXG4gICAgICAgICAgaWYgKHNvcnQuX2NyZWF0ZWRfYXQpIHtcbiAgICAgICAgICAgIHNvcnQuY3JlYXRlZEF0ID0gc29ydC5fY3JlYXRlZF9hdDtcbiAgICAgICAgICAgIGRlbGV0ZSBzb3J0Ll9jcmVhdGVkX2F0O1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoc29ydC5fdXBkYXRlZF9hdCkge1xuICAgICAgICAgICAgc29ydC51cGRhdGVkQXQgPSBzb3J0Ll91cGRhdGVkX2F0O1xuICAgICAgICAgICAgZGVsZXRlIHNvcnQuX3VwZGF0ZWRfYXQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHF1ZXJ5T3B0aW9ucyA9IHtcbiAgICAgICAgICAgIHNraXAsXG4gICAgICAgICAgICBsaW1pdCxcbiAgICAgICAgICAgIHNvcnQsXG4gICAgICAgICAgICBrZXlzLFxuICAgICAgICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICBoaW50LFxuICAgICAgICAgICAgY2FzZUluc2Vuc2l0aXZlLFxuICAgICAgICAgICAgZXhwbGFpbixcbiAgICAgICAgICB9O1xuICAgICAgICAgIE9iamVjdC5rZXlzKHNvcnQpLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgICAgICAgIGlmIChmaWVsZE5hbWUubWF0Y2goL15hdXRoRGF0YVxcLihbYS16QS1aMC05X10rKVxcLmlkJC8pKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FLCBgQ2Fubm90IHNvcnQgYnkgJHtmaWVsZE5hbWV9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCByb290RmllbGROYW1lID0gZ2V0Um9vdEZpZWxkTmFtZShmaWVsZE5hbWUpO1xuICAgICAgICAgICAgaWYgKCFTY2hlbWFDb250cm9sbGVyLmZpZWxkTmFtZUlzVmFsaWQocm9vdEZpZWxkTmFtZSwgY2xhc3NOYW1lKSkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSxcbiAgICAgICAgICAgICAgICBgSW52YWxpZCBmaWVsZCBuYW1lOiAke2ZpZWxkTmFtZX0uYFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybiAoaXNNYXN0ZXJcbiAgICAgICAgICAgID8gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgICAgIDogc2NoZW1hQ29udHJvbGxlci52YWxpZGF0ZVBlcm1pc3Npb24oY2xhc3NOYW1lLCBhY2xHcm91cCwgb3ApXG4gICAgICAgICAgKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5yZWR1Y2VSZWxhdGlvbktleXMoY2xhc3NOYW1lLCBxdWVyeSwgcXVlcnlPcHRpb25zKSlcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMucmVkdWNlSW5SZWxhdGlvbihjbGFzc05hbWUsIHF1ZXJ5LCBzY2hlbWFDb250cm9sbGVyKSlcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgbGV0IHByb3RlY3RlZEZpZWxkcztcbiAgICAgICAgICAgICAgaWYgKCFpc01hc3Rlcikge1xuICAgICAgICAgICAgICAgIHF1ZXJ5ID0gdGhpcy5hZGRQb2ludGVyUGVybWlzc2lvbnMoXG4gICAgICAgICAgICAgICAgICBzY2hlbWFDb250cm9sbGVyLFxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgb3AsXG4gICAgICAgICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgICAgICAgIGFjbEdyb3VwXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAvKiBEb24ndCB1c2UgcHJvamVjdGlvbnMgdG8gb3B0aW1pemUgdGhlIHByb3RlY3RlZEZpZWxkcyBzaW5jZSB0aGUgcHJvdGVjdGVkRmllbGRzXG4gICAgICAgICAgICAgICAgICBiYXNlZCBvbiBwb2ludGVyLXBlcm1pc3Npb25zIGFyZSBkZXRlcm1pbmVkIGFmdGVyIHF1ZXJ5aW5nLiBUaGUgZmlsdGVyaW5nIGNhblxuICAgICAgICAgICAgICAgICAgb3ZlcndyaXRlIHRoZSBwcm90ZWN0ZWQgZmllbGRzLiAqL1xuICAgICAgICAgICAgICAgIHByb3RlY3RlZEZpZWxkcyA9IHRoaXMuYWRkUHJvdGVjdGVkRmllbGRzKFxuICAgICAgICAgICAgICAgICAgc2NoZW1hQ29udHJvbGxlcixcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgIHF1ZXJ5LFxuICAgICAgICAgICAgICAgICAgYWNsR3JvdXAsXG4gICAgICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICAgICAgcXVlcnlPcHRpb25zXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoIXF1ZXJ5KSB7XG4gICAgICAgICAgICAgICAgaWYgKG9wID09PSAnZ2V0Jykge1xuICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kLicpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmICghaXNNYXN0ZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAob3AgPT09ICd1cGRhdGUnIHx8IG9wID09PSAnZGVsZXRlJykge1xuICAgICAgICAgICAgICAgICAgcXVlcnkgPSBhZGRXcml0ZUFDTChxdWVyeSwgYWNsR3JvdXApO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBxdWVyeSA9IGFkZFJlYWRBQ0wocXVlcnksIGFjbEdyb3VwKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdmFsaWRhdGVRdWVyeShxdWVyeSk7XG4gICAgICAgICAgICAgIGlmIChjb3VudCkge1xuICAgICAgICAgICAgICAgIGlmICghY2xhc3NFeGlzdHMpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmNvdW50KFxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgICAgIHNjaGVtYSxcbiAgICAgICAgICAgICAgICAgICAgcXVlcnksXG4gICAgICAgICAgICAgICAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgIGhpbnRcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGRpc3RpbmN0KSB7XG4gICAgICAgICAgICAgICAgaWYgKCFjbGFzc0V4aXN0cykge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmRpc3RpbmN0KGNsYXNzTmFtZSwgc2NoZW1hLCBxdWVyeSwgZGlzdGluY3QpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChwaXBlbGluZSkge1xuICAgICAgICAgICAgICAgIGlmICghY2xhc3NFeGlzdHMpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWRhcHRlci5hZ2dyZWdhdGUoXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgICAgICAgICAgICBwaXBlbGluZSxcbiAgICAgICAgICAgICAgICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICAgICAgICAgIGhpbnQsXG4gICAgICAgICAgICAgICAgICAgIGV4cGxhaW5cbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGV4cGxhaW4pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmZpbmQoY2xhc3NOYW1lLCBzY2hlbWEsIHF1ZXJ5LCBxdWVyeU9wdGlvbnMpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXJcbiAgICAgICAgICAgICAgICAgIC5maW5kKGNsYXNzTmFtZSwgc2NoZW1hLCBxdWVyeSwgcXVlcnlPcHRpb25zKVxuICAgICAgICAgICAgICAgICAgLnRoZW4ob2JqZWN0cyA9PlxuICAgICAgICAgICAgICAgICAgICBvYmplY3RzLm1hcChvYmplY3QgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgIG9iamVjdCA9IHVudHJhbnNmb3JtT2JqZWN0QUNMKG9iamVjdCk7XG4gICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZpbHRlclNlbnNpdGl2ZURhdGEoXG4gICAgICAgICAgICAgICAgICAgICAgICBpc01hc3RlcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjbEdyb3VwLFxuICAgICAgICAgICAgICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2NoZW1hQ29udHJvbGxlcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHByb3RlY3RlZEZpZWxkcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdFxuICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZGVsZXRlU2NoZW1hKGNsYXNzTmFtZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMubG9hZFNjaGVtYSh7IGNsZWFyQ2FjaGU6IHRydWUgfSlcbiAgICAgIC50aGVuKHNjaGVtYUNvbnRyb2xsZXIgPT4gc2NoZW1hQ29udHJvbGxlci5nZXRPbmVTY2hlbWEoY2xhc3NOYW1lLCB0cnVlKSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmV0dXJuIHsgZmllbGRzOiB7fSB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLnRoZW4oKHNjaGVtYTogYW55KSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbGxlY3Rpb25FeGlzdHMoY2xhc3NOYW1lKVxuICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMuYWRhcHRlci5jb3VudChjbGFzc05hbWUsIHsgZmllbGRzOiB7fSB9LCBudWxsLCAnJywgZmFsc2UpKVxuICAgICAgICAgIC50aGVuKGNvdW50ID0+IHtcbiAgICAgICAgICAgIGlmIChjb3VudCA+IDApIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIDI1NSxcbiAgICAgICAgICAgICAgICBgQ2xhc3MgJHtjbGFzc05hbWV9IGlzIG5vdCBlbXB0eSwgY29udGFpbnMgJHtjb3VudH0gb2JqZWN0cywgY2Fubm90IGRyb3Agc2NoZW1hLmBcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuZGVsZXRlQ2xhc3MoY2xhc3NOYW1lKTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC50aGVuKHdhc1BhcnNlQ29sbGVjdGlvbiA9PiB7XG4gICAgICAgICAgICBpZiAod2FzUGFyc2VDb2xsZWN0aW9uKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHJlbGF0aW9uRmllbGROYW1lcyA9IE9iamVjdC5rZXlzKHNjaGVtYS5maWVsZHMpLmZpbHRlcihcbiAgICAgICAgICAgICAgICBmaWVsZE5hbWUgPT4gc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdSZWxhdGlvbidcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgICAgICAgICAgICAgIHJlbGF0aW9uRmllbGROYW1lcy5tYXAobmFtZSA9PlxuICAgICAgICAgICAgICAgICAgdGhpcy5hZGFwdGVyLmRlbGV0ZUNsYXNzKGpvaW5UYWJsZU5hbWUoY2xhc3NOYW1lLCBuYW1lKSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gVGhpcyBoZWxwcyB0byBjcmVhdGUgaW50ZXJtZWRpYXRlIG9iamVjdHMgZm9yIHNpbXBsZXIgY29tcGFyaXNvbiBvZlxuICAvLyBrZXkgdmFsdWUgcGFpcnMgdXNlZCBpbiBxdWVyeSBvYmplY3RzLiBFYWNoIGtleSB2YWx1ZSBwYWlyIHdpbGwgcmVwcmVzZW50ZWRcbiAgLy8gaW4gYSBzaW1pbGFyIHdheSB0byBqc29uXG4gIG9iamVjdFRvRW50cmllc1N0cmluZ3MocXVlcnk6IGFueSk6IEFycmF5PHN0cmluZz4ge1xuICAgIHJldHVybiBPYmplY3QuZW50cmllcyhxdWVyeSkubWFwKGEgPT4gYS5tYXAocyA9PiBKU09OLnN0cmluZ2lmeShzKSkuam9pbignOicpKTtcbiAgfVxuXG4gIC8vIE5haXZlIGxvZ2ljIHJlZHVjZXIgZm9yIE9SIG9wZXJhdGlvbnMgbWVhbnQgdG8gYmUgdXNlZCBvbmx5IGZvciBwb2ludGVyIHBlcm1pc3Npb25zLlxuICByZWR1Y2VPck9wZXJhdGlvbihxdWVyeTogeyAkb3I6IEFycmF5PGFueT4gfSk6IGFueSB7XG4gICAgaWYgKCFxdWVyeS4kb3IpIHtcbiAgICAgIHJldHVybiBxdWVyeTtcbiAgICB9XG4gICAgY29uc3QgcXVlcmllcyA9IHF1ZXJ5LiRvci5tYXAocSA9PiB0aGlzLm9iamVjdFRvRW50cmllc1N0cmluZ3MocSkpO1xuICAgIGxldCByZXBlYXQgPSBmYWxzZTtcbiAgICBkbyB7XG4gICAgICByZXBlYXQgPSBmYWxzZTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcXVlcmllcy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgZm9yIChsZXQgaiA9IGkgKyAxOyBqIDwgcXVlcmllcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgIGNvbnN0IFtzaG9ydGVyLCBsb25nZXJdID0gcXVlcmllc1tpXS5sZW5ndGggPiBxdWVyaWVzW2pdLmxlbmd0aCA/IFtqLCBpXSA6IFtpLCBqXTtcbiAgICAgICAgICBjb25zdCBmb3VuZEVudHJpZXMgPSBxdWVyaWVzW3Nob3J0ZXJdLnJlZHVjZShcbiAgICAgICAgICAgIChhY2MsIGVudHJ5KSA9PiBhY2MgKyAocXVlcmllc1tsb25nZXJdLmluY2x1ZGVzKGVudHJ5KSA/IDEgOiAwKSxcbiAgICAgICAgICAgIDBcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IHNob3J0ZXJFbnRyaWVzID0gcXVlcmllc1tzaG9ydGVyXS5sZW5ndGg7XG4gICAgICAgICAgaWYgKGZvdW5kRW50cmllcyA9PT0gc2hvcnRlckVudHJpZXMpIHtcbiAgICAgICAgICAgIC8vIElmIHRoZSBzaG9ydGVyIHF1ZXJ5IGlzIGNvbXBsZXRlbHkgY29udGFpbmVkIGluIHRoZSBsb25nZXIgb25lLCB3ZSBjYW4gc3RyaWtlXG4gICAgICAgICAgICAvLyBvdXQgdGhlIGxvbmdlciBxdWVyeS5cbiAgICAgICAgICAgIHF1ZXJ5LiRvci5zcGxpY2UobG9uZ2VyLCAxKTtcbiAgICAgICAgICAgIHF1ZXJpZXMuc3BsaWNlKGxvbmdlciwgMSk7XG4gICAgICAgICAgICByZXBlYXQgPSB0cnVlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSB3aGlsZSAocmVwZWF0KTtcbiAgICBpZiAocXVlcnkuJG9yLmxlbmd0aCA9PT0gMSkge1xuICAgICAgcXVlcnkgPSB7IC4uLnF1ZXJ5LCAuLi5xdWVyeS4kb3JbMF0gfTtcbiAgICAgIGRlbGV0ZSBxdWVyeS4kb3I7XG4gICAgfVxuICAgIHJldHVybiBxdWVyeTtcbiAgfVxuXG4gIC8vIE5haXZlIGxvZ2ljIHJlZHVjZXIgZm9yIEFORCBvcGVyYXRpb25zIG1lYW50IHRvIGJlIHVzZWQgb25seSBmb3IgcG9pbnRlciBwZXJtaXNzaW9ucy5cbiAgcmVkdWNlQW5kT3BlcmF0aW9uKHF1ZXJ5OiB7ICRhbmQ6IEFycmF5PGFueT4gfSk6IGFueSB7XG4gICAgaWYgKCFxdWVyeS4kYW5kKSB7XG4gICAgICByZXR1cm4gcXVlcnk7XG4gICAgfVxuICAgIGNvbnN0IHF1ZXJpZXMgPSBxdWVyeS4kYW5kLm1hcChxID0+IHRoaXMub2JqZWN0VG9FbnRyaWVzU3RyaW5ncyhxKSk7XG4gICAgbGV0IHJlcGVhdCA9IGZhbHNlO1xuICAgIGRvIHtcbiAgICAgIHJlcGVhdCA9IGZhbHNlO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBxdWVyaWVzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICBmb3IgKGxldCBqID0gaSArIDE7IGogPCBxdWVyaWVzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgICAgY29uc3QgW3Nob3J0ZXIsIGxvbmdlcl0gPSBxdWVyaWVzW2ldLmxlbmd0aCA+IHF1ZXJpZXNbal0ubGVuZ3RoID8gW2osIGldIDogW2ksIGpdO1xuICAgICAgICAgIGNvbnN0IGZvdW5kRW50cmllcyA9IHF1ZXJpZXNbc2hvcnRlcl0ucmVkdWNlKFxuICAgICAgICAgICAgKGFjYywgZW50cnkpID0+IGFjYyArIChxdWVyaWVzW2xvbmdlcl0uaW5jbHVkZXMoZW50cnkpID8gMSA6IDApLFxuICAgICAgICAgICAgMFxuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3Qgc2hvcnRlckVudHJpZXMgPSBxdWVyaWVzW3Nob3J0ZXJdLmxlbmd0aDtcbiAgICAgICAgICBpZiAoZm91bmRFbnRyaWVzID09PSBzaG9ydGVyRW50cmllcykge1xuICAgICAgICAgICAgLy8gSWYgdGhlIHNob3J0ZXIgcXVlcnkgaXMgY29tcGxldGVseSBjb250YWluZWQgaW4gdGhlIGxvbmdlciBvbmUsIHdlIGNhbiBzdHJpa2VcbiAgICAgICAgICAgIC8vIG91dCB0aGUgc2hvcnRlciBxdWVyeS5cbiAgICAgICAgICAgIHF1ZXJ5LiRhbmQuc3BsaWNlKHNob3J0ZXIsIDEpO1xuICAgICAgICAgICAgcXVlcmllcy5zcGxpY2Uoc2hvcnRlciwgMSk7XG4gICAgICAgICAgICByZXBlYXQgPSB0cnVlO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSB3aGlsZSAocmVwZWF0KTtcbiAgICBpZiAocXVlcnkuJGFuZC5sZW5ndGggPT09IDEpIHtcbiAgICAgIHF1ZXJ5ID0geyAuLi5xdWVyeSwgLi4ucXVlcnkuJGFuZFswXSB9O1xuICAgICAgZGVsZXRlIHF1ZXJ5LiRhbmQ7XG4gICAgfVxuICAgIHJldHVybiBxdWVyeTtcbiAgfVxuXG4gIC8vIENvbnN0cmFpbnRzIHF1ZXJ5IHVzaW5nIENMUCdzIHBvaW50ZXIgcGVybWlzc2lvbnMgKFBQKSBpZiBhbnkuXG4gIC8vIDEuIEV0cmFjdCB0aGUgdXNlciBpZCBmcm9tIGNhbGxlcidzIEFDTGdyb3VwO1xuICAvLyAyLiBFeGN0cmFjdCBhIGxpc3Qgb2YgZmllbGQgbmFtZXMgdGhhdCBhcmUgUFAgZm9yIHRhcmdldCBjb2xsZWN0aW9uIGFuZCBvcGVyYXRpb247XG4gIC8vIDMuIENvbnN0cmFpbnQgdGhlIG9yaWdpbmFsIHF1ZXJ5IHNvIHRoYXQgZWFjaCBQUCBmaWVsZCBtdXN0XG4gIC8vIHBvaW50IHRvIGNhbGxlcidzIGlkIChvciBjb250YWluIGl0IGluIGNhc2Ugb2YgUFAgZmllbGQgYmVpbmcgYW4gYXJyYXkpXG4gIGFkZFBvaW50ZXJQZXJtaXNzaW9ucyhcbiAgICBzY2hlbWE6IFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlcixcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBvcGVyYXRpb246IHN0cmluZyxcbiAgICBxdWVyeTogYW55LFxuICAgIGFjbEdyb3VwOiBhbnlbXSA9IFtdXG4gICk6IGFueSB7XG4gICAgLy8gQ2hlY2sgaWYgY2xhc3MgaGFzIHB1YmxpYyBwZXJtaXNzaW9uIGZvciBvcGVyYXRpb25cbiAgICAvLyBJZiB0aGUgQmFzZUNMUCBwYXNzLCBsZXQgZ28gdGhyb3VnaFxuICAgIGlmIChzY2hlbWEudGVzdFBlcm1pc3Npb25zRm9yQ2xhc3NOYW1lKGNsYXNzTmFtZSwgYWNsR3JvdXAsIG9wZXJhdGlvbikpIHtcbiAgICAgIHJldHVybiBxdWVyeTtcbiAgICB9XG4gICAgY29uc3QgcGVybXMgPSBzY2hlbWEuZ2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zKGNsYXNzTmFtZSk7XG5cbiAgICBjb25zdCB1c2VyQUNMID0gYWNsR3JvdXAuZmlsdGVyKGFjbCA9PiB7XG4gICAgICByZXR1cm4gYWNsLmluZGV4T2YoJ3JvbGU6JykgIT0gMCAmJiBhY2wgIT0gJyonO1xuICAgIH0pO1xuXG4gICAgY29uc3QgZ3JvdXBLZXkgPVxuICAgICAgWydnZXQnLCAnZmluZCcsICdjb3VudCddLmluZGV4T2Yob3BlcmF0aW9uKSA+IC0xID8gJ3JlYWRVc2VyRmllbGRzJyA6ICd3cml0ZVVzZXJGaWVsZHMnO1xuXG4gICAgY29uc3QgcGVybUZpZWxkcyA9IFtdO1xuXG4gICAgaWYgKHBlcm1zW29wZXJhdGlvbl0gJiYgcGVybXNbb3BlcmF0aW9uXS5wb2ludGVyRmllbGRzKSB7XG4gICAgICBwZXJtRmllbGRzLnB1c2goLi4ucGVybXNbb3BlcmF0aW9uXS5wb2ludGVyRmllbGRzKTtcbiAgICB9XG5cbiAgICBpZiAocGVybXNbZ3JvdXBLZXldKSB7XG4gICAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIHBlcm1zW2dyb3VwS2V5XSkge1xuICAgICAgICBpZiAoIXBlcm1GaWVsZHMuaW5jbHVkZXMoZmllbGQpKSB7XG4gICAgICAgICAgcGVybUZpZWxkcy5wdXNoKGZpZWxkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyB0aGUgQUNMIHNob3VsZCBoYXZlIGV4YWN0bHkgMSB1c2VyXG4gICAgaWYgKHBlcm1GaWVsZHMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gdGhlIEFDTCBzaG91bGQgaGF2ZSBleGFjdGx5IDEgdXNlclxuICAgICAgLy8gTm8gdXNlciBzZXQgcmV0dXJuIHVuZGVmaW5lZFxuICAgICAgLy8gSWYgdGhlIGxlbmd0aCBpcyA+IDEsIHRoYXQgbWVhbnMgd2UgZGlkbid0IGRlLWR1cGUgdXNlcnMgY29ycmVjdGx5XG4gICAgICBpZiAodXNlckFDTC5sZW5ndGggIT0gMSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCB1c2VySWQgPSB1c2VyQUNMWzBdO1xuICAgICAgY29uc3QgdXNlclBvaW50ZXIgPSB7XG4gICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICBjbGFzc05hbWU6ICdfVXNlcicsXG4gICAgICAgIG9iamVjdElkOiB1c2VySWQsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBxdWVyaWVzID0gcGVybUZpZWxkcy5tYXAoa2V5ID0+IHtcbiAgICAgICAgY29uc3QgZmllbGREZXNjcmlwdG9yID0gc2NoZW1hLmdldEV4cGVjdGVkVHlwZShjbGFzc05hbWUsIGtleSk7XG4gICAgICAgIGNvbnN0IGZpZWxkVHlwZSA9XG4gICAgICAgICAgZmllbGREZXNjcmlwdG9yICYmXG4gICAgICAgICAgdHlwZW9mIGZpZWxkRGVzY3JpcHRvciA9PT0gJ29iamVjdCcgJiZcbiAgICAgICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZmllbGREZXNjcmlwdG9yLCAndHlwZScpXG4gICAgICAgICAgICA/IGZpZWxkRGVzY3JpcHRvci50eXBlXG4gICAgICAgICAgICA6IG51bGw7XG5cbiAgICAgICAgbGV0IHF1ZXJ5Q2xhdXNlO1xuXG4gICAgICAgIGlmIChmaWVsZFR5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgICAgIC8vIGNvbnN0cmFpbnQgZm9yIHNpbmdsZSBwb2ludGVyIHNldHVwXG4gICAgICAgICAgcXVlcnlDbGF1c2UgPSB7IFtrZXldOiB1c2VyUG9pbnRlciB9O1xuICAgICAgICB9IGVsc2UgaWYgKGZpZWxkVHlwZSA9PT0gJ0FycmF5Jykge1xuICAgICAgICAgIC8vIGNvbnN0cmFpbnQgZm9yIHVzZXJzLWFycmF5IHNldHVwXG4gICAgICAgICAgcXVlcnlDbGF1c2UgPSB7IFtrZXldOiB7ICRhbGw6IFt1c2VyUG9pbnRlcl0gfSB9O1xuICAgICAgICB9IGVsc2UgaWYgKGZpZWxkVHlwZSA9PT0gJ09iamVjdCcpIHtcbiAgICAgICAgICAvLyBjb25zdHJhaW50IGZvciBvYmplY3Qgc2V0dXBcbiAgICAgICAgICBxdWVyeUNsYXVzZSA9IHsgW2tleV06IHVzZXJQb2ludGVyIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gVGhpcyBtZWFucyB0aGF0IHRoZXJlIGlzIGEgQ0xQIGZpZWxkIG9mIGFuIHVuZXhwZWN0ZWQgdHlwZS4gVGhpcyBjb25kaXRpb24gc2hvdWxkIG5vdCBoYXBwZW4sIHdoaWNoIGlzXG4gICAgICAgICAgLy8gd2h5IGlzIGJlaW5nIHRyZWF0ZWQgYXMgYW4gZXJyb3IuXG4gICAgICAgICAgdGhyb3cgRXJyb3IoXG4gICAgICAgICAgICBgQW4gdW5leHBlY3RlZCBjb25kaXRpb24gb2NjdXJyZWQgd2hlbiByZXNvbHZpbmcgcG9pbnRlciBwZXJtaXNzaW9uczogJHtjbGFzc05hbWV9ICR7a2V5fWBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIC8vIGlmIHdlIGFscmVhZHkgaGF2ZSBhIGNvbnN0cmFpbnQgb24gdGhlIGtleSwgdXNlIHRoZSAkYW5kXG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocXVlcnksIGtleSkpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5yZWR1Y2VBbmRPcGVyYXRpb24oeyAkYW5kOiBbcXVlcnlDbGF1c2UsIHF1ZXJ5XSB9KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBvdGhlcndpc2UganVzdCBhZGQgdGhlIGNvbnN0YWludFxuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgcXVlcnksIHF1ZXJ5Q2xhdXNlKTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gcXVlcmllcy5sZW5ndGggPT09IDEgPyBxdWVyaWVzWzBdIDogdGhpcy5yZWR1Y2VPck9wZXJhdGlvbih7ICRvcjogcXVlcmllcyB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHF1ZXJ5O1xuICAgIH1cbiAgfVxuXG4gIGFkZFByb3RlY3RlZEZpZWxkcyhcbiAgICBzY2hlbWE6IFNjaGVtYUNvbnRyb2xsZXIuU2NoZW1hQ29udHJvbGxlcixcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBxdWVyeTogYW55ID0ge30sXG4gICAgYWNsR3JvdXA6IGFueVtdID0gW10sXG4gICAgYXV0aDogYW55ID0ge30sXG4gICAgcXVlcnlPcHRpb25zOiBGdWxsUXVlcnlPcHRpb25zID0ge31cbiAgKTogbnVsbCB8IHN0cmluZ1tdIHtcbiAgICBjb25zdCBwZXJtcyA9IHNjaGVtYS5nZXRDbGFzc0xldmVsUGVybWlzc2lvbnMoY2xhc3NOYW1lKTtcbiAgICBpZiAoIXBlcm1zKSByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IHByb3RlY3RlZEZpZWxkcyA9IHBlcm1zLnByb3RlY3RlZEZpZWxkcztcbiAgICBpZiAoIXByb3RlY3RlZEZpZWxkcykgcmV0dXJuIG51bGw7XG5cbiAgICBpZiAoYWNsR3JvdXAuaW5kZXhPZihxdWVyeS5vYmplY3RJZCkgPiAtMSkgcmV0dXJuIG51bGw7XG5cbiAgICAvLyBmb3IgcXVlcmllcyB3aGVyZSBcImtleXNcIiBhcmUgc2V0IGFuZCBkbyBub3QgaW5jbHVkZSBhbGwgJ3VzZXJGaWVsZCc6e2ZpZWxkfSxcbiAgICAvLyB3ZSBoYXZlIHRvIHRyYW5zcGFyZW50bHkgaW5jbHVkZSBpdCwgYW5kIHRoZW4gcmVtb3ZlIGJlZm9yZSByZXR1cm5pbmcgdG8gY2xpZW50XG4gICAgLy8gQmVjYXVzZSBpZiBzdWNoIGtleSBub3QgcHJvamVjdGVkIHRoZSBwZXJtaXNzaW9uIHdvbid0IGJlIGVuZm9yY2VkIHByb3Blcmx5XG4gICAgLy8gUFMgdGhpcyBpcyBjYWxsZWQgd2hlbiAnZXhjbHVkZUtleXMnIGFscmVhZHkgcmVkdWNlZCB0byAna2V5cydcbiAgICBjb25zdCBwcmVzZXJ2ZUtleXMgPSBxdWVyeU9wdGlvbnMua2V5cztcblxuICAgIC8vIHRoZXNlIGFyZSBrZXlzIHRoYXQgbmVlZCB0byBiZSBpbmNsdWRlZCBvbmx5XG4gICAgLy8gdG8gYmUgYWJsZSB0byBhcHBseSBwcm90ZWN0ZWRGaWVsZHMgYnkgcG9pbnRlclxuICAgIC8vIGFuZCB0aGVuIHVuc2V0IGJlZm9yZSByZXR1cm5pbmcgdG8gY2xpZW50IChsYXRlciBpbiAgZmlsdGVyU2Vuc2l0aXZlRmllbGRzKVxuICAgIGNvbnN0IHNlcnZlck9ubHlLZXlzID0gW107XG5cbiAgICBjb25zdCBhdXRoZW50aWNhdGVkID0gYXV0aC51c2VyO1xuXG4gICAgLy8gbWFwIHRvIGFsbG93IGNoZWNrIHdpdGhvdXQgYXJyYXkgc2VhcmNoXG4gICAgY29uc3Qgcm9sZXMgPSAoYXV0aC51c2VyUm9sZXMgfHwgW10pLnJlZHVjZSgoYWNjLCByKSA9PiB7XG4gICAgICBhY2Nbcl0gPSBwcm90ZWN0ZWRGaWVsZHNbcl07XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHt9KTtcblxuICAgIC8vIGFycmF5IG9mIHNldHMgb2YgcHJvdGVjdGVkIGZpZWxkcy4gc2VwYXJhdGUgaXRlbSBmb3IgZWFjaCBhcHBsaWNhYmxlIGNyaXRlcmlhXG4gICAgY29uc3QgcHJvdGVjdGVkS2V5c1NldHMgPSBbXTtcblxuICAgIGZvciAoY29uc3Qga2V5IGluIHByb3RlY3RlZEZpZWxkcykge1xuICAgICAgLy8gc2tpcCB1c2VyRmllbGRzXG4gICAgICBpZiAoa2V5LnN0YXJ0c1dpdGgoJ3VzZXJGaWVsZDonKSkge1xuICAgICAgICBpZiAocHJlc2VydmVLZXlzKSB7XG4gICAgICAgICAgY29uc3QgZmllbGROYW1lID0ga2V5LnN1YnN0cmluZygxMCk7XG4gICAgICAgICAgaWYgKCFwcmVzZXJ2ZUtleXMuaW5jbHVkZXMoZmllbGROYW1lKSkge1xuICAgICAgICAgICAgLy8gMS4gcHV0IGl0IHRoZXJlIHRlbXBvcmFyaWx5XG4gICAgICAgICAgICBxdWVyeU9wdGlvbnMua2V5cyAmJiBxdWVyeU9wdGlvbnMua2V5cy5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICAgICAgICAvLyAyLiBwcmVzZXJ2ZSBpdCBkZWxldGUgbGF0ZXJcbiAgICAgICAgICAgIHNlcnZlck9ubHlLZXlzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGFkZCBwdWJsaWMgdGllclxuICAgICAgaWYgKGtleSA9PT0gJyonKSB7XG4gICAgICAgIHByb3RlY3RlZEtleXNTZXRzLnB1c2gocHJvdGVjdGVkRmllbGRzW2tleV0pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGF1dGhlbnRpY2F0ZWQpIHtcbiAgICAgICAgaWYgKGtleSA9PT0gJ2F1dGhlbnRpY2F0ZWQnKSB7XG4gICAgICAgICAgLy8gZm9yIGxvZ2dlZCBpbiB1c2Vyc1xuICAgICAgICAgIHByb3RlY3RlZEtleXNTZXRzLnB1c2gocHJvdGVjdGVkRmllbGRzW2tleV0pO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJvbGVzW2tleV0gJiYga2V5LnN0YXJ0c1dpdGgoJ3JvbGU6JykpIHtcbiAgICAgICAgICAvLyBhZGQgYXBwbGljYWJsZSByb2xlc1xuICAgICAgICAgIHByb3RlY3RlZEtleXNTZXRzLnB1c2gocm9sZXNba2V5XSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBjaGVjayBpZiB0aGVyZSdzIGEgcnVsZSBmb3IgY3VycmVudCB1c2VyJ3MgaWRcbiAgICBpZiAoYXV0aGVudGljYXRlZCkge1xuICAgICAgY29uc3QgdXNlcklkID0gYXV0aC51c2VyLmlkO1xuICAgICAgaWYgKHBlcm1zLnByb3RlY3RlZEZpZWxkc1t1c2VySWRdKSB7XG4gICAgICAgIHByb3RlY3RlZEtleXNTZXRzLnB1c2gocGVybXMucHJvdGVjdGVkRmllbGRzW3VzZXJJZF0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHByZXNlcnZlIGZpZWxkcyB0byBiZSByZW1vdmVkIGJlZm9yZSBzZW5kaW5nIHJlc3BvbnNlIHRvIGNsaWVudFxuICAgIGlmIChzZXJ2ZXJPbmx5S2V5cy5sZW5ndGggPiAwKSB7XG4gICAgICBwZXJtcy5wcm90ZWN0ZWRGaWVsZHMudGVtcG9yYXJ5S2V5cyA9IHNlcnZlck9ubHlLZXlzO1xuICAgIH1cblxuICAgIGxldCBwcm90ZWN0ZWRLZXlzID0gcHJvdGVjdGVkS2V5c1NldHMucmVkdWNlKChhY2MsIG5leHQpID0+IHtcbiAgICAgIGlmIChuZXh0KSB7XG4gICAgICAgIGFjYy5wdXNoKC4uLm5leHQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCBbXSk7XG5cbiAgICAvLyBpbnRlcnNlY3QgYWxsIHNldHMgb2YgcHJvdGVjdGVkRmllbGRzXG4gICAgcHJvdGVjdGVkS2V5c1NldHMuZm9yRWFjaChmaWVsZHMgPT4ge1xuICAgICAgaWYgKGZpZWxkcykge1xuICAgICAgICBwcm90ZWN0ZWRLZXlzID0gcHJvdGVjdGVkS2V5cy5maWx0ZXIodiA9PiBmaWVsZHMuaW5jbHVkZXModikpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHByb3RlY3RlZEtleXM7XG4gIH1cblxuICBjcmVhdGVUcmFuc2FjdGlvbmFsU2Vzc2lvbigpIHtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uKCkudGhlbih0cmFuc2FjdGlvbmFsU2Vzc2lvbiA9PiB7XG4gICAgICB0aGlzLl90cmFuc2FjdGlvbmFsU2Vzc2lvbiA9IHRyYW5zYWN0aW9uYWxTZXNzaW9uO1xuICAgIH0pO1xuICB9XG5cbiAgY29tbWl0VHJhbnNhY3Rpb25hbFNlc3Npb24oKSB7XG4gICAgaWYgKCF0aGlzLl90cmFuc2FjdGlvbmFsU2Vzc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGVyZSBpcyBubyB0cmFuc2FjdGlvbmFsIHNlc3Npb24gdG8gY29tbWl0Jyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuY29tbWl0VHJhbnNhY3Rpb25hbFNlc3Npb24odGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb24pLnRoZW4oKCkgPT4ge1xuICAgICAgdGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb24gPSBudWxsO1xuICAgIH0pO1xuICB9XG5cbiAgYWJvcnRUcmFuc2FjdGlvbmFsU2Vzc2lvbigpIHtcbiAgICBpZiAoIXRoaXMuX3RyYW5zYWN0aW9uYWxTZXNzaW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZXJlIGlzIG5vIHRyYW5zYWN0aW9uYWwgc2Vzc2lvbiB0byBhYm9ydCcpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmFib3J0VHJhbnNhY3Rpb25hbFNlc3Npb24odGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb24pLnRoZW4oKCkgPT4ge1xuICAgICAgdGhpcy5fdHJhbnNhY3Rpb25hbFNlc3Npb24gPSBudWxsO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gVE9ETzogY3JlYXRlIGluZGV4ZXMgb24gZmlyc3QgY3JlYXRpb24gb2YgYSBfVXNlciBvYmplY3QuIE90aGVyd2lzZSBpdCdzIGltcG9zc2libGUgdG9cbiAgLy8gaGF2ZSBhIFBhcnNlIGFwcCB3aXRob3V0IGl0IGhhdmluZyBhIF9Vc2VyIGNvbGxlY3Rpb24uXG4gIHBlcmZvcm1Jbml0aWFsaXphdGlvbigpIHtcbiAgICBjb25zdCByZXF1aXJlZFVzZXJGaWVsZHMgPSB7XG4gICAgICBmaWVsZHM6IHtcbiAgICAgICAgLi4uU2NoZW1hQ29udHJvbGxlci5kZWZhdWx0Q29sdW1ucy5fRGVmYXVsdCxcbiAgICAgICAgLi4uU2NoZW1hQ29udHJvbGxlci5kZWZhdWx0Q29sdW1ucy5fVXNlcixcbiAgICAgIH0sXG4gICAgfTtcbiAgICBjb25zdCByZXF1aXJlZFJvbGVGaWVsZHMgPSB7XG4gICAgICBmaWVsZHM6IHtcbiAgICAgICAgLi4uU2NoZW1hQ29udHJvbGxlci5kZWZhdWx0Q29sdW1ucy5fRGVmYXVsdCxcbiAgICAgICAgLi4uU2NoZW1hQ29udHJvbGxlci5kZWZhdWx0Q29sdW1ucy5fUm9sZSxcbiAgICAgIH0sXG4gICAgfTtcbiAgICBjb25zdCByZXF1aXJlZElkZW1wb3RlbmN5RmllbGRzID0ge1xuICAgICAgZmllbGRzOiB7XG4gICAgICAgIC4uLlNjaGVtYUNvbnRyb2xsZXIuZGVmYXVsdENvbHVtbnMuX0RlZmF1bHQsXG4gICAgICAgIC4uLlNjaGVtYUNvbnRyb2xsZXIuZGVmYXVsdENvbHVtbnMuX0lkZW1wb3RlbmN5LFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgY29uc3QgdXNlckNsYXNzUHJvbWlzZSA9IHRoaXMubG9hZFNjaGVtYSgpLnRoZW4oc2NoZW1hID0+IHNjaGVtYS5lbmZvcmNlQ2xhc3NFeGlzdHMoJ19Vc2VyJykpO1xuICAgIGNvbnN0IHJvbGVDbGFzc1Byb21pc2UgPSB0aGlzLmxvYWRTY2hlbWEoKS50aGVuKHNjaGVtYSA9PiBzY2hlbWEuZW5mb3JjZUNsYXNzRXhpc3RzKCdfUm9sZScpKTtcbiAgICBjb25zdCBpZGVtcG90ZW5jeUNsYXNzUHJvbWlzZSA9XG4gICAgICB0aGlzLmFkYXB0ZXIgaW5zdGFuY2VvZiBNb25nb1N0b3JhZ2VBZGFwdGVyXG4gICAgICAgID8gdGhpcy5sb2FkU2NoZW1hKCkudGhlbihzY2hlbWEgPT4gc2NoZW1hLmVuZm9yY2VDbGFzc0V4aXN0cygnX0lkZW1wb3RlbmN5JykpXG4gICAgICAgIDogUHJvbWlzZS5yZXNvbHZlKCk7XG5cbiAgICBjb25zdCB1c2VybmFtZVVuaXF1ZW5lc3MgPSB1c2VyQ2xhc3NQcm9taXNlXG4gICAgICAudGhlbigoKSA9PiB0aGlzLmFkYXB0ZXIuZW5zdXJlVW5pcXVlbmVzcygnX1VzZXInLCByZXF1aXJlZFVzZXJGaWVsZHMsIFsndXNlcm5hbWUnXSkpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBsb2dnZXIud2FybignVW5hYmxlIHRvIGVuc3VyZSB1bmlxdWVuZXNzIGZvciB1c2VybmFtZXM6ICcsIGVycm9yKTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcblxuICAgIGNvbnN0IHVzZXJuYW1lQ2FzZUluc2Vuc2l0aXZlSW5kZXggPSB1c2VyQ2xhc3NQcm9taXNlXG4gICAgICAudGhlbigoKSA9PlxuICAgICAgICB0aGlzLmFkYXB0ZXIuZW5zdXJlSW5kZXgoXG4gICAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAgICByZXF1aXJlZFVzZXJGaWVsZHMsXG4gICAgICAgICAgWyd1c2VybmFtZSddLFxuICAgICAgICAgICdjYXNlX2luc2Vuc2l0aXZlX3VzZXJuYW1lJyxcbiAgICAgICAgICB0cnVlXG4gICAgICAgIClcbiAgICAgIClcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdVbmFibGUgdG8gY3JlYXRlIGNhc2UgaW5zZW5zaXRpdmUgdXNlcm5hbWUgaW5kZXg6ICcsIGVycm9yKTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcblxuICAgIGNvbnN0IGVtYWlsVW5pcXVlbmVzcyA9IHVzZXJDbGFzc1Byb21pc2VcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuYWRhcHRlci5lbnN1cmVVbmlxdWVuZXNzKCdfVXNlcicsIHJlcXVpcmVkVXNlckZpZWxkcywgWydlbWFpbCddKSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdVbmFibGUgdG8gZW5zdXJlIHVuaXF1ZW5lc3MgZm9yIHVzZXIgZW1haWwgYWRkcmVzc2VzOiAnLCBlcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG5cbiAgICBjb25zdCBlbWFpbENhc2VJbnNlbnNpdGl2ZUluZGV4ID0gdXNlckNsYXNzUHJvbWlzZVxuICAgICAgLnRoZW4oKCkgPT5cbiAgICAgICAgdGhpcy5hZGFwdGVyLmVuc3VyZUluZGV4KFxuICAgICAgICAgICdfVXNlcicsXG4gICAgICAgICAgcmVxdWlyZWRVc2VyRmllbGRzLFxuICAgICAgICAgIFsnZW1haWwnXSxcbiAgICAgICAgICAnY2FzZV9pbnNlbnNpdGl2ZV9lbWFpbCcsXG4gICAgICAgICAgdHJ1ZVxuICAgICAgICApXG4gICAgICApXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBsb2dnZXIud2FybignVW5hYmxlIHRvIGNyZWF0ZSBjYXNlIGluc2Vuc2l0aXZlIGVtYWlsIGluZGV4OiAnLCBlcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG5cbiAgICBjb25zdCByb2xlVW5pcXVlbmVzcyA9IHJvbGVDbGFzc1Byb21pc2VcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuYWRhcHRlci5lbnN1cmVVbmlxdWVuZXNzKCdfUm9sZScsIHJlcXVpcmVkUm9sZUZpZWxkcywgWyduYW1lJ10pKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1VuYWJsZSB0byBlbnN1cmUgdW5pcXVlbmVzcyBmb3Igcm9sZSBuYW1lOiAnLCBlcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG5cbiAgICBjb25zdCBpZGVtcG90ZW5jeVJlcXVlc3RJZEluZGV4ID1cbiAgICAgIHRoaXMuYWRhcHRlciBpbnN0YW5jZW9mIE1vbmdvU3RvcmFnZUFkYXB0ZXJcbiAgICAgICAgPyBpZGVtcG90ZW5jeUNsYXNzUHJvbWlzZVxuICAgICAgICAgIC50aGVuKCgpID0+XG4gICAgICAgICAgICB0aGlzLmFkYXB0ZXIuZW5zdXJlVW5pcXVlbmVzcygnX0lkZW1wb3RlbmN5JywgcmVxdWlyZWRJZGVtcG90ZW5jeUZpZWxkcywgWydyZXFJZCddKVxuICAgICAgICAgIClcbiAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ1VuYWJsZSB0byBlbnN1cmUgdW5pcXVlbmVzcyBmb3IgaWRlbXBvdGVuY3kgcmVxdWVzdCBJRDogJywgZXJyb3IpO1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfSlcbiAgICAgICAgOiBQcm9taXNlLnJlc29sdmUoKTtcblxuICAgIGNvbnN0IGlkZW1wb3RlbmN5RXhwaXJlSW5kZXggPVxuICAgICAgdGhpcy5hZGFwdGVyIGluc3RhbmNlb2YgTW9uZ29TdG9yYWdlQWRhcHRlclxuICAgICAgICA/IGlkZW1wb3RlbmN5Q2xhc3NQcm9taXNlXG4gICAgICAgICAgLnRoZW4oKCkgPT5cbiAgICAgICAgICAgIHRoaXMuYWRhcHRlci5lbnN1cmVJbmRleChcbiAgICAgICAgICAgICAgJ19JZGVtcG90ZW5jeScsXG4gICAgICAgICAgICAgIHJlcXVpcmVkSWRlbXBvdGVuY3lGaWVsZHMsXG4gICAgICAgICAgICAgIFsnZXhwaXJlJ10sXG4gICAgICAgICAgICAgICd0dGwnLFxuICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgeyB0dGw6IDAgfVxuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ1VuYWJsZSB0byBjcmVhdGUgVFRMIGluZGV4IGZvciBpZGVtcG90ZW5jeSBleHBpcmUgZGF0ZTogJywgZXJyb3IpO1xuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgICAgfSlcbiAgICAgICAgOiBQcm9taXNlLnJlc29sdmUoKTtcblxuICAgIGNvbnN0IGluZGV4UHJvbWlzZSA9IHRoaXMuYWRhcHRlci51cGRhdGVTY2hlbWFXaXRoSW5kZXhlcygpO1xuXG4gICAgLy8gQ3JlYXRlIHRhYmxlcyBmb3Igdm9sYXRpbGUgY2xhc3Nlc1xuICAgIGNvbnN0IGFkYXB0ZXJJbml0ID0gdGhpcy5hZGFwdGVyLnBlcmZvcm1Jbml0aWFsaXphdGlvbih7XG4gICAgICBWb2xhdGlsZUNsYXNzZXNTY2hlbWFzOiBTY2hlbWFDb250cm9sbGVyLlZvbGF0aWxlQ2xhc3Nlc1NjaGVtYXMsXG4gICAgfSk7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKFtcbiAgICAgIHVzZXJuYW1lVW5pcXVlbmVzcyxcbiAgICAgIHVzZXJuYW1lQ2FzZUluc2Vuc2l0aXZlSW5kZXgsXG4gICAgICBlbWFpbFVuaXF1ZW5lc3MsXG4gICAgICBlbWFpbENhc2VJbnNlbnNpdGl2ZUluZGV4LFxuICAgICAgcm9sZVVuaXF1ZW5lc3MsXG4gICAgICBpZGVtcG90ZW5jeVJlcXVlc3RJZEluZGV4LFxuICAgICAgaWRlbXBvdGVuY3lFeHBpcmVJbmRleCxcbiAgICAgIGFkYXB0ZXJJbml0LFxuICAgICAgaW5kZXhQcm9taXNlLFxuICAgIF0pO1xuICB9XG5cbiAgc3RhdGljIF92YWxpZGF0ZVF1ZXJ5OiBhbnkgPT4gdm9pZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBEYXRhYmFzZUNvbnRyb2xsZXI7XG4vLyBFeHBvc2UgdmFsaWRhdGVRdWVyeSBmb3IgdGVzdHNcbm1vZHVsZS5leHBvcnRzLl92YWxpZGF0ZVF1ZXJ5ID0gdmFsaWRhdGVRdWVyeTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/FilesController.js b/lib/Controllers/FilesController.js deleted file mode 100644 index a5e3b29465..0000000000 --- a/lib/Controllers/FilesController.js +++ /dev/null @@ -1,136 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.FilesController = void 0; - -var _cryptoUtils = require("../cryptoUtils"); - -var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); - -var _FilesAdapter = require("../Adapters/Files/FilesAdapter"); - -var _path = _interopRequireDefault(require("path")); - -var _mime = _interopRequireDefault(require("mime")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// FilesController.js -const Parse = require('parse').Parse; - -const legacyFilesRegex = new RegExp('^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}-.*'); - -class FilesController extends _AdaptableController.default { - getFileData(config, filename) { - return this.adapter.getFileData(filename); - } - - createFile(config, filename, data, contentType, options) { - const extname = _path.default.extname(filename); - - const hasExtension = extname.length > 0; - - if (!hasExtension && contentType && _mime.default.getExtension(contentType)) { - filename = filename + '.' + _mime.default.getExtension(contentType); - } else if (hasExtension && !contentType) { - contentType = _mime.default.getType(filename); - } - - if (!this.options.preserveFileName) { - filename = (0, _cryptoUtils.randomHexString)(32) + '_' + filename; - } - - const location = this.adapter.getFileLocation(config, filename); - return this.adapter.createFile(filename, data, contentType, options).then(() => { - return Promise.resolve({ - url: location, - name: filename - }); - }); - } - - deleteFile(config, filename) { - return this.adapter.deleteFile(filename); - } - - getMetadata(filename) { - if (typeof this.adapter.getMetadata === 'function') { - return this.adapter.getMetadata(filename); - } - - return Promise.resolve({}); - } - /** - * Find file references in REST-format object and adds the url key - * with the current mount point and app id. - * Object may be a single object or list of REST-format objects. - */ - - - expandFilesInObject(config, object) { - if (object instanceof Array) { - object.map(obj => this.expandFilesInObject(config, obj)); - return; - } - - if (typeof object !== 'object') { - return; - } - - for (const key in object) { - const fileObject = object[key]; - - if (fileObject && fileObject['__type'] === 'File') { - if (fileObject['url']) { - continue; - } - - const filename = fileObject['name']; // all filenames starting with "tfss-" should be from files.parsetfss.com - // all filenames starting with a "-" seperated UUID should be from files.parse.com - // all other filenames have been migrated or created from Parse Server - - if (config.fileKey === undefined) { - fileObject['url'] = this.adapter.getFileLocation(config, filename); - } else { - if (filename.indexOf('tfss-') === 0) { - fileObject['url'] = 'http://files.parsetfss.com/' + config.fileKey + '/' + encodeURIComponent(filename); - } else if (legacyFilesRegex.test(filename)) { - fileObject['url'] = 'http://files.parse.com/' + config.fileKey + '/' + encodeURIComponent(filename); - } else { - fileObject['url'] = this.adapter.getFileLocation(config, filename); - } - } - } - } - } - - expectedAdapterType() { - return _FilesAdapter.FilesAdapter; - } - - handleFileStream(config, filename, req, res, contentType) { - return this.adapter.handleFileStream(filename, req, res, contentType); - } - - validateFilename(filename) { - if (typeof this.adapter.validateFilename === 'function') { - const error = this.adapter.validateFilename(filename); - - if (typeof error !== 'string') { - return error; - } - - return new Parse.Error(Parse.Error.INVALID_FILE_NAME, error); - } - - return (0, _FilesAdapter.validateFilename)(filename); - } - -} - -exports.FilesController = FilesController; -var _default = FilesController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9GaWxlc0NvbnRyb2xsZXIuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwibGVnYWN5RmlsZXNSZWdleCIsIlJlZ0V4cCIsIkZpbGVzQ29udHJvbGxlciIsIkFkYXB0YWJsZUNvbnRyb2xsZXIiLCJnZXRGaWxlRGF0YSIsImNvbmZpZyIsImZpbGVuYW1lIiwiYWRhcHRlciIsImNyZWF0ZUZpbGUiLCJkYXRhIiwiY29udGVudFR5cGUiLCJvcHRpb25zIiwiZXh0bmFtZSIsInBhdGgiLCJoYXNFeHRlbnNpb24iLCJsZW5ndGgiLCJtaW1lIiwiZ2V0RXh0ZW5zaW9uIiwiZ2V0VHlwZSIsInByZXNlcnZlRmlsZU5hbWUiLCJsb2NhdGlvbiIsImdldEZpbGVMb2NhdGlvbiIsInRoZW4iLCJQcm9taXNlIiwicmVzb2x2ZSIsInVybCIsIm5hbWUiLCJkZWxldGVGaWxlIiwiZ2V0TWV0YWRhdGEiLCJleHBhbmRGaWxlc0luT2JqZWN0Iiwib2JqZWN0IiwiQXJyYXkiLCJtYXAiLCJvYmoiLCJrZXkiLCJmaWxlT2JqZWN0IiwiZmlsZUtleSIsInVuZGVmaW5lZCIsImluZGV4T2YiLCJlbmNvZGVVUklDb21wb25lbnQiLCJ0ZXN0IiwiZXhwZWN0ZWRBZGFwdGVyVHlwZSIsIkZpbGVzQWRhcHRlciIsImhhbmRsZUZpbGVTdHJlYW0iLCJyZXEiLCJyZXMiLCJ2YWxpZGF0ZUZpbGVuYW1lIiwiZXJyb3IiLCJFcnJvciIsIklOVkFMSURfRklMRV9OQU1FIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFMQTtBQU1BLE1BQU1BLEtBQUssR0FBR0MsT0FBTyxDQUFDLE9BQUQsQ0FBUCxDQUFpQkQsS0FBL0I7O0FBRUEsTUFBTUUsZ0JBQWdCLEdBQUcsSUFBSUMsTUFBSixDQUN2QixpRkFEdUIsQ0FBekI7O0FBSU8sTUFBTUMsZUFBTixTQUE4QkMsNEJBQTlCLENBQWtEO0FBQ3ZE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QUFDeEMsUUFBRCxFQUFXO0FBQ3pCLFFBQUksT0FBTyxLQUFLQyxPQUFMLENBQWF1QyxnQkFBcEIsS0FBeUMsVUFBN0MsRUFBeUQ7QUFDdkQsWUFBTUMsS0FBSyxHQUFHLEtBQUt4QyxPQUFMLENBQWF1QyxnQkFBYixDQUE4QnhDLFFBQTlCLENBQWQ7O0FBQ0EsVUFBSSxPQUFPeUMsS0FBUCxLQUFpQixRQUFyQixFQUErQjtBQUM3QixlQUFPQSxLQUFQO0FBQ0Q7O0FBQ0QsYUFBTyxJQUFJakQsS0FBSyxDQUFDa0QsS0FBVixDQUFnQmxELEtBQUssQ0FBQ2tELEtBQU4sQ0FBWUMsaUJBQTVCLEVBQStDRixLQUEvQyxDQUFQO0FBQ0Q7O0FBQ0QsV0FBTyxvQ0FBaUJ6QyxRQUFqQixDQUFQO0FBQ0Q7O0FBakdzRDs7O2VBb0cxQ0osZSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEZpbGVzQ29udHJvbGxlci5qc1xuaW1wb3J0IHsgcmFuZG9tSGV4U3RyaW5nIH0gZnJvbSAnLi4vY3J5cHRvVXRpbHMnO1xuaW1wb3J0IEFkYXB0YWJsZUNvbnRyb2xsZXIgZnJvbSAnLi9BZGFwdGFibGVDb250cm9sbGVyJztcbmltcG9ydCB7IHZhbGlkYXRlRmlsZW5hbWUsIEZpbGVzQWRhcHRlciB9IGZyb20gJy4uL0FkYXB0ZXJzL0ZpbGVzL0ZpbGVzQWRhcHRlcic7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCBtaW1lIGZyb20gJ21pbWUnO1xuY29uc3QgUGFyc2UgPSByZXF1aXJlKCdwYXJzZScpLlBhcnNlO1xuXG5jb25zdCBsZWdhY3lGaWxlc1JlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgJ15bMC05YS1mQS1GXXs4fS1bMC05YS1mQS1GXXs0fS1bMC05YS1mQS1GXXs0fS1bMC05YS1mQS1GXXs0fS1bMC05YS1mQS1GXXsxMn0tLionXG4pO1xuXG5leHBvcnQgY2xhc3MgRmlsZXNDb250cm9sbGVyIGV4dGVuZHMgQWRhcHRhYmxlQ29udHJvbGxlciB7XG4gIGdldEZpbGVEYXRhKGNvbmZpZywgZmlsZW5hbWUpIHtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmdldEZpbGVEYXRhKGZpbGVuYW1lKTtcbiAgfVxuXG4gIGNyZWF0ZUZpbGUoY29uZmlnLCBmaWxlbmFtZSwgZGF0YSwgY29udGVudFR5cGUsIG9wdGlvbnMpIHtcbiAgICBjb25zdCBleHRuYW1lID0gcGF0aC5leHRuYW1lKGZpbGVuYW1lKTtcblxuICAgIGNvbnN0IGhhc0V4dGVuc2lvbiA9IGV4dG5hbWUubGVuZ3RoID4gMDtcblxuICAgIGlmICghaGFzRXh0ZW5zaW9uICYmIGNvbnRlbnRUeXBlICYmIG1pbWUuZ2V0RXh0ZW5zaW9uKGNvbnRlbnRUeXBlKSkge1xuICAgICAgZmlsZW5hbWUgPSBmaWxlbmFtZSArICcuJyArIG1pbWUuZ2V0RXh0ZW5zaW9uKGNvbnRlbnRUeXBlKTtcbiAgICB9IGVsc2UgaWYgKGhhc0V4dGVuc2lvbiAmJiAhY29udGVudFR5cGUpIHtcbiAgICAgIGNvbnRlbnRUeXBlID0gbWltZS5nZXRUeXBlKGZpbGVuYW1lKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMub3B0aW9ucy5wcmVzZXJ2ZUZpbGVOYW1lKSB7XG4gICAgICBmaWxlbmFtZSA9IHJhbmRvbUhleFN0cmluZygzMikgKyAnXycgKyBmaWxlbmFtZTtcbiAgICB9XG5cbiAgICBjb25zdCBsb2NhdGlvbiA9IHRoaXMuYWRhcHRlci5nZXRGaWxlTG9jYXRpb24oY29uZmlnLCBmaWxlbmFtZSk7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5jcmVhdGVGaWxlKGZpbGVuYW1lLCBkYXRhLCBjb250ZW50VHlwZSwgb3B0aW9ucykudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgdXJsOiBsb2NhdGlvbixcbiAgICAgICAgbmFtZTogZmlsZW5hbWUsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGRlbGV0ZUZpbGUoY29uZmlnLCBmaWxlbmFtZSkge1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuZGVsZXRlRmlsZShmaWxlbmFtZSk7XG4gIH1cblxuICBnZXRNZXRhZGF0YShmaWxlbmFtZSkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5hZGFwdGVyLmdldE1ldGFkYXRhID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gdGhpcy5hZGFwdGVyLmdldE1ldGFkYXRhKGZpbGVuYW1lKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gIH1cblxuICAvKipcbiAgICogRmluZCBmaWxlIHJlZmVyZW5jZXMgaW4gUkVTVC1mb3JtYXQgb2JqZWN0IGFuZCBhZGRzIHRoZSB1cmwga2V5XG4gICAqIHdpdGggdGhlIGN1cnJlbnQgbW91bnQgcG9pbnQgYW5kIGFwcCBpZC5cbiAgICogT2JqZWN0IG1heSBiZSBhIHNpbmdsZSBvYmplY3Qgb3IgbGlzdCBvZiBSRVNULWZvcm1hdCBvYmplY3RzLlxuICAgKi9cbiAgZXhwYW5kRmlsZXNJbk9iamVjdChjb25maWcsIG9iamVjdCkge1xuICAgIGlmIChvYmplY3QgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgb2JqZWN0Lm1hcChvYmogPT4gdGhpcy5leHBhbmRGaWxlc0luT2JqZWN0KGNvbmZpZywgb2JqKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqZWN0ICE9PSAnb2JqZWN0Jykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGtleSBpbiBvYmplY3QpIHtcbiAgICAgIGNvbnN0IGZpbGVPYmplY3QgPSBvYmplY3Rba2V5XTtcbiAgICAgIGlmIChmaWxlT2JqZWN0ICYmIGZpbGVPYmplY3RbJ19fdHlwZSddID09PSAnRmlsZScpIHtcbiAgICAgICAgaWYgKGZpbGVPYmplY3RbJ3VybCddKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZmlsZW5hbWUgPSBmaWxlT2JqZWN0WyduYW1lJ107XG4gICAgICAgIC8vIGFsbCBmaWxlbmFtZXMgc3RhcnRpbmcgd2l0aCBcInRmc3MtXCIgc2hvdWxkIGJlIGZyb20gZmlsZXMucGFyc2V0ZnNzLmNvbVxuICAgICAgICAvLyBhbGwgZmlsZW5hbWVzIHN0YXJ0aW5nIHdpdGggYSBcIi1cIiBzZXBlcmF0ZWQgVVVJRCBzaG91bGQgYmUgZnJvbSBmaWxlcy5wYXJzZS5jb21cbiAgICAgICAgLy8gYWxsIG90aGVyIGZpbGVuYW1lcyBoYXZlIGJlZW4gbWlncmF0ZWQgb3IgY3JlYXRlZCBmcm9tIFBhcnNlIFNlcnZlclxuICAgICAgICBpZiAoY29uZmlnLmZpbGVLZXkgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGZpbGVPYmplY3RbJ3VybCddID0gdGhpcy5hZGFwdGVyLmdldEZpbGVMb2NhdGlvbihjb25maWcsIGZpbGVuYW1lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoZmlsZW5hbWUuaW5kZXhPZigndGZzcy0nKSA9PT0gMCkge1xuICAgICAgICAgICAgZmlsZU9iamVjdFsndXJsJ10gPVxuICAgICAgICAgICAgICAnaHR0cDovL2ZpbGVzLnBhcnNldGZzcy5jb20vJyArIGNvbmZpZy5maWxlS2V5ICsgJy8nICsgZW5jb2RlVVJJQ29tcG9uZW50KGZpbGVuYW1lKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGxlZ2FjeUZpbGVzUmVnZXgudGVzdChmaWxlbmFtZSkpIHtcbiAgICAgICAgICAgIGZpbGVPYmplY3RbJ3VybCddID1cbiAgICAgICAgICAgICAgJ2h0dHA6Ly9maWxlcy5wYXJzZS5jb20vJyArIGNvbmZpZy5maWxlS2V5ICsgJy8nICsgZW5jb2RlVVJJQ29tcG9uZW50KGZpbGVuYW1lKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZmlsZU9iamVjdFsndXJsJ10gPSB0aGlzLmFkYXB0ZXIuZ2V0RmlsZUxvY2F0aW9uKGNvbmZpZywgZmlsZW5hbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGV4cGVjdGVkQWRhcHRlclR5cGUoKSB7XG4gICAgcmV0dXJuIEZpbGVzQWRhcHRlcjtcbiAgfVxuXG4gIGhhbmRsZUZpbGVTdHJlYW0oY29uZmlnLCBmaWxlbmFtZSwgcmVxLCByZXMsIGNvbnRlbnRUeXBlKSB7XG4gICAgcmV0dXJuIHRoaXMuYWRhcHRlci5oYW5kbGVGaWxlU3RyZWFtKGZpbGVuYW1lLCByZXEsIHJlcywgY29udGVudFR5cGUpO1xuICB9XG5cbiAgdmFsaWRhdGVGaWxlbmFtZShmaWxlbmFtZSkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5hZGFwdGVyLnZhbGlkYXRlRmlsZW5hbWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGNvbnN0IGVycm9yID0gdGhpcy5hZGFwdGVyLnZhbGlkYXRlRmlsZW5hbWUoZmlsZW5hbWUpO1xuICAgICAgaWYgKHR5cGVvZiBlcnJvciAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0ZJTEVfTkFNRSwgZXJyb3IpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsaWRhdGVGaWxlbmFtZShmaWxlbmFtZSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRmlsZXNDb250cm9sbGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/HooksController.js b/lib/Controllers/HooksController.js deleted file mode 100644 index cec8c49e9e..0000000000 --- a/lib/Controllers/HooksController.js +++ /dev/null @@ -1,302 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.HooksController = void 0; - -var triggers = _interopRequireWildcard(require("../triggers")); - -var Parse = _interopRequireWildcard(require("parse/node")); - -var _request = _interopRequireDefault(require("../request")); - -var _logger = require("../logger"); - -var _http = _interopRequireDefault(require("http")); - -var _https = _interopRequireDefault(require("https")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -// -disable-next -// -disable-next -const DefaultHooksCollectionName = '_Hooks'; -const HTTPAgents = { - http: new _http.default.Agent({ - keepAlive: true - }), - https: new _https.default.Agent({ - keepAlive: true - }) -}; - -class HooksController { - constructor(applicationId, databaseController, webhookKey) { - this._applicationId = applicationId; - this._webhookKey = webhookKey; - this.database = databaseController; - } - - load() { - return this._getHooks().then(hooks => { - hooks = hooks || []; - hooks.forEach(hook => { - this.addHookToTriggers(hook); - }); - }); - } - - getFunction(functionName) { - return this._getHooks({ - functionName: functionName - }).then(results => results[0]); - } - - getFunctions() { - return this._getHooks({ - functionName: { - $exists: true - } - }); - } - - getTrigger(className, triggerName) { - return this._getHooks({ - className: className, - triggerName: triggerName - }).then(results => results[0]); - } - - getTriggers() { - return this._getHooks({ - className: { - $exists: true - }, - triggerName: { - $exists: true - } - }); - } - - deleteFunction(functionName) { - triggers.removeFunction(functionName, this._applicationId); - return this._removeHooks({ - functionName: functionName - }); - } - - deleteTrigger(className, triggerName) { - triggers.removeTrigger(triggerName, className, this._applicationId); - return this._removeHooks({ - className: className, - triggerName: triggerName - }); - } - - _getHooks(query = {}) { - return this.database.find(DefaultHooksCollectionName, query).then(results => { - return results.map(result => { - delete result.objectId; - return result; - }); - }); - } - - _removeHooks(query) { - return this.database.destroy(DefaultHooksCollectionName, query).then(() => { - return Promise.resolve({}); - }); - } - - saveHook(hook) { - var query; - - if (hook.functionName && hook.url) { - query = { - functionName: hook.functionName - }; - } else if (hook.triggerName && hook.className && hook.url) { - query = { - className: hook.className, - triggerName: hook.triggerName - }; - } else { - throw new Parse.Error(143, 'invalid hook declaration'); - } - - return this.database.update(DefaultHooksCollectionName, query, hook, { - upsert: true - }).then(() => { - return Promise.resolve(hook); - }); - } - - addHookToTriggers(hook) { - var wrappedFunction = wrapToHTTPRequest(hook, this._webhookKey); - wrappedFunction.url = hook.url; - - if (hook.className) { - triggers.addTrigger(hook.triggerName, hook.className, wrappedFunction, this._applicationId); - } else { - triggers.addFunction(hook.functionName, wrappedFunction, null, this._applicationId); - } - } - - addHook(hook) { - this.addHookToTriggers(hook); - return this.saveHook(hook); - } - - createOrUpdateHook(aHook) { - var hook; - - if (aHook && aHook.functionName && aHook.url) { - hook = {}; - hook.functionName = aHook.functionName; - hook.url = aHook.url; - } else if (aHook && aHook.className && aHook.url && aHook.triggerName && triggers.Types[aHook.triggerName]) { - hook = {}; - hook.className = aHook.className; - hook.url = aHook.url; - hook.triggerName = aHook.triggerName; - } else { - throw new Parse.Error(143, 'invalid hook declaration'); - } - - return this.addHook(hook); - } - - createHook(aHook) { - if (aHook.functionName) { - return this.getFunction(aHook.functionName).then(result => { - if (result) { - throw new Parse.Error(143, `function name: ${aHook.functionName} already exits`); - } else { - return this.createOrUpdateHook(aHook); - } - }); - } else if (aHook.className && aHook.triggerName) { - return this.getTrigger(aHook.className, aHook.triggerName).then(result => { - if (result) { - throw new Parse.Error(143, `class ${aHook.className} already has trigger ${aHook.triggerName}`); - } - - return this.createOrUpdateHook(aHook); - }); - } - - throw new Parse.Error(143, 'invalid hook declaration'); - } - - updateHook(aHook) { - if (aHook.functionName) { - return this.getFunction(aHook.functionName).then(result => { - if (result) { - return this.createOrUpdateHook(aHook); - } - - throw new Parse.Error(143, `no function named: ${aHook.functionName} is defined`); - }); - } else if (aHook.className && aHook.triggerName) { - return this.getTrigger(aHook.className, aHook.triggerName).then(result => { - if (result) { - return this.createOrUpdateHook(aHook); - } - - throw new Parse.Error(143, `class ${aHook.className} does not exist`); - }); - } - - throw new Parse.Error(143, 'invalid hook declaration'); - } - -} - -exports.HooksController = HooksController; - -function wrapToHTTPRequest(hook, key) { - return req => { - const jsonBody = {}; - - for (var i in req) { - jsonBody[i] = req[i]; - } - - if (req.object) { - jsonBody.object = req.object.toJSON(); - jsonBody.object.className = req.object.className; - } - - if (req.original) { - jsonBody.original = req.original.toJSON(); - jsonBody.original.className = req.original.className; - } - - const jsonRequest = { - url: hook.url, - headers: { - 'Content-Type': 'application/json' - }, - body: jsonBody, - method: 'POST' - }; - const agent = hook.url.startsWith('https') ? HTTPAgents['https'] : HTTPAgents['http']; - jsonRequest.agent = agent; - - if (key) { - jsonRequest.headers['X-Parse-Webhook-Key'] = key; - } else { - _logger.logger.warn('Making outgoing webhook request without webhookKey being set!'); - } - - return (0, _request.default)(jsonRequest).then(response => { - let err; - let result; - let body = response.data; - - if (body) { - if (typeof body === 'string') { - try { - body = JSON.parse(body); - } catch (e) { - err = { - error: 'Malformed response', - code: -1, - partialResponse: body.substring(0, 100) - }; - } - } - - if (!err) { - result = body.success; - err = body.error; - } - } - - if (err) { - throw err; - } else if (hook.triggerName === 'beforeSave') { - if (typeof result === 'object') { - delete result.createdAt; - delete result.updatedAt; - delete result.className; - } - - return { - object: result - }; - } else { - return result; - } - }); - }; -} - -var _default = HooksController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9Ib29rc0NvbnRyb2xsZXIuanMiXSwibmFtZXMiOlsiRGVmYXVsdEhvb2tzQ29sbGVjdGlvbk5hbWUiLCJIVFRQQWdlbnRzIiwiaHR0cCIsIkFnZW50Iiwia2VlcEFsaXZlIiwiaHR0cHMiLCJIb29rc0NvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImFwcGxpY2F0aW9uSWQiLCJkYXRhYmFzZUNvbnRyb2xsZXIiLCJ3ZWJob29rS2V5IiwiX2FwcGxpY2F0aW9uSWQiLCJfd2ViaG9va0tleSIsImRhdGFiYXNlIiwibG9hZCIsIl9nZXRIb29rcyIsInRoZW4iLCJob29rcyIsImZvckVhY2giLCJob29rIiwiYWRkSG9va1RvVHJpZ2dlcnMiLCJnZXRGdW5jdGlvbiIsImZ1bmN0aW9uTmFtZSIsInJlc3VsdHMiLCJnZXRGdW5jdGlvbnMiLCIkZXhpc3RzIiwiZ2V0VHJpZ2dlciIsImNsYXNzTmFtZSIsInRyaWdnZXJOYW1lIiwiZ2V0VHJpZ2dlcnMiLCJkZWxldGVGdW5jdGlvbiIsInRyaWdnZXJzIiwicmVtb3ZlRnVuY3Rpb24iLCJfcmVtb3ZlSG9va3MiLCJkZWxldGVUcmlnZ2VyIiwicmVtb3ZlVHJpZ2dlciIsInF1ZXJ5IiwiZmluZCIsIm1hcCIsInJlc3VsdCIsIm9iamVjdElkIiwiZGVzdHJveSIsIlByb21pc2UiLCJyZXNvbHZlIiwic2F2ZUhvb2siLCJ1cmwiLCJQYXJzZSIsIkVycm9yIiwidXBkYXRlIiwidXBzZXJ0Iiwid3JhcHBlZEZ1bmN0aW9uIiwid3JhcFRvSFRUUFJlcXVlc3QiLCJhZGRUcmlnZ2VyIiwiYWRkRnVuY3Rpb24iLCJhZGRIb29rIiwiY3JlYXRlT3JVcGRhdGVIb29rIiwiYUhvb2siLCJUeXBlcyIsImNyZWF0ZUhvb2siLCJ1cGRhdGVIb29rIiwia2V5IiwicmVxIiwianNvbkJvZHkiLCJpIiwib2JqZWN0IiwidG9KU09OIiwib3JpZ2luYWwiLCJqc29uUmVxdWVzdCIsImhlYWRlcnMiLCJib2R5IiwibWV0aG9kIiwiYWdlbnQiLCJzdGFydHNXaXRoIiwibG9nZ2VyIiwid2FybiIsInJlc3BvbnNlIiwiZXJyIiwiZGF0YSIsIkpTT04iLCJwYXJzZSIsImUiLCJlcnJvciIsImNvZGUiLCJwYXJ0aWFsUmVzcG9uc2UiLCJzdWJzdHJpbmciLCJzdWNjZXNzIiwiY3JlYXRlZEF0IiwidXBkYXRlZEF0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBRUE7O0FBRUE7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBTkE7QUFFQTtBQU1BLE1BQU1BLDBCQUEwQixHQUFHLFFBQW5DO0FBQ0EsTUFBTUMsVUFBVSxHQUFHO0FBQ2pCQyxFQUFBQSxJQUFJLEVBQUUsSUFBSUEsY0FBS0MsS0FBVCxDQUFlO0FBQUVDLElBQUFBLFNBQVMsRUFBRTtBQUFiLEdBQWYsQ0FEVztBQUVqQkMsRUFBQUEsS0FBSyxFQUFFLElBQUlBLGVBQU1GLEtBQVYsQ0FBZ0I7QUFBRUMsSUFBQUEsU0FBUyxFQUFFO0FBQWIsR0FBaEI7QUFGVSxDQUFuQjs7QUFLTyxNQUFNRSxlQUFOLENBQXNCO0FBSzNCQyxFQUFBQSxXQUFXLENBQUNDLGFBQUQsRUFBd0JDLGtCQUF4QixFQUE0Q0MsVUFBNUMsRUFBd0Q7QUFDakUsU0FBS0MsY0FBTCxHQUFzQkgsYUFBdEI7QUFDQSxTQUFLSSxXQUFMLEdBQW1CRixVQUFuQjtBQUNBLFNBQUtHLFFBQUwsR0FBZ0JKLGtCQUFoQjtBQUNEOztBQUVESyxFQUFBQSxJQUFJLEdBQUc7QUFDTCxXQUFPLEtBQUtDLFNBQUwsR0FBaUJDLElBQWpCLENBQXNCQyxLQUFLLElBQUk7QUFDcENBLE1BQUFBLEtBQUssR0FBR0EsS0FBSyxJQUFJLEVBQWpCO0FBQ0FBLE1BQUFBLEtBQUssQ0FBQ0MsT0FBTixDQUFjQyxJQUFJLElBQUk7QUFDcEIsYUFBS0MsaUJBQUwsQ0FBdUJELElBQXZCO0FBQ0QsT0FGRDtBQUdELEtBTE0sQ0FBUDtBQU1EOztBQUVERSxFQUFBQSxXQUFXLENBQUNDLFlBQUQsRUFBZTtB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RUpDLGNBQUFBLElBQUksRUFBRSxDQUFDLENBRkg7QUFHSkMsY0FBQUEsZUFBZSxFQUFFZCxJQUFJLENBQUNlLFNBQUwsQ0FBZSxDQUFmLEVBQWtCLEdBQWxCO0FBSGIsYUFBTjtBQUtEO0FBQ0Y7O0FBQ0QsWUFBSSxDQUFDUixHQUFMLEVBQVU7QUFDUnJDLFVBQUFBLE1BQU0sR0FBRzhCLElBQUksQ0FBQ2dCLE9BQWQ7QUFDQVQsVUFBQUEsR0FBRyxHQUFHUCxJQUFJLENBQUNZLEtBQVg7QUFDRDtBQUNGOztBQUNELFVBQUlMLEdBQUosRUFBUztBQUNQLGNBQU1BLEdBQU47QUFDRCxPQUZELE1BRU8sSUFBSXpELElBQUksQ0FBQ1MsV0FBTCxLQUFxQixZQUF6QixFQUF1QztBQUM1QyxZQUFJLE9BQU9XLE1BQVAsS0FBa0IsUUFBdEIsRUFBZ0M7QUFDOUIsaUJBQU9BLE1BQU0sQ0FBQytDLFNBQWQ7QUFDQSxpQkFBTy9DLE1BQU0sQ0FBQ2dELFNBQWQ7QUFDQSxpQkFBT2hELE1BQU0sQ0FBQ1osU0FBZDtBQUNEOztBQUNELGVBQU87QUFBRXFDLFVBQUFBLE1BQU0sRUFBRXpCO0FBQVYsU0FBUDtBQUNELE9BUE0sTUFPQTtBQUNMLGVBQU9BLE1BQVA7QUFDRDtBQUNGLEtBakNNLENBQVA7QUFrQ0QsR0FoRUQ7QUFpRUQ7O2VBRWNqQyxlIiwic291cmNlc0NvbnRlbnQiOlsiLyoqIEBmbG93IHdlYWsgKi9cblxuaW1wb3J0ICogYXMgdHJpZ2dlcnMgZnJvbSAnLi4vdHJpZ2dlcnMnO1xuLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG5pbXBvcnQgKiBhcyBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuaW1wb3J0IHJlcXVlc3QgZnJvbSAnLi4vcmVxdWVzdCc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi9sb2dnZXInO1xuaW1wb3J0IGh0dHAgZnJvbSAnaHR0cCc7XG5pbXBvcnQgaHR0cHMgZnJvbSAnaHR0cHMnO1xuXG5jb25zdCBEZWZhdWx0SG9va3NDb2xsZWN0aW9uTmFtZSA9ICdfSG9va3MnO1xuY29uc3QgSFRUUEFnZW50cyA9IHtcbiAgaHR0cDogbmV3IGh0dHAuQWdlbnQoeyBrZWVwQWxpdmU6IHRydWUgfSksXG4gIGh0dHBzOiBuZXcgaHR0cHMuQWdlbnQoeyBrZWVwQWxpdmU6IHRydWUgfSksXG59O1xuXG5leHBvcnQgY2xhc3MgSG9va3NDb250cm9sbGVyIHtcbiAgX2FwcGxpY2F0aW9uSWQ6IHN0cmluZztcbiAgX3dlYmhvb2tLZXk6IHN0cmluZztcbiAgZGF0YWJhc2U6IGFueTtcblxuICBjb25zdHJ1Y3RvcihhcHBsaWNhdGlvbklkOiBzdHJpbmcsIGRhdGFiYXNlQ29udHJvbGxlciwgd2ViaG9va0tleSkge1xuICAgIHRoaXMuX2FwcGxpY2F0aW9uSWQgPSBhcHBsaWNhdGlvbklkO1xuICAgIHRoaXMuX3dlYmhvb2tLZXkgPSB3ZWJob29rS2V5O1xuICAgIHRoaXMuZGF0YWJhc2UgPSBkYXRhYmFzZUNvbnRyb2xsZXI7XG4gIH1cblxuICBsb2FkKCkge1xuICAgIHJldHVybiB0aGlzLl9nZXRIb29rcygpLnRoZW4oaG9va3MgPT4ge1xuICAgICAgaG9va3MgPSBob29rcyB8fCBbXTtcbiAgICAgIGhvb2tzLmZvckVhY2goaG9vayA9PiB7XG4gICAgICAgIHRoaXMuYWRkSG9va1RvVHJpZ2dlcnMoaG9vayk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldEZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSkge1xuICAgIHJldHVybiB0aGlzLl9nZXRIb29rcyh7IGZ1bmN0aW9uTmFtZTogZnVuY3Rpb25OYW1lIH0pLnRoZW4ocmVzdWx0cyA9PiByZXN1bHRzWzBdKTtcbiAgfVxuXG4gIGdldEZ1bmN0aW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0SG9va3MoeyBmdW5jdGlvbk5hbWU6IHsgJGV4aXN0czogdHJ1ZSB9IH0pO1xuICB9XG5cbiAgZ2V0VHJpZ2dlcihjbGFzc05hbWUsIHRyaWdnZXJOYW1lKSB7XG4gICAgcmV0dXJuIHRoaXMuX2dldEhvb2tzKHtcbiAgICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lLFxuICAgICAgdHJpZ2dlck5hbWU6IHRyaWdnZXJOYW1lLFxuICAgIH0pLnRoZW4ocmVzdWx0cyA9PiByZXN1bHRzWzBdKTtcbiAgfVxuXG4gIGdldFRyaWdnZXJzKCkge1xuICAgIHJldHVybiB0aGlzLl9nZXRIb29rcyh7XG4gICAgICBjbGFzc05hbWU6IHsgJGV4aXN0czogdHJ1ZSB9LFxuICAgICAgdHJpZ2dlck5hbWU6IHsgJGV4aXN0czogdHJ1ZSB9LFxuICAgIH0pO1xuICB9XG5cbiAgZGVsZXRlRnVuY3Rpb24oZnVuY3Rpb25OYW1lKSB7XG4gICAgdHJpZ2dlcnMucmVtb3ZlRnVuY3Rpb24oZnVuY3Rpb25OYW1lLCB0aGlzLl9hcHBsaWNhdGlvbklkKTtcbiAgICByZXR1cm4gdGhpcy5fcmVtb3ZlSG9va3MoeyBmdW5jdGlvbk5hbWU6IGZ1bmN0aW9uTmFtZSB9KTtcbiAgfVxuXG4gIGRlbGV0ZVRyaWdnZXIoY2xhc3NOYW1lLCB0cmlnZ2VyTmFtZSkge1xuICAgIHRyaWdnZXJzLnJlbW92ZVRyaWdnZXIodHJpZ2dlck5hbWUsIGNsYXNzTmFtZSwgdGhpcy5fYXBwbGljYXRpb25JZCk7XG4gICAgcmV0dXJuIHRoaXMuX3JlbW92ZUhvb2tzKHtcbiAgICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lLFxuICAgICAgdHJpZ2dlck5hbWU6IHRyaWdnZXJOYW1lLFxuICAgIH0pO1xuICB9XG5cbiAgX2dldEhvb2tzKHF1ZXJ5ID0ge30pIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhYmFzZS5maW5kKERlZmF1bHRIb29rc0NvbGxlY3Rpb25OYW1lLCBxdWVyeSkudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIHJldHVybiByZXN1bHRzLm1hcChyZXN1bHQgPT4ge1xuICAgICAgICBkZWxldGUgcmVzdWx0Lm9iamVjdElkO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBfcmVtb3ZlSG9va3MocXVlcnkpIHtcbiAgICByZXR1cm4gdGhpcy5kYXRhYmFzZS5kZXN0cm95KERlZmF1bHRIb29rc0NvbGxlY3Rpb25OYW1lLCBxdWVyeSkudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHNhdmVIb29rKGhvb2spIHtcbiAgICB2YXIgcXVlcnk7XG4gICAgaWYgKGhvb2suZnVuY3Rpb25OYW1lICYmIGhvb2sudXJsKSB7XG4gICAgICBxdWVyeSA9IHsgZnVuY3Rpb25OYW1lOiBob29rLmZ1bmN0aW9uTmFtZSB9O1xuICAgIH0gZWxzZSBpZiAoaG9vay50cmlnZ2VyTmFtZSAmJiBob29rLmNsYXNzTmFtZSAmJiBob29rLnVybCkge1xuICAgICAgcXVlcnkgPSB7IGNsYXNzTmFtZTogaG9vay5jbGFzc05hbWUsIHRyaWdnZXJOYW1lOiBob29rLnRyaWdnZXJOYW1lIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigxNDMsICdpbnZhbGlkIGhvb2sgZGVjbGFyYXRpb24nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZGF0YWJhc2VcbiAgICAgIC51cGRhdGUoRGVmYXVsdEhvb2tzQ29sbGVjdGlvbk5hbWUsIHF1ZXJ5LCBob29rLCB7IHVwc2VydDogdHJ1ZSB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGhvb2spO1xuICAgICAgfSk7XG4gIH1cblxuICBhZGRIb29rVG9UcmlnZ2Vycyhob29rKSB7XG4gICAgdmFyIHdyYXBwZWRGdW5jdGlvbiA9IHdyYXBUb0hUVFBSZXF1ZXN0KGhvb2ssIHRoaXMuX3dlYmhvb2tLZXkpO1xuICAgIHdyYXBwZWRGdW5jdGlvbi51cmwgPSBob29rLnVybDtcbiAgICBpZiAoaG9vay5jbGFzc05hbWUpIHtcbiAgICAgIHRyaWdnZXJzLmFkZFRyaWdnZXIoaG9vay50cmlnZ2VyTmFtZSwgaG9vay5jbGFzc05hbWUsIHdyYXBwZWRGdW5jdGlvbiwgdGhpcy5fYXBwbGljYXRpb25JZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRyaWdnZXJzLmFkZEZ1bmN0aW9uKGhvb2suZnVuY3Rpb25OYW1lLCB3cmFwcGVkRnVuY3Rpb24sIG51bGwsIHRoaXMuX2FwcGxpY2F0aW9uSWQpO1xuICAgIH1cbiAgfVxuXG4gIGFkZEhvb2soaG9vaykge1xuICAgIHRoaXMuYWRkSG9va1RvVHJpZ2dlcnMoaG9vayk7XG4gICAgcmV0dXJuIHRoaXMuc2F2ZUhvb2soaG9vayk7XG4gIH1cblxuICBjcmVhdGVPclVwZGF0ZUhvb2soYUhvb2spIHtcbiAgICB2YXIgaG9vaztcbiAgICBpZiAoYUhvb2sgJiYgYUhvb2suZnVuY3Rpb25OYW1lICYmIGFIb29rLnVybCkge1xuICAgICAgaG9vayA9IHt9O1xuICAgICAgaG9vay5mdW5jdGlvbk5hbWUgPSBhSG9vay5mdW5jdGlvbk5hbWU7XG4gICAgICBob29rLnVybCA9IGFIb29rLnVybDtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgYUhvb2sgJiZcbiAgICAgIGFIb29rLmNsYXNzTmFtZSAmJlxuICAgICAgYUhvb2sudXJsICYmXG4gICAgICBhSG9vay50cmlnZ2VyTmFtZSAmJlxuICAgICAgdHJpZ2dlcnMuVHlwZXNbYUhvb2sudHJpZ2dlck5hbWVdXG4gICAgKSB7XG4gICAgICBob29rID0ge307XG4gICAgICBob29rLmNsYXNzTmFtZSA9IGFIb29rLmNsYXNzTmFtZTtcbiAgICAgIGhvb2sudXJsID0gYUhvb2sudXJsO1xuICAgICAgaG9vay50cmlnZ2VyTmFtZSA9IGFIb29rLnRyaWdnZXJOYW1lO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTQzLCAnaW52YWxpZCBob29rIGRlY2xhcmF0aW9uJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuYWRkSG9vayhob29rKTtcbiAgfVxuXG4gIGNyZWF0ZUhvb2soYUhvb2spIHtcbiAgICBpZiAoYUhvb2suZnVuY3Rpb25OYW1lKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRGdW5jdGlvbihhSG9vay5mdW5jdGlvbk5hbWUpLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigxNDMsIGBmdW5jdGlvbiBuYW1lOiAke2FIb29rLmZ1bmN0aW9uTmFtZX0gYWxyZWFkeSBleGl0c2ApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZU9yVXBkYXRlSG9vayhhSG9vayk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoYUhvb2suY2xhc3NOYW1lICYmIGFIb29rLnRyaWdnZXJOYW1lKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRUcmlnZ2VyKGFIb29rLmNsYXNzTmFtZSwgYUhvb2sudHJpZ2dlck5hbWUpLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIDE0MyxcbiAgICAgICAgICAgIGBjbGFzcyAke2FIb29rLmNsYXNzTmFtZX0gYWxyZWFkeSBoYXMgdHJpZ2dlciAke2FIb29rLnRyaWdnZXJOYW1lfWBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZU9yVXBkYXRlSG9vayhhSG9vayk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTQzLCAnaW52YWxpZCBob29rIGRlY2xhcmF0aW9uJyk7XG4gIH1cblxuICB1cGRhdGVIb29rKGFIb29rKSB7XG4gICAgaWYgKGFIb29rLmZ1bmN0aW9uTmFtZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0RnVuY3Rpb24oYUhvb2suZnVuY3Rpb25OYW1lKS50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVPclVwZGF0ZUhvb2soYUhvb2spO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigxNDMsIGBubyBmdW5jdGlvbiBuYW1lZDogJHthSG9vay5mdW5jdGlvbk5hbWV9IGlzIGRlZmluZWRgKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoYUhvb2suY2xhc3NOYW1lICYmIGFIb29rLnRyaWdnZXJOYW1lKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRUcmlnZ2VyKGFIb29rLmNsYXNzTmFtZSwgYUhvb2sudHJpZ2dlck5hbWUpLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmNyZWF0ZU9yVXBkYXRlSG9vayhhSG9vayk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDE0MywgYGNsYXNzICR7YUhvb2suY2xhc3NOYW1lfSBkb2VzIG5vdCBleGlzdGApO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigxNDMsICdpbnZhbGlkIGhvb2sgZGVjbGFyYXRpb24nKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB3cmFwVG9IVFRQUmVxdWVzdChob29rLCBrZXkpIHtcbiAgcmV0dXJuIHJlcSA9PiB7XG4gICAgY29uc3QganNvbkJvZHkgPSB7fTtcbiAgICBmb3IgKHZhciBpIGluIHJlcSkge1xuICAgICAganNvbkJvZHlbaV0gPSByZXFbaV07XG4gICAgfVxuICAgIGlmIChyZXEub2JqZWN0KSB7XG4gICAgICBqc29uQm9keS5vYmplY3QgPSByZXEub2JqZWN0LnRvSlNPTigpO1xuICAgICAganNvbkJvZHkub2JqZWN0LmNsYXNzTmFtZSA9IHJlcS5vYmplY3QuY2xhc3NOYW1lO1xuICAgIH1cbiAgICBpZiAocmVxLm9yaWdpbmFsKSB7XG4gICAgICBqc29uQm9keS5vcmlnaW5hbCA9IHJlcS5vcmlnaW5hbC50b0pTT04oKTtcbiAgICAgIGpzb25Cb2R5Lm9yaWdpbmFsLmNsYXNzTmFtZSA9IHJlcS5vcmlnaW5hbC5jbGFzc05hbWU7XG4gICAgfVxuICAgIGNvbnN0IGpzb25SZXF1ZXN0OiBhbnkgPSB7XG4gICAgICB1cmw6IGhvb2sudXJsLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgfSxcbiAgICAgIGJvZHk6IGpzb25Cb2R5LFxuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgfTtcblxuICAgIGNvbnN0IGFnZW50ID0gaG9vay51cmwuc3RhcnRzV2l0aCgnaHR0cHMnKSA/IEhUVFBBZ2VudHNbJ2h0dHBzJ10gOiBIVFRQQWdlbnRzWydodHRwJ107XG4gICAganNvblJlcXVlc3QuYWdlbnQgPSBhZ2VudDtcblxuICAgIGlmIChrZXkpIHtcbiAgICAgIGpzb25SZXF1ZXN0LmhlYWRlcnNbJ1gtUGFyc2UtV2ViaG9vay1LZXknXSA9IGtleTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9nZ2VyLndhcm4oJ01ha2luZyBvdXRnb2luZyB3ZWJob29rIHJlcXVlc3Qgd2l0aG91dCB3ZWJob29rS2V5IGJlaW5nIHNldCEnKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcXVlc3QoanNvblJlcXVlc3QpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgbGV0IGVycjtcbiAgICAgIGxldCByZXN1bHQ7XG4gICAgICBsZXQgYm9keSA9IHJlc3BvbnNlLmRhdGE7XG4gICAgICBpZiAoYm9keSkge1xuICAgICAgICBpZiAodHlwZW9mIGJvZHkgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGJvZHkgPSBKU09OLnBhcnNlKGJvZHkpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGVyciA9IHtcbiAgICAgICAgICAgICAgZXJyb3I6ICdNYWxmb3JtZWQgcmVzcG9uc2UnLFxuICAgICAgICAgICAgICBjb2RlOiAtMSxcbiAgICAgICAgICAgICAgcGFydGlhbFJlc3BvbnNlOiBib2R5LnN1YnN0cmluZygwLCAxMDApLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFlcnIpIHtcbiAgICAgICAgICByZXN1bHQgPSBib2R5LnN1Y2Nlc3M7XG4gICAgICAgICAgZXJyID0gYm9keS5lcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGVycikge1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9IGVsc2UgaWYgKGhvb2sudHJpZ2dlck5hbWUgPT09ICdiZWZvcmVTYXZlJykge1xuICAgICAgICBpZiAodHlwZW9mIHJlc3VsdCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICBkZWxldGUgcmVzdWx0LmNyZWF0ZWRBdDtcbiAgICAgICAgICBkZWxldGUgcmVzdWx0LnVwZGF0ZWRBdDtcbiAgICAgICAgICBkZWxldGUgcmVzdWx0LmNsYXNzTmFtZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBvYmplY3Q6IHJlc3VsdCB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgSG9va3NDb250cm9sbGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/LiveQueryController.js b/lib/Controllers/LiveQueryController.js deleted file mode 100644 index ac461a03aa..0000000000 --- a/lib/Controllers/LiveQueryController.js +++ /dev/null @@ -1,78 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.LiveQueryController = void 0; - -var _ParseCloudCodePublisher = require("../LiveQuery/ParseCloudCodePublisher"); - -var _Options = require("../Options"); - -class LiveQueryController { - constructor(config) { - // If config is empty, we just assume no classs needs to be registered as LiveQuery - if (!config || !config.classNames) { - this.classNames = new Set(); - } else if (config.classNames instanceof Array) { - const classNames = config.classNames.map(name => new RegExp("^" + name + "$")); - this.classNames = new Set(classNames); - } else { - throw 'liveQuery.classes should be an array of string'; - } - - this.liveQueryPublisher = new _ParseCloudCodePublisher.ParseCloudCodePublisher(config); - } - - onAfterSave(className, currentObject, originalObject, classLevelPermissions) { - if (!this.hasLiveQuery(className)) { - return; - } - - const req = this._makePublisherRequest(currentObject, originalObject, classLevelPermissions); - - this.liveQueryPublisher.onCloudCodeAfterSave(req); - } - - onAfterDelete(className, currentObject, originalObject, classLevelPermissions) { - if (!this.hasLiveQuery(className)) { - return; - } - - const req = this._makePublisherRequest(currentObject, originalObject, classLevelPermissions); - - this.liveQueryPublisher.onCloudCodeAfterDelete(req); - } - - hasLiveQuery(className) { - for (const name of this.classNames) { - if (name.test(className)) { - return true; - } - } - - return false; - } - - _makePublisherRequest(currentObject, originalObject, classLevelPermissions) { - const req = { - object: currentObject - }; - - if (currentObject) { - req.original = originalObject; - } - - if (classLevelPermissions) { - req.classLevelPermissions = classLevelPermissions; - } - - return req; - } - -} - -exports.LiveQueryController = LiveQueryController; -var _default = LiveQueryController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9MaXZlUXVlcnlDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIkxpdmVRdWVyeUNvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImNvbmZpZyIsImNsYXNzTmFtZXMiLCJTZXQiLCJBcnJheSIsIm1hcCIsIm5hbWUiLCJSZWdFeHAiLCJsaXZlUXVlcnlQdWJsaXNoZXIiLCJQYXJzZUNsb3VkQ29kZVB1Ymxpc2hlciIsIm9uQWZ0ZXJTYXZlIiwiY2xhc3NOYW1lIiwiY3VycmVudE9iamVjdCIsIm9yaWdpbmFsT2JqZWN0IiwiY2xhc3NMZXZlbFBlcm1pc3Npb25zIiwiaGFzTGl2ZVF1ZXJ5IiwicmVxIiwiX21ha2VQdWJsaXNoZXJSZXF1ZXN0Iiwib25DbG91ZENvZGVBZnRlclNhdmUiLCJvbkFmdGVyRGVsZXRlIiwib25DbG91ZENvZGVBZnRlckRlbGV0ZSIsInRlc3QiLCJvYmplY3QiLCJvcmlnaW5hbCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNPLE1BQU1BLG1CQUFOLENBQTBCO0FBSS9CQyxFQUFBQSxXQUFXLENBQUNDLE1BQUQsRUFBNEI7QUFDckM7QUFDQSxRQUFJLENBQUNBLE1BQUQsSUFBVyxDQUFDQSxNQUFNLENBQUNDLFVBQXZCLEVBQW1DO0FBQ2pDLFdBQUtBLFVBQUwsR0FBa0IsSUFBSUMsR0FBSixFQUFsQjtBQUNELEtBRkQsTUFFTyxJQUFJRixNQUFNLENBQUNDLFVBQVAsWUFBNkJFLEtBQWpDLEVBQXdDO0FBQzdDLFlBQU1GLFVBQVUsR0FBR0QsTUFBTSxDQUFDQyxVQUFQLENBQ2hCRyxHQURnQixDQUNaQyxJQUFJLElBQUksSUFBSUMsTUFBSixDQUFXLE1BQU1ELElBQU4sR0FBYSxHQUF4QixDQURJLENBQW5CO0FBRUEsV0FBS0osVUFBTCxHQUFrQixJQUFJQyxHQUFKLENBQVFELFVBQVIsQ0FBbEI7QUFDRCxLQUpNLE1BSUE7QUFDTCxZQUFNLGdEQUFOO0FBQ0Q7O0FBQ0QsU0FBS00sa0JBQUwsR0FBMEIsSUFBSUMsZ0RBQUosQ0FBNEJSLE1BQTVCLENBQTFCO0FBQ0Q7O0FBRURTLEVBQUFBLFdBQVcsQ0FDVEMsU0FEUyxFQUVUQyxhQUZTLEVBR1RDLGNBSFMsRUFJVEMscUJBSlMsRUFLVDtBQUNBLFFBQUksQ0FBQyxLQUFLQyxZQUFMLENBQWtCSixTQUFsQixDQUFMLEVBQW1DO0FBQ2pDO0FBQ0Q7O0FBQ0QsVUFBTUssR0FBRyxHQUFHLEtBQUtDLHFCQUFMLENBQTJCTCxhQUEzQixFQUEwQ0MsY0FBMUMsRUFBMERDLHFCQUExRCxDQUFaOztBQUNBLFNBQUtOLGtCQUFMLENBQXdCVSxvQkFBeEIsQ0FBNkNGLEdBQTdDO0FBQ0Q7O0FBRURHLEVBQUFBLGFBQWEsQ0FDWFIsU0FEVyxFQUVYQyxhQUZXLEVBR1hDLGNBSFcsRUFJWEMscUJBSlcsRUFLWDtBQUNBLFFBQUksQ0FBQyxLQUFLQyxZQUFMLENBQWtCSixTQUFsQixDQUFMLEVBQW1DO0FBQ2pDO0FBQ0Q7O0FBQ0QsVUFBTUssR0FBRyxHQUFHLEtBQUtDLHFCQUFMLENBQTJCTCxhQUEzQixFQUEwQ0MsY0FBMUMsRUFBMERDLHFCQUExRCxDQUFaOztBQUNBLFNBQUtOLGtCQUFMLENBQXdCWSxzQkFBeEIsQ0FBK0NKLEdBQS9DO0FBQ0Q7O0FBRURELEVBQUFBLFlBQVksQ0FBQ0osU0FBRCxFQUE2QjtBQUN2QyxTQUFLLE1BQU1MLElBQVgsSUFBbUIsS0FBS0osVUFBeEIsRUFBb0M7QUFDbEMsVUFBSUksSUFBSSxDQUFDZSxJQUFMLENBQVVWLFNBQVYsQ0FBSixFQUEwQjtBQUN4QixlQUFPLElBQVA7QUFDRDtBQUNGOztBQUNELFdBQU8sS0FBUDtBQUNEOztBQUVETSxFQUFBQSxxQkFBcUIsQ0FBQ0wsYUFBRCxFQUFxQkMsY0FBckIsRUFBMENDLHFCQUExQyxFQUE0RTtBQUMvRixVQUFNRSxHQUFHLEdBQUc7QUFDVk0sTUFBQUEsTUFBTSxFQUFFVjtBQURFLEtBQVo7O0FBR0EsUUFBSUEsYUFBSixFQUFtQjtBQUNqQkksTUFBQUEsR0FBRyxDQUFDTyxRQUFKLEdBQWVWLGNBQWY7QUFDRDs7QUFDRCxRQUFJQyxxQkFBSixFQUEyQjtBQUN6QkUsTUFBQUEsR0FBRyxDQUFDRixxQkFBSixHQUE0QkEscUJBQTVCO0FBQ0Q7O0FBQ0QsV0FBT0UsR0FBUDtBQUNEOztBQWhFOEI7OztlQW1FbEJqQixtQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBhcnNlQ2xvdWRDb2RlUHVibGlzaGVyIH0gZnJvbSAnLi4vTGl2ZVF1ZXJ5L1BhcnNlQ2xvdWRDb2RlUHVibGlzaGVyJztcbmltcG9ydCB7IExpdmVRdWVyeU9wdGlvbnMgfSBmcm9tICcuLi9PcHRpb25zJztcbmV4cG9ydCBjbGFzcyBMaXZlUXVlcnlDb250cm9sbGVyIHtcbiAgY2xhc3NOYW1lczogYW55O1xuICBsaXZlUXVlcnlQdWJsaXNoZXI6IGFueTtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6ID9MaXZlUXVlcnlPcHRpb25zKSB7XG4gICAgLy8gSWYgY29uZmlnIGlzIGVtcHR5LCB3ZSBqdXN0IGFzc3VtZSBubyBjbGFzc3MgbmVlZHMgdG8gYmUgcmVnaXN0ZXJlZCBhcyBMaXZlUXVlcnlcbiAgICBpZiAoIWNvbmZpZyB8fCAhY29uZmlnLmNsYXNzTmFtZXMpIHtcbiAgICAgIHRoaXMuY2xhc3NOYW1lcyA9IG5ldyBTZXQoKTtcbiAgICB9IGVsc2UgaWYgKGNvbmZpZy5jbGFzc05hbWVzIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgIGNvbnN0IGNsYXNzTmFtZXMgPSBjb25maWcuY2xhc3NOYW1lc1xuICAgICAgICAubWFwKG5hbWUgPT4gbmV3IFJlZ0V4cChcIl5cIiArIG5hbWUgKyBcIiRcIikpO1xuICAgICAgdGhpcy5jbGFzc05hbWVzID0gbmV3IFNldChjbGFzc05hbWVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgJ2xpdmVRdWVyeS5jbGFzc2VzIHNob3VsZCBiZSBhbiBhcnJheSBvZiBzdHJpbmcnO1xuICAgIH1cbiAgICB0aGlzLmxpdmVRdWVyeVB1Ymxpc2hlciA9IG5ldyBQYXJzZUNsb3VkQ29kZVB1Ymxpc2hlcihjb25maWcpO1xuICB9XG5cbiAgb25BZnRlclNhdmUoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgY3VycmVudE9iamVjdDogYW55LFxuICAgIG9yaWdpbmFsT2JqZWN0OiBhbnksXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiA/YW55XG4gICkge1xuICAgIGlmICghdGhpcy5oYXNMaXZlUXVlcnkoY2xhc3NOYW1lKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByZXEgPSB0aGlzLl9tYWtlUHVibGlzaGVyUmVxdWVzdChjdXJyZW50T2JqZWN0LCBvcmlnaW5hbE9iamVjdCwgY2xhc3NMZXZlbFBlcm1pc3Npb25zKTtcbiAgICB0aGlzLmxpdmVRdWVyeVB1Ymxpc2hlci5vbkNsb3VkQ29kZUFmdGVyU2F2ZShyZXEpO1xuICB9XG5cbiAgb25BZnRlckRlbGV0ZShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBjdXJyZW50T2JqZWN0OiBhbnksXG4gICAgb3JpZ2luYWxPYmplY3Q6IGFueSxcbiAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IGFueVxuICApIHtcbiAgICBpZiAoIXRoaXMuaGFzTGl2ZVF1ZXJ5KGNsYXNzTmFtZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcmVxID0gdGhpcy5fbWFrZVB1Ymxpc2hlclJlcXVlc3QoY3VycmVudE9iamVjdCwgb3JpZ2luYWxPYmplY3QsIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyk7XG4gICAgdGhpcy5saXZlUXVlcnlQdWJsaXNoZXIub25DbG91ZENvZGVBZnRlckRlbGV0ZShyZXEpO1xuICB9XG5cbiAgaGFzTGl2ZVF1ZXJ5KGNsYXNzTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgZm9yIChjb25zdCBuYW1lIG9mIHRoaXMuY2xhc3NOYW1lcykge1xuICAgICAgaWYgKG5hbWUudGVzdChjbGFzc05hbWUpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBfbWFrZVB1Ymxpc2hlclJlcXVlc3QoY3VycmVudE9iamVjdDogYW55LCBvcmlnaW5hbE9iamVjdDogYW55LCBjbGFzc0xldmVsUGVybWlzc2lvbnM6ID9hbnkpOiBhbnkge1xuICAgIGNvbnN0IHJlcSA9IHtcbiAgICAgIG9iamVjdDogY3VycmVudE9iamVjdCxcbiAgICB9O1xuICAgIGlmIChjdXJyZW50T2JqZWN0KSB7XG4gICAgICByZXEub3JpZ2luYWwgPSBvcmlnaW5hbE9iamVjdDtcbiAgICB9XG4gICAgaWYgKGNsYXNzTGV2ZWxQZXJtaXNzaW9ucykge1xuICAgICAgcmVxLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucyA9IGNsYXNzTGV2ZWxQZXJtaXNzaW9ucztcbiAgICB9XG4gICAgcmV0dXJuIHJlcTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBMaXZlUXVlcnlDb250cm9sbGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/LoggerController.js b/lib/Controllers/LoggerController.js deleted file mode 100644 index be11d8877f..0000000000 --- a/lib/Controllers/LoggerController.js +++ /dev/null @@ -1,265 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.LoggerController = exports.LogOrder = exports.LogLevel = void 0; - -var _node = require("parse/node"); - -var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); - -var _LoggerAdapter = require("../Adapters/Logger/LoggerAdapter"); - -var _url = _interopRequireDefault(require("url")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000; -const LOG_STRING_TRUNCATE_LENGTH = 1000; -const truncationMarker = '... (truncated)'; -const LogLevel = { - INFO: 'info', - ERROR: 'error' -}; -exports.LogLevel = LogLevel; -const LogOrder = { - DESCENDING: 'desc', - ASCENDING: 'asc' -}; -exports.LogOrder = LogOrder; -const logLevels = ['error', 'warn', 'info', 'debug', 'verbose', 'silly']; - -class LoggerController extends _AdaptableController.default { - constructor(adapter, appId, options = { - logLevel: 'info' - }) { - super(adapter, appId, options); - let level = 'info'; - - if (options.verbose) { - level = 'verbose'; - } - - if (options.logLevel) { - level = options.logLevel; - } - - const index = logLevels.indexOf(level); // info by default - - logLevels.forEach((level, levelIndex) => { - if (levelIndex > index) { - // silence the levels that are > maxIndex - this[level] = () => {}; - } - }); - } - - maskSensitiveUrl(urlString) { - const urlObj = _url.default.parse(urlString, true); - - const query = urlObj.query; - let sanitizedQuery = '?'; - - for (const key in query) { - if (key !== 'password') { - // normal value - sanitizedQuery += key + '=' + query[key] + '&'; - } else { - // password value, redact it - sanitizedQuery += key + '=' + '********' + '&'; - } - } // trim last character, ? or & - - - sanitizedQuery = sanitizedQuery.slice(0, -1); // return original path name with sanitized params attached - - return urlObj.pathname + sanitizedQuery; - } - - maskSensitive(argArray) { - return argArray.map(e => { - if (!e) { - return e; - } - - if (typeof e === 'string') { - return e.replace(/(password".?:.?")[^"]*"/g, '$1********"'); - } // else it is an object... - // check the url - - - if (e.url) { - // for strings - if (typeof e.url === 'string') { - e.url = this.maskSensitiveUrl(e.url); - } else if (Array.isArray(e.url)) { - // for strings in array - e.url = e.url.map(item => { - if (typeof item === 'string') { - return this.maskSensitiveUrl(item); - } - - return item; - }); - } - } - - if (e.body) { - for (const key of Object.keys(e.body)) { - if (key === 'password') { - e.body[key] = '********'; - break; - } - } - } - - if (e.params) { - for (const key of Object.keys(e.params)) { - if (key === 'password') { - e.params[key] = '********'; - break; - } - } - } - - return e; - }); - } - - log(level, args) { - // make the passed in arguments object an array with the spread operator - args = this.maskSensitive([...args]); - args = [].concat(level, args.map(arg => { - if (typeof arg === 'function') { - return arg(); - } - - return arg; - })); - this.adapter.log.apply(this.adapter, args); - } - - info() { - return this.log('info', arguments); - } - - error() { - return this.log('error', arguments); - } - - warn() { - return this.log('warn', arguments); - } - - verbose() { - return this.log('verbose', arguments); - } - - debug() { - return this.log('debug', arguments); - } - - silly() { - return this.log('silly', arguments); - } - - logRequest({ - method, - url, - headers, - body - }) { - this.verbose(() => { - const stringifiedBody = JSON.stringify(body, null, 2); - return `REQUEST for [${method}] ${url}: ${stringifiedBody}`; - }, { - method, - url, - headers, - body - }); - } - - logResponse({ - method, - url, - result - }) { - this.verbose(() => { - const stringifiedResponse = JSON.stringify(result, null, 2); - return `RESPONSE from [${method}] ${url}: ${stringifiedResponse}`; - }, { - result: result - }); - } // check that date input is valid - - - static validDateTime(date) { - if (!date) { - return null; - } - - date = new Date(date); - - if (!isNaN(date.getTime())) { - return date; - } - - return null; - } - - truncateLogMessage(string) { - if (string && string.length > LOG_STRING_TRUNCATE_LENGTH) { - const truncated = string.substring(0, LOG_STRING_TRUNCATE_LENGTH) + truncationMarker; - return truncated; - } - - return string; - } - - static parseOptions(options = {}) { - const from = LoggerController.validDateTime(options.from) || new Date(Date.now() - 7 * MILLISECONDS_IN_A_DAY); - const until = LoggerController.validDateTime(options.until) || new Date(); - const size = Number(options.size) || 10; - const order = options.order || LogOrder.DESCENDING; - const level = options.level || LogLevel.INFO; - return { - from, - until, - size, - order, - level - }; - } // Returns a promise for a {response} object. - // query params: - // level (optional) Level of logging you want to query for (info || error) - // from (optional) Start time for the search. Defaults to 1 week ago. - // until (optional) End time for the search. Defaults to current time. - // order (optional) Direction of results returned, either “asc” or “desc”. Defaults to “desc”. - // size (optional) Number of rows returned by search. Defaults to 10 - - - getLogs(options = {}) { - if (!this.adapter) { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Logger adapter is not available'); - } - - if (typeof this.adapter.query !== 'function') { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Querying logs is not supported with this adapter'); - } - - options = LoggerController.parseOptions(options); - return this.adapter.query(options); - } - - expectedAdapterType() { - return _LoggerAdapter.LoggerAdapter; - } - -} - -exports.LoggerController = LoggerController; -var _default = LoggerController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9Mb2dnZXJDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIk1JTExJU0VDT05EU19JTl9BX0RBWSIsIkxPR19TVFJJTkdfVFJVTkNBVEVfTEVOR1RIIiwidHJ1bmNhdGlvbk1hcmtlciIsIkxvZ0xldmVsIiwiSU5GTyIsIkVSUk9SIiwiTG9nT3JkZXIiLCJERVNDRU5ESU5HIiwiQVNDRU5ESU5HIiwibG9nTGV2ZWxzIiwiTG9nZ2VyQ29udHJvbGxlciIsIkFkYXB0YWJsZUNvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImFkYXB0ZXIiLCJhcHBJZCIsIm9wdGlvbnMiLCJsb2dMZXZlbCIsImxldmVsIiwidmVyYm9zZSIsImluZGV4IiwiaW5kZXhPZiIsImZvckVhY2giLCJsZXZlbEluZGV4IiwibWFza1NlbnNpdGl2ZVVybCIsInVybFN0cmluZyIsInVybE9iaiIsInVybCIsInBhcnNlIiwicXVlcnkiLCJzYW5pdGl6ZWRRdWVyeSIsImtleSIsInNsaWNlIiwicGF0aG5hbWUiLCJtYXNrU2Vuc2l0aXZlIiwiYXJnQXJyYXkiLCJtYXAiLCJlIiwicmVwbGFjZSIsIkFycmF5IiwiaXNBcnJheSIsIml0ZW0iLCJib2R5IiwiT2JqZWN0Iiwia2V5cyIsInBhcmFtcyIsImxvZyIsImFyZ3MiLCJjb25jYXQiLCJhcmciLCJhcHBseSIsImluZm8iLCJhcmd1bWVudHMiLCJlcnJvciIsIndhcm4iLCJkZWJ1ZyIsInNpbGx5IiwibG9nUmVxdWVzdCIsIm1ldGhvZCIsImhlYWRlcnMiLCJzdHJpbmdpZmllZEJvZHkiLCJKU09OIiwic3RyaW5naWZ5IiwibG9nUmVzcG9uc2UiLCJyZXN1bHQiLCJzdHJpbmdpZmllZFJlc3BvbnNlIiwidmFsaWREYXRlVGltZSIsImRhdGUiLCJEYXRlIiwiaXNOYU4iLCJnZXRUaW1lIiwidHJ1bmNhdGVMb2dNZXNzYWdlIiwic3RyaW5nIiwibGVuZ3RoIiwidHJ1bmNhdGVkIiwic3Vic3RyaW5nIiwicGFyc2VPcHRpb25zIiwiZnJvbSIsIm5vdyIsInVudGlsIiwic2l6ZSIsIk51bWJlciIsIm9yZGVyIiwiZ2V0TG9ncyIsIlBhcnNlIiwiRXJyb3IiLCJQVVNIX01JU0NPTkZJR1VSRUQiLCJleHBlY3RlZEFkYXB0ZXJUeXBlIiwiTG9nZ2VyQWRhcHRlciJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRUEsTUFBTUEscUJBQXFCLEdBQUcsS0FBSyxFQUFMLEdBQVUsRUFBVixHQUFlLElBQTdDO0FBQ0EsTUFBTUMsMEJBQTBCLEdBQUcsSUFBbkM7QUFDQSxNQUFNQyxnQkFBZ0IsR0FBRyxpQkFBekI7QUFFTyxNQUFNQyxRQUFRLEdBQUc7QUFDdEJDLEVBQUFBLElBQUksRUFBRSxNQURnQjtBQUV0QkMsRUFBQUEsS0FBSyxFQUFFO0FBRmUsQ0FBakI7O0FBS0EsTUFBTUMsUUFBUSxHQUFHO0FBQ3RCQyxFQUFBQSxVQUFVLEVBQUUsTUFEVTtBQUV0QkMsRUFBQUEsU0FBUyxFQUFFO0FBRlcsQ0FBakI7O0FBS1AsTUFBTUMsU0FBUyxHQUFHLENBQUMsT0FBRCxFQUFVLE1BQVYsRUFBa0IsTUFBbEIsRUFBMEIsT0FBMUIsRUFBbUMsU0FBbkMsRUFBOEMsT0FBOUMsQ0FBbEI7O0FBRU8sTUFBTUMsZ0JBQU4sU0FBK0JDLDRCQUEvQixDQUFtRDtBQUN4REMsRUFBQUEsV0FBVyxDQUFDQyxPQUFELEVBQVVDLEtBQVYsRUFBaUJDLE9BQU8sR0FBRztBQUFFQyxJQUFBQSxRQUFRLEVBQUU7QUFBWixHQUEzQixFQUFpRDtBQUMxRCxVQUFNSCxPQUFOLEVBQWVDLEtBQWYsRUFBc0JDLE9BQXRCO0FBQ0EsUUFBSUUsS0FBSyxHQUFHLE1BQVo7O0FBQ0EsUUFBSUYsT0FBTyxDQUFDRyxPQUFaLEVBQXFCO0FBQ25CRCxNQUFBQSxLQUFLLEdBQUcsU0FBUjtBQUNEOztBQUNELFFBQUlGLE9BQU8sQ0FBQ0MsUUFBWixFQUFzQjtBQUNwQkMsTUFBQUEsS0FBSyxHQUFHRixPQUFPLENBQUND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LEtBSks7QUFLTGhFLE1BQUFBO0FBTEssS0FBUDtBQU9ELEdBak11RCxDQW1NeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNBaUUsRUFBQUEsT0FBTyxDQUFDbkUsT0FBTyxHQUFHLEVBQVgsRUFBZTtBQUNwQixRQUFJLENBQUMsS0FBS0YsT0FBVixFQUFtQjtBQUNqQixZQUFNLElBQUlzRSxZQUFNQyxLQUFWLENBQWdCRCxZQUFNQyxLQUFOLENBQVlDLGtCQUE1QixFQUFnRCxpQ0FBaEQsQ0FBTjtBQUNEOztBQUNELFFBQUksT0FBTyxLQUFLeEUsT0FBTCxDQUFhZSxLQUFwQixLQUE4QixVQUFsQyxFQUE4QztBQUM1QyxZQUFNLElBQUl1RCxZQUFNQyxLQUFWLENBQ0pELFlBQU1DLEtBQU4sQ0FBWUMsa0JBRFIsRUFFSixrREFGSSxDQUFOO0FBSUQ7O0FBQ0R0RSxJQUFBQSxPQUFPLEdBQUdMLGdCQUFnQixDQUFDaUUsWUFBakIsQ0FBOEI1RCxPQUE5QixDQUFWO0FBQ0EsV0FBTyxLQUFLRixPQUFMLENBQWFlLEtBQWIsQ0FBbUJiLE9BQW5CLENBQVA7QUFDRDs7QUFFRHVFLEVBQUFBLG1CQUFtQixHQUFHO0FBQ3BCLFdBQU9DLDRCQUFQO0FBQ0Q7O0FBMU51RDs7O2VBNk4zQzdFLGdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUGFyc2UgfSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBBZGFwdGFibGVDb250cm9sbGVyIGZyb20gJy4vQWRhcHRhYmxlQ29udHJvbGxlcic7XG5pbXBvcnQgeyBMb2dnZXJBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvTG9nZ2VyL0xvZ2dlckFkYXB0ZXInO1xuaW1wb3J0IHVybCBmcm9tICd1cmwnO1xuXG5jb25zdCBNSUxMSVNFQ09ORFNfSU5fQV9EQVkgPSAyNCAqIDYwICogNjAgKiAxMDAwO1xuY29uc3QgTE9HX1NUUklOR19UUlVOQ0FURV9MRU5HVEggPSAxMDAwO1xuY29uc3QgdHJ1bmNhdGlvbk1hcmtlciA9ICcuLi4gKHRydW5jYXRlZCknO1xuXG5leHBvcnQgY29uc3QgTG9nTGV2ZWwgPSB7XG4gIElORk86ICdpbmZvJyxcbiAgRVJST1I6ICdlcnJvcicsXG59O1xuXG5leHBvcnQgY29uc3QgTG9nT3JkZXIgPSB7XG4gIERFU0NFTkRJTkc6ICdkZXNjJyxcbiAgQVNDRU5ESU5HOiAnYXNjJyxcbn07XG5cbmNvbnN0IGxvZ0xldmVscyA9IFsnZXJyb3InLCAnd2FybicsICdpbmZvJywgJ2RlYnVnJywgJ3ZlcmJvc2UnLCAnc2lsbHknXTtcblxuZXhwb3J0IGNsYXNzIExvZ2dlckNvbnRyb2xsZXIgZXh0ZW5kcyBBZGFwdGFibGVDb250cm9sbGVyIHtcbiAgY29uc3RydWN0b3IoYWRhcHRlciwgYXBwSWQsIG9wdGlvbnMgPSB7IGxvZ0xldmVsOiAnaW5mbycgfSkge1xuICAgIHN1cGVyKGFkYXB0ZXIsIGFwcElkLCBvcHRpb25zKTtcbiAgICBsZXQgbGV2ZWwgPSAnaW5mbyc7XG4gICAgaWYgKG9wdGlvbnMudmVyYm9zZSkge1xuICAgICAgbGV2ZWwgPSAndmVyYm9zZSc7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmxvZ0xldmVsKSB7XG4gICAgICBsZXZlbCA9IG9wdGlvbnMubG9nTGV2ZWw7XG4gICAgfVxuICAgIGNvbnN0IGluZGV4ID0gbG9nTGV2ZWxzLmluZGV4T2YobGV2ZWwpOyAvLyBpbmZvIGJ5IGRlZmF1bHRcbiAgICBsb2dMZXZlbHMuZm9yRWFjaCgobGV2ZWwsIGxldmVsSW5kZXgpID0+IHtcbiAgICAgIGlmIChsZXZlbEluZGV4ID4gaW5kZXgpIHtcbiAgICAgICAgLy8gc2lsZW5jZSB0aGUgbGV2ZWxzIHRoYXQgYXJlID4gbWF4SW5kZXhcbiAgICAgICAgdGhpc1tsZXZlbF0gPSAoKSA9PiB7fTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIG1hc2tTZW5zaXRpdmVVcmwodXJsU3RyaW5nKSB7XG4gICAgY29uc3QgdXJsT2JqID0gdXJsLnBhcnNlKHVybFN0cmluZywgdHJ1ZSk7XG4gICAgY29uc3QgcXVlcnkgPSB1cmxPYmoucXVlcnk7XG4gICAgbGV0IHNhbml0aXplZFF1ZXJ5ID0gJz8nO1xuXG4gICAgZm9yIChjb25zdCBrZXkgaW4gcXVlcnkpIHtcbiAgICAgIGlmIChrZXkgIT09ICdwYXNzd29yZCcpIHtcbiAgICAgICAgLy8gbm9ybWFsIHZhbHVlXG4gICAgICAgIHNhbml0aXplZFF1ZXJ5ICs9IGtleSArICc9JyArIHF1ZXJ5W2tleV0gKyAnJic7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBwYXNzd29yZCB2YWx1ZSwgcmVkYWN0IGl0XG4gICAgICAgIHNhbml0aXplZFF1ZXJ5ICs9IGtleSArICc9JyArICcqKioqKioqKicgKyAnJic7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdHJpbSBsYXN0IGNoYXJhY3RlciwgPyBvciAmXG4gICAgc2FuaXRpemVkUXVlcnkgPSBzYW5pdGl6ZWRRdWVyeS5zbGljZSgwLCAtMSk7XG5cbiAgICAvLyByZXR1cm4gb3JpZ2luYWwgcGF0aCBuYW1lIHdpdGggc2FuaXRpemVkIHBhcmFtcyBhdHRhY2hlZFxuICAgIHJldHVybiB1cmxPYmoucGF0aG5hbWUgKyBzYW5pdGl6ZWRRdWVyeTtcbiAgfVxuXG4gIG1hc2tTZW5zaXRpdmUoYXJnQXJyYXkpIHtcbiAgICByZXR1cm4gYXJnQXJyYXkubWFwKGUgPT4ge1xuICAgICAgaWYgKCFlKSB7XG4gICAgICAgIHJldHVybiBlO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBlLnJlcGxhY2UoLyhwYXNzd29yZFwiLj86Lj9cIilbXlwiXSpcIi9nLCAnJDEqKioqKioqKlwiJyk7XG4gICAgICB9XG4gICAgICAvLyBlbHNlIGl0IGlzIGFuIG9iamVjdC4uLlxuXG4gICAgICAvLyBjaGVjayB0aGUgdXJsXG4gICAgICBpZiAoZS51cmwpIHtcbiAgICAgICAgLy8gZm9yIHN0cmluZ3NcbiAgICAgICAgaWYgKHR5cGVvZiBlLnVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBlLnVybCA9IHRoaXMubWFza1NlbnNpdGl2ZVVybChlLnVybCk7XG4gICAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShlLnVybCkpIHtcbiAgICAgICAgICAvLyBmb3Igc3RyaW5ncyBpbiBhcnJheVxuICAgICAgICAgIGUudXJsID0gZS51cmwubWFwKGl0ZW0gPT4ge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5tYXNrU2Vuc2l0aXZlVXJsKGl0ZW0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gaXRlbTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZS5ib2R5KSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGUuYm9keSkpIHtcbiAgICAgICAgICBpZiAoa2V5ID09PSAncGFzc3dvcmQnKSB7XG4gICAgICAgICAgICBlLmJvZHlba2V5XSA9ICcqKioqKioqKic7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGUucGFyYW1zKSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGUucGFyYW1zKSkge1xuICAgICAgICAgIGlmIChrZXkgPT09ICdwYXNzd29yZCcpIHtcbiAgICAgICAgICAgIGUucGFyYW1zW2tleV0gPSAnKioqKioqKionO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBlO1xuICAgIH0pO1xuICB9XG5cbiAgbG9nKGxldmVsLCBhcmdzKSB7XG4gICAgLy8gbWFrZSB0aGUgcGFzc2VkIGluIGFyZ3VtZW50cyBvYmplY3QgYW4gYXJyYXkgd2l0aCB0aGUgc3ByZWFkIG9wZXJhdG9yXG4gICAgYXJncyA9IHRoaXMubWFza1NlbnNpdGl2ZShbLi4uYXJnc10pO1xuICAgIGFyZ3MgPSBbXS5jb25jYXQoXG4gICAgICBsZXZlbCxcbiAgICAgIGFyZ3MubWFwKGFyZyA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgcmV0dXJuIGFyZygpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhcmc7XG4gICAgICB9KVxuICAgICk7XG4gICAgdGhpcy5hZGFwdGVyLmxvZy5hcHBseSh0aGlzLmFkYXB0ZXIsIGFyZ3MpO1xuICB9XG5cbiAgaW5mbygpIHtcbiAgICByZXR1cm4gdGhpcy5sb2coJ2luZm8nLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgZXJyb3IoKSB7XG4gICAgcmV0dXJuIHRoaXMubG9nKCdlcnJvcicsIGFyZ3VtZW50cyk7XG4gIH1cblxuICB3YXJuKCkge1xuICAgIHJldHVybiB0aGlzLmxvZygnd2FybicsIGFyZ3VtZW50cyk7XG4gIH1cblxuICB2ZXJib3NlKCkge1xuICAgIHJldHVybiB0aGlzLmxvZygndmVyYm9zZScsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBkZWJ1ZygpIHtcbiAgICByZXR1cm4gdGhpcy5sb2coJ2RlYnVnJywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIHNpbGx5KCkge1xuICAgIHJldHVybiB0aGlzLmxvZygnc2lsbHknLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgbG9nUmVxdWVzdCh7IG1ldGhvZCwgdXJsLCBoZWFkZXJzLCBib2R5IH0pIHtcbiAgICB0aGlzLnZlcmJvc2UoXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHN0cmluZ2lmaWVkQm9keSA9IEpTT04uc3RyaW5naWZ5KGJvZHksIG51bGwsIDIpO1xuICAgICAgICByZXR1cm4gYFJFUVVFU1QgZm9yIFske21ldGhvZH1dICR7dXJsfTogJHtzdHJpbmdpZmllZEJvZHl9YDtcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG1ldGhvZCxcbiAgICAgICAgdXJsLFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICBib2R5LFxuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBsb2dSZXNwb25zZSh7IG1ldGhvZCwgdXJsLCByZXN1bHQgfSkge1xuICAgIHRoaXMudmVyYm9zZShcbiAgICAgICgpID0+IHtcbiAgICAgICAgY29uc3Qgc3RyaW5naWZpZWRSZXNwb25zZSA9IEpTT04uc3RyaW5naWZ5KHJlc3VsdCwgbnVsbCwgMik7XG4gICAgICAgIHJldHVybiBgUkVTUE9OU0UgZnJvbSBbJHttZXRob2R9XSAke3VybH06ICR7c3RyaW5naWZpZWRSZXNwb25zZX1gO1xuICAgICAgfSxcbiAgICAgIHsgcmVzdWx0OiByZXN1bHQgfVxuICAgICk7XG4gIH1cbiAgLy8gY2hlY2sgdGhhdCBkYXRlIGlucHV0IGlzIHZhbGlkXG4gIHN0YXRpYyB2YWxpZERhdGVUaW1lKGRhdGUpIHtcbiAgICBpZiAoIWRhdGUpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBkYXRlID0gbmV3IERhdGUoZGF0ZSk7XG5cbiAgICBpZiAoIWlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB0cnVuY2F0ZUxvZ01lc3NhZ2Uoc3RyaW5nKSB7XG4gICAgaWYgKHN0cmluZyAmJiBzdHJpbmcubGVuZ3RoID4gTE9HX1NUUklOR19UUlVOQ0FURV9MRU5HVEgpIHtcbiAgICAgIGNvbnN0IHRydW5jYXRlZCA9IHN0cmluZy5zdWJzdHJpbmcoMCwgTE9HX1NUUklOR19UUlVOQ0FURV9MRU5HVEgpICsgdHJ1bmNhdGlvbk1hcmtlcjtcbiAgICAgIHJldHVybiB0cnVuY2F0ZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0cmluZztcbiAgfVxuXG4gIHN0YXRpYyBwYXJzZU9wdGlvbnMob3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgZnJvbSA9XG4gICAgICBMb2dnZXJDb250cm9sbGVyLnZhbGlkRGF0ZVRpbWUob3B0aW9ucy5mcm9tKSB8fFxuICAgICAgbmV3IERhdGUoRGF0ZS5ub3coKSAtIDcgKiBNSUxMSVNFQ09ORFNfSU5fQV9EQVkpO1xuICAgIGNvbnN0IHVudGlsID0gTG9nZ2VyQ29udHJvbGxlci52YWxpZERhdGVUaW1lKG9wdGlvbnMudW50aWwpIHx8IG5ldyBEYXRlKCk7XG4gICAgY29uc3Qgc2l6ZSA9IE51bWJlcihvcHRpb25zLnNpemUpIHx8IDEwO1xuICAgIGNvbnN0IG9yZGVyID0gb3B0aW9ucy5vcmRlciB8fCBMb2dPcmRlci5ERVNDRU5ESU5HO1xuICAgIGNvbnN0IGxldmVsID0gb3B0aW9ucy5sZXZlbCB8fCBMb2dMZXZlbC5JTkZPO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGZyb20sXG4gICAgICB1bnRpbCxcbiAgICAgIHNpemUsXG4gICAgICBvcmRlcixcbiAgICAgIGxldmVsLFxuICAgIH07XG4gIH1cblxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYSB7cmVzcG9uc2V9IG9iamVjdC5cbiAgLy8gcXVlcnkgcGFyYW1zOlxuICAvLyBsZXZlbCAob3B0aW9uYWwpIExldmVsIG9mIGxvZ2dpbmcgeW91IHdhbnQgdG8gcXVlcnkgZm9yIChpbmZvIHx8IGVycm9yKVxuICAvLyBmcm9tIChvcHRpb25hbCkgU3RhcnQgdGltZSBmb3IgdGhlIHNlYXJjaC4gRGVmYXVsdHMgdG8gMSB3ZWVrIGFnby5cbiAgLy8gdW50aWwgKG9wdGlvbmFsKSBFbmQgdGltZSBmb3IgdGhlIHNlYXJjaC4gRGVmYXVsdHMgdG8gY3VycmVudCB0aW1lLlxuICAvLyBvcmRlciAob3B0aW9uYWwpIERpcmVjdGlvbiBvZiByZXN1bHRzIHJldHVybmVkLCBlaXRoZXIg4oCcYXNj4oCdIG9yIOKAnGRlc2PigJ0uIERlZmF1bHRzIHRvIOKAnGRlc2PigJ0uXG4gIC8vIHNpemUgKG9wdGlvbmFsKSBOdW1iZXIgb2Ygcm93cyByZXR1cm5lZCBieSBzZWFyY2guIERlZmF1bHRzIHRvIDEwXG4gIGdldExvZ3Mob3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKCF0aGlzLmFkYXB0ZXIpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5QVVNIX01JU0NPTkZJR1VSRUQsICdMb2dnZXIgYWRhcHRlciBpcyBub3QgYXZhaWxhYmxlJyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdGhpcy5hZGFwdGVyLnF1ZXJ5ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgJ1F1ZXJ5aW5nIGxvZ3MgaXMgbm90IHN1cHBvcnRlZCB3aXRoIHRoaXMgYWRhcHRlcidcbiAgICAgICk7XG4gICAgfVxuICAgIG9wdGlvbnMgPSBMb2dnZXJDb250cm9sbGVyLnBhcnNlT3B0aW9ucyhvcHRpb25zKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnF1ZXJ5KG9wdGlvbnMpO1xuICB9XG5cbiAgZXhwZWN0ZWRBZGFwdGVyVHlwZSgpIHtcbiAgICByZXR1cm4gTG9nZ2VyQWRhcHRlcjtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBMb2dnZXJDb250cm9sbGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Controllers/ParseGraphQLController.js b/lib/Controllers/ParseGraphQLController.js deleted file mode 100644 index 64dabf14fb..0000000000 --- a/lib/Controllers/ParseGraphQLController.js +++ /dev/null @@ -1,358 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.GraphQLConfigKey = exports.GraphQLConfigId = exports.GraphQLConfigClassName = exports.default = void 0; - -var _requiredParameter = _interopRequireDefault(require("../../lib/requiredParameter")); - -var _DatabaseController = _interopRequireDefault(require("./DatabaseController")); - -var _CacheController = _interopRequireDefault(require("./CacheController")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } - -function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const GraphQLConfigClassName = '_GraphQLConfig'; -exports.GraphQLConfigClassName = GraphQLConfigClassName; -const GraphQLConfigId = '1'; -exports.GraphQLConfigId = GraphQLConfigId; -const GraphQLConfigKey = 'config'; -exports.GraphQLConfigKey = GraphQLConfigKey; - -class ParseGraphQLController { - constructor(params = {}) { - this.databaseController = params.databaseController || (0, _requiredParameter.default)(`ParseGraphQLController requires a "databaseController" to be instantiated.`); - this.cacheController = params.cacheController; - this.isMounted = !!params.mountGraphQL; - this.configCacheKey = GraphQLConfigKey; - } - - async getGraphQLConfig() { - if (this.isMounted) { - const _cachedConfig = await this._getCachedGraphQLConfig(); - - if (_cachedConfig) { - return _cachedConfig; - } - } - - const results = await this.databaseController.find(GraphQLConfigClassName, { - objectId: GraphQLConfigId - }, { - limit: 1 - }); - let graphQLConfig; - - if (results.length != 1) { - // If there is no config in the database - return empty config. - return {}; - } else { - graphQLConfig = results[0][GraphQLConfigKey]; - } - - if (this.isMounted) { - this._putCachedGraphQLConfig(graphQLConfig); - } - - return graphQLConfig; - } - - async updateGraphQLConfig(graphQLConfig) { - // throws if invalid - this._validateGraphQLConfig(graphQLConfig || (0, _requiredParameter.default)('You must provide a graphQLConfig!')); // Transform in dot notation to make sure it works - - - const update = Object.keys(graphQLConfig).reduce((acc, key) => { - return { - [GraphQLConfigKey]: _objectSpread(_objectSpread({}, acc[GraphQLConfigKey]), {}, { - [key]: graphQLConfig[key] - }) - }; - }, { - [GraphQLConfigKey]: {} - }); - await this.databaseController.update(GraphQLConfigClassName, { - objectId: GraphQLConfigId - }, update, { - upsert: true - }); - - if (this.isMounted) { - this._putCachedGraphQLConfig(graphQLConfig); - } - - return { - response: { - result: true - } - }; - } - - _getCachedGraphQLConfig() { - return this.cacheController.graphQL.get(this.configCacheKey); - } - - _putCachedGraphQLConfig(graphQLConfig) { - return this.cacheController.graphQL.put(this.configCacheKey, graphQLConfig, 60000); - } - - _validateGraphQLConfig(graphQLConfig) { - const errorMessages = []; - - if (!graphQLConfig) { - errorMessages.push('cannot be undefined, null or empty'); - } else if (!isValidSimpleObject(graphQLConfig)) { - errorMessages.push('must be a valid object'); - } else { - const { - enabledForClasses = null, - disabledForClasses = null, - classConfigs = null - } = graphQLConfig, - invalidKeys = _objectWithoutProperties(graphQLConfig, ["enabledForClasses", "disabledForClasses", "classConfigs"]); - - if (Object.keys(invalidKeys).length) { - errorMessages.push(`encountered invalid keys: [${Object.keys(invalidKeys)}]`); - } - - if (enabledForClasses !== null && !isValidStringArray(enabledForClasses)) { - errorMessages.push(`"enabledForClasses" is not a valid array`); - } - - if (disabledForClasses !== null && !isValidStringArray(disabledForClasses)) { - errorMessages.push(`"disabledForClasses" is not a valid array`); - } - - if (classConfigs !== null) { - if (Array.isArray(classConfigs)) { - classConfigs.forEach(classConfig => { - const errorMessage = this._validateClassConfig(classConfig); - - if (errorMessage) { - errorMessages.push(`classConfig:${classConfig.className} is invalid because ${errorMessage}`); - } - }); - } else { - errorMessages.push(`"classConfigs" is not a valid array`); - } - } - } - - if (errorMessages.length) { - throw new Error(`Invalid graphQLConfig: ${errorMessages.join('; ')}`); - } - } - - _validateClassConfig(classConfig) { - if (!isValidSimpleObject(classConfig)) { - return 'it must be a valid object'; - } else { - const { - className, - type = null, - query = null, - mutation = null - } = classConfig, - invalidKeys = _objectWithoutProperties(classConfig, ["className", "type", "query", "mutation"]); - - if (Object.keys(invalidKeys).length) { - return `"invalidKeys" [${Object.keys(invalidKeys)}] should not be present`; - } - - if (typeof className !== 'string' || !className.trim().length) { - // TODO consider checking class exists in schema? - return `"className" must be a valid string`; - } - - if (type !== null) { - if (!isValidSimpleObject(type)) { - return `"type" must be a valid object`; - } - - const { - inputFields = null, - outputFields = null, - constraintFields = null, - sortFields = null - } = type, - invalidKeys = _objectWithoutProperties(type, ["inputFields", "outputFields", "constraintFields", "sortFields"]); - - if (Object.keys(invalidKeys).length) { - return `"type" contains invalid keys, [${Object.keys(invalidKeys)}]`; - } else if (outputFields !== null && !isValidStringArray(outputFields)) { - return `"outputFields" must be a valid string array`; - } else if (constraintFields !== null && !isValidStringArray(constraintFields)) { - return `"constraintFields" must be a valid string array`; - } - - if (sortFields !== null) { - if (Array.isArray(sortFields)) { - let errorMessage; - sortFields.every((sortField, index) => { - if (!isValidSimpleObject(sortField)) { - errorMessage = `"sortField" at index ${index} is not a valid object`; - return false; - } else { - const { - field, - asc, - desc - } = sortField, - invalidKeys = _objectWithoutProperties(sortField, ["field", "asc", "desc"]); - - if (Object.keys(invalidKeys).length) { - errorMessage = `"sortField" at index ${index} contains invalid keys, [${Object.keys(invalidKeys)}]`; - return false; - } else { - if (typeof field !== 'string' || field.trim().length === 0) { - errorMessage = `"sortField" at index ${index} did not provide the "field" as a string`; - return false; - } else if (typeof asc !== 'boolean' || typeof desc !== 'boolean') { - errorMessage = `"sortField" at index ${index} did not provide "asc" or "desc" as booleans`; - return false; - } - } - } - - return true; - }); - - if (errorMessage) { - return errorMessage; - } - } else { - return `"sortFields" must be a valid array.`; - } - } - - if (inputFields !== null) { - if (isValidSimpleObject(inputFields)) { - const { - create = null, - update = null - } = inputFields, - invalidKeys = _objectWithoutProperties(inputFields, ["create", "update"]); - - if (Object.keys(invalidKeys).length) { - return `"inputFields" contains invalid keys: [${Object.keys(invalidKeys)}]`; - } else { - if (update !== null && !isValidStringArray(update)) { - return `"inputFields.update" must be a valid string array`; - } else if (create !== null) { - if (!isValidStringArray(create)) { - return `"inputFields.create" must be a valid string array`; - } else if (className === '_User') { - if (!create.includes('username') || !create.includes('password')) { - return `"inputFields.create" must include required fields, username and password`; - } - } - } - } - } else { - return `"inputFields" must be a valid object`; - } - } - } - - if (query !== null) { - if (isValidSimpleObject(query)) { - const { - find = null, - get = null, - findAlias = null, - getAlias = null - } = query, - invalidKeys = _objectWithoutProperties(query, ["find", "get", "findAlias", "getAlias"]); - - if (Object.keys(invalidKeys).length) { - return `"query" contains invalid keys, [${Object.keys(invalidKeys)}]`; - } else if (find !== null && typeof find !== 'boolean') { - return `"query.find" must be a boolean`; - } else if (get !== null && typeof get !== 'boolean') { - return `"query.get" must be a boolean`; - } else if (findAlias !== null && typeof findAlias !== 'string') { - return `"query.findAlias" must be a string`; - } else if (getAlias !== null && typeof getAlias !== 'string') { - return `"query.getAlias" must be a string`; - } - } else { - return `"query" must be a valid object`; - } - } - - if (mutation !== null) { - if (isValidSimpleObject(mutation)) { - const { - create = null, - update = null, - destroy = null, - createAlias = null, - updateAlias = null, - destroyAlias = null - } = mutation, - invalidKeys = _objectWithoutProperties(mutation, ["create", "update", "destroy", "createAlias", "updateAlias", "destroyAlias"]); - - if (Object.keys(invalidKeys).length) { - return `"mutation" contains invalid keys, [${Object.keys(invalidKeys)}]`; - } - - if (create !== null && typeof create !== 'boolean') { - return `"mutation.create" must be a boolean`; - } - - if (update !== null && typeof update !== 'boolean') { - return `"mutation.update" must be a boolean`; - } - - if (destroy !== null && typeof destroy !== 'boolean') { - return `"mutation.destroy" must be a boolean`; - } - - if (createAlias !== null && typeof createAlias !== 'string') { - return `"mutation.createAlias" must be a string`; - } - - if (updateAlias !== null && typeof updateAlias !== 'string') { - return `"mutation.updateAlias" must be a string`; - } - - if (destroyAlias !== null && typeof destroyAlias !== 'string') { - return `"mutation.destroyAlias" must be a string`; - } - } else { - return `"mutation" must be a valid object`; - } - } - } - } - -} - -const isValidStringArray = function (array) { - return Array.isArray(array) ? !array.some(s => typeof s !== 'string' || s.trim().length < 1) : false; -}; -/** - * Ensures the obj is a simple JSON/{} - * object, i.e. not an array, null, date - * etc. - */ - - -const isValidSimpleObject = function (obj) { - return typeof obj === 'object' && !Array.isArray(obj) && obj !== null && obj instanceof Date !== true && obj instanceof Promise !== true; -}; - -var _default = ParseGraphQLController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9QYXJzZUdyYXBoUUxDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIkdyYXBoUUxDb25maWdDbGFzc05hbWUiLCJHcmFwaFFMQ29uZmlnSWQiLCJHcmFwaFFMQ29uZmlnS2V5IiwiUGFyc2VHcmFwaFFMQ29udHJvbGxlciIsImNvbnN0cnVjdG9yIiwicGFyYW1zIiwiZGF0YWJhc2VDb250cm9sbGVyIiwiY2FjaGVDb250cm9sbGVyIiwiaXNNb3VudGVkIiwibW91bnRHcmFwaFFMIiwiY29uZmlnQ2FjaGVLZXkiLCJnZXRHcmFwaFFMQ29uZmlnIiwiX2NhY2hlZENvbmZpZyIsIl9nZXRDYWNoZWRHcmFwaFFMQ29uZmlnIiwicmVzdWx0cyIsImZpbmQiLCJvYmplY3RJZCIsImxpbWl0IiwiZ3JhcGhRTENvbmZpZyIsImxlbmd0aCIsIl9wdXRDYWNoZWRHcmFwaFFMQ29uZmlnIiwidXBkYXRlR3JhcGhRTENvbmZpZyIsIl92YWxpZGF0ZUdyYXBoUUxDb25maWciLCJ1cGRhdGUiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwiYWNjIiwia2V5IiwidXBzZXJ0IiwicmVzcG9uc2UiLCJyZXN1bHQiLCJncmFwaFFMIiwiZ2V0IiwicHV0IiwiZXJyb3JNZXNzYWdlcyIsInB1c2giLCJpc1ZhbGlkU2ltcGxlT2JqZWN0IiwiZW5hYmxlZEZvckNsYXNzZXMiLCJkaXNhYmxlZEZvckNsYXNzZXMiLCJjbGFzc0NvbmZpZ3MiLCJpbnZhbGlkS2V5cyIsImlzVmFsaWRTdHJpbmdBcnJheSIsIkFycmF5IiwiaXNBcnJheSIsImZvckVhY2giLCJjbGFzc0NvbmZpZyIsImVycm9yTWVzc2FnZSIsIl92YWxpZGF0ZUNsYXNzQ29uZmlnIiwiY2xhc3NOYW1lIiwiRXJyb3IiLCJqb2luIiwidHlwZSIsInF1ZXJ5IiwibXV0YXRpb24iLCJ0cmltIiwiaW5wdXRGaWVsZHMiLCJvdXRwdXRGaWVsZHMiLCJjb25zdHJhaW50RmllbGRzIiwic29ydEZpZWxkcyIsImV2ZXJ5Iiwic29ydEZpZWxkIiwiaW5kZXgiLCJmaWVsZCIsImFzYyIsImRlc2MiLCJjcmVhdGUiLCJpbmNsdWRlcyIsImZpbmRBbGlhcyIsImdldEFsaWFzIiwiZGVzdHJveSIsImNyZWF0ZUFsaWFzIiwidXBkYXRlQWxpYXMiLCJkZXN0cm95QWxpYXMiLCJhcnJheSIsInNvbWUiLCJzIiwib2JqIiwiRGF0ZSIsIlByb21pc2UiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7Ozs7Ozs7QUFFQSxNQUFNQSxzQkFBc0IsR0FBRyxnQkFBL0I7O0FBQ0EsTUFBTUMsZUFBZSxHQUFHLEdBQXhCOztBQUNBLE1BQU1DLGdCQUFnQixHQUFHLFFBQXpCOzs7QUFFQSxNQUFNQyxzQkFBTixDQUE2QjtBQU0zQkMsRUFBQUEsV0FBVyxDQUNUQyxNQUdDLEdBQUcsRUFKSyxFQUtUO0FBQ0EsU0FBS0Msa0JBQUwsR0FDRUQsTUFBTSxDQUFDQyxrQkFBUCxJQUNBLGdDQUNHLDRFQURILENBRkY7QUFLQSxTQUFLQyxlQUFMLEdBQXVCRixNQUFNLENBQUNFLGVBQTlCO0FBQ0EsU0FBS0MsU0FBTCxHQUFpQixDQUFDLENBQUNILE1BQU0sQ0FBQ0ksWUFBMUI7QUFDQSxTQUFLQyxjQUFMLEdBQXNCUixnQkFBdEI7QUFDRDs7QUFFRCxRQUFNUyxnQkFBTixHQUFzRDtBQUNwRCxRQUFJLEtBQUtILFNBQVQsRUFBb0I7QUFDbEIsWUFBTUksYUFBYSxHQUFHLE1BQU0sS0FBS0MsdUJBQUwsRUFBNUI7O0FBQ0EsVUFBSUQsYUFBSixFQUFtQjtBQUNqQixlQUFPQSxhQUFQO0FBQ0Q7QUFDRjs7QUFFRCxVQUFNRSxPQUFPLEdBQUcsTUFBTSxLQUFLUixrQkFBTCxDQUF3QlMsSUFBeEIsQ0FDcEJmLHNCQURvQixFQUVwQjtBQUFFZ0IsTUFBQUEsUUFBUSxFQUFFZjtBQUFaLEtBRm9CLEVBR3BCO0FBQUVnQixNQUFBQSxLQUFLLEVBQUU7QUFBVCxLQUhvQixDQUF0QjtBQU1BLFFBQUlDLGFB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QUFhLFFBQWIsSUFBeUJBLENBQUMsQ0FBQ3JCLElBQUYsR0FBU3BDLE1BQVQsR0FBa0IsQ0FBM0QsQ0FERSxHQUVILEtBRko7QUFHRCxDQUpEO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0EsTUFBTWtCLG1CQUFtQixHQUFHLFVBQVV3QyxHQUFWLEVBQXdCO0FBQ2xELFNBQ0UsT0FBT0EsR0FBUCxLQUFlLFFBQWYsSUFDQSxDQUFDbEMsS0FBSyxDQUFDQyxPQUFOLENBQWNpQyxHQUFkLENBREQsSUFFQUEsR0FBRyxLQUFLLElBRlIsSUFHQUEsR0FBRyxZQUFZQyxJQUFmLEtBQXdCLElBSHhCLElBSUFELEdBQUcsWUFBWUUsT0FBZixLQUEyQixJQUw3QjtBQU9ELENBUkQ7O2VBd0RlNUUsc0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcmVxdWlyZWRQYXJhbWV0ZXIgZnJvbSAnLi4vLi4vbGliL3JlcXVpcmVkUGFyYW1ldGVyJztcbmltcG9ydCBEYXRhYmFzZUNvbnRyb2xsZXIgZnJvbSAnLi9EYXRhYmFzZUNvbnRyb2xsZXInO1xuaW1wb3J0IENhY2hlQ29udHJvbGxlciBmcm9tICcuL0NhY2hlQ29udHJvbGxlcic7XG5cbmNvbnN0IEdyYXBoUUxDb25maWdDbGFzc05hbWUgPSAnX0dyYXBoUUxDb25maWcnO1xuY29uc3QgR3JhcGhRTENvbmZpZ0lkID0gJzEnO1xuY29uc3QgR3JhcGhRTENvbmZpZ0tleSA9ICdjb25maWcnO1xuXG5jbGFzcyBQYXJzZUdyYXBoUUxDb250cm9sbGVyIHtcbiAgZGF0YWJhc2VDb250cm9sbGVyOiBEYXRhYmFzZUNvbnRyb2xsZXI7XG4gIGNhY2hlQ29udHJvbGxlcjogQ2FjaGVDb250cm9sbGVyO1xuICBpc01vdW50ZWQ6IGJvb2xlYW47XG4gIGNvbmZpZ0NhY2hlS2V5OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcGFyYW1zOiB7XG4gICAgICBkYXRhYmFzZUNvbnRyb2xsZXI6IERhdGFiYXNlQ29udHJvbGxlcixcbiAgICAgIGNhY2hlQ29udHJvbGxlcjogQ2FjaGVDb250cm9sbGVyLFxuICAgIH0gPSB7fVxuICApIHtcbiAgICB0aGlzLmRhdGFiYXNlQ29udHJvbGxlciA9XG4gICAgICBwYXJhbXMuZGF0YWJhc2VDb250cm9sbGVyIHx8XG4gICAgICByZXF1aXJlZFBhcmFtZXRlcihcbiAgICAgICAgYFBhcnNlR3JhcGhRTENvbnRyb2xsZXIgcmVxdWlyZXMgYSBcImRhdGFiYXNlQ29udHJvbGxlclwiIHRvIGJlIGluc3RhbnRpYXRlZC5gXG4gICAgICApO1xuICAgIHRoaXMuY2FjaGVDb250cm9sbGVyID0gcGFyYW1zLmNhY2hlQ29udHJvbGxlcjtcbiAgICB0aGlzLmlzTW91bnRlZCA9ICEhcGFyYW1zLm1vdW50R3JhcGhRTDtcbiAgICB0aGlzLmNvbmZpZ0NhY2hlS2V5ID0gR3JhcGhRTENvbmZpZ0tleTtcbiAgfVxuXG4gIGFzeW5jIGdldEdyYXBoUUxDb25maWcoKTogUHJvbWlzZTxQYXJzZUdyYXBoUUxDb25maWc+IHtcbiAgICBpZiAodGhpcy5pc01vdW50ZWQpIHtcbiAgICAgIGNvbnN0IF9jYWNoZWRDb25maWcgPSBhd2FpdCB0aGlzLl9nZXRDYWNoZWRHcmFwaFFMQ29uZmlnKCk7XG4gICAgICBpZiAoX2NhY2hlZENvbmZpZykge1xuICAgICAgICByZXR1cm4gX2NhY2hlZENvbmZpZztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5kYXRhYmFzZUNvbnRyb2xsZXIuZmluZChcbiAgICAgIEdyYXBoUUxDb25maWdDbGFzc05hbWUsXG4gICAgICB7IG9iamVjdElkOiBHcmFwaFFMQ29uZmlnSWQgfSxcbiAgICAgIHsgbGltaXQ6IDEgfVxuICAgICk7XG5cbiAgICBsZXQgZ3JhcGhRTENvbmZpZztcbiAgICBpZiAocmVzdWx0cy5sZW5ndGggIT0gMSkge1xuICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gY29uZmlnIGluIHRoZSBkYXRhYmFzZSAtIHJldHVybiBlbXB0eSBjb25maWcuXG4gICAgICByZXR1cm4ge307XG4gICAgfSBlbHNlIHtcbiAgICAgIGdyYXBoUUxDb25maWcgPSByZXN1bHRzWzBdW0dyYXBoUUxDb25maWdLZXldO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzTW91bnRlZCkge1xuICAgICAgdGhpcy5fcHV0Q2FjaGVkR3JhcGhRTENvbmZpZyhncmFwaFFMQ29uZmlnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZ3JhcGhRTENvbmZpZztcbiAgfVxuXG4gIGFzeW5jIHVwZGF0ZUdyYXBoUUxDb25maWcoZ3JhcGhRTENvbmZpZzogUGFyc2VHcmFwaFFMQ29uZmlnKTogUHJvbWlzZTxQYXJzZUdyYXBoUUxDb25maWc+IHtcbiAgICAvLyB0aHJvd3MgaWYgaW52YWxpZFxuICAgIHRoaXMuX3ZhbGlkYXRlR3JhcGhRTENvbmZpZyhcbiAgICAgIGdyYXBoUUxDb25maWcgfHwgcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYSBncmFwaFFMQ29uZmlnIScpXG4gICAgKTtcblxuICAgIC8vIFRyYW5zZm9ybSBpbiBkb3Qgbm90YXRpb24gdG8gbWFrZSBzdXJlIGl0IHdvcmtzXG4gICAgY29uc3QgdXBkYXRlID0gT2JqZWN0LmtleXMoZ3JhcGhRTENvbmZpZykucmVkdWNlKFxuICAgICAgKGFjYywga2V5KSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgW0dyYXBoUUxDb25maWdLZXldOiB7XG4gICAgICAgICAgICAuLi5hY2NbR3JhcGhRTENvbmZpZ0tleV0sXG4gICAgICAgICAgICBba2V5XTogZ3JhcGhRTENvbmZpZ1trZXldLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgICAgeyBbR3JhcGhRTENvbmZpZ0tleV06IHt9IH1cbiAgICApO1xuXG4gICAgYXdhaXQgdGhpcy5kYXRhYmFzZUNvbnRyb2xsZXIudXBkYXRlKFxuICAgICAgR3JhcGhRTENvbmZpZ0NsYXNzTmFtZSxcbiAgICAgIHsgb2JqZWN0SWQ6IEdyYXBoUUxDb25maWdJZCB9LFxuICAgICAgdXBkYXRlLFxuICAgICAgeyB1cHNlcnQ6IHRydWUgfVxuICAgICk7XG5cbiAgICBpZiAodGhpcy5pc01vdW50ZWQpIHtcbiAgICAgIHRoaXMuX3B1dENhY2hlZEdyYXBoUUxDb25maWcoZ3JhcGhRTENvbmZpZyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgcmVzcG9uc2U6IHsgcmVzdWx0OiB0cnVlIH0gfTtcbiAgfVxuXG4gIF9nZXRDYWNoZWRHcmFwaFFMQ29uZmlnKCkge1xuICAgIHJldHVybiB0aGlzLmNhY2hlQ29udHJvbGxlci5ncmFwaFFMLmdldCh0aGlzLmNvbmZpZ0NhY2hlS2V5KTtcbiAgfVxuXG4gIF9wdXRDYWNoZWRHcmFwaFFMQ29uZmlnKGdyYXBoUUxDb25maWc6IFBhcnNlR3JhcGhRTENvbmZpZykge1xuICAgIHJldHVybiB0aGlzLmNhY2hlQ29udHJvbGxlci5ncmFwaFFMLnB1dCh0aGlzLmNvbmZpZ0NhY2hlS2V5LCBncmFwaFFMQ29uZmlnLCA2MDAwMCk7XG4gIH1cblxuICBfdmFsaWRhdGVHcmFwaFFMQ29uZmlnKGdyYXBoUUxDb25maWc6ID9QYXJzZUdyYXBoUUxDb25maWcpOiB2b2lkIHtcbiAgICBjb25zdCBlcnJvck1lc3NhZ2VzOiBzdHJpbmcgPSBbXTtcbiAgICBpZiAoIWdyYXBoUUxDb25maWcpIHtcbiAgICAgIGVycm9yTWVzc2FnZXMucHVzaCgnY2Fubm90IGJlIHVuZGVmaW5lZCwgbnVsbCBvciBlbXB0eScpO1xuICAgIH0gZWxzZSBpZiAoIWlzVmFsaWRTaW1wbGVPYmplY3QoZ3JhcGhRTENvbmZpZykpIHtcbiAgICAgIGVycm9yTWVzc2FnZXMucHVzaCgnbXVzdCBiZSBhIHZhbGlkIG9iamVjdCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB7XG4gICAgICAgIGVuYWJsZWRGb3JDbGFzc2VzID0gbnVsbCxcbiAgICAgICAgZGlzYWJsZWRGb3JDbGFzc2VzID0gbnVsbCxcbiAgICAgICAgY2xhc3NDb25maWdzID0gbnVsbCxcbiAgICAgICAgLi4uaW52YWxpZEtleXNcbiAgICAgIH0gPSBncmFwaFFMQ29uZmlnO1xuXG4gICAgICBpZiAoT2JqZWN0LmtleXMoaW52YWxpZEtleXMpLmxlbmd0aCkge1xuICAgICAgICBlcnJvck1lc3NhZ2VzLnB1c2goYGVuY291bnRlcmVkIGludmFsaWQga2V5czogWyR7T2JqZWN0LmtleXMoaW52YWxpZEtleXMpfV1gKTtcbiAgICAgIH1cbiAgICAgIGlmIChlbmFibGVkRm9yQ2xhc3NlcyAhPT0gbnVsbCAmJiAhaXNWYWxpZFN0cmluZ0FycmF5KGVuYWJsZWRGb3JDbGFzc2VzKSkge1xuICAgICAgICBlcnJvck1lc3NhZ2VzLnB1c2goYFwiZW5hYmxlZEZvckNsYXNzZXNcIiBpcyBub3QgYSB2YWxpZCBhcnJheWApO1xuICAgICAgfVxuICAgICAgaWYgKGRpc2FibGVkRm9yQ2xhc3NlcyAhPT0gbnVsbCAmJiAhaXNWYWxpZFN0cmluZ0FycmF5KGRpc2FibGVkRm9yQ2xhc3NlcykpIHtcbiAgICAgICAgZXJyb3JNZXNzYWdlcy5wdXNoKGBcImRpc2FibGVkRm9yQ2xhc3Nlc1wiIGlzIG5vdCBhIHZhbGlkIGFycmF5YCk7XG4gICAgICB9XG4gICAgICBpZiAoY2xhc3NDb25maWdzICE9PSBudWxsKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGNsYXNzQ29uZmlncykpIHtcbiAgICAgICAgICBjbGFzc0NvbmZpZ3MuZm9yRWFjaChjbGFzc0NvbmZpZyA9PiB7XG4gICAgICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSB0aGlzLl92YWxpZGF0ZUNsYXNzQ29uZmlnKGNsYXNzQ29uZmlnKTtcbiAgICAgICAgICAgIGlmIChlcnJvck1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlcy5wdXNoKFxuICAgICAgICAgICAgICAgIGBjbGFzc0NvbmZpZzoke2NsYXNzQ29uZmlnLmNsYXNzTmFtZX0gaXMgaW52YWxpZCBiZWNhdXNlICR7ZXJyb3JNZXNzYWdlfWBcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBlcnJvck1lc3NhZ2VzLnB1c2goYFwiY2xhc3NDb25maWdzXCIgaXMgbm90IGEgdmFsaWQgYXJyYXlgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZXJyb3JNZXNzYWdlcy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBncmFwaFFMQ29uZmlnOiAke2Vycm9yTWVzc2FnZXMuam9pbignOyAnKX1gKTtcbiAgICB9XG4gIH1cblxuICBfdmFsaWRhdGVDbGFzc0NvbmZpZyhjbGFzc0NvbmZpZzogP1BhcnNlR3JhcGhRTENsYXNzQ29uZmlnKTogc3RyaW5nIHwgdm9pZCB7XG4gICAgaWYgKCFpc1ZhbGlkU2ltcGxlT2JqZWN0KGNsYXNzQ29uZmlnKSkge1xuICAgICAgcmV0dXJuICdpdCBtdXN0IGJlIGEgdmFsaWQgb2JqZWN0JztcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgeyBjbGFzc05hbWUsIHR5cGUgPSBudWxsLCBxdWVyeSA9IG51bGwsIG11dGF0aW9uID0gbnVsbCwgLi4uaW52YWxpZEtleXMgfSA9IGNsYXNzQ29uZmlnO1xuICAgICAgaWYgKE9iamVjdC5rZXlzKGludmFsaWRLZXlzKS5sZW5ndGgpIHtcbiAgICAgICAgcmV0dXJuIGBcImludmFsaWRLZXlzXCIgWyR7T2JqZWN0LmtleXMoaW52YWxpZEtleXMpfV0gc2hvdWxkIG5vdCBiZSBwcmVzZW50YDtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgY2xhc3NOYW1lICE9PSAnc3RyaW5nJyB8fCAhY2xhc3NOYW1lLnRyaW0oKS5sZW5ndGgpIHtcbiAgICAgICAgLy8gVE9ETyBjb25zaWRlciBjaGVja2luZyBjbGFzcyBleGlzdHMgaW4gc2NoZW1hP1xuICAgICAgICByZXR1cm4gYFwiY2xhc3NOYW1lXCIgbXVzdCBiZSBhIHZhbGlkIHN0cmluZ2A7XG4gICAgICB9XG4gICAgICBpZiAodHlwZSAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoIWlzVmFsaWRTaW1wbGVPYmplY3QodHlwZSkpIHtcbiAgICAgICAgICByZXR1cm4gYFwidHlwZVwiIG11c3QgYmUgYSB2YWxpZCBvYmplY3RgO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHtcbiAgICAgICAgICBpbnB1dEZpZWxkcyA9IG51bGwsXG4gICAgICAgICAgb3V0cHV0RmllbGRzID0gbnVsbCxcbiAgICAgICAgICBjb25zdHJhaW50RmllbGRzID0gbnVsbCxcbiAgICAgICAgICBzb3J0RmllbGRzID0gbnVsbCxcbiAgICAgICAgICAuLi5pbnZhbGlkS2V5c1xuICAgICAgICB9ID0gdHlwZTtcbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKGludmFsaWRLZXlzKS5sZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm4gYFwidHlwZVwiIGNvbnRhaW5zIGludmFsaWQga2V5cywgWyR7T2JqZWN0LmtleXMoaW52YWxpZEtleXMpfV1gO1xuICAgICAgICB9IGVsc2UgaWYgKG91dHB1dEZpZWxkcyAhPT0gbnVsbCAmJiAhaXNWYWxpZFN0cmluZ0FycmF5KG91dHB1dEZpZWxkcykpIHtcbiAgICAgICAgICByZXR1cm4gYFwib3V0cHV0RmllbGRzXCIgbXVzdCBiZSBhIHZhbGlkIHN0cmluZyBhcnJheWA7XG4gICAgICAgIH0gZWxzZSBpZiAoY29uc3RyYWludEZpZWxkcyAhPT0gbnVsbCAmJiAhaXNWYWxpZFN0cmluZ0FycmF5KGNvbnN0cmFpbnRGaWVsZHMpKSB7XG4gICAgICAgICAgcmV0dXJuIGBcImNvbnN0cmFpbnRGaWVsZHNcIiBtdXN0IGJlIGEgdmFsaWQgc3RyaW5nIGFycmF5YDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc29ydEZpZWxkcyAhPT0gbnVsbCkge1xuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHNvcnRGaWVsZHMpKSB7XG4gICAgICAgICAgICBsZXQgZXJyb3JNZXNzYWdlO1xuICAgICAgICAgICAgc29ydEZpZWxkcy5ldmVyeSgoc29ydEZpZWxkLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICBpZiAoIWlzVmFsaWRTaW1wbGVPYmplY3Qoc29ydEZpZWxkKSkge1xuICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGBcInNvcnRGaWVsZFwiIGF0IGluZGV4ICR7aW5kZXh9IGlzIG5vdCBhIHZhbGlkIG9iamVjdGA7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgZmllbGQsIGFzYywgZGVzYywgLi4uaW52YWxpZEtleXMgfSA9IHNvcnRGaWVsZDtcbiAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LmtleXMoaW52YWxpZEtleXMpLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gYFwic29ydEZpZWxkXCIgYXQgaW5kZXggJHtpbmRleH0gY29udGFpbnMgaW52YWxpZCBrZXlzLCBbJHtPYmplY3Qua2V5cyhcbiAgICAgICAgICAgICAgICAgICAgaW52YWxpZEtleXNcbiAgICAgICAgICAgICAgICAgICl9XWA7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZmllbGQgIT09ICdzdHJpbmcnIHx8IGZpZWxkLnRyaW0oKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gYFwic29ydEZpZWxkXCIgYXQgaW5kZXggJHtpbmRleH0gZGlkIG5vdCBwcm92aWRlIHRoZSBcImZpZWxkXCIgYXMgYSBzdHJpbmdgO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBhc2MgIT09ICdib29sZWFuJyB8fCB0eXBlb2YgZGVzYyAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yTWVzc2FnZSA9IGBcInNvcnRGaWVsZFwiIGF0IGluZGV4ICR7aW5kZXh9IGRpZCBub3QgcHJvdmlkZSBcImFzY1wiIG9yIFwiZGVzY1wiIGFzIGJvb2xlYW5zYDtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKGVycm9yTWVzc2FnZSkge1xuICAgICAgICAgICAgICByZXR1cm4gZXJyb3JNZXNzYWdlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gYFwic29ydEZpZWxkc1wiIG11c3QgYmUgYSB2YWxpZCBhcnJheS5gO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoaW5wdXRGaWVsZHMgIT09IG51bGwpIHtcbiAgICAgICAgICBpZiAoaXNWYWxpZFNpbXBsZU9iamVjdChpbnB1dEZpZWxkcykpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgY3JlYXRlID0gbnVsbCwgdXBkYXRlID0gbnVsbCwgLi4uaW52YWxpZEtleXMgfSA9IGlucHV0RmllbGRzO1xuICAgICAgICAgICAgaWYgKE9iamVjdC5rZXlzKGludmFsaWRLZXlzKS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGBcImlucHV0RmllbGRzXCIgY29udGFpbnMgaW52YWxpZCBrZXlzOiBbJHtPYmplY3Qua2V5cyhpbnZhbGlkS2V5cyl9XWA7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpZiAodXBkYXRlICE9PSBudWxsICYmICFpc1ZhbGlkU3RyaW5nQXJyYXkodXBkYXRlKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBgXCJpbnB1dEZpZWxkcy51cGRhdGVcIiBtdXN0IGJlIGEgdmFsaWQgc3RyaW5nIGFycmF5YDtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChjcmVhdGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWlzVmFsaWRTdHJpbmdBcnJheShjcmVhdGUpKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gYFwiaW5wdXRGaWVsZHMuY3JlYXRlXCIgbXVzdCBiZSBhIHZhbGlkIHN0cmluZyBhcnJheWA7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICAgICAgICAgICAgICAgIGlmICghY3JlYXRlLmluY2x1ZGVzKCd1c2VybmFtZScpIHx8ICFjcmVhdGUuaW5jbHVkZXMoJ3Bhc3N3b3JkJykpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGBcImlucHV0RmllbGRzLmNyZWF0ZVwiIG11c3QgaW5jbHVkZSByZXF1aXJlZCBmaWVsZHMsIHVzZXJuYW1lIGFuZCBwYXNzd29yZGA7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBgXCJpbnB1dEZpZWxkc1wiIG11c3QgYmUgYSB2YWxpZCBvYmplY3RgO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHF1ZXJ5ICE9PSBudWxsKSB7XG4gICAgICAgIGlmIChpc1ZhbGlkU2ltcGxlT2JqZWN0KHF1ZXJ5KSkge1xuICAgICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgIGZpbmQgPSBudWxsLFxuICAgICAgICAgICAgZ2V0ID0gbnVsbCxcbiAgICAgICAgICAgIGZpbmRBbGlhcyA9IG51bGwsXG4gICAgICAgICAgICBnZXRBbGlhcyA9IG51bGwsXG4gICAgICAgICAgICAuLi5pbnZhbGlkS2V5c1xuICAgICAgICAgIH0gPSBxdWVyeTtcbiAgICAgICAgICBpZiAoT2JqZWN0LmtleXMoaW52YWxpZEtleXMpLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGBcInF1ZXJ5XCIgY29udGFpbnMgaW52YWxpZCBrZXlzLCBbJHtPYmplY3Qua2V5cyhpbnZhbGlkS2V5cyl9XWA7XG4gICAgICAgICAgfSBlbHNlIGlmIChmaW5kICE9PSBudWxsICYmIHR5cGVvZiBmaW5kICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIHJldHVybiBgXCJxdWVyeS5maW5kXCIgbXVzdCBiZSBhIGJvb2xlYW5gO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZ2V0ICE9PSBudWxsICYmIHR5cGVvZiBnZXQgIT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgcmV0dXJuIGBcInF1ZXJ5LmdldFwiIG11c3QgYmUgYSBib29sZWFuYDtcbiAgICAgICAgICB9IGVsc2UgaWYgKGZpbmRBbGlhcyAhPT0gbnVsbCAmJiB0eXBlb2YgZmluZEFsaWFzICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGBcInF1ZXJ5LmZpbmRBbGlhc1wiIG11c3QgYmUgYSBzdHJpbmdgO1xuICAgICAgICAgIH0gZWxzZSBpZiAoZ2V0QWxpYXMgIT09IG51bGwgJiYgdHlwZW9mIGdldEFsaWFzICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIGBcInF1ZXJ5LmdldEFsaWFzXCIgbXVzdCBiZSBhIHN0cmluZ2A7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBgXCJxdWVyeVwiIG11c3QgYmUgYSB2YWxpZCBvYmplY3RgO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobXV0YXRpb24gIT09IG51bGwpIHtcbiAgICAgICAgaWYgKGlzVmFsaWRTaW1wbGVPYmplY3QobXV0YXRpb24pKSB7XG4gICAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgY3JlYXRlID0gbnVsbCxcbiAgICAgICAgICAgIHVwZGF0ZSA9IG51bGwsXG4gICAgICAgICAgICBkZXN0cm95ID0gbnVsbCxcbiAgICAgICAgICAgIGNyZWF0ZUFsaWFzID0gbnVsbCxcbiAgICAgICAgICAgIHVwZGF0ZUFsaWFzID0gbnVsbCxcbiAgICAgICAgICAgIGRlc3Ryb3lBbGlhcyA9IG51bGwsXG4gICAgICAgICAgICAuLi5pbnZhbGlkS2V5c1xuICAgICAgICAgIH0gPSBtdXRhdGlvbjtcbiAgICAgICAgICBpZiAoT2JqZWN0LmtleXMoaW52YWxpZEtleXMpLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIGBcIm11dGF0aW9uXCIgY29udGFpbnMgaW52YWxpZCBrZXlzLCBbJHtPYmplY3Qua2V5cyhpbnZhbGlkS2V5cyl9XWA7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChjcmVhdGUgIT09IG51bGwgJiYgdHlwZW9mIGNyZWF0ZSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwibXV0YXRpb24uY3JlYXRlXCIgbXVzdCBiZSBhIGJvb2xlYW5gO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodXBkYXRlICE9PSBudWxsICYmIHR5cGVvZiB1cGRhdGUgIT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgcmV0dXJuIGBcIm11dGF0aW9uLnVwZGF0ZVwiIG11c3QgYmUgYSBib29sZWFuYDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGRlc3Ryb3kgIT09IG51bGwgJiYgdHlwZW9mIGRlc3Ryb3kgIT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgcmV0dXJuIGBcIm11dGF0aW9uLmRlc3Ryb3lcIiBtdXN0IGJlIGEgYm9vbGVhbmA7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChjcmVhdGVBbGlhcyAhPT0gbnVsbCAmJiB0eXBlb2YgY3JlYXRlQWxpYXMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwibXV0YXRpb24uY3JlYXRlQWxpYXNcIiBtdXN0IGJlIGEgc3RyaW5nYDtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHVwZGF0ZUFsaWFzICE9PSBudWxsICYmIHR5cGVvZiB1cGRhdGVBbGlhcyAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHJldHVybiBgXCJtdXRhdGlvbi51cGRhdGVBbGlhc1wiIG11c3QgYmUgYSBzdHJpbmdgO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZGVzdHJveUFsaWFzICE9PSBudWxsICYmIHR5cGVvZiBkZXN0cm95QWxpYXMgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gYFwibXV0YXRpb24uZGVzdHJveUFsaWFzXCIgbXVzdCBiZSBhIHN0cmluZ2A7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBgXCJtdXRhdGlvblwiIG11c3QgYmUgYSB2YWxpZCBvYmplY3RgO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmNvbnN0IGlzVmFsaWRTdHJpbmdBcnJheSA9IGZ1bmN0aW9uIChhcnJheSk6IGJvb2xlYW4ge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheShhcnJheSlcbiAgICA/ICFhcnJheS5zb21lKHMgPT4gdHlwZW9mIHMgIT09ICdzdHJpbmcnIHx8IHMudHJpbSgpLmxlbmd0aCA8IDEpXG4gICAgOiBmYWxzZTtcbn07XG4vKipcbiAqIEVuc3VyZXMgdGhlIG9iaiBpcyBhIHNpbXBsZSBKU09OL3t9XG4gKiBvYmplY3QsIGkuZS4gbm90IGFuIGFycmF5LCBudWxsLCBkYXRlXG4gKiBldGMuXG4gKi9cbmNvbnN0IGlzVmFsaWRTaW1wbGVPYmplY3QgPSBmdW5jdGlvbiAob2JqKTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgdHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiZcbiAgICAhQXJyYXkuaXNBcnJheShvYmopICYmXG4gICAgb2JqICE9PSBudWxsICYmXG4gICAgb2JqIGluc3RhbmNlb2YgRGF0ZSAhPT0gdHJ1ZSAmJlxuICAgIG9iaiBpbnN0YW5jZW9mIFByb21pc2UgIT09IHRydWVcbiAgKTtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFyc2VHcmFwaFFMQ29uZmlnIHtcbiAgZW5hYmxlZEZvckNsYXNzZXM/OiBzdHJpbmdbXTtcbiAgZGlzYWJsZWRGb3JDbGFzc2VzPzogc3RyaW5nW107XG4gIGNsYXNzQ29uZmlncz86IFBhcnNlR3JhcGhRTENsYXNzQ29uZmlnW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFyc2VHcmFwaFFMQ2xhc3NDb25maWcge1xuICBjbGFzc05hbWU6IHN0cmluZztcbiAgLyogVGhlIGB0eXBlYCBvYmplY3QgY29udGFpbnMgb3B0aW9ucyBmb3IgaG93IHRoZSBjbGFzcyB0eXBlcyBhcmUgZ2VuZXJhdGVkICovXG4gIHR5cGU6ID97XG4gICAgLyogRmllbGRzIHRoYXQgYXJlIGFsbG93ZWQgd2hlbiBjcmVhdGluZyBvciB1cGRhdGluZyBhbiBvYmplY3QuICovXG4gICAgaW5wdXRGaWVsZHM6ID97XG4gICAgICAvKiBMZWF2ZSBibGFuayB0byBhbGxvdyBhbGwgYXZhaWxhYmxlIGZpZWxkcyBpbiB0aGUgc2NoZW1hLiAqL1xuICAgICAgY3JlYXRlPzogc3RyaW5nW10sXG4gICAgICB1cGRhdGU/OiBzdHJpbmdbXSxcbiAgICB9LFxuICAgIC8qIEZpZWxkcyBvbiB0aGUgZWRnZXMgdGhhdCBjYW4gYmUgcmVzb2x2ZWQgZnJvbSBhIHF1ZXJ5LCBpLmUuIHRoZSBSZXN1bHQgVHlwZS4gKi9cbiAgICBvdXRwdXRGaWVsZHM6ID8oc3RyaW5nW10pLFxuICAgIC8qIEZpZWxkcyBieSB3aGljaCBhIHF1ZXJ5IGNhbiBiZSBmaWx0ZXJlZCwgaS5lLiB0aGUgYHdoZXJlYCBvYmplY3QuICovXG4gICAgY29uc3RyYWludEZpZWxkczogPyhzdHJpbmdbXSksXG4gICAgLyogRmllbGRzIGJ5IHdoaWNoIGEgcXVlcnkgY2FuIGJlIHNvcnRlZDsgKi9cbiAgICBzb3J0RmllbGRzOiA/KHtcbiAgICAgIGZpZWxkOiBzdHJpbmcsXG4gICAgICBhc2M6IGJvb2xlYW4sXG4gICAgICBkZXNjOiBib29sZWFuLFxuICAgIH1bXSksXG4gIH07XG4gIC8qIFRoZSBgcXVlcnlgIG9iamVjdCBjb250YWlucyBvcHRpb25zIGZvciB3aGljaCBjbGFzcyBxdWVyaWVzIGFyZSBnZW5lcmF0ZWQgKi9cbiAgcXVlcnk6ID97XG4gICAgZ2V0OiA/Ym9vbGVhbixcbiAgICBmaW5kOiA/Ym9vbGVhbixcbiAgICBmaW5kQWxpYXM6ID9TdHJpbmcsXG4gICAgZ2V0QWxpYXM6ID9TdHJpbmcsXG4gIH07XG4gIC8qIFRoZSBgbXV0YXRpb25gIG9iamVjdCBjb250YWlucyBvcHRpb25zIGZvciB3aGljaCBjbGFzcyBtdXRhdGlvbnMgYXJlIGdlbmVyYXRlZCAqL1xuICBtdXRhdGlvbjogP3tcbiAgICBjcmVhdGU6ID9ib29sZWFuLFxuICAgIHVwZGF0ZTogP2Jvb2xlYW4sXG4gICAgLy8gZGVsZXRlIGlzIGEgcmVzZXJ2ZWQga2V5IHdvcmQgaW4ganNcbiAgICBkZXN0cm95OiA/Ym9vbGVhbixcbiAgICBjcmVhdGVBbGlhczogP1N0cmluZyxcbiAgICB1cGRhdGVBbGlhczogP1N0cmluZyxcbiAgICBkZXN0cm95QWxpYXM6ID9TdHJpbmcsXG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBhcnNlR3JhcGhRTENvbnRyb2xsZXI7XG5leHBvcnQgeyBHcmFwaFFMQ29uZmlnQ2xhc3NOYW1lLCBHcmFwaFFMQ29uZmlnSWQsIEdyYXBoUUxDb25maWdLZXkgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/PushController.js b/lib/Controllers/PushController.js deleted file mode 100644 index e1608934b3..0000000000 --- a/lib/Controllers/PushController.js +++ /dev/null @@ -1,257 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.PushController = void 0; - -var _node = require("parse/node"); - -var _RestQuery = _interopRequireDefault(require("../RestQuery")); - -var _RestWrite = _interopRequireDefault(require("../RestWrite")); - -var _Auth = require("../Auth"); - -var _StatusHandler = require("../StatusHandler"); - -var _utils = require("../Push/utils"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class PushController { - sendPush(body = {}, where = {}, config, auth, onPushStatusSaved = () => {}, now = new Date()) { - if (!config.hasPushSupport) { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Missing push configuration'); - } // Replace the expiration_time and push_time with a valid Unix epoch milliseconds time - - - body.expiration_time = PushController.getExpirationTime(body); - body.expiration_interval = PushController.getExpirationInterval(body); - - if (body.expiration_time && body.expiration_interval) { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Both expiration_time and expiration_interval cannot be set'); - } // Immediate push - - - if (body.expiration_interval && !Object.prototype.hasOwnProperty.call(body, 'push_time')) { - const ttlMs = body.expiration_interval * 1000; - body.expiration_time = new Date(now.valueOf() + ttlMs).valueOf(); - } - - const pushTime = PushController.getPushTime(body); - - if (pushTime && pushTime.date !== 'undefined') { - body['push_time'] = PushController.formatPushTime(pushTime); - } // TODO: If the req can pass the checking, we return immediately instead of waiting - // pushes to be sent. We probably change this behaviour in the future. - - - let badgeUpdate = () => { - return Promise.resolve(); - }; - - if (body.data && body.data.badge) { - const badge = body.data.badge; - let restUpdate = {}; - - if (typeof badge == 'string' && badge.toLowerCase() === 'increment') { - restUpdate = { - badge: { - __op: 'Increment', - amount: 1 - } - }; - } else if (typeof badge == 'object' && typeof badge.__op == 'string' && badge.__op.toLowerCase() == 'increment' && Number(badge.amount)) { - restUpdate = { - badge: { - __op: 'Increment', - amount: badge.amount - } - }; - } else if (Number(badge)) { - restUpdate = { - badge: badge - }; - } else { - throw "Invalid value for badge, expected number or 'Increment' or {increment: number}"; - } // Force filtering on only valid device tokens - - - const updateWhere = (0, _utils.applyDeviceTokenExists)(where); - - badgeUpdate = () => { - // Build a real RestQuery so we can use it in RestWrite - const restQuery = new _RestQuery.default(config, (0, _Auth.master)(config), '_Installation', updateWhere); - return restQuery.buildRestWhere().then(() => { - const write = new _RestWrite.default(config, (0, _Auth.master)(config), '_Installation', restQuery.restWhere, restUpdate); - write.runOptions.many = true; - return write.execute(); - }); - }; - } - - const pushStatus = (0, _StatusHandler.pushStatusHandler)(config); - return Promise.resolve().then(() => { - return pushStatus.setInitial(body, where); - }).then(() => { - onPushStatusSaved(pushStatus.objectId); - return badgeUpdate(); - }).then(() => { - // Update audience lastUsed and timesUsed - if (body.audience_id) { - const audienceId = body.audience_id; - var updateAudience = { - lastUsed: { - __type: 'Date', - iso: new Date().toISOString() - }, - timesUsed: { - __op: 'Increment', - amount: 1 - } - }; - const write = new _RestWrite.default(config, (0, _Auth.master)(config), '_Audience', { - objectId: audienceId - }, updateAudience); - write.execute(); - } // Don't wait for the audience update promise to resolve. - - - return Promise.resolve(); - }).then(() => { - if (Object.prototype.hasOwnProperty.call(body, 'push_time') && config.hasPushScheduledSupport) { - return Promise.resolve(); - } - - return config.pushControllerQueue.enqueue(body, where, config, auth, pushStatus); - }).catch(err => { - return pushStatus.fail(err).then(() => { - throw err; - }); - }); - } - /** - * Get expiration time from the request body. - * @param {Object} request A request object - * @returns {Number|undefined} The expiration time if it exists in the request - */ - - - static getExpirationTime(body = {}) { - var hasExpirationTime = Object.prototype.hasOwnProperty.call(body, 'expiration_time'); - - if (!hasExpirationTime) { - return; - } - - var expirationTimeParam = body['expiration_time']; - var expirationTime; - - if (typeof expirationTimeParam === 'number') { - expirationTime = new Date(expirationTimeParam * 1000); - } else if (typeof expirationTimeParam === 'string') { - expirationTime = new Date(expirationTimeParam); - } else { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['expiration_time'] + ' is not valid time.'); - } // Check expirationTime is valid or not, if it is not valid, expirationTime is NaN - - - if (!isFinite(expirationTime)) { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['expiration_time'] + ' is not valid time.'); - } - - return expirationTime.valueOf(); - } - - static getExpirationInterval(body = {}) { - const hasExpirationInterval = Object.prototype.hasOwnProperty.call(body, 'expiration_interval'); - - if (!hasExpirationInterval) { - return; - } - - var expirationIntervalParam = body['expiration_interval']; - - if (typeof expirationIntervalParam !== 'number' || expirationIntervalParam <= 0) { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, `expiration_interval must be a number greater than 0`); - } - - return expirationIntervalParam; - } - /** - * Get push time from the request body. - * @param {Object} request A request object - * @returns {Number|undefined} The push time if it exists in the request - */ - - - static getPushTime(body = {}) { - var hasPushTime = Object.prototype.hasOwnProperty.call(body, 'push_time'); - - if (!hasPushTime) { - return; - } - - var pushTimeParam = body['push_time']; - var date; - var isLocalTime = true; - - if (typeof pushTimeParam === 'number') { - date = new Date(pushTimeParam * 1000); - } else if (typeof pushTimeParam === 'string') { - isLocalTime = !PushController.pushTimeHasTimezoneComponent(pushTimeParam); - date = new Date(pushTimeParam); - } else { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['push_time'] + ' is not valid time.'); - } // Check pushTime is valid or not, if it is not valid, pushTime is NaN - - - if (!isFinite(date)) { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, body['push_time'] + ' is not valid time.'); - } - - return { - date, - isLocalTime - }; - } - /** - * Checks if a ISO8601 formatted date contains a timezone component - * @param pushTimeParam {string} - * @returns {boolean} - */ - - - static pushTimeHasTimezoneComponent(pushTimeParam) { - const offsetPattern = /(.+)([+-])\d\d:\d\d$/; - return pushTimeParam.indexOf('Z') === pushTimeParam.length - 1 || offsetPattern.test(pushTimeParam) // 2007-04-05T12:30Z - ; // 2007-04-05T12:30.000+02:00, 2007-04-05T12:30.000-02:00 - } - /** - * Converts a date to ISO format in UTC time and strips the timezone if `isLocalTime` is true - * @param date {Date} - * @param isLocalTime {boolean} - * @returns {string} - */ - - - static formatPushTime({ - date, - isLocalTime - }) { - if (isLocalTime) { - // Strip 'Z' - const isoString = date.toISOString(); - return isoString.substring(0, isoString.indexOf('Z')); - } - - return date.toISOString(); - } - -} - -exports.PushController = PushController; -var _default = PushController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9QdXNoQ29udHJvbGxlci5qcyJdLCJuYW1lcyI6WyJQdXNoQ29udHJvbGxlciIsInNlbmRQdXNoIiwiYm9keSIsIndoZXJlIiwiY29uZmlnIiwiYXV0aCIsIm9uUHVzaFN0YXR1c1NhdmVkIiwibm93IiwiRGF0ZSIsImhhc1B1c2hTdXBwb3J0IiwiUGFyc2UiLCJFcnJvciIsIlBVU0hfTUlTQ09ORklHVVJFRCIsImV4cGlyYXRpb25fdGltZSIsImdldEV4cGlyYXRpb25UaW1lIiwiZXhwaXJhdGlvbl9pbnRlcnZhbCIsImdldEV4cGlyYXRpb25JbnRlcnZhbCIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInR0bE1zIiwidmFsdWVPZiIsInB1c2hUaW1lIiwiZ2V0UHVzaFRpbWUiLCJkYXRlIiwiZm9ybWF0UHVzaFRpbWUiLCJiYWRnZVVwZGF0ZSIsIlByb21pc2UiLCJyZXNvbHZlIiwiZGF0YSIsImJhZGdlIiwicmVzdFVwZGF0ZSIsInRvTG93ZXJDYXNlIiwiX19vcCIsImFtb3VudCIsIk51bWJlciIsInVwZGF0ZVdoZXJlIiwicmVzdFF1ZXJ5IiwiUmVzdFF1ZXJ5IiwiYnVpbGRSZXN0V2hlcmUiLCJ0aGVuIiwid3JpdGUiLCJSZXN0V3JpdGUiLCJyZXN0V2hlcmUiLCJydW5PcHRpb25zIiwibWFueSIsImV4ZWN1dGUiLCJwdXNoU3RhdHVzIiwic2V0SW5pdGlhbCIsIm9iamVjdElkIiwiYXVkaWVuY2VfaWQiLCJhdWRpZW5jZUlkIiwidXBkYXRlQXVkaWVuY2UiLCJsYXN0VXNlZCIsIl9fdHlwZSIsImlzbyIsInRvSVNPU3RyaW5nIiwidGltZXNVc2VkIiwiaGFzUHVzaFNjaGVkdWxlZFN1cHBvcnQiLCJwdXNoQ29udHJvbGxlclF1ZXVlIiwiZW5xdWV1ZSIsImNhdGNoIiwiZXJyIiwiZmFpbCIsImhhc0V4cGlyYXRpb25UaW1lIiwiZXhwaXJhdGlvblRpbWVQYXJhbSIsImV4cGlyYXRpb25UaW1lIiwiaXNGaW5pdGUiLCJoYXNFeHBpcmF0aW9uSW50ZXJ2YWwiLCJleHBpcmF0aW9uSW50ZXJ2YWxQYXJhbSIsImhhc1B1c2hUaW1lIiwicHVzaFRpbWVQYXJhbSIsImlzTG9jYWxUaW1lIiwicHVzaFRpbWVIYXNUaW1lem9uZUNvbXBvbmVudCIsIm9mZnNldFBhdHRlcm4iLCJpbmRleE9mIiwibGVuZ3RoIiwidGVzdCIsImlzb1N0cmluZyIsInN1YnN0cmluZyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRU8sTUFBTUEsY0FBTixDQUFxQjtBQUMxQkMsRUFBQUEsUUFBUSxDQUFDQyxJQUFJLEdBQUcsRUFBUixFQUFZQyxLQUFLLEdBQUcsRUFBcEIsRUFBd0JDLE1BQXhCLEVBQWdDQyxJQUFoQyxFQUFzQ0MsaUJBQWlCLEdBQUcsTUFBTSxDQUFFLENBQWxFLEVBQW9FQyxHQUFHLEdBQUcsSUFBSUMsSUFBSixFQUExRSxFQUFzRjtBQUM1RixRQUFJLENBQUNKLE1BQU0sQ0FBQ0ssY0FBWixFQUE0QjtBQUMxQixZQUFNLElBQUlDLFlBQU1DLEtBQVYsQ0FBZ0JELFlBQU1DLEtBQU4sQ0FBWUMsa0JBQTVCLEVBQWdELDRCQUFoRCxDQUFOO0FBQ0QsS0FIMkYsQ0FLNUY7OztBQUNBVixJQUFBQSxJQUFJLENBQUNXLGVBQUwsR0FBdUJiLGNBQWMsQ0FBQ2MsaUJBQWYsQ0FBaUNaLElBQWpDLENBQXZCO0FBQ0FBLElBQUFBLElBQUksQ0FBQ2EsbUJBQUwsR0FBMkJmLGNBQWMsQ0FBQ2dCLHFCQUFmLENBQXFDZCxJQUFyQyxDQUEzQjs7QUFDQSxRQUFJQSxJQUFJLENBQUNXLGVBQUwsSUFBd0JYLElBQUksQ0FBQ2EsbUJBQWpDLEVBQXNEO0FBQ3BELFlBQU0sSUFBSUwsWUFBTUMsS0FBVixDQUNKRCxZQUFNQyxLQUFOLENBQVlDLGtCQURSLEVBRUosNERBRkksQ0FBTjtBQUlELEtBYjJGLENBZTVGOzs7QUFDQSxRQUFJVixJ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SUFBZCxDQUFtQk4sYUFBbkIsQ0FEN0QsQ0FDK0Y7QUFEL0YsS0FGa0UsQ0FJL0Q7QUFDSjtBQUVEO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0UsU0FBTzlDLGNBQVAsQ0FBc0I7QUFBRUQsSUFBQUEsSUFBRjtBQUFRZ0QsSUFBQUE7QUFBUixHQUF0QixFQUFtRjtBQUNqRixRQUFJQSxXQUFKLEVBQWlCO0FBQ2Y7QUFDQSxZQUFNTSxTQUFTLEdBQUd0RCxJQUFJLENBQUNnQyxXQUFMLEVBQWxCO0FBQ0EsYUFBT3NCLFNBQVMsQ0FBQ0MsU0FBVixDQUFvQixDQUFwQixFQUF1QkQsU0FBUyxDQUFDSCxPQUFWLENBQWtCLEdBQWxCLENBQXZCLENBQVA7QUFDRDs7QUFDRCxXQUFPbkQsSUFBSSxDQUFDZ0MsV0FBTCxFQUFQO0FBQ0Q7O0FBbk95Qjs7O2VBc09iekQsYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBhcnNlIH0gZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgUmVzdFF1ZXJ5IGZyb20gJy4uL1Jlc3RRdWVyeSc7XG5pbXBvcnQgUmVzdFdyaXRlIGZyb20gJy4uL1Jlc3RXcml0ZSc7XG5pbXBvcnQgeyBtYXN0ZXIgfSBmcm9tICcuLi9BdXRoJztcbmltcG9ydCB7IHB1c2hTdGF0dXNIYW5kbGVyIH0gZnJvbSAnLi4vU3RhdHVzSGFuZGxlcic7XG5pbXBvcnQgeyBhcHBseURldmljZVRva2VuRXhpc3RzIH0gZnJvbSAnLi4vUHVzaC91dGlscyc7XG5cbmV4cG9ydCBjbGFzcyBQdXNoQ29udHJvbGxlciB7XG4gIHNlbmRQdXNoKGJvZHkgPSB7fSwgd2hlcmUgPSB7fSwgY29uZmlnLCBhdXRoLCBvblB1c2hTdGF0dXNTYXZlZCA9ICgpID0+IHt9LCBub3cgPSBuZXcgRGF0ZSgpKSB7XG4gICAgaWYgKCFjb25maWcuaGFzUHVzaFN1cHBvcnQpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5QVVNIX01JU0NPTkZJR1VSRUQsICdNaXNzaW5nIHB1c2ggY29uZmlndXJhdGlvbicpO1xuICAgIH1cblxuICAgIC8vIFJlcGxhY2UgdGhlIGV4cGlyYXRpb25fdGltZSBhbmQgcHVzaF90aW1lIHdpdGggYSB2YWxpZCBVbml4IGVwb2NoIG1pbGxpc2Vjb25kcyB0aW1lXG4gICAgYm9keS5leHBpcmF0aW9uX3RpbWUgPSBQdXNoQ29udHJvbGxlci5nZXRFeHBpcmF0aW9uVGltZShib2R5KTtcbiAgICBib2R5LmV4cGlyYXRpb25faW50ZXJ2YWwgPSBQdXNoQ29udHJvbGxlci5nZXRFeHBpcmF0aW9uSW50ZXJ2YWwoYm9keSk7XG4gICAgaWYgKGJvZHkuZXhwaXJhdGlvbl90aW1lICYmIGJvZHkuZXhwaXJhdGlvbl9pbnRlcnZhbCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5QVVNIX01JU0NPTkZJR1VSRUQsXG4gICAgICAgICdCb3RoIGV4cGlyYXRpb25fdGltZSBhbmQgZXhwaXJhdGlvbl9pbnRlcnZhbCBjYW5ub3QgYmUgc2V0J1xuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBJbW1lZGlhdGUgcHVzaFxuICAgIGlmIChib2R5LmV4cGlyYXRpb25faW50ZXJ2YWwgJiYgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChib2R5LCAncHVzaF90aW1lJykpIHtcbiAgICAgIGNvbnN0IHR0bE1zID0gYm9keS5leHBpcmF0aW9uX2ludGVydmFsICogMTAwMDtcbiAgICAgIGJvZHkuZXhwaXJhdGlvbl90aW1lID0gbmV3IERhdGUobm93LnZhbHVlT2YoKSArIHR0bE1zKS52YWx1ZU9mKCk7XG4gICAgfVxuXG4gICAgY29uc3QgcHVzaFRpbWUgPSBQdXNoQ29udHJvbGxlci5nZXRQdXNoVGltZShib2R5KTtcbiAgICBpZiAocHVzaFRpbWUgJiYgcHVzaFRpbWUuZGF0ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGJvZHlbJ3B1c2hfdGltZSddID0gUHVzaENvbnRyb2xsZXIuZm9ybWF0UHVzaFRpbWUocHVzaFRpbWUpO1xuICAgIH1cblxuICAgIC8vIFRPRE86IElmIHRoZSByZXEgY2FuIHBhc3MgdGhlIGNoZWNraW5nLCB3ZSByZXR1cm4gaW1tZWRpYXRlbHkgaW5zdGVhZCBvZiB3YWl0aW5nXG4gICAgLy8gcHVzaGVzIHRvIGJlIHNlbnQuIFdlIHByb2JhYmx5IGNoYW5nZSB0aGlzIGJlaGF2aW91ciBpbiB0aGUgZnV0dXJlLlxuICAgIGxldCBiYWRnZVVwZGF0ZSA9ICgpID0+IHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9O1xuXG4gICAgaWYgKGJvZHkuZGF0YSAmJiBib2R5LmRhdGEuYmFkZ2UpIHtcbiAgICAgIGNvbnN0IGJhZGdlID0gYm9keS5kYXRhLmJhZGdlO1xuICAgICAgbGV0IHJlc3RVcGRhdGUgPSB7fTtcbiAgICAgIGlmICh0eXBlb2YgYmFkZ2UgPT0gJ3N0cmluZycgJiYgYmFkZ2UudG9Mb3dlckNhc2UoKSA9PT0gJ2luY3JlbWVudCcpIHtcbiAgICAgICAgcmVzdFVwZGF0ZSA9IHsgYmFkZ2U6IHsgX19vcDogJ0luY3JlbWVudCcsIGFtb3VudDogMSB9IH07XG4gICAgICB9IGVsc2UgaWYgKFxuICAgICAgICB0eXBlb2YgYmFkZ2UgPT0gJ29iamVjdCcgJiZcbiAgICAgICAgdHlwZW9mIGJhZGdlLl9fb3AgPT0gJ3N0cmluZycgJiZcbiAgICAgICAgYmFkZ2UuX19vcC50b0xvd2VyQ2FzZSgpID09ICdpbmNyZW1lbnQnICYmXG4gICAgICAgIE51bWJlcihiYWRnZS5hbW91bnQpXG4gICAgICApIHtcbiAgICAgICAgcmVzdFVwZGF0ZSA9IHsgYmFkZ2U6IHsgX19vcDogJ0luY3JlbWVudCcsIGFtb3VudDogYmFkZ2UuYW1vdW50IH0gfTtcbiAgICAgIH0gZWxzZSBpZiAoTnVtYmVyKGJhZGdlKSkge1xuICAgICAgICByZXN0VXBkYXRlID0geyBiYWRnZTogYmFkZ2UgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IFwiSW52YWxpZCB2YWx1ZSBmb3IgYmFkZ2UsIGV4cGVjdGVkIG51bWJlciBvciAnSW5jcmVtZW50JyBvciB7aW5jcmVtZW50OiBudW1iZXJ9XCI7XG4gICAgICB9XG5cbiAgICAgIC8vIEZvcmNlIGZpbHRlcmluZyBvbiBvbmx5IHZhbGlkIGRldmljZSB0b2tlbnNcbiAgICAgIGNvbnN0IHVwZGF0ZVdoZXJlID0gYXBwbHlEZXZpY2VUb2tlbkV4aXN0cyh3aGVyZSk7XG4gICAgICBiYWRnZVVwZGF0ZSA9ICgpID0+IHtcbiAgICAgICAgLy8gQnVpbGQgYSByZWFsIFJlc3RRdWVyeSBzbyB3ZSBjYW4gdXNlIGl0IGluIFJlc3RXcml0ZVxuICAgICAgICBjb25zdCByZXN0UXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KGNvbmZpZywgbWFzdGVyKGNvbmZpZyksICdfSW5zdGFsbGF0aW9uJywgdXBkYXRlV2hlcmUpO1xuICAgICAgICByZXR1cm4gcmVzdFF1ZXJ5LmJ1aWxkUmVzdFdoZXJlKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgY29uc3Qgd3JpdGUgPSBuZXcgUmVzdFdyaXRlKFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgbWFzdGVyKGNvbmZpZyksXG4gICAgICAgICAgICAnX0luc3RhbGxhdGlvbicsXG4gICAgICAgICAgICByZXN0UXVlcnkucmVzdFdoZXJlLFxuICAgICAgICAgICAgcmVzdFVwZGF0ZVxuICAgICAgICAgICk7XG4gICAgICAgICAgd3JpdGUucnVuT3B0aW9ucy5tYW55ID0gdHJ1ZTtcbiAgICAgICAgICByZXR1cm4gd3JpdGUuZXhlY3V0ZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH07XG4gICAgfVxuICAgIGNvbnN0IHB1c2hTdGF0dXMgPSBwdXNoU3RhdHVzSGFuZGxlcihjb25maWcpO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gcHVzaFN0YXR1cy5zZXRJbml0aWFsKGJvZHksIHdoZXJlKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIG9uUHVzaFN0YXR1c1NhdmVkKHB1c2hTdGF0dXMub2JqZWN0SWQpO1xuICAgICAgICByZXR1cm4gYmFkZ2VVcGRhdGUoKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIC8vIFVwZGF0ZSBhdWRpZW5jZSBsYXN0VXNlZCBhbmQgdGltZXNVc2VkXG4gICAgICAgIGlmIChib2R5LmF1ZGllbmNlX2lkKSB7XG4gICAgICAgICAgY29uc3QgYXVkaWVuY2VJZCA9IGJvZHkuYXVkaWVuY2VfaWQ7XG5cbiAgICAgICAgICB2YXIgdXBkYXRlQXVkaWVuY2UgPSB7XG4gICAgICAgICAgICBsYXN0VXNlZDogeyBfX3R5cGU6ICdEYXRlJywgaXNvOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkgfSxcbiAgICAgICAgICAgIHRpbWVzVXNlZDogeyBfX29wOiAnSW5jcmVtZW50JywgYW1vdW50OiAxIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgICBjb25zdCB3cml0ZSA9IG5ldyBSZXN0V3JpdGUoXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBtYXN0ZXIoY29uZmlnKSxcbiAgICAgICAgICAgICdfQXVkaWVuY2UnLFxuICAgICAgICAgICAgeyBvYmplY3RJZDogYXVkaWVuY2VJZCB9LFxuICAgICAgICAgICAgdXBkYXRlQXVkaWVuY2VcbiAgICAgICAgICApO1xuICAgICAgICAgIHdyaXRlLmV4ZWN1dGUoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBEb24ndCB3YWl0IGZvciB0aGUgYXVkaWVuY2UgdXBkYXRlIHByb21pc2UgdG8gcmVzb2x2ZS5cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChib2R5LCAncHVzaF90aW1lJykgJiZcbiAgICAgICAgICBjb25maWcuaGFzUHVzaFNjaGVkdWxlZFN1cHBvcnRcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb25maWcucHVzaENvbnRyb2xsZXJRdWV1ZS5lbnF1ZXVlKGJvZHksIHdoZXJlLCBjb25maWcsIGF1dGgsIHB1c2hTdGF0dXMpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4ge1xuICAgICAgICByZXR1cm4gcHVzaFN0YXR1cy5mYWlsKGVycikudGhlbigoKSA9PiB7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBleHBpcmF0aW9uIHRpbWUgZnJvbSB0aGUgcmVxdWVzdCBib2R5LlxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxdWVzdCBBIHJlcXVlc3Qgb2JqZWN0XG4gICAqIEByZXR1cm5zIHtOdW1iZXJ8dW5kZWZpbmVkfSBUaGUgZXhwaXJhdGlvbiB0aW1lIGlmIGl0IGV4aXN0cyBpbiB0aGUgcmVxdWVzdFxuICAgKi9cbiAgc3RhdGljIGdldEV4cGlyYXRpb25UaW1lKGJvZHkgPSB7fSkge1xuICAgIHZhciBoYXNFeHBpcmF0aW9uVGltZSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChib2R5LCAnZXhwaXJhdGlvbl90aW1lJyk7XG4gICAgaWYgKCFoYXNFeHBpcmF0aW9uVGltZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgZXhwaXJhdGlvblRpbWVQYXJhbSA9IGJvZHlbJ2V4cGlyYXRpb25fdGltZSddO1xuICAgIHZhciBleHBpcmF0aW9uVGltZTtcbiAgICBpZiAodHlwZW9mIGV4cGlyYXRpb25UaW1lUGFyYW0gPT09ICdudW1iZXInKSB7XG4gICAgICBleHBpcmF0aW9uVGltZSA9IG5ldyBEYXRlKGV4cGlyYXRpb25UaW1lUGFyYW0gKiAxMDAwKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBleHBpcmF0aW9uVGltZVBhcmFtID09PSAnc3RyaW5nJykge1xuICAgICAgZXhwaXJhdGlvblRpbWUgPSBuZXcgRGF0ZShleHBpcmF0aW9uVGltZVBhcmFtKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5QVVNIX01JU0NPTkZJR1VSRUQsXG4gICAgICAgIGJvZHlbJ2V4cGlyYXRpb25fdGltZSddICsgJyBpcyBub3QgdmFsaWQgdGltZS4nXG4gICAgICApO1xuICAgIH1cbiAgICAvLyBDaGVjayBleHBpcmF0aW9uVGltZSBpcyB2YWxpZCBvciBub3QsIGlmIGl0IGlzIG5vdCB2YWxpZCwgZXhwaXJhdGlvblRpbWUgaXMgTmFOXG4gICAgaWYgKCFpc0Zpbml0ZShleHBpcmF0aW9uVGltZSkpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICBib2R5WydleHBpcmF0aW9uX3RpbWUnXSArICcgaXMgbm90IHZhbGlkIHRpbWUuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIGV4cGlyYXRpb25UaW1lLnZhbHVlT2YoKTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRFeHBpcmF0aW9uSW50ZXJ2YWwoYm9keSA9IHt9KSB7XG4gICAgY29uc3QgaGFzRXhwaXJhdGlvbkludGVydmFsID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGJvZHksICdleHBpcmF0aW9uX2ludGVydmFsJyk7XG4gICAgaWYgKCFoYXNFeHBpcmF0aW9uSW50ZXJ2YWwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgZXhwaXJhdGlvbkludGVydmFsUGFyYW0gPSBib2R5WydleHBpcmF0aW9uX2ludGVydmFsJ107XG4gICAgaWYgKHR5cGVvZiBleHBpcmF0aW9uSW50ZXJ2YWxQYXJhbSAhPT0gJ251bWJlcicgfHwgZXhwaXJhdGlvbkludGVydmFsUGFyYW0gPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5QVVNIX01JU0NPTkZJR1VSRUQsXG4gICAgICAgIGBleHBpcmF0aW9uX2ludGVydmFsIG11c3QgYmUgYSBudW1iZXIgZ3JlYXRlciB0aGFuIDBgXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gZXhwaXJhdGlvbkludGVydmFsUGFyYW07XG4gIH1cblxuICAvKipcbiAgICogR2V0IHB1c2ggdGltZSBmcm9tIHRoZSByZXF1ZXN0IGJvZHkuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSByZXF1ZXN0IEEgcmVxdWVzdCBvYmplY3RcbiAgICogQHJldHVybnMge051bWJlcnx1bmRlZmluZWR9IFRoZSBwdXNoIHRpbWUgaWYgaXQgZXhpc3RzIGluIHRoZSByZXF1ZXN0XG4gICAqL1xuICBzdGF0aWMgZ2V0UHVzaFRpbWUoYm9keSA9IHt9KSB7XG4gICAgdmFyIGhhc1B1c2hUaW1lID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGJvZHksICdwdXNoX3RpbWUnKTtcbiAgICBpZiAoIWhhc1B1c2hUaW1lKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciBwdXNoVGltZVBhcmFtID0gYm9keVsncHVzaF90aW1lJ107XG4gICAgdmFyIGRhdGU7XG4gICAgdmFyIGlzTG9jYWxUaW1lID0gdHJ1ZTtcblxuICAgIGlmICh0eXBlb2YgcHVzaFRpbWVQYXJhbSA9PT0gJ251bWJlcicpIHtcbiAgICAgIGRhdGUgPSBuZXcgRGF0ZShwdXNoVGltZVBhcmFtICogMTAwMCk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcHVzaFRpbWVQYXJhbSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlzTG9jYWxUaW1lID0gIVB1c2hDb250cm9sbGVyLnB1c2hUaW1lSGFzVGltZXpvbmVDb21wb25lbnQocHVzaFRpbWVQYXJhbSk7XG4gICAgICBkYXRlID0gbmV3IERhdGUocHVzaFRpbWVQYXJhbSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICBib2R5WydwdXNoX3RpbWUnXSArICcgaXMgbm90IHZhbGlkIHRpbWUuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgLy8gQ2hlY2sgcHVzaFRpbWUgaXMgdmFsaWQgb3Igbm90LCBpZiBpdCBpcyBub3QgdmFsaWQsIHB1c2hUaW1lIGlzIE5hTlxuICAgIGlmICghaXNGaW5pdGUoZGF0ZSkpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICBib2R5WydwdXNoX3RpbWUnXSArICcgaXMgbm90IHZhbGlkIHRpbWUuJ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgZGF0ZSxcbiAgICAgIGlzTG9jYWxUaW1lLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGlmIGEgSVNPODYwMSBmb3JtYXR0ZWQgZGF0ZSBjb250YWlucyBhIHRpbWV6b25lIGNvbXBvbmVudFxuICAgKiBAcGFyYW0gcHVzaFRpbWVQYXJhbSB7c3RyaW5nfVxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICovXG4gIHN0YXRpYyBwdXNoVGltZUhhc1RpbWV6b25lQ29tcG9uZW50KHB1c2hUaW1lUGFyYW06IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IG9mZnNldFBhdHRlcm4gPSAvKC4rKShbKy1dKVxcZFxcZDpcXGRcXGQkLztcbiAgICByZXR1cm4gKFxuICAgICAgcHVzaFRpbWVQYXJhbS5pbmRleE9mKCdaJykgPT09IHB1c2hUaW1lUGFyYW0ubGVuZ3RoIC0gMSB8fCBvZmZzZXRQYXR0ZXJuLnRlc3QocHVzaFRpbWVQYXJhbSkgLy8gMjAwNy0wNC0wNVQxMjozMFpcbiAgICApOyAvLyAyMDA3LTA0LTA1VDEyOjMwLjAwMCswMjowMCwgMjAwNy0wNC0wNVQxMjozMC4wMDAtMDI6MDBcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhIGRhdGUgdG8gSVNPIGZvcm1hdCBpbiBVVEMgdGltZSBhbmQgc3RyaXBzIHRoZSB0aW1lem9uZSBpZiBgaXNMb2NhbFRpbWVgIGlzIHRydWVcbiAgICogQHBhcmFtIGRhdGUge0RhdGV9XG4gICAqIEBwYXJhbSBpc0xvY2FsVGltZSB7Ym9vbGVhbn1cbiAgICogQHJldHVybnMge3N0cmluZ31cbiAgICovXG4gIHN0YXRpYyBmb3JtYXRQdXNoVGltZSh7IGRhdGUsIGlzTG9jYWxUaW1lIH06IHsgZGF0ZTogRGF0ZSwgaXNMb2NhbFRpbWU6IGJvb2xlYW4gfSkge1xuICAgIGlmIChpc0xvY2FsVGltZSkge1xuICAgICAgLy8gU3RyaXAgJ1onXG4gICAgICBjb25zdCBpc29TdHJpbmcgPSBkYXRlLnRvSVNPU3RyaW5nKCk7XG4gICAgICByZXR1cm4gaXNvU3RyaW5nLnN1YnN0cmluZygwLCBpc29TdHJpbmcuaW5kZXhPZignWicpKTtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGUudG9JU09TdHJpbmcoKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQdXNoQ29udHJvbGxlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/SchemaCache.js b/lib/Controllers/SchemaCache.js deleted file mode 100644 index 638bb91ad5..0000000000 --- a/lib/Controllers/SchemaCache.js +++ /dev/null @@ -1,75 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _cryptoUtils = require("../cryptoUtils"); - -var _defaults = _interopRequireDefault(require("../defaults")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const MAIN_SCHEMA = '__MAIN_SCHEMA'; -const SCHEMA_CACHE_PREFIX = '__SCHEMA'; - -class SchemaCache { - constructor(cacheController, ttl = _defaults.default.schemaCacheTTL, singleCache = false) { - this.ttl = ttl; - - if (typeof ttl == 'string') { - this.ttl = parseInt(ttl); - } - - this.cache = cacheController; - this.prefix = SCHEMA_CACHE_PREFIX; - - if (!singleCache) { - this.prefix += (0, _cryptoUtils.randomString)(20); - } - } - - getAllClasses() { - if (!this.ttl) { - return Promise.resolve(null); - } - - return this.cache.get(this.prefix + MAIN_SCHEMA); - } - - setAllClasses(schema) { - if (!this.ttl) { - return Promise.resolve(null); - } - - return this.cache.put(this.prefix + MAIN_SCHEMA, schema, this.ttl); - } - - getOneSchema(className) { - if (!this.ttl) { - return Promise.resolve(null); - } - - return this.cache.get(this.prefix + MAIN_SCHEMA).then(cachedSchemas => { - cachedSchemas = cachedSchemas || []; - const schema = cachedSchemas.find(cachedSchema => { - return cachedSchema.className === className; - }); - - if (schema) { - return Promise.resolve(schema); - } - - return Promise.resolve(null); - }); - } - - clear() { - return this.cache.del(this.prefix + MAIN_SCHEMA); - } - -} - -exports.default = SchemaCache; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9TY2hlbWFDYWNoZS5qcyJdLCJuYW1lcyI6WyJNQUlOX1NDSEVNQSIsIlNDSEVNQV9DQUNIRV9QUkVGSVgiLCJTY2hlbWFDYWNoZSIsImNvbnN0cnVjdG9yIiwiY2FjaGVDb250cm9sbGVyIiwidHRsIiwiZGVmYXVsdHMiLCJzY2hlbWFDYWNoZVRUTCIsInNpbmdsZUNhY2hlIiwicGFyc2VJbnQiLCJjYWNoZSIsInByZWZpeCIsImdldEFsbENsYXNzZXMiLCJQcm9taXNlIiwicmVzb2x2ZSIsImdldCIsInNldEFsbENsYXNzZXMiLCJzY2hlbWEiLCJwdXQiLCJnZXRPbmVTY2hlbWEiLCJjbGFzc05hbWUiLCJ0aGVuIiwiY2FjaGVkU2NoZW1hcyIsImZpbmQiLCJjYWNoZWRTY2hlbWEiLCJjbGVhciIsImRlbCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUdBOztBQUNBOzs7O0FBSkEsTUFBTUEsV0FBVyxHQUFHLGVBQXBCO0FBQ0EsTUFBTUMsbUJBQW1CLEdBQUcsVUFBNUI7O0FBS2UsTUFBTUMsV0FBTixDQUFrQjtBQUcvQkMsRUFBQUEsV0FBVyxDQUFDQyxlQUFELEVBQWtCQyxHQUFHLEdBQUdDLGtCQUFTQyxjQUFqQyxFQUFpREMsV0FBVyxHQUFHLEtBQS9ELEVBQXNFO0FBQy9FLFNBQUtILEdBQUwsR0FBV0EsR0FBWDs7QUFDQSxRQUFJLE9BQU9BLEdBQVAsSUFBYyxRQUFsQixFQUE0QjtBQUMxQixXQUFLQSxHQUFMLEdBQVdJLFFBQVEsQ0FBQ0osR0FBRCxDQUFuQjtBQUNEOztBQUNELFNBQUtLLEtBQUwsR0FBYU4sZUFBYjtBQUNBLFNBQUtPLE1BQUwsR0FBY1YsbUJBQWQ7O0FBQ0EsUUFBSSxDQUFDTyxXQUFMLEVBQWtCO0FBQ2hCLFdBQUtHLE1BQUwsSUFBZSwrQkFBYSxFQUFiLENBQWY7QUFDRDtBQUNGOztBQUVEQyxFQUFBQSxhQUFhLEdBQUc7QUFDZCxRQUFJLENBQUMsS0FBS1AsR0FBVixFQUFlO0FBQ2IsYUFBT1EsT0FBTyxDQUFDQyxPQUFSLENBQWdCLElBQWhCLENBQVA7QUFDRDs7QUFDRCxXQUFPLEtBQUtKLEtBQUwsQ0FBV0ssR0FBWCxDQUFlLEtBQUtKLE1BQUwsR0FBY1gsV0FBN0IsQ0FBUDtBQUNEOztBQUVEZ0IsRUFBQUEsYUFBYSxDQUFDQyxNQUFELEVBQVM7QUFDcEIsUUFBSSxDQUFDLEtBQUtaLEdBQVYsRUFBZTtBQUNiLGFBQU9RLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQixJQUFoQixDQUFQO0FBQ0Q7O0FBQ0QsV0FBTyxLQUFLSixLQUFMLENBQVdRLEdBQVgsQ0FBZSxLQUFLUCxNQUFMLEdBQWNYLFdBQTdCLEVBQTBDaUIsTUFBMUMsRUFBa0QsS0FBS1osR0FBdkQsQ0FBUDtBQUNEOztBQUVEYyxFQUFBQSxZQUFZLENBQUNDLFNBQUQsRUFBWTtBQUN0QixRQUFJLENBQUMsS0FBS2YsR0FBVixFQUFlO0FBQ2IsYUFBT1EsT0FBTyxDQUFDQyxPQUFSLENBQWdCLElBQWhCLENBQVA7QUFDRDs7QUFDRCxXQUFPLEtBQUtKLEtBQUwsQ0FBV0ssR0FBWCxDQUFlLEtBQUtKLE1BQUwsR0FBY1gsV0FBN0IsRUFBMENxQixJQUExQyxDQUErQ0MsYUFBYSxJQUFJO0FBQ3JFQSxNQUFBQSxhQUFhLEdBQUdBLGFBQWEsSUFBSSxFQUFqQztBQUNBLFlBQU1MLE1BQU0sR0FBR0ssYUFBYSxDQUFDQyxJQUFkLENBQW1CQyxZQUFZLElBQUk7QUFDaEQsZUFBT0EsWUFBWSxDQUFDSixTQUFiLEtBQTJCQSxTQUFsQztBQUNELE9BRmMsQ0FBZjs7QUFHQSxVQUFJSCxNQUFKLEVBQVk7QUFDVixlQUFPSixPQUFPLENBQUNDLE9BQVIsQ0FBZ0JHLE1BQWhCLENBQVA7QUFDRDs7QUFDRCxhQUFPSixPQUFPLENBQUNDLE9BQVIsQ0FBZ0IsSUFBaEIsQ0FBUDtBQUNELEtBVE0sQ0FBUDtBQVVEOztBQUVEVyxFQUFBQSxLQUFLLEdBQUc7QUFDTixXQUFPLEtBQUtmLEtBQUwsQ0FBV2dCLEdBQVgsQ0FBZSxLQUFLZixNQUFMLEdBQWNYLFdBQTdCLENBQVA7QUFDRDs7QUEvQzhCIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgTUFJTl9TQ0hFTUEgPSAnX19NQUlOX1NDSEVNQSc7XG5jb25zdCBTQ0hFTUFfQ0FDSEVfUFJFRklYID0gJ19fU0NIRU1BJztcblxuaW1wb3J0IHsgcmFuZG9tU3RyaW5nIH0gZnJvbSAnLi4vY3J5cHRvVXRpbHMnO1xuaW1wb3J0IGRlZmF1bHRzIGZyb20gJy4uL2RlZmF1bHRzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU2NoZW1hQ2FjaGUge1xuICBjYWNoZTogT2JqZWN0O1xuXG4gIGNvbnN0cnVjdG9yKGNhY2hlQ29udHJvbGxlciwgdHRsID0gZGVmYXVsdHMuc2NoZW1hQ2FjaGVUVEwsIHNpbmdsZUNhY2hlID0gZmFsc2UpIHtcbiAgICB0aGlzLnR0bCA9IHR0bDtcbiAgICBpZiAodHlwZW9mIHR0bCA9PSAnc3RyaW5nJykge1xuICAgICAgdGhpcy50dGwgPSBwYXJzZUludCh0dGwpO1xuICAgIH1cbiAgICB0aGlzLmNhY2hlID0gY2FjaGVDb250cm9sbGVyO1xuICAgIHRoaXMucHJlZml4ID0gU0NIRU1BX0NBQ0hFX1BSRUZJWDtcbiAgICBpZiAoIXNpbmdsZUNhY2hlKSB7XG4gICAgICB0aGlzLnByZWZpeCArPSByYW5kb21TdHJpbmcoMjApO1xuICAgIH1cbiAgfVxuXG4gIGdldEFsbENsYXNzZXMoKSB7XG4gICAgaWYgKCF0aGlzLnR0bCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShudWxsKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0KHRoaXMucHJlZml4ICsgTUFJTl9TQ0hFTUEpO1xuICB9XG5cbiAgc2V0QWxsQ2xhc3NlcyhzY2hlbWEpIHtcbiAgICBpZiAoIXRoaXMudHRsKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG51bGwpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jYWNoZS5wdXQodGhpcy5wcmVmaXggKyBNQUlOX1NDSEVNQSwgc2NoZW1hLCB0aGlzLnR0bCk7XG4gIH1cblxuICBnZXRPbmVTY2hlbWEoY2xhc3NOYW1lKSB7XG4gICAgaWYgKCF0aGlzLnR0bCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShudWxsKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0KHRoaXMucHJlZml4ICsgTUFJTl9TQ0hFTUEpLnRoZW4oY2FjaGVkU2NoZW1hcyA9PiB7XG4gICAgICBjYWNoZWRTY2hlbWFzID0gY2FjaGVkU2NoZW1hcyB8fCBbXTtcbiAgICAgIGNvbnN0IHNjaGVtYSA9IGNhY2hlZFNjaGVtYXMuZmluZChjYWNoZWRTY2hlbWEgPT4ge1xuICAgICAgICByZXR1cm4gY2FjaGVkU2NoZW1hLmNsYXNzTmFtZSA9PT0gY2xhc3NOYW1lO1xuICAgICAgfSk7XG4gICAgICBpZiAoc2NoZW1hKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoc2NoZW1hKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobnVsbCk7XG4gICAgfSk7XG4gIH1cblxuICBjbGVhcigpIHtcbiAgICByZXR1cm4gdGhpcy5jYWNoZS5kZWwodGhpcy5wcmVmaXggKyBNQUlOX1NDSEVNQSk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/SchemaController.js b/lib/Controllers/SchemaController.js deleted file mode 100644 index cf11ba237f..0000000000 --- a/lib/Controllers/SchemaController.js +++ /dev/null @@ -1,1670 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.classNameIsValid = classNameIsValid; -exports.fieldNameIsValid = fieldNameIsValid; -exports.invalidClassNameMessage = invalidClassNameMessage; -exports.buildMergedSchemaObject = buildMergedSchemaObject; -exports.VolatileClassesSchemas = exports.convertSchemaToAdapterSchema = exports.defaultColumns = exports.systemClasses = exports.load = exports.SchemaController = exports.default = void 0; - -var _StorageAdapter = require("../Adapters/Storage/StorageAdapter"); - -var _DatabaseController = _interopRequireDefault(require("./DatabaseController")); - -var _Config = _interopRequireDefault(require("../Config")); - -var _deepcopy = _interopRequireDefault(require("deepcopy")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } - -// This class handles schema validation, persistence, and modification. -// -// Each individual Schema object should be immutable. The helpers to -// do things with the Schema just return a new schema when the schema -// is changed. -// -// The canonical place to store this Schema is in the database itself, -// in a _SCHEMA collection. This is not the right way to do it for an -// open source framework, but it's backward compatible, so we're -// keeping it this way for now. -// -// In API-handling code, you should only use the Schema class via the -// DatabaseController. This will let us replace the schema logic for -// different databases. -// TODO: hide all schema logic inside the database adapter. -// -disable-next -const Parse = require('parse/node').Parse; - -const defaultColumns = Object.freeze({ - // Contain the default columns for every parse object type (except _Join collection) - _Default: { - objectId: { - type: 'String' - }, - createdAt: { - type: 'Date' - }, - updatedAt: { - type: 'Date' - }, - ACL: { - type: 'ACL' - } - }, - // The additional default columns for the _User collection (in addition to DefaultCols) - _User: { - username: { - type: 'String' - }, - password: { - type: 'String' - }, - email: { - type: 'String' - }, - emailVerified: { - type: 'Boolean' - }, - authData: { - type: 'Object' - } - }, - // The additional default columns for the _Installation collection (in addition to DefaultCols) - _Installation: { - installationId: { - type: 'String' - }, - deviceToken: { - type: 'String' - }, - channels: { - type: 'Array' - }, - deviceType: { - type: 'String' - }, - pushType: { - type: 'String' - }, - GCMSenderId: { - type: 'String' - }, - timeZone: { - type: 'String' - }, - localeIdentifier: { - type: 'String' - }, - badge: { - type: 'Number' - }, - appVersion: { - type: 'String' - }, - appName: { - type: 'String' - }, - appIdentifier: { - type: 'String' - }, - parseVersion: { - type: 'String' - } - }, - // The additional default columns for the _Role collection (in addition to DefaultCols) - _Role: { - name: { - type: 'String' - }, - users: { - type: 'Relation', - targetClass: '_User' - }, - roles: { - type: 'Relation', - targetClass: '_Role' - } - }, - // The additional default columns for the _Session collection (in addition to DefaultCols) - _Session: { - restricted: { - type: 'Boolean' - }, - user: { - type: 'Pointer', - targetClass: '_User' - }, - installationId: { - type: 'String' - }, - sessionToken: { - type: 'String' - }, - expiresAt: { - type: 'Date' - }, - createdWith: { - type: 'Object' - } - }, - _Product: { - productIdentifier: { - type: 'String' - }, - download: { - type: 'File' - }, - downloadName: { - type: 'String' - }, - icon: { - type: 'File' - }, - order: { - type: 'Number' - }, - title: { - type: 'String' - }, - subtitle: { - type: 'String' - } - }, - _PushStatus: { - pushTime: { - type: 'String' - }, - source: { - type: 'String' - }, - // rest or webui - query: { - type: 'String' - }, - // the stringified JSON query - payload: { - type: 'String' - }, - // the stringified JSON payload, - title: { - type: 'String' - }, - expiry: { - type: 'Number' - }, - expiration_interval: { - type: 'Number' - }, - status: { - type: 'String' - }, - numSent: { - type: 'Number' - }, - numFailed: { - type: 'Number' - }, - pushHash: { - type: 'String' - }, - errorMessage: { - type: 'Object' - }, - sentPerType: { - type: 'Object' - }, - failedPerType: { - type: 'Object' - }, - sentPerUTCOffset: { - type: 'Object' - }, - failedPerUTCOffset: { - type: 'Object' - }, - count: { - type: 'Number' - } // tracks # of batches queued and pending - - }, - _JobStatus: { - jobName: { - type: 'String' - }, - source: { - type: 'String' - }, - status: { - type: 'String' - }, - message: { - type: 'String' - }, - params: { - type: 'Object' - }, - // params received when calling the job - finishedAt: { - type: 'Date' - } - }, - _JobSchedule: { - jobName: { - type: 'String' - }, - description: { - type: 'String' - }, - params: { - type: 'String' - }, - startAfter: { - type: 'String' - }, - daysOfWeek: { - type: 'Array' - }, - timeOfDay: { - type: 'String' - }, - lastRun: { - type: 'Number' - }, - repeatMinutes: { - type: 'Number' - } - }, - _Hooks: { - functionName: { - type: 'String' - }, - className: { - type: 'String' - }, - triggerName: { - type: 'String' - }, - url: { - type: 'String' - } - }, - _GlobalConfig: { - objectId: { - type: 'String' - }, - params: { - type: 'Object' - }, - masterKeyOnly: { - type: 'Object' - } - }, - _GraphQLConfig: { - objectId: { - type: 'String' - }, - config: { - type: 'Object' - } - }, - _Audience: { - objectId: { - type: 'String' - }, - name: { - type: 'String' - }, - query: { - type: 'String' - }, - //storing query as JSON string to prevent "Nested keys should not contain the '$' or '.' characters" error - lastUsed: { - type: 'Date' - }, - timesUsed: { - type: 'Number' - } - }, - _Idempotency: { - reqId: { - type: 'String' - }, - expire: { - type: 'Date' - } - } -}); -exports.defaultColumns = defaultColumns; -const requiredColumns = Object.freeze({ - _Product: ['productIdentifier', 'icon', 'order', 'title', 'subtitle'], - _Role: ['name', 'ACL'] -}); -const invalidColumns = ['length']; -const systemClasses = Object.freeze(['_User', '_Installation', '_Role', '_Session', '_Product', '_PushStatus', '_JobStatus', '_JobSchedule', '_Audience', '_Idempotency']); -exports.systemClasses = systemClasses; -const volatileClasses = Object.freeze(['_JobStatus', '_PushStatus', '_Hooks', '_GlobalConfig', '_GraphQLConfig', '_JobSchedule', '_Audience', '_Idempotency']); // Anything that start with role - -const roleRegex = /^role:.*/; // Anything that starts with userField (allowed for protected fields only) - -const protectedFieldsPointerRegex = /^userField:.*/; // * permission - -const publicRegex = /^\*$/; -const authenticatedRegex = /^authenticated$/; -const requiresAuthenticationRegex = /^requiresAuthentication$/; -const clpPointerRegex = /^pointerFields$/; // regex for validating entities in protectedFields object - -const protectedFieldsRegex = Object.freeze([protectedFieldsPointerRegex, publicRegex, authenticatedRegex, roleRegex]); // clp regex - -const clpFieldsRegex = Object.freeze([clpPointerRegex, publicRegex, requiresAuthenticationRegex, roleRegex]); - -function validatePermissionKey(key, userIdRegExp) { - let matchesSome = false; - - for (const regEx of clpFieldsRegex) { - if (key.match(regEx) !== null) { - matchesSome = true; - break; - } - } // userId depends on startup options so it's dynamic - - - const valid = matchesSome || key.match(userIdRegExp) !== null; - - if (!valid) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `'${key}' is not a valid key for class level permissions`); - } -} - -function validateProtectedFieldsKey(key, userIdRegExp) { - let matchesSome = false; - - for (const regEx of protectedFieldsRegex) { - if (key.match(regEx) !== null) { - matchesSome = true; - break; - } - } // userId regex depends on launch options so it's dynamic - - - const valid = matchesSome || key.match(userIdRegExp) !== null; - - if (!valid) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `'${key}' is not a valid key for class level permissions`); - } -} - -const CLPValidKeys = Object.freeze(['find', 'count', 'get', 'create', 'update', 'delete', 'addField', 'readUserFields', 'writeUserFields', 'protectedFields']); // validation before setting class-level permissions on collection - -function validateCLP(perms, fields, userIdRegExp) { - if (!perms) { - return; - } - - for (const operationKey in perms) { - if (CLPValidKeys.indexOf(operationKey) == -1) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `${operationKey} is not a valid operation for class level permissions`); - } - - const operation = perms[operationKey]; // proceed with next operationKey - // throws when root fields are of wrong type - - validateCLPjson(operation, operationKey); - - if (operationKey === 'readUserFields' || operationKey === 'writeUserFields') { - // validate grouped pointer permissions - // must be an array with field names - for (const fieldName of operation) { - validatePointerPermission(fieldName, fields, operationKey); - } // readUserFields and writerUserFields do not have nesdted fields - // proceed with next operationKey - - - continue; - } // validate protected fields - - - if (operationKey === 'protectedFields') { - for (const entity in operation) { - // throws on unexpected key - validateProtectedFieldsKey(entity, userIdRegExp); - const protectedFields = operation[entity]; - - if (!Array.isArray(protectedFields)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `'${protectedFields}' is not a valid value for protectedFields[${entity}] - expected an array.`); - } // if the field is in form of array - - - for (const field of protectedFields) { - // do not alloow to protect default fields - if (defaultColumns._Default[field]) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `Default field '${field}' can not be protected`); - } // field should exist on collection - - - if (!Object.prototype.hasOwnProperty.call(fields, field)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `Field '${field}' in protectedFields:${entity} does not exist`); - } - } - } // proceed with next operationKey - - - continue; - } // validate other fields - // Entity can be: - // "*" - Public, - // "requiresAuthentication" - authenticated users, - // "objectId" - _User id, - // "role:rolename", - // "pointerFields" - array of field names containing pointers to users - - - for (const entity in operation) { - // throws on unexpected key - validatePermissionKey(entity, userIdRegExp); // entity can be either: - // "pointerFields": string[] - - if (entity === 'pointerFields') { - const pointerFields = operation[entity]; - - if (Array.isArray(pointerFields)) { - for (const pointerField of pointerFields) { - validatePointerPermission(pointerField, fields, operation); - } - } else { - throw new Parse.Error(Parse.Error.INVALID_JSON, `'${pointerFields}' is not a valid value for ${operationKey}[${entity}] - expected an array.`); - } // proceed with next entity key - - - continue; - } // or [entity]: boolean - - - const permit = operation[entity]; - - if (permit !== true) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `'${permit}' is not a valid value for class level permissions ${operationKey}:${entity}:${permit}`); - } - } - } -} - -function validateCLPjson(operation, operationKey) { - if (operationKey === 'readUserFields' || operationKey === 'writeUserFields') { - if (!Array.isArray(operation)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `'${operation}' is not a valid value for class level permissions ${operationKey} - must be an array`); - } - } else { - if (typeof operation === 'object' && operation !== null) { - // ok to proceed - return; - } else { - throw new Parse.Error(Parse.Error.INVALID_JSON, `'${operation}' is not a valid value for class level permissions ${operationKey} - must be an object`); - } - } -} - -function validatePointerPermission(fieldName, fields, operation) { - // Uses collection schema to ensure the field is of type: - // - Pointer<_User> (pointers) - // - Array - // - // It's not possible to enforce type on Array's items in schema - // so we accept any Array field, and later when applying permissions - // only items that are pointers to _User are considered. - if (!(fields[fieldName] && (fields[fieldName].type == 'Pointer' && fields[fieldName].targetClass == '_User' || fields[fieldName].type == 'Array'))) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `'${fieldName}' is not a valid column for class level pointer permissions ${operation}`); - } -} - -const joinClassRegex = /^_Join:[A-Za-z0-9_]+:[A-Za-z0-9_]+/; -const classAndFieldRegex = /^[A-Za-z][A-Za-z0-9_]*$/; - -function classNameIsValid(className) { - // Valid classes must: - return (// Be one of _User, _Installation, _Role, _Session OR - systemClasses.indexOf(className) > -1 || // Be a join table OR - joinClassRegex.test(className) || // Include only alpha-numeric and underscores, and not start with an underscore or number - fieldNameIsValid(className, className) - ); -} // Valid fields must be alpha-numeric, and not start with an underscore or number -// must not be a reserved key - - -function fieldNameIsValid(fieldName, className) { - if (className && className !== '_Hooks') { - if (fieldName === 'className') { - return false; - } - } - - return classAndFieldRegex.test(fieldName) && !invalidColumns.includes(fieldName); -} // Checks that it's not trying to clobber one of the default fields of the class. - - -function fieldNameIsValidForClass(fieldName, className) { - if (!fieldNameIsValid(fieldName, className)) { - return false; - } - - if (defaultColumns._Default[fieldName]) { - return false; - } - - if (defaultColumns[className] && defaultColumns[className][fieldName]) { - return false; - } - - return true; -} - -function invalidClassNameMessage(className) { - return 'Invalid classname: ' + className + ', classnames can only have alphanumeric characters and _, and must start with an alpha character '; -} - -const invalidJsonError = new Parse.Error(Parse.Error.INVALID_JSON, 'invalid JSON'); -const validNonRelationOrPointerTypes = ['Number', 'String', 'Boolean', 'Date', 'Object', 'Array', 'GeoPoint', 'File', 'Bytes', 'Polygon']; // Returns an error suitable for throwing if the type is invalid - -const fieldTypeIsInvalid = ({ - type, - targetClass -}) => { - if (['Pointer', 'Relation'].indexOf(type) >= 0) { - if (!targetClass) { - return new Parse.Error(135, `type ${type} needs a class name`); - } else if (typeof targetClass !== 'string') { - return invalidJsonError; - } else if (!classNameIsValid(targetClass)) { - return new Parse.Error(Parse.Error.INVALID_CLASS_NAME, invalidClassNameMessage(targetClass)); - } else { - return undefined; - } - } - - if (typeof type !== 'string') { - return invalidJsonError; - } - - if (validNonRelationOrPointerTypes.indexOf(type) < 0) { - return new Parse.Error(Parse.Error.INCORRECT_TYPE, `invalid field type: ${type}`); - } - - return undefined; -}; - -const convertSchemaToAdapterSchema = schema => { - schema = injectDefaultSchema(schema); - delete schema.fields.ACL; - schema.fields._rperm = { - type: 'Array' - }; - schema.fields._wperm = { - type: 'Array' - }; - - if (schema.className === '_User') { - delete schema.fields.password; - schema.fields._hashed_password = { - type: 'String' - }; - } - - return schema; -}; - -exports.convertSchemaToAdapterSchema = convertSchemaToAdapterSchema; - -const convertAdapterSchemaToParseSchema = (_ref) => { - let schema = _extends({}, _ref); - - delete schema.fields._rperm; - delete schema.fields._wperm; - schema.fields.ACL = { - type: 'ACL' - }; - - if (schema.className === '_User') { - delete schema.fields.authData; //Auth data is implicit - - delete schema.fields._hashed_password; - schema.fields.password = { - type: 'String' - }; - } - - if (schema.indexes && Object.keys(schema.indexes).length === 0) { - delete schema.indexes; - } - - return schema; -}; - -class SchemaData { - constructor(allSchemas = [], protectedFields = {}) { - this.__data = {}; - this.__protectedFields = protectedFields; - allSchemas.forEach(schema => { - if (volatileClasses.includes(schema.className)) { - return; - } - - Object.defineProperty(this, schema.className, { - get: () => { - if (!this.__data[schema.className]) { - const data = {}; - data.fields = injectDefaultSchema(schema).fields; - data.classLevelPermissions = (0, _deepcopy.default)(schema.classLevelPermissions); - data.indexes = schema.indexes; - const classProtectedFields = this.__protectedFields[schema.className]; - - if (classProtectedFields) { - for (const key in classProtectedFields) { - const unq = new Set([...(data.classLevelPermissions.protectedFields[key] || []), ...classProtectedFields[key]]); - data.classLevelPermissions.protectedFields[key] = Array.from(unq); - } - } - - this.__data[schema.className] = data; - } - - return this.__data[schema.className]; - } - }); - }); // Inject the in-memory classes - - volatileClasses.forEach(className => { - Object.defineProperty(this, className, { - get: () => { - if (!this.__data[className]) { - const schema = injectDefaultSchema({ - className, - fields: {}, - classLevelPermissions: {} - }); - const data = {}; - data.fields = schema.fields; - data.classLevelPermissions = schema.classLevelPermissions; - data.indexes = schema.indexes; - this.__data[className] = data; - } - - return this.__data[className]; - } - }); - }); - } - -} - -const injectDefaultSchema = ({ - className, - fields, - classLevelPermissions, - indexes -}) => { - const defaultSchema = { - className, - fields: _objectSpread(_objectSpread(_objectSpread({}, defaultColumns._Default), defaultColumns[className] || {}), fields), - classLevelPermissions - }; - - if (indexes && Object.keys(indexes).length !== 0) { - defaultSchema.indexes = indexes; - } - - return defaultSchema; -}; - -const _HooksSchema = { - className: '_Hooks', - fields: defaultColumns._Hooks -}; -const _GlobalConfigSchema = { - className: '_GlobalConfig', - fields: defaultColumns._GlobalConfig -}; -const _GraphQLConfigSchema = { - className: '_GraphQLConfig', - fields: defaultColumns._GraphQLConfig -}; - -const _PushStatusSchema = convertSchemaToAdapterSchema(injectDefaultSchema({ - className: '_PushStatus', - fields: {}, - classLevelPermissions: {} -})); - -const _JobStatusSchema = convertSchemaToAdapterSchema(injectDefaultSchema({ - className: '_JobStatus', - fields: {}, - classLevelPermissions: {} -})); - -const _JobScheduleSchema = convertSchemaToAdapterSchema(injectDefaultSchema({ - className: '_JobSchedule', - fields: {}, - classLevelPermissions: {} -})); - -const _AudienceSchema = convertSchemaToAdapterSchema(injectDefaultSchema({ - className: '_Audience', - fields: defaultColumns._Audience, - classLevelPermissions: {} -})); - -const _IdempotencySchema = convertSchemaToAdapterSchema(injectDefaultSchema({ - className: '_Idempotency', - fields: defaultColumns._Idempotency, - classLevelPermissions: {} -})); - -const VolatileClassesSchemas = [_HooksSchema, _JobStatusSchema, _JobScheduleSchema, _PushStatusSchema, _GlobalConfigSchema, _GraphQLConfigSchema, _AudienceSchema, _IdempotencySchema]; -exports.VolatileClassesSchemas = VolatileClassesSchemas; - -const dbTypeMatchesObjectType = (dbType, objectType) => { - if (dbType.type !== objectType.type) return false; - if (dbType.targetClass !== objectType.targetClass) return false; - if (dbType === objectType.type) return true; - if (dbType.type === objectType.type) return true; - return false; -}; - -const typeToString = type => { - if (typeof type === 'string') { - return type; - } - - if (type.targetClass) { - return `${type.type}<${type.targetClass}>`; - } - - return `${type.type}`; -}; // Stores the entire schema of the app in a weird hybrid format somewhere between -// the mongo format and the Parse format. Soon, this will all be Parse format. - - -class SchemaController { - constructor(databaseAdapter, schemaCache) { - this._dbAdapter = databaseAdapter; - this._cache = schemaCache; - this.schemaData = new SchemaData(); - this.protectedFields = _Config.default.get(Parse.applicationId).protectedFields; - - const customIds = _Config.default.get(Parse.applicationId).allowCustomObjectId; - - const customIdRegEx = /^.{1,}$/u; // 1+ chars - - const autoIdRegEx = /^[a-zA-Z0-9]{1,}$/; - this.userIdRegEx = customIds ? customIdRegEx : autoIdRegEx; - } - - reloadData(options = { - clearCache: false - }) { - if (this.reloadDataPromise && !options.clearCache) { - return this.reloadDataPromise; - } - - this.reloadDataPromise = this.getAllClasses(options).then(allSchemas => { - this.schemaData = new SchemaData(allSchemas, this.protectedFields); - delete this.reloadDataPromise; - }, err => { - this.schemaData = new SchemaData(); - delete this.reloadDataPromise; - throw err; - }).then(() => {}); - return this.reloadDataPromise; - } - - getAllClasses(options = { - clearCache: false - }) { - if (options.clearCache) { - return this.setAllClasses(); - } - - return this._cache.getAllClasses().then(allClasses => { - if (allClasses && allClasses.length) { - return Promise.resolve(allClasses); - } - - return this.setAllClasses(); - }); - } - - setAllClasses() { - return this._dbAdapter.getAllClasses().then(allSchemas => allSchemas.map(injectDefaultSchema)).then(allSchemas => { - /* eslint-disable no-console */ - this._cache.setAllClasses(allSchemas).catch(error => console.error('Error saving schema to cache:', error)); - /* eslint-enable no-console */ - - - return allSchemas; - }); - } - - getOneSchema(className, allowVolatileClasses = false, options = { - clearCache: false - }) { - let promise = Promise.resolve(); - - if (options.clearCache) { - promise = this._cache.clear(); - } - - return promise.then(() => { - if (allowVolatileClasses && volatileClasses.indexOf(className) > -1) { - const data = this.schemaData[className]; - return Promise.resolve({ - className, - fields: data.fields, - classLevelPermissions: data.classLevelPermissions, - indexes: data.indexes - }); - } - - return this._cache.getOneSchema(className).then(cached => { - if (cached && !options.clearCache) { - return Promise.resolve(cached); - } - - return this.setAllClasses().then(allSchemas => { - const oneSchema = allSchemas.find(schema => schema.className === className); - - if (!oneSchema) { - return Promise.reject(undefined); - } - - return oneSchema; - }); - }); - }); - } // Create a new class that includes the three default fields. - // ACL is an implicit column that does not get an entry in the - // _SCHEMAS database. Returns a promise that resolves with the - // created schema, in mongo format. - // on success, and rejects with an error on fail. Ensure you - // have authorization (master key, or client class creation - // enabled) before calling this function. - - - addClassIfNotExists(className, fields = {}, classLevelPermissions, indexes = {}) { - var validationError = this.validateNewClass(className, fields, classLevelPermissions); - - if (validationError) { - if (validationError instanceof Parse.Error) { - return Promise.reject(validationError); - } else if (validationError.code && validationError.error) { - return Promise.reject(new Parse.Error(validationError.code, validationError.error)); - } - - return Promise.reject(validationError); - } - - return this._dbAdapter.createClass(className, convertSchemaToAdapterSchema({ - fields, - classLevelPermissions, - indexes, - className - })).then(convertAdapterSchemaToParseSchema).catch(error => { - if (error && error.code === Parse.Error.DUPLICATE_VALUE) { - throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} already exists.`); - } else { - throw error; - } - }); - } - - updateClass(className, submittedFields, classLevelPermissions, indexes, database) { - return this.getOneSchema(className).then(schema => { - const existingFields = schema.fields; - Object.keys(submittedFields).forEach(name => { - const field = submittedFields[name]; - - if (existingFields[name] && field.__op !== 'Delete') { - throw new Parse.Error(255, `Field ${name} exists, cannot update.`); - } - - if (!existingFields[name] && field.__op === 'Delete') { - throw new Parse.Error(255, `Field ${name} does not exist, cannot delete.`); - } - }); - delete existingFields._rperm; - delete existingFields._wperm; - const newSchema = buildMergedSchemaObject(existingFields, submittedFields); - const defaultFields = defaultColumns[className] || defaultColumns._Default; - const fullNewSchema = Object.assign({}, newSchema, defaultFields); - const validationError = this.validateSchemaData(className, newSchema, classLevelPermissions, Object.keys(existingFields)); - - if (validationError) { - throw new Parse.Error(validationError.code, validationError.error); - } // Finally we have checked to make sure the request is valid and we can start deleting fields. - // Do all deletions first, then a single save to _SCHEMA collection to handle all additions. - - - const deletedFields = []; - const insertedFields = []; - Object.keys(submittedFields).forEach(fieldName => { - if (submittedFields[fieldName].__op === 'Delete') { - deletedFields.push(fieldName); - } else { - insertedFields.push(fieldName); - } - }); - let deletePromise = Promise.resolve(); - - if (deletedFields.length > 0) { - deletePromise = this.deleteFields(deletedFields, className, database); - } - - let enforceFields = []; - return deletePromise // Delete Everything - .then(() => this.reloadData({ - clearCache: true - })) // Reload our Schema, so we have all the new values - .then(() => { - const promises = insertedFields.map(fieldName => { - const type = submittedFields[fieldName]; - return this.enforceFieldExists(className, fieldName, type); - }); - return Promise.all(promises); - }).then(results => { - enforceFields = results.filter(result => !!result); - return this.setPermissions(className, classLevelPermissions, newSchema); - }).then(() => this._dbAdapter.setIndexesWithSchemaFormat(className, indexes, schema.indexes, fullNewSchema)).then(() => this.reloadData({ - clearCache: true - })) //TODO: Move this logic into the database adapter - .then(() => { - this.ensureFields(enforceFields); - const schema = this.schemaData[className]; - const reloadedSchema = { - className: className, - fields: schema.fields, - classLevelPermissions: schema.classLevelPermissions - }; - - if (schema.indexes && Object.keys(schema.indexes).length !== 0) { - reloadedSchema.indexes = schema.indexes; - } - - return reloadedSchema; - }); - }).catch(error => { - if (error === undefined) { - throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} does not exist.`); - } else { - throw error; - } - }); - } // Returns a promise that resolves successfully to the new schema - // object or fails with a reason. - - - enforceClassExists(className) { - if (this.schemaData[className]) { - return Promise.resolve(this); - } // We don't have this class. Update the schema - - - return this.addClassIfNotExists(className) // The schema update succeeded. Reload the schema - .then(() => this.reloadData({ - clearCache: true - })).catch(() => { - // The schema update failed. This can be okay - it might - // have failed because there's a race condition and a different - // client is making the exact same schema update that we want. - // So just reload the schema. - return this.reloadData({ - clearCache: true - }); - }).then(() => { - // Ensure that the schema now validates - if (this.schemaData[className]) { - return this; - } else { - throw new Parse.Error(Parse.Error.INVALID_JSON, `Failed to add ${className}`); - } - }).catch(() => { - // The schema still doesn't validate. Give up - throw new Parse.Error(Parse.Error.INVALID_JSON, 'schema class name does not revalidate'); - }); - } - - validateNewClass(className, fields = {}, classLevelPermissions) { - if (this.schemaData[className]) { - throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} already exists.`); - } - - if (!classNameIsValid(className)) { - return { - code: Parse.Error.INVALID_CLASS_NAME, - error: invalidClassNameMessage(className) - }; - } - - return this.validateSchemaData(className, fields, classLevelPermissions, []); - } - - validateSchemaData(className, fields, classLevelPermissions, existingFieldNames) { - for (const fieldName in fields) { - if (existingFieldNames.indexOf(fieldName) < 0) { - if (!fieldNameIsValid(fieldName, className)) { - return { - code: Parse.Error.INVALID_KEY_NAME, - error: 'invalid field name: ' + fieldName - }; - } - - if (!fieldNameIsValidForClass(fieldName, className)) { - return { - code: 136, - error: 'field ' + fieldName + ' cannot be added' - }; - } - - const fieldType = fields[fieldName]; - const error = fieldTypeIsInvalid(fieldType); - if (error) return { - code: error.code, - error: error.message - }; - - if (fieldType.defaultValue !== undefined) { - let defaultValueType = getType(fieldType.defaultValue); - - if (typeof defaultValueType === 'string') { - defaultValueType = { - type: defaultValueType - }; - } else if (typeof defaultValueType === 'object' && fieldType.type === 'Relation') { - return { - code: Parse.Error.INCORRECT_TYPE, - error: `The 'default value' option is not applicable for ${typeToString(fieldType)}` - }; - } - - if (!dbTypeMatchesObjectType(fieldType, defaultValueType)) { - return { - code: Parse.Error.INCORRECT_TYPE, - error: `schema mismatch for ${className}.${fieldName} default value; expected ${typeToString(fieldType)} but got ${typeToString(defaultValueType)}` - }; - } - } else if (fieldType.required) { - if (typeof fieldType === 'object' && fieldType.type === 'Relation') { - return { - code: Parse.Error.INCORRECT_TYPE, - error: `The 'required' option is not applicable for ${typeToString(fieldType)}` - }; - } - } - } - } - - for (const fieldName in defaultColumns[className]) { - fields[fieldName] = defaultColumns[className][fieldName]; - } - - const geoPoints = Object.keys(fields).filter(key => fields[key] && fields[key].type === 'GeoPoint'); - - if (geoPoints.length > 1) { - return { - code: Parse.Error.INCORRECT_TYPE, - error: 'currently, only one GeoPoint field may exist in an object. Adding ' + geoPoints[1] + ' when ' + geoPoints[0] + ' already exists.' - }; - } - - validateCLP(classLevelPermissions, fields, this.userIdRegEx); - } // Sets the Class-level permissions for a given className, which must exist. - - - setPermissions(className, perms, newSchema) { - if (typeof perms === 'undefined') { - return Promise.resolve(); - } - - validateCLP(perms, newSchema, this.userIdRegEx); - return this._dbAdapter.setClassLevelPermissions(className, perms); - } // Returns a promise that resolves successfully to the new schema - // object if the provided className-fieldName-type tuple is valid. - // The className must already be validated. - // If 'freeze' is true, refuse to update the schema for this field. - - - enforceFieldExists(className, fieldName, type) { - if (fieldName.indexOf('.') > 0) { - // subdocument key (x.y) => ok if x is of type 'object' - fieldName = fieldName.split('.')[0]; - type = 'Object'; - } - - if (!fieldNameIsValid(fieldName, className)) { - throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, `Invalid field name: ${fieldName}.`); - } // If someone tries to create a new field with null/undefined as the value, return; - - - if (!type) { - return undefined; - } - - const expectedType = this.getExpectedType(className, fieldName); - - if (typeof type === 'string') { - type = { - type - }; - } - - if (type.defaultValue !== undefined) { - let defaultValueType = getType(type.defaultValue); - - if (typeof defaultValueType === 'string') { - defaultValueType = { - type: defaultValueType - }; - } - - if (!dbTypeMatchesObjectType(type, defaultValueType)) { - throw new Parse.Error(Parse.Error.INCORRECT_TYPE, `schema mismatch for ${className}.${fieldName} default value; expected ${typeToString(type)} but got ${typeToString(defaultValueType)}`); - } - } - - if (expectedType) { - if (!dbTypeMatchesObjectType(expectedType, type)) { - throw new Parse.Error(Parse.Error.INCORRECT_TYPE, `schema mismatch for ${className}.${fieldName}; expected ${typeToString(expectedType)} but got ${typeToString(type)}`); - } - - return undefined; - } - - return this._dbAdapter.addFieldIfNotExists(className, fieldName, type).catch(error => { - if (error.code == Parse.Error.INCORRECT_TYPE) { - // Make sure that we throw errors when it is appropriate to do so. - throw error; - } // The update failed. This can be okay - it might have been a race - // condition where another client updated the schema in the same - // way that we wanted to. So, just reload the schema - - - return Promise.resolve(); - }).then(() => { - return { - className, - fieldName, - type - }; - }); - } - - ensureFields(fields) { - for (let i = 0; i < fields.length; i += 1) { - const { - className, - fieldName - } = fields[i]; - let { - type - } = fields[i]; - const expectedType = this.getExpectedType(className, fieldName); - - if (typeof type === 'string') { - type = { - type: type - }; - } - - if (!expectedType || !dbTypeMatchesObjectType(expectedType, type)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, `Could not add field ${fieldName}`); - } - } - } // maintain compatibility - - - deleteField(fieldName, className, database) { - return this.deleteFields([fieldName], className, database); - } // Delete fields, and remove that data from all objects. This is intended - // to remove unused fields, if other writers are writing objects that include - // this field, the field may reappear. Returns a Promise that resolves with - // no object on success, or rejects with { code, error } on failure. - // Passing the database and prefix is necessary in order to drop relation collections - // and remove fields from objects. Ideally the database would belong to - // a database adapter and this function would close over it or access it via member. - - - deleteFields(fieldNames, className, database) { - if (!classNameIsValid(className)) { - throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, invalidClassNameMessage(className)); - } - - fieldNames.forEach(fieldName => { - if (!fieldNameIsValid(fieldName, className)) { - throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, `invalid field name: ${fieldName}`); - } //Don't allow deleting the default fields. - - - if (!fieldNameIsValidForClass(fieldName, className)) { - throw new Parse.Error(136, `field ${fieldName} cannot be changed`); - } - }); - return this.getOneSchema(className, false, { - clearCache: true - }).catch(error => { - if (error === undefined) { - throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} does not exist.`); - } else { - throw error; - } - }).then(schema => { - fieldNames.forEach(fieldName => { - if (!schema.fields[fieldName]) { - throw new Parse.Error(255, `Field ${fieldName} does not exist, cannot delete.`); - } - }); - - const schemaFields = _objectSpread({}, schema.fields); - - return database.adapter.deleteFields(className, schema, fieldNames).then(() => { - return Promise.all(fieldNames.map(fieldName => { - const field = schemaFields[fieldName]; - - if (field && field.type === 'Relation') { - //For relations, drop the _Join table - return database.adapter.deleteClass(`_Join:${fieldName}:${className}`); - } - - return Promise.resolve(); - })); - }); - }).then(() => this._cache.clear()); - } // Validates an object provided in REST format. - // Returns a promise that resolves to the new schema if this object is - // valid. - - - async validateObject(className, object, query) { - let geocount = 0; - const schema = await this.enforceClassExists(className); - const promises = []; - - for (const fieldName in object) { - if (object[fieldName] === undefined) { - continue; - } - - const expected = getType(object[fieldName]); - - if (expected === 'GeoPoint') { - geocount++; - } - - if (geocount > 1) { - // Make sure all field validation operations run before we return. - // If not - we are continuing to run logic, but already provided response from the server. - return Promise.reject(new Parse.Error(Parse.Error.INCORRECT_TYPE, 'there can only be one geopoint field in a class')); - } - - if (!expected) { - continue; - } - - if (fieldName === 'ACL') { - // Every object has ACL implicitly. - continue; - } - - promises.push(schema.enforceFieldExists(className, fieldName, expected)); - } - - const results = await Promise.all(promises); - const enforceFields = results.filter(result => !!result); - - if (enforceFields.length !== 0) { - await this.reloadData({ - clearCache: true - }); - } - - this.ensureFields(enforceFields); - const promise = Promise.resolve(schema); - return thenValidateRequiredColumns(promise, className, object, query); - } // Validates that all the properties are set for the object - - - validateRequiredColumns(className, object, query) { - const columns = requiredColumns[className]; - - if (!columns || columns.length == 0) { - return Promise.resolve(this); - } - - const missingColumns = columns.filter(function (column) { - if (query && query.objectId) { - if (object[column] && typeof object[column] === 'object') { - // Trying to delete a required column - return object[column].__op == 'Delete'; - } // Not trying to do anything there - - - return false; - } - - return !object[column]; - }); - - if (missingColumns.length > 0) { - throw new Parse.Error(Parse.Error.INCORRECT_TYPE, missingColumns[0] + ' is required.'); - } - - return Promise.resolve(this); - } - - testPermissionsForClassName(className, aclGroup, operation) { - return SchemaController.testPermissions(this.getClassLevelPermissions(className), aclGroup, operation); - } // Tests that the class level permission let pass the operation for a given aclGroup - - - static testPermissions(classPermissions, aclGroup, operation) { - if (!classPermissions || !classPermissions[operation]) { - return true; - } - - const perms = classPermissions[operation]; - - if (perms['*']) { - return true; - } // Check permissions against the aclGroup provided (array of userId/roles) - - - if (aclGroup.some(acl => { - return perms[acl] === true; - })) { - return true; - } - - return false; - } // Validates an operation passes class-level-permissions set in the schema - - - static validatePermission(classPermissions, className, aclGroup, operation, action) { - if (SchemaController.testPermissions(classPermissions, aclGroup, operation)) { - return Promise.resolve(); - } - - if (!classPermissions || !classPermissions[operation]) { - return true; - } - - const perms = classPermissions[operation]; // If only for authenticated users - // make sure we have an aclGroup - - if (perms['requiresAuthentication']) { - // If aclGroup has * (public) - if (!aclGroup || aclGroup.length == 0) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Permission denied, user needs to be authenticated.'); - } else if (aclGroup.indexOf('*') > -1 && aclGroup.length == 1) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Permission denied, user needs to be authenticated.'); - } // requiresAuthentication passed, just move forward - // probably would be wise at some point to rename to 'authenticatedUser' - - - return Promise.resolve(); - } // No matching CLP, let's check the Pointer permissions - // And handle those later - - - const permissionField = ['get', 'find', 'count'].indexOf(operation) > -1 ? 'readUserFields' : 'writeUserFields'; // Reject create when write lockdown - - if (permissionField == 'writeUserFields' && operation == 'create') { - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, `Permission denied for action ${operation} on class ${className}.`); - } // Process the readUserFields later - - - if (Array.isArray(classPermissions[permissionField]) && classPermissions[permissionField].length > 0) { - return Promise.resolve(); - } - - const pointerFields = classPermissions[operation].pointerFields; - - if (Array.isArray(pointerFields) && pointerFields.length > 0) { - // any op except 'addField as part of create' is ok. - if (operation !== 'addField' || action === 'update') { - // We can allow adding field on update flow only. - return Promise.resolve(); - } - } - - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, `Permission denied for action ${operation} on class ${className}.`); - } // Validates an operation passes class-level-permissions set in the schema - - - validatePermission(className, aclGroup, operation, action) { - return SchemaController.validatePermission(this.getClassLevelPermissions(className), className, aclGroup, operation, action); - } - - getClassLevelPermissions(className) { - return this.schemaData[className] && this.schemaData[className].classLevelPermissions; - } // Returns the expected type for a className+key combination - // or undefined if the schema is not set - - - getExpectedType(className, fieldName) { - if (this.schemaData[className]) { - const expectedType = this.schemaData[className].fields[fieldName]; - return expectedType === 'map' ? 'Object' : expectedType; - } - - return undefined; - } // Checks if a given class is in the schema. - - - hasClass(className) { - if (this.schemaData[className]) { - return Promise.resolve(true); - } - - return this.reloadData().then(() => !!this.schemaData[className]); - } - -} // Returns a promise for a new Schema. - - -exports.SchemaController = exports.default = SchemaController; - -const load = (dbAdapter, schemaCache, options) => { - const schema = new SchemaController(dbAdapter, schemaCache); - return schema.reloadData(options).then(() => schema); -}; // Builds a new schema (in schema API response format) out of an -// existing mongo schema + a schemas API put request. This response -// does not include the default fields, as it is intended to be passed -// to mongoSchemaFromFieldsAndClassName. No validation is done here, it -// is done in mongoSchemaFromFieldsAndClassName. - - -exports.load = load; - -function buildMergedSchemaObject(existingFields, putRequest) { - const newSchema = {}; // -disable-next - - const sysSchemaField = Object.keys(defaultColumns).indexOf(existingFields._id) === -1 ? [] : Object.keys(defaultColumns[existingFields._id]); - - for (const oldField in existingFields) { - if (oldField !== '_id' && oldField !== 'ACL' && oldField !== 'updatedAt' && oldField !== 'createdAt' && oldField !== 'objectId') { - if (sysSchemaField.length > 0 && sysSchemaField.indexOf(oldField) !== -1) { - continue; - } - - const fieldIsDeleted = putRequest[oldField] && putRequest[oldField].__op === 'Delete'; - - if (!fieldIsDeleted) { - newSchema[oldField] = existingFields[oldField]; - } - } - } - - for (const newField in putRequest) { - if (newField !== 'objectId' && putRequest[newField].__op !== 'Delete') { - if (sysSchemaField.length > 0 && sysSchemaField.indexOf(newField) !== -1) { - continue; - } - - newSchema[newField] = putRequest[newField]; - } - } - - return newSchema; -} // Given a schema promise, construct another schema promise that -// validates this field once the schema loads. - - -function thenValidateRequiredColumns(schemaPromise, className, object, query) { - return schemaPromise.then(schema => { - return schema.validateRequiredColumns(className, object, query); - }); -} // Gets the type from a REST API formatted object, where 'type' is -// extended past javascript types to include the rest of the Parse -// type system. -// The output should be a valid schema value. -// TODO: ensure that this is compatible with the format used in Open DB - - -function getType(obj) { - const type = typeof obj; - - switch (type) { - case 'boolean': - return 'Boolean'; - - case 'string': - return 'String'; - - case 'number': - return 'Number'; - - case 'map': - case 'object': - if (!obj) { - return undefined; - } - - return getObjectType(obj); - - case 'function': - case 'symbol': - case 'undefined': - default: - throw 'bad obj: ' + obj; - } -} // This gets the type for non-JSON types like pointers and files, but -// also gets the appropriate type for $ operators. -// Returns null if the type is unknown. - - -function getObjectType(obj) { - if (obj instanceof Array) { - return 'Array'; - } - - if (obj.__type) { - switch (obj.__type) { - case 'Pointer': - if (obj.className) { - return { - type: 'Pointer', - targetClass: obj.className - }; - } - - break; - - case 'Relation': - if (obj.className) { - return { - type: 'Relation', - targetClass: obj.className - }; - } - - break; - - case 'File': - if (obj.name) { - return 'File'; - } - - break; - - case 'Date': - if (obj.iso) { - return 'Date'; - } - - break; - - case 'GeoPoint': - if (obj.latitude != null && obj.longitude != null) { - return 'GeoPoint'; - } - - break; - - case 'Bytes': - if (obj.base64) { - return 'Bytes'; - } - - break; - - case 'Polygon': - if (obj.coordinates) { - return 'Polygon'; - } - - break; - } - - throw new Parse.Error(Parse.Error.INCORRECT_TYPE, 'This is not a valid ' + obj.__type); - } - - if (obj['$ne']) { - return getObjectType(obj['$ne']); - } - - if (obj.__op) { - switch (obj.__op) { - case 'Increment': - return 'Number'; - - case 'Delete': - return null; - - case 'Add': - case 'AddUnique': - case 'Remove': - return 'Array'; - - case 'AddRelation': - case 'RemoveRelation': - return { - type: 'Relation', - targetClass: obj.objects[0].className - }; - - case 'Batch': - return getObjectType(obj.ops[0]); - - default: - throw 'unexpected op: ' + obj.__op; - } - } - - return 'Object'; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9TY2hlbWFDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsImRlZmF1bHRDb2x1bW5zIiwiT2JqZWN0IiwiZnJlZXplIiwiX0RlZmF1bHQiLCJvYmplY3RJZCIsInR5cGUiLCJjcmVhdGVkQXQiLCJ1cGRhdGVkQXQiLCJBQ0wiLCJfVXNlciIsInVzZXJuYW1lIiwicGFzc3dvcmQiLCJlbWFpbCIsImVtYWlsVmVyaWZpZWQiLCJhdXRoRGF0YSIsIl9JbnN0YWxsYXRpb24iLCJpbnN0YWxsYXRpb25JZCIsImRldmljZVRva2VuIiwiY2hhbm5lbHMiLCJkZXZpY2VUeXBlIiwicHVzaFR5cGUiLCJHQ01TZW5kZXJJZCIsInRpbWVab25lIiwibG9jYWxlSWRlbnRpZmllciIsImJhZGdlIiwiYXBwVmVyc2lvbiIsImFwcE5hbWUiLCJhcHBJZGVudGlmaWVyIiwicGFyc2VWZXJzaW9uIiwiX1JvbGUiLCJuYW1lIiwidXNlcnMiLCJ0YXJnZXRDbGFzcyIsInJvbGVzIiwiX1Nlc3Npb24iLCJyZXN0cmljdGVkIiwidXNlciIsInNlc3Npb25Ub2tlbiIsImV4cGlyZXNBdCIsImNyZWF0ZWRXaXRoIiwiX1Byb2R1Y3QiLCJwcm9kdWN0SWRlbnRpZmllciIsImRvd25sb2FkIiwiZG93bmxvYWROYW1lIiwiaWNvbiIsIm9yZGVyIiwidGl0bGUiLCJzdWJ0aXRsZSIsIl9QdXNoU3RhdHVzIiwicHVzaFRpbWUiLCJzb3VyY2UiLCJxdWVyeSIsInBheWxvYWQiLCJleHBpcnkiLCJleHBpcmF0aW9uX2ludGVydmFsIiwic3RhdHVzIiwibnVtU2VudCIsIm51bUZhaWxlZCIsInB1c2hIYXNoIiwiZXJyb3JNZXNzYWdlIiwic2VudFBlclR5cGUiLCJmYWlsZWRQZXJUeXBlIiwic2VudFBlclVUQ09mZnNldCIsImZhaWxlZFBlclVUQ09mZnNldCIsImNvdW50IiwiX0pvYlN0YXR1cyIsImpvYk5hbWUiLCJtZXNzYWdlIiwicGFyYW1zIiwiZmluaXNoZWRBdCIsIl9Kb2JTY2hlZHVsZSIsImRlc2NyaXB0aW9uIiwic3RhcnRBZnRlciIsImRheXNPZldlZWsiLCJ0aW1lT2ZEYXkiLCJsYXN0UnVuIiwicmVwZWF0TWludXRlcyIsIl9Ib29rcyIsImZ1bmN0aW9uTmFtZSIsImNsYXNzTmFtZSIsInRyaWdnZXJOYW1lIiwidXJsIiwiX0dsb2JhbENvbmZpZyIsIm1hc3RlcktleU9ubHkiLCJfR3JhcGhRTENvbmZpZyIsImNvbmZpZyIsIl9BdWRpZW5jZSIsImxhc3RVc2VkIiwidGltZXNVc2VkIiwiX0lkZW1wb3RlbmN5IiwicmVxSWQiLCJleHBpcmUiLCJyZXF1aXJlZENvbHVtbnMiLCJpbnZhbGlkQ29sdW1ucyIsInN5c3RlbUNsYXNzZXMiLCJ2b2xhdGlsZUNsYXNzZXMiLCJyb2xlUmVnZXgiLCJwcm90ZWN0ZWRGaWVsZHNQb2ludGVyUmVnZXgiLCJwdWJsaWNSZWdleCIsImF1dGhlbnRpY2F0ZWRSZWdleCIsInJlcXVpcmVzQXV0aGVudGljYXRpb25SZWdleCIsImNscFBvaW50ZXJSZWdleCIsInByb3RlY3RlZEZpZWxkc1JlZ2V4IiwiY2xwRmllbGRzUmVnZXgiLCJ2YWxpZGF0ZVBlcm1pc3Npb25LZXkiLCJrZXkiLCJ1c2VySWRSZWdFeHAiLCJtYXRjaGVzU29tZSIsInJlZ0V4IiwibWF0Y2giLCJ2YWxpZCIsIkVycm9yIiwiSU5WQUxJRF9KU09OIiwidmFsaWRhdGVQcm90ZWN0ZWRGaWVsZHNLZXkiLCJDTFBWYWxpZEtleXMiLCJ2YWxpZGF0ZUNMUCIsInBlcm1zIiwiZmllbGRzIiwib3BlcmF0aW9uS2V5IiwiaW5kZXhPZiIsIm9wZXJhdGlvbiIsInZhbGlkYXRlQ0xQanNvbiIsImZpZWxkTmFtZSIsInZhbGlkYXRlUG9pbnRlclBlcm1pc3Npb24iLCJlbnRpdHkiLCJwcm90ZWN0ZWRGaWVsZHMiLCJBcnJheSIsImlzQXJyYXkiLCJmaWVsZCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInBvaW50ZXJGaWVsZHMiLCJwb2ludGVyRmllbGQiLCJwZXJtaXQiLCJqb2luQ2xhc3NSZWdleCIsImNsYXNzQW5kRmllbGRSZWdleCIsImNsYXNzTmFtZUlzVmFsaWQiLCJ0ZXN0IiwiZmllbGROYW1lSXNWYWxpZCIsImluY2x1ZGVzIiwiZmllbGROYW1lSXNWYWxpZEZvckNsYXNzIiwiaW52YWxpZENsYXNzTmFtZU1lc3NhZ2UiLCJpbnZhbGlkSnNvbkVycm9yIiwidmFsaWROb25SZWxhdGlvbk9yUG9pbnRlclR5cGVzIiwiZmllbGRUeXBlSXNJbnZhbGlkIiwiSU5WQUxJRF9DTEFTU19OQU1FIiwidW5kZWZpbmVkIiwiSU5DT1JSRUNUX1RZUEUiLCJjb252ZXJ0U2NoZW1hVG9BZGFwdGVyU2NoZW1hIiwic2NoZW1hIiwiaW5qZWN0RGVmYXVsdFNjaGVtYSIsIl9ycGVybSIsIl93cGVybSIsIl9oYXNoZWRfcGFzc3dvcmQiLCJjb252ZXJ0QWRhcHRlclNjaGVtYVRvUGFyc2VTY2hlbWEiLCJpbmRleGVzIiwia2V5cyIsImxlbmd0aCIsIlNjaGVtYURhdGEiLCJjb25zdHJ1Y3RvciIsImFsbFNjaGVtYXMiLCJfX2RhdGEiLCJfX3Byb3RlY3RlZEZpZWxkcyIsImZvckVhY2giLCJkZWZpbmVQcm9wZXJ0eSIsImdldCIsImRhdGEiLCJjbGFzc0xldmVsUGVybWlzc2lvbnMiLCJjbGFzc1Byb3RlY3RlZEZpZWxkcyIsInVucSIsIlNldCIsImZyb20iLCJkZWZhdWx0U2NoZW1hIiwiX0hvb2tzU2NoZW1hIiwiX0dsb2JhbENvbmZpZ1NjaGVtYSIsIl9HcmFwaFFMQ29uZmlnU2NoZW1hIiwiX1B1c2hTdGF0dXNTY2hlbWEiLCJfSm9iU3RhdHVzU2NoZW1hIiwiX0pvYlNjaGVkdWxlU2NoZW1hIiwiX0F1ZGllbmNlU2NoZW1hIiwiX0lkZW1wb3RlbmN5U2NoZW1hIiwiVm9sYXRpbGVDbGFzc2VzU2NoZW1hcyIsImRiVHlwZU1hdGNoZXNPYmplY3RUeXBlIiwiZGJUeXBlIiwib2JqZWN0VHlwZSIsInR5cGVUb1N0cmluZyIsIlNjaGVtYUNvbnRyb2xsZXIiLCJkYXRhYmFzZUFkYXB0ZXIiLCJzY2hlbWFDYWNoZSIsIl9kYkFkYXB0ZXIiLCJfY2FjaGUiLCJzY2hlbWFEYXRhIiwiQ29uZmlnIiwiYXBwbGljYXRpb25JZCIsImN1c3RvbUlkcyIsImFsbG93Q3VzdG9tT2JqZWN0SWQiLCJjdXN0b21JZFJlZ0V4IiwiYXV0b0lkUmVnRXgiLCJ1c2VySWRSZWdFeCIsInJlbG9hZERhdGEiLCJvcHRpb25zIiwiY2xlYXJDYWNoZSIsInJlbG9hZERhdGFQcm9taXNlIiwiZ2V0QWxsQ2xhc3NlcyIsInRoZW4iLCJlcnIiLCJzZXRBbGxDbGFzc2VzIiwiYWxsQ2xhc3NlcyIsIlByb21pc2UiLCJyZXNvbHZlIiwibWFwIiwiY2F0Y2giLCJlcnJvciIsImNvbnNvbGUiLCJnZXRPbmVTY2hlbWEiLCJhbGxvd1ZvbGF0aWxlQ2xhc3NlcyIsInByb21pc2UiLCJjbGVhciIsImNhY2hlZCIsIm9uZVNjaGVtYSIsImZpbmQiLCJyZWplY3QiLCJhZGRDbGFzc0lmTm90RXhpc3RzIiwidmFsaWRhdGlvbkVycm9yIiwidmFsaWRhdGVOZXdDbGFzcyIsImNvZGUiLCJjcmVhdGVDbGFzcyIsIkRVUExJQ0FURV9WQUxVRSIsInVwZGF0ZUNsYXNzIiwic3VibWl0dGVkRmllbGRzIiwiZGF0YWJhc2UiLCJleGlzdGluZ0ZpZWxkcyIsIl9fb3AiLCJuZXdTY2hlbWEiLCJidWlsZE1lcmdlZFNjaGVtYU9iamVjdCIsImRlZmF1bHRGaWVsZHMiLCJmdWxsTmV3U2NoZW1hIiwiYXNzaWduIiwidmFsaWRhdGVTY2hlbWFEYXRhIiwiZGVsZXRlZEZpZWxkcyIsImluc2VydGVkRmllbGRzIiwicHVzaCIsImRlbGV0ZVByb21pc2UiLCJkZWxldGVGaWVsZHMiLCJlbmZvcmNlRmllbGRzIiwicHJvbWlzZXMiLCJlbmZvcmNlRmllbGRFeGlzdHMiLCJhbGwiLCJyZXN1bHRzIiwiZmlsdGVyIiwicmVzdWx0Iiwic2V0UGVybWlzc2lvbnMiLCJzZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdCIsImVuc3VyZUZpZWxkcyIsInJlbG9hZGVkU2NoZW1hIiwiZW5mb3JjZUNsYXNzRXhpc3RzIiwiZXhpc3RpbmdGaWVsZE5hbWVzIiwiSU5WQUxJRF9LRVlfTkFNRSIsImZpZWxkVHlwZSIsImRlZmF1bHRWYWx1ZSIsImRlZmF1bHRWYWx1ZVR5cGUiLCJnZXRUeXBlIiwicmVxdWlyZWQiLCJnZW9Qb2ludHMiLCJzZXRDbGFzc0xldmVsUGVybWlzc2lvbnMiLCJzcGxpdCIsImV4cGVjdGVkVHlwZSIsImdldEV4cGVjdGVkVHlwZSIsImFkZEZpZWxkSWZOb3RFeGlzdHMiLCJpIiwiZGVsZXRlRmllbGQiLCJmaWVsZE5hbWVzIiwic2NoZW1hRmllbGRzIiwiYWRhcHRlciIsImRlbGV0ZUNsYXNzIiwidmFsaWRhdGVPYmplY3QiLCJvYmplY3QiLCJnZW9jb3VudCIsImV4cGVjdGVkIiwidGhlblZhbGlkYXRlUmVxdWlyZWRDb2x1bW5zIiwidmFsaWRhdGVSZXF1aXJlZENvbHVtbnMiLCJjb2x1bW5zIiwibWlzc2luZ0NvbHVtbnMiLCJjb2x1bW4iLCJ0ZXN0UGVybWlzc2lvbnNGb3JDbGFzc05hbWUiLCJhY2xHcm91cCIsInRlc3RQZXJtaXNzaW9ucyIsImdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsImNsYXNzUGVybWlzc2lvbnMiLCJzb21lIiwiYWNsIiwidmFsaWRhdGVQZXJtaXNzaW9uIiwiYWN0aW9uIiwiT0JKRUNUX05PVF9GT1VORCIsInBlcm1pc3Npb25GaWVsZCIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJoYXNDbGFzcyIsImxvYWQiLCJkYkFkYXB0ZXIiLCJwdXRSZXF1ZXN0Iiwic3lzU2NoZW1hRmllbGQiLCJfaWQiLCJvbGRGaWVsZCIsImZpZWxkSXNEZWxldGVkIiwibmV3RmllbGQiLCJzY2hlbWFQcm9taXNlIiwib2JqIiwiZ2V0T2JqZWN0VHlwZSIsIl9fdHlwZSIsImlzbyIsImxhdGl0dWRlIiwibG9uZ2l0dWRlIiwiYmFzZTY0IiwiY29vcmRpbmF0ZXMi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ZW50IjpbIi8vIEBmbG93XG4vLyBUaGlzIGNsYXNzIGhhbmRsZXMgc2NoZW1hIHZhbGlkYXRpb24sIHBlcnNpc3RlbmNlLCBhbmQgbW9kaWZpY2F0aW9uLlxuLy9cbi8vIEVhY2ggaW5kaXZpZHVhbCBTY2hlbWEgb2JqZWN0IHNob3VsZCBiZSBpbW11dGFibGUuIFRoZSBoZWxwZXJzIHRvXG4vLyBkbyB0aGluZ3Mgd2l0aCB0aGUgU2NoZW1hIGp1c3QgcmV0dXJuIGEgbmV3IHNjaGVtYSB3aGVuIHRoZSBzY2hlbWFcbi8vIGlzIGNoYW5nZWQuXG4vL1xuLy8gVGhlIGNhbm9uaWNhbCBwbGFjZSB0byBzdG9yZSB0aGlzIFNjaGVtYSBpcyBpbiB0aGUgZGF0YWJhc2UgaXRzZWxmLFxuLy8gaW4gYSBfU0NIRU1BIGNvbGxlY3Rpb24uIFRoaXMgaXMgbm90IHRoZSByaWdodCB3YXkgdG8gZG8gaXQgZm9yIGFuXG4vLyBvcGVuIHNvdXJjZSBmcmFtZXdvcmssIGJ1dCBpdCdzIGJhY2t3YXJkIGNvbXBhdGlibGUsIHNvIHdlJ3JlXG4vLyBrZWVwaW5nIGl0IHRoaXMgd2F5IGZvciBub3cuXG4vL1xuLy8gSW4gQVBJLWhhbmRsaW5nIGNvZGUsIHlvdSBzaG91bGQgb25seSB1c2UgdGhlIFNjaGVtYSBjbGFzcyB2aWEgdGhlXG4vLyBEYXRhYmFzZUNvbnRyb2xsZXIuIFRoaXMgd2lsbCBsZXQgdXMgcmVwbGFjZSB0aGUgc2NoZW1hIGxvZ2ljIGZvclxuLy8gZGlmZmVyZW50IGRhdGFiYXNlcy5cbi8vIFRPRE86IGhpZGUgYWxsIHNjaGVtYSBsb2dpYyBpbnNpZGUgdGhlIGRhdGFiYXNlIGFkYXB0ZXIuXG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmNvbnN0IFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuaW1wb3J0IHsgU3RvcmFnZUFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9TdG9yYWdlL1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCBEYXRhYmFzZUNvbnRyb2xsZXIgZnJvbSAnLi9EYXRhYmFzZUNvbnRyb2xsZXInO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuLi9Db25maWcnO1xuLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG5pbXBvcnQgZGVlcGNvcHkgZnJvbSAnZGVlcGNvcHknO1xuaW1wb3J0IHR5cGUge1xuICBTY2hlbWEsXG4gIFNjaGVtYUZpZWxkcyxcbiAgQ2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICBTY2hlbWFGaWVsZCxcbiAgTG9hZFNjaGVtYU9wdGlvbnMsXG59IGZyb20gJy4vdHlwZXMnO1xuXG5jb25zdCBkZWZhdWx0Q29sdW1uczogeyBbc3RyaW5nXTogU2NoZW1hRmllbGRzIH0gPSBPYmplY3QuZnJlZXplKHtcbiAgLy8gQ29udGFpbiB0aGUgZGVmYXVsdCBjb2x1bW5zIGZvciBldmVyeSBwYXJzZSBvYmplY3QgdHlwZSAoZXhjZXB0IF9Kb2luIGNvbGxlY3Rpb24pXG4gIF9EZWZhdWx0OiB7XG4gICAgb2JqZWN0SWQ6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBjcmVhdGVkQXQ6IHsgdHlwZTogJ0RhdGUnIH0sXG4gICAgdXBkYXRlZEF0OiB7IHR5cGU6ICdEYXRlJyB9LFxuICAgIEFDTDogeyB0eXBlOiAnQUNMJyB9LFxuICB9LFxuICAvLyBUaGUgYWRkaXRpb25hbCBkZWZhdWx0IGNvbHVtbnMgZm9yIHRoZSBfVXNlciBjb2xsZWN0aW9uIChpbiBhZGRpdGlvbiB0byBEZWZhdWx0Q29scylcbiAgX1VzZXI6IHtcbiAgICB1c2VybmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHBhc3N3b3JkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZW1haWw6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBlbWFpbFZlcmlmaWVkOiB7IHR5cGU6ICdCb29sZWFuJyB9LFxuICAgIGF1dGhEYXRhOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gIH0sXG4gIC8vIFRoZSBhZGRpdGlvbmFsIGRlZmF1bHQgY29sdW1ucyBmb3IgdGhlIF9JbnN0YWxsYXRpb24gY29sbGVjdGlvbiAoaW4gYWRkaXRpb24gdG8gRGVmYXVsdENvbHMpXG4gIF9JbnN0YWxsYXRpb246IHtcbiAgICBpbnN0YWxsYXRpb25JZDogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGRldmljZVRva2VuOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgY2hhbm5lbHM6IHsgdHlwZTogJ0FycmF5JyB9LFxuICAgIGRldmljZVR5cGU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBwdXNoVHlwZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIEdDTVNlbmRlcklkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgdGltZVpvbmU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBsb2NhbGVJZGVudGlmaWVyOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgYmFkZ2U6IHsgdHlwZTogJ051bWJlcicgfSxcbiAgICBhcHBWZXJzaW9uOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgYXBwTmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGFwcElkZW50aWZpZXI6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBwYXJzZVZlcnNpb246IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgfSxcbiAgLy8gVGhlIGFkZGl0aW9uYWwgZGVmYXVsdCBjb2x1bW5zIGZvciB0aGUgX1JvbGUgY29sbGVjdGlvbiAoaW4gYWRkaXRpb24gdG8gRGVmYXVsdENvbHMpXG4gIF9Sb2xlOiB7XG4gICAgbmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHVzZXJzOiB7IHR5cGU6ICdSZWxhdGlvbicsIHRhcmdldENsYXNzOiAnX1VzZXInIH0sXG4gICAgcm9sZXM6IHsgdHlwZTogJ1JlbGF0aW9uJywgdGFyZ2V0Q2xhc3M6ICdfUm9sZScgfSxcbiAgfSxcbiAgLy8gVGhlIGFkZGl0aW9uYWwgZGVmYXVsdCBjb2x1bW5zIGZvciB0aGUgX1Nlc3Npb24gY29sbGVjdGlvbiAoaW4gYWRkaXRpb24gdG8gRGVmYXVsdENvbHMpXG4gIF9TZXNzaW9uOiB7XG4gICAgcmVzdHJpY3RlZDogeyB0eXBlOiAnQm9vbGVhbicgfSxcbiAgICB1c2VyOiB7IHR5cGU6ICdQb2ludGVyJywgdGFyZ2V0Q2xhc3M6ICdfVXNlcicgfSxcbiAgICBpbnN0YWxsYXRpb25JZDogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHNlc3Npb25Ub2tlbjogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGV4cGlyZXNBdDogeyB0eXBlOiAnRGF0ZScgfSxcbiAgICBjcmVhdGVkV2l0aDogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICB9LFxuICBfUHJvZHVjdDoge1xuICAgIHByb2R1Y3RJZGVudGlmaWVyOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZG93bmxvYWQ6IHsgdHlwZTogJ0ZpbGUnIH0sXG4gICAgZG93bmxvYWROYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgaWNvbjogeyB0eXBlOiAnRmlsZScgfSxcbiAgICBvcmRlcjogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICAgIHRpdGxlOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgc3VidGl0bGU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgfSxcbiAgX1B1c2hTdGF0dXM6IHtcbiAgICBwdXNoVGltZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHNvdXJjZTogeyB0eXBlOiAnU3RyaW5nJyB9LCAvLyByZXN0IG9yIHdlYnVpXG4gICAgcXVlcnk6IHsgdHlwZTogJ1N0cmluZycgfSwgLy8gdGhlIHN0cmluZ2lmaWVkIEpTT04gcXVlcnlcbiAgICBwYXlsb2FkOiB7IHR5cGU6ICdTdHJpbmcnIH0sIC8vIHRoZSBzdHJpbmdpZmllZCBKU09OIHBheWxvYWQsXG4gICAgdGl0bGU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBleHBpcnk6IHsgdHlwZTogJ051bWJlcicgfSxcbiAgICBleHBpcmF0aW9uX2ludGVydmFsOiB7IHR5cGU6ICdOdW1iZXInIH0sXG4gICAgc3RhdHVzOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgbnVtU2VudDogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICAgIG51bUZhaWxlZDogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICAgIHB1c2hIYXNoOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZXJyb3JNZXNzYWdlOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gICAgc2VudFBlclR5cGU6IHsgdHlwZTogJ09iamVjdCcgfSxcbiAgICBmYWlsZWRQZXJUeXBlOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gICAgc2VudFBlclVUQ09mZnNldDogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICAgIGZhaWxlZFBlclVUQ09mZnNldDogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICAgIGNvdW50OiB7IHR5cGU6ICdOdW1iZXInIH0sIC8vIHRyYWNrcyAjIG9mIGJhdGNoZXMgcXVldWVkIGFuZCBwZW5kaW5nXG4gIH0sXG4gIF9Kb2JTdGF0dXM6IHtcbiAgICBqb2JOYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgc291cmNlOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgc3RhdHVzOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgbWVzc2FnZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHBhcmFtczogeyB0eXBlOiAnT2JqZWN0JyB9LCAvLyBwYXJhbXMgcmVjZWl2ZWQgd2hlbiBjYWxsaW5nIHRoZSBqb2JcbiAgICBmaW5pc2hlZEF0OiB7IHR5cGU6ICdEYXRlJyB9LFxuICB9LFxuICBfSm9iU2NoZWR1bGU6IHtcbiAgICBqb2JOYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZGVzY3JpcHRpb246IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBwYXJhbXM6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBzdGFydEFmdGVyOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZGF5c09mV2VlazogeyB0eXBlOiAnQXJyYXknIH0sXG4gICAgdGltZU9mRGF5OiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgbGFzdFJ1bjogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICAgIHJlcGVhdE1pbnV0ZXM6IHsgdHlwZTogJ051bWJlcicgfSxcbiAgfSxcbiAgX0hvb2tzOiB7XG4gICAgZnVuY3Rpb25OYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgY2xhc3NOYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgdHJpZ2dlck5hbWU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICB1cmw6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgfSxcbiAgX0dsb2JhbENvbmZpZzoge1xuICAgIG9iamVjdElkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgcGFyYW1zOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gICAgbWFzdGVyS2V5T25seTogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICB9LFxuICBfR3JhcGhRTENvbmZpZzoge1xuICAgIG9iamVjdElkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgY29uZmlnOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gIH0sXG4gIF9BdWRpZW5jZToge1xuICAgIG9iamVjdElkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgbmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHF1ZXJ5OiB7IHR5cGU6ICdTdHJpbmcnIH0sIC8vc3RvcmluZyBxdWVyeSBhcyBKU09OIHN0cmluZyB0byBwcmV2ZW50IFwiTmVzdGVkIGtleXMgc2hvdWxkIG5vdCBjb250YWluIHRoZSAnJCcgb3IgJy4nIGNoYXJhY3RlcnNcIiBlcnJvclxuICAgIGxhc3RVc2VkOiB7IHR5cGU6ICdEYXRlJyB9LFxuICAgIHRpbWVzVXNlZDogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICB9LFxuICBfSWRlbXBvdGVuY3k6IHtcbiAgICByZXFJZDogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGV4cGlyZTogeyB0eXBlOiAnRGF0ZScgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCByZXF1aXJlZENvbHVtbnMgPSBPYmplY3QuZnJlZXplKHtcbiAgX1Byb2R1Y3Q6IFsncHJvZHVjdElkZW50aWZpZXInLCAnaWNvbicsICdvcmRlcicsICd0aXRsZScsICdzdWJ0aXRsZSddLFxuICBfUm9sZTogWyduYW1lJywgJ0FDTCddLFxufSk7XG5cbmNvbnN0IGludmFsaWRDb2x1bW5zID0gWydsZW5ndGgnXTtcblxuY29uc3Qgc3lzdGVtQ2xhc3NlcyA9IE9iamVjdC5mcmVlemUoW1xuICAnX1VzZXInLFxuICAnX0luc3RhbGxhdGlvbicsXG4gICdfUm9sZScsXG4gICdfU2Vzc2lvbicsXG4gICdfUHJvZHVjdCcsXG4gICdfUHVzaFN0YXR1cycsXG4gICdfSm9iU3RhdHVzJyxcbiAgJ19Kb2JTY2hlZHVsZScsXG4gICdfQXVkaWVuY2UnLFxuICAnX0lkZW1wb3RlbmN5Jyxcbl0pO1xuXG5jb25zdCB2b2xhdGlsZUNsYXNzZXMgPSBPYmplY3QuZnJlZXplKFtcbiAgJ19Kb2JTdGF0dXMnLFxuICAnX1B1c2hTdGF0dXMnLFxuICAnX0hvb2tzJyxcbiAgJ19HbG9iYWxDb25maWcnLFxuICAnX0dyYXBoUUxDb25maWcnLFxuICAnX0pvYlNjaGVkdWxlJyxcbiAgJ19BdWRpZW5jZScsXG4gICdfSWRlbXBvdGVuY3knLFxuXSk7XG5cbi8vIEFueXRoaW5nIHRoYXQgc3RhcnQgd2l0aCByb2xlXG5jb25zdCByb2xlUmVnZXggPSAvXnJvbGU6LiovO1xuLy8gQW55dGhpbmcgdGhhdCBzdGFydHMgd2l0aCB1c2VyRmllbGQgKGFsbG93ZWQgZm9yIHByb3RlY3RlZCBmaWVsZHMgb25seSlcbmNvbnN0IHByb3RlY3RlZEZpZWxkc1BvaW50ZXJSZWdleCA9IC9edXNlckZpZWxkOi4qLztcbi8vICogcGVybWlzc2lvblxuY29uc3QgcHVibGljUmVnZXggPSAvXlxcKiQvO1xuXG5jb25zdCBhdXRoZW50aWNhdGVkUmVnZXggPSAvXmF1dGhlbnRpY2F0ZWQkLztcblxuY29uc3QgcmVxdWlyZXNBdXRoZW50aWNhdGlvblJlZ2V4ID0gL15yZXF1aXJlc0F1dGhlbnRpY2F0aW9uJC87XG5cbmNvbnN0IGNscFBvaW50ZXJSZWdleCA9IC9ecG9pbnRlckZpZWxkcyQvO1xuXG4vLyByZWdleCBmb3IgdmFsaWRhdGluZyBlbnRpdGllcyBpbiBwcm90ZWN0ZWRGaWVsZHMgb2JqZWN0XG5jb25zdCBwcm90ZWN0ZWRGaWVsZHNSZWdleCA9IE9iamVjdC5mcmVlemUoW1xuICBwcm90ZWN0ZWRGaWVsZHNQb2ludGVyUmVnZXgsXG4gIHB1YmxpY1JlZ2V4LFxuICBhdXRoZW50aWNhdGVkUmVnZXgsXG4gIHJvbGVSZWdleCxcbl0pO1xuXG4vLyBjbHAgcmVnZXhcbmNvbnN0IGNscEZpZWxkc1JlZ2V4ID0gT2JqZWN0LmZyZWV6ZShbXG4gIGNscFBvaW50ZXJSZWdleCxcbiAgcHVibGljUmVnZXgsXG4gIHJlcXVpcmVzQXV0aGVudGljYXRpb25SZWdleCxcbiAgcm9sZVJlZ2V4LFxuXSk7XG5cbmZ1bmN0aW9uIHZhbGlkYXRlUGVybWlzc2lvbktleShrZXksIHVzZXJJZFJlZ0V4cCkge1xuICBsZXQgbWF0Y2hlc1NvbWUgPSBmYWxzZTtcbiAgZm9yIChjb25zdCByZWdFeCBvZiBjbHBGaWVsZHNSZWdleCkge1xuICAgIGlmIChrZXkubWF0Y2gocmVnRXgpICE9PSBudWxsKSB7XG4gICAgICBtYXRjaGVzU29tZSA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvLyB1c2VySWQgZGVwZW5kcyBvbiBzdGFydHVwIG9wdGlvbnMgc28gaXQncyBkeW5hbWljXG4gIGNvbnN0IHZhbGlkID0gbWF0Y2hlc1NvbWUgfHwga2V5Lm1hdGNoKHVzZXJJZFJlZ0V4cCkgIT09IG51bGw7XG4gIGlmICghdmFsaWQpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICBgJyR7a2V5fScgaXMgbm90IGEgdmFsaWQga2V5IGZvciBjbGFzcyBsZXZlbCBwZXJtaXNzaW9uc2BcbiAgICApO1xuICB9XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlUHJvdGVjdGVkRmllbGRzS2V5KGtleSwgdXNlcklkUmVnRXhwKSB7XG4gIGxldCBtYXRjaGVzU29tZSA9IGZhbHNlO1xuICBmb3IgKGNvbnN0IHJlZ0V4IG9mIHByb3RlY3RlZEZpZWxkc1JlZ2V4KSB7XG4gICAgaWYgKGtleS5tYXRjaChyZWdFeCkgIT09IG51bGwpIHtcbiAgICAgIG1hdGNoZXNTb21lID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8vIHVzZXJJZCByZWdleCBkZXBlbmRzIG9uIGxhdW5jaCBvcHRpb25zIHNvIGl0J3MgZHluYW1pY1xuICBjb25zdCB2YWxpZCA9IG1hdGNoZXNTb21lIHx8IGtleS5tYXRjaCh1c2VySWRSZWdFeHApICE9PSBudWxsO1xuICBpZiAoIXZhbGlkKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgYCcke2tleX0nIGlzIG5vdCBhIHZhbGlkIGtleSBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnNgXG4gICAgKTtcbiAgfVxufVxuXG5jb25zdCBDTFBWYWxpZEtleXMgPSBPYmplY3QuZnJlZXplKFtcbiAgJ2ZpbmQnLFxuICAnY291bnQnLFxuICAnZ2V0JyxcbiAgJ2NyZWF0ZScsXG4gICd1cGRhdGUnLFxuICAnZGVsZXRlJyxcbiAgJ2FkZEZpZWxkJyxcbiAgJ3JlYWRVc2VyRmllbGRzJyxcbiAgJ3dyaXRlVXNlckZpZWxkcycsXG4gICdwcm90ZWN0ZWRGaWVsZHMnLFxuXSk7XG5cbi8vIHZhbGlkYXRpb24gYmVmb3JlIHNldHRpbmcgY2xhc3MtbGV2ZWwgcGVybWlzc2lvbnMgb24gY29sbGVjdGlvblxuZnVuY3Rpb24gdmFsaWRhdGVDTFAocGVybXM6IENsYXNzTGV2ZWxQZXJtaXNzaW9ucywgZmllbGRzOiBTY2hlbWFGaWVsZHMsIHVzZXJJZFJlZ0V4cDogUmVnRXhwKSB7XG4gIGlmICghcGVybXMpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgZm9yIChjb25zdCBvcGVyYXRpb25LZXkgaW4gcGVybXMpIHtcbiAgICBpZiAoQ0xQVmFsaWRLZXlzLmluZGV4T2Yob3BlcmF0aW9uS2V5KSA9PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgIGAke29wZXJhdGlvbktleX0gaXMgbm90IGEgdmFsaWQgb3BlcmF0aW9uIGZvciBjbGFzcyBsZXZlbCBwZXJtaXNzaW9uc2BcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3Qgb3BlcmF0aW9uID0gcGVybXNbb3BlcmF0aW9uS2V5XTtcbiAgICAvLyBwcm9jZWVkIHdpdGggbmV4dCBvcGVyYXRpb25LZXlcblxuICAgIC8vIHRocm93cyB3aGVuIHJvb3QgZmllbGRzIGFyZSBvZiB3cm9uZyB0eXBlXG4gICAgdmFsaWRhdGVDTFBqc29uKG9wZXJhdGlvbiwgb3BlcmF0aW9uS2V5KTtcblxuICAgIGlmIChvcGVyYXRpb25LZXkgPT09ICdyZWFkVXNlckZpZWxkcycgfHwgb3BlcmF0aW9uS2V5ID09PSAnd3JpdGVVc2VyRmllbGRzJykge1xuICAgICAgLy8gdmFsaWRhdGUgZ3JvdXBlZCBwb2ludGVyIHBlcm1pc3Npb25zXG4gICAgICAvLyBtdXN0IGJlIGFuIGFycmF5IHdpdGggZmllbGQgbmFtZXNcbiAgICAgIGZvciAoY29uc3QgZmllbGROYW1lIG9mIG9wZXJhdGlvbikge1xuICAgICAgICB2YWxpZGF0ZVBvaW50ZXJQZXJtaXNzaW9uKGZpZWxkTmFtZSwgZmllbGRzLCBvcGVyYXRpb25LZXkpO1xuICAgICAgfVxuICAgICAgLy8gcmVhZFVzZXJGaWVsZHMgYW5kIHdyaXRlclVzZXJGaWVsZHMgZG8gbm90IGhhdmUgbmVzZHRlZCBmaWVsZHNcbiAgICAgIC8vIHByb2NlZWQgd2l0aCBuZXh0IG9wZXJhdGlvbktleVxuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gdmFsaWRhdGUgcHJvdGVjdGVkIGZpZWxkc1xuICAgIGlmIChvcGVyYXRpb25LZXkgPT09ICdwcm90ZWN0ZWRGaWVsZHMnKSB7XG4gICAgICBmb3IgKGNvbnN0IGVudGl0eSBpbiBvcGVyYXRpb24pIHtcbiAgICAgICAgLy8gdGhyb3dzIG9uIHVuZXhwZWN0ZWQga2V5XG4gICAgICAgIHZhbGlkYXRlUHJvdGVjdGVkRmllbGRzS2V5KGVudGl0eSwgdXNlcklkUmVnRXhwKTtcblxuICAgICAgICBjb25zdCBwcm90ZWN0ZWRGaWVsZHMgPSBvcGVyYXRpb25bZW50aXR5XTtcblxuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkocHJvdGVjdGVkRmllbGRzKSkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgIGAnJHtwcm90ZWN0ZWRGaWVsZHN9JyBpcyBub3QgYSB2YWxpZCB2YWx1ZSBmb3IgcHJvdGVjdGVkRmllbGRzWyR7ZW50aXR5fV0gLSBleHBlY3RlZCBhbiBhcnJheS5gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGlmIHRoZSBmaWVsZCBpcyBpbiBmb3JtIG9mIGFycmF5XG4gICAgICAgIGZvciAoY29uc3QgZmllbGQgb2YgcHJvdGVjdGVkRmllbGRzKSB7XG4gICAgICAgICAgLy8gZG8gbm90IGFsbG9vdyB0byBwcm90ZWN0IGRlZmF1bHQgZmllbGRzXG4gICAgICAgICAgaWYgKGRlZmF1bHRDb2x1bW5zLl9EZWZhdWx0W2ZpZWxkXSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAgIGBEZWZhdWx0IGZpZWxkICcke2ZpZWxkfScgY2FuIG5vdCBiZSBwcm90ZWN0ZWRgXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBmaWVsZCBzaG91bGQgZXhpc3Qgb24gY29sbGVjdGlvblxuICAgICAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGZpZWxkcywgZmllbGQpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgICAgYEZpZWxkICcke2ZpZWxkfScgaW4gcHJvdGVjdGVkRmllbGRzOiR7ZW50aXR5fSBkb2VzIG5vdCBleGlzdGBcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBwcm9jZWVkIHdpdGggbmV4dCBvcGVyYXRpb25LZXlcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIHZhbGlkYXRlIG90aGVyIGZpZWxkc1xuICAgIC8vIEVudGl0eSBjYW4gYmU6XG4gICAgLy8gXCIqXCIgLSBQdWJsaWMsXG4gICAgLy8gXCJyZXF1aXJlc0F1dGhlbnRpY2F0aW9uXCIgLSBhdXRoZW50aWNhdGVkIHVzZXJzLFxuICAgIC8vIFwib2JqZWN0SWRcIiAtIF9Vc2VyIGlkLFxuICAgIC8vIFwicm9sZTpyb2xlbmFtZVwiLFxuICAgIC8vIFwicG9pbnRlckZpZWxkc1wiIC0gYXJyYXkgb2YgZmllbGQgbmFtZXMgY29udGFpbmluZyBwb2ludGVycyB0byB1c2Vyc1xuICAgIGZvciAoY29uc3QgZW50aXR5IGluIG9wZXJhdGlvbikge1xuICAgICAgLy8gdGhyb3dzIG9uIHVuZXhwZWN0ZWQga2V5XG4gICAgICB2YWxpZGF0ZVBlcm1pc3Npb25LZXkoZW50aXR5LCB1c2VySWRSZWdFeHApO1xuXG4gICAgICAvLyBlbnRpdHkgY2FuIGJlIGVpdGhlcjpcbiAgICAgIC8vIFwicG9pbnRlckZpZWxkc1wiOiBzdHJpbmdbXVxuICAgICAgaWYgKGVudGl0eSA9PT0gJ3BvaW50ZXJGaWVsZHMnKSB7XG4gICAgICAgIGNvbnN0IHBvaW50ZXJGaWVsZHMgPSBvcGVyYXRpb25bZW50aXR5XTtcblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShwb2ludGVyRmllbGRzKSkge1xuICAgICAgICAgIGZvciAoY29uc3QgcG9pbnRlckZpZWxkIG9mIHBvaW50ZXJGaWVsZHMpIHtcbiAgICAgICAgICAgIHZhbGlkYXRlUG9pbnRlclBlcm1pc3Npb24ocG9pbnRlckZpZWxkLCBmaWVsZHMsIG9wZXJhdGlvbik7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfSlNPTixcbiAgICAgICAgICAgIGAnJHtwb2ludGVyRmllbGRzfScgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yICR7b3BlcmF0aW9uS2V5fVske2VudGl0eX1dIC0gZXhwZWN0ZWQgYW4gYXJyYXkuYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcHJvY2VlZCB3aXRoIG5leHQgZW50aXR5IGtleVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gb3IgW2VudGl0eV06IGJvb2xlYW5cbiAgICAgIGNvbnN0IHBlcm1pdCA9IG9wZXJhdGlvbltlbnRpdHldO1xuXG4gICAgICBpZiAocGVybWl0ICE9PSB0cnVlKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgYCcke3Blcm1pdH0nIGlzIG5vdCBhIHZhbGlkIHZhbHVlIGZvciBjbGFzcyBsZXZlbCBwZXJtaXNzaW9ucyAke29wZXJhdGlvbktleX06JHtlbnRpdHl9OiR7cGVybWl0fWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVDTFBqc29uKG9wZXJhdGlvbjogYW55LCBvcGVyYXRpb25LZXk6IHN0cmluZykge1xuICBpZiAob3BlcmF0aW9uS2V5ID09PSAncmVhZFVzZXJGaWVsZHMnIHx8IG9wZXJhdGlvbktleSA9PT0gJ3dyaXRlVXNlckZpZWxkcycpIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkob3BlcmF0aW9uKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgIGAnJHtvcGVyYXRpb259JyBpcyBub3QgYSB2YWxpZCB2YWx1ZSBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnMgJHtvcGVyYXRpb25LZXl9IC0gbXVzdCBiZSBhbiBhcnJheWBcbiAgICAgICk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmICh0eXBlb2Ygb3BlcmF0aW9uID09PSAnb2JqZWN0JyAmJiBvcGVyYXRpb24gIT09IG51bGwpIHtcbiAgICAgIC8vIG9rIHRvIHByb2NlZWRcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgIGAnJHtvcGVyYXRpb259JyBpcyBub3QgYSB2YWxpZCB2YWx1ZSBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnMgJHtvcGVyYXRpb25LZXl9IC0gbXVzdCBiZSBhbiBvYmplY3RgXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZVBvaW50ZXJQZXJtaXNzaW9uKGZpZWxkTmFtZTogc3RyaW5nLCBmaWVsZHM6IE9iamVjdCwgb3BlcmF0aW9uOiBzdHJpbmcpIHtcbiAgLy8gVXNlcyBjb2xsZWN0aW9uIHNjaGVtYSB0byBlbnN1cmUgdGhlIGZpZWxkIGlzIG9mIHR5cGU6XG4gIC8vIC0gUG9pbnRlcjxfVXNlcj4gKHBvaW50ZXJzKVxuICAvLyAtIEFycmF5XG4gIC8vXG4gIC8vICAgIEl0J3Mgbm90IHBvc3NpYmxlIHRvIGVuZm9yY2UgdHlwZSBvbiBBcnJheSdzIGl0ZW1zIGluIHNjaGVtYVxuICAvLyAgc28gd2UgYWNjZXB0IGFueSBBcnJheSBmaWVsZCwgYW5kIGxhdGVyIHdoZW4gYXBwbHlpbmcgcGVybWlzc2lvbnNcbiAgLy8gIG9ubHkgaXRlbXMgdGhhdCBhcmUgcG9pbnRlcnMgdG8gX1VzZXIgYXJlIGNvbnNpZGVyZWQuXG4gIGlmIChcbiAgICAhKFxuICAgICAgZmllbGRzW2ZpZWxkTmFtZV0gJiZcbiAgICAgICgoZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PSAnUG9pbnRlcicgJiYgZmllbGRzW2ZpZWxkTmFtZV0udGFyZ2V0Q2xhc3MgPT0gJ19Vc2VyJykgfHxcbiAgICAgICAgZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PSAnQXJyYXknKVxuICAgIClcbiAgKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgYCcke2ZpZWxkTmFtZX0nIGlzIG5vdCBhIHZhbGlkIGNvbHVtbiBmb3IgY2xhc3MgbGV2ZWwgcG9pbnRlciBwZXJtaXNzaW9ucyAke29wZXJhdGlvbn1gXG4gICAgKTtcbiAgfVxufVxuXG5jb25zdCBqb2luQ2xhc3NSZWdleCA9IC9eX0pvaW46W0EtWmEtejAtOV9dKzpbQS1aYS16MC05X10rLztcbmNvbnN0IGNsYXNzQW5kRmllbGRSZWdleCA9IC9eW0EtWmEtel1bQS1aYS16MC05X10qJC87XG5mdW5jdGlvbiBjbGFzc05hbWVJc1ZhbGlkKGNsYXNzTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIC8vIFZhbGlkIGNsYXNzZXMgbXVzdDpcbiAgcmV0dXJuIChcbiAgICAvLyBCZSBvbmUgb2YgX1VzZXIsIF9JbnN0YWxsYXRpb24sIF9Sb2xlLCBfU2Vzc2lvbiBPUlxuICAgIHN5c3RlbUNsYXNzZXMuaW5kZXhPZihjbGFzc05hbWUpID4gLTEgfHxcbiAgICAvLyBCZSBhIGpvaW4gdGFibGUgT1JcbiAgICBqb2luQ2xhc3NSZWdleC50ZXN0KGNsYXNzTmFtZSkgfHxcbiAgICAvLyBJbmNsdWRlIG9ubHkgYWxwaGEtbnVtZXJpYyBhbmQgdW5kZXJzY29yZXMsIGFuZCBub3Qgc3RhcnQgd2l0aCBhbiB1bmRlcnNjb3JlIG9yIG51bWJlclxuICAgIGZpZWxkTmFtZUlzVmFsaWQoY2xhc3NOYW1lLCBjbGFzc05hbWUpXG4gICk7XG59XG5cbi8vIFZhbGlkIGZpZWxkcyBtdXN0IGJlIGFscGhhLW51bWVyaWMsIGFuZCBub3Qgc3RhcnQgd2l0aCBhbiB1bmRlcnNjb3JlIG9yIG51bWJlclxuLy8gbXVzdCBub3QgYmUgYSByZXNlcnZlZCBrZXlcbmZ1bmN0aW9uIGZpZWxkTmFtZUlzVmFsaWQoZmllbGROYW1lOiBzdHJpbmcsIGNsYXNzTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmIChjbGFzc05hbWUgJiYgY2xhc3NOYW1lICE9PSAnX0hvb2tzJykge1xuICAgIGlmIChmaWVsZE5hbWUgPT09ICdjbGFzc05hbWUnKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiBjbGFzc0FuZEZpZWxkUmVnZXgudGVzdChmaWVsZE5hbWUpICYmICFpbnZhbGlkQ29sdW1ucy5pbmNsdWRlcyhmaWVsZE5hbWUpO1xufVxuXG4vLyBDaGVja3MgdGhhdCBpdCdzIG5vdCB0cnlpbmcgdG8gY2xvYmJlciBvbmUgb2YgdGhlIGRlZmF1bHQgZmllbGRzIG9mIHRoZSBjbGFzcy5cbmZ1bmN0aW9uIGZpZWxkTmFtZUlzVmFsaWRGb3JDbGFzcyhmaWVsZE5hbWU6IHN0cmluZywgY2xhc3NOYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgaWYgKCFmaWVsZE5hbWVJc1ZhbGlkKGZpZWxkTmFtZSwgY2xhc3NOYW1lKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoZGVmYXVsdENvbHVtbnMuX0RlZmF1bHRbZmllbGROYW1lXSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoZGVmYXVsdENvbHVtbnNbY2xhc3NOYW1lXSAmJiBkZWZhdWx0Q29sdW1uc1tjbGFzc05hbWVdW2ZpZWxkTmFtZV0pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGludmFsaWRDbGFzc05hbWVNZXNzYWdlKGNsYXNzTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIChcbiAgICAnSW52YWxpZCBjbGFzc25hbWU6ICcgK1xuICAgIGNsYXNzTmFtZSArXG4gICAgJywgY2xhc3NuYW1lcyBjYW4gb25seSBoYXZlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIGFuZCBfLCBhbmQgbXVzdCBzdGFydCB3aXRoIGFuIGFscGhhIGNoYXJhY3RlciAnXG4gICk7XG59XG5cbmNvbnN0IGludmFsaWRKc29uRXJyb3IgPSBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnaW52YWxpZCBKU09OJyk7XG5jb25zdCB2YWxpZE5vblJlbGF0aW9uT3JQb2ludGVyVHlwZXMgPSBbXG4gICdOdW1iZXInLFxuICAnU3RyaW5nJyxcbiAgJ0Jvb2xlYW4nLFxuICAnRGF0ZScsXG4gICdPYmplY3QnLFxuICAnQXJyYXknLFxuICAnR2VvUG9pbnQnLFxuICAnRmlsZScsXG4gICdCeXRlcycsXG4gICdQb2x5Z29uJyxcbl07XG4vLyBSZXR1cm5zIGFuIGVycm9yIHN1aXRhYmxlIGZvciB0aHJvd2luZyBpZiB0aGUgdHlwZSBpcyBpbnZhbGlkXG5jb25zdCBmaWVsZFR5cGVJc0ludmFsaWQgPSAoeyB0eXBlLCB0YXJnZXRDbGFzcyB9KSA9PiB7XG4gIGlmIChbJ1BvaW50ZXInLCAnUmVsYXRpb24nXS5pbmRleE9mKHR5cGUpID49IDApIHtcbiAgICBpZiAoIXRhcmdldENsYXNzKSB7XG4gICAgICByZXR1cm4gbmV3IFBhcnNlLkVycm9yKDEzNSwgYHR5cGUgJHt0eXBlfSBuZWVkcyBhIGNsYXNzIG5hbWVgKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB0YXJnZXRDbGFzcyAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBpbnZhbGlkSnNvbkVycm9yO1xuICAgIH0gZWxzZSBpZiAoIWNsYXNzTmFtZUlzVmFsaWQodGFyZ2V0Q2xhc3MpKSB7XG4gICAgICByZXR1cm4gbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSwgaW52YWxpZENsYXNzTmFtZU1lc3NhZ2UodGFyZ2V0Q2xhc3MpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgaWYgKHR5cGVvZiB0eXBlICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBpbnZhbGlkSnNvbkVycm9yO1xuICB9XG4gIGlmICh2YWxpZE5vblJlbGF0aW9uT3JQb2ludGVyVHlwZXMuaW5kZXhPZih0eXBlKSA8IDApIHtcbiAgICByZXR1cm4gbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLCBgaW52YWxpZCBmaWVsZCB0eXBlOiAke3R5cGV9YCk7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn07XG5cbmNvbnN0IGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEgPSAoc2NoZW1hOiBhbnkpID0+IHtcbiAgc2NoZW1hID0gaW5qZWN0RGVmYXVsdFNjaGVtYShzY2hlbWEpO1xuICBkZWxldGUgc2NoZW1hLmZpZWxkcy5BQ0w7XG4gIHNjaGVtYS5maWVsZHMuX3JwZXJtID0geyB0eXBlOiAnQXJyYXknIH07XG4gIHNjaGVtYS5maWVsZHMuX3dwZXJtID0geyB0eXBlOiAnQXJyYXknIH07XG5cbiAgaWYgKHNjaGVtYS5jbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICBkZWxldGUgc2NoZW1hLmZpZWxkcy5wYXNzd29yZDtcbiAgICBzY2hlbWEuZmllbGRzLl9oYXNoZWRfcGFzc3dvcmQgPSB7IHR5cGU6ICdTdHJpbmcnIH07XG4gIH1cblxuICByZXR1cm4gc2NoZW1hO1xufTtcblxuY29uc3QgY29udmVydEFkYXB0ZXJTY2hlbWFUb1BhcnNlU2NoZW1hID0gKHsgLi4uc2NoZW1hIH0pID0+IHtcbiAgZGVsZXRlIHNjaGVtYS5maWVsZHMuX3JwZXJtO1xuICBkZWxldGUgc2NoZW1hLmZpZWxkcy5fd3Blcm07XG5cbiAgc2NoZW1hLmZpZWxkcy5BQ0wgPSB7IHR5cGU6ICdBQ0wnIH07XG5cbiAgaWYgKHNjaGVtYS5jbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICBkZWxldGUgc2NoZW1hLmZpZWxkcy5hdXRoRGF0YTsgLy9BdXRoIGRhdGEgaXMgaW1wbGljaXRcbiAgICBkZWxldGUgc2NoZW1hLmZpZWxkcy5faGFzaGVkX3Bhc3N3b3JkO1xuICAgIHNjaGVtYS5maWVsZHMucGFzc3dvcmQgPSB7IHR5cGU6ICdTdHJpbmcnIH07XG4gIH1cblxuICBpZiAoc2NoZW1hLmluZGV4ZXMgJiYgT2JqZWN0LmtleXMoc2NoZW1hLmluZGV4ZXMpLmxlbmd0aCA9PT0gMCkge1xuICAgIGRlbGV0ZSBzY2hlbWEuaW5kZXhlcztcbiAgfVxuXG4gIHJldHVybiBzY2hlbWE7XG59O1xuXG5jbGFzcyBTY2hlbWFEYXRhIHtcbiAgX19kYXRhOiBhbnk7XG4gIF9fcHJvdGVjdGVkRmllbGRzOiBhbnk7XG4gIGNvbnN0cnVjdG9yKGFsbFNjaGVtYXMgPSBbXSwgcHJvdGVjdGVkRmllbGRzID0ge30pIHtcbiAgICB0aGlzLl9fZGF0YSA9IHt9O1xuICAgIHRoaXMuX19wcm90ZWN0ZWRGaWVsZHMgPSBwcm90ZWN0ZWRGaWVsZHM7XG4gICAgYWxsU2NoZW1hcy5mb3JFYWNoKHNjaGVtYSA9PiB7XG4gICAgICBpZiAodm9sYXRpbGVDbGFzc2VzLmluY2x1ZGVzKHNjaGVtYS5jbGFzc05hbWUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBzY2hlbWEuY2xhc3NOYW1lLCB7XG4gICAgICAgIGdldDogKCkgPT4ge1xuICAgICAgICAgIGlmICghdGhpcy5fX2RhdGFbc2NoZW1hLmNsYXNzTmFtZV0pIHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSB7fTtcbiAgICAgICAgICAgIGRhdGEuZmllbGRzID0gaW5qZWN0RGVmYXVsdFNjaGVtYShzY2hlbWEpLmZpZWxkcztcbiAgICAgICAgICAgIGRhdGEuY2xhc3NMZXZlbFBlcm1pc3Npb25zID0gZGVlcGNvcHkoc2NoZW1hLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucyk7XG4gICAgICAgICAgICBkYXRhLmluZGV4ZXMgPSBzY2hlbWEuaW5kZXhlcztcblxuICAgICAgICAgICAgY29uc3QgY2xhc3NQcm90ZWN0ZWRGaWVsZHMgPSB0aGlzLl9fcHJvdGVjdGVkRmllbGRzW3NjaGVtYS5jbGFzc05hbWVdO1xuICAgICAgICAgICAgaWYgKGNsYXNzUHJvdGVjdGVkRmllbGRzKSB7XG4gICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIGNsYXNzUHJvdGVjdGVkRmllbGRzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdW5xID0gbmV3IFNldChbXG4gICAgICAgICAgICAgICAgICAuLi4oZGF0YS5jbGFzc0xldmVsUGVybWlzc2lvbnMucHJvdGVjdGVkRmllbGRzW2tleV0gfHwgW10pLFxuICAgICAgICAgICAgICAgICAgLi4uY2xhc3NQcm90ZWN0ZWRGaWVsZHNba2V5XSxcbiAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICBkYXRhLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucy5wcm90ZWN0ZWRGaWVsZHNba2V5XSA9IEFycmF5LmZyb20odW5xKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLl9fZGF0YVtzY2hlbWEuY2xhc3NOYW1lXSA9IGRhdGE7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0aGlzLl9fZGF0YVtzY2hlbWEuY2xhc3NOYW1lXTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gSW5qZWN0IHRoZSBpbi1tZW1vcnkgY2xhc3Nlc1xuICAgIHZvbGF0aWxlQ2xhc3Nlcy5mb3JFYWNoKGNsYXNzTmFtZSA9PiB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgY2xhc3NOYW1lLCB7XG4gICAgICAgIGdldDogKCkgPT4ge1xuICAgICAgICAgIGlmICghdGhpcy5fX2RhdGFbY2xhc3NOYW1lXSkge1xuICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0gaW5qZWN0RGVmYXVsdFNjaGVtYSh7XG4gICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgZmllbGRzOiB7fSxcbiAgICAgICAgICAgICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiB7fSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgZGF0YSA9IHt9O1xuICAgICAgICAgICAgZGF0YS5maWVsZHMgPSBzY2hlbWEuZmllbGRzO1xuICAgICAgICAgICAgZGF0YS5jbGFzc0xldmVsUGVybWlzc2lvbnMgPSBzY2hlbWEuY2xhc3NMZXZlbFBlcm1pc3Npb25zO1xuICAgICAgICAgICAgZGF0YS5pbmRleGVzID0gc2NoZW1hLmluZGV4ZXM7XG4gICAgICAgICAgICB0aGlzLl9fZGF0YVtjbGFzc05hbWVdID0gZGF0YTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRoaXMuX19kYXRhW2NsYXNzTmFtZV07XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxufVxuXG5jb25zdCBpbmplY3REZWZhdWx0U2NoZW1hID0gKHsgY2xhc3NOYW1lLCBmaWVsZHMsIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgaW5kZXhlcyB9OiBTY2hlbWEpID0+IHtcbiAgY29uc3QgZGVmYXVsdFNjaGVtYTogU2NoZW1hID0ge1xuICAgIGNsYXNzTmFtZSxcbiAgICBmaWVsZHM6IHtcbiAgICAgIC4uLmRlZmF1bHRDb2x1bW5zLl9EZWZhdWx0LFxuICAgICAgLi4uKGRlZmF1bHRDb2x1bW5zW2NsYXNzTmFtZV0gfHwge30pLFxuICAgICAgLi4uZmllbGRzLFxuICAgIH0sXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICB9O1xuICBpZiAoaW5kZXhlcyAmJiBPYmplY3Qua2V5cyhpbmRleGVzKS5sZW5ndGggIT09IDApIHtcbiAgICBkZWZhdWx0U2NoZW1hLmluZGV4ZXMgPSBpbmRleGVzO1xuICB9XG4gIHJldHVybiBkZWZhdWx0U2NoZW1hO1xufTtcblxuY29uc3QgX0hvb2tzU2NoZW1hID0geyBjbGFzc05hbWU6ICdfSG9va3MnLCBmaWVsZHM6IGRlZmF1bHRDb2x1bW5zLl9Ib29rcyB9O1xuY29uc3QgX0dsb2JhbENvbmZpZ1NjaGVtYSA9IHtcbiAgY2xhc3NOYW1lOiAnX0dsb2JhbENvbmZpZycsXG4gIGZpZWxkczogZGVmYXVsdENvbHVtbnMuX0dsb2JhbENvbmZpZyxcbn07XG5jb25zdCBfR3JhcGhRTENvbmZpZ1NjaGVtYSA9IHtcbiAgY2xhc3NOYW1lOiAnX0dyYXBoUUxDb25maWcnLFxuICBmaWVsZHM6IGRlZmF1bHRDb2x1bW5zLl9HcmFwaFFMQ29uZmlnLFxufTtcbmNvbnN0IF9QdXNoU3RhdHVzU2NoZW1hID0gY29udmVydFNjaGVtYVRvQWRhcHRlclNjaGVtYShcbiAgaW5qZWN0RGVmYXVsdFNjaGVtYSh7XG4gICAgY2xhc3NOYW1lOiAnX1B1c2hTdGF0dXMnLFxuICAgIGZpZWxkczoge30sXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiB7fSxcbiAgfSlcbik7XG5jb25zdCBfSm9iU3RhdHVzU2NoZW1hID0gY29udmVydFNjaGVtYVRvQWRhcHRlclNjaGVtYShcbiAgaW5qZWN0RGVmYXVsdFNjaGVtYSh7XG4gICAgY2xhc3NOYW1lOiAnX0pvYlN0YXR1cycsXG4gICAgZmllbGRzOiB7fSxcbiAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IHt9LFxuICB9KVxuKTtcbmNvbnN0IF9Kb2JTY2hlZHVsZVNjaGVtYSA9IGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEoXG4gIGluamVjdERlZmF1bHRTY2hlbWEoe1xuICAgIGNsYXNzTmFtZTogJ19Kb2JTY2hlZHVsZScsXG4gICAgZmllbGRzOiB7fSxcbiAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IHt9LFxuICB9KVxuKTtcbmNvbnN0IF9BdWRpZW5jZVNjaGVtYSA9IGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEoXG4gIGluamVjdERlZmF1bHRTY2hlbWEoe1xuICAgIGNsYXNzTmFtZTogJ19BdWRpZW5jZScsXG4gICAgZmllbGRzOiBkZWZhdWx0Q29sdW1ucy5fQXVkaWVuY2UsXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiB7fSxcbiAgfSlcbik7XG5jb25zdCBfSWRlbXBvdGVuY3lTY2hlbWEgPSBjb252ZXJ0U2NoZW1hVG9BZGFwdGVyU2NoZW1hKFxuICBpbmplY3REZWZhdWx0U2NoZW1hKHtcbiAgICBjbGFzc05hbWU6ICdfSWRlbXBvdGVuY3knLFxuICAgIGZpZWxkczogZGVmYXVsdENvbHVtbnMuX0lkZW1wb3RlbmN5LFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczoge30sXG4gIH0pXG4pO1xuY29uc3QgVm9sYXRpbGVDbGFzc2VzU2NoZW1hcyA9IFtcbiAgX0hvb2tzU2NoZW1hLFxuICBfSm9iU3RhdHVzU2NoZW1hLFxuICBfSm9iU2NoZWR1bGVTY2hlbWEsXG4gIF9QdXNoU3RhdHVzU2NoZW1hLFxuICBfR2xvYmFsQ29uZmlnU2NoZW1hLFxuICBfR3JhcGhRTENvbmZpZ1NjaGVtYSxcbiAgX0F1ZGllbmNlU2NoZW1hLFxuICBfSWRlbXBvdGVuY3lTY2hlbWEsXG5dO1xuXG5jb25zdCBkYlR5cGVNYXRjaGVzT2JqZWN0VHlwZSA9IChkYlR5cGU6IFNjaGVtYUZpZWxkIHwgc3RyaW5nLCBvYmplY3RUeXBlOiBTY2hlbWFGaWVsZCkgPT4ge1xuICBpZiAoZGJUeXBlLnR5cGUgIT09IG9iamVjdFR5cGUudHlwZSkgcmV0dXJuIGZhbHNlO1xuICBpZiAoZGJUeXBlLnRhcmdldENsYXNzICE9PSBvYmplY3RUeXBlLnRhcmdldENsYXNzKSByZXR1cm4gZmFsc2U7XG4gIGlmIChkYlR5cGUgPT09IG9iamVjdFR5cGUudHlwZSkgcmV0dXJuIHRydWU7XG4gIGlmIChkYlR5cGUudHlwZSA9PT0gb2JqZWN0VHlwZS50eXBlKSByZXR1cm4gdHJ1ZTtcbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuY29uc3QgdHlwZVRvU3RyaW5nID0gKHR5cGU6IFNjaGVtYUZpZWxkIHwgc3RyaW5nKTogc3RyaW5nID0+IHtcbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB0eXBlO1xuICB9XG4gIGlmICh0eXBlLnRhcmdldENsYXNzKSB7XG4gICAgcmV0dXJuIGAke3R5cGUudHlwZX08JHt0eXBlLnRhcmdldENsYXNzfT5gO1xuICB9XG4gIHJldHVybiBgJHt0eXBlLnR5cGV9YDtcbn07XG5cbi8vIFN0b3JlcyB0aGUgZW50aXJlIHNjaGVtYSBvZiB0aGUgYXBwIGluIGEgd2VpcmQgaHlicmlkIGZvcm1hdCBzb21ld2hlcmUgYmV0d2VlblxuLy8gdGhlIG1vbmdvIGZvcm1hdCBhbmQgdGhlIFBhcnNlIGZvcm1hdC4gU29vbiwgdGhpcyB3aWxsIGFsbCBiZSBQYXJzZSBmb3JtYXQuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTY2hlbWFDb250cm9sbGVyIHtcbiAgX2RiQWRhcHRlcjogU3RvcmFnZUFkYXB0ZXI7XG4gIHNjaGVtYURhdGE6IHsgW3N0cmluZ106IFNjaGVtYSB9O1xuICBfY2FjaGU6IGFueTtcbiAgcmVsb2FkRGF0YVByb21pc2U6ID9Qcm9taXNlPGFueT47XG4gIHByb3RlY3RlZEZpZWxkczogYW55O1xuICB1c2VySWRSZWdFeDogUmVnRXhwO1xuXG4gIGNvbnN0cnVjdG9yKGRhdGFiYXNlQWRhcHRlcjogU3RvcmFnZUFkYXB0ZXIsIHNjaGVtYUNhY2hlOiBhbnkpIHtcbiAgICB0aGlzLl9kYkFkYXB0ZXIgPSBkYXRhYmFzZUFkYXB0ZXI7XG4gICAgdGhpcy5fY2FjaGUgPSBzY2hlbWFDYWNoZTtcbiAgICB0aGlzLnNjaGVtYURhdGEgPSBuZXcgU2NoZW1hRGF0YSgpO1xuICAgIHRoaXMucHJvdGVjdGVkRmllbGRzID0gQ29uZmlnLmdldChQYXJzZS5hcHBsaWNhdGlvbklkKS5wcm90ZWN0ZWRGaWVsZHM7XG5cbiAgICBjb25zdCBjdXN0b21JZHMgPSBDb25maWcuZ2V0KFBhcnNlLmFwcGxpY2F0aW9uSWQpLmFsbG93Q3VzdG9tT2JqZWN0SWQ7XG5cbiAgICBjb25zdCBjdXN0b21JZFJlZ0V4ID0gL14uezEsfSQvdTsgLy8gMSsgY2hhcnNcbiAgICBjb25zdCBhdXRvSWRSZWdFeCA9IC9eW2EtekEtWjAtOV17MSx9JC87XG5cbiAgICB0aGlzLnVzZXJJZFJlZ0V4ID0gY3VzdG9tSWRzID8gY3VzdG9tSWRSZWdFeCA6IGF1dG9JZFJlZ0V4O1xuICB9XG5cbiAgcmVsb2FkRGF0YShvcHRpb25zOiBMb2FkU2NoZW1hT3B0aW9ucyA9IHsgY2xlYXJDYWNoZTogZmFsc2UgfSk6IFByb21pc2U8YW55PiB7XG4gICAgaWYgKHRoaXMucmVsb2FkRGF0YVByb21pc2UgJiYgIW9wdGlvbnMuY2xlYXJDYWNoZSkge1xuICAgICAgcmV0dXJuIHRoaXMucmVsb2FkRGF0YVByb21pc2U7XG4gICAgfVxuICAgIHRoaXMucmVsb2FkRGF0YVByb21pc2UgPSB0aGlzLmdldEFsbENsYXNzZXMob3B0aW9ucylcbiAgICAgIC50aGVuKFxuICAgICAgICBhbGxTY2hlbWFzID0+IHtcbiAgICAgICAgICB0aGlzLnNjaGVtYURhdGEgPSBuZXcgU2NoZW1hRGF0YShhbGxTY2hlbWFzLCB0aGlzLnByb3RlY3RlZEZpZWxkcyk7XG4gICAgICAgICAgZGVsZXRlIHRoaXMucmVsb2FkRGF0YVByb21pc2U7XG4gICAgICAgIH0sXG4gICAgICAgIGVyciA9PiB7XG4gICAgICAgICAgdGhpcy5zY2hlbWFEYXRhID0gbmV3IFNjaGVtYURhdGEoKTtcbiAgICAgICAgICBkZWxldGUgdGhpcy5yZWxvYWREYXRhUHJvbWlzZTtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgIClcbiAgICAgIC50aGVuKCgpID0+IHt9KTtcbiAgICByZXR1cm4gdGhpcy5yZWxvYWREYXRhUHJvbWlzZTtcbiAgfVxuXG4gIGdldEFsbENsYXNzZXMob3B0aW9uczogTG9hZFNjaGVtYU9wdGlvbnMgPSB7IGNsZWFyQ2FjaGU6IGZhbHNlIH0pOiBQcm9taXNlPEFycmF5PFNjaGVtYT4+IHtcbiAgICBpZiAob3B0aW9ucy5jbGVhckNhY2hlKSB7XG4gICAgICByZXR1cm4gdGhpcy5zZXRBbGxDbGFzc2VzKCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9jYWNoZS5nZXRBbGxDbGFzc2VzKCkudGhlbihhbGxDbGFzc2VzID0+IHtcbiAgICAgIGlmIChhbGxDbGFzc2VzICYmIGFsbENsYXNzZXMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoYWxsQ2xhc3Nlcyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5zZXRBbGxDbGFzc2VzKCk7XG4gICAgfSk7XG4gIH1cblxuICBzZXRBbGxDbGFzc2VzKCk6IFByb21pc2U8QXJyYXk8U2NoZW1hPj4ge1xuICAgIHJldHVybiB0aGlzLl9kYkFkYXB0ZXJcbiAgICAgIC5nZXRBbGxDbGFzc2VzKClcbiAgICAgIC50aGVuKGFsbFNjaGVtYXMgPT4gYWxsU2NoZW1hcy5tYXAoaW5qZWN0RGVmYXVsdFNjaGVtYSkpXG4gICAgICAudGhlbihhbGxTY2hlbWFzID0+IHtcbiAgICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuICAgICAgICB0aGlzLl9jYWNoZVxuICAgICAgICAgIC5zZXRBbGxDbGFzc2VzKGFsbFNjaGVtYXMpXG4gICAgICAgICAgLmNhdGNoKGVycm9yID0+IGNvbnNvbGUuZXJyb3IoJ0Vycm9yIHNhdmluZyBzY2hlbWEgdG8gY2FjaGU6JywgZXJyb3IpKTtcbiAgICAgICAgLyogZXNsaW50LWVuYWJsZSBuby1jb25zb2xlICovXG4gICAgICAgIHJldHVybiBhbGxTY2hlbWFzO1xuICAgICAgfSk7XG4gIH1cblxuICBnZXRPbmVTY2hlbWEoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgYWxsb3dWb2xhdGlsZUNsYXNzZXM6IGJvb2xlYW4gPSBmYWxzZSxcbiAgICBvcHRpb25zOiBMb2FkU2NoZW1hT3B0aW9ucyA9IHsgY2xlYXJDYWNoZTogZmFsc2UgfVxuICApOiBQcm9taXNlPFNjaGVtYT4ge1xuICAgIGxldCBwcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgaWYgKG9wdGlvbnMuY2xlYXJDYWNoZSkge1xuICAgICAgcHJvbWlzZSA9IHRoaXMuX2NhY2hlLmNsZWFyKCk7XG4gICAgfVxuICAgIHJldHVybiBwcm9taXNlLnRoZW4oKCkgPT4ge1xuICAgICAgaWYgKGFsbG93Vm9sYXRpbGVDbGFzc2VzICYmIHZvbGF0aWxlQ2xhc3Nlcy5pbmRleE9mKGNsYXNzTmFtZSkgPiAtMSkge1xuICAgICAgICBjb25zdCBkYXRhID0gdGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV07XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICBmaWVsZHM6IGRhdGEuZmllbGRzLFxuICAgICAgICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogZGF0YS5jbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gICAgICAgICAgaW5kZXhlczogZGF0YS5pbmRleGVzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLl9jYWNoZS5nZXRPbmVTY2hlbWEoY2xhc3NOYW1lKS50aGVuKGNhY2hlZCA9PiB7XG4gICAgICAgIGlmIChjYWNoZWQgJiYgIW9wdGlvbnMuY2xlYXJDYWNoZSkge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoY2FjaGVkKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5zZXRBbGxDbGFzc2VzKCkudGhlbihhbGxTY2hlbWFzID0+IHtcbiAgICAgICAgICBjb25zdCBvbmVTY2hlbWEgPSBhbGxTY2hlbWFzLmZpbmQoc2NoZW1hID0+IHNjaGVtYS5jbGFzc05hbWUgPT09IGNsYXNzTmFtZSk7XG4gICAgICAgICAgaWYgKCFvbmVTY2hlbWEpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCh1bmRlZmluZWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gb25lU2NoZW1hO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gQ3JlYXRlIGEgbmV3IGNsYXNzIHRoYXQgaW5jbHVkZXMgdGhlIHRocmVlIGRlZmF1bHQgZmllbGRzLlxuICAvLyBBQ0wgaXMgYW4gaW1wbGljaXQgY29sdW1uIHRoYXQgZG9lcyBub3QgZ2V0IGFuIGVudHJ5IGluIHRoZVxuICAvLyBfU0NIRU1BUyBkYXRhYmFzZS4gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZVxuICAvLyBjcmVhdGVkIHNjaGVtYSwgaW4gbW9uZ28gZm9ybWF0LlxuICAvLyBvbiBzdWNjZXNzLCBhbmQgcmVqZWN0cyB3aXRoIGFuIGVycm9yIG9uIGZhaWwuIEVuc3VyZSB5b3VcbiAgLy8gaGF2ZSBhdXRob3JpemF0aW9uIChtYXN0ZXIga2V5LCBvciBjbGllbnQgY2xhc3MgY3JlYXRpb25cbiAgLy8gZW5hYmxlZCkgYmVmb3JlIGNhbGxpbmcgdGhpcyBmdW5jdGlvbi5cbiAgYWRkQ2xhc3NJZk5vdEV4aXN0cyhcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBmaWVsZHM6IFNjaGVtYUZpZWxkcyA9IHt9LFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogYW55LFxuICAgIGluZGV4ZXM6IGFueSA9IHt9XG4gICk6IFByb21pc2U8dm9pZCB8IFNjaGVtYT4ge1xuICAgIHZhciB2YWxpZGF0aW9uRXJyb3IgPSB0aGlzLnZhbGlkYXRlTmV3Q2xhc3MoY2xhc3NOYW1lLCBmaWVsZHMsIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyk7XG4gICAgaWYgKHZhbGlkYXRpb25FcnJvcikge1xuICAgICAgaWYgKHZhbGlkYXRpb25FcnJvciBpbnN0YW5jZW9mIFBhcnNlLkVycm9yKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCh2YWxpZGF0aW9uRXJyb3IpO1xuICAgICAgfSBlbHNlIGlmICh2YWxpZGF0aW9uRXJyb3IuY29kZSAmJiB2YWxpZGF0aW9uRXJyb3IuZXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBQYXJzZS5FcnJvcih2YWxpZGF0aW9uRXJyb3IuY29kZSwgdmFsaWRhdGlvbkVycm9yLmVycm9yKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QodmFsaWRhdGlvbkVycm9yKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fZGJBZGFwdGVyXG4gICAgICAuY3JlYXRlQ2xhc3MoXG4gICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgY29udmVydFNjaGVtYVRvQWRhcHRlclNjaGVtYSh7XG4gICAgICAgICAgZmllbGRzLFxuICAgICAgICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgICAgICBpbmRleGVzLFxuICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC50aGVuKGNvbnZlcnRBZGFwdGVyU2NoZW1hVG9QYXJzZVNjaGVtYSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvciAmJiBlcnJvci5jb2RlID09PSBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0NMQVNTX05BTUUsXG4gICAgICAgICAgICBgQ2xhc3MgJHtjbGFzc05hbWV9IGFscmVhZHkgZXhpc3RzLmBcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIHVwZGF0ZUNsYXNzKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHN1Ym1pdHRlZEZpZWxkczogU2NoZW1hRmllbGRzLFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogYW55LFxuICAgIGluZGV4ZXM6IGFueSxcbiAgICBkYXRhYmFzZTogRGF0YWJhc2VDb250cm9sbGVyXG4gICkge1xuICAgIHJldHVybiB0aGlzLmdldE9uZVNjaGVtYShjbGFzc05hbWUpXG4gICAgICAudGhlbihzY2hlbWEgPT4ge1xuICAgICAgICBjb25zdCBleGlzdGluZ0ZpZWxkcyA9IHNjaGVtYS5maWVsZHM7XG4gICAgICAgIE9iamVjdC5rZXlzKHN1Ym1pdHRlZEZpZWxkcykuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgICAgICBjb25zdCBmaWVsZCA9IHN1Ym1pdHRlZEZpZWxkc1tuYW1lXTtcbiAgICAgICAgICBpZiAoZXhpc3RpbmdGaWVsZHNbbmFtZV0gJiYgZmllbGQuX19vcCAhPT0gJ0RlbGV0ZScpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigyNTUsIGBGaWVsZCAke25hbWV9IGV4aXN0cywgY2Fubm90IHVwZGF0ZS5gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFleGlzdGluZ0ZpZWxkc1tuYW1lXSAmJiBmaWVsZC5fX29wID09PSAnRGVsZXRlJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDI1NSwgYEZpZWxkICR7bmFtZX0gZG9lcyBub3QgZXhpc3QsIGNhbm5vdCBkZWxldGUuYCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBkZWxldGUgZXhpc3RpbmdGaWVsZHMuX3JwZXJtO1xuICAgICAgICBkZWxldGUgZXhpc3RpbmdGaWVsZHMuX3dwZXJtO1xuICAgICAgICBjb25zdCBuZXdTY2hlbWEgPSBidWlsZE1lcmdlZFNjaGVtYU9iamVjdChleGlzdGluZ0ZpZWxkcywgc3VibWl0dGVkRmllbGRzKTtcbiAgICAgICAgY29uc3QgZGVmYXVsdEZpZWxkcyA9IGRlZmF1bHRDb2x1bW5zW2NsYXNzTmFtZV0gfHwgZGVmYXVsdENvbHVtbnMuX0RlZmF1bHQ7XG4gICAgICAgIGNvbnN0IGZ1bGxOZXdTY2hlbWEgPSBPYmplY3QuYXNzaWduKHt9LCBuZXdTY2hlbWEsIGRlZmF1bHRGaWVsZHMpO1xuICAgICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3IgPSB0aGlzLnZhbGlkYXRlU2NoZW1hRGF0YShcbiAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgbmV3U2NoZW1hLFxuICAgICAgICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgICAgICBPYmplY3Qua2V5cyhleGlzdGluZ0ZpZWxkcylcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHZhbGlkYXRpb25FcnJvcikge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcih2YWxpZGF0aW9uRXJyb3IuY29kZSwgdmFsaWRhdGlvbkVycm9yLmVycm9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZpbmFsbHkgd2UgaGF2ZSBjaGVja2VkIHRvIG1ha2Ugc3VyZSB0aGUgcmVxdWVzdCBpcyB2YWxpZCBhbmQgd2UgY2FuIHN0YXJ0IGRlbGV0aW5nIGZpZWxkcy5cbiAgICAgICAgLy8gRG8gYWxsIGRlbGV0aW9ucyBmaXJzdCwgdGhlbiBhIHNpbmdsZSBzYXZlIHRvIF9TQ0hFTUEgY29sbGVjdGlvbiB0byBoYW5kbGUgYWxsIGFkZGl0aW9ucy5cbiAgICAgICAgY29uc3QgZGVsZXRlZEZpZWxkczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgY29uc3QgaW5zZXJ0ZWRGaWVsZHMgPSBbXTtcbiAgICAgICAgT2JqZWN0LmtleXMoc3VibWl0dGVkRmllbGRzKS5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICAgICAgaWYgKHN1Ym1pdHRlZEZpZWxkc1tmaWVsZE5hbWVdLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgICAgICBkZWxldGVkRmllbGRzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaW5zZXJ0ZWRGaWVsZHMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgbGV0IGRlbGV0ZVByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgaWYgKGRlbGV0ZWRGaWVsZHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGRlbGV0ZVByb21pc2UgPSB0aGlzLmRlbGV0ZUZpZWxkcyhkZWxldGVkRmllbGRzLCBjbGFzc05hbWUsIGRhdGFiYXNlKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgZW5mb3JjZUZpZWxkcyA9IFtdO1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIGRlbGV0ZVByb21pc2UgLy8gRGVsZXRlIEV2ZXJ5dGhpbmdcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMucmVsb2FkRGF0YSh7IGNsZWFyQ2FjaGU6IHRydWUgfSkpIC8vIFJlbG9hZCBvdXIgU2NoZW1hLCBzbyB3ZSBoYXZlIGFsbCB0aGUgbmV3IHZhbHVlc1xuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IGluc2VydGVkRmllbGRzLm1hcChmaWVsZE5hbWUgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHR5cGUgPSBzdWJtaXR0ZWRGaWVsZHNbZmllbGROYW1lXTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbmZvcmNlRmllbGRFeGlzdHMoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHR5cGUpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgICAgICAgZW5mb3JjZUZpZWxkcyA9IHJlc3VsdHMuZmlsdGVyKHJlc3VsdCA9PiAhIXJlc3VsdCk7XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLnNldFBlcm1pc3Npb25zKGNsYXNzTmFtZSwgY2xhc3NMZXZlbFBlcm1pc3Npb25zLCBuZXdTY2hlbWEpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKCgpID0+XG4gICAgICAgICAgICAgIHRoaXMuX2RiQWRhcHRlci5zZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdChcbiAgICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgaW5kZXhlcyxcbiAgICAgICAgICAgICAgICBzY2hlbWEuaW5kZXhlcyxcbiAgICAgICAgICAgICAgICBmdWxsTmV3U2NoZW1hXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMucmVsb2FkRGF0YSh7IGNsZWFyQ2FjaGU6IHRydWUgfSkpXG4gICAgICAgICAgICAvL1RPRE86IE1vdmUgdGhpcyBsb2dpYyBpbnRvIHRoZSBkYXRhYmFzZSBhZGFwdGVyXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuZW5zdXJlRmllbGRzKGVuZm9yY2VGaWVsZHMpO1xuICAgICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB0aGlzLnNjaGVtYURhdGFbY2xhc3NOYW1lXTtcbiAgICAgICAgICAgICAgY29uc3QgcmVsb2FkZWRTY2hlbWE6IFNjaGVtYSA9IHtcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU6IGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICBmaWVsZHM6IHNjaGVtYS5maWVsZHMsXG4gICAgICAgICAgICAgICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiBzY2hlbWEuY2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICBpZiAoc2NoZW1hLmluZGV4ZXMgJiYgT2JqZWN0LmtleXMoc2NoZW1hLmluZGV4ZXMpLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgICAgIHJlbG9hZGVkU2NoZW1hLmluZGV4ZXMgPSBzY2hlbWEuaW5kZXhlcztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gcmVsb2FkZWRTY2hlbWE7XG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLFxuICAgICAgICAgICAgYENsYXNzICR7Y2xhc3NOYW1lfSBkb2VzIG5vdCBleGlzdC5gXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHN1Y2Nlc3NmdWxseSB0byB0aGUgbmV3IHNjaGVtYVxuICAvLyBvYmplY3Qgb3IgZmFpbHMgd2l0aCBhIHJlYXNvbi5cbiAgZW5mb3JjZUNsYXNzRXhpc3RzKGNsYXNzTmFtZTogc3RyaW5nKTogUHJvbWlzZTxTY2hlbWFDb250cm9sbGVyPiB7XG4gICAgaWYgKHRoaXMuc2NoZW1hRGF0YVtjbGFzc05hbWVdKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMpO1xuICAgIH1cbiAgICAvLyBXZSBkb24ndCBoYXZlIHRoaXMgY2xhc3MuIFVwZGF0ZSB0aGUgc2NoZW1hXG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuYWRkQ2xhc3NJZk5vdEV4aXN0cyhjbGFzc05hbWUpXG4gICAgICAgIC8vIFRoZSBzY2hlbWEgdXBkYXRlIHN1Y2NlZWRlZC4gUmVsb2FkIHRoZSBzY2hlbWFcbiAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5yZWxvYWREYXRhKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KSlcbiAgICAgICAgLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAvLyBUaGUgc2NoZW1hIHVwZGF0ZSBmYWlsZWQuIFRoaXMgY2FuIGJlIG9rYXkgLSBpdCBtaWdodFxuICAgICAgICAgIC8vIGhhdmUgZmFpbGVkIGJlY2F1c2UgdGhlcmUncyBhIHJhY2UgY29uZGl0aW9uIGFuZCBhIGRpZmZlcmVudFxuICAgICAgICAgIC8vIGNsaWVudCBpcyBtYWtpbmcgdGhlIGV4YWN0IHNhbWUgc2NoZW1hIHVwZGF0ZSB0aGF0IHdlIHdhbnQuXG4gICAgICAgICAgLy8gU28ganVzdCByZWxvYWQgdGhlIHNjaGVtYS5cbiAgICAgICAgICByZXR1cm4gdGhpcy5yZWxvYWREYXRhKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIC8vIEVuc3VyZSB0aGF0IHRoZSBzY2hlbWEgbm93IHZhbGlkYXRlc1xuICAgICAgICAgIGlmICh0aGlzLnNjaGVtYURhdGFbY2xhc3NOYW1lXSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sIGBGYWlsZWQgdG8gYWRkICR7Y2xhc3NOYW1lfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKCgpID0+IHtcbiAgICAgICAgICAvLyBUaGUgc2NoZW1hIHN0aWxsIGRvZXNuJ3QgdmFsaWRhdGUuIEdpdmUgdXBcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnc2NoZW1hIGNsYXNzIG5hbWUgZG9lcyBub3QgcmV2YWxpZGF0ZScpO1xuICAgICAgICB9KVxuICAgICk7XG4gIH1cblxuICB2YWxpZGF0ZU5ld0NsYXNzKGNsYXNzTmFtZTogc3RyaW5nLCBmaWVsZHM6IFNjaGVtYUZpZWxkcyA9IHt9LCBjbGFzc0xldmVsUGVybWlzc2lvbnM6IGFueSk6IGFueSB7XG4gICAgaWYgKHRoaXMuc2NoZW1hRGF0YVtjbGFzc05hbWVdKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLCBgQ2xhc3MgJHtjbGFzc05hbWV9IGFscmVhZHkgZXhpc3RzLmApO1xuICAgIH1cbiAgICBpZiAoIWNsYXNzTmFtZUlzVmFsaWQoY2xhc3NOYW1lKSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29kZTogUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLFxuICAgICAgICBlcnJvcjogaW52YWxpZENsYXNzTmFtZU1lc3NhZ2UoY2xhc3NOYW1lKSxcbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnZhbGlkYXRlU2NoZW1hRGF0YShjbGFzc05hbWUsIGZpZWxkcywgY2xhc3NMZXZlbFBlcm1pc3Npb25zLCBbXSk7XG4gIH1cblxuICB2YWxpZGF0ZVNjaGVtYURhdGEoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgZmllbGRzOiBTY2hlbWFGaWVsZHMsXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiBDbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gICAgZXhpc3RpbmdGaWVsZE5hbWVzOiBBcnJheTxzdHJpbmc+XG4gICkge1xuICAgIGZvciAoY29uc3QgZmllbGROYW1lIGluIGZpZWxkcykge1xuICAgICAgaWYgKGV4aXN0aW5nRmllbGROYW1lcy5pbmRleE9mKGZpZWxkTmFtZSkgPCAwKSB7XG4gICAgICAgIGlmICghZmllbGROYW1lSXNWYWxpZChmaWVsZE5hbWUsIGNsYXNzTmFtZSkpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29kZTogUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSxcbiAgICAgICAgICAgIGVycm9yOiAnaW52YWxpZCBmaWVsZCBuYW1lOiAnICsgZmllbGROYW1lLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFmaWVsZE5hbWVJc1ZhbGlkRm9yQ2xhc3MoZmllbGROYW1lLCBjbGFzc05hbWUpKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvZGU6IDEzNixcbiAgICAgICAgICAgIGVycm9yOiAnZmllbGQgJyArIGZpZWxkTmFtZSArICcgY2Fubm90IGJlIGFkZGVkJyxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGZpZWxkVHlwZSA9IGZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgICBjb25zdCBlcnJvciA9IGZpZWxkVHlwZUlzSW52YWxpZChmaWVsZFR5cGUpO1xuICAgICAgICBpZiAoZXJyb3IpIHJldHVybiB7IGNvZGU6IGVycm9yLmNvZGUsIGVycm9yOiBlcnJvci5tZXNzYWdlIH07XG4gICAgICAgIGlmIChmaWVsZFR5cGUuZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBsZXQgZGVmYXVsdFZhbHVlVHlwZSA9IGdldFR5cGUoZmllbGRUeXBlLmRlZmF1bHRWYWx1ZSk7XG4gICAgICAgICAgaWYgKHR5cGVvZiBkZWZhdWx0VmFsdWVUeXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgZGVmYXVsdFZhbHVlVHlwZSA9IHsgdHlwZTogZGVmYXVsdFZhbHVlVHlwZSB9O1xuICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGRlZmF1bHRWYWx1ZVR5cGUgPT09ICdvYmplY3QnICYmIGZpZWxkVHlwZS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBjb2RlOiBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSxcbiAgICAgICAgICAgICAgZXJyb3I6IGBUaGUgJ2RlZmF1bHQgdmFsdWUnIG9wdGlvbiBpcyBub3QgYXBwbGljYWJsZSBmb3IgJHt0eXBlVG9TdHJpbmcoZmllbGRUeXBlKX1gLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFkYlR5cGVNYXRjaGVzT2JqZWN0VHlwZShmaWVsZFR5cGUsIGRlZmF1bHRWYWx1ZVR5cGUpKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBjb2RlOiBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSxcbiAgICAgICAgICAgICAgZXJyb3I6IGBzY2hlbWEgbWlzbWF0Y2ggZm9yICR7Y2xhc3NOYW1lfS4ke2ZpZWxkTmFtZX0gZGVmYXVsdCB2YWx1ZTsgZXhwZWN0ZWQgJHt0eXBlVG9TdHJpbmcoXG4gICAgICAgICAgICAgICAgZmllbGRUeXBlXG4gICAgICAgICAgICAgICl9IGJ1dCBnb3QgJHt0eXBlVG9TdHJpbmcoZGVmYXVsdFZhbHVlVHlwZSl9YCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGZpZWxkVHlwZS5yZXF1aXJlZCkge1xuICAgICAgICAgIGlmICh0eXBlb2YgZmllbGRUeXBlID09PSAnb2JqZWN0JyAmJiBmaWVsZFR5cGUudHlwZSA9PT0gJ1JlbGF0aW9uJykge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgY29kZTogUGFyc2UuRXJyb3IuSU5DT1JSRUNUX1RZUEUsXG4gICAgICAgICAgICAgIGVycm9yOiBgVGhlICdyZXF1aXJlZCcgb3B0aW9uIGlzIG5vdCBhcHBsaWNhYmxlIGZvciAke3R5cGVUb1N0cmluZyhmaWVsZFR5cGUpfWAsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZmllbGROYW1lIGluIGRlZmF1bHRDb2x1bW5zW2NsYXNzTmFtZV0pIHtcbiAgICAgIGZpZWxkc1tmaWVsZE5hbWVdID0gZGVmYXVsdENvbHVtbnNbY2xhc3NOYW1lXVtmaWVsZE5hbWVdO1xuICAgIH1cblxuICAgIGNvbnN0IGdlb1BvaW50cyA9IE9iamVjdC5rZXlzKGZpZWxkcykuZmlsdGVyKFxuICAgICAga2V5ID0+IGZpZWxkc1trZXldICYmIGZpZWxkc1trZXldLnR5cGUgPT09ICdHZW9Qb2ludCdcbiAgICApO1xuICAgIGlmIChnZW9Qb2ludHMubGVuZ3RoID4gMSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29kZTogUGFyc2UuRXJyb3IuSU5DT1JSRUNUX1RZUEUsXG4gICAgICAgIGVycm9yOlxuICAgICAgICAgICdjdXJyZW50bHksIG9ubHkgb25lIEdlb1BvaW50IGZpZWxkIG1heSBleGlzdCBpbiBhbiBvYmplY3QuIEFkZGluZyAnICtcbiAgICAgICAgICBnZW9Qb2ludHNbMV0gK1xuICAgICAgICAgICcgd2hlbiAnICtcbiAgICAgICAgICBnZW9Qb2ludHNbMF0gK1xuICAgICAgICAgICcgYWxyZWFkeSBleGlzdHMuJyxcbiAgICAgIH07XG4gICAgfVxuICAgIHZhbGlkYXRlQ0xQKGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgZmllbGRzLCB0aGlzLnVzZXJJZFJlZ0V4KTtcbiAgfVxuXG4gIC8vIFNldHMgdGhlIENsYXNzLWxldmVsIHBlcm1pc3Npb25zIGZvciBhIGdpdmVuIGNsYXNzTmFtZSwgd2hpY2ggbXVzdCBleGlzdC5cbiAgc2V0UGVybWlzc2lvbnMoY2xhc3NOYW1lOiBzdHJpbmcsIHBlcm1zOiBhbnksIG5ld1NjaGVtYTogU2NoZW1hRmllbGRzKSB7XG4gICAgaWYgKHR5cGVvZiBwZXJtcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgdmFsaWRhdGVDTFAocGVybXMsIG5ld1NjaGVtYSwgdGhpcy51c2VySWRSZWdFeCk7XG4gICAgcmV0dXJuIHRoaXMuX2RiQWRhcHRlci5zZXRDbGFzc0xldmVsUGVybWlzc2lvbnMoY2xhc3NOYW1lLCBwZXJtcyk7XG4gIH1cblxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHN1Y2Nlc3NmdWxseSB0byB0aGUgbmV3IHNjaGVtYVxuICAvLyBvYmplY3QgaWYgdGhlIHByb3ZpZGVkIGNsYXNzTmFtZS1maWVsZE5hbWUtdHlwZSB0dXBsZSBpcyB2YWxpZC5cbiAgLy8gVGhlIGNsYXNzTmFtZSBtdXN0IGFscmVhZHkgYmUgdmFsaWRhdGVkLlxuICAvLyBJZiAnZnJlZXplJyBpcyB0cnVlLCByZWZ1c2UgdG8gdXBkYXRlIHRoZSBzY2hlbWEgZm9yIHRoaXMgZmllbGQuXG4gIGVuZm9yY2VGaWVsZEV4aXN0cyhjbGFzc05hbWU6IHN0cmluZywgZmllbGROYW1lOiBzdHJpbmcsIHR5cGU6IHN0cmluZyB8IFNjaGVtYUZpZWxkKSB7XG4gICAgaWYgKGZpZWxkTmFtZS5pbmRleE9mKCcuJykgPiAwKSB7XG4gICAgICAvLyBzdWJkb2N1bWVudCBrZXkgKHgueSkgPT4gb2sgaWYgeCBpcyBvZiB0eXBlICdvYmplY3QnXG4gICAgICBmaWVsZE5hbWUgPSBmaWVsZE5hbWUuc3BsaXQoJy4nKVswXTtcbiAgICAgIHR5cGUgPSAnT2JqZWN0JztcbiAgICB9XG4gICAgaWYgKCFmaWVsZE5hbWVJc1ZhbGlkKGZpZWxkTmFtZSwgY2xhc3NOYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUsIGBJbnZhbGlkIGZpZWxkIG5hbWU6ICR7ZmllbGROYW1lfS5gKTtcbiAgICB9XG5cbiAgICAvLyBJZiBzb21lb25lIHRyaWVzIHRvIGNyZWF0ZSBhIG5ldyBmaWVsZCB3aXRoIG51bGwvdW5kZWZpbmVkIGFzIHRoZSB2YWx1ZSwgcmV0dXJuO1xuICAgIGlmICghdHlwZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBleHBlY3RlZFR5cGUgPSB0aGlzLmdldEV4cGVjdGVkVHlwZShjbGFzc05hbWUsIGZpZWxkTmFtZSk7XG4gICAgaWYgKHR5cGVvZiB0eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgdHlwZSA9ICh7IHR5cGUgfTogU2NoZW1hRmllbGQpO1xuICAgIH1cblxuICAgIGlmICh0eXBlLmRlZmF1bHRWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBsZXQgZGVmYXVsdFZhbHVlVHlwZSA9IGdldFR5cGUodHlwZS5kZWZhdWx0VmFsdWUpO1xuICAgICAgaWYgKHR5cGVvZiBkZWZhdWx0VmFsdWVUeXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICBkZWZhdWx0VmFsdWVUeXBlID0geyB0eXBlOiBkZWZhdWx0VmFsdWVUeXBlIH07XG4gICAgICB9XG4gICAgICBpZiAoIWRiVHlwZU1hdGNoZXNPYmplY3RUeXBlKHR5cGUsIGRlZmF1bHRWYWx1ZVR5cGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSxcbiAgICAgICAgICBgc2NoZW1hIG1pc21hdGNoIGZvciAke2NsYXNzTmFtZX0uJHtmaWVsZE5hbWV9IGRlZmF1bHQgdmFsdWU7IGV4cGVjdGVkICR7dHlwZVRvU3RyaW5nKFxuICAgICAgICAgICAgdHlwZVxuICAgICAgICAgICl9IGJ1dCBnb3QgJHt0eXBlVG9TdHJpbmcoZGVmYXVsdFZhbHVlVHlwZSl9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChleHBlY3RlZFR5cGUpIHtcbiAgICAgIGlmICghZGJUeXBlTWF0Y2hlc09iamVjdFR5cGUoZXhwZWN0ZWRUeXBlLCB0eXBlKSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5DT1JSRUNUX1RZUEUsXG4gICAgICAgICAgYHNjaGVtYSBtaXNtYXRjaCBmb3IgJHtjbGFzc05hbWV9LiR7ZmllbGROYW1lfTsgZXhwZWN0ZWQgJHt0eXBlVG9TdHJpbmcoXG4gICAgICAgICAgICBleHBlY3RlZFR5cGVcbiAgICAgICAgICApfSBidXQgZ290ICR7dHlwZVRvU3RyaW5nKHR5cGUpfWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2RiQWRhcHRlclxuICAgICAgLmFkZEZpZWxkSWZOb3RFeGlzdHMoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHR5cGUpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PSBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSkge1xuICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHdlIHRocm93IGVycm9ycyB3aGVuIGl0IGlzIGFwcHJvcHJpYXRlIHRvIGRvIHNvLlxuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRoZSB1cGRhdGUgZmFpbGVkLiBUaGlzIGNhbiBiZSBva2F5IC0gaXQgbWlnaHQgaGF2ZSBiZWVuIGEgcmFjZVxuICAgICAgICAvLyBjb25kaXRpb24gd2hlcmUgYW5vdGhlciBjbGllbnQgdXBkYXRlZCB0aGUgc2NoZW1hIGluIHRoZSBzYW1lXG4gICAgICAgIC8vIHdheSB0aGF0IHdlIHdhbnRlZCB0by4gU28sIGp1c3QgcmVsb2FkIHRoZSBzY2hlbWFcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgZmllbGROYW1lLFxuICAgICAgICAgIHR5cGUsXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgfVxuXG4gIGVuc3VyZUZpZWxkcyhmaWVsZHM6IGFueSkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZmllbGRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCB7IGNsYXNzTmFtZSwgZmllbGROYW1lIH0gPSBmaWVsZHNbaV07XG4gICAgICBsZXQgeyB0eXBlIH0gPSBmaWVsZHNbaV07XG4gICAgICBjb25zdCBleHBlY3RlZFR5cGUgPSB0aGlzLmdldEV4cGVjdGVkVHlwZShjbGFzc05hbWUsIGZpZWxkTmFtZSk7XG4gICAgICBpZiAodHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHR5cGUgPSB7IHR5cGU6IHR5cGUgfTtcbiAgICAgIH1cbiAgICAgIGlmICghZXhwZWN0ZWRUeXBlIHx8ICFkYlR5cGVNYXRjaGVzT2JqZWN0VHlwZShleHBlY3RlZFR5cGUsIHR5cGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sIGBDb3VsZCBub3QgYWRkIGZpZWxkICR7ZmllbGROYW1lfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIG1haW50YWluIGNvbXBhdGliaWxpdHlcbiAgZGVsZXRlRmllbGQoZmllbGROYW1lOiBzdHJpbmcsIGNsYXNzTmFtZTogc3RyaW5nLCBkYXRhYmFzZTogRGF0YWJhc2VDb250cm9sbGVyKSB7XG4gICAgcmV0dXJuIHRoaXMuZGVsZXRlRmllbGRzKFtmaWVsZE5hbWVdLCBjbGFzc05hbWUsIGRhdGFiYXNlKTtcbiAgfVxuXG4gIC8vIERlbGV0ZSBmaWVsZHMsIGFuZCByZW1vdmUgdGhhdCBkYXRhIGZyb20gYWxsIG9iamVjdHMuIFRoaXMgaXMgaW50ZW5kZWRcbiAgLy8gdG8gcmVtb3ZlIHVudXNlZCBmaWVsZHMsIGlmIG90aGVyIHdyaXRlcnMgYXJlIHdyaXRpbmcgb2JqZWN0cyB0aGF0IGluY2x1ZGVcbiAgLy8gdGhpcyBmaWVsZCwgdGhlIGZpZWxkIG1heSByZWFwcGVhci4gUmV0dXJucyBhIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoXG4gIC8vIG5vIG9iamVjdCBvbiBzdWNjZXNzLCBvciByZWplY3RzIHdpdGggeyBjb2RlLCBlcnJvciB9IG9uIGZhaWx1cmUuXG4gIC8vIFBhc3NpbmcgdGhlIGRhdGFiYXNlIGFuZCBwcmVmaXggaXMgbmVjZXNzYXJ5IGluIG9yZGVyIHRvIGRyb3AgcmVsYXRpb24gY29sbGVjdGlvbnNcbiAgLy8gYW5kIHJlbW92ZSBmaWVsZHMgZnJvbSBvYmplY3RzLiBJZGVhbGx5IHRoZSBkYXRhYmFzZSB3b3VsZCBiZWxvbmcgdG9cbiAgLy8gYSBkYXRhYmFzZSBhZGFwdGVyIGFuZCB0aGlzIGZ1bmN0aW9uIHdvdWxkIGNsb3NlIG92ZXIgaXQgb3IgYWNjZXNzIGl0IHZpYSBtZW1iZXIuXG4gIGRlbGV0ZUZpZWxkcyhmaWVsZE5hbWVzOiBBcnJheTxzdHJpbmc+LCBjbGFzc05hbWU6IHN0cmluZywgZGF0YWJhc2U6IERhdGFiYXNlQ29udHJvbGxlcikge1xuICAgIGlmICghY2xhc3NOYW1lSXNWYWxpZChjbGFzc05hbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLCBpbnZhbGlkQ2xhc3NOYW1lTWVzc2FnZShjbGFzc05hbWUpKTtcbiAgICB9XG5cbiAgICBmaWVsZE5hbWVzLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgIGlmICghZmllbGROYW1lSXNWYWxpZChmaWVsZE5hbWUsIGNsYXNzTmFtZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUsIGBpbnZhbGlkIGZpZWxkIG5hbWU6ICR7ZmllbGROYW1lfWApO1xuICAgICAgfVxuICAgICAgLy9Eb24ndCBhbGxvdyBkZWxldGluZyB0aGUgZGVmYXVsdCBmaWVsZHMuXG4gICAgICBpZiAoIWZpZWxkTmFtZUlzVmFsaWRGb3JDbGFzcyhmaWVsZE5hbWUsIGNsYXNzTmFtZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDEzNiwgYGZpZWxkICR7ZmllbGROYW1lfSBjYW5ub3QgYmUgY2hhbmdlZGApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMuZ2V0T25lU2NoZW1hKGNsYXNzTmFtZSwgZmFsc2UsIHsgY2xlYXJDYWNoZTogdHJ1ZSB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0NMQVNTX05BTUUsXG4gICAgICAgICAgICBgQ2xhc3MgJHtjbGFzc05hbWV9IGRvZXMgbm90IGV4aXN0LmBcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLnRoZW4oc2NoZW1hID0+IHtcbiAgICAgICAgZmllbGROYW1lcy5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICAgICAgaWYgKCFzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigyNTUsIGBGaWVsZCAke2ZpZWxkTmFtZX0gZG9lcyBub3QgZXhpc3QsIGNhbm5vdCBkZWxldGUuYCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBzY2hlbWFGaWVsZHMgPSB7IC4uLnNjaGVtYS5maWVsZHMgfTtcbiAgICAgICAgcmV0dXJuIGRhdGFiYXNlLmFkYXB0ZXIuZGVsZXRlRmllbGRzKGNsYXNzTmFtZSwgc2NoZW1hLCBmaWVsZE5hbWVzKS50aGVuKCgpID0+IHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICBmaWVsZE5hbWVzLm1hcChmaWVsZE5hbWUgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBmaWVsZCA9IHNjaGVtYUZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgICAgICAgICBpZiAoZmllbGQgJiYgZmllbGQudHlwZSA9PT0gJ1JlbGF0aW9uJykge1xuICAgICAgICAgICAgICAgIC8vRm9yIHJlbGF0aW9ucywgZHJvcCB0aGUgX0pvaW4gdGFibGVcbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YWJhc2UuYWRhcHRlci5kZWxldGVDbGFzcyhgX0pvaW46JHtmaWVsZE5hbWV9OiR7Y2xhc3NOYW1lfWApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5fY2FjaGUuY2xlYXIoKSk7XG4gIH1cblxuICAvLyBWYWxpZGF0ZXMgYW4gb2JqZWN0IHByb3ZpZGVkIGluIFJFU1QgZm9ybWF0LlxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBuZXcgc2NoZW1hIGlmIHRoaXMgb2JqZWN0IGlzXG4gIC8vIHZhbGlkLlxuICBhc3luYyB2YWxpZGF0ZU9iamVjdChjbGFzc05hbWU6IHN0cmluZywgb2JqZWN0OiBhbnksIHF1ZXJ5OiBhbnkpIHtcbiAgICBsZXQgZ2VvY291bnQgPSAwO1xuICAgIGNvbnN0IHNjaGVtYSA9IGF3YWl0IHRoaXMuZW5mb3JjZUNsYXNzRXhpc3RzKGNsYXNzTmFtZSk7XG4gICAgY29uc3QgcHJvbWlzZXMgPSBbXTtcblxuICAgIGZvciAoY29uc3QgZmllbGROYW1lIGluIG9iamVjdCkge1xuICAgICAgaWYgKG9iamVjdFtmaWVsZE5hbWVdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBleHBlY3RlZCA9IGdldFR5cGUob2JqZWN0W2ZpZWxkTmFtZV0pO1xuICAgICAgaWYgKGV4cGVjdGVkID09PSAnR2VvUG9pbnQnKSB7XG4gICAgICAgIGdlb2NvdW50Kys7XG4gICAgICB9XG4gICAgICBpZiAoZ2VvY291bnQgPiAxKSB7XG4gICAgICAgIC8vIE1ha2Ugc3VyZSBhbGwgZmllbGQgdmFsaWRhdGlvbiBvcGVyYXRpb25zIHJ1biBiZWZvcmUgd2UgcmV0dXJuLlxuICAgICAgICAvLyBJZiBub3QgLSB3ZSBhcmUgY29udGludWluZyB0byBydW4gbG9naWMsIGJ1dCBhbHJlYWR5IHByb3ZpZGVkIHJlc3BvbnNlIGZyb20gdGhlIHNlcnZlci5cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KFxuICAgICAgICAgIG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLFxuICAgICAgICAgICAgJ3RoZXJlIGNhbiBvbmx5IGJlIG9uZSBnZW9wb2ludCBmaWVsZCBpbiBhIGNsYXNzJ1xuICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmICghZXhwZWN0ZWQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoZmllbGROYW1lID09PSAnQUNMJykge1xuICAgICAgICAvLyBFdmVyeSBvYmplY3QgaGFzIEFDTCBpbXBsaWNpdGx5LlxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHByb21pc2VzLnB1c2goc2NoZW1hLmVuZm9yY2VGaWVsZEV4aXN0cyhjbGFzc05hbWUsIGZpZWxkTmFtZSwgZXhwZWN0ZWQpKTtcbiAgICB9XG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICBjb25zdCBlbmZvcmNlRmllbGRzID0gcmVzdWx0cy5maWx0ZXIocmVzdWx0ID0+ICEhcmVzdWx0KTtcblxuICAgIGlmIChlbmZvcmNlRmllbGRzLmxlbmd0aCAhPT0gMCkge1xuICAgICAgYXdhaXQgdGhpcy5yZWxvYWREYXRhKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KTtcbiAgICB9XG4gICAgdGhpcy5lbnN1cmVGaWVsZHMoZW5mb3JjZUZpZWxkcyk7XG5cbiAgICBjb25zdCBwcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKHNjaGVtYSk7XG4gICAgcmV0dXJuIHRoZW5WYWxpZGF0ZVJlcXVpcmVkQ29sdW1ucyhwcm9taXNlLCBjbGFzc05hbWUsIG9iamVjdCwgcXVlcnkpO1xuICB9XG5cbiAgLy8gVmFsaWRhdGVzIHRoYXQgYWxsIHRoZSBwcm9wZXJ0aWVzIGFyZSBzZXQgZm9yIHRoZSBvYmplY3RcbiAgdmFsaWRhdGVSZXF1aXJlZENvbHVtbnMoY2xhc3NOYW1lOiBzdHJpbmcsIG9iamVjdDogYW55LCBxdWVyeTogYW55KSB7XG4gICAgY29uc3QgY29sdW1ucyA9IHJlcXVpcmVkQ29sdW1uc1tjbGFzc05hbWVdO1xuICAgIGlmICghY29sdW1ucyB8fCBjb2x1bW5zLmxlbmd0aCA9PSAwKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMpO1xuICAgIH1cblxuICAgIGNvbnN0IG1pc3NpbmdDb2x1bW5zID0gY29sdW1ucy5maWx0ZXIoZnVuY3Rpb24gKGNvbHVtbikge1xuICAgICAgaWYgKHF1ZXJ5ICYmIHF1ZXJ5Lm9iamVjdElkKSB7XG4gICAgICAgIGlmIChvYmplY3RbY29sdW1uXSAmJiB0eXBlb2Ygb2JqZWN0W2NvbHVtbl0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgLy8gVHJ5aW5nIHRvIGRlbGV0ZSBhIHJlcXVpcmVkIGNvbHVtblxuICAgICAgICAgIHJldHVybiBvYmplY3RbY29sdW1uXS5fX29wID09ICdEZWxldGUnO1xuICAgICAgICB9XG4gICAgICAgIC8vIE5vdCB0cnlpbmcgdG8gZG8gYW55dGhpbmcgdGhlcmVcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuICFvYmplY3RbY29sdW1uXTtcbiAgICB9KTtcblxuICAgIGlmIChtaXNzaW5nQ29sdW1ucy5sZW5ndGggPiAwKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5DT1JSRUNUX1RZUEUsIG1pc3NpbmdDb2x1bW5zWzBdICsgJyBpcyByZXF1aXJlZC4nKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzKTtcbiAgfVxuXG4gIHRlc3RQZXJtaXNzaW9uc0ZvckNsYXNzTmFtZShjbGFzc05hbWU6IHN0cmluZywgYWNsR3JvdXA6IHN0cmluZ1tdLCBvcGVyYXRpb246IHN0cmluZykge1xuICAgIHJldHVybiBTY2hlbWFDb250cm9sbGVyLnRlc3RQZXJtaXNzaW9ucyhcbiAgICAgIHRoaXMuZ2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zKGNsYXNzTmFtZSksXG4gICAgICBhY2xHcm91cCxcbiAgICAgIG9wZXJhdGlvblxuICAgICk7XG4gIH1cblxuICAvLyBUZXN0cyB0aGF0IHRoZSBjbGFzcyBsZXZlbCBwZXJtaXNzaW9uIGxldCBwYXNzIHRoZSBvcGVyYXRpb24gZm9yIGEgZ2l2ZW4gYWNsR3JvdXBcbiAgc3RhdGljIHRlc3RQZXJtaXNzaW9ucyhjbGFzc1Blcm1pc3Npb25zOiA/YW55LCBhY2xHcm91cDogc3RyaW5nW10sIG9wZXJhdGlvbjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKCFjbGFzc1Blcm1pc3Npb25zIHx8ICFjbGFzc1Blcm1pc3Npb25zW29wZXJhdGlvbl0pIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjb25zdCBwZXJtcyA9IGNsYXNzUGVybWlzc2lvbnNbb3BlcmF0aW9uXTtcbiAgICBpZiAocGVybXNbJyonXSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8vIENoZWNrIHBlcm1pc3Npb25zIGFnYWluc3QgdGhlIGFjbEdyb3VwIHByb3ZpZGVkIChhcnJheSBvZiB1c2VySWQvcm9sZXMpXG4gICAgaWYgKFxuICAgICAgYWNsR3JvdXAuc29tZShhY2wgPT4ge1xuICAgICAgICByZXR1cm4gcGVybXNbYWNsXSA9PT0gdHJ1ZTtcbiAgICAgIH0pXG4gICAgKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gVmFsaWRhdGVzIGFuIG9wZXJhdGlvbiBwYXNzZXMgY2xhc3MtbGV2ZWwtcGVybWlzc2lvbnMgc2V0IGluIHRoZSBzY2hlbWFcbiAgc3RhdGljIHZhbGlkYXRlUGVybWlzc2lvbihcbiAgICBjbGFzc1Blcm1pc3Npb25zOiA/YW55LFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIGFjbEdyb3VwOiBzdHJpbmdbXSxcbiAgICBvcGVyYXRpb246IHN0cmluZyxcbiAgICBhY3Rpb24/OiBzdHJpbmdcbiAgKSB7XG4gICAgaWYgKFNjaGVtYUNvbnRyb2xsZXIudGVzdFBlcm1pc3Npb25zKGNsYXNzUGVybWlzc2lvbnMsIGFjbEdyb3VwLCBvcGVyYXRpb24pKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuXG4gICAgaWYgKCFjbGFzc1Blcm1pc3Npb25zIHx8ICFjbGFzc1Blcm1pc3Npb25zW29wZXJhdGlvbl0pIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjb25zdCBwZXJtcyA9IGNsYXNzUGVybWlzc2lvbnNbb3BlcmF0aW9uXTtcbiAgICAvLyBJZiBvbmx5IGZvciBhdXRoZW50aWNhdGVkIHVzZXJzXG4gICAgLy8gbWFrZSBzdXJlIHdlIGhhdmUgYW4gYWNsR3JvdXBcbiAgICBpZiAocGVybXNbJ3JlcXVpcmVzQXV0aGVudGljYXRpb24nXSkge1xuICAgICAgLy8gSWYgYWNsR3JvdXAgaGFzICogKHB1YmxpYylcbiAgICAgIGlmICghYWNsR3JvdXAgfHwgYWNsR3JvdXAubGVuZ3RoID09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICAgJ1Blcm1pc3Npb24gZGVuaWVkLCB1c2VyIG5lZWRzIHRvIGJlIGF1dGhlbnRpY2F0ZWQuJ1xuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmIChhY2xHcm91cC5pbmRleE9mKCcqJykgPiAtMSAmJiBhY2xHcm91cC5sZW5ndGggPT0gMSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICAgICAnUGVybWlzc2lvbiBkZW5pZWQsIHVzZXIgbmVlZHMgdG8gYmUgYXV0aGVudGljYXRlZC4nXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICAvLyByZXF1aXJlc0F1dGhlbnRpY2F0aW9uIHBhc3NlZCwganVzdCBtb3ZlIGZvcndhcmRcbiAgICAgIC8vIHByb2JhYmx5IHdvdWxkIGJlIHdpc2UgYXQgc29tZSBwb2ludCB0byByZW5hbWUgdG8gJ2F1dGhlbnRpY2F0ZWRVc2VyJ1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIC8vIE5vIG1hdGNoaW5nIENMUCwgbGV0J3MgY2hlY2sgdGhlIFBvaW50ZXIgcGVybWlzc2lvbnNcbiAgICAvLyBBbmQgaGFuZGxlIHRob3NlIGxhdGVyXG4gICAgY29uc3QgcGVybWlzc2lvbkZpZWxkID1cbiAgICAgIFsnZ2V0JywgJ2ZpbmQnLCAnY291bnQnXS5pbmRleE9mKG9wZXJhdGlvbikgPiAtMSA/ICdyZWFkVXNlckZpZWxkcycgOiAnd3JpdGVVc2VyRmllbGRzJztcblxuICAgIC8vIFJlamVjdCBjcmVhdGUgd2hlbiB3cml0ZSBsb2NrZG93blxuICAgIGlmIChwZXJtaXNzaW9uRmllbGQgPT0gJ3dyaXRlVXNlckZpZWxkcycgJiYgb3BlcmF0aW9uID09ICdjcmVhdGUnKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sXG4gICAgICAgIGBQZXJtaXNzaW9uIGRlbmllZCBmb3IgYWN0aW9uICR7b3BlcmF0aW9ufSBvbiBjbGFzcyAke2NsYXNzTmFtZX0uYFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBQcm9jZXNzIHRoZSByZWFkVXNlckZpZWxkcyBsYXRlclxuICAgIGlmIChcbiAgICAgIEFycmF5LmlzQXJyYXkoY2xhc3NQZXJtaXNzaW9uc1twZXJtaXNzaW9uRmllbGRdKSAmJlxuICAgICAgY2xhc3NQZXJtaXNzaW9uc1twZXJtaXNzaW9uRmllbGRdLmxlbmd0aCA+IDBcbiAgICApIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG5cbiAgICBjb25zdCBwb2ludGVyRmllbGRzID0gY2xhc3NQZXJtaXNzaW9uc1tvcGVyYXRpb25dLnBvaW50ZXJGaWVsZHM7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocG9pbnRlckZpZWxkcykgJiYgcG9pbnRlckZpZWxkcy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBhbnkgb3AgZXhjZXB0ICdhZGRGaWVsZCBhcyBwYXJ0IG9mIGNyZWF0ZScgaXMgb2suXG4gICAgICBpZiAob3BlcmF0aW9uICE9PSAnYWRkRmllbGQnIHx8IGFjdGlvbiA9PT0gJ3VwZGF0ZScpIHtcbiAgICAgICAgLy8gV2UgY2FuIGFsbG93IGFkZGluZyBmaWVsZCBvbiB1cGRhdGUgZmxvdyBvbmx5LlxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgIGBQZXJtaXNzaW9uIGRlbmllZCBmb3IgYWN0aW9uICR7b3BlcmF0aW9ufSBvbiBjbGFzcyAke2NsYXNzTmFtZX0uYFxuICAgICk7XG4gIH1cblxuICAvLyBWYWxpZGF0ZXMgYW4gb3BlcmF0aW9uIHBhc3NlcyBjbGFzcy1sZXZlbC1wZXJtaXNzaW9ucyBzZXQgaW4gdGhlIHNjaGVtYVxuICB2YWxpZGF0ZVBlcm1pc3Npb24oY2xhc3NOYW1lOiBzdHJpbmcsIGFjbEdyb3VwOiBzdHJpbmdbXSwgb3BlcmF0aW9uOiBzdHJpbmcsIGFjdGlvbj86IHN0cmluZykge1xuICAgIHJldHVybiBTY2hlbWFDb250cm9sbGVyLnZhbGlkYXRlUGVybWlzc2lvbihcbiAgICAgIHRoaXMuZ2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zKGNsYXNzTmFtZSksXG4gICAgICBjbGFzc05hbWUsXG4gICAgICBhY2xHcm91cCxcbiAgICAgIG9wZXJhdGlvbixcbiAgICAgIGFjdGlvblxuICAgICk7XG4gIH1cblxuICBnZXRDbGFzc0xldmVsUGVybWlzc2lvbnMoY2xhc3NOYW1lOiBzdHJpbmcpOiBhbnkge1xuICAgIHJldHVybiB0aGlzLnNjaGVtYURhdGFbY2xhc3NOYW1lXSAmJiB0aGlzLnNjaGVtYURhdGFbY2xhc3NOYW1lXS5jbGFzc0xldmVsUGVybWlzc2lvbnM7XG4gIH1cblxuICAvLyBSZXR1cm5zIHRoZSBleHBlY3RlZCB0eXBlIGZvciBhIGNsYXNzTmFtZStrZXkgY29tYmluYXRpb25cbiAgLy8gb3IgdW5kZWZpbmVkIGlmIHRoZSBzY2hlbWEgaXMgbm90IHNldFxuICBnZXRFeHBlY3RlZFR5cGUoY2xhc3NOYW1lOiBzdHJpbmcsIGZpZWxkTmFtZTogc3RyaW5nKTogPyhTY2hlbWFGaWVsZCB8IHN0cmluZykge1xuICAgIGlmICh0aGlzLnNjaGVtYURhdGFbY2xhc3NOYW1lXSkge1xuICAgICAgY29uc3QgZXhwZWN0ZWRUeXBlID0gdGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV0uZmllbGRzW2ZpZWxkTmFtZV07XG4gICAgICByZXR1cm4gZXhwZWN0ZWRUeXBlID09PSAnbWFwJyA/ICdPYmplY3QnIDogZXhwZWN0ZWRUeXBlO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLy8gQ2hlY2tzIGlmIGEgZ2l2ZW4gY2xhc3MgaXMgaW4gdGhlIHNjaGVtYS5cbiAgaGFzQ2xhc3MoY2xhc3NOYW1lOiBzdHJpbmcpIHtcbiAgICBpZiAodGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV0pIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodHJ1ZSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnJlbG9hZERhdGEoKS50aGVuKCgpID0+ICEhdGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV0pO1xuICB9XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIGZvciBhIG5ldyBTY2hlbWEuXG5jb25zdCBsb2FkID0gKFxuICBkYkFkYXB0ZXI6IFN0b3JhZ2VBZGFwdGVyLFxuICBzY2hlbWFDYWNoZTogYW55LFxuICBvcHRpb25zOiBhbnlcbik6IFByb21pc2U8U2NoZW1hQ29udHJvbGxlcj4gPT4ge1xuICBjb25zdCBzY2hlbWEgPSBuZXcgU2NoZW1hQ29udHJvbGxlcihkYkFkYXB0ZXIsIHNjaGVtYUNhY2hlKTtcbiAgcmV0dXJuIHNjaGVtYS5yZWxvYWREYXRhKG9wdGlvbnMpLnRoZW4oKCkgPT4gc2NoZW1hKTtcbn07XG5cbi8vIEJ1aWxkcyBhIG5ldyBzY2hlbWEgKGluIHNjaGVtYSBBUEkgcmVzcG9uc2UgZm9ybWF0KSBvdXQgb2YgYW5cbi8vIGV4aXN0aW5nIG1vbmdvIHNjaGVtYSArIGEgc2NoZW1hcyBBUEkgcHV0IHJlcXVlc3QuIFRoaXMgcmVzcG9uc2Vcbi8vIGRvZXMgbm90IGluY2x1ZGUgdGhlIGRlZmF1bHQgZmllbGRzLCBhcyBpdCBpcyBpbnRlbmRlZCB0byBiZSBwYXNzZWRcbi8vIHRvIG1vbmdvU2NoZW1hRnJvbUZpZWxkc0FuZENsYXNzTmFtZS4gTm8gdmFsaWRhdGlvbiBpcyBkb25lIGhlcmUsIGl0XG4vLyBpcyBkb25lIGluIG1vbmdvU2NoZW1hRnJvbUZpZWxkc0FuZENsYXNzTmFtZS5cbmZ1bmN0aW9uIGJ1aWxkTWVyZ2VkU2NoZW1hT2JqZWN0KGV4aXN0aW5nRmllbGRzOiBTY2hlbWFGaWVsZHMsIHB1dFJlcXVlc3Q6IGFueSk6IFNjaGVtYUZpZWxkcyB7XG4gIGNvbnN0IG5ld1NjaGVtYSA9IHt9O1xuICAvLyBAZmxvdy1kaXNhYmxlLW5leHRcbiAgY29uc3Qgc3lzU2NoZW1hRmllbGQgPVxuICAgIE9iamVjdC5rZXlzKGRlZmF1bHRDb2x1bW5zKS5pbmRleE9mKGV4aXN0aW5nRmllbGRzLl9pZCkgPT09IC0xXG4gICAgICA/IFtdXG4gICAgICA6IE9iamVjdC5rZXlzKGRlZmF1bHRDb2x1bW5zW2V4aXN0aW5nRmllbGRzLl9pZF0pO1xuICBmb3IgKGNvbnN0IG9sZEZpZWxkIGluIGV4aXN0aW5nRmllbGRzKSB7XG4gICAgaWYgKFxuICAgICAgb2xkRmllbGQgIT09ICdfaWQnICYmXG4gICAgICBvbGRGaWVsZCAhPT0gJ0FDTCcgJiZcbiAgICAgIG9sZEZpZWxkICE9PSAndXBkYXRlZEF0JyAmJlxuICAgICAgb2xkRmllbGQgIT09ICdjcmVhdGVkQXQnICYmXG4gICAgICBvbGRGaWVsZCAhPT0gJ29iamVjdElkJ1xuICAgICkge1xuICAgICAgaWYgKHN5c1NjaGVtYUZpZWxkLmxlbmd0aCA+IDAgJiYgc3lzU2NoZW1hRmllbGQuaW5kZXhPZihvbGRGaWVsZCkgIT09IC0xKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgZmllbGRJc0RlbGV0ZWQgPSBwdXRSZXF1ZXN0W29sZEZpZWxkXSAmJiBwdXRSZXF1ZXN0W29sZEZpZWxkXS5fX29wID09PSAnRGVsZXRlJztcbiAgICAgIGlmICghZmllbGRJc0RlbGV0ZWQpIHtcbiAgICAgICAgbmV3U2NoZW1hW29sZEZpZWxkXSA9IGV4aXN0aW5nRmllbGRzW29sZEZpZWxkXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZm9yIChjb25zdCBuZXdGaWVsZCBpbiBwdXRSZXF1ZXN0KSB7XG4gICAgaWYgKG5ld0ZpZWxkICE9PSAnb2JqZWN0SWQnICYmIHB1dFJlcXVlc3RbbmV3RmllbGRdLl9fb3AgIT09ICdEZWxldGUnKSB7XG4gICAgICBpZiAoc3lzU2NoZW1hRmllbGQubGVuZ3RoID4gMCAmJiBzeXNTY2hlbWFGaWVsZC5pbmRleE9mKG5ld0ZpZWxkKSAhPT0gLTEpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBuZXdTY2hlbWFbbmV3RmllbGRdID0gcHV0UmVxdWVzdFtuZXdGaWVsZF07XG4gICAgfVxuICB9XG4gIHJldHVybiBuZXdTY2hlbWE7XG59XG5cbi8vIEdpdmVuIGEgc2NoZW1hIHByb21pc2UsIGNvbnN0cnVjdCBhbm90aGVyIHNjaGVtYSBwcm9taXNlIHRoYXRcbi8vIHZhbGlkYXRlcyB0aGlzIGZpZWxkIG9uY2UgdGhlIHNjaGVtYSBsb2Fkcy5cbmZ1bmN0aW9uIHRoZW5WYWxpZGF0ZVJlcXVpcmVkQ29sdW1ucyhzY2hlbWFQcm9taXNlLCBjbGFzc05hbWUsIG9iamVjdCwgcXVlcnkpIHtcbiAgcmV0dXJuIHNjaGVtYVByb21pc2UudGhlbihzY2hlbWEgPT4ge1xuICAgIHJldHVybiBzY2hlbWEudmFsaWRhdGVSZXF1aXJlZENvbHVtbnMoY2xhc3NOYW1lLCBvYmplY3QsIHF1ZXJ5KTtcbiAgfSk7XG59XG5cbi8vIEdldHMgdGhlIHR5cGUgZnJvbSBhIFJFU1QgQVBJIGZvcm1hdHRlZCBvYmplY3QsIHdoZXJlICd0eXBlJyBpc1xuLy8gZXh0ZW5kZWQgcGFzdCBqYXZhc2NyaXB0IHR5cGVzIHRvIGluY2x1ZGUgdGhlIHJlc3Qgb2YgdGhlIFBhcnNlXG4vLyB0eXBlIHN5c3RlbS5cbi8vIFRoZSBvdXRwdXQgc2hvdWxkIGJlIGEgdmFsaWQgc2NoZW1hIHZhbHVlLlxuLy8gVE9ETzogZW5zdXJlIHRoYXQgdGhpcyBpcyBjb21wYXRpYmxlIHdpdGggdGhlIGZvcm1hdCB1c2VkIGluIE9wZW4gREJcbmZ1bmN0aW9uIGdldFR5cGUob2JqOiBhbnkpOiA/KFNjaGVtYUZpZWxkIHwgc3RyaW5nKSB7XG4gIGNvbnN0IHR5cGUgPSB0eXBlb2Ygb2JqO1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdib29sZWFuJzpcbiAgICAgIHJldHVybiAnQm9vbGVhbic7XG4gICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgIHJldHVybiAnU3RyaW5nJztcbiAgICBjYXNlICdudW1iZXInOlxuICAgICAgcmV0dXJuICdOdW1iZXInO1xuICAgIGNhc2UgJ21hcCc6XG4gICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgIGlmICghb2JqKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gZ2V0T2JqZWN0VHlwZShvYmopO1xuICAgIGNhc2UgJ2Z1bmN0aW9uJzpcbiAgICBjYXNlICdzeW1ib2wnOlxuICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93ICdiYWQgb2JqOiAnICsgb2JqO1xuICB9XG59XG5cbi8vIFRoaXMgZ2V0cyB0aGUgdHlwZSBmb3Igbm9uLUpTT04gdHlwZXMgbGlrZSBwb2ludGVycyBhbmQgZmlsZXMsIGJ1dFxuLy8gYWxzbyBnZXRzIHRoZSBhcHByb3ByaWF0ZSB0eXBlIGZvciAkIG9wZXJhdG9ycy5cbi8vIFJldHVybnMgbnVsbCBpZiB0aGUgdHlwZSBpcyB1bmtub3duLlxuZnVuY3Rpb24gZ2V0T2JqZWN0VHlwZShvYmopOiA/KFNjaGVtYUZpZWxkIHwgc3RyaW5nKSB7XG4gIGlmIChvYmogaW5zdGFuY2VvZiBBcnJheSkge1xuICAgIHJldHVybiAnQXJyYXknO1xuICB9XG4gIGlmIChvYmouX190eXBlKSB7XG4gICAgc3dpdGNoIChvYmouX190eXBlKSB7XG4gICAgICBjYXNlICdQb2ludGVyJzpcbiAgICAgICAgaWYgKG9iai5jbGFzc05hbWUpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICAgICAgdGFyZ2V0Q2xhc3M6IG9iai5jbGFzc05hbWUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ1JlbGF0aW9uJzpcbiAgICAgICAgaWYgKG9iai5jbGFzc05hbWUpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ1JlbGF0aW9uJyxcbiAgICAgICAgICAgIHRhcmdldENsYXNzOiBvYmouY2xhc3NOYW1lLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdGaWxlJzpcbiAgICAgICAgaWYgKG9iai5uYW1lKSB7XG4gICAgICAgICAgcmV0dXJuICdGaWxlJztcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0RhdGUnOlxuICAgICAgICBpZiAob2JqLmlzbykge1xuICAgICAgICAgIHJldHVybiAnRGF0ZSc7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdHZW9Qb2ludCc6XG4gICAgICAgIGlmIChvYmoubGF0aXR1ZGUgIT0gbnVsbCAmJiBvYmoubG9uZ2l0dWRlICE9IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gJ0dlb1BvaW50JztcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0J5dGVzJzpcbiAgICAgICAgaWYgKG9iai5iYXNlNjQpIHtcbiAgICAgICAgICByZXR1cm4gJ0J5dGVzJztcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ1BvbHlnb24nOlxuICAgICAgICBpZiAob2JqLmNvb3JkaW5hdGVzKSB7XG4gICAgICAgICAgcmV0dXJuICdQb2x5Z29uJztcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLCAnVGhpcyBpcyBub3QgYSB2YWxpZCAnICsgb2JqLl9fdHlwZSk7XG4gIH1cbiAgaWYgKG9ialsnJG5lJ10pIHtcbiAgICByZXR1cm4gZ2V0T2JqZWN0VHlwZShvYmpbJyRuZSddKTtcbiAgfVxuICBpZiAob2JqLl9fb3ApIHtcbiAgICBzd2l0Y2ggKG9iai5fX29wKSB7XG4gICAgICBjYXNlICdJbmNyZW1lbnQnOlxuICAgICAgICByZXR1cm4gJ051bWJlcic7XG4gICAgICBjYXNlICdEZWxldGUnOlxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIGNhc2UgJ0FkZCc6XG4gICAgICBjYXNlICdBZGRVbmlxdWUnOlxuICAgICAgY2FzZSAnUmVtb3ZlJzpcbiAgICAgICAgcmV0dXJuICdBcnJheSc7XG4gICAgICBjYXNlICdBZGRSZWxhdGlvbic6XG4gICAgICBjYXNlICdSZW1vdmVSZWxhdGlvbic6XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdHlwZTogJ1JlbGF0aW9uJyxcbiAgICAgICAgICB0YXJnZXRDbGFzczogb2JqLm9iamVjdHNbMF0uY2xhc3NOYW1lLFxuICAgICAgICB9O1xuICAgICAgY2FzZSAnQmF0Y2gnOlxuICAgICAgICByZXR1cm4gZ2V0T2JqZWN0VHlwZShvYmoub3BzWzBdKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93ICd1bmV4cGVjdGVkIG9wOiAnICsgb2JqLl9fb3A7XG4gICAgfVxuICB9XG4gIHJldHVybiAnT2JqZWN0Jztcbn1cblxuZXhwb3J0IHtcbiAgbG9hZCxcbiAgY2xhc3NOYW1lSXNWYWxpZCxcbiAgZmllbGROYW1lSXNWYWxpZCxcbiAgaW52YWxpZENsYXNzTmFtZU1lc3NhZ2UsXG4gIGJ1aWxkTWVyZ2VkU2NoZW1hT2JqZWN0LFxuICBzeXN0ZW1DbGFzc2VzLFxuICBkZWZhdWx0Q29sdW1ucyxcbiAgY29udmVydFNjaGVtYVRvQWRhcHRlclNjaGVtYSxcbiAgVm9sYXRpbGVDbGFzc2VzU2NoZW1hcyxcbiAgU2NoZW1hQ29udHJvbGxlcixcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Controllers/UserController.js b/lib/Controllers/UserController.js deleted file mode 100644 index b327209870..0000000000 --- a/lib/Controllers/UserController.js +++ /dev/null @@ -1,375 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.UserController = void 0; - -var _cryptoUtils = require("../cryptoUtils"); - -var _triggers = require("../triggers"); - -var _AdaptableController = _interopRequireDefault(require("./AdaptableController")); - -var _MailAdapter = _interopRequireDefault(require("../Adapters/Email/MailAdapter")); - -var _rest = _interopRequireDefault(require("../rest")); - -var _node = _interopRequireDefault(require("parse/node")); - -var _AccountLockout = _interopRequireDefault(require("../AccountLockout")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var RestQuery = require('../RestQuery'); - -var Auth = require('../Auth'); - -class UserController extends _AdaptableController.default { - constructor(adapter, appId, options = {}) { - super(adapter, appId, options); - } - - validateAdapter(adapter) { - // Allow no adapter - if (!adapter && !this.shouldVerifyEmails) { - return; - } - - super.validateAdapter(adapter); - } - - expectedAdapterType() { - return _MailAdapter.default; - } - - get shouldVerifyEmails() { - return this.options.verifyUserEmails; - } - - setEmailVerifyToken(user) { - if (this.shouldVerifyEmails) { - user._email_verify_token = (0, _cryptoUtils.randomString)(25); - user.emailVerified = false; - - if (this.config.emailVerifyTokenValidityDuration) { - user._email_verify_token_expires_at = _node.default._encode(this.config.generateEmailVerifyTokenExpiresAt()); - } - } - } - - verifyEmail(username, token) { - if (!this.shouldVerifyEmails) { - // Trying to verify email when not enabled - // TODO: Better error here. - throw undefined; - } - - const query = { - username: username, - _email_verify_token: token - }; - const updateFields = { - emailVerified: true, - _email_verify_token: { - __op: 'Delete' - } - }; // if the email verify token needs to be validated then - // add additional query params and additional fields that need to be updated - - if (this.config.emailVerifyTokenValidityDuration) { - query.emailVerified = false; - query._email_verify_token_expires_at = { - $gt: _node.default._encode(new Date()) - }; - updateFields._email_verify_token_expires_at = { - __op: 'Delete' - }; - } - - const masterAuth = Auth.master(this.config); - var findUserForEmailVerification = new RestQuery(this.config, Auth.master(this.config), '_User', { - username: username - }); - return findUserForEmailVerification.execute().then(result => { - if (result.results.length && result.results[0].emailVerified) { - return Promise.resolve(result.results.length[0]); - } else if (result.results.length) { - query.objectId = result.results[0].objectId; - } - - return _rest.default.update(this.config, masterAuth, '_User', query, updateFields); - }); - } - - checkResetTokenValidity(username, token) { - return this.config.database.find('_User', { - username: username, - _perishable_token: token - }, { - limit: 1 - }).then(results => { - if (results.length != 1) { - throw 'Failed to reset password: username / email / token is invalid'; - } - - if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenValidityDuration) { - let expiresDate = results[0]._perishable_token_expires_at; - - if (expiresDate && expiresDate.__type == 'Date') { - expiresDate = new Date(expiresDate.iso); - } - - if (expiresDate < new Date()) throw 'The password reset link has expired'; - } - - return results[0]; - }); - } - - getUserIfNeeded(user) { - if (user.username && user.email) { - return Promise.resolve(user); - } - - var where = {}; - - if (user.username) { - where.username = user.username; - } - - if (user.email) { - where.email = user.email; - } - - var query = new RestQuery(this.config, Auth.master(this.config), '_User', where); - return query.execute().then(function (result) { - if (result.results.length != 1) { - throw undefined; - } - - return result.results[0]; - }); - } - - sendVerificationEmail(user) { - if (!this.shouldVerifyEmails) { - return; - } - - const token = encodeURIComponent(user._email_verify_token); // We may need to fetch the user in case of update email - - this.getUserIfNeeded(user).then(user => { - const username = encodeURIComponent(user.username); - const link = buildEmailLink(this.config.verifyEmailURL, username, token, this.config); - const options = { - appName: this.config.appName, - link: link, - user: (0, _triggers.inflate)('_User', user) - }; - - if (this.adapter.sendVerificationEmail) { - this.adapter.sendVerificationEmail(options); - } else { - this.adapter.sendMail(this.defaultVerificationEmail(options)); - } - }); - } - /** - * Regenerates the given user's email verification token - * - * @param user - * @returns {*} - */ - - - regenerateEmailVerifyToken(user) { - const { - _email_verify_token - } = user; - let { - _email_verify_token_expires_at - } = user; - - if (_email_verify_token_expires_at && _email_verify_token_expires_at.__type === 'Date') { - _email_verify_token_expires_at = _email_verify_token_expires_at.iso; - } - - if (this.config.emailVerifyTokenReuseIfValid && this.config.emailVerifyTokenValidityDuration && _email_verify_token && new Date() < new Date(_email_verify_token_expires_at)) { - return Promise.resolve(); - } - - this.setEmailVerifyToken(user); - return this.config.database.update('_User', { - username: user.username - }, user); - } - - resendVerificationEmail(username) { - return this.getUserIfNeeded({ - username: username - }).then(aUser => { - if (!aUser || aUser.emailVerified) { - throw undefined; - } - - return this.regenerateEmailVerifyToken(aUser).then(() => { - this.sendVerificationEmail(aUser); - }); - }); - } - - setPasswordResetToken(email) { - const token = { - _perishable_token: (0, _cryptoUtils.randomString)(25) - }; - - if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenValidityDuration) { - token._perishable_token_expires_at = _node.default._encode(this.config.generatePasswordResetTokenExpiresAt()); - } - - return this.config.database.update('_User', { - $or: [{ - email - }, { - username: email, - email: { - $exists: false - } - }] - }, token, {}, true); - } - - async sendPasswordResetEmail(email) { - if (!this.adapter) { - throw 'Trying to send a reset password but no adapter is set'; // TODO: No adapter? - } - - let user; - - if (this.config.passwordPolicy && this.config.passwordPolicy.resetTokenReuseIfValid && this.config.passwordPolicy.resetTokenValidityDuration) { - const results = await this.config.database.find('_User', { - $or: [{ - email, - _perishable_token: { - $exists: true - } - }, { - username: email, - email: { - $exists: false - }, - _perishable_token: { - $exists: true - } - }] - }, { - limit: 1 - }); - - if (results.length == 1) { - let expiresDate = results[0]._perishable_token_expires_at; - - if (expiresDate && expiresDate.__type == 'Date') { - expiresDate = new Date(expiresDate.iso); - } - - if (expiresDate > new Date()) { - user = results[0]; - } - } - } - - if (!user || !user._perishable_token) { - user = await this.setPasswordResetToken(email); - } - - const token = encodeURIComponent(user._perishable_token); - const username = encodeURIComponent(user.username); - const link = buildEmailLink(this.config.requestResetPasswordURL, username, token, this.config); - const options = { - appName: this.config.appName, - link: link, - user: (0, _triggers.inflate)('_User', user) - }; - - if (this.adapter.sendPasswordResetEmail) { - this.adapter.sendPasswordResetEmail(options); - } else { - this.adapter.sendMail(this.defaultResetPasswordEmail(options)); - } - - return Promise.resolve(user); - } - - updatePassword(username, token, password) { - return this.checkResetTokenValidity(username, token).then(user => updateUserPassword(user, password, this.config)).then(user => { - const accountLockoutPolicy = new _AccountLockout.default(user, this.config); - return accountLockoutPolicy.unlockAccount(); - }).catch(error => { - if (error && error.message) { - // in case of Parse.Error, fail with the error message only - return Promise.reject(error.message); - } else { - return Promise.reject(error); - } - }); - } - - defaultVerificationEmail({ - link, - user, - appName - }) { - const text = 'Hi,\n\n' + 'You are being asked to confirm the e-mail address ' + user.get('email') + ' with ' + appName + '\n\n' + '' + 'Click here to confirm it:\n' + link; - const to = user.get('email'); - const subject = 'Please verify your e-mail for ' + appName; - return { - text, - to, - subject - }; - } - - defaultResetPasswordEmail({ - link, - user, - appName - }) { - const text = 'Hi,\n\n' + 'You requested to reset your password for ' + appName + (user.get('username') ? " (your username is '" + user.get('username') + "')" : '') + '.\n\n' + '' + 'Click here to reset it:\n' + link; - const to = user.get('email') || user.get('username'); - const subject = 'Password Reset for ' + appName; - return { - text, - to, - subject - }; - } - -} // Mark this private - - -exports.UserController = UserController; - -function updateUserPassword(user, password, config) { - return _rest.default.update(config, Auth.master(config), '_User', { - objectId: user.objectId - }, { - password: password - }).then(() => user); -} - -function buildEmailLink(destination, username, token, config) { - const usernameAndToken = `token=${token}&username=${username}`; - - if (config.parseFrameURL) { - const destinationWithoutHost = destination.replace(config.publicServerURL, ''); - return `${config.parseFrameURL}?link=${encodeURIComponent(destinationWithoutHost)}&${usernameAndToken}`; - } else { - return `${destination}?${usernameAndToken}`; - } -} - -var _default = UserController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9Vc2VyQ29udHJvbGxlci5qcyJdLCJuYW1lcyI6WyJSZXN0UXVlcnkiLCJyZXF1aXJlIiwiQXV0aCIsIlVzZXJDb250cm9sbGVyIiwiQWRhcHRhYmxlQ29udHJvbGxlciIsImNvbnN0cnVjdG9yIiwiYWRhcHRlciIsImFwcElkIiwib3B0aW9ucyIsInZhbGlkYXRlQWRhcHRlciIsInNob3VsZFZlcmlmeUVtYWlscyIsImV4cGVjdGVkQWRhcHRlclR5cGUiLCJNYWlsQWRhcHRlciIsInZlcmlmeVVzZXJFbWFpbHMiLCJzZXRFbWFpbFZlcmlmeVRva2VuIiwidXNlciIsIl9lbWFpbF92ZXJpZnlfdG9rZW4iLCJlbWFpbFZlcmlmaWVkIiwiY29uZmlnIiwiZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQiLCJQYXJzZSIsIl9lbmNvZGUiLCJnZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW5FeHBpcmVzQXQiLCJ2ZXJpZnlFbWFpbCIsInVzZXJuYW1lIiwidG9rZW4iLCJ1bmRlZmluZWQiLCJxdWVyeSIsInVwZGF0ZUZpZWxkcyIsIl9fb3AiLCIkZ3QiLCJEYXRlIiwibWFzdGVyQXV0aCIsIm1hc3RlciIsImZpbmRVc2VyRm9yRW1haWxWZXJpZmljYXRpb24iLCJleGVjdXRlIiwidGhlbiIsInJlc3VsdCIsInJlc3VsdHMiLCJsZW5ndGgiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm9iamVjdElkIiwicmVzdCIsInVwZGF0ZSIsImNoZWNrUmVzZXRUb2tlblZhbGlkaXR5IiwiZGF0YWJhc2UiLCJmaW5kIiwiX3BlcmlzaGFibGVfdG9rZW4iLCJsaW1pdCIsInBhc3N3b3JkUG9saWN5IiwicmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJleHBpcmVzRGF0ZSIsIl9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQiLCJfX3R5cGUiLCJpc28iLCJnZXRVc2VySWZOZWVkZWQiLCJlbWFpbCIsIndoZXJlIiwic2VuZFZlcmlmaWNhdGlvbkVtYWlsIiwiZW5jb2RlVVJJQ29tcG9uZW50IiwibGluayIsImJ1aWxkRW1haWxMaW5rIiwidmVyaWZ5RW1haWxVUkwiLCJhcHBOYW1lIiwic2VuZE1haWwiLCJkZWZhdWx0VmVyaWZpY2F0aW9uRW1haWwiLCJyZWdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbiIsImVtYWlsVmVyaWZ5VG9rZW5SZXVzZUlmVmFsaWQiLCJyZXNlbmRWZXJpZmljYXRpb25FbWFpbCIsImFVc2VyIiwic2V0UGFzc3dvcmRSZXNldFRva2VuIiwiZ2VuZXJhdGVQYXNzd29yZFJlc2V0VG9rZW5FeHBpcmVzQXQiLCIkb3IiLCIkZXhpc3RzIiwic2VuZFBhc3N3b3JkUmVzZXRFbWFpbCIsInJlc2V0VG9rZW5SZXVzZUlmVmFsaWQiLCJyZXF1ZXN0UmVzZXRQYXNzd29yZFVSTCIsImRlZmF1bHRSZXNldFBhc3N3b3JkRW1haWwiLCJ1cGRhdGVQYXNzd29yZCIsInBhc3N3b3JkIiwidXBkYXRlVXNlclBhc3N3b3JkIiwiYWNjb3VudExvY2tvdXRQb2xpY3kiLCJBY2NvdW50TG9ja291dCIsInVubG9ja0FjY291bnQiLCJjYXRjaCIsImVycm9yIiwibWVzc2FnZSIsInJlamVjdCIsInRleHQiLCJnZXQiLCJ0byIsInN1YmplY3QiLCJkZXN0aW5hdGlvbiIsInVzZXJuYW1lQW5kVG9rZW4iLCJwYXJzZUZyYW1lVVJMIiwiZGVzdGluYXRpb25XaXRob3V0SG9zdCIsInJlcGxhY2UiLCJwdWJsaWNTZXJ2ZXJVUkwiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUVBLElBQUlBLFNBQVMsR0FBR0MsT0FBTyxDQUFDLGNBQUQsQ0FBdkI7O0FBQ0EsSUFBSUMsSUFBSSxHQUFHRCxPQUFPLENBQUMsU0FBRCxDQUFsQjs7QUFFTyxNQUFNRSxjQUFOLFNBQTZCQyw0QkFBN0IsQ0FBaUQ7QUFDdERDLEVB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QUFEWixHQUxLLEVBUUw1QyxJQVJLLENBUUEsTUFBTXRCLElBUk4sQ0FBUDtBQVNEOztBQUVELFNBQVNnRCxjQUFULENBQXdCK0IsV0FBeEIsRUFBcUNyRSxRQUFyQyxFQUErQ0MsS0FBL0MsRUFBc0RSLE1BQXRELEVBQThEO0FBQzVELFFBQU02RSxnQkFBZ0IsR0FBSSxTQUFRckUsS0FBTSxhQUFZRCxRQUFTLEVBQTdEOztBQUVBLE1BQUlQLE1BQU0sQ0FBQzhFLGFBQVgsRUFBMEI7QUFDeEIsVUFBTUMsc0JBQXNCLEdBQUdILFdBQVcsQ0FBQ0ksT0FBWixDQUFvQmhGLE1BQU0sQ0FBQ2lGLGVBQTNCLEVBQTRDLEVBQTVDLENBQS9CO0FBRUEsV0FBUSxHQUFFakYsTUFBTSxDQUFDOEUsYUFBYyxTQUFRbkMsa0JBQWtCLENBQ3ZEb0Msc0JBRHVELENBRXZELElBQUdGLGdCQUFpQixFQUZ0QjtBQUdELEdBTkQsTUFNTztBQUNMLFdBQVEsR0FBRUQsV0FBWSxJQUFHQyxnQkFBaUIsRUFBMUM7QUFDRDtBQUNGOztlQUVjNUYsYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHJhbmRvbVN0cmluZyB9IGZyb20gJy4uL2NyeXB0b1V0aWxzJztcbmltcG9ydCB7IGluZmxhdGUgfSBmcm9tICcuLi90cmlnZ2Vycyc7XG5pbXBvcnQgQWRhcHRhYmxlQ29udHJvbGxlciBmcm9tICcuL0FkYXB0YWJsZUNvbnRyb2xsZXInO1xuaW1wb3J0IE1haWxBZGFwdGVyIGZyb20gJy4uL0FkYXB0ZXJzL0VtYWlsL01haWxBZGFwdGVyJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IEFjY291bnRMb2Nrb3V0IGZyb20gJy4uL0FjY291bnRMb2Nrb3V0JztcblxudmFyIFJlc3RRdWVyeSA9IHJlcXVpcmUoJy4uL1Jlc3RRdWVyeScpO1xudmFyIEF1dGggPSByZXF1aXJlKCcuLi9BdXRoJyk7XG5cbmV4cG9ydCBjbGFzcyBVc2VyQ29udHJvbGxlciBleHRlbmRzIEFkYXB0YWJsZUNvbnRyb2xsZXIge1xuICBjb25zdHJ1Y3RvcihhZGFwdGVyLCBhcHBJZCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgc3VwZXIoYWRhcHRlciwgYXBwSWQsIG9wdGlvbnMpO1xuICB9XG5cbiAgdmFsaWRhdGVBZGFwdGVyKGFkYXB0ZXIpIHtcbiAgICAvLyBBbGxvdyBubyBhZGFwdGVyXG4gICAgaWYgKCFhZGFwdGVyICYmICF0aGlzLnNob3VsZFZlcmlmeUVtYWlscykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzdXBlci52YWxpZGF0ZUFkYXB0ZXIoYWRhcHRlcik7XG4gIH1cblxuICBleHBlY3RlZEFkYXB0ZXJUeXBlKCkge1xuICAgIHJldHVybiBNYWlsQWRhcHRlcjtcbiAgfVxuXG4gIGdldCBzaG91bGRWZXJpZnlFbWFpbHMoKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy52ZXJpZnlVc2VyRW1haWxzO1xuICB9XG5cbiAgc2V0RW1haWxWZXJpZnlUb2tlbih1c2VyKSB7XG4gICAgaWYgKHRoaXMuc2hvdWxkVmVyaWZ5RW1haWxzKSB7XG4gICAgICB1c2VyLl9lbWFpbF92ZXJpZnlfdG9rZW4gPSByYW5kb21TdHJpbmcoMjUpO1xuICAgICAgdXNlci5lbWFpbFZlcmlmaWVkID0gZmFsc2U7XG5cbiAgICAgIGlmICh0aGlzLmNvbmZpZy5lbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbikge1xuICAgICAgICB1c2VyLl9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCA9IFBhcnNlLl9lbmNvZGUoXG4gICAgICAgICAgdGhpcy5jb25maWcuZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuRXhwaXJlc0F0KClcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB2ZXJpZnlFbWFpbCh1c2VybmFtZSwgdG9rZW4pIHtcbiAgICBpZiAoIXRoaXMuc2hvdWxkVmVyaWZ5RW1haWxzKSB7XG4gICAgICAvLyBUcnlpbmcgdG8gdmVyaWZ5IGVtYWlsIHdoZW4gbm90IGVuYWJsZWRcbiAgICAgIC8vIFRPRE86IEJldHRlciBlcnJvciBoZXJlLlxuICAgICAgdGhyb3cgdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IHF1ZXJ5ID0geyB1c2VybmFtZTogdXNlcm5hbWUsIF9lbWFpbF92ZXJpZnlfdG9rZW46IHRva2VuIH07XG4gICAgY29uc3QgdXBkYXRlRmllbGRzID0ge1xuICAgICAgZW1haWxWZXJpZmllZDogdHJ1ZSxcbiAgICAgIF9lbWFpbF92ZXJpZnlfdG9rZW46IHsgX19vcDogJ0RlbGV0ZScgfSxcbiAgICB9O1xuXG4gICAgLy8gaWYgdGhlIGVtYWlsIHZlcmlmeSB0b2tlbiBuZWVkcyB0byBiZSB2YWxpZGF0ZWQgdGhlblxuICAgIC8vIGFkZCBhZGRpdGlvbmFsIHF1ZXJ5IHBhcmFtcyBhbmQgYWRkaXRpb25hbCBmaWVsZHMgdGhhdCBuZWVkIHRvIGJlIHVwZGF0ZWRcbiAgICBpZiAodGhpcy5jb25maWcuZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24pIHtcbiAgICAgIHF1ZXJ5LmVtYWlsVmVyaWZpZWQgPSBmYWxzZTtcbiAgICAgIHF1ZXJ5Ll9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCA9IHsgJGd0OiBQYXJzZS5fZW5jb2RlKG5ldyBEYXRlKCkpIH07XG5cbiAgICAgIHVwZGF0ZUZpZWxkcy5fZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQgPSB7IF9fb3A6ICdEZWxldGUnIH07XG4gICAgfVxuICAgIGNvbnN0IG1hc3RlckF1dGggPSBBdXRoLm1hc3Rlcih0aGlzLmNvbmZpZyk7XG4gICAgdmFyIGZpbmRVc2VyRm9yRW1haWxWZXJpZmljYXRpb24gPSBuZXcgUmVzdFF1ZXJ5KFxuICAgICAgdGhpcy5jb25maWcsXG4gICAgICBBdXRoLm1hc3Rlcih0aGlzLmNvbmZpZyksXG4gICAgICAnX1VzZXInLFxuICAgICAgeyB1c2VybmFtZTogdXNlcm5hbWUgfVxuICAgICk7XG4gICAgcmV0dXJuIGZpbmRVc2VyRm9yRW1haWxWZXJpZmljYXRpb24uZXhlY3V0ZSgpLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgIGlmIChyZXN1bHQucmVzdWx0cy5sZW5ndGggJiYgcmVzdWx0LnJlc3VsdHNbMF0uZW1haWxWZXJpZmllZCkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlc3VsdC5yZXN1bHRzLmxlbmd0aFswXSk7XG4gICAgICB9IGVsc2UgaWYgKHJlc3VsdC5yZXN1bHRzLmxlbmd0aCkge1xuICAgICAgICBxdWVyeS5vYmplY3RJZCA9IHJlc3VsdC5yZXN1bHRzWzBdLm9iamVjdElkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3QudXBkYXRlKHRoaXMuY29uZmlnLCBtYXN0ZXJBdXRoLCAnX1VzZXInLCBxdWVyeSwgdXBkYXRlRmllbGRzKTtcbiAgICB9KTtcbiAgfVxuXG4gIGNoZWNrUmVzZXRUb2tlblZhbGlkaXR5KHVzZXJuYW1lLCB0b2tlbikge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgICAgLmZpbmQoXG4gICAgICAgICdfVXNlcicsXG4gICAgICAgIHtcbiAgICAgICAgICB1c2VybmFtZTogdXNlcm5hbWUsXG4gICAgICAgICAgX3BlcmlzaGFibGVfdG9rZW46IHRva2VuLFxuICAgICAgICB9LFxuICAgICAgICB7IGxpbWl0OiAxIH1cbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggIT0gMSkge1xuICAgICAgICAgIHRocm93ICdGYWlsZWQgdG8gcmVzZXQgcGFzc3dvcmQ6IHVzZXJuYW1lIC8gZW1haWwgLyB0b2tlbiBpcyBpbnZhbGlkJztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeSAmJiB0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbikge1xuICAgICAgICAgIGxldCBleHBpcmVzRGF0ZSA9IHJlc3VsdHNbMF0uX3BlcmlzaGFibGVfdG9rZW5fZXhwaXJlc19hdDtcbiAgICAgICAgICBpZiAoZXhwaXJlc0RhdGUgJiYgZXhwaXJlc0RhdGUuX190eXBlID09ICdEYXRlJykge1xuICAgICAgICAgICAgZXhwaXJlc0RhdGUgPSBuZXcgRGF0ZShleHBpcmVzRGF0ZS5pc28pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZXhwaXJlc0RhdGUgPCBuZXcgRGF0ZSgpKSB0aHJvdyAnVGhlIHBhc3N3b3JkIHJlc2V0IGxpbmsgaGFzIGV4cGlyZWQnO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRzWzBdO1xuICAgICAgfSk7XG4gIH1cblxuICBnZXRVc2VySWZOZWVkZWQodXNlcikge1xuICAgIGlmICh1c2VyLnVzZXJuYW1lICYmIHVzZXIuZW1haWwpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodXNlcik7XG4gICAgfVxuICAgIHZhciB3aGVyZSA9IHt9O1xuICAgIGlmICh1c2VyLnVzZXJuYW1lKSB7XG4gICAgICB3aGVyZS51c2VybmFtZSA9IHVzZXIudXNlcm5hbWU7XG4gICAgfVxuICAgIGlmICh1c2VyLmVtYWlsKSB7XG4gICAgICB3aGVyZS5lbWFpbCA9IHVzZXIuZW1haWw7XG4gICAgfVxuXG4gICAgdmFyIHF1ZXJ5ID0gbmV3IFJlc3RRdWVyeSh0aGlzLmNvbmZpZywgQXV0aC5tYXN0ZXIodGhpcy5jb25maWcpLCAnX1VzZXInLCB3aGVyZSk7XG4gICAgcmV0dXJuIHF1ZXJ5LmV4ZWN1dGUoKS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgIGlmIChyZXN1bHQucmVzdWx0cy5sZW5ndGggIT0gMSkge1xuICAgICAgICB0aHJvdyB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0LnJlc3VsdHNbMF07XG4gICAgfSk7XG4gIH1cblxuICBzZW5kVmVyaWZpY2F0aW9uRW1haWwodXNlcikge1xuICAgIGlmICghdGhpcy5zaG91bGRWZXJpZnlFbWFpbHMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgdG9rZW4gPSBlbmNvZGVVUklDb21wb25lbnQodXNlci5fZW1haWxfdmVyaWZ5X3Rva2VuKTtcbiAgICAvLyBXZSBtYXkgbmVlZCB0byBmZXRjaCB0aGUgdXNlciBpbiBjYXNlIG9mIHVwZGF0ZSBlbWFpbFxuICAgIHRoaXMuZ2V0VXNlcklmTmVlZGVkKHVzZXIpLnRoZW4odXNlciA9PiB7XG4gICAgICBjb25zdCB1c2VybmFtZSA9IGVuY29kZVVSSUNvbXBvbmVudCh1c2VyLnVzZXJuYW1lKTtcblxuICAgICAgY29uc3QgbGluayA9IGJ1aWxkRW1haWxMaW5rKHRoaXMuY29uZmlnLnZlcmlmeUVtYWlsVVJMLCB1c2VybmFtZSwgdG9rZW4sIHRoaXMuY29uZmlnKTtcbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgIGFwcE5hbWU6IHRoaXMuY29uZmlnLmFwcE5hbWUsXG4gICAgICAgIGxpbms6IGxpbmssXG4gICAgICAgIHVzZXI6IGluZmxhdGUoJ19Vc2VyJywgdXNlciksXG4gICAgICB9O1xuICAgICAgaWYgKHRoaXMuYWRhcHRlci5zZW5kVmVyaWZpY2F0aW9uRW1haWwpIHtcbiAgICAgICAgdGhpcy5hZGFwdGVyLnNlbmRWZXJpZmljYXRpb25FbWFpbChvcHRpb25zKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYWRhcHRlci5zZW5kTWFpbCh0aGlzLmRlZmF1bHRWZXJpZmljYXRpb25FbWFpbChvcHRpb25zKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmVnZW5lcmF0ZXMgdGhlIGdpdmVuIHVzZXIncyBlbWFpbCB2ZXJpZmljYXRpb24gdG9rZW5cbiAgICpcbiAgICogQHBhcmFtIHVzZXJcbiAgICogQHJldHVybnMgeyp9XG4gICAqL1xuICByZWdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbih1c2VyKSB7XG4gICAgY29uc3QgeyBfZW1haWxfdmVyaWZ5X3Rva2VuIH0gPSB1c2VyO1xuICAgIGxldCB7IF9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdCB9ID0gdXNlcjtcbiAgICBpZiAoX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0ICYmIF9lbWFpbF92ZXJpZnlfdG9rZW5fZXhwaXJlc19hdC5fX3R5cGUgPT09ICdEYXRlJykge1xuICAgICAgX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0ID0gX2VtYWlsX3ZlcmlmeV90b2tlbl9leHBpcmVzX2F0LmlzbztcbiAgICB9XG4gICAgaWYgKFxuICAgICAgdGhpcy5jb25maWcuZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZCAmJlxuICAgICAgdGhpcy5jb25maWcuZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24gJiZcbiAgICAgIF9lbWFpbF92ZXJpZnlfdG9rZW4gJiZcbiAgICAgIG5ldyBEYXRlKCkgPCBuZXcgRGF0ZShfZW1haWxfdmVyaWZ5X3Rva2VuX2V4cGlyZXNfYXQpXG4gICAgKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIHRoaXMuc2V0RW1haWxWZXJpZnlUb2tlbih1c2VyKTtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UudXBkYXRlKCdfVXNlcicsIHsgdXNlcm5hbWU6IHVzZXIudXNlcm5hbWUgfSwgdXNlcik7XG4gIH1cblxuICByZXNlbmRWZXJpZmljYXRpb25FbWFpbCh1c2VybmFtZSkge1xuICAgIHJldHVybiB0aGlzLmdldFVzZXJJZk5lZWRlZCh7IHVzZXJuYW1lOiB1c2VybmFtZSB9KS50aGVuKGFVc2VyID0+IHtcbiAgICAgIGlmICghYVVzZXIgfHwgYVVzZXIuZW1haWxWZXJpZmllZCkge1xuICAgICAgICB0aHJvdyB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5yZWdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbihhVXNlcikudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMuc2VuZFZlcmlmaWNhdGlvbkVtYWlsKGFVc2VyKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgc2V0UGFzc3dvcmRSZXNldFRva2VuKGVtYWlsKSB7XG4gICAgY29uc3QgdG9rZW4gPSB7IF9wZXJpc2hhYmxlX3Rva2VuOiByYW5kb21TdHJpbmcoMjUpIH07XG5cbiAgICBpZiAodGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kgJiYgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24pIHtcbiAgICAgIHRva2VuLl9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQgPSBQYXJzZS5fZW5jb2RlKFxuICAgICAgICB0aGlzLmNvbmZpZy5nZW5lcmF0ZVBhc3N3b3JkUmVzZXRUb2tlbkV4cGlyZXNBdCgpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZS51cGRhdGUoXG4gICAgICAnX1VzZXInLFxuICAgICAgeyAkb3I6IFt7IGVtYWlsIH0sIHsgdXNlcm5hbWU6IGVtYWlsLCBlbWFpbDogeyAkZXhpc3RzOiBmYWxzZSB9IH1dIH0sXG4gICAgICB0b2tlbixcbiAgICAgIHt9LFxuICAgICAgdHJ1ZVxuICAgICk7XG4gIH1cblxuICBhc3luYyBzZW5kUGFzc3dvcmRSZXNldEVtYWlsKGVtYWlsKSB7XG4gICAgaWYgKCF0aGlzLmFkYXB0ZXIpIHtcbiAgICAgIHRocm93ICdUcnlpbmcgdG8gc2VuZCBhIHJlc2V0IHBhc3N3b3JkIGJ1dCBubyBhZGFwdGVyIGlzIHNldCc7XG4gICAgICAvLyAgVE9ETzogTm8gYWRhcHRlcj9cbiAgICB9XG4gICAgbGV0IHVzZXI7XG4gICAgaWYgKFxuICAgICAgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kgJiZcbiAgICAgIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5SZXVzZUlmVmFsaWQgJiZcbiAgICAgIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uXG4gICAgKSB7XG4gICAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5jb25maWcuZGF0YWJhc2UuZmluZChcbiAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAge1xuICAgICAgICAgICRvcjogW1xuICAgICAgICAgICAgeyBlbWFpbCwgX3BlcmlzaGFibGVfdG9rZW46IHsgJGV4aXN0czogdHJ1ZSB9IH0sXG4gICAgICAgICAgICB7IHVzZXJuYW1lOiBlbWFpbCwgZW1haWw6IHsgJGV4aXN0czogZmFsc2UgfSwgX3BlcmlzaGFibGVfdG9rZW46IHsgJGV4aXN0czogdHJ1ZSB9IH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgeyBsaW1pdDogMSB9XG4gICAgICApO1xuICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID09IDEpIHtcbiAgICAgICAgbGV0IGV4cGlyZXNEYXRlID0gcmVzdWx0c1swXS5fcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0O1xuICAgICAgICBpZiAoZXhwaXJlc0RhdGUgJiYgZXhwaXJlc0RhdGUuX190eXBlID09ICdEYXRlJykge1xuICAgICAgICAgIGV4cGlyZXNEYXRlID0gbmV3IERhdGUoZXhwaXJlc0RhdGUuaXNvKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXhwaXJlc0RhdGUgPiBuZXcgRGF0ZSgpKSB7XG4gICAgICAgICAgdXNlciA9IHJlc3VsdHNbMF07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCF1c2VyIHx8ICF1c2VyLl9wZXJpc2hhYmxlX3Rva2VuKSB7XG4gICAgICB1c2VyID0gYXdhaXQgdGhpcy5zZXRQYXNzd29yZFJlc2V0VG9rZW4oZW1haWwpO1xuICAgIH1cbiAgICBjb25zdCB0b2tlbiA9IGVuY29kZVVSSUNvbXBvbmVudCh1c2VyLl9wZXJpc2hhYmxlX3Rva2VuKTtcbiAgICBjb25zdCB1c2VybmFtZSA9IGVuY29kZVVSSUNvbXBvbmVudCh1c2VyLnVzZXJuYW1lKTtcblxuICAgIGNvbnN0IGxpbmsgPSBidWlsZEVtYWlsTGluayh0aGlzLmNvbmZpZy5yZXF1ZXN0UmVzZXRQYXNzd29yZFVSTCwgdXNlcm5hbWUsIHRva2VuLCB0aGlzLmNvbmZpZyk7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgIGFwcE5hbWU6IHRoaXMuY29uZmlnLmFwcE5hbWUsXG4gICAgICBsaW5rOiBsaW5rLFxuICAgICAgdXNlcjogaW5mbGF0ZSgnX1VzZXInLCB1c2VyKSxcbiAgICB9O1xuXG4gICAgaWYgKHRoaXMuYWRhcHRlci5zZW5kUGFzc3dvcmRSZXNldEVtYWlsKSB7XG4gICAgICB0aGlzLmFkYXB0ZXIuc2VuZFBhc3N3b3JkUmVzZXRFbWFpbChvcHRpb25zKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hZGFwdGVyLnNlbmRNYWlsKHRoaXMuZGVmYXVsdFJlc2V0UGFzc3dvcmRFbWFpbChvcHRpb25zKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh1c2VyKTtcbiAgfVxuXG4gIHVwZGF0ZVBhc3N3b3JkKHVzZXJuYW1lLCB0b2tlbiwgcGFzc3dvcmQpIHtcbiAgICByZXR1cm4gdGhpcy5jaGVja1Jlc2V0VG9rZW5WYWxpZGl0eSh1c2VybmFtZSwgdG9rZW4pXG4gICAgICAudGhlbih1c2VyID0+IHVwZGF0ZVVzZXJQYXNzd29yZCh1c2VyLCBwYXNzd29yZCwgdGhpcy5jb25maWcpKVxuICAgICAgLnRoZW4odXNlciA9PiB7XG4gICAgICAgIGNvbnN0IGFjY291bnRMb2Nrb3V0UG9saWN5ID0gbmV3IEFjY291bnRMb2Nrb3V0KHVzZXIsIHRoaXMuY29uZmlnKTtcbiAgICAgICAgcmV0dXJuIGFjY291bnRMb2Nrb3V0UG9saWN5LnVubG9ja0FjY291bnQoKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgJiYgZXJyb3IubWVzc2FnZSkge1xuICAgICAgICAgIC8vIGluIGNhc2Ugb2YgUGFyc2UuRXJyb3IsIGZhaWwgd2l0aCB0aGUgZXJyb3IgbWVzc2FnZSBvbmx5XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycm9yLm1lc3NhZ2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnJvcik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgZGVmYXVsdFZlcmlmaWNhdGlvbkVtYWlsKHsgbGluaywgdXNlciwgYXBwTmFtZSB9KSB7XG4gICAgY29uc3QgdGV4dCA9XG4gICAgICAnSGksXFxuXFxuJyArXG4gICAgICAnWW91IGFyZSBiZWluZyBhc2tlZCB0byBjb25maXJtIHRoZSBlLW1haWwgYWRkcmVzcyAnICtcbiAgICAgIHVzZXIuZ2V0KCdlbWFpbCcpICtcbiAgICAgICcgd2l0aCAnICtcbiAgICAgIGFwcE5hbWUgK1xuICAgICAgJ1xcblxcbicgK1xuICAgICAgJycgK1xuICAgICAgJ0NsaWNrIGhlcmUgdG8gY29uZmlybSBpdDpcXG4nICtcbiAgICAgIGxpbms7XG4gICAgY29uc3QgdG8gPSB1c2VyLmdldCgnZW1haWwnKTtcbiAgICBjb25zdCBzdWJqZWN0ID0gJ1BsZWFzZSB2ZXJpZnkgeW91ciBlLW1haWwgZm9yICcgKyBhcHBOYW1lO1xuICAgIHJldHVybiB7IHRleHQsIHRvLCBzdWJqZWN0IH07XG4gIH1cblxuICBkZWZhdWx0UmVzZXRQYXNzd29yZEVtYWlsKHsgbGluaywgdXNlciwgYXBwTmFtZSB9KSB7XG4gICAgY29uc3QgdGV4dCA9XG4gICAgICAnSGksXFxuXFxuJyArXG4gICAgICAnWW91IHJlcXVlc3RlZCB0byByZXNldCB5b3VyIHBhc3N3b3JkIGZvciAnICtcbiAgICAgIGFwcE5hbWUgK1xuICAgICAgKHVzZXIuZ2V0KCd1c2VybmFtZScpID8gXCIgKHlvdXIgdXNlcm5hbWUgaXMgJ1wiICsgdXNlci5nZXQoJ3VzZXJuYW1lJykgKyBcIicpXCIgOiAnJykgK1xuICAgICAgJy5cXG5cXG4nICtcbiAgICAgICcnICtcbiAgICAgICdDbGljayBoZXJlIHRvIHJlc2V0IGl0OlxcbicgK1xuICAgICAgbGluaztcbiAgICBjb25zdCB0byA9IHVzZXIuZ2V0KCdlbWFpbCcpIHx8IHVzZXIuZ2V0KCd1c2VybmFtZScpO1xuICAgIGNvbnN0IHN1YmplY3QgPSAnUGFzc3dvcmQgUmVzZXQgZm9yICcgKyBhcHBOYW1lO1xuICAgIHJldHVybiB7IHRleHQsIHRvLCBzdWJqZWN0IH07XG4gIH1cbn1cblxuLy8gTWFyayB0aGlzIHByaXZhdGVcbmZ1bmN0aW9uIHVwZGF0ZVVzZXJQYXNzd29yZCh1c2VyLCBwYXNzd29yZCwgY29uZmlnKSB7XG4gIHJldHVybiByZXN0LnVwZGF0ZShcbiAgICBjb25maWcsXG4gICAgQXV0aC5tYXN0ZXIoY29uZmlnKSxcbiAgICAnX1VzZXInLFxuICAgIHsgb2JqZWN0SWQ6IHVzZXIub2JqZWN0SWQgfSxcbiAgICB7XG4gICAgICBwYXNzd29yZDogcGFzc3dvcmQsXG4gICAgfVxuICApLnRoZW4oKCkgPT4gdXNlcik7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkRW1haWxMaW5rKGRlc3RpbmF0aW9uLCB1c2VybmFtZSwgdG9rZW4sIGNvbmZpZykge1xuICBjb25zdCB1c2VybmFtZUFuZFRva2VuID0gYHRva2VuPSR7dG9rZW59JnVzZXJuYW1lPSR7dXNlcm5hbWV9YDtcblxuICBpZiAoY29uZmlnLnBhcnNlRnJhbWVVUkwpIHtcbiAgICBjb25zdCBkZXN0aW5hdGlvbldpdGhvdXRIb3N0ID0gZGVzdGluYXRpb24ucmVwbGFjZShjb25maWcucHVibGljU2VydmVyVVJMLCAnJyk7XG5cbiAgICByZXR1cm4gYCR7Y29uZmlnLnBhcnNlRnJhbWVVUkx9P2xpbms9JHtlbmNvZGVVUklDb21wb25lbnQoXG4gICAgICBkZXN0aW5hdGlvbldpdGhvdXRIb3N0XG4gICAgKX0mJHt1c2VybmFtZUFuZFRva2VufWA7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGAke2Rlc3RpbmF0aW9ufT8ke3VzZXJuYW1lQW5kVG9rZW59YDtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBVc2VyQ29udHJvbGxlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Controllers/index.js b/lib/Controllers/index.js deleted file mode 100644 index e3ace5883c..0000000000 --- a/lib/Controllers/index.js +++ /dev/null @@ -1,312 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.getControllers = getControllers; -exports.getLoggerController = getLoggerController; -exports.getFilesController = getFilesController; -exports.getUserController = getUserController; -exports.getCacheController = getCacheController; -exports.getParseGraphQLController = getParseGraphQLController; -exports.getAnalyticsController = getAnalyticsController; -exports.getLiveQueryController = getLiveQueryController; -exports.getDatabaseController = getDatabaseController; -exports.getHooksController = getHooksController; -exports.getPushController = getPushController; -exports.getAuthDataManager = getAuthDataManager; -exports.getDatabaseAdapter = getDatabaseAdapter; - -var _Auth = _interopRequireDefault(require("../Adapters/Auth")); - -var _Options = require("../Options"); - -var _AdapterLoader = require("../Adapters/AdapterLoader"); - -var _defaults = _interopRequireDefault(require("../defaults")); - -var _url = _interopRequireDefault(require("url")); - -var _LoggerController = require("./LoggerController"); - -var _FilesController = require("./FilesController"); - -var _HooksController = require("./HooksController"); - -var _UserController = require("./UserController"); - -var _CacheController = require("./CacheController"); - -var _LiveQueryController = require("./LiveQueryController"); - -var _AnalyticsController = require("./AnalyticsController"); - -var _PushController = require("./PushController"); - -var _PushQueue = require("../Push/PushQueue"); - -var _PushWorker = require("../Push/PushWorker"); - -var _DatabaseController = _interopRequireDefault(require("./DatabaseController")); - -var _SchemaCache = _interopRequireDefault(require("./SchemaCache")); - -var _GridFSBucketAdapter = require("../Adapters/Files/GridFSBucketAdapter"); - -var _WinstonLoggerAdapter = require("../Adapters/Logger/WinstonLoggerAdapter"); - -var _InMemoryCacheAdapter = require("../Adapters/Cache/InMemoryCacheAdapter"); - -var _AnalyticsAdapter = require("../Adapters/Analytics/AnalyticsAdapter"); - -var _MongoStorageAdapter = _interopRequireDefault(require("../Adapters/Storage/Mongo/MongoStorageAdapter")); - -var _PostgresStorageAdapter = _interopRequireDefault(require("../Adapters/Storage/Postgres/PostgresStorageAdapter")); - -var _pushAdapter = _interopRequireDefault(require("@parse/push-adapter")); - -var _ParseGraphQLController = _interopRequireDefault(require("./ParseGraphQLController")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function getControllers(options) { - const loggerController = getLoggerController(options); - const filesController = getFilesController(options); - const userController = getUserController(options); - const { - pushController, - hasPushScheduledSupport, - hasPushSupport, - pushControllerQueue, - pushWorker - } = getPushController(options); - const cacheController = getCacheController(options); - const analyticsController = getAnalyticsController(options); - const liveQueryController = getLiveQueryController(options); - const databaseController = getDatabaseController(options, cacheController); - const hooksController = getHooksController(options, databaseController); - const authDataManager = getAuthDataManager(options); - const parseGraphQLController = getParseGraphQLController(options, { - databaseController, - cacheController - }); - return { - loggerController, - filesController, - userController, - pushController, - hasPushScheduledSupport, - hasPushSupport, - pushWorker, - pushControllerQueue, - analyticsController, - cacheController, - parseGraphQLController, - liveQueryController, - databaseController, - hooksController, - authDataManager - }; -} - -function getLoggerController(options) { - const { - appId, - jsonLogs, - logsFolder, - verbose, - logLevel, - maxLogFiles, - silent, - loggerAdapter - } = options; - const loggerOptions = { - jsonLogs, - logsFolder, - verbose, - logLevel, - silent, - maxLogFiles - }; - const loggerControllerAdapter = (0, _AdapterLoader.loadAdapter)(loggerAdapter, _WinstonLoggerAdapter.WinstonLoggerAdapter, loggerOptions); - return new _LoggerController.LoggerController(loggerControllerAdapter, appId, loggerOptions); -} - -function getFilesController(options) { - const { - appId, - databaseURI, - filesAdapter, - databaseAdapter, - preserveFileName, - fileKey - } = options; - - if (!filesAdapter && databaseAdapter) { - throw 'When using an explicit database adapter, you must also use an explicit filesAdapter.'; - } - - const filesControllerAdapter = (0, _AdapterLoader.loadAdapter)(filesAdapter, () => { - return new _GridFSBucketAdapter.GridFSBucketAdapter(databaseURI, {}, fileKey); - }); - return new _FilesController.FilesController(filesControllerAdapter, appId, { - preserveFileName - }); -} - -function getUserController(options) { - const { - appId, - emailAdapter, - verifyUserEmails - } = options; - const emailControllerAdapter = (0, _AdapterLoader.loadAdapter)(emailAdapter); - return new _UserController.UserController(emailControllerAdapter, appId, { - verifyUserEmails - }); -} - -function getCacheController(options) { - const { - appId, - cacheAdapter, - cacheTTL, - cacheMaxSize - } = options; - const cacheControllerAdapter = (0, _AdapterLoader.loadAdapter)(cacheAdapter, _InMemoryCacheAdapter.InMemoryCacheAdapter, { - appId: appId, - ttl: cacheTTL, - maxSize: cacheMaxSize - }); - return new _CacheController.CacheController(cacheControllerAdapter, appId); -} - -function getParseGraphQLController(options, controllerDeps) { - return new _ParseGraphQLController.default(_objectSpread({ - mountGraphQL: options.mountGraphQL - }, controllerDeps)); -} - -function getAnalyticsController(options) { - const { - analyticsAdapter - } = options; - const analyticsControllerAdapter = (0, _AdapterLoader.loadAdapter)(analyticsAdapter, _AnalyticsAdapter.AnalyticsAdapter); - return new _AnalyticsController.AnalyticsController(analyticsControllerAdapter); -} - -function getLiveQueryController(options) { - return new _LiveQueryController.LiveQueryController(options.liveQuery); -} - -function getDatabaseController(options, cacheController) { - const { - databaseURI, - databaseOptions, - collectionPrefix, - schemaCacheTTL, - enableSingleSchemaCache - } = options; - let { - databaseAdapter - } = options; - - if ((databaseOptions || databaseURI && databaseURI !== _defaults.default.databaseURI || collectionPrefix !== _defaults.default.collectionPrefix) && databaseAdapter) { - throw 'You cannot specify both a databaseAdapter and a databaseURI/databaseOptions/collectionPrefix.'; - } else if (!databaseAdapter) { - databaseAdapter = getDatabaseAdapter(databaseURI, collectionPrefix, databaseOptions); - } else { - databaseAdapter = (0, _AdapterLoader.loadAdapter)(databaseAdapter); - } - - return new _DatabaseController.default(databaseAdapter, new _SchemaCache.default(cacheController, schemaCacheTTL, enableSingleSchemaCache)); -} - -function getHooksController(options, databaseController) { - const { - appId, - webhookKey - } = options; - return new _HooksController.HooksController(appId, databaseController, webhookKey); -} - -function getPushController(options) { - const { - scheduledPush, - push - } = options; - const pushOptions = Object.assign({}, push); - const pushQueueOptions = pushOptions.queueOptions || {}; - - if (pushOptions.queueOptions) { - delete pushOptions.queueOptions; - } // Pass the push options too as it works with the default - - - const pushAdapter = (0, _AdapterLoader.loadAdapter)(pushOptions && pushOptions.adapter, _pushAdapter.default, pushOptions); // We pass the options and the base class for the adatper, - // Note that passing an instance would work too - - const pushController = new _PushController.PushController(); - const hasPushSupport = !!(pushAdapter && push); - const hasPushScheduledSupport = hasPushSupport && scheduledPush === true; - const { - disablePushWorker - } = pushQueueOptions; - const pushControllerQueue = new _PushQueue.PushQueue(pushQueueOptions); - let pushWorker; - - if (!disablePushWorker) { - pushWorker = new _PushWorker.PushWorker(pushAdapter, pushQueueOptions); - } - - return { - pushController, - hasPushSupport, - hasPushScheduledSupport, - pushControllerQueue, - pushWorker - }; -} - -function getAuthDataManager(options) { - const { - auth, - enableAnonymousUsers - } = options; - return (0, _Auth.default)(auth, enableAnonymousUsers); -} - -function getDatabaseAdapter(databaseURI, collectionPrefix, databaseOptions) { - let protocol; - - try { - const parsedURI = _url.default.parse(databaseURI); - - protocol = parsedURI.protocol ? parsedURI.protocol.toLowerCase() : null; - } catch (e) { - /* */ - } - - switch (protocol) { - case 'postgres:': - return new _PostgresStorageAdapter.default({ - uri: databaseURI, - collectionPrefix, - databaseOptions - }); - - default: - return new _MongoStorageAdapter.default({ - uri: databaseURI, - collectionPrefix, - mongoOptions: databaseOptions - }); - } -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9pbmRleC5qcyJdLCJuYW1lcyI6WyJnZXRDb250cm9sbGVycyIsIm9wdGlvbnMiLCJsb2dnZXJDb250cm9sbGVyIiwiZ2V0TG9nZ2VyQ29udHJvbGxlciIsImZpbGVzQ29udHJvbGxlciIsImdldEZpbGVzQ29udHJvbGxlciIsInVzZXJDb250cm9sbGVyIiwiZ2V0VXNlckNvbnRyb2xsZXIiLCJwdXNoQ29udHJvbGxlciIsImhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0IiwiaGFzUHVzaFN1cHBvcnQiLCJwdXNoQ29udHJvbGxlclF1ZXVlIiwicHVzaFdvcmtlciIsImdldFB1c2hDb250cm9sbGVyIiwiY2FjaGVDb250cm9sbGVyIiwiZ2V0Q2FjaGVDb250cm9sbGVyIiwiYW5hbHl0aWNzQ29udHJvbGxlciIsImdldEFuYWx5dGljc0NvbnRyb2xsZXIiLCJsaXZlUXVlcnlDb250cm9sbGVyIiwiZ2V0TGl2ZVF1ZXJ5Q29udHJvbGxlciIsImRhdGFiYXNlQ29udHJvbGxlciIsImdldERhdGFiYXNlQ29udHJvbGxlciIsImhvb2tzQ29udHJvbGxlciIsImdldEhvb2tzQ29udHJvbGxlciIsImF1dGhEYXRhTWFuYWdlciIsImdldEF1dGhEYXRhTWFuYWdlciIsInBhcnNlR3JhcGhRTENvbnRyb2xsZXIiLCJnZXRQYXJzZUdyYXBoUUxDb250cm9sbGVyIiwiYXBwSWQiLCJqc29uTG9ncyIsImxvZ3NGb2xkZXIiLCJ2ZXJib3NlIiwibG9nTGV2ZWwiLCJtYXhMb2dGaWxlcyIsInNpbGVudCIsImxvZ2dlckFkYXB0ZXIiLCJsb2dnZXJPcHRpb25zIiwibG9nZ2VyQ29udHJvbGxlckFkYXB0ZXIiLCJXaW5zdG9uTG9nZ2VyQWRhcHRlciIsIkxvZ2dlckNvbnRyb2xsZXIiLCJkYXRhYmFzZVVSSSIsImZpbGVzQWRhcHRlciIsImRhdGFiYXNlQWRhcHRlciIsInByZXNlcnZlRmlsZU5hbWUiLCJmaWxlS2V5IiwiZmlsZXNDb250cm9sbGVyQWRhcHRlciIsIkdyaWRGU0J1Y2tldEFkYXB0ZXIiLCJGaWxlc0NvbnRyb2xsZXIiLCJlbWFpbEFkYXB0ZXIiLCJ2ZXJpZnlVc2VyRW1haWxzIiwiZW1haWxDb250cm9sbGVyQWRhcHRlciIsIlVzZXJDb250cm9sbGVyIiwiY2FjaGVBZGFwdGVyIiwiY2FjaGVUVEwiLCJjYWNoZU1heFNpemUiLCJjYWNoZUNvbnRyb2xsZXJBZGFwdGVyIiwiSW5NZW1vcnlDYWNoZUFkYXB0ZXIiLCJ0dGwiLCJtYXhTaXplIiwiQ2FjaGVDb250cm9sbGVyIiwiY29udHJvbGxlckRlcHMiLCJQYXJzZUdyYXBoUUxDb250cm9sbGVyIiwibW91bnRHcmFwaFFMIiwiYW5hbHl0aWNzQWRhcHRlciIsImFuYWx5dGljc0NvbnRyb2xsZXJBZGFwdGVyIiwiQW5hbHl0aWNzQWRhcHRlciIsIkFuYWx5dGljc0NvbnRyb2xsZXIiLCJMaXZlUXVlcnlDb250cm9sbGVyIiwibGl2ZVF1ZXJ5IiwiZGF0YWJhc2VPcHRpb25zIiwiY29sbGVjdGlvblByZWZpeCIsInNjaGVtYUNhY2hlVFRMIiwiZW5hYmxlU2luZ2xlU2NoZW1hQ2FjaGUiLCJkZWZhdWx0cyIsImdldERhdGFiYXNlQWRhcHRlciIsIkRhdGFiYXNlQ29udHJvbGxlciIsIlNjaGVtYUNhY2hlIiwid2ViaG9va0tleSIsIkhvb2tzQ29udHJvbGxlciIsInNjaGVkdWxlZFB1c2giLCJwdXNoIiwicHVzaE9wdGlvbnMiLCJPYmplY3QiLCJhc3NpZ24iLCJwdXNoUXVldWVPcHRpb25zIiwicXVldWVPcHRpb25zIiwicHVzaEFkYXB0ZXIiLCJhZGFwdGVyIiwiUGFyc2VQdXNoQWRhcHRlciIsIlB1c2hDb250cm9sbGVyIiwiZGlzYWJsZVB1c2hXb3JrZXIiLCJQdXNoUXVldWUiLCJQdXNoV29ya2VyIiwiYXV0aCIsImVuYWJsZUFub255bW91c1VzZXJzIiwicHJvdG9jb2wiLCJwYXJzZWRVUkkiLCJ1cmwiLCJwYXJzZSIsInRvTG93ZXJDYXNlIiwiZSIsIlBvc3RncmVzU3Rv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QUEsR0FBRyxFQUFFOUQsV0FEMkI7QUFFaEM4QixRQUFBQSxnQkFGZ0M7QUFHaENELFFBQUFBO0FBSGdDLE9BQTNCLENBQVA7O0FBS0Y7QUFDRSxhQUFPLElBQUlrQyw0QkFBSixDQUF3QjtBQUM3QkQsUUFBQUEsR0FBRyxFQUFFOUQsV0FEd0I7QUFFN0I4QixRQUFBQSxnQkFGNkI7QUFHN0JrQyxRQUFBQSxZQUFZLEVBQUVuQztBQUhlLE9BQXhCLENBQVA7QUFSSjtBQWNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGF1dGhEYXRhTWFuYWdlciBmcm9tICcuLi9BZGFwdGVycy9BdXRoJztcbmltcG9ydCB7IFBhcnNlU2VydmVyT3B0aW9ucyB9IGZyb20gJy4uL09wdGlvbnMnO1xuaW1wb3J0IHsgbG9hZEFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9BZGFwdGVyTG9hZGVyJztcbmltcG9ydCBkZWZhdWx0cyBmcm9tICcuLi9kZWZhdWx0cyc7XG5pbXBvcnQgdXJsIGZyb20gJ3VybCc7XG4vLyBDb250cm9sbGVyc1xuaW1wb3J0IHsgTG9nZ2VyQ29udHJvbGxlciB9IGZyb20gJy4vTG9nZ2VyQ29udHJvbGxlcic7XG5pbXBvcnQgeyBGaWxlc0NvbnRyb2xsZXIgfSBmcm9tICcuL0ZpbGVzQ29udHJvbGxlcic7XG5pbXBvcnQgeyBIb29rc0NvbnRyb2xsZXIgfSBmcm9tICcuL0hvb2tzQ29udHJvbGxlcic7XG5pbXBvcnQgeyBVc2VyQ29udHJvbGxlciB9IGZyb20gJy4vVXNlckNvbnRyb2xsZXInO1xuaW1wb3J0IHsgQ2FjaGVDb250cm9sbGVyIH0gZnJvbSAnLi9DYWNoZUNvbnRyb2xsZXInO1xuaW1wb3J0IHsgTGl2ZVF1ZXJ5Q29udHJvbGxlciB9IGZyb20gJy4vTGl2ZVF1ZXJ5Q29udHJvbGxlcic7XG5pbXBvcnQgeyBBbmFseXRpY3NDb250cm9sbGVyIH0gZnJvbSAnLi9BbmFseXRpY3NDb250cm9sbGVyJztcbmltcG9ydCB7IFB1c2hDb250cm9sbGVyIH0gZnJvbSAnLi9QdXNoQ29udHJvbGxlcic7XG5pbXBvcnQgeyBQdXNoUXVldWUgfSBmcm9tICcuLi9QdXNoL1B1c2hRdWV1ZSc7XG5pbXBvcnQgeyBQdXNoV29ya2VyIH0gZnJvbSAnLi4vUHVzaC9QdXNoV29ya2VyJztcbmltcG9ydCBEYXRhYmFzZUNvbnRyb2xsZXIgZnJvbSAnLi9EYXRhYmFzZUNvbnRyb2xsZXInO1xuaW1wb3J0IFNjaGVtYUNhY2hlIGZyb20gJy4vU2NoZW1hQ2FjaGUnO1xuXG4vLyBBZGFwdGVyc1xuaW1wb3J0IHsgR3JpZEZTQnVja2V0QWRhcHRlciB9IGZyb20gJy4uL0FkYXB0ZXJzL0ZpbGVzL0dyaWRGU0J1Y2tldEFkYXB0ZXInO1xuaW1wb3J0IHsgV2luc3RvbkxvZ2dlckFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9Mb2dnZXIvV2luc3RvbkxvZ2dlckFkYXB0ZXInO1xuaW1wb3J0IHsgSW5NZW1vcnlDYWNoZUFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9DYWNoZS9Jbk1lbW9yeUNhY2hlQWRhcHRlcic7XG5pbXBvcnQgeyBBbmFseXRpY3NBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvQW5hbHl0aWNzL0FuYWx5dGljc0FkYXB0ZXInO1xuaW1wb3J0IE1vbmdvU3RvcmFnZUFkYXB0ZXIgZnJvbSAnLi4vQWRhcHRlcnMvU3RvcmFnZS9Nb25nby9Nb25nb1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCBQb3N0Z3Jlc1N0b3JhZ2VBZGFwdGVyIGZyb20gJy4uL0FkYXB0ZXJzL1N0b3JhZ2UvUG9zdGdyZXMvUG9zdGdyZXNTdG9yYWdlQWRhcHRlcic7XG5pbXBvcnQgUGFyc2VQdXNoQWRhcHRlciBmcm9tICdAcGFyc2UvcHVzaC1hZGFwdGVyJztcbmltcG9ydCBQYXJzZUdyYXBoUUxDb250cm9sbGVyIGZyb20gJy4vUGFyc2VHcmFwaFFMQ29udHJvbGxlcic7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb250cm9sbGVycyhvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMpIHtcbiAgY29uc3QgbG9nZ2VyQ29udHJvbGxlciA9IGdldExvZ2dlckNvbnRyb2xsZXIob3B0aW9ucyk7XG4gIGNvbnN0IGZpbGVzQ29udHJvbGxlciA9IGdldEZpbGVzQ29udHJvbGxlcihvcHRpb25zKTtcbiAgY29uc3QgdXNlckNvbnRyb2xsZXIgPSBnZXRVc2VyQ29udHJvbGxlcihvcHRpb25zKTtcbiAgY29uc3Qge1xuICAgIHB1c2hDb250cm9sbGVyLFxuICAgIGhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0LFxuICAgIGhhc1B1c2hTdXBwb3J0LFxuICAgIHB1c2hDb250cm9sbGVyUXVldWUsXG4gICAgcHVzaFdvcmtlcixcbiAgfSA9IGdldFB1c2hDb250cm9sbGVyKG9wdGlvbnMpO1xuICBjb25zdCBjYWNoZUNvbnRyb2xsZXIgPSBnZXRDYWNoZUNvbnRyb2xsZXIob3B0aW9ucyk7XG4gIGNvbnN0IGFuYWx5dGljc0NvbnRyb2xsZXIgPSBnZXRBbmFseXRpY3NDb250cm9sbGVyKG9wdGlvbnMpO1xuICBjb25zdCBsaXZlUXVlcnlDb250cm9sbGVyID0gZ2V0TGl2ZVF1ZXJ5Q29udHJvbGxlcihvcHRpb25zKTtcbiAgY29uc3QgZGF0YWJhc2VDb250cm9sbGVyID0gZ2V0RGF0YWJhc2VDb250cm9sbGVyKG9wdGlvbnMsIGNhY2hlQ29udHJvbGxlcik7XG4gIGNvbnN0IGhvb2tzQ29udHJvbGxlciA9IGdldEhvb2tzQ29udHJvbGxlcihvcHRpb25zLCBkYXRhYmFzZUNvbnRyb2xsZXIpO1xuICBjb25zdCBhdXRoRGF0YU1hbmFnZXIgPSBnZXRBdXRoRGF0YU1hbmFnZXIob3B0aW9ucyk7XG4gIGNvbnN0IHBhcnNlR3JhcGhRTENvbnRyb2xsZXIgPSBnZXRQYXJzZUdyYXBoUUxDb250cm9sbGVyKG9wdGlvbnMsIHtcbiAgICBkYXRhYmFzZUNvbnRyb2xsZXIsXG4gICAgY2FjaGVDb250cm9sbGVyLFxuICB9KTtcbiAgcmV0dXJuIHtcbiAgICBsb2dnZXJDb250cm9sbGVyLFxuICAgIGZpbGVzQ29udHJvbGxlcixcbiAgICB1c2VyQ29udHJvbGxlcixcbiAgICBwdXNoQ29udHJvbGxlcixcbiAgICBoYXNQdXNoU2NoZWR1bGVkU3VwcG9ydCxcbiAgICBoYXNQdXNoU3VwcG9ydCxcbiAgICBwdXNoV29ya2VyLFxuICAgIHB1c2hDb250cm9sbGVyUXVldWUsXG4gICAgYW5hbHl0aWNzQ29udHJvbGxlcixcbiAgICBjYWNoZUNvbnRyb2xsZXIsXG4gICAgcGFyc2VHcmFwaFFMQ29udHJvbGxlcixcbiAgICBsaXZlUXVlcnlDb250cm9sbGVyLFxuICAgIGRhdGFiYXNlQ29udHJvbGxlcixcbiAgICBob29rc0NvbnRyb2xsZXIsXG4gICAgYXV0aERhdGFNYW5hZ2VyLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TG9nZ2VyQ29udHJvbGxlcihvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMpOiBMb2dnZXJDb250cm9sbGVyIHtcbiAgY29uc3Qge1xuICAgIGFwcElkLFxuICAgIGpzb25Mb2dzLFxuICAgIGxvZ3NGb2xkZXIsXG4gICAgdmVyYm9zZSxcbiAgICBsb2dMZXZlbCxcbiAgICBtYXhMb2dGaWxlcyxcbiAgICBzaWxlbnQsXG4gICAgbG9nZ2VyQWRhcHRlcixcbiAgfSA9IG9wdGlvbnM7XG4gIGNvbnN0IGxvZ2dlck9wdGlvbnMgPSB7XG4gICAganNvbkxvZ3MsXG4gICAgbG9nc0ZvbGRlcixcbiAgICB2ZXJib3NlLFxuICAgIGxvZ0xldmVsLFxuICAgIHNpbGVudCxcbiAgICBtYXhMb2dGaWxlcyxcbiAgfTtcbiAgY29uc3QgbG9nZ2VyQ29udHJvbGxlckFkYXB0ZXIgPSBsb2FkQWRhcHRlcihsb2dnZXJBZGFwdGVyLCBXaW5zdG9uTG9nZ2VyQWRhcHRlciwgbG9nZ2VyT3B0aW9ucyk7XG4gIHJldHVybiBuZXcgTG9nZ2VyQ29udHJvbGxlcihsb2dnZXJDb250cm9sbGVyQWRhcHRlciwgYXBwSWQsIGxvZ2dlck9wdGlvbnMpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmlsZXNDb250cm9sbGVyKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucyk6IEZpbGVzQ29udHJvbGxlciB7XG4gIGNvbnN0IHsgYXBwSWQsIGRhdGFiYXNlVVJJLCBmaWxlc0FkYXB0ZXIsIGRhdGFiYXNlQWRhcHRlciwgcHJlc2VydmVGaWxlTmFtZSwgZmlsZUtleSB9ID0gb3B0aW9ucztcbiAgaWYgKCFmaWxlc0FkYXB0ZXIgJiYgZGF0YWJhc2VBZGFwdGVyKSB7XG4gICAgdGhyb3cgJ1doZW4gdXNpbmcgYW4gZXhwbGljaXQgZGF0YWJhc2UgYWRhcHRlciwgeW91IG11c3QgYWxzbyB1c2UgYW4gZXhwbGljaXQgZmlsZXNBZGFwdGVyLic7XG4gIH1cbiAgY29uc3QgZmlsZXNDb250cm9sbGVyQWRhcHRlciA9IGxvYWRBZGFwdGVyKGZpbGVzQWRhcHRlciwgKCkgPT4ge1xuICAgIHJldHVybiBuZXcgR3JpZEZTQnVja2V0QWRhcHRlcihkYXRhYmFzZVVSSSwge30sIGZpbGVLZXkpO1xuICB9KTtcbiAgcmV0dXJuIG5ldyBGaWxlc0NvbnRyb2xsZXIoZmlsZXNDb250cm9sbGVyQWRhcHRlciwgYXBwSWQsIHtcbiAgICBwcmVzZXJ2ZUZpbGVOYW1lLFxuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFVzZXJDb250cm9sbGVyKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucyk6IFVzZXJDb250cm9sbGVyIHtcbiAgY29uc3QgeyBhcHBJZCwgZW1haWxBZGFwdGVyLCB2ZXJpZnlVc2VyRW1haWxzIH0gPSBvcHRpb25zO1xuICBjb25zdCBlbWFpbENvbnRyb2xsZXJBZGFwdGVyID0gbG9hZEFkYXB0ZXIoZW1haWxBZGFwdGVyKTtcbiAgcmV0dXJuIG5ldyBVc2VyQ29udHJvbGxlcihlbWFpbENvbnRyb2xsZXJBZGFwdGVyLCBhcHBJZCwge1xuICAgIHZlcmlmeVVzZXJFbWFpbHMsXG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2FjaGVDb250cm9sbGVyKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucyk6IENhY2hlQ29udHJvbGxlciB7XG4gIGNvbnN0IHsgYXBwSWQsIGNhY2hlQWRhcHRlciwgY2FjaGVUVEwsIGNhY2hlTWF4U2l6ZSB9ID0gb3B0aW9ucztcbiAgY29uc3QgY2FjaGVDb250cm9sbGVyQWRhcHRlciA9IGxvYWRBZGFwdGVyKGNhY2hlQWRhcHRlciwgSW5NZW1vcnlDYWNoZUFkYXB0ZXIsIHtcbiAgICBhcHBJZDogYXBwSWQsXG4gICAgdHRsOiBjYWNoZVRUTCxcbiAgICBtYXhTaXplOiBjYWNoZU1heFNpemUsXG4gIH0pO1xuICByZXR1cm4gbmV3IENhY2hlQ29udHJvbGxlcihjYWNoZUNvbnRyb2xsZXJBZGFwdGVyLCBhcHBJZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQYXJzZUdyYXBoUUxDb250cm9sbGVyKFxuICBvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMsXG4gIGNvbnRyb2xsZXJEZXBzXG4pOiBQYXJzZUdyYXBoUUxDb250cm9sbGVyIHtcbiAgcmV0dXJuIG5ldyBQYXJzZUdyYXBoUUxDb250cm9sbGVyKHtcbiAgICBtb3VudEdyYXBoUUw6IG9wdGlvbnMubW91bnRHcmFwaFFMLFxuICAgIC4uLmNvbnRyb2xsZXJEZXBzLFxuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEFuYWx5dGljc0NvbnRyb2xsZXIob3B0aW9uczogUGFyc2VTZXJ2ZXJPcHRpb25zKTogQW5hbHl0aWNzQ29udHJvbGxlciB7XG4gIGNvbnN0IHsgYW5hbHl0aWNzQWRhcHRlciB9ID0gb3B0aW9ucztcbiAgY29uc3QgYW5hbHl0aWNzQ29udHJvbGxlckFkYXB0ZXIgPSBsb2FkQWRhcHRlcihhbmFseXRpY3NBZGFwdGVyLCBBbmFseXRpY3NBZGFwdGVyKTtcbiAgcmV0dXJuIG5ldyBBbmFseXRpY3NDb250cm9sbGVyKGFuYWx5dGljc0NvbnRyb2xsZXJBZGFwdGVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldExpdmVRdWVyeUNvbnRyb2xsZXIob3B0aW9uczogUGFyc2VTZXJ2ZXJPcHRpb25zKTogTGl2ZVF1ZXJ5Q29udHJvbGxlciB7XG4gIHJldHVybiBuZXcgTGl2ZVF1ZXJ5Q29udHJvbGxlcihvcHRpb25zLmxpdmVRdWVyeSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREYXRhYmFzZUNvbnRyb2xsZXIoXG4gIG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucyxcbiAgY2FjaGVDb250cm9sbGVyOiBDYWNoZUNvbnRyb2xsZXJcbik6IERhdGFiYXNlQ29udHJvbGxlciB7XG4gIGNvbnN0IHtcbiAgICBkYXRhYmFzZVVSSSxcbiAgICBkYXRhYmFzZU9wdGlvbnMsXG4gICAgY29sbGVjdGlvblByZWZpeCxcbiAgICBzY2hlbWFDYWNoZVRUTCxcbiAgICBlbmFibGVTaW5nbGVTY2hlbWFDYWNoZSxcbiAgfSA9IG9wdGlvbnM7XG4gIGxldCB7IGRhdGFiYXNlQWRhcHRlciB9ID0gb3B0aW9ucztcbiAgaWYgKFxuICAgIChkYXRhYmFzZU9wdGlvbnMgfHxcbiAgICAgIChkYXRhYmFzZVVSSSAmJiBkYXRhYmFzZVVSSSAhPT0gZGVmYXVsdHMuZGF0YWJhc2VVUkkpIHx8XG4gICAgICBjb2xsZWN0aW9uUHJlZml4ICE9PSBkZWZhdWx0cy5jb2xsZWN0aW9uUHJlZml4KSAmJlxuICAgIGRhdGFiYXNlQWRhcHRlclxuICApIHtcbiAgICB0aHJvdyAnWW91IGNhbm5vdCBzcGVjaWZ5IGJvdGggYSBkYXRhYmFzZUFkYXB0ZXIgYW5kIGEgZGF0YWJhc2VVUkkvZGF0YWJhc2VPcHRpb25zL2NvbGxlY3Rpb25QcmVmaXguJztcbiAgfSBlbHNlIGlmICghZGF0YWJhc2VBZGFwdGVyKSB7XG4gICAgZGF0YWJhc2VBZGFwdGVyID0gZ2V0RGF0YWJhc2VBZGFwdGVyKGRhdGFiYXNlVVJJLCBjb2xsZWN0aW9uUHJlZml4LCBkYXRhYmFzZU9wdGlvbnMpO1xuICB9IGVsc2Uge1xuICAgIGRhdGFiYXNlQWRhcHRlciA9IGxvYWRBZGFwdGVyKGRhdGFiYXNlQWRhcHRlcik7XG4gIH1cbiAgcmV0dXJuIG5ldyBEYXRhYmFzZUNvbnRyb2xsZXIoXG4gICAgZGF0YWJhc2VBZGFwdGVyLFxuICAgIG5ldyBTY2hlbWFDYWNoZShjYWNoZUNvbnRyb2xsZXIsIHNjaGVtYUNhY2hlVFRMLCBlbmFibGVTaW5nbGVTY2hlbWFDYWNoZSlcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEhvb2tzQ29udHJvbGxlcihcbiAgb3B0aW9uczogUGFyc2VTZXJ2ZXJPcHRpb25zLFxuICBkYXRhYmFzZUNvbnRyb2xsZXI6IERhdGFiYXNlQ29udHJvbGxlclxuKTogSG9va3NDb250cm9sbGVyIHtcbiAgY29uc3QgeyBhcHBJZCwgd2ViaG9va0tleSB9ID0gb3B0aW9ucztcbiAgcmV0dXJuIG5ldyBIb29rc0NvbnRyb2xsZXIoYXBwSWQsIGRhdGFiYXNlQ29udHJvbGxlciwgd2ViaG9va0tleSk7XG59XG5cbmludGVyZmFjZSBQdXNoQ29udHJvbGxpbmcge1xuICBwdXNoQ29udHJvbGxlcjogUHVzaENvbnRyb2xsZXI7XG4gIGhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0OiBib29sZWFuO1xuICBwdXNoQ29udHJvbGxlclF1ZXVlOiBQdXNoUXVldWU7XG4gIHB1c2hXb3JrZXI6IFB1c2hXb3JrZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRQdXNoQ29udHJvbGxlcihvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMpOiBQdXNoQ29udHJvbGxpbmcge1xuICBjb25zdCB7IHNjaGVkdWxlZFB1c2gsIHB1c2ggfSA9IG9wdGlvbnM7XG5cbiAgY29uc3QgcHVzaE9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBwdXNoKTtcbiAgY29uc3QgcHVzaFF1ZXVlT3B0aW9ucyA9IHB1c2hPcHRpb25zLnF1ZXVlT3B0aW9ucyB8fCB7fTtcbiAgaWYgKHB1c2hPcHRpb25zLnF1ZXVlT3B0aW9ucykge1xuICAgIGRlbGV0ZSBwdXNoT3B0aW9ucy5xdWV1ZU9wdGlvbnM7XG4gIH1cblxuICAvLyBQYXNzIHRoZSBwdXNoIG9wdGlvbnMgdG9vIGFzIGl0IHdvcmtzIHdpdGggdGhlIGRlZmF1bHRcbiAgY29uc3QgcHVzaEFkYXB0ZXIgPSBsb2FkQWRhcHRlcihcbiAgICBwdXNoT3B0aW9ucyAmJiBwdXNoT3B0aW9ucy5hZGFwdGVyLFxuICAgIFBhcnNlUHVzaEFkYXB0ZXIsXG4gICAgcHVzaE9wdGlvbnNcbiAgKTtcbiAgLy8gV2UgcGFzcyB0aGUgb3B0aW9ucyBhbmQgdGhlIGJhc2UgY2xhc3MgZm9yIHRoZSBhZGF0cGVyLFxuICAvLyBOb3RlIHRoYXQgcGFzc2luZyBhbiBpbnN0YW5jZSB3b3VsZCB3b3JrIHRvb1xuICBjb25zdCBwdXNoQ29udHJvbGxlciA9IG5ldyBQdXNoQ29udHJvbGxlcigpO1xuICBjb25zdCBoYXNQdXNoU3VwcG9ydCA9ICEhKHB1c2hBZGFwdGVyICYmIHB1c2gpO1xuICBjb25zdCBoYXNQdXNoU2NoZWR1bGVkU3VwcG9ydCA9IGhhc1B1c2hTdXBwb3J0ICYmIHNjaGVkdWxlZFB1c2ggPT09IHRydWU7XG5cbiAgY29uc3QgeyBkaXNhYmxlUHVzaFdvcmtlciB9ID0gcHVzaFF1ZXVlT3B0aW9ucztcblxuICBjb25zdCBwdXNoQ29udHJvbGxlclF1ZXVlID0gbmV3IFB1c2hRdWV1ZShwdXNoUXVldWVPcHRpb25zKTtcbiAgbGV0IHB1c2hXb3JrZXI7XG4gIGlmICghZGlzYWJsZVB1c2hXb3JrZXIpIHtcbiAgICBwdXNoV29ya2VyID0gbmV3IFB1c2hXb3JrZXIocHVzaEFkYXB0ZXIsIHB1c2hRdWV1ZU9wdGlvbnMpO1xuICB9XG4gIHJldHVybiB7XG4gICAgcHVzaENvbnRyb2xsZXIsXG4gICAgaGFzUHVzaFN1cHBvcnQsXG4gICAgaGFzUHVzaFNjaGVkdWxlZFN1cHBvcnQsXG4gICAgcHVzaENvbnRyb2xsZXJRdWV1ZSxcbiAgICBwdXNoV29ya2VyLFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXV0aERhdGFNYW5hZ2VyKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucykge1xuICBjb25zdCB7IGF1dGgsIGVuYWJsZUFub255bW91c1VzZXJzIH0gPSBvcHRpb25zO1xuICByZXR1cm4gYXV0aERhdGFNYW5hZ2VyKGF1dGgsIGVuYWJsZUFub255bW91c1VzZXJzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERhdGFiYXNlQWRhcHRlcihkYXRhYmFzZVVSSSwgY29sbGVjdGlvblByZWZpeCwgZGF0YWJhc2VPcHRpb25zKSB7XG4gIGxldCBwcm90b2NvbDtcbiAgdHJ5IHtcbiAgICBjb25zdCBwYXJzZWRVUkkgPSB1cmwucGFyc2UoZGF0YWJhc2VVUkkpO1xuICAgIHByb3RvY29sID0gcGFyc2VkVVJJLnByb3RvY29sID8gcGFyc2VkVVJJLnByb3RvY29sLnRvTG93ZXJDYXNlKCkgOiBudWxsO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLyogKi9cbiAgfVxuICBzd2l0Y2ggKHByb3RvY29sKSB7XG4gICAgY2FzZSAncG9zdGdyZXM6JzpcbiAgICAgIHJldHVybiBuZXcgUG9zdGdyZXNTdG9yYWdlQWRhcHRlcih7XG4gICAgICAgIHVyaTogZGF0YWJhc2VVUkksXG4gICAgICAgIGNvbGxlY3Rpb25QcmVmaXgsXG4gICAgICAgIGRhdGFiYXNlT3B0aW9ucyxcbiAgICAgIH0pO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gbmV3IE1vbmdvU3RvcmFnZUFkYXB0ZXIoe1xuICAgICAgICB1cmk6IGRhdGFiYXNlVVJJLFxuICAgICAgICBjb2xsZWN0aW9uUHJlZml4LFxuICAgICAgICBtb25nb09wdGlvbnM6IGRhdGFiYXNlT3B0aW9ucyxcbiAgICAgIH0pO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Controllers/types.js b/lib/Controllers/types.js deleted file mode 100644 index 4310b4ffac..0000000000 --- a/lib/Controllers/types.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbXX0= \ No newline at end of file diff --git a/lib/GraphQL/ParseGraphQLSchema.js b/lib/GraphQL/ParseGraphQLSchema.js deleted file mode 100644 index 874d8fb3ef..0000000000 --- a/lib/GraphQL/ParseGraphQLSchema.js +++ /dev/null @@ -1,446 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.ParseGraphQLSchema = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _graphql = require("graphql"); - -var _stitch = require("@graphql-tools/stitch"); - -var _utils = require("@graphql-tools/utils"); - -var _requiredParameter = _interopRequireDefault(require("../requiredParameter")); - -var defaultGraphQLTypes = _interopRequireWildcard(require("./loaders/defaultGraphQLTypes")); - -var parseClassTypes = _interopRequireWildcard(require("./loaders/parseClassTypes")); - -var parseClassQueries = _interopRequireWildcard(require("./loaders/parseClassQueries")); - -var parseClassMutations = _interopRequireWildcard(require("./loaders/parseClassMutations")); - -var defaultGraphQLQueries = _interopRequireWildcard(require("./loaders/defaultGraphQLQueries")); - -var defaultGraphQLMutations = _interopRequireWildcard(require("./loaders/defaultGraphQLMutations")); - -var _ParseGraphQLController = _interopRequireWildcard(require("../Controllers/ParseGraphQLController")); - -var _DatabaseController = _interopRequireDefault(require("../Controllers/DatabaseController")); - -var _parseGraphQLUtils = require("./parseGraphQLUtils"); - -var schemaDirectives = _interopRequireWildcard(require("./loaders/schemaDirectives")); - -var schemaTypes = _interopRequireWildcard(require("./loaders/schemaTypes")); - -var _triggers = require("../triggers"); - -var defaultRelaySchema = _interopRequireWildcard(require("./loaders/defaultRelaySchema")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const RESERVED_GRAPHQL_TYPE_NAMES = ['String', 'Boolean', 'Int', 'Float', 'ID', 'ArrayResult', 'Query', 'Mutation', 'Subscription', 'CreateFileInput', 'CreateFilePayload', 'Viewer', 'SignUpInput', 'SignUpPayload', 'LogInInput', 'LogInPayload', 'LogOutInput', 'LogOutPayload', 'CloudCodeFunction', 'CallCloudCodeInput', 'CallCloudCodePayload', 'CreateClassInput', 'CreateClassPayload', 'UpdateClassInput', 'UpdateClassPayload', 'DeleteClassInput', 'DeleteClassPayload', 'PageInfo']; -const RESERVED_GRAPHQL_QUERY_NAMES = ['health', 'viewer', 'class', 'classes']; -const RESERVED_GRAPHQL_MUTATION_NAMES = ['signUp', 'logIn', 'logOut', 'createFile', 'callCloudCode', 'createClass', 'updateClass', 'deleteClass']; - -class ParseGraphQLSchema { - constructor(params = {}) { - this.parseGraphQLController = params.parseGraphQLController || (0, _requiredParameter.default)('You must provide a parseGraphQLController instance!'); - this.databaseController = params.databaseController || (0, _requiredParameter.default)('You must provide a databaseController instance!'); - this.log = params.log || (0, _requiredParameter.default)('You must provide a log instance!'); - this.graphQLCustomTypeDefs = params.graphQLCustomTypeDefs; - this.appId = params.appId || (0, _requiredParameter.default)('You must provide the appId!'); - } - - async load() { - const { - parseGraphQLConfig - } = await this._initializeSchemaAndConfig(); - const parseClasses = await this._getClassesForSchema(parseGraphQLConfig); - const parseClassesString = JSON.stringify(parseClasses); - const functionNames = await this._getFunctionNames(); - const functionNamesString = JSON.stringify(functionNames); - - if (this.graphQLSchema && !this._hasSchemaInputChanged({ - parseClasses, - parseClassesString, - parseGraphQLConfig, - functionNamesString - })) { - return this.graphQLSchema; - } - - this.parseClasses = parseClasses; - this.parseClassesString = parseClassesString; - this.parseGraphQLConfig = parseGraphQLConfig; - this.functionNames = functionNames; - this.functionNamesString = functionNamesString; - this.parseClassTypes = {}; - this.viewerType = null; - this.graphQLAutoSchema = null; - this.graphQLSchema = null; - this.graphQLTypes = []; - this.graphQLQueries = {}; - this.graphQLMutations = {}; - this.graphQLSubscriptions = {}; - this.graphQLSchemaDirectivesDefinitions = null; - this.graphQLSchemaDirectives = {}; - this.relayNodeInterface = null; - defaultGraphQLTypes.load(this); - defaultRelaySchema.load(this); - schemaTypes.load(this); - - this._getParseClassesWithConfig(parseClasses, parseGraphQLConfig).forEach(([parseClass, parseClassConfig]) => { - parseClassTypes.load(this, parseClass, parseClassConfig); - parseClassQueries.load(this, parseClass, parseClassConfig); - parseClassMutations.load(this, parseClass, parseClassConfig); - }); - - defaultGraphQLTypes.loadArrayResult(this, parseClasses); - defaultGraphQLQueries.load(this); - defaultGraphQLMutations.load(this); - let graphQLQuery = undefined; - - if (Object.keys(this.graphQLQueries).length > 0) { - graphQLQuery = new _graphql.GraphQLObjectType({ - name: 'Query', - description: 'Query is the top level type for queries.', - fields: this.graphQLQueries - }); - this.addGraphQLType(graphQLQuery, true, true); - } - - let graphQLMutation = undefined; - - if (Object.keys(this.graphQLMutations).length > 0) { - graphQLMutation = new _graphql.GraphQLObjectType({ - name: 'Mutation', - description: 'Mutation is the top level type for mutations.', - fields: this.graphQLMutations - }); - this.addGraphQLType(graphQLMutation, true, true); - } - - let graphQLSubscription = undefined; - - if (Object.keys(this.graphQLSubscriptions).length > 0) { - graphQLSubscription = new _graphql.GraphQLObjectType({ - name: 'Subscription', - description: 'Subscription is the top level type for subscriptions.', - fields: this.graphQLSubscriptions - }); - this.addGraphQLType(graphQLSubscription, true, true); - } - - this.graphQLAutoSchema = new _graphql.GraphQLSchema({ - types: this.graphQLTypes, - query: graphQLQuery, - mutation: graphQLMutation, - subscription: graphQLSubscription - }); - - if (this.graphQLCustomTypeDefs) { - schemaDirectives.load(this); - - if (typeof this.graphQLCustomTypeDefs.getTypeMap === 'function') { - const customGraphQLSchemaTypeMap = this.graphQLCustomTypeDefs.getTypeMap(); - - const findAndReplaceLastType = (parent, key) => { - if (parent[key].name) { - if (this.graphQLAutoSchema.getType(parent[key].name) && this.graphQLAutoSchema.getType(parent[key].name) !== parent[key]) { - // To avoid unresolved field on overloaded schema - // replace the final type with the auto schema one - parent[key] = this.graphQLAutoSchema.getType(parent[key].name); - } - } else { - if (parent[key].ofType) { - findAndReplaceLastType(parent[key], 'ofType'); - } - } - }; - - Object.values(customGraphQLSchemaTypeMap).forEach(customGraphQLSchemaType => { - if (!customGraphQLSchemaType || !customGraphQLSchemaType.name || customGraphQLSchemaType.name.startsWith('__')) { - return; - } - - const autoGraphQLSchemaType = this.graphQLAutoSchema.getType(customGraphQLSchemaType.name); - - if (!autoGraphQLSchemaType) { - this.graphQLAutoSchema._typeMap[customGraphQLSchemaType.name] = customGraphQLSchemaType; - } - }); - Object.values(customGraphQLSchemaTypeMap).forEach(customGraphQLSchemaType => { - if (!customGraphQLSchemaType || !customGraphQLSchemaType.name || customGraphQLSchemaType.name.startsWith('__')) { - return; - } - - const autoGraphQLSchemaType = this.graphQLAutoSchema.getType(customGraphQLSchemaType.name); - - if (autoGraphQLSchemaType && typeof customGraphQLSchemaType.getFields === 'function') { - Object.values(customGraphQLSchemaType.getFields()).forEach(field => { - findAndReplaceLastType(field, 'type'); - }); - autoGraphQLSchemaType._fields = _objectSpread(_objectSpread({}, autoGraphQLSchemaType.getFields()), customGraphQLSchemaType.getFields()); - } - }); - this.graphQLSchema = (0, _stitch.stitchSchemas)({ - schemas: [this.graphQLSchemaDirectivesDefinitions, this.graphQLAutoSchema], - mergeDirectives: true - }); - } else if (typeof this.graphQLCustomTypeDefs === 'function') { - this.graphQLSchema = await this.graphQLCustomTypeDefs({ - directivesDefinitionsSchema: this.graphQLSchemaDirectivesDefinitions, - autoSchema: this.graphQLAutoSchema, - stitchSchemas: _stitch.stitchSchemas - }); - } else { - this.graphQLSchema = (0, _stitch.stitchSchemas)({ - schemas: [this.graphQLSchemaDirectivesDefinitions, this.graphQLAutoSchema, this.graphQLCustomTypeDefs], - mergeDirectives: true - }); - } - - const graphQLSchemaTypeMap = this.graphQLSchema.getTypeMap(); - Object.keys(graphQLSchemaTypeMap).forEach(graphQLSchemaTypeName => { - const graphQLSchemaType = graphQLSchemaTypeMap[graphQLSchemaTypeName]; - - if (typeof graphQLSchemaType.getFields === 'function' && this.graphQLCustomTypeDefs.definitions) { - const graphQLCustomTypeDef = this.graphQLCustomTypeDefs.definitions.find(definition => definition.name.value === graphQLSchemaTypeName); - - if (graphQLCustomTypeDef) { - const graphQLSchemaTypeFieldMap = graphQLSchemaType.getFields(); - Object.keys(graphQLSchemaTypeFieldMap).forEach(graphQLSchemaTypeFieldName => { - const graphQLSchemaTypeField = graphQLSchemaTypeFieldMap[graphQLSchemaTypeFieldName]; - - if (!graphQLSchemaTypeField.astNode) { - const astNode = graphQLCustomTypeDef.fields.find(field => field.name.value === graphQLSchemaTypeFieldName); - - if (astNode) { - graphQLSchemaTypeField.astNode = astNode; - } - } - }); - } - } - }); - - _utils.SchemaDirectiveVisitor.visitSchemaDirectives(this.graphQLSchema, this.graphQLSchemaDirectives); - } else { - this.graphQLSchema = this.graphQLAutoSchema; - } - - return this.graphQLSchema; - } - - addGraphQLType(type, throwError = false, ignoreReserved = false, ignoreConnection = false) { - if (!ignoreReserved && RESERVED_GRAPHQL_TYPE_NAMES.includes(type.name) || this.graphQLTypes.find(existingType => existingType.name === type.name) || !ignoreConnection && type.name.endsWith('Connection')) { - const message = `Type ${type.name} could not be added to the auto schema because it collided with an existing type.`; - - if (throwError) { - throw new Error(message); - } - - this.log.warn(message); - return undefined; - } - - this.graphQLTypes.push(type); - return type; - } - - addGraphQLQuery(fieldName, field, throwError = false, ignoreReserved = false) { - if (!ignoreReserved && RESERVED_GRAPHQL_QUERY_NAMES.includes(fieldName) || this.graphQLQueries[fieldName]) { - const message = `Query ${fieldName} could not be added to the auto schema because it collided with an existing field.`; - - if (throwError) { - throw new Error(message); - } - - this.log.warn(message); - return undefined; - } - - this.graphQLQueries[fieldName] = field; - return field; - } - - addGraphQLMutation(fieldName, field, throwError = false, ignoreReserved = false) { - if (!ignoreReserved && RESERVED_GRAPHQL_MUTATION_NAMES.includes(fieldName) || this.graphQLMutations[fieldName]) { - const message = `Mutation ${fieldName} could not be added to the auto schema because it collided with an existing field.`; - - if (throwError) { - throw new Error(message); - } - - this.log.warn(message); - return undefined; - } - - this.graphQLMutations[fieldName] = field; - return field; - } - - handleError(error) { - if (error instanceof _node.default.Error) { - this.log.error('Parse error: ', error); - } else { - this.log.error('Uncaught internal server error.', error, error.stack); - } - - throw (0, _parseGraphQLUtils.toGraphQLError)(error); - } - - async _initializeSchemaAndConfig() { - const [schemaController, parseGraphQLConfig] = await Promise.all([this.databaseController.loadSchema(), this.parseGraphQLController.getGraphQLConfig()]); - this.schemaController = schemaController; - return { - parseGraphQLConfig - }; - } - /** - * Gets all classes found by the `schemaController` - * minus those filtered out by the app's parseGraphQLConfig. - */ - - - async _getClassesForSchema(parseGraphQLConfig) { - const { - enabledForClasses, - disabledForClasses - } = parseGraphQLConfig; - const allClasses = await this.schemaController.getAllClasses(); - - if (Array.isArray(enabledForClasses) || Array.isArray(disabledForClasses)) { - let includedClasses = allClasses; - - if (enabledForClasses) { - includedClasses = allClasses.filter(clazz => { - return enabledForClasses.includes(clazz.className); - }); - } - - if (disabledForClasses) { - // Classes included in `enabledForClasses` that - // are also present in `disabledForClasses` will - // still be filtered out - includedClasses = includedClasses.filter(clazz => { - return !disabledForClasses.includes(clazz.className); - }); - } - - this.isUsersClassDisabled = !includedClasses.some(clazz => { - return clazz.className === '_User'; - }); - return includedClasses; - } else { - return allClasses; - } - } - /** - * This method returns a list of tuples - * that provide the parseClass along with - * its parseClassConfig where provided. - */ - - - _getParseClassesWithConfig(parseClasses, parseGraphQLConfig) { - const { - classConfigs - } = parseGraphQLConfig; // Make sures that the default classes and classes that - // starts with capitalized letter will be generated first. - - const sortClasses = (a, b) => { - a = a.className; - b = b.className; - - if (a[0] === '_') { - if (b[0] !== '_') { - return -1; - } - } - - if (b[0] === '_') { - if (a[0] !== '_') { - return 1; - } - } - - if (a === b) { - return 0; - } else if (a < b) { - return -1; - } else { - return 1; - } - }; - - return parseClasses.sort(sortClasses).map(parseClass => { - let parseClassConfig; - - if (classConfigs) { - parseClassConfig = classConfigs.find(c => c.className === parseClass.className); - } - - return [parseClass, parseClassConfig]; - }); - } - - async _getFunctionNames() { - return await (0, _triggers.getFunctionNames)(this.appId).filter(functionName => { - if (/^[_a-zA-Z][_a-zA-Z0-9]*$/.test(functionName)) { - return true; - } else { - this.log.warn(`Function ${functionName} could not be added to the auto schema because GraphQL names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/.`); - return false; - } - }); - } - /** - * Checks for changes to the parseClasses - * objects (i.e. database schema) or to - * the parseGraphQLConfig object. If no - * changes are found, return true; - */ - - - _hasSchemaInputChanged(params) { - const { - parseClasses, - parseClassesString, - parseGraphQLConfig, - functionNamesString - } = params; - - if (JSON.stringify(this.parseGraphQLConfig) === JSON.stringify(parseGraphQLConfig) && this.functionNamesString === functionNamesString) { - if (this.parseClasses === parseClasses) { - return false; - } - - if (this.parseClassesString === parseClassesString) { - this.parseClasses = parseClasses; - return false; - } - } - - return true; - } - -} - -exports.ParseGraphQLSchema = ParseGraphQLSchema; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9HcmFwaFFML1BhcnNlR3JhcGhRTFNjaGVtYS5qcyJdLCJuYW1lcyI6WyJSRVNFUlZFRF9HUkFQSFFMX1RZUEVfTkFNRVMiLCJSRVNFUlZFRF9HUkFQSFFMX1FVRVJZX05BTUVTIiwiUkVTRVJWRURfR1JBUEhRTF9NVVRBVElPTl9OQU1FUyIsIlBhcnNlR3JhcGhRTFNjaGVtYSIsImNvbnN0cnVjdG9yIiwicGFyYW1zIiwicGFyc2VHcmFwaFFMQ29udHJvbGxlciIsImRhdGFiYXNlQ29udHJvbGxlciIsImxvZyIsImdyYXBoUUxDdXN0b21UeXBlRGVmcyIsImFwcElkIiwibG9hZCIsInBhcnNlR3JhcGhRTENvbmZpZyIsIl9pbml0aWFsaXplU2NoZW1hQW5kQ29uZmlnIiwicGFyc2VDbGFzc2VzIiwiX2dldENsYXNzZXNGb3JTY2hlbWEiLCJwYXJzZUNsYXNzZXNTdHJpbmciLCJKU09OIiwic3RyaW5naWZ5IiwiZnVuY3Rpb25OYW1lcyIsIl9nZXRGdW5jdGlvbk5hbWVzIiwiZnVuY3Rpb25OYW1lc1N0cmluZyIsImdyYXBoUUxTY2hlbWEiLCJfaGFzU2NoZW1hSW5wdXRDaGFuZ2VkIiwicGFyc2VDbGFzc1R5cGVzIiwidmlld2VyVHlwZSIsImdyYXBoUUxBdXRvU2NoZW1hIiwiZ3JhcGhRTFR5cGVzIiwiZ3JhcGhRTFF1ZXJpZXMiLCJncmFwaFFMTXV0YXRpb25zIiwiZ3JhcGhRTFN1YnNjcmlwdGlvbnMiLCJncmFwaFFMU2NoZW1hRGlyZWN0aXZlc0RlZmluaXRpb25zIiwiZ3JhcGhRTFNjaGVtYURpcmVjdGl2ZXMiLCJyZWxheU5vZGVJbnRlcmZhY2UiLCJkZWZhdWx0R3JhcGhRTFR5cGVzIiwiZGVmYXVsdFJlbGF5U2NoZW1hIiwic2NoZW1hVHlwZXMiLCJfZ2V0UGFyc2VDbGFzc2VzV2l0aENvbmZpZyIsImZvckVhY2giLCJwYXJzZUNsYXNzIiwicGFyc2VDbGFzc0NvbmZpZyIsInBhcnNlQ2xhc3NRdWVyaWVzIiwicGFyc2VDbGFzc011dGF0aW9ucyIsImxvYWRBcnJheVJlc3VsdCIsImRlZmF1bHRHcmFwaFFMUXVlcmllcyIsImRlZmF1bHRHcmFwaFFMTXV0YXRpb25zIiwiZ3JhcGhRTFF1ZXJ5IiwidW5kZWZpbmVkIiwiT2JqZWN0Iiwia2V5cyIsImxlbmd0aCIsIkdyYXBoUUxPYmplY3RUeXBlIiwibmFtZSIsImRlc2NyaXB0aW9uIiwiZmllbGRzIiwiYWRkR3JhcGhRTFR5cGUiLCJncmFwaFFMTXV0YXRpb24iLCJncmFwaFFMU3Vic2NyaXB0aW9uIiwiR3JhcGhRTFNjaGVtYSIsInR5cGVzIiwicXVlcnkiLCJtdXRhdGlvbiIsInN1YnNjcmlwdGlvbiIsInNjaGVtYURpcmVjdGl2ZXMiLCJnZXRUeXBlTWFwIiwiY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGVNYXAiLCJmaW5kQW5kUmVwbGFjZUxhc3RUeXBlIiwicGFyZW50Iiwia2V5IiwiZ2V0VHlwZSIsIm9mVHlwZSIsInZhbHVlcyIsImN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlIiwic3RhcnRzV2l0aCIsImF1dG9HcmFwaFFMU2NoZW1hVHlwZSIsIl90eXBlTWFwIiwiZ2V0RmllbGRzIiwiZmllbGQiLCJfZmllbGRzIiwic2NoZW1hcyIsIm1lcmdlRGlyZWN0aXZlcyIsImRpcmVjdGl2ZXNEZWZpbml0aW9uc1NjaGVtYSIsImF1dG9TY2hlbWEiLCJzdGl0Y2hTY2hlbWFzIiwiZ3JhcGhRTFNjaGVtYVR5cGVNYXAiLCJncmFwaFFMU2NoZW1hVHlwZU5hbWUiLCJncmFwaFFMU2NoZW1hVHlwZSIsImRlZmluaXRpb25zIiwiZ3JhcGhRTEN1c3RvbVR5cGVEZWYiLCJmaW5kIiwiZGVmaW5pdGlvbiIsInZhbHVlIiwiZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZE1hcCIsImdyYXBoUUxTY2hlbWFUeXBlRmllbGROYW1lIiwiZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZCIsImFzdE5vZGUiLCJTY2hlbWFEaXJlY3RpdmVWaXNpdG9yIiwidmlzaXRTY2hlbWFEaXJlY3RpdmVzIiwidHlwZSIsInRocm93RXJyb3IiLCJpZ25vcmVSZXNlcnZlZCIsImlnbm9yZUNvbm5lY3Rpb24iLCJpbmNsdWRlcyIsImV4aXN0aW5nVHlwZSIsImVuZHNXaXRoIiwibWVzc2FnZSIsIkVycm9yIiwid2FybiIsInB1c2giLCJhZGRHcmFwaFFMUXVlcnkiLCJmaWVsZE5hbWUiLCJhZGRHcmFwaFFMTXV0YXRpb24iLCJoYW5kbGVFcnJvciIsImVycm9yIiwiUGFyc2UiLCJzdGFjayIsInNjaGVtYUNvbnRyb2xsZXIiLCJQcm9taXNlIiwiYWxsIiwibG9hZFNjaGVtYSIsImdldEdyYXBoUUxDb25maWciLCJlbmFibGVkRm9yQ2xhc3NlcyIsImRpc2FibGVkRm9yQ2xhc3NlcyIsImFsbENsYXNzZXMiLCJnZXRBbGxDbGFzc2VzIiwiQXJyYXkiLCJpc0FycmF5IiwiaW5jbHVkZWRDbGFzc2VzIiwiZmlsdGVyIiwiY2xhenoiLCJjbGFzc05hbWUiLCJpc1VzZXJzQ2xhc3NEaXNhYmxlZCIsInNvbWUiLCJjbGFzc0NvbmZpZ3MiLCJzb3J0Q2xhc3NlcyIsImEiLCJiIiwic29ydCIsIm1hcCIsImMiLCJmdW5jdGlvbk5hbWUiLCJ0ZXN0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FBRUEsTUFBTUEsMkJBQTJCLEdBQUcsQ0FDbEMsUUFEa0MsRUFFbEMsU0FGa0MsRUFHbEMsS0FIa0MsRUFJbEMsT0FKa0MsRUFLbEMsSUFMa0MsRUFNbEMsYUFOa0MsRUFPbEMsT0FQa0MsRUFRbEMsVUFSa0MsRUFTbEMsY0FUa0MsRUFVbEMsaUJBVmtDLEVBV2xDLG1CQVhrQyxFQVlsQyxRQVprQyxFQWFsQyxhQWJrQyxFQWNsQyxlQWRrQyxFQWVsQyxZQWZrQyxFQWdCbEMsY0FoQmtDLEVBaUJsQyxhQWpCa0MsRUFrQmxDLGVBbEJrQyxF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RDtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNFckgsRUFBQUEsc0JBQXNCLENBQUNsQixNQUFELEVBS1Y7QUFDVixVQUFNO0FBQUVTLE1BQUFBLFlBQUY7QUFBZ0JFLE1BQUFBLGtCQUFoQjtBQUFvQ0osTUFBQUEsa0JBQXBDO0FBQXdEUyxNQUFBQTtBQUF4RCxRQUFnRmhCLE1BQXRGOztBQUVBLFFBQ0VZLElBQUksQ0FBQ0MsU0FBTCxDQUFlLEtBQUtOLGtCQUFwQixNQUE0Q0ssSUFBSSxDQUFDQyxTQUFMLENBQWVOLGtCQUFmLENBQTVDLElBQ0EsS0FBS1MsbUJBQUwsS0FBNkJBLG1CQUYvQixFQUdFO0FBQ0EsVUFBSSxLQUFLUCxZQUFMLEtBQXNCQSxZQUExQixFQUF3QztBQUN0QyxlQUFPLEtBQVA7QUFDRDs7QUFFRCxVQUFJLEtBQUtFLGtCQUFMLEtBQTRCQSxrQkFBaEMsRUFBb0Q7QUFDbEQsYUFBS0YsWUFBTCxHQUFvQkEsWUFBcEI7QUFDQSxlQUFPLEtBQVA7QUFDRDtBQUNGOztBQUVELFdBQU8sSUFBUDtBQUNEOztBQXRhc0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBHcmFwaFFMU2NoZW1hLCBHcmFwaFFMT2JqZWN0VHlwZSwgRG9jdW1lbnROb2RlLCBHcmFwaFFMTmFtZWRUeXBlIH0gZnJvbSAnZ3JhcGhxbCc7XG5pbXBvcnQgeyBzdGl0Y2hTY2hlbWFzIH0gZnJvbSAnQGdyYXBocWwtdG9vbHMvc3RpdGNoJztcbmltcG9ydCB7IFNjaGVtYURpcmVjdGl2ZVZpc2l0b3IgfSBmcm9tICdAZ3JhcGhxbC10b29scy91dGlscyc7XG5pbXBvcnQgcmVxdWlyZWRQYXJhbWV0ZXIgZnJvbSAnLi4vcmVxdWlyZWRQYXJhbWV0ZXInO1xuaW1wb3J0ICogYXMgZGVmYXVsdEdyYXBoUUxUeXBlcyBmcm9tICcuL2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQgKiBhcyBwYXJzZUNsYXNzVHlwZXMgZnJvbSAnLi9sb2FkZXJzL3BhcnNlQ2xhc3NUeXBlcyc7XG5pbXBvcnQgKiBhcyBwYXJzZUNsYXNzUXVlcmllcyBmcm9tICcuL2xvYWRlcnMvcGFyc2VDbGFzc1F1ZXJpZXMnO1xuaW1wb3J0ICogYXMgcGFyc2VDbGFzc011dGF0aW9ucyBmcm9tICcuL2xvYWRlcnMvcGFyc2VDbGFzc011dGF0aW9ucyc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFF1ZXJpZXMgZnJvbSAnLi9sb2FkZXJzL2RlZmF1bHRHcmFwaFFMUXVlcmllcyc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTE11dGF0aW9ucyBmcm9tICcuL2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxNdXRhdGlvbnMnO1xuaW1wb3J0IFBhcnNlR3JhcGhRTENvbnRyb2xsZXIsIHsgUGFyc2VHcmFwaFFMQ29uZmlnIH0gZnJvbSAnLi4vQ29udHJvbGxlcnMvUGFyc2VHcmFwaFFMQ29udHJvbGxlcic7XG5pbXBvcnQgRGF0YWJhc2VDb250cm9sbGVyIGZyb20gJy4uL0NvbnRyb2xsZXJzL0RhdGFiYXNlQ29udHJvbGxlcic7XG5pbXBvcnQgeyB0b0dyYXBoUUxFcnJvciB9IGZyb20gJy4vcGFyc2VHcmFwaFFMVXRpbHMnO1xuaW1wb3J0ICogYXMgc2NoZW1hRGlyZWN0aXZlcyBmcm9tICcuL2xvYWRlcnMvc2NoZW1hRGlyZWN0aXZlcyc7XG5pbXBvcnQgKiBhcyBzY2hlbWFUeXBlcyBmcm9tICcuL2xvYWRlcnMvc2NoZW1hVHlwZXMnO1xuaW1wb3J0IHsgZ2V0RnVuY3Rpb25OYW1lcyB9IGZyb20gJy4uL3RyaWdnZXJzJztcbmltcG9ydCAqIGFzIGRlZmF1bHRSZWxheVNjaGVtYSBmcm9tICcuL2xvYWRlcnMvZGVmYXVsdFJlbGF5U2NoZW1hJztcblxuY29uc3QgUkVTRVJWRURfR1JBUEhRTF9UWVBFX05BTUVTID0gW1xuICAnU3RyaW5nJyxcbiAgJ0Jvb2xlYW4nLFxuICAnSW50JyxcbiAgJ0Zsb2F0JyxcbiAgJ0lEJyxcbiAgJ0FycmF5UmVzdWx0JyxcbiAgJ1F1ZXJ5JyxcbiAgJ011dGF0aW9uJyxcbiAgJ1N1YnNjcmlwdGlvbicsXG4gICdDcmVhdGVGaWxlSW5wdXQnLFxuICAnQ3JlYXRlRmlsZVBheWxvYWQnLFxuICAnVmlld2VyJyxcbiAgJ1NpZ25VcElucHV0JyxcbiAgJ1NpZ25VcFBheWxvYWQnLFxuICAnTG9nSW5JbnB1dCcsXG4gICdMb2dJblBheWxvYWQnLFxuICAnTG9nT3V0SW5wdXQnLFxuICAnTG9nT3V0UGF5bG9hZCcsXG4gICdDbG91ZENvZGVGdW5jdGlvbicsXG4gICdDYWxsQ2xvdWRDb2RlSW5wdXQnLFxuICAnQ2FsbENsb3VkQ29kZVBheWxvYWQnLFxuICAnQ3JlYXRlQ2xhc3NJbnB1dCcsXG4gICdDcmVhdGVDbGFzc1BheWxvYWQnLFxuICAnVXBkYXRlQ2xhc3NJbnB1dCcsXG4gICdVcGRhdGVDbGFzc1BheWxvYWQnLFxuICAnRGVsZXRlQ2xhc3NJbnB1dCcsXG4gICdEZWxldGVDbGFzc1BheWxvYWQnLFxuICAnUGFnZUluZm8nLFxuXTtcbmNvbnN0IFJFU0VSVkVEX0dSQVBIUUxfUVVFUllfTkFNRVMgPSBbJ2hlYWx0aCcsICd2aWV3ZXInLCAnY2xhc3MnLCAnY2xhc3NlcyddO1xuY29uc3QgUkVTRVJWRURfR1JBUEhRTF9NVVRBVElPTl9OQU1FUyA9IFtcbiAgJ3NpZ25VcCcsXG4gICdsb2dJbicsXG4gICdsb2dPdXQnLFxuICAnY3JlYXRlRmlsZScsXG4gICdjYWxsQ2xvdWRDb2RlJyxcbiAgJ2NyZWF0ZUNsYXNzJyxcbiAgJ3VwZGF0ZUNsYXNzJyxcbiAgJ2RlbGV0ZUNsYXNzJyxcbl07XG5cbmNsYXNzIFBhcnNlR3JhcGhRTFNjaGVtYSB7XG4gIGRhdGFiYXNlQ29udHJvbGxlcjogRGF0YWJhc2VDb250cm9sbGVyO1xuICBwYXJzZUdyYXBoUUxDb250cm9sbGVyOiBQYXJzZUdyYXBoUUxDb250cm9sbGVyO1xuICBwYXJzZUdyYXBoUUxDb25maWc6IFBhcnNlR3JhcGhRTENvbmZpZztcbiAgbG9nOiBhbnk7XG4gIGFwcElkOiBzdHJpbmc7XG4gIGdyYXBoUUxDdXN0b21UeXBlRGVmczogPyhzdHJpbmcgfCBHcmFwaFFMU2NoZW1hIHwgRG9jdW1lbnROb2RlIHwgR3JhcGhRTE5hbWVkVHlwZVtdKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwYXJhbXM6IHtcbiAgICAgIGRhdGFiYXNlQ29udHJvbGxlcjogRGF0YWJhc2VDb250cm9sbGVyLFxuICAgICAgcGFyc2VHcmFwaFFMQ29udHJvbGxlcjogUGFyc2VHcmFwaFFMQ29udHJvbGxlcixcbiAgICAgIGxvZzogYW55LFxuICAgICAgYXBwSWQ6IHN0cmluZyxcbiAgICAgIGdyYXBoUUxDdXN0b21UeXBlRGVmczogPyhzdHJpbmcgfCBHcmFwaFFMU2NoZW1hIHwgRG9jdW1lbnROb2RlIHwgR3JhcGhRTE5hbWVkVHlwZVtdKSxcbiAgICB9ID0ge31cbiAgKSB7XG4gICAgdGhpcy5wYXJzZUdyYXBoUUxDb250cm9sbGVyID1cbiAgICAgIHBhcmFtcy5wYXJzZUdyYXBoUUxDb250cm9sbGVyIHx8XG4gICAgICByZXF1aXJlZFBhcmFtZXRlcignWW91IG11c3QgcHJvdmlkZSBhIHBhcnNlR3JhcGhRTENvbnRyb2xsZXIgaW5zdGFuY2UhJyk7XG4gICAgdGhpcy5kYXRhYmFzZUNvbnRyb2xsZXIgPVxuICAgICAgcGFyYW1zLmRhdGFiYXNlQ29udHJvbGxlciB8fFxuICAgICAgcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYSBkYXRhYmFzZUNvbnRyb2xsZXIgaW5zdGFuY2UhJyk7XG4gICAgdGhpcy5sb2cgPSBwYXJhbXMubG9nIHx8IHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGEgbG9nIGluc3RhbmNlIScpO1xuICAgIHRoaXMuZ3JhcGhRTEN1c3RvbVR5cGVEZWZzID0gcGFyYW1zLmdyYXBoUUxDdXN0b21UeXBlRGVmcztcbiAgICB0aGlzLmFwcElkID0gcGFyYW1zLmFwcElkIHx8IHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIHRoZSBhcHBJZCEnKTtcbiAgfVxuXG4gIGFzeW5jIGxvYWQoKSB7XG4gICAgY29uc3QgeyBwYXJzZUdyYXBoUUxDb25maWcgfSA9IGF3YWl0IHRoaXMuX2luaXRpYWxpemVTY2hlbWFBbmRDb25maWcoKTtcbiAgICBjb25zdCBwYXJzZUNsYXNzZXMgPSBhd2FpdCB0aGlzLl9nZXRDbGFzc2VzRm9yU2NoZW1hKHBhcnNlR3JhcGhRTENvbmZpZyk7XG4gICAgY29uc3QgcGFyc2VDbGFzc2VzU3RyaW5nID0gSlNPTi5zdHJpbmdpZnkocGFyc2VDbGFzc2VzKTtcbiAgICBjb25zdCBmdW5jdGlvbk5hbWVzID0gYXdhaXQgdGhpcy5fZ2V0RnVuY3Rpb25OYW1lcygpO1xuICAgIGNvbnN0IGZ1bmN0aW9uTmFtZXNTdHJpbmcgPSBKU09OLnN0cmluZ2lmeShmdW5jdGlvbk5hbWVzKTtcblxuICAgIGlmIChcbiAgICAgIHRoaXMuZ3JhcGhRTFNjaGVtYSAmJlxuICAgICAgIXRoaXMuX2hhc1NjaGVtYUlucHV0Q2hhbmdlZCh7XG4gICAgICAgIHBhcnNlQ2xhc3NlcyxcbiAgICAgICAgcGFyc2VDbGFzc2VzU3RyaW5nLFxuICAgICAgICBwYXJzZUdyYXBoUUxDb25maWcsXG4gICAgICAgIGZ1bmN0aW9uTmFtZXNTdHJpbmcsXG4gICAgICB9KVxuICAgICkge1xuICAgICAgcmV0dXJuIHRoaXMuZ3JhcGhRTFNjaGVtYTtcbiAgICB9XG5cbiAgICB0aGlzLnBhcnNlQ2xhc3NlcyA9IHBhcnNlQ2xhc3NlcztcbiAgICB0aGlzLnBhcnNlQ2xhc3Nlc1N0cmluZyA9IHBhcnNlQ2xhc3Nlc1N0cmluZztcbiAgICB0aGlzLnBhcnNlR3JhcGhRTENvbmZpZyA9IHBhcnNlR3JhcGhRTENvbmZpZztcbiAgICB0aGlzLmZ1bmN0aW9uTmFtZXMgPSBmdW5jdGlvbk5hbWVzO1xuICAgIHRoaXMuZnVuY3Rpb25OYW1lc1N0cmluZyA9IGZ1bmN0aW9uTmFtZXNTdHJpbmc7XG4gICAgdGhpcy5wYXJzZUNsYXNzVHlwZXMgPSB7fTtcbiAgICB0aGlzLnZpZXdlclR5cGUgPSBudWxsO1xuICAgIHRoaXMuZ3JhcGhRTEF1dG9TY2hlbWEgPSBudWxsO1xuICAgIHRoaXMuZ3JhcGhRTFNjaGVtYSA9IG51bGw7XG4gICAgdGhpcy5ncmFwaFFMVHlwZXMgPSBbXTtcbiAgICB0aGlzLmdyYXBoUUxRdWVyaWVzID0ge307XG4gICAgdGhpcy5ncmFwaFFMTXV0YXRpb25zID0ge307XG4gICAgdGhpcy5ncmFwaFFMU3Vic2NyaXB0aW9ucyA9IHt9O1xuICAgIHRoaXMuZ3JhcGhRTFNjaGVtYURpcmVjdGl2ZXNEZWZpbml0aW9ucyA9IG51bGw7XG4gICAgdGhpcy5ncmFwaFFMU2NoZW1hRGlyZWN0aXZlcyA9IHt9O1xuICAgIHRoaXMucmVsYXlOb2RlSW50ZXJmYWNlID0gbnVsbDtcblxuICAgIGRlZmF1bHRHcmFwaFFMVHlwZXMubG9hZCh0aGlzKTtcbiAgICBkZWZhdWx0UmVsYXlTY2hlbWEubG9hZCh0aGlzKTtcbiAgICBzY2hlbWFUeXBlcy5sb2FkKHRoaXMpO1xuXG4gICAgdGhpcy5fZ2V0UGFyc2VDbGFzc2VzV2l0aENvbmZpZyhwYXJzZUNsYXNzZXMsIHBhcnNlR3JhcGhRTENvbmZpZykuZm9yRWFjaChcbiAgICAgIChbcGFyc2VDbGFzcywgcGFyc2VDbGFzc0NvbmZpZ10pID0+IHtcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzLmxvYWQodGhpcywgcGFyc2VDbGFzcywgcGFyc2VDbGFzc0NvbmZpZyk7XG4gICAgICAgIHBhcnNlQ2xhc3NRdWVyaWVzLmxvYWQodGhpcywgcGFyc2VDbGFzcywgcGFyc2VDbGFzc0NvbmZpZyk7XG4gICAgICAgIHBhcnNlQ2xhc3NNdXRhdGlvbnMubG9hZCh0aGlzLCBwYXJzZUNsYXNzLCBwYXJzZUNsYXNzQ29uZmlnKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgZGVmYXVsdEdyYXBoUUxUeXBlcy5sb2FkQXJyYXlSZXN1bHQodGhpcywgcGFyc2VDbGFzc2VzKTtcbiAgICBkZWZhdWx0R3JhcGhRTFF1ZXJpZXMubG9hZCh0aGlzKTtcbiAgICBkZWZhdWx0R3JhcGhRTE11dGF0aW9ucy5sb2FkKHRoaXMpO1xuXG4gICAgbGV0IGdyYXBoUUxRdWVyeSA9IHVuZGVmaW5lZDtcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5ncmFwaFFMUXVlcmllcykubGVuZ3RoID4gMCkge1xuICAgICAgZ3JhcGhRTFF1ZXJ5ID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgICAgICAgbmFtZTogJ1F1ZXJ5JyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdRdWVyeSBpcyB0aGUgdG9wIGxldmVsIHR5cGUgZm9yIHF1ZXJpZXMuJyxcbiAgICAgICAgZmllbGRzOiB0aGlzLmdyYXBoUUxRdWVyaWVzLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmFkZEdyYXBoUUxUeXBlKGdyYXBoUUxRdWVyeSwgdHJ1ZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgbGV0IGdyYXBoUUxNdXRhdGlvbiA9IHVuZGVmaW5lZDtcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5ncmFwaFFMTXV0YXRpb25zKS5sZW5ndGggPiAwKSB7XG4gICAgICBncmFwaFFMTXV0YXRpb24gPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICAgICAgICBuYW1lOiAnTXV0YXRpb24nLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ011dGF0aW9uIGlzIHRoZSB0b3AgbGV2ZWwgdHlwZSBmb3IgbXV0YXRpb25zLicsXG4gICAgICAgIGZpZWxkczogdGhpcy5ncmFwaFFMTXV0YXRpb25zLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmFkZEdyYXBoUUxUeXBlKGdyYXBoUUxNdXRhdGlvbiwgdHJ1ZSwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgbGV0IGdyYXBoUUxTdWJzY3JpcHRpb24gPSB1bmRlZmluZWQ7XG4gICAgaWYgKE9iamVjdC5rZXlzKHRoaXMuZ3JhcGhRTFN1YnNjcmlwdGlvbnMpLmxlbmd0aCA+IDApIHtcbiAgICAgIGdyYXBoUUxTdWJzY3JpcHRpb24gPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICAgICAgICBuYW1lOiAnU3Vic2NyaXB0aW9uJyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdTdWJzY3JpcHRpb24gaXMgdGhlIHRvcCBsZXZlbCB0eXBlIGZvciBzdWJzY3JpcHRpb25zLicsXG4gICAgICAgIGZpZWxkczogdGhpcy5ncmFwaFFMU3Vic2NyaXB0aW9ucyxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5hZGRHcmFwaFFMVHlwZShncmFwaFFMU3Vic2NyaXB0aW9uLCB0cnVlLCB0cnVlKTtcbiAgICB9XG5cbiAgICB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hID0gbmV3IEdyYXBoUUxTY2hlbWEoe1xuICAgICAgdHlwZXM6IHRoaXMuZ3JhcGhRTFR5cGVzLFxuICAgICAgcXVlcnk6IGdyYXBoUUxRdWVyeSxcbiAgICAgIG11dGF0aW9uOiBncmFwaFFMTXV0YXRpb24sXG4gICAgICBzdWJzY3JpcHRpb246IGdyYXBoUUxTdWJzY3JpcHRpb24sXG4gICAgfSk7XG5cbiAgICBpZiAodGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMpIHtcbiAgICAgIHNjaGVtYURpcmVjdGl2ZXMubG9hZCh0aGlzKTtcblxuICAgICAgaWYgKHR5cGVvZiB0aGlzLmdyYXBoUUxDdXN0b21UeXBlRGVmcy5nZXRUeXBlTWFwID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGNvbnN0IGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlTWFwID0gdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMuZ2V0VHlwZU1hcCgpO1xuICAgICAgICBjb25zdCBmaW5kQW5kUmVwbGFjZUxhc3RUeXBlID0gKHBhcmVudCwga2V5KSA9PiB7XG4gICAgICAgICAgaWYgKHBhcmVudFtrZXldLm5hbWUpIHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgdGhpcy5ncmFwaFFMQXV0b1NjaGVtYS5nZXRUeXBlKHBhcmVudFtrZXldLm5hbWUpICYmXG4gICAgICAgICAgICAgIHRoaXMuZ3JhcGhRTEF1dG9TY2hlbWEuZ2V0VHlwZShwYXJlbnRba2V5XS5uYW1lKSAhPT0gcGFyZW50W2tleV1cbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAvLyBUbyBhdm9pZCB1bnJlc29sdmVkIGZpZWxkIG9uIG92ZXJsb2FkZWQgc2NoZW1hXG4gICAgICAgICAgICAgIC8vIHJlcGxhY2UgdGhlIGZpbmFsIHR5cGUgd2l0aCB0aGUgYXV0byBzY2hlbWEgb25lXG4gICAgICAgICAgICAgIHBhcmVudFtrZXldID0gdGhpcy5ncmFwaFFMQXV0b1NjaGVtYS5nZXRUeXBlKHBhcmVudFtrZXldLm5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAocGFyZW50W2tleV0ub2ZUeXBlKSB7XG4gICAgICAgICAgICAgIGZpbmRBbmRSZXBsYWNlTGFzdFR5cGUocGFyZW50W2tleV0sICdvZlR5cGUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIE9iamVjdC52YWx1ZXMoY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGVNYXApLmZvckVhY2goY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGUgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICFjdXN0b21HcmFwaFFMU2NoZW1hVHlwZSB8fFxuICAgICAgICAgICAgIWN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLm5hbWUgfHxcbiAgICAgICAgICAgIGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLm5hbWUuc3RhcnRzV2l0aCgnX18nKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBhdXRvR3JhcGhRTFNjaGVtYVR5cGUgPSB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hLmdldFR5cGUoXG4gICAgICAgICAgICBjdXN0b21HcmFwaFFMU2NoZW1hVHlwZS5uYW1lXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoIWF1dG9HcmFwaFFMU2NoZW1hVHlwZSkge1xuICAgICAgICAgICAgdGhpcy5ncmFwaFFMQXV0b1NjaGVtYS5fdHlwZU1hcFtjdXN0b21HcmFwaFFMU2NoZW1hVHlwZS5uYW1lXSA9IGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIE9iamVjdC52YWx1ZXMoY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGVNYXApLmZvckVhY2goY3VzdG9tR3JhcGhRTFNjaGVtYVR5cGUgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICFjdXN0b21HcmFwaFFMU2NoZW1hVHlwZSB8fFxuICAgICAgICAgICAgIWN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLm5hbWUgfHxcbiAgICAgICAgICAgIGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLm5hbWUuc3RhcnRzV2l0aCgnX18nKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBhdXRvR3JhcGhRTFNjaGVtYVR5cGUgPSB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hLmdldFR5cGUoXG4gICAgICAgICAgICBjdXN0b21HcmFwaFFMU2NoZW1hVHlwZS5uYW1lXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGlmIChhdXRvR3JhcGhRTFNjaGVtYVR5cGUgJiYgdHlwZW9mIGN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLmdldEZpZWxkcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgT2JqZWN0LnZhbHVlcyhjdXN0b21HcmFwaFFMU2NoZW1hVHlwZS5nZXRGaWVsZHMoKSkuZm9yRWFjaChmaWVsZCA9PiB7XG4gICAgICAgICAgICAgIGZpbmRBbmRSZXBsYWNlTGFzdFR5cGUoZmllbGQsICd0eXBlJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGF1dG9HcmFwaFFMU2NoZW1hVHlwZS5fZmllbGRzID0ge1xuICAgICAgICAgICAgICAuLi5hdXRvR3JhcGhRTFNjaGVtYVR5cGUuZ2V0RmllbGRzKCksXG4gICAgICAgICAgICAgIC4uLmN1c3RvbUdyYXBoUUxTY2hlbWFUeXBlLmdldEZpZWxkcygpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmdyYXBoUUxTY2hlbWEgPSBzdGl0Y2hTY2hlbWFzKHtcbiAgICAgICAgICBzY2hlbWFzOiBbdGhpcy5ncmFwaFFMU2NoZW1hRGlyZWN0aXZlc0RlZmluaXRpb25zLCB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hXSxcbiAgICAgICAgICBtZXJnZURpcmVjdGl2ZXM6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhpcy5ncmFwaFFMU2NoZW1hID0gYXdhaXQgdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMoe1xuICAgICAgICAgIGRpcmVjdGl2ZXNEZWZpbml0aW9uc1NjaGVtYTogdGhpcy5ncmFwaFFMU2NoZW1hRGlyZWN0aXZlc0RlZmluaXRpb25zLFxuICAgICAgICAgIGF1dG9TY2hlbWE6IHRoaXMuZ3JhcGhRTEF1dG9TY2hlbWEsXG4gICAgICAgICAgc3RpdGNoU2NoZW1hcyxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmdyYXBoUUxTY2hlbWEgPSBzdGl0Y2hTY2hlbWFzKHtcbiAgICAgICAgICBzY2hlbWFzOiBbXG4gICAgICAgICAgICB0aGlzLmdyYXBoUUxTY2hlbWFEaXJlY3RpdmVzRGVmaW5pdGlvbnMsXG4gICAgICAgICAgICB0aGlzLmdyYXBoUUxBdXRvU2NoZW1hLFxuICAgICAgICAgICAgdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMsXG4gICAgICAgICAgXSxcbiAgICAgICAgICBtZXJnZURpcmVjdGl2ZXM6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBncmFwaFFMU2NoZW1hVHlwZU1hcCA9IHRoaXMuZ3JhcGhRTFNjaGVtYS5nZXRUeXBlTWFwKCk7XG4gICAgICBPYmplY3Qua2V5cyhncmFwaFFMU2NoZW1hVHlwZU1hcCkuZm9yRWFjaChncmFwaFFMU2NoZW1hVHlwZU5hbWUgPT4ge1xuICAgICAgICBjb25zdCBncmFwaFFMU2NoZW1hVHlwZSA9IGdyYXBoUUxTY2hlbWFUeXBlTWFwW2dyYXBoUUxTY2hlbWFUeXBlTmFtZV07XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0eXBlb2YgZ3JhcGhRTFNjaGVtYVR5cGUuZ2V0RmllbGRzID09PSAnZnVuY3Rpb24nICYmXG4gICAgICAgICAgdGhpcy5ncmFwaFFMQ3VzdG9tVHlwZURlZnMuZGVmaW5pdGlvbnNcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgZ3JhcGhRTEN1c3RvbVR5cGVEZWYgPSB0aGlzLmdyYXBoUUxDdXN0b21UeXBlRGVmcy5kZWZpbml0aW9ucy5maW5kKFxuICAgICAgICAgICAgZGVmaW5pdGlvbiA9PiBkZWZpbml0aW9uLm5hbWUudmFsdWUgPT09IGdyYXBoUUxTY2hlbWFUeXBlTmFtZVxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKGdyYXBoUUxDdXN0b21UeXBlRGVmKSB7XG4gICAgICAgICAgICBjb25zdCBncmFwaFFMU2NoZW1hVHlwZUZpZWxkTWFwID0gZ3JhcGhRTFNjaGVtYVR5cGUuZ2V0RmllbGRzKCk7XG4gICAgICAgICAgICBPYmplY3Qua2V5cyhncmFwaFFMU2NoZW1hVHlwZUZpZWxkTWFwKS5mb3JFYWNoKGdyYXBoUUxTY2hlbWFUeXBlRmllbGROYW1lID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZCA9IGdyYXBoUUxTY2hlbWFUeXBlRmllbGRNYXBbZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZE5hbWVdO1xuICAgICAgICAgICAgICBpZiAoIWdyYXBoUUxTY2hlbWFUeXBlRmllbGQuYXN0Tm9kZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFzdE5vZGUgPSBncmFwaFFMQ3VzdG9tVHlwZURlZi5maWVsZHMuZmluZChcbiAgICAgICAgICAgICAgICAgIGZpZWxkID0+IGZpZWxkLm5hbWUudmFsdWUgPT09IGdyYXBoUUxTY2hlbWFUeXBlRmllbGROYW1lXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBpZiAoYXN0Tm9kZSkge1xuICAgICAgICAgICAgICAgICAgZ3JhcGhRTFNjaGVtYVR5cGVGaWVsZC5hc3ROb2RlID0gYXN0Tm9kZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIFNjaGVtYURpcmVjdGl2ZVZpc2l0b3IudmlzaXRTY2hlbWFEaXJlY3RpdmVzKFxuICAgICAgICB0aGlzLmdyYXBoUUxTY2hlbWEsXG4gICAgICAgIHRoaXMuZ3JhcGhRTFNjaGVtYURpcmVjdGl2ZXNcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZ3JhcGhRTFNjaGVtYSA9IHRoaXMuZ3JhcGhRTEF1dG9TY2hlbWE7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZ3JhcGhRTFNjaGVtYTtcbiAgfVxuXG4gIGFkZEdyYXBoUUxUeXBlKHR5cGUsIHRocm93RXJyb3IgPSBmYWxzZSwgaWdub3JlUmVzZXJ2ZWQgPSBmYWxzZSwgaWdub3JlQ29ubmVjdGlvbiA9IGZhbHNlKSB7XG4gICAgaWYgKFxuICAgICAgKCFpZ25vcmVSZXNlcnZlZCAmJiBSRVNFUlZFRF9HUkFQSFFMX1RZUEVfTkFNRVMuaW5jbHVkZXModHlwZS5uYW1lKSkgfHxcbiAgICAgIHRoaXMuZ3JhcGhRTFR5cGVzLmZpbmQoZXhpc3RpbmdUeXBlID0+IGV4aXN0aW5nVHlwZS5uYW1lID09PSB0eXBlLm5hbWUpIHx8XG4gICAgICAoIWlnbm9yZUNvbm5lY3Rpb24gJiYgdHlwZS5uYW1lLmVuZHNXaXRoKCdDb25uZWN0aW9uJykpXG4gICAgKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gYFR5cGUgJHt0eXBlLm5hbWV9IGNvdWxkIG5vdCBiZSBhZGRlZCB0byB0aGUgYXV0byBzY2hlbWEgYmVjYXVzZSBpdCBjb2xsaWRlZCB3aXRoIGFuIGV4aXN0aW5nIHR5cGUuYDtcbiAgICAgIGlmICh0aHJvd0Vycm9yKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubG9nLndhcm4obWVzc2FnZSk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICB0aGlzLmdyYXBoUUxUeXBlcy5wdXNoKHR5cGUpO1xuICAgIHJldHVybiB0eXBlO1xuICB9XG5cbiAgYWRkR3JhcGhRTFF1ZXJ5KGZpZWxkTmFtZSwgZmllbGQsIHRocm93RXJyb3IgPSBmYWxzZSwgaWdub3JlUmVzZXJ2ZWQgPSBmYWxzZSkge1xuICAgIGlmIChcbiAgICAgICghaWdub3JlUmVzZXJ2ZWQgJiYgUkVTRVJWRURfR1JBUEhRTF9RVUVSWV9OQU1FUy5pbmNsdWRlcyhmaWVsZE5hbWUpKSB8fFxuICAgICAgdGhpcy5ncmFwaFFMUXVlcmllc1tmaWVsZE5hbWVdXG4gICAgKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gYFF1ZXJ5ICR7ZmllbGROYW1lfSBjb3VsZCBub3QgYmUgYWRkZWQgdG8gdGhlIGF1dG8gc2NoZW1hIGJlY2F1c2UgaXQgY29sbGlkZWQgd2l0aCBhbiBleGlzdGluZyBmaWVsZC5gO1xuICAgICAgaWYgKHRocm93RXJyb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2cud2FybihtZXNzYWdlKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRoaXMuZ3JhcGhRTFF1ZXJpZXNbZmllbGROYW1lXSA9IGZpZWxkO1xuICAgIHJldHVybiBmaWVsZDtcbiAgfVxuXG4gIGFkZEdyYXBoUUxNdXRhdGlvbihmaWVsZE5hbWUsIGZpZWxkLCB0aHJvd0Vycm9yID0gZmFsc2UsIGlnbm9yZVJlc2VydmVkID0gZmFsc2UpIHtcbiAgICBpZiAoXG4gICAgICAoIWlnbm9yZVJlc2VydmVkICYmIFJFU0VSVkVEX0dSQVBIUUxfTVVUQVRJT05fTkFNRVMuaW5jbHVkZXMoZmllbGROYW1lKSkgfHxcbiAgICAgIHRoaXMuZ3JhcGhRTE11dGF0aW9uc1tmaWVsZE5hbWVdXG4gICAgKSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gYE11dGF0aW9uICR7ZmllbGROYW1lfSBjb3VsZCBub3QgYmUgYWRkZWQgdG8gdGhlIGF1dG8gc2NoZW1hIGJlY2F1c2UgaXQgY29sbGlkZWQgd2l0aCBhbiBleGlzdGluZyBmaWVsZC5gO1xuICAgICAgaWYgKHRocm93RXJyb3IpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2cud2FybihtZXNzYWdlKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHRoaXMuZ3JhcGhRTE11dGF0aW9uc1tmaWVsZE5hbWVdID0gZmllbGQ7XG4gICAgcmV0dXJuIGZpZWxkO1xuICB9XG5cbiAgaGFuZGxlRXJyb3IoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBQYXJzZS5FcnJvcikge1xuICAgICAgdGhpcy5sb2cuZXJyb3IoJ1BhcnNlIGVycm9yOiAnLCBlcnJvcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubG9nLmVycm9yKCdVbmNhdWdodCBpbnRlcm5hbCBzZXJ2ZXIgZXJyb3IuJywgZXJyb3IsIGVycm9yLnN0YWNrKTtcbiAgICB9XG4gICAgdGhyb3cgdG9HcmFwaFFMRXJyb3IoZXJyb3IpO1xuICB9XG5cbiAgYXN5bmMgX2luaXRpYWxpemVTY2hlbWFBbmRDb25maWcoKSB7XG4gICAgY29uc3QgW3NjaGVtYUNvbnRyb2xsZXIsIHBhcnNlR3JhcGhRTENvbmZpZ10gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICB0aGlzLmRhdGFiYXNlQ29udHJvbGxlci5sb2FkU2NoZW1hKCksXG4gICAgICB0aGlzLnBhcnNlR3JhcGhRTENvbnRyb2xsZXIuZ2V0R3JhcGhRTENvbmZpZygpLFxuICAgIF0pO1xuXG4gICAgdGhpcy5zY2hlbWFDb250cm9sbGVyID0gc2NoZW1hQ29udHJvbGxlcjtcblxuICAgIHJldHVybiB7XG4gICAgICBwYXJzZUdyYXBoUUxDb25maWcsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGFsbCBjbGFzc2VzIGZvdW5kIGJ5IHRoZSBgc2NoZW1hQ29udHJvbGxlcmBcbiAgICogbWludXMgdGhvc2UgZmlsdGVyZWQgb3V0IGJ5IHRoZSBhcHAncyBwYXJzZUdyYXBoUUxDb25maWcuXG4gICAqL1xuICBhc3luYyBfZ2V0Q2xhc3Nlc0ZvclNjaGVtYShwYXJzZUdyYXBoUUxDb25maWc6IFBhcnNlR3JhcGhRTENvbmZpZykge1xuICAgIGNvbnN0IHsgZW5hYmxlZEZvckNsYXNzZXMsIGRpc2FibGVkRm9yQ2xhc3NlcyB9ID0gcGFyc2VHcmFwaFFMQ29uZmlnO1xuICAgIGNvbnN0IGFsbENsYXNzZXMgPSBhd2FpdCB0aGlzLnNjaGVtYUNvbnRyb2xsZXIuZ2V0QWxsQ2xhc3NlcygpO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoZW5hYmxlZEZvckNsYXNzZXMpIHx8IEFycmF5LmlzQXJyYXkoZGlzYWJsZWRGb3JDbGFzc2VzKSkge1xuICAgICAgbGV0IGluY2x1ZGVkQ2xhc3NlcyA9IGFsbENsYXNzZXM7XG4gICAgICBpZiAoZW5hYmxlZEZvckNsYXNzZXMpIHtcbiAgICAgICAgaW5jbHVkZWRDbGFzc2VzID0gYWxsQ2xhc3Nlcy5maWx0ZXIoY2xhenogPT4ge1xuICAgICAgICAgIHJldHVybiBlbmFibGVkRm9yQ2xhc3Nlcy5pbmNsdWRlcyhjbGF6ei5jbGFzc05hbWUpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChkaXNhYmxlZEZvckNsYXNzZXMpIHtcbiAgICAgICAgLy8gQ2xhc3NlcyBpbmNsdWRlZCBpbiBgZW5hYmxlZEZvckNsYXNzZXNgIHRoYXRcbiAgICAgICAgLy8gYXJlIGFsc28gcHJlc2VudCBpbiBgZGlzYWJsZWRGb3JDbGFzc2VzYCB3aWxsXG4gICAgICAgIC8vIHN0aWxsIGJlIGZpbHRlcmVkIG91dFxuICAgICAgICBpbmNsdWRlZENsYXNzZXMgPSBpbmNsdWRlZENsYXNzZXMuZmlsdGVyKGNsYXp6ID0+IHtcbiAgICAgICAgICByZXR1cm4gIWRpc2FibGVkRm9yQ2xhc3Nlcy5pbmNsdWRlcyhjbGF6ei5jbGFzc05hbWUpO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5pc1VzZXJzQ2xhc3NEaXNhYmxlZCA9ICFpbmNsdWRlZENsYXNzZXMuc29tZShjbGF6eiA9PiB7XG4gICAgICAgIHJldHVybiBjbGF6ei5jbGFzc05hbWUgPT09ICdfVXNlcic7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGluY2x1ZGVkQ2xhc3NlcztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGFsbENsYXNzZXM7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIHJldHVybnMgYSBsaXN0IG9mIHR1cGxlc1xuICAgKiB0aGF0IHByb3ZpZGUgdGhlIHBhcnNlQ2xhc3MgYWxvbmcgd2l0aFxuICAgKiBpdHMgcGFyc2VDbGFzc0NvbmZpZyB3aGVyZSBwcm92aWRlZC5cbiAgICovXG4gIF9nZXRQYXJzZUNsYXNzZXNXaXRoQ29uZmlnKHBhcnNlQ2xhc3NlcywgcGFyc2VHcmFwaFFMQ29uZmlnOiBQYXJzZUdyYXBoUUxDb25maWcpIHtcbiAgICBjb25zdCB7IGNsYXNzQ29uZmlncyB9ID0gcGFyc2VHcmFwaFFMQ29uZmlnO1xuXG4gICAgLy8gTWFrZSBzdXJlcyB0aGF0IHRoZSBkZWZhdWx0IGNsYXNzZXMgYW5kIGNsYXNzZXMgdGhhdFxuICAgIC8vIHN0YXJ0cyB3aXRoIGNhcGl0YWxpemVkIGxldHRlciB3aWxsIGJlIGdlbmVyYXRlZCBmaXJzdC5cbiAgICBjb25zdCBzb3J0Q2xhc3NlcyA9IChhLCBiKSA9PiB7XG4gICAgICBhID0gYS5jbGFzc05hbWU7XG4gICAgICBiID0gYi5jbGFzc05hbWU7XG4gICAgICBpZiAoYVswXSA9PT0gJ18nKSB7XG4gICAgICAgIGlmIChiWzBdICE9PSAnXycpIHtcbiAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChiWzBdID09PSAnXycpIHtcbiAgICAgICAgaWYgKGFbMF0gIT09ICdfJykge1xuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoYSA9PT0gYikge1xuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH0gZWxzZSBpZiAoYSA8IGIpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHJldHVybiBwYXJzZUNsYXNzZXMuc29ydChzb3J0Q2xhc3NlcykubWFwKHBhcnNlQ2xhc3MgPT4ge1xuICAgICAgbGV0IHBhcnNlQ2xhc3NDb25maWc7XG4gICAgICBpZiAoY2xhc3NDb25maWdzKSB7XG4gICAgICAgIHBhcnNlQ2xhc3NDb25maWcgPSBjbGFzc0NvbmZpZ3MuZmluZChjID0+IGMuY2xhc3NOYW1lID09PSBwYXJzZUNsYXNzLmNsYXNzTmFtZSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gW3BhcnNlQ2xhc3MsIHBhcnNlQ2xhc3NDb25maWddO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgX2dldEZ1bmN0aW9uTmFtZXMoKSB7XG4gICAgcmV0dXJuIGF3YWl0IGdldEZ1bmN0aW9uTmFtZXModGhpcy5hcHBJZCkuZmlsdGVyKGZ1bmN0aW9uTmFtZSA9PiB7XG4gICAgICBpZiAoL15bX2EtekEtWl1bX2EtekEtWjAtOV0qJC8udGVzdChmdW5jdGlvbk5hbWUpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5sb2cud2FybihcbiAgICAgICAgICBgRnVuY3Rpb24gJHtmdW5jdGlvbk5hbWV9IGNvdWxkIG5vdCBiZSBhZGRlZCB0byB0aGUgYXV0byBzY2hlbWEgYmVjYXVzZSBHcmFwaFFMIG5hbWVzIG11c3QgbWF0Y2ggL15bX2EtekEtWl1bX2EtekEtWjAtOV0qJC8uYFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGZvciBjaGFuZ2VzIHRvIHRoZSBwYXJzZUNsYXNzZXNcbiAgICogb2JqZWN0cyAoaS5lLiBkYXRhYmFzZSBzY2hlbWEpIG9yIHRvXG4gICAqIHRoZSBwYXJzZUdyYXBoUUxDb25maWcgb2JqZWN0LiBJZiBub1xuICAgKiBjaGFuZ2VzIGFyZSBmb3VuZCwgcmV0dXJuIHRydWU7XG4gICAqL1xuICBfaGFzU2NoZW1hSW5wdXRDaGFuZ2VkKHBhcmFtczoge1xuICAgIHBhcnNlQ2xhc3NlczogYW55LFxuICAgIHBhcnNlQ2xhc3Nlc1N0cmluZzogc3RyaW5nLFxuICAgIHBhcnNlR3JhcGhRTENvbmZpZzogP1BhcnNlR3JhcGhRTENvbmZpZyxcbiAgICBmdW5jdGlvbk5hbWVzU3RyaW5nOiBzdHJpbmcsXG4gIH0pOiBib29sZWFuIHtcbiAgICBjb25zdCB7IHBhcnNlQ2xhc3NlcywgcGFyc2VDbGFzc2VzU3RyaW5nLCBwYXJzZUdyYXBoUUxDb25maWcsIGZ1bmN0aW9uTmFtZXNTdHJpbmcgfSA9IHBhcmFtcztcblxuICAgIGlmIChcbiAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMucGFyc2VHcmFwaFFMQ29uZmlnKSA9PT0gSlNPTi5zdHJpbmdpZnkocGFyc2VHcmFwaFFMQ29uZmlnKSAmJlxuICAgICAgdGhpcy5mdW5jdGlvbk5hbWVzU3RyaW5nID09PSBmdW5jdGlvbk5hbWVzU3RyaW5nXG4gICAgKSB7XG4gICAgICBpZiAodGhpcy5wYXJzZUNsYXNzZXMgPT09IHBhcnNlQ2xhc3Nlcykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnBhcnNlQ2xhc3Nlc1N0cmluZyA9PT0gcGFyc2VDbGFzc2VzU3RyaW5nKSB7XG4gICAgICAgIHRoaXMucGFyc2VDbGFzc2VzID0gcGFyc2VDbGFzc2VzO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cblxuZXhwb3J0IHsgUGFyc2VHcmFwaFFMU2NoZW1hIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/ParseGraphQLServer.js b/lib/GraphQL/ParseGraphQLServer.js deleted file mode 100644 index 3025e6ae74..0000000000 --- a/lib/GraphQL/ParseGraphQLServer.js +++ /dev/null @@ -1,140 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.ParseGraphQLServer = void 0; - -var _cors = _interopRequireDefault(require("cors")); - -var _bodyParser = _interopRequireDefault(require("body-parser")); - -var _graphqlUpload = require("graphql-upload"); - -var _expressApollo = require("apollo-server-express/dist/expressApollo"); - -var _graphqlPlaygroundHtml = require("@apollographql/graphql-playground-html"); - -var _graphql = require("graphql"); - -var _subscriptionsTransportWs = require("subscriptions-transport-ws"); - -var _middlewares = require("../middlewares"); - -var _requiredParameter = _interopRequireDefault(require("../requiredParameter")); - -var _logger = _interopRequireDefault(require("../logger")); - -var _ParseGraphQLSchema = require("./ParseGraphQLSchema"); - -var _ParseGraphQLController = _interopRequireWildcard(require("../Controllers/ParseGraphQLController")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class ParseGraphQLServer { - constructor(parseServer, config) { - this.parseServer = parseServer || (0, _requiredParameter.default)('You must provide a parseServer instance!'); - - if (!config || !config.graphQLPath) { - (0, _requiredParameter.default)('You must provide a config.graphQLPath!'); - } - - this.config = config; - this.parseGraphQLController = this.parseServer.config.parseGraphQLController; - this.log = this.parseServer.config && this.parseServer.config.loggerController || _logger.default; - this.parseGraphQLSchema = new _ParseGraphQLSchema.ParseGraphQLSchema({ - parseGraphQLController: this.parseGraphQLController, - databaseController: this.parseServer.config.databaseController, - log: this.log, - graphQLCustomTypeDefs: this.config.graphQLCustomTypeDefs, - appId: this.parseServer.config.appId - }); - } - - async _getGraphQLOptions(req) { - try { - return { - schema: await this.parseGraphQLSchema.load(), - context: { - info: req.info, - config: req.config, - auth: req.auth - }, - formatError: error => { - // Allow to console.log here to debug - return error; - } - }; - } catch (e) { - this.log.error(e.stack || typeof e.toString === 'function' && e.toString() || e); - throw e; - } - } - - _transformMaxUploadSizeToBytes(maxUploadSize) { - const unitMap = { - kb: 1, - mb: 2, - gb: 3 - }; - return Number(maxUploadSize.slice(0, -2)) * Math.pow(1024, unitMap[maxUploadSize.slice(-2).toLowerCase()]); - } - - applyGraphQL(app) { - if (!app || !app.use) { - (0, _requiredParameter.default)('You must provide an Express.js app instance!'); - } - - app.use(this.config.graphQLPath, (0, _graphqlUpload.graphqlUploadExpress)({ - maxFileSize: this._transformMaxUploadSizeToBytes(this.parseServer.config.maxUploadSize || '20mb') - })); - app.use(this.config.graphQLPath, (0, _cors.default)()); - app.use(this.config.graphQLPath, _bodyParser.default.json()); - app.use(this.config.graphQLPath, _middlewares.handleParseHeaders); - app.use(this.config.graphQLPath, _middlewares.handleParseErrors); - app.use(this.config.graphQLPath, (0, _expressApollo.graphqlExpress)(async req => await this._getGraphQLOptions(req))); - } - - applyPlayground(app) { - if (!app || !app.get) { - (0, _requiredParameter.default)('You must provide an Express.js app instance!'); - } - - app.get(this.config.playgroundPath || (0, _requiredParameter.default)('You must provide a config.playgroundPath to applyPlayground!'), (_req, res) => { - res.setHeader('Content-Type', 'text/html'); - res.write((0, _graphqlPlaygroundHtml.renderPlaygroundPage)({ - endpoint: this.config.graphQLPath, - version: '1.7.25', - subscriptionEndpoint: this.config.subscriptionsPath, - headers: { - 'X-Parse-Application-Id': this.parseServer.config.appId, - 'X-Parse-Master-Key': this.parseServer.config.masterKey - } - })); - res.end(); - }); - } - - createSubscriptions(server) { - _subscriptionsTransportWs.SubscriptionServer.create({ - execute: _graphql.execute, - subscribe: _graphql.subscribe, - onOperation: async (_message, params, webSocket) => Object.assign({}, params, await this._getGraphQLOptions(webSocket.upgradeReq)) - }, { - server, - path: this.config.subscriptionsPath || (0, _requiredParameter.default)('You must provide a config.subscriptionsPath to createSubscriptions!') - }); - } - - setGraphQLConfig(graphQLConfig) { - return this.parseGraphQLController.updateGraphQLConfig(graphQLConfig); - } - -} - -exports.ParseGraphQLServer = ParseGraphQLServer; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9HcmFwaFFML1BhcnNlR3JhcGhRTFNlcnZlci5qcyJdLCJuYW1lcyI6WyJQYXJzZUdyYXBoUUxTZXJ2ZXIiLCJjb25zdHJ1Y3RvciIsInBhcnNlU2VydmVyIiwiY29uZmlnIiwiZ3JhcGhRTFBhdGgiLCJwYXJzZUdyYXBoUUxDb250cm9sbGVyIiwibG9nIiwibG9nZ2VyQ29udHJvbGxlciIsImRlZmF1bHRMb2dnZXIiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJQYXJzZUdyYXBoUUxTY2hlbWEiLCJkYXRhYmFzZUNvbnRyb2xsZXIiLCJncmFwaFFMQ3VzdG9tVHlwZURlZnMiLCJhcHBJZCIsIl9nZXRHcmFwaFFMT3B0aW9ucyIsInJlcSIsInNjaGVtYSIsImxvYWQiLCJjb250ZXh0IiwiaW5mbyIsImF1dGgiLCJmb3JtYXRFcnJvciIsImVycm9yIiwiZSIsInN0YWNrIiwidG9TdHJpbmciLCJfdHJhbnNmb3JtTWF4VXBsb2FkU2l6ZVRvQnl0ZXMiLCJtYXhVcGxvYWRTaXplIiwidW5pdE1hcCIsImtiIiwibWIiLCJnYiIsIk51bWJlciIsInNsaWNlIiwiTWF0aCIsInBvdyIsInRvTG93ZXJDYXNlIiwiYXBwbHlHcmFwaFFMIiwiYXBwIiwidXNlIiwibWF4RmlsZVNpemUiLCJib2R5UGFyc2VyIiwianNvbiIsImhhbmRsZVBhcnNlSGVhZGVycyIsImhhbmRsZVBhcnNlRXJyb3JzIiwiYXBwbHlQbGF5Z3JvdW5kIiwiZ2V0IiwicGxheWdyb3VuZFBhdGgiLCJfcmVxIiwicmVzIiwic2V0SGVhZGVyIiwid3JpdGUiLCJlbmRwb2ludCIsInZlcnNpb24iLCJzdWJzY3JpcHRpb25FbmRwb2ludCIsInN1YnNjcmlwdGlvbnNQYXRoIiwiaGVhZGVycyIsIm1hc3RlcktleSIsImVuZCIsImNyZWF0ZVN1YnNjcmlwdGlvbnMiLCJzZXJ2ZXIiLCJTdWJzY3JpcHRpb25TZXJ2ZXIiLCJjcmVhdGUiLCJleGVjdXRlIiwic3Vic2NyaWJlIiwib25PcGVyYXRpb24iLCJfbWVzc2FnZSIsInBhcmFtcyIsIndlYlNvY2tldCIsIk9iamVjdCIsImFzc2lnbiIsInVwZ3JhZGVSZXEiLCJwYXRoIiwic2V0R3JhcGhRTENvbmZpZyIsImdyYXBoUUxDb25maWciLCJ1cGRhdGVHcmFwaFFMQ29uZmlnIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBRUEsTUFBTUEsa0JBQU4sQ0FBeUI7QUFHdkJDLEVBQUFBLFdBQVcsQ0FBQ0MsV0FBRCxFQUFjQyxNQUFkLEVBQXNCO0FBQy9CLFNBQUtELFdBQUwsR0FBbUJBLFdBQVcsSUFBSSxnQ0FBa0IsMENBQWxCLENBQWxDOztBQUNBLFFBQUksQ0FBQ0MsTUFBRCxJQUFXLENBQUNBLE1BQU0sQ0FBQ0MsV0FBdkIsRUFBb0M7QUFDbEMsc0NBQWtCLHdDQUFsQjtBQUNEOztBQUNELFNBQUtELE1BQUwsR0FBY0EsTUFBZDtBQUNBLFNBQUtFLHNCQUFMLEdBQThCLEtBQUtILFdBQUwsQ0FBaUJDLE1BQWpCLENBQXdCRSxzQkFBdEQ7QUFDQSxTQUFLQyxHQUFMLEdBQ0csS0FBS0osV0FBTCxDQUFpQkMsTUFBakIsSUFBMkIsS0FBS0QsV0FBTCxDQUFpQkMsTUFBakIsQ0FBd0JJLGdCQUFwRCxJQUF5RUMsZUFEM0U7QUFFQSxTQUFLQyxrQkFBTCxHQUEwQixJQUFJQyxzQ0FBSixDQUF1QjtBQUMvQ0wsTUFBQUEsc0JBQXNCLEVBQUUsS0FBS0Esc0JBRGtCO0FBRS9DTSxNQUFBQSxrQkFBa0IsRUFBRSxLQUFLVCxXQUFMLENBQWlCQyxNQUFqQixDQUF3QlEsa0JBRkc7QUFHL0NMLE1BQUFBLEdBQUcsRUFBRSxLQUFLQSxHQUhxQztBQUkvQ00sTUFBQUEscUJBQXFCLEVBQUUsS0FBS1QsTUFBTCxDQUFZUyxxQkFKWTtBQUsvQ0MsTUFBQUEsS0FBSyxFQUFFLEtBQUtYLFdBQUwsQ0FBaUJDLE1BQWpCLENBQXdC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QixDQUFnREQsYUFBaEQsQ0FBUDtBQUNEOztBQXpIc0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY29yc01pZGRsZXdhcmUgZnJvbSAnY29ycyc7XG5pbXBvcnQgYm9keVBhcnNlciBmcm9tICdib2R5LXBhcnNlcic7XG5pbXBvcnQgeyBncmFwaHFsVXBsb2FkRXhwcmVzcyB9IGZyb20gJ2dyYXBocWwtdXBsb2FkJztcbmltcG9ydCB7IGdyYXBocWxFeHByZXNzIH0gZnJvbSAnYXBvbGxvLXNlcnZlci1leHByZXNzL2Rpc3QvZXhwcmVzc0Fwb2xsbyc7XG5pbXBvcnQgeyByZW5kZXJQbGF5Z3JvdW5kUGFnZSB9IGZyb20gJ0BhcG9sbG9ncmFwaHFsL2dyYXBocWwtcGxheWdyb3VuZC1odG1sJztcbmltcG9ydCB7IGV4ZWN1dGUsIHN1YnNjcmliZSB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uU2VydmVyIH0gZnJvbSAnc3Vic2NyaXB0aW9ucy10cmFuc3BvcnQtd3MnO1xuaW1wb3J0IHsgaGFuZGxlUGFyc2VFcnJvcnMsIGhhbmRsZVBhcnNlSGVhZGVycyB9IGZyb20gJy4uL21pZGRsZXdhcmVzJztcbmltcG9ydCByZXF1aXJlZFBhcmFtZXRlciBmcm9tICcuLi9yZXF1aXJlZFBhcmFtZXRlcic7XG5pbXBvcnQgZGVmYXVsdExvZ2dlciBmcm9tICcuLi9sb2dnZXInO1xuaW1wb3J0IHsgUGFyc2VHcmFwaFFMU2NoZW1hIH0gZnJvbSAnLi9QYXJzZUdyYXBoUUxTY2hlbWEnO1xuaW1wb3J0IFBhcnNlR3JhcGhRTENvbnRyb2xsZXIsIHsgUGFyc2VHcmFwaFFMQ29uZmlnIH0gZnJvbSAnLi4vQ29udHJvbGxlcnMvUGFyc2VHcmFwaFFMQ29udHJvbGxlcic7XG5cbmNsYXNzIFBhcnNlR3JhcGhRTFNlcnZlciB7XG4gIHBhcnNlR3JhcGhRTENvbnRyb2xsZXI6IFBhcnNlR3JhcGhRTENvbnRyb2xsZXI7XG5cbiAgY29uc3RydWN0b3IocGFyc2VTZXJ2ZXIsIGNvbmZpZykge1xuICAgIHRoaXMucGFyc2VTZXJ2ZXIgPSBwYXJzZVNlcnZlciB8fCByZXF1aXJlZFBhcmFtZXRlcignWW91IG11c3QgcHJvdmlkZSBhIHBhcnNlU2VydmVyIGluc3RhbmNlIScpO1xuICAgIGlmICghY29uZmlnIHx8ICFjb25maWcuZ3JhcGhRTFBhdGgpIHtcbiAgICAgIHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGEgY29uZmlnLmdyYXBoUUxQYXRoIScpO1xuICAgIH1cbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICB0aGlzLnBhcnNlR3JhcGhRTENvbnRyb2xsZXIgPSB0aGlzLnBhcnNlU2VydmVyLmNvbmZpZy5wYXJzZUdyYXBoUUxDb250cm9sbGVyO1xuICAgIHRoaXMubG9nID1cbiAgICAgICh0aGlzLnBhcnNlU2VydmVyLmNvbmZpZyAmJiB0aGlzLnBhcnNlU2VydmVyLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyKSB8fCBkZWZhdWx0TG9nZ2VyO1xuICAgIHRoaXMucGFyc2VHcmFwaFFMU2NoZW1hID0gbmV3IFBhcnNlR3JhcGhRTFNjaGVtYSh7XG4gICAgICBwYXJzZUdyYXBoUUxDb250cm9sbGVyOiB0aGlzLnBhcnNlR3JhcGhRTENvbnRyb2xsZXIsXG4gICAgICBkYXRhYmFzZUNvbnRyb2xsZXI6IHRoaXMucGFyc2VTZXJ2ZXIuY29uZmlnLmRhdGFiYXNlQ29udHJvbGxlcixcbiAgICAgIGxvZzogdGhpcy5sb2csXG4gICAgICBncmFwaFFMQ3VzdG9tVHlwZURlZnM6IHRoaXMuY29uZmlnLmdyYXBoUUxDdXN0b21UeXBlRGVmcyxcbiAgICAgIGFwcElkOiB0aGlzLnBhcnNlU2VydmVyLmNvbmZpZy5hcHBJZCxcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIF9nZXRHcmFwaFFMT3B0aW9ucyhyZXEpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc2NoZW1hOiBhd2FpdCB0aGlzLnBhcnNlR3JhcGhRTFNjaGVtYS5sb2FkKCksXG4gICAgICAgIGNvbnRleHQ6IHtcbiAgICAgICAgICBpbmZvOiByZXEuaW5mbyxcbiAgICAgICAgICBjb25maWc6IHJlcS5jb25maWcsXG4gICAgICAgICAgYXV0aDogcmVxLmF1dGgsXG4gICAgICAgIH0sXG4gICAgICAgIGZvcm1hdEVycm9yOiBlcnJvciA9PiB7XG4gICAgICAgICAgLy8gQWxsb3cgdG8gY29uc29sZS5sb2cgaGVyZSB0byBkZWJ1Z1xuICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5sb2cuZXJyb3IoZS5zdGFjayB8fCAodHlwZW9mIGUudG9TdHJpbmcgPT09ICdmdW5jdGlvbicgJiYgZS50b1N0cmluZygpKSB8fCBlKTtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG5cbiAgX3RyYW5zZm9ybU1heFVwbG9hZFNpemVUb0J5dGVzKG1heFVwbG9hZFNpemUpIHtcbiAgICBjb25zdCB1bml0TWFwID0ge1xuICAgICAga2I6IDEsXG4gICAgICBtYjogMixcbiAgICAgIGdiOiAzLFxuICAgIH07XG5cbiAgICByZXR1cm4gKFxuICAgICAgTnVtYmVyKG1heFVwbG9hZFNpemUuc2xpY2UoMCwgLTIpKSAqXG4gICAgICBNYXRoLnBvdygxMDI0LCB1bml0TWFwW21heFVwbG9hZFNpemUuc2xpY2UoLTIpLnRvTG93ZXJDYXNlKCldKVxuICAgICk7XG4gIH1cblxuICBhcHBseUdyYXBoUUwoYXBwKSB7XG4gICAgaWYgKCFhcHAgfHwgIWFwcC51c2UpIHtcbiAgICAgIHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGFuIEV4cHJlc3MuanMgYXBwIGluc3RhbmNlIScpO1xuICAgIH1cblxuICAgIGFwcC51c2UoXG4gICAgICB0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCxcbiAgICAgIGdyYXBocWxVcGxvYWRFeHByZXNzKHtcbiAgICAgICAgbWF4RmlsZVNpemU6IHRoaXMuX3RyYW5zZm9ybU1heFVwbG9hZFNpemVUb0J5dGVzKFxuICAgICAgICAgIHRoaXMucGFyc2VTZXJ2ZXIuY29uZmlnLm1heFVwbG9hZFNpemUgfHwgJzIwbWInXG4gICAgICAgICksXG4gICAgICB9KVxuICAgICk7XG4gICAgYXBwLnVzZSh0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCwgY29yc01pZGRsZXdhcmUoKSk7XG4gICAgYXBwLnVzZSh0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCwgYm9keVBhcnNlci5qc29uKCkpO1xuICAgIGFwcC51c2UodGhpcy5jb25maWcuZ3JhcGhRTFBhdGgsIGhhbmRsZVBhcnNlSGVhZGVycyk7XG4gICAgYXBwLnVzZSh0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCwgaGFuZGxlUGFyc2VFcnJvcnMpO1xuICAgIGFwcC51c2UoXG4gICAgICB0aGlzLmNvbmZpZy5ncmFwaFFMUGF0aCxcbiAgICAgIGdyYXBocWxFeHByZXNzKGFzeW5jIHJlcSA9PiBhd2FpdCB0aGlzLl9nZXRHcmFwaFFMT3B0aW9ucyhyZXEpKVxuICAgICk7XG4gIH1cblxuICBhcHBseVBsYXlncm91bmQoYXBwKSB7XG4gICAgaWYgKCFhcHAgfHwgIWFwcC5nZXQpIHtcbiAgICAgIHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGFuIEV4cHJlc3MuanMgYXBwIGluc3RhbmNlIScpO1xuICAgIH1cbiAgICBhcHAuZ2V0KFxuICAgICAgdGhpcy5jb25maWcucGxheWdyb3VuZFBhdGggfHxcbiAgICAgICAgcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYSBjb25maWcucGxheWdyb3VuZFBhdGggdG8gYXBwbHlQbGF5Z3JvdW5kIScpLFxuICAgICAgKF9yZXEsIHJlcykgPT4ge1xuICAgICAgICByZXMuc2V0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAndGV4dC9odG1sJyk7XG4gICAgICAgIHJlcy53cml0ZShcbiAgICAgICAgICByZW5kZXJQbGF5Z3JvdW5kUGFnZSh7XG4gICAgICAgICAgICBlbmRwb2ludDogdGhpcy5jb25maWcuZ3JhcGhRTFBhdGgsXG4gICAgICAgICAgICB2ZXJzaW9uOiAnMS43LjI1JyxcbiAgICAgICAgICAgIHN1YnNjcmlwdGlvbkVuZHBvaW50OiB0aGlzLmNvbmZpZy5zdWJzY3JpcHRpb25zUGF0aCxcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgJ1gtUGFyc2UtQXBwbGljYXRpb24tSWQnOiB0aGlzLnBhcnNlU2VydmVyLmNvbmZpZy5hcHBJZCxcbiAgICAgICAgICAgICAgJ1gtUGFyc2UtTWFzdGVyLUtleSc6IHRoaXMucGFyc2VTZXJ2ZXIuY29uZmlnLm1hc3RlcktleSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBjcmVhdGVTdWJzY3JpcHRpb25zKHNlcnZlcikge1xuICAgIFN1YnNjcmlwdGlvblNlcnZlci5jcmVhdGUoXG4gICAgICB7XG4gICAgICAgIGV4ZWN1dGUsXG4gICAgICAgIHN1YnNjcmliZSxcbiAgICAgICAgb25PcGVyYXRpb246IGFzeW5jIChfbWVzc2FnZSwgcGFyYW1zLCB3ZWJTb2NrZXQpID0+XG4gICAgICAgICAgT2JqZWN0LmFzc2lnbih7fSwgcGFyYW1zLCBhd2FpdCB0aGlzLl9nZXRHcmFwaFFMT3B0aW9ucyh3ZWJTb2NrZXQudXBncmFkZVJlcSkpLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgc2VydmVyLFxuICAgICAgICBwYXRoOlxuICAgICAgICAgIHRoaXMuY29uZmlnLnN1YnNjcmlwdGlvbnNQYXRoIHx8XG4gICAgICAgICAgcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYSBjb25maWcuc3Vic2NyaXB0aW9uc1BhdGggdG8gY3JlYXRlU3Vic2NyaXB0aW9ucyEnKSxcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgc2V0R3JhcGhRTENvbmZpZyhncmFwaFFMQ29uZmlnOiBQYXJzZUdyYXBoUUxDb25maWcpOiBQcm9taXNlIHtcbiAgICByZXR1cm4gdGhpcy5wYXJzZUdyYXBoUUxDb250cm9sbGVyLnVwZGF0ZUdyYXBoUUxDb25maWcoZ3JhcGhRTENvbmZpZyk7XG4gIH1cbn1cblxuZXhwb3J0IHsgUGFyc2VHcmFwaFFMU2VydmVyIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/helpers/objectsMutations.js b/lib/GraphQL/helpers/objectsMutations.js deleted file mode 100644 index 2658a07253..0000000000 --- a/lib/GraphQL/helpers/objectsMutations.js +++ /dev/null @@ -1,40 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.deleteObject = exports.updateObject = exports.createObject = void 0; - -var _rest = _interopRequireDefault(require("../../rest")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const createObject = async (className, fields, config, auth, info) => { - if (!fields) { - fields = {}; - } - - return (await _rest.default.create(config, auth, className, fields, info.clientSDK, info.context)).response; -}; - -exports.createObject = createObject; - -const updateObject = async (className, objectId, fields, config, auth, info) => { - if (!fields) { - fields = {}; - } - - return (await _rest.default.update(config, auth, className, { - objectId - }, fields, info.clientSDK, info.context)).response; -}; - -exports.updateObject = updateObject; - -const deleteObject = async (className, objectId, config, auth, info) => { - await _rest.default.del(config, auth, className, objectId, info.context); - return true; -}; - -exports.deleteObject = deleteObject; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2hlbHBlcnMvb2JqZWN0c011dGF0aW9ucy5qcyJdLCJuYW1lcyI6WyJjcmVhdGVPYmplY3QiLCJjbGFzc05hbWUiLCJmaWVsZHMiLCJjb25maWciLCJhdXRoIiwiaW5mbyIsInJlc3QiLCJjcmVhdGUiLCJjbGllbnRTREsiLCJjb250ZXh0IiwicmVzcG9uc2UiLCJ1cGRhdGVPYmplY3QiLCJvYmplY3RJZCIsInVwZGF0ZSIsImRlbGV0ZU9iamVjdCIsImRlbCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7O0FBRUEsTUFBTUEsWUFBWSxHQUFHLE9BQU9DLFNBQVAsRUFBa0JDLE1BQWxCLEVBQTBCQyxNQUExQixFQUFrQ0MsSUFBbEMsRUFBd0NDLElBQXhDLEtBQWlEO0FBQ3BFLE1BQUksQ0FBQ0gsTUFBTCxFQUFhO0FBQ1hBLElBQUFBLE1BQU0sR0FBRyxFQUFUO0FBQ0Q7O0FBRUQsU0FBTyxDQUFDLE1BQU1JLGNBQUtDLE1BQUwsQ0FBWUosTUFBWixFQUFvQkMsSUFBcEIsRUFBMEJILFNBQTFCLEVBQXFDQyxNQUFyQyxFQUE2Q0csSUFBSSxDQUFDRyxTQUFsRCxFQUE2REgsSUFBSSxDQUFDSSxPQUFsRSxDQUFQLEVBQ0pDLFFBREg7QUFFRCxDQVBEOzs7O0FBU0EsTUFBTUMsWUFBWSxHQUFHLE9BQU9WLFNBQVAsRUFBa0JXLFFBQWxCLEVBQTRCVixNQUE1QixFQUFvQ0MsTUFBcEMsRUFBNENDLElBQTVDLEVBQWtEQyxJQUFsRCxLQUEyRDtBQUM5RSxNQUFJLENBQUNILE1BQUwsRUFBYTtBQUNYQSxJQUFBQSxNQUFNLEdBQUcsRUFBVDtBQUNEOztBQUVELFNBQU8sQ0FDTCxNQUFNSSxjQUFLTyxNQUFMLENBQVlWLE1BQVosRUFBb0JDLElBQXBCLEVBQTBCSCxTQUExQixFQUFxQztBQUFFVyxJQUFBQTtBQUFGLEdBQXJDLEVBQW1EVixNQUFuRCxFQUEyREcsSUFBSSxDQUFDRyxTQUFoRSxFQUEyRUgsSUFBSSxDQUFDSSxPQUFoRixDQURELEVBRUxDLFFBRkY7QUFHRCxDQVJEOzs7O0FBVUEsTUFBTUksWUFBWSxHQUFHLE9BQU9iLFNBQVAsRUFBa0JXLFFBQWxCLEVBQTRCVCxNQUE1QixFQUFvQ0MsSUFBcEMsRUFBMENDLElBQTFDLEtBQW1EO0FBQ3RFLFFBQU1DLGNBQUtTLEdBQUwsQ0FBU1osTUFBVCxFQUFpQkMsSUFBakIsRUFBdUJILFNBQXZCLEVBQWtDVyxRQUFsQyxFQUE0Q1AsSUFBSSxDQUFDSSxPQUFqRCxDQUFOO0FBQ0EsU0FBTyxJQUFQO0FBQ0QsQ0FIRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCByZXN0IGZyb20gJy4uLy4uL3Jlc3QnO1xuXG5jb25zdCBjcmVhdGVPYmplY3QgPSBhc3luYyAoY2xhc3NOYW1lLCBmaWVsZHMsIGNvbmZpZywgYXV0aCwgaW5mbykgPT4ge1xuICBpZiAoIWZpZWxkcykge1xuICAgIGZpZWxkcyA9IHt9O1xuICB9XG5cbiAgcmV0dXJuIChhd2FpdCByZXN0LmNyZWF0ZShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgZmllbGRzLCBpbmZvLmNsaWVudFNESywgaW5mby5jb250ZXh0KSlcbiAgICAucmVzcG9uc2U7XG59O1xuXG5jb25zdCB1cGRhdGVPYmplY3QgPSBhc3luYyAoY2xhc3NOYW1lLCBvYmplY3RJZCwgZmllbGRzLCBjb25maWcsIGF1dGgsIGluZm8pID0+IHtcbiAgaWYgKCFmaWVsZHMpIHtcbiAgICBmaWVsZHMgPSB7fTtcbiAgfVxuXG4gIHJldHVybiAoXG4gICAgYXdhaXQgcmVzdC51cGRhdGUoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIHsgb2JqZWN0SWQgfSwgZmllbGRzLCBpbmZvLmNsaWVudFNESywgaW5mby5jb250ZXh0KVxuICApLnJlc3BvbnNlO1xufTtcblxuY29uc3QgZGVsZXRlT2JqZWN0ID0gYXN5bmMgKGNsYXNzTmFtZSwgb2JqZWN0SWQsIGNvbmZpZywgYXV0aCwgaW5mbykgPT4ge1xuICBhd2FpdCByZXN0LmRlbChjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgb2JqZWN0SWQsIGluZm8uY29udGV4dCk7XG4gIHJldHVybiB0cnVlO1xufTtcblxuZXhwb3J0IHsgY3JlYXRlT2JqZWN0LCB1cGRhdGVPYmplY3QsIGRlbGV0ZU9iamVjdCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/helpers/objectsQueries.js b/lib/GraphQL/helpers/objectsQueries.js deleted file mode 100644 index ec9decc0b7..0000000000 --- a/lib/GraphQL/helpers/objectsQueries.js +++ /dev/null @@ -1,309 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.needToGetAllKeys = exports.calculateSkipAndLimit = exports.findObjects = exports.getObject = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _graphqlRelay = require("graphql-relay"); - -var _rest = _interopRequireDefault(require("../../rest")); - -var _query = require("../transformers/query"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// Eslint/Prettier conflict - -/* eslint-disable*/ -const needToGetAllKeys = (fields, keys, parseClasses) => keys ? keys.split(',').some(keyName => { - const key = keyName.split('.'); - - if (fields[key[0]]) { - if (fields[key[0]].type === 'Relation') return false; - - if (fields[key[0]].type === 'Pointer') { - const subClass = parseClasses.find(({ - className: parseClassName - }) => fields[key[0]].targetClass === parseClassName); - - if (subClass && subClass.fields[key[1]]) { - // Current sub key is not custom - return false; - } - } else if (!key[1] || fields[key[0]].type === 'Array' || fields[key[0]].type === 'Object') { - // current key is not custom - return false; - } - } // Key not found into Parse Schema so it's custom - - - return true; -}) : true; -/* eslint-enable*/ - - -exports.needToGetAllKeys = needToGetAllKeys; - -const getObject = async (className, objectId, keys, include, readPreference, includeReadPreference, config, auth, info, parseClasses) => { - const options = {}; - - try { - if (!needToGetAllKeys(parseClasses.find(({ - className: parseClassName - }) => className === parseClassName).fields, keys, parseClasses)) { - options.keys = keys; - } - } catch (e) { - console.log(e); - } - - if (include) { - options.include = include; - - if (includeReadPreference) { - options.includeReadPreference = includeReadPreference; - } - } - - if (readPreference) { - options.readPreference = readPreference; - } - - const response = await _rest.default.get(config, auth, className, objectId, options, info.clientSDK, info.context); - - if (!response.results || response.results.length == 0) { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } - - const object = response.results[0]; - - if (className === '_User') { - delete object.sessionToken; - } - - return object; -}; - -exports.getObject = getObject; - -const findObjects = async (className, where, order, skipInput, first, after, last, before, keys, include, includeAll, readPreference, includeReadPreference, subqueryReadPreference, config, auth, info, selectedFields, parseClasses) => { - if (!where) { - where = {}; - } - - (0, _query.transformQueryInputToParse)(where, className, parseClasses); - const skipAndLimitCalculation = calculateSkipAndLimit(skipInput, first, after, last, before, config.maxLimit); - let { - skip - } = skipAndLimitCalculation; - const { - limit, - needToPreCount - } = skipAndLimitCalculation; - let preCount = undefined; - - if (needToPreCount) { - const preCountOptions = { - limit: 0, - count: true - }; - - if (readPreference) { - preCountOptions.readPreference = readPreference; - } - - if (Object.keys(where).length > 0 && subqueryReadPreference) { - preCountOptions.subqueryReadPreference = subqueryReadPreference; - } - - preCount = (await _rest.default.find(config, auth, className, where, preCountOptions, info.clientSDK, info.context)).count; - - if ((skip || 0) + limit < preCount) { - skip = preCount - limit; - } - } - - const options = {}; - - if (selectedFields.find(field => field.startsWith('edges.') || field.startsWith('pageInfo.'))) { - if (limit || limit === 0) { - options.limit = limit; - } else { - options.limit = 100; - } - - if (options.limit !== 0) { - if (order) { - options.order = order; - } - - if (skip) { - options.skip = skip; - } - - if (config.maxLimit && options.limit > config.maxLimit) { - // Silently replace the limit on the query with the max configured - options.limit = config.maxLimit; - } - - if (!needToGetAllKeys(parseClasses.find(({ - className: parseClassName - }) => className === parseClassName).fields, keys, parseClasses)) { - options.keys = keys; - } - - if (includeAll === true) { - options.includeAll = includeAll; - } - - if (!options.includeAll && include) { - options.include = include; - } - - if ((options.includeAll || options.include) && includeReadPreference) { - options.includeReadPreference = includeReadPreference; - } - } - } else { - options.limit = 0; - } - - if ((selectedFields.includes('count') || selectedFields.includes('pageInfo.hasPreviousPage') || selectedFields.includes('pageInfo.hasNextPage')) && !needToPreCount) { - options.count = true; - } - - if (readPreference) { - options.readPreference = readPreference; - } - - if (Object.keys(where).length > 0 && subqueryReadPreference) { - options.subqueryReadPreference = subqueryReadPreference; - } - - let results, count; - - if (options.count || !options.limit || options.limit && options.limit > 0) { - const findResult = await _rest.default.find(config, auth, className, where, options, info.clientSDK, info.context); - results = findResult.results; - count = findResult.count; - } - - let edges = null; - let pageInfo = null; - - if (results) { - edges = results.map((result, index) => ({ - cursor: (0, _graphqlRelay.offsetToCursor)((skip || 0) + index), - node: result - })); - pageInfo = { - hasPreviousPage: (preCount && preCount > 0 || count && count > 0) && skip !== undefined && skip > 0, - startCursor: (0, _graphqlRelay.offsetToCursor)(skip || 0), - endCursor: (0, _graphqlRelay.offsetToCursor)((skip || 0) + (results.length || 1) - 1), - hasNextPage: (preCount || count) > (skip || 0) + results.length - }; - } - - return { - edges, - pageInfo, - count: preCount || count - }; -}; - -exports.findObjects = findObjects; - -const calculateSkipAndLimit = (skipInput, first, after, last, before, maxLimit) => { - let skip = undefined; - let limit = undefined; - let needToPreCount = false; // Validates the skip input - - if (skipInput || skipInput === 0) { - if (skipInput < 0) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Skip should be a positive number'); - } - - skip = skipInput; - } // Validates the after param - - - if (after) { - after = (0, _graphqlRelay.cursorToOffset)(after); - - if (!after && after !== 0 || after < 0) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'After is not a valid cursor'); - } // If skip and after are passed, a new skip is calculated by adding them - - - skip = (skip || 0) + (after + 1); - } // Validates the first param - - - if (first || first === 0) { - if (first < 0) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'First should be a positive number'); - } // The first param is translated to the limit param of the Parse legacy API - - - limit = first; - } // Validates the before param - - - if (before || before === 0) { - // This method converts the cursor to the index of the object - before = (0, _graphqlRelay.cursorToOffset)(before); - - if (!before && before !== 0 || before < 0) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Before is not a valid cursor'); - } - - if ((skip || 0) >= before) { - // If the before index is less then the skip, no objects will be returned - limit = 0; - } else if (!limit && limit !== 0 || (skip || 0) + limit > before) { - // If there is no limit set, the limit is calculated. Or, if the limit (plus skip) is bigger than the before index, the new limit is set. - limit = before - (skip || 0); - } - } // Validates the last param - - - if (last || last === 0) { - if (last < 0) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Last should be a positive number'); - } - - if (last > maxLimit) { - // Last can't be bigger than Parse server maxLimit config. - last = maxLimit; - } - - if (limit || limit === 0) { - // If there is a previous limit set, it may be adjusted - if (last < limit) { - // if last is less than the current limit - skip = (skip || 0) + (limit - last); // The skip is adjusted - - limit = last; // the limit is adjusted - } - } else if (last === 0) { - // No objects will be returned - limit = 0; - } else { - // No previous limit set, the limit will be equal to last and pre count is needed. - limit = last; - needToPreCount = true; - } - } - - return { - skip, - limit, - needToPreCount - }; -}; - -exports.calculateSkipAndLimit = calculateSkipAndLimit; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2hlbHBlcnMvb2JqZWN0c1F1ZXJpZXMuanMiXSwibmFtZXMiOlsibmVlZFRvR2V0QWxsS2V5cyIsImZpZWxkcyIsImtleXMiLCJwYXJzZUNsYXNzZXMiLCJzcGxpdCIsInNvbWUiLCJrZXlOYW1lIiwia2V5IiwidHlwZSIsInN1YkNsYXNzIiwiZmluZCIsImNsYXNzTmFtZSIsInBhcnNlQ2xhc3NOYW1lIiwidGFyZ2V0Q2xhc3MiLCJnZXRPYmplY3QiLCJvYmplY3RJZCIsImluY2x1ZGUiLCJyZWFkUHJlZmVyZW5jZSIsImluY2x1ZGVSZWFkUHJlZmVyZW5jZSIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwib3B0aW9ucyIsImUiLCJjb25zb2xlIiwibG9nIiwicmVzcG9uc2UiLCJyZXN0IiwiZ2V0IiwiY2xpZW50U0RLIiwiY29udGV4dCIsInJlc3VsdHMiLCJsZW5ndGgiLCJQYXJzZSIsIkVycm9yIiwiT0JKRUNUX05PVF9GT1VORCIsIm9iamVjdCIsInNlc3Npb25Ub2tlbiIsImZpbmRPYmplY3RzIiwid2hlcmUiLCJvcmRlciIsInNraXBJbnB1dCIsImZpcnN0IiwiYWZ0ZXIiLCJsYXN0IiwiYmVmb3JlIiwiaW5jbHVkZUFsbCIsInN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UiLCJzZWxlY3RlZEZpZWxkcyIsInNraXBBbmRMaW1pdENhbGN1bGF0aW9uIiwiY2FsY3VsYXRlU2tpcEFuZExpbWl0IiwibWF4TGltaXQiLCJza2lwIiwibGltaXQiLCJuZWVkVG9QcmVDb3VudCIsInByZUNvdW50IiwidW5kZWZpbmVkIiwicHJlQ291bnRPcHRpb25zIiwiY291bnQiLCJPYmplY3QiLCJmaWVsZCIsInN0YXJ0c1dpdGgiLCJpbmNsdWRlcyIsImZpbmRSZXN1bHQiLCJlZGdlcyIsInBhZ2VJbmZvIiwibWFwIiwicmVzdWx0IiwiaW5kZXgiLCJjdXJzb3IiLCJub2RlIiwiaGFzUHJldmlvdXNQYWdlIiwic3RhcnRDdXJzb3IiLCJl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a0I7QUFDaEI7QUFDQUQsUUFBQUEsSUFBSSxHQUFHLENBQUNBLElBQUksSUFBSSxDQUFULEtBQWVDLEtBQUssR0FBR1QsSUFBdkIsQ0FBUCxDQUZnQixDQUVxQjs7QUFDckNTLFFBQUFBLEtBQUssR0FBR1QsSUFBUixDQUhnQixDQUdGO0FBQ2Y7QUFDRixLQVBELE1BT08sSUFBSUEsSUFBSSxLQUFLLENBQWIsRUFBZ0I7QUFDckI7QUFDQVMsTUFBQUEsS0FBSyxHQUFHLENBQVI7QUFDRCxLQUhNLE1BR0E7QUFDTDtBQUNBQSxNQUFBQSxLQUFLLEdBQUdULElBQVI7QUFDQVUsTUFBQUEsY0FBYyxHQUFHLElBQWpCO0FBQ0Q7QUFDRjs7QUFDRCxTQUFPO0FBQ0xGLElBQUFBLElBREs7QUFFTEMsSUFBQUEsS0FGSztBQUdMQyxJQUFBQTtBQUhLLEdBQVA7QUFLRCxDQW5GRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCB7IG9mZnNldFRvQ3Vyc29yLCBjdXJzb3JUb09mZnNldCB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0IHJlc3QgZnJvbSAnLi4vLi4vcmVzdCc7XG5pbXBvcnQgeyB0cmFuc2Zvcm1RdWVyeUlucHV0VG9QYXJzZSB9IGZyb20gJy4uL3RyYW5zZm9ybWVycy9xdWVyeSc7XG5cbi8vIEVzbGludC9QcmV0dGllciBjb25mbGljdFxuLyogZXNsaW50LWRpc2FibGUqL1xuY29uc3QgbmVlZFRvR2V0QWxsS2V5cyA9IChmaWVsZHMsIGtleXMsIHBhcnNlQ2xhc3NlcykgPT5cbiAga2V5c1xuICAgID8ga2V5cy5zcGxpdCgnLCcpLnNvbWUoa2V5TmFtZSA9PiB7XG4gICAgICAgIGNvbnN0IGtleSA9IGtleU5hbWUuc3BsaXQoJy4nKTtcbiAgICAgICAgaWYgKGZpZWxkc1trZXlbMF1dKSB7XG4gICAgICAgICAgaWYgKGZpZWxkc1trZXlbMF1dLnR5cGUgPT09ICdSZWxhdGlvbicpIHJldHVybiBmYWxzZTtcbiAgICAgICAgICBpZiAoZmllbGRzW2tleVswXV0udHlwZSA9PT0gJ1BvaW50ZXInKSB7XG4gICAgICAgICAgICBjb25zdCBzdWJDbGFzcyA9IHBhcnNlQ2xhc3Nlcy5maW5kKFxuICAgICAgICAgICAgICAoeyBjbGFzc05hbWU6IHBhcnNlQ2xhc3NOYW1lIH0pID0+IGZpZWxkc1trZXlbMF1dLnRhcmdldENsYXNzID09PSBwYXJzZUNsYXNzTmFtZVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChzdWJDbGFzcyAmJiBzdWJDbGFzcy5maWVsZHNba2V5WzFdXSkge1xuICAgICAgICAgICAgICAvLyBDdXJyZW50IHN1YiBrZXkgaXMgbm90IGN1c3RvbVxuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgICFrZXlbMV0gfHxcbiAgICAgICAgICAgIGZpZWxkc1trZXlbMF1dLnR5cGUgPT09ICdBcnJheScgfHxcbiAgICAgICAgICAgIGZpZWxkc1trZXlbMF1dLnR5cGUgPT09ICdPYmplY3QnXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICAvLyBjdXJyZW50IGtleSBpcyBub3QgY3VzdG9tXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIEtleSBub3QgZm91bmQgaW50byBQYXJzZSBTY2hlbWEgc28gaXQncyBjdXN0b21cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9KVxuICAgIDogdHJ1ZTtcbi8qIGVzbGludC1lbmFibGUqL1xuXG5jb25zdCBnZXRPYmplY3QgPSBhc3luYyAoXG4gIGNsYXNzTmFtZSxcbiAgb2JqZWN0SWQsXG4gIGtleXMsXG4gIGluY2x1ZGUsXG4gIHJlYWRQcmVmZXJlbmNlLFxuICBpbmNsdWRlUmVhZFByZWZlcmVuY2UsXG4gIGNvbmZpZyxcbiAgYXV0aCxcbiAgaW5mbyxcbiAgcGFyc2VDbGFzc2VzXG4pID0+IHtcbiAgY29uc3Qgb3B0aW9ucyA9IHt9O1xuICB0cnkge1xuICAgIGlmIChcbiAgICAgICFuZWVkVG9HZXRBbGxLZXlzKFxuICAgICAgICBwYXJzZUNsYXNzZXMuZmluZCgoeyBjbGFzc05hbWU6IHBhcnNlQ2xhc3NOYW1lIH0pID0+IGNsYXNzTmFtZSA9PT0gcGFyc2VDbGFzc05hbWUpLmZpZWxkcyxcbiAgICAgICAga2V5cyxcbiAgICAgICAgcGFyc2VDbGFzc2VzXG4gICAgICApXG4gICAgKSB7XG4gICAgICBvcHRpb25zLmtleXMgPSBrZXlzO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUubG9nKGUpO1xuICB9XG4gIGlmIChpbmNsdWRlKSB7XG4gICAgb3B0aW9ucy5pbmNsdWRlID0gaW5jbHVkZTtcbiAgICBpZiAoaW5jbHVkZVJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICBvcHRpb25zLmluY2x1ZGVSZWFkUHJlZmVyZW5jZSA9IGluY2x1ZGVSZWFkUHJlZmVyZW5jZTtcbiAgICB9XG4gIH1cbiAgaWYgKHJlYWRQcmVmZXJlbmNlKSB7XG4gICAgb3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHJlYWRQcmVmZXJlbmNlO1xuICB9XG5cbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCByZXN0LmdldChcbiAgICBjb25maWcsXG4gICAgYXV0aCxcbiAgICBjbGFzc05hbWUsXG4gICAgb2JqZWN0SWQsXG4gICAgb3B0aW9ucyxcbiAgICBpbmZvLmNsaWVudFNESyxcbiAgICBpbmZvLmNvbnRleHRcbiAgKTtcblxuICBpZiAoIXJlc3BvbnNlLnJlc3VsdHMgfHwgcmVzcG9uc2UucmVzdWx0cy5sZW5ndGggPT0gMCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnT2JqZWN0IG5vdCBmb3VuZC4nKTtcbiAgfVxuXG4gIGNvbnN0IG9iamVjdCA9IHJlc3BvbnNlLnJlc3VsdHNbMF07XG4gIGlmIChjbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICBkZWxldGUgb2JqZWN0LnNlc3Npb25Ub2tlbjtcbiAgfVxuICByZXR1cm4gb2JqZWN0O1xufTtcblxuY29uc3QgZmluZE9iamVjdHMgPSBhc3luYyAoXG4gIGNsYXNzTmFtZSxcbiAgd2hlcmUsXG4gIG9yZGVyLFxuICBza2lwSW5wdXQsXG4gIGZpcnN0LFxuICBhZnRlcixcbiAgbGFzdCxcbiAgYmVmb3JlLFxuICBrZXlzLFxuICBpbmNsdWRlLFxuICBpbmNsdWRlQWxsLFxuICByZWFkUHJlZmVyZW5jZSxcbiAgaW5jbHVkZVJlYWRQcmVmZXJlbmNlLFxuICBzdWJxdWVyeVJlYWRQcmVmZXJlbmNlLFxuICBjb25maWcsXG4gIGF1dGgsXG4gIGluZm8sXG4gIHNlbGVjdGVkRmllbGRzLFxuICBwYXJzZUNsYXNzZXNcbikgPT4ge1xuICBpZiAoIXdoZXJlKSB7XG4gICAgd2hlcmUgPSB7fTtcbiAgfVxuICB0cmFuc2Zvcm1RdWVyeUlucHV0VG9QYXJzZSh3aGVyZSwgY2xhc3NOYW1lLCBwYXJzZUNsYXNzZXMpO1xuICBjb25zdCBza2lwQW5kTGltaXRDYWxjdWxhdGlvbiA9IGNhbGN1bGF0ZVNraXBBbmRMaW1pdChcbiAgICBza2lwSW5wdXQsXG4gICAgZmlyc3QsXG4gICAgYWZ0ZXIsXG4gICAgbGFzdCxcbiAgICBiZWZvcmUsXG4gICAgY29uZmlnLm1heExpbWl0XG4gICk7XG4gIGxldCB7IHNraXAgfSA9IHNraXBBbmRMaW1pdENhbGN1bGF0aW9uO1xuICBjb25zdCB7IGxpbWl0LCBuZWVkVG9QcmVDb3VudCB9ID0gc2tpcEFuZExpbWl0Q2FsY3VsYXRpb247XG4gIGxldCBwcmVDb3VudCA9IHVuZGVmaW5lZDtcbiAgaWYgKG5lZWRUb1ByZUNvdW50KSB7XG4gICAgY29uc3QgcHJlQ291bnRPcHRpb25zID0ge1xuICAgICAgbGltaXQ6IDAsXG4gICAgICBjb3VudDogdHJ1ZSxcbiAgICB9O1xuICAgIGlmIChyZWFkUHJlZmVyZW5jZSkge1xuICAgICAgcHJlQ291bnRPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gcmVhZFByZWZlcmVuY2U7XG4gICAgfVxuICAgIGlmIChPYmplY3Qua2V5cyh3aGVyZSkubGVuZ3RoID4gMCAmJiBzdWJxdWVyeVJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICBwcmVDb3VudE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSA9IHN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U7XG4gICAgfVxuICAgIHByZUNvdW50ID0gKFxuICAgICAgYXdhaXQgcmVzdC5maW5kKGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCB3aGVyZSwgcHJlQ291bnRPcHRpb25zLCBpbmZvLmNsaWVudFNESywgaW5mby5jb250ZXh0KVxuICAgICkuY291bnQ7XG4gICAgaWYgKChza2lwIHx8IDApICsgbGltaXQgPCBwcmVDb3VudCkge1xuICAgICAgc2tpcCA9IHByZUNvdW50IC0gbGltaXQ7XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgb3B0aW9ucyA9IHt9O1xuXG4gIGlmIChzZWxlY3RlZEZpZWxkcy5maW5kKGZpZWxkID0+IGZpZWxkLnN0YXJ0c1dpdGgoJ2VkZ2VzLicpIHx8IGZpZWxkLnN0YXJ0c1dpdGgoJ3BhZ2VJbmZvLicpKSkge1xuICAgIGlmIChsaW1pdCB8fCBsaW1pdCA9PT0gMCkge1xuICAgICAgb3B0aW9ucy5saW1pdCA9IGxpbWl0O1xuICAgIH0gZWxzZSB7XG4gICAgICBvcHRpb25zLmxpbWl0ID0gMTAwO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy5saW1pdCAhPT0gMCkge1xuICAgICAgaWYgKG9yZGVyKSB7XG4gICAgICAgIG9wdGlvbnMub3JkZXIgPSBvcmRlcjtcbiAgICAgIH1cbiAgICAgIGlmIChza2lwKSB7XG4gICAgICAgIG9wdGlvbnMuc2tpcCA9IHNraXA7XG4gICAgICB9XG4gICAgICBpZiAoY29uZmlnLm1heExpbWl0ICYmIG9wdGlvbnMubGltaXQgPiBjb25maWcubWF4TGltaXQpIHtcbiAgICAgICAgLy8gU2lsZW50bHkgcmVwbGFjZSB0aGUgbGltaXQgb24gdGhlIHF1ZXJ5IHdpdGggdGhlIG1heCBjb25maWd1cmVkXG4gICAgICAgIG9wdGlvbnMubGltaXQgPSBjb25maWcubWF4TGltaXQ7XG4gICAgICB9XG4gICAgICBpZiAoXG4gICAgICAgICFuZWVkVG9HZXRBbGxLZXlzKFxuICAgICAgICAgIHBhcnNlQ2xhc3Nlcy5maW5kKCh7IGNsYXNzTmFtZTogcGFyc2VDbGFzc05hbWUgfSkgPT4gY2xhc3NOYW1lID09PSBwYXJzZUNsYXNzTmFtZSkuZmllbGRzLFxuICAgICAgICAgIGtleXMsXG4gICAgICAgICAgcGFyc2VDbGFzc2VzXG4gICAgICAgIClcbiAgICAgICkge1xuICAgICAgICBvcHRpb25zLmtleXMgPSBrZXlzO1xuICAgICAgfVxuICAgICAgaWYgKGluY2x1ZGVBbGwgPT09IHRydWUpIHtcbiAgICAgICAgb3B0aW9ucy5pbmNsdWRlQWxsID0gaW5jbHVkZUFsbDtcbiAgICAgIH1cbiAgICAgIGlmICghb3B0aW9ucy5pbmNsdWRlQWxsICYmIGluY2x1ZGUpIHtcbiAgICAgICAgb3B0aW9ucy5pbmNsdWRlID0gaW5jbHVkZTtcbiAgICAgIH1cbiAgICAgIGlmICgob3B0aW9ucy5pbmNsdWRlQWxsIHx8IG9wdGlvbnMuaW5jbHVkZSkgJiYgaW5jbHVkZVJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICAgIG9wdGlvbnMuaW5jbHVkZVJlYWRQcmVmZXJlbmNlID0gaW5jbHVkZVJlYWRQcmVmZXJlbmNlO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBvcHRpb25zLmxpbWl0ID0gMDtcbiAgfVxuXG4gIGlmIChcbiAgICAoc2VsZWN0ZWRGaWVsZHMuaW5jbHVkZXMoJ2NvdW50JykgfHxcbiAgICAgIHNlbGVjdGVkRmllbGRzLmluY2x1ZGVzKCdwYWdlSW5mby5oYXNQcmV2aW91c1BhZ2UnKSB8fFxuICAgICAgc2VsZWN0ZWRGaWVsZHMuaW5jbHVkZXMoJ3BhZ2VJbmZvLmhhc05leHRQYWdlJykpICYmXG4gICAgIW5lZWRUb1ByZUNvdW50XG4gICkge1xuICAgIG9wdGlvbnMuY291bnQgPSB0cnVlO1xuICB9XG5cbiAgaWYgKHJlYWRQcmVmZXJlbmNlKSB7XG4gICAgb3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHJlYWRQcmVmZXJlbmNlO1xuICB9XG4gIGlmIChPYmplY3Qua2V5cyh3aGVyZSkubGVuZ3RoID4gMCAmJiBzdWJxdWVyeVJlYWRQcmVmZXJlbmNlKSB7XG4gICAgb3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlID0gc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgfVxuXG4gIGxldCByZXN1bHRzLCBjb3VudDtcbiAgaWYgKG9wdGlvbnMuY291bnQgfHwgIW9wdGlvbnMubGltaXQgfHwgKG9wdGlvbnMubGltaXQgJiYgb3B0aW9ucy5saW1pdCA+IDApKSB7XG4gICAgY29uc3QgZmluZFJlc3VsdCA9IGF3YWl0IHJlc3QuZmluZChcbiAgICAgIGNvbmZpZyxcbiAgICAgIGF1dGgsXG4gICAgICBjbGFzc05hbWUsXG4gICAgICB3aGVyZSxcbiAgICAgIG9wdGlvbnMsXG4gICAgICBpbmZvLmNsaWVudFNESyxcbiAgICAgIGluZm8uY29udGV4dFxuICAgICk7XG4gICAgcmVzdWx0cyA9IGZpbmRSZXN1bHQucmVzdWx0cztcbiAgICBjb3VudCA9IGZpbmRSZXN1bHQuY291bnQ7XG4gIH1cblxuICBsZXQgZWRnZXMgPSBudWxsO1xuICBsZXQgcGFnZUluZm8gPSBudWxsO1xuICBpZiAocmVzdWx0cykge1xuICAgIGVkZ2VzID0gcmVzdWx0cy5tYXAoKHJlc3VsdCwgaW5kZXgpID0+ICh7XG4gICAgICBjdXJzb3I6IG9mZnNldFRvQ3Vyc29yKChza2lwIHx8IDApICsgaW5kZXgpLFxuICAgICAgbm9kZTogcmVzdWx0LFxuICAgIH0pKTtcblxuICAgIHBhZ2VJbmZvID0ge1xuICAgICAgaGFzUHJldmlvdXNQYWdlOlxuICAgICAgICAoKHByZUNvdW50ICYmIHByZUNvdW50ID4gMCkgfHwgKGNvdW50ICYmIGNvdW50ID4gMCkpICYmIHNraXAgIT09IHVuZGVmaW5lZCAmJiBza2lwID4gMCxcbiAgICAgIHN0YXJ0Q3Vyc29yOiBvZmZzZXRUb0N1cnNvcihza2lwIHx8IDApLFxuICAgICAgZW5kQ3Vyc29yOiBvZmZzZXRUb0N1cnNvcigoc2tpcCB8fCAwKSArIChyZXN1bHRzLmxlbmd0aCB8fCAxKSAtIDEpLFxuICAgICAgaGFzTmV4dFBhZ2U6IChwcmVDb3VudCB8fCBjb3VudCkgPiAoc2tpcCB8fCAwKSArIHJlc3VsdHMubGVuZ3RoLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGVkZ2VzLFxuICAgIHBhZ2VJbmZvLFxuICAgIGNvdW50OiBwcmVDb3VudCB8fCBjb3VudCxcbiAgfTtcbn07XG5cbmNvbnN0IGNhbGN1bGF0ZVNraXBBbmRMaW1pdCA9IChza2lwSW5wdXQsIGZpcnN0LCBhZnRlciwgbGFzdCwgYmVmb3JlLCBtYXhMaW1pdCkgPT4ge1xuICBsZXQgc2tpcCA9IHVuZGVmaW5lZDtcbiAgbGV0IGxpbWl0ID0gdW5kZWZpbmVkO1xuICBsZXQgbmVlZFRvUHJlQ291bnQgPSBmYWxzZTtcblxuICAvLyBWYWxpZGF0ZXMgdGhlIHNraXAgaW5wdXRcbiAgaWYgKHNraXBJbnB1dCB8fCBza2lwSW5wdXQgPT09IDApIHtcbiAgICBpZiAoc2tpcElucHV0IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksICdTa2lwIHNob3VsZCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICAgIH1cbiAgICBza2lwID0gc2tpcElucHV0O1xuICB9XG5cbiAgLy8gVmFsaWRhdGVzIHRoZSBhZnRlciBwYXJhbVxuICBpZiAoYWZ0ZXIpIHtcbiAgICBhZnRlciA9IGN1cnNvclRvT2Zmc2V0KGFmdGVyKTtcbiAgICBpZiAoKCFhZnRlciAmJiBhZnRlciAhPT0gMCkgfHwgYWZ0ZXIgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSwgJ0FmdGVyIGlzIG5vdCBhIHZhbGlkIGN1cnNvcicpO1xuICAgIH1cblxuICAgIC8vIElmIHNraXAgYW5kIGFmdGVyIGFyZSBwYXNzZWQsIGEgbmV3IHNraXAgaXMgY2FsY3VsYXRlZCBieSBhZGRpbmcgdGhlbVxuICAgIHNraXAgPSAoc2tpcCB8fCAwKSArIChhZnRlciArIDEpO1xuICB9XG5cbiAgLy8gVmFsaWRhdGVzIHRoZSBmaXJzdCBwYXJhbVxuICBpZiAoZmlyc3QgfHwgZmlyc3QgPT09IDApIHtcbiAgICBpZiAoZmlyc3QgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSwgJ0ZpcnN0IHNob3VsZCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICAgIH1cblxuICAgIC8vIFRoZSBmaXJzdCBwYXJhbSBpcyB0cmFuc2xhdGVkIHRvIHRoZSBsaW1pdCBwYXJhbSBvZiB0aGUgUGFyc2UgbGVnYWN5IEFQSVxuICAgIGxpbWl0ID0gZmlyc3Q7XG4gIH1cblxuICAvLyBWYWxpZGF0ZXMgdGhlIGJlZm9yZSBwYXJhbVxuICBpZiAoYmVmb3JlIHx8IGJlZm9yZSA9PT0gMCkge1xuICAgIC8vIFRoaXMgbWV0aG9kIGNvbnZlcnRzIHRoZSBjdXJzb3IgdG8gdGhlIGluZGV4IG9mIHRoZSBvYmplY3RcbiAgICBiZWZvcmUgPSBjdXJzb3JUb09mZnNldChiZWZvcmUpO1xuICAgIGlmICgoIWJlZm9yZSAmJiBiZWZvcmUgIT09IDApIHx8IGJlZm9yZSA8IDApIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnQmVmb3JlIGlzIG5vdCBhIHZhbGlkIGN1cnNvcicpO1xuICAgIH1cblxuICAgIGlmICgoc2tpcCB8fCAwKSA+PSBiZWZvcmUpIHtcbiAgICAgIC8vIElmIHRoZSBiZWZvcmUgaW5kZXggaXMgbGVzcyB0aGVuIHRoZSBza2lwLCBubyBvYmplY3RzIHdpbGwgYmUgcmV0dXJuZWRcbiAgICAgIGxpbWl0ID0gMDtcbiAgICB9IGVsc2UgaWYgKCghbGltaXQgJiYgbGltaXQgIT09IDApIHx8IChza2lwIHx8IDApICsgbGltaXQgPiBiZWZvcmUpIHtcbiAgICAgIC8vIElmIHRoZXJlIGlzIG5vIGxpbWl0IHNldCwgdGhlIGxpbWl0IGlzIGNhbGN1bGF0ZWQuIE9yLCBpZiB0aGUgbGltaXQgKHBsdXMgc2tpcCkgaXMgYmlnZ2VyIHRoYW4gdGhlIGJlZm9yZSBpbmRleCwgdGhlIG5ldyBsaW1pdCBpcyBzZXQuXG4gICAgICBsaW1pdCA9IGJlZm9yZSAtIChza2lwIHx8IDApO1xuICAgIH1cbiAgfVxuXG4gIC8vIFZhbGlkYXRlcyB0aGUgbGFzdCBwYXJhbVxuICBpZiAobGFzdCB8fCBsYXN0ID09PSAwKSB7XG4gICAgaWYgKGxhc3QgPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSwgJ0xhc3Qgc2hvdWxkIGJlIGEgcG9zaXRpdmUgbnVtYmVyJyk7XG4gICAgfVxuXG4gICAgaWYgKGxhc3QgPiBtYXhMaW1pdCkge1xuICAgICAgLy8gTGFzdCBjYW4ndCBiZSBiaWdnZXIgdGhhbiBQYXJzZSBzZXJ2ZXIgbWF4TGltaXQgY29uZmlnLlxuICAgICAgbGFzdCA9IG1heExpbWl0O1xuICAgIH1cblxuICAgIGlmIChsaW1pdCB8fCBsaW1pdCA9PT0gMCkge1xuICAgICAgLy8gSWYgdGhlcmUgaXMgYSBwcmV2aW91cyBsaW1pdCBzZXQsIGl0IG1heSBiZSBhZGp1c3RlZFxuICAgICAgaWYgKGxhc3QgPCBsaW1pdCkge1xuICAgICAgICAvLyBpZiBsYXN0IGlzIGxlc3MgdGhhbiB0aGUgY3VycmVudCBsaW1pdFxuICAgICAgICBza2lwID0gKHNraXAgfHwgMCkgKyAobGltaXQgLSBsYXN0KTsgLy8gVGhlIHNraXAgaXMgYWRqdXN0ZWRcbiAgICAgICAgbGltaXQgPSBsYXN0OyAvLyB0aGUgbGltaXQgaXMgYWRqdXN0ZWRcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGxhc3QgPT09IDApIHtcbiAgICAgIC8vIE5vIG9iamVjdHMgd2lsbCBiZSByZXR1cm5lZFxuICAgICAgbGltaXQgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBObyBwcmV2aW91cyBsaW1pdCBzZXQsIHRoZSBsaW1pdCB3aWxsIGJlIGVxdWFsIHRvIGxhc3QgYW5kIHByZSBjb3VudCBpcyBuZWVkZWQuXG4gICAgICBsaW1pdCA9IGxhc3Q7XG4gICAgICBuZWVkVG9QcmVDb3VudCA9IHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiB7XG4gICAgc2tpcCxcbiAgICBsaW1pdCxcbiAgICBuZWVkVG9QcmVDb3VudCxcbiAgfTtcbn07XG5cbmV4cG9ydCB7IGdldE9iamVjdCwgZmluZE9iamVjdHMsIGNhbGN1bGF0ZVNraXBBbmRMaW1pdCwgbmVlZFRvR2V0QWxsS2V5cyB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/defaultGraphQLMutations.js b/lib/GraphQL/loaders/defaultGraphQLMutations.js deleted file mode 100644 index afe32cc4fb..0000000000 --- a/lib/GraphQL/loaders/defaultGraphQLMutations.js +++ /dev/null @@ -1,28 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = void 0; - -var filesMutations = _interopRequireWildcard(require("./filesMutations")); - -var usersMutations = _interopRequireWildcard(require("./usersMutations")); - -var functionsMutations = _interopRequireWildcard(require("./functionsMutations")); - -var schemaMutations = _interopRequireWildcard(require("./schemaMutations")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -const load = parseGraphQLSchema => { - filesMutations.load(parseGraphQLSchema); - usersMutations.load(parseGraphQLSchema); - functionsMutations.load(parseGraphQLSchema); - schemaMutations.load(parseGraphQLSchema); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxNdXRhdGlvbnMuanMiXSwibmFtZXMiOlsibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsImZpbGVzTXV0YXRpb25zIiwidXNlcnNNdXRhdGlvbnMiLCJmdW5jdGlvbnNNdXRhdGlvbnMiLCJzY2hlbWFNdXRhdGlvbnMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7O0FBRUEsTUFBTUEsSUFBSSxHQUFHQyxrQkFBa0IsSUFBSTtBQUNqQ0MsRUFBQUEsY0FBYyxDQUFDRixJQUFmLENBQW9CQyxrQkFBcEI7QUFDQUUsRUFBQUEsY0FBYyxDQUFDSCxJQUFmLENBQW9CQyxrQkFBcEI7QUFDQUcsRUFBQUEsa0JBQWtCLENBQUNKLElBQW5CLENBQXdCQyxrQkFBeEI7QUFDQUksRUFBQUEsZUFBZSxDQUFDTCxJQUFoQixDQUFxQkMsa0JBQXJCO0FBQ0QsQ0FMRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZpbGVzTXV0YXRpb25zIGZyb20gJy4vZmlsZXNNdXRhdGlvbnMnO1xuaW1wb3J0ICogYXMgdXNlcnNNdXRhdGlvbnMgZnJvbSAnLi91c2Vyc011dGF0aW9ucyc7XG5pbXBvcnQgKiBhcyBmdW5jdGlvbnNNdXRhdGlvbnMgZnJvbSAnLi9mdW5jdGlvbnNNdXRhdGlvbnMnO1xuaW1wb3J0ICogYXMgc2NoZW1hTXV0YXRpb25zIGZyb20gJy4vc2NoZW1hTXV0YXRpb25zJztcblxuY29uc3QgbG9hZCA9IHBhcnNlR3JhcGhRTFNjaGVtYSA9PiB7XG4gIGZpbGVzTXV0YXRpb25zLmxvYWQocGFyc2VHcmFwaFFMU2NoZW1hKTtcbiAgdXNlcnNNdXRhdGlvbnMubG9hZChwYXJzZUdyYXBoUUxTY2hlbWEpO1xuICBmdW5jdGlvbnNNdXRhdGlvbnMubG9hZChwYXJzZUdyYXBoUUxTY2hlbWEpO1xuICBzY2hlbWFNdXRhdGlvbnMubG9hZChwYXJzZUdyYXBoUUxTY2hlbWEpO1xufTtcblxuZXhwb3J0IHsgbG9hZCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/defaultGraphQLQueries.js b/lib/GraphQL/loaders/defaultGraphQLQueries.js deleted file mode 100644 index 58a4f474d6..0000000000 --- a/lib/GraphQL/loaders/defaultGraphQLQueries.js +++ /dev/null @@ -1,29 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = void 0; - -var _graphql = require("graphql"); - -var usersQueries = _interopRequireWildcard(require("./usersQueries")); - -var schemaQueries = _interopRequireWildcard(require("./schemaQueries")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -const load = parseGraphQLSchema => { - parseGraphQLSchema.addGraphQLQuery('health', { - description: 'The health query can be used to check if the server is up and running.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean), - resolve: () => true - }, true, true); - usersQueries.load(parseGraphQLSchema); - schemaQueries.load(parseGraphQLSchema); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxRdWVyaWVzLmpzIl0sIm5hbWVzIjpbImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJhZGRHcmFwaFFMUXVlcnkiLCJkZXNjcmlwdGlvbiIsInR5cGUiLCJHcmFwaFFMTm9uTnVsbCIsIkdyYXBoUUxCb29sZWFuIiwicmVzb2x2ZSIsInVzZXJzUXVlcmllcyIsInNjaGVtYVF1ZXJpZXMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7O0FBRUEsTUFBTUEsSUFBSSxHQUFHQyxrQkFBa0IsSUFBSTtBQUNqQ0EsRUFBQUEsa0JBQWtCLENBQUNDLGVBQW5CLENBQ0UsUUFERixFQUVFO0FBQ0VDLElBQUFBLFdBQVcsRUFBRSx3RUFEZjtBQUVFQyxJQUFBQSxJQUFJLEVBQUUsSUFBSUMsdUJBQUosQ0FBbUJDLHVCQUFuQixDQUZSO0FBR0VDLElBQUFBLE9BQU8sRUFBRSxNQUFNO0FBSGpCLEdBRkYsRUFPRSxJQVBGLEVBUUUsSUFSRjtBQVdBQyxFQUFBQSxZQUFZLENBQUNSLElBQWIsQ0FBa0JDLGtCQUFsQjtBQUNBUSxFQUFBQSxhQUFhLENBQUNULElBQWQsQ0FBbUJDLGtCQUFuQjtBQUNELENBZEQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBHcmFwaFFMTm9uTnVsbCwgR3JhcGhRTEJvb2xlYW4gfSBmcm9tICdncmFwaHFsJztcbmltcG9ydCAqIGFzIHVzZXJzUXVlcmllcyBmcm9tICcuL3VzZXJzUXVlcmllcyc7XG5pbXBvcnQgKiBhcyBzY2hlbWFRdWVyaWVzIGZyb20gJy4vc2NoZW1hUXVlcmllcyc7XG5cbmNvbnN0IGxvYWQgPSBwYXJzZUdyYXBoUUxTY2hlbWEgPT4ge1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFF1ZXJ5KFxuICAgICdoZWFsdGgnLFxuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIGhlYWx0aCBxdWVyeSBjYW4gYmUgdXNlZCB0byBjaGVjayBpZiB0aGUgc2VydmVyIGlzIHVwIGFuZCBydW5uaW5nLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgICAgcmVzb2x2ZTogKCkgPT4gdHJ1ZSxcbiAgICB9LFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuXG4gIHVzZXJzUXVlcmllcy5sb2FkKHBhcnNlR3JhcGhRTFNjaGVtYSk7XG4gIHNjaGVtYVF1ZXJpZXMubG9hZChwYXJzZUdyYXBoUUxTY2hlbWEpO1xufTtcblxuZXhwb3J0IHsgbG9hZCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/defaultGraphQLTypes.js b/lib/GraphQL/loaders/defaultGraphQLTypes.js deleted file mode 100644 index 14487e4658..0000000000 --- a/lib/GraphQL/loaders/defaultGraphQLTypes.js +++ /dev/null @@ -1,1271 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.loadArrayResult = exports.load = exports.PUBLIC_ACL = exports.ROLE_ACL = exports.USER_ACL = exports.ACL = exports.PUBLIC_ACL_INPUT = exports.ROLE_ACL_INPUT = exports.USER_ACL_INPUT = exports.ACL_INPUT = exports.ELEMENT = exports.ARRAY_RESULT = exports.POLYGON_WHERE_INPUT = exports.GEO_POINT_WHERE_INPUT = exports.FILE_WHERE_INPUT = exports.BYTES_WHERE_INPUT = exports.DATE_WHERE_INPUT = exports.OBJECT_WHERE_INPUT = exports.KEY_VALUE_INPUT = exports.ARRAY_WHERE_INPUT = exports.BOOLEAN_WHERE_INPUT = exports.NUMBER_WHERE_INPUT = exports.STRING_WHERE_INPUT = exports.ID_WHERE_INPUT = exports.notInQueryKey = exports.inQueryKey = exports.options = exports.matchesRegex = exports.exists = exports.notIn = exports.inOp = exports.greaterThanOrEqualTo = exports.greaterThan = exports.lessThanOrEqualTo = exports.lessThan = exports.notEqualTo = exports.equalTo = exports.GEO_INTERSECTS_INPUT = exports.GEO_WITHIN_INPUT = exports.CENTER_SPHERE_INPUT = exports.WITHIN_INPUT = exports.BOX_INPUT = exports.TEXT_INPUT = exports.SEARCH_INPUT = exports.COUNT_ATT = exports.LIMIT_ATT = exports.SKIP_ATT = exports.WHERE_ATT = exports.READ_OPTIONS_ATT = exports.READ_OPTIONS_INPUT = exports.SUBQUERY_READ_PREFERENCE_ATT = exports.INCLUDE_READ_PREFERENCE_ATT = exports.READ_PREFERENCE_ATT = exports.READ_PREFERENCE = exports.SESSION_TOKEN_ATT = exports.PARSE_OBJECT = exports.PARSE_OBJECT_FIELDS = exports.UPDATE_RESULT_FIELDS = exports.CREATE_RESULT_FIELDS = exports.INPUT_FIELDS = exports.CREATED_AT_ATT = exports.UPDATED_AT_ATT = exports.OBJECT_ID_ATT = exports.GLOBAL_OR_OBJECT_ID_ATT = exports.CLASS_NAME_ATT = exports.OBJECT_ID = exports.POLYGON = exports.POLYGON_INPUT = exports.GEO_POINT = exports.GEO_POINT_INPUT = exports.GEO_POINT_FIELDS = exports.FILE_INPUT = exports.FILE_INFO = exports.FILE = exports.SELECT_INPUT = exports.SUBQUERY_INPUT = exports.parseFileValue = exports.BYTES = exports.DATE = exports.serializeDateIso = exports.parseDateIsoValue = exports.OBJECT = exports.ANY = exports.parseObjectFields = exports.parseListValues = exports.parseValue = exports.parseBooleanValue = exports.parseFloatValue = exports.parseIntValue = exports.parseStringValue = exports.TypeValidationError = void 0; - -var _graphql = require("graphql"); - -var _graphqlRelay = require("graphql-relay"); - -var _links = require("@graphql-tools/links"); - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -class TypeValidationError extends Error { - constructor(value, type) { - super(`${value} is not a valid ${type}`); - } - -} - -exports.TypeValidationError = TypeValidationError; - -const parseStringValue = value => { - if (typeof value === 'string') { - return value; - } - - throw new TypeValidationError(value, 'String'); -}; - -exports.parseStringValue = parseStringValue; - -const parseIntValue = value => { - if (typeof value === 'string') { - const int = Number(value); - - if (Number.isInteger(int)) { - return int; - } - } - - throw new TypeValidationError(value, 'Int'); -}; - -exports.parseIntValue = parseIntValue; - -const parseFloatValue = value => { - if (typeof value === 'string') { - const float = Number(value); - - if (!isNaN(float)) { - return float; - } - } - - throw new TypeValidationError(value, 'Float'); -}; - -exports.parseFloatValue = parseFloatValue; - -const parseBooleanValue = value => { - if (typeof value === 'boolean') { - return value; - } - - throw new TypeValidationError(value, 'Boolean'); -}; - -exports.parseBooleanValue = parseBooleanValue; - -const parseValue = value => { - switch (value.kind) { - case _graphql.Kind.STRING: - return parseStringValue(value.value); - - case _graphql.Kind.INT: - return parseIntValue(value.value); - - case _graphql.Kind.FLOAT: - return parseFloatValue(value.value); - - case _graphql.Kind.BOOLEAN: - return parseBooleanValue(value.value); - - case _graphql.Kind.LIST: - return parseListValues(value.values); - - case _graphql.Kind.OBJECT: - return parseObjectFields(value.fields); - - default: - return value.value; - } -}; - -exports.parseValue = parseValue; - -const parseListValues = values => { - if (Array.isArray(values)) { - return values.map(value => parseValue(value)); - } - - throw new TypeValidationError(values, 'List'); -}; - -exports.parseListValues = parseListValues; - -const parseObjectFields = fields => { - if (Array.isArray(fields)) { - return fields.reduce((object, field) => _objectSpread(_objectSpread({}, object), {}, { - [field.name.value]: parseValue(field.value) - }), {}); - } - - throw new TypeValidationError(fields, 'Object'); -}; - -exports.parseObjectFields = parseObjectFields; -const ANY = new _graphql.GraphQLScalarType({ - name: 'Any', - description: 'The Any scalar type is used in operations and types that involve any type of value.', - parseValue: value => value, - serialize: value => value, - parseLiteral: ast => parseValue(ast) -}); -exports.ANY = ANY; -const OBJECT = new _graphql.GraphQLScalarType({ - name: 'Object', - description: 'The Object scalar type is used in operations and types that involve objects.', - - parseValue(value) { - if (typeof value === 'object') { - return value; - } - - throw new TypeValidationError(value, 'Object'); - }, - - serialize(value) { - if (typeof value === 'object') { - return value; - } - - throw new TypeValidationError(value, 'Object'); - }, - - parseLiteral(ast) { - if (ast.kind === _graphql.Kind.OBJECT) { - return parseObjectFields(ast.fields); - } - - throw new TypeValidationError(ast.kind, 'Object'); - } - -}); -exports.OBJECT = OBJECT; - -const parseDateIsoValue = value => { - if (typeof value === 'string') { - const date = new Date(value); - - if (!isNaN(date)) { - return date; - } - } else if (value instanceof Date) { - return value; - } - - throw new TypeValidationError(value, 'Date'); -}; - -exports.parseDateIsoValue = parseDateIsoValue; - -const serializeDateIso = value => { - if (typeof value === 'string') { - return value; - } - - if (value instanceof Date) { - return value.toISOString(); - } - - throw new TypeValidationError(value, 'Date'); -}; - -exports.serializeDateIso = serializeDateIso; - -const parseDateIsoLiteral = ast => { - if (ast.kind === _graphql.Kind.STRING) { - return parseDateIsoValue(ast.value); - } - - throw new TypeValidationError(ast.kind, 'Date'); -}; - -const DATE = new _graphql.GraphQLScalarType({ - name: 'Date', - description: 'The Date scalar type is used in operations and types that involve dates.', - - parseValue(value) { - if (typeof value === 'string' || value instanceof Date) { - return { - __type: 'Date', - iso: parseDateIsoValue(value) - }; - } else if (typeof value === 'object' && value.__type === 'Date' && value.iso) { - return { - __type: value.__type, - iso: parseDateIsoValue(value.iso) - }; - } - - throw new TypeValidationError(value, 'Date'); - }, - - serialize(value) { - if (typeof value === 'string' || value instanceof Date) { - return serializeDateIso(value); - } else if (typeof value === 'object' && value.__type === 'Date' && value.iso) { - return serializeDateIso(value.iso); - } - - throw new TypeValidationError(value, 'Date'); - }, - - parseLiteral(ast) { - if (ast.kind === _graphql.Kind.STRING) { - return { - __type: 'Date', - iso: parseDateIsoLiteral(ast) - }; - } else if (ast.kind === _graphql.Kind.OBJECT) { - const __type = ast.fields.find(field => field.name.value === '__type'); - - const iso = ast.fields.find(field => field.name.value === 'iso'); - - if (__type && __type.value && __type.value.value === 'Date' && iso) { - return { - __type: __type.value.value, - iso: parseDateIsoLiteral(iso.value) - }; - } - } - - throw new TypeValidationError(ast.kind, 'Date'); - } - -}); -exports.DATE = DATE; -const BYTES = new _graphql.GraphQLScalarType({ - name: 'Bytes', - description: 'The Bytes scalar type is used in operations and types that involve base 64 binary data.', - - parseValue(value) { - if (typeof value === 'string') { - return { - __type: 'Bytes', - base64: value - }; - } else if (typeof value === 'object' && value.__type === 'Bytes' && typeof value.base64 === 'string') { - return value; - } - - throw new TypeValidationError(value, 'Bytes'); - }, - - serialize(value) { - if (typeof value === 'string') { - return value; - } else if (typeof value === 'object' && value.__type === 'Bytes' && typeof value.base64 === 'string') { - return value.base64; - } - - throw new TypeValidationError(value, 'Bytes'); - }, - - parseLiteral(ast) { - if (ast.kind === _graphql.Kind.STRING) { - return { - __type: 'Bytes', - base64: ast.value - }; - } else if (ast.kind === _graphql.Kind.OBJECT) { - const __type = ast.fields.find(field => field.name.value === '__type'); - - const base64 = ast.fields.find(field => field.name.value === 'base64'); - - if (__type && __type.value && __type.value.value === 'Bytes' && base64 && base64.value && typeof base64.value.value === 'string') { - return { - __type: __type.value.value, - base64: base64.value.value - }; - } - } - - throw new TypeValidationError(ast.kind, 'Bytes'); - } - -}); -exports.BYTES = BYTES; - -const parseFileValue = value => { - if (typeof value === 'string') { - return { - __type: 'File', - name: value - }; - } else if (typeof value === 'object' && value.__type === 'File' && typeof value.name === 'string' && (value.url === undefined || typeof value.url === 'string')) { - return value; - } - - throw new TypeValidationError(value, 'File'); -}; - -exports.parseFileValue = parseFileValue; -const FILE = new _graphql.GraphQLScalarType({ - name: 'File', - description: 'The File scalar type is used in operations and types that involve files.', - parseValue: parseFileValue, - serialize: value => { - if (typeof value === 'string') { - return value; - } else if (typeof value === 'object' && value.__type === 'File' && typeof value.name === 'string' && (value.url === undefined || typeof value.url === 'string')) { - return value.name; - } - - throw new TypeValidationError(value, 'File'); - }, - - parseLiteral(ast) { - if (ast.kind === _graphql.Kind.STRING) { - return parseFileValue(ast.value); - } else if (ast.kind === _graphql.Kind.OBJECT) { - const __type = ast.fields.find(field => field.name.value === '__type'); - - const name = ast.fields.find(field => field.name.value === 'name'); - const url = ast.fields.find(field => field.name.value === 'url'); - - if (__type && __type.value && name && name.value) { - return parseFileValue({ - __type: __type.value.value, - name: name.value.value, - url: url && url.value ? url.value.value : undefined - }); - } - } - - throw new TypeValidationError(ast.kind, 'File'); - } - -}); -exports.FILE = FILE; -const FILE_INFO = new _graphql.GraphQLObjectType({ - name: 'FileInfo', - description: 'The FileInfo object type is used to return the information about files.', - fields: { - name: { - description: 'This is the file name.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - }, - url: { - description: 'This is the url in which the file can be downloaded.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - } - } -}); -exports.FILE_INFO = FILE_INFO; -const FILE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'FileInput', - fields: { - file: { - description: 'A File Scalar can be an url or a FileInfo object. If this field is set to null the file will be unlinked.', - type: FILE - }, - upload: { - description: 'Use this field if you want to create a new file.', - type: _links.GraphQLUpload - }, - unlink: { - description: 'Use this field if you want to unlink the file (the file will not be deleted on cloud storage)', - type: _graphql.GraphQLBoolean - } - } -}); -exports.FILE_INPUT = FILE_INPUT; -const GEO_POINT_FIELDS = { - latitude: { - description: 'This is the latitude.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLFloat) - }, - longitude: { - description: 'This is the longitude.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLFloat) - } -}; -exports.GEO_POINT_FIELDS = GEO_POINT_FIELDS; -const GEO_POINT_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'GeoPointInput', - description: 'The GeoPointInput type is used in operations that involve inputting fields of type geo point.', - fields: GEO_POINT_FIELDS -}); -exports.GEO_POINT_INPUT = GEO_POINT_INPUT; -const GEO_POINT = new _graphql.GraphQLObjectType({ - name: 'GeoPoint', - description: 'The GeoPoint object type is used to return the information about geo point fields.', - fields: GEO_POINT_FIELDS -}); -exports.GEO_POINT = GEO_POINT; -const POLYGON_INPUT = new _graphql.GraphQLList(new _graphql.GraphQLNonNull(GEO_POINT_INPUT)); -exports.POLYGON_INPUT = POLYGON_INPUT; -const POLYGON = new _graphql.GraphQLList(new _graphql.GraphQLNonNull(GEO_POINT)); -exports.POLYGON = POLYGON; -const USER_ACL_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'UserACLInput', - description: 'Allow to manage users in ACL.', - fields: { - userId: { - description: 'ID of the targetted User.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLID) - }, - read: { - description: 'Allow the user to read the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - }, - write: { - description: 'Allow the user to write on the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - } - } -}); -exports.USER_ACL_INPUT = USER_ACL_INPUT; -const ROLE_ACL_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'RoleACLInput', - description: 'Allow to manage roles in ACL.', - fields: { - roleName: { - description: 'Name of the targetted Role.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - }, - read: { - description: 'Allow users who are members of the role to read the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - }, - write: { - description: 'Allow users who are members of the role to write on the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - } - } -}); -exports.ROLE_ACL_INPUT = ROLE_ACL_INPUT; -const PUBLIC_ACL_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'PublicACLInput', - description: 'Allow to manage public rights.', - fields: { - read: { - description: 'Allow anyone to read the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - }, - write: { - description: 'Allow anyone to write on the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - } - } -}); -exports.PUBLIC_ACL_INPUT = PUBLIC_ACL_INPUT; -const ACL_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'ACLInput', - description: 'Allow to manage access rights. If not provided object will be publicly readable and writable', - fields: { - users: { - description: 'Access control list for users.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(USER_ACL_INPUT)) - }, - roles: { - description: 'Access control list for roles.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(ROLE_ACL_INPUT)) - }, - public: { - description: 'Public access control list.', - type: PUBLIC_ACL_INPUT - } - } -}); -exports.ACL_INPUT = ACL_INPUT; -const USER_ACL = new _graphql.GraphQLObjectType({ - name: 'UserACL', - description: 'Allow to manage users in ACL. If read and write are null the users have read and write rights.', - fields: { - userId: { - description: 'ID of the targetted User.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLID) - }, - read: { - description: 'Allow the user to read the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - }, - write: { - description: 'Allow the user to write on the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - } - } -}); -exports.USER_ACL = USER_ACL; -const ROLE_ACL = new _graphql.GraphQLObjectType({ - name: 'RoleACL', - description: 'Allow to manage roles in ACL. If read and write are null the role have read and write rights.', - fields: { - roleName: { - description: 'Name of the targetted Role.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLID) - }, - read: { - description: 'Allow users who are members of the role to read the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - }, - write: { - description: 'Allow users who are members of the role to write on the current object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - } - } -}); -exports.ROLE_ACL = ROLE_ACL; -const PUBLIC_ACL = new _graphql.GraphQLObjectType({ - name: 'PublicACL', - description: 'Allow to manage public rights.', - fields: { - read: { - description: 'Allow anyone to read the current object.', - type: _graphql.GraphQLBoolean - }, - write: { - description: 'Allow anyone to write on the current object.', - type: _graphql.GraphQLBoolean - } - } -}); -exports.PUBLIC_ACL = PUBLIC_ACL; -const ACL = new _graphql.GraphQLObjectType({ - name: 'ACL', - description: 'Current access control list of the current object.', - fields: { - users: { - description: 'Access control list for users.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(USER_ACL)), - - resolve(p) { - const users = []; - Object.keys(p).forEach(rule => { - if (rule !== '*' && rule.indexOf('role:') !== 0) { - users.push({ - userId: (0, _graphqlRelay.toGlobalId)('_User', rule), - read: p[rule].read ? true : false, - write: p[rule].write ? true : false - }); - } - }); - return users.length ? users : null; - } - - }, - roles: { - description: 'Access control list for roles.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(ROLE_ACL)), - - resolve(p) { - const roles = []; - Object.keys(p).forEach(rule => { - if (rule.indexOf('role:') === 0) { - roles.push({ - roleName: rule.replace('role:', ''), - read: p[rule].read ? true : false, - write: p[rule].write ? true : false - }); - } - }); - return roles.length ? roles : null; - } - - }, - public: { - description: 'Public access control list.', - type: PUBLIC_ACL, - - resolve(p) { - /* eslint-disable */ - return p['*'] ? { - read: p['*'].read ? true : false, - write: p['*'].write ? true : false - } : null; - } - - } - } -}); -exports.ACL = ACL; -const OBJECT_ID = new _graphql.GraphQLNonNull(_graphql.GraphQLID); -exports.OBJECT_ID = OBJECT_ID; -const CLASS_NAME_ATT = { - description: 'This is the class name of the object.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) -}; -exports.CLASS_NAME_ATT = CLASS_NAME_ATT; -const GLOBAL_OR_OBJECT_ID_ATT = { - description: 'This is the object id. You can use either the global or the object id.', - type: OBJECT_ID -}; -exports.GLOBAL_OR_OBJECT_ID_ATT = GLOBAL_OR_OBJECT_ID_ATT; -const OBJECT_ID_ATT = { - description: 'This is the object id.', - type: OBJECT_ID -}; -exports.OBJECT_ID_ATT = OBJECT_ID_ATT; -const CREATED_AT_ATT = { - description: 'This is the date in which the object was created.', - type: new _graphql.GraphQLNonNull(DATE) -}; -exports.CREATED_AT_ATT = CREATED_AT_ATT; -const UPDATED_AT_ATT = { - description: 'This is the date in which the object was las updated.', - type: new _graphql.GraphQLNonNull(DATE) -}; -exports.UPDATED_AT_ATT = UPDATED_AT_ATT; -const INPUT_FIELDS = { - ACL: { - type: ACL - } -}; -exports.INPUT_FIELDS = INPUT_FIELDS; -const CREATE_RESULT_FIELDS = { - objectId: OBJECT_ID_ATT, - createdAt: CREATED_AT_ATT -}; -exports.CREATE_RESULT_FIELDS = CREATE_RESULT_FIELDS; -const UPDATE_RESULT_FIELDS = { - updatedAt: UPDATED_AT_ATT -}; -exports.UPDATE_RESULT_FIELDS = UPDATE_RESULT_FIELDS; - -const PARSE_OBJECT_FIELDS = _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, CREATE_RESULT_FIELDS), UPDATE_RESULT_FIELDS), INPUT_FIELDS), {}, { - ACL: { - type: new _graphql.GraphQLNonNull(ACL), - resolve: ({ - ACL - }) => ACL ? ACL : { - '*': { - read: true, - write: true - } - } - } -}); - -exports.PARSE_OBJECT_FIELDS = PARSE_OBJECT_FIELDS; -const PARSE_OBJECT = new _graphql.GraphQLInterfaceType({ - name: 'ParseObject', - description: 'The ParseObject interface type is used as a base type for the auto generated object types.', - fields: PARSE_OBJECT_FIELDS -}); -exports.PARSE_OBJECT = PARSE_OBJECT; -const SESSION_TOKEN_ATT = { - description: 'The current user session token.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) -}; -exports.SESSION_TOKEN_ATT = SESSION_TOKEN_ATT; -const READ_PREFERENCE = new _graphql.GraphQLEnumType({ - name: 'ReadPreference', - description: 'The ReadPreference enum type is used in queries in order to select in which database replica the operation must run.', - values: { - PRIMARY: { - value: 'PRIMARY' - }, - PRIMARY_PREFERRED: { - value: 'PRIMARY_PREFERRED' - }, - SECONDARY: { - value: 'SECONDARY' - }, - SECONDARY_PREFERRED: { - value: 'SECONDARY_PREFERRED' - }, - NEAREST: { - value: 'NEAREST' - } - } -}); -exports.READ_PREFERENCE = READ_PREFERENCE; -const READ_PREFERENCE_ATT = { - description: 'The read preference for the main query to be executed.', - type: READ_PREFERENCE -}; -exports.READ_PREFERENCE_ATT = READ_PREFERENCE_ATT; -const INCLUDE_READ_PREFERENCE_ATT = { - description: 'The read preference for the queries to be executed to include fields.', - type: READ_PREFERENCE -}; -exports.INCLUDE_READ_PREFERENCE_ATT = INCLUDE_READ_PREFERENCE_ATT; -const SUBQUERY_READ_PREFERENCE_ATT = { - description: 'The read preference for the subqueries that may be required.', - type: READ_PREFERENCE -}; -exports.SUBQUERY_READ_PREFERENCE_ATT = SUBQUERY_READ_PREFERENCE_ATT; -const READ_OPTIONS_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'ReadOptionsInput', - description: 'The ReadOptionsInputt type is used in queries in order to set the read preferences.', - fields: { - readPreference: READ_PREFERENCE_ATT, - includeReadPreference: INCLUDE_READ_PREFERENCE_ATT, - subqueryReadPreference: SUBQUERY_READ_PREFERENCE_ATT - } -}); -exports.READ_OPTIONS_INPUT = READ_OPTIONS_INPUT; -const READ_OPTIONS_ATT = { - description: 'The read options for the query to be executed.', - type: READ_OPTIONS_INPUT -}; -exports.READ_OPTIONS_ATT = READ_OPTIONS_ATT; -const WHERE_ATT = { - description: 'These are the conditions that the objects need to match in order to be found', - type: OBJECT -}; -exports.WHERE_ATT = WHERE_ATT; -const SKIP_ATT = { - description: 'This is the number of objects that must be skipped to return.', - type: _graphql.GraphQLInt -}; -exports.SKIP_ATT = SKIP_ATT; -const LIMIT_ATT = { - description: 'This is the limit number of objects that must be returned.', - type: _graphql.GraphQLInt -}; -exports.LIMIT_ATT = LIMIT_ATT; -const COUNT_ATT = { - description: 'This is the total matched objecs count that is returned when the count flag is set.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLInt) -}; -exports.COUNT_ATT = COUNT_ATT; -const SEARCH_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SearchInput', - description: 'The SearchInput type is used to specifiy a search operation on a full text search.', - fields: { - term: { - description: 'This is the term to be searched.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - }, - language: { - description: 'This is the language to tetermine the list of stop words and the rules for tokenizer.', - type: _graphql.GraphQLString - }, - caseSensitive: { - description: 'This is the flag to enable or disable case sensitive search.', - type: _graphql.GraphQLBoolean - }, - diacriticSensitive: { - description: 'This is the flag to enable or disable diacritic sensitive search.', - type: _graphql.GraphQLBoolean - } - } -}); -exports.SEARCH_INPUT = SEARCH_INPUT; -const TEXT_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'TextInput', - description: 'The TextInput type is used to specify a text operation on a constraint.', - fields: { - search: { - description: 'This is the search to be executed.', - type: new _graphql.GraphQLNonNull(SEARCH_INPUT) - } - } -}); -exports.TEXT_INPUT = TEXT_INPUT; -const BOX_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'BoxInput', - description: 'The BoxInput type is used to specifiy a box operation on a within geo query.', - fields: { - bottomLeft: { - description: 'This is the bottom left coordinates of the box.', - type: new _graphql.GraphQLNonNull(GEO_POINT_INPUT) - }, - upperRight: { - description: 'This is the upper right coordinates of the box.', - type: new _graphql.GraphQLNonNull(GEO_POINT_INPUT) - } - } -}); -exports.BOX_INPUT = BOX_INPUT; -const WITHIN_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'WithinInput', - description: 'The WithinInput type is used to specify a within operation on a constraint.', - fields: { - box: { - description: 'This is the box to be specified.', - type: new _graphql.GraphQLNonNull(BOX_INPUT) - } - } -}); -exports.WITHIN_INPUT = WITHIN_INPUT; -const CENTER_SPHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'CenterSphereInput', - description: 'The CenterSphereInput type is used to specifiy a centerSphere operation on a geoWithin query.', - fields: { - center: { - description: 'This is the center of the sphere.', - type: new _graphql.GraphQLNonNull(GEO_POINT_INPUT) - }, - distance: { - description: 'This is the radius of the sphere.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLFloat) - } - } -}); -exports.CENTER_SPHERE_INPUT = CENTER_SPHERE_INPUT; -const GEO_WITHIN_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'GeoWithinInput', - description: 'The GeoWithinInput type is used to specify a geoWithin operation on a constraint.', - fields: { - polygon: { - description: 'This is the polygon to be specified.', - type: POLYGON_INPUT - }, - centerSphere: { - description: 'This is the sphere to be specified.', - type: CENTER_SPHERE_INPUT - } - } -}); -exports.GEO_WITHIN_INPUT = GEO_WITHIN_INPUT; -const GEO_INTERSECTS_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'GeoIntersectsInput', - description: 'The GeoIntersectsInput type is used to specify a geoIntersects operation on a constraint.', - fields: { - point: { - description: 'This is the point to be specified.', - type: GEO_POINT_INPUT - } - } -}); -exports.GEO_INTERSECTS_INPUT = GEO_INTERSECTS_INPUT; - -const equalTo = type => ({ - description: 'This is the equalTo operator to specify a constraint to select the objects where the value of a field equals to a specified value.', - type -}); - -exports.equalTo = equalTo; - -const notEqualTo = type => ({ - description: 'This is the notEqualTo operator to specify a constraint to select the objects where the value of a field do not equal to a specified value.', - type -}); - -exports.notEqualTo = notEqualTo; - -const lessThan = type => ({ - description: 'This is the lessThan operator to specify a constraint to select the objects where the value of a field is less than a specified value.', - type -}); - -exports.lessThan = lessThan; - -const lessThanOrEqualTo = type => ({ - description: 'This is the lessThanOrEqualTo operator to specify a constraint to select the objects where the value of a field is less than or equal to a specified value.', - type -}); - -exports.lessThanOrEqualTo = lessThanOrEqualTo; - -const greaterThan = type => ({ - description: 'This is the greaterThan operator to specify a constraint to select the objects where the value of a field is greater than a specified value.', - type -}); - -exports.greaterThan = greaterThan; - -const greaterThanOrEqualTo = type => ({ - description: 'This is the greaterThanOrEqualTo operator to specify a constraint to select the objects where the value of a field is greater than or equal to a specified value.', - type -}); - -exports.greaterThanOrEqualTo = greaterThanOrEqualTo; - -const inOp = type => ({ - description: 'This is the in operator to specify a constraint to select the objects where the value of a field equals any value in the specified array.', - type: new _graphql.GraphQLList(type) -}); - -exports.inOp = inOp; - -const notIn = type => ({ - description: 'This is the notIn operator to specify a constraint to select the objects where the value of a field do not equal any value in the specified array.', - type: new _graphql.GraphQLList(type) -}); - -exports.notIn = notIn; -const exists = { - description: 'This is the exists operator to specify a constraint to select the objects where a field exists (or do not exist).', - type: _graphql.GraphQLBoolean -}; -exports.exists = exists; -const matchesRegex = { - description: 'This is the matchesRegex operator to specify a constraint to select the objects where the value of a field matches a specified regular expression.', - type: _graphql.GraphQLString -}; -exports.matchesRegex = matchesRegex; -const options = { - description: 'This is the options operator to specify optional flags (such as "i" and "m") to be added to a matchesRegex operation in the same set of constraints.', - type: _graphql.GraphQLString -}; -exports.options = options; -const SUBQUERY_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SubqueryInput', - description: 'The SubqueryInput type is used to specify a sub query to another class.', - fields: { - className: CLASS_NAME_ATT, - where: Object.assign({}, WHERE_ATT, { - type: new _graphql.GraphQLNonNull(WHERE_ATT.type) - }) - } -}); -exports.SUBQUERY_INPUT = SUBQUERY_INPUT; -const SELECT_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SelectInput', - description: 'The SelectInput type is used to specify an inQueryKey or a notInQueryKey operation on a constraint.', - fields: { - query: { - description: 'This is the subquery to be executed.', - type: new _graphql.GraphQLNonNull(SUBQUERY_INPUT) - }, - key: { - description: 'This is the key in the result of the subquery that must match (not match) the field.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - } - } -}); -exports.SELECT_INPUT = SELECT_INPUT; -const inQueryKey = { - description: 'This is the inQueryKey operator to specify a constraint to select the objects where a field equals to a key in the result of a different query.', - type: SELECT_INPUT -}; -exports.inQueryKey = inQueryKey; -const notInQueryKey = { - description: 'This is the notInQueryKey operator to specify a constraint to select the objects where a field do not equal to a key in the result of a different query.', - type: SELECT_INPUT -}; -exports.notInQueryKey = notInQueryKey; -const ID_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'IdWhereInput', - description: 'The IdWhereInput input type is used in operations that involve filtering objects by an id.', - fields: { - equalTo: equalTo(_graphql.GraphQLID), - notEqualTo: notEqualTo(_graphql.GraphQLID), - lessThan: lessThan(_graphql.GraphQLID), - lessThanOrEqualTo: lessThanOrEqualTo(_graphql.GraphQLID), - greaterThan: greaterThan(_graphql.GraphQLID), - greaterThanOrEqualTo: greaterThanOrEqualTo(_graphql.GraphQLID), - in: inOp(_graphql.GraphQLID), - notIn: notIn(_graphql.GraphQLID), - exists, - inQueryKey, - notInQueryKey - } -}); -exports.ID_WHERE_INPUT = ID_WHERE_INPUT; -const STRING_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'StringWhereInput', - description: 'The StringWhereInput input type is used in operations that involve filtering objects by a field of type String.', - fields: { - equalTo: equalTo(_graphql.GraphQLString), - notEqualTo: notEqualTo(_graphql.GraphQLString), - lessThan: lessThan(_graphql.GraphQLString), - lessThanOrEqualTo: lessThanOrEqualTo(_graphql.GraphQLString), - greaterThan: greaterThan(_graphql.GraphQLString), - greaterThanOrEqualTo: greaterThanOrEqualTo(_graphql.GraphQLString), - in: inOp(_graphql.GraphQLString), - notIn: notIn(_graphql.GraphQLString), - exists, - matchesRegex, - options, - text: { - description: 'This is the $text operator to specify a full text search constraint.', - type: TEXT_INPUT - }, - inQueryKey, - notInQueryKey - } -}); -exports.STRING_WHERE_INPUT = STRING_WHERE_INPUT; -const NUMBER_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'NumberWhereInput', - description: 'The NumberWhereInput input type is used in operations that involve filtering objects by a field of type Number.', - fields: { - equalTo: equalTo(_graphql.GraphQLFloat), - notEqualTo: notEqualTo(_graphql.GraphQLFloat), - lessThan: lessThan(_graphql.GraphQLFloat), - lessThanOrEqualTo: lessThanOrEqualTo(_graphql.GraphQLFloat), - greaterThan: greaterThan(_graphql.GraphQLFloat), - greaterThanOrEqualTo: greaterThanOrEqualTo(_graphql.GraphQLFloat), - in: inOp(_graphql.GraphQLFloat), - notIn: notIn(_graphql.GraphQLFloat), - exists, - inQueryKey, - notInQueryKey - } -}); -exports.NUMBER_WHERE_INPUT = NUMBER_WHERE_INPUT; -const BOOLEAN_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'BooleanWhereInput', - description: 'The BooleanWhereInput input type is used in operations that involve filtering objects by a field of type Boolean.', - fields: { - equalTo: equalTo(_graphql.GraphQLBoolean), - notEqualTo: notEqualTo(_graphql.GraphQLBoolean), - exists, - inQueryKey, - notInQueryKey - } -}); -exports.BOOLEAN_WHERE_INPUT = BOOLEAN_WHERE_INPUT; -const ARRAY_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'ArrayWhereInput', - description: 'The ArrayWhereInput input type is used in operations that involve filtering objects by a field of type Array.', - fields: { - equalTo: equalTo(ANY), - notEqualTo: notEqualTo(ANY), - lessThan: lessThan(ANY), - lessThanOrEqualTo: lessThanOrEqualTo(ANY), - greaterThan: greaterThan(ANY), - greaterThanOrEqualTo: greaterThanOrEqualTo(ANY), - in: inOp(ANY), - notIn: notIn(ANY), - exists, - containedBy: { - description: 'This is the containedBy operator to specify a constraint to select the objects where the values of an array field is contained by another specified array.', - type: new _graphql.GraphQLList(ANY) - }, - contains: { - description: 'This is the contains operator to specify a constraint to select the objects where the values of an array field contain all elements of another specified array.', - type: new _graphql.GraphQLList(ANY) - }, - inQueryKey, - notInQueryKey - } -}); -exports.ARRAY_WHERE_INPUT = ARRAY_WHERE_INPUT; -const KEY_VALUE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'KeyValueInput', - description: 'An entry from an object, i.e., a pair of key and value.', - fields: { - key: { - description: 'The key used to retrieve the value of this entry.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - }, - value: { - description: 'The value of the entry. Could be any type of scalar data.', - type: new _graphql.GraphQLNonNull(ANY) - } - } -}); -exports.KEY_VALUE_INPUT = KEY_VALUE_INPUT; -const OBJECT_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'ObjectWhereInput', - description: 'The ObjectWhereInput input type is used in operations that involve filtering result by a field of type Object.', - fields: { - equalTo: equalTo(KEY_VALUE_INPUT), - notEqualTo: notEqualTo(KEY_VALUE_INPUT), - in: inOp(KEY_VALUE_INPUT), - notIn: notIn(KEY_VALUE_INPUT), - lessThan: lessThan(KEY_VALUE_INPUT), - lessThanOrEqualTo: lessThanOrEqualTo(KEY_VALUE_INPUT), - greaterThan: greaterThan(KEY_VALUE_INPUT), - greaterThanOrEqualTo: greaterThanOrEqualTo(KEY_VALUE_INPUT), - exists, - inQueryKey, - notInQueryKey - } -}); -exports.OBJECT_WHERE_INPUT = OBJECT_WHERE_INPUT; -const DATE_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'DateWhereInput', - description: 'The DateWhereInput input type is used in operations that involve filtering objects by a field of type Date.', - fields: { - equalTo: equalTo(DATE), - notEqualTo: notEqualTo(DATE), - lessThan: lessThan(DATE), - lessThanOrEqualTo: lessThanOrEqualTo(DATE), - greaterThan: greaterThan(DATE), - greaterThanOrEqualTo: greaterThanOrEqualTo(DATE), - in: inOp(DATE), - notIn: notIn(DATE), - exists, - inQueryKey, - notInQueryKey - } -}); -exports.DATE_WHERE_INPUT = DATE_WHERE_INPUT; -const BYTES_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'BytesWhereInput', - description: 'The BytesWhereInput input type is used in operations that involve filtering objects by a field of type Bytes.', - fields: { - equalTo: equalTo(BYTES), - notEqualTo: notEqualTo(BYTES), - lessThan: lessThan(BYTES), - lessThanOrEqualTo: lessThanOrEqualTo(BYTES), - greaterThan: greaterThan(BYTES), - greaterThanOrEqualTo: greaterThanOrEqualTo(BYTES), - in: inOp(BYTES), - notIn: notIn(BYTES), - exists, - inQueryKey, - notInQueryKey - } -}); -exports.BYTES_WHERE_INPUT = BYTES_WHERE_INPUT; -const FILE_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'FileWhereInput', - description: 'The FileWhereInput input type is used in operations that involve filtering objects by a field of type File.', - fields: { - equalTo: equalTo(FILE), - notEqualTo: notEqualTo(FILE), - lessThan: lessThan(FILE), - lessThanOrEqualTo: lessThanOrEqualTo(FILE), - greaterThan: greaterThan(FILE), - greaterThanOrEqualTo: greaterThanOrEqualTo(FILE), - in: inOp(FILE), - notIn: notIn(FILE), - exists, - matchesRegex, - options, - inQueryKey, - notInQueryKey - } -}); -exports.FILE_WHERE_INPUT = FILE_WHERE_INPUT; -const GEO_POINT_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'GeoPointWhereInput', - description: 'The GeoPointWhereInput input type is used in operations that involve filtering objects by a field of type GeoPoint.', - fields: { - exists, - nearSphere: { - description: 'This is the nearSphere operator to specify a constraint to select the objects where the values of a geo point field is near to another geo point.', - type: GEO_POINT_INPUT - }, - maxDistance: { - description: 'This is the maxDistance operator to specify a constraint to select the objects where the values of a geo point field is at a max distance (in radians) from the geo point specified in the $nearSphere operator.', - type: _graphql.GraphQLFloat - }, - maxDistanceInRadians: { - description: 'This is the maxDistanceInRadians operator to specify a constraint to select the objects where the values of a geo point field is at a max distance (in radians) from the geo point specified in the $nearSphere operator.', - type: _graphql.GraphQLFloat - }, - maxDistanceInMiles: { - description: 'This is the maxDistanceInMiles operator to specify a constraint to select the objects where the values of a geo point field is at a max distance (in miles) from the geo point specified in the $nearSphere operator.', - type: _graphql.GraphQLFloat - }, - maxDistanceInKilometers: { - description: 'This is the maxDistanceInKilometers operator to specify a constraint to select the objects where the values of a geo point field is at a max distance (in kilometers) from the geo point specified in the $nearSphere operator.', - type: _graphql.GraphQLFloat - }, - within: { - description: 'This is the within operator to specify a constraint to select the objects where the values of a geo point field is within a specified box.', - type: WITHIN_INPUT - }, - geoWithin: { - description: 'This is the geoWithin operator to specify a constraint to select the objects where the values of a geo point field is within a specified polygon or sphere.', - type: GEO_WITHIN_INPUT - } - } -}); -exports.GEO_POINT_WHERE_INPUT = GEO_POINT_WHERE_INPUT; -const POLYGON_WHERE_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'PolygonWhereInput', - description: 'The PolygonWhereInput input type is used in operations that involve filtering objects by a field of type Polygon.', - fields: { - exists, - geoIntersects: { - description: 'This is the geoIntersects operator to specify a constraint to select the objects where the values of a polygon field intersect a specified point.', - type: GEO_INTERSECTS_INPUT - } - } -}); -exports.POLYGON_WHERE_INPUT = POLYGON_WHERE_INPUT; -const ELEMENT = new _graphql.GraphQLObjectType({ - name: 'Element', - description: "The Element object type is used to return array items' value.", - fields: { - value: { - description: 'Return the value of the element in the array', - type: new _graphql.GraphQLNonNull(ANY) - } - } -}); // Default static union type, we update types and resolveType function later - -exports.ELEMENT = ELEMENT; -let ARRAY_RESULT; -exports.ARRAY_RESULT = ARRAY_RESULT; - -const loadArrayResult = (parseGraphQLSchema, parseClasses) => { - const classTypes = parseClasses.filter(parseClass => parseGraphQLSchema.parseClassTypes[parseClass.className].classGraphQLOutputType ? true : false).map(parseClass => parseGraphQLSchema.parseClassTypes[parseClass.className].classGraphQLOutputType); - exports.ARRAY_RESULT = ARRAY_RESULT = new _graphql.GraphQLUnionType({ - name: 'ArrayResult', - description: 'Use Inline Fragment on Array to get results: https://graphql.org/learn/queries/#inline-fragments', - types: () => [ELEMENT, ...classTypes], - resolveType: value => { - if (value.__type === 'Object' && value.className && value.objectId) { - if (parseGraphQLSchema.parseClassTypes[value.className]) { - return parseGraphQLSchema.parseClassTypes[value.className].classGraphQLOutputType; - } else { - return ELEMENT; - } - } else { - return ELEMENT; - } - } - }); - parseGraphQLSchema.graphQLTypes.push(ARRAY_RESULT); -}; - -exports.loadArrayResult = loadArrayResult; - -const load = parseGraphQLSchema => { - parseGraphQLSchema.addGraphQLType(_links.GraphQLUpload, true); - parseGraphQLSchema.addGraphQLType(ANY, true); - parseGraphQLSchema.addGraphQLType(OBJECT, true); - parseGraphQLSchema.addGraphQLType(DATE, true); - parseGraphQLSchema.addGraphQLType(BYTES, true); - parseGraphQLSchema.addGraphQLType(FILE, true); - parseGraphQLSchema.addGraphQLType(FILE_INFO, true); - parseGraphQLSchema.addGraphQLType(FILE_INPUT, true); - parseGraphQLSchema.addGraphQLType(GEO_POINT_INPUT, true); - parseGraphQLSchema.addGraphQLType(GEO_POINT, true); - parseGraphQLSchema.addGraphQLType(PARSE_OBJECT, true); - parseGraphQLSchema.addGraphQLType(READ_PREFERENCE, true); - parseGraphQLSchema.addGraphQLType(READ_OPTIONS_INPUT, true); - parseGraphQLSchema.addGraphQLType(SEARCH_INPUT, true); - parseGraphQLSchema.addGraphQLType(TEXT_INPUT, true); - parseGraphQLSchema.addGraphQLType(BOX_INPUT, true); - parseGraphQLSchema.addGraphQLType(WITHIN_INPUT, true); - parseGraphQLSchema.addGraphQLType(CENTER_SPHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(GEO_WITHIN_INPUT, true); - parseGraphQLSchema.addGraphQLType(GEO_INTERSECTS_INPUT, true); - parseGraphQLSchema.addGraphQLType(ID_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(STRING_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(NUMBER_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(BOOLEAN_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(ARRAY_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(KEY_VALUE_INPUT, true); - parseGraphQLSchema.addGraphQLType(OBJECT_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(DATE_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(BYTES_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(FILE_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(GEO_POINT_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(POLYGON_WHERE_INPUT, true); - parseGraphQLSchema.addGraphQLType(ELEMENT, true); - parseGraphQLSchema.addGraphQLType(ACL_INPUT, true); - parseGraphQLSchema.addGraphQLType(USER_ACL_INPUT, true); - parseGraphQLSchema.addGraphQLType(ROLE_ACL_INPUT, true); - parseGraphQLSchema.addGraphQLType(PUBLIC_ACL_INPUT, true); - parseGraphQLSchema.addGraphQLType(ACL, true); - parseGraphQLSchema.addGraphQLType(USER_ACL, true); - parseGraphQLSchema.addGraphQLType(ROLE_ACL, true); - parseGraphQLSchema.addGraphQLType(PUBLIC_ACL, true); - parseGraphQLSchema.addGraphQLType(SUBQUERY_INPUT, true); - parseGraphQLSchema.addGraphQLType(SELECT_INPUT, true); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxUeXBlcy5qcyJdLCJuYW1lcyI6WyJUeXBlVmFsaWRhdGlvbkVycm9yIiwiRXJyb3IiLCJjb25zdHJ1Y3RvciIsInZhbHVlIiwidHlwZSIsInBhcnNlU3RyaW5nVmFsdWUiLCJwYXJzZUludFZhbHVlIiwiaW50IiwiTnVtYmVyIiwiaXNJbnRlZ2VyIiwicGFyc2VGbG9hdFZhbHVlIiwiZmxvYXQiLCJpc05hTiIsInBhcnNlQm9vbGVhblZhbHVlIiwicGFyc2VWYWx1ZSIsImtpbmQiLCJLaW5kIiwiU1RSSU5HIiwiSU5UIiwiRkxPQVQiLCJCT09MRUFOIiwiTElTVCIsInBhcnNlTGlzdFZhbHVlcyIsInZhbHVlcyIsIk9CSkVDVCIsInBhcnNlT2JqZWN0RmllbGRzIiwiZmllbGRzIiwiQXJyYXkiLCJpc0FycmF5IiwibWFwIiwicmVkdWNlIiwib2JqZWN0IiwiZmllbGQiLCJuYW1lIiwiQU5ZIiwiR3JhcGhRTFNjYWxhclR5cGUiLCJkZXNjcmlwdGlvbiIsInNlcmlhbGl6ZSIsInBhcnNlTGl0ZXJhbCIsImFzdCIsInBhcnNlRGF0ZUlzb1ZhbHVlIiwiZGF0ZSIsIkRhdGUiLCJzZXJpYWxpemVEYXRlSXNvIiwidG9JU09TdHJpbmciLCJwYXJzZURhdGVJc29MaXRlcmFsIiwiREFURSIsIl9fdHlwZSIsImlzbyIsImZpbmQiLCJCWVRFUyIsImJhc2U2NCIsInBhcnNlRmlsZVZhbHVlIiwidXJsIiwidW5kZWZpbmVkIiwiRklMRSIsIkZJTEVfSU5GTyIsIkdyYXBoUUxPYmplY3RUeXBlIiwiR3JhcGhRTE5vbk51bGwiLCJHcmFwaFFMU3RyaW5nIiwiRklMRV9JTlBVVCIsIkdyYXBoUUxJbnB1dE9iamVjdFR5cGUiLCJmaWxlIiwidXBsb2FkIiwiR3JhcGhRTFVwbG9hZCIsInVubGluayIsIkdyYXBoUUxCb29sZWFuIiwiR0VPX1BPSU5UX0ZJRUxEUyIsImxhdGl0dWRlIiwiR3JhcGhRTEZsb2F0IiwibG9uZ2l0dWRlIiwiR0VPX1BPSU5UX0lOUFVUIiwiR0VPX1BPSU5UIiwiUE9MWUdPTl9JTlBVVCIsIkdyYXBoUUxMaXN0IiwiUE9MWUdPTiIsIlVTRVJfQUNMX0lOUFVUIiwidXNlcklkIiwiR3JhcGhRTElEIiwicmVhZCIsIndyaXRlIiwiUk9MRV9BQ0xfSU5QVVQiLCJyb2xlTmFtZSIsIlBVQkxJQ19BQ0xfSU5QVVQiLCJBQ0xfSU5QVVQiLCJ1c2VycyIsInJvbGVzIiwicHVibGljIiwiVVNFUl9BQ0wiLCJST0xFX0FDTCIsIlBVQkxJQ19BQ0wiLCJBQ0wiLCJyZXNvbHZlIiwicCIsIk9iamVjdCIsImtleXMiLCJmb3JFYWNoIiwicnVsZSIsImluZGV4T2YiLCJwdXNoIiwibGVuZ3RoIiwicmVwbGFjZSIsIk9CSkVDVF9JRCIsIkNMQVNTX05BTUVfQVRUIiwiR0xPQkFMX09SX09CSkVDVF9JRF9BVFQiLCJPQkpFQ1RfSURfQVRUIiwiQ1JFQVRFRF9BVF9BVFQiLCJVUERBVEVEX0FUX0FUVCIsIklOUFVUX0ZJRUxEUyIsIkNSRUFURV9SRVNVTFRfRklFTERTIiwib2JqZWN0SWQiLCJjcmVhdGVkQXQiLCJVUERBVEVfUkVTVUxUX0ZJRUxEUyIsInVwZGF0ZWRBdCIsIlBBUlNFX09CSkVDVF9GSUVMRFMiLCJQQVJTRV9PQkpFQ1QiLCJHcmFwaFFMSW50ZXJmYWNlVHlwZSIsIlNFU1NJT05fVE9LRU5fQVRUIiwiUkVBRF9QUkVGRVJFTkNFIiwiR3JhcGhRTEVudW1UeXBlIiwiUFJJTUFSWSIsIlBSSU1BUllfUFJFRkVSUkVEIiwiU0VDT05EQVJZIiwiU0VDT05EQVJZX1BSRUZFUlJFRCIsIk5FQVJFU1QiLCJSRUFEX1BSRUZFUkVOQ0VfQVRUIiwiSU5DTFVERV9SRUFEX1BSRUZFUkVOQ0VfQVRUIiwiU1VCUVVFUllfUkVBRF9QUkVGRVJFTkNFX0FUVCIsIlJFQURfT1BUSU9OU19JTlBVVCIsInJlYWRQcmVmZXJlbmNlIiwiaW5jbHVkZVJlYWRQcmVmZXJlbmNlIiwic3VicXVlcnlSZWFkUHJlZmVyZW5jZSIsIlJFQURfT1BUSU9OU19BVFQiLCJXSEVSRV9BVFQiLCJTS0lQX0FUVCIsIkdyYXBoUUxJbnQiLCJMSU1JVF9BVFQiLCJDT1VOVF9BVFQiLCJTRUFSQ0hfSU5QVVQiLCJ0ZXJtIiwibGFuZ3VhZ2UiLCJjYXNlU2Vuc2l0aXZlIiwiZGlhY3JpdGljU2Vuc2l0aXZlIiwiVEVYVF9JTlBVVCIsInNlYXJjaCIsIkJPWF9JTlBVVCIsImJvdHRvbUxlZnQiLCJ1cHBlclJpZ2h0IiwiV0lUSElOX0lOUFVUIiwiYm94IiwiQ0VOVEVSX1NQSEVSRV9JTlBVVCIsImNlbnRlciIsImRpc3RhbmNlIiwiR0VPX1dJVEhJTl9JTlBVVCIsInBvbHlnb24iLCJjZW50ZXJTcGhlcmUiLCJHRU9fSU5URVJTRUNUU19JTlBVVCIsInBvaW50IiwiZXF1YWxUbyIsIm5vdEVxdWFsVG8iLCJsZXNzVGhhbiIsImxlc3NUaGFuT3JFcXVhbFRvIiwiZ3JlYXRlclRoYW4iLCJncmVhdGVyVGhhbk9yRXF1YWxUbyIsImluT3AiLCJub3RJbiIsImV4aXN0cyIsIm1hdGNoZXNSZWdleCIsIm9wdGlvbnMiLCJTVUJRVUVSWV9JTlBVVCIsImNsYXNzTmFtZSIsIndoZXJlIiwiYXNzaWduIiwiU0VMRUNUX0lOUFVUIiwicXVlcnkiLCJrZXkiLCJpblF1ZXJ5S2V5Iiwibm90SW5RdWVyeUtleSIsIklEX1dIRVJFX0lOUFVUIiwiaW4iLCJTVFJJTkdfV0hFUkVfSU5QVVQiLCJ0ZXh0IiwiTlVNQkVSX1dIRVJFX0lOUFVUIiwiQk9PTEVBTl9XSEVSRV9JTlBVVCIsIkFSUkFZX1dIRVJFX0lOUFVUIiwiY29udGFpbmVkQnkiLCJjb250YWlucyIsIktFWV9WQUxVRV9JTlBVVCIsIk9CSkVDVF9XSEVSRV9JTlBVVCIsIkRBVEVfV0hFUkVfSU5QVVQiLCJCWVRFU19XSEVSRV9JTlBVVCIsIkZJTEVfV0hFUkVfSU5QVVQiLCJHRU9fUE9JTlRfV0hFUkVfSU5QVVQiLCJuZWFyU3BoZXJlIiwibWF4RGlzdGFuY2UiLCJtYXhEaXN0YW5jZUluUmFkaWFucyIsIm1heERpc3RhbmNlSW5NaWxlcyIsIm1heERpc3RhbmNlSW5LaWxvbWV0ZXJzIiwid2l0aGluIiwiZ2VvV2l0aGluIiwiUE9MWUdPTl9XSEVSRV9JTlBVVCIsImdlb0ludGVyc2VjdHMiLCJFTEVNRU5UIiwiQVJSQVlfUkVTVUxUIiwibG9hZEFycmF5UmVzdWx0IiwicGFyc2VHcmFwaFFMU2NoZW1hIiwicGFyc2VDbGFzc2VzIiwiY2xhc3NUeXBlcyIsImZpbHRlciIsInBhcnNlQ2xhc3MiLCJwYXJzZUNsYXNzVHlwZXMiLCJjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIiwiR3JhcGhRTFVuaW9uVHlwZSIsInR5cGVzIiwicmVzb2x2ZVR5cGUiLCJncmFwaFFMVHlwZXMiLCJsb2FkIiwiYWRkR3JhcGhRTFR5cGUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFnQkE7O0FBQ0E7Ozs7Ozs7O0FBRUEsTUFBTUEsbUJBQU4sU0FBa0NDLEtBQWxDLENBQXdDO0FBQ3RDQyxFQUFBQSxXQUFXLENBQUNDLEtBQUQsRUFBUUMsSUFBUixFQUFjO0FBQ3ZCLFVBQU8sR0FBRUQsS0FBTSxtQkFBa0JDLElBQUssRUFBdEM7QUFDRDs7QUFIcUM7Ozs7QUFNeEMsTUFBTUMsZ0JBQWdCLEdBQUdGLEtBQUssSUFBSTtBQUNoQyxNQUFJLE9BQU9BLEtBQVAsS0FBaUIsUUFBckIsRUFBK0I7QUFDN0IsV0FBT0EsS0FBUDtBQUNEOztBQUVELFFBQU0sSUFBSUgsbUJBQUosQ0FBd0JHLEtBQXhCLEVBQStCLFFBQS9CLENBQU47QUFDRCxDQU5EOzs7O0FBUUEsTUFBTUcsYUFBYSxHQUFHSCxLQUFLLElBQUk7QUFDN0IsTUFBSSxPQUFPQSxLQUFQLEtBQWlCLFFBQXJCLEVBQStCO0FBQzdCLFVBQU1JLEdBQUcsR0FBR0MsTUFBTSxDQUFDTCxLQUFELENBQWxCOztBQUNBLFFBQUlLLE1BQU0sQ0FBQ0MsU0FBUCxDQUFpQkYsR0FBakIsQ0FBSixFQUEyQjtBQUN6QixhQUFPQSxHQUFQO0FBQ0Q7QUFDRjs7QUFF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QUFBQSxrQkFBa0IsQ0FBQ1ksY0FBbkIsQ0FBa0MvSCxVQUFsQyxFQUE4QyxJQUE5QztBQUNBbUgsRUFBQUEsa0JBQWtCLENBQUNZLGNBQW5CLENBQWtDaEQsY0FBbEMsRUFBa0QsSUFBbEQ7QUFDQW9DLEVBQUFBLGtCQUFrQixDQUFDWSxjQUFuQixDQUFrQzVDLFlBQWxDLEVBQWdELElBQWhEO0FBQ0QsQ0E1Q0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBLaW5kLFxuICBHcmFwaFFMTm9uTnVsbCxcbiAgR3JhcGhRTFNjYWxhclR5cGUsXG4gIEdyYXBoUUxJRCxcbiAgR3JhcGhRTFN0cmluZyxcbiAgR3JhcGhRTE9iamVjdFR5cGUsXG4gIEdyYXBoUUxJbnRlcmZhY2VUeXBlLFxuICBHcmFwaFFMRW51bVR5cGUsXG4gIEdyYXBoUUxJbnQsXG4gIEdyYXBoUUxGbG9hdCxcbiAgR3JhcGhRTExpc3QsXG4gIEdyYXBoUUxJbnB1dE9iamVjdFR5cGUsXG4gIEdyYXBoUUxCb29sZWFuLFxuICBHcmFwaFFMVW5pb25UeXBlLFxufSBmcm9tICdncmFwaHFsJztcbmltcG9ydCB7IHRvR2xvYmFsSWQgfSBmcm9tICdncmFwaHFsLXJlbGF5JztcbmltcG9ydCB7IEdyYXBoUUxVcGxvYWQgfSBmcm9tICdAZ3JhcGhxbC10b29scy9saW5rcyc7XG5cbmNsYXNzIFR5cGVWYWxpZGF0aW9uRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKHZhbHVlLCB0eXBlKSB7XG4gICAgc3VwZXIoYCR7dmFsdWV9IGlzIG5vdCBhIHZhbGlkICR7dHlwZX1gKTtcbiAgfVxufVxuXG5jb25zdCBwYXJzZVN0cmluZ1ZhbHVlID0gdmFsdWUgPT4ge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHZhbHVlLCAnU3RyaW5nJyk7XG59O1xuXG5jb25zdCBwYXJzZUludFZhbHVlID0gdmFsdWUgPT4ge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIGNvbnN0IGludCA9IE51bWJlcih2YWx1ZSk7XG4gICAgaWYgKE51bWJlci5pc0ludGVnZXIoaW50KSkge1xuICAgICAgcmV0dXJuIGludDtcbiAgICB9XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ0ludCcpO1xufTtcblxuY29uc3QgcGFyc2VGbG9hdFZhbHVlID0gdmFsdWUgPT4ge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIGNvbnN0IGZsb2F0ID0gTnVtYmVyKHZhbHVlKTtcbiAgICBpZiAoIWlzTmFOKGZsb2F0KSkge1xuICAgICAgcmV0dXJuIGZsb2F0O1xuICAgIH1cbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHZhbHVlLCAnRmxvYXQnKTtcbn07XG5cbmNvbnN0IHBhcnNlQm9vbGVhblZhbHVlID0gdmFsdWUgPT4ge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ0Jvb2xlYW4nKTtcbn07XG5cbmNvbnN0IHBhcnNlVmFsdWUgPSB2YWx1ZSA9PiB7XG4gIHN3aXRjaCAodmFsdWUua2luZCkge1xuICAgIGNhc2UgS2luZC5TVFJJTkc6XG4gICAgICByZXR1cm4gcGFyc2VTdHJpbmdWYWx1ZSh2YWx1ZS52YWx1ZSk7XG5cbiAgICBjYXNlIEtpbmQuSU5UOlxuICAgICAgcmV0dXJuIHBhcnNlSW50VmFsdWUodmFsdWUudmFsdWUpO1xuXG4gICAgY2FzZSBLaW5kLkZMT0FUOlxuICAgICAgcmV0dXJuIHBhcnNlRmxvYXRWYWx1ZSh2YWx1ZS52YWx1ZSk7XG5cbiAgICBjYXNlIEtpbmQuQk9PTEVBTjpcbiAgICAgIHJldHVybiBwYXJzZUJvb2xlYW5WYWx1ZSh2YWx1ZS52YWx1ZSk7XG5cbiAgICBjYXNlIEtpbmQuTElTVDpcbiAgICAgIHJldHVybiBwYXJzZUxpc3RWYWx1ZXModmFsdWUudmFsdWVzKTtcblxuICAgIGNhc2UgS2luZC5PQkpFQ1Q6XG4gICAgICByZXR1cm4gcGFyc2VPYmplY3RGaWVsZHModmFsdWUuZmllbGRzKTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gdmFsdWUudmFsdWU7XG4gIH1cbn07XG5cbmNvbnN0IHBhcnNlTGlzdFZhbHVlcyA9IHZhbHVlcyA9PiB7XG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlcykpIHtcbiAgICByZXR1cm4gdmFsdWVzLm1hcCh2YWx1ZSA9PiBwYXJzZVZhbHVlKHZhbHVlKSk7XG4gIH1cblxuICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZXMsICdMaXN0Jyk7XG59O1xuXG5jb25zdCBwYXJzZU9iamVjdEZpZWxkcyA9IGZpZWxkcyA9PiB7XG4gIGlmIChBcnJheS5pc0FycmF5KGZpZWxkcykpIHtcbiAgICByZXR1cm4gZmllbGRzLnJlZHVjZShcbiAgICAgIChvYmplY3QsIGZpZWxkKSA9PiAoe1xuICAgICAgICAuLi5vYmplY3QsXG4gICAgICAgIFtmaWVsZC5uYW1lLnZhbHVlXTogcGFyc2VWYWx1ZShmaWVsZC52YWx1ZSksXG4gICAgICB9KSxcbiAgICAgIHt9XG4gICAgKTtcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKGZpZWxkcywgJ09iamVjdCcpO1xufTtcblxuY29uc3QgQU5ZID0gbmV3IEdyYXBoUUxTY2FsYXJUeXBlKHtcbiAgbmFtZTogJ0FueScsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgQW55IHNjYWxhciB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyBhbmQgdHlwZXMgdGhhdCBpbnZvbHZlIGFueSB0eXBlIG9mIHZhbHVlLicsXG4gIHBhcnNlVmFsdWU6IHZhbHVlID0+IHZhbHVlLFxuICBzZXJpYWxpemU6IHZhbHVlID0+IHZhbHVlLFxuICBwYXJzZUxpdGVyYWw6IGFzdCA9PiBwYXJzZVZhbHVlKGFzdCksXG59KTtcblxuY29uc3QgT0JKRUNUID0gbmV3IEdyYXBoUUxTY2FsYXJUeXBlKHtcbiAgbmFtZTogJ09iamVjdCcsXG4gIGRlc2NyaXB0aW9uOiAnVGhlIE9iamVjdCBzY2FsYXIgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgYW5kIHR5cGVzIHRoYXQgaW52b2x2ZSBvYmplY3RzLicsXG4gIHBhcnNlVmFsdWUodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHZhbHVlLCAnT2JqZWN0Jyk7XG4gIH0sXG4gIHNlcmlhbGl6ZSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdPYmplY3QnKTtcbiAgfSxcbiAgcGFyc2VMaXRlcmFsKGFzdCkge1xuICAgIGlmIChhc3Qua2luZCA9PT0gS2luZC5PQkpFQ1QpIHtcbiAgICAgIHJldHVybiBwYXJzZU9iamVjdEZpZWxkcyhhc3QuZmllbGRzKTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcihhc3Qua2luZCwgJ09iamVjdCcpO1xuICB9LFxufSk7XG5cbmNvbnN0IHBhcnNlRGF0ZUlzb1ZhbHVlID0gdmFsdWUgPT4ge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgaWYgKCFpc05hTihkYXRlKSkge1xuICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHZhbHVlLCAnRGF0ZScpO1xufTtcblxuY29uc3Qgc2VyaWFsaXplRGF0ZUlzbyA9IHZhbHVlID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgIHJldHVybiB2YWx1ZS50b0lTT1N0cmluZygpO1xuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdEYXRlJyk7XG59O1xuXG5jb25zdCBwYXJzZURhdGVJc29MaXRlcmFsID0gYXN0ID0+IHtcbiAgaWYgKGFzdC5raW5kID09PSBLaW5kLlNUUklORykge1xuICAgIHJldHVybiBwYXJzZURhdGVJc29WYWx1ZShhc3QudmFsdWUpO1xuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IoYXN0LmtpbmQsICdEYXRlJyk7XG59O1xuXG5jb25zdCBEQVRFID0gbmV3IEdyYXBoUUxTY2FsYXJUeXBlKHtcbiAgbmFtZTogJ0RhdGUnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBEYXRlIHNjYWxhciB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyBhbmQgdHlwZXMgdGhhdCBpbnZvbHZlIGRhdGVzLicsXG4gIHBhcnNlVmFsdWUodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyB8fCB2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIF9fdHlwZTogJ0RhdGUnLFxuICAgICAgICBpc286IHBhcnNlRGF0ZUlzb1ZhbHVlKHZhbHVlKSxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlLl9fdHlwZSA9PT0gJ0RhdGUnICYmIHZhbHVlLmlzbykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgX190eXBlOiB2YWx1ZS5fX3R5cGUsXG4gICAgICAgIGlzbzogcGFyc2VEYXRlSXNvVmFsdWUodmFsdWUuaXNvKSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdEYXRlJyk7XG4gIH0sXG4gIHNlcmlhbGl6ZSh2YWx1ZSkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnIHx8IHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgcmV0dXJuIHNlcmlhbGl6ZURhdGVJc28odmFsdWUpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZS5fX3R5cGUgPT09ICdEYXRlJyAmJiB2YWx1ZS5pc28pIHtcbiAgICAgIHJldHVybiBzZXJpYWxpemVEYXRlSXNvKHZhbHVlLmlzbyk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdEYXRlJyk7XG4gIH0sXG4gIHBhcnNlTGl0ZXJhbChhc3QpIHtcbiAgICBpZiAoYXN0LmtpbmQgPT09IEtpbmQuU1RSSU5HKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBfX3R5cGU6ICdEYXRlJyxcbiAgICAgICAgaXNvOiBwYXJzZURhdGVJc29MaXRlcmFsKGFzdCksXG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoYXN0LmtpbmQgPT09IEtpbmQuT0JKRUNUKSB7XG4gICAgICBjb25zdCBfX3R5cGUgPSBhc3QuZmllbGRzLmZpbmQoZmllbGQgPT4gZmllbGQubmFtZS52YWx1ZSA9PT0gJ19fdHlwZScpO1xuICAgICAgY29uc3QgaXNvID0gYXN0LmZpZWxkcy5maW5kKGZpZWxkID0+IGZpZWxkLm5hbWUudmFsdWUgPT09ICdpc28nKTtcbiAgICAgIGlmIChfX3R5cGUgJiYgX190eXBlLnZhbHVlICYmIF9fdHlwZS52YWx1ZS52YWx1ZSA9PT0gJ0RhdGUnICYmIGlzbykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIF9fdHlwZTogX190eXBlLnZhbHVlLnZhbHVlLFxuICAgICAgICAgIGlzbzogcGFyc2VEYXRlSXNvTGl0ZXJhbChpc28udmFsdWUpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKGFzdC5raW5kLCAnRGF0ZScpO1xuICB9LFxufSk7XG5cbmNvbnN0IEJZVEVTID0gbmV3IEdyYXBoUUxTY2FsYXJUeXBlKHtcbiAgbmFtZTogJ0J5dGVzJyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBCeXRlcyBzY2FsYXIgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgYW5kIHR5cGVzIHRoYXQgaW52b2x2ZSBiYXNlIDY0IGJpbmFyeSBkYXRhLicsXG4gIHBhcnNlVmFsdWUodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgX190eXBlOiAnQnl0ZXMnLFxuICAgICAgICBiYXNlNjQ6IHZhbHVlLFxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJlxuICAgICAgdmFsdWUuX190eXBlID09PSAnQnl0ZXMnICYmXG4gICAgICB0eXBlb2YgdmFsdWUuYmFzZTY0ID09PSAnc3RyaW5nJ1xuICAgICkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKHZhbHVlLCAnQnl0ZXMnKTtcbiAgfSxcbiAgc2VyaWFsaXplKHZhbHVlKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJlxuICAgICAgdmFsdWUuX190eXBlID09PSAnQnl0ZXMnICYmXG4gICAgICB0eXBlb2YgdmFsdWUuYmFzZTY0ID09PSAnc3RyaW5nJ1xuICAgICkge1xuICAgICAgcmV0dXJuIHZhbHVlLmJhc2U2NDtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ0J5dGVzJyk7XG4gIH0sXG4gIHBhcnNlTGl0ZXJhbChhc3QpIHtcbiAgICBpZiAoYXN0LmtpbmQgPT09IEtpbmQuU1RSSU5HKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBfX3R5cGU6ICdCeXRlcycsXG4gICAgICAgIGJhc2U2NDogYXN0LnZhbHVlLFxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKGFzdC5raW5kID09PSBLaW5kLk9CSkVDVCkge1xuICAgICAgY29uc3QgX190eXBlID0gYXN0LmZpZWxkcy5maW5kKGZpZWxkID0+IGZpZWxkLm5hbWUudmFsdWUgPT09ICdfX3R5cGUnKTtcbiAgICAgIGNvbnN0IGJhc2U2NCA9IGFzdC5maWVsZHMuZmluZChmaWVsZCA9PiBmaWVsZC5uYW1lLnZhbHVlID09PSAnYmFzZTY0Jyk7XG4gICAgICBpZiAoXG4gICAgICAgIF9fdHlwZSAmJlxuICAgICAgICBfX3R5cGUudmFsdWUgJiZcbiAgICAgICAgX190eXBlLnZhbHVlLnZhbHVlID09PSAnQnl0ZXMnICYmXG4gICAgICAgIGJhc2U2NCAmJlxuICAgICAgICBiYXNlNjQudmFsdWUgJiZcbiAgICAgICAgdHlwZW9mIGJhc2U2NC52YWx1ZS52YWx1ZSA9PT0gJ3N0cmluZydcbiAgICAgICkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIF9fdHlwZTogX190eXBlLnZhbHVlLnZhbHVlLFxuICAgICAgICAgIGJhc2U2NDogYmFzZTY0LnZhbHVlLnZhbHVlLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIHRocm93IG5ldyBUeXBlVmFsaWRhdGlvbkVycm9yKGFzdC5raW5kLCAnQnl0ZXMnKTtcbiAgfSxcbn0pO1xuXG5jb25zdCBwYXJzZUZpbGVWYWx1ZSA9IHZhbHVlID0+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4ge1xuICAgICAgX190eXBlOiAnRmlsZScsXG4gICAgICBuYW1lOiB2YWx1ZSxcbiAgICB9O1xuICB9IGVsc2UgaWYgKFxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICB2YWx1ZS5fX3R5cGUgPT09ICdGaWxlJyAmJlxuICAgIHR5cGVvZiB2YWx1ZS5uYW1lID09PSAnc3RyaW5nJyAmJlxuICAgICh2YWx1ZS51cmwgPT09IHVuZGVmaW5lZCB8fCB0eXBlb2YgdmFsdWUudXJsID09PSAnc3RyaW5nJylcbiAgKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgdGhyb3cgbmV3IFR5cGVWYWxpZGF0aW9uRXJyb3IodmFsdWUsICdGaWxlJyk7XG59O1xuXG5jb25zdCBGSUxFID0gbmV3IEdyYXBoUUxTY2FsYXJUeXBlKHtcbiAgbmFtZTogJ0ZpbGUnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBGaWxlIHNjYWxhciB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyBhbmQgdHlwZXMgdGhhdCBpbnZvbHZlIGZpbGVzLicsXG4gIHBhcnNlVmFsdWU6IHBhcnNlRmlsZVZhbHVlLFxuICBzZXJpYWxpemU6IHZhbHVlID0+IHtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICB2YWx1ZS5fX3R5cGUgPT09ICdGaWxlJyAmJlxuICAgICAgdHlwZW9mIHZhbHVlLm5hbWUgPT09ICdzdHJpbmcnICYmXG4gICAgICAodmFsdWUudXJsID09PSB1bmRlZmluZWQgfHwgdHlwZW9mIHZhbHVlLnVybCA9PT0gJ3N0cmluZycpXG4gICAgKSB7XG4gICAgICByZXR1cm4gdmFsdWUubmFtZTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcih2YWx1ZSwgJ0ZpbGUnKTtcbiAgfSxcbiAgcGFyc2VMaXRlcmFsKGFzdCkge1xuICAgIGlmIChhc3Qua2luZCA9PT0gS2luZC5TVFJJTkcpIHtcbiAgICAgIHJldHVybiBwYXJzZUZpbGVWYWx1ZShhc3QudmFsdWUpO1xuICAgIH0gZWxzZSBpZiAoYXN0LmtpbmQgPT09IEtpbmQuT0JKRUNUKSB7XG4gICAgICBjb25zdCBfX3R5cGUgPSBhc3QuZmllbGRzLmZpbmQoZmllbGQgPT4gZmllbGQubmFtZS52YWx1ZSA9PT0gJ19fdHlwZScpO1xuICAgICAgY29uc3QgbmFtZSA9IGFzdC5maWVsZHMuZmluZChmaWVsZCA9PiBmaWVsZC5uYW1lLnZhbHVlID09PSAnbmFtZScpO1xuICAgICAgY29uc3QgdXJsID0gYXN0LmZpZWxkcy5maW5kKGZpZWxkID0+IGZpZWxkLm5hbWUudmFsdWUgPT09ICd1cmwnKTtcbiAgICAgIGlmIChfX3R5cGUgJiYgX190eXBlLnZhbHVlICYmIG5hbWUgJiYgbmFtZS52YWx1ZSkge1xuICAgICAgICByZXR1cm4gcGFyc2VGaWxlVmFsdWUoe1xuICAgICAgICAgIF9fdHlwZTogX190eXBlLnZhbHVlLnZhbHVlLFxuICAgICAgICAgIG5hbWU6IG5hbWUudmFsdWUudmFsdWUsXG4gICAgICAgICAgdXJsOiB1cmwgJiYgdXJsLnZhbHVlID8gdXJsLnZhbHVlLnZhbHVlIDogdW5kZWZpbmVkLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgVHlwZVZhbGlkYXRpb25FcnJvcihhc3Qua2luZCwgJ0ZpbGUnKTtcbiAgfSxcbn0pO1xuXG5jb25zdCBGSUxFX0lORk8gPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICBuYW1lOiAnRmlsZUluZm8nLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBGaWxlSW5mbyBvYmplY3QgdHlwZSBpcyB1c2VkIHRvIHJldHVybiB0aGUgaW5mb3JtYXRpb24gYWJvdXQgZmlsZXMuJyxcbiAgZmllbGRzOiB7XG4gICAgbmFtZToge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBmaWxlIG5hbWUuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbiAgICB9LFxuICAgIHVybDoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSB1cmwgaW4gd2hpY2ggdGhlIGZpbGUgY2FuIGJlIGRvd25sb2FkZWQuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IEZJTEVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdGaWxlSW5wdXQnLFxuICBmaWVsZHM6IHtcbiAgICBmaWxlOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ0EgRmlsZSBTY2FsYXIgY2FuIGJlIGFuIHVybCBvciBhIEZpbGVJbmZvIG9iamVjdC4gSWYgdGhpcyBmaWVsZCBpcyBzZXQgdG8gbnVsbCB0aGUgZmlsZSB3aWxsIGJlIHVubGlua2VkLicsXG4gICAgICB0eXBlOiBGSUxFLFxuICAgIH0sXG4gICAgdXBsb2FkOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1VzZSB0aGlzIGZpZWxkIGlmIHlvdSB3YW50IHRvIGNyZWF0ZSBhIG5ldyBmaWxlLicsXG4gICAgICB0eXBlOiBHcmFwaFFMVXBsb2FkLFxuICAgIH0sXG4gICAgdW5saW5rOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1VzZSB0aGlzIGZpZWxkIGlmIHlvdSB3YW50IHRvIHVubGluayB0aGUgZmlsZSAodGhlIGZpbGUgd2lsbCBub3QgYmUgZGVsZXRlZCBvbiBjbG91ZCBzdG9yYWdlKScsXG4gICAgICB0eXBlOiBHcmFwaFFMQm9vbGVhbixcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IEdFT19QT0lOVF9GSUVMRFMgPSB7XG4gIGxhdGl0dWRlOiB7XG4gICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBsYXRpdHVkZS4nLFxuICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMRmxvYXQpLFxuICB9LFxuICBsb25naXR1ZGU6IHtcbiAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGxvbmdpdHVkZS4nLFxuICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMRmxvYXQpLFxuICB9LFxufTtcblxuY29uc3QgR0VPX1BPSU5UX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnR2VvUG9pbnRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgR2VvUG9pbnRJbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgaW5wdXR0aW5nIGZpZWxkcyBvZiB0eXBlIGdlbyBwb2ludC4nLFxuICBmaWVsZHM6IEdFT19QT0lOVF9GSUVMRFMsXG59KTtcblxuY29uc3QgR0VPX1BPSU5UID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0dlb1BvaW50JyxcbiAgZGVzY3JpcHRpb246ICdUaGUgR2VvUG9pbnQgb2JqZWN0IHR5cGUgaXMgdXNlZCB0byByZXR1cm4gdGhlIGluZm9ybWF0aW9uIGFib3V0IGdlbyBwb2ludCBmaWVsZHMuJyxcbiAgZmllbGRzOiBHRU9fUE9JTlRfRklFTERTLFxufSk7XG5cbmNvbnN0IFBPTFlHT05fSU5QVVQgPSBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKEdFT19QT0lOVF9JTlBVVCkpO1xuXG5jb25zdCBQT0xZR09OID0gbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChHRU9fUE9JTlQpKTtcblxuY29uc3QgVVNFUl9BQ0xfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdVc2VyQUNMSW5wdXQnLFxuICBkZXNjcmlwdGlvbjogJ0FsbG93IHRvIG1hbmFnZSB1c2VycyBpbiBBQ0wuJyxcbiAgZmllbGRzOiB7XG4gICAgdXNlcklkOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0lEIG9mIHRoZSB0YXJnZXR0ZWQgVXNlci4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxJRCksXG4gICAgfSxcbiAgICByZWFkOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0FsbG93IHRoZSB1c2VyIHRvIHJlYWQgdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gICAgd3JpdGU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQWxsb3cgdGhlIHVzZXIgdG8gd3JpdGUgb24gdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgUk9MRV9BQ0xfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdSb2xlQUNMSW5wdXQnLFxuICBkZXNjcmlwdGlvbjogJ0FsbG93IHRvIG1hbmFnZSByb2xlcyBpbiBBQ0wuJyxcbiAgZmllbGRzOiB7XG4gICAgcm9sZU5hbWU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnTmFtZSBvZiB0aGUgdGFyZ2V0dGVkIFJvbGUuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbiAgICB9LFxuICAgIHJlYWQ6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQWxsb3cgdXNlcnMgd2hvIGFyZSBtZW1iZXJzIG9mIHRoZSByb2xlIHRvIHJlYWQgdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gICAgd3JpdGU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQWxsb3cgdXNlcnMgd2hvIGFyZSBtZW1iZXJzIG9mIHRoZSByb2xlIHRvIHdyaXRlIG9uIHRoZSBjdXJyZW50IG9iamVjdC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxCb29sZWFuKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFBVQkxJQ19BQ0xfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdQdWJsaWNBQ0xJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOiAnQWxsb3cgdG8gbWFuYWdlIHB1YmxpYyByaWdodHMuJyxcbiAgZmllbGRzOiB7XG4gICAgcmVhZDoge1xuICAgICAgZGVzY3JpcHRpb246ICdBbGxvdyBhbnlvbmUgdG8gcmVhZCB0aGUgY3VycmVudCBvYmplY3QuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMQm9vbGVhbiksXG4gICAgfSxcbiAgICB3cml0ZToge1xuICAgICAgZGVzY3JpcHRpb246ICdBbGxvdyBhbnlvbmUgdG8gd3JpdGUgb24gdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgQUNMX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnQUNMSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnQWxsb3cgdG8gbWFuYWdlIGFjY2VzcyByaWdodHMuIElmIG5vdCBwcm92aWRlZCBvYmplY3Qgd2lsbCBiZSBwdWJsaWNseSByZWFkYWJsZSBhbmQgd3JpdGFibGUnLFxuICBmaWVsZHM6IHtcbiAgICB1c2Vyczoge1xuICAgICAgZGVzY3JpcHRpb246ICdBY2Nlc3MgY29udHJvbCBsaXN0IGZvciB1c2Vycy4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChVU0VSX0FDTF9JTlBVVCkpLFxuICAgIH0sXG4gICAgcm9sZXM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQWNjZXNzIGNvbnRyb2wgbGlzdCBmb3Igcm9sZXMuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoUk9MRV9BQ0xfSU5QVVQpKSxcbiAgICB9LFxuICAgIHB1YmxpYzoge1xuICAgICAgZGVzY3JpcHRpb246ICdQdWJsaWMgYWNjZXNzIGNvbnRyb2wgbGlzdC4nLFxuICAgICAgdHlwZTogUFVCTElDX0FDTF9JTlBVVCxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFVTRVJfQUNMID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1VzZXJBQ0wnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnQWxsb3cgdG8gbWFuYWdlIHVzZXJzIGluIEFDTC4gSWYgcmVhZCBhbmQgd3JpdGUgYXJlIG51bGwgdGhlIHVzZXJzIGhhdmUgcmVhZCBhbmQgd3JpdGUgcmlnaHRzLicsXG4gIGZpZWxkczoge1xuICAgIHVzZXJJZDoge1xuICAgICAgZGVzY3JpcHRpb246ICdJRCBvZiB0aGUgdGFyZ2V0dGVkIFVzZXIuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMSUQpLFxuICAgIH0sXG4gICAgcmVhZDoge1xuICAgICAgZGVzY3JpcHRpb246ICdBbGxvdyB0aGUgdXNlciB0byByZWFkIHRoZSBjdXJyZW50IG9iamVjdC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxCb29sZWFuKSxcbiAgICB9LFxuICAgIHdyaXRlOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0FsbG93IHRoZSB1c2VyIHRvIHdyaXRlIG9uIHRoZSBjdXJyZW50IG9iamVjdC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxCb29sZWFuKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFJPTEVfQUNMID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1JvbGVBQ0wnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnQWxsb3cgdG8gbWFuYWdlIHJvbGVzIGluIEFDTC4gSWYgcmVhZCBhbmQgd3JpdGUgYXJlIG51bGwgdGhlIHJvbGUgaGF2ZSByZWFkIGFuZCB3cml0ZSByaWdodHMuJyxcbiAgZmllbGRzOiB7XG4gICAgcm9sZU5hbWU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnTmFtZSBvZiB0aGUgdGFyZ2V0dGVkIFJvbGUuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMSUQpLFxuICAgIH0sXG4gICAgcmVhZDoge1xuICAgICAgZGVzY3JpcHRpb246ICdBbGxvdyB1c2VycyB3aG8gYXJlIG1lbWJlcnMgb2YgdGhlIHJvbGUgdG8gcmVhZCB0aGUgY3VycmVudCBvYmplY3QuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMQm9vbGVhbiksXG4gICAgfSxcbiAgICB3cml0ZToge1xuICAgICAgZGVzY3JpcHRpb246ICdBbGxvdyB1c2VycyB3aG8gYXJlIG1lbWJlcnMgb2YgdGhlIHJvbGUgdG8gd3JpdGUgb24gdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgUFVCTElDX0FDTCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdQdWJsaWNBQ0wnLFxuICBkZXNjcmlwdGlvbjogJ0FsbG93IHRvIG1hbmFnZSBwdWJsaWMgcmlnaHRzLicsXG4gIGZpZWxkczoge1xuICAgIHJlYWQ6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQWxsb3cgYW55b25lIHRvIHJlYWQgdGhlIGN1cnJlbnQgb2JqZWN0LicsXG4gICAgICB0eXBlOiBHcmFwaFFMQm9vbGVhbixcbiAgICB9LFxuICAgIHdyaXRlOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0FsbG93IGFueW9uZSB0byB3cml0ZSBvbiB0aGUgY3VycmVudCBvYmplY3QuJyxcbiAgICAgIHR5cGU6IEdyYXBoUUxCb29sZWFuLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgQUNMID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0FDTCcsXG4gIGRlc2NyaXB0aW9uOiAnQ3VycmVudCBhY2Nlc3MgY29udHJvbCBsaXN0IG9mIHRoZSBjdXJyZW50IG9iamVjdC4nLFxuICBmaWVsZHM6IHtcbiAgICB1c2Vyczoge1xuICAgICAgZGVzY3JpcHRpb246ICdBY2Nlc3MgY29udHJvbCBsaXN0IGZvciB1c2Vycy4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChVU0VSX0FDTCkpLFxuICAgICAgcmVzb2x2ZShwKSB7XG4gICAgICAgIGNvbnN0IHVzZXJzID0gW107XG4gICAgICAgIE9iamVjdC5rZXlzKHApLmZvckVhY2gocnVsZSA9PiB7XG4gICAgICAgICAgaWYgKHJ1bGUgIT09ICcqJyAmJiBydWxlLmluZGV4T2YoJ3JvbGU6JykgIT09IDApIHtcbiAgICAgICAgICAgIHVzZXJzLnB1c2goe1xuICAgICAgICAgICAgICB1c2VySWQ6IHRvR2xvYmFsSWQoJ19Vc2VyJywgcnVsZSksXG4gICAgICAgICAgICAgIHJlYWQ6IHBbcnVsZV0ucmVhZCA/IHRydWUgOiBmYWxzZSxcbiAgICAgICAgICAgICAgd3JpdGU6IHBbcnVsZV0ud3JpdGUgPyB0cnVlIDogZmFsc2UsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdXNlcnMubGVuZ3RoID8gdXNlcnMgOiBudWxsO1xuICAgICAgfSxcbiAgICB9LFxuICAgIHJvbGVzOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ0FjY2VzcyBjb250cm9sIGxpc3QgZm9yIHJvbGVzLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKFJPTEVfQUNMKSksXG4gICAgICByZXNvbHZlKHApIHtcbiAgICAgICAgY29uc3Qgcm9sZXMgPSBbXTtcbiAgICAgICAgT2JqZWN0LmtleXMocCkuZm9yRWFjaChydWxlID0+IHtcbiAgICAgICAgICBpZiAocnVsZS5pbmRleE9mKCdyb2xlOicpID09PSAwKSB7XG4gICAgICAgICAgICByb2xlcy5wdXNoKHtcbiAgICAgICAgICAgICAgcm9sZU5hbWU6IHJ1bGUucmVwbGFjZSgncm9sZTonLCAnJyksXG4gICAgICAgICAgICAgIHJlYWQ6IHBbcnVsZV0ucmVhZCA/IHRydWUgOiBmYWxzZSxcbiAgICAgICAgICAgICAgd3JpdGU6IHBbcnVsZV0ud3JpdGUgPyB0cnVlIDogZmFsc2UsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcm9sZXMubGVuZ3RoID8gcm9sZXMgOiBudWxsO1xuICAgICAgfSxcbiAgICB9LFxuICAgIHB1YmxpYzoge1xuICAgICAgZGVzY3JpcHRpb246ICdQdWJsaWMgYWNjZXNzIGNvbnRyb2wgbGlzdC4nLFxuICAgICAgdHlwZTogUFVCTElDX0FDTCxcbiAgICAgIHJlc29sdmUocCkge1xuICAgICAgICAvKiBlc2xpbnQtZGlzYWJsZSAqL1xuICAgICAgICByZXR1cm4gcFsnKiddXG4gICAgICAgICAgPyB7XG4gICAgICAgICAgICAgIHJlYWQ6IHBbJyonXS5yZWFkID8gdHJ1ZSA6IGZhbHNlLFxuICAgICAgICAgICAgICB3cml0ZTogcFsnKiddLndyaXRlID8gdHJ1ZSA6IGZhbHNlLFxuICAgICAgICAgICAgfVxuICAgICAgICAgIDogbnVsbDtcbiAgICAgIH0sXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBPQkpFQ1RfSUQgPSBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTElEKTtcblxuY29uc3QgQ0xBU1NfTkFNRV9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgY2xhc3MgbmFtZSBvZiB0aGUgb2JqZWN0LicsXG4gIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbn07XG5cbmNvbnN0IEdMT0JBTF9PUl9PQkpFQ1RfSURfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIG9iamVjdCBpZC4gWW91IGNhbiB1c2UgZWl0aGVyIHRoZSBnbG9iYWwgb3IgdGhlIG9iamVjdCBpZC4nLFxuICB0eXBlOiBPQkpFQ1RfSUQsXG59O1xuXG5jb25zdCBPQkpFQ1RfSURfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIG9iamVjdCBpZC4nLFxuICB0eXBlOiBPQkpFQ1RfSUQsXG59O1xuXG5jb25zdCBDUkVBVEVEX0FUX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBkYXRlIGluIHdoaWNoIHRoZSBvYmplY3Qgd2FzIGNyZWF0ZWQuJyxcbiAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKERBVEUpLFxufTtcblxuY29uc3QgVVBEQVRFRF9BVF9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgZGF0ZSBpbiB3aGljaCB0aGUgb2JqZWN0IHdhcyBsYXMgdXBkYXRlZC4nLFxuICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoREFURSksXG59O1xuXG5jb25zdCBJTlBVVF9GSUVMRFMgPSB7XG4gIEFDTDoge1xuICAgIHR5cGU6IEFDTCxcbiAgfSxcbn07XG5cbmNvbnN0IENSRUFURV9SRVNVTFRfRklFTERTID0ge1xuICBvYmplY3RJZDogT0JKRUNUX0lEX0FUVCxcbiAgY3JlYXRlZEF0OiBDUkVBVEVEX0FUX0FUVCxcbn07XG5cbmNvbnN0IFVQREFURV9SRVNVTFRfRklFTERTID0ge1xuICB1cGRhdGVkQXQ6IFVQREFURURfQVRfQVRULFxufTtcblxuY29uc3QgUEFSU0VfT0JKRUNUX0ZJRUxEUyA9IHtcbiAgLi4uQ1JFQVRFX1JFU1VMVF9GSUVMRFMsXG4gIC4uLlVQREFURV9SRVNVTFRfRklFTERTLFxuICAuLi5JTlBVVF9GSUVMRFMsXG4gIEFDTDoge1xuICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChBQ0wpLFxuICAgIHJlc29sdmU6ICh7IEFDTCB9KSA9PiAoQUNMID8gQUNMIDogeyAnKic6IHsgcmVhZDogdHJ1ZSwgd3JpdGU6IHRydWUgfSB9KSxcbiAgfSxcbn07XG5cbmNvbnN0IFBBUlNFX09CSkVDVCA9IG5ldyBHcmFwaFFMSW50ZXJmYWNlVHlwZSh7XG4gIG5hbWU6ICdQYXJzZU9iamVjdCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgUGFyc2VPYmplY3QgaW50ZXJmYWNlIHR5cGUgaXMgdXNlZCBhcyBhIGJhc2UgdHlwZSBmb3IgdGhlIGF1dG8gZ2VuZXJhdGVkIG9iamVjdCB0eXBlcy4nLFxuICBmaWVsZHM6IFBBUlNFX09CSkVDVF9GSUVMRFMsXG59KTtcblxuY29uc3QgU0VTU0lPTl9UT0tFTl9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhlIGN1cnJlbnQgdXNlciBzZXNzaW9uIHRva2VuLicsXG4gIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbn07XG5cbmNvbnN0IFJFQURfUFJFRkVSRU5DRSA9IG5ldyBHcmFwaFFMRW51bVR5cGUoe1xuICBuYW1lOiAnUmVhZFByZWZlcmVuY2UnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFJlYWRQcmVmZXJlbmNlIGVudW0gdHlwZSBpcyB1c2VkIGluIHF1ZXJpZXMgaW4gb3JkZXIgdG8gc2VsZWN0IGluIHdoaWNoIGRhdGFiYXNlIHJlcGxpY2EgdGhlIG9wZXJhdGlvbiBtdXN0IHJ1bi4nLFxuICB2YWx1ZXM6IHtcbiAgICBQUklNQVJZOiB7IHZhbHVlOiAnUFJJTUFSWScgfSxcbiAgICBQUklNQVJZX1BSRUZFUlJFRDogeyB2YWx1ZTogJ1BSSU1BUllfUFJFRkVSUkVEJyB9LFxuICAgIFNFQ09OREFSWTogeyB2YWx1ZTogJ1NFQ09OREFSWScgfSxcbiAgICBTRUNPTkRBUllfUFJFRkVSUkVEOiB7IHZhbHVlOiAnU0VDT05EQVJZX1BSRUZFUlJFRCcgfSxcbiAgICBORUFSRVNUOiB7IHZhbHVlOiAnTkVBUkVTVCcgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBSRUFEX1BSRUZFUkVOQ0VfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoZSByZWFkIHByZWZlcmVuY2UgZm9yIHRoZSBtYWluIHF1ZXJ5IHRvIGJlIGV4ZWN1dGVkLicsXG4gIHR5cGU6IFJFQURfUFJFRkVSRU5DRSxcbn07XG5cbmNvbnN0IElOQ0xVREVfUkVBRF9QUkVGRVJFTkNFX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246ICdUaGUgcmVhZCBwcmVmZXJlbmNlIGZvciB0aGUgcXVlcmllcyB0byBiZSBleGVjdXRlZCB0byBpbmNsdWRlIGZpZWxkcy4nLFxuICB0eXBlOiBSRUFEX1BSRUZFUkVOQ0UsXG59O1xuXG5jb25zdCBTVUJRVUVSWV9SRUFEX1BSRUZFUkVOQ0VfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoZSByZWFkIHByZWZlcmVuY2UgZm9yIHRoZSBzdWJxdWVyaWVzIHRoYXQgbWF5IGJlIHJlcXVpcmVkLicsXG4gIHR5cGU6IFJFQURfUFJFRkVSRU5DRSxcbn07XG5cbmNvbnN0IFJFQURfT1BUSU9OU19JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1JlYWRPcHRpb25zSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFJlYWRPcHRpb25zSW5wdXR0IHR5cGUgaXMgdXNlZCBpbiBxdWVyaWVzIGluIG9yZGVyIHRvIHNldCB0aGUgcmVhZCBwcmVmZXJlbmNlcy4nLFxuICBmaWVsZHM6IHtcbiAgICByZWFkUHJlZmVyZW5jZTogUkVBRF9QUkVGRVJFTkNFX0FUVCxcbiAgICBpbmNsdWRlUmVhZFByZWZlcmVuY2U6IElOQ0xVREVfUkVBRF9QUkVGRVJFTkNFX0FUVCxcbiAgICBzdWJxdWVyeVJlYWRQcmVmZXJlbmNlOiBTVUJRVUVSWV9SRUFEX1BSRUZFUkVOQ0VfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFJFQURfT1BUSU9OU19BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhlIHJlYWQgb3B0aW9ucyBmb3IgdGhlIHF1ZXJ5IHRvIGJlIGV4ZWN1dGVkLicsXG4gIHR5cGU6IFJFQURfT1BUSU9OU19JTlBVVCxcbn07XG5cbmNvbnN0IFdIRVJFX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIGNvbmRpdGlvbnMgdGhhdCB0aGUgb2JqZWN0cyBuZWVkIHRvIG1hdGNoIGluIG9yZGVyIHRvIGJlIGZvdW5kJyxcbiAgdHlwZTogT0JKRUNULFxufTtcblxuY29uc3QgU0tJUF9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgbnVtYmVyIG9mIG9iamVjdHMgdGhhdCBtdXN0IGJlIHNraXBwZWQgdG8gcmV0dXJuLicsXG4gIHR5cGU6IEdyYXBoUUxJbnQsXG59O1xuXG5jb25zdCBMSU1JVF9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgbGltaXQgbnVtYmVyIG9mIG9iamVjdHMgdGhhdCBtdXN0IGJlIHJldHVybmVkLicsXG4gIHR5cGU6IEdyYXBoUUxJbnQsXG59O1xuXG5jb25zdCBDT1VOVF9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSB0b3RhbCBtYXRjaGVkIG9iamVjcyBjb3VudCB0aGF0IGlzIHJldHVybmVkIHdoZW4gdGhlIGNvdW50IGZsYWcgaXMgc2V0LicsXG4gIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMSW50KSxcbn07XG5cbmNvbnN0IFNFQVJDSF9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NlYXJjaElucHV0JyxcbiAgZGVzY3JpcHRpb246ICdUaGUgU2VhcmNoSW5wdXQgdHlwZSBpcyB1c2VkIHRvIHNwZWNpZml5IGEgc2VhcmNoIG9wZXJhdGlvbiBvbiBhIGZ1bGwgdGV4dCBzZWFyY2guJyxcbiAgZmllbGRzOiB7XG4gICAgdGVybToge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSB0ZXJtIHRvIGJlIHNlYXJjaGVkLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgfSxcbiAgICBsYW5ndWFnZToge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSBsYW5ndWFnZSB0byB0ZXRlcm1pbmUgdGhlIGxpc3Qgb2Ygc3RvcCB3b3JkcyBhbmQgdGhlIHJ1bGVzIGZvciB0b2tlbml6ZXIuJyxcbiAgICAgIHR5cGU6IEdyYXBoUUxTdHJpbmcsXG4gICAgfSxcbiAgICBjYXNlU2Vuc2l0aXZlOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGZsYWcgdG8gZW5hYmxlIG9yIGRpc2FibGUgY2FzZSBzZW5zaXRpdmUgc2VhcmNoLicsXG4gICAgICB0eXBlOiBHcmFwaFFMQm9vbGVhbixcbiAgICB9LFxuICAgIGRpYWNyaXRpY1NlbnNpdGl2ZToge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBmbGFnIHRvIGVuYWJsZSBvciBkaXNhYmxlIGRpYWNyaXRpYyBzZW5zaXRpdmUgc2VhcmNoLicsXG4gICAgICB0eXBlOiBHcmFwaFFMQm9vbGVhbixcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IFRFWFRfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdUZXh0SW5wdXQnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBUZXh0SW5wdXQgdHlwZSBpcyB1c2VkIHRvIHNwZWNpZnkgYSB0ZXh0IG9wZXJhdGlvbiBvbiBhIGNvbnN0cmFpbnQuJyxcbiAgZmllbGRzOiB7XG4gICAgc2VhcmNoOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIHNlYXJjaCB0byBiZSBleGVjdXRlZC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKFNFQVJDSF9JTlBVVCksXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBCT1hfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdCb3hJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOiAnVGhlIEJveElucHV0IHR5cGUgaXMgdXNlZCB0byBzcGVjaWZpeSBhIGJveCBvcGVyYXRpb24gb24gYSB3aXRoaW4gZ2VvIHF1ZXJ5LicsXG4gIGZpZWxkczoge1xuICAgIGJvdHRvbUxlZnQ6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgYm90dG9tIGxlZnQgY29vcmRpbmF0ZXMgb2YgdGhlIGJveC4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdFT19QT0lOVF9JTlBVVCksXG4gICAgfSxcbiAgICB1cHBlclJpZ2h0OiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIHVwcGVyIHJpZ2h0IGNvb3JkaW5hdGVzIG9mIHRoZSBib3guJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHRU9fUE9JTlRfSU5QVVQpLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgV0lUSElOX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnV2l0aGluSW5wdXQnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBXaXRoaW5JbnB1dCB0eXBlIGlzIHVzZWQgdG8gc3BlY2lmeSBhIHdpdGhpbiBvcGVyYXRpb24gb24gYSBjb25zdHJhaW50LicsXG4gIGZpZWxkczoge1xuICAgIGJveDoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBib3ggdG8gYmUgc3BlY2lmaWVkLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoQk9YX0lOUFVUKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IENFTlRFUl9TUEhFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdDZW50ZXJTcGhlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgQ2VudGVyU3BoZXJlSW5wdXQgdHlwZSBpcyB1c2VkIHRvIHNwZWNpZml5IGEgY2VudGVyU3BoZXJlIG9wZXJhdGlvbiBvbiBhIGdlb1dpdGhpbiBxdWVyeS4nLFxuICBmaWVsZHM6IHtcbiAgICBjZW50ZXI6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgY2VudGVyIG9mIHRoZSBzcGhlcmUuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHRU9fUE9JTlRfSU5QVVQpLFxuICAgIH0sXG4gICAgZGlzdGFuY2U6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgcmFkaXVzIG9mIHRoZSBzcGhlcmUuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMRmxvYXQpLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgR0VPX1dJVEhJTl9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0dlb1dpdGhpbklucHV0JyxcbiAgZGVzY3JpcHRpb246ICdUaGUgR2VvV2l0aGluSW5wdXQgdHlwZSBpcyB1c2VkIHRvIHNwZWNpZnkgYSBnZW9XaXRoaW4gb3BlcmF0aW9uIG9uIGEgY29uc3RyYWludC4nLFxuICBmaWVsZHM6IHtcbiAgICBwb2x5Z29uOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIHBvbHlnb24gdG8gYmUgc3BlY2lmaWVkLicsXG4gICAgICB0eXBlOiBQT0xZR09OX0lOUFVULFxuICAgIH0sXG4gICAgY2VudGVyU3BoZXJlOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIHNwaGVyZSB0byBiZSBzcGVjaWZpZWQuJyxcbiAgICAgIHR5cGU6IENFTlRFUl9TUEhFUkVfSU5QVVQsXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBHRU9fSU5URVJTRUNUU19JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0dlb0ludGVyc2VjdHNJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgR2VvSW50ZXJzZWN0c0lucHV0IHR5cGUgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZ2VvSW50ZXJzZWN0cyBvcGVyYXRpb24gb24gYSBjb25zdHJhaW50LicsXG4gIGZpZWxkczoge1xuICAgIHBvaW50OiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIHBvaW50IHRvIGJlIHNwZWNpZmllZC4nLFxuICAgICAgdHlwZTogR0VPX1BPSU5UX0lOUFVULFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgZXF1YWxUbyA9IHR5cGUgPT4gKHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIGVxdWFsVG8gb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIHRoZSB2YWx1ZSBvZiBhIGZpZWxkIGVxdWFscyB0byBhIHNwZWNpZmllZCB2YWx1ZS4nLFxuICB0eXBlLFxufSk7XG5cbmNvbnN0IG5vdEVxdWFsVG8gPSB0eXBlID0+ICh7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBub3RFcXVhbFRvIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBkbyBub3QgZXF1YWwgdG8gYSBzcGVjaWZpZWQgdmFsdWUuJyxcbiAgdHlwZSxcbn0pO1xuXG5jb25zdCBsZXNzVGhhbiA9IHR5cGUgPT4gKHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIGxlc3NUaGFuIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBpcyBsZXNzIHRoYW4gYSBzcGVjaWZpZWQgdmFsdWUuJyxcbiAgdHlwZSxcbn0pO1xuXG5jb25zdCBsZXNzVGhhbk9yRXF1YWxUbyA9IHR5cGUgPT4gKHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIGxlc3NUaGFuT3JFcXVhbFRvIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gYSBzcGVjaWZpZWQgdmFsdWUuJyxcbiAgdHlwZSxcbn0pO1xuXG5jb25zdCBncmVhdGVyVGhhbiA9IHR5cGUgPT4gKHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIGdyZWF0ZXJUaGFuIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBpcyBncmVhdGVyIHRoYW4gYSBzcGVjaWZpZWQgdmFsdWUuJyxcbiAgdHlwZSxcbn0pO1xuXG5jb25zdCBncmVhdGVyVGhhbk9yRXF1YWxUbyA9IHR5cGUgPT4gKHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIGdyZWF0ZXJUaGFuT3JFcXVhbFRvIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYSBzcGVjaWZpZWQgdmFsdWUuJyxcbiAgdHlwZSxcbn0pO1xuXG5jb25zdCBpbk9wID0gdHlwZSA9PiAoe1xuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhpcyBpcyB0aGUgaW4gb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIHRoZSB2YWx1ZSBvZiBhIGZpZWxkIGVxdWFscyBhbnkgdmFsdWUgaW4gdGhlIHNwZWNpZmllZCBhcnJheS4nLFxuICB0eXBlOiBuZXcgR3JhcGhRTExpc3QodHlwZSksXG59KTtcblxuY29uc3Qgbm90SW4gPSB0eXBlID0+ICh7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBub3RJbiBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlIG9mIGEgZmllbGQgZG8gbm90IGVxdWFsIGFueSB2YWx1ZSBpbiB0aGUgc3BlY2lmaWVkIGFycmF5LicsXG4gIHR5cGU6IG5ldyBHcmFwaFFMTGlzdCh0eXBlKSxcbn0pO1xuXG5jb25zdCBleGlzdHMgPSB7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBleGlzdHMgb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIGEgZmllbGQgZXhpc3RzIChvciBkbyBub3QgZXhpc3QpLicsXG4gIHR5cGU6IEdyYXBoUUxCb29sZWFuLFxufTtcblxuY29uc3QgbWF0Y2hlc1JlZ2V4ID0ge1xuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhpcyBpcyB0aGUgbWF0Y2hlc1JlZ2V4IG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWUgb2YgYSBmaWVsZCBtYXRjaGVzIGEgc3BlY2lmaWVkIHJlZ3VsYXIgZXhwcmVzc2lvbi4nLFxuICB0eXBlOiBHcmFwaFFMU3RyaW5nLFxufTtcblxuY29uc3Qgb3B0aW9ucyA9IHtcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoaXMgaXMgdGhlIG9wdGlvbnMgb3BlcmF0b3IgdG8gc3BlY2lmeSBvcHRpb25hbCBmbGFncyAoc3VjaCBhcyBcImlcIiBhbmQgXCJtXCIpIHRvIGJlIGFkZGVkIHRvIGEgbWF0Y2hlc1JlZ2V4IG9wZXJhdGlvbiBpbiB0aGUgc2FtZSBzZXQgb2YgY29uc3RyYWludHMuJyxcbiAgdHlwZTogR3JhcGhRTFN0cmluZyxcbn07XG5cbmNvbnN0IFNVQlFVRVJZX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU3VicXVlcnlJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOiAnVGhlIFN1YnF1ZXJ5SW5wdXQgdHlwZSBpcyB1c2VkIHRvIHNwZWNpZnkgYSBzdWIgcXVlcnkgdG8gYW5vdGhlciBjbGFzcy4nLFxuICBmaWVsZHM6IHtcbiAgICBjbGFzc05hbWU6IENMQVNTX05BTUVfQVRULFxuICAgIHdoZXJlOiBPYmplY3QuYXNzaWduKHt9LCBXSEVSRV9BVFQsIHtcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChXSEVSRV9BVFQudHlwZSksXG4gICAgfSksXG4gIH0sXG59KTtcblxuY29uc3QgU0VMRUNUX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2VsZWN0SW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNlbGVjdElucHV0IHR5cGUgaXMgdXNlZCB0byBzcGVjaWZ5IGFuIGluUXVlcnlLZXkgb3IgYSBub3RJblF1ZXJ5S2V5IG9wZXJhdGlvbiBvbiBhIGNvbnN0cmFpbnQuJyxcbiAgZmllbGRzOiB7XG4gICAgcXVlcnk6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgc3VicXVlcnkgdG8gYmUgZXhlY3V0ZWQuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChTVUJRVUVSWV9JTlBVVCksXG4gICAgfSxcbiAgICBrZXk6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhpcyBpcyB0aGUga2V5IGluIHRoZSByZXN1bHQgb2YgdGhlIHN1YnF1ZXJ5IHRoYXQgbXVzdCBtYXRjaCAobm90IG1hdGNoKSB0aGUgZmllbGQuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IGluUXVlcnlLZXkgPSB7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBpblF1ZXJ5S2V5IG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSBhIGZpZWxkIGVxdWFscyB0byBhIGtleSBpbiB0aGUgcmVzdWx0IG9mIGEgZGlmZmVyZW50IHF1ZXJ5LicsXG4gIHR5cGU6IFNFTEVDVF9JTlBVVCxcbn07XG5cbmNvbnN0IG5vdEluUXVlcnlLZXkgPSB7XG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGlzIGlzIHRoZSBub3RJblF1ZXJ5S2V5IG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSBhIGZpZWxkIGRvIG5vdCBlcXVhbCB0byBhIGtleSBpbiB0aGUgcmVzdWx0IG9mIGEgZGlmZmVyZW50IHF1ZXJ5LicsXG4gIHR5cGU6IFNFTEVDVF9JTlBVVCxcbn07XG5cbmNvbnN0IElEX1dIRVJFX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnSWRXaGVyZUlucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBJZFdoZXJlSW5wdXQgaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGZpbHRlcmluZyBvYmplY3RzIGJ5IGFuIGlkLicsXG4gIGZpZWxkczoge1xuICAgIGVxdWFsVG86IGVxdWFsVG8oR3JhcGhRTElEKSxcbiAgICBub3RFcXVhbFRvOiBub3RFcXVhbFRvKEdyYXBoUUxJRCksXG4gICAgbGVzc1RoYW46IGxlc3NUaGFuKEdyYXBoUUxJRCksXG4gICAgbGVzc1RoYW5PckVxdWFsVG86IGxlc3NUaGFuT3JFcXVhbFRvKEdyYXBoUUxJRCksXG4gICAgZ3JlYXRlclRoYW46IGdyZWF0ZXJUaGFuKEdyYXBoUUxJRCksXG4gICAgZ3JlYXRlclRoYW5PckVxdWFsVG86IGdyZWF0ZXJUaGFuT3JFcXVhbFRvKEdyYXBoUUxJRCksXG4gICAgaW46IGluT3AoR3JhcGhRTElEKSxcbiAgICBub3RJbjogbm90SW4oR3JhcGhRTElEKSxcbiAgICBleGlzdHMsXG4gICAgaW5RdWVyeUtleSxcbiAgICBub3RJblF1ZXJ5S2V5LFxuICB9LFxufSk7XG5cbmNvbnN0IFNUUklOR19XSEVSRV9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1N0cmluZ1doZXJlSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFN0cmluZ1doZXJlSW5wdXQgaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGZpbHRlcmluZyBvYmplY3RzIGJ5IGEgZmllbGQgb2YgdHlwZSBTdHJpbmcuJyxcbiAgZmllbGRzOiB7XG4gICAgZXF1YWxUbzogZXF1YWxUbyhHcmFwaFFMU3RyaW5nKSxcbiAgICBub3RFcXVhbFRvOiBub3RFcXVhbFRvKEdyYXBoUUxTdHJpbmcpLFxuICAgIGxlc3NUaGFuOiBsZXNzVGhhbihHcmFwaFFMU3RyaW5nKSxcbiAgICBsZXNzVGhhbk9yRXF1YWxUbzogbGVzc1RoYW5PckVxdWFsVG8oR3JhcGhRTFN0cmluZyksXG4gICAgZ3JlYXRlclRoYW46IGdyZWF0ZXJUaGFuKEdyYXBoUUxTdHJpbmcpLFxuICAgIGdyZWF0ZXJUaGFuT3JFcXVhbFRvOiBncmVhdGVyVGhhbk9yRXF1YWxUbyhHcmFwaFFMU3RyaW5nKSxcbiAgICBpbjogaW5PcChHcmFwaFFMU3RyaW5nKSxcbiAgICBub3RJbjogbm90SW4oR3JhcGhRTFN0cmluZyksXG4gICAgZXhpc3RzLFxuICAgIG1hdGNoZXNSZWdleCxcbiAgICBvcHRpb25zLFxuICAgIHRleHQ6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgJHRleHQgb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGZ1bGwgdGV4dCBzZWFyY2ggY29uc3RyYWludC4nLFxuICAgICAgdHlwZTogVEVYVF9JTlBVVCxcbiAgICB9LFxuICAgIGluUXVlcnlLZXksXG4gICAgbm90SW5RdWVyeUtleSxcbiAgfSxcbn0pO1xuXG5jb25zdCBOVU1CRVJfV0hFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdOdW1iZXJXaGVyZUlucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBOdW1iZXJXaGVyZUlucHV0IGlucHV0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBmaWx0ZXJpbmcgb2JqZWN0cyBieSBhIGZpZWxkIG9mIHR5cGUgTnVtYmVyLicsXG4gIGZpZWxkczoge1xuICAgIGVxdWFsVG86IGVxdWFsVG8oR3JhcGhRTEZsb2F0KSxcbiAgICBub3RFcXVhbFRvOiBub3RFcXVhbFRvKEdyYXBoUUxGbG9hdCksXG4gICAgbGVzc1RoYW46IGxlc3NUaGFuKEdyYXBoUUxGbG9hdCksXG4gICAgbGVzc1RoYW5PckVxdWFsVG86IGxlc3NUaGFuT3JFcXVhbFRvKEdyYXBoUUxGbG9hdCksXG4gICAgZ3JlYXRlclRoYW46IGdyZWF0ZXJUaGFuKEdyYXBoUUxGbG9hdCksXG4gICAgZ3JlYXRlclRoYW5PckVxdWFsVG86IGdyZWF0ZXJUaGFuT3JFcXVhbFRvKEdyYXBoUUxGbG9hdCksXG4gICAgaW46IGluT3AoR3JhcGhRTEZsb2F0KSxcbiAgICBub3RJbjogbm90SW4oR3JhcGhRTEZsb2F0KSxcbiAgICBleGlzdHMsXG4gICAgaW5RdWVyeUtleSxcbiAgICBub3RJblF1ZXJ5S2V5LFxuICB9LFxufSk7XG5cbmNvbnN0IEJPT0xFQU5fV0hFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdCb29sZWFuV2hlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgQm9vbGVhbldoZXJlSW5wdXQgaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGZpbHRlcmluZyBvYmplY3RzIGJ5IGEgZmllbGQgb2YgdHlwZSBCb29sZWFuLicsXG4gIGZpZWxkczoge1xuICAgIGVxdWFsVG86IGVxdWFsVG8oR3JhcGhRTEJvb2xlYW4pLFxuICAgIG5vdEVxdWFsVG86IG5vdEVxdWFsVG8oR3JhcGhRTEJvb2xlYW4pLFxuICAgIGV4aXN0cyxcbiAgICBpblF1ZXJ5S2V5LFxuICAgIG5vdEluUXVlcnlLZXksXG4gIH0sXG59KTtcblxuY29uc3QgQVJSQVlfV0hFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdBcnJheVdoZXJlSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIEFycmF5V2hlcmVJbnB1dCBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIG9iamVjdHMgYnkgYSBmaWVsZCBvZiB0eXBlIEFycmF5LicsXG4gIGZpZWxkczoge1xuICAgIGVxdWFsVG86IGVxdWFsVG8oQU5ZKSxcbiAgICBub3RFcXVhbFRvOiBub3RFcXVhbFRvKEFOWSksXG4gICAgbGVzc1RoYW46IGxlc3NUaGFuKEFOWSksXG4gICAgbGVzc1RoYW5PckVxdWFsVG86IGxlc3NUaGFuT3JFcXVhbFRvKEFOWSksXG4gICAgZ3JlYXRlclRoYW46IGdyZWF0ZXJUaGFuKEFOWSksXG4gICAgZ3JlYXRlclRoYW5PckVxdWFsVG86IGdyZWF0ZXJUaGFuT3JFcXVhbFRvKEFOWSksXG4gICAgaW46IGluT3AoQU5ZKSxcbiAgICBub3RJbjogbm90SW4oQU5ZKSxcbiAgICBleGlzdHMsXG4gICAgY29udGFpbmVkQnk6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhpcyBpcyB0aGUgY29udGFpbmVkQnkgb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIHRoZSB2YWx1ZXMgb2YgYW4gYXJyYXkgZmllbGQgaXMgY29udGFpbmVkIGJ5IGFub3RoZXIgc3BlY2lmaWVkIGFycmF5LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QoQU5ZKSxcbiAgICB9LFxuICAgIGNvbnRhaW5zOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIGNvbnRhaW5zIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWVzIG9mIGFuIGFycmF5IGZpZWxkIGNvbnRhaW4gYWxsIGVsZW1lbnRzIG9mIGFub3RoZXIgc3BlY2lmaWVkIGFycmF5LicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QoQU5ZKSxcbiAgICB9LFxuICAgIGluUXVlcnlLZXksXG4gICAgbm90SW5RdWVyeUtleSxcbiAgfSxcbn0pO1xuXG5jb25zdCBLRVlfVkFMVUVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdLZXlWYWx1ZUlucHV0JyxcbiAgZGVzY3JpcHRpb246ICdBbiBlbnRyeSBmcm9tIGFuIG9iamVjdCwgaS5lLiwgYSBwYWlyIG9mIGtleSBhbmQgdmFsdWUuJyxcbiAgZmllbGRzOiB7XG4gICAga2V5OiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSBrZXkgdXNlZCB0byByZXRyaWV2ZSB0aGUgdmFsdWUgb2YgdGhpcyBlbnRyeS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKEdyYXBoUUxTdHJpbmcpLFxuICAgIH0sXG4gICAgdmFsdWU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIHZhbHVlIG9mIHRoZSBlbnRyeS4gQ291bGQgYmUgYW55IHR5cGUgb2Ygc2NhbGFyIGRhdGEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChBTlkpLFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgT0JKRUNUX1dIRVJFX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnT2JqZWN0V2hlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgT2JqZWN0V2hlcmVJbnB1dCBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIHJlc3VsdCBieSBhIGZpZWxkIG9mIHR5cGUgT2JqZWN0LicsXG4gIGZpZWxkczoge1xuICAgIGVxdWFsVG86IGVxdWFsVG8oS0VZX1ZBTFVFX0lOUFVUKSxcbiAgICBub3RFcXVhbFRvOiBub3RFcXVhbFRvKEtFWV9WQUxVRV9JTlBVVCksXG4gICAgaW46IGluT3AoS0VZX1ZBTFVFX0lOUFVUKSxcbiAgICBub3RJbjogbm90SW4oS0VZX1ZBTFVFX0lOUFVUKSxcbiAgICBsZXNzVGhhbjogbGVzc1RoYW4oS0VZX1ZBTFVFX0lOUFVUKSxcbiAgICBsZXNzVGhhbk9yRXF1YWxUbzogbGVzc1RoYW5PckVxdWFsVG8oS0VZX1ZBTFVFX0lOUFVUKSxcbiAgICBncmVhdGVyVGhhbjogZ3JlYXRlclRoYW4oS0VZX1ZBTFVFX0lOUFVUKSxcbiAgICBncmVhdGVyVGhhbk9yRXF1YWxUbzogZ3JlYXRlclRoYW5PckVxdWFsVG8oS0VZX1ZBTFVFX0lOUFVUKSxcbiAgICBleGlzdHMsXG4gICAgaW5RdWVyeUtleSxcbiAgICBub3RJblF1ZXJ5S2V5LFxuICB9LFxufSk7XG5cbmNvbnN0IERBVEVfV0hFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdEYXRlV2hlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgRGF0ZVdoZXJlSW5wdXQgaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGZpbHRlcmluZyBvYmplY3RzIGJ5IGEgZmllbGQgb2YgdHlwZSBEYXRlLicsXG4gIGZpZWxkczoge1xuICAgIGVxdWFsVG86IGVxdWFsVG8oREFURSksXG4gICAgbm90RXF1YWxUbzogbm90RXF1YWxUbyhEQVRFKSxcbiAgICBsZXNzVGhhbjogbGVzc1RoYW4oREFURSksXG4gICAgbGVzc1RoYW5PckVxdWFsVG86IGxlc3NUaGFuT3JFcXVhbFRvKERBVEUpLFxuICAgIGdyZWF0ZXJUaGFuOiBncmVhdGVyVGhhbihEQVRFKSxcbiAgICBncmVhdGVyVGhhbk9yRXF1YWxUbzogZ3JlYXRlclRoYW5PckVxdWFsVG8oREFURSksXG4gICAgaW46IGluT3AoREFURSksXG4gICAgbm90SW46IG5vdEluKERBVEUpLFxuICAgIGV4aXN0cyxcbiAgICBpblF1ZXJ5S2V5LFxuICAgIG5vdEluUXVlcnlLZXksXG4gIH0sXG59KTtcblxuY29uc3QgQllURVNfV0hFUkVfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdCeXRlc1doZXJlSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIEJ5dGVzV2hlcmVJbnB1dCBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIG9iamVjdHMgYnkgYSBmaWVsZCBvZiB0eXBlIEJ5dGVzLicsXG4gIGZpZWxkczoge1xuICAgIGVxdWFsVG86IGVxdWFsVG8oQllURVMpLFxuICAgIG5vdEVxdWFsVG86IG5vdEVxdWFsVG8oQllURVMpLFxuICAgIGxlc3NUaGFuOiBsZXNzVGhhbihCWVRFUyksXG4gICAgbGVzc1RoYW5PckVxdWFsVG86IGxlc3NUaGFuT3JFcXVhbFRvKEJZVEVTKSxcbiAgICBncmVhdGVyVGhhbjogZ3JlYXRlclRoYW4oQllURVMpLFxuICAgIGdyZWF0ZXJUaGFuT3JFcXVhbFRvOiBncmVhdGVyVGhhbk9yRXF1YWxUbyhCWVRFUyksXG4gICAgaW46IGluT3AoQllURVMpLFxuICAgIG5vdEluOiBub3RJbihCWVRFUyksXG4gICAgZXhpc3RzLFxuICAgIGluUXVlcnlLZXksXG4gICAgbm90SW5RdWVyeUtleSxcbiAgfSxcbn0pO1xuXG5jb25zdCBGSUxFX1dIRVJFX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnRmlsZVdoZXJlSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIEZpbGVXaGVyZUlucHV0IGlucHV0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBmaWx0ZXJpbmcgb2JqZWN0cyBieSBhIGZpZWxkIG9mIHR5cGUgRmlsZS4nLFxuICBmaWVsZHM6IHtcbiAgICBlcXVhbFRvOiBlcXVhbFRvKEZJTEUpLFxuICAgIG5vdEVxdWFsVG86IG5vdEVxdWFsVG8oRklMRSksXG4gICAgbGVzc1RoYW46IGxlc3NUaGFuKEZJTEUpLFxuICAgIGxlc3NUaGFuT3JFcXVhbFRvOiBsZXNzVGhhbk9yRXF1YWxUbyhGSUxFKSxcbiAgICBncmVhdGVyVGhhbjogZ3JlYXRlclRoYW4oRklMRSksXG4gICAgZ3JlYXRlclRoYW5PckVxdWFsVG86IGdyZWF0ZXJUaGFuT3JFcXVhbFRvKEZJTEUpLFxuICAgIGluOiBpbk9wKEZJTEUpLFxuICAgIG5vdEluOiBub3RJbihGSUxFKSxcbiAgICBleGlzdHMsXG4gICAgbWF0Y2hlc1JlZ2V4LFxuICAgIG9wdGlvbnMsXG4gICAgaW5RdWVyeUtleSxcbiAgICBub3RJblF1ZXJ5S2V5LFxuICB9LFxufSk7XG5cbmNvbnN0IEdFT19QT0lOVF9XSEVSRV9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ0dlb1BvaW50V2hlcmVJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgR2VvUG9pbnRXaGVyZUlucHV0IGlucHV0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBmaWx0ZXJpbmcgb2JqZWN0cyBieSBhIGZpZWxkIG9mIHR5cGUgR2VvUG9pbnQuJyxcbiAgZmllbGRzOiB7XG4gICAgZXhpc3RzLFxuICAgIG5lYXJTcGhlcmU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhpcyBpcyB0aGUgbmVhclNwaGVyZSBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlcyBvZiBhIGdlbyBwb2ludCBmaWVsZCBpcyBuZWFyIHRvIGFub3RoZXIgZ2VvIHBvaW50LicsXG4gICAgICB0eXBlOiBHRU9fUE9JTlRfSU5QVVQsXG4gICAgfSxcbiAgICBtYXhEaXN0YW5jZToge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSBtYXhEaXN0YW5jZSBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlcyBvZiBhIGdlbyBwb2ludCBmaWVsZCBpcyBhdCBhIG1heCBkaXN0YW5jZSAoaW4gcmFkaWFucykgZnJvbSB0aGUgZ2VvIHBvaW50IHNwZWNpZmllZCBpbiB0aGUgJG5lYXJTcGhlcmUgb3BlcmF0b3IuJyxcbiAgICAgIHR5cGU6IEdyYXBoUUxGbG9hdCxcbiAgICB9LFxuICAgIG1heERpc3RhbmNlSW5SYWRpYW5zOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIG1heERpc3RhbmNlSW5SYWRpYW5zIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWVzIG9mIGEgZ2VvIHBvaW50IGZpZWxkIGlzIGF0IGEgbWF4IGRpc3RhbmNlIChpbiByYWRpYW5zKSBmcm9tIHRoZSBnZW8gcG9pbnQgc3BlY2lmaWVkIGluIHRoZSAkbmVhclNwaGVyZSBvcGVyYXRvci4nLFxuICAgICAgdHlwZTogR3JhcGhRTEZsb2F0LFxuICAgIH0sXG4gICAgbWF4RGlzdGFuY2VJbk1pbGVzOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIG1heERpc3RhbmNlSW5NaWxlcyBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlcyBvZiBhIGdlbyBwb2ludCBmaWVsZCBpcyBhdCBhIG1heCBkaXN0YW5jZSAoaW4gbWlsZXMpIGZyb20gdGhlIGdlbyBwb2ludCBzcGVjaWZpZWQgaW4gdGhlICRuZWFyU3BoZXJlIG9wZXJhdG9yLicsXG4gICAgICB0eXBlOiBHcmFwaFFMRmxvYXQsXG4gICAgfSxcbiAgICBtYXhEaXN0YW5jZUluS2lsb21ldGVyczoge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSBtYXhEaXN0YW5jZUluS2lsb21ldGVycyBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlcyBvZiBhIGdlbyBwb2ludCBmaWVsZCBpcyBhdCBhIG1heCBkaXN0YW5jZSAoaW4ga2lsb21ldGVycykgZnJvbSB0aGUgZ2VvIHBvaW50IHNwZWNpZmllZCBpbiB0aGUgJG5lYXJTcGhlcmUgb3BlcmF0b3IuJyxcbiAgICAgIHR5cGU6IEdyYXBoUUxGbG9hdCxcbiAgICB9LFxuICAgIHdpdGhpbjoge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSB3aXRoaW4gb3BlcmF0b3IgdG8gc3BlY2lmeSBhIGNvbnN0cmFpbnQgdG8gc2VsZWN0IHRoZSBvYmplY3RzIHdoZXJlIHRoZSB2YWx1ZXMgb2YgYSBnZW8gcG9pbnQgZmllbGQgaXMgd2l0aGluIGEgc3BlY2lmaWVkIGJveC4nLFxuICAgICAgdHlwZTogV0lUSElOX0lOUFVULFxuICAgIH0sXG4gICAgZ2VvV2l0aGluOiB7XG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgJ1RoaXMgaXMgdGhlIGdlb1dpdGhpbiBvcGVyYXRvciB0byBzcGVjaWZ5IGEgY29uc3RyYWludCB0byBzZWxlY3QgdGhlIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlcyBvZiBhIGdlbyBwb2ludCBmaWVsZCBpcyB3aXRoaW4gYSBzcGVjaWZpZWQgcG9seWdvbiBvciBzcGhlcmUuJyxcbiAgICAgIHR5cGU6IEdFT19XSVRISU5fSU5QVVQsXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBQT0xZR09OX1dIRVJFX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnUG9seWdvbldoZXJlSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFBvbHlnb25XaGVyZUlucHV0IGlucHV0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBmaWx0ZXJpbmcgb2JqZWN0cyBieSBhIGZpZWxkIG9mIHR5cGUgUG9seWdvbi4nLFxuICBmaWVsZHM6IHtcbiAgICBleGlzdHMsXG4gICAgZ2VvSW50ZXJzZWN0czoge1xuICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICdUaGlzIGlzIHRoZSBnZW9JbnRlcnNlY3RzIG9wZXJhdG9yIHRvIHNwZWNpZnkgYSBjb25zdHJhaW50IHRvIHNlbGVjdCB0aGUgb2JqZWN0cyB3aGVyZSB0aGUgdmFsdWVzIG9mIGEgcG9seWdvbiBmaWVsZCBpbnRlcnNlY3QgYSBzcGVjaWZpZWQgcG9pbnQuJyxcbiAgICAgIHR5cGU6IEdFT19JTlRFUlNFQ1RTX0lOUFVULFxuICAgIH0sXG4gIH0sXG59KTtcblxuY29uc3QgRUxFTUVOVCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdFbGVtZW50JyxcbiAgZGVzY3JpcHRpb246IFwiVGhlIEVsZW1lbnQgb2JqZWN0IHR5cGUgaXMgdXNlZCB0byByZXR1cm4gYXJyYXkgaXRlbXMnIHZhbHVlLlwiLFxuICBmaWVsZHM6IHtcbiAgICB2YWx1ZToge1xuICAgICAgZGVzY3JpcHRpb246ICdSZXR1cm4gdGhlIHZhbHVlIG9mIHRoZSBlbGVtZW50IGluIHRoZSBhcnJheScsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoQU5ZKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbi8vIERlZmF1bHQgc3RhdGljIHVuaW9uIHR5cGUsIHdlIHVwZGF0ZSB0eXBlcyBhbmQgcmVzb2x2ZVR5cGUgZnVuY3Rpb24gbGF0ZXJcbmxldCBBUlJBWV9SRVNVTFQ7XG5cbmNvbnN0IGxvYWRBcnJheVJlc3VsdCA9IChwYXJzZUdyYXBoUUxTY2hlbWEsIHBhcnNlQ2xhc3NlcykgPT4ge1xuICBjb25zdCBjbGFzc1R5cGVzID0gcGFyc2VDbGFzc2VzXG4gICAgLmZpbHRlcihwYXJzZUNsYXNzID0+XG4gICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzW3BhcnNlQ2xhc3MuY2xhc3NOYW1lXS5jbGFzc0dyYXBoUUxPdXRwdXRUeXBlID8gdHJ1ZSA6IGZhbHNlXG4gICAgKVxuICAgIC5tYXAoXG4gICAgICBwYXJzZUNsYXNzID0+IHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzVHlwZXNbcGFyc2VDbGFzcy5jbGFzc05hbWVdLmNsYXNzR3JhcGhRTE91dHB1dFR5cGVcbiAgICApO1xuICBBUlJBWV9SRVNVTFQgPSBuZXcgR3JhcGhRTFVuaW9uVHlwZSh7XG4gICAgbmFtZTogJ0FycmF5UmVzdWx0JyxcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgICdVc2UgSW5saW5lIEZyYWdtZW50IG9uIEFycmF5IHRvIGdldCByZXN1bHRzOiBodHRwczovL2dyYXBocWwub3JnL2xlYXJuL3F1ZXJpZXMvI2lubGluZS1mcmFnbWVudHMnLFxuICAgIHR5cGVzOiAoKSA9PiBbRUxFTUVOVCwgLi4uY2xhc3NUeXBlc10sXG4gICAgcmVzb2x2ZVR5cGU6IHZhbHVlID0+IHtcbiAgICAgIGlmICh2YWx1ZS5fX3R5cGUgPT09ICdPYmplY3QnICYmIHZhbHVlLmNsYXNzTmFtZSAmJiB2YWx1ZS5vYmplY3RJZCkge1xuICAgICAgICBpZiAocGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1t2YWx1ZS5jbGFzc05hbWVdKSB7XG4gICAgICAgICAgcmV0dXJuIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzVHlwZXNbdmFsdWUuY2xhc3NOYW1lXS5jbGFzc0dyYXBoUUxPdXRwdXRUeXBlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBFTEVNRU5UO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gRUxFTUVOVDtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmdyYXBoUUxUeXBlcy5wdXNoKEFSUkFZX1JFU1VMVCk7XG59O1xuXG5jb25zdCBsb2FkID0gcGFyc2VHcmFwaFFMU2NoZW1hID0+IHtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEdyYXBoUUxVcGxvYWQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoQU5ZLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKE9CSkVDVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShEQVRFLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEJZVEVTLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEZJTEUsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoRklMRV9JTkZPLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEZJTEVfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoR0VPX1BPSU5UX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEdFT19QT0lOVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShQQVJTRV9PQkpFQ1QsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoUkVBRF9QUkVGRVJFTkNFLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFJFQURfT1BUSU9OU19JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTRUFSQ0hfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoVEVYVF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShCT1hfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoV0lUSElOX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKENFTlRFUl9TUEhFUkVfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoR0VPX1dJVEhJTl9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShHRU9fSU5URVJTRUNUU19JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShJRF9XSEVSRV9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTVFJJTkdfV0hFUkVfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoTlVNQkVSX1dIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEJPT0xFQU5fV0hFUkVfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoQVJSQVlfV0hFUkVfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoS0VZX1ZBTFVFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKE9CSkVDVF9XSEVSRV9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShEQVRFX1dIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEJZVEVTX1dIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKEZJTEVfV0hFUkVfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoR0VPX1BPSU5UX1dIRVJFX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFBPTFlHT05fV0hFUkVfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoRUxFTUVOVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShBQ0xfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoVVNFUl9BQ0xfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoUk9MRV9BQ0xfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoUFVCTElDX0FDTF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShBQ0wsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoVVNFUl9BQ0wsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoUk9MRV9BQ0wsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoUFVCTElDX0FDTCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTVUJRVUVSWV9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTRUxFQ1RfSU5QVVQsIHRydWUpO1xufTtcblxuZXhwb3J0IHtcbiAgVHlwZVZhbGlkYXRpb25FcnJvcixcbiAgcGFyc2VTdHJpbmdWYWx1ZSxcbiAgcGFyc2VJbnRWYWx1ZSxcbiAgcGFyc2VGbG9hdFZhbHVlLFxuICBwYXJzZUJvb2xlYW5WYWx1ZSxcbiAgcGFyc2VWYWx1ZSxcbiAgcGFyc2VMaXN0VmFsdWVzLFxuICBwYXJzZU9iamVjdEZpZWxkcyxcbiAgQU5ZLFxuICBPQkpFQ1QsXG4gIHBhcnNlRGF0ZUlzb1ZhbHVlLFxuICBzZXJpYWxpemVEYXRlSXNvLFxuICBEQVRFLFxuICBCWVRFUyxcbiAgcGFyc2VGaWxlVmFsdWUsXG4gIFNVQlFVRVJZX0lOUFVULFxuICBTRUxFQ1RfSU5QVVQsXG4gIEZJTEUsXG4gIEZJTEVfSU5GTyxcbiAgRklMRV9JTlBVVCxcbiAgR0VPX1BPSU5UX0ZJRUxEUyxcbiAgR0VPX1BPSU5UX0lOUFVULFxuICBHRU9fUE9JTlQsXG4gIFBPTFlHT05fSU5QVVQsXG4gIFBPTFlHT04sXG4gIE9CSkVDVF9JRCxcbiAgQ0xBU1NfTkFNRV9BVFQsXG4gIEdMT0JBTF9PUl9PQkpFQ1RfSURfQVRULFxuICBPQkpFQ1RfSURfQVRULFxuICBVUERBVEVEX0FUX0FUVCxcbiAgQ1JFQVRFRF9BVF9BVFQsXG4gIElOUFVUX0ZJRUxEUyxcbiAgQ1JFQVRFX1JFU1VMVF9GSUVMRFMsXG4gIFVQREFURV9SRVNVTFRfRklFTERTLFxuICBQQVJTRV9PQkpFQ1RfRklFTERTLFxuICBQQVJTRV9PQkpFQ1QsXG4gIFNFU1NJT05fVE9LRU5fQVRULFxuICBSRUFEX1BSRUZFUkVOQ0UsXG4gIFJFQURfUFJFRkVSRU5DRV9BVFQsXG4gIElOQ0xVREVfUkVBRF9QUkVGRVJFTkNFX0FUVCxcbiAgU1VCUVVFUllfUkVBRF9QUkVGRVJFTkNFX0FUVCxcbiAgUkVBRF9PUFRJT05TX0lOUFVULFxuICBSRUFEX09QVElPTlNfQVRULFxuICBXSEVSRV9BVFQsXG4gIFNLSVBfQVRULFxuICBMSU1JVF9BVFQsXG4gIENPVU5UX0FUVCxcbiAgU0VBUkNIX0lOUFVULFxuICBURVhUX0lOUFVULFxuICBCT1hfSU5QVVQsXG4gIFdJVEhJTl9JTlBVVCxcbiAgQ0VOVEVSX1NQSEVSRV9JTlBVVCxcbiAgR0VPX1dJVEhJTl9JTlBVVCxcbiAgR0VPX0lOVEVSU0VDVFNfSU5QVVQsXG4gIGVxdWFsVG8sXG4gIG5vdEVxdWFsVG8sXG4gIGxlc3NUaGFuLFxuICBsZXNzVGhhbk9yRXF1YWxUbyxcbiAgZ3JlYXRlclRoYW4sXG4gIGdyZWF0ZXJUaGFuT3JFcXVhbFRvLFxuICBpbk9wLFxuICBub3RJbixcbiAgZXhpc3RzLFxuICBtYXRjaGVzUmVnZXgsXG4gIG9wdGlvbnMsXG4gIGluUXVlcnlLZXksXG4gIG5vdEluUXVlcnlLZXksXG4gIElEX1dIRVJFX0lOUFVULFxuICBTVFJJTkdfV0hFUkVfSU5QVVQsXG4gIE5VTUJFUl9XSEVSRV9JTlBVVCxcbiAgQk9PTEVBTl9XSEVSRV9JTlBVVCxcbiAgQVJSQVlfV0hFUkVfSU5QVVQsXG4gIEtFWV9WQUxVRV9JTlBVVCxcbiAgT0JKRUNUX1dIRVJFX0lOUFVULFxuICBEQVRFX1dIRVJFX0lOUFVULFxuICBCWVRFU19XSEVSRV9JTlBVVCxcbiAgRklMRV9XSEVSRV9JTlBVVCxcbiAgR0VPX1BPSU5UX1dIRVJFX0lOUFVULFxuICBQT0xZR09OX1dIRVJFX0lOUFVULFxuICBBUlJBWV9SRVNVTFQsXG4gIEVMRU1FTlQsXG4gIEFDTF9JTlBVVCxcbiAgVVNFUl9BQ0xfSU5QVVQsXG4gIFJPTEVfQUNMX0lOUFVULFxuICBQVUJMSUNfQUNMX0lOUFVULFxuICBBQ0wsXG4gIFVTRVJfQUNMLFxuICBST0xFX0FDTCxcbiAgUFVCTElDX0FDTCxcbiAgbG9hZCxcbiAgbG9hZEFycmF5UmVzdWx0LFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/defaultRelaySchema.js b/lib/GraphQL/loaders/defaultRelaySchema.js deleted file mode 100644 index 9cbe35176b..0000000000 --- a/lib/GraphQL/loaders/defaultRelaySchema.js +++ /dev/null @@ -1,71 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = exports.GLOBAL_ID_ATT = void 0; - -var _graphqlRelay = require("graphql-relay"); - -var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); - -var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); - -var objectsQueries = _interopRequireWildcard(require("../helpers/objectsQueries")); - -var _parseClassTypes = require("./parseClassTypes"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const GLOBAL_ID_ATT = { - description: 'This is the global id.', - type: defaultGraphQLTypes.OBJECT_ID -}; -exports.GLOBAL_ID_ATT = GLOBAL_ID_ATT; - -const load = parseGraphQLSchema => { - const { - nodeInterface, - nodeField - } = (0, _graphqlRelay.nodeDefinitions)(async (globalId, context, queryInfo) => { - try { - const { - type, - id - } = (0, _graphqlRelay.fromGlobalId)(globalId); - const { - config, - auth, - info - } = context; - const selectedFields = (0, _graphqlListFields.default)(queryInfo); - const { - keys, - include - } = (0, _parseClassTypes.extractKeysAndInclude)(selectedFields); - return _objectSpread({ - className: type - }, await objectsQueries.getObject(type, id, keys, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses)); - } catch (e) { - parseGraphQLSchema.handleError(e); - } - }, obj => { - return parseGraphQLSchema.parseClassTypes[obj.className].classGraphQLOutputType; - }); - parseGraphQLSchema.addGraphQLType(nodeInterface, true); - parseGraphQLSchema.relayNodeInterface = nodeInterface; - parseGraphQLSchema.addGraphQLQuery('node', nodeField, true); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZGVmYXVsdFJlbGF5U2NoZW1hLmpzIl0sIm5hbWVzIjpbIkdMT0JBTF9JRF9BVFQiLCJkZXNjcmlwdGlvbiIsInR5cGUiLCJkZWZhdWx0R3JhcGhRTFR5cGVzIiwiT0JKRUNUX0lEIiwibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsIm5vZGVJbnRlcmZhY2UiLCJub2RlRmllbGQiLCJnbG9iYWxJZCIsImNvbnRleHQiLCJxdWVyeUluZm8iLCJpZCIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwic2VsZWN0ZWRGaWVsZHMiLCJrZXlzIiwiaW5jbHVkZSIsImNsYXNzTmFtZSIsIm9iamVjdHNRdWVyaWVzIiwiZ2V0T2JqZWN0IiwidW5kZWZpbmVkIiwicGFyc2VDbGFzc2VzIiwiZSIsImhhbmRsZUVycm9yIiwib2JqIiwicGFyc2VDbGFzc1R5cGVzIiwiY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSIsImFkZEdyYXBoUUxUeXBlIiwicmVsYXlOb2RlSW50ZXJmYWNlIiwiYWRkR3JhcGhRTFF1ZXJ5Il0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FBRUEsTUFBTUEsYUFBYSxHQUFHO0FBQ3BCQyxFQUFBQSxXQUFXLEVBQUUsd0JBRE87QUFFcEJDLEVBQUFBLElBQUksRUFBRUMsbUJBQW1CLENBQUNDO0FBRk4sQ0FBdEI7OztBQUtBLE1BQU1DLElBQUksR0FBR0Msa0JBQWtCLElBQUk7QUFDakMsUUFBTTtBQUFFQyxJQUFBQSxhQUFGO0FBQWlCQyxJQUFBQTtBQUFqQixNQUErQixtQ0FDbkMsT0FBT0MsUUFBUCxFQUFpQkMsT0FBakIsRUFBMEJDLFNBQTFCLEtBQXdDO0FBQ3RDLFFBQUk7QUFDRixZQUFNO0FBQUVULFFBQUFBLElBQUY7QUFBUVUsUUFBQUE7QUFBUixVQUFlLGdDQUFhSCxRQUFiLENBQXJCO0FBQ0EsWUFBTTtBQUFFSSxRQUFBQSxNQUFGO0FBQVVDLFFBQUFBLElBQVY7QUFBZ0JDLFFBQUFBO0FBQWhCLFVBQXlCTCxPQUEvQjtBQUNBLFlBQU1NLGNBQWMsR0FBRyxnQ0FBY0wsU0FBZCxDQUF2QjtBQUVBLFlBQU07QUFBRU0sUUFBQUEsSUFBRjtBQUFRQyxRQUFBQTtBQUFSLFVBQW9CLDRDQUFzQkYsY0FBdEIsQ0FBMUI7QUFFQTtBQUNFRyxRQUFBQSxTQUFTLEVBQUVqQjtBQURiLFNBRU0sTUFBTWtCLGNBQWMsQ0FBQ0MsU0FBZixDQUNSbkIsSUFEUSxFQUVSVSxFQUZRLEVBR1JLLElBSFEsRUFJUkMsT0FKUSxFQUtSSSxTQUxRLEVBTVJBLFNBTlEsRUFPUlQsTUFQUSxFQVFSQyxJQVJRLEVBU1JDLElBVFEsRUFVUlQsa0JBQWtCLENBQUNpQixZQVZYLENBRlo7QUFlRCxLQXRCRCxDQXNCRSxPQUFPQyxDQUFQLEVBQVU7QUFDVmxCLE1BQUFBLGtCQUFrQixDQUFDbUIsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRixHQTNCa0MsRUE0Qm5DRSxHQUFHLElBQUk7QUFDTCxXQUFPcEIsa0JBQWtCLENBQUNxQixlQUFuQixDQUFtQ0QsR0FBRyxDQUFDUCxTQUF2QyxFQUFrRFMsc0JBQXpEO0FBQ0QsR0E5QmtDLENBQXJDO0FBaUNBdEIsRUFBQUEsa0JBQWtCLENBQUN1QixjQUFuQixDQUFrQ3RCLGFBQWxDLEVBQWlELElBQWpEO0FBQ0FELEVBQUFBLGtCQUFrQixDQUFDd0Isa0JBQW5CLEdBQXdDdkIsYUFBeEM7QUFDQUQsRUFBQUEsa0JBQWtCLENBQUN5QixlQUFuQixDQUFtQyxNQUFuQyxFQUEyQ3ZCLFNBQTNDLEVBQXNELElBQXREO0FBQ0QsQ0FyQ0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBub2RlRGVmaW5pdGlvbnMsIGZyb21HbG9iYWxJZCB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0IGdldEZpZWxkTmFtZXMgZnJvbSAnZ3JhcGhxbC1saXN0LWZpZWxkcyc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4vZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQgKiBhcyBvYmplY3RzUXVlcmllcyBmcm9tICcuLi9oZWxwZXJzL29iamVjdHNRdWVyaWVzJztcbmltcG9ydCB7IGV4dHJhY3RLZXlzQW5kSW5jbHVkZSB9IGZyb20gJy4vcGFyc2VDbGFzc1R5cGVzJztcblxuY29uc3QgR0xPQkFMX0lEX0FUVCA9IHtcbiAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBnbG9iYWwgaWQuJyxcbiAgdHlwZTogZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1RfSUQsXG59O1xuXG5jb25zdCBsb2FkID0gcGFyc2VHcmFwaFFMU2NoZW1hID0+IHtcbiAgY29uc3QgeyBub2RlSW50ZXJmYWNlLCBub2RlRmllbGQgfSA9IG5vZGVEZWZpbml0aW9ucyhcbiAgICBhc3luYyAoZ2xvYmFsSWQsIGNvbnRleHQsIHF1ZXJ5SW5mbykgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyB0eXBlLCBpZCB9ID0gZnJvbUdsb2JhbElkKGdsb2JhbElkKTtcbiAgICAgICAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkRmllbGRzID0gZ2V0RmllbGROYW1lcyhxdWVyeUluZm8pO1xuXG4gICAgICAgIGNvbnN0IHsga2V5cywgaW5jbHVkZSB9ID0gZXh0cmFjdEtleXNBbmRJbmNsdWRlKHNlbGVjdGVkRmllbGRzKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNsYXNzTmFtZTogdHlwZSxcbiAgICAgICAgICAuLi4oYXdhaXQgb2JqZWN0c1F1ZXJpZXMuZ2V0T2JqZWN0KFxuICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAga2V5cyxcbiAgICAgICAgICAgIGluY2x1ZGUsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzZXNcbiAgICAgICAgICApKSxcbiAgICAgICAgfTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgfVxuICAgIH0sXG4gICAgb2JqID0+IHtcbiAgICAgIHJldHVybiBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzW29iai5jbGFzc05hbWVdLmNsYXNzR3JhcGhRTE91dHB1dFR5cGU7XG4gICAgfVxuICApO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShub2RlSW50ZXJmYWNlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLnJlbGF5Tm9kZUludGVyZmFjZSA9IG5vZGVJbnRlcmZhY2U7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMUXVlcnkoJ25vZGUnLCBub2RlRmllbGQsIHRydWUpO1xufTtcblxuZXhwb3J0IHsgR0xPQkFMX0lEX0FUVCwgbG9hZCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/filesMutations.js b/lib/GraphQL/loaders/filesMutations.js deleted file mode 100644 index ada46e07be..0000000000 --- a/lib/GraphQL/loaders/filesMutations.js +++ /dev/null @@ -1,103 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.handleUpload = exports.load = void 0; - -var _graphql = require("graphql"); - -var _graphqlRelay = require("graphql-relay"); - -var _links = require("@graphql-tools/links"); - -var _node = _interopRequireDefault(require("parse/node")); - -var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); - -var _logger = _interopRequireDefault(require("../../logger")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const handleUpload = async (upload, config) => { - const { - createReadStream, - filename, - mimetype - } = await upload; - let data = null; - - if (createReadStream) { - const stream = createReadStream(); - data = await new Promise((resolve, reject) => { - const chunks = []; - stream.on('error', reject).on('data', chunk => chunks.push(chunk)).on('end', () => resolve(Buffer.concat(chunks))); - }); - } - - if (!data || !data.length) { - throw new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, 'Invalid file upload.'); - } - - if (filename.length > 128) { - throw new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename too long.'); - } - - if (!filename.match(/^[_a-zA-Z0-9][a-zA-Z0-9@\.\ ~_-]*$/)) { - throw new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename contains invalid characters.'); - } - - try { - return { - fileInfo: await config.filesController.createFile(config, filename, data, mimetype) - }; - } catch (e) { - _logger.default.error('Error creating a file: ', e); - - throw new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, `Could not store file: ${filename}.`); - } -}; - -exports.handleUpload = handleUpload; - -const load = parseGraphQLSchema => { - const createMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'CreateFile', - description: 'The createFile mutation can be used to create and upload a new file.', - inputFields: { - upload: { - description: 'This is the new file to be created and uploaded.', - type: new _graphql.GraphQLNonNull(_links.GraphQLUpload) - } - }, - outputFields: { - fileInfo: { - description: 'This is the created file info.', - type: new _graphql.GraphQLNonNull(defaultGraphQLTypes.FILE_INFO) - } - }, - mutateAndGetPayload: async (args, context) => { - try { - const { - upload - } = args; - const { - config - } = context; - return handleUpload(upload, config); - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(createMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(createMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('createFile', createMutation, true, true); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZmlsZXNNdXRhdGlvbnMuanMiXSwibmFtZXMiOlsiaGFuZGxlVXBsb2FkIiwidXBsb2FkIiwiY29uZmlnIiwiY3JlYXRlUmVhZFN0cmVhbSIsImZpbGVuYW1lIiwibWltZXR5cGUiLCJkYXRhIiwic3RyZWFtIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJjaHVua3MiLCJvbiIsImNodW5rIiwicHVzaCIsIkJ1ZmZlciIsImNvbmNhdCIsImxlbmd0aCIsIlBhcnNlIiwiRXJyb3IiLCJGSUxFX1NBVkVfRVJST1IiLCJJTlZBTElEX0ZJTEVfTkFNRSIsIm1hdGNoIiwiZmlsZUluZm8iLCJmaWxlc0NvbnRyb2xsZXIiLCJjcmVhdGVGaWxlIiwiZSIsImxvZ2dlciIsImVycm9yIiwibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsImNyZWF0ZU11dGF0aW9uIiwibmFtZSIsImRlc2NyaXB0aW9uIiwiaW5wdXRGaWVsZHMiLCJ0eXBlIiwiR3JhcGhRTE5vbk51bGwiLCJHcmFwaFFMVXBsb2FkIiwib3V0cHV0RmllbGRzIiwiZGVmYXVsdEdyYXBoUUxUeXBlcyIsIkZJTEVfSU5GTyIsIm11dGF0ZUFuZEdldFBheWxvYWQiLCJhcmdzIiwiY29udGV4dCIsImhhbmRsZUVycm9yIiwiYWRkR3JhcGhRTFR5cGUiLCJpbnB1dCIsIm9mVHlwZSIsImFkZEdyYXBoUUxNdXRhdGlvbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVBLE1BQU1BLFlBQVksR0FBRyxPQUFPQyxNQUFQLEVBQWVDLE1BQWYsS0FBMEI7QUFDN0MsUUFBTTtBQUFFQyxJQUFBQSxnQkFBRjtBQUFvQkMsSUFBQUEsUUFBcEI7QUFBOEJDLElBQUFBO0FBQTlCLE1BQTJDLE1BQU1KLE1BQXZEO0FBQ0EsTUFBSUssSUFBSSxHQUFHLElBQVg7O0FBQ0EsTUFBSUgsZ0JBQUos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QUEwQkFJLEVBQUFBLGtCQUFrQixDQUFDZSxjQUFuQixDQUFrQ2QsY0FBYyxDQUFDVyxJQUFmLENBQW9CSSxLQUFwQixDQUEwQlgsSUFBMUIsQ0FBK0JZLE1BQWpFLEVBQXlFLElBQXpFLEVBQStFLElBQS9FO0FBQ0FqQixFQUFBQSxrQkFBa0IsQ0FBQ2UsY0FBbkIsQ0FBa0NkLGNBQWMsQ0FBQ0ksSUFBakQsRUFBdUQsSUFBdkQsRUFBNkQsSUFBN0Q7QUFDQUwsRUFBQUEsa0JBQWtCLENBQUNrQixrQkFBbkIsQ0FBc0MsWUFBdEMsRUFBb0RqQixjQUFwRCxFQUFvRSxJQUFwRSxFQUEwRSxJQUExRTtBQUNELENBOUJEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgR3JhcGhRTE5vbk51bGwgfSBmcm9tICdncmFwaHFsJztcbmltcG9ydCB7IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQgfSBmcm9tICdncmFwaHFsLXJlbGF5JztcbmltcG9ydCB7IEdyYXBoUUxVcGxvYWQgfSBmcm9tICdAZ3JhcGhxbC10b29scy9saW5rcyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4vZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uLy4uL2xvZ2dlcic7XG5cbmNvbnN0IGhhbmRsZVVwbG9hZCA9IGFzeW5jICh1cGxvYWQsIGNvbmZpZykgPT4ge1xuICBjb25zdCB7IGNyZWF0ZVJlYWRTdHJlYW0sIGZpbGVuYW1lLCBtaW1ldHlwZSB9ID0gYXdhaXQgdXBsb2FkO1xuICBsZXQgZGF0YSA9IG51bGw7XG4gIGlmIChjcmVhdGVSZWFkU3RyZWFtKSB7XG4gICAgY29uc3Qgc3RyZWFtID0gY3JlYXRlUmVhZFN0cmVhbSgpO1xuICAgIGRhdGEgPSBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBjaHVua3MgPSBbXTtcbiAgICAgIHN0cmVhbVxuICAgICAgICAub24oJ2Vycm9yJywgcmVqZWN0KVxuICAgICAgICAub24oJ2RhdGEnLCBjaHVuayA9PiBjaHVua3MucHVzaChjaHVuaykpXG4gICAgICAgIC5vbignZW5kJywgKCkgPT4gcmVzb2x2ZShCdWZmZXIuY29uY2F0KGNodW5rcykpKTtcbiAgICB9KTtcbiAgfVxuXG4gIGlmICghZGF0YSB8fCAhZGF0YS5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRklMRV9TQVZFX0VSUk9SLCAnSW52YWxpZCBmaWxlIHVwbG9hZC4nKTtcbiAgfVxuXG4gIGlmIChmaWxlbmFtZS5sZW5ndGggPiAxMjgpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9GSUxFX05BTUUsICdGaWxlbmFtZSB0b28gbG9uZy4nKTtcbiAgfVxuXG4gIGlmICghZmlsZW5hbWUubWF0Y2goL15bX2EtekEtWjAtOV1bYS16QS1aMC05QFxcLlxcIH5fLV0qJC8pKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfRklMRV9OQU1FLCAnRmlsZW5hbWUgY29udGFpbnMgaW52YWxpZCBjaGFyYWN0ZXJzLicpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICByZXR1cm4ge1xuICAgICAgZmlsZUluZm86IGF3YWl0IGNvbmZpZy5maWxlc0NvbnRyb2xsZXIuY3JlYXRlRmlsZShjb25maWcsIGZpbGVuYW1lLCBkYXRhLCBtaW1ldHlwZSksXG4gICAgfTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGxvZ2dlci5lcnJvcignRXJyb3IgY3JlYXRpbmcgYSBmaWxlOiAnLCBlKTtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRklMRV9TQVZFX0VSUk9SLCBgQ291bGQgbm90IHN0b3JlIGZpbGU6ICR7ZmlsZW5hbWV9LmApO1xuICB9XG59O1xuXG5jb25zdCBsb2FkID0gcGFyc2VHcmFwaFFMU2NoZW1hID0+IHtcbiAgY29uc3QgY3JlYXRlTXV0YXRpb24gPSBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkKHtcbiAgICBuYW1lOiAnQ3JlYXRlRmlsZScsXG4gICAgZGVzY3JpcHRpb246ICdUaGUgY3JlYXRlRmlsZSBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBjcmVhdGUgYW5kIHVwbG9hZCBhIG5ldyBmaWxlLicsXG4gICAgaW5wdXRGaWVsZHM6IHtcbiAgICAgIHVwbG9hZDoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIG5ldyBmaWxlIHRvIGJlIGNyZWF0ZWQgYW5kIHVwbG9hZGVkLicsXG4gICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMVXBsb2FkKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgIGZpbGVJbmZvOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgY3JlYXRlZCBmaWxlIGluZm8uJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKGRlZmF1bHRHcmFwaFFMVHlwZXMuRklMRV9JTkZPKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBtdXRhdGVBbmRHZXRQYXlsb2FkOiBhc3luYyAoYXJncywgY29udGV4dCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyB1cGxvYWQgfSA9IGFyZ3M7XG4gICAgICAgIGNvbnN0IHsgY29uZmlnIH0gPSBjb250ZXh0O1xuICAgICAgICByZXR1cm4gaGFuZGxlVXBsb2FkKHVwbG9hZCwgY29uZmlnKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjcmVhdGVNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNyZWF0ZU11dGF0aW9uLnR5cGUsIHRydWUsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTE11dGF0aW9uKCdjcmVhdGVGaWxlJywgY3JlYXRlTXV0YXRpb24sIHRydWUsIHRydWUpO1xufTtcblxuZXhwb3J0IHsgbG9hZCwgaGFuZGxlVXBsb2FkIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/loaders/functionsMutations.js b/lib/GraphQL/loaders/functionsMutations.js deleted file mode 100644 index e8246ee21a..0000000000 --- a/lib/GraphQL/loaders/functionsMutations.js +++ /dev/null @@ -1,90 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = void 0; - -var _graphql = require("graphql"); - -var _graphqlRelay = require("graphql-relay"); - -var _FunctionsRouter = require("../../Routers/FunctionsRouter"); - -var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const load = parseGraphQLSchema => { - if (parseGraphQLSchema.functionNames.length > 0) { - const cloudCodeFunctionEnum = parseGraphQLSchema.addGraphQLType(new _graphql.GraphQLEnumType({ - name: 'CloudCodeFunction', - description: 'The CloudCodeFunction enum type contains a list of all available cloud code functions.', - values: parseGraphQLSchema.functionNames.reduce((values, functionName) => _objectSpread(_objectSpread({}, values), {}, { - [functionName]: { - value: functionName - } - }), {}) - }), true, true); - const callCloudCodeMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'CallCloudCode', - description: 'The callCloudCode mutation can be used to invoke a cloud code function.', - inputFields: { - functionName: { - description: 'This is the function to be called.', - type: new _graphql.GraphQLNonNull(cloudCodeFunctionEnum) - }, - params: { - description: 'These are the params to be passed to the function.', - type: defaultGraphQLTypes.OBJECT - } - }, - outputFields: { - result: { - description: 'This is the result value of the cloud code function execution.', - type: defaultGraphQLTypes.ANY - } - }, - mutateAndGetPayload: async (args, context) => { - try { - const { - functionName, - params - } = args; - const { - config, - auth, - info - } = context; - return { - result: (await _FunctionsRouter.FunctionsRouter.handleCloudFunction({ - params: { - functionName - }, - config, - auth, - info, - body: params - })).response.result - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(callCloudCodeMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(callCloudCodeMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('callCloudCode', callCloudCodeMutation, true, true); - } -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvZnVuY3Rpb25zTXV0YXRpb25zLmpzIl0sIm5hbWVzIjpbImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJmdW5jdGlvbk5hbWVzIiwibGVuZ3RoIiwiY2xvdWRDb2RlRnVuY3Rpb25FbnVtIiwiYWRkR3JhcGhRTFR5cGUiLCJHcmFwaFFMRW51bVR5cGUiLCJuYW1lIiwiZGVzY3JpcHRpb24iLCJ2YWx1ZXMiLCJyZWR1Y2UiLCJmdW5jdGlvbk5hbWUiLCJ2YWx1ZSIsImNhbGxDbG91ZENvZGVNdXRhdGlvbiIsImlucHV0RmllbGRzIiwidHlwZSIsIkdyYXBoUUxOb25OdWxsIiwicGFyYW1zIiwiZGVmYXVsdEdyYXBoUUxUeXBlcyIsIk9CSkVDVCIsIm91dHB1dEZpZWxkcyIsInJlc3VsdCIsIkFOWSIsIm11dGF0ZUFuZEdldFBheWxvYWQiLCJhcmdzIiwiY29udGV4dCIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwiRnVuY3Rpb25zUm91dGVyIiwiaGFuZGxlQ2xvdWRGdW5jdGlvbiIsImJvZHkiLCJyZXNwb25zZSIsImUiLCJoYW5kbGVFcnJvciIsImlucHV0Iiwib2ZUeXBlIiwiYWRkR3JhcGhRTE11dGF0aW9uIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7OztBQUVBLE1BQU1BLElBQUksR0FBR0Msa0JBQWtCLElBQUk7QUFDakMsTUFBSUEsa0JBQWtCLENBQUNDLGFBQW5CLENBQWlDQyxNQUFqQyxHQUEwQyxDQUE5QyxFQUFpRDtBQUMvQyxVQUFNQyxxQkFBcUIsR0FBR0gsa0JBQWtCLENBQUNJLGNBQW5CLENBQzVCLElBQUlDLHdCQUFKLENBQW9CO0FBQ2xCQyxNQUFBQSxJQUFJLEVBQUUsbUJBRFk7QUFFbEJDLE1BQUFBLFdBQVcsRUFDVCx3RkFIZ0I7QUFJbEJDLE1BQUFBLE1BQU0sRUFBRVIsa0JBQWtCLENBQUNDLGFBQW5CLENBQWlDUSxNQUFqQyxDQUNOLENBQUNELE1BQUQsRUFBU0UsWUFBVCxxQ0FDS0YsTUFETDtBQUVFLFNBQUNFLFlBQUQsR0FBZ0I7QUFBRUMsVUFBQUEsS0FBSyxFQUFFRDtBQUFUO0FBRmxCLFFBRE0sRUFLTixFQUxNO0FBSlUsS0FBcEIsQ0FENEIsRUFhNUIsSUFiNEIsRUFjNUIsSUFkNEIsQ0FBOUI7QUFpQkEsVUFBTUUscUJBQXFCLEdBQUcsZ0RBQTZCO0FBQ3pETixNQUFBQSxJQUFJLEVBQUUsZUFEbUQ7QUFFekRDLE1BQUFBLFdBQVcsRUFBRSx5RUFGNEM7QUFHekRNLE1BQUFBLFdBQVcsRUFBRTtBQUNYSCxRQUFBQSxZQUFZLEVBQUU7QUFDWkgsVUFBQUEsV0FBVyxFQUFFLG9DQUREO0FBRVpPLFVBQUFBLElBQUksRUFBRSxJQUFJQyx1QkFBSixDQUFtQloscUJBQW5CO0FBRk0sU0FESDtBQUtYYSxRQUFBQSxNQUFNLEVBQUU7QUFDTlQsVUFBQUEsV0FBVyxFQUFFLG9EQURQO0FBRU5PLFVBQUFBLElBQUksRUFBRUcsbUJBQW1CLENBQUNDO0FBRnBCO0FBTEcsT0FINEM7QUFhekRDLE1BQUFBLFlBQVksRUFBRTtBQUNaQyxRQUFBQSxNQUFNLEVBQUU7QUFDTmIsVUFBQUEsV0FBVyxFQUFFLGdFQURQO0FBRU5PLFVBQUFBLElBQUksRUFBRUcsbUJBQW1CLENBQUNJO0FBRnBCO0FBREksT0FiMkM7QUFtQnpEQyxNQUFBQSxtQkFBbUIsRUFBRSxPQUFPQyxJQUFQLEVBQWFDLE9BQWIsS0FBeUI7QUFDNUMsWUFBSTtBQUNGLGdCQUFNO0FBQUVkLFlBQUFBLFlBQUY7QUFBZ0JNLFlBQUFBO0FBQWhCLGNBQTJCTyxJQUFqQztBQUNBLGdCQUFNO0FBQUVFLFlBQUFBLE1BQUY7QUFBVUMsWUFBQUEsSUFBVjtBQUFnQkMsWUFBQUE7QUFBaEIsY0FBeUJILE9BQS9CO0FBRUEsaUJBQU87QUFDTEosWUFBQUEsTUFBTSxFQUFFLENBQ04sTUFBTVEsaUNBQWdCQyxtQkFBaEIsQ0FBb0M7QUFDeENiLGNBQUFBLE1BQU0sRUFBRTtBQUNOTixnQkFBQUE7QUFETSxlQURnQztBQUl4Q2UsY0FBQUEsTUFKd0M7QUFLeENDLGNBQUFBLElBTHdDO0FBTXhDQyxjQUFBQSxJQU53QztBQU94Q0csY0FBQUEsSUFBSSxFQUFFZDtBQVBrQyxhQUFwQyxDQURBLEVBVU5lLFFBVk0sQ0FVR1g7QUFYTixXQUFQO0FBYUQsU0FqQkQsQ0FpQkUsT0FBT1ksQ0FBUCxFQUFVO0FBQ1ZoQyxVQUFBQSxrQkFBa0IsQ0FBQ2lDLFdBQW5CLENBQStCRCxDQUEvQjtBQUNEO0FBQ0Y7QUF4Q3dELEtBQTdCLENBQTlCO0FBMkNBaEMsSUFBQUEsa0JBQWtCLENBQUNJLGNBQW5CLENBQWtDUSxxQkFBcUIsQ0FBQ1csSUFBdEIsQ0FBMkJXLEtBQTNCLENBQWlDcEIsSUFBakMsQ0FBc0NxQixNQUF4RSxFQUFnRixJQUFoRixFQUFzRixJQUF0RjtBQUNBbkMsSUFBQUEsa0JBQWtCLENBQUNJLGNBQW5CLENBQWtDUSxxQkFBcUIsQ0FBQ0UsSUFBeEQsRUFBOEQsSUFBOUQsRUFBb0UsSUFBcEU7QUFDQWQsSUFBQUEsa0JBQWtCLENBQUNvQyxrQkFBbkIsQ0FBc0MsZUFBdEMsRUFBdUR4QixxQkFBdkQsRUFBOEUsSUFBOUUsRUFBb0YsSUFBcEY7QUFDRDtBQUNGLENBbEVEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgR3JhcGhRTE5vbk51bGwsIEdyYXBoUUxFbnVtVHlwZSB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0IHsgRnVuY3Rpb25zUm91dGVyIH0gZnJvbSAnLi4vLi4vUm91dGVycy9GdW5jdGlvbnNSb3V0ZXInO1xuaW1wb3J0ICogYXMgZGVmYXVsdEdyYXBoUUxUeXBlcyBmcm9tICcuL2RlZmF1bHRHcmFwaFFMVHlwZXMnO1xuXG5jb25zdCBsb2FkID0gcGFyc2VHcmFwaFFMU2NoZW1hID0+IHtcbiAgaWYgKHBhcnNlR3JhcGhRTFNjaGVtYS5mdW5jdGlvbk5hbWVzLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBjbG91ZENvZGVGdW5jdGlvbkVudW0gPSBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoXG4gICAgICBuZXcgR3JhcGhRTEVudW1UeXBlKHtcbiAgICAgICAgbmFtZTogJ0Nsb3VkQ29kZUZ1bmN0aW9uJyxcbiAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgJ1RoZSBDbG91ZENvZGVGdW5jdGlvbiBlbnVtIHR5cGUgY29udGFpbnMgYSBsaXN0IG9mIGFsbCBhdmFpbGFibGUgY2xvdWQgY29kZSBmdW5jdGlvbnMuJyxcbiAgICAgICAgdmFsdWVzOiBwYXJzZUdyYXBoUUxTY2hlbWEuZnVuY3Rpb25OYW1lcy5yZWR1Y2UoXG4gICAgICAgICAgKHZhbHVlcywgZnVuY3Rpb25OYW1lKSA9PiAoe1xuICAgICAgICAgICAgLi4udmFsdWVzLFxuICAgICAgICAgICAgW2Z1bmN0aW9uTmFtZV06IHsgdmFsdWU6IGZ1bmN0aW9uTmFtZSB9LFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIHt9XG4gICAgICAgICksXG4gICAgICB9KSxcbiAgICAgIHRydWUsXG4gICAgICB0cnVlXG4gICAgKTtcblxuICAgIGNvbnN0IGNhbGxDbG91ZENvZGVNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgICAgbmFtZTogJ0NhbGxDbG91ZENvZGUnLFxuICAgICAgZGVzY3JpcHRpb246ICdUaGUgY2FsbENsb3VkQ29kZSBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBpbnZva2UgYSBjbG91ZCBjb2RlIGZ1bmN0aW9uLicsXG4gICAgICBpbnB1dEZpZWxkczoge1xuICAgICAgICBmdW5jdGlvbk5hbWU6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZC4nLFxuICAgICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChjbG91ZENvZGVGdW5jdGlvbkVudW0pLFxuICAgICAgICB9LFxuICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1RoZXNlIGFyZSB0aGUgcGFyYW1zIHRvIGJlIHBhc3NlZCB0byB0aGUgZnVuY3Rpb24uJyxcbiAgICAgICAgICB0eXBlOiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgICAgcmVzdWx0OiB7XG4gICAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSByZXN1bHQgdmFsdWUgb2YgdGhlIGNsb3VkIGNvZGUgZnVuY3Rpb24gZXhlY3V0aW9uLicsXG4gICAgICAgICAgdHlwZTogZGVmYXVsdEdyYXBoUUxUeXBlcy5BTlksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgbXV0YXRlQW5kR2V0UGF5bG9hZDogYXN5bmMgKGFyZ3MsIGNvbnRleHQpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB7IGZ1bmN0aW9uTmFtZSwgcGFyYW1zIH0gPSBhcmdzO1xuICAgICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJlc3VsdDogKFxuICAgICAgICAgICAgICBhd2FpdCBGdW5jdGlvbnNSb3V0ZXIuaGFuZGxlQ2xvdWRGdW5jdGlvbih7XG4gICAgICAgICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICAgICAgICBmdW5jdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgICAgICBpbmZvLFxuICAgICAgICAgICAgICAgIGJvZHk6IHBhcmFtcyxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICkucmVzcG9uc2UucmVzdWx0LFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoY2FsbENsb3VkQ29kZU11dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGUsIHRydWUsIHRydWUpO1xuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjYWxsQ2xvdWRDb2RlTXV0YXRpb24udHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbignY2FsbENsb3VkQ29kZScsIGNhbGxDbG91ZENvZGVNdXRhdGlvbiwgdHJ1ZSwgdHJ1ZSk7XG4gIH1cbn07XG5cbmV4cG9ydCB7IGxvYWQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/parseClassMutations.js b/lib/GraphQL/loaders/parseClassMutations.js deleted file mode 100644 index 56441fe1c2..0000000000 --- a/lib/GraphQL/loaders/parseClassMutations.js +++ /dev/null @@ -1,288 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = void 0; - -var _graphql = require("graphql"); - -var _graphqlRelay = require("graphql-relay"); - -var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); - -var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); - -var _parseGraphQLUtils = require("../parseGraphQLUtils"); - -var objectsMutations = _interopRequireWildcard(require("../helpers/objectsMutations")); - -var objectsQueries = _interopRequireWildcard(require("../helpers/objectsQueries")); - -var _ParseGraphQLController = require("../../Controllers/ParseGraphQLController"); - -var _className = require("../transformers/className"); - -var _mutation = require("../transformers/mutation"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const getOnlyRequiredFields = (updatedFields, selectedFieldsString, includedFieldsString, nativeObjectFields) => { - const includedFields = includedFieldsString ? includedFieldsString.split(',') : []; - const selectedFields = selectedFieldsString ? selectedFieldsString.split(',') : []; - const missingFields = selectedFields.filter(field => !nativeObjectFields.includes(field) || includedFields.includes(field)).join(','); - - if (!missingFields.length) { - return { - needGet: false, - keys: '' - }; - } else { - return { - needGet: true, - keys: missingFields - }; - } -}; - -const load = function (parseGraphQLSchema, parseClass, parseClassConfig) { - const className = parseClass.className; - const graphQLClassName = (0, _className.transformClassNameToGraphQL)(className); - const getGraphQLQueryName = graphQLClassName.charAt(0).toLowerCase() + graphQLClassName.slice(1); - const { - create: isCreateEnabled = true, - update: isUpdateEnabled = true, - destroy: isDestroyEnabled = true, - createAlias = '', - updateAlias = '', - destroyAlias = '' - } = (0, _parseGraphQLUtils.getParseClassMutationConfig)(parseClassConfig); - const { - classGraphQLCreateType, - classGraphQLUpdateType, - classGraphQLOutputType - } = parseGraphQLSchema.parseClassTypes[className]; - - if (isCreateEnabled) { - const createGraphQLMutationName = createAlias || `create${graphQLClassName}`; - const createGraphQLMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: `Create${graphQLClassName}`, - description: `The ${createGraphQLMutationName} mutation can be used to create a new object of the ${graphQLClassName} class.`, - inputFields: { - fields: { - description: 'These are the fields that will be used to create the new object.', - type: classGraphQLCreateType || defaultGraphQLTypes.OBJECT - } - }, - outputFields: { - [getGraphQLQueryName]: { - description: 'This is the created object.', - type: new _graphql.GraphQLNonNull(classGraphQLOutputType || defaultGraphQLTypes.OBJECT) - } - }, - mutateAndGetPayload: async (args, context, mutationInfo) => { - try { - let { - fields - } = args; - if (!fields) fields = {}; - const { - config, - auth, - info - } = context; - const parseFields = await (0, _mutation.transformTypes)('create', fields, { - className, - parseGraphQLSchema, - req: { - config, - auth, - info - } - }); - const createdObject = await objectsMutations.createObject(className, parseFields, config, auth, info); - const selectedFields = (0, _graphqlListFields.default)(mutationInfo).filter(field => field.startsWith(`${getGraphQLQueryName}.`)).map(field => field.replace(`${getGraphQLQueryName}.`, '')); - const { - keys, - include - } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields); - const { - keys: requiredKeys, - needGet - } = getOnlyRequiredFields(fields, keys, include, ['id', 'objectId', 'createdAt', 'updatedAt']); - const needToGetAllKeys = objectsQueries.needToGetAllKeys(parseClass.fields, keys, parseGraphQLSchema.parseClasses); - let optimizedObject = {}; - - if (needGet && !needToGetAllKeys) { - optimizedObject = await objectsQueries.getObject(className, createdObject.objectId, requiredKeys, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); - } else if (needToGetAllKeys) { - optimizedObject = await objectsQueries.getObject(className, createdObject.objectId, undefined, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); - } - - return { - [getGraphQLQueryName]: _objectSpread(_objectSpread(_objectSpread({}, createdObject), {}, { - updatedAt: createdObject.createdAt - }, parseFields), optimizedObject) - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - - if (parseGraphQLSchema.addGraphQLType(createGraphQLMutation.args.input.type.ofType) && parseGraphQLSchema.addGraphQLType(createGraphQLMutation.type)) { - parseGraphQLSchema.addGraphQLMutation(createGraphQLMutationName, createGraphQLMutation); - } - } - - if (isUpdateEnabled) { - const updateGraphQLMutationName = updateAlias || `update${graphQLClassName}`; - const updateGraphQLMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: `Update${graphQLClassName}`, - description: `The ${updateGraphQLMutationName} mutation can be used to update an object of the ${graphQLClassName} class.`, - inputFields: { - id: defaultGraphQLTypes.GLOBAL_OR_OBJECT_ID_ATT, - fields: { - description: 'These are the fields that will be used to update the object.', - type: classGraphQLUpdateType || defaultGraphQLTypes.OBJECT - } - }, - outputFields: { - [getGraphQLQueryName]: { - description: 'This is the updated object.', - type: new _graphql.GraphQLNonNull(classGraphQLOutputType || defaultGraphQLTypes.OBJECT) - } - }, - mutateAndGetPayload: async (args, context, mutationInfo) => { - try { - let { - id, - fields - } = args; - if (!fields) fields = {}; - const { - config, - auth, - info - } = context; - const globalIdObject = (0, _graphqlRelay.fromGlobalId)(id); - - if (globalIdObject.type === className) { - id = globalIdObject.id; - } - - const parseFields = await (0, _mutation.transformTypes)('update', fields, { - className, - parseGraphQLSchema, - req: { - config, - auth, - info - } - }); - const updatedObject = await objectsMutations.updateObject(className, id, parseFields, config, auth, info); - const selectedFields = (0, _graphqlListFields.default)(mutationInfo).filter(field => field.startsWith(`${getGraphQLQueryName}.`)).map(field => field.replace(`${getGraphQLQueryName}.`, '')); - const { - keys, - include - } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields); - const { - keys: requiredKeys, - needGet - } = getOnlyRequiredFields(fields, keys, include, ['id', 'objectId', 'updatedAt']); - const needToGetAllKeys = objectsQueries.needToGetAllKeys(parseClass.fields, keys, parseGraphQLSchema.parseClasses); - let optimizedObject = {}; - - if (needGet && !needToGetAllKeys) { - optimizedObject = await objectsQueries.getObject(className, id, requiredKeys, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); - } else if (needToGetAllKeys) { - optimizedObject = await objectsQueries.getObject(className, id, undefined, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); - } - - return { - [getGraphQLQueryName]: _objectSpread(_objectSpread(_objectSpread({ - objectId: id - }, updatedObject), parseFields), optimizedObject) - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - - if (parseGraphQLSchema.addGraphQLType(updateGraphQLMutation.args.input.type.ofType) && parseGraphQLSchema.addGraphQLType(updateGraphQLMutation.type)) { - parseGraphQLSchema.addGraphQLMutation(updateGraphQLMutationName, updateGraphQLMutation); - } - } - - if (isDestroyEnabled) { - const deleteGraphQLMutationName = destroyAlias || `delete${graphQLClassName}`; - const deleteGraphQLMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: `Delete${graphQLClassName}`, - description: `The ${deleteGraphQLMutationName} mutation can be used to delete an object of the ${graphQLClassName} class.`, - inputFields: { - id: defaultGraphQLTypes.GLOBAL_OR_OBJECT_ID_ATT - }, - outputFields: { - [getGraphQLQueryName]: { - description: 'This is the deleted object.', - type: new _graphql.GraphQLNonNull(classGraphQLOutputType || defaultGraphQLTypes.OBJECT) - } - }, - mutateAndGetPayload: async (args, context, mutationInfo) => { - try { - let { - id - } = args; - const { - config, - auth, - info - } = context; - const globalIdObject = (0, _graphqlRelay.fromGlobalId)(id); - - if (globalIdObject.type === className) { - id = globalIdObject.id; - } - - const selectedFields = (0, _graphqlListFields.default)(mutationInfo).filter(field => field.startsWith(`${getGraphQLQueryName}.`)).map(field => field.replace(`${getGraphQLQueryName}.`, '')); - const { - keys, - include - } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields); - let optimizedObject = {}; - - if (keys && keys.split(',').filter(key => !['id', 'objectId'].includes(key)).length > 0) { - optimizedObject = await objectsQueries.getObject(className, id, keys, include, undefined, undefined, config, auth, info, parseGraphQLSchema.parseClasses); - } - - await objectsMutations.deleteObject(className, id, config, auth, info); - return { - [getGraphQLQueryName]: _objectSpread({ - objectId: id - }, optimizedObject) - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - - if (parseGraphQLSchema.addGraphQLType(deleteGraphQLMutation.args.input.type.ofType) && parseGraphQLSchema.addGraphQLType(deleteGraphQLMutation.type)) { - parseGraphQLSchema.addGraphQLMutation(deleteGraphQLMutationName, deleteGraphQLMutation); - } - } -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvcGFyc2VDbGFzc011dGF0aW9ucy5qcyJdLCJuYW1lcyI6WyJnZXRPbmx5UmVxdWlyZWRGaWVsZHMiLCJ1cGRhdGVkRmllbGRzIiwic2VsZWN0ZWRGaWVsZHNTdHJpbmciLCJpbmNsdWRlZEZpZWxkc1N0cmluZyIsIm5hdGl2ZU9iamVjdEZpZWxkcyIsImluY2x1ZGVkRmllbGRzIiwic3BsaXQiLCJzZWxlY3RlZEZpZWxkcyIsIm1pc3NpbmdGaWVsZHMiLCJmaWx0ZXIiLCJmaWVsZCIsImluY2x1ZGVzIiwiam9pbiIsImxlbmd0aCIsIm5lZWRHZXQiLCJrZXlzIiwibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsInBhcnNlQ2xhc3MiLCJwYXJzZUNsYXNzQ29uZmlnIiwiY2xhc3NOYW1lIiwiZ3JhcGhRTENsYXNzTmFtZSIsImdldEdyYXBoUUxRdWVyeU5hbWUiLCJjaGFyQXQiLCJ0b0xvd2VyQ2FzZSIsInNsaWNlIiwiY3JlYXRlIiwiaXNDcmVhdGVFbmFibGVkIiwidXBkYXRlIiwiaXNVcGRhdGVFbmFibGVkIiwiZGVzdHJveSIsImlzRGVzdHJveUVuYWJsZWQiLCJjcmVhdGVBbGlhcyIsInVwZGF0ZUFsaWFzIiwiZGVzdHJveUFsaWFzIiwiY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSIsImNsYXNzR3JhcGhRTFVwZGF0ZVR5cGUiLCJjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIiwicGFyc2VDbGFzc1R5cGVzIiwiY3JlYXRlR3JhcGhRTE11dGF0aW9uTmFtZSIsImNyZWF0ZUdyYXBoUUxNdXRhdGlvbiIsIm5hbWUiLCJkZXNjcmlwdGlvbiIsImlucHV0RmllbGRzIiwiZmllbGRzIiwidHlwZSIsImRlZmF1bHRHcmFwaFFMVHlwZXMiLCJPQkpFQ1QiLCJvdXRwdXRGaWVsZHMiLCJHcmFwaFFMTm9uTnVsbCIsIm11dGF0ZUFuZEdldFBheWxvYWQiLCJhcmdzIiwiY29udGV4dCIsIm11dGF0aW9uSW5mbyIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwicGFyc2VGaWVsZHMiLCJyZXEiLCJjcmVhdGVkT2JqZWN0Iiwib2JqZWN0c011dGF0aW9ucyIsImNyZWF0ZU9iamVjdCIsInN0YXJ0c1dpdGgiLCJtYXAiLCJyZXBsYWNlIiwiaW5jbHVkZSIsInJlcXVpcmVkS2V5cyIsIm5lZWRUb0dldEFsbEtleXMiLCJvYmplY3RzUXVlcmllcyIsInBhcnNlQ2xhc3NlcyIsIm9wdGltaXplZE9iamVjdCIsImdldE9iamVjdCIsIm9iamVjdElkIiwidW5kZWZpbmVkIiwidXBkYXRlZEF0IiwiY3JlYXRlZEF0IiwiZSIsImhhbmRsZUVycm9yIiwiYWRkR3JhcGhRTFR5cGUiLCJpbnB1dCIsIm9mVHlwZSIsImFkZEdyYXBoUUxNdXRhdGlvbiIsInVwZGF0ZUdyYXBoUUxNdXRhdGlvbk5hbWUiLCJ1cGRhdGVHcmFwaFFMTXV0YXRpb24iLCJpZCIsIkdMT0JBTF9PUl9PQkpFQ1RfSURfQVRUIiwiZ2xvYmFsSWRPYmplY3QiLCJ1cGRhdGVkT2JqZWN0IiwidXBkYXRlT2JqZWN0IiwiZGVsZXRlR3JhcGhRTE11dGF0aW9uTmFtZSIsImRlbGV0ZUdyYXBoUUxNdXRhdGlvbiIsImtleSIsImRlbGV0ZU9iamVjdCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7Ozs7Ozs7OztBQUVBLE1BQU1BLHFCQUFxQixHQUFHLENBQzVCQyxhQUQ0QixFQUU1QkMsb0JBRjRCLEVBRzVCQyxvQkFINEIsRUFJNUJDLGtCQUo0QixLQUt6QjtBQUNILFFBQU1DLGNBQWMsR0FBR0Ysb0JBQW9CLEdBQUdBLG9CQUFvQixDQUFDRyxLQUFyQixDQUEyQixHQUEzQixDQUFILEdBQXFDLEVBQWhGO0FBQ0EsUUFBTUMsY0FBYyxHQUFHTCxvQkFBb0IsR0FBR0Esb0JBQW9CLENBQUNJLEtBQXJCLENBQTJCLEdBQTNCLENBQUgsR0FBcUMsRUFBaEY7QUFDQSxRQUFN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RCxDQW9DRSxPQUFPTSxDQUFQLEVBQVU7QUFDVjNELFVBQUFBLGtCQUFrQixDQUFDNEQsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRjtBQXBEd0QsS0FBN0IsQ0FBOUI7O0FBdURBLFFBQ0UzRCxrQkFBa0IsQ0FBQzZELGNBQW5CLENBQWtDWSxxQkFBcUIsQ0FBQ3ZDLElBQXRCLENBQTJCNEIsS0FBM0IsQ0FBaUNsQyxJQUFqQyxDQUFzQ21DLE1BQXhFLEtBQ0EvRCxrQkFBa0IsQ0FBQzZELGNBQW5CLENBQWtDWSxxQkFBcUIsQ0FBQzdDLElBQXhELENBRkYsRUFHRTtBQUNBNUIsTUFBQUEsa0JBQWtCLENBQUNnRSxrQkFBbkIsQ0FBc0NRLHlCQUF0QyxFQUFpRUMscUJBQWpFO0FBQ0Q7QUFDRjtBQUNGLENBdFNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgR3JhcGhRTE5vbk51bGwgfSBmcm9tICdncmFwaHFsJztcbmltcG9ydCB7IGZyb21HbG9iYWxJZCwgbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0IGdldEZpZWxkTmFtZXMgZnJvbSAnZ3JhcGhxbC1saXN0LWZpZWxkcyc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4vZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQgeyBleHRyYWN0S2V5c0FuZEluY2x1ZGUsIGdldFBhcnNlQ2xhc3NNdXRhdGlvbkNvbmZpZyB9IGZyb20gJy4uL3BhcnNlR3JhcGhRTFV0aWxzJztcbmltcG9ydCAqIGFzIG9iamVjdHNNdXRhdGlvbnMgZnJvbSAnLi4vaGVscGVycy9vYmplY3RzTXV0YXRpb25zJztcbmltcG9ydCAqIGFzIG9iamVjdHNRdWVyaWVzIGZyb20gJy4uL2hlbHBlcnMvb2JqZWN0c1F1ZXJpZXMnO1xuaW1wb3J0IHsgUGFyc2VHcmFwaFFMQ2xhc3NDb25maWcgfSBmcm9tICcuLi8uLi9Db250cm9sbGVycy9QYXJzZUdyYXBoUUxDb250cm9sbGVyJztcbmltcG9ydCB7IHRyYW5zZm9ybUNsYXNzTmFtZVRvR3JhcGhRTCB9IGZyb20gJy4uL3RyYW5zZm9ybWVycy9jbGFzc05hbWUnO1xuaW1wb3J0IHsgdHJhbnNmb3JtVHlwZXMgfSBmcm9tICcuLi90cmFuc2Zvcm1lcnMvbXV0YXRpb24nO1xuXG5jb25zdCBnZXRPbmx5UmVxdWlyZWRGaWVsZHMgPSAoXG4gIHVwZGF0ZWRGaWVsZHMsXG4gIHNlbGVjdGVkRmllbGRzU3RyaW5nLFxuICBpbmNsdWRlZEZpZWxkc1N0cmluZyxcbiAgbmF0aXZlT2JqZWN0RmllbGRzXG4pID0+IHtcbiAgY29uc3QgaW5jbHVkZWRGaWVsZHMgPSBpbmNsdWRlZEZpZWxkc1N0cmluZyA/IGluY2x1ZGVkRmllbGRzU3RyaW5nLnNwbGl0KCcsJykgOiBbXTtcbiAgY29uc3Qgc2VsZWN0ZWRGaWVsZHMgPSBzZWxlY3RlZEZpZWxkc1N0cmluZyA/IHNlbGVjdGVkRmllbGRzU3RyaW5nLnNwbGl0KCcsJykgOiBbXTtcbiAgY29uc3QgbWlzc2luZ0ZpZWxkcyA9IHNlbGVjdGVkRmllbGRzXG4gICAgLmZpbHRlcihmaWVsZCA9PiAhbmF0aXZlT2JqZWN0RmllbGRzLmluY2x1ZGVzKGZpZWxkKSB8fCBpbmNsdWRlZEZpZWxkcy5pbmNsdWRlcyhmaWVsZCkpXG4gICAgLmpvaW4oJywnKTtcbiAgaWYgKCFtaXNzaW5nRmllbGRzLmxlbmd0aCkge1xuICAgIHJldHVybiB7IG5lZWRHZXQ6IGZhbHNlLCBrZXlzOiAnJyB9O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB7IG5lZWRHZXQ6IHRydWUsIGtleXM6IG1pc3NpbmdGaWVsZHMgfTtcbiAgfVxufTtcblxuY29uc3QgbG9hZCA9IGZ1bmN0aW9uIChwYXJzZUdyYXBoUUxTY2hlbWEsIHBhcnNlQ2xhc3MsIHBhcnNlQ2xhc3NDb25maWc6ID9QYXJzZUdyYXBoUUxDbGFzc0NvbmZpZykge1xuICBjb25zdCBjbGFzc05hbWUgPSBwYXJzZUNsYXNzLmNsYXNzTmFtZTtcbiAgY29uc3QgZ3JhcGhRTENsYXNzTmFtZSA9IHRyYW5zZm9ybUNsYXNzTmFtZVRvR3JhcGhRTChjbGFzc05hbWUpO1xuICBjb25zdCBnZXRHcmFwaFFMUXVlcnlOYW1lID0gZ3JhcGhRTENsYXNzTmFtZS5jaGFyQXQoMCkudG9Mb3dlckNhc2UoKSArIGdyYXBoUUxDbGFzc05hbWUuc2xpY2UoMSk7XG5cbiAgY29uc3Qge1xuICAgIGNyZWF0ZTogaXNDcmVhdGVFbmFibGVkID0gdHJ1ZSxcbiAgICB1cGRhdGU6IGlzVXBkYXRlRW5hYmxlZCA9IHRydWUsXG4gICAgZGVzdHJveTogaXNEZXN0cm95RW5hYmxlZCA9IHRydWUsXG4gICAgY3JlYXRlQWxpYXM6IGNyZWF0ZUFsaWFzID0gJycsXG4gICAgdXBkYXRlQWxpYXM6IHVwZGF0ZUFsaWFzID0gJycsXG4gICAgZGVzdHJveUFsaWFzOiBkZXN0cm95QWxpYXMgPSAnJyxcbiAgfSA9IGdldFBhcnNlQ2xhc3NNdXRhdGlvbkNvbmZpZyhwYXJzZUNsYXNzQ29uZmlnKTtcblxuICBjb25zdCB7XG4gICAgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSxcbiAgICBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlLFxuICAgIGNsYXNzR3JhcGhRTE91dHB1dFR5cGUsXG4gIH0gPSBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzW2NsYXNzTmFtZV07XG5cbiAgaWYgKGlzQ3JlYXRlRW5hYmxlZCkge1xuICAgIGNvbnN0IGNyZWF0ZUdyYXBoUUxNdXRhdGlvbk5hbWUgPSBjcmVhdGVBbGlhcyB8fCBgY3JlYXRlJHtncmFwaFFMQ2xhc3NOYW1lfWA7XG4gICAgY29uc3QgY3JlYXRlR3JhcGhRTE11dGF0aW9uID0gbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCh7XG4gICAgICBuYW1lOiBgQ3JlYXRlJHtncmFwaFFMQ2xhc3NOYW1lfWAsXG4gICAgICBkZXNjcmlwdGlvbjogYFRoZSAke2NyZWF0ZUdyYXBoUUxNdXRhdGlvbk5hbWV9IG11dGF0aW9uIGNhbiBiZSB1c2VkIHRvIGNyZWF0ZSBhIG5ldyBvYmplY3Qgb2YgdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuYCxcbiAgICAgIGlucHV0RmllbGRzOiB7XG4gICAgICAgIGZpZWxkczoge1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnVGhlc2UgYXJlIHRoZSBmaWVsZHMgdGhhdCB3aWxsIGJlIHVzZWQgdG8gY3JlYXRlIHRoZSBuZXcgb2JqZWN0LicsXG4gICAgICAgICAgdHlwZTogY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSB8fCBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgICAgW2dldEdyYXBoUUxRdWVyeU5hbWVdOiB7XG4gICAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBjcmVhdGVkIG9iamVjdC4nLFxuICAgICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIHx8IGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUKSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBtdXRhdGVBbmRHZXRQYXlsb2FkOiBhc3luYyAoYXJncywgY29udGV4dCwgbXV0YXRpb25JbmZvKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgbGV0IHsgZmllbGRzIH0gPSBhcmdzO1xuICAgICAgICAgIGlmICghZmllbGRzKSBmaWVsZHMgPSB7fTtcbiAgICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcblxuICAgICAgICAgIGNvbnN0IHBhcnNlRmllbGRzID0gYXdhaXQgdHJhbnNmb3JtVHlwZXMoJ2NyZWF0ZScsIGZpZWxkcywge1xuICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLFxuICAgICAgICAgICAgcmVxOiB7IGNvbmZpZywgYXV0aCwgaW5mbyB9LFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3QgY3JlYXRlZE9iamVjdCA9IGF3YWl0IG9iamVjdHNNdXRhdGlvbnMuY3JlYXRlT2JqZWN0KFxuICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgcGFyc2VGaWVsZHMsXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgaW5mb1xuICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3Qgc2VsZWN0ZWRGaWVsZHMgPSBnZXRGaWVsZE5hbWVzKG11dGF0aW9uSW5mbylcbiAgICAgICAgICAgIC5maWx0ZXIoZmllbGQgPT4gZmllbGQuc3RhcnRzV2l0aChgJHtnZXRHcmFwaFFMUXVlcnlOYW1lfS5gKSlcbiAgICAgICAgICAgIC5tYXAoZmllbGQgPT4gZmllbGQucmVwbGFjZShgJHtnZXRHcmFwaFFMUXVlcnlOYW1lfS5gLCAnJykpO1xuICAgICAgICAgIGNvbnN0IHsga2V5cywgaW5jbHVkZSB9ID0gZXh0cmFjdEtleXNBbmRJbmNsdWRlKHNlbGVjdGVkRmllbGRzKTtcbiAgICAgICAgICBjb25zdCB7IGtleXM6IHJlcXVpcmVkS2V5cywgbmVlZEdldCB9ID0gZ2V0T25seVJlcXVpcmVkRmllbGRzKGZpZWxkcywga2V5cywgaW5jbHVkZSwgW1xuICAgICAgICAgICAgJ2lkJyxcbiAgICAgICAgICAgICdvYmplY3RJZCcsXG4gICAgICAgICAgICAnY3JlYXRlZEF0JyxcbiAgICAgICAgICAgICd1cGRhdGVkQXQnLFxuICAgICAgICAgIF0pO1xuICAgICAgICAgIGNvbnN0IG5lZWRUb0dldEFsbEtleXMgPSBvYmplY3RzUXVlcmllcy5uZWVkVG9HZXRBbGxLZXlzKFxuICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHMsXG4gICAgICAgICAgICBrZXlzLFxuICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3Nlc1xuICAgICAgICAgICk7XG4gICAgICAgICAgbGV0IG9wdGltaXplZE9iamVjdCA9IHt9O1xuICAgICAgICAgIGlmIChuZWVkR2V0ICYmICFuZWVkVG9HZXRBbGxLZXlzKSB7XG4gICAgICAgICAgICBvcHRpbWl6ZWRPYmplY3QgPSBhd2FpdCBvYmplY3RzUXVlcmllcy5nZXRPYmplY3QoXG4gICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgY3JlYXRlZE9iamVjdC5vYmplY3RJZCxcbiAgICAgICAgICAgICAgcmVxdWlyZWRLZXlzLFxuICAgICAgICAgICAgICBpbmNsdWRlLFxuICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICBpbmZvLFxuICAgICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc2VzXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSBpZiAobmVlZFRvR2V0QWxsS2V5cykge1xuICAgICAgICAgICAgb3B0aW1pemVkT2JqZWN0ID0gYXdhaXQgb2JqZWN0c1F1ZXJpZXMuZ2V0T2JqZWN0KFxuICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgIGNyZWF0ZWRPYmplY3Qub2JqZWN0SWQsXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgaW5jbHVkZSxcbiAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3Nlc1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIFtnZXRHcmFwaFFMUXVlcnlOYW1lXToge1xuICAgICAgICAgICAgICAuLi5jcmVhdGVkT2JqZWN0LFxuICAgICAgICAgICAgICB1cGRhdGVkQXQ6IGNyZWF0ZWRPYmplY3QuY3JlYXRlZEF0LFxuICAgICAgICAgICAgICAuLi5wYXJzZUZpZWxkcyxcbiAgICAgICAgICAgICAgLi4ub3B0aW1pemVkT2JqZWN0LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgaWYgKFxuICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNyZWF0ZUdyYXBoUUxNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlKSAmJlxuICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNyZWF0ZUdyYXBoUUxNdXRhdGlvbi50eXBlKVxuICAgICkge1xuICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbihjcmVhdGVHcmFwaFFMTXV0YXRpb25OYW1lLCBjcmVhdGVHcmFwaFFMTXV0YXRpb24pO1xuICAgIH1cbiAgfVxuXG4gIGlmIChpc1VwZGF0ZUVuYWJsZWQpIHtcbiAgICBjb25zdCB1cGRhdGVHcmFwaFFMTXV0YXRpb25OYW1lID0gdXBkYXRlQWxpYXMgfHwgYHVwZGF0ZSR7Z3JhcGhRTENsYXNzTmFtZX1gO1xuICAgIGNvbnN0IHVwZGF0ZUdyYXBoUUxNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgICAgbmFtZTogYFVwZGF0ZSR7Z3JhcGhRTENsYXNzTmFtZX1gLFxuICAgICAgZGVzY3JpcHRpb246IGBUaGUgJHt1cGRhdGVHcmFwaFFMTXV0YXRpb25OYW1lfSBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byB1cGRhdGUgYW4gb2JqZWN0IG9mIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLmAsXG4gICAgICBpbnB1dEZpZWxkczoge1xuICAgICAgICBpZDogZGVmYXVsdEdyYXBoUUxUeXBlcy5HTE9CQUxfT1JfT0JKRUNUX0lEX0FUVCxcbiAgICAgICAgZmllbGRzOiB7XG4gICAgICAgICAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIGZpZWxkcyB0aGF0IHdpbGwgYmUgdXNlZCB0byB1cGRhdGUgdGhlIG9iamVjdC4nLFxuICAgICAgICAgIHR5cGU6IGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGUgfHwgZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1QsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgb3V0cHV0RmllbGRzOiB7XG4gICAgICAgIFtnZXRHcmFwaFFMUXVlcnlOYW1lXToge1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgdXBkYXRlZCBvYmplY3QuJyxcbiAgICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSB8fCBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVCksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgbXV0YXRlQW5kR2V0UGF5bG9hZDogYXN5bmMgKGFyZ3MsIGNvbnRleHQsIG11dGF0aW9uSW5mbykgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGxldCB7IGlkLCBmaWVsZHMgfSA9IGFyZ3M7XG4gICAgICAgICAgaWYgKCFmaWVsZHMpIGZpZWxkcyA9IHt9O1xuICAgICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuXG4gICAgICAgICAgY29uc3QgZ2xvYmFsSWRPYmplY3QgPSBmcm9tR2xvYmFsSWQoaWQpO1xuXG4gICAgICAgICAgaWYgKGdsb2JhbElkT2JqZWN0LnR5cGUgPT09IGNsYXNzTmFtZSkge1xuICAgICAgICAgICAgaWQgPSBnbG9iYWxJZE9iamVjdC5pZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBwYXJzZUZpZWxkcyA9IGF3YWl0IHRyYW5zZm9ybVR5cGVzKCd1cGRhdGUnLCBmaWVsZHMsIHtcbiAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYSxcbiAgICAgICAgICAgIHJlcTogeyBjb25maWcsIGF1dGgsIGluZm8gfSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNvbnN0IHVwZGF0ZWRPYmplY3QgPSBhd2FpdCBvYmplY3RzTXV0YXRpb25zLnVwZGF0ZU9iamVjdChcbiAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgcGFyc2VGaWVsZHMsXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgaW5mb1xuICAgICAgICAgICk7XG5cbiAgICAgICAgICBjb25zdCBzZWxlY3RlZEZpZWxkcyA9IGdldEZpZWxkTmFtZXMobXV0YXRpb25JbmZvKVxuICAgICAgICAgICAgLmZpbHRlcihmaWVsZCA9PiBmaWVsZC5zdGFydHNXaXRoKGAke2dldEdyYXBoUUxRdWVyeU5hbWV9LmApKVxuICAgICAgICAgICAgLm1hcChmaWVsZCA9PiBmaWVsZC5yZXBsYWNlKGAke2dldEdyYXBoUUxRdWVyeU5hbWV9LmAsICcnKSk7XG4gICAgICAgICAgY29uc3QgeyBrZXlzLCBpbmNsdWRlIH0gPSBleHRyYWN0S2V5c0FuZEluY2x1ZGUoc2VsZWN0ZWRGaWVsZHMpO1xuICAgICAgICAgIGNvbnN0IHsga2V5czogcmVxdWlyZWRLZXlzLCBuZWVkR2V0IH0gPSBnZXRPbmx5UmVxdWlyZWRGaWVsZHMoZmllbGRzLCBrZXlzLCBpbmNsdWRlLCBbXG4gICAgICAgICAgICAnaWQnLFxuICAgICAgICAgICAgJ29iamVjdElkJyxcbiAgICAgICAgICAgICd1cGRhdGVkQXQnLFxuICAgICAgICAgIF0pO1xuICAgICAgICAgIGNvbnN0IG5lZWRUb0dldEFsbEtleXMgPSBvYmplY3RzUXVlcmllcy5uZWVkVG9HZXRBbGxLZXlzKFxuICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHMsXG4gICAgICAgICAgICBrZXlzLFxuICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3Nlc1xuICAgICAgICAgICk7XG4gICAgICAgICAgbGV0IG9wdGltaXplZE9iamVjdCA9IHt9O1xuICAgICAgICAgIGlmIChuZWVkR2V0ICYmICFuZWVkVG9HZXRBbGxLZXlzKSB7XG4gICAgICAgICAgICBvcHRpbWl6ZWRPYmplY3QgPSBhd2FpdCBvYmplY3RzUXVlcmllcy5nZXRPYmplY3QoXG4gICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICAgIHJlcXVpcmVkS2V5cyxcbiAgICAgICAgICAgICAgaW5jbHVkZSxcbiAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3Nlc1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKG5lZWRUb0dldEFsbEtleXMpIHtcbiAgICAgICAgICAgIG9wdGltaXplZE9iamVjdCA9IGF3YWl0IG9iamVjdHNRdWVyaWVzLmdldE9iamVjdChcbiAgICAgICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgICAgICBpZCxcbiAgICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgICBpbmNsdWRlLFxuICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICBpbmZvLFxuICAgICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc2VzXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgW2dldEdyYXBoUUxRdWVyeU5hbWVdOiB7XG4gICAgICAgICAgICAgIG9iamVjdElkOiBpZCxcbiAgICAgICAgICAgICAgLi4udXBkYXRlZE9iamVjdCxcbiAgICAgICAgICAgICAgLi4ucGFyc2VGaWVsZHMsXG4gICAgICAgICAgICAgIC4uLm9wdGltaXplZE9iamVjdCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGlmIChcbiAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZSh1cGRhdGVHcmFwaFFMTXV0YXRpb24uYXJncy5pbnB1dC50eXBlLm9mVHlwZSkgJiZcbiAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZSh1cGRhdGVHcmFwaFFMTXV0YXRpb24udHlwZSlcbiAgICApIHtcbiAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24odXBkYXRlR3JhcGhRTE11dGF0aW9uTmFtZSwgdXBkYXRlR3JhcGhRTE11dGF0aW9uKTtcbiAgICB9XG4gIH1cblxuICBpZiAoaXNEZXN0cm95RW5hYmxlZCkge1xuICAgIGNvbnN0IGRlbGV0ZUdyYXBoUUxNdXRhdGlvbk5hbWUgPSBkZXN0cm95QWxpYXMgfHwgYGRlbGV0ZSR7Z3JhcGhRTENsYXNzTmFtZX1gO1xuICAgIGNvbnN0IGRlbGV0ZUdyYXBoUUxNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgICAgbmFtZTogYERlbGV0ZSR7Z3JhcGhRTENsYXNzTmFtZX1gLFxuICAgICAgZGVzY3JpcHRpb246IGBUaGUgJHtkZWxldGVHcmFwaFFMTXV0YXRpb25OYW1lfSBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBkZWxldGUgYW4gb2JqZWN0IG9mIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLmAsXG4gICAgICBpbnB1dEZpZWxkczoge1xuICAgICAgICBpZDogZGVmYXVsdEdyYXBoUUxUeXBlcy5HTE9CQUxfT1JfT0JKRUNUX0lEX0FUVCxcbiAgICAgIH0sXG4gICAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgICAgW2dldEdyYXBoUUxRdWVyeU5hbWVdOiB7XG4gICAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBkZWxldGVkIG9iamVjdC4nLFxuICAgICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIHx8IGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUKSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBtdXRhdGVBbmRHZXRQYXlsb2FkOiBhc3luYyAoYXJncywgY29udGV4dCwgbXV0YXRpb25JbmZvKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgbGV0IHsgaWQgfSA9IGFyZ3M7XG4gICAgICAgICAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG5cbiAgICAgICAgICBjb25zdCBnbG9iYWxJZE9iamVjdCA9IGZyb21HbG9iYWxJZChpZCk7XG5cbiAgICAgICAgICBpZiAoZ2xvYmFsSWRPYmplY3QudHlwZSA9PT0gY2xhc3NOYW1lKSB7XG4gICAgICAgICAgICBpZCA9IGdsb2JhbElkT2JqZWN0LmlkO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHNlbGVjdGVkRmllbGRzID0gZ2V0RmllbGROYW1lcyhtdXRhdGlvbkluZm8pXG4gICAgICAgICAgICAuZmlsdGVyKGZpZWxkID0+IGZpZWxkLnN0YXJ0c1dpdGgoYCR7Z2V0R3JhcGhRTFF1ZXJ5TmFtZX0uYCkpXG4gICAgICAgICAgICAubWFwKGZpZWxkID0+IGZpZWxkLnJlcGxhY2UoYCR7Z2V0R3JhcGhRTFF1ZXJ5TmFtZX0uYCwgJycpKTtcbiAgICAgICAgICBjb25zdCB7IGtleXMsIGluY2x1ZGUgfSA9IGV4dHJhY3RLZXlzQW5kSW5jbHVkZShzZWxlY3RlZEZpZWxkcyk7XG4gICAgICAgICAgbGV0IG9wdGltaXplZE9iamVjdCA9IHt9O1xuICAgICAgICAgIGlmIChrZXlzICYmIGtleXMuc3BsaXQoJywnKS5maWx0ZXIoa2V5ID0+ICFbJ2lkJywgJ29iamVjdElkJ10uaW5jbHVkZXMoa2V5KSkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgb3B0aW1pemVkT2JqZWN0ID0gYXdhaXQgb2JqZWN0c1F1ZXJpZXMuZ2V0T2JqZWN0KFxuICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgICBrZXlzLFxuICAgICAgICAgICAgICBpbmNsdWRlLFxuICAgICAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICBpbmZvLFxuICAgICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc2VzXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBhd2FpdCBvYmplY3RzTXV0YXRpb25zLmRlbGV0ZU9iamVjdChjbGFzc05hbWUsIGlkLCBjb25maWcsIGF1dGgsIGluZm8pO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBbZ2V0R3JhcGhRTFF1ZXJ5TmFtZV06IHtcbiAgICAgICAgICAgICAgb2JqZWN0SWQ6IGlkLFxuICAgICAgICAgICAgICAuLi5vcHRpbWl6ZWRPYmplY3QsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAoXG4gICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoZGVsZXRlR3JhcGhRTE11dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGUpICYmXG4gICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoZGVsZXRlR3JhcGhRTE11dGF0aW9uLnR5cGUpXG4gICAgKSB7XG4gICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTE11dGF0aW9uKGRlbGV0ZUdyYXBoUUxNdXRhdGlvbk5hbWUsIGRlbGV0ZUdyYXBoUUxNdXRhdGlvbik7XG4gICAgfVxuICB9XG59O1xuXG5leHBvcnQgeyBsb2FkIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/loaders/parseClassQueries.js b/lib/GraphQL/loaders/parseClassQueries.js deleted file mode 100644 index e834ec09c2..0000000000 --- a/lib/GraphQL/loaders/parseClassQueries.js +++ /dev/null @@ -1,150 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = void 0; - -var _graphql = require("graphql"); - -var _graphqlRelay = require("graphql-relay"); - -var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); - -var _pluralize = _interopRequireDefault(require("pluralize")); - -var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); - -var objectsQueries = _interopRequireWildcard(require("../helpers/objectsQueries")); - -var _ParseGraphQLController = require("../../Controllers/ParseGraphQLController"); - -var _className = require("../transformers/className"); - -var _parseGraphQLUtils = require("../parseGraphQLUtils"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const getParseClassQueryConfig = function (parseClassConfig) { - return parseClassConfig && parseClassConfig.query || {}; -}; - -const getQuery = async (parseClass, _source, args, context, queryInfo, parseClasses) => { - let { - id - } = args; - const { - options - } = args; - const { - readPreference, - includeReadPreference - } = options || {}; - const { - config, - auth, - info - } = context; - const selectedFields = (0, _graphqlListFields.default)(queryInfo); - const globalIdObject = (0, _graphqlRelay.fromGlobalId)(id); - - if (globalIdObject.type === parseClass.className) { - id = globalIdObject.id; - } - - const { - keys, - include - } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields); - return await objectsQueries.getObject(parseClass.className, id, keys, include, readPreference, includeReadPreference, config, auth, info, parseClasses); -}; - -const load = function (parseGraphQLSchema, parseClass, parseClassConfig) { - const className = parseClass.className; - const graphQLClassName = (0, _className.transformClassNameToGraphQL)(className); - const { - get: isGetEnabled = true, - find: isFindEnabled = true, - getAlias = '', - findAlias = '' - } = getParseClassQueryConfig(parseClassConfig); - const { - classGraphQLOutputType, - classGraphQLFindArgs, - classGraphQLFindResultType - } = parseGraphQLSchema.parseClassTypes[className]; - - if (isGetEnabled) { - const lowerCaseClassName = graphQLClassName.charAt(0).toLowerCase() + graphQLClassName.slice(1); - const getGraphQLQueryName = getAlias || lowerCaseClassName; - parseGraphQLSchema.addGraphQLQuery(getGraphQLQueryName, { - description: `The ${getGraphQLQueryName} query can be used to get an object of the ${graphQLClassName} class by its id.`, - args: { - id: defaultGraphQLTypes.GLOBAL_OR_OBJECT_ID_ATT, - options: defaultGraphQLTypes.READ_OPTIONS_ATT - }, - type: new _graphql.GraphQLNonNull(classGraphQLOutputType || defaultGraphQLTypes.OBJECT), - - async resolve(_source, args, context, queryInfo) { - try { - return await getQuery(parseClass, _source, args, context, queryInfo, parseGraphQLSchema.parseClasses); - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - - }); - } - - if (isFindEnabled) { - const lowerCaseClassName = graphQLClassName.charAt(0).toLowerCase() + graphQLClassName.slice(1); - const findGraphQLQueryName = findAlias || (0, _pluralize.default)(lowerCaseClassName); - parseGraphQLSchema.addGraphQLQuery(findGraphQLQueryName, { - description: `The ${findGraphQLQueryName} query can be used to find objects of the ${graphQLClassName} class.`, - args: classGraphQLFindArgs, - type: new _graphql.GraphQLNonNull(classGraphQLFindResultType || defaultGraphQLTypes.OBJECT), - - async resolve(_source, args, context, queryInfo) { - try { - const { - where, - order, - skip, - first, - after, - last, - before, - options - } = args; - const { - readPreference, - includeReadPreference, - subqueryReadPreference - } = options || {}; - const { - config, - auth, - info - } = context; - const selectedFields = (0, _graphqlListFields.default)(queryInfo); - const { - keys, - include - } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields.filter(field => field.startsWith('edges.node.')).map(field => field.replace('edges.node.', ''))); - const parseOrder = order && order.join(','); - return await objectsQueries.findObjects(className, where, parseOrder, skip, first, after, last, before, keys, include, false, readPreference, includeReadPreference, subqueryReadPreference, config, auth, info, selectedFields, parseGraphQLSchema.parseClasses); - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - - }); - } -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvcGFyc2VDbGFzc1F1ZXJpZXMuanMiXSwibmFtZXMiOlsiZ2V0UGFyc2VDbGFzc1F1ZXJ5Q29uZmlnIiwicGFyc2VDbGFzc0NvbmZpZyIsInF1ZXJ5IiwiZ2V0UXVlcnkiLCJwYXJzZUNsYXNzIiwiX3NvdXJjZSIsImFyZ3MiLCJjb250ZXh0IiwicXVlcnlJbmZvIiwicGFyc2VDbGFzc2VzIiwiaWQiLCJvcHRpb25zIiwicmVhZFByZWZlcmVuY2UiLCJpbmNsdWRlUmVhZFByZWZlcmVuY2UiLCJjb25maWciLCJhdXRoIiwiaW5mbyIsInNlbGVjdGVkRmllbGRzIiwiZ2xvYmFsSWRPYmplY3QiLCJ0eXBlIiwiY2xhc3NOYW1lIiwia2V5cyIsImluY2x1ZGUiLCJvYmplY3RzUXVlcmllcyIsImdldE9iamVjdCIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJncmFwaFFMQ2xhc3NOYW1lIiwiZ2V0IiwiaXNHZXRFbmFibGVkIiwiZmluZCIsImlzRmluZEVuYWJsZWQiLCJnZXRBbGlhcyIsImZpbmRBbGlhcyIsImNsYXNzR3JhcGhRTE91dHB1dFR5cGUiLCJjbGFzc0dyYXBoUUxGaW5kQXJncyIsImNsYXNzR3JhcGhRTEZpbmRSZXN1bHRUeXBlIiwicGFyc2VDbGFzc1R5cGVzIiwibG93ZXJDYXNlQ2xhc3NOYW1lIiwiY2hhckF0IiwidG9Mb3dlckNhc2UiLCJzbGljZSIsImdldEdyYXBoUUxRdWVyeU5hbWUiLCJhZGRHcmFwaFFMUXVlcnkiLCJkZXNjcmlwdGlvbiIsImRlZmF1bHRHcmFwaFFMVHlwZXMiLCJHTE9CQUxfT1JfT0JKRUNUX0lEX0FUVCIsIlJFQURfT1BUSU9OU19BVFQiLCJHcmFwaFFMTm9uTnVsbCIsIk9CSkVDVCIsInJlc29sdmUiLCJlIiwiaGFuZGxlRXJyb3IiLCJmaW5kR3JhcGhRTFF1ZXJ5TmFtZSIsIndoZXJlIiwib3JkZXIiLCJza2lwIiwiZmlyc3QiLCJhZnRlciIsImxhc3QiLCJiZWZvcmUiLCJzdWJxdWVyeVJlYWRQcmVmZXJlbmNlIiwiZmlsdGVyIiwiZmllbGQiLCJzdGFydHNXaXRoIiwibWFwIiwicmVwbGFjZSIsInBhcnNlT3JkZXIiLCJqb2luIiwiZmluZE9iamVjdHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFQSxNQUFNQSx3QkFBd0IsR0FBRyxVQUFVQyxnQkFBVixFQUFzRDtBQUNyRixTQUFRQSxnQkFBZ0IsSUFBSUEsZ0JBQWdCLENBQUNDLEtBQXRDLElBQWdELEVBQXZEO0FBQ0QsQ0FGRDs7QUFJQSxNQUFNQyxRQUFRLEdBQUcsT0FBT0MsVUFBUCxFQUFtQkMsT0FBbkIsRUFBNEJDLElBQTVCLEVBQWtDQyxPQUFsQyxFQUEyQ0MsU0FBM0MsRUFBc0RDLFlBQXRELEtBQXVFO0FBQ3RGLE1BQUk7QUFBRUMsSUFBQUE7QUFBRixNQUFTSixJQUFiO0FBQ0EsUUFBTTtBQUFFSyxJQUFBQTtBQUFGLE1BQWNMLElBQXBCO0FBQ0EsUUFBTTtBQUFFTSxJQUFBQSxjQUFGO0FBQWtCQyxJQUFBQTtBQUFsQixNQUE0Q0YsT0FBTyxJQUFJLEVBQTdEO0FBQ0EsUUFBTTtBQUFFRyxJQUFBQSxNQUFGO0FBQVVDLElBQUFBLElBQVY7QUFBZ0JDLElBQUFBO0FBQWhCLE1BQXlCVCxPQUEvQjtBQUNBLFFBQU1VLGNBQWMsR0FBRyxnQ0FBY1QsU0FBZCxDQUF2QjtBQUVBLFFBQU1VLGNBQWMsR0FBRyxnQ0FBYVIsRUFBYixDQUF2Qjs7QUFFQSxNQUFJUSxjQUFjLENBQUNDLElBQWYsS0FBd0JmLFVBQVUsQ0FBQ2dCLFNBQXZDLEVBQWtEO0FBQ2hEVixJQUFBQSxFQUFFLEdBQUdRLGNBQWMsQ0FBQ1IsRUFBcEI7QUFDRDs7QUFFRCxRQUFNO0FBQUVXLElBQUFBLElBQUY7QUFBUUMsSUFBQUE7QUFBUixNQUFvQiw4Q0FBc0JMLGNBQXRCLENBQTFCO0FBRUEsU0FBTyxNQUFNTSxj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QyxPQVZXLEVBV1gsS0FYVyxFQVlYVixjQVpXLEVBYVhDLHFCQWJXLEVBY1hnRCxzQkFkVyxFQWVYL0MsTUFmVyxFQWdCWEMsSUFoQlcsRUFpQlhDLElBakJXLEVBa0JYQyxjQWxCVyxFQW1CWFMsa0JBQWtCLENBQUNqQixZQW5CUixDQUFiO0FBcUJELFNBbENELENBa0NFLE9BQU8wQyxDQUFQLEVBQVU7QUFDVnpCLFVBQUFBLGtCQUFrQixDQUFDMEIsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRjs7QUExQ3NELEtBQXpEO0FBNENEO0FBQ0YsQ0EvRkQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBHcmFwaFFMTm9uTnVsbCB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgZnJvbUdsb2JhbElkIH0gZnJvbSAnZ3JhcGhxbC1yZWxheSc7XG5pbXBvcnQgZ2V0RmllbGROYW1lcyBmcm9tICdncmFwaHFsLWxpc3QtZmllbGRzJztcbmltcG9ydCBwbHVyYWxpemUgZnJvbSAncGx1cmFsaXplJztcbmltcG9ydCAqIGFzIGRlZmF1bHRHcmFwaFFMVHlwZXMgZnJvbSAnLi9kZWZhdWx0R3JhcGhRTFR5cGVzJztcbmltcG9ydCAqIGFzIG9iamVjdHNRdWVyaWVzIGZyb20gJy4uL2hlbHBlcnMvb2JqZWN0c1F1ZXJpZXMnO1xuaW1wb3J0IHsgUGFyc2VHcmFwaFFMQ2xhc3NDb25maWcgfSBmcm9tICcuLi8uLi9Db250cm9sbGVycy9QYXJzZUdyYXBoUUxDb250cm9sbGVyJztcbmltcG9ydCB7IHRyYW5zZm9ybUNsYXNzTmFtZVRvR3JhcGhRTCB9IGZyb20gJy4uL3RyYW5zZm9ybWVycy9jbGFzc05hbWUnO1xuaW1wb3J0IHsgZXh0cmFjdEtleXNBbmRJbmNsdWRlIH0gZnJvbSAnLi4vcGFyc2VHcmFwaFFMVXRpbHMnO1xuXG5jb25zdCBnZXRQYXJzZUNsYXNzUXVlcnlDb25maWcgPSBmdW5jdGlvbiAocGFyc2VDbGFzc0NvbmZpZzogP1BhcnNlR3JhcGhRTENsYXNzQ29uZmlnKSB7XG4gIHJldHVybiAocGFyc2VDbGFzc0NvbmZpZyAmJiBwYXJzZUNsYXNzQ29uZmlnLnF1ZXJ5KSB8fCB7fTtcbn07XG5cbmNvbnN0IGdldFF1ZXJ5ID0gYXN5bmMgKHBhcnNlQ2xhc3MsIF9zb3VyY2UsIGFyZ3MsIGNvbnRleHQsIHF1ZXJ5SW5mbywgcGFyc2VDbGFzc2VzKSA9PiB7XG4gIGxldCB7IGlkIH0gPSBhcmdzO1xuICBjb25zdCB7IG9wdGlvbnMgfSA9IGFyZ3M7XG4gIGNvbnN0IHsgcmVhZFByZWZlcmVuY2UsIGluY2x1ZGVSZWFkUHJlZmVyZW5jZSB9ID0gb3B0aW9ucyB8fCB7fTtcbiAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG4gIGNvbnN0IHNlbGVjdGVkRmllbGRzID0gZ2V0RmllbGROYW1lcyhxdWVyeUluZm8pO1xuXG4gIGNvbnN0IGdsb2JhbElkT2JqZWN0ID0gZnJvbUdsb2JhbElkKGlkKTtcblxuICBpZiAoZ2xvYmFsSWRPYmplY3QudHlwZSA9PT0gcGFyc2VDbGFzcy5jbGFzc05hbWUpIHtcbiAgICBpZCA9IGdsb2JhbElkT2JqZWN0LmlkO1xuICB9XG5cbiAgY29uc3QgeyBrZXlzLCBpbmNsdWRlIH0gPSBleHRyYWN0S2V5c0FuZEluY2x1ZGUoc2VsZWN0ZWRGaWVsZHMpO1xuXG4gIHJldHVybiBhd2FpdCBvYmplY3RzUXVlcmllcy5nZXRPYmplY3QoXG4gICAgcGFyc2VDbGFzcy5jbGFzc05hbWUsXG4gICAgaWQsXG4gICAga2V5cyxcbiAgICBpbmNsdWRlLFxuICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgIGluY2x1ZGVSZWFkUHJlZmVyZW5jZSxcbiAgICBjb25maWcsXG4gICAgYXV0aCxcbiAgICBpbmZvLFxuICAgIHBhcnNlQ2xhc3Nlc1xuICApO1xufTtcblxuY29uc3QgbG9hZCA9IGZ1bmN0aW9uIChwYXJzZUdyYXBoUUxTY2hlbWEsIHBhcnNlQ2xhc3MsIHBhcnNlQ2xhc3NDb25maWc6ID9QYXJzZUdyYXBoUUxDbGFzc0NvbmZpZykge1xuICBjb25zdCBjbGFzc05hbWUgPSBwYXJzZUNsYXNzLmNsYXNzTmFtZTtcbiAgY29uc3QgZ3JhcGhRTENsYXNzTmFtZSA9IHRyYW5zZm9ybUNsYXNzTmFtZVRvR3JhcGhRTChjbGFzc05hbWUpO1xuICBjb25zdCB7XG4gICAgZ2V0OiBpc0dldEVuYWJsZWQgPSB0cnVlLFxuICAgIGZpbmQ6IGlzRmluZEVuYWJsZWQgPSB0cnVlLFxuICAgIGdldEFsaWFzOiBnZXRBbGlhcyA9ICcnLFxuICAgIGZpbmRBbGlhczogZmluZEFsaWFzID0gJycsXG4gIH0gPSBnZXRQYXJzZUNsYXNzUXVlcnlDb25maWcocGFyc2VDbGFzc0NvbmZpZyk7XG5cbiAgY29uc3Qge1xuICAgIGNsYXNzR3JhcGhRTE91dHB1dFR5cGUsXG4gICAgY2xhc3NHcmFwaFFMRmluZEFyZ3MsXG4gICAgY2xhc3NHcmFwaFFMRmluZFJlc3VsdFR5cGUsXG4gIH0gPSBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzW2NsYXNzTmFtZV07XG5cbiAgaWYgKGlzR2V0RW5hYmxlZCkge1xuICAgIGNvbnN0IGxvd2VyQ2FzZUNsYXNzTmFtZSA9IGdyYXBoUUxDbGFzc05hbWUuY2hhckF0KDApLnRvTG93ZXJDYXNlKCkgKyBncmFwaFFMQ2xhc3NOYW1lLnNsaWNlKDEpO1xuXG4gICAgY29uc3QgZ2V0R3JhcGhRTFF1ZXJ5TmFtZSA9IGdldEFsaWFzIHx8IGxvd2VyQ2FzZUNsYXNzTmFtZTtcblxuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMUXVlcnkoZ2V0R3JhcGhRTFF1ZXJ5TmFtZSwge1xuICAgICAgZGVzY3JpcHRpb246IGBUaGUgJHtnZXRHcmFwaFFMUXVlcnlOYW1lfSBxdWVyeSBjYW4gYmUgdXNlZCB0byBnZXQgYW4gb2JqZWN0IG9mIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzIGJ5IGl0cyBpZC5gLFxuICAgICAgYXJnczoge1xuICAgICAgICBpZDogZGVmYXVsdEdyYXBoUUxUeXBlcy5HTE9CQUxfT1JfT0JKRUNUX0lEX0FUVCxcbiAgICAgICAgb3B0aW9uczogZGVmYXVsdEdyYXBoUUxUeXBlcy5SRUFEX09QVElPTlNfQVRULFxuICAgICAgfSxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIHx8IGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUKSxcbiAgICAgIGFzeW5jIHJlc29sdmUoX3NvdXJjZSwgYXJncywgY29udGV4dCwgcXVlcnlJbmZvKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIGF3YWl0IGdldFF1ZXJ5KFxuICAgICAgICAgICAgcGFyc2VDbGFzcyxcbiAgICAgICAgICAgIF9zb3VyY2UsXG4gICAgICAgICAgICBhcmdzLFxuICAgICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICAgIHF1ZXJ5SW5mbyxcbiAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzZXNcbiAgICAgICAgICApO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgaWYgKGlzRmluZEVuYWJsZWQpIHtcbiAgICBjb25zdCBsb3dlckNhc2VDbGFzc05hbWUgPSBncmFwaFFMQ2xhc3NOYW1lLmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpICsgZ3JhcGhRTENsYXNzTmFtZS5zbGljZSgxKTtcblxuICAgIGNvbnN0IGZpbmRHcmFwaFFMUXVlcnlOYW1lID0gZmluZEFsaWFzIHx8IHBsdXJhbGl6ZShsb3dlckNhc2VDbGFzc05hbWUpO1xuXG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxRdWVyeShmaW5kR3JhcGhRTFF1ZXJ5TmFtZSwge1xuICAgICAgZGVzY3JpcHRpb246IGBUaGUgJHtmaW5kR3JhcGhRTFF1ZXJ5TmFtZX0gcXVlcnkgY2FuIGJlIHVzZWQgdG8gZmluZCBvYmplY3RzIG9mIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLmAsXG4gICAgICBhcmdzOiBjbGFzc0dyYXBoUUxGaW5kQXJncyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxGaW5kUmVzdWx0VHlwZSB8fCBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVCksXG4gICAgICBhc3luYyByZXNvbHZlKF9zb3VyY2UsIGFyZ3MsIGNvbnRleHQsIHF1ZXJ5SW5mbykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHsgd2hlcmUsIG9yZGVyLCBza2lwLCBmaXJzdCwgYWZ0ZXIsIGxhc3QsIGJlZm9yZSwgb3B0aW9ucyB9ID0gYXJncztcbiAgICAgICAgICBjb25zdCB7IHJlYWRQcmVmZXJlbmNlLCBpbmNsdWRlUmVhZFByZWZlcmVuY2UsIHN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UgfSA9IG9wdGlvbnMgfHwge307XG4gICAgICAgICAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG4gICAgICAgICAgY29uc3Qgc2VsZWN0ZWRGaWVsZHMgPSBnZXRGaWVsZE5hbWVzKHF1ZXJ5SW5mbyk7XG5cbiAgICAgICAgICBjb25zdCB7IGtleXMsIGluY2x1ZGUgfSA9IGV4dHJhY3RLZXlzQW5kSW5jbHVkZShcbiAgICAgICAgICAgIHNlbGVjdGVkRmllbGRzXG4gICAgICAgICAgICAgIC5maWx0ZXIoZmllbGQgPT4gZmllbGQuc3RhcnRzV2l0aCgnZWRnZXMubm9kZS4nKSlcbiAgICAgICAgICAgICAgLm1hcChmaWVsZCA9PiBmaWVsZC5yZXBsYWNlKCdlZGdlcy5ub2RlLicsICcnKSlcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IHBhcnNlT3JkZXIgPSBvcmRlciAmJiBvcmRlci5qb2luKCcsJyk7XG5cbiAgICAgICAgICByZXR1cm4gYXdhaXQgb2JqZWN0c1F1ZXJpZXMuZmluZE9iamVjdHMoXG4gICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICB3aGVyZSxcbiAgICAgICAgICAgIHBhcnNlT3JkZXIsXG4gICAgICAgICAgICBza2lwLFxuICAgICAgICAgICAgZmlyc3QsXG4gICAgICAgICAgICBhZnRlcixcbiAgICAgICAgICAgIGxhc3QsXG4gICAgICAgICAgICBiZWZvcmUsXG4gICAgICAgICAgICBrZXlzLFxuICAgICAgICAgICAgaW5jbHVkZSxcbiAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICBpbmNsdWRlUmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICBzdWJxdWVyeVJlYWRQcmVmZXJlbmNlLFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgIGluZm8sXG4gICAgICAgICAgICBzZWxlY3RlZEZpZWxkcyxcbiAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzZXNcbiAgICAgICAgICApO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG59O1xuXG5leHBvcnQgeyBsb2FkIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/loaders/parseClassTypes.js b/lib/GraphQL/loaders/parseClassTypes.js deleted file mode 100644 index 33e7bf5ea1..0000000000 --- a/lib/GraphQL/loaders/parseClassTypes.js +++ /dev/null @@ -1,531 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "extractKeysAndInclude", { - enumerable: true, - get: function () { - return _parseGraphQLUtils.extractKeysAndInclude; - } -}); -exports.load = void 0; - -var _graphql = require("graphql"); - -var _graphqlRelay = require("graphql-relay"); - -var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); - -var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes")); - -var objectsQueries = _interopRequireWildcard(require("../helpers/objectsQueries")); - -var _ParseGraphQLController = require("../../Controllers/ParseGraphQLController"); - -var _className = require("../transformers/className"); - -var _inputType = require("../transformers/inputType"); - -var _outputType = require("../transformers/outputType"); - -var _constraintType = require("../transformers/constraintType"); - -var _parseGraphQLUtils = require("../parseGraphQLUtils"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const getParseClassTypeConfig = function (parseClassConfig) { - return parseClassConfig && parseClassConfig.type || {}; -}; - -const getInputFieldsAndConstraints = function (parseClass, parseClassConfig) { - const classFields = Object.keys(parseClass.fields).concat('id'); - const { - inputFields: allowedInputFields, - outputFields: allowedOutputFields, - constraintFields: allowedConstraintFields, - sortFields: allowedSortFields - } = getParseClassTypeConfig(parseClassConfig); - let classOutputFields; - let classCreateFields; - let classUpdateFields; - let classConstraintFields; - let classSortFields; // All allowed customs fields - - const classCustomFields = classFields.filter(field => { - return !Object.keys(defaultGraphQLTypes.PARSE_OBJECT_FIELDS).includes(field) && field !== 'id'; - }); - - if (allowedInputFields && allowedInputFields.create) { - classCreateFields = classCustomFields.filter(field => { - return allowedInputFields.create.includes(field); - }); - } else { - classCreateFields = classCustomFields; - } - - if (allowedInputFields && allowedInputFields.update) { - classUpdateFields = classCustomFields.filter(field => { - return allowedInputFields.update.includes(field); - }); - } else { - classUpdateFields = classCustomFields; - } - - if (allowedOutputFields) { - classOutputFields = classCustomFields.filter(field => { - return allowedOutputFields.includes(field); - }); - } else { - classOutputFields = classCustomFields; - } // Filters the "password" field from class _User - - - if (parseClass.className === '_User') { - classOutputFields = classOutputFields.filter(outputField => outputField !== 'password'); - } - - if (allowedConstraintFields) { - classConstraintFields = classCustomFields.filter(field => { - return allowedConstraintFields.includes(field); - }); - } else { - classConstraintFields = classFields; - } - - if (allowedSortFields) { - classSortFields = allowedSortFields; - - if (!classSortFields.length) { - // must have at least 1 order field - // otherwise the FindArgs Input Type will throw. - classSortFields.push({ - field: 'id', - asc: true, - desc: true - }); - } - } else { - classSortFields = classFields.map(field => { - return { - field, - asc: true, - desc: true - }; - }); - } - - return { - classCreateFields, - classUpdateFields, - classConstraintFields, - classOutputFields, - classSortFields - }; -}; - -const load = (parseGraphQLSchema, parseClass, parseClassConfig) => { - const className = parseClass.className; - const graphQLClassName = (0, _className.transformClassNameToGraphQL)(className); - const { - classCreateFields, - classUpdateFields, - classOutputFields, - classConstraintFields, - classSortFields - } = getInputFieldsAndConstraints(parseClass, parseClassConfig); - const { - create: isCreateEnabled = true, - update: isUpdateEnabled = true - } = (0, _parseGraphQLUtils.getParseClassMutationConfig)(parseClassConfig); - const classGraphQLCreateTypeName = `Create${graphQLClassName}FieldsInput`; - let classGraphQLCreateType = new _graphql.GraphQLInputObjectType({ - name: classGraphQLCreateTypeName, - description: `The ${classGraphQLCreateTypeName} input type is used in operations that involve creation of objects in the ${graphQLClassName} class.`, - fields: () => classCreateFields.reduce((fields, field) => { - const type = (0, _inputType.transformInputTypeToGraphQL)(parseClass.fields[field].type, parseClass.fields[field].targetClass, parseGraphQLSchema.parseClassTypes); - - if (type) { - return _objectSpread(_objectSpread({}, fields), {}, { - [field]: { - description: `This is the object ${field}.`, - type: className === '_User' && (field === 'username' || field === 'password') || parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type - } - }); - } else { - return fields; - } - }, { - ACL: { - type: defaultGraphQLTypes.ACL_INPUT - } - }) - }); - classGraphQLCreateType = parseGraphQLSchema.addGraphQLType(classGraphQLCreateType); - const classGraphQLUpdateTypeName = `Update${graphQLClassName}FieldsInput`; - let classGraphQLUpdateType = new _graphql.GraphQLInputObjectType({ - name: classGraphQLUpdateTypeName, - description: `The ${classGraphQLUpdateTypeName} input type is used in operations that involve creation of objects in the ${graphQLClassName} class.`, - fields: () => classUpdateFields.reduce((fields, field) => { - const type = (0, _inputType.transformInputTypeToGraphQL)(parseClass.fields[field].type, parseClass.fields[field].targetClass, parseGraphQLSchema.parseClassTypes); - - if (type) { - return _objectSpread(_objectSpread({}, fields), {}, { - [field]: { - description: `This is the object ${field}.`, - type - } - }); - } else { - return fields; - } - }, { - ACL: { - type: defaultGraphQLTypes.ACL_INPUT - } - }) - }); - classGraphQLUpdateType = parseGraphQLSchema.addGraphQLType(classGraphQLUpdateType); - const classGraphQLPointerTypeName = `${graphQLClassName}PointerInput`; - let classGraphQLPointerType = new _graphql.GraphQLInputObjectType({ - name: classGraphQLPointerTypeName, - description: `Allow to link OR add and link an object of the ${graphQLClassName} class.`, - fields: () => { - const fields = { - link: { - description: `Link an existing object from ${graphQLClassName} class. You can use either the global or the object id.`, - type: _graphql.GraphQLID - } - }; - - if (isCreateEnabled) { - fields['createAndLink'] = { - description: `Create and link an object from ${graphQLClassName} class.`, - type: classGraphQLCreateType - }; - } - - return fields; - } - }); - classGraphQLPointerType = parseGraphQLSchema.addGraphQLType(classGraphQLPointerType) || defaultGraphQLTypes.OBJECT; - const classGraphQLRelationTypeName = `${graphQLClassName}RelationInput`; - let classGraphQLRelationType = new _graphql.GraphQLInputObjectType({ - name: classGraphQLRelationTypeName, - description: `Allow to add, remove, createAndAdd objects of the ${graphQLClassName} class into a relation field.`, - fields: () => { - const fields = { - add: { - description: `Add existing objects from the ${graphQLClassName} class into the relation. You can use either the global or the object ids.`, - type: new _graphql.GraphQLList(defaultGraphQLTypes.OBJECT_ID) - }, - remove: { - description: `Remove existing objects from the ${graphQLClassName} class out of the relation. You can use either the global or the object ids.`, - type: new _graphql.GraphQLList(defaultGraphQLTypes.OBJECT_ID) - } - }; - - if (isCreateEnabled) { - fields['createAndAdd'] = { - description: `Create and add objects of the ${graphQLClassName} class into the relation.`, - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLCreateType)) - }; - } - - return fields; - } - }); - classGraphQLRelationType = parseGraphQLSchema.addGraphQLType(classGraphQLRelationType) || defaultGraphQLTypes.OBJECT; - const classGraphQLConstraintsTypeName = `${graphQLClassName}WhereInput`; - let classGraphQLConstraintsType = new _graphql.GraphQLInputObjectType({ - name: classGraphQLConstraintsTypeName, - description: `The ${classGraphQLConstraintsTypeName} input type is used in operations that involve filtering objects of ${graphQLClassName} class.`, - fields: () => _objectSpread(_objectSpread({}, classConstraintFields.reduce((fields, field) => { - if (['OR', 'AND', 'NOR'].includes(field)) { - parseGraphQLSchema.log.warn(`Field ${field} could not be added to the auto schema ${classGraphQLConstraintsTypeName} because it collided with an existing one.`); - return fields; - } - - const parseField = field === 'id' ? 'objectId' : field; - const type = (0, _constraintType.transformConstraintTypeToGraphQL)(parseClass.fields[parseField].type, parseClass.fields[parseField].targetClass, parseGraphQLSchema.parseClassTypes, field); - - if (type) { - return _objectSpread(_objectSpread({}, fields), {}, { - [field]: { - description: `This is the object ${field}.`, - type - } - }); - } else { - return fields; - } - }, {})), {}, { - OR: { - description: 'This is the OR operator to compound constraints.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLConstraintsType)) - }, - AND: { - description: 'This is the AND operator to compound constraints.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLConstraintsType)) - }, - NOR: { - description: 'This is the NOR operator to compound constraints.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLConstraintsType)) - } - }) - }); - classGraphQLConstraintsType = parseGraphQLSchema.addGraphQLType(classGraphQLConstraintsType) || defaultGraphQLTypes.OBJECT; - const classGraphQLRelationConstraintsTypeName = `${graphQLClassName}RelationWhereInput`; - let classGraphQLRelationConstraintsType = new _graphql.GraphQLInputObjectType({ - name: classGraphQLRelationConstraintsTypeName, - description: `The ${classGraphQLRelationConstraintsTypeName} input type is used in operations that involve filtering objects of ${graphQLClassName} class.`, - fields: () => ({ - have: { - description: 'Run a relational/pointer query where at least one child object can match.', - type: classGraphQLConstraintsType - }, - haveNot: { - description: 'Run an inverted relational/pointer query where at least one child object can match.', - type: classGraphQLConstraintsType - }, - exists: { - description: 'Check if the relation/pointer contains objects.', - type: _graphql.GraphQLBoolean - } - }) - }); - classGraphQLRelationConstraintsType = parseGraphQLSchema.addGraphQLType(classGraphQLRelationConstraintsType) || defaultGraphQLTypes.OBJECT; - const classGraphQLOrderTypeName = `${graphQLClassName}Order`; - let classGraphQLOrderType = new _graphql.GraphQLEnumType({ - name: classGraphQLOrderTypeName, - description: `The ${classGraphQLOrderTypeName} input type is used when sorting objects of the ${graphQLClassName} class.`, - values: classSortFields.reduce((sortFields, fieldConfig) => { - const { - field, - asc, - desc - } = fieldConfig; - - const updatedSortFields = _objectSpread({}, sortFields); - - const value = field === 'id' ? 'objectId' : field; - - if (asc) { - updatedSortFields[`${field}_ASC`] = { - value - }; - } - - if (desc) { - updatedSortFields[`${field}_DESC`] = { - value: `-${value}` - }; - } - - return updatedSortFields; - }, {}) - }); - classGraphQLOrderType = parseGraphQLSchema.addGraphQLType(classGraphQLOrderType); - - const classGraphQLFindArgs = _objectSpread(_objectSpread({ - where: { - description: 'These are the conditions that the objects need to match in order to be found.', - type: classGraphQLConstraintsType - }, - order: { - description: 'The fields to be used when sorting the data fetched.', - type: classGraphQLOrderType ? new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLOrderType)) : _graphql.GraphQLString - }, - skip: defaultGraphQLTypes.SKIP_ATT - }, _graphqlRelay.connectionArgs), {}, { - options: defaultGraphQLTypes.READ_OPTIONS_ATT - }); - - const classGraphQLOutputTypeName = `${graphQLClassName}`; - const interfaces = [defaultGraphQLTypes.PARSE_OBJECT, parseGraphQLSchema.relayNodeInterface]; - - const parseObjectFields = _objectSpread({ - id: (0, _graphqlRelay.globalIdField)(className, obj => obj.objectId) - }, defaultGraphQLTypes.PARSE_OBJECT_FIELDS); - - const outputFields = () => { - return classOutputFields.reduce((fields, field) => { - const type = (0, _outputType.transformOutputTypeToGraphQL)(parseClass.fields[field].type, parseClass.fields[field].targetClass, parseGraphQLSchema.parseClassTypes); - - if (parseClass.fields[field].type === 'Relation') { - const targetParseClassTypes = parseGraphQLSchema.parseClassTypes[parseClass.fields[field].targetClass]; - const args = targetParseClassTypes ? targetParseClassTypes.classGraphQLFindArgs : undefined; - return _objectSpread(_objectSpread({}, fields), {}, { - [field]: { - description: `This is the object ${field}.`, - args, - type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type, - - async resolve(source, args, context, queryInfo) { - try { - const { - where, - order, - skip, - first, - after, - last, - before, - options - } = args; - const { - readPreference, - includeReadPreference, - subqueryReadPreference - } = options || {}; - const { - config, - auth, - info - } = context; - const selectedFields = (0, _graphqlListFields.default)(queryInfo); - const { - keys, - include - } = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields.filter(field => field.startsWith('edges.node.')).map(field => field.replace('edges.node.', ''))); - const parseOrder = order && order.join(','); - return objectsQueries.findObjects(source[field].className, _objectSpread({ - $relatedTo: { - object: { - __type: 'Pointer', - className: className, - objectId: source.objectId - }, - key: field - } - }, where || {}), parseOrder, skip, first, after, last, before, keys, include, false, readPreference, includeReadPreference, subqueryReadPreference, config, auth, info, selectedFields, parseGraphQLSchema.parseClasses); - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - - } - }); - } else if (parseClass.fields[field].type === 'Polygon') { - return _objectSpread(_objectSpread({}, fields), {}, { - [field]: { - description: `This is the object ${field}.`, - type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type, - - async resolve(source) { - if (source[field] && source[field].coordinates) { - return source[field].coordinates.map(coordinate => ({ - latitude: coordinate[0], - longitude: coordinate[1] - })); - } else { - return null; - } - } - - } - }); - } else if (parseClass.fields[field].type === 'Array') { - return _objectSpread(_objectSpread({}, fields), {}, { - [field]: { - description: `Use Inline Fragment on Array to get results: https://graphql.org/learn/queries/#inline-fragments`, - type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type, - - async resolve(source) { - if (!source[field]) return null; - return source[field].map(async elem => { - if (elem.className && elem.objectId && elem.__type === 'Object') { - return elem; - } else { - return { - value: elem - }; - } - }); - } - - } - }); - } else if (type) { - return _objectSpread(_objectSpread({}, fields), {}, { - [field]: { - description: `This is the object ${field}.`, - type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type - } - }); - } else { - return fields; - } - }, parseObjectFields); - }; - - let classGraphQLOutputType = new _graphql.GraphQLObjectType({ - name: classGraphQLOutputTypeName, - description: `The ${classGraphQLOutputTypeName} object type is used in operations that involve outputting objects of ${graphQLClassName} class.`, - interfaces, - fields: outputFields - }); - classGraphQLOutputType = parseGraphQLSchema.addGraphQLType(classGraphQLOutputType); - const { - connectionType, - edgeType - } = (0, _graphqlRelay.connectionDefinitions)({ - name: graphQLClassName, - connectionFields: { - count: defaultGraphQLTypes.COUNT_ATT - }, - nodeType: classGraphQLOutputType || defaultGraphQLTypes.OBJECT - }); - let classGraphQLFindResultType = undefined; - - if (parseGraphQLSchema.addGraphQLType(edgeType) && parseGraphQLSchema.addGraphQLType(connectionType, false, false, true)) { - classGraphQLFindResultType = connectionType; - } - - parseGraphQLSchema.parseClassTypes[className] = { - classGraphQLPointerType, - classGraphQLRelationType, - classGraphQLCreateType, - classGraphQLUpdateType, - classGraphQLConstraintsType, - classGraphQLRelationConstraintsType, - classGraphQLFindArgs, - classGraphQLOutputType, - classGraphQLFindResultType, - config: { - parseClassConfig, - isCreateEnabled, - isUpdateEnabled - } - }; - - if (className === '_User') { - const viewerType = new _graphql.GraphQLObjectType({ - name: 'Viewer', - description: `The Viewer object type is used in operations that involve outputting the current user data.`, - fields: () => ({ - sessionToken: defaultGraphQLTypes.SESSION_TOKEN_ATT, - user: { - description: 'This is the current user.', - type: new _graphql.GraphQLNonNull(classGraphQLOutputType) - } - }) - }); - parseGraphQLSchema.addGraphQLType(viewerType, true, true); - parseGraphQLSchema.viewerType = viewerType; - } -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvcGFyc2VDbGFzc1R5cGVzLmpzIl0sIm5hbWVzIjpbImdldFBhcnNlQ2xhc3NUeXBlQ29uZmlnIiwicGFyc2VDbGFzc0NvbmZpZyIsInR5cGUiLCJnZXRJbnB1dEZpZWxkc0FuZENvbnN0cmFpbnRzIiwicGFyc2VDbGFzcyIsImNsYXNzRmllbGRzIiwiT2JqZWN0Iiwia2V5cyIsImZpZWxkcyIsImNvbmNhdCIsImlucHV0RmllbGRzIiwiYWxsb3dlZElucHV0RmllbGRzIiwib3V0cHV0RmllbGRzIiwiYWxsb3dlZE91dHB1dEZpZWxkcyIsImNvbnN0cmFpbnRGaWVsZHMiLCJhbGxvd2VkQ29uc3RyYWludEZpZWxkcyIsInNvcnRGaWVsZHMiLCJhbGxvd2VkU29ydEZpZWxkcyIsImNsYXNzT3V0cHV0RmllbGRzIiwiY2xhc3NDcmVhdGVGaWVsZHMiLCJjbGFzc1VwZGF0ZUZpZWxkcyIsImNsYXNzQ29uc3RyYWludEZpZWxkcyIsImNsYXNzU29ydEZpZWxkcyIsImNsYXNzQ3VzdG9tRmllbGRzIiwiZmlsdGVyIiwiZmllbGQiLCJkZWZhdWx0R3JhcGhRTFR5cGVzIiwiUEFSU0VfT0JKRUNUX0ZJRUxEUyIsImluY2x1ZGVzIiwiY3JlYXRlIiwidXBkYXRlIiwiY2xhc3NOYW1lIiwib3V0cHV0RmllbGQiLCJsZW5ndGgiLCJwdXNoIiwiYXNjIiwiZGVzYyIsIm1hcCIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJncmFwaFFMQ2xhc3NOYW1lIiwiaXNDcmVhdGVFbmFibGVkIiwiaXNVcGRhdGVFbmFibGVkIiwiY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZU5hbWUiLCJjbGFzc0dyYXBoUUxDcmVhdGVUeXBlIiwiR3JhcGhRTElucHV0T2JqZWN0VHlwZSIsIm5hbWUiLCJkZXNjcmlwdGlvbiIsInJlZHVjZSIsInRhcmdldENsYXNzIiwicGFyc2VDbGFzc1R5cGVzIiwicmVxdWlyZWQiLCJHcmFwaFFMTm9uTnVsbCIsIkFDTCIsIkFDTF9JTlBVVCIsImFkZEdyYXBoUUxUeXBlIiwiY2xhc3NHcmFwaFFMVXBkYXRlVHlwZU5hbWUiLCJjbGFzc0dyYXBoUUxVcGRhdGVUeXBlIiwiY2xhc3NHcmFwaFFMUG9pbnRlclR5cGVOYW1lIiwiY2xhc3NHcmFwaFFMUG9pbnRlclR5cGUiLCJsaW5rIiwiR3JhcGhRTElEIiwiT0JKRUNUIiwiY2xhc3NHcmFwaFFMUmVsYXRpb25UeXBlTmFtZSIsImNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZSIsImFkZCIsIkdyYXBoUUxMaXN0IiwiT0JKRUNUX0lEIiwicmVtb3ZlIiwiY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlTmFtZSIsImNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSIsImxvZyIsIndhcm4iLCJwYXJzZUZpZWxkIiwiT1IiLCJBTkQiLCJOT1IiLCJjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZU5hbWUiLCJjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZSIsImhhdmUiLCJoYXZlTm90IiwiZXhpc3RzIiwiR3JhcGhRTEJvb2xlYW4iLCJjbGFzc0dyYXBoUUxPcmRlclR5cGVOYW1lIiwiY2xhc3NHcmFwaFFMT3JkZXJUeXBlIiwiR3JhcGhRTEVudW1UeXBlIiwidmFsdWVzIiwiZmllbGRDb25maWciLCJ1cGRhdGVkU29ydEZpZWxkcyIsInZhbHVlIiwiY2xhc3NHcmFwaFFMRmluZEFyZ3MiLCJ3aGVyZSIsIm9yZGVyIiwiR3JhcGhRTFN0cmluZyIsInNraXAiLCJTS0lQX0FUVCIsImNvbm5lY3Rpb25BcmdzIiwib3B0aW9ucyIsIlJFQURfT1BUSU9OU19BVFQiLCJjbGFzc0dyYXBoUUxPdXRwdXRUeXBlTmFtZSIsImludGVyZmFjZXMiLCJQQVJTRV9PQkpFQ1QiLCJyZWxheU5vZGVJbnRlcmZhY2UiLCJwYXJzZU9iamVjdEZpZWxkcyIsImlkIiwib2JqIiwib2JqZWN0SWQiLCJ0YXJnZXRQYXJzZUNsYXNzVHlwZXMiLCJhcmdzIiwidW5kZWZpbmVkIiwicmVzb2x2ZSIsInNvdXJjZSIsImNvbnRleHQiLCJxdWVyeUluZm8iLCJmaXJzdCIsImFmdGVyIiwibGFzdCIsImJlZm9yZSIsInJlYWRQcmVmZXJlbmNlIiwiaW5jbHVkZVJlYWRQcmVmZXJlbmNlIiwic3VicXVlcnlSZWFkUHJlZmVyZW5jZSIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwic2VsZWN0ZWRGaWVsZHMiLCJpbmNsdWRlIiwic3RhcnRzV2l0aCIsInJlcGxhY2UiLCJwYXJzZU9yZGVyIiwiam9pbiIsIm9iamVjdHNRdWVyaWVzIiwiZmluZE9iamVjdHMiLCIkcmVsYXRlZFRvIiwib2JqZWN0IiwiX190eXBlIiwia2V5IiwicGFyc2VDbGFzc2VzIiwiZSIsImhhbmRsZUVycm9yIiwiY29vcmRpbmF0ZXMiLCJjb29yZGluYXRlIiwibGF0aXR1ZGUiLCJsb25naXR1ZGUiLCJlbGVtIiwiY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSIsIkdyYXBoUUxPYmplY3RUeXBlIiwiY29ubmVjdGlvblR5cGUiLCJlZGdlVHlwZSIsImNvbm5lY3Rpb25GaWVsZHMiLCJjb3VudCIsIkNPVU5UX0FUVCIsIm5vZGVUeXBlIiwiY2xhc3NHcmFwaFFMRmluZFJlc3VsdFR5cGUiLCJ2aWV3ZXJUeXBlIiwic2Vzc2lvblRva2VuIiwiU0VTU0lPTl9UT0tFTl9BVFQiLCJ1c2VyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBQUE7O0FBVUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FBRUEsTUFBTUEsdUJBQXVCLEdBQUcsVUFBVUMsZ0JBQVYsRUFBc0Q7QUFDcEYsU0FBUUEsZ0JBQWdCLElBQUlBLGdCQUFnQixDQUFDQyxJQUF0QyxJQUErQyxFQUF0RDtBQUNELENBRkQ7O0FBSUEsTUFBTUMsNEJBQTRCLEdBQUcsVUFDbkNDLFVBRG1DLEVBRW5DSCxnQkFGbUMsRUFHbkM7QUFDQSxRQUFNSSxXQUFXLEdBQUdDLE1BQU0s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QixDQUFDVyxlQUFuQixDQUFtQ25CLFNBQW5DLElBQWdEO0FBQzlDNEIsSUFBQUEsdUJBRDhDO0FBRTlDSyxJQUFBQSx3QkFGOEM7QUFHOUNwQixJQUFBQSxzQkFIOEM7QUFJOUNhLElBQUFBLHNCQUo4QztBQUs5Q2EsSUFBQUEsMkJBTDhDO0FBTTlDUSxJQUFBQSxtQ0FOOEM7QUFPOUNZLElBQUFBLG9CQVA4QztBQVE5Q3NELElBQUFBLHNCQVI4QztBQVM5Q1EsSUFBQUEsMEJBVDhDO0FBVTlDL0IsSUFBQUEsTUFBTSxFQUFFO0FBQ054SCxNQUFBQSxnQkFETTtBQUVOd0MsTUFBQUEsZUFGTTtBQUdOQyxNQUFBQTtBQUhNO0FBVnNDLEdBQWhEOztBQWlCQSxNQUFJWCxTQUFTLEtBQUssT0FBbEIsRUFBMkI7QUFDekIsVUFBTTBILFVBQVUsR0FBRyxJQUFJUiwwQkFBSixDQUFzQjtBQUN2Q25HLE1BQUFBLElBQUksRUFBRSxRQURpQztBQUV2Q0MsTUFBQUEsV0FBVyxFQUFHLDZGQUZ5QjtBQUd2Q3ZDLE1BQUFBLE1BQU0sRUFBRSxPQUFPO0FBQ2JrSixRQUFBQSxZQUFZLEVBQUVoSSxtQkFBbUIsQ0FBQ2lJLGlCQURyQjtBQUViQyxRQUFBQSxJQUFJLEVBQUU7QUFDSjdHLFVBQUFBLFdBQVcsRUFBRSwyQkFEVDtBQUVKN0MsVUFBQUEsSUFBSSxFQUFFLElBQUlrRCx1QkFBSixDQUFtQjRGLHNCQUFuQjtBQUZGO0FBRk8sT0FBUDtBQUgrQixLQUF0QixDQUFuQjtBQVdBekcsSUFBQUEsa0JBQWtCLENBQUNnQixjQUFuQixDQUFrQ2tHLFVBQWxDLEVBQThDLElBQTlDLEVBQW9ELElBQXBEO0FBQ0FsSCxJQUFBQSxrQkFBa0IsQ0FBQ2tILFVBQW5CLEdBQWdDQSxVQUFoQztBQUNEO0FBQ0YsQ0FuYUQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBHcmFwaFFMSUQsXG4gIEdyYXBoUUxPYmplY3RUeXBlLFxuICBHcmFwaFFMU3RyaW5nLFxuICBHcmFwaFFMTGlzdCxcbiAgR3JhcGhRTElucHV0T2JqZWN0VHlwZSxcbiAgR3JhcGhRTE5vbk51bGwsXG4gIEdyYXBoUUxCb29sZWFuLFxuICBHcmFwaFFMRW51bVR5cGUsXG59IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgZ2xvYmFsSWRGaWVsZCwgY29ubmVjdGlvbkFyZ3MsIGNvbm5lY3Rpb25EZWZpbml0aW9ucyB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0IGdldEZpZWxkTmFtZXMgZnJvbSAnZ3JhcGhxbC1saXN0LWZpZWxkcyc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4vZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQgKiBhcyBvYmplY3RzUXVlcmllcyBmcm9tICcuLi9oZWxwZXJzL29iamVjdHNRdWVyaWVzJztcbmltcG9ydCB7IFBhcnNlR3JhcGhRTENsYXNzQ29uZmlnIH0gZnJvbSAnLi4vLi4vQ29udHJvbGxlcnMvUGFyc2VHcmFwaFFMQ29udHJvbGxlcic7XG5pbXBvcnQgeyB0cmFuc2Zvcm1DbGFzc05hbWVUb0dyYXBoUUwgfSBmcm9tICcuLi90cmFuc2Zvcm1lcnMvY2xhc3NOYW1lJztcbmltcG9ydCB7IHRyYW5zZm9ybUlucHV0VHlwZVRvR3JhcGhRTCB9IGZyb20gJy4uL3RyYW5zZm9ybWVycy9pbnB1dFR5cGUnO1xuaW1wb3J0IHsgdHJhbnNmb3JtT3V0cHV0VHlwZVRvR3JhcGhRTCB9IGZyb20gJy4uL3RyYW5zZm9ybWVycy9vdXRwdXRUeXBlJztcbmltcG9ydCB7IHRyYW5zZm9ybUNvbnN0cmFpbnRUeXBlVG9HcmFwaFFMIH0gZnJvbSAnLi4vdHJhbnNmb3JtZXJzL2NvbnN0cmFpbnRUeXBlJztcbmltcG9ydCB7IGV4dHJhY3RLZXlzQW5kSW5jbHVkZSwgZ2V0UGFyc2VDbGFzc011dGF0aW9uQ29uZmlnIH0gZnJvbSAnLi4vcGFyc2VHcmFwaFFMVXRpbHMnO1xuXG5jb25zdCBnZXRQYXJzZUNsYXNzVHlwZUNvbmZpZyA9IGZ1bmN0aW9uIChwYXJzZUNsYXNzQ29uZmlnOiA/UGFyc2VHcmFwaFFMQ2xhc3NDb25maWcpIHtcbiAgcmV0dXJuIChwYXJzZUNsYXNzQ29uZmlnICYmIHBhcnNlQ2xhc3NDb25maWcudHlwZSkgfHwge307XG59O1xuXG5jb25zdCBnZXRJbnB1dEZpZWxkc0FuZENvbnN0cmFpbnRzID0gZnVuY3Rpb24gKFxuICBwYXJzZUNsYXNzLFxuICBwYXJzZUNsYXNzQ29uZmlnOiA/UGFyc2VHcmFwaFFMQ2xhc3NDb25maWdcbikge1xuICBjb25zdCBjbGFzc0ZpZWxkcyA9IE9iamVjdC5rZXlzKHBhcnNlQ2xhc3MuZmllbGRzKS5jb25jYXQoJ2lkJyk7XG4gIGNvbnN0IHtcbiAgICBpbnB1dEZpZWxkczogYWxsb3dlZElucHV0RmllbGRzLFxuICAgIG91dHB1dEZpZWxkczogYWxsb3dlZE91dHB1dEZpZWxkcyxcbiAgICBjb25zdHJhaW50RmllbGRzOiBhbGxvd2VkQ29uc3RyYWludEZpZWxkcyxcbiAgICBzb3J0RmllbGRzOiBhbGxvd2VkU29ydEZpZWxkcyxcbiAgfSA9IGdldFBhcnNlQ2xhc3NUeXBlQ29uZmlnKHBhcnNlQ2xhc3NDb25maWcpO1xuXG4gIGxldCBjbGFzc091dHB1dEZpZWxkcztcbiAgbGV0IGNsYXNzQ3JlYXRlRmllbGRzO1xuICBsZXQgY2xhc3NVcGRhdGVGaWVsZHM7XG4gIGxldCBjbGFzc0NvbnN0cmFpbnRGaWVsZHM7XG4gIGxldCBjbGFzc1NvcnRGaWVsZHM7XG5cbiAgLy8gQWxsIGFsbG93ZWQgY3VzdG9tcyBmaWVsZHNcbiAgY29uc3QgY2xhc3NDdXN0b21GaWVsZHMgPSBjbGFzc0ZpZWxkcy5maWx0ZXIoZmllbGQgPT4ge1xuICAgIHJldHVybiAhT2JqZWN0LmtleXMoZGVmYXVsdEdyYXBoUUxUeXBlcy5QQVJTRV9PQkpFQ1RfRklFTERTKS5pbmNsdWRlcyhmaWVsZCkgJiYgZmllbGQgIT09ICdpZCc7XG4gIH0pO1xuXG4gIGlmIChhbGxvd2VkSW5wdXRGaWVsZHMgJiYgYWxsb3dlZElucHV0RmllbGRzLmNyZWF0ZSkge1xuICAgIGNsYXNzQ3JlYXRlRmllbGRzID0gY2xhc3NDdXN0b21GaWVsZHMuZmlsdGVyKGZpZWxkID0+IHtcbiAgICAgIHJldHVybiBhbGxvd2VkSW5wdXRGaWVsZHMuY3JlYXRlLmluY2x1ZGVzKGZpZWxkKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBjbGFzc0NyZWF0ZUZpZWxkcyA9IGNsYXNzQ3VzdG9tRmllbGRzO1xuICB9XG4gIGlmIChhbGxvd2VkSW5wdXRGaWVsZHMgJiYgYWxsb3dlZElucHV0RmllbGRzLnVwZGF0ZSkge1xuICAgIGNsYXNzVXBkYXRlRmllbGRzID0gY2xhc3NDdXN0b21GaWVsZHMuZmlsdGVyKGZpZWxkID0+IHtcbiAgICAgIHJldHVybiBhbGxvd2VkSW5wdXRGaWVsZHMudXBkYXRlLmluY2x1ZGVzKGZpZWxkKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBjbGFzc1VwZGF0ZUZpZWxkcyA9IGNsYXNzQ3VzdG9tRmllbGRzO1xuICB9XG5cbiAgaWYgKGFsbG93ZWRPdXRwdXRGaWVsZHMpIHtcbiAgICBjbGFzc091dHB1dEZpZWxkcyA9IGNsYXNzQ3VzdG9tRmllbGRzLmZpbHRlcihmaWVsZCA9PiB7XG4gICAgICByZXR1cm4gYWxsb3dlZE91dHB1dEZpZWxkcy5pbmNsdWRlcyhmaWVsZCk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgY2xhc3NPdXRwdXRGaWVsZHMgPSBjbGFzc0N1c3RvbUZpZWxkcztcbiAgfVxuICAvLyBGaWx0ZXJzIHRoZSBcInBhc3N3b3JkXCIgZmllbGQgZnJvbSBjbGFzcyBfVXNlclxuICBpZiAocGFyc2VDbGFzcy5jbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICBjbGFzc091dHB1dEZpZWxkcyA9IGNsYXNzT3V0cHV0RmllbGRzLmZpbHRlcihvdXRwdXRGaWVsZCA9PiBvdXRwdXRGaWVsZCAhPT0gJ3Bhc3N3b3JkJyk7XG4gIH1cblxuICBpZiAoYWxsb3dlZENvbnN0cmFpbnRGaWVsZHMpIHtcbiAgICBjbGFzc0NvbnN0cmFpbnRGaWVsZHMgPSBjbGFzc0N1c3RvbUZpZWxkcy5maWx0ZXIoZmllbGQgPT4ge1xuICAgICAgcmV0dXJuIGFsbG93ZWRDb25zdHJhaW50RmllbGRzLmluY2x1ZGVzKGZpZWxkKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBjbGFzc0NvbnN0cmFpbnRGaWVsZHMgPSBjbGFzc0ZpZWxkcztcbiAgfVxuXG4gIGlmIChhbGxvd2VkU29ydEZpZWxkcykge1xuICAgIGNsYXNzU29ydEZpZWxkcyA9IGFsbG93ZWRTb3J0RmllbGRzO1xuICAgIGlmICghY2xhc3NTb3J0RmllbGRzLmxlbmd0aCkge1xuICAgICAgLy8gbXVzdCBoYXZlIGF0IGxlYXN0IDEgb3JkZXIgZmllbGRcbiAgICAgIC8vIG90aGVyd2lzZSB0aGUgRmluZEFyZ3MgSW5wdXQgVHlwZSB3aWxsIHRocm93LlxuICAgICAgY2xhc3NTb3J0RmllbGRzLnB1c2goe1xuICAgICAgICBmaWVsZDogJ2lkJyxcbiAgICAgICAgYXNjOiB0cnVlLFxuICAgICAgICBkZXNjOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGNsYXNzU29ydEZpZWxkcyA9IGNsYXNzRmllbGRzLm1hcChmaWVsZCA9PiB7XG4gICAgICByZXR1cm4geyBmaWVsZCwgYXNjOiB0cnVlLCBkZXNjOiB0cnVlIH07XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGNsYXNzQ3JlYXRlRmllbGRzLFxuICAgIGNsYXNzVXBkYXRlRmllbGRzLFxuICAgIGNsYXNzQ29uc3RyYWludEZpZWxkcyxcbiAgICBjbGFzc091dHB1dEZpZWxkcyxcbiAgICBjbGFzc1NvcnRGaWVsZHMsXG4gIH07XG59O1xuXG5jb25zdCBsb2FkID0gKHBhcnNlR3JhcGhRTFNjaGVtYSwgcGFyc2VDbGFzcywgcGFyc2VDbGFzc0NvbmZpZzogP1BhcnNlR3JhcGhRTENsYXNzQ29uZmlnKSA9PiB7XG4gIGNvbnN0IGNsYXNzTmFtZSA9IHBhcnNlQ2xhc3MuY2xhc3NOYW1lO1xuICBjb25zdCBncmFwaFFMQ2xhc3NOYW1lID0gdHJhbnNmb3JtQ2xhc3NOYW1lVG9HcmFwaFFMKGNsYXNzTmFtZSk7XG4gIGNvbnN0IHtcbiAgICBjbGFzc0NyZWF0ZUZpZWxkcyxcbiAgICBjbGFzc1VwZGF0ZUZpZWxkcyxcbiAgICBjbGFzc091dHB1dEZpZWxkcyxcbiAgICBjbGFzc0NvbnN0cmFpbnRGaWVsZHMsXG4gICAgY2xhc3NTb3J0RmllbGRzLFxuICB9ID0gZ2V0SW5wdXRGaWVsZHNBbmRDb25zdHJhaW50cyhwYXJzZUNsYXNzLCBwYXJzZUNsYXNzQ29uZmlnKTtcblxuICBjb25zdCB7XG4gICAgY3JlYXRlOiBpc0NyZWF0ZUVuYWJsZWQgPSB0cnVlLFxuICAgIHVwZGF0ZTogaXNVcGRhdGVFbmFibGVkID0gdHJ1ZSxcbiAgfSA9IGdldFBhcnNlQ2xhc3NNdXRhdGlvbkNvbmZpZyhwYXJzZUNsYXNzQ29uZmlnKTtcblxuICBjb25zdCBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlTmFtZSA9IGBDcmVhdGUke2dyYXBoUUxDbGFzc05hbWV9RmllbGRzSW5wdXRgO1xuICBsZXQgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgICBuYW1lOiBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlTmFtZSxcbiAgICBkZXNjcmlwdGlvbjogYFRoZSAke2NsYXNzR3JhcGhRTENyZWF0ZVR5cGVOYW1lfSBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgY3JlYXRpb24gb2Ygb2JqZWN0cyBpbiB0aGUgJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgIGZpZWxkczogKCkgPT5cbiAgICAgIGNsYXNzQ3JlYXRlRmllbGRzLnJlZHVjZShcbiAgICAgICAgKGZpZWxkcywgZmllbGQpID0+IHtcbiAgICAgICAgICBjb25zdCB0eXBlID0gdHJhbnNmb3JtSW5wdXRUeXBlVG9HcmFwaFFMKFxuICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnR5cGUsXG4gICAgICAgICAgICBwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0udGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAodHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgLi4uZmllbGRzLFxuICAgICAgICAgICAgICBbZmllbGRdOiB7XG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IGBUaGlzIGlzIHRoZSBvYmplY3QgJHtmaWVsZH0uYCxcbiAgICAgICAgICAgICAgICB0eXBlOlxuICAgICAgICAgICAgICAgICAgKGNsYXNzTmFtZSA9PT0gJ19Vc2VyJyAmJiAoZmllbGQgPT09ICd1c2VybmFtZScgfHwgZmllbGQgPT09ICdwYXNzd29yZCcpKSB8fFxuICAgICAgICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnJlcXVpcmVkXG4gICAgICAgICAgICAgICAgICAgID8gbmV3IEdyYXBoUUxOb25OdWxsKHR5cGUpXG4gICAgICAgICAgICAgICAgICAgIDogdHlwZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmaWVsZHM7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgQUNMOiB7IHR5cGU6IGRlZmF1bHRHcmFwaFFMVHlwZXMuQUNMX0lOUFVUIH0sXG4gICAgICAgIH1cbiAgICAgICksXG4gIH0pO1xuICBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlID0gcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNsYXNzR3JhcGhRTENyZWF0ZVR5cGUpO1xuXG4gIGNvbnN0IGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGVOYW1lID0gYFVwZGF0ZSR7Z3JhcGhRTENsYXNzTmFtZX1GaWVsZHNJbnB1dGA7XG4gIGxldCBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICAgIG5hbWU6IGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGVOYW1lLFxuICAgIGRlc2NyaXB0aW9uOiBgVGhlICR7Y2xhc3NHcmFwaFFMVXBkYXRlVHlwZU5hbWV9IGlucHV0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBjcmVhdGlvbiBvZiBvYmplY3RzIGluIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLmAsXG4gICAgZmllbGRzOiAoKSA9PlxuICAgICAgY2xhc3NVcGRhdGVGaWVsZHMucmVkdWNlKFxuICAgICAgICAoZmllbGRzLCBmaWVsZCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHR5cGUgPSB0cmFuc2Zvcm1JbnB1dFR5cGVUb0dyYXBoUUwoXG4gICAgICAgICAgICBwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0udHlwZSxcbiAgICAgICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50YXJnZXRDbGFzcyxcbiAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzVHlwZXNcbiAgICAgICAgICApO1xuICAgICAgICAgIGlmICh0eXBlKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAuLi5maWVsZHMsXG4gICAgICAgICAgICAgIFtmaWVsZF06IHtcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogYFRoaXMgaXMgdGhlIG9iamVjdCAke2ZpZWxkfS5gLFxuICAgICAgICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZmllbGRzO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIEFDTDogeyB0eXBlOiBkZWZhdWx0R3JhcGhRTFR5cGVzLkFDTF9JTlBVVCB9LFxuICAgICAgICB9XG4gICAgICApLFxuICB9KTtcbiAgY2xhc3NHcmFwaFFMVXBkYXRlVHlwZSA9IHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjbGFzc0dyYXBoUUxVcGRhdGVUeXBlKTtcblxuICBjb25zdCBjbGFzc0dyYXBoUUxQb2ludGVyVHlwZU5hbWUgPSBgJHtncmFwaFFMQ2xhc3NOYW1lfVBvaW50ZXJJbnB1dGA7XG4gIGxldCBjbGFzc0dyYXBoUUxQb2ludGVyVHlwZSA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgICBuYW1lOiBjbGFzc0dyYXBoUUxQb2ludGVyVHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBBbGxvdyB0byBsaW5rIE9SIGFkZCBhbmQgbGluayBhbiBvYmplY3Qgb2YgdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuYCxcbiAgICBmaWVsZHM6ICgpID0+IHtcbiAgICAgIGNvbnN0IGZpZWxkcyA9IHtcbiAgICAgICAgbGluazoge1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiBgTGluayBhbiBleGlzdGluZyBvYmplY3QgZnJvbSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLiBZb3UgY2FuIHVzZSBlaXRoZXIgdGhlIGdsb2JhbCBvciB0aGUgb2JqZWN0IGlkLmAsXG4gICAgICAgICAgdHlwZTogR3JhcGhRTElELFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGlmIChpc0NyZWF0ZUVuYWJsZWQpIHtcbiAgICAgICAgZmllbGRzWydjcmVhdGVBbmRMaW5rJ10gPSB7XG4gICAgICAgICAgZGVzY3JpcHRpb246IGBDcmVhdGUgYW5kIGxpbmsgYW4gb2JqZWN0IGZyb20gJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgICAgICAgIHR5cGU6IGNsYXNzR3JhcGhRTENyZWF0ZVR5cGUsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gZmllbGRzO1xuICAgIH0sXG4gIH0pO1xuICBjbGFzc0dyYXBoUUxQb2ludGVyVHlwZSA9XG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNsYXNzR3JhcGhRTFBvaW50ZXJUeXBlKSB8fCBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVDtcblxuICBjb25zdCBjbGFzc0dyYXBoUUxSZWxhdGlvblR5cGVOYW1lID0gYCR7Z3JhcGhRTENsYXNzTmFtZX1SZWxhdGlvbklucHV0YDtcbiAgbGV0IGNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZSA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgICBuYW1lOiBjbGFzc0dyYXBoUUxSZWxhdGlvblR5cGVOYW1lLFxuICAgIGRlc2NyaXB0aW9uOiBgQWxsb3cgdG8gYWRkLCByZW1vdmUsIGNyZWF0ZUFuZEFkZCBvYmplY3RzIG9mIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzIGludG8gYSByZWxhdGlvbiBmaWVsZC5gLFxuICAgIGZpZWxkczogKCkgPT4ge1xuICAgICAgY29uc3QgZmllbGRzID0ge1xuICAgICAgICBhZGQ6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogYEFkZCBleGlzdGluZyBvYmplY3RzIGZyb20gdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MgaW50byB0aGUgcmVsYXRpb24uIFlvdSBjYW4gdXNlIGVpdGhlciB0aGUgZ2xvYmFsIG9yIHRoZSBvYmplY3QgaWRzLmAsXG4gICAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUX0lEKSxcbiAgICAgICAgfSxcbiAgICAgICAgcmVtb3ZlOiB7XG4gICAgICAgICAgZGVzY3JpcHRpb246IGBSZW1vdmUgZXhpc3Rpbmcgb2JqZWN0cyBmcm9tIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzIG91dCBvZiB0aGUgcmVsYXRpb24uIFlvdSBjYW4gdXNlIGVpdGhlciB0aGUgZ2xvYmFsIG9yIHRoZSBvYmplY3QgaWRzLmAsXG4gICAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUX0lEKSxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICBpZiAoaXNDcmVhdGVFbmFibGVkKSB7XG4gICAgICAgIGZpZWxkc1snY3JlYXRlQW5kQWRkJ10gPSB7XG4gICAgICAgICAgZGVzY3JpcHRpb246IGBDcmVhdGUgYW5kIGFkZCBvYmplY3RzIG9mIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzIGludG8gdGhlIHJlbGF0aW9uLmAsXG4gICAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxDcmVhdGVUeXBlKSksXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gZmllbGRzO1xuICAgIH0sXG4gIH0pO1xuICBjbGFzc0dyYXBoUUxSZWxhdGlvblR5cGUgPVxuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjbGFzc0dyYXBoUUxSZWxhdGlvblR5cGUpIHx8IGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUO1xuXG4gIGNvbnN0IGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZU5hbWUgPSBgJHtncmFwaFFMQ2xhc3NOYW1lfVdoZXJlSW5wdXRgO1xuICBsZXQgY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICAgIG5hbWU6IGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBUaGUgJHtjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGVOYW1lfSBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIG9iamVjdHMgb2YgJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgIGZpZWxkczogKCkgPT4gKHtcbiAgICAgIC4uLmNsYXNzQ29uc3RyYWludEZpZWxkcy5yZWR1Y2UoKGZpZWxkcywgZmllbGQpID0+IHtcbiAgICAgICAgaWYgKFsnT1InLCAnQU5EJywgJ05PUiddLmluY2x1ZGVzKGZpZWxkKSkge1xuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5sb2cud2FybihcbiAgICAgICAgICAgIGBGaWVsZCAke2ZpZWxkfSBjb3VsZCBub3QgYmUgYWRkZWQgdG8gdGhlIGF1dG8gc2NoZW1hICR7Y2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlTmFtZX0gYmVjYXVzZSBpdCBjb2xsaWRlZCB3aXRoIGFuIGV4aXN0aW5nIG9uZS5gXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4gZmllbGRzO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhcnNlRmllbGQgPSBmaWVsZCA9PT0gJ2lkJyA/ICdvYmplY3RJZCcgOiBmaWVsZDtcbiAgICAgICAgY29uc3QgdHlwZSA9IHRyYW5zZm9ybUNvbnN0cmFpbnRUeXBlVG9HcmFwaFFMKFxuICAgICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzW3BhcnNlRmllbGRdLnR5cGUsXG4gICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbcGFyc2VGaWVsZF0udGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlcyxcbiAgICAgICAgICBmaWVsZFxuICAgICAgICApO1xuICAgICAgICBpZiAodHlwZSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAuLi5maWVsZHMsXG4gICAgICAgICAgICBbZmllbGRdOiB7XG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgVGhpcyBpcyB0aGUgb2JqZWN0ICR7ZmllbGR9LmAsXG4gICAgICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIGZpZWxkcztcbiAgICAgICAgfVxuICAgICAgfSwge30pLFxuICAgICAgT1I6IHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBPUiBvcGVyYXRvciB0byBjb21wb3VuZCBjb25zdHJhaW50cy4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSkpLFxuICAgICAgfSxcbiAgICAgIEFORDoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIEFORCBvcGVyYXRvciB0byBjb21wb3VuZCBjb25zdHJhaW50cy4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSkpLFxuICAgICAgfSxcbiAgICAgIE5PUjoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIE5PUiBvcGVyYXRvciB0byBjb21wb3VuZCBjb25zdHJhaW50cy4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSkpLFxuICAgICAgfSxcbiAgICB9KSxcbiAgfSk7XG4gIGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSA9XG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSkgfHwgZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1Q7XG5cbiAgY29uc3QgY2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGVOYW1lID0gYCR7Z3JhcGhRTENsYXNzTmFtZX1SZWxhdGlvbldoZXJlSW5wdXRgO1xuICBsZXQgY2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGUgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gICAgbmFtZTogY2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGVOYW1lLFxuICAgIGRlc2NyaXB0aW9uOiBgVGhlICR7Y2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGVOYW1lfSBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgZmlsdGVyaW5nIG9iamVjdHMgb2YgJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgIGZpZWxkczogKCkgPT4gKHtcbiAgICAgIGhhdmU6IHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdSdW4gYSByZWxhdGlvbmFsL3BvaW50ZXIgcXVlcnkgd2hlcmUgYXQgbGVhc3Qgb25lIGNoaWxkIG9iamVjdCBjYW4gbWF0Y2guJyxcbiAgICAgICAgdHlwZTogY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlLFxuICAgICAgfSxcbiAgICAgIGhhdmVOb3Q6IHtcbiAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgJ1J1biBhbiBpbnZlcnRlZCByZWxhdGlvbmFsL3BvaW50ZXIgcXVlcnkgd2hlcmUgYXQgbGVhc3Qgb25lIGNoaWxkIG9iamVjdCBjYW4gbWF0Y2guJyxcbiAgICAgICAgdHlwZTogY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlLFxuICAgICAgfSxcbiAgICAgIGV4aXN0czoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ0NoZWNrIGlmIHRoZSByZWxhdGlvbi9wb2ludGVyIGNvbnRhaW5zIG9iamVjdHMuJyxcbiAgICAgICAgdHlwZTogR3JhcGhRTEJvb2xlYW4sXG4gICAgICB9LFxuICAgIH0pLFxuICB9KTtcbiAgY2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGUgPVxuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZSkgfHxcbiAgICBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVDtcblxuICBjb25zdCBjbGFzc0dyYXBoUUxPcmRlclR5cGVOYW1lID0gYCR7Z3JhcGhRTENsYXNzTmFtZX1PcmRlcmA7XG4gIGxldCBjbGFzc0dyYXBoUUxPcmRlclR5cGUgPSBuZXcgR3JhcGhRTEVudW1UeXBlKHtcbiAgICBuYW1lOiBjbGFzc0dyYXBoUUxPcmRlclR5cGVOYW1lLFxuICAgIGRlc2NyaXB0aW9uOiBgVGhlICR7Y2xhc3NHcmFwaFFMT3JkZXJUeXBlTmFtZX0gaW5wdXQgdHlwZSBpcyB1c2VkIHdoZW4gc29ydGluZyBvYmplY3RzIG9mIHRoZSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLmAsXG4gICAgdmFsdWVzOiBjbGFzc1NvcnRGaWVsZHMucmVkdWNlKChzb3J0RmllbGRzLCBmaWVsZENvbmZpZykgPT4ge1xuICAgICAgY29uc3QgeyBmaWVsZCwgYXNjLCBkZXNjIH0gPSBmaWVsZENvbmZpZztcbiAgICAgIGNvbnN0IHVwZGF0ZWRTb3J0RmllbGRzID0ge1xuICAgICAgICAuLi5zb3J0RmllbGRzLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHZhbHVlID0gZmllbGQgPT09ICdpZCcgPyAnb2JqZWN0SWQnIDogZmllbGQ7XG4gICAgICBpZiAoYXNjKSB7XG4gICAgICAgIHVwZGF0ZWRTb3J0RmllbGRzW2Ake2ZpZWxkfV9BU0NgXSA9IHsgdmFsdWUgfTtcbiAgICAgIH1cbiAgICAgIGlmIChkZXNjKSB7XG4gICAgICAgIHVwZGF0ZWRTb3J0RmllbGRzW2Ake2ZpZWxkfV9ERVNDYF0gPSB7IHZhbHVlOiBgLSR7dmFsdWV9YCB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHVwZGF0ZWRTb3J0RmllbGRzO1xuICAgIH0sIHt9KSxcbiAgfSk7XG4gIGNsYXNzR3JhcGhRTE9yZGVyVHlwZSA9IHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjbGFzc0dyYXBoUUxPcmRlclR5cGUpO1xuXG4gIGNvbnN0IGNsYXNzR3JhcGhRTEZpbmRBcmdzID0ge1xuICAgIHdoZXJlOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZXNlIGFyZSB0aGUgY29uZGl0aW9ucyB0aGF0IHRoZSBvYmplY3RzIG5lZWQgdG8gbWF0Y2ggaW4gb3JkZXIgdG8gYmUgZm91bmQuJyxcbiAgICAgIHR5cGU6IGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSxcbiAgICB9LFxuICAgIG9yZGVyOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSBmaWVsZHMgdG8gYmUgdXNlZCB3aGVuIHNvcnRpbmcgdGhlIGRhdGEgZmV0Y2hlZC4nLFxuICAgICAgdHlwZTogY2xhc3NHcmFwaFFMT3JkZXJUeXBlXG4gICAgICAgID8gbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxPcmRlclR5cGUpKVxuICAgICAgICA6IEdyYXBoUUxTdHJpbmcsXG4gICAgfSxcbiAgICBza2lwOiBkZWZhdWx0R3JhcGhRTFR5cGVzLlNLSVBfQVRULFxuICAgIC4uLmNvbm5lY3Rpb25BcmdzLFxuICAgIG9wdGlvbnM6IGRlZmF1bHRHcmFwaFFMVHlwZXMuUkVBRF9PUFRJT05TX0FUVCxcbiAgfTtcbiAgY29uc3QgY2xhc3NHcmFwaFFMT3V0cHV0VHlwZU5hbWUgPSBgJHtncmFwaFFMQ2xhc3NOYW1lfWA7XG4gIGNvbnN0IGludGVyZmFjZXMgPSBbZGVmYXVsdEdyYXBoUUxUeXBlcy5QQVJTRV9PQkpFQ1QsIHBhcnNlR3JhcGhRTFNjaGVtYS5yZWxheU5vZGVJbnRlcmZhY2VdO1xuICBjb25zdCBwYXJzZU9iamVjdEZpZWxkcyA9IHtcbiAgICBpZDogZ2xvYmFsSWRGaWVsZChjbGFzc05hbWUsIG9iaiA9PiBvYmoub2JqZWN0SWQpLFxuICAgIC4uLmRlZmF1bHRHcmFwaFFMVHlwZXMuUEFSU0VfT0JKRUNUX0ZJRUxEUyxcbiAgfTtcbiAgY29uc3Qgb3V0cHV0RmllbGRzID0gKCkgPT4ge1xuICAgIHJldHVybiBjbGFzc091dHB1dEZpZWxkcy5yZWR1Y2UoKGZpZWxkcywgZmllbGQpID0+IHtcbiAgICAgIGNvbnN0IHR5cGUgPSB0cmFuc2Zvcm1PdXRwdXRUeXBlVG9HcmFwaFFMKFxuICAgICAgICBwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0udHlwZSxcbiAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnRhcmdldENsYXNzLFxuICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzXG4gICAgICApO1xuICAgICAgaWYgKHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgIGNvbnN0IHRhcmdldFBhcnNlQ2xhc3NUeXBlcyA9XG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1twYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0udGFyZ2V0Q2xhc3NdO1xuICAgICAgICBjb25zdCBhcmdzID0gdGFyZ2V0UGFyc2VDbGFzc1R5cGVzID8gdGFyZ2V0UGFyc2VDbGFzc1R5cGVzLmNsYXNzR3JhcGhRTEZpbmRBcmdzIDogdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLmZpZWxkcyxcbiAgICAgICAgICBbZmllbGRdOiB7XG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogYFRoaXMgaXMgdGhlIG9iamVjdCAke2ZpZWxkfS5gLFxuICAgICAgICAgICAgYXJncyxcbiAgICAgICAgICAgIHR5cGU6IHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS5yZXF1aXJlZCA/IG5ldyBHcmFwaFFMTm9uTnVsbCh0eXBlKSA6IHR5cGUsXG4gICAgICAgICAgICBhc3luYyByZXNvbHZlKHNvdXJjZSwgYXJncywgY29udGV4dCwgcXVlcnlJbmZvKSB7XG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgeyB3aGVyZSwgb3JkZXIsIHNraXAsIGZpcnN0LCBhZnRlciwgbGFzdCwgYmVmb3JlLCBvcHRpb25zIH0gPSBhcmdzO1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgcmVhZFByZWZlcmVuY2UsIGluY2x1ZGVSZWFkUHJlZmVyZW5jZSwgc3VicXVlcnlSZWFkUHJlZmVyZW5jZSB9ID1cbiAgICAgICAgICAgICAgICAgIG9wdGlvbnMgfHwge307XG4gICAgICAgICAgICAgICAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2VsZWN0ZWRGaWVsZHMgPSBnZXRGaWVsZE5hbWVzKHF1ZXJ5SW5mbyk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCB7IGtleXMsIGluY2x1ZGUgfSA9IGV4dHJhY3RLZXlzQW5kSW5jbHVkZShcbiAgICAgICAgICAgICAgICAgIHNlbGVjdGVkRmllbGRzXG4gICAgICAgICAgICAgICAgICAgIC5maWx0ZXIoZmllbGQgPT4gZmllbGQuc3RhcnRzV2l0aCgnZWRnZXMubm9kZS4nKSlcbiAgICAgICAgICAgICAgICAgICAgLm1hcChmaWVsZCA9PiBmaWVsZC5yZXBsYWNlKCdlZGdlcy5ub2RlLicsICcnKSlcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcnNlT3JkZXIgPSBvcmRlciAmJiBvcmRlci5qb2luKCcsJyk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0c1F1ZXJpZXMuZmluZE9iamVjdHMoXG4gICAgICAgICAgICAgICAgICBzb3VyY2VbZmllbGRdLmNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgJHJlbGF0ZWRUbzoge1xuICAgICAgICAgICAgICAgICAgICAgIG9iamVjdDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdElkOiBzb3VyY2Uub2JqZWN0SWQsXG4gICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICBrZXk6IGZpZWxkLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAuLi4od2hlcmUgfHwge30pLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHBhcnNlT3JkZXIsXG4gICAgICAgICAgICAgICAgICBza2lwLFxuICAgICAgICAgICAgICAgICAgZmlyc3QsXG4gICAgICAgICAgICAgICAgICBhZnRlcixcbiAgICAgICAgICAgICAgICAgIGxhc3QsXG4gICAgICAgICAgICAgICAgICBiZWZvcmUsXG4gICAgICAgICAgICAgICAgICBrZXlzLFxuICAgICAgICAgICAgICAgICAgaW5jbHVkZSxcbiAgICAgICAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICAgICAgICBpbmNsdWRlUmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgICAgICAgICBzdWJxdWVyeVJlYWRQcmVmZXJlbmNlLFxuICAgICAgICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgICAgICAgIGluZm8sXG4gICAgICAgICAgICAgICAgICBzZWxlY3RlZEZpZWxkcyxcbiAgICAgICAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzZXNcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9IGVsc2UgaWYgKHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnUG9seWdvbicpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5maWVsZHMsXG4gICAgICAgICAgW2ZpZWxkXToge1xuICAgICAgICAgICAgZGVzY3JpcHRpb246IGBUaGlzIGlzIHRoZSBvYmplY3QgJHtmaWVsZH0uYCxcbiAgICAgICAgICAgIHR5cGU6IHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS5yZXF1aXJlZCA/IG5ldyBHcmFwaFFMTm9uTnVsbCh0eXBlKSA6IHR5cGUsXG4gICAgICAgICAgICBhc3luYyByZXNvbHZlKHNvdXJjZSkge1xuICAgICAgICAgICAgICBpZiAoc291cmNlW2ZpZWxkXSAmJiBzb3VyY2VbZmllbGRdLmNvb3JkaW5hdGVzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNvdXJjZVtmaWVsZF0uY29vcmRpbmF0ZXMubWFwKGNvb3JkaW5hdGUgPT4gKHtcbiAgICAgICAgICAgICAgICAgIGxhdGl0dWRlOiBjb29yZGluYXRlWzBdLFxuICAgICAgICAgICAgICAgICAgbG9uZ2l0dWRlOiBjb29yZGluYXRlWzFdLFxuICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIGlmIChwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0udHlwZSA9PT0gJ0FycmF5Jykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLmZpZWxkcyxcbiAgICAgICAgICBbZmllbGRdOiB7XG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogYFVzZSBJbmxpbmUgRnJhZ21lbnQgb24gQXJyYXkgdG8gZ2V0IHJlc3VsdHM6IGh0dHBzOi8vZ3JhcGhxbC5vcmcvbGVhcm4vcXVlcmllcy8jaW5saW5lLWZyYWdtZW50c2AsXG4gICAgICAgICAgICB0eXBlOiBwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0ucmVxdWlyZWQgPyBuZXcgR3JhcGhRTE5vbk51bGwodHlwZSkgOiB0eXBlLFxuICAgICAgICAgICAgYXN5bmMgcmVzb2x2ZShzb3VyY2UpIHtcbiAgICAgICAgICAgICAgaWYgKCFzb3VyY2VbZmllbGRdKSByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgcmV0dXJuIHNvdXJjZVtmaWVsZF0ubWFwKGFzeW5jIGVsZW0gPT4ge1xuICAgICAgICAgICAgICAgIGlmIChlbGVtLmNsYXNzTmFtZSAmJiBlbGVtLm9iamVjdElkICYmIGVsZW0uX190eXBlID09PSAnT2JqZWN0Jykge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIGVsZW07XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiB7IHZhbHVlOiBlbGVtIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLmZpZWxkcyxcbiAgICAgICAgICBbZmllbGRdOiB7XG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogYFRoaXMgaXMgdGhlIG9iamVjdCAke2ZpZWxkfS5gLFxuICAgICAgICAgICAgdHlwZTogcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnJlcXVpcmVkID8gbmV3IEdyYXBoUUxOb25OdWxsKHR5cGUpIDogdHlwZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZpZWxkcztcbiAgICAgIH1cbiAgICB9LCBwYXJzZU9iamVjdEZpZWxkcyk7XG4gIH07XG4gIGxldCBjbGFzc0dyYXBoUUxPdXRwdXRUeXBlID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgICBuYW1lOiBjbGFzc0dyYXBoUUxPdXRwdXRUeXBlTmFtZSxcbiAgICBkZXNjcmlwdGlvbjogYFRoZSAke2NsYXNzR3JhcGhRTE91dHB1dFR5cGVOYW1lfSBvYmplY3QgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIG91dHB1dHRpbmcgb2JqZWN0cyBvZiAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLmAsXG4gICAgaW50ZXJmYWNlcyxcbiAgICBmaWVsZHM6IG91dHB1dEZpZWxkcyxcbiAgfSk7XG4gIGNsYXNzR3JhcGhRTE91dHB1dFR5cGUgPSBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSk7XG5cbiAgY29uc3QgeyBjb25uZWN0aW9uVHlwZSwgZWRnZVR5cGUgfSA9IGNvbm5lY3Rpb25EZWZpbml0aW9ucyh7XG4gICAgbmFtZTogZ3JhcGhRTENsYXNzTmFtZSxcbiAgICBjb25uZWN0aW9uRmllbGRzOiB7XG4gICAgICBjb3VudDogZGVmYXVsdEdyYXBoUUxUeXBlcy5DT1VOVF9BVFQsXG4gICAgfSxcbiAgICBub2RlVHlwZTogY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSB8fCBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVCxcbiAgfSk7XG4gIGxldCBjbGFzc0dyYXBoUUxGaW5kUmVzdWx0VHlwZSA9IHVuZGVmaW5lZDtcbiAgaWYgKFxuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShlZGdlVHlwZSkgJiZcbiAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoY29ubmVjdGlvblR5cGUsIGZhbHNlLCBmYWxzZSwgdHJ1ZSlcbiAgKSB7XG4gICAgY2xhc3NHcmFwaFFMRmluZFJlc3VsdFR5cGUgPSBjb25uZWN0aW9uVHlwZTtcbiAgfVxuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzVHlwZXNbY2xhc3NOYW1lXSA9IHtcbiAgICBjbGFzc0dyYXBoUUxQb2ludGVyVHlwZSxcbiAgICBjbGFzc0dyYXBoUUxSZWxhdGlvblR5cGUsXG4gICAgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSxcbiAgICBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlLFxuICAgIGNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZSxcbiAgICBjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZSxcbiAgICBjbGFzc0dyYXBoUUxGaW5kQXJncyxcbiAgICBjbGFzc0dyYXBoUUxPdXRwdXRUeXBlLFxuICAgIGNsYXNzR3JhcGhRTEZpbmRSZXN1bHRUeXBlLFxuICAgIGNvbmZpZzoge1xuICAgICAgcGFyc2VDbGFzc0NvbmZpZyxcbiAgICAgIGlzQ3JlYXRlRW5hYmxlZCxcbiAgICAgIGlzVXBkYXRlRW5hYmxlZCxcbiAgICB9LFxuICB9O1xuXG4gIGlmIChjbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICBjb25zdCB2aWV3ZXJUeXBlID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgICAgIG5hbWU6ICdWaWV3ZXInLFxuICAgICAgZGVzY3JpcHRpb246IGBUaGUgVmlld2VyIG9iamVjdCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgb3V0cHV0dGluZyB0aGUgY3VycmVudCB1c2VyIGRhdGEuYCxcbiAgICAgIGZpZWxkczogKCkgPT4gKHtcbiAgICAgICAgc2Vzc2lvblRva2VuOiBkZWZhdWx0R3JhcGhRTFR5cGVzLlNFU1NJT05fVE9LRU5fQVRULFxuICAgICAgICB1c2VyOiB7XG4gICAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBjdXJyZW50IHVzZXIuJyxcbiAgICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSksXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICB9KTtcbiAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUodmlld2VyVHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLnZpZXdlclR5cGUgPSB2aWV3ZXJUeXBlO1xuICB9XG59O1xuXG5leHBvcnQgeyBleHRyYWN0S2V5c0FuZEluY2x1ZGUsIGxvYWQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/schemaDirectives.js b/lib/GraphQL/loaders/schemaDirectives.js deleted file mode 100644 index a792079b0e..0000000000 --- a/lib/GraphQL/loaders/schemaDirectives.js +++ /dev/null @@ -1,72 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = exports.definitions = void 0; - -var _graphqlTag = _interopRequireDefault(require("graphql-tag")); - -var _utils = require("@graphql-tools/utils"); - -var _FunctionsRouter = require("../../Routers/FunctionsRouter"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const definitions = (0, _graphqlTag.default)` - directive @resolve(to: String) on FIELD_DEFINITION - directive @mock(with: Any!) on FIELD_DEFINITION -`; -exports.definitions = definitions; - -const load = parseGraphQLSchema => { - parseGraphQLSchema.graphQLSchemaDirectivesDefinitions = definitions; - - class ResolveDirectiveVisitor extends _utils.SchemaDirectiveVisitor { - visitFieldDefinition(field) { - field.resolve = async (_source, args, context) => { - try { - const { - config, - auth, - info - } = context; - let functionName = field.name; - - if (this.args.to) { - functionName = this.args.to; - } - - return (await _FunctionsRouter.FunctionsRouter.handleCloudFunction({ - params: { - functionName - }, - config, - auth, - info, - body: args - })).response.result; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - }; - } - - } - - parseGraphQLSchema.graphQLSchemaDirectives.resolve = ResolveDirectiveVisitor; - - class MockDirectiveVisitor extends _utils.SchemaDirectiveVisitor { - visitFieldDefinition(field) { - field.resolve = () => { - return this.args.with; - }; - } - - } - - parseGraphQLSchema.graphQLSchemaDirectives.mock = MockDirectiveVisitor; -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvc2NoZW1hRGlyZWN0aXZlcy5qcyJdLCJuYW1lcyI6WyJkZWZpbml0aW9ucyIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJncmFwaFFMU2NoZW1hRGlyZWN0aXZlc0RlZmluaXRpb25zIiwiUmVzb2x2ZURpcmVjdGl2ZVZpc2l0b3IiLCJTY2hlbWFEaXJlY3RpdmVWaXNpdG9yIiwidmlzaXRGaWVsZERlZmluaXRpb24iLCJmaWVsZCIsInJlc29sdmUiLCJfc291cmNlIiwiYXJncyIsImNvbnRleHQiLCJjb25maWciLCJhdXRoIiwiaW5mbyIsImZ1bmN0aW9uTmFtZSIsIm5hbWUiLCJ0byIsIkZ1bmN0aW9uc1JvdXRlciIsImhhbmRsZUNsb3VkRnVuY3Rpb24iLCJwYXJhbXMiLCJib2R5IiwicmVzcG9uc2UiLCJyZXN1bHQiLCJlIiwiaGFuZGxlRXJyb3IiLCJncmFwaFFMU2NoZW1hRGlyZWN0aXZlcyIsIk1vY2tEaXJlY3RpdmVWaXNpdG9yIiwid2l0aCIsIm1vY2siXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7OztBQUVPLE1BQU1BLFdBQVcsR0FBRyx3QkFBSTtBQUMvQjtBQUNBO0FBQ0EsQ0FITzs7O0FBS1AsTUFBTUMsSUFBSSxHQUFHQyxrQkFBa0IsSUFBSTtBQUNqQ0EsRUFBQUEsa0JBQWtCLENBQUNDLGtDQUFuQixHQUF3REgsV0FBeEQ7O0FBRUEsUUFBTUksdUJBQU4sU0FBc0NDLDZCQUF0QyxDQUE2RDtBQUMzREMsSUFBQUEsb0JBQW9CLENBQUNDLEtBQUQsRUFBUTtBQUMxQkEsTUFBQUEsS0FBSyxDQUFDQyxPQUFOLEdBQWdCLE9BQU9DLE9BQVAsRUFBZ0JDLElBQWhCLEVBQXNCQyxPQUF0QixLQUFrQztBQUNoRCxZQUFJO0FBQ0YsZ0JBQU07QUFBRUMsWUFBQUEsTUFBRjtBQUFVQyxZQUFBQSxJQUFWO0FBQWdCQyxZQUFBQTtBQUFoQixjQUF5QkgsT0FBL0I7QUFFQSxjQUFJSSxZQUFZLEdBQUdSLEtBQUssQ0FBQ1MsSUFBekI7O0FBQ0EsY0FBSSxLQUFLTixJQUFMLENBQVVPLEVBQWQsRUFBa0I7QUFDaEJGLFlBQUFBLFlBQVksR0FBRyxLQUFLTCxJQUFMLENBQVVPLEVBQXpCO0FBQ0Q7O0FBRUQsaUJBQU8sQ0FDTCxNQUFNQyxpQ0FBZ0JDLG1CQUFoQixDQUFvQztBQUN4Q0MsWUFBQUEsTUFBTSxFQUFFO0FBQ05MLGNBQUFBO0FBRE0sYUFEZ0M7QUFJeENILFlBQUFBLE1BSndDO0FBS3hDQyxZQUFBQSxJQUx3QztBQU14Q0MsWUFBQUEsSUFOd0M7QUFPeENPLFlBQUFBLElBQUksRUFBRVg7QUFQa0MsV0FBcEMsQ0FERCxFQVVMWSxRQVZLLENBVUlDLE1BVlg7QUFXRCxTQW5CRCxDQW1CRSxPQUFPQyxDQUFQLEVBQVU7QUFDVnRCLFVBQUFBLGtCQUFrQixDQUFDdUIsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRixPQXZCRDtBQXdCRDs7QUExQjBEOztBQTZCN0R0QixFQUFBQSxrQkFBa0IsQ0FBQ3dCLHVCQUFuQixDQUEyQ2xCLE9BQTNDLEdBQXFESix1QkFBckQ7O0FBRUEsUUFBTXVCLG9CQUFOLFNBQW1DdEIsNkJBQW5DLENBQTBEO0FBQ3hEQyxJQUFBQSxvQkFBb0IsQ0FBQ0MsS0FBRCxFQUFRO0FBQzFCQSxNQUFBQSxLQUFLLENBQUNDLE9BQU4sR0FBZ0IsTUFBTTtBQUNwQixlQUFPLEtBQUtFLElBQUwsQ0FBVWtCLElBQWpCO0FBQ0QsT0FGRDtBQUdEOztBQUx1RDs7QUFRMUQxQixFQUFBQSxrQkFBa0IsQ0FBQ3dCLHVCQUFuQixDQUEyQ0csSUFBM0MsR0FBa0RGLG9CQUFsRDtBQUNELENBM0NEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGdxbCBmcm9tICdncmFwaHFsLXRhZyc7XG5pbXBvcnQgeyBTY2hlbWFEaXJlY3RpdmVWaXNpdG9yIH0gZnJvbSAnQGdyYXBocWwtdG9vbHMvdXRpbHMnO1xuaW1wb3J0IHsgRnVuY3Rpb25zUm91dGVyIH0gZnJvbSAnLi4vLi4vUm91dGVycy9GdW5jdGlvbnNSb3V0ZXInO1xuXG5leHBvcnQgY29uc3QgZGVmaW5pdGlvbnMgPSBncWxgXG4gIGRpcmVjdGl2ZSBAcmVzb2x2ZSh0bzogU3RyaW5nKSBvbiBGSUVMRF9ERUZJTklUSU9OXG4gIGRpcmVjdGl2ZSBAbW9jayh3aXRoOiBBbnkhKSBvbiBGSUVMRF9ERUZJTklUSU9OXG5gO1xuXG5jb25zdCBsb2FkID0gcGFyc2VHcmFwaFFMU2NoZW1hID0+IHtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmdyYXBoUUxTY2hlbWFEaXJlY3RpdmVzRGVmaW5pdGlvbnMgPSBkZWZpbml0aW9ucztcblxuICBjbGFzcyBSZXNvbHZlRGlyZWN0aXZlVmlzaXRvciBleHRlbmRzIFNjaGVtYURpcmVjdGl2ZVZpc2l0b3Ige1xuICAgIHZpc2l0RmllbGREZWZpbml0aW9uKGZpZWxkKSB7XG4gICAgICBmaWVsZC5yZXNvbHZlID0gYXN5bmMgKF9zb3VyY2UsIGFyZ3MsIGNvbnRleHQpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcblxuICAgICAgICAgIGxldCBmdW5jdGlvbk5hbWUgPSBmaWVsZC5uYW1lO1xuICAgICAgICAgIGlmICh0aGlzLmFyZ3MudG8pIHtcbiAgICAgICAgICAgIGZ1bmN0aW9uTmFtZSA9IHRoaXMuYXJncy50bztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgYXdhaXQgRnVuY3Rpb25zUm91dGVyLmhhbmRsZUNsb3VkRnVuY3Rpb24oe1xuICAgICAgICAgICAgICBwYXJhbXM6IHtcbiAgICAgICAgICAgICAgICBmdW5jdGlvbk5hbWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgICAgYXV0aCxcbiAgICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICAgICAgYm9keTogYXJncyxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKS5yZXNwb25zZS5yZXN1bHQ7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmdyYXBoUUxTY2hlbWFEaXJlY3RpdmVzLnJlc29sdmUgPSBSZXNvbHZlRGlyZWN0aXZlVmlzaXRvcjtcblxuICBjbGFzcyBNb2NrRGlyZWN0aXZlVmlzaXRvciBleHRlbmRzIFNjaGVtYURpcmVjdGl2ZVZpc2l0b3Ige1xuICAgIHZpc2l0RmllbGREZWZpbml0aW9uKGZpZWxkKSB7XG4gICAgICBmaWVsZC5yZXNvbHZlID0gKCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5hcmdzLndpdGg7XG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5ncmFwaFFMU2NoZW1hRGlyZWN0aXZlcy5tb2NrID0gTW9ja0RpcmVjdGl2ZVZpc2l0b3I7XG59O1xuXG5leHBvcnQgeyBsb2FkIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/loaders/schemaMutations.js b/lib/GraphQL/loaders/schemaMutations.js deleted file mode 100644 index bc85bdf1a7..0000000000 --- a/lib/GraphQL/loaders/schemaMutations.js +++ /dev/null @@ -1,179 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _graphql = require("graphql"); - -var _graphqlRelay = require("graphql-relay"); - -var schemaTypes = _interopRequireWildcard(require("./schemaTypes")); - -var _schemaFields = require("../transformers/schemaFields"); - -var _parseGraphQLUtils = require("../parseGraphQLUtils"); - -var _schemaQueries = require("./schemaQueries"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const load = parseGraphQLSchema => { - const createClassMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'CreateClass', - description: 'The createClass mutation can be used to create the schema for a new object class.', - inputFields: { - name: schemaTypes.CLASS_NAME_ATT, - schemaFields: { - description: "These are the schema's fields of the object class.", - type: schemaTypes.SCHEMA_FIELDS_INPUT - } - }, - outputFields: { - class: { - description: 'This is the created class.', - type: new _graphql.GraphQLNonNull(schemaTypes.CLASS) - } - }, - mutateAndGetPayload: async (args, context) => { - try { - const { - name, - schemaFields - } = args; - const { - config, - auth - } = context; - (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); - - if (auth.isReadOnly) { - throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to create a schema."); - } - - const schema = await config.database.loadSchema({ - clearCache: true - }); - const parseClass = await schema.addClassIfNotExists(name, (0, _schemaFields.transformToParse)(schemaFields)); - return { - class: { - name: parseClass.className, - schemaFields: (0, _schemaFields.transformToGraphQL)(parseClass.fields) - } - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(createClassMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(createClassMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('createClass', createClassMutation, true, true); - const updateClassMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'UpdateClass', - description: 'The updateClass mutation can be used to update the schema for an existing object class.', - inputFields: { - name: schemaTypes.CLASS_NAME_ATT, - schemaFields: { - description: "These are the schema's fields of the object class.", - type: schemaTypes.SCHEMA_FIELDS_INPUT - } - }, - outputFields: { - class: { - description: 'This is the updated class.', - type: new _graphql.GraphQLNonNull(schemaTypes.CLASS) - } - }, - mutateAndGetPayload: async (args, context) => { - try { - const { - name, - schemaFields - } = args; - const { - config, - auth - } = context; - (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); - - if (auth.isReadOnly) { - throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to update a schema."); - } - - const schema = await config.database.loadSchema({ - clearCache: true - }); - const existingParseClass = await (0, _schemaQueries.getClass)(name, schema); - const parseClass = await schema.updateClass(name, (0, _schemaFields.transformToParse)(schemaFields, existingParseClass.fields), undefined, undefined, config.database); - return { - class: { - name: parseClass.className, - schemaFields: (0, _schemaFields.transformToGraphQL)(parseClass.fields) - } - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(updateClassMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(updateClassMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('updateClass', updateClassMutation, true, true); - const deleteClassMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'DeleteClass', - description: 'The deleteClass mutation can be used to delete an existing object class.', - inputFields: { - name: schemaTypes.CLASS_NAME_ATT - }, - outputFields: { - class: { - description: 'This is the deleted class.', - type: new _graphql.GraphQLNonNull(schemaTypes.CLASS) - } - }, - mutateAndGetPayload: async (args, context) => { - try { - const { - name - } = args; - const { - config, - auth - } = context; - (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); - - if (auth.isReadOnly) { - throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to delete a schema."); - } - - const schema = await config.database.loadSchema({ - clearCache: true - }); - const existingParseClass = await (0, _schemaQueries.getClass)(name, schema); - await config.database.deleteSchema(name); - return { - class: { - name: existingParseClass.className, - schemaFields: (0, _schemaFields.transformToGraphQL)(existingParseClass.fields) - } - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(deleteClassMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(deleteClassMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('deleteClass', deleteClassMutation, true, true); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvc2NoZW1hTXV0YXRpb25zLmpzIl0sIm5hbWVzIjpbImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJjcmVhdGVDbGFzc011dGF0aW9uIiwibmFtZSIsImRlc2NyaXB0aW9uIiwiaW5wdXRGaWVsZHMiLCJzY2hlbWFUeXBlcyIsIkNMQVNTX05BTUVfQVRUIiwic2NoZW1hRmllbGRzIiwidHlwZSIsIlNDSEVNQV9GSUVMRFNfSU5QVVQiLCJvdXRwdXRGaWVsZHMiLCJjbGFzcyIsIkdyYXBoUUxOb25OdWxsIiwiQ0xBU1MiLCJtdXRhdGVBbmRHZXRQYXlsb2FkIiwiYXJncyIsImNvbnRleHQiLCJjb25maWciLCJhdXRoIiwiaXNSZWFkT25seSIsIlBhcnNlIiwiRXJyb3IiLCJPUEVSQVRJT05fRk9SQklEREVOIiwic2NoZW1hIiwiZGF0YWJhc2UiLCJsb2FkU2NoZW1hIiwiY2xlYXJDYWNoZSIsInBhcnNlQ2xhc3MiLCJhZGRDbGFzc0lmTm90RXhpc3RzIiwiY2xhc3NOYW1lIiwiZmllbGRzIiwiZSIsImhhbmRsZUVycm9yIiwiYWRkR3JhcGhRTFR5cGUiLCJpbnB1dCIsIm9mVHlwZSIsImFkZEdyYXBoUUxNdXRhdGlvbiIsInVwZGF0ZUNsYXNzTXV0YXRpb24iLCJleGlzdGluZ1BhcnNlQ2xhc3MiLCJ1cGRhdGVDbGFzcyIsInVuZGVmaW5lZCIsImRlbGV0ZUNsYXNzTXV0YXRpb24iLCJkZWxldGVTY2hlbWEiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFQSxNQUFNQSxJQUFJLEdBQUdDLGtCQUFrQixJQUFJO0FBQ2pDLFFBQU1DLG1CQUFtQixHQUFHLGdEQUE2QjtBQUN2REMsSUFBQUEsSUFBSSxFQUFFLGFBRGlEO0FBRXZEQyxJQUFBQSxXQUFXLEVBQ1QsbUZBSHFEO0FBSXZEQyxJQUFBQSxXQUFXLEVBQUU7QUFDWEYsTUFBQUEsSUFBSSxFQUFFRyxXQUFXLENBQUNDLGNBRFA7QUFFWEMsTUFBQUEsWUFBWSxFQUFFO0FBQ1pKLFFBQUFBLFdBQVcsRUFBRSxvREFERDtBQUVaSyxRQUFBQSxJQUFJLEVBQUVILFdBQVcsQ0FBQ0k7QUFGTjtBQUZILEtBSjBDO0FBV3ZEQyxJQUFBQSxZQUFZLEVBQUU7QUFDWkMsTUFBQUEsS0FBSyxFQUFFO0FBQ0xSLFFBQUFBLFdBQVcsRUFBRSw0QkFEUjtBQUVMSyxRQUFBQSxJQUFJLEVBQUUsSUFBSUksdUJBQUosQ0FBbUJQLFdBQVcsQ0FBQ1EsS0FBL0I7QUFGRDtBQURLLEtBWHlDO0FBaUJ2REMsSUFBQUEsbUJBQW1CLEVBQUUsT0FBT0MsSUFBUCxFQUFhQyxPQUFiLEtBQXlCO0FBQzVDLFVBQUk7QUFDRixjQUFNO0FBQUVkLFVBQUFBLElBQUY7QUFBUUssVUFBQUE7QUFBUixZQUF5QlEsSUFBL0I7QUFDQSxjQUFNO0FBQUVFLFVBQUFBLE1BQUY7QUFBVUMsVUFBQUE7QUFBVixZQUFtQkYsT0FBekI7QUFFQSx1REFBdUJFLElBQXZCOztBQUVBLFlBQUlBLElBQUksQ0FBQ0MsVUFBVCxFQUFxQjtBQUNuQixnQkFBTSxJQUFJQyxjQUFNQyxLQUFWLENBQ0pELGNBQU1DLEtBQU4sQ0FBWUMsbUJBRFIsRUFFSix1REFGSSxDQUFOO0FBSUQ7O0FBRUQsY0FBTUMsTUFBTSxHQUFHLE1BQU1OLE1BQU0sQ0FBQ08sUUFBUCxDQUFnQkMsVUFBaEIsQ0FBMkI7QUFBRUMsVUFBQUEsVUFBVSxFQUFFO0FBQWQsU0FBM0IsQ0FBckI7QUFDQSxjQUFNQyxVQUFVLEdBQUcsTUFBTUosTUFBTSxDQUFDSyxtQkFBUCxDQUEyQjFCLElBQTNCLEVBQWlDLG9DQUFpQkssWUFBakIsQ0FBakMsQ0FBekI7QUFDQSxlQUFPO0FBQ0xJLFVBQUFBLEtBQUssRUFBRTtBQUNMVCxZQUFBQSxJQUFJLEVBQUV5QixVQUFVLENBQUNFLFNBRFo7QUFFTHRCLFlBQUFBLFlBQVksRUFBRSxzQ0FBbUJvQixVQUFVLENBQUNHLE1BQTlCO0FBRlQ7QUFERixTQUFQO0FBTUQsT0FyQkQsQ0FxQkUsT0FBT0MsQ0FBUCxFQUFVO0FBQ1YvQixRQUFBQSxrQkFBa0IsQ0FBQ2dDLFdBQW5CLENBQStCRCxDQUEvQjtBQUNEO0FBQ0Y7QUExQ3NELEdBQTdCLENBQTVCO0FBNkNBL0IsRUFBQUEsa0JBQWtCLENBQUNpQyxjQUFuQixDQUFrQ2hDLG1CQUFtQixDQUFDYyxJQUFwQixDQUF5Qm1CLEtBQXpCLENBQStCMUIsSUFBL0IsQ0FBb0MyQixNQUF0RSxFQUE4RSxJQUE5RSxFQUFvRixJQUFwRjtBQUNBbkMsRUFBQUEsa0JBQWtCLENBQUNpQyxjQUFuQixDQUFrQ2hDLG1CQUFtQixDQUFDTyxJQUF0RCxFQUE0RCxJQUE1RCxFQUFrRSxJQUFsRTtBQUNBUixFQUFBQSxrQkFBa0IsQ0FBQ29DLGtCQUFuQixDQUFzQyxhQUF0QyxFQUFxRG5DLG1CQUFyRCxFQUEwRSxJQUExRSxFQUFnRixJQUFoRjtBQUVBLFFBQU1vQyxtQkFBbUIsR0FBRyxnREFBNkI7QUFDdkRuQyxJQUFBQSxJQUFJLEVBQUUsYUFEaUQ7QUFFdkRDLElBQUFBLFdBQVcsRUFDVCx5RkFIcUQ7QUFJdkRDLElBQUFBLFdBQVcsRUFBRTtBQUNYRixNQUFBQSxJQUFJLEVBQUVHLFdBQVcsQ0FBQ0MsY0FEUDtBQUVYQyxNQUFBQSxZQUFZLEVBQUU7QUFDWkosUUFBQUEsV0FBVyxFQUFFLG9EQUREO0FBRVpLLFFBQUFBLElBQUksRUFBRUgsV0FBVyxDQUFDSTtBQUZOO0FBRkgsS0FKMEM7QUFXdkRDLElBQUFBLFlBQVksRUFBRTtBQUNaQyxNQUFBQSxLQUFLLEVBQUU7QUFDTFIsUUFBQUEsV0FBVyxFQUFFLDRCQURSO0FBRUxLLFFBQUFBLElBQUksRUFBRSxJQUFJSSx1QkFBSixDQUFtQlAsV0FBVyxDQUFDUSxLQUEvQjtBQUZEO0FBREssS0FYeUM7QUFpQnZEQyxJQUFBQSxtQkFBbUIsRUFBRSxPQUFPQyxJQUFQLEVBQWFDLE9BQWIsS0FBeUI7QUFDNUMsVUFBSTtBQUNGLGNBQU07QUFBRWQsVUFBQUEsSUFBRjtBQUFRSyxVQUFBQTtBQUFSLFlBQXlCUSxJQUEvQjtBQUNBLGNBQU07QUFBRUUsVUFBQUEsTUFBRjtBQUFVQyxVQUFBQTtBQUFWLFlBQW1CRixPQUF6QjtBQUVBLHVEQUF1QkUsSUFBdkI7O0FBRUEsWUFBSUEsSUFBSSxDQUFDQyxVQUFULEVBQXFCO0FBQ25CLGdCQUFNLElBQUlDLGNBQU1DLEtBQVYsQ0FDSkQsY0FBTUMsS0FBTixDQUFZQyxtQkFEUixFQUVKLHVEQUZJLENBQU47QUFJRDs7QUFFRCxjQUFNQyxNQUFNLEdBQUcsTUFBTU4sTUFBTSxDQUFDTyxRQUFQLENBQWdCQyxVQUFoQixDQUEyQjtBQUFFQyxVQUFBQSxVQUFVLEVBQUU7QUFBZCxTQUEzQixDQUFyQjtBQUNBLGNBQU1ZLGtCQUFrQixHQUFHLE1BQU0sNkJBQVNwQyxJQUFULEVBQWVxQixNQUFmLENBQWpDO0FBQ0EsY0FBTUksVUFBVSxHQUFHLE1BQU1KLE1BQU0sQ0FBQ2dCLFdBQVAsQ0FDdkJyQyxJQUR1QixFQUV2QixvQ0FBaUJLLFlBQWpCLEVBQStCK0Isa0JBQWtCLENBQUNSLE1BQWxELENBRnVCLEVBR3ZCVSxTQUh1QixFQUl2QkEsU0FKdUIsRUFLdkJ2QixNQUFNLENBQUNPLFFBTGdCLENBQXpCO0FBT0EsZUFBTztBQUNMYixVQUFBQSxLQUFLLEVBQUU7QUFDTFQsWUFBQUEsSUFBSSxFQUFFeUIsVUFBVSxDQUFDRSxTQURaO0FBRUx0QixZQUFBQSxZQUFZLEVBQUUsc0NBQW1Cb0IsVUFBVSxDQUFDRyxNQUE5QjtBQUZUO0FBREYsU0FBUDtBQU1ELE9BNUJELENBNEJFLE9BQU9DLENBQVAsRUFBVTtBQUNWL0IsUUFBQUEsa0JBQWtCLENBQUNnQyxXQUFuQixDQUErQkQsQ0FBL0I7QUFDRDtBQUNGO0FBakRzRCxHQUE3QixDQUE1QjtBQW9EQS9CLEVBQUFBLGtCQUFrQixDQUFDaUMsY0FBbkIsQ0FBa0NJLG1CQUFtQixDQUFDdEIsSUFBcEIsQ0FBeUJtQixLQUF6QixDQUErQjFCLElBQS9CLENBQW9DMkIsTUFBdEUsRUFBOEUsSUFBOUUsRUFBb0YsSUFBcEY7QUFDQW5DLEVBQUFBLGtCQUFrQixDQUFDaUMsY0FBbkIsQ0FBa0NJLG1CQUFtQixDQUFDN0IsSUFBdEQsRUFBNEQsSUFBNUQsRUFBa0UsSUFBbEU7QUFDQVIsRUFBQUEsa0JBQWtCLENBQUNvQyxrQkFBbkIsQ0FBc0MsYUFBdEMsRUFBcURDLG1CQUFyRCxFQUEwRSxJQUExRSxFQUFnRixJQUFoRjtBQUVBLFFBQU1JLG1CQUFtQixHQUFHLGdEQUE2QjtBQUN2RHZDLElBQUFBLElBQUksRUFBRSxhQURpRDtBQUV2REMsSUFBQUEsV0FBVyxFQUFFLDBFQUYwQztBQUd2REMsSUFBQUEsV0FBVyxFQUFFO0FBQ1hGLE1BQUFBLElBQUksRUFBRUcsV0FBVyxDQUFDQztBQURQLEtBSDBDO0FBTXZESSxJQUFBQSxZQUFZLEVBQUU7QUFDWkMsTUFBQUEsS0FBSyxFQUFFO0FBQ0xSLFFBQUFBLFdBQVcsRUFBRSw0QkFEUjtBQUVMSyxRQUFBQSxJQUFJLEVBQUUsSUFBSUksdUJBQUosQ0FBbUJQLFdBQVcsQ0FBQ1EsS0FBL0I7QUFGRDtBQURLLEtBTnlDO0FBWXZEQyxJQUFBQSxtQkFBbUIsRUFBRSxPQUFPQyxJQUFQLEVBQWFDLE9BQWIsS0FBeUI7QUFDNUMsVUFBSTtBQUNGLGNBQU07QUFBRWQsVUFBQUE7QUFBRixZQUFXYSxJQUFqQjtBQUNBLGNBQU07QUFBRUUsVUFBQUEsTUFBRjtBQUFVQyxVQUFBQTtBQUFWLFlBQW1CRixPQUF6QjtBQUVBLHVEQUF1QkUsSUFBdkI7O0FBRUEsWUFBSUEsSUFBSSxDQUFDQyxVQUFULEVBQXFCO0FBQ25CLGdCQUFNLElBQUlDLGNBQU1DLEtBQVYsQ0FDSkQsY0FBTUMsS0FBTixDQUFZQyxtQkFEUixFQUVKLHVEQUZJLENBQU47QUFJRDs7QUFFRCxjQUFNQyxNQUFNLEdBQUcsTUFBTU4sTUFBTSxDQUFDTyxRQUFQLENBQWdCQyxVQUFoQixDQUEyQjtBQUFFQyxVQUFBQSxVQUFVLEVBQUU7QUFBZCxTQUEzQixDQUFyQjtBQUNBLGNBQU1ZLGtCQUFrQixHQUFHLE1BQU0sNkJBQVNwQyxJQUFULEVBQWVxQixNQUFmLENBQWpDO0FBQ0EsY0FBTU4sTUFBTSxDQUFDTyxRQUFQLENBQWdCa0IsWUFBaEIsQ0FBNkJ4QyxJQUE3QixDQUFOO0FBQ0EsZUFBTztBQUNMUyxVQUFBQSxLQUFLLEVBQUU7QUFDTFQsWUFBQUEsSUFBSSxFQUFFb0Msa0JBQWtCLENBQUNULFNBRHBCO0FBRUx0QixZQUFBQSxZQUFZLEVBQUUsc0NBQW1CK0Isa0JBQWtCLENBQUNSLE1BQXRDO0FBRlQ7QUFERixTQUFQO0FBTUQsT0F0QkQsQ0FzQkUsT0FBT0MsQ0FBUCxFQUFVO0FBQ1YvQixRQUFBQSxrQkFBa0IsQ0FBQ2dDLFdBQW5CLENBQStCRCxDQUEvQjtBQUNEO0FBQ0Y7QUF0Q3NELEdBQTdCLENBQTVCO0FBeUNBL0IsRUFBQUEsa0JBQWtCLENBQUNpQyxjQUFuQixDQUFrQ1EsbUJBQW1CLENBQUMxQixJQUFwQixDQUF5Qm1CLEtBQXpCLENBQStCMUIsSUFBL0IsQ0FBb0MyQixNQUF0RSxFQUE4RSxJQUE5RSxFQUFvRixJQUFwRjtBQUNBbkMsRUFBQUEsa0JBQWtCLENBQUNpQyxjQUFuQixDQUFrQ1EsbUJBQW1CLENBQUNqQyxJQUF0RCxFQUE0RCxJQUE1RCxFQUFrRSxJQUFsRTtBQUNBUixFQUFBQSxrQkFBa0IsQ0FBQ29DLGtCQUFuQixDQUFzQyxhQUF0QyxFQUFxREssbUJBQXJELEVBQTBFLElBQTFFLEVBQWdGLElBQWhGO0FBQ0QsQ0F0SkQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBHcmFwaFFMTm9uTnVsbCB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0ICogYXMgc2NoZW1hVHlwZXMgZnJvbSAnLi9zY2hlbWFUeXBlcyc7XG5pbXBvcnQgeyB0cmFuc2Zvcm1Ub1BhcnNlLCB0cmFuc2Zvcm1Ub0dyYXBoUUwgfSBmcm9tICcuLi90cmFuc2Zvcm1lcnMvc2NoZW1hRmllbGRzJztcbmltcG9ydCB7IGVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MgfSBmcm9tICcuLi9wYXJzZUdyYXBoUUxVdGlscyc7XG5pbXBvcnQgeyBnZXRDbGFzcyB9IGZyb20gJy4vc2NoZW1hUXVlcmllcyc7XG5cbmNvbnN0IGxvYWQgPSBwYXJzZUdyYXBoUUxTY2hlbWEgPT4ge1xuICBjb25zdCBjcmVhdGVDbGFzc011dGF0aW9uID0gbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCh7XG4gICAgbmFtZTogJ0NyZWF0ZUNsYXNzJyxcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgICdUaGUgY3JlYXRlQ2xhc3MgbXV0YXRpb24gY2FuIGJlIHVzZWQgdG8gY3JlYXRlIHRoZSBzY2hlbWEgZm9yIGEgbmV3IG9iamVjdCBjbGFzcy4nLFxuICAgIGlucHV0RmllbGRzOiB7XG4gICAgICBuYW1lOiBzY2hlbWFUeXBlcy5DTEFTU19OQU1FX0FUVCxcbiAgICAgIHNjaGVtYUZpZWxkczoge1xuICAgICAgICBkZXNjcmlwdGlvbjogXCJUaGVzZSBhcmUgdGhlIHNjaGVtYSdzIGZpZWxkcyBvZiB0aGUgb2JqZWN0IGNsYXNzLlwiLFxuICAgICAgICB0eXBlOiBzY2hlbWFUeXBlcy5TQ0hFTUFfRklFTERTX0lOUFVULFxuICAgICAgfSxcbiAgICB9LFxuICAgIG91dHB1dEZpZWxkczoge1xuICAgICAgY2xhc3M6IHtcbiAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHRoZSBjcmVhdGVkIGNsYXNzLicsXG4gICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChzY2hlbWFUeXBlcy5DTEFTUyksXG4gICAgICB9LFxuICAgIH0sXG4gICAgbXV0YXRlQW5kR2V0UGF5bG9hZDogYXN5bmMgKGFyZ3MsIGNvbnRleHQpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgbmFtZSwgc2NoZW1hRmllbGRzIH0gPSBhcmdzO1xuICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCB9ID0gY29udGV4dDtcblxuICAgICAgICBlbmZvcmNlTWFzdGVyS2V5QWNjZXNzKGF1dGgpO1xuXG4gICAgICAgIGlmIChhdXRoLmlzUmVhZE9ubHkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICAgICAgXCJyZWFkLW9ubHkgbWFzdGVyS2V5IGlzbid0IGFsbG93ZWQgdG8gY3JlYXRlIGEgc2NoZW1hLlwiXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNjaGVtYSA9IGF3YWl0IGNvbmZpZy5kYXRhYmFzZS5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KTtcbiAgICAgICAgY29uc3QgcGFyc2VDbGFzcyA9IGF3YWl0IHNjaGVtYS5hZGRDbGFzc0lmTm90RXhpc3RzKG5hbWUsIHRyYW5zZm9ybVRvUGFyc2Uoc2NoZW1hRmllbGRzKSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgY2xhc3M6IHtcbiAgICAgICAgICAgIG5hbWU6IHBhcnNlQ2xhc3MuY2xhc3NOYW1lLFxuICAgICAgICAgICAgc2NoZW1hRmllbGRzOiB0cmFuc2Zvcm1Ub0dyYXBoUUwocGFyc2VDbGFzcy5maWVsZHMpLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcblxuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoY3JlYXRlQ2xhc3NNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNyZWF0ZUNsYXNzTXV0YXRpb24udHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oJ2NyZWF0ZUNsYXNzJywgY3JlYXRlQ2xhc3NNdXRhdGlvbiwgdHJ1ZSwgdHJ1ZSk7XG5cbiAgY29uc3QgdXBkYXRlQ2xhc3NNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgIG5hbWU6ICdVcGRhdGVDbGFzcycsXG4gICAgZGVzY3JpcHRpb246XG4gICAgICAnVGhlIHVwZGF0ZUNsYXNzIG11dGF0aW9uIGNhbiBiZSB1c2VkIHRvIHVwZGF0ZSB0aGUgc2NoZW1hIGZvciBhbiBleGlzdGluZyBvYmplY3QgY2xhc3MuJyxcbiAgICBpbnB1dEZpZWxkczoge1xuICAgICAgbmFtZTogc2NoZW1hVHlwZXMuQ0xBU1NfTkFNRV9BVFQsXG4gICAgICBzY2hlbWFGaWVsZHM6IHtcbiAgICAgICAgZGVzY3JpcHRpb246IFwiVGhlc2UgYXJlIHRoZSBzY2hlbWEncyBmaWVsZHMgb2YgdGhlIG9iamVjdCBjbGFzcy5cIixcbiAgICAgICAgdHlwZTogc2NoZW1hVHlwZXMuU0NIRU1BX0ZJRUxEU19JTlBVVCxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgIGNsYXNzOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgdXBkYXRlZCBjbGFzcy4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoc2NoZW1hVHlwZXMuQ0xBU1MpLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jIChhcmdzLCBjb250ZXh0KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB7IG5hbWUsIHNjaGVtYUZpZWxkcyB9ID0gYXJncztcbiAgICAgICAgY29uc3QgeyBjb25maWcsIGF1dGggfSA9IGNvbnRleHQ7XG5cbiAgICAgICAgZW5mb3JjZU1hc3RlcktleUFjY2VzcyhhdXRoKTtcblxuICAgICAgICBpZiAoYXV0aC5pc1JlYWRPbmx5KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgICAgICAgIFwicmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIHVwZGF0ZSBhIHNjaGVtYS5cIlxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzY2hlbWEgPSBhd2FpdCBjb25maWcuZGF0YWJhc2UubG9hZFNjaGVtYSh7IGNsZWFyQ2FjaGU6IHRydWUgfSk7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nUGFyc2VDbGFzcyA9IGF3YWl0IGdldENsYXNzKG5hbWUsIHNjaGVtYSk7XG4gICAgICAgIGNvbnN0IHBhcnNlQ2xhc3MgPSBhd2FpdCBzY2hlbWEudXBkYXRlQ2xhc3MoXG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgICB0cmFuc2Zvcm1Ub1BhcnNlKHNjaGVtYUZpZWxkcywgZXhpc3RpbmdQYXJzZUNsYXNzLmZpZWxkcyksXG4gICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICBjb25maWcuZGF0YWJhc2VcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjbGFzczoge1xuICAgICAgICAgICAgbmFtZTogcGFyc2VDbGFzcy5jbGFzc05hbWUsXG4gICAgICAgICAgICBzY2hlbWFGaWVsZHM6IHRyYW5zZm9ybVRvR3JhcGhRTChwYXJzZUNsYXNzLmZpZWxkcyksXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZSh1cGRhdGVDbGFzc011dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGUsIHRydWUsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUodXBkYXRlQ2xhc3NNdXRhdGlvbi50eXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbigndXBkYXRlQ2xhc3MnLCB1cGRhdGVDbGFzc011dGF0aW9uLCB0cnVlLCB0cnVlKTtcblxuICBjb25zdCBkZWxldGVDbGFzc011dGF0aW9uID0gbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCh7XG4gICAgbmFtZTogJ0RlbGV0ZUNsYXNzJyxcbiAgICBkZXNjcmlwdGlvbjogJ1RoZSBkZWxldGVDbGFzcyBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBkZWxldGUgYW4gZXhpc3Rpbmcgb2JqZWN0IGNsYXNzLicsXG4gICAgaW5wdXRGaWVsZHM6IHtcbiAgICAgIG5hbWU6IHNjaGVtYVR5cGVzLkNMQVNTX05BTUVfQVRULFxuICAgIH0sXG4gICAgb3V0cHV0RmllbGRzOiB7XG4gICAgICBjbGFzczoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGRlbGV0ZWQgY2xhc3MuJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKHNjaGVtYVR5cGVzLkNMQVNTKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBtdXRhdGVBbmRHZXRQYXlsb2FkOiBhc3luYyAoYXJncywgY29udGV4dCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgeyBuYW1lIH0gPSBhcmdzO1xuICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCB9ID0gY29udGV4dDtcblxuICAgICAgICBlbmZvcmNlTWFzdGVyS2V5QWNjZXNzKGF1dGgpO1xuXG4gICAgICAgIGlmIChhdXRoLmlzUmVhZE9ubHkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICAgICAgXCJyZWFkLW9ubHkgbWFzdGVyS2V5IGlzbid0IGFsbG93ZWQgdG8gZGVsZXRlIGEgc2NoZW1hLlwiXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHNjaGVtYSA9IGF3YWl0IGNvbmZpZy5kYXRhYmFzZS5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KTtcbiAgICAgICAgY29uc3QgZXhpc3RpbmdQYXJzZUNsYXNzID0gYXdhaXQgZ2V0Q2xhc3MobmFtZSwgc2NoZW1hKTtcbiAgICAgICAgYXdhaXQgY29uZmlnLmRhdGFiYXNlLmRlbGV0ZVNjaGVtYShuYW1lKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjbGFzczoge1xuICAgICAgICAgICAgbmFtZTogZXhpc3RpbmdQYXJzZUNsYXNzLmNsYXNzTmFtZSxcbiAgICAgICAgICAgIHNjaGVtYUZpZWxkczogdHJhbnNmb3JtVG9HcmFwaFFMKGV4aXN0aW5nUGFyc2VDbGFzcy5maWVsZHMpLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcblxuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoZGVsZXRlQ2xhc3NNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGRlbGV0ZUNsYXNzTXV0YXRpb24udHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oJ2RlbGV0ZUNsYXNzJywgZGVsZXRlQ2xhc3NNdXRhdGlvbiwgdHJ1ZSwgdHJ1ZSk7XG59O1xuXG5leHBvcnQgeyBsb2FkIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/loaders/schemaQueries.js b/lib/GraphQL/loaders/schemaQueries.js deleted file mode 100644 index 33bef76fe1..0000000000 --- a/lib/GraphQL/loaders/schemaQueries.js +++ /dev/null @@ -1,93 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = exports.getClass = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _graphql = require("graphql"); - -var _schemaFields = require("../transformers/schemaFields"); - -var schemaTypes = _interopRequireWildcard(require("./schemaTypes")); - -var _parseGraphQLUtils = require("../parseGraphQLUtils"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const getClass = async (name, schema) => { - try { - return await schema.getOneSchema(name, true); - } catch (e) { - if (e === undefined) { - throw new _node.default.Error(_node.default.Error.INVALID_CLASS_NAME, `Class ${name} does not exist.`); - } else { - throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'Database adapter error.'); - } - } -}; - -exports.getClass = getClass; - -const load = parseGraphQLSchema => { - parseGraphQLSchema.addGraphQLQuery('class', { - description: 'The class query can be used to retrieve an existing object class.', - args: { - name: schemaTypes.CLASS_NAME_ATT - }, - type: new _graphql.GraphQLNonNull(schemaTypes.CLASS), - resolve: async (_source, args, context) => { - try { - const { - name - } = args; - const { - config, - auth - } = context; - (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); - const schema = await config.database.loadSchema({ - clearCache: true - }); - const parseClass = await getClass(name, schema); - return { - name: parseClass.className, - schemaFields: (0, _schemaFields.transformToGraphQL)(parseClass.fields) - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }, true, true); - parseGraphQLSchema.addGraphQLQuery('classes', { - description: 'The classes query can be used to retrieve the existing object classes.', - type: new _graphql.GraphQLNonNull(new _graphql.GraphQLList(new _graphql.GraphQLNonNull(schemaTypes.CLASS))), - resolve: async (_source, _args, context) => { - try { - const { - config, - auth - } = context; - (0, _parseGraphQLUtils.enforceMasterKeyAccess)(auth); - const schema = await config.database.loadSchema({ - clearCache: true - }); - return (await schema.getAllClasses(true)).map(parseClass => ({ - name: parseClass.className, - schemaFields: (0, _schemaFields.transformToGraphQL)(parseClass.fields) - })); - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }, true, true); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvc2NoZW1hUXVlcmllcy5qcyJdLCJuYW1lcyI6WyJnZXRDbGFzcyIsIm5hbWUiLCJzY2hlbWEiLCJnZXRPbmVTY2hlbWEiLCJlIiwidW5kZWZpbmVkIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfQ0xBU1NfTkFNRSIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJhZGRHcmFwaFFMUXVlcnkiLCJkZXNjcmlwdGlvbiIsImFyZ3MiLCJzY2hlbWFUeXBlcyIsIkNMQVNTX05BTUVfQVRUIiwidHlwZSIsIkdyYXBoUUxOb25OdWxsIiwiQ0xBU1MiLCJyZXNvbHZlIiwiX3NvdXJjZSIsImNvbnRleHQiLCJjb25maWciLCJhdXRoIiwiZGF0YWJhc2UiLCJsb2FkU2NoZW1hIiwiY2xlYXJDYWNoZSIsInBhcnNlQ2xhc3MiLCJjbGFzc05hbWUiLCJzY2hlbWFGaWVsZHMiLCJmaWVsZHMiLCJoYW5kbGVFcnJvciIsIkdyYXBoUUxMaXN0IiwiX2FyZ3MiLCJnZXRBbGxDbGFzc2VzIiwibWFwIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBRUEsTUFBTUEsUUFBUSxHQUFHLE9BQU9DLElBQVAsRUFBYUMsTUFBYixLQUF3QjtBQUN2QyxNQUFJO0FBQ0YsV0FBTyxNQUFNQSxNQUFNLENBQUNDLFlBQVAsQ0FBb0JGLElBQXBCLEVBQTBCLElBQTFCLENBQWI7QUFDRCxHQUZELENBRUUsT0FBT0csQ0FBUCxFQUFVO0FBQ1YsUUFBSUEsQ0FBQyxLQUFLQyxTQUFWLEVBQXFCO0FBQ25CLFlBQU0sSUFBSUMsY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZQyxrQkFBNUIsRUFBaUQsU0FBUVAsSUFBSyxrQkFBOUQsQ0FBTjtBQUNELEtBRkQsTUFFTztBQUNMLFlBQU0sSUFBSUssY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZRSxxQkFBNUIsRUFBbUQseUJBQW5ELENBQU47QUFDRDtBQUNGO0FBQ0YsQ0FWRDs7OztBQVlBLE1BQU1DLElBQUksR0FBR0Msa0JBQWtCLElBQUk7QUFDakNBLEVBQUFBLGtCQUFrQixDQUFDQyxlQUFuQixDQUNFLE9BREYsRUFFRTtBQUNFQyxJQUFBQSxXQUFXLEVBQUUsbUVBRGY7QUFFRUMsSUFBQUEsSUFBSSxFQUFFO0FBQ0piLE1BQUFBLElBQUksRUFBRWMsV0FBVyxDQUFDQztBQURkLEtBRlI7QUFLRUMsSUFBQUEsSUFBSSxFQUFFLElBQUlDLHVCQUFKLENBQW1CSCxXQUFXLENBQUNJLEtBQS9CLENBTFI7QUFNRUMsSUFBQUEsT0FBTyxFQUFFLE9BQU9DLE9BQVAsRUFBZ0JQLElBQWhCLEVBQXNCUSxPQUF0QixLQUFrQztBQUN6QyxVQUFJO0FBQ0YsY0FBTTtBQUFFckIsVUFBQUE7QUFBRixZQUFXYSxJQUFqQjtBQUNBLGNBQU07QUFBRVMsVUFBQUEsTUFBRjtBQUFVQyxVQUFBQTtBQUFWLFlBQW1CRixPQUF6QjtBQUVBLHVEQUF1QkUsSUFBdkI7QUFFQSxjQUFNdEIsTUFBTSxHQUFHLE1BQU1xQixNQUFNLENBQUNFLFFBQVAsQ0FBZ0JDLFVBQWhCLENBQTJCO0FBQUVDLFVBQUFBLFVBQVUsRUFBRTtBQUFkLFNBQTNCLENBQXJCO0FBQ0EsY0FBTUMsVUFBVSxHQUFHLE1BQU01QixRQUFRLENBQUNDLElBQUQsRUFBT0MsTUFBUCxDQUFqQztBQUNBLGVBQU87QUFDTEQsVUFBQUEsSUFBSSxFQUFFMkIsVUFBVSxDQUFDQyxTQURaO0FBRUxDLFVBQUFBLFlBQVksRUFBRSxzQ0FBbUJGLFVBQVUsQ0FBQ0csTUFBOUI7QUFGVCxTQUFQO0FBSUQsT0FaRCxDQVlFLE9BQU8zQixDQUFQLEVBQVU7QUFDVk8sUUFBQUEsa0JBQWtCLENBQUNxQixXQUFuQixDQUErQjVCLENBQS9CO0FBQ0Q7QUFDRjtBQXRCSCxHQUZGLEVBMEJFLElBMUJGLEVBMkJFLElBM0JGO0FBOEJBTyxFQUFBQSxrQkFBa0IsQ0FBQ0MsZUFBbkIsQ0FDRSxTQURGLEVBRUU7QUFDRUMsSUFBQUEsV0FBVyxFQUFFLHdFQURmO0FBRUVJLElBQUFBLElBQUksRUFBRSxJQUFJQyx1QkFBSixDQUFtQixJQUFJZSxvQkFBSixDQUFnQixJQUFJZix1QkFBSixDQUFtQkgsV0FBVyxDQUFDSSxLQUEvQixDQUFoQixDQUFuQixDQUZSO0FBR0VDLElBQUFBLE9BQU8sRUFBRSxPQUFPQyxPQUFQLEVBQWdCYSxLQUFoQixFQUF1QlosT0FBdkIsS0FBbUM7QUFDMUMsVUFBSTtBQUNGLGNBQU07QUFBRUMsVUFBQUEsTUFBRjtBQUFVQyxVQUFBQTtBQUFWLFlBQW1CRixPQUF6QjtBQUVBLHVEQUF1QkUsSUFBdkI7QUFFQSxjQUFNdEIsTUFBTSxHQUFHLE1BQU1xQixNQUFNLENBQUNFLFFBQVAsQ0FBZ0JDLFVBQWhCLENBQTJCO0FBQUVDLFVBQUFBLFVBQVUsRUFBRTtBQUFkLFNBQTNCLENBQXJCO0FBQ0EsZUFBTyxDQUFDLE1BQU16QixNQUFNLENBQUNpQyxhQUFQLENBQXFCLElBQXJCLENBQVAsRUFBbUNDLEdBQW5DLENBQXVDUixVQUFVLEtBQUs7QUFDM0QzQixVQUFBQSxJQUFJLEVBQUUyQixVQUFVLENBQUNDLFNBRDBDO0FBRTNEQyxVQUFBQSxZQUFZLEVBQUUsc0NBQW1CRixVQUFVLENBQUNHLE1BQTlCO0FBRjZDLFNBQUwsQ0FBakQsQ0FBUDtBQUlELE9BVkQsQ0FVRSxPQUFPM0IsQ0FBUCxFQUFVO0FBQ1ZPLFFBQUFBLGtCQUFrQixDQUFDcUIsV0FBbkIsQ0FBK0I1QixDQUEvQjtBQUNEO0FBQ0Y7QUFqQkgsR0FGRixFQXFCRSxJQXJCRixFQXNCRSxJQXRCRjtBQXdCRCxDQXZERCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCB7IEdyYXBoUUxOb25OdWxsLCBHcmFwaFFMTGlzdCB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgdHJhbnNmb3JtVG9HcmFwaFFMIH0gZnJvbSAnLi4vdHJhbnNmb3JtZXJzL3NjaGVtYUZpZWxkcyc7XG5pbXBvcnQgKiBhcyBzY2hlbWFUeXBlcyBmcm9tICcuL3NjaGVtYVR5cGVzJztcbmltcG9ydCB7IGVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MgfSBmcm9tICcuLi9wYXJzZUdyYXBoUUxVdGlscyc7XG5cbmNvbnN0IGdldENsYXNzID0gYXN5bmMgKG5hbWUsIHNjaGVtYSkgPT4ge1xuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBzY2hlbWEuZ2V0T25lU2NoZW1hKG5hbWUsIHRydWUpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSwgYENsYXNzICR7bmFtZX0gZG9lcyBub3QgZXhpc3QuYCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsICdEYXRhYmFzZSBhZGFwdGVyIGVycm9yLicpO1xuICAgIH1cbiAgfVxufTtcblxuY29uc3QgbG9hZCA9IHBhcnNlR3JhcGhRTFNjaGVtYSA9PiB7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMUXVlcnkoXG4gICAgJ2NsYXNzJyxcbiAgICB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSBjbGFzcyBxdWVyeSBjYW4gYmUgdXNlZCB0byByZXRyaWV2ZSBhbiBleGlzdGluZyBvYmplY3QgY2xhc3MuJyxcbiAgICAgIGFyZ3M6IHtcbiAgICAgICAgbmFtZTogc2NoZW1hVHlwZXMuQ0xBU1NfTkFNRV9BVFQsXG4gICAgICB9LFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKHNjaGVtYVR5cGVzLkNMQVNTKSxcbiAgICAgIHJlc29sdmU6IGFzeW5jIChfc291cmNlLCBhcmdzLCBjb250ZXh0KSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgeyBuYW1lIH0gPSBhcmdzO1xuICAgICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoIH0gPSBjb250ZXh0O1xuXG4gICAgICAgICAgZW5mb3JjZU1hc3RlcktleUFjY2VzcyhhdXRoKTtcblxuICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IGF3YWl0IGNvbmZpZy5kYXRhYmFzZS5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KTtcbiAgICAgICAgICBjb25zdCBwYXJzZUNsYXNzID0gYXdhaXQgZ2V0Q2xhc3MobmFtZSwgc2NoZW1hKTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbmFtZTogcGFyc2VDbGFzcy5jbGFzc05hbWUsXG4gICAgICAgICAgICBzY2hlbWFGaWVsZHM6IHRyYW5zZm9ybVRvR3JhcGhRTChwYXJzZUNsYXNzLmZpZWxkcyksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICB9LFxuICAgIHRydWUsXG4gICAgdHJ1ZVxuICApO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMUXVlcnkoXG4gICAgJ2NsYXNzZXMnLFxuICAgIHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIGNsYXNzZXMgcXVlcnkgY2FuIGJlIHVzZWQgdG8gcmV0cmlldmUgdGhlIGV4aXN0aW5nIG9iamVjdCBjbGFzc2VzLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwobmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChzY2hlbWFUeXBlcy5DTEFTUykpKSxcbiAgICAgIHJlc29sdmU6IGFzeW5jIChfc291cmNlLCBfYXJncywgY29udGV4dCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoIH0gPSBjb250ZXh0O1xuXG4gICAgICAgICAgZW5mb3JjZU1hc3RlcktleUFjY2VzcyhhdXRoKTtcblxuICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IGF3YWl0IGNvbmZpZy5kYXRhYmFzZS5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KTtcbiAgICAgICAgICByZXR1cm4gKGF3YWl0IHNjaGVtYS5nZXRBbGxDbGFzc2VzKHRydWUpKS5tYXAocGFyc2VDbGFzcyA9PiAoe1xuICAgICAgICAgICAgbmFtZTogcGFyc2VDbGFzcy5jbGFzc05hbWUsXG4gICAgICAgICAgICBzY2hlbWFGaWVsZHM6IHRyYW5zZm9ybVRvR3JhcGhRTChwYXJzZUNsYXNzLmZpZWxkcyksXG4gICAgICAgICAgfSkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0sXG4gICAgdHJ1ZSxcbiAgICB0cnVlXG4gICk7XG59O1xuXG5leHBvcnQgeyBnZXRDbGFzcywgbG9hZCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/loaders/schemaTypes.js b/lib/GraphQL/loaders/schemaTypes.js deleted file mode 100644 index 832edfa0e1..0000000000 --- a/lib/GraphQL/loaders/schemaTypes.js +++ /dev/null @@ -1,376 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = exports.CLASS = exports.CLASS_NAME_ATT = exports.SCHEMA_FIELDS_INPUT = exports.SCHEMA_ACL_FIELD = exports.SCHEMA_RELATION_FIELD = exports.SCHEMA_RELATION_FIELD_INPUT = exports.SCHEMA_POINTER_FIELD = exports.SCHEMA_POINTER_FIELD_INPUT = exports.TARGET_CLASS_ATT = exports.SCHEMA_BYTES_FIELD = exports.SCHEMA_BYTES_FIELD_INPUT = exports.SCHEMA_POLYGON_FIELD = exports.SCHEMA_POLYGON_FIELD_INPUT = exports.SCHEMA_GEO_POINT_FIELD = exports.SCHEMA_GEO_POINT_FIELD_INPUT = exports.SCHEMA_FILE_FIELD = exports.SCHEMA_FILE_FIELD_INPUT = exports.SCHEMA_DATE_FIELD = exports.SCHEMA_DATE_FIELD_INPUT = exports.SCHEMA_OBJECT_FIELD = exports.SCHEMA_OBJECT_FIELD_INPUT = exports.SCHEMA_ARRAY_FIELD = exports.SCHEMA_ARRAY_FIELD_INPUT = exports.SCHEMA_BOOLEAN_FIELD = exports.SCHEMA_BOOLEAN_FIELD_INPUT = exports.SCHEMA_NUMBER_FIELD = exports.SCHEMA_NUMBER_FIELD_INPUT = exports.SCHEMA_STRING_FIELD = exports.SCHEMA_STRING_FIELD_INPUT = exports.SCHEMA_FIELD_INPUT = exports.SCHEMA_FIELD_NAME_ATT = void 0; - -var _graphql = require("graphql"); - -const SCHEMA_FIELD_NAME_ATT = { - description: 'This is the field name.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) -}; -exports.SCHEMA_FIELD_NAME_ATT = SCHEMA_FIELD_NAME_ATT; -const SCHEMA_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaFieldInput', - description: 'The SchemaFieldInput is used to specify a field of an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_FIELD_INPUT = SCHEMA_FIELD_INPUT; -const SCHEMA_FIELD = new _graphql.GraphQLInterfaceType({ - name: 'SchemaField', - description: 'The SchemaField interface type is used as a base type for the different supported fields of an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - }, - resolveType: value => ({ - String: SCHEMA_STRING_FIELD, - Number: SCHEMA_NUMBER_FIELD, - Boolean: SCHEMA_BOOLEAN_FIELD, - Array: SCHEMA_ARRAY_FIELD, - Object: SCHEMA_OBJECT_FIELD, - Date: SCHEMA_DATE_FIELD, - File: SCHEMA_FILE_FIELD, - GeoPoint: SCHEMA_GEO_POINT_FIELD, - Polygon: SCHEMA_POLYGON_FIELD, - Bytes: SCHEMA_BYTES_FIELD, - Pointer: SCHEMA_POINTER_FIELD, - Relation: SCHEMA_RELATION_FIELD, - ACL: SCHEMA_ACL_FIELD - })[value.type] -}); -const SCHEMA_STRING_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaStringFieldInput', - description: 'The SchemaStringFieldInput is used to specify a field of type string for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_STRING_FIELD_INPUT = SCHEMA_STRING_FIELD_INPUT; -const SCHEMA_STRING_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaStringField', - description: 'The SchemaStringField is used to return information of a String field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_STRING_FIELD = SCHEMA_STRING_FIELD; -const SCHEMA_NUMBER_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaNumberFieldInput', - description: 'The SchemaNumberFieldInput is used to specify a field of type number for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_NUMBER_FIELD_INPUT = SCHEMA_NUMBER_FIELD_INPUT; -const SCHEMA_NUMBER_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaNumberField', - description: 'The SchemaNumberField is used to return information of a Number field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_NUMBER_FIELD = SCHEMA_NUMBER_FIELD; -const SCHEMA_BOOLEAN_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaBooleanFieldInput', - description: 'The SchemaBooleanFieldInput is used to specify a field of type boolean for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_BOOLEAN_FIELD_INPUT = SCHEMA_BOOLEAN_FIELD_INPUT; -const SCHEMA_BOOLEAN_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaBooleanField', - description: 'The SchemaBooleanField is used to return information of a Boolean field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_BOOLEAN_FIELD = SCHEMA_BOOLEAN_FIELD; -const SCHEMA_ARRAY_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaArrayFieldInput', - description: 'The SchemaArrayFieldInput is used to specify a field of type array for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_ARRAY_FIELD_INPUT = SCHEMA_ARRAY_FIELD_INPUT; -const SCHEMA_ARRAY_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaArrayField', - description: 'The SchemaArrayField is used to return information of an Array field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_ARRAY_FIELD = SCHEMA_ARRAY_FIELD; -const SCHEMA_OBJECT_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaObjectFieldInput', - description: 'The SchemaObjectFieldInput is used to specify a field of type object for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_OBJECT_FIELD_INPUT = SCHEMA_OBJECT_FIELD_INPUT; -const SCHEMA_OBJECT_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaObjectField', - description: 'The SchemaObjectField is used to return information of an Object field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_OBJECT_FIELD = SCHEMA_OBJECT_FIELD; -const SCHEMA_DATE_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaDateFieldInput', - description: 'The SchemaDateFieldInput is used to specify a field of type date for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_DATE_FIELD_INPUT = SCHEMA_DATE_FIELD_INPUT; -const SCHEMA_DATE_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaDateField', - description: 'The SchemaDateField is used to return information of a Date field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_DATE_FIELD = SCHEMA_DATE_FIELD; -const SCHEMA_FILE_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaFileFieldInput', - description: 'The SchemaFileFieldInput is used to specify a field of type file for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_FILE_FIELD_INPUT = SCHEMA_FILE_FIELD_INPUT; -const SCHEMA_FILE_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaFileField', - description: 'The SchemaFileField is used to return information of a File field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_FILE_FIELD = SCHEMA_FILE_FIELD; -const SCHEMA_GEO_POINT_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaGeoPointFieldInput', - description: 'The SchemaGeoPointFieldInput is used to specify a field of type geo point for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_GEO_POINT_FIELD_INPUT = SCHEMA_GEO_POINT_FIELD_INPUT; -const SCHEMA_GEO_POINT_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaGeoPointField', - description: 'The SchemaGeoPointField is used to return information of a Geo Point field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_GEO_POINT_FIELD = SCHEMA_GEO_POINT_FIELD; -const SCHEMA_POLYGON_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaPolygonFieldInput', - description: 'The SchemaPolygonFieldInput is used to specify a field of type polygon for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_POLYGON_FIELD_INPUT = SCHEMA_POLYGON_FIELD_INPUT; -const SCHEMA_POLYGON_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaPolygonField', - description: 'The SchemaPolygonField is used to return information of a Polygon field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_POLYGON_FIELD = SCHEMA_POLYGON_FIELD; -const SCHEMA_BYTES_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaBytesFieldInput', - description: 'The SchemaBytesFieldInput is used to specify a field of type bytes for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_BYTES_FIELD_INPUT = SCHEMA_BYTES_FIELD_INPUT; -const SCHEMA_BYTES_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaBytesField', - description: 'The SchemaBytesField is used to return information of a Bytes field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_BYTES_FIELD = SCHEMA_BYTES_FIELD; -const TARGET_CLASS_ATT = { - description: 'This is the name of the target class for the field.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) -}; -exports.TARGET_CLASS_ATT = TARGET_CLASS_ATT; -const SCHEMA_POINTER_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'PointerFieldInput', - description: 'The PointerFieldInput is used to specify a field of type pointer for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT, - targetClassName: TARGET_CLASS_ATT - } -}); -exports.SCHEMA_POINTER_FIELD_INPUT = SCHEMA_POINTER_FIELD_INPUT; -const SCHEMA_POINTER_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaPointerField', - description: 'The SchemaPointerField is used to return information of a Pointer field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT, - targetClassName: TARGET_CLASS_ATT - } -}); -exports.SCHEMA_POINTER_FIELD = SCHEMA_POINTER_FIELD; -const SCHEMA_RELATION_FIELD_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'RelationFieldInput', - description: 'The RelationFieldInput is used to specify a field of type relation for an object class schema.', - fields: { - name: SCHEMA_FIELD_NAME_ATT, - targetClassName: TARGET_CLASS_ATT - } -}); -exports.SCHEMA_RELATION_FIELD_INPUT = SCHEMA_RELATION_FIELD_INPUT; -const SCHEMA_RELATION_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaRelationField', - description: 'The SchemaRelationField is used to return information of a Relation field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT, - targetClassName: TARGET_CLASS_ATT - } -}); -exports.SCHEMA_RELATION_FIELD = SCHEMA_RELATION_FIELD; -const SCHEMA_ACL_FIELD = new _graphql.GraphQLObjectType({ - name: 'SchemaACLField', - description: 'The SchemaACLField is used to return information of an ACL field.', - interfaces: [SCHEMA_FIELD], - fields: { - name: SCHEMA_FIELD_NAME_ATT - } -}); -exports.SCHEMA_ACL_FIELD = SCHEMA_ACL_FIELD; -const SCHEMA_FIELDS_INPUT = new _graphql.GraphQLInputObjectType({ - name: 'SchemaFieldsInput', - description: `The CreateClassSchemaInput type is used to specify the schema for a new object class to be created.`, - fields: { - addStrings: { - description: 'These are the String fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_STRING_FIELD_INPUT)) - }, - addNumbers: { - description: 'These are the Number fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_NUMBER_FIELD_INPUT)) - }, - addBooleans: { - description: 'These are the Boolean fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_BOOLEAN_FIELD_INPUT)) - }, - addArrays: { - description: 'These are the Array fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_ARRAY_FIELD_INPUT)) - }, - addObjects: { - description: 'These are the Object fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_OBJECT_FIELD_INPUT)) - }, - addDates: { - description: 'These are the Date fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_DATE_FIELD_INPUT)) - }, - addFiles: { - description: 'These are the File fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_FILE_FIELD_INPUT)) - }, - addGeoPoint: { - description: 'This is the Geo Point field to be added to the class schema. Currently it is supported only one GeoPoint field per Class.', - type: SCHEMA_GEO_POINT_FIELD_INPUT - }, - addPolygons: { - description: 'These are the Polygon fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_POLYGON_FIELD_INPUT)) - }, - addBytes: { - description: 'These are the Bytes fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_BYTES_FIELD_INPUT)) - }, - addPointers: { - description: 'These are the Pointer fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_POINTER_FIELD_INPUT)) - }, - addRelations: { - description: 'These are the Relation fields to be added to the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_RELATION_FIELD_INPUT)) - }, - remove: { - description: 'These are the fields to be removed from the class schema.', - type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_FIELD_INPUT)) - } - } -}); -exports.SCHEMA_FIELDS_INPUT = SCHEMA_FIELDS_INPUT; -const CLASS_NAME_ATT = { - description: 'This is the name of the object class.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) -}; -exports.CLASS_NAME_ATT = CLASS_NAME_ATT; -const CLASS = new _graphql.GraphQLObjectType({ - name: 'Class', - description: `The Class type is used to return the information about an object class.`, - fields: { - name: CLASS_NAME_ATT, - schemaFields: { - description: "These are the schema's fields of the object class.", - type: new _graphql.GraphQLNonNull(new _graphql.GraphQLList(new _graphql.GraphQLNonNull(SCHEMA_FIELD))) - } - } -}); -exports.CLASS = CLASS; - -const load = parseGraphQLSchema => { - parseGraphQLSchema.addGraphQLType(SCHEMA_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_STRING_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_STRING_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_NUMBER_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_NUMBER_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_BOOLEAN_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_BOOLEAN_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_ARRAY_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_ARRAY_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_OBJECT_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_OBJECT_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_DATE_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_DATE_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_FILE_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_FILE_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_GEO_POINT_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_GEO_POINT_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_POLYGON_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_POLYGON_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_BYTES_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_BYTES_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_POINTER_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_POINTER_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_RELATION_FIELD_INPUT, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_RELATION_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_ACL_FIELD, true); - parseGraphQLSchema.addGraphQLType(SCHEMA_FIELDS_INPUT, true); - parseGraphQLSchema.addGraphQLType(CLASS, true); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvc2NoZW1hVHlwZXMuanMiXSwibmFtZXMiOlsiU0NIRU1BX0ZJRUxEX05BTUVfQVRUIiwiZGVzY3JpcHRpb24iLCJ0eXBlIiwiR3JhcGhRTE5vbk51bGwiLCJHcmFwaFFMU3RyaW5nIiwiU0NIRU1BX0ZJRUxEX0lOUFVUIiwiR3JhcGhRTElucHV0T2JqZWN0VHlwZSIsIm5hbWUiLCJmaWVsZHMiLCJTQ0hFTUFfRklFTEQiLCJHcmFwaFFMSW50ZXJmYWNlVHlwZSIsInJlc29sdmVUeXBlIiwidmFsdWUiLCJTdHJpbmciLCJTQ0hFTUFfU1RSSU5HX0ZJRUxEIiwiTnVtYmVyIiwiU0NIRU1BX05VTUJFUl9GSUVMRCIsIkJvb2xlYW4iLCJTQ0hFTUFfQk9PTEVBTl9GSUVMRCIsIkFycmF5IiwiU0NIRU1BX0FSUkFZX0ZJRUxEIiwiT2JqZWN0IiwiU0NIRU1BX09CSkVDVF9GSUVMRCIsIkRhdGUiLCJTQ0hFTUFfREFURV9GSUVMRCIsIkZpbGUiLCJTQ0hFTUFfRklMRV9GSUVMRCIsIkdlb1BvaW50IiwiU0NIRU1BX0dFT19QT0lOVF9GSUVMRCIsIlBvbHlnb24iLCJTQ0hFTUFfUE9MWUdPTl9GSUVMRCIsIkJ5dGVzIiwiU0NIRU1BX0JZVEVTX0ZJRUxEIiwiUG9pbnRlciIsIlNDSEVNQV9QT0lOVEVSX0ZJRUxEIiwiUmVsYXRpb24iLCJTQ0hFTUFfUkVMQVRJT05fRklFTEQiLCJBQ0wiLCJTQ0hFTUFfQUNMX0ZJRUxEIiwiU0NIRU1BX1NUUklOR19GSUVMRF9JTlBVVCIsIkdyYXBoUUxPYmplY3RUeXBlIiwiaW50ZXJmYWNlcyIsIlNDSEVNQV9OVU1CRVJfRklFTERfSU5QVVQiLCJTQ0hFTUFfQk9PTEVBTl9GSUVMRF9JTlBVVCIsIlNDSEVNQV9BUlJBWV9GSUVMRF9JTlBVVCIsIlNDSEVNQV9PQkpFQ1RfRklFTERfSU5QVVQiLCJTQ0hFTUFfREFURV9GSUVMRF9JTlBVVCIsIlNDSEVNQV9GSUxFX0ZJRUxEX0lOUFVUIiwiU0NIRU1BX0dFT19QT0lOVF9GSUVMRF9JTlBVVCIsIlNDSEVNQV9QT0xZR09OX0ZJRUxEX0lOUFVUIiwiU0NIRU1BX0JZVEVTX0ZJRUxEX0lOUFVUIiwiVEFSR0VUX0NMQVNTX0FUVCIsIlNDSEVNQV9QT0lOVEVSX0ZJRUxEX0lOUFVUIiwidGFyZ2V0Q2xhc3NOYW1lIiwiU0NIRU1BX1JFTEFUSU9OX0ZJRUxEX0lOUFVUIiwiU0NIRU1BX0ZJRUxEU19JTlBVVCIsImFkZFN0cmluZ3MiLCJHcmFwaFFMTGlzdCIsImFkZE51bWJlcnMiLCJhZGRCb29sZWFucyIsImFkZEFycmF5cyIsImFkZE9iamVjdHMiLCJhZGREYXRlcyIsImFkZEZpbGVzIiwiYWRkR2VvUG9pbnQiLCJhZGRQb2x5Z29ucyIsImFkZEJ5dGVzIiwiYWRkUG9pbnRlcnMiLCJhZGRSZWxhdGlvbnMiLCJyZW1vdmUiLCJDTEFTU19OQU1FX0FUVCIsIkNMQVNTIiwic2NoZW1hRmllbGRzIiwibG9hZCIsInBhcnNlR3JhcGhRTFNjaGVtYSIsImFkZEdyYXBoUUxUeXBlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBU0EsTUFBTUEscUJBQXFCLEdBQUc7QUFDNUJDLEVBQUFBLFdBQVcsRUFBRSx5QkFEZTtBQUU1QkMsRUFBQUEsSUFBSSxFQUFFLElBQUlDLHVCQUFKLENBQW1CQyxzQkFBbkI7QUFGc0IsQ0FBOUI7O0FBS0EsTUFBTUMsa0JBQWtCLEdBQUcsSUFBSUMsK0JBQUosQ0FBMkI7QUFDcERDLEVBQUFBLElBQUksRUFBRSxrQkFEOEM7QUFFcEROLEVBQUFBLFdBQVcsRUFBRSw0RUFGdUM7QUFHcERPLEVBQUFBLE1BQU0sRUFBRTtBQUNORCxJQUFBQSxJQUFJLEVBQUVQO0FBREE7QUFINEMsQ0FBM0IsQ0FBM0I7O0FBUUEsTUFBTVMsWUFBWSxHQUFHLElBQUlDLDZCQUFKLENBQXlCO0FBQzVDSCxFQUFBQSxJQUFJLEVBQUUsYUFEc0M7QUFFNUNOLEVBQUFBLFdBQVcsRUFDVCxxSEFIMEM7QUFJNUNPLEVBQUFBLE1BQU0s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QUFuQixDQUFrQzFCLDBCQUFsQyxFQUE4RCxJQUE5RDtBQUNBeUIsRUFBQUEsa0JBQWtCLENBQUNDLGNBQW5CLENBQWtDN0Msb0JBQWxDLEVBQXdELElBQXhEO0FBQ0E0QyxFQUFBQSxrQkFBa0IsQ0FBQ0MsY0FBbkIsQ0FBa0N6Qix3QkFBbEMsRUFBNEQsSUFBNUQ7QUFDQXdCLEVBQUFBLGtCQUFrQixDQUFDQyxjQUFuQixDQUFrQzNDLGtCQUFsQyxFQUFzRCxJQUF0RDtBQUNBMEMsRUFBQUEsa0JBQWtCLENBQUNDLGNBQW5CLENBQWtDdkIsMEJBQWxDLEVBQThELElBQTlEO0FBQ0FzQixFQUFBQSxrQkFBa0IsQ0FBQ0MsY0FBbkIsQ0FBa0N6QyxvQkFBbEMsRUFBd0QsSUFBeEQ7QUFDQXdDLEVBQUFBLGtCQUFrQixDQUFDQyxjQUFuQixDQUFrQ3JCLDJCQUFsQyxFQUErRCxJQUEvRDtBQUNBb0IsRUFBQUEsa0JBQWtCLENBQUNDLGNBQW5CLENBQWtDdkMscUJBQWxDLEVBQXlELElBQXpEO0FBQ0FzQyxFQUFBQSxrQkFBa0IsQ0FBQ0MsY0FBbkIsQ0FBa0NyQyxnQkFBbEMsRUFBb0QsSUFBcEQ7QUFDQW9DLEVBQUFBLGtCQUFrQixDQUFDQyxjQUFuQixDQUFrQ3BCLG1CQUFsQyxFQUF1RCxJQUF2RDtBQUNBbUIsRUFBQUEsa0JBQWtCLENBQUNDLGNBQW5CLENBQWtDSixLQUFsQyxFQUF5QyxJQUF6QztBQUNELENBN0JEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgR3JhcGhRTE5vbk51bGwsXG4gIEdyYXBoUUxTdHJpbmcsXG4gIEdyYXBoUUxJbnB1dE9iamVjdFR5cGUsXG4gIEdyYXBoUUxMaXN0LFxuICBHcmFwaFFMT2JqZWN0VHlwZSxcbiAgR3JhcGhRTEludGVyZmFjZVR5cGUsXG59IGZyb20gJ2dyYXBocWwnO1xuXG5jb25zdCBTQ0hFTUFfRklFTERfTkFNRV9BVFQgPSB7XG4gIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgZmllbGQgbmFtZS4nLFxuICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG59O1xuXG5jb25zdCBTQ0hFTUFfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFGaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246ICdUaGUgU2NoZW1hRmllbGRJbnB1dCBpcyB1c2VkIHRvIHNwZWNpZnkgYSBmaWVsZCBvZiBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfRklFTEQgPSBuZXcgR3JhcGhRTEludGVyZmFjZVR5cGUoe1xuICBuYW1lOiAnU2NoZW1hRmllbGQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYUZpZWxkIGludGVyZmFjZSB0eXBlIGlzIHVzZWQgYXMgYSBiYXNlIHR5cGUgZm9yIHRoZSBkaWZmZXJlbnQgc3VwcG9ydGVkIGZpZWxkcyBvZiBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbiAgcmVzb2x2ZVR5cGU6IHZhbHVlID0+XG4gICAgKHtcbiAgICAgIFN0cmluZzogU0NIRU1BX1NUUklOR19GSUVMRCxcbiAgICAgIE51bWJlcjogU0NIRU1BX05VTUJFUl9GSUVMRCxcbiAgICAgIEJvb2xlYW46IFNDSEVNQV9CT09MRUFOX0ZJRUxELFxuICAgICAgQXJyYXk6IFNDSEVNQV9BUlJBWV9GSUVMRCxcbiAgICAgIE9iamVjdDogU0NIRU1BX09CSkVDVF9GSUVMRCxcbiAgICAgIERhdGU6IFNDSEVNQV9EQVRFX0ZJRUxELFxuICAgICAgRmlsZTogU0NIRU1BX0ZJTEVfRklFTEQsXG4gICAgICBHZW9Qb2ludDogU0NIRU1BX0dFT19QT0lOVF9GSUVMRCxcbiAgICAgIFBvbHlnb246IFNDSEVNQV9QT0xZR09OX0ZJRUxELFxuICAgICAgQnl0ZXM6IFNDSEVNQV9CWVRFU19GSUVMRCxcbiAgICAgIFBvaW50ZXI6IFNDSEVNQV9QT0lOVEVSX0ZJRUxELFxuICAgICAgUmVsYXRpb246IFNDSEVNQV9SRUxBVElPTl9GSUVMRCxcbiAgICAgIEFDTDogU0NIRU1BX0FDTF9GSUVMRCxcbiAgICB9W3ZhbHVlLnR5cGVdKSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfU1RSSU5HX0ZJRUxEX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hU3RyaW5nRmllbGRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hU3RyaW5nRmllbGRJbnB1dCBpcyB1c2VkIHRvIHNwZWNpZnkgYSBmaWVsZCBvZiB0eXBlIHN0cmluZyBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX1NUUklOR19GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFTdHJpbmdGaWVsZCcsXG4gIGRlc2NyaXB0aW9uOiAnVGhlIFNjaGVtYVN0cmluZ0ZpZWxkIGlzIHVzZWQgdG8gcmV0dXJuIGluZm9ybWF0aW9uIG9mIGEgU3RyaW5nIGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX05VTUJFUl9GSUVMRF9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYU51bWJlckZpZWxkSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYU51bWJlckZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSBudW1iZXIgZm9yIGFuIG9iamVjdCBjbGFzcyBzY2hlbWEuJyxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9OVU1CRVJfRklFTEQgPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hTnVtYmVyRmllbGQnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBTY2hlbWFOdW1iZXJGaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhIE51bWJlciBmaWVsZC4nLFxuICBpbnRlcmZhY2VzOiBbU0NIRU1BX0ZJRUxEXSxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9CT09MRUFOX0ZJRUxEX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hQm9vbGVhbkZpZWxkSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFNjaGVtYUJvb2xlYW5GaWVsZElucHV0IGlzIHVzZWQgdG8gc3BlY2lmeSBhIGZpZWxkIG9mIHR5cGUgYm9vbGVhbiBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0JPT0xFQU5fRklFTEQgPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hQm9vbGVhbkZpZWxkJyxcbiAgZGVzY3JpcHRpb246ICdUaGUgU2NoZW1hQm9vbGVhbkZpZWxkIGlzIHVzZWQgdG8gcmV0dXJuIGluZm9ybWF0aW9uIG9mIGEgQm9vbGVhbiBmaWVsZC4nLFxuICBpbnRlcmZhY2VzOiBbU0NIRU1BX0ZJRUxEXSxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9BUlJBWV9GSUVMRF9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYUFycmF5RmllbGRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hQXJyYXlGaWVsZElucHV0IGlzIHVzZWQgdG8gc3BlY2lmeSBhIGZpZWxkIG9mIHR5cGUgYXJyYXkgZm9yIGFuIG9iamVjdCBjbGFzcyBzY2hlbWEuJyxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9BUlJBWV9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFBcnJheUZpZWxkJyxcbiAgZGVzY3JpcHRpb246ICdUaGUgU2NoZW1hQXJyYXlGaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhbiBBcnJheSBmaWVsZC4nLFxuICBpbnRlcmZhY2VzOiBbU0NIRU1BX0ZJRUxEXSxcbiAgZmllbGRzOiB7XG4gICAgbmFtZTogU0NIRU1BX0ZJRUxEX05BTUVfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9PQkpFQ1RfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFPYmplY3RGaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFPYmplY3RGaWVsZElucHV0IGlzIHVzZWQgdG8gc3BlY2lmeSBhIGZpZWxkIG9mIHR5cGUgb2JqZWN0IGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfT0JKRUNUX0ZJRUxEID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYU9iamVjdEZpZWxkJyxcbiAgZGVzY3JpcHRpb246ICdUaGUgU2NoZW1hT2JqZWN0RmllbGQgaXMgdXNlZCB0byByZXR1cm4gaW5mb3JtYXRpb24gb2YgYW4gT2JqZWN0IGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0RBVEVfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFEYXRlRmllbGRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hRGF0ZUZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSBkYXRlIGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfREFURV9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFEYXRlRmllbGQnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBTY2hlbWFEYXRlRmllbGQgaXMgdXNlZCB0byByZXR1cm4gaW5mb3JtYXRpb24gb2YgYSBEYXRlIGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0ZJTEVfRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFGaWxlRmllbGRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hRmlsZUZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSBmaWxlIGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfRklMRV9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFGaWxlRmllbGQnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBTY2hlbWFGaWxlRmllbGQgaXMgdXNlZCB0byByZXR1cm4gaW5mb3JtYXRpb24gb2YgYSBGaWxlIGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0dFT19QT0lOVF9GSUVMRF9JTlBVVCA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYUdlb1BvaW50RmllbGRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hR2VvUG9pbnRGaWVsZElucHV0IGlzIHVzZWQgdG8gc3BlY2lmeSBhIGZpZWxkIG9mIHR5cGUgZ2VvIHBvaW50IGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfR0VPX1BPSU5UX0ZJRUxEID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYUdlb1BvaW50RmllbGQnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBTY2hlbWFHZW9Qb2ludEZpZWxkIGlzIHVzZWQgdG8gcmV0dXJuIGluZm9ybWF0aW9uIG9mIGEgR2VvIFBvaW50IGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX1BPTFlHT05fRklFTERfSU5QVVQgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFQb2x5Z29uRmllbGRJbnB1dCcsXG4gIGRlc2NyaXB0aW9uOlxuICAgICdUaGUgU2NoZW1hUG9seWdvbkZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSBwb2x5Z29uIGZvciBhbiBvYmplY3QgY2xhc3Mgc2NoZW1hLicsXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfUE9MWUdPTl9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFQb2x5Z29uRmllbGQnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBTY2hlbWFQb2x5Z29uRmllbGQgaXMgdXNlZCB0byByZXR1cm4gaW5mb3JtYXRpb24gb2YgYSBQb2x5Z29uIGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0JZVEVTX0ZJRUxEX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hQnl0ZXNGaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBTY2hlbWFCeXRlc0ZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSBieXRlcyBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX0JZVEVTX0ZJRUxEID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYUJ5dGVzRmllbGQnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBTY2hlbWFCeXRlc0ZpZWxkIGlzIHVzZWQgdG8gcmV0dXJuIGluZm9ybWF0aW9uIG9mIGEgQnl0ZXMgZmllbGQuJyxcbiAgaW50ZXJmYWNlczogW1NDSEVNQV9GSUVMRF0sXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBUQVJHRVRfQ0xBU1NfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIG5hbWUgb2YgdGhlIHRhcmdldCBjbGFzcyBmb3IgdGhlIGZpZWxkLicsXG4gIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbn07XG5cbmNvbnN0IFNDSEVNQV9QT0lOVEVSX0ZJRUxEX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnUG9pbnRlckZpZWxkSW5wdXQnLFxuICBkZXNjcmlwdGlvbjpcbiAgICAnVGhlIFBvaW50ZXJGaWVsZElucHV0IGlzIHVzZWQgdG8gc3BlY2lmeSBhIGZpZWxkIG9mIHR5cGUgcG9pbnRlciBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gICAgdGFyZ2V0Q2xhc3NOYW1lOiBUQVJHRVRfQ0xBU1NfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9QT0lOVEVSX0ZJRUxEID0gbmV3IEdyYXBoUUxPYmplY3RUeXBlKHtcbiAgbmFtZTogJ1NjaGVtYVBvaW50ZXJGaWVsZCcsXG4gIGRlc2NyaXB0aW9uOiAnVGhlIFNjaGVtYVBvaW50ZXJGaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhIFBvaW50ZXIgZmllbGQuJyxcbiAgaW50ZXJmYWNlczogW1NDSEVNQV9GSUVMRF0sXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgICB0YXJnZXRDbGFzc05hbWU6IFRBUkdFVF9DTEFTU19BVFQsXG4gIH0sXG59KTtcblxuY29uc3QgU0NIRU1BX1JFTEFUSU9OX0ZJRUxEX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnUmVsYXRpb25GaWVsZElucHV0JyxcbiAgZGVzY3JpcHRpb246XG4gICAgJ1RoZSBSZWxhdGlvbkZpZWxkSW5wdXQgaXMgdXNlZCB0byBzcGVjaWZ5IGEgZmllbGQgb2YgdHlwZSByZWxhdGlvbiBmb3IgYW4gb2JqZWN0IGNsYXNzIHNjaGVtYS4nLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gICAgdGFyZ2V0Q2xhc3NOYW1lOiBUQVJHRVRfQ0xBU1NfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9SRUxBVElPTl9GSUVMRCA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdTY2hlbWFSZWxhdGlvbkZpZWxkJyxcbiAgZGVzY3JpcHRpb246ICdUaGUgU2NoZW1hUmVsYXRpb25GaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhIFJlbGF0aW9uIGZpZWxkLicsXG4gIGludGVyZmFjZXM6IFtTQ0hFTUFfRklFTERdLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBTQ0hFTUFfRklFTERfTkFNRV9BVFQsXG4gICAgdGFyZ2V0Q2xhc3NOYW1lOiBUQVJHRVRfQ0xBU1NfQVRULFxuICB9LFxufSk7XG5cbmNvbnN0IFNDSEVNQV9BQ0xfRklFTEQgPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hQUNMRmllbGQnLFxuICBkZXNjcmlwdGlvbjogJ1RoZSBTY2hlbWFBQ0xGaWVsZCBpcyB1c2VkIHRvIHJldHVybiBpbmZvcm1hdGlvbiBvZiBhbiBBQ0wgZmllbGQuJyxcbiAgaW50ZXJmYWNlczogW1NDSEVNQV9GSUVMRF0sXG4gIGZpZWxkczoge1xuICAgIG5hbWU6IFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgfSxcbn0pO1xuXG5jb25zdCBTQ0hFTUFfRklFTERTX0lOUFVUID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICBuYW1lOiAnU2NoZW1hRmllbGRzSW5wdXQnLFxuICBkZXNjcmlwdGlvbjogYFRoZSBDcmVhdGVDbGFzc1NjaGVtYUlucHV0IHR5cGUgaXMgdXNlZCB0byBzcGVjaWZ5IHRoZSBzY2hlbWEgZm9yIGEgbmV3IG9iamVjdCBjbGFzcyB0byBiZSBjcmVhdGVkLmAsXG4gIGZpZWxkczoge1xuICAgIGFkZFN0cmluZ3M6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlc2UgYXJlIHRoZSBTdHJpbmcgZmllbGRzIHRvIGJlIGFkZGVkIHRvIHRoZSBjbGFzcyBzY2hlbWEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoU0NIRU1BX1NUUklOR19GSUVMRF9JTlBVVCkpLFxuICAgIH0sXG4gICAgYWRkTnVtYmVyczoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIE51bWJlciBmaWVsZHMgdG8gYmUgYWRkZWQgdG8gdGhlIGNsYXNzIHNjaGVtYS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfTlVNQkVSX0ZJRUxEX0lOUFVUKSksXG4gICAgfSxcbiAgICBhZGRCb29sZWFuczoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIEJvb2xlYW4gZmllbGRzIHRvIGJlIGFkZGVkIHRvIHRoZSBjbGFzcyBzY2hlbWEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoU0NIRU1BX0JPT0xFQU5fRklFTERfSU5QVVQpKSxcbiAgICB9LFxuICAgIGFkZEFycmF5czoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIEFycmF5IGZpZWxkcyB0byBiZSBhZGRlZCB0byB0aGUgY2xhc3Mgc2NoZW1hLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKFNDSEVNQV9BUlJBWV9GSUVMRF9JTlBVVCkpLFxuICAgIH0sXG4gICAgYWRkT2JqZWN0czoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIE9iamVjdCBmaWVsZHMgdG8gYmUgYWRkZWQgdG8gdGhlIGNsYXNzIHNjaGVtYS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfT0JKRUNUX0ZJRUxEX0lOUFVUKSksXG4gICAgfSxcbiAgICBhZGREYXRlczoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIERhdGUgZmllbGRzIHRvIGJlIGFkZGVkIHRvIHRoZSBjbGFzcyBzY2hlbWEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoU0NIRU1BX0RBVEVfRklFTERfSU5QVVQpKSxcbiAgICB9LFxuICAgIGFkZEZpbGVzOiB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZXNlIGFyZSB0aGUgRmlsZSBmaWVsZHMgdG8gYmUgYWRkZWQgdG8gdGhlIGNsYXNzIHNjaGVtYS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfRklMRV9GSUVMRF9JTlBVVCkpLFxuICAgIH0sXG4gICAgYWRkR2VvUG9pbnQ6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnVGhpcyBpcyB0aGUgR2VvIFBvaW50IGZpZWxkIHRvIGJlIGFkZGVkIHRvIHRoZSBjbGFzcyBzY2hlbWEuIEN1cnJlbnRseSBpdCBpcyBzdXBwb3J0ZWQgb25seSBvbmUgR2VvUG9pbnQgZmllbGQgcGVyIENsYXNzLicsXG4gICAgICB0eXBlOiBTQ0hFTUFfR0VPX1BPSU5UX0ZJRUxEX0lOUFVULFxuICAgIH0sXG4gICAgYWRkUG9seWdvbnM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlc2UgYXJlIHRoZSBQb2x5Z29uIGZpZWxkcyB0byBiZSBhZGRlZCB0byB0aGUgY2xhc3Mgc2NoZW1hLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKFNDSEVNQV9QT0xZR09OX0ZJRUxEX0lOUFVUKSksXG4gICAgfSxcbiAgICBhZGRCeXRlczoge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIEJ5dGVzIGZpZWxkcyB0byBiZSBhZGRlZCB0byB0aGUgY2xhc3Mgc2NoZW1hLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKFNDSEVNQV9CWVRFU19GSUVMRF9JTlBVVCkpLFxuICAgIH0sXG4gICAgYWRkUG9pbnRlcnM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlc2UgYXJlIHRoZSBQb2ludGVyIGZpZWxkcyB0byBiZSBhZGRlZCB0byB0aGUgY2xhc3Mgc2NoZW1hLicsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKFNDSEVNQV9QT0lOVEVSX0ZJRUxEX0lOUFVUKSksXG4gICAgfSxcbiAgICBhZGRSZWxhdGlvbnM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlc2UgYXJlIHRoZSBSZWxhdGlvbiBmaWVsZHMgdG8gYmUgYWRkZWQgdG8gdGhlIGNsYXNzIHNjaGVtYS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfUkVMQVRJT05fRklFTERfSU5QVVQpKSxcbiAgICB9LFxuICAgIHJlbW92ZToge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGVzZSBhcmUgdGhlIGZpZWxkcyB0byBiZSByZW1vdmVkIGZyb20gdGhlIGNsYXNzIHNjaGVtYS4nLFxuICAgICAgdHlwZTogbmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfRklFTERfSU5QVVQpKSxcbiAgICB9LFxuICB9LFxufSk7XG5cbmNvbnN0IENMQVNTX05BTUVfQVRUID0ge1xuICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIG5hbWUgb2YgdGhlIG9iamVjdCBjbGFzcy4nLFxuICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG59O1xuXG5jb25zdCBDTEFTUyA9IG5ldyBHcmFwaFFMT2JqZWN0VHlwZSh7XG4gIG5hbWU6ICdDbGFzcycsXG4gIGRlc2NyaXB0aW9uOiBgVGhlIENsYXNzIHR5cGUgaXMgdXNlZCB0byByZXR1cm4gdGhlIGluZm9ybWF0aW9uIGFib3V0IGFuIG9iamVjdCBjbGFzcy5gLFxuICBmaWVsZHM6IHtcbiAgICBuYW1lOiBDTEFTU19OQU1FX0FUVCxcbiAgICBzY2hlbWFGaWVsZHM6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlRoZXNlIGFyZSB0aGUgc2NoZW1hJ3MgZmllbGRzIG9mIHRoZSBvYmplY3QgY2xhc3MuXCIsXG4gICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwobmV3IEdyYXBoUUxMaXN0KG5ldyBHcmFwaFFMTm9uTnVsbChTQ0hFTUFfRklFTEQpKSksXG4gICAgfSxcbiAgfSxcbn0pO1xuXG5jb25zdCBsb2FkID0gcGFyc2VHcmFwaFFMU2NoZW1hID0+IHtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfU1RSSU5HX0ZJRUxEX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9TVFJJTkdfRklFTEQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX05VTUJFUl9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfTlVNQkVSX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9CT09MRUFOX0ZJRUxEX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9CT09MRUFOX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9BUlJBWV9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfQVJSQVlfRklFTEQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX09CSkVDVF9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfT0JKRUNUX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9EQVRFX0ZJRUxEX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9EQVRFX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9GSUxFX0ZJRUxEX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9GSUxFX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9HRU9fUE9JTlRfRklFTERfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX0dFT19QT0lOVF9GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfUE9MWUdPTl9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfUE9MWUdPTl9GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfQllURVNfRklFTERfSU5QVVQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX0JZVEVTX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9QT0lOVEVSX0ZJRUxEX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9QT0lOVEVSX0ZJRUxELCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFNDSEVNQV9SRUxBVElPTl9GSUVMRF9JTlBVVCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfUkVMQVRJT05fRklFTEQsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoU0NIRU1BX0FDTF9GSUVMRCwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShTQ0hFTUFfRklFTERTX0lOUFVULCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKENMQVNTLCB0cnVlKTtcbn07XG5cbmV4cG9ydCB7XG4gIFNDSEVNQV9GSUVMRF9OQU1FX0FUVCxcbiAgU0NIRU1BX0ZJRUxEX0lOUFVULFxuICBTQ0hFTUFfU1RSSU5HX0ZJRUxEX0lOUFVULFxuICBTQ0hFTUFfU1RSSU5HX0ZJRUxELFxuICBTQ0hFTUFfTlVNQkVSX0ZJRUxEX0lOUFVULFxuICBTQ0hFTUFfTlVNQkVSX0ZJRUxELFxuICBTQ0hFTUFfQk9PTEVBTl9GSUVMRF9JTlBVVCxcbiAgU0NIRU1BX0JPT0xFQU5fRklFTEQsXG4gIFNDSEVNQV9BUlJBWV9GSUVMRF9JTlBVVCxcbiAgU0NIRU1BX0FSUkFZX0ZJRUxELFxuICBTQ0hFTUFfT0JKRUNUX0ZJRUxEX0lOUFVULFxuICBTQ0hFTUFfT0JKRUNUX0ZJRUxELFxuICBTQ0hFTUFfREFURV9GSUVMRF9JTlBVVCxcbiAgU0NIRU1BX0RBVEVfRklFTEQsXG4gIFNDSEVNQV9GSUxFX0ZJRUxEX0lOUFVULFxuICBTQ0hFTUFfRklMRV9GSUVMRCxcbiAgU0NIRU1BX0dFT19QT0lOVF9GSUVMRF9JTlBVVCxcbiAgU0NIRU1BX0dFT19QT0lOVF9GSUVMRCxcbiAgU0NIRU1BX1BPTFlHT05fRklFTERfSU5QVVQsXG4gIFNDSEVNQV9QT0xZR09OX0ZJRUxELFxuICBTQ0hFTUFfQllURVNfRklFTERfSU5QVVQsXG4gIFNDSEVNQV9CWVRFU19GSUVMRCxcbiAgVEFSR0VUX0NMQVNTX0FUVCxcbiAgU0NIRU1BX1BPSU5URVJfRklFTERfSU5QVVQsXG4gIFNDSEVNQV9QT0lOVEVSX0ZJRUxELFxuICBTQ0hFTUFfUkVMQVRJT05fRklFTERfSU5QVVQsXG4gIFNDSEVNQV9SRUxBVElPTl9GSUVMRCxcbiAgU0NIRU1BX0FDTF9GSUVMRCxcbiAgU0NIRU1BX0ZJRUxEU19JTlBVVCxcbiAgQ0xBU1NfTkFNRV9BVFQsXG4gIENMQVNTLFxuICBsb2FkLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/usersMutations.js b/lib/GraphQL/loaders/usersMutations.js deleted file mode 100644 index 9170c52015..0000000000 --- a/lib/GraphQL/loaders/usersMutations.js +++ /dev/null @@ -1,332 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.load = void 0; - -var _graphql = require("graphql"); - -var _graphqlRelay = require("graphql-relay"); - -var _UsersRouter = _interopRequireDefault(require("../../Routers/UsersRouter")); - -var objectsMutations = _interopRequireWildcard(require("../helpers/objectsMutations")); - -var _defaultGraphQLTypes = require("./defaultGraphQLTypes"); - -var _usersQueries = require("./usersQueries"); - -var _mutation = require("../transformers/mutation"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const usersRouter = new _UsersRouter.default(); - -const load = parseGraphQLSchema => { - if (parseGraphQLSchema.isUsersClassDisabled) { - return; - } - - const signUpMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'SignUp', - description: 'The signUp mutation can be used to create and sign up a new user.', - inputFields: { - fields: { - descriptions: 'These are the fields of the new user to be created and signed up.', - type: parseGraphQLSchema.parseClassTypes['_User'].classGraphQLCreateType - } - }, - outputFields: { - viewer: { - description: 'This is the new user that was created, signed up and returned as a viewer.', - type: new _graphql.GraphQLNonNull(parseGraphQLSchema.viewerType) - } - }, - mutateAndGetPayload: async (args, context, mutationInfo) => { - try { - const { - fields - } = args; - const { - config, - auth, - info - } = context; - const parseFields = await (0, _mutation.transformTypes)('create', fields, { - className: '_User', - parseGraphQLSchema, - req: { - config, - auth, - info - } - }); - const { - sessionToken, - objectId - } = await objectsMutations.createObject('_User', parseFields, config, auth, info); - context.info.sessionToken = sessionToken; - return { - viewer: await (0, _usersQueries.getUserFromSessionToken)(context, mutationInfo, 'viewer.user.', objectId) - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(signUpMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(signUpMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('signUp', signUpMutation, true, true); - const logInWithMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'LogInWith', - description: 'The logInWith mutation can be used to signup, login user with 3rd party authentication system. This mutation create a user if the authData do not correspond to an existing one.', - inputFields: { - authData: { - descriptions: 'This is the auth data of your custom auth provider', - type: new _graphql.GraphQLNonNull(_defaultGraphQLTypes.OBJECT) - }, - fields: { - descriptions: 'These are the fields of the user to be created/updated and logged in.', - type: new _graphql.GraphQLInputObjectType({ - name: 'UserLoginWithInput', - fields: () => { - const classGraphQLCreateFields = parseGraphQLSchema.parseClassTypes['_User'].classGraphQLCreateType.getFields(); - return Object.keys(classGraphQLCreateFields).reduce((fields, fieldName) => { - if (fieldName !== 'password' && fieldName !== 'username' && fieldName !== 'authData') { - fields[fieldName] = classGraphQLCreateFields[fieldName]; - } - - return fields; - }, {}); - } - }) - } - }, - outputFields: { - viewer: { - description: 'This is the new user that was created, signed up and returned as a viewer.', - type: new _graphql.GraphQLNonNull(parseGraphQLSchema.viewerType) - } - }, - mutateAndGetPayload: async (args, context, mutationInfo) => { - try { - const { - fields, - authData - } = args; - const { - config, - auth, - info - } = context; - const parseFields = await (0, _mutation.transformTypes)('create', fields, { - className: '_User', - parseGraphQLSchema, - req: { - config, - auth, - info - } - }); - const { - sessionToken, - objectId - } = await objectsMutations.createObject('_User', _objectSpread(_objectSpread({}, parseFields), {}, { - authData - }), config, auth, info); - context.info.sessionToken = sessionToken; - return { - viewer: await (0, _usersQueries.getUserFromSessionToken)(context, mutationInfo, 'viewer.user.', objectId) - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(logInWithMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(logInWithMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('logInWith', logInWithMutation, true, true); - const logInMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'LogIn', - description: 'The logIn mutation can be used to log in an existing user.', - inputFields: { - username: { - description: 'This is the username used to log in the user.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - }, - password: { - description: 'This is the password used to log in the user.', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - } - }, - outputFields: { - viewer: { - description: 'This is the existing user that was logged in and returned as a viewer.', - type: new _graphql.GraphQLNonNull(parseGraphQLSchema.viewerType) - } - }, - mutateAndGetPayload: async (args, context, mutationInfo) => { - try { - const { - username, - password - } = args; - const { - config, - auth, - info - } = context; - const { - sessionToken, - objectId - } = (await usersRouter.handleLogIn({ - body: { - username, - password - }, - query: {}, - config, - auth, - info - })).response; - context.info.sessionToken = sessionToken; - return { - viewer: await (0, _usersQueries.getUserFromSessionToken)(context, mutationInfo, 'viewer.user.', objectId) - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(logInMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(logInMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('logIn', logInMutation, true, true); - const logOutMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'LogOut', - description: 'The logOut mutation can be used to log out an existing user.', - outputFields: { - ok: { - description: "It's always true.", - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - } - }, - mutateAndGetPayload: async (_args, context) => { - try { - const { - config, - auth, - info - } = context; - await usersRouter.handleLogOut({ - config, - auth, - info - }); - return { - ok: true - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(logOutMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(logOutMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('logOut', logOutMutation, true, true); - const resetPasswordMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'ResetPassword', - description: 'The resetPassword mutation can be used to reset the password of an existing user.', - inputFields: { - email: { - descriptions: 'Email of the user that should receive the reset email', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - } - }, - outputFields: { - ok: { - description: "It's always true.", - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - } - }, - mutateAndGetPayload: async ({ - email - }, context) => { - const { - config, - auth, - info - } = context; - await usersRouter.handleResetRequest({ - body: { - email - }, - config, - auth, - info - }); - return { - ok: true - }; - } - }); - parseGraphQLSchema.addGraphQLType(resetPasswordMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(resetPasswordMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('resetPassword', resetPasswordMutation, true, true); - const sendVerificationEmailMutation = (0, _graphqlRelay.mutationWithClientMutationId)({ - name: 'SendVerificationEmail', - description: 'The sendVerificationEmail mutation can be used to send the verification email again.', - inputFields: { - email: { - descriptions: 'Email of the user that should receive the verification email', - type: new _graphql.GraphQLNonNull(_graphql.GraphQLString) - } - }, - outputFields: { - ok: { - description: "It's always true.", - type: new _graphql.GraphQLNonNull(_graphql.GraphQLBoolean) - } - }, - mutateAndGetPayload: async ({ - email - }, context) => { - try { - const { - config, - auth, - info - } = context; - await usersRouter.handleVerificationEmailRequest({ - body: { - email - }, - config, - auth, - info - }); - return { - ok: true - }; - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - }); - parseGraphQLSchema.addGraphQLType(sendVerificationEmailMutation.args.input.type.ofType, true, true); - parseGraphQLSchema.addGraphQLType(sendVerificationEmailMutation.type, true, true); - parseGraphQLSchema.addGraphQLMutation('sendVerificationEmail', sendVerificationEmailMutation, true, true); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvdXNlcnNNdXRhdGlvbnMuanMiXSwibmFtZXMiOlsidXNlcnNSb3V0ZXIiLCJVc2Vyc1JvdXRlciIsImxvYWQiLCJwYXJzZUdyYXBoUUxTY2hlbWEiLCJpc1VzZXJzQ2xhc3NEaXNhYmxlZCIsInNpZ25VcE11dGF0aW9uIiwibmFtZSIsImRlc2NyaXB0aW9uIiwiaW5wdXRGaWVsZHMiLCJmaWVsZHMiLCJkZXNjcmlwdGlvbnMiLCJ0eXBlIiwicGFyc2VDbGFzc1R5cGVzIiwiY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSIsIm91dHB1dEZpZWxkcyIsInZpZXdlciIsIkdyYXBoUUxOb25OdWxsIiwidmlld2VyVHlwZSIsIm11dGF0ZUFuZEdldFBheWxvYWQiLCJhcmdzIiwiY29udGV4dCIsIm11dGF0aW9uSW5mbyIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwicGFyc2VGaWVsZHMiLCJjbGFzc05hbWUiLCJyZXEiLCJzZXNzaW9uVG9rZW4iLCJvYmplY3RJZCIsIm9iamVjdHNNdXRhdGlvbnMiLCJjcmVhdGVPYmplY3QiLCJlIiwiaGFuZGxlRXJyb3IiLCJhZGRHcmFwaFFMVHlwZSIsImlucHV0Iiwib2ZUeXBlIiwiYWRkR3JhcGhRTE11dGF0aW9uIiwibG9nSW5XaXRoTXV0YXRpb24iLCJhdXRoRGF0YSIsIk9CSkVDVCIsIkdyYXBoUUxJbnB1dE9iamVjdFR5cGUiLCJjbGFzc0dyYXBoUUxDcmVhdGVGaWVsZHMiLCJnZXRGaWVsZHMiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwiZmllbGROYW1lIiwibG9nSW5NdXRhdGlvbiIsInVzZXJuYW1lIiwiR3JhcGhRTFN0cmluZyIsInBhc3N3b3JkIiwiaGFuZGxlTG9nSW4iLCJib2R5IiwicXVlcnkiLCJyZXNwb25zZSIsImxvZ091dE11dGF0aW9uIiwib2siLCJHcmFwaFFMQm9vbGVhbiIsIl9hcmdzIiwiaGFuZGxlTG9nT3V0IiwicmVzZXRQYXNzd29yZE11dGF0aW9uIiwiZW1haWwiLCJoYW5kbGVSZXNldFJlcXVlc3QiLCJzZW5kVmVyaWZpY2F0aW9uRW1haWxNdXRhdGlvbiIsImhhbmRsZVZlcmlmaWNhdGlvbkVtYWlsUmVxdWVzdCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7Ozs7Ozs7OztBQUVBLE1BQU1BLFdBQVcsR0FBRyxJQUFJQyxvQkFBSixFQUFwQjs7QUFFQSxNQUFNQyxJQUFJLEdBQUdDLGtCQUFrQixJQUFJO0FBQ2pDLE1BQUlBLGtCQUFrQixDQUFDQyxvQkFBdkIsRUFBNkM7QUFDM0M7QUFDRDs7QUFFRCxRQUFNQyxjQUFjLEdBQUcsZ0RBQTZCO0FBQ2xEQyxJQUFBQSxJQUFJLEVBQUUsUUFENEM7QUFFbERDLElBQUFBLFdBQVcsRUFBRSxtRUFGcUM7QUFHbERDLElBQUFBLFdBQVcsRUFBRTtBQUNYQyxNQUFBQSxNQUFNLEVBQUU7QUFDTkMsUUFBQUEsWUFBWSxFQUFFLG1FQURSO0FBRU5DLFFBQUFBLElBQUksRUFBRVIsa0JBQWtCLENBQUNTLGVBQW5CLENBQW1DLE9BQW5DLEVBQTRDQztBQUY1QztBQURHLEtBSHFDO0FBU2xEQyxJQUFBQSxZQUFZLEVBQUU7QUFDWkMsTUFBQUEsTUFBTSxFQUFFO0FBQ05SLFFBQUFBLFdBQVcsRUFBRSw0RUFEUDtBQUVOSSxRQUFBQSxJQUFJLEVBQUUsSUFBSUssdUJBQUosQ0FBbUJiLGtCQUFrQixDQUFDYyxVQUF0QztBQUZBO0FBREksS0FUb0M7QUFlbERDLElBQUFBLG1CQUFtQixFQUFFLE9BQU9DLElBQVAsRUFBYUMsT0FBYixFQUFzQkMsWUFBdEIsS0FBdUM7QUFDMUQsVUFBSTtBQUNGLGNBQU07QUFBRVosVUFBQUE7QUFBRixZQUFhVSxJQUFuQjtBQUNBLGNBQU07QUFBRUcsVUFBQUEsTUFBRjtBQUFVQyxVQUFBQSxJQUFWO0FBQWdCQyxVQUFBQTtBQUFoQixZQUF5QkosT0FBL0I7QUFFQSxjQUFNSyxXQUFXLEdBQUcsTUFBTSw4QkFBZSxRQUFmLEVBQXlCaEIsTUFBekIsRUFBaUM7QUFDekRpQixVQUFBQSxTQUFTLEVBQUUsT0FEOEM7QUFFekR2QixVQUFBQSxrQkFGeUQ7QUFHekR3QixVQUFBQSxHQUFHLEVBQUU7QUFBRUwsWUFBQUEsTUFBRjtBQUFVQyxZQUFBQSxJQUFWO0FBQWdCQyxZQUFBQTtBQUFoQjtBQUhvRCxTQUFqQyxDQUExQjtBQU1BLGNBQU07QUFBRUksVUFBQUEsWUFBRjtBQUFnQkMsVUFBQUE7QUFBaEIsWUFBNkIsTUFBTUMsZ0JBQWdCLENBQUNDLFlBQWpCLENBQ3ZDLE9BRHVDLEVBRXZDTixXQUZ1QyxFQUd2Q0gsTUFIdUMsRUFJdkNDLElBSnVDLEVBS3ZDQyxJQUx1QyxDQUF6QztBQVFBSixRQUFBQSxPQUFPLENBQUNJLElBQVIsQ0FBYUksWUFBYixHQUE0QkEsWUFBNUI7QUFFQSxlQUFPO0FBQ0xiLFVBQUFBLE1BQU0sRUFBRSxNQUFNLDJDQUF3QkssT0FBeEIsRUFBaUNDLFlBQWpDLEVBQStDLGNBQS9DLEVBQStEUSxRQUEvRDtBQURULFNBQVA7QUFHRCxPQXZCRCxDQXVCRSxPQUFPRyxDQUFQLEVBQVU7QUFDVjdCLFFBQUFBLGtCQUFrQixDQUFDOEIsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRjtBQTFDaUQsR0FBN0IsQ0FBdkI7QUE2Q0E3QixFQUFBQSxrQkFBa0IsQ0FBQytCLGNBQW5CLENBQWtDN0IsY0FBYyxDQUFDYyxJQUFmLENBQW9CZ0IsS0FBcEIsQ0FBMEJ4QixJQUExQixDQUErQnlCLE1BQWpFLEVBQXlFLElBQXpFLEVBQStFLElBQS9FO0FBQ0FqQyxFQUFBQSxrQkFBa0IsQ0FBQytCLGNBQW5CLENBQWtDN0IsY0FBYyxDQUFDTSxJQUFqRCxFQUF1RCxJQUF2RCxFQUE2RCxJQUE3RDtBQUNBUixFQUFBQSxrQkFBa0IsQ0FBQ2tDLGtCQUFuQixDQUFzQyxRQUF0QyxFQUFnRGhDLGNBQWhELEVBQWdFLElBQWhFLEVBQXNFLElBQXRFO0FBQ0EsUUFBTWlDLGlCQUFpQixHQUFHLGdEQUE2QjtBQUNyRGhDLElBQUFBLElBQUksRUFBRSxXQUQrQztBQUVyREMsSUFBQUEsV0FBVyxFQUNULGtMQUhtRDtBQUlyREMsSUFBQUEsV0FBVyxFQUFFO0FBQ1grQixNQUFBQSxRQUFRLEVBQUU7QUFDUjdCLFFBQUFBLFlBQVksRUFBRSxvREFETjtBQUVSQyxRQUFBQSxJQUFJLEVBQUUsSUFBSUssdUJBQUosQ0FBbUJ3QiwyQkFBbkI7QUFGRSxPQURDO0FBS1gvQixNQUFBQSxNQUFNLEVBQUU7QUFDTkMsUUFBQUEsWUFBWSxFQUFFLHVFQURSO0FBRU5DLFFBQUFBLElBQUksRUFBRSxJQUFJOEIsK0JBQUosQ0FBMkI7QUFDL0JuQyxVQUFBQSxJQUFJLEVBQUUsb0JBRHlCO0FBRS9CRyxVQUFBQSxNQUFNLEVBQUUsTUFBTTtBQUNaLGtCQUFNaUMsd0JBQXdCLEdBQUd2QyxrQkFBa0IsQ0FBQ1MsZUFBbkIsQ0FDL0IsT0FEK0IsRUFFL0JDLHNCQUYrQixDQUVSOEIsU0FGUSxFQUFqQztBQUdBLG1CQUFPQyxNQUFNLENBQUNDLElBQVAsQ0FBWUgsd0JBQVosRUFBc0NJLE1BQXRDLENBQTZDLENBQUNyQyxNQUFELEVBQVNzQyxTQUFULEtBQXVCO0FBQ3pFLGtCQUNFQSxTQUFTLEtBQUssVUFBZCxJQUNBQSxTQUFTLEtBQUssVUFEZCxJQUVBQSxTQUFTLEtBQUssVUFIaEIsRUFJRTtBQUNBdEMsZ0JBQUFBLE1BQU0sQ0FBQ3NDLFNBQUQsQ0FBTixHQUFvQkwsd0JBQXdCLENBQUNLLFNBQUQsQ0FBNUM7QUFDRDs7QUFDRCxxQkFBT3RDLE1BQVA7QUFDRCxhQVRNLEVBU0osRUFUSSxDQUFQO0FBVUQ7QUFoQjhCLFNBQTNCO0FBRkE7QUFMRyxLQUp3QztBQStCckRLLElBQUFBLFlBQVksRUFBRTtBQUNaQyxNQUFBQSxNQUFNLEVBQUU7QUFDTlIsUUFBQUEsV0FBVyxFQUFFLDRFQURQO0FBRU5JLFFBQUFBLElBQUksRUFBRSxJQUFJSyx1QkFBSixDQUFtQmIsa0JBQWtCLENBQUNjLFVBQXRDO0FBRkE7QUFESSxLQS9CdUM7QUFxQ3JEQyxJQUFBQSxtQkFBbUIsRUFBRSxPQUFPQyxJQUFQLEVBQWFDLE9BQWIsRUFBc0JDLFlBQXRCLEtBQXVDO0FBQzFELFVBQUk7QUFDRixjQUFNO0FBQUVaLFVBQUFBLE1BQUY7QUFBVThCLFVBQUFBO0FBQVYsWUFBdUJwQixJQUE3QjtBQUNBLGNBQU07QUFBRUcsVUFBQUEsTUFBRjtBQUFVQyxVQUFBQSxJQUFWO0FBQWdCQyxVQUFBQTtBQUFoQixZQUF5QkosT0FBL0I7QUFFQSxjQUFNSyxXQUFXLEdBQUcsTUFBTSw4QkFBZSxRQUFmLEVBQXlCaEIsTUFBekIsRUFBaUM7QUFDekRpQixVQUFBQSxTQUFTLEVBQUUsT0FEOEM7QUFFekR2QixVQUFBQSxrQkFGeUQ7QUFHekR3QixVQUFBQSxHQUFHLEVBQUU7QUFBRUwsWUFBQUEsTUFBRjtBQUFVQyxZQUFBQSxJQUFWO0FBQWdCQyxZQUFBQTtBQUFoQjtBQUhvRCxTQUFqQyxDQUExQjtBQU1BLGNBQU07QUFBRUksVUFBQUEsWUFBRjtBQUFnQkMsVUFBQUE7QUFBaEIsWUFBNkIsTUFBTUMsZ0JBQWdCLENBQUNDLFlBQWpCLENBQ3ZDLE9BRHVDLGtDQUVsQ04sV0FGa0M7QUFFckJjLFVBQUFBO0FBRnFCLFlBR3ZDakIsTUFIdUMsRUFJdkNDLElBSnVDLEVBS3ZDQyxJQUx1QyxDQUF6QztBQVFBSixRQUFBQSxPQUFPLENBQUNJLElBQVIsQ0FBYUksWUFBYixHQUE0QkEsWUFBNUI7QUFFQSxlQUFPO0FBQ0xiLFVBQUFBLE1BQU0sRUFBRSxNQUFNLDJDQUF3QkssT0FBeEIsRUFBaUNDLFlBQWpDLEVBQStDLGNBQS9DLEVBQStEUSxRQUEvRDtBQURULFNBQVA7QUFHRCxPQXZCRCxDQXVCRSxPQUFPRyxDQUFQLEVBQVU7QUFDVjdCLFFBQUFBLGtCQUFrQixDQUFDOEIsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRjtBQWhFb0QsR0FBN0IsQ0FBMUI7QUFtRUE3QixFQUFBQSxrQkFBa0IsQ0FBQytCLGNBQW5CLENBQWtDSSxpQkFBaUIsQ0FBQ25CLElBQWxCLENBQXVCZ0IsS0FBdkIsQ0FBNkJ4QixJQUE3QixDQUFrQ3lCLE1BQXBFLEVBQTRFLElBQTVFLEVBQWtGLElBQWxGO0FBQ0FqQyxFQUFBQSxrQkFBa0IsQ0FBQytCLGNBQW5CLENBQWtDSSxpQkFBaUIsQ0FBQzNCLElBQXBELEVBQTBELElBQTFELEVBQWdFLElBQWhFO0FBQ0FSLEVBQUFBLGtCQUFrQixDQUFDa0Msa0JBQW5CLENBQXNDLFdBQXRDLEVBQW1EQyxpQkFBbkQsRUFBc0UsSUFBdEUsRUFBNEUsSUFBNUU7QUFFQSxRQUFNVSxhQUFhLEdBQUcsZ0RBQTZCO0FBQ2pEMUMsSUFBQUEsSUFBSSxFQUFFLE9BRDJDO0FBRWpEQyxJQUFBQSxXQUFXLEVBQUUsNERBRm9DO0FBR2pEQyxJQUFBQSxXQUFXLEVBQUU7QUFDWHlDLE1BQUFBLFFBQVEsRUFBRTtBQUNSMUMsUUFBQUEsV0FBVyxFQUFFLCtDQURMO0FBRVJJLFFBQUFBLElBQUksRUFBRSxJQUFJSyx1QkFBSixDQUFtQmtDLHNCQUFuQjtBQUZFLE9BREM7QUFLWEMsTUFBQUEsUUFBUSxFQUFFO0FBQ1I1QyxRQUFBQSxXQUFXLEVBQUUsK0NBREw7QUFFUkksUUFBQUEsSUFBSSxFQUFFLElBQUlLLHVCQUFKLENBQW1Ca0Msc0JBQW5CO0FBRkU7QUFMQyxLQUhvQztBQWFqRHBDLElBQUFBLFlBQVksRUFBRTtBQUNaQyxNQUFBQSxNQUFNLEVBQUU7QUFDTlIsUUFBQUEsV0FBVyxFQUFFLHdFQURQO0FBRU5JLFFBQUFBLElBQUksRUFBRSxJQUFJSyx1QkFBSixDQUFtQmIsa0JBQWtCLENBQUNjLFVBQXRDO0FBRkE7QUFESSxLQWJtQztBQW1CakRDLElBQUFBLG1CQUFtQixFQUFFLE9BQU9DLElBQVAsRUFBYUMsT0FBYixFQUFzQkMsWUFBdEIsS0FBdUM7QUFDMUQsVUFBSTtBQUNGLGNBQU07QUFBRTRCLFVBQUFBLFFBQUY7QUFBWUUsVUFBQUE7QUFBWixZQUF5QmhDLElBQS9CO0FBQ0EsY0FBTTtBQUFFRyxVQUFBQSxNQUFGO0FBQVVDLFVBQUFBLElBQVY7QUFBZ0JDLFVBQUFBO0FBQWhCLFlBQXlCSixPQUEvQjtBQUVBLGNBQU07QUFBRVEsVUFBQUEsWUFBRjtBQUFnQkMsVUFBQUE7QUFBaEIsWUFBNkIsQ0FDakMsTUFBTTdCLFdBQVcsQ0FBQ29ELFdBQVosQ0FBd0I7QUFDNUJDLFVBQUFBLElBQUksRUFBRTtBQUNKSixZQUFBQSxRQURJO0FBRUpFLFlBQUFBO0FBRkksV0FEc0I7QUFLNUJHLFVBQUFBLEtBQUssRUFBRSxFQUxxQjtBQU01QmhDLFVBQUFBLE1BTjRCO0FBTzVCQyxVQUFBQSxJQVA0QjtBQVE1QkMsVUFBQUE7QUFSNEIsU0FBeEIsQ0FEMkIsRUFXakMrQixRQVhGO0FBYUFuQyxRQUFBQSxPQUFPLENBQUNJLElBQVIsQ0FBYUksWUFBYixHQUE0QkEsWUFBNUI7QUFFQSxlQUFPO0FBQ0xiLFVBQUFBLE1BQU0sRUFBRSxNQUFNLDJDQUF3QkssT0FBeEIsRUFBaUNDLFlBQWpDLEVBQStDLGNBQS9DLEVBQStEUSxRQUEvRDtBQURULFNBQVA7QUFHRCxPQXRCRCxDQXNCRSxPQUFPRyxDQUFQLEVBQVU7QUFDVjdCLFFBQUFBLGtCQUFrQixDQUFDOEIsV0FBbkIsQ0FBK0JELENBQS9CO0FBQ0Q7QUFDRjtBQTdDZ0QsR0FBN0IsQ0FBdEI7QUFnREE3QixFQUFBQSxrQkFBa0IsQ0FBQytCLGNBQW5CLENBQWtDYyxhQUFhLENBQUM3QixJQUFkLENBQW1CZ0IsS0FBbkIsQ0FBeUJ4QixJQUF6QixDQUE4QnlCLE1BQWhFLEVBQXdFLElBQXhFLEVBQThFLElBQTlFO0FBQ0FqQyxFQUFBQSxrQkFBa0IsQ0FBQytCLGNBQW5CLENBQWtDYyxhQUFhLENBQUNyQyxJQUFoRCxFQUFzRCxJQUF0RCxFQUE0RCxJQUE1RDtBQUNBUixFQUFBQSxrQkFBa0IsQ0FBQ2tDLGtCQUFuQixDQUFzQyxPQUF0QyxFQUErQ1csYUFBL0MsRUFBOEQsSUFBOUQsRUFBb0UsSUFBcEU7QUFFQSxRQUFNUSxjQUFjLEdBQUcsZ0RBQTZCO0FBQ2xEbEQsSUFBQUEsSUFBSSxFQUFFLFFBRDRDO0FBRWxEQyxJQUFBQSxXQUFXLEVBQUUsOERBRnFDO0FBR2xETyxJQUFBQSxZQUFZLEVBQUU7QUFDWjJDLE1BQUFBLEVBQUUsRUFBRTtBQUNGbEQsUUFBQUEsV0FBVyxFQUFFLG1CQURYO0FBRUZJLFFBQUFBLElBQUksRUFBRSxJQUFJSyx1QkFBSixDQUFtQjBDLHVCQUFuQjtBQUZKO0FBRFEsS0FIb0M7QUFTbER4QyxJQUFBQSxtQkFBbUIsRUFBRSxPQUFPeUMsS0FBUCxFQUFjdkMsT0FBZCxLQUEwQjtBQUM3QyxVQUFJO0FBQ0YsY0FBTTtBQUFFRSxVQUFBQSxNQUFGO0FBQVVDLFVBQUFBLElBQVY7QUFBZ0JDLFVBQUFBO0FBQWhCLFlBQXlCSixPQUEvQjtBQUVBLGNBQU1wQixXQUFXLENBQUM0RCxZQUFaLENBQXlCO0FBQzdCdEMsVUFBQUEsTUFENkI7QUFFN0JDLFVBQUFBLElBRjZCO0FBRzdCQyxVQUFBQTtBQUg2QixTQUF6QixDQUFOO0FBTUEsZUFBTztBQUFFaUMsVUFBQUEsRUFBRSxFQUFFO0FBQU4sU0FBUDtBQUNELE9BVkQsQ0FVRSxPQUFPekIsQ0FBUCxFQUFVO0FBQ1Y3QixRQUFBQSxrQkFBa0IsQ0FBQzhCLFdBQW5CLENBQStCRCxDQUEvQjtBQUNEO0FBQ0Y7QUF2QmlELEdBQTdCLENBQXZCO0FBMEJBN0IsRUFBQUEsa0JBQWtCLENBQUMrQixjQUFuQixDQUFrQ3NCLGNBQWMsQ0FBQ3JDLElBQWYsQ0FBb0JnQixLQUFwQixDQUEwQnhCLElBQTFCLENBQStCeUIsTUFBakUsRUFBeUUsSUFBekUsRUFBK0UsSUFBL0U7QUFDQWpDLEVBQUFBLGtCQUFrQixDQUFDK0IsY0FBbkIsQ0FBa0NzQixjQUFjLENBQUM3QyxJQUFqRCxFQUF1RCxJQUF2RCxFQUE2RCxJQUE3RDtBQUNBUixFQUFBQSxrQkFBa0IsQ0FBQ2tDLGtCQUFuQixDQUFzQyxRQUF0QyxFQUFnRG1CLGNBQWhELEVBQWdFLElBQWhFLEVBQXNFLElBQXRFO0FBRUEsUUFBTUsscUJBQXFCLEdBQUcsZ0RBQTZCO0FBQ3pEdkQsSUFBQUEsSUFBSSxFQUFFLGVBRG1EO0FBRXpEQyxJQUFBQSxXQUFXLEVBQ1QsbUZBSHVEO0FBSXpEQyxJQUFBQSxXQUFXLEVBQUU7QUFDWHNELE1BQUFBLEtBQUssRUFBRTtBQUNMcEQsUUFBQUEsWUFBWSxFQUFFLHVEQURUO0FBRUxDLFFBQUFBLElBQUksRUFBRSxJQUFJSyx1QkFBSixDQUFtQmtDLHNCQUFuQjtBQUZEO0FBREksS0FKNEM7QUFVekRwQyxJQUFBQSxZQUFZLEVBQUU7QUFDWjJDLE1BQUFBLEVBQUUsRUFBRTtBQUNGbEQsUUFBQUEsV0FBVyxFQUFFLG1CQURYO0FBRUZJLFFBQUFBLElBQUksRUFBRSxJQUFJSyx1QkFBSixDQUFtQjBDLHVCQUFuQjtBQUZKO0FBRFEsS0FWMkM7QUFnQnpEeEMsSUFBQUEsbUJBQW1CLEVBQUUsT0FBTztBQUFFNEMsTUFBQUE7QUFBRixLQUFQLEVBQWtCMUMsT0FBbEIsS0FBOEI7QUFDakQsWUFBTTtBQUFFRSxRQUFBQSxNQUFGO0FBQVVDLFFBQUFBLElBQVY7QUFBZ0JDLFFBQUFBO0FBQWhCLFVBQXlCSixPQUEvQjtBQUVBLFlBQU1wQixXQUFXLENBQUMrRCxrQkFBWixDQUErQjtBQUNuQ1YsUUFBQUEsSUFBSSxFQUFFO0FBQ0pTLFVBQUFBO0FBREksU0FENkI7QUFJbkN4QyxRQUFBQSxNQUptQztBQUtuQ0MsUUFBQUEsSUFMbUM7QUFNbkNDLFFBQUFBO0FBTm1DLE9BQS9CLENBQU47QUFTQSxhQUFPO0FBQUVpQyxRQUFBQSxFQUFFLEVBQUU7QUFBTixPQUFQO0FBQ0Q7QUE3QndELEdBQTdCLENBQTlCO0FBZ0NBdEQsRUFBQUEsa0JBQWtCLENBQUMrQixjQUFuQixDQUFrQzJCLHFCQUFxQixDQUFDMUMsSUFBdEIsQ0FBMkJnQixLQUEzQixDQUFpQ3hCLElBQWpDLENBQXNDeUIsTUFBeEUsRUFBZ0YsSUFBaEYsRUFBc0YsSUFBdEY7QUFDQWpDLEVBQUFBLGtCQUFrQixDQUFDK0IsY0FBbkIsQ0FBa0MyQixxQkFBcUIsQ0FBQ2xELElBQXhELEVBQThELElBQTlELEVBQW9FLElBQXBFO0FBQ0FSLEVBQUFBLGtCQUFrQixDQUFDa0Msa0JBQW5CLENBQXNDLGVBQXRDLEVBQXVEd0IscUJBQXZELEVBQThFLElBQTlFLEVBQW9GLElBQXBGO0FBRUEsUUFBTUcsNkJBQTZCLEdBQUcsZ0RBQTZCO0FBQ2pFMUQsSUFBQUEsSUFBSSxFQUFFLHVCQUQyRDtBQUVqRUMsSUFBQUEsV0FBVyxFQUNULHNGQUgrRDtBQUlqRUMsSUFBQUEsV0FBVyxFQUFFO0FBQ1hzRCxNQUFBQSxLQUFLLEVBQUU7QUFDTHBELFFBQUFBLFlBQVksRUFBRSw4REFEVDtBQUVMQyxRQUFBQSxJQUFJLEVBQUUsSUFBSUssdUJBQUosQ0FBbUJrQyxzQkFBbkI7QUFGRDtBQURJLEtBSm9EO0FBVWpFcEMsSUFBQUEsWUFBWSxFQUFFO0FBQ1oyQyxNQUFBQSxFQUFFLEVBQUU7QUFDRmxELFFBQUFBLFdBQVcsRUFBRSxtQkFEWDtBQUVGSSxRQUFBQSxJQUFJLEVBQUUsSUFBSUssdUJBQUosQ0FBbUIwQyx1QkFBbkI7QUFGSjtBQURRLEtBVm1EO0FBZ0JqRXhDLElBQUFBLG1CQUFtQixFQUFFLE9BQU87QUFBRTRDLE1BQUFBO0FBQUYsS0FBUCxFQUFrQjFDLE9BQWxCLEtBQThCO0FBQ2pELFVBQUk7QUFDRixjQUFNO0FBQUVFLFVBQUFBLE1BQUY7QUFBVUMsVUFBQUEsSUFBVjtBQUFnQkMsVUFBQUE7QUFBaEIsWUFBeUJKLE9BQS9CO0FBRUEsY0FBTXBCLFdBQVcsQ0FBQ2lFLDhCQUFaLENBQTJDO0FBQy9DWixVQUFBQSxJQUFJLEVBQUU7QUFDSlMsWUFBQUE7QUFESSxXQUR5QztBQUkvQ3hDLFVBQUFBLE1BSitDO0FBSy9DQyxVQUFBQSxJQUwrQztBQU0vQ0MsVUFBQUE7QUFOK0MsU0FBM0MsQ0FBTjtBQVNBLGVBQU87QUFBRWlDLFVBQUFBLEVBQUUsRUFBRTtBQUFOLFNBQVA7QUFDRCxPQWJELENBYUUsT0FBT3pCLENBQVAsRUFBVTtBQUNWN0IsUUFBQUEsa0JBQWtCLENBQUM4QixXQUFuQixDQUErQkQsQ0FBL0I7QUFDRDtBQUNGO0FBakNnRSxHQUE3QixDQUF0QztBQW9DQTdCLEVBQUFBLGtCQUFrQixDQUFDK0IsY0FBbkIsQ0FDRThCLDZCQUE2QixDQUFDN0MsSUFBOUIsQ0FBbUNnQixLQUFuQyxDQUF5Q3hCLElBQXpDLENBQThDeUIsTUFEaEQsRUFFRSxJQUZGLEVBR0UsSUFIRjtBQUtBakMsRUFBQUEsa0JBQWtCLENBQUMrQixjQUFuQixDQUFrQzhCLDZCQUE2QixDQUFDckQsSUFBaEUsRUFBc0UsSUFBdEUsRUFBNEUsSUFBNUU7QUFDQVIsRUFBQUEsa0JBQWtCLENBQUNrQyxrQkFBbkIsQ0FDRSx1QkFERixFQUVFMkIsNkJBRkYsRUFHRSxJQUhGLEVBSUUsSUFKRjtBQU1ELENBbFNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgR3JhcGhRTE5vbk51bGwsIEdyYXBoUUxTdHJpbmcsIEdyYXBoUUxCb29sZWFuLCBHcmFwaFFMSW5wdXRPYmplY3RUeXBlIH0gZnJvbSAnZ3JhcGhxbCc7XG5pbXBvcnQgeyBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkIH0gZnJvbSAnZ3JhcGhxbC1yZWxheSc7XG5pbXBvcnQgVXNlcnNSb3V0ZXIgZnJvbSAnLi4vLi4vUm91dGVycy9Vc2Vyc1JvdXRlcic7XG5pbXBvcnQgKiBhcyBvYmplY3RzTXV0YXRpb25zIGZyb20gJy4uL2hlbHBlcnMvb2JqZWN0c011dGF0aW9ucyc7XG5pbXBvcnQgeyBPQkpFQ1QgfSBmcm9tICcuL2RlZmF1bHRHcmFwaFFMVHlwZXMnO1xuaW1wb3J0IHsgZ2V0VXNlckZyb21TZXNzaW9uVG9rZW4gfSBmcm9tICcuL3VzZXJzUXVlcmllcyc7XG5pbXBvcnQgeyB0cmFuc2Zvcm1UeXBlcyB9IGZyb20gJy4uL3RyYW5zZm9ybWVycy9tdXRhdGlvbic7XG5cbmNvbnN0IHVzZXJzUm91dGVyID0gbmV3IFVzZXJzUm91dGVyKCk7XG5cbmNvbnN0IGxvYWQgPSBwYXJzZUdyYXBoUUxTY2hlbWEgPT4ge1xuICBpZiAocGFyc2VHcmFwaFFMU2NoZW1hLmlzVXNlcnNDbGFzc0Rpc2FibGVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3Qgc2lnblVwTXV0YXRpb24gPSBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkKHtcbiAgICBuYW1lOiAnU2lnblVwJyxcbiAgICBkZXNjcmlwdGlvbjogJ1RoZSBzaWduVXAgbXV0YXRpb24gY2FuIGJlIHVzZWQgdG8gY3JlYXRlIGFuZCBzaWduIHVwIGEgbmV3IHVzZXIuJyxcbiAgICBpbnB1dEZpZWxkczoge1xuICAgICAgZmllbGRzOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uczogJ1RoZXNlIGFyZSB0aGUgZmllbGRzIG9mIHRoZSBuZXcgdXNlciB0byBiZSBjcmVhdGVkIGFuZCBzaWduZWQgdXAuJyxcbiAgICAgICAgdHlwZTogcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1snX1VzZXInXS5jbGFzc0dyYXBoUUxDcmVhdGVUeXBlLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG91dHB1dEZpZWxkczoge1xuICAgICAgdmlld2VyOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgbmV3IHVzZXIgdGhhdCB3YXMgY3JlYXRlZCwgc2lnbmVkIHVwIGFuZCByZXR1cm5lZCBhcyBhIHZpZXdlci4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwocGFyc2VHcmFwaFFMU2NoZW1hLnZpZXdlclR5cGUpLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jIChhcmdzLCBjb250ZXh0LCBtdXRhdGlvbkluZm8pID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgZmllbGRzIH0gPSBhcmdzO1xuICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcblxuICAgICAgICBjb25zdCBwYXJzZUZpZWxkcyA9IGF3YWl0IHRyYW5zZm9ybVR5cGVzKCdjcmVhdGUnLCBmaWVsZHMsIHtcbiAgICAgICAgICBjbGFzc05hbWU6ICdfVXNlcicsXG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLFxuICAgICAgICAgIHJlcTogeyBjb25maWcsIGF1dGgsIGluZm8gfSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgeyBzZXNzaW9uVG9rZW4sIG9iamVjdElkIH0gPSBhd2FpdCBvYmplY3RzTXV0YXRpb25zLmNyZWF0ZU9iamVjdChcbiAgICAgICAgICAnX1VzZXInLFxuICAgICAgICAgIHBhcnNlRmllbGRzLFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICBhdXRoLFxuICAgICAgICAgIGluZm9cbiAgICAgICAgKTtcblxuICAgICAgICBjb250ZXh0LmluZm8uc2Vzc2lvblRva2VuID0gc2Vzc2lvblRva2VuO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdmlld2VyOiBhd2FpdCBnZXRVc2VyRnJvbVNlc3Npb25Ub2tlbihjb250ZXh0LCBtdXRhdGlvbkluZm8sICd2aWV3ZXIudXNlci4nLCBvYmplY3RJZCksXG4gICAgICAgIH07XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcblxuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoc2lnblVwTXV0YXRpb24uYXJncy5pbnB1dC50eXBlLm9mVHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShzaWduVXBNdXRhdGlvbi50eXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbignc2lnblVwJywgc2lnblVwTXV0YXRpb24sIHRydWUsIHRydWUpO1xuICBjb25zdCBsb2dJbldpdGhNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgIG5hbWU6ICdMb2dJbldpdGgnLFxuICAgIGRlc2NyaXB0aW9uOlxuICAgICAgJ1RoZSBsb2dJbldpdGggbXV0YXRpb24gY2FuIGJlIHVzZWQgdG8gc2lnbnVwLCBsb2dpbiB1c2VyIHdpdGggM3JkIHBhcnR5IGF1dGhlbnRpY2F0aW9uIHN5c3RlbS4gVGhpcyBtdXRhdGlvbiBjcmVhdGUgYSB1c2VyIGlmIHRoZSBhdXRoRGF0YSBkbyBub3QgY29ycmVzcG9uZCB0byBhbiBleGlzdGluZyBvbmUuJyxcbiAgICBpbnB1dEZpZWxkczoge1xuICAgICAgYXV0aERhdGE6IHtcbiAgICAgICAgZGVzY3JpcHRpb25zOiAnVGhpcyBpcyB0aGUgYXV0aCBkYXRhIG9mIHlvdXIgY3VzdG9tIGF1dGggcHJvdmlkZXInLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoT0JKRUNUKSxcbiAgICAgIH0sXG4gICAgICBmaWVsZHM6IHtcbiAgICAgICAgZGVzY3JpcHRpb25zOiAnVGhlc2UgYXJlIHRoZSBmaWVsZHMgb2YgdGhlIHVzZXIgdG8gYmUgY3JlYXRlZC91cGRhdGVkIGFuZCBsb2dnZWQgaW4uJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICAgICAgICAgIG5hbWU6ICdVc2VyTG9naW5XaXRoSW5wdXQnLFxuICAgICAgICAgIGZpZWxkczogKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY2xhc3NHcmFwaFFMQ3JlYXRlRmllbGRzID0gcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1tcbiAgICAgICAgICAgICAgJ19Vc2VyJ1xuICAgICAgICAgICAgXS5jbGFzc0dyYXBoUUxDcmVhdGVUeXBlLmdldEZpZWxkcygpO1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKGNsYXNzR3JhcGhRTENyZWF0ZUZpZWxkcykucmVkdWNlKChmaWVsZHMsIGZpZWxkTmFtZSkgPT4ge1xuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgZmllbGROYW1lICE9PSAncGFzc3dvcmQnICYmXG4gICAgICAgICAgICAgICAgZmllbGROYW1lICE9PSAndXNlcm5hbWUnICYmXG4gICAgICAgICAgICAgICAgZmllbGROYW1lICE9PSAnYXV0aERhdGEnXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGZpZWxkc1tmaWVsZE5hbWVdID0gY2xhc3NHcmFwaFFMQ3JlYXRlRmllbGRzW2ZpZWxkTmFtZV07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIGZpZWxkcztcbiAgICAgICAgICAgIH0sIHt9KTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgIHZpZXdlcjoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIG5ldyB1c2VyIHRoYXQgd2FzIGNyZWF0ZWQsIHNpZ25lZCB1cCBhbmQgcmV0dXJuZWQgYXMgYSB2aWV3ZXIuJyxcbiAgICAgICAgdHlwZTogbmV3IEdyYXBoUUxOb25OdWxsKHBhcnNlR3JhcGhRTFNjaGVtYS52aWV3ZXJUeXBlKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBtdXRhdGVBbmRHZXRQYXlsb2FkOiBhc3luYyAoYXJncywgY29udGV4dCwgbXV0YXRpb25JbmZvKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB7IGZpZWxkcywgYXV0aERhdGEgfSA9IGFyZ3M7XG4gICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuXG4gICAgICAgIGNvbnN0IHBhcnNlRmllbGRzID0gYXdhaXQgdHJhbnNmb3JtVHlwZXMoJ2NyZWF0ZScsIGZpZWxkcywge1xuICAgICAgICAgIGNsYXNzTmFtZTogJ19Vc2VyJyxcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEsXG4gICAgICAgICAgcmVxOiB7IGNvbmZpZywgYXV0aCwgaW5mbyB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCB7IHNlc3Npb25Ub2tlbiwgb2JqZWN0SWQgfSA9IGF3YWl0IG9iamVjdHNNdXRhdGlvbnMuY3JlYXRlT2JqZWN0KFxuICAgICAgICAgICdfVXNlcicsXG4gICAgICAgICAgeyAuLi5wYXJzZUZpZWxkcywgYXV0aERhdGEgfSxcbiAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgYXV0aCxcbiAgICAgICAgICBpbmZvXG4gICAgICAgICk7XG5cbiAgICAgICAgY29udGV4dC5pbmZvLnNlc3Npb25Ub2tlbiA9IHNlc3Npb25Ub2tlbjtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHZpZXdlcjogYXdhaXQgZ2V0VXNlckZyb21TZXNzaW9uVG9rZW4oY29udGV4dCwgbXV0YXRpb25JbmZvLCAndmlld2VyLnVzZXIuJywgb2JqZWN0SWQpLFxuICAgICAgICB9O1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGxvZ0luV2l0aE11dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGUsIHRydWUsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUobG9nSW5XaXRoTXV0YXRpb24udHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMTXV0YXRpb24oJ2xvZ0luV2l0aCcsIGxvZ0luV2l0aE11dGF0aW9uLCB0cnVlLCB0cnVlKTtcblxuICBjb25zdCBsb2dJbk11dGF0aW9uID0gbXV0YXRpb25XaXRoQ2xpZW50TXV0YXRpb25JZCh7XG4gICAgbmFtZTogJ0xvZ0luJyxcbiAgICBkZXNjcmlwdGlvbjogJ1RoZSBsb2dJbiBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBsb2cgaW4gYW4gZXhpc3RpbmcgdXNlci4nLFxuICAgIGlucHV0RmllbGRzOiB7XG4gICAgICB1c2VybmFtZToge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIHVzZXJuYW1lIHVzZWQgdG8gbG9nIGluIHRoZSB1c2VyLicsXG4gICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbiAgICAgIH0sXG4gICAgICBwYXNzd29yZDoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIHBhc3N3b3JkIHVzZWQgdG8gbG9nIGluIHRoZSB1c2VyLicsXG4gICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgIHZpZXdlcjoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGV4aXN0aW5nIHVzZXIgdGhhdCB3YXMgbG9nZ2VkIGluIGFuZCByZXR1cm5lZCBhcyBhIHZpZXdlci4nLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwocGFyc2VHcmFwaFFMU2NoZW1hLnZpZXdlclR5cGUpLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jIChhcmdzLCBjb250ZXh0LCBtdXRhdGlvbkluZm8pID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgdXNlcm5hbWUsIHBhc3N3b3JkIH0gPSBhcmdzO1xuICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcblxuICAgICAgICBjb25zdCB7IHNlc3Npb25Ub2tlbiwgb2JqZWN0SWQgfSA9IChcbiAgICAgICAgICBhd2FpdCB1c2Vyc1JvdXRlci5oYW5kbGVMb2dJbih7XG4gICAgICAgICAgICBib2R5OiB7XG4gICAgICAgICAgICAgIHVzZXJuYW1lLFxuICAgICAgICAgICAgICBwYXNzd29yZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBxdWVyeToge30sXG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgaW5mbyxcbiAgICAgICAgICB9KVxuICAgICAgICApLnJlc3BvbnNlO1xuXG4gICAgICAgIGNvbnRleHQuaW5mby5zZXNzaW9uVG9rZW4gPSBzZXNzaW9uVG9rZW47XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB2aWV3ZXI6IGF3YWl0IGdldFVzZXJGcm9tU2Vzc2lvblRva2VuKGNvbnRleHQsIG11dGF0aW9uSW5mbywgJ3ZpZXdlci51c2VyLicsIG9iamVjdElkKSxcbiAgICAgICAgfTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmhhbmRsZUVycm9yKGUpO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShsb2dJbk11dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGUsIHRydWUsIHRydWUpO1xuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUobG9nSW5NdXRhdGlvbi50eXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbignbG9nSW4nLCBsb2dJbk11dGF0aW9uLCB0cnVlLCB0cnVlKTtcblxuICBjb25zdCBsb2dPdXRNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgIG5hbWU6ICdMb2dPdXQnLFxuICAgIGRlc2NyaXB0aW9uOiAnVGhlIGxvZ091dCBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byBsb2cgb3V0IGFuIGV4aXN0aW5nIHVzZXIuJyxcbiAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgIG9rOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIkl0J3MgYWx3YXlzIHRydWUuXCIsXG4gICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMQm9vbGVhbiksXG4gICAgICB9LFxuICAgIH0sXG4gICAgbXV0YXRlQW5kR2V0UGF5bG9hZDogYXN5bmMgKF9hcmdzLCBjb250ZXh0KSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcblxuICAgICAgICBhd2FpdCB1c2Vyc1JvdXRlci5oYW5kbGVMb2dPdXQoe1xuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICBhdXRoLFxuICAgICAgICAgIGluZm8sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB7IG9rOiB0cnVlIH07XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgIH1cbiAgICB9LFxuICB9KTtcblxuICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUobG9nT3V0TXV0YXRpb24uYXJncy5pbnB1dC50eXBlLm9mVHlwZSwgdHJ1ZSwgdHJ1ZSk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShsb2dPdXRNdXRhdGlvbi50eXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbignbG9nT3V0JywgbG9nT3V0TXV0YXRpb24sIHRydWUsIHRydWUpO1xuXG4gIGNvbnN0IHJlc2V0UGFzc3dvcmRNdXRhdGlvbiA9IG11dGF0aW9uV2l0aENsaWVudE11dGF0aW9uSWQoe1xuICAgIG5hbWU6ICdSZXNldFBhc3N3b3JkJyxcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgICdUaGUgcmVzZXRQYXNzd29yZCBtdXRhdGlvbiBjYW4gYmUgdXNlZCB0byByZXNldCB0aGUgcGFzc3dvcmQgb2YgYW4gZXhpc3RpbmcgdXNlci4nLFxuICAgIGlucHV0RmllbGRzOiB7XG4gICAgICBlbWFpbDoge1xuICAgICAgICBkZXNjcmlwdGlvbnM6ICdFbWFpbCBvZiB0aGUgdXNlciB0aGF0IHNob3VsZCByZWNlaXZlIHRoZSByZXNldCBlbWFpbCcsXG4gICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMU3RyaW5nKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBvdXRwdXRGaWVsZHM6IHtcbiAgICAgIG9rOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIkl0J3MgYWx3YXlzIHRydWUuXCIsXG4gICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChHcmFwaFFMQm9vbGVhbiksXG4gICAgICB9LFxuICAgIH0sXG4gICAgbXV0YXRlQW5kR2V0UGF5bG9hZDogYXN5bmMgKHsgZW1haWwgfSwgY29udGV4dCkgPT4ge1xuICAgICAgY29uc3QgeyBjb25maWcsIGF1dGgsIGluZm8gfSA9IGNvbnRleHQ7XG5cbiAgICAgIGF3YWl0IHVzZXJzUm91dGVyLmhhbmRsZVJlc2V0UmVxdWVzdCh7XG4gICAgICAgIGJvZHk6IHtcbiAgICAgICAgICBlbWFpbCxcbiAgICAgICAgfSxcbiAgICAgICAgY29uZmlnLFxuICAgICAgICBhdXRoLFxuICAgICAgICBpbmZvLFxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB7IG9rOiB0cnVlIH07XG4gICAgfSxcbiAgfSk7XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKHJlc2V0UGFzc3dvcmRNdXRhdGlvbi5hcmdzLmlucHV0LnR5cGUub2ZUeXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKHJlc2V0UGFzc3dvcmRNdXRhdGlvbi50eXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbigncmVzZXRQYXNzd29yZCcsIHJlc2V0UGFzc3dvcmRNdXRhdGlvbiwgdHJ1ZSwgdHJ1ZSk7XG5cbiAgY29uc3Qgc2VuZFZlcmlmaWNhdGlvbkVtYWlsTXV0YXRpb24gPSBtdXRhdGlvbldpdGhDbGllbnRNdXRhdGlvbklkKHtcbiAgICBuYW1lOiAnU2VuZFZlcmlmaWNhdGlvbkVtYWlsJyxcbiAgICBkZXNjcmlwdGlvbjpcbiAgICAgICdUaGUgc2VuZFZlcmlmaWNhdGlvbkVtYWlsIG11dGF0aW9uIGNhbiBiZSB1c2VkIHRvIHNlbmQgdGhlIHZlcmlmaWNhdGlvbiBlbWFpbCBhZ2Fpbi4nLFxuICAgIGlucHV0RmllbGRzOiB7XG4gICAgICBlbWFpbDoge1xuICAgICAgICBkZXNjcmlwdGlvbnM6ICdFbWFpbCBvZiB0aGUgdXNlciB0aGF0IHNob3VsZCByZWNlaXZlIHRoZSB2ZXJpZmljYXRpb24gZW1haWwnLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTFN0cmluZyksXG4gICAgICB9LFxuICAgIH0sXG4gICAgb3V0cHV0RmllbGRzOiB7XG4gICAgICBvazoge1xuICAgICAgICBkZXNjcmlwdGlvbjogXCJJdCdzIGFsd2F5cyB0cnVlLlwiLFxuICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTE5vbk51bGwoR3JhcGhRTEJvb2xlYW4pLFxuICAgICAgfSxcbiAgICB9LFxuICAgIG11dGF0ZUFuZEdldFBheWxvYWQ6IGFzeW5jICh7IGVtYWlsIH0sIGNvbnRleHQpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0gPSBjb250ZXh0O1xuXG4gICAgICAgIGF3YWl0IHVzZXJzUm91dGVyLmhhbmRsZVZlcmlmaWNhdGlvbkVtYWlsUmVxdWVzdCh7XG4gICAgICAgICAgYm9keToge1xuICAgICAgICAgICAgZW1haWwsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgYXV0aCxcbiAgICAgICAgICBpbmZvLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4geyBvazogdHJ1ZSB9O1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKFxuICAgIHNlbmRWZXJpZmljYXRpb25FbWFpbE11dGF0aW9uLmFyZ3MuaW5wdXQudHlwZS5vZlR5cGUsXG4gICAgdHJ1ZSxcbiAgICB0cnVlXG4gICk7XG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShzZW5kVmVyaWZpY2F0aW9uRW1haWxNdXRhdGlvbi50eXBlLCB0cnVlLCB0cnVlKTtcbiAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxNdXRhdGlvbihcbiAgICAnc2VuZFZlcmlmaWNhdGlvbkVtYWlsJyxcbiAgICBzZW5kVmVyaWZpY2F0aW9uRW1haWxNdXRhdGlvbixcbiAgICB0cnVlLFxuICAgIHRydWVcbiAgKTtcbn07XG5cbmV4cG9ydCB7IGxvYWQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/loaders/usersQueries.js b/lib/GraphQL/loaders/usersQueries.js deleted file mode 100644 index a085211ef6..0000000000 --- a/lib/GraphQL/loaders/usersQueries.js +++ /dev/null @@ -1,111 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.getUserFromSessionToken = exports.load = void 0; - -var _graphql = require("graphql"); - -var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields")); - -var _node = _interopRequireDefault(require("parse/node")); - -var _rest = _interopRequireDefault(require("../../rest")); - -var _parseClassTypes = require("./parseClassTypes"); - -var _Auth = require("../../Auth"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const getUserFromSessionToken = async (context, queryInfo, keysPrefix, userId) => { - const { - info, - config - } = context; - - if (!info || !info.sessionToken) { - throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); - } - - const sessionToken = info.sessionToken; - const selectedFields = (0, _graphqlListFields.default)(queryInfo).filter(field => field.startsWith(keysPrefix)).map(field => field.replace(keysPrefix, '')); - const keysAndInclude = (0, _parseClassTypes.extractKeysAndInclude)(selectedFields); - const { - keys - } = keysAndInclude; - let { - include - } = keysAndInclude; - - if (userId && !keys && !include) { - return { - sessionToken - }; - } else if (keys && !include) { - include = 'user'; - } - - if (userId) { - // We need to re create the auth context - // to avoid security breach if userId is provided - context.auth = new _Auth.Auth({ - config, - isMaster: context.auth.isMaster, - user: { - id: userId - } - }); - } - - const options = {}; - - if (keys) { - options.keys = keys.split(',').map(key => `${key}`).join(','); - } - - if (include) { - options.include = include.split(',').map(included => `${included}`).join(','); - } - - const response = await _rest.default.find(config, context.auth, '_User', // Get the user it self from auth object - { - objectId: context.auth.user.id - }, options, info.clientVersion, info.context); - - if (!response.results || response.results.length == 0) { - throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); - } else { - const user = response.results[0]; - return { - sessionToken, - user - }; - } -}; - -exports.getUserFromSessionToken = getUserFromSessionToken; - -const load = parseGraphQLSchema => { - if (parseGraphQLSchema.isUsersClassDisabled) { - return; - } - - parseGraphQLSchema.addGraphQLQuery('viewer', { - description: 'The viewer query can be used to return the current user data.', - type: new _graphql.GraphQLNonNull(parseGraphQLSchema.viewerType), - - async resolve(_source, _args, context, queryInfo) { - try { - return await getUserFromSessionToken(context, queryInfo, 'user.', false); - } catch (e) { - parseGraphQLSchema.handleError(e); - } - } - - }, true, true); -}; - -exports.load = load; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML2xvYWRlcnMvdXNlcnNRdWVyaWVzLmpzIl0sIm5hbWVzIjpbImdldFVzZXJGcm9tU2Vzc2lvblRva2VuIiwiY29udGV4dCIsInF1ZXJ5SW5mbyIsImtleXNQcmVmaXgiLCJ1c2VySWQiLCJpbmZvIiwiY29uZmlnIiwic2Vzc2lvblRva2VuIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfU0VTU0lPTl9UT0tFTiIsInNlbGVjdGVkRmllbGRzIiwiZmlsdGVyIiwiZmllbGQiLCJzdGFydHNXaXRoIiwibWFwIiwicmVwbGFjZSIsImtleXNBbmRJbmNsdWRlIiwia2V5cyIsImluY2x1ZGUiLCJhdXRoIiwiQXV0aCIsImlzTWFzdGVyIiwidXNlciIsImlkIiwib3B0aW9ucyIsInNwbGl0Iiwia2V5Iiwiam9pbiIsImluY2x1ZGVkIiwicmVzcG9uc2UiLCJyZXN0IiwiZmluZCIsIm9iamVjdElkIiwiY2xpZW50VmVyc2lvbiIsInJlc3VsdHMiLCJsZW5ndGgiLCJsb2FkIiwicGFyc2VHcmFwaFFMU2NoZW1hIiwiaXNVc2Vyc0NsYXNzRGlzYWJsZWQiLCJhZGRHcmFwaFFMUXVlcnkiLCJkZXNjcmlwdGlvbiIsInR5cGUiLCJHcmFwaFFMTm9uTnVsbCIsInZpZXdlclR5cGUiLCJyZXNvbHZlIiwiX3NvdXJjZSIsIl9hcmdzIiwiZSIsImhhbmRsZUVycm9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxNQUFNQSx1QkFBdUIsR0FBRyxPQUFPQyxPQUFQLEVBQWdCQyxTQUFoQixFQUEyQkMsVUFBM0IsRUFBdUNDLE1BQXZDLEtBQWtEO0FBQ2hGLFFBQU07QUFBRUMsSUFBQUEsSUFBRjtBQUFRQyxJQUFBQTtBQUFSLE1BQW1CTCxPQUF6Qjs7QUFDQSxNQUFJLENBQUNJLElBQUQsSUFBUyxDQUFDQSxJQUFJLENBQUNFLFlBQW5CLEVBQWlDO0FBQy9CLFVBQU0sSUFB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Q0FBQ0UsZUFBbkIsQ0FDRSxRQURGLEVBRUU7QUFDRUMsSUFBQUEsV0FBVyxFQUFFLCtEQURmO0FBRUVDLElBQUFBLElBQUksRUFBRSxJQUFJQyx1QkFBSixDQUFtQkwsa0JBQWtCLENBQUNNLFVBQXRDLENBRlI7O0FBR0UsVUFBTUMsT0FBTixDQUFjQyxPQUFkLEVBQXVCQyxLQUF2QixFQUE4QjlDLE9BQTlCLEVBQXVDQyxTQUF2QyxFQUFrRDtBQUNoRCxVQUFJO0FBQ0YsZUFBTyxNQUFNRix1QkFBdUIsQ0FBQ0MsT0FBRCxFQUFVQyxTQUFWLEVBQXFCLE9BQXJCLEVBQThCLEtBQTlCLENBQXBDO0FBQ0QsT0FGRCxDQUVFLE9BQU84QyxDQUFQLEVBQVU7QUFDVlYsUUFBQUEsa0JBQWtCLENBQUNXLFdBQW5CLENBQStCRCxDQUEvQjtBQUNEO0FBQ0Y7O0FBVEgsR0FGRixFQWFFLElBYkYsRUFjRSxJQWRGO0FBZ0JELENBckJEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgR3JhcGhRTE5vbk51bGwgfSBmcm9tICdncmFwaHFsJztcbmltcG9ydCBnZXRGaWVsZE5hbWVzIGZyb20gJ2dyYXBocWwtbGlzdC1maWVsZHMnO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IHJlc3QgZnJvbSAnLi4vLi4vcmVzdCc7XG5pbXBvcnQgeyBleHRyYWN0S2V5c0FuZEluY2x1ZGUgfSBmcm9tICcuL3BhcnNlQ2xhc3NUeXBlcyc7XG5pbXBvcnQgeyBBdXRoIH0gZnJvbSAnLi4vLi4vQXV0aCc7XG5cbmNvbnN0IGdldFVzZXJGcm9tU2Vzc2lvblRva2VuID0gYXN5bmMgKGNvbnRleHQsIHF1ZXJ5SW5mbywga2V5c1ByZWZpeCwgdXNlcklkKSA9PiB7XG4gIGNvbnN0IHsgaW5mbywgY29uZmlnIH0gPSBjb250ZXh0O1xuICBpZiAoIWluZm8gfHwgIWluZm8uc2Vzc2lvblRva2VuKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTiwgJ0ludmFsaWQgc2Vzc2lvbiB0b2tlbicpO1xuICB9XG4gIGNvbnN0IHNlc3Npb25Ub2tlbiA9IGluZm8uc2Vzc2lvblRva2VuO1xuICBjb25zdCBzZWxlY3RlZEZpZWxkcyA9IGdldEZpZWxkTmFtZXMocXVlcnlJbmZvKVxuICAgIC5maWx0ZXIoZmllbGQgPT4gZmllbGQuc3RhcnRzV2l0aChrZXlzUHJlZml4KSlcbiAgICAubWFwKGZpZWxkID0+IGZpZWxkLnJlcGxhY2Uoa2V5c1ByZWZpeCwgJycpKTtcblxuICBjb25zdCBrZXlzQW5kSW5jbHVkZSA9IGV4dHJhY3RLZXlzQW5kSW5jbHVkZShzZWxlY3RlZEZpZWxkcyk7XG4gIGNvbnN0IHsga2V5cyB9ID0ga2V5c0FuZEluY2x1ZGU7XG4gIGxldCB7IGluY2x1ZGUgfSA9IGtleXNBbmRJbmNsdWRlO1xuXG4gIGlmICh1c2VySWQgJiYgIWtleXMgJiYgIWluY2x1ZGUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc2Vzc2lvblRva2VuLFxuICAgIH07XG4gIH0gZWxzZSBpZiAoa2V5cyAmJiAhaW5jbHVkZSkge1xuICAgIGluY2x1ZGUgPSAndXNlcic7XG4gIH1cblxuICBpZiAodXNlcklkKSB7XG4gICAgLy8gV2UgbmVlZCB0byByZSBjcmVhdGUgdGhlIGF1dGggY29udGV4dFxuICAgIC8vIHRvIGF2b2lkIHNlY3VyaXR5IGJyZWFjaCBpZiB1c2VySWQgaXMgcHJvdmlkZWRcbiAgICBjb250ZXh0LmF1dGggPSBuZXcgQXV0aCh7XG4gICAgICBjb25maWcsXG4gICAgICBpc01hc3RlcjogY29udGV4dC5hdXRoLmlzTWFzdGVyLFxuICAgICAgdXNlcjogeyBpZDogdXNlcklkIH0sXG4gICAgfSk7XG4gIH1cblxuICBjb25zdCBvcHRpb25zID0ge307XG4gIGlmIChrZXlzKSB7XG4gICAgb3B0aW9ucy5rZXlzID0ga2V5c1xuICAgICAgLnNwbGl0KCcsJylcbiAgICAgIC5tYXAoa2V5ID0+IGAke2tleX1gKVxuICAgICAgLmpvaW4oJywnKTtcbiAgfVxuICBpZiAoaW5jbHVkZSkge1xuICAgIG9wdGlvbnMuaW5jbHVkZSA9IGluY2x1ZGVcbiAgICAgIC5zcGxpdCgnLCcpXG4gICAgICAubWFwKGluY2x1ZGVkID0+IGAke2luY2x1ZGVkfWApXG4gICAgICAuam9pbignLCcpO1xuICB9XG5cbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCByZXN0LmZpbmQoXG4gICAgY29uZmlnLFxuICAgIGNvbnRleHQuYXV0aCxcbiAgICAnX1VzZXInLFxuICAgIC8vIEdldCB0aGUgdXNlciBpdCBzZWxmIGZyb20gYXV0aCBvYmplY3RcbiAgICB7IG9iamVjdElkOiBjb250ZXh0LmF1dGgudXNlci5pZCB9LFxuICAgIG9wdGlvbnMsXG4gICAgaW5mby5jbGllbnRWZXJzaW9uLFxuICAgIGluZm8uY29udGV4dFxuICApO1xuICBpZiAoIXJlc3BvbnNlLnJlc3VsdHMgfHwgcmVzcG9uc2UucmVzdWx0cy5sZW5ndGggPT0gMCkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdJbnZhbGlkIHNlc3Npb24gdG9rZW4nKTtcbiAgfSBlbHNlIHtcbiAgICBjb25zdCB1c2VyID0gcmVzcG9uc2UucmVzdWx0c1swXTtcbiAgICByZXR1cm4ge1xuICAgICAgc2Vzc2lvblRva2VuLFxuICAgICAgdXNlcixcbiAgICB9O1xuICB9XG59O1xuXG5jb25zdCBsb2FkID0gcGFyc2VHcmFwaFFMU2NoZW1hID0+IHtcbiAgaWYgKHBhcnNlR3JhcGhRTFNjaGVtYS5pc1VzZXJzQ2xhc3NEaXNhYmxlZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMUXVlcnkoXG4gICAgJ3ZpZXdlcicsXG4gICAge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGUgdmlld2VyIHF1ZXJ5IGNhbiBiZSB1c2VkIHRvIHJldHVybiB0aGUgY3VycmVudCB1c2VyIGRhdGEuJyxcbiAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChwYXJzZUdyYXBoUUxTY2hlbWEudmlld2VyVHlwZSksXG4gICAgICBhc3luYyByZXNvbHZlKF9zb3VyY2UsIF9hcmdzLCBjb250ZXh0LCBxdWVyeUluZm8pIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgZ2V0VXNlckZyb21TZXNzaW9uVG9rZW4oY29udGV4dCwgcXVlcnlJbmZvLCAndXNlci4nLCBmYWxzZSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEuaGFuZGxlRXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSxcbiAgICB0cnVlLFxuICAgIHRydWVcbiAgKTtcbn07XG5cbmV4cG9ydCB7IGxvYWQsIGdldFVzZXJGcm9tU2Vzc2lvblRva2VuIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/parseGraphQLUtils.js b/lib/GraphQL/parseGraphQLUtils.js deleted file mode 100644 index 3677a6ca26..0000000000 --- a/lib/GraphQL/parseGraphQLUtils.js +++ /dev/null @@ -1,69 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.enforceMasterKeyAccess = enforceMasterKeyAccess; -exports.toGraphQLError = toGraphQLError; -exports.getParseClassMutationConfig = exports.extractKeysAndInclude = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _apolloServerCore = require("apollo-server-core"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function enforceMasterKeyAccess(auth) { - if (!auth.isMaster) { - throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, 'unauthorized: master key is required'); - } -} - -function toGraphQLError(error) { - let code, message; - - if (error instanceof _node.default.Error) { - code = error.code; - message = error.message; - } else { - code = _node.default.Error.INTERNAL_SERVER_ERROR; - message = 'Internal server error'; - } - - return new _apolloServerCore.ApolloError(message, code); -} - -const extractKeysAndInclude = selectedFields => { - selectedFields = selectedFields.filter(field => !field.includes('__typename')); // Handles "id" field for both current and included objects - - selectedFields = selectedFields.map(field => { - if (field === 'id') return 'objectId'; - return field.endsWith('.id') ? `${field.substring(0, field.lastIndexOf('.id'))}.objectId` : field; - }); - let keys = undefined; - let include = undefined; - - if (selectedFields.length > 0) { - keys = [...new Set(selectedFields)].join(','); // We can use this shortcut since optimization is handled - // later on RestQuery, avoid overhead here. - - include = keys; - } - - return { - // If authData is detected keys will not work properly - // since authData has a special storage behavior - // so we need to skip keys currently - keys: keys && keys.indexOf('authData') === -1 ? keys : undefined, - include - }; -}; - -exports.extractKeysAndInclude = extractKeysAndInclude; - -const getParseClassMutationConfig = function (parseClassConfig) { - return parseClassConfig && parseClassConfig.mutation || {}; -}; - -exports.getParseClassMutationConfig = getParseClassMutationConfig; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9HcmFwaFFML3BhcnNlR3JhcGhRTFV0aWxzLmpzIl0sIm5hbWVzIjpbImVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiLCJhdXRoIiwiaXNNYXN0ZXIiLCJQYXJzZSIsIkVycm9yIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsInRvR3JhcGhRTEVycm9yIiwiZXJyb3IiLCJjb2RlIiwibWVzc2FnZSIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsIkFwb2xsb0Vycm9yIiwiZXh0cmFjdEtleXNBbmRJbmNsdWRlIiwic2VsZWN0ZWRGaWVsZHMiLCJmaWx0ZXIiLCJmaWVsZCIsImluY2x1ZGVzIiwibWFwIiwiZW5kc1dpdGgiLCJzdWJzdHJpbmciLCJsYXN0SW5kZXhPZiIsImtleXMiLCJ1bmRlZmluZWQiLCJpbmNsdWRlIiwibGVuZ3RoIiwiU2V0Iiwiam9pbiIsImluZGV4T2YiLCJnZXRQYXJzZUNsYXNzTXV0YXRpb25Db25maWciLCJwYXJzZUNsYXNzQ29uZmlnIiwibXV0YXRpb24iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBOztBQUNBOzs7O0FBRU8sU0FBU0Esc0JBQVQsQ0FBZ0NDLElBQWhDLEVBQXNDO0FBQzNDLE1BQUksQ0FBQ0EsSUFBSSxDQUFDQyxRQUFWLEVBQW9CO0FBQ2xCLFVBQU0sSUFBSUMsY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZQyxtQkFBNUIsRUFBaUQsc0NBQWpELENBQU47QUFDRDtBQUNGOztBQUVNLFNBQVNDLGNBQVQsQ0FBd0JDLEtBQXhCLEVBQStCO0FBQ3BDLE1BQUlDLElBQUosRUFBVUMsT0FBVjs7QUFDQSxNQUFJRixLQUFLLFlBQVlKLGNBQU1DLEtBQTNCLEVBQWtDO0FBQ2hDSSxJQUFBQSxJQUFJLEdBQUdELEtBQUssQ0FBQ0MsSUFBYjtBQUNBQyxJQUFBQSxPQUFPLEdBQUdGLEtBQUssQ0FBQ0UsT0FBaEI7QUFDRCxHQUhELE1BR087QUFDTEQsSUFBQUEsSUFBSSxHQUFHTCxjQUFNQyxLQUFOLENBQVlNLHFCQUFuQjtBQUNBRCxJQUFBQSxPQUFPLEdBQUcsdUJBQVY7QUFDRDs7QUFDRCxTQUFPLElBQUlFLDZCQUFKLENBQWdCRixPQUFoQixFQUF5QkQsSUFBekIsQ0FBUDtBQUNEOztBQUVNLE1BQU1JLHFCQUFxQixHQUFHQyxjQUFjLElBQUk7QUFDckRBLEVBQUFBLGNBQWMsR0FBR0EsY0FBYyxDQUFDQyxNQUFmLENBQXNCQyxLQUFLLElBQUksQ0FBQ0EsS0FBSyxDQUFDQyxRQUFOLENBQWUsWUFBZixDQUFoQyxDQUFqQixDQURxRCxDQUVyRDs7QUFDQUgsRUFBQUEsY0FBYyxHQUFHQSxjQUFjLENBQUNJLEdBQWYsQ0FBbUJGLEtBQUssSUFBSTtBQUMzQyxRQUFJQSxLQUFLLEtBQUssSUFBZCxFQUFvQixPQUFPLFVBQVA7QUFDcEIsV0FBT0EsS0FBSyxDQUFDRyxRQUFOLENBQWUsS0FBZixJQUNGLEdBQUVILEtBQUssQ0FBQ0ksU0FBTixDQUFnQixDQUFoQixFQUFtQkosS0FBSyxDQUFDSyxXQUFOLENBQWtCLEtBQWxCLENBQW5CLENBQTZDLFdBRDdDLEdBRUhMLEtBRko7QUFHRCxHQUxnQixDQUFqQjtBQU1BLE1BQUlNLElBQUksR0FBR0MsU0FBWDtBQUNBLE1BQUlDLE9BQU8sR0FBR0QsU0FBZDs7QUFFQSxNQUFJVCxjQUFjLENBQUNXLE1BQWYsR0FBd0IsQ0FBNUIsRUFBK0I7QUFDN0JILElBQUFBLElBQUksR0FBRyxDQUFDLEdBQUcsSUFBSUksR0FBSixDQUFRWixjQUFSLENBQUosRUFBNkJhLElBQTdCLENBQWtDLEdBQWxDLENBQVAsQ0FENkIsQ0FFN0I7QUFDQTs7QUFDQUgsSUFBQUEsT0FBTyxHQUFHRixJQUFWO0FBQ0Q7O0FBRUQsU0FBTztBQUNMO0FBQ0E7QUFDQTtBQUNBQSxJQUFBQSxJQUFJLEVBQUVBLElBQUksSUFBSUEsSUFBSSxDQUFDTSxPQUFMLENBQWEsVUFBYixNQUE2QixDQUFDLENBQXRDLEdBQTBDTixJQUExQyxHQUFpREMsU0FKbEQ7QUFLTEMsSUFBQUE7QUFMSyxHQUFQO0FBT0QsQ0ExQk07Ozs7QUE0QkEsTUFBTUssMkJBQTJCLEdBQUcsVUFBVUMsZ0JBQVYsRUFBNEI7QUFDckUsU0FBUUEsZ0JBQWdCLElBQUlBLGdCQUFnQixDQUFDQyxRQUF0QyxJQUFtRCxFQUExRDtBQUNELENBRk0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBBcG9sbG9FcnJvciB9IGZyb20gJ2Fwb2xsby1zZXJ2ZXItY29yZSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBlbmZvcmNlTWFzdGVyS2V5QWNjZXNzKGF1dGgpIHtcbiAgaWYgKCFhdXRoLmlzTWFzdGVyKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sICd1bmF1dGhvcml6ZWQ6IG1hc3RlciBrZXkgaXMgcmVxdWlyZWQnKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdG9HcmFwaFFMRXJyb3IoZXJyb3IpIHtcbiAgbGV0IGNvZGUsIG1lc3NhZ2U7XG4gIGlmIChlcnJvciBpbnN0YW5jZW9mIFBhcnNlLkVycm9yKSB7XG4gICAgY29kZSA9IGVycm9yLmNvZGU7XG4gICAgbWVzc2FnZSA9IGVycm9yLm1lc3NhZ2U7XG4gIH0gZWxzZSB7XG4gICAgY29kZSA9IFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUjtcbiAgICBtZXNzYWdlID0gJ0ludGVybmFsIHNlcnZlciBlcnJvcic7XG4gIH1cbiAgcmV0dXJuIG5ldyBBcG9sbG9FcnJvcihtZXNzYWdlLCBjb2RlKTtcbn1cblxuZXhwb3J0IGNvbnN0IGV4dHJhY3RLZXlzQW5kSW5jbHVkZSA9IHNlbGVjdGVkRmllbGRzID0+IHtcbiAgc2VsZWN0ZWRGaWVsZHMgPSBzZWxlY3RlZEZpZWxkcy5maWx0ZXIoZmllbGQgPT4gIWZpZWxkLmluY2x1ZGVzKCdfX3R5cGVuYW1lJykpO1xuICAvLyBIYW5kbGVzIFwiaWRcIiBmaWVsZCBmb3IgYm90aCBjdXJyZW50IGFuZCBpbmNsdWRlZCBvYmplY3RzXG4gIHNlbGVjdGVkRmllbGRzID0gc2VsZWN0ZWRGaWVsZHMubWFwKGZpZWxkID0+IHtcbiAgICBpZiAoZmllbGQgPT09ICdpZCcpIHJldHVybiAnb2JqZWN0SWQnO1xuICAgIHJldHVybiBmaWVsZC5lbmRzV2l0aCgnLmlkJylcbiAgICAgID8gYCR7ZmllbGQuc3Vic3RyaW5nKDAsIGZpZWxkLmxhc3RJbmRleE9mKCcuaWQnKSl9Lm9iamVjdElkYFxuICAgICAgOiBmaWVsZDtcbiAgfSk7XG4gIGxldCBrZXlzID0gdW5kZWZpbmVkO1xuICBsZXQgaW5jbHVkZSA9IHVuZGVmaW5lZDtcblxuICBpZiAoc2VsZWN0ZWRGaWVsZHMubGVuZ3RoID4gMCkge1xuICAgIGtleXMgPSBbLi4ubmV3IFNldChzZWxlY3RlZEZpZWxkcyldLmpvaW4oJywnKTtcbiAgICAvLyBXZSBjYW4gdXNlIHRoaXMgc2hvcnRjdXQgc2luY2Ugb3B0aW1pemF0aW9uIGlzIGhhbmRsZWRcbiAgICAvLyBsYXRlciBvbiBSZXN0UXVlcnksIGF2b2lkIG92ZXJoZWFkIGhlcmUuXG4gICAgaW5jbHVkZSA9IGtleXM7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIC8vIElmIGF1dGhEYXRhIGlzIGRldGVjdGVkIGtleXMgd2lsbCBub3Qgd29yayBwcm9wZXJseVxuICAgIC8vIHNpbmNlIGF1dGhEYXRhIGhhcyBhIHNwZWNpYWwgc3RvcmFnZSBiZWhhdmlvclxuICAgIC8vIHNvIHdlIG5lZWQgdG8gc2tpcCBrZXlzIGN1cnJlbnRseVxuICAgIGtleXM6IGtleXMgJiYga2V5cy5pbmRleE9mKCdhdXRoRGF0YScpID09PSAtMSA/IGtleXMgOiB1bmRlZmluZWQsXG4gICAgaW5jbHVkZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRQYXJzZUNsYXNzTXV0YXRpb25Db25maWcgPSBmdW5jdGlvbiAocGFyc2VDbGFzc0NvbmZpZykge1xuICByZXR1cm4gKHBhcnNlQ2xhc3NDb25maWcgJiYgcGFyc2VDbGFzc0NvbmZpZy5tdXRhdGlvbikgfHwge307XG59O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/transformers/className.js b/lib/GraphQL/transformers/className.js deleted file mode 100644 index a3b221d3fe..0000000000 --- a/lib/GraphQL/transformers/className.js +++ /dev/null @@ -1,17 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.transformClassNameToGraphQL = void 0; - -const transformClassNameToGraphQL = className => { - if (className[0] === '_') { - className = className.slice(1); - } - - return className[0].toUpperCase() + className.slice(1); -}; - -exports.transformClassNameToGraphQL = transformClassNameToGraphQL; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9jbGFzc05hbWUuanMiXSwibmFtZXMiOlsidHJhbnNmb3JtQ2xhc3NOYW1lVG9HcmFwaFFMIiwiY2xhc3NOYW1lIiwic2xpY2UiLCJ0b1VwcGVyQ2FzZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBLE1BQU1BLDJCQUEyQixHQUFHQyxTQUFTLElBQUk7QUFDL0MsTUFBSUEsU0FBUyxDQUFDLENBQUQsQ0FBVCxLQUFpQixHQUFyQixFQUEwQjtBQUN4QkEsSUFBQUEsU0FBUyxHQUFHQSxTQUFTLENBQUNDLEtBQVYsQ0FBZ0IsQ0FBaEIsQ0FBWjtBQUNEOztBQUNELFNBQU9ELFNBQVMsQ0FBQyxDQUFELENBQVQsQ0FBYUUsV0FBYixLQUE2QkYsU0FBUyxDQUFDQyxLQUFWLENBQWdCLENBQWhCLENBQXBDO0FBQ0QsQ0FMRCIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHRyYW5zZm9ybUNsYXNzTmFtZVRvR3JhcGhRTCA9IGNsYXNzTmFtZSA9PiB7XG4gIGlmIChjbGFzc05hbWVbMF0gPT09ICdfJykge1xuICAgIGNsYXNzTmFtZSA9IGNsYXNzTmFtZS5zbGljZSgxKTtcbiAgfVxuICByZXR1cm4gY2xhc3NOYW1lWzBdLnRvVXBwZXJDYXNlKCkgKyBjbGFzc05hbWUuc2xpY2UoMSk7XG59O1xuXG5leHBvcnQgeyB0cmFuc2Zvcm1DbGFzc05hbWVUb0dyYXBoUUwgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/transformers/constraintType.js b/lib/GraphQL/transformers/constraintType.js deleted file mode 100644 index 8f1bb7e138..0000000000 --- a/lib/GraphQL/transformers/constraintType.js +++ /dev/null @@ -1,73 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.transformConstraintTypeToGraphQL = void 0; - -var defaultGraphQLTypes = _interopRequireWildcard(require("../loaders/defaultGraphQLTypes")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -const transformConstraintTypeToGraphQL = (parseType, targetClass, parseClassTypes, fieldName) => { - if (fieldName === 'id' || fieldName === 'objectId') { - return defaultGraphQLTypes.ID_WHERE_INPUT; - } - - switch (parseType) { - case 'String': - return defaultGraphQLTypes.STRING_WHERE_INPUT; - - case 'Number': - return defaultGraphQLTypes.NUMBER_WHERE_INPUT; - - case 'Boolean': - return defaultGraphQLTypes.BOOLEAN_WHERE_INPUT; - - case 'Array': - return defaultGraphQLTypes.ARRAY_WHERE_INPUT; - - case 'Object': - return defaultGraphQLTypes.OBJECT_WHERE_INPUT; - - case 'Date': - return defaultGraphQLTypes.DATE_WHERE_INPUT; - - case 'Pointer': - if (parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLRelationConstraintsType) { - return parseClassTypes[targetClass].classGraphQLRelationConstraintsType; - } else { - return defaultGraphQLTypes.OBJECT; - } - - case 'File': - return defaultGraphQLTypes.FILE_WHERE_INPUT; - - case 'GeoPoint': - return defaultGraphQLTypes.GEO_POINT_WHERE_INPUT; - - case 'Polygon': - return defaultGraphQLTypes.POLYGON_WHERE_INPUT; - - case 'Bytes': - return defaultGraphQLTypes.BYTES_WHERE_INPUT; - - case 'ACL': - return defaultGraphQLTypes.OBJECT_WHERE_INPUT; - - case 'Relation': - if (parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLRelationConstraintsType) { - return parseClassTypes[targetClass].classGraphQLRelationConstraintsType; - } else { - return defaultGraphQLTypes.OBJECT; - } - - default: - return undefined; - } -}; - -exports.transformConstraintTypeToGraphQL = transformConstraintTypeToGraphQL; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9jb25zdHJhaW50VHlwZS5qcyJdLCJuYW1lcyI6WyJ0cmFuc2Zvcm1Db25zdHJhaW50VHlwZVRvR3JhcGhRTCIsInBhcnNlVHlwZSIsInRhcmdldENsYXNzIiwicGFyc2VDbGFzc1R5cGVzIiwiZmllbGROYW1lIiwiZGVmYXVsdEdyYXBoUUxUeXBlcyIsIklEX1dIRVJFX0lOUFVUIiwiU1RSSU5HX1dIRVJFX0lOUFVUIiwiTlVNQkVSX1dIRVJFX0lOUFVUIiwiQk9PTEVBTl9XSEVSRV9JTlBVVCIsIkFSUkFZX1dIRVJFX0lOUFVUIiwiT0JKRUNUX1dIRVJFX0lOUFVUIiwiREFURV9XSEVSRV9JTlBVVCIsImNsYXNzR3JhcGhRTFJlbGF0aW9uQ29uc3RyYWludHNUeXBlIiwiT0JKRUNUIiwiRklMRV9XSEVSRV9JTlBVVCIsIkdFT19QT0lOVF9XSEVSRV9JTlBVVCIsIlBPTFlHT05fV0hFUkVfSU5QVVQiLCJCWVRFU19XSEVSRV9JTlBVVCIsInVuZGVmaW5lZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7Ozs7QUFFQSxNQUFNQSxnQ0FBZ0MsR0FBRyxDQUFDQyxTQUFELEVBQVlDLFdBQVosRUFBeUJDLGVBQXpCLEVBQTBDQyxTQUExQyxLQUF3RDtBQUMvRixNQUFJQSxTQUFTLEtBQUssSUFBZCxJQUFzQkEsU0FBUyxLQUFLLFVBQXhDLEVBQW9EO0FBQ2xELFdBQU9DLG1CQUFtQixDQUFDQyxjQUEzQjtBQUNEOztBQUVELFVBQVFMLFNBQVI7QUFDRSxTQUFLLFFBQUw7QUFDRSxhQUFPSSxtQkFBbUIsQ0FBQ0Usa0JBQTNCOztBQUNGLFNBQUssUUFBTDtBQUNFLGFBQU9GLG1CQUFtQixDQUFDRyxrQkFBM0I7O0FBQ0YsU0FBSyxTQUFMO0FBQ0UsYUFBT0gsbUJBQW1CLENBQUNJLG1CQUEzQjs7QUFDRixTQUFLLE9BQUw7QUFDRSxhQUFPSixtQkFBbUIsQ0FBQ0ssaUJBQTNCOztBQUNGLFNBQUssUUFBTDtBQUNFLGFBQU9MLG1CQUFtQixDQUFDTSxrQkFBM0I7O0FBQ0YsU0FBSyxNQUFMO0FBQ0UsYUFBT04sbUJBQW1CLENBQUNPLGdCQUEzQjs7QUFDRixTQUFLLFNBQUw7QUFDRSxVQUNFVCxlQUFlLENBQUNELFdBQUQsQ0FBZixJQUNBQyxlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2QlcsbUNBRi9CLEVBR0U7QUFDQSxlQUFPVixlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2QlcsbUNBQXBDO0FBQ0QsT0FMRCxNQUtPO0FBQ0wsZUFBT1IsbUJBQW1CLENBQUNTLE1BQTNCO0FBQ0Q7O0FBQ0gsU0FBSyxNQUFMO0FBQ0UsYUFBT1QsbUJBQW1CLENBQUNVLGdCQUEzQjs7QUFDRixTQUFLLFVBQUw7QUFDRSxhQUFPVixtQkFBbUIsQ0FBQ1cscUJBQTNCOztBQUNGLFNBQUssU0FBTDtBQUNFLGFBQU9YLG1CQUFtQixDQUFDWSxtQkFBM0I7O0FBQ0YsU0FBSyxPQUFMO0FBQ0UsYUFBT1osbUJBQW1CLENBQUNhLGlCQUEzQjs7QUFDRixTQUFLLEtBQUw7QUFDRSxhQUFPYixtQkFBbUIsQ0FBQ00sa0JBQTNCOztBQUNGLFNBQUssVUFBTDtBQUNFLFVBQ0VSLGVBQWUsQ0FBQ0QsV0FBRCxDQUFmLElBQ0FDLGVBQWUsQ0FBQ0QsV0FBRCxDQUFmLENBQTZCVyxtQ0FGL0IsRUFHRTtBQUNBLGVBQU9WLGVBQWUsQ0FBQ0QsV0FBRCxDQUFmLENBQTZCVyxtQ0FBcEM7QUFDRCxPQUxELE1BS087QUFDTCxlQUFPUixtQkFBbUIsQ0FBQ1MsTUFBM0I7QUFDRDs7QUFDSDtBQUNFLGFBQU9LLFNBQVA7QUExQ0o7QUE0Q0QsQ0FqREQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4uL2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5cbmNvbnN0IHRyYW5zZm9ybUNvbnN0cmFpbnRUeXBlVG9HcmFwaFFMID0gKHBhcnNlVHlwZSwgdGFyZ2V0Q2xhc3MsIHBhcnNlQ2xhc3NUeXBlcywgZmllbGROYW1lKSA9PiB7XG4gIGlmIChmaWVsZE5hbWUgPT09ICdpZCcgfHwgZmllbGROYW1lID09PSAnb2JqZWN0SWQnKSB7XG4gICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuSURfV0hFUkVfSU5QVVQ7XG4gIH1cblxuICBzd2l0Y2ggKHBhcnNlVHlwZSkge1xuICAgIGNhc2UgJ1N0cmluZyc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5TVFJJTkdfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnTnVtYmVyJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk5VTUJFUl9XSEVSRV9JTlBVVDtcbiAgICBjYXNlICdCb29sZWFuJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkJPT0xFQU5fV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnQXJyYXknOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuQVJSQVlfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnT2JqZWN0JzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVF9XSEVSRV9JTlBVVDtcbiAgICBjYXNlICdEYXRlJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkRBVEVfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnUG9pbnRlcic6XG4gICAgICBpZiAoXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10gJiZcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXS5jbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdLmNsYXNzR3JhcGhRTFJlbGF0aW9uQ29uc3RyYWludHNUeXBlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUO1xuICAgICAgfVxuICAgIGNhc2UgJ0ZpbGUnOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuRklMRV9XSEVSRV9JTlBVVDtcbiAgICBjYXNlICdHZW9Qb2ludCc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5HRU9fUE9JTlRfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnUG9seWdvbic6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5QT0xZR09OX1dIRVJFX0lOUFVUO1xuICAgIGNhc2UgJ0J5dGVzJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkJZVEVTX1dIRVJFX0lOUFVUO1xuICAgIGNhc2UgJ0FDTCc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1RfV0hFUkVfSU5QVVQ7XG4gICAgY2FzZSAnUmVsYXRpb24nOlxuICAgICAgaWYgKFxuICAgICAgICBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdICYmXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10uY2xhc3NHcmFwaFFMUmVsYXRpb25Db25zdHJhaW50c1R5cGVcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXS5jbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVDtcbiAgICAgIH1cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufTtcblxuZXhwb3J0IHsgdHJhbnNmb3JtQ29uc3RyYWludFR5cGVUb0dyYXBoUUwgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/transformers/inputType.js b/lib/GraphQL/transformers/inputType.js deleted file mode 100644 index af04ed30b5..0000000000 --- a/lib/GraphQL/transformers/inputType.js +++ /dev/null @@ -1,71 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.transformInputTypeToGraphQL = void 0; - -var _graphql = require("graphql"); - -var defaultGraphQLTypes = _interopRequireWildcard(require("../loaders/defaultGraphQLTypes")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -const transformInputTypeToGraphQL = (parseType, targetClass, parseClassTypes) => { - switch (parseType) { - case 'String': - return _graphql.GraphQLString; - - case 'Number': - return _graphql.GraphQLFloat; - - case 'Boolean': - return _graphql.GraphQLBoolean; - - case 'Array': - return new _graphql.GraphQLList(defaultGraphQLTypes.ANY); - - case 'Object': - return defaultGraphQLTypes.OBJECT; - - case 'Date': - return defaultGraphQLTypes.DATE; - - case 'Pointer': - if (parseClassTypes && parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLPointerType) { - return parseClassTypes[targetClass].classGraphQLPointerType; - } else { - return defaultGraphQLTypes.OBJECT; - } - - case 'Relation': - if (parseClassTypes && parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLRelationType) { - return parseClassTypes[targetClass].classGraphQLRelationType; - } else { - return defaultGraphQLTypes.OBJECT; - } - - case 'File': - return defaultGraphQLTypes.FILE_INPUT; - - case 'GeoPoint': - return defaultGraphQLTypes.GEO_POINT_INPUT; - - case 'Polygon': - return defaultGraphQLTypes.POLYGON_INPUT; - - case 'Bytes': - return defaultGraphQLTypes.BYTES; - - case 'ACL': - return defaultGraphQLTypes.ACL_INPUT; - - default: - return undefined; - } -}; - -exports.transformInputTypeToGraphQL = transformInputTypeToGraphQL; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9pbnB1dFR5cGUuanMiXSwibmFtZXMiOlsidHJhbnNmb3JtSW5wdXRUeXBlVG9HcmFwaFFMIiwicGFyc2VUeXBlIiwidGFyZ2V0Q2xhc3MiLCJwYXJzZUNsYXNzVHlwZXMiLCJHcmFwaFFMU3RyaW5nIiwiR3JhcGhRTEZsb2F0IiwiR3JhcGhRTEJvb2xlYW4iLCJHcmFwaFFMTGlzdCIsImRlZmF1bHRHcmFwaFFMVHlwZXMiLCJBTlkiLCJPQkpFQ1QiLCJEQVRFIiwiY2xhc3NHcmFwaFFMUG9pbnRlclR5cGUiLCJjbGFzc0dyYXBoUUxSZWxhdGlvblR5cGUiLCJGSUxFX0lOUFVUIiwiR0VPX1BPSU5UX0lOUFVUIiwiUE9MWUdPTl9JTlBVVCIsIkJZVEVTIiwiQUNMX0lOUFVUIiwidW5kZWZpbmVkIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7Ozs7OztBQUVBLE1BQU1BLDJCQUEyQixHQUFHLENBQUNDLFNBQUQsRUFBWUMsV0FBWixFQUF5QkMsZUFBekIsS0FBNkM7QUFDL0UsVUFBUUYsU0FBUjtBQUNFLFNBQUssUUFBTDtBQUNFLGFBQU9HLHNCQUFQOztBQUNGLFNBQUssUUFBTDtBQUNFLGFBQU9DLHFCQUFQOztBQUNGLFNBQUssU0FBTDtBQUNFLGFBQU9DLHVCQUFQOztBQUNGLFNBQUssT0FBTDtBQUNFLGFBQU8sSUFBSUMsb0JBQUosQ0FBZ0JDLG1CQUFtQixDQUFDQyxHQUFwQyxDQUFQOztBQUNGLFNBQUssUUFBTDtBQUNFLGFBQU9ELG1CQUFtQixDQUFDRSxNQUEzQjs7QUFDRixTQUFLLE1BQUw7QUFDRSxhQUFPRixtQkFBbUIsQ0FBQ0csSUFBM0I7O0FBQ0YsU0FBSyxTQUFMO0FBQ0UsVUFDRVIsZUFBZSxJQUNmQSxlQUFlLENBQUNELFdBQUQsQ0FEZixJQUVBQyxlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2QlUsdUJBSC9CLEVBSUU7QUFDQSxlQUFPVCxlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2QlUsdUJBQXBDO0FBQ0QsT0FORCxNQU1PO0FBQ0wsZUFBT0osbUJBQW1CLENBQUNFLE1BQTNCO0FBQ0Q7O0FBQ0gsU0FBSyxVQUFMO0FBQ0UsVUFDRVAsZUFBZSxJQUNmQSxlQUFlLENBQUNELFdBQUQsQ0FEZixJQUVBQyxlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2Qlcsd0JBSC9CLEVBSUU7QUFDQSxlQUFPVixlQUFlLENBQUNELFdBQUQsQ0FBZixDQUE2Qlcsd0JBQXBDO0FBQ0QsT0FORCxNQU1PO0FBQ0wsZUFBT0wsbUJBQW1CLENBQUNFLE1BQTNCO0FBQ0Q7O0FBQ0gsU0FBSyxNQUFMO0FBQ0UsYUFBT0YsbUJBQW1CLENBQUNNLFVBQTNCOztBQUNGLFNBQUssVUFBTDtBQUNFLGFBQU9OLG1CQUFtQixDQUFDTyxlQUEzQjs7QUFDRixTQUFLLFNBQUw7QUFDRSxhQUFPUCxtQkFBbUIsQ0FBQ1EsYUFBM0I7O0FBQ0YsU0FBSyxPQUFMO0FBQ0UsYUFBT1IsbUJBQW1CLENBQUNTLEtBQTNCOztBQUNGLFNBQUssS0FBTDtBQUNFLGFBQU9ULG1CQUFtQixDQUFDVSxTQUEzQjs7QUFDRjtBQUNFLGFBQU9DLFNBQVA7QUE1Q0o7QUE4Q0QsQ0EvQ0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBHcmFwaFFMU3RyaW5nLCBHcmFwaFFMRmxvYXQsIEdyYXBoUUxCb29sZWFuLCBHcmFwaFFMTGlzdCB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0ICogYXMgZGVmYXVsdEdyYXBoUUxUeXBlcyBmcm9tICcuLi9sb2FkZXJzL2RlZmF1bHRHcmFwaFFMVHlwZXMnO1xuXG5jb25zdCB0cmFuc2Zvcm1JbnB1dFR5cGVUb0dyYXBoUUwgPSAocGFyc2VUeXBlLCB0YXJnZXRDbGFzcywgcGFyc2VDbGFzc1R5cGVzKSA9PiB7XG4gIHN3aXRjaCAocGFyc2VUeXBlKSB7XG4gICAgY2FzZSAnU3RyaW5nJzpcbiAgICAgIHJldHVybiBHcmFwaFFMU3RyaW5nO1xuICAgIGNhc2UgJ051bWJlcic6XG4gICAgICByZXR1cm4gR3JhcGhRTEZsb2F0O1xuICAgIGNhc2UgJ0Jvb2xlYW4nOlxuICAgICAgcmV0dXJuIEdyYXBoUUxCb29sZWFuO1xuICAgIGNhc2UgJ0FycmF5JzpcbiAgICAgIHJldHVybiBuZXcgR3JhcGhRTExpc3QoZGVmYXVsdEdyYXBoUUxUeXBlcy5BTlkpO1xuICAgIGNhc2UgJ09iamVjdCc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1Q7XG4gICAgY2FzZSAnRGF0ZSc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5EQVRFO1xuICAgIGNhc2UgJ1BvaW50ZXInOlxuICAgICAgaWYgKFxuICAgICAgICBwYXJzZUNsYXNzVHlwZXMgJiZcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXSAmJlxuICAgICAgICBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdLmNsYXNzR3JhcGhRTFBvaW50ZXJUeXBlXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10uY2xhc3NHcmFwaFFMUG9pbnRlclR5cGU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1Q7XG4gICAgICB9XG4gICAgY2FzZSAnUmVsYXRpb24nOlxuICAgICAgaWYgKFxuICAgICAgICBwYXJzZUNsYXNzVHlwZXMgJiZcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXSAmJlxuICAgICAgICBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdLmNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdLmNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVDtcbiAgICAgIH1cbiAgICBjYXNlICdGaWxlJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkZJTEVfSU5QVVQ7XG4gICAgY2FzZSAnR2VvUG9pbnQnOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuR0VPX1BPSU5UX0lOUFVUO1xuICAgIGNhc2UgJ1BvbHlnb24nOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuUE9MWUdPTl9JTlBVVDtcbiAgICBjYXNlICdCeXRlcyc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5CWVRFUztcbiAgICBjYXNlICdBQ0wnOlxuICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuQUNMX0lOUFVUO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59O1xuXG5leHBvcnQgeyB0cmFuc2Zvcm1JbnB1dFR5cGVUb0dyYXBoUUwgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/transformers/mutation.js b/lib/GraphQL/transformers/mutation.js deleted file mode 100644 index 1cefb52b90..0000000000 --- a/lib/GraphQL/transformers/mutation.js +++ /dev/null @@ -1,275 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.transformTypes = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _graphqlRelay = require("graphql-relay"); - -var _filesMutations = require("../loaders/filesMutations"); - -var defaultGraphQLTypes = _interopRequireWildcard(require("../loaders/defaultGraphQLTypes")); - -var objectsMutations = _interopRequireWildcard(require("../helpers/objectsMutations")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const transformTypes = async (inputType, fields, { - className, - parseGraphQLSchema, - req -}) => { - const { - classGraphQLCreateType, - classGraphQLUpdateType, - config: { - isCreateEnabled, - isUpdateEnabled - } - } = parseGraphQLSchema.parseClassTypes[className]; - const parseClass = parseGraphQLSchema.parseClasses.find(clazz => clazz.className === className); - - if (fields) { - const classGraphQLCreateTypeFields = isCreateEnabled && classGraphQLCreateType ? classGraphQLCreateType.getFields() : null; - const classGraphQLUpdateTypeFields = isUpdateEnabled && classGraphQLUpdateType ? classGraphQLUpdateType.getFields() : null; - const promises = Object.keys(fields).map(async field => { - let inputTypeField; - - if (inputType === 'create' && classGraphQLCreateTypeFields) { - inputTypeField = classGraphQLCreateTypeFields[field]; - } else if (classGraphQLUpdateTypeFields) { - inputTypeField = classGraphQLUpdateTypeFields[field]; - } - - if (inputTypeField) { - switch (true) { - case inputTypeField.type === defaultGraphQLTypes.GEO_POINT_INPUT: - fields[field] = transformers.geoPoint(fields[field]); - break; - - case inputTypeField.type === defaultGraphQLTypes.POLYGON_INPUT: - fields[field] = transformers.polygon(fields[field]); - break; - - case inputTypeField.type === defaultGraphQLTypes.FILE_INPUT: - fields[field] = await transformers.file(fields[field], req); - break; - - case parseClass.fields[field].type === 'Relation': - fields[field] = await transformers.relation(parseClass.fields[field].targetClass, field, fields[field], parseGraphQLSchema, req); - break; - - case parseClass.fields[field].type === 'Pointer': - fields[field] = await transformers.pointer(parseClass.fields[field].targetClass, field, fields[field], parseGraphQLSchema, req); - break; - } - } - }); - await Promise.all(promises); - if (fields.ACL) fields.ACL = transformers.ACL(fields.ACL); - } - - return fields; -}; - -exports.transformTypes = transformTypes; -const transformers = { - file: async ({ - file, - upload - }, { - config - }) => { - if (file === null && !upload) { - return null; - } - - if (upload) { - const { - fileInfo - } = await (0, _filesMutations.handleUpload)(upload, config); - return _objectSpread(_objectSpread({}, fileInfo), {}, { - __type: 'File' - }); - } else if (file && file.name) { - return { - name: file.name, - __type: 'File', - url: file.url - }; - } - - throw new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, 'Invalid file upload.'); - }, - polygon: value => ({ - __type: 'Polygon', - coordinates: value.map(geoPoint => [geoPoint.latitude, geoPoint.longitude]) - }), - geoPoint: value => _objectSpread(_objectSpread({}, value), {}, { - __type: 'GeoPoint' - }), - ACL: value => { - const parseACL = {}; - - if (value.public) { - parseACL['*'] = { - read: value.public.read, - write: value.public.write - }; - } - - if (value.users) { - value.users.forEach(rule => { - const globalIdObject = (0, _graphqlRelay.fromGlobalId)(rule.userId); - - if (globalIdObject.type === '_User') { - rule.userId = globalIdObject.id; - } - - parseACL[rule.userId] = { - read: rule.read, - write: rule.write - }; - }); - } - - if (value.roles) { - value.roles.forEach(rule => { - parseACL[`role:${rule.roleName}`] = { - read: rule.read, - write: rule.write - }; - }); - } - - return parseACL; - }, - relation: async (targetClass, field, value, parseGraphQLSchema, { - config, - auth, - info - }) => { - if (Object.keys(value).length === 0) throw new _node.default.Error(_node.default.Error.INVALID_POINTER, `You need to provide at least one operation on the relation mutation of field ${field}`); - const op = { - __op: 'Batch', - ops: [] - }; - let nestedObjectsToAdd = []; - - if (value.createAndAdd) { - nestedObjectsToAdd = (await Promise.all(value.createAndAdd.map(async input => { - const parseFields = await transformTypes('create', input, { - className: targetClass, - parseGraphQLSchema, - req: { - config, - auth, - info - } - }); - return objectsMutations.createObject(targetClass, parseFields, config, auth, info); - }))).map(object => ({ - __type: 'Pointer', - className: targetClass, - objectId: object.objectId - })); - } - - if (value.add || nestedObjectsToAdd.length > 0) { - if (!value.add) value.add = []; - value.add = value.add.map(input => { - const globalIdObject = (0, _graphqlRelay.fromGlobalId)(input); - - if (globalIdObject.type === targetClass) { - input = globalIdObject.id; - } - - return { - __type: 'Pointer', - className: targetClass, - objectId: input - }; - }); - op.ops.push({ - __op: 'AddRelation', - objects: [...value.add, ...nestedObjectsToAdd] - }); - } - - if (value.remove) { - op.ops.push({ - __op: 'RemoveRelation', - objects: value.remove.map(input => { - const globalIdObject = (0, _graphqlRelay.fromGlobalId)(input); - - if (globalIdObject.type === targetClass) { - input = globalIdObject.id; - } - - return { - __type: 'Pointer', - className: targetClass, - objectId: input - }; - }) - }); - } - - return op; - }, - pointer: async (targetClass, field, value, parseGraphQLSchema, { - config, - auth, - info - }) => { - if (Object.keys(value).length > 1 || Object.keys(value).length === 0) throw new _node.default.Error(_node.default.Error.INVALID_POINTER, `You need to provide link OR createLink on the pointer mutation of field ${field}`); - let nestedObjectToAdd; - - if (value.createAndLink) { - const parseFields = await transformTypes('create', value.createAndLink, { - className: targetClass, - parseGraphQLSchema, - req: { - config, - auth, - info - } - }); - nestedObjectToAdd = await objectsMutations.createObject(targetClass, parseFields, config, auth, info); - return { - __type: 'Pointer', - className: targetClass, - objectId: nestedObjectToAdd.objectId - }; - } - - if (value.link) { - let objectId = value.link; - const globalIdObject = (0, _graphqlRelay.fromGlobalId)(objectId); - - if (globalIdObject.type === targetClass) { - objectId = globalIdObject.id; - } - - return { - __type: 'Pointer', - className: targetClass, - objectId - }; - } - } -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9tdXRhdGlvbi5qcyJdLCJuYW1lcyI6WyJ0cmFuc2Zvcm1UeXBlcyIsImlucHV0VHlwZSIsImZpZWxkcyIsImNsYXNzTmFtZSIsInBhcnNlR3JhcGhRTFNjaGVtYSIsInJlcSIsImNsYXNzR3JhcGhRTENyZWF0ZVR5cGUiLCJjbGFzc0dyYXBoUUxVcGRhdGVUeXBlIiwiY29uZmlnIiwiaXNDcmVhdGVFbmFibGVkIiwiaXNVcGRhdGVFbmFibGVkIiwicGFyc2VDbGFzc1R5cGVzIiwicGFyc2VDbGFzcyIsInBhcnNlQ2xhc3NlcyIsImZpbmQiLCJjbGF6eiIsImNsYXNzR3JhcGhRTENyZWF0ZVR5cGVGaWVsZHMiLCJnZXRGaWVsZHMiLCJjbGFzc0dyYXBoUUxVcGRhdGVUeXBlRmllbGRzIiwicHJvbWlzZXMiLCJPYmplY3QiLCJrZXlzIiwibWFwIiwiZmllbGQiLCJpbnB1dFR5cGVGaWVsZCIsInR5cGUiLCJkZWZhdWx0R3JhcGhRTFR5cGVzIiwiR0VPX1BPSU5UX0lOUFVUIiwidHJhbnNmb3JtZXJzIiwiZ2VvUG9pbnQiLCJQT0xZR09OX0lOUFVUIiwicG9seWdvbiIsIkZJTEVfSU5QVVQiLCJmaWxlIiwicmVsYXRpb24iLCJ0YXJnZXRDbGFzcyIsInBvaW50ZXIiLCJQcm9taXNlIiwiYWxsIiwiQUNMIiwidXBsb2FkIiwiZmlsZUluZm8iLCJfX3R5cGUiLCJuYW1lIiwidXJsIiwiUGFyc2UiLCJFcnJvciIsIkZJTEVfU0FWRV9FUlJPUiIsInZhbHVlIiwiY29vcmRpbmF0ZXMiLCJsYXRpdHVkZSIsImxvbmdpdHVkZSIsInBhcnNlQUNMIiwicHVibGljIiwicmVhZCIsIndyaXRlIiwidXNlcnMiLCJmb3JFYWNoIiwicnVsZSIsImdsb2JhbElkT2JqZWN0IiwidXNlcklkIiwiaWQiLCJyb2xlcyIsInJvbGVOYW1lIiwiYXV0aCIsImluZm8iLCJsZW5ndGgiLCJJTlZBTElEX1BPSU5URVIiLCJvcCIsIl9fb3AiLCJvcHMiLCJuZXN0ZWRPYmplY3RzVG9BZGQiLCJjcmVhdGVBbmRBZGQiLCJpbnB1dCIsInBhcnNlRmllbGRzIiwib2JqZWN0c011dGF0aW9ucyIsImNyZWF0ZU9iamVjdCIsIm9iamVjdCIsIm9iamVjdElkIiwiYWRkIiwicHVzaCIsIm9iamVjdHMiLCJyZW1vdmUiLCJuZXN0ZWRPYmplY3RUb0FkZCIsImNyZWF0ZUFuZExpbmsiLCJsaW5rIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FBRUEsTUFBTUEsY0FBYyxHQUFHLE9BQ3JCQyxTQURxQixFQUVyQkMsTUFGcUIsRUFHckI7QUFBRUMsRUFBQUEsU0FBRjtBQUFhQyxFQUFBQSxrQkFBYjtBQUFpQ0MsRUFBQUE7QUFBakMsQ0FIcUIsS0FJbEI7QUFDSCxRQUFNO0FBQ0pDLElBQUFBLHNCQURJO0FBRUpDLElBQUFBLHNCQUZJO0FBR0pDLElBQUFBLE1BQU0sRUFBRTtBQUFFQyxNQUFBQSxlQUFGO0FBQW1CQyxNQUFBQTtBQUFuQjtBQUhKLE1BSUZOLGtCQUFrQixDQUFDTyxlQUFuQixDQUFtQ1IsU0FBbkMsQ0FKSjtBQUtBLFFBQU1TLFVBQVUsR0FBR1Isa0JBQWtCLENBQUNTLFlBQW5CLENBQWdDQyxJQUFoQyxDQUFxQ0MsS0FBSyxJQUFJQSxLQUFLLENBQUNaLFNBQU4sS0FBb0JBLFNBQWxFLENBQW5COztBQUNBLE1BQUlELE1BQUosRUFBWTtBQUNWLFVBQU1jLDRCQUE0QixHQUNoQ1AsZUFBZSxJQUFJSCxzQkFBbkIsR0FBNENBLHNCQUFzQixDQUFDVyxTQUF2QixFQUE1QyxHQUFpRixJQURuRjtBQUVBLFVBQU1DLDRCQUE0QixHQUNoQ1IsZUFBZSxJQUFJSCxzQkFBbkIsR0FBNENBLHNCQUFzQixDQUFDVSxTQUF2QixFQUE1QyxHQUFpRixJQURuRjtBQUVBLFVBQU1FLFFBQVEsR0FBR0MsTUFBTSxDQUFDQyxJQUFQLENBQVluQixNQUFaLEVBQW9Cb0IsR0FBcEIs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QVEsRUFBRUssaUJBQWlCLENBQUNMO0FBSHZCLE9BQVA7QUFLRDs7QUFDRCxRQUFJOUIsS0FBSyxDQUFDcUMsSUFBVixFQUFnQjtBQUNkLFVBQUlQLFFBQVEsR0FBRzlCLEtBQUssQ0FBQ3FDLElBQXJCO0FBQ0EsWUFBTTFCLGNBQWMsR0FBRyxnQ0FBYW1CLFFBQWIsQ0FBdkI7O0FBQ0EsVUFBSW5CLGNBQWMsQ0FBQ2xDLElBQWYsS0FBd0JVLFdBQTVCLEVBQXlDO0FBQ3ZDMkMsUUFBQUEsUUFBUSxHQUFHbkIsY0FBYyxDQUFDRSxFQUExQjtBQUNEOztBQUNELGFBQU87QUFDTG5CLFFBQUFBLE1BQU0sRUFBRSxTQURIO0FBRUx2QyxRQUFBQSxTQUFTLEVBQUVnQyxXQUZOO0FBR0wyQyxRQUFBQTtBQUhLLE9BQVA7QUFLRDtBQUNGO0FBL0prQixDQUFyQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCB7IGZyb21HbG9iYWxJZCB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0IHsgaGFuZGxlVXBsb2FkIH0gZnJvbSAnLi4vbG9hZGVycy9maWxlc011dGF0aW9ucyc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4uL2xvYWRlcnMvZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQgKiBhcyBvYmplY3RzTXV0YXRpb25zIGZyb20gJy4uL2hlbHBlcnMvb2JqZWN0c011dGF0aW9ucyc7XG5cbmNvbnN0IHRyYW5zZm9ybVR5cGVzID0gYXN5bmMgKFxuICBpbnB1dFR5cGU6ICdjcmVhdGUnIHwgJ3VwZGF0ZScsXG4gIGZpZWxkcyxcbiAgeyBjbGFzc05hbWUsIHBhcnNlR3JhcGhRTFNjaGVtYSwgcmVxIH1cbikgPT4ge1xuICBjb25zdCB7XG4gICAgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSxcbiAgICBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlLFxuICAgIGNvbmZpZzogeyBpc0NyZWF0ZUVuYWJsZWQsIGlzVXBkYXRlRW5hYmxlZCB9LFxuICB9ID0gcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1tjbGFzc05hbWVdO1xuICBjb25zdCBwYXJzZUNsYXNzID0gcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3Nlcy5maW5kKGNsYXp6ID0+IGNsYXp6LmNsYXNzTmFtZSA9PT0gY2xhc3NOYW1lKTtcbiAgaWYgKGZpZWxkcykge1xuICAgIGNvbnN0IGNsYXNzR3JhcGhRTENyZWF0ZVR5cGVGaWVsZHMgPVxuICAgICAgaXNDcmVhdGVFbmFibGVkICYmIGNsYXNzR3JhcGhRTENyZWF0ZVR5cGUgPyBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlLmdldEZpZWxkcygpIDogbnVsbDtcbiAgICBjb25zdCBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlRmllbGRzID1cbiAgICAgIGlzVXBkYXRlRW5hYmxlZCAmJiBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlID8gY2xhc3NHcmFwaFFMVXBkYXRlVHlwZS5nZXRGaWVsZHMoKSA6IG51bGw7XG4gICAgY29uc3QgcHJvbWlzZXMgPSBPYmplY3Qua2V5cyhmaWVsZHMpLm1hcChhc3luYyBmaWVsZCA9PiB7XG4gICAgICBsZXQgaW5wdXRUeXBlRmllbGQ7XG4gICAgICBpZiAoaW5wdXRUeXBlID09PSAnY3JlYXRlJyAmJiBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlRmllbGRzKSB7XG4gICAgICAgIGlucHV0VHlwZUZpZWxkID0gY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZUZpZWxkc1tmaWVsZF07XG4gICAgICB9IGVsc2UgaWYgKGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGVGaWVsZHMpIHtcbiAgICAgICAgaW5wdXRUeXBlRmllbGQgPSBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlRmllbGRzW2ZpZWxkXTtcbiAgICAgIH1cbiAgICAgIGlmIChpbnB1dFR5cGVGaWVsZCkge1xuICAgICAgICBzd2l0Y2ggKHRydWUpIHtcbiAgICAgICAgICBjYXNlIGlucHV0VHlwZUZpZWxkLnR5cGUgPT09IGRlZmF1bHRHcmFwaFFMVHlwZXMuR0VPX1BPSU5UX0lOUFVUOlxuICAgICAgICAgICAgZmllbGRzW2ZpZWxkXSA9IHRyYW5zZm9ybWVycy5nZW9Qb2ludChmaWVsZHNbZmllbGRdKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgaW5wdXRUeXBlRmllbGQudHlwZSA9PT0gZGVmYXVsdEdyYXBoUUxUeXBlcy5QT0xZR09OX0lOUFVUOlxuICAgICAgICAgICAgZmllbGRzW2ZpZWxkXSA9IHRyYW5zZm9ybWVycy5wb2x5Z29uKGZpZWxkc1tmaWVsZF0pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSBpbnB1dFR5cGVGaWVsZC50eXBlID09PSBkZWZhdWx0R3JhcGhRTFR5cGVzLkZJTEVfSU5QVVQ6XG4gICAgICAgICAgICBmaWVsZHNbZmllbGRdID0gYXdhaXQgdHJhbnNmb3JtZXJzLmZpbGUoZmllbGRzW2ZpZWxkXSwgcmVxKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdSZWxhdGlvbic6XG4gICAgICAgICAgICBmaWVsZHNbZmllbGRdID0gYXdhaXQgdHJhbnNmb3JtZXJzLnJlbGF0aW9uKFxuICAgICAgICAgICAgICBwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0udGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICAgIGZpZWxkLFxuICAgICAgICAgICAgICBmaWVsZHNbZmllbGRdLFxuICAgICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEsXG4gICAgICAgICAgICAgIHJlcVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdQb2ludGVyJzpcbiAgICAgICAgICAgIGZpZWxkc1tmaWVsZF0gPSBhd2FpdCB0cmFuc2Zvcm1lcnMucG9pbnRlcihcbiAgICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnRhcmdldENsYXNzLFxuICAgICAgICAgICAgICBmaWVsZCxcbiAgICAgICAgICAgICAgZmllbGRzW2ZpZWxkXSxcbiAgICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLFxuICAgICAgICAgICAgICByZXFcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICBpZiAoZmllbGRzLkFDTCkgZmllbGRzLkFDTCA9IHRyYW5zZm9ybWVycy5BQ0woZmllbGRzLkFDTCk7XG4gIH1cbiAgcmV0dXJuIGZpZWxkcztcbn07XG5cbmNvbnN0IHRyYW5zZm9ybWVycyA9IHtcbiAgZmlsZTogYXN5bmMgKHsgZmlsZSwgdXBsb2FkIH0sIHsgY29uZmlnIH0pID0+IHtcbiAgICBpZiAoZmlsZSA9PT0gbnVsbCAmJiAhdXBsb2FkKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKHVwbG9hZCkge1xuICAgICAgY29uc3QgeyBmaWxlSW5mbyB9ID0gYXdhaXQgaGFuZGxlVXBsb2FkKHVwbG9hZCwgY29uZmlnKTtcbiAgICAgIHJldHVybiB7IC4uLmZpbGVJbmZvLCBfX3R5cGU6ICdGaWxlJyB9O1xuICAgIH0gZWxzZSBpZiAoZmlsZSAmJiBmaWxlLm5hbWUpIHtcbiAgICAgIHJldHVybiB7IG5hbWU6IGZpbGUubmFtZSwgX190eXBlOiAnRmlsZScsIHVybDogZmlsZS51cmwgfTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkZJTEVfU0FWRV9FUlJPUiwgJ0ludmFsaWQgZmlsZSB1cGxvYWQuJyk7XG4gIH0sXG4gIHBvbHlnb246IHZhbHVlID0+ICh7XG4gICAgX190eXBlOiAnUG9seWdvbicsXG4gICAgY29vcmRpbmF0ZXM6IHZhbHVlLm1hcChnZW9Qb2ludCA9PiBbZ2VvUG9pbnQubGF0aXR1ZGUsIGdlb1BvaW50LmxvbmdpdHVkZV0pLFxuICB9KSxcbiAgZ2VvUG9pbnQ6IHZhbHVlID0+ICh7XG4gICAgLi4udmFsdWUsXG4gICAgX190eXBlOiAnR2VvUG9pbnQnLFxuICB9KSxcbiAgQUNMOiB2YWx1ZSA9PiB7XG4gICAgY29uc3QgcGFyc2VBQ0wgPSB7fTtcbiAgICBpZiAodmFsdWUucHVibGljKSB7XG4gICAgICBwYXJzZUFDTFsnKiddID0ge1xuICAgICAgICByZWFkOiB2YWx1ZS5wdWJsaWMucmVhZCxcbiAgICAgICAgd3JpdGU6IHZhbHVlLnB1YmxpYy53cml0ZSxcbiAgICAgIH07XG4gICAgfVxuICAgIGlmICh2YWx1ZS51c2Vycykge1xuICAgICAgdmFsdWUudXNlcnMuZm9yRWFjaChydWxlID0+IHtcbiAgICAgICAgY29uc3QgZ2xvYmFsSWRPYmplY3QgPSBmcm9tR2xvYmFsSWQocnVsZS51c2VySWQpO1xuICAgICAgICBpZiAoZ2xvYmFsSWRPYmplY3QudHlwZSA9PT0gJ19Vc2VyJykge1xuICAgICAgICAgIHJ1bGUudXNlcklkID0gZ2xvYmFsSWRPYmplY3QuaWQ7XG4gICAgICAgIH1cbiAgICAgICAgcGFyc2VBQ0xbcnVsZS51c2VySWRdID0ge1xuICAgICAgICAgIHJlYWQ6IHJ1bGUucmVhZCxcbiAgICAgICAgICB3cml0ZTogcnVsZS53cml0ZSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAodmFsdWUucm9sZXMpIHtcbiAgICAgIHZhbHVlLnJvbGVzLmZvckVhY2gocnVsZSA9PiB7XG4gICAgICAgIHBhcnNlQUNMW2Byb2xlOiR7cnVsZS5yb2xlTmFtZX1gXSA9IHtcbiAgICAgICAgICByZWFkOiBydWxlLnJlYWQsXG4gICAgICAgICAgd3JpdGU6IHJ1bGUud3JpdGUsXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHBhcnNlQUNMO1xuICB9LFxuICByZWxhdGlvbjogYXN5bmMgKHRhcmdldENsYXNzLCBmaWVsZCwgdmFsdWUsIHBhcnNlR3JhcGhRTFNjaGVtYSwgeyBjb25maWcsIGF1dGgsIGluZm8gfSkgPT4ge1xuICAgIGlmIChPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoID09PSAwKVxuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1BPSU5URVIsXG4gICAgICAgIGBZb3UgbmVlZCB0byBwcm92aWRlIGF0IGxlYXN0IG9uZSBvcGVyYXRpb24gb24gdGhlIHJlbGF0aW9uIG11dGF0aW9uIG9mIGZpZWxkICR7ZmllbGR9YFxuICAgICAgKTtcblxuICAgIGNvbnN0IG9wID0ge1xuICAgICAgX19vcDogJ0JhdGNoJyxcbiAgICAgIG9wczogW10sXG4gICAgfTtcbiAgICBsZXQgbmVzdGVkT2JqZWN0c1RvQWRkID0gW107XG5cbiAgICBpZiAodmFsdWUuY3JlYXRlQW5kQWRkKSB7XG4gICAgICBuZXN0ZWRPYmplY3RzVG9BZGQgPSAoXG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgIHZhbHVlLmNyZWF0ZUFuZEFkZC5tYXAoYXN5bmMgaW5wdXQgPT4ge1xuICAgICAgICAgICAgY29uc3QgcGFyc2VGaWVsZHMgPSBhd2FpdCB0cmFuc2Zvcm1UeXBlcygnY3JlYXRlJywgaW5wdXQsIHtcbiAgICAgICAgICAgICAgY2xhc3NOYW1lOiB0YXJnZXRDbGFzcyxcbiAgICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLFxuICAgICAgICAgICAgICByZXE6IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBvYmplY3RzTXV0YXRpb25zLmNyZWF0ZU9iamVjdCh0YXJnZXRDbGFzcywgcGFyc2VGaWVsZHMsIGNvbmZpZywgYXV0aCwgaW5mbyk7XG4gICAgICAgICAgfSlcbiAgICAgICAgKVxuICAgICAgKS5tYXAob2JqZWN0ID0+ICh7XG4gICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICBvYmplY3RJZDogb2JqZWN0Lm9iamVjdElkLFxuICAgICAgfSkpO1xuICAgIH1cblxuICAgIGlmICh2YWx1ZS5hZGQgfHwgbmVzdGVkT2JqZWN0c1RvQWRkLmxlbmd0aCA+IDApIHtcbiAgICAgIGlmICghdmFsdWUuYWRkKSB2YWx1ZS5hZGQgPSBbXTtcbiAgICAgIHZhbHVlLmFkZCA9IHZhbHVlLmFkZC5tYXAoaW5wdXQgPT4ge1xuICAgICAgICBjb25zdCBnbG9iYWxJZE9iamVjdCA9IGZyb21HbG9iYWxJZChpbnB1dCk7XG4gICAgICAgIGlmIChnbG9iYWxJZE9iamVjdC50eXBlID09PSB0YXJnZXRDbGFzcykge1xuICAgICAgICAgIGlucHV0ID0gZ2xvYmFsSWRPYmplY3QuaWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICAgIG9iamVjdElkOiBpbnB1dCxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgICAgb3Aub3BzLnB1c2goe1xuICAgICAgICBfX29wOiAnQWRkUmVsYXRpb24nLFxuICAgICAgICBvYmplY3RzOiBbLi4udmFsdWUuYWRkLCAuLi5uZXN0ZWRPYmplY3RzVG9BZGRdLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHZhbHVlLnJlbW92ZSkge1xuICAgICAgb3Aub3BzLnB1c2goe1xuICAgICAgICBfX29wOiAnUmVtb3ZlUmVsYXRpb24nLFxuICAgICAgICBvYmplY3RzOiB2YWx1ZS5yZW1vdmUubWFwKGlucHV0ID0+IHtcbiAgICAgICAgICBjb25zdCBnbG9iYWxJZE9iamVjdCA9IGZyb21HbG9iYWxJZChpbnB1dCk7XG4gICAgICAgICAgaWYgKGdsb2JhbElkT2JqZWN0LnR5cGUgPT09IHRhcmdldENsYXNzKSB7XG4gICAgICAgICAgICBpbnB1dCA9IGdsb2JhbElkT2JqZWN0LmlkO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICAgICAgb2JqZWN0SWQ6IGlucHV0LFxuICAgICAgICAgIH07XG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBvcDtcbiAgfSxcbiAgcG9pbnRlcjogYXN5bmMgKHRhcmdldENsYXNzLCBmaWVsZCwgdmFsdWUsIHBhcnNlR3JhcGhRTFNjaGVtYSwgeyBjb25maWcsIGF1dGgsIGluZm8gfSkgPT4ge1xuICAgIGlmIChPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoID4gMSB8fCBPYmplY3Qua2V5cyh2YWx1ZSkubGVuZ3RoID09PSAwKVxuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1BPSU5URVIsXG4gICAgICAgIGBZb3UgbmVlZCB0byBwcm92aWRlIGxpbmsgT1IgY3JlYXRlTGluayBvbiB0aGUgcG9pbnRlciBtdXRhdGlvbiBvZiBmaWVsZCAke2ZpZWxkfWBcbiAgICAgICk7XG5cbiAgICBsZXQgbmVzdGVkT2JqZWN0VG9BZGQ7XG4gICAgaWYgKHZhbHVlLmNyZWF0ZUFuZExpbmspIHtcbiAgICAgIGNvbnN0IHBhcnNlRmllbGRzID0gYXdhaXQgdHJhbnNmb3JtVHlwZXMoJ2NyZWF0ZScsIHZhbHVlLmNyZWF0ZUFuZExpbmssIHtcbiAgICAgICAgY2xhc3NOYW1lOiB0YXJnZXRDbGFzcyxcbiAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLFxuICAgICAgICByZXE6IHsgY29uZmlnLCBhdXRoLCBpbmZvIH0sXG4gICAgICB9KTtcbiAgICAgIG5lc3RlZE9iamVjdFRvQWRkID0gYXdhaXQgb2JqZWN0c011dGF0aW9ucy5jcmVhdGVPYmplY3QoXG4gICAgICAgIHRhcmdldENsYXNzLFxuICAgICAgICBwYXJzZUZpZWxkcyxcbiAgICAgICAgY29uZmlnLFxuICAgICAgICBhdXRoLFxuICAgICAgICBpbmZvXG4gICAgICApO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICAgIGNsYXNzTmFtZTogdGFyZ2V0Q2xhc3MsXG4gICAgICAgIG9iamVjdElkOiBuZXN0ZWRPYmplY3RUb0FkZC5vYmplY3RJZCxcbiAgICAgIH07XG4gICAgfVxuICAgIGlmICh2YWx1ZS5saW5rKSB7XG4gICAgICBsZXQgb2JqZWN0SWQgPSB2YWx1ZS5saW5rO1xuICAgICAgY29uc3QgZ2xvYmFsSWRPYmplY3QgPSBmcm9tR2xvYmFsSWQob2JqZWN0SWQpO1xuICAgICAgaWYgKGdsb2JhbElkT2JqZWN0LnR5cGUgPT09IHRhcmdldENsYXNzKSB7XG4gICAgICAgIG9iamVjdElkID0gZ2xvYmFsSWRPYmplY3QuaWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgY2xhc3NOYW1lOiB0YXJnZXRDbGFzcyxcbiAgICAgICAgb2JqZWN0SWQsXG4gICAgICB9O1xuICAgIH1cbiAgfSxcbn07XG5cbmV4cG9ydCB7IHRyYW5zZm9ybVR5cGVzIH07XG4iXX0= \ No newline at end of file diff --git a/lib/GraphQL/transformers/outputType.js b/lib/GraphQL/transformers/outputType.js deleted file mode 100644 index e4713fafb8..0000000000 --- a/lib/GraphQL/transformers/outputType.js +++ /dev/null @@ -1,71 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.transformOutputTypeToGraphQL = void 0; - -var defaultGraphQLTypes = _interopRequireWildcard(require("../loaders/defaultGraphQLTypes")); - -var _graphql = require("graphql"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -const transformOutputTypeToGraphQL = (parseType, targetClass, parseClassTypes) => { - switch (parseType) { - case 'String': - return _graphql.GraphQLString; - - case 'Number': - return _graphql.GraphQLFloat; - - case 'Boolean': - return _graphql.GraphQLBoolean; - - case 'Array': - return new _graphql.GraphQLList(defaultGraphQLTypes.ARRAY_RESULT); - - case 'Object': - return defaultGraphQLTypes.OBJECT; - - case 'Date': - return defaultGraphQLTypes.DATE; - - case 'Pointer': - if (parseClassTypes && parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLOutputType) { - return parseClassTypes[targetClass].classGraphQLOutputType; - } else { - return defaultGraphQLTypes.OBJECT; - } - - case 'Relation': - if (parseClassTypes && parseClassTypes[targetClass] && parseClassTypes[targetClass].classGraphQLFindResultType) { - return new _graphql.GraphQLNonNull(parseClassTypes[targetClass].classGraphQLFindResultType); - } else { - return new _graphql.GraphQLNonNull(defaultGraphQLTypes.OBJECT); - } - - case 'File': - return defaultGraphQLTypes.FILE_INFO; - - case 'GeoPoint': - return defaultGraphQLTypes.GEO_POINT; - - case 'Polygon': - return defaultGraphQLTypes.POLYGON; - - case 'Bytes': - return defaultGraphQLTypes.BYTES; - - case 'ACL': - return new _graphql.GraphQLNonNull(defaultGraphQLTypes.ACL); - - default: - return undefined; - } -}; - -exports.transformOutputTypeToGraphQL = transformOutputTypeToGraphQL; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9vdXRwdXRUeXBlLmpzIl0sIm5hbWVzIjpbInRyYW5zZm9ybU91dHB1dFR5cGVUb0dyYXBoUUwiLCJwYXJzZVR5cGUiLCJ0YXJnZXRDbGFzcyIsInBhcnNlQ2xhc3NUeXBlcyIsIkdyYXBoUUxTdHJpbmciLCJHcmFwaFFMRmxvYXQiLCJHcmFwaFFMQm9vbGVhbiIsIkdyYXBoUUxMaXN0IiwiZGVmYXVsdEdyYXBoUUxUeXBlcyIsIkFSUkFZX1JFU1VMVCIsIk9CSkVDVCIsIkRBVEUiLCJjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIiwiY2xhc3NHcmFwaFFMRmluZFJlc3VsdFR5cGUiLCJHcmFwaFFMTm9uTnVsbCIsIkZJTEVfSU5GTyIsIkdFT19QT0lOVCIsIlBPTFlHT04iLCJCWVRFUyIsIkFDTCIsInVuZGVmaW5lZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOzs7Ozs7QUFFQSxNQUFNQSw0QkFBNEIsR0FBRyxDQUFDQyxTQUFELEVBQVlDLFdBQVosRUFBeUJDLGVBQXpCLEtBQTZDO0FBQ2hGLFVBQVFGLFNBQVI7QUFDRSxTQUFLLFFBQUw7QUFDRSxhQUFPRyxzQkFBUDs7QUFDRixTQUFLLFFBQUw7QUFDRSxhQUFPQyxxQkFBUDs7QUFDRixTQUFLLFNBQUw7QUFDRSxhQUFPQyx1QkFBUDs7QUFDRixTQUFLLE9BQUw7QUFDRSxhQUFPLElBQUlDLG9CQUFKLENBQWdCQyxtQkFBbUIsQ0FBQ0MsWUFBcEMsQ0FBUDs7QUFDRixTQUFLLFFBQUw7QUFDRSxhQUFPRCxtQkFBbUIsQ0FBQ0UsTUFBM0I7O0FBQ0YsU0FBSyxNQUFMO0FBQ0UsYUFBT0YsbUJBQW1CLENBQUNHLElBQTNCOztBQUNGLFNBQUssU0FBTDtBQUNFLFVBQ0VSLGVBQWUsSUFDZkEsZUFBZSxDQUFDRCxXQUFELENBRGYsSUFFQUMsZUFBZSxDQUFDRCxXQUFELENBQWYsQ0FBNkJVLHNCQUgvQixFQUlFO0FBQ0EsZUFBT1QsZUFBZSxDQUFDRCxXQUFELENBQWYsQ0FBNkJVLHNCQUFwQztBQUNELE9BTkQsTUFNTztBQUNMLGVBQU9KLG1CQUFtQixDQUFDRSxNQUEzQjtBQUNEOztBQUNILFNBQUssVUFBTDtBQUNFLFVBQ0VQLGVBQWUsSUFDZkEsZUFBZSxDQUFDRCxXQUFELENBRGYsSUFFQUMsZUFBZSxDQUFDRCxXQUFELENBQWYsQ0FBNkJXLDBCQUgvQixFQUlFO0FBQ0EsZUFBTyxJQUFJQyx1QkFBSixDQUFtQlgsZUFBZSxDQUFDRCxXQUFELENBQWYsQ0FBNkJXLDBCQUFoRCxDQUFQO0FBQ0QsT0FORCxNQU1PO0FBQ0wsZUFBTyxJQUFJQyx1QkFBSixDQUFtQk4sbUJBQW1CLENBQUNFLE1BQXZDLENBQVA7QUFDRDs7QUFDSCxTQUFLLE1BQUw7QUFDRSxhQUFPRixtQkFBbUIsQ0FBQ08sU0FBM0I7O0FBQ0YsU0FBSyxVQUFMO0FBQ0UsYUFBT1AsbUJBQW1CLENBQUNRLFNBQTNCOztBQUNGLFNBQUssU0FBTDtBQUNFLGFBQU9SLG1CQUFtQixDQUFDUyxPQUEzQjs7QUFDRixTQUFLLE9BQUw7QUFDRSxhQUFPVCxtQkFBbUIsQ0FBQ1UsS0FBM0I7O0FBQ0YsU0FBSyxLQUFMO0FBQ0UsYUFBTyxJQUFJSix1QkFBSixDQUFtQk4sbUJBQW1CLENBQUNXLEdBQXZDLENBQVA7O0FBQ0Y7QUFDRSxhQUFPQyxTQUFQO0FBNUNKO0FBOENELENBL0NEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZGVmYXVsdEdyYXBoUUxUeXBlcyBmcm9tICcuLi9sb2FkZXJzL2RlZmF1bHRHcmFwaFFMVHlwZXMnO1xuaW1wb3J0IHsgR3JhcGhRTFN0cmluZywgR3JhcGhRTEZsb2F0LCBHcmFwaFFMQm9vbGVhbiwgR3JhcGhRTExpc3QsIEdyYXBoUUxOb25OdWxsIH0gZnJvbSAnZ3JhcGhxbCc7XG5cbmNvbnN0IHRyYW5zZm9ybU91dHB1dFR5cGVUb0dyYXBoUUwgPSAocGFyc2VUeXBlLCB0YXJnZXRDbGFzcywgcGFyc2VDbGFzc1R5cGVzKSA9PiB7XG4gIHN3aXRjaCAocGFyc2VUeXBlKSB7XG4gICAgY2FzZSAnU3RyaW5nJzpcbiAgICAgIHJldHVybiBHcmFwaFFMU3RyaW5nO1xuICAgIGNhc2UgJ051bWJlcic6XG4gICAgICByZXR1cm4gR3JhcGhRTEZsb2F0O1xuICAgIGNhc2UgJ0Jvb2xlYW4nOlxuICAgICAgcmV0dXJuIEdyYXBoUUxCb29sZWFuO1xuICAgIGNhc2UgJ0FycmF5JzpcbiAgICAgIHJldHVybiBuZXcgR3JhcGhRTExpc3QoZGVmYXVsdEdyYXBoUUxUeXBlcy5BUlJBWV9SRVNVTFQpO1xuICAgIGNhc2UgJ09iamVjdCc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1Q7XG4gICAgY2FzZSAnRGF0ZSc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5EQVRFO1xuICAgIGNhc2UgJ1BvaW50ZXInOlxuICAgICAgaWYgKFxuICAgICAgICBwYXJzZUNsYXNzVHlwZXMgJiZcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXSAmJlxuICAgICAgICBwYXJzZUNsYXNzVHlwZXNbdGFyZ2V0Q2xhc3NdLmNsYXNzR3JhcGhRTE91dHB1dFR5cGVcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXS5jbGFzc0dyYXBoUUxPdXRwdXRUeXBlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUO1xuICAgICAgfVxuICAgIGNhc2UgJ1JlbGF0aW9uJzpcbiAgICAgIGlmIChcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzICYmXG4gICAgICAgIHBhcnNlQ2xhc3NUeXBlc1t0YXJnZXRDbGFzc10gJiZcbiAgICAgICAgcGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXS5jbGFzc0dyYXBoUUxGaW5kUmVzdWx0VHlwZVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBuZXcgR3JhcGhRTE5vbk51bGwocGFyc2VDbGFzc1R5cGVzW3RhcmdldENsYXNzXS5jbGFzc0dyYXBoUUxGaW5kUmVzdWx0VHlwZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbmV3IEdyYXBoUUxOb25OdWxsKGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUKTtcbiAgICAgIH1cbiAgICBjYXNlICdGaWxlJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkZJTEVfSU5GTztcbiAgICBjYXNlICdHZW9Qb2ludCc6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5HRU9fUE9JTlQ7XG4gICAgY2FzZSAnUG9seWdvbic6XG4gICAgICByZXR1cm4gZGVmYXVsdEdyYXBoUUxUeXBlcy5QT0xZR09OO1xuICAgIGNhc2UgJ0J5dGVzJzpcbiAgICAgIHJldHVybiBkZWZhdWx0R3JhcGhRTFR5cGVzLkJZVEVTO1xuICAgIGNhc2UgJ0FDTCc6XG4gICAgICByZXR1cm4gbmV3IEdyYXBoUUxOb25OdWxsKGRlZmF1bHRHcmFwaFFMVHlwZXMuQUNMKTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufTtcblxuZXhwb3J0IHsgdHJhbnNmb3JtT3V0cHV0VHlwZVRvR3JhcGhRTCB9O1xuIl19 \ No newline at end of file diff --git a/lib/GraphQL/transformers/query.js b/lib/GraphQL/transformers/query.js deleted file mode 100644 index d13b1cbb09..0000000000 --- a/lib/GraphQL/transformers/query.js +++ /dev/null @@ -1,273 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.transformQueryInputToParse = exports.transformQueryConstraintInputToParse = void 0; - -var _graphqlRelay = require("graphql-relay"); - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const parseQueryMap = { - OR: '$or', - AND: '$and', - NOR: '$nor' -}; -const parseConstraintMap = { - equalTo: '$eq', - notEqualTo: '$ne', - lessThan: '$lt', - lessThanOrEqualTo: '$lte', - greaterThan: '$gt', - greaterThanOrEqualTo: '$gte', - in: '$in', - notIn: '$nin', - exists: '$exists', - inQueryKey: '$select', - notInQueryKey: '$dontSelect', - inQuery: '$inQuery', - notInQuery: '$notInQuery', - containedBy: '$containedBy', - contains: '$all', - matchesRegex: '$regex', - options: '$options', - text: '$text', - search: '$search', - term: '$term', - language: '$language', - caseSensitive: '$caseSensitive', - diacriticSensitive: '$diacriticSensitive', - nearSphere: '$nearSphere', - maxDistance: '$maxDistance', - maxDistanceInRadians: '$maxDistanceInRadians', - maxDistanceInMiles: '$maxDistanceInMiles', - maxDistanceInKilometers: '$maxDistanceInKilometers', - within: '$within', - box: '$box', - geoWithin: '$geoWithin', - polygon: '$polygon', - centerSphere: '$centerSphere', - geoIntersects: '$geoIntersects', - point: '$point' -}; - -const transformQueryConstraintInputToParse = (constraints, parentFieldName, className, parentConstraints, parseClasses) => { - const fields = parseClasses.find(parseClass => parseClass.className === className).fields; - - if (parentFieldName === 'id' && className) { - Object.keys(constraints).forEach(constraintName => { - const constraintValue = constraints[constraintName]; - - if (typeof constraintValue === 'string') { - const globalIdObject = (0, _graphqlRelay.fromGlobalId)(constraintValue); - - if (globalIdObject.type === className) { - constraints[constraintName] = globalIdObject.id; - } - } else if (Array.isArray(constraintValue)) { - constraints[constraintName] = constraintValue.map(value => { - const globalIdObject = (0, _graphqlRelay.fromGlobalId)(value); - - if (globalIdObject.type === className) { - return globalIdObject.id; - } - - return value; - }); - } - }); - parentConstraints.objectId = constraints; - delete parentConstraints.id; - } - - Object.keys(constraints).forEach(fieldName => { - let fieldValue = constraints[fieldName]; - - if (parseConstraintMap[fieldName]) { - constraints[parseConstraintMap[fieldName]] = constraints[fieldName]; - delete constraints[fieldName]; - } - /** - * If we have a key-value pair, we need to change the way the constraint is structured. - * - * Example: - * From: - * { - * "someField": { - * "lessThan": { - * "key":"foo.bar", - * "value": 100 - * }, - * "greaterThan": { - * "key":"foo.bar", - * "value": 10 - * } - * } - * } - * - * To: - * { - * "someField.foo.bar": { - * "$lt": 100, - * "$gt": 10 - * } - * } - */ - - - if (fieldValue.key && fieldValue.value && parentConstraints && parentFieldName) { - delete parentConstraints[parentFieldName]; - parentConstraints[`${parentFieldName}.${fieldValue.key}`] = _objectSpread(_objectSpread({}, parentConstraints[`${parentFieldName}.${fieldValue.key}`]), {}, { - [parseConstraintMap[fieldName]]: fieldValue.value - }); - } else if (fields[parentFieldName] && (fields[parentFieldName].type === 'Pointer' || fields[parentFieldName].type === 'Relation')) { - const { - targetClass - } = fields[parentFieldName]; - - if (fieldName === 'exists') { - if (fields[parentFieldName].type === 'Relation') { - const whereTarget = fieldValue ? 'where' : 'notWhere'; - - if (constraints[whereTarget]) { - if (constraints[whereTarget].objectId) { - constraints[whereTarget].objectId = _objectSpread(_objectSpread({}, constraints[whereTarget].objectId), {}, { - $exists: fieldValue - }); - } else { - constraints[whereTarget].objectId = { - $exists: fieldValue - }; - } - } else { - const parseWhereTarget = fieldValue ? '$inQuery' : '$notInQuery'; - parentConstraints[parentFieldName][parseWhereTarget] = { - where: { - objectId: { - $exists: true - } - }, - className: targetClass - }; - } - - delete constraints.$exists; - } else { - parentConstraints[parentFieldName].$exists = fieldValue; - } - - return; - } - - switch (fieldName) { - case 'have': - parentConstraints[parentFieldName].$inQuery = { - where: fieldValue, - className: targetClass - }; - transformQueryInputToParse(parentConstraints[parentFieldName].$inQuery.where, targetClass, parseClasses); - break; - - case 'haveNot': - parentConstraints[parentFieldName].$notInQuery = { - where: fieldValue, - className: targetClass - }; - transformQueryInputToParse(parentConstraints[parentFieldName].$notInQuery.where, targetClass, parseClasses); - break; - } - - delete constraints[fieldName]; - return; - } - - switch (fieldName) { - case 'point': - if (typeof fieldValue === 'object' && !fieldValue.__type) { - fieldValue.__type = 'GeoPoint'; - } - - break; - - case 'nearSphere': - if (typeof fieldValue === 'object' && !fieldValue.__type) { - fieldValue.__type = 'GeoPoint'; - } - - break; - - case 'box': - if (typeof fieldValue === 'object' && fieldValue.bottomLeft && fieldValue.upperRight) { - fieldValue = [_objectSpread({ - __type: 'GeoPoint' - }, fieldValue.bottomLeft), _objectSpread({ - __type: 'GeoPoint' - }, fieldValue.upperRight)]; - constraints[parseConstraintMap[fieldName]] = fieldValue; - } - - break; - - case 'polygon': - if (fieldValue instanceof Array) { - fieldValue.forEach(geoPoint => { - if (typeof geoPoint === 'object' && !geoPoint.__type) { - geoPoint.__type = 'GeoPoint'; - } - }); - } - - break; - - case 'centerSphere': - if (typeof fieldValue === 'object' && fieldValue.center && fieldValue.distance) { - fieldValue = [_objectSpread({ - __type: 'GeoPoint' - }, fieldValue.center), fieldValue.distance]; - constraints[parseConstraintMap[fieldName]] = fieldValue; - } - - break; - } - - if (typeof fieldValue === 'object') { - if (fieldName === 'where') { - transformQueryInputToParse(fieldValue, className, parseClasses); - } else { - transformQueryConstraintInputToParse(fieldValue, fieldName, className, constraints, parseClasses); - } - } - }); -}; - -exports.transformQueryConstraintInputToParse = transformQueryConstraintInputToParse; - -const transformQueryInputToParse = (constraints, className, parseClasses) => { - if (!constraints || typeof constraints !== 'object') { - return; - } - - Object.keys(constraints).forEach(fieldName => { - const fieldValue = constraints[fieldName]; - - if (parseQueryMap[fieldName]) { - delete constraints[fieldName]; - fieldName = parseQueryMap[fieldName]; - constraints[fieldName] = fieldValue; - fieldValue.forEach(fieldValueItem => { - transformQueryInputToParse(fieldValueItem, className, parseClasses); - }); - return; - } else { - transformQueryConstraintInputToParse(fieldValue, fieldName, className, constraints, parseClasses); - } - }); -}; - -exports.transformQueryInputToParse = transformQueryInputToParse; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9xdWVyeS5qcyJdLCJuYW1lcyI6WyJwYXJzZVF1ZXJ5TWFwIiwiT1IiLCJBTkQiLCJOT1IiLCJwYXJzZUNvbnN0cmFpbnRNYXAiLCJlcXVhbFRvIiwibm90RXF1YWxUbyIsImxlc3NUaGFuIiwibGVzc1RoYW5PckVxdWFsVG8iLCJncmVhdGVyVGhhbiIsImdyZWF0ZXJUaGFuT3JFcXVhbFRvIiwiaW4iLCJub3RJbiIsImV4aXN0cyIsImluUXVlcnlLZXkiLCJub3RJblF1ZXJ5S2V5IiwiaW5RdWVyeSIsIm5vdEluUXVlcnkiLCJjb250YWluZWRCeSIsImNvbnRhaW5zIiwibWF0Y2hlc1JlZ2V4Iiwib3B0aW9ucyIsInRleHQiLCJzZWFyY2giLCJ0ZXJtIiwibGFuZ3VhZ2UiLCJjYXNlU2Vuc2l0aXZlIiwiZGlhY3JpdGljU2Vuc2l0aXZlIiwibmVhclNwaGVyZSIsIm1heERpc3RhbmNlIiwibWF4RGlzdGFuY2VJblJhZGlhbnMiLCJtYXhEaXN0YW5jZUluTWlsZXMiLCJtYXhEaXN0YW5jZUluS2lsb21ldGVycyIsIndpdGhpbiIsImJveCIsImdlb1dpdGhpbiIsInBvbHlnb24iLCJjZW50ZXJTcGhlcmUiLCJnZW9JbnRlcnNlY3RzIiwicG9pbnQiLCJ0cmFuc2Zvcm1RdWVyeUNvbnN0cmFpbnRJbnB1dFRvUGFyc2UiLCJjb25zdHJhaW50cyIsInBhcmVudEZpZWxkTmFtZSIsImNsYXNzTmFtZSIsInBhcmVudENvbnN0cmFpbnRzIiwicGFyc2VDbGFzc2VzIiwiZmllbGRzIiwiZmluZCIsInBhcnNlQ2xhc3MiLCJPYmplY3QiLCJrZXlzIiwiZm9yRWFjaCIsImNvbnN0cmFpbnROYW1lIiwiY29uc3RyYWludFZhbHVlIiwiZ2xvYmFsSWRPYmplY3QiLCJ0eXBlIiwiaWQiLCJBcnJheSIsImlzQXJyYXkiLCJtYXAiLCJ2YWx1ZSIsIm9iamVjdElkIiwiZmllbGROYW1lIiwiZmllbGRWYWx1ZSIsImtleSIsInRhcmdldENsYXNzIiwid2hlcmVUYXJnZXQiLCIkZXhpc3RzIiwicGFyc2VXaGVyZVRhcmdldCIsIndoZXJlIiwiJGluUXVlcnkiLCJ0cmFuc2Zvcm1RdWVyeUlucHV0VG9QYXJzZSIsIiRub3RJblF1ZXJ5IiwiX190eXBlIiwiYm90dG9tTGVmdCIsInVwcGVyUmlnaHQiLCJnZW9Qb2ludCIsImNlbnRlciIsImRpc3RhbmNlIiwiZmllbGRWYWx1ZUl0ZW0iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7Ozs7Ozs7QUFFQSxNQUFNQSxhQUFhLEdBQUc7QUFDcEJDLEVBQUFBLEVBQUUsRUFBRSxLQURnQjtBQUVwQkMsRUFBQUEsR0FBRyxFQUFFLE1BRmU7QUFHcEJDLEVBQUFBLEdBQUcsRUFBRTtBQUhlLENBQXRCO0FBTUEsTUFBTUMsa0JBQWtCLEdBQUc7QUFDekJDLEVBQUFBLE9BQU8sRUFBRSxLQURnQjtBQUV6QkMsRUFBQUEsVUFBVSxFQUFFLEtBRmE7QUFHekJDLEVBQUFBLFFBQVEsRUFBRSxLQUhlO0FBSXpCQyxFQUFBQSxpQkFBaUIsRUFBRSxNQUpNO0FBS3pCQyxFQUFBQSxXQUFXLEVBQUUsS0FMWTtBQU16QkMsRUFBQUEsb0JBQW9CLEVBQUUsTUFORztBQU96QkMsRUFBQUEsRUFBRSxFQUFFLEtBUHFCO0FBUXpCQyxFQUFBQSxLQUFLLEVBQUUsTUFSa0I7QUFTekJDLEVBQUFBLE1BQU0sRUFBRSxTQVRpQjtBQVV6QkMsRUFBQUEsVUFBVSxFQUFFLFNBVmE7QUFXekJDLEVBQUFBLGFBQWEsRUFBRSxhQVhVO0FBWXpCQyxFQUFBQSxPQUFPLEVBQUUsVUFaZ0I7QUFhekJDLEVBQUFBLFVBQVUsRUFBRSxhQWJhO0FBY3pCQyxFQUFBQSxXQUFXLEVBQUUsY0FkWTtBQWV6QkMsRUFBQUEsUUFBUSxFQUFFLE1BZmU7QUFnQnpCQyxFQUFBQSxZQUFZLEVBQUUsUUFoQlc7QUFpQnpCQyxFQUFBQSxPQUFPLEVBQUUsVUFqQmdCO0FBa0J6QkMsRUFBQUEsSUFBSSxFQUFFLE9BbEJtQjtBQW1CekJD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LEVBQUFBLE1BQU0sQ0FBQ0MsSUFBUCxDQUFZVCxXQUFaLEVBQXlCVSxPQUF6QixDQUFpQ1csU0FBUyxJQUFJO0FBQzVDLFVBQU1DLFVBQVUsR0FBR3RCLFdBQVcsQ0FBQ3FCLFNBQUQsQ0FBOUI7O0FBRUEsUUFBSTlELGFBQWEsQ0FBQzhELFNBQUQsQ0FBakIsRUFBOEI7QUFDNUIsYUFBT3JCLFdBQVcsQ0FBQ3FCLFNBQUQsQ0FBbEI7QUFDQUEsTUFBQUEsU0FBUyxHQUFHOUQsYUFBYSxDQUFDOEQsU0FBRCxDQUF6QjtBQUNBckIsTUFBQUEsV0FBVyxDQUFDcUIsU0FBRCxDQUFYLEdBQXlCQyxVQUF6QjtBQUNBQSxNQUFBQSxVQUFVLENBQUNaLE9BQVgsQ0FBbUI0QixjQUFjLElBQUk7QUFDbkNSLFFBQUFBLDBCQUEwQixDQUFDUSxjQUFELEVBQWlCcEMsU0FBakIsRUFBNEJFLFlBQTVCLENBQTFCO0FBQ0QsT0FGRDtBQUdBO0FBQ0QsS0FSRCxNQVFPO0FBQ0xMLE1BQUFBLG9DQUFvQyxDQUNsQ3VCLFVBRGtDLEVBRWxDRCxTQUZrQyxFQUdsQ25CLFNBSGtDLEVBSWxDRixXQUprQyxFQUtsQ0ksWUFMa0MsQ0FBcEM7QUFPRDtBQUNGLEdBcEJEO0FBcUJELENBMUJEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZnJvbUdsb2JhbElkIH0gZnJvbSAnZ3JhcGhxbC1yZWxheSc7XG5cbmNvbnN0IHBhcnNlUXVlcnlNYXAgPSB7XG4gIE9SOiAnJG9yJyxcbiAgQU5EOiAnJGFuZCcsXG4gIE5PUjogJyRub3InLFxufTtcblxuY29uc3QgcGFyc2VDb25zdHJhaW50TWFwID0ge1xuICBlcXVhbFRvOiAnJGVxJyxcbiAgbm90RXF1YWxUbzogJyRuZScsXG4gIGxlc3NUaGFuOiAnJGx0JyxcbiAgbGVzc1RoYW5PckVxdWFsVG86ICckbHRlJyxcbiAgZ3JlYXRlclRoYW46ICckZ3QnLFxuICBncmVhdGVyVGhhbk9yRXF1YWxUbzogJyRndGUnLFxuICBpbjogJyRpbicsXG4gIG5vdEluOiAnJG5pbicsXG4gIGV4aXN0czogJyRleGlzdHMnLFxuICBpblF1ZXJ5S2V5OiAnJHNlbGVjdCcsXG4gIG5vdEluUXVlcnlLZXk6ICckZG9udFNlbGVjdCcsXG4gIGluUXVlcnk6ICckaW5RdWVyeScsXG4gIG5vdEluUXVlcnk6ICckbm90SW5RdWVyeScsXG4gIGNvbnRhaW5lZEJ5OiAnJGNvbnRhaW5lZEJ5JyxcbiAgY29udGFpbnM6ICckYWxsJyxcbiAgbWF0Y2hlc1JlZ2V4OiAnJHJlZ2V4JyxcbiAgb3B0aW9uczogJyRvcHRpb25zJyxcbiAgdGV4dDogJyR0ZXh0JyxcbiAgc2VhcmNoOiAnJHNlYXJjaCcsXG4gIHRlcm06ICckdGVybScsXG4gIGxhbmd1YWdlOiAnJGxhbmd1YWdlJyxcbiAgY2FzZVNlbnNpdGl2ZTogJyRjYXNlU2Vuc2l0aXZlJyxcbiAgZGlhY3JpdGljU2Vuc2l0aXZlOiAnJGRpYWNyaXRpY1NlbnNpdGl2ZScsXG4gIG5lYXJTcGhlcmU6ICckbmVhclNwaGVyZScsXG4gIG1heERpc3RhbmNlOiAnJG1heERpc3RhbmNlJyxcbiAgbWF4RGlzdGFuY2VJblJhZGlhbnM6ICckbWF4RGlzdGFuY2VJblJhZGlhbnMnLFxuICBtYXhEaXN0YW5jZUluTWlsZXM6ICckbWF4RGlzdGFuY2VJbk1pbGVzJyxcbiAgbWF4RGlzdGFuY2VJbktpbG9tZXRlcnM6ICckbWF4RGlzdGFuY2VJbktpbG9tZXRlcnMnLFxuICB3aXRoaW46ICckd2l0aGluJyxcbiAgYm94OiAnJGJveCcsXG4gIGdlb1dpdGhpbjogJyRnZW9XaXRoaW4nLFxuICBwb2x5Z29uOiAnJHBvbHlnb24nLFxuICBjZW50ZXJTcGhlcmU6ICckY2VudGVyU3BoZXJlJyxcbiAgZ2VvSW50ZXJzZWN0czogJyRnZW9JbnRlcnNlY3RzJyxcbiAgcG9pbnQ6ICckcG9pbnQnLFxufTtcblxuY29uc3QgdHJhbnNmb3JtUXVlcnlDb25zdHJhaW50SW5wdXRUb1BhcnNlID0gKFxuICBjb25zdHJhaW50cyxcbiAgcGFyZW50RmllbGROYW1lLFxuICBjbGFzc05hbWUsXG4gIHBhcmVudENvbnN0cmFpbnRzLFxuICBwYXJzZUNsYXNzZXNcbikgPT4ge1xuICBjb25zdCBmaWVsZHMgPSBwYXJzZUNsYXNzZXMuZmluZChwYXJzZUNsYXNzID0+IHBhcnNlQ2xhc3MuY2xhc3NOYW1lID09PSBjbGFzc05hbWUpLmZpZWxkcztcbiAgaWYgKHBhcmVudEZpZWxkTmFtZSA9PT0gJ2lkJyAmJiBjbGFzc05hbWUpIHtcbiAgICBPYmplY3Qua2V5cyhjb25zdHJhaW50cykuZm9yRWFjaChjb25zdHJhaW50TmFtZSA9PiB7XG4gICAgICBjb25zdCBjb25zdHJhaW50VmFsdWUgPSBjb25zdHJhaW50c1tjb25zdHJhaW50TmFtZV07XG4gICAgICBpZiAodHlwZW9mIGNvbnN0cmFpbnRWYWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc3QgZ2xvYmFsSWRPYmplY3QgPSBmcm9tR2xvYmFsSWQoY29uc3RyYWludFZhbHVlKTtcblxuICAgICAgICBpZiAoZ2xvYmFsSWRPYmplY3QudHlwZSA9PT0gY2xhc3NOYW1lKSB7XG4gICAgICAgICAgY29uc3RyYWludHNbY29uc3RyYWludE5hbWVdID0gZ2xvYmFsSWRPYmplY3QuaWQ7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShjb25zdHJhaW50VmFsdWUpKSB7XG4gICAgICAgIGNvbnN0cmFpbnRzW2NvbnN0cmFpbnROYW1lXSA9IGNvbnN0cmFpbnRWYWx1ZS5tYXAodmFsdWUgPT4ge1xuICAgICAgICAgIGNvbnN0IGdsb2JhbElkT2JqZWN0ID0gZnJvbUdsb2JhbElkKHZhbHVlKTtcblxuICAgICAgICAgIGlmIChnbG9iYWxJZE9iamVjdC50eXBlID09PSBjbGFzc05hbWUpIHtcbiAgICAgICAgICAgIHJldHVybiBnbG9iYWxJZE9iamVjdC5pZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHBhcmVudENvbnN0cmFpbnRzLm9iamVjdElkID0gY29uc3RyYWludHM7XG4gICAgZGVsZXRlIHBhcmVudENvbnN0cmFpbnRzLmlkO1xuICB9XG4gIE9iamVjdC5rZXlzKGNvbnN0cmFpbnRzKS5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgbGV0IGZpZWxkVmFsdWUgPSBjb25zdHJhaW50c1tmaWVsZE5hbWVdO1xuICAgIGlmIChwYXJzZUNvbnN0cmFpbnRNYXBbZmllbGROYW1lXSkge1xuICAgICAgY29uc3RyYWludHNbcGFyc2VDb25zdHJhaW50TWFwW2ZpZWxkTmFtZV1dID0gY29uc3RyYWludHNbZmllbGROYW1lXTtcbiAgICAgIGRlbGV0ZSBjb25zdHJhaW50c1tmaWVsZE5hbWVdO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBJZiB3ZSBoYXZlIGEga2V5LXZhbHVlIHBhaXIsIHdlIG5lZWQgdG8gY2hhbmdlIHRoZSB3YXkgdGhlIGNvbnN0cmFpbnQgaXMgc3RydWN0dXJlZC5cbiAgICAgKlxuICAgICAqIEV4YW1wbGU6XG4gICAgICogICBGcm9tOlxuICAgICAqICAge1xuICAgICAqICAgICBcInNvbWVGaWVsZFwiOiB7XG4gICAgICogICAgICAgXCJsZXNzVGhhblwiOiB7XG4gICAgICogICAgICAgICBcImtleVwiOlwiZm9vLmJhclwiLFxuICAgICAqICAgICAgICAgXCJ2YWx1ZVwiOiAxMDBcbiAgICAgKiAgICAgICB9LFxuICAgICAqICAgICAgIFwiZ3JlYXRlclRoYW5cIjoge1xuICAgICAqICAgICAgICAgXCJrZXlcIjpcImZvby5iYXJcIixcbiAgICAgKiAgICAgICAgIFwidmFsdWVcIjogMTBcbiAgICAgKiAgICAgICB9XG4gICAgICogICAgIH1cbiAgICAgKiAgIH1cbiAgICAgKlxuICAgICAqICAgVG86XG4gICAgICogICB7XG4gICAgICogICAgIFwic29tZUZpZWxkLmZvby5iYXJcIjoge1xuICAgICAqICAgICAgIFwiJGx0XCI6IDEwMCxcbiAgICAgKiAgICAgICBcIiRndFwiOiAxMFxuICAgICAqICAgICAgfVxuICAgICAqICAgfVxuICAgICAqL1xuICAgIGlmIChmaWVsZFZhbHVlLmtleSAmJiBmaWVsZFZhbHVlLnZhbHVlICYmIHBhcmVudENvbnN0cmFpbnRzICYmIHBhcmVudEZpZWxkTmFtZSkge1xuICAgICAgZGVsZXRlIHBhcmVudENvbnN0cmFpbnRzW3BhcmVudEZpZWxkTmFtZV07XG4gICAgICBwYXJlbnRDb25zdHJhaW50c1tgJHtwYXJlbnRGaWVsZE5hbWV9LiR7ZmllbGRWYWx1ZS5rZXl9YF0gPSB7XG4gICAgICAgIC4uLnBhcmVudENvbnN0cmFpbnRzW2Ake3BhcmVudEZpZWxkTmFtZX0uJHtmaWVsZFZhbHVlLmtleX1gXSxcbiAgICAgICAgW3BhcnNlQ29uc3RyYWludE1hcFtmaWVsZE5hbWVdXTogZmllbGRWYWx1ZS52YWx1ZSxcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIGZpZWxkc1twYXJlbnRGaWVsZE5hbWVdICYmXG4gICAgICAoZmllbGRzW3BhcmVudEZpZWxkTmFtZV0udHlwZSA9PT0gJ1BvaW50ZXInIHx8IGZpZWxkc1twYXJlbnRGaWVsZE5hbWVdLnR5cGUgPT09ICdSZWxhdGlvbicpXG4gICAgKSB7XG4gICAgICBjb25zdCB7IHRhcmdldENsYXNzIH0gPSBmaWVsZHNbcGFyZW50RmllbGROYW1lXTtcbiAgICAgIGlmIChmaWVsZE5hbWUgPT09ICdleGlzdHMnKSB7XG4gICAgICAgIGlmIChmaWVsZHNbcGFyZW50RmllbGROYW1lXS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgICAgY29uc3Qgd2hlcmVUYXJnZXQgPSBmaWVsZFZhbHVlID8gJ3doZXJlJyA6ICdub3RXaGVyZSc7XG4gICAgICAgICAgaWYgKGNvbnN0cmFpbnRzW3doZXJlVGFyZ2V0XSkge1xuICAgICAgICAgICAgaWYgKGNvbnN0cmFpbnRzW3doZXJlVGFyZ2V0XS5vYmplY3RJZCkge1xuICAgICAgICAgICAgICBjb25zdHJhaW50c1t3aGVyZVRhcmdldF0ub2JqZWN0SWQgPSB7XG4gICAgICAgICAgICAgICAgLi4uY29uc3RyYWludHNbd2hlcmVUYXJnZXRdLm9iamVjdElkLFxuICAgICAgICAgICAgICAgICRleGlzdHM6IGZpZWxkVmFsdWUsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBjb25zdHJhaW50c1t3aGVyZVRhcmdldF0ub2JqZWN0SWQgPSB7XG4gICAgICAgICAgICAgICAgJGV4aXN0czogZmllbGRWYWx1ZSxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgcGFyc2VXaGVyZVRhcmdldCA9IGZpZWxkVmFsdWUgPyAnJGluUXVlcnknIDogJyRub3RJblF1ZXJ5JztcbiAgICAgICAgICAgIHBhcmVudENvbnN0cmFpbnRzW3BhcmVudEZpZWxkTmFtZV1bcGFyc2VXaGVyZVRhcmdldF0gPSB7XG4gICAgICAgICAgICAgIHdoZXJlOiB7IG9iamVjdElkOiB7ICRleGlzdHM6IHRydWUgfSB9LFxuICAgICAgICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZGVsZXRlIGNvbnN0cmFpbnRzLiRleGlzdHM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcGFyZW50Q29uc3RyYWludHNbcGFyZW50RmllbGROYW1lXS4kZXhpc3RzID0gZmllbGRWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzd2l0Y2ggKGZpZWxkTmFtZSkge1xuICAgICAgICBjYXNlICdoYXZlJzpcbiAgICAgICAgICBwYXJlbnRDb25zdHJhaW50c1twYXJlbnRGaWVsZE5hbWVdLiRpblF1ZXJ5ID0ge1xuICAgICAgICAgICAgd2hlcmU6IGZpZWxkVmFsdWUsXG4gICAgICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICAgIH07XG4gICAgICAgICAgdHJhbnNmb3JtUXVlcnlJbnB1dFRvUGFyc2UoXG4gICAgICAgICAgICBwYXJlbnRDb25zdHJhaW50c1twYXJlbnRGaWVsZE5hbWVdLiRpblF1ZXJ5LndoZXJlLFxuICAgICAgICAgICAgdGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICBwYXJzZUNsYXNzZXNcbiAgICAgICAgICApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdoYXZlTm90JzpcbiAgICAgICAgICBwYXJlbnRDb25zdHJhaW50c1twYXJlbnRGaWVsZE5hbWVdLiRub3RJblF1ZXJ5ID0ge1xuICAgICAgICAgICAgd2hlcmU6IGZpZWxkVmFsdWUsXG4gICAgICAgICAgICBjbGFzc05hbWU6IHRhcmdldENsYXNzLFxuICAgICAgICAgIH07XG4gICAgICAgICAgdHJhbnNmb3JtUXVlcnlJbnB1dFRvUGFyc2UoXG4gICAgICAgICAgICBwYXJlbnRDb25zdHJhaW50c1twYXJlbnRGaWVsZE5hbWVdLiRub3RJblF1ZXJ5LndoZXJlLFxuICAgICAgICAgICAgdGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICBwYXJzZUNsYXNzZXNcbiAgICAgICAgICApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZGVsZXRlIGNvbnN0cmFpbnRzW2ZpZWxkTmFtZV07XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHN3aXRjaCAoZmllbGROYW1lKSB7XG4gICAgICBjYXNlICdwb2ludCc6XG4gICAgICAgIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ29iamVjdCcgJiYgIWZpZWxkVmFsdWUuX190eXBlKSB7XG4gICAgICAgICAgZmllbGRWYWx1ZS5fX3R5cGUgPSAnR2VvUG9pbnQnO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnbmVhclNwaGVyZSc6XG4gICAgICAgIGlmICh0eXBlb2YgZmllbGRWYWx1ZSA9PT0gJ29iamVjdCcgJiYgIWZpZWxkVmFsdWUuX190eXBlKSB7XG4gICAgICAgICAgZmllbGRWYWx1ZS5fX3R5cGUgPSAnR2VvUG9pbnQnO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYm94JzpcbiAgICAgICAgaWYgKHR5cGVvZiBmaWVsZFZhbHVlID09PSAnb2JqZWN0JyAmJiBmaWVsZFZhbHVlLmJvdHRvbUxlZnQgJiYgZmllbGRWYWx1ZS51cHBlclJpZ2h0KSB7XG4gICAgICAgICAgZmllbGRWYWx1ZSA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgX190eXBlOiAnR2VvUG9pbnQnLFxuICAgICAgICAgICAgICAuLi5maWVsZFZhbHVlLmJvdHRvbUxlZnQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBfX3R5cGU6ICdHZW9Qb2ludCcsXG4gICAgICAgICAgICAgIC4uLmZpZWxkVmFsdWUudXBwZXJSaWdodCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXTtcbiAgICAgICAgICBjb25zdHJhaW50c1twYXJzZUNvbnN0cmFpbnRNYXBbZmllbGROYW1lXV0gPSBmaWVsZFZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAncG9seWdvbic6XG4gICAgICAgIGlmIChmaWVsZFZhbHVlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgICAgICBmaWVsZFZhbHVlLmZvckVhY2goZ2VvUG9pbnQgPT4ge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBnZW9Qb2ludCA9PT0gJ29iamVjdCcgJiYgIWdlb1BvaW50Ll9fdHlwZSkge1xuICAgICAgICAgICAgICBnZW9Qb2ludC5fX3R5cGUgPSAnR2VvUG9pbnQnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnY2VudGVyU3BoZXJlJzpcbiAgICAgICAgaWYgKHR5cGVvZiBmaWVsZFZhbHVlID09PSAnb2JqZWN0JyAmJiBmaWVsZFZhbHVlLmNlbnRlciAmJiBmaWVsZFZhbHVlLmRpc3RhbmNlKSB7XG4gICAgICAgICAgZmllbGRWYWx1ZSA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgX190eXBlOiAnR2VvUG9pbnQnLFxuICAgICAgICAgICAgICAuLi5maWVsZFZhbHVlLmNlbnRlcixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBmaWVsZFZhbHVlLmRpc3RhbmNlLFxuICAgICAgICAgIF07XG4gICAgICAgICAgY29uc3RyYWludHNbcGFyc2VDb25zdHJhaW50TWFwW2ZpZWxkTmFtZV1dID0gZmllbGRWYWx1ZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBmaWVsZFZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKGZpZWxkTmFtZSA9PT0gJ3doZXJlJykge1xuICAgICAgICB0cmFuc2Zvcm1RdWVyeUlucHV0VG9QYXJzZShmaWVsZFZhbHVlLCBjbGFzc05hbWUsIHBhcnNlQ2xhc3Nlcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0cmFuc2Zvcm1RdWVyeUNvbnN0cmFpbnRJbnB1dFRvUGFyc2UoXG4gICAgICAgICAgZmllbGRWYWx1ZSxcbiAgICAgICAgICBmaWVsZE5hbWUsXG4gICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgIGNvbnN0cmFpbnRzLFxuICAgICAgICAgIHBhcnNlQ2xhc3Nlc1xuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1RdWVyeUlucHV0VG9QYXJzZSA9IChjb25zdHJhaW50cywgY2xhc3NOYW1lLCBwYXJzZUNsYXNzZXMpID0+IHtcbiAgaWYgKCFjb25zdHJhaW50cyB8fCB0eXBlb2YgY29uc3RyYWludHMgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgT2JqZWN0LmtleXMoY29uc3RyYWludHMpLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICBjb25zdCBmaWVsZFZhbHVlID0gY29uc3RyYWludHNbZmllbGROYW1lXTtcblxuICAgIGlmIChwYXJzZVF1ZXJ5TWFwW2ZpZWxkTmFtZV0pIHtcbiAgICAgIGRlbGV0ZSBjb25zdHJhaW50c1tmaWVsZE5hbWVdO1xuICAgICAgZmllbGROYW1lID0gcGFyc2VRdWVyeU1hcFtmaWVsZE5hbWVdO1xuICAgICAgY29uc3RyYWludHNbZmllbGROYW1lXSA9IGZpZWxkVmFsdWU7XG4gICAgICBmaWVsZFZhbHVlLmZvckVhY2goZmllbGRWYWx1ZUl0ZW0gPT4ge1xuICAgICAgICB0cmFuc2Zvcm1RdWVyeUlucHV0VG9QYXJzZShmaWVsZFZhbHVlSXRlbSwgY2xhc3NOYW1lLCBwYXJzZUNsYXNzZXMpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIHtcbiAgICAgIHRyYW5zZm9ybVF1ZXJ5Q29uc3RyYWludElucHV0VG9QYXJzZShcbiAgICAgICAgZmllbGRWYWx1ZSxcbiAgICAgICAgZmllbGROYW1lLFxuICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgIGNvbnN0cmFpbnRzLFxuICAgICAgICBwYXJzZUNsYXNzZXNcbiAgICAgICk7XG4gICAgfVxuICB9KTtcbn07XG5cbmV4cG9ydCB7IHRyYW5zZm9ybVF1ZXJ5Q29uc3RyYWludElucHV0VG9QYXJzZSwgdHJhbnNmb3JtUXVlcnlJbnB1dFRvUGFyc2UgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/GraphQL/transformers/schemaFields.js b/lib/GraphQL/transformers/schemaFields.js deleted file mode 100644 index 1ca178f576..0000000000 --- a/lib/GraphQL/transformers/schemaFields.js +++ /dev/null @@ -1,128 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.transformToGraphQL = exports.transformToParse = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const transformToParse = (graphQLSchemaFields, existingFields) => { - if (!graphQLSchemaFields) { - return {}; - } - - let parseSchemaFields = {}; - - const reducerGenerator = type => (parseSchemaFields, field) => { - if (type === 'Remove') { - if (existingFields[field.name]) { - return _objectSpread(_objectSpread({}, parseSchemaFields), {}, { - [field.name]: { - __op: 'Delete' - } - }); - } else { - return parseSchemaFields; - } - } - - if (graphQLSchemaFields.remove && graphQLSchemaFields.remove.find(removeField => removeField.name === field.name)) { - return parseSchemaFields; - } - - if (parseSchemaFields[field.name] || existingFields && existingFields[field.name]) { - throw new _node.default.Error(_node.default.Error.INVALID_KEY_NAME, `Duplicated field name: ${field.name}`); - } - - if (type === 'Relation' || type === 'Pointer') { - return _objectSpread(_objectSpread({}, parseSchemaFields), {}, { - [field.name]: { - type, - targetClass: field.targetClassName - } - }); - } - - return _objectSpread(_objectSpread({}, parseSchemaFields), {}, { - [field.name]: { - type - } - }); - }; - - if (graphQLSchemaFields.addStrings) { - parseSchemaFields = graphQLSchemaFields.addStrings.reduce(reducerGenerator('String'), parseSchemaFields); - } - - if (graphQLSchemaFields.addNumbers) { - parseSchemaFields = graphQLSchemaFields.addNumbers.reduce(reducerGenerator('Number'), parseSchemaFields); - } - - if (graphQLSchemaFields.addBooleans) { - parseSchemaFields = graphQLSchemaFields.addBooleans.reduce(reducerGenerator('Boolean'), parseSchemaFields); - } - - if (graphQLSchemaFields.addArrays) { - parseSchemaFields = graphQLSchemaFields.addArrays.reduce(reducerGenerator('Array'), parseSchemaFields); - } - - if (graphQLSchemaFields.addObjects) { - parseSchemaFields = graphQLSchemaFields.addObjects.reduce(reducerGenerator('Object'), parseSchemaFields); - } - - if (graphQLSchemaFields.addDates) { - parseSchemaFields = graphQLSchemaFields.addDates.reduce(reducerGenerator('Date'), parseSchemaFields); - } - - if (graphQLSchemaFields.addFiles) { - parseSchemaFields = graphQLSchemaFields.addFiles.reduce(reducerGenerator('File'), parseSchemaFields); - } - - if (graphQLSchemaFields.addGeoPoint) { - parseSchemaFields = [graphQLSchemaFields.addGeoPoint].reduce(reducerGenerator('GeoPoint'), parseSchemaFields); - } - - if (graphQLSchemaFields.addPolygons) { - parseSchemaFields = graphQLSchemaFields.addPolygons.reduce(reducerGenerator('Polygon'), parseSchemaFields); - } - - if (graphQLSchemaFields.addBytes) { - parseSchemaFields = graphQLSchemaFields.addBytes.reduce(reducerGenerator('Bytes'), parseSchemaFields); - } - - if (graphQLSchemaFields.addPointers) { - parseSchemaFields = graphQLSchemaFields.addPointers.reduce(reducerGenerator('Pointer'), parseSchemaFields); - } - - if (graphQLSchemaFields.addRelations) { - parseSchemaFields = graphQLSchemaFields.addRelations.reduce(reducerGenerator('Relation'), parseSchemaFields); - } - - if (existingFields && graphQLSchemaFields.remove) { - parseSchemaFields = graphQLSchemaFields.remove.reduce(reducerGenerator('Remove'), parseSchemaFields); - } - - return parseSchemaFields; -}; - -exports.transformToParse = transformToParse; - -const transformToGraphQL = parseSchemaFields => { - return Object.keys(parseSchemaFields).map(name => ({ - name, - type: parseSchemaFields[name].type, - targetClassName: parseSchemaFields[name].targetClass - })); -}; - -exports.transformToGraphQL = transformToGraphQL; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9HcmFwaFFML3RyYW5zZm9ybWVycy9zY2hlbWFGaWVsZHMuanMiXSwibmFtZXMiOlsidHJhbnNmb3JtVG9QYXJzZSIsImdyYXBoUUxTY2hlbWFGaWVsZHMiLCJleGlzdGluZ0ZpZWxkcyIsInBhcnNlU2NoZW1hRmllbGRzIiwicmVkdWNlckdlbmVyYXRvciIsInR5cGUiLCJmaWVsZCIsIm5hbWUiLCJfX29wIiwicmVtb3ZlIiwiZmluZCIsInJlbW92ZUZpZWxkIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfS0VZX05BTUUiLCJ0YXJnZXRDbGFzcyIsInRhcmdldENsYXNzTmFtZSIsImFkZFN0cmluZ3MiLCJyZWR1Y2UiLCJhZGROdW1iZXJzIiwiYWRkQm9vbGVhbnMiLCJhZGRBcnJheXMiLCJhZGRPYmplY3RzIiwiYWRkRGF0ZXMiLCJhZGRGaWxlcyIsImFkZEdlb1BvaW50IiwiYWRkUG9seWdvbnMiLCJhZGRCeXRlcyIsImFkZFBvaW50ZXJzIiwiYWRkUmVsYXRpb25zIiwidHJhbnNmb3JtVG9HcmFwaFFMIiwiT2JqZWN0Iiwia2V5cyIsIm1hcCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7Ozs7Ozs7O0FBRUEsTUFBTUEsZ0JBQWdCLEdBQUcsQ0FBQ0MsbUJBQUQsRUFBc0JDLGNBQXRCLEtBQXlDO0FBQ2hFLE1BQUksQ0FBQ0QsbUJBQUwsRUFBMEI7QUFDeEIsV0FBTyxFQUFQO0FBQ0Q7O0FBRUQsTUFBSUUsaUJBQWlCLEdBQUcsRUFBeEI7O0FBRUEsUUFBTUMsZ0JBQWdCLEdBQUdDLElBQUksSUFBSSxDQUFDRixpQkFBRCxFQUFvQkcsS0FBcEIsS0FBOEI7QUFDN0QsUUFBSUQsSUFBSSxLQUFLLFFBQWIsRUFBdUI7QUFDckIsVUFBSUgsY0FBYyxDQUFDSSxLQUFLLENBQUNDLElBQVAsQ0FBbEIsRUFBZ0M7QUFDOUIsK0NBQ0tKLGlCQURMO0FBRUUsV0FBQ0csS0FBSyxDQUFDQyxJQUFQLEdBQWM7QUFDWkMsWUFBQUEsSUFB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QTlIRDs7OztBQWdJQSxNQUFNMkIsa0JBQWtCLEdBQUczQixpQkFBaUIsSUFBSTtBQUM5QyxTQUFPNEIsTUFBTSxDQUFDQyxJQUFQLENBQVk3QixpQkFBWixFQUErQjhCLEdBQS9CLENBQW1DMUIsSUFBSSxLQUFLO0FBQ2pEQSxJQUFBQSxJQURpRDtBQUVqREYsSUFBQUEsSUFBSSxFQUFFRixpQkFBaUIsQ0FBQ0ksSUFBRCxDQUFqQixDQUF3QkYsSUFGbUI7QUFHakRXLElBQUFBLGVBQWUsRUFBRWIsaUJBQWlCLENBQUNJLElBQUQsQ0FBakIsQ0FBd0JRO0FBSFEsR0FBTCxDQUF2QyxDQUFQO0FBS0QsQ0FORCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcblxuY29uc3QgdHJhbnNmb3JtVG9QYXJzZSA9IChncmFwaFFMU2NoZW1hRmllbGRzLCBleGlzdGluZ0ZpZWxkcykgPT4ge1xuICBpZiAoIWdyYXBoUUxTY2hlbWFGaWVsZHMpIHtcbiAgICByZXR1cm4ge307XG4gIH1cblxuICBsZXQgcGFyc2VTY2hlbWFGaWVsZHMgPSB7fTtcblxuICBjb25zdCByZWR1Y2VyR2VuZXJhdG9yID0gdHlwZSA9PiAocGFyc2VTY2hlbWFGaWVsZHMsIGZpZWxkKSA9PiB7XG4gICAgaWYgKHR5cGUgPT09ICdSZW1vdmUnKSB7XG4gICAgICBpZiAoZXhpc3RpbmdGaWVsZHNbZmllbGQubmFtZV0pIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5wYXJzZVNjaGVtYUZpZWxkcyxcbiAgICAgICAgICBbZmllbGQubmFtZV06IHtcbiAgICAgICAgICAgIF9fb3A6ICdEZWxldGUnLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gcGFyc2VTY2hlbWFGaWVsZHM7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChcbiAgICAgIGdyYXBoUUxTY2hlbWFGaWVsZHMucmVtb3ZlICYmXG4gICAgICBncmFwaFFMU2NoZW1hRmllbGRzLnJlbW92ZS5maW5kKHJlbW92ZUZpZWxkID0+IHJlbW92ZUZpZWxkLm5hbWUgPT09IGZpZWxkLm5hbWUpXG4gICAgKSB7XG4gICAgICByZXR1cm4gcGFyc2VTY2hlbWFGaWVsZHM7XG4gICAgfVxuICAgIGlmIChwYXJzZVNjaGVtYUZpZWxkc1tmaWVsZC5uYW1lXSB8fCAoZXhpc3RpbmdGaWVsZHMgJiYgZXhpc3RpbmdGaWVsZHNbZmllbGQubmFtZV0pKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSwgYER1cGxpY2F0ZWQgZmllbGQgbmFtZTogJHtmaWVsZC5uYW1lfWApO1xuICAgIH1cbiAgICBpZiAodHlwZSA9PT0gJ1JlbGF0aW9uJyB8fCB0eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLnBhcnNlU2NoZW1hRmllbGRzLFxuICAgICAgICBbZmllbGQubmFtZV06IHtcbiAgICAgICAgICB0eXBlLFxuICAgICAgICAgIHRhcmdldENsYXNzOiBmaWVsZC50YXJnZXRDbGFzc05hbWUsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgLi4ucGFyc2VTY2hlbWFGaWVsZHMsXG4gICAgICBbZmllbGQubmFtZV06IHtcbiAgICAgICAgdHlwZSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfTtcblxuICBpZiAoZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRTdHJpbmdzKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLmFkZFN0cmluZ3MucmVkdWNlKFxuICAgICAgcmVkdWNlckdlbmVyYXRvcignU3RyaW5nJyksXG4gICAgICBwYXJzZVNjaGVtYUZpZWxkc1xuICAgICk7XG4gIH1cbiAgaWYgKGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkTnVtYmVycykge1xuICAgIHBhcnNlU2NoZW1hRmllbGRzID0gZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGROdW1iZXJzLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ051bWJlcicpLFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNcbiAgICApO1xuICB9XG4gIGlmIChncmFwaFFMU2NoZW1hRmllbGRzLmFkZEJvb2xlYW5zKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLmFkZEJvb2xlYW5zLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ0Jvb2xlYW4nKSxcbiAgICAgIHBhcnNlU2NoZW1hRmllbGRzXG4gICAgKTtcbiAgfVxuICBpZiAoZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRBcnJheXMpIHtcbiAgICBwYXJzZVNjaGVtYUZpZWxkcyA9IGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkQXJyYXlzLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ0FycmF5JyksXG4gICAgICBwYXJzZVNjaGVtYUZpZWxkc1xuICAgICk7XG4gIH1cbiAgaWYgKGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkT2JqZWN0cykge1xuICAgIHBhcnNlU2NoZW1hRmllbGRzID0gZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRPYmplY3RzLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ09iamVjdCcpLFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNcbiAgICApO1xuICB9XG4gIGlmIChncmFwaFFMU2NoZW1hRmllbGRzLmFkZERhdGVzKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLmFkZERhdGVzLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ0RhdGUnKSxcbiAgICAgIHBhcnNlU2NoZW1hRmllbGRzXG4gICAgKTtcbiAgfVxuICBpZiAoZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRGaWxlcykge1xuICAgIHBhcnNlU2NoZW1hRmllbGRzID0gZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRGaWxlcy5yZWR1Y2UoXG4gICAgICByZWR1Y2VyR2VuZXJhdG9yKCdGaWxlJyksXG4gICAgICBwYXJzZVNjaGVtYUZpZWxkc1xuICAgICk7XG4gIH1cbiAgaWYgKGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkR2VvUG9pbnQpIHtcbiAgICBwYXJzZVNjaGVtYUZpZWxkcyA9IFtncmFwaFFMU2NoZW1hRmllbGRzLmFkZEdlb1BvaW50XS5yZWR1Y2UoXG4gICAgICByZWR1Y2VyR2VuZXJhdG9yKCdHZW9Qb2ludCcpLFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNcbiAgICApO1xuICB9XG4gIGlmIChncmFwaFFMU2NoZW1hRmllbGRzLmFkZFBvbHlnb25zKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLmFkZFBvbHlnb25zLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ1BvbHlnb24nKSxcbiAgICAgIHBhcnNlU2NoZW1hRmllbGRzXG4gICAgKTtcbiAgfVxuICBpZiAoZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRCeXRlcykge1xuICAgIHBhcnNlU2NoZW1hRmllbGRzID0gZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRCeXRlcy5yZWR1Y2UoXG4gICAgICByZWR1Y2VyR2VuZXJhdG9yKCdCeXRlcycpLFxuICAgICAgcGFyc2VTY2hlbWFGaWVsZHNcbiAgICApO1xuICB9XG4gIGlmIChncmFwaFFMU2NoZW1hRmllbGRzLmFkZFBvaW50ZXJzKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLmFkZFBvaW50ZXJzLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ1BvaW50ZXInKSxcbiAgICAgIHBhcnNlU2NoZW1hRmllbGRzXG4gICAgKTtcbiAgfVxuICBpZiAoZ3JhcGhRTFNjaGVtYUZpZWxkcy5hZGRSZWxhdGlvbnMpIHtcbiAgICBwYXJzZVNjaGVtYUZpZWxkcyA9IGdyYXBoUUxTY2hlbWFGaWVsZHMuYWRkUmVsYXRpb25zLnJlZHVjZShcbiAgICAgIHJlZHVjZXJHZW5lcmF0b3IoJ1JlbGF0aW9uJyksXG4gICAgICBwYXJzZVNjaGVtYUZpZWxkc1xuICAgICk7XG4gIH1cbiAgaWYgKGV4aXN0aW5nRmllbGRzICYmIGdyYXBoUUxTY2hlbWFGaWVsZHMucmVtb3ZlKSB7XG4gICAgcGFyc2VTY2hlbWFGaWVsZHMgPSBncmFwaFFMU2NoZW1hRmllbGRzLnJlbW92ZS5yZWR1Y2UoXG4gICAgICByZWR1Y2VyR2VuZXJhdG9yKCdSZW1vdmUnKSxcbiAgICAgIHBhcnNlU2NoZW1hRmllbGRzXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiBwYXJzZVNjaGVtYUZpZWxkcztcbn07XG5cbmNvbnN0IHRyYW5zZm9ybVRvR3JhcGhRTCA9IHBhcnNlU2NoZW1hRmllbGRzID0+IHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKHBhcnNlU2NoZW1hRmllbGRzKS5tYXAobmFtZSA9PiAoe1xuICAgIG5hbWUsXG4gICAgdHlwZTogcGFyc2VTY2hlbWFGaWVsZHNbbmFtZV0udHlwZSxcbiAgICB0YXJnZXRDbGFzc05hbWU6IHBhcnNlU2NoZW1hRmllbGRzW25hbWVdLnRhcmdldENsYXNzLFxuICB9KSk7XG59O1xuXG5leHBvcnQgeyB0cmFuc2Zvcm1Ub1BhcnNlLCB0cmFuc2Zvcm1Ub0dyYXBoUUwgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/Client.js b/lib/LiveQuery/Client.js deleted file mode 100644 index 205e284d05..0000000000 --- a/lib/LiveQuery/Client.js +++ /dev/null @@ -1,114 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.Client = void 0; - -var _logger = _interopRequireDefault(require("../logger")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const dafaultFields = ['className', 'objectId', 'updatedAt', 'createdAt', 'ACL']; - -class Client { - constructor(id, parseWebSocket, hasMasterKey = false, sessionToken, installationId) { - this.id = id; - this.parseWebSocket = parseWebSocket; - this.hasMasterKey = hasMasterKey; - this.sessionToken = sessionToken; - this.installationId = installationId; - this.roles = []; - this.subscriptionInfos = new Map(); - this.pushConnect = this._pushEvent('connected'); - this.pushSubscribe = this._pushEvent('subscribed'); - this.pushUnsubscribe = this._pushEvent('unsubscribed'); - this.pushCreate = this._pushEvent('create'); - this.pushEnter = this._pushEvent('enter'); - this.pushUpdate = this._pushEvent('update'); - this.pushDelete = this._pushEvent('delete'); - this.pushLeave = this._pushEvent('leave'); - } - - static pushResponse(parseWebSocket, message) { - _logger.default.verbose('Push Response : %j', message); - - parseWebSocket.send(message); - } - - static pushError(parseWebSocket, code, error, reconnect = true, requestId = null) { - Client.pushResponse(parseWebSocket, JSON.stringify({ - op: 'error', - error, - code, - reconnect, - requestId - })); - } - - addSubscriptionInfo(requestId, subscriptionInfo) { - this.subscriptionInfos.set(requestId, subscriptionInfo); - } - - getSubscriptionInfo(requestId) { - return this.subscriptionInfos.get(requestId); - } - - deleteSubscriptionInfo(requestId) { - return this.subscriptionInfos.delete(requestId); - } - - _pushEvent(type) { - return function (subscriptionId, parseObjectJSON, parseOriginalObjectJSON) { - const response = { - op: type, - clientId: this.id, - installationId: this.installationId - }; - - if (typeof subscriptionId !== 'undefined') { - response['requestId'] = subscriptionId; - } - - if (typeof parseObjectJSON !== 'undefined') { - let fields; - - if (this.subscriptionInfos.has(subscriptionId)) { - fields = this.subscriptionInfos.get(subscriptionId).fields; - } - - response['object'] = this._toJSONWithFields(parseObjectJSON, fields); - - if (parseOriginalObjectJSON) { - response['original'] = this._toJSONWithFields(parseOriginalObjectJSON, fields); - } - } - - Client.pushResponse(this.parseWebSocket, JSON.stringify(response)); - }; - } - - _toJSONWithFields(parseObjectJSON, fields) { - if (!fields) { - return parseObjectJSON; - } - - const limitedParseObject = {}; - - for (const field of dafaultFields) { - limitedParseObject[field] = parseObjectJSON[field]; - } - - for (const field of fields) { - if (field in parseObjectJSON) { - limitedParseObject[field] = parseObjectJSON[field]; - } - } - - return limitedParseObject; - } - -} - -exports.Client = Client; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvQ2xpZW50LmpzIl0sIm5hbWVzIjpbImRhZmF1bHRGaWVsZHMiLCJDbGllbnQiLCJjb25zdHJ1Y3RvciIsImlkIiwicGFyc2VXZWJTb2NrZXQiLCJoYXNNYXN0ZXJLZXkiLCJzZXNzaW9uVG9rZW4iLCJpbnN0YWxsYXRpb25JZCIsInJvbGVzIiwic3Vic2NyaXB0aW9uSW5mb3MiLCJNYXAiLCJwdXNoQ29ubmVjdCIsIl9wdXNoRXZlbnQiLCJwdXNoU3Vic2NyaWJlIiwicHVzaFVuc3Vic2NyaWJlIiwicHVzaENyZWF0ZSIsInB1c2hFbnRlciIsInB1c2hVcGRhdGUiLCJwdXNoRGVsZXRlIiwicHVzaExlYXZlIiwicHVzaFJlc3BvbnNlIiwibWVzc2FnZSIsImxvZ2dlciIsInZlcmJvc2UiLCJzZW5kIiwicHVzaEVycm9yIiwiY29kZSIsImVycm9yIiwicmVjb25uZWN0IiwicmVxdWVzdElkIiwiSlNPTiIsInN0cmluZ2lmeSIsIm9wIiwiYWRkU3Vic2NyaXB0aW9uSW5mbyIsInN1YnNjcmlwdGlvbkluZm8iLCJzZXQiLCJnZXRTdWJzY3JpcHRpb25JbmZvIiwiZ2V0IiwiZGVsZXRlU3Vic2NyaXB0aW9uSW5mbyIsImRlbGV0ZSIsInR5cGUiLCJzdWJzY3JpcHRpb25JZCIsInBhcnNlT2JqZWN0SlNPTiIsInBhcnNlT3JpZ2luYWxPYmplY3RKU09OIiwicmVzcG9uc2UiLCJjbGllbnRJZCIsImZpZWxkcyIsImhhcyIsIl90b0pTT05XaXRoRmllbGRzIiwibGltaXRlZFBhcnNlT2JqZWN0IiwiZmllbGQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7OztBQUtBLE1BQU1BLGFBQWEsR0FBRyxDQUFDLFdBQUQsRUFBYyxVQUFkLEVBQTBCLFdBQTFCLEVBQXVDLFdBQXZDLEVBQW9ELEtBQXBELENBQXRCOztBQUVBLE1BQU1DLE1BQU4sQ0FBYTtBQWtCWEMsRUFBQUEsV0FBVyxDQUNUQyxFQURTLEVBRVRDLGNBRlMsRUFHVEMs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cnQgdHlwZSB7IEZsYXR0ZW5lZE9iamVjdERhdGEgfSBmcm9tICcuL1N1YnNjcmlwdGlvbic7XG5leHBvcnQgdHlwZSBNZXNzYWdlID0geyBbYXR0cjogc3RyaW5nXTogYW55IH07XG5cbmNvbnN0IGRhZmF1bHRGaWVsZHMgPSBbJ2NsYXNzTmFtZScsICdvYmplY3RJZCcsICd1cGRhdGVkQXQnLCAnY3JlYXRlZEF0JywgJ0FDTCddO1xuXG5jbGFzcyBDbGllbnQge1xuICBpZDogbnVtYmVyO1xuICBwYXJzZVdlYlNvY2tldDogYW55O1xuICBoYXNNYXN0ZXJLZXk6IGJvb2xlYW47XG4gIHNlc3Npb25Ub2tlbjogc3RyaW5nO1xuICBpbnN0YWxsYXRpb25JZDogc3RyaW5nO1xuICB1c2VySWQ6IHN0cmluZztcbiAgcm9sZXM6IEFycmF5PHN0cmluZz47XG4gIHN1YnNjcmlwdGlvbkluZm9zOiBPYmplY3Q7XG4gIHB1c2hDb25uZWN0OiBGdW5jdGlvbjtcbiAgcHVzaFN1YnNjcmliZTogRnVuY3Rpb247XG4gIHB1c2hVbnN1YnNjcmliZTogRnVuY3Rpb247XG4gIHB1c2hDcmVhdGU6IEZ1bmN0aW9uO1xuICBwdXNoRW50ZXI6IEZ1bmN0aW9uO1xuICBwdXNoVXBkYXRlOiBGdW5jdGlvbjtcbiAgcHVzaERlbGV0ZTogRnVuY3Rpb247XG4gIHB1c2hMZWF2ZTogRnVuY3Rpb247XG5cbiAgY29uc3RydWN0b3IoXG4gICAgaWQ6IG51bWJlcixcbiAgICBwYXJzZVdlYlNvY2tldDogYW55LFxuICAgIGhhc01hc3RlcktleTogYm9vbGVhbiA9IGZhbHNlLFxuICAgIHNlc3Npb25Ub2tlbjogc3RyaW5nLFxuICAgIGluc3RhbGxhdGlvbklkOiBzdHJpbmdcbiAgKSB7XG4gICAgdGhpcy5pZCA9IGlkO1xuICAgIHRoaXMucGFyc2VXZWJTb2NrZXQgPSBwYXJzZVdlYlNvY2tldDtcbiAgICB0aGlzLmhhc01hc3RlcktleSA9IGhhc01hc3RlcktleTtcbiAgICB0aGlzLnNlc3Npb25Ub2tlbiA9IHNlc3Npb25Ub2tlbjtcbiAgICB0aGlzLmluc3RhbGxhdGlvbklkID0gaW5zdGFsbGF0aW9uSWQ7XG4gICAgdGhpcy5yb2xlcyA9IFtdO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uSW5mb3MgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5wdXNoQ29ubmVjdCA9IHRoaXMuX3B1c2hFdmVudCgnY29ubmVjdGVkJyk7XG4gICAgdGhpcy5wdXNoU3Vic2NyaWJlID0gdGhpcy5fcHVzaEV2ZW50KCdzdWJzY3JpYmVkJyk7XG4gICAgdGhpcy5wdXNoVW5zdWJzY3JpYmUgPSB0aGlzLl9wdXNoRXZlbnQoJ3Vuc3Vic2NyaWJlZCcpO1xuICAgIHRoaXMucHVzaENyZWF0ZSA9IHRoaXMuX3B1c2hFdmVudCgnY3JlYXRlJyk7XG4gICAgdGhpcy5wdXNoRW50ZXIgPSB0aGlzLl9wdXNoRXZlbnQoJ2VudGVyJyk7XG4gICAgdGhpcy5wdXNoVXBkYXRlID0gdGhpcy5fcHVzaEV2ZW50KCd1cGRhdGUnKTtcbiAgICB0aGlzLnB1c2hEZWxldGUgPSB0aGlzLl9wdXNoRXZlbnQoJ2RlbGV0ZScpO1xuICAgIHRoaXMucHVzaExlYXZlID0gdGhpcy5fcHVzaEV2ZW50KCdsZWF2ZScpO1xuICB9XG5cbiAgc3RhdGljIHB1c2hSZXNwb25zZShwYXJzZVdlYlNvY2tldDogYW55LCBtZXNzYWdlOiBNZXNzYWdlKTogdm9pZCB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoJ1B1c2ggUmVzcG9uc2UgOiAlaicsIG1lc3NhZ2UpO1xuICAgIHBhcnNlV2ViU29ja2V0LnNlbmQobWVzc2FnZSk7XG4gIH1cblxuICBzdGF0aWMgcHVzaEVycm9yKFxuICAgIHBhcnNlV2ViU29ja2V0OiBhbnksXG4gICAgY29kZTogbnVtYmVyLFxuICAgIGVycm9yOiBzdHJpbmcsXG4gICAgcmVjb25uZWN0OiBib29sZWFuID0gdHJ1ZSxcbiAgICByZXF1ZXN0SWQ6IG51bWJlciB8IHZvaWQgPSBudWxsXG4gICk6IHZvaWQge1xuICAgIENsaWVudC5wdXNoUmVzcG9uc2UoXG4gICAgICBwYXJzZVdlYlNvY2tldCxcbiAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgb3A6ICdlcnJvcicsXG4gICAgICAgIGVycm9yLFxuICAgICAgICBjb2RlLFxuICAgICAgICByZWNvbm5lY3QsXG4gICAgICAgIHJlcXVlc3RJZCxcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuXG4gIGFkZFN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdElkOiBudW1iZXIsIHN1YnNjcmlwdGlvbkluZm86IGFueSk6IHZvaWQge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uSW5mb3Muc2V0KHJlcXVlc3RJZCwgc3Vic2NyaXB0aW9uSW5mbyk7XG4gIH1cblxuICBnZXRTdWJzY3JpcHRpb25JbmZvKHJlcXVlc3RJZDogbnVtYmVyKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5zdWJzY3JpcHRpb25JbmZvcy5nZXQocmVxdWVzdElkKTtcbiAgfVxuXG4gIGRlbGV0ZVN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdElkOiBudW1iZXIpOiB2b2lkIHtcbiAgICByZXR1cm4gdGhpcy5zdWJzY3JpcHRpb25JbmZvcy5kZWxldGUocmVxdWVzdElkKTtcbiAgfVxuXG4gIF9wdXNoRXZlbnQodHlwZTogc3RyaW5nKTogRnVuY3Rpb24ge1xuICAgIHJldHVybiBmdW5jdGlvbiAoXG4gICAgICBzdWJzY3JpcHRpb25JZDogbnVtYmVyLFxuICAgICAgcGFyc2VPYmplY3RKU09OOiBhbnksXG4gICAgICBwYXJzZU9yaWdpbmFsT2JqZWN0SlNPTjogYW55XG4gICAgKTogdm9pZCB7XG4gICAgICBjb25zdCByZXNwb25zZTogTWVzc2FnZSA9IHtcbiAgICAgICAgb3A6IHR5cGUsXG4gICAgICAgIGNsaWVudElkOiB0aGlzLmlkLFxuICAgICAgICBpbnN0YWxsYXRpb25JZDogdGhpcy5pbnN0YWxsYXRpb25JZCxcbiAgICAgIH07XG4gICAgICBpZiAodHlwZW9mIHN1YnNjcmlwdGlvbklkICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXNwb25zZVsncmVxdWVzdElkJ10gPSBzdWJzY3JpcHRpb25JZDtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgcGFyc2VPYmplY3RKU09OICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBsZXQgZmllbGRzO1xuICAgICAgICBpZiAodGhpcy5zdWJzY3JpcHRpb25JbmZvcy5oYXMoc3Vic2NyaXB0aW9uSWQpKSB7XG4gICAgICAgICAgZmllbGRzID0gdGhpcy5zdWJzY3JpcHRpb25JbmZvcy5nZXQoc3Vic2NyaXB0aW9uSWQpLmZpZWxkcztcbiAgICAgICAgfVxuICAgICAgICByZXNwb25zZVsnb2JqZWN0J10gPSB0aGlzLl90b0pTT05XaXRoRmllbGRzKHBhcnNlT2JqZWN0SlNPTiwgZmllbGRzKTtcbiAgICAgICAgaWYgKHBhcnNlT3JpZ2luYWxPYmplY3RKU09OKSB7XG4gICAgICAgICAgcmVzcG9uc2VbJ29yaWdpbmFsJ10gPSB0aGlzLl90b0pTT05XaXRoRmllbGRzKHBhcnNlT3JpZ2luYWxPYmplY3RKU09OLCBmaWVsZHMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBDbGllbnQucHVzaFJlc3BvbnNlKHRoaXMucGFyc2VXZWJTb2NrZXQsIEpTT04uc3RyaW5naWZ5KHJlc3BvbnNlKSk7XG4gICAgfTtcbiAgfVxuXG4gIF90b0pTT05XaXRoRmllbGRzKHBhcnNlT2JqZWN0SlNPTjogYW55LCBmaWVsZHM6IGFueSk6IEZsYXR0ZW5lZE9iamVjdERhdGEge1xuICAgIGlmICghZmllbGRzKSB7XG4gICAgICByZXR1cm4gcGFyc2VPYmplY3RKU09OO1xuICAgIH1cbiAgICBjb25zdCBsaW1pdGVkUGFyc2VPYmplY3QgPSB7fTtcbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIGRhZmF1bHRGaWVsZHMpIHtcbiAgICAgIGxpbWl0ZWRQYXJzZU9iamVjdFtmaWVsZF0gPSBwYXJzZU9iamVjdEpTT05bZmllbGRdO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIGZpZWxkcykge1xuICAgICAgaWYgKGZpZWxkIGluIHBhcnNlT2JqZWN0SlNPTikge1xuICAgICAgICBsaW1pdGVkUGFyc2VPYmplY3RbZmllbGRdID0gcGFyc2VPYmplY3RKU09OW2ZpZWxkXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGxpbWl0ZWRQYXJzZU9iamVjdDtcbiAgfVxufVxuXG5leHBvcnQgeyBDbGllbnQgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/Id.js b/lib/LiveQuery/Id.js deleted file mode 100644 index 379e29b88d..0000000000 --- a/lib/LiveQuery/Id.js +++ /dev/null @@ -1,26 +0,0 @@ -"use strict"; - -class Id { - constructor(className, objectId) { - this.className = className; - this.objectId = objectId; - } - - toString() { - return this.className + ':' + this.objectId; - } - - static fromString(str) { - var split = str.split(':'); - - if (split.length !== 2) { - throw new TypeError('Cannot create Id object from this string'); - } - - return new Id(split[0], split[1]); - } - -} - -module.exports = Id; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvSWQuanMiXSwibmFtZXMiOlsiSWQiLCJjb25zdHJ1Y3RvciIsImNsYXNzTmFtZSIsIm9iamVjdElkIiwidG9TdHJpbmciLCJmcm9tU3RyaW5nIiwic3RyIiwic3BsaXQiLCJsZW5ndGgiLCJUeXBlRXJyb3IiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLE1BQU1BLEVBQU4sQ0FBUztBQUlQQyxFQUFBQSxXQUFXLENBQUNDLFNBQUQsRUFBb0JDLFFBQXBCLEVBQXNDO0FBQy9DLFNBQUtELFNBQUwsR0FBaUJBLFNBQWpCO0FBQ0EsU0FBS0MsUUFBTCxHQUFnQkEsUUFBaEI7QUFDRDs7QUFDREMsRUFBQUEsUUFBUSxHQUFXO0FBQ2pCLFdBQU8sS0FBS0YsU0FBTCxHQUFpQixHQUFqQixHQUF1QixLQUFLQyxRQUFuQztBQUNEOztBQUVELFNBQU9FLFVBQVAsQ0FBa0JDLEdBQWxCLEVBQStCO0FBQzdCLFFBQUlDLEtBQUssR0FBR0QsR0FBRyxDQUFDQyxLQUFKLENBQVUsR0FBVixDQUFaOztBQUNBLFFBQUlBLEtBQUssQ0FBQ0MsTUFBTixLQUFpQixDQUFyQixFQUF3QjtBQUN0QixZQUFNLElBQUlDLFNBQUosQ0FBYywwQ0FBZCxDQUFOO0FBQ0Q7O0FBQ0QsV0FBTyxJQUFJVCxFQUFKLENBQU9PLEtBQUssQ0FBQyxDQUFELENBQVosRUFBaUJBLEtBQUssQ0FBQyxDQUFELENBQXRCLENBQVA7QUFDRDs7QUFsQk07O0FBcUJURyxNQUFNLENBQUNDLE9BQVAsR0FBaUJYLEVBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiY2xhc3MgSWQge1xuICBjbGFzc05hbWU6IHN0cmluZztcbiAgb2JqZWN0SWQ6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihjbGFzc05hbWU6IHN0cmluZywgb2JqZWN0SWQ6IHN0cmluZykge1xuICAgIHRoaXMuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xuICAgIHRoaXMub2JqZWN0SWQgPSBvYmplY3RJZDtcbiAgfVxuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmNsYXNzTmFtZSArICc6JyArIHRoaXMub2JqZWN0SWQ7XG4gIH1cblxuICBzdGF0aWMgZnJvbVN0cmluZyhzdHI6IHN0cmluZykge1xuICAgIHZhciBzcGxpdCA9IHN0ci5zcGxpdCgnOicpO1xuICAgIGlmIChzcGxpdC5sZW5ndGggIT09IDIpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjcmVhdGUgSWQgb2JqZWN0IGZyb20gdGhpcyBzdHJpbmcnKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBJZChzcGxpdFswXSwgc3BsaXRbMV0pO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gSWQ7XG4iXX0= \ No newline at end of file diff --git a/lib/LiveQuery/ParseCloudCodePublisher.js b/lib/LiveQuery/ParseCloudCodePublisher.js deleted file mode 100644 index 974770a79f..0000000000 --- a/lib/LiveQuery/ParseCloudCodePublisher.js +++ /dev/null @@ -1,50 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.ParseCloudCodePublisher = void 0; - -var _ParsePubSub = require("./ParsePubSub"); - -var _node = _interopRequireDefault(require("parse/node")); - -var _logger = _interopRequireDefault(require("../logger")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class ParseCloudCodePublisher { - // config object of the publisher, right now it only contains the redisURL, - // but we may extend it later. - constructor(config = {}) { - this.parsePublisher = _ParsePubSub.ParsePubSub.createPublisher(config); - } - - onCloudCodeAfterSave(request) { - this._onCloudCodeMessage(_node.default.applicationId + 'afterSave', request); - } - - onCloudCodeAfterDelete(request) { - this._onCloudCodeMessage(_node.default.applicationId + 'afterDelete', request); - } // Request is the request object from cloud code functions. request.object is a ParseObject. - - - _onCloudCodeMessage(type, request) { - _logger.default.verbose('Raw request from cloud code current : %j | original : %j', request.object, request.original); // We need the full JSON which includes className - - - const message = { - currentParseObject: request.object._toFullJSON() - }; - - if (request.original) { - message.originalParseObject = request.original._toFullJSON(); - } - - this.parsePublisher.publish(type, JSON.stringify(message)); - } - -} - -exports.ParseCloudCodePublisher = ParseCloudCodePublisher; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUGFyc2VDbG91ZENvZGVQdWJsaXNoZXIuanMiXSwibmFtZXMiOlsiUGFyc2VDbG91ZENvZGVQdWJsaXNoZXIiLCJjb25zdHJ1Y3RvciIsImNvbmZpZyIsInBhcnNlUHVibGlzaGVyIiwiUGFyc2VQdWJTdWIiLCJjcmVhdGVQdWJsaXNoZXIiLCJvbkNsb3VkQ29kZUFmdGVyU2F2ZSIsInJlcXVlc3QiLCJfb25DbG91ZENvZGVNZXNzYWdlIiwiUGFyc2UiLCJhcHBsaWNhdGlvbklkIiwib25DbG91ZENvZGVBZnRlckRlbGV0ZSIsInR5cGUiLCJsb2dnZXIiLCJ2ZXJib3NlIiwib2JqZWN0Iiwib3JpZ2luYWwiLCJtZXNzYWdlIiwiY3VycmVudFBhcnNlT2JqZWN0IiwiX3RvRnVsbEpTT04iLCJvcmlnaW5hbFBhcnNlT2JqZWN0IiwicHVibGlzaCIsIkpTT04iLCJzdHJpbmdpZnkiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7OztBQUVBLE1BQU1BLHVCQUFOLENBQThCO0FBRzVCO0FBQ0E7QUFDQUMsRUFBQUEsV0FBVyxDQUFDQyxNQUFXLEdBQUcsRUFBZixFQUFtQjtBQUM1QixTQUFLQyxjQUFMLEdBQXNCQyx5QkFBWUMsZUFBWixDQUE0QkgsTUFBNUIsQ0FBdEI7QUFDRDs7QUFFREksRUFBQUEsb0JBQW9CLENBQUNDLE9BQUQsRUFBcUI7QUFDdkMsU0FBS0MsbUJBQUwsQ0FBeUJDLGNBQU1DLGFBQU4sR0FBc0IsV0FBL0MsRUFBNERILE9BQTVEO0FBQ0Q7O0FBRURJLEVBQUFBLHNCQUFzQixDQUFDSixPQUFELEVBQXFCO0FBQ3pDLFNBQUtDLG1CQUFMLENBQXlCQyxjQUFNQyxhQUFOLEdBQXNCLGFBQS9DLEVBQThESCxPQUE5RDtBQUNELEdBZjJCLENBaUI1Qjs7O0FBQ0FDLEVBQUFBLG1CQUFtQixDQUFDSSxJQUFELEVBQWVMLE9BQWYsRUFBbUM7QUFDcERNLG9CQUFPQyxPQUFQLENBQ0UsMERBREYsRUFFRVAsT0FBTyxDQUFDUSxNQUZWLEVBR0VSLE9BQU8sQ0FBQ1MsUUFIVixFQURvRCxDQU1wRDs7O0FBQ0EsVUFBTUMsT0FBTyxHQUFHO0FBQ2RDLE1BQUFBLGtCQUFrQixFQUFFWCxPQUFPLENBQUNRLE1BQVIsQ0FBZUksV0FBZjtBQUROLEtBQWhCOztBQUdBLFFBQUlaLE9BQU8sQ0FBQ1MsUUFBWixFQUFzQjtBQUNwQkMsTUFBQUEsT0FBTyxDQUFDRyxtQkFBUixHQUE4QmIsT0FBTyxDQUFDUyxRQUFSLENBQWlCRyxXQUFqQixFQUE5QjtBQUNEOztBQUNELFNBQUtoQixjQUFMLENBQW9Ca0IsT0FBcEIsQ0FBNEJULElBQTVCLEVBQWtDVSxJQUFJLENBQUNDLFNBQUwsQ0FBZU4sT0FBZixDQUFsQztBQUNEOztBQWhDMkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBQYXJzZVB1YlN1YiB9IGZyb20gJy4vUGFyc2VQdWJTdWInO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IGxvZ2dlciBmcm9tICcuLi9sb2dnZXInO1xuXG5jbGFzcyBQYXJzZUNsb3VkQ29kZVB1Ymxpc2hlciB7XG4gIHBhcnNlUHVibGlzaGVyOiBPYmplY3Q7XG5cbiAgLy8gY29uZmlnIG9iamVjdCBvZiB0aGUgcHVibGlzaGVyLCByaWdodCBub3cgaXQgb25seSBjb250YWlucyB0aGUgcmVkaXNVUkwsXG4gIC8vIGJ1dCB3ZSBtYXkgZXh0ZW5kIGl0IGxhdGVyLlxuICBjb25zdHJ1Y3Rvcihjb25maWc6IGFueSA9IHt9KSB7XG4gICAgdGhpcy5wYXJzZVB1Ymxpc2hlciA9IFBhcnNlUHViU3ViLmNyZWF0ZVB1Ymxpc2hlcihjb25maWcpO1xuICB9XG5cbiAgb25DbG91ZENvZGVBZnRlclNhdmUocmVxdWVzdDogYW55KTogdm9pZCB7XG4gICAgdGhpcy5fb25DbG91ZENvZGVNZXNzYWdlKFBhcnNlLmFwcGxpY2F0aW9uSWQgKyAnYWZ0ZXJTYXZlJywgcmVxdWVzdCk7XG4gIH1cblxuICBvbkNsb3VkQ29kZUFmdGVyRGVsZXRlKHJlcXVlc3Q6IGFueSk6IHZvaWQge1xuICAgIHRoaXMuX29uQ2xvdWRDb2RlTWVzc2FnZShQYXJzZS5hcHBsaWNhdGlvbklkICsgJ2FmdGVyRGVsZXRlJywgcmVxdWVzdCk7XG4gIH1cblxuICAvLyBSZXF1ZXN0IGlzIHRoZSByZXF1ZXN0IG9iamVjdCBmcm9tIGNsb3VkIGNvZGUgZnVuY3Rpb25zLiByZXF1ZXN0Lm9iamVjdCBpcyBhIFBhcnNlT2JqZWN0LlxuICBfb25DbG91ZENvZGVNZXNzYWdlKHR5cGU6IHN0cmluZywgcmVxdWVzdDogYW55KTogdm9pZCB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoXG4gICAgICAnUmF3IHJlcXVlc3QgZnJvbSBjbG91ZCBjb2RlIGN1cnJlbnQgOiAlaiB8IG9yaWdpbmFsIDogJWonLFxuICAgICAgcmVxdWVzdC5vYmplY3QsXG4gICAgICByZXF1ZXN0Lm9yaWdpbmFsXG4gICAgKTtcbiAgICAvLyBXZSBuZWVkIHRoZSBmdWxsIEpTT04gd2hpY2ggaW5jbHVkZXMgY2xhc3NOYW1lXG4gICAgY29uc3QgbWVzc2FnZSA9IHtcbiAgICAgIGN1cnJlbnRQYXJzZU9iamVjdDogcmVxdWVzdC5vYmplY3QuX3RvRnVsbEpTT04oKSxcbiAgICB9O1xuICAgIGlmIChyZXF1ZXN0Lm9yaWdpbmFsKSB7XG4gICAgICBtZXNzYWdlLm9yaWdpbmFsUGFyc2VPYmplY3QgPSByZXF1ZXN0Lm9yaWdpbmFsLl90b0Z1bGxKU09OKCk7XG4gICAgfVxuICAgIHRoaXMucGFyc2VQdWJsaXNoZXIucHVibGlzaCh0eXBlLCBKU09OLnN0cmluZ2lmeShtZXNzYWdlKSk7XG4gIH1cbn1cblxuZXhwb3J0IHsgUGFyc2VDbG91ZENvZGVQdWJsaXNoZXIgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/ParseLiveQueryServer.js b/lib/LiveQuery/ParseLiveQueryServer.js deleted file mode 100644 index a286c9daf7..0000000000 --- a/lib/LiveQuery/ParseLiveQueryServer.js +++ /dev/null @@ -1,848 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.ParseLiveQueryServer = void 0; - -var _tv = _interopRequireDefault(require("tv4")); - -var _node = _interopRequireDefault(require("parse/node")); - -var _Subscription = require("./Subscription"); - -var _Client = require("./Client"); - -var _ParseWebSocketServer = require("./ParseWebSocketServer"); - -var _logger = _interopRequireDefault(require("../logger")); - -var _RequestSchema = _interopRequireDefault(require("./RequestSchema")); - -var _QueryTools = require("./QueryTools"); - -var _ParsePubSub = require("./ParsePubSub"); - -var _SchemaController = _interopRequireDefault(require("../Controllers/SchemaController")); - -var _lodash = _interopRequireDefault(require("lodash")); - -var _uuid = require("uuid"); - -var _triggers = require("../triggers"); - -var _Auth = require("../Auth"); - -var _Controllers = require("../Controllers"); - -var _lruCache = _interopRequireDefault(require("lru-cache")); - -var _UsersRouter = _interopRequireDefault(require("../Routers/UsersRouter")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class ParseLiveQueryServer { - // className -> (queryHash -> subscription) - // The subscriber we use to get object update from publisher - constructor(server, config = {}, parseServerConfig = {}) { - this.server = server; - this.clients = new Map(); - this.subscriptions = new Map(); - this.config = config; - config.appId = config.appId || _node.default.applicationId; - config.masterKey = config.masterKey || _node.default.masterKey; // Store keys, convert obj to map - - const keyPairs = config.keyPairs || {}; - this.keyPairs = new Map(); - - for (const key of Object.keys(keyPairs)) { - this.keyPairs.set(key, keyPairs[key]); - } - - _logger.default.verbose('Support key pairs', this.keyPairs); // Initialize Parse - - - _node.default.Object.disableSingleInstance(); - - const serverURL = config.serverURL || _node.default.serverURL; - _node.default.serverURL = serverURL; - - _node.default.initialize(config.appId, _node.default.javaScriptKey, config.masterKey); // The cache controller is a proper cache controller - // with access to User and Roles - - - this.cacheController = (0, _Controllers.getCacheController)(parseServerConfig); - config.cacheTimeout = config.cacheTimeout || 5 * 1000; // 5s - // This auth cache stores the promises for each auth resolution. - // The main benefit is to be able to reuse the same user / session token resolution. - - this.authCache = new _lruCache.default({ - max: 500, - // 500 concurrent - maxAge: config.cacheTimeout - }); // Initialize websocket server - - this.parseWebSocketServer = new _ParseWebSocketServer.ParseWebSocketServer(server, parseWebsocket => this._onConnect(parseWebsocket), config); // Initialize subscriber - - this.subscriber = _ParsePubSub.ParsePubSub.createSubscriber(config); - this.subscriber.subscribe(_node.default.applicationId + 'afterSave'); - this.subscriber.subscribe(_node.default.applicationId + 'afterDelete'); // Register message handler for subscriber. When publisher get messages, it will publish message - // to the subscribers and the handler will be called. - - this.subscriber.on('message', (channel, messageStr) => { - _logger.default.verbose('Subscribe message %j', messageStr); - - let message; - - try { - message = JSON.parse(messageStr); - } catch (e) { - _logger.default.error('unable to parse message', messageStr, e); - - return; - } - - this._inflateParseObject(message); - - if (channel === _node.default.applicationId + 'afterSave') { - this._onAfterSave(message); - } else if (channel === _node.default.applicationId + 'afterDelete') { - this._onAfterDelete(message); - } else { - _logger.default.error('Get message %s from unknown channel %j', message, channel); - } - }); - } // Message is the JSON object from publisher. Message.currentParseObject is the ParseObject JSON after changes. - // Message.originalParseObject is the original ParseObject JSON. - - - _inflateParseObject(message) { - // Inflate merged object - const currentParseObject = message.currentParseObject; - - _UsersRouter.default.removeHiddenProperties(currentParseObject); - - let className = currentParseObject.className; - let parseObject = new _node.default.Object(className); - - parseObject._finishFetch(currentParseObject); - - message.currentParseObject = parseObject; // Inflate original object - - const originalParseObject = message.originalParseObject; - - if (originalParseObject) { - _UsersRouter.default.removeHiddenProperties(originalParseObject); - - className = originalParseObject.className; - parseObject = new _node.default.Object(className); - - parseObject._finishFetch(originalParseObject); - - message.originalParseObject = parseObject; - } - } // Message is the JSON object from publisher after inflated. Message.currentParseObject is the ParseObject after changes. - // Message.originalParseObject is the original ParseObject. - - - _onAfterDelete(message) { - _logger.default.verbose(_node.default.applicationId + 'afterDelete is triggered'); - - let deletedParseObject = message.currentParseObject.toJSON(); - const classLevelPermissions = message.classLevelPermissions; - const className = deletedParseObject.className; - - _logger.default.verbose('ClassName: %j | ObjectId: %s', className, deletedParseObject.id); - - _logger.default.verbose('Current client number : %d', this.clients.size); - - const classSubscriptions = this.subscriptions.get(className); - - if (typeof classSubscriptions === 'undefined') { - _logger.default.debug('Can not find subscriptions under this class ' + className); - - return; - } - - for (const subscription of classSubscriptions.values()) { - const isSubscriptionMatched = this._matchesSubscription(deletedParseObject, subscription); - - if (!isSubscriptionMatched) { - continue; - } - - for (const [clientId, requestIds] of _lodash.default.entries(subscription.clientRequestIds)) { - const client = this.clients.get(clientId); - - if (typeof client === 'undefined') { - continue; - } - - for (const requestId of requestIds) { - const acl = message.currentParseObject.getACL(); // Check CLP - - const op = this._getCLPOperation(subscription.query); - - let res = {}; - - this._matchesCLP(classLevelPermissions, message.currentParseObject, client, requestId, op).then(() => { - // Check ACL - return this._matchesACL(acl, client, requestId); - }).then(isMatched => { - if (!isMatched) { - return null; - } - - res = { - event: 'delete', - sessionToken: client.sessionToken, - object: deletedParseObject, - clients: this.clients.size, - subscriptions: this.subscriptions.size, - useMasterKey: client.hasMasterKey, - installationId: client.installationId, - sendEvent: true - }; - return (0, _triggers.maybeRunAfterEventTrigger)('afterEvent', className, res); - }).then(() => { - if (!res.sendEvent) { - return; - } - - if (res.object && typeof res.object.toJSON === 'function') { - deletedParseObject = res.object.toJSON(); - deletedParseObject.className = className; - } - - client.pushDelete(requestId, deletedParseObject); - }).catch(error => { - _Client.Client.pushError(client.parseWebSocket, error.code || 141, error.message || error, false, requestId); - - _logger.default.error(`Failed running afterLiveQueryEvent on class ${className} for event ${res.event} with session ${res.sessionToken} with:\n Error: ` + JSON.stringify(error)); - }); - } - } - } - } // Message is the JSON object from publisher after inflated. Message.currentParseObject is the ParseObject after changes. - // Message.originalParseObject is the original ParseObject. - - - _onAfterSave(message) { - _logger.default.verbose(_node.default.applicationId + 'afterSave is triggered'); - - let originalParseObject = null; - - if (message.originalParseObject) { - originalParseObject = message.originalParseObject.toJSON(); - } - - const classLevelPermissions = message.classLevelPermissions; - let currentParseObject = message.currentParseObject.toJSON(); - const className = currentParseObject.className; - - _logger.default.verbose('ClassName: %s | ObjectId: %s', className, currentParseObject.id); - - _logger.default.verbose('Current client number : %d', this.clients.size); - - const classSubscriptions = this.subscriptions.get(className); - - if (typeof classSubscriptions === 'undefined') { - _logger.default.debug('Can not find subscriptions under this class ' + className); - - return; - } - - for (const subscription of classSubscriptions.values()) { - const isOriginalSubscriptionMatched = this._matchesSubscription(originalParseObject, subscription); - - const isCurrentSubscriptionMatched = this._matchesSubscription(currentParseObject, subscription); - - for (const [clientId, requestIds] of _lodash.default.entries(subscription.clientRequestIds)) { - const client = this.clients.get(clientId); - - if (typeof client === 'undefined') { - continue; - } - - for (const requestId of requestIds) { - // Set orignal ParseObject ACL checking promise, if the object does not match - // subscription, we do not need to check ACL - let originalACLCheckingPromise; - - if (!isOriginalSubscriptionMatched) { - originalACLCheckingPromise = Promise.resolve(false); - } else { - let originalACL; - - if (message.originalParseObject) { - originalACL = message.originalParseObject.getACL(); - } - - originalACLCheckingPromise = this._matchesACL(originalACL, client, requestId); - } // Set current ParseObject ACL checking promise, if the object does not match - // subscription, we do not need to check ACL - - - let currentACLCheckingPromise; - let res = {}; - - if (!isCurrentSubscriptionMatched) { - currentACLCheckingPromise = Promise.resolve(false); - } else { - const currentACL = message.currentParseObject.getACL(); - currentACLCheckingPromise = this._matchesACL(currentACL, client, requestId); - } - - const op = this._getCLPOperation(subscription.query); - - this._matchesCLP(classLevelPermissions, message.currentParseObject, client, requestId, op).then(() => { - return Promise.all([originalACLCheckingPromise, currentACLCheckingPromise]); - }).then(([isOriginalMatched, isCurrentMatched]) => { - _logger.default.verbose('Original %j | Current %j | Match: %s, %s, %s, %s | Query: %s', originalParseObject, currentParseObject, isOriginalSubscriptionMatched, isCurrentSubscriptionMatched, isOriginalMatched, isCurrentMatched, subscription.hash); // Decide event type - - - let type; - - if (isOriginalMatched && isCurrentMatched) { - type = 'update'; - } else if (isOriginalMatched && !isCurrentMatched) { - type = 'leave'; - } else if (!isOriginalMatched && isCurrentMatched) { - if (originalParseObject) { - type = 'enter'; - } else { - type = 'create'; - } - } else { - return null; - } - - message.event = type; - res = { - event: type, - sessionToken: client.sessionToken, - object: currentParseObject, - original: originalParseObject, - clients: this.clients.size, - subscriptions: this.subscriptions.size, - useMasterKey: client.hasMasterKey, - installationId: client.installationId, - sendEvent: true - }; - return (0, _triggers.maybeRunAfterEventTrigger)('afterEvent', className, res); - }).then(() => { - if (!res.sendEvent) { - return; - } - - if (res.object && typeof res.object.toJSON === 'function') { - currentParseObject = res.object.toJSON(); - currentParseObject.className = res.object.className || className; - } - - if (res.original && typeof res.original.toJSON === 'function') { - originalParseObject = res.original.toJSON(); - originalParseObject.className = res.original.className || className; - } - - const functionName = 'push' + message.event.charAt(0).toUpperCase() + message.event.slice(1); - - if (client[functionName]) { - client[functionName](requestId, currentParseObject, originalParseObject); - } - }, error => { - _Client.Client.pushError(client.parseWebSocket, error.code || 141, error.message || error, false, requestId); - - _logger.default.error(`Failed running afterLiveQueryEvent on class ${className} for event ${res.event} with session ${res.sessionToken} with:\n Error: ` + JSON.stringify(error)); - }); - } - } - } - } - - _onConnect(parseWebsocket) { - parseWebsocket.on('message', request => { - if (typeof request === 'string') { - try { - request = JSON.parse(request); - } catch (e) { - _logger.default.error('unable to parse request', request, e); - - return; - } - } - - _logger.default.verbose('Request: %j', request); // Check whether this request is a valid request, return error directly if not - - - if (!_tv.default.validate(request, _RequestSchema.default['general']) || !_tv.default.validate(request, _RequestSchema.default[request.op])) { - _Client.Client.pushError(parseWebsocket, 1, _tv.default.error.message); - - _logger.default.error('Connect message error %s', _tv.default.error.message); - - return; - } - - switch (request.op) { - case 'connect': - this._handleConnect(parseWebsocket, request); - - break; - - case 'subscribe': - this._handleSubscribe(parseWebsocket, request); - - break; - - case 'update': - this._handleUpdateSubscription(parseWebsocket, request); - - break; - - case 'unsubscribe': - this._handleUnsubscribe(parseWebsocket, request); - - break; - - default: - _Client.Client.pushError(parseWebsocket, 3, 'Get unknown operation'); - - _logger.default.error('Get unknown operation', request.op); - - } - }); - parseWebsocket.on('disconnect', () => { - _logger.default.info(`Client disconnect: ${parseWebsocket.clientId}`); - - const clientId = parseWebsocket.clientId; - - if (!this.clients.has(clientId)) { - (0, _triggers.runLiveQueryEventHandlers)({ - event: 'ws_disconnect_error', - clients: this.clients.size, - subscriptions: this.subscriptions.size, - error: `Unable to find client ${clientId}` - }); - - _logger.default.error(`Can not find client ${clientId} on disconnect`); - - return; - } // Delete client - - - const client = this.clients.get(clientId); - this.clients.delete(clientId); // Delete client from subscriptions - - for (const [requestId, subscriptionInfo] of _lodash.default.entries(client.subscriptionInfos)) { - const subscription = subscriptionInfo.subscription; - subscription.deleteClientSubscription(clientId, requestId); // If there is no client which is subscribing this subscription, remove it from subscriptions - - const classSubscriptions = this.subscriptions.get(subscription.className); - - if (!subscription.hasSubscribingClient()) { - classSubscriptions.delete(subscription.hash); - } // If there is no subscriptions under this class, remove it from subscriptions - - - if (classSubscriptions.size === 0) { - this.subscriptions.delete(subscription.className); - } - } - - _logger.default.verbose('Current clients %d', this.clients.size); - - _logger.default.verbose('Current subscriptions %d', this.subscriptions.size); - - (0, _triggers.runLiveQueryEventHandlers)({ - event: 'ws_disconnect', - clients: this.clients.size, - subscriptions: this.subscriptions.size, - useMasterKey: client.hasMasterKey, - installationId: client.installationId, - sessionToken: client.sessionToken - }); - }); - (0, _triggers.runLiveQueryEventHandlers)({ - event: 'ws_connect', - clients: this.clients.size, - subscriptions: this.subscriptions.size - }); - } - - _matchesSubscription(parseObject, subscription) { - // Object is undefined or null, not match - if (!parseObject) { - return false; - } - - return (0, _QueryTools.matchesQuery)(parseObject, subscription.query); - } - - getAuthForSessionToken(sessionToken) { - if (!sessionToken) { - return Promise.resolve({}); - } - - const fromCache = this.authCache.get(sessionToken); - - if (fromCache) { - return fromCache; - } - - const authPromise = (0, _Auth.getAuthForSessionToken)({ - cacheController: this.cacheController, - sessionToken: sessionToken - }).then(auth => { - return { - auth, - userId: auth && auth.user && auth.user.id - }; - }).catch(error => { - // There was an error with the session token - const result = {}; - - if (error && error.code === _node.default.Error.INVALID_SESSION_TOKEN) { - result.error = error; - this.authCache.set(sessionToken, Promise.resolve(result), this.config.cacheTimeout); - } else { - this.authCache.del(sessionToken); - } - - return result; - }); - this.authCache.set(sessionToken, authPromise); - return authPromise; - } - - async _matchesCLP(classLevelPermissions, object, client, requestId, op) { - // try to match on user first, less expensive than with roles - const subscriptionInfo = client.getSubscriptionInfo(requestId); - const aclGroup = ['*']; - let userId; - - if (typeof subscriptionInfo !== 'undefined') { - const { - userId - } = await this.getAuthForSessionToken(subscriptionInfo.sessionToken); - - if (userId) { - aclGroup.push(userId); - } - } - - try { - await _SchemaController.default.validatePermission(classLevelPermissions, object.className, aclGroup, op); - return true; - } catch (e) { - _logger.default.verbose(`Failed matching CLP for ${object.id} ${userId} ${e}`); - - return false; - } // TODO: handle roles permissions - // Object.keys(classLevelPermissions).forEach((key) => { - // const perm = classLevelPermissions[key]; - // Object.keys(perm).forEach((key) => { - // if (key.indexOf('role')) - // }); - // }) - // // it's rejected here, check the roles - // var rolesQuery = new Parse.Query(Parse.Role); - // rolesQuery.equalTo("users", user); - // return rolesQuery.find({useMasterKey:true}); - - } - - _getCLPOperation(query) { - return typeof query === 'object' && Object.keys(query).length == 1 && typeof query.objectId === 'string' ? 'get' : 'find'; - } - - async _verifyACL(acl, token) { - if (!token) { - return false; - } - - const { - auth, - userId - } = await this.getAuthForSessionToken(token); // Getting the session token failed - // This means that no additional auth is available - // At this point, just bail out as no additional visibility can be inferred. - - if (!auth || !userId) { - return false; - } - - const isSubscriptionSessionTokenMatched = acl.getReadAccess(userId); - - if (isSubscriptionSessionTokenMatched) { - return true; - } // Check if the user has any roles that match the ACL - - - return Promise.resolve().then(async () => { - // Resolve false right away if the acl doesn't have any roles - const acl_has_roles = Object.keys(acl.permissionsById).some(key => key.startsWith('role:')); - - if (!acl_has_roles) { - return false; - } - - const roleNames = await auth.getUserRoles(); // Finally, see if any of the user's roles allow them read access - - for (const role of roleNames) { - // We use getReadAccess as `role` is in the form `role:roleName` - if (acl.getReadAccess(role)) { - return true; - } - } - - return false; - }).catch(() => { - return false; - }); - } - - async _matchesACL(acl, client, requestId) { - // Return true directly if ACL isn't present, ACL is public read, or client has master key - if (!acl || acl.getPublicReadAccess() || client.hasMasterKey) { - return true; - } // Check subscription sessionToken matches ACL first - - - const subscriptionInfo = client.getSubscriptionInfo(requestId); - - if (typeof subscriptionInfo === 'undefined') { - return false; - } - - const subscriptionToken = subscriptionInfo.sessionToken; - const clientSessionToken = client.sessionToken; - - if (await this._verifyACL(acl, subscriptionToken)) { - return true; - } - - if (await this._verifyACL(acl, clientSessionToken)) { - return true; - } - - return false; - } - - async _handleConnect(parseWebsocket, request) { - if (!this._validateKeys(request, this.keyPairs)) { - _Client.Client.pushError(parseWebsocket, 4, 'Key in request is not valid'); - - _logger.default.error('Key in request is not valid'); - - return; - } - - const hasMasterKey = this._hasMasterKey(request, this.keyPairs); - - const clientId = (0, _uuid.v4)(); - const client = new _Client.Client(clientId, parseWebsocket, hasMasterKey, request.sessionToken, request.installationId); - - try { - const req = { - client, - event: 'connect', - clients: this.clients.size, - subscriptions: this.subscriptions.size, - sessionToken: request.sessionToken, - useMasterKey: client.hasMasterKey, - installationId: request.installationId - }; - await (0, _triggers.maybeRunConnectTrigger)('beforeConnect', req); - parseWebsocket.clientId = clientId; - this.clients.set(parseWebsocket.clientId, client); - - _logger.default.info(`Create new client: ${parseWebsocket.clientId}`); - - client.pushConnect(); - (0, _triggers.runLiveQueryEventHandlers)(req); - } catch (error) { - _Client.Client.pushError(parseWebsocket, error.code || 141, error.message || error, false); - - _logger.default.error(`Failed running beforeConnect for session ${request.sessionToken} with:\n Error: ` + JSON.stringify(error)); - } - } - - _hasMasterKey(request, validKeyPairs) { - if (!validKeyPairs || validKeyPairs.size == 0 || !validKeyPairs.has('masterKey')) { - return false; - } - - if (!request || !Object.prototype.hasOwnProperty.call(request, 'masterKey')) { - return false; - } - - return request.masterKey === validKeyPairs.get('masterKey'); - } - - _validateKeys(request, validKeyPairs) { - if (!validKeyPairs || validKeyPairs.size == 0) { - return true; - } - - let isValid = false; - - for (const [key, secret] of validKeyPairs) { - if (!request[key] || request[key] !== secret) { - continue; - } - - isValid = true; - break; - } - - return isValid; - } - - async _handleSubscribe(parseWebsocket, request) { - // If we can not find this client, return error to client - if (!Object.prototype.hasOwnProperty.call(parseWebsocket, 'clientId')) { - _Client.Client.pushError(parseWebsocket, 2, 'Can not find this client, make sure you connect to server before subscribing'); - - _logger.default.error('Can not find this client, make sure you connect to server before subscribing'); - - return; - } - - const client = this.clients.get(parseWebsocket.clientId); - const className = request.query.className; - - try { - await (0, _triggers.maybeRunSubscribeTrigger)('beforeSubscribe', className, request); // Get subscription from subscriptions, create one if necessary - - const subscriptionHash = (0, _QueryTools.queryHash)(request.query); // Add className to subscriptions if necessary - - if (!this.subscriptions.has(className)) { - this.subscriptions.set(className, new Map()); - } - - const classSubscriptions = this.subscriptions.get(className); - let subscription; - - if (classSubscriptions.has(subscriptionHash)) { - subscription = classSubscriptions.get(subscriptionHash); - } else { - subscription = new _Subscription.Subscription(className, request.query.where, subscriptionHash); - classSubscriptions.set(subscriptionHash, subscription); - } // Add subscriptionInfo to client - - - const subscriptionInfo = { - subscription: subscription - }; // Add selected fields, sessionToken and installationId for this subscription if necessary - - if (request.query.fields) { - subscriptionInfo.fields = request.query.fields; - } - - if (request.sessionToken) { - subscriptionInfo.sessionToken = request.sessionToken; - } - - client.addSubscriptionInfo(request.requestId, subscriptionInfo); // Add clientId to subscription - - subscription.addClientSubscription(parseWebsocket.clientId, request.requestId); - client.pushSubscribe(request.requestId); - - _logger.default.verbose(`Create client ${parseWebsocket.clientId} new subscription: ${request.requestId}`); - - _logger.default.verbose('Current client number: %d', this.clients.size); - - (0, _triggers.runLiveQueryEventHandlers)({ - client, - event: 'subscribe', - clients: this.clients.size, - subscriptions: this.subscriptions.size, - sessionToken: request.sessionToken, - useMasterKey: client.hasMasterKey, - installationId: client.installationId - }); - } catch (e) { - _Client.Client.pushError(parseWebsocket, e.code || 141, e.message || e, false, request.requestId); - - _logger.default.error(`Failed running beforeSubscribe on ${className} for session ${request.sessionToken} with:\n Error: ` + JSON.stringify(e)); - } - } - - _handleUpdateSubscription(parseWebsocket, request) { - this._handleUnsubscribe(parseWebsocket, request, false); - - this._handleSubscribe(parseWebsocket, request); - } - - _handleUnsubscribe(parseWebsocket, request, notifyClient = true) { - // If we can not find this client, return error to client - if (!Object.prototype.hasOwnProperty.call(parseWebsocket, 'clientId')) { - _Client.Client.pushError(parseWebsocket, 2, 'Can not find this client, make sure you connect to server before unsubscribing'); - - _logger.default.error('Can not find this client, make sure you connect to server before unsubscribing'); - - return; - } - - const requestId = request.requestId; - const client = this.clients.get(parseWebsocket.clientId); - - if (typeof client === 'undefined') { - _Client.Client.pushError(parseWebsocket, 2, 'Cannot find client with clientId ' + parseWebsocket.clientId + '. Make sure you connect to live query server before unsubscribing.'); - - _logger.default.error('Can not find this client ' + parseWebsocket.clientId); - - return; - } - - const subscriptionInfo = client.getSubscriptionInfo(requestId); - - if (typeof subscriptionInfo === 'undefined') { - _Client.Client.pushError(parseWebsocket, 2, 'Cannot find subscription with clientId ' + parseWebsocket.clientId + ' subscriptionId ' + requestId + '. Make sure you subscribe to live query server before unsubscribing.'); - - _logger.default.error('Can not find subscription with clientId ' + parseWebsocket.clientId + ' subscriptionId ' + requestId); - - return; - } // Remove subscription from client - - - client.deleteSubscriptionInfo(requestId); // Remove client from subscription - - const subscription = subscriptionInfo.subscription; - const className = subscription.className; - subscription.deleteClientSubscription(parseWebsocket.clientId, requestId); // If there is no client which is subscribing this subscription, remove it from subscriptions - - const classSubscriptions = this.subscriptions.get(className); - - if (!subscription.hasSubscribingClient()) { - classSubscriptions.delete(subscription.hash); - } // If there is no subscriptions under this class, remove it from subscriptions - - - if (classSubscriptions.size === 0) { - this.subscriptions.delete(className); - } - - (0, _triggers.runLiveQueryEventHandlers)({ - client, - event: 'unsubscribe', - clients: this.clients.size, - subscriptions: this.subscriptions.size, - sessionToken: subscriptionInfo.sessionToken, - useMasterKey: client.hasMasterKey, - installationId: client.installationId - }); - - if (!notifyClient) { - return; - } - - client.pushUnsubscribe(request.requestId); - - _logger.default.verbose(`Delete client: ${parseWebsocket.clientId} | subscription: ${request.requestId}`); - } - -} - -exports.ParseLiveQueryServer = ParseLiveQueryServer; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUGFyc2VMaXZlUXVlcnlTZXJ2ZXIuanMiXSwibmFtZXMiOlsiUGFyc2VMaXZlUXVlcnlTZXJ2ZXIiLCJjb25zdHJ1Y3RvciIsInNlcnZlciIsImNvbmZpZyIsInBhcnNlU2VydmVyQ29uZmlnIiwiY2xpZW50cyIsIk1hcCIsInN1YnNjcmlwdGlvbnMiLCJhcHBJZCIsIlBhcnNlIiwiYXBwbGljYXRpb25JZCIsIm1hc3RlcktleSIsImtleVBhaXJzIiwia2V5IiwiT2JqZWN0Iiwia2V5cyIsInNldCIsImxvZ2dlciIsInZlcmJvc2UiLCJkaXNhYmxlU2luZ2xlSW5zdGFuY2UiLCJzZXJ2ZXJVUkwiLCJpbml0aWFsaXplIiwiamF2YVNjcmlwdEtleSIsImNhY2hlQ29udHJvbGxlciIsImNhY2hlVGltZW91dCIsImF1dGhDYWNoZSIsIkxSVSIsIm1heCIsIm1heEFnZSIsInBhcnNlV2ViU29ja2V0U2VydmVyIiwiUGFyc2VXZWJTb2NrZXRTZXJ2ZXIiLCJwYXJzZVdlYnNvY2tldCIsIl9vbkNvbm5lY3QiLCJzdWJzY3JpYmVyIiwiUGFyc2VQdWJTdWIiLCJjcmVhdGVTdWJzY3JpYmVyIiwic3Vic2NyaWJlIiwib24iLCJjaGFubmVsIiwibWVzc2FnZVN0ciIsIm1lc3NhZ2UiLCJKU09OIiwicGFyc2UiLCJlIiwiZXJyb3IiLCJfaW5mbGF0ZVBhcnNlT2JqZWN0IiwiX29uQWZ0ZXJTYXZlIiwiX29uQWZ0ZXJEZWxldGUiLCJjdXJyZW50UGFyc2VPYmplY3QiLCJVc2VyUm91dGVyIiwicmVtb3ZlSGlkZGVuUHJvcGVydGllcyIsImNsYXNzTmFtZSIsInBhcnNlT2JqZWN0IiwiX2ZpbmlzaEZldGNoIiwib3JpZ2luYWxQYXJzZU9iamVjdCIsImRlbGV0ZWRQYXJzZU9iamVjdCIsInRvSlNPTiIsImNsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsImlkIiwic2l6ZSIsImNsYXNzU3Vic2NyaXB0aW9ucyIsImdldCIsImRlYnVnIiwic3Vic2NyaXB0aW9uIiwidmFsdWVzIiwiaXNTdWJzY3JpcHRpb25NYXRjaGVkIiwiX21hdGNoZXNTdWJzY3JpcHRpb24iLCJjbGllbnRJZCIsInJlcXVlc3RJZHMiLCJfIiwiZW50cmllcyIsImNsaWVudFJlcXVlc3RJZHMiLCJjbGllbnQiLCJyZXF1ZXN0SWQiLCJhY2wiLCJnZXRBQ0wiLCJvcCIsIl9nZXRDTFBPcGVyYXRpb24iLCJxdWVyeSIsInJlcyIsIl9tYXRjaGVzQ0xQIiwidGhlbiIsIl9tYXRjaGVzQUNMIiwiaXNNYXRjaGVkIiwiZXZlbnQiLCJzZXNzaW9uVG9rZW4iLCJvYmplY3QiLCJ1c2VNYXN0ZXJLZXkiLCJoYXNNYXN0ZXJLZXkiLCJpbnN0YWxsYXRpb25JZCIsInNlbmRFdmVudCIsInB1c2hEZWxldGUiLCJjYXRjaCIsIkNsaWVudCIsInB1c2hFcnJvciIsInBhcnNlV2ViU29ja2V0IiwiY29kZSIsInN0cmluZ2lmeSIsImlzT3JpZ2luYWxTdWJzY3JpcHRpb25NYXRjaGVkIiwiaXNDdXJyZW50U3Vic2NyaXB0aW9uTWF0Y2hlZCIsIm9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJvcmlnaW5hbEFDTCIsImN1cnJlbnRBQ0xDaGVja2luZ1Byb21pc2UiLCJjdXJyZW50QUNMIiwiYWxsIiwiaXNPcmlnaW5hbE1hdGNoZWQiLCJpc0N1cnJlbnRNYXRjaGVkIiwiaGFzaCIsInR5cGUiLCJvcmlnaW5hbCIsImZ1bmN0aW9uTmFtZSIsImNoYXJBdCIsInRvVXBwZXJDYXNlIiwic2xpY2UiLCJyZXF1ZXN0IiwidHY0IiwidmFsaWRhdGUiLCJSZXF1ZXN0U2NoZW1hIiwiX2hhbmRsZUNvbm5lY3QiLCJfaGFuZGxlU3Vic2NyaWJlIiwiX2hhbmRsZVVwZGF0ZVN1YnNjcmlwdGlvbiIsIl9oYW5kbGVVbnN1YnNjcmliZSIsImluZm8iLCJoYXMiLCJkZWxldGUiLCJzdWJzY3JpcHRpb25JbmZvIiwic3Vic2NyaXB0aW9uSW5mb3MiLCJkZWxldGVDbGllbnRTdWJzY3JpcHRpb24iLCJoYXNTdWJzY3JpYmluZ0NsaWVudCIsImdldEF1dGhGb3JTZXNzaW9uVG9rZW4iLCJmcm9tQ2FjaGUiLCJhdXRoUHJvbWlzZSIsImF1dGgiLCJ1c2VySWQiLCJ1c2VyIiwicmVzdWx0IiwiRXJyb3IiLCJJTlZBTElEX1NFU1NJT05fVE9LRU4iLCJkZWwiLCJnZXRTdWJzY3JpcHRpb25JbmZvIiwiYWNsR3JvdXAiLCJwdXNoIiwiU2NoZW1hQ29udHJvbGxlciIsInZhbGlkYXRlUGVybWlzc2lvbiIsImxlbmd0aCIsIm9iamVjdElkIiwiX3ZlcmlmeUFDTCIsInRva2VuIiwiaXNTdWJzY3JpcHRpb25TZXNzaW9uVG9rZW5NYXRjaGVkIiwiZ2V0UmVhZEFjY2VzcyIsImFjbF9oYXNfcm9sZXMiLCJwZXJtaXNzaW9uc0J5SWQiLCJzb21lIiwic3RhcnRzV2l0aCIsInJvbGVOYW1lcyIsImdldFVzZXJSb2xlcyIsInJvbGUiLCJnZXRQdWJsaWNSZWFkQWNjZXNzIiwic3Vic2NyaXB0aW9uVG9rZW4iLCJjbGllbnRTZXNzaW9uVG9rZW4iLCJfdmFsaWRhdGVLZXlzIiwiX2hhc01hc3RlcktleSIsInJlcSIsInB1c2hDb25uZWN0IiwidmFsaWRLZXlQYWlycyIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImlzVmFsaWQiLCJzZWNyZXQiLCJzdWJzY3JpcHRpb25IYXNoIiwiU3Vic2NyaXB0aW9uIiwid2hlcmUiLCJmaWVsZHMiLCJhZGRTdWJzY3JpcHRpb25JbmZvIiwiYWRkQ2xpZW50U3Vic2NyaXB0aW9uIiwicHVzaFN1YnNjcmliZSIsIm5vdGlmeUNsaWVudCIsImRlbGV0ZVN1YnNjcmlwdGlvbkluZm8iLCJwdXNoVW5zdWJzY3JpYmUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFNQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztB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LFlBQVksQ0FBQ21FLG9CQUFiLEVBQUwsRUFBMEM7QUFDeEN0RSxNQUFBQSxrQkFBa0IsQ0FBQ2tFLE1BQW5CLENBQTBCL0QsWUFBWSxDQUFDOEMsSUFBdkM7QUFDRCxLQXpEc0YsQ0EwRHZGOzs7QUFDQSxRQUFJakQsa0JBQWtCLENBQUNELElBQW5CLEtBQTRCLENBQWhDLEVBQW1DO0FBQ2pDLFdBQUtwRCxhQUFMLENBQW1CdUgsTUFBbkIsQ0FBMEIzRSxTQUExQjtBQUNEOztBQUNELDZDQUEwQjtBQUN4QnFCLE1BQUFBLE1BRHdCO0FBRXhCWSxNQUFBQSxLQUFLLEVBQUUsYUFGaUI7QUFHeEIvRSxNQUFBQSxPQUFPLEVBQUUsS0FBS0EsT0FBTCxDQUFhc0QsSUFIRTtBQUl4QnBELE1BQUFBLGFBQWEsRUFBRSxLQUFLQSxhQUFMLENBQW1Cb0QsSUFKVjtBQUt4QjBCLE1BQUFBLFlBQVksRUFBRTBDLGdCQUFnQixDQUFDMUMsWUFMUDtBQU14QkUsTUFBQUEsWUFBWSxFQUFFZixNQUFNLENBQUNnQixZQU5HO0FBT3hCQyxNQUFBQSxjQUFjLEVBQUVqQixNQUFNLENBQUNpQjtBQVBDLEtBQTFCOztBQVVBLFFBQUksQ0FBQzBGLFlBQUwsRUFBbUI7QUFDakI7QUFDRDs7QUFFRDNHLElBQUFBLE1BQU0sQ0FBQzZHLGVBQVAsQ0FBdUJqRSxPQUFPLENBQUMzQyxTQUEvQjs7QUFFQXhELG9CQUFPQyxPQUFQLENBQ0csa0JBQWlCYSxjQUFjLENBQUNvQyxRQUFTLG9CQUFtQmlELE9BQU8sQ0FBQzNDLFNBQVUsRUFEakY7QUFHRDs7QUF2eEJ3QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0djQgZnJvbSAndHY0JztcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJy4vU3Vic2NyaXB0aW9uJztcbmltcG9ydCB7IENsaWVudCB9IGZyb20gJy4vQ2xpZW50JztcbmltcG9ydCB7IFBhcnNlV2ViU29ja2V0U2VydmVyIH0gZnJvbSAnLi9QYXJzZVdlYlNvY2tldFNlcnZlcic7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5pbXBvcnQgUmVxdWVzdFNjaGVtYSBmcm9tICcuL1JlcXVlc3RTY2hlbWEnO1xuaW1wb3J0IHsgbWF0Y2hlc1F1ZXJ5LCBxdWVyeUhhc2ggfSBmcm9tICcuL1F1ZXJ5VG9vbHMnO1xuaW1wb3J0IHsgUGFyc2VQdWJTdWIgfSBmcm9tICcuL1BhcnNlUHViU3ViJztcbmltcG9ydCBTY2hlbWFDb250cm9sbGVyIGZyb20gJy4uL0NvbnRyb2xsZXJzL1NjaGVtYUNvbnRyb2xsZXInO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IHY0IGFzIHV1aWR2NCB9IGZyb20gJ3V1aWQnO1xuaW1wb3J0IHtcbiAgcnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyxcbiAgbWF5YmVSdW5Db25uZWN0VHJpZ2dlcixcbiAgbWF5YmVSdW5TdWJzY3JpYmVUcmlnZ2VyLFxuICBtYXliZVJ1bkFmdGVyRXZlbnRUcmlnZ2VyLFxufSBmcm9tICcuLi90cmlnZ2Vycyc7XG5pbXBvcnQgeyBnZXRBdXRoRm9yU2Vzc2lvblRva2VuLCBBdXRoIH0gZnJvbSAnLi4vQXV0aCc7XG5pbXBvcnQgeyBnZXRDYWNoZUNvbnRyb2xsZXIgfSBmcm9tICcuLi9Db250cm9sbGVycyc7XG5pbXBvcnQgTFJVIGZyb20gJ2xydS1jYWNoZSc7XG5pbXBvcnQgVXNlclJvdXRlciBmcm9tICcuLi9Sb3V0ZXJzL1VzZXJzUm91dGVyJztcblxuY2xhc3MgUGFyc2VMaXZlUXVlcnlTZXJ2ZXIge1xuICBjbGllbnRzOiBNYXA7XG4gIC8vIGNsYXNzTmFtZSAtPiAocXVlcnlIYXNoIC0+IHN1YnNjcmlwdGlvbilcbiAgc3Vic2NyaXB0aW9uczogT2JqZWN0O1xuICBwYXJzZVdlYlNvY2tldFNlcnZlcjogT2JqZWN0O1xuICBrZXlQYWlyczogYW55O1xuICAvLyBUaGUgc3Vic2NyaWJlciB3ZSB1c2UgdG8gZ2V0IG9iamVjdCB1cGRhdGUgZnJvbSBwdWJsaXNoZXJcbiAgc3Vic2NyaWJlcjogT2JqZWN0O1xuXG4gIGNvbnN0cnVjdG9yKHNlcnZlcjogYW55LCBjb25maWc6IGFueSA9IHt9LCBwYXJzZVNlcnZlckNvbmZpZzogYW55ID0ge30pIHtcbiAgICB0aGlzLnNlcnZlciA9IHNlcnZlcjtcbiAgICB0aGlzLmNsaWVudHMgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuXG4gICAgY29uZmlnLmFwcElkID0gY29uZmlnLmFwcElkIHx8IFBhcnNlLmFwcGxpY2F0aW9uSWQ7XG4gICAgY29uZmlnLm1hc3RlcktleSA9IGNvbmZpZy5tYXN0ZXJLZXkgfHwgUGFyc2UubWFzdGVyS2V5O1xuXG4gICAgLy8gU3RvcmUga2V5cywgY29udmVydCBvYmogdG8gbWFwXG4gICAgY29uc3Qga2V5UGFpcnMgPSBjb25maWcua2V5UGFpcnMgfHwge307XG4gICAgdGhpcy5rZXlQYWlycyA9IG5ldyBNYXAoKTtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhrZXlQYWlycykpIHtcbiAgICAgIHRoaXMua2V5UGFpcnMuc2V0KGtleSwga2V5UGFpcnNba2V5XSk7XG4gICAgfVxuICAgIGxvZ2dlci52ZXJib3NlKCdTdXBwb3J0IGtleSBwYWlycycsIHRoaXMua2V5UGFpcnMpO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSBQYXJzZVxuICAgIFBhcnNlLk9iamVjdC5kaXNhYmxlU2luZ2xlSW5zdGFuY2UoKTtcbiAgICBjb25zdCBzZXJ2ZXJVUkwgPSBjb25maWcuc2VydmVyVVJMIHx8IFBhcnNlLnNlcnZlclVSTDtcbiAgICBQYXJzZS5zZXJ2ZXJVUkwgPSBzZXJ2ZXJVUkw7XG4gICAgUGFyc2UuaW5pdGlhbGl6ZShjb25maWcuYXBwSWQsIFBhcnNlLmphdmFTY3JpcHRLZXksIGNvbmZpZy5tYXN0ZXJLZXkpO1xuXG4gICAgLy8gVGhlIGNhY2hlIGNvbnRyb2xsZXIgaXMgYSBwcm9wZXIgY2FjaGUgY29udHJvbGxlclxuICAgIC8vIHdpdGggYWNjZXNzIHRvIFVzZXIgYW5kIFJvbGVzXG4gICAgdGhpcy5jYWNoZUNvbnRyb2xsZXIgPSBnZXRDYWNoZUNvbnRyb2xsZXIocGFyc2VTZXJ2ZXJDb25maWcpO1xuXG4gICAgY29uZmlnLmNhY2hlVGltZW91dCA9IGNvbmZpZy5jYWNoZVRpbWVvdXQgfHwgNSAqIDEwMDA7IC8vIDVzXG5cbiAgICAvLyBUaGlzIGF1dGggY2FjaGUgc3RvcmVzIHRoZSBwcm9taXNlcyBmb3IgZWFjaCBhdXRoIHJlc29sdXRpb24uXG4gICAgLy8gVGhlIG1haW4gYmVuZWZpdCBpcyB0byBiZSBhYmxlIHRvIHJldXNlIHRoZSBzYW1lIHVzZXIgLyBzZXNzaW9uIHRva2VuIHJlc29sdXRpb24uXG4gICAgdGhpcy5hdXRoQ2FjaGUgPSBuZXcgTFJVKHtcbiAgICAgIG1heDogNTAwLCAvLyA1MDAgY29uY3VycmVudFxuICAgICAgbWF4QWdlOiBjb25maWcuY2FjaGVUaW1lb3V0LFxuICAgIH0pO1xuICAgIC8vIEluaXRpYWxpemUgd2Vic29ja2V0IHNlcnZlclxuICAgIHRoaXMucGFyc2VXZWJTb2NrZXRTZXJ2ZXIgPSBuZXcgUGFyc2VXZWJTb2NrZXRTZXJ2ZXIoXG4gICAgICBzZXJ2ZXIsXG4gICAgICBwYXJzZVdlYnNvY2tldCA9PiB0aGlzLl9vbkNvbm5lY3QocGFyc2VXZWJzb2NrZXQpLFxuICAgICAgY29uZmlnXG4gICAgKTtcblxuICAgIC8vIEluaXRpYWxpemUgc3Vic2NyaWJlclxuICAgIHRoaXMuc3Vic2NyaWJlciA9IFBhcnNlUHViU3ViLmNyZWF0ZVN1YnNjcmliZXIoY29uZmlnKTtcbiAgICB0aGlzLnN1YnNjcmliZXIuc3Vic2NyaWJlKFBhcnNlLmFwcGxpY2F0aW9uSWQgKyAnYWZ0ZXJTYXZlJyk7XG4gICAgdGhpcy5zdWJzY3JpYmVyLnN1YnNjcmliZShQYXJzZS5hcHBsaWNhdGlvbklkICsgJ2FmdGVyRGVsZXRlJyk7XG4gICAgLy8gUmVnaXN0ZXIgbWVzc2FnZSBoYW5kbGVyIGZvciBzdWJzY3JpYmVyLiBXaGVuIHB1Ymxpc2hlciBnZXQgbWVzc2FnZXMsIGl0IHdpbGwgcHVibGlzaCBtZXNzYWdlXG4gICAgLy8gdG8gdGhlIHN1YnNjcmliZXJzIGFuZCB0aGUgaGFuZGxlciB3aWxsIGJlIGNhbGxlZC5cbiAgICB0aGlzLnN1YnNjcmliZXIub24oJ21lc3NhZ2UnLCAoY2hhbm5lbCwgbWVzc2FnZVN0cikgPT4ge1xuICAgICAgbG9nZ2VyLnZlcmJvc2UoJ1N1YnNjcmliZSBtZXNzYWdlICVqJywgbWVzc2FnZVN0cik7XG4gICAgICBsZXQgbWVzc2FnZTtcbiAgICAgIHRyeSB7XG4gICAgICAgIG1lc3NhZ2UgPSBKU09OLnBhcnNlKG1lc3NhZ2VTdHIpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ3VuYWJsZSB0byBwYXJzZSBtZXNzYWdlJywgbWVzc2FnZVN0ciwgZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2luZmxhdGVQYXJzZU9iamVjdChtZXNzYWdlKTtcbiAgICAgIGlmIChjaGFubmVsID09PSBQYXJzZS5hcHBsaWNhdGlvbklkICsgJ2FmdGVyU2F2ZScpIHtcbiAgICAgICAgdGhpcy5fb25BZnRlclNhdmUobWVzc2FnZSk7XG4gICAgICB9IGVsc2UgaWYgKGNoYW5uZWwgPT09IFBhcnNlLmFwcGxpY2F0aW9uSWQgKyAnYWZ0ZXJEZWxldGUnKSB7XG4gICAgICAgIHRoaXMuX29uQWZ0ZXJEZWxldGUobWVzc2FnZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ0dldCBtZXNzYWdlICVzIGZyb20gdW5rbm93biBjaGFubmVsICVqJywgbWVzc2FnZSwgY2hhbm5lbCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBNZXNzYWdlIGlzIHRoZSBKU09OIG9iamVjdCBmcm9tIHB1Ymxpc2hlci4gTWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QgaXMgdGhlIFBhcnNlT2JqZWN0IEpTT04gYWZ0ZXIgY2hhbmdlcy5cbiAgLy8gTWVzc2FnZS5vcmlnaW5hbFBhcnNlT2JqZWN0IGlzIHRoZSBvcmlnaW5hbCBQYXJzZU9iamVjdCBKU09OLlxuICBfaW5mbGF0ZVBhcnNlT2JqZWN0KG1lc3NhZ2U6IGFueSk6IHZvaWQge1xuICAgIC8vIEluZmxhdGUgbWVyZ2VkIG9iamVjdFxuICAgIGNvbnN0IGN1cnJlbnRQYXJzZU9iamVjdCA9IG1lc3NhZ2UuY3VycmVudFBhcnNlT2JqZWN0O1xuICAgIFVzZXJSb3V0ZXIucmVtb3ZlSGlkZGVuUHJvcGVydGllcyhjdXJyZW50UGFyc2VPYmplY3QpO1xuICAgIGxldCBjbGFzc05hbWUgPSBjdXJyZW50UGFyc2VPYmplY3QuY2xhc3NOYW1lO1xuICAgIGxldCBwYXJzZU9iamVjdCA9IG5ldyBQYXJzZS5PYmplY3QoY2xhc3NOYW1lKTtcbiAgICBwYXJzZU9iamVjdC5fZmluaXNoRmV0Y2goY3VycmVudFBhcnNlT2JqZWN0KTtcbiAgICBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdCA9IHBhcnNlT2JqZWN0O1xuICAgIC8vIEluZmxhdGUgb3JpZ2luYWwgb2JqZWN0XG4gICAgY29uc3Qgb3JpZ2luYWxQYXJzZU9iamVjdCA9IG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdDtcbiAgICBpZiAob3JpZ2luYWxQYXJzZU9iamVjdCkge1xuICAgICAgVXNlclJvdXRlci5yZW1vdmVIaWRkZW5Qcm9wZXJ0aWVzKG9yaWdpbmFsUGFyc2VPYmplY3QpO1xuICAgICAgY2xhc3NOYW1lID0gb3JpZ2luYWxQYXJzZU9iamVjdC5jbGFzc05hbWU7XG4gICAgICBwYXJzZU9iamVjdCA9IG5ldyBQYXJzZS5PYmplY3QoY2xhc3NOYW1lKTtcbiAgICAgIHBhcnNlT2JqZWN0Ll9maW5pc2hGZXRjaChvcmlnaW5hbFBhcnNlT2JqZWN0KTtcbiAgICAgIG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdCA9IHBhcnNlT2JqZWN0O1xuICAgIH1cbiAgfVxuXG4gIC8vIE1lc3NhZ2UgaXMgdGhlIEpTT04gb2JqZWN0IGZyb20gcHVibGlzaGVyIGFmdGVyIGluZmxhdGVkLiBNZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdCBpcyB0aGUgUGFyc2VPYmplY3QgYWZ0ZXIgY2hhbmdlcy5cbiAgLy8gTWVzc2FnZS5vcmlnaW5hbFBhcnNlT2JqZWN0IGlzIHRoZSBvcmlnaW5hbCBQYXJzZU9iamVjdC5cbiAgX29uQWZ0ZXJEZWxldGUobWVzc2FnZTogYW55KTogdm9pZCB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoUGFyc2UuYXBwbGljYXRpb25JZCArICdhZnRlckRlbGV0ZSBpcyB0cmlnZ2VyZWQnKTtcblxuICAgIGxldCBkZWxldGVkUGFyc2VPYmplY3QgPSBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdC50b0pTT04oKTtcbiAgICBjb25zdCBjbGFzc0xldmVsUGVybWlzc2lvbnMgPSBtZXNzYWdlLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucztcbiAgICBjb25zdCBjbGFzc05hbWUgPSBkZWxldGVkUGFyc2VPYmplY3QuY2xhc3NOYW1lO1xuICAgIGxvZ2dlci52ZXJib3NlKCdDbGFzc05hbWU6ICVqIHwgT2JqZWN0SWQ6ICVzJywgY2xhc3NOYW1lLCBkZWxldGVkUGFyc2VPYmplY3QuaWQpO1xuICAgIGxvZ2dlci52ZXJib3NlKCdDdXJyZW50IGNsaWVudCBudW1iZXIgOiAlZCcsIHRoaXMuY2xpZW50cy5zaXplKTtcblxuICAgIGNvbnN0IGNsYXNzU3Vic2NyaXB0aW9ucyA9IHRoaXMuc3Vic2NyaXB0aW9ucy5nZXQoY2xhc3NOYW1lKTtcbiAgICBpZiAodHlwZW9mIGNsYXNzU3Vic2NyaXB0aW9ucyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZygnQ2FuIG5vdCBmaW5kIHN1YnNjcmlwdGlvbnMgdW5kZXIgdGhpcyBjbGFzcyAnICsgY2xhc3NOYW1lKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZm9yIChjb25zdCBzdWJzY3JpcHRpb24gb2YgY2xhc3NTdWJzY3JpcHRpb25zLnZhbHVlcygpKSB7XG4gICAgICBjb25zdCBpc1N1YnNjcmlwdGlvbk1hdGNoZWQgPSB0aGlzLl9tYXRjaGVzU3Vic2NyaXB0aW9uKGRlbGV0ZWRQYXJzZU9iamVjdCwgc3Vic2NyaXB0aW9uKTtcbiAgICAgIGlmICghaXNTdWJzY3JpcHRpb25NYXRjaGVkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBbY2xpZW50SWQsIHJlcXVlc3RJZHNdIG9mIF8uZW50cmllcyhzdWJzY3JpcHRpb24uY2xpZW50UmVxdWVzdElkcykpIHtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRzLmdldChjbGllbnRJZCk7XG4gICAgICAgIGlmICh0eXBlb2YgY2xpZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgcmVxdWVzdElkIG9mIHJlcXVlc3RJZHMpIHtcbiAgICAgICAgICBjb25zdCBhY2wgPSBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdC5nZXRBQ0woKTtcbiAgICAgICAgICAvLyBDaGVjayBDTFBcbiAgICAgICAgICBjb25zdCBvcCA9IHRoaXMuX2dldENMUE9wZXJhdGlvbihzdWJzY3JpcHRpb24ucXVlcnkpO1xuICAgICAgICAgIGxldCByZXMgPSB7fTtcbiAgICAgICAgICB0aGlzLl9tYXRjaGVzQ0xQKGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgbWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QsIGNsaWVudCwgcmVxdWVzdElkLCBvcClcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgLy8gQ2hlY2sgQUNMXG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLl9tYXRjaGVzQUNMKGFjbCwgY2xpZW50LCByZXF1ZXN0SWQpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKGlzTWF0Y2hlZCA9PiB7XG4gICAgICAgICAgICAgIGlmICghaXNNYXRjaGVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmVzID0ge1xuICAgICAgICAgICAgICAgIGV2ZW50OiAnZGVsZXRlJyxcbiAgICAgICAgICAgICAgICBzZXNzaW9uVG9rZW46IGNsaWVudC5zZXNzaW9uVG9rZW4sXG4gICAgICAgICAgICAgICAgb2JqZWN0OiBkZWxldGVkUGFyc2VPYmplY3QsXG4gICAgICAgICAgICAgICAgY2xpZW50czogdGhpcy5jbGllbnRzLnNpemUsXG4gICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgICAgICAgICAgICAgdXNlTWFzdGVyS2V5OiBjbGllbnQuaGFzTWFzdGVyS2V5LFxuICAgICAgICAgICAgICAgIGluc3RhbGxhdGlvbklkOiBjbGllbnQuaW5zdGFsbGF0aW9uSWQsXG4gICAgICAgICAgICAgICAgc2VuZEV2ZW50OiB0cnVlLFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICByZXR1cm4gbWF5YmVSdW5BZnRlckV2ZW50VHJpZ2dlcignYWZ0ZXJFdmVudCcsIGNsYXNzTmFtZSwgcmVzKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgIGlmICghcmVzLnNlbmRFdmVudCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAocmVzLm9iamVjdCAmJiB0eXBlb2YgcmVzLm9iamVjdC50b0pTT04gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICBkZWxldGVkUGFyc2VPYmplY3QgPSByZXMub2JqZWN0LnRvSlNPTigpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZWRQYXJzZU9iamVjdC5jbGFzc05hbWUgPSBjbGFzc05hbWU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgY2xpZW50LnB1c2hEZWxldGUocmVxdWVzdElkLCBkZWxldGVkUGFyc2VPYmplY3QpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgIENsaWVudC5wdXNoRXJyb3IoXG4gICAgICAgICAgICAgICAgY2xpZW50LnBhcnNlV2ViU29ja2V0LFxuICAgICAgICAgICAgICAgIGVycm9yLmNvZGUgfHwgMTQxLFxuICAgICAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgfHwgZXJyb3IsXG4gICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICAgcmVxdWVzdElkXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAgICBgRmFpbGVkIHJ1bm5pbmcgYWZ0ZXJMaXZlUXVlcnlFdmVudCBvbiBjbGFzcyAke2NsYXNzTmFtZX0gZm9yIGV2ZW50ICR7cmVzLmV2ZW50fSB3aXRoIHNlc3Npb24gJHtyZXMuc2Vzc2lvblRva2VufSB3aXRoOlxcbiBFcnJvcjogYCArXG4gICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShlcnJvcilcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gTWVzc2FnZSBpcyB0aGUgSlNPTiBvYmplY3QgZnJvbSBwdWJsaXNoZXIgYWZ0ZXIgaW5mbGF0ZWQuIE1lc3NhZ2UuY3VycmVudFBhcnNlT2JqZWN0IGlzIHRoZSBQYXJzZU9iamVjdCBhZnRlciBjaGFuZ2VzLlxuICAvLyBNZXNzYWdlLm9yaWdpbmFsUGFyc2VPYmplY3QgaXMgdGhlIG9yaWdpbmFsIFBhcnNlT2JqZWN0LlxuICBfb25BZnRlclNhdmUobWVzc2FnZTogYW55KTogdm9pZCB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoUGFyc2UuYXBwbGljYXRpb25JZCArICdhZnRlclNhdmUgaXMgdHJpZ2dlcmVkJyk7XG5cbiAgICBsZXQgb3JpZ2luYWxQYXJzZU9iamVjdCA9IG51bGw7XG4gICAgaWYgKG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdCkge1xuICAgICAgb3JpZ2luYWxQYXJzZU9iamVjdCA9IG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdC50b0pTT04oKTtcbiAgICB9XG4gICAgY29uc3QgY2xhc3NMZXZlbFBlcm1pc3Npb25zID0gbWVzc2FnZS5jbGFzc0xldmVsUGVybWlzc2lvbnM7XG4gICAgbGV0IGN1cnJlbnRQYXJzZU9iamVjdCA9IG1lc3NhZ2UuY3VycmVudFBhcnNlT2JqZWN0LnRvSlNPTigpO1xuICAgIGNvbnN0IGNsYXNzTmFtZSA9IGN1cnJlbnRQYXJzZU9iamVjdC5jbGFzc05hbWU7XG4gICAgbG9nZ2VyLnZlcmJvc2UoJ0NsYXNzTmFtZTogJXMgfCBPYmplY3RJZDogJXMnLCBjbGFzc05hbWUsIGN1cnJlbnRQYXJzZU9iamVjdC5pZCk7XG4gICAgbG9nZ2VyLnZlcmJvc2UoJ0N1cnJlbnQgY2xpZW50IG51bWJlciA6ICVkJywgdGhpcy5jbGllbnRzLnNpemUpO1xuXG4gICAgY29uc3QgY2xhc3NTdWJzY3JpcHRpb25zID0gdGhpcy5zdWJzY3JpcHRpb25zLmdldChjbGFzc05hbWUpO1xuICAgIGlmICh0eXBlb2YgY2xhc3NTdWJzY3JpcHRpb25zID09PSAndW5kZWZpbmVkJykge1xuICAgICAgbG9nZ2VyLmRlYnVnKCdDYW4gbm90IGZpbmQgc3Vic2NyaXB0aW9ucyB1bmRlciB0aGlzIGNsYXNzICcgKyBjbGFzc05hbWUpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHN1YnNjcmlwdGlvbiBvZiBjbGFzc1N1YnNjcmlwdGlvbnMudmFsdWVzKCkpIHtcbiAgICAgIGNvbnN0IGlzT3JpZ2luYWxTdWJzY3JpcHRpb25NYXRjaGVkID0gdGhpcy5fbWF0Y2hlc1N1YnNjcmlwdGlvbihcbiAgICAgICAgb3JpZ2luYWxQYXJzZU9iamVjdCxcbiAgICAgICAgc3Vic2NyaXB0aW9uXG4gICAgICApO1xuICAgICAgY29uc3QgaXNDdXJyZW50U3Vic2NyaXB0aW9uTWF0Y2hlZCA9IHRoaXMuX21hdGNoZXNTdWJzY3JpcHRpb24oXG4gICAgICAgIGN1cnJlbnRQYXJzZU9iamVjdCxcbiAgICAgICAgc3Vic2NyaXB0aW9uXG4gICAgICApO1xuICAgICAgZm9yIChjb25zdCBbY2xpZW50SWQsIHJlcXVlc3RJZHNdIG9mIF8uZW50cmllcyhzdWJzY3JpcHRpb24uY2xpZW50UmVxdWVzdElkcykpIHtcbiAgICAgICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRzLmdldChjbGllbnRJZCk7XG4gICAgICAgIGlmICh0eXBlb2YgY2xpZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3QgcmVxdWVzdElkIG9mIHJlcXVlc3RJZHMpIHtcbiAgICAgICAgICAvLyBTZXQgb3JpZ25hbCBQYXJzZU9iamVjdCBBQ0wgY2hlY2tpbmcgcHJvbWlzZSwgaWYgdGhlIG9iamVjdCBkb2VzIG5vdCBtYXRjaFxuICAgICAgICAgIC8vIHN1YnNjcmlwdGlvbiwgd2UgZG8gbm90IG5lZWQgdG8gY2hlY2sgQUNMXG4gICAgICAgICAgbGV0IG9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlO1xuICAgICAgICAgIGlmICghaXNPcmlnaW5hbFN1YnNjcmlwdGlvbk1hdGNoZWQpIHtcbiAgICAgICAgICAgIG9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbGV0IG9yaWdpbmFsQUNMO1xuICAgICAgICAgICAgaWYgKG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdCkge1xuICAgICAgICAgICAgICBvcmlnaW5hbEFDTCA9IG1lc3NhZ2Uub3JpZ2luYWxQYXJzZU9iamVjdC5nZXRBQ0woKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG9yaWdpbmFsQUNMQ2hlY2tpbmdQcm9taXNlID0gdGhpcy5fbWF0Y2hlc0FDTChvcmlnaW5hbEFDTCwgY2xpZW50LCByZXF1ZXN0SWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBTZXQgY3VycmVudCBQYXJzZU9iamVjdCBBQ0wgY2hlY2tpbmcgcHJvbWlzZSwgaWYgdGhlIG9iamVjdCBkb2VzIG5vdCBtYXRjaFxuICAgICAgICAgIC8vIHN1YnNjcmlwdGlvbiwgd2UgZG8gbm90IG5lZWQgdG8gY2hlY2sgQUNMXG4gICAgICAgICAgbGV0IGN1cnJlbnRBQ0xDaGVja2luZ1Byb21pc2U7XG4gICAgICAgICAgbGV0IHJlcyA9IHt9O1xuICAgICAgICAgIGlmICghaXNDdXJyZW50U3Vic2NyaXB0aW9uTWF0Y2hlZCkge1xuICAgICAgICAgICAgY3VycmVudEFDTENoZWNraW5nUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRBQ0wgPSBtZXNzYWdlLmN1cnJlbnRQYXJzZU9iamVjdC5nZXRBQ0woKTtcbiAgICAgICAgICAgIGN1cnJlbnRBQ0xDaGVja2luZ1Byb21pc2UgPSB0aGlzLl9tYXRjaGVzQUNMKGN1cnJlbnRBQ0wsIGNsaWVudCwgcmVxdWVzdElkKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3Qgb3AgPSB0aGlzLl9nZXRDTFBPcGVyYXRpb24oc3Vic2NyaXB0aW9uLnF1ZXJ5KTtcbiAgICAgICAgICB0aGlzLl9tYXRjaGVzQ0xQKGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgbWVzc2FnZS5jdXJyZW50UGFyc2VPYmplY3QsIGNsaWVudCwgcmVxdWVzdElkLCBvcClcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtvcmlnaW5hbEFDTENoZWNraW5nUHJvbWlzZSwgY3VycmVudEFDTENoZWNraW5nUHJvbWlzZV0pO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKChbaXNPcmlnaW5hbE1hdGNoZWQsIGlzQ3VycmVudE1hdGNoZWRdKSA9PiB7XG4gICAgICAgICAgICAgIGxvZ2dlci52ZXJib3NlKFxuICAgICAgICAgICAgICAgICdPcmlnaW5hbCAlaiB8IEN1cnJlbnQgJWogfCBNYXRjaDogJXMsICVzLCAlcywgJXMgfCBRdWVyeTogJXMnLFxuICAgICAgICAgICAgICAgIG9yaWdpbmFsUGFyc2VPYmplY3QsXG4gICAgICAgICAgICAgICAgY3VycmVudFBhcnNlT2JqZWN0LFxuICAgICAgICAgICAgICAgIGlzT3JpZ2luYWxTdWJzY3JpcHRpb25NYXRjaGVkLFxuICAgICAgICAgICAgICAgIGlzQ3VycmVudFN1YnNjcmlwdGlvbk1hdGNoZWQsXG4gICAgICAgICAgICAgICAgaXNPcmlnaW5hbE1hdGNoZWQsXG4gICAgICAgICAgICAgICAgaXNDdXJyZW50TWF0Y2hlZCxcbiAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb24uaGFzaFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAvLyBEZWNpZGUgZXZlbnQgdHlwZVxuICAgICAgICAgICAgICBsZXQgdHlwZTtcbiAgICAgICAgICAgICAgaWYgKGlzT3JpZ2luYWxNYXRjaGVkICYmIGlzQ3VycmVudE1hdGNoZWQpIHtcbiAgICAgICAgICAgICAgICB0eXBlID0gJ3VwZGF0ZSc7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNPcmlnaW5hbE1hdGNoZWQgJiYgIWlzQ3VycmVudE1hdGNoZWQpIHtcbiAgICAgICAgICAgICAgICB0eXBlID0gJ2xlYXZlJztcbiAgICAgICAgICAgICAgfSBlbHNlIGlmICghaXNPcmlnaW5hbE1hdGNoZWQgJiYgaXNDdXJyZW50TWF0Y2hlZCkge1xuICAgICAgICAgICAgICAgIGlmIChvcmlnaW5hbFBhcnNlT2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgICB0eXBlID0gJ2VudGVyJztcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgdHlwZSA9ICdjcmVhdGUnO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBtZXNzYWdlLmV2ZW50ID0gdHlwZTtcbiAgICAgICAgICAgICAgcmVzID0ge1xuICAgICAgICAgICAgICAgIGV2ZW50OiB0eXBlLFxuICAgICAgICAgICAgICAgIHNlc3Npb25Ub2tlbjogY2xpZW50LnNlc3Npb25Ub2tlbixcbiAgICAgICAgICAgICAgICBvYmplY3Q6IGN1cnJlbnRQYXJzZU9iamVjdCxcbiAgICAgICAgICAgICAgICBvcmlnaW5hbDogb3JpZ2luYWxQYXJzZU9iamVjdCxcbiAgICAgICAgICAgICAgICBjbGllbnRzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb25zOiB0aGlzLnN1YnNjcmlwdGlvbnMuc2l6ZSxcbiAgICAgICAgICAgICAgICB1c2VNYXN0ZXJLZXk6IGNsaWVudC5oYXNNYXN0ZXJLZXksXG4gICAgICAgICAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IGNsaWVudC5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgICAgICAgICBzZW5kRXZlbnQ6IHRydWUsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIHJldHVybiBtYXliZVJ1bkFmdGVyRXZlbnRUcmlnZ2VyKCdhZnRlckV2ZW50JywgY2xhc3NOYW1lLCByZXMpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFyZXMuc2VuZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChyZXMub2JqZWN0ICYmIHR5cGVvZiByZXMub2JqZWN0LnRvSlNPTiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgY3VycmVudFBhcnNlT2JqZWN0ID0gcmVzLm9iamVjdC50b0pTT04oKTtcbiAgICAgICAgICAgICAgICAgIGN1cnJlbnRQYXJzZU9iamVjdC5jbGFzc05hbWUgPSByZXMub2JqZWN0LmNsYXNzTmFtZSB8fCBjbGFzc05hbWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHJlcy5vcmlnaW5hbCAmJiB0eXBlb2YgcmVzLm9yaWdpbmFsLnRvSlNPTiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgb3JpZ2luYWxQYXJzZU9iamVjdCA9IHJlcy5vcmlnaW5hbC50b0pTT04oKTtcbiAgICAgICAgICAgICAgICAgIG9yaWdpbmFsUGFyc2VPYmplY3QuY2xhc3NOYW1lID0gcmVzLm9yaWdpbmFsLmNsYXNzTmFtZSB8fCBjbGFzc05hbWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGZ1bmN0aW9uTmFtZSA9XG4gICAgICAgICAgICAgICAgICAncHVzaCcgKyBtZXNzYWdlLmV2ZW50LmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgbWVzc2FnZS5ldmVudC5zbGljZSgxKTtcbiAgICAgICAgICAgICAgICBpZiAoY2xpZW50W2Z1bmN0aW9uTmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgIGNsaWVudFtmdW5jdGlvbk5hbWVdKHJlcXVlc3RJZCwgY3VycmVudFBhcnNlT2JqZWN0LCBvcmlnaW5hbFBhcnNlT2JqZWN0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICBDbGllbnQucHVzaEVycm9yKFxuICAgICAgICAgICAgICAgICAgY2xpZW50LnBhcnNlV2ViU29ja2V0LFxuICAgICAgICAgICAgICAgICAgZXJyb3IuY29kZSB8fCAxNDEsXG4gICAgICAgICAgICAgICAgICBlcnJvci5tZXNzYWdlIHx8IGVycm9yLFxuICAgICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICAgICByZXF1ZXN0SWRcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgICAgICAgICAgIGBGYWlsZWQgcnVubmluZyBhZnRlckxpdmVRdWVyeUV2ZW50IG9uIGNsYXNzICR7Y2xhc3NOYW1lfSBmb3IgZXZlbnQgJHtyZXMuZXZlbnR9IHdpdGggc2Vzc2lvbiAke3Jlcy5zZXNzaW9uVG9rZW59IHdpdGg6XFxuIEVycm9yOiBgICtcbiAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkoZXJyb3IpXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIF9vbkNvbm5lY3QocGFyc2VXZWJzb2NrZXQ6IGFueSk6IHZvaWQge1xuICAgIHBhcnNlV2Vic29ja2V0Lm9uKCdtZXNzYWdlJywgcmVxdWVzdCA9PiB7XG4gICAgICBpZiAodHlwZW9mIHJlcXVlc3QgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmVxdWVzdCA9IEpTT04ucGFyc2UocmVxdWVzdCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoJ3VuYWJsZSB0byBwYXJzZSByZXF1ZXN0JywgcmVxdWVzdCwgZSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBsb2dnZXIudmVyYm9zZSgnUmVxdWVzdDogJWonLCByZXF1ZXN0KTtcblxuICAgICAgLy8gQ2hlY2sgd2hldGhlciB0aGlzIHJlcXVlc3QgaXMgYSB2YWxpZCByZXF1ZXN0LCByZXR1cm4gZXJyb3IgZGlyZWN0bHkgaWYgbm90XG4gICAgICBpZiAoXG4gICAgICAgICF0djQudmFsaWRhdGUocmVxdWVzdCwgUmVxdWVzdFNjaGVtYVsnZ2VuZXJhbCddKSB8fFxuICAgICAgICAhdHY0LnZhbGlkYXRlKHJlcXVlc3QsIFJlcXVlc3RTY2hlbWFbcmVxdWVzdC5vcF0pXG4gICAgICApIHtcbiAgICAgICAgQ2xpZW50LnB1c2hFcnJvcihwYXJzZVdlYnNvY2tldCwgMSwgdHY0LmVycm9yLm1lc3NhZ2UpO1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ0Nvbm5lY3QgbWVzc2FnZSBlcnJvciAlcycsIHR2NC5lcnJvci5tZXNzYWdlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBzd2l0Y2ggKHJlcXVlc3Qub3ApIHtcbiAgICAgICAgY2FzZSAnY29ubmVjdCc6XG4gICAgICAgICAgdGhpcy5faGFuZGxlQ29ubmVjdChwYXJzZVdlYnNvY2tldCwgcmVxdWVzdCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ3N1YnNjcmliZSc6XG4gICAgICAgICAgdGhpcy5faGFuZGxlU3Vic2NyaWJlKHBhcnNlV2Vic29ja2V0LCByZXF1ZXN0KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAndXBkYXRlJzpcbiAgICAgICAgICB0aGlzLl9oYW5kbGVVcGRhdGVTdWJzY3JpcHRpb24ocGFyc2VXZWJzb2NrZXQsIHJlcXVlc3QpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICd1bnN1YnNjcmliZSc6XG4gICAgICAgICAgdGhpcy5faGFuZGxlVW5zdWJzY3JpYmUocGFyc2VXZWJzb2NrZXQsIHJlcXVlc3QpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIENsaWVudC5wdXNoRXJyb3IocGFyc2VXZWJzb2NrZXQsIDMsICdHZXQgdW5rbm93biBvcGVyYXRpb24nKTtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0dldCB1bmtub3duIG9wZXJhdGlvbicsIHJlcXVlc3Qub3ApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcGFyc2VXZWJzb2NrZXQub24oJ2Rpc2Nvbm5lY3QnLCAoKSA9PiB7XG4gICAgICBsb2dnZXIuaW5mbyhgQ2xpZW50IGRpc2Nvbm5lY3Q6ICR7cGFyc2VXZWJzb2NrZXQuY2xpZW50SWR9YCk7XG4gICAgICBjb25zdCBjbGllbnRJZCA9IHBhcnNlV2Vic29ja2V0LmNsaWVudElkO1xuICAgICAgaWYgKCF0aGlzLmNsaWVudHMuaGFzKGNsaWVudElkKSkge1xuICAgICAgICBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzKHtcbiAgICAgICAgICBldmVudDogJ3dzX2Rpc2Nvbm5lY3RfZXJyb3InLFxuICAgICAgICAgIGNsaWVudHM6IHRoaXMuY2xpZW50cy5zaXplLFxuICAgICAgICAgIHN1YnNjcmlwdGlvbnM6IHRoaXMuc3Vic2NyaXB0aW9ucy5zaXplLFxuICAgICAgICAgIGVycm9yOiBgVW5hYmxlIHRvIGZpbmQgY2xpZW50ICR7Y2xpZW50SWR9YCxcbiAgICAgICAgfSk7XG4gICAgICAgIGxvZ2dlci5lcnJvcihgQ2FuIG5vdCBmaW5kIGNsaWVudCAke2NsaWVudElkfSBvbiBkaXNjb25uZWN0YCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gRGVsZXRlIGNsaWVudFxuICAgICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRzLmdldChjbGllbnRJZCk7XG4gICAgICB0aGlzLmNsaWVudHMuZGVsZXRlKGNsaWVudElkKTtcblxuICAgICAgLy8gRGVsZXRlIGNsaWVudCBmcm9tIHN1YnNjcmlwdGlvbnNcbiAgICAgIGZvciAoY29uc3QgW3JlcXVlc3RJZCwgc3Vic2NyaXB0aW9uSW5mb10gb2YgXy5lbnRyaWVzKGNsaWVudC5zdWJzY3JpcHRpb25JbmZvcykpIHtcbiAgICAgICAgY29uc3Qgc3Vic2NyaXB0aW9uID0gc3Vic2NyaXB0aW9uSW5mby5zdWJzY3JpcHRpb247XG4gICAgICAgIHN1YnNjcmlwdGlvbi5kZWxldGVDbGllbnRTdWJzY3JpcHRpb24oY2xpZW50SWQsIHJlcXVlc3RJZCk7XG5cbiAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gY2xpZW50IHdoaWNoIGlzIHN1YnNjcmliaW5nIHRoaXMgc3Vic2NyaXB0aW9uLCByZW1vdmUgaXQgZnJvbSBzdWJzY3JpcHRpb25zXG4gICAgICAgIGNvbnN0IGNsYXNzU3Vic2NyaXB0aW9ucyA9IHRoaXMuc3Vic2NyaXB0aW9ucy5nZXQoc3Vic2NyaXB0aW9uLmNsYXNzTmFtZSk7XG4gICAgICAgIGlmICghc3Vic2NyaXB0aW9uLmhhc1N1YnNjcmliaW5nQ2xpZW50KCkpIHtcbiAgICAgICAgICBjbGFzc1N1YnNjcmlwdGlvbnMuZGVsZXRlKHN1YnNjcmlwdGlvbi5oYXNoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBJZiB0aGVyZSBpcyBubyBzdWJzY3JpcHRpb25zIHVuZGVyIHRoaXMgY2xhc3MsIHJlbW92ZSBpdCBmcm9tIHN1YnNjcmlwdGlvbnNcbiAgICAgICAgaWYgKGNsYXNzU3Vic2NyaXB0aW9ucy5zaXplID09PSAwKSB7XG4gICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zLmRlbGV0ZShzdWJzY3JpcHRpb24uY2xhc3NOYW1lKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBsb2dnZXIudmVyYm9zZSgnQ3VycmVudCBjbGllbnRzICVkJywgdGhpcy5jbGllbnRzLnNpemUpO1xuICAgICAgbG9nZ2VyLnZlcmJvc2UoJ0N1cnJlbnQgc3Vic2NyaXB0aW9ucyAlZCcsIHRoaXMuc3Vic2NyaXB0aW9ucy5zaXplKTtcbiAgICAgIHJ1bkxpdmVRdWVyeUV2ZW50SGFuZGxlcnMoe1xuICAgICAgICBldmVudDogJ3dzX2Rpc2Nvbm5lY3QnLFxuICAgICAgICBjbGllbnRzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgICAgIHVzZU1hc3RlcktleTogY2xpZW50Lmhhc01hc3RlcktleSxcbiAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IGNsaWVudC5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgc2Vzc2lvblRva2VuOiBjbGllbnQuc2Vzc2lvblRva2VuLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzKHtcbiAgICAgIGV2ZW50OiAnd3NfY29ubmVjdCcsXG4gICAgICBjbGllbnRzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgIHN1YnNjcmlwdGlvbnM6IHRoaXMuc3Vic2NyaXB0aW9ucy5zaXplLFxuICAgIH0pO1xuICB9XG5cbiAgX21hdGNoZXNTdWJzY3JpcHRpb24ocGFyc2VPYmplY3Q6IGFueSwgc3Vic2NyaXB0aW9uOiBhbnkpOiBib29sZWFuIHtcbiAgICAvLyBPYmplY3QgaXMgdW5kZWZpbmVkIG9yIG51bGwsIG5vdCBtYXRjaFxuICAgIGlmICghcGFyc2VPYmplY3QpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoZXNRdWVyeShwYXJzZU9iamVjdCwgc3Vic2NyaXB0aW9uLnF1ZXJ5KTtcbiAgfVxuXG4gIGdldEF1dGhGb3JTZXNzaW9uVG9rZW4oc2Vzc2lvblRva2VuOiA/c3RyaW5nKTogUHJvbWlzZTx7IGF1dGg6ID9BdXRoLCB1c2VySWQ6ID9zdHJpbmcgfT4ge1xuICAgIGlmICghc2Vzc2lvblRva2VuKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgICB9XG4gICAgY29uc3QgZnJvbUNhY2hlID0gdGhpcy5hdXRoQ2FjaGUuZ2V0KHNlc3Npb25Ub2tlbik7XG4gICAgaWYgKGZyb21DYWNoZSkge1xuICAgICAgcmV0dXJuIGZyb21DYWNoZTtcbiAgICB9XG4gICAgY29uc3QgYXV0aFByb21pc2UgPSBnZXRBdXRoRm9yU2Vzc2lvblRva2VuKHtcbiAgICAgIGNhY2hlQ29udHJvbGxlcjogdGhpcy5jYWNoZUNvbnRyb2xsZXIsXG4gICAgICBzZXNzaW9uVG9rZW46IHNlc3Npb25Ub2tlbixcbiAgICB9KVxuICAgICAgLnRoZW4oYXV0aCA9PiB7XG4gICAgICAgIHJldHVybiB7IGF1dGgsIHVzZXJJZDogYXV0aCAmJiBhdXRoLnVzZXIgJiYgYXV0aC51c2VyLmlkIH07XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgLy8gVGhlcmUgd2FzIGFuIGVycm9yIHdpdGggdGhlIHNlc3Npb24gdG9rZW5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0ge307XG4gICAgICAgIGlmIChlcnJvciAmJiBlcnJvci5jb2RlID09PSBQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4pIHtcbiAgICAgICAgICByZXN1bHQuZXJyb3IgPSBlcnJvcjtcbiAgICAgICAgICB0aGlzLmF1dGhDYWNoZS5zZXQoc2Vzc2lvblRva2VuLCBQcm9taXNlLnJlc29sdmUocmVzdWx0KSwgdGhpcy5jb25maWcuY2FjaGVUaW1lb3V0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmF1dGhDYWNoZS5kZWwoc2Vzc2lvblRva2VuKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSk7XG4gICAgdGhpcy5hdXRoQ2FjaGUuc2V0KHNlc3Npb25Ub2tlbiwgYXV0aFByb21pc2UpO1xuICAgIHJldHVybiBhdXRoUHJvbWlzZTtcbiAgfVxuXG4gIGFzeW5jIF9tYXRjaGVzQ0xQKFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogP2FueSxcbiAgICBvYmplY3Q6IGFueSxcbiAgICBjbGllbnQ6IGFueSxcbiAgICByZXF1ZXN0SWQ6IG51bWJlcixcbiAgICBvcDogc3RyaW5nXG4gICk6IGFueSB7XG4gICAgLy8gdHJ5IHRvIG1hdGNoIG9uIHVzZXIgZmlyc3QsIGxlc3MgZXhwZW5zaXZlIHRoYW4gd2l0aCByb2xlc1xuICAgIGNvbnN0IHN1YnNjcmlwdGlvbkluZm8gPSBjbGllbnQuZ2V0U3Vic2NyaXB0aW9uSW5mbyhyZXF1ZXN0SWQpO1xuICAgIGNvbnN0IGFjbEdyb3VwID0gWycqJ107XG4gICAgbGV0IHVzZXJJZDtcbiAgICBpZiAodHlwZW9mIHN1YnNjcmlwdGlvbkluZm8gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBjb25zdCB7IHVzZXJJZCB9ID0gYXdhaXQgdGhpcy5nZXRBdXRoRm9yU2Vzc2lvblRva2VuKHN1YnNjcmlwdGlvbkluZm8uc2Vzc2lvblRva2VuKTtcbiAgICAgIGlmICh1c2VySWQpIHtcbiAgICAgICAgYWNsR3JvdXAucHVzaCh1c2VySWQpO1xuICAgICAgfVxuICAgIH1cbiAgICB0cnkge1xuICAgICAgYXdhaXQgU2NoZW1hQ29udHJvbGxlci52YWxpZGF0ZVBlcm1pc3Npb24oXG4gICAgICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgICAgb2JqZWN0LmNsYXNzTmFtZSxcbiAgICAgICAgYWNsR3JvdXAsXG4gICAgICAgIG9wXG4gICAgICApO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgbG9nZ2VyLnZlcmJvc2UoYEZhaWxlZCBtYXRjaGluZyBDTFAgZm9yICR7b2JqZWN0LmlkfSAke3VzZXJJZH0gJHtlfWApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICAvLyBUT0RPOiBoYW5kbGUgcm9sZXMgcGVybWlzc2lvbnNcbiAgICAvLyBPYmplY3Qua2V5cyhjbGFzc0xldmVsUGVybWlzc2lvbnMpLmZvckVhY2goKGtleSkgPT4ge1xuICAgIC8vICAgY29uc3QgcGVybSA9IGNsYXNzTGV2ZWxQZXJtaXNzaW9uc1trZXldO1xuICAgIC8vICAgT2JqZWN0LmtleXMocGVybSkuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgLy8gICAgIGlmIChrZXkuaW5kZXhPZigncm9sZScpKVxuICAgIC8vICAgfSk7XG4gICAgLy8gfSlcbiAgICAvLyAvLyBpdCdzIHJlamVjdGVkIGhlcmUsIGNoZWNrIHRoZSByb2xlc1xuICAgIC8vIHZhciByb2xlc1F1ZXJ5ID0gbmV3IFBhcnNlLlF1ZXJ5KFBhcnNlLlJvbGUpO1xuICAgIC8vIHJvbGVzUXVlcnkuZXF1YWxUbyhcInVzZXJzXCIsIHVzZXIpO1xuICAgIC8vIHJldHVybiByb2xlc1F1ZXJ5LmZpbmQoe3VzZU1hc3RlcktleTp0cnVlfSk7XG4gIH1cblxuICBfZ2V0Q0xQT3BlcmF0aW9uKHF1ZXJ5OiBhbnkpIHtcbiAgICByZXR1cm4gdHlwZW9mIHF1ZXJ5ID09PSAnb2JqZWN0JyAmJlxuICAgICAgT2JqZWN0LmtleXMocXVlcnkpLmxlbmd0aCA9PSAxICYmXG4gICAgICB0eXBlb2YgcXVlcnkub2JqZWN0SWQgPT09ICdzdHJpbmcnXG4gICAgICA/ICdnZXQnXG4gICAgICA6ICdmaW5kJztcbiAgfVxuXG4gIGFzeW5jIF92ZXJpZnlBQ0woYWNsOiBhbnksIHRva2VuOiBzdHJpbmcpIHtcbiAgICBpZiAoIXRva2VuKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgeyBhdXRoLCB1c2VySWQgfSA9IGF3YWl0IHRoaXMuZ2V0QXV0aEZvclNlc3Npb25Ub2tlbih0b2tlbik7XG5cbiAgICAvLyBHZXR0aW5nIHRoZSBzZXNzaW9uIHRva2VuIGZhaWxlZFxuICAgIC8vIFRoaXMgbWVhbnMgdGhhdCBubyBhZGRpdGlvbmFsIGF1dGggaXMgYXZhaWxhYmxlXG4gICAgLy8gQXQgdGhpcyBwb2ludCwganVzdCBiYWlsIG91dCBhcyBubyBhZGRpdGlvbmFsIHZpc2liaWxpdHkgY2FuIGJlIGluZmVycmVkLlxuICAgIGlmICghYXV0aCB8fCAhdXNlcklkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IGlzU3Vic2NyaXB0aW9uU2Vzc2lvblRva2VuTWF0Y2hlZCA9IGFjbC5nZXRSZWFkQWNjZXNzKHVzZXJJZCk7XG4gICAgaWYgKGlzU3Vic2NyaXB0aW9uU2Vzc2lvblRva2VuTWF0Y2hlZCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgaWYgdGhlIHVzZXIgaGFzIGFueSByb2xlcyB0aGF0IG1hdGNoIHRoZSBBQ0xcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgIC50aGVuKGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8gUmVzb2x2ZSBmYWxzZSByaWdodCBhd2F5IGlmIHRoZSBhY2wgZG9lc24ndCBoYXZlIGFueSByb2xlc1xuICAgICAgICBjb25zdCBhY2xfaGFzX3JvbGVzID0gT2JqZWN0LmtleXMoYWNsLnBlcm1pc3Npb25zQnlJZCkuc29tZShrZXkgPT4ga2V5LnN0YXJ0c1dpdGgoJ3JvbGU6JykpO1xuICAgICAgICBpZiAoIWFjbF9oYXNfcm9sZXMpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByb2xlTmFtZXMgPSBhd2FpdCBhdXRoLmdldFVzZXJSb2xlcygpO1xuICAgICAgICAvLyBGaW5hbGx5LCBzZWUgaWYgYW55IG9mIHRoZSB1c2VyJ3Mgcm9sZXMgYWxsb3cgdGhlbSByZWFkIGFjY2Vzc1xuICAgICAgICBmb3IgKGNvbnN0IHJvbGUgb2Ygcm9sZU5hbWVzKSB7XG4gICAgICAgICAgLy8gV2UgdXNlIGdldFJlYWRBY2Nlc3MgYXMgYHJvbGVgIGlzIGluIHRoZSBmb3JtIGByb2xlOnJvbGVOYW1lYFxuICAgICAgICAgIGlmIChhY2wuZ2V0UmVhZEFjY2Vzcyhyb2xlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKCkgPT4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIF9tYXRjaGVzQUNMKGFjbDogYW55LCBjbGllbnQ6IGFueSwgcmVxdWVzdElkOiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICAvLyBSZXR1cm4gdHJ1ZSBkaXJlY3RseSBpZiBBQ0wgaXNuJ3QgcHJlc2VudCwgQUNMIGlzIHB1YmxpYyByZWFkLCBvciBjbGllbnQgaGFzIG1hc3RlciBrZXlcbiAgICBpZiAoIWFjbCB8fCBhY2wuZ2V0UHVibGljUmVhZEFjY2VzcygpIHx8IGNsaWVudC5oYXNNYXN0ZXJLZXkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvLyBDaGVjayBzdWJzY3JpcHRpb24gc2Vzc2lvblRva2VuIG1hdGNoZXMgQUNMIGZpcnN0XG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uSW5mbyA9IGNsaWVudC5nZXRTdWJzY3JpcHRpb25JbmZvKHJlcXVlc3RJZCk7XG4gICAgaWYgKHR5cGVvZiBzdWJzY3JpcHRpb25JbmZvID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IHN1YnNjcmlwdGlvblRva2VuID0gc3Vic2NyaXB0aW9uSW5mby5zZXNzaW9uVG9rZW47XG4gICAgY29uc3QgY2xpZW50U2Vzc2lvblRva2VuID0gY2xpZW50LnNlc3Npb25Ub2tlbjtcblxuICAgIGlmIChhd2FpdCB0aGlzLl92ZXJpZnlBQ0woYWNsLCBzdWJzY3JpcHRpb25Ub2tlbikpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmIChhd2FpdCB0aGlzLl92ZXJpZnlBQ0woYWNsLCBjbGllbnRTZXNzaW9uVG9rZW4pKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBhc3luYyBfaGFuZGxlQ29ubmVjdChwYXJzZVdlYnNvY2tldDogYW55LCByZXF1ZXN0OiBhbnkpOiBhbnkge1xuICAgIGlmICghdGhpcy5fdmFsaWRhdGVLZXlzKHJlcXVlc3QsIHRoaXMua2V5UGFpcnMpKSB7XG4gICAgICBDbGllbnQucHVzaEVycm9yKHBhcnNlV2Vic29ja2V0LCA0LCAnS2V5IGluIHJlcXVlc3QgaXMgbm90IHZhbGlkJyk7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0tleSBpbiByZXF1ZXN0IGlzIG5vdCB2YWxpZCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBoYXNNYXN0ZXJLZXkgPSB0aGlzLl9oYXNNYXN0ZXJLZXkocmVxdWVzdCwgdGhpcy5rZXlQYWlycyk7XG4gICAgY29uc3QgY2xpZW50SWQgPSB1dWlkdjQoKTtcbiAgICBjb25zdCBjbGllbnQgPSBuZXcgQ2xpZW50KFxuICAgICAgY2xpZW50SWQsXG4gICAgICBwYXJzZVdlYnNvY2tldCxcbiAgICAgIGhhc01hc3RlcktleSxcbiAgICAgIHJlcXVlc3Quc2Vzc2lvblRva2VuLFxuICAgICAgcmVxdWVzdC5pbnN0YWxsYXRpb25JZFxuICAgICk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlcSA9IHtcbiAgICAgICAgY2xpZW50LFxuICAgICAgICBldmVudDogJ2Nvbm5lY3QnLFxuICAgICAgICBjbGllbnRzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgICAgIHNlc3Npb25Ub2tlbjogcmVxdWVzdC5zZXNzaW9uVG9rZW4sXG4gICAgICAgIHVzZU1hc3RlcktleTogY2xpZW50Lmhhc01hc3RlcktleSxcbiAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IHJlcXVlc3QuaW5zdGFsbGF0aW9uSWQsXG4gICAgICB9O1xuICAgICAgYXdhaXQgbWF5YmVSdW5Db25uZWN0VHJpZ2dlcignYmVmb3JlQ29ubmVjdCcsIHJlcSk7XG4gICAgICBwYXJzZVdlYnNvY2tldC5jbGllbnRJZCA9IGNsaWVudElkO1xuICAgICAgdGhpcy5jbGllbnRzLnNldChwYXJzZVdlYnNvY2tldC5jbGllbnRJZCwgY2xpZW50KTtcbiAgICAgIGxvZ2dlci5pbmZvKGBDcmVhdGUgbmV3IGNsaWVudDogJHtwYXJzZVdlYnNvY2tldC5jbGllbnRJZH1gKTtcbiAgICAgIGNsaWVudC5wdXNoQ29ubmVjdCgpO1xuICAgICAgcnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyhyZXEpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBDbGllbnQucHVzaEVycm9yKHBhcnNlV2Vic29ja2V0LCBlcnJvci5jb2RlIHx8IDE0MSwgZXJyb3IubWVzc2FnZSB8fCBlcnJvciwgZmFsc2UpO1xuICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICBgRmFpbGVkIHJ1bm5pbmcgYmVmb3JlQ29ubmVjdCBmb3Igc2Vzc2lvbiAke3JlcXVlc3Quc2Vzc2lvblRva2VufSB3aXRoOlxcbiBFcnJvcjogYCArXG4gICAgICAgICAgSlNPTi5zdHJpbmdpZnkoZXJyb3IpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIF9oYXNNYXN0ZXJLZXkocmVxdWVzdDogYW55LCB2YWxpZEtleVBhaXJzOiBhbnkpOiBib29sZWFuIHtcbiAgICBpZiAoIXZhbGlkS2V5UGFpcnMgfHwgdmFsaWRLZXlQYWlycy5zaXplID09IDAgfHwgIXZhbGlkS2V5UGFpcnMuaGFzKCdtYXN0ZXJLZXknKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAoIXJlcXVlc3QgfHwgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChyZXF1ZXN0LCAnbWFzdGVyS2V5JykpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcXVlc3QubWFzdGVyS2V5ID09PSB2YWxpZEtleVBhaXJzLmdldCgnbWFzdGVyS2V5Jyk7XG4gIH1cblxuICBfdmFsaWRhdGVLZXlzKHJlcXVlc3Q6IGFueSwgdmFsaWRLZXlQYWlyczogYW55KTogYm9vbGVhbiB7XG4gICAgaWYgKCF2YWxpZEtleVBhaXJzIHx8IHZhbGlkS2V5UGFpcnMuc2l6ZSA9PSAwKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgbGV0IGlzVmFsaWQgPSBmYWxzZTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHNlY3JldF0gb2YgdmFsaWRLZXlQYWlycykge1xuICAgICAgaWYgKCFyZXF1ZXN0W2tleV0gfHwgcmVxdWVzdFtrZXldICE9PSBzZWNyZXQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpc1ZhbGlkID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gaXNWYWxpZDtcbiAgfVxuXG4gIGFzeW5jIF9oYW5kbGVTdWJzY3JpYmUocGFyc2VXZWJzb2NrZXQ6IGFueSwgcmVxdWVzdDogYW55KTogYW55IHtcbiAgICAvLyBJZiB3ZSBjYW4gbm90IGZpbmQgdGhpcyBjbGllbnQsIHJldHVybiBlcnJvciB0byBjbGllbnRcbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChwYXJzZVdlYnNvY2tldCwgJ2NsaWVudElkJykpIHtcbiAgICAgIENsaWVudC5wdXNoRXJyb3IoXG4gICAgICAgIHBhcnNlV2Vic29ja2V0LFxuICAgICAgICAyLFxuICAgICAgICAnQ2FuIG5vdCBmaW5kIHRoaXMgY2xpZW50LCBtYWtlIHN1cmUgeW91IGNvbm5lY3QgdG8gc2VydmVyIGJlZm9yZSBzdWJzY3JpYmluZydcbiAgICAgICk7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0NhbiBub3QgZmluZCB0aGlzIGNsaWVudCwgbWFrZSBzdXJlIHlvdSBjb25uZWN0IHRvIHNlcnZlciBiZWZvcmUgc3Vic2NyaWJpbmcnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRzLmdldChwYXJzZVdlYnNvY2tldC5jbGllbnRJZCk7XG4gICAgY29uc3QgY2xhc3NOYW1lID0gcmVxdWVzdC5xdWVyeS5jbGFzc05hbWU7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IG1heWJlUnVuU3Vic2NyaWJlVHJpZ2dlcignYmVmb3JlU3Vic2NyaWJlJywgY2xhc3NOYW1lLCByZXF1ZXN0KTtcblxuICAgICAgLy8gR2V0IHN1YnNjcmlwdGlvbiBmcm9tIHN1YnNjcmlwdGlvbnMsIGNyZWF0ZSBvbmUgaWYgbmVjZXNzYXJ5XG4gICAgICBjb25zdCBzdWJzY3JpcHRpb25IYXNoID0gcXVlcnlIYXNoKHJlcXVlc3QucXVlcnkpO1xuICAgICAgLy8gQWRkIGNsYXNzTmFtZSB0byBzdWJzY3JpcHRpb25zIGlmIG5lY2Vzc2FyeVxuXG4gICAgICBpZiAoIXRoaXMuc3Vic2NyaXB0aW9ucy5oYXMoY2xhc3NOYW1lKSkge1xuICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbnMuc2V0KGNsYXNzTmFtZSwgbmV3IE1hcCgpKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNsYXNzU3Vic2NyaXB0aW9ucyA9IHRoaXMuc3Vic2NyaXB0aW9ucy5nZXQoY2xhc3NOYW1lKTtcbiAgICAgIGxldCBzdWJzY3JpcHRpb247XG4gICAgICBpZiAoY2xhc3NTdWJzY3JpcHRpb25zLmhhcyhzdWJzY3JpcHRpb25IYXNoKSkge1xuICAgICAgICBzdWJzY3JpcHRpb24gPSBjbGFzc1N1YnNjcmlwdGlvbnMuZ2V0KHN1YnNjcmlwdGlvbkhhc2gpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbihjbGFzc05hbWUsIHJlcXVlc3QucXVlcnkud2hlcmUsIHN1YnNjcmlwdGlvbkhhc2gpO1xuICAgICAgICBjbGFzc1N1YnNjcmlwdGlvbnMuc2V0KHN1YnNjcmlwdGlvbkhhc2gsIHN1YnNjcmlwdGlvbik7XG4gICAgICB9XG5cbiAgICAgIC8vIEFkZCBzdWJzY3JpcHRpb25JbmZvIHRvIGNsaWVudFxuICAgICAgY29uc3Qgc3Vic2NyaXB0aW9uSW5mbyA9IHtcbiAgICAgICAgc3Vic2NyaXB0aW9uOiBzdWJzY3JpcHRpb24sXG4gICAgICB9O1xuICAgICAgLy8gQWRkIHNlbGVjdGVkIGZpZWxkcywgc2Vzc2lvblRva2VuIGFuZCBpbnN0YWxsYXRpb25JZCBmb3IgdGhpcyBzdWJzY3JpcHRpb24gaWYgbmVjZXNzYXJ5XG4gICAgICBpZiAocmVxdWVzdC5xdWVyeS5maWVsZHMpIHtcbiAgICAgICAgc3Vic2NyaXB0aW9uSW5mby5maWVsZHMgPSByZXF1ZXN0LnF1ZXJ5LmZpZWxkcztcbiAgICAgIH1cbiAgICAgIGlmIChyZXF1ZXN0LnNlc3Npb25Ub2tlbikge1xuICAgICAgICBzdWJzY3JpcHRpb25JbmZvLnNlc3Npb25Ub2tlbiA9IHJlcXVlc3Quc2Vzc2lvblRva2VuO1xuICAgICAgfVxuICAgICAgY2xpZW50LmFkZFN1YnNjcmlwdGlvbkluZm8ocmVxdWVzdC5yZXF1ZXN0SWQsIHN1YnNjcmlwdGlvbkluZm8pO1xuXG4gICAgICAvLyBBZGQgY2xpZW50SWQgdG8gc3Vic2NyaXB0aW9uXG4gICAgICBzdWJzY3JpcHRpb24uYWRkQ2xpZW50U3Vic2NyaXB0aW9uKHBhcnNlV2Vic29ja2V0LmNsaWVudElkLCByZXF1ZXN0LnJlcXVlc3RJZCk7XG5cbiAgICAgIGNsaWVudC5wdXNoU3Vic2NyaWJlKHJlcXVlc3QucmVxdWVzdElkKTtcblxuICAgICAgbG9nZ2VyLnZlcmJvc2UoXG4gICAgICAgIGBDcmVhdGUgY2xpZW50ICR7cGFyc2VXZWJzb2NrZXQuY2xpZW50SWR9IG5ldyBzdWJzY3JpcHRpb246ICR7cmVxdWVzdC5yZXF1ZXN0SWR9YFxuICAgICAgKTtcbiAgICAgIGxvZ2dlci52ZXJib3NlKCdDdXJyZW50IGNsaWVudCBudW1iZXI6ICVkJywgdGhpcy5jbGllbnRzLnNpemUpO1xuICAgICAgcnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyh7XG4gICAgICAgIGNsaWVudCxcbiAgICAgICAgZXZlbnQ6ICdzdWJzY3JpYmUnLFxuICAgICAgICBjbGllbnRzOiB0aGlzLmNsaWVudHMuc2l6ZSxcbiAgICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgICAgIHNlc3Npb25Ub2tlbjogcmVxdWVzdC5zZXNzaW9uVG9rZW4sXG4gICAgICAgIHVzZU1hc3RlcktleTogY2xpZW50Lmhhc01hc3RlcktleSxcbiAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IGNsaWVudC5pbnN0YWxsYXRpb25JZCxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIENsaWVudC5wdXNoRXJyb3IocGFyc2VXZWJzb2NrZXQsIGUuY29kZSB8fCAxNDEsIGUubWVzc2FnZSB8fCBlLCBmYWxzZSwgcmVxdWVzdC5yZXF1ZXN0SWQpO1xuICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICBgRmFpbGVkIHJ1bm5pbmcgYmVmb3JlU3Vic2NyaWJlIG9uICR7Y2xhc3NOYW1lfSBmb3Igc2Vzc2lvbiAke3JlcXVlc3Quc2Vzc2lvblRva2VufSB3aXRoOlxcbiBFcnJvcjogYCArXG4gICAgICAgICAgSlNPTi5zdHJpbmdpZnkoZSlcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgX2hhbmRsZVVwZGF0ZVN1YnNjcmlwdGlvbihwYXJzZVdlYnNvY2tldDogYW55LCByZXF1ZXN0OiBhbnkpOiBhbnkge1xuICAgIHRoaXMuX2hhbmRsZVVuc3Vic2NyaWJlKHBhcnNlV2Vic29ja2V0LCByZXF1ZXN0LCBmYWxzZSk7XG4gICAgdGhpcy5faGFuZGxlU3Vic2NyaWJlKHBhcnNlV2Vic29ja2V0LCByZXF1ZXN0KTtcbiAgfVxuXG4gIF9oYW5kbGVVbnN1YnNjcmliZShwYXJzZVdlYnNvY2tldDogYW55LCByZXF1ZXN0OiBhbnksIG5vdGlmeUNsaWVudDogYm9vbGVhbiA9IHRydWUpOiBhbnkge1xuICAgIC8vIElmIHdlIGNhbiBub3QgZmluZCB0aGlzIGNsaWVudCwgcmV0dXJuIGVycm9yIHRvIGNsaWVudFxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHBhcnNlV2Vic29ja2V0LCAnY2xpZW50SWQnKSkge1xuICAgICAgQ2xpZW50LnB1c2hFcnJvcihcbiAgICAgICAgcGFyc2VXZWJzb2NrZXQsXG4gICAgICAgIDIsXG4gICAgICAgICdDYW4gbm90IGZpbmQgdGhpcyBjbGllbnQsIG1ha2Ugc3VyZSB5b3UgY29ubmVjdCB0byBzZXJ2ZXIgYmVmb3JlIHVuc3Vic2NyaWJpbmcnXG4gICAgICApO1xuICAgICAgbG9nZ2VyLmVycm9yKFxuICAgICAgICAnQ2FuIG5vdCBmaW5kIHRoaXMgY2xpZW50LCBtYWtlIHN1cmUgeW91IGNvbm5lY3QgdG8gc2VydmVyIGJlZm9yZSB1bnN1YnNjcmliaW5nJ1xuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcmVxdWVzdElkID0gcmVxdWVzdC5yZXF1ZXN0SWQ7XG4gICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRzLmdldChwYXJzZVdlYnNvY2tldC5jbGllbnRJZCk7XG4gICAgaWYgKHR5cGVvZiBjbGllbnQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBDbGllbnQucHVzaEVycm9yKFxuICAgICAgICBwYXJzZVdlYnNvY2tldCxcbiAgICAgICAgMixcbiAgICAgICAgJ0Nhbm5vdCBmaW5kIGNsaWVudCB3aXRoIGNsaWVudElkICcgK1xuICAgICAgICAgIHBhcnNlV2Vic29ja2V0LmNsaWVudElkICtcbiAgICAgICAgICAnLiBNYWtlIHN1cmUgeW91IGNvbm5lY3QgdG8gbGl2ZSBxdWVyeSBzZXJ2ZXIgYmVmb3JlIHVuc3Vic2NyaWJpbmcuJ1xuICAgICAgKTtcbiAgICAgIGxvZ2dlci5lcnJvcignQ2FuIG5vdCBmaW5kIHRoaXMgY2xpZW50ICcgKyBwYXJzZVdlYnNvY2tldC5jbGllbnRJZCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uSW5mbyA9IGNsaWVudC5nZXRTdWJzY3JpcHRpb25JbmZvKHJlcXVlc3RJZCk7XG4gICAgaWYgKHR5cGVvZiBzdWJzY3JpcHRpb25JbmZvID09PSAndW5kZWZpbmVkJykge1xuICAgICAgQ2xpZW50LnB1c2hFcnJvcihcbiAgICAgICAgcGFyc2VXZWJzb2NrZXQsXG4gICAgICAgIDIsXG4gICAgICAgICdDYW5ub3QgZmluZCBzdWJzY3JpcHRpb24gd2l0aCBjbGllbnRJZCAnICtcbiAgICAgICAgICBwYXJzZVdlYnNvY2tldC5jbGllbnRJZCArXG4gICAgICAgICAgJyBzdWJzY3JpcHRpb25JZCAnICtcbiAgICAgICAgICByZXF1ZXN0SWQgK1xuICAgICAgICAgICcuIE1ha2Ugc3VyZSB5b3Ugc3Vic2NyaWJlIHRvIGxpdmUgcXVlcnkgc2VydmVyIGJlZm9yZSB1bnN1YnNjcmliaW5nLidcbiAgICAgICk7XG4gICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICdDYW4gbm90IGZpbmQgc3Vic2NyaXB0aW9uIHdpdGggY2xpZW50SWQgJyArXG4gICAgICAgICAgcGFyc2VXZWJzb2NrZXQuY2xpZW50SWQgK1xuICAgICAgICAgICcgc3Vic2NyaXB0aW9uSWQgJyArXG4gICAgICAgICAgcmVxdWVzdElkXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFJlbW92ZSBzdWJzY3JpcHRpb24gZnJvbSBjbGllbnRcbiAgICBjbGllbnQuZGVsZXRlU3Vic2NyaXB0aW9uSW5mbyhyZXF1ZXN0SWQpO1xuICAgIC8vIFJlbW92ZSBjbGllbnQgZnJvbSBzdWJzY3JpcHRpb25cbiAgICBjb25zdCBzdWJzY3JpcHRpb24gPSBzdWJzY3JpcHRpb25JbmZvLnN1YnNjcmlwdGlvbjtcbiAgICBjb25zdCBjbGFzc05hbWUgPSBzdWJzY3JpcHRpb24uY2xhc3NOYW1lO1xuICAgIHN1YnNjcmlwdGlvbi5kZWxldGVDbGllbnRTdWJzY3JpcHRpb24ocGFyc2VXZWJzb2NrZXQuY2xpZW50SWQsIHJlcXVlc3RJZCk7XG4gICAgLy8gSWYgdGhlcmUgaXMgbm8gY2xpZW50IHdoaWNoIGlzIHN1YnNjcmliaW5nIHRoaXMgc3Vic2NyaXB0aW9uLCByZW1vdmUgaXQgZnJvbSBzdWJzY3JpcHRpb25zXG4gICAgY29uc3QgY2xhc3NTdWJzY3JpcHRpb25zID0gdGhpcy5zdWJzY3JpcHRpb25zLmdldChjbGFzc05hbWUpO1xuICAgIGlmICghc3Vic2NyaXB0aW9uLmhhc1N1YnNjcmliaW5nQ2xpZW50KCkpIHtcbiAgICAgIGNsYXNzU3Vic2NyaXB0aW9ucy5kZWxldGUoc3Vic2NyaXB0aW9uLmhhc2gpO1xuICAgIH1cbiAgICAvLyBJZiB0aGVyZSBpcyBubyBzdWJzY3JpcHRpb25zIHVuZGVyIHRoaXMgY2xhc3MsIHJlbW92ZSBpdCBmcm9tIHN1YnNjcmlwdGlvbnNcbiAgICBpZiAoY2xhc3NTdWJzY3JpcHRpb25zLnNpemUgPT09IDApIHtcbiAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5kZWxldGUoY2xhc3NOYW1lKTtcbiAgICB9XG4gICAgcnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyh7XG4gICAgICBjbGllbnQsXG4gICAgICBldmVudDogJ3Vuc3Vic2NyaWJlJyxcbiAgICAgIGNsaWVudHM6IHRoaXMuY2xpZW50cy5zaXplLFxuICAgICAgc3Vic2NyaXB0aW9uczogdGhpcy5zdWJzY3JpcHRpb25zLnNpemUsXG4gICAgICBzZXNzaW9uVG9rZW46IHN1YnNjcmlwdGlvbkluZm8uc2Vzc2lvblRva2VuLFxuICAgICAgdXNlTWFzdGVyS2V5OiBjbGllbnQuaGFzTWFzdGVyS2V5LFxuICAgICAgaW5zdGFsbGF0aW9uSWQ6IGNsaWVudC5pbnN0YWxsYXRpb25JZCxcbiAgICB9KTtcblxuICAgIGlmICghbm90aWZ5Q2xpZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY2xpZW50LnB1c2hVbnN1YnNjcmliZShyZXF1ZXN0LnJlcXVlc3RJZCk7XG5cbiAgICBsb2dnZXIudmVyYm9zZShcbiAgICAgIGBEZWxldGUgY2xpZW50OiAke3BhcnNlV2Vic29ja2V0LmNsaWVudElkfSB8IHN1YnNjcmlwdGlvbjogJHtyZXF1ZXN0LnJlcXVlc3RJZH1gXG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgeyBQYXJzZUxpdmVRdWVyeVNlcnZlciB9O1xuIl19 \ No newline at end of file diff --git a/lib/LiveQuery/ParsePubSub.js b/lib/LiveQuery/ParsePubSub.js deleted file mode 100644 index 87f2438cff..0000000000 --- a/lib/LiveQuery/ParsePubSub.js +++ /dev/null @@ -1,49 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.ParsePubSub = void 0; - -var _AdapterLoader = require("../Adapters/AdapterLoader"); - -var _EventEmitterPubSub = require("../Adapters/PubSub/EventEmitterPubSub"); - -var _RedisPubSub = require("../Adapters/PubSub/RedisPubSub"); - -const ParsePubSub = {}; -exports.ParsePubSub = ParsePubSub; - -function useRedis(config) { - const redisURL = config.redisURL; - return typeof redisURL !== 'undefined' && redisURL !== ''; -} - -ParsePubSub.createPublisher = function (config) { - if (useRedis(config)) { - return _RedisPubSub.RedisPubSub.createPublisher(config); - } else { - const adapter = (0, _AdapterLoader.loadAdapter)(config.pubSubAdapter, _EventEmitterPubSub.EventEmitterPubSub, config); - - if (typeof adapter.createPublisher !== 'function') { - throw 'pubSubAdapter should have createPublisher()'; - } - - return adapter.createPublisher(config); - } -}; - -ParsePubSub.createSubscriber = function (config) { - if (useRedis(config)) { - return _RedisPubSub.RedisPubSub.createSubscriber(config); - } else { - const adapter = (0, _AdapterLoader.loadAdapter)(config.pubSubAdapter, _EventEmitterPubSub.EventEmitterPubSub, config); - - if (typeof adapter.createSubscriber !== 'function') { - throw 'pubSubAdapter should have createSubscriber()'; - } - - return adapter.createSubscriber(config); - } -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUGFyc2VQdWJTdWIuanMiXSwibmFtZXMiOlsiUGFyc2VQdWJTdWIiLCJ1c2VSZWRpcyIsImNvbmZpZyIsInJlZGlzVVJMIiwiY3JlYXRlUHVibGlzaGVyIiwiUmVkaXNQdWJTdWIiLCJhZGFwdGVyIiwicHViU3ViQWRhcHRlciIsIkV2ZW50RW1pdHRlclB1YlN1YiIsImNyZWF0ZVN1YnNjcmliZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFFQTs7QUFFQSxNQUFNQSxXQUFXLEdBQUcsRUFBcEI7OztBQUVBLFNBQVNDLFFBQVQsQ0FBa0JDLE1BQWxCLEVBQXdDO0FBQ3RDLFFBQU1DLFFBQVEsR0FBR0QsTUFBTSxDQUFDQyxRQUF4QjtBQUNBLFNBQU8sT0FBT0EsUUFBUCxLQUFvQixXQUFwQixJQUFtQ0EsUUFBUSxLQUFLLEVBQXZEO0FBQ0Q7O0FBRURILFdBQVcsQ0FBQ0ksZUFBWixHQUE4QixVQUFVRixNQUFWLEVBQTRCO0FBQ3hELE1BQUlELFFBQVEsQ0FBQ0MsTUFBRCxDQUFaLEVBQXNCO0FBQ3BCLFdBQU9HLHlCQUFZRCxlQUFaLENBQTRCRixNQUE1QixDQUFQO0FBQ0QsR0FGRCxNQUVPO0FBQ0wsVUFBTUksT0FBTyxHQUFHLGdDQUFZSixNQUFNLENBQUNLLGFBQW5CLEVBQWtDQyxzQ0FBbEMsRUFBc0ROLE1BQXRELENBQWhCOztBQUNBLFFBQUksT0FBT0ksT0FBTyxDQUFDRixlQUFmLEtBQW1DLFVBQXZDLEVBQW1EO0FBQ2pELFlBQU0sNkNBQU47QUFDRDs7QUFDRCxXQUFPRSxPQUFPLENBQUNGLGVBQVIsQ0FBd0JGLE1BQXhCLENBQVA7QUFDRDtBQUNGLENBVkQ7O0FBWUFGLFdBQVcsQ0FBQ1MsZ0JBQVosR0FBK0IsVUFBVVAsTUFBVixFQUE2QjtBQUMxRCxNQUFJRCxRQUFRLENBQUNDLE1BQUQsQ0FBWixFQUFzQjtBQUNwQixXQUFPRyx5QkFBWUksZ0JBQVosQ0FBNkJQLE1BQTdCLENBQVA7QUFDRCxHQUZELE1BRU87QUFDTCxVQUFNSSxPQUFPLEdBQUcsZ0NBQVlKLE1BQU0sQ0FBQ0ssYUFBbkIsRUFBa0NDLHNDQUFsQyxFQUFzRE4sTUFBdEQsQ0FBaEI7O0FBQ0EsUUFBSSxPQUFPSSxPQUFPLENBQUNHLGdCQUFmLEtBQW9DLFVBQXhDLEVBQW9EO0FBQ2xELFlBQU0sOENBQU47QUFDRDs7QUFDRCxXQUFPSCxPQUFPLENBQUNHLGdCQUFSLENBQXlCUCxNQUF6QixDQUFQO0FBQ0Q7QUFDRixDQVZEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbG9hZEFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9BZGFwdGVyTG9hZGVyJztcbmltcG9ydCB7IEV2ZW50RW1pdHRlclB1YlN1YiB9IGZyb20gJy4uL0FkYXB0ZXJzL1B1YlN1Yi9FdmVudEVtaXR0ZXJQdWJTdWInO1xuXG5pbXBvcnQgeyBSZWRpc1B1YlN1YiB9IGZyb20gJy4uL0FkYXB0ZXJzL1B1YlN1Yi9SZWRpc1B1YlN1Yic7XG5cbmNvbnN0IFBhcnNlUHViU3ViID0ge307XG5cbmZ1bmN0aW9uIHVzZVJlZGlzKGNvbmZpZzogYW55KTogYm9vbGVhbiB7XG4gIGNvbnN0IHJlZGlzVVJMID0gY29uZmlnLnJlZGlzVVJMO1xuICByZXR1cm4gdHlwZW9mIHJlZGlzVVJMICE9PSAndW5kZWZpbmVkJyAmJiByZWRpc1VSTCAhPT0gJyc7XG59XG5cblBhcnNlUHViU3ViLmNyZWF0ZVB1Ymxpc2hlciA9IGZ1bmN0aW9uIChjb25maWc6IGFueSk6IGFueSB7XG4gIGlmICh1c2VSZWRpcyhjb25maWcpKSB7XG4gICAgcmV0dXJuIFJlZGlzUHViU3ViLmNyZWF0ZVB1Ymxpc2hlcihjb25maWcpO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGFkYXB0ZXIgPSBsb2FkQWRhcHRlcihjb25maWcucHViU3ViQWRhcHRlciwgRXZlbnRFbWl0dGVyUHViU3ViLCBjb25maWcpO1xuICAgIGlmICh0eXBlb2YgYWRhcHRlci5jcmVhdGVQdWJsaXNoZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRocm93ICdwdWJTdWJBZGFwdGVyIHNob3VsZCBoYXZlIGNyZWF0ZVB1Ymxpc2hlcigpJztcbiAgICB9XG4gICAgcmV0dXJuIGFkYXB0ZXIuY3JlYXRlUHVibGlzaGVyKGNvbmZpZyk7XG4gIH1cbn07XG5cblBhcnNlUHViU3ViLmNyZWF0ZVN1YnNjcmliZXIgPSBmdW5jdGlvbiAoY29uZmlnOiBhbnkpOiB2b2lkIHtcbiAgaWYgKHVzZVJlZGlzKGNvbmZpZykpIHtcbiAgICByZXR1cm4gUmVkaXNQdWJTdWIuY3JlYXRlU3Vic2NyaWJlcihjb25maWcpO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGFkYXB0ZXIgPSBsb2FkQWRhcHRlcihjb25maWcucHViU3ViQWRhcHRlciwgRXZlbnRFbWl0dGVyUHViU3ViLCBjb25maWcpO1xuICAgIGlmICh0eXBlb2YgYWRhcHRlci5jcmVhdGVTdWJzY3JpYmVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyAncHViU3ViQWRhcHRlciBzaG91bGQgaGF2ZSBjcmVhdGVTdWJzY3JpYmVyKCknO1xuICAgIH1cbiAgICByZXR1cm4gYWRhcHRlci5jcmVhdGVTdWJzY3JpYmVyKGNvbmZpZyk7XG4gIH1cbn07XG5cbmV4cG9ydCB7IFBhcnNlUHViU3ViIH07XG4iXX0= \ No newline at end of file diff --git a/lib/LiveQuery/ParseWebSocketServer.js b/lib/LiveQuery/ParseWebSocketServer.js deleted file mode 100644 index b7ab9d6099..0000000000 --- a/lib/LiveQuery/ParseWebSocketServer.js +++ /dev/null @@ -1,80 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.ParseWebSocket = exports.ParseWebSocketServer = void 0; - -var _AdapterLoader = require("../Adapters/AdapterLoader"); - -var _WSAdapter = require("../Adapters/WebSocketServer/WSAdapter"); - -var _logger = _interopRequireDefault(require("../logger")); - -var _events = _interopRequireDefault(require("events")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class ParseWebSocketServer { - constructor(server, onConnect, config) { - config.server = server; - const wss = (0, _AdapterLoader.loadAdapter)(config.wssAdapter, _WSAdapter.WSAdapter, config); - - wss.onListen = () => { - _logger.default.info('Parse LiveQuery Server starts running'); - }; - - wss.onConnection = ws => { - ws.on('error', error => { - _logger.default.error(error.message); - - _logger.default.error(JSON.stringify(ws)); - }); - onConnect(new ParseWebSocket(ws)); // Send ping to client periodically - - const pingIntervalId = setInterval(() => { - if (ws.readyState == ws.OPEN) { - ws.ping(); - } else { - clearInterval(pingIntervalId); - } - }, config.websocketTimeout || 10 * 1000); - }; - - wss.onError = error => { - _logger.default.error(error); - }; - - wss.start(); - this.server = wss; - } - - close() { - if (this.server && this.server.close) { - this.server.close(); - } - } - -} - -exports.ParseWebSocketServer = ParseWebSocketServer; - -class ParseWebSocket extends _events.default.EventEmitter { - constructor(ws) { - super(); - - ws.onmessage = request => this.emit('message', request && request.data ? request.data : request); - - ws.onclose = () => this.emit('disconnect'); - - this.ws = ws; - } - - send(message) { - this.ws.send(message); - } - -} - -exports.ParseWebSocket = ParseWebSocket; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUGFyc2VXZWJTb2NrZXRTZXJ2ZXIuanMiXSwibmFtZXMiOlsiUGFyc2VXZWJTb2NrZXRTZXJ2ZXIiLCJjb25zdHJ1Y3RvciIsInNlcnZlciIsIm9uQ29ubmVjdCIsImNvbmZpZyIsIndzcyIsIndzc0FkYXB0ZXIiLCJXU0FkYXB0ZXIiLCJvbkxpc3RlbiIsImxvZ2dlciIsImluZm8iLCJvbkNvbm5lY3Rpb24iLCJ3cyIsIm9uIiwiZXJyb3IiLCJtZXNzYWdlIiwiSlNPTiIsInN0cmluZ2lmeSIsIlBhcnNlV2ViU29ja2V0IiwicGluZ0ludGVydmFsSWQiLCJzZXRJbnRlcnZhbCIsInJlYWR5U3RhdGUiLCJPUEVOIiwicGluZyIsImNsZWFySW50ZXJ2YWwiLCJ3ZWJzb2NrZXRUaW1lb3V0Iiwib25FcnJvciIsInN0YXJ0IiwiY2xvc2UiLCJldmVudHMiLCJFdmVudEVtaXR0ZXIiLCJvbm1lc3NhZ2UiLCJyZXF1ZXN0IiwiZW1pdCIsImRhdGEiLCJvbmNsb3NlIiwic2VuZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRU8sTUFBTUEsb0JBQU4sQ0FBMkI7QUFHaENDLEVBQUFBLFdBQVcsQ0FBQ0MsTUFBRCxFQUFjQyxTQUFkLEVBQW1DQyxNQUFuQyxFQUEyQztBQUNwREEsSUFBQUEsTUFBTSxDQUFDRixNQUFQLEdBQWdCQSxNQUFoQjtBQUNBLFVBQU1HLEdBQUcsR0FBRyxnQ0FBWUQsTUFBTSxDQUFDRSxVQUFuQixFQUErQkMsb0JBQS9CLEVBQTBDSCxNQUExQyxDQUFaOztBQUNBQyxJQUFBQSxHQUFHLENBQUNHLFFBQUosR0FBZSxNQUFNO0FBQ25CQyxzQkFBT0MsSUFBUCxDQUFZLHVDQUFaO0FBQ0QsS0FGRDs7QUFHQUwsSUFBQUEsR0FBRyxDQUFDTSxZQUFKLEdBQW1CQyxFQUFFLElBQUk7QUFDdkJBLE1BQUFBLEVBQUUsQ0FBQ0MsRUFBSCxDQUFNLE9BQU4sRUFBZUMsS0FBSyxJQUFJO0FBQ3RCTCx3QkFBT0ssS0FBUCxDQUFhQSxLQUFLLENBQUNDLE9BQW5COztBQUNBTix3QkFBT0ssS0FBUCxDQUFhRSxJQUFJLENBQUNDLFNBQUwsQ0FBZUwsRUFBZixDQUFiO0FBQ0QsT0FIRDtBQUlBVCxNQUFBQSxTQUFTLENBQUMsSUFBSWUsY0FBSixDQUFtQk4sRUFBbkIsQ0FBRCxDQUFULENBTHVCLENBTXZCOztBQUNBLFlBQU1PLGNBQWMsR0FBR0MsV0FBVyxDQUFDLE1BQU07QUFDdkMsWUFBSVIsRUFBRSxDQUFDUyxVQUFILElBQWlCVCxFQUFFLENBQUNVLElBQXhCLEVBQThCO0FBQzVCVixVQUFBQSxFQUFFLENBQUNXLElBQUg7QUFDRCxTQUZELE1BRU87QUFDTEMsVUFBQUEsYUFBYSxDQUFDTCxjQUFELENBQWI7QUFDRDtBQUNGLE9BTmlDLEVBTS9CZixNQUFNLENBQUNxQixnQkFBUCxJQUEyQixLQUFLLElBTkQsQ0FBbEM7QUFPRCxLQWREOztBQWVBcEIsSUFBQUEsR0FBRyxDQUFDcUIsT0FBSixHQUFjWixLQUFLLElBQUk7QUFDckJMLHNCQUFPSyxLQUFQLENBQWFBLEtBQWI7QUFDRCxLQUZEOztBQUdBVCxJQUFBQSxHQUFHLENBQUNzQixLQUFKO0FBQ0EsU0FBS3pCLE1BQUwsR0FBY0csR0FBZDtBQUNEOztBQUVEdUIsRUFBQUEsS0FBSyxHQUFHO0FBQ04sUUFBSSxLQUFLMUIsTUFBTCxJQUFlLEtBQUtBLE1BQUwsQ0FBWTBCLEtBQS9CLEVBQXNDO0FBQ3BDLFdBQUsxQixNQUFMLENBQVkwQixLQUFaO0FBQ0Q7QUFDRjs7QUFuQytCOzs7O0FBc0MzQixNQUFNVixjQUFOLFNBQTZCVyxnQkFBT0MsWUFBcEMsQ0FBaUQ7QUFHdEQ3QixFQUFBQSxXQUFXLENBQUNXLEVBQUQsRUFBVTtBQUNuQjs7QUFDQUEsSUFBQUEsRUFBRSxDQUFDbUIsU0FBSCxHQUFlQyxPQUFPLElBQ3BCLEtBQUtDLElBQUwsQ0FBVSxTQUFWLEVBQXFCRCxPQUFPLElBQUlBLE9BQU8sQ0FBQ0UsSUFBbkIsR0FBMEJGLE9BQU8sQ0FBQ0UsSUFBbEMsR0FBeUNGLE9BQTlELENBREY7O0FBRUFwQixJQUFBQSxFQUFFLENBQUN1QixPQUFILEdBQWEsTUFBTSxLQUFLRixJQUFMLENBQVUsWUFBVixDQUFuQjs7QUFDQSxTQUFLckIsRUFBTCxHQUFVQSxFQUFWO0FBQ0Q7O0FBRUR3QixFQUFBQSxJQUFJLENBQUNyQixPQUFELEVBQXFCO0FBQ3ZCLFNBQUtILEVBQUwsQ0FBUXdCLElBQVIsQ0FBYXJCLE9BQWI7QUFDRDs7QUFicUQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBsb2FkQWRhcHRlciB9IGZyb20gJy4uL0FkYXB0ZXJzL0FkYXB0ZXJMb2FkZXInO1xuaW1wb3J0IHsgV1NBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvV2ViU29ja2V0U2VydmVyL1dTQWRhcHRlcic7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5pbXBvcnQgZXZlbnRzIGZyb20gJ2V2ZW50cyc7XG5cbmV4cG9ydCBjbGFzcyBQYXJzZVdlYlNvY2tldFNlcnZlciB7XG4gIHNlcnZlcjogT2JqZWN0O1xuXG4gIGNvbnN0cnVjdG9yKHNlcnZlcjogYW55LCBvbkNvbm5lY3Q6IEZ1bmN0aW9uLCBjb25maWcpIHtcbiAgICBjb25maWcuc2VydmVyID0gc2VydmVyO1xuICAgIGNvbnN0IHdzcyA9IGxvYWRBZGFwdGVyKGNvbmZpZy53c3NBZGFwdGVyLCBXU0FkYXB0ZXIsIGNvbmZpZyk7XG4gICAgd3NzLm9uTGlzdGVuID0gKCkgPT4ge1xuICAgICAgbG9nZ2VyLmluZm8oJ1BhcnNlIExpdmVRdWVyeSBTZXJ2ZXIgc3RhcnRzIHJ1bm5pbmcnKTtcbiAgICB9O1xuICAgIHdzcy5vbkNvbm5lY3Rpb24gPSB3cyA9PiB7XG4gICAgICB3cy5vbignZXJyb3InLCBlcnJvciA9PiB7XG4gICAgICAgIGxvZ2dlci5lcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgICAgbG9nZ2VyLmVycm9yKEpTT04uc3RyaW5naWZ5KHdzKSk7XG4gICAgICB9KTtcbiAgICAgIG9uQ29ubmVjdChuZXcgUGFyc2VXZWJTb2NrZXQod3MpKTtcbiAgICAgIC8vIFNlbmQgcGluZyB0byBjbGllbnQgcGVyaW9kaWNhbGx5XG4gICAgICBjb25zdCBwaW5nSW50ZXJ2YWxJZCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgaWYgKHdzLnJlYWR5U3RhdGUgPT0gd3MuT1BFTikge1xuICAgICAgICAgIHdzLnBpbmcoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjbGVhckludGVydmFsKHBpbmdJbnRlcnZhbElkKTtcbiAgICAgICAgfVxuICAgICAgfSwgY29uZmlnLndlYnNvY2tldFRpbWVvdXQgfHwgMTAgKiAxMDAwKTtcbiAgICB9O1xuICAgIHdzcy5vbkVycm9yID0gZXJyb3IgPT4ge1xuICAgICAgbG9nZ2VyLmVycm9yKGVycm9yKTtcbiAgICB9O1xuICAgIHdzcy5zdGFydCgpO1xuICAgIHRoaXMuc2VydmVyID0gd3NzO1xuICB9XG5cbiAgY2xvc2UoKSB7XG4gICAgaWYgKHRoaXMuc2VydmVyICYmIHRoaXMuc2VydmVyLmNsb3NlKSB7XG4gICAgICB0aGlzLnNlcnZlci5jbG9zZSgpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUGFyc2VXZWJTb2NrZXQgZXh0ZW5kcyBldmVudHMuRXZlbnRFbWl0dGVyIHtcbiAgd3M6IGFueTtcblxuICBjb25zdHJ1Y3Rvcih3czogYW55KSB7XG4gICAgc3VwZXIoKTtcbiAgICB3cy5vbm1lc3NhZ2UgPSByZXF1ZXN0ID0+XG4gICAgICB0aGlzLmVtaXQoJ21lc3NhZ2UnLCByZXF1ZXN0ICYmIHJlcXVlc3QuZGF0YSA/IHJlcXVlc3QuZGF0YSA6IHJlcXVlc3QpO1xuICAgIHdzLm9uY2xvc2UgPSAoKSA9PiB0aGlzLmVtaXQoJ2Rpc2Nvbm5lY3QnKTtcbiAgICB0aGlzLndzID0gd3M7XG4gIH1cblxuICBzZW5kKG1lc3NhZ2U6IGFueSk6IHZvaWQge1xuICAgIHRoaXMud3Muc2VuZChtZXNzYWdlKTtcbiAgfVxufVxuIl19 \ No newline at end of file diff --git a/lib/LiveQuery/QueryTools.js b/lib/LiveQuery/QueryTools.js deleted file mode 100644 index 6185b13082..0000000000 --- a/lib/LiveQuery/QueryTools.js +++ /dev/null @@ -1,452 +0,0 @@ -"use strict"; - -var equalObjects = require('./equalObjects'); - -var Id = require('./Id'); - -var Parse = require('parse/node'); -/** - * Query Hashes are deterministic hashes for Parse Queries. - * Any two queries that have the same set of constraints will produce the same - * hash. This lets us reliably group components by the queries they depend upon, - * and quickly determine if a query has changed. - */ - -/** - * Convert $or queries into an array of where conditions - */ - - -function flattenOrQueries(where) { - if (!Object.prototype.hasOwnProperty.call(where, '$or')) { - return where; - } - - var accum = []; - - for (var i = 0; i < where.$or.length; i++) { - accum = accum.concat(where.$or[i]); - } - - return accum; -} -/** - * Deterministically turns an object into a string. Disregards ordering - */ - - -function stringify(object) { - if (typeof object !== 'object' || object === null) { - if (typeof object === 'string') { - return '"' + object.replace(/\|/g, '%|') + '"'; - } - - return object + ''; - } - - if (Array.isArray(object)) { - var copy = object.map(stringify); - copy.sort(); - return '[' + copy.join(',') + ']'; - } - - var sections = []; - var keys = Object.keys(object); - keys.sort(); - - for (var k = 0; k < keys.length; k++) { - sections.push(stringify(keys[k]) + ':' + stringify(object[keys[k]])); - } - - return '{' + sections.join(',') + '}'; -} -/** - * Generate a hash from a query, with unique fields for columns, values, order, - * skip, and limit. - */ - - -function queryHash(query) { - if (query instanceof Parse.Query) { - query = { - className: query.className, - where: query._where - }; - } - - var where = flattenOrQueries(query.where || {}); - var columns = []; - var values = []; - var i; - - if (Array.isArray(where)) { - var uniqueColumns = {}; - - for (i = 0; i < where.length; i++) { - var subValues = {}; - var keys = Object.keys(where[i]); - keys.sort(); - - for (var j = 0; j < keys.length; j++) { - subValues[keys[j]] = where[i][keys[j]]; - uniqueColumns[keys[j]] = true; - } - - values.push(subValues); - } - - columns = Object.keys(uniqueColumns); - columns.sort(); - } else { - columns = Object.keys(where); - columns.sort(); - - for (i = 0; i < columns.length; i++) { - values.push(where[columns[i]]); - } - } - - var sections = [columns.join(','), stringify(values)]; - return query.className + ':' + sections.join('|'); -} -/** - * contains -- Determines if an object is contained in a list with special handling for Parse pointers. - */ - - -function contains(haystack, needle) { - if (needle && needle.__type && needle.__type === 'Pointer') { - for (const i in haystack) { - const ptr = haystack[i]; - - if (typeof ptr === 'string' && ptr === needle.objectId) { - return true; - } - - if (ptr.className === needle.className && ptr.objectId === needle.objectId) { - return true; - } - } - - return false; - } - - return haystack.indexOf(needle) > -1; -} -/** - * matchesQuery -- Determines if an object would be returned by a Parse Query - * It's a lightweight, where-clause only implementation of a full query engine. - * Since we find queries that match objects, rather than objects that match - * queries, we can avoid building a full-blown query tool. - */ - - -function matchesQuery(object, query) { - if (query instanceof Parse.Query) { - var className = object.id instanceof Id ? object.id.className : object.className; - - if (className !== query.className) { - return false; - } - - return matchesQuery(object, query._where); - } - - for (var field in query) { - if (!matchesKeyConstraints(object, field, query[field])) { - return false; - } - } - - return true; -} - -function equalObjectsGeneric(obj, compareTo, eqlFn) { - if (Array.isArray(obj)) { - for (var i = 0; i < obj.length; i++) { - if (eqlFn(obj[i], compareTo)) { - return true; - } - } - - return false; - } - - return eqlFn(obj, compareTo); -} -/** - * Determines whether an object matches a single key's constraints - */ - - -function matchesKeyConstraints(object, key, constraints) { - if (constraints === null) { - return false; - } - - if (key.indexOf('.') >= 0) { - // Key references a subobject - var keyComponents = key.split('.'); - var subObjectKey = keyComponents[0]; - var keyRemainder = keyComponents.slice(1).join('.'); - return matchesKeyConstraints(object[subObjectKey] || {}, keyRemainder, constraints); - } - - var i; - - if (key === '$or') { - for (i = 0; i < constraints.length; i++) { - if (matchesQuery(object, constraints[i])) { - return true; - } - } - - return false; - } - - if (key === '$and') { - for (i = 0; i < constraints.length; i++) { - if (!matchesQuery(object, constraints[i])) { - return false; - } - } - - return true; - } - - if (key === '$nor') { - for (i = 0; i < constraints.length; i++) { - if (matchesQuery(object, constraints[i])) { - return false; - } - } - - return true; - } - - if (key === '$relatedTo') { - // Bail! We can't handle relational queries locally - return false; - } // Decode Date JSON value - - - if (object[key] && object[key].__type == 'Date') { - object[key] = new Date(object[key].iso); - } // Equality (or Array contains) cases - - - if (typeof constraints !== 'object') { - if (Array.isArray(object[key])) { - return object[key].indexOf(constraints) > -1; - } - - return object[key] === constraints; - } - - var compareTo; - - if (constraints.__type) { - if (constraints.__type === 'Pointer') { - return equalObjectsGeneric(object[key], constraints, function (obj, ptr) { - return typeof obj !== 'undefined' && ptr.className === obj.className && ptr.objectId === obj.objectId; - }); - } - - return equalObjectsGeneric(object[key], Parse._decode(key, constraints), equalObjects); - } // More complex cases - - - for (var condition in constraints) { - compareTo = constraints[condition]; - - if (compareTo.__type) { - compareTo = Parse._decode(key, compareTo); - } - - switch (condition) { - case '$lt': - if (object[key] >= compareTo) { - return false; - } - - break; - - case '$lte': - if (object[key] > compareTo) { - return false; - } - - break; - - case '$gt': - if (object[key] <= compareTo) { - return false; - } - - break; - - case '$gte': - if (object[key] < compareTo) { - return false; - } - - break; - - case '$ne': - if (equalObjects(object[key], compareTo)) { - return false; - } - - break; - - case '$in': - if (!contains(compareTo, object[key])) { - return false; - } - - break; - - case '$nin': - if (contains(compareTo, object[key])) { - return false; - } - - break; - - case '$all': - for (i = 0; i < compareTo.length; i++) { - if (object[key].indexOf(compareTo[i]) < 0) { - return false; - } - } - - break; - - case '$exists': - { - const propertyExists = typeof object[key] !== 'undefined'; - const existenceIsRequired = constraints['$exists']; - - if (typeof constraints['$exists'] !== 'boolean') { - // The SDK will never submit a non-boolean for $exists, but if someone - // tries to submit a non-boolean for $exits outside the SDKs, just ignore it. - break; - } - - if (!propertyExists && existenceIsRequired || propertyExists && !existenceIsRequired) { - return false; - } - - break; - } - - case '$regex': - if (typeof compareTo === 'object') { - return compareTo.test(object[key]); - } // JS doesn't support perl-style escaping - - - var expString = ''; - var escapeEnd = -2; - var escapeStart = compareTo.indexOf('\\Q'); - - while (escapeStart > -1) { - // Add the unescaped portion - expString += compareTo.substring(escapeEnd + 2, escapeStart); - escapeEnd = compareTo.indexOf('\\E', escapeStart); - - if (escapeEnd > -1) { - expString += compareTo.substring(escapeStart + 2, escapeEnd).replace(/\\\\\\\\E/g, '\\E').replace(/\W/g, '\\$&'); - } - - escapeStart = compareTo.indexOf('\\Q', escapeEnd); - } - - expString += compareTo.substring(Math.max(escapeStart, escapeEnd + 2)); - var exp = new RegExp(expString, constraints.$options || ''); - - if (!exp.test(object[key])) { - return false; - } - - break; - - case '$nearSphere': - if (!compareTo || !object[key]) { - return false; - } - - var distance = compareTo.radiansTo(object[key]); - var max = constraints.$maxDistance || Infinity; - return distance <= max; - - case '$within': - if (!compareTo || !object[key]) { - return false; - } - - var southWest = compareTo.$box[0]; - var northEast = compareTo.$box[1]; - - if (southWest.latitude > northEast.latitude || southWest.longitude > northEast.longitude) { - // Invalid box, crosses the date line - return false; - } - - return object[key].latitude > southWest.latitude && object[key].latitude < northEast.latitude && object[key].longitude > southWest.longitude && object[key].longitude < northEast.longitude; - - case '$containedBy': - { - for (const value of object[key]) { - if (!contains(compareTo, value)) { - return false; - } - } - - return true; - } - - case '$geoWithin': - { - const points = compareTo.$polygon.map(geoPoint => [geoPoint.latitude, geoPoint.longitude]); - const polygon = new Parse.Polygon(points); - return polygon.containsPoint(object[key]); - } - - case '$geoIntersects': - { - const polygon = new Parse.Polygon(object[key].coordinates); - const point = new Parse.GeoPoint(compareTo.$point); - return polygon.containsPoint(point); - } - - case '$options': - // Not a query type, but a way to add options to $regex. Ignore and - // avoid the default - break; - - case '$maxDistance': - // Not a query type, but a way to add a cap to $nearSphere. Ignore and - // avoid the default - break; - - case '$select': - return false; - - case '$dontSelect': - return false; - - default: - return false; - } - } - - return true; -} - -var QueryTools = { - queryHash: queryHash, - matchesQuery: matchesQuery -}; -module.exports = QueryTools; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUXVlcnlUb29scy5qcyJdLCJuYW1lcyI6WyJlcXVhbE9iamVjdHMiLCJyZXF1aXJlIiwiSWQiLCJQYXJzZSIsImZsYXR0ZW5PclF1ZXJpZXMiLCJ3aGVyZSIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImFjY3VtIiwiaSIsIiRvciIsImxlbmd0aCIsImNvbmNhdCIsInN0cmluZ2lmeSIsIm9iamVjdCIsInJlcGxhY2UiLCJBcnJheSIsImlzQXJyYXkiLCJjb3B5IiwibWFwIiwic29ydCIsImpvaW4iLCJzZWN0aW9ucyIsImtleXMiLCJrIiwicHVzaCIsInF1ZXJ5SGFzaCIsInF1ZXJ5IiwiUXVlcnkiLCJjbGFzc05hbWUiLCJfd2hlcmUiLCJjb2x1bW5zIiwidmFsdWVzIiwidW5pcXVlQ29sdW1ucyIsInN1YlZhbHVlcyIsImoiLCJjb250YWlucyIsImhheXN0YWNrIiwibmVlZGxlIiwiX190eXBlIiwicHRyIiwib2JqZWN0SWQiLCJpbmRleE9mIiwibWF0Y2hlc1F1ZXJ5IiwiaWQiLCJmaWVsZCIsIm1hdGNoZXNLZXlDb25zdHJhaW50cyIsImVxdWFsT2JqZWN0c0dlbmVyaWMiLCJvYmoiLCJjb21wYXJlVG8iLCJlcWxGbiIsImtleSIsImNvbnN0cmFpbnRzIiwia2V5Q29tcG9uZW50cyIsInNwbGl0Iiwic3ViT2JqZWN0S2V5Iiwia2V5UmVtYWluZGVyIiwic2xpY2UiLCJEYXRlIiwiaXNvIiwiX2RlY29kZSIsImNvbmRpdGlvbiIsInByb3BlcnR5RXhpc3RzIiwiZXhpc3RlbmNlSXNSZXF1aXJlZCIsInRlc3QiLCJleHBTdHJpbmciLCJlc2NhcGVFbmQiLCJlc2NhcGVTdGFydCIsInN1YnN0cmluZyIsIk1hdGgiLCJtYXgiLCJleHAiLCJSZWdFeHAiLCIkb3B0aW9ucyIsImRpc3RhbmNlIiwicmFkaWFuc1RvIiwiJG1heERpc3RhbmNlIiwiSW5maW5pdHkiLCJzb3V0aFdlc3QiLCIkYm94Iiwibm9ydGhFYXN0IiwibGF0aXR1ZGUiLCJsb25naXR1ZGUiLCJ2YWx1ZSIsInBvaW50cyIsIiRwb2x5Z29uIiwiZ2VvUG9pbnQiLCJwb2x5Z29uIiwiUG9seWdvbiIsImNvbnRhaW5zUG9pbnQiLCJjb29yZGluYXRlcyIsInBvaW50IiwiR2VvUG9pbnQiLCIkcG9pbnQiLCJRdWVyeVRvb2xzIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQSxJQUFJQSxZQUFZLEdBQUdDLE9BQU8sQ0FBQyxnQkFBRCxDQUExQjs7QUFDQSxJQUFJQyxFQUFFLEdBQUdELE9BQU8sQ0FBQyxNQUFELENBQWhCOztBQUNBLElBQUlFLEtBQUssR0FBR0YsT0FBTyxDQUFDLFlBQUQsQ0FBbkI7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFDQSxTQUFTRyxnQkFBVCxDQUEwQkMsS0FBMUIsRUFBaUM7QUFDL0IsTUFBSSxDQUFDQyxNQUFNLENBQUNDLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUFxQ0osS0FBckMsRUFBNEMsS0FBNUMsQ0FBTCxFQUF5RDtBQUN2RCxXQUFPQSxLQUFQO0FBQ0Q7O0FBQ0QsTUFBSUssS0FBSyxHQUFHLEVBQVo7O0FBQ0EsT0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHTixLQUFLLENBQUNPLEdBQU4sQ0FBVUMsTUFBOUIsRUFBc0NGLENBQUMsRUFBdkMsRUFBMkM7QUFDekNELElBQUFBLEtBQUssR0FBR0EsS0FBSyxDQUFDSSxNQUFOLENBQWFULEtBQUssQ0FBQ08sR0FBTixDQUFVRCxDQUFWLENBQWIsQ0FBUjtBQUNEOztBQUNELFNBQU9ELEtBQVA7QUFDRDtBQUVEO0FBQ0E7QUFDQTs7O0FBQ0EsU0FBU0ssU0FBVCxDQUFtQkMsTUFBbkIsRUFBbUM7QUFDakMsTUFBSSxPQUFPQSxNQUFQLEtBQWtCLFFBQWxCLElBQThCQSxNQUFNLEtBQUssSUFBN0MsRUFBbUQ7QUFDakQs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cUMsR0FBRCxDQUFOLENBQVl1QyxXQUE5QixDQUFoQjtBQUNBLGdCQUFNQyxLQUFLLEdBQUcsSUFBSTFGLEtBQUssQ0FBQzJGLFFBQVYsQ0FBbUIzQyxTQUFTLENBQUM0QyxNQUE3QixDQUFkO0FBQ0EsaUJBQU9OLE9BQU8sQ0FBQ0UsYUFBUixDQUFzQkUsS0FBdEIsQ0FBUDtBQUNEOztBQUNELFdBQUssVUFBTDtBQUNFO0FBQ0E7QUFDQTs7QUFDRixXQUFLLGNBQUw7QUFDRTtBQUNBO0FBQ0E7O0FBQ0YsV0FBSyxTQUFMO0FBQ0UsZUFBTyxLQUFQOztBQUNGLFdBQUssYUFBTDtBQUNFLGVBQU8sS0FBUDs7QUFDRjtBQUNFLGVBQU8sS0FBUDtBQXpJSjtBQTJJRDs7QUFDRCxTQUFPLElBQVA7QUFDRDs7QUFFRCxJQUFJRyxVQUFVLEdBQUc7QUFDZnBFLEVBQUFBLFNBQVMsRUFBRUEsU0FESTtBQUVmaUIsRUFBQUEsWUFBWSxFQUFFQTtBQUZDLENBQWpCO0FBS0FvRCxNQUFNLENBQUNDLE9BQVAsR0FBaUJGLFVBQWpCIiwic291cmNlc0NvbnRlbnQiOlsidmFyIGVxdWFsT2JqZWN0cyA9IHJlcXVpcmUoJy4vZXF1YWxPYmplY3RzJyk7XG52YXIgSWQgPSByZXF1aXJlKCcuL0lkJyk7XG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5cbi8qKlxuICogUXVlcnkgSGFzaGVzIGFyZSBkZXRlcm1pbmlzdGljIGhhc2hlcyBmb3IgUGFyc2UgUXVlcmllcy5cbiAqIEFueSB0d28gcXVlcmllcyB0aGF0IGhhdmUgdGhlIHNhbWUgc2V0IG9mIGNvbnN0cmFpbnRzIHdpbGwgcHJvZHVjZSB0aGUgc2FtZVxuICogaGFzaC4gVGhpcyBsZXRzIHVzIHJlbGlhYmx5IGdyb3VwIGNvbXBvbmVudHMgYnkgdGhlIHF1ZXJpZXMgdGhleSBkZXBlbmQgdXBvbixcbiAqIGFuZCBxdWlja2x5IGRldGVybWluZSBpZiBhIHF1ZXJ5IGhhcyBjaGFuZ2VkLlxuICovXG5cbi8qKlxuICogQ29udmVydCAkb3IgcXVlcmllcyBpbnRvIGFuIGFycmF5IG9mIHdoZXJlIGNvbmRpdGlvbnNcbiAqL1xuZnVuY3Rpb24gZmxhdHRlbk9yUXVlcmllcyh3aGVyZSkge1xuICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh3aGVyZSwgJyRvcicpKSB7XG4gICAgcmV0dXJuIHdoZXJlO1xuICB9XG4gIHZhciBhY2N1bSA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHdoZXJlLiRvci5sZW5ndGg7IGkrKykge1xuICAgIGFjY3VtID0gYWNjdW0uY29uY2F0KHdoZXJlLiRvcltpXSk7XG4gIH1cbiAgcmV0dXJuIGFjY3VtO1xufVxuXG4vKipcbiAqIERldGVybWluaXN0aWNhbGx5IHR1cm5zIGFuIG9iamVjdCBpbnRvIGEgc3RyaW5nLiBEaXNyZWdhcmRzIG9yZGVyaW5nXG4gKi9cbmZ1bmN0aW9uIHN0cmluZ2lmeShvYmplY3QpOiBzdHJpbmcge1xuICBpZiAodHlwZW9mIG9iamVjdCAhPT0gJ29iamVjdCcgfHwgb2JqZWN0ID09PSBudWxsKSB7XG4gICAgaWYgKHR5cGVvZiBvYmplY3QgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gJ1wiJyArIG9iamVjdC5yZXBsYWNlKC9cXHwvZywgJyV8JykgKyAnXCInO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0ICsgJyc7XG4gIH1cbiAgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkge1xuICAgIHZhciBjb3B5ID0gb2JqZWN0Lm1hcChzdHJpbmdpZnkpO1xuICAgIGNvcHkuc29ydCgpO1xuICAgIHJldHVybiAnWycgKyBjb3B5LmpvaW4oJywnKSArICddJztcbiAgfVxuICB2YXIgc2VjdGlvbnMgPSBbXTtcbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvYmplY3QpO1xuICBrZXlzLnNvcnQoKTtcbiAgZm9yICh2YXIgayA9IDA7IGsgPCBrZXlzLmxlbmd0aDsgaysrKSB7XG4gICAgc2VjdGlvbnMucHVzaChzdHJpbmdpZnkoa2V5c1trXSkgKyAnOicgKyBzdHJpbmdpZnkob2JqZWN0W2tleXNba11dKSk7XG4gIH1cbiAgcmV0dXJuICd7JyArIHNlY3Rpb25zLmpvaW4oJywnKSArICd9Jztcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBhIGhhc2ggZnJvbSBhIHF1ZXJ5LCB3aXRoIHVuaXF1ZSBmaWVsZHMgZm9yIGNvbHVtbnMsIHZhbHVlcywgb3JkZXIsXG4gKiBza2lwLCBhbmQgbGltaXQuXG4gKi9cbmZ1bmN0aW9uIHF1ZXJ5SGFzaChxdWVyeSkge1xuICBpZiAocXVlcnkgaW5zdGFuY2VvZiBQYXJzZS5RdWVyeSkge1xuICAgIHF1ZXJ5ID0ge1xuICAgICAgY2xhc3NOYW1lOiBxdWVyeS5jbGFzc05hbWUsXG4gICAgICB3aGVyZTogcXVlcnkuX3doZXJlLFxuICAgIH07XG4gIH1cbiAgdmFyIHdoZXJlID0gZmxhdHRlbk9yUXVlcmllcyhxdWVyeS53aGVyZSB8fCB7fSk7XG4gIHZhciBjb2x1bW5zID0gW107XG4gIHZhciB2YWx1ZXMgPSBbXTtcbiAgdmFyIGk7XG4gIGlmIChBcnJheS5pc0FycmF5KHdoZXJlKSkge1xuICAgIHZhciB1bmlxdWVDb2x1bW5zID0ge307XG4gICAgZm9yIChpID0gMDsgaSA8IHdoZXJlLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgc3ViVmFsdWVzID0ge307XG4gICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHdoZXJlW2ldKTtcbiAgICAgIGtleXMuc29ydCgpO1xuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBrZXlzLmxlbmd0aDsgaisrKSB7XG4gICAgICAgIHN1YlZhbHVlc1trZXlzW2pdXSA9IHdoZXJlW2ldW2tleXNbal1dO1xuICAgICAgICB1bmlxdWVDb2x1bW5zW2tleXNbal1dID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHZhbHVlcy5wdXNoKHN1YlZhbHVlcyk7XG4gICAgfVxuICAgIGNvbHVtbnMgPSBPYmplY3Qua2V5cyh1bmlxdWVDb2x1bW5zKTtcbiAgICBjb2x1bW5zLnNvcnQoKTtcbiAgfSBlbHNlIHtcbiAgICBjb2x1bW5zID0gT2JqZWN0LmtleXMod2hlcmUpO1xuICAgIGNvbHVtbnMuc29ydCgpO1xuICAgIGZvciAoaSA9IDA7IGkgPCBjb2x1bW5zLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YWx1ZXMucHVzaCh3aGVyZVtjb2x1bW5zW2ldXSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIHNlY3Rpb25zID0gW2NvbHVtbnMuam9pbignLCcpLCBzdHJpbmdpZnkodmFsdWVzKV07XG5cbiAgcmV0dXJuIHF1ZXJ5LmNsYXNzTmFtZSArICc6JyArIHNlY3Rpb25zLmpvaW4oJ3wnKTtcbn1cblxuLyoqXG4gKiBjb250YWlucyAtLSBEZXRlcm1pbmVzIGlmIGFuIG9iamVjdCBpcyBjb250YWluZWQgaW4gYSBsaXN0IHdpdGggc3BlY2lhbCBoYW5kbGluZyBmb3IgUGFyc2UgcG9pbnRlcnMuXG4gKi9cbmZ1bmN0aW9uIGNvbnRhaW5zKGhheXN0YWNrOiBBcnJheSwgbmVlZGxlOiBhbnkpOiBib29sZWFuIHtcbiAgaWYgKG5lZWRsZSAmJiBuZWVkbGUuX190eXBlICYmIG5lZWRsZS5fX3R5cGUgPT09ICdQb2ludGVyJykge1xuICAgIGZvciAoY29uc3QgaSBpbiBoYXlzdGFjaykge1xuICAgICAgY29uc3QgcHRyID0gaGF5c3RhY2tbaV07XG4gICAgICBpZiAodHlwZW9mIHB0ciA9PT0gJ3N0cmluZycgJiYgcHRyID09PSBuZWVkbGUub2JqZWN0SWQpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBpZiAocHRyLmNsYXNzTmFtZSA9PT0gbmVlZGxlLmNsYXNzTmFtZSAmJiBwdHIub2JqZWN0SWQgPT09IG5lZWRsZS5vYmplY3RJZCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiBoYXlzdGFjay5pbmRleE9mKG5lZWRsZSkgPiAtMTtcbn1cbi8qKlxuICogbWF0Y2hlc1F1ZXJ5IC0tIERldGVybWluZXMgaWYgYW4gb2JqZWN0IHdvdWxkIGJlIHJldHVybmVkIGJ5IGEgUGFyc2UgUXVlcnlcbiAqIEl0J3MgYSBsaWdodHdlaWdodCwgd2hlcmUtY2xhdXNlIG9ubHkgaW1wbGVtZW50YXRpb24gb2YgYSBmdWxsIHF1ZXJ5IGVuZ2luZS5cbiAqIFNpbmNlIHdlIGZpbmQgcXVlcmllcyB0aGF0IG1hdGNoIG9iamVjdHMsIHJhdGhlciB0aGFuIG9iamVjdHMgdGhhdCBtYXRjaFxuICogcXVlcmllcywgd2UgY2FuIGF2b2lkIGJ1aWxkaW5nIGEgZnVsbC1ibG93biBxdWVyeSB0b29sLlxuICovXG5mdW5jdGlvbiBtYXRjaGVzUXVlcnkob2JqZWN0OiBhbnksIHF1ZXJ5OiBhbnkpOiBib29sZWFuIHtcbiAgaWYgKHF1ZXJ5IGluc3RhbmNlb2YgUGFyc2UuUXVlcnkpIHtcbiAgICB2YXIgY2xhc3NOYW1lID0gb2JqZWN0LmlkIGluc3RhbmNlb2YgSWQgPyBvYmplY3QuaWQuY2xhc3NOYW1lIDogb2JqZWN0LmNsYXNzTmFtZTtcbiAgICBpZiAoY2xhc3NOYW1lICE9PSBxdWVyeS5jbGFzc05hbWUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoZXNRdWVyeShvYmplY3QsIHF1ZXJ5Ll93aGVyZSk7XG4gIH1cbiAgZm9yICh2YXIgZmllbGQgaW4gcXVlcnkpIHtcbiAgICBpZiAoIW1hdGNoZXNLZXlDb25zdHJhaW50cyhvYmplY3QsIGZpZWxkLCBxdWVyeVtmaWVsZF0pKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBlcXVhbE9iamVjdHNHZW5lcmljKG9iaiwgY29tcGFyZVRvLCBlcWxGbikge1xuICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChlcWxGbihvYmpbaV0sIGNvbXBhcmVUbykpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiBlcWxGbihvYmosIGNvbXBhcmVUbyk7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIGFuIG9iamVjdCBtYXRjaGVzIGEgc2luZ2xlIGtleSdzIGNvbnN0cmFpbnRzXG4gKi9cbmZ1bmN0aW9uIG1hdGNoZXNLZXlDb25zdHJhaW50cyhvYmplY3QsIGtleSwgY29uc3RyYWludHMpIHtcbiAgaWYgKGNvbnN0cmFpbnRzID09PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChrZXkuaW5kZXhPZignLicpID49IDApIHtcbiAgICAvLyBLZXkgcmVmZXJlbmNlcyBhIHN1Ym9iamVjdFxuICAgIHZhciBrZXlDb21wb25lbnRzID0ga2V5LnNwbGl0KCcuJyk7XG4gICAgdmFyIHN1Yk9iamVjdEtleSA9IGtleUNvbXBvbmVudHNbMF07XG4gICAgdmFyIGtleVJlbWFpbmRlciA9IGtleUNvbXBvbmVudHMuc2xpY2UoMSkuam9pbignLicpO1xuICAgIHJldHVybiBtYXRjaGVzS2V5Q29uc3RyYWludHMob2JqZWN0W3N1Yk9iamVjdEtleV0gfHwge30sIGtleVJlbWFpbmRlciwgY29uc3RyYWludHMpO1xuICB9XG4gIHZhciBpO1xuICBpZiAoa2V5ID09PSAnJG9yJykge1xuICAgIGZvciAoaSA9IDA7IGkgPCBjb25zdHJhaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKG1hdGNoZXNRdWVyeShvYmplY3QsIGNvbnN0cmFpbnRzW2ldKSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChrZXkgPT09ICckYW5kJykge1xuICAgIGZvciAoaSA9IDA7IGkgPCBjb25zdHJhaW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKCFtYXRjaGVzUXVlcnkob2JqZWN0LCBjb25zdHJhaW50c1tpXSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoa2V5ID09PSAnJG5vcicpIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgY29uc3RyYWludHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChtYXRjaGVzUXVlcnkob2JqZWN0LCBjb25zdHJhaW50c1tpXSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoa2V5ID09PSAnJHJlbGF0ZWRUbycpIHtcbiAgICAvLyBCYWlsISBXZSBjYW4ndCBoYW5kbGUgcmVsYXRpb25hbCBxdWVyaWVzIGxvY2FsbHlcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gRGVjb2RlIERhdGUgSlNPTiB2YWx1ZVxuICBpZiAob2JqZWN0W2tleV0gJiYgb2JqZWN0W2tleV0uX190eXBlID09ICdEYXRlJykge1xuICAgIG9iamVjdFtrZXldID0gbmV3IERhdGUob2JqZWN0W2tleV0uaXNvKTtcbiAgfVxuICAvLyBFcXVhbGl0eSAob3IgQXJyYXkgY29udGFpbnMpIGNhc2VzXG4gIGlmICh0eXBlb2YgY29uc3RyYWludHMgIT09ICdvYmplY3QnKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0W2tleV0pKSB7XG4gICAgICByZXR1cm4gb2JqZWN0W2tleV0uaW5kZXhPZihjb25zdHJhaW50cykgPiAtMTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdFtrZXldID09PSBjb25zdHJhaW50cztcbiAgfVxuICB2YXIgY29tcGFyZVRvO1xuICBpZiAoY29uc3RyYWludHMuX190eXBlKSB7XG4gICAgaWYgKGNvbnN0cmFpbnRzLl9fdHlwZSA9PT0gJ1BvaW50ZXInKSB7XG4gICAgICByZXR1cm4gZXF1YWxPYmplY3RzR2VuZXJpYyhvYmplY3Rba2V5XSwgY29uc3RyYWludHMsIGZ1bmN0aW9uIChvYmosIHB0cikge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIHR5cGVvZiBvYmogIT09ICd1bmRlZmluZWQnICYmXG4gICAgICAgICAgcHRyLmNsYXNzTmFtZSA9PT0gb2JqLmNsYXNzTmFtZSAmJlxuICAgICAgICAgIHB0ci5vYmplY3RJZCA9PT0gb2JqLm9iamVjdElkXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXF1YWxPYmplY3RzR2VuZXJpYyhvYmplY3Rba2V5XSwgUGFyc2UuX2RlY29kZShrZXksIGNvbnN0cmFpbnRzKSwgZXF1YWxPYmplY3RzKTtcbiAgfVxuICAvLyBNb3JlIGNvbXBsZXggY2FzZXNcbiAgZm9yICh2YXIgY29uZGl0aW9uIGluIGNvbnN0cmFpbnRzKSB7XG4gICAgY29tcGFyZVRvID0gY29uc3RyYWludHNbY29uZGl0aW9uXTtcbiAgICBpZiAoY29tcGFyZVRvLl9fdHlwZSkge1xuICAgICAgY29tcGFyZVRvID0gUGFyc2UuX2RlY29kZShrZXksIGNvbXBhcmVUbyk7XG4gICAgfVxuICAgIHN3aXRjaCAoY29uZGl0aW9uKSB7XG4gICAgICBjYXNlICckbHQnOlxuICAgICAgICBpZiAob2JqZWN0W2tleV0gPj0gY29tcGFyZVRvKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJGx0ZSc6XG4gICAgICAgIGlmIChvYmplY3Rba2V5XSA+IGNvbXBhcmVUbykge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRndCc6XG4gICAgICAgIGlmIChvYmplY3Rba2V5XSA8PSBjb21wYXJlVG8pIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICckZ3RlJzpcbiAgICAgICAgaWYgKG9iamVjdFtrZXldIDwgY29tcGFyZVRvKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJG5lJzpcbiAgICAgICAgaWYgKGVxdWFsT2JqZWN0cyhvYmplY3Rba2V5XSwgY29tcGFyZVRvKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRpbic6XG4gICAgICAgIGlmICghY29udGFpbnMoY29tcGFyZVRvLCBvYmplY3Rba2V5XSkpIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICckbmluJzpcbiAgICAgICAgaWYgKGNvbnRhaW5zKGNvbXBhcmVUbywgb2JqZWN0W2tleV0pKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJGFsbCc6XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb21wYXJlVG8ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBpZiAob2JqZWN0W2tleV0uaW5kZXhPZihjb21wYXJlVG9baV0pIDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRleGlzdHMnOiB7XG4gICAgICAgIGNvbnN0IHByb3BlcnR5RXhpc3RzID0gdHlwZW9mIG9iamVjdFtrZXldICE9PSAndW5kZWZpbmVkJztcbiAgICAgICAgY29uc3QgZXhpc3RlbmNlSXNSZXF1aXJlZCA9IGNvbnN0cmFpbnRzWyckZXhpc3RzJ107XG4gICAgICAgIGlmICh0eXBlb2YgY29uc3RyYWludHNbJyRleGlzdHMnXSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgLy8gVGhlIFNESyB3aWxsIG5ldmVyIHN1Ym1pdCBhIG5vbi1ib29sZWFuIGZvciAkZXhpc3RzLCBidXQgaWYgc29tZW9uZVxuICAgICAgICAgIC8vIHRyaWVzIHRvIHN1Ym1pdCBhIG5vbi1ib29sZWFuIGZvciAkZXhpdHMgb3V0c2lkZSB0aGUgU0RLcywganVzdCBpZ25vcmUgaXQuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCghcHJvcGVydHlFeGlzdHMgJiYgZXhpc3RlbmNlSXNSZXF1aXJlZCkgfHwgKHByb3BlcnR5RXhpc3RzICYmICFleGlzdGVuY2VJc1JlcXVpcmVkKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJyRyZWdleCc6XG4gICAgICAgIGlmICh0eXBlb2YgY29tcGFyZVRvID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIHJldHVybiBjb21wYXJlVG8udGVzdChvYmplY3Rba2V5XSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSlMgZG9lc24ndCBzdXBwb3J0IHBlcmwtc3R5bGUgZXNjYXBpbmdcbiAgICAgICAgdmFyIGV4cFN0cmluZyA9ICcnO1xuICAgICAgICB2YXIgZXNjYXBlRW5kID0gLTI7XG4gICAgICAgIHZhciBlc2NhcGVTdGFydCA9IGNvbXBhcmVUby5pbmRleE9mKCdcXFxcUScpO1xuICAgICAgICB3aGlsZSAoZXNjYXBlU3RhcnQgPiAtMSkge1xuICAgICAgICAgIC8vIEFkZCB0aGUgdW5lc2NhcGVkIHBvcnRpb25cbiAgICAgICAgICBleHBTdHJpbmcgKz0gY29tcGFyZVRvLnN1YnN0cmluZyhlc2NhcGVFbmQgKyAyLCBlc2NhcGVTdGFydCk7XG4gICAgICAgICAgZXNjYXBlRW5kID0gY29tcGFyZVRvLmluZGV4T2YoJ1xcXFxFJywgZXNjYXBlU3RhcnQpO1xuICAgICAgICAgIGlmIChlc2NhcGVFbmQgPiAtMSkge1xuICAgICAgICAgICAgZXhwU3RyaW5nICs9IGNvbXBhcmVUb1xuICAgICAgICAgICAgICAuc3Vic3RyaW5nKGVzY2FwZVN0YXJ0ICsgMiwgZXNjYXBlRW5kKVxuICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXFxcXFxcXFxcXFxcXEUvZywgJ1xcXFxFJylcbiAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcVy9nLCAnXFxcXCQmJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZXNjYXBlU3RhcnQgPSBjb21wYXJlVG8uaW5kZXhPZignXFxcXFEnLCBlc2NhcGVFbmQpO1xuICAgICAgICB9XG4gICAgICAgIGV4cFN0cmluZyArPSBjb21wYXJlVG8uc3Vic3RyaW5nKE1hdGgubWF4KGVzY2FwZVN0YXJ0LCBlc2NhcGVFbmQgKyAyKSk7XG4gICAgICAgIHZhciBleHAgPSBuZXcgUmVnRXhwKGV4cFN0cmluZywgY29uc3RyYWludHMuJG9wdGlvbnMgfHwgJycpO1xuICAgICAgICBpZiAoIWV4cC50ZXN0KG9iamVjdFtrZXldKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyRuZWFyU3BoZXJlJzpcbiAgICAgICAgaWYgKCFjb21wYXJlVG8gfHwgIW9iamVjdFtrZXldKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBkaXN0YW5jZSA9IGNvbXBhcmVUby5yYWRpYW5zVG8ob2JqZWN0W2tleV0pO1xuICAgICAgICB2YXIgbWF4ID0gY29uc3RyYWludHMuJG1heERpc3RhbmNlIHx8IEluZmluaXR5O1xuICAgICAgICByZXR1cm4gZGlzdGFuY2UgPD0gbWF4O1xuICAgICAgY2FzZSAnJHdpdGhpbic6XG4gICAgICAgIGlmICghY29tcGFyZVRvIHx8ICFvYmplY3Rba2V5XSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc291dGhXZXN0ID0gY29tcGFyZVRvLiRib3hbMF07XG4gICAgICAgIHZhciBub3J0aEVhc3QgPSBjb21wYXJlVG8uJGJveFsxXTtcbiAgICAgICAgaWYgKHNvdXRoV2VzdC5sYXRpdHVkZSA+IG5vcnRoRWFzdC5sYXRpdHVkZSB8fCBzb3V0aFdlc3QubG9uZ2l0dWRlID4gbm9ydGhFYXN0LmxvbmdpdHVkZSkge1xuICAgICAgICAgIC8vIEludmFsaWQgYm94LCBjcm9zc2VzIHRoZSBkYXRlIGxpbmVcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICBvYmplY3Rba2V5XS5sYXRpdHVkZSA+IHNvdXRoV2VzdC5sYXRpdHVkZSAmJlxuICAgICAgICAgIG9iamVjdFtrZXldLmxhdGl0dWRlIDwgbm9ydGhFYXN0LmxhdGl0dWRlICYmXG4gICAgICAgICAgb2JqZWN0W2tleV0ubG9uZ2l0dWRlID4gc291dGhXZXN0LmxvbmdpdHVkZSAmJlxuICAgICAgICAgIG9iamVjdFtrZXldLmxvbmdpdHVkZSA8IG5vcnRoRWFzdC5sb25naXR1ZGVcbiAgICAgICAgKTtcbiAgICAgIGNhc2UgJyRjb250YWluZWRCeSc6IHtcbiAgICAgICAgZm9yIChjb25zdCB2YWx1ZSBvZiBvYmplY3Rba2V5XSkge1xuICAgICAgICAgIGlmICghY29udGFpbnMoY29tcGFyZVRvLCB2YWx1ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgICBjYXNlICckZ2VvV2l0aGluJzoge1xuICAgICAgICBjb25zdCBwb2ludHMgPSBjb21wYXJlVG8uJHBvbHlnb24ubWFwKGdlb1BvaW50ID0+IFtnZW9Qb2ludC5sYXRpdHVkZSwgZ2VvUG9pbnQubG9uZ2l0dWRlXSk7XG4gICAgICAgIGNvbnN0IHBvbHlnb24gPSBuZXcgUGFyc2UuUG9seWdvbihwb2ludHMpO1xuICAgICAgICByZXR1cm4gcG9seWdvbi5jb250YWluc1BvaW50KG9iamVjdFtrZXldKTtcbiAgICAgIH1cbiAgICAgIGNhc2UgJyRnZW9JbnRlcnNlY3RzJzoge1xuICAgICAgICBjb25zdCBwb2x5Z29uID0gbmV3IFBhcnNlLlBvbHlnb24ob2JqZWN0W2tleV0uY29vcmRpbmF0ZXMpO1xuICAgICAgICBjb25zdCBwb2ludCA9IG5ldyBQYXJzZS5HZW9Qb2ludChjb21wYXJlVG8uJHBvaW50KTtcbiAgICAgICAgcmV0dXJuIHBvbHlnb24uY29udGFpbnNQb2ludChwb2ludCk7XG4gICAgICB9XG4gICAgICBjYXNlICckb3B0aW9ucyc6XG4gICAgICAgIC8vIE5vdCBhIHF1ZXJ5IHR5cGUsIGJ1dCBhIHdheSB0byBhZGQgb3B0aW9ucyB0byAkcmVnZXguIElnbm9yZSBhbmRcbiAgICAgICAgLy8gYXZvaWQgdGhlIGRlZmF1bHRcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICckbWF4RGlzdGFuY2UnOlxuICAgICAgICAvLyBOb3QgYSBxdWVyeSB0eXBlLCBidXQgYSB3YXkgdG8gYWRkIGEgY2FwIHRvICRuZWFyU3BoZXJlLiBJZ25vcmUgYW5kXG4gICAgICAgIC8vIGF2b2lkIHRoZSBkZWZhdWx0XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJHNlbGVjdCc6XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIGNhc2UgJyRkb250U2VsZWN0JzpcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxudmFyIFF1ZXJ5VG9vbHMgPSB7XG4gIHF1ZXJ5SGFzaDogcXVlcnlIYXNoLFxuICBtYXRjaGVzUXVlcnk6IG1hdGNoZXNRdWVyeSxcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUXVlcnlUb29scztcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/RequestSchema.js b/lib/LiveQuery/RequestSchema.js deleted file mode 100644 index 08cb08c4c0..0000000000 --- a/lib/LiveQuery/RequestSchema.js +++ /dev/null @@ -1,146 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; -const general = { - title: 'General request schema', - type: 'object', - properties: { - op: { - type: 'string', - enum: ['connect', 'subscribe', 'unsubscribe', 'update'] - } - }, - required: ['op'] -}; -const connect = { - title: 'Connect operation schema', - type: 'object', - properties: { - op: 'connect', - applicationId: { - type: 'string' - }, - javascriptKey: { - type: 'string' - }, - masterKey: { - type: 'string' - }, - clientKey: { - type: 'string' - }, - windowsKey: { - type: 'string' - }, - restAPIKey: { - type: 'string' - }, - sessionToken: { - type: 'string' - }, - installationId: { - type: 'string' - } - }, - required: ['op', 'applicationId'], - additionalProperties: false -}; -const subscribe = { - title: 'Subscribe operation schema', - type: 'object', - properties: { - op: 'subscribe', - requestId: { - type: 'number' - }, - query: { - title: 'Query field schema', - type: 'object', - properties: { - className: { - type: 'string' - }, - where: { - type: 'object' - }, - fields: { - type: 'array', - items: { - type: 'string' - }, - minItems: 1, - uniqueItems: true - } - }, - required: ['where', 'className'], - additionalProperties: false - }, - sessionToken: { - type: 'string' - } - }, - required: ['op', 'requestId', 'query'], - additionalProperties: false -}; -const update = { - title: 'Update operation schema', - type: 'object', - properties: { - op: 'update', - requestId: { - type: 'number' - }, - query: { - title: 'Query field schema', - type: 'object', - properties: { - className: { - type: 'string' - }, - where: { - type: 'object' - }, - fields: { - type: 'array', - items: { - type: 'string' - }, - minItems: 1, - uniqueItems: true - } - }, - required: ['where', 'className'], - additionalProperties: false - }, - sessionToken: { - type: 'string' - } - }, - required: ['op', 'requestId', 'query'], - additionalProperties: false -}; -const unsubscribe = { - title: 'Unsubscribe operation schema', - type: 'object', - properties: { - op: 'unsubscribe', - requestId: { - type: 'number' - } - }, - required: ['op', 'requestId'], - additionalProperties: false -}; -const RequestSchema = { - general: general, - connect: connect, - subscribe: subscribe, - update: update, - unsubscribe: unsubscribe -}; -var _default = RequestSchema; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvUmVxdWVzdFNjaGVtYS5qcyJdLCJuYW1lcyI6WyJnZW5lcmFsIiwidGl0bGUiLCJ0eXBlIiwicHJvcGVydGllcyIsIm9wIiwiZW51bSIsInJlcXVpcmVkIiwiY29ubmVjdCIsImFwcGxpY2F0aW9uSWQiLCJqYXZhc2NyaXB0S2V5IiwibWFzdGVyS2V5IiwiY2xpZW50S2V5Iiwid2luZG93c0tleSIsInJlc3RBUElLZXkiLCJzZXNzaW9uVG9rZW4iLCJpbnN0YWxsYXRpb25JZCIsImFkZGl0aW9uYWxQcm9wZXJ0aWVzIiwic3Vic2NyaWJlIiwicmVxdWVzdElkIiwicXVlcnkiLCJjbGFzc05hbWUiLCJ3aGVyZSIsImZpZWxkcyIsIml0ZW1zIiwibWluSXRlbXMiLCJ1bmlxdWVJdGVtcyIsInVwZGF0ZSIsInVuc3Vic2NyaWJlIiwiUmVxdWVzdFNjaGVtYSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsTUFBTUEsT0FBTyxHQUFHO0FBQ2RDLEVBQUFBLEtBQUssRUFBRSx3QkFETztBQUVkQyxFQUFBQSxJQUFJLEVBQUUsUUFGUTtBQUdkQyxFQUFBQSxVQUFVLEVBQUU7QUFDVkMsSUFBQUEsRUFBRSxFQUFFO0FBQ0ZGLE1BQUFBLElBQUksRUFBRSxRQURKO0FBRUZHLE1BQUFBLElBQUksRUFBRSxDQUFDLFNBQUQsRUFBWSxXQUFaLEVBQXlCLGFBQXpCLEVBQXdDLFFBQXhDO0FBRko7QUFETSxHQUhFO0FBU2RDLEVBQUFBLFFBQVEsRUFBRSxDQUFDLElBQUQ7QUFUSSxDQUFoQjtBQVlBLE1BQU1DLE9BQU8sR0FBRztBQUNkTixFQUFBQSxLQUFLLEVBQUUsMEJBRE87QUFFZEMsRUFBQUEsSUFBSSxFQUFFLFFBRlE7QUFHZEMsRUFBQUEsVUFBVSxFQUFFO0FBQ1ZDLElBQUFBLEVBQUUsRUFBRSxTQURNO0FBRVZJLElBQUFBLGFBQWEsRUFBRTtBQUNiTixNQUFBQSxJQUFJLEVBQUU7QUFETyxLQUZMO0FBS1ZPLElBQUFBLGFBQWEs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LENBTEo7QUFNTkMsVUFBQUEsV0FBVyxFQUFFO0FBTlA7QUFQRSxPQUhQO0FBbUJMbkIsTUFBQUEsUUFBUSxFQUFFLENBQUMsT0FBRCxFQUFVLFdBQVYsQ0FuQkw7QUFvQkxVLE1BQUFBLG9CQUFvQixFQUFFO0FBcEJqQixLQUxHO0FBMkJWRixJQUFBQSxZQUFZLEVBQUU7QUFDWlosTUFBQUEsSUFBSSxFQUFFO0FBRE07QUEzQkosR0FIQztBQWtDYkksRUFBQUEsUUFBUSxFQUFFLENBQUMsSUFBRCxFQUFPLFdBQVAsRUFBb0IsT0FBcEIsQ0FsQ0c7QUFtQ2JVLEVBQUFBLG9CQUFvQixFQUFFO0FBbkNULENBQWY7QUFzQ0EsTUFBTVcsV0FBVyxHQUFHO0FBQ2xCMUIsRUFBQUEsS0FBSyxFQUFFLDhCQURXO0FBRWxCQyxFQUFBQSxJQUFJLEVBQUUsUUFGWTtBQUdsQkMsRUFBQUEsVUFBVSxFQUFFO0FBQ1ZDLElBQUFBLEVBQUUsRUFBRSxhQURNO0FBRVZjLElBQUFBLFNBQVMsRUFBRTtBQUNUaEIsTUFBQUEsSUFBSSxFQUFFO0FBREc7QUFGRCxHQUhNO0FBU2xCSSxFQUFBQSxRQUFRLEVBQUUsQ0FBQyxJQUFELEVBQU8sV0FBUCxDQVRRO0FBVWxCVSxFQUFBQSxvQkFBb0IsRUFBRTtBQVZKLENBQXBCO0FBYUEsTUFBTVksYUFBYSxHQUFHO0FBQ3BCNUIsRUFBQUEsT0FBTyxFQUFFQSxPQURXO0FBRXBCTyxFQUFBQSxPQUFPLEVBQUVBLE9BRlc7QUFHcEJVLEVBQUFBLFNBQVMsRUFBRUEsU0FIUztBQUlwQlMsRUFBQUEsTUFBTSxFQUFFQSxNQUpZO0FBS3BCQyxFQUFBQSxXQUFXLEVBQUVBO0FBTE8sQ0FBdEI7ZUFRZUMsYSIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGdlbmVyYWwgPSB7XG4gIHRpdGxlOiAnR2VuZXJhbCByZXF1ZXN0IHNjaGVtYScsXG4gIHR5cGU6ICdvYmplY3QnLFxuICBwcm9wZXJ0aWVzOiB7XG4gICAgb3A6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgZW51bTogWydjb25uZWN0JywgJ3N1YnNjcmliZScsICd1bnN1YnNjcmliZScsICd1cGRhdGUnXSxcbiAgICB9LFxuICB9LFxuICByZXF1aXJlZDogWydvcCddLFxufTtcblxuY29uc3QgY29ubmVjdCA9IHtcbiAgdGl0bGU6ICdDb25uZWN0IG9wZXJhdGlvbiBzY2hlbWEnLFxuICB0eXBlOiAnb2JqZWN0JyxcbiAgcHJvcGVydGllczoge1xuICAgIG9wOiAnY29ubmVjdCcsXG4gICAgYXBwbGljYXRpb25JZDoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgICBqYXZhc2NyaXB0S2V5OiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICB9LFxuICAgIG1hc3RlcktleToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgICBjbGllbnRLZXk6IHtcbiAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgIH0sXG4gICAgd2luZG93c0tleToge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgICByZXN0QVBJS2V5OiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICB9LFxuICAgIHNlc3Npb25Ub2tlbjoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgICBpbnN0YWxsYXRpb25JZDoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgfSxcbiAgcmVxdWlyZWQ6IFsnb3AnLCAnYXBwbGljYXRpb25JZCddLFxuICBhZGRpdGlvbmFsUHJvcGVydGllczogZmFsc2UsXG59O1xuXG5jb25zdCBzdWJzY3JpYmUgPSB7XG4gIHRpdGxlOiAnU3Vic2NyaWJlIG9wZXJhdGlvbiBzY2hlbWEnLFxuICB0eXBlOiAnb2JqZWN0JyxcbiAgcHJvcGVydGllczoge1xuICAgIG9wOiAnc3Vic2NyaWJlJyxcbiAgICByZXF1ZXN0SWQ6IHtcbiAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgIH0sXG4gICAgcXVlcnk6IHtcbiAgICAgIHRpdGxlOiAnUXVlcnkgZmllbGQgc2NoZW1hJyxcbiAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBjbGFzc05hbWU6IHtcbiAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgfSxcbiAgICAgICAgd2hlcmU6IHtcbiAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgfSxcbiAgICAgICAgZmllbGRzOiB7XG4gICAgICAgICAgdHlwZTogJ2FycmF5JyxcbiAgICAgICAgICBpdGVtczoge1xuICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBtaW5JdGVtczogMSxcbiAgICAgICAgICB1bmlxdWVJdGVtczogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICByZXF1aXJlZDogWyd3aGVyZScsICdjbGFzc05hbWUnXSxcbiAgICAgIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbiAgICB9LFxuICAgIHNlc3Npb25Ub2tlbjoge1xuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgfSxcbiAgfSxcbiAgcmVxdWlyZWQ6IFsnb3AnLCAncmVxdWVzdElkJywgJ3F1ZXJ5J10sXG4gIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbn07XG5cbmNvbnN0IHVwZGF0ZSA9IHtcbiAgdGl0bGU6ICdVcGRhdGUgb3BlcmF0aW9uIHNjaGVtYScsXG4gIHR5cGU6ICdvYmplY3QnLFxuICBwcm9wZXJ0aWVzOiB7XG4gICAgb3A6ICd1cGRhdGUnLFxuICAgIHJlcXVlc3RJZDoge1xuICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgfSxcbiAgICBxdWVyeToge1xuICAgICAgdGl0bGU6ICdRdWVyeSBmaWVsZCBzY2hlbWEnLFxuICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGNsYXNzTmFtZToge1xuICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICB9LFxuICAgICAgICB3aGVyZToge1xuICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICB9LFxuICAgICAgICBmaWVsZHM6IHtcbiAgICAgICAgICB0eXBlOiAnYXJyYXknLFxuICAgICAgICAgIGl0ZW1zOiB7XG4gICAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG1pbkl0ZW1zOiAxLFxuICAgICAgICAgIHVuaXF1ZUl0ZW1zOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbJ3doZXJlJywgJ2NsYXNzTmFtZSddLFxuICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxuICAgIH0sXG4gICAgc2Vzc2lvblRva2VuOiB7XG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICB9LFxuICB9LFxuICByZXF1aXJlZDogWydvcCcsICdyZXF1ZXN0SWQnLCAncXVlcnknXSxcbiAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxufTtcblxuY29uc3QgdW5zdWJzY3JpYmUgPSB7XG4gIHRpdGxlOiAnVW5zdWJzY3JpYmUgb3BlcmF0aW9uIHNjaGVtYScsXG4gIHR5cGU6ICdvYmplY3QnLFxuICBwcm9wZXJ0aWVzOiB7XG4gICAgb3A6ICd1bnN1YnNjcmliZScsXG4gICAgcmVxdWVzdElkOiB7XG4gICAgICB0eXBlOiAnbnVtYmVyJyxcbiAgICB9LFxuICB9LFxuICByZXF1aXJlZDogWydvcCcsICdyZXF1ZXN0SWQnXSxcbiAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxufTtcblxuY29uc3QgUmVxdWVzdFNjaGVtYSA9IHtcbiAgZ2VuZXJhbDogZ2VuZXJhbCxcbiAgY29ubmVjdDogY29ubmVjdCxcbiAgc3Vic2NyaWJlOiBzdWJzY3JpYmUsXG4gIHVwZGF0ZTogdXBkYXRlLFxuICB1bnN1YnNjcmliZTogdW5zdWJzY3JpYmUsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBSZXF1ZXN0U2NoZW1hO1xuIl19 \ No newline at end of file diff --git a/lib/LiveQuery/SessionTokenCache.js b/lib/LiveQuery/SessionTokenCache.js deleted file mode 100644 index 07a9a06965..0000000000 --- a/lib/LiveQuery/SessionTokenCache.js +++ /dev/null @@ -1,67 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.SessionTokenCache = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _lruCache = _interopRequireDefault(require("lru-cache")); - -var _logger = _interopRequireDefault(require("../logger")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function userForSessionToken(sessionToken) { - var q = new _node.default.Query('_Session'); - q.equalTo('sessionToken', sessionToken); - return q.first({ - useMasterKey: true - }).then(function (session) { - if (!session) { - return Promise.reject('No session found for session token'); - } - - return session.get('user'); - }); -} - -class SessionTokenCache { - constructor(timeout = 30 * 24 * 60 * 60 * 1000, maxSize = 10000) { - this.cache = new _lruCache.default({ - max: maxSize, - maxAge: timeout - }); - } - - getUserId(sessionToken) { - if (!sessionToken) { - return Promise.reject('Empty sessionToken'); - } - - const userId = this.cache.get(sessionToken); - - if (userId) { - _logger.default.verbose('Fetch userId %s of sessionToken %s from Cache', userId, sessionToken); - - return Promise.resolve(userId); - } - - return userForSessionToken(sessionToken).then(user => { - _logger.default.verbose('Fetch userId %s of sessionToken %s from Parse', user.id, sessionToken); - - const userId = user.id; - this.cache.set(sessionToken, userId); - return Promise.resolve(userId); - }, error => { - _logger.default.error('Can not fetch userId for sessionToken %j, error %j', sessionToken, error); - - return Promise.reject(error); - }); - } - -} - -exports.SessionTokenCache = SessionTokenCache; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvU2Vzc2lvblRva2VuQ2FjaGUuanMiXSwibmFtZXMiOlsidXNlckZvclNlc3Npb25Ub2tlbiIsInNlc3Npb25Ub2tlbiIsInEiLCJQYXJzZSIsIlF1ZXJ5IiwiZXF1YWxUbyIsImZpcnN0IiwidXNlTWFzdGVyS2V5IiwidGhlbiIsInNlc3Npb24iLCJQcm9taXNlIiwicmVqZWN0IiwiZ2V0IiwiU2Vzc2lvblRva2VuQ2FjaGUiLCJjb25zdHJ1Y3RvciIsInRpbWVvdXQiLCJtYXhTaXplIiwiY2FjaGUiLCJMUlUiLCJtYXgiLCJtYXhBZ2UiLCJnZXRVc2VySWQiLCJ1c2VySWQiLCJsb2dnZXIiLCJ2ZXJib3NlIiwicmVzb2x2ZSIsInVzZXIiLCJpZCIsInNldCIsImVycm9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxTQUFTQSxtQkFBVCxDQUE2QkMsWUFBN0IsRUFBMkM7QUFDekMsTUFBSUMsQ0FBQyxHQUFHLElBQUlDLGNBQU1DLEtBQVYsQ0FBZ0IsVUFBaEIsQ0FBUjtBQUNBRixFQUFBQSxDQUFDLENBQUNHLE9BQUYsQ0FBVSxjQUFWLEVBQTBCSixZQUExQjtBQUNBLFNBQU9DLENBQUMsQ0FBQ0ksS0FBRixDQUFRO0FBQUVDLElBQUFBLFlBQVksRUFBRTtBQUFoQixHQUFSLEVBQWdDQyxJQUFoQyxDQUFxQyxVQUFVQyxPQUFWLEVBQW1CO0FBQzdELFFBQUksQ0FBQ0EsT0FBTCxFQUFjO0FBQ1osYUFBT0MsT0FBTyxDQUFDQyxNQUFSLENBQWUsb0NBQWYsQ0FBUDtBQUNEOztBQUNELFdBQU9GLE9BQU8sQ0FBQ0csR0FBUixDQUFZLE1BQVosQ0FBUDtBQUNELEdBTE0sQ0FBUDtBQU1EOztBQUVELE1BQU1DLGlCQUFOLENBQXdCO0FBR3RCQyxFQUFBQSxXQUFXLENBQUNDLE9BQWUsR0FBRyxLQUFLLEVBQUwsR0FBVSxFQUFWLEdBQWUsRUFBZixHQUFvQixJQUF2QyxFQUE2Q0MsT0FBZSxHQUFHLEtBQS9ELEVBQXNFO0FBQy9FLFNBQUtDLEtBQUwsR0FBYSxJQUFJQyxpQkFBSixDQUFRO0FBQ25CQyxNQUFBQSxHQUFHLEVBQUVILE9BRGM7QUFFbkJJLE1BQUFBLE1BQU0sRUFBRUw7QUFGVyxLQUFSLENBQWI7QUFJRDs7QUFFRE0sRUFBQUEsU0FBUyxDQUFDcEIsWUFBRCxFQUE0QjtBQUNuQyxRQUFJLENBQUNBLFlBQUwsRUFBbUI7QUFDakIsYUFBT1MsT0FBTyxDQUFDQyxNQUFSLENBQWUsb0JBQWYsQ0FBUDtBQUNEOztBQUNELFVBQU1XLE1BQU0sR0FBRyxLQUFLTCxLQUFMLENBQVdMLEdBQVgsQ0FBZVgsWUFBZixDQUFmOztBQUNBLFFBQUlxQixNQUFKLEVBQVk7QUFDVkMsc0JBQU9DLE9BQVAsQ0FBZSwrQ0FBZixFQUFnRUYsTUFBaEUsRUFBd0VyQixZQUF4RTs7QUFDQSxhQUFPUyxPQUFPLENBQUNlLE9BQVIsQ0FBZ0JILE1BQWhCLENBQVA7QUFDRDs7QUFDRCxXQUFPdEIsbUJBQW1CLENBQUNDLFlBQUQsQ0FBbkIsQ0FBa0NPLElBQWxDLENBQ0xrQixJQUFJLElBQUk7QUFDTkgsc0JBQU9DLE9BQVAsQ0FBZSwrQ0FBZixFQUFnRUUsSUFBSSxDQUFDQyxFQUFyRSxFQUF5RTFCLFlBQXpFOztBQUNBLFlBQU1xQixNQUFNLEdBQUdJLElBQUksQ0FBQ0MsRUFBcEI7QUFDQSxXQUFLVixLQUFMLENBQVdXLEdBQVgsQ0FBZTNCLFlBQWYsRUFBNkJxQixNQUE3QjtBQUNBLGFBQU9aLE9BQU8sQ0FBQ2UsT0FBUixDQUFnQkgsTUFBaEIsQ0FBUDtBQUNELEtBTkksRUFPTE8sS0FBSyxJQUFJO0FBQ1BOLHNCQUFPTSxLQUFQLENBQWEsb0RBQWIsRUFBbUU1QixZQUFuRSxFQUFpRjRCLEtBQWpGOztBQUNBLGFBQU9uQixPQUFPLENBQUNDLE1BQVIsQ0FBZWtCLEtBQWYsQ0FBUDtBQUNELEtBVkksQ0FBUDtBQVlEOztBQS9CcUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgTFJVIGZyb20gJ2xydS1jYWNoZSc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5cbmZ1bmN0aW9uIHVzZXJGb3JTZXNzaW9uVG9rZW4oc2Vzc2lvblRva2VuKSB7XG4gIHZhciBxID0gbmV3IFBhcnNlLlF1ZXJ5KCdfU2Vzc2lvbicpO1xuICBxLmVxdWFsVG8oJ3Nlc3Npb25Ub2tlbicsIHNlc3Npb25Ub2tlbik7XG4gIHJldHVybiBxLmZpcnN0KHsgdXNlTWFzdGVyS2V5OiB0cnVlIH0pLnRoZW4oZnVuY3Rpb24gKHNlc3Npb24pIHtcbiAgICBpZiAoIXNlc3Npb24pIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCgnTm8gc2Vzc2lvbiBmb3VuZCBmb3Igc2Vzc2lvbiB0b2tlbicpO1xuICAgIH1cbiAgICByZXR1cm4gc2Vzc2lvbi5nZXQoJ3VzZXInKTtcbiAgfSk7XG59XG5cbmNsYXNzIFNlc3Npb25Ub2tlbkNhY2hlIHtcbiAgY2FjaGU6IE9iamVjdDtcblxuICBjb25zdHJ1Y3Rvcih0aW1lb3V0OiBudW1iZXIgPSAzMCAqIDI0ICogNjAgKiA2MCAqIDEwMDAsIG1heFNpemU6IG51bWJlciA9IDEwMDAwKSB7XG4gICAgdGhpcy5jYWNoZSA9IG5ldyBMUlUoe1xuICAgICAgbWF4OiBtYXhTaXplLFxuICAgICAgbWF4QWdlOiB0aW1lb3V0LFxuICAgIH0pO1xuICB9XG5cbiAgZ2V0VXNlcklkKHNlc3Npb25Ub2tlbjogc3RyaW5nKTogYW55IHtcbiAgICBpZiAoIXNlc3Npb25Ub2tlbikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdFbXB0eSBzZXNzaW9uVG9rZW4nKTtcbiAgICB9XG4gICAgY29uc3QgdXNlcklkID0gdGhpcy5jYWNoZS5nZXQoc2Vzc2lvblRva2VuKTtcbiAgICBpZiAodXNlcklkKSB7XG4gICAgICBsb2dnZXIudmVyYm9zZSgnRmV0Y2ggdXNlcklkICVzIG9mIHNlc3Npb25Ub2tlbiAlcyBmcm9tIENhY2hlJywgdXNlcklkLCBzZXNzaW9uVG9rZW4pO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh1c2VySWQpO1xuICAgIH1cbiAgICByZXR1cm4gdXNlckZvclNlc3Npb25Ub2tlbihzZXNzaW9uVG9rZW4pLnRoZW4oXG4gICAgICB1c2VyID0+IHtcbiAgICAgICAgbG9nZ2VyLnZlcmJvc2UoJ0ZldGNoIHVzZXJJZCAlcyBvZiBzZXNzaW9uVG9rZW4gJXMgZnJvbSBQYXJzZScsIHVzZXIuaWQsIHNlc3Npb25Ub2tlbik7XG4gICAgICAgIGNvbnN0IHVzZXJJZCA9IHVzZXIuaWQ7XG4gICAgICAgIHRoaXMuY2FjaGUuc2V0KHNlc3Npb25Ub2tlbiwgdXNlcklkKTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh1c2VySWQpO1xuICAgICAgfSxcbiAgICAgIGVycm9yID0+IHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKCdDYW4gbm90IGZldGNoIHVzZXJJZCBmb3Igc2Vzc2lvblRva2VuICVqLCBlcnJvciAlaicsIHNlc3Npb25Ub2tlbiwgZXJyb3IpO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpO1xuICAgICAgfVxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IHsgU2Vzc2lvblRva2VuQ2FjaGUgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/Subscription.js b/lib/LiveQuery/Subscription.js deleted file mode 100644 index a424955752..0000000000 --- a/lib/LiveQuery/Subscription.js +++ /dev/null @@ -1,61 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.Subscription = void 0; - -var _logger = _interopRequireDefault(require("../logger")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class Subscription { - // It is query condition eg query.where - constructor(className, query, queryHash) { - this.className = className; - this.query = query; - this.hash = queryHash; - this.clientRequestIds = new Map(); - } - - addClientSubscription(clientId, requestId) { - if (!this.clientRequestIds.has(clientId)) { - this.clientRequestIds.set(clientId, []); - } - - const requestIds = this.clientRequestIds.get(clientId); - requestIds.push(requestId); - } - - deleteClientSubscription(clientId, requestId) { - const requestIds = this.clientRequestIds.get(clientId); - - if (typeof requestIds === 'undefined') { - _logger.default.error('Can not find client %d to delete', clientId); - - return; - } - - const index = requestIds.indexOf(requestId); - - if (index < 0) { - _logger.default.error('Can not find client %d subscription %d to delete', clientId, requestId); - - return; - } - - requestIds.splice(index, 1); // Delete client reference if it has no subscription - - if (requestIds.length == 0) { - this.clientRequestIds.delete(clientId); - } - } - - hasSubscribingClient() { - return this.clientRequestIds.size > 0; - } - -} - -exports.Subscription = Subscription; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvU3Vic2NyaXB0aW9uLmpzIl0sIm5hbWVzIjpbIlN1YnNjcmlwdGlvbiIsImNvbnN0cnVjdG9yIiwiY2xhc3NOYW1lIiwicXVlcnkiLCJxdWVyeUhhc2giLCJoYXNoIiwiY2xpZW50UmVxdWVzdElkcyIsIk1hcCIsImFkZENsaWVudFN1YnNjcmlwdGlvbiIsImNsaWVudElkIiwicmVxdWVzdElkIiwiaGFzIiwic2V0IiwicmVxdWVzdElkcyIsImdldCIsInB1c2giLCJkZWxldGVDbGllbnRTdWJzY3JpcHRpb24iLCJsb2dnZXIiLCJlcnJvciIsImluZGV4IiwiaW5kZXhPZiIsInNwbGljZSIsImxlbmd0aCIsImRlbGV0ZSIsImhhc1N1YnNjcmliaW5nQ2xpZW50Iiwic2l6ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7O0FBS0EsTUFBTUEsWUFBTixDQUFtQjtBQUNqQjtBQU1BQyxFQUFBQSxXQUFXLENBQUNDLFNBQUQsRUFBb0JDLEtBQXBCLEVBQXNDQyxTQUF0QyxFQUF5RDtBQUNsRSxTQUFLRixTQUFMLEdBQWlCQSxTQUFqQjtBQUNBLFNBQUtDLEtBQUwsR0FBYUEsS0FBYjtBQUNBLFNBQUtFLElBQUwsR0FBWUQsU0FBWjtBQUNBLFNBQUtFLGdCQUFMLEdBQXdCLElBQUlDLEdBQUosRUFBeEI7QUFDRDs7QUFFREMsRUFBQUEscUJBQXFCLENBQUNDLFFBQUQsRUFBbUJDLFNBQW5CLEVBQTRDO0FBQy9ELFFBQUksQ0FBQyxLQUFLSixnQkFBTCxDQUFzQkssR0FBdEIsQ0FBMEJGLFFBQTFCLENBQUwsRUFBMEM7QUFDeEMsV0FBS0gsZ0JBQUwsQ0FBc0JNLEdBQXRCLENBQTBCSCxRQUExQixFQUFvQyxFQUFwQztBQUNEOztBQUNELFVBQU1JLFVBQVUsR0FBRyxLQUFLUCxnQkFBTCxDQUFzQlEsR0FBdEIsQ0FBMEJMLFFBQTFCLENBQW5CO0FBQ0FJLElBQUFBLFVBQVUsQ0FBQ0UsSUFBWCxDQUFnQkwsU0FBaEI7QUFDRDs7QUFFRE0sRUFBQUEsd0JBQXdCLENBQUNQLFFBQUQsRUFBbUJDLFNBQW5CLEVBQTRDO0FBQ2xFLFVBQU1HLFVBQVUsR0FBRyxLQUFLUCxnQkFBTCxDQUFzQlEsR0FBdEIsQ0FBMEJMLFFBQTFCLENBQW5COztBQUNBLFFBQUksT0FBT0ksVUFBUCxLQUFzQixXQUExQixFQUF1QztBQUNyQ0ksc0JBQU9DLEtBQVAsQ0FBYSxrQ0FBYixFQUFpRFQsUUFBakQ7O0FBQ0E7QUFDRDs7QUFFRCxVQUFNVSxLQUFLLEdBQUdOLFVBQVUsQ0FBQ08sT0FBWCxDQUFtQlYsU0FBbkIsQ0FBZDs7QUFDQSxRQUFJUyxLQUFLLEdBQUcsQ0FBWixFQUFlO0FBQ2JGLHNCQUFPQyxLQUFQLENBQWEsa0RBQWIsRUFBaUVULFFBQWpFLEVBQTJFQyxTQUEzRTs7QUFDQTtBQUNEOztBQUNERyxJQUFBQSxVQUFVLENBQUNRLE1BQVgsQ0FBa0JGLEtBQWxCLEVBQXlCLENBQXpCLEVBWmtFLENBYWxFOztBQUNBLFFBQUlOLFVBQVUsQ0FBQ1MsTUFBWCxJQUFxQixDQUF6QixFQUE0QjtBQUMxQixXQUFLaEIsZ0JBQUwsQ0FBc0JpQixNQUF0QixDQUE2QmQsUUFBN0I7QUFDRDtBQUNGOztBQUVEZSxFQUFBQSxvQkFBb0IsR0FBWTtBQUM5QixXQUFPLEtBQUtsQixnQkFBTCxDQUFzQm1CLElBQXRCLEdBQTZCLENBQXBDO0FBQ0Q7O0FBM0NnQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBsb2dnZXIgZnJvbSAnLi4vbG9nZ2VyJztcblxuZXhwb3J0IHR5cGUgRmxhdHRlbmVkT2JqZWN0RGF0YSA9IHsgW2F0dHI6IHN0cmluZ106IGFueSB9O1xuZXhwb3J0IHR5cGUgUXVlcnlEYXRhID0geyBbYXR0cjogc3RyaW5nXTogYW55IH07XG5cbmNsYXNzIFN1YnNjcmlwdGlvbiB7XG4gIC8vIEl0IGlzIHF1ZXJ5IGNvbmRpdGlvbiBlZyBxdWVyeS53aGVyZVxuICBxdWVyeTogUXVlcnlEYXRhO1xuICBjbGFzc05hbWU6IHN0cmluZztcbiAgaGFzaDogc3RyaW5nO1xuICBjbGllbnRSZXF1ZXN0SWRzOiBPYmplY3Q7XG5cbiAgY29uc3RydWN0b3IoY2xhc3NOYW1lOiBzdHJpbmcsIHF1ZXJ5OiBRdWVyeURhdGEsIHF1ZXJ5SGFzaDogc3RyaW5nKSB7XG4gICAgdGhpcy5jbGFzc05hbWUgPSBjbGFzc05hbWU7XG4gICAgdGhpcy5xdWVyeSA9IHF1ZXJ5O1xuICAgIHRoaXMuaGFzaCA9IHF1ZXJ5SGFzaDtcbiAgICB0aGlzLmNsaWVudFJlcXVlc3RJZHMgPSBuZXcgTWFwKCk7XG4gIH1cblxuICBhZGRDbGllbnRTdWJzY3JpcHRpb24oY2xpZW50SWQ6IG51bWJlciwgcmVxdWVzdElkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY2xpZW50UmVxdWVzdElkcy5oYXMoY2xpZW50SWQpKSB7XG4gICAgICB0aGlzLmNsaWVudFJlcXVlc3RJZHMuc2V0KGNsaWVudElkLCBbXSk7XG4gICAgfVxuICAgIGNvbnN0IHJlcXVlc3RJZHMgPSB0aGlzLmNsaWVudFJlcXVlc3RJZHMuZ2V0KGNsaWVudElkKTtcbiAgICByZXF1ZXN0SWRzLnB1c2gocmVxdWVzdElkKTtcbiAgfVxuXG4gIGRlbGV0ZUNsaWVudFN1YnNjcmlwdGlvbihjbGllbnRJZDogbnVtYmVyLCByZXF1ZXN0SWQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHJlcXVlc3RJZHMgPSB0aGlzLmNsaWVudFJlcXVlc3RJZHMuZ2V0KGNsaWVudElkKTtcbiAgICBpZiAodHlwZW9mIHJlcXVlc3RJZHMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0NhbiBub3QgZmluZCBjbGllbnQgJWQgdG8gZGVsZXRlJywgY2xpZW50SWQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGluZGV4ID0gcmVxdWVzdElkcy5pbmRleE9mKHJlcXVlc3RJZCk7XG4gICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgbG9nZ2VyLmVycm9yKCdDYW4gbm90IGZpbmQgY2xpZW50ICVkIHN1YnNjcmlwdGlvbiAlZCB0byBkZWxldGUnLCBjbGllbnRJZCwgcmVxdWVzdElkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcmVxdWVzdElkcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIC8vIERlbGV0ZSBjbGllbnQgcmVmZXJlbmNlIGlmIGl0IGhhcyBubyBzdWJzY3JpcHRpb25cbiAgICBpZiAocmVxdWVzdElkcy5sZW5ndGggPT0gMCkge1xuICAgICAgdGhpcy5jbGllbnRSZXF1ZXN0SWRzLmRlbGV0ZShjbGllbnRJZCk7XG4gICAgfVxuICB9XG5cbiAgaGFzU3Vic2NyaWJpbmdDbGllbnQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY2xpZW50UmVxdWVzdElkcy5zaXplID4gMDtcbiAgfVxufVxuXG5leHBvcnQgeyBTdWJzY3JpcHRpb24gfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/LiveQuery/equalObjects.js b/lib/LiveQuery/equalObjects.js deleted file mode 100644 index 7adfc2cc20..0000000000 --- a/lib/LiveQuery/equalObjects.js +++ /dev/null @@ -1,62 +0,0 @@ -"use strict"; - -var toString = Object.prototype.toString; -/** - * Determines whether two objects represent the same primitive, special Parse - * type, or full Parse Object. - */ - -function equalObjects(a, b) { - if (typeof a !== typeof b) { - return false; - } - - if (typeof a !== 'object') { - return a === b; - } - - if (a === b) { - return true; - } - - if (toString.call(a) === '[object Date]') { - if (toString.call(b) === '[object Date]') { - return +a === +b; - } - - return false; - } - - if (Array.isArray(a)) { - if (Array.isArray(b)) { - if (a.length !== b.length) { - return false; - } - - for (var i = 0; i < a.length; i++) { - if (!equalObjects(a[i], b[i])) { - return false; - } - } - - return true; - } - - return false; - } - - if (Object.keys(a).length !== Object.keys(b).length) { - return false; - } - - for (var key in a) { - if (!equalObjects(a[key], b[key])) { - return false; - } - } - - return true; -} - -module.exports = equalObjects; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9MaXZlUXVlcnkvZXF1YWxPYmplY3RzLmpzIl0sIm5hbWVzIjpbInRvU3RyaW5nIiwiT2JqZWN0IiwicHJvdG90eXBlIiwiZXF1YWxPYmplY3RzIiwiYSIsImIiLCJjYWxsIiwiQXJyYXkiLCJpc0FycmF5IiwibGVuZ3RoIiwiaSIsImtleXMiLCJrZXkiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLElBQUlBLFFBQVEsR0FBR0MsTUFBTSxDQUFDQyxTQUFQLENBQWlCRixRQUFoQztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUNBLFNBQVNHLFlBQVQsQ0FBc0JDLENBQXRCLEVBQXlCQyxDQUF6QixFQUE0QjtBQUMxQixNQUFJLE9BQU9ELENBQVAsS0FBYSxPQUFPQyxDQUF4QixFQUEyQjtBQUN6QixXQUFPLEtBQVA7QUFDRDs7QUFDRCxNQUFJLE9BQU9ELENBQVAsS0FBYSxRQUFqQixFQUEyQjtBQUN6QixXQUFPQSxDQUFDLEtBQUtDLENBQWI7QUFDRDs7QUFDRCxNQUFJRCxDQUFDLEtBQUtDLENBQVYsRUFBYTtBQUNYLFdBQU8sSUFBUDtBQUNEOztBQUNELE1BQUlMLFFBQVEsQ0FBQ00sSUFBVCxDQUFjRixDQUFkLE1BQXFCLGVBQXpCLEVBQTBDO0FBQ3hDLFFBQUlKLFFBQVEsQ0FBQ00sSUFBVCxDQUFjRCxDQUFkLE1BQXFCLGVBQXpCLEVBQTBDO0FBQ3hDLGFBQU8sQ0FBQ0QsQ0FBRCxLQUFPLENBQUNDLENBQWY7QUFDRDs7QUFDRCxXQUFPLEtBQVA7QUFDRDs7QUFDRCxNQUFJRSxLQUFLLENBQUNDLE9BQU4sQ0FBY0osQ0FBZCxDQUFKLEVBQXNCO0FBQ3BCLFFBQUlHLEtBQUssQ0FBQ0MsT0FBTixDQUFjSCxDQUFkLENBQUosRUFBc0I7QUFDcEIsVUFBSUQsQ0FBQyxDQUFDSyxNQUFGLEtBQWFKLENBQUMsQ0FBQ0ksTUFBbkIsRUFBMkI7QUFDekIsZUFBTyxLQUFQO0FBQ0Q7O0FBQ0QsV0FBSyxJQUFJQyxDQUFDLEdBQUcsQ0FBYixFQUFnQkEsQ0FBQyxHQUFHTixDQUFDLENBQUNLLE1BQXRCLEVBQThCQyxDQUFDLEVBQS9CLEVBQW1DO0FBQ2pDLFlBQUksQ0FBQ1AsWUFBWSxDQUFDQyxDQUFDLENBQUNNLENBQUQsQ0FBRixFQUFPTCxDQUFDLENBQUNLLENBQUQsQ0FBUixDQUFqQixFQUErQjtBQUM3QixpQkFBTyxLQUFQO0FBQ0Q7QUFDRjs7QUFDRCxhQUFPLElBQVA7QUFDRDs7QUFDRCxXQUFPLEtBQVA7QUFDRDs7QUFDRCxNQUFJVCxNQUFNLENBQUNVLElBQVAsQ0FBWVAsQ0FBWixFQUFlSyxNQUFmLEtBQTBCUixNQUFNLENBQUNVLElBQVAsQ0FBWU4sQ0FBWixFQUFlSSxNQUE3QyxFQUFxRDtBQUNuRCxXQUFPLEtBQVA7QUFDRDs7QUFDRCxPQUFLLElBQUlHLEdBQVQsSUFBZ0JSLENBQWhCLEVBQW1CO0FBQ2pCLFFBQUksQ0FBQ0QsWUFBWSxDQUFDQyxDQUFDLENBQUNRLEdBQUQsQ0FBRixFQUFTUCxDQUFDLENBQUNPLEdBQUQsQ0FBVixDQUFqQixFQUFtQztBQUNqQyxhQUFPLEtBQVA7QUFDRDtBQUNGOztBQUNELFNBQU8sSUFBUDtBQUNEOztBQUVEQyxNQUFNLENBQUNDLE9BQVAsR0FBaUJYLFlBQWpCIiwic291cmNlc0NvbnRlbnQiOlsidmFyIHRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztcblxuLyoqXG4gKiBEZXRlcm1pbmVzIHdoZXRoZXIgdHdvIG9iamVjdHMgcmVwcmVzZW50IHRoZSBzYW1lIHByaW1pdGl2ZSwgc3BlY2lhbCBQYXJzZVxuICogdHlwZSwgb3IgZnVsbCBQYXJzZSBPYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGVxdWFsT2JqZWN0cyhhLCBiKSB7XG4gIGlmICh0eXBlb2YgYSAhPT0gdHlwZW9mIGIpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHR5cGVvZiBhICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBhID09PSBiO1xuICB9XG4gIGlmIChhID09PSBiKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKHRvU3RyaW5nLmNhbGwoYSkgPT09ICdbb2JqZWN0IERhdGVdJykge1xuICAgIGlmICh0b1N0cmluZy5jYWxsKGIpID09PSAnW29iamVjdCBEYXRlXScpIHtcbiAgICAgIHJldHVybiArYSA9PT0gK2I7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoQXJyYXkuaXNBcnJheShhKSkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGIpKSB7XG4gICAgICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoIWVxdWFsT2JqZWN0cyhhW2ldLCBiW2ldKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoT2JqZWN0LmtleXMoYSkubGVuZ3RoICE9PSBPYmplY3Qua2V5cyhiKS5sZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgZm9yICh2YXIga2V5IGluIGEpIHtcbiAgICBpZiAoIWVxdWFsT2JqZWN0cyhhW2tleV0sIGJba2V5XSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXF1YWxPYmplY3RzO1xuIl19 \ No newline at end of file diff --git a/lib/Options/Definitions.js b/lib/Options/Definitions.js deleted file mode 100644 index b2a74cfae1..0000000000 --- a/lib/Options/Definitions.js +++ /dev/null @@ -1,715 +0,0 @@ -"use strict"; - -/* -**** GENERATED CODE **** -This code has been generated by resources/buildConfigDefinitions.js -Do not edit manually, but update Options/index.js -*/ -var parsers = require('./parsers'); - -module.exports.ParseServerOptions = { - accountLockout: { - env: 'PARSE_SERVER_ACCOUNT_LOCKOUT', - help: 'account lockout policy for failed login attempts', - action: parsers.objectParser - }, - allowClientClassCreation: { - env: 'PARSE_SERVER_ALLOW_CLIENT_CLASS_CREATION', - help: 'Enable (or disable) client class creation, defaults to true', - action: parsers.booleanParser, - default: true - }, - allowCustomObjectId: { - env: 'PARSE_SERVER_ALLOW_CUSTOM_OBJECT_ID', - help: 'Enable (or disable) custom objectId', - action: parsers.booleanParser, - default: false - }, - allowHeaders: { - env: 'PARSE_SERVER_ALLOW_HEADERS', - help: 'Add headers to Access-Control-Allow-Headers', - action: parsers.arrayParser - }, - allowOrigin: { - env: 'PARSE_SERVER_ALLOW_ORIGIN', - help: 'Sets the origin to Access-Control-Allow-Origin' - }, - analyticsAdapter: { - env: 'PARSE_SERVER_ANALYTICS_ADAPTER', - help: 'Adapter module for the analytics', - action: parsers.moduleOrObjectParser - }, - appId: { - env: 'PARSE_SERVER_APPLICATION_ID', - help: 'Your Parse Application ID', - required: true - }, - appName: { - env: 'PARSE_SERVER_APP_NAME', - help: 'Sets the app name' - }, - auth: { - env: 'PARSE_SERVER_AUTH_PROVIDERS', - help: 'Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication', - action: parsers.objectParser - }, - cacheAdapter: { - env: 'PARSE_SERVER_CACHE_ADAPTER', - help: 'Adapter module for the cache', - action: parsers.moduleOrObjectParser - }, - cacheMaxSize: { - env: 'PARSE_SERVER_CACHE_MAX_SIZE', - help: 'Sets the maximum size for the in memory cache, defaults to 10000', - action: parsers.numberParser('cacheMaxSize'), - default: 10000 - }, - cacheTTL: { - env: 'PARSE_SERVER_CACHE_TTL', - help: 'Sets the TTL for the in memory cache (in ms), defaults to 5000 (5 seconds)', - action: parsers.numberParser('cacheTTL'), - default: 5000 - }, - clientKey: { - env: 'PARSE_SERVER_CLIENT_KEY', - help: 'Key for iOS, MacOS, tvOS clients' - }, - cloud: { - env: 'PARSE_SERVER_CLOUD', - help: 'Full path to your cloud code main.js' - }, - cluster: { - env: 'PARSE_SERVER_CLUSTER', - help: 'Run with cluster, optionally set the number of processes default to os.cpus().length', - action: parsers.numberOrBooleanParser - }, - collectionPrefix: { - env: 'PARSE_SERVER_COLLECTION_PREFIX', - help: 'A collection prefix for the classes', - default: '' - }, - customPages: { - env: 'PARSE_SERVER_CUSTOM_PAGES', - help: 'custom pages for password validation and reset', - action: parsers.objectParser, - default: {} - }, - databaseAdapter: { - env: 'PARSE_SERVER_DATABASE_ADAPTER', - help: 'Adapter module for the database', - action: parsers.moduleOrObjectParser - }, - databaseOptions: { - env: 'PARSE_SERVER_DATABASE_OPTIONS', - help: 'Options to pass to the mongodb client', - action: parsers.objectParser - }, - databaseURI: { - env: 'PARSE_SERVER_DATABASE_URI', - help: 'The full URI to your database. Supported databases are mongodb or postgres.', - required: true, - default: 'mongodb://localhost:27017/parse' - }, - directAccess: { - env: 'PARSE_SERVER_ENABLE_EXPERIMENTAL_DIRECT_ACCESS', - help: 'Replace HTTP Interface when using JS SDK in current node runtime, defaults to false. Caution, this is an experimental feature that may not be appropriate for production.', - action: parsers.booleanParser, - default: false - }, - dotNetKey: { - env: 'PARSE_SERVER_DOT_NET_KEY', - help: 'Key for Unity and .Net SDK' - }, - emailAdapter: { - env: 'PARSE_SERVER_EMAIL_ADAPTER', - help: 'Adapter module for email sending', - action: parsers.moduleOrObjectParser - }, - emailVerifyTokenReuseIfValid: { - env: 'PARSE_SERVER_EMAIL_VERIFY_TOKEN_REUSE_IF_VALID', - help: 'an existing email verify token should be reused when resend verification email is requested', - action: parsers.booleanParser, - default: false - }, - emailVerifyTokenValidityDuration: { - env: 'PARSE_SERVER_EMAIL_VERIFY_TOKEN_VALIDITY_DURATION', - help: 'Email verification token validity duration, in seconds', - action: parsers.numberParser('emailVerifyTokenValidityDuration') - }, - enableAnonymousUsers: { - env: 'PARSE_SERVER_ENABLE_ANON_USERS', - help: 'Enable (or disable) anonymous users, defaults to true', - action: parsers.booleanParser, - default: true - }, - enableExpressErrorHandler: { - env: 'PARSE_SERVER_ENABLE_EXPRESS_ERROR_HANDLER', - help: 'Enables the default express error handler for all errors', - action: parsers.booleanParser, - default: false - }, - enableSingleSchemaCache: { - env: 'PARSE_SERVER_ENABLE_SINGLE_SCHEMA_CACHE', - help: 'Use a single schema cache shared across requests. Reduces number of queries made to _SCHEMA, defaults to false, i.e. unique schema cache per request.', - action: parsers.booleanParser, - default: false - }, - encryptionKey: { - env: 'PARSE_SERVER_ENCRYPTION_KEY', - help: 'Key for encrypting your files' - }, - expireInactiveSessions: { - env: 'PARSE_SERVER_EXPIRE_INACTIVE_SESSIONS', - help: 'Sets wether we should expire the inactive sessions, defaults to true', - action: parsers.booleanParser, - default: true - }, - fileKey: { - env: 'PARSE_SERVER_FILE_KEY', - help: 'Key for your files' - }, - filesAdapter: { - env: 'PARSE_SERVER_FILES_ADAPTER', - help: 'Adapter module for the files sub-system', - action: parsers.moduleOrObjectParser - }, - fileUpload: { - env: 'PARSE_SERVER_FILE_UPLOAD_OPTIONS', - help: 'Options for file uploads', - action: parsers.objectParser, - default: {} - }, - graphQLPath: { - env: 'PARSE_SERVER_GRAPHQL_PATH', - help: 'Mount path for the GraphQL endpoint, defaults to /graphql', - default: '/graphql' - }, - graphQLSchema: { - env: 'PARSE_SERVER_GRAPH_QLSCHEMA', - help: 'Full path to your GraphQL custom schema.graphql file' - }, - host: { - env: 'PARSE_SERVER_HOST', - help: 'The host to serve ParseServer on, defaults to 0.0.0.0', - default: '0.0.0.0' - }, - idempotencyOptions: { - env: 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_OPTIONS', - help: 'Options for request idempotency to deduplicate identical requests that may be caused by network issues. Caution, this is an experimental feature that may not be appropriate for production.', - action: parsers.objectParser, - default: {} - }, - javascriptKey: { - env: 'PARSE_SERVER_JAVASCRIPT_KEY', - help: 'Key for the Javascript SDK' - }, - jsonLogs: { - env: 'JSON_LOGS', - help: 'Log as structured JSON objects', - action: parsers.booleanParser - }, - liveQuery: { - env: 'PARSE_SERVER_LIVE_QUERY', - help: "parse-server's LiveQuery configuration object", - action: parsers.objectParser - }, - liveQueryServerOptions: { - env: 'PARSE_SERVER_LIVE_QUERY_SERVER_OPTIONS', - help: 'Live query server configuration options (will start the liveQuery server)', - action: parsers.objectParser - }, - loggerAdapter: { - env: 'PARSE_SERVER_LOGGER_ADAPTER', - help: 'Adapter module for the logging sub-system', - action: parsers.moduleOrObjectParser - }, - logLevel: { - env: 'PARSE_SERVER_LOG_LEVEL', - help: 'Sets the level for logs' - }, - logsFolder: { - env: 'PARSE_SERVER_LOGS_FOLDER', - help: "Folder for the logs (defaults to './logs'); set to null to disable file based logging", - default: './logs' - }, - masterKey: { - env: 'PARSE_SERVER_MASTER_KEY', - help: 'Your Parse Master Key', - required: true - }, - masterKeyIps: { - env: 'PARSE_SERVER_MASTER_KEY_IPS', - help: 'Restrict masterKey to be used by only these ips, defaults to [] (allow all ips)', - action: parsers.arrayParser, - default: [] - }, - maxLimit: { - env: 'PARSE_SERVER_MAX_LIMIT', - help: 'Max value for limit option on queries, defaults to unlimited', - action: parsers.numberParser('maxLimit') - }, - maxLogFiles: { - env: 'PARSE_SERVER_MAX_LOG_FILES', - help: "Maximum number of logs to keep. If not set, no logs will be removed. This can be a number of files or number of days. If using days, add 'd' as the suffix. (default: null)", - action: parsers.objectParser - }, - maxUploadSize: { - env: 'PARSE_SERVER_MAX_UPLOAD_SIZE', - help: 'Max file size for uploads, defaults to 20mb', - default: '20mb' - }, - middleware: { - env: 'PARSE_SERVER_MIDDLEWARE', - help: 'middleware for express server, can be string or function' - }, - mountGraphQL: { - env: 'PARSE_SERVER_MOUNT_GRAPHQL', - help: 'Mounts the GraphQL endpoint', - action: parsers.booleanParser, - default: false - }, - mountPath: { - env: 'PARSE_SERVER_MOUNT_PATH', - help: 'Mount path for the server, defaults to /parse', - default: '/parse' - }, - mountPlayground: { - env: 'PARSE_SERVER_MOUNT_PLAYGROUND', - help: 'Mounts the GraphQL Playground - never use this option in production', - action: parsers.booleanParser, - default: false - }, - objectIdSize: { - env: 'PARSE_SERVER_OBJECT_ID_SIZE', - help: "Sets the number of characters in generated object id's, default 10", - action: parsers.numberParser('objectIdSize'), - default: 10 - }, - pages: { - env: 'PARSE_SERVER_PAGES', - help: 'The options for pages such as password reset and email verification. Caution, this is an experimental feature that may not be appropriate for production.', - action: parsers.objectParser, - default: {} - }, - passwordPolicy: { - env: 'PARSE_SERVER_PASSWORD_POLICY', - help: 'Password policy for enforcing password related rules', - action: parsers.objectParser - }, - playgroundPath: { - env: 'PARSE_SERVER_PLAYGROUND_PATH', - help: 'Mount path for the GraphQL Playground, defaults to /playground', - default: '/playground' - }, - port: { - env: 'PORT', - help: 'The port to run the ParseServer, defaults to 1337.', - action: parsers.numberParser('port'), - default: 1337 - }, - preserveFileName: { - env: 'PARSE_SERVER_PRESERVE_FILE_NAME', - help: 'Enable (or disable) the addition of a unique hash to the file names', - action: parsers.booleanParser, - default: false - }, - preventLoginWithUnverifiedEmail: { - env: 'PARSE_SERVER_PREVENT_LOGIN_WITH_UNVERIFIED_EMAIL', - help: 'Prevent user from login if email is not verified and PARSE_SERVER_VERIFY_USER_EMAILS is true, defaults to false', - action: parsers.booleanParser, - default: false - }, - protectedFields: { - env: 'PARSE_SERVER_PROTECTED_FIELDS', - help: 'Protected fields that should be treated with extra security when fetching details.', - action: parsers.objectParser, - default: { - _User: { - '*': ['email'] - } - } - }, - publicServerURL: { - env: 'PARSE_PUBLIC_SERVER_URL', - help: 'Public URL to your parse server with http:// or https://.' - }, - push: { - env: 'PARSE_SERVER_PUSH', - help: 'Configuration for push, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#push-notifications', - action: parsers.objectParser - }, - readOnlyMasterKey: { - env: 'PARSE_SERVER_READ_ONLY_MASTER_KEY', - help: 'Read-only key, which has the same capabilities as MasterKey without writes' - }, - restAPIKey: { - env: 'PARSE_SERVER_REST_API_KEY', - help: 'Key for REST calls' - }, - revokeSessionOnPasswordReset: { - env: 'PARSE_SERVER_REVOKE_SESSION_ON_PASSWORD_RESET', - help: "When a user changes their password, either through the reset password email or while logged in, all sessions are revoked if this is true. Set to false if you don't want to revoke sessions.", - action: parsers.booleanParser, - default: true - }, - scheduledPush: { - env: 'PARSE_SERVER_SCHEDULED_PUSH', - help: 'Configuration for push scheduling, defaults to false.', - action: parsers.booleanParser, - default: false - }, - schemaCacheTTL: { - env: 'PARSE_SERVER_SCHEMA_CACHE_TTL', - help: 'The TTL for caching the schema for optimizing read/write operations. You should put a long TTL when your DB is in production. default to 5000; set 0 to disable.', - action: parsers.numberParser('schemaCacheTTL'), - default: 5000 - }, - serverCloseComplete: { - env: 'PARSE_SERVER_SERVER_CLOSE_COMPLETE', - help: 'Callback when server has closed' - }, - serverStartComplete: { - env: 'PARSE_SERVER_SERVER_START_COMPLETE', - help: 'Callback when server has started' - }, - serverURL: { - env: 'PARSE_SERVER_URL', - help: 'URL to your parse server with http:// or https://.', - required: true - }, - sessionLength: { - env: 'PARSE_SERVER_SESSION_LENGTH', - help: 'Session duration, in seconds, defaults to 1 year', - action: parsers.numberParser('sessionLength'), - default: 31536000 - }, - silent: { - env: 'SILENT', - help: 'Disables console output', - action: parsers.booleanParser - }, - startLiveQueryServer: { - env: 'PARSE_SERVER_START_LIVE_QUERY_SERVER', - help: 'Starts the liveQuery server', - action: parsers.booleanParser - }, - userSensitiveFields: { - env: 'PARSE_SERVER_USER_SENSITIVE_FIELDS', - help: 'Personally identifiable information fields in the user table the should be removed for non-authorized users. Deprecated @see protectedFields', - action: parsers.arrayParser - }, - verbose: { - env: 'VERBOSE', - help: 'Set the logging to verbose', - action: parsers.booleanParser - }, - verifyUserEmails: { - env: 'PARSE_SERVER_VERIFY_USER_EMAILS', - help: 'Enable (or disable) user email validation, defaults to false', - action: parsers.booleanParser, - default: false - }, - webhookKey: { - env: 'PARSE_SERVER_WEBHOOK_KEY', - help: 'Key sent with outgoing webhook calls' - } -}; -module.exports.PagesOptions = { - customUrls: { - env: 'PARSE_SERVER_PAGES_CUSTOM_URLS', - help: 'The URLs to the custom pages.', - action: parsers.objectParser, - default: {} - }, - enableLocalization: { - env: 'PARSE_SERVER_PAGES_ENABLE_LOCALIZATION', - help: 'Is true if pages should be localized; this has no effect on custom page redirects.', - action: parsers.booleanParser, - default: false - }, - enableRouter: { - env: 'PARSE_SERVER_PAGES_ENABLE_ROUTER', - help: 'Is true if the pages router should be enabled; this is required for any of the pages options to take effect. Caution, this is an experimental feature that may not be appropriate for production.', - action: parsers.booleanParser, - default: false - }, - forceRedirect: { - env: 'PARSE_SERVER_PAGES_FORCE_REDIRECT', - help: 'Is true if responses should always be redirects and never content, false if the response type should depend on the request type (GET request -> content response; POST request -> redirect response).', - action: parsers.booleanParser, - default: false - }, - localizationFallbackLocale: { - env: 'PARSE_SERVER_PAGES_LOCALIZATION_FALLBACK_LOCALE', - help: 'The fallback locale for localization if no matching translation is provided for the given locale. This is only relevant when providing translation resources via JSON file.', - default: 'en' - }, - localizationJsonPath: { - env: 'PARSE_SERVER_PAGES_LOCALIZATION_JSON_PATH', - help: 'The path to the JSON file for localization; the translations will be used to fill template placeholders according to the locale.' - }, - pagesEndpoint: { - env: 'PARSE_SERVER_PAGES_PAGES_ENDPOINT', - help: "The API endpoint for the pages. Default is 'apps'.", - default: 'apps' - }, - pagesPath: { - env: 'PARSE_SERVER_PAGES_PAGES_PATH', - help: "The path to the pages directory; this also defines where the static endpoint '/apps' points to. Default is the './public/' directory.", - default: './public' - }, - placeholders: { - env: 'PARSE_SERVER_PAGES_PLACEHOLDERS', - help: 'The placeholder keys and values which will be filled in pages; this can be a simple object or a callback function.', - action: parsers.objectParser, - default: {} - } -}; -module.exports.PagesCustomUrlsOptions = { - emailVerificationLinkExpired: { - env: 'PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_LINK_EXPIRED', - help: 'The URL to the custom page for email verification -> link expired.' - }, - emailVerificationLinkInvalid: { - env: 'PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_LINK_INVALID', - help: 'The URL to the custom page for email verification -> link invalid.' - }, - emailVerificationSendFail: { - env: 'PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_SEND_FAIL', - help: 'The URL to the custom page for email verification -> link send fail.' - }, - emailVerificationSendSuccess: { - env: 'PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_SEND_SUCCESS', - help: 'The URL to the custom page for email verification -> resend link -> success.' - }, - emailVerificationSuccess: { - env: 'PARSE_SERVER_PAGES_CUSTOM_URL_EMAIL_VERIFICATION_SUCCESS', - help: 'The URL to the custom page for email verification -> success.' - }, - passwordReset: { - env: 'PARSE_SERVER_PAGES_CUSTOM_URL_PASSWORD_RESET', - help: 'The URL to the custom page for password reset.' - }, - passwordResetLinkInvalid: { - env: 'PARSE_SERVER_PAGES_CUSTOM_URL_PASSWORD_RESET_LINK_INVALID', - help: 'The URL to the custom page for password reset -> link invalid.' - }, - passwordResetSuccess: { - env: 'PARSE_SERVER_PAGES_CUSTOM_URL_PASSWORD_RESET_SUCCESS', - help: 'The URL to the custom page for password reset -> success.' - } -}; -module.exports.CustomPagesOptions = { - choosePassword: { - env: 'PARSE_SERVER_CUSTOM_PAGES_CHOOSE_PASSWORD', - help: 'choose password page path' - }, - expiredVerificationLink: { - env: 'PARSE_SERVER_CUSTOM_PAGES_EXPIRED_VERIFICATION_LINK', - help: 'expired verification link page path' - }, - invalidLink: { - env: 'PARSE_SERVER_CUSTOM_PAGES_INVALID_LINK', - help: 'invalid link page path' - }, - invalidPasswordResetLink: { - env: 'PARSE_SERVER_CUSTOM_PAGES_INVALID_PASSWORD_RESET_LINK', - help: 'invalid password reset link page path' - }, - invalidVerificationLink: { - env: 'PARSE_SERVER_CUSTOM_PAGES_INVALID_VERIFICATION_LINK', - help: 'invalid verification link page path' - }, - linkSendFail: { - env: 'PARSE_SERVER_CUSTOM_PAGES_LINK_SEND_FAIL', - help: 'verification link send fail page path' - }, - linkSendSuccess: { - env: 'PARSE_SERVER_CUSTOM_PAGES_LINK_SEND_SUCCESS', - help: 'verification link send success page path' - }, - parseFrameURL: { - env: 'PARSE_SERVER_CUSTOM_PAGES_PARSE_FRAME_URL', - help: 'for masking user-facing pages' - }, - passwordResetSuccess: { - env: 'PARSE_SERVER_CUSTOM_PAGES_PASSWORD_RESET_SUCCESS', - help: 'password reset success page path' - }, - verifyEmailSuccess: { - env: 'PARSE_SERVER_CUSTOM_PAGES_VERIFY_EMAIL_SUCCESS', - help: 'verify email success page path' - } -}; -module.exports.LiveQueryOptions = { - classNames: { - env: 'PARSE_SERVER_LIVEQUERY_CLASSNAMES', - help: "parse-server's LiveQuery classNames", - action: parsers.arrayParser - }, - pubSubAdapter: { - env: 'PARSE_SERVER_LIVEQUERY_PUB_SUB_ADAPTER', - help: 'LiveQuery pubsub adapter', - action: parsers.moduleOrObjectParser - }, - redisOptions: { - env: 'PARSE_SERVER_LIVEQUERY_REDIS_OPTIONS', - help: "parse-server's LiveQuery redisOptions", - action: parsers.objectParser - }, - redisURL: { - env: 'PARSE_SERVER_LIVEQUERY_REDIS_URL', - help: "parse-server's LiveQuery redisURL" - }, - wssAdapter: { - env: 'PARSE_SERVER_LIVEQUERY_WSS_ADAPTER', - help: 'Adapter module for the WebSocketServer', - action: parsers.moduleOrObjectParser - } -}; -module.exports.LiveQueryServerOptions = { - appId: { - env: 'PARSE_LIVE_QUERY_SERVER_APP_ID', - help: 'This string should match the appId in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same appId.' - }, - cacheTimeout: { - env: 'PARSE_LIVE_QUERY_SERVER_CACHE_TIMEOUT', - help: "Number in milliseconds. When clients provide the sessionToken to the LiveQuery server, the LiveQuery server will try to fetch its ParseUser's objectId from parse server and store it in the cache. The value defines the duration of the cache. Check the following Security section and our protocol specification for details, defaults to 5 * 1000 ms (5 seconds).", - action: parsers.numberParser('cacheTimeout') - }, - keyPairs: { - env: 'PARSE_LIVE_QUERY_SERVER_KEY_PAIRS', - help: 'A JSON object that serves as a whitelist of keys. It is used for validating clients when they try to connect to the LiveQuery server. Check the following Security section and our protocol specification for details.', - action: parsers.objectParser - }, - logLevel: { - env: 'PARSE_LIVE_QUERY_SERVER_LOG_LEVEL', - help: 'This string defines the log level of the LiveQuery server. We support VERBOSE, INFO, ERROR, NONE, defaults to INFO.' - }, - masterKey: { - env: 'PARSE_LIVE_QUERY_SERVER_MASTER_KEY', - help: 'This string should match the masterKey in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same masterKey.' - }, - port: { - env: 'PARSE_LIVE_QUERY_SERVER_PORT', - help: 'The port to run the LiveQuery server, defaults to 1337.', - action: parsers.numberParser('port'), - default: 1337 - }, - pubSubAdapter: { - env: 'PARSE_LIVE_QUERY_SERVER_PUB_SUB_ADAPTER', - help: 'LiveQuery pubsub adapter', - action: parsers.moduleOrObjectParser - }, - redisOptions: { - env: 'PARSE_LIVE_QUERY_SERVER_REDIS_OPTIONS', - help: "parse-server's LiveQuery redisOptions", - action: parsers.objectParser - }, - redisURL: { - env: 'PARSE_LIVE_QUERY_SERVER_REDIS_URL', - help: "parse-server's LiveQuery redisURL" - }, - serverURL: { - env: 'PARSE_LIVE_QUERY_SERVER_SERVER_URL', - help: 'This string should match the serverURL in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same serverURL.' - }, - websocketTimeout: { - env: 'PARSE_LIVE_QUERY_SERVER_WEBSOCKET_TIMEOUT', - help: 'Number of milliseconds between ping/pong frames. The WebSocket server sends ping/pong frames to the clients to keep the WebSocket alive. This value defines the interval of the ping/pong frame from the server to clients, defaults to 10 * 1000 ms (10 s).', - action: parsers.numberParser('websocketTimeout') - }, - wssAdapter: { - env: 'PARSE_LIVE_QUERY_SERVER_WSS_ADAPTER', - help: 'Adapter module for the WebSocketServer', - action: parsers.moduleOrObjectParser - } -}; -module.exports.IdempotencyOptions = { - paths: { - env: 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_PATHS', - help: 'An array of paths for which the feature should be enabled. The mount path must not be included, for example instead of `/parse/functions/myFunction` specifiy `functions/myFunction`. The entries are interpreted as regular expression, for example `functions/.*` matches all functions, `jobs/.*` matches all jobs, `classes/.*` matches all classes, `.*` matches all paths.', - action: parsers.arrayParser, - default: [] - }, - ttl: { - env: 'PARSE_SERVER_EXPERIMENTAL_IDEMPOTENCY_TTL', - help: 'The duration in seconds after which a request record is discarded from the database, defaults to 300s.', - action: parsers.numberParser('ttl'), - default: 300 - } -}; -module.exports.AccountLockoutOptions = { - duration: { - env: 'PARSE_SERVER_ACCOUNT_LOCKOUT_DURATION', - help: 'number of minutes that a locked-out account remains locked out before automatically becoming unlocked.', - action: parsers.numberParser('duration') - }, - threshold: { - env: 'PARSE_SERVER_ACCOUNT_LOCKOUT_THRESHOLD', - help: 'number of failed sign-in attempts that will cause a user account to be locked', - action: parsers.numberParser('threshold') - }, - unlockOnPasswordReset: { - env: 'PARSE_SERVER_ACCOUNT_LOCKOUT_UNLOCK_ON_PASSWORD_RESET', - help: 'Is true if the account lock should be removed after a successful password reset.', - action: parsers.booleanParser, - default: false - } -}; -module.exports.PasswordPolicyOptions = { - doNotAllowUsername: { - env: 'PARSE_SERVER_PASSWORD_POLICY_DO_NOT_ALLOW_USERNAME', - help: 'disallow username in passwords', - action: parsers.booleanParser - }, - maxPasswordAge: { - env: 'PARSE_SERVER_PASSWORD_POLICY_MAX_PASSWORD_AGE', - help: 'days for password expiry', - action: parsers.numberParser('maxPasswordAge') - }, - maxPasswordHistory: { - env: 'PARSE_SERVER_PASSWORD_POLICY_MAX_PASSWORD_HISTORY', - help: 'setting to prevent reuse of previous n passwords', - action: parsers.numberParser('maxPasswordHistory') - }, - resetTokenReuseIfValid: { - env: 'PARSE_SERVER_PASSWORD_POLICY_RESET_TOKEN_REUSE_IF_VALID', - help: "resend token if it's still valid", - action: parsers.booleanParser - }, - resetTokenValidityDuration: { - env: 'PARSE_SERVER_PASSWORD_POLICY_RESET_TOKEN_VALIDITY_DURATION', - help: 'time for token to expire', - action: parsers.numberParser('resetTokenValidityDuration') - }, - validatorCallback: { - env: 'PARSE_SERVER_PASSWORD_POLICY_VALIDATOR_CALLBACK', - help: 'a callback function to be invoked to validate the password' - }, - validatorPattern: { - env: 'PARSE_SERVER_PASSWORD_POLICY_VALIDATOR_PATTERN', - help: 'a RegExp object or a regex string representing the pattern to enforce' - } -}; -module.exports.FileUploadOptions = { - enableForAnonymousUser: { - env: 'PARSE_SERVER_FILE_UPLOAD_ENABLE_FOR_ANONYMOUS_USER', - help: 'Is true if file upload should be allowed for anonymous users.', - action: parsers.booleanParser, - default: false - }, - enableForAuthenticatedUser: { - env: 'PARSE_SERVER_FILE_UPLOAD_ENABLE_FOR_AUTHENTICATED_USER', - help: 'Is true if file upload should be allowed for authenticated users.', - action: parsers.booleanParser, - default: true - }, - enableForPublic: { - env: 'PARSE_SERVER_FILE_UPLOAD_ENABLE_FOR_PUBLIC', - help: 'Is true if file upload should be allowed for anyone, regardless of user authentication.', - action: parsers.booleanParser, - default: false - } -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9PcHRpb25zL0RlZmluaXRpb25zLmpzIl0sIm5hbWVzIjpbInBhcnNlcnMiLCJyZXF1aXJlIiwibW9kdWxlIiwiZXhwb3J0cyIsIlBhcnNlU2VydmVyT3B0aW9ucyIsImFjY291bnRMb2Nrb3V0IiwiZW52IiwiaGVscCIsImFjdGlvbiIsIm9iamVjdFBhcnNlciIsImFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbiIsImJvb2xlYW5QYXJzZXIiLCJkZWZhdWx0IiwiYWxsb3dDdXN0b21PYmplY3RJZCIsImFsbG93SGVhZGVycyIsImFycmF5UGFyc2VyIiwiYWxsb3dPcmlnaW4iLCJhbmFseXRpY3NBZGFwdGVyIiwibW9kdWxlT3JPYmplY3RQYXJzZXIiLCJhcHBJZCIsInJlcXVpcmVkIiwiYXBwTmFtZSIsImF1dGgiLCJjYWNoZUFkYXB0ZXIiLCJjYWNoZU1heFNpemUiLCJudW1iZXJQYXJzZXIiLCJjYWNoZVRUTCIsImNsaWVudEtleSIsImNsb3VkIiwiY2x1c3RlciIsIm51bWJlck9yQm9vbGVhblBhcnNlciIsImNvbGxlY3Rpb25QcmVmaXgiLCJjdXN0b21QYWdlcyIsImRhdGFiYXNlQWRhcHRlciIsImRhdGFiYXNlT3B0aW9ucyIsImRhdGFiYXNlVVJJIiwiZGlyZWN0QWNjZXNzIiwiZG90TmV0S2V5IiwiZW1haWxBZGFwdGVyIiwiZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZCIsImVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uIiwiZW5hYmxlQW5vbnltb3VzVXNlcnMiLCJlbmFibGVFeHByZXNzRXJyb3JIYW5kbGVyIiwiZW5hYmxlU2luZ2xlU2NoZW1hQ2FjaGUiLCJlbmNyeXB0aW9uS2V5IiwiZXhwaXJlSW5hY3RpdmVTZXNzaW9ucyIsImZpbGVLZXkiLCJmaWxlc0FkYXB0ZXIiLCJmaWxlVXBsb2FkIiwiZ3JhcGhRTFBhdGgiLCJncmFwaFFMU2NoZW1hIiwiaG9zdCIsImlkZW1wb3RlbmN5T3B0aW9ucyIsImphdmFzY3JpcHRLZXkiLCJqc29uTG9ncyIsImxpdmVRdWVyeSIsImxpdmVRdWVyeVNlcnZlck9wdGlvbnMiLCJsb2dnZXJBZGFwdGVyIiwibG9nTGV2ZWwiLCJsb2dzRm9sZGVyIiwibWFzdGVyS2V5IiwibWFzdGVyS2V5SXBzIiwibWF4TGltaXQiLCJtYXhMb2dGaWxlcyIsIm1heFVwbG9hZFNpemUiLCJtaWRkbGV3YXJlIiwibW91bnRHcmFwaFFMIiwibW91bnRQYXRoIiwibW91bnRQbGF5Z3JvdW5kIiwib2JqZWN0SWRTaXplIiwicGFnZXMiLCJwYXNzd29yZFBvbGljeSIsInBsYXlncm91bmRQYXRoIiwicG9ydCIsInByZXNlcnZlRmlsZU5hbWUiLCJwcmV2ZW50TG9naW5XaXRoVW52ZXJpZmllZEVtYWlsIiwicHJvdGVjdGVkRmllbGRzIiwiX1VzZXIiLCJwdWJsaWNTZXJ2ZXJVUkwiLCJwdXNoIiwicmVhZE9ubHlNYXN0ZXJLZXkiLCJyZXN0QVBJS2V5IiwicmV2b2tlU2Vzc2lvbk9uUGFzc3dvcmRSZXNldCIsInNjaGVkdWxlZFB1c2giLCJzY2hlbWFDYWNoZVRUTCIsInNlcnZlckNsb3NlQ29tcGxldGUiLCJzZXJ2ZXJTdGFydENvbXBsZXRlIiwic2VydmVyVVJMIiwic2Vzc2lvbkxlbmd0aCIsInNpbGVudCIsInN0YXJ0TGl2ZVF1ZXJ5U2VydmVyIiwidXNlclNlbnNpdGl2ZUZpZWxkcyIsInZlcmJvc2UiLCJ2ZXJpZnlVc2VyRW1haWxzIiwid2ViaG9va0tleSIsIlBhZ2VzT3B0aW9ucyIsImN1c3RvbVVybHMiLCJlbmFibGVMb2NhbGl6YXRpb24iLCJlbmFibGVSb3V0ZXIiLCJmb3JjZVJlZGlyZWN0IiwibG9jYWxpemF0aW9uRmFsbGJhY2tMb2NhbGUiLCJsb2NhbGl6YXRpb25Kc29uUGF0aCIsInBhZ2VzRW5kcG9pbnQiLCJwYWdlc1BhdGgiLCJwbGFjZWhvbGRlcnMiLCJQYWdlc0N1c3RvbVVybHNPcHRpb25zIiwiZW1haWxWZXJpZmljYXRpb25MaW5rRXhwaXJlZCIsImVtYWlsVmVyaWZpY2F0aW9uTGlua0ludmFsaWQiLCJlbWFpbFZlcmlmaWNhdGlvblNlbmRGYWlsIiwiZW1haWxWZXJpZmljYXRpb25TZW5kU3VjY2VzcyIsImVtYWlsVmVyaWZpY2F0aW9uU3VjY2VzcyIsInBhc3N3b3JkUmVzZXQiLCJwYXNzd29yZFJlc2V0TGlua0ludmFsaWQiLCJwYXNzd29yZFJlc2V0U3VjY2VzcyIsIkN1c3RvbVBhZ2VzT3B0aW9ucyIsImNob29zZVBhc3N3b3JkIiwiZXhwaXJlZFZlcmlmaWNhdGlvbkxpbmsiLCJpbnZhbGlkTGluayIsImludmFsaWRQYXNzd29yZFJlc2V0TGluayIsImludmFsaWRWZXJpZmljYXRpb25MaW5rIiwibGlua1NlbmRGYWlsIiwibGlua1NlbmRTdWNjZXNzIiwicGFyc2VGcmFtZVVSTCIsInZlcmlmeUVtYWlsU3VjY2VzcyIsIkxpdmVRdWVyeU9wdGlvbnMiLCJjbGFzc05hbWVzIiwicHViU3ViQWRhcHRlciIsInJlZGlzT3B0aW9ucyIsInJlZGlzVVJMIiwid3NzQWRhcHRlciIsIkxpdmVRdWVyeVNlcnZlck9wdGlvbnMiLCJjYWNoZVRpbWVvdXQiLCJrZXlQYWlycyIsIndlYnNvY2tldFRpbWVvdXQiLCJJZGVtcG90ZW5jeU9wdGlvbnMiLCJwYXRocyIsInR0bCIsIkFjY291bnRMb2Nrb3V0T3B0aW9ucyIsImR1cmF0aW9uIiwidGhyZXNob2xkIiwidW5sb2NrT25QYXNzd29yZFJlc2V0IiwiUGFzc3dvcmRQb2xpY3lPcHRpb25zIiwiZG9Ob3RBbGxvd1VzZXJuYW1lIiwibWF4UGFzc3dvcmRBZ2UiLCJtYXhQYXNzd29yZEhpc3RvcnkiLCJyZXNldFRva2VuUmV1c2VJZlZhbGlkIiwicmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJ2YWxpZGF0b3JDYWxsYmFjayIsInZhbGlkYXRvclBhdHRlcm4iLCJGaWxlVXBsb2FkT3B0aW9ucyIsImVuYWJsZUZvckFub255bW91c1VzZXIiLCJlbmFibGVGb3JBdXRoZW50aWNhdGVkVXNlciIsImVuYWJsZUZvclB1Ymxp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SSxJQUFBQSxHQUFHLEVBQUUsaURBRFk7QUFFakJDLElBQUFBLElBQUksRUFBRTtBQUZXLEdBMUJrQjtBQThCckM2SSxFQUFBQSxnQkFBZ0IsRUFBRTtBQUNoQjlJLElBQUFBLEdBQUcsRUFBRSxnREFEVztBQUVoQkMsSUFBQUEsSUFBSSxFQUFFO0FBRlU7QUE5Qm1CLENBQXZDO0FBbUNBTCxNQUFNLENBQUNDLE9BQVAsQ0FBZWtKLGlCQUFmLEdBQW1DO0FBQ2pDQyxFQUFBQSxzQkFBc0IsRUFBRTtBQUN0QmhKLElBQUFBLEdBQUcsRUFBRSxvREFEaUI7QUFFdEJDLElBQUFBLElBQUksRUFBRSwrREFGZ0I7QUFHdEJDLElBQUFBLE1BQU0sRUFBRVIsT0FBTyxDQUFDVyxhQUhNO0FBSXRCQyxJQUFBQSxPQUFPLEVBQUU7QUFKYSxHQURTO0FBT2pDMkksRUFBQUEsMEJBQTBCLEVBQUU7QUFDMUJqSixJQUFBQSxHQUFHLEVBQUUsd0RBRHFCO0FBRTFCQyxJQUFBQSxJQUFJLEVBQUUsbUVBRm9CO0FBRzFCQyxJQUFBQSxNQUFNLEVBQUVSLE9BQU8sQ0FBQ1csYUFIVTtBQUkxQkMsSUFBQUEsT0FBTyxFQUFFO0FBSmlCLEdBUEs7QUFhakM0SSxFQUFBQSxlQUFlLEVBQUU7QUFDZmxKLElBQUFBLEdBQUcsRUFBRSw0Q0FEVTtBQUVmQyxJQUFBQSxJQUFJLEVBQUUseUZBRlM7QUFHZkMsSUFBQUEsTUFBTSxFQUFFUixPQUFPLENBQUNXLGFBSEQ7QUFJZkMsSUFBQUEsT0FBTyxFQUFFO0FBSk07QUFiZ0IsQ0FBbkMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuKioqKiBHRU5FUkFURUQgQ09ERSAqKioqXG5UaGlzIGNvZGUgaGFzIGJlZW4gZ2VuZXJhdGVkIGJ5IHJlc291cmNlcy9idWlsZENvbmZpZ0RlZmluaXRpb25zLmpzXG5EbyBub3QgZWRpdCBtYW51YWxseSwgYnV0IHVwZGF0ZSBPcHRpb25zL2luZGV4LmpzXG4qL1xudmFyIHBhcnNlcnMgPSByZXF1aXJlKCcuL3BhcnNlcnMnKTtcblxubW9kdWxlLmV4cG9ydHMuUGFyc2VTZXJ2ZXJPcHRpb25zID0ge1xuICBhY2NvdW50TG9ja291dDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9BQ0NPVU5UX0xPQ0tPVVQnLFxuICAgIGhlbHA6ICdhY2NvdW50IGxvY2tvdXQgcG9saWN5IGZvciBmYWlsZWQgbG9naW4gYXR0ZW1wdHMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5vYmplY3RQYXJzZXIsXG4gIH0sXG4gIGFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbjoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9BTExPV19DTElFTlRfQ0xBU1NfQ1JFQVRJT04nLFxuICAgIGhlbHA6ICdFbmFibGUgKG9yIGRpc2FibGUpIGNsaWVudCBjbGFzcyBjcmVhdGlvbiwgZGVmYXVsdHMgdG8gdHJ1ZScsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogdHJ1ZSxcbiAgfSxcbiAgYWxsb3dDdXN0b21PYmplY3RJZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9BTExPV19DVVNUT01fT0JKRUNUX0lEJyxcbiAgICBoZWxwOiAnRW5hYmxlIChvciBkaXNhYmxlKSBjdXN0b20gb2JqZWN0SWQnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IGZhbHNlLFxuICB9LFxuICBhbGxvd0hlYWRlcnM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQUxMT1dfSEVBREVSUycsXG4gICAgaGVscDogJ0FkZCBoZWFkZXJzIHRvIEFjY2Vzcy1Db250cm9sLUFsbG93LUhlYWRlcnMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5hcnJheVBhcnNlcixcbiAgfSxcbiAgYWxsb3dPcmlnaW46IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQUxMT1dfT1JJR0lOJyxcbiAgICBoZWxwOiAnU2V0cyB0aGUgb3JpZ2luIHRvIEFjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbicsXG4gIH0sXG4gIGFuYWx5dGljc0FkYXB0ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQU5BTFlUSUNTX0FEQVBURVInLFxuICAgIGhlbHA6ICdBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGFuYWx5dGljcycsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm1vZHVsZU9yT2JqZWN0UGFyc2VyLFxuICB9LFxuICBhcHBJZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9BUFBMSUNBVElPTl9JRCcsXG4gICAgaGVscDogJ1lvdXIgUGFyc2UgQXBwbGljYXRpb24gSUQnLFxuICAgIHJlcXVpcmVkOiB0cnVlLFxuICB9LFxuICBhcHBOYW1lOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0FQUF9OQU1FJyxcbiAgICBoZWxwOiAnU2V0cyB0aGUgYXBwIG5hbWUnLFxuICB9LFxuICBhdXRoOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0FVVEhfUFJPVklERVJTJyxcbiAgICBoZWxwOlxuICAgICAgJ0NvbmZpZ3VyYXRpb24gZm9yIHlvdXIgYXV0aGVudGljYXRpb24gcHJvdmlkZXJzLCBhcyBzdHJpbmdpZmllZCBKU09OLiBTZWUgaHR0cDovL2RvY3MucGFyc2VwbGF0Zm9ybS5vcmcvcGFyc2Utc2VydmVyL2d1aWRlLyNvYXV0aC1hbmQtM3JkLXBhcnR5LWF1dGhlbnRpY2F0aW9uJyxcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICBjYWNoZUFkYXB0ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ0FDSEVfQURBUFRFUicsXG4gICAgaGVscDogJ0FkYXB0ZXIgbW9kdWxlIGZvciB0aGUgY2FjaGUnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5tb2R1bGVPck9iamVjdFBhcnNlcixcbiAgfSxcbiAgY2FjaGVNYXhTaXplOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0NBQ0hFX01BWF9TSVpFJyxcbiAgICBoZWxwOiAnU2V0cyB0aGUgbWF4aW11bSBzaXplIGZvciB0aGUgaW4gbWVtb3J5IGNhY2hlLCBkZWZhdWx0cyB0byAxMDAwMCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm51bWJlclBhcnNlcignY2FjaGVNYXhTaXplJyksXG4gICAgZGVmYXVsdDogMTAwMDAsXG4gIH0sXG4gIGNhY2hlVFRMOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0NBQ0hFX1RUTCcsXG4gICAgaGVscDogJ1NldHMgdGhlIFRUTCBmb3IgdGhlIGluIG1lbW9yeSBjYWNoZSAoaW4gbXMpLCBkZWZhdWx0cyB0byA1MDAwICg1IHNlY29uZHMpJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCdjYWNoZVRUTCcpLFxuICAgIGRlZmF1bHQ6IDUwMDAsXG4gIH0sXG4gIGNsaWVudEtleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DTElFTlRfS0VZJyxcbiAgICBoZWxwOiAnS2V5IGZvciBpT1MsIE1hY09TLCB0dk9TIGNsaWVudHMnLFxuICB9LFxuICBjbG91ZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DTE9VRCcsXG4gICAgaGVscDogJ0Z1bGwgcGF0aCB0byB5b3VyIGNsb3VkIGNvZGUgbWFpbi5qcycsXG4gIH0sXG4gIGNsdXN0ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ0xVU1RFUicsXG4gICAgaGVscDogJ1J1biB3aXRoIGNsdXN0ZXIsIG9wdGlvbmFsbHkgc2V0IHRoZSBudW1iZXIgb2YgcHJvY2Vzc2VzIGRlZmF1bHQgdG8gb3MuY3B1cygpLmxlbmd0aCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm51bWJlck9yQm9vbGVhblBhcnNlcixcbiAgfSxcbiAgY29sbGVjdGlvblByZWZpeDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DT0xMRUNUSU9OX1BSRUZJWCcsXG4gICAgaGVscDogJ0EgY29sbGVjdGlvbiBwcmVmaXggZm9yIHRoZSBjbGFzc2VzJyxcbiAgICBkZWZhdWx0OiAnJyxcbiAgfSxcbiAgY3VzdG9tUGFnZXM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTJyxcbiAgICBoZWxwOiAnY3VzdG9tIHBhZ2VzIGZvciBwYXNzd29yZCB2YWxpZGF0aW9uIGFuZCByZXNldCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgICBkZWZhdWx0OiB7fSxcbiAgfSxcbiAgZGF0YWJhc2VBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0RBVEFCQVNFX0FEQVBURVInLFxuICAgIGhlbHA6ICdBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGRhdGFiYXNlJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubW9kdWxlT3JPYmplY3RQYXJzZXIsXG4gIH0sXG4gIGRhdGFiYXNlT3B0aW9uczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9EQVRBQkFTRV9PUFRJT05TJyxcbiAgICBoZWxwOiAnT3B0aW9ucyB0byBwYXNzIHRvIHRoZSBtb25nb2RiIGNsaWVudCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgfSxcbiAgZGF0YWJhc2VVUkk6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfREFUQUJBU0VfVVJJJyxcbiAgICBoZWxwOiAnVGhlIGZ1bGwgVVJJIHRvIHlvdXIgZGF0YWJhc2UuIFN1cHBvcnRlZCBkYXRhYmFzZXMgYXJlIG1vbmdvZGIgb3IgcG9zdGdyZXMuJyxcbiAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICBkZWZhdWx0OiAnbW9uZ29kYjovL2xvY2FsaG9zdDoyNzAxNy9wYXJzZScsXG4gIH0sXG4gIGRpcmVjdEFjY2Vzczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9FTkFCTEVfRVhQRVJJTUVOVEFMX0RJUkVDVF9BQ0NFU1MnLFxuICAgIGhlbHA6XG4gICAgICAnUmVwbGFjZSBIVFRQIEludGVyZmFjZSB3aGVuIHVzaW5nIEpTIFNESyBpbiBjdXJyZW50IG5vZGUgcnVudGltZSwgZGVmYXVsdHMgdG8gZmFsc2UuIENhdXRpb24sIHRoaXMgaXMgYW4gZXhwZXJpbWVudGFsIGZlYXR1cmUgdGhhdCBtYXkgbm90IGJlIGFwcHJvcHJpYXRlIGZvciBwcm9kdWN0aW9uLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIGRvdE5ldEtleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9ET1RfTkVUX0tFWScsXG4gICAgaGVscDogJ0tleSBmb3IgVW5pdHkgYW5kIC5OZXQgU0RLJyxcbiAgfSxcbiAgZW1haWxBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VNQUlMX0FEQVBURVInLFxuICAgIGhlbHA6ICdBZGFwdGVyIG1vZHVsZSBmb3IgZW1haWwgc2VuZGluZycsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm1vZHVsZU9yT2JqZWN0UGFyc2VyLFxuICB9LFxuICBlbWFpbFZlcmlmeVRva2VuUmV1c2VJZlZhbGlkOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VNQUlMX1ZFUklGWV9UT0tFTl9SRVVTRV9JRl9WQUxJRCcsXG4gICAgaGVscDpcbiAgICAgICdhbiBleGlzdGluZyBlbWFpbCB2ZXJpZnkgdG9rZW4gc2hvdWxkIGJlIHJldXNlZCB3aGVuIHJlc2VuZCB2ZXJpZmljYXRpb24gZW1haWwgaXMgcmVxdWVzdGVkJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbiAgZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb246IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfRU1BSUxfVkVSSUZZX1RPS0VOX1ZBTElESVRZX0RVUkFUSU9OJyxcbiAgICBoZWxwOiAnRW1haWwgdmVyaWZpY2F0aW9uIHRva2VuIHZhbGlkaXR5IGR1cmF0aW9uLCBpbiBzZWNvbmRzJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCdlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbicpLFxuICB9LFxuICBlbmFibGVBbm9ueW1vdXNVc2Vyczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9FTkFCTEVfQU5PTl9VU0VSUycsXG4gICAgaGVscDogJ0VuYWJsZSAob3IgZGlzYWJsZSkgYW5vbnltb3VzIHVzZXJzLCBkZWZhdWx0cyB0byB0cnVlJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiB0cnVlLFxuICB9LFxuICBlbmFibGVFeHByZXNzRXJyb3JIYW5kbGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VOQUJMRV9FWFBSRVNTX0VSUk9SX0hBTkRMRVInLFxuICAgIGhlbHA6ICdFbmFibGVzIHRoZSBkZWZhdWx0IGV4cHJlc3MgZXJyb3IgaGFuZGxlciBmb3IgYWxsIGVycm9ycycsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIGVuYWJsZVNpbmdsZVNjaGVtYUNhY2hlOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VOQUJMRV9TSU5HTEVfU0NIRU1BX0NBQ0hFJyxcbiAgICBoZWxwOlxuICAgICAgJ1VzZSBhIHNpbmdsZSBzY2hlbWEgY2FjaGUgc2hhcmVkIGFjcm9zcyByZXF1ZXN0cy4gUmVkdWNlcyBudW1iZXIgb2YgcXVlcmllcyBtYWRlIHRvIF9TQ0hFTUEsIGRlZmF1bHRzIHRvIGZhbHNlLCBpLmUuIHVuaXF1ZSBzY2hlbWEgY2FjaGUgcGVyIHJlcXVlc3QuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbiAgZW5jcnlwdGlvbktleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9FTkNSWVBUSU9OX0tFWScsXG4gICAgaGVscDogJ0tleSBmb3IgZW5jcnlwdGluZyB5b3VyIGZpbGVzJyxcbiAgfSxcbiAgZXhwaXJlSW5hY3RpdmVTZXNzaW9uczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9FWFBJUkVfSU5BQ1RJVkVfU0VTU0lPTlMnLFxuICAgIGhlbHA6ICdTZXRzIHdldGhlciB3ZSBzaG91bGQgZXhwaXJlIHRoZSBpbmFjdGl2ZSBzZXNzaW9ucywgZGVmYXVsdHMgdG8gdHJ1ZScsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogdHJ1ZSxcbiAgfSxcbiAgZmlsZUtleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9GSUxFX0tFWScsXG4gICAgaGVscDogJ0tleSBmb3IgeW91ciBmaWxlcycsXG4gIH0sXG4gIGZpbGVzQWRhcHRlcjoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9GSUxFU19BREFQVEVSJyxcbiAgICBoZWxwOiAnQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBmaWxlcyBzdWItc3lzdGVtJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubW9kdWxlT3JPYmplY3RQYXJzZXIsXG4gIH0sXG4gIGZpbGVVcGxvYWQ6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfRklMRV9VUExPQURfT1BUSU9OUycsXG4gICAgaGVscDogJ09wdGlvbnMgZm9yIGZpbGUgdXBsb2FkcycsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgICBkZWZhdWx0OiB7fSxcbiAgfSxcbiAgZ3JhcGhRTFBhdGg6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfR1JBUEhRTF9QQVRIJyxcbiAgICBoZWxwOiAnTW91bnQgcGF0aCBmb3IgdGhlIEdyYXBoUUwgZW5kcG9pbnQsIGRlZmF1bHRzIHRvIC9ncmFwaHFsJyxcbiAgICBkZWZhdWx0OiAnL2dyYXBocWwnLFxuICB9LFxuICBncmFwaFFMU2NoZW1hOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0dSQVBIX1FMU0NIRU1BJyxcbiAgICBoZWxwOiAnRnVsbCBwYXRoIHRvIHlvdXIgR3JhcGhRTCBjdXN0b20gc2NoZW1hLmdyYXBocWwgZmlsZScsXG4gIH0sXG4gIGhvc3Q6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfSE9TVCcsXG4gICAgaGVscDogJ1RoZSBob3N0IHRvIHNlcnZlIFBhcnNlU2VydmVyIG9uLCBkZWZhdWx0cyB0byAwLjAuMC4wJyxcbiAgICBkZWZhdWx0OiAnMC4wLjAuMCcsXG4gIH0sXG4gIGlkZW1wb3RlbmN5T3B0aW9uczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9FWFBFUklNRU5UQUxfSURFTVBPVEVOQ1lfT1BUSU9OUycsXG4gICAgaGVscDpcbiAgICAgICdPcHRpb25zIGZvciByZXF1ZXN0IGlkZW1wb3RlbmN5IHRvIGRlZHVwbGljYXRlIGlkZW50aWNhbCByZXF1ZXN0cyB0aGF0IG1heSBiZSBjYXVzZWQgYnkgbmV0d29yayBpc3N1ZXMuIENhdXRpb24sIHRoaXMgaXMgYW4gZXhwZXJpbWVudGFsIGZlYXR1cmUgdGhhdCBtYXkgbm90IGJlIGFwcHJvcHJpYXRlIGZvciBwcm9kdWN0aW9uLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgICBkZWZhdWx0OiB7fSxcbiAgfSxcbiAgamF2YXNjcmlwdEtleToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9KQVZBU0NSSVBUX0tFWScsXG4gICAgaGVscDogJ0tleSBmb3IgdGhlIEphdmFzY3JpcHQgU0RLJyxcbiAgfSxcbiAganNvbkxvZ3M6IHtcbiAgICBlbnY6ICdKU09OX0xPR1MnLFxuICAgIGhlbHA6ICdMb2cgYXMgc3RydWN0dXJlZCBKU09OIG9iamVjdHMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICB9LFxuICBsaXZlUXVlcnk6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTElWRV9RVUVSWScsXG4gICAgaGVscDogXCJwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgY29uZmlndXJhdGlvbiBvYmplY3RcIixcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICBsaXZlUXVlcnlTZXJ2ZXJPcHRpb25zOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xJVkVfUVVFUllfU0VSVkVSX09QVElPTlMnLFxuICAgIGhlbHA6ICdMaXZlIHF1ZXJ5IHNlcnZlciBjb25maWd1cmF0aW9uIG9wdGlvbnMgKHdpbGwgc3RhcnQgdGhlIGxpdmVRdWVyeSBzZXJ2ZXIpJyxcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICBsb2dnZXJBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xPR0dFUl9BREFQVEVSJyxcbiAgICBoZWxwOiAnQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBsb2dnaW5nIHN1Yi1zeXN0ZW0nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5tb2R1bGVPck9iamVjdFBhcnNlcixcbiAgfSxcbiAgbG9nTGV2ZWw6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTE9HX0xFVkVMJyxcbiAgICBoZWxwOiAnU2V0cyB0aGUgbGV2ZWwgZm9yIGxvZ3MnLFxuICB9LFxuICBsb2dzRm9sZGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xPR1NfRk9MREVSJyxcbiAgICBoZWxwOiBcIkZvbGRlciBmb3IgdGhlIGxvZ3MgKGRlZmF1bHRzIHRvICcuL2xvZ3MnKTsgc2V0IHRvIG51bGwgdG8gZGlzYWJsZSBmaWxlIGJhc2VkIGxvZ2dpbmdcIixcbiAgICBkZWZhdWx0OiAnLi9sb2dzJyxcbiAgfSxcbiAgbWFzdGVyS2V5OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX01BU1RFUl9LRVknLFxuICAgIGhlbHA6ICdZb3VyIFBhcnNlIE1hc3RlciBLZXknLFxuICAgIHJlcXVpcmVkOiB0cnVlLFxuICB9LFxuICBtYXN0ZXJLZXlJcHM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTUFTVEVSX0tFWV9JUFMnLFxuICAgIGhlbHA6ICdSZXN0cmljdCBtYXN0ZXJLZXkgdG8gYmUgdXNlZCBieSBvbmx5IHRoZXNlIGlwcywgZGVmYXVsdHMgdG8gW10gKGFsbG93IGFsbCBpcHMpJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYXJyYXlQYXJzZXIsXG4gICAgZGVmYXVsdDogW10sXG4gIH0sXG4gIG1heExpbWl0OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX01BWF9MSU1JVCcsXG4gICAgaGVscDogJ01heCB2YWx1ZSBmb3IgbGltaXQgb3B0aW9uIG9uIHF1ZXJpZXMsIGRlZmF1bHRzIHRvIHVubGltaXRlZCcsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm51bWJlclBhcnNlcignbWF4TGltaXQnKSxcbiAgfSxcbiAgbWF4TG9nRmlsZXM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTUFYX0xPR19GSUxFUycsXG4gICAgaGVscDpcbiAgICAgIFwiTWF4aW11bSBudW1iZXIgb2YgbG9ncyB0byBrZWVwLiBJZiBub3Qgc2V0LCBubyBsb2dzIHdpbGwgYmUgcmVtb3ZlZC4gVGhpcyBjYW4gYmUgYSBudW1iZXIgb2YgZmlsZXMgb3IgbnVtYmVyIG9mIGRheXMuIElmIHVzaW5nIGRheXMsIGFkZCAnZCcgYXMgdGhlIHN1ZmZpeC4gKGRlZmF1bHQ6IG51bGwpXCIsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgfSxcbiAgbWF4VXBsb2FkU2l6ZToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9NQVhfVVBMT0FEX1NJWkUnLFxuICAgIGhlbHA6ICdNYXggZmlsZSBzaXplIGZvciB1cGxvYWRzLCBkZWZhdWx0cyB0byAyMG1iJyxcbiAgICBkZWZhdWx0OiAnMjBtYicsXG4gIH0sXG4gIG1pZGRsZXdhcmU6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTUlERExFV0FSRScsXG4gICAgaGVscDogJ21pZGRsZXdhcmUgZm9yIGV4cHJlc3Mgc2VydmVyLCBjYW4gYmUgc3RyaW5nIG9yIGZ1bmN0aW9uJyxcbiAgfSxcbiAgbW91bnRHcmFwaFFMOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX01PVU5UX0dSQVBIUUwnLFxuICAgIGhlbHA6ICdNb3VudHMgdGhlIEdyYXBoUUwgZW5kcG9pbnQnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IGZhbHNlLFxuICB9LFxuICBtb3VudFBhdGg6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTU9VTlRfUEFUSCcsXG4gICAgaGVscDogJ01vdW50IHBhdGggZm9yIHRoZSBzZXJ2ZXIsIGRlZmF1bHRzIHRvIC9wYXJzZScsXG4gICAgZGVmYXVsdDogJy9wYXJzZScsXG4gIH0sXG4gIG1vdW50UGxheWdyb3VuZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9NT1VOVF9QTEFZR1JPVU5EJyxcbiAgICBoZWxwOiAnTW91bnRzIHRoZSBHcmFwaFFMIFBsYXlncm91bmQgLSBuZXZlciB1c2UgdGhpcyBvcHRpb24gaW4gcHJvZHVjdGlvbicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIG9iamVjdElkU2l6ZToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9PQkpFQ1RfSURfU0laRScsXG4gICAgaGVscDogXCJTZXRzIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiBnZW5lcmF0ZWQgb2JqZWN0IGlkJ3MsIGRlZmF1bHQgMTBcIixcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCdvYmplY3RJZFNpemUnKSxcbiAgICBkZWZhdWx0OiAxMCxcbiAgfSxcbiAgcGFnZXM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUEFHRVMnLFxuICAgIGhlbHA6XG4gICAgICAnVGhlIG9wdGlvbnMgZm9yIHBhZ2VzIHN1Y2ggYXMgcGFzc3dvcmQgcmVzZXQgYW5kIGVtYWlsIHZlcmlmaWNhdGlvbi4gQ2F1dGlvbiwgdGhpcyBpcyBhbiBleHBlcmltZW50YWwgZmVhdHVyZSB0aGF0IG1heSBub3QgYmUgYXBwcm9wcmlhdGUgZm9yIHByb2R1Y3Rpb24uJyxcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICAgIGRlZmF1bHQ6IHt9LFxuICB9LFxuICBwYXNzd29yZFBvbGljeToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QQVNTV09SRF9QT0xJQ1knLFxuICAgIGhlbHA6ICdQYXNzd29yZCBwb2xpY3kgZm9yIGVuZm9yY2luZyBwYXNzd29yZCByZWxhdGVkIHJ1bGVzJyxcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICBwbGF5Z3JvdW5kUGF0aDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QTEFZR1JPVU5EX1BBVEgnLFxuICAgIGhlbHA6ICdNb3VudCBwYXRoIGZvciB0aGUgR3JhcGhRTCBQbGF5Z3JvdW5kLCBkZWZhdWx0cyB0byAvcGxheWdyb3VuZCcsXG4gICAgZGVmYXVsdDogJy9wbGF5Z3JvdW5kJyxcbiAgfSxcbiAgcG9ydDoge1xuICAgIGVudjogJ1BPUlQnLFxuICAgIGhlbHA6ICdUaGUgcG9ydCB0byBydW4gdGhlIFBhcnNlU2VydmVyLCBkZWZhdWx0cyB0byAxMzM3LicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm51bWJlclBhcnNlcigncG9ydCcpLFxuICAgIGRlZmF1bHQ6IDEzMzcsXG4gIH0sXG4gIHByZXNlcnZlRmlsZU5hbWU6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUFJFU0VSVkVfRklMRV9OQU1FJyxcbiAgICBoZWxwOiAnRW5hYmxlIChvciBkaXNhYmxlKSB0aGUgYWRkaXRpb24gb2YgYSB1bmlxdWUgaGFzaCB0byB0aGUgZmlsZSBuYW1lcycsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIHByZXZlbnRMb2dpbldpdGhVbnZlcmlmaWVkRW1haWw6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUFJFVkVOVF9MT0dJTl9XSVRIX1VOVkVSSUZJRURfRU1BSUwnLFxuICAgIGhlbHA6XG4gICAgICAnUHJldmVudCB1c2VyIGZyb20gbG9naW4gaWYgZW1haWwgaXMgbm90IHZlcmlmaWVkIGFuZCBQQVJTRV9TRVJWRVJfVkVSSUZZX1VTRVJfRU1BSUxTIGlzIHRydWUsIGRlZmF1bHRzIHRvIGZhbHNlJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbiAgcHJvdGVjdGVkRmllbGRzOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BST1RFQ1RFRF9GSUVMRFMnLFxuICAgIGhlbHA6ICdQcm90ZWN0ZWQgZmllbGRzIHRoYXQgc2hvdWxkIGJlIHRyZWF0ZWQgd2l0aCBleHRyYSBzZWN1cml0eSB3aGVuIGZldGNoaW5nIGRldGFpbHMuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICAgIGRlZmF1bHQ6IHtcbiAgICAgIF9Vc2VyOiB7XG4gICAgICAgICcqJzogWydlbWFpbCddLFxuICAgICAgfSxcbiAgICB9LFxuICB9LFxuICBwdWJsaWNTZXJ2ZXJVUkw6IHtcbiAgICBlbnY6ICdQQVJTRV9QVUJMSUNfU0VSVkVSX1VSTCcsXG4gICAgaGVscDogJ1B1YmxpYyBVUkwgdG8geW91ciBwYXJzZSBzZXJ2ZXIgd2l0aCBodHRwOi8vIG9yIGh0dHBzOi8vLicsXG4gIH0sXG4gIHB1c2g6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUFVTSCcsXG4gICAgaGVscDpcbiAgICAgICdDb25maWd1cmF0aW9uIGZvciBwdXNoLCBhcyBzdHJpbmdpZmllZCBKU09OLiBTZWUgaHR0cDovL2RvY3MucGFyc2VwbGF0Zm9ybS5vcmcvcGFyc2Utc2VydmVyL2d1aWRlLyNwdXNoLW5vdGlmaWNhdGlvbnMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5vYmplY3RQYXJzZXIsXG4gIH0sXG4gIHJlYWRPbmx5TWFzdGVyS2V5OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1JFQURfT05MWV9NQVNURVJfS0VZJyxcbiAgICBoZWxwOiAnUmVhZC1vbmx5IGtleSwgd2hpY2ggaGFzIHRoZSBzYW1lIGNhcGFiaWxpdGllcyBhcyBNYXN0ZXJLZXkgd2l0aG91dCB3cml0ZXMnLFxuICB9LFxuICByZXN0QVBJS2V5OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1JFU1RfQVBJX0tFWScsXG4gICAgaGVscDogJ0tleSBmb3IgUkVTVCBjYWxscycsXG4gIH0sXG4gIHJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQ6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUkVWT0tFX1NFU1NJT05fT05fUEFTU1dPUkRfUkVTRVQnLFxuICAgIGhlbHA6XG4gICAgICBcIldoZW4gYSB1c2VyIGNoYW5nZXMgdGhlaXIgcGFzc3dvcmQsIGVpdGhlciB0aHJvdWdoIHRoZSByZXNldCBwYXNzd29yZCBlbWFpbCBvciB3aGlsZSBsb2dnZWQgaW4sIGFsbCBzZXNzaW9ucyBhcmUgcmV2b2tlZCBpZiB0aGlzIGlzIHRydWUuIFNldCB0byBmYWxzZSBpZiB5b3UgZG9uJ3Qgd2FudCB0byByZXZva2Ugc2Vzc2lvbnMuXCIsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogdHJ1ZSxcbiAgfSxcbiAgc2NoZWR1bGVkUHVzaDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9TQ0hFRFVMRURfUFVTSCcsXG4gICAgaGVscDogJ0NvbmZpZ3VyYXRpb24gZm9yIHB1c2ggc2NoZWR1bGluZywgZGVmYXVsdHMgdG8gZmFsc2UuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbiAgc2NoZW1hQ2FjaGVUVEw6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfU0NIRU1BX0NBQ0hFX1RUTCcsXG4gICAgaGVscDpcbiAgICAgICdUaGUgVFRMIGZvciBjYWNoaW5nIHRoZSBzY2hlbWEgZm9yIG9wdGltaXppbmcgcmVhZC93cml0ZSBvcGVyYXRpb25zLiBZb3Ugc2hvdWxkIHB1dCBhIGxvbmcgVFRMIHdoZW4geW91ciBEQiBpcyBpbiBwcm9kdWN0aW9uLiBkZWZhdWx0IHRvIDUwMDA7IHNldCAwIHRvIGRpc2FibGUuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCdzY2hlbWFDYWNoZVRUTCcpLFxuICAgIGRlZmF1bHQ6IDUwMDAsXG4gIH0sXG4gIHNlcnZlckNsb3NlQ29tcGxldGU6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfU0VSVkVSX0NMT1NFX0NPTVBMRVRFJyxcbiAgICBoZWxwOiAnQ2FsbGJhY2sgd2hlbiBzZXJ2ZXIgaGFzIGNsb3NlZCcsXG4gIH0sXG4gIHNlcnZlclN0YXJ0Q29tcGxldGU6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfU0VSVkVSX1NUQVJUX0NPTVBMRVRFJyxcbiAgICBoZWxwOiAnQ2FsbGJhY2sgd2hlbiBzZXJ2ZXIgaGFzIHN0YXJ0ZWQnLFxuICB9LFxuICBzZXJ2ZXJVUkw6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfVVJMJyxcbiAgICBoZWxwOiAnVVJMIHRvIHlvdXIgcGFyc2Ugc2VydmVyIHdpdGggaHR0cDovLyBvciBodHRwczovLy4nLFxuICAgIHJlcXVpcmVkOiB0cnVlLFxuICB9LFxuICBzZXNzaW9uTGVuZ3RoOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1NFU1NJT05fTEVOR1RIJyxcbiAgICBoZWxwOiAnU2Vzc2lvbiBkdXJhdGlvbiwgaW4gc2Vjb25kcywgZGVmYXVsdHMgdG8gMSB5ZWFyJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubnVtYmVyUGFyc2VyKCdzZXNzaW9uTGVuZ3RoJyksXG4gICAgZGVmYXVsdDogMzE1MzYwMDAsXG4gIH0sXG4gIHNpbGVudDoge1xuICAgIGVudjogJ1NJTEVOVCcsXG4gICAgaGVscDogJ0Rpc2FibGVzIGNvbnNvbGUgb3V0cHV0JyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgfSxcbiAgc3RhcnRMaXZlUXVlcnlTZXJ2ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfU1RBUlRfTElWRV9RVUVSWV9TRVJWRVInLFxuICAgIGhlbHA6ICdTdGFydHMgdGhlIGxpdmVRdWVyeSBzZXJ2ZXInLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICB9LFxuICB1c2VyU2Vuc2l0aXZlRmllbGRzOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1VTRVJfU0VOU0lUSVZFX0ZJRUxEUycsXG4gICAgaGVscDpcbiAgICAgICdQZXJzb25hbGx5IGlkZW50aWZpYWJsZSBpbmZvcm1hdGlvbiBmaWVsZHMgaW4gdGhlIHVzZXIgdGFibGUgdGhlIHNob3VsZCBiZSByZW1vdmVkIGZvciBub24tYXV0aG9yaXplZCB1c2Vycy4gRGVwcmVjYXRlZCBAc2VlIHByb3RlY3RlZEZpZWxkcycsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmFycmF5UGFyc2VyLFxuICB9LFxuICB2ZXJib3NlOiB7XG4gICAgZW52OiAnVkVSQk9TRScsXG4gICAgaGVscDogJ1NldCB0aGUgbG9nZ2luZyB0byB2ZXJib3NlJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgfSxcbiAgdmVyaWZ5VXNlckVtYWlsczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9WRVJJRllfVVNFUl9FTUFJTFMnLFxuICAgIGhlbHA6ICdFbmFibGUgKG9yIGRpc2FibGUpIHVzZXIgZW1haWwgdmFsaWRhdGlvbiwgZGVmYXVsdHMgdG8gZmFsc2UnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IGZhbHNlLFxuICB9LFxuICB3ZWJob29rS2V5OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1dFQkhPT0tfS0VZJyxcbiAgICBoZWxwOiAnS2V5IHNlbnQgd2l0aCBvdXRnb2luZyB3ZWJob29rIGNhbGxzJyxcbiAgfSxcbn07XG5tb2R1bGUuZXhwb3J0cy5QYWdlc09wdGlvbnMgPSB7XG4gIGN1c3RvbVVybHM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUEFHRVNfQ1VTVE9NX1VSTFMnLFxuICAgIGhlbHA6ICdUaGUgVVJMcyB0byB0aGUgY3VzdG9tIHBhZ2VzLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm9iamVjdFBhcnNlcixcbiAgICBkZWZhdWx0OiB7fSxcbiAgfSxcbiAgZW5hYmxlTG9jYWxpemF0aW9uOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BBR0VTX0VOQUJMRV9MT0NBTElaQVRJT04nLFxuICAgIGhlbHA6ICdJcyB0cnVlIGlmIHBhZ2VzIHNob3VsZCBiZSBsb2NhbGl6ZWQ7IHRoaXMgaGFzIG5vIGVmZmVjdCBvbiBjdXN0b20gcGFnZSByZWRpcmVjdHMuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbiAgZW5hYmxlUm91dGVyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BBR0VTX0VOQUJMRV9ST1VURVInLFxuICAgIGhlbHA6XG4gICAgICAnSXMgdHJ1ZSBpZiB0aGUgcGFnZXMgcm91dGVyIHNob3VsZCBiZSBlbmFibGVkOyB0aGlzIGlzIHJlcXVpcmVkIGZvciBhbnkgb2YgdGhlIHBhZ2VzIG9wdGlvbnMgdG8gdGFrZSBlZmZlY3QuIENhdXRpb24sIHRoaXMgaXMgYW4gZXhwZXJpbWVudGFsIGZlYXR1cmUgdGhhdCBtYXkgbm90IGJlIGFwcHJvcHJpYXRlIGZvciBwcm9kdWN0aW9uLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogZmFsc2UsXG4gIH0sXG4gIGZvcmNlUmVkaXJlY3Q6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUEFHRVNfRk9SQ0VfUkVESVJFQ1QnLFxuICAgIGhlbHA6XG4gICAgICAnSXMgdHJ1ZSBpZiByZXNwb25zZXMgc2hvdWxkIGFsd2F5cyBiZSByZWRpcmVjdHMgYW5kIG5ldmVyIGNvbnRlbnQsIGZhbHNlIGlmIHRoZSByZXNwb25zZSB0eXBlIHNob3VsZCBkZXBlbmQgb24gdGhlIHJlcXVlc3QgdHlwZSAoR0VUIHJlcXVlc3QgLT4gY29udGVudCByZXNwb25zZTsgUE9TVCByZXF1ZXN0IC0+IHJlZGlyZWN0IHJlc3BvbnNlKS4nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICAgIGRlZmF1bHQ6IGZhbHNlLFxuICB9LFxuICBsb2NhbGl6YXRpb25GYWxsYmFja0xvY2FsZToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QQUdFU19MT0NBTElaQVRJT05fRkFMTEJBQ0tfTE9DQUxFJyxcbiAgICBoZWxwOlxuICAgICAgJ1RoZSBmYWxsYmFjayBsb2NhbGUgZm9yIGxvY2FsaXphdGlvbiBpZiBubyBtYXRjaGluZyB0cmFuc2xhdGlvbiBpcyBwcm92aWRlZCBmb3IgdGhlIGdpdmVuIGxvY2FsZS4gVGhpcyBpcyBvbmx5IHJlbGV2YW50IHdoZW4gcHJvdmlkaW5nIHRyYW5zbGF0aW9uIHJlc291cmNlcyB2aWEgSlNPTiBmaWxlLicsXG4gICAgZGVmYXVsdDogJ2VuJyxcbiAgfSxcbiAgbG9jYWxpemF0aW9uSnNvblBhdGg6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUEFHRVNfTE9DQUxJWkFUSU9OX0pTT05fUEFUSCcsXG4gICAgaGVscDpcbiAgICAgICdUaGUgcGF0aCB0byB0aGUgSlNPTiBmaWxlIGZvciBsb2NhbGl6YXRpb247IHRoZSB0cmFuc2xhdGlvbnMgd2lsbCBiZSB1c2VkIHRvIGZpbGwgdGVtcGxhdGUgcGxhY2Vob2xkZXJzIGFjY29yZGluZyB0byB0aGUgbG9jYWxlLicsXG4gIH0sXG4gIHBhZ2VzRW5kcG9pbnQ6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUEFHRVNfUEFHRVNfRU5EUE9JTlQnLFxuICAgIGhlbHA6IFwiVGhlIEFQSSBlbmRwb2ludCBmb3IgdGhlIHBhZ2VzLiBEZWZhdWx0IGlzICdhcHBzJy5cIixcbiAgICBkZWZhdWx0OiAnYXBwcycsXG4gIH0sXG4gIHBhZ2VzUGF0aDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QQUdFU19QQUdFU19QQVRIJyxcbiAgICBoZWxwOlxuICAgICAgXCJUaGUgcGF0aCB0byB0aGUgcGFnZXMgZGlyZWN0b3J5OyB0aGlzIGFsc28gZGVmaW5lcyB3aGVyZSB0aGUgc3RhdGljIGVuZHBvaW50ICcvYXBwcycgcG9pbnRzIHRvLiBEZWZhdWx0IGlzIHRoZSAnLi9wdWJsaWMvJyBkaXJlY3RvcnkuXCIsXG4gICAgZGVmYXVsdDogJy4vcHVibGljJyxcbiAgfSxcbiAgcGxhY2Vob2xkZXJzOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BBR0VTX1BMQUNFSE9MREVSUycsXG4gICAgaGVscDpcbiAgICAgICdUaGUgcGxhY2Vob2xkZXIga2V5cyBhbmQgdmFsdWVzIHdoaWNoIHdpbGwgYmUgZmlsbGVkIGluIHBhZ2VzOyB0aGlzIGNhbiBiZSBhIHNpbXBsZSBvYmplY3Qgb3IgYSBjYWxsYmFjayBmdW5jdGlvbi4nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5vYmplY3RQYXJzZXIsXG4gICAgZGVmYXVsdDoge30sXG4gIH0sXG59O1xubW9kdWxlLmV4cG9ydHMuUGFnZXNDdXN0b21VcmxzT3B0aW9ucyA9IHtcbiAgZW1haWxWZXJpZmljYXRpb25MaW5rRXhwaXJlZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QQUdFU19DVVNUT01fVVJMX0VNQUlMX1ZFUklGSUNBVElPTl9MSU5LX0VYUElSRUQnLFxuICAgIGhlbHA6ICdUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgZW1haWwgdmVyaWZpY2F0aW9uIC0+IGxpbmsgZXhwaXJlZC4nLFxuICB9LFxuICBlbWFpbFZlcmlmaWNhdGlvbkxpbmtJbnZhbGlkOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BBR0VTX0NVU1RPTV9VUkxfRU1BSUxfVkVSSUZJQ0FUSU9OX0xJTktfSU5WQUxJRCcsXG4gICAgaGVscDogJ1RoZSBVUkwgdG8gdGhlIGN1c3RvbSBwYWdlIGZvciBlbWFpbCB2ZXJpZmljYXRpb24gLT4gbGluayBpbnZhbGlkLicsXG4gIH0sXG4gIGVtYWlsVmVyaWZpY2F0aW9uU2VuZEZhaWw6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUEFHRVNfQ1VTVE9NX1VSTF9FTUFJTF9WRVJJRklDQVRJT05fU0VORF9GQUlMJyxcbiAgICBoZWxwOiAnVGhlIFVSTCB0byB0aGUgY3VzdG9tIHBhZ2UgZm9yIGVtYWlsIHZlcmlmaWNhdGlvbiAtPiBsaW5rIHNlbmQgZmFpbC4nLFxuICB9LFxuICBlbWFpbFZlcmlmaWNhdGlvblNlbmRTdWNjZXNzOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BBR0VTX0NVU1RPTV9VUkxfRU1BSUxfVkVSSUZJQ0FUSU9OX1NFTkRfU1VDQ0VTUycsXG4gICAgaGVscDogJ1RoZSBVUkwgdG8gdGhlIGN1c3RvbSBwYWdlIGZvciBlbWFpbCB2ZXJpZmljYXRpb24gLT4gcmVzZW5kIGxpbmsgLT4gc3VjY2Vzcy4nLFxuICB9LFxuICBlbWFpbFZlcmlmaWNhdGlvblN1Y2Nlc3M6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUEFHRVNfQ1VTVE9NX1VSTF9FTUFJTF9WRVJJRklDQVRJT05fU1VDQ0VTUycsXG4gICAgaGVscDogJ1RoZSBVUkwgdG8gdGhlIGN1c3RvbSBwYWdlIGZvciBlbWFpbCB2ZXJpZmljYXRpb24gLT4gc3VjY2Vzcy4nLFxuICB9LFxuICBwYXNzd29yZFJlc2V0OiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BBR0VTX0NVU1RPTV9VUkxfUEFTU1dPUkRfUkVTRVQnLFxuICAgIGhlbHA6ICdUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgcGFzc3dvcmQgcmVzZXQuJyxcbiAgfSxcbiAgcGFzc3dvcmRSZXNldExpbmtJbnZhbGlkOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BBR0VTX0NVU1RPTV9VUkxfUEFTU1dPUkRfUkVTRVRfTElOS19JTlZBTElEJyxcbiAgICBoZWxwOiAnVGhlIFVSTCB0byB0aGUgY3VzdG9tIHBhZ2UgZm9yIHBhc3N3b3JkIHJlc2V0IC0+IGxpbmsgaW52YWxpZC4nLFxuICB9LFxuICBwYXNzd29yZFJlc2V0U3VjY2Vzczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QQUdFU19DVVNUT01fVVJMX1BBU1NXT1JEX1JFU0VUX1NVQ0NFU1MnLFxuICAgIGhlbHA6ICdUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgcGFzc3dvcmQgcmVzZXQgLT4gc3VjY2Vzcy4nLFxuICB9LFxufTtcbm1vZHVsZS5leHBvcnRzLkN1c3RvbVBhZ2VzT3B0aW9ucyA9IHtcbiAgY2hvb3NlUGFzc3dvcmQ6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTX0NIT09TRV9QQVNTV09SRCcsXG4gICAgaGVscDogJ2Nob29zZSBwYXNzd29yZCBwYWdlIHBhdGgnLFxuICB9LFxuICBleHBpcmVkVmVyaWZpY2F0aW9uTGluazoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DVVNUT01fUEFHRVNfRVhQSVJFRF9WRVJJRklDQVRJT05fTElOSycsXG4gICAgaGVscDogJ2V4cGlyZWQgdmVyaWZpY2F0aW9uIGxpbmsgcGFnZSBwYXRoJyxcbiAgfSxcbiAgaW52YWxpZExpbms6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTX0lOVkFMSURfTElOSycsXG4gICAgaGVscDogJ2ludmFsaWQgbGluayBwYWdlIHBhdGgnLFxuICB9LFxuICBpbnZhbGlkUGFzc3dvcmRSZXNldExpbms6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTX0lOVkFMSURfUEFTU1dPUkRfUkVTRVRfTElOSycsXG4gICAgaGVscDogJ2ludmFsaWQgcGFzc3dvcmQgcmVzZXQgbGluayBwYWdlIHBhdGgnLFxuICB9LFxuICBpbnZhbGlkVmVyaWZpY2F0aW9uTGluazoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DVVNUT01fUEFHRVNfSU5WQUxJRF9WRVJJRklDQVRJT05fTElOSycsXG4gICAgaGVscDogJ2ludmFsaWQgdmVyaWZpY2F0aW9uIGxpbmsgcGFnZSBwYXRoJyxcbiAgfSxcbiAgbGlua1NlbmRGYWlsOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0NVU1RPTV9QQUdFU19MSU5LX1NFTkRfRkFJTCcsXG4gICAgaGVscDogJ3ZlcmlmaWNhdGlvbiBsaW5rIHNlbmQgZmFpbCBwYWdlIHBhdGgnLFxuICB9LFxuICBsaW5rU2VuZFN1Y2Nlc3M6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTX0xJTktfU0VORF9TVUNDRVNTJyxcbiAgICBoZWxwOiAndmVyaWZpY2F0aW9uIGxpbmsgc2VuZCBzdWNjZXNzIHBhZ2UgcGF0aCcsXG4gIH0sXG4gIHBhcnNlRnJhbWVVUkw6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTX1BBUlNFX0ZSQU1FX1VSTCcsXG4gICAgaGVscDogJ2ZvciBtYXNraW5nIHVzZXItZmFjaW5nIHBhZ2VzJyxcbiAgfSxcbiAgcGFzc3dvcmRSZXNldFN1Y2Nlc3M6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQ1VTVE9NX1BBR0VTX1BBU1NXT1JEX1JFU0VUX1NVQ0NFU1MnLFxuICAgIGhlbHA6ICdwYXNzd29yZCByZXNldCBzdWNjZXNzIHBhZ2UgcGF0aCcsXG4gIH0sXG4gIHZlcmlmeUVtYWlsU3VjY2Vzczoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9DVVNUT01fUEFHRVNfVkVSSUZZX0VNQUlMX1NVQ0NFU1MnLFxuICAgIGhlbHA6ICd2ZXJpZnkgZW1haWwgc3VjY2VzcyBwYWdlIHBhdGgnLFxuICB9LFxufTtcbm1vZHVsZS5leHBvcnRzLkxpdmVRdWVyeU9wdGlvbnMgPSB7XG4gIGNsYXNzTmFtZXM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTElWRVFVRVJZX0NMQVNTTkFNRVMnLFxuICAgIGhlbHA6IFwicGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IGNsYXNzTmFtZXNcIixcbiAgICBhY3Rpb246IHBhcnNlcnMuYXJyYXlQYXJzZXIsXG4gIH0sXG4gIHB1YlN1YkFkYXB0ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTElWRVFVRVJZX1BVQl9TVUJfQURBUFRFUicsXG4gICAgaGVscDogJ0xpdmVRdWVyeSBwdWJzdWIgYWRhcHRlcicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLm1vZHVsZU9yT2JqZWN0UGFyc2VyLFxuICB9LFxuICByZWRpc09wdGlvbnM6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTElWRVFVRVJZX1JFRElTX09QVElPTlMnLFxuICAgIGhlbHA6IFwicGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IHJlZGlzT3B0aW9uc1wiLFxuICAgIGFjdGlvbjogcGFyc2Vycy5vYmplY3RQYXJzZXIsXG4gIH0sXG4gIHJlZGlzVVJMOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0xJVkVRVUVSWV9SRURJU19VUkwnLFxuICAgIGhlbHA6IFwicGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IHJlZGlzVVJMXCIsXG4gIH0sXG4gIHdzc0FkYXB0ZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfTElWRVFVRVJZX1dTU19BREFQVEVSJyxcbiAgICBoZWxwOiAnQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBXZWJTb2NrZXRTZXJ2ZXInLFxuICAgIGFjdGlvbjogcGFyc2Vycy5tb2R1bGVPck9iamVjdFBhcnNlcixcbiAgfSxcbn07XG5tb2R1bGUuZXhwb3J0cy5MaXZlUXVlcnlTZXJ2ZXJPcHRpb25zID0ge1xuICBhcHBJZDoge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX0FQUF9JRCcsXG4gICAgaGVscDpcbiAgICAgICdUaGlzIHN0cmluZyBzaG91bGQgbWF0Y2ggdGhlIGFwcElkIGluIHVzZSBieSB5b3VyIFBhcnNlIFNlcnZlci4gSWYgeW91IGRlcGxveSB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciBhbG9uZ3NpZGUgUGFyc2UgU2VydmVyLCB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciB3aWxsIHRyeSB0byB1c2UgdGhlIHNhbWUgYXBwSWQuJyxcbiAgfSxcbiAgY2FjaGVUaW1lb3V0OiB7XG4gICAgZW52OiAnUEFSU0VfTElWRV9RVUVSWV9TRVJWRVJfQ0FDSEVfVElNRU9VVCcsXG4gICAgaGVscDpcbiAgICAgIFwiTnVtYmVyIGluIG1pbGxpc2Vjb25kcy4gV2hlbiBjbGllbnRzIHByb3ZpZGUgdGhlIHNlc3Npb25Ub2tlbiB0byB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciwgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgd2lsbCB0cnkgdG8gZmV0Y2ggaXRzIFBhcnNlVXNlcidzIG9iamVjdElkIGZyb20gcGFyc2Ugc2VydmVyIGFuZCBzdG9yZSBpdCBpbiB0aGUgY2FjaGUuIFRoZSB2YWx1ZSBkZWZpbmVzIHRoZSBkdXJhdGlvbiBvZiB0aGUgY2FjaGUuIENoZWNrIHRoZSBmb2xsb3dpbmcgU2VjdXJpdHkgc2VjdGlvbiBhbmQgb3VyIHByb3RvY29sIHNwZWNpZmljYXRpb24gZm9yIGRldGFpbHMsIGRlZmF1bHRzIHRvIDUgKiAxMDAwIG1zICg1IHNlY29uZHMpLlwiLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ2NhY2hlVGltZW91dCcpLFxuICB9LFxuICBrZXlQYWlyczoge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX0tFWV9QQUlSUycsXG4gICAgaGVscDpcbiAgICAgICdBIEpTT04gb2JqZWN0IHRoYXQgc2VydmVzIGFzIGEgd2hpdGVsaXN0IG9mIGtleXMuIEl0IGlzIHVzZWQgZm9yIHZhbGlkYXRpbmcgY2xpZW50cyB3aGVuIHRoZXkgdHJ5IHRvIGNvbm5lY3QgdG8gdGhlIExpdmVRdWVyeSBzZXJ2ZXIuIENoZWNrIHRoZSBmb2xsb3dpbmcgU2VjdXJpdHkgc2VjdGlvbiBhbmQgb3VyIHByb3RvY29sIHNwZWNpZmljYXRpb24gZm9yIGRldGFpbHMuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMub2JqZWN0UGFyc2VyLFxuICB9LFxuICBsb2dMZXZlbDoge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX0xPR19MRVZFTCcsXG4gICAgaGVscDpcbiAgICAgICdUaGlzIHN0cmluZyBkZWZpbmVzIHRoZSBsb2cgbGV2ZWwgb2YgdGhlIExpdmVRdWVyeSBzZXJ2ZXIuIFdlIHN1cHBvcnQgVkVSQk9TRSwgSU5GTywgRVJST1IsIE5PTkUsIGRlZmF1bHRzIHRvIElORk8uJyxcbiAgfSxcbiAgbWFzdGVyS2V5OiB7XG4gICAgZW52OiAnUEFSU0VfTElWRV9RVUVSWV9TRVJWRVJfTUFTVEVSX0tFWScsXG4gICAgaGVscDpcbiAgICAgICdUaGlzIHN0cmluZyBzaG91bGQgbWF0Y2ggdGhlIG1hc3RlcktleSBpbiB1c2UgYnkgeW91ciBQYXJzZSBTZXJ2ZXIuIElmIHlvdSBkZXBsb3kgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgYWxvbmdzaWRlIFBhcnNlIFNlcnZlciwgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgd2lsbCB0cnkgdG8gdXNlIHRoZSBzYW1lIG1hc3RlcktleS4nLFxuICB9LFxuICBwb3J0OiB7XG4gICAgZW52OiAnUEFSU0VfTElWRV9RVUVSWV9TRVJWRVJfUE9SVCcsXG4gICAgaGVscDogJ1RoZSBwb3J0IHRvIHJ1biB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciwgZGVmYXVsdHMgdG8gMTMzNy4nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ3BvcnQnKSxcbiAgICBkZWZhdWx0OiAxMzM3LFxuICB9LFxuICBwdWJTdWJBZGFwdGVyOiB7XG4gICAgZW52OiAnUEFSU0VfTElWRV9RVUVSWV9TRVJWRVJfUFVCX1NVQl9BREFQVEVSJyxcbiAgICBoZWxwOiAnTGl2ZVF1ZXJ5IHB1YnN1YiBhZGFwdGVyJyxcbiAgICBhY3Rpb246IHBhcnNlcnMubW9kdWxlT3JPYmplY3RQYXJzZXIsXG4gIH0sXG4gIHJlZGlzT3B0aW9uczoge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX1JFRElTX09QVElPTlMnLFxuICAgIGhlbHA6IFwicGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IHJlZGlzT3B0aW9uc1wiLFxuICAgIGFjdGlvbjogcGFyc2Vycy5vYmplY3RQYXJzZXIsXG4gIH0sXG4gIHJlZGlzVVJMOiB7XG4gICAgZW52OiAnUEFSU0VfTElWRV9RVUVSWV9TRVJWRVJfUkVESVNfVVJMJyxcbiAgICBoZWxwOiBcInBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSByZWRpc1VSTFwiLFxuICB9LFxuICBzZXJ2ZXJVUkw6IHtcbiAgICBlbnY6ICdQQVJTRV9MSVZFX1FVRVJZX1NFUlZFUl9TRVJWRVJfVVJMJyxcbiAgICBoZWxwOlxuICAgICAgJ1RoaXMgc3RyaW5nIHNob3VsZCBtYXRjaCB0aGUgc2VydmVyVVJMIGluIHVzZSBieSB5b3VyIFBhcnNlIFNlcnZlci4gSWYgeW91IGRlcGxveSB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciBhbG9uZ3NpZGUgUGFyc2UgU2VydmVyLCB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciB3aWxsIHRyeSB0byB1c2UgdGhlIHNhbWUgc2VydmVyVVJMLicsXG4gIH0sXG4gIHdlYnNvY2tldFRpbWVvdXQ6IHtcbiAgICBlbnY6ICdQQVJTRV9MSVZFX1FVRVJZX1NFUlZFUl9XRUJTT0NLRVRfVElNRU9VVCcsXG4gICAgaGVscDpcbiAgICAgICdOdW1iZXIgb2YgbWlsbGlzZWNvbmRzIGJldHdlZW4gcGluZy9wb25nIGZyYW1lcy4gVGhlIFdlYlNvY2tldCBzZXJ2ZXIgc2VuZHMgcGluZy9wb25nIGZyYW1lcyB0byB0aGUgY2xpZW50cyB0byBrZWVwIHRoZSBXZWJTb2NrZXQgYWxpdmUuIFRoaXMgdmFsdWUgZGVmaW5lcyB0aGUgaW50ZXJ2YWwgb2YgdGhlIHBpbmcvcG9uZyBmcmFtZSBmcm9tIHRoZSBzZXJ2ZXIgdG8gY2xpZW50cywgZGVmYXVsdHMgdG8gMTAgKiAxMDAwIG1zICgxMCBzKS4nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ3dlYnNvY2tldFRpbWVvdXQnKSxcbiAgfSxcbiAgd3NzQWRhcHRlcjoge1xuICAgIGVudjogJ1BBUlNFX0xJVkVfUVVFUllfU0VSVkVSX1dTU19BREFQVEVSJyxcbiAgICBoZWxwOiAnQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBXZWJTb2NrZXRTZXJ2ZXInLFxuICAgIGFjdGlvbjogcGFyc2Vycy5tb2R1bGVPck9iamVjdFBhcnNlcixcbiAgfSxcbn07XG5tb2R1bGUuZXhwb3J0cy5JZGVtcG90ZW5jeU9wdGlvbnMgPSB7XG4gIHBhdGhzOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0VYUEVSSU1FTlRBTF9JREVNUE9URU5DWV9QQVRIUycsXG4gICAgaGVscDpcbiAgICAgICdBbiBhcnJheSBvZiBwYXRocyBmb3Igd2hpY2ggdGhlIGZlYXR1cmUgc2hvdWxkIGJlIGVuYWJsZWQuIFRoZSBtb3VudCBwYXRoIG11c3Qgbm90IGJlIGluY2x1ZGVkLCBmb3IgZXhhbXBsZSBpbnN0ZWFkIG9mIGAvcGFyc2UvZnVuY3Rpb25zL215RnVuY3Rpb25gIHNwZWNpZml5IGBmdW5jdGlvbnMvbXlGdW5jdGlvbmAuIFRoZSBlbnRyaWVzIGFyZSBpbnRlcnByZXRlZCBhcyByZWd1bGFyIGV4cHJlc3Npb24sIGZvciBleGFtcGxlIGBmdW5jdGlvbnMvLipgIG1hdGNoZXMgYWxsIGZ1bmN0aW9ucywgYGpvYnMvLipgIG1hdGNoZXMgYWxsIGpvYnMsIGBjbGFzc2VzLy4qYCBtYXRjaGVzIGFsbCBjbGFzc2VzLCBgLipgIG1hdGNoZXMgYWxsIHBhdGhzLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmFycmF5UGFyc2VyLFxuICAgIGRlZmF1bHQ6IFtdLFxuICB9LFxuICB0dGw6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfRVhQRVJJTUVOVEFMX0lERU1QT1RFTkNZX1RUTCcsXG4gICAgaGVscDpcbiAgICAgICdUaGUgZHVyYXRpb24gaW4gc2Vjb25kcyBhZnRlciB3aGljaCBhIHJlcXVlc3QgcmVjb3JkIGlzIGRpc2NhcmRlZCBmcm9tIHRoZSBkYXRhYmFzZSwgZGVmYXVsdHMgdG8gMzAwcy4nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ3R0bCcpLFxuICAgIGRlZmF1bHQ6IDMwMCxcbiAgfSxcbn07XG5tb2R1bGUuZXhwb3J0cy5BY2NvdW50TG9ja291dE9wdGlvbnMgPSB7XG4gIGR1cmF0aW9uOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0FDQ09VTlRfTE9DS09VVF9EVVJBVElPTicsXG4gICAgaGVscDpcbiAgICAgICdudW1iZXIgb2YgbWludXRlcyB0aGF0IGEgbG9ja2VkLW91dCBhY2NvdW50IHJlbWFpbnMgbG9ja2VkIG91dCBiZWZvcmUgYXV0b21hdGljYWxseSBiZWNvbWluZyB1bmxvY2tlZC4nLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ2R1cmF0aW9uJyksXG4gIH0sXG4gIHRocmVzaG9sZDoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9BQ0NPVU5UX0xPQ0tPVVRfVEhSRVNIT0xEJyxcbiAgICBoZWxwOiAnbnVtYmVyIG9mIGZhaWxlZCBzaWduLWluIGF0dGVtcHRzIHRoYXQgd2lsbCBjYXVzZSBhIHVzZXIgYWNjb3VudCB0byBiZSBsb2NrZWQnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ3RocmVzaG9sZCcpLFxuICB9LFxuICB1bmxvY2tPblBhc3N3b3JkUmVzZXQ6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfQUNDT1VOVF9MT0NLT1VUX1VOTE9DS19PTl9QQVNTV09SRF9SRVNFVCcsXG4gICAgaGVscDogJ0lzIHRydWUgaWYgdGhlIGFjY291bnQgbG9jayBzaG91bGQgYmUgcmVtb3ZlZCBhZnRlciBhIHN1Y2Nlc3NmdWwgcGFzc3dvcmQgcmVzZXQuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbn07XG5tb2R1bGUuZXhwb3J0cy5QYXNzd29yZFBvbGljeU9wdGlvbnMgPSB7XG4gIGRvTm90QWxsb3dVc2VybmFtZToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QQVNTV09SRF9QT0xJQ1lfRE9fTk9UX0FMTE9XX1VTRVJOQU1FJyxcbiAgICBoZWxwOiAnZGlzYWxsb3cgdXNlcm5hbWUgaW4gcGFzc3dvcmRzJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgfSxcbiAgbWF4UGFzc3dvcmRBZ2U6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfUEFTU1dPUkRfUE9MSUNZX01BWF9QQVNTV09SRF9BR0UnLFxuICAgIGhlbHA6ICdkYXlzIGZvciBwYXNzd29yZCBleHBpcnknLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ21heFBhc3N3b3JkQWdlJyksXG4gIH0sXG4gIG1heFBhc3N3b3JkSGlzdG9yeToge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QQVNTV09SRF9QT0xJQ1lfTUFYX1BBU1NXT1JEX0hJU1RPUlknLFxuICAgIGhlbHA6ICdzZXR0aW5nIHRvIHByZXZlbnQgcmV1c2Ugb2YgcHJldmlvdXMgbiBwYXNzd29yZHMnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ21heFBhc3N3b3JkSGlzdG9yeScpLFxuICB9LFxuICByZXNldFRva2VuUmV1c2VJZlZhbGlkOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BBU1NXT1JEX1BPTElDWV9SRVNFVF9UT0tFTl9SRVVTRV9JRl9WQUxJRCcsXG4gICAgaGVscDogXCJyZXNlbmQgdG9rZW4gaWYgaXQncyBzdGlsbCB2YWxpZFwiLFxuICAgIGFjdGlvbjogcGFyc2Vycy5ib29sZWFuUGFyc2VyLFxuICB9LFxuICByZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbjoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QQVNTV09SRF9QT0xJQ1lfUkVTRVRfVE9LRU5fVkFMSURJVFlfRFVSQVRJT04nLFxuICAgIGhlbHA6ICd0aW1lIGZvciB0b2tlbiB0byBleHBpcmUnLFxuICAgIGFjdGlvbjogcGFyc2Vycy5udW1iZXJQYXJzZXIoJ3Jlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uJyksXG4gIH0sXG4gIHZhbGlkYXRvckNhbGxiYWNrOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX1BBU1NXT1JEX1BPTElDWV9WQUxJREFUT1JfQ0FMTEJBQ0snLFxuICAgIGhlbHA6ICdhIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGJlIGludm9rZWQgdG8gdmFsaWRhdGUgdGhlIHBhc3N3b3JkJyxcbiAgfSxcbiAgdmFsaWRhdG9yUGF0dGVybjoge1xuICAgIGVudjogJ1BBUlNFX1NFUlZFUl9QQVNTV09SRF9QT0xJQ1lfVkFMSURBVE9SX1BBVFRFUk4nLFxuICAgIGhlbHA6ICdhIFJlZ0V4cCBvYmplY3Qgb3IgYSByZWdleCBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBwYXR0ZXJuIHRvIGVuZm9yY2UnLFxuICB9LFxufTtcbm1vZHVsZS5leHBvcnRzLkZpbGVVcGxvYWRPcHRpb25zID0ge1xuICBlbmFibGVGb3JBbm9ueW1vdXNVc2VyOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0ZJTEVfVVBMT0FEX0VOQUJMRV9GT1JfQU5PTllNT1VTX1VTRVInLFxuICAgIGhlbHA6ICdJcyB0cnVlIGlmIGZpbGUgdXBsb2FkIHNob3VsZCBiZSBhbGxvd2VkIGZvciBhbm9ueW1vdXMgdXNlcnMuJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbiAgZW5hYmxlRm9yQXV0aGVudGljYXRlZFVzZXI6IHtcbiAgICBlbnY6ICdQQVJTRV9TRVJWRVJfRklMRV9VUExPQURfRU5BQkxFX0ZPUl9BVVRIRU5USUNBVEVEX1VTRVInLFxuICAgIGhlbHA6ICdJcyB0cnVlIGlmIGZpbGUgdXBsb2FkIHNob3VsZCBiZSBhbGxvd2VkIGZvciBhdXRoZW50aWNhdGVkIHVzZXJzLicsXG4gICAgYWN0aW9uOiBwYXJzZXJzLmJvb2xlYW5QYXJzZXIsXG4gICAgZGVmYXVsdDogdHJ1ZSxcbiAgfSxcbiAgZW5hYmxlRm9yUHVibGljOiB7XG4gICAgZW52OiAnUEFSU0VfU0VSVkVSX0ZJTEVfVVBMT0FEX0VOQUJMRV9GT1JfUFVCTElDJyxcbiAgICBoZWxwOiAnSXMgdHJ1ZSBpZiBmaWxlIHVwbG9hZCBzaG91bGQgYmUgYWxsb3dlZCBmb3IgYW55b25lLCByZWdhcmRsZXNzIG9mIHVzZXIgYXV0aGVudGljYXRpb24uJyxcbiAgICBhY3Rpb246IHBhcnNlcnMuYm9vbGVhblBhcnNlcixcbiAgICBkZWZhdWx0OiBmYWxzZSxcbiAgfSxcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/Options/docs.js b/lib/Options/docs.js deleted file mode 100644 index ce971eafec..0000000000 --- a/lib/Options/docs.js +++ /dev/null @@ -1,178 +0,0 @@ -/** - * @interface ParseServerOptions - * @property {AccountLockoutOptions} accountLockout account lockout policy for failed login attempts - * @property {Boolean} allowClientClassCreation Enable (or disable) client class creation, defaults to true - * @property {Boolean} allowCustomObjectId Enable (or disable) custom objectId - * @property {String[]} allowHeaders Add headers to Access-Control-Allow-Headers - * @property {String} allowOrigin Sets the origin to Access-Control-Allow-Origin - * @property {Adapter} analyticsAdapter Adapter module for the analytics - * @property {String} appId Your Parse Application ID - * @property {String} appName Sets the app name - * @property {Any} auth Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication - * @property {Adapter} cacheAdapter Adapter module for the cache - * @property {Number} cacheMaxSize Sets the maximum size for the in memory cache, defaults to 10000 - * @property {Number} cacheTTL Sets the TTL for the in memory cache (in ms), defaults to 5000 (5 seconds) - * @property {String} clientKey Key for iOS, MacOS, tvOS clients - * @property {String} cloud Full path to your cloud code main.js - * @property {Number|Boolean} cluster Run with cluster, optionally set the number of processes default to os.cpus().length - * @property {String} collectionPrefix A collection prefix for the classes - * @property {CustomPagesOptions} customPages custom pages for password validation and reset - * @property {Adapter} databaseAdapter Adapter module for the database - * @property {Any} databaseOptions Options to pass to the mongodb client - * @property {String} databaseURI The full URI to your database. Supported databases are mongodb or postgres. - * @property {Boolean} directAccess Replace HTTP Interface when using JS SDK in current node runtime, defaults to false. Caution, this is an experimental feature that may not be appropriate for production. - * @property {String} dotNetKey Key for Unity and .Net SDK - * @property {Adapter} emailAdapter Adapter module for email sending - * @property {Boolean} emailVerifyTokenReuseIfValid an existing email verify token should be reused when resend verification email is requested - * @property {Number} emailVerifyTokenValidityDuration Email verification token validity duration, in seconds - * @property {Boolean} enableAnonymousUsers Enable (or disable) anonymous users, defaults to true - * @property {Boolean} enableExpressErrorHandler Enables the default express error handler for all errors - * @property {Boolean} enableSingleSchemaCache Use a single schema cache shared across requests. Reduces number of queries made to _SCHEMA, defaults to false, i.e. unique schema cache per request. - * @property {String} encryptionKey Key for encrypting your files - * @property {Boolean} expireInactiveSessions Sets wether we should expire the inactive sessions, defaults to true - * @property {String} fileKey Key for your files - * @property {Adapter} filesAdapter Adapter module for the files sub-system - * @property {FileUploadOptions} fileUpload Options for file uploads - * @property {String} graphQLPath Mount path for the GraphQL endpoint, defaults to /graphql - * @property {String} graphQLSchema Full path to your GraphQL custom schema.graphql file - * @property {String} host The host to serve ParseServer on, defaults to 0.0.0.0 - * @property {IdempotencyOptions} idempotencyOptions Options for request idempotency to deduplicate identical requests that may be caused by network issues. Caution, this is an experimental feature that may not be appropriate for production. - * @property {String} javascriptKey Key for the Javascript SDK - * @property {Boolean} jsonLogs Log as structured JSON objects - * @property {LiveQueryOptions} liveQuery parse-server's LiveQuery configuration object - * @property {LiveQueryServerOptions} liveQueryServerOptions Live query server configuration options (will start the liveQuery server) - * @property {Adapter} loggerAdapter Adapter module for the logging sub-system - * @property {String} logLevel Sets the level for logs - * @property {String} logsFolder Folder for the logs (defaults to './logs'); set to null to disable file based logging - * @property {String} masterKey Your Parse Master Key - * @property {String[]} masterKeyIps Restrict masterKey to be used by only these ips, defaults to [] (allow all ips) - * @property {Number} maxLimit Max value for limit option on queries, defaults to unlimited - * @property {Number|String} maxLogFiles Maximum number of logs to keep. If not set, no logs will be removed. This can be a number of files or number of days. If using days, add 'd' as the suffix. (default: null) - * @property {String} maxUploadSize Max file size for uploads, defaults to 20mb - * @property {Union} middleware middleware for express server, can be string or function - * @property {Boolean} mountGraphQL Mounts the GraphQL endpoint - * @property {String} mountPath Mount path for the server, defaults to /parse - * @property {Boolean} mountPlayground Mounts the GraphQL Playground - never use this option in production - * @property {Number} objectIdSize Sets the number of characters in generated object id's, default 10 - * @property {PagesOptions} pages The options for pages such as password reset and email verification. Caution, this is an experimental feature that may not be appropriate for production. - * @property {PasswordPolicyOptions} passwordPolicy Password policy for enforcing password related rules - * @property {String} playgroundPath Mount path for the GraphQL Playground, defaults to /playground - * @property {Number} port The port to run the ParseServer, defaults to 1337. - * @property {Boolean} preserveFileName Enable (or disable) the addition of a unique hash to the file names - * @property {Boolean} preventLoginWithUnverifiedEmail Prevent user from login if email is not verified and PARSE_SERVER_VERIFY_USER_EMAILS is true, defaults to false - * @property {ProtectedFields} protectedFields Protected fields that should be treated with extra security when fetching details. - * @property {String} publicServerURL Public URL to your parse server with http:// or https://. - * @property {Any} push Configuration for push, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#push-notifications - * @property {String} readOnlyMasterKey Read-only key, which has the same capabilities as MasterKey without writes - * @property {String} restAPIKey Key for REST calls - * @property {Boolean} revokeSessionOnPasswordReset When a user changes their password, either through the reset password email or while logged in, all sessions are revoked if this is true. Set to false if you don't want to revoke sessions. - * @property {Boolean} scheduledPush Configuration for push scheduling, defaults to false. - * @property {Number} schemaCacheTTL The TTL for caching the schema for optimizing read/write operations. You should put a long TTL when your DB is in production. default to 5000; set 0 to disable. - * @property {Function} serverCloseComplete Callback when server has closed - * @property {Function} serverStartComplete Callback when server has started - * @property {String} serverURL URL to your parse server with http:// or https://. - * @property {Number} sessionLength Session duration, in seconds, defaults to 1 year - * @property {Boolean} silent Disables console output - * @property {Boolean} startLiveQueryServer Starts the liveQuery server - * @property {String[]} userSensitiveFields Personally identifiable information fields in the user table the should be removed for non-authorized users. Deprecated @see protectedFields - * @property {Boolean} verbose Set the logging to verbose - * @property {Boolean} verifyUserEmails Enable (or disable) user email validation, defaults to false - * @property {String} webhookKey Key sent with outgoing webhook calls - */ - -/** - * @interface PagesOptions - * @property {PagesCustomUrlsOptions} customUrls The URLs to the custom pages. - * @property {Boolean} enableLocalization Is true if pages should be localized; this has no effect on custom page redirects. - * @property {Boolean} enableRouter Is true if the pages router should be enabled; this is required for any of the pages options to take effect. Caution, this is an experimental feature that may not be appropriate for production. - * @property {Boolean} forceRedirect Is true if responses should always be redirects and never content, false if the response type should depend on the request type (GET request -> content response; POST request -> redirect response). - * @property {String} localizationFallbackLocale The fallback locale for localization if no matching translation is provided for the given locale. This is only relevant when providing translation resources via JSON file. - * @property {String} localizationJsonPath The path to the JSON file for localization; the translations will be used to fill template placeholders according to the locale. - * @property {String} pagesEndpoint The API endpoint for the pages. Default is 'apps'. - * @property {String} pagesPath The path to the pages directory; this also defines where the static endpoint '/apps' points to. Default is the './public/' directory. - * @property {Object} placeholders The placeholder keys and values which will be filled in pages; this can be a simple object or a callback function. - */ - -/** - * @interface PagesCustomUrlsOptions - * @property {String} emailVerificationLinkExpired The URL to the custom page for email verification -> link expired. - * @property {String} emailVerificationLinkInvalid The URL to the custom page for email verification -> link invalid. - * @property {String} emailVerificationSendFail The URL to the custom page for email verification -> link send fail. - * @property {String} emailVerificationSendSuccess The URL to the custom page for email verification -> resend link -> success. - * @property {String} emailVerificationSuccess The URL to the custom page for email verification -> success. - * @property {String} passwordReset The URL to the custom page for password reset. - * @property {String} passwordResetLinkInvalid The URL to the custom page for password reset -> link invalid. - * @property {String} passwordResetSuccess The URL to the custom page for password reset -> success. - */ - -/** - * @interface CustomPagesOptions - * @property {String} choosePassword choose password page path - * @property {String} expiredVerificationLink expired verification link page path - * @property {String} invalidLink invalid link page path - * @property {String} invalidPasswordResetLink invalid password reset link page path - * @property {String} invalidVerificationLink invalid verification link page path - * @property {String} linkSendFail verification link send fail page path - * @property {String} linkSendSuccess verification link send success page path - * @property {String} parseFrameURL for masking user-facing pages - * @property {String} passwordResetSuccess password reset success page path - * @property {String} verifyEmailSuccess verify email success page path - */ - -/** - * @interface LiveQueryOptions - * @property {String[]} classNames parse-server's LiveQuery classNames - * @property {Adapter} pubSubAdapter LiveQuery pubsub adapter - * @property {Any} redisOptions parse-server's LiveQuery redisOptions - * @property {String} redisURL parse-server's LiveQuery redisURL - * @property {Adapter} wssAdapter Adapter module for the WebSocketServer - */ - -/** - * @interface LiveQueryServerOptions - * @property {String} appId This string should match the appId in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same appId. - * @property {Number} cacheTimeout Number in milliseconds. When clients provide the sessionToken to the LiveQuery server, the LiveQuery server will try to fetch its ParseUser's objectId from parse server and store it in the cache. The value defines the duration of the cache. Check the following Security section and our protocol specification for details, defaults to 5 * 1000 ms (5 seconds). - * @property {Any} keyPairs A JSON object that serves as a whitelist of keys. It is used for validating clients when they try to connect to the LiveQuery server. Check the following Security section and our protocol specification for details. - * @property {String} logLevel This string defines the log level of the LiveQuery server. We support VERBOSE, INFO, ERROR, NONE, defaults to INFO. - * @property {String} masterKey This string should match the masterKey in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same masterKey. - * @property {Number} port The port to run the LiveQuery server, defaults to 1337. - * @property {Adapter} pubSubAdapter LiveQuery pubsub adapter - * @property {Any} redisOptions parse-server's LiveQuery redisOptions - * @property {String} redisURL parse-server's LiveQuery redisURL - * @property {String} serverURL This string should match the serverURL in use by your Parse Server. If you deploy the LiveQuery server alongside Parse Server, the LiveQuery server will try to use the same serverURL. - * @property {Number} websocketTimeout Number of milliseconds between ping/pong frames. The WebSocket server sends ping/pong frames to the clients to keep the WebSocket alive. This value defines the interval of the ping/pong frame from the server to clients, defaults to 10 * 1000 ms (10 s). - * @property {Adapter} wssAdapter Adapter module for the WebSocketServer - */ - -/** - * @interface IdempotencyOptions - * @property {String[]} paths An array of paths for which the feature should be enabled. The mount path must not be included, for example instead of `/parse/functions/myFunction` specifiy `functions/myFunction`. The entries are interpreted as regular expression, for example `functions/.*` matches all functions, `jobs/.*` matches all jobs, `classes/.*` matches all classes, `.*` matches all paths. - * @property {Number} ttl The duration in seconds after which a request record is discarded from the database, defaults to 300s. - */ - -/** - * @interface AccountLockoutOptions - * @property {Number} duration number of minutes that a locked-out account remains locked out before automatically becoming unlocked. - * @property {Number} threshold number of failed sign-in attempts that will cause a user account to be locked - * @property {Boolean} unlockOnPasswordReset Is true if the account lock should be removed after a successful password reset. - */ - -/** - * @interface PasswordPolicyOptions - * @property {Boolean} doNotAllowUsername disallow username in passwords - * @property {Number} maxPasswordAge days for password expiry - * @property {Number} maxPasswordHistory setting to prevent reuse of previous n passwords - * @property {Boolean} resetTokenReuseIfValid resend token if it's still valid - * @property {Number} resetTokenValidityDuration time for token to expire - * @property {Function} validatorCallback a callback function to be invoked to validate the password - * @property {String} validatorPattern a RegExp object or a regex string representing the pattern to enforce - */ - -/** - * @interface FileUploadOptions - * @property {Boolean} enableForAnonymousUser Is true if file upload should be allowed for anonymous users. - * @property {Boolean} enableForAuthenticatedUser Is true if file upload should be allowed for authenticated users. - * @property {Boolean} enableForPublic Is true if file upload should be allowed for anyone, regardless of user authentication. - */ -"use strict"; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9PcHRpb25zL2RvY3MuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGludGVyZmFjZSBQYXJzZVNlcnZlck9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7QWNjb3VudExvY2tvdXRPcHRpb25zfSBhY2NvdW50TG9ja291dCBhY2NvdW50IGxvY2tvdXQgcG9saWN5IGZvciBmYWlsZWQgbG9naW4gYXR0ZW1wdHNcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gYWxsb3dDbGllbnRDbGFzc0NyZWF0aW9uIEVuYWJsZSAob3IgZGlzYWJsZSkgY2xpZW50IGNsYXNzIGNyZWF0aW9uLCBkZWZhdWx0cyB0byB0cnVlXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGFsbG93Q3VzdG9tT2JqZWN0SWQgRW5hYmxlIChvciBkaXNhYmxlKSBjdXN0b20gb2JqZWN0SWRcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nW119IGFsbG93SGVhZGVycyBBZGQgaGVhZGVycyB0byBBY2Nlc3MtQ29udHJvbC1BbGxvdy1IZWFkZXJzXG4gKiBAcHJvcGVydHkge1N0cmluZ30gYWxsb3dPcmlnaW4gU2V0cyB0aGUgb3JpZ2luIHRvIEFjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpblxuICogQHByb3BlcnR5IHtBZGFwdGVyPEFuYWx5dGljc0FkYXB0ZXI+fSBhbmFseXRpY3NBZGFwdGVyIEFkYXB0ZXIgbW9kdWxlIGZvciB0aGUgYW5hbHl0aWNzXG4gKiBAcHJvcGVydHkge1N0cmluZ30gYXBwSWQgWW91ciBQYXJzZSBBcHBsaWNhdGlvbiBJRFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGFwcE5hbWUgU2V0cyB0aGUgYXBwIG5hbWVcbiAqIEBwcm9wZXJ0eSB7QW55fSBhdXRoIENvbmZpZ3VyYXRpb24gZm9yIHlvdXIgYXV0aGVudGljYXRpb24gcHJvdmlkZXJzLCBhcyBzdHJpbmdpZmllZCBKU09OLiBTZWUgaHR0cDovL2RvY3MucGFyc2VwbGF0Zm9ybS5vcmcvcGFyc2Utc2VydmVyL2d1aWRlLyNvYXV0aC1hbmQtM3JkLXBhcnR5LWF1dGhlbnRpY2F0aW9uXG4gKiBAcHJvcGVydHkge0FkYXB0ZXI8Q2FjaGVBZGFwdGVyPn0gY2FjaGVBZGFwdGVyIEFkYXB0ZXIgbW9kdWxlIGZvciB0aGUgY2FjaGVcbiAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBjYWNoZU1heFNpemUgU2V0cyB0aGUgbWF4aW11bSBzaXplIGZvciB0aGUgaW4gbWVtb3J5IGNhY2hlLCBkZWZhdWx0cyB0byAxMDAwMFxuICogQHByb3BlcnR5IHtOdW1iZXJ9IGNhY2hlVFRMIFNldHMgdGhlIFRUTCBmb3IgdGhlIGluIG1lbW9yeSBjYWNoZSAoaW4gbXMpLCBkZWZhdWx0cyB0byA1MDAwICg1IHNlY29uZHMpXG4gKiBAcHJvcGVydHkge1N0cmluZ30gY2xpZW50S2V5IEtleSBmb3IgaU9TLCBNYWNPUywgdHZPUyBjbGllbnRzXG4gKiBAcHJvcGVydHkge1N0cmluZ30gY2xvdWQgRnVsbCBwYXRoIHRvIHlvdXIgY2xvdWQgY29kZSBtYWluLmpzXG4gKiBAcHJvcGVydHkge051bWJlcnxCb29sZWFufSBjbHVzdGVyIFJ1biB3aXRoIGNsdXN0ZXIsIG9wdGlvbmFsbHkgc2V0IHRoZSBudW1iZXIgb2YgcHJvY2Vzc2VzIGRlZmF1bHQgdG8gb3MuY3B1cygpLmxlbmd0aFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGNvbGxlY3Rpb25QcmVmaXggQSBjb2xsZWN0aW9uIHByZWZpeCBmb3IgdGhlIGNsYXNzZXNcbiAqIEBwcm9wZXJ0eSB7Q3VzdG9tUGFnZXNPcHRpb25zfSBjdXN0b21QYWdlcyBjdXN0b20gcGFnZXMgZm9yIHBhc3N3b3JkIHZhbGlkYXRpb24gYW5kIHJlc2V0XG4gKiBAcHJvcGVydHkge0FkYXB0ZXI8U3RvcmFnZUFkYXB0ZXI+fSBkYXRhYmFzZUFkYXB0ZXIgQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBkYXRhYmFzZVxuICogQHByb3BlcnR5IHtBbnl9IGRhdGFiYXNlT3B0aW9ucyBPcHRpb25zIHRvIHBhc3MgdG8gdGhlIG1vbmdvZGIgY2xpZW50XG4gKiBAcHJvcGVydHkge1N0cmluZ30gZGF0YWJhc2VVUkkgVGhlIGZ1bGwgVVJJIHRvIHlvdXIgZGF0YWJhc2UuIFN1cHBvcnRlZCBkYXRhYmFzZXMgYXJlIG1vbmdvZGIgb3IgcG9zdGdyZXMuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGRpcmVjdEFjY2VzcyBSZXBsYWNlIEhUVFAgSW50ZXJmYWNlIHdoZW4gdXNpbmcgSlMgU0RLIGluIGN1cnJlbnQgbm9kZSBydW50aW1lLCBkZWZhdWx0cyB0byBmYWxzZS4gQ2F1dGlvbiwgdGhpcyBpcyBhbiBleHBlcmltZW50YWwgZmVhdHVyZSB0aGF0IG1heSBub3QgYmUgYXBwcm9wcmlhdGUgZm9yIHByb2R1Y3Rpb24uXG4gKiBAcHJvcGVydHkge1N0cmluZ30gZG90TmV0S2V5IEtleSBmb3IgVW5pdHkgYW5kIC5OZXQgU0RLXG4gKiBAcHJvcGVydHkge0FkYXB0ZXI8TWFpbEFkYXB0ZXI+fSBlbWFpbEFkYXB0ZXIgQWRhcHRlciBtb2R1bGUgZm9yIGVtYWlsIHNlbmRpbmdcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZCBhbiBleGlzdGluZyBlbWFpbCB2ZXJpZnkgdG9rZW4gc2hvdWxkIGJlIHJldXNlZCB3aGVuIHJlc2VuZCB2ZXJpZmljYXRpb24gZW1haWwgaXMgcmVxdWVzdGVkXG4gKiBAcHJvcGVydHkge051bWJlcn0gZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24gRW1haWwgdmVyaWZpY2F0aW9uIHRva2VuIHZhbGlkaXR5IGR1cmF0aW9uLCBpbiBzZWNvbmRzXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGVuYWJsZUFub255bW91c1VzZXJzIEVuYWJsZSAob3IgZGlzYWJsZSkgYW5vbnltb3VzIHVzZXJzLCBkZWZhdWx0cyB0byB0cnVlXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGVuYWJsZUV4cHJlc3NFcnJvckhhbmRsZXIgRW5hYmxlcyB0aGUgZGVmYXVsdCBleHByZXNzIGVycm9yIGhhbmRsZXIgZm9yIGFsbCBlcnJvcnNcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gZW5hYmxlU2luZ2xlU2NoZW1hQ2FjaGUgVXNlIGEgc2luZ2xlIHNjaGVtYSBjYWNoZSBzaGFyZWQgYWNyb3NzIHJlcXVlc3RzLiBSZWR1Y2VzIG51bWJlciBvZiBxdWVyaWVzIG1hZGUgdG8gX1NDSEVNQSwgZGVmYXVsdHMgdG8gZmFsc2UsIGkuZS4gdW5pcXVlIHNjaGVtYSBjYWNoZSBwZXIgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBlbmNyeXB0aW9uS2V5IEtleSBmb3IgZW5jcnlwdGluZyB5b3VyIGZpbGVzXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGV4cGlyZUluYWN0aXZlU2Vzc2lvbnMgU2V0cyB3ZXRoZXIgd2Ugc2hvdWxkIGV4cGlyZSB0aGUgaW5hY3RpdmUgc2Vzc2lvbnMsIGRlZmF1bHRzIHRvIHRydWVcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBmaWxlS2V5IEtleSBmb3IgeW91ciBmaWxlc1xuICogQHByb3BlcnR5IHtBZGFwdGVyPEZpbGVzQWRhcHRlcj59IGZpbGVzQWRhcHRlciBBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGZpbGVzIHN1Yi1zeXN0ZW1cbiAqIEBwcm9wZXJ0eSB7RmlsZVVwbG9hZE9wdGlvbnN9IGZpbGVVcGxvYWQgT3B0aW9ucyBmb3IgZmlsZSB1cGxvYWRzXG4gKiBAcHJvcGVydHkge1N0cmluZ30gZ3JhcGhRTFBhdGggTW91bnQgcGF0aCBmb3IgdGhlIEdyYXBoUUwgZW5kcG9pbnQsIGRlZmF1bHRzIHRvIC9ncmFwaHFsXG4gKiBAcHJvcGVydHkge1N0cmluZ30gZ3JhcGhRTFNjaGVtYSBGdWxsIHBhdGggdG8geW91ciBHcmFwaFFMIGN1c3RvbSBzY2hlbWEuZ3JhcGhxbCBmaWxlXG4gKiBAcHJvcGVydHkge1N0cmluZ30gaG9zdCBUaGUgaG9zdCB0byBzZXJ2ZSBQYXJzZVNlcnZlciBvbiwgZGVmYXVsdHMgdG8gMC4wLjAuMFxuICogQHByb3BlcnR5IHtJZGVtcG90ZW5jeU9wdGlvbnN9IGlkZW1wb3RlbmN5T3B0aW9ucyBPcHRpb25zIGZvciByZXF1ZXN0IGlkZW1wb3RlbmN5IHRvIGRlZHVwbGljYXRlIGlkZW50aWNhbCByZXF1ZXN0cyB0aGF0IG1heSBiZSBjYXVzZWQgYnkgbmV0d29yayBpc3N1ZXMuIENhdXRpb24sIHRoaXMgaXMgYW4gZXhwZXJpbWVudGFsIGZlYXR1cmUgdGhhdCBtYXkgbm90IGJlIGFwcHJvcHJpYXRlIGZvciBwcm9kdWN0aW9uLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGphdmFzY3JpcHRLZXkgS2V5IGZvciB0aGUgSmF2YXNjcmlwdCBTREtcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0ganNvbkxvZ3MgTG9nIGFzIHN0cnVjdHVyZWQgSlNPTiBvYmplY3RzXG4gKiBAcHJvcGVydHkge0xpdmVRdWVyeU9wdGlvbnN9IGxpdmVRdWVyeSBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgY29uZmlndXJhdGlvbiBvYmplY3RcbiAqIEBwcm9wZXJ0eSB7TGl2ZVF1ZXJ5U2VydmVyT3B0aW9uc30gbGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucyBMaXZlIHF1ZXJ5IHNlcnZlciBjb25maWd1cmF0aW9uIG9wdGlvbnMgKHdpbGwgc3RhcnQgdGhlIGxpdmVRdWVyeSBzZXJ2ZXIpXG4gKiBAcHJvcGVydHkge0FkYXB0ZXI8TG9nZ2VyQWRhcHRlcj59IGxvZ2dlckFkYXB0ZXIgQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBsb2dnaW5nIHN1Yi1zeXN0ZW1cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBsb2dMZXZlbCBTZXRzIHRoZSBsZXZlbCBmb3IgbG9nc1xuICogQHByb3BlcnR5IHtTdHJpbmd9IGxvZ3NGb2xkZXIgRm9sZGVyIGZvciB0aGUgbG9ncyAoZGVmYXVsdHMgdG8gJy4vbG9ncycpOyBzZXQgdG8gbnVsbCB0byBkaXNhYmxlIGZpbGUgYmFzZWQgbG9nZ2luZ1xuICogQHByb3BlcnR5IHtTdHJpbmd9IG1hc3RlcktleSBZb3VyIFBhcnNlIE1hc3RlciBLZXlcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nW119IG1hc3RlcktleUlwcyBSZXN0cmljdCBtYXN0ZXJLZXkgdG8gYmUgdXNlZCBieSBvbmx5IHRoZXNlIGlwcywgZGVmYXVsdHMgdG8gW10gKGFsbG93IGFsbCBpcHMpXG4gKiBAcHJvcGVydHkge051bWJlcn0gbWF4TGltaXQgTWF4IHZhbHVlIGZvciBsaW1pdCBvcHRpb24gb24gcXVlcmllcywgZGVmYXVsdHMgdG8gdW5saW1pdGVkXG4gKiBAcHJvcGVydHkge051bWJlcnxTdHJpbmd9IG1heExvZ0ZpbGVzIE1heGltdW0gbnVtYmVyIG9mIGxvZ3MgdG8ga2VlcC4gSWYgbm90IHNldCwgbm8gbG9ncyB3aWxsIGJlIHJlbW92ZWQuIFRoaXMgY2FuIGJlIGEgbnVtYmVyIG9mIGZpbGVzIG9yIG51bWJlciBvZiBkYXlzLiBJZiB1c2luZyBkYXlzLCBhZGQgJ2QnIGFzIHRoZSBzdWZmaXguIChkZWZhdWx0OiBudWxsKVxuICogQHByb3BlcnR5IHtTdHJpbmd9IG1heFVwbG9hZFNpemUgTWF4IGZpbGUgc2l6ZSBmb3IgdXBsb2FkcywgZGVmYXVsdHMgdG8gMjBtYlxuICogQHByb3BlcnR5IHtVbmlvbn0gbWlkZGxld2FyZSBtaWRkbGV3YXJlIGZvciBleHByZXNzIHNlcnZlciwgY2FuIGJlIHN0cmluZyBvciBmdW5jdGlvblxuICogQHByb3BlcnR5IHtCb29sZWFufSBtb3VudEdyYXBoUUwgTW91bnRzIHRoZSBHcmFwaFFMIGVuZHBvaW50XG4gKiBAcHJvcGVydHkge1N0cmluZ30gbW91bnRQYXRoIE1vdW50IHBhdGggZm9yIHRoZSBzZXJ2ZXIsIGRlZmF1bHRzIHRvIC9wYXJzZVxuICogQHByb3BlcnR5IHtCb29sZWFufSBtb3VudFBsYXlncm91bmQgTW91bnRzIHRoZSBHcmFwaFFMIFBsYXlncm91bmQgLSBuZXZlciB1c2UgdGhpcyBvcHRpb24gaW4gcHJvZHVjdGlvblxuICogQHByb3BlcnR5IHtOdW1iZXJ9IG9iamVjdElkU2l6ZSBTZXRzIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiBnZW5lcmF0ZWQgb2JqZWN0IGlkJ3MsIGRlZmF1bHQgMTBcbiAqIEBwcm9wZXJ0eSB7UGFnZXNPcHRpb25zfSBwYWdlcyBUaGUgb3B0aW9ucyBmb3IgcGFnZXMgc3VjaCBhcyBwYXNzd29yZCByZXNldCBhbmQgZW1haWwgdmVyaWZpY2F0aW9uLiBDYXV0aW9uLCB0aGlzIGlzIGFuIGV4cGVyaW1lbnRhbCBmZWF0dXJlIHRoYXQgbWF5IG5vdCBiZSBhcHByb3ByaWF0ZSBmb3IgcHJvZHVjdGlvbi5cbiAqIEBwcm9wZXJ0eSB7UGFzc3dvcmRQb2xpY3lPcHRpb25zfSBwYXNzd29yZFBvbGljeSBQYXNzd29yZCBwb2xpY3kgZm9yIGVuZm9yY2luZyBwYXNzd29yZCByZWxhdGVkIHJ1bGVzXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcGxheWdyb3VuZFBhdGggTW91bnQgcGF0aCBmb3IgdGhlIEdyYXBoUUwgUGxheWdyb3VuZCwgZGVmYXVsdHMgdG8gL3BsYXlncm91bmRcbiAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBwb3J0IFRoZSBwb3J0IHRvIHJ1biB0aGUgUGFyc2VTZXJ2ZXIsIGRlZmF1bHRzIHRvIDEzMzcuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHByZXNlcnZlRmlsZU5hbWUgRW5hYmxlIChvciBkaXNhYmxlKSB0aGUgYWRkaXRpb24gb2YgYSB1bmlxdWUgaGFzaCB0byB0aGUgZmlsZSBuYW1lc1xuICogQHByb3BlcnR5IHtCb29sZWFufSBwcmV2ZW50TG9naW5XaXRoVW52ZXJpZmllZEVtYWlsIFByZXZlbnQgdXNlciBmcm9tIGxvZ2luIGlmIGVtYWlsIGlzIG5vdCB2ZXJpZmllZCBhbmQgUEFSU0VfU0VSVkVSX1ZFUklGWV9VU0VSX0VNQUlMUyBpcyB0cnVlLCBkZWZhdWx0cyB0byBmYWxzZVxuICogQHByb3BlcnR5IHtQcm90ZWN0ZWRGaWVsZHN9IHByb3RlY3RlZEZpZWxkcyBQcm90ZWN0ZWQgZmllbGRzIHRoYXQgc2hvdWxkIGJlIHRyZWF0ZWQgd2l0aCBleHRyYSBzZWN1cml0eSB3aGVuIGZldGNoaW5nIGRldGFpbHMuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcHVibGljU2VydmVyVVJMIFB1YmxpYyBVUkwgdG8geW91ciBwYXJzZSBzZXJ2ZXIgd2l0aCBodHRwOi8vIG9yIGh0dHBzOi8vLlxuICogQHByb3BlcnR5IHtBbnl9IHB1c2ggQ29uZmlndXJhdGlvbiBmb3IgcHVzaCwgYXMgc3RyaW5naWZpZWQgSlNPTi4gU2VlIGh0dHA6Ly9kb2NzLnBhcnNlcGxhdGZvcm0ub3JnL3BhcnNlLXNlcnZlci9ndWlkZS8jcHVzaC1ub3RpZmljYXRpb25zXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcmVhZE9ubHlNYXN0ZXJLZXkgUmVhZC1vbmx5IGtleSwgd2hpY2ggaGFzIHRoZSBzYW1lIGNhcGFiaWxpdGllcyBhcyBNYXN0ZXJLZXkgd2l0aG91dCB3cml0ZXNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSByZXN0QVBJS2V5IEtleSBmb3IgUkVTVCBjYWxsc1xuICogQHByb3BlcnR5IHtCb29sZWFufSByZXZva2VTZXNzaW9uT25QYXNzd29yZFJlc2V0IFdoZW4gYSB1c2VyIGNoYW5nZXMgdGhlaXIgcGFzc3dvcmQsIGVpdGhlciB0aHJvdWdoIHRoZSByZXNldCBwYXNzd29yZCBlbWFpbCBvciB3aGlsZSBsb2dnZWQgaW4sIGFsbCBzZXNzaW9ucyBhcmUgcmV2b2tlZCBpZiB0aGlzIGlzIHRydWUuIFNldCB0byBmYWxzZSBpZiB5b3UgZG9uJ3Qgd2FudCB0byByZXZva2Ugc2Vzc2lvbnMuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHNjaGVkdWxlZFB1c2ggQ29uZmlndXJhdGlvbiBmb3IgcHVzaCBzY2hlZHVsaW5nLCBkZWZhdWx0cyB0byBmYWxzZS5cbiAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBzY2hlbWFDYWNoZVRUTCBUaGUgVFRMIGZvciBjYWNoaW5nIHRoZSBzY2hlbWEgZm9yIG9wdGltaXppbmcgcmVhZC93cml0ZSBvcGVyYXRpb25zLiBZb3Ugc2hvdWxkIHB1dCBhIGxvbmcgVFRMIHdoZW4geW91ciBEQiBpcyBpbiBwcm9kdWN0aW9uLiBkZWZhdWx0IHRvIDUwMDA7IHNldCAwIHRvIGRpc2FibGUuXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBzZXJ2ZXJDbG9zZUNvbXBsZXRlIENhbGxiYWNrIHdoZW4gc2VydmVyIGhhcyBjbG9zZWRcbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IHNlcnZlclN0YXJ0Q29tcGxldGUgQ2FsbGJhY2sgd2hlbiBzZXJ2ZXIgaGFzIHN0YXJ0ZWRcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBzZXJ2ZXJVUkwgVVJMIHRvIHlvdXIgcGFyc2Ugc2VydmVyIHdpdGggaHR0cDovLyBvciBodHRwczovLy5cbiAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBzZXNzaW9uTGVuZ3RoIFNlc3Npb24gZHVyYXRpb24sIGluIHNlY29uZHMsIGRlZmF1bHRzIHRvIDEgeWVhclxuICogQHByb3BlcnR5IHtCb29sZWFufSBzaWxlbnQgRGlzYWJsZXMgY29uc29sZSBvdXRwdXRcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gc3RhcnRMaXZlUXVlcnlTZXJ2ZXIgU3RhcnRzIHRoZSBsaXZlUXVlcnkgc2VydmVyXG4gKiBAcHJvcGVydHkge1N0cmluZ1tdfSB1c2VyU2Vuc2l0aXZlRmllbGRzIFBlcnNvbmFsbHkgaWRlbnRpZmlhYmxlIGluZm9ybWF0aW9uIGZpZWxkcyBpbiB0aGUgdXNlciB0YWJsZSB0aGUgc2hvdWxkIGJlIHJlbW92ZWQgZm9yIG5vbi1hdXRob3JpemVkIHVzZXJzLiBEZXByZWNhdGVkIEBzZWUgcHJvdGVjdGVkRmllbGRzXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHZlcmJvc2UgU2V0IHRoZSBsb2dnaW5nIHRvIHZlcmJvc2VcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gdmVyaWZ5VXNlckVtYWlscyBFbmFibGUgKG9yIGRpc2FibGUpIHVzZXIgZW1haWwgdmFsaWRhdGlvbiwgZGVmYXVsdHMgdG8gZmFsc2VcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSB3ZWJob29rS2V5IEtleSBzZW50IHdpdGggb3V0Z29pbmcgd2ViaG9vayBjYWxsc1xuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBQYWdlc09wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7UGFnZXNDdXN0b21VcmxzT3B0aW9uc30gY3VzdG9tVXJscyBUaGUgVVJMcyB0byB0aGUgY3VzdG9tIHBhZ2VzLlxuICogQHByb3BlcnR5IHtCb29sZWFufSBlbmFibGVMb2NhbGl6YXRpb24gSXMgdHJ1ZSBpZiBwYWdlcyBzaG91bGQgYmUgbG9jYWxpemVkOyB0aGlzIGhhcyBubyBlZmZlY3Qgb24gY3VzdG9tIHBhZ2UgcmVkaXJlY3RzLlxuICogQHByb3BlcnR5IHtCb29sZWFufSBlbmFibGVSb3V0ZXIgSXMgdHJ1ZSBpZiB0aGUgcGFnZXMgcm91dGVyIHNob3VsZCBiZSBlbmFibGVkOyB0aGlzIGlzIHJlcXVpcmVkIGZvciBhbnkgb2YgdGhlIHBhZ2VzIG9wdGlvbnMgdG8gdGFrZSBlZmZlY3QuIENhdXRpb24sIHRoaXMgaXMgYW4gZXhwZXJpbWVudGFsIGZlYXR1cmUgdGhhdCBtYXkgbm90IGJlIGFwcHJvcHJpYXRlIGZvciBwcm9kdWN0aW9uLlxuICogQHByb3BlcnR5IHtCb29sZWFufSBmb3JjZVJlZGlyZWN0IElzIHRydWUgaWYgcmVzcG9uc2VzIHNob3VsZCBhbHdheXMgYmUgcmVkaXJlY3RzIGFuZCBuZXZlciBjb250ZW50LCBmYWxzZSBpZiB0aGUgcmVzcG9uc2UgdHlwZSBzaG91bGQgZGVwZW5kIG9uIHRoZSByZXF1ZXN0IHR5cGUgKEdFVCByZXF1ZXN0IC0+IGNvbnRlbnQgcmVzcG9uc2U7IFBPU1QgcmVxdWVzdCAtPiByZWRpcmVjdCByZXNwb25zZSkuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gbG9jYWxpemF0aW9uRmFsbGJhY2tMb2NhbGUgVGhlIGZhbGxiYWNrIGxvY2FsZSBmb3IgbG9jYWxpemF0aW9uIGlmIG5vIG1hdGNoaW5nIHRyYW5zbGF0aW9uIGlzIHByb3ZpZGVkIGZvciB0aGUgZ2l2ZW4gbG9jYWxlLiBUaGlzIGlzIG9ubHkgcmVsZXZhbnQgd2hlbiBwcm92aWRpbmcgdHJhbnNsYXRpb24gcmVzb3VyY2VzIHZpYSBKU09OIGZpbGUuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gbG9jYWxpemF0aW9uSnNvblBhdGggVGhlIHBhdGggdG8gdGhlIEpTT04gZmlsZSBmb3IgbG9jYWxpemF0aW9uOyB0aGUgdHJhbnNsYXRpb25zIHdpbGwgYmUgdXNlZCB0byBmaWxsIHRlbXBsYXRlIHBsYWNlaG9sZGVycyBhY2NvcmRpbmcgdG8gdGhlIGxvY2FsZS5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBwYWdlc0VuZHBvaW50IFRoZSBBUEkgZW5kcG9pbnQgZm9yIHRoZSBwYWdlcy4gRGVmYXVsdCBpcyAnYXBwcycuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcGFnZXNQYXRoIFRoZSBwYXRoIHRvIHRoZSBwYWdlcyBkaXJlY3Rvcnk7IHRoaXMgYWxzbyBkZWZpbmVzIHdoZXJlIHRoZSBzdGF0aWMgZW5kcG9pbnQgJy9hcHBzJyBwb2ludHMgdG8uIERlZmF1bHQgaXMgdGhlICcuL3B1YmxpYy8nIGRpcmVjdG9yeS5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBwbGFjZWhvbGRlcnMgVGhlIHBsYWNlaG9sZGVyIGtleXMgYW5kIHZhbHVlcyB3aGljaCB3aWxsIGJlIGZpbGxlZCBpbiBwYWdlczsgdGhpcyBjYW4gYmUgYSBzaW1wbGUgb2JqZWN0IG9yIGEgY2FsbGJhY2sgZnVuY3Rpb24uXG4gKi9cblxuLyoqXG4gKiBAaW50ZXJmYWNlIFBhZ2VzQ3VzdG9tVXJsc09wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBlbWFpbFZlcmlmaWNhdGlvbkxpbmtFeHBpcmVkIFRoZSBVUkwgdG8gdGhlIGN1c3RvbSBwYWdlIGZvciBlbWFpbCB2ZXJpZmljYXRpb24gLT4gbGluayBleHBpcmVkLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGVtYWlsVmVyaWZpY2F0aW9uTGlua0ludmFsaWQgVGhlIFVSTCB0byB0aGUgY3VzdG9tIHBhZ2UgZm9yIGVtYWlsIHZlcmlmaWNhdGlvbiAtPiBsaW5rIGludmFsaWQuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gZW1haWxWZXJpZmljYXRpb25TZW5kRmFpbCBUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgZW1haWwgdmVyaWZpY2F0aW9uIC0+IGxpbmsgc2VuZCBmYWlsLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGVtYWlsVmVyaWZpY2F0aW9uU2VuZFN1Y2Nlc3MgVGhlIFVSTCB0byB0aGUgY3VzdG9tIHBhZ2UgZm9yIGVtYWlsIHZlcmlmaWNhdGlvbiAtPiByZXNlbmQgbGluayAtPiBzdWNjZXNzLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGVtYWlsVmVyaWZpY2F0aW9uU3VjY2VzcyBUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgZW1haWwgdmVyaWZpY2F0aW9uIC0+IHN1Y2Nlc3MuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcGFzc3dvcmRSZXNldCBUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgcGFzc3dvcmQgcmVzZXQuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcGFzc3dvcmRSZXNldExpbmtJbnZhbGlkIFRoZSBVUkwgdG8gdGhlIGN1c3RvbSBwYWdlIGZvciBwYXNzd29yZCByZXNldCAtPiBsaW5rIGludmFsaWQuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcGFzc3dvcmRSZXNldFN1Y2Nlc3MgVGhlIFVSTCB0byB0aGUgY3VzdG9tIHBhZ2UgZm9yIHBhc3N3b3JkIHJlc2V0IC0+IHN1Y2Nlc3MuXG4gKi9cblxuLyoqXG4gKiBAaW50ZXJmYWNlIEN1c3RvbVBhZ2VzT3B0aW9uc1xuICogQHByb3BlcnR5IHtTdHJpbmd9IGNob29zZVBhc3N3b3JkIGNob29zZSBwYXNzd29yZCBwYWdlIHBhdGhcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBleHBpcmVkVmVyaWZpY2F0aW9uTGluayBleHBpcmVkIHZlcmlmaWNhdGlvbiBsaW5rIHBhZ2UgcGF0aFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGludmFsaWRMaW5rIGludmFsaWQgbGluayBwYWdlIHBhdGhcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpbnZhbGlkUGFzc3dvcmRSZXNldExpbmsgaW52YWxpZCBwYXNzd29yZCByZXNldCBsaW5rIHBhZ2UgcGF0aFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGludmFsaWRWZXJpZmljYXRpb25MaW5rIGludmFsaWQgdmVyaWZpY2F0aW9uIGxpbmsgcGFnZSBwYXRoXG4gKiBAcHJvcGVydHkge1N0cmluZ30gbGlua1NlbmRGYWlsIHZlcmlmaWNhdGlvbiBsaW5rIHNlbmQgZmFpbCBwYWdlIHBhdGhcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBsaW5rU2VuZFN1Y2Nlc3MgdmVyaWZpY2F0aW9uIGxpbmsgc2VuZCBzdWNjZXNzIHBhZ2UgcGF0aFxuICogQHByb3BlcnR5IHtTdHJpbmd9IHBhcnNlRnJhbWVVUkwgZm9yIG1hc2tpbmcgdXNlci1mYWNpbmcgcGFnZXNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBwYXNzd29yZFJlc2V0U3VjY2VzcyBwYXNzd29yZCByZXNldCBzdWNjZXNzIHBhZ2UgcGF0aFxuICogQHByb3BlcnR5IHtTdHJpbmd9IHZlcmlmeUVtYWlsU3VjY2VzcyB2ZXJpZnkgZW1haWwgc3VjY2VzcyBwYWdlIHBhdGhcbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgTGl2ZVF1ZXJ5T3B0aW9uc1xuICogQHByb3BlcnR5IHtTdHJpbmdbXX0gY2xhc3NOYW1lcyBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgY2xhc3NOYW1lc1xuICogQHByb3BlcnR5IHtBZGFwdGVyPFB1YlN1YkFkYXB0ZXI+fSBwdWJTdWJBZGFwdGVyIExpdmVRdWVyeSBwdWJzdWIgYWRhcHRlclxuICogQHByb3BlcnR5IHtBbnl9IHJlZGlzT3B0aW9ucyBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgcmVkaXNPcHRpb25zXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcmVkaXNVUkwgcGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IHJlZGlzVVJMXG4gKiBAcHJvcGVydHkge0FkYXB0ZXI8V1NTQWRhcHRlcj59IHdzc0FkYXB0ZXIgQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBXZWJTb2NrZXRTZXJ2ZXJcbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgTGl2ZVF1ZXJ5U2VydmVyT3B0aW9uc1xuICogQHByb3BlcnR5IHtTdHJpbmd9IGFwcElkIFRoaXMgc3RyaW5nIHNob3VsZCBtYXRjaCB0aGUgYXBwSWQgaW4gdXNlIGJ5IHlvdXIgUGFyc2UgU2VydmVyLiBJZiB5b3UgZGVwbG95IHRoZSBMaXZlUXVlcnkgc2VydmVyIGFsb25nc2lkZSBQYXJzZSBTZXJ2ZXIsIHRoZSBMaXZlUXVlcnkgc2VydmVyIHdpbGwgdHJ5IHRvIHVzZSB0aGUgc2FtZSBhcHBJZC5cbiAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBjYWNoZVRpbWVvdXQgTnVtYmVyIGluIG1pbGxpc2Vjb25kcy4gV2hlbiBjbGllbnRzIHByb3ZpZGUgdGhlIHNlc3Npb25Ub2tlbiB0byB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciwgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgd2lsbCB0cnkgdG8gZmV0Y2ggaXRzIFBhcnNlVXNlcidzIG9iamVjdElkIGZyb20gcGFyc2Ugc2VydmVyIGFuZCBzdG9yZSBpdCBpbiB0aGUgY2FjaGUuIFRoZSB2YWx1ZSBkZWZpbmVzIHRoZSBkdXJhdGlvbiBvZiB0aGUgY2FjaGUuIENoZWNrIHRoZSBmb2xsb3dpbmcgU2VjdXJpdHkgc2VjdGlvbiBhbmQgb3VyIHByb3RvY29sIHNwZWNpZmljYXRpb24gZm9yIGRldGFpbHMsIGRlZmF1bHRzIHRvIDUgKiAxMDAwIG1zICg1IHNlY29uZHMpLlxuICogQHByb3BlcnR5IHtBbnl9IGtleVBhaXJzIEEgSlNPTiBvYmplY3QgdGhhdCBzZXJ2ZXMgYXMgYSB3aGl0ZWxpc3Qgb2Yga2V5cy4gSXQgaXMgdXNlZCBmb3IgdmFsaWRhdGluZyBjbGllbnRzIHdoZW4gdGhleSB0cnkgdG8gY29ubmVjdCB0byB0aGUgTGl2ZVF1ZXJ5IHNlcnZlci4gQ2hlY2sgdGhlIGZvbGxvd2luZyBTZWN1cml0eSBzZWN0aW9uIGFuZCBvdXIgcHJvdG9jb2wgc3BlY2lmaWNhdGlvbiBmb3IgZGV0YWlscy5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBsb2dMZXZlbCBUaGlzIHN0cmluZyBkZWZpbmVzIHRoZSBsb2cgbGV2ZWwgb2YgdGhlIExpdmVRdWVyeSBzZXJ2ZXIuIFdlIHN1cHBvcnQgVkVSQk9TRSwgSU5GTywgRVJST1IsIE5PTkUsIGRlZmF1bHRzIHRvIElORk8uXG4gKiBAcHJvcGVydHkge1N0cmluZ30gbWFzdGVyS2V5IFRoaXMgc3RyaW5nIHNob3VsZCBtYXRjaCB0aGUgbWFzdGVyS2V5IGluIHVzZSBieSB5b3VyIFBhcnNlIFNlcnZlci4gSWYgeW91IGRlcGxveSB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciBhbG9uZ3NpZGUgUGFyc2UgU2VydmVyLCB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciB3aWxsIHRyeSB0byB1c2UgdGhlIHNhbWUgbWFzdGVyS2V5LlxuICogQHByb3BlcnR5IHtOdW1iZXJ9IHBvcnQgVGhlIHBvcnQgdG8gcnVuIHRoZSBMaXZlUXVlcnkgc2VydmVyLCBkZWZhdWx0cyB0byAxMzM3LlxuICogQHByb3BlcnR5IHtBZGFwdGVyPFB1YlN1YkFkYXB0ZXI+fSBwdWJTdWJBZGFwdGVyIExpdmVRdWVyeSBwdWJzdWIgYWRhcHRlclxuICogQHByb3BlcnR5IHtBbnl9IHJlZGlzT3B0aW9ucyBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgcmVkaXNPcHRpb25zXG4gKiBAcHJvcGVydHkge1N0cmluZ30gcmVkaXNVUkwgcGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IHJlZGlzVVJMXG4gKiBAcHJvcGVydHkge1N0cmluZ30gc2VydmVyVVJMIFRoaXMgc3RyaW5nIHNob3VsZCBtYXRjaCB0aGUgc2VydmVyVVJMIGluIHVzZSBieSB5b3VyIFBhcnNlIFNlcnZlci4gSWYgeW91IGRlcGxveSB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciBhbG9uZ3NpZGUgUGFyc2UgU2VydmVyLCB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciB3aWxsIHRyeSB0byB1c2UgdGhlIHNhbWUgc2VydmVyVVJMLlxuICogQHByb3BlcnR5IHtOdW1iZXJ9IHdlYnNvY2tldFRpbWVvdXQgTnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBiZXR3ZWVuIHBpbmcvcG9uZyBmcmFtZXMuIFRoZSBXZWJTb2NrZXQgc2VydmVyIHNlbmRzIHBpbmcvcG9uZyBmcmFtZXMgdG8gdGhlIGNsaWVudHMgdG8ga2VlcCB0aGUgV2ViU29ja2V0IGFsaXZlLiBUaGlzIHZhbHVlIGRlZmluZXMgdGhlIGludGVydmFsIG9mIHRoZSBwaW5nL3BvbmcgZnJhbWUgZnJvbSB0aGUgc2VydmVyIHRvIGNsaWVudHMsIGRlZmF1bHRzIHRvIDEwICogMTAwMCBtcyAoMTAgcykuXG4gKiBAcHJvcGVydHkge0FkYXB0ZXI8V1NTQWRhcHRlcj59IHdzc0FkYXB0ZXIgQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBXZWJTb2NrZXRTZXJ2ZXJcbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgSWRlbXBvdGVuY3lPcHRpb25zXG4gKiBAcHJvcGVydHkge1N0cmluZ1tdfSBwYXRocyBBbiBhcnJheSBvZiBwYXRocyBmb3Igd2hpY2ggdGhlIGZlYXR1cmUgc2hvdWxkIGJlIGVuYWJsZWQuIFRoZSBtb3VudCBwYXRoIG11c3Qgbm90IGJlIGluY2x1ZGVkLCBmb3IgZXhhbXBsZSBpbnN0ZWFkIG9mIGAvcGFyc2UvZnVuY3Rpb25zL215RnVuY3Rpb25gIHNwZWNpZml5IGBmdW5jdGlvbnMvbXlGdW5jdGlvbmAuIFRoZSBlbnRyaWVzIGFyZSBpbnRlcnByZXRlZCBhcyByZWd1bGFyIGV4cHJlc3Npb24sIGZvciBleGFtcGxlIGBmdW5jdGlvbnMvLipgIG1hdGNoZXMgYWxsIGZ1bmN0aW9ucywgYGpvYnMvLipgIG1hdGNoZXMgYWxsIGpvYnMsIGBjbGFzc2VzLy4qYCBtYXRjaGVzIGFsbCBjbGFzc2VzLCBgLipgIG1hdGNoZXMgYWxsIHBhdGhzLlxuICogQHByb3BlcnR5IHtOdW1iZXJ9IHR0bCBUaGUgZHVyYXRpb24gaW4gc2Vjb25kcyBhZnRlciB3aGljaCBhIHJlcXVlc3QgcmVjb3JkIGlzIGRpc2NhcmRlZCBmcm9tIHRoZSBkYXRhYmFzZSwgZGVmYXVsdHMgdG8gMzAwcy5cbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgQWNjb3VudExvY2tvdXRPcHRpb25zXG4gKiBAcHJvcGVydHkge051bWJlcn0gZHVyYXRpb24gbnVtYmVyIG9mIG1pbnV0ZXMgdGhhdCBhIGxvY2tlZC1vdXQgYWNjb3VudCByZW1haW5zIGxvY2tlZCBvdXQgYmVmb3JlIGF1dG9tYXRpY2FsbHkgYmVjb21pbmcgdW5sb2NrZWQuXG4gKiBAcHJvcGVydHkge051bWJlcn0gdGhyZXNob2xkIG51bWJlciBvZiBmYWlsZWQgc2lnbi1pbiBhdHRlbXB0cyB0aGF0IHdpbGwgY2F1c2UgYSB1c2VyIGFjY291bnQgdG8gYmUgbG9ja2VkXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHVubG9ja09uUGFzc3dvcmRSZXNldCBJcyB0cnVlIGlmIHRoZSBhY2NvdW50IGxvY2sgc2hvdWxkIGJlIHJlbW92ZWQgYWZ0ZXIgYSBzdWNjZXNzZnVsIHBhc3N3b3JkIHJlc2V0LlxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBQYXNzd29yZFBvbGljeU9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gZG9Ob3RBbGxvd1VzZXJuYW1lIGRpc2FsbG93IHVzZXJuYW1lIGluIHBhc3N3b3Jkc1xuICogQHByb3BlcnR5IHtOdW1iZXJ9IG1heFBhc3N3b3JkQWdlIGRheXMgZm9yIHBhc3N3b3JkIGV4cGlyeVxuICogQHByb3BlcnR5IHtOdW1iZXJ9IG1heFBhc3N3b3JkSGlzdG9yeSBzZXR0aW5nIHRvIHByZXZlbnQgcmV1c2Ugb2YgcHJldmlvdXMgbiBwYXNzd29yZHNcbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gcmVzZXRUb2tlblJldXNlSWZWYWxpZCByZXNlbmQgdG9rZW4gaWYgaXQncyBzdGlsbCB2YWxpZFxuICogQHByb3BlcnR5IHtOdW1iZXJ9IHJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uIHRpbWUgZm9yIHRva2VuIHRvIGV4cGlyZVxuICogQHByb3BlcnR5IHtGdW5jdGlvbn0gdmFsaWRhdG9yQ2FsbGJhY2sgYSBjYWxsYmFjayBmdW5jdGlvbiB0byBiZSBpbnZva2VkIHRvIHZhbGlkYXRlIHRoZSBwYXNzd29yZFxuICogQHByb3BlcnR5IHtTdHJpbmd9IHZhbGlkYXRvclBhdHRlcm4gYSBSZWdFeHAgb2JqZWN0IG9yIGEgcmVnZXggc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgcGF0dGVybiB0byBlbmZvcmNlXG4gKi9cblxuLyoqXG4gKiBAaW50ZXJmYWNlIEZpbGVVcGxvYWRPcHRpb25zXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGVuYWJsZUZvckFub255bW91c1VzZXIgSXMgdHJ1ZSBpZiBmaWxlIHVwbG9hZCBzaG91bGQgYmUgYWxsb3dlZCBmb3IgYW5vbnltb3VzIHVzZXJzLlxuICogQHByb3BlcnR5IHtCb29sZWFufSBlbmFibGVGb3JBdXRoZW50aWNhdGVkVXNlciBJcyB0cnVlIGlmIGZpbGUgdXBsb2FkIHNob3VsZCBiZSBhbGxvd2VkIGZvciBhdXRoZW50aWNhdGVkIHVzZXJzLlxuICogQHByb3BlcnR5IHtCb29sZWFufSBlbmFibGVGb3JQdWJsaWMgSXMgdHJ1ZSBpZiBmaWxlIHVwbG9hZCBzaG91bGQgYmUgYWxsb3dlZCBmb3IgYW55b25lLCByZWdhcmRsZXNzIG9mIHVzZXIgYXV0aGVudGljYXRpb24uXG4gKi9cbiJdfQ== \ No newline at end of file diff --git a/lib/Options/index.js b/lib/Options/index.js deleted file mode 100644 index 19f00164db..0000000000 --- a/lib/Options/index.js +++ /dev/null @@ -1,18 +0,0 @@ -"use strict"; - -var _AnalyticsAdapter = require("../Adapters/Analytics/AnalyticsAdapter"); - -var _FilesAdapter = require("../Adapters/Files/FilesAdapter"); - -var _LoggerAdapter = require("../Adapters/Logger/LoggerAdapter"); - -var _StorageAdapter = require("../Adapters/Storage/StorageAdapter"); - -var _CacheAdapter = require("../Adapters/Cache/CacheAdapter"); - -var _MailAdapter = require("../Adapters/Email/MailAdapter"); - -var _PubSubAdapter = require("../Adapters/PubSub/PubSubAdapter"); - -var _WSSAdapter = require("../Adapters/WebSocketServer/WSSAdapter"); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9PcHRpb25zL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0EiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBbmFseXRpY3NBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvQW5hbHl0aWNzL0FuYWx5dGljc0FkYXB0ZXInO1xuaW1wb3J0IHsgRmlsZXNBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvRmlsZXMvRmlsZXNBZGFwdGVyJztcbmltcG9ydCB7IExvZ2dlckFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9Mb2dnZXIvTG9nZ2VyQWRhcHRlcic7XG5pbXBvcnQgeyBTdG9yYWdlQWRhcHRlciB9IGZyb20gJy4uL0FkYXB0ZXJzL1N0b3JhZ2UvU3RvcmFnZUFkYXB0ZXInO1xuaW1wb3J0IHsgQ2FjaGVBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvQ2FjaGUvQ2FjaGVBZGFwdGVyJztcbmltcG9ydCB7IE1haWxBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvRW1haWwvTWFpbEFkYXB0ZXInO1xuaW1wb3J0IHsgUHViU3ViQWRhcHRlciB9IGZyb20gJy4uL0FkYXB0ZXJzL1B1YlN1Yi9QdWJTdWJBZGFwdGVyJztcbmltcG9ydCB7IFdTU0FkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9XZWJTb2NrZXRTZXJ2ZXIvV1NTQWRhcHRlcic7XG5cbi8vIEBmbG93XG50eXBlIEFkYXB0ZXI8VD4gPSBzdHJpbmcgfCBhbnkgfCBUO1xudHlwZSBOdW1iZXJPckJvb2xlYW4gPSBudW1iZXIgfCBib29sZWFuO1xudHlwZSBOdW1iZXJPclN0cmluZyA9IG51bWJlciB8IHN0cmluZztcbnR5cGUgUHJvdGVjdGVkRmllbGRzID0gYW55O1xuXG5leHBvcnQgaW50ZXJmYWNlIFBhcnNlU2VydmVyT3B0aW9ucyB7XG4gIC8qIFlvdXIgUGFyc2UgQXBwbGljYXRpb24gSURcbiAgOkVOVjogUEFSU0VfU0VSVkVSX0FQUExJQ0FUSU9OX0lEICovXG4gIGFwcElkOiBzdHJpbmc7XG4gIC8qIFlvdXIgUGFyc2UgTWFzdGVyIEtleSAqL1xuICBtYXN0ZXJLZXk6IHN0cmluZztcbiAgLyogVVJMIHRvIHlvdXIgcGFyc2Ugc2VydmVyIHdpdGggaHR0cDovLyBvciBodHRwczovLy5cbiAgOkVOVjogUEFSU0VfU0VSVkVSX1VSTCAqL1xuICBzZXJ2ZXJVUkw6IHN0cmluZztcbiAgLyogUmVzdHJpY3QgbWFzdGVyS2V5IHRvIGJlIHVzZWQgYnkgb25seSB0aGVzZSBpcHMsIGRlZmF1bHRzIHRvIFtdIChhbGxvdyBhbGwgaXBzKVxuICA6REVGQVVMVDogW10gKi9cbiAgbWFzdGVyS2V5SXBzOiA/KHN0cmluZ1tdKTtcbiAgLyogU2V0cyB0aGUgYXBwIG5hbWUgKi9cbiAgYXBwTmFtZTogP3N0cmluZztcbiAgLyogQWRkIGhlYWRlcnMgdG8gQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycyAqL1xuICBhbGxvd0hlYWRlcnM6ID8oc3RyaW5nW10pO1xuICAvKiBTZXRzIHRoZSBvcmlnaW4gdG8gQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luICovXG4gIGFsbG93T3JpZ2luOiA/c3RyaW5nO1xuICAvKiBBZGFwdGVyIG1vZHVsZSBmb3IgdGhlIGFuYWx5dGljcyAqL1xuICBhbmFseXRpY3NBZGFwdGVyOiA/QWRhcHRlcjxBbmFseXRpY3NBZGFwdGVyPjtcbiAgLyogQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBmaWxlcyBzdWItc3lzdGVtICovXG4gIGZpbGVzQWRhcHRlcjogP0FkYXB0ZXI8RmlsZXNBZGFwdGVyPjtcbiAgLyogQ29uZmlndXJhdGlvbiBmb3IgcHVzaCwgYXMgc3RyaW5naWZpZWQgSlNPTi4gU2VlIGh0dHA6Ly9kb2NzLnBhcnNlcGxhdGZvcm0ub3JnL3BhcnNlLXNlcnZlci9ndWlkZS8jcHVzaC1ub3RpZmljYXRpb25zICovXG4gIHB1c2g6ID9hbnk7XG4gIC8qIENvbmZpZ3VyYXRpb24gZm9yIHB1c2ggc2NoZWR1bGluZywgZGVmYXVsdHMgdG8gZmFsc2UuXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICBzY2hlZHVsZWRQdXNoOiA/Ym9vbGVhbjtcbiAgLyogQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBsb2dnaW5nIHN1Yi1zeXN0ZW0gKi9cbiAgbG9nZ2VyQWRhcHRlcjogP0FkYXB0ZXI8TG9nZ2VyQWRhcHRlcj47XG4gIC8qIExvZyBhcyBzdHJ1Y3R1cmVkIEpTT04gb2JqZWN0c1xuICA6RU5WOiBKU09OX0xPR1MgKi9cbiAganNvbkxvZ3M6ID9ib29sZWFuO1xuICAvKiBGb2xkZXIgZm9yIHRoZSBsb2dzIChkZWZhdWx0cyB0byAnLi9sb2dzJyk7IHNldCB0byBudWxsIHRvIGRpc2FibGUgZmlsZSBiYXNlZCBsb2dnaW5nXG4gIDpFTlY6IFBBUlNFX1NFUlZFUl9MT0dTX0ZPTERFUlxuICA6REVGQVVMVDogLi9sb2dzICovXG4gIGxvZ3NGb2xkZXI6ID9zdHJpbmc7XG4gIC8qIFNldCB0aGUgbG9nZ2luZyB0byB2ZXJib3NlXG4gIDpFTlY6IFZFUkJPU0UgKi9cbiAgdmVyYm9zZTogP2Jvb2xlYW47XG4gIC8qIFNldHMgdGhlIGxldmVsIGZvciBsb2dzICovXG4gIGxvZ0xldmVsOiA/c3RyaW5nO1xuICAvKiBNYXhpbXVtIG51bWJlciBvZiBsb2dzIHRvIGtlZXAuIElmIG5vdCBzZXQsIG5vIGxvZ3Mgd2lsbCBiZSByZW1vdmVkLiBUaGlzIGNhbiBiZSBhIG51bWJlciBvZiBmaWxlcyBvciBudW1iZXIgb2YgZGF5cy4gSWYgdXNpbmcgZGF5cywgYWRkICdkJyBhcyB0aGUgc3VmZml4LiAoZGVmYXVsdDogbnVsbCkgKi9cbiAgbWF4TG9nRmlsZXM6ID9OdW1iZXJPclN0cmluZztcbiAgLyogRGlzYWJsZXMgY29uc29sZSBvdXRwdXRcbiAgOkVOVjogU0lMRU5UICovXG4gIHNpbGVudDogP2Jvb2xlYW47XG4gIC8qIFRoZSBmdWxsIFVSSSB0byB5b3VyIGRhdGFiYXNlLiBTdXBwb3J0ZWQgZGF0YWJhc2VzIGFyZSBtb25nb2RiIG9yIHBvc3RncmVzLlxuICA6REVGQVVMVDogbW9uZ29kYjovL2xvY2FsaG9zdDoyNzAxNy9wYXJzZSAqL1xuICBkYXRhYmFzZVVSSTogc3RyaW5nO1xuICAvKiBPcHRpb25zIHRvIHBhc3MgdG8gdGhlIG1vbmdvZGIgY2xpZW50ICovXG4gIGRhdGFiYXNlT3B0aW9uczogP2FueTtcbiAgLyogQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBkYXRhYmFzZSAqL1xuICBkYXRhYmFzZUFkYXB0ZXI6ID9BZGFwdGVyPFN0b3JhZ2VBZGFwdGVyPjtcbiAgLyogRnVsbCBwYXRoIHRvIHlvdXIgY2xvdWQgY29kZSBtYWluLmpzICovXG4gIGNsb3VkOiA/c3RyaW5nO1xuICAvKiBBIGNvbGxlY3Rpb24gcHJlZml4IGZvciB0aGUgY2xhc3Nlc1xuICA6REVGQVVMVDogJycgKi9cbiAgY29sbGVjdGlvblByZWZpeDogP3N0cmluZztcbiAgLyogS2V5IGZvciBpT1MsIE1hY09TLCB0dk9TIGNsaWVudHMgKi9cbiAgY2xpZW50S2V5OiA/c3RyaW5nO1xuICAvKiBLZXkgZm9yIHRoZSBKYXZhc2NyaXB0IFNESyAqL1xuICBqYXZhc2NyaXB0S2V5OiA/c3RyaW5nO1xuICAvKiBLZXkgZm9yIFVuaXR5IGFuZCAuTmV0IFNESyAqL1xuICBkb3ROZXRLZXk6ID9zdHJpbmc7XG4gIC8qIEtleSBmb3IgZW5jcnlwdGluZyB5b3VyIGZpbGVzXG4gIDpFTlY6IFBBUlNFX1NFUlZFUl9FTkNSWVBUSU9OX0tFWSAqL1xuICBlbmNyeXB0aW9uS2V5OiA/c3RyaW5nO1xuICAvKiBLZXkgZm9yIFJFU1QgY2FsbHNcbiAgOkVOVjogUEFSU0VfU0VSVkVSX1JFU1RfQVBJX0tFWSAqL1xuICByZXN0QVBJS2V5OiA/c3RyaW5nO1xuICAvKiBSZWFkLW9ubHkga2V5LCB3aGljaCBoYXMgdGhlIHNhbWUgY2FwYWJpbGl0aWVzIGFzIE1hc3RlcktleSB3aXRob3V0IHdyaXRlcyAqL1xuICByZWFkT25seU1hc3RlcktleTogP3N0cmluZztcbiAgLyogS2V5IHNlbnQgd2l0aCBvdXRnb2luZyB3ZWJob29rIGNhbGxzICovXG4gIHdlYmhvb2tLZXk6ID9zdHJpbmc7XG4gIC8qIEtleSBmb3IgeW91ciBmaWxlcyAqL1xuICBmaWxlS2V5OiA/c3RyaW5nO1xuICAvKiBFbmFibGUgKG9yIGRpc2FibGUpIHRoZSBhZGRpdGlvbiBvZiBhIHVuaXF1ZSBoYXNoIHRvIHRoZSBmaWxlIG5hbWVzXG4gIDpFTlY6IFBBUlNFX1NFUlZFUl9QUkVTRVJWRV9GSUxFX05BTUVcbiAgOkRFRkFVTFQ6IGZhbHNlICovXG4gIHByZXNlcnZlRmlsZU5hbWU6ID9ib29sZWFuO1xuICAvKiBQZXJzb25hbGx5IGlkZW50aWZpYWJsZSBpbmZvcm1hdGlvbiBmaWVsZHMgaW4gdGhlIHVzZXIgdGFibGUgdGhlIHNob3VsZCBiZSByZW1vdmVkIGZvciBub24tYXV0aG9yaXplZCB1c2Vycy4gRGVwcmVjYXRlZCBAc2VlIHByb3RlY3RlZEZpZWxkcyAqL1xuICB1c2VyU2Vuc2l0aXZlRmllbGRzOiA/KHN0cmluZ1tdKTtcbiAgLyogUHJvdGVjdGVkIGZpZWxkcyB0aGF0IHNob3VsZCBiZSB0cmVhdGVkIHdpdGggZXh0cmEgc2VjdXJpdHkgd2hlbiBmZXRjaGluZyBkZXRhaWxzLlxuICA6REVGQVVMVDoge1wiX1VzZXJcIjoge1wiKlwiOiBbXCJlbWFpbFwiXX19ICovXG4gIHByb3RlY3RlZEZpZWxkczogP1Byb3RlY3RlZEZpZWxkcztcbiAgLyogRW5hYmxlIChvciBkaXNhYmxlKSBhbm9ueW1vdXMgdXNlcnMsIGRlZmF1bHRzIHRvIHRydWVcbiAgOkVOVjogUEFSU0VfU0VSVkVSX0VOQUJMRV9BTk9OX1VTRVJTXG4gIDpERUZBVUxUOiB0cnVlICovXG4gIGVuYWJsZUFub255bW91c1VzZXJzOiA/Ym9vbGVhbjtcbiAgLyogRW5hYmxlIChvciBkaXNhYmxlKSBjbGllbnQgY2xhc3MgY3JlYXRpb24sIGRlZmF1bHRzIHRvIHRydWVcbiAgOkVOVjogUEFSU0VfU0VSVkVSX0FMTE9XX0NMSUVOVF9DTEFTU19DUkVBVElPTlxuICA6REVGQVVMVDogdHJ1ZSAqL1xuICBhbGxvd0NsaWVudENsYXNzQ3JlYXRpb246ID9ib29sZWFuO1xuICAvKiBFbmFibGUgKG9yIGRpc2FibGUpIGN1c3RvbSBvYmplY3RJZFxuICA6RU5WOiBQQVJTRV9TRVJWRVJfQUxMT1dfQ1VTVE9NX09CSkVDVF9JRFxuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgYWxsb3dDdXN0b21PYmplY3RJZDogP2Jvb2xlYW47XG4gIC8qIENvbmZpZ3VyYXRpb24gZm9yIHlvdXIgYXV0aGVudGljYXRpb24gcHJvdmlkZXJzLCBhcyBzdHJpbmdpZmllZCBKU09OLiBTZWUgaHR0cDovL2RvY3MucGFyc2VwbGF0Zm9ybS5vcmcvcGFyc2Utc2VydmVyL2d1aWRlLyNvYXV0aC1hbmQtM3JkLXBhcnR5LWF1dGhlbnRpY2F0aW9uXG4gIDpFTlY6IFBBUlNFX1NFUlZFUl9BVVRIX1BST1ZJREVSUyAqL1xuICBhdXRoOiA/YW55O1xuICAvKiBNYXggZmlsZSBzaXplIGZvciB1cGxvYWRzLCBkZWZhdWx0cyB0byAyMG1iXG4gIDpERUZBVUxUOiAyMG1iICovXG4gIG1heFVwbG9hZFNpemU6ID9zdHJpbmc7XG4gIC8qIEVuYWJsZSAob3IgZGlzYWJsZSkgdXNlciBlbWFpbCB2YWxpZGF0aW9uLCBkZWZhdWx0cyB0byBmYWxzZVxuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgdmVyaWZ5VXNlckVtYWlsczogP2Jvb2xlYW47XG4gIC8qIFByZXZlbnQgdXNlciBmcm9tIGxvZ2luIGlmIGVtYWlsIGlzIG5vdCB2ZXJpZmllZCBhbmQgUEFSU0VfU0VSVkVSX1ZFUklGWV9VU0VSX0VNQUlMUyBpcyB0cnVlLCBkZWZhdWx0cyB0byBmYWxzZVxuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgcHJldmVudExvZ2luV2l0aFVudmVyaWZpZWRFbWFpbDogP2Jvb2xlYW47XG4gIC8qIEVtYWlsIHZlcmlmaWNhdGlvbiB0b2tlbiB2YWxpZGl0eSBkdXJhdGlvbiwgaW4gc2Vjb25kcyAqL1xuICBlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbjogP251bWJlcjtcbiAgLyogYW4gZXhpc3RpbmcgZW1haWwgdmVyaWZ5IHRva2VuIHNob3VsZCBiZSByZXVzZWQgd2hlbiByZXNlbmQgdmVyaWZpY2F0aW9uIGVtYWlsIGlzIHJlcXVlc3RlZFxuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZDogP2Jvb2xlYW47XG4gIC8qIGFjY291bnQgbG9ja291dCBwb2xpY3kgZm9yIGZhaWxlZCBsb2dpbiBhdHRlbXB0cyAqL1xuICBhY2NvdW50TG9ja291dDogP0FjY291bnRMb2Nrb3V0T3B0aW9ucztcbiAgLyogUGFzc3dvcmQgcG9saWN5IGZvciBlbmZvcmNpbmcgcGFzc3dvcmQgcmVsYXRlZCBydWxlcyAqL1xuICBwYXNzd29yZFBvbGljeTogP1Bhc3N3b3JkUG9saWN5T3B0aW9ucztcbiAgLyogQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBjYWNoZSAqL1xuICBjYWNoZUFkYXB0ZXI6ID9BZGFwdGVyPENhY2hlQWRhcHRlcj47XG4gIC8qIEFkYXB0ZXIgbW9kdWxlIGZvciBlbWFpbCBzZW5kaW5nICovXG4gIGVtYWlsQWRhcHRlcjogP0FkYXB0ZXI8TWFpbEFkYXB0ZXI+O1xuICAvKiBQdWJsaWMgVVJMIHRvIHlvdXIgcGFyc2Ugc2VydmVyIHdpdGggaHR0cDovLyBvciBodHRwczovLy5cbiAgOkVOVjogUEFSU0VfUFVCTElDX1NFUlZFUl9VUkwgKi9cbiAgcHVibGljU2VydmVyVVJMOiA/c3RyaW5nO1xuICAvKiBUaGUgb3B0aW9ucyBmb3IgcGFnZXMgc3VjaCBhcyBwYXNzd29yZCByZXNldCBhbmQgZW1haWwgdmVyaWZpY2F0aW9uLiBDYXV0aW9uLCB0aGlzIGlzIGFuIGV4cGVyaW1lbnRhbCBmZWF0dXJlIHRoYXQgbWF5IG5vdCBiZSBhcHByb3ByaWF0ZSBmb3IgcHJvZHVjdGlvbi5cbiAgOkRFRkFVTFQ6IHt9ICovXG4gIHBhZ2VzOiA/UGFnZXNPcHRpb25zO1xuICAvKiBjdXN0b20gcGFnZXMgZm9yIHBhc3N3b3JkIHZhbGlkYXRpb24gYW5kIHJlc2V0XG4gIDpERUZBVUxUOiB7fSAqL1xuICBjdXN0b21QYWdlczogP0N1c3RvbVBhZ2VzT3B0aW9ucztcbiAgLyogcGFyc2Utc2VydmVyJ3MgTGl2ZVF1ZXJ5IGNvbmZpZ3VyYXRpb24gb2JqZWN0ICovXG4gIGxpdmVRdWVyeTogP0xpdmVRdWVyeU9wdGlvbnM7XG4gIC8qIFNlc3Npb24gZHVyYXRpb24sIGluIHNlY29uZHMsIGRlZmF1bHRzIHRvIDEgeWVhclxuICA6REVGQVVMVDogMzE1MzYwMDAgKi9cbiAgc2Vzc2lvbkxlbmd0aDogP251bWJlcjtcbiAgLyogTWF4IHZhbHVlIGZvciBsaW1pdCBvcHRpb24gb24gcXVlcmllcywgZGVmYXVsdHMgdG8gdW5saW1pdGVkICovXG4gIG1heExpbWl0OiA/bnVtYmVyO1xuICAvKiBTZXRzIHdldGhlciB3ZSBzaG91bGQgZXhwaXJlIHRoZSBpbmFjdGl2ZSBzZXNzaW9ucywgZGVmYXVsdHMgdG8gdHJ1ZVxuICA6REVGQVVMVDogdHJ1ZSAqL1xuICBleHBpcmVJbmFjdGl2ZVNlc3Npb25zOiA/Ym9vbGVhbjtcbiAgLyogV2hlbiBhIHVzZXIgY2hhbmdlcyB0aGVpciBwYXNzd29yZCwgZWl0aGVyIHRocm91Z2ggdGhlIHJlc2V0IHBhc3N3b3JkIGVtYWlsIG9yIHdoaWxlIGxvZ2dlZCBpbiwgYWxsIHNlc3Npb25zIGFyZSByZXZva2VkIGlmIHRoaXMgaXMgdHJ1ZS4gU2V0IHRvIGZhbHNlIGlmIHlvdSBkb24ndCB3YW50IHRvIHJldm9rZSBzZXNzaW9ucy5cbiAgOkRFRkFVTFQ6IHRydWUgKi9cbiAgcmV2b2tlU2Vzc2lvbk9uUGFzc3dvcmRSZXNldDogP2Jvb2xlYW47XG4gIC8qIFRoZSBUVEwgZm9yIGNhY2hpbmcgdGhlIHNjaGVtYSBmb3Igb3B0aW1pemluZyByZWFkL3dyaXRlIG9wZXJhdGlvbnMuIFlvdSBzaG91bGQgcHV0IGEgbG9uZyBUVEwgd2hlbiB5b3VyIERCIGlzIGluIHByb2R1Y3Rpb24uIGRlZmF1bHQgdG8gNTAwMDsgc2V0IDAgdG8gZGlzYWJsZS5cbiAgOkRFRkFVTFQ6IDUwMDAgKi9cbiAgc2NoZW1hQ2FjaGVUVEw6ID9udW1iZXI7XG4gIC8qIFNldHMgdGhlIFRUTCBmb3IgdGhlIGluIG1lbW9yeSBjYWNoZSAoaW4gbXMpLCBkZWZhdWx0cyB0byA1MDAwICg1IHNlY29uZHMpXG4gIDpERUZBVUxUOiA1MDAwICovXG4gIGNhY2hlVFRMOiA/bnVtYmVyO1xuICAvKiBTZXRzIHRoZSBtYXhpbXVtIHNpemUgZm9yIHRoZSBpbiBtZW1vcnkgY2FjaGUsIGRlZmF1bHRzIHRvIDEwMDAwXG4gIDpERUZBVUxUOiAxMDAwMCAqL1xuICBjYWNoZU1heFNpemU6ID9udW1iZXI7XG4gIC8qIFJlcGxhY2UgSFRUUCBJbnRlcmZhY2Ugd2hlbiB1c2luZyBKUyBTREsgaW4gY3VycmVudCBub2RlIHJ1bnRpbWUsIGRlZmF1bHRzIHRvIGZhbHNlLiBDYXV0aW9uLCB0aGlzIGlzIGFuIGV4cGVyaW1lbnRhbCBmZWF0dXJlIHRoYXQgbWF5IG5vdCBiZSBhcHByb3ByaWF0ZSBmb3IgcHJvZHVjdGlvbi5cbiAgOkVOVjogUEFSU0VfU0VSVkVSX0VOQUJMRV9FWFBFUklNRU5UQUxfRElSRUNUX0FDQ0VTU1xuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgZGlyZWN0QWNjZXNzOiA/Ym9vbGVhbjtcbiAgLyogVXNlIGEgc2luZ2xlIHNjaGVtYSBjYWNoZSBzaGFyZWQgYWNyb3NzIHJlcXVlc3RzLiBSZWR1Y2VzIG51bWJlciBvZiBxdWVyaWVzIG1hZGUgdG8gX1NDSEVNQSwgZGVmYXVsdHMgdG8gZmFsc2UsIGkuZS4gdW5pcXVlIHNjaGVtYSBjYWNoZSBwZXIgcmVxdWVzdC5cbiAgOkRFRkFVTFQ6IGZhbHNlICovXG4gIGVuYWJsZVNpbmdsZVNjaGVtYUNhY2hlOiA/Ym9vbGVhbjtcbiAgLyogRW5hYmxlcyB0aGUgZGVmYXVsdCBleHByZXNzIGVycm9yIGhhbmRsZXIgZm9yIGFsbCBlcnJvcnNcbiAgOkRFRkFVTFQ6IGZhbHNlICovXG4gIGVuYWJsZUV4cHJlc3NFcnJvckhhbmRsZXI6ID9ib29sZWFuO1xuICAvKiBTZXRzIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyBpbiBnZW5lcmF0ZWQgb2JqZWN0IGlkJ3MsIGRlZmF1bHQgMTBcbiAgOkRFRkFVTFQ6IDEwICovXG4gIG9iamVjdElkU2l6ZTogP251bWJlcjtcbiAgLyogVGhlIHBvcnQgdG8gcnVuIHRoZSBQYXJzZVNlcnZlciwgZGVmYXVsdHMgdG8gMTMzNy5cbiAgOkVOVjogUE9SVFxuICA6REVGQVVMVDogMTMzNyAqL1xuICBwb3J0OiA/bnVtYmVyO1xuICAvKiBUaGUgaG9zdCB0byBzZXJ2ZSBQYXJzZVNlcnZlciBvbiwgZGVmYXVsdHMgdG8gMC4wLjAuMFxuICA6REVGQVVMVDogMC4wLjAuMCAqL1xuICBob3N0OiA/c3RyaW5nO1xuICAvKiBNb3VudCBwYXRoIGZvciB0aGUgc2VydmVyLCBkZWZhdWx0cyB0byAvcGFyc2VcbiAgOkRFRkFVTFQ6IC9wYXJzZSAqL1xuICBtb3VudFBhdGg6ID9zdHJpbmc7XG4gIC8qIFJ1biB3aXRoIGNsdXN0ZXIsIG9wdGlvbmFsbHkgc2V0IHRoZSBudW1iZXIgb2YgcHJvY2Vzc2VzIGRlZmF1bHQgdG8gb3MuY3B1cygpLmxlbmd0aCAqL1xuICBjbHVzdGVyOiA/TnVtYmVyT3JCb29sZWFuO1xuICAvKiBtaWRkbGV3YXJlIGZvciBleHByZXNzIHNlcnZlciwgY2FuIGJlIHN0cmluZyBvciBmdW5jdGlvbiAqL1xuICBtaWRkbGV3YXJlOiA/KCgoKSA9PiB2b2lkKSB8IHN0cmluZyk7XG4gIC8qIFN0YXJ0cyB0aGUgbGl2ZVF1ZXJ5IHNlcnZlciAqL1xuICBzdGFydExpdmVRdWVyeVNlcnZlcjogP2Jvb2xlYW47XG4gIC8qIExpdmUgcXVlcnkgc2VydmVyIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyAod2lsbCBzdGFydCB0aGUgbGl2ZVF1ZXJ5IHNlcnZlcikgKi9cbiAgbGl2ZVF1ZXJ5U2VydmVyT3B0aW9uczogP0xpdmVRdWVyeVNlcnZlck9wdGlvbnM7XG4gIC8qIE9wdGlvbnMgZm9yIHJlcXVlc3QgaWRlbXBvdGVuY3kgdG8gZGVkdXBsaWNhdGUgaWRlbnRpY2FsIHJlcXVlc3RzIHRoYXQgbWF5IGJlIGNhdXNlZCBieSBuZXR3b3JrIGlzc3Vlcy4gQ2F1dGlvbiwgdGhpcyBpcyBhbiBleHBlcmltZW50YWwgZmVhdHVyZSB0aGF0IG1heSBub3QgYmUgYXBwcm9wcmlhdGUgZm9yIHByb2R1Y3Rpb24uXG4gIDpFTlY6IFBBUlNFX1NFUlZFUl9FWFBFUklNRU5UQUxfSURFTVBPVEVOQ1lfT1BUSU9OU1xuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgaWRlbXBvdGVuY3lPcHRpb25zOiA/SWRlbXBvdGVuY3lPcHRpb25zO1xuICAvKiBPcHRpb25zIGZvciBmaWxlIHVwbG9hZHNcbiAgOkVOVjogUEFSU0VfU0VSVkVSX0ZJTEVfVVBMT0FEX09QVElPTlNcbiAgOkRFRkFVTFQ6IHt9ICovXG4gIGZpbGVVcGxvYWQ6ID9GaWxlVXBsb2FkT3B0aW9ucztcbiAgLyogRnVsbCBwYXRoIHRvIHlvdXIgR3JhcGhRTCBjdXN0b20gc2NoZW1hLmdyYXBocWwgZmlsZSAqL1xuICBncmFwaFFMU2NoZW1hOiA/c3RyaW5nO1xuICAvKiBNb3VudHMgdGhlIEdyYXBoUUwgZW5kcG9pbnRcbiAgOkVOVjogUEFSU0VfU0VSVkVSX01PVU5UX0dSQVBIUUxcbiAgOkRFRkFVTFQ6IGZhbHNlICovXG4gIG1vdW50R3JhcGhRTDogP2Jvb2xlYW47XG4gIC8qIE1vdW50IHBhdGggZm9yIHRoZSBHcmFwaFFMIGVuZHBvaW50LCBkZWZhdWx0cyB0byAvZ3JhcGhxbFxuICA6RU5WOiBQQVJTRV9TRVJWRVJfR1JBUEhRTF9QQVRIXG4gIDpERUZBVUxUOiAvZ3JhcGhxbCAqL1xuICBncmFwaFFMUGF0aDogP3N0cmluZztcbiAgLyogTW91bnRzIHRoZSBHcmFwaFFMIFBsYXlncm91bmQgLSBuZXZlciB1c2UgdGhpcyBvcHRpb24gaW4gcHJvZHVjdGlvblxuICA6RU5WOiBQQVJTRV9TRVJWRVJfTU9VTlRfUExBWUdST1VORFxuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgbW91bnRQbGF5Z3JvdW5kOiA/Ym9vbGVhbjtcbiAgLyogTW91bnQgcGF0aCBmb3IgdGhlIEdyYXBoUUwgUGxheWdyb3VuZCwgZGVmYXVsdHMgdG8gL3BsYXlncm91bmRcbiAgOkVOVjogUEFSU0VfU0VSVkVSX1BMQVlHUk9VTkRfUEFUSFxuICA6REVGQVVMVDogL3BsYXlncm91bmQgKi9cbiAgcGxheWdyb3VuZFBhdGg6ID9zdHJpbmc7XG4gIC8qIENhbGxiYWNrIHdoZW4gc2VydmVyIGhhcyBzdGFydGVkICovXG4gIHNlcnZlclN0YXJ0Q29tcGxldGU6ID8oZXJyb3I6ID9FcnJvcikgPT4gdm9pZDtcbiAgLyogQ2FsbGJhY2sgd2hlbiBzZXJ2ZXIgaGFzIGNsb3NlZCAqL1xuICBzZXJ2ZXJDbG9zZUNvbXBsZXRlOiA/KCkgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQYWdlc09wdGlvbnMge1xuICAvKiBJcyB0cnVlIGlmIHRoZSBwYWdlcyByb3V0ZXIgc2hvdWxkIGJlIGVuYWJsZWQ7IHRoaXMgaXMgcmVxdWlyZWQgZm9yIGFueSBvZiB0aGUgcGFnZXMgb3B0aW9ucyB0byB0YWtlIGVmZmVjdC4gQ2F1dGlvbiwgdGhpcyBpcyBhbiBleHBlcmltZW50YWwgZmVhdHVyZSB0aGF0IG1heSBub3QgYmUgYXBwcm9wcmlhdGUgZm9yIHByb2R1Y3Rpb24uXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICBlbmFibGVSb3V0ZXI6ID9ib29sZWFuO1xuICAvKiBJcyB0cnVlIGlmIHBhZ2VzIHNob3VsZCBiZSBsb2NhbGl6ZWQ7IHRoaXMgaGFzIG5vIGVmZmVjdCBvbiBjdXN0b20gcGFnZSByZWRpcmVjdHMuXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICBlbmFibGVMb2NhbGl6YXRpb246ID9ib29sZWFuO1xuICAvKiBUaGUgcGF0aCB0byB0aGUgSlNPTiBmaWxlIGZvciBsb2NhbGl6YXRpb247IHRoZSB0cmFuc2xhdGlvbnMgd2lsbCBiZSB1c2VkIHRvIGZpbGwgdGVtcGxhdGUgcGxhY2Vob2xkZXJzIGFjY29yZGluZyB0byB0aGUgbG9jYWxlLiAqL1xuICBsb2NhbGl6YXRpb25Kc29uUGF0aDogP3N0cmluZztcbiAgLyogVGhlIGZhbGxiYWNrIGxvY2FsZSBmb3IgbG9jYWxpemF0aW9uIGlmIG5vIG1hdGNoaW5nIHRyYW5zbGF0aW9uIGlzIHByb3ZpZGVkIGZvciB0aGUgZ2l2ZW4gbG9jYWxlLiBUaGlzIGlzIG9ubHkgcmVsZXZhbnQgd2hlbiBwcm92aWRpbmcgdHJhbnNsYXRpb24gcmVzb3VyY2VzIHZpYSBKU09OIGZpbGUuXG4gIDpERUZBVUxUOiBlbiAqL1xuICBsb2NhbGl6YXRpb25GYWxsYmFja0xvY2FsZTogP3N0cmluZztcbiAgLyogVGhlIHBsYWNlaG9sZGVyIGtleXMgYW5kIHZhbHVlcyB3aGljaCB3aWxsIGJlIGZpbGxlZCBpbiBwYWdlczsgdGhpcyBjYW4gYmUgYSBzaW1wbGUgb2JqZWN0IG9yIGEgY2FsbGJhY2sgZnVuY3Rpb24uXG4gIDpERUZBVUxUOiB7fSAqL1xuICBwbGFjZWhvbGRlcnM6ID9PYmplY3Q7XG4gIC8qIElzIHRydWUgaWYgcmVzcG9uc2VzIHNob3VsZCBhbHdheXMgYmUgcmVkaXJlY3RzIGFuZCBuZXZlciBjb250ZW50LCBmYWxzZSBpZiB0aGUgcmVzcG9uc2UgdHlwZSBzaG91bGQgZGVwZW5kIG9uIHRoZSByZXF1ZXN0IHR5cGUgKEdFVCByZXF1ZXN0IC0+IGNvbnRlbnQgcmVzcG9uc2U7IFBPU1QgcmVxdWVzdCAtPiByZWRpcmVjdCByZXNwb25zZSkuXG4gIDpERUZBVUxUOiBmYWxzZSAqL1xuICBmb3JjZVJlZGlyZWN0OiA/Ym9vbGVhbjtcbiAgLyogVGhlIHBhdGggdG8gdGhlIHBhZ2VzIGRpcmVjdG9yeTsgdGhpcyBhbHNvIGRlZmluZXMgd2hlcmUgdGhlIHN0YXRpYyBlbmRwb2ludCAnL2FwcHMnIHBvaW50cyB0by4gRGVmYXVsdCBpcyB0aGUgJy4vcHVibGljLycgZGlyZWN0b3J5LlxuICA6REVGQVVMVDogLi9wdWJsaWMgKi9cbiAgcGFnZXNQYXRoOiA/c3RyaW5nO1xuICAvKiBUaGUgQVBJIGVuZHBvaW50IGZvciB0aGUgcGFnZXMuIERlZmF1bHQgaXMgJ2FwcHMnLlxuICA6REVGQVVMVDogYXBwcyAqL1xuICBwYWdlc0VuZHBvaW50OiA/c3RyaW5nO1xuICAvKiBUaGUgVVJMcyB0byB0aGUgY3VzdG9tIHBhZ2VzLlxuICA6REVGQVVMVDoge30gKi9cbiAgY3VzdG9tVXJsczogP1BhZ2VzQ3VzdG9tVXJsc09wdGlvbnM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGFnZXNDdXN0b21VcmxzT3B0aW9ucyB7XG4gIC8qIFRoZSBVUkwgdG8gdGhlIGN1c3RvbSBwYWdlIGZvciBwYXNzd29yZCByZXNldC4gKi9cbiAgcGFzc3dvcmRSZXNldDogP3N0cmluZztcbiAgLyogVGhlIFVSTCB0byB0aGUgY3VzdG9tIHBhZ2UgZm9yIHBhc3N3b3JkIHJlc2V0IC0+IGxpbmsgaW52YWxpZC4gKi9cbiAgcGFzc3dvcmRSZXNldExpbmtJbnZhbGlkOiA/c3RyaW5nO1xuICAvKiBUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgcGFzc3dvcmQgcmVzZXQgLT4gc3VjY2Vzcy4gKi9cbiAgcGFzc3dvcmRSZXNldFN1Y2Nlc3M6ID9zdHJpbmc7XG4gIC8qIFRoZSBVUkwgdG8gdGhlIGN1c3RvbSBwYWdlIGZvciBlbWFpbCB2ZXJpZmljYXRpb24gLT4gc3VjY2Vzcy4gKi9cbiAgZW1haWxWZXJpZmljYXRpb25TdWNjZXNzOiA/c3RyaW5nO1xuICAvKiBUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgZW1haWwgdmVyaWZpY2F0aW9uIC0+IGxpbmsgc2VuZCBmYWlsLiAqL1xuICBlbWFpbFZlcmlmaWNhdGlvblNlbmRGYWlsOiA/c3RyaW5nO1xuICAvKiBUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgZW1haWwgdmVyaWZpY2F0aW9uIC0+IHJlc2VuZCBsaW5rIC0+IHN1Y2Nlc3MuICovXG4gIGVtYWlsVmVyaWZpY2F0aW9uU2VuZFN1Y2Nlc3M6ID9zdHJpbmc7XG4gIC8qIFRoZSBVUkwgdG8gdGhlIGN1c3RvbSBwYWdlIGZvciBlbWFpbCB2ZXJpZmljYXRpb24gLT4gbGluayBpbnZhbGlkLiAqL1xuICBlbWFpbFZlcmlmaWNhdGlvbkxpbmtJbnZhbGlkOiA/c3RyaW5nO1xuICAvKiBUaGUgVVJMIHRvIHRoZSBjdXN0b20gcGFnZSBmb3IgZW1haWwgdmVyaWZpY2F0aW9uIC0+IGxpbmsgZXhwaXJlZC4gKi9cbiAgZW1haWxWZXJpZmljYXRpb25MaW5rRXhwaXJlZDogP3N0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDdXN0b21QYWdlc09wdGlvbnMge1xuICAvKiBpbnZhbGlkIGxpbmsgcGFnZSBwYXRoICovXG4gIGludmFsaWRMaW5rOiA/c3RyaW5nO1xuICAvKiB2ZXJpZmljYXRpb24gbGluayBzZW5kIGZhaWwgcGFnZSBwYXRoICovXG4gIGxpbmtTZW5kRmFpbDogP3N0cmluZztcbiAgLyogY2hvb3NlIHBhc3N3b3JkIHBhZ2UgcGF0aCAqL1xuICBjaG9vc2VQYXNzd29yZDogP3N0cmluZztcbiAgLyogdmVyaWZpY2F0aW9uIGxpbmsgc2VuZCBzdWNjZXNzIHBhZ2UgcGF0aCAqL1xuICBsaW5rU2VuZFN1Y2Nlc3M6ID9zdHJpbmc7XG4gIC8qIHZlcmlmeSBlbWFpbCBzdWNjZXNzIHBhZ2UgcGF0aCAqL1xuICB2ZXJpZnlFbWFpbFN1Y2Nlc3M6ID9zdHJpbmc7XG4gIC8qIHBhc3N3b3JkIHJlc2V0IHN1Y2Nlc3MgcGFnZSBwYXRoICovXG4gIHBhc3N3b3JkUmVzZXRTdWNjZXNzOiA/c3RyaW5nO1xuICAvKiBpbnZhbGlkIHZlcmlmaWNhdGlvbiBsaW5rIHBhZ2UgcGF0aCAqL1xuICBpbnZhbGlkVmVyaWZpY2F0aW9uTGluazogP3N0cmluZztcbiAgLyogZXhwaXJlZCB2ZXJpZmljYXRpb24gbGluayBwYWdlIHBhdGggKi9cbiAgZXhwaXJlZFZlcmlmaWNhdGlvbkxpbms6ID9zdHJpbmc7XG4gIC8qIGludmFsaWQgcGFzc3dvcmQgcmVzZXQgbGluayBwYWdlIHBhdGggKi9cbiAgaW52YWxpZFBhc3N3b3JkUmVzZXRMaW5rOiA/c3RyaW5nO1xuICAvKiBmb3IgbWFza2luZyB1c2VyLWZhY2luZyBwYWdlcyAqL1xuICBwYXJzZUZyYW1lVVJMOiA/c3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExpdmVRdWVyeU9wdGlvbnMge1xuICAvKiBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgY2xhc3NOYW1lc1xuICA6RU5WOiBQQVJTRV9TRVJWRVJfTElWRVFVRVJZX0NMQVNTTkFNRVMgKi9cbiAgY2xhc3NOYW1lczogPyhzdHJpbmdbXSk7XG4gIC8qIHBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSByZWRpc09wdGlvbnMgKi9cbiAgcmVkaXNPcHRpb25zOiA/YW55O1xuICAvKiBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgcmVkaXNVUkwgKi9cbiAgcmVkaXNVUkw6ID9zdHJpbmc7XG4gIC8qIExpdmVRdWVyeSBwdWJzdWIgYWRhcHRlciAqL1xuICBwdWJTdWJBZGFwdGVyOiA/QWRhcHRlcjxQdWJTdWJBZGFwdGVyPjtcbiAgLyogQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBXZWJTb2NrZXRTZXJ2ZXIgKi9cbiAgd3NzQWRhcHRlcjogP0FkYXB0ZXI8V1NTQWRhcHRlcj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucyB7XG4gIC8qIFRoaXMgc3RyaW5nIHNob3VsZCBtYXRjaCB0aGUgYXBwSWQgaW4gdXNlIGJ5IHlvdXIgUGFyc2UgU2VydmVyLiBJZiB5b3UgZGVwbG95IHRoZSBMaXZlUXVlcnkgc2VydmVyIGFsb25nc2lkZSBQYXJzZSBTZXJ2ZXIsIHRoZSBMaXZlUXVlcnkgc2VydmVyIHdpbGwgdHJ5IHRvIHVzZSB0aGUgc2FtZSBhcHBJZC4qL1xuICBhcHBJZDogP3N0cmluZztcbiAgLyogVGhpcyBzdHJpbmcgc2hvdWxkIG1hdGNoIHRoZSBtYXN0ZXJLZXkgaW4gdXNlIGJ5IHlvdXIgUGFyc2UgU2VydmVyLiBJZiB5b3UgZGVwbG95IHRoZSBMaXZlUXVlcnkgc2VydmVyIGFsb25nc2lkZSBQYXJzZSBTZXJ2ZXIsIHRoZSBMaXZlUXVlcnkgc2VydmVyIHdpbGwgdHJ5IHRvIHVzZSB0aGUgc2FtZSBtYXN0ZXJLZXkuKi9cbiAgbWFzdGVyS2V5OiA/c3RyaW5nO1xuICAvKiBUaGlzIHN0cmluZyBzaG91bGQgbWF0Y2ggdGhlIHNlcnZlclVSTCBpbiB1c2UgYnkgeW91ciBQYXJzZSBTZXJ2ZXIuIElmIHlvdSBkZXBsb3kgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgYWxvbmdzaWRlIFBhcnNlIFNlcnZlciwgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgd2lsbCB0cnkgdG8gdXNlIHRoZSBzYW1lIHNlcnZlclVSTC4qL1xuICBzZXJ2ZXJVUkw6ID9zdHJpbmc7XG4gIC8qIEEgSlNPTiBvYmplY3QgdGhhdCBzZXJ2ZXMgYXMgYSB3aGl0ZWxpc3Qgb2Yga2V5cy4gSXQgaXMgdXNlZCBmb3IgdmFsaWRhdGluZyBjbGllbnRzIHdoZW4gdGhleSB0cnkgdG8gY29ubmVjdCB0byB0aGUgTGl2ZVF1ZXJ5IHNlcnZlci4gQ2hlY2sgdGhlIGZvbGxvd2luZyBTZWN1cml0eSBzZWN0aW9uIGFuZCBvdXIgcHJvdG9jb2wgc3BlY2lmaWNhdGlvbiBmb3IgZGV0YWlscy4qL1xuICBrZXlQYWlyczogP2FueTtcbiAgLyogTnVtYmVyIG9mIG1pbGxpc2Vjb25kcyBiZXR3ZWVuIHBpbmcvcG9uZyBmcmFtZXMuIFRoZSBXZWJTb2NrZXQgc2VydmVyIHNlbmRzIHBpbmcvcG9uZyBmcmFtZXMgdG8gdGhlIGNsaWVudHMgdG8ga2VlcCB0aGUgV2ViU29ja2V0IGFsaXZlLiBUaGlzIHZhbHVlIGRlZmluZXMgdGhlIGludGVydmFsIG9mIHRoZSBwaW5nL3BvbmcgZnJhbWUgZnJvbSB0aGUgc2VydmVyIHRvIGNsaWVudHMsIGRlZmF1bHRzIHRvIDEwICogMTAwMCBtcyAoMTAgcykuKi9cbiAgd2Vic29ja2V0VGltZW91dDogP251bWJlcjtcbiAgLyogTnVtYmVyIGluIG1pbGxpc2Vjb25kcy4gV2hlbiBjbGllbnRzIHByb3ZpZGUgdGhlIHNlc3Npb25Ub2tlbiB0byB0aGUgTGl2ZVF1ZXJ5IHNlcnZlciwgdGhlIExpdmVRdWVyeSBzZXJ2ZXIgd2lsbCB0cnkgdG8gZmV0Y2ggaXRzIFBhcnNlVXNlcidzIG9iamVjdElkIGZyb20gcGFyc2Ugc2VydmVyIGFuZCBzdG9yZSBpdCBpbiB0aGUgY2FjaGUuIFRoZSB2YWx1ZSBkZWZpbmVzIHRoZSBkdXJhdGlvbiBvZiB0aGUgY2FjaGUuIENoZWNrIHRoZSBmb2xsb3dpbmcgU2VjdXJpdHkgc2VjdGlvbiBhbmQgb3VyIHByb3RvY29sIHNwZWNpZmljYXRpb24gZm9yIGRldGFpbHMsIGRlZmF1bHRzIHRvIDUgKiAxMDAwIG1zICg1IHNlY29uZHMpLiovXG4gIGNhY2hlVGltZW91dDogP251bWJlcjtcbiAgLyogVGhpcyBzdHJpbmcgZGVmaW5lcyB0aGUgbG9nIGxldmVsIG9mIHRoZSBMaXZlUXVlcnkgc2VydmVyLiBXZSBzdXBwb3J0IFZFUkJPU0UsIElORk8sIEVSUk9SLCBOT05FLCBkZWZhdWx0cyB0byBJTkZPLiovXG4gIGxvZ0xldmVsOiA/c3RyaW5nO1xuICAvKiBUaGUgcG9ydCB0byBydW4gdGhlIExpdmVRdWVyeSBzZXJ2ZXIsIGRlZmF1bHRzIHRvIDEzMzcuXG4gIDpERUZBVUxUOiAxMzM3ICovXG4gIHBvcnQ6ID9udW1iZXI7XG4gIC8qIHBhcnNlLXNlcnZlcidzIExpdmVRdWVyeSByZWRpc09wdGlvbnMgKi9cbiAgcmVkaXNPcHRpb25zOiA/YW55O1xuICAvKiBwYXJzZS1zZXJ2ZXIncyBMaXZlUXVlcnkgcmVkaXNVUkwgKi9cbiAgcmVkaXNVUkw6ID9zdHJpbmc7XG4gIC8qIExpdmVRdWVyeSBwdWJzdWIgYWRhcHRlciAqL1xuICBwdWJTdWJBZGFwdGVyOiA/QWRhcHRlcjxQdWJTdWJBZGFwdGVyPjtcbiAgLyogQWRhcHRlciBtb2R1bGUgZm9yIHRoZSBXZWJTb2NrZXRTZXJ2ZXIgKi9cbiAgd3NzQWRhcHRlcjogP0FkYXB0ZXI8V1NTQWRhcHRlcj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSWRlbXBvdGVuY3lPcHRpb25zIHtcbiAgLyogQW4gYXJyYXkgb2YgcGF0aHMgZm9yIHdoaWNoIHRoZSBmZWF0dXJlIHNob3VsZCBiZSBlbmFibGVkLiBUaGUgbW91bnQgcGF0aCBtdXN0IG5vdCBiZSBpbmNsdWRlZCwgZm9yIGV4YW1wbGUgaW5zdGVhZCBvZiBgL3BhcnNlL2Z1bmN0aW9ucy9teUZ1bmN0aW9uYCBzcGVjaWZpeSBgZnVuY3Rpb25zL215RnVuY3Rpb25gLiBUaGUgZW50cmllcyBhcmUgaW50ZXJwcmV0ZWQgYXMgcmVndWxhciBleHByZXNzaW9uLCBmb3IgZXhhbXBsZSBgZnVuY3Rpb25zLy4qYCBtYXRjaGVzIGFsbCBmdW5jdGlvbnMsIGBqb2JzLy4qYCBtYXRjaGVzIGFsbCBqb2JzLCBgY2xhc3Nlcy8uKmAgbWF0Y2hlcyBhbGwgY2xhc3NlcywgYC4qYCBtYXRjaGVzIGFsbCBwYXRocy5cbiAgOkRFRkFVTFQ6IFtdICovXG4gIHBhdGhzOiA/KHN0cmluZ1tdKTtcbiAgLyogVGhlIGR1cmF0aW9uIGluIHNlY29uZHMgYWZ0ZXIgd2hpY2ggYSByZXF1ZXN0IHJlY29yZCBpcyBkaXNjYXJkZWQgZnJvbSB0aGUgZGF0YWJhc2UsIGRlZmF1bHRzIHRvIDMwMHMuXG4gIDpERUZBVUxUOiAzMDAgKi9cbiAgdHRsOiA/bnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFjY291bnRMb2Nrb3V0T3B0aW9ucyB7XG4gIC8qIG51bWJlciBvZiBtaW51dGVzIHRoYXQgYSBsb2NrZWQtb3V0IGFjY291bnQgcmVtYWlucyBsb2NrZWQgb3V0IGJlZm9yZSBhdXRvbWF0aWNhbGx5IGJlY29taW5nIHVubG9ja2VkLiAqL1xuICBkdXJhdGlvbjogP251bWJlcjtcbiAgLyogbnVtYmVyIG9mIGZhaWxlZCBzaWduLWluIGF0dGVtcHRzIHRoYXQgd2lsbCBjYXVzZSBhIHVzZXIgYWNjb3VudCB0byBiZSBsb2NrZWQgKi9cbiAgdGhyZXNob2xkOiA/bnVtYmVyO1xuICAvKiBJcyB0cnVlIGlmIHRoZSBhY2NvdW50IGxvY2sgc2hvdWxkIGJlIHJlbW92ZWQgYWZ0ZXIgYSBzdWNjZXNzZnVsIHBhc3N3b3JkIHJlc2V0LlxuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgdW5sb2NrT25QYXNzd29yZFJlc2V0OiA/Ym9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQYXNzd29yZFBvbGljeU9wdGlvbnMge1xuICAvKiBhIFJlZ0V4cCBvYmplY3Qgb3IgYSByZWdleCBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBwYXR0ZXJuIHRvIGVuZm9yY2UgKi9cbiAgdmFsaWRhdG9yUGF0dGVybjogP3N0cmluZztcbiAgLyogYSBjYWxsYmFjayBmdW5jdGlvbiB0byBiZSBpbnZva2VkIHRvIHZhbGlkYXRlIHRoZSBwYXNzd29yZCAgKi9cbiAgdmFsaWRhdG9yQ2FsbGJhY2s6ID8oKSA9PiB2b2lkO1xuICAvKiBkaXNhbGxvdyB1c2VybmFtZSBpbiBwYXNzd29yZHMgKi9cbiAgZG9Ob3RBbGxvd1VzZXJuYW1lOiA/Ym9vbGVhbjtcbiAgLyogZGF5cyBmb3IgcGFzc3dvcmQgZXhwaXJ5ICovXG4gIG1heFBhc3N3b3JkQWdlOiA/bnVtYmVyO1xuICAvKiBzZXR0aW5nIHRvIHByZXZlbnQgcmV1c2Ugb2YgcHJldmlvdXMgbiBwYXNzd29yZHMgKi9cbiAgbWF4UGFzc3dvcmRIaXN0b3J5OiA/bnVtYmVyO1xuICAvKiB0aW1lIGZvciB0b2tlbiB0byBleHBpcmUgKi9cbiAgcmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb246ID9udW1iZXI7XG4gIC8qIHJlc2VuZCB0b2tlbiBpZiBpdCdzIHN0aWxsIHZhbGlkICovXG4gIHJlc2V0VG9rZW5SZXVzZUlmVmFsaWQ6ID9ib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEZpbGVVcGxvYWRPcHRpb25zIHtcbiAgLyogIElzIHRydWUgaWYgZmlsZSB1cGxvYWQgc2hvdWxkIGJlIGFsbG93ZWQgZm9yIGFub255bW91cyB1c2Vycy5cbiAgOkRFRkFVTFQ6IGZhbHNlICovXG4gIGVuYWJsZUZvckFub255bW91c1VzZXI6ID9ib29sZWFuO1xuICAvKiBJcyB0cnVlIGlmIGZpbGUgdXBsb2FkIHNob3VsZCBiZSBhbGxvd2VkIGZvciBhdXRoZW50aWNhdGVkIHVzZXJzLlxuICA6REVGQVVMVDogdHJ1ZSAqL1xuICBlbmFibGVGb3JBdXRoZW50aWNhdGVkVXNlcjogP2Jvb2xlYW47XG4gIC8qIElzIHRydWUgaWYgZmlsZSB1cGxvYWQgc2hvdWxkIGJlIGFsbG93ZWQgZm9yIGFueW9uZSwgcmVnYXJkbGVzcyBvZiB1c2VyIGF1dGhlbnRpY2F0aW9uLlxuICA6REVGQVVMVDogZmFsc2UgKi9cbiAgZW5hYmxlRm9yUHVibGljOiA/Ym9vbGVhbjtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Options/parsers.js b/lib/Options/parsers.js deleted file mode 100644 index d5bc65c7d4..0000000000 --- a/lib/Options/parsers.js +++ /dev/null @@ -1,90 +0,0 @@ -"use strict"; - -function numberParser(key) { - return function (opt) { - const intOpt = parseInt(opt); - - if (!Number.isInteger(intOpt)) { - throw new Error(`Key ${key} has invalid value ${opt}`); - } - - return intOpt; - }; -} - -function numberOrBoolParser(key) { - return function (opt) { - if (typeof opt === 'boolean') { - return opt; - } - - if (opt === 'true') { - return true; - } - - if (opt === 'false') { - return false; - } - - return numberParser(key)(opt); - }; -} - -function objectParser(opt) { - if (typeof opt == 'object') { - return opt; - } - - return JSON.parse(opt); -} - -function arrayParser(opt) { - if (Array.isArray(opt)) { - return opt; - } else if (typeof opt === 'string') { - return opt.split(','); - } else { - throw new Error(`${opt} should be a comma separated string or an array`); - } -} - -function moduleOrObjectParser(opt) { - if (typeof opt == 'object') { - return opt; - } - - try { - return JSON.parse(opt); - } catch (e) { - /* */ - } - - return opt; -} - -function booleanParser(opt) { - if (opt == true || opt == 'true' || opt == '1') { - return true; - } - - return false; -} - -function nullParser(opt) { - if (opt == 'null') { - return null; - } - - return opt; -} - -module.exports = { - numberParser, - numberOrBoolParser, - nullParser, - booleanParser, - moduleOrObjectParser, - arrayParser, - objectParser -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9PcHRpb25zL3BhcnNlcnMuanMiXSwibmFtZXMiOlsibnVtYmVyUGFyc2VyIiwia2V5Iiwib3B0IiwiaW50T3B0IiwicGFyc2VJbnQiLCJOdW1iZXIiLCJpc0ludGVnZXIiLCJFcnJvciIsIm51bWJlck9yQm9vbFBhcnNlciIsIm9iamVjdFBhcnNlciIsIkpTT04iLCJwYXJzZSIsImFycmF5UGFyc2VyIiwiQXJyYXkiLCJpc0FycmF5Iiwic3BsaXQiLCJtb2R1bGVPck9iamVjdFBhcnNlciIsImUiLCJib29sZWFuUGFyc2VyIiwibnVsbFBhcnNlciIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUEsU0FBU0EsWUFBVCxDQUFzQkMsR0FBdEIsRUFBMkI7QUFDekIsU0FBTyxVQUFVQyxHQUFWLEVBQWU7QUFDcEIsVUFBTUMsTUFBTSxHQUFHQyxRQUFRLENBQUNGLEdBQUQsQ0FBdkI7O0FBQ0EsUUFBSSxDQUFDRyxNQUFNLENBQUNDLFNBQVAsQ0FBaUJILE1BQWpCLENBQUwsRUFBK0I7QUFDN0IsWUFBTSxJQUFJSSxLQUFKLENBQVcsT0FBTU4sR0FBSSxzQkFBcUJDLEdBQUksRUFBOUMsQ0FBTjtBQUNEOztBQUNELFdBQU9DLE1BQVA7QUFDRCxHQU5EO0FBT0Q7O0FBRUQsU0FBU0ssa0JBQVQsQ0FBNEJQLEdBQTVCLEVBQWlDO0FBQy9CLFNBQU8sVUFBVUMsR0FBVixFQUFlO0FBQ3BCLFFBQUksT0FBT0EsR0FBUCxLQUFlLFNBQW5CLEVBQThCO0FBQzVCLGFBQU9BLEdBQVA7QUFDRDs7QUFDRCxRQUFJQSxHQUFHLEtBQUssTUFBWixFQUFvQjtBQUNsQixhQUFPLElBQVA7QUFDRDs7QUFDRCxRQUFJQSxHQUFHLEtBQUssT0FBWixFQUFxQjtBQUNuQixhQUFPLEtBQVA7QUFDRDs7QUFDRCxXQUFPRixZQUFZLENBQUNDLEdBQUQsQ0FBWixDQUFrQkMsR0FBbEIsQ0FBUDtBQUNELEdBWEQ7QUFZRDs7QUFFRCxTQUFTTyxZQUFULENBQXNCUCxHQUF0QixFQUEyQjtBQUN6QixNQUFJLE9BQU9BLEdBQVAsSUFBYyxRQUFsQixFQUE0QjtBQUMxQixXQUFPQSxHQUFQO0FBQ0Q7O0FBQ0QsU0FBT1EsSUFBSSxDQUFDQyxLQUFMLENBQVdULEdBQVgsQ0FBUDtBQUNEOztBQUVELFNBQVNVLFdBQVQsQ0FBcUJWLEdBQXJCLEVBQTBCO0FBQ3hCLE1BQUlXLEtBQUssQ0FBQ0MsT0FBTixDQUFjWixHQUFkLENBQUosRUFBd0I7QUFDdEIsV0FBT0EsR0FBUDtBQUNELEdBRkQsTUFFTyxJQUFJLE9BQU9BLEdBQVAsS0FBZSxRQUFuQixFQUE2QjtBQUNsQyxXQUFPQSxHQUFHLENBQUNhLEtBQUosQ0FBVSxHQUFWLENBQVA7QUFDRCxHQUZNLE1BRUE7QUFDTCxVQUFNLElBQUlSLEtBQUosQ0FBVyxHQUFFTCxHQUFJLGlEQUFqQixDQUFOO0FBQ0Q7QUFDRjs7QUFFRCxTQUFTYyxvQkFBVCxDQUE4QmQsR0FBOUIsRUFBbUM7QUFDakMsTUFBSSxPQUFPQSxHQUFQLElBQWMsUUFBbEIsRUFBNEI7QUFDMUIsV0FBT0EsR0FBUDtBQUNEOztBQUNELE1BQUk7QUFDRixXQUFPUSxJQUFJLENBQUNDLEtBQUwsQ0FBV1QsR0FBWCxDQUFQO0FBQ0QsR0FGRCxDQUVFLE9BQU9lLENBQVAsRUFBVTtBQUNWO0FBQ0Q7O0FBQ0QsU0FBT2YsR0FBUDtBQUNEOztBQUVELFNBQVNnQixhQUFULENBQXVCaEIsR0FBdkIsRUFBNEI7QUFDMUIsTUFBSUEsR0FBRyxJQUFJLElBQVAsSUFBZUEsR0FBRyxJQUFJLE1BQXRCLElBQWdDQSxHQUFHLElBQUksR0FBM0MsRUFBZ0Q7QUFDOUMsV0FBTyxJQUFQO0FBQ0Q7O0FBQ0QsU0FBTyxLQUFQO0FBQ0Q7O0FBRUQsU0FBU2lCLFVBQVQsQ0FBb0JqQixHQUFwQixFQUF5QjtBQUN2QixNQUFJQSxHQUFHLElBQUksTUFBWCxFQUFtQjtBQUNqQixXQUFPLElBQVA7QUFDRDs7QUFDRCxTQUFPQSxHQUFQO0FBQ0Q7O0FBRURrQixNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZnJCLEVBQUFBLFlBRGU7QUFFZlEsRUFBQUEsa0JBRmU7QUFHZlcsRUFBQUEsVUFIZTtBQUlmRCxFQUFBQSxhQUplO0FBS2ZGLEVBQUFBLG9CQUxlO0FBTWZKLEVBQUFBLFdBTmU7QUFPZkgsRUFBQUE7QUFQZSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIG51bWJlclBhcnNlcihrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChvcHQpIHtcbiAgICBjb25zdCBpbnRPcHQgPSBwYXJzZUludChvcHQpO1xuICAgIGlmICghTnVtYmVyLmlzSW50ZWdlcihpbnRPcHQpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEtleSAke2tleX0gaGFzIGludmFsaWQgdmFsdWUgJHtvcHR9YCk7XG4gICAgfVxuICAgIHJldHVybiBpbnRPcHQ7XG4gIH07XG59XG5cbmZ1bmN0aW9uIG51bWJlck9yQm9vbFBhcnNlcihrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChvcHQpIHtcbiAgICBpZiAodHlwZW9mIG9wdCA9PT0gJ2Jvb2xlYW4nKSB7XG4gICAgICByZXR1cm4gb3B0O1xuICAgIH1cbiAgICBpZiAob3B0ID09PSAndHJ1ZScpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAob3B0ID09PSAnZmFsc2UnKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBudW1iZXJQYXJzZXIoa2V5KShvcHQpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBvYmplY3RQYXJzZXIob3B0KSB7XG4gIGlmICh0eXBlb2Ygb3B0ID09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIG9wdDtcbiAgfVxuICByZXR1cm4gSlNPTi5wYXJzZShvcHQpO1xufVxuXG5mdW5jdGlvbiBhcnJheVBhcnNlcihvcHQpIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkob3B0KSkge1xuICAgIHJldHVybiBvcHQ7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG9wdCA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gb3B0LnNwbGl0KCcsJyk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke29wdH0gc2hvdWxkIGJlIGEgY29tbWEgc2VwYXJhdGVkIHN0cmluZyBvciBhbiBhcnJheWApO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1vZHVsZU9yT2JqZWN0UGFyc2VyKG9wdCkge1xuICBpZiAodHlwZW9mIG9wdCA9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBvcHQ7XG4gIH1cbiAgdHJ5IHtcbiAgICByZXR1cm4gSlNPTi5wYXJzZShvcHQpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLyogKi9cbiAgfVxuICByZXR1cm4gb3B0O1xufVxuXG5mdW5jdGlvbiBib29sZWFuUGFyc2VyKG9wdCkge1xuICBpZiAob3B0ID09IHRydWUgfHwgb3B0ID09ICd0cnVlJyB8fCBvcHQgPT0gJzEnKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBudWxsUGFyc2VyKG9wdCkge1xuICBpZiAob3B0ID09ICdudWxsJykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiBvcHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBudW1iZXJQYXJzZXIsXG4gIG51bWJlck9yQm9vbFBhcnNlcixcbiAgbnVsbFBhcnNlcixcbiAgYm9vbGVhblBhcnNlcixcbiAgbW9kdWxlT3JPYmplY3RQYXJzZXIsXG4gIGFycmF5UGFyc2VyLFxuICBvYmplY3RQYXJzZXIsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/Page.js b/lib/Page.js deleted file mode 100644 index 324e123cc8..0000000000 --- a/lib/Page.js +++ /dev/null @@ -1,53 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.Page = void 0; - -/*eslint no-unused-vars: "off"*/ - -/** - * @interface Page - * Page - * Page content that is returned by PageRouter. - */ -class Page { - /** - * @description Creates a page. - * @param {Object} params The page parameters. - * @param {String} params.id The page identifier. - * @param {String} params.defaultFile The page file name. - * @returns {Page} The page. - */ - constructor(params = {}) { - const { - id, - defaultFile - } = params; - this._id = id; - this._defaultFile = defaultFile; - } - - get id() { - return this._id; - } - - get defaultFile() { - return this._defaultFile; - } - - set id(v) { - this._id = v; - } - - set defaultFile(v) { - this._defaultFile = v; - } - -} - -exports.Page = Page; -var _default = Page; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9QYWdlLmpzIl0sIm5hbWVzIjpbIlBhZ2UiLCJjb25zdHJ1Y3RvciIsInBhcmFtcyIsImlkIiwiZGVmYXVsdEZpbGUiLCJfaWQiLCJfZGVmYXVsdEZpbGUiLCJ2Il0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU1BLElBQU4sQ0FBVztBQUNoQjtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNFQyxFQUFBQSxXQUFXLENBQUNDLE1BQU0sR0FBRyxFQUFWLEVBQWM7QUFDdkIsVUFBTTtBQUFFQyxNQUFBQSxFQUFGO0FBQU1DLE1BQUFBO0FBQU4sUUFBc0JGLE1BQTVCO0FBRUEsU0FBS0csR0FBTCxHQUFXRixFQUFYO0FBQ0EsU0FBS0csWUFBTCxHQUFvQkYsV0FBcEI7QUFDRDs7QUFFRCxNQUFJRCxFQUFKLEdBQVM7QUFDUCxXQUFPLEtBQUtFLEdBQVo7QUFDRDs7QUFDRCxNQUFJRCxXQUFKLEdBQWtCO0FBQ2hCLFdBQU8sS0FBS0UsWUFBWjtBQUNEOztBQUNELE1BQUlILEVBQUosQ0FBT0ksQ0FBUCxFQUFVO0FBQ1IsU0FBS0YsR0FBTCxHQUFXRSxDQUFYO0FBQ0Q7O0FBQ0QsTUFBSUgsV0FBSixDQUFnQkcsQ0FBaEIsRUFBbUI7QUFDakIsU0FBS0QsWUFBTCxHQUFvQkMsQ0FBcEI7QUFDRDs7QUExQmU7OztlQTZCSFAsSSIsInNvdXJjZXNDb250ZW50IjpbIi8qZXNsaW50IG5vLXVudXNlZC12YXJzOiBcIm9mZlwiKi9cbi8qKlxuICogQGludGVyZmFjZSBQYWdlXG4gKiBQYWdlXG4gKiBQYWdlIGNvbnRlbnQgdGhhdCBpcyByZXR1cm5lZCBieSBQYWdlUm91dGVyLlxuICovXG5leHBvcnQgY2xhc3MgUGFnZSB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIHBhZ2UuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgVGhlIHBhZ2UgcGFyYW1ldGVycy5cbiAgICogQHBhcmFtIHtTdHJpbmd9IHBhcmFtcy5pZCBUaGUgcGFnZSBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gcGFyYW1zLmRlZmF1bHRGaWxlIFRoZSBwYWdlIGZpbGUgbmFtZS5cbiAgICogQHJldHVybnMge1BhZ2V9IFRoZSBwYWdlLlxuICAgKi9cbiAgY29uc3RydWN0b3IocGFyYW1zID0ge30pIHtcbiAgICBjb25zdCB7IGlkLCBkZWZhdWx0RmlsZSB9ID0gcGFyYW1zO1xuXG4gICAgdGhpcy5faWQgPSBpZDtcbiAgICB0aGlzLl9kZWZhdWx0RmlsZSA9IGRlZmF1bHRGaWxlO1xuICB9XG5cbiAgZ2V0IGlkKCkge1xuICAgIHJldHVybiB0aGlzLl9pZDtcbiAgfVxuICBnZXQgZGVmYXVsdEZpbGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2RlZmF1bHRGaWxlO1xuICB9XG4gIHNldCBpZCh2KSB7XG4gICAgdGhpcy5faWQgPSB2O1xuICB9XG4gIHNldCBkZWZhdWx0RmlsZSh2KSB7XG4gICAgdGhpcy5fZGVmYXVsdEZpbGUgPSB2O1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBhZ2U7XG4iXX0= \ No newline at end of file diff --git a/lib/ParseMessageQueue.js b/lib/ParseMessageQueue.js deleted file mode 100644 index 3bf0e42236..0000000000 --- a/lib/ParseMessageQueue.js +++ /dev/null @@ -1,34 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.ParseMessageQueue = void 0; - -var _AdapterLoader = require("./Adapters/AdapterLoader"); - -var _EventEmitterMQ = require("./Adapters/MessageQueue/EventEmitterMQ"); - -const ParseMessageQueue = {}; -exports.ParseMessageQueue = ParseMessageQueue; - -ParseMessageQueue.createPublisher = function (config) { - const adapter = (0, _AdapterLoader.loadAdapter)(config.messageQueueAdapter, _EventEmitterMQ.EventEmitterMQ, config); - - if (typeof adapter.createPublisher !== 'function') { - throw 'pubSubAdapter should have createPublisher()'; - } - - return adapter.createPublisher(config); -}; - -ParseMessageQueue.createSubscriber = function (config) { - const adapter = (0, _AdapterLoader.loadAdapter)(config.messageQueueAdapter, _EventEmitterMQ.EventEmitterMQ, config); - - if (typeof adapter.createSubscriber !== 'function') { - throw 'messageQueueAdapter should have createSubscriber()'; - } - - return adapter.createSubscriber(config); -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9QYXJzZU1lc3NhZ2VRdWV1ZS5qcyJdLCJuYW1lcyI6WyJQYXJzZU1lc3NhZ2VRdWV1ZSIsImNyZWF0ZVB1Ymxpc2hlciIsImNvbmZpZyIsImFkYXB0ZXIiLCJtZXNzYWdlUXVldWVBZGFwdGVyIiwiRXZlbnRFbWl0dGVyTVEiLCJjcmVhdGVTdWJzY3JpYmVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBRUEsTUFBTUEsaUJBQWlCLEdBQUcsRUFBMUI7OztBQUVBQSxpQkFBaUIsQ0FBQ0MsZUFBbEIsR0FBb0MsVUFBVUMsTUFBVixFQUE0QjtBQUM5RCxRQUFNQyxPQUFPLEdBQUcsZ0NBQVlELE1BQU0sQ0FBQ0UsbUJBQW5CLEVBQXdDQyw4QkFBeEMsRUFBd0RILE1BQXhELENBQWhCOztBQUNBLE1BQUksT0FBT0MsT0FBTyxDQUFDRixlQUFmLEtBQW1DLFVBQXZDLEVBQW1EO0FBQ2pELFVBQU0sNkNBQU47QUFDRDs7QUFDRCxTQUFPRSxPQUFPLENBQUNGLGVBQVIsQ0FBd0JDLE1BQXhCLENBQVA7QUFDRCxDQU5EOztBQVFBRixpQkFBaUIsQ0FBQ00sZ0JBQWxCLEdBQXFDLFVBQVVKLE1BQVYsRUFBNkI7QUFDaEUsUUFBTUMsT0FBTyxHQUFHLGdDQUFZRCxNQUFNLENBQUNFLG1CQUFuQixFQUF3Q0MsOEJBQXhDLEVBQXdESCxNQUF4RCxDQUFoQjs7QUFDQSxNQUFJLE9BQU9DLE9BQU8sQ0FBQ0csZ0JBQWYsS0FBb0MsVUFBeEMsRUFBb0Q7QUFDbEQsVUFBTSxvREFBTjtBQUNEOztBQUNELFNBQU9ILE9BQU8sQ0FBQ0csZ0JBQVIsQ0FBeUJKLE1BQXpCLENBQVA7QUFDRCxDQU5EIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbG9hZEFkYXB0ZXIgfSBmcm9tICcuL0FkYXB0ZXJzL0FkYXB0ZXJMb2FkZXInO1xuaW1wb3J0IHsgRXZlbnRFbWl0dGVyTVEgfSBmcm9tICcuL0FkYXB0ZXJzL01lc3NhZ2VRdWV1ZS9FdmVudEVtaXR0ZXJNUSc7XG5cbmNvbnN0IFBhcnNlTWVzc2FnZVF1ZXVlID0ge307XG5cblBhcnNlTWVzc2FnZVF1ZXVlLmNyZWF0ZVB1Ymxpc2hlciA9IGZ1bmN0aW9uIChjb25maWc6IGFueSk6IGFueSB7XG4gIGNvbnN0IGFkYXB0ZXIgPSBsb2FkQWRhcHRlcihjb25maWcubWVzc2FnZVF1ZXVlQWRhcHRlciwgRXZlbnRFbWl0dGVyTVEsIGNvbmZpZyk7XG4gIGlmICh0eXBlb2YgYWRhcHRlci5jcmVhdGVQdWJsaXNoZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyAncHViU3ViQWRhcHRlciBzaG91bGQgaGF2ZSBjcmVhdGVQdWJsaXNoZXIoKSc7XG4gIH1cbiAgcmV0dXJuIGFkYXB0ZXIuY3JlYXRlUHVibGlzaGVyKGNvbmZpZyk7XG59O1xuXG5QYXJzZU1lc3NhZ2VRdWV1ZS5jcmVhdGVTdWJzY3JpYmVyID0gZnVuY3Rpb24gKGNvbmZpZzogYW55KTogdm9pZCB7XG4gIGNvbnN0IGFkYXB0ZXIgPSBsb2FkQWRhcHRlcihjb25maWcubWVzc2FnZVF1ZXVlQWRhcHRlciwgRXZlbnRFbWl0dGVyTVEsIGNvbmZpZyk7XG4gIGlmICh0eXBlb2YgYWRhcHRlci5jcmVhdGVTdWJzY3JpYmVyICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgJ21lc3NhZ2VRdWV1ZUFkYXB0ZXIgc2hvdWxkIGhhdmUgY3JlYXRlU3Vic2NyaWJlcigpJztcbiAgfVxuICByZXR1cm4gYWRhcHRlci5jcmVhdGVTdWJzY3JpYmVyKGNvbmZpZyk7XG59O1xuXG5leHBvcnQgeyBQYXJzZU1lc3NhZ2VRdWV1ZSB9O1xuIl19 \ No newline at end of file diff --git a/lib/ParseServer.js b/lib/ParseServer.js deleted file mode 100644 index 7081dac4fb..0000000000 --- a/lib/ParseServer.js +++ /dev/null @@ -1,499 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _Options = require("./Options"); - -var _defaults = _interopRequireDefault(require("./defaults")); - -var logging = _interopRequireWildcard(require("./logger")); - -var _Config = _interopRequireDefault(require("./Config")); - -var _PromiseRouter = _interopRequireDefault(require("./PromiseRouter")); - -var _requiredParameter = _interopRequireDefault(require("./requiredParameter")); - -var _AnalyticsRouter = require("./Routers/AnalyticsRouter"); - -var _ClassesRouter = require("./Routers/ClassesRouter"); - -var _FeaturesRouter = require("./Routers/FeaturesRouter"); - -var _FilesRouter = require("./Routers/FilesRouter"); - -var _FunctionsRouter = require("./Routers/FunctionsRouter"); - -var _GlobalConfigRouter = require("./Routers/GlobalConfigRouter"); - -var _GraphQLRouter = require("./Routers/GraphQLRouter"); - -var _HooksRouter = require("./Routers/HooksRouter"); - -var _IAPValidationRouter = require("./Routers/IAPValidationRouter"); - -var _InstallationsRouter = require("./Routers/InstallationsRouter"); - -var _LogsRouter = require("./Routers/LogsRouter"); - -var _ParseLiveQueryServer = require("./LiveQuery/ParseLiveQueryServer"); - -var _PagesRouter = require("./Routers/PagesRouter"); - -var _PublicAPIRouter = require("./Routers/PublicAPIRouter"); - -var _PushRouter = require("./Routers/PushRouter"); - -var _CloudCodeRouter = require("./Routers/CloudCodeRouter"); - -var _RolesRouter = require("./Routers/RolesRouter"); - -var _SchemasRouter = require("./Routers/SchemasRouter"); - -var _SessionsRouter = require("./Routers/SessionsRouter"); - -var _UsersRouter = require("./Routers/UsersRouter"); - -var _PurgeRouter = require("./Routers/PurgeRouter"); - -var _AudiencesRouter = require("./Routers/AudiencesRouter"); - -var _AggregateRouter = require("./Routers/AggregateRouter"); - -var _ParseServerRESTController = require("./ParseServerRESTController"); - -var controllers = _interopRequireWildcard(require("./Controllers")); - -var _ParseGraphQLServer = require("./GraphQL/ParseGraphQLServer"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// ParseServer - open-source compatible API Server for Parse apps -var batch = require('./batch'), - bodyParser = require('body-parser'), - express = require('express'), - middlewares = require('./middlewares'), - Parse = require('parse/node').Parse, - { - parse -} = require('graphql'), - path = require('path'), - fs = require('fs'); - -// Mutate the Parse object to add the Cloud Code handlers -addParseCloud(); // ParseServer works like a constructor of an express app. -// https://parseplatform.org/parse-server/api/master/ParseServerOptions.html - -class ParseServer { - /** - * @constructor - * @param {ParseServerOptions} options the parse server initialization options - */ - constructor(options) { - injectDefaults(options); - const { - appId = (0, _requiredParameter.default)('You must provide an appId!'), - masterKey = (0, _requiredParameter.default)('You must provide a masterKey!'), - cloud, - javascriptKey, - serverURL = (0, _requiredParameter.default)('You must provide a serverURL!'), - serverStartComplete - } = options; // Initialize the node client SDK automatically - - Parse.initialize(appId, javascriptKey || 'unused', masterKey); - Parse.serverURL = serverURL; - const allControllers = controllers.getControllers(options); - const { - loggerController, - databaseController, - hooksController - } = allControllers; - this.config = _Config.default.put(Object.assign({}, options, allControllers)); - logging.setLogger(loggerController); - const dbInitPromise = databaseController.performInitialization(); - const hooksLoadPromise = hooksController.load(); // Note: Tests will start to fail if any validation happens after this is called. - - Promise.all([dbInitPromise, hooksLoadPromise]).then(() => { - if (serverStartComplete) { - serverStartComplete(); - } - }).catch(error => { - if (serverStartComplete) { - serverStartComplete(error); - } else { - console.error(error); - process.exit(1); - } - }); - - if (cloud) { - addParseCloud(); - - if (typeof cloud === 'function') { - cloud(Parse); - } else if (typeof cloud === 'string') { - require(path.resolve(process.cwd(), cloud)); - } else { - throw "argument 'cloud' must either be a string or a function"; - } - } - } - - get app() { - if (!this._app) { - this._app = ParseServer.app(this.config); - } - - return this._app; - } - - handleShutdown() { - const promises = []; - const { - adapter: databaseAdapter - } = this.config.databaseController; - - if (databaseAdapter && typeof databaseAdapter.handleShutdown === 'function') { - promises.push(databaseAdapter.handleShutdown()); - } - - const { - adapter: fileAdapter - } = this.config.filesController; - - if (fileAdapter && typeof fileAdapter.handleShutdown === 'function') { - promises.push(fileAdapter.handleShutdown()); - } - - const { - adapter: cacheAdapter - } = this.config.cacheController; - - if (cacheAdapter && typeof cacheAdapter.handleShutdown === 'function') { - promises.push(cacheAdapter.handleShutdown()); - } - - return (promises.length > 0 ? Promise.all(promises) : Promise.resolve()).then(() => { - if (this.config.serverCloseComplete) { - this.config.serverCloseComplete(); - } - }); - } - /** - * @static - * Create an express app for the parse server - * @param {Object} options let you specify the maxUploadSize when creating the express app */ - - - static app(options) { - const { - maxUploadSize = '20mb', - appId, - directAccess, - pages - } = options; // This app serves the Parse API directly. - // It's the equivalent of https://api.parse.com/1 in the hosted Parse API. - - var api = express(); //api.use("/apps", express.static(__dirname + "/public")); - - api.use(middlewares.allowCrossDomain(appId)); // File handling needs to be before default middlewares are applied - - api.use('/', new _FilesRouter.FilesRouter().expressRouter({ - maxUploadSize: maxUploadSize - })); - api.use('/health', function (req, res) { - res.json({ - status: 'ok' - }); - }); - api.use('/', bodyParser.urlencoded({ - extended: false - }), pages.enableRouter ? new _PagesRouter.PagesRouter(pages).expressRouter() : new _PublicAPIRouter.PublicAPIRouter().expressRouter()); - api.use(bodyParser.json({ - type: '*/*', - limit: maxUploadSize - })); - api.use(middlewares.allowMethodOverride); - api.use(middlewares.handleParseHeaders); - const appRouter = ParseServer.promiseRouter({ - appId - }); - api.use(appRouter.expressRouter()); - api.use(middlewares.handleParseErrors); // run the following when not testing - - if (!process.env.TESTING) { - //This causes tests to spew some useless warnings, so disable in test - - /* istanbul ignore next */ - process.on('uncaughtException', err => { - if (err.code === 'EADDRINUSE') { - // user-friendly message for this common error - process.stderr.write(`Unable to listen on port ${err.port}. The port is already in use.`); - process.exit(0); - } else { - throw err; - } - }); // verify the server url after a 'mount' event is received - - /* istanbul ignore next */ - - api.on('mount', function () { - ParseServer.verifyServerUrl(); - }); - } - - if (process.env.PARSE_SERVER_ENABLE_EXPERIMENTAL_DIRECT_ACCESS === '1' || directAccess) { - Parse.CoreManager.setRESTController((0, _ParseServerRESTController.ParseServerRESTController)(appId, appRouter)); - } - - return api; - } - - static promiseRouter({ - appId - }) { - const routers = [new _ClassesRouter.ClassesRouter(), new _UsersRouter.UsersRouter(), new _SessionsRouter.SessionsRouter(), new _RolesRouter.RolesRouter(), new _AnalyticsRouter.AnalyticsRouter(), new _InstallationsRouter.InstallationsRouter(), new _FunctionsRouter.FunctionsRouter(), new _SchemasRouter.SchemasRouter(), new _PushRouter.PushRouter(), new _LogsRouter.LogsRouter(), new _IAPValidationRouter.IAPValidationRouter(), new _FeaturesRouter.FeaturesRouter(), new _GlobalConfigRouter.GlobalConfigRouter(), new _GraphQLRouter.GraphQLRouter(), new _PurgeRouter.PurgeRouter(), new _HooksRouter.HooksRouter(), new _CloudCodeRouter.CloudCodeRouter(), new _AudiencesRouter.AudiencesRouter(), new _AggregateRouter.AggregateRouter()]; - const routes = routers.reduce((memo, router) => { - return memo.concat(router.routes); - }, []); - const appRouter = new _PromiseRouter.default(routes, appId); - batch.mountOnto(appRouter); - return appRouter; - } - /** - * starts the parse server's express app - * @param {ParseServerOptions} options to use to start the server - * @param {Function} callback called when the server has started - * @returns {ParseServer} the parse server instance - */ - - - start(options, callback) { - const app = express(); - - if (options.middleware) { - let middleware; - - if (typeof options.middleware == 'string') { - middleware = require(path.resolve(process.cwd(), options.middleware)); - } else { - middleware = options.middleware; // use as-is let express fail - } - - app.use(middleware); - } - - app.use(options.mountPath, this.app); - - if (options.mountGraphQL === true || options.mountPlayground === true) { - let graphQLCustomTypeDefs = undefined; - - if (typeof options.graphQLSchema === 'string') { - graphQLCustomTypeDefs = parse(fs.readFileSync(options.graphQLSchema, 'utf8')); - } else if (typeof options.graphQLSchema === 'object' || typeof options.graphQLSchema === 'function') { - graphQLCustomTypeDefs = options.graphQLSchema; - } - - const parseGraphQLServer = new _ParseGraphQLServer.ParseGraphQLServer(this, { - graphQLPath: options.graphQLPath, - playgroundPath: options.playgroundPath, - graphQLCustomTypeDefs - }); - - if (options.mountGraphQL) { - parseGraphQLServer.applyGraphQL(app); - } - - if (options.mountPlayground) { - parseGraphQLServer.applyPlayground(app); - } - } - - const server = app.listen(options.port, options.host, callback); - this.server = server; - - if (options.startLiveQueryServer || options.liveQueryServerOptions) { - this.liveQueryServer = ParseServer.createLiveQueryServer(server, options.liveQueryServerOptions, options); - } - /* istanbul ignore next */ - - - if (!process.env.TESTING) { - configureListeners(this); - } - - this.expressApp = app; - return this; - } - /** - * Creates a new ParseServer and starts it. - * @param {ParseServerOptions} options used to start the server - * @param {Function} callback called when the server has started - * @returns {ParseServer} the parse server instance - */ - - - static start(options, callback) { - const parseServer = new ParseServer(options); - return parseServer.start(options, callback); - } - /** - * Helper method to create a liveQuery server - * @static - * @param {Server} httpServer an optional http server to pass - * @param {LiveQueryServerOptions} config options for the liveQueryServer - * @param {ParseServerOptions} options options for the ParseServer - * @returns {ParseLiveQueryServer} the live query server instance - */ - - - static createLiveQueryServer(httpServer, config, options) { - if (!httpServer || config && config.port) { - var app = express(); - httpServer = require('http').createServer(app); - httpServer.listen(config.port); - } - - return new _ParseLiveQueryServer.ParseLiveQueryServer(httpServer, config, options); - } - - static verifyServerUrl(callback) { - // perform a health check on the serverURL value - if (Parse.serverURL) { - const request = require('./request'); - - request({ - url: Parse.serverURL.replace(/\/$/, '') + '/health' - }).catch(response => response).then(response => { - const json = response.data || null; - - if (response.status !== 200 || !json || json && json.status !== 'ok') { - /* eslint-disable no-console */ - console.warn(`\nWARNING, Unable to connect to '${Parse.serverURL}'.` + ` Cloud code and push notifications may be unavailable!\n`); - /* eslint-enable no-console */ - - if (callback) { - callback(false); - } - } else { - if (callback) { - callback(true); - } - } - }); - } - } - -} - -function addParseCloud() { - const ParseCloud = require('./cloud-code/Parse.Cloud'); - - Object.assign(Parse.Cloud, ParseCloud); - global.Parse = Parse; -} - -function injectDefaults(options) { - Object.keys(_defaults.default).forEach(key => { - if (!Object.prototype.hasOwnProperty.call(options, key)) { - options[key] = _defaults.default[key]; - } - }); - - if (!Object.prototype.hasOwnProperty.call(options, 'serverURL')) { - options.serverURL = `http://localhost:${options.port}${options.mountPath}`; - } // Reserved Characters - - - if (options.appId) { - const regex = /[!#$%'()*+&/:;=?@[\]{}^,|<>]/g; - - if (options.appId.match(regex)) { - console.warn(`\nWARNING, appId that contains special characters can cause issues while using with urls.\n`); - } - } // Backwards compatibility - - - if (options.userSensitiveFields) { - /* eslint-disable no-console */ - !process.env.TESTING && console.warn(`\nDEPRECATED: userSensitiveFields has been replaced by protectedFields allowing the ability to protect fields in all classes with CLP. \n`); - /* eslint-enable no-console */ - - const userSensitiveFields = Array.from(new Set([...(_defaults.default.userSensitiveFields || []), ...(options.userSensitiveFields || [])])); // If the options.protectedFields is unset, - // it'll be assigned the default above. - // Here, protect against the case where protectedFields - // is set, but doesn't have _User. - - if (!('_User' in options.protectedFields)) { - options.protectedFields = Object.assign({ - _User: [] - }, options.protectedFields); - } - - options.protectedFields['_User']['*'] = Array.from(new Set([...(options.protectedFields['_User']['*'] || []), ...userSensitiveFields])); - } // Merge protectedFields options with defaults. - - - Object.keys(_defaults.default.protectedFields).forEach(c => { - const cur = options.protectedFields[c]; - - if (!cur) { - options.protectedFields[c] = _defaults.default.protectedFields[c]; - } else { - Object.keys(_defaults.default.protectedFields[c]).forEach(r => { - const unq = new Set([...(options.protectedFields[c][r] || []), ..._defaults.default.protectedFields[c][r]]); - options.protectedFields[c][r] = Array.from(unq); - }); - } - }); - options.masterKeyIps = Array.from(new Set(options.masterKeyIps.concat(_defaults.default.masterKeyIps, options.masterKeyIps))); -} // Those can't be tested as it requires a subprocess - -/* istanbul ignore next */ - - -function configureListeners(parseServer) { - const server = parseServer.server; - const sockets = {}; - /* Currently, express doesn't shut down immediately after receiving SIGINT/SIGTERM if it has client connections that haven't timed out. (This is a known issue with node - https://github.com/nodejs/node/issues/2642) - This function, along with `destroyAliveConnections()`, intend to fix this behavior such that parse server will close all open connections and initiate the shutdown process as soon as it receives a SIGINT/SIGTERM signal. */ - - server.on('connection', socket => { - const socketId = socket.remoteAddress + ':' + socket.remotePort; - sockets[socketId] = socket; - socket.on('close', () => { - delete sockets[socketId]; - }); - }); - - const destroyAliveConnections = function () { - for (const socketId in sockets) { - try { - sockets[socketId].destroy(); - } catch (e) { - /* */ - } - } - }; - - const handleShutdown = function () { - process.stdout.write('Termination signal received. Shutting down.'); - destroyAliveConnections(); - server.close(); - parseServer.handleShutdown(); - }; - - process.on('SIGTERM', handleShutdown); - process.on('SIGINT', handleShutdown); -} - -var _default = ParseServer; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9QYXJzZVNlcnZlci5qcyJdLCJuYW1lcyI6WyJiYXRjaCIsInJlcXVpcmUiLCJib2R5UGFyc2VyIiwiZXhwcmVzcyIsIm1pZGRsZXdhcmVzIiwiUGFyc2UiLCJwYXJzZSIsInBhdGgiLCJmcyIsImFkZFBhcnNlQ2xvdWQiLCJQYXJzZVNlcnZlciIsImNvbnN0cnVjdG9yIiwib3B0aW9ucyIsImluamVjdERlZmF1bHRzIiwiYXBwSWQiLCJtYXN0ZXJLZXkiLCJjbG91ZCIsImphdmFzY3JpcHRLZXkiLCJzZXJ2ZXJVUkwiLCJzZXJ2ZXJTdGFydENvbXBsZXRlIiwiaW5pdGlhbGl6ZSIsImFsbENvbnRyb2xsZXJzIiwiY29udHJvbGxlcnMiLCJnZXRDb250cm9sbGVycyIsImxvZ2dlckNvbnRyb2xsZXIiLCJkYXRhYmFzZUNvbnRyb2xsZXIiLCJob29rc0NvbnRyb2xsZXIiLCJjb25maWciLCJDb25maWciLCJwdXQiLCJPYmplY3QiLCJhc3NpZ24iLCJsb2dnaW5nIiwic2V0TG9nZ2VyIiwiZGJJbml0UHJvbWlzZSIsInBlcmZvcm1Jbml0aWFsaXphdGlvbiIsImhvb2tzTG9hZFByb21pc2UiLCJsb2FkIiwiUHJvbWlzZSIsImFsbCIsInRoZW4iLCJjYXRjaCIsImVycm9yIiwiY29uc29sZSIsInByb2Nlc3MiLCJleGl0IiwicmVzb2x2ZSIsImN3ZCIsImFwcCIsIl9hcHAiLCJoYW5kbGVTaHV0ZG93biIsInByb21pc2VzIiwiYWRhcHRlciIsImRhdGFiYXNlQWRhcHRlciIsInB1c2giLCJmaWxlQWRhcHRlciIsImZpbGVzQ29udHJvbGxlciIsImNhY2hlQWRhcHRlciIsImNhY2hlQ29udHJvbGxlciIsImxlbmd0aCIsInNlcnZlckNsb3NlQ29tcGxldGUiLCJtYXhVcGxvYWRTaXplIiwiZGlyZWN0QWNjZXNzIiwicGFnZXMiLCJhcGkiLCJ1c2UiLCJhbGxvd0Nyb3NzRG9tYWluIiwiRmlsZXNSb3V0ZXIiLCJleHByZXNzUm91dGVyIiwicmVxIiwicmVzIiwianNvbiIsInN0YXR1cyIsInVybGVuY29kZWQiLCJleHRlbmRlZCIsImVuYWJsZVJvdXRlciIsIlBhZ2VzUm91dGVyIiwiUHVibGljQVBJUm91dGVyIiwidHlwZSIsImxpbWl0IiwiYWxsb3dNZXRob2RPdmVycmlkZSIsImhhbmRsZVBhcnNlSGVhZGVycyIsImFwcFJvdXRlciIsInByb21pc2VSb3V0ZXIiLCJoYW5kbGVQYXJzZUVycm9ycyIsImVudiIsIlRFU1RJTkciLCJvbiIsImVyciIsImNvZGUiLCJzdGRlcnIiLCJ3cml0ZSIsInBvcnQiLCJ2ZXJpZnlTZXJ2ZXJVcmwiLCJQQVJTRV9TRVJWRVJfRU5BQkxFX0VYUEVSSU1FTlRBTF9ESVJFQ1RfQUNDRVNTIiwiQ29yZU1hbmFnZXIiLCJzZXRSRVNUQ29udHJvbGxlciIsInJvdXRlcnMiLCJDbGFzc2VzUm91dGVyIiwiVXNlcnNSb3V0ZXIiLCJTZXNzaW9uc1JvdXRlciIsIlJvbGVzUm91dGVyIiwiQW5hbHl0aWNzUm91dGVyIiwiSW5zdGFsbGF0aW9uc1JvdXRlciIsIkZ1bmN0aW9uc1JvdXRlciIsIlNjaGVtYXNSb3V0ZXIiLCJQdXNoUm91dGVyIiwiTG9nc1JvdXRlciIsIklBUFZhbGlkYXRpb25Sb3V0ZXIiLCJGZWF0dXJlc1JvdXRlciIsIkdsb2JhbENvbmZpZ1JvdXRlciIsIkdyYXBoUUxSb3V0ZXIiLCJQdXJnZVJvdXRlciIsIkhvb2tzUm91dGVyIiwiQ2xvdWRDb2RlUm91dGVyIiwiQXVkaWVuY2VzUm91dGVyIiwiQWdncmVnYXRlUm91dGVyIiwicm91dGVzIiwicmVkdWNlIiwibWVtbyIsInJvdXRlciIsImNvbmNhdCIsIlByb21pc2VSb3V0ZXIiLCJtb3VudE9udG8iLCJzdGFydCIsImNhbGxiYWNrIiwibWlkZGxld2FyZSIsIm1vdW50UGF0aCIsIm1vdW50R3JhcGhRTCIsIm1vdW50UGxheWdyb3VuZCIsImdyYXBoUUxDdXN0b21UeXBlRGVmcyIsInVuZGVmaW5lZCIsImdyYXBoUUxTY2hlbWEiLCJyZWFkRmlsZVN5bmMiLCJwYXJzZUdyYXBoUUxTZXJ2ZXIiLCJQYXJzZUdyYXBoUUxTZXJ2ZXIiLCJncmFwaFFMUGF0aCIsInBsYXlncm91bmRQYXRoIiwiYXBwbHlHcmFwaFFMIiwiYXBwbHlQbGF5Z3JvdW5kIiwic2VydmVyIiwibGlzdGVuIiwiaG9zdCIsInN0YXJ0TGl2ZVF1ZXJ5U2VydmVyIiwibGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucyIsImxpdmVRdWVyeVNlcnZlciIsImNyZWF0ZUxpdmVRdWVyeVNlcnZlciIsImNvbmZpZ3VyZUxpc3RlbmVycyIsImV4cHJlc3NBcHAiLCJwYXJzZVNlcnZlciIsImh0dHBTZXJ2ZXIiLCJjcmVhdGVTZXJ2ZXIiLCJQYXJzZUxpdmVRdWVyeVNlcnZlciIsInJlcXVlc3QiLCJ1cmwiLCJyZXBsYWNlIiwicmVzcG9uc2UiLCJkYXRhIiwid2FybiIsIlBhcnNlQ2xvdWQiLCJDbG91ZCIsImdsb2JhbCIsImtleXMiLCJkZWZhdWx0cyIsImZvckVhY2giLCJrZXkiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJyZWdleCIsIm1hdGNoIiwidXNlclNlbnNpdGl2ZUZpZWxkcyIsIkFycmF5IiwiZnJvbSIsIlNldCIsInByb3RlY3RlZEZpZWxkcyIsIl9Vc2VyIiwiYyIsImN1ciIsInIiLCJ1bnEiLCJtYXN0ZXJLZXlJcHMiLCJzb2NrZXRzIiwic29ja2V0Iiwic29ja2V0SWQiLCJyZW1vdGVBZGRyZXNzIiwicmVtb3RlUG9ydCIsImRlc3Ryb3lBbGl2ZUNvbm5lY3Rpb25zIiwiZGVzdHJveSIsImUiLCJzdGRvdXQiLCJjbG9zZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQVdBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNB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LENBRUUsT0FBT0MsQ0FBUCxFQUFVO0FBQ1Y7QUFDRDtBQUNGO0FBQ0YsR0FSRDs7QUFVQSxRQUFNM0ksY0FBYyxHQUFHLFlBQVk7QUFDakNOLElBQUFBLE9BQU8sQ0FBQ2tKLE1BQVIsQ0FBZW5HLEtBQWYsQ0FBcUIsNkNBQXJCO0FBQ0FnRyxJQUFBQSx1QkFBdUI7QUFDdkIvQyxJQUFBQSxNQUFNLENBQUNtRCxLQUFQO0FBQ0ExQyxJQUFBQSxXQUFXLENBQUNuRyxjQUFaO0FBQ0QsR0FMRDs7QUFNQU4sRUFBQUEsT0FBTyxDQUFDMkMsRUFBUixDQUFXLFNBQVgsRUFBc0JyQyxjQUF0QjtBQUNBTixFQUFBQSxPQUFPLENBQUMyQyxFQUFSLENBQVcsUUFBWCxFQUFxQnJDLGNBQXJCO0FBQ0Q7O2VBRWN4QyxXIiwic291cmNlc0NvbnRlbnQiOlsiLy8gUGFyc2VTZXJ2ZXIgLSBvcGVuLXNvdXJjZSBjb21wYXRpYmxlIEFQSSBTZXJ2ZXIgZm9yIFBhcnNlIGFwcHNcblxudmFyIGJhdGNoID0gcmVxdWlyZSgnLi9iYXRjaCcpLFxuICBib2R5UGFyc2VyID0gcmVxdWlyZSgnYm9keS1wYXJzZXInKSxcbiAgZXhwcmVzcyA9IHJlcXVpcmUoJ2V4cHJlc3MnKSxcbiAgbWlkZGxld2FyZXMgPSByZXF1aXJlKCcuL21pZGRsZXdhcmVzJyksXG4gIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlLFxuICB7IHBhcnNlIH0gPSByZXF1aXJlKCdncmFwaHFsJyksXG4gIHBhdGggPSByZXF1aXJlKCdwYXRoJyksXG4gIGZzID0gcmVxdWlyZSgnZnMnKTtcblxuaW1wb3J0IHsgUGFyc2VTZXJ2ZXJPcHRpb25zLCBMaXZlUXVlcnlTZXJ2ZXJPcHRpb25zIH0gZnJvbSAnLi9PcHRpb25zJztcbmltcG9ydCBkZWZhdWx0cyBmcm9tICcuL2RlZmF1bHRzJztcbmltcG9ydCAqIGFzIGxvZ2dpbmcgZnJvbSAnLi9sb2dnZXInO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuL0NvbmZpZyc7XG5pbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0IHJlcXVpcmVkUGFyYW1ldGVyIGZyb20gJy4vcmVxdWlyZWRQYXJhbWV0ZXInO1xuaW1wb3J0IHsgQW5hbHl0aWNzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0FuYWx5dGljc1JvdXRlcic7XG5pbXBvcnQgeyBDbGFzc2VzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0NsYXNzZXNSb3V0ZXInO1xuaW1wb3J0IHsgRmVhdHVyZXNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvRmVhdHVyZXNSb3V0ZXInO1xuaW1wb3J0IHsgRmlsZXNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvRmlsZXNSb3V0ZXInO1xuaW1wb3J0IHsgRnVuY3Rpb25zUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0Z1bmN0aW9uc1JvdXRlcic7XG5pbXBvcnQgeyBHbG9iYWxDb25maWdSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvR2xvYmFsQ29uZmlnUm91dGVyJztcbmltcG9ydCB7IEdyYXBoUUxSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvR3JhcGhRTFJvdXRlcic7XG5pbXBvcnQgeyBIb29rc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9Ib29rc1JvdXRlcic7XG5pbXBvcnQgeyBJQVBWYWxpZGF0aW9uUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0lBUFZhbGlkYXRpb25Sb3V0ZXInO1xuaW1wb3J0IHsgSW5zdGFsbGF0aW9uc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9JbnN0YWxsYXRpb25zUm91dGVyJztcbmltcG9ydCB7IExvZ3NSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvTG9nc1JvdXRlcic7XG5pbXBvcnQgeyBQYXJzZUxpdmVRdWVyeVNlcnZlciB9IGZyb20gJy4vTGl2ZVF1ZXJ5L1BhcnNlTGl2ZVF1ZXJ5U2VydmVyJztcbmltcG9ydCB7IFBhZ2VzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL1BhZ2VzUm91dGVyJztcbmltcG9ydCB7IFB1YmxpY0FQSVJvdXRlciB9IGZyb20gJy4vUm91dGVycy9QdWJsaWNBUElSb3V0ZXInO1xuaW1wb3J0IHsgUHVzaFJvdXRlciB9IGZyb20gJy4vUm91dGVycy9QdXNoUm91dGVyJztcbmltcG9ydCB7IENsb3VkQ29kZVJvdXRlciB9IGZyb20gJy4vUm91dGVycy9DbG91ZENvZGVSb3V0ZXInO1xuaW1wb3J0IHsgUm9sZXNSb3V0ZXIgfSBmcm9tICcuL1JvdXRlcnMvUm9sZXNSb3V0ZXInO1xuaW1wb3J0IHsgU2NoZW1hc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9TY2hlbWFzUm91dGVyJztcbmltcG9ydCB7IFNlc3Npb25zUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL1Nlc3Npb25zUm91dGVyJztcbmltcG9ydCB7IFVzZXJzUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL1VzZXJzUm91dGVyJztcbmltcG9ydCB7IFB1cmdlUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL1B1cmdlUm91dGVyJztcbmltcG9ydCB7IEF1ZGllbmNlc1JvdXRlciB9IGZyb20gJy4vUm91dGVycy9BdWRpZW5jZXNSb3V0ZXInO1xuaW1wb3J0IHsgQWdncmVnYXRlUm91dGVyIH0gZnJvbSAnLi9Sb3V0ZXJzL0FnZ3JlZ2F0ZVJvdXRlcic7XG5pbXBvcnQgeyBQYXJzZVNlcnZlclJFU1RDb250cm9sbGVyIH0gZnJvbSAnLi9QYXJzZVNlcnZlclJFU1RDb250cm9sbGVyJztcbmltcG9ydCAqIGFzIGNvbnRyb2xsZXJzIGZyb20gJy4vQ29udHJvbGxlcnMnO1xuaW1wb3J0IHsgUGFyc2VHcmFwaFFMU2VydmVyIH0gZnJvbSAnLi9HcmFwaFFML1BhcnNlR3JhcGhRTFNlcnZlcic7XG5cbi8vIE11dGF0ZSB0aGUgUGFyc2Ugb2JqZWN0IHRvIGFkZCB0aGUgQ2xvdWQgQ29kZSBoYW5kbGVyc1xuYWRkUGFyc2VDbG91ZCgpO1xuXG4vLyBQYXJzZVNlcnZlciB3b3JrcyBsaWtlIGEgY29uc3RydWN0b3Igb2YgYW4gZXhwcmVzcyBhcHAuXG4vLyBodHRwczovL3BhcnNlcGxhdGZvcm0ub3JnL3BhcnNlLXNlcnZlci9hcGkvbWFzdGVyL1BhcnNlU2VydmVyT3B0aW9ucy5odG1sXG5jbGFzcyBQYXJzZVNlcnZlciB7XG4gIC8qKlxuICAgKiBAY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtQYXJzZVNlcnZlck9wdGlvbnN9IG9wdGlvbnMgdGhlIHBhcnNlIHNlcnZlciBpbml0aWFsaXphdGlvbiBvcHRpb25zXG4gICAqL1xuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMpIHtcbiAgICBpbmplY3REZWZhdWx0cyhvcHRpb25zKTtcbiAgICBjb25zdCB7XG4gICAgICBhcHBJZCA9IHJlcXVpcmVkUGFyYW1ldGVyKCdZb3UgbXVzdCBwcm92aWRlIGFuIGFwcElkIScpLFxuICAgICAgbWFzdGVyS2V5ID0gcmVxdWlyZWRQYXJhbWV0ZXIoJ1lvdSBtdXN0IHByb3ZpZGUgYSBtYXN0ZXJLZXkhJyksXG4gICAgICBjbG91ZCxcbiAgICAgIGphdmFzY3JpcHRLZXksXG4gICAgICBzZXJ2ZXJVUkwgPSByZXF1aXJlZFBhcmFtZXRlcignWW91IG11c3QgcHJvdmlkZSBhIHNlcnZlclVSTCEnKSxcbiAgICAgIHNlcnZlclN0YXJ0Q29tcGxldGUsXG4gICAgfSA9IG9wdGlvbnM7XG4gICAgLy8gSW5pdGlhbGl6ZSB0aGUgbm9kZSBjbGllbnQgU0RLIGF1dG9tYXRpY2FsbHlcbiAgICBQYXJzZS5pbml0aWFsaXplKGFwcElkLCBqYXZhc2NyaXB0S2V5IHx8ICd1bnVzZWQnLCBtYXN0ZXJLZXkpO1xuICAgIFBhcnNlLnNlcnZlclVSTCA9IHNlcnZlclVSTDtcblxuICAgIGNvbnN0IGFsbENvbnRyb2xsZXJzID0gY29udHJvbGxlcnMuZ2V0Q29udHJvbGxlcnMob3B0aW9ucyk7XG5cbiAgICBjb25zdCB7IGxvZ2dlckNvbnRyb2xsZXIsIGRhdGFiYXNlQ29udHJvbGxlciwgaG9va3NDb250cm9sbGVyIH0gPSBhbGxDb250cm9sbGVycztcbiAgICB0aGlzLmNvbmZpZyA9IENvbmZpZy5wdXQoT2JqZWN0LmFzc2lnbih7fSwgb3B0aW9ucywgYWxsQ29udHJvbGxlcnMpKTtcblxuICAgIGxvZ2dpbmcuc2V0TG9nZ2VyKGxvZ2dlckNvbnRyb2xsZXIpO1xuICAgIGNvbnN0IGRiSW5pdFByb21pc2UgPSBkYXRhYmFzZUNvbnRyb2xsZXIucGVyZm9ybUluaXRpYWxpemF0aW9uKCk7XG4gICAgY29uc3QgaG9va3NMb2FkUHJvbWlzZSA9IGhvb2tzQ29udHJvbGxlci5sb2FkKCk7XG5cbiAgICAvLyBOb3RlOiBUZXN0cyB3aWxsIHN0YXJ0IHRvIGZhaWwgaWYgYW55IHZhbGlkYXRpb24gaGFwcGVucyBhZnRlciB0aGlzIGlzIGNhbGxlZC5cbiAgICBQcm9taXNlLmFsbChbZGJJbml0UHJvbWlzZSwgaG9va3NMb2FkUHJvbWlzZV0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIGlmIChzZXJ2ZXJTdGFydENvbXBsZXRlKSB7XG4gICAgICAgICAgc2VydmVyU3RhcnRDb21wbGV0ZSgpO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKHNlcnZlclN0YXJ0Q29tcGxldGUpIHtcbiAgICAgICAgICBzZXJ2ZXJTdGFydENvbXBsZXRlKGVycm9yKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgaWYgKGNsb3VkKSB7XG4gICAgICBhZGRQYXJzZUNsb3VkKCk7XG4gICAgICBpZiAodHlwZW9mIGNsb3VkID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGNsb3VkKFBhcnNlKTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGNsb3VkID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXF1aXJlKHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBjbG91ZCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgXCJhcmd1bWVudCAnY2xvdWQnIG11c3QgZWl0aGVyIGJlIGEgc3RyaW5nIG9yIGEgZnVuY3Rpb25cIjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBnZXQgYXBwKCkge1xuICAgIGlmICghdGhpcy5fYXBwKSB7XG4gICAgICB0aGlzLl9hcHAgPSBQYXJzZVNlcnZlci5hcHAodGhpcy5jb25maWcpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fYXBwO1xuICB9XG5cbiAgaGFuZGxlU2h1dGRvd24oKSB7XG4gICAgY29uc3QgcHJvbWlzZXMgPSBbXTtcbiAgICBjb25zdCB7IGFkYXB0ZXI6IGRhdGFiYXNlQWRhcHRlciB9ID0gdGhpcy5jb25maWcuZGF0YWJhc2VDb250cm9sbGVyO1xuICAgIGlmIChkYXRhYmFzZUFkYXB0ZXIgJiYgdHlwZW9mIGRhdGFiYXNlQWRhcHRlci5oYW5kbGVTaHV0ZG93biA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcHJvbWlzZXMucHVzaChkYXRhYmFzZUFkYXB0ZXIuaGFuZGxlU2h1dGRvd24oKSk7XG4gICAgfVxuICAgIGNvbnN0IHsgYWRhcHRlcjogZmlsZUFkYXB0ZXIgfSA9IHRoaXMuY29uZmlnLmZpbGVzQ29udHJvbGxlcjtcbiAgICBpZiAoZmlsZUFkYXB0ZXIgJiYgdHlwZW9mIGZpbGVBZGFwdGVyLmhhbmRsZVNodXRkb3duID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICBwcm9taXNlcy5wdXNoKGZpbGVBZGFwdGVyLmhhbmRsZVNodXRkb3duKCkpO1xuICAgIH1cbiAgICBjb25zdCB7IGFkYXB0ZXI6IGNhY2hlQWRhcHRlciB9ID0gdGhpcy5jb25maWcuY2FjaGVDb250cm9sbGVyO1xuICAgIGlmIChjYWNoZUFkYXB0ZXIgJiYgdHlwZW9mIGNhY2hlQWRhcHRlci5oYW5kbGVTaHV0ZG93biA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcHJvbWlzZXMucHVzaChjYWNoZUFkYXB0ZXIuaGFuZGxlU2h1dGRvd24oKSk7XG4gICAgfVxuICAgIHJldHVybiAocHJvbWlzZXMubGVuZ3RoID4gMCA/IFByb21pc2UuYWxsKHByb21pc2VzKSA6IFByb21pc2UucmVzb2x2ZSgpKS50aGVuKCgpID0+IHtcbiAgICAgIGlmICh0aGlzLmNvbmZpZy5zZXJ2ZXJDbG9zZUNvbXBsZXRlKSB7XG4gICAgICAgIHRoaXMuY29uZmlnLnNlcnZlckNsb3NlQ29tcGxldGUoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3RhdGljXG4gICAqIENyZWF0ZSBhbiBleHByZXNzIGFwcCBmb3IgdGhlIHBhcnNlIHNlcnZlclxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBsZXQgeW91IHNwZWNpZnkgdGhlIG1heFVwbG9hZFNpemUgd2hlbiBjcmVhdGluZyB0aGUgZXhwcmVzcyBhcHAgICovXG4gIHN0YXRpYyBhcHAob3B0aW9ucykge1xuICAgIGNvbnN0IHsgbWF4VXBsb2FkU2l6ZSA9ICcyMG1iJywgYXBwSWQsIGRpcmVjdEFjY2VzcywgcGFnZXMgfSA9IG9wdGlvbnM7XG4gICAgLy8gVGhpcyBhcHAgc2VydmVzIHRoZSBQYXJzZSBBUEkgZGlyZWN0bHkuXG4gICAgLy8gSXQncyB0aGUgZXF1aXZhbGVudCBvZiBodHRwczovL2FwaS5wYXJzZS5jb20vMSBpbiB0aGUgaG9zdGVkIFBhcnNlIEFQSS5cbiAgICB2YXIgYXBpID0gZXhwcmVzcygpO1xuICAgIC8vYXBpLnVzZShcIi9hcHBzXCIsIGV4cHJlc3Muc3RhdGljKF9fZGlybmFtZSArIFwiL3B1YmxpY1wiKSk7XG4gICAgYXBpLnVzZShtaWRkbGV3YXJlcy5hbGxvd0Nyb3NzRG9tYWluKGFwcElkKSk7XG4gICAgLy8gRmlsZSBoYW5kbGluZyBuZWVkcyB0byBiZSBiZWZvcmUgZGVmYXVsdCBtaWRkbGV3YXJlcyBhcmUgYXBwbGllZFxuICAgIGFwaS51c2UoXG4gICAgICAnLycsXG4gICAgICBuZXcgRmlsZXNSb3V0ZXIoKS5leHByZXNzUm91dGVyKHtcbiAgICAgICAgbWF4VXBsb2FkU2l6ZTogbWF4VXBsb2FkU2l6ZSxcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIGFwaS51c2UoJy9oZWFsdGgnLCBmdW5jdGlvbiAocmVxLCByZXMpIHtcbiAgICAgIHJlcy5qc29uKHtcbiAgICAgICAgc3RhdHVzOiAnb2snLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBhcGkudXNlKFxuICAgICAgJy8nLFxuICAgICAgYm9keVBhcnNlci51cmxlbmNvZGVkKHsgZXh0ZW5kZWQ6IGZhbHNlIH0pLFxuICAgICAgcGFnZXMuZW5hYmxlUm91dGVyXG4gICAgICAgID8gbmV3IFBhZ2VzUm91dGVyKHBhZ2VzKS5leHByZXNzUm91dGVyKClcbiAgICAgICAgOiBuZXcgUHVibGljQVBJUm91dGVyKCkuZXhwcmVzc1JvdXRlcigpXG4gICAgKTtcblxuICAgIGFwaS51c2UoYm9keVBhcnNlci5qc29uKHsgdHlwZTogJyovKicsIGxpbWl0OiBtYXhVcGxvYWRTaXplIH0pKTtcbiAgICBhcGkudXNlKG1pZGRsZXdhcmVzLmFsbG93TWV0aG9kT3ZlcnJpZGUpO1xuICAgIGFwaS51c2UobWlkZGxld2FyZXMuaGFuZGxlUGFyc2VIZWFkZXJzKTtcblxuICAgIGNvbnN0IGFwcFJvdXRlciA9IFBhcnNlU2VydmVyLnByb21pc2VSb3V0ZXIoeyBhcHBJZCB9KTtcbiAgICBhcGkudXNlKGFwcFJvdXRlci5leHByZXNzUm91dGVyKCkpO1xuXG4gICAgYXBpLnVzZShtaWRkbGV3YXJlcy5oYW5kbGVQYXJzZUVycm9ycyk7XG5cbiAgICAvLyBydW4gdGhlIGZvbGxvd2luZyB3aGVuIG5vdCB0ZXN0aW5nXG4gICAgaWYgKCFwcm9jZXNzLmVudi5URVNUSU5HKSB7XG4gICAgICAvL1RoaXMgY2F1c2VzIHRlc3RzIHRvIHNwZXcgc29tZSB1c2VsZXNzIHdhcm5pbmdzLCBzbyBkaXNhYmxlIGluIHRlc3RcbiAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgICBwcm9jZXNzLm9uKCd1bmNhdWdodEV4Y2VwdGlvbicsIGVyciA9PiB7XG4gICAgICAgIGlmIChlcnIuY29kZSA9PT0gJ0VBRERSSU5VU0UnKSB7XG4gICAgICAgICAgLy8gdXNlci1mcmllbmRseSBtZXNzYWdlIGZvciB0aGlzIGNvbW1vbiBlcnJvclxuICAgICAgICAgIHByb2Nlc3Muc3RkZXJyLndyaXRlKGBVbmFibGUgdG8gbGlzdGVuIG9uIHBvcnQgJHtlcnIucG9ydH0uIFRoZSBwb3J0IGlzIGFscmVhZHkgaW4gdXNlLmApO1xuICAgICAgICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgLy8gdmVyaWZ5IHRoZSBzZXJ2ZXIgdXJsIGFmdGVyIGEgJ21vdW50JyBldmVudCBpcyByZWNlaXZlZFxuICAgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgICAgIGFwaS5vbignbW91bnQnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIFBhcnNlU2VydmVyLnZlcmlmeVNlcnZlclVybCgpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChwcm9jZXNzLmVudi5QQVJTRV9TRVJWRVJfRU5BQkxFX0VYUEVSSU1FTlRBTF9ESVJFQ1RfQUNDRVNTID09PSAnMScgfHwgZGlyZWN0QWNjZXNzKSB7XG4gICAgICBQYXJzZS5Db3JlTWFuYWdlci5zZXRSRVNUQ29udHJvbGxlcihQYXJzZVNlcnZlclJFU1RDb250cm9sbGVyKGFwcElkLCBhcHBSb3V0ZXIpKTtcbiAgICB9XG4gICAgcmV0dXJuIGFwaTtcbiAgfVxuXG4gIHN0YXRpYyBwcm9taXNlUm91dGVyKHsgYXBwSWQgfSkge1xuICAgIGNvbnN0IHJvdXRlcnMgPSBbXG4gICAgICBuZXcgQ2xhc3Nlc1JvdXRlcigpLFxuICAgICAgbmV3IFVzZXJzUm91dGVyKCksXG4gICAgICBuZXcgU2Vzc2lvbnNSb3V0ZXIoKSxcbiAgICAgIG5ldyBSb2xlc1JvdXRlcigpLFxuICAgICAgbmV3IEFuYWx5dGljc1JvdXRlcigpLFxuICAgICAgbmV3IEluc3RhbGxhdGlvbnNSb3V0ZXIoKSxcbiAgICAgIG5ldyBGdW5jdGlvbnNSb3V0ZXIoKSxcbiAgICAgIG5ldyBTY2hlbWFzUm91dGVyKCksXG4gICAgICBuZXcgUHVzaFJvdXRlcigpLFxuICAgICAgbmV3IExvZ3NSb3V0ZXIoKSxcbiAgICAgIG5ldyBJQVBWYWxpZGF0aW9uUm91dGVyKCksXG4gICAgICBuZXcgRmVhdHVyZXNSb3V0ZXIoKSxcbiAgICAgIG5ldyBHbG9iYWxDb25maWdSb3V0ZXIoKSxcbiAgICAgIG5ldyBHcmFwaFFMUm91dGVyKCksXG4gICAgICBuZXcgUHVyZ2VSb3V0ZXIoKSxcbiAgICAgIG5ldyBIb29rc1JvdXRlcigpLFxuICAgICAgbmV3IENsb3VkQ29kZVJvdXRlcigpLFxuICAgICAgbmV3IEF1ZGllbmNlc1JvdXRlcigpLFxuICAgICAgbmV3IEFnZ3JlZ2F0ZVJvdXRlcigpLFxuICAgIF07XG5cbiAgICBjb25zdCByb3V0ZXMgPSByb3V0ZXJzLnJlZHVjZSgobWVtbywgcm91dGVyKSA9PiB7XG4gICAgICByZXR1cm4gbWVtby5jb25jYXQocm91dGVyLnJvdXRlcyk7XG4gICAgfSwgW10pO1xuXG4gICAgY29uc3QgYXBwUm91dGVyID0gbmV3IFByb21pc2VSb3V0ZXIocm91dGVzLCBhcHBJZCk7XG5cbiAgICBiYXRjaC5tb3VudE9udG8oYXBwUm91dGVyKTtcbiAgICByZXR1cm4gYXBwUm91dGVyO1xuICB9XG5cbiAgLyoqXG4gICAqIHN0YXJ0cyB0aGUgcGFyc2Ugc2VydmVyJ3MgZXhwcmVzcyBhcHBcbiAgICogQHBhcmFtIHtQYXJzZVNlcnZlck9wdGlvbnN9IG9wdGlvbnMgdG8gdXNlIHRvIHN0YXJ0IHRoZSBzZXJ2ZXJcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgY2FsbGVkIHdoZW4gdGhlIHNlcnZlciBoYXMgc3RhcnRlZFxuICAgKiBAcmV0dXJucyB7UGFyc2VTZXJ2ZXJ9IHRoZSBwYXJzZSBzZXJ2ZXIgaW5zdGFuY2VcbiAgICovXG4gIHN0YXJ0KG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucywgY2FsbGJhY2s6ID8oKSA9PiB2b2lkKSB7XG4gICAgY29uc3QgYXBwID0gZXhwcmVzcygpO1xuICAgIGlmIChvcHRpb25zLm1pZGRsZXdhcmUpIHtcbiAgICAgIGxldCBtaWRkbGV3YXJlO1xuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLm1pZGRsZXdhcmUgPT0gJ3N0cmluZycpIHtcbiAgICAgICAgbWlkZGxld2FyZSA9IHJlcXVpcmUocGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksIG9wdGlvbnMubWlkZGxld2FyZSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWlkZGxld2FyZSA9IG9wdGlvbnMubWlkZGxld2FyZTsgLy8gdXNlIGFzLWlzIGxldCBleHByZXNzIGZhaWxcbiAgICAgIH1cbiAgICAgIGFwcC51c2UobWlkZGxld2FyZSk7XG4gICAgfVxuXG4gICAgYXBwLnVzZShvcHRpb25zLm1vdW50UGF0aCwgdGhpcy5hcHApO1xuXG4gICAgaWYgKG9wdGlvbnMubW91bnRHcmFwaFFMID09PSB0cnVlIHx8IG9wdGlvbnMubW91bnRQbGF5Z3JvdW5kID09PSB0cnVlKSB7XG4gICAgICBsZXQgZ3JhcGhRTEN1c3RvbVR5cGVEZWZzID0gdW5kZWZpbmVkO1xuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLmdyYXBoUUxTY2hlbWEgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGdyYXBoUUxDdXN0b21UeXBlRGVmcyA9IHBhcnNlKGZzLnJlYWRGaWxlU3luYyhvcHRpb25zLmdyYXBoUUxTY2hlbWEsICd1dGY4JykpO1xuICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgdHlwZW9mIG9wdGlvbnMuZ3JhcGhRTFNjaGVtYSA9PT0gJ29iamVjdCcgfHxcbiAgICAgICAgdHlwZW9mIG9wdGlvbnMuZ3JhcGhRTFNjaGVtYSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgKSB7XG4gICAgICAgIGdyYXBoUUxDdXN0b21UeXBlRGVmcyA9IG9wdGlvbnMuZ3JhcGhRTFNjaGVtYTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGFyc2VHcmFwaFFMU2VydmVyID0gbmV3IFBhcnNlR3JhcGhRTFNlcnZlcih0aGlzLCB7XG4gICAgICAgIGdyYXBoUUxQYXRoOiBvcHRpb25zLmdyYXBoUUxQYXRoLFxuICAgICAgICBwbGF5Z3JvdW5kUGF0aDogb3B0aW9ucy5wbGF5Z3JvdW5kUGF0aCxcbiAgICAgICAgZ3JhcGhRTEN1c3RvbVR5cGVEZWZzLFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChvcHRpb25zLm1vdW50R3JhcGhRTCkge1xuICAgICAgICBwYXJzZUdyYXBoUUxTZXJ2ZXIuYXBwbHlHcmFwaFFMKGFwcCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zLm1vdW50UGxheWdyb3VuZCkge1xuICAgICAgICBwYXJzZUdyYXBoUUxTZXJ2ZXIuYXBwbHlQbGF5Z3JvdW5kKGFwcCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgc2VydmVyID0gYXBwLmxpc3RlbihvcHRpb25zLnBvcnQsIG9wdGlvbnMuaG9zdCwgY2FsbGJhY2spO1xuICAgIHRoaXMuc2VydmVyID0gc2VydmVyO1xuXG4gICAgaWYgKG9wdGlvbnMuc3RhcnRMaXZlUXVlcnlTZXJ2ZXIgfHwgb3B0aW9ucy5saXZlUXVlcnlTZXJ2ZXJPcHRpb25zKSB7XG4gICAgICB0aGlzLmxpdmVRdWVyeVNlcnZlciA9IFBhcnNlU2VydmVyLmNyZWF0ZUxpdmVRdWVyeVNlcnZlcihcbiAgICAgICAgc2VydmVyLFxuICAgICAgICBvcHRpb25zLmxpdmVRdWVyeVNlcnZlck9wdGlvbnMsXG4gICAgICAgIG9wdGlvbnNcbiAgICAgICk7XG4gICAgfVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgaWYgKCFwcm9jZXNzLmVudi5URVNUSU5HKSB7XG4gICAgICBjb25maWd1cmVMaXN0ZW5lcnModGhpcyk7XG4gICAgfVxuICAgIHRoaXMuZXhwcmVzc0FwcCA9IGFwcDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IFBhcnNlU2VydmVyIGFuZCBzdGFydHMgaXQuXG4gICAqIEBwYXJhbSB7UGFyc2VTZXJ2ZXJPcHRpb25zfSBvcHRpb25zIHVzZWQgdG8gc3RhcnQgdGhlIHNlcnZlclxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBjYWxsZWQgd2hlbiB0aGUgc2VydmVyIGhhcyBzdGFydGVkXG4gICAqIEByZXR1cm5zIHtQYXJzZVNlcnZlcn0gdGhlIHBhcnNlIHNlcnZlciBpbnN0YW5jZVxuICAgKi9cbiAgc3RhdGljIHN0YXJ0KG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucywgY2FsbGJhY2s6ID8oKSA9PiB2b2lkKSB7XG4gICAgY29uc3QgcGFyc2VTZXJ2ZXIgPSBuZXcgUGFyc2VTZXJ2ZXIob3B0aW9ucyk7XG4gICAgcmV0dXJuIHBhcnNlU2VydmVyLnN0YXJ0KG9wdGlvbnMsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIZWxwZXIgbWV0aG9kIHRvIGNyZWF0ZSBhIGxpdmVRdWVyeSBzZXJ2ZXJcbiAgICogQHN0YXRpY1xuICAgKiBAcGFyYW0ge1NlcnZlcn0gaHR0cFNlcnZlciBhbiBvcHRpb25hbCBodHRwIHNlcnZlciB0byBwYXNzXG4gICAqIEBwYXJhbSB7TGl2ZVF1ZXJ5U2VydmVyT3B0aW9uc30gY29uZmlnIG9wdGlvbnMgZm9yIHRoZSBsaXZlUXVlcnlTZXJ2ZXJcbiAgICogQHBhcmFtIHtQYXJzZVNlcnZlck9wdGlvbnN9IG9wdGlvbnMgb3B0aW9ucyBmb3IgdGhlIFBhcnNlU2VydmVyXG4gICAqIEByZXR1cm5zIHtQYXJzZUxpdmVRdWVyeVNlcnZlcn0gdGhlIGxpdmUgcXVlcnkgc2VydmVyIGluc3RhbmNlXG4gICAqL1xuICBzdGF0aWMgY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyKFxuICAgIGh0dHBTZXJ2ZXIsXG4gICAgY29uZmlnOiBMaXZlUXVlcnlTZXJ2ZXJPcHRpb25zLFxuICAgIG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9uc1xuICApIHtcbiAgICBpZiAoIWh0dHBTZXJ2ZXIgfHwgKGNvbmZpZyAmJiBjb25maWcucG9ydCkpIHtcbiAgICAgIHZhciBhcHAgPSBleHByZXNzKCk7XG4gICAgICBodHRwU2VydmVyID0gcmVxdWlyZSgnaHR0cCcpLmNyZWF0ZVNlcnZlcihhcHApO1xuICAgICAgaHR0cFNlcnZlci5saXN0ZW4oY29uZmlnLnBvcnQpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFBhcnNlTGl2ZVF1ZXJ5U2VydmVyKGh0dHBTZXJ2ZXIsIGNvbmZpZywgb3B0aW9ucyk7XG4gIH1cblxuICBzdGF0aWMgdmVyaWZ5U2VydmVyVXJsKGNhbGxiYWNrKSB7XG4gICAgLy8gcGVyZm9ybSBhIGhlYWx0aCBjaGVjayBvbiB0aGUgc2VydmVyVVJMIHZhbHVlXG4gICAgaWYgKFBhcnNlLnNlcnZlclVSTCkge1xuICAgICAgY29uc3QgcmVxdWVzdCA9IHJlcXVpcmUoJy4vcmVxdWVzdCcpO1xuICAgICAgcmVxdWVzdCh7IHVybDogUGFyc2Uuc2VydmVyVVJMLnJlcGxhY2UoL1xcLyQvLCAnJykgKyAnL2hlYWx0aCcgfSlcbiAgICAgICAgLmNhdGNoKHJlc3BvbnNlID0+IHJlc3BvbnNlKVxuICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgY29uc3QganNvbiA9IHJlc3BvbnNlLmRhdGEgfHwgbnVsbDtcbiAgICAgICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzICE9PSAyMDAgfHwgIWpzb24gfHwgKGpzb24gJiYganNvbi5zdGF0dXMgIT09ICdvaycpKSB7XG4gICAgICAgICAgICAvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgIGBcXG5XQVJOSU5HLCBVbmFibGUgdG8gY29ubmVjdCB0byAnJHtQYXJzZS5zZXJ2ZXJVUkx9Jy5gICtcbiAgICAgICAgICAgICAgICBgIENsb3VkIGNvZGUgYW5kIHB1c2ggbm90aWZpY2F0aW9ucyBtYXkgYmUgdW5hdmFpbGFibGUhXFxuYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIC8qIGVzbGludC1lbmFibGUgbm8tY29uc29sZSAqL1xuICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrKGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrKHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGFkZFBhcnNlQ2xvdWQoKSB7XG4gIGNvbnN0IFBhcnNlQ2xvdWQgPSByZXF1aXJlKCcuL2Nsb3VkLWNvZGUvUGFyc2UuQ2xvdWQnKTtcbiAgT2JqZWN0LmFzc2lnbihQYXJzZS5DbG91ZCwgUGFyc2VDbG91ZCk7XG4gIGdsb2JhbC5QYXJzZSA9IFBhcnNlO1xufVxuXG5mdW5jdGlvbiBpbmplY3REZWZhdWx0cyhvcHRpb25zOiBQYXJzZVNlcnZlck9wdGlvbnMpIHtcbiAgT2JqZWN0LmtleXMoZGVmYXVsdHMpLmZvckVhY2goa2V5ID0+IHtcbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvcHRpb25zLCBrZXkpKSB7XG4gICAgICBvcHRpb25zW2tleV0gPSBkZWZhdWx0c1trZXldO1xuICAgIH1cbiAgfSk7XG5cbiAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob3B0aW9ucywgJ3NlcnZlclVSTCcpKSB7XG4gICAgb3B0aW9ucy5zZXJ2ZXJVUkwgPSBgaHR0cDovL2xvY2FsaG9zdDoke29wdGlvbnMucG9ydH0ke29wdGlvbnMubW91bnRQYXRofWA7XG4gIH1cblxuICAvLyBSZXNlcnZlZCBDaGFyYWN0ZXJzXG4gIGlmIChvcHRpb25zLmFwcElkKSB7XG4gICAgY29uc3QgcmVnZXggPSAvWyEjJCUnKCkqKyYvOjs9P0BbXFxde31eLHw8Pl0vZztcbiAgICBpZiAob3B0aW9ucy5hcHBJZC5tYXRjaChyZWdleCkpIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYFxcbldBUk5JTkcsIGFwcElkIHRoYXQgY29udGFpbnMgc3BlY2lhbCBjaGFyYWN0ZXJzIGNhbiBjYXVzZSBpc3N1ZXMgd2hpbGUgdXNpbmcgd2l0aCB1cmxzLlxcbmBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLy8gQmFja3dhcmRzIGNvbXBhdGliaWxpdHlcbiAgaWYgKG9wdGlvbnMudXNlclNlbnNpdGl2ZUZpZWxkcykge1xuICAgIC8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbiAgICAhcHJvY2Vzcy5lbnYuVEVTVElORyAmJlxuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBgXFxuREVQUkVDQVRFRDogdXNlclNlbnNpdGl2ZUZpZWxkcyBoYXMgYmVlbiByZXBsYWNlZCBieSBwcm90ZWN0ZWRGaWVsZHMgYWxsb3dpbmcgdGhlIGFiaWxpdHkgdG8gcHJvdGVjdCBmaWVsZHMgaW4gYWxsIGNsYXNzZXMgd2l0aCBDTFAuIFxcbmBcbiAgICAgICk7XG4gICAgLyogZXNsaW50LWVuYWJsZSBuby1jb25zb2xlICovXG5cbiAgICBjb25zdCB1c2VyU2Vuc2l0aXZlRmllbGRzID0gQXJyYXkuZnJvbShcbiAgICAgIG5ldyBTZXQoWy4uLihkZWZhdWx0cy51c2VyU2Vuc2l0aXZlRmllbGRzIHx8IFtdKSwgLi4uKG9wdGlvbnMudXNlclNlbnNpdGl2ZUZpZWxkcyB8fCBbXSldKVxuICAgICk7XG5cbiAgICAvLyBJZiB0aGUgb3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHMgaXMgdW5zZXQsXG4gICAgLy8gaXQnbGwgYmUgYXNzaWduZWQgdGhlIGRlZmF1bHQgYWJvdmUuXG4gICAgLy8gSGVyZSwgcHJvdGVjdCBhZ2FpbnN0IHRoZSBjYXNlIHdoZXJlIHByb3RlY3RlZEZpZWxkc1xuICAgIC8vIGlzIHNldCwgYnV0IGRvZXNuJ3QgaGF2ZSBfVXNlci5cbiAgICBpZiAoISgnX1VzZXInIGluIG9wdGlvbnMucHJvdGVjdGVkRmllbGRzKSkge1xuICAgICAgb3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHMgPSBPYmplY3QuYXNzaWduKHsgX1VzZXI6IFtdIH0sIG9wdGlvbnMucHJvdGVjdGVkRmllbGRzKTtcbiAgICB9XG5cbiAgICBvcHRpb25zLnByb3RlY3RlZEZpZWxkc1snX1VzZXInXVsnKiddID0gQXJyYXkuZnJvbShcbiAgICAgIG5ldyBTZXQoWy4uLihvcHRpb25zLnByb3RlY3RlZEZpZWxkc1snX1VzZXInXVsnKiddIHx8IFtdKSwgLi4udXNlclNlbnNpdGl2ZUZpZWxkc10pXG4gICAgKTtcbiAgfVxuXG4gIC8vIE1lcmdlIHByb3RlY3RlZEZpZWxkcyBvcHRpb25zIHdpdGggZGVmYXVsdHMuXG4gIE9iamVjdC5rZXlzKGRlZmF1bHRzLnByb3RlY3RlZEZpZWxkcykuZm9yRWFjaChjID0+IHtcbiAgICBjb25zdCBjdXIgPSBvcHRpb25zLnByb3RlY3RlZEZpZWxkc1tjXTtcbiAgICBpZiAoIWN1cikge1xuICAgICAgb3B0aW9ucy5wcm90ZWN0ZWRGaWVsZHNbY10gPSBkZWZhdWx0cy5wcm90ZWN0ZWRGaWVsZHNbY107XG4gICAgfSBlbHNlIHtcbiAgICAgIE9iamVjdC5rZXlzKGRlZmF1bHRzLnByb3RlY3RlZEZpZWxkc1tjXSkuZm9yRWFjaChyID0+IHtcbiAgICAgICAgY29uc3QgdW5xID0gbmV3IFNldChbXG4gICAgICAgICAgLi4uKG9wdGlvbnMucHJvdGVjdGVkRmllbGRzW2NdW3JdIHx8IFtdKSxcbiAgICAgICAgICAuLi5kZWZhdWx0cy5wcm90ZWN0ZWRGaWVsZHNbY11bcl0sXG4gICAgICAgIF0pO1xuICAgICAgICBvcHRpb25zLnByb3RlY3RlZEZpZWxkc1tjXVtyXSA9IEFycmF5LmZyb20odW5xKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgb3B0aW9ucy5tYXN0ZXJLZXlJcHMgPSBBcnJheS5mcm9tKFxuICAgIG5ldyBTZXQob3B0aW9ucy5tYXN0ZXJLZXlJcHMuY29uY2F0KGRlZmF1bHRzLm1hc3RlcktleUlwcywgb3B0aW9ucy5tYXN0ZXJLZXlJcHMpKVxuICApO1xufVxuXG4vLyBUaG9zZSBjYW4ndCBiZSB0ZXN0ZWQgYXMgaXQgcmVxdWlyZXMgYSBzdWJwcm9jZXNzXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuZnVuY3Rpb24gY29uZmlndXJlTGlzdGVuZXJzKHBhcnNlU2VydmVyKSB7XG4gIGNvbnN0IHNlcnZlciA9IHBhcnNlU2VydmVyLnNlcnZlcjtcbiAgY29uc3Qgc29ja2V0cyA9IHt9O1xuICAvKiBDdXJyZW50bHksIGV4cHJlc3MgZG9lc24ndCBzaHV0IGRvd24gaW1tZWRpYXRlbHkgYWZ0ZXIgcmVjZWl2aW5nIFNJR0lOVC9TSUdURVJNIGlmIGl0IGhhcyBjbGllbnQgY29ubmVjdGlvbnMgdGhhdCBoYXZlbid0IHRpbWVkIG91dC4gKFRoaXMgaXMgYSBrbm93biBpc3N1ZSB3aXRoIG5vZGUgLSBodHRwczovL2dpdGh1Yi5jb20vbm9kZWpzL25vZGUvaXNzdWVzLzI2NDIpXG4gICAgVGhpcyBmdW5jdGlvbiwgYWxvbmcgd2l0aCBgZGVzdHJveUFsaXZlQ29ubmVjdGlvbnMoKWAsIGludGVuZCB0byBmaXggdGhpcyBiZWhhdmlvciBzdWNoIHRoYXQgcGFyc2Ugc2VydmVyIHdpbGwgY2xvc2UgYWxsIG9wZW4gY29ubmVjdGlvbnMgYW5kIGluaXRpYXRlIHRoZSBzaHV0ZG93biBwcm9jZXNzIGFzIHNvb24gYXMgaXQgcmVjZWl2ZXMgYSBTSUdJTlQvU0lHVEVSTSBzaWduYWwuICovXG4gIHNlcnZlci5vbignY29ubmVjdGlvbicsIHNvY2tldCA9PiB7XG4gICAgY29uc3Qgc29ja2V0SWQgPSBzb2NrZXQucmVtb3RlQWRkcmVzcyArICc6JyArIHNvY2tldC5yZW1vdGVQb3J0O1xuICAgIHNvY2tldHNbc29ja2V0SWRdID0gc29ja2V0O1xuICAgIHNvY2tldC5vbignY2xvc2UnLCAoKSA9PiB7XG4gICAgICBkZWxldGUgc29ja2V0c1tzb2NrZXRJZF07XG4gICAgfSk7XG4gIH0pO1xuXG4gIGNvbnN0IGRlc3Ryb3lBbGl2ZUNvbm5lY3Rpb25zID0gZnVuY3Rpb24gKCkge1xuICAgIGZvciAoY29uc3Qgc29ja2V0SWQgaW4gc29ja2V0cykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgc29ja2V0c1tzb2NrZXRJZF0uZGVzdHJveSgpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAvKiAqL1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBjb25zdCBoYW5kbGVTaHV0ZG93biA9IGZ1bmN0aW9uICgpIHtcbiAgICBwcm9jZXNzLnN0ZG91dC53cml0ZSgnVGVybWluYXRpb24gc2lnbmFsIHJlY2VpdmVkLiBTaHV0dGluZyBkb3duLicpO1xuICAgIGRlc3Ryb3lBbGl2ZUNvbm5lY3Rpb25zKCk7XG4gICAgc2VydmVyLmNsb3NlKCk7XG4gICAgcGFyc2VTZXJ2ZXIuaGFuZGxlU2h1dGRvd24oKTtcbiAgfTtcbiAgcHJvY2Vzcy5vbignU0lHVEVSTScsIGhhbmRsZVNodXRkb3duKTtcbiAgcHJvY2Vzcy5vbignU0lHSU5UJywgaGFuZGxlU2h1dGRvd24pO1xufVxuXG5leHBvcnQgZGVmYXVsdCBQYXJzZVNlcnZlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/ParseServerRESTController.js b/lib/ParseServerRESTController.js deleted file mode 100644 index 9602de13a6..0000000000 --- a/lib/ParseServerRESTController.js +++ /dev/null @@ -1,184 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.ParseServerRESTController = ParseServerRESTController; -exports.default = void 0; - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const Config = require('./Config'); - -const Auth = require('./Auth'); - -const RESTController = require('parse/lib/node/RESTController'); - -const URL = require('url'); - -const Parse = require('parse/node'); - -function getSessionToken(options) { - if (options && typeof options.sessionToken === 'string') { - return Promise.resolve(options.sessionToken); - } - - return Promise.resolve(null); -} - -function getAuth(options = {}, config) { - const installationId = options.installationId || 'cloud'; - - if (options.useMasterKey) { - return Promise.resolve(new Auth.Auth({ - config, - isMaster: true, - installationId - })); - } - - return getSessionToken(options).then(sessionToken => { - if (sessionToken) { - options.sessionToken = sessionToken; - return Auth.getAuthForSessionToken({ - config, - sessionToken: sessionToken, - installationId - }); - } else { - return Promise.resolve(new Auth.Auth({ - config, - installationId - })); - } - }); -} - -function ParseServerRESTController(applicationId, router) { - function handleRequest(method, path, data = {}, options = {}, config) { - // Store the arguments, for later use if internal fails - const args = arguments; - - if (!config) { - config = Config.get(applicationId); - } - - const serverURL = URL.parse(config.serverURL); - - if (path.indexOf(serverURL.path) === 0) { - path = path.slice(serverURL.path.length, path.length); - } - - if (path[0] !== '/') { - path = '/' + path; - } - - if (path === '/batch') { - let initialPromise = Promise.resolve(); - - if (data.transaction === true) { - initialPromise = config.database.createTransactionalSession(); - } - - return initialPromise.then(() => { - const promises = data.requests.map(request => { - return handleRequest(request.method, request.path, request.body, options, config).then(response => { - if (options.returnStatus) { - const status = response._status; - delete response._status; - return { - success: response, - _status: status - }; - } - - return { - success: response - }; - }, error => { - return { - error: { - code: error.code, - error: error.message - } - }; - }); - }); - return Promise.all(promises).then(result => { - if (data.transaction === true) { - if (result.find(resultItem => typeof resultItem.error === 'object')) { - return config.database.abortTransactionalSession().then(() => { - return Promise.reject(result); - }); - } else { - return config.database.commitTransactionalSession().then(() => { - return result; - }); - } - } else { - return result; - } - }); - }); - } - - let query; - - if (method === 'GET') { - query = data; - } - - return new Promise((resolve, reject) => { - getAuth(options, config).then(auth => { - const request = { - body: data, - config, - auth, - info: { - applicationId: applicationId, - sessionToken: options.sessionToken, - installationId: options.installationId, - context: options.context || {} // Add context - - }, - query - }; - return Promise.resolve().then(() => { - return router.tryRouteRequest(method, path, request); - }).then(resp => { - const { - response, - status - } = resp; - - if (options.returnStatus) { - resolve(_objectSpread(_objectSpread({}, response), {}, { - _status: status - })); - } else { - resolve(response); - } - }, err => { - if (err instanceof Parse.Error && err.code == Parse.Error.INVALID_JSON && err.message == `cannot route ${method} ${path}`) { - RESTController.request.apply(null, args).then(resolve, reject); - } else { - reject(err); - } - }); - }, reject); - }); - } - - return { - request: handleRequest, - ajax: RESTController.ajax - }; -} - -var _default = ParseServerRESTController; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9QYXJzZVNlcnZlclJFU1RDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIkNvbmZpZyIsInJlcXVpcmUiLCJBdXRoIiwiUkVTVENvbnRyb2xsZXIiLCJVUkwiLCJQYXJzZSIsImdldFNlc3Npb25Ub2tlbiIsIm9wdGlvbnMiLCJzZXNzaW9uVG9rZW4iLCJQcm9taXNlIiwicmVzb2x2ZSIsImdldEF1dGgiLCJjb25maWciLCJpbnN0YWxsYXRpb25JZCIsInVzZU1hc3RlcktleSIsImlzTWFzdGVyIiwidGhlbiIsImdldEF1dGhGb3JTZXNzaW9uVG9rZW4iLCJQYXJzZVNlcnZlclJFU1RDb250cm9sbGVyIiwiYXBwbGljYXRpb25JZCIsInJvdXRlciIsImhhbmRsZVJlcXVlc3QiLCJtZXRob2QiLCJwYXRoIiwiZGF0YSIsImFyZ3MiLCJhcmd1bWVudHMiLCJnZXQiLCJzZXJ2ZXJVUkwiLCJwYXJzZSIsImluZGV4T2YiLCJzbGljZSIsImxlbmd0aCIsImluaXRpYWxQcm9taXNlIiwidHJhbnNhY3Rpb24iLCJkYXRhYmFzZSIsImNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uIiwicHJvbWlzZXMiLCJyZXF1ZXN0cyIsIm1hcCIsInJlcXVlc3QiLCJib2R5IiwicmVzcG9uc2UiLCJyZXR1cm5TdGF0dXMiLCJzdGF0dXMiLCJfc3RhdHVzIiwic3VjY2VzcyIsImVycm9yIiwiY29kZSIsIm1lc3NhZ2UiLCJhbGwiLCJyZXN1bHQiLCJmaW5kIiwicmVzdWx0SXRlbSIsImFib3J0VHJhbnNhY3Rpb25hbFNlc3Npb24iLCJyZWplY3QiLCJjb21taXRUcmFuc2FjdGlvbmFsU2Vzc2lvbiIsInF1ZXJ5IiwiYXV0aCIsImluZm8iLCJjb250ZXh0IiwidHJ5Um91dGVSZXF1ZXN0IiwicmVzcCIsImVyciIsIkVycm9yIiwiSU5WQUxJRF9KU09OIiwiYXBwbHkiLCJhamF4Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQUFBLE1BQU1BLE1BQU0sR0FBR0MsT0FBTyxDQUFDLFVBQUQsQ0FBdEI7O0FBQ0EsTUFBTUMsSUFBSSxHQUFHRCxPQUFPLENBQUMsUUFBRCxDQUFwQjs7QUFDQSxNQUFNRSxjQUFjLEdBQUdGLE9BQU8sQ0FBQywrQkFBRCxDQUE5Qjs7QUFDQSxNQUFNRyxHQUFHLEdBQUdILE9BQU8sQ0FBQyxLQUFELENBQW5COztBQUNBLE1BQU1JLEtBQUssR0FBR0osT0FBTyxDQUFDLFlBQUQsQ0FBckI7O0FBRUEsU0FBU0ssZUFBVCxDQUF5QkMsT0FBekIsRUFBa0M7QUFDaEMsTUFBSUEsT0FBTyxJQUFJLE9BQU9BLE9BQU8sQ0FBQ0MsWUFBZixLQUFnQyxRQUEvQyxFQUF5RDtBQUN2RCxXQUFPQyxPQUFPLENBQUNDLE9BQVIsQ0FBZ0JILE9BQU8sQ0FBQ0MsWUFBeEIsQ0FBUDtBQUNEOztBQUNELFNBQU9DLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQixJQUFoQixDQUFQO0FBQ0Q7O0FBRUQsU0FBU0MsT0FBVCxDQUFpQkosT0FBTyxHQUFHLEVBQTNCLEVBQStCSyxNQUEvQixFQUF1QztBQUNyQyxRQUFNQyxjQUFjLEdBQUdOLE9BQU8sQ0FBQ00sY0FBUixJQUEwQixPQUFqRDs7QUFDQSxNQUFJTixPQUFPLENBQUNPLFlBQVosRUFBMEI7QUFDeEIsV0FBT0wsT0FBTyxDQUFDQyxPQUFSLENBQWdCLElBQUlSLElBQUksQ0FBQ0EsSUFBVCxDQUFjO0FBQUVVLE1BQUFBLE1BQUY7QUFBVUcsTUFBQUEsUUFBUSxFQUFFLElBQXBCO0FBQTBCRixNQUFBQTtBQUExQixLQUFkLENBQWhCLENBQVA7QUFDRDs7QUFDRCxTQUFPUCxlQUFlLENBQUNDLE9BQUQsQ0FBZixDQUF5QlMsSUFBekIsQ0FBOEJSLFlBQVksSUFBSTtBQUNuRCxRQUFJQSxZQUFKLEVBQWtCO0FBQ2hCRCxNQUFBQSxPQUFPLENBQUNDLFlBQVIsR0FBdUJBLFlBQXZCO0FBQ0EsYUFBT04sSUFBSSxDQUFDZSxzQkFBTCxDQUE0QjtBQUNqQ0wsUUFBQUEsTUFEaUM7QUFFakNKLFFBQUFBLFlBQVksRUFBRUEsWUFGbUI7QUFHakNLLFFBQUFBO0FBSGlDLE9BQTVCLENBQVA7QUFLRCxLQVBELE1BT087QUFDTCxhQUFPSixPQUFPLENBQUNDLE9BQVIsQ0FBZ0IsSUFBSVIsSUFBSSxDQUFDQSxJQUFULENBQWM7QUFBRVUsUUFBQUEsTUFBRjtBQUFVQyxRQUFBQTtBQUFWLE9BQWQsQ0FBaEIsQ0FBUDtBQUNEO0FBQ0YsR0FYTSxDQUFQO0FBWUQ7O0FBRUQsU0FBU0sseUJBQVQsQ0FBbUNDLGFBQW5DLEVBQWtEQyxNQUFsRCxFQUEwRDtBQUN4RCxXQUFTQyxhQUFULENBQXVCQyxNQUF2QixFQUErQkMsSUFBL0IsRUFBcUNDLElBQUksR0FBRyxFQUE1QyxFQUFnRGpCLE9BQU8sR0FBRyxFQUExRCxFQUE4REssTUFBOUQsRUFBc0U7QUFDcEU7QUFDQSxVQUFNYSxJQUFJLEdBQUdDLFNBQWI7O0FBRUEsUUFBSSxDQUFDZCxNQUFMLEVBQWE7QUFDWEEsTUFBQUEsTUFBTSxHQUFHWixNQUFNLENBQUMyQixHQUFQLENBQVdSLGFBQVgsQ0FBVDtBQUNEOztBQUNELFVBQU1TLFNBQVMsR0FBR3hCLEdBQUcsQ0FBQ3lCLEtBQUosQ0FBVWpCLE1BQU0sQ0FBQ2dCLFNBQWpCLENBQWxCOztBQUNBLFFBQUlMLElBQUksQ0FBQ08sT0FBTCxDQUFhRixTQUFTLENBQUNMLElBQXZCLE1BQWlDLENBQXJDLEVBQXdDO0FBQ3RDQSxNQUFBQSxJQUFJLEdBQUdBLElBQUksQ0FBQ1EsS0FBTCxDQUFXSCxTQUFTLENBQUNMLElBQVYsQ0FBZVMsTUFBMUIsRUFBa0NULElBQUksQ0FBQ1MsTUFBdkMsQ0FBUDtBQUNEOztBQUVELFFBQUlULElBQUksQ0FBQyxDQUFELENBQUosS0FBWSxHQUFoQixFQUFxQjtBQUNuQkEsTUFBQUEsSUFBSSxHQUFHLE1BQU1BLElBQWI7QUFDRDs7QUFFRCxRQUFJQSxJQUFJLEtBQUssUUFBYixFQUF1QjtBQUNyQixVQUFJVSxjQUFjLEdBQUd4QixPQUFPLENBQUNDLE9BQVIsRUFBckI7O0FBQ0EsVUFBSWMsSUFBSSxDQUFDVSxXQUFMLEtBQXFCLElBQXpCLEVBQStCO0FBQzdCRCxRQUFBQSxjQUFjLEdBQUdyQixNQUFNLENBQUN1QixRQUFQLENBQWdCQywwQkFBaEIsRUFBakI7QUFDRDs7QUFDRCxhQUFPSCxjQUFjLENBQUNqQixJQUFmLENBQW9CLE1BQU07QUFDL0IsY0FBTXFCLFFBQVEsR0FBR2IsSUFBSSxDQUFDYyxRQUFMLENBQWNDLEdBQWQsQ0FBa0JDLE9BQU8sSUFBSTtBQUM1QyxpQkFBT25CLGFBQWEsQ0FBQ21CLE9BQU8sQ0FBQ2xCLE1BQVQsRUFBaUJrQixPQUFPLENBQUNqQixJQUF6QixFQUErQmlCLE9BQU8sQ0FBQ0MsSUFBdkMsRUFBNkNsQyxPQUE3QyxFQUFzREssTUFBdEQsQ0FBYixDQUEyRUksSUFBM0UsQ0FDTDBCLFFBQVEsSUFBSTtBQUNWLGdCQUFJbkMsT0FBTyxDQUFDb0MsWUFBWixFQUEwQjtBQUN4QixvQkFBTUMsTUFBTSxHQUFHRixRQUFRLENBQUNHLE9BQXhCO0FBQ0EscUJBQU9ILFFBQVEsQ0FBQ0csT0FBaEI7QUFDQSxxQkFBTztBQUFFQyxnQkFBQUEsT0FBTyxFQUFFSixRQUFYO0FBQXFCRyxnQkFBQUEsT0FBTyxFQUFFRDtBQUE5QixlQUFQO0FBQ0Q7O0FBQ0QsbUJBQU87QUFBRUUsY0FBQUEsT0FBTyxFQUFFSjtBQUFYLGFBQVA7QUFDRCxXQVJJLEVBU0xLLEtBQUssSUFBSTtBQUNQLG1CQUFPO0FBQ0xBLGNBQUFBLEtBQUssRUFBRTtBQUFFQyxnQkFBQUEsSUFBSSxFQUFFRCxLQUFLLENBQUNDLElBQWQ7QUFBb0JELGdCQUFBQSxLQUFLLEVBQUVBLEtBQUssQ0FBQ0U7QUFBakM7QUFERixhQUFQO0FBR0QsV0FiSSxDQUFQO0FBZUQsU0FoQmdCLENBQWpCO0FBaUJBLGVBQU94QyxPQUFPLENBQUN5QyxHQUFSLENBQVliLFFBQVosRUFBc0JyQixJQUF0QixDQUEyQm1DLE1BQU0sSUFBSTtBQUMxQyxjQUFJM0IsSUFBSSxDQUFDVSxXQUFMLEtBQXFCLElBQXpCLEVBQStCO0FBQzdCLGdCQUFJaUIsTUFBTSxDQUFDQyxJQUFQLENBQVlDLFVBQVUsSUFBSSxPQUFPQSxVQUFVLENBQUNOLEtBQWxCLEtBQTRCLFFBQXRELENBQUosRUFBcUU7QUFDbkUscUJBQU9uQyxNQUFNLENBQUN1QixRQUFQLENBQWdCbUIseUJBQWhCLEdBQTRDdEMsSUFBNUMsQ0FBaUQsTUFBTTtBQUM1RCx1QkFBT1AsT0FBTyxDQUFDOEMsTUFBUixDQUFlSixNQUFmLENBQVA7QUFDRCxlQUZNLENBQVA7QUFHRCxhQUpELE1BSU87QUFDTCxxQkFBT3ZDLE1BQU0sQ0FBQ3VCLFFBQVAsQ0FBZ0JxQiwwQkFBaEIsR0FBNkN4QyxJQUE3QyxDQUFrRCxNQUFNO0FBQzdELHVCQUFPbUMsTUFBUDtBQUNELGVBRk0sQ0FBUDtBQUdEO0FBQ0YsV0FWRCxNQVVPO0FBQ0wsbUJBQU9BLE1BQVA7QUFDRDtBQUNGLFNBZE0sQ0FBUDtBQWVELE9BakNNLENBQVA7QUFrQ0Q7O0FBRUQsUUFBSU0sS0FBSjs7QUFDQSxRQUFJbkMsTUFBTSxLQUFLLEtBQWYsRUFBc0I7QUFDcEJtQyxNQUFBQSxLQUFLLEdBQUdqQyxJQUFSO0FBQ0Q7O0FBRUQsV0FBTyxJQUFJZixPQUFKLENBQVksQ0FBQ0MsT0FBRCxFQUFVNkMsTUFBVixLQUFxQjtBQUN0QzVDLE1BQUFBLE9BQU8sQ0FBQ0osT0FBRCxFQUFVSyxNQUFWLENBQVAsQ0FBeUJJLElBQXpCLENBQThCMEMsSUFBSSxJQUFJO0FBQ3BDLGNBQU1sQixPQUFPLEdBQUc7QUFDZEMsVUFBQUEsSUFBSSxFQUFFakIsSUFEUTtBQUVkWixVQUFBQSxNQUZjO0FBR2Q4QyxVQUFBQSxJQUhjO0FBSWRDLFVBQUFBLElBQUksRUFBRTtBQUNKeEMsWUFBQUEsYUFBYSxFQUFFQSxhQURYO0FBRUpYLFlBQUFBLFlBQVksRUFBRUQsT0FBTyxDQUFDQyxZQUZsQjtBQUdKSyxZQUFBQSxjQUFjLEVBQUVOLE9BQU8sQ0FBQ00sY0FIcEI7QUFJSitDLFlBQUFBLE9BQU8sRUFBRXJELE9BQU8sQ0FBQ3FELE9BQVIsSUFBbUIsRUFKeEIsQ0FJNEI7O0FBSjVCLFdBSlE7QUFVZEgsVUFBQUE7QUFWYyxTQUFoQjtBQVlBLGVBQU9oRCxPQUFPLENBQUNDLE9BQVIsR0FDSk0sSUFESSxDQUNDLE1BQU07QUFDVixpQkFBT0ksTUFBTSxDQUFDeUMsZUFBUCxDQUF1QnZDLE1BQXZCLEVBQStCQyxJQUEvQixFQUFxQ2lCLE9BQXJDLENBQVA7QUFDRCxTQUhJLEVBSUp4QixJQUpJLENBS0g4QyxJQUFJLElBQUk7QUFDTixnQkFBTTtBQUFFcEIsWUFBQUEsUUFBRjtBQUFZRSxZQUFBQTtBQUFaLGNBQXVCa0IsSUFBN0I7O0FBQ0EsY0FBSXZELE9BQU8sQ0FBQ29DLFlBQVosRUFBMEI7QUFDeEJqQyxZQUFBQSxPQUFPLGlDQUFNZ0MsUUFBTjtBQUFnQkcsY0FBQUEsT0FBTyxFQUFFRDtBQUF6QixlQUFQO0FBQ0QsV0FGRCxNQUVPO0FBQ0xsQyxZQUFBQSxPQUFPLENBQUNnQyxRQUFELENBQVA7QUFDRDtBQUNGLFNBWkUsRUFhSHFCLEdBQUcsSUFBSTtBQUNMLGNBQ0VBLEdBQUcsWUFBWTFELEtBQUssQ0FBQzJELEtBQXJCLElBQ0FELEdBQUcsQ0FBQ2YsSUFBSixJQUFZM0MsS0FBSyxDQUFDMkQsS0FBTixDQUFZQyxZQUR4QixJQUVBRixHQUFHLENBQUNkLE9BQUosSUFBZ0IsZ0JBQWUzQixNQUFPLElBQUdDLElBQUssRUFIaEQsRUFJRTtBQUNBcEIsWUFBQUEsY0FBYyxDQUFDcUMsT0FBZixDQUF1QjBCLEtBQXZCLENBQTZCLElBQTdCLEVBQW1DekMsSUFBbkMsRUFBeUNULElBQXpDLENBQThDTixPQUE5QyxFQUF1RDZDLE1BQXZEO0FBQ0QsV0FORCxNQU1PO0FBQ0xBLFlBQUFBLE1BQU0sQ0FBQ1EsR0FBRCxDQUFOO0FBQ0Q7QUFDRixTQXZCRSxDQUFQO0FBeUJELE9BdENELEVBc0NHUixNQXRDSDtBQXVDRCxLQXhDTSxDQUFQO0FBeUNEOztBQUVELFNBQU87QUFDTGYsSUFBQUEsT0FBTyxFQUFFbkIsYUFESjtBQUVMOEMsSUFBQUEsSUFBSSxFQUFFaEUsY0FBYyxDQUFDZ0U7QUFGaEIsR0FBUDtBQUlEOztlQUVjakQseUIiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBDb25maWcgPSByZXF1aXJlKCcuL0NvbmZpZycpO1xuY29uc3QgQXV0aCA9IHJlcXVpcmUoJy4vQXV0aCcpO1xuY29uc3QgUkVTVENvbnRyb2xsZXIgPSByZXF1aXJlKCdwYXJzZS9saWIvbm9kZS9SRVNUQ29udHJvbGxlcicpO1xuY29uc3QgVVJMID0gcmVxdWlyZSgndXJsJyk7XG5jb25zdCBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKTtcblxuZnVuY3Rpb24gZ2V0U2Vzc2lvblRva2VuKG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgJiYgdHlwZW9mIG9wdGlvbnMuc2Vzc2lvblRva2VuID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUob3B0aW9ucy5zZXNzaW9uVG9rZW4pO1xuICB9XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUobnVsbCk7XG59XG5cbmZ1bmN0aW9uIGdldEF1dGgob3B0aW9ucyA9IHt9LCBjb25maWcpIHtcbiAgY29uc3QgaW5zdGFsbGF0aW9uSWQgPSBvcHRpb25zLmluc3RhbGxhdGlvbklkIHx8ICdjbG91ZCc7XG4gIGlmIChvcHRpb25zLnVzZU1hc3RlcktleSkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IEF1dGguQXV0aCh7IGNvbmZpZywgaXNNYXN0ZXI6IHRydWUsIGluc3RhbGxhdGlvbklkIH0pKTtcbiAgfVxuICByZXR1cm4gZ2V0U2Vzc2lvblRva2VuKG9wdGlvbnMpLnRoZW4oc2Vzc2lvblRva2VuID0+IHtcbiAgICBpZiAoc2Vzc2lvblRva2VuKSB7XG4gICAgICBvcHRpb25zLnNlc3Npb25Ub2tlbiA9IHNlc3Npb25Ub2tlbjtcbiAgICAgIHJldHVybiBBdXRoLmdldEF1dGhGb3JTZXNzaW9uVG9rZW4oe1xuICAgICAgICBjb25maWcsXG4gICAgICAgIHNlc3Npb25Ub2tlbjogc2Vzc2lvblRva2VuLFxuICAgICAgICBpbnN0YWxsYXRpb25JZCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBBdXRoLkF1dGgoeyBjb25maWcsIGluc3RhbGxhdGlvbklkIH0pKTtcbiAgICB9XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBQYXJzZVNlcnZlclJFU1RDb250cm9sbGVyKGFwcGxpY2F0aW9uSWQsIHJvdXRlcikge1xuICBmdW5jdGlvbiBoYW5kbGVSZXF1ZXN0KG1ldGhvZCwgcGF0aCwgZGF0YSA9IHt9LCBvcHRpb25zID0ge30sIGNvbmZpZykge1xuICAgIC8vIFN0b3JlIHRoZSBhcmd1bWVudHMsIGZvciBsYXRlciB1c2UgaWYgaW50ZXJuYWwgZmFpbHNcbiAgICBjb25zdCBhcmdzID0gYXJndW1lbnRzO1xuXG4gICAgaWYgKCFjb25maWcpIHtcbiAgICAgIGNvbmZpZyA9IENvbmZpZy5nZXQoYXBwbGljYXRpb25JZCk7XG4gICAgfVxuICAgIGNvbnN0IHNlcnZlclVSTCA9IFVSTC5wYXJzZShjb25maWcuc2VydmVyVVJMKTtcbiAgICBpZiAocGF0aC5pbmRleE9mKHNlcnZlclVSTC5wYXRoKSA9PT0gMCkge1xuICAgICAgcGF0aCA9IHBhdGguc2xpY2Uoc2VydmVyVVJMLnBhdGgubGVuZ3RoLCBwYXRoLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgaWYgKHBhdGhbMF0gIT09ICcvJykge1xuICAgICAgcGF0aCA9ICcvJyArIHBhdGg7XG4gICAgfVxuXG4gICAgaWYgKHBhdGggPT09ICcvYmF0Y2gnKSB7XG4gICAgICBsZXQgaW5pdGlhbFByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgIGlmIChkYXRhLnRyYW5zYWN0aW9uID09PSB0cnVlKSB7XG4gICAgICAgIGluaXRpYWxQcm9taXNlID0gY29uZmlnLmRhdGFiYXNlLmNyZWF0ZVRyYW5zYWN0aW9uYWxTZXNzaW9uKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gaW5pdGlhbFByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gZGF0YS5yZXF1ZXN0cy5tYXAocmVxdWVzdCA9PiB7XG4gICAgICAgICAgcmV0dXJuIGhhbmRsZVJlcXVlc3QocmVxdWVzdC5tZXRob2QsIHJlcXVlc3QucGF0aCwgcmVxdWVzdC5ib2R5LCBvcHRpb25zLCBjb25maWcpLnRoZW4oXG4gICAgICAgICAgICByZXNwb25zZSA9PiB7XG4gICAgICAgICAgICAgIGlmIChvcHRpb25zLnJldHVyblN0YXR1cykge1xuICAgICAgICAgICAgICAgIGNvbnN0IHN0YXR1cyA9IHJlc3BvbnNlLl9zdGF0dXM7XG4gICAgICAgICAgICAgICAgZGVsZXRlIHJlc3BvbnNlLl9zdGF0dXM7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogcmVzcG9uc2UsIF9zdGF0dXM6IHN0YXR1cyB9O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHJlc3BvbnNlIH07XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXJyb3IgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGVycm9yOiB7IGNvZGU6IGVycm9yLmNvZGUsIGVycm9yOiBlcnJvci5tZXNzYWdlIH0sXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIGlmIChkYXRhLnRyYW5zYWN0aW9uID09PSB0cnVlKSB7XG4gICAgICAgICAgICBpZiAocmVzdWx0LmZpbmQocmVzdWx0SXRlbSA9PiB0eXBlb2YgcmVzdWx0SXRlbS5lcnJvciA9PT0gJ29iamVjdCcpKSB7XG4gICAgICAgICAgICAgIHJldHVybiBjb25maWcuZGF0YWJhc2UuYWJvcnRUcmFuc2FjdGlvbmFsU2Vzc2lvbigpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChyZXN1bHQpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBjb25maWcuZGF0YWJhc2UuY29tbWl0VHJhbnNhY3Rpb25hbFNlc3Npb24oKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgbGV0IHF1ZXJ5O1xuICAgIGlmIChtZXRob2QgPT09ICdHRVQnKSB7XG4gICAgICBxdWVyeSA9IGRhdGE7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGdldEF1dGgob3B0aW9ucywgY29uZmlnKS50aGVuKGF1dGggPT4ge1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0ge1xuICAgICAgICAgIGJvZHk6IGRhdGEsXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIGF1dGgsXG4gICAgICAgICAgaW5mbzoge1xuICAgICAgICAgICAgYXBwbGljYXRpb25JZDogYXBwbGljYXRpb25JZCxcbiAgICAgICAgICAgIHNlc3Npb25Ub2tlbjogb3B0aW9ucy5zZXNzaW9uVG9rZW4sXG4gICAgICAgICAgICBpbnN0YWxsYXRpb25JZDogb3B0aW9ucy5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgICAgIGNvbnRleHQ6IG9wdGlvbnMuY29udGV4dCB8fCB7fSwgLy8gQWRkIGNvbnRleHRcbiAgICAgICAgICB9LFxuICAgICAgICAgIHF1ZXJ5LFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gcm91dGVyLnRyeVJvdXRlUmVxdWVzdChtZXRob2QsIHBhdGgsIHJlcXVlc3QpO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnRoZW4oXG4gICAgICAgICAgICByZXNwID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgeyByZXNwb25zZSwgc3RhdHVzIH0gPSByZXNwO1xuICAgICAgICAgICAgICBpZiAob3B0aW9ucy5yZXR1cm5TdGF0dXMpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHsgLi4ucmVzcG9uc2UsIF9zdGF0dXM6IHN0YXR1cyB9KTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVyciA9PiB7XG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBlcnIgaW5zdGFuY2VvZiBQYXJzZS5FcnJvciAmJlxuICAgICAgICAgICAgICAgIGVyci5jb2RlID09IFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiAmJlxuICAgICAgICAgICAgICAgIGVyci5tZXNzYWdlID09IGBjYW5ub3Qgcm91dGUgJHttZXRob2R9ICR7cGF0aH1gXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIFJFU1RDb250cm9sbGVyLnJlcXVlc3QuYXBwbHkobnVsbCwgYXJncykudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgIH0sIHJlamVjdCk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHJlcXVlc3Q6IGhhbmRsZVJlcXVlc3QsXG4gICAgYWpheDogUkVTVENvbnRyb2xsZXIuYWpheCxcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgUGFyc2VTZXJ2ZXJSRVNUQ29udHJvbGxlcjtcbmV4cG9ydCB7IFBhcnNlU2VydmVyUkVTVENvbnRyb2xsZXIgfTtcbiJdfQ== \ No newline at end of file diff --git a/lib/PromiseRouter.js b/lib/PromiseRouter.js deleted file mode 100644 index 348b89f044..0000000000 --- a/lib/PromiseRouter.js +++ /dev/null @@ -1,255 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _express = _interopRequireDefault(require("express")); - -var _logger = _interopRequireDefault(require("./logger")); - -var _util = require("util"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// A router that is based on promises rather than req/res/next. -// This is intended to replace the use of express.Router to handle -// subsections of the API surface. -// This will make it easier to have methods like 'batch' that -// themselves use our routing information, without disturbing express -// components that external developers may be modifying. -const Layer = require('express/lib/router/layer'); - -function validateParameter(key, value) { - if (key == 'className') { - if (value.match(/_?[A-Za-z][A-Za-z_0-9]*/)) { - return value; - } - } else if (key == 'objectId') { - if (value.match(/[A-Za-z0-9]+/)) { - return value; - } - } else { - return value; - } -} - -class PromiseRouter { - // Each entry should be an object with: - // path: the path to route, in express format - // method: the HTTP method that this route handles. - // Must be one of: POST, GET, PUT, DELETE - // handler: a function that takes request, and returns a promise. - // Successful handlers should resolve to an object with fields: - // status: optional. the http status code. defaults to 200 - // response: a json object with the content of the response - // location: optional. a location header - constructor(routes = [], appId) { - this.routes = routes; - this.appId = appId; - this.mountRoutes(); - } // Leave the opportunity to - // subclasses to mount their routes by overriding - - - mountRoutes() {} // Merge the routes into this one - - - merge(router) { - for (var route of router.routes) { - this.routes.push(route); - } - } - - route(method, path, ...handlers) { - switch (method) { - case 'POST': - case 'GET': - case 'PUT': - case 'DELETE': - break; - - default: - throw 'cannot route method: ' + method; - } - - let handler = handlers[0]; - - if (handlers.length > 1) { - handler = function (req) { - return handlers.reduce((promise, handler) => { - return promise.then(() => { - return handler(req); - }); - }, Promise.resolve()); - }; - } - - this.routes.push({ - path: path, - method: method, - handler: handler, - layer: new Layer(path, null, handler) - }); - } // Returns an object with: - // handler: the handler that should deal with this request - // params: any :-params that got parsed from the path - // Returns undefined if there is no match. - - - match(method, path) { - for (var route of this.routes) { - if (route.method != method) { - continue; - } - - const layer = route.layer || new Layer(route.path, null, route.handler); - const match = layer.match(path); - - if (match) { - const params = layer.params; - Object.keys(params).forEach(key => { - params[key] = validateParameter(key, params[key]); - }); - return { - params: params, - handler: route.handler - }; - } - } - } // Mount the routes on this router onto an express app (or express router) - - - mountOnto(expressApp) { - this.routes.forEach(route => { - const method = route.method.toLowerCase(); - const handler = makeExpressHandler(this.appId, route.handler); - expressApp[method].call(expressApp, route.path, handler); - }); - return expressApp; - } - - expressRouter() { - return this.mountOnto(_express.default.Router()); - } - - tryRouteRequest(method, path, request) { - var match = this.match(method, path); - - if (!match) { - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'cannot route ' + method + ' ' + path); - } - - request.params = match.params; - return new Promise((resolve, reject) => { - match.handler(request).then(resolve, reject); - }); - } - -} // A helper function to make an express handler out of a a promise -// handler. -// Express handlers should never throw; if a promise handler throws we -// just treat it like it resolved to an error. - - -exports.default = PromiseRouter; - -function makeExpressHandler(appId, promiseHandler) { - return function (req, res, next) { - try { - const url = maskSensitiveUrl(req); - const body = Object.assign({}, req.body); - const method = req.method; - const headers = req.headers; - - _logger.default.logRequest({ - method, - url, - headers, - body - }); - - promiseHandler(req).then(result => { - clearSchemaCache(req); - - if (!result.response && !result.location && !result.text) { - _logger.default.error('the handler did not include a "response" or a "location" field'); - - throw 'control should not get here'; - } - - _logger.default.logResponse({ - method, - url, - result - }); - - var status = result.status || 200; - res.status(status); - - if (result.headers) { - Object.keys(result.headers).forEach(header => { - res.set(header, result.headers[header]); - }); - } - - if (result.text) { - res.send(result.text); - return; - } - - if (result.location) { - res.set('Location', result.location); // Override the default expressjs response - // as it double encodes %encoded chars in URL - - if (!result.response) { - res.send('Found. Redirecting to ' + result.location); - return; - } - } - - res.json(result.response); - }, error => { - clearSchemaCache(req); - next(error); - }).catch(e => { - clearSchemaCache(req); - - _logger.default.error(`Error generating response. ${(0, _util.inspect)(e)}`, { - error: e - }); - - next(e); - }); - } catch (e) { - clearSchemaCache(req); - - _logger.default.error(`Error handling request: ${(0, _util.inspect)(e)}`, { - error: e - }); - - next(e); - } - }; -} - -function maskSensitiveUrl(req) { - let maskUrl = req.originalUrl.toString(); - const shouldMaskUrl = req.method === 'GET' && req.originalUrl.includes('/login') && !req.originalUrl.includes('classes'); - - if (shouldMaskUrl) { - maskUrl = _logger.default.maskSensitiveUrl(maskUrl); - } - - return maskUrl; -} - -function clearSchemaCache(req) { - if (req.config && !req.config.enableSingleSchemaCache) { - req.config.database.schemaCache.clear(); - } -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9Qcm9taXNlUm91dGVyLmpzIl0sIm5hbWVzIjpbIkxheWVyIiwicmVxdWlyZSIsInZhbGlkYXRlUGFyYW1ldGVyIiwia2V5IiwidmFsdWUiLCJtYXRjaCIsIlByb21pc2VSb3V0ZXIiLCJjb25zdHJ1Y3RvciIsInJvdXRlcyIsImFwcElkIiwibW91bnRSb3V0ZXMiLCJtZXJnZSIsInJvdXRlciIsInJvdXRlIiwicHVzaCIsIm1ldGhvZCIsInBhdGgiLCJoYW5kbGVycyIsImhhbmRsZXIiLCJsZW5ndGgiLCJyZXEiLCJyZWR1Y2UiLCJwcm9taXNlIiwidGhlbiIsIlByb21pc2UiLCJyZXNvbHZlIiwibGF5ZXIiLCJwYXJhbXMiLCJPYmplY3QiLCJrZXlzIiwiZm9yRWFjaCIsIm1vdW50T250byIsImV4cHJlc3NBcHAiLCJ0b0xvd2VyQ2FzZSIsIm1ha2VFeHByZXNzSGFuZGxlciIsImNhbGwiLCJleHByZXNzUm91dGVyIiwiZXhwcmVzcyIsIlJvdXRlciIsInRyeVJvdXRlUmVxdWVzdCIsInJlcXVlc3QiLCJQYXJzZSIsIkVycm9yIiwiSU5WQUxJRF9KU09OIiwicmVqZWN0IiwicHJvbWlzZUhhbmRsZXIiLCJyZXMiLCJuZXh0IiwidXJsIiwibWFza1NlbnNpdGl2ZVVybCIsImJvZHkiLCJhc3NpZ24iLCJoZWFkZXJzIiwibG9nIiwibG9nUmVxdWVzdCIsInJlc3VsdCIsImNsZWFyU2NoZW1hQ2FjaGUiLCJyZXNwb25zZSIsImxvY2F0aW9uIiwidGV4dCIsImVycm9yIiwibG9nUmVzcG9uc2UiLCJzdGF0dXMiLCJoZWFkZXIiLCJzZXQiLCJzZW5kIiwianNvbiIsImNhdGNoIiwiZSIsIm1hc2tVcmwiLCJvcmlnaW5hbFVybCIsInRvU3RyaW5nIiwic2hvdWxkTWFza1VybCIsImluY2x1ZGVzIiwiY29uZmlnIiwiZW5hYmxlU2luZ2xlU2NoZW1hQ2FjaGUiLCJkYXRhYmFzZSIsInNjaGVtYUNhY2hlIiwiY2xlYXIiXSwibWFwcGluZ3MiOiI7Ozs7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QkcsUUFBaEIsQ0FBeUIsU0FBekIsQ0FISDs7QUFJQSxNQUFJRCxhQUFKLEVBQW1CO0FBQ2pCSCxJQUFBQSxPQUFPLEdBQUdoQixnQkFBSUosZ0JBQUosQ0FBcUJvQixPQUFyQixDQUFWO0FBQ0Q7O0FBQ0QsU0FBT0EsT0FBUDtBQUNEOztBQUVELFNBQVNiLGdCQUFULENBQTBCcEMsR0FBMUIsRUFBK0I7QUFDN0IsTUFBSUEsR0FBRyxDQUFDc0QsTUFBSixJQUFjLENBQUN0RCxHQUFHLENBQUNzRCxNQUFKLENBQVdDLHVCQUE5QixFQUF1RDtBQUNyRHZELElBQUFBLEdBQUcsQ0FBQ3NELE1BQUosQ0FBV0UsUUFBWCxDQUFvQkMsV0FBcEIsQ0FBZ0NDLEtBQWhDO0FBQ0Q7QUFDRiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEEgcm91dGVyIHRoYXQgaXMgYmFzZWQgb24gcHJvbWlzZXMgcmF0aGVyIHRoYW4gcmVxL3Jlcy9uZXh0LlxuLy8gVGhpcyBpcyBpbnRlbmRlZCB0byByZXBsYWNlIHRoZSB1c2Ugb2YgZXhwcmVzcy5Sb3V0ZXIgdG8gaGFuZGxlXG4vLyBzdWJzZWN0aW9ucyBvZiB0aGUgQVBJIHN1cmZhY2UuXG4vLyBUaGlzIHdpbGwgbWFrZSBpdCBlYXNpZXIgdG8gaGF2ZSBtZXRob2RzIGxpa2UgJ2JhdGNoJyB0aGF0XG4vLyB0aGVtc2VsdmVzIHVzZSBvdXIgcm91dGluZyBpbmZvcm1hdGlvbiwgd2l0aG91dCBkaXN0dXJiaW5nIGV4cHJlc3Ncbi8vIGNvbXBvbmVudHMgdGhhdCBleHRlcm5hbCBkZXZlbG9wZXJzIG1heSBiZSBtb2RpZnlpbmcuXG5cbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBleHByZXNzIGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IGxvZyBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgeyBpbnNwZWN0IH0gZnJvbSAndXRpbCc7XG5jb25zdCBMYXllciA9IHJlcXVpcmUoJ2V4cHJlc3MvbGliL3JvdXRlci9sYXllcicpO1xuXG5mdW5jdGlvbiB2YWxpZGF0ZVBhcmFtZXRlcihrZXksIHZhbHVlKSB7XG4gIGlmIChrZXkgPT0gJ2NsYXNzTmFtZScpIHtcbiAgICBpZiAodmFsdWUubWF0Y2goL18/W0EtWmEtel1bQS1aYS16XzAtOV0qLykpIHtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoa2V5ID09ICdvYmplY3RJZCcpIHtcbiAgICBpZiAodmFsdWUubWF0Y2goL1tBLVphLXowLTldKy8pKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQcm9taXNlUm91dGVyIHtcbiAgLy8gRWFjaCBlbnRyeSBzaG91bGQgYmUgYW4gb2JqZWN0IHdpdGg6XG4gIC8vIHBhdGg6IHRoZSBwYXRoIHRvIHJvdXRlLCBpbiBleHByZXNzIGZvcm1hdFxuICAvLyBtZXRob2Q6IHRoZSBIVFRQIG1ldGhvZCB0aGF0IHRoaXMgcm91dGUgaGFuZGxlcy5cbiAgLy8gICBNdXN0IGJlIG9uZSBvZjogUE9TVCwgR0VULCBQVVQsIERFTEVURVxuICAvLyBoYW5kbGVyOiBhIGZ1bmN0aW9uIHRoYXQgdGFrZXMgcmVxdWVzdCwgYW5kIHJldHVybnMgYSBwcm9taXNlLlxuICAvLyAgIFN1Y2Nlc3NmdWwgaGFuZGxlcnMgc2hvdWxkIHJlc29sdmUgdG8gYW4gb2JqZWN0IHdpdGggZmllbGRzOlxuICAvLyAgICAgc3RhdHVzOiBvcHRpb25hbC4gdGhlIGh0dHAgc3RhdHVzIGNvZGUuIGRlZmF1bHRzIHRvIDIwMFxuICAvLyAgICAgcmVzcG9uc2U6IGEganNvbiBvYmplY3Qgd2l0aCB0aGUgY29udGVudCBvZiB0aGUgcmVzcG9uc2VcbiAgLy8gICAgIGxvY2F0aW9uOiBvcHRpb25hbC4gYSBsb2NhdGlvbiBoZWFkZXJcbiAgY29uc3RydWN0b3Iocm91dGVzID0gW10sIGFwcElkKSB7XG4gICAgdGhpcy5yb3V0ZXMgPSByb3V0ZXM7XG4gICAgdGhpcy5hcHBJZCA9IGFwcElkO1xuICAgIHRoaXMubW91bnRSb3V0ZXMoKTtcbiAgfVxuXG4gIC8vIExlYXZlIHRoZSBvcHBvcnR1bml0eSB0b1xuICAvLyBzdWJjbGFzc2VzIHRvIG1vdW50IHRoZWlyIHJvdXRlcyBieSBvdmVycmlkaW5nXG4gIG1vdW50Um91dGVzKCkge31cblxuICAvLyBNZXJnZSB0aGUgcm91dGVzIGludG8gdGhpcyBvbmVcbiAgbWVyZ2Uocm91dGVyKSB7XG4gICAgZm9yICh2YXIgcm91dGUgb2Ygcm91dGVyLnJvdXRlcykge1xuICAgICAgdGhpcy5yb3V0ZXMucHVzaChyb3V0ZSk7XG4gICAgfVxuICB9XG5cbiAgcm91dGUobWV0aG9kLCBwYXRoLCAuLi5oYW5kbGVycykge1xuICAgIHN3aXRjaCAobWV0aG9kKSB7XG4gICAgICBjYXNlICdQT1NUJzpcbiAgICAgIGNhc2UgJ0dFVCc6XG4gICAgICBjYXNlICdQVVQnOlxuICAgICAgY2FzZSAnREVMRVRFJzpcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyAnY2Fubm90IHJvdXRlIG1ldGhvZDogJyArIG1ldGhvZDtcbiAgICB9XG5cbiAgICBsZXQgaGFuZGxlciA9IGhhbmRsZXJzWzBdO1xuXG4gICAgaWYgKGhhbmRsZXJzLmxlbmd0aCA+IDEpIHtcbiAgICAgIGhhbmRsZXIgPSBmdW5jdGlvbiAocmVxKSB7XG4gICAgICAgIHJldHVybiBoYW5kbGVycy5yZWR1Y2UoKHByb21pc2UsIGhhbmRsZXIpID0+IHtcbiAgICAgICAgICByZXR1cm4gcHJvbWlzZS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGVyKHJlcSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0sIFByb21pc2UucmVzb2x2ZSgpKTtcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdGhpcy5yb3V0ZXMucHVzaCh7XG4gICAgICBwYXRoOiBwYXRoLFxuICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICBoYW5kbGVyOiBoYW5kbGVyLFxuICAgICAgbGF5ZXI6IG5ldyBMYXllcihwYXRoLCBudWxsLCBoYW5kbGVyKSxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFJldHVybnMgYW4gb2JqZWN0IHdpdGg6XG4gIC8vICAgaGFuZGxlcjogdGhlIGhhbmRsZXIgdGhhdCBzaG91bGQgZGVhbCB3aXRoIHRoaXMgcmVxdWVzdFxuICAvLyAgIHBhcmFtczogYW55IDotcGFyYW1zIHRoYXQgZ290IHBhcnNlZCBmcm9tIHRoZSBwYXRoXG4gIC8vIFJldHVybnMgdW5kZWZpbmVkIGlmIHRoZXJlIGlzIG5vIG1hdGNoLlxuICBtYXRjaChtZXRob2QsIHBhdGgpIHtcbiAgICBmb3IgKHZhciByb3V0ZSBvZiB0aGlzLnJvdXRlcykge1xuICAgICAgaWYgKHJvdXRlLm1ldGhvZCAhPSBtZXRob2QpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBsYXllciA9IHJvdXRlLmxheWVyIHx8IG5ldyBMYXllcihyb3V0ZS5wYXRoLCBudWxsLCByb3V0ZS5oYW5kbGVyKTtcbiAgICAgIGNvbnN0IG1hdGNoID0gbGF5ZXIubWF0Y2gocGF0aCk7XG4gICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgY29uc3QgcGFyYW1zID0gbGF5ZXIucGFyYW1zO1xuICAgICAgICBPYmplY3Qua2V5cyhwYXJhbXMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICBwYXJhbXNba2V5XSA9IHZhbGlkYXRlUGFyYW1ldGVyKGtleSwgcGFyYW1zW2tleV0pO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHsgcGFyYW1zOiBwYXJhbXMsIGhhbmRsZXI6IHJvdXRlLmhhbmRsZXIgfTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBNb3VudCB0aGUgcm91dGVzIG9uIHRoaXMgcm91dGVyIG9udG8gYW4gZXhwcmVzcyBhcHAgKG9yIGV4cHJlc3Mgcm91dGVyKVxuICBtb3VudE9udG8oZXhwcmVzc0FwcCkge1xuICAgIHRoaXMucm91dGVzLmZvckVhY2gocm91dGUgPT4ge1xuICAgICAgY29uc3QgbWV0aG9kID0gcm91dGUubWV0aG9kLnRvTG93ZXJDYXNlKCk7XG4gICAgICBjb25zdCBoYW5kbGVyID0gbWFrZUV4cHJlc3NIYW5kbGVyKHRoaXMuYXBwSWQsIHJvdXRlLmhhbmRsZXIpO1xuICAgICAgZXhwcmVzc0FwcFttZXRob2RdLmNhbGwoZXhwcmVzc0FwcCwgcm91dGUucGF0aCwgaGFuZGxlcik7XG4gICAgfSk7XG4gICAgcmV0dXJuIGV4cHJlc3NBcHA7XG4gIH1cblxuICBleHByZXNzUm91dGVyKCkge1xuICAgIHJldHVybiB0aGlzLm1vdW50T250byhleHByZXNzLlJvdXRlcigpKTtcbiAgfVxuXG4gIHRyeVJvdXRlUmVxdWVzdChtZXRob2QsIHBhdGgsIHJlcXVlc3QpIHtcbiAgICB2YXIgbWF0Y2ggPSB0aGlzLm1hdGNoKG1ldGhvZCwgcGF0aCk7XG4gICAgaWYgKCFtYXRjaCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2Nhbm5vdCByb3V0ZSAnICsgbWV0aG9kICsgJyAnICsgcGF0aCk7XG4gICAgfVxuICAgIHJlcXVlc3QucGFyYW1zID0gbWF0Y2gucGFyYW1zO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBtYXRjaC5oYW5kbGVyKHJlcXVlc3QpLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KTtcbiAgICB9KTtcbiAgfVxufVxuXG4vLyBBIGhlbHBlciBmdW5jdGlvbiB0byBtYWtlIGFuIGV4cHJlc3MgaGFuZGxlciBvdXQgb2YgYSBhIHByb21pc2Vcbi8vIGhhbmRsZXIuXG4vLyBFeHByZXNzIGhhbmRsZXJzIHNob3VsZCBuZXZlciB0aHJvdzsgaWYgYSBwcm9taXNlIGhhbmRsZXIgdGhyb3dzIHdlXG4vLyBqdXN0IHRyZWF0IGl0IGxpa2UgaXQgcmVzb2x2ZWQgdG8gYW4gZXJyb3IuXG5mdW5jdGlvbiBtYWtlRXhwcmVzc0hhbmRsZXIoYXBwSWQsIHByb21pc2VIYW5kbGVyKSB7XG4gIHJldHVybiBmdW5jdGlvbiAocmVxLCByZXMsIG5leHQpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdXJsID0gbWFza1NlbnNpdGl2ZVVybChyZXEpO1xuICAgICAgY29uc3QgYm9keSA9IE9iamVjdC5hc3NpZ24oe30sIHJlcS5ib2R5KTtcbiAgICAgIGNvbnN0IG1ldGhvZCA9IHJlcS5tZXRob2Q7XG4gICAgICBjb25zdCBoZWFkZXJzID0gcmVxLmhlYWRlcnM7XG4gICAgICBsb2cubG9nUmVxdWVzdCh7XG4gICAgICAgIG1ldGhvZCxcbiAgICAgICAgdXJsLFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICBib2R5LFxuICAgICAgfSk7XG4gICAgICBwcm9taXNlSGFuZGxlcihyZXEpXG4gICAgICAgIC50aGVuKFxuICAgICAgICAgIHJlc3VsdCA9PiB7XG4gICAgICAgICAgICBjbGVhclNjaGVtYUNhY2hlKHJlcSk7XG4gICAgICAgICAgICBpZiAoIXJlc3VsdC5yZXNwb25zZSAmJiAhcmVzdWx0LmxvY2F0aW9uICYmICFyZXN1bHQudGV4dCkge1xuICAgICAgICAgICAgICBsb2cuZXJyb3IoJ3RoZSBoYW5kbGVyIGRpZCBub3QgaW5jbHVkZSBhIFwicmVzcG9uc2VcIiBvciBhIFwibG9jYXRpb25cIiBmaWVsZCcpO1xuICAgICAgICAgICAgICB0aHJvdyAnY29udHJvbCBzaG91bGQgbm90IGdldCBoZXJlJztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbG9nLmxvZ1Jlc3BvbnNlKHsgbWV0aG9kLCB1cmwsIHJlc3VsdCB9KTtcblxuICAgICAgICAgICAgdmFyIHN0YXR1cyA9IHJlc3VsdC5zdGF0dXMgfHwgMjAwO1xuICAgICAgICAgICAgcmVzLnN0YXR1cyhzdGF0dXMpO1xuXG4gICAgICAgICAgICBpZiAocmVzdWx0LmhlYWRlcnMpIHtcbiAgICAgICAgICAgICAgT2JqZWN0LmtleXMocmVzdWx0LmhlYWRlcnMpLmZvckVhY2goaGVhZGVyID0+IHtcbiAgICAgICAgICAgICAgICByZXMuc2V0KGhlYWRlciwgcmVzdWx0LmhlYWRlcnNbaGVhZGVyXSk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocmVzdWx0LnRleHQpIHtcbiAgICAgICAgICAgICAgcmVzLnNlbmQocmVzdWx0LnRleHQpO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChyZXN1bHQubG9jYXRpb24pIHtcbiAgICAgICAgICAgICAgcmVzLnNldCgnTG9jYXRpb24nLCByZXN1bHQubG9jYXRpb24pO1xuICAgICAgICAgICAgICAvLyBPdmVycmlkZSB0aGUgZGVmYXVsdCBleHByZXNzanMgcmVzcG9uc2VcbiAgICAgICAgICAgICAgLy8gYXMgaXQgZG91YmxlIGVuY29kZXMgJWVuY29kZWQgY2hhcnMgaW4gVVJMXG4gICAgICAgICAgICAgIGlmICghcmVzdWx0LnJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgcmVzLnNlbmQoJ0ZvdW5kLiBSZWRpcmVjdGluZyB0byAnICsgcmVzdWx0LmxvY2F0aW9uKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlcy5qc29uKHJlc3VsdC5yZXNwb25zZSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBlcnJvciA9PiB7XG4gICAgICAgICAgICBjbGVhclNjaGVtYUNhY2hlKHJlcSk7XG4gICAgICAgICAgICBuZXh0KGVycm9yKTtcbiAgICAgICAgICB9XG4gICAgICAgIClcbiAgICAgICAgLmNhdGNoKGUgPT4ge1xuICAgICAgICAgIGNsZWFyU2NoZW1hQ2FjaGUocmVxKTtcbiAgICAgICAgICBsb2cuZXJyb3IoYEVycm9yIGdlbmVyYXRpbmcgcmVzcG9uc2UuICR7aW5zcGVjdChlKX1gLCB7IGVycm9yOiBlIH0pO1xuICAgICAgICAgIG5leHQoZSk7XG4gICAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNsZWFyU2NoZW1hQ2FjaGUocmVxKTtcbiAgICAgIGxvZy5lcnJvcihgRXJyb3IgaGFuZGxpbmcgcmVxdWVzdDogJHtpbnNwZWN0KGUpfWAsIHsgZXJyb3I6IGUgfSk7XG4gICAgICBuZXh0KGUpO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gbWFza1NlbnNpdGl2ZVVybChyZXEpIHtcbiAgbGV0IG1hc2tVcmwgPSByZXEub3JpZ2luYWxVcmwudG9TdHJpbmcoKTtcbiAgY29uc3Qgc2hvdWxkTWFza1VybCA9XG4gICAgcmVxLm1ldGhvZCA9PT0gJ0dFVCcgJiZcbiAgICByZXEub3JpZ2luYWxVcmwuaW5jbHVkZXMoJy9sb2dpbicpICYmXG4gICAgIXJlcS5vcmlnaW5hbFVybC5pbmNsdWRlcygnY2xhc3NlcycpO1xuICBpZiAoc2hvdWxkTWFza1VybCkge1xuICAgIG1hc2tVcmwgPSBsb2cubWFza1NlbnNpdGl2ZVVybChtYXNrVXJsKTtcbiAgfVxuICByZXR1cm4gbWFza1VybDtcbn1cblxuZnVuY3Rpb24gY2xlYXJTY2hlbWFDYWNoZShyZXEpIHtcbiAgaWYgKHJlcS5jb25maWcgJiYgIXJlcS5jb25maWcuZW5hYmxlU2luZ2xlU2NoZW1hQ2FjaGUpIHtcbiAgICByZXEuY29uZmlnLmRhdGFiYXNlLnNjaGVtYUNhY2hlLmNsZWFyKCk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Push/PushQueue.js b/lib/Push/PushQueue.js deleted file mode 100644 index f3e2d1d755..0000000000 --- a/lib/Push/PushQueue.js +++ /dev/null @@ -1,79 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.PushQueue = void 0; - -var _ParseMessageQueue = require("../ParseMessageQueue"); - -var _rest = _interopRequireDefault(require("../rest")); - -var _utils = require("./utils"); - -var _node = _interopRequireDefault(require("parse/node")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const PUSH_CHANNEL = 'parse-server-push'; -const DEFAULT_BATCH_SIZE = 100; - -class PushQueue { - // config object of the publisher, right now it only contains the redisURL, - // but we may extend it later. - constructor(config = {}) { - this.channel = config.channel || PushQueue.defaultPushChannel(); - this.batchSize = config.batchSize || DEFAULT_BATCH_SIZE; - this.parsePublisher = _ParseMessageQueue.ParseMessageQueue.createPublisher(config); - } - - static defaultPushChannel() { - return `${_node.default.applicationId}-${PUSH_CHANNEL}`; - } - - enqueue(body, where, config, auth, pushStatus) { - const limit = this.batchSize; - where = (0, _utils.applyDeviceTokenExists)(where); // Order by objectId so no impact on the DB - - const order = 'objectId'; - return Promise.resolve().then(() => { - return _rest.default.find(config, auth, '_Installation', where, { - limit: 0, - count: true - }); - }).then(({ - results, - count - }) => { - if (!results || count == 0) { - return pushStatus.complete(); - } - - pushStatus.setRunning(Math.ceil(count / limit)); - let skip = 0; - - while (skip < count) { - const query = { - where, - limit, - skip, - order - }; - const pushWorkItem = { - body, - query, - pushStatus: { - objectId: pushStatus.objectId - }, - applicationId: config.applicationId - }; - this.parsePublisher.publish(this.channel, JSON.stringify(pushWorkItem)); - skip += limit; - } - }); - } - -} - -exports.PushQueue = PushQueue; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9QdXNoL1B1c2hRdWV1ZS5qcyJdLCJuYW1lcyI6WyJQVVNIX0NIQU5ORUwiLCJERUZBVUxUX0JBVENIX1NJWkUiLCJQdXNoUXVldWUiLCJjb25zdHJ1Y3RvciIsImNvbmZpZyIsImNoYW5uZWwiLCJkZWZhdWx0UHVzaENoYW5uZWwiLCJiYXRjaFNpemUiLCJwYXJzZVB1Ymxpc2hlciIsIlBhcnNlTWVzc2FnZVF1ZXVlIiwiY3JlYXRlUHVibGlzaGVyIiwiUGFyc2UiLCJhcHBsaWNhdGlvbklkIiwiZW5xdWV1ZSIsImJvZHkiLCJ3aGVyZSIsImF1dGgiLCJwdXNoU3RhdHVzIiwibGltaXQiLCJvcmRlciIsIlByb21pc2UiLCJyZXNvbHZlIiwidGhlbiIsInJlc3QiLCJmaW5kIiwiY291bnQiLCJyZXN1bHRzIiwiY29tcGxldGUiLCJzZXRSdW5uaW5nIiwiTWF0aCIsImNlaWwiLCJza2lwIiwicXVlcnkiLCJwdXNoV29ya0l0ZW0iLCJvYmplY3RJZCIsInB1Ymxpc2giLCJKU09OIiwic3RyaW5naWZ5Il0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxNQUFNQSxZQUFZLEdBQUcsbUJBQXJCO0FBQ0EsTUFBTUMsa0JBQWtCLEdBQUcsR0FBM0I7O0FBRU8sTUFBTUMsU0FBTixDQUFnQjtBQUtyQjtBQUNBO0FBQ0FDLEVBQUFBLFdBQVcsQ0FBQ0MsTUFBVyxHQUFHLEVBQWYsRUFBbUI7QUFDNUIsU0FBS0MsT0FBTCxHQUFlRCxNQUFNLENBQUNDLE9BQVAsSUFBa0JILFNBQVMsQ0FBQ0ksa0JBQVYsRUFBakM7QUFDQSxTQUFLQyxTQUFMLEdBQWlCSCxNQUFNLENBQUNHLFNBQVAsSUFBb0JOLGtCQUFyQztBQUNBLFNBQUtPLGNBQUwsR0FBc0JDLHFDQUFrQkMsZUFBbEIsQ0FBa0NOLE1BQWxDLENBQXRCO0FBQ0Q7O0FBRUQsU0FBT0Usa0JBQVAsR0FBNEI7QUFDMUIsV0FBUSxHQUFFSyxjQUFNQyxhQUFjLElBQUdaLFlBQWEsRUFBOUM7QUFDRDs7QUFFRGEsRUFBQUEsT0FBTyxDQUFDQyxJQUFELEVBQU9DLEtBQVAsRUFBY1gsTUFBZCxFQUFzQlksSUFBdEIsRUFBNEJDLFVBQTVCLEVBQXdDO0FBQzdDLFVBQU1DLEtBQUssR0FBRyxLQUFLWCxTQUFuQjtBQUVBUSxJQUFBQSxLQUFLLEdBQUcsbUNBQXVCQSxLQUF2QixDQUFSLENBSDZDLENBSzdDOztBQUNBLFVBQU1JLEtBQUssR0FBRyxVQUFkO0FBQ0EsV0FBT0MsT0FBTyxDQUFDQyxPQUFSLEdBQ0pDLElBREksQ0FDQyxNQUFNO0FBQ1YsYUFBT0MsY0FBS0MsSUFBTCxDQUFVcEIsTUFBVixFQUFrQlksSUFBbEIsRUFBd0IsZUFBeEIsRUFBeUNELEtBQXpDLEVBQWdEO0FBQ3JERyxRQUFBQSxLQUFLLEVBQUUsQ0FEOEM7QUFFckRPLFFBQUFBLEtBQUssRUFBRTtBQUY4QyxPQUFoRCxDQUFQO0FBSUQsS0FOSSxFQU9KSCxJQVBJLENBT0MsQ0FBQztBQUFFSSxNQUFBQSxPQUFGO0FBQVdELE1BQUFBO0FBQVgsS0FBRCxLQUF3QjtBQUM1QixVQUFJLENBQUNDLE9BQUQsSUFBWUQsS0FBSyxJQUFJLENBQXpCLEVBQTRCO0FBQzFCLGVBQU9SLFVBQVUsQ0FBQ1UsUUFBWCxFQUFQO0FBQ0Q7O0FBQ0RWLE1BQUFBLFVBQVUsQ0FBQ1csVUFBWCxDQUFzQkMsSUFBSSxDQUFDQyxJQUFMLENBQVVMLEtBQUssR0FBR1AsS0FBbEIsQ0FBdEI7QUFDQSxVQUFJYSxJQUFJLEdBQUcsQ0FBWDs7QUFDQSxhQUFPQSxJQUFJLEdBQUdOLEtBQWQsRUFBcUI7QUFDbkIsY0FBTU8sS0FBSyxHQUFHO0FBQ1pqQixVQUFBQSxLQURZO0FBRVpHLFVBQUFBLEtBRlk7QUFHWmEsVUFBQUEsSUFIWTtBQUlaWixVQUFBQTtBQUpZLFNBQWQ7QUFPQSxjQUFNYyxZQUFZLEdBQUc7QUFDbkJuQixVQUFBQSxJQURtQjtBQUVuQmtCLFVBQUFBLEtBRm1CO0FBR25CZixVQUFBQSxVQUFVLEVBQUU7QUFBRWlCLFlBQUFBLFFBQVEsRUFBRWpCLFVBQVUsQ0FBQ2lCO0FBQXZCLFdBSE87QUFJbkJ0QixVQUFBQSxhQUFhLEVBQUVSLE1BQU0sQ0FBQ1E7QUFKSCxTQUFyQjtBQU1BLGFBQUtKLGNBQUwsQ0FBb0IyQixPQUFwQixDQUE0QixLQUFLOUIsT0FBakMsRUFBMEMrQixJQUFJLENBQUNDLFNBQUwsQ0FBZUosWUFBZixDQUExQztBQUNBRixRQUFBQSxJQUFJLElBQUliLEtBQVI7QUFDRDtBQUNGLEtBOUJJLENBQVA7QUErQkQ7O0FBdkRvQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBhcnNlTWVzc2FnZVF1ZXVlIH0gZnJvbSAnLi4vUGFyc2VNZXNzYWdlUXVldWUnO1xuaW1wb3J0IHJlc3QgZnJvbSAnLi4vcmVzdCc7XG5pbXBvcnQgeyBhcHBseURldmljZVRva2VuRXhpc3RzIH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5cbmNvbnN0IFBVU0hfQ0hBTk5FTCA9ICdwYXJzZS1zZXJ2ZXItcHVzaCc7XG5jb25zdCBERUZBVUxUX0JBVENIX1NJWkUgPSAxMDA7XG5cbmV4cG9ydCBjbGFzcyBQdXNoUXVldWUge1xuICBwYXJzZVB1Ymxpc2hlcjogT2JqZWN0O1xuICBjaGFubmVsOiBTdHJpbmc7XG4gIGJhdGNoU2l6ZTogTnVtYmVyO1xuXG4gIC8vIGNvbmZpZyBvYmplY3Qgb2YgdGhlIHB1Ymxpc2hlciwgcmlnaHQgbm93IGl0IG9ubHkgY29udGFpbnMgdGhlIHJlZGlzVVJMLFxuICAvLyBidXQgd2UgbWF5IGV4dGVuZCBpdCBsYXRlci5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBhbnkgPSB7fSkge1xuICAgIHRoaXMuY2hhbm5lbCA9IGNvbmZpZy5jaGFubmVsIHx8IFB1c2hRdWV1ZS5kZWZhdWx0UHVzaENoYW5uZWwoKTtcbiAgICB0aGlzLmJhdGNoU2l6ZSA9IGNvbmZpZy5iYXRjaFNpemUgfHwgREVGQVVMVF9CQVRDSF9TSVpFO1xuICAgIHRoaXMucGFyc2VQdWJsaXNoZXIgPSBQYXJzZU1lc3NhZ2VRdWV1ZS5jcmVhdGVQdWJsaXNoZXIoY29uZmlnKTtcbiAgfVxuXG4gIHN0YXRpYyBkZWZhdWx0UHVzaENoYW5uZWwoKSB7XG4gICAgcmV0dXJuIGAke1BhcnNlLmFwcGxpY2F0aW9uSWR9LSR7UFVTSF9DSEFOTkVMfWA7XG4gIH1cblxuICBlbnF1ZXVlKGJvZHksIHdoZXJlLCBjb25maWcsIGF1dGgsIHB1c2hTdGF0dXMpIHtcbiAgICBjb25zdCBsaW1pdCA9IHRoaXMuYmF0Y2hTaXplO1xuXG4gICAgd2hlcmUgPSBhcHBseURldmljZVRva2VuRXhpc3RzKHdoZXJlKTtcblxuICAgIC8vIE9yZGVyIGJ5IG9iamVjdElkIHNvIG5vIGltcGFjdCBvbiB0aGUgREJcbiAgICBjb25zdCBvcmRlciA9ICdvYmplY3RJZCc7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiByZXN0LmZpbmQoY29uZmlnLCBhdXRoLCAnX0luc3RhbGxhdGlvbicsIHdoZXJlLCB7XG4gICAgICAgICAgbGltaXQ6IDAsXG4gICAgICAgICAgY291bnQ6IHRydWUsXG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCh7IHJlc3VsdHMsIGNvdW50IH0pID0+IHtcbiAgICAgICAgaWYgKCFyZXN1bHRzIHx8IGNvdW50ID09IDApIHtcbiAgICAgICAgICByZXR1cm4gcHVzaFN0YXR1cy5jb21wbGV0ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHB1c2hTdGF0dXMuc2V0UnVubmluZyhNYXRoLmNlaWwoY291bnQgLyBsaW1pdCkpO1xuICAgICAgICBsZXQgc2tpcCA9IDA7XG4gICAgICAgIHdoaWxlIChza2lwIDwgY291bnQpIHtcbiAgICAgICAgICBjb25zdCBxdWVyeSA9IHtcbiAgICAgICAgICAgIHdoZXJlLFxuICAgICAgICAgICAgbGltaXQsXG4gICAgICAgICAgICBza2lwLFxuICAgICAgICAgICAgb3JkZXIsXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGNvbnN0IHB1c2hXb3JrSXRlbSA9IHtcbiAgICAgICAgICAgIGJvZHksXG4gICAgICAgICAgICBxdWVyeSxcbiAgICAgICAgICAgIHB1c2hTdGF0dXM6IHsgb2JqZWN0SWQ6IHB1c2hTdGF0dXMub2JqZWN0SWQgfSxcbiAgICAgICAgICAgIGFwcGxpY2F0aW9uSWQ6IGNvbmZpZy5hcHBsaWNhdGlvbklkLFxuICAgICAgICAgIH07XG4gICAgICAgICAgdGhpcy5wYXJzZVB1Ymxpc2hlci5wdWJsaXNoKHRoaXMuY2hhbm5lbCwgSlNPTi5zdHJpbmdpZnkocHVzaFdvcmtJdGVtKSk7XG4gICAgICAgICAgc2tpcCArPSBsaW1pdDtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Push/PushWorker.js b/lib/Push/PushWorker.js deleted file mode 100644 index d845117b7b..0000000000 --- a/lib/Push/PushWorker.js +++ /dev/null @@ -1,130 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.PushWorker = void 0; - -var _deepcopy = _interopRequireDefault(require("deepcopy")); - -var _AdaptableController = _interopRequireDefault(require("../Controllers/AdaptableController")); - -var _Auth = require("../Auth"); - -var _Config = _interopRequireDefault(require("../Config")); - -var _PushAdapter = require("../Adapters/Push/PushAdapter"); - -var _rest = _interopRequireDefault(require("../rest")); - -var _StatusHandler = require("../StatusHandler"); - -var utils = _interopRequireWildcard(require("./utils")); - -var _ParseMessageQueue = require("../ParseMessageQueue"); - -var _PushQueue = require("./PushQueue"); - -var _logger = _interopRequireDefault(require("../logger")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// -disable-next -function groupByBadge(installations) { - return installations.reduce((map, installation) => { - const badge = installation.badge + ''; - map[badge] = map[badge] || []; - map[badge].push(installation); - return map; - }, {}); -} - -class PushWorker { - constructor(pushAdapter, subscriberConfig = {}) { - _AdaptableController.default.validateAdapter(pushAdapter, this, _PushAdapter.PushAdapter); - - this.adapter = pushAdapter; - this.channel = subscriberConfig.channel || _PushQueue.PushQueue.defaultPushChannel(); - this.subscriber = _ParseMessageQueue.ParseMessageQueue.createSubscriber(subscriberConfig); - - if (this.subscriber) { - const subscriber = this.subscriber; - subscriber.subscribe(this.channel); - subscriber.on('message', (channel, messageStr) => { - const workItem = JSON.parse(messageStr); - this.run(workItem); - }); - } - } - - run({ - body, - query, - pushStatus, - applicationId, - UTCOffset - }) { - const config = _Config.default.get(applicationId); - - const auth = (0, _Auth.master)(config); - const where = utils.applyDeviceTokenExists(query.where); - delete query.where; - pushStatus = (0, _StatusHandler.pushStatusHandler)(config, pushStatus.objectId); - return _rest.default.find(config, auth, '_Installation', where, query).then(({ - results - }) => { - if (results.length == 0) { - return; - } - - return this.sendToAdapter(body, results, pushStatus, config, UTCOffset); - }); - } - - sendToAdapter(body, installations, pushStatus, config, UTCOffset) { - // Check if we have locales in the push body - const locales = utils.getLocalesFromPush(body); - - if (locales.length > 0) { - // Get all tranformed bodies for each locale - const bodiesPerLocales = utils.bodiesPerLocales(body, locales); // Group installations on the specified locales (en, fr, default etc...) - - const grouppedInstallations = utils.groupByLocaleIdentifier(installations, locales); - const promises = Object.keys(grouppedInstallations).map(locale => { - const installations = grouppedInstallations[locale]; - const body = bodiesPerLocales[locale]; - return this.sendToAdapter(body, installations, pushStatus, config, UTCOffset); - }); - return Promise.all(promises); - } - - if (!utils.isPushIncrementing(body)) { - _logger.default.verbose(`Sending push to ${installations.length}`); - - return this.adapter.send(body, installations, pushStatus.objectId).then(results => { - return pushStatus.trackSent(results, UTCOffset).then(() => results); - }); - } // Collect the badges to reduce the # of calls - - - const badgeInstallationsMap = groupByBadge(installations); // Map the on the badges count and return the send result - - const promises = Object.keys(badgeInstallationsMap).map(badge => { - const payload = (0, _deepcopy.default)(body); - payload.data.badge = parseInt(badge); - const installations = badgeInstallationsMap[badge]; - return this.sendToAdapter(payload, installations, pushStatus, config, UTCOffset); - }); - return Promise.all(promises); - } - -} - -exports.PushWorker = PushWorker; -var _default = PushWorker; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9QdXNoL1B1c2hXb3JrZXIuanMiXSwibmFtZXMiOlsiZ3JvdXBCeUJhZGdlIiwiaW5zdGFsbGF0aW9ucyIsInJlZHVjZSIsIm1hcCIsImluc3RhbGxhdGlvbiIsImJhZGdlIiwicHVzaCIsIlB1c2hXb3JrZXIiLCJjb25zdHJ1Y3RvciIsInB1c2hBZGFwdGVyIiwic3Vic2NyaWJlckNvbmZpZyIsIkFkYXB0YWJsZUNvbnRyb2xsZXIiLCJ2YWxpZGF0ZUFkYXB0ZXIiLCJQdXNoQWRhcHRlciIsImFkYXB0ZXIiLCJjaGFubmVsIiwiUHVzaFF1ZXVlIiwiZGVmYXVsdFB1c2hDaGFubmVsIiwic3Vic2NyaWJlciIsIlBhcnNlTWVzc2FnZVF1ZXVlIiwiY3JlYXRlU3Vic2NyaWJlciIsInN1YnNjcmliZSIsIm9uIiwibWVzc2FnZVN0ciIsIndvcmtJdGVtIiwiSlNPTiIsInBhcnNlIiwicnVuIiwiYm9keSIsInF1ZXJ5IiwicHVzaFN0YXR1cyIsImFwcGxpY2F0aW9uSWQiLCJVVENPZmZzZXQiLCJjb25maWciLCJDb25maWciLCJnZXQiLCJhdXRoIiwid2hlcmUiLCJ1dGlscyIsImFwcGx5RGV2aWNlVG9rZW5FeGlzdHMiLCJvYmplY3RJZCIsInJlc3QiLCJmaW5kIiwidGhlbiIsInJlc3VsdHMiLCJsZW5ndGgiLCJzZW5kVG9BZGFwdGVyIiwibG9jYWxlcyIsImdldExvY2FsZXNGcm9tUHVzaCIsImJvZGllc1BlckxvY2FsZXMiLCJncm91cHBlZEluc3RhbGxhdGlvbnMiLCJncm91cEJ5TG9jYWxlSWRlbnRpZmllciIsInByb21pc2VzIiwiT2JqZWN0Iiwia2V5cyIsImxvY2FsZSIsIlByb21pc2UiLCJhbGwiLCJpc1B1c2hJbmNyZW1lbnRpbmciLCJsb2dnZXIiLCJ2ZXJib3NlIiwic2VuZCIsInRyYWNrU2VudCIsImJhZGdlSW5zdGFsbGF0aW9uc01hcCIsInBheWxvYWQiLCJkYXRhIiwicGFyc2VJbnQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7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O0FBR0QsS0F0QlcsQ0F3Qlo7OztBQUNBLFVBQU1tQixxQkFBcUIsR0FBRy9ELFlBQVksQ0FBQ0MsYUFBRCxDQUExQyxDQXpCWSxDQTJCWjs7QUFDQSxVQUFNbUQsUUFBUSxHQUFHQyxNQUFNLENBQUNDLElBQVAsQ0FBWVMscUJBQVosRUFBbUM1RCxHQUFuQyxDQUF1Q0UsS0FBSyxJQUFJO0FBQy9ELFlBQU0yRCxPQUFPLEdBQUcsdUJBQVNwQyxJQUFULENBQWhCO0FBQ0FvQyxNQUFBQSxPQUFPLENBQUNDLElBQVIsQ0FBYTVELEtBQWIsR0FBcUI2RCxRQUFRLENBQUM3RCxLQUFELENBQTdCO0FBQ0EsWUFBTUosYUFBYSxHQUFHOEQscUJBQXFCLENBQUMxRCxLQUFELENBQTNDO0FBQ0EsYUFBTyxLQUFLeUMsYUFBTCxDQUFtQmtCLE9BQW5CLEVBQTRCL0QsYUFBNUIsRUFBMkM2QixVQUEzQyxFQUF1REcsTUFBdkQsRUFBK0RELFNBQS9ELENBQVA7QUFDRCxLQUxnQixDQUFqQjtBQU1BLFdBQU93QixPQUFPLENBQUNDLEdBQVIsQ0FBWUwsUUFBWixDQUFQO0FBQ0Q7O0FBNUVxQjs7O2VBK0VUN0MsVSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCBkZWVwY29weSBmcm9tICdkZWVwY29weSc7XG5pbXBvcnQgQWRhcHRhYmxlQ29udHJvbGxlciBmcm9tICcuLi9Db250cm9sbGVycy9BZGFwdGFibGVDb250cm9sbGVyJztcbmltcG9ydCB7IG1hc3RlciB9IGZyb20gJy4uL0F1dGgnO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuLi9Db25maWcnO1xuaW1wb3J0IHsgUHVzaEFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9QdXNoL1B1c2hBZGFwdGVyJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IHsgcHVzaFN0YXR1c0hhbmRsZXIgfSBmcm9tICcuLi9TdGF0dXNIYW5kbGVyJztcbmltcG9ydCAqIGFzIHV0aWxzIGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHsgUGFyc2VNZXNzYWdlUXVldWUgfSBmcm9tICcuLi9QYXJzZU1lc3NhZ2VRdWV1ZSc7XG5pbXBvcnQgeyBQdXNoUXVldWUgfSBmcm9tICcuL1B1c2hRdWV1ZSc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5cbmZ1bmN0aW9uIGdyb3VwQnlCYWRnZShpbnN0YWxsYXRpb25zKSB7XG4gIHJldHVybiBpbnN0YWxsYXRpb25zLnJlZHVjZSgobWFwLCBpbnN0YWxsYXRpb24pID0+IHtcbiAgICBjb25zdCBiYWRnZSA9IGluc3RhbGxhdGlvbi5iYWRnZSArICcnO1xuICAgIG1hcFtiYWRnZV0gPSBtYXBbYmFkZ2VdIHx8IFtdO1xuICAgIG1hcFtiYWRnZV0ucHVzaChpbnN0YWxsYXRpb24pO1xuICAgIHJldHVybiBtYXA7XG4gIH0sIHt9KTtcbn1cblxuZXhwb3J0IGNsYXNzIFB1c2hXb3JrZXIge1xuICBzdWJzY3JpYmVyOiA/YW55O1xuICBhZGFwdGVyOiBhbnk7XG4gIGNoYW5uZWw6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihwdXNoQWRhcHRlcjogUHVzaEFkYXB0ZXIsIHN1YnNjcmliZXJDb25maWc6IGFueSA9IHt9KSB7XG4gICAgQWRhcHRhYmxlQ29udHJvbGxlci52YWxpZGF0ZUFkYXB0ZXIocHVzaEFkYXB0ZXIsIHRoaXMsIFB1c2hBZGFwdGVyKTtcbiAgICB0aGlzLmFkYXB0ZXIgPSBwdXNoQWRhcHRlcjtcblxuICAgIHRoaXMuY2hhbm5lbCA9IHN1YnNjcmliZXJDb25maWcuY2hhbm5lbCB8fCBQdXNoUXVldWUuZGVmYXVsdFB1c2hDaGFubmVsKCk7XG4gICAgdGhpcy5zdWJzY3JpYmVyID0gUGFyc2VNZXNzYWdlUXVldWUuY3JlYXRlU3Vic2NyaWJlcihzdWJzY3JpYmVyQ29uZmlnKTtcbiAgICBpZiAodGhpcy5zdWJzY3JpYmVyKSB7XG4gICAgICBjb25zdCBzdWJzY3JpYmVyID0gdGhpcy5zdWJzY3JpYmVyO1xuICAgICAgc3Vic2NyaWJlci5zdWJzY3JpYmUodGhpcy5jaGFubmVsKTtcbiAgICAgIHN1YnNjcmliZXIub24oJ21lc3NhZ2UnLCAoY2hhbm5lbCwgbWVzc2FnZVN0cikgPT4ge1xuICAgICAgICBjb25zdCB3b3JrSXRlbSA9IEpTT04ucGFyc2UobWVzc2FnZVN0cik7XG4gICAgICAgIHRoaXMucnVuKHdvcmtJdGVtKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHJ1bih7IGJvZHksIHF1ZXJ5LCBwdXNoU3RhdHVzLCBhcHBsaWNhdGlvbklkLCBVVENPZmZzZXQgfTogYW55KTogUHJvbWlzZTwqPiB7XG4gICAgY29uc3QgY29uZmlnID0gQ29uZmlnLmdldChhcHBsaWNhdGlvbklkKTtcbiAgICBjb25zdCBhdXRoID0gbWFzdGVyKGNvbmZpZyk7XG4gICAgY29uc3Qgd2hlcmUgPSB1dGlscy5hcHBseURldmljZVRva2VuRXhpc3RzKHF1ZXJ5LndoZXJlKTtcbiAgICBkZWxldGUgcXVlcnkud2hlcmU7XG4gICAgcHVzaFN0YXR1cyA9IHB1c2hTdGF0dXNIYW5kbGVyKGNvbmZpZywgcHVzaFN0YXR1cy5vYmplY3RJZCk7XG4gICAgcmV0dXJuIHJlc3QuZmluZChjb25maWcsIGF1dGgsICdfSW5zdGFsbGF0aW9uJywgd2hlcmUsIHF1ZXJ5KS50aGVuKCh7IHJlc3VsdHMgfSkgPT4ge1xuICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuc2VuZFRvQWRhcHRlcihib2R5LCByZXN1bHRzLCBwdXNoU3RhdHVzLCBjb25maWcsIFVUQ09mZnNldCk7XG4gICAgfSk7XG4gIH1cblxuICBzZW5kVG9BZGFwdGVyKFxuICAgIGJvZHk6IGFueSxcbiAgICBpbnN0YWxsYXRpb25zOiBhbnlbXSxcbiAgICBwdXNoU3RhdHVzOiBhbnksXG4gICAgY29uZmlnOiBDb25maWcsXG4gICAgVVRDT2Zmc2V0OiA/YW55XG4gICk6IFByb21pc2U8Kj4ge1xuICAgIC8vIENoZWNrIGlmIHdlIGhhdmUgbG9jYWxlcyBpbiB0aGUgcHVzaCBib2R5XG4gICAgY29uc3QgbG9jYWxlcyA9IHV0aWxzLmdldExvY2FsZXNGcm9tUHVzaChib2R5KTtcbiAgICBpZiAobG9jYWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBHZXQgYWxsIHRyYW5mb3JtZWQgYm9kaWVzIGZvciBlYWNoIGxvY2FsZVxuICAgICAgY29uc3QgYm9kaWVzUGVyTG9jYWxlcyA9IHV0aWxzLmJvZGllc1BlckxvY2FsZXMoYm9keSwgbG9jYWxlcyk7XG5cbiAgICAgIC8vIEdyb3VwIGluc3RhbGxhdGlvbnMgb24gdGhlIHNwZWNpZmllZCBsb2NhbGVzIChlbiwgZnIsIGRlZmF1bHQgZXRjLi4uKVxuICAgICAgY29uc3QgZ3JvdXBwZWRJbnN0YWxsYXRpb25zID0gdXRpbHMuZ3JvdXBCeUxvY2FsZUlkZW50aWZpZXIoaW5zdGFsbGF0aW9ucywgbG9jYWxlcyk7XG4gICAgICBjb25zdCBwcm9taXNlcyA9IE9iamVjdC5rZXlzKGdyb3VwcGVkSW5zdGFsbGF0aW9ucykubWFwKGxvY2FsZSA9PiB7XG4gICAgICAgIGNvbnN0IGluc3RhbGxhdGlvbnMgPSBncm91cHBlZEluc3RhbGxhdGlvbnNbbG9jYWxlXTtcbiAgICAgICAgY29uc3QgYm9keSA9IGJvZGllc1BlckxvY2FsZXNbbG9jYWxlXTtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VuZFRvQWRhcHRlcihib2R5LCBpbnN0YWxsYXRpb25zLCBwdXNoU3RhdHVzLCBjb25maWcsIFVUQ09mZnNldCk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgfVxuXG4gICAgaWYgKCF1dGlscy5pc1B1c2hJbmNyZW1lbnRpbmcoYm9keSkpIHtcbiAgICAgIGxvZ2dlci52ZXJib3NlKGBTZW5kaW5nIHB1c2ggdG8gJHtpbnN0YWxsYXRpb25zLmxlbmd0aH1gKTtcbiAgICAgIHJldHVybiB0aGlzLmFkYXB0ZXIuc2VuZChib2R5LCBpbnN0YWxsYXRpb25zLCBwdXNoU3RhdHVzLm9iamVjdElkKS50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICByZXR1cm4gcHVzaFN0YXR1cy50cmFja1NlbnQocmVzdWx0cywgVVRDT2Zmc2V0KS50aGVuKCgpID0+IHJlc3VsdHMpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gQ29sbGVjdCB0aGUgYmFkZ2VzIHRvIHJlZHVjZSB0aGUgIyBvZiBjYWxsc1xuICAgIGNvbnN0IGJhZGdlSW5zdGFsbGF0aW9uc01hcCA9IGdyb3VwQnlCYWRnZShpbnN0YWxsYXRpb25zKTtcblxuICAgIC8vIE1hcCB0aGUgb24gdGhlIGJhZGdlcyBjb3VudCBhbmQgcmV0dXJuIHRoZSBzZW5kIHJlc3VsdFxuICAgIGNvbnN0IHByb21pc2VzID0gT2JqZWN0LmtleXMoYmFkZ2VJbnN0YWxsYXRpb25zTWFwKS5tYXAoYmFkZ2UgPT4ge1xuICAgICAgY29uc3QgcGF5bG9hZCA9IGRlZXBjb3B5KGJvZHkpO1xuICAgICAgcGF5bG9hZC5kYXRhLmJhZGdlID0gcGFyc2VJbnQoYmFkZ2UpO1xuICAgICAgY29uc3QgaW5zdGFsbGF0aW9ucyA9IGJhZGdlSW5zdGFsbGF0aW9uc01hcFtiYWRnZV07XG4gICAgICByZXR1cm4gdGhpcy5zZW5kVG9BZGFwdGVyKHBheWxvYWQsIGluc3RhbGxhdGlvbnMsIHB1c2hTdGF0dXMsIGNvbmZpZywgVVRDT2Zmc2V0KTtcbiAgICB9KTtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1c2hXb3JrZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Push/utils.js b/lib/Push/utils.js deleted file mode 100644 index 0092d90ebd..0000000000 --- a/lib/Push/utils.js +++ /dev/null @@ -1,159 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.isPushIncrementing = isPushIncrementing; -exports.getLocalesFromPush = getLocalesFromPush; -exports.transformPushBodyForLocale = transformPushBodyForLocale; -exports.stripLocalesFromBody = stripLocalesFromBody; -exports.bodiesPerLocales = bodiesPerLocales; -exports.groupByLocaleIdentifier = groupByLocaleIdentifier; -exports.validatePushType = validatePushType; -exports.applyDeviceTokenExists = applyDeviceTokenExists; - -var _node = _interopRequireDefault(require("parse/node")); - -var _deepcopy = _interopRequireDefault(require("deepcopy")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function isPushIncrementing(body) { - if (!body.data || !body.data.badge) { - return false; - } - - const badge = body.data.badge; - - if (typeof badge == 'string' && badge.toLowerCase() == 'increment') { - return true; - } - - return typeof badge == 'object' && typeof badge.__op == 'string' && badge.__op.toLowerCase() == 'increment' && Number(badge.amount); -} - -const localizableKeys = ['alert', 'title']; - -function getLocalesFromPush(body) { - const data = body.data; - - if (!data) { - return []; - } - - return [...new Set(Object.keys(data).reduce((memo, key) => { - localizableKeys.forEach(localizableKey => { - if (key.indexOf(`${localizableKey}-`) == 0) { - memo.push(key.slice(localizableKey.length + 1)); - } - }); - return memo; - }, []))]; -} - -function transformPushBodyForLocale(body, locale) { - const data = body.data; - - if (!data) { - return body; - } - - body = (0, _deepcopy.default)(body); - localizableKeys.forEach(key => { - const localeValue = body.data[`${key}-${locale}`]; - - if (localeValue) { - body.data[key] = localeValue; - } - }); - return stripLocalesFromBody(body); -} - -function stripLocalesFromBody(body) { - if (!body.data) { - return body; - } - - Object.keys(body.data).forEach(key => { - localizableKeys.forEach(localizableKey => { - if (key.indexOf(`${localizableKey}-`) == 0) { - delete body.data[key]; - } - }); - }); - return body; -} - -function bodiesPerLocales(body, locales = []) { - // Get all tranformed bodies for each locale - const result = locales.reduce((memo, locale) => { - memo[locale] = transformPushBodyForLocale(body, locale); - return memo; - }, {}); // Set the default locale, with the stripped body - - result.default = stripLocalesFromBody(body); - return result; -} - -function groupByLocaleIdentifier(installations, locales = []) { - return installations.reduce((map, installation) => { - let added = false; - locales.forEach(locale => { - if (added) { - return; - } - - if (installation.localeIdentifier && installation.localeIdentifier.indexOf(locale) === 0) { - added = true; - map[locale] = map[locale] || []; - map[locale].push(installation); - } - }); - - if (!added) { - map.default.push(installation); - } - - return map; - }, { - default: [] - }); -} -/** - * Check whether the deviceType parameter in qury condition is valid or not. - * @param {Object} where A query condition - * @param {Array} validPushTypes An array of valid push types(string) - */ - - -function validatePushType(where = {}, validPushTypes = []) { - var deviceTypeField = where.deviceType || {}; - var deviceTypes = []; - - if (typeof deviceTypeField === 'string') { - deviceTypes.push(deviceTypeField); - } else if (Array.isArray(deviceTypeField['$in'])) { - deviceTypes.concat(deviceTypeField['$in']); - } - - for (var i = 0; i < deviceTypes.length; i++) { - var deviceType = deviceTypes[i]; - - if (validPushTypes.indexOf(deviceType) < 0) { - throw new _node.default.Error(_node.default.Error.PUSH_MISCONFIGURED, deviceType + ' is not supported push type.'); - } - } -} - -function applyDeviceTokenExists(where) { - where = (0, _deepcopy.default)(where); - - if (!Object.prototype.hasOwnProperty.call(where, 'deviceToken')) { - where['deviceToken'] = { - $exists: true - }; - } - - return where; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9QdXNoL3V0aWxzLmpzIl0sIm5hbWVzIjpbImlzUHVzaEluY3JlbWVudGluZyIsImJvZHkiLCJkYXRhIiwiYmFkZ2UiLCJ0b0xvd2VyQ2FzZSIsIl9fb3AiLCJOdW1iZXIiLCJhbW91bnQiLCJsb2NhbGl6YWJsZUtleXMiLCJnZXRMb2NhbGVzRnJvbVB1c2giLCJTZXQiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwibWVtbyIsImtleSIsImZvckVhY2giLCJsb2NhbGl6YWJsZUtleSIsImluZGV4T2YiLCJwdXNoIiwic2xpY2UiLCJsZW5ndGgiLCJ0cmFuc2Zvcm1QdXNoQm9keUZvckxvY2FsZSIsImxvY2FsZSIsImxvY2FsZVZhbHVlIiwic3RyaXBMb2NhbGVzRnJvbUJvZHkiLCJib2RpZXNQZXJMb2NhbGVzIiwibG9jYWxlcyIsInJlc3VsdCIsImRlZmF1bHQiLCJncm91cEJ5TG9jYWxlSWRlbnRpZmllciIsImluc3RhbGxhdGlvbnMiLCJtYXAiLCJpbnN0YWxsYXRpb24iLCJhZGRlZCIsImxvY2FsZUlkZW50aWZpZXIiLCJ2YWxpZGF0ZVB1c2hUeXBlIiwid2hlcmUiLCJ2YWxpZFB1c2hUeXBlcyIsImRldmljZVR5cGVGaWVsZCIsImRldmljZVR5cGUiLCJkZXZpY2VUeXBlcyIsIkFycmF5IiwiaXNBcnJheSIsImNvbmNhdCIsImkiLCJQYXJzZSIsIkVycm9yIiwiUFVTSF9NSVNDT05GSUdVUkVEIiwiYXBwbHlEZXZpY2VUb2tlbkV4aXN0cyIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIiRleGlzdHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7Ozs7QUFFTyxTQUFTQSxrQkFBVCxDQUE0QkMsSUFBNUIsRUFBa0M7QUFDdkMsTUFBSSxDQUFDQSxJQUFJLENBQUNDLElBQU4sSUFBYyxDQUFDRCxJQUFJLENBQUNDLElBQUwsQ0FBVUMsS0FBN0IsRUFBb0M7QUFDbEMsV0FBTyxLQUFQO0FB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LENBQUwsR0FBdUI7QUFBRWdCLE1BQUFBLE9BQU8sRUFBRTtBQUFYLEtBQXZCO0FBQ0Q7O0FBQ0QsU0FBT2hCLEtBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBkZWVwY29weSBmcm9tICdkZWVwY29weSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1B1c2hJbmNyZW1lbnRpbmcoYm9keSkge1xuICBpZiAoIWJvZHkuZGF0YSB8fCAhYm9keS5kYXRhLmJhZGdlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgYmFkZ2UgPSBib2R5LmRhdGEuYmFkZ2U7XG4gIGlmICh0eXBlb2YgYmFkZ2UgPT0gJ3N0cmluZycgJiYgYmFkZ2UudG9Mb3dlckNhc2UoKSA9PSAnaW5jcmVtZW50Jykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIChcbiAgICB0eXBlb2YgYmFkZ2UgPT0gJ29iamVjdCcgJiZcbiAgICB0eXBlb2YgYmFkZ2UuX19vcCA9PSAnc3RyaW5nJyAmJlxuICAgIGJhZGdlLl9fb3AudG9Mb3dlckNhc2UoKSA9PSAnaW5jcmVtZW50JyAmJlxuICAgIE51bWJlcihiYWRnZS5hbW91bnQpXG4gICk7XG59XG5cbmNvbnN0IGxvY2FsaXphYmxlS2V5cyA9IFsnYWxlcnQnLCAndGl0bGUnXTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldExvY2FsZXNGcm9tUHVzaChib2R5KSB7XG4gIGNvbnN0IGRhdGEgPSBib2R5LmRhdGE7XG4gIGlmICghZGF0YSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuICByZXR1cm4gW1xuICAgIC4uLm5ldyBTZXQoXG4gICAgICBPYmplY3Qua2V5cyhkYXRhKS5yZWR1Y2UoKG1lbW8sIGtleSkgPT4ge1xuICAgICAgICBsb2NhbGl6YWJsZUtleXMuZm9yRWFjaChsb2NhbGl6YWJsZUtleSA9PiB7XG4gICAgICAgICAgaWYgKGtleS5pbmRleE9mKGAke2xvY2FsaXphYmxlS2V5fS1gKSA9PSAwKSB7XG4gICAgICAgICAgICBtZW1vLnB1c2goa2V5LnNsaWNlKGxvY2FsaXphYmxlS2V5Lmxlbmd0aCArIDEpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gbWVtbztcbiAgICAgIH0sIFtdKVxuICAgICksXG4gIF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0cmFuc2Zvcm1QdXNoQm9keUZvckxvY2FsZShib2R5LCBsb2NhbGUpIHtcbiAgY29uc3QgZGF0YSA9IGJvZHkuZGF0YTtcbiAgaWYgKCFkYXRhKSB7XG4gICAgcmV0dXJuIGJvZHk7XG4gIH1cbiAgYm9keSA9IGRlZXBjb3B5KGJvZHkpO1xuICBsb2NhbGl6YWJsZUtleXMuZm9yRWFjaChrZXkgPT4ge1xuICAgIGNvbnN0IGxvY2FsZVZhbHVlID0gYm9keS5kYXRhW2Ake2tleX0tJHtsb2NhbGV9YF07XG4gICAgaWYgKGxvY2FsZVZhbHVlKSB7XG4gICAgICBib2R5LmRhdGFba2V5XSA9IGxvY2FsZVZhbHVlO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBzdHJpcExvY2FsZXNGcm9tQm9keShib2R5KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHN0cmlwTG9jYWxlc0Zyb21Cb2R5KGJvZHkpIHtcbiAgaWYgKCFib2R5LmRhdGEpIHtcbiAgICByZXR1cm4gYm9keTtcbiAgfVxuICBPYmplY3Qua2V5cyhib2R5LmRhdGEpLmZvckVhY2goa2V5ID0+IHtcbiAgICBsb2NhbGl6YWJsZUtleXMuZm9yRWFjaChsb2NhbGl6YWJsZUtleSA9PiB7XG4gICAgICBpZiAoa2V5LmluZGV4T2YoYCR7bG9jYWxpemFibGVLZXl9LWApID09IDApIHtcbiAgICAgICAgZGVsZXRlIGJvZHkuZGF0YVtrZXldO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbiAgcmV0dXJuIGJvZHk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBib2RpZXNQZXJMb2NhbGVzKGJvZHksIGxvY2FsZXMgPSBbXSkge1xuICAvLyBHZXQgYWxsIHRyYW5mb3JtZWQgYm9kaWVzIGZvciBlYWNoIGxvY2FsZVxuICBjb25zdCByZXN1bHQgPSBsb2NhbGVzLnJlZHVjZSgobWVtbywgbG9jYWxlKSA9PiB7XG4gICAgbWVtb1tsb2NhbGVdID0gdHJhbnNmb3JtUHVzaEJvZHlGb3JMb2NhbGUoYm9keSwgbG9jYWxlKTtcbiAgICByZXR1cm4gbWVtbztcbiAgfSwge30pO1xuICAvLyBTZXQgdGhlIGRlZmF1bHQgbG9jYWxlLCB3aXRoIHRoZSBzdHJpcHBlZCBib2R5XG4gIHJlc3VsdC5kZWZhdWx0ID0gc3RyaXBMb2NhbGVzRnJvbUJvZHkoYm9keSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBncm91cEJ5TG9jYWxlSWRlbnRpZmllcihpbnN0YWxsYXRpb25zLCBsb2NhbGVzID0gW10pIHtcbiAgcmV0dXJuIGluc3RhbGxhdGlvbnMucmVkdWNlKFxuICAgIChtYXAsIGluc3RhbGxhdGlvbikgPT4ge1xuICAgICAgbGV0IGFkZGVkID0gZmFsc2U7XG4gICAgICBsb2NhbGVzLmZvckVhY2gobG9jYWxlID0+IHtcbiAgICAgICAgaWYgKGFkZGVkKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpbnN0YWxsYXRpb24ubG9jYWxlSWRlbnRpZmllciAmJiBpbnN0YWxsYXRpb24ubG9jYWxlSWRlbnRpZmllci5pbmRleE9mKGxvY2FsZSkgPT09IDApIHtcbiAgICAgICAgICBhZGRlZCA9IHRydWU7XG4gICAgICAgICAgbWFwW2xvY2FsZV0gPSBtYXBbbG9jYWxlXSB8fCBbXTtcbiAgICAgICAgICBtYXBbbG9jYWxlXS5wdXNoKGluc3RhbGxhdGlvbik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgaWYgKCFhZGRlZCkge1xuICAgICAgICBtYXAuZGVmYXVsdC5wdXNoKGluc3RhbGxhdGlvbik7XG4gICAgICB9XG4gICAgICByZXR1cm4gbWFwO1xuICAgIH0sXG4gICAgeyBkZWZhdWx0OiBbXSB9XG4gICk7XG59XG5cbi8qKlxuICogQ2hlY2sgd2hldGhlciB0aGUgZGV2aWNlVHlwZSBwYXJhbWV0ZXIgaW4gcXVyeSBjb25kaXRpb24gaXMgdmFsaWQgb3Igbm90LlxuICogQHBhcmFtIHtPYmplY3R9IHdoZXJlIEEgcXVlcnkgY29uZGl0aW9uXG4gKiBAcGFyYW0ge0FycmF5fSB2YWxpZFB1c2hUeXBlcyBBbiBhcnJheSBvZiB2YWxpZCBwdXNoIHR5cGVzKHN0cmluZylcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlUHVzaFR5cGUod2hlcmUgPSB7fSwgdmFsaWRQdXNoVHlwZXMgPSBbXSkge1xuICB2YXIgZGV2aWNlVHlwZUZpZWxkID0gd2hlcmUuZGV2aWNlVHlwZSB8fCB7fTtcbiAgdmFyIGRldmljZVR5cGVzID0gW107XG4gIGlmICh0eXBlb2YgZGV2aWNlVHlwZUZpZWxkID09PSAnc3RyaW5nJykge1xuICAgIGRldmljZVR5cGVzLnB1c2goZGV2aWNlVHlwZUZpZWxkKTtcbiAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGRldmljZVR5cGVGaWVsZFsnJGluJ10pKSB7XG4gICAgZGV2aWNlVHlwZXMuY29uY2F0KGRldmljZVR5cGVGaWVsZFsnJGluJ10pO1xuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgZGV2aWNlVHlwZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZGV2aWNlVHlwZSA9IGRldmljZVR5cGVzW2ldO1xuICAgIGlmICh2YWxpZFB1c2hUeXBlcy5pbmRleE9mKGRldmljZVR5cGUpIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5QVVNIX01JU0NPTkZJR1VSRUQsXG4gICAgICAgIGRldmljZVR5cGUgKyAnIGlzIG5vdCBzdXBwb3J0ZWQgcHVzaCB0eXBlLidcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhcHBseURldmljZVRva2VuRXhpc3RzKHdoZXJlKSB7XG4gIHdoZXJlID0gZGVlcGNvcHkod2hlcmUpO1xuICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh3aGVyZSwgJ2RldmljZVRva2VuJykpIHtcbiAgICB3aGVyZVsnZGV2aWNlVG9rZW4nXSA9IHsgJGV4aXN0czogdHJ1ZSB9O1xuICB9XG4gIHJldHVybiB3aGVyZTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/RestQuery.js b/lib/RestQuery.js deleted file mode 100644 index 850595acc5..0000000000 --- a/lib/RestQuery.js +++ /dev/null @@ -1,979 +0,0 @@ -"use strict"; - -// An object that encapsulates everything we need to run a 'find' -// operation, encoded in the REST API format. -var SchemaController = require('./Controllers/SchemaController'); - -var Parse = require('parse/node').Parse; - -const triggers = require('./triggers'); - -const { - continueWhile -} = require('parse/lib/node/promiseUtils'); - -const AlwaysSelectedKeys = ['objectId', 'createdAt', 'updatedAt', 'ACL']; // restOptions can include: -// skip -// limit -// order -// count -// include -// keys -// excludeKeys -// redirectClassNameForKey -// readPreference -// includeReadPreference -// subqueryReadPreference - -function RestQuery(config, auth, className, restWhere = {}, restOptions = {}, clientSDK, runAfterFind = true, context) { - this.config = config; - this.auth = auth; - this.className = className; - this.restWhere = restWhere; - this.restOptions = restOptions; - this.clientSDK = clientSDK; - this.runAfterFind = runAfterFind; - this.response = null; - this.findOptions = {}; - this.context = context || {}; - - if (!this.auth.isMaster) { - if (this.className == '_Session') { - if (!this.auth.user) { - throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); - } - - this.restWhere = { - $and: [this.restWhere, { - user: { - __type: 'Pointer', - className: '_User', - objectId: this.auth.user.id - } - }] - }; - } - } - - this.doCount = false; - this.includeAll = false; // The format for this.include is not the same as the format for the - // include option - it's the paths we should include, in order, - // stored as arrays, taking into account that we need to include foo - // before including foo.bar. Also it should dedupe. - // For example, passing an arg of include=foo.bar,foo.baz could lead to - // this.include = [['foo'], ['foo', 'baz'], ['foo', 'bar']] - - this.include = []; // If we have keys, we probably want to force some includes (n-1 level) - // See issue: https://github.com/parse-community/parse-server/issues/3185 - - if (Object.prototype.hasOwnProperty.call(restOptions, 'keys')) { - const keysForInclude = restOptions.keys.split(',').filter(key => { - // At least 2 components - return key.split('.').length > 1; - }).map(key => { - // Slice the last component (a.b.c -> a.b) - // Otherwise we'll include one level too much. - return key.slice(0, key.lastIndexOf('.')); - }).join(','); // Concat the possibly present include string with the one from the keys - // Dedup / sorting is handle in 'include' case. - - if (keysForInclude.length > 0) { - if (!restOptions.include || restOptions.include.length == 0) { - restOptions.include = keysForInclude; - } else { - restOptions.include += ',' + keysForInclude; - } - } - } - - for (var option in restOptions) { - switch (option) { - case 'keys': - { - const keys = restOptions.keys.split(',').filter(key => key.length > 0).concat(AlwaysSelectedKeys); - this.keys = Array.from(new Set(keys)); - break; - } - - case 'excludeKeys': - { - const exclude = restOptions.excludeKeys.split(',').filter(k => AlwaysSelectedKeys.indexOf(k) < 0); - this.excludeKeys = Array.from(new Set(exclude)); - break; - } - - case 'count': - this.doCount = true; - break; - - case 'includeAll': - this.includeAll = true; - break; - - case 'explain': - case 'hint': - case 'distinct': - case 'pipeline': - case 'skip': - case 'limit': - case 'readPreference': - this.findOptions[option] = restOptions[option]; - break; - - case 'order': - var fields = restOptions.order.split(','); - this.findOptions.sort = fields.reduce((sortMap, field) => { - field = field.trim(); - - if (field === '$score') { - sortMap.score = { - $meta: 'textScore' - }; - } else if (field[0] == '-') { - sortMap[field.slice(1)] = -1; - } else { - sortMap[field] = 1; - } - - return sortMap; - }, {}); - break; - - case 'include': - { - const paths = restOptions.include.split(','); - - if (paths.includes('*')) { - this.includeAll = true; - break; - } // Load the existing includes (from keys) - - - const pathSet = paths.reduce((memo, path) => { - // Split each paths on . (a.b.c -> [a,b,c]) - // reduce to create all paths - // ([a,b,c] -> {a: true, 'a.b': true, 'a.b.c': true}) - return path.split('.').reduce((memo, path, index, parts) => { - memo[parts.slice(0, index + 1).join('.')] = true; - return memo; - }, memo); - }, {}); - this.include = Object.keys(pathSet).map(s => { - return s.split('.'); - }).sort((a, b) => { - return a.length - b.length; // Sort by number of components - }); - break; - } - - case 'redirectClassNameForKey': - this.redirectKey = restOptions.redirectClassNameForKey; - this.redirectClassName = null; - break; - - case 'includeReadPreference': - case 'subqueryReadPreference': - break; - - default: - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad option: ' + option); - } - } -} // A convenient method to perform all the steps of processing a query -// in order. -// Returns a promise for the response - an object with optional keys -// 'results' and 'count'. -// TODO: consolidate the replaceX functions - - -RestQuery.prototype.execute = function (executeOptions) { - return Promise.resolve().then(() => { - return this.buildRestWhere(); - }).then(() => { - return this.handleIncludeAll(); - }).then(() => { - return this.handleExcludeKeys(); - }).then(() => { - return this.runFind(executeOptions); - }).then(() => { - return this.runCount(); - }).then(() => { - return this.handleInclude(); - }).then(() => { - return this.runAfterFindTrigger(); - }).then(() => { - return this.response; - }); -}; - -RestQuery.prototype.each = function (callback) { - const { - config, - auth, - className, - restWhere, - restOptions, - clientSDK - } = this; // if the limit is set, use it - - restOptions.limit = restOptions.limit || 100; - restOptions.order = 'objectId'; - let finished = false; - return continueWhile(() => { - return !finished; - }, async () => { - const query = new RestQuery(config, auth, className, restWhere, restOptions, clientSDK, this.runAfterFind, this.context); - const { - results - } = await query.execute(); - results.forEach(callback); - finished = results.length < restOptions.limit; - - if (!finished) { - restWhere.objectId = Object.assign({}, restWhere.objectId, { - $gt: results[results.length - 1].objectId - }); - } - }); -}; - -RestQuery.prototype.buildRestWhere = function () { - return Promise.resolve().then(() => { - return this.getUserAndRoleACL(); - }).then(() => { - return this.redirectClassNameForKey(); - }).then(() => { - return this.validateClientClassCreation(); - }).then(() => { - return this.replaceSelect(); - }).then(() => { - return this.replaceDontSelect(); - }).then(() => { - return this.replaceInQuery(); - }).then(() => { - return this.replaceNotInQuery(); - }).then(() => { - return this.replaceEquality(); - }); -}; // Uses the Auth object to get the list of roles, adds the user id - - -RestQuery.prototype.getUserAndRoleACL = function () { - if (this.auth.isMaster) { - return Promise.resolve(); - } - - this.findOptions.acl = ['*']; - - if (this.auth.user) { - return this.auth.getUserRoles().then(roles => { - this.findOptions.acl = this.findOptions.acl.concat(roles, [this.auth.user.id]); - return; - }); - } else { - return Promise.resolve(); - } -}; // Changes the className if redirectClassNameForKey is set. -// Returns a promise. - - -RestQuery.prototype.redirectClassNameForKey = function () { - if (!this.redirectKey) { - return Promise.resolve(); - } // We need to change the class name based on the schema - - - return this.config.database.redirectClassNameForKey(this.className, this.redirectKey).then(newClassName => { - this.className = newClassName; - this.redirectClassName = newClassName; - }); -}; // Validates this operation against the allowClientClassCreation config. - - -RestQuery.prototype.validateClientClassCreation = function () { - if (this.config.allowClientClassCreation === false && !this.auth.isMaster && SchemaController.systemClasses.indexOf(this.className) === -1) { - return this.config.database.loadSchema().then(schemaController => schemaController.hasClass(this.className)).then(hasClass => { - if (hasClass !== true) { - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'This user is not allowed to access ' + 'non-existent class: ' + this.className); - } - }); - } else { - return Promise.resolve(); - } -}; - -function transformInQuery(inQueryObject, className, results) { - var values = []; - - for (var result of results) { - values.push({ - __type: 'Pointer', - className: className, - objectId: result.objectId - }); - } - - delete inQueryObject['$inQuery']; - - if (Array.isArray(inQueryObject['$in'])) { - inQueryObject['$in'] = inQueryObject['$in'].concat(values); - } else { - inQueryObject['$in'] = values; - } -} // Replaces a $inQuery clause by running the subquery, if there is an -// $inQuery clause. -// The $inQuery clause turns into an $in with values that are just -// pointers to the objects returned in the subquery. - - -RestQuery.prototype.replaceInQuery = function () { - var inQueryObject = findObjectWithKey(this.restWhere, '$inQuery'); - - if (!inQueryObject) { - return; - } // The inQuery value must have precisely two keys - where and className - - - var inQueryValue = inQueryObject['$inQuery']; - - if (!inQueryValue.where || !inQueryValue.className) { - throw new Parse.Error(Parse.Error.INVALID_QUERY, 'improper usage of $inQuery'); - } - - const additionalOptions = { - redirectClassNameForKey: inQueryValue.redirectClassNameForKey - }; - - if (this.restOptions.subqueryReadPreference) { - additionalOptions.readPreference = this.restOptions.subqueryReadPreference; - additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference; - } else if (this.restOptions.readPreference) { - additionalOptions.readPreference = this.restOptions.readPreference; - } - - var subquery = new RestQuery(this.config, this.auth, inQueryValue.className, inQueryValue.where, additionalOptions); - return subquery.execute().then(response => { - transformInQuery(inQueryObject, subquery.className, response.results); // Recurse to repeat - - return this.replaceInQuery(); - }); -}; - -function transformNotInQuery(notInQueryObject, className, results) { - var values = []; - - for (var result of results) { - values.push({ - __type: 'Pointer', - className: className, - objectId: result.objectId - }); - } - - delete notInQueryObject['$notInQuery']; - - if (Array.isArray(notInQueryObject['$nin'])) { - notInQueryObject['$nin'] = notInQueryObject['$nin'].concat(values); - } else { - notInQueryObject['$nin'] = values; - } -} // Replaces a $notInQuery clause by running the subquery, if there is an -// $notInQuery clause. -// The $notInQuery clause turns into a $nin with values that are just -// pointers to the objects returned in the subquery. - - -RestQuery.prototype.replaceNotInQuery = function () { - var notInQueryObject = findObjectWithKey(this.restWhere, '$notInQuery'); - - if (!notInQueryObject) { - return; - } // The notInQuery value must have precisely two keys - where and className - - - var notInQueryValue = notInQueryObject['$notInQuery']; - - if (!notInQueryValue.where || !notInQueryValue.className) { - throw new Parse.Error(Parse.Error.INVALID_QUERY, 'improper usage of $notInQuery'); - } - - const additionalOptions = { - redirectClassNameForKey: notInQueryValue.redirectClassNameForKey - }; - - if (this.restOptions.subqueryReadPreference) { - additionalOptions.readPreference = this.restOptions.subqueryReadPreference; - additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference; - } else if (this.restOptions.readPreference) { - additionalOptions.readPreference = this.restOptions.readPreference; - } - - var subquery = new RestQuery(this.config, this.auth, notInQueryValue.className, notInQueryValue.where, additionalOptions); - return subquery.execute().then(response => { - transformNotInQuery(notInQueryObject, subquery.className, response.results); // Recurse to repeat - - return this.replaceNotInQuery(); - }); -}; // Used to get the deepest object from json using dot notation. - - -const getDeepestObjectFromKey = (json, key, idx, src) => { - if (key in json) { - return json[key]; - } - - src.splice(1); // Exit Early -}; - -const transformSelect = (selectObject, key, objects) => { - var values = []; - - for (var result of objects) { - values.push(key.split('.').reduce(getDeepestObjectFromKey, result)); - } - - delete selectObject['$select']; - - if (Array.isArray(selectObject['$in'])) { - selectObject['$in'] = selectObject['$in'].concat(values); - } else { - selectObject['$in'] = values; - } -}; // Replaces a $select clause by running the subquery, if there is a -// $select clause. -// The $select clause turns into an $in with values selected out of -// the subquery. -// Returns a possible-promise. - - -RestQuery.prototype.replaceSelect = function () { - var selectObject = findObjectWithKey(this.restWhere, '$select'); - - if (!selectObject) { - return; - } // The select value must have precisely two keys - query and key - - - var selectValue = selectObject['$select']; // iOS SDK don't send where if not set, let it pass - - if (!selectValue.query || !selectValue.key || typeof selectValue.query !== 'object' || !selectValue.query.className || Object.keys(selectValue).length !== 2) { - throw new Parse.Error(Parse.Error.INVALID_QUERY, 'improper usage of $select'); - } - - const additionalOptions = { - redirectClassNameForKey: selectValue.query.redirectClassNameForKey - }; - - if (this.restOptions.subqueryReadPreference) { - additionalOptions.readPreference = this.restOptions.subqueryReadPreference; - additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference; - } else if (this.restOptions.readPreference) { - additionalOptions.readPreference = this.restOptions.readPreference; - } - - var subquery = new RestQuery(this.config, this.auth, selectValue.query.className, selectValue.query.where, additionalOptions); - return subquery.execute().then(response => { - transformSelect(selectObject, selectValue.key, response.results); // Keep replacing $select clauses - - return this.replaceSelect(); - }); -}; - -const transformDontSelect = (dontSelectObject, key, objects) => { - var values = []; - - for (var result of objects) { - values.push(key.split('.').reduce(getDeepestObjectFromKey, result)); - } - - delete dontSelectObject['$dontSelect']; - - if (Array.isArray(dontSelectObject['$nin'])) { - dontSelectObject['$nin'] = dontSelectObject['$nin'].concat(values); - } else { - dontSelectObject['$nin'] = values; - } -}; // Replaces a $dontSelect clause by running the subquery, if there is a -// $dontSelect clause. -// The $dontSelect clause turns into an $nin with values selected out of -// the subquery. -// Returns a possible-promise. - - -RestQuery.prototype.replaceDontSelect = function () { - var dontSelectObject = findObjectWithKey(this.restWhere, '$dontSelect'); - - if (!dontSelectObject) { - return; - } // The dontSelect value must have precisely two keys - query and key - - - var dontSelectValue = dontSelectObject['$dontSelect']; - - if (!dontSelectValue.query || !dontSelectValue.key || typeof dontSelectValue.query !== 'object' || !dontSelectValue.query.className || Object.keys(dontSelectValue).length !== 2) { - throw new Parse.Error(Parse.Error.INVALID_QUERY, 'improper usage of $dontSelect'); - } - - const additionalOptions = { - redirectClassNameForKey: dontSelectValue.query.redirectClassNameForKey - }; - - if (this.restOptions.subqueryReadPreference) { - additionalOptions.readPreference = this.restOptions.subqueryReadPreference; - additionalOptions.subqueryReadPreference = this.restOptions.subqueryReadPreference; - } else if (this.restOptions.readPreference) { - additionalOptions.readPreference = this.restOptions.readPreference; - } - - var subquery = new RestQuery(this.config, this.auth, dontSelectValue.query.className, dontSelectValue.query.where, additionalOptions); - return subquery.execute().then(response => { - transformDontSelect(dontSelectObject, dontSelectValue.key, response.results); // Keep replacing $dontSelect clauses - - return this.replaceDontSelect(); - }); -}; - -const cleanResultAuthData = function (result) { - delete result.password; - - if (result.authData) { - Object.keys(result.authData).forEach(provider => { - if (result.authData[provider] === null) { - delete result.authData[provider]; - } - }); - - if (Object.keys(result.authData).length == 0) { - delete result.authData; - } - } -}; - -const replaceEqualityConstraint = constraint => { - if (typeof constraint !== 'object') { - return constraint; - } - - const equalToObject = {}; - let hasDirectConstraint = false; - let hasOperatorConstraint = false; - - for (const key in constraint) { - if (key.indexOf('$') !== 0) { - hasDirectConstraint = true; - equalToObject[key] = constraint[key]; - } else { - hasOperatorConstraint = true; - } - } - - if (hasDirectConstraint && hasOperatorConstraint) { - constraint['$eq'] = equalToObject; - Object.keys(equalToObject).forEach(key => { - delete constraint[key]; - }); - } - - return constraint; -}; - -RestQuery.prototype.replaceEquality = function () { - if (typeof this.restWhere !== 'object') { - return; - } - - for (const key in this.restWhere) { - this.restWhere[key] = replaceEqualityConstraint(this.restWhere[key]); - } -}; // Returns a promise for whether it was successful. -// Populates this.response with an object that only has 'results'. - - -RestQuery.prototype.runFind = function (options = {}) { - if (this.findOptions.limit === 0) { - this.response = { - results: [] - }; - return Promise.resolve(); - } - - const findOptions = Object.assign({}, this.findOptions); - - if (this.keys) { - findOptions.keys = this.keys.map(key => { - return key.split('.')[0]; - }); - } - - if (options.op) { - findOptions.op = options.op; - } - - return this.config.database.find(this.className, this.restWhere, findOptions, this.auth).then(results => { - if (this.className === '_User' && findOptions.explain !== true) { - for (var result of results) { - cleanResultAuthData(result); - } - } - - this.config.filesController.expandFilesInObject(this.config, results); - - if (this.redirectClassName) { - for (var r of results) { - r.className = this.redirectClassName; - } - } - - this.response = { - results: results - }; - }); -}; // Returns a promise for whether it was successful. -// Populates this.response.count with the count - - -RestQuery.prototype.runCount = function () { - if (!this.doCount) { - return; - } - - this.findOptions.count = true; - delete this.findOptions.skip; - delete this.findOptions.limit; - return this.config.database.find(this.className, this.restWhere, this.findOptions).then(c => { - this.response.count = c; - }); -}; // Augments this.response with all pointers on an object - - -RestQuery.prototype.handleIncludeAll = function () { - if (!this.includeAll) { - return; - } - - return this.config.database.loadSchema().then(schemaController => schemaController.getOneSchema(this.className)).then(schema => { - const includeFields = []; - const keyFields = []; - - for (const field in schema.fields) { - if (schema.fields[field].type && schema.fields[field].type === 'Pointer' || schema.fields[field].type && schema.fields[field].type === 'Array') { - includeFields.push([field]); - keyFields.push(field); - } - } // Add fields to include, keys, remove dups - - - this.include = [...new Set([...this.include, ...includeFields])]; // if this.keys not set, then all keys are already included - - if (this.keys) { - this.keys = [...new Set([...this.keys, ...keyFields])]; - } - }); -}; // Updates property `this.keys` to contain all keys but the ones unselected. - - -RestQuery.prototype.handleExcludeKeys = function () { - if (!this.excludeKeys) { - return; - } - - if (this.keys) { - this.keys = this.keys.filter(k => !this.excludeKeys.includes(k)); - return; - } - - return this.config.database.loadSchema().then(schemaController => schemaController.getOneSchema(this.className)).then(schema => { - const fields = Object.keys(schema.fields); - this.keys = fields.filter(k => !this.excludeKeys.includes(k)); - }); -}; // Augments this.response with data at the paths provided in this.include. - - -RestQuery.prototype.handleInclude = function () { - if (this.include.length == 0) { - return; - } - - var pathResponse = includePath(this.config, this.auth, this.response, this.include[0], this.restOptions); - - if (pathResponse.then) { - return pathResponse.then(newResponse => { - this.response = newResponse; - this.include = this.include.slice(1); - return this.handleInclude(); - }); - } else if (this.include.length > 0) { - this.include = this.include.slice(1); - return this.handleInclude(); - } - - return pathResponse; -}; //Returns a promise of a processed set of results - - -RestQuery.prototype.runAfterFindTrigger = function () { - if (!this.response) { - return; - } - - if (!this.runAfterFind) { - return; - } // Avoid doing any setup for triggers if there is no 'afterFind' trigger for this class. - - - const hasAfterFindHook = triggers.triggerExists(this.className, triggers.Types.afterFind, this.config.applicationId); - - if (!hasAfterFindHook) { - return Promise.resolve(); - } // Skip Aggregate and Distinct Queries - - - if (this.findOptions.pipeline || this.findOptions.distinct) { - return Promise.resolve(); - } - - const json = Object.assign({}, this.restOptions); - json.where = this.restWhere; - const parseQuery = new Parse.Query(this.className); - parseQuery.withJSON(json); // Run afterFind trigger and set the new results - - return triggers.maybeRunAfterFindTrigger(triggers.Types.afterFind, this.auth, this.className, this.response.results, this.config, parseQuery, this.context).then(results => { - // Ensure we properly set the className back - if (this.redirectClassName) { - this.response.results = results.map(object => { - if (object instanceof Parse.Object) { - object = object.toJSON(); - } - - object.className = this.redirectClassName; - return object; - }); - } else { - this.response.results = results; - } - }); -}; // Adds included values to the response. -// Path is a list of field names. -// Returns a promise for an augmented response. - - -function includePath(config, auth, response, path, restOptions = {}) { - var pointers = findPointers(response.results, path); - - if (pointers.length == 0) { - return response; - } - - const pointersHash = {}; - - for (var pointer of pointers) { - if (!pointer) { - continue; - } - - const className = pointer.className; // only include the good pointers - - if (className) { - pointersHash[className] = pointersHash[className] || new Set(); - pointersHash[className].add(pointer.objectId); - } - } - - const includeRestOptions = {}; - - if (restOptions.keys) { - const keys = new Set(restOptions.keys.split(',')); - const keySet = Array.from(keys).reduce((set, key) => { - const keyPath = key.split('.'); - let i = 0; - - for (i; i < path.length; i++) { - if (path[i] != keyPath[i]) { - return set; - } - } - - if (i < keyPath.length) { - set.add(keyPath[i]); - } - - return set; - }, new Set()); - - if (keySet.size > 0) { - includeRestOptions.keys = Array.from(keySet).join(','); - } - } - - if (restOptions.includeReadPreference) { - includeRestOptions.readPreference = restOptions.includeReadPreference; - includeRestOptions.includeReadPreference = restOptions.includeReadPreference; - } else if (restOptions.readPreference) { - includeRestOptions.readPreference = restOptions.readPreference; - } - - const queryPromises = Object.keys(pointersHash).map(className => { - const objectIds = Array.from(pointersHash[className]); - let where; - - if (objectIds.length === 1) { - where = { - objectId: objectIds[0] - }; - } else { - where = { - objectId: { - $in: objectIds - } - }; - } - - var query = new RestQuery(config, auth, className, where, includeRestOptions); - return query.execute({ - op: 'get' - }).then(results => { - results.className = className; - return Promise.resolve(results); - }); - }); // Get the objects for all these object ids - - return Promise.all(queryPromises).then(responses => { - var replace = responses.reduce((replace, includeResponse) => { - for (var obj of includeResponse.results) { - obj.__type = 'Object'; - obj.className = includeResponse.className; - - if (obj.className == '_User' && !auth.isMaster) { - delete obj.sessionToken; - delete obj.authData; - } - - replace[obj.objectId] = obj; - } - - return replace; - }, {}); - var resp = { - results: replacePointers(response.results, path, replace) - }; - - if (response.count) { - resp.count = response.count; - } - - return resp; - }); -} // Object may be a list of REST-format object to find pointers in, or -// it may be a single object. -// If the path yields things that aren't pointers, this throws an error. -// Path is a list of fields to search into. -// Returns a list of pointers in REST format. - - -function findPointers(object, path) { - if (object instanceof Array) { - var answer = []; - - for (var x of object) { - answer = answer.concat(findPointers(x, path)); - } - - return answer; - } - - if (typeof object !== 'object' || !object) { - return []; - } - - if (path.length == 0) { - if (object === null || object.__type == 'Pointer') { - return [object]; - } - - return []; - } - - var subobject = object[path[0]]; - - if (!subobject) { - return []; - } - - return findPointers(subobject, path.slice(1)); -} // Object may be a list of REST-format objects to replace pointers -// in, or it may be a single object. -// Path is a list of fields to search into. -// replace is a map from object id -> object. -// Returns something analogous to object, but with the appropriate -// pointers inflated. - - -function replacePointers(object, path, replace) { - if (object instanceof Array) { - return object.map(obj => replacePointers(obj, path, replace)).filter(obj => typeof obj !== 'undefined'); - } - - if (typeof object !== 'object' || !object) { - return object; - } - - if (path.length === 0) { - if (object && object.__type === 'Pointer') { - return replace[object.objectId]; - } - - return object; - } - - var subobject = object[path[0]]; - - if (!subobject) { - return object; - } - - var newsub = replacePointers(subobject, path.slice(1), replace); - var answer = {}; - - for (var key in object) { - if (key == path[0]) { - answer[key] = newsub; - } else { - answer[key] = object[key]; - } - } - - return answer; -} // Finds a subobject that has the given key, if there is one. -// Returns undefined otherwise. - - -function findObjectWithKey(root, key) { - if (typeof root !== 'object') { - return; - } - - if (root instanceof Array) { - for (var item of root) { - const answer = findObjectWithKey(item, key); - - if (answer) { - return answer; - } - } - } - - if (root && root[key]) { - return root; - } - - for (var subkey in root) { - const answer = findObjectWithKey(root[subkey], key); - - if (answer) { - return answer; - } - } -} - -module.exports = RestQuery; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9SZXN0UXVlcnkuanMiXSwibmFtZXMiOlsiU2NoZW1hQ29udHJvbGxlciIsInJlcXVpcmUiLCJQYXJzZSIsInRyaWdnZXJzIiwiY29udGludWVXaGlsZSIsIkFsd2F5c1NlbGVjdGVkS2V5cyIsIlJlc3RRdWVyeSIsImNvbmZpZyIsImF1dGgiLCJjbGFzc05hbWUiLCJyZXN0V2hlcmUiLCJyZXN0T3B0aW9ucyIsImNsaWVudFNESyIsInJ1bkFmdGVyRmluZCIsImNvbnRleHQiLCJyZXNwb25zZSIsImZpbmRPcHRpb25zIiwiaXNNYXN0ZXIiLCJ1c2VyIiwiRXJyb3IiLCJJTlZBTElEX1NFU1NJT05fVE9LRU4iLCIkYW5kIiwiX190eXBlIiwib2JqZWN0SWQiLCJpZCIsImRvQ291bnQiLCJpbmNsdWRlQWxsIiwiaW5jbHVkZSIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImtleXNGb3JJbmNsdWRlIiwia2V5cyIsInNwbGl0IiwiZmlsdGVyIiwia2V5IiwibGVuZ3RoIiwibWFwIiwic2xpY2UiLCJsYXN0SW5kZXhPZiIsImpvaW4iLCJvcHRpb24iLCJjb25jYXQiLCJBcnJheSIsImZyb20iLCJTZXQiLCJleGNsdWRlIiwiZXhjbHVkZUtleXMiLCJrIiwiaW5kZXhPZiIsImZpZWxkcyIsIm9yZGVyIiwic29ydCIsInJlZHVjZSIsInNvcnRNYXAiLCJmaWVsZCIsInRyaW0iLCJzY29yZSIsIiRtZXRhIiwicGF0aHMiLCJpbmNsdWRlcyIsInBhdGhTZXQiLCJtZW1vIiwicGF0aCIsImluZGV4IiwicGFydHMiLCJzIiwiYSIsImIiLCJyZWRpcmVjdEtleSIsInJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5IiwicmVkaXJlY3RDbGFzc05hbWUiLCJJTlZBTElEX0pTT04iLCJleGVjdXRlIiwiZXhlY3V0ZU9wdGlvbnMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInRoZW4iLCJidWlsZFJlc3RXaGVyZSIsImhhbmRsZUluY2x1ZGVBbGwiLCJoYW5kbGVFeGNsdWRlS2V5cyIsInJ1bkZpbmQiLCJydW5Db3VudCIsImhhbmRsZUluY2x1ZGUiLCJydW5BZnRlckZpbmRUcmlnZ2VyIiwiZWFjaCIsImNhbGxiYWNrIiwibGltaXQiLCJmaW5pc2hlZCIsInF1ZXJ5IiwicmVzdWx0cyIsImZvckVhY2giLCJhc3NpZ24iLCIkZ3QiLCJnZXRVc2VyQW5kUm9sZUFDTCIsInZhbGlkYXRlQ2xpZW50Q2xhc3NDcmVhdGlvbiIsInJlcGxhY2VTZWxlY3QiLCJyZXBsYWNlRG9udFNlbGVjdCIsInJlcGxhY2VJblF1ZXJ5IiwicmVwbGFjZU5vdEluUXVlcnkiLCJyZXBsYWNlRXF1YWxpdHkiLCJhY2wiLCJnZXRVc2VyUm9sZXMiLCJyb2xlcyIsImRhdGFiYXNlIiwibmV3Q2xhc3NOYW1lIiwiYWxsb3dDbGllbnRDbGFzc0NyZWF0aW9uIiwic3lzdGVtQ2xhc3NlcyIsImxvYWRTY2hlbWEiLCJzY2hlbWFDb250cm9sbGVyIiwiaGFzQ2xhc3MiLCJPUEVSQVRJT05fRk9SQklEREVOIiwidHJhbnNmb3JtSW5RdWVyeSIsImluUXVlcnlPYmplY3QiLCJ2YWx1ZXMiLCJyZXN1bHQiLCJwdXNoIiwiaXNBcnJheSIsImZpbmRPYmplY3RXaXRoS2V5IiwiaW5RdWVyeVZhbHVlIiwid2hlcmUiLCJJTlZBTElEX1FVRVJZIiwiYWRkaXRpb25hbE9wdGlvbnMiLCJzdWJxdWVyeVJlYWRQcmVmZXJlbmNlIiwicmVhZFByZWZlcmVuY2UiLCJzdWJxdWVyeSIsInRyYW5zZm9ybU5vdEluUXVlcnkiLCJub3RJblF1ZXJ5T2JqZWN0Iiwibm90SW5RdWVyeVZhbHVlIiwiZ2V0RGVlcGVzdE9iamVjdEZyb21LZXkiLCJqc29uIiwiaWR4Iiwic3JjIiwic3BsaWNlIiwidHJhbnNmb3JtU2VsZWN0Iiwic2VsZWN0T2JqZWN0Iiwib2JqZWN0cyIsInNlbGVjdFZhbHVlIiwidHJhbnNmb3JtRG9udFNlbGVjdCIsImRvbnRTZWxlY3RPYmplY3QiLCJkb250U2VsZWN0VmFsdWUiLCJjbGVhblJlc3VsdEF1dGhEYXRhIiwicGFzc3dvcmQiLCJhdXRoRGF0YSIsInByb3ZpZGVyIiwicmVwbGFjZUVxdWFsaXR5Q29uc3RyYWludCIsImNvbnN0cmFpbnQiLCJlcXVhbFRvT2JqZWN0IiwiaGFzRGlyZWN0Q29uc3RyYWludCIsImhhc09wZXJhdG9yQ29uc3RyYWludCIsIm9wdGlvbnMiLCJvcCIsImZpbmQiLCJleHBsYWluIiwiZmlsZXNDb250cm9sbGVyIiwiZXhwYW5kRmlsZXNJbk9iamVjdCIsInIiLCJjb3VudCIsInNraXAiLCJjIiwiZ2V0T25lU2NoZW1hIiwic2NoZW1hIiwiaW5jbHVkZUZpZWxkcyIsImtleUZpZWxkcyIsInR5cGUiLCJwYXRoUmVzcG9uc2UiLCJpbmNsdWRlUGF0aCIsIm5ld1Jlc3BvbnNlIiwiaGFzQWZ0ZXJGaW5kSG9vayIsInRyaWdnZXJFeGlzdHMiLCJUeXBlcyIsImFmdGVyRmluZCIsImFwcGxpY2F0aW9uSWQiLCJwaXBlbGluZSIsImRpc3RpbmN0IiwicGFyc2VRdWVyeSIsIlF1ZXJ5Iiwid2l0aEpTT04iLCJtYXliZVJ1bkFmdGVyRmluZFRyaWdnZXIiLCJvYmplY3QiLCJ0b0pTT04iLCJwb2ludGVycyIsImZpbmRQb2ludGVycyIsInBvaW50ZXJzSGFzaCIsInBvaW50ZXIiLCJhZGQiLCJpbmNsdWRlUmVzdE9wdGlvbnMiLCJrZXlTZXQiLCJzZXQiLCJrZXlQYXRoIiwiaSIsInNpemUiLCJpbmNsdWRlUmVhZFByZWZlcmVuY2UiLCJxdWVyeVByb21pc2VzIiwib2JqZWN0SWRzIiwiJGluIiwiYWxsIiwicmVzcG9uc2VzIiwicmVwbGFjZSIsImluY2x1ZGVSZXNwb25zZSIsIm9iaiIsInNlc3Npb25Ub2tlbiIsInJlc3AiLCJyZXBsYWNlUG9pbnRlcnMiLCJhbnN3ZXIiLCJ4Iiwic3Vib2JqZWN0IiwibmV3c3ViIiwicm9vdCIsIml0ZW0iLCJzdWJrZXkiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFFQSxJQUFJ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LE1BQU0sQ0FBQ3pLLEdBQUQsQ0FBTixHQUFjNEssTUFBZDtBQUNELEtBRkQsTUFFTztBQUNMSCxNQUFBQSxNQUFNLENBQUN6SyxHQUFELENBQU4sR0FBY2dKLE1BQU0sQ0FBQ2hKLEdBQUQsQ0FBcEI7QUFDRDtBQUNGOztBQUNELFNBQU95SyxNQUFQO0FBQ0QsQyxDQUVEO0FBQ0E7OztBQUNBLFNBQVN0RixpQkFBVCxDQUEyQjBGLElBQTNCLEVBQWlDN0ssR0FBakMsRUFBc0M7QUFDcEMsTUFBSSxPQUFPNkssSUFBUCxLQUFnQixRQUFwQixFQUE4QjtBQUM1QjtBQUNEOztBQUNELE1BQUlBLElBQUksWUFBWXJLLEtBQXBCLEVBQTJCO0FBQ3pCLFNBQUssSUFBSXNLLElBQVQsSUFBaUJELElBQWpCLEVBQXVCO0FBQ3JCLFlBQU1KLE1BQU0sR0FBR3RGLGlCQUFpQixDQUFDMkYsSUFBRCxFQUFPOUssR0FBUCxDQUFoQzs7QUFDQSxVQUFJeUssTUFBSixFQUFZO0FBQ1YsZUFBT0EsTUFBUDtBQUNEO0FBQ0Y7QUFDRjs7QUFDRCxNQUFJSSxJQUFJLElBQUlBLElBQUksQ0FBQzdLLEdBQUQsQ0FBaEIsRUFBdUI7QUFDckIsV0FBTzZLLElBQVA7QUFDRDs7QUFDRCxPQUFLLElBQUlFLE1BQVQsSUFBbUJGLElBQW5CLEVBQXlCO0FBQ3ZCLFVBQU1KLE1BQU0sR0FBR3RGLGlCQUFpQixDQUFDMEYsSUFBSSxDQUFDRSxNQUFELENBQUwsRUFBZS9LLEdBQWYsQ0FBaEM7O0FBQ0EsUUFBSXlLLE1BQUosRUFBWTtBQUNWLGFBQU9BLE1BQVA7QUFDRDtBQUNGO0FBQ0Y7O0FBRURPLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQi9NLFNBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQW4gb2JqZWN0IHRoYXQgZW5jYXBzdWxhdGVzIGV2ZXJ5dGhpbmcgd2UgbmVlZCB0byBydW4gYSAnZmluZCdcbi8vIG9wZXJhdGlvbiwgZW5jb2RlZCBpbiB0aGUgUkVTVCBBUEkgZm9ybWF0LlxuXG52YXIgU2NoZW1hQ29udHJvbGxlciA9IHJlcXVpcmUoJy4vQ29udHJvbGxlcnMvU2NoZW1hQ29udHJvbGxlcicpO1xudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuY29uc3QgdHJpZ2dlcnMgPSByZXF1aXJlKCcuL3RyaWdnZXJzJyk7XG5jb25zdCB7IGNvbnRpbnVlV2hpbGUgfSA9IHJlcXVpcmUoJ3BhcnNlL2xpYi9ub2RlL3Byb21pc2VVdGlscycpO1xuY29uc3QgQWx3YXlzU2VsZWN0ZWRLZXlzID0gWydvYmplY3RJZCcsICdjcmVhdGVkQXQnLCAndXBkYXRlZEF0JywgJ0FDTCddO1xuLy8gcmVzdE9wdGlvbnMgY2FuIGluY2x1ZGU6XG4vLyAgIHNraXBcbi8vICAgbGltaXRcbi8vICAgb3JkZXJcbi8vICAgY291bnRcbi8vICAgaW5jbHVkZVxuLy8gICBrZXlzXG4vLyAgIGV4Y2x1ZGVLZXlzXG4vLyAgIHJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5XG4vLyAgIHJlYWRQcmVmZXJlbmNlXG4vLyAgIGluY2x1ZGVSZWFkUHJlZmVyZW5jZVxuLy8gICBzdWJxdWVyeVJlYWRQcmVmZXJlbmNlXG5mdW5jdGlvbiBSZXN0UXVlcnkoXG4gIGNvbmZpZyxcbiAgYXV0aCxcbiAgY2xhc3NOYW1lLFxuICByZXN0V2hlcmUgPSB7fSxcbiAgcmVzdE9wdGlvbnMgPSB7fSxcbiAgY2xpZW50U0RLLFxuICBydW5BZnRlckZpbmQgPSB0cnVlLFxuICBjb250ZXh0XG4pIHtcbiAgdGhpcy5jb25maWcgPSBjb25maWc7XG4gIHRoaXMuYXV0aCA9IGF1dGg7XG4gIHRoaXMuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xuICB0aGlzLnJlc3RXaGVyZSA9IHJlc3RXaGVyZTtcbiAgdGhpcy5yZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zO1xuICB0aGlzLmNsaWVudFNESyA9IGNsaWVudFNESztcbiAgdGhpcy5ydW5BZnRlckZpbmQgPSBydW5BZnRlckZpbmQ7XG4gIHRoaXMucmVzcG9uc2UgPSBudWxsO1xuICB0aGlzLmZpbmRPcHRpb25zID0ge307XG4gIHRoaXMuY29udGV4dCA9IGNvbnRleHQgfHwge307XG5cbiAgaWYgKCF0aGlzLmF1dGguaXNNYXN0ZXIpIHtcbiAgICBpZiAodGhpcy5jbGFzc05hbWUgPT0gJ19TZXNzaW9uJykge1xuICAgICAgaWYgKCF0aGlzLmF1dGgudXNlcikge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOLCAnSW52YWxpZCBzZXNzaW9uIHRva2VuJyk7XG4gICAgICB9XG4gICAgICB0aGlzLnJlc3RXaGVyZSA9IHtcbiAgICAgICAgJGFuZDogW1xuICAgICAgICAgIHRoaXMucmVzdFdoZXJlLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHVzZXI6IHtcbiAgICAgICAgICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICAgICAgICAgIGNsYXNzTmFtZTogJ19Vc2VyJyxcbiAgICAgICAgICAgICAgb2JqZWN0SWQ6IHRoaXMuYXV0aC51c2VyLmlkLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICB0aGlzLmRvQ291bnQgPSBmYWxzZTtcbiAgdGhpcy5pbmNsdWRlQWxsID0gZmFsc2U7XG5cbiAgLy8gVGhlIGZvcm1hdCBmb3IgdGhpcy5pbmNsdWRlIGlzIG5vdCB0aGUgc2FtZSBhcyB0aGUgZm9ybWF0IGZvciB0aGVcbiAgLy8gaW5jbHVkZSBvcHRpb24gLSBpdCdzIHRoZSBwYXRocyB3ZSBzaG91bGQgaW5jbHVkZSwgaW4gb3JkZXIsXG4gIC8vIHN0b3JlZCBhcyBhcnJheXMsIHRha2luZyBpbnRvIGFjY291bnQgdGhhdCB3ZSBuZWVkIHRvIGluY2x1ZGUgZm9vXG4gIC8vIGJlZm9yZSBpbmNsdWRpbmcgZm9vLmJhci4gQWxzbyBpdCBzaG91bGQgZGVkdXBlLlxuICAvLyBGb3IgZXhhbXBsZSwgcGFzc2luZyBhbiBhcmcgb2YgaW5jbHVkZT1mb28uYmFyLGZvby5iYXogY291bGQgbGVhZCB0b1xuICAvLyB0aGlzLmluY2x1ZGUgPSBbWydmb28nXSwgWydmb28nLCAnYmF6J10sIFsnZm9vJywgJ2JhciddXVxuICB0aGlzLmluY2x1ZGUgPSBbXTtcblxuICAvLyBJZiB3ZSBoYXZlIGtleXMsIHdlIHByb2JhYmx5IHdhbnQgdG8gZm9yY2Ugc29tZSBpbmNsdWRlcyAobi0xIGxldmVsKVxuICAvLyBTZWUgaXNzdWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9wYXJzZS1jb21tdW5pdHkvcGFyc2Utc2VydmVyL2lzc3Vlcy8zMTg1XG4gIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocmVzdE9wdGlvbnMsICdrZXlzJykpIHtcbiAgICBjb25zdCBrZXlzRm9ySW5jbHVkZSA9IHJlc3RPcHRpb25zLmtleXNcbiAgICAgIC5zcGxpdCgnLCcpXG4gICAgICAuZmlsdGVyKGtleSA9PiB7XG4gICAgICAgIC8vIEF0IGxlYXN0IDIgY29tcG9uZW50c1xuICAgICAgICByZXR1cm4ga2V5LnNwbGl0KCcuJykubGVuZ3RoID4gMTtcbiAgICAgIH0pXG4gICAgICAubWFwKGtleSA9PiB7XG4gICAgICAgIC8vIFNsaWNlIHRoZSBsYXN0IGNvbXBvbmVudCAoYS5iLmMgLT4gYS5iKVxuICAgICAgICAvLyBPdGhlcndpc2Ugd2UnbGwgaW5jbHVkZSBvbmUgbGV2ZWwgdG9vIG11Y2guXG4gICAgICAgIHJldHVybiBrZXkuc2xpY2UoMCwga2V5Lmxhc3RJbmRleE9mKCcuJykpO1xuICAgICAgfSlcbiAgICAgIC5qb2luKCcsJyk7XG5cbiAgICAvLyBDb25jYXQgdGhlIHBvc3NpYmx5IHByZXNlbnQgaW5jbHVkZSBzdHJpbmcgd2l0aCB0aGUgb25lIGZyb20gdGhlIGtleXNcbiAgICAvLyBEZWR1cCAvIHNvcnRpbmcgaXMgaGFuZGxlIGluICdpbmNsdWRlJyBjYXNlLlxuICAgIGlmIChrZXlzRm9ySW5jbHVkZS5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAoIXJlc3RPcHRpb25zLmluY2x1ZGUgfHwgcmVzdE9wdGlvbnMuaW5jbHVkZS5sZW5ndGggPT0gMCkge1xuICAgICAgICByZXN0T3B0aW9ucy5pbmNsdWRlID0ga2V5c0ZvckluY2x1ZGU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN0T3B0aW9ucy5pbmNsdWRlICs9ICcsJyArIGtleXNGb3JJbmNsdWRlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZvciAodmFyIG9wdGlvbiBpbiByZXN0T3B0aW9ucykge1xuICAgIHN3aXRjaCAob3B0aW9uKSB7XG4gICAgICBjYXNlICdrZXlzJzoge1xuICAgICAgICBjb25zdCBrZXlzID0gcmVzdE9wdGlvbnMua2V5cy5zcGxpdCgnLCcpLmZpbHRlcihrZXkgPT4ga2V5Lmxlbmd0aCA+IDApLmNvbmNhdChBbHdheXNTZWxlY3RlZEtleXMpO1xuICAgICAgICB0aGlzLmtleXMgPSBBcnJheS5mcm9tKG5ldyBTZXQoa2V5cykpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2V4Y2x1ZGVLZXlzJzoge1xuICAgICAgICBjb25zdCBleGNsdWRlID0gcmVzdE9wdGlvbnMuZXhjbHVkZUtleXNcbiAgICAgICAgICAuc3BsaXQoJywnKVxuICAgICAgICAgIC5maWx0ZXIoayA9PiBBbHdheXNTZWxlY3RlZEtleXMuaW5kZXhPZihrKSA8IDApO1xuICAgICAgICB0aGlzLmV4Y2x1ZGVLZXlzID0gQXJyYXkuZnJvbShuZXcgU2V0KGV4Y2x1ZGUpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdjb3VudCc6XG4gICAgICAgIHRoaXMuZG9Db3VudCA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW5jbHVkZUFsbCc6XG4gICAgICAgIHRoaXMuaW5jbHVkZUFsbCA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnZXhwbGFpbic6XG4gICAgICBjYXNlICdoaW50JzpcbiAgICAgIGNhc2UgJ2Rpc3RpbmN0JzpcbiAgICAgIGNhc2UgJ3BpcGVsaW5lJzpcbiAgICAgIGNhc2UgJ3NraXAnOlxuICAgICAgY2FzZSAnbGltaXQnOlxuICAgICAgY2FzZSAncmVhZFByZWZlcmVuY2UnOlxuICAgICAgICB0aGlzLmZpbmRPcHRpb25zW29wdGlvbl0gPSByZXN0T3B0aW9uc1tvcHRpb25dO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ29yZGVyJzpcbiAgICAgICAgdmFyIGZpZWxkcyA9IHJlc3RPcHRpb25zLm9yZGVyLnNwbGl0KCcsJyk7XG4gICAgICAgIHRoaXMuZmluZE9wdGlvbnMuc29ydCA9IGZpZWxkcy5yZWR1Y2UoKHNvcnRNYXAsIGZpZWxkKSA9PiB7XG4gICAgICAgICAgZmllbGQgPSBmaWVsZC50cmltKCk7XG4gICAgICAgICAgaWYgKGZpZWxkID09PSAnJHNjb3JlJykge1xuICAgICAgICAgICAgc29ydE1hcC5zY29yZSA9IHsgJG1ldGE6ICd0ZXh0U2NvcmUnIH07XG4gICAgICAgICAgfSBlbHNlIGlmIChmaWVsZFswXSA9PSAnLScpIHtcbiAgICAgICAgICAgIHNvcnRNYXBbZmllbGQuc2xpY2UoMSldID0gLTE7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNvcnRNYXBbZmllbGRdID0gMTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHNvcnRNYXA7XG4gICAgICAgIH0sIHt9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdpbmNsdWRlJzoge1xuICAgICAgICBjb25zdCBwYXRocyA9IHJlc3RPcHRpb25zLmluY2x1ZGUuc3BsaXQoJywnKTtcbiAgICAgICAgaWYgKHBhdGhzLmluY2x1ZGVzKCcqJykpIHtcbiAgICAgICAgICB0aGlzLmluY2x1ZGVBbGwgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIC8vIExvYWQgdGhlIGV4aXN0aW5nIGluY2x1ZGVzIChmcm9tIGtleXMpXG4gICAgICAgIGNvbnN0IHBhdGhTZXQgPSBwYXRocy5yZWR1Y2UoKG1lbW8sIHBhdGgpID0+IHtcbiAgICAgICAgICAvLyBTcGxpdCBlYWNoIHBhdGhzIG9uIC4gKGEuYi5jIC0+IFthLGIsY10pXG4gICAgICAgICAgLy8gcmVkdWNlIHRvIGNyZWF0ZSBhbGwgcGF0aHNcbiAgICAgICAgICAvLyAoW2EsYixjXSAtPiB7YTogdHJ1ZSwgJ2EuYic6IHRydWUsICdhLmIuYyc6IHRydWV9KVxuICAgICAgICAgIHJldHVybiBwYXRoLnNwbGl0KCcuJykucmVkdWNlKChtZW1vLCBwYXRoLCBpbmRleCwgcGFydHMpID0+IHtcbiAgICAgICAgICAgIG1lbW9bcGFydHMuc2xpY2UoMCwgaW5kZXggKyAxKS5qb2luKCcuJyldID0gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVybiBtZW1vO1xuICAgICAgICAgIH0sIG1lbW8pO1xuICAgICAgICB9LCB7fSk7XG5cbiAgICAgICAgdGhpcy5pbmNsdWRlID0gT2JqZWN0LmtleXMocGF0aFNldClcbiAgICAgICAgICAubWFwKHMgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHMuc3BsaXQoJy4nKTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gYS5sZW5ndGggLSBiLmxlbmd0aDsgLy8gU29ydCBieSBudW1iZXIgb2YgY29tcG9uZW50c1xuICAgICAgICAgIH0pO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ3JlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5JzpcbiAgICAgICAgdGhpcy5yZWRpcmVjdEtleSA9IHJlc3RPcHRpb25zLnJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5O1xuICAgICAgICB0aGlzLnJlZGlyZWN0Q2xhc3NOYW1lID0gbnVsbDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdpbmNsdWRlUmVhZFByZWZlcmVuY2UnOlxuICAgICAgY2FzZSAnc3VicXVlcnlSZWFkUHJlZmVyZW5jZSc6XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2JhZCBvcHRpb246ICcgKyBvcHRpb24pO1xuICAgIH1cbiAgfVxufVxuXG4vLyBBIGNvbnZlbmllbnQgbWV0aG9kIHRvIHBlcmZvcm0gYWxsIHRoZSBzdGVwcyBvZiBwcm9jZXNzaW5nIGEgcXVlcnlcbi8vIGluIG9yZGVyLlxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSByZXNwb25zZSAtIGFuIG9iamVjdCB3aXRoIG9wdGlvbmFsIGtleXNcbi8vICdyZXN1bHRzJyBhbmQgJ2NvdW50Jy5cbi8vIFRPRE86IGNvbnNvbGlkYXRlIHRoZSByZXBsYWNlWCBmdW5jdGlvbnNcblJlc3RRdWVyeS5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uIChleGVjdXRlT3B0aW9ucykge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5idWlsZFJlc3RXaGVyZSgpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlSW5jbHVkZUFsbCgpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRXhjbHVkZUtleXMoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnJ1bkZpbmQoZXhlY3V0ZU9wdGlvbnMpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMucnVuQ291bnQoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUluY2x1ZGUoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnJ1bkFmdGVyRmluZFRyaWdnZXIoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnJlc3BvbnNlO1xuICAgIH0pO1xufTtcblxuUmVzdFF1ZXJ5LnByb3RvdHlwZS5lYWNoID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gIGNvbnN0IHsgY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIHJlc3RXaGVyZSwgcmVzdE9wdGlvbnMsIGNsaWVudFNESyB9ID0gdGhpcztcbiAgLy8gaWYgdGhlIGxpbWl0IGlzIHNldCwgdXNlIGl0XG4gIHJlc3RPcHRpb25zLmxpbWl0ID0gcmVzdE9wdGlvbnMubGltaXQgfHwgMTAwO1xuICByZXN0T3B0aW9ucy5vcmRlciA9ICdvYmplY3RJZCc7XG4gIGxldCBmaW5pc2hlZCA9IGZhbHNlO1xuXG4gIHJldHVybiBjb250aW51ZVdoaWxlKFxuICAgICgpID0+IHtcbiAgICAgIHJldHVybiAhZmluaXNoZWQ7XG4gICAgfSxcbiAgICBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBxdWVyeSA9IG5ldyBSZXN0UXVlcnkoXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgYXV0aCxcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICByZXN0V2hlcmUsXG4gICAgICAgIHJlc3RPcHRpb25zLFxuICAgICAgICBjbGllbnRTREssXG4gICAgICAgIHRoaXMucnVuQWZ0ZXJGaW5kLFxuICAgICAgICB0aGlzLmNvbnRleHRcbiAgICAgICk7XG4gICAgICBjb25zdCB7IHJlc3VsdHMgfSA9IGF3YWl0IHF1ZXJ5LmV4ZWN1dGUoKTtcbiAgICAgIHJlc3VsdHMuZm9yRWFjaChjYWxsYmFjayk7XG4gICAgICBmaW5pc2hlZCA9IHJlc3VsdHMubGVuZ3RoIDwgcmVzdE9wdGlvbnMubGltaXQ7XG4gICAgICBpZiAoIWZpbmlzaGVkKSB7XG4gICAgICAgIHJlc3RXaGVyZS5vYmplY3RJZCA9IE9iamVjdC5hc3NpZ24oe30sIHJlc3RXaGVyZS5vYmplY3RJZCwge1xuICAgICAgICAgICRndDogcmVzdWx0c1tyZXN1bHRzLmxlbmd0aCAtIDFdLm9iamVjdElkLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICk7XG59O1xuXG5SZXN0UXVlcnkucHJvdG90eXBlLmJ1aWxkUmVzdFdoZXJlID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRVc2VyQW5kUm9sZUFDTCgpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMucmVkaXJlY3RDbGFzc05hbWVGb3JLZXkoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlQ2xpZW50Q2xhc3NDcmVhdGlvbigpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMucmVwbGFjZVNlbGVjdCgpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMucmVwbGFjZURvbnRTZWxlY3QoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnJlcGxhY2VJblF1ZXJ5KCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5yZXBsYWNlTm90SW5RdWVyeSgpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMucmVwbGFjZUVxdWFsaXR5KCk7XG4gICAgfSk7XG59O1xuXG4vLyBVc2VzIHRoZSBBdXRoIG9iamVjdCB0byBnZXQgdGhlIGxpc3Qgb2Ygcm9sZXMsIGFkZHMgdGhlIHVzZXIgaWRcblJlc3RRdWVyeS5wcm90b3R5cGUuZ2V0VXNlckFuZFJvbGVBQ0wgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmF1dGguaXNNYXN0ZXIpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICB0aGlzLmZpbmRPcHRpb25zLmFjbCA9IFsnKiddO1xuXG4gIGlmICh0aGlzLmF1dGgudXNlcikge1xuICAgIHJldHVybiB0aGlzLmF1dGguZ2V0VXNlclJvbGVzKCkudGhlbihyb2xlcyA9PiB7XG4gICAgICB0aGlzLmZpbmRPcHRpb25zLmFjbCA9IHRoaXMuZmluZE9wdGlvbnMuYWNsLmNvbmNhdChyb2xlcywgW3RoaXMuYXV0aC51c2VyLmlkXSk7XG4gICAgICByZXR1cm47XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG59O1xuXG4vLyBDaGFuZ2VzIHRoZSBjbGFzc05hbWUgaWYgcmVkaXJlY3RDbGFzc05hbWVGb3JLZXkgaXMgc2V0LlxuLy8gUmV0dXJucyBhIHByb21pc2UuXG5SZXN0UXVlcnkucHJvdG90eXBlLnJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5ID0gZnVuY3Rpb24gKCkge1xuICBpZiAoIXRoaXMucmVkaXJlY3RLZXkpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICAvLyBXZSBuZWVkIHRvIGNoYW5nZSB0aGUgY2xhc3MgbmFtZSBiYXNlZCBvbiB0aGUgc2NoZW1hXG4gIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgIC5yZWRpcmVjdENsYXNzTmFtZUZvcktleSh0aGlzLmNsYXNzTmFtZSwgdGhpcy5yZWRpcmVjdEtleSlcbiAgICAudGhlbihuZXdDbGFzc05hbWUgPT4ge1xuICAgICAgdGhpcy5jbGFzc05hbWUgPSBuZXdDbGFzc05hbWU7XG4gICAgICB0aGlzLnJlZGlyZWN0Q2xhc3NOYW1lID0gbmV3Q2xhc3NOYW1lO1xuICAgIH0pO1xufTtcblxuLy8gVmFsaWRhdGVzIHRoaXMgb3BlcmF0aW9uIGFnYWluc3QgdGhlIGFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbiBjb25maWcuXG5SZXN0UXVlcnkucHJvdG90eXBlLnZhbGlkYXRlQ2xpZW50Q2xhc3NDcmVhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKFxuICAgIHRoaXMuY29uZmlnLmFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbiA9PT0gZmFsc2UgJiZcbiAgICAhdGhpcy5hdXRoLmlzTWFzdGVyICYmXG4gICAgU2NoZW1hQ29udHJvbGxlci5zeXN0ZW1DbGFzc2VzLmluZGV4T2YodGhpcy5jbGFzc05hbWUpID09PSAtMVxuICApIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAgIC5sb2FkU2NoZW1hKClcbiAgICAgIC50aGVuKHNjaGVtYUNvbnRyb2xsZXIgPT4gc2NoZW1hQ29udHJvbGxlci5oYXNDbGFzcyh0aGlzLmNsYXNzTmFtZSkpXG4gICAgICAudGhlbihoYXNDbGFzcyA9PiB7XG4gICAgICAgIGlmIChoYXNDbGFzcyAhPT0gdHJ1ZSkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sXG4gICAgICAgICAgICAnVGhpcyB1c2VyIGlzIG5vdCBhbGxvd2VkIHRvIGFjY2VzcyAnICsgJ25vbi1leGlzdGVudCBjbGFzczogJyArIHRoaXMuY2xhc3NOYW1lXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG59O1xuXG5mdW5jdGlvbiB0cmFuc2Zvcm1JblF1ZXJ5KGluUXVlcnlPYmplY3QsIGNsYXNzTmFtZSwgcmVzdWx0cykge1xuICB2YXIgdmFsdWVzID0gW107XG4gIGZvciAodmFyIHJlc3VsdCBvZiByZXN1bHRzKSB7XG4gICAgdmFsdWVzLnB1c2goe1xuICAgICAgX190eXBlOiAnUG9pbnRlcicsXG4gICAgICBjbGFzc05hbWU6IGNsYXNzTmFtZSxcbiAgICAgIG9iamVjdElkOiByZXN1bHQub2JqZWN0SWQsXG4gICAgfSk7XG4gIH1cbiAgZGVsZXRlIGluUXVlcnlPYmplY3RbJyRpblF1ZXJ5J107XG4gIGlmIChBcnJheS5pc0FycmF5KGluUXVlcnlPYmplY3RbJyRpbiddKSkge1xuICAgIGluUXVlcnlPYmplY3RbJyRpbiddID0gaW5RdWVyeU9iamVjdFsnJGluJ10uY29uY2F0KHZhbHVlcyk7XG4gIH0gZWxzZSB7XG4gICAgaW5RdWVyeU9iamVjdFsnJGluJ10gPSB2YWx1ZXM7XG4gIH1cbn1cblxuLy8gUmVwbGFjZXMgYSAkaW5RdWVyeSBjbGF1c2UgYnkgcnVubmluZyB0aGUgc3VicXVlcnksIGlmIHRoZXJlIGlzIGFuXG4vLyAkaW5RdWVyeSBjbGF1c2UuXG4vLyBUaGUgJGluUXVlcnkgY2xhdXNlIHR1cm5zIGludG8gYW4gJGluIHdpdGggdmFsdWVzIHRoYXQgYXJlIGp1c3Rcbi8vIHBvaW50ZXJzIHRvIHRoZSBvYmplY3RzIHJldHVybmVkIGluIHRoZSBzdWJxdWVyeS5cblJlc3RRdWVyeS5wcm90b3R5cGUucmVwbGFjZUluUXVlcnkgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBpblF1ZXJ5T2JqZWN0ID0gZmluZE9iamVjdFdpdGhLZXkodGhpcy5yZXN0V2hlcmUsICckaW5RdWVyeScpO1xuICBpZiAoIWluUXVlcnlPYmplY3QpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBUaGUgaW5RdWVyeSB2YWx1ZSBtdXN0IGhhdmUgcHJlY2lzZWx5IHR3byBrZXlzIC0gd2hlcmUgYW5kIGNsYXNzTmFtZVxuICB2YXIgaW5RdWVyeVZhbHVlID0gaW5RdWVyeU9iamVjdFsnJGluUXVlcnknXTtcbiAgaWYgKCFpblF1ZXJ5VmFsdWUud2hlcmUgfHwgIWluUXVlcnlWYWx1ZS5jbGFzc05hbWUpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSwgJ2ltcHJvcGVyIHVzYWdlIG9mICRpblF1ZXJ5Jyk7XG4gIH1cblxuICBjb25zdCBhZGRpdGlvbmFsT3B0aW9ucyA9IHtcbiAgICByZWRpcmVjdENsYXNzTmFtZUZvcktleTogaW5RdWVyeVZhbHVlLnJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5LFxuICB9O1xuXG4gIGlmICh0aGlzLnJlc3RPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UpIHtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHRoaXMucmVzdE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlO1xuICB9IGVsc2UgaWYgKHRoaXMucmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2UpIHtcbiAgICBhZGRpdGlvbmFsT3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHRoaXMucmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2U7XG4gIH1cblxuICB2YXIgc3VicXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KFxuICAgIHRoaXMuY29uZmlnLFxuICAgIHRoaXMuYXV0aCxcbiAgICBpblF1ZXJ5VmFsdWUuY2xhc3NOYW1lLFxuICAgIGluUXVlcnlWYWx1ZS53aGVyZSxcbiAgICBhZGRpdGlvbmFsT3B0aW9uc1xuICApO1xuICByZXR1cm4gc3VicXVlcnkuZXhlY3V0ZSgpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgIHRyYW5zZm9ybUluUXVlcnkoaW5RdWVyeU9iamVjdCwgc3VicXVlcnkuY2xhc3NOYW1lLCByZXNwb25zZS5yZXN1bHRzKTtcbiAgICAvLyBSZWN1cnNlIHRvIHJlcGVhdFxuICAgIHJldHVybiB0aGlzLnJlcGxhY2VJblF1ZXJ5KCk7XG4gIH0pO1xufTtcblxuZnVuY3Rpb24gdHJhbnNmb3JtTm90SW5RdWVyeShub3RJblF1ZXJ5T2JqZWN0LCBjbGFzc05hbWUsIHJlc3VsdHMpIHtcbiAgdmFyIHZhbHVlcyA9IFtdO1xuICBmb3IgKHZhciByZXN1bHQgb2YgcmVzdWx0cykge1xuICAgIHZhbHVlcy5wdXNoKHtcbiAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgY2xhc3NOYW1lOiBjbGFzc05hbWUsXG4gICAgICBvYmplY3RJZDogcmVzdWx0Lm9iamVjdElkLFxuICAgIH0pO1xuICB9XG4gIGRlbGV0ZSBub3RJblF1ZXJ5T2JqZWN0Wyckbm90SW5RdWVyeSddO1xuICBpZiAoQXJyYXkuaXNBcnJheShub3RJblF1ZXJ5T2JqZWN0WyckbmluJ10pKSB7XG4gICAgbm90SW5RdWVyeU9iamVjdFsnJG5pbiddID0gbm90SW5RdWVyeU9iamVjdFsnJG5pbiddLmNvbmNhdCh2YWx1ZXMpO1xuICB9IGVsc2Uge1xuICAgIG5vdEluUXVlcnlPYmplY3RbJyRuaW4nXSA9IHZhbHVlcztcbiAgfVxufVxuXG4vLyBSZXBsYWNlcyBhICRub3RJblF1ZXJ5IGNsYXVzZSBieSBydW5uaW5nIHRoZSBzdWJxdWVyeSwgaWYgdGhlcmUgaXMgYW5cbi8vICRub3RJblF1ZXJ5IGNsYXVzZS5cbi8vIFRoZSAkbm90SW5RdWVyeSBjbGF1c2UgdHVybnMgaW50byBhICRuaW4gd2l0aCB2YWx1ZXMgdGhhdCBhcmUganVzdFxuLy8gcG9pbnRlcnMgdG8gdGhlIG9iamVjdHMgcmV0dXJuZWQgaW4gdGhlIHN1YnF1ZXJ5LlxuUmVzdFF1ZXJ5LnByb3RvdHlwZS5yZXBsYWNlTm90SW5RdWVyeSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG5vdEluUXVlcnlPYmplY3QgPSBmaW5kT2JqZWN0V2l0aEtleSh0aGlzLnJlc3RXaGVyZSwgJyRub3RJblF1ZXJ5Jyk7XG4gIGlmICghbm90SW5RdWVyeU9iamVjdCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIFRoZSBub3RJblF1ZXJ5IHZhbHVlIG11c3QgaGF2ZSBwcmVjaXNlbHkgdHdvIGtleXMgLSB3aGVyZSBhbmQgY2xhc3NOYW1lXG4gIHZhciBub3RJblF1ZXJ5VmFsdWUgPSBub3RJblF1ZXJ5T2JqZWN0Wyckbm90SW5RdWVyeSddO1xuICBpZiAoIW5vdEluUXVlcnlWYWx1ZS53aGVyZSB8fCAhbm90SW5RdWVyeVZhbHVlLmNsYXNzTmFtZSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnaW1wcm9wZXIgdXNhZ2Ugb2YgJG5vdEluUXVlcnknKTtcbiAgfVxuXG4gIGNvbnN0IGFkZGl0aW9uYWxPcHRpb25zID0ge1xuICAgIHJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5OiBub3RJblF1ZXJ5VmFsdWUucmVkaXJlY3RDbGFzc05hbWVGb3JLZXksXG4gIH07XG5cbiAgaWYgKHRoaXMucmVzdE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSkge1xuICAgIGFkZGl0aW9uYWxPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlO1xuICAgIGFkZGl0aW9uYWxPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UgPSB0aGlzLnJlc3RPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U7XG4gIH0gZWxzZSBpZiAodGhpcy5yZXN0T3B0aW9ucy5yZWFkUHJlZmVyZW5jZSkge1xuICAgIGFkZGl0aW9uYWxPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5yZWFkUHJlZmVyZW5jZTtcbiAgfVxuXG4gIHZhciBzdWJxdWVyeSA9IG5ldyBSZXN0UXVlcnkoXG4gICAgdGhpcy5jb25maWcsXG4gICAgdGhpcy5hdXRoLFxuICAgIG5vdEluUXVlcnlWYWx1ZS5jbGFzc05hbWUsXG4gICAgbm90SW5RdWVyeVZhbHVlLndoZXJlLFxuICAgIGFkZGl0aW9uYWxPcHRpb25zXG4gICk7XG4gIHJldHVybiBzdWJxdWVyeS5leGVjdXRlKCkudGhlbihyZXNwb25zZSA9PiB7XG4gICAgdHJhbnNmb3JtTm90SW5RdWVyeShub3RJblF1ZXJ5T2JqZWN0LCBzdWJxdWVyeS5jbGFzc05hbWUsIHJlc3BvbnNlLnJlc3VsdHMpO1xuICAgIC8vIFJlY3Vyc2UgdG8gcmVwZWF0XG4gICAgcmV0dXJuIHRoaXMucmVwbGFjZU5vdEluUXVlcnkoKTtcbiAgfSk7XG59O1xuXG4vLyBVc2VkIHRvIGdldCB0aGUgZGVlcGVzdCBvYmplY3QgZnJvbSBqc29uIHVzaW5nIGRvdCBub3RhdGlvbi5cbmNvbnN0IGdldERlZXBlc3RPYmplY3RGcm9tS2V5ID0gKGpzb24sIGtleSwgaWR4LCBzcmMpID0+IHtcbiAgaWYgKGtleSBpbiBqc29uKSB7XG4gICAgcmV0dXJuIGpzb25ba2V5XTtcbiAgfVxuICBzcmMuc3BsaWNlKDEpOyAvLyBFeGl0IEVhcmx5XG59O1xuXG5jb25zdCB0cmFuc2Zvcm1TZWxlY3QgPSAoc2VsZWN0T2JqZWN0LCBrZXksIG9iamVjdHMpID0+IHtcbiAgdmFyIHZhbHVlcyA9IFtdO1xuICBmb3IgKHZhciByZXN1bHQgb2Ygb2JqZWN0cykge1xuICAgIHZhbHVlcy5wdXNoKGtleS5zcGxpdCgnLicpLnJlZHVjZShnZXREZWVwZXN0T2JqZWN0RnJvbUtleSwgcmVzdWx0KSk7XG4gIH1cbiAgZGVsZXRlIHNlbGVjdE9iamVjdFsnJHNlbGVjdCddO1xuICBpZiAoQXJyYXkuaXNBcnJheShzZWxlY3RPYmplY3RbJyRpbiddKSkge1xuICAgIHNlbGVjdE9iamVjdFsnJGluJ10gPSBzZWxlY3RPYmplY3RbJyRpbiddLmNvbmNhdCh2YWx1ZXMpO1xuICB9IGVsc2Uge1xuICAgIHNlbGVjdE9iamVjdFsnJGluJ10gPSB2YWx1ZXM7XG4gIH1cbn07XG5cbi8vIFJlcGxhY2VzIGEgJHNlbGVjdCBjbGF1c2UgYnkgcnVubmluZyB0aGUgc3VicXVlcnksIGlmIHRoZXJlIGlzIGFcbi8vICRzZWxlY3QgY2xhdXNlLlxuLy8gVGhlICRzZWxlY3QgY2xhdXNlIHR1cm5zIGludG8gYW4gJGluIHdpdGggdmFsdWVzIHNlbGVjdGVkIG91dCBvZlxuLy8gdGhlIHN1YnF1ZXJ5LlxuLy8gUmV0dXJucyBhIHBvc3NpYmxlLXByb21pc2UuXG5SZXN0UXVlcnkucHJvdG90eXBlLnJlcGxhY2VTZWxlY3QgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBzZWxlY3RPYmplY3QgPSBmaW5kT2JqZWN0V2l0aEtleSh0aGlzLnJlc3RXaGVyZSwgJyRzZWxlY3QnKTtcbiAgaWYgKCFzZWxlY3RPYmplY3QpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBUaGUgc2VsZWN0IHZhbHVlIG11c3QgaGF2ZSBwcmVjaXNlbHkgdHdvIGtleXMgLSBxdWVyeSBhbmQga2V5XG4gIHZhciBzZWxlY3RWYWx1ZSA9IHNlbGVjdE9iamVjdFsnJHNlbGVjdCddO1xuICAvLyBpT1MgU0RLIGRvbid0IHNlbmQgd2hlcmUgaWYgbm90IHNldCwgbGV0IGl0IHBhc3NcbiAgaWYgKFxuICAgICFzZWxlY3RWYWx1ZS5xdWVyeSB8fFxuICAgICFzZWxlY3RWYWx1ZS5rZXkgfHxcbiAgICB0eXBlb2Ygc2VsZWN0VmFsdWUucXVlcnkgIT09ICdvYmplY3QnIHx8XG4gICAgIXNlbGVjdFZhbHVlLnF1ZXJ5LmNsYXNzTmFtZSB8fFxuICAgIE9iamVjdC5rZXlzKHNlbGVjdFZhbHVlKS5sZW5ndGggIT09IDJcbiAgKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksICdpbXByb3BlciB1c2FnZSBvZiAkc2VsZWN0Jyk7XG4gIH1cblxuICBjb25zdCBhZGRpdGlvbmFsT3B0aW9ucyA9IHtcbiAgICByZWRpcmVjdENsYXNzTmFtZUZvcktleTogc2VsZWN0VmFsdWUucXVlcnkucmVkaXJlY3RDbGFzc05hbWVGb3JLZXksXG4gIH07XG5cbiAgaWYgKHRoaXMucmVzdE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSkge1xuICAgIGFkZGl0aW9uYWxPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlO1xuICAgIGFkZGl0aW9uYWxPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UgPSB0aGlzLnJlc3RPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U7XG4gIH0gZWxzZSBpZiAodGhpcy5yZXN0T3B0aW9ucy5yZWFkUHJlZmVyZW5jZSkge1xuICAgIGFkZGl0aW9uYWxPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5yZWFkUHJlZmVyZW5jZTtcbiAgfVxuXG4gIHZhciBzdWJxdWVyeSA9IG5ldyBSZXN0UXVlcnkoXG4gICAgdGhpcy5jb25maWcsXG4gICAgdGhpcy5hdXRoLFxuICAgIHNlbGVjdFZhbHVlLnF1ZXJ5LmNsYXNzTmFtZSxcbiAgICBzZWxlY3RWYWx1ZS5xdWVyeS53aGVyZSxcbiAgICBhZGRpdGlvbmFsT3B0aW9uc1xuICApO1xuICByZXR1cm4gc3VicXVlcnkuZXhlY3V0ZSgpLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgIHRyYW5zZm9ybVNlbGVjdChzZWxlY3RPYmplY3QsIHNlbGVjdFZhbHVlLmtleSwgcmVzcG9uc2UucmVzdWx0cyk7XG4gICAgLy8gS2VlcCByZXBsYWNpbmcgJHNlbGVjdCBjbGF1c2VzXG4gICAgcmV0dXJuIHRoaXMucmVwbGFjZVNlbGVjdCgpO1xuICB9KTtcbn07XG5cbmNvbnN0IHRyYW5zZm9ybURvbnRTZWxlY3QgPSAoZG9udFNlbGVjdE9iamVjdCwga2V5LCBvYmplY3RzKSA9PiB7XG4gIHZhciB2YWx1ZXMgPSBbXTtcbiAgZm9yICh2YXIgcmVzdWx0IG9mIG9iamVjdHMpIHtcbiAgICB2YWx1ZXMucHVzaChrZXkuc3BsaXQoJy4nKS5yZWR1Y2UoZ2V0RGVlcGVzdE9iamVjdEZyb21LZXksIHJlc3VsdCkpO1xuICB9XG4gIGRlbGV0ZSBkb250U2VsZWN0T2JqZWN0WyckZG9udFNlbGVjdCddO1xuICBpZiAoQXJyYXkuaXNBcnJheShkb250U2VsZWN0T2JqZWN0WyckbmluJ10pKSB7XG4gICAgZG9udFNlbGVjdE9iamVjdFsnJG5pbiddID0gZG9udFNlbGVjdE9iamVjdFsnJG5pbiddLmNvbmNhdCh2YWx1ZXMpO1xuICB9IGVsc2Uge1xuICAgIGRvbnRTZWxlY3RPYmplY3RbJyRuaW4nXSA9IHZhbHVlcztcbiAgfVxufTtcblxuLy8gUmVwbGFjZXMgYSAkZG9udFNlbGVjdCBjbGF1c2UgYnkgcnVubmluZyB0aGUgc3VicXVlcnksIGlmIHRoZXJlIGlzIGFcbi8vICRkb250U2VsZWN0IGNsYXVzZS5cbi8vIFRoZSAkZG9udFNlbGVjdCBjbGF1c2UgdHVybnMgaW50byBhbiAkbmluIHdpdGggdmFsdWVzIHNlbGVjdGVkIG91dCBvZlxuLy8gdGhlIHN1YnF1ZXJ5LlxuLy8gUmV0dXJucyBhIHBvc3NpYmxlLXByb21pc2UuXG5SZXN0UXVlcnkucHJvdG90eXBlLnJlcGxhY2VEb250U2VsZWN0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgZG9udFNlbGVjdE9iamVjdCA9IGZpbmRPYmplY3RXaXRoS2V5KHRoaXMucmVzdFdoZXJlLCAnJGRvbnRTZWxlY3QnKTtcbiAgaWYgKCFkb250U2VsZWN0T2JqZWN0KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gVGhlIGRvbnRTZWxlY3QgdmFsdWUgbXVzdCBoYXZlIHByZWNpc2VseSB0d28ga2V5cyAtIHF1ZXJ5IGFuZCBrZXlcbiAgdmFyIGRvbnRTZWxlY3RWYWx1ZSA9IGRvbnRTZWxlY3RPYmplY3RbJyRkb250U2VsZWN0J107XG4gIGlmIChcbiAgICAhZG9udFNlbGVjdFZhbHVlLnF1ZXJ5IHx8XG4gICAgIWRvbnRTZWxlY3RWYWx1ZS5rZXkgfHxcbiAgICB0eXBlb2YgZG9udFNlbGVjdFZhbHVlLnF1ZXJ5ICE9PSAnb2JqZWN0JyB8fFxuICAgICFkb250U2VsZWN0VmFsdWUucXVlcnkuY2xhc3NOYW1lIHx8XG4gICAgT2JqZWN0LmtleXMoZG9udFNlbGVjdFZhbHVlKS5sZW5ndGggIT09IDJcbiAgKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksICdpbXByb3BlciB1c2FnZSBvZiAkZG9udFNlbGVjdCcpO1xuICB9XG4gIGNvbnN0IGFkZGl0aW9uYWxPcHRpb25zID0ge1xuICAgIHJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5OiBkb250U2VsZWN0VmFsdWUucXVlcnkucmVkaXJlY3RDbGFzc05hbWVGb3JLZXksXG4gIH07XG5cbiAgaWYgKHRoaXMucmVzdE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSkge1xuICAgIGFkZGl0aW9uYWxPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlO1xuICAgIGFkZGl0aW9uYWxPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UgPSB0aGlzLnJlc3RPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U7XG4gIH0gZWxzZSBpZiAodGhpcy5yZXN0T3B0aW9ucy5yZWFkUHJlZmVyZW5jZSkge1xuICAgIGFkZGl0aW9uYWxPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gdGhpcy5yZXN0T3B0aW9ucy5yZWFkUHJlZmVyZW5jZTtcbiAgfVxuXG4gIHZhciBzdWJxdWVyeSA9IG5ldyBSZXN0UXVlcnkoXG4gICAgdGhpcy5jb25maWcsXG4gICAgdGhpcy5hdXRoLFxuICAgIGRvbnRTZWxlY3RWYWx1ZS5xdWVyeS5jbGFzc05hbWUsXG4gICAgZG9udFNlbGVjdFZhbHVlLnF1ZXJ5LndoZXJlLFxuICAgIGFkZGl0aW9uYWxPcHRpb25zXG4gICk7XG4gIHJldHVybiBzdWJxdWVyeS5leGVjdXRlKCkudGhlbihyZXNwb25zZSA9PiB7XG4gICAgdHJhbnNmb3JtRG9udFNlbGVjdChkb250U2VsZWN0T2JqZWN0LCBkb250U2VsZWN0VmFsdWUua2V5LCByZXNwb25zZS5yZXN1bHRzKTtcbiAgICAvLyBLZWVwIHJlcGxhY2luZyAkZG9udFNlbGVjdCBjbGF1c2VzXG4gICAgcmV0dXJuIHRoaXMucmVwbGFjZURvbnRTZWxlY3QoKTtcbiAgfSk7XG59O1xuXG5jb25zdCBjbGVhblJlc3VsdEF1dGhEYXRhID0gZnVuY3Rpb24gKHJlc3VsdCkge1xuICBkZWxldGUgcmVzdWx0LnBhc3N3b3JkO1xuICBpZiAocmVzdWx0LmF1dGhEYXRhKSB7XG4gICAgT2JqZWN0LmtleXMocmVzdWx0LmF1dGhEYXRhKS5mb3JFYWNoKHByb3ZpZGVyID0+IHtcbiAgICAgIGlmIChyZXN1bHQuYXV0aERhdGFbcHJvdmlkZXJdID09PSBudWxsKSB7XG4gICAgICAgIGRlbGV0ZSByZXN1bHQuYXV0aERhdGFbcHJvdmlkZXJdO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKE9iamVjdC5rZXlzKHJlc3VsdC5hdXRoRGF0YSkubGVuZ3RoID09IDApIHtcbiAgICAgIGRlbGV0ZSByZXN1bHQuYXV0aERhdGE7XG4gICAgfVxuICB9XG59O1xuXG5jb25zdCByZXBsYWNlRXF1YWxpdHlDb25zdHJhaW50ID0gY29uc3RyYWludCA9PiB7XG4gIGlmICh0eXBlb2YgY29uc3RyYWludCAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gY29uc3RyYWludDtcbiAgfVxuICBjb25zdCBlcXVhbFRvT2JqZWN0ID0ge307XG4gIGxldCBoYXNEaXJlY3RDb25zdHJhaW50ID0gZmFsc2U7XG4gIGxldCBoYXNPcGVyYXRvckNvbnN0cmFpbnQgPSBmYWxzZTtcbiAgZm9yIChjb25zdCBrZXkgaW4gY29uc3RyYWludCkge1xuICAgIGlmIChrZXkuaW5kZXhPZignJCcpICE9PSAwKSB7XG4gICAgICBoYXNEaXJlY3RDb25zdHJhaW50ID0gdHJ1ZTtcbiAgICAgIGVxdWFsVG9PYmplY3Rba2V5XSA9IGNvbnN0cmFpbnRba2V5XTtcbiAgICB9IGVsc2Uge1xuICAgICAgaGFzT3BlcmF0b3JDb25zdHJhaW50ID0gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgaWYgKGhhc0RpcmVjdENvbnN0cmFpbnQgJiYgaGFzT3BlcmF0b3JDb25zdHJhaW50KSB7XG4gICAgY29uc3RyYWludFsnJGVxJ10gPSBlcXVhbFRvT2JqZWN0O1xuICAgIE9iamVjdC5rZXlzKGVxdWFsVG9PYmplY3QpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGRlbGV0ZSBjb25zdHJhaW50W2tleV07XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIGNvbnN0cmFpbnQ7XG59O1xuXG5SZXN0UXVlcnkucHJvdG90eXBlLnJlcGxhY2VFcXVhbGl0eSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHR5cGVvZiB0aGlzLnJlc3RXaGVyZSAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgZm9yIChjb25zdCBrZXkgaW4gdGhpcy5yZXN0V2hlcmUpIHtcbiAgICB0aGlzLnJlc3RXaGVyZVtrZXldID0gcmVwbGFjZUVxdWFsaXR5Q29uc3RyYWludCh0aGlzLnJlc3RXaGVyZVtrZXldKTtcbiAgfVxufTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIHdoZXRoZXIgaXQgd2FzIHN1Y2Nlc3NmdWwuXG4vLyBQb3B1bGF0ZXMgdGhpcy5yZXNwb25zZSB3aXRoIGFuIG9iamVjdCB0aGF0IG9ubHkgaGFzICdyZXN1bHRzJy5cblJlc3RRdWVyeS5wcm90b3R5cGUucnVuRmluZCA9IGZ1bmN0aW9uIChvcHRpb25zID0ge30pIHtcbiAgaWYgKHRoaXMuZmluZE9wdGlvbnMubGltaXQgPT09IDApIHtcbiAgICB0aGlzLnJlc3BvbnNlID0geyByZXN1bHRzOiBbXSB9O1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuICBjb25zdCBmaW5kT3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oe30sIHRoaXMuZmluZE9wdGlvbnMpO1xuICBpZiAodGhpcy5rZXlzKSB7XG4gICAgZmluZE9wdGlvbnMua2V5cyA9IHRoaXMua2V5cy5tYXAoa2V5ID0+IHtcbiAgICAgIHJldHVybiBrZXkuc3BsaXQoJy4nKVswXTtcbiAgICB9KTtcbiAgfVxuICBpZiAob3B0aW9ucy5vcCkge1xuICAgIGZpbmRPcHRpb25zLm9wID0gb3B0aW9ucy5vcDtcbiAgfVxuICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAuZmluZCh0aGlzLmNsYXNzTmFtZSwgdGhpcy5yZXN0V2hlcmUsIGZpbmRPcHRpb25zLCB0aGlzLmF1dGgpXG4gICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICBpZiAodGhpcy5jbGFzc05hbWUgPT09ICdfVXNlcicgJiYgZmluZE9wdGlvbnMuZXhwbGFpbiAhPT0gdHJ1ZSkge1xuICAgICAgICBmb3IgKHZhciByZXN1bHQgb2YgcmVzdWx0cykge1xuICAgICAgICAgIGNsZWFuUmVzdWx0QXV0aERhdGEocmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLmNvbmZpZy5maWxlc0NvbnRyb2xsZXIuZXhwYW5kRmlsZXNJbk9iamVjdCh0aGlzLmNvbmZpZywgcmVzdWx0cyk7XG5cbiAgICAgIGlmICh0aGlzLnJlZGlyZWN0Q2xhc3NOYW1lKSB7XG4gICAgICAgIGZvciAodmFyIHIgb2YgcmVzdWx0cykge1xuICAgICAgICAgIHIuY2xhc3NOYW1lID0gdGhpcy5yZWRpcmVjdENsYXNzTmFtZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5yZXNwb25zZSA9IHsgcmVzdWx0czogcmVzdWx0cyB9O1xuICAgIH0pO1xufTtcblxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIHdoZXRoZXIgaXQgd2FzIHN1Y2Nlc3NmdWwuXG4vLyBQb3B1bGF0ZXMgdGhpcy5yZXNwb25zZS5jb3VudCB3aXRoIHRoZSBjb3VudFxuUmVzdFF1ZXJ5LnByb3RvdHlwZS5ydW5Db3VudCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCF0aGlzLmRvQ291bnQpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdGhpcy5maW5kT3B0aW9ucy5jb3VudCA9IHRydWU7XG4gIGRlbGV0ZSB0aGlzLmZpbmRPcHRpb25zLnNraXA7XG4gIGRlbGV0ZSB0aGlzLmZpbmRPcHRpb25zLmxpbWl0O1xuICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UuZmluZCh0aGlzLmNsYXNzTmFtZSwgdGhpcy5yZXN0V2hlcmUsIHRoaXMuZmluZE9wdGlvbnMpLnRoZW4oYyA9PiB7XG4gICAgdGhpcy5yZXNwb25zZS5jb3VudCA9IGM7XG4gIH0pO1xufTtcblxuLy8gQXVnbWVudHMgdGhpcy5yZXNwb25zZSB3aXRoIGFsbCBwb2ludGVycyBvbiBhbiBvYmplY3RcblJlc3RRdWVyeS5wcm90b3R5cGUuaGFuZGxlSW5jbHVkZUFsbCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCF0aGlzLmluY2x1ZGVBbGwpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgLmxvYWRTY2hlbWEoKVxuICAgIC50aGVuKHNjaGVtYUNvbnRyb2xsZXIgPT4gc2NoZW1hQ29udHJvbGxlci5nZXRPbmVTY2hlbWEodGhpcy5jbGFzc05hbWUpKVxuICAgIC50aGVuKHNjaGVtYSA9PiB7XG4gICAgICBjb25zdCBpbmNsdWRlRmllbGRzID0gW107XG4gICAgICBjb25zdCBrZXlGaWVsZHMgPSBbXTtcbiAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gc2NoZW1hLmZpZWxkcykge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgKHNjaGVtYS5maWVsZHNbZmllbGRdLnR5cGUgJiYgc2NoZW1hLmZpZWxkc1tmaWVsZF0udHlwZSA9PT0gJ1BvaW50ZXInKSB8fFxuICAgICAgICAgIChzY2hlbWEuZmllbGRzW2ZpZWxkXS50eXBlICYmIHNjaGVtYS5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdBcnJheScpXG4gICAgICAgICkge1xuICAgICAgICAgIGluY2x1ZGVGaWVsZHMucHVzaChbZmllbGRdKTtcbiAgICAgICAgICBrZXlGaWVsZHMucHVzaChmaWVsZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIEFkZCBmaWVsZHMgdG8gaW5jbHVkZSwga2V5cywgcmVtb3ZlIGR1cHNcbiAgICAgIHRoaXMuaW5jbHVkZSA9IFsuLi5uZXcgU2V0KFsuLi50aGlzLmluY2x1ZGUsIC4uLmluY2x1ZGVGaWVsZHNdKV07XG4gICAgICAvLyBpZiB0aGlzLmtleXMgbm90IHNldCwgdGhlbiBhbGwga2V5cyBhcmUgYWxyZWFkeSBpbmNsdWRlZFxuICAgICAgaWYgKHRoaXMua2V5cykge1xuICAgICAgICB0aGlzLmtleXMgPSBbLi4ubmV3IFNldChbLi4udGhpcy5rZXlzLCAuLi5rZXlGaWVsZHNdKV07XG4gICAgICB9XG4gICAgfSk7XG59O1xuXG4vLyBVcGRhdGVzIHByb3BlcnR5IGB0aGlzLmtleXNgIHRvIGNvbnRhaW4gYWxsIGtleXMgYnV0IHRoZSBvbmVzIHVuc2VsZWN0ZWQuXG5SZXN0UXVlcnkucHJvdG90eXBlLmhhbmRsZUV4Y2x1ZGVLZXlzID0gZnVuY3Rpb24gKCkge1xuICBpZiAoIXRoaXMuZXhjbHVkZUtleXMpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHRoaXMua2V5cykge1xuICAgIHRoaXMua2V5cyA9IHRoaXMua2V5cy5maWx0ZXIoayA9PiAhdGhpcy5leGNsdWRlS2V5cy5pbmNsdWRlcyhrKSk7XG4gICAgcmV0dXJuO1xuICB9XG4gIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgIC5sb2FkU2NoZW1hKClcbiAgICAudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHNjaGVtYUNvbnRyb2xsZXIuZ2V0T25lU2NoZW1hKHRoaXMuY2xhc3NOYW1lKSlcbiAgICAudGhlbihzY2hlbWEgPT4ge1xuICAgICAgY29uc3QgZmllbGRzID0gT2JqZWN0LmtleXMoc2NoZW1hLmZpZWxkcyk7XG4gICAgICB0aGlzLmtleXMgPSBmaWVsZHMuZmlsdGVyKGsgPT4gIXRoaXMuZXhjbHVkZUtleXMuaW5jbHVkZXMoaykpO1xuICAgIH0pO1xufTtcblxuLy8gQXVnbWVudHMgdGhpcy5yZXNwb25zZSB3aXRoIGRhdGEgYXQgdGhlIHBhdGhzIHByb3ZpZGVkIGluIHRoaXMuaW5jbHVkZS5cblJlc3RRdWVyeS5wcm90b3R5cGUuaGFuZGxlSW5jbHVkZSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuaW5jbHVkZS5sZW5ndGggPT0gMCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBwYXRoUmVzcG9uc2UgPSBpbmNsdWRlUGF0aChcbiAgICB0aGlzLmNvbmZpZyxcbiAgICB0aGlzLmF1dGgsXG4gICAgdGhpcy5yZXNwb25zZSxcbiAgICB0aGlzLmluY2x1ZGVbMF0sXG4gICAgdGhpcy5yZXN0T3B0aW9uc1xuICApO1xuICBpZiAocGF0aFJlc3BvbnNlLnRoZW4pIHtcbiAgICByZXR1cm4gcGF0aFJlc3BvbnNlLnRoZW4obmV3UmVzcG9uc2UgPT4ge1xuICAgICAgdGhpcy5yZXNwb25zZSA9IG5ld1Jlc3BvbnNlO1xuICAgICAgdGhpcy5pbmNsdWRlID0gdGhpcy5pbmNsdWRlLnNsaWNlKDEpO1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlSW5jbHVkZSgpO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKHRoaXMuaW5jbHVkZS5sZW5ndGggPiAwKSB7XG4gICAgdGhpcy5pbmNsdWRlID0gdGhpcy5pbmNsdWRlLnNsaWNlKDEpO1xuICAgIHJldHVybiB0aGlzLmhhbmRsZUluY2x1ZGUoKTtcbiAgfVxuXG4gIHJldHVybiBwYXRoUmVzcG9uc2U7XG59O1xuXG4vL1JldHVybnMgYSBwcm9taXNlIG9mIGEgcHJvY2Vzc2VkIHNldCBvZiByZXN1bHRzXG5SZXN0UXVlcnkucHJvdG90eXBlLnJ1bkFmdGVyRmluZFRyaWdnZXIgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5yZXNwb25zZSkge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoIXRoaXMucnVuQWZ0ZXJGaW5kKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIEF2b2lkIGRvaW5nIGFueSBzZXR1cCBmb3IgdHJpZ2dlcnMgaWYgdGhlcmUgaXMgbm8gJ2FmdGVyRmluZCcgdHJpZ2dlciBmb3IgdGhpcyBjbGFzcy5cbiAgY29uc3QgaGFzQWZ0ZXJGaW5kSG9vayA9IHRyaWdnZXJzLnRyaWdnZXJFeGlzdHMoXG4gICAgdGhpcy5jbGFzc05hbWUsXG4gICAgdHJpZ2dlcnMuVHlwZXMuYWZ0ZXJGaW5kLFxuICAgIHRoaXMuY29uZmlnLmFwcGxpY2F0aW9uSWRcbiAgKTtcbiAgaWYgKCFoYXNBZnRlckZpbmRIb29rKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG4gIC8vIFNraXAgQWdncmVnYXRlIGFuZCBEaXN0aW5jdCBRdWVyaWVzXG4gIGlmICh0aGlzLmZpbmRPcHRpb25zLnBpcGVsaW5lIHx8IHRoaXMuZmluZE9wdGlvbnMuZGlzdGluY3QpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBjb25zdCBqc29uID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5yZXN0T3B0aW9ucyk7XG4gIGpzb24ud2hlcmUgPSB0aGlzLnJlc3RXaGVyZTtcbiAgY29uc3QgcGFyc2VRdWVyeSA9IG5ldyBQYXJzZS5RdWVyeSh0aGlzLmNsYXNzTmFtZSk7XG4gIHBhcnNlUXVlcnkud2l0aEpTT04oanNvbik7XG4gIC8vIFJ1biBhZnRlckZpbmQgdHJpZ2dlciBhbmQgc2V0IHRoZSBuZXcgcmVzdWx0c1xuICByZXR1cm4gdHJpZ2dlcnNcbiAgICAubWF5YmVSdW5BZnRlckZpbmRUcmlnZ2VyKFxuICAgICAgdHJpZ2dlcnMuVHlwZXMuYWZ0ZXJGaW5kLFxuICAgICAgdGhpcy5hdXRoLFxuICAgICAgdGhpcy5jbGFzc05hbWUsXG4gICAgICB0aGlzLnJlc3BvbnNlLnJlc3VsdHMsXG4gICAgICB0aGlzLmNvbmZpZyxcbiAgICAgIHBhcnNlUXVlcnksXG4gICAgICB0aGlzLmNvbnRleHRcbiAgICApXG4gICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAvLyBFbnN1cmUgd2UgcHJvcGVybHkgc2V0IHRoZSBjbGFzc05hbWUgYmFja1xuICAgICAgaWYgKHRoaXMucmVkaXJlY3RDbGFzc05hbWUpIHtcbiAgICAgICAgdGhpcy5yZXNwb25zZS5yZXN1bHRzID0gcmVzdWx0cy5tYXAob2JqZWN0ID0+IHtcbiAgICAgICAgICBpZiAob2JqZWN0IGluc3RhbmNlb2YgUGFyc2UuT2JqZWN0KSB7XG4gICAgICAgICAgICBvYmplY3QgPSBvYmplY3QudG9KU09OKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIG9iamVjdC5jbGFzc05hbWUgPSB0aGlzLnJlZGlyZWN0Q2xhc3NOYW1lO1xuICAgICAgICAgIHJldHVybiBvYmplY3Q7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5yZXNwb25zZS5yZXN1bHRzID0gcmVzdWx0cztcbiAgICAgIH1cbiAgICB9KTtcbn07XG5cbi8vIEFkZHMgaW5jbHVkZWQgdmFsdWVzIHRvIHRoZSByZXNwb25zZS5cbi8vIFBhdGggaXMgYSBsaXN0IG9mIGZpZWxkIG5hbWVzLlxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGFuIGF1Z21lbnRlZCByZXNwb25zZS5cbmZ1bmN0aW9uIGluY2x1ZGVQYXRoKGNvbmZpZywgYXV0aCwgcmVzcG9uc2UsIHBhdGgsIHJlc3RPcHRpb25zID0ge30pIHtcbiAgdmFyIHBvaW50ZXJzID0gZmluZFBvaW50ZXJzKHJlc3BvbnNlLnJlc3VsdHMsIHBhdGgpO1xuICBpZiAocG9pbnRlcnMubGVuZ3RoID09IDApIHtcbiAgICByZXR1cm4gcmVzcG9uc2U7XG4gIH1cbiAgY29uc3QgcG9pbnRlcnNIYXNoID0ge307XG4gIGZvciAodmFyIHBvaW50ZXIgb2YgcG9pbnRlcnMpIHtcbiAgICBpZiAoIXBvaW50ZXIpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBjb25zdCBjbGFzc05hbWUgPSBwb2ludGVyLmNsYXNzTmFtZTtcbiAgICAvLyBvbmx5IGluY2x1ZGUgdGhlIGdvb2QgcG9pbnRlcnNcbiAgICBpZiAoY2xhc3NOYW1lKSB7XG4gICAgICBwb2ludGVyc0hhc2hbY2xhc3NOYW1lXSA9IHBvaW50ZXJzSGFzaFtjbGFzc05hbWVdIHx8IG5ldyBTZXQoKTtcbiAgICAgIHBvaW50ZXJzSGFzaFtjbGFzc05hbWVdLmFkZChwb2ludGVyLm9iamVjdElkKTtcbiAgICB9XG4gIH1cbiAgY29uc3QgaW5jbHVkZVJlc3RPcHRpb25zID0ge307XG4gIGlmIChyZXN0T3B0aW9ucy5rZXlzKSB7XG4gICAgY29uc3Qga2V5cyA9IG5ldyBTZXQocmVzdE9wdGlvbnMua2V5cy5zcGxpdCgnLCcpKTtcbiAgICBjb25zdCBrZXlTZXQgPSBBcnJheS5mcm9tKGtleXMpLnJlZHVjZSgoc2V0LCBrZXkpID0+IHtcbiAgICAgIGNvbnN0IGtleVBhdGggPSBrZXkuc3BsaXQoJy4nKTtcbiAgICAgIGxldCBpID0gMDtcbiAgICAgIGZvciAoaTsgaSA8IHBhdGgubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKHBhdGhbaV0gIT0ga2V5UGF0aFtpXSkge1xuICAgICAgICAgIHJldHVybiBzZXQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChpIDwga2V5UGF0aC5sZW5ndGgpIHtcbiAgICAgICAgc2V0LmFkZChrZXlQYXRoW2ldKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzZXQ7XG4gICAgfSwgbmV3IFNldCgpKTtcbiAgICBpZiAoa2V5U2V0LnNpemUgPiAwKSB7XG4gICAgICBpbmNsdWRlUmVzdE9wdGlvbnMua2V5cyA9IEFycmF5LmZyb20oa2V5U2V0KS5qb2luKCcsJyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHJlc3RPcHRpb25zLmluY2x1ZGVSZWFkUHJlZmVyZW5jZSkge1xuICAgIGluY2x1ZGVSZXN0T3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IHJlc3RPcHRpb25zLmluY2x1ZGVSZWFkUHJlZmVyZW5jZTtcbiAgICBpbmNsdWRlUmVzdE9wdGlvbnMuaW5jbHVkZVJlYWRQcmVmZXJlbmNlID0gcmVzdE9wdGlvbnMuaW5jbHVkZVJlYWRQcmVmZXJlbmNlO1xuICB9IGVsc2UgaWYgKHJlc3RPcHRpb25zLnJlYWRQcmVmZXJlbmNlKSB7XG4gICAgaW5jbHVkZVJlc3RPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gcmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2U7XG4gIH1cblxuICBjb25zdCBxdWVyeVByb21pc2VzID0gT2JqZWN0LmtleXMocG9pbnRlcnNIYXNoKS5tYXAoY2xhc3NOYW1lID0+IHtcbiAgICBjb25zdCBvYmplY3RJZHMgPSBBcnJheS5mcm9tKHBvaW50ZXJzSGFzaFtjbGFzc05hbWVdKTtcbiAgICBsZXQgd2hlcmU7XG4gICAgaWYgKG9iamVjdElkcy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHdoZXJlID0geyBvYmplY3RJZDogb2JqZWN0SWRzWzBdIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHdoZXJlID0geyBvYmplY3RJZDogeyAkaW46IG9iamVjdElkcyB9IH07XG4gICAgfVxuICAgIHZhciBxdWVyeSA9IG5ldyBSZXN0UXVlcnkoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIHdoZXJlLCBpbmNsdWRlUmVzdE9wdGlvbnMpO1xuICAgIHJldHVybiBxdWVyeS5leGVjdXRlKHsgb3A6ICdnZXQnIH0pLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICByZXN1bHRzLmNsYXNzTmFtZSA9IGNsYXNzTmFtZTtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVzdWx0cyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIEdldCB0aGUgb2JqZWN0cyBmb3IgYWxsIHRoZXNlIG9iamVjdCBpZHNcbiAgcmV0dXJuIFByb21pc2UuYWxsKHF1ZXJ5UHJvbWlzZXMpLnRoZW4ocmVzcG9uc2VzID0+IHtcbiAgICB2YXIgcmVwbGFjZSA9IHJlc3BvbnNlcy5yZWR1Y2UoKHJlcGxhY2UsIGluY2x1ZGVSZXNwb25zZSkgPT4ge1xuICAgICAgZm9yICh2YXIgb2JqIG9mIGluY2x1ZGVSZXNwb25zZS5yZXN1bHRzKSB7XG4gICAgICAgIG9iai5fX3R5cGUgPSAnT2JqZWN0JztcbiAgICAgICAgb2JqLmNsYXNzTmFtZSA9IGluY2x1ZGVSZXNwb25zZS5jbGFzc05hbWU7XG5cbiAgICAgICAgaWYgKG9iai5jbGFzc05hbWUgPT0gJ19Vc2VyJyAmJiAhYXV0aC5pc01hc3Rlcikge1xuICAgICAgICAgIGRlbGV0ZSBvYmouc2Vzc2lvblRva2VuO1xuICAgICAgICAgIGRlbGV0ZSBvYmouYXV0aERhdGE7XG4gICAgICAgIH1cbiAgICAgICAgcmVwbGFjZVtvYmoub2JqZWN0SWRdID0gb2JqO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlcGxhY2U7XG4gICAgfSwge30pO1xuXG4gICAgdmFyIHJlc3AgPSB7XG4gICAgICByZXN1bHRzOiByZXBsYWNlUG9pbnRlcnMocmVzcG9uc2UucmVzdWx0cywgcGF0aCwgcmVwbGFjZSksXG4gICAgfTtcbiAgICBpZiAocmVzcG9uc2UuY291bnQpIHtcbiAgICAgIHJlc3AuY291bnQgPSByZXNwb25zZS5jb3VudDtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3A7XG4gIH0pO1xufVxuXG4vLyBPYmplY3QgbWF5IGJlIGEgbGlzdCBvZiBSRVNULWZvcm1hdCBvYmplY3QgdG8gZmluZCBwb2ludGVycyBpbiwgb3Jcbi8vIGl0IG1heSBiZSBhIHNpbmdsZSBvYmplY3QuXG4vLyBJZiB0aGUgcGF0aCB5aWVsZHMgdGhpbmdzIHRoYXQgYXJlbid0IHBvaW50ZXJzLCB0aGlzIHRocm93cyBhbiBlcnJvci5cbi8vIFBhdGggaXMgYSBsaXN0IG9mIGZpZWxkcyB0byBzZWFyY2ggaW50by5cbi8vIFJldHVybnMgYSBsaXN0IG9mIHBvaW50ZXJzIGluIFJFU1QgZm9ybWF0LlxuZnVuY3Rpb24gZmluZFBvaW50ZXJzKG9iamVjdCwgcGF0aCkge1xuICBpZiAob2JqZWN0IGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICB2YXIgYW5zd2VyID0gW107XG4gICAgZm9yICh2YXIgeCBvZiBvYmplY3QpIHtcbiAgICAgIGFuc3dlciA9IGFuc3dlci5jb25jYXQoZmluZFBvaW50ZXJzKHgsIHBhdGgpKTtcbiAgICB9XG4gICAgcmV0dXJuIGFuc3dlcjtcbiAgfVxuXG4gIGlmICh0eXBlb2Ygb2JqZWN0ICE9PSAnb2JqZWN0JyB8fCAhb2JqZWN0KSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgaWYgKHBhdGgubGVuZ3RoID09IDApIHtcbiAgICBpZiAob2JqZWN0ID09PSBudWxsIHx8IG9iamVjdC5fX3R5cGUgPT0gJ1BvaW50ZXInKSB7XG4gICAgICByZXR1cm4gW29iamVjdF07XG4gICAgfVxuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHZhciBzdWJvYmplY3QgPSBvYmplY3RbcGF0aFswXV07XG4gIGlmICghc3Vib2JqZWN0KSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIHJldHVybiBmaW5kUG9pbnRlcnMoc3Vib2JqZWN0LCBwYXRoLnNsaWNlKDEpKTtcbn1cblxuLy8gT2JqZWN0IG1heSBiZSBhIGxpc3Qgb2YgUkVTVC1mb3JtYXQgb2JqZWN0cyB0byByZXBsYWNlIHBvaW50ZXJzXG4vLyBpbiwgb3IgaXQgbWF5IGJlIGEgc2luZ2xlIG9iamVjdC5cbi8vIFBhdGggaXMgYSBsaXN0IG9mIGZpZWxkcyB0byBzZWFyY2ggaW50by5cbi8vIHJlcGxhY2UgaXMgYSBtYXAgZnJvbSBvYmplY3QgaWQgLT4gb2JqZWN0LlxuLy8gUmV0dXJucyBzb21ldGhpbmcgYW5hbG9nb3VzIHRvIG9iamVjdCwgYnV0IHdpdGggdGhlIGFwcHJvcHJpYXRlXG4vLyBwb2ludGVycyBpbmZsYXRlZC5cbmZ1bmN0aW9uIHJlcGxhY2VQb2ludGVycyhvYmplY3QsIHBhdGgsIHJlcGxhY2UpIHtcbiAgaWYgKG9iamVjdCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgcmV0dXJuIG9iamVjdFxuICAgICAgLm1hcChvYmogPT4gcmVwbGFjZVBvaW50ZXJzKG9iaiwgcGF0aCwgcmVwbGFjZSkpXG4gICAgICAuZmlsdGVyKG9iaiA9PiB0eXBlb2Ygb2JqICE9PSAndW5kZWZpbmVkJyk7XG4gIH1cblxuICBpZiAodHlwZW9mIG9iamVjdCAhPT0gJ29iamVjdCcgfHwgIW9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3Q7XG4gIH1cblxuICBpZiAocGF0aC5sZW5ndGggPT09IDApIHtcbiAgICBpZiAob2JqZWN0ICYmIG9iamVjdC5fX3R5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgcmV0dXJuIHJlcGxhY2Vbb2JqZWN0Lm9iamVjdElkXTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfVxuXG4gIHZhciBzdWJvYmplY3QgPSBvYmplY3RbcGF0aFswXV07XG4gIGlmICghc3Vib2JqZWN0KSB7XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfVxuICB2YXIgbmV3c3ViID0gcmVwbGFjZVBvaW50ZXJzKHN1Ym9iamVjdCwgcGF0aC5zbGljZSgxKSwgcmVwbGFjZSk7XG4gIHZhciBhbnN3ZXIgPSB7fTtcbiAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgIGlmIChrZXkgPT0gcGF0aFswXSkge1xuICAgICAgYW5zd2VyW2tleV0gPSBuZXdzdWI7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFuc3dlcltrZXldID0gb2JqZWN0W2tleV07XG4gICAgfVxuICB9XG4gIHJldHVybiBhbnN3ZXI7XG59XG5cbi8vIEZpbmRzIGEgc3Vib2JqZWN0IHRoYXQgaGFzIHRoZSBnaXZlbiBrZXksIGlmIHRoZXJlIGlzIG9uZS5cbi8vIFJldHVybnMgdW5kZWZpbmVkIG90aGVyd2lzZS5cbmZ1bmN0aW9uIGZpbmRPYmplY3RXaXRoS2V5KHJvb3QsIGtleSkge1xuICBpZiAodHlwZW9mIHJvb3QgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChyb290IGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICBmb3IgKHZhciBpdGVtIG9mIHJvb3QpIHtcbiAgICAgIGNvbnN0IGFuc3dlciA9IGZpbmRPYmplY3RXaXRoS2V5KGl0ZW0sIGtleSk7XG4gICAgICBpZiAoYW5zd2VyKSB7XG4gICAgICAgIHJldHVybiBhbnN3ZXI7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlmIChyb290ICYmIHJvb3Rba2V5XSkge1xuICAgIHJldHVybiByb290O1xuICB9XG4gIGZvciAodmFyIHN1YmtleSBpbiByb290KSB7XG4gICAgY29uc3QgYW5zd2VyID0gZmluZE9iamVjdFdpdGhLZXkocm9vdFtzdWJrZXldLCBrZXkpO1xuICAgIGlmIChhbnN3ZXIpIHtcbiAgICAgIHJldHVybiBhbnN3ZXI7XG4gICAgfVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gUmVzdFF1ZXJ5O1xuIl19 \ No newline at end of file diff --git a/lib/RestWrite.js b/lib/RestWrite.js deleted file mode 100644 index 2b2be3e25e..0000000000 --- a/lib/RestWrite.js +++ /dev/null @@ -1,1485 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _RestQuery = _interopRequireDefault(require("./RestQuery")); - -var _lodash = _interopRequireDefault(require("lodash")); - -var _logger = _interopRequireDefault(require("./logger")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// A RestWrite encapsulates everything we need to run an operation -// that writes to the database. -// This could be either a "create" or an "update". -var SchemaController = require('./Controllers/SchemaController'); - -var deepcopy = require('deepcopy'); - -const Auth = require('./Auth'); - -var cryptoUtils = require('./cryptoUtils'); - -var passwordCrypto = require('./password'); - -var Parse = require('parse/node'); - -var triggers = require('./triggers'); - -var ClientSDK = require('./ClientSDK'); - -// query and data are both provided in REST API format. So data -// types are encoded by plain old objects. -// If query is null, this is a "create" and the data in data should be -// created. -// Otherwise this is an "update" - the object matching the query -// should get updated with data. -// RestWrite will handle objectId, createdAt, and updatedAt for -// everything. It also knows to use triggers and special modifications -// for the _User class. -function RestWrite(config, auth, className, query, data, originalData, clientSDK, context, action) { - if (auth.isReadOnly) { - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'Cannot perform a write operation when using readOnlyMasterKey'); - } - - this.config = config; - this.auth = auth; - this.className = className; - this.clientSDK = clientSDK; - this.storage = {}; - this.runOptions = {}; - this.context = context || {}; - - if (action) { - this.runOptions.action = action; - } - - if (!query) { - if (this.config.allowCustomObjectId) { - if (Object.prototype.hasOwnProperty.call(data, 'objectId') && !data.objectId) { - throw new Parse.Error(Parse.Error.MISSING_OBJECT_ID, 'objectId must not be empty, null or undefined'); - } - } else { - if (data.objectId) { - throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'objectId is an invalid field name.'); - } - - if (data.id) { - throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'id is an invalid field name.'); - } - } - } // When the operation is complete, this.response may have several - // fields. - // response: the actual data to be returned - // status: the http status code. if not present, treated like a 200 - // location: the location header. if not present, no location header - - - this.response = null; // Processing this operation may mutate our data, so we operate on a - // copy - - this.query = deepcopy(query); - this.data = deepcopy(data); // We never change originalData, so we do not need a deep copy - - this.originalData = originalData; // The timestamp we'll use for this whole operation - - this.updatedAt = Parse._encode(new Date()).iso; // Shared SchemaController to be reused to reduce the number of loadSchema() calls per request - // Once set the schemaData should be immutable - - this.validSchemaController = null; -} // A convenient method to perform all the steps of processing the -// write, in order. -// Returns a promise for a {response, status, location} object. -// status and location are optional. - - -RestWrite.prototype.execute = function () { - return Promise.resolve().then(() => { - return this.getUserAndRoleACL(); - }).then(() => { - return this.validateClientClassCreation(); - }).then(() => { - return this.handleInstallation(); - }).then(() => { - return this.handleSession(); - }).then(() => { - return this.validateAuthData(); - }).then(() => { - return this.runBeforeSaveTrigger(); - }).then(() => { - return this.deleteEmailResetTokenIfNeeded(); - }).then(() => { - return this.validateSchema(); - }).then(schemaController => { - this.validSchemaController = schemaController; - return this.setRequiredFieldsIfNeeded(); - }).then(() => { - return this.transformUser(); - }).then(() => { - return this.expandFilesForExistingObjects(); - }).then(() => { - return this.destroyDuplicatedSessions(); - }).then(() => { - return this.runDatabaseOperation(); - }).then(() => { - return this.createSessionTokenIfNeeded(); - }).then(() => { - return this.handleFollowup(); - }).then(() => { - return this.runAfterSaveTrigger(); - }).then(() => { - return this.cleanUserAuthData(); - }).then(() => { - return this.response; - }); -}; // Uses the Auth object to get the list of roles, adds the user id - - -RestWrite.prototype.getUserAndRoleACL = function () { - if (this.auth.isMaster) { - return Promise.resolve(); - } - - this.runOptions.acl = ['*']; - - if (this.auth.user) { - return this.auth.getUserRoles().then(roles => { - this.runOptions.acl = this.runOptions.acl.concat(roles, [this.auth.user.id]); - return; - }); - } else { - return Promise.resolve(); - } -}; // Validates this operation against the allowClientClassCreation config. - - -RestWrite.prototype.validateClientClassCreation = function () { - if (this.config.allowClientClassCreation === false && !this.auth.isMaster && SchemaController.systemClasses.indexOf(this.className) === -1) { - return this.config.database.loadSchema().then(schemaController => schemaController.hasClass(this.className)).then(hasClass => { - if (hasClass !== true) { - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, 'This user is not allowed to access ' + 'non-existent class: ' + this.className); - } - }); - } else { - return Promise.resolve(); - } -}; // Validates this operation against the schema. - - -RestWrite.prototype.validateSchema = function () { - return this.config.database.validateObject(this.className, this.data, this.query, this.runOptions); -}; // Runs any beforeSave triggers against this operation. -// Any change leads to our data being mutated. - - -RestWrite.prototype.runBeforeSaveTrigger = function () { - if (this.response) { - return; - } // Avoid doing any setup for triggers if there is no 'beforeSave' trigger for this class. - - - if (!triggers.triggerExists(this.className, triggers.Types.beforeSave, this.config.applicationId)) { - return Promise.resolve(); - } // Cloud code gets a bit of extra data for its objects - - - var extraData = { - className: this.className - }; - - if (this.query && this.query.objectId) { - extraData.objectId = this.query.objectId; - } - - let originalObject = null; - const updatedObject = this.buildUpdatedObject(extraData); - - if (this.query && this.query.objectId) { - // This is an update for existing object. - originalObject = triggers.inflate(extraData, this.originalData); - } - - return Promise.resolve().then(() => { - // Before calling the trigger, validate the permissions for the save operation - let databasePromise = null; - - if (this.query) { - // Validate for updating - databasePromise = this.config.database.update(this.className, this.query, this.data, this.runOptions, true, true); - } else { - // Validate for creating - databasePromise = this.config.database.create(this.className, this.data, this.runOptions, true); - } // In the case that there is no permission for the operation, it throws an error - - - return databasePromise.then(result => { - if (!result || result.length <= 0) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } - }); - }).then(() => { - return triggers.maybeRunTrigger(triggers.Types.beforeSave, this.auth, updatedObject, originalObject, this.config, this.context); - }).then(response => { - if (response && response.object) { - this.storage.fieldsChangedByTrigger = _lodash.default.reduce(response.object, (result, value, key) => { - if (!_lodash.default.isEqual(this.data[key], value)) { - result.push(key); - } - - return result; - }, []); - this.data = response.object; // We should delete the objectId for an update write - - if (this.query && this.query.objectId) { - delete this.data.objectId; - } - } - }); -}; - -RestWrite.prototype.runBeforeLoginTrigger = async function (userData) { - // Avoid doing any setup for triggers if there is no 'beforeLogin' trigger - if (!triggers.triggerExists(this.className, triggers.Types.beforeLogin, this.config.applicationId)) { - return; - } // Cloud code gets a bit of extra data for its objects - - - const extraData = { - className: this.className - }; // Expand file objects - - this.config.filesController.expandFilesInObject(this.config, userData); - const user = triggers.inflate(extraData, userData); // no need to return a response - - await triggers.maybeRunTrigger(triggers.Types.beforeLogin, this.auth, user, null, this.config, this.context); -}; - -RestWrite.prototype.setRequiredFieldsIfNeeded = function () { - if (this.data) { - return this.validSchemaController.getAllClasses().then(allClasses => { - const schema = allClasses.find(oneClass => oneClass.className === this.className); - - const setRequiredFieldIfNeeded = (fieldName, setDefault) => { - if (this.data[fieldName] === undefined || this.data[fieldName] === null || this.data[fieldName] === '' || typeof this.data[fieldName] === 'object' && this.data[fieldName].__op === 'Delete') { - if (setDefault && schema.fields[fieldName] && schema.fields[fieldName].defaultValue !== null && schema.fields[fieldName].defaultValue !== undefined && (this.data[fieldName] === undefined || typeof this.data[fieldName] === 'object' && this.data[fieldName].__op === 'Delete')) { - this.data[fieldName] = schema.fields[fieldName].defaultValue; - this.storage.fieldsChangedByTrigger = this.storage.fieldsChangedByTrigger || []; - - if (this.storage.fieldsChangedByTrigger.indexOf(fieldName) < 0) { - this.storage.fieldsChangedByTrigger.push(fieldName); - } - } else if (schema.fields[fieldName] && schema.fields[fieldName].required === true) { - throw new Parse.Error(Parse.Error.VALIDATION_ERROR, `${fieldName} is required`); - } - } - }; // Add default fields - - - this.data.updatedAt = this.updatedAt; - - if (!this.query) { - this.data.createdAt = this.updatedAt; // Only assign new objectId if we are creating new object - - if (!this.data.objectId) { - this.data.objectId = cryptoUtils.newObjectId(this.config.objectIdSize); - } - - if (schema) { - Object.keys(schema.fields).forEach(fieldName => { - setRequiredFieldIfNeeded(fieldName, true); - }); - } - } else if (schema) { - Object.keys(this.data).forEach(fieldName => { - setRequiredFieldIfNeeded(fieldName, false); - }); - } - }); - } - - return Promise.resolve(); -}; // Transforms auth data for a user object. -// Does nothing if this isn't a user object. -// Returns a promise for when we're done if it can't finish this tick. - - -RestWrite.prototype.validateAuthData = function () { - if (this.className !== '_User') { - return; - } - - if (!this.query && !this.data.authData) { - if (typeof this.data.username !== 'string' || _lodash.default.isEmpty(this.data.username)) { - throw new Parse.Error(Parse.Error.USERNAME_MISSING, 'bad or missing username'); - } - - if (typeof this.data.password !== 'string' || _lodash.default.isEmpty(this.data.password)) { - throw new Parse.Error(Parse.Error.PASSWORD_MISSING, 'password is required'); - } - } - - if (this.data.authData && !Object.keys(this.data.authData).length || !Object.prototype.hasOwnProperty.call(this.data, 'authData')) { - // Handle saving authData to {} or if authData doesn't exist - return; - } else if (Object.prototype.hasOwnProperty.call(this.data, 'authData') && !this.data.authData) { - // Handle saving authData to null - throw new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE, 'This authentication method is unsupported.'); - } - - var authData = this.data.authData; - var providers = Object.keys(authData); - - if (providers.length > 0) { - const canHandleAuthData = providers.reduce((canHandle, provider) => { - var providerAuthData = authData[provider]; - var hasToken = providerAuthData && providerAuthData.id; - return canHandle && (hasToken || providerAuthData == null); - }, true); - - if (canHandleAuthData) { - return this.handleAuthData(authData); - } - } - - throw new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE, 'This authentication method is unsupported.'); -}; - -RestWrite.prototype.handleAuthDataValidation = function (authData) { - const validations = Object.keys(authData).map(provider => { - if (authData[provider] === null) { - return Promise.resolve(); - } - - const validateAuthData = this.config.authDataManager.getValidatorForProvider(provider); - - if (!validateAuthData) { - throw new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE, 'This authentication method is unsupported.'); - } - - return validateAuthData(authData[provider]); - }); - return Promise.all(validations); -}; - -RestWrite.prototype.findUsersWithAuthData = function (authData) { - const providers = Object.keys(authData); - const query = providers.reduce((memo, provider) => { - if (!authData[provider]) { - return memo; - } - - const queryKey = `authData.${provider}.id`; - const query = {}; - query[queryKey] = authData[provider].id; - memo.push(query); - return memo; - }, []).filter(q => { - return typeof q !== 'undefined'; - }); - let findPromise = Promise.resolve([]); - - if (query.length > 0) { - findPromise = this.config.database.find(this.className, { - $or: query - }, {}); - } - - return findPromise; -}; - -RestWrite.prototype.filteredObjectsByACL = function (objects) { - if (this.auth.isMaster) { - return objects; - } - - return objects.filter(object => { - if (!object.ACL) { - return true; // legacy users that have no ACL field on them - } // Regular users that have been locked out. - - - return object.ACL && Object.keys(object.ACL).length > 0; - }); -}; - -RestWrite.prototype.handleAuthData = function (authData) { - let results; - return this.findUsersWithAuthData(authData).then(async r => { - results = this.filteredObjectsByACL(r); - - if (results.length == 1) { - this.storage['authProvider'] = Object.keys(authData).join(','); - const userResult = results[0]; - const mutatedAuthData = {}; - Object.keys(authData).forEach(provider => { - const providerData = authData[provider]; - const userAuthData = userResult.authData[provider]; - - if (!_lodash.default.isEqual(providerData, userAuthData)) { - mutatedAuthData[provider] = providerData; - } - }); - const hasMutatedAuthData = Object.keys(mutatedAuthData).length !== 0; - let userId; - - if (this.query && this.query.objectId) { - userId = this.query.objectId; - } else if (this.auth && this.auth.user && this.auth.user.id) { - userId = this.auth.user.id; - } - - if (!userId || userId === userResult.objectId) { - // no user making the call - // OR the user making the call is the right one - // Login with auth data - delete results[0].password; // need to set the objectId first otherwise location has trailing undefined - - this.data.objectId = userResult.objectId; - - if (!this.query || !this.query.objectId) { - // this a login call, no userId passed - this.response = { - response: userResult, - location: this.location() - }; // Run beforeLogin hook before storing any updates - // to authData on the db; changes to userResult - // will be ignored. - - await this.runBeforeLoginTrigger(deepcopy(userResult)); - } // If we didn't change the auth data, just keep going - - - if (!hasMutatedAuthData) { - return; - } // We have authData that is updated on login - // that can happen when token are refreshed, - // We should update the token and let the user in - // We should only check the mutated keys - - - return this.handleAuthDataValidation(mutatedAuthData).then(async () => { - // IF we have a response, we'll skip the database operation / beforeSave / afterSave etc... - // we need to set it up there. - // We are supposed to have a response only on LOGIN with authData, so we skip those - // If we're not logging in, but just updating the current user, we can safely skip that part - if (this.response) { - // Assign the new authData in the response - Object.keys(mutatedAuthData).forEach(provider => { - this.response.response.authData[provider] = mutatedAuthData[provider]; - }); // Run the DB update directly, as 'master' - // Just update the authData part - // Then we're good for the user, early exit of sorts - - return this.config.database.update(this.className, { - objectId: this.data.objectId - }, { - authData: mutatedAuthData - }, {}); - } - }); - } else if (userId) { - // Trying to update auth data but users - // are different - if (userResult.objectId !== userId) { - throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used'); - } // No auth data was mutated, just keep going - - - if (!hasMutatedAuthData) { - return; - } - } - } - - return this.handleAuthDataValidation(authData).then(() => { - if (results.length > 1) { - // More than 1 user with the passed id's - throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED, 'this auth is already used'); - } - }); - }); -}; // The non-third-party parts of User transformation - - -RestWrite.prototype.transformUser = function () { - var promise = Promise.resolve(); - - if (this.className !== '_User') { - return promise; - } - - if (!this.auth.isMaster && 'emailVerified' in this.data) { - const error = `Clients aren't allowed to manually update email verification.`; - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); - } // Do not cleanup session if objectId is not set - - - if (this.query && this.objectId()) { - // If we're updating a _User object, we need to clear out the cache for that user. Find all their - // session tokens, and remove them from the cache. - promise = new _RestQuery.default(this.config, Auth.master(this.config), '_Session', { - user: { - __type: 'Pointer', - className: '_User', - objectId: this.objectId() - } - }).execute().then(results => { - results.results.forEach(session => this.config.cacheController.user.del(session.sessionToken)); - }); - } - - return promise.then(() => { - // Transform the password - if (this.data.password === undefined) { - // ignore only if undefined. should proceed if empty ('') - return Promise.resolve(); - } - - if (this.query) { - this.storage['clearSessions'] = true; // Generate a new session only if the user requested - - if (!this.auth.isMaster) { - this.storage['generateNewSession'] = true; - } - } - - return this._validatePasswordPolicy().then(() => { - return passwordCrypto.hash(this.data.password).then(hashedPassword => { - this.data._hashed_password = hashedPassword; - delete this.data.password; - }); - }); - }).then(() => { - return this._validateUserName(); - }).then(() => { - return this._validateEmail(); - }); -}; - -RestWrite.prototype._validateUserName = function () { - // Check for username uniqueness - if (!this.data.username) { - if (!this.query) { - this.data.username = cryptoUtils.randomString(25); - this.responseShouldHaveUsername = true; - } - - return Promise.resolve(); - } - /* - Usernames should be unique when compared case insensitively - Users should be able to make case sensitive usernames and - login using the case they entered. I.e. 'Snoopy' should preclude - 'snoopy' as a valid username. - */ - - - return this.config.database.find(this.className, { - username: this.data.username, - objectId: { - $ne: this.objectId() - } - }, { - limit: 1, - caseInsensitive: true - }, {}, this.validSchemaController).then(results => { - if (results.length > 0) { - throw new Parse.Error(Parse.Error.USERNAME_TAKEN, 'Account already exists for this username.'); - } - - return; - }); -}; -/* - As with usernames, Parse should not allow case insensitive collisions of email. - unlike with usernames (which can have case insensitive collisions in the case of - auth adapters), emails should never have a case insensitive collision. - - This behavior can be enforced through a properly configured index see: - https://docs.mongodb.com/manual/core/index-case-insensitive/#create-a-case-insensitive-index - which could be implemented instead of this code based validation. - - Given that this lookup should be a relatively low use case and that the case sensitive - unique index will be used by the db for the query, this is an adequate solution. -*/ - - -RestWrite.prototype._validateEmail = function () { - if (!this.data.email || this.data.email.__op === 'Delete') { - return Promise.resolve(); - } // Validate basic email address format - - - if (!this.data.email.match(/^.+@.+$/)) { - return Promise.reject(new Parse.Error(Parse.Error.INVALID_EMAIL_ADDRESS, 'Email address format is invalid.')); - } // Case insensitive match, see note above function. - - - return this.config.database.find(this.className, { - email: this.data.email, - objectId: { - $ne: this.objectId() - } - }, { - limit: 1, - caseInsensitive: true - }, {}, this.validSchemaController).then(results => { - if (results.length > 0) { - throw new Parse.Error(Parse.Error.EMAIL_TAKEN, 'Account already exists for this email address.'); - } - - if (!this.data.authData || !Object.keys(this.data.authData).length || Object.keys(this.data.authData).length === 1 && Object.keys(this.data.authData)[0] === 'anonymous') { - // We updated the email, send a new validation - this.storage['sendVerificationEmail'] = true; - this.config.userController.setEmailVerifyToken(this.data); - } - }); -}; - -RestWrite.prototype._validatePasswordPolicy = function () { - if (!this.config.passwordPolicy) return Promise.resolve(); - return this._validatePasswordRequirements().then(() => { - return this._validatePasswordHistory(); - }); -}; - -RestWrite.prototype._validatePasswordRequirements = function () { - // check if the password conforms to the defined password policy if configured - // If we specified a custom error in our configuration use it. - // Example: "Passwords must include a Capital Letter, Lowercase Letter, and a number." - // - // This is especially useful on the generic "password reset" page, - // as it allows the programmer to communicate specific requirements instead of: - // a. making the user guess whats wrong - // b. making a custom password reset page that shows the requirements - const policyError = this.config.passwordPolicy.validationError ? this.config.passwordPolicy.validationError : 'Password does not meet the Password Policy requirements.'; - const containsUsernameError = 'Password cannot contain your username.'; // check whether the password meets the password strength requirements - - if (this.config.passwordPolicy.patternValidator && !this.config.passwordPolicy.patternValidator(this.data.password) || this.config.passwordPolicy.validatorCallback && !this.config.passwordPolicy.validatorCallback(this.data.password)) { - return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, policyError)); - } // check whether password contain username - - - if (this.config.passwordPolicy.doNotAllowUsername === true) { - if (this.data.username) { - // username is not passed during password reset - if (this.data.password.indexOf(this.data.username) >= 0) return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, containsUsernameError)); - } else { - // retrieve the User object using objectId during password reset - return this.config.database.find('_User', { - objectId: this.objectId() - }).then(results => { - if (results.length != 1) { - throw undefined; - } - - if (this.data.password.indexOf(results[0].username) >= 0) return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, containsUsernameError)); - return Promise.resolve(); - }); - } - } - - return Promise.resolve(); -}; - -RestWrite.prototype._validatePasswordHistory = function () { - // check whether password is repeating from specified history - if (this.query && this.config.passwordPolicy.maxPasswordHistory) { - return this.config.database.find('_User', { - objectId: this.objectId() - }, { - keys: ['_password_history', '_hashed_password'] - }).then(results => { - if (results.length != 1) { - throw undefined; - } - - const user = results[0]; - let oldPasswords = []; - if (user._password_history) oldPasswords = _lodash.default.take(user._password_history, this.config.passwordPolicy.maxPasswordHistory - 1); - oldPasswords.push(user.password); - const newPassword = this.data.password; // compare the new password hash with all old password hashes - - const promises = oldPasswords.map(function (hash) { - return passwordCrypto.compare(newPassword, hash).then(result => { - if (result) // reject if there is a match - return Promise.reject('REPEAT_PASSWORD'); - return Promise.resolve(); - }); - }); // wait for all comparisons to complete - - return Promise.all(promises).then(() => { - return Promise.resolve(); - }).catch(err => { - if (err === 'REPEAT_PASSWORD') // a match was found - return Promise.reject(new Parse.Error(Parse.Error.VALIDATION_ERROR, `New password should not be the same as last ${this.config.passwordPolicy.maxPasswordHistory} passwords.`)); - throw err; - }); - }); - } - - return Promise.resolve(); -}; - -RestWrite.prototype.createSessionTokenIfNeeded = function () { - if (this.className !== '_User') { - return; - } // Don't generate session for updating user (this.query is set) unless authData exists - - - if (this.query && !this.data.authData) { - return; - } // Don't generate new sessionToken if linking via sessionToken - - - if (this.auth.user && this.data.authData) { - return; - } - - if (!this.storage['authProvider'] && // signup call, with - this.config.preventLoginWithUnverifiedEmail && // no login without verification - this.config.verifyUserEmails) { - // verification is on - return; // do not create the session token in that case! - } - - return this.createSessionToken(); -}; - -RestWrite.prototype.createSessionToken = async function () { - // cloud installationId from Cloud Code, - // never create session tokens from there. - if (this.auth.installationId && this.auth.installationId === 'cloud') { - return; - } - - const { - sessionData, - createSession - } = Auth.createSession(this.config, { - userId: this.objectId(), - createdWith: { - action: this.storage['authProvider'] ? 'login' : 'signup', - authProvider: this.storage['authProvider'] || 'password' - }, - installationId: this.auth.installationId - }); - - if (this.response && this.response.response) { - this.response.response.sessionToken = sessionData.sessionToken; - } - - return createSession(); -}; // Delete email reset tokens if user is changing password or email. - - -RestWrite.prototype.deleteEmailResetTokenIfNeeded = function () { - if (this.className !== '_User' || this.query === null) { - // null query means create - return; - } - - if ('password' in this.data || 'email' in this.data) { - const addOps = { - _perishable_token: { - __op: 'Delete' - }, - _perishable_token_expires_at: { - __op: 'Delete' - } - }; - this.data = Object.assign(this.data, addOps); - } -}; - -RestWrite.prototype.destroyDuplicatedSessions = function () { - // Only for _Session, and at creation time - if (this.className != '_Session' || this.query) { - return; - } // Destroy the sessions in 'Background' - - - const { - user, - installationId, - sessionToken - } = this.data; - - if (!user || !installationId) { - return; - } - - if (!user.objectId) { - return; - } - - this.config.database.destroy('_Session', { - user, - installationId, - sessionToken: { - $ne: sessionToken - } - }, {}, this.validSchemaController); -}; // Handles any followup logic - - -RestWrite.prototype.handleFollowup = function () { - if (this.storage && this.storage['clearSessions'] && this.config.revokeSessionOnPasswordReset) { - var sessionQuery = { - user: { - __type: 'Pointer', - className: '_User', - objectId: this.objectId() - } - }; - delete this.storage['clearSessions']; - return this.config.database.destroy('_Session', sessionQuery).then(this.handleFollowup.bind(this)); - } - - if (this.storage && this.storage['generateNewSession']) { - delete this.storage['generateNewSession']; - return this.createSessionToken().then(this.handleFollowup.bind(this)); - } - - if (this.storage && this.storage['sendVerificationEmail']) { - delete this.storage['sendVerificationEmail']; // Fire and forget! - - this.config.userController.sendVerificationEmail(this.data); - return this.handleFollowup.bind(this); - } -}; // Handles the _Session class specialness. -// Does nothing if this isn't an _Session object. - - -RestWrite.prototype.handleSession = function () { - if (this.response || this.className !== '_Session') { - return; - } - - if (!this.auth.user && !this.auth.isMaster) { - throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Session token required.'); - } // TODO: Verify proper error to throw - - - if (this.data.ACL) { - throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'Cannot set ' + 'ACL on a Session.'); - } - - if (this.query) { - if (this.data.user && !this.auth.isMaster && this.data.user.objectId != this.auth.user.id) { - throw new Parse.Error(Parse.Error.INVALID_KEY_NAME); - } else if (this.data.installationId) { - throw new Parse.Error(Parse.Error.INVALID_KEY_NAME); - } else if (this.data.sessionToken) { - throw new Parse.Error(Parse.Error.INVALID_KEY_NAME); - } - } - - if (!this.query && !this.auth.isMaster) { - const additionalSessionData = {}; - - for (var key in this.data) { - if (key === 'objectId' || key === 'user') { - continue; - } - - additionalSessionData[key] = this.data[key]; - } - - const { - sessionData, - createSession - } = Auth.createSession(this.config, { - userId: this.auth.user.id, - createdWith: { - action: 'create' - }, - additionalSessionData - }); - return createSession().then(results => { - if (!results.response) { - throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Error creating session.'); - } - - sessionData['objectId'] = results.response['objectId']; - this.response = { - status: 201, - location: results.location, - response: sessionData - }; - }); - } -}; // Handles the _Installation class specialness. -// Does nothing if this isn't an installation object. -// If an installation is found, this can mutate this.query and turn a create -// into an update. -// Returns a promise for when we're done if it can't finish this tick. - - -RestWrite.prototype.handleInstallation = function () { - if (this.response || this.className !== '_Installation') { - return; - } - - if (!this.query && !this.data.deviceToken && !this.data.installationId && !this.auth.installationId) { - throw new Parse.Error(135, 'at least one ID field (deviceToken, installationId) ' + 'must be specified in this operation'); - } // If the device token is 64 characters long, we assume it is for iOS - // and lowercase it. - - - if (this.data.deviceToken && this.data.deviceToken.length == 64) { - this.data.deviceToken = this.data.deviceToken.toLowerCase(); - } // We lowercase the installationId if present - - - if (this.data.installationId) { - this.data.installationId = this.data.installationId.toLowerCase(); - } - - let installationId = this.data.installationId; // If data.installationId is not set and we're not master, we can lookup in auth - - if (!installationId && !this.auth.isMaster) { - installationId = this.auth.installationId; - } - - if (installationId) { - installationId = installationId.toLowerCase(); - } // Updating _Installation but not updating anything critical - - - if (this.query && !this.data.deviceToken && !installationId && !this.data.deviceType) { - return; - } - - var promise = Promise.resolve(); - var idMatch; // Will be a match on either objectId or installationId - - var objectIdMatch; - var installationIdMatch; - var deviceTokenMatches = []; // Instead of issuing 3 reads, let's do it with one OR. - - const orQueries = []; - - if (this.query && this.query.objectId) { - orQueries.push({ - objectId: this.query.objectId - }); - } - - if (installationId) { - orQueries.push({ - installationId: installationId - }); - } - - if (this.data.deviceToken) { - orQueries.push({ - deviceToken: this.data.deviceToken - }); - } - - if (orQueries.length == 0) { - return; - } - - promise = promise.then(() => { - return this.config.database.find('_Installation', { - $or: orQueries - }, {}); - }).then(results => { - results.forEach(result => { - if (this.query && this.query.objectId && result.objectId == this.query.objectId) { - objectIdMatch = result; - } - - if (result.installationId == installationId) { - installationIdMatch = result; - } - - if (result.deviceToken == this.data.deviceToken) { - deviceTokenMatches.push(result); - } - }); // Sanity checks when running a query - - if (this.query && this.query.objectId) { - if (!objectIdMatch) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found for update.'); - } - - if (this.data.installationId && objectIdMatch.installationId && this.data.installationId !== objectIdMatch.installationId) { - throw new Parse.Error(136, 'installationId may not be changed in this ' + 'operation'); - } - - if (this.data.deviceToken && objectIdMatch.deviceToken && this.data.deviceToken !== objectIdMatch.deviceToken && !this.data.installationId && !objectIdMatch.installationId) { - throw new Parse.Error(136, 'deviceToken may not be changed in this ' + 'operation'); - } - - if (this.data.deviceType && this.data.deviceType && this.data.deviceType !== objectIdMatch.deviceType) { - throw new Parse.Error(136, 'deviceType may not be changed in this ' + 'operation'); - } - } - - if (this.query && this.query.objectId && objectIdMatch) { - idMatch = objectIdMatch; - } - - if (installationId && installationIdMatch) { - idMatch = installationIdMatch; - } // need to specify deviceType only if it's new - - - if (!this.query && !this.data.deviceType && !idMatch) { - throw new Parse.Error(135, 'deviceType must be specified in this operation'); - } - }).then(() => { - if (!idMatch) { - if (!deviceTokenMatches.length) { - return; - } else if (deviceTokenMatches.length == 1 && (!deviceTokenMatches[0]['installationId'] || !installationId)) { - // Single match on device token but none on installationId, and either - // the passed object or the match is missing an installationId, so we - // can just return the match. - return deviceTokenMatches[0]['objectId']; - } else if (!this.data.installationId) { - throw new Parse.Error(132, 'Must specify installationId when deviceToken ' + 'matches multiple Installation objects'); - } else { - // Multiple device token matches and we specified an installation ID, - // or a single match where both the passed and matching objects have - // an installation ID. Try cleaning out old installations that match - // the deviceToken, and return nil to signal that a new object should - // be created. - var delQuery = { - deviceToken: this.data.deviceToken, - installationId: { - $ne: installationId - } - }; - - if (this.data.appIdentifier) { - delQuery['appIdentifier'] = this.data.appIdentifier; - } - - this.config.database.destroy('_Installation', delQuery).catch(err => { - if (err.code == Parse.Error.OBJECT_NOT_FOUND) { - // no deletions were made. Can be ignored. - return; - } // rethrow the error - - - throw err; - }); - return; - } - } else { - if (deviceTokenMatches.length == 1 && !deviceTokenMatches[0]['installationId']) { - // Exactly one device token match and it doesn't have an installation - // ID. This is the one case where we want to merge with the existing - // object. - const delQuery = { - objectId: idMatch.objectId - }; - return this.config.database.destroy('_Installation', delQuery).then(() => { - return deviceTokenMatches[0]['objectId']; - }).catch(err => { - if (err.code == Parse.Error.OBJECT_NOT_FOUND) { - // no deletions were made. Can be ignored - return; - } // rethrow the error - - - throw err; - }); - } else { - if (this.data.deviceToken && idMatch.deviceToken != this.data.deviceToken) { - // We're setting the device token on an existing installation, so - // we should try cleaning out old installations that match this - // device token. - const delQuery = { - deviceToken: this.data.deviceToken - }; // We have a unique install Id, use that to preserve - // the interesting installation - - if (this.data.installationId) { - delQuery['installationId'] = { - $ne: this.data.installationId - }; - } else if (idMatch.objectId && this.data.objectId && idMatch.objectId == this.data.objectId) { - // we passed an objectId, preserve that instalation - delQuery['objectId'] = { - $ne: idMatch.objectId - }; - } else { - // What to do here? can't really clean up everything... - return idMatch.objectId; - } - - if (this.data.appIdentifier) { - delQuery['appIdentifier'] = this.data.appIdentifier; - } - - this.config.database.destroy('_Installation', delQuery).catch(err => { - if (err.code == Parse.Error.OBJECT_NOT_FOUND) { - // no deletions were made. Can be ignored. - return; - } // rethrow the error - - - throw err; - }); - } // In non-merge scenarios, just return the installation match id - - - return idMatch.objectId; - } - } - }).then(objId => { - if (objId) { - this.query = { - objectId: objId - }; - delete this.data.objectId; - delete this.data.createdAt; - } // TODO: Validate ops (add/remove on channels, $inc on badge, etc.) - - }); - return promise; -}; // If we short-circuted the object response - then we need to make sure we expand all the files, -// since this might not have a query, meaning it won't return the full result back. -// TODO: (nlutsenko) This should die when we move to per-class based controllers on _Session/_User - - -RestWrite.prototype.expandFilesForExistingObjects = function () { - // Check whether we have a short-circuited response - only then run expansion. - if (this.response && this.response.response) { - this.config.filesController.expandFilesInObject(this.config, this.response.response); - } -}; - -RestWrite.prototype.runDatabaseOperation = function () { - if (this.response) { - return; - } - - if (this.className === '_Role') { - this.config.cacheController.role.clear(); - } - - if (this.className === '_User' && this.query && this.auth.isUnauthenticated()) { - throw new Parse.Error(Parse.Error.SESSION_MISSING, `Cannot modify user ${this.query.objectId}.`); - } - - if (this.className === '_Product' && this.data.download) { - this.data.downloadName = this.data.download.name; - } // TODO: Add better detection for ACL, ensuring a user can't be locked from - // their own user record. - - - if (this.data.ACL && this.data.ACL['*unresolved']) { - throw new Parse.Error(Parse.Error.INVALID_ACL, 'Invalid ACL.'); - } - - if (this.query) { - // Force the user to not lockout - // Matched with parse.com - if (this.className === '_User' && this.data.ACL && this.auth.isMaster !== true) { - this.data.ACL[this.query.objectId] = { - read: true, - write: true - }; - } // update password timestamp if user password is being changed - - - if (this.className === '_User' && this.data._hashed_password && this.config.passwordPolicy && this.config.passwordPolicy.maxPasswordAge) { - this.data._password_changed_at = Parse._encode(new Date()); - } // Ignore createdAt when update - - - delete this.data.createdAt; - let defer = Promise.resolve(); // if password history is enabled then save the current password to history - - if (this.className === '_User' && this.data._hashed_password && this.config.passwordPolicy && this.config.passwordPolicy.maxPasswordHistory) { - defer = this.config.database.find('_User', { - objectId: this.objectId() - }, { - keys: ['_password_history', '_hashed_password'] - }).then(results => { - if (results.length != 1) { - throw undefined; - } - - const user = results[0]; - let oldPasswords = []; - - if (user._password_history) { - oldPasswords = _lodash.default.take(user._password_history, this.config.passwordPolicy.maxPasswordHistory); - } //n-1 passwords go into history including last password - - - while (oldPasswords.length > Math.max(0, this.config.passwordPolicy.maxPasswordHistory - 2)) { - oldPasswords.shift(); - } - - oldPasswords.push(user.password); - this.data._password_history = oldPasswords; - }); - } - - return defer.then(() => { - // Run an update - return this.config.database.update(this.className, this.query, this.data, this.runOptions, false, false, this.validSchemaController).then(response => { - response.updatedAt = this.updatedAt; - - this._updateResponseWithData(response, this.data); - - this.response = { - response - }; - }); - }); - } else { - // Set the default ACL and password timestamp for the new _User - if (this.className === '_User') { - var ACL = this.data.ACL; // default public r/w ACL - - if (!ACL) { - ACL = {}; - ACL['*'] = { - read: true, - write: false - }; - } // make sure the user is not locked down - - - ACL[this.data.objectId] = { - read: true, - write: true - }; - this.data.ACL = ACL; // password timestamp to be used when password expiry policy is enforced - - if (this.config.passwordPolicy && this.config.passwordPolicy.maxPasswordAge) { - this.data._password_changed_at = Parse._encode(new Date()); - } - } // Run a create - - - return this.config.database.create(this.className, this.data, this.runOptions, false, this.validSchemaController).catch(error => { - if (this.className !== '_User' || error.code !== Parse.Error.DUPLICATE_VALUE) { - throw error; - } // Quick check, if we were able to infer the duplicated field name - - - if (error && error.userInfo && error.userInfo.duplicated_field === 'username') { - throw new Parse.Error(Parse.Error.USERNAME_TAKEN, 'Account already exists for this username.'); - } - - if (error && error.userInfo && error.userInfo.duplicated_field === 'email') { - throw new Parse.Error(Parse.Error.EMAIL_TAKEN, 'Account already exists for this email address.'); - } // If this was a failed user creation due to username or email already taken, we need to - // check whether it was username or email and return the appropriate error. - // Fallback to the original method - // TODO: See if we can later do this without additional queries by using named indexes. - - - return this.config.database.find(this.className, { - username: this.data.username, - objectId: { - $ne: this.objectId() - } - }, { - limit: 1 - }).then(results => { - if (results.length > 0) { - throw new Parse.Error(Parse.Error.USERNAME_TAKEN, 'Account already exists for this username.'); - } - - return this.config.database.find(this.className, { - email: this.data.email, - objectId: { - $ne: this.objectId() - } - }, { - limit: 1 - }); - }).then(results => { - if (results.length > 0) { - throw new Parse.Error(Parse.Error.EMAIL_TAKEN, 'Account already exists for this email address.'); - } - - throw new Parse.Error(Parse.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided'); - }); - }).then(response => { - response.objectId = this.data.objectId; - response.createdAt = this.data.createdAt; - - if (this.responseShouldHaveUsername) { - response.username = this.data.username; - } - - this._updateResponseWithData(response, this.data); - - this.response = { - status: 201, - response, - location: this.location() - }; - }); - } -}; // Returns nothing - doesn't wait for the trigger. - - -RestWrite.prototype.runAfterSaveTrigger = function () { - if (!this.response || !this.response.response) { - return; - } // Avoid doing any setup for triggers if there is no 'afterSave' trigger for this class. - - - const hasAfterSaveHook = triggers.triggerExists(this.className, triggers.Types.afterSave, this.config.applicationId); - const hasLiveQuery = this.config.liveQueryController.hasLiveQuery(this.className); - - if (!hasAfterSaveHook && !hasLiveQuery) { - return Promise.resolve(); - } - - var extraData = { - className: this.className - }; - - if (this.query && this.query.objectId) { - extraData.objectId = this.query.objectId; - } // Build the original object, we only do this for a update write. - - - let originalObject; - - if (this.query && this.query.objectId) { - originalObject = triggers.inflate(extraData, this.originalData); - } // Build the inflated object, different from beforeSave, originalData is not empty - // since developers can change data in the beforeSave. - - - const updatedObject = this.buildUpdatedObject(extraData); - - updatedObject._handleSaveResponse(this.response.response, this.response.status || 200); - - this.config.database.loadSchema().then(schemaController => { - // Notifiy LiveQueryServer if possible - const perms = schemaController.getClassLevelPermissions(updatedObject.className); - this.config.liveQueryController.onAfterSave(updatedObject.className, updatedObject, originalObject, perms); - }); // Run afterSave trigger - - return triggers.maybeRunTrigger(triggers.Types.afterSave, this.auth, updatedObject, originalObject, this.config, this.context).then(result => { - if (result && typeof result === 'object') { - this.response.response = result; - } - }).catch(function (err) { - _logger.default.warn('afterSave caught an error', err); - }); -}; // A helper to figure out what location this operation happens at. - - -RestWrite.prototype.location = function () { - var middle = this.className === '_User' ? '/users/' : '/classes/' + this.className + '/'; - const mount = this.config.mount || this.config.serverURL; - return mount + middle + this.data.objectId; -}; // A helper to get the object id for this operation. -// Because it could be either on the query or on the data - - -RestWrite.prototype.objectId = function () { - return this.data.objectId || this.query.objectId; -}; // Returns a copy of the data and delete bad keys (_auth_data, _hashed_password...) - - -RestWrite.prototype.sanitizedData = function () { - const data = Object.keys(this.data).reduce((data, key) => { - // Regexp comes from Parse.Object.prototype.validate - if (!/^[A-Za-z][0-9A-Za-z_]*$/.test(key)) { - delete data[key]; - } - - return data; - }, deepcopy(this.data)); - return Parse._decode(undefined, data); -}; // Returns an updated copy of the object - - -RestWrite.prototype.buildUpdatedObject = function (extraData) { - const updatedObject = triggers.inflate(extraData, this.originalData); - Object.keys(this.data).reduce(function (data, key) { - if (key.indexOf('.') > 0) { - if (typeof data[key].__op === 'string') { - updatedObject.set(key, data[key]); - } else { - // subdocument key with dot notation { 'x.y': v } => { 'x': { 'y' : v } }) - const splittedKey = key.split('.'); - const parentProp = splittedKey[0]; - let parentVal = updatedObject.get(parentProp); - - if (typeof parentVal !== 'object') { - parentVal = {}; - } - - parentVal[splittedKey[1]] = data[key]; - updatedObject.set(parentProp, parentVal); - } - - delete data[key]; - } - - return data; - }, deepcopy(this.data)); - updatedObject.set(this.sanitizedData()); - return updatedObject; -}; - -RestWrite.prototype.cleanUserAuthData = function () { - if (this.response && this.response.response && this.className === '_User') { - const user = this.response.response; - - if (user.authData) { - Object.keys(user.authData).forEach(provider => { - if (user.authData[provider] === null) { - delete user.authData[provider]; - } - }); - - if (Object.keys(user.authData).length == 0) { - delete user.authData; - } - } - } -}; - -RestWrite.prototype._updateResponseWithData = function (response, data) { - if (_lodash.default.isEmpty(this.storage.fieldsChangedByTrigger)) { - return response; - } - - const clientSupportsDelete = ClientSDK.supportsForwardDelete(this.clientSDK); - this.storage.fieldsChangedByTrigger.forEach(fieldName => { - const dataValue = data[fieldName]; - - if (!Object.prototype.hasOwnProperty.call(response, fieldName)) { - response[fieldName] = dataValue; - } // Strips operations from responses - - - if (response[fieldName] && response[fieldName].__op) { - delete response[fieldName]; - - if (clientSupportsDelete && dataValue.__op == 'Delete') { - response[fieldName] = dataValue; - } - } - }); - return response; -}; - -var _default = RestWrite; -exports.default = _default; -module.exports = RestWrite; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9SZXN0V3JpdGUuanMiXSwibmFtZXMiOlsiU2NoZW1hQ29udHJvbGxlciIsInJlcXVpcmUiLCJkZWVwY29weSIsIkF1dGgiLCJjcnlwdG9VdGlscyIsInBhc3N3b3JkQ3J5cHRvIiwiUGFyc2UiLCJ0cmlnZ2VycyIsIkNsaWVudFNESyIsIlJlc3RXcml0ZSIsImNvbmZpZyIsImF1dGgiLCJjbGFzc05hbWUiLCJxdWVyeSIsImRhdGEiLCJvcmlnaW5hbERhdGEiLCJjbGllbnRTREsiLCJjb250ZXh0IiwiYWN0aW9uIiwiaXNSZWFkT25seSIsIkVycm9yIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsInN0b3JhZ2UiLCJydW5PcHRpb25zIiwiYWxsb3dDdXN0b21PYmplY3RJZCIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIm9iamVjdElkIiwiTUlTU0lOR19PQkpFQ1RfSUQiLCJJTlZBTElEX0tFWV9OQU1FIiwiaWQiLCJyZXNwb25zZSIsInVwZGF0ZWRBdCIsIl9lbmNvZGUiLCJEYXRlIiwiaXNvIiwidmFsaWRTY2hlbWFDb250cm9sbGVyIiwiZXhlY3V0ZSIsIlByb21pc2UiLCJyZXNvbHZlIiwidGhlbiIsImdldFVzZXJBbmRSb2xlQUNMIiwidmFsaWRhdGVDbGllbnRDbGFzc0NyZWF0aW9uIiwiaGFuZGxlSW5zdGFsbGF0aW9uIiwiaGFuZGxlU2Vzc2lvbiIsInZhbGlkYXRlQXV0aERhdGEiLCJydW5CZWZvcmVTYXZlVHJpZ2dlciIsImRlbGV0ZUVtYWlsUmVzZXRUb2tlbklmTmVlZGVkIiwidmFsaWRhdGVTY2hlbWEiLCJzY2hlbWFDb250cm9sbGVyIiwic2V0UmVxdWlyZWRGaWVsZHNJZk5lZWRlZCIsInRyYW5zZm9ybVVzZXIiLCJleHBhbmRGaWxlc0ZvckV4aXN0aW5nT2JqZWN0cyIsImRlc3Ryb3lEdXBsaWNhdGVkU2Vzc2lvbnMiLCJydW5EYXRhYmFzZU9wZXJhdGlvbiIsImNyZWF0ZVNlc3Npb25Ub2tlbklmTmVlZGVkIiwiaGFuZGxlRm9sbG93dXAiLCJydW5BZnRlclNhdmVUcmlnZ2VyIiwiY2xlYW5Vc2VyQXV0aERhdGEiLCJpc01hc3RlciIsImFjbCIsInVzZXIiLCJnZXRVc2VyUm9sZXMiLCJyb2xlcyIsImNvbmNhdCIsImFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbiIsInN5c3RlbUNsYXNzZXMiLCJpbmRleE9mIiwiZGF0YWJhc2UiLCJsb2FkU2NoZW1hIiwiaGFzQ2xhc3MiLCJ2YWxpZGF0ZU9iamVjdCIsInRyaWdnZXJFeGlzdHMiLCJUeXBlcyIsImJlZm9yZVNhdmUiLCJhcHBsaWNhdGlvbklkIiwiZXh0cmFEYXRhIiwib3JpZ2luYWxPYmplY3QiLCJ1cGRhdGVkT2JqZWN0IiwiYnVpbGRVcGRhdGVkT2JqZWN0IiwiaW5mbGF0ZSIsImRhdGFiYXNlUHJvbWlzZSIsInVwZGF0ZSIsImNyZWF0ZSIsInJlc3VsdCIsImxlbmd0aCIsIk9CSkVDVF9OT1RfRk9VTkQiLCJtYXliZVJ1blRyaWdnZXIiLCJvYmplY3QiLCJmaWVsZHNDaGFuZ2VkQnlUcmlnZ2VyIiwiXyIsInJlZHVjZSIsInZhbHVlIiwia2V5IiwiaXNFcXVhbCIsInB1c2giLCJydW5CZWZvcmVMb2dpblRyaWdnZXIiLCJ1c2VyRGF0YSIsImJlZm9yZUxvZ2luIiwiZmlsZXNDb250cm9sbGVyIiwiZXhwYW5kRmlsZXNJbk9iamVjdCIsImdldEFsbENsYXNzZXMiLCJhbGxDbGFzc2VzIiwic2NoZW1hIiwiZmluZCIsIm9uZUNsYXNzIiwic2V0UmVxdWlyZWRGaWVsZElmTmVlZGVkIiwiZmllbGROYW1lIiwic2V0RGVmYXVsdCIsInVuZGVmaW5lZCIsIl9fb3AiLCJmaWVsZHMiLCJkZWZhdWx0VmFsdWUiLCJyZXF1aXJlZCIsIlZBTElEQVRJT05fRVJST1IiLCJjcmVhdGVkQXQiLCJuZXdPYmplY3RJZCIsIm9iamVjdElkU2l6ZSIsImtleXMiLCJmb3JFYWNoIiwiYXV0aERhdGEiLCJ1c2VybmFtZSIsImlzRW1wdHkiLCJVU0VSTkFNRV9NSVNTSU5HIiwicGFzc3dvcmQiLCJQQVNTV09SRF9NSVNTSU5HIiwiVU5TVVBQT1JURURfU0VSVklDRSIsInByb3ZpZGVycyIsImNhbkhhbmRsZUF1dGhEYXRhIiwiY2FuSGFuZGxlIiwicHJvdmlkZXIiLCJwcm92aWRlckF1dGhEYXRhIiwiaGFzVG9rZW4iLCJoYW5kbGVBdXRoRGF0YSIsImhhbmRsZUF1dGhEYXRhVmFsaWRhdGlvbiIsInZhbGlkYXRpb25zIiwibWFwIiwiYXV0aERhdGFNYW5hZ2VyIiwiZ2V0VmFsaWRhdG9yRm9yUHJvdmlkZXIiLCJhbGwiLCJmaW5kVXNlcnNXaXRoQXV0aERhdGEiLCJtZW1vIiwicXVlcnlLZXkiLCJmaWx0ZXIiLCJxIiwiZmluZFByb21pc2UiLCIkb3IiLCJmaWx0ZXJlZE9iamVjdHNCeUFDTCIsIm9iamVjdHMiLCJBQ0wiLCJyZXN1bHRzIiwiciIsImpvaW4iLCJ1c2VyUmVzdWx0IiwibXV0YXRlZEF1dGhEYXRhIiwicHJvdmlkZXJEYXRhIiwidXNlckF1dGhEYXRhIiwiaGFzTXV0YXRlZEF1dGhEYXRhIiwidXNlcklkIiwibG9jYXRpb24iLCJBQ0NPVU5UX0FMUkVBRFlfTElOS0VEIiwicHJvbWlzZSIsImVycm9yIiwiUmVzdFF1ZXJ5IiwibWFzdGVyIiwiX190eXBlIiwic2Vzc2lvbiIsImNhY2hlQ29udHJvbGxlciIsImRlbCIsInNlc3Npb25Ub2tlbiIsIl92YWxpZGF0ZVBhc3N3b3JkUG9saWN5IiwiaGFzaCIsImhhc2hlZFBhc3N3b3JkIiwiX2hhc2hlZF9wYXNzd29yZCIsIl92YWxpZGF0ZVVzZXJOYW1lIiwiX3ZhbGlkYXRlRW1haWwiLCJyYW5kb21TdHJpbmciLCJyZXNwb25zZVNob3VsZEhhdmVVc2VybmFtZSIsIiRuZSIsImxpbWl0IiwiY2FzZUluc2Vuc2l0aXZlIiwiVVNFUk5BTUVfVEFLRU4iLCJlbWFpbCIsIm1hdGNoIiwicmVqZWN0IiwiSU5WQUxJRF9FTUFJTF9BRERSRVNTIiwiRU1BSUxfVEFLRU4iLCJ1c2VyQ29udHJvbGxlciIsInNldEVtYWlsVmVyaWZ5VG9rZW4iLCJwYXNzd29yZFBvbGljeSIsIl92YWxpZGF0ZVBhc3N3b3JkUmVxdWlyZW1lbnRzIiwiX3ZhbGlkYXRlUGFzc3dvcmRIaXN0b3J5IiwicG9saWN5RXJyb3IiLCJ2YWxpZGF0aW9uRXJyb3IiLCJjb250YWluc1VzZXJuYW1lRXJyb3IiLCJwYXR0ZXJuVmFsaWRhdG9yIiwidmFsaWRhdG9yQ2FsbGJhY2siLCJkb05vdEFsbG93VXNlcm5hbWUiLCJtYXhQYXNzd29yZEhpc3RvcnkiLCJvbGRQYXNzd29yZHMiLCJfcGFzc3dvcmRfaGlzdG9yeSIsInRha2UiLCJuZXdQYXNzd29yZCIsInByb21pc2VzIiwiY29tcGFyZSIsImNhdGNoIiwiZXJyIiwicHJldmVudExvZ2luV2l0aFVudmVyaWZpZWRFbWFpbCIsInZlcmlmeVVzZXJFbWFpbHMiLCJjcmVhdGVTZXNzaW9uVG9rZW4iLCJpbnN0YWxsYXRpb25JZCIsInNlc3Npb25EYXRhIiwiY3JlYXRlU2Vzc2lvbiIsImNyZWF0ZWRXaXRoIiwiYXV0aFByb3ZpZGVyIiwiYWRkT3BzIiwiX3BlcmlzaGFibGVfdG9rZW4iLCJfcGVyaXNoYWJsZV90b2tlbl9leHBpcmVzX2F0IiwiYXNzaWduIiwiZGVzdHJveSIsInJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQiLCJzZXNzaW9uUXVlcnkiLCJiaW5kIiwic2VuZFZlcmlmaWNhdGlvbkVtYWlsIiwiSU5WQUxJRF9TRVNTSU9OX1RPS0VOIiwiYWRkaXRpb25hbFNlc3Npb25EYXRhIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwic3RhdHVzIiwiZGV2aWNlVG9rZW4iLCJ0b0xvd2VyQ2FzZSIsImRldmljZVR5cGUiLCJpZE1hdGNoIiwib2JqZWN0SWRNYXRjaCIsImluc3RhbGxhdGlvbklkTWF0Y2giLCJkZXZpY2VUb2tlbk1hdGNoZXMiLCJvclF1ZXJpZXMiLCJkZWxRdWVyeSIsImFwcElkZW50aWZpZXIiLCJjb2RlIiwib2JqSWQiLCJyb2xlIiwiY2xlYXIiLCJpc1VuYXV0aGVudGljYXRlZCIsIlNFU1NJT05fTUlTU0lORyIsImRvd25sb2FkIiwiZG93bmxvYWROYW1lIiwibmFtZSIsIklOVkFMSURfQUNMIiwicmVhZCIsIndyaXRlIiwibWF4UGFzc3dvcmRBZ2UiLCJfcGFzc3dvcmRfY2hhbmdlZF9hdCIsImRlZmVyIiwiTWF0aCIsIm1heCIsInNoaWZ0IiwiX3VwZGF0ZVJlc3BvbnNlV2l0aERhdGEiLCJEVVBMSUNBVEVfVkFMVUUiLCJ1c2VySW5mbyIsImR1cGxpY2F0ZWRfZmllbGQiLCJoYXNBZnRlclNhdmVIb29rIiwiYWZ0ZXJTYXZlIiwiaGFzTGl2ZVF1ZXJ5IiwibGl2ZVF1ZXJ5Q29udHJvbGxlciIsIl9oYW5kbGVTYXZlUmVzcG9uc2UiLCJwZXJtcyIsImdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsIm9uQWZ0ZXJTYXZlIiwibG9nZ2VyIiwid2FybiIsIm1pZGRsZSIsIm1vdW50Iiwic2VydmVyVVJMIiwic2FuaXRpemVkRGF0YSIsInRlc3QiLCJfZGVjb2RlIiwic2V0Iiwic3BsaXR0ZWRLZXkiLCJzcGxpdCIsInBhcmVudFByb3AiLCJwYXJlbnRWYWwiLCJnZXQiLCJjbGllbnRTdXBwb3J0c0RlbGV0ZSIsInN1cHBvcnRzRm9yd2FyZERlbGV0ZSIsImRhdGFWYWx1ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFhQTs7QUFDQTs7QUFDQTs7OztBQWZBO0FBQ0E7QUFDQTtBQUVBLElBQUlBLGdCQUFnQixHQUFHQyxPQUFPLENBQUMsZ0NBQUQsQ0FBOUI7O0FBQ0EsSUFBSUMsUUFBUSxHQUFHRCxPQUFPLENBQUMsVUFBRCxDQUF0Qjs7QUFFQSxNQUFNRSxJQUFJLEdBQUdGLE9BQU8sQ0FBQyxRQUFELENBQXBCOztBQUNBLElBQUlHLFdBQVcsR0FBR0gsT0FBTyxDQUFDLGVBQUQsQ0FBekI7O0FBQ0EsSUFBSUksY0FBYyxHQUFHSixPQUFPLENBQUMsWUFBRCxDQUE1Qjs7QUFDQSxJQUFJSyxLQUFLLEdBQUdMLE9BQU8sQ0FBQyxZ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dkIsQ0FBSixFQUFvRDtBQUNsRCxXQUFPMUQsUUFBUDtBQUNEOztBQUNELFFBQU0yUCxvQkFBb0IsR0FBR3BSLFNBQVMsQ0FBQ3FSLHFCQUFWLENBQWdDLEtBQUs3USxTQUFyQyxDQUE3QjtBQUNBLE9BQUtNLE9BQUwsQ0FBYXFFLHNCQUFiLENBQW9DOEIsT0FBcEMsQ0FBNENaLFNBQVMsSUFBSTtBQUN2RCxVQUFNaUwsU0FBUyxHQUFHaFIsSUFBSSxDQUFDK0YsU0FBRCxDQUF0Qjs7QUFFQSxRQUFJLENBQUNwRixNQUFNLENBQUNDLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUFxQ0ssUUFBckMsRUFBK0M0RSxTQUEvQyxDQUFMLEVBQWdFO0FBQzlENUUsTUFBQUEsUUFBUSxDQUFDNEUsU0FBRCxDQUFSLEdBQXNCaUwsU0FBdEI7QUFDRCxLQUxzRCxDQU92RDs7O0FBQ0EsUUFBSTdQLFFBQVEsQ0FBQzRFLFNBQUQsQ0FBUixJQUF1QjVFLFFBQVEsQ0FBQzRFLFNBQUQsQ0FBUixDQUFvQkcsSUFBL0MsRUFBcUQ7QUFDbkQsYUFBTy9FLFFBQVEsQ0FBQzRFLFNBQUQsQ0FBZjs7QUFDQSxVQUFJK0ssb0JBQW9CLElBQUlFLFNBQVMsQ0FBQzlLLElBQVYsSUFBa0IsUUFBOUMsRUFBd0Q7QUFDdEQvRSxRQUFBQSxRQUFRLENBQUM0RSxTQUFELENBQVIsR0FBc0JpTCxTQUF0QjtBQUNEO0FBQ0Y7QUFDRixHQWREO0FBZUEsU0FBTzdQLFFBQVA7QUFDRCxDQXJCRDs7ZUF1QmV4QixTOztBQUNmc1IsTUFBTSxDQUFDQyxPQUFQLEdBQWlCdlIsU0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBBIFJlc3RXcml0ZSBlbmNhcHN1bGF0ZXMgZXZlcnl0aGluZyB3ZSBuZWVkIHRvIHJ1biBhbiBvcGVyYXRpb25cbi8vIHRoYXQgd3JpdGVzIHRvIHRoZSBkYXRhYmFzZS5cbi8vIFRoaXMgY291bGQgYmUgZWl0aGVyIGEgXCJjcmVhdGVcIiBvciBhbiBcInVwZGF0ZVwiLlxuXG52YXIgU2NoZW1hQ29udHJvbGxlciA9IHJlcXVpcmUoJy4vQ29udHJvbGxlcnMvU2NoZW1hQ29udHJvbGxlcicpO1xudmFyIGRlZXBjb3B5ID0gcmVxdWlyZSgnZGVlcGNvcHknKTtcblxuY29uc3QgQXV0aCA9IHJlcXVpcmUoJy4vQXV0aCcpO1xudmFyIGNyeXB0b1V0aWxzID0gcmVxdWlyZSgnLi9jcnlwdG9VdGlscycpO1xudmFyIHBhc3N3b3JkQ3J5cHRvID0gcmVxdWlyZSgnLi9wYXNzd29yZCcpO1xudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpO1xudmFyIHRyaWdnZXJzID0gcmVxdWlyZSgnLi90cmlnZ2VycycpO1xudmFyIENsaWVudFNESyA9IHJlcXVpcmUoJy4vQ2xpZW50U0RLJyk7XG5pbXBvcnQgUmVzdFF1ZXJ5IGZyb20gJy4vUmVzdFF1ZXJ5JztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4vbG9nZ2VyJztcblxuLy8gcXVlcnkgYW5kIGRhdGEgYXJlIGJvdGggcHJvdmlkZWQgaW4gUkVTVCBBUEkgZm9ybWF0LiBTbyBkYXRhXG4vLyB0eXBlcyBhcmUgZW5jb2RlZCBieSBwbGFpbiBvbGQgb2JqZWN0cy5cbi8vIElmIHF1ZXJ5IGlzIG51bGwsIHRoaXMgaXMgYSBcImNyZWF0ZVwiIGFuZCB0aGUgZGF0YSBpbiBkYXRhIHNob3VsZCBiZVxuLy8gY3JlYXRlZC5cbi8vIE90aGVyd2lzZSB0aGlzIGlzIGFuIFwidXBkYXRlXCIgLSB0aGUgb2JqZWN0IG1hdGNoaW5nIHRoZSBxdWVyeVxuLy8gc2hvdWxkIGdldCB1cGRhdGVkIHdpdGggZGF0YS5cbi8vIFJlc3RXcml0ZSB3aWxsIGhhbmRsZSBvYmplY3RJZCwgY3JlYXRlZEF0LCBhbmQgdXBkYXRlZEF0IGZvclxuLy8gZXZlcnl0aGluZy4gSXQgYWxzbyBrbm93cyB0byB1c2UgdHJpZ2dlcnMgYW5kIHNwZWNpYWwgbW9kaWZpY2F0aW9uc1xuLy8gZm9yIHRoZSBfVXNlciBjbGFzcy5cbmZ1bmN0aW9uIFJlc3RXcml0ZShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgcXVlcnksIGRhdGEsIG9yaWdpbmFsRGF0YSwgY2xpZW50U0RLLCBjb250ZXh0LCBhY3Rpb24pIHtcbiAgaWYgKGF1dGguaXNSZWFkT25seSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgIFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sXG4gICAgICAnQ2Fubm90IHBlcmZvcm0gYSB3cml0ZSBvcGVyYXRpb24gd2hlbiB1c2luZyByZWFkT25seU1hc3RlcktleSdcbiAgICApO1xuICB9XG4gIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICB0aGlzLmF1dGggPSBhdXRoO1xuICB0aGlzLmNsYXNzTmFtZSA9IGNsYXNzTmFtZTtcbiAgdGhpcy5jbGllbnRTREsgPSBjbGllbnRTREs7XG4gIHRoaXMuc3RvcmFnZSA9IHt9O1xuICB0aGlzLnJ1bk9wdGlvbnMgPSB7fTtcbiAgdGhpcy5jb250ZXh0ID0gY29udGV4dCB8fCB7fTtcblxuICBpZiAoYWN0aW9uKSB7XG4gICAgdGhpcy5ydW5PcHRpb25zLmFjdGlvbiA9IGFjdGlvbjtcbiAgfVxuXG4gIGlmICghcXVlcnkpIHtcbiAgICBpZiAodGhpcy5jb25maWcuYWxsb3dDdXN0b21PYmplY3RJZCkge1xuICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChkYXRhLCAnb2JqZWN0SWQnKSAmJiAhZGF0YS5vYmplY3RJZCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuTUlTU0lOR19PQkpFQ1RfSUQsXG4gICAgICAgICAgJ29iamVjdElkIG11c3Qgbm90IGJlIGVtcHR5LCBudWxsIG9yIHVuZGVmaW5lZCdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGRhdGEub2JqZWN0SWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUsICdvYmplY3RJZCBpcyBhbiBpbnZhbGlkIGZpZWxkIG5hbWUuJyk7XG4gICAgICB9XG4gICAgICBpZiAoZGF0YS5pZCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSwgJ2lkIGlzIGFuIGludmFsaWQgZmllbGQgbmFtZS4nKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBXaGVuIHRoZSBvcGVyYXRpb24gaXMgY29tcGxldGUsIHRoaXMucmVzcG9uc2UgbWF5IGhhdmUgc2V2ZXJhbFxuICAvLyBmaWVsZHMuXG4gIC8vIHJlc3BvbnNlOiB0aGUgYWN0dWFsIGRhdGEgdG8gYmUgcmV0dXJuZWRcbiAgLy8gc3RhdHVzOiB0aGUgaHR0cCBzdGF0dXMgY29kZS4gaWYgbm90IHByZXNlbnQsIHRyZWF0ZWQgbGlrZSBhIDIwMFxuICAvLyBsb2NhdGlvbjogdGhlIGxvY2F0aW9uIGhlYWRlci4gaWYgbm90IHByZXNlbnQsIG5vIGxvY2F0aW9uIGhlYWRlclxuICB0aGlzLnJlc3BvbnNlID0gbnVsbDtcblxuICAvLyBQcm9jZXNzaW5nIHRoaXMgb3BlcmF0aW9uIG1heSBtdXRhdGUgb3VyIGRhdGEsIHNvIHdlIG9wZXJhdGUgb24gYVxuICAvLyBjb3B5XG4gIHRoaXMucXVlcnkgPSBkZWVwY29weShxdWVyeSk7XG4gIHRoaXMuZGF0YSA9IGRlZXBjb3B5KGRhdGEpO1xuICAvLyBXZSBuZXZlciBjaGFuZ2Ugb3JpZ2luYWxEYXRhLCBzbyB3ZSBkbyBub3QgbmVlZCBhIGRlZXAgY29weVxuICB0aGlzLm9yaWdpbmFsRGF0YSA9IG9yaWdpbmFsRGF0YTtcblxuICAvLyBUaGUgdGltZXN0YW1wIHdlJ2xsIHVzZSBmb3IgdGhpcyB3aG9sZSBvcGVyYXRpb25cbiAgdGhpcy51cGRhdGVkQXQgPSBQYXJzZS5fZW5jb2RlKG5ldyBEYXRlKCkpLmlzbztcblxuICAvLyBTaGFyZWQgU2NoZW1hQ29udHJvbGxlciB0byBiZSByZXVzZWQgdG8gcmVkdWNlIHRoZSBudW1iZXIgb2YgbG9hZFNjaGVtYSgpIGNhbGxzIHBlciByZXF1ZXN0XG4gIC8vIE9uY2Ugc2V0IHRoZSBzY2hlbWFEYXRhIHNob3VsZCBiZSBpbW11dGFibGVcbiAgdGhpcy52YWxpZFNjaGVtYUNvbnRyb2xsZXIgPSBudWxsO1xufVxuXG4vLyBBIGNvbnZlbmllbnQgbWV0aG9kIHRvIHBlcmZvcm0gYWxsIHRoZSBzdGVwcyBvZiBwcm9jZXNzaW5nIHRoZVxuLy8gd3JpdGUsIGluIG9yZGVyLlxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGEge3Jlc3BvbnNlLCBzdGF0dXMsIGxvY2F0aW9ufSBvYmplY3QuXG4vLyBzdGF0dXMgYW5kIGxvY2F0aW9uIGFyZSBvcHRpb25hbC5cblJlc3RXcml0ZS5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0VXNlckFuZFJvbGVBQ0woKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlQ2xpZW50Q2xhc3NDcmVhdGlvbigpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlSW5zdGFsbGF0aW9uKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVTZXNzaW9uKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZUF1dGhEYXRhKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5ydW5CZWZvcmVTYXZlVHJpZ2dlcigpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZGVsZXRlRW1haWxSZXNldFRva2VuSWZOZWVkZWQoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlU2NoZW1hKCk7XG4gICAgfSlcbiAgICAudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHtcbiAgICAgIHRoaXMudmFsaWRTY2hlbWFDb250cm9sbGVyID0gc2NoZW1hQ29udHJvbGxlcjtcbiAgICAgIHJldHVybiB0aGlzLnNldFJlcXVpcmVkRmllbGRzSWZOZWVkZWQoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybVVzZXIoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmV4cGFuZEZpbGVzRm9yRXhpc3RpbmdPYmplY3RzKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5kZXN0cm95RHVwbGljYXRlZFNlc3Npb25zKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5ydW5EYXRhYmFzZU9wZXJhdGlvbigpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlU2Vzc2lvblRva2VuSWZOZWVkZWQoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZvbGxvd3VwKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5ydW5BZnRlclNhdmVUcmlnZ2VyKCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5jbGVhblVzZXJBdXRoRGF0YSgpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMucmVzcG9uc2U7XG4gICAgfSk7XG59O1xuXG4vLyBVc2VzIHRoZSBBdXRoIG9iamVjdCB0byBnZXQgdGhlIGxpc3Qgb2Ygcm9sZXMsIGFkZHMgdGhlIHVzZXIgaWRcblJlc3RXcml0ZS5wcm90b3R5cGUuZ2V0VXNlckFuZFJvbGVBQ0wgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmF1dGguaXNNYXN0ZXIpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICB0aGlzLnJ1bk9wdGlvbnMuYWNsID0gWycqJ107XG5cbiAgaWYgKHRoaXMuYXV0aC51c2VyKSB7XG4gICAgcmV0dXJuIHRoaXMuYXV0aC5nZXRVc2VyUm9sZXMoKS50aGVuKHJvbGVzID0+IHtcbiAgICAgIHRoaXMucnVuT3B0aW9ucy5hY2wgPSB0aGlzLnJ1bk9wdGlvbnMuYWNsLmNvbmNhdChyb2xlcywgW3RoaXMuYXV0aC51c2VyLmlkXSk7XG4gICAgICByZXR1cm47XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG59O1xuXG4vLyBWYWxpZGF0ZXMgdGhpcyBvcGVyYXRpb24gYWdhaW5zdCB0aGUgYWxsb3dDbGllbnRDbGFzc0NyZWF0aW9uIGNvbmZpZy5cblJlc3RXcml0ZS5wcm90b3R5cGUudmFsaWRhdGVDbGllbnRDbGFzc0NyZWF0aW9uID0gZnVuY3Rpb24gKCkge1xuICBpZiAoXG4gICAgdGhpcy5jb25maWcuYWxsb3dDbGllbnRDbGFzc0NyZWF0aW9uID09PSBmYWxzZSAmJlxuICAgICF0aGlzLmF1dGguaXNNYXN0ZXIgJiZcbiAgICBTY2hlbWFDb250cm9sbGVyLnN5c3RlbUNsYXNzZXMuaW5kZXhPZih0aGlzLmNsYXNzTmFtZSkgPT09IC0xXG4gICkge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgICAgLmxvYWRTY2hlbWEoKVxuICAgICAgLnRoZW4oc2NoZW1hQ29udHJvbGxlciA9PiBzY2hlbWFDb250cm9sbGVyLmhhc0NsYXNzKHRoaXMuY2xhc3NOYW1lKSlcbiAgICAgIC50aGVuKGhhc0NsYXNzID0+IHtcbiAgICAgICAgaWYgKGhhc0NsYXNzICE9PSB0cnVlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgICAgICAgICdUaGlzIHVzZXIgaXMgbm90IGFsbG93ZWQgdG8gYWNjZXNzICcgKyAnbm9uLWV4aXN0ZW50IGNsYXNzOiAnICsgdGhpcy5jbGFzc05hbWVcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbn07XG5cbi8vIFZhbGlkYXRlcyB0aGlzIG9wZXJhdGlvbiBhZ2FpbnN0IHRoZSBzY2hlbWEuXG5SZXN0V3JpdGUucHJvdG90eXBlLnZhbGlkYXRlU2NoZW1hID0gZnVuY3Rpb24gKCkge1xuICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UudmFsaWRhdGVPYmplY3QoXG4gICAgdGhpcy5jbGFzc05hbWUsXG4gICAgdGhpcy5kYXRhLFxuICAgIHRoaXMucXVlcnksXG4gICAgdGhpcy5ydW5PcHRpb25zXG4gICk7XG59O1xuXG4vLyBSdW5zIGFueSBiZWZvcmVTYXZlIHRyaWdnZXJzIGFnYWluc3QgdGhpcyBvcGVyYXRpb24uXG4vLyBBbnkgY2hhbmdlIGxlYWRzIHRvIG91ciBkYXRhIGJlaW5nIG11dGF0ZWQuXG5SZXN0V3JpdGUucHJvdG90eXBlLnJ1bkJlZm9yZVNhdmVUcmlnZ2VyID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5yZXNwb25zZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEF2b2lkIGRvaW5nIGFueSBzZXR1cCBmb3IgdHJpZ2dlcnMgaWYgdGhlcmUgaXMgbm8gJ2JlZm9yZVNhdmUnIHRyaWdnZXIgZm9yIHRoaXMgY2xhc3MuXG4gIGlmIChcbiAgICAhdHJpZ2dlcnMudHJpZ2dlckV4aXN0cyh0aGlzLmNsYXNzTmFtZSwgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlU2F2ZSwgdGhpcy5jb25maWcuYXBwbGljYXRpb25JZClcbiAgKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgLy8gQ2xvdWQgY29kZSBnZXRzIGEgYml0IG9mIGV4dHJhIGRhdGEgZm9yIGl0cyBvYmplY3RzXG4gIHZhciBleHRyYURhdGEgPSB7IGNsYXNzTmFtZTogdGhpcy5jbGFzc05hbWUgfTtcbiAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgIGV4dHJhRGF0YS5vYmplY3RJZCA9IHRoaXMucXVlcnkub2JqZWN0SWQ7XG4gIH1cblxuICBsZXQgb3JpZ2luYWxPYmplY3QgPSBudWxsO1xuICBjb25zdCB1cGRhdGVkT2JqZWN0ID0gdGhpcy5idWlsZFVwZGF0ZWRPYmplY3QoZXh0cmFEYXRhKTtcbiAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgIC8vIFRoaXMgaXMgYW4gdXBkYXRlIGZvciBleGlzdGluZyBvYmplY3QuXG4gICAgb3JpZ2luYWxPYmplY3QgPSB0cmlnZ2Vycy5pbmZsYXRlKGV4dHJhRGF0YSwgdGhpcy5vcmlnaW5hbERhdGEpO1xuICB9XG5cbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgLy8gQmVmb3JlIGNhbGxpbmcgdGhlIHRyaWdnZXIsIHZhbGlkYXRlIHRoZSBwZXJtaXNzaW9ucyBmb3IgdGhlIHNhdmUgb3BlcmF0aW9uXG4gICAgICBsZXQgZGF0YWJhc2VQcm9taXNlID0gbnVsbDtcbiAgICAgIGlmICh0aGlzLnF1ZXJ5KSB7XG4gICAgICAgIC8vIFZhbGlkYXRlIGZvciB1cGRhdGluZ1xuICAgICAgICBkYXRhYmFzZVByb21pc2UgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS51cGRhdGUoXG4gICAgICAgICAgdGhpcy5jbGFzc05hbWUsXG4gICAgICAgICAgdGhpcy5xdWVyeSxcbiAgICAgICAgICB0aGlzLmRhdGEsXG4gICAgICAgICAgdGhpcy5ydW5PcHRpb25zLFxuICAgICAgICAgIHRydWUsXG4gICAgICAgICAgdHJ1ZVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVmFsaWRhdGUgZm9yIGNyZWF0aW5nXG4gICAgICAgIGRhdGFiYXNlUHJvbWlzZSA9IHRoaXMuY29uZmlnLmRhdGFiYXNlLmNyZWF0ZShcbiAgICAgICAgICB0aGlzLmNsYXNzTmFtZSxcbiAgICAgICAgICB0aGlzLmRhdGEsXG4gICAgICAgICAgdGhpcy5ydW5PcHRpb25zLFxuICAgICAgICAgIHRydWVcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIC8vIEluIHRoZSBjYXNlIHRoYXQgdGhlcmUgaXMgbm8gcGVybWlzc2lvbiBmb3IgdGhlIG9wZXJhdGlvbiwgaXQgdGhyb3dzIGFuIGVycm9yXG4gICAgICByZXR1cm4gZGF0YWJhc2VQcm9taXNlLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKCFyZXN1bHQgfHwgcmVzdWx0Lmxlbmd0aCA8PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kLicpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB0cmlnZ2Vycy5tYXliZVJ1blRyaWdnZXIoXG4gICAgICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZVNhdmUsXG4gICAgICAgIHRoaXMuYXV0aCxcbiAgICAgICAgdXBkYXRlZE9iamVjdCxcbiAgICAgICAgb3JpZ2luYWxPYmplY3QsXG4gICAgICAgIHRoaXMuY29uZmlnLFxuICAgICAgICB0aGlzLmNvbnRleHRcbiAgICAgICk7XG4gICAgfSlcbiAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICBpZiAocmVzcG9uc2UgJiYgcmVzcG9uc2Uub2JqZWN0KSB7XG4gICAgICAgIHRoaXMuc3RvcmFnZS5maWVsZHNDaGFuZ2VkQnlUcmlnZ2VyID0gXy5yZWR1Y2UoXG4gICAgICAgICAgcmVzcG9uc2Uub2JqZWN0LFxuICAgICAgICAgIChyZXN1bHQsIHZhbHVlLCBrZXkpID0+IHtcbiAgICAgICAgICAgIGlmICghXy5pc0VxdWFsKHRoaXMuZGF0YVtrZXldLCB2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgcmVzdWx0LnB1c2goa2V5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBbXVxuICAgICAgICApO1xuICAgICAgICB0aGlzLmRhdGEgPSByZXNwb25zZS5vYmplY3Q7XG4gICAgICAgIC8vIFdlIHNob3VsZCBkZWxldGUgdGhlIG9iamVjdElkIGZvciBhbiB1cGRhdGUgd3JpdGVcbiAgICAgICAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgICAgICAgIGRlbGV0ZSB0aGlzLmRhdGEub2JqZWN0SWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUucnVuQmVmb3JlTG9naW5UcmlnZ2VyID0gYXN5bmMgZnVuY3Rpb24gKHVzZXJEYXRhKSB7XG4gIC8vIEF2b2lkIGRvaW5nIGFueSBzZXR1cCBmb3IgdHJpZ2dlcnMgaWYgdGhlcmUgaXMgbm8gJ2JlZm9yZUxvZ2luJyB0cmlnZ2VyXG4gIGlmIChcbiAgICAhdHJpZ2dlcnMudHJpZ2dlckV4aXN0cyh0aGlzLmNsYXNzTmFtZSwgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlTG9naW4sIHRoaXMuY29uZmlnLmFwcGxpY2F0aW9uSWQpXG4gICkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIENsb3VkIGNvZGUgZ2V0cyBhIGJpdCBvZiBleHRyYSBkYXRhIGZvciBpdHMgb2JqZWN0c1xuICBjb25zdCBleHRyYURhdGEgPSB7IGNsYXNzTmFtZTogdGhpcy5jbGFzc05hbWUgfTtcblxuICAvLyBFeHBhbmQgZmlsZSBvYmplY3RzXG4gIHRoaXMuY29uZmlnLmZpbGVzQ29udHJvbGxlci5leHBhbmRGaWxlc0luT2JqZWN0KHRoaXMuY29uZmlnLCB1c2VyRGF0YSk7XG5cbiAgY29uc3QgdXNlciA9IHRyaWdnZXJzLmluZmxhdGUoZXh0cmFEYXRhLCB1c2VyRGF0YSk7XG5cbiAgLy8gbm8gbmVlZCB0byByZXR1cm4gYSByZXNwb25zZVxuICBhd2FpdCB0cmlnZ2Vycy5tYXliZVJ1blRyaWdnZXIoXG4gICAgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlTG9naW4sXG4gICAgdGhpcy5hdXRoLFxuICAgIHVzZXIsXG4gICAgbnVsbCxcbiAgICB0aGlzLmNvbmZpZyxcbiAgICB0aGlzLmNvbnRleHRcbiAgKTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuc2V0UmVxdWlyZWRGaWVsZHNJZk5lZWRlZCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMuZGF0YSkge1xuICAgIHJldHVybiB0aGlzLnZhbGlkU2NoZW1hQ29udHJvbGxlci5nZXRBbGxDbGFzc2VzKCkudGhlbihhbGxDbGFzc2VzID0+IHtcbiAgICAgIGNvbnN0IHNjaGVtYSA9IGFsbENsYXNzZXMuZmluZChvbmVDbGFzcyA9PiBvbmVDbGFzcy5jbGFzc05hbWUgPT09IHRoaXMuY2xhc3NOYW1lKTtcbiAgICAgIGNvbnN0IHNldFJlcXVpcmVkRmllbGRJZk5lZWRlZCA9IChmaWVsZE5hbWUsIHNldERlZmF1bHQpID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRoaXMuZGF0YVtmaWVsZE5hbWVdID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgICB0aGlzLmRhdGFbZmllbGROYW1lXSA9PT0gbnVsbCB8fFxuICAgICAgICAgIHRoaXMuZGF0YVtmaWVsZE5hbWVdID09PSAnJyB8fFxuICAgICAgICAgICh0eXBlb2YgdGhpcy5kYXRhW2ZpZWxkTmFtZV0gPT09ICdvYmplY3QnICYmIHRoaXMuZGF0YVtmaWVsZE5hbWVdLl9fb3AgPT09ICdEZWxldGUnKVxuICAgICAgICApIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBzZXREZWZhdWx0ICYmXG4gICAgICAgICAgICBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiZcbiAgICAgICAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS5kZWZhdWx0VmFsdWUgIT09IG51bGwgJiZcbiAgICAgICAgICAgIHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS5kZWZhdWx0VmFsdWUgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgKHRoaXMuZGF0YVtmaWVsZE5hbWVdID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgICAgICAgKHR5cGVvZiB0aGlzLmRhdGFbZmllbGROYW1lXSA9PT0gJ29iamVjdCcgJiYgdGhpcy5kYXRhW2ZpZWxkTmFtZV0uX19vcCA9PT0gJ0RlbGV0ZScpKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy5kYXRhW2ZpZWxkTmFtZV0gPSBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0uZGVmYXVsdFZhbHVlO1xuICAgICAgICAgICAgdGhpcy5zdG9yYWdlLmZpZWxkc0NoYW5nZWRCeVRyaWdnZXIgPSB0aGlzLnN0b3JhZ2UuZmllbGRzQ2hhbmdlZEJ5VHJpZ2dlciB8fCBbXTtcbiAgICAgICAgICAgIGlmICh0aGlzLnN0b3JhZ2UuZmllbGRzQ2hhbmdlZEJ5VHJpZ2dlci5pbmRleE9mKGZpZWxkTmFtZSkgPCAwKSB7XG4gICAgICAgICAgICAgIHRoaXMuc3RvcmFnZS5maWVsZHNDaGFuZ2VkQnlUcmlnZ2VyLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0ucmVxdWlyZWQgPT09IHRydWUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5WQUxJREFUSU9OX0VSUk9SLCBgJHtmaWVsZE5hbWV9IGlzIHJlcXVpcmVkYCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICAvLyBBZGQgZGVmYXVsdCBmaWVsZHNcbiAgICAgIHRoaXMuZGF0YS51cGRhdGVkQXQgPSB0aGlzLnVwZGF0ZWRBdDtcbiAgICAgIGlmICghdGhpcy5xdWVyeSkge1xuICAgICAgICB0aGlzLmRhdGEuY3JlYXRlZEF0ID0gdGhpcy51cGRhdGVkQXQ7XG5cbiAgICAgICAgLy8gT25seSBhc3NpZ24gbmV3IG9iamVjdElkIGlmIHdlIGFyZSBjcmVhdGluZyBuZXcgb2JqZWN0XG4gICAgICAgIGlmICghdGhpcy5kYXRhLm9iamVjdElkKSB7XG4gICAgICAgICAgdGhpcy5kYXRhLm9iamVjdElkID0gY3J5cHRvVXRpbHMubmV3T2JqZWN0SWQodGhpcy5jb25maWcub2JqZWN0SWRTaXplKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2NoZW1hKSB7XG4gICAgICAgICAgT2JqZWN0LmtleXMoc2NoZW1hLmZpZWxkcykuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgICAgICAgc2V0UmVxdWlyZWRGaWVsZElmTmVlZGVkKGZpZWxkTmFtZSwgdHJ1ZSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoc2NoZW1hKSB7XG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMuZGF0YSkuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgICAgICAgIHNldFJlcXVpcmVkRmllbGRJZk5lZWRlZChmaWVsZE5hbWUsIGZhbHNlKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufTtcblxuLy8gVHJhbnNmb3JtcyBhdXRoIGRhdGEgZm9yIGEgdXNlciBvYmplY3QuXG4vLyBEb2VzIG5vdGhpbmcgaWYgdGhpcyBpc24ndCBhIHVzZXIgb2JqZWN0LlxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIHdoZW4gd2UncmUgZG9uZSBpZiBpdCBjYW4ndCBmaW5pc2ggdGhpcyB0aWNrLlxuUmVzdFdyaXRlLnByb3RvdHlwZS52YWxpZGF0ZUF1dGhEYXRhID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jbGFzc05hbWUgIT09ICdfVXNlcicpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoIXRoaXMucXVlcnkgJiYgIXRoaXMuZGF0YS5hdXRoRGF0YSkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5kYXRhLnVzZXJuYW1lICE9PSAnc3RyaW5nJyB8fCBfLmlzRW1wdHkodGhpcy5kYXRhLnVzZXJuYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlVTRVJOQU1FX01JU1NJTkcsICdiYWQgb3IgbWlzc2luZyB1c2VybmFtZScpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHRoaXMuZGF0YS5wYXNzd29yZCAhPT0gJ3N0cmluZycgfHwgXy5pc0VtcHR5KHRoaXMuZGF0YS5wYXNzd29yZCkpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5QQVNTV09SRF9NSVNTSU5HLCAncGFzc3dvcmQgaXMgcmVxdWlyZWQnKTtcbiAgICB9XG4gIH1cblxuICBpZiAoXG4gICAgKHRoaXMuZGF0YS5hdXRoRGF0YSAmJiAhT2JqZWN0LmtleXModGhpcy5kYXRhLmF1dGhEYXRhKS5sZW5ndGgpIHx8XG4gICAgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0aGlzLmRhdGEsICdhdXRoRGF0YScpXG4gICkge1xuICAgIC8vIEhhbmRsZSBzYXZpbmcgYXV0aERhdGEgdG8ge30gb3IgaWYgYXV0aERhdGEgZG9lc24ndCBleGlzdFxuICAgIHJldHVybjtcbiAgfSBlbHNlIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5kYXRhLCAnYXV0aERhdGEnKSAmJiAhdGhpcy5kYXRhLmF1dGhEYXRhKSB7XG4gICAgLy8gSGFuZGxlIHNhdmluZyBhdXRoRGF0YSB0byBudWxsXG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuVU5TVVBQT1JURURfU0VSVklDRSxcbiAgICAgICdUaGlzIGF1dGhlbnRpY2F0aW9uIG1ldGhvZCBpcyB1bnN1cHBvcnRlZC4nXG4gICAgKTtcbiAgfVxuXG4gIHZhciBhdXRoRGF0YSA9IHRoaXMuZGF0YS5hdXRoRGF0YTtcbiAgdmFyIHByb3ZpZGVycyA9IE9iamVjdC5rZXlzKGF1dGhEYXRhKTtcbiAgaWYgKHByb3ZpZGVycy5sZW5ndGggPiAwKSB7XG4gICAgY29uc3QgY2FuSGFuZGxlQXV0aERhdGEgPSBwcm92aWRlcnMucmVkdWNlKChjYW5IYW5kbGUsIHByb3ZpZGVyKSA9PiB7XG4gICAgICB2YXIgcHJvdmlkZXJBdXRoRGF0YSA9IGF1dGhEYXRhW3Byb3ZpZGVyXTtcbiAgICAgIHZhciBoYXNUb2tlbiA9IHByb3ZpZGVyQXV0aERhdGEgJiYgcHJvdmlkZXJBdXRoRGF0YS5pZDtcbiAgICAgIHJldHVybiBjYW5IYW5kbGUgJiYgKGhhc1Rva2VuIHx8IHByb3ZpZGVyQXV0aERhdGEgPT0gbnVsbCk7XG4gICAgfSwgdHJ1ZSk7XG4gICAgaWYgKGNhbkhhbmRsZUF1dGhEYXRhKSB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVBdXRoRGF0YShhdXRoRGF0YSk7XG4gICAgfVxuICB9XG4gIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICBQYXJzZS5FcnJvci5VTlNVUFBPUlRFRF9TRVJWSUNFLFxuICAgICdUaGlzIGF1dGhlbnRpY2F0aW9uIG1ldGhvZCBpcyB1bnN1cHBvcnRlZC4nXG4gICk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLmhhbmRsZUF1dGhEYXRhVmFsaWRhdGlvbiA9IGZ1bmN0aW9uIChhdXRoRGF0YSkge1xuICBjb25zdCB2YWxpZGF0aW9ucyA9IE9iamVjdC5rZXlzKGF1dGhEYXRhKS5tYXAocHJvdmlkZXIgPT4ge1xuICAgIGlmIChhdXRoRGF0YVtwcm92aWRlcl0gPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgY29uc3QgdmFsaWRhdGVBdXRoRGF0YSA9IHRoaXMuY29uZmlnLmF1dGhEYXRhTWFuYWdlci5nZXRWYWxpZGF0b3JGb3JQcm92aWRlcihwcm92aWRlcik7XG4gICAgaWYgKCF2YWxpZGF0ZUF1dGhEYXRhKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlVOU1VQUE9SVEVEX1NFUlZJQ0UsXG4gICAgICAgICdUaGlzIGF1dGhlbnRpY2F0aW9uIG1ldGhvZCBpcyB1bnN1cHBvcnRlZC4nXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdmFsaWRhdGVBdXRoRGF0YShhdXRoRGF0YVtwcm92aWRlcl0pO1xuICB9KTtcbiAgcmV0dXJuIFByb21pc2UuYWxsKHZhbGlkYXRpb25zKTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuZmluZFVzZXJzV2l0aEF1dGhEYXRhID0gZnVuY3Rpb24gKGF1dGhEYXRhKSB7XG4gIGNvbnN0IHByb3ZpZGVycyA9IE9iamVjdC5rZXlzKGF1dGhEYXRhKTtcbiAgY29uc3QgcXVlcnkgPSBwcm92aWRlcnNcbiAgICAucmVkdWNlKChtZW1vLCBwcm92aWRlcikgPT4ge1xuICAgICAgaWYgKCFhdXRoRGF0YVtwcm92aWRlcl0pIHtcbiAgICAgICAgcmV0dXJuIG1lbW87XG4gICAgICB9XG4gICAgICBjb25zdCBxdWVyeUtleSA9IGBhdXRoRGF0YS4ke3Byb3ZpZGVyfS5pZGA7XG4gICAgICBjb25zdCBxdWVyeSA9IHt9O1xuICAgICAgcXVlcnlbcXVlcnlLZXldID0gYXV0aERhdGFbcHJvdmlkZXJdLmlkO1xuICAgICAgbWVtby5wdXNoKHF1ZXJ5KTtcbiAgICAgIHJldHVybiBtZW1vO1xuICAgIH0sIFtdKVxuICAgIC5maWx0ZXIocSA9PiB7XG4gICAgICByZXR1cm4gdHlwZW9mIHEgIT09ICd1bmRlZmluZWQnO1xuICAgIH0pO1xuXG4gIGxldCBmaW5kUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZShbXSk7XG4gIGlmIChxdWVyeS5sZW5ndGggPiAwKSB7XG4gICAgZmluZFByb21pc2UgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZS5maW5kKHRoaXMuY2xhc3NOYW1lLCB7ICRvcjogcXVlcnkgfSwge30pO1xuICB9XG5cbiAgcmV0dXJuIGZpbmRQcm9taXNlO1xufTtcblxuUmVzdFdyaXRlLnByb3RvdHlwZS5maWx0ZXJlZE9iamVjdHNCeUFDTCA9IGZ1bmN0aW9uIChvYmplY3RzKSB7XG4gIGlmICh0aGlzLmF1dGguaXNNYXN0ZXIpIHtcbiAgICByZXR1cm4gb2JqZWN0cztcbiAgfVxuICByZXR1cm4gb2JqZWN0cy5maWx0ZXIob2JqZWN0ID0+IHtcbiAgICBpZiAoIW9iamVjdC5BQ0wpIHtcbiAgICAgIHJldHVybiB0cnVlOyAvLyBsZWdhY3kgdXNlcnMgdGhhdCBoYXZlIG5vIEFDTCBmaWVsZCBvbiB0aGVtXG4gICAgfVxuICAgIC8vIFJlZ3VsYXIgdXNlcnMgdGhhdCBoYXZlIGJlZW4gbG9ja2VkIG91dC5cbiAgICByZXR1cm4gb2JqZWN0LkFDTCAmJiBPYmplY3Qua2V5cyhvYmplY3QuQUNMKS5sZW5ndGggPiAwO1xuICB9KTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuaGFuZGxlQXV0aERhdGEgPSBmdW5jdGlvbiAoYXV0aERhdGEpIHtcbiAgbGV0IHJlc3VsdHM7XG4gIHJldHVybiB0aGlzLmZpbmRVc2Vyc1dpdGhBdXRoRGF0YShhdXRoRGF0YSkudGhlbihhc3luYyByID0+IHtcbiAgICByZXN1bHRzID0gdGhpcy5maWx0ZXJlZE9iamVjdHNCeUFDTChyKTtcblxuICAgIGlmIChyZXN1bHRzLmxlbmd0aCA9PSAxKSB7XG4gICAgICB0aGlzLnN0b3JhZ2VbJ2F1dGhQcm92aWRlciddID0gT2JqZWN0LmtleXMoYXV0aERhdGEpLmpvaW4oJywnKTtcblxuICAgICAgY29uc3QgdXNlclJlc3VsdCA9IHJlc3VsdHNbMF07XG4gICAgICBjb25zdCBtdXRhdGVkQXV0aERhdGEgPSB7fTtcbiAgICAgIE9iamVjdC5rZXlzKGF1dGhEYXRhKS5mb3JFYWNoKHByb3ZpZGVyID0+IHtcbiAgICAgICAgY29uc3QgcHJvdmlkZXJEYXRhID0gYXV0aERhdGFbcHJvdmlkZXJdO1xuICAgICAgICBjb25zdCB1c2VyQXV0aERhdGEgPSB1c2VyUmVzdWx0LmF1dGhEYXRhW3Byb3ZpZGVyXTtcbiAgICAgICAgaWYgKCFfLmlzRXF1YWwocHJvdmlkZXJEYXRhLCB1c2VyQXV0aERhdGEpKSB7XG4gICAgICAgICAgbXV0YXRlZEF1dGhEYXRhW3Byb3ZpZGVyXSA9IHByb3ZpZGVyRGF0YTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBjb25zdCBoYXNNdXRhdGVkQXV0aERhdGEgPSBPYmplY3Qua2V5cyhtdXRhdGVkQXV0aERhdGEpLmxlbmd0aCAhPT0gMDtcbiAgICAgIGxldCB1c2VySWQ7XG4gICAgICBpZiAodGhpcy5xdWVyeSAmJiB0aGlzLnF1ZXJ5Lm9iamVjdElkKSB7XG4gICAgICAgIHVzZXJJZCA9IHRoaXMucXVlcnkub2JqZWN0SWQ7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuYXV0aCAmJiB0aGlzLmF1dGgudXNlciAmJiB0aGlzLmF1dGgudXNlci5pZCkge1xuICAgICAgICB1c2VySWQgPSB0aGlzLmF1dGgudXNlci5pZDtcbiAgICAgIH1cbiAgICAgIGlmICghdXNlcklkIHx8IHVzZXJJZCA9PT0gdXNlclJlc3VsdC5vYmplY3RJZCkge1xuICAgICAgICAvLyBubyB1c2VyIG1ha2luZyB0aGUgY2FsbFxuICAgICAgICAvLyBPUiB0aGUgdXNlciBtYWtpbmcgdGhlIGNhbGwgaXMgdGhlIHJpZ2h0IG9uZVxuICAgICAgICAvLyBMb2dpbiB3aXRoIGF1dGggZGF0YVxuICAgICAgICBkZWxldGUgcmVzdWx0c1swXS5wYXNzd29yZDtcblxuICAgICAgICAvLyBuZWVkIHRvIHNldCB0aGUgb2JqZWN0SWQgZmlyc3Qgb3RoZXJ3aXNlIGxvY2F0aW9uIGhhcyB0cmFpbGluZyB1bmRlZmluZWRcbiAgICAgICAgdGhpcy5kYXRhLm9iamVjdElkID0gdXNlclJlc3VsdC5vYmplY3RJZDtcblxuICAgICAgICBpZiAoIXRoaXMucXVlcnkgfHwgIXRoaXMucXVlcnkub2JqZWN0SWQpIHtcbiAgICAgICAgICAvLyB0aGlzIGEgbG9naW4gY2FsbCwgbm8gdXNlcklkIHBhc3NlZFxuICAgICAgICAgIHRoaXMucmVzcG9uc2UgPSB7XG4gICAgICAgICAgICByZXNwb25zZTogdXNlclJlc3VsdCxcbiAgICAgICAgICAgIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKCksXG4gICAgICAgICAgfTtcbiAgICAgICAgICAvLyBSdW4gYmVmb3JlTG9naW4gaG9vayBiZWZvcmUgc3RvcmluZyBhbnkgdXBkYXRlc1xuICAgICAgICAgIC8vIHRvIGF1dGhEYXRhIG9uIHRoZSBkYjsgY2hhbmdlcyB0byB1c2VyUmVzdWx0XG4gICAgICAgICAgLy8gd2lsbCBiZSBpZ25vcmVkLlxuICAgICAgICAgIGF3YWl0IHRoaXMucnVuQmVmb3JlTG9naW5UcmlnZ2VyKGRlZXBjb3B5KHVzZXJSZXN1bHQpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIHdlIGRpZG4ndCBjaGFuZ2UgdGhlIGF1dGggZGF0YSwganVzdCBrZWVwIGdvaW5nXG4gICAgICAgIGlmICghaGFzTXV0YXRlZEF1dGhEYXRhKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIFdlIGhhdmUgYXV0aERhdGEgdGhhdCBpcyB1cGRhdGVkIG9uIGxvZ2luXG4gICAgICAgIC8vIHRoYXQgY2FuIGhhcHBlbiB3aGVuIHRva2VuIGFyZSByZWZyZXNoZWQsXG4gICAgICAgIC8vIFdlIHNob3VsZCB1cGRhdGUgdGhlIHRva2VuIGFuZCBsZXQgdGhlIHVzZXIgaW5cbiAgICAgICAgLy8gV2Ugc2hvdWxkIG9ubHkgY2hlY2sgdGhlIG11dGF0ZWQga2V5c1xuICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVBdXRoRGF0YVZhbGlkYXRpb24obXV0YXRlZEF1dGhEYXRhKS50aGVuKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAvLyBJRiB3ZSBoYXZlIGEgcmVzcG9uc2UsIHdlJ2xsIHNraXAgdGhlIGRhdGFiYXNlIG9wZXJhdGlvbiAvIGJlZm9yZVNhdmUgLyBhZnRlclNhdmUgZXRjLi4uXG4gICAgICAgICAgLy8gd2UgbmVlZCB0byBzZXQgaXQgdXAgdGhlcmUuXG4gICAgICAgICAgLy8gV2UgYXJlIHN1cHBvc2VkIHRvIGhhdmUgYSByZXNwb25zZSBvbmx5IG9uIExPR0lOIHdpdGggYXV0aERhdGEsIHNvIHdlIHNraXAgdGhvc2VcbiAgICAgICAgICAvLyBJZiB3ZSdyZSBub3QgbG9nZ2luZyBpbiwgYnV0IGp1c3QgdXBkYXRpbmcgdGhlIGN1cnJlbnQgdXNlciwgd2UgY2FuIHNhZmVseSBza2lwIHRoYXQgcGFydFxuICAgICAgICAgIGlmICh0aGlzLnJlc3BvbnNlKSB7XG4gICAgICAgICAgICAvLyBBc3NpZ24gdGhlIG5ldyBhdXRoRGF0YSBpbiB0aGUgcmVzcG9uc2VcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKG11dGF0ZWRBdXRoRGF0YSkuZm9yRWFjaChwcm92aWRlciA9PiB7XG4gICAgICAgICAgICAgIHRoaXMucmVzcG9uc2UucmVzcG9uc2UuYXV0aERhdGFbcHJvdmlkZXJdID0gbXV0YXRlZEF1dGhEYXRhW3Byb3ZpZGVyXTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBSdW4gdGhlIERCIHVwZGF0ZSBkaXJlY3RseSwgYXMgJ21hc3RlcidcbiAgICAgICAgICAgIC8vIEp1c3QgdXBkYXRlIHRoZSBhdXRoRGF0YSBwYXJ0XG4gICAgICAgICAgICAvLyBUaGVuIHdlJ3JlIGdvb2QgZm9yIHRoZSB1c2VyLCBlYXJseSBleGl0IG9mIHNvcnRzXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UudXBkYXRlKFxuICAgICAgICAgICAgICB0aGlzLmNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgeyBvYmplY3RJZDogdGhpcy5kYXRhLm9iamVjdElkIH0sXG4gICAgICAgICAgICAgIHsgYXV0aERhdGE6IG11dGF0ZWRBdXRoRGF0YSB9LFxuICAgICAgICAgICAgICB7fVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIGlmICh1c2VySWQpIHtcbiAgICAgICAgLy8gVHJ5aW5nIHRvIHVwZGF0ZSBhdXRoIGRhdGEgYnV0IHVzZXJzXG4gICAgICAgIC8vIGFyZSBkaWZmZXJlbnRcbiAgICAgICAgaWYgKHVzZXJSZXN1bHQub2JqZWN0SWQgIT09IHVzZXJJZCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5BQ0NPVU5UX0FMUkVBRFlfTElOS0VELCAndGhpcyBhdXRoIGlzIGFscmVhZHkgdXNlZCcpO1xuICAgICAgICB9XG4gICAgICAgIC8vIE5vIGF1dGggZGF0YSB3YXMgbXV0YXRlZCwganVzdCBrZWVwIGdvaW5nXG4gICAgICAgIGlmICghaGFzTXV0YXRlZEF1dGhEYXRhKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmhhbmRsZUF1dGhEYXRhVmFsaWRhdGlvbihhdXRoRGF0YSkudGhlbigoKSA9PiB7XG4gICAgICBpZiAocmVzdWx0cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIC8vIE1vcmUgdGhhbiAxIHVzZXIgd2l0aCB0aGUgcGFzc2VkIGlkJ3NcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkFDQ09VTlRfQUxSRUFEWV9MSU5LRUQsICd0aGlzIGF1dGggaXMgYWxyZWFkeSB1c2VkJyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufTtcblxuLy8gVGhlIG5vbi10aGlyZC1wYXJ0eSBwYXJ0cyBvZiBVc2VyIHRyYW5zZm9ybWF0aW9uXG5SZXN0V3JpdGUucHJvdG90eXBlLnRyYW5zZm9ybVVzZXIgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBwcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG5cbiAgaWYgKHRoaXMuY2xhc3NOYW1lICE9PSAnX1VzZXInKSB7XG4gICAgcmV0dXJuIHByb21pc2U7XG4gIH1cblxuICBpZiAoIXRoaXMuYXV0aC5pc01hc3RlciAmJiAnZW1haWxWZXJpZmllZCcgaW4gdGhpcy5kYXRhKSB7XG4gICAgY29uc3QgZXJyb3IgPSBgQ2xpZW50cyBhcmVuJ3QgYWxsb3dlZCB0byBtYW51YWxseSB1cGRhdGUgZW1haWwgdmVyaWZpY2F0aW9uLmA7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sIGVycm9yKTtcbiAgfVxuXG4gIC8vIERvIG5vdCBjbGVhbnVwIHNlc3Npb24gaWYgb2JqZWN0SWQgaXMgbm90IHNldFxuICBpZiAodGhpcy5xdWVyeSAmJiB0aGlzLm9iamVjdElkKCkpIHtcbiAgICAvLyBJZiB3ZSdyZSB1cGRhdGluZyBhIF9Vc2VyIG9iamVjdCwgd2UgbmVlZCB0byBjbGVhciBvdXQgdGhlIGNhY2hlIGZvciB0aGF0IHVzZXIuIEZpbmQgYWxsIHRoZWlyXG4gICAgLy8gc2Vzc2lvbiB0b2tlbnMsIGFuZCByZW1vdmUgdGhlbSBmcm9tIHRoZSBjYWNoZS5cbiAgICBwcm9taXNlID0gbmV3IFJlc3RRdWVyeSh0aGlzLmNvbmZpZywgQXV0aC5tYXN0ZXIodGhpcy5jb25maWcpLCAnX1Nlc3Npb24nLCB7XG4gICAgICB1c2VyOiB7XG4gICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICBjbGFzc05hbWU6ICdfVXNlcicsXG4gICAgICAgIG9iamVjdElkOiB0aGlzLm9iamVjdElkKCksXG4gICAgICB9LFxuICAgIH0pXG4gICAgICAuZXhlY3V0ZSgpXG4gICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgcmVzdWx0cy5yZXN1bHRzLmZvckVhY2goc2Vzc2lvbiA9PlxuICAgICAgICAgIHRoaXMuY29uZmlnLmNhY2hlQ29udHJvbGxlci51c2VyLmRlbChzZXNzaW9uLnNlc3Npb25Ub2tlbilcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHByb21pc2VcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICAvLyBUcmFuc2Zvcm0gdGhlIHBhc3N3b3JkXG4gICAgICBpZiAodGhpcy5kYXRhLnBhc3N3b3JkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gaWdub3JlIG9ubHkgaWYgdW5kZWZpbmVkLiBzaG91bGQgcHJvY2VlZCBpZiBlbXB0eSAoJycpXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMucXVlcnkpIHtcbiAgICAgICAgdGhpcy5zdG9yYWdlWydjbGVhclNlc3Npb25zJ10gPSB0cnVlO1xuICAgICAgICAvLyBHZW5lcmF0ZSBhIG5ldyBzZXNzaW9uIG9ubHkgaWYgdGhlIHVzZXIgcmVxdWVzdGVkXG4gICAgICAgIGlmICghdGhpcy5hdXRoLmlzTWFzdGVyKSB7XG4gICAgICAgICAgdGhpcy5zdG9yYWdlWydnZW5lcmF0ZU5ld1Nlc3Npb24nXSA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlUGFzc3dvcmRQb2xpY3koKS50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHBhc3N3b3JkQ3J5cHRvLmhhc2godGhpcy5kYXRhLnBhc3N3b3JkKS50aGVuKGhhc2hlZFBhc3N3b3JkID0+IHtcbiAgICAgICAgICB0aGlzLmRhdGEuX2hhc2hlZF9wYXNzd29yZCA9IGhhc2hlZFBhc3N3b3JkO1xuICAgICAgICAgIGRlbGV0ZSB0aGlzLmRhdGEucGFzc3dvcmQ7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5fdmFsaWRhdGVVc2VyTmFtZSgpO1xuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlRW1haWwoKTtcbiAgICB9KTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuX3ZhbGlkYXRlVXNlck5hbWUgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIENoZWNrIGZvciB1c2VybmFtZSB1bmlxdWVuZXNzXG4gIGlmICghdGhpcy5kYXRhLnVzZXJuYW1lKSB7XG4gICAgaWYgKCF0aGlzLnF1ZXJ5KSB7XG4gICAgICB0aGlzLmRhdGEudXNlcm5hbWUgPSBjcnlwdG9VdGlscy5yYW5kb21TdHJpbmcoMjUpO1xuICAgICAgdGhpcy5yZXNwb25zZVNob3VsZEhhdmVVc2VybmFtZSA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuICAvKlxuICAgIFVzZXJuYW1lcyBzaG91bGQgYmUgdW5pcXVlIHdoZW4gY29tcGFyZWQgY2FzZSBpbnNlbnNpdGl2ZWx5XG5cbiAgICBVc2VycyBzaG91bGQgYmUgYWJsZSB0byBtYWtlIGNhc2Ugc2Vuc2l0aXZlIHVzZXJuYW1lcyBhbmRcbiAgICBsb2dpbiB1c2luZyB0aGUgY2FzZSB0aGV5IGVudGVyZWQuICBJLmUuICdTbm9vcHknIHNob3VsZCBwcmVjbHVkZVxuICAgICdzbm9vcHknIGFzIGEgdmFsaWQgdXNlcm5hbWUuXG4gICovXG4gIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgIC5maW5kKFxuICAgICAgdGhpcy5jbGFzc05hbWUsXG4gICAgICB7XG4gICAgICAgIHVzZXJuYW1lOiB0aGlzLmRhdGEudXNlcm5hbWUsXG4gICAgICAgIG9iamVjdElkOiB7ICRuZTogdGhpcy5vYmplY3RJZCgpIH0sXG4gICAgICB9LFxuICAgICAgeyBsaW1pdDogMSwgY2FzZUluc2Vuc2l0aXZlOiB0cnVlIH0sXG4gICAgICB7fSxcbiAgICAgIHRoaXMudmFsaWRTY2hlbWFDb250cm9sbGVyXG4gICAgKVxuICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID4gMCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuVVNFUk5BTUVfVEFLRU4sXG4gICAgICAgICAgJ0FjY291bnQgYWxyZWFkeSBleGlzdHMgZm9yIHRoaXMgdXNlcm5hbWUuJ1xuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH0pO1xufTtcblxuLypcbiAgQXMgd2l0aCB1c2VybmFtZXMsIFBhcnNlIHNob3VsZCBub3QgYWxsb3cgY2FzZSBpbnNlbnNpdGl2ZSBjb2xsaXNpb25zIG9mIGVtYWlsLlxuICB1bmxpa2Ugd2l0aCB1c2VybmFtZXMgKHdoaWNoIGNhbiBoYXZlIGNhc2UgaW5zZW5zaXRpdmUgY29sbGlzaW9ucyBpbiB0aGUgY2FzZSBvZlxuICBhdXRoIGFkYXB0ZXJzKSwgZW1haWxzIHNob3VsZCBuZXZlciBoYXZlIGEgY2FzZSBpbnNlbnNpdGl2ZSBjb2xsaXNpb24uXG5cbiAgVGhpcyBiZWhhdmlvciBjYW4gYmUgZW5mb3JjZWQgdGhyb3VnaCBhIHByb3Blcmx5IGNvbmZpZ3VyZWQgaW5kZXggc2VlOlxuICBodHRwczovL2RvY3MubW9uZ29kYi5jb20vbWFudWFsL2NvcmUvaW5kZXgtY2FzZS1pbnNlbnNpdGl2ZS8jY3JlYXRlLWEtY2FzZS1pbnNlbnNpdGl2ZS1pbmRleFxuICB3aGljaCBjb3VsZCBiZSBpbXBsZW1lbnRlZCBpbnN0ZWFkIG9mIHRoaXMgY29kZSBiYXNlZCB2YWxpZGF0aW9uLlxuXG4gIEdpdmVuIHRoYXQgdGhpcyBsb29rdXAgc2hvdWxkIGJlIGEgcmVsYXRpdmVseSBsb3cgdXNlIGNhc2UgYW5kIHRoYXQgdGhlIGNhc2Ugc2Vuc2l0aXZlXG4gIHVuaXF1ZSBpbmRleCB3aWxsIGJlIHVzZWQgYnkgdGhlIGRiIGZvciB0aGUgcXVlcnksIHRoaXMgaXMgYW4gYWRlcXVhdGUgc29sdXRpb24uXG4qL1xuUmVzdFdyaXRlLnByb3RvdHlwZS5fdmFsaWRhdGVFbWFpbCA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCF0aGlzLmRhdGEuZW1haWwgfHwgdGhpcy5kYXRhLmVtYWlsLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG4gIC8vIFZhbGlkYXRlIGJhc2ljIGVtYWlsIGFkZHJlc3MgZm9ybWF0XG4gIGlmICghdGhpcy5kYXRhLmVtYWlsLm1hdGNoKC9eLitALiskLykpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9FTUFJTF9BRERSRVNTLCAnRW1haWwgYWRkcmVzcyBmb3JtYXQgaXMgaW52YWxpZC4nKVxuICAgICk7XG4gIH1cbiAgLy8gQ2FzZSBpbnNlbnNpdGl2ZSBtYXRjaCwgc2VlIG5vdGUgYWJvdmUgZnVuY3Rpb24uXG4gIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgIC5maW5kKFxuICAgICAgdGhpcy5jbGFzc05hbWUsXG4gICAgICB7XG4gICAgICAgIGVtYWlsOiB0aGlzLmRhdGEuZW1haWwsXG4gICAgICAgIG9iamVjdElkOiB7ICRuZTogdGhpcy5vYmplY3RJZCgpIH0sXG4gICAgICB9LFxuICAgICAgeyBsaW1pdDogMSwgY2FzZUluc2Vuc2l0aXZlOiB0cnVlIH0sXG4gICAgICB7fSxcbiAgICAgIHRoaXMudmFsaWRTY2hlbWFDb250cm9sbGVyXG4gICAgKVxuICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID4gMCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuRU1BSUxfVEFLRU4sXG4gICAgICAgICAgJ0FjY291bnQgYWxyZWFkeSBleGlzdHMgZm9yIHRoaXMgZW1haWwgYWRkcmVzcy4nXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoXG4gICAgICAgICF0aGlzLmRhdGEuYXV0aERhdGEgfHxcbiAgICAgICAgIU9iamVjdC5rZXlzKHRoaXMuZGF0YS5hdXRoRGF0YSkubGVuZ3RoIHx8XG4gICAgICAgIChPYmplY3Qua2V5cyh0aGlzLmRhdGEuYXV0aERhdGEpLmxlbmd0aCA9PT0gMSAmJlxuICAgICAgICAgIE9iamVjdC5rZXlzKHRoaXMuZGF0YS5hdXRoRGF0YSlbMF0gPT09ICdhbm9ueW1vdXMnKVxuICAgICAgKSB7XG4gICAgICAgIC8vIFdlIHVwZGF0ZWQgdGhlIGVtYWlsLCBzZW5kIGEgbmV3IHZhbGlkYXRpb25cbiAgICAgICAgdGhpcy5zdG9yYWdlWydzZW5kVmVyaWZpY2F0aW9uRW1haWwnXSA9IHRydWU7XG4gICAgICAgIHRoaXMuY29uZmlnLnVzZXJDb250cm9sbGVyLnNldEVtYWlsVmVyaWZ5VG9rZW4odGhpcy5kYXRhKTtcbiAgICAgIH1cbiAgICB9KTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuX3ZhbGlkYXRlUGFzc3dvcmRQb2xpY3kgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICghdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kpIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRlUGFzc3dvcmRSZXF1aXJlbWVudHMoKS50aGVuKCgpID0+IHtcbiAgICByZXR1cm4gdGhpcy5fdmFsaWRhdGVQYXNzd29yZEhpc3RvcnkoKTtcbiAgfSk7XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLl92YWxpZGF0ZVBhc3N3b3JkUmVxdWlyZW1lbnRzID0gZnVuY3Rpb24gKCkge1xuICAvLyBjaGVjayBpZiB0aGUgcGFzc3dvcmQgY29uZm9ybXMgdG8gdGhlIGRlZmluZWQgcGFzc3dvcmQgcG9saWN5IGlmIGNvbmZpZ3VyZWRcbiAgLy8gSWYgd2Ugc3BlY2lmaWVkIGEgY3VzdG9tIGVycm9yIGluIG91ciBjb25maWd1cmF0aW9uIHVzZSBpdC5cbiAgLy8gRXhhbXBsZTogXCJQYXNzd29yZHMgbXVzdCBpbmNsdWRlIGEgQ2FwaXRhbCBMZXR0ZXIsIExvd2VyY2FzZSBMZXR0ZXIsIGFuZCBhIG51bWJlci5cIlxuICAvL1xuICAvLyBUaGlzIGlzIGVzcGVjaWFsbHkgdXNlZnVsIG9uIHRoZSBnZW5lcmljIFwicGFzc3dvcmQgcmVzZXRcIiBwYWdlLFxuICAvLyBhcyBpdCBhbGxvd3MgdGhlIHByb2dyYW1tZXIgdG8gY29tbXVuaWNhdGUgc3BlY2lmaWMgcmVxdWlyZW1lbnRzIGluc3RlYWQgb2Y6XG4gIC8vIGEuIG1ha2luZyB0aGUgdXNlciBndWVzcyB3aGF0cyB3cm9uZ1xuICAvLyBiLiBtYWtpbmcgYSBjdXN0b20gcGFzc3dvcmQgcmVzZXQgcGFnZSB0aGF0IHNob3dzIHRoZSByZXF1aXJlbWVudHNcbiAgY29uc3QgcG9saWN5RXJyb3IgPSB0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS52YWxpZGF0aW9uRXJyb3JcbiAgICA/IHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LnZhbGlkYXRpb25FcnJvclxuICAgIDogJ1Bhc3N3b3JkIGRvZXMgbm90IG1lZXQgdGhlIFBhc3N3b3JkIFBvbGljeSByZXF1aXJlbWVudHMuJztcbiAgY29uc3QgY29udGFpbnNVc2VybmFtZUVycm9yID0gJ1Bhc3N3b3JkIGNhbm5vdCBjb250YWluIHlvdXIgdXNlcm5hbWUuJztcblxuICAvLyBjaGVjayB3aGV0aGVyIHRoZSBwYXNzd29yZCBtZWV0cyB0aGUgcGFzc3dvcmQgc3RyZW5ndGggcmVxdWlyZW1lbnRzXG4gIGlmIChcbiAgICAodGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kucGF0dGVyblZhbGlkYXRvciAmJlxuICAgICAgIXRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LnBhdHRlcm5WYWxpZGF0b3IodGhpcy5kYXRhLnBhc3N3b3JkKSkgfHxcbiAgICAodGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yQ2FsbGJhY2sgJiZcbiAgICAgICF0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS52YWxpZGF0b3JDYWxsYmFjayh0aGlzLmRhdGEucGFzc3dvcmQpKVxuICApIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlZBTElEQVRJT05fRVJST1IsIHBvbGljeUVycm9yKSk7XG4gIH1cblxuICAvLyBjaGVjayB3aGV0aGVyIHBhc3N3b3JkIGNvbnRhaW4gdXNlcm5hbWVcbiAgaWYgKHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5LmRvTm90QWxsb3dVc2VybmFtZSA9PT0gdHJ1ZSkge1xuICAgIGlmICh0aGlzLmRhdGEudXNlcm5hbWUpIHtcbiAgICAgIC8vIHVzZXJuYW1lIGlzIG5vdCBwYXNzZWQgZHVyaW5nIHBhc3N3b3JkIHJlc2V0XG4gICAgICBpZiAodGhpcy5kYXRhLnBhc3N3b3JkLmluZGV4T2YodGhpcy5kYXRhLnVzZXJuYW1lKSA+PSAwKVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlZBTElEQVRJT05fRVJST1IsIGNvbnRhaW5zVXNlcm5hbWVFcnJvcikpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyByZXRyaWV2ZSB0aGUgVXNlciBvYmplY3QgdXNpbmcgb2JqZWN0SWQgZHVyaW5nIHBhc3N3b3JkIHJlc2V0XG4gICAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UuZmluZCgnX1VzZXInLCB7IG9iamVjdElkOiB0aGlzLm9iamVjdElkKCkgfSkudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoICE9IDEpIHtcbiAgICAgICAgICB0aHJvdyB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZGF0YS5wYXNzd29yZC5pbmRleE9mKHJlc3VsdHNbMF0udXNlcm5hbWUpID49IDApXG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KFxuICAgICAgICAgICAgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlZBTElEQVRJT05fRVJST1IsIGNvbnRhaW5zVXNlcm5hbWVFcnJvcilcbiAgICAgICAgICApO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xufTtcblxuUmVzdFdyaXRlLnByb3RvdHlwZS5fdmFsaWRhdGVQYXNzd29yZEhpc3RvcnkgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIGNoZWNrIHdoZXRoZXIgcGFzc3dvcmQgaXMgcmVwZWF0aW5nIGZyb20gc3BlY2lmaWVkIGhpc3RvcnlcbiAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRIaXN0b3J5KSB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLmRhdGFiYXNlXG4gICAgICAuZmluZChcbiAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAgeyBvYmplY3RJZDogdGhpcy5vYmplY3RJZCgpIH0sXG4gICAgICAgIHsga2V5czogWydfcGFzc3dvcmRfaGlzdG9yeScsICdfaGFzaGVkX3Bhc3N3b3JkJ10gfVxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCAhPSAxKSB7XG4gICAgICAgICAgdGhyb3cgdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHVzZXIgPSByZXN1bHRzWzBdO1xuICAgICAgICBsZXQgb2xkUGFzc3dvcmRzID0gW107XG4gICAgICAgIGlmICh1c2VyLl9wYXNzd29yZF9oaXN0b3J5KVxuICAgICAgICAgIG9sZFBhc3N3b3JkcyA9IF8udGFrZShcbiAgICAgICAgICAgIHVzZXIuX3Bhc3N3b3JkX2hpc3RvcnksXG4gICAgICAgICAgICB0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEhpc3RvcnkgLSAxXG4gICAgICAgICAgKTtcbiAgICAgICAgb2xkUGFzc3dvcmRzLnB1c2godXNlci5wYXNzd29yZCk7XG4gICAgICAgIGNvbnN0IG5ld1Bhc3N3b3JkID0gdGhpcy5kYXRhLnBhc3N3b3JkO1xuICAgICAgICAvLyBjb21wYXJlIHRoZSBuZXcgcGFzc3dvcmQgaGFzaCB3aXRoIGFsbCBvbGQgcGFzc3dvcmQgaGFzaGVzXG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gb2xkUGFzc3dvcmRzLm1hcChmdW5jdGlvbiAoaGFzaCkge1xuICAgICAgICAgIHJldHVybiBwYXNzd29yZENyeXB0by5jb21wYXJlKG5ld1Bhc3N3b3JkLCBoYXNoKS50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgICBpZiAocmVzdWx0KVxuICAgICAgICAgICAgICAvLyByZWplY3QgaWYgdGhlcmUgaXMgYSBtYXRjaFxuICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoJ1JFUEVBVF9QQVNTV09SRCcpO1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gd2FpdCBmb3IgYWxsIGNvbXBhcmlzb25zIHRvIGNvbXBsZXRlXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcylcbiAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICAgIGlmIChlcnIgPT09ICdSRVBFQVRfUEFTU1dPUkQnKVxuICAgICAgICAgICAgICAvLyBhIG1hdGNoIHdhcyBmb3VuZFxuICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICAgICAgICAgICAgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuVkFMSURBVElPTl9FUlJPUixcbiAgICAgICAgICAgICAgICAgIGBOZXcgcGFzc3dvcmQgc2hvdWxkIG5vdCBiZSB0aGUgc2FtZSBhcyBsYXN0ICR7dGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRIaXN0b3J5fSBwYXNzd29yZHMuYFxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICB9KTtcbiAgICAgIH0pO1xuICB9XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuY3JlYXRlU2Vzc2lvblRva2VuSWZOZWVkZWQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmNsYXNzTmFtZSAhPT0gJ19Vc2VyJykge1xuICAgIHJldHVybjtcbiAgfVxuICAvLyBEb24ndCBnZW5lcmF0ZSBzZXNzaW9uIGZvciB1cGRhdGluZyB1c2VyICh0aGlzLnF1ZXJ5IGlzIHNldCkgdW5sZXNzIGF1dGhEYXRhIGV4aXN0c1xuICBpZiAodGhpcy5xdWVyeSAmJiAhdGhpcy5kYXRhLmF1dGhEYXRhKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIERvbid0IGdlbmVyYXRlIG5ldyBzZXNzaW9uVG9rZW4gaWYgbGlua2luZyB2aWEgc2Vzc2lvblRva2VuXG4gIGlmICh0aGlzLmF1dGgudXNlciAmJiB0aGlzLmRhdGEuYXV0aERhdGEpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKFxuICAgICF0aGlzLnN0b3JhZ2VbJ2F1dGhQcm92aWRlciddICYmIC8vIHNpZ251cCBjYWxsLCB3aXRoXG4gICAgdGhpcy5jb25maWcucHJldmVudExvZ2luV2l0aFVudmVyaWZpZWRFbWFpbCAmJiAvLyBubyBsb2dpbiB3aXRob3V0IHZlcmlmaWNhdGlvblxuICAgIHRoaXMuY29uZmlnLnZlcmlmeVVzZXJFbWFpbHNcbiAgKSB7XG4gICAgLy8gdmVyaWZpY2F0aW9uIGlzIG9uXG4gICAgcmV0dXJuOyAvLyBkbyBub3QgY3JlYXRlIHRoZSBzZXNzaW9uIHRva2VuIGluIHRoYXQgY2FzZSFcbiAgfVxuICByZXR1cm4gdGhpcy5jcmVhdGVTZXNzaW9uVG9rZW4oKTtcbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuY3JlYXRlU2Vzc2lvblRva2VuID0gYXN5bmMgZnVuY3Rpb24gKCkge1xuICAvLyBjbG91ZCBpbnN0YWxsYXRpb25JZCBmcm9tIENsb3VkIENvZGUsXG4gIC8vIG5ldmVyIGNyZWF0ZSBzZXNzaW9uIHRva2VucyBmcm9tIHRoZXJlLlxuICBpZiAodGhpcy5hdXRoLmluc3RhbGxhdGlvbklkICYmIHRoaXMuYXV0aC5pbnN0YWxsYXRpb25JZCA9PT0gJ2Nsb3VkJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHsgc2Vzc2lvbkRhdGEsIGNyZWF0ZVNlc3Npb24gfSA9IEF1dGguY3JlYXRlU2Vzc2lvbih0aGlzLmNvbmZpZywge1xuICAgIHVzZXJJZDogdGhpcy5vYmplY3RJZCgpLFxuICAgIGNyZWF0ZWRXaXRoOiB7XG4gICAgICBhY3Rpb246IHRoaXMuc3RvcmFnZVsnYXV0aFByb3ZpZGVyJ10gPyAnbG9naW4nIDogJ3NpZ251cCcsXG4gICAgICBhdXRoUHJvdmlkZXI6IHRoaXMuc3RvcmFnZVsnYXV0aFByb3ZpZGVyJ10gfHwgJ3Bhc3N3b3JkJyxcbiAgICB9LFxuICAgIGluc3RhbGxhdGlvbklkOiB0aGlzLmF1dGguaW5zdGFsbGF0aW9uSWQsXG4gIH0pO1xuXG4gIGlmICh0aGlzLnJlc3BvbnNlICYmIHRoaXMucmVzcG9uc2UucmVzcG9uc2UpIHtcbiAgICB0aGlzLnJlc3BvbnNlLnJlc3BvbnNlLnNlc3Npb25Ub2tlbiA9IHNlc3Npb25EYXRhLnNlc3Npb25Ub2tlbjtcbiAgfVxuXG4gIHJldHVybiBjcmVhdGVTZXNzaW9uKCk7XG59O1xuXG4vLyBEZWxldGUgZW1haWwgcmVzZXQgdG9rZW5zIGlmIHVzZXIgaXMgY2hhbmdpbmcgcGFzc3dvcmQgb3IgZW1haWwuXG5SZXN0V3JpdGUucHJvdG90eXBlLmRlbGV0ZUVtYWlsUmVzZXRUb2tlbklmTmVlZGVkID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5jbGFzc05hbWUgIT09ICdfVXNlcicgfHwgdGhpcy5xdWVyeSA9PT0gbnVsbCkge1xuICAgIC8vIG51bGwgcXVlcnkgbWVhbnMgY3JlYXRlXG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKCdwYXNzd29yZCcgaW4gdGhpcy5kYXRhIHx8ICdlbWFpbCcgaW4gdGhpcy5kYXRhKSB7XG4gICAgY29uc3QgYWRkT3BzID0ge1xuICAgICAgX3BlcmlzaGFibGVfdG9rZW46IHsgX19vcDogJ0RlbGV0ZScgfSxcbiAgICAgIF9wZXJpc2hhYmxlX3Rva2VuX2V4cGlyZXNfYXQ6IHsgX19vcDogJ0RlbGV0ZScgfSxcbiAgICB9O1xuICAgIHRoaXMuZGF0YSA9IE9iamVjdC5hc3NpZ24odGhpcy5kYXRhLCBhZGRPcHMpO1xuICB9XG59O1xuXG5SZXN0V3JpdGUucHJvdG90eXBlLmRlc3Ryb3lEdXBsaWNhdGVkU2Vzc2lvbnMgPSBmdW5jdGlvbiAoKSB7XG4gIC8vIE9ubHkgZm9yIF9TZXNzaW9uLCBhbmQgYXQgY3JlYXRpb24gdGltZVxuICBpZiAodGhpcy5jbGFzc05hbWUgIT0gJ19TZXNzaW9uJyB8fCB0aGlzLnF1ZXJ5KSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIERlc3Ryb3kgdGhlIHNlc3Npb25zIGluICdCYWNrZ3JvdW5kJ1xuICBjb25zdCB7IHVzZXIsIGluc3RhbGxhdGlvbklkLCBzZXNzaW9uVG9rZW4gfSA9IHRoaXMuZGF0YTtcbiAgaWYgKCF1c2VyIHx8ICFpbnN0YWxsYXRpb25JZCkge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoIXVzZXIub2JqZWN0SWQpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdGhpcy5jb25maWcuZGF0YWJhc2UuZGVzdHJveShcbiAgICAnX1Nlc3Npb24nLFxuICAgIHtcbiAgICAgIHVzZXIsXG4gICAgICBpbnN0YWxsYXRpb25JZCxcbiAgICAgIHNlc3Npb25Ub2tlbjogeyAkbmU6IHNlc3Npb25Ub2tlbiB9LFxuICAgIH0sXG4gICAge30sXG4gICAgdGhpcy52YWxpZFNjaGVtYUNvbnRyb2xsZXJcbiAgKTtcbn07XG5cbi8vIEhhbmRsZXMgYW55IGZvbGxvd3VwIGxvZ2ljXG5SZXN0V3JpdGUucHJvdG90eXBlLmhhbmRsZUZvbGxvd3VwID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5zdG9yYWdlICYmIHRoaXMuc3RvcmFnZVsnY2xlYXJTZXNzaW9ucyddICYmIHRoaXMuY29uZmlnLnJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQpIHtcbiAgICB2YXIgc2Vzc2lvblF1ZXJ5ID0ge1xuICAgICAgdXNlcjoge1xuICAgICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgICAgY2xhc3NOYW1lOiAnX1VzZXInLFxuICAgICAgICBvYmplY3RJZDogdGhpcy5vYmplY3RJZCgpLFxuICAgICAgfSxcbiAgICB9O1xuICAgIGRlbGV0ZSB0aGlzLnN0b3JhZ2VbJ2NsZWFyU2Vzc2lvbnMnXTtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAgIC5kZXN0cm95KCdfU2Vzc2lvbicsIHNlc3Npb25RdWVyeSlcbiAgICAgIC50aGVuKHRoaXMuaGFuZGxlRm9sbG93dXAuYmluZCh0aGlzKSk7XG4gIH1cblxuICBpZiAodGhpcy5zdG9yYWdlICYmIHRoaXMuc3RvcmFnZVsnZ2VuZXJhdGVOZXdTZXNzaW9uJ10pIHtcbiAgICBkZWxldGUgdGhpcy5zdG9yYWdlWydnZW5lcmF0ZU5ld1Nlc3Npb24nXTtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVTZXNzaW9uVG9rZW4oKS50aGVuKHRoaXMuaGFuZGxlRm9sbG93dXAuYmluZCh0aGlzKSk7XG4gIH1cblxuICBpZiAodGhpcy5zdG9yYWdlICYmIHRoaXMuc3RvcmFnZVsnc2VuZFZlcmlmaWNhdGlvbkVtYWlsJ10pIHtcbiAgICBkZWxldGUgdGhpcy5zdG9yYWdlWydzZW5kVmVyaWZpY2F0aW9uRW1haWwnXTtcbiAgICAvLyBGaXJlIGFuZCBmb3JnZXQhXG4gICAgdGhpcy5jb25maWcudXNlckNvbnRyb2xsZXIuc2VuZFZlcmlmaWNhdGlvbkVtYWlsKHRoaXMuZGF0YSk7XG4gICAgcmV0dXJuIHRoaXMuaGFuZGxlRm9sbG93dXAuYmluZCh0aGlzKTtcbiAgfVxufTtcblxuLy8gSGFuZGxlcyB0aGUgX1Nlc3Npb24gY2xhc3Mgc3BlY2lhbG5lc3MuXG4vLyBEb2VzIG5vdGhpbmcgaWYgdGhpcyBpc24ndCBhbiBfU2Vzc2lvbiBvYmplY3QuXG5SZXN0V3JpdGUucHJvdG90eXBlLmhhbmRsZVNlc3Npb24gPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLnJlc3BvbnNlIHx8IHRoaXMuY2xhc3NOYW1lICE9PSAnX1Nlc3Npb24nKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKCF0aGlzLmF1dGgudXNlciAmJiAhdGhpcy5hdXRoLmlzTWFzdGVyKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTiwgJ1Nlc3Npb24gdG9rZW4gcmVxdWlyZWQuJyk7XG4gIH1cblxuICAvLyBUT0RPOiBWZXJpZnkgcHJvcGVyIGVycm9yIHRvIHRocm93XG4gIGlmICh0aGlzLmRhdGEuQUNMKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUsICdDYW5ub3Qgc2V0ICcgKyAnQUNMIG9uIGEgU2Vzc2lvbi4nKTtcbiAgfVxuXG4gIGlmICh0aGlzLnF1ZXJ5KSB7XG4gICAgaWYgKHRoaXMuZGF0YS51c2VyICYmICF0aGlzLmF1dGguaXNNYXN0ZXIgJiYgdGhpcy5kYXRhLnVzZXIub2JqZWN0SWQgIT0gdGhpcy5hdXRoLnVzZXIuaWQpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0tFWV9OQU1FKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5kYXRhLnNlc3Npb25Ub2tlbikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUpO1xuICAgIH1cbiAgfVxuXG4gIGlmICghdGhpcy5xdWVyeSAmJiAhdGhpcy5hdXRoLmlzTWFzdGVyKSB7XG4gICAgY29uc3QgYWRkaXRpb25hbFNlc3Npb25EYXRhID0ge307XG4gICAgZm9yICh2YXIga2V5IGluIHRoaXMuZGF0YSkge1xuICAgICAgaWYgKGtleSA9PT0gJ29iamVjdElkJyB8fCBrZXkgPT09ICd1c2VyJykge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGFkZGl0aW9uYWxTZXNzaW9uRGF0YVtrZXldID0gdGhpcy5kYXRhW2tleV07XG4gICAgfVxuXG4gICAgY29uc3QgeyBzZXNzaW9uRGF0YSwgY3JlYXRlU2Vzc2lvbiB9ID0gQXV0aC5jcmVhdGVTZXNzaW9uKHRoaXMuY29uZmlnLCB7XG4gICAgICB1c2VySWQ6IHRoaXMuYXV0aC51c2VyLmlkLFxuICAgICAgY3JlYXRlZFdpdGg6IHtcbiAgICAgICAgYWN0aW9uOiAnY3JlYXRlJyxcbiAgICAgIH0sXG4gICAgICBhZGRpdGlvbmFsU2Vzc2lvbkRhdGEsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gY3JlYXRlU2Vzc2lvbigpLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICBpZiAoIXJlc3VsdHMucmVzcG9uc2UpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUiwgJ0Vycm9yIGNyZWF0aW5nIHNlc3Npb24uJyk7XG4gICAgICB9XG4gICAgICBzZXNzaW9uRGF0YVsnb2JqZWN0SWQnXSA9IHJlc3VsdHMucmVzcG9uc2VbJ29iamVjdElkJ107XG4gICAgICB0aGlzLnJlc3BvbnNlID0ge1xuICAgICAgICBzdGF0dXM6IDIwMSxcbiAgICAgICAgbG9jYXRpb246IHJlc3VsdHMubG9jYXRpb24sXG4gICAgICAgIHJlc3BvbnNlOiBzZXNzaW9uRGF0YSxcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cbn07XG5cbi8vIEhhbmRsZXMgdGhlIF9JbnN0YWxsYXRpb24gY2xhc3Mgc3BlY2lhbG5lc3MuXG4vLyBEb2VzIG5vdGhpbmcgaWYgdGhpcyBpc24ndCBhbiBpbnN0YWxsYXRpb24gb2JqZWN0LlxuLy8gSWYgYW4gaW5zdGFsbGF0aW9uIGlzIGZvdW5kLCB0aGlzIGNhbiBtdXRhdGUgdGhpcy5xdWVyeSBhbmQgdHVybiBhIGNyZWF0ZVxuLy8gaW50byBhbiB1cGRhdGUuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3Igd2hlbiB3ZSdyZSBkb25lIGlmIGl0IGNhbid0IGZpbmlzaCB0aGlzIHRpY2suXG5SZXN0V3JpdGUucHJvdG90eXBlLmhhbmRsZUluc3RhbGxhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMucmVzcG9uc2UgfHwgdGhpcy5jbGFzc05hbWUgIT09ICdfSW5zdGFsbGF0aW9uJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChcbiAgICAhdGhpcy5xdWVyeSAmJlxuICAgICF0aGlzLmRhdGEuZGV2aWNlVG9rZW4gJiZcbiAgICAhdGhpcy5kYXRhLmluc3RhbGxhdGlvbklkICYmXG4gICAgIXRoaXMuYXV0aC5pbnN0YWxsYXRpb25JZFxuICApIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAxMzUsXG4gICAgICAnYXQgbGVhc3Qgb25lIElEIGZpZWxkIChkZXZpY2VUb2tlbiwgaW5zdGFsbGF0aW9uSWQpICcgKyAnbXVzdCBiZSBzcGVjaWZpZWQgaW4gdGhpcyBvcGVyYXRpb24nXG4gICAgKTtcbiAgfVxuXG4gIC8vIElmIHRoZSBkZXZpY2UgdG9rZW4gaXMgNjQgY2hhcmFjdGVycyBsb25nLCB3ZSBhc3N1bWUgaXQgaXMgZm9yIGlPU1xuICAvLyBhbmQgbG93ZXJjYXNlIGl0LlxuICBpZiAodGhpcy5kYXRhLmRldmljZVRva2VuICYmIHRoaXMuZGF0YS5kZXZpY2VUb2tlbi5sZW5ndGggPT0gNjQpIHtcbiAgICB0aGlzLmRhdGEuZGV2aWNlVG9rZW4gPSB0aGlzLmRhdGEuZGV2aWNlVG9rZW4udG9Mb3dlckNhc2UoKTtcbiAgfVxuXG4gIC8vIFdlIGxvd2VyY2FzZSB0aGUgaW5zdGFsbGF0aW9uSWQgaWYgcHJlc2VudFxuICBpZiAodGhpcy5kYXRhLmluc3RhbGxhdGlvbklkKSB7XG4gICAgdGhpcy5kYXRhLmluc3RhbGxhdGlvbklkID0gdGhpcy5kYXRhLmluc3RhbGxhdGlvbklkLnRvTG93ZXJDYXNlKCk7XG4gIH1cblxuICBsZXQgaW5zdGFsbGF0aW9uSWQgPSB0aGlzLmRhdGEuaW5zdGFsbGF0aW9uSWQ7XG5cbiAgLy8gSWYgZGF0YS5pbnN0YWxsYXRpb25JZCBpcyBub3Qgc2V0IGFuZCB3ZSdyZSBub3QgbWFzdGVyLCB3ZSBjYW4gbG9va3VwIGluIGF1dGhcbiAgaWYgKCFpbnN0YWxsYXRpb25JZCAmJiAhdGhpcy5hdXRoLmlzTWFzdGVyKSB7XG4gICAgaW5zdGFsbGF0aW9uSWQgPSB0aGlzLmF1dGguaW5zdGFsbGF0aW9uSWQ7XG4gIH1cblxuICBpZiAoaW5zdGFsbGF0aW9uSWQpIHtcbiAgICBpbnN0YWxsYXRpb25JZCA9IGluc3RhbGxhdGlvbklkLnRvTG93ZXJDYXNlKCk7XG4gIH1cblxuICAvLyBVcGRhdGluZyBfSW5zdGFsbGF0aW9uIGJ1dCBub3QgdXBkYXRpbmcgYW55dGhpbmcgY3JpdGljYWxcbiAgaWYgKHRoaXMucXVlcnkgJiYgIXRoaXMuZGF0YS5kZXZpY2VUb2tlbiAmJiAhaW5zdGFsbGF0aW9uSWQgJiYgIXRoaXMuZGF0YS5kZXZpY2VUeXBlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcblxuICB2YXIgaWRNYXRjaDsgLy8gV2lsbCBiZSBhIG1hdGNoIG9uIGVpdGhlciBvYmplY3RJZCBvciBpbnN0YWxsYXRpb25JZFxuICB2YXIgb2JqZWN0SWRNYXRjaDtcbiAgdmFyIGluc3RhbGxhdGlvbklkTWF0Y2g7XG4gIHZhciBkZXZpY2VUb2tlbk1hdGNoZXMgPSBbXTtcblxuICAvLyBJbnN0ZWFkIG9mIGlzc3VpbmcgMyByZWFkcywgbGV0J3MgZG8gaXQgd2l0aCBvbmUgT1IuXG4gIGNvbnN0IG9yUXVlcmllcyA9IFtdO1xuICBpZiAodGhpcy5xdWVyeSAmJiB0aGlzLnF1ZXJ5Lm9iamVjdElkKSB7XG4gICAgb3JRdWVyaWVzLnB1c2goe1xuICAgICAgb2JqZWN0SWQ6IHRoaXMucXVlcnkub2JqZWN0SWQsXG4gICAgfSk7XG4gIH1cbiAgaWYgKGluc3RhbGxhdGlvbklkKSB7XG4gICAgb3JRdWVyaWVzLnB1c2goe1xuICAgICAgaW5zdGFsbGF0aW9uSWQ6IGluc3RhbGxhdGlvbklkLFxuICAgIH0pO1xuICB9XG4gIGlmICh0aGlzLmRhdGEuZGV2aWNlVG9rZW4pIHtcbiAgICBvclF1ZXJpZXMucHVzaCh7IGRldmljZVRva2VuOiB0aGlzLmRhdGEuZGV2aWNlVG9rZW4gfSk7XG4gIH1cblxuICBpZiAob3JRdWVyaWVzLmxlbmd0aCA9PSAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcHJvbWlzZSA9IHByb21pc2VcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2UuZmluZChcbiAgICAgICAgJ19JbnN0YWxsYXRpb24nLFxuICAgICAgICB7XG4gICAgICAgICAgJG9yOiBvclF1ZXJpZXMsXG4gICAgICAgIH0sXG4gICAgICAgIHt9XG4gICAgICApO1xuICAgIH0pXG4gICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICByZXN1bHRzLmZvckVhY2gocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCAmJiByZXN1bHQub2JqZWN0SWQgPT0gdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgICAgICAgIG9iamVjdElkTWF0Y2ggPSByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlc3VsdC5pbnN0YWxsYXRpb25JZCA9PSBpbnN0YWxsYXRpb25JZCkge1xuICAgICAgICAgIGluc3RhbGxhdGlvbklkTWF0Y2ggPSByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlc3VsdC5kZXZpY2VUb2tlbiA9PSB0aGlzLmRhdGEuZGV2aWNlVG9rZW4pIHtcbiAgICAgICAgICBkZXZpY2VUb2tlbk1hdGNoZXMucHVzaChyZXN1bHQpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLy8gU2FuaXR5IGNoZWNrcyB3aGVuIHJ1bm5pbmcgYSBxdWVyeVxuICAgICAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgICAgICBpZiAoIW9iamVjdElkTWF0Y2gpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ09iamVjdCBub3QgZm91bmQgZm9yIHVwZGF0ZS4nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoXG4gICAgICAgICAgdGhpcy5kYXRhLmluc3RhbGxhdGlvbklkICYmXG4gICAgICAgICAgb2JqZWN0SWRNYXRjaC5pbnN0YWxsYXRpb25JZCAmJlxuICAgICAgICAgIHRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZCAhPT0gb2JqZWN0SWRNYXRjaC5pbnN0YWxsYXRpb25JZFxuICAgICAgICApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTM2LCAnaW5zdGFsbGF0aW9uSWQgbWF5IG5vdCBiZSBjaGFuZ2VkIGluIHRoaXMgJyArICdvcGVyYXRpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoXG4gICAgICAgICAgdGhpcy5kYXRhLmRldmljZVRva2VuICYmXG4gICAgICAgICAgb2JqZWN0SWRNYXRjaC5kZXZpY2VUb2tlbiAmJlxuICAgICAgICAgIHRoaXMuZGF0YS5kZXZpY2VUb2tlbiAhPT0gb2JqZWN0SWRNYXRjaC5kZXZpY2VUb2tlbiAmJlxuICAgICAgICAgICF0aGlzLmRhdGEuaW5zdGFsbGF0aW9uSWQgJiZcbiAgICAgICAgICAhb2JqZWN0SWRNYXRjaC5pbnN0YWxsYXRpb25JZFxuICAgICAgICApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTM2LCAnZGV2aWNlVG9rZW4gbWF5IG5vdCBiZSBjaGFuZ2VkIGluIHRoaXMgJyArICdvcGVyYXRpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoXG4gICAgICAgICAgdGhpcy5kYXRhLmRldmljZVR5cGUgJiZcbiAgICAgICAgICB0aGlzLmRhdGEuZGV2aWNlVHlwZSAmJlxuICAgICAgICAgIHRoaXMuZGF0YS5kZXZpY2VUeXBlICE9PSBvYmplY3RJZE1hdGNoLmRldmljZVR5cGVcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDEzNiwgJ2RldmljZVR5cGUgbWF5IG5vdCBiZSBjaGFuZ2VkIGluIHRoaXMgJyArICdvcGVyYXRpb24nKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5xdWVyeSAmJiB0aGlzLnF1ZXJ5Lm9iamVjdElkICYmIG9iamVjdElkTWF0Y2gpIHtcbiAgICAgICAgaWRNYXRjaCA9IG9iamVjdElkTWF0Y2g7XG4gICAgICB9XG5cbiAgICAgIGlmIChpbnN0YWxsYXRpb25JZCAmJiBpbnN0YWxsYXRpb25JZE1hdGNoKSB7XG4gICAgICAgIGlkTWF0Y2ggPSBpbnN0YWxsYXRpb25JZE1hdGNoO1xuICAgICAgfVxuICAgICAgLy8gbmVlZCB0byBzcGVjaWZ5IGRldmljZVR5cGUgb25seSBpZiBpdCdzIG5ld1xuICAgICAgaWYgKCF0aGlzLnF1ZXJ5ICYmICF0aGlzLmRhdGEuZGV2aWNlVHlwZSAmJiAhaWRNYXRjaCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTM1LCAnZGV2aWNlVHlwZSBtdXN0IGJlIHNwZWNpZmllZCBpbiB0aGlzIG9wZXJhdGlvbicpO1xuICAgICAgfVxuICAgIH0pXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgaWYgKCFpZE1hdGNoKSB7XG4gICAgICAgIGlmICghZGV2aWNlVG9rZW5NYXRjaGVzLmxlbmd0aCkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBkZXZpY2VUb2tlbk1hdGNoZXMubGVuZ3RoID09IDEgJiZcbiAgICAgICAgICAoIWRldmljZVRva2VuTWF0Y2hlc1swXVsnaW5zdGFsbGF0aW9uSWQnXSB8fCAhaW5zdGFsbGF0aW9uSWQpXG4gICAgICAgICkge1xuICAgICAgICAgIC8vIFNpbmdsZSBtYXRjaCBvbiBkZXZpY2UgdG9rZW4gYnV0IG5vbmUgb24gaW5zdGFsbGF0aW9uSWQsIGFuZCBlaXRoZXJcbiAgICAgICAgICAvLyB0aGUgcGFzc2VkIG9iamVjdCBvciB0aGUgbWF0Y2ggaXMgbWlzc2luZyBhbiBpbnN0YWxsYXRpb25JZCwgc28gd2VcbiAgICAgICAgICAvLyBjYW4ganVzdCByZXR1cm4gdGhlIG1hdGNoLlxuICAgICAgICAgIHJldHVybiBkZXZpY2VUb2tlbk1hdGNoZXNbMF1bJ29iamVjdElkJ107XG4gICAgICAgIH0gZWxzZSBpZiAoIXRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIDEzMixcbiAgICAgICAgICAgICdNdXN0IHNwZWNpZnkgaW5zdGFsbGF0aW9uSWQgd2hlbiBkZXZpY2VUb2tlbiAnICtcbiAgICAgICAgICAgICAgJ21hdGNoZXMgbXVsdGlwbGUgSW5zdGFsbGF0aW9uIG9iamVjdHMnXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBNdWx0aXBsZSBkZXZpY2UgdG9rZW4gbWF0Y2hlcyBhbmQgd2Ugc3BlY2lmaWVkIGFuIGluc3RhbGxhdGlvbiBJRCxcbiAgICAgICAgICAvLyBvciBhIHNpbmdsZSBtYXRjaCB3aGVyZSBib3RoIHRoZSBwYXNzZWQgYW5kIG1hdGNoaW5nIG9iamVjdHMgaGF2ZVxuICAgICAgICAgIC8vIGFuIGluc3RhbGxhdGlvbiBJRC4gVHJ5IGNsZWFuaW5nIG91dCBvbGQgaW5zdGFsbGF0aW9ucyB0aGF0IG1hdGNoXG4gICAgICAgICAgLy8gdGhlIGRldmljZVRva2VuLCBhbmQgcmV0dXJuIG5pbCB0byBzaWduYWwgdGhhdCBhIG5ldyBvYmplY3Qgc2hvdWxkXG4gICAgICAgICAgLy8gYmUgY3JlYXRlZC5cbiAgICAgICAgICB2YXIgZGVsUXVlcnkgPSB7XG4gICAgICAgICAgICBkZXZpY2VUb2tlbjogdGhpcy5kYXRhLmRldmljZVRva2VuLFxuICAgICAgICAgICAgaW5zdGFsbGF0aW9uSWQ6IHtcbiAgICAgICAgICAgICAgJG5lOiBpbnN0YWxsYXRpb25JZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgICBpZiAodGhpcy5kYXRhLmFwcElkZW50aWZpZXIpIHtcbiAgICAgICAgICAgIGRlbFF1ZXJ5WydhcHBJZGVudGlmaWVyJ10gPSB0aGlzLmRhdGEuYXBwSWRlbnRpZmllcjtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5jb25maWcuZGF0YWJhc2UuZGVzdHJveSgnX0luc3RhbGxhdGlvbicsIGRlbFF1ZXJ5KS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgaWYgKGVyci5jb2RlID09IFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQpIHtcbiAgICAgICAgICAgICAgLy8gbm8gZGVsZXRpb25zIHdlcmUgbWFkZS4gQ2FuIGJlIGlnbm9yZWQuXG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHJldGhyb3cgdGhlIGVycm9yXG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoZGV2aWNlVG9rZW5NYXRjaGVzLmxlbmd0aCA9PSAxICYmICFkZXZpY2VUb2tlbk1hdGNoZXNbMF1bJ2luc3RhbGxhdGlvbklkJ10pIHtcbiAgICAgICAgICAvLyBFeGFjdGx5IG9uZSBkZXZpY2UgdG9rZW4gbWF0Y2ggYW5kIGl0IGRvZXNuJ3QgaGF2ZSBhbiBpbnN0YWxsYXRpb25cbiAgICAgICAgICAvLyBJRC4gVGhpcyBpcyB0aGUgb25lIGNhc2Ugd2hlcmUgd2Ugd2FudCB0byBtZXJnZSB3aXRoIHRoZSBleGlzdGluZ1xuICAgICAgICAgIC8vIG9iamVjdC5cbiAgICAgICAgICBjb25zdCBkZWxRdWVyeSA9IHsgb2JqZWN0SWQ6IGlkTWF0Y2gub2JqZWN0SWQgfTtcbiAgICAgICAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAgICAgICAgIC5kZXN0cm95KCdfSW5zdGFsbGF0aW9uJywgZGVsUXVlcnkpXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBkZXZpY2VUb2tlbk1hdGNoZXNbMF1bJ29iamVjdElkJ107XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVyciA9PiB7XG4gICAgICAgICAgICAgIGlmIChlcnIuY29kZSA9PSBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5EKSB7XG4gICAgICAgICAgICAgICAgLy8gbm8gZGVsZXRpb25zIHdlcmUgbWFkZS4gQ2FuIGJlIGlnbm9yZWRcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgLy8gcmV0aHJvdyB0aGUgZXJyb3JcbiAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKHRoaXMuZGF0YS5kZXZpY2VUb2tlbiAmJiBpZE1hdGNoLmRldmljZVRva2VuICE9IHRoaXMuZGF0YS5kZXZpY2VUb2tlbikge1xuICAgICAgICAgICAgLy8gV2UncmUgc2V0dGluZyB0aGUgZGV2aWNlIHRva2VuIG9uIGFuIGV4aXN0aW5nIGluc3RhbGxhdGlvbiwgc29cbiAgICAgICAgICAgIC8vIHdlIHNob3VsZCB0cnkgY2xlYW5pbmcgb3V0IG9sZCBpbnN0YWxsYXRpb25zIHRoYXQgbWF0Y2ggdGhpc1xuICAgICAgICAgICAgLy8gZGV2aWNlIHRva2VuLlxuICAgICAgICAgICAgY29uc3QgZGVsUXVlcnkgPSB7XG4gICAgICAgICAgICAgIGRldmljZVRva2VuOiB0aGlzLmRhdGEuZGV2aWNlVG9rZW4sXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy8gV2UgaGF2ZSBhIHVuaXF1ZSBpbnN0YWxsIElkLCB1c2UgdGhhdCB0byBwcmVzZXJ2ZVxuICAgICAgICAgICAgLy8gdGhlIGludGVyZXN0aW5nIGluc3RhbGxhdGlvblxuICAgICAgICAgICAgaWYgKHRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZCkge1xuICAgICAgICAgICAgICBkZWxRdWVyeVsnaW5zdGFsbGF0aW9uSWQnXSA9IHtcbiAgICAgICAgICAgICAgICAkbmU6IHRoaXMuZGF0YS5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgIGlkTWF0Y2gub2JqZWN0SWQgJiZcbiAgICAgICAgICAgICAgdGhpcy5kYXRhLm9iamVjdElkICYmXG4gICAgICAgICAgICAgIGlkTWF0Y2gub2JqZWN0SWQgPT0gdGhpcy5kYXRhLm9iamVjdElkXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgLy8gd2UgcGFzc2VkIGFuIG9iamVjdElkLCBwcmVzZXJ2ZSB0aGF0IGluc3RhbGF0aW9uXG4gICAgICAgICAgICAgIGRlbFF1ZXJ5WydvYmplY3RJZCddID0ge1xuICAgICAgICAgICAgICAgICRuZTogaWRNYXRjaC5vYmplY3RJZCxcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIFdoYXQgdG8gZG8gaGVyZT8gY2FuJ3QgcmVhbGx5IGNsZWFuIHVwIGV2ZXJ5dGhpbmcuLi5cbiAgICAgICAgICAgICAgcmV0dXJuIGlkTWF0Y2gub2JqZWN0SWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5kYXRhLmFwcElkZW50aWZpZXIpIHtcbiAgICAgICAgICAgICAgZGVsUXVlcnlbJ2FwcElkZW50aWZpZXInXSA9IHRoaXMuZGF0YS5hcHBJZGVudGlmaWVyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jb25maWcuZGF0YWJhc2UuZGVzdHJveSgnX0luc3RhbGxhdGlvbicsIGRlbFF1ZXJ5KS5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgICBpZiAoZXJyLmNvZGUgPT0gUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCkge1xuICAgICAgICAgICAgICAgIC8vIG5vIGRlbGV0aW9ucyB3ZXJlIG1hZGUuIENhbiBiZSBpZ25vcmVkLlxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAvLyByZXRocm93IHRoZSBlcnJvclxuICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gSW4gbm9uLW1lcmdlIHNjZW5hcmlvcywganVzdCByZXR1cm4gdGhlIGluc3RhbGxhdGlvbiBtYXRjaCBpZFxuICAgICAgICAgIHJldHVybiBpZE1hdGNoLm9iamVjdElkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSlcbiAgICAudGhlbihvYmpJZCA9PiB7XG4gICAgICBpZiAob2JqSWQpIHtcbiAgICAgICAgdGhpcy5xdWVyeSA9IHsgb2JqZWN0SWQ6IG9iaklkIH07XG4gICAgICAgIGRlbGV0ZSB0aGlzLmRhdGEub2JqZWN0SWQ7XG4gICAgICAgIGRlbGV0ZSB0aGlzLmRhdGEuY3JlYXRlZEF0O1xuICAgICAgfVxuICAgICAgLy8gVE9ETzogVmFsaWRhdGUgb3BzIChhZGQvcmVtb3ZlIG9uIGNoYW5uZWxzLCAkaW5jIG9uIGJhZGdlLCBldGMuKVxuICAgIH0pO1xuICByZXR1cm4gcHJvbWlzZTtcbn07XG5cbi8vIElmIHdlIHNob3J0LWNpcmN1dGVkIHRoZSBvYmplY3QgcmVzcG9uc2UgLSB0aGVuIHdlIG5lZWQgdG8gbWFrZSBzdXJlIHdlIGV4cGFuZCBhbGwgdGhlIGZpbGVzLFxuLy8gc2luY2UgdGhpcyBtaWdodCBub3QgaGF2ZSBhIHF1ZXJ5LCBtZWFuaW5nIGl0IHdvbid0IHJldHVybiB0aGUgZnVsbCByZXN1bHQgYmFjay5cbi8vIFRPRE86IChubHV0c2Vua28pIFRoaXMgc2hvdWxkIGRpZSB3aGVuIHdlIG1vdmUgdG8gcGVyLWNsYXNzIGJhc2VkIGNvbnRyb2xsZXJzIG9uIF9TZXNzaW9uL19Vc2VyXG5SZXN0V3JpdGUucHJvdG90eXBlLmV4cGFuZEZpbGVzRm9yRXhpc3RpbmdPYmplY3RzID0gZnVuY3Rpb24gKCkge1xuICAvLyBDaGVjayB3aGV0aGVyIHdlIGhhdmUgYSBzaG9ydC1jaXJjdWl0ZWQgcmVzcG9uc2UgLSBvbmx5IHRoZW4gcnVuIGV4cGFuc2lvbi5cbiAgaWYgKHRoaXMucmVzcG9uc2UgJiYgdGhpcy5yZXNwb25zZS5yZXNwb25zZSkge1xuICAgIHRoaXMuY29uZmlnLmZpbGVzQ29udHJvbGxlci5leHBhbmRGaWxlc0luT2JqZWN0KHRoaXMuY29uZmlnLCB0aGlzLnJlc3BvbnNlLnJlc3BvbnNlKTtcbiAgfVxufTtcblxuUmVzdFdyaXRlLnByb3RvdHlwZS5ydW5EYXRhYmFzZU9wZXJhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMucmVzcG9uc2UpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAodGhpcy5jbGFzc05hbWUgPT09ICdfUm9sZScpIHtcbiAgICB0aGlzLmNvbmZpZy5jYWNoZUNvbnRyb2xsZXIucm9sZS5jbGVhcigpO1xuICB9XG5cbiAgaWYgKHRoaXMuY2xhc3NOYW1lID09PSAnX1VzZXInICYmIHRoaXMucXVlcnkgJiYgdGhpcy5hdXRoLmlzVW5hdXRoZW50aWNhdGVkKCkpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5TRVNTSU9OX01JU1NJTkcsXG4gICAgICBgQ2Fubm90IG1vZGlmeSB1c2VyICR7dGhpcy5xdWVyeS5vYmplY3RJZH0uYFxuICAgICk7XG4gIH1cblxuICBpZiAodGhpcy5jbGFzc05hbWUgPT09ICdfUHJvZHVjdCcgJiYgdGhpcy5kYXRhLmRvd25sb2FkKSB7XG4gICAgdGhpcy5kYXRhLmRvd25sb2FkTmFtZSA9IHRoaXMuZGF0YS5kb3dubG9hZC5uYW1lO1xuICB9XG5cbiAgLy8gVE9ETzogQWRkIGJldHRlciBkZXRlY3Rpb24gZm9yIEFDTCwgZW5zdXJpbmcgYSB1c2VyIGNhbid0IGJlIGxvY2tlZCBmcm9tXG4gIC8vICAgICAgIHRoZWlyIG93biB1c2VyIHJlY29yZC5cbiAgaWYgKHRoaXMuZGF0YS5BQ0wgJiYgdGhpcy5kYXRhLkFDTFsnKnVucmVzb2x2ZWQnXSkge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0FDTCwgJ0ludmFsaWQgQUNMLicpO1xuICB9XG5cbiAgaWYgKHRoaXMucXVlcnkpIHtcbiAgICAvLyBGb3JjZSB0aGUgdXNlciB0byBub3QgbG9ja291dFxuICAgIC8vIE1hdGNoZWQgd2l0aCBwYXJzZS5jb21cbiAgICBpZiAodGhpcy5jbGFzc05hbWUgPT09ICdfVXNlcicgJiYgdGhpcy5kYXRhLkFDTCAmJiB0aGlzLmF1dGguaXNNYXN0ZXIgIT09IHRydWUpIHtcbiAgICAgIHRoaXMuZGF0YS5BQ0xbdGhpcy5xdWVyeS5vYmplY3RJZF0gPSB7IHJlYWQ6IHRydWUsIHdyaXRlOiB0cnVlIH07XG4gICAgfVxuICAgIC8vIHVwZGF0ZSBwYXNzd29yZCB0aW1lc3RhbXAgaWYgdXNlciBwYXNzd29yZCBpcyBiZWluZyBjaGFuZ2VkXG4gICAgaWYgKFxuICAgICAgdGhpcy5jbGFzc05hbWUgPT09ICdfVXNlcicgJiZcbiAgICAgIHRoaXMuZGF0YS5faGFzaGVkX3Bhc3N3b3JkICYmXG4gICAgICB0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeSAmJlxuICAgICAgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRBZ2VcbiAgICApIHtcbiAgICAgIHRoaXMuZGF0YS5fcGFzc3dvcmRfY2hhbmdlZF9hdCA9IFBhcnNlLl9lbmNvZGUobmV3IERhdGUoKSk7XG4gICAgfVxuICAgIC8vIElnbm9yZSBjcmVhdGVkQXQgd2hlbiB1cGRhdGVcbiAgICBkZWxldGUgdGhpcy5kYXRhLmNyZWF0ZWRBdDtcblxuICAgIGxldCBkZWZlciA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIC8vIGlmIHBhc3N3b3JkIGhpc3RvcnkgaXMgZW5hYmxlZCB0aGVuIHNhdmUgdGhlIGN1cnJlbnQgcGFzc3dvcmQgdG8gaGlzdG9yeVxuICAgIGlmIChcbiAgICAgIHRoaXMuY2xhc3NOYW1lID09PSAnX1VzZXInICYmXG4gICAgICB0aGlzLmRhdGEuX2hhc2hlZF9wYXNzd29yZCAmJlxuICAgICAgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kgJiZcbiAgICAgIHRoaXMuY29uZmlnLnBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeVxuICAgICkge1xuICAgICAgZGVmZXIgPSB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgICAgICAuZmluZChcbiAgICAgICAgICAnX1VzZXInLFxuICAgICAgICAgIHsgb2JqZWN0SWQ6IHRoaXMub2JqZWN0SWQoKSB9LFxuICAgICAgICAgIHsga2V5czogWydfcGFzc3dvcmRfaGlzdG9yeScsICdfaGFzaGVkX3Bhc3N3b3JkJ10gfVxuICAgICAgICApXG4gICAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCAhPSAxKSB7XG4gICAgICAgICAgICB0aHJvdyB1bmRlZmluZWQ7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHVzZXIgPSByZXN1bHRzWzBdO1xuICAgICAgICAgIGxldCBvbGRQYXNzd29yZHMgPSBbXTtcbiAgICAgICAgICBpZiAodXNlci5fcGFzc3dvcmRfaGlzdG9yeSkge1xuICAgICAgICAgICAgb2xkUGFzc3dvcmRzID0gXy50YWtlKFxuICAgICAgICAgICAgICB1c2VyLl9wYXNzd29yZF9oaXN0b3J5LFxuICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5wYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEhpc3RvcnlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vbi0xIHBhc3N3b3JkcyBnbyBpbnRvIGhpc3RvcnkgaW5jbHVkaW5nIGxhc3QgcGFzc3dvcmRcbiAgICAgICAgICB3aGlsZSAoXG4gICAgICAgICAgICBvbGRQYXNzd29yZHMubGVuZ3RoID4gTWF0aC5tYXgoMCwgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRIaXN0b3J5IC0gMilcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIG9sZFBhc3N3b3Jkcy5zaGlmdCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBvbGRQYXNzd29yZHMucHVzaCh1c2VyLnBhc3N3b3JkKTtcbiAgICAgICAgICB0aGlzLmRhdGEuX3Bhc3N3b3JkX2hpc3RvcnkgPSBvbGRQYXNzd29yZHM7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBkZWZlci50aGVuKCgpID0+IHtcbiAgICAgIC8vIFJ1biBhbiB1cGRhdGVcbiAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZVxuICAgICAgICAudXBkYXRlKFxuICAgICAgICAgIHRoaXMuY2xhc3NOYW1lLFxuICAgICAgICAgIHRoaXMucXVlcnksXG4gICAgICAgICAgdGhpcy5kYXRhLFxuICAgICAgICAgIHRoaXMucnVuT3B0aW9ucyxcbiAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICB0aGlzLnZhbGlkU2NoZW1hQ29udHJvbGxlclxuICAgICAgICApXG4gICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICByZXNwb25zZS51cGRhdGVkQXQgPSB0aGlzLnVwZGF0ZWRBdDtcbiAgICAgICAgICB0aGlzLl91cGRhdGVSZXNwb25zZVdpdGhEYXRhKHJlc3BvbnNlLCB0aGlzLmRhdGEpO1xuICAgICAgICAgIHRoaXMucmVzcG9uc2UgPSB7IHJlc3BvbnNlIH07XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIC8vIFNldCB0aGUgZGVmYXVsdCBBQ0wgYW5kIHBhc3N3b3JkIHRpbWVzdGFtcCBmb3IgdGhlIG5ldyBfVXNlclxuICAgIGlmICh0aGlzLmNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgICAgdmFyIEFDTCA9IHRoaXMuZGF0YS5BQ0w7XG4gICAgICAvLyBkZWZhdWx0IHB1YmxpYyByL3cgQUNMXG4gICAgICBpZiAoIUFDTCkge1xuICAgICAgICBBQ0wgPSB7fTtcbiAgICAgICAgQUNMWycqJ10gPSB7IHJlYWQ6IHRydWUsIHdyaXRlOiBmYWxzZSB9O1xuICAgICAgfVxuICAgICAgLy8gbWFrZSBzdXJlIHRoZSB1c2VyIGlzIG5vdCBsb2NrZWQgZG93blxuICAgICAgQUNMW3RoaXMuZGF0YS5vYmplY3RJZF0gPSB7IHJlYWQ6IHRydWUsIHdyaXRlOiB0cnVlIH07XG4gICAgICB0aGlzLmRhdGEuQUNMID0gQUNMO1xuICAgICAgLy8gcGFzc3dvcmQgdGltZXN0YW1wIHRvIGJlIHVzZWQgd2hlbiBwYXNzd29yZCBleHBpcnkgcG9saWN5IGlzIGVuZm9yY2VkXG4gICAgICBpZiAodGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kgJiYgdGhpcy5jb25maWcucGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRBZ2UpIHtcbiAgICAgICAgdGhpcy5kYXRhLl9wYXNzd29yZF9jaGFuZ2VkX2F0ID0gUGFyc2UuX2VuY29kZShuZXcgRGF0ZSgpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSdW4gYSBjcmVhdGVcbiAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAgIC5jcmVhdGUodGhpcy5jbGFzc05hbWUsIHRoaXMuZGF0YSwgdGhpcy5ydW5PcHRpb25zLCBmYWxzZSwgdGhpcy52YWxpZFNjaGVtYUNvbnRyb2xsZXIpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAodGhpcy5jbGFzc05hbWUgIT09ICdfVXNlcicgfHwgZXJyb3IuY29kZSAhPT0gUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFKSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBRdWljayBjaGVjaywgaWYgd2Ugd2VyZSBhYmxlIHRvIGluZmVyIHRoZSBkdXBsaWNhdGVkIGZpZWxkIG5hbWVcbiAgICAgICAgaWYgKGVycm9yICYmIGVycm9yLnVzZXJJbmZvICYmIGVycm9yLnVzZXJJbmZvLmR1cGxpY2F0ZWRfZmllbGQgPT09ICd1c2VybmFtZScpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5VU0VSTkFNRV9UQUtFTixcbiAgICAgICAgICAgICdBY2NvdW50IGFscmVhZHkgZXhpc3RzIGZvciB0aGlzIHVzZXJuYW1lLidcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVycm9yICYmIGVycm9yLnVzZXJJbmZvICYmIGVycm9yLnVzZXJJbmZvLmR1cGxpY2F0ZWRfZmllbGQgPT09ICdlbWFpbCcpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5FTUFJTF9UQUtFTixcbiAgICAgICAgICAgICdBY2NvdW50IGFscmVhZHkgZXhpc3RzIGZvciB0aGlzIGVtYWlsIGFkZHJlc3MuJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBJZiB0aGlzIHdhcyBhIGZhaWxlZCB1c2VyIGNyZWF0aW9uIGR1ZSB0byB1c2VybmFtZSBvciBlbWFpbCBhbHJlYWR5IHRha2VuLCB3ZSBuZWVkIHRvXG4gICAgICAgIC8vIGNoZWNrIHdoZXRoZXIgaXQgd2FzIHVzZXJuYW1lIG9yIGVtYWlsIGFuZCByZXR1cm4gdGhlIGFwcHJvcHJpYXRlIGVycm9yLlxuICAgICAgICAvLyBGYWxsYmFjayB0byB0aGUgb3JpZ2luYWwgbWV0aG9kXG4gICAgICAgIC8vIFRPRE86IFNlZSBpZiB3ZSBjYW4gbGF0ZXIgZG8gdGhpcyB3aXRob3V0IGFkZGl0aW9uYWwgcXVlcmllcyBieSB1c2luZyBuYW1lZCBpbmRleGVzLlxuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcuZGF0YWJhc2VcbiAgICAgICAgICAuZmluZChcbiAgICAgICAgICAgIHRoaXMuY2xhc3NOYW1lLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB1c2VybmFtZTogdGhpcy5kYXRhLnVzZXJuYW1lLFxuICAgICAgICAgICAgICBvYmplY3RJZDogeyAkbmU6IHRoaXMub2JqZWN0SWQoKSB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHsgbGltaXQ6IDEgfVxuICAgICAgICAgIClcbiAgICAgICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgICAgIGlmIChyZXN1bHRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICAgIFBhcnNlLkVycm9yLlVTRVJOQU1FX1RBS0VOLFxuICAgICAgICAgICAgICAgICdBY2NvdW50IGFscmVhZHkgZXhpc3RzIGZvciB0aGlzIHVzZXJuYW1lLidcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5kYXRhYmFzZS5maW5kKFxuICAgICAgICAgICAgICB0aGlzLmNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgeyBlbWFpbDogdGhpcy5kYXRhLmVtYWlsLCBvYmplY3RJZDogeyAkbmU6IHRoaXMub2JqZWN0SWQoKSB9IH0sXG4gICAgICAgICAgICAgIHsgbGltaXQ6IDEgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuRU1BSUxfVEFLRU4sXG4gICAgICAgICAgICAgICAgJ0FjY291bnQgYWxyZWFkeSBleGlzdHMgZm9yIHRoaXMgZW1haWwgYWRkcmVzcy4nXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLkRVUExJQ0FURV9WQUxVRSxcbiAgICAgICAgICAgICAgJ0EgZHVwbGljYXRlIHZhbHVlIGZvciBhIGZpZWxkIHdpdGggdW5pcXVlIHZhbHVlcyB3YXMgcHJvdmlkZWQnXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgcmVzcG9uc2Uub2JqZWN0SWQgPSB0aGlzLmRhdGEub2JqZWN0SWQ7XG4gICAgICAgIHJlc3BvbnNlLmNyZWF0ZWRBdCA9IHRoaXMuZGF0YS5jcmVhdGVkQXQ7XG5cbiAgICAgICAgaWYgKHRoaXMucmVzcG9uc2VTaG91bGRIYXZlVXNlcm5hbWUpIHtcbiAgICAgICAgICByZXNwb25zZS51c2VybmFtZSA9IHRoaXMuZGF0YS51c2VybmFtZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl91cGRhdGVSZXNwb25zZVdpdGhEYXRhKHJlc3BvbnNlLCB0aGlzLmRhdGEpO1xuICAgICAgICB0aGlzLnJlc3BvbnNlID0ge1xuICAgICAgICAgIHN0YXR1czogMjAxLFxuICAgICAgICAgIHJlc3BvbnNlLFxuICAgICAgICAgIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKCksXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgfVxufTtcblxuLy8gUmV0dXJucyBub3RoaW5nIC0gZG9lc24ndCB3YWl0IGZvciB0aGUgdHJpZ2dlci5cblJlc3RXcml0ZS5wcm90b3R5cGUucnVuQWZ0ZXJTYXZlVHJpZ2dlciA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKCF0aGlzLnJlc3BvbnNlIHx8ICF0aGlzLnJlc3BvbnNlLnJlc3BvbnNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gQXZvaWQgZG9pbmcgYW55IHNldHVwIGZvciB0cmlnZ2VycyBpZiB0aGVyZSBpcyBubyAnYWZ0ZXJTYXZlJyB0cmlnZ2VyIGZvciB0aGlzIGNsYXNzLlxuICBjb25zdCBoYXNBZnRlclNhdmVIb29rID0gdHJpZ2dlcnMudHJpZ2dlckV4aXN0cyhcbiAgICB0aGlzLmNsYXNzTmFtZSxcbiAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlclNhdmUsXG4gICAgdGhpcy5jb25maWcuYXBwbGljYXRpb25JZFxuICApO1xuICBjb25zdCBoYXNMaXZlUXVlcnkgPSB0aGlzLmNvbmZpZy5saXZlUXVlcnlDb250cm9sbGVyLmhhc0xpdmVRdWVyeSh0aGlzLmNsYXNzTmFtZSk7XG4gIGlmICghaGFzQWZ0ZXJTYXZlSG9vayAmJiAhaGFzTGl2ZVF1ZXJ5KSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgdmFyIGV4dHJhRGF0YSA9IHsgY2xhc3NOYW1lOiB0aGlzLmNsYXNzTmFtZSB9O1xuICBpZiAodGhpcy5xdWVyeSAmJiB0aGlzLnF1ZXJ5Lm9iamVjdElkKSB7XG4gICAgZXh0cmFEYXRhLm9iamVjdElkID0gdGhpcy5xdWVyeS5vYmplY3RJZDtcbiAgfVxuXG4gIC8vIEJ1aWxkIHRoZSBvcmlnaW5hbCBvYmplY3QsIHdlIG9ubHkgZG8gdGhpcyBmb3IgYSB1cGRhdGUgd3JpdGUuXG4gIGxldCBvcmlnaW5hbE9iamVjdDtcbiAgaWYgKHRoaXMucXVlcnkgJiYgdGhpcy5xdWVyeS5vYmplY3RJZCkge1xuICAgIG9yaWdpbmFsT2JqZWN0ID0gdHJpZ2dlcnMuaW5mbGF0ZShleHRyYURhdGEsIHRoaXMub3JpZ2luYWxEYXRhKTtcbiAgfVxuXG4gIC8vIEJ1aWxkIHRoZSBpbmZsYXRlZCBvYmplY3QsIGRpZmZlcmVudCBmcm9tIGJlZm9yZVNhdmUsIG9yaWdpbmFsRGF0YSBpcyBub3QgZW1wdHlcbiAgLy8gc2luY2UgZGV2ZWxvcGVycyBjYW4gY2hhbmdlIGRhdGEgaW4gdGhlIGJlZm9yZVNhdmUuXG4gIGNvbnN0IHVwZGF0ZWRPYmplY3QgPSB0aGlzLmJ1aWxkVXBkYXRlZE9iamVjdChleHRyYURhdGEpO1xuICB1cGRhdGVkT2JqZWN0Ll9oYW5kbGVTYXZlUmVzcG9uc2UodGhpcy5yZXNwb25zZS5yZXNwb25zZSwgdGhpcy5yZXNwb25zZS5zdGF0dXMgfHwgMjAwKTtcblxuICB0aGlzLmNvbmZpZy5kYXRhYmFzZS5sb2FkU2NoZW1hKCkudGhlbihzY2hlbWFDb250cm9sbGVyID0+IHtcbiAgICAvLyBOb3RpZml5IExpdmVRdWVyeVNlcnZlciBpZiBwb3NzaWJsZVxuICAgIGNvbnN0IHBlcm1zID0gc2NoZW1hQ29udHJvbGxlci5nZXRDbGFzc0xldmVsUGVybWlzc2lvbnModXBkYXRlZE9iamVjdC5jbGFzc05hbWUpO1xuICAgIHRoaXMuY29uZmlnLmxpdmVRdWVyeUNvbnRyb2xsZXIub25BZnRlclNhdmUoXG4gICAgICB1cGRhdGVkT2JqZWN0LmNsYXNzTmFtZSxcbiAgICAgIHVwZGF0ZWRPYmplY3QsXG4gICAgICBvcmlnaW5hbE9iamVjdCxcbiAgICAgIHBlcm1zXG4gICAgKTtcbiAgfSk7XG5cbiAgLy8gUnVuIGFmdGVyU2F2ZSB0cmlnZ2VyXG4gIHJldHVybiB0cmlnZ2Vyc1xuICAgIC5tYXliZVJ1blRyaWdnZXIoXG4gICAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlclNhdmUsXG4gICAgICB0aGlzLmF1dGgsXG4gICAgICB1cGRhdGVkT2JqZWN0LFxuICAgICAgb3JpZ2luYWxPYmplY3QsXG4gICAgICB0aGlzLmNvbmZpZyxcbiAgICAgIHRoaXMuY29udGV4dFxuICAgIClcbiAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgaWYgKHJlc3VsdCAmJiB0eXBlb2YgcmVzdWx0ID09PSAnb2JqZWN0Jykge1xuICAgICAgICB0aGlzLnJlc3BvbnNlLnJlc3BvbnNlID0gcmVzdWx0O1xuICAgICAgfVxuICAgIH0pXG4gICAgLmNhdGNoKGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgIGxvZ2dlci53YXJuKCdhZnRlclNhdmUgY2F1Z2h0IGFuIGVycm9yJywgZXJyKTtcbiAgICB9KTtcbn07XG5cbi8vIEEgaGVscGVyIHRvIGZpZ3VyZSBvdXQgd2hhdCBsb2NhdGlvbiB0aGlzIG9wZXJhdGlvbiBoYXBwZW5zIGF0LlxuUmVzdFdyaXRlLnByb3RvdHlwZS5sb2NhdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG1pZGRsZSA9IHRoaXMuY2xhc3NOYW1lID09PSAnX1VzZXInID8gJy91c2Vycy8nIDogJy9jbGFzc2VzLycgKyB0aGlzLmNsYXNzTmFtZSArICcvJztcbiAgY29uc3QgbW91bnQgPSB0aGlzLmNvbmZpZy5tb3VudCB8fCB0aGlzLmNvbmZpZy5zZXJ2ZXJVUkw7XG4gIHJldHVybiBtb3VudCArIG1pZGRsZSArIHRoaXMuZGF0YS5vYmplY3RJZDtcbn07XG5cbi8vIEEgaGVscGVyIHRvIGdldCB0aGUgb2JqZWN0IGlkIGZvciB0aGlzIG9wZXJhdGlvbi5cbi8vIEJlY2F1c2UgaXQgY291bGQgYmUgZWl0aGVyIG9uIHRoZSBxdWVyeSBvciBvbiB0aGUgZGF0YVxuUmVzdFdyaXRlLnByb3RvdHlwZS5vYmplY3RJZCA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIHRoaXMuZGF0YS5vYmplY3RJZCB8fCB0aGlzLnF1ZXJ5Lm9iamVjdElkO1xufTtcblxuLy8gUmV0dXJucyBhIGNvcHkgb2YgdGhlIGRhdGEgYW5kIGRlbGV0ZSBiYWQga2V5cyAoX2F1dGhfZGF0YSwgX2hhc2hlZF9wYXNzd29yZC4uLilcblJlc3RXcml0ZS5wcm90b3R5cGUuc2FuaXRpemVkRGF0YSA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgZGF0YSA9IE9iamVjdC5rZXlzKHRoaXMuZGF0YSkucmVkdWNlKChkYXRhLCBrZXkpID0+IHtcbiAgICAvLyBSZWdleHAgY29tZXMgZnJvbSBQYXJzZS5PYmplY3QucHJvdG90eXBlLnZhbGlkYXRlXG4gICAgaWYgKCEvXltBLVphLXpdWzAtOUEtWmEtel9dKiQvLnRlc3Qoa2V5KSkge1xuICAgICAgZGVsZXRlIGRhdGFba2V5XTtcbiAgICB9XG4gICAgcmV0dXJuIGRhdGE7XG4gIH0sIGRlZXBjb3B5KHRoaXMuZGF0YSkpO1xuICByZXR1cm4gUGFyc2UuX2RlY29kZSh1bmRlZmluZWQsIGRhdGEpO1xufTtcblxuLy8gUmV0dXJucyBhbiB1cGRhdGVkIGNvcHkgb2YgdGhlIG9iamVjdFxuUmVzdFdyaXRlLnByb3RvdHlwZS5idWlsZFVwZGF0ZWRPYmplY3QgPSBmdW5jdGlvbiAoZXh0cmFEYXRhKSB7XG4gIGNvbnN0IHVwZGF0ZWRPYmplY3QgPSB0cmlnZ2Vycy5pbmZsYXRlKGV4dHJhRGF0YSwgdGhpcy5vcmlnaW5hbERhdGEpO1xuICBPYmplY3Qua2V5cyh0aGlzLmRhdGEpLnJlZHVjZShmdW5jdGlvbiAoZGF0YSwga2V5KSB7XG4gICAgaWYgKGtleS5pbmRleE9mKCcuJykgPiAwKSB7XG4gICAgICBpZiAodHlwZW9mIGRhdGFba2V5XS5fX29wID09PSAnc3RyaW5nJykge1xuICAgICAgICB1cGRhdGVkT2JqZWN0LnNldChrZXksIGRhdGFba2V5XSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBzdWJkb2N1bWVudCBrZXkgd2l0aCBkb3Qgbm90YXRpb24geyAneC55JzogdiB9ID0+IHsgJ3gnOiB7ICd5JyA6IHYgfSB9KVxuICAgICAgICBjb25zdCBzcGxpdHRlZEtleSA9IGtleS5zcGxpdCgnLicpO1xuICAgICAgICBjb25zdCBwYXJlbnRQcm9wID0gc3BsaXR0ZWRLZXlbMF07XG4gICAgICAgIGxldCBwYXJlbnRWYWwgPSB1cGRhdGVkT2JqZWN0LmdldChwYXJlbnRQcm9wKTtcbiAgICAgICAgaWYgKHR5cGVvZiBwYXJlbnRWYWwgIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgcGFyZW50VmFsID0ge307XG4gICAgICAgIH1cbiAgICAgICAgcGFyZW50VmFsW3NwbGl0dGVkS2V5WzFdXSA9IGRhdGFba2V5XTtcbiAgICAgICAgdXBkYXRlZE9iamVjdC5zZXQocGFyZW50UHJvcCwgcGFyZW50VmFsKTtcbiAgICAgIH1cbiAgICAgIGRlbGV0ZSBkYXRhW2tleV07XG4gICAgfVxuICAgIHJldHVybiBkYXRhO1xuICB9LCBkZWVwY29weSh0aGlzLmRhdGEpKTtcblxuICB1cGRhdGVkT2JqZWN0LnNldCh0aGlzLnNhbml0aXplZERhdGEoKSk7XG4gIHJldHVybiB1cGRhdGVkT2JqZWN0O1xufTtcblxuUmVzdFdyaXRlLnByb3RvdHlwZS5jbGVhblVzZXJBdXRoRGF0YSA9IGZ1bmN0aW9uICgpIHtcbiAgaWYgKHRoaXMucmVzcG9uc2UgJiYgdGhpcy5yZXNwb25zZS5yZXNwb25zZSAmJiB0aGlzLmNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIGNvbnN0IHVzZXIgPSB0aGlzLnJlc3BvbnNlLnJlc3BvbnNlO1xuICAgIGlmICh1c2VyLmF1dGhEYXRhKSB7XG4gICAgICBPYmplY3Qua2V5cyh1c2VyLmF1dGhEYXRhKS5mb3JFYWNoKHByb3ZpZGVyID0+IHtcbiAgICAgICAgaWYgKHVzZXIuYXV0aERhdGFbcHJvdmlkZXJdID09PSBudWxsKSB7XG4gICAgICAgICAgZGVsZXRlIHVzZXIuYXV0aERhdGFbcHJvdmlkZXJdO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGlmIChPYmplY3Qua2V5cyh1c2VyLmF1dGhEYXRhKS5sZW5ndGggPT0gMCkge1xuICAgICAgICBkZWxldGUgdXNlci5hdXRoRGF0YTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn07XG5cblJlc3RXcml0ZS5wcm90b3R5cGUuX3VwZGF0ZVJlc3BvbnNlV2l0aERhdGEgPSBmdW5jdGlvbiAocmVzcG9uc2UsIGRhdGEpIHtcbiAgaWYgKF8uaXNFbXB0eSh0aGlzLnN0b3JhZ2UuZmllbGRzQ2hhbmdlZEJ5VHJpZ2dlcikpIHtcbiAgICByZXR1cm4gcmVzcG9uc2U7XG4gIH1cbiAgY29uc3QgY2xpZW50U3VwcG9ydHNEZWxldGUgPSBDbGllbnRTREsuc3VwcG9ydHNGb3J3YXJkRGVsZXRlKHRoaXMuY2xpZW50U0RLKTtcbiAgdGhpcy5zdG9yYWdlLmZpZWxkc0NoYW5nZWRCeVRyaWdnZXIuZm9yRWFjaChmaWVsZE5hbWUgPT4ge1xuICAgIGNvbnN0IGRhdGFWYWx1ZSA9IGRhdGFbZmllbGROYW1lXTtcblxuICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3BvbnNlLCBmaWVsZE5hbWUpKSB7XG4gICAgICByZXNwb25zZVtmaWVsZE5hbWVdID0gZGF0YVZhbHVlO1xuICAgIH1cblxuICAgIC8vIFN0cmlwcyBvcGVyYXRpb25zIGZyb20gcmVzcG9uc2VzXG4gICAgaWYgKHJlc3BvbnNlW2ZpZWxkTmFtZV0gJiYgcmVzcG9uc2VbZmllbGROYW1lXS5fX29wKSB7XG4gICAgICBkZWxldGUgcmVzcG9uc2VbZmllbGROYW1lXTtcbiAgICAgIGlmIChjbGllbnRTdXBwb3J0c0RlbGV0ZSAmJiBkYXRhVmFsdWUuX19vcCA9PSAnRGVsZXRlJykge1xuICAgICAgICByZXNwb25zZVtmaWVsZE5hbWVdID0gZGF0YVZhbHVlO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHJldHVybiByZXNwb25zZTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFJlc3RXcml0ZTtcbm1vZHVsZS5leHBvcnRzID0gUmVzdFdyaXRlO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/AggregateRouter.js b/lib/Routers/AggregateRouter.js deleted file mode 100644 index 8529b49ea8..0000000000 --- a/lib/Routers/AggregateRouter.js +++ /dev/null @@ -1,153 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.AggregateRouter = void 0; - -var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); - -var _rest = _interopRequireDefault(require("../rest")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -var _node = _interopRequireDefault(require("parse/node")); - -var _UsersRouter = _interopRequireDefault(require("./UsersRouter")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const BASE_KEYS = ['where', 'distinct', 'pipeline', 'hint', 'explain']; -const PIPELINE_KEYS = ['addFields', 'bucket', 'bucketAuto', 'collStats', 'count', 'currentOp', 'facet', 'geoNear', 'graphLookup', 'group', 'indexStats', 'limit', 'listLocalSessions', 'listSessions', 'lookup', 'match', 'out', 'project', 'redact', 'replaceRoot', 'sample', 'skip', 'sort', 'sortByCount', 'unwind']; -const ALLOWED_KEYS = [...BASE_KEYS, ...PIPELINE_KEYS]; - -class AggregateRouter extends _ClassesRouter.default { - handleFind(req) { - const body = Object.assign(req.body, _ClassesRouter.default.JSONFromQuery(req.query)); - const options = {}; - - if (body.distinct) { - options.distinct = String(body.distinct); - } - - if (body.hint) { - options.hint = body.hint; - delete body.hint; - } - - if (body.explain) { - options.explain = body.explain; - delete body.explain; - } - - if (body.readPreference) { - options.readPreference = body.readPreference; - delete body.readPreference; - } - - options.pipeline = AggregateRouter.getPipeline(body); - - if (typeof body.where === 'string') { - body.where = JSON.parse(body.where); - } - - return _rest.default.find(req.config, req.auth, this.className(req), body.where, options, req.info.clientSDK, req.info.context).then(response => { - for (const result of response.results) { - if (typeof result === 'object') { - _UsersRouter.default.removeHiddenProperties(result); - } - } - - return { - response - }; - }); - } - /* Builds a pipeline from the body. Originally the body could be passed as a single object, - * and now we support many options - * - * Array - * - * body: [{ - * group: { objectId: '$name' }, - * }] - * - * Object - * - * body: { - * group: { objectId: '$name' }, - * } - * - * - * Pipeline Operator with an Array or an Object - * - * body: { - * pipeline: { - * group: { objectId: '$name' }, - * } - * } - * - */ - - - static getPipeline(body) { - let pipeline = body.pipeline || body; - - if (!Array.isArray(pipeline)) { - pipeline = Object.keys(pipeline).map(key => { - return { - [key]: pipeline[key] - }; - }); - } - - return pipeline.map(stage => { - const keys = Object.keys(stage); - - if (keys.length != 1) { - throw new Error(`Pipeline stages should only have one key found ${keys.join(', ')}`); - } - - return AggregateRouter.transformStage(keys[0], stage); - }); - } - - static transformStage(stageName, stage) { - if (ALLOWED_KEYS.indexOf(stageName) === -1) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Invalid parameter for query: ${stageName}`); - } - - if (stageName === 'group') { - if (Object.prototype.hasOwnProperty.call(stage[stageName], '_id')) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Invalid parameter for query: group. Please use objectId instead of _id`); - } - - if (!Object.prototype.hasOwnProperty.call(stage[stageName], 'objectId')) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Invalid parameter for query: group. objectId is required`); - } - - stage[stageName]._id = stage[stageName].objectId; - delete stage[stageName].objectId; - } - - return { - [`$${stageName}`]: stage[stageName] - }; - } - - mountRoutes() { - this.route('GET', '/aggregate/:className', middleware.promiseEnforceMasterKeyAccess, req => { - return this.handleFind(req); - }); - } - -} - -exports.AggregateRouter = AggregateRouter; -var _default = AggregateRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0FnZ3JlZ2F0ZVJvdXRlci5qcyJdLCJuYW1lcyI6WyJCQVNFX0tFWVMiLCJQSVBFTElORV9LRVlTIiwiQUxMT1dFRF9LRVlTIiwiQWdncmVnYXRlUm91dGVyIiwiQ2xhc3Nlc1JvdXRlciIsImhhbmRsZUZpbmQiLCJyZXEiLCJib2R5IiwiT2JqZWN0IiwiYXNzaWduIiwiSlNPTkZyb21RdWVyeSIsInF1ZXJ5Iiwib3B0aW9ucyIsImRpc3RpbmN0IiwiU3RyaW5nIiwiaGludCIsImV4cGxhaW4iLCJyZWFkUHJlZmVyZW5jZSIsInBpcGVsaW5lIiwiZ2V0UGlwZWxpbmUiLCJ3aGVyZSIsIkpTT04iLCJwYXJzZSIsInJlc3QiLCJmaW5kIiwiY29uZmlnIiwiYXV0aCIsImNsYXNzTmFtZSIsImluZm8iLCJjbGllbnRTREsiLCJjb250ZXh0IiwidGhlbiIsInJlc3BvbnNlIiwicmVzdWx0IiwicmVzdWx0cyIsIlVzZXJzUm91dGVyIiwicmVtb3ZlSGlkZGVuUHJvcGVydGllcyIsIkFycmF5IiwiaXNBcnJheSIsImtleXMiLCJtYXAiLCJrZXkiLCJzdGFnZSIsImxlbmd0aCIsIkVycm9yIiwiam9pbiIsInRyYW5zZm9ybVN0YWdlIiwic3RhZ2VOYW1lIiwiaW5kZXhPZiIsIlBhcnNlIiwiSU5WQUxJRF9RVUVSWSIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIl9pZCIsIm9iamVjdElkIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsIm1pZGRsZXdhcmUiLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVBLE1BQU1BLFNBQVMsR0FBRyxDQUFDLE9BQUQsRUFBVSxVQUFWLEVBQXNCLFVBQXRCLEVBQWtDLE1BQWxDLEVBQTBDLFNBQTFDLENBQWxCO0FBRUEsTUFBTUMsYUFBYSxHQUFHLENBQ3BCLFdBRG9C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dkMsTUFBTSxDQUFDMkMsU0FBUCxDQUFpQkMsY0FBakIsQ0FBZ0NDLElBQWhDLENBQXFDWCxLQUFLLENBQUNLLFNBQUQsQ0FBMUMsRUFBdUQsS0FBdkQsQ0FBSixFQUFtRTtBQUNqRSxjQUFNLElBQUlFLGNBQU1MLEtBQVYsQ0FDSkssY0FBTUwsS0FBTixDQUFZTSxhQURSLEVBRUgsd0VBRkcsQ0FBTjtBQUlEOztBQUNELFVBQUksQ0FBQzFDLE1BQU0sQ0FBQzJDLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUFxQ1gsS0FBSyxDQUFDSyxTQUFELENBQTFDLEVBQXVELFVBQXZELENBQUwsRUFBeUU7QUFDdkUsY0FBTSxJQUFJRSxjQUFNTCxLQUFWLENBQ0pLLGNBQU1MLEtBQU4sQ0FBWU0sYUFEUixFQUVILDBEQUZHLENBQU47QUFJRDs7QUFDRFIsTUFBQUEsS0FBSyxDQUFDSyxTQUFELENBQUwsQ0FBaUJPLEdBQWpCLEdBQXVCWixLQUFLLENBQUNLLFNBQUQsQ0FBTCxDQUFpQlEsUUFBeEM7QUFDQSxhQUFPYixLQUFLLENBQUNLLFNBQUQsQ0FBTCxDQUFpQlEsUUFBeEI7QUFDRDs7QUFDRCxXQUFPO0FBQUUsT0FBRSxJQUFHUixTQUFVLEVBQWYsR0FBbUJMLEtBQUssQ0FBQ0ssU0FBRDtBQUExQixLQUFQO0FBQ0Q7O0FBRURTLEVBQUFBLFdBQVcsR0FBRztBQUNaLFNBQUtDLEtBQUwsQ0FBVyxLQUFYLEVBQWtCLHVCQUFsQixFQUEyQ0MsVUFBVSxDQUFDQyw2QkFBdEQsRUFBcUZyRCxHQUFHLElBQUk7QUFDMUYsYUFBTyxLQUFLRCxVQUFMLENBQWdCQyxHQUFoQixDQUFQO0FBQ0QsS0FGRDtBQUdEOztBQWhIZ0Q7OztlQW1IcENILGUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQ2xhc3Nlc1JvdXRlciBmcm9tICcuL0NsYXNzZXNSb3V0ZXInO1xuaW1wb3J0IHJlc3QgZnJvbSAnLi4vcmVzdCc7XG5pbXBvcnQgKiBhcyBtaWRkbGV3YXJlIGZyb20gJy4uL21pZGRsZXdhcmVzJztcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBVc2Vyc1JvdXRlciBmcm9tICcuL1VzZXJzUm91dGVyJztcblxuY29uc3QgQkFTRV9LRVlTID0gWyd3aGVyZScsICdkaXN0aW5jdCcsICdwaXBlbGluZScsICdoaW50JywgJ2V4cGxhaW4nXTtcblxuY29uc3QgUElQRUxJTkVfS0VZUyA9IFtcbiAgJ2FkZEZpZWxkcycsXG4gICdidWNrZXQnLFxuICAnYnVja2V0QXV0bycsXG4gICdjb2xsU3RhdHMnLFxuICAnY291bnQnLFxuICAnY3VycmVudE9wJyxcbiAgJ2ZhY2V0JyxcbiAgJ2dlb05lYXInLFxuICAnZ3JhcGhMb29rdXAnLFxuICAnZ3JvdXAnLFxuICAnaW5kZXhTdGF0cycsXG4gICdsaW1pdCcsXG4gICdsaXN0TG9jYWxTZXNzaW9ucycsXG4gICdsaXN0U2Vzc2lvbnMnLFxuICAnbG9va3VwJyxcbiAgJ21hdGNoJyxcbiAgJ291dCcsXG4gICdwcm9qZWN0JyxcbiAgJ3JlZGFjdCcsXG4gICdyZXBsYWNlUm9vdCcsXG4gICdzYW1wbGUnLFxuICAnc2tpcCcsXG4gICdzb3J0JyxcbiAgJ3NvcnRCeUNvdW50JyxcbiAgJ3Vud2luZCcsXG5dO1xuXG5jb25zdCBBTExPV0VEX0tFWVMgPSBbLi4uQkFTRV9LRVlTLCAuLi5QSVBFTElORV9LRVlTXTtcblxuZXhwb3J0IGNsYXNzIEFnZ3JlZ2F0ZVJvdXRlciBleHRlbmRzIENsYXNzZXNSb3V0ZXIge1xuICBoYW5kbGVGaW5kKHJlcSkge1xuICAgIGNvbnN0IGJvZHkgPSBPYmplY3QuYXNzaWduKHJlcS5ib2R5LCBDbGFzc2VzUm91dGVyLkpTT05Gcm9tUXVlcnkocmVxLnF1ZXJ5KSk7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHt9O1xuICAgIGlmIChib2R5LmRpc3RpbmN0KSB7XG4gICAgICBvcHRpb25zLmRpc3RpbmN0ID0gU3RyaW5nKGJvZHkuZGlzdGluY3QpO1xuICAgIH1cbiAgICBpZiAoYm9keS5oaW50KSB7XG4gICAgICBvcHRpb25zLmhpbnQgPSBib2R5LmhpbnQ7XG4gICAgICBkZWxldGUgYm9keS5oaW50O1xuICAgIH1cbiAgICBpZiAoYm9keS5leHBsYWluKSB7XG4gICAgICBvcHRpb25zLmV4cGxhaW4gPSBib2R5LmV4cGxhaW47XG4gICAgICBkZWxldGUgYm9keS5leHBsYWluO1xuICAgIH1cbiAgICBpZiAoYm9keS5yZWFkUHJlZmVyZW5jZSkge1xuICAgICAgb3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IGJvZHkucmVhZFByZWZlcmVuY2U7XG4gICAgICBkZWxldGUgYm9keS5yZWFkUHJlZmVyZW5jZTtcbiAgICB9XG4gICAgb3B0aW9ucy5waXBlbGluZSA9IEFnZ3JlZ2F0ZVJvdXRlci5nZXRQaXBlbGluZShib2R5KTtcbiAgICBpZiAodHlwZW9mIGJvZHkud2hlcmUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBib2R5LndoZXJlID0gSlNPTi5wYXJzZShib2R5LndoZXJlKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3RcbiAgICAgIC5maW5kKFxuICAgICAgICByZXEuY29uZmlnLFxuICAgICAgICByZXEuYXV0aCxcbiAgICAgICAgdGhpcy5jbGFzc05hbWUocmVxKSxcbiAgICAgICAgYm9keS53aGVyZSxcbiAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgcmVxLmluZm8uY2xpZW50U0RLLFxuICAgICAgICByZXEuaW5mby5jb250ZXh0XG4gICAgICApXG4gICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIHJlc3BvbnNlLnJlc3VsdHMpIHtcbiAgICAgICAgICBpZiAodHlwZW9mIHJlc3VsdCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIFVzZXJzUm91dGVyLnJlbW92ZUhpZGRlblByb3BlcnRpZXMocmVzdWx0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2UgfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyogQnVpbGRzIGEgcGlwZWxpbmUgZnJvbSB0aGUgYm9keS4gT3JpZ2luYWxseSB0aGUgYm9keSBjb3VsZCBiZSBwYXNzZWQgYXMgYSBzaW5nbGUgb2JqZWN0LFxuICAgKiBhbmQgbm93IHdlIHN1cHBvcnQgbWFueSBvcHRpb25zXG4gICAqXG4gICAqIEFycmF5XG4gICAqXG4gICAqIGJvZHk6IFt7XG4gICAqICAgZ3JvdXA6IHsgb2JqZWN0SWQ6ICckbmFtZScgfSxcbiAgICogfV1cbiAgICpcbiAgICogT2JqZWN0XG4gICAqXG4gICAqIGJvZHk6IHtcbiAgICogICBncm91cDogeyBvYmplY3RJZDogJyRuYW1lJyB9LFxuICAgKiB9XG4gICAqXG4gICAqXG4gICAqIFBpcGVsaW5lIE9wZXJhdG9yIHdpdGggYW4gQXJyYXkgb3IgYW4gT2JqZWN0XG4gICAqXG4gICAqIGJvZHk6IHtcbiAgICogICBwaXBlbGluZToge1xuICAgKiAgICAgZ3JvdXA6IHsgb2JqZWN0SWQ6ICckbmFtZScgfSxcbiAgICogICB9XG4gICAqIH1cbiAgICpcbiAgICovXG4gIHN0YXRpYyBnZXRQaXBlbGluZShib2R5KSB7XG4gICAgbGV0IHBpcGVsaW5lID0gYm9keS5waXBlbGluZSB8fCBib2R5O1xuICAgIGlmICghQXJyYXkuaXNBcnJheShwaXBlbGluZSkpIHtcbiAgICAgIHBpcGVsaW5lID0gT2JqZWN0LmtleXMocGlwZWxpbmUpLm1hcChrZXkgPT4ge1xuICAgICAgICByZXR1cm4geyBba2V5XTogcGlwZWxpbmVba2V5XSB9O1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBpcGVsaW5lLm1hcChzdGFnZSA9PiB7XG4gICAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoc3RhZ2UpO1xuICAgICAgaWYgKGtleXMubGVuZ3RoICE9IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBQaXBlbGluZSBzdGFnZXMgc2hvdWxkIG9ubHkgaGF2ZSBvbmUga2V5IGZvdW5kICR7a2V5cy5qb2luKCcsICcpfWApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIEFnZ3JlZ2F0ZVJvdXRlci50cmFuc2Zvcm1TdGFnZShrZXlzWzBdLCBzdGFnZSk7XG4gICAgfSk7XG4gIH1cblxuICBzdGF0aWMgdHJhbnNmb3JtU3RhZ2Uoc3RhZ2VOYW1lLCBzdGFnZSkge1xuICAgIGlmIChBTExPV0VEX0tFWVMuaW5kZXhPZihzdGFnZU5hbWUpID09PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksIGBJbnZhbGlkIHBhcmFtZXRlciBmb3IgcXVlcnk6ICR7c3RhZ2VOYW1lfWApO1xuICAgIH1cbiAgICBpZiAoc3RhZ2VOYW1lID09PSAnZ3JvdXAnKSB7XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHN0YWdlW3N0YWdlTmFtZV0sICdfaWQnKSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSxcbiAgICAgICAgICBgSW52YWxpZCBwYXJhbWV0ZXIgZm9yIHF1ZXJ5OiBncm91cC4gUGxlYXNlIHVzZSBvYmplY3RJZCBpbnN0ZWFkIG9mIF9pZGBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHN0YWdlW3N0YWdlTmFtZV0sICdvYmplY3RJZCcpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLFxuICAgICAgICAgIGBJbnZhbGlkIHBhcmFtZXRlciBmb3IgcXVlcnk6IGdyb3VwLiBvYmplY3RJZCBpcyByZXF1aXJlZGBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHN0YWdlW3N0YWdlTmFtZV0uX2lkID0gc3RhZ2Vbc3RhZ2VOYW1lXS5vYmplY3RJZDtcbiAgICAgIGRlbGV0ZSBzdGFnZVtzdGFnZU5hbWVdLm9iamVjdElkO1xuICAgIH1cbiAgICByZXR1cm4geyBbYCQke3N0YWdlTmFtZX1gXTogc3RhZ2Vbc3RhZ2VOYW1lXSB9O1xuICB9XG5cbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9hZ2dyZWdhdGUvOmNsYXNzTmFtZScsIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVGaW5kKHJlcSk7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQWdncmVnYXRlUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/AnalyticsRouter.js b/lib/Routers/AnalyticsRouter.js deleted file mode 100644 index d37290b37f..0000000000 --- a/lib/Routers/AnalyticsRouter.js +++ /dev/null @@ -1,32 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.AnalyticsRouter = void 0; - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// AnalyticsRouter.js -function appOpened(req) { - const analyticsController = req.config.analyticsController; - return analyticsController.appOpened(req); -} - -function trackEvent(req) { - const analyticsController = req.config.analyticsController; - return analyticsController.trackEvent(req); -} - -class AnalyticsRouter extends _PromiseRouter.default { - mountRoutes() { - this.route('POST', '/events/AppOpened', appOpened); - this.route('POST', '/events/:eventName', trackEvent); - } - -} - -exports.AnalyticsRouter = AnalyticsRouter; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0FuYWx5dGljc1JvdXRlci5qcyJdLCJuYW1lcyI6WyJhcHBPcGVuZWQiLCJyZXEiLCJhbmFseXRpY3NDb250cm9sbGVyIiwiY29uZmlnIiwidHJhY2tFdmVudCIsIkFuYWx5dGljc1JvdXRlciIsIlByb21pc2VSb3V0ZXIiLCJtb3VudFJvdXRlcyIsInJvdXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7Ozs7QUFEQTtBQUdBLFNBQVNBLFNBQVQsQ0FBbUJDLEdBQW5CLEVBQXdCO0FBQ3RCLFFBQU1DLG1CQUFtQixHQUFHRCxHQUFHLENBQUNFLE1BQUosQ0FBV0QsbUJBQXZDO0FBQ0EsU0FBT0EsbUJBQW1CLENBQUNGLFNBQXBCLENBQThCQyxHQUE5QixDQUFQO0FBQ0Q7O0FBRUQsU0FBU0csVUFBVCxDQUFvQkgsR0FBcEIsRUFBeUI7QUFDdkIsUUFBTUMsbUJBQW1CLEdBQUdELEdBQUcsQ0FBQ0UsTUFBSixDQUFXRCxtQkFBdkM7QUFDQSxTQUFPQSxtQkFBbUIsQ0FBQ0UsVUFBcEIsQ0FBK0JILEdBQS9CLENBQVA7QUFDRDs7QUFFTSxNQUFNSSxlQUFOLFNBQThCQyxzQkFBOUIsQ0FBNEM7QUFDakRDLEVBQUFBLFdBQVcsR0FBRztBQUNaLFNBQUtDLEtBQUwsQ0FBVyxNQUFYLEVBQW1CLG1CQUFuQixFQUF3Q1IsU0FBeEM7QUFDQSxTQUFLUSxLQUFMLENBQVcsTUFBWCxFQUFtQixvQkFBbkIsRUFBeUNKLFVBQXpDO0FBQ0Q7O0FBSmdEIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQW5hbHl0aWNzUm91dGVyLmpzXG5pbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuLi9Qcm9taXNlUm91dGVyJztcblxuZnVuY3Rpb24gYXBwT3BlbmVkKHJlcSkge1xuICBjb25zdCBhbmFseXRpY3NDb250cm9sbGVyID0gcmVxLmNvbmZpZy5hbmFseXRpY3NDb250cm9sbGVyO1xuICByZXR1cm4gYW5hbHl0aWNzQ29udHJvbGxlci5hcHBPcGVuZWQocmVxKTtcbn1cblxuZnVuY3Rpb24gdHJhY2tFdmVudChyZXEpIHtcbiAgY29uc3QgYW5hbHl0aWNzQ29udHJvbGxlciA9IHJlcS5jb25maWcuYW5hbHl0aWNzQ29udHJvbGxlcjtcbiAgcmV0dXJuIGFuYWx5dGljc0NvbnRyb2xsZXIudHJhY2tFdmVudChyZXEpO1xufVxuXG5leHBvcnQgY2xhc3MgQW5hbHl0aWNzUm91dGVyIGV4dGVuZHMgUHJvbWlzZVJvdXRlciB7XG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL2V2ZW50cy9BcHBPcGVuZWQnLCBhcHBPcGVuZWQpO1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL2V2ZW50cy86ZXZlbnROYW1lJywgdHJhY2tFdmVudCk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/AudiencesRouter.js b/lib/Routers/AudiencesRouter.js deleted file mode 100644 index 684d3e42a2..0000000000 --- a/lib/Routers/AudiencesRouter.js +++ /dev/null @@ -1,70 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.AudiencesRouter = void 0; - -var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); - -var _rest = _interopRequireDefault(require("../rest")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class AudiencesRouter extends _ClassesRouter.default { - className() { - return '_Audience'; - } - - handleFind(req) { - const body = Object.assign(req.body, _ClassesRouter.default.JSONFromQuery(req.query)); - - const options = _ClassesRouter.default.optionsFromBody(body); - - return _rest.default.find(req.config, req.auth, '_Audience', body.where, options, req.info.clientSDK, req.info.context).then(response => { - response.results.forEach(item => { - item.query = JSON.parse(item.query); - }); - return { - response: response - }; - }); - } - - handleGet(req) { - return super.handleGet(req).then(data => { - data.response.query = JSON.parse(data.response.query); - return data; - }); - } - - mountRoutes() { - this.route('GET', '/push_audiences', middleware.promiseEnforceMasterKeyAccess, req => { - return this.handleFind(req); - }); - this.route('GET', '/push_audiences/:objectId', middleware.promiseEnforceMasterKeyAccess, req => { - return this.handleGet(req); - }); - this.route('POST', '/push_audiences', middleware.promiseEnforceMasterKeyAccess, req => { - return this.handleCreate(req); - }); - this.route('PUT', '/push_audiences/:objectId', middleware.promiseEnforceMasterKeyAccess, req => { - return this.handleUpdate(req); - }); - this.route('DELETE', '/push_audiences/:objectId', middleware.promiseEnforceMasterKeyAccess, req => { - return this.handleDelete(req); - }); - } - -} - -exports.AudiencesRouter = AudiencesRouter; -var _default = AudiencesRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0F1ZGllbmNlc1JvdXRlci5qcyJdLCJuYW1lcyI6WyJBdWRpZW5jZXNSb3V0ZXIiLCJDbGFzc2VzUm91dGVyIiwiY2xhc3NOYW1lIiwiaGFuZGxlRmluZCIsInJlcSIsImJvZHkiLCJPYmplY3QiLCJhc3NpZ24iLCJKU09ORnJvbVF1ZXJ5IiwicXVlcnkiLCJvcHRpb25zIiwib3B0aW9uc0Zyb21Cb2R5IiwicmVzdCIsImZpbmQiLCJjb25maWciLCJhdXRoIiwid2hlcmUiLCJpbmZvIiwiY2xpZW50U0RLIiwiY29udGV4dCIsInRoZW4iLCJyZXNwb25zZSIsInJlc3VsdHMiLCJmb3JFYWNoIiwiaXRlbSIsIkpTT04iLCJwYXJzZSIsImhhbmRsZUdldCIsImRhdGEiLCJtb3VudFJvdXRlcyIsInJvdXRlIiwibWlkZGxld2FyZSIsInByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzIiwiaGFuZGxlQ3JlYXRlIiwiaGFuZGxlVXBkYXRlIiwiaGFuZGxlRGVsZXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7Ozs7O0FBRU8sTUFBTUEsZUFBTixTQUE4QkMsc0JBQTlCLENBQTRDO0FBQ2pEQyxFQUFBQSxTQUFTLEdBQUc7QUFDVixXQUFPLFdBQVA7QUFDRDs7QUFFREMsRUFBQUEsVUFBVSxDQUFDQyxHQUFELEVBQU07QUFDZCxVQUFNQyxJQUFJLEdBQUdDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjSCxHQUFHLENBQUNDLElBQWxCLEVBQXdCSix1QkFBY08sYUFBZCxDQUE0QkosR0FBRyxDQUFDSyxLQUFoQyxDQUF4QixDQUFiOztBQUNBLFVBQU1DLE9BQU8sR0FBR1QsdUJBQWNVLGVBQWQsQ0FBOEJOLElBQTlCLENBQWhCOztBQUVBLFdBQU9PLGNBQ0pDLElBREksQ0FFSFQsR0FBRyxDQUFDVSxNQUZELEVBR0hWLEdBQUcsQ0FBQ1csSUFIRCxFQUlILFdBSkcsRUFLSFYsSUFBSSxDQUFDVyxLQUxGLEVBTUhOLE9BTkcsRUFPSE4sR0FBRyxDQUFDYSxJQUFKLENBQVNDLFNBUE4sRUFRSGQsR0FBRyxDQUFDYSxJQUFKLENBQVNFLE9BUk4sRUFVSkMsSUFWSSxDQVVDQyxRQUFRLElBQUk7QUFDaEJBLE1BQUFBLFFBQVEsQ0FBQ0MsT0FBVCxDQUFpQkMsT0FBakIsQ0FBeUJDLElBQUksSUFBSTtBQUMvQkEsUUFBQUEsSUFBSSxDQUFDZixLQUFMLEdBQWFnQixJQUFJLENBQUNDLEtBQUwsQ0FBV0YsSUFBSSxDQUFDZixLQUFoQixDQUFiO0FBQ0QsT0FGRDtBQUlBLGFBQU87QUFBRVksUUFBQUEsUUFBUSxFQUFFQTtBQUFaLE9BQVA7QUFDRCxLQWhCSSxDQUFQO0FBaUJEOztBQUVETSxFQUFBQSxTQUFTLENBQUN2QixHQUFELEVBQU07QUFDYixXQUFPLE1BQU11QixTQUFOLENBQWdCdkIsR0FBaEIsRUFBcUJnQixJQUFyQixDQUEwQlEsSUFBSSxJQUFJO0FBQ3ZDQSxNQUFBQSxJQUFJLENBQUNQLFFBQUwsQ0FBY1osS0FBZCxHQUFzQmdCLElBQUksQ0FBQ0MsS0FBTCxDQUFXRSxJQUFJLENBQUNQLFFBQUwsQ0FBY1osS0FBekIsQ0FBdEI7QUFFQSxhQUFPbUIsSUFBUDtBQUNELEtBSk0sQ0FBUDtBQUtEOztBQUVEQyxFQUFBQSxXQUFXLEdBQUc7QUFDWixTQUFLQyxLQUFMLENBQVcsS0FBWCxFQUFrQixpQkFBbEIsRUFBcUNDLFVBQVUsQ0FBQ0MsNkJBQWhELEVBQStFNUIsR0FBRyxJQUFJO0FBQ3BGLGFBQU8sS0FBS0QsVUFBTCxDQUFnQkMsR0FBaEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLMEIsS0FBTCxDQUNFLEtBREYsRUFFRSwyQkFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUU1QixHQUFHLElBQUk7QUFDTCxhQUFPLEtBQUt1QixTQUFMLENBQWV2QixHQUFmLENBQVA7QUFDRCxLQU5IO0FBUUEsU0FBSzBCLEtBQUwsQ0FBVyxNQUFYLEVBQW1CLGlCQUFuQixFQUFzQ0MsVUFBVSxDQUFDQyw2QkFBakQsRUFBZ0Y1QixHQUFHLElBQUk7QUFDckYsYUFBTyxLQUFLNkIsWUFBTCxDQUFrQjdCLEdBQWxCLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBSzBCLEtBQUwsQ0FDRSxLQURGLEVBRUUsMkJBRkYsRUFHRUMsVUFBVSxDQUFDQyw2QkFIYixFQUlFNUIsR0FBRyxJQUFJO0FBQ0wsYUFBTyxLQUFLOEIsWUFBTCxDQUFrQjlCLEdBQWxCLENBQVA7QUFDRCxLQU5IO0FBUUEsU0FBSzBCLEtBQUwsQ0FDRSxRQURGLEVBRUUsMkJBRkYsRUFHRUMsVUFBVSxDQUFDQyw2QkFIYixFQUlFNUIsR0FBRyxJQUFJO0FBQ0wsYUFBTyxLQUFLK0IsWUFBTCxDQUFrQi9CLEdBQWxCLENBQVA7QUFDRCxLQU5IO0FBUUQ7O0FBbkVnRDs7O2VBc0VwQ0osZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBDbGFzc2VzUm91dGVyIGZyb20gJy4vQ2xhc3Nlc1JvdXRlcic7XG5pbXBvcnQgcmVzdCBmcm9tICcuLi9yZXN0JztcbmltcG9ydCAqIGFzIG1pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5leHBvcnQgY2xhc3MgQXVkaWVuY2VzUm91dGVyIGV4dGVuZHMgQ2xhc3Nlc1JvdXRlciB7XG4gIGNsYXNzTmFtZSgpIHtcbiAgICByZXR1cm4gJ19BdWRpZW5jZSc7XG4gIH1cblxuICBoYW5kbGVGaW5kKHJlcSkge1xuICAgIGNvbnN0IGJvZHkgPSBPYmplY3QuYXNzaWduKHJlcS5ib2R5LCBDbGFzc2VzUm91dGVyLkpTT05Gcm9tUXVlcnkocmVxLnF1ZXJ5KSk7XG4gICAgY29uc3Qgb3B0aW9ucyA9IENsYXNzZXNSb3V0ZXIub3B0aW9uc0Zyb21Cb2R5KGJvZHkpO1xuXG4gICAgcmV0dXJuIHJlc3RcbiAgICAgIC5maW5kKFxuICAgICAgICByZXEuY29uZmlnLFxuICAgICAgICByZXEuYXV0aCxcbiAgICAgICAgJ19BdWRpZW5jZScsXG4gICAgICAgIGJvZHkud2hlcmUsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICByZXNwb25zZS5yZXN1bHRzLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgICAgaXRlbS5xdWVyeSA9IEpTT04ucGFyc2UoaXRlbS5xdWVyeSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiByZXNwb25zZSB9O1xuICAgICAgfSk7XG4gIH1cblxuICBoYW5kbGVHZXQocmVxKSB7XG4gICAgcmV0dXJuIHN1cGVyLmhhbmRsZUdldChyZXEpLnRoZW4oZGF0YSA9PiB7XG4gICAgICBkYXRhLnJlc3BvbnNlLnF1ZXJ5ID0gSlNPTi5wYXJzZShkYXRhLnJlc3BvbnNlLnF1ZXJ5KTtcblxuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfSk7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3B1c2hfYXVkaWVuY2VzJywgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZpbmQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL3B1c2hfYXVkaWVuY2VzLzpvYmplY3RJZCcsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlR2V0KHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9wdXNoX2F1ZGllbmNlcycsIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVDcmVhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ1BVVCcsXG4gICAgICAnL3B1c2hfYXVkaWVuY2VzLzpvYmplY3RJZCcsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlVXBkYXRlKHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0RFTEVURScsXG4gICAgICAnL3B1c2hfYXVkaWVuY2VzLzpvYmplY3RJZCcsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRGVsZXRlKHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBBdWRpZW5jZXNSb3V0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/ClassesRouter.js b/lib/Routers/ClassesRouter.js deleted file mode 100644 index e3b3e93fd2..0000000000 --- a/lib/Routers/ClassesRouter.js +++ /dev/null @@ -1,231 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.ClassesRouter = void 0; - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var _rest = _interopRequireDefault(require("../rest")); - -var _lodash = _interopRequireDefault(require("lodash")); - -var _node = _interopRequireDefault(require("parse/node")); - -var _middlewares = require("../middlewares"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const ALLOWED_GET_QUERY_KEYS = ['keys', 'include', 'excludeKeys', 'readPreference', 'includeReadPreference', 'subqueryReadPreference']; - -class ClassesRouter extends _PromiseRouter.default { - className(req) { - return req.params.className; - } - - handleFind(req) { - const body = Object.assign(req.body, ClassesRouter.JSONFromQuery(req.query)); - const options = ClassesRouter.optionsFromBody(body); - - if (req.config.maxLimit && body.limit > req.config.maxLimit) { - // Silently replace the limit on the query with the max configured - options.limit = Number(req.config.maxLimit); - } - - if (body.redirectClassNameForKey) { - options.redirectClassNameForKey = String(body.redirectClassNameForKey); - } - - if (typeof body.where === 'string') { - body.where = JSON.parse(body.where); - } - - return _rest.default.find(req.config, req.auth, this.className(req), body.where, options, req.info.clientSDK, req.info.context).then(response => { - return { - response: response - }; - }); - } // Returns a promise for a {response} object. - - - handleGet(req) { - const body = Object.assign(req.body, ClassesRouter.JSONFromQuery(req.query)); - const options = {}; - - for (const key of Object.keys(body)) { - if (ALLOWED_GET_QUERY_KEYS.indexOf(key) === -1) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Improper encode of parameter'); - } - } - - if (typeof body.keys === 'string') { - options.keys = body.keys; - } - - if (body.include) { - options.include = String(body.include); - } - - if (typeof body.excludeKeys == 'string') { - options.excludeKeys = body.excludeKeys; - } - - if (typeof body.readPreference === 'string') { - options.readPreference = body.readPreference; - } - - if (typeof body.includeReadPreference === 'string') { - options.includeReadPreference = body.includeReadPreference; - } - - if (typeof body.subqueryReadPreference === 'string') { - options.subqueryReadPreference = body.subqueryReadPreference; - } - - return _rest.default.get(req.config, req.auth, this.className(req), req.params.objectId, options, req.info.clientSDK).then(response => { - if (!response.results || response.results.length == 0) { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } - - if (this.className(req) === '_User') { - delete response.results[0].sessionToken; - const user = response.results[0]; - - if (req.auth.user && user.objectId == req.auth.user.id) { - // Force the session token - response.results[0].sessionToken = req.info.sessionToken; - } - } - - return { - response: response.results[0] - }; - }); - } - - handleCreate(req) { - return _rest.default.create(req.config, req.auth, this.className(req), req.body, req.info.clientSDK, req.info.context); - } - - handleUpdate(req) { - const where = { - objectId: req.params.objectId - }; - return _rest.default.update(req.config, req.auth, this.className(req), where, req.body, req.info.clientSDK, req.info.context); - } - - handleDelete(req) { - return _rest.default.del(req.config, req.auth, this.className(req), req.params.objectId, req.info.context).then(() => { - return { - response: {} - }; - }); - } - - static JSONFromQuery(query) { - const json = {}; - - for (const [key, value] of _lodash.default.entries(query)) { - try { - json[key] = JSON.parse(value); - } catch (e) { - json[key] = value; - } - } - - return json; - } - - static optionsFromBody(body) { - const allowConstraints = ['skip', 'limit', 'order', 'count', 'keys', 'excludeKeys', 'include', 'includeAll', 'redirectClassNameForKey', 'where', 'readPreference', 'includeReadPreference', 'subqueryReadPreference', 'hint', 'explain']; - - for (const key of Object.keys(body)) { - if (allowConstraints.indexOf(key) === -1) { - throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Invalid parameter for query: ${key}`); - } - } - - const options = {}; - - if (body.skip) { - options.skip = Number(body.skip); - } - - if (body.limit || body.limit === 0) { - options.limit = Number(body.limit); - } else { - options.limit = Number(100); - } - - if (body.order) { - options.order = String(body.order); - } - - if (body.count) { - options.count = true; - } - - if (typeof body.keys == 'string') { - options.keys = body.keys; - } - - if (typeof body.excludeKeys == 'string') { - options.excludeKeys = body.excludeKeys; - } - - if (body.include) { - options.include = String(body.include); - } - - if (body.includeAll) { - options.includeAll = true; - } - - if (typeof body.readPreference === 'string') { - options.readPreference = body.readPreference; - } - - if (typeof body.includeReadPreference === 'string') { - options.includeReadPreference = body.includeReadPreference; - } - - if (typeof body.subqueryReadPreference === 'string') { - options.subqueryReadPreference = body.subqueryReadPreference; - } - - if (body.hint && (typeof body.hint === 'string' || typeof body.hint === 'object')) { - options.hint = body.hint; - } - - if (body.explain) { - options.explain = body.explain; - } - - return options; - } - - mountRoutes() { - this.route('GET', '/classes/:className', req => { - return this.handleFind(req); - }); - this.route('GET', '/classes/:className/:objectId', req => { - return this.handleGet(req); - }); - this.route('POST', '/classes/:className', _middlewares.promiseEnsureIdempotency, req => { - return this.handleCreate(req); - }); - this.route('PUT', '/classes/:className/:objectId', _middlewares.promiseEnsureIdempotency, req => { - return this.handleUpdate(req); - }); - this.route('DELETE', '/classes/:className/:objectId', req => { - return this.handleDelete(req); - }); - } - -} - -exports.ClassesRouter = ClassesRouter; -var _default = ClassesRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0NsYXNzZXNSb3V0ZXIuanMiXSwibmFtZXMiOlsiQUxMT1dFRF9HRVRfUVVFUllfS0VZUyIsIkNsYXNzZXNSb3V0ZXIiLCJQcm9taXNlUm91dGVyIiwiY2xhc3NOYW1lIiwicmVxIiwicGFyYW1zIiwiaGFuZGxlRmluZCIsImJvZHkiLCJPYmplY3QiLCJhc3NpZ24iLCJKU09ORnJvbVF1ZXJ5IiwicXVlcnkiLCJvcHRpb25zIiwib3B0aW9uc0Zyb21Cb2R5IiwiY29uZmlnIiwibWF4TGltaXQiLCJsaW1pdCIsIk51bWJlciIsInJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5IiwiU3RyaW5nIiwid2hlcmUiLCJKU09OIiwicGFyc2UiLCJyZXN0IiwiZmluZCIsImF1dGgiLCJpbmZvIiwiY2xpZW50U0RLIiwiY29udGV4dCIsInRoZW4iLCJyZXNwb25zZSIsImhhbmRsZUdldCIsImtleSIsImtleXMiLCJpbmRleE9mIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfUVVFUlkiLCJpbmNsdWRlIiwiZXhjbHVkZUtleXMiLCJyZWFkUHJlZmVyZW5jZSIsImluY2x1ZGVSZWFkUHJlZmVyZW5jZSIsInN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UiLCJnZXQiLCJvYmplY3RJZCIsInJlc3VsdHMiLCJsZW5ndGgiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwic2Vzc2lvblRva2VuIiwidXNlciIsImlkIiwiaGFuZGxlQ3JlYXRlIiwiY3JlYXRlIiwiaGFuZGxlVXBkYXRlIiwidXBkYXRlIiwiaGFuZGxlRGVsZXRlIiwiZGVsIiwianNvbiIsInZhbHVlIiwiXyIsImVudHJpZXMiLCJlIiwiYWxsb3dDb25zdHJhaW50cyIsInNraXAiLCJvcmRlciIsImNvdW50IiwiaW5jbHVkZUFsbCIsImhpbnQiLCJleHBsYWluIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsInByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNB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cG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCB7IHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSB9IGZyb20gJy4uL21pZGRsZXdhcmVzJztcblxuY29uc3QgQUxMT1dFRF9HRVRfUVVFUllfS0VZUyA9IFtcbiAgJ2tleXMnLFxuICAnaW5jbHVkZScsXG4gICdleGNsdWRlS2V5cycsXG4gICdyZWFkUHJlZmVyZW5jZScsXG4gICdpbmNsdWRlUmVhZFByZWZlcmVuY2UnLFxuICAnc3VicXVlcnlSZWFkUHJlZmVyZW5jZScsXG5dO1xuXG5leHBvcnQgY2xhc3MgQ2xhc3Nlc1JvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBjbGFzc05hbWUocmVxKSB7XG4gICAgcmV0dXJuIHJlcS5wYXJhbXMuY2xhc3NOYW1lO1xuICB9XG5cbiAgaGFuZGxlRmluZChyZXEpIHtcbiAgICBjb25zdCBib2R5ID0gT2JqZWN0LmFzc2lnbihyZXEuYm9keSwgQ2xhc3Nlc1JvdXRlci5KU09ORnJvbVF1ZXJ5KHJlcS5xdWVyeSkpO1xuICAgIGNvbnN0IG9wdGlvbnMgPSBDbGFzc2VzUm91dGVyLm9wdGlvbnNGcm9tQm9keShib2R5KTtcbiAgICBpZiAocmVxLmNvbmZpZy5tYXhMaW1pdCAmJiBib2R5LmxpbWl0ID4gcmVxLmNvbmZpZy5tYXhMaW1pdCkge1xuICAgICAgLy8gU2lsZW50bHkgcmVwbGFjZSB0aGUgbGltaXQgb24gdGhlIHF1ZXJ5IHdpdGggdGhlIG1heCBjb25maWd1cmVkXG4gICAgICBvcHRpb25zLmxpbWl0ID0gTnVtYmVyKHJlcS5jb25maWcubWF4TGltaXQpO1xuICAgIH1cbiAgICBpZiAoYm9keS5yZWRpcmVjdENsYXNzTmFtZUZvcktleSkge1xuICAgICAgb3B0aW9ucy5yZWRpcmVjdENsYXNzTmFtZUZvcktleSA9IFN0cmluZyhib2R5LnJlZGlyZWN0Q2xhc3NOYW1lRm9yS2V5KTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LndoZXJlID09PSAnc3RyaW5nJykge1xuICAgICAgYm9keS53aGVyZSA9IEpTT04ucGFyc2UoYm9keS53aGVyZSk7XG4gICAgfVxuICAgIHJldHVybiByZXN0XG4gICAgICAuZmluZChcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgcmVxLmF1dGgsXG4gICAgICAgIHRoaXMuY2xhc3NOYW1lKHJlcSksXG4gICAgICAgIGJvZHkud2hlcmUsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICByZXR1cm4geyByZXNwb25zZTogcmVzcG9uc2UgfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGEge3Jlc3BvbnNlfSBvYmplY3QuXG4gIGhhbmRsZUdldChyZXEpIHtcbiAgICBjb25zdCBib2R5ID0gT2JqZWN0LmFzc2lnbihyZXEuYm9keSwgQ2xhc3Nlc1JvdXRlci5KU09ORnJvbVF1ZXJ5KHJlcS5xdWVyeSkpO1xuICAgIGNvbnN0IG9wdGlvbnMgPSB7fTtcblxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGJvZHkpKSB7XG4gICAgICBpZiAoQUxMT1dFRF9HRVRfUVVFUllfS0VZUy5pbmRleE9mKGtleSkgPT09IC0xKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnSW1wcm9wZXIgZW5jb2RlIG9mIHBhcmFtZXRlcicpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgYm9keS5rZXlzID09PSAnc3RyaW5nJykge1xuICAgICAgb3B0aW9ucy5rZXlzID0gYm9keS5rZXlzO1xuICAgIH1cbiAgICBpZiAoYm9keS5pbmNsdWRlKSB7XG4gICAgICBvcHRpb25zLmluY2x1ZGUgPSBTdHJpbmcoYm9keS5pbmNsdWRlKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LmV4Y2x1ZGVLZXlzID09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zLmV4Y2x1ZGVLZXlzID0gYm9keS5leGNsdWRlS2V5cztcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LnJlYWRQcmVmZXJlbmNlID09PSAnc3RyaW5nJykge1xuICAgICAgb3B0aW9ucy5yZWFkUHJlZmVyZW5jZSA9IGJvZHkucmVhZFByZWZlcmVuY2U7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgYm9keS5pbmNsdWRlUmVhZFByZWZlcmVuY2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zLmluY2x1ZGVSZWFkUHJlZmVyZW5jZSA9IGJvZHkuaW5jbHVkZVJlYWRQcmVmZXJlbmNlO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGJvZHkuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSA9IGJvZHkuc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdFxuICAgICAgLmdldChcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgcmVxLmF1dGgsXG4gICAgICAgIHRoaXMuY2xhc3NOYW1lKHJlcSksXG4gICAgICAgIHJlcS5wYXJhbXMub2JqZWN0SWQsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIHJlcS5pbmZvLmNsaWVudFNES1xuICAgICAgKVxuICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICBpZiAoIXJlc3BvbnNlLnJlc3VsdHMgfHwgcmVzcG9uc2UucmVzdWx0cy5sZW5ndGggPT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnT2JqZWN0IG5vdCBmb3VuZC4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmNsYXNzTmFtZShyZXEpID09PSAnX1VzZXInKSB7XG4gICAgICAgICAgZGVsZXRlIHJlc3BvbnNlLnJlc3VsdHNbMF0uc2Vzc2lvblRva2VuO1xuXG4gICAgICAgICAgY29uc3QgdXNlciA9IHJlc3BvbnNlLnJlc3VsdHNbMF07XG5cbiAgICAgICAgICBpZiAocmVxLmF1dGgudXNlciAmJiB1c2VyLm9iamVjdElkID09IHJlcS5hdXRoLnVzZXIuaWQpIHtcbiAgICAgICAgICAgIC8vIEZvcmNlIHRoZSBzZXNzaW9uIHRva2VuXG4gICAgICAgICAgICByZXNwb25zZS5yZXN1bHRzWzBdLnNlc3Npb25Ub2tlbiA9IHJlcS5pbmZvLnNlc3Npb25Ub2tlbjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHJlc3BvbnNlLnJlc3VsdHNbMF0gfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgaGFuZGxlQ3JlYXRlKHJlcSkge1xuICAgIHJldHVybiByZXN0LmNyZWF0ZShcbiAgICAgIHJlcS5jb25maWcsXG4gICAgICByZXEuYXV0aCxcbiAgICAgIHRoaXMuY2xhc3NOYW1lKHJlcSksXG4gICAgICByZXEuYm9keSxcbiAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICApO1xuICB9XG5cbiAgaGFuZGxlVXBkYXRlKHJlcSkge1xuICAgIGNvbnN0IHdoZXJlID0geyBvYmplY3RJZDogcmVxLnBhcmFtcy5vYmplY3RJZCB9O1xuICAgIHJldHVybiByZXN0LnVwZGF0ZShcbiAgICAgIHJlcS5jb25maWcsXG4gICAgICByZXEuYXV0aCxcbiAgICAgIHRoaXMuY2xhc3NOYW1lKHJlcSksXG4gICAgICB3aGVyZSxcbiAgICAgIHJlcS5ib2R5LFxuICAgICAgcmVxLmluZm8uY2xpZW50U0RLLFxuICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICk7XG4gIH1cblxuICBoYW5kbGVEZWxldGUocmVxKSB7XG4gICAgcmV0dXJuIHJlc3RcbiAgICAgIC5kZWwocmVxLmNvbmZpZywgcmVxLmF1dGgsIHRoaXMuY2xhc3NOYW1lKHJlcSksIHJlcS5wYXJhbXMub2JqZWN0SWQsIHJlcS5pbmZvLmNvbnRleHQpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7fSB9O1xuICAgICAgfSk7XG4gIH1cblxuICBzdGF0aWMgSlNPTkZyb21RdWVyeShxdWVyeSkge1xuICAgIGNvbnN0IGpzb24gPSB7fTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBfLmVudHJpZXMocXVlcnkpKSB7XG4gICAgICB0cnkge1xuICAgICAgICBqc29uW2tleV0gPSBKU09OLnBhcnNlKHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAganNvbltrZXldID0gdmFsdWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBqc29uO1xuICB9XG5cbiAgc3RhdGljIG9wdGlvbnNGcm9tQm9keShib2R5KSB7XG4gICAgY29uc3QgYWxsb3dDb25zdHJhaW50cyA9IFtcbiAgICAgICdza2lwJyxcbiAgICAgICdsaW1pdCcsXG4gICAgICAnb3JkZXInLFxuICAgICAgJ2NvdW50JyxcbiAgICAgICdrZXlzJyxcbiAgICAgICdleGNsdWRlS2V5cycsXG4gICAgICAnaW5jbHVkZScsXG4gICAgICAnaW5jbHVkZUFsbCcsXG4gICAgICAncmVkaXJlY3RDbGFzc05hbWVGb3JLZXknLFxuICAgICAgJ3doZXJlJyxcbiAgICAgICdyZWFkUHJlZmVyZW5jZScsXG4gICAgICAnaW5jbHVkZVJlYWRQcmVmZXJlbmNlJyxcbiAgICAgICdzdWJxdWVyeVJlYWRQcmVmZXJlbmNlJyxcbiAgICAgICdoaW50JyxcbiAgICAgICdleHBsYWluJyxcbiAgICBdO1xuXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoYm9keSkpIHtcbiAgICAgIGlmIChhbGxvd0NvbnN0cmFpbnRzLmluZGV4T2Yoa2V5KSA9PT0gLTEpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksIGBJbnZhbGlkIHBhcmFtZXRlciBmb3IgcXVlcnk6ICR7a2V5fWApO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBvcHRpb25zID0ge307XG4gICAgaWYgKGJvZHkuc2tpcCkge1xuICAgICAgb3B0aW9ucy5za2lwID0gTnVtYmVyKGJvZHkuc2tpcCk7XG4gICAgfVxuICAgIGlmIChib2R5LmxpbWl0IHx8IGJvZHkubGltaXQgPT09IDApIHtcbiAgICAgIG9wdGlvbnMubGltaXQgPSBOdW1iZXIoYm9keS5saW1pdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9wdGlvbnMubGltaXQgPSBOdW1iZXIoMTAwKTtcbiAgICB9XG4gICAgaWYgKGJvZHkub3JkZXIpIHtcbiAgICAgIG9wdGlvbnMub3JkZXIgPSBTdHJpbmcoYm9keS5vcmRlcik7XG4gICAgfVxuICAgIGlmIChib2R5LmNvdW50KSB7XG4gICAgICBvcHRpb25zLmNvdW50ID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LmtleXMgPT0gJ3N0cmluZycpIHtcbiAgICAgIG9wdGlvbnMua2V5cyA9IGJvZHkua2V5cztcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LmV4Y2x1ZGVLZXlzID09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zLmV4Y2x1ZGVLZXlzID0gYm9keS5leGNsdWRlS2V5cztcbiAgICB9XG4gICAgaWYgKGJvZHkuaW5jbHVkZSkge1xuICAgICAgb3B0aW9ucy5pbmNsdWRlID0gU3RyaW5nKGJvZHkuaW5jbHVkZSk7XG4gICAgfVxuICAgIGlmIChib2R5LmluY2x1ZGVBbGwpIHtcbiAgICAgIG9wdGlvbnMuaW5jbHVkZUFsbCA9IHRydWU7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgYm9keS5yZWFkUHJlZmVyZW5jZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSBib2R5LnJlYWRQcmVmZXJlbmNlO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGJvZHkuaW5jbHVkZVJlYWRQcmVmZXJlbmNlID09PSAnc3RyaW5nJykge1xuICAgICAgb3B0aW9ucy5pbmNsdWRlUmVhZFByZWZlcmVuY2UgPSBib2R5LmluY2x1ZGVSZWFkUHJlZmVyZW5jZTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBib2R5LnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UgPSBib2R5LnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U7XG4gICAgfVxuICAgIGlmIChib2R5LmhpbnQgJiYgKHR5cGVvZiBib2R5LmhpbnQgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBib2R5LmhpbnQgPT09ICdvYmplY3QnKSkge1xuICAgICAgb3B0aW9ucy5oaW50ID0gYm9keS5oaW50O1xuICAgIH1cbiAgICBpZiAoYm9keS5leHBsYWluKSB7XG4gICAgICBvcHRpb25zLmV4cGxhaW4gPSBib2R5LmV4cGxhaW47XG4gICAgfVxuICAgIHJldHVybiBvcHRpb25zO1xuICB9XG5cbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9jbGFzc2VzLzpjbGFzc05hbWUnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRmluZChyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvY2xhc3Nlcy86Y2xhc3NOYW1lLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9jbGFzc2VzLzpjbGFzc05hbWUnLCBwcm9taXNlRW5zdXJlSWRlbXBvdGVuY3ksIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVDcmVhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQVVQnLCAnL2NsYXNzZXMvOmNsYXNzTmFtZS86b2JqZWN0SWQnLCBwcm9taXNlRW5zdXJlSWRlbXBvdGVuY3ksIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVVcGRhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdERUxFVEUnLCAnL2NsYXNzZXMvOmNsYXNzTmFtZS86b2JqZWN0SWQnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRGVsZXRlKHJlcSk7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgQ2xhc3Nlc1JvdXRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/CloudCodeRouter.js b/lib/Routers/CloudCodeRouter.js deleted file mode 100644 index 423ee10a50..0000000000 --- a/lib/Routers/CloudCodeRouter.js +++ /dev/null @@ -1,105 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.CloudCodeRouter = void 0; - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var _node = _interopRequireDefault(require("parse/node")); - -var _rest = _interopRequireDefault(require("../rest")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const triggers = require('../triggers'); - -const middleware = require('../middlewares'); - -function formatJobSchedule(job_schedule) { - if (typeof job_schedule.startAfter === 'undefined') { - job_schedule.startAfter = new Date().toISOString(); - } - - return job_schedule; -} - -function validateJobSchedule(config, job_schedule) { - const jobs = triggers.getJobs(config.applicationId) || {}; - - if (job_schedule.jobName && !jobs[job_schedule.jobName]) { - throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'Cannot Schedule a job that is not deployed'); - } -} - -class CloudCodeRouter extends _PromiseRouter.default { - mountRoutes() { - this.route('GET', '/cloud_code/jobs', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.getJobs); - this.route('GET', '/cloud_code/jobs/data', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.getJobsData); - this.route('POST', '/cloud_code/jobs', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.createJob); - this.route('PUT', '/cloud_code/jobs/:objectId', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.editJob); - this.route('DELETE', '/cloud_code/jobs/:objectId', middleware.promiseEnforceMasterKeyAccess, CloudCodeRouter.deleteJob); - } - - static getJobs(req) { - return _rest.default.find(req.config, req.auth, '_JobSchedule', {}, {}).then(scheduledJobs => { - return { - response: scheduledJobs.results - }; - }); - } - - static getJobsData(req) { - const config = req.config; - const jobs = triggers.getJobs(config.applicationId) || {}; - return _rest.default.find(req.config, req.auth, '_JobSchedule', {}, {}).then(scheduledJobs => { - return { - response: { - in_use: scheduledJobs.results.map(job => job.jobName), - jobs: Object.keys(jobs) - } - }; - }); - } - - static createJob(req) { - const { - job_schedule - } = req.body; - validateJobSchedule(req.config, job_schedule); - return _rest.default.create(req.config, req.auth, '_JobSchedule', formatJobSchedule(job_schedule), req.client, req.info.context); - } - - static editJob(req) { - const { - objectId - } = req.params; - const { - job_schedule - } = req.body; - validateJobSchedule(req.config, job_schedule); - return _rest.default.update(req.config, req.auth, '_JobSchedule', { - objectId - }, formatJobSchedule(job_schedule), undefined, req.info.context).then(response => { - return { - response - }; - }); - } - - static deleteJob(req) { - const { - objectId - } = req.params; - return _rest.default.del(req.config, req.auth, '_JobSchedule', objectId, req.info.context).then(response => { - return { - response - }; - }); - } - -} - -exports.CloudCodeRouter = CloudCodeRouter; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0Nsb3VkQ29kZVJvdXRlci5qcyJdLCJuYW1lcyI6WyJ0cmlnZ2VycyIsInJlcXVpcmUiLCJtaWRkbGV3YXJlIiwiZm9ybWF0Sm9iU2NoZWR1bGUiLCJqb2Jfc2NoZWR1bGUiLCJzdGFydEFmdGVyIiwiRGF0ZSIsInRvSVNPU3RyaW5nIiwidmFsaWRhdGVKb2JTY2hlZHVsZSIsImNvbmZpZyIsImpvYnMiLCJnZXRKb2JzIiwiYXBwbGljYXRpb25JZCIsImpvYk5hbWUiLCJQYXJzZSIsIkVycm9yIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwiQ2xvdWRDb2RlUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsIm1vdW50Um91dGVzIiwicm91dGUiLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyIsImdldEpvYnNEYXRhIiwiY3JlYXRlSm9iIiwiZWRpdEpvYiIsImRlbGV0ZUpvYiIsInJlcSIsInJlc3QiLCJmaW5kIiwiYXV0aCIsInRoZW4iLCJzY2hlZHVsZWRKb2JzIiwicmVzcG9uc2UiLCJyZXN1bHRzIiwiaW5fdXNlIiwibWFwIiwiam9iIiwiT2JqZWN0Iiwia2V5cyIsImJvZHkiLCJjcmVhdGUiLCJjbGllbnQiLCJpbmZvIiwiY29udGV4dCIsIm9iamVjdElkIiwicGFyYW1zIiwidXBkYXRlIiwidW5kZWZpbmVkIiwiZGVsIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7Ozs7QUFDQSxNQUFNQSxRQUFRLEdBQUdDLE9BQU8sQ0FBQyxhQUFELENBQXhCOztBQUNBLE1BQU1DLFVBQVUsR0FBR0QsT0FBTyxDQUFDLGdCQUFELENBQTFCOztBQUVBLFNBQVNFLGlCQUFULENBQTJCQyxZQUEzQixFQUF5QztBQUN2QyxNQUFJLE9BQU9BLFlBQVksQ0FBQ0MsVUFBcEIsS0FBbUMsV0FBdkMsRUFBb0Q7QUFDbERELElBQUFBLFlBQVksQ0FBQ0MsVUFBYixHQUEwQixJQUFJQyxJQUFKLEdBQVdDLFdBQVgsRUFB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dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IHJlc3QgZnJvbSAnLi4vcmVzdCc7XG5jb25zdCB0cmlnZ2VycyA9IHJlcXVpcmUoJy4uL3RyaWdnZXJzJyk7XG5jb25zdCBtaWRkbGV3YXJlID0gcmVxdWlyZSgnLi4vbWlkZGxld2FyZXMnKTtcblxuZnVuY3Rpb24gZm9ybWF0Sm9iU2NoZWR1bGUoam9iX3NjaGVkdWxlKSB7XG4gIGlmICh0eXBlb2Ygam9iX3NjaGVkdWxlLnN0YXJ0QWZ0ZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgam9iX3NjaGVkdWxlLnN0YXJ0QWZ0ZXIgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gIH1cbiAgcmV0dXJuIGpvYl9zY2hlZHVsZTtcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVKb2JTY2hlZHVsZShjb25maWcsIGpvYl9zY2hlZHVsZSkge1xuICBjb25zdCBqb2JzID0gdHJpZ2dlcnMuZ2V0Sm9icyhjb25maWcuYXBwbGljYXRpb25JZCkgfHwge307XG4gIGlmIChqb2Jfc2NoZWR1bGUuam9iTmFtZSAmJiAham9ic1tqb2Jfc2NoZWR1bGUuam9iTmFtZV0pIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsXG4gICAgICAnQ2Fubm90IFNjaGVkdWxlIGEgam9iIHRoYXQgaXMgbm90IGRlcGxveWVkJ1xuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIENsb3VkQ29kZVJvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2Nsb3VkX2NvZGUvam9icycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgQ2xvdWRDb2RlUm91dGVyLmdldEpvYnNcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnR0VUJyxcbiAgICAgICcvY2xvdWRfY29kZS9qb2JzL2RhdGEnLFxuICAgICAgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyxcbiAgICAgIENsb3VkQ29kZVJvdXRlci5nZXRKb2JzRGF0YVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdQT1NUJyxcbiAgICAgICcvY2xvdWRfY29kZS9qb2JzJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICBDbG91ZENvZGVSb3V0ZXIuY3JlYXRlSm9iXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ1BVVCcsXG4gICAgICAnL2Nsb3VkX2NvZGUvam9icy86b2JqZWN0SWQnLFxuICAgICAgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyxcbiAgICAgIENsb3VkQ29kZVJvdXRlci5lZGl0Sm9iXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0RFTEVURScsXG4gICAgICAnL2Nsb3VkX2NvZGUvam9icy86b2JqZWN0SWQnLFxuICAgICAgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyxcbiAgICAgIENsb3VkQ29kZVJvdXRlci5kZWxldGVKb2JcbiAgICApO1xuICB9XG5cbiAgc3RhdGljIGdldEpvYnMocmVxKSB7XG4gICAgcmV0dXJuIHJlc3QuZmluZChyZXEuY29uZmlnLCByZXEuYXV0aCwgJ19Kb2JTY2hlZHVsZScsIHt9LCB7fSkudGhlbihzY2hlZHVsZWRKb2JzID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHJlc3BvbnNlOiBzY2hlZHVsZWRKb2JzLnJlc3VsdHMsXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGdldEpvYnNEYXRhKHJlcSkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHJlcS5jb25maWc7XG4gICAgY29uc3Qgam9icyA9IHRyaWdnZXJzLmdldEpvYnMoY29uZmlnLmFwcGxpY2F0aW9uSWQpIHx8IHt9O1xuICAgIHJldHVybiByZXN0LmZpbmQocmVxLmNvbmZpZywgcmVxLmF1dGgsICdfSm9iU2NoZWR1bGUnLCB7fSwge30pLnRoZW4oc2NoZWR1bGVkSm9icyA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgIGluX3VzZTogc2NoZWR1bGVkSm9icy5yZXN1bHRzLm1hcChqb2IgPT4gam9iLmpvYk5hbWUpLFxuICAgICAgICAgIGpvYnM6IE9iamVjdC5rZXlzKGpvYnMpLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVKb2IocmVxKSB7XG4gICAgY29uc3QgeyBqb2Jfc2NoZWR1bGUgfSA9IHJlcS5ib2R5O1xuICAgIHZhbGlkYXRlSm9iU2NoZWR1bGUocmVxLmNvbmZpZywgam9iX3NjaGVkdWxlKTtcbiAgICByZXR1cm4gcmVzdC5jcmVhdGUoXG4gICAgICByZXEuY29uZmlnLFxuICAgICAgcmVxLmF1dGgsXG4gICAgICAnX0pvYlNjaGVkdWxlJyxcbiAgICAgIGZvcm1hdEpvYlNjaGVkdWxlKGpvYl9zY2hlZHVsZSksXG4gICAgICByZXEuY2xpZW50LFxuICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICk7XG4gIH1cblxuICBzdGF0aWMgZWRpdEpvYihyZXEpIHtcbiAgICBjb25zdCB7IG9iamVjdElkIH0gPSByZXEucGFyYW1zO1xuICAgIGNvbnN0IHsgam9iX3NjaGVkdWxlIH0gPSByZXEuYm9keTtcbiAgICB2YWxpZGF0ZUpvYlNjaGVkdWxlKHJlcS5jb25maWcsIGpvYl9zY2hlZHVsZSk7XG4gICAgcmV0dXJuIHJlc3RcbiAgICAgIC51cGRhdGUoXG4gICAgICAgIHJlcS5jb25maWcsXG4gICAgICAgIHJlcS5hdXRoLFxuICAgICAgICAnX0pvYlNjaGVkdWxlJyxcbiAgICAgICAgeyBvYmplY3RJZCB9LFxuICAgICAgICBmb3JtYXRKb2JTY2hlZHVsZShqb2Jfc2NoZWR1bGUpLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICByZXNwb25zZSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGRlbGV0ZUpvYihyZXEpIHtcbiAgICBjb25zdCB7IG9iamVjdElkIH0gPSByZXEucGFyYW1zO1xuICAgIHJldHVybiByZXN0XG4gICAgICAuZGVsKHJlcS5jb25maWcsIHJlcS5hdXRoLCAnX0pvYlNjaGVkdWxlJywgb2JqZWN0SWQsIHJlcS5pbmZvLmNvbnRleHQpXG4gICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcmVzcG9uc2UsXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgfVxufVxuIl19 \ No newline at end of file diff --git a/lib/Routers/FeaturesRouter.js b/lib/Routers/FeaturesRouter.js deleted file mode 100644 index 51c3c26849..0000000000 --- a/lib/Routers/FeaturesRouter.js +++ /dev/null @@ -1,79 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.FeaturesRouter = void 0; - -var _package = require("../../package.json"); - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class FeaturesRouter extends _PromiseRouter.default { - mountRoutes() { - this.route('GET', '/serverInfo', middleware.promiseEnforceMasterKeyAccess, req => { - const { - config - } = req; - const features = { - globalConfig: { - create: true, - read: true, - update: true, - delete: true - }, - hooks: { - create: true, - read: true, - update: true, - delete: true - }, - cloudCode: { - jobs: true - }, - logs: { - level: true, - size: true, - order: true, - until: true, - from: true - }, - push: { - immediatePush: config.hasPushSupport, - scheduledPush: config.hasPushScheduledSupport, - storedPushData: config.hasPushSupport, - pushAudiences: true, - localization: true - }, - schemas: { - addField: true, - removeField: true, - addClass: true, - removeClass: true, - clearAllDataFromClass: true, - exportClass: false, - editClassLevelPermissions: true, - editPointerPermissions: true - } - }; - return { - response: { - features: features, - parseServerVersion: _package.version - } - }; - }); - } - -} - -exports.FeaturesRouter = FeaturesRouter; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0ZlYXR1cmVzUm91dGVyLmpzIl0sIm5hbWVzIjpbIkZlYXR1cmVzUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsIm1vdW50Um91dGVzIiwicm91dGUiLCJtaWRkbGV3YXJlIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiLCJyZXEiLCJjb25maWciLCJmZWF0dXJlcyIsImdsb2JhbENvbmZpZyIsImNyZWF0ZSIsInJlYWQiLCJ1cGRhdGUiLCJkZWxldGUiLCJob29rcyIsImNsb3VkQ29kZSIsImpvYnMiLCJsb2dzIiwibGV2ZWwiLCJzaXplIiwib3JkZXIiLCJ1bnRpbCIsImZyb20iLCJwdXNoIiwiaW1tZWRpYXRlUHVzaCIsImhhc1B1c2hTdXBwb3J0Iiwic2NoZWR1bGVkUHVzaCIsImhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0Iiwic3RvcmVkUHVzaERhdGEiLCJwdXNoQXVkaWVuY2VzIiwibG9jYWxpemF0aW9uIiwic2NoZW1hcyIsImFkZEZpZWxkIiwicmVtb3ZlRmllbGQiLCJhZGRDbGFzcyIsInJlbW92ZUNsYXNzIiwiY2xlYXJBbGxEYXRhRnJvbUNsYXNzIiwiZXhwb3J0Q2xhc3MiLCJlZGl0Q2xhc3NMZXZlbFBlcm1pc3Npb25zIiwiZWRpdFBvaW50ZXJQZXJtaXNzaW9ucyIsInJlc3BvbnNlIiwicGFyc2VTZXJ2ZXJWZXJzaW9uIiwidmVyc2lvbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVPLE1BQU1BLGNBQU4sU0FBNkJDLHNCQUE3QixDQUEyQztBQUNoREMsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxDQUFXLEtBQVgsRUFBa0IsYUFBbEIsRUFBaUNDLFVBQVUsQ0FBQ0MsNkJBQTVDLEVBQTJFQyxHQUFHLElBQUk7QUFDaEYsWUFBTTtBQUFFQyxRQUFBQTtBQUFGLFVBQWFELEdBQW5CO0FBQ0EsWUFBTUUsUUFBUSxHQUFHO0FBQ2ZDLFFBQUFBLFlBQVksRUFBRTtBQUNaQyxVQUFBQSxNQUFNLEVBQUUsSUFESTtBQUVaQyxVQUFBQSxJQUFJLEVBQUUsSUFGTTtBQUdaQyxVQUFBQSxNQUFNLEVBQUUsSUFISTtBQUlaQyxVQUFBQSxNQUFNLEVBQUU7QUFKSSxTQURDO0FBT2ZDLFFBQUFBLEtBQUssRUFBRTtBQUNMSixVQUFBQSxNQUFNLEVBQUUsSUFESDtBQUVMQyxVQUFBQSxJQUFJLEVBQUUsSUFGRDtBQUdMQyxVQUFBQSxNQUFNLEVBQUUsSUFISDtBQUlMQyxVQUFBQSxNQUFNLEVBQUU7QUFKSCxTQVBRO0FBYWZFLFFBQUFBLFNBQVMsRUFBRTtBQUNUQyxVQUFBQSxJQUFJLEVBQUU7QUFERyxTQWJJO0FBZ0JmQyxRQUFBQSxJQUFJLEVBQUU7QUFDSkMsVUFBQUEsS0FBSyxFQUFFLElBREg7QUFFSkMsVUFBQUEsSUFBSSxFQUFFLElBRkY7QUFHSkMsVUFBQUEsS0FBSyxFQUFFLElBSEg7QUFJSkMsVUFBQUEsS0FBSyxFQUFFLElBSkg7QUFLSkMsVUFBQUEsSUFBSSxFQUFFO0FBTEYsU0FoQlM7QUF1QmZDLFFBQUFBLElBQUksRUFBRTtBQUNKQyxVQUFBQSxhQUFhLEVBQUVqQixNQUFNLENBQUNrQixjQURsQjtBQUVKQyxVQUFBQSxhQUFhLEVBQUVuQixNQUFNLENBQUNvQix1QkFGbEI7QUFHSkMsVUFBQUEsY0FBYyxFQUFFckIsTUFBTSxDQUFDa0IsY0FIbkI7QUFJSkksVUFBQUEsYUFBYSxFQUFFLElBSlg7QUFLSkMsVUFBQUEsWUFBWSxFQUFFO0FBTFYsU0F2QlM7QUE4QmZDLFFBQUFBLE9BQU8sRUFBRTtBQUNQQyxVQUFBQSxRQUFRLEVBQUUsSUFESDtBQUVQQyxVQUFBQSxXQUFXLEVBQUUsSUFGTjtBQUdQQyxVQUFBQSxRQUFRLEVBQUUsSUFISDtBQUlQQyxVQUFBQSxXQUFXLEVBQUUsSUFKTjtBQUtQQyxVQUFBQSxxQkFBcUIsRUFBRSxJQUxoQjtBQU1QQyxVQUFBQSxXQUFXLEVBQUUsS0FOTjtBQU9QQyxVQUFBQSx5QkFBeUIsRUFBRSxJQVBwQjtBQVFQQyxVQUFBQSxzQkFBc0IsRUFBRTtBQVJqQjtBQTlCTSxPQUFqQjtBQTBDQSxhQUFPO0FBQ0xDLFFBQUFBLFFBQVEsRUFBRTtBQUNSaEMsVUFBQUEsUUFBUSxFQUFFQSxRQURGO0FBRVJpQyxVQUFBQSxrQkFBa0IsRUFBRUM7QUFGWjtBQURMLE9BQVA7QUFNRCxLQWxERDtBQW1ERDs7QUFyRCtDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgdmVyc2lvbiB9IGZyb20gJy4uLy4uL3BhY2thZ2UuanNvbic7XG5pbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuLi9Qcm9taXNlUm91dGVyJztcbmltcG9ydCAqIGFzIG1pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5leHBvcnQgY2xhc3MgRmVhdHVyZXNSb3V0ZXIgZXh0ZW5kcyBQcm9taXNlUm91dGVyIHtcbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9zZXJ2ZXJJbmZvJywgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcywgcmVxID0+IHtcbiAgICAgIGNvbnN0IHsgY29uZmlnIH0gPSByZXE7XG4gICAgICBjb25zdCBmZWF0dXJlcyA9IHtcbiAgICAgICAgZ2xvYmFsQ29uZmlnOiB7XG4gICAgICAgICAgY3JlYXRlOiB0cnVlLFxuICAgICAgICAgIHJlYWQ6IHRydWUsXG4gICAgICAgICAgdXBkYXRlOiB0cnVlLFxuICAgICAgICAgIGRlbGV0ZTogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAgaG9va3M6IHtcbiAgICAgICAgICBjcmVhdGU6IHRydWUsXG4gICAgICAgICAgcmVhZDogdHJ1ZSxcbiAgICAgICAgICB1cGRhdGU6IHRydWUsXG4gICAgICAgICAgZGVsZXRlOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBjbG91ZENvZGU6IHtcbiAgICAgICAgICBqb2JzOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBsb2dzOiB7XG4gICAgICAgICAgbGV2ZWw6IHRydWUsXG4gICAgICAgICAgc2l6ZTogdHJ1ZSxcbiAgICAgICAgICBvcmRlcjogdHJ1ZSxcbiAgICAgICAgICB1bnRpbDogdHJ1ZSxcbiAgICAgICAgICBmcm9tOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBwdXNoOiB7XG4gICAgICAgICAgaW1tZWRpYXRlUHVzaDogY29uZmlnLmhhc1B1c2hTdXBwb3J0LFxuICAgICAgICAgIHNjaGVkdWxlZFB1c2g6IGNvbmZpZy5oYXNQdXNoU2NoZWR1bGVkU3VwcG9ydCxcbiAgICAgICAgICBzdG9yZWRQdXNoRGF0YTogY29uZmlnLmhhc1B1c2hTdXBwb3J0LFxuICAgICAgICAgIHB1c2hBdWRpZW5jZXM6IHRydWUsXG4gICAgICAgICAgbG9jYWxpemF0aW9uOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBzY2hlbWFzOiB7XG4gICAgICAgICAgYWRkRmllbGQ6IHRydWUsXG4gICAgICAgICAgcmVtb3ZlRmllbGQ6IHRydWUsXG4gICAgICAgICAgYWRkQ2xhc3M6IHRydWUsXG4gICAgICAgICAgcmVtb3ZlQ2xhc3M6IHRydWUsXG4gICAgICAgICAgY2xlYXJBbGxEYXRhRnJvbUNsYXNzOiB0cnVlLFxuICAgICAgICAgIGV4cG9ydENsYXNzOiBmYWxzZSxcbiAgICAgICAgICBlZGl0Q2xhc3NMZXZlbFBlcm1pc3Npb25zOiB0cnVlLFxuICAgICAgICAgIGVkaXRQb2ludGVyUGVybWlzc2lvbnM6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgIGZlYXR1cmVzOiBmZWF0dXJlcyxcbiAgICAgICAgICBwYXJzZVNlcnZlclZlcnNpb246IHZlcnNpb24sXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/FilesRouter.js b/lib/Routers/FilesRouter.js deleted file mode 100644 index 009dc3db69..0000000000 --- a/lib/Routers/FilesRouter.js +++ /dev/null @@ -1,280 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.FilesRouter = void 0; - -var _express = _interopRequireDefault(require("express")); - -var _bodyParser = _interopRequireDefault(require("body-parser")); - -var Middlewares = _interopRequireWildcard(require("../middlewares")); - -var _node = _interopRequireDefault(require("parse/node")); - -var _Config = _interopRequireDefault(require("../Config")); - -var _mime = _interopRequireDefault(require("mime")); - -var _logger = _interopRequireDefault(require("../logger")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const triggers = require('../triggers'); - -const http = require('http'); - -const downloadFileFromURI = uri => { - return new Promise((res, rej) => { - http.get(uri, response => { - response.setDefaultEncoding('base64'); - let body = `data:${response.headers['content-type']};base64,`; - response.on('data', data => body += data); - response.on('end', () => res(body)); - }).on('error', e => { - rej(`Error downloading file from ${uri}: ${e.message}`); - }); - }); -}; - -const addFileDataIfNeeded = async file => { - if (file._source.format === 'uri') { - const base64 = await downloadFileFromURI(file._source.uri); - file._previousSave = file; - file._data = base64; - file._requestTask = null; - } - - return file; -}; - -class FilesRouter { - expressRouter({ - maxUploadSize = '20Mb' - } = {}) { - var router = _express.default.Router(); - - router.get('/files/:appId/:filename', this.getHandler); - router.get('/files/:appId/metadata/:filename', this.metadataHandler); - router.post('/files', function (req, res, next) { - next(new _node.default.Error(_node.default.Error.INVALID_FILE_NAME, 'Filename not provided.')); - }); - router.post('/files/:filename', _bodyParser.default.raw({ - type: () => { - return true; - }, - limit: maxUploadSize - }), // Allow uploads without Content-Type, or with any Content-Type. - Middlewares.handleParseHeaders, this.createHandler); - router.delete('/files/:filename', Middlewares.handleParseHeaders, Middlewares.enforceMasterKeyAccess, this.deleteHandler); - return router; - } - - getHandler(req, res) { - const config = _Config.default.get(req.params.appId); - - const filesController = config.filesController; - const filename = req.params.filename; - - const contentType = _mime.default.getType(filename); - - if (isFileStreamable(req, filesController)) { - filesController.handleFileStream(config, filename, req, res, contentType).catch(() => { - res.status(404); - res.set('Content-Type', 'text/plain'); - res.end('File not found.'); - }); - } else { - filesController.getFileData(config, filename).then(data => { - res.status(200); - res.set('Content-Type', contentType); - res.set('Content-Length', data.length); - res.end(data); - }).catch(() => { - res.status(404); - res.set('Content-Type', 'text/plain'); - res.end('File not found.'); - }); - } - } - - async createHandler(req, res, next) { - const config = req.config; - const user = req.auth.user; - const isMaster = req.auth.isMaster; - - const isLinked = user && _node.default.AnonymousUtils.isLinked(user); - - if (!isMaster && !config.fileUpload.enableForAnonymousUser && isLinked) { - next(new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, 'File upload by anonymous user is disabled.')); - return; - } - - if (!isMaster && !config.fileUpload.enableForAuthenticatedUser && !isLinked && user) { - next(new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, 'File upload by authenticated user is disabled.')); - return; - } - - if (!isMaster && !config.fileUpload.enableForPublic && !user) { - next(new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, 'File upload by public is disabled.')); - return; - } - - const filesController = config.filesController; - const { - filename - } = req.params; - const contentType = req.get('Content-type'); - - if (!req.body || !req.body.length) { - next(new _node.default.Error(_node.default.Error.FILE_SAVE_ERROR, 'Invalid file upload.')); - return; - } - - const error = filesController.validateFilename(filename); - - if (error) { - next(error); - return; - } - - const base64 = req.body.toString('base64'); - const file = new _node.default.File(filename, { - base64 - }, contentType); - const { - metadata = {}, - tags = {} - } = req.fileData || {}; - file.setTags(tags); - file.setMetadata(metadata); - const fileSize = Buffer.byteLength(req.body); - const fileObject = { - file, - fileSize - }; - - try { - // run beforeSaveFile trigger - const triggerResult = await triggers.maybeRunFileTrigger(triggers.Types.beforeSaveFile, fileObject, config, req.auth); - let saveResult; // if a new ParseFile is returned check if it's an already saved file - - if (triggerResult instanceof _node.default.File) { - fileObject.file = triggerResult; - - if (triggerResult.url()) { - // set fileSize to null because we wont know how big it is here - fileObject.fileSize = null; - saveResult = { - url: triggerResult.url(), - name: triggerResult._name - }; - } - } // if the file returned by the trigger has already been saved skip saving anything - - - if (!saveResult) { - // if the ParseFile returned is type uri, download the file before saving it - await addFileDataIfNeeded(fileObject.file); // update fileSize - - const bufferData = Buffer.from(fileObject.file._data, 'base64'); - fileObject.fileSize = Buffer.byteLength(bufferData); // save file - - const createFileResult = await filesController.createFile(config, fileObject.file._name, bufferData, fileObject.file._source.type, { - tags: fileObject.file._tags, - metadata: fileObject.file._metadata - }); // update file with new data - - fileObject.file._name = createFileResult.name; - fileObject.file._url = createFileResult.url; - fileObject.file._requestTask = null; - fileObject.file._previousSave = Promise.resolve(fileObject.file); - saveResult = { - url: createFileResult.url, - name: createFileResult.name - }; - } // run afterSaveFile trigger - - - await triggers.maybeRunFileTrigger(triggers.Types.afterSaveFile, fileObject, config, req.auth); - res.status(201); - res.set('Location', saveResult.url); - res.json(saveResult); - } catch (e) { - _logger.default.error('Error creating a file: ', e); - - const error = triggers.resolveError(e, { - code: _node.default.Error.FILE_SAVE_ERROR, - message: `Could not store file: ${fileObject.file._name}.` - }); - next(error); - } - } - - async deleteHandler(req, res, next) { - try { - const { - filesController - } = req.config; - const { - filename - } = req.params; // run beforeDeleteFile trigger - - const file = new _node.default.File(filename); - file._url = filesController.adapter.getFileLocation(req.config, filename); - const fileObject = { - file, - fileSize: null - }; - await triggers.maybeRunFileTrigger(triggers.Types.beforeDeleteFile, fileObject, req.config, req.auth); // delete file - - await filesController.deleteFile(req.config, filename); // run afterDeleteFile trigger - - await triggers.maybeRunFileTrigger(triggers.Types.afterDeleteFile, fileObject, req.config, req.auth); - res.status(200); // TODO: return useful JSON here? - - res.end(); - } catch (e) { - _logger.default.error('Error deleting a file: ', e); - - const error = triggers.resolveError(e, { - code: _node.default.Error.FILE_DELETE_ERROR, - message: 'Could not delete file.' - }); - next(error); - } - } - - async metadataHandler(req, res) { - const config = _Config.default.get(req.params.appId); - - const { - filesController - } = config; - const { - filename - } = req.params; - - try { - const data = await filesController.getMetadata(filename); - res.status(200); - res.json(data); - } catch (e) { - res.status(200); - res.json({}); - } - } - -} - -exports.FilesRouter = FilesRouter; - -function isFileStreamable(req, filesController) { - return req.get('Range') && typeof filesController.adapter.handleFileStream === 'function'; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0ZpbGVzUm91dGVyLmpzIl0sIm5hbWVzIjpbInRyaWdnZXJzIiwicmVxdWlyZSIsImh0dHAiLCJkb3dubG9hZEZpbGVGcm9tVVJJIiwidXJpIiwiUHJvbWlzZSIsInJlcyIsInJlaiIsImdldCIsInJlc3BvbnNlIiwic2V0RGVmYXVsdEVuY29kaW5nIiwiYm9keSIsImhlYWRlcnMiLCJvbiIsImRhdGEiLCJlIiwibWVzc2FnZSIsImFkZEZpbGVEYXRhSWZOZWVkZWQiLCJmaWxlIiwiX3NvdXJjZSIsImZvcm1hdCIsImJhc2U2NCIsIl9wcmV2aW91c1NhdmUiLCJfZGF0YSIsIl9yZXF1ZXN0VGFzayIsIkZpbGVzUm91dGVyIiwiZXhwcmVzc1JvdXRlciIsIm1heFVwbG9hZFNpemUiLCJyb3V0ZXIiLCJleHByZXNzIiwiUm91dGVyIiwiZ2V0SGFuZGxlciIsIm1ldGFkYXRhSGFuZGxlciIsInBvc3QiLCJyZXEiLCJuZXh0IiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfRklMRV9OQU1FIiwiQm9keVBhcnNlciIsInJhdyIsInR5cGUiLCJsaW1pdCIsIk1pZGRsZXdhcmVzIiwiaGFuZGxlUGFyc2VIZWFkZXJzIiwiY3JlYXRlSGFuZGxlciIsImRlbGV0ZSIsImVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiLCJkZWxldGVIYW5kbGVyIiwiY29uZmlnIiwiQ29uZmlnIiwicGFyYW1zIiwiYXBwSWQiLCJmaWxlc0NvbnRyb2xsZXIiLCJmaWxlbmFtZSIsImNvbnRlbnRUeXBlIiwibWltZSIsImdldFR5cGUiLCJpc0ZpbGVTdHJlYW1hYmxlIiwiaGFuZGxlRmlsZVN0cmVhbSIsImNhdGNoIiwic3RhdHVzIiwic2V0IiwiZW5kIiwiZ2V0RmlsZURhdGEiLCJ0aGVuIiwibGVuZ3RoIiwidXNlciIsImF1dGgiLCJpc01hc3RlciIsImlzTGlua2VkIiwiQW5vbnltb3VzVXRpbHMiLCJmaWxlVXBsb2FkIiwiZW5hYmxlRm9yQW5vbnltb3VzVXNlciIsIkZJTEVfU0FWRV9FUlJPUiIsImVuYWJsZUZvckF1dGhlbnRpY2F0ZWRVc2VyIiwiZW5hYmxlRm9yUHVibGljIiwiZXJyb3IiLCJ2YWxpZGF0ZUZpbGVuYW1lIiwidG9TdHJpbmciLCJGaWxlIiwibWV0YWRhdGEiLCJ0YWdzIiwiZmlsZURhdGEiLCJzZXRUYWdzIiwic2V0TWV0YWRhdGEiLCJmaWxlU2l6ZSIsIkJ1ZmZlciIsImJ5dGVMZW5ndGgiLCJmaWxlT2JqZWN0IiwidHJpZ2dlclJlc3VsdCIsIm1heWJlUnVuRmlsZVRyaWdnZXIiLCJUeXBlcyIsImJlZm9yZVNhdmVGaWxlIiwic2F2ZVJlc3VsdCIsInVybCIsIm5hbWUiLCJfbmFtZSIsImJ1ZmZlckRhdGEiLCJmcm9tIiwiY3JlYXRlRmlsZVJlc3VsdCIsImNyZWF0ZUZpbGUiLCJfdGFncyIsIl9tZXRhZGF0YSIsIl91cmwiLCJyZXNvbHZlIiwiYWZ0ZXJTYXZlRmlsZSIsImpzb24iLCJsb2dnZXIiLCJyZXNvbHZlRXJyb3IiLCJjb2RlIiwiYWRhcHRlciIsImdldEZpbGVMb2NhdGlvbiIsImJlZm9yZURlbGV0ZUZpbGUiLCJkZWxldGVGaWxlIiwiYWZ0ZXJEZWxldGVGaWxlIiwiRklMRV9ERUxFVEVfRVJST1IiLCJnZXRNZXRhZGF0YSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7OztBQUNBLE1BQU1BLFFBQVEsR0FBR0MsT0FBTyxDQUFDLGFBQUQsQ0FBeEI7O0FBQ0EsTUFBTUMsSUFBSSxHQUFHRCxPQUFPLENBQUMsTUFBRCxDQUFwQjs7QUFFQSxNQUFNRSxtQkFBbUIsR0FBR0MsR0FBRyxJQUFJO0FBQ2pDLFNBQU8sSUFBSUMsT0FBSixDQUFZLENBQUNDLEdBQUQsRUFBTUMsR0FBTixLQUFjO0FBQy9CTCxJQUFBQSxJQUFJLENBQ0RNLEdBREgsQ0FDT0osR0FEUCxFQUNZSyxRQUFRLElBQUk7QUFDcEJBLE1BQUFBLFFBQVEsQ0FBQ0Msa0JBQVQsQ0FBNEIs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Z0JBQVQsQ0FBMEJ4QixHQUExQixFQUErQm1CLGVBQS9CLEVBQWdEO0FBQzlDLFNBQU9uQixHQUFHLENBQUMxQixHQUFKLENBQVEsT0FBUixLQUFvQixPQUFPNkMsZUFBZSxDQUFDMEQsT0FBaEIsQ0FBd0JwRCxnQkFBL0IsS0FBb0QsVUFBL0U7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBleHByZXNzIGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IEJvZHlQYXJzZXIgZnJvbSAnYm9keS1wYXJzZXInO1xuaW1wb3J0ICogYXMgTWlkZGxld2FyZXMgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuLi9Db25maWcnO1xuaW1wb3J0IG1pbWUgZnJvbSAnbWltZSc7XG5pbXBvcnQgbG9nZ2VyIGZyb20gJy4uL2xvZ2dlcic7XG5jb25zdCB0cmlnZ2VycyA9IHJlcXVpcmUoJy4uL3RyaWdnZXJzJyk7XG5jb25zdCBodHRwID0gcmVxdWlyZSgnaHR0cCcpO1xuXG5jb25zdCBkb3dubG9hZEZpbGVGcm9tVVJJID0gdXJpID0+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXMsIHJlaikgPT4ge1xuICAgIGh0dHBcbiAgICAgIC5nZXQodXJpLCByZXNwb25zZSA9PiB7XG4gICAgICAgIHJlc3BvbnNlLnNldERlZmF1bHRFbmNvZGluZygnYmFzZTY0Jyk7XG4gICAgICAgIGxldCBib2R5ID0gYGRhdGE6JHtyZXNwb25zZS5oZWFkZXJzWydjb250ZW50LXR5cGUnXX07YmFzZTY0LGA7XG4gICAgICAgIHJlc3BvbnNlLm9uKCdkYXRhJywgZGF0YSA9PiAoYm9keSArPSBkYXRhKSk7XG4gICAgICAgIHJlc3BvbnNlLm9uKCdlbmQnLCAoKSA9PiByZXMoYm9keSkpO1xuICAgICAgfSlcbiAgICAgIC5vbignZXJyb3InLCBlID0+IHtcbiAgICAgICAgcmVqKGBFcnJvciBkb3dubG9hZGluZyBmaWxlIGZyb20gJHt1cml9OiAke2UubWVzc2FnZX1gKTtcbiAgICAgIH0pO1xuICB9KTtcbn07XG5cbmNvbnN0IGFkZEZpbGVEYXRhSWZOZWVkZWQgPSBhc3luYyBmaWxlID0+IHtcbiAgaWYgKGZpbGUuX3NvdXJjZS5mb3JtYXQgPT09ICd1cmknKSB7XG4gICAgY29uc3QgYmFzZTY0ID0gYXdhaXQgZG93bmxvYWRGaWxlRnJvbVVSSShmaWxlLl9zb3VyY2UudXJpKTtcbiAgICBmaWxlLl9wcmV2aW91c1NhdmUgPSBmaWxlO1xuICAgIGZpbGUuX2RhdGEgPSBiYXNlNjQ7XG4gICAgZmlsZS5fcmVxdWVzdFRhc2sgPSBudWxsO1xuICB9XG4gIHJldHVybiBmaWxlO1xufTtcblxuZXhwb3J0IGNsYXNzIEZpbGVzUm91dGVyIHtcbiAgZXhwcmVzc1JvdXRlcih7IG1heFVwbG9hZFNpemUgPSAnMjBNYicgfSA9IHt9KSB7XG4gICAgdmFyIHJvdXRlciA9IGV4cHJlc3MuUm91dGVyKCk7XG4gICAgcm91dGVyLmdldCgnL2ZpbGVzLzphcHBJZC86ZmlsZW5hbWUnLCB0aGlzLmdldEhhbmRsZXIpO1xuICAgIHJvdXRlci5nZXQoJy9maWxlcy86YXBwSWQvbWV0YWRhdGEvOmZpbGVuYW1lJywgdGhpcy5tZXRhZGF0YUhhbmRsZXIpO1xuXG4gICAgcm91dGVyLnBvc3QoJy9maWxlcycsIGZ1bmN0aW9uIChyZXEsIHJlcywgbmV4dCkge1xuICAgICAgbmV4dChuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9GSUxFX05BTUUsICdGaWxlbmFtZSBub3QgcHJvdmlkZWQuJykpO1xuICAgIH0pO1xuXG4gICAgcm91dGVyLnBvc3QoXG4gICAgICAnL2ZpbGVzLzpmaWxlbmFtZScsXG4gICAgICBCb2R5UGFyc2VyLnJhdyh7XG4gICAgICAgIHR5cGU6ICgpID0+IHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSxcbiAgICAgICAgbGltaXQ6IG1heFVwbG9hZFNpemUsXG4gICAgICB9KSwgLy8gQWxsb3cgdXBsb2FkcyB3aXRob3V0IENvbnRlbnQtVHlwZSwgb3Igd2l0aCBhbnkgQ29udGVudC1UeXBlLlxuICAgICAgTWlkZGxld2FyZXMuaGFuZGxlUGFyc2VIZWFkZXJzLFxuICAgICAgdGhpcy5jcmVhdGVIYW5kbGVyXG4gICAgKTtcblxuICAgIHJvdXRlci5kZWxldGUoXG4gICAgICAnL2ZpbGVzLzpmaWxlbmFtZScsXG4gICAgICBNaWRkbGV3YXJlcy5oYW5kbGVQYXJzZUhlYWRlcnMsXG4gICAgICBNaWRkbGV3YXJlcy5lbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5kZWxldGVIYW5kbGVyXG4gICAgKTtcbiAgICByZXR1cm4gcm91dGVyO1xuICB9XG5cbiAgZ2V0SGFuZGxlcihyZXEsIHJlcykge1xuICAgIGNvbnN0IGNvbmZpZyA9IENvbmZpZy5nZXQocmVxLnBhcmFtcy5hcHBJZCk7XG4gICAgY29uc3QgZmlsZXNDb250cm9sbGVyID0gY29uZmlnLmZpbGVzQ29udHJvbGxlcjtcbiAgICBjb25zdCBmaWxlbmFtZSA9IHJlcS5wYXJhbXMuZmlsZW5hbWU7XG4gICAgY29uc3QgY29udGVudFR5cGUgPSBtaW1lLmdldFR5cGUoZmlsZW5hbWUpO1xuICAgIGlmIChpc0ZpbGVTdHJlYW1hYmxlKHJlcSwgZmlsZXNDb250cm9sbGVyKSkge1xuICAgICAgZmlsZXNDb250cm9sbGVyLmhhbmRsZUZpbGVTdHJlYW0oY29uZmlnLCBmaWxlbmFtZSwgcmVxLCByZXMsIGNvbnRlbnRUeXBlKS5jYXRjaCgoKSA9PiB7XG4gICAgICAgIHJlcy5zdGF0dXMoNDA0KTtcbiAgICAgICAgcmVzLnNldCgnQ29udGVudC1UeXBlJywgJ3RleHQvcGxhaW4nKTtcbiAgICAgICAgcmVzLmVuZCgnRmlsZSBub3QgZm91bmQuJyk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZmlsZXNDb250cm9sbGVyXG4gICAgICAgIC5nZXRGaWxlRGF0YShjb25maWcsIGZpbGVuYW1lKVxuICAgICAgICAudGhlbihkYXRhID0+IHtcbiAgICAgICAgICByZXMuc3RhdHVzKDIwMCk7XG4gICAgICAgICAgcmVzLnNldCgnQ29udGVudC1UeXBlJywgY29udGVudFR5cGUpO1xuICAgICAgICAgIHJlcy5zZXQoJ0NvbnRlbnQtTGVuZ3RoJywgZGF0YS5sZW5ndGgpO1xuICAgICAgICAgIHJlcy5lbmQoZGF0YSk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgcmVzLnN0YXR1cyg0MDQpO1xuICAgICAgICAgIHJlcy5zZXQoJ0NvbnRlbnQtVHlwZScsICd0ZXh0L3BsYWluJyk7XG4gICAgICAgICAgcmVzLmVuZCgnRmlsZSBub3QgZm91bmQuJyk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZUhhbmRsZXIocmVxLCByZXMsIG5leHQpIHtcbiAgICBjb25zdCBjb25maWcgPSByZXEuY29uZmlnO1xuICAgIGNvbnN0IHVzZXIgPSByZXEuYXV0aC51c2VyO1xuICAgIGNvbnN0IGlzTWFzdGVyID0gcmVxLmF1dGguaXNNYXN0ZXI7XG4gICAgY29uc3QgaXNMaW5rZWQgPSB1c2VyICYmIFBhcnNlLkFub255bW91c1V0aWxzLmlzTGlua2VkKHVzZXIpO1xuICAgIGlmICghaXNNYXN0ZXIgJiYgIWNvbmZpZy5maWxlVXBsb2FkLmVuYWJsZUZvckFub255bW91c1VzZXIgJiYgaXNMaW5rZWQpIHtcbiAgICAgIG5leHQobmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5GSUxFX1NBVkVfRVJST1IsXG4gICAgICAgICdGaWxlIHVwbG9hZCBieSBhbm9ueW1vdXMgdXNlciBpcyBkaXNhYmxlZC4nXG4gICAgICApKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCFpc01hc3RlciAmJiAhY29uZmlnLmZpbGVVcGxvYWQuZW5hYmxlRm9yQXV0aGVudGljYXRlZFVzZXIgJiYgIWlzTGlua2VkICYmIHVzZXIpIHtcbiAgICAgIG5leHQobmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5GSUxFX1NBVkVfRVJST1IsXG4gICAgICAgICdGaWxlIHVwbG9hZCBieSBhdXRoZW50aWNhdGVkIHVzZXIgaXMgZGlzYWJsZWQuJ1xuICAgICAgKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghaXNNYXN0ZXIgJiYgIWNvbmZpZy5maWxlVXBsb2FkLmVuYWJsZUZvclB1YmxpYyAmJiAhdXNlcikge1xuICAgICAgbmV4dChuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRklMRV9TQVZFX0VSUk9SLCAnRmlsZSB1cGxvYWQgYnkgcHVibGljIGlzIGRpc2FibGVkLicpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZmlsZXNDb250cm9sbGVyID0gY29uZmlnLmZpbGVzQ29udHJvbGxlcjtcbiAgICBjb25zdCB7IGZpbGVuYW1lIH0gPSByZXEucGFyYW1zO1xuICAgIGNvbnN0IGNvbnRlbnRUeXBlID0gcmVxLmdldCgnQ29udGVudC10eXBlJyk7XG5cbiAgICBpZiAoIXJlcS5ib2R5IHx8ICFyZXEuYm9keS5sZW5ndGgpIHtcbiAgICAgIG5leHQobmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkZJTEVfU0FWRV9FUlJPUiwgJ0ludmFsaWQgZmlsZSB1cGxvYWQuJykpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGVycm9yID0gZmlsZXNDb250cm9sbGVyLnZhbGlkYXRlRmlsZW5hbWUoZmlsZW5hbWUpO1xuICAgIGlmIChlcnJvcikge1xuICAgICAgbmV4dChlcnJvcik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgYmFzZTY0ID0gcmVxLmJvZHkudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuICAgIGNvbnN0IGZpbGUgPSBuZXcgUGFyc2UuRmlsZShmaWxlbmFtZSwgeyBiYXNlNjQgfSwgY29udGVudFR5cGUpO1xuICAgIGNvbnN0IHsgbWV0YWRhdGEgPSB7fSwgdGFncyA9IHt9IH0gPSByZXEuZmlsZURhdGEgfHwge307XG4gICAgZmlsZS5zZXRUYWdzKHRhZ3MpO1xuICAgIGZpbGUuc2V0TWV0YWRhdGEobWV0YWRhdGEpO1xuICAgIGNvbnN0IGZpbGVTaXplID0gQnVmZmVyLmJ5dGVMZW5ndGgocmVxLmJvZHkpO1xuICAgIGNvbnN0IGZpbGVPYmplY3QgPSB7IGZpbGUsIGZpbGVTaXplIH07XG4gICAgdHJ5IHtcbiAgICAgIC8vIHJ1biBiZWZvcmVTYXZlRmlsZSB0cmlnZ2VyXG4gICAgICBjb25zdCB0cmlnZ2VyUmVzdWx0ID0gYXdhaXQgdHJpZ2dlcnMubWF5YmVSdW5GaWxlVHJpZ2dlcihcbiAgICAgICAgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlU2F2ZUZpbGUsXG4gICAgICAgIGZpbGVPYmplY3QsXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgcmVxLmF1dGhcbiAgICAgICk7XG4gICAgICBsZXQgc2F2ZVJlc3VsdDtcbiAgICAgIC8vIGlmIGEgbmV3IFBhcnNlRmlsZSBpcyByZXR1cm5lZCBjaGVjayBpZiBpdCdzIGFuIGFscmVhZHkgc2F2ZWQgZmlsZVxuICAgICAgaWYgKHRyaWdnZXJSZXN1bHQgaW5zdGFuY2VvZiBQYXJzZS5GaWxlKSB7XG4gICAgICAgIGZpbGVPYmplY3QuZmlsZSA9IHRyaWdnZXJSZXN1bHQ7XG4gICAgICAgIGlmICh0cmlnZ2VyUmVzdWx0LnVybCgpKSB7XG4gICAgICAgICAgLy8gc2V0IGZpbGVTaXplIHRvIG51bGwgYmVjYXVzZSB3ZSB3b250IGtub3cgaG93IGJpZyBpdCBpcyBoZXJlXG4gICAgICAgICAgZmlsZU9iamVjdC5maWxlU2l6ZSA9IG51bGw7XG4gICAgICAgICAgc2F2ZVJlc3VsdCA9IHtcbiAgICAgICAgICAgIHVybDogdHJpZ2dlclJlc3VsdC51cmwoKSxcbiAgICAgICAgICAgIG5hbWU6IHRyaWdnZXJSZXN1bHQuX25hbWUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gaWYgdGhlIGZpbGUgcmV0dXJuZWQgYnkgdGhlIHRyaWdnZXIgaGFzIGFscmVhZHkgYmVlbiBzYXZlZCBza2lwIHNhdmluZyBhbnl0aGluZ1xuICAgICAgaWYgKCFzYXZlUmVzdWx0KSB7XG4gICAgICAgIC8vIGlmIHRoZSBQYXJzZUZpbGUgcmV0dXJuZWQgaXMgdHlwZSB1cmksIGRvd25sb2FkIHRoZSBmaWxlIGJlZm9yZSBzYXZpbmcgaXRcbiAgICAgICAgYXdhaXQgYWRkRmlsZURhdGFJZk5lZWRlZChmaWxlT2JqZWN0LmZpbGUpO1xuICAgICAgICAvLyB1cGRhdGUgZmlsZVNpemVcbiAgICAgICAgY29uc3QgYnVmZmVyRGF0YSA9IEJ1ZmZlci5mcm9tKGZpbGVPYmplY3QuZmlsZS5fZGF0YSwgJ2Jhc2U2NCcpO1xuICAgICAgICBmaWxlT2JqZWN0LmZpbGVTaXplID0gQnVmZmVyLmJ5dGVMZW5ndGgoYnVmZmVyRGF0YSk7XG4gICAgICAgIC8vIHNhdmUgZmlsZVxuICAgICAgICBjb25zdCBjcmVhdGVGaWxlUmVzdWx0ID0gYXdhaXQgZmlsZXNDb250cm9sbGVyLmNyZWF0ZUZpbGUoXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIGZpbGVPYmplY3QuZmlsZS5fbmFtZSxcbiAgICAgICAgICBidWZmZXJEYXRhLFxuICAgICAgICAgIGZpbGVPYmplY3QuZmlsZS5fc291cmNlLnR5cGUsXG4gICAgICAgICAge1xuICAgICAgICAgICAgdGFnczogZmlsZU9iamVjdC5maWxlLl90YWdzLFxuICAgICAgICAgICAgbWV0YWRhdGE6IGZpbGVPYmplY3QuZmlsZS5fbWV0YWRhdGEsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICAvLyB1cGRhdGUgZmlsZSB3aXRoIG5ldyBkYXRhXG4gICAgICAgIGZpbGVPYmplY3QuZmlsZS5fbmFtZSA9IGNyZWF0ZUZpbGVSZXN1bHQubmFtZTtcbiAgICAgICAgZmlsZU9iamVjdC5maWxlLl91cmwgPSBjcmVhdGVGaWxlUmVzdWx0LnVybDtcbiAgICAgICAgZmlsZU9iamVjdC5maWxlLl9yZXF1ZXN0VGFzayA9IG51bGw7XG4gICAgICAgIGZpbGVPYmplY3QuZmlsZS5fcHJldmlvdXNTYXZlID0gUHJvbWlzZS5yZXNvbHZlKGZpbGVPYmplY3QuZmlsZSk7XG4gICAgICAgIHNhdmVSZXN1bHQgPSB7XG4gICAgICAgICAgdXJsOiBjcmVhdGVGaWxlUmVzdWx0LnVybCxcbiAgICAgICAgICBuYW1lOiBjcmVhdGVGaWxlUmVzdWx0Lm5hbWUsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICAvLyBydW4gYWZ0ZXJTYXZlRmlsZSB0cmlnZ2VyXG4gICAgICBhd2FpdCB0cmlnZ2Vycy5tYXliZVJ1bkZpbGVUcmlnZ2VyKFxuICAgICAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlclNhdmVGaWxlLFxuICAgICAgICBmaWxlT2JqZWN0LFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHJlcS5hdXRoXG4gICAgICApO1xuICAgICAgcmVzLnN0YXR1cygyMDEpO1xuICAgICAgcmVzLnNldCgnTG9jYXRpb24nLCBzYXZlUmVzdWx0LnVybCk7XG4gICAgICByZXMuanNvbihzYXZlUmVzdWx0KTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIGNyZWF0aW5nIGEgZmlsZTogJywgZSk7XG4gICAgICBjb25zdCBlcnJvciA9IHRyaWdnZXJzLnJlc29sdmVFcnJvcihlLCB7XG4gICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLkZJTEVfU0FWRV9FUlJPUixcbiAgICAgICAgbWVzc2FnZTogYENvdWxkIG5vdCBzdG9yZSBmaWxlOiAke2ZpbGVPYmplY3QuZmlsZS5fbmFtZX0uYCxcbiAgICAgIH0pO1xuICAgICAgbmV4dChlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZGVsZXRlSGFuZGxlcihyZXEsIHJlcywgbmV4dCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IGZpbGVzQ29udHJvbGxlciB9ID0gcmVxLmNvbmZpZztcbiAgICAgIGNvbnN0IHsgZmlsZW5hbWUgfSA9IHJlcS5wYXJhbXM7XG4gICAgICAvLyBydW4gYmVmb3JlRGVsZXRlRmlsZSB0cmlnZ2VyXG4gICAgICBjb25zdCBmaWxlID0gbmV3IFBhcnNlLkZpbGUoZmlsZW5hbWUpO1xuICAgICAgZmlsZS5fdXJsID0gZmlsZXNDb250cm9sbGVyLmFkYXB0ZXIuZ2V0RmlsZUxvY2F0aW9uKHJlcS5jb25maWcsIGZpbGVuYW1lKTtcbiAgICAgIGNvbnN0IGZpbGVPYmplY3QgPSB7IGZpbGUsIGZpbGVTaXplOiBudWxsIH07XG4gICAgICBhd2FpdCB0cmlnZ2Vycy5tYXliZVJ1bkZpbGVUcmlnZ2VyKFxuICAgICAgICB0cmlnZ2Vycy5UeXBlcy5iZWZvcmVEZWxldGVGaWxlLFxuICAgICAgICBmaWxlT2JqZWN0LFxuICAgICAgICByZXEuY29uZmlnLFxuICAgICAgICByZXEuYXV0aFxuICAgICAgKTtcbiAgICAgIC8vIGRlbGV0ZSBmaWxlXG4gICAgICBhd2FpdCBmaWxlc0NvbnRyb2xsZXIuZGVsZXRlRmlsZShyZXEuY29uZmlnLCBmaWxlbmFtZSk7XG4gICAgICAvLyBydW4gYWZ0ZXJEZWxldGVGaWxlIHRyaWdnZXJcbiAgICAgIGF3YWl0IHRyaWdnZXJzLm1heWJlUnVuRmlsZVRyaWdnZXIoXG4gICAgICAgIHRyaWdnZXJzLlR5cGVzLmFmdGVyRGVsZXRlRmlsZSxcbiAgICAgICAgZmlsZU9iamVjdCxcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgcmVxLmF1dGhcbiAgICAgICk7XG4gICAgICByZXMuc3RhdHVzKDIwMCk7XG4gICAgICAvLyBUT0RPOiByZXR1cm4gdXNlZnVsIEpTT04gaGVyZT9cbiAgICAgIHJlcy5lbmQoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIGRlbGV0aW5nIGEgZmlsZTogJywgZSk7XG4gICAgICBjb25zdCBlcnJvciA9IHRyaWdnZXJzLnJlc29sdmVFcnJvcihlLCB7XG4gICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLkZJTEVfREVMRVRFX0VSUk9SLFxuICAgICAgICBtZXNzYWdlOiAnQ291bGQgbm90IGRlbGV0ZSBmaWxlLicsXG4gICAgICB9KTtcbiAgICAgIG5leHQoZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIG1ldGFkYXRhSGFuZGxlcihyZXEsIHJlcykge1xuICAgIGNvbnN0IGNvbmZpZyA9IENvbmZpZy5nZXQocmVxLnBhcmFtcy5hcHBJZCk7XG4gICAgY29uc3QgeyBmaWxlc0NvbnRyb2xsZXIgfSA9IGNvbmZpZztcbiAgICBjb25zdCB7IGZpbGVuYW1lIH0gPSByZXEucGFyYW1zO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgZmlsZXNDb250cm9sbGVyLmdldE1ldGFkYXRhKGZpbGVuYW1lKTtcbiAgICAgIHJlcy5zdGF0dXMoMjAwKTtcbiAgICAgIHJlcy5qc29uKGRhdGEpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJlcy5zdGF0dXMoMjAwKTtcbiAgICAgIHJlcy5qc29uKHt9KTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNGaWxlU3RyZWFtYWJsZShyZXEsIGZpbGVzQ29udHJvbGxlcikge1xuICByZXR1cm4gcmVxLmdldCgnUmFuZ2UnKSAmJiB0eXBlb2YgZmlsZXNDb250cm9sbGVyLmFkYXB0ZXIuaGFuZGxlRmlsZVN0cmVhbSA9PT0gJ2Z1bmN0aW9uJztcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/FunctionsRouter.js b/lib/Routers/FunctionsRouter.js deleted file mode 100644 index 0e5c6b67d3..0000000000 --- a/lib/Routers/FunctionsRouter.js +++ /dev/null @@ -1,181 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.FunctionsRouter = void 0; - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var _middlewares = require("../middlewares"); - -var _StatusHandler = require("../StatusHandler"); - -var _lodash = _interopRequireDefault(require("lodash")); - -var _logger = require("../logger"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// FunctionsRouter.js -var Parse = require('parse/node').Parse, - triggers = require('../triggers'); - -function parseObject(obj) { - if (Array.isArray(obj)) { - return obj.map(item => { - return parseObject(item); - }); - } else if (obj && obj.__type == 'Date') { - return Object.assign(new Date(obj.iso), obj); - } else if (obj && obj.__type == 'File') { - return Parse.File.fromJSON(obj); - } else if (obj && typeof obj === 'object') { - return parseParams(obj); - } else { - return obj; - } -} - -function parseParams(params) { - return _lodash.default.mapValues(params, parseObject); -} - -class FunctionsRouter extends _PromiseRouter.default { - mountRoutes() { - this.route('POST', '/functions/:functionName', _middlewares.promiseEnsureIdempotency, FunctionsRouter.handleCloudFunction); - this.route('POST', '/jobs/:jobName', _middlewares.promiseEnsureIdempotency, _middlewares.promiseEnforceMasterKeyAccess, function (req) { - return FunctionsRouter.handleCloudJob(req); - }); - this.route('POST', '/jobs', _middlewares.promiseEnforceMasterKeyAccess, function (req) { - return FunctionsRouter.handleCloudJob(req); - }); - } - - static handleCloudJob(req) { - const jobName = req.params.jobName || req.body.jobName; - const applicationId = req.config.applicationId; - const jobHandler = (0, _StatusHandler.jobStatusHandler)(req.config); - const jobFunction = triggers.getJob(jobName, applicationId); - - if (!jobFunction) { - throw new Parse.Error(Parse.Error.SCRIPT_FAILED, 'Invalid job.'); - } - - let params = Object.assign({}, req.body, req.query); - params = parseParams(params); - const request = { - params: params, - log: req.config.loggerController, - headers: req.config.headers, - ip: req.config.ip, - jobName, - message: jobHandler.setMessage.bind(jobHandler) - }; - return jobHandler.setRunning(jobName, params).then(jobStatus => { - request.jobId = jobStatus.objectId; // run the function async - - process.nextTick(() => { - Promise.resolve().then(() => { - return jobFunction(request); - }).then(result => { - jobHandler.setSucceeded(result); - }, error => { - jobHandler.setFailed(error); - }); - }); - return { - headers: { - 'X-Parse-Job-Status-Id': jobStatus.objectId - }, - response: {} - }; - }); - } - - static createResponseObject(resolve, reject) { - return { - success: function (result) { - resolve({ - response: { - result: Parse._encode(result) - } - }); - }, - error: function (message) { - const error = triggers.resolveError(message); - reject(error); - } - }; - } - - static handleCloudFunction(req) { - const functionName = req.params.functionName; - const applicationId = req.config.applicationId; - const theFunction = triggers.getFunction(functionName, applicationId); - - if (!theFunction) { - throw new Parse.Error(Parse.Error.SCRIPT_FAILED, `Invalid function: "${functionName}"`); - } - - let params = Object.assign({}, req.body, req.query); - params = parseParams(params); - const request = { - params: params, - master: req.auth && req.auth.isMaster, - user: req.auth && req.auth.user, - installationId: req.info.installationId, - log: req.config.loggerController, - headers: req.config.headers, - ip: req.config.ip, - functionName, - context: req.info.context - }; - return new Promise(function (resolve, reject) { - const userString = req.auth && req.auth.user ? req.auth.user.id : undefined; - - const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(params)); - - const { - success, - error - } = FunctionsRouter.createResponseObject(result => { - try { - const cleanResult = _logger.logger.truncateLogMessage(JSON.stringify(result.response.result)); - - _logger.logger.info(`Ran cloud function ${functionName} for user ${userString} with:\n Input: ${cleanInput}\n Result: ${cleanResult}`, { - functionName, - params, - user: userString - }); - - resolve(result); - } catch (e) { - reject(e); - } - }, error => { - try { - _logger.logger.error(`Failed running cloud function ${functionName} for user ${userString} with:\n Input: ${cleanInput}\n Error: ` + JSON.stringify(error), { - functionName, - error, - params, - user: userString - }); - - reject(error); - } catch (e) { - reject(e); - } - }); - return Promise.resolve().then(() => { - return triggers.maybeRunValidator(request, functionName); - }).then(() => { - return theFunction(request); - }).then(success, error); - }); - } - -} - -exports.FunctionsRouter = FunctionsRouter; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0Z1bmN0aW9uc1JvdXRlci5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJ0cmlnZ2VycyIsInBhcnNlT2JqZWN0Iiwib2JqIiwiQXJyYXkiLCJpc0FycmF5IiwibWFwIiwiaXRlbSIsIl9fdHlwZSIsIk9iamVjdCIsImFzc2lnbiIsIkRhdGUiLCJpc28iLCJGaWxlIiwiZnJvbUpTT04iLCJwYXJzZVBhcmFtcyIsInBhcmFtcyIsIl8iLCJtYXBWYWx1ZXMiLCJGdW5jdGlvbnNSb3V0ZXIiLCJQcm9taXNlUm91dGVyIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsInByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSIsImhhbmRsZUNsb3VkRnVuY3Rpb24iLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyIsInJlcSIsImhhbmRsZUNsb3VkSm9iIiwiam9iTmFtZSIsImJvZHkiLCJhcHBsaWNhdGlvbklkIiwiY29uZmlnIiwiam9iSGFuZGxlciIsImpvYkZ1bmN0aW9uIiwiZ2V0Sm9iIiwiRXJyb3IiLCJTQ1JJUFRfRkFJTEVEIiwicXVlcnkiLCJyZXF1ZXN0IiwibG9nIiwibG9nZ2VyQ29udHJvbGxlciIsImhlYWRlcnMiLCJpcCIsIm1lc3NhZ2UiLCJzZXRNZXNzYWdlIiwiYmluZCIsInNldFJ1bm5pbmciLCJ0aGVuIiwiam9iU3RhdHVzIiwiam9iSWQiLCJvYmplY3RJZCIsInByb2Nlc3MiLCJuZXh0VGljayIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVzdWx0Iiwic2V0U3VjY2VlZGVkIiwiZXJyb3IiLCJzZXRGYWlsZWQiLCJyZXNwb25zZSIsImNyZWF0ZVJlc3BvbnNlT2JqZWN0IiwicmVqZWN0Iiwic3VjY2VzcyIsIl9lbmNvZGUiLCJyZXNvbHZlRXJyb3IiLCJmdW5jdGlvbk5hbWUiLCJ0aGVGdW5jdGlvbiIsImdldEZ1bmN0aW9uIiwibWFzdGVyIiwiYXV0aCIsImlzTWFzdGVyIiwidXNlciIsImluc3RhbGxhdGlvbklkIiwiaW5mbyIsImNvbnRleHQiLCJ1c2VyU3RyaW5nIiwiaWQiLCJ1bmRlZmluZWQiLCJjbGVhbklucHV0IiwibG9nZ2VyIiwidHJ1bmNhdGVMb2dNZXNzYWdlIiwiSlNPTiIsInN0cmluZ2lmeSIsImNsZWFuUmVzdWx0IiwiZSIsIm1heWJlUnVuVmFsaWRhdG9yIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBS0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFUQTtBQUVBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBbEM7QUFBQSxJQUNFRSxRQUFRLEdBQUdELE9BQU8sQ0FBQyxhQUFELENBRHBCOztBQVNBLFNBQVNFLFdBQVQsQ0FBcUJDLEdBQXJCLEVBQTBCO0FBQ3hCLE1BQUlDLEtBQUssQ0FBQ0MsT0FBTixDQUFjRixHQUFkLENBQUosRUFBd0I7QUFDdEIsV0FBT0EsR0FBRyxDQUFDRyxHQUFKLENBQVFDLElBQUksSUFBSTtBQUNyQixhQUFPTCxXQUFXLENBQUNLLElBQUQsQ0FBbEI7QUFDRCxLQUZNLENBQVA7QUFHRCxHQUpELE1BSU8sSUFBSUosR0FBRyxJQUFJQSxHQUFHLENBQUNLLE1BQUosSUFBYyxNQUF6QixFQUFpQztBQUN0QyxXQUFPQyxNQUFNLENBQUNDLE1BQVAsQ0FBYyxJQUFJQyxJQUFKLENBQVNSLEdBQUcsQ0FBQ1MsR0FBYixDQUFkLEVBQWlDVCxHQUFqQyxDQUFQO0FBQ0QsR0FGTSxNQUVBLElBQUlBLEdBQUcsSUFBSUEsR0FBRyxDQUFDSyxNQUFKLElBQWMsTUFBekIsRUFBaUM7QUFDdEMsV0FBT1QsS0FBSyxDQUFDYyxJQUFOLENBQVdDLFFBQVgsQ0FBb0JYLEdBQXBCLENBQVA7QUFDRCxHQUZNLE1BRUEsSUFBSUEsR0FBRyxJQUFJLE9BQU9BLEdBQVAsS0FBZSxRQUExQixFQUFvQztBQUN6QyxXQUFPWSxXQUFXLENBQUNaLEdBQUQsQ0FBbEI7QUFDRCxHQUZNLE1BRUE7QUFDTCxXQUFPQSxHQUFQO0FBQ0Q7QUFDRjs7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LEVBQW9DMkIsWUFBcEMsQ0FBUDtBQUNELE9BSEksRUFJSmxCLElBSkksQ0FJQyxNQUFNO0FBQ1YsZUFBT21CLFdBQVcsQ0FBQzVCLE9BQUQsQ0FBbEI7QUFDRCxPQU5JLEVBT0pTLElBUEksQ0FPQ2UsT0FQRCxFQU9VTCxLQVBWLENBQVA7QUFRRCxLQTlDTSxDQUFQO0FBK0NEOztBQXZKZ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBGdW5jdGlvbnNSb3V0ZXIuanNcblxudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlLFxuICB0cmlnZ2VycyA9IHJlcXVpcmUoJy4uL3RyaWdnZXJzJyk7XG5cbmltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0IHsgcHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSB9IGZyb20gJy4uL21pZGRsZXdhcmVzJztcbmltcG9ydCB7IGpvYlN0YXR1c0hhbmRsZXIgfSBmcm9tICcuLi9TdGF0dXNIYW5kbGVyJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuLi9sb2dnZXInO1xuXG5mdW5jdGlvbiBwYXJzZU9iamVjdChvYmopIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgIHJldHVybiBvYmoubWFwKGl0ZW0gPT4ge1xuICAgICAgcmV0dXJuIHBhcnNlT2JqZWN0KGl0ZW0pO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKG9iaiAmJiBvYmouX190eXBlID09ICdEYXRlJykge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKG5ldyBEYXRlKG9iai5pc28pLCBvYmopO1xuICB9IGVsc2UgaWYgKG9iaiAmJiBvYmouX190eXBlID09ICdGaWxlJykge1xuICAgIHJldHVybiBQYXJzZS5GaWxlLmZyb21KU09OKG9iaik7XG4gIH0gZWxzZSBpZiAob2JqICYmIHR5cGVvZiBvYmogPT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIHBhcnNlUGFyYW1zKG9iaik7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG9iajtcbiAgfVxufVxuXG5mdW5jdGlvbiBwYXJzZVBhcmFtcyhwYXJhbXMpIHtcbiAgcmV0dXJuIF8ubWFwVmFsdWVzKHBhcmFtcywgcGFyc2VPYmplY3QpO1xufVxuXG5leHBvcnQgY2xhc3MgRnVuY3Rpb25zUm91dGVyIGV4dGVuZHMgUHJvbWlzZVJvdXRlciB7XG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnUE9TVCcsXG4gICAgICAnL2Z1bmN0aW9ucy86ZnVuY3Rpb25OYW1lJyxcbiAgICAgIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSxcbiAgICAgIEZ1bmN0aW9uc1JvdXRlci5oYW5kbGVDbG91ZEZ1bmN0aW9uXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ1BPU1QnLFxuICAgICAgJy9qb2JzLzpqb2JOYW1lJyxcbiAgICAgIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSxcbiAgICAgIHByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgZnVuY3Rpb24gKHJlcSkge1xuICAgICAgICByZXR1cm4gRnVuY3Rpb25zUm91dGVyLmhhbmRsZUNsb3VkSm9iKHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9qb2JzJywgcHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIGZ1bmN0aW9uIChyZXEpIHtcbiAgICAgIHJldHVybiBGdW5jdGlvbnNSb3V0ZXIuaGFuZGxlQ2xvdWRKb2IocmVxKTtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBoYW5kbGVDbG91ZEpvYihyZXEpIHtcbiAgICBjb25zdCBqb2JOYW1lID0gcmVxLnBhcmFtcy5qb2JOYW1lIHx8IHJlcS5ib2R5LmpvYk5hbWU7XG4gICAgY29uc3QgYXBwbGljYXRpb25JZCA9IHJlcS5jb25maWcuYXBwbGljYXRpb25JZDtcbiAgICBjb25zdCBqb2JIYW5kbGVyID0gam9iU3RhdHVzSGFuZGxlcihyZXEuY29uZmlnKTtcbiAgICBjb25zdCBqb2JGdW5jdGlvbiA9IHRyaWdnZXJzLmdldEpvYihqb2JOYW1lLCBhcHBsaWNhdGlvbklkKTtcbiAgICBpZiAoIWpvYkZ1bmN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuU0NSSVBUX0ZBSUxFRCwgJ0ludmFsaWQgam9iLicpO1xuICAgIH1cbiAgICBsZXQgcGFyYW1zID0gT2JqZWN0LmFzc2lnbih7fSwgcmVxLmJvZHksIHJlcS5xdWVyeSk7XG4gICAgcGFyYW1zID0gcGFyc2VQYXJhbXMocGFyYW1zKTtcbiAgICBjb25zdCByZXF1ZXN0ID0ge1xuICAgICAgcGFyYW1zOiBwYXJhbXMsXG4gICAgICBsb2c6IHJlcS5jb25maWcubG9nZ2VyQ29udHJvbGxlcixcbiAgICAgIGhlYWRlcnM6IHJlcS5jb25maWcuaGVhZGVycyxcbiAgICAgIGlwOiByZXEuY29uZmlnLmlwLFxuICAgICAgam9iTmFtZSxcbiAgICAgIG1lc3NhZ2U6IGpvYkhhbmRsZXIuc2V0TWVzc2FnZS5iaW5kKGpvYkhhbmRsZXIpLFxuICAgIH07XG5cbiAgICByZXR1cm4gam9iSGFuZGxlci5zZXRSdW5uaW5nKGpvYk5hbWUsIHBhcmFtcykudGhlbihqb2JTdGF0dXMgPT4ge1xuICAgICAgcmVxdWVzdC5qb2JJZCA9IGpvYlN0YXR1cy5vYmplY3RJZDtcbiAgICAgIC8vIHJ1biB0aGUgZnVuY3Rpb24gYXN5bmNcbiAgICAgIHByb2Nlc3MubmV4dFRpY2soKCkgPT4ge1xuICAgICAgICBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBqb2JGdW5jdGlvbihyZXF1ZXN0KTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC50aGVuKFxuICAgICAgICAgICAgcmVzdWx0ID0+IHtcbiAgICAgICAgICAgICAgam9iSGFuZGxlci5zZXRTdWNjZWVkZWQocmVzdWx0KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvciA9PiB7XG4gICAgICAgICAgICAgIGpvYkhhbmRsZXIuc2V0RmFpbGVkKGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgJ1gtUGFyc2UtSm9iLVN0YXR1cy1JZCc6IGpvYlN0YXR1cy5vYmplY3RJZCxcbiAgICAgICAgfSxcbiAgICAgICAgcmVzcG9uc2U6IHt9LFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBjcmVhdGVSZXNwb25zZU9iamVjdChyZXNvbHZlLCByZWplY3QpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgICAgcmVzdWx0OiBQYXJzZS5fZW5jb2RlKHJlc3VsdCksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgZXJyb3I6IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgICAgIGNvbnN0IGVycm9yID0gdHJpZ2dlcnMucmVzb2x2ZUVycm9yKG1lc3NhZ2UpO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSxcbiAgICB9O1xuICB9XG4gIHN0YXRpYyBoYW5kbGVDbG91ZEZ1bmN0aW9uKHJlcSkge1xuICAgIGNvbnN0IGZ1bmN0aW9uTmFtZSA9IHJlcS5wYXJhbXMuZnVuY3Rpb25OYW1lO1xuICAgIGNvbnN0IGFwcGxpY2F0aW9uSWQgPSByZXEuY29uZmlnLmFwcGxpY2F0aW9uSWQ7XG4gICAgY29uc3QgdGhlRnVuY3Rpb24gPSB0cmlnZ2Vycy5nZXRGdW5jdGlvbihmdW5jdGlvbk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xuXG4gICAgaWYgKCF0aGVGdW5jdGlvbikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlNDUklQVF9GQUlMRUQsIGBJbnZhbGlkIGZ1bmN0aW9uOiBcIiR7ZnVuY3Rpb25OYW1lfVwiYCk7XG4gICAgfVxuICAgIGxldCBwYXJhbXMgPSBPYmplY3QuYXNzaWduKHt9LCByZXEuYm9keSwgcmVxLnF1ZXJ5KTtcbiAgICBwYXJhbXMgPSBwYXJzZVBhcmFtcyhwYXJhbXMpO1xuICAgIGNvbnN0IHJlcXVlc3QgPSB7XG4gICAgICBwYXJhbXM6IHBhcmFtcyxcbiAgICAgIG1hc3RlcjogcmVxLmF1dGggJiYgcmVxLmF1dGguaXNNYXN0ZXIsXG4gICAgICB1c2VyOiByZXEuYXV0aCAmJiByZXEuYXV0aC51c2VyLFxuICAgICAgaW5zdGFsbGF0aW9uSWQ6IHJlcS5pbmZvLmluc3RhbGxhdGlvbklkLFxuICAgICAgbG9nOiByZXEuY29uZmlnLmxvZ2dlckNvbnRyb2xsZXIsXG4gICAgICBoZWFkZXJzOiByZXEuY29uZmlnLmhlYWRlcnMsXG4gICAgICBpcDogcmVxLmNvbmZpZy5pcCxcbiAgICAgIGZ1bmN0aW9uTmFtZSxcbiAgICAgIGNvbnRleHQ6IHJlcS5pbmZvLmNvbnRleHQsXG4gICAgfTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICBjb25zdCB1c2VyU3RyaW5nID0gcmVxLmF1dGggJiYgcmVxLmF1dGgudXNlciA/IHJlcS5hdXRoLnVzZXIuaWQgOiB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBjbGVhbklucHV0ID0gbG9nZ2VyLnRydW5jYXRlTG9nTWVzc2FnZShKU09OLnN0cmluZ2lmeShwYXJhbXMpKTtcbiAgICAgIGNvbnN0IHsgc3VjY2VzcywgZXJyb3IgfSA9IEZ1bmN0aW9uc1JvdXRlci5jcmVhdGVSZXNwb25zZU9iamVjdChcbiAgICAgICAgcmVzdWx0ID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgY2xlYW5SZXN1bHQgPSBsb2dnZXIudHJ1bmNhdGVMb2dNZXNzYWdlKEpTT04uc3RyaW5naWZ5KHJlc3VsdC5yZXNwb25zZS5yZXN1bHQpKTtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgICBgUmFuIGNsb3VkIGZ1bmN0aW9uICR7ZnVuY3Rpb25OYW1lfSBmb3IgdXNlciAke3VzZXJTdHJpbmd9IHdpdGg6XFxuICBJbnB1dDogJHtjbGVhbklucHV0fVxcbiAgUmVzdWx0OiAke2NsZWFuUmVzdWx0fWAsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmdW5jdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgICAgICAgIHVzZXI6IHVzZXJTdHJpbmcsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3IgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoXG4gICAgICAgICAgICAgIGBGYWlsZWQgcnVubmluZyBjbG91ZCBmdW5jdGlvbiAke2Z1bmN0aW9uTmFtZX0gZm9yIHVzZXIgJHt1c2VyU3RyaW5nfSB3aXRoOlxcbiAgSW5wdXQ6ICR7Y2xlYW5JbnB1dH1cXG4gIEVycm9yOiBgICtcbiAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShlcnJvciksXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBmdW5jdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgICAgICAgIHVzZXI6IHVzZXJTdHJpbmcsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIHJldHVybiB0cmlnZ2Vycy5tYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0LCBmdW5jdGlvbk5hbWUpO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHRoZUZ1bmN0aW9uKHJlcXVlc3QpO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihzdWNjZXNzLCBlcnJvcik7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/GlobalConfigRouter.js b/lib/Routers/GlobalConfigRouter.js deleted file mode 100644 index 7156f27974..0000000000 --- a/lib/Routers/GlobalConfigRouter.js +++ /dev/null @@ -1,95 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.GlobalConfigRouter = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// global_config.js -class GlobalConfigRouter extends _PromiseRouter.default { - getGlobalConfig(req) { - return req.config.database.find('_GlobalConfig', { - objectId: '1' - }, { - limit: 1 - }).then(results => { - if (results.length != 1) { - // If there is no config in the database - return empty config. - return { - response: { - params: {} - } - }; - } - - const globalConfig = results[0]; - - if (!req.auth.isMaster && globalConfig.masterKeyOnly !== undefined) { - for (const param in globalConfig.params) { - if (globalConfig.masterKeyOnly[param]) { - delete globalConfig.params[param]; - delete globalConfig.masterKeyOnly[param]; - } - } - } - - return { - response: { - params: globalConfig.params, - masterKeyOnly: globalConfig.masterKeyOnly - } - }; - }); - } - - updateGlobalConfig(req) { - if (req.auth.isReadOnly) { - throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to update the config."); - } - - const params = req.body.params; - const masterKeyOnly = req.body.masterKeyOnly || {}; // Transform in dot notation to make sure it works - - const update = Object.keys(params).reduce((acc, key) => { - acc[`params.${key}`] = params[key]; - acc[`masterKeyOnly.${key}`] = masterKeyOnly[key] || false; - return acc; - }, {}); - return req.config.database.update('_GlobalConfig', { - objectId: '1' - }, update, { - upsert: true - }).then(() => ({ - response: { - result: true - } - })); - } - - mountRoutes() { - this.route('GET', '/config', req => { - return this.getGlobalConfig(req); - }); - this.route('PUT', '/config', middleware.promiseEnforceMasterKeyAccess, req => { - return this.updateGlobalConfig(req); - }); - } - -} - -exports.GlobalConfigRouter = GlobalConfigRouter; -var _default = GlobalConfigRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0dsb2JhbENvbmZpZ1JvdXRlci5qcyJdLCJuYW1lcyI6WyJHbG9iYWxDb25maWdSb3V0ZXIiLCJQcm9taXNlUm91dGVyIiwiZ2V0R2xvYmFsQ29uZmlnIiwicmVxIiwiY29uZmlnIiwiZGF0YWJhc2UiLCJmaW5kIiwib2JqZWN0SWQiLCJsaW1pdCIsInRoZW4iLCJyZXN1bHRzIiwibGVuZ3RoIiwicmVzcG9uc2UiLCJwYXJhbXMiLCJnbG9iYWxDb25maWciLCJhdXRoIiwiaXNNYXN0ZXIiLCJtYXN0ZXJLZXlPbmx5IiwidW5kZWZpbmVkIiwicGFyYW0iLCJ1cGRhdGVHbG9iYWxDb25maWciLCJpc1JlYWRPbmx5IiwiUGFyc2UiLCJFcnJvciIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJib2R5IiwidXBkYXRlIiwiT2JqZWN0Iiwia2V5cyIsInJlZHVjZSIsImFjYyIsImtleSIsInVwc2VydCIsInJlc3VsdCIsIm1vdW50Um91dGVzIiwicm91dGUiLCJtaWRkbGV3YXJlIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFIQTtBQUtPLE1BQU1BLGtCQUFOLFNBQWlDQyxzQkFBakMsQ0FBK0M7QUFDcERDLEVBQUFBLGVBQWUsQ0FBQ0MsR0FBRCxFQUFNO0FBQ25CLFdBQU9BLEdBQUcsQ0FBQ0MsTUFBSixDQUFXQyxRQUFYLENBQ0pDLElBREksQ0FDQyxlQURELEVBQ2tCO0FBQUVDLE1BQUFBLFFBQVEsRUFBRTtBQUFaLEtBRGxCLEVBQ3FDO0FBQUVDLE1BQUFBLEtBQUssRUFBRTtBQUFULEtBRHJDLEVBRUpDLElBRkksQ0FFQ0MsT0FBTyxJQUFJO0FBQ2YsVUFBSUEsT0FBTyxDQUFDQyxNQUFSLElBQWtCLENBQXRCLEVBQXlCO0FBQ3ZCO0FBQ0EsZUFBTztBQUFFQyxVQUFBQSxRQUFRLEVBQUU7QUFBRUMsWUFBQUEsTUFBTSxFQUFFO0FBQVY7QUFBWixTQUFQO0FBQ0Q7O0FBQ0QsWUFBTUMsWUFBWSxHQUFHSixPQUFPLENBQUMsQ0FBRCxDQUE1Qjs7QUFDQSxVQUFJLENBQUNQLEdBQUcsQ0FBQ1ksSUFBSixDQUFTQyxRQUFWLElBQXNCRixZQUFZLENBQUNHLGFBQWIsS0FBK0JDLFNBQXpELEVBQW9FO0FBQ2xFLGFBQUssTUFBTUMsS0FBWCxJQUFvQkwsWUFBWSxDQUFDRCxNQUFqQyxFQUF5QztBQUN2QyxjQUFJQyxZQUFZLENBQUNHLGFBQWIsQ0FBMkJFLEtBQTNCLENBQUosRUFBdUM7QUFDckMsbUJBQU9MLFlBQVksQ0FBQ0QsTUFBYixDQUFvQk0sS0FBcEIsQ0FBUDtBQUNBLG1CQUFPTCxZQUFZLENBQUNHLGFBQWIsQ0FBMkJFLEtBQTNCLENBQVA7QUFDRDtBQUNGO0FBQ0Y7O0FBQ0QsYUFBTztBQUNMUCxRQUFBQSxRQUFRLEVBQUU7QUFDUkMsVUFBQUEsTUFBTSxFQUFFQyxZQUFZLENBQUNELE1BRGI7QUFFUkksVUFBQUEsYUFBYSxFQUFFSCxZQUFZLENBQUNHO0FBRnBCO0FBREwsT0FBUDtBQU1ELEtBdEJJLENBQVA7QUF1QkQ7O0FBRURHLEVBQUFBLGtCQUFrQixDQUFDakIsR0FBRCxFQUFNO0FBQ3RCLFFBQUlBLEdBQUcsQ0FBQ1ksSUFBSixDQUFTTSxVQUFiLEVBQXlCO0FBQ3ZCLFlBQU0sSUFBSUMsY0FBTUMsS0FBVixDQUNKRCxjQUFNQyxLQUFOLENBQVlDLG1CQURSLEVBRUoseURBRkksQ0FBTjtBQUlEOztBQUNELFVBQU1YLE1BQU0sR0FBR1YsR0FBRyxDQUFDc0IsSUFBSixDQUFTWixNQUF4QjtBQUNBLFVBQU1JLGFBQWEsR0FBR2QsR0FBRyxDQUFDc0IsSUFBSixDQUFTUixhQUFULElBQTBCLEVBQWhELENBUnNCLENBU3RCOztBQUNBLFVBQU1TLE1BQU0sR0FBR0MsTUFBTSxDQUFDQyxJQUFQLENBQVlmLE1BQVosRUFBb0JnQixNQUFwQixDQUEyQixDQUFDQyxHQUFELEVBQU1DLEdBQU4sS0FBYztBQUN0REQsTUFBQUEsR0FBRyxDQUFFLFVBQVNDLEdBQUksRUFBZixDQUFILEdBQXVCbEIsTUFBTSxDQUFDa0IsR0FBRCxDQUE3QjtBQUNBRCxNQUFBQSxHQUFHLENBQUUsaUJBQWdCQyxHQUFJLEVBQXRCLENBQUgsR0FBOEJkLGFBQWEsQ0FBQ2MsR0FBRCxDQUFiLElBQXNCLEtBQXBEO0FBQ0EsYUFBT0QsR0FBUDtBQUNELEtBSmMsRUFJWixFQUpZLENBQWY7QUFLQSxXQUFPM0IsR0FBRyxDQUFDQyxNQUFKLENBQVdDLFFBQVgsQ0FDSnFCLE1BREksQ0FDRyxlQURILEVBQ29CO0FBQUVuQixNQUFBQSxRQUFRLEVBQUU7QUFBWixLQURwQixFQUN1Q21CLE1BRHZDLEVBQytDO0FBQUVNLE1BQUFBLE1BQU0sRUFBRTtBQUFWLEtBRC9DLEVBRUp2QixJQUZJLENBRUMsT0FBTztBQUFFRyxNQUFBQSxRQUFRLEVBQUU7QUFBRXFCLFFBQUFBLE1BQU0sRUFBRTtBQUFWO0FBQVosS0FBUCxDQUZELENBQVA7QUFHRDs7QUFFREMsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxDQUFXLEtBQVgsRUFBa0IsU0FBbEIsRUFBNkJoQyxHQUFHLElBQUk7QUFDbEMsYUFBTyxLQUFLRCxlQUFMLENBQXFCQyxHQUFyQixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUtnQyxLQUFMLENBQVcsS0FBWCxFQUFrQixTQUFsQixFQUE2QkMsVUFBVSxDQUFDQyw2QkFBeEMsRUFBdUVsQyxHQUFHLElBQUk7QUFDNUUsYUFBTyxLQUFLaUIsa0JBQUwsQ0FBd0JqQixHQUF4QixDQUFQO0FBQ0QsS0FGRDtBQUdEOztBQXREbUQ7OztlQXlEdkNILGtCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gZ2xvYmFsX2NvbmZpZy5qc1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IFByb21pc2VSb3V0ZXIgZnJvbSAnLi4vUHJvbWlzZVJvdXRlcic7XG5pbXBvcnQgKiBhcyBtaWRkbGV3YXJlIGZyb20gJy4uL21pZGRsZXdhcmVzJztcblxuZXhwb3J0IGNsYXNzIEdsb2JhbENvbmZpZ1JvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBnZXRHbG9iYWxDb25maWcocmVxKSB7XG4gICAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2VcbiAgICAgIC5maW5kKCdfR2xvYmFsQ29uZmlnJywgeyBvYmplY3RJZDogJzEnIH0sIHsgbGltaXQ6IDEgfSlcbiAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICBpZiAocmVzdWx0cy5sZW5ndGggIT0gMSkge1xuICAgICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIGNvbmZpZyBpbiB0aGUgZGF0YWJhc2UgLSByZXR1cm4gZW1wdHkgY29uZmlnLlxuICAgICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7IHBhcmFtczoge30gfSB9O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGdsb2JhbENvbmZpZyA9IHJlc3VsdHNbMF07XG4gICAgICAgIGlmICghcmVxLmF1dGguaXNNYXN0ZXIgJiYgZ2xvYmFsQ29uZmlnLm1hc3RlcktleU9ubHkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGZvciAoY29uc3QgcGFyYW0gaW4gZ2xvYmFsQ29uZmlnLnBhcmFtcykge1xuICAgICAgICAgICAgaWYgKGdsb2JhbENvbmZpZy5tYXN0ZXJLZXlPbmx5W3BhcmFtXSkge1xuICAgICAgICAgICAgICBkZWxldGUgZ2xvYmFsQ29uZmlnLnBhcmFtc1twYXJhbV07XG4gICAgICAgICAgICAgIGRlbGV0ZSBnbG9iYWxDb25maWcubWFzdGVyS2V5T25seVtwYXJhbV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICAgIHBhcmFtczogZ2xvYmFsQ29uZmlnLnBhcmFtcyxcbiAgICAgICAgICAgIG1hc3RlcktleU9ubHk6IGdsb2JhbENvbmZpZy5tYXN0ZXJLZXlPbmx5LFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgfVxuXG4gIHVwZGF0ZUdsb2JhbENvbmZpZyhyZXEpIHtcbiAgICBpZiAocmVxLmF1dGguaXNSZWFkT25seSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICBcInJlYWQtb25seSBtYXN0ZXJLZXkgaXNuJ3QgYWxsb3dlZCB0byB1cGRhdGUgdGhlIGNvbmZpZy5cIlxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgcGFyYW1zID0gcmVxLmJvZHkucGFyYW1zO1xuICAgIGNvbnN0IG1hc3RlcktleU9ubHkgPSByZXEuYm9keS5tYXN0ZXJLZXlPbmx5IHx8IHt9O1xuICAgIC8vIFRyYW5zZm9ybSBpbiBkb3Qgbm90YXRpb24gdG8gbWFrZSBzdXJlIGl0IHdvcmtzXG4gICAgY29uc3QgdXBkYXRlID0gT2JqZWN0LmtleXMocGFyYW1zKS5yZWR1Y2UoKGFjYywga2V5KSA9PiB7XG4gICAgICBhY2NbYHBhcmFtcy4ke2tleX1gXSA9IHBhcmFtc1trZXldO1xuICAgICAgYWNjW2BtYXN0ZXJLZXlPbmx5LiR7a2V5fWBdID0gbWFzdGVyS2V5T25seVtrZXldIHx8IGZhbHNlO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSk7XG4gICAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2VcbiAgICAgIC51cGRhdGUoJ19HbG9iYWxDb25maWcnLCB7IG9iamVjdElkOiAnMScgfSwgdXBkYXRlLCB7IHVwc2VydDogdHJ1ZSB9KVxuICAgICAgLnRoZW4oKCkgPT4gKHsgcmVzcG9uc2U6IHsgcmVzdWx0OiB0cnVlIH0gfSkpO1xuICB9XG5cbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9jb25maWcnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0R2xvYmFsQ29uZmlnKHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnUFVUJywgJy9jb25maWcnLCBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMudXBkYXRlR2xvYmFsQ29uZmlnKHJlcSk7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgR2xvYmFsQ29uZmlnUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/GraphQLRouter.js b/lib/Routers/GraphQLRouter.js deleted file mode 100644 index 67a92b3032..0000000000 --- a/lib/Routers/GraphQLRouter.js +++ /dev/null @@ -1,55 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.GraphQLRouter = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const GraphQLConfigPath = '/graphql-config'; - -class GraphQLRouter extends _PromiseRouter.default { - async getGraphQLConfig(req) { - const result = await req.config.parseGraphQLController.getGraphQLConfig(); - return { - response: result - }; - } - - async updateGraphQLConfig(req) { - if (req.auth.isReadOnly) { - throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to update the GraphQL config."); - } - - const data = await req.config.parseGraphQLController.updateGraphQLConfig(req.body.params); - return { - response: data - }; - } - - mountRoutes() { - this.route('GET', GraphQLConfigPath, middleware.promiseEnforceMasterKeyAccess, req => { - return this.getGraphQLConfig(req); - }); - this.route('PUT', GraphQLConfigPath, middleware.promiseEnforceMasterKeyAccess, req => { - return this.updateGraphQLConfig(req); - }); - } - -} - -exports.GraphQLRouter = GraphQLRouter; -var _default = GraphQLRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0dyYXBoUUxSb3V0ZXIuanMiXSwibmFtZXMiOlsiR3JhcGhRTENvbmZpZ1BhdGgiLCJHcmFwaFFMUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsImdldEdyYXBoUUxDb25maWciLCJyZXEiLCJyZXN1bHQiLCJjb25maWciLCJwYXJzZUdyYXBoUUxDb250cm9sbGVyIiwicmVzcG9uc2UiLCJ1cGRhdGVHcmFwaFFMQ29uZmlnIiwiYXV0aCIsImlzUmVhZE9ubHkiLCJQYXJzZSIsIkVycm9yIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsImRhdGEiLCJib2R5IiwicGFyYW1zIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsIm1pZGRsZXdhcmUiLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVBLE1BQU1BLGlCQUFpQixHQUFHLGlCQUExQjs7QUFFTyxNQUFNQyxhQUFOLFNBQTRCQyxzQkFBNUIsQ0FBMEM7QUFDL0MsUUFBTUMsZ0JBQU4sQ0FBdUJDLEdBQXZCLEVBQTRCO0FBQzFCLFVBQU1DLE1BQU0sR0FBRyxNQUFNRCxHQUFHLENBQUNFLE1BQUosQ0FBV0Msc0JBQVgsQ0FBa0NKLGdCQUFsQyxFQUFyQjtBQUNBLFdBQU87QUFDTEssTUFBQUEsUUFBUSxFQUFFSDtBQURMLEtBQVA7QUFHRDs7QUFFRCxRQUFNSSxtQkFBTixDQUEwQkwsR0FBMUIsRUFBK0I7QUFDN0IsUUFBSUEsR0FBRyxDQUFDTSxJQUFKLENBQVNDLFVBQWIsRUFBeUI7QUFDdkIsWUFBTSxJQUFJQyxjQUFNQyxLQUFWLENBQ0pELGNBQU1DLEtBQU4sQ0FBWUMsbUJBRFIsRUFFSixpRUFGSSxDQUFOO0FBSUQ7O0FBQ0QsVUFBTUMsSUFBSSxHQUFHLE1BQU1YLEdBQUcsQ0FBQ0UsTUFBSixDQUFXQyxzQkFBWCxDQUFrQ0UsbUJBQWxDLENBQXNETCxHQUFHLENBQUNZLElBQUosQ0FBU0MsTUFBL0QsQ0FBbkI7QUFDQSxXQUFPO0FBQ0xULE1BQUFBLFFBQVEsRUFBRU87QUFETCxLQUFQO0FBR0Q7O0FBRURHLEVBQUFBLFdBQVcsR0FBRztBQUNaLFNBQUtDLEtBQUwsQ0FBVyxLQUFYLEVBQWtCbkIsaUJBQWxCLEVBQXFDb0IsVUFBVSxDQUFDQyw2QkFBaEQsRUFBK0VqQixHQUFHLElBQUk7QUFDcEYsYUFBTyxLQUFLRCxnQkFBTCxDQUFzQkMsR0FBdEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLZSxLQUFMLENBQVcsS0FBWCxFQUFrQm5CLGlCQUFsQixFQUFxQ29CLFVBQVUsQ0FBQ0MsNkJBQWhELEVBQStFakIsR0FBRyxJQUFJO0FBQ3BGLGFBQU8sS0FBS0ssbUJBQUwsQ0FBeUJMLEdBQXpCLENBQVA7QUFDRCxLQUZEO0FBR0Q7O0FBNUI4Qzs7O2VBK0JsQ0gsYSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0ICogYXMgbWlkZGxld2FyZSBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5cbmNvbnN0IEdyYXBoUUxDb25maWdQYXRoID0gJy9ncmFwaHFsLWNvbmZpZyc7XG5cbmV4cG9ydCBjbGFzcyBHcmFwaFFMUm91dGVyIGV4dGVuZHMgUHJvbWlzZVJvdXRlciB7XG4gIGFzeW5jIGdldEdyYXBoUUxDb25maWcocmVxKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVxLmNvbmZpZy5wYXJzZUdyYXBoUUxDb250cm9sbGVyLmdldEdyYXBoUUxDb25maWcoKTtcbiAgICByZXR1cm4ge1xuICAgICAgcmVzcG9uc2U6IHJlc3VsdCxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgdXBkYXRlR3JhcGhRTENvbmZpZyhyZXEpIHtcbiAgICBpZiAocmVxLmF1dGguaXNSZWFkT25seSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICBcInJlYWQtb25seSBtYXN0ZXJLZXkgaXNuJ3QgYWxsb3dlZCB0byB1cGRhdGUgdGhlIEdyYXBoUUwgY29uZmlnLlwiXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVxLmNvbmZpZy5wYXJzZUdyYXBoUUxDb250cm9sbGVyLnVwZGF0ZUdyYXBoUUxDb25maWcocmVxLmJvZHkucGFyYW1zKTtcbiAgICByZXR1cm4ge1xuICAgICAgcmVzcG9uc2U6IGRhdGEsXG4gICAgfTtcbiAgfVxuXG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ0dFVCcsIEdyYXBoUUxDb25maWdQYXRoLCBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0R3JhcGhRTENvbmZpZyhyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ1BVVCcsIEdyYXBoUUxDb25maWdQYXRoLCBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMudXBkYXRlR3JhcGhRTENvbmZpZyhyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IEdyYXBoUUxSb3V0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/HooksRouter.js b/lib/Routers/HooksRouter.js deleted file mode 100644 index b93d5e0543..0000000000 --- a/lib/Routers/HooksRouter.js +++ /dev/null @@ -1,144 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.HooksRouter = void 0; - -var _node = require("parse/node"); - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class HooksRouter extends _PromiseRouter.default { - createHook(aHook, config) { - return config.hooksController.createHook(aHook).then(hook => ({ - response: hook - })); - } - - updateHook(aHook, config) { - return config.hooksController.updateHook(aHook).then(hook => ({ - response: hook - })); - } - - handlePost(req) { - return this.createHook(req.body, req.config); - } - - handleGetFunctions(req) { - var hooksController = req.config.hooksController; - - if (req.params.functionName) { - return hooksController.getFunction(req.params.functionName).then(foundFunction => { - if (!foundFunction) { - throw new _node.Parse.Error(143, `no function named: ${req.params.functionName} is defined`); - } - - return Promise.resolve({ - response: foundFunction - }); - }); - } - - return hooksController.getFunctions().then(functions => { - return { - response: functions || [] - }; - }, err => { - throw err; - }); - } - - handleGetTriggers(req) { - var hooksController = req.config.hooksController; - - if (req.params.className && req.params.triggerName) { - return hooksController.getTrigger(req.params.className, req.params.triggerName).then(foundTrigger => { - if (!foundTrigger) { - throw new _node.Parse.Error(143, `class ${req.params.className} does not exist`); - } - - return Promise.resolve({ - response: foundTrigger - }); - }); - } - - return hooksController.getTriggers().then(triggers => ({ - response: triggers || [] - })); - } - - handleDelete(req) { - var hooksController = req.config.hooksController; - - if (req.params.functionName) { - return hooksController.deleteFunction(req.params.functionName).then(() => ({ - response: {} - })); - } else if (req.params.className && req.params.triggerName) { - return hooksController.deleteTrigger(req.params.className, req.params.triggerName).then(() => ({ - response: {} - })); - } - - return Promise.resolve({ - response: {} - }); - } - - handleUpdate(req) { - var hook; - - if (req.params.functionName && req.body.url) { - hook = {}; - hook.functionName = req.params.functionName; - hook.url = req.body.url; - } else if (req.params.className && req.params.triggerName && req.body.url) { - hook = {}; - hook.className = req.params.className; - hook.triggerName = req.params.triggerName; - hook.url = req.body.url; - } else { - throw new _node.Parse.Error(143, 'invalid hook declaration'); - } - - return this.updateHook(hook, req.config); - } - - handlePut(req) { - var body = req.body; - - if (body.__op == 'Delete') { - return this.handleDelete(req); - } else { - return this.handleUpdate(req); - } - } - - mountRoutes() { - this.route('GET', '/hooks/functions', middleware.promiseEnforceMasterKeyAccess, this.handleGetFunctions.bind(this)); - this.route('GET', '/hooks/triggers', middleware.promiseEnforceMasterKeyAccess, this.handleGetTriggers.bind(this)); - this.route('GET', '/hooks/functions/:functionName', middleware.promiseEnforceMasterKeyAccess, this.handleGetFunctions.bind(this)); - this.route('GET', '/hooks/triggers/:className/:triggerName', middleware.promiseEnforceMasterKeyAccess, this.handleGetTriggers.bind(this)); - this.route('POST', '/hooks/functions', middleware.promiseEnforceMasterKeyAccess, this.handlePost.bind(this)); - this.route('POST', '/hooks/triggers', middleware.promiseEnforceMasterKeyAccess, this.handlePost.bind(this)); - this.route('PUT', '/hooks/functions/:functionName', middleware.promiseEnforceMasterKeyAccess, this.handlePut.bind(this)); - this.route('PUT', '/hooks/triggers/:className/:triggerName', middleware.promiseEnforceMasterKeyAccess, this.handlePut.bind(this)); - } - -} - -exports.HooksRouter = HooksRouter; -var _default = HooksRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0hvb2tzUm91dGVyLmpzIl0sIm5hbWVzIjpbIkhvb2tzUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsImNyZWF0ZUhvb2siLCJhSG9vayIsImNvbmZpZyIsImhvb2tzQ29udHJvbGxlciIsInRoZW4iLCJob29rIiwicmVzcG9uc2UiLCJ1cGRhdGVIb29rIiwiaGFuZGxlUG9zdCIsInJlcSIsImJvZHkiLCJoYW5kbGVHZXRGdW5jdGlvbnMiLCJwYXJhbXMiLCJmdW5jdGlvbk5hbWUiLCJnZXRGdW5jdGlvbiIsImZvdW5kRnVuY3Rpb24iLCJQYXJzZSIsIkVycm9yIiwiUHJvbWlzZSIsInJlc29sdmUiLCJnZXRGdW5jdGlvbnMiLCJmdW5jdGlvbnMiLCJlcnIiLCJoYW5kbGVHZXRUcmlnZ2VycyIsImNsYXNzTmFtZSIsInRyaWdnZXJOYW1lIiwiZ2V0VHJpZ2dlciIsImZvdW5kVHJpZ2dlciIsImdldFRyaWdnZXJzIiwidHJpZ2dlcnMiLCJoYW5kbGVEZWxldGUiLCJkZWxldGVGdW5jdGlvbiIsImRlbGV0ZVRyaWdnZXIiLCJoYW5kbGVVcGRhdGUiLCJ1cmwiLCJoYW5kbGVQdXQiLCJfX29wIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsIm1pZGRsZXdhcmUiLCJwcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyIsImJpbmQiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFTyxNQUFNQSxXQUFOLFNBQTBCQyxzQkFBMUIsQ0FBd0M7QUFDN0NDLEVBQUFBLFVBQVUsQ0FBQ0MsS0FBRCxFQUFRQyxNQUFSLEVBQWdCO0FBQ3hCLFdBQU9BLE1BQU0sQ0FBQ0MsZUFBUCxDQUF1QkgsVUFBdkIsQ0FBa0NDLEtBQWxDLEVBQXlDRyxJQUF6QyxDQUE4Q0MsSUFBSSxLQUFLO0FBQUVDLE1BQUFBLFFBQVEsRUFBRUQ7QUFBWixLQUFMLENBQWxELENBQVA7QUFDRDs7QUFFREUsRUFBQUEsVUFBVSxDQUFDTixL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QixDQUpGO0FBTUEsU0FBS0gsS0FBTCxDQUNFLE1BREYsRUFFRSxrQkFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUUsS0FBS2hDLFVBQUwsQ0FBZ0JpQyxJQUFoQixDQUFxQixJQUFyQixDQUpGO0FBTUEsU0FBS0gsS0FBTCxDQUNFLE1BREYsRUFFRSxpQkFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUUsS0FBS2hDLFVBQUwsQ0FBZ0JpQyxJQUFoQixDQUFxQixJQUFyQixDQUpGO0FBTUEsU0FBS0gsS0FBTCxDQUNFLEtBREYsRUFFRSxnQ0FGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUUsS0FBS0wsU0FBTCxDQUFlTSxJQUFmLENBQW9CLElBQXBCLENBSkY7QUFNQSxTQUFLSCxLQUFMLENBQ0UsS0FERixFQUVFLHlDQUZGLEVBR0VDLFVBQVUsQ0FBQ0MsNkJBSGIsRUFJRSxLQUFLTCxTQUFMLENBQWVNLElBQWYsQ0FBb0IsSUFBcEIsQ0FKRjtBQU1EOztBQXpJNEM7OztlQTRJaEMzQyxXIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUGFyc2UgfSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0ICogYXMgbWlkZGxld2FyZSBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5cbmV4cG9ydCBjbGFzcyBIb29rc1JvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBjcmVhdGVIb29rKGFIb29rLCBjb25maWcpIHtcbiAgICByZXR1cm4gY29uZmlnLmhvb2tzQ29udHJvbGxlci5jcmVhdGVIb29rKGFIb29rKS50aGVuKGhvb2sgPT4gKHsgcmVzcG9uc2U6IGhvb2sgfSkpO1xuICB9XG5cbiAgdXBkYXRlSG9vayhhSG9vaywgY29uZmlnKSB7XG4gICAgcmV0dXJuIGNvbmZpZy5ob29rc0NvbnRyb2xsZXIudXBkYXRlSG9vayhhSG9vaykudGhlbihob29rID0+ICh7IHJlc3BvbnNlOiBob29rIH0pKTtcbiAgfVxuXG4gIGhhbmRsZVBvc3QocmVxKSB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlSG9vayhyZXEuYm9keSwgcmVxLmNvbmZpZyk7XG4gIH1cblxuICBoYW5kbGVHZXRGdW5jdGlvbnMocmVxKSB7XG4gICAgdmFyIGhvb2tzQ29udHJvbGxlciA9IHJlcS5jb25maWcuaG9va3NDb250cm9sbGVyO1xuICAgIGlmIChyZXEucGFyYW1zLmZ1bmN0aW9uTmFtZSkge1xuICAgICAgcmV0dXJuIGhvb2tzQ29udHJvbGxlci5nZXRGdW5jdGlvbihyZXEucGFyYW1zLmZ1bmN0aW9uTmFtZSkudGhlbihmb3VuZEZ1bmN0aW9uID0+IHtcbiAgICAgICAgaWYgKCFmb3VuZEZ1bmN0aW9uKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDE0MywgYG5vIGZ1bmN0aW9uIG5hbWVkOiAke3JlcS5wYXJhbXMuZnVuY3Rpb25OYW1lfSBpcyBkZWZpbmVkYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHJlc3BvbnNlOiBmb3VuZEZ1bmN0aW9uIH0pO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGhvb2tzQ29udHJvbGxlci5nZXRGdW5jdGlvbnMoKS50aGVuKFxuICAgICAgZnVuY3Rpb25zID0+IHtcbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IGZ1bmN0aW9ucyB8fCBbXSB9O1xuICAgICAgfSxcbiAgICAgIGVyciA9PiB7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgaGFuZGxlR2V0VHJpZ2dlcnMocmVxKSB7XG4gICAgdmFyIGhvb2tzQ29udHJvbGxlciA9IHJlcS5jb25maWcuaG9va3NDb250cm9sbGVyO1xuICAgIGlmIChyZXEucGFyYW1zLmNsYXNzTmFtZSAmJiByZXEucGFyYW1zLnRyaWdnZXJOYW1lKSB7XG4gICAgICByZXR1cm4gaG9va3NDb250cm9sbGVyXG4gICAgICAgIC5nZXRUcmlnZ2VyKHJlcS5wYXJhbXMuY2xhc3NOYW1lLCByZXEucGFyYW1zLnRyaWdnZXJOYW1lKVxuICAgICAgICAudGhlbihmb3VuZFRyaWdnZXIgPT4ge1xuICAgICAgICAgIGlmICghZm91bmRUcmlnZ2VyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTQzLCBgY2xhc3MgJHtyZXEucGFyYW1zLmNsYXNzTmFtZX0gZG9lcyBub3QgZXhpc3RgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHJlc3BvbnNlOiBmb3VuZFRyaWdnZXIgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBob29rc0NvbnRyb2xsZXIuZ2V0VHJpZ2dlcnMoKS50aGVuKHRyaWdnZXJzID0+ICh7IHJlc3BvbnNlOiB0cmlnZ2VycyB8fCBbXSB9KSk7XG4gIH1cblxuICBoYW5kbGVEZWxldGUocmVxKSB7XG4gICAgdmFyIGhvb2tzQ29udHJvbGxlciA9IHJlcS5jb25maWcuaG9va3NDb250cm9sbGVyO1xuICAgIGlmIChyZXEucGFyYW1zLmZ1bmN0aW9uTmFtZSkge1xuICAgICAgcmV0dXJuIGhvb2tzQ29udHJvbGxlci5kZWxldGVGdW5jdGlvbihyZXEucGFyYW1zLmZ1bmN0aW9uTmFtZSkudGhlbigoKSA9PiAoeyByZXNwb25zZToge30gfSkpO1xuICAgIH0gZWxzZSBpZiAocmVxLnBhcmFtcy5jbGFzc05hbWUgJiYgcmVxLnBhcmFtcy50cmlnZ2VyTmFtZSkge1xuICAgICAgcmV0dXJuIGhvb2tzQ29udHJvbGxlclxuICAgICAgICAuZGVsZXRlVHJpZ2dlcihyZXEucGFyYW1zLmNsYXNzTmFtZSwgcmVxLnBhcmFtcy50cmlnZ2VyTmFtZSlcbiAgICAgICAgLnRoZW4oKCkgPT4gKHsgcmVzcG9uc2U6IHt9IH0pKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHJlc3BvbnNlOiB7fSB9KTtcbiAgfVxuXG4gIGhhbmRsZVVwZGF0ZShyZXEpIHtcbiAgICB2YXIgaG9vaztcbiAgICBpZiAocmVxLnBhcmFtcy5mdW5jdGlvbk5hbWUgJiYgcmVxLmJvZHkudXJsKSB7XG4gICAgICBob29rID0ge307XG4gICAgICBob29rLmZ1bmN0aW9uTmFtZSA9IHJlcS5wYXJhbXMuZnVuY3Rpb25OYW1lO1xuICAgICAgaG9vay51cmwgPSByZXEuYm9keS51cmw7XG4gICAgfSBlbHNlIGlmIChyZXEucGFyYW1zLmNsYXNzTmFtZSAmJiByZXEucGFyYW1zLnRyaWdnZXJOYW1lICYmIHJlcS5ib2R5LnVybCkge1xuICAgICAgaG9vayA9IHt9O1xuICAgICAgaG9vay5jbGFzc05hbWUgPSByZXEucGFyYW1zLmNsYXNzTmFtZTtcbiAgICAgIGhvb2sudHJpZ2dlck5hbWUgPSByZXEucGFyYW1zLnRyaWdnZXJOYW1lO1xuICAgICAgaG9vay51cmwgPSByZXEuYm9keS51cmw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigxNDMsICdpbnZhbGlkIGhvb2sgZGVjbGFyYXRpb24nKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudXBkYXRlSG9vayhob29rLCByZXEuY29uZmlnKTtcbiAgfVxuXG4gIGhhbmRsZVB1dChyZXEpIHtcbiAgICB2YXIgYm9keSA9IHJlcS5ib2R5O1xuICAgIGlmIChib2R5Ll9fb3AgPT0gJ0RlbGV0ZScpIHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZURlbGV0ZShyZXEpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVVcGRhdGUocmVxKTtcbiAgICB9XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2hvb2tzL2Z1bmN0aW9ucycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVHZXRGdW5jdGlvbnMuYmluZCh0aGlzKVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdHRVQnLFxuICAgICAgJy9ob29rcy90cmlnZ2VycycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVHZXRUcmlnZ2Vycy5iaW5kKHRoaXMpXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2hvb2tzL2Z1bmN0aW9ucy86ZnVuY3Rpb25OYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICB0aGlzLmhhbmRsZUdldEZ1bmN0aW9ucy5iaW5kKHRoaXMpXG4gICAgKTtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2hvb2tzL3RyaWdnZXJzLzpjbGFzc05hbWUvOnRyaWdnZXJOYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICB0aGlzLmhhbmRsZUdldFRyaWdnZXJzLmJpbmQodGhpcylcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnUE9TVCcsXG4gICAgICAnL2hvb2tzL2Z1bmN0aW9ucycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVQb3N0LmJpbmQodGhpcylcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnUE9TVCcsXG4gICAgICAnL2hvb2tzL3RyaWdnZXJzJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICB0aGlzLmhhbmRsZVBvc3QuYmluZCh0aGlzKVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdQVVQnLFxuICAgICAgJy9ob29rcy9mdW5jdGlvbnMvOmZ1bmN0aW9uTmFtZScsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVQdXQuYmluZCh0aGlzKVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdQVVQnLFxuICAgICAgJy9ob29rcy90cmlnZ2Vycy86Y2xhc3NOYW1lLzp0cmlnZ2VyTmFtZScsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy5oYW5kbGVQdXQuYmluZCh0aGlzKVxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSG9va3NSb3V0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/IAPValidationRouter.js b/lib/Routers/IAPValidationRouter.js deleted file mode 100644 index f0ba814941..0000000000 --- a/lib/Routers/IAPValidationRouter.js +++ /dev/null @@ -1,136 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.IAPValidationRouter = void 0; - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var _node = _interopRequireDefault(require("parse/node")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const request = require('../request'); - -const rest = require('../rest'); - -// TODO move validation logic in IAPValidationController -const IAP_SANDBOX_URL = 'https://sandbox.itunes.apple.com/verifyReceipt'; -const IAP_PRODUCTION_URL = 'https://buy.itunes.apple.com/verifyReceipt'; -const APP_STORE_ERRORS = { - 21000: 'The App Store could not read the JSON object you provided.', - 21002: 'The data in the receipt-data property was malformed or missing.', - 21003: 'The receipt could not be authenticated.', - 21004: 'The shared secret you provided does not match the shared secret on file for your account.', - 21005: 'The receipt server is not currently available.', - 21006: 'This receipt is valid but the subscription has expired.', - 21007: 'This receipt is from the test environment, but it was sent to the production environment for verification. Send it to the test environment instead.', - 21008: 'This receipt is from the production environment, but it was sent to the test environment for verification. Send it to the production environment instead.' -}; - -function appStoreError(status) { - status = parseInt(status); - var errorString = APP_STORE_ERRORS[status] || 'unknown error.'; - return { - status: status, - error: errorString - }; -} - -function validateWithAppStore(url, receipt) { - return request({ - url: url, - method: 'POST', - body: { - 'receipt-data': receipt - }, - headers: { - 'Content-Type': 'application/json' - } - }).then(httpResponse => { - const body = httpResponse.data; - - if (body && body.status === 0) { - // No need to pass anything, status is OK - return; - } // receipt is from test and should go to test - - - throw body; - }); -} - -function getFileForProductIdentifier(productIdentifier, req) { - return rest.find(req.config, req.auth, '_Product', { - productIdentifier: productIdentifier - }, undefined, req.info.clientSDK, req.info.context).then(function (result) { - const products = result.results; - - if (!products || products.length != 1) { - // Error not found or too many - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.'); - } - - var download = products[0].download; - return Promise.resolve({ - response: download - }); - }); -} - -class IAPValidationRouter extends _PromiseRouter.default { - handleRequest(req) { - let receipt = req.body.receipt; - const productIdentifier = req.body.productIdentifier; - - if (!receipt || !productIdentifier) { - // TODO: Error, malformed request - throw new _node.default.Error(_node.default.Error.INVALID_JSON, 'missing receipt or productIdentifier'); - } // Transform the object if there - // otherwise assume it's in Base64 already - - - if (typeof receipt == 'object') { - if (receipt['__type'] == 'Bytes') { - receipt = receipt.base64; - } - } - - if (process.env.TESTING == '1' && req.body.bypassAppStoreValidation) { - return getFileForProductIdentifier(productIdentifier, req); - } - - function successCallback() { - return getFileForProductIdentifier(productIdentifier, req); - } - - function errorCallback(error) { - return Promise.resolve({ - response: appStoreError(error.status) - }); - } - - return validateWithAppStore(IAP_PRODUCTION_URL, receipt).then(() => { - return successCallback(); - }, error => { - if (error.status == 21007) { - return validateWithAppStore(IAP_SANDBOX_URL, receipt).then(() => { - return successCallback(); - }, error => { - return errorCallback(error); - }); - } - - return errorCallback(error); - }); - } - - mountRoutes() { - this.route('POST', '/validate_purchase', this.handleRequest); - } - -} - -exports.IAPValidationRouter = IAPValidationRouter; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0lBUFZhbGlkYXRpb25Sb3V0ZXIuanMiXSwibmFtZXMiOlsicmVxdWVzdCIsInJlcXVpcmUiLCJyZXN0IiwiSUFQX1NBTkRCT1hfVVJMIiwiSUFQX1BST0RVQ1RJT05fVVJMIiwiQVBQX1NUT1JFX0VSUk9SUyIsImFwcFN0b3JlRXJyb3IiLCJzdGF0dXMiLCJwYXJzZUludCIsImVycm9yU3RyaW5nIiwiZXJyb3IiLCJ2YWxpZGF0ZVdpdGhBcHBTdG9yZSIsInVybCIsInJlY2VpcHQiLCJtZXRob2QiLCJib2R5IiwiaGVhZGVycyIsInRoZW4iLCJodHRwUmVzcG9uc2UiLCJkYXRhIiwiZ2V0RmlsZUZvclByb2R1Y3RJZGVudGlmaWVyIiwicHJvZHVjdElkZW50aWZpZXIiLCJyZXEiLCJmaW5kIiwiY29uZmlnIiwiYXV0aCIsInVuZGVmaW5lZCIsImluZm8iLCJjbGllbnRTREsiLCJjb250ZXh0IiwicmVzdWx0IiwicHJvZHVjdHMiLCJyZXN1bHRzIiwibGVuZ3RoIiwiUGFyc2UiLCJFcnJvciIsIk9CSkVDVF9OT1RfRk9VTkQiLCJkb3dubG9hZCIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVzcG9uc2UiLCJJQVBWYWxpZGF0aW9uUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsImhhbmRsZVJlcXVlc3QiLCJJTlZBTElEX0pTT04iLCJiYXNlNjQiLCJwcm9jZXNzIiwiZW52IiwiVEVTVElORyIsImJ5cGFzc0FwcFN0b3JlVmFsaWRhdGlvbiIsInN1Y2Nlc3NDYWxsYmFjayIsImVycm9yQ2FsbGJhY2siLCJtb3VudFJvdXRlcyIsInJvdXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBR0E7Ozs7QUFGQSxNQUFNQSxPQUFPLEdBQUdDLE9BQU8sQ0FBQyxZQUFELENBQXZCOztBQUNBLE1BQU1DLElBQUksR0FBR0QsT0FBTyxDQUFDLFNBQUQsQ0FBcEI7O0FBR0E7QUFDQSxNQUFNRSxlQUFlLEdBQUcsZ0RBQXhCO0FBQ0EsTUFB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O0FBbUJEOztBQUVEMEMsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxDQUFXLE1BQVgsRUFBbUIsb0JBQW5CLEVBQXlDLEtBQUtWLGFBQTlDO0FBQ0Q7O0FBckRvRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuY29uc3QgcmVxdWVzdCA9IHJlcXVpcmUoJy4uL3JlcXVlc3QnKTtcbmNvbnN0IHJlc3QgPSByZXF1aXJlKCcuLi9yZXN0Jyk7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5cbi8vIFRPRE8gbW92ZSB2YWxpZGF0aW9uIGxvZ2ljIGluIElBUFZhbGlkYXRpb25Db250cm9sbGVyXG5jb25zdCBJQVBfU0FOREJPWF9VUkwgPSAnaHR0cHM6Ly9zYW5kYm94Lml0dW5lcy5hcHBsZS5jb20vdmVyaWZ5UmVjZWlwdCc7XG5jb25zdCBJQVBfUFJPRFVDVElPTl9VUkwgPSAnaHR0cHM6Ly9idXkuaXR1bmVzLmFwcGxlLmNvbS92ZXJpZnlSZWNlaXB0JztcblxuY29uc3QgQVBQX1NUT1JFX0VSUk9SUyA9IHtcbiAgMjEwMDA6ICdUaGUgQXBwIFN0b3JlIGNvdWxkIG5vdCByZWFkIHRoZSBKU09OIG9iamVjdCB5b3UgcHJvdmlkZWQuJyxcbiAgMjEwMDI6ICdUaGUgZGF0YSBpbiB0aGUgcmVjZWlwdC1kYXRhIHByb3BlcnR5IHdhcyBtYWxmb3JtZWQgb3IgbWlzc2luZy4nLFxuICAyMTAwMzogJ1RoZSByZWNlaXB0IGNvdWxkIG5vdCBiZSBhdXRoZW50aWNhdGVkLicsXG4gIDIxMDA0OiAnVGhlIHNoYXJlZCBzZWNyZXQgeW91IHByb3ZpZGVkIGRvZXMgbm90IG1hdGNoIHRoZSBzaGFyZWQgc2VjcmV0IG9uIGZpbGUgZm9yIHlvdXIgYWNjb3VudC4nLFxuICAyMTAwNTogJ1RoZSByZWNlaXB0IHNlcnZlciBpcyBub3QgY3VycmVudGx5IGF2YWlsYWJsZS4nLFxuICAyMTAwNjogJ1RoaXMgcmVjZWlwdCBpcyB2YWxpZCBidXQgdGhlIHN1YnNjcmlwdGlvbiBoYXMgZXhwaXJlZC4nLFxuICAyMTAwNzogJ1RoaXMgcmVjZWlwdCBpcyBmcm9tIHRoZSB0ZXN0IGVudmlyb25tZW50LCBidXQgaXQgd2FzIHNlbnQgdG8gdGhlIHByb2R1Y3Rpb24gZW52aXJvbm1lbnQgZm9yIHZlcmlmaWNhdGlvbi4gU2VuZCBpdCB0byB0aGUgdGVzdCBlbnZpcm9ubWVudCBpbnN0ZWFkLicsXG4gIDIxMDA4OiAnVGhpcyByZWNlaXB0IGlzIGZyb20gdGhlIHByb2R1Y3Rpb24gZW52aXJvbm1lbnQsIGJ1dCBpdCB3YXMgc2VudCB0byB0aGUgdGVzdCBlbnZpcm9ubWVudCBmb3IgdmVyaWZpY2F0aW9uLiBTZW5kIGl0IHRvIHRoZSBwcm9kdWN0aW9uIGVudmlyb25tZW50IGluc3RlYWQuJyxcbn07XG5cbmZ1bmN0aW9uIGFwcFN0b3JlRXJyb3Ioc3RhdHVzKSB7XG4gIHN0YXR1cyA9IHBhcnNlSW50KHN0YXR1cyk7XG4gIHZhciBlcnJvclN0cmluZyA9IEFQUF9TVE9SRV9FUlJPUlNbc3RhdHVzXSB8fCAndW5rbm93biBlcnJvci4nO1xuICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cywgZXJyb3I6IGVycm9yU3RyaW5nIH07XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlV2l0aEFwcFN0b3JlKHVybCwgcmVjZWlwdCkge1xuICByZXR1cm4gcmVxdWVzdCh7XG4gICAgdXJsOiB1cmwsXG4gICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgYm9keTogeyAncmVjZWlwdC1kYXRhJzogcmVjZWlwdCB9LFxuICAgIGhlYWRlcnM6IHtcbiAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgfSxcbiAgfSkudGhlbihodHRwUmVzcG9uc2UgPT4ge1xuICAgIGNvbnN0IGJvZHkgPSBodHRwUmVzcG9uc2UuZGF0YTtcbiAgICBpZiAoYm9keSAmJiBib2R5LnN0YXR1cyA9PT0gMCkge1xuICAgICAgLy8gTm8gbmVlZCB0byBwYXNzIGFueXRoaW5nLCBzdGF0dXMgaXMgT0tcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gcmVjZWlwdCBpcyBmcm9tIHRlc3QgYW5kIHNob3VsZCBnbyB0byB0ZXN0XG4gICAgdGhyb3cgYm9keTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldEZpbGVGb3JQcm9kdWN0SWRlbnRpZmllcihwcm9kdWN0SWRlbnRpZmllciwgcmVxKSB7XG4gIHJldHVybiByZXN0XG4gICAgLmZpbmQoXG4gICAgICByZXEuY29uZmlnLFxuICAgICAgcmVxLmF1dGgsXG4gICAgICAnX1Byb2R1Y3QnLFxuICAgICAgeyBwcm9kdWN0SWRlbnRpZmllcjogcHJvZHVjdElkZW50aWZpZXIgfSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIHJlcS5pbmZvLmNsaWVudFNESyxcbiAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICApXG4gICAgLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgY29uc3QgcHJvZHVjdHMgPSByZXN1bHQucmVzdWx0cztcbiAgICAgIGlmICghcHJvZHVjdHMgfHwgcHJvZHVjdHMubGVuZ3RoICE9IDEpIHtcbiAgICAgICAgLy8gRXJyb3Igbm90IGZvdW5kIG9yIHRvbyBtYW55XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnT2JqZWN0IG5vdCBmb3VuZC4nKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGRvd25sb2FkID0gcHJvZHVjdHNbMF0uZG93bmxvYWQ7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHsgcmVzcG9uc2U6IGRvd25sb2FkIH0pO1xuICAgIH0pO1xufVxuXG5leHBvcnQgY2xhc3MgSUFQVmFsaWRhdGlvblJvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBoYW5kbGVSZXF1ZXN0KHJlcSkge1xuICAgIGxldCByZWNlaXB0ID0gcmVxLmJvZHkucmVjZWlwdDtcbiAgICBjb25zdCBwcm9kdWN0SWRlbnRpZmllciA9IHJlcS5ib2R5LnByb2R1Y3RJZGVudGlmaWVyO1xuXG4gICAgaWYgKCFyZWNlaXB0IHx8ICFwcm9kdWN0SWRlbnRpZmllcikge1xuICAgICAgLy8gVE9ETzogRXJyb3IsIG1hbGZvcm1lZCByZXF1ZXN0XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnbWlzc2luZyByZWNlaXB0IG9yIHByb2R1Y3RJZGVudGlmaWVyJyk7XG4gICAgfVxuXG4gICAgLy8gVHJhbnNmb3JtIHRoZSBvYmplY3QgaWYgdGhlcmVcbiAgICAvLyBvdGhlcndpc2UgYXNzdW1lIGl0J3MgaW4gQmFzZTY0IGFscmVhZHlcbiAgICBpZiAodHlwZW9mIHJlY2VpcHQgPT0gJ29iamVjdCcpIHtcbiAgICAgIGlmIChyZWNlaXB0WydfX3R5cGUnXSA9PSAnQnl0ZXMnKSB7XG4gICAgICAgIHJlY2VpcHQgPSByZWNlaXB0LmJhc2U2NDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAocHJvY2Vzcy5lbnYuVEVTVElORyA9PSAnMScgJiYgcmVxLmJvZHkuYnlwYXNzQXBwU3RvcmVWYWxpZGF0aW9uKSB7XG4gICAgICByZXR1cm4gZ2V0RmlsZUZvclByb2R1Y3RJZGVudGlmaWVyKHByb2R1Y3RJZGVudGlmaWVyLCByZXEpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN1Y2Nlc3NDYWxsYmFjaygpIHtcbiAgICAgIHJldHVybiBnZXRGaWxlRm9yUHJvZHVjdElkZW50aWZpZXIocHJvZHVjdElkZW50aWZpZXIsIHJlcSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXJyb3JDYWxsYmFjayhlcnJvcikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHJlc3BvbnNlOiBhcHBTdG9yZUVycm9yKGVycm9yLnN0YXR1cykgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbGlkYXRlV2l0aEFwcFN0b3JlKElBUF9QUk9EVUNUSU9OX1VSTCwgcmVjZWlwdCkudGhlbihcbiAgICAgICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHN1Y2Nlc3NDYWxsYmFjaygpO1xuICAgICAgfSxcbiAgICAgIGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLnN0YXR1cyA9PSAyMTAwNykge1xuICAgICAgICAgIHJldHVybiB2YWxpZGF0ZVdpdGhBcHBTdG9yZShJQVBfU0FOREJPWF9VUkwsIHJlY2VpcHQpLnRoZW4oXG4gICAgICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBzdWNjZXNzQ2FsbGJhY2soKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvciA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBlcnJvckNhbGxiYWNrKGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy92YWxpZGF0ZV9wdXJjaGFzZScsIHRoaXMuaGFuZGxlUmVxdWVzdCk7XG4gIH1cbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/InstallationsRouter.js b/lib/Routers/InstallationsRouter.js deleted file mode 100644 index 62b677126a..0000000000 --- a/lib/Routers/InstallationsRouter.js +++ /dev/null @@ -1,57 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.InstallationsRouter = void 0; - -var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); - -var _rest = _interopRequireDefault(require("../rest")); - -var _middlewares = require("../middlewares"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// InstallationsRouter.js -class InstallationsRouter extends _ClassesRouter.default { - className() { - return '_Installation'; - } - - handleFind(req) { - const body = Object.assign(req.body, _ClassesRouter.default.JSONFromQuery(req.query)); - - const options = _ClassesRouter.default.optionsFromBody(body); - - return _rest.default.find(req.config, req.auth, '_Installation', body.where, options, req.info.clientSDK, req.info.context).then(response => { - return { - response: response - }; - }); - } - - mountRoutes() { - this.route('GET', '/installations', req => { - return this.handleFind(req); - }); - this.route('GET', '/installations/:objectId', req => { - return this.handleGet(req); - }); - this.route('POST', '/installations', _middlewares.promiseEnsureIdempotency, req => { - return this.handleCreate(req); - }); - this.route('PUT', '/installations/:objectId', _middlewares.promiseEnsureIdempotency, req => { - return this.handleUpdate(req); - }); - this.route('DELETE', '/installations/:objectId', req => { - return this.handleDelete(req); - }); - } - -} - -exports.InstallationsRouter = InstallationsRouter; -var _default = InstallationsRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0luc3RhbGxhdGlvbnNSb3V0ZXIuanMiXSwibmFtZXMiOlsiSW5zdGFsbGF0aW9uc1JvdXRlciIsIkNsYXNzZXNSb3V0ZXIiLCJjbGFzc05hbWUiLCJoYW5kbGVGaW5kIiwicmVxIiwiYm9keSIsIk9iamVjdCIsImFzc2lnbiIsIkpTT05Gcm9tUXVlcnkiLCJxdWVyeSIsIm9wdGlvbnMiLCJvcHRpb25zRnJvbUJvZHkiLCJyZXN0IiwiZmluZCIsImNvbmZpZyIsImF1dGgiLCJ3aGVyZSIsImluZm8iLCJjbGllbnRTREsiLCJjb250ZXh0IiwidGhlbiIsInJlc3BvbnNlIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsImhhbmRsZUdldCIsInByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSIsImhhbmRsZUNyZWF0ZSIsImhhbmRsZVVwZGF0ZSIsImhhbmRsZURlbGV0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUVBOztBQUNBOztBQUNBOzs7O0FBSkE7QUFNTyxNQUFNQSxtQkFBTixTQUFrQ0Msc0JBQWxDLENBQWdEO0FBQ3JEQyxFQUFBQSxTQUFTLEdBQUc7QUFDVixXQUFPLGVBQVA7QUFDRDs7QUFFREMsRUFBQUEsVUFBVSxDQUFDQyxHQUFELEVBQU07QUFDZCxVQUFNQyxJQUFJLEdBQUdDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjSCxHQUFHLENBQUNDLElBQWxCLEVBQXdCSix1QkFBY08sYUFBZCxDQUE0QkosR0FBRyxDQUFDSyxLQUFoQyxDQUF4QixDQUFiOztBQUNBLFVBQU1DLE9BQU8sR0FBR1QsdUJBQWNVLGVBQWQsQ0FBOEJOLElBQTlCLENBQWhCOztBQUNBLFdBQU9PLGNBQ0pDLElBREksQ0FFSFQsR0FBRyxDQUFDVSxNQUZELEVBR0hWLEdBQUcsQ0FBQ1csSUFIRCxFQUlILGVBSkcsRUFLSFYsSUFBSSxDQUFDVyxLQUxGLEVBTUhOLE9BTkcsRUFPSE4sR0FBRyxDQUFDYSxJQUFKLENBQVNDLFNBUE4sRUFRSGQsR0FBRyxDQUFDYSxJQUFKLENBQVNFLE9BUk4sRUFVSkMsSUFWSSxDQVVDQyxRQUFRLElBQUk7QUFDaEIsYUFBTztBQUFFQSxRQUFBQSxRQUFRLEVBQUVBO0FBQVosT0FBUDtBQUNELEtBWkksQ0FBUDtBQWFEOztBQUVEQyxFQUFBQSxXQUFXLEdBQUc7QUFDWixTQUFLQyxLQUFMLENBQVcsS0FBWCxFQUFrQixnQkFBbEIsRUFBb0NuQixHQUFHLElBQUk7QUFDekMsYUFBTyxLQUFLRCxVQUFMLENBQWdCQyxHQUFoQixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUttQixLQUFMLENBQVcsS0FBWCxFQUFrQiwwQkFBbEIsRUFBOENuQixHQUFHLElBQUk7QUFDbkQsYUFBTyxLQUFLb0IsU0FBTCxDQUFlcEIsR0FBZixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUttQixLQUFMLENBQVcsTUFBWCxFQUFtQixnQkFBbkIsRUFBcUNFLHFDQUFyQyxFQUErRHJCLEdBQUcsSUFBSTtBQUNwRSxhQUFPLEtBQUtzQixZQUFMLENBQWtCdEIsR0FBbEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLbUIsS0FBTCxDQUFXLEtBQVgsRUFBa0IsMEJBQWxCLEVBQThDRSxxQ0FBOUMsRUFBd0VyQixHQUFHLElBQUk7QUFDN0UsYUFBTyxLQUFLdUIsWUFBTCxDQUFrQnZCLEdBQWxCLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBS21CLEtBQUwsQ0FBVyxRQUFYLEVBQXFCLDBCQUFyQixFQUFpRG5CLEdBQUcsSUFBSTtBQUN0RCxhQUFPLEtBQUt3QixZQUFMLENBQWtCeEIsR0FBbEIsQ0FBUDtBQUNELEtBRkQ7QUFHRDs7QUF2Q29EOzs7ZUEwQ3hDSixtQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEluc3RhbGxhdGlvbnNSb3V0ZXIuanNcblxuaW1wb3J0IENsYXNzZXNSb3V0ZXIgZnJvbSAnLi9DbGFzc2VzUm91dGVyJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IHsgcHJvbWlzZUVuc3VyZUlkZW1wb3RlbmN5IH0gZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5leHBvcnQgY2xhc3MgSW5zdGFsbGF0aW9uc1JvdXRlciBleHRlbmRzIENsYXNzZXNSb3V0ZXIge1xuICBjbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICdfSW5zdGFsbGF0aW9uJztcbiAgfVxuXG4gIGhhbmRsZUZpbmQocmVxKSB7XG4gICAgY29uc3QgYm9keSA9IE9iamVjdC5hc3NpZ24ocmVxLmJvZHksIENsYXNzZXNSb3V0ZXIuSlNPTkZyb21RdWVyeShyZXEucXVlcnkpKTtcbiAgICBjb25zdCBvcHRpb25zID0gQ2xhc3Nlc1JvdXRlci5vcHRpb25zRnJvbUJvZHkoYm9keSk7XG4gICAgcmV0dXJuIHJlc3RcbiAgICAgIC5maW5kKFxuICAgICAgICByZXEuY29uZmlnLFxuICAgICAgICByZXEuYXV0aCxcbiAgICAgICAgJ19JbnN0YWxsYXRpb24nLFxuICAgICAgICBib2R5LndoZXJlLFxuICAgICAgICBvcHRpb25zLFxuICAgICAgICByZXEuaW5mby5jbGllbnRTREssXG4gICAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHJlc3BvbnNlIH07XG4gICAgICB9KTtcbiAgfVxuXG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvaW5zdGFsbGF0aW9ucycsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVGaW5kKHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9pbnN0YWxsYXRpb25zLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9pbnN0YWxsYXRpb25zJywgcHJvbWlzZUVuc3VyZUlkZW1wb3RlbmN5LCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlQ3JlYXRlKHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnUFVUJywgJy9pbnN0YWxsYXRpb25zLzpvYmplY3RJZCcsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSwgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZVVwZGF0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0RFTEVURScsICcvaW5zdGFsbGF0aW9ucy86b2JqZWN0SWQnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlRGVsZXRlKHJlcSk7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgSW5zdGFsbGF0aW9uc1JvdXRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/LogsRouter.js b/lib/Routers/LogsRouter.js deleted file mode 100644 index 4399b717f5..0000000000 --- a/lib/Routers/LogsRouter.js +++ /dev/null @@ -1,71 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.LogsRouter = void 0; - -var _node = require("parse/node"); - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class LogsRouter extends _PromiseRouter.default { - mountRoutes() { - this.route('GET', '/scriptlog', middleware.promiseEnforceMasterKeyAccess, this.validateRequest, req => { - return this.handleGET(req); - }); - } - - validateRequest(req) { - if (!req.config || !req.config.loggerController) { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Logger adapter is not available'); - } - } // Returns a promise for a {response} object. - // query params: - // level (optional) Level of logging you want to query for (info || error) - // from (optional) Start time for the search. Defaults to 1 week ago. - // until (optional) End time for the search. Defaults to current time. - // order (optional) Direction of results returned, either “asc” or “desc”. Defaults to “desc”. - // size (optional) Number of rows returned by search. Defaults to 10 - // n same as size, overrides size if set - - - handleGET(req) { - const from = req.query.from; - const until = req.query.until; - let size = req.query.size; - - if (req.query.n) { - size = req.query.n; - } - - const order = req.query.order; - const level = req.query.level; - const options = { - from, - until, - size, - order, - level - }; - return req.config.loggerController.getLogs(options).then(result => { - return Promise.resolve({ - response: result - }); - }); - } - -} - -exports.LogsRouter = LogsRouter; -var _default = LogsRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL0xvZ3NSb3V0ZXIuanMiXSwibmFtZXMiOlsiTG9nc1JvdXRlciIsIlByb21pc2VSb3V0ZXIiLCJtb3VudFJvdXRlcyIsInJvdXRlIiwibWlkZGxld2FyZSIsInByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzIiwidmFsaWRhdGVSZXF1ZXN0IiwicmVxIiwiaGFuZGxlR0VUIiwiY29uZmlnIiwibG9nZ2VyQ29udHJvbGxlciIsIlBhcnNlIiwiRXJyb3IiLCJQVVNIX01JU0NPTkZJR1VSRUQiLCJmcm9tIiwicXVlcnkiLCJ1bnRpbCIsInNpemUiLCJuIiwib3JkZXIiLCJsZXZlbCIsIm9wdGlvbnMiLCJnZXRMb2dzIiwidGhlbiIsInJlc3VsdCIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVzcG9uc2UiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFTyxNQUFNQSxVQUFOLFNBQXlCQyxzQkFBekIsQ0FBdUM7QUFDNUNDLEVBQUFBLFdBQVcsR0FBRztBQUNaLFNBQUtDLEtBQUwsQ0FDRSxLQURGLEVBRUUsWUFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUUsS0FBS0MsZUFKUCxFQUtFQyxHQUFHLElBQUk7QUFDTCxhQUFPLEtBQUtDLFNBQUwsQ0FBZUQsR0FBZixDQUFQO0FBQ0QsS0FQSDtBQVNEOztBQUVERCxFQUFBQSxlQUFlLENBQUNDLEdBQUQsRUFBTTtBQUNuQixRQUFJLENBQUNBLEdBQUcsQ0FBQ0UsTUFBTCxJQUFlLENBQUNGLEdBQUcsQ0FBQ0UsTUFBSixDQUFXQyxnQkFBL0IsRUFBaUQ7QUFDL0MsWUFBTSxJQUFJQyxZQUFNQyxLQUFWLENBQWdCRCxZQUFNQyxLQUFOLENBQVlDLGtCQUE1QixFQUFnRCxpQ0FBaEQsQ0FBTjtBQUNEO0FBQ0YsR0FqQjJDLENBbUI1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDQUwsRUFBQUEsU0FBUyxDQUFDRCxHQUFELEVBQU07QUFDYixVQUFNTyxJQUFJLEdBQUdQLEdBQUcsQ0FBQ1EsS0FBSixDQUFVRCxJQUF2QjtBQUNBLFVBQU1FLEtBQUssR0FBR1QsR0FBRyxDQUFDUSxLQUFKLENBQVVDLEtBQXhCO0FBQ0EsUUFBSUMsSUFBSSxHQUFHVixHQUFHLENBQUNRLEtBQUosQ0FBVUUsSUFBckI7O0FBQ0EsUUFBSVYsR0FBRyxDQUFDUSxLQUFKLENBQVVHLENBQWQsRUFBaUI7QUFDZkQsTUFBQUEsSUFBSSxHQUFHVixHQUFHLENBQUNRLEtBQUosQ0FBVUcsQ0FBakI7QUFDRDs7QUFFRCxVQUFNQyxLQUFLLEdBQUdaLEdBQUcsQ0FBQ1EsS0FBSixDQUFVSSxLQUF4QjtBQUNBLFVBQU1DLEtBQUssR0FBR2IsR0FBRyxDQUFDUSxLQUFKLENBQVVLLEtBQXhCO0FBQ0EsVUFBTUMsT0FBTyxHQUFHO0FBQ2RQLE1BQUFBLElBRGM7QUFFZEUsTUFBQUEsS0FGYztBQUdkQyxNQUFBQSxJQUhjO0FBSWRFLE1BQUFBLEtBSmM7QUFLZEMsTUFBQUE7QUFMYyxLQUFoQjtBQVFBLFdBQU9iLEdBQUcsQ0FBQ0UsTUFBSixDQUFXQyxnQkFBWCxDQUE0QlksT0FBNUIsQ0FBb0NELE9BQXBDLEVBQTZDRSxJQUE3QyxDQUFrREMsTUFBTSxJQUFJO0FBQ2pFLGFBQU9DLE9BQU8sQ0FBQ0MsT0FBUixDQUFnQjtBQUNyQkMsUUFBQUEsUUFBUSxFQUFFSDtBQURXLE9BQWhCLENBQVA7QUFHRCxLQUpNLENBQVA7QUFLRDs7QUFsRDJDOzs7ZUFxRC9CeEIsVSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBhcnNlIH0gZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuLi9Qcm9taXNlUm91dGVyJztcbmltcG9ydCAqIGFzIG1pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5leHBvcnQgY2xhc3MgTG9nc1JvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL3NjcmlwdGxvZycsXG4gICAgICBtaWRkbGV3YXJlLnByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzLFxuICAgICAgdGhpcy52YWxpZGF0ZVJlcXVlc3QsXG4gICAgICByZXEgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVHRVQocmVxKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgdmFsaWRhdGVSZXF1ZXN0KHJlcSkge1xuICAgIGlmICghcmVxLmNvbmZpZyB8fCAhcmVxLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELCAnTG9nZ2VyIGFkYXB0ZXIgaXMgbm90IGF2YWlsYWJsZScpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIGZvciBhIHtyZXNwb25zZX0gb2JqZWN0LlxuICAvLyBxdWVyeSBwYXJhbXM6XG4gIC8vIGxldmVsIChvcHRpb25hbCkgTGV2ZWwgb2YgbG9nZ2luZyB5b3Ugd2FudCB0byBxdWVyeSBmb3IgKGluZm8gfHwgZXJyb3IpXG4gIC8vIGZyb20gKG9wdGlvbmFsKSBTdGFydCB0aW1lIGZvciB0aGUgc2VhcmNoLiBEZWZhdWx0cyB0byAxIHdlZWsgYWdvLlxuICAvLyB1bnRpbCAob3B0aW9uYWwpIEVuZCB0aW1lIGZvciB0aGUgc2VhcmNoLiBEZWZhdWx0cyB0byBjdXJyZW50IHRpbWUuXG4gIC8vIG9yZGVyIChvcHRpb25hbCkgRGlyZWN0aW9uIG9mIHJlc3VsdHMgcmV0dXJuZWQsIGVpdGhlciDigJxhc2PigJ0gb3Ig4oCcZGVzY+KAnS4gRGVmYXVsdHMgdG8g4oCcZGVzY+KAnS5cbiAgLy8gc2l6ZSAob3B0aW9uYWwpIE51bWJlciBvZiByb3dzIHJldHVybmVkIGJ5IHNlYXJjaC4gRGVmYXVsdHMgdG8gMTBcbiAgLy8gbiBzYW1lIGFzIHNpemUsIG92ZXJyaWRlcyBzaXplIGlmIHNldFxuICBoYW5kbGVHRVQocmVxKSB7XG4gICAgY29uc3QgZnJvbSA9IHJlcS5xdWVyeS5mcm9tO1xuICAgIGNvbnN0IHVudGlsID0gcmVxLnF1ZXJ5LnVudGlsO1xuICAgIGxldCBzaXplID0gcmVxLnF1ZXJ5LnNpemU7XG4gICAgaWYgKHJlcS5xdWVyeS5uKSB7XG4gICAgICBzaXplID0gcmVxLnF1ZXJ5Lm47XG4gICAgfVxuXG4gICAgY29uc3Qgb3JkZXIgPSByZXEucXVlcnkub3JkZXI7XG4gICAgY29uc3QgbGV2ZWwgPSByZXEucXVlcnkubGV2ZWw7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgIGZyb20sXG4gICAgICB1bnRpbCxcbiAgICAgIHNpemUsXG4gICAgICBvcmRlcixcbiAgICAgIGxldmVsLFxuICAgIH07XG5cbiAgICByZXR1cm4gcmVxLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyLmdldExvZ3Mob3B0aW9ucykudGhlbihyZXN1bHQgPT4ge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgIHJlc3BvbnNlOiByZXN1bHQsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBMb2dzUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/PagesRouter.js b/lib/Routers/PagesRouter.js deleted file mode 100644 index 815a3566b1..0000000000 --- a/lib/Routers/PagesRouter.js +++ /dev/null @@ -1,693 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.PagesRouter = void 0; - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var _Config = _interopRequireDefault(require("../Config")); - -var _express = _interopRequireDefault(require("express")); - -var _path = _interopRequireDefault(require("path")); - -var _fs = require("fs"); - -var _node = require("parse/node"); - -var _Utils = _interopRequireDefault(require("../Utils")); - -var _mustache = _interopRequireDefault(require("mustache")); - -var _Page = _interopRequireDefault(require("../Page")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// All pages with custom page key for reference and file name -const pages = Object.freeze({ - passwordReset: new _Page.default({ - id: 'passwordReset', - defaultFile: 'password_reset.html' - }), - passwordResetSuccess: new _Page.default({ - id: 'passwordResetSuccess', - defaultFile: 'password_reset_success.html' - }), - passwordResetLinkInvalid: new _Page.default({ - id: 'passwordResetLinkInvalid', - defaultFile: 'password_reset_link_invalid.html' - }), - emailVerificationSuccess: new _Page.default({ - id: 'emailVerificationSuccess', - defaultFile: 'email_verification_success.html' - }), - emailVerificationSendFail: new _Page.default({ - id: 'emailVerificationSendFail', - defaultFile: 'email_verification_send_fail.html' - }), - emailVerificationSendSuccess: new _Page.default({ - id: 'emailVerificationSendSuccess', - defaultFile: 'email_verification_send_success.html' - }), - emailVerificationLinkInvalid: new _Page.default({ - id: 'emailVerificationLinkInvalid', - defaultFile: 'email_verification_link_invalid.html' - }), - emailVerificationLinkExpired: new _Page.default({ - id: 'emailVerificationLinkExpired', - defaultFile: 'email_verification_link_expired.html' - }) -}); // All page parameters for reference to be used as template placeholders or query params - -const pageParams = Object.freeze({ - appName: 'appName', - appId: 'appId', - token: 'token', - username: 'username', - error: 'error', - locale: 'locale', - publicServerUrl: 'publicServerUrl' -}); // The header prefix to add page params as response headers - -const pageParamHeaderPrefix = 'x-parse-page-param-'; // The errors being thrown - -const errors = Object.freeze({ - jsonFailedFileLoading: 'failed to load JSON file', - fileOutsideAllowedScope: 'not allowed to read file outside of pages directory' -}); - -class PagesRouter extends _PromiseRouter.default { - /** - * Constructs a PagesRouter. - * @param {Object} pages The pages options from the Parse Server configuration. - */ - constructor(pages = {}) { - super(); // Set instance properties - - this.pagesConfig = pages; - this.pagesEndpoint = pages.pagesEndpoint ? pages.pagesEndpoint : 'apps'; - this.pagesPath = pages.pagesPath ? _path.default.resolve('./', pages.pagesPath) : _path.default.resolve(__dirname, '../../public'); - this.loadJsonResource(); - this.mountPagesRoutes(); - } - - verifyEmail(req) { - const config = req.config; - const { - username, - token: rawToken - } = req.query; - const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken; - - if (!config) { - this.invalidRequest(); - } - - if (!token || !username) { - return this.goToPage(req, pages.emailVerificationLinkInvalid); - } - - const userController = config.userController; - return userController.verifyEmail(username, token).then(() => { - const params = { - [pageParams.username]: username - }; - return this.goToPage(req, pages.emailVerificationSuccess, params); - }, () => { - const params = { - [pageParams.username]: username - }; - return this.goToPage(req, pages.emailVerificationLinkExpired, params); - }); - } - - resendVerificationEmail(req) { - const config = req.config; - const username = req.body.username; - - if (!config) { - this.invalidRequest(); - } - - if (!username) { - return this.goToPage(req, pages.emailVerificationLinkInvalid); - } - - const userController = config.userController; - return userController.resendVerificationEmail(username).then(() => { - return this.goToPage(req, pages.emailVerificationSendSuccess); - }, () => { - return this.goToPage(req, pages.emailVerificationSendFail); - }); - } - - passwordReset(req) { - const config = req.config; - const params = { - [pageParams.appId]: req.params.appId, - [pageParams.appName]: config.appName, - [pageParams.token]: req.query.token, - [pageParams.username]: req.query.username, - [pageParams.publicServerUrl]: config.publicServerURL - }; - return this.goToPage(req, pages.passwordReset, params); - } - - requestResetPassword(req) { - const config = req.config; - - if (!config) { - this.invalidRequest(); - } - - const { - username, - token: rawToken - } = req.query; - const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken; - - if (!username || !token) { - return this.goToPage(req, pages.passwordResetLinkInvalid); - } - - return config.userController.checkResetTokenValidity(username, token).then(() => { - const params = { - [pageParams.token]: token, - [pageParams.username]: username, - [pageParams.appId]: config.applicationId, - [pageParams.appName]: config.appName - }; - return this.goToPage(req, pages.passwordReset, params); - }, () => { - const params = { - [pageParams.username]: username - }; - return this.goToPage(req, pages.passwordResetLinkInvalid, params); - }); - } - - resetPassword(req) { - const config = req.config; - - if (!config) { - this.invalidRequest(); - } - - const { - username, - new_password, - token: rawToken - } = req.body; - const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken; - - if ((!username || !token || !new_password) && req.xhr === false) { - return this.goToPage(req, pages.passwordResetLinkInvalid); - } - - if (!username) { - throw new _node.Parse.Error(_node.Parse.Error.USERNAME_MISSING, 'Missing username'); - } - - if (!token) { - throw new _node.Parse.Error(_node.Parse.Error.OTHER_CAUSE, 'Missing token'); - } - - if (!new_password) { - throw new _node.Parse.Error(_node.Parse.Error.PASSWORD_MISSING, 'Missing password'); - } - - return config.userController.updatePassword(username, token, new_password).then(() => { - return Promise.resolve({ - success: true - }); - }, err => { - return Promise.resolve({ - success: false, - err - }); - }).then(result => { - if (req.xhr) { - if (result.success) { - return Promise.resolve({ - status: 200, - response: 'Password successfully reset' - }); - } - - if (result.err) { - throw new _node.Parse.Error(_node.Parse.Error.OTHER_CAUSE, `${result.err}`); - } - } - - const query = result.success ? { - [pageParams.username]: username - } : { - [pageParams.username]: username, - [pageParams.token]: token, - [pageParams.appId]: config.applicationId, - [pageParams.error]: result.err, - [pageParams.appName]: config.appName - }; - const page = result.success ? pages.passwordResetSuccess : pages.passwordReset; - return this.goToPage(req, page, query, false); - }); - } - /** - * Returns page content if the page is a local file or returns a - * redirect to a custom page. - * @param {Object} req The express request. - * @param {Page} page The page to go to. - * @param {Object} [params={}] The query parameters to attach to the URL in case of - * HTTP redirect responses for POST requests, or the placeholders to fill into - * the response content in case of HTTP content responses for GET requests. - * @param {Boolean} [responseType] Is true if a redirect response should be forced, - * false if a content response should be forced, undefined if the response type - * should depend on the request type by default: - * - GET request -> content response - * - POST request -> redirect response (PRG pattern) - * @returns {Promise} The PromiseRouter response. - */ - - - goToPage(req, page, params = {}, responseType) { - const config = req.config; // Determine redirect either by force, response setting or request method - - const redirect = config.pages.forceRedirect ? true : responseType !== undefined ? responseType : req.method == 'POST'; // Include default parameters - - const defaultParams = this.getDefaultParams(config); - - if (Object.values(defaultParams).includes(undefined)) { - return this.notFound(); - } - - params = Object.assign(params, defaultParams); // Add locale to params to ensure it is passed on with every request; - // that means, once a locale is set, it is passed on to any follow-up page, - // e.g. request_password_reset -> password_reset -> passwort_reset_success - - const locale = this.getLocale(req); - params[pageParams.locale] = locale; // Compose paths and URLs - - const defaultFile = page.defaultFile; - const defaultPath = this.defaultPagePath(defaultFile); - const defaultUrl = this.composePageUrl(defaultFile, config.publicServerURL); // If custom URL is set redirect to it without localization - - const customUrl = config.pages.customUrls[page.id]; - - if (customUrl && !_Utils.default.isPath(customUrl)) { - return this.redirectResponse(customUrl, params); - } // Get JSON placeholders - - - let placeholders = {}; - - if (config.pages.enableLocalization && config.pages.localizationJsonPath) { - placeholders = this.getJsonPlaceholders(locale, params); - } // Send response - - - if (config.pages.enableLocalization && locale) { - return _Utils.default.getLocalizedPath(defaultPath, locale).then(({ - path, - subdir - }) => redirect ? this.redirectResponse(this.composePageUrl(defaultFile, config.publicServerURL, subdir), params) : this.pageResponse(path, params, placeholders)); - } else { - return redirect ? this.redirectResponse(defaultUrl, params) : this.pageResponse(defaultPath, params, placeholders); - } - } - /** - * Serves a request to a static resource and localizes the resource if it - * is a HTML file. - * @param {Object} req The request object. - * @returns {Promise} The response. - */ - - - staticRoute(req) { - // Get requested path - const relativePath = req.params[0]; // Resolve requested path to absolute path - - const absolutePath = _path.default.resolve(this.pagesPath, relativePath); // If the requested file is not a HTML file send its raw content - - - if (!absolutePath || !absolutePath.endsWith('.html')) { - return this.fileResponse(absolutePath); - } // Get parameters - - - const params = this.getDefaultParams(req.config); - const locale = this.getLocale(req); - - if (locale) { - params.locale = locale; - } // Get JSON placeholders - - - const placeholders = this.getJsonPlaceholders(locale, params); - return this.pageResponse(absolutePath, params, placeholders); - } - /** - * Returns a translation from the JSON resource for a given locale. The JSON - * resource is parsed according to i18next syntax. - * - * Example JSON content: - * ```js - * { - * "en": { // resource for language `en` (English) - * "translation": { - * "greeting": "Hello!" - * } - * }, - * "de": { // resource for language `de` (German) - * "translation": { - * "greeting": "Hallo!" - * } - * } - * "de-CH": { // resource for locale `de-CH` (Swiss German) - * "translation": { - * "greeting": "Grüezi!" - * } - * } - * } - * ``` - * @param {String} locale The locale to translate to. - * @returns {Object} The translation or an empty object if no matching - * translation was found. - */ - - - getJsonTranslation(locale) { - // If there is no JSON resource - if (this.jsonParameters === undefined) { - return {}; - } // If locale is not set use the fallback locale - - - locale = locale || this.pagesConfig.localizationFallbackLocale; // Get matching translation by locale, language or fallback locale - - const language = locale.split('-')[0]; - const resource = this.jsonParameters[locale] || this.jsonParameters[language] || this.jsonParameters[this.pagesConfig.localizationFallbackLocale] || {}; - const translation = resource.translation || {}; - return translation; - } - /** - * Returns a translation from the JSON resource for a given locale with - * placeholders filled in by given parameters. - * @param {String} locale The locale to translate to. - * @param {Object} params The parameters to fill into any placeholders - * within the translations. - * @returns {Object} The translation or an empty object if no matching - * translation was found. - */ - - - getJsonPlaceholders(locale, params = {}) { - // If localization is disabled or there is no JSON resource - if (!this.pagesConfig.enableLocalization || !this.pagesConfig.localizationJsonPath) { - return {}; - } // Get JSON placeholders - - - let placeholders = this.getJsonTranslation(locale); // Fill in any placeholders in the translation; this allows a translation - // to contain default placeholders like {{appName}} which are filled here - - placeholders = JSON.stringify(placeholders); - placeholders = _mustache.default.render(placeholders, params); - placeholders = JSON.parse(placeholders); - return placeholders; - } - /** - * Creates a response with file content. - * @param {String} path The path of the file to return. - * @param {Object} [params={}] The parameters to be included in the response - * header. These will also be used to fill placeholders. - * @param {Object} [placeholders={}] The placeholders to fill in the content. - * These will not be included in the response header. - * @returns {Object} The Promise Router response. - */ - - - async pageResponse(path, params = {}, placeholders = {}) { - // Get file content - let data; - - try { - data = await this.readFile(path); - } catch (e) { - return this.notFound(); - } // Get config placeholders; can be an object, a function or an async function - - - let configPlaceholders = typeof this.pagesConfig.placeholders === 'function' ? this.pagesConfig.placeholders(params) : Object.prototype.toString.call(this.pagesConfig.placeholders) === '[object Object]' ? this.pagesConfig.placeholders : {}; - - if (configPlaceholders instanceof Promise) { - configPlaceholders = await configPlaceholders; - } // Fill placeholders - - - const allPlaceholders = Object.assign({}, configPlaceholders, placeholders); - const paramsAndPlaceholders = Object.assign({}, params, allPlaceholders); - data = _mustache.default.render(data, paramsAndPlaceholders); // Add placeholders in header to allow parsing for programmatic use - // of response, instead of having to parse the HTML content. - - const headers = Object.entries(params).reduce((m, p) => { - if (p[1] !== undefined) { - m[`${pageParamHeaderPrefix}${p[0].toLowerCase()}`] = p[1]; - } - - return m; - }, {}); - return { - text: data, - headers: headers - }; - } - /** - * Creates a response with file content. - * @param {String} path The path of the file to return. - * @returns {Object} The PromiseRouter response. - */ - - - async fileResponse(path) { - // Get file content - let data; - - try { - data = await this.readFile(path); - } catch (e) { - return this.notFound(); - } - - return { - text: data - }; - } - /** - * Reads and returns the content of a file at a given path. File reading to - * serve content on the static route is only allowed from the pages - * directory on downwards. - * ----------------------------------------------------------------------- - * **WARNING:** All file reads in the PagesRouter must be executed by this - * wrapper because it also detects and prevents common exploits. - * ----------------------------------------------------------------------- - * @param {String} filePath The path to the file to read. - * @returns {Promise} The file content. - */ - - - async readFile(filePath) { - // Normalize path to prevent it from containing any directory changing - // UNIX patterns which could expose the whole file system, e.g. - // `http://example.com/parse/apps/../file.txt` requests a file outside - // of the pages directory scope. - const normalizedPath = _path.default.normalize(filePath); // Abort if the path is outside of the path directory scope - - - if (!normalizedPath.startsWith(this.pagesPath)) { - throw errors.fileOutsideAllowedScope; - } - - return await _fs.promises.readFile(normalizedPath, 'utf-8'); - } - /** - * Loads a language resource JSON file that is used for translations. - */ - - - loadJsonResource() { - if (this.pagesConfig.localizationJsonPath === undefined) { - return; - } - - try { - const json = require(_path.default.resolve('./', this.pagesConfig.localizationJsonPath)); - - this.jsonParameters = json; - } catch (e) { - throw errors.jsonFailedFileLoading; - } - } - /** - * Extracts and returns the page default parameters from the Parse Server - * configuration. These parameters are made accessible in every page served - * by this router. - * @param {Object} config The Parse Server configuration. - * @returns {Object} The default parameters. - */ - - - getDefaultParams(config) { - return config ? { - [pageParams.appId]: config.appId, - [pageParams.appName]: config.appName, - [pageParams.publicServerUrl]: config.publicServerURL - } : {}; - } - /** - * Extracts and returns the locale from an express request. - * @param {Object} req The express request. - * @returns {String|undefined} The locale, or undefined if no locale was set. - */ - - - getLocale(req) { - const locale = (req.query || {})[pageParams.locale] || (req.body || {})[pageParams.locale] || (req.params || {})[pageParams.locale] || (req.headers || {})[pageParamHeaderPrefix + pageParams.locale]; - return locale; - } - /** - * Creates a response with http rediret. - * @param {Object} req The express request. - * @param {String} path The path of the file to return. - * @param {Object} params The query parameters to include. - * @returns {Object} The Promise Router response. - */ - - - async redirectResponse(url, params) { - // Remove any parameters with undefined value - params = Object.entries(params).reduce((m, p) => { - if (p[1] !== undefined) { - m[p[0]] = p[1]; - } - - return m; - }, {}); // Compose URL with parameters in query - - const location = new URL(url); - Object.entries(params).forEach(p => location.searchParams.set(p[0], p[1])); - const locationString = location.toString(); // Add parameters to header to allow parsing for programmatic use - // of response, instead of having to parse the HTML content. - - const headers = Object.entries(params).reduce((m, p) => { - if (p[1] !== undefined) { - m[`${pageParamHeaderPrefix}${p[0].toLowerCase()}`] = p[1]; - } - - return m; - }, {}); - return { - status: 303, - location: locationString, - headers: headers - }; - } - - defaultPagePath(file) { - return _path.default.join(this.pagesPath, file); - } - - composePageUrl(file, publicServerUrl, locale) { - let url = publicServerUrl; - url += url.endsWith('/') ? '' : '/'; - url += this.pagesEndpoint + '/'; - url += locale === undefined ? '' : locale + '/'; - url += file; - return url; - } - - notFound() { - return { - text: 'Not found.', - status: 404 - }; - } - - invalidRequest() { - const error = new Error(); - error.status = 403; - error.message = 'unauthorized'; - throw error; - } - /** - * Sets the Parse Server configuration in the request object to make it - * easily accessible throughtout request processing. - * @param {Object} req The request. - * @param {Boolean} failGracefully Is true if failing to set the config should - * not result in an invalid request response. Default is `false`. - */ - - - setConfig(req, failGracefully = false) { - req.config = _Config.default.get(req.params.appId || req.query.appId); - - if (!req.config && !failGracefully) { - this.invalidRequest(); - } - - return Promise.resolve(); - } - - mountPagesRoutes() { - this.route('GET', `/${this.pagesEndpoint}/:appId/verify_email`, req => { - this.setConfig(req); - }, req => { - return this.verifyEmail(req); - }); - this.route('POST', `/${this.pagesEndpoint}/:appId/resend_verification_email`, req => { - this.setConfig(req); - }, req => { - return this.resendVerificationEmail(req); - }); - this.route('GET', `/${this.pagesEndpoint}/choose_password`, req => { - this.setConfig(req); - }, req => { - return this.passwordReset(req); - }); - this.route('POST', `/${this.pagesEndpoint}/:appId/request_password_reset`, req => { - this.setConfig(req); - }, req => { - return this.resetPassword(req); - }); - this.route('GET', `/${this.pagesEndpoint}/:appId/request_password_reset`, req => { - this.setConfig(req); - }, req => { - return this.requestResetPassword(req); - }); - this.route('GET', `/${this.pagesEndpoint}/(*)?`, req => { - this.setConfig(req, true); - }, req => { - return this.staticRoute(req); - }); - } - - expressRouter() { - const router = _express.default.Router(); - - router.use('/', super.expressRouter()); - return router; - } - -} - -exports.PagesRouter = PagesRouter; -var _default = PagesRouter; -exports.default = _default; -module.exports = { - PagesRouter, - pageParamHeaderPrefix, - pageParams, - pages -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1BhZ2VzUm91dGVyLmpzIl0sIm5hbWVzIjpbInBhZ2VzIiwiT2JqZWN0IiwiZnJlZXplIiwicGFzc3dvcmRSZXNldCIsIlBhZ2UiLCJpZCIsImRlZmF1bHRGaWxlIiwicGFzc3dvcmRSZXNldFN1Y2Nlc3MiLCJwYXNzd29yZFJlc2V0TGlua0ludmFsaWQiLCJlbWFpbFZlcmlmaWNhdGlvblN1Y2Nlc3MiLCJlbWFpbFZlcmlmaWNhdGlvblNlbmRGYWlsIiwiZW1haWxWZXJpZmljYXRpb25TZW5kU3VjY2VzcyIsImVtYWlsVmVyaWZpY2F0aW9uTGlua0ludmFsaWQiLCJlbWFpbFZlcmlmaWNhdGlvbkxpbmtFeHBpcmVkIiwicGFnZVBhcmFtcyIsImFwcE5hbWUiLCJhcHBJZCIsInRva2VuIiwidXNlcm5hbWUiLCJlcnJvciIsImxvY2FsZSIsInB1YmxpY1NlcnZlclVybCIsInBhZ2VQYXJhbUhlYWRlclByZWZpeCIsImVycm9ycyIsImpzb25GYWlsZWRGaWxlTG9hZGluZyIsImZpbGVPdXRzaWRlQWxsb3dlZFNjb3BlIiwiUGFnZXNSb3V0ZXIiLCJQcm9taXNlUm91dGVyIiwiY29uc3RydWN0b3IiLCJwYWdlc0NvbmZpZyIsInBhZ2VzRW5kcG9pbnQiLCJwYWdlc1BhdGgiLCJwYXRoIiwicmVzb2x2ZSIsIl9fZGlybmFtZSIsImxvYWRKc29uUmVzb3VyY2UiLCJtb3VudFBhZ2VzUm91dGVzIiwidmVyaWZ5RW1haWwiLCJyZXEiLCJjb25maWciLCJyYXdUb2tlbiIsInF1ZXJ5IiwidG9TdHJpbmciLCJpbnZhbGlkUmVxdWVzdCIsImdvVG9QYWdlIiwidXNlckNvbnRyb2xsZXIiLCJ0aGVuIiwicGFyYW1zIiwicmVzZW5kVmVyaWZpY2F0aW9uRW1haWwiLCJib2R5IiwicHVibGljU2VydmVyVVJMIiwicmVxdWVzdFJlc2V0UGFzc3dvcmQiLCJjaGVja1Jlc2V0VG9rZW5WYWxpZGl0eSIsImFwcGxpY2F0aW9uSWQiLCJyZXNldFBhc3N3b3JkIiwibmV3X3Bhc3N3b3JkIiwieGhyIiwiUGFyc2UiLCJFcnJvciIsIlVTRVJOQU1FX01JU1NJTkciLCJPVEhFUl9DQVVTRSIsIlBBU1NXT1JEX01JU1NJTkciLCJ1cGRhdGVQYXNzd29yZCIsIlByb21pc2UiLCJzdWNjZXNzIiwiZXJyIiwicmVzdWx0Iiwic3RhdHVzIiwicmVzcG9uc2UiLCJwYWdlIiwicmVzcG9uc2VUeXBlIiwicmVkaXJlY3QiLCJmb3JjZVJlZGlyZWN0IiwidW5kZWZpbmVkIiwibWV0aG9kIiwiZGVmYXVsdFBhcmFtcyIsImdldERlZmF1bHRQYXJhbXMiLCJ2YWx1ZXMiLCJpbmNsdWRlcyIsIm5vdEZvdW5kIiwiYXNzaWduIiwiZ2V0TG9jYWxlIiwiZGVmYXVsdFBhdGgiLCJkZWZhdWx0UGFnZVBhdGgiLCJkZWZhdWx0VXJsIiwiY29tcG9zZVBhZ2VVcmwiLCJjdXN0b21VcmwiLCJjdXN0b21VcmxzIiwiVXRpbHMiLCJpc1BhdGgiLCJyZWRpcmVjdFJlc3BvbnNlIiwicGxhY2Vob2xkZXJzIiwiZW5hYmxlTG9jYWxpemF0aW9uIiwibG9jYWxpemF0aW9uSnNvblBhdGgiLCJnZXRKc29uUGxhY2Vob2xkZXJzIiwiZ2V0TG9jYWxpemVkUGF0aCIsInN1YmRpciIsInBhZ2VSZXNwb25zZSIsInN0YXRpY1JvdXRlIiwicmVsYXRpdmVQYXRoIiwiYWJzb2x1dGVQYXRoIiwiZW5kc1dpdGgiLCJmaWxlUmVzcG9uc2UiLCJnZXRKc29uVHJhbnNsYXRpb24iLCJqc29uUGFyYW1ldGVycyIsImxvY2FsaXphdGlvbkZhbGxiYWNrTG9jYWxlIiwibGFuZ3VhZ2UiLCJzcGxpdCIsInJlc291cmNlIiwidHJhbnNsYXRpb24iLCJKU09OIiwic3RyaW5naWZ5IiwibXVzdGFjaGUiLCJyZW5kZXIiLCJwYXJzZSIsImRhdGEiLCJyZWFkRmlsZSIsImUiLCJjb25maWdQbGFjZWhvbGRlcnMiLCJwcm90b3R5cGUiLCJjYWxsIiwiYWxsUGxhY2Vob2xkZXJzIiwicGFyYW1zQW5kUGxhY2Vob2xkZXJzIiwiaGVhZGVycyIsImVudHJpZXMiLCJyZWR1Y2UiLCJtIiwicCIsInRvTG93ZXJDYXNlIiwidGV4dCIsImZpbGVQYXRoIiwibm9ybWFsaXplZFBhdGgiLCJub3JtYWxpemUiLCJzdGFydHNXaXRoIiwiZnMiLCJqc29uIiwicmVxdWlyZSIsInVybCIsImxvY2F0aW9uIiwiVVJMIiwiZm9yRWFjaCIsInNlYXJjaFBhcmFtcyIsInNldCIsImxvY2F0aW9uU3RyaW5nIiwiZmlsZSIsImpvaW4iLCJtZXNzYWdlIiwic2V0Q29uZmlnIiwiZmFpbEdyYWNlZnVsbHkiLCJDb25maWciLCJnZXQiLCJyb3V0ZSIsImV4cHJlc3NSb3V0ZXIiLCJyb3V0ZXIiLCJleHByZXNzIiwiUm91dGVyIiwidXNlIiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRUE7QUFDQSxNQUFNQSxLQUFLLEdBQUdDLE1BQU0sQ0FBQ0MsTUFBUCxDQUFjO0FBQzFCQyxFQUFBQSxhQUFhLEVBQUUsSUFBSUMsYUFBSixDQUFTO0FBQUVDLElBQUFBLEVBQUUsRUFBRSxlQUFOO0FBQXVCQyxJQUFBQSxXQUFXLEVBQUU7QUFBcEMsR0FBVCxDQURXO0FBRTFCQyxFQUFBQSxvQkFBb0IsRUFBRSxJQUFJSCxhQUFKLENBQVM7QUFDN0JDLElBQUFBLEVBQUUsRUFBRSxzQkFEeUI7QUFFN0JDLElBQUFBLFdBQVcsRUFBRTtBQUZnQixHQUFULENBRkk7QUFNMUJFLEVBQUFBLHdCQUF3QixFQUFFLElBQUlKLGFBQUosQ0FBUztBQUNqQ0MsSUFBQUEsRUFBRSxFQUFFLDBCQUQ2QjtBQUVqQ0MsSUFBQUEsV0FBVyxFQUFFO0FBRm9CLEdBQVQsQ0FOQTtBQVUxQkcsRUFBQUEsd0JBQXdCLEVBQUUsSUFBSUwsYUFBSixDQUFTO0FBQ2pDQyxJQUFBQSxFQUFFLEVBQUUsMEJBRDZCO0FBRWpDQyxJQUFBQSxXQUFXLEVBQUU7QUFGb0IsR0FBVCxDQVZBO0FBYzFCSSxFQUFBQSx5QkFBeUIsRUFBRSxJQUFJTixhQUFKLENBQVM7QUFDbENDLElBQUFBLEVBQUUsRUFBRSwyQkFEOEI7QUFFbENDLElBQUFBLFdBQVcsRUFBRTtBQUZxQixHQUFULENBZEQ7QUFrQjFCSyxFQUFBQSw0QkFBNEIsRUFBRSxJQUFJUCxhQUFKLENBQVM7QUFDckNDLElBQUFBLEVBQUUsRUFBRSw4QkFEaUM7QUFFckNDLElBQUFBLFdBQVcsRUFBRTtBQUZ3QixHQUFULENBbEJKO0FBc0IxQk0sRUFBQUEsNEJBQTRCLEVBQUUsSUFBSVIsYUFBSixDQUFTO0FBQ3JDQyxJQUFBQSxFQUFFLEVBQUUsOEJBRGlDO0FBRXJDQyxJQUFBQSxXQUFXLEVBQUU7QUFGd0IsR0FBVCxDQXRCSjtBQTBCMUJPLEVBQUFBLDRCQUE0QixFQUFFLElBQUlULGFBQUosQ0FBUztBQUNyQ0MsSUFBQUEsRUFBRSxFQUFFLDhCQURpQztBQUVyQ0MsSUFBQUEsV0FBVyxFQUFFO0FBRndCLEdBQVQ7QUExQkosQ0FBZCxDQUFkLEMsQ0FnQ0E7O0FBQ0EsTUFBTVEsVUFBVSxHQUFHYixNQUFNLENBQUNDLE1BQVAsQ0FBYztBQUMvQmEsRUFBQUEsT0FBTyxFQUFFLFNBRHNCO0FBRS9CQyxFQUFBQSxLQUFLLEVBQUUsT0FGd0I7QUFHL0JDLEVBQUFBLEtBQUssRUFBRSxPQUh3QjtBQUkvQkMsRUFBQUEsUUFBUSxFQUFFLFVBSnFCO0FBSy9CQyxFQUFBQSxLQUFLLEVBQUUsT0FMd0I7QUFNL0JDLEVBQUFBLE1BQU0sRUFBRSxRQU51QjtBQU8vQkMsRUFBQUEsZUFBZSxFQUFFO0FBUGMsQ0FBZCxDQUFuQixDLENBVUE7O0FBQ0EsTUFBTUMscUJBQXFCLEdBQUcscUJBQTlCLEMsQ0FFQTs7QUFDQSxNQUFNQyxNQUFNLEdBQUd0QixNQUFNLENBQUNDLE1BQVAsQ0FBYztBQUMzQnNCLEVBQUFBLHFCQUFxQixFQUFFLDBCQURJO0FBRTNCQyxFQUFBQSx1QkFBdUIsRUFBRTtBQUZFLENBQWQsQ0FBZjs7QUFLTyxNQUFNQyxXQUFOLFNBQTBCQyxzQkFBMUIsQ0FBd0M7QUFDN0M7QUFDRjtBQUNBO0FBQ0E7QUFDRUMsRUFBQUEsV0FBVyxDQUFDNUIsS0FBSyxHQUFHLEVBQVQsRUFBYTtBQUN0QixZQURzQixDQUd0Qjs7QUFDQSxTQUFLNkIsV0FBTCxHQUFtQjdCLEtBQW5CO0FBQ0EsU0FBSzhCLGFBQUwsR0FBcUI5QixLQUFLLENBQUM4QixhQUFOLEdBQXNCOUIsS0FBSyxDQUFDOEIsYUFBNUIsR0FBNEMsTUFBakU7QUFDQSxTQUFLQyxTQUFMLEdBQWlCL0IsS0FBSyxDQUFDK0IsU0FBTixHQUNiQyxjQUFLQyxPQUFMLENBQWEsSUFBYixFQUFtQmpDLEtBQUssQ0FBQytCLFNBQXpCLENBRGEsR0FFYkMsY0FBS0MsT0FBTCxDQUFhQyxTQUFiLEVBQXdCLGNBQXhCLENBRko7QUFHQSxTQUFLQyxnQkFBTDtBQUNBLFNBQUtDLGdCQUFMO0FBQ0Q7O0FBRURDLEVBQUFBLFdBQVcsQ0FBQ0MsR0FBRCxFQUFNO0FBQ2YsVUFBTUMsTUFBTSxHQUFHRCxHQUFHLENBQUNDLE1BQW5CO0FBQ0EsVUFBTTtBQUFFckIsTUFBQUEsUUFBRjtBQUFZRCxNQUFBQSxLQUFLLEVBQUV1QjtBQUFuQixRQUFnQ0YsR0FBRyxDQUFDRyxLQUExQztBQUNBLFVBQU14QixLQUFLLEdBQUd1QixRQUFRLElBQUksT0FBT0EsUUFBUCxLQUFvQixRQUFoQyxHQUEyQ0EsUUFBUSxDQUFDRSxRQUFULEVBQTNDLEdBQWlFRixRQUEvRTs7QUFFQSxRQUFJLENBQUNELE1BQUwsRUFBYTtBQUNYLFdBQUtJLGNBQUw7QUFDRDs7QUFFRCxRQUFJLENBQUMxQixLQUFELElBQVUsQ0FBQ0MsUUFBZixFQUF5QjtBQUN2QixhQUFPLEtBQUswQixRQUFMLENBQWNOLEdBQWQsRUFBbUJ0QyxLQUFLLENBQUNZLDRCQUF6QixDQUFQO0FBQ0Q7O0FBRUQsVUFBTWlDLGNBQWMsR0FBR04sTUFBTSxDQUFDTSxjQUE5QjtBQUNBLFdBQU9BLGNBQWMsQ0FBQ1IsV0FBZixDQUEyQm5CLFFBQTNCLEVBQXFDRCxLQUFyQyxFQUE0QzZCLElBQTVDLENBQ0wsTUFBTTtBQUNKLFlBQU1DLE1BQU0sR0FBRztBQUNiLFNBQUNqQyxVQUFVLENBQUNJLFFBQVosR0FBdUJBO0FBRFYsT0FBZjtBQUdBLGFBQU8sS0FBSzBCLFFBQUwsQ0FBY04sR0FBZCxFQUFtQnRDLEtBQUssQ0FBQ1Msd0JBQXpCLEVBQW1Ec0MsTUFBbkQsQ0FBUDtBQUNELEtBTkksRUFPTCxNQUFNO0FBQ0osWUFBTUEsTUFBTSxHQUFHO0FBQ2IsU0FBQ2pDLFVBQVUsQ0FBQ0ksUUFBWixHQUF1QkE7QUFEVixPQUFmO0FBR0EsYUFBTyxLQUFLMEIsUUFBTCxDQUFjTixHQUFkLEVBQW1CdEMsS0FBSyxDQUFDYSw0QkFBekIsRUFBdURrQyxNQUF2RCxDQUFQO0FBQ0QsS0FaSSxDQUFQO0FBY0Q7O0FBRURDLEVBQUFBLHVCQUF1QixDQUFDVixHQUFELEVBQU07QUFDM0IsVUFBTUMsTUFBTSxHQUFHRCxHQUFHLENBQUNDLE1BQW5CO0FBQ0EsVUFBTXJCLFFBQVEsR0FBR29CLEdBQUcsQ0FBQ1csSUFBSixDQUFTL0IsUUFBMUI7O0FBRUEsUUFBSSxDQUFDcUIsTUFBTCxFQUFhO0FBQ1gsV0FBS0ksY0FBTDtBQUNEOztBQUVELFFBQUksQ0FBQ3pCLFFBQUwsRUFBZTtBQUNiLGFBQU8sS0FBSzBCLFFBQUwsQ0FBY04sR0FBZCxFQUFtQnRDLEtBQUssQ0FBQ1ksNEJBQXpCLENBQVA7QUFDRDs7QUFFRCxVQUFNaUMsY0FBYyxHQUFHTixNQUFNLENBQUNNLGNBQTlCO0FBRUEsV0FBT0EsY0FBYyxDQUFDRyx1QkFBZixDQUF1QzlCLFFBQXZDLEVBQWlENEIsSUFBakQsQ0FDTCxNQUFNO0FBQ0osYUFBTyxLQUFLRixRQUFMLENBQWNOLEdBQWQsRUFBbUJ0QyxLQUFLLENBQUNXLDRCQUF6QixDQUFQO0FBQ0QsS0FISSxFQUlMLE1BQU07QUFDSixhQUFPLEtBQUtpQyxRQUFMLENBQWNOLEdBQWQsRUFBbUJ0QyxLQUFLLENBQUNVLHlCQUF6QixDQUFQO0FBQ0QsS0FOSSxDQUFQO0FBUUQ7O0FBRURQLEVBQUFBLGFBQWEsQ0FBQ21DLEdBQUQsRUFBTTtBQUNqQixVQUFNQyxNQUFNLEdBQUdELEdBQUcsQ0FBQ0MsTUFBbkI7QUFDQSxVQUFNUSxNQUFNLEdBQUc7QUFDYixPQUFDakMsVUFBVSxDQUFDRSxLQUFaLEdBQW9Cc0IsR0FBRyxDQUFDUyxNQUFKLENBQVcvQixLQURsQjtBQUViLE9BQUNGLFVBQVUsQ0FBQ0MsT0FBWixHQUFzQndCLE1BQU0sQ0FBQ3hCLE9BRmhCO0FBR2IsT0FBQ0QsVUFBVSxDQUFDRyxLQUFaLEdBQW9CcUIsR0FBRyxDQUFDRyxLQUFKLENBQVV4QixLQUhqQjtBQUliLE9BQUNILFVBQVUsQ0FBQ0ksUUFBWixHQUF1Qm9CLEdBQUcsQ0FBQ0csS0FBSixDQUFVdkIsUUFKcEI7QUFLYixPQUFDSixVQUFVLENBQUNPLGVBQVosR0FBOEJrQixNQUFNLENBQUNXO0FBTHhCLEtBQWY7QUFPQSxXQUFPLEtBQUtOLFFBQUwsQ0FBY04sR0FBZCxFQUFtQnRDLEtBQUssQ0FBQ0csYUFBekIsRUFBd0M0QyxNQUF4QyxDQUFQO0FBQ0Q7O0FBRURJLEVBQUFBLG9CQUFvQixDQUFDYixHQUFELEVBQU07QUFDeEIsVUFBTUMsTUFBTSxHQUFHRCxHQUFHLENBQUNDLE1BQW5COztBQUVBLFFBQUksQ0FBQ0EsTUFBTCxFQUFhO0FBQ1gsV0FBS0ksY0FBTDtBQUNEOztBQUVELFVBQU07QUFBRXpCLE1BQUFBLFFBQUY7QUFBWUQsTUFBQUEsS0FBSyxFQUFFdUI7QUFBbkIsUUFBZ0NGLEdBQUcsQ0FBQ0csS0FBMUM7QUFDQSxVQUFNeEIsS0FBSyxHQUFHdUIsUUFBUSxJQUFJLE9BQU9BLFFBQVAsS0FBb0IsUUFBaEMsR0FBMkNBLFFBQVEsQ0FBQ0UsUUFBVCxFQUEzQyxHQUFpRUYsUUFBL0U7O0FBRUEsUUFBSSxDQUFDdEIsUUFBRCxJQUFhLENBQUNELEtBQWxCLEVBQXlCO0FBQ3ZCLGFBQU8sS0FBSzJCLFFBQUwsQ0FBY04sR0FBZCxFQUFtQnRDLEtBQUssQ0FBQ1Esd0JBQXpCLENBQVA7QUFDRDs7QUFFRCxXQUFPK0IsTUFBTSxDQUFDTSxjQUFQLENBQXNCTyx1QkFBdEIsQ0FBOENsQyxRQUE5QyxFQUF3REQsS0FBeEQsRUFBK0Q2QixJQUEvRCxDQUNMLE1BQU07QUFDSixZQUFNQyxNQUFNLEdBQUc7QUFDYixTQUFDakMsVUFBVSxDQUFDRyxLQUFaLEdBQW9CQSxLQURQO0FBRWIsU0FBQ0gsVUFBVSxDQUFDSSxRQUFaLEdBQXVCQSxRQUZWO0FBR2IsU0FBQ0osVUFBVSxDQUFDRSxLQUFaLEdBQW9CdUIsTUFBTSxDQUFDYyxhQUhkO0FBSWIsU0FBQ3ZDLFVBQVUsQ0FBQ0MsT0FBWixHQUFzQndCLE1BQU0sQ0FBQ3hCO0FBSmhCLE9BQWY7QUFNQSxhQUFPLEtBQUs2QixRQUFMLENBQWNOLEdBQWQsRUFBbUJ0QyxLQUFLLENBQUNHLGFBQXpCLEVBQXdDNEMsTUFBeEMsQ0FBUDtBQUNELEtBVEksRUFVTCxNQUFNO0FBQ0osWUFBTUEsTUFBTSxHQUFHO0FBQ2IsU0FBQ2pDLFVBQVUsQ0FBQ0ksUUFBWixHQUF1QkE7QUFEVixPQUFmO0FBR0EsYUFBTyxLQUFLMEIsUUFBTCxDQUFjTixHQUFkLEVBQW1CdEMsS0FBSyxDQUFDUSx3QkFBekIsRUFBbUR1QyxNQUFuRCxDQUFQO0FBQ0QsS0FmSSxDQUFQO0FBaUJEOztBQUVETyxFQUFBQSxhQUFhLENBQUNoQixHQUFELEVBQU07QUFDakIsVUFBTUMsTUFBTSxHQUFHRCxHQUFHLENBQUNDLE1BQW5COztBQUVBLFFBQUksQ0FBQ0EsTUFBTCxFQUFhO0FBQ1gsV0FBS0ksY0FBTDtBQUNEOztBQUVELFVBQU07QUFBRXpCLE1BQUFBLFFBQUY7QUFBWXFDLE1BQUFBLFlBQVo7QUFBMEJ0QyxNQUFBQSxLQUFLLEVBQUV1QjtBQUFqQyxRQUE4Q0YsR0FBRyxDQUFDVyxJQUF4RDtBQUNBLFVBQU1oQyxLQUFLLEdBQUd1QixRQUFRLElBQUksT0FBT0EsUUFBUCxLQUFvQixRQUFoQyxHQUEyQ0EsUUFBUSxDQUFDRSxRQUFULEVBQTNDLEdBQWlFRixRQUEvRTs7QUFFQSxRQUFJLENBQUMsQ0FBQ3RCLFFBQUQsSUFBYSxDQUFDRCxLQUFkLElBQXVCLENBQUNzQyxZQUF6QixLQUEwQ2pCLEdBQUcsQ0FBQ2tCLEdBQUosS0FBWSxLQUExRCxFQUFpRTtBQUMvRCxhQUFPLEtBQUtaLFFBQUwsQ0FBY04sR0FBZCxFQUFtQnRDLEtBQUssQ0FBQ1Esd0JBQXpCLENBQVA7QUFDRDs7QUFFRCxRQUFJLENBQUNVLFFBQUwsRUFBZTtBQUNiLFlBQU0sSUFBSXVDLFlBQU1DLEtBQVYsQ0FBZ0JELFlBQU1DLEtBQU4sQ0FBWUMsZ0JBQTVCLEVBQThDLGtCQUE5QyxDQUFOO0FBQ0Q7O0FBRUQsUUFBSSxDQUFDMUMsS0FBTCxFQUFZO0FBQ1YsWUFBTSxJQUFJd0MsWUFBTUMsS0FBVixDQUFnQkQsWUFBTUMsS0FBTixDQUFZRSxXQUE1QixFQUF5QyxlQUF6QyxDQUFOO0FBQ0Q7O0FBRUQsUUFBSSxDQUFDTCxZQUFMLEVBQW1CO0FBQ2pCLFlBQU0sSUFBSUUsWUFBTUMsS0FBVixDQUFnQkQsWUFBTUMsS0FBTixDQUFZRyxnQkFBNUIsRUFBOEMsa0JBQTlDLENBQU47QUFDRDs7QUFFRCxXQUFPdEIsTUFBTSxDQUFDTSxjQUFQLENBQ0ppQixjQURJLENBQ1c1QyxRQURYLEVBQ3FCRCxLQURyQixFQUM0QnNDLFlBRDVCLEVBRUpULElBRkksQ0FHSCxNQUFNO0FBQ0osYUFBT2lCLE9BQU8sQ0FBQzlCLE9BQVIsQ0FBZ0I7QUFDckIrQixRQUFBQSxPQUFPLEVBQUU7QUFEWSxPQUFoQixDQUFQO0FBR0QsS0FQRSxFQVFIQyxHQUFHLElBQUk7QUFDTCxhQUFPRixPQUFPLENBQUM5QixPQUFSLENBQWdCO0FBQ3JCK0IsUUFBQUEsT0FBTyxFQUFFLEtBRFk7QUFFckJDLFFBQUFBO0FBRnFCLE9BQWhCLENBQVA7QUFJRCxLQWJFLEVBZUpuQixJQWZJLENBZUNvQixNQUFNLElBQUk7QUFDZCxVQUFJNUIsR0FBRyxDQUFDa0IsR0FBUixFQUFhO0FBQ1gsWUFBSVUsTUFBTSxDQUFDRixPQUFYLEVBQW9CO0FBQ2xCLGlCQUFPRCxPQUFPLENBQUM5QixPQUFSLENBQWdCO0FBQ3JCa0MsWUFBQUEsTUFBTSxFQUFFLEdBRGE7QUFFckJDLFlBQUFBLFFBQVEsRUFBRTtBQUZXLFdBQWhCLENBQVA7QUFJRDs7QUFDRCxZQUFJRixNQUFNLENBQUNELEdBQVgsRUFBZ0I7QUFDZCxnQkFBTSxJQUFJUixZQUFNQyxLQUFWLENBQWdCRCxZQUFNQyxLQUFOLENBQVlFLFdBQTVCLEVBQTBDLEdBQUVNLE1BQU0sQ0FBQ0QsR0FBSSxFQUF2RCxDQUFOO0FBQ0Q7QUFDRjs7QUFFRCxZQUFNeEIsS0FBSyxHQUFHeUIsTUFBTSxDQUFDRixPQUFQLEdBQ1Y7QUFDQSxTQUFDbEQsVUFBVSxDQUFDSSxRQUFaLEdBQXVCQTtBQUR2QixPQURVLEdBSVY7QUFDQSxTQUFDSixVQUFVLENBQUNJLFFBQVosR0FBdUJBLFFBRHZCO0FBRUEsU0FBQ0osVUFBVSxDQUFDRyxLQUFaLEdBQW9CQSxLQUZwQjtBQUdBLFNBQUNILFVBQVUsQ0FBQ0UsS0FBWixHQUFvQnVCLE1BQU0sQ0FBQ2MsYUFIM0I7QUFJQSxTQUFDdkMsVUFBVSxDQUFDSyxLQUFaLEdBQW9CK0MsTUFBTSxDQUFDRCxHQUozQjtBQUtBLFNBQUNuRCxVQUFVLENBQUNDLE9BQVosR0FBc0J3QixNQUFNLENBQUN4QjtBQUw3QixPQUpKO0FBV0EsWUFBTXNELElBQUksR0FBR0gsTUFBTSxDQUFDRixPQUFQLEdBQWlCaEUsS0FBSyxDQUFDTyxvQkFBdkIsR0FBOENQLEtBQUssQ0FBQ0csYUFBakU7QUFFQSxhQUFPLEtBQUt5QyxRQUFMLENBQWNOLEdBQWQsRUFBbUIrQixJQUFuQixFQUF5QjVCLEtBQXpCLEVBQWdDLEtBQWhDLENBQVA7QUFDRCxLQTFDSSxDQUFQO0FBMkNEO0FBRUQ7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDRUcsRUFBQUEsUUFBUSxDQUFDTixHQUFELEVBQU0rQixJQUFOLEVBQVl0QixNQUFNLEdBQUcsRUFBckIsRUFBeUJ1QixZQUF6QixFQUF1QztBQUM3QyxVQUFNL0IsTUFBTSxHQUFHRCxHQUFHLENBQUNDLE1BQW5CLENBRDZDLENBRzdDOztBQUNBLFVBQU1nQyxRQUFRLEdBQUdoQyxNQUFNLENBQUN2QyxLQUFQLENBQWF3RSxhQUFiLEdBQ2IsSUFEYSxHQUViRixZQUFZLEtBQUtHLFNBQWpCLEdBQ0VILFlBREYsR0FFRWhDLEdBQUcsQ0FBQ29DLE1BQUosSUFBYyxNQUpwQixDQUo2QyxDQVU3Qzs7QUFDQSxVQUFNQyxhQUFhLEdBQUcsS0FBS0MsZ0JBQUwsQ0FBc0JyQyxNQUF0QixDQUF0Qjs7QUFDQSxRQUFJdEMsTUFBTSxDQUFDNEUsTUFBUCxDQUFjRixhQUFkLEVBQTZCRyxRQUE3QixDQUFzQ0wsU0FBdEMsQ0FBSixFQUFzRDtBQUNwRCxhQUFPLEtBQUtNLFFBQUwsRUFBUDtBQUNEOztBQUNEaEMsSUFBQUEsTUFBTSxHQUFHOUMsTUFBTSxDQUFDK0UsTUFBUCxDQUFjakMsTUFBZCxFQUFzQjRCLGFBQXRCLENBQVQsQ0FmNkMsQ0FpQjdDO0FBQ0E7QUFDQTs7QUFDQSxVQUFNdkQsTUFBTSxHQUFHLEtBQUs2RCxTQUFMLENBQWUzQyxHQUFmLENBQWY7QUFDQVMsSUFBQUEsTUFBTSxDQUFDakMsVUFBVSxDQUFDTSxNQUFaLENBQU4sR0FBNEJBLE1BQTVCLENBckI2QyxDQXVCN0M7O0FBQ0EsVUFBTWQsV0FBVyxHQUFHK0QsSUFBSSxDQUFDL0QsV0FBekI7QUFDQSxVQUFNNEUsV0FBVyxHQUFHLEtBQUtDLGVBQUwsQ0FBcUI3RSxXQUFyQixDQUFwQjtBQUNBLFVBQU04RSxVQUFVLEdBQUcsS0FBS0MsY0FBTCxDQUFvQi9FLFdBQXBCLEVBQWlDaUMsTUFBTSxDQUFDVyxlQUF4QyxDQUFuQixDQTFCNkMsQ0E0QjdDOztBQUNBLFVBQU1vQyxTQUFTLEdBQUcvQyxNQUFNLENBQUN2QyxLQUFQLENBQWF1RixVQUFiLENBQXdCbEIsSUFBSSxDQUFDaEUsRUFBN0IsQ0FBbEI7O0FBQ0EsUUFBSWlGLFNBQVMsSUFBSSxDQUFDRSxlQUFNQyxNQUFOLENBQWFILFNBQWIsQ0FBbEIsRUFBMkM7QUFDekMsYUFBTyxLQUFLSSxnQkFBTCxDQUFzQkosU0FBdEIsRUFBaUN2QyxNQUFqQyxDQUFQO0FBQ0QsS0FoQzRDLENBa0M3Qzs7O0FBQ0EsUUFBSTRDLFlBQVksR0FBRyxFQUFuQjs7QUFDQSxRQUFJcEQsTUFBTSxDQUFDdkMsS0FBUCxDQUFhNEYsa0JBQWIsSUFBbUNyRCxNQUFNLENBQUN2QyxLQUFQLENBQWE2RixvQkFBcEQsRUFBMEU7QUFDeEVGLE1BQUFBLFlBQVksR0FBRyxLQUFLRyxtQkFBTCxDQUF5QjFFLE1BQXpCLEVBQWlDMkIsTUFBakMsQ0FBZjtBQUNELEtBdEM0QyxDQXdDN0M7OztBQUNBLFFBQUlSLE1BQU0sQ0FBQ3ZDLEtBQVAsQ0FBYTRGLGtCQUFiLElBQW1DeEUsTUFBdkMsRUFBK0M7QUFDN0MsYUFBT29FLGVBQU1PLGdCQUFOLENBQXVCYixXQUF2QixFQUFvQzlELE1BQXBDLEVBQTRDMEIsSUFBNUMsQ0FBaUQsQ0FBQztBQUFFZCxRQUFBQSxJQUFGO0FBQVFnRSxRQUFBQTtBQUFSLE9BQUQsS0FDdER6QixRQUFRLEdBQ0osS0FBS21CLGdCQUFMLENBQ0EsS0FBS0wsY0FBTCxDQUFvQi9FLFdBQXBCLEVBQWlDaUMsTUFBTSxDQUFDVyxlQUF4QyxFQUF5RDhDLE1BQXpELENBREEsRUFFQWpELE1BRkEsQ0FESSxHQUtKLEtBQUtrRCxZQUFMLENBQWtCakUsSUFBbEIsRUFBd0JlLE1BQXhCLEVBQWdDNEMsWUFBaEMsQ0FOQyxDQUFQO0FBUUQsS0FURCxNQVNPO0FBQ0wsYUFBT3BCLFFBQVEsR0FDWCxLQUFLbUIsZ0JBQUwsQ0FBc0JOLFVBQXRCLEVBQWtDckMsTUFBbEMsQ0FEVyxHQUVYLEtBQUtrRCxZQUFMLENBQWtCZixXQUFsQixFQUErQm5DLE1BQS9CLEVBQXVDNEMsWUFBdkMsQ0FGSjtBQUdEO0FBQ0Y7QUFFRDtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNFTyxFQUFBQSxXQUFXLENBQUM1RCxHQUFELEVBQU07QUFDZjtBQUNBLFVBQU02RCxZQUFZLEdBQUc3RCxHQUFHLENBQUNTLE1BQUosQ0FBVyxDQUFYLENBQXJCLENBRmUsQ0FJZjs7QUFDQSxVQUFNcUQsWUFBWSxHQUFHcEUsY0FBS0MsT0FBTCxDQUFhLEtBQUtGLFNBQWxCLEVBQTZCb0UsWUFBN0IsQ0FBckIsQ0FMZSxDQU9mOzs7QUFDQSxRQUFJLENBQUNDLFlBQUQsSUFBaUIsQ0FBQ0EsWUFBWSxDQUFDQyxRQUFiLENBQXNCLE9BQXRCLENBQXRCLEVBQXNEO0FBQ3BELGFBQU8sS0FBS0MsWUFBTCxDQUFrQkYsWUFBbEIsQ0FBUDtBQUNELEtBVmMsQ0FZZjs7O0FBQ0EsVUFBTXJELE1BQU0sR0FBRyxLQUFLNkIsZ0JBQUwsQ0FBc0J0QyxHQUFHLENBQUNDLE1BQTFCLENBQWY7QUFDQSxVQUFNbkIsTUFBTSxHQUFHLEtBQUs2RCxTQUFMLENBQWUzQyxHQUFmLENBQWY7O0FBQ0EsUUFBSWxCLE1BQUosRUFBWTtBQUNWMkIsTUFBQUEsTUFBTSxDQUFDM0IsTUFBUCxHQUFnQkEsTUFBaEI7QUFDRCxLQWpCYyxDQW1CZjs7O0FBQ0EsVUFBTXVFLFlBQVksR0FBRyxLQUFLRyxtQkFBTCxDQUF5QjFFLE1BQXpCLEVBQWlDMkIsTUFBakMsQ0FBckI7QUFFQSxXQUFPLEtBQUtrRCxZQUFMLENBQWtCRyxZQUFsQixFQUFnQ3JELE1BQWhDLEVBQXdDNEMsWUFBeEMsQ0FBUDtBQUNEO0FBRUQ7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNFWSxFQUFBQSxrQkFBa0IsQ0FBQ25GLE1BQUQsRUFBUztBQUN6QjtBQUNBLFFBQUksS0FBS29GLGNBQUwsS0FBd0IvQixTQUE1QixFQUF1QztBQUNyQyxhQUFPLEVBQVA7QUFDRCxLQUp3QixDQU16Qjs7O0FBQ0FyRCxJQUFBQSxNQUFNLEdBQUdBLE1BQU0sSUFBSSxLQUFLUyxXQUFMLENBQWlCNEUsMEJBQXBDLENBUHlCLENBU3pCOztBQUNBLFVBQU1DLFFBQVEsR0FBR3RGLE1BQU0sQ0FBQ3VGLEtBQVAsQ0FBYSxHQUFiLEVBQWtCLENBQWxCLENBQWpCO0FBQ0EsVUFBTUMsUUFBUSxHQUNaLEtBQUtKLGNBQUwsQ0FBb0JwRixNQUFwQixLQUNBLEtBQUtvRixjQUFMLENBQW9CRSxRQUFwQixDQURBLElBRUEsS0FBS0YsY0FBTCxDQUFvQixLQUFLM0UsV0FBTCxDQUFpQjRFLDBCQUFyQyxDQUZBLElBR0EsRUFKRjtBQUtBLFVBQU1JLFdBQVcsR0FBR0QsUUFBUSxDQUFDQyxXQUFULElBQXdCLEVBQTVDO0FBQ0EsV0FBT0EsV0FBUDtBQUNEO0FBRUQ7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDRWYsRUFBQUEsbUJBQW1CLENBQUMxRSxNQUFELEVBQVMyQixNQUFNLEdBQUcsRUFBbEIsRUFBc0I7QUFDdkM7QUFDQSxRQUFJLENBQUMsS0FBS2xCLFdBQUwsQ0FBaUIrRCxrQkFBbEIsSUFBd0MsQ0FBQyxLQUFLL0QsV0FBTCxDQUFpQmdFLG9CQUE5RCxFQUFvRjtBQUNsRixhQUFPLEVBQVA7QUFDRCxLQUpzQyxDQU12Qzs7O0FBQ0EsUUFBSUYsWUFBWSxHQUFHLEtBQUtZLGtCQUFMLENBQXdCbkYsTUFBeEIsQ0FBbkIsQ0FQdUMsQ0FTdkM7QUFDQTs7QUFDQXVFLElBQUFBLFlBQVksR0FBR21CLElBQUksQ0FBQ0MsU0FBTCxDQUFlcEIsWUFBZixDQUFmO0FBQ0FBLElBQUFBLFlBQVksR0FBR3FCLGtCQUFTQyxNQUFULENBQWdCdEIsWUFBaEIsRUFBOEI1QyxNQUE5QixDQUFmO0FBQ0E0QyxJQUFBQSxZQUFZLEdBQUdtQixJQUFJLENBQUNJLEtBQUwsQ0FBV3ZCLFlBQVgsQ0FBZjtBQUVBLFdBQU9BLFlBQVA7QUFDRDtBQUVEO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0UsUUFBTU0sWUFBTixDQUFtQmpFLElBQW5CLEVBQXlCZSxNQUFNLEdBQUcsRUFBbEMsRUFBc0M0QyxZQUFZLEdBQUcsRUFBckQsRUFBeUQ7QUFDdkQ7QUFDQSxRQUFJd0IsSUFBSjs7QUFDQSxRQUFJO0FBQ0ZBLE1BQUFBLElBQUksR0FBRyxNQUFNLEtBQUtDLFFBQUwsQ0FBY3BGLElBQWQsQ0FBYjtBQUNELEtBRkQsQ0FFRSxPQUFPcUYsQ0FBUCxFQUFVO0FBQ1YsYUFBTyxLQUFLdEMsUUFBTCxFQUFQO0FBQ0QsS0FQc0QsQ0FTdkQ7OztBQUNBLFFBQUl1QyxrQkFBa0IsR0FDcEIsT0FBTyxLQUFLekYsV0FBTCxDQUFpQjhELFlBQXhCLEtBQXlDLFVBQXpDLEdBQ0ksS0FBSzlELFdBQUwsQ0FBaUI4RCxZQUFqQixDQUE4QjVDLE1BQTlCLENBREosR0FFSTlDLE1BQU0sQ0FBQ3NILFNBQVAsQ0FBaUI3RSxRQUFqQixDQUEwQjhFLElBQTFCLENBQStCLEtBQUszRixXQUFMLENBQWlCOEQsWUFBaEQsTUFBa0UsaUJBQWxFLEdBQ0UsS0FBSzlELFdBQUwsQ0FBaUI4RCxZQURuQixHQUVFLEVBTFI7O0FBTUEsUUFBSTJCLGtCQUFrQixZQUFZdkQsT0FBbEMsRUFBMkM7QUFDekN1RCxNQUFBQSxrQkFBa0IsR0FBRyxNQUFNQSxrQkFBM0I7QUFDRCxLQWxCc0QsQ0FvQnZEOzs7QUFDQSxVQUFNRyxlQUFlLEdBQUd4SCxNQUFNLENBQUMrRSxNQUFQLENBQWMsRUFBZCxFQUFrQnNDLGtCQUFsQixFQUFzQzNCLFlBQXRDLENBQXhCO0FBQ0EsVUFBTStCLHFCQUFxQixHQUFHekgsTUFBTSxDQUFDK0UsTUFBUCxDQUFjLEVBQWQsRUFBa0JqQyxNQUFsQixFQUEwQjBFLGVBQTFCLENBQTlCO0FBQ0FOLElBQUFBLElBQUksR0FBR0gsa0JBQVNDLE1BQVQsQ0FBZ0JFLElBQWhCLEVBQXNCTyxxQkFBdEIsQ0FBUCxDQXZCdUQsQ0F5QnZEO0FBQ0E7O0FBQ0EsVUFBTUMsT0FBTyxHQUFHMUgsTUFBTSxDQUFDMkgsT0FBUCxDQUFlN0UsTUFBZixFQUF1QjhFLE1BQXZCLENBQThCLENBQUNDLENBQUQsRUFBSUMsQ0FBSixLQUFVO0FBQ3RELFVBQUlBLENBQUMsQ0FBQyxDQUFELENBQUQsS0FBU3RELFNBQWIsRUFBd0I7QUFDdEJxRCxRQUFBQSxDQUFDLENBQUUsR0FBRXhHLHFCQUFzQixHQUFFeUcsQ0FBQyxDQUFDLENBQUQsQ0FBRCxDQUFLQyxXQUFMLEVBQW1CLEVBQS9DLENBQUQsR0FBcURELENBQUMsQ0FBQyxDQUFELENBQXREO0FBQ0Q7O0FBQ0QsYUFBT0QsQ0FBUDtBQUNELEtBTGUsRUFLYixFQUxhLENBQWhCO0FBT0EsV0FBTztBQUFFRyxNQUFBQSxJQUFJLEVBQUVkLElBQVI7QUFBY1EsTUFBQUEsT0FBTyxFQUFFQTtBQUF2QixLQUFQO0FBQ0Q7QUFFRDtBQUNGO0FBQ0E7QUFDQTtBQUNBOzs7QUFDRSxRQUFNckIsWUFBTixDQUFtQnRFLElBQW5CLEVBQXlCO0FBQ3ZCO0FBQ0EsUUFBSW1GLElBQUo7O0FBQ0EsUUFBSTtBQUNGQSxNQUFBQSxJQUFJLEdBQUcsTUFBTSxLQUFLQyxRQUFMLENBQWNwRixJQUFkLENBQWI7QUFDRCxLQUZELENBRUUsT0FBT3FGLENBQVAsRUFBVTtBQUNWLGFBQU8sS0FBS3RDLFFBQUwsRUFBUDtBQUNEOztBQUVELFdBQU87QUFBRWtELE1BQUFBLElBQUksRUFBRWQ7QUFBUixLQUFQO0FBQ0Q7QUFFRDtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDRSxRQUFNQyxRQUFOLENBQWVjLFFBQWYsRUFBeUI7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFNQyxjQUFjLEdBQUduRyxjQUFLb0csU0FBTCxDQUFlRixRQUFmLENBQXZCLENBTHVCLENBT3ZCOzs7QUFDQSxRQUFJLENBQUNDLGNBQWMsQ0FBQ0UsVUFBZixDQUEwQixLQUFLdEcsU0FBL0IsQ0FBTCxFQUFnRDtBQUM5QyxZQUFNUixNQUFNLENBQUNFLHVCQUFiO0FBQ0Q7O0FBRUQsV0FBTyxNQUFNNkcsYUFBR2xCLFFBQUgsQ0FBWWUsY0FBWixFQUE0QixPQUE1QixDQUFiO0FBQ0Q7QUFFRDtBQUNGO0FBQ0E7OztBQUNFaEcsRUFBQUEsZ0JBQWdCLEdBQUc7QUFDakIsUUFBSSxLQUFLTixXQUFMLENBQWlCZ0Usb0JBQWpCLEtBQTBDcEIsU0FBOUMsRUFBeUQ7QUFDdkQ7QUFDRDs7QUFDRCxRQUFJO0FBQ0YsWUFBTThELElBQUksR0FBR0MsT0FBTyxDQUFDeEcsY0FBS0MsT0FBTCxDQUFhLElBQWIsRUFBbUIsS0FBS0osV0FBTCxDQUFpQmdFLG9CQUFwQyxDQUFELENBQXBCOztBQUNBLFdBQUtXLGNBQUwsR0FBc0IrQixJQUF0QjtBQUNELEtBSEQsQ0FHRSxPQUFPbEIsQ0FBUCxFQUFVO0FBQ1YsWUFBTTlGLE1BQU0sQ0FBQ0MscUJBQWI7QUFDRDtBQUNGO0FBRUQ7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNFb0QsRUFBQUEsZ0JBQWdCLENBQUNyQyxNQUFELEVBQVM7QUFDdkIsV0FBT0EsTUFBTSxHQUNUO0FBQ0EsT0FBQ3pCLFVBQVUsQ0FBQ0UsS0FBWixHQUFvQnVCLE1BQU0sQ0FBQ3ZCLEtBRDNCO0FBRUEsT0FBQ0YsVUFBVSxDQUFDQyxPQUFaLEdBQXNCd0IsTUFBTSxDQUFDeEIsT0FGN0I7QUFHQSxPQUFDRCxVQUFVLENBQUNPLGVBQVosR0FBOEJrQixNQUFNLENBQUNXO0FBSHJDLEtBRFMsR0FNVCxFQU5KO0FBT0Q7QUFFRDtBQUNGO0FBQ0E7QUFDQTtBQUNBOzs7QUFDRStCLEVBQUFBLFNBQVMsQ0FBQzNDLEdBQUQsRUFBTTtBQUNiLFVBQU1sQixNQUFNLEdBQ1YsQ0FBQ2tCLEdBQUcsQ0FBQ0csS0FBSixJQUFhLEVBQWQsRUFBa0IzQixVQUFVLENBQUNNLE1BQTdCLEtBQ0EsQ0FBQ2tCLEdBQUcsQ0FBQ1csSUFBSixJQUFZLEVBQWIsRUFBaUJuQyxVQUFVLENBQUNNLE1BQTVCLENBREEsSUFFQSxDQUFDa0IsR0FBRyxDQUFDUyxNQUFKLElBQWMsRUFBZixFQUFtQmpDLFVBQVUsQ0FBQ00sTUFBOUIsQ0FGQSxJQUdBLENBQUNrQixHQUFHLENBQUNxRixPQUFKLElBQWUsRUFBaEIsRUFBb0JyRyxxQkFBcUIsR0FBR1IsVUFBVSxDQUFDTSxNQUF2RCxDQUpGO0FBS0EsV0FBT0EsTUFBUDtBQUNEO0FBRUQ7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNFLFFBQU1zRSxnQkFBTixDQUF1QitDLEdBQXZCLEVBQTRCMUYsTUFBNUIsRUFBb0M7QUFDbEM7QUFDQUEsSUFBQUEsTUFBTSxHQUFHOUMsTUFBTSxDQUFDMkgsT0FBUCxDQUFlN0UsTUFBZixFQUF1QjhFLE1BQXZCLENBQThCLENBQUNDLENBQUQsRUFBSUMsQ0FBSixLQUFVO0FBQy9DLFVBQUlBLENBQUMsQ0FBQyxDQUFELENBQUQsS0FBU3RELFNBQWIsRUFBd0I7QUFDdEJxRCxRQUFBQSxDQUFDLENBQUNDLENBQUMsQ0FBQyxDQUFELENBQUYsQ0FBRCxHQUFVQSxDQUFDLENBQUMsQ0FBRCxDQUFYO0FBQ0Q7O0FBQ0QsYUFBT0QsQ0FBUDtBQUNELEtBTFEsRUFLTixFQUxNLENBQVQsQ0FGa0MsQ0FTbEM7O0FBQ0EsVUFBTVksUUFBUSxHQUFHLElBQUlDLEdBQUosQ0FBUUYsR0FBUixDQUFqQjtBQUNBeEksSUFBQUEsTUFBTSxDQUFDMkgsT0FBUCxDQUFlN0UsTUFBZixFQUF1QjZGLE9BQXZCLENBQStCYixDQUFDLElBQUlXLFFBQVEsQ0FBQ0csWUFBVCxDQUFzQkMsR0FBdEIsQ0FBMEJmLENBQUMsQ0FBQyxDQUFELENBQTNCLEVBQWdDQSxDQUFDLENBQUMsQ0FBRCxDQUFqQyxDQUFwQztBQUNBLFVBQU1nQixjQUFjLEdBQUdMLFFBQVEsQ0FBQ2hHLFFBQVQsRUFBdkIsQ0Faa0MsQ0FjbEM7QUFDQTs7QUFDQSxVQUFNaUYsT0FBTyxHQUFHMUgsTUFBTSxDQUFDMkgsT0FBUCxDQUFlN0UsTUFBZixFQUF1QjhFLE1BQXZCLENBQThCLENBQUNDLENBQUQsRUFBSUMsQ0FBSixLQUFVO0FBQ3RELFVBQUlBLENBQUMsQ0FBQyxDQUFELENBQUQsS0FBU3RELFNBQWIsRUFBd0I7QUFDdEJxRCxRQUFBQSxDQUFDLENBQUUsR0FBRXhHLHFCQUFzQixHQUFFeUcsQ0FBQyxDQUFDLENBQUQsQ0FBRCxDQUFLQyxXQUFMLEVBQW1CLEVBQS9DLENBQUQsR0FBcURELENBQUMsQ0FBQyxDQUFELENBQXREO0FBQ0Q7O0FBQ0QsYUFBT0QsQ0FBUDtBQUNELEtBTGUsRUFLYixFQUxhLENBQWhCO0FBT0EsV0FBTztBQUNMM0QsTUFBQUEsTUFBTSxFQUFFLEdBREg7QUFFTHVFLE1BQUFBLFFBQVEsRUFBRUssY0FGTDtBQUdMcEIsTUFBQUEsT0FBTyxFQUFFQTtBQUhKLEtBQVA7QUFLRDs7QUFFRHhDLEVBQUFBLGVBQWUsQ0FBQzZELElBQUQsRUFBTztBQUNwQixXQUFPaEgsY0FBS2lILElBQUwsQ0FBVSxLQUFLbEgsU0FBZixFQUEwQmlILElBQTFCLENBQVA7QUFDRDs7QUFFRDNELEVBQUFBLGNBQWMsQ0FBQzJELElBQUQsRUFBTzNILGVBQVAsRUFBd0JELE1BQXhCLEVBQWdDO0FBQzVDLFFBQUlxSCxHQUFHLEdBQUdwSCxlQUFWO0FBQ0FvSCxJQUFBQSxHQUFHLElBQUlBLEdBQUcsQ0FBQ3BDLFFBQUosQ0FBYSxHQUFiLElBQW9CLEVBQXBCLEdBQXlCLEdBQWhDO0FBQ0FvQyxJQUFBQSxHQUFHLElBQUksS0FBSzNHLGFBQUwsR0FBcUIsR0FBNUI7QUFDQTJHLElBQUFBLEdBQUcsSUFBSXJILE1BQU0sS0FBS3FELFNBQVgsR0FBdUIsRUFBdkIsR0FBNEJyRCxNQUFNLEdBQUcsR0FBNUM7QUFDQXFILElBQUFBLEdBQUcsSUFBSU8sSUFBUDtBQUNBLFdBQU9QLEdBQVA7QUFDRDs7QUFFRDFELEVBQUFBLFFBQVEsR0FBRztBQUNULFdBQU87QUFDTGtELE1BQUFBLElBQUksRUFBRSxZQUREO0FBRUw5RCxNQUFBQSxNQUFNLEVBQUU7QUFGSCxLQUFQO0FBSUQ7O0FBRUR4QixFQUFBQSxjQUFjLEdBQUc7QUFDZixVQUFNeEIsS0FBSyxHQUFHLElBQUl1QyxLQUFKLEVBQWQ7QUFDQXZDLElBQUFBLEtBQUssQ0FBQ2dELE1BQU4sR0FBZSxHQUFmO0FBQ0FoRCxJQUFBQSxLQUFLLENBQUMrSCxPQUFOLEdBQWdCLGNBQWhCO0FBQ0EsVUFBTS9ILEtBQU47QUFDRDtBQUVEO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFDRWdJLEVBQUFBLFNBQVMsQ0FBQzdHLEdBQUQsRUFBTThHLGNBQWMsR0FBRyxLQUF2QixFQUE4QjtBQUNyQzlHLElBQUFBLEdBQUcsQ0FBQ0MsTUFBSixHQUFhOEcsZ0JBQU9DLEdBQVAsQ0FBV2hILEdBQUcsQ0FBQ1MsTUFBSixDQUFXL0IsS0FBWCxJQUFvQnNCLEdBQUcsQ0FBQ0csS0FBSixDQUFVekIsS0FBekMsQ0FBYjs7QUFDQSxRQUFJLENBQUNzQixHQUFHLENBQUNDLE1BQUwsSUFBZSxDQUFDNkcsY0FBcEIsRUFBb0M7QUFDbEMsV0FBS3pHLGNBQUw7QUFDRDs7QUFDRCxXQUFPb0IsT0FBTyxDQUFDOUIsT0FBUixFQUFQO0FBQ0Q7O0FBRURHLEVBQUFBLGdCQUFnQixHQUFHO0FBQ2pCLFNBQUttSCxLQUFMLENBQ0UsS0FERixFQUVHLElBQUcsS0FBS3pILGFBQWMsc0JBRnpCLEVBR0VRLEdBQUcsSUFBSTtBQUNMLFdBQUs2RyxTQUFMLENBQWU3RyxHQUFmO0FBQ0QsS0FMSCxFQU1FQSxHQUFHLElBQUk7QUFDTCxhQUFPLEtBQUtELFdBQUwsQ0FBaUJDLEdBQWpCLENBQVA7QUFDRCxLQVJIO0FBV0EsU0FBS2lILEtBQUwsQ0FDRSxNQURGLEVBRUcsSUFBRyxLQUFLekgsYUFBYyxtQ0FGekIsRUFHRVEsR0FBRyxJQUFJO0FBQ0wsV0FBSzZHLFNBQUwsQ0FBZTdHLEdBQWY7QUFDRCxLQUxILEVBTUVBLEdBQUcsSUFBSTtBQUNMLGFBQU8sS0FBS1UsdUJBQUwsQ0FBNkJWLEdBQTdCLENBQVA7QUFDRCxLQVJIO0FBV0EsU0FBS2lILEtBQUwsQ0FDRSxLQURGLEVBRUcsSUFBRyxLQUFLekgsYUFBYyxrQkFGekIsRUFHRVEsR0FBRyxJQUFJO0FBQ0wsV0FBSzZHLFNBQUwsQ0FBZTdHLEdBQWY7QUFDRCxLQUxILEVBTUVBLEdBQUcsSUFBSTtBQUNMLGFBQU8sS0FBS25DLGFBQUwsQ0FBbUJtQyxHQUFuQixDQUFQO0FBQ0QsS0FSSDtBQVdBLFNBQUtpSCxLQUFMLENBQ0UsTUFERixFQUVHLElBQUcsS0FBS3pILGFBQWMsZ0NBRnpCLEVBR0VRLEdBQUcsSUFBSTtBQUNMLFdBQUs2RyxTQUFMLENBQWU3RyxHQUFmO0FBQ0QsS0FMSCxFQU1FQSxHQUFHLElBQUk7QUFDTCxhQUFPLEtBQUtnQixhQUFMLENBQW1CaEIsR0FBbkIsQ0FBUDtBQUNELEtBUkg7QUFXQSxTQUFLaUgsS0FBTCxDQUNFLEtBREYsRUFFRyxJQUFHLEtBQUt6SCxhQUFjLGdDQUZ6QixFQUdFUSxHQUFHLElBQUk7QUFDTCxXQUFLNkcsU0FBTCxDQUFlN0csR0FBZjtBQUNELEtBTEgsRUFNRUEsR0FBRyxJQUFJO0FBQ0wsYUFBTyxLQUFLYSxvQkFBTCxDQUEwQmIsR0FBMUIsQ0FBUDtBQUNELEtBUkg7QUFXQSxTQUFLaUgsS0FBTCxDQUNFLEtBREYsRUFFRyxJQUFHLEtBQUt6SCxhQUFjLE9BRnpCLEVBR0VRLEdBQUcsSUFBSTtBQUNMLFdBQUs2RyxTQUFMLENBQWU3RyxHQUFmLEVBQW9CLElBQXBCO0FBQ0QsS0FMSCxFQU1FQSxHQUFHLElBQUk7QUFDTCxhQUFPLEtBQUs0RCxXQUFMLENBQWlCNUQsR0FBakIsQ0FBUDtBQUNELEtBUkg7QUFVRDs7QUFFRGtILEVBQUFBLGFBQWEsR0FBRztBQUNkLFVBQU1DLE1BQU0sR0FBR0MsaUJBQVFDLE1BQVIsRUFBZjs7QUFDQUYsSUFBQUEsTUFBTSxDQUFDRyxHQUFQLENBQVcsR0FBWCxFQUFnQixNQUFNSixhQUFOLEVBQWhCO0FBQ0EsV0FBT0MsTUFBUDtBQUNEOztBQTVvQjRDOzs7ZUErb0JoQy9ILFc7O0FBQ2ZtSSxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZnBJLEVBQUFBLFdBRGU7QUFFZkosRUFBQUEscUJBRmU7QUFHZlIsRUFBQUEsVUFIZTtBQUlmZCxFQUFBQTtBQUplLENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFByb21pc2VSb3V0ZXIgZnJvbSAnLi4vUHJvbWlzZVJvdXRlcic7XG5pbXBvcnQgQ29uZmlnIGZyb20gJy4uL0NvbmZpZyc7XG5pbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgcHJvbWlzZXMgYXMgZnMgfSBmcm9tICdmcyc7XG5pbXBvcnQgeyBQYXJzZSB9IGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IFV0aWxzIGZyb20gJy4uL1V0aWxzJztcbmltcG9ydCBtdXN0YWNoZSBmcm9tICdtdXN0YWNoZSc7XG5pbXBvcnQgUGFnZSBmcm9tICcuLi9QYWdlJztcblxuLy8gQWxsIHBhZ2VzIHdpdGggY3VzdG9tIHBhZ2Uga2V5IGZvciByZWZlcmVuY2UgYW5kIGZpbGUgbmFtZVxuY29uc3QgcGFnZXMgPSBPYmplY3QuZnJlZXplKHtcbiAgcGFzc3dvcmRSZXNldDogbmV3IFBhZ2UoeyBpZDogJ3Bhc3N3b3JkUmVzZXQnLCBkZWZhdWx0RmlsZTogJ3Bhc3N3b3JkX3Jlc2V0Lmh0bWwnIH0pLFxuICBwYXNzd29yZFJlc2V0U3VjY2VzczogbmV3IFBhZ2Uoe1xuICAgIGlkOiAncGFzc3dvcmRSZXNldFN1Y2Nlc3MnLFxuICAgIGRlZmF1bHRGaWxlOiAncGFzc3dvcmRfcmVzZXRfc3VjY2Vzcy5odG1sJyxcbiAgfSksXG4gIHBhc3N3b3JkUmVzZXRMaW5rSW52YWxpZDogbmV3IFBhZ2Uoe1xuICAgIGlkOiAncGFzc3dvcmRSZXNldExpbmtJbnZhbGlkJyxcbiAgICBkZWZhdWx0RmlsZTogJ3Bhc3N3b3JkX3Jlc2V0X2xpbmtfaW52YWxpZC5odG1sJyxcbiAgfSksXG4gIGVtYWlsVmVyaWZpY2F0aW9uU3VjY2VzczogbmV3IFBhZ2Uoe1xuICAgIGlkOiAnZW1haWxWZXJpZmljYXRpb25TdWNjZXNzJyxcbiAgICBkZWZhdWx0RmlsZTogJ2VtYWlsX3ZlcmlmaWNhdGlvbl9zdWNjZXNzLmh0bWwnLFxuICB9KSxcbiAgZW1haWxWZXJpZmljYXRpb25TZW5kRmFpbDogbmV3IFBhZ2Uoe1xuICAgIGlkOiAnZW1haWxWZXJpZmljYXRpb25TZW5kRmFpbCcsXG4gICAgZGVmYXVsdEZpbGU6ICdlbWFpbF92ZXJpZmljYXRpb25fc2VuZF9mYWlsLmh0bWwnLFxuICB9KSxcbiAgZW1haWxWZXJpZmljYXRpb25TZW5kU3VjY2VzczogbmV3IFBhZ2Uoe1xuICAgIGlkOiAnZW1haWxWZXJpZmljYXRpb25TZW5kU3VjY2VzcycsXG4gICAgZGVmYXVsdEZpbGU6ICdlbWFpbF92ZXJpZmljYXRpb25fc2VuZF9zdWNjZXNzLmh0bWwnLFxuICB9KSxcbiAgZW1haWxWZXJpZmljYXRpb25MaW5rSW52YWxpZDogbmV3IFBhZ2Uoe1xuICAgIGlkOiAnZW1haWxWZXJpZmljYXRpb25MaW5rSW52YWxpZCcsXG4gICAgZGVmYXVsdEZpbGU6ICdlbWFpbF92ZXJpZmljYXRpb25fbGlua19pbnZhbGlkLmh0bWwnLFxuICB9KSxcbiAgZW1haWxWZXJpZmljYXRpb25MaW5rRXhwaXJlZDogbmV3IFBhZ2Uoe1xuICAgIGlkOiAnZW1haWxWZXJpZmljYXRpb25MaW5rRXhwaXJlZCcsXG4gICAgZGVmYXVsdEZpbGU6ICdlbWFpbF92ZXJpZmljYXRpb25fbGlua19leHBpcmVkLmh0bWwnLFxuICB9KSxcbn0pO1xuXG4vLyBBbGwgcGFnZSBwYXJhbWV0ZXJzIGZvciByZWZlcmVuY2UgdG8gYmUgdXNlZCBhcyB0ZW1wbGF0ZSBwbGFjZWhvbGRlcnMgb3IgcXVlcnkgcGFyYW1zXG5jb25zdCBwYWdlUGFyYW1zID0gT2JqZWN0LmZyZWV6ZSh7XG4gIGFwcE5hbWU6ICdhcHBOYW1lJyxcbiAgYXBwSWQ6ICdhcHBJZCcsXG4gIHRva2VuOiAndG9rZW4nLFxuICB1c2VybmFtZTogJ3VzZXJuYW1lJyxcbiAgZXJyb3I6ICdlcnJvcicsXG4gIGxvY2FsZTogJ2xvY2FsZScsXG4gIHB1YmxpY1NlcnZlclVybDogJ3B1YmxpY1NlcnZlclVybCcsXG59KTtcblxuLy8gVGhlIGhlYWRlciBwcmVmaXggdG8gYWRkIHBhZ2UgcGFyYW1zIGFzIHJlc3BvbnNlIGhlYWRlcnNcbmNvbnN0IHBhZ2VQYXJhbUhlYWRlclByZWZpeCA9ICd4LXBhcnNlLXBhZ2UtcGFyYW0tJztcblxuLy8gVGhlIGVycm9ycyBiZWluZyB0aHJvd25cbmNvbnN0IGVycm9ycyA9IE9iamVjdC5mcmVlemUoe1xuICBqc29uRmFpbGVkRmlsZUxvYWRpbmc6ICdmYWlsZWQgdG8gbG9hZCBKU09OIGZpbGUnLFxuICBmaWxlT3V0c2lkZUFsbG93ZWRTY29wZTogJ25vdCBhbGxvd2VkIHRvIHJlYWQgZmlsZSBvdXRzaWRlIG9mIHBhZ2VzIGRpcmVjdG9yeScsXG59KTtcblxuZXhwb3J0IGNsYXNzIFBhZ2VzUm91dGVyIGV4dGVuZHMgUHJvbWlzZVJvdXRlciB7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RzIGEgUGFnZXNSb3V0ZXIuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwYWdlcyBUaGUgcGFnZXMgb3B0aW9ucyBmcm9tIHRoZSBQYXJzZSBTZXJ2ZXIgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHBhZ2VzID0ge30pIHtcbiAgICBzdXBlcigpO1xuXG4gICAgLy8gU2V0IGluc3RhbmNlIHByb3BlcnRpZXNcbiAgICB0aGlzLnBhZ2VzQ29uZmlnID0gcGFnZXM7XG4gICAgdGhpcy5wYWdlc0VuZHBvaW50ID0gcGFnZXMucGFnZXNFbmRwb2ludCA/IHBhZ2VzLnBhZ2VzRW5kcG9pbnQgOiAnYXBwcyc7XG4gICAgdGhpcy5wYWdlc1BhdGggPSBwYWdlcy5wYWdlc1BhdGhcbiAgICAgID8gcGF0aC5yZXNvbHZlKCcuLycsIHBhZ2VzLnBhZ2VzUGF0aClcbiAgICAgIDogcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4uLy4uL3B1YmxpYycpO1xuICAgIHRoaXMubG9hZEpzb25SZXNvdXJjZSgpO1xuICAgIHRoaXMubW91bnRQYWdlc1JvdXRlcygpO1xuICB9XG5cbiAgdmVyaWZ5RW1haWwocmVxKSB7XG4gICAgY29uc3QgY29uZmlnID0gcmVxLmNvbmZpZztcbiAgICBjb25zdCB7IHVzZXJuYW1lLCB0b2tlbjogcmF3VG9rZW4gfSA9IHJlcS5xdWVyeTtcbiAgICBjb25zdCB0b2tlbiA9IHJhd1Rva2VuICYmIHR5cGVvZiByYXdUb2tlbiAhPT0gJ3N0cmluZycgPyByYXdUb2tlbi50b1N0cmluZygpIDogcmF3VG9rZW47XG5cbiAgICBpZiAoIWNvbmZpZykge1xuICAgICAgdGhpcy5pbnZhbGlkUmVxdWVzdCgpO1xuICAgIH1cblxuICAgIGlmICghdG9rZW4gfHwgIXVzZXJuYW1lKSB7XG4gICAgICByZXR1cm4gdGhpcy5nb1RvUGFnZShyZXEsIHBhZ2VzLmVtYWlsVmVyaWZpY2F0aW9uTGlua0ludmFsaWQpO1xuICAgIH1cblxuICAgIGNvbnN0IHVzZXJDb250cm9sbGVyID0gY29uZmlnLnVzZXJDb250cm9sbGVyO1xuICAgIHJldHVybiB1c2VyQ29udHJvbGxlci52ZXJpZnlFbWFpbCh1c2VybmFtZSwgdG9rZW4pLnRoZW4oXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBbcGFnZVBhcmFtcy51c2VybmFtZV06IHVzZXJuYW1lLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gdGhpcy5nb1RvUGFnZShyZXEsIHBhZ2VzLmVtYWlsVmVyaWZpY2F0aW9uU3VjY2VzcywgcGFyYW1zKTtcbiAgICAgIH0sXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBbcGFnZVBhcmFtcy51c2VybmFtZV06IHVzZXJuYW1lLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gdGhpcy5nb1RvUGFnZShyZXEsIHBhZ2VzLmVtYWlsVmVyaWZpY2F0aW9uTGlua0V4cGlyZWQsIHBhcmFtcyk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHJlc2VuZFZlcmlmaWNhdGlvbkVtYWlsKHJlcSkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHJlcS5jb25maWc7XG4gICAgY29uc3QgdXNlcm5hbWUgPSByZXEuYm9keS51c2VybmFtZTtcblxuICAgIGlmICghY29uZmlnKSB7XG4gICAgICB0aGlzLmludmFsaWRSZXF1ZXN0KCk7XG4gICAgfVxuXG4gICAgaWYgKCF1c2VybmFtZSkge1xuICAgICAgcmV0dXJuIHRoaXMuZ29Ub1BhZ2UocmVxLCBwYWdlcy5lbWFpbFZlcmlmaWNhdGlvbkxpbmtJbnZhbGlkKTtcbiAgICB9XG5cbiAgICBjb25zdCB1c2VyQ29udHJvbGxlciA9IGNvbmZpZy51c2VyQ29udHJvbGxlcjtcblxuICAgIHJldHVybiB1c2VyQ29udHJvbGxlci5yZXNlbmRWZXJpZmljYXRpb25FbWFpbCh1c2VybmFtZSkudGhlbihcbiAgICAgICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ29Ub1BhZ2UocmVxLCBwYWdlcy5lbWFpbFZlcmlmaWNhdGlvblNlbmRTdWNjZXNzKTtcbiAgICAgIH0sXG4gICAgICAoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmdvVG9QYWdlKHJlcSwgcGFnZXMuZW1haWxWZXJpZmljYXRpb25TZW5kRmFpbCk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHBhc3N3b3JkUmVzZXQocmVxKSB7XG4gICAgY29uc3QgY29uZmlnID0gcmVxLmNvbmZpZztcbiAgICBjb25zdCBwYXJhbXMgPSB7XG4gICAgICBbcGFnZVBhcmFtcy5hcHBJZF06IHJlcS5wYXJhbXMuYXBwSWQsXG4gICAgICBbcGFnZVBhcmFtcy5hcHBOYW1lXTogY29uZmlnLmFwcE5hbWUsXG4gICAgICBbcGFnZVBhcmFtcy50b2tlbl06IHJlcS5xdWVyeS50b2tlbixcbiAgICAgIFtwYWdlUGFyYW1zLnVzZXJuYW1lXTogcmVxLnF1ZXJ5LnVzZXJuYW1lLFxuICAgICAgW3BhZ2VQYXJhbXMucHVibGljU2VydmVyVXJsXTogY29uZmlnLnB1YmxpY1NlcnZlclVSTCxcbiAgICB9O1xuICAgIHJldHVybiB0aGlzLmdvVG9QYWdlKHJlcSwgcGFnZXMucGFzc3dvcmRSZXNldCwgcGFyYW1zKTtcbiAgfVxuXG4gIHJlcXVlc3RSZXNldFBhc3N3b3JkKHJlcSkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHJlcS5jb25maWc7XG5cbiAgICBpZiAoIWNvbmZpZykge1xuICAgICAgdGhpcy5pbnZhbGlkUmVxdWVzdCgpO1xuICAgIH1cblxuICAgIGNvbnN0IHsgdXNlcm5hbWUsIHRva2VuOiByYXdUb2tlbiB9ID0gcmVxLnF1ZXJ5O1xuICAgIGNvbnN0IHRva2VuID0gcmF3VG9rZW4gJiYgdHlwZW9mIHJhd1Rva2VuICE9PSAnc3RyaW5nJyA/IHJhd1Rva2VuLnRvU3RyaW5nKCkgOiByYXdUb2tlbjtcblxuICAgIGlmICghdXNlcm5hbWUgfHwgIXRva2VuKSB7XG4gICAgICByZXR1cm4gdGhpcy5nb1RvUGFnZShyZXEsIHBhZ2VzLnBhc3N3b3JkUmVzZXRMaW5rSW52YWxpZCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbmZpZy51c2VyQ29udHJvbGxlci5jaGVja1Jlc2V0VG9rZW5WYWxpZGl0eSh1c2VybmFtZSwgdG9rZW4pLnRoZW4oXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBbcGFnZVBhcmFtcy50b2tlbl06IHRva2VuLFxuICAgICAgICAgIFtwYWdlUGFyYW1zLnVzZXJuYW1lXTogdXNlcm5hbWUsXG4gICAgICAgICAgW3BhZ2VQYXJhbXMuYXBwSWRdOiBjb25maWcuYXBwbGljYXRpb25JZCxcbiAgICAgICAgICBbcGFnZVBhcmFtcy5hcHBOYW1lXTogY29uZmlnLmFwcE5hbWUsXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiB0aGlzLmdvVG9QYWdlKHJlcSwgcGFnZXMucGFzc3dvcmRSZXNldCwgcGFyYW1zKTtcbiAgICAgIH0sXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICBbcGFnZVBhcmFtcy51c2VybmFtZV06IHVzZXJuYW1lLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gdGhpcy5nb1RvUGFnZShyZXEsIHBhZ2VzLnBhc3N3b3JkUmVzZXRMaW5rSW52YWxpZCwgcGFyYW1zKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgcmVzZXRQYXNzd29yZChyZXEpIHtcbiAgICBjb25zdCBjb25maWcgPSByZXEuY29uZmlnO1xuXG4gICAgaWYgKCFjb25maWcpIHtcbiAgICAgIHRoaXMuaW52YWxpZFJlcXVlc3QoKTtcbiAgICB9XG5cbiAgICBjb25zdCB7IHVzZXJuYW1lLCBuZXdfcGFzc3dvcmQsIHRva2VuOiByYXdUb2tlbiB9ID0gcmVxLmJvZHk7XG4gICAgY29uc3QgdG9rZW4gPSByYXdUb2tlbiAmJiB0eXBlb2YgcmF3VG9rZW4gIT09ICdzdHJpbmcnID8gcmF3VG9rZW4udG9TdHJpbmcoKSA6IHJhd1Rva2VuO1xuXG4gICAgaWYgKCghdXNlcm5hbWUgfHwgIXRva2VuIHx8ICFuZXdfcGFzc3dvcmQpICYmIHJlcS54aHIgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm4gdGhpcy5nb1RvUGFnZShyZXEsIHBhZ2VzLnBhc3N3b3JkUmVzZXRMaW5rSW52YWxpZCk7XG4gICAgfVxuXG4gICAgaWYgKCF1c2VybmFtZSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlVTRVJOQU1FX01JU1NJTkcsICdNaXNzaW5nIHVzZXJuYW1lJyk7XG4gICAgfVxuXG4gICAgaWYgKCF0b2tlbikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9USEVSX0NBVVNFLCAnTWlzc2luZyB0b2tlbicpO1xuICAgIH1cblxuICAgIGlmICghbmV3X3Bhc3N3b3JkKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuUEFTU1dPUkRfTUlTU0lORywgJ01pc3NpbmcgcGFzc3dvcmQnKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29uZmlnLnVzZXJDb250cm9sbGVyXG4gICAgICAudXBkYXRlUGFzc3dvcmQodXNlcm5hbWUsIHRva2VuLCBuZXdfcGFzc3dvcmQpXG4gICAgICAudGhlbihcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyID0+IHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgZXJyLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICApXG4gICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICBpZiAocmVxLnhocikge1xuICAgICAgICAgIGlmIChyZXN1bHQuc3VjY2Vzcykge1xuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgICAgIHN0YXR1czogMjAwLFxuICAgICAgICAgICAgICByZXNwb25zZTogJ1Bhc3N3b3JkIHN1Y2Nlc3NmdWxseSByZXNldCcsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHJlc3VsdC5lcnIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PVEhFUl9DQVVTRSwgYCR7cmVzdWx0LmVycn1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBxdWVyeSA9IHJlc3VsdC5zdWNjZXNzXG4gICAgICAgICAgPyB7XG4gICAgICAgICAgICBbcGFnZVBhcmFtcy51c2VybmFtZV06IHVzZXJuYW1lLFxuICAgICAgICAgIH1cbiAgICAgICAgICA6IHtcbiAgICAgICAgICAgIFtwYWdlUGFyYW1zLnVzZXJuYW1lXTogdXNlcm5hbWUsXG4gICAgICAgICAgICBbcGFnZVBhcmFtcy50b2tlbl06IHRva2VuLFxuICAgICAgICAgICAgW3BhZ2VQYXJhbXMuYXBwSWRdOiBjb25maWcuYXBwbGljYXRpb25JZCxcbiAgICAgICAgICAgIFtwYWdlUGFyYW1zLmVycm9yXTogcmVzdWx0LmVycixcbiAgICAgICAgICAgIFtwYWdlUGFyYW1zLmFwcE5hbWVdOiBjb25maWcuYXBwTmFtZSxcbiAgICAgICAgICB9O1xuICAgICAgICBjb25zdCBwYWdlID0gcmVzdWx0LnN1Y2Nlc3MgPyBwYWdlcy5wYXNzd29yZFJlc2V0U3VjY2VzcyA6IHBhZ2VzLnBhc3N3b3JkUmVzZXQ7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZ29Ub1BhZ2UocmVxLCBwYWdlLCBxdWVyeSwgZmFsc2UpO1xuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBwYWdlIGNvbnRlbnQgaWYgdGhlIHBhZ2UgaXMgYSBsb2NhbCBmaWxlIG9yIHJldHVybnMgYVxuICAgKiByZWRpcmVjdCB0byBhIGN1c3RvbSBwYWdlLlxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxIFRoZSBleHByZXNzIHJlcXVlc3QuXG4gICAqIEBwYXJhbSB7UGFnZX0gcGFnZSBUaGUgcGFnZSB0byBnbyB0by5cbiAgICogQHBhcmFtIHtPYmplY3R9IFtwYXJhbXM9e31dIFRoZSBxdWVyeSBwYXJhbWV0ZXJzIHRvIGF0dGFjaCB0byB0aGUgVVJMIGluIGNhc2Ugb2ZcbiAgICogSFRUUCByZWRpcmVjdCByZXNwb25zZXMgZm9yIFBPU1QgcmVxdWVzdHMsIG9yIHRoZSBwbGFjZWhvbGRlcnMgdG8gZmlsbCBpbnRvXG4gICAqIHRoZSByZXNwb25zZSBjb250ZW50IGluIGNhc2Ugb2YgSFRUUCBjb250ZW50IHJlc3BvbnNlcyBmb3IgR0VUIHJlcXVlc3RzLlxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IFtyZXNwb25zZVR5cGVdIElzIHRydWUgaWYgYSByZWRpcmVjdCByZXNwb25zZSBzaG91bGQgYmUgZm9yY2VkLFxuICAgKiBmYWxzZSBpZiBhIGNvbnRlbnQgcmVzcG9uc2Ugc2hvdWxkIGJlIGZvcmNlZCwgdW5kZWZpbmVkIGlmIHRoZSByZXNwb25zZSB0eXBlXG4gICAqIHNob3VsZCBkZXBlbmQgb24gdGhlIHJlcXVlc3QgdHlwZSBieSBkZWZhdWx0OlxuICAgKiAtIEdFVCByZXF1ZXN0IC0+IGNvbnRlbnQgcmVzcG9uc2VcbiAgICogLSBQT1NUIHJlcXVlc3QgLT4gcmVkaXJlY3QgcmVzcG9uc2UgKFBSRyBwYXR0ZXJuKVxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxPYmplY3Q+fSBUaGUgUHJvbWlzZVJvdXRlciByZXNwb25zZS5cbiAgICovXG4gIGdvVG9QYWdlKHJlcSwgcGFnZSwgcGFyYW1zID0ge30sIHJlc3BvbnNlVHlwZSkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHJlcS5jb25maWc7XG5cbiAgICAvLyBEZXRlcm1pbmUgcmVkaXJlY3QgZWl0aGVyIGJ5IGZvcmNlLCByZXNwb25zZSBzZXR0aW5nIG9yIHJlcXVlc3QgbWV0aG9kXG4gICAgY29uc3QgcmVkaXJlY3QgPSBjb25maWcucGFnZXMuZm9yY2VSZWRpcmVjdFxuICAgICAgPyB0cnVlXG4gICAgICA6IHJlc3BvbnNlVHlwZSAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8gcmVzcG9uc2VUeXBlXG4gICAgICAgIDogcmVxLm1ldGhvZCA9PSAnUE9TVCc7XG5cbiAgICAvLyBJbmNsdWRlIGRlZmF1bHQgcGFyYW1ldGVyc1xuICAgIGNvbnN0IGRlZmF1bHRQYXJhbXMgPSB0aGlzLmdldERlZmF1bHRQYXJhbXMoY29uZmlnKTtcbiAgICBpZiAoT2JqZWN0LnZhbHVlcyhkZWZhdWx0UGFyYW1zKS5pbmNsdWRlcyh1bmRlZmluZWQpKSB7XG4gICAgICByZXR1cm4gdGhpcy5ub3RGb3VuZCgpO1xuICAgIH1cbiAgICBwYXJhbXMgPSBPYmplY3QuYXNzaWduKHBhcmFtcywgZGVmYXVsdFBhcmFtcyk7XG5cbiAgICAvLyBBZGQgbG9jYWxlIHRvIHBhcmFtcyB0byBlbnN1cmUgaXQgaXMgcGFzc2VkIG9uIHdpdGggZXZlcnkgcmVxdWVzdDtcbiAgICAvLyB0aGF0IG1lYW5zLCBvbmNlIGEgbG9jYWxlIGlzIHNldCwgaXQgaXMgcGFzc2VkIG9uIHRvIGFueSBmb2xsb3ctdXAgcGFnZSxcbiAgICAvLyBlLmcuIHJlcXVlc3RfcGFzc3dvcmRfcmVzZXQgLT4gcGFzc3dvcmRfcmVzZXQgLT4gcGFzc3dvcnRfcmVzZXRfc3VjY2Vzc1xuICAgIGNvbnN0IGxvY2FsZSA9IHRoaXMuZ2V0TG9jYWxlKHJlcSk7XG4gICAgcGFyYW1zW3BhZ2VQYXJhbXMubG9jYWxlXSA9IGxvY2FsZTtcblxuICAgIC8vIENvbXBvc2UgcGF0aHMgYW5kIFVSTHNcbiAgICBjb25zdCBkZWZhdWx0RmlsZSA9IHBhZ2UuZGVmYXVsdEZpbGU7XG4gICAgY29uc3QgZGVmYXVsdFBhdGggPSB0aGlzLmRlZmF1bHRQYWdlUGF0aChkZWZhdWx0RmlsZSk7XG4gICAgY29uc3QgZGVmYXVsdFVybCA9IHRoaXMuY29tcG9zZVBhZ2VVcmwoZGVmYXVsdEZpbGUsIGNvbmZpZy5wdWJsaWNTZXJ2ZXJVUkwpO1xuXG4gICAgLy8gSWYgY3VzdG9tIFVSTCBpcyBzZXQgcmVkaXJlY3QgdG8gaXQgd2l0aG91dCBsb2NhbGl6YXRpb25cbiAgICBjb25zdCBjdXN0b21VcmwgPSBjb25maWcucGFnZXMuY3VzdG9tVXJsc1twYWdlLmlkXTtcbiAgICBpZiAoY3VzdG9tVXJsICYmICFVdGlscy5pc1BhdGgoY3VzdG9tVXJsKSkge1xuICAgICAgcmV0dXJuIHRoaXMucmVkaXJlY3RSZXNwb25zZShjdXN0b21VcmwsIHBhcmFtcyk7XG4gICAgfVxuXG4gICAgLy8gR2V0IEpTT04gcGxhY2Vob2xkZXJzXG4gICAgbGV0IHBsYWNlaG9sZGVycyA9IHt9O1xuICAgIGlmIChjb25maWcucGFnZXMuZW5hYmxlTG9jYWxpemF0aW9uICYmIGNvbmZpZy5wYWdlcy5sb2NhbGl6YXRpb25Kc29uUGF0aCkge1xuICAgICAgcGxhY2Vob2xkZXJzID0gdGhpcy5nZXRKc29uUGxhY2Vob2xkZXJzKGxvY2FsZSwgcGFyYW1zKTtcbiAgICB9XG5cbiAgICAvLyBTZW5kIHJlc3BvbnNlXG4gICAgaWYgKGNvbmZpZy5wYWdlcy5lbmFibGVMb2NhbGl6YXRpb24gJiYgbG9jYWxlKSB7XG4gICAgICByZXR1cm4gVXRpbHMuZ2V0TG9jYWxpemVkUGF0aChkZWZhdWx0UGF0aCwgbG9jYWxlKS50aGVuKCh7IHBhdGgsIHN1YmRpciB9KSA9PlxuICAgICAgICByZWRpcmVjdFxuICAgICAgICAgID8gdGhpcy5yZWRpcmVjdFJlc3BvbnNlKFxuICAgICAgICAgICAgdGhpcy5jb21wb3NlUGFnZVVybChkZWZhdWx0RmlsZSwgY29uZmlnLnB1YmxpY1NlcnZlclVSTCwgc3ViZGlyKSxcbiAgICAgICAgICAgIHBhcmFtc1xuICAgICAgICAgIClcbiAgICAgICAgICA6IHRoaXMucGFnZVJlc3BvbnNlKHBhdGgsIHBhcmFtcywgcGxhY2Vob2xkZXJzKVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJlZGlyZWN0XG4gICAgICAgID8gdGhpcy5yZWRpcmVjdFJlc3BvbnNlKGRlZmF1bHRVcmwsIHBhcmFtcylcbiAgICAgICAgOiB0aGlzLnBhZ2VSZXNwb25zZShkZWZhdWx0UGF0aCwgcGFyYW1zLCBwbGFjZWhvbGRlcnMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXJ2ZXMgYSByZXF1ZXN0IHRvIGEgc3RhdGljIHJlc291cmNlIGFuZCBsb2NhbGl6ZXMgdGhlIHJlc291cmNlIGlmIGl0XG4gICAqIGlzIGEgSFRNTCBmaWxlLlxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxIFRoZSByZXF1ZXN0IG9iamVjdC5cbiAgICogQHJldHVybnMge1Byb21pc2U8T2JqZWN0Pn0gVGhlIHJlc3BvbnNlLlxuICAgKi9cbiAgc3RhdGljUm91dGUocmVxKSB7XG4gICAgLy8gR2V0IHJlcXVlc3RlZCBwYXRoXG4gICAgY29uc3QgcmVsYXRpdmVQYXRoID0gcmVxLnBhcmFtc1swXTtcblxuICAgIC8vIFJlc29sdmUgcmVxdWVzdGVkIHBhdGggdG8gYWJzb2x1dGUgcGF0aFxuICAgIGNvbnN0IGFic29sdXRlUGF0aCA9IHBhdGgucmVzb2x2ZSh0aGlzLnBhZ2VzUGF0aCwgcmVsYXRpdmVQYXRoKTtcblxuICAgIC8vIElmIHRoZSByZXF1ZXN0ZWQgZmlsZSBpcyBub3QgYSBIVE1MIGZpbGUgc2VuZCBpdHMgcmF3IGNvbnRlbnRcbiAgICBpZiAoIWFic29sdXRlUGF0aCB8fCAhYWJzb2x1dGVQYXRoLmVuZHNXaXRoKCcuaHRtbCcpKSB7XG4gICAgICByZXR1cm4gdGhpcy5maWxlUmVzcG9uc2UoYWJzb2x1dGVQYXRoKTtcbiAgICB9XG5cbiAgICAvLyBHZXQgcGFyYW1ldGVyc1xuICAgIGNvbnN0IHBhcmFtcyA9IHRoaXMuZ2V0RGVmYXVsdFBhcmFtcyhyZXEuY29uZmlnKTtcbiAgICBjb25zdCBsb2NhbGUgPSB0aGlzLmdldExvY2FsZShyZXEpO1xuICAgIGlmIChsb2NhbGUpIHtcbiAgICAgIHBhcmFtcy5sb2NhbGUgPSBsb2NhbGU7XG4gICAgfVxuXG4gICAgLy8gR2V0IEpTT04gcGxhY2Vob2xkZXJzXG4gICAgY29uc3QgcGxhY2Vob2xkZXJzID0gdGhpcy5nZXRKc29uUGxhY2Vob2xkZXJzKGxvY2FsZSwgcGFyYW1zKTtcblxuICAgIHJldHVybiB0aGlzLnBhZ2VSZXNwb25zZShhYnNvbHV0ZVBhdGgsIHBhcmFtcywgcGxhY2Vob2xkZXJzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgdHJhbnNsYXRpb24gZnJvbSB0aGUgSlNPTiByZXNvdXJjZSBmb3IgYSBnaXZlbiBsb2NhbGUuIFRoZSBKU09OXG4gICAqIHJlc291cmNlIGlzIHBhcnNlZCBhY2NvcmRpbmcgdG8gaTE4bmV4dCBzeW50YXguXG4gICAqXG4gICAqIEV4YW1wbGUgSlNPTiBjb250ZW50OlxuICAgKiBgYGBqc1xuICAgKiAge1xuICAgKiAgICBcImVuXCI6IHsgICAgICAgICAgICAgICAvLyByZXNvdXJjZSBmb3IgbGFuZ3VhZ2UgYGVuYCAoRW5nbGlzaClcbiAgICogICAgICBcInRyYW5zbGF0aW9uXCI6IHtcbiAgICogICAgICAgIFwiZ3JlZXRpbmdcIjogXCJIZWxsbyFcIlxuICAgKiAgICAgIH1cbiAgICogICAgfSxcbiAgICogICAgXCJkZVwiOiB7ICAgICAgICAgICAgICAgLy8gcmVzb3VyY2UgZm9yIGxhbmd1YWdlIGBkZWAgKEdlcm1hbilcbiAgICogICAgICBcInRyYW5zbGF0aW9uXCI6IHtcbiAgICogICAgICAgIFwiZ3JlZXRpbmdcIjogXCJIYWxsbyFcIlxuICAgKiAgICAgIH1cbiAgICogICAgfVxuICAgKiAgICBcImRlLUNIXCI6IHsgICAgICAgICAgICAvLyByZXNvdXJjZSBmb3IgbG9jYWxlIGBkZS1DSGAgKFN3aXNzIEdlcm1hbilcbiAgICogICAgICBcInRyYW5zbGF0aW9uXCI6IHtcbiAgICogICAgICAgIFwiZ3JlZXRpbmdcIjogXCJHcsO8ZXppIVwiXG4gICAqICAgICAgfVxuICAgKiAgICB9XG4gICAqICB9XG4gICAqIGBgYFxuICAgKiBAcGFyYW0ge1N0cmluZ30gbG9jYWxlIFRoZSBsb2NhbGUgdG8gdHJhbnNsYXRlIHRvLlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBUaGUgdHJhbnNsYXRpb24gb3IgYW4gZW1wdHkgb2JqZWN0IGlmIG5vIG1hdGNoaW5nXG4gICAqIHRyYW5zbGF0aW9uIHdhcyBmb3VuZC5cbiAgICovXG4gIGdldEpzb25UcmFuc2xhdGlvbihsb2NhbGUpIHtcbiAgICAvLyBJZiB0aGVyZSBpcyBubyBKU09OIHJlc291cmNlXG4gICAgaWYgKHRoaXMuanNvblBhcmFtZXRlcnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHt9O1xuICAgIH1cblxuICAgIC8vIElmIGxvY2FsZSBpcyBub3Qgc2V0IHVzZSB0aGUgZmFsbGJhY2sgbG9jYWxlXG4gICAgbG9jYWxlID0gbG9jYWxlIHx8IHRoaXMucGFnZXNDb25maWcubG9jYWxpemF0aW9uRmFsbGJhY2tMb2NhbGU7XG5cbiAgICAvLyBHZXQgbWF0Y2hpbmcgdHJhbnNsYXRpb24gYnkgbG9jYWxlLCBsYW5ndWFnZSBvciBmYWxsYmFjayBsb2NhbGVcbiAgICBjb25zdCBsYW5ndWFnZSA9IGxvY2FsZS5zcGxpdCgnLScpWzBdO1xuICAgIGNvbnN0IHJlc291cmNlID1cbiAgICAgIHRoaXMuanNvblBhcmFtZXRlcnNbbG9jYWxlXSB8fFxuICAgICAgdGhpcy5qc29uUGFyYW1ldGVyc1tsYW5ndWFnZV0gfHxcbiAgICAgIHRoaXMuanNvblBhcmFtZXRlcnNbdGhpcy5wYWdlc0NvbmZpZy5sb2NhbGl6YXRpb25GYWxsYmFja0xvY2FsZV0gfHxcbiAgICAgIHt9O1xuICAgIGNvbnN0IHRyYW5zbGF0aW9uID0gcmVzb3VyY2UudHJhbnNsYXRpb24gfHwge307XG4gICAgcmV0dXJuIHRyYW5zbGF0aW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSB0cmFuc2xhdGlvbiBmcm9tIHRoZSBKU09OIHJlc291cmNlIGZvciBhIGdpdmVuIGxvY2FsZSB3aXRoXG4gICAqIHBsYWNlaG9sZGVycyBmaWxsZWQgaW4gYnkgZ2l2ZW4gcGFyYW1ldGVycy5cbiAgICogQHBhcmFtIHtTdHJpbmd9IGxvY2FsZSBUaGUgbG9jYWxlIHRvIHRyYW5zbGF0ZSB0by5cbiAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyBUaGUgcGFyYW1ldGVycyB0byBmaWxsIGludG8gYW55IHBsYWNlaG9sZGVyc1xuICAgKiB3aXRoaW4gdGhlIHRyYW5zbGF0aW9ucy5cbiAgICogQHJldHVybnMge09iamVjdH0gVGhlIHRyYW5zbGF0aW9uIG9yIGFuIGVtcHR5IG9iamVjdCBpZiBubyBtYXRjaGluZ1xuICAgKiB0cmFuc2xhdGlvbiB3YXMgZm91bmQuXG4gICAqL1xuICBnZXRKc29uUGxhY2Vob2xkZXJzKGxvY2FsZSwgcGFyYW1zID0ge30pIHtcbiAgICAvLyBJZiBsb2NhbGl6YXRpb24gaXMgZGlzYWJsZWQgb3IgdGhlcmUgaXMgbm8gSlNPTiByZXNvdXJjZVxuICAgIGlmICghdGhpcy5wYWdlc0NvbmZpZy5lbmFibGVMb2NhbGl6YXRpb24gfHwgIXRoaXMucGFnZXNDb25maWcubG9jYWxpemF0aW9uSnNvblBhdGgpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG5cbiAgICAvLyBHZXQgSlNPTiBwbGFjZWhvbGRlcnNcbiAgICBsZXQgcGxhY2Vob2xkZXJzID0gdGhpcy5nZXRKc29uVHJhbnNsYXRpb24obG9jYWxlKTtcblxuICAgIC8vIEZpbGwgaW4gYW55IHBsYWNlaG9sZGVycyBpbiB0aGUgdHJhbnNsYXRpb247IHRoaXMgYWxsb3dzIGEgdHJhbnNsYXRpb25cbiAgICAvLyB0byBjb250YWluIGRlZmF1bHQgcGxhY2Vob2xkZXJzIGxpa2Uge3thcHBOYW1lfX0gd2hpY2ggYXJlIGZpbGxlZCBoZXJlXG4gICAgcGxhY2Vob2xkZXJzID0gSlNPTi5zdHJpbmdpZnkocGxhY2Vob2xkZXJzKTtcbiAgICBwbGFjZWhvbGRlcnMgPSBtdXN0YWNoZS5yZW5kZXIocGxhY2Vob2xkZXJzLCBwYXJhbXMpO1xuICAgIHBsYWNlaG9sZGVycyA9IEpTT04ucGFyc2UocGxhY2Vob2xkZXJzKTtcblxuICAgIHJldHVybiBwbGFjZWhvbGRlcnM7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHJlc3BvbnNlIHdpdGggZmlsZSBjb250ZW50LlxuICAgKiBAcGFyYW0ge1N0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgZmlsZSB0byByZXR1cm4uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbcGFyYW1zPXt9XSBUaGUgcGFyYW1ldGVycyB0byBiZSBpbmNsdWRlZCBpbiB0aGUgcmVzcG9uc2VcbiAgICogaGVhZGVyLiBUaGVzZSB3aWxsIGFsc28gYmUgdXNlZCB0byBmaWxsIHBsYWNlaG9sZGVycy5cbiAgICogQHBhcmFtIHtPYmplY3R9IFtwbGFjZWhvbGRlcnM9e31dIFRoZSBwbGFjZWhvbGRlcnMgdG8gZmlsbCBpbiB0aGUgY29udGVudC5cbiAgICogVGhlc2Ugd2lsbCBub3QgYmUgaW5jbHVkZWQgaW4gdGhlIHJlc3BvbnNlIGhlYWRlci5cbiAgICogQHJldHVybnMge09iamVjdH0gVGhlIFByb21pc2UgUm91dGVyIHJlc3BvbnNlLlxuICAgKi9cbiAgYXN5bmMgcGFnZVJlc3BvbnNlKHBhdGgsIHBhcmFtcyA9IHt9LCBwbGFjZWhvbGRlcnMgPSB7fSkge1xuICAgIC8vIEdldCBmaWxlIGNvbnRlbnRcbiAgICBsZXQgZGF0YTtcbiAgICB0cnkge1xuICAgICAgZGF0YSA9IGF3YWl0IHRoaXMucmVhZEZpbGUocGF0aCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIHRoaXMubm90Rm91bmQoKTtcbiAgICB9XG5cbiAgICAvLyBHZXQgY29uZmlnIHBsYWNlaG9sZGVyczsgY2FuIGJlIGFuIG9iamVjdCwgYSBmdW5jdGlvbiBvciBhbiBhc3luYyBmdW5jdGlvblxuICAgIGxldCBjb25maWdQbGFjZWhvbGRlcnMgPVxuICAgICAgdHlwZW9mIHRoaXMucGFnZXNDb25maWcucGxhY2Vob2xkZXJzID09PSAnZnVuY3Rpb24nXG4gICAgICAgID8gdGhpcy5wYWdlc0NvbmZpZy5wbGFjZWhvbGRlcnMocGFyYW1zKVxuICAgICAgICA6IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0aGlzLnBhZ2VzQ29uZmlnLnBsYWNlaG9sZGVycykgPT09ICdbb2JqZWN0IE9iamVjdF0nXG4gICAgICAgICAgPyB0aGlzLnBhZ2VzQ29uZmlnLnBsYWNlaG9sZGVyc1xuICAgICAgICAgIDoge307XG4gICAgaWYgKGNvbmZpZ1BsYWNlaG9sZGVycyBpbnN0YW5jZW9mIFByb21pc2UpIHtcbiAgICAgIGNvbmZpZ1BsYWNlaG9sZGVycyA9IGF3YWl0IGNvbmZpZ1BsYWNlaG9sZGVycztcbiAgICB9XG5cbiAgICAvLyBGaWxsIHBsYWNlaG9sZGVyc1xuICAgIGNvbnN0IGFsbFBsYWNlaG9sZGVycyA9IE9iamVjdC5hc3NpZ24oe30sIGNvbmZpZ1BsYWNlaG9sZGVycywgcGxhY2Vob2xkZXJzKTtcbiAgICBjb25zdCBwYXJhbXNBbmRQbGFjZWhvbGRlcnMgPSBPYmplY3QuYXNzaWduKHt9LCBwYXJhbXMsIGFsbFBsYWNlaG9sZGVycyk7XG4gICAgZGF0YSA9IG11c3RhY2hlLnJlbmRlcihkYXRhLCBwYXJhbXNBbmRQbGFjZWhvbGRlcnMpO1xuXG4gICAgLy8gQWRkIHBsYWNlaG9sZGVycyBpbiBoZWFkZXIgdG8gYWxsb3cgcGFyc2luZyBmb3IgcHJvZ3JhbW1hdGljIHVzZVxuICAgIC8vIG9mIHJlc3BvbnNlLCBpbnN0ZWFkIG9mIGhhdmluZyB0byBwYXJzZSB0aGUgSFRNTCBjb250ZW50LlxuICAgIGNvbnN0IGhlYWRlcnMgPSBPYmplY3QuZW50cmllcyhwYXJhbXMpLnJlZHVjZSgobSwgcCkgPT4ge1xuICAgICAgaWYgKHBbMV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBtW2Ake3BhZ2VQYXJhbUhlYWRlclByZWZpeH0ke3BbMF0udG9Mb3dlckNhc2UoKX1gXSA9IHBbMV07XG4gICAgICB9XG4gICAgICByZXR1cm4gbTtcbiAgICB9LCB7fSk7XG5cbiAgICByZXR1cm4geyB0ZXh0OiBkYXRhLCBoZWFkZXJzOiBoZWFkZXJzIH07XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHJlc3BvbnNlIHdpdGggZmlsZSBjb250ZW50LlxuICAgKiBAcGFyYW0ge1N0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgZmlsZSB0byByZXR1cm4uXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFRoZSBQcm9taXNlUm91dGVyIHJlc3BvbnNlLlxuICAgKi9cbiAgYXN5bmMgZmlsZVJlc3BvbnNlKHBhdGgpIHtcbiAgICAvLyBHZXQgZmlsZSBjb250ZW50XG4gICAgbGV0IGRhdGE7XG4gICAgdHJ5IHtcbiAgICAgIGRhdGEgPSBhd2FpdCB0aGlzLnJlYWRGaWxlKHBhdGgpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiB0aGlzLm5vdEZvdW5kKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgdGV4dDogZGF0YSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYWRzIGFuZCByZXR1cm5zIHRoZSBjb250ZW50IG9mIGEgZmlsZSBhdCBhIGdpdmVuIHBhdGguIEZpbGUgcmVhZGluZyB0b1xuICAgKiBzZXJ2ZSBjb250ZW50IG9uIHRoZSBzdGF0aWMgcm91dGUgaXMgb25seSBhbGxvd2VkIGZyb20gdGhlIHBhZ2VzXG4gICAqIGRpcmVjdG9yeSBvbiBkb3dud2FyZHMuXG4gICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAqICoqV0FSTklORzoqKiBBbGwgZmlsZSByZWFkcyBpbiB0aGUgUGFnZXNSb3V0ZXIgbXVzdCBiZSBleGVjdXRlZCBieSB0aGlzXG4gICAqIHdyYXBwZXIgYmVjYXVzZSBpdCBhbHNvIGRldGVjdHMgYW5kIHByZXZlbnRzIGNvbW1vbiBleHBsb2l0cy5cbiAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICogQHBhcmFtIHtTdHJpbmd9IGZpbGVQYXRoIFRoZSBwYXRoIHRvIHRoZSBmaWxlIHRvIHJlYWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFN0cmluZz59IFRoZSBmaWxlIGNvbnRlbnQuXG4gICAqL1xuICBhc3luYyByZWFkRmlsZShmaWxlUGF0aCkge1xuICAgIC8vIE5vcm1hbGl6ZSBwYXRoIHRvIHByZXZlbnQgaXQgZnJvbSBjb250YWluaW5nIGFueSBkaXJlY3RvcnkgY2hhbmdpbmdcbiAgICAvLyBVTklYIHBhdHRlcm5zIHdoaWNoIGNvdWxkIGV4cG9zZSB0aGUgd2hvbGUgZmlsZSBzeXN0ZW0sIGUuZy5cbiAgICAvLyBgaHR0cDovL2V4YW1wbGUuY29tL3BhcnNlL2FwcHMvLi4vZmlsZS50eHRgIHJlcXVlc3RzIGEgZmlsZSBvdXRzaWRlXG4gICAgLy8gb2YgdGhlIHBhZ2VzIGRpcmVjdG9yeSBzY29wZS5cbiAgICBjb25zdCBub3JtYWxpemVkUGF0aCA9IHBhdGgubm9ybWFsaXplKGZpbGVQYXRoKTtcblxuICAgIC8vIEFib3J0IGlmIHRoZSBwYXRoIGlzIG91dHNpZGUgb2YgdGhlIHBhdGggZGlyZWN0b3J5IHNjb3BlXG4gICAgaWYgKCFub3JtYWxpemVkUGF0aC5zdGFydHNXaXRoKHRoaXMucGFnZXNQYXRoKSkge1xuICAgICAgdGhyb3cgZXJyb3JzLmZpbGVPdXRzaWRlQWxsb3dlZFNjb3BlO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCBmcy5yZWFkRmlsZShub3JtYWxpemVkUGF0aCwgJ3V0Zi04Jyk7XG4gIH1cblxuICAvKipcbiAgICogTG9hZHMgYSBsYW5ndWFnZSByZXNvdXJjZSBKU09OIGZpbGUgdGhhdCBpcyB1c2VkIGZvciB0cmFuc2xhdGlvbnMuXG4gICAqL1xuICBsb2FkSnNvblJlc291cmNlKCkge1xuICAgIGlmICh0aGlzLnBhZ2VzQ29uZmlnLmxvY2FsaXphdGlvbkpzb25QYXRoID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGpzb24gPSByZXF1aXJlKHBhdGgucmVzb2x2ZSgnLi8nLCB0aGlzLnBhZ2VzQ29uZmlnLmxvY2FsaXphdGlvbkpzb25QYXRoKSk7XG4gICAgICB0aGlzLmpzb25QYXJhbWV0ZXJzID0ganNvbjtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBlcnJvcnMuanNvbkZhaWxlZEZpbGVMb2FkaW5nO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBFeHRyYWN0cyBhbmQgcmV0dXJucyB0aGUgcGFnZSBkZWZhdWx0IHBhcmFtZXRlcnMgZnJvbSB0aGUgUGFyc2UgU2VydmVyXG4gICAqIGNvbmZpZ3VyYXRpb24uIFRoZXNlIHBhcmFtZXRlcnMgYXJlIG1hZGUgYWNjZXNzaWJsZSBpbiBldmVyeSBwYWdlIHNlcnZlZFxuICAgKiBieSB0aGlzIHJvdXRlci5cbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyBUaGUgUGFyc2UgU2VydmVyIGNvbmZpZ3VyYXRpb24uXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFRoZSBkZWZhdWx0IHBhcmFtZXRlcnMuXG4gICAqL1xuICBnZXREZWZhdWx0UGFyYW1zKGNvbmZpZykge1xuICAgIHJldHVybiBjb25maWdcbiAgICAgID8ge1xuICAgICAgICBbcGFnZVBhcmFtcy5hcHBJZF06IGNvbmZpZy5hcHBJZCxcbiAgICAgICAgW3BhZ2VQYXJhbXMuYXBwTmFtZV06IGNvbmZpZy5hcHBOYW1lLFxuICAgICAgICBbcGFnZVBhcmFtcy5wdWJsaWNTZXJ2ZXJVcmxdOiBjb25maWcucHVibGljU2VydmVyVVJMLFxuICAgICAgfVxuICAgICAgOiB7fTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHRyYWN0cyBhbmQgcmV0dXJucyB0aGUgbG9jYWxlIGZyb20gYW4gZXhwcmVzcyByZXF1ZXN0LlxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxIFRoZSBleHByZXNzIHJlcXVlc3QuXG4gICAqIEByZXR1cm5zIHtTdHJpbmd8dW5kZWZpbmVkfSBUaGUgbG9jYWxlLCBvciB1bmRlZmluZWQgaWYgbm8gbG9jYWxlIHdhcyBzZXQuXG4gICAqL1xuICBnZXRMb2NhbGUocmVxKSB7XG4gICAgY29uc3QgbG9jYWxlID1cbiAgICAgIChyZXEucXVlcnkgfHwge30pW3BhZ2VQYXJhbXMubG9jYWxlXSB8fFxuICAgICAgKHJlcS5ib2R5IHx8IHt9KVtwYWdlUGFyYW1zLmxvY2FsZV0gfHxcbiAgICAgIChyZXEucGFyYW1zIHx8IHt9KVtwYWdlUGFyYW1zLmxvY2FsZV0gfHxcbiAgICAgIChyZXEuaGVhZGVycyB8fCB7fSlbcGFnZVBhcmFtSGVhZGVyUHJlZml4ICsgcGFnZVBhcmFtcy5sb2NhbGVdO1xuICAgIHJldHVybiBsb2NhbGU7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIHJlc3BvbnNlIHdpdGggaHR0cCByZWRpcmV0LlxuICAgKiBAcGFyYW0ge09iamVjdH0gcmVxIFRoZSBleHByZXNzIHJlcXVlc3QuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBmaWxlIHRvIHJldHVybi5cbiAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtcyBUaGUgcXVlcnkgcGFyYW1ldGVycyB0byBpbmNsdWRlLlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBUaGUgUHJvbWlzZSBSb3V0ZXIgcmVzcG9uc2UuXG4gICAqL1xuICBhc3luYyByZWRpcmVjdFJlc3BvbnNlKHVybCwgcGFyYW1zKSB7XG4gICAgLy8gUmVtb3ZlIGFueSBwYXJhbWV0ZXJzIHdpdGggdW5kZWZpbmVkIHZhbHVlXG4gICAgcGFyYW1zID0gT2JqZWN0LmVudHJpZXMocGFyYW1zKS5yZWR1Y2UoKG0sIHApID0+IHtcbiAgICAgIGlmIChwWzFdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbVtwWzBdXSA9IHBbMV07XG4gICAgICB9XG4gICAgICByZXR1cm4gbTtcbiAgICB9LCB7fSk7XG5cbiAgICAvLyBDb21wb3NlIFVSTCB3aXRoIHBhcmFtZXRlcnMgaW4gcXVlcnlcbiAgICBjb25zdCBsb2NhdGlvbiA9IG5ldyBVUkwodXJsKTtcbiAgICBPYmplY3QuZW50cmllcyhwYXJhbXMpLmZvckVhY2gocCA9PiBsb2NhdGlvbi5zZWFyY2hQYXJhbXMuc2V0KHBbMF0sIHBbMV0pKTtcbiAgICBjb25zdCBsb2NhdGlvblN0cmluZyA9IGxvY2F0aW9uLnRvU3RyaW5nKCk7XG5cbiAgICAvLyBBZGQgcGFyYW1ldGVycyB0byBoZWFkZXIgdG8gYWxsb3cgcGFyc2luZyBmb3IgcHJvZ3JhbW1hdGljIHVzZVxuICAgIC8vIG9mIHJlc3BvbnNlLCBpbnN0ZWFkIG9mIGhhdmluZyB0byBwYXJzZSB0aGUgSFRNTCBjb250ZW50LlxuICAgIGNvbnN0IGhlYWRlcnMgPSBPYmplY3QuZW50cmllcyhwYXJhbXMpLnJlZHVjZSgobSwgcCkgPT4ge1xuICAgICAgaWYgKHBbMV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBtW2Ake3BhZ2VQYXJhbUhlYWRlclByZWZpeH0ke3BbMF0udG9Mb3dlckNhc2UoKX1gXSA9IHBbMV07XG4gICAgICB9XG4gICAgICByZXR1cm4gbTtcbiAgICB9LCB7fSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiAzMDMsXG4gICAgICBsb2NhdGlvbjogbG9jYXRpb25TdHJpbmcsXG4gICAgICBoZWFkZXJzOiBoZWFkZXJzLFxuICAgIH07XG4gIH1cblxuICBkZWZhdWx0UGFnZVBhdGgoZmlsZSkge1xuICAgIHJldHVybiBwYXRoLmpvaW4odGhpcy5wYWdlc1BhdGgsIGZpbGUpO1xuICB9XG5cbiAgY29tcG9zZVBhZ2VVcmwoZmlsZSwgcHVibGljU2VydmVyVXJsLCBsb2NhbGUpIHtcbiAgICBsZXQgdXJsID0gcHVibGljU2VydmVyVXJsO1xuICAgIHVybCArPSB1cmwuZW5kc1dpdGgoJy8nKSA/ICcnIDogJy8nO1xuICAgIHVybCArPSB0aGlzLnBhZ2VzRW5kcG9pbnQgKyAnLyc7XG4gICAgdXJsICs9IGxvY2FsZSA9PT0gdW5kZWZpbmVkID8gJycgOiBsb2NhbGUgKyAnLyc7XG4gICAgdXJsICs9IGZpbGU7XG4gICAgcmV0dXJuIHVybDtcbiAgfVxuXG4gIG5vdEZvdW5kKCkge1xuICAgIHJldHVybiB7XG4gICAgICB0ZXh0OiAnTm90IGZvdW5kLicsXG4gICAgICBzdGF0dXM6IDQwNCxcbiAgICB9O1xuICB9XG5cbiAgaW52YWxpZFJlcXVlc3QoKSB7XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoKTtcbiAgICBlcnJvci5zdGF0dXMgPSA0MDM7XG4gICAgZXJyb3IubWVzc2FnZSA9ICd1bmF1dGhvcml6ZWQnO1xuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIFBhcnNlIFNlcnZlciBjb25maWd1cmF0aW9uIGluIHRoZSByZXF1ZXN0IG9iamVjdCB0byBtYWtlIGl0XG4gICAqIGVhc2lseSBhY2Nlc3NpYmxlIHRocm91Z2h0b3V0IHJlcXVlc3QgcHJvY2Vzc2luZy5cbiAgICogQHBhcmFtIHtPYmplY3R9IHJlcSBUaGUgcmVxdWVzdC5cbiAgICogQHBhcmFtIHtCb29sZWFufSBmYWlsR3JhY2VmdWxseSBJcyB0cnVlIGlmIGZhaWxpbmcgdG8gc2V0IHRoZSBjb25maWcgc2hvdWxkXG4gICAqIG5vdCByZXN1bHQgaW4gYW4gaW52YWxpZCByZXF1ZXN0IHJlc3BvbnNlLiBEZWZhdWx0IGlzIGBmYWxzZWAuXG4gICAqL1xuICBzZXRDb25maWcocmVxLCBmYWlsR3JhY2VmdWxseSA9IGZhbHNlKSB7XG4gICAgcmVxLmNvbmZpZyA9IENvbmZpZy5nZXQocmVxLnBhcmFtcy5hcHBJZCB8fCByZXEucXVlcnkuYXBwSWQpO1xuICAgIGlmICghcmVxLmNvbmZpZyAmJiAhZmFpbEdyYWNlZnVsbHkpIHtcbiAgICAgIHRoaXMuaW52YWxpZFJlcXVlc3QoKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgbW91bnRQYWdlc1JvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICBgLyR7dGhpcy5wYWdlc0VuZHBvaW50fS86YXBwSWQvdmVyaWZ5X2VtYWlsYCxcbiAgICAgIHJlcSA9PiB7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKHJlcSk7XG4gICAgICB9LFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMudmVyaWZ5RW1haWwocmVxKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdQT1NUJyxcbiAgICAgIGAvJHt0aGlzLnBhZ2VzRW5kcG9pbnR9LzphcHBJZC9yZXNlbmRfdmVyaWZpY2F0aW9uX2VtYWlsYCxcbiAgICAgIHJlcSA9PiB7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKHJlcSk7XG4gICAgICB9LFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVzZW5kVmVyaWZpY2F0aW9uRW1haWwocmVxKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdHRVQnLFxuICAgICAgYC8ke3RoaXMucGFnZXNFbmRwb2ludH0vY2hvb3NlX3Bhc3N3b3JkYCxcbiAgICAgIHJlcSA9PiB7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKHJlcSk7XG4gICAgICB9LFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGFzc3dvcmRSZXNldChyZXEpO1xuICAgICAgfVxuICAgICk7XG5cbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ1BPU1QnLFxuICAgICAgYC8ke3RoaXMucGFnZXNFbmRwb2ludH0vOmFwcElkL3JlcXVlc3RfcGFzc3dvcmRfcmVzZXRgLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgdGhpcy5zZXRDb25maWcocmVxKTtcbiAgICAgIH0sXG4gICAgICByZXEgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXNldFBhc3N3b3JkKHJlcSk7XG4gICAgICB9XG4gICAgKTtcblxuICAgIHRoaXMucm91dGUoXG4gICAgICAnR0VUJyxcbiAgICAgIGAvJHt0aGlzLnBhZ2VzRW5kcG9pbnR9LzphcHBJZC9yZXF1ZXN0X3Bhc3N3b3JkX3Jlc2V0YCxcbiAgICAgIHJlcSA9PiB7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKHJlcSk7XG4gICAgICB9LFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVxdWVzdFJlc2V0UGFzc3dvcmQocmVxKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdHRVQnLFxuICAgICAgYC8ke3RoaXMucGFnZXNFbmRwb2ludH0vKCopP2AsXG4gICAgICByZXEgPT4ge1xuICAgICAgICB0aGlzLnNldENvbmZpZyhyZXEsIHRydWUpO1xuICAgICAgfSxcbiAgICAgIHJlcSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXRpY1JvdXRlKHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIGV4cHJlc3NSb3V0ZXIoKSB7XG4gICAgY29uc3Qgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcbiAgICByb3V0ZXIudXNlKCcvJywgc3VwZXIuZXhwcmVzc1JvdXRlcigpKTtcbiAgICByZXR1cm4gcm91dGVyO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFBhZ2VzUm91dGVyO1xubW9kdWxlLmV4cG9ydHMgPSB7XG4gIFBhZ2VzUm91dGVyLFxuICBwYWdlUGFyYW1IZWFkZXJQcmVmaXgsXG4gIHBhZ2VQYXJhbXMsXG4gIHBhZ2VzLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/PublicAPIRouter.js b/lib/Routers/PublicAPIRouter.js deleted file mode 100644 index 1ee21b99b2..0000000000 --- a/lib/Routers/PublicAPIRouter.js +++ /dev/null @@ -1,322 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.PublicAPIRouter = void 0; - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var _Config = _interopRequireDefault(require("../Config")); - -var _express = _interopRequireDefault(require("express")); - -var _path = _interopRequireDefault(require("path")); - -var _fs = _interopRequireDefault(require("fs")); - -var _querystring = _interopRequireDefault(require("querystring")); - -var _node = require("parse/node"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const public_html = _path.default.resolve(__dirname, '../../public_html'); - -const views = _path.default.resolve(__dirname, '../../views'); - -class PublicAPIRouter extends _PromiseRouter.default { - verifyEmail(req) { - const { - username, - token: rawToken - } = req.query; - const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken; - const appId = req.params.appId; - - const config = _Config.default.get(appId); - - if (!config) { - this.invalidRequest(); - } - - if (!config.publicServerURL) { - return this.missingPublicServerURL(); - } - - if (!token || !username) { - return this.invalidLink(req); - } - - const userController = config.userController; - return userController.verifyEmail(username, token).then(() => { - const params = _querystring.default.stringify({ - username - }); - - return Promise.resolve({ - status: 302, - location: `${config.verifyEmailSuccessURL}?${params}` - }); - }, () => { - return this.invalidVerificationLink(req); - }); - } - - resendVerificationEmail(req) { - const username = req.body.username; - const appId = req.params.appId; - - const config = _Config.default.get(appId); - - if (!config) { - this.invalidRequest(); - } - - if (!config.publicServerURL) { - return this.missingPublicServerURL(); - } - - if (!username) { - return this.invalidLink(req); - } - - const userController = config.userController; - return userController.resendVerificationEmail(username).then(() => { - return Promise.resolve({ - status: 302, - location: `${config.linkSendSuccessURL}` - }); - }, () => { - return Promise.resolve({ - status: 302, - location: `${config.linkSendFailURL}` - }); - }); - } - - changePassword(req) { - return new Promise((resolve, reject) => { - const config = _Config.default.get(req.query.id); - - if (!config) { - this.invalidRequest(); - } - - if (!config.publicServerURL) { - return resolve({ - status: 404, - text: 'Not found.' - }); - } // Should we keep the file in memory or leave like that? - - - _fs.default.readFile(_path.default.resolve(views, 'choose_password'), 'utf-8', (err, data) => { - if (err) { - return reject(err); - } - - data = data.replace('PARSE_SERVER_URL', `'${config.publicServerURL}'`); - resolve({ - text: data - }); - }); - }); - } - - requestResetPassword(req) { - const config = req.config; - - if (!config) { - this.invalidRequest(); - } - - if (!config.publicServerURL) { - return this.missingPublicServerURL(); - } - - const { - username, - token: rawToken - } = req.query; - const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken; - - if (!username || !token) { - return this.invalidLink(req); - } - - return config.userController.checkResetTokenValidity(username, token).then(() => { - const params = _querystring.default.stringify({ - token, - id: config.applicationId, - username, - app: config.appName - }); - - return Promise.resolve({ - status: 302, - location: `${config.choosePasswordURL}?${params}` - }); - }, () => { - return this.invalidLink(req); - }); - } - - resetPassword(req) { - const config = req.config; - - if (!config) { - this.invalidRequest(); - } - - if (!config.publicServerURL) { - return this.missingPublicServerURL(); - } - - const { - username, - new_password, - token: rawToken - } = req.body; - const token = rawToken && typeof rawToken !== 'string' ? rawToken.toString() : rawToken; - - if ((!username || !token || !new_password) && req.xhr === false) { - return this.invalidLink(req); - } - - if (!username) { - throw new _node.Parse.Error(_node.Parse.Error.USERNAME_MISSING, 'Missing username'); - } - - if (!token) { - throw new _node.Parse.Error(_node.Parse.Error.OTHER_CAUSE, 'Missing token'); - } - - if (!new_password) { - throw new _node.Parse.Error(_node.Parse.Error.PASSWORD_MISSING, 'Missing password'); - } - - return config.userController.updatePassword(username, token, new_password).then(() => { - return Promise.resolve({ - success: true - }); - }, err => { - return Promise.resolve({ - success: false, - err - }); - }).then(result => { - const params = _querystring.default.stringify({ - username: username, - token: token, - id: config.applicationId, - error: result.err, - app: config.appName - }); - - if (req.xhr) { - if (result.success) { - return Promise.resolve({ - status: 200, - response: 'Password successfully reset' - }); - } - - if (result.err) { - throw new _node.Parse.Error(_node.Parse.Error.OTHER_CAUSE, `${result.err}`); - } - } - - const encodedUsername = encodeURIComponent(username); - const location = result.success ? `${config.passwordResetSuccessURL}?username=${encodedUsername}` : `${config.choosePasswordURL}?${params}`; - return Promise.resolve({ - status: 302, - location - }); - }); - } - - invalidLink(req) { - return Promise.resolve({ - status: 302, - location: req.config.invalidLinkURL - }); - } - - invalidVerificationLink(req) { - const config = req.config; - - if (req.query.username && req.params.appId) { - const params = _querystring.default.stringify({ - username: req.query.username, - appId: req.params.appId - }); - - return Promise.resolve({ - status: 302, - location: `${config.invalidVerificationLinkURL}?${params}` - }); - } else { - return this.invalidLink(req); - } - } - - missingPublicServerURL() { - return Promise.resolve({ - text: 'Not found.', - status: 404 - }); - } - - invalidRequest() { - const error = new Error(); - error.status = 403; - error.message = 'unauthorized'; - throw error; - } - - setConfig(req) { - req.config = _Config.default.get(req.params.appId); - return Promise.resolve(); - } - - mountRoutes() { - this.route('GET', '/apps/:appId/verify_email', req => { - this.setConfig(req); - }, req => { - return this.verifyEmail(req); - }); - this.route('POST', '/apps/:appId/resend_verification_email', req => { - this.setConfig(req); - }, req => { - return this.resendVerificationEmail(req); - }); - this.route('GET', '/apps/choose_password', req => { - return this.changePassword(req); - }); - this.route('POST', '/apps/:appId/request_password_reset', req => { - this.setConfig(req); - }, req => { - return this.resetPassword(req); - }); - this.route('GET', '/apps/:appId/request_password_reset', req => { - this.setConfig(req); - }, req => { - return this.requestResetPassword(req); - }); - } - - expressRouter() { - const router = _express.default.Router(); - - router.use('/apps', _express.default.static(public_html)); - router.use('/', super.expressRouter()); - return router; - } - -} - -exports.PublicAPIRouter = PublicAPIRouter; -var _default = PublicAPIRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1B1YmxpY0FQSVJvdXRlci5qcyJdLCJuYW1lcyI6WyJwdWJsaWNfaHRtbCIsInBhdGgiLCJyZXNvbHZlIiwiX19kaXJuYW1lIiwidmlld3MiLCJQdWJsaWNBUElSb3V0ZXIiLCJQcm9taXNlUm91dGVyIiwidmVyaWZ5RW1haWwiLCJyZXEiLCJ1c2VybmFtZSIsInRva2VuIiwicmF3VG9rZW4iLCJxdWVyeSIsInRvU3RyaW5nIiwiYXBwSWQiLCJwYXJhbXMiLCJjb25maWciLCJDb25maWciLCJnZXQiLCJpbnZhbGlkUmVxdWVzdCIsInB1YmxpY1NlcnZlclVSTCIsIm1pc3NpbmdQdWJsaWNTZXJ2ZXJVUkwiLCJpbnZhbGlkTGluayIsInVzZXJDb250cm9sbGVyIiwidGhlbiIsInFzIiwic3RyaW5naWZ5IiwiUHJvbWlzZSIsInN0YXR1cyIsImxvY2F0aW9uIiwidmVyaWZ5RW1haWxTdWNjZXNzVVJMIiwiaW52YWxpZFZlcmlmaWNhdGlvbkxpbmsiLCJyZXNlbmRWZXJpZmljYXRpb25FbWFpbCIsImJvZHkiLCJsaW5rU2VuZFN1Y2Nlc3NVUkwiLCJsaW5rU2VuZEZhaWxVUkwiLCJjaGFuZ2VQYXNzd29yZCIsInJlamVjdCIsImlkIiwidGV4dCIsImZzIiwicmVhZEZpbGUiLCJlcnIiLCJkYXRhIiwicmVwbGFjZSIsInJlcXVlc3RSZXNldFBhc3N3b3JkIiwiY2hlY2tSZXNldFRva2VuVmFsaWRpdHkiLCJhcHBsaWNhdGlvbklkIiwiYXBwIiwiYXBwTmFtZSIsImNob29zZVBhc3N3b3JkVVJMIiwicmVzZXRQYXNzd29yZCIsIm5ld19wYXNzd29yZCIsInhociIsIlBhcnNlIiwiRXJyb3IiLCJVU0VSTkFNRV9NSVNTSU5HIiwiT1RIRVJfQ0FVU0UiLCJQQVNTV09SRF9NSVNTSU5HIiwidXBkYXRlUGFzc3dvcmQiLCJzdWNjZXNzIiwicmVzdWx0IiwiZXJyb3IiLCJyZXNwb25zZSIsImVuY29kZWRVc2VybmFtZSIsImVuY29kZVVSSUNvbXBvbmVudCIsInBhc3N3b3JkUmVzZXRTdWNjZXNzVVJMIiwiaW52YWxpZExpbmtVUkwiLCJpbnZhbGlkVmVyaWZpY2F0aW9uTGlua1VSTCIsIm1lc3NhZ2UiLCJzZXRDb25maWciLCJtb3VudFJvdXRlcyIsInJvdXRlIiwiZXhwcmVzc1JvdXRlciIsInJvdXRlciIsImV4cHJlc3MiLCJSb3V0ZXIiLCJ1c2UiLCJzdGF0aWMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUVBLE1BQU1BLFdBQVcsR0FBR0MsY0FBS0MsT0FBTCxDQUFhQyxTQUFiLEVBQXdCLG1CQUF4QixDQUFwQjs7QUFDQSxNQUFNQyxLQUFLLEdBQUdILGNBQUtDLE9BQUwsQ0FBYUMsU0FBYixFQUF3QixhQUF4QixDQUFkOztBQUVPLE1BQU1FLGVBQU4sU0FBOEJDLHNCQUE5QixDQUE0QztBQUNqREMsRUFBQUEsV0FBVyxDQUFDQyxHQUFELEVBQU07QUFDZixVQUFNO0FBQUVDLE1BQUFBLFFBQUY7QUFBWUMsTUFBQUEsS0FBSyxFQUFFQztBQUFuQixRQUFnQ0gsR0FBRyxDQUFDSSxLQUExQztBQUNBLFVBQU1GLEtBQUssR0FBR0MsUUFBUSxJQUFJLE9BQU9BLFFBQVAsS0FBb0IsUUFBaEMsR0FBMkNBLFFBQVEsQ0FBQ0UsUUFBVCxFQUEzQyxHQUFpRUYsUUFBL0U7QUFFQSxVQUFNRyxLQUFLLEdBQUdOLEdBQUcsQ0FBQ08sTUFBSixDQUFXRCxLQUF6Qjs7QUFDQSxVQUFNRSxNQUFNLEdBQUdDLGdCQUFPQyxHQUFQLENBQVdKLEtBQVgsQ0FBZjs7QUFFQSxRQUFJLENBQUNFLE1BQUwsRUFBYTtBQUNYLFdBQUtHLGNBQUw7QUFDRDs7QUFFRCxRQUFJLENBQUNILE1BQU0sQ0FBQ0ksZUFBWixFQUE2QjtBQUMzQixhQUFPLEtBQUtDLHNCQUFMLEVBQVA7QUFDRDs7QUFFRCxRQUFJLENBQUNYLEtBQUQsSUFBVSxDQUFDRCxRQUFmLEVBQXlCO0FBQ3ZCLGFBQU8s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cnQgQ29uZmlnIGZyb20gJy4uL0NvbmZpZyc7XG5pbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IGZzIGZyb20gJ2ZzJztcbmltcG9ydCBxcyBmcm9tICdxdWVyeXN0cmluZyc7XG5pbXBvcnQgeyBQYXJzZSB9IGZyb20gJ3BhcnNlL25vZGUnO1xuXG5jb25zdCBwdWJsaWNfaHRtbCA9IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuLi8uLi9wdWJsaWNfaHRtbCcpO1xuY29uc3Qgdmlld3MgPSBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4vLi4vdmlld3MnKTtcblxuZXhwb3J0IGNsYXNzIFB1YmxpY0FQSVJvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICB2ZXJpZnlFbWFpbChyZXEpIHtcbiAgICBjb25zdCB7IHVzZXJuYW1lLCB0b2tlbjogcmF3VG9rZW4gfSA9IHJlcS5xdWVyeTtcbiAgICBjb25zdCB0b2tlbiA9IHJhd1Rva2VuICYmIHR5cGVvZiByYXdUb2tlbiAhPT0gJ3N0cmluZycgPyByYXdUb2tlbi50b1N0cmluZygpIDogcmF3VG9rZW47XG5cbiAgICBjb25zdCBhcHBJZCA9IHJlcS5wYXJhbXMuYXBwSWQ7XG4gICAgY29uc3QgY29uZmlnID0gQ29uZmlnLmdldChhcHBJZCk7XG5cbiAgICBpZiAoIWNvbmZpZykge1xuICAgICAgdGhpcy5pbnZhbGlkUmVxdWVzdCgpO1xuICAgIH1cblxuICAgIGlmICghY29uZmlnLnB1YmxpY1NlcnZlclVSTCkge1xuICAgICAgcmV0dXJuIHRoaXMubWlzc2luZ1B1YmxpY1NlcnZlclVSTCgpO1xuICAgIH1cblxuICAgIGlmICghdG9rZW4gfHwgIXVzZXJuYW1lKSB7XG4gICAgICByZXR1cm4gdGhpcy5pbnZhbGlkTGluayhyZXEpO1xuICAgIH1cblxuICAgIGNvbnN0IHVzZXJDb250cm9sbGVyID0gY29uZmlnLnVzZXJDb250cm9sbGVyO1xuICAgIHJldHVybiB1c2VyQ29udHJvbGxlci52ZXJpZnlFbWFpbCh1c2VybmFtZSwgdG9rZW4pLnRoZW4oXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHFzLnN0cmluZ2lmeSh7IHVzZXJuYW1lIH0pO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICBzdGF0dXM6IDMwMixcbiAgICAgICAgICBsb2NhdGlvbjogYCR7Y29uZmlnLnZlcmlmeUVtYWlsU3VjY2Vzc1VSTH0/JHtwYXJhbXN9YCxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgKCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5pbnZhbGlkVmVyaWZpY2F0aW9uTGluayhyZXEpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICByZXNlbmRWZXJpZmljYXRpb25FbWFpbChyZXEpIHtcbiAgICBjb25zdCB1c2VybmFtZSA9IHJlcS5ib2R5LnVzZXJuYW1lO1xuICAgIGNvbnN0IGFwcElkID0gcmVxLnBhcmFtcy5hcHBJZDtcbiAgICBjb25zdCBjb25maWcgPSBDb25maWcuZ2V0KGFwcElkKTtcblxuICAgIGlmICghY29uZmlnKSB7XG4gICAgICB0aGlzLmludmFsaWRSZXF1ZXN0KCk7XG4gICAgfVxuXG4gICAgaWYgKCFjb25maWcucHVibGljU2VydmVyVVJMKSB7XG4gICAgICByZXR1cm4gdGhpcy5taXNzaW5nUHVibGljU2VydmVyVVJMKCk7XG4gICAgfVxuXG4gICAgaWYgKCF1c2VybmFtZSkge1xuICAgICAgcmV0dXJuIHRoaXMuaW52YWxpZExpbmsocmVxKTtcbiAgICB9XG5cbiAgICBjb25zdCB1c2VyQ29udHJvbGxlciA9IGNvbmZpZy51c2VyQ29udHJvbGxlcjtcblxuICAgIHJldHVybiB1c2VyQ29udHJvbGxlci5yZXNlbmRWZXJpZmljYXRpb25FbWFpbCh1c2VybmFtZSkudGhlbihcbiAgICAgICgpID0+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgc3RhdHVzOiAzMDIsXG4gICAgICAgICAgbG9jYXRpb246IGAke2NvbmZpZy5saW5rU2VuZFN1Y2Nlc3NVUkx9YCxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgICAgKCkgPT4ge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICBzdGF0dXM6IDMwMixcbiAgICAgICAgICBsb2NhdGlvbjogYCR7Y29uZmlnLmxpbmtTZW5kRmFpbFVSTH1gLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgY2hhbmdlUGFzc3dvcmQocmVxKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IENvbmZpZy5nZXQocmVxLnF1ZXJ5LmlkKTtcblxuICAgICAgaWYgKCFjb25maWcpIHtcbiAgICAgICAgdGhpcy5pbnZhbGlkUmVxdWVzdCgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWNvbmZpZy5wdWJsaWNTZXJ2ZXJVUkwpIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUoe1xuICAgICAgICAgIHN0YXR1czogNDA0LFxuICAgICAgICAgIHRleHQ6ICdOb3QgZm91bmQuJyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICAvLyBTaG91bGQgd2Uga2VlcCB0aGUgZmlsZSBpbiBtZW1vcnkgb3IgbGVhdmUgbGlrZSB0aGF0P1xuICAgICAgZnMucmVhZEZpbGUocGF0aC5yZXNvbHZlKHZpZXdzLCAnY2hvb3NlX3Bhc3N3b3JkJyksICd1dGYtOCcsIChlcnIsIGRhdGEpID0+IHtcbiAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgICAgfVxuICAgICAgICBkYXRhID0gZGF0YS5yZXBsYWNlKCdQQVJTRV9TRVJWRVJfVVJMJywgYCcke2NvbmZpZy5wdWJsaWNTZXJ2ZXJVUkx9J2ApO1xuICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICB0ZXh0OiBkYXRhLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcmVxdWVzdFJlc2V0UGFzc3dvcmQocmVxKSB7XG4gICAgY29uc3QgY29uZmlnID0gcmVxLmNvbmZpZztcblxuICAgIGlmICghY29uZmlnKSB7XG4gICAgICB0aGlzLmludmFsaWRSZXF1ZXN0KCk7XG4gICAgfVxuXG4gICAgaWYgKCFjb25maWcucHVibGljU2VydmVyVVJMKSB7XG4gICAgICByZXR1cm4gdGhpcy5taXNzaW5nUHVibGljU2VydmVyVVJMKCk7XG4gICAgfVxuXG4gICAgY29uc3QgeyB1c2VybmFtZSwgdG9rZW46IHJhd1Rva2VuIH0gPSByZXEucXVlcnk7XG4gICAgY29uc3QgdG9rZW4gPSByYXdUb2tlbiAmJiB0eXBlb2YgcmF3VG9rZW4gIT09ICdzdHJpbmcnID8gcmF3VG9rZW4udG9TdHJpbmcoKSA6IHJhd1Rva2VuO1xuXG4gICAgaWYgKCF1c2VybmFtZSB8fCAhdG9rZW4pIHtcbiAgICAgIHJldHVybiB0aGlzLmludmFsaWRMaW5rKHJlcSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbmZpZy51c2VyQ29udHJvbGxlci5jaGVja1Jlc2V0VG9rZW5WYWxpZGl0eSh1c2VybmFtZSwgdG9rZW4pLnRoZW4oXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHFzLnN0cmluZ2lmeSh7XG4gICAgICAgICAgdG9rZW4sXG4gICAgICAgICAgaWQ6IGNvbmZpZy5hcHBsaWNhdGlvbklkLFxuICAgICAgICAgIHVzZXJuYW1lLFxuICAgICAgICAgIGFwcDogY29uZmlnLmFwcE5hbWUsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICBzdGF0dXM6IDMwMixcbiAgICAgICAgICBsb2NhdGlvbjogYCR7Y29uZmlnLmNob29zZVBhc3N3b3JkVVJMfT8ke3BhcmFtc31gLFxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICAoKSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLmludmFsaWRMaW5rKHJlcSk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHJlc2V0UGFzc3dvcmQocmVxKSB7XG4gICAgY29uc3QgY29uZmlnID0gcmVxLmNvbmZpZztcblxuICAgIGlmICghY29uZmlnKSB7XG4gICAgICB0aGlzLmludmFsaWRSZXF1ZXN0KCk7XG4gICAgfVxuXG4gICAgaWYgKCFjb25maWcucHVibGljU2VydmVyVVJMKSB7XG4gICAgICByZXR1cm4gdGhpcy5taXNzaW5nUHVibGljU2VydmVyVVJMKCk7XG4gICAgfVxuXG4gICAgY29uc3QgeyB1c2VybmFtZSwgbmV3X3Bhc3N3b3JkLCB0b2tlbjogcmF3VG9rZW4gfSA9IHJlcS5ib2R5O1xuICAgIGNvbnN0IHRva2VuID0gcmF3VG9rZW4gJiYgdHlwZW9mIHJhd1Rva2VuICE9PSAnc3RyaW5nJyA/IHJhd1Rva2VuLnRvU3RyaW5nKCkgOiByYXdUb2tlbjtcblxuICAgIGlmICgoIXVzZXJuYW1lIHx8ICF0b2tlbiB8fCAhbmV3X3Bhc3N3b3JkKSAmJiByZXEueGhyID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuIHRoaXMuaW52YWxpZExpbmsocmVxKTtcbiAgICB9XG5cbiAgICBpZiAoIXVzZXJuYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuVVNFUk5BTUVfTUlTU0lORywgJ01pc3NpbmcgdXNlcm5hbWUnKTtcbiAgICB9XG5cbiAgICBpZiAoIXRva2VuKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT1RIRVJfQ0FVU0UsICdNaXNzaW5nIHRva2VuJyk7XG4gICAgfVxuXG4gICAgaWYgKCFuZXdfcGFzc3dvcmQpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5QQVNTV09SRF9NSVNTSU5HLCAnTWlzc2luZyBwYXNzd29yZCcpO1xuICAgIH1cblxuICAgIHJldHVybiBjb25maWcudXNlckNvbnRyb2xsZXJcbiAgICAgIC51cGRhdGVQYXNzd29yZCh1c2VybmFtZSwgdG9rZW4sIG5ld19wYXNzd29yZClcbiAgICAgIC50aGVuKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgICBlcnIgPT4ge1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICBlcnIsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHFzLnN0cmluZ2lmeSh7XG4gICAgICAgICAgdXNlcm5hbWU6IHVzZXJuYW1lLFxuICAgICAgICAgIHRva2VuOiB0b2tlbixcbiAgICAgICAgICBpZDogY29uZmlnLmFwcGxpY2F0aW9uSWQsXG4gICAgICAgICAgZXJyb3I6IHJlc3VsdC5lcnIsXG4gICAgICAgICAgYXBwOiBjb25maWcuYXBwTmFtZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHJlcS54aHIpIHtcbiAgICAgICAgICBpZiAocmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgICAgICBzdGF0dXM6IDIwMCxcbiAgICAgICAgICAgICAgcmVzcG9uc2U6ICdQYXNzd29yZCBzdWNjZXNzZnVsbHkgcmVzZXQnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChyZXN1bHQuZXJyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT1RIRVJfQ0FVU0UsIGAke3Jlc3VsdC5lcnJ9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZW5jb2RlZFVzZXJuYW1lID0gZW5jb2RlVVJJQ29tcG9uZW50KHVzZXJuYW1lKTtcbiAgICAgICAgY29uc3QgbG9jYXRpb24gPSByZXN1bHQuc3VjY2Vzc1xuICAgICAgICAgID8gYCR7Y29uZmlnLnBhc3N3b3JkUmVzZXRTdWNjZXNzVVJMfT91c2VybmFtZT0ke2VuY29kZWRVc2VybmFtZX1gXG4gICAgICAgICAgOiBgJHtjb25maWcuY2hvb3NlUGFzc3dvcmRVUkx9PyR7cGFyYW1zfWA7XG5cbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgc3RhdHVzOiAzMDIsXG4gICAgICAgICAgbG9jYXRpb24sXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gIH1cblxuICBpbnZhbGlkTGluayhyZXEpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgIHN0YXR1czogMzAyLFxuICAgICAgbG9jYXRpb246IHJlcS5jb25maWcuaW52YWxpZExpbmtVUkwsXG4gICAgfSk7XG4gIH1cblxuICBpbnZhbGlkVmVyaWZpY2F0aW9uTGluayhyZXEpIHtcbiAgICBjb25zdCBjb25maWcgPSByZXEuY29uZmlnO1xuICAgIGlmIChyZXEucXVlcnkudXNlcm5hbWUgJiYgcmVxLnBhcmFtcy5hcHBJZCkge1xuICAgICAgY29uc3QgcGFyYW1zID0gcXMuc3RyaW5naWZ5KHtcbiAgICAgICAgdXNlcm5hbWU6IHJlcS5xdWVyeS51c2VybmFtZSxcbiAgICAgICAgYXBwSWQ6IHJlcS5wYXJhbXMuYXBwSWQsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICBzdGF0dXM6IDMwMixcbiAgICAgICAgbG9jYXRpb246IGAke2NvbmZpZy5pbnZhbGlkVmVyaWZpY2F0aW9uTGlua1VSTH0/JHtwYXJhbXN9YCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5pbnZhbGlkTGluayhyZXEpO1xuICAgIH1cbiAgfVxuXG4gIG1pc3NpbmdQdWJsaWNTZXJ2ZXJVUkwoKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICB0ZXh0OiAnTm90IGZvdW5kLicsXG4gICAgICBzdGF0dXM6IDQwNCxcbiAgICB9KTtcbiAgfVxuXG4gIGludmFsaWRSZXF1ZXN0KCkge1xuICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKCk7XG4gICAgZXJyb3Iuc3RhdHVzID0gNDAzO1xuICAgIGVycm9yLm1lc3NhZ2UgPSAndW5hdXRob3JpemVkJztcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuXG4gIHNldENvbmZpZyhyZXEpIHtcbiAgICByZXEuY29uZmlnID0gQ29uZmlnLmdldChyZXEucGFyYW1zLmFwcElkKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2FwcHMvOmFwcElkL3ZlcmlmeV9lbWFpbCcsXG4gICAgICByZXEgPT4ge1xuICAgICAgICB0aGlzLnNldENvbmZpZyhyZXEpO1xuICAgICAgfSxcbiAgICAgIHJlcSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnZlcmlmeUVtYWlsKHJlcSk7XG4gICAgICB9XG4gICAgKTtcblxuICAgIHRoaXMucm91dGUoXG4gICAgICAnUE9TVCcsXG4gICAgICAnL2FwcHMvOmFwcElkL3Jlc2VuZF92ZXJpZmljYXRpb25fZW1haWwnLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgdGhpcy5zZXRDb25maWcocmVxKTtcbiAgICAgIH0sXG4gICAgICByZXEgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXNlbmRWZXJpZmljYXRpb25FbWFpbChyZXEpO1xuICAgICAgfVxuICAgICk7XG5cbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL2FwcHMvY2hvb3NlX3Bhc3N3b3JkJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmNoYW5nZVBhc3N3b3JkKHJlcSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ1BPU1QnLFxuICAgICAgJy9hcHBzLzphcHBJZC9yZXF1ZXN0X3Bhc3N3b3JkX3Jlc2V0JyxcbiAgICAgIHJlcSA9PiB7XG4gICAgICAgIHRoaXMuc2V0Q29uZmlnKHJlcSk7XG4gICAgICB9LFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVzZXRQYXNzd29yZChyZXEpO1xuICAgICAgfVxuICAgICk7XG5cbiAgICB0aGlzLnJvdXRlKFxuICAgICAgJ0dFVCcsXG4gICAgICAnL2FwcHMvOmFwcElkL3JlcXVlc3RfcGFzc3dvcmRfcmVzZXQnLFxuICAgICAgcmVxID0+IHtcbiAgICAgICAgdGhpcy5zZXRDb25maWcocmVxKTtcbiAgICAgIH0sXG4gICAgICByZXEgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5yZXF1ZXN0UmVzZXRQYXNzd29yZChyZXEpO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBleHByZXNzUm91dGVyKCkge1xuICAgIGNvbnN0IHJvdXRlciA9IGV4cHJlc3MuUm91dGVyKCk7XG4gICAgcm91dGVyLnVzZSgnL2FwcHMnLCBleHByZXNzLnN0YXRpYyhwdWJsaWNfaHRtbCkpO1xuICAgIHJvdXRlci51c2UoJy8nLCBzdXBlci5leHByZXNzUm91dGVyKCkpO1xuICAgIHJldHVybiByb3V0ZXI7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgUHVibGljQVBJUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/PurgeRouter.js b/lib/Routers/PurgeRouter.js deleted file mode 100644 index 503d9eb543..0000000000 --- a/lib/Routers/PurgeRouter.js +++ /dev/null @@ -1,60 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.PurgeRouter = void 0; - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -var _node = _interopRequireDefault(require("parse/node")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class PurgeRouter extends _PromiseRouter.default { - handlePurge(req) { - if (req.auth.isReadOnly) { - throw new _node.default.Error(_node.default.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to purge a schema."); - } - - return req.config.database.purgeCollection(req.params.className).then(() => { - var cacheAdapter = req.config.cacheController; - - if (req.params.className == '_Session') { - cacheAdapter.user.clear(); - } else if (req.params.className == '_Role') { - cacheAdapter.role.clear(); - } - - return { - response: {} - }; - }).catch(error => { - if (!error || error && error.code === _node.default.Error.OBJECT_NOT_FOUND) { - return { - response: {} - }; - } - - throw error; - }); - } - - mountRoutes() { - this.route('DELETE', '/purge/:className', middleware.promiseEnforceMasterKeyAccess, req => { - return this.handlePurge(req); - }); - } - -} - -exports.PurgeRouter = PurgeRouter; -var _default = PurgeRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1B1cmdlUm91dGVyLmpzIl0sIm5hbWVzIjpbIlB1cmdlUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsImhhbmRsZVB1cmdlIiwicmVxIiwiYXV0aCIsImlzUmVhZE9ubHkiLCJQYXJzZSIsIkVycm9yIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsImNvbmZpZyIsImRhdGFiYXNlIiwicHVyZ2VDb2xsZWN0aW9uIiwicGFyYW1zIiwiY2xhc3NOYW1lIiwidGhlbiIsImNhY2hlQWRhcHRlciIsImNhY2hlQ29udHJvbGxlciIsInVzZXIiLCJjbGVhciIsInJvbGUiLCJyZXNwb25zZSIsImNhdGNoIiwiZXJyb3IiLCJjb2RlIiwiT0JKRUNUX05PVF9GT1VORCIsIm1vdW50Um91dGVzIiwicm91dGUiLCJtaWRkbGV3YXJlIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFTyxNQUFNQSxXQUFOLFNBQTBCQyxzQkFBMUIsQ0FBd0M7QUFDN0NDLEVBQUFBLFdBQVcsQ0FBQ0MsR0FBRCxFQUFNO0FBQ2YsUUFBSUEsR0FBRyxDQUFDQyxJQUFKLENBQVNDLFVBQWIsRUFBeUI7QUFDdkIsWUFBTSxJQUFJQyxjQUFNQyxLQUFWLENBQ0pELGNBQU1DLEtBQU4sQ0FBWUMsbUJBRFIsRUFFSixzREFGSSxDQUFOO0FBSUQ7O0FBQ0QsV0FBT0wsR0FBRyxDQUFDTSxNQUFKLENBQVdDLFFBQVgsQ0FDSkMsZUFESSxDQUNZUixHQUFHLENBQUNTLE1BQUosQ0FBV0MsU0FEdkIsRUFFSkMsSUFGSSxDQUVDLE1BQU07QUFDVixVQUFJQyxZQUFZLEdBQUdaLEdBQUcsQ0FBQ00sTUFBSixDQUFXTyxlQUE5Qjs7QUFDQSxVQUFJYixHQUFHLENBQUNTLE1BQUosQ0FBV0MsU0FBWCxJQUF3QixVQUE1QixFQUF3QztBQUN0Q0UsUUFBQUEsWUFBWSxDQUFDRSxJQUFiLENBQWtCQyxLQUFsQjtBQUNELE9BRkQsTUFFTyxJQUFJZixHQUFHLENBQUNTLE1BQUosQ0FBV0MsU0FBWCxJQUF3QixPQUE1QixFQUFxQztBQUMxQ0UsUUFBQUEsWUFBWSxDQUFDSSxJQUFiLENBQWtCRCxLQUFsQjtBQUNEOztBQUNELGFBQU87QUFBRUUsUUFBQUEsUUFBUSxFQUFFO0FBQVosT0FBUDtBQUNELEtBVkksRUFXSkMsS0FYSSxDQVdFQyxLQUFLLElBQUk7QUFDZCxVQUFJLENBQUNBLEtBQUQsSUFBV0EsS0FBSyxJQUFJQSxLQUFLLENBQUNDLElBQU4sS0FBZWpCLGNBQU1DLEtBQU4sQ0FBWWlCLGdCQUFuRCxFQUFzRTtBQUNwRSxlQUFPO0FBQUVKLFVBQUFBLFFBQVEsRUFBRTtBQUFaLFNBQVA7QUFDRDs7QUFDRCxZQUFNRSxLQUFOO0FBQ0QsS0FoQkksQ0FBUDtBQWlCRDs7QUFFREcsRUFBQUEsV0FBVyxHQUFHO0FBQ1osU0FBS0MsS0FBTCxDQUFXLFFBQVgsRUFBcUIsbUJBQXJCLEVBQTBDQyxVQUFVLENBQUNDLDZCQUFyRCxFQUFvRnpCLEdBQUcsSUFBSTtBQUN6RixhQUFPLEtBQUtELFdBQUwsQ0FBaUJDLEdBQWpCLENBQVA7QUFDRCxLQUZEO0FBR0Q7O0FBL0I0Qzs7O2VBa0NoQ0gsVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBQcm9taXNlUm91dGVyIGZyb20gJy4uL1Byb21pc2VSb3V0ZXInO1xuaW1wb3J0ICogYXMgbWlkZGxld2FyZSBmcm9tICcuLi9taWRkbGV3YXJlcyc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5cbmV4cG9ydCBjbGFzcyBQdXJnZVJvdXRlciBleHRlbmRzIFByb21pc2VSb3V0ZXIge1xuICBoYW5kbGVQdXJnZShyZXEpIHtcbiAgICBpZiAocmVxLmF1dGguaXNSZWFkT25seSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICBcInJlYWQtb25seSBtYXN0ZXJLZXkgaXNuJ3QgYWxsb3dlZCB0byBwdXJnZSBhIHNjaGVtYS5cIlxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2VcbiAgICAgIC5wdXJnZUNvbGxlY3Rpb24ocmVxLnBhcmFtcy5jbGFzc05hbWUpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHZhciBjYWNoZUFkYXB0ZXIgPSByZXEuY29uZmlnLmNhY2hlQ29udHJvbGxlcjtcbiAgICAgICAgaWYgKHJlcS5wYXJhbXMuY2xhc3NOYW1lID09ICdfU2Vzc2lvbicpIHtcbiAgICAgICAgICBjYWNoZUFkYXB0ZXIudXNlci5jbGVhcigpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlcS5wYXJhbXMuY2xhc3NOYW1lID09ICdfUm9sZScpIHtcbiAgICAgICAgICBjYWNoZUFkYXB0ZXIucm9sZS5jbGVhcigpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7fSB9O1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmICghZXJyb3IgfHwgKGVycm9yICYmIGVycm9yLmNvZGUgPT09IFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQpKSB7XG4gICAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHt9IH07XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcbiAgfVxuXG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ0RFTEVURScsICcvcHVyZ2UvOmNsYXNzTmFtZScsIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVQdXJnZShyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1cmdlUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/PushRouter.js b/lib/Routers/PushRouter.js deleted file mode 100644 index 93eda269af..0000000000 --- a/lib/Routers/PushRouter.js +++ /dev/null @@ -1,92 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.PushRouter = void 0; - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -var _node = require("parse/node"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class PushRouter extends _PromiseRouter.default { - mountRoutes() { - this.route('POST', '/push', middleware.promiseEnforceMasterKeyAccess, PushRouter.handlePOST); - } - - static handlePOST(req) { - if (req.auth.isReadOnly) { - throw new _node.Parse.Error(_node.Parse.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to send push notifications."); - } - - const pushController = req.config.pushController; - - if (!pushController) { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Push controller is not set'); - } - - const where = PushRouter.getQueryCondition(req); - let resolve; - const promise = new Promise(_resolve => { - resolve = _resolve; - }); - let pushStatusId; - pushController.sendPush(req.body, where, req.config, req.auth, objectId => { - pushStatusId = objectId; - resolve({ - headers: { - 'X-Parse-Push-Status-Id': pushStatusId - }, - response: { - result: true - } - }); - }).catch(err => { - req.config.loggerController.error(`_PushStatus ${pushStatusId}: error while sending push`, err); - }); - return promise; - } - /** - * Get query condition from the request body. - * @param {Object} req A request object - * @returns {Object} The query condition, the where field in a query api call - */ - - - static getQueryCondition(req) { - const body = req.body || {}; - const hasWhere = typeof body.where !== 'undefined'; - const hasChannels = typeof body.channels !== 'undefined'; - let where; - - if (hasWhere && hasChannels) { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Channels and query can not be set at the same time.'); - } else if (hasWhere) { - where = body.where; - } else if (hasChannels) { - where = { - channels: { - $in: body.channels - } - }; - } else { - throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Sending a push requires either "channels" or a "where" query.'); - } - - return where; - } - -} - -exports.PushRouter = PushRouter; -var _default = PushRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1B1c2hSb3V0ZXIuanMiXSwibmFtZXMiOlsiUHVzaFJvdXRlciIsIlByb21pc2VSb3V0ZXIiLCJtb3VudFJvdXRlcyIsInJvdXRlIiwibWlkZGxld2FyZSIsInByb21pc2VFbmZvcmNlTWFzdGVyS2V5QWNjZXNzIiwiaGFuZGxlUE9TVCIsInJlcSIsImF1dGgiLCJpc1JlYWRPbmx5IiwiUGFyc2UiLCJFcnJvciIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJwdXNoQ29udHJvbGxlciIsImNvbmZpZyIsIlBVU0hfTUlTQ09ORklHVVJFRCIsIndoZXJlIiwiZ2V0UXVlcnlDb25kaXRpb24iLCJyZXNvbHZlIiwicHJvbWlzZSIsIlByb21pc2UiLCJfcmVzb2x2ZSIsInB1c2hTdGF0dXNJZCIsInNlbmRQdXNoIiwiYm9keSIsIm9iamVjdElkIiwiaGVhZGVycyIsInJlc3BvbnNlIiwicmVzdWx0IiwiY2F0Y2giLCJlcnIiLCJsb2dnZXJDb250cm9sbGVyIiwiZXJyb3IiLCJoYXNXaGVyZSIsImhhc0NoYW5uZWxzIiwiY2hhbm5lbHMiLCIkaW4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7QUFFTyxNQUFNQSxVQUFOLFNBQXlCQyxzQkFBekIsQ0FBdUM7QUFDNUNDLEVBQUFBLFdBQVcsR0FBRztBQUNaLFNBQUtDLEtBQUwsQ0FBVyxNQUFYLEVBQW1CLE9BQW5CLEVBQTRCQyxVQUFVLENBQUNDLDZCQUF2QyxFQUFzRUwsVUFBVSxDQUFDTSxVQUFqRjtBQUNEOztBQUVELFNBQU9BLFVBQVAsQ0FBa0JDLEdBQWxCLEVBQXVCO0FBQ3JCLFFBQUlBLEdBQUcsQ0FBQ0MsSUFBSixDQUFTQyxVQUFiLEVBQXlCO0FBQ3ZCLFlBQU0sSUFBSUMsWUFBTUMsS0FBVixDQUNKRCxZQUFNQyxLQUFOLENBQVlDLG1CQURSLEVBRUosK0RBRkksQ0FBTjtBQUlEOztBQUNELFVBQU1DLGNBQWMsR0FBR04sR0FBRyxDQUFDTyxNQUFKLENBQVdELGNBQWxDOztBQUNBLFFBQUksQ0FBQ0EsY0FBTCxFQUFxQjtBQUNuQixZQUFNLElBQUlILFlBQU1DLEtBQVYsQ0FBZ0JELFlBQU1DLEtBQU4sQ0FBWUksa0JBQTVCLEVBQWdELDRCQUFoRCxDQUFOO0FBQ0Q7O0FBRUQsVUFBTUMsS0FBSyxHQUFHaEIsVUFBVSxDQUFDaUIsaUJBQVgsQ0FBNkJWLEdBQTdCLENBQWQ7QUFDQSxRQUFJVyxPQUFKO0FBQ0EsVUFBTUMsT0FBTyxHQUFHLElBQUlDLE9BQUosQ0FBWUMsUUFBUSxJQUFJO0FBQ3RDSCxNQUFBQSxPQUFPLEdBQUdHLFFBQVY7QUFDRCxLQUZlLENBQWhCO0FBR0EsUUFBSUMsWUFBSjtBQUNBVCxJQUFBQSxjQUFjLENBQ1hVLFFBREgsQ0FDWWhCLEdBQUcsQ0FBQ2lCLElBRGhCLEVBQ3NCUixLQUR0QixFQUM2QlQsR0FBRyxDQUFDTyxNQURqQyxFQUN5Q1AsR0FBRyxDQUFDQyxJQUQ3QyxFQUNtRGlCLFFBQVEsSUFBSTtBQUMzREgsTUFBQUEsWUFBWSxHQUFHRyxRQUFmO0FBQ0FQLE1BQUFBLE9BQU8sQ0FBQztBQUNOUSxRQUFBQSxPQUFPLEVBQUU7QUFDUCxvQ0FBMEJKO0FBRG5CLFNBREg7QUFJTkssUUFBQUEsUUFBUSxFQUFFO0FBQ1JDLFVBQUFBLE1BQU0sRUFBRTtBQURBO0FBSkosT0FBRCxDQUFQO0FBUUQsS0FYSCxFQVlHQyxLQVpILENBWVNDLEdBQUcsSUFBSTtBQUNadkIsTUFBQUEsR0FBRyxDQUFDTyxNQUFKLENBQVdpQixnQkFBWCxDQUE0QkMsS0FBNUIsQ0FDRyxlQUFjVixZQUFhLDRCQUQ5QixFQUVFUSxHQUZGO0FBSUQsS0FqQkg7QUFrQkEsV0FBT1gsT0FBUDtBQUNEO0FBRUQ7QUFDRjtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0UsU0FBT0YsaUJBQVAsQ0FBeUJWLEdBQXpCLEVBQThCO0FBQzVCLFVBQU1pQixJQUFJLEdBQUdqQixHQUFHLENBQUNpQixJQUFKLElBQVksRUFBekI7QUFDQSxVQUFNUyxRQUFRLEdBQUcsT0FBT1QsSUFBSSxDQUFDUixLQUFaLEtBQXNCLFdBQXZDO0FBQ0EsVUFBTWtCLFdBQVcsR0FBRyxPQUFPVixJQUFJLENBQUNXLFFBQVosS0FBeUIsV0FBN0M7QUFFQSxRQUFJbkIsS0FBSjs7QUFDQSxRQUFJaUIsUUFBUSxJQUFJQyxXQUFoQixFQUE2QjtBQUMzQixZQUFNLElBQUl4QixZQUFNQyxLQUFWLENBQ0pELFlBQU1DLEtBQU4sQ0FBWUksa0JBRFIsRUFFSixxREFGSSxDQUFOO0FBSUQsS0FMRCxNQUtPLElBQUlrQixRQUFKLEVBQWM7QUFDbkJqQixNQUFBQSxLQUFLLEdBQUdRLElBQUksQ0FBQ1IsS0FBYjtBQUNELEtBRk0sTUFFQSxJQUFJa0IsV0FBSixFQUFpQjtBQUN0QmxCLE1BQUFBLEtBQUssR0FBRztBQUNObUIsUUFBQUEsUUFBUSxFQUFFO0FBQ1JDLFVBQUFBLEdBQUcsRUFBRVosSUFBSSxDQUFDVztBQURGO0FBREosT0FBUjtBQUtELEtBTk0sTUFNQTtBQUNMLFlBQU0sSUFBSXpCLFlBQU1DLEtBQVYsQ0FDSkQsWUFBTUMsS0FBTixDQUFZSSxrQkFEUixFQUVKLCtEQUZJLENBQU47QUFJRDs7QUFDRCxXQUFPQyxLQUFQO0FBQ0Q7O0FBM0UyQzs7O2VBOEUvQmhCLFUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuLi9Qcm9taXNlUm91dGVyJztcbmltcG9ydCAqIGFzIG1pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuaW1wb3J0IHsgUGFyc2UgfSBmcm9tICdwYXJzZS9ub2RlJztcblxuZXhwb3J0IGNsYXNzIFB1c2hSb3V0ZXIgZXh0ZW5kcyBQcm9taXNlUm91dGVyIHtcbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnUE9TVCcsICcvcHVzaCcsIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIFB1c2hSb3V0ZXIuaGFuZGxlUE9TVCk7XG4gIH1cblxuICBzdGF0aWMgaGFuZGxlUE9TVChyZXEpIHtcbiAgICBpZiAocmVxLmF1dGguaXNSZWFkT25seSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICBcInJlYWQtb25seSBtYXN0ZXJLZXkgaXNuJ3QgYWxsb3dlZCB0byBzZW5kIHB1c2ggbm90aWZpY2F0aW9ucy5cIlxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgcHVzaENvbnRyb2xsZXIgPSByZXEuY29uZmlnLnB1c2hDb250cm9sbGVyO1xuICAgIGlmICghcHVzaENvbnRyb2xsZXIpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5QVVNIX01JU0NPTkZJR1VSRUQsICdQdXNoIGNvbnRyb2xsZXIgaXMgbm90IHNldCcpO1xuICAgIH1cblxuICAgIGNvbnN0IHdoZXJlID0gUHVzaFJvdXRlci5nZXRRdWVyeUNvbmRpdGlvbihyZXEpO1xuICAgIGxldCByZXNvbHZlO1xuICAgIGNvbnN0IHByb21pc2UgPSBuZXcgUHJvbWlzZShfcmVzb2x2ZSA9PiB7XG4gICAgICByZXNvbHZlID0gX3Jlc29sdmU7XG4gICAgfSk7XG4gICAgbGV0IHB1c2hTdGF0dXNJZDtcbiAgICBwdXNoQ29udHJvbGxlclxuICAgICAgLnNlbmRQdXNoKHJlcS5ib2R5LCB3aGVyZSwgcmVxLmNvbmZpZywgcmVxLmF1dGgsIG9iamVjdElkID0+IHtcbiAgICAgICAgcHVzaFN0YXR1c0lkID0gb2JqZWN0SWQ7XG4gICAgICAgIHJlc29sdmUoe1xuICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICdYLVBhcnNlLVB1c2gtU3RhdHVzLUlkJzogcHVzaFN0YXR1c0lkLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICAgIHJlc3VsdDogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgcmVxLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyLmVycm9yKFxuICAgICAgICAgIGBfUHVzaFN0YXR1cyAke3B1c2hTdGF0dXNJZH06IGVycm9yIHdoaWxlIHNlbmRpbmcgcHVzaGAsXG4gICAgICAgICAgZXJyXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgcXVlcnkgY29uZGl0aW9uIGZyb20gdGhlIHJlcXVlc3QgYm9keS5cbiAgICogQHBhcmFtIHtPYmplY3R9IHJlcSBBIHJlcXVlc3Qgb2JqZWN0XG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFRoZSBxdWVyeSBjb25kaXRpb24sIHRoZSB3aGVyZSBmaWVsZCBpbiBhIHF1ZXJ5IGFwaSBjYWxsXG4gICAqL1xuICBzdGF0aWMgZ2V0UXVlcnlDb25kaXRpb24ocmVxKSB7XG4gICAgY29uc3QgYm9keSA9IHJlcS5ib2R5IHx8IHt9O1xuICAgIGNvbnN0IGhhc1doZXJlID0gdHlwZW9mIGJvZHkud2hlcmUgIT09ICd1bmRlZmluZWQnO1xuICAgIGNvbnN0IGhhc0NoYW5uZWxzID0gdHlwZW9mIGJvZHkuY2hhbm5lbHMgIT09ICd1bmRlZmluZWQnO1xuXG4gICAgbGV0IHdoZXJlO1xuICAgIGlmIChoYXNXaGVyZSAmJiBoYXNDaGFubmVscykge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5QVVNIX01JU0NPTkZJR1VSRUQsXG4gICAgICAgICdDaGFubmVscyBhbmQgcXVlcnkgY2FuIG5vdCBiZSBzZXQgYXQgdGhlIHNhbWUgdGltZS4nXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAoaGFzV2hlcmUpIHtcbiAgICAgIHdoZXJlID0gYm9keS53aGVyZTtcbiAgICB9IGVsc2UgaWYgKGhhc0NoYW5uZWxzKSB7XG4gICAgICB3aGVyZSA9IHtcbiAgICAgICAgY2hhbm5lbHM6IHtcbiAgICAgICAgICAkaW46IGJvZHkuY2hhbm5lbHMsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgJ1NlbmRpbmcgYSBwdXNoIHJlcXVpcmVzIGVpdGhlciBcImNoYW5uZWxzXCIgb3IgYSBcIndoZXJlXCIgcXVlcnkuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHdoZXJlO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1c2hSb3V0ZXI7XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/RolesRouter.js b/lib/Routers/RolesRouter.js deleted file mode 100644 index 10fd6e7942..0000000000 --- a/lib/Routers/RolesRouter.js +++ /dev/null @@ -1,40 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.RolesRouter = void 0; - -var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class RolesRouter extends _ClassesRouter.default { - className() { - return '_Role'; - } - - mountRoutes() { - this.route('GET', '/roles', req => { - return this.handleFind(req); - }); - this.route('GET', '/roles/:objectId', req => { - return this.handleGet(req); - }); - this.route('POST', '/roles', req => { - return this.handleCreate(req); - }); - this.route('PUT', '/roles/:objectId', req => { - return this.handleUpdate(req); - }); - this.route('DELETE', '/roles/:objectId', req => { - return this.handleDelete(req); - }); - } - -} - -exports.RolesRouter = RolesRouter; -var _default = RolesRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1JvbGVzUm91dGVyLmpzIl0sIm5hbWVzIjpbIlJvbGVzUm91dGVyIiwiQ2xhc3Nlc1JvdXRlciIsImNsYXNzTmFtZSIsIm1vdW50Um91dGVzIiwicm91dGUiLCJyZXEiLCJoYW5kbGVGaW5kIiwiaGFuZGxlR2V0IiwiaGFuZGxlQ3JlYXRlIiwiaGFuZGxlVXBkYXRlIiwiaGFuZGxlRGVsZXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7Ozs7QUFFTyxNQUFNQSxXQUFOLFNBQTBCQyxzQkFBMUIsQ0FBd0M7QUFDN0NDLEVBQUFBLFNBQVMsR0FBRztBQUNWLFdBQU8sT0FBUDtBQUNEOztBQUVEQyxFQUFBQSxXQUFXLEdBQUc7QUFDWixTQUFLQyxLQUFMLENBQVcsS0FBWCxFQUFrQixRQUFsQixFQUE0QkMsR0FBRyxJQUFJO0FBQ2pDLGFBQU8sS0FBS0MsVUFBTCxDQUFnQkQsR0FBaEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLRCxLQUFMLENBQVcsS0FBWCxFQUFrQixrQkFBbEIsRUFBc0NDLEdBQUcsSUFBSTtBQUMzQyxhQUFPLEtBQUtFLFNBQUwsQ0FBZUYsR0FBZixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUtELEtBQUwsQ0FBVyxNQUFYLEVBQW1CLFFBQW5CLEVBQTZCQyxHQUFHLElBQUk7QUFDbEMsYUFBTyxLQUFLRyxZQUFMLENBQWtCSCxHQUFsQixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUtELEtBQUwsQ0FBVyxLQUFYLEVBQWtCLGtCQUFsQixFQUFzQ0MsR0FBRyxJQUFJO0FBQzNDLGFBQU8sS0FBS0ksWUFBTCxDQUFrQkosR0FBbEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLRCxLQUFMLENBQVcsUUFBWCxFQUFxQixrQkFBckIsRUFBeUNDLEdBQUcsSUFBSTtBQUM5QyxhQUFPLEtBQUtLLFlBQUwsQ0FBa0JMLEdBQWxCLENBQVA7QUFDRCxLQUZEO0FBR0Q7O0FBckI0Qzs7O2VBd0JoQ0wsVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBDbGFzc2VzUm91dGVyIGZyb20gJy4vQ2xhc3Nlc1JvdXRlcic7XG5cbmV4cG9ydCBjbGFzcyBSb2xlc1JvdXRlciBleHRlbmRzIENsYXNzZXNSb3V0ZXIge1xuICBjbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICdfUm9sZSc7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3JvbGVzJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZpbmQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3JvbGVzLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9yb2xlcycsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVDcmVhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQVVQnLCAnL3JvbGVzLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVVcGRhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdERUxFVEUnLCAnL3JvbGVzLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVEZWxldGUocmVxKTtcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBSb2xlc1JvdXRlcjtcbiJdfQ== \ No newline at end of file diff --git a/lib/Routers/SchemasRouter.js b/lib/Routers/SchemasRouter.js deleted file mode 100644 index 04681476df..0000000000 --- a/lib/Routers/SchemasRouter.js +++ /dev/null @@ -1,120 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.SchemasRouter = void 0; - -var _PromiseRouter = _interopRequireDefault(require("../PromiseRouter")); - -var middleware = _interopRequireWildcard(require("../middlewares")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// schemas.js -var Parse = require('parse/node').Parse, - SchemaController = require('../Controllers/SchemaController'); - -function classNameMismatchResponse(bodyClass, pathClass) { - throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class name mismatch between ${bodyClass} and ${pathClass}.`); -} - -function getAllSchemas(req) { - return req.config.database.loadSchema({ - clearCache: true - }).then(schemaController => schemaController.getAllClasses(true)).then(schemas => ({ - response: { - results: schemas - } - })); -} - -function getOneSchema(req) { - const className = req.params.className; - return req.config.database.loadSchema({ - clearCache: true - }).then(schemaController => schemaController.getOneSchema(className, true)).then(schema => ({ - response: schema - })).catch(error => { - if (error === undefined) { - throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} does not exist.`); - } else { - throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Database adapter error.'); - } - }); -} - -function createSchema(req) { - if (req.auth.isReadOnly) { - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to create a schema."); - } - - if (req.params.className && req.body.className) { - if (req.params.className != req.body.className) { - return classNameMismatchResponse(req.body.className, req.params.className); - } - } - - const className = req.params.className || req.body.className; - - if (!className) { - throw new Parse.Error(135, `POST ${req.path} needs a class name.`); - } - - return req.config.database.loadSchema({ - clearCache: true - }).then(schema => schema.addClassIfNotExists(className, req.body.fields, req.body.classLevelPermissions, req.body.indexes)).then(schema => ({ - response: schema - })); -} - -function modifySchema(req) { - if (req.auth.isReadOnly) { - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to update a schema."); - } - - if (req.body.className && req.body.className != req.params.className) { - return classNameMismatchResponse(req.body.className, req.params.className); - } - - const submittedFields = req.body.fields || {}; - const className = req.params.className; - return req.config.database.loadSchema({ - clearCache: true - }).then(schema => schema.updateClass(className, submittedFields, req.body.classLevelPermissions, req.body.indexes, req.config.database)).then(result => ({ - response: result - })); -} - -const deleteSchema = req => { - if (req.auth.isReadOnly) { - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, "read-only masterKey isn't allowed to delete a schema."); - } - - if (!SchemaController.classNameIsValid(req.params.className)) { - throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, SchemaController.invalidClassNameMessage(req.params.className)); - } - - return req.config.database.deleteSchema(req.params.className).then(() => ({ - response: {} - })); -}; - -class SchemasRouter extends _PromiseRouter.default { - mountRoutes() { - this.route('GET', '/schemas', middleware.promiseEnforceMasterKeyAccess, getAllSchemas); - this.route('GET', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, getOneSchema); - this.route('POST', '/schemas', middleware.promiseEnforceMasterKeyAccess, createSchema); - this.route('POST', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, createSchema); - this.route('PUT', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, modifySchema); - this.route('DELETE', '/schemas/:className', middleware.promiseEnforceMasterKeyAccess, deleteSchema); - } - -} - -exports.SchemasRouter = SchemasRouter; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1NjaGVtYXNSb3V0ZXIuanMiXSwibmFtZXMiOlsiUGFyc2UiLCJyZXF1aXJlIiwiU2NoZW1hQ29udHJvbGxlciIsImNsYXNzTmFtZU1pc21hdGNoUmVzcG9uc2UiLCJib2R5Q2xhc3MiLCJwYXRoQ2xhc3MiLCJFcnJvciIsIklOVkFMSURfQ0xBU1NfTkFNRSIsImdldEFsbFNjaGVtYXMiLCJyZXEiLCJjb25maWciLCJkYXRhYmFzZSIsImxvYWRTY2hlbWEiLCJjbGVhckNhY2hlIiwidGhlbiIsInNjaGVtYUNvbnRyb2xsZXIiLCJnZXRBbGxDbGFzc2VzIiwic2NoZW1hcyIsInJlc3BvbnNlIiwicmVzdWx0cyIsImdldE9uZVNjaGVtYSIsImNsYXNzTmFtZSIsInBhcmFtcyIsInNjaGVtYSIsImNhdGNoIiwiZXJyb3IiLCJ1bmRlZmluZWQiLCJJTlRFUk5BTF9TRVJWRVJfRVJST1IiLCJjcmVhdGVTY2hlbWEiLCJhdXRoIiwiaXNSZWFkT25seSIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJib2R5IiwicGF0aCIsImFkZENsYXNzSWZOb3RFeGlzdHMiLCJmaWVsZHMiLCJjbGFzc0xldmVsUGVybWlzc2lvbnMiLCJpbmRleGVzIiwibW9kaWZ5U2NoZW1hIiwic3VibWl0dGVkRmllbGRzIiwidXBkYXRlQ2xhc3MiLCJyZXN1bHQiLCJkZWxldGVTY2hlbWEiLCJjbGFzc05hbWVJc1ZhbGlkIiwiaW52YWxpZENsYXNzTmFtZU1lc3NhZ2UiLCJTY2hlbWFzUm91dGVyIiwiUHJvbWlzZVJvdXRlciIsIm1vdW50Um91dGVzIiwicm91dGUiLCJtaWRkbGV3YXJlIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFLQTs7QUFDQTs7Ozs7Ozs7QUFOQTtBQUVBLElBQUlBLEtBQUssR0FBR0MsT0FBTyxDQUFDLFlBQUQsQ0FBUCxDQUFzQkQsS0FBbEM7QUFBQSxJQUNFRSxnQkFBZ0IsR0FBR0Qs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QXdFMUMsYUFBeEU7QUFDQSxTQUFLd0MsS0FBTCxDQUNFLEtBREYsRUFFRSxxQkFGRixFQUdFQyxVQUFVLENBQUNDLDZCQUhiLEVBSUU5QixZQUpGO0FBTUEsU0FBSzRCLEtBQUwsQ0FBVyxNQUFYLEVBQW1CLFVBQW5CLEVBQStCQyxVQUFVLENBQUNDLDZCQUExQyxFQUF5RXRCLFlBQXpFO0FBQ0EsU0FBS29CLEtBQUwsQ0FDRSxNQURGLEVBRUUscUJBRkYsRUFHRUMsVUFBVSxDQUFDQyw2QkFIYixFQUlFdEIsWUFKRjtBQU1BLFNBQUtvQixLQUFMLENBQ0UsS0FERixFQUVFLHFCQUZGLEVBR0VDLFVBQVUsQ0FBQ0MsNkJBSGIsRUFJRVosWUFKRjtBQU1BLFNBQUtVLEtBQUwsQ0FDRSxRQURGLEVBRUUscUJBRkYsRUFHRUMsVUFBVSxDQUFDQyw2QkFIYixFQUlFUixZQUpGO0FBTUQ7O0FBNUI4QyIsInNvdXJjZXNDb250ZW50IjpbIi8vIHNjaGVtYXMuanNcblxudmFyIFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlLFxuICBTY2hlbWFDb250cm9sbGVyID0gcmVxdWlyZSgnLi4vQ29udHJvbGxlcnMvU2NoZW1hQ29udHJvbGxlcicpO1xuXG5pbXBvcnQgUHJvbWlzZVJvdXRlciBmcm9tICcuLi9Qcm9taXNlUm91dGVyJztcbmltcG9ydCAqIGFzIG1pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5mdW5jdGlvbiBjbGFzc05hbWVNaXNtYXRjaFJlc3BvbnNlKGJvZHlDbGFzcywgcGF0aENsYXNzKSB7XG4gIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICBQYXJzZS5FcnJvci5JTlZBTElEX0NMQVNTX05BTUUsXG4gICAgYENsYXNzIG5hbWUgbWlzbWF0Y2ggYmV0d2VlbiAke2JvZHlDbGFzc30gYW5kICR7cGF0aENsYXNzfS5gXG4gICk7XG59XG5cbmZ1bmN0aW9uIGdldEFsbFNjaGVtYXMocmVxKSB7XG4gIHJldHVybiByZXEuY29uZmlnLmRhdGFiYXNlXG4gICAgLmxvYWRTY2hlbWEoeyBjbGVhckNhY2hlOiB0cnVlIH0pXG4gICAgLnRoZW4oc2NoZW1hQ29udHJvbGxlciA9PiBzY2hlbWFDb250cm9sbGVyLmdldEFsbENsYXNzZXModHJ1ZSkpXG4gICAgLnRoZW4oc2NoZW1hcyA9PiAoeyByZXNwb25zZTogeyByZXN1bHRzOiBzY2hlbWFzIH0gfSkpO1xufVxuXG5mdW5jdGlvbiBnZXRPbmVTY2hlbWEocmVxKSB7XG4gIGNvbnN0IGNsYXNzTmFtZSA9IHJlcS5wYXJhbXMuY2xhc3NOYW1lO1xuICByZXR1cm4gcmVxLmNvbmZpZy5kYXRhYmFzZVxuICAgIC5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KVxuICAgIC50aGVuKHNjaGVtYUNvbnRyb2xsZXIgPT4gc2NoZW1hQ29udHJvbGxlci5nZXRPbmVTY2hlbWEoY2xhc3NOYW1lLCB0cnVlKSlcbiAgICAudGhlbihzY2hlbWEgPT4gKHsgcmVzcG9uc2U6IHNjaGVtYSB9KSlcbiAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgaWYgKGVycm9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSwgYENsYXNzICR7Y2xhc3NOYW1lfSBkb2VzIG5vdCBleGlzdC5gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsICdEYXRhYmFzZSBhZGFwdGVyIGVycm9yLicpO1xuICAgICAgfVxuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVTY2hlbWEocmVxKSB7XG4gIGlmIChyZXEuYXV0aC5pc1JlYWRPbmx5KSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgIFwicmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIGNyZWF0ZSBhIHNjaGVtYS5cIlxuICAgICk7XG4gIH1cbiAgaWYgKHJlcS5wYXJhbXMuY2xhc3NOYW1lICYmIHJlcS5ib2R5LmNsYXNzTmFtZSkge1xuICAgIGlmIChyZXEucGFyYW1zLmNsYXNzTmFtZSAhPSByZXEuYm9keS5jbGFzc05hbWUpIHtcbiAgICAgIHJldHVybiBjbGFzc05hbWVNaXNtYXRjaFJlc3BvbnNlKHJlcS5ib2R5LmNsYXNzTmFtZSwgcmVxLnBhcmFtcy5jbGFzc05hbWUpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGNsYXNzTmFtZSA9IHJlcS5wYXJhbXMuY2xhc3NOYW1lIHx8IHJlcS5ib2R5LmNsYXNzTmFtZTtcbiAgaWYgKCFjbGFzc05hbWUpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTM1LCBgUE9TVCAke3JlcS5wYXRofSBuZWVkcyBhIGNsYXNzIG5hbWUuYCk7XG4gIH1cblxuICByZXR1cm4gcmVxLmNvbmZpZy5kYXRhYmFzZVxuICAgIC5sb2FkU2NoZW1hKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KVxuICAgIC50aGVuKHNjaGVtYSA9PlxuICAgICAgc2NoZW1hLmFkZENsYXNzSWZOb3RFeGlzdHMoXG4gICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgcmVxLmJvZHkuZmllbGRzLFxuICAgICAgICByZXEuYm9keS5jbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gICAgICAgIHJlcS5ib2R5LmluZGV4ZXNcbiAgICAgIClcbiAgICApXG4gICAgLnRoZW4oc2NoZW1hID0+ICh7IHJlc3BvbnNlOiBzY2hlbWEgfSkpO1xufVxuXG5mdW5jdGlvbiBtb2RpZnlTY2hlbWEocmVxKSB7XG4gIGlmIChyZXEuYXV0aC5pc1JlYWRPbmx5KSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgIFwicmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIHVwZGF0ZSBhIHNjaGVtYS5cIlxuICAgICk7XG4gIH1cbiAgaWYgKHJlcS5ib2R5LmNsYXNzTmFtZSAmJiByZXEuYm9keS5jbGFzc05hbWUgIT0gcmVxLnBhcmFtcy5jbGFzc05hbWUpIHtcbiAgICByZXR1cm4gY2xhc3NOYW1lTWlzbWF0Y2hSZXNwb25zZShyZXEuYm9keS5jbGFzc05hbWUsIHJlcS5wYXJhbXMuY2xhc3NOYW1lKTtcbiAgfVxuXG4gIGNvbnN0IHN1Ym1pdHRlZEZpZWxkcyA9IHJlcS5ib2R5LmZpZWxkcyB8fCB7fTtcbiAgY29uc3QgY2xhc3NOYW1lID0gcmVxLnBhcmFtcy5jbGFzc05hbWU7XG5cbiAgcmV0dXJuIHJlcS5jb25maWcuZGF0YWJhc2VcbiAgICAubG9hZFNjaGVtYSh7IGNsZWFyQ2FjaGU6IHRydWUgfSlcbiAgICAudGhlbihzY2hlbWEgPT5cbiAgICAgIHNjaGVtYS51cGRhdGVDbGFzcyhcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICBzdWJtaXR0ZWRGaWVsZHMsXG4gICAgICAgIHJlcS5ib2R5LmNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgICAgcmVxLmJvZHkuaW5kZXhlcyxcbiAgICAgICAgcmVxLmNvbmZpZy5kYXRhYmFzZVxuICAgICAgKVxuICAgIClcbiAgICAudGhlbihyZXN1bHQgPT4gKHsgcmVzcG9uc2U6IHJlc3VsdCB9KSk7XG59XG5cbmNvbnN0IGRlbGV0ZVNjaGVtYSA9IHJlcSA9PiB7XG4gIGlmIChyZXEuYXV0aC5pc1JlYWRPbmx5KSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgIFwicmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIGRlbGV0ZSBhIHNjaGVtYS5cIlxuICAgICk7XG4gIH1cbiAgaWYgKCFTY2hlbWFDb250cm9sbGVyLmNsYXNzTmFtZUlzVmFsaWQocmVxLnBhcmFtcy5jbGFzc05hbWUpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLFxuICAgICAgU2NoZW1hQ29udHJvbGxlci5pbnZhbGlkQ2xhc3NOYW1lTWVzc2FnZShyZXEucGFyYW1zLmNsYXNzTmFtZSlcbiAgICApO1xuICB9XG4gIHJldHVybiByZXEuY29uZmlnLmRhdGFiYXNlLmRlbGV0ZVNjaGVtYShyZXEucGFyYW1zLmNsYXNzTmFtZSkudGhlbigoKSA9PiAoeyByZXNwb25zZToge30gfSkpO1xufTtcblxuZXhwb3J0IGNsYXNzIFNjaGVtYXNSb3V0ZXIgZXh0ZW5kcyBQcm9taXNlUm91dGVyIHtcbiAgbW91bnRSb3V0ZXMoKSB7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy9zY2hlbWFzJywgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcywgZ2V0QWxsU2NoZW1hcyk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdHRVQnLFxuICAgICAgJy9zY2hlbWFzLzpjbGFzc05hbWUnLFxuICAgICAgbWlkZGxld2FyZS5wcm9taXNlRW5mb3JjZU1hc3RlcktleUFjY2VzcyxcbiAgICAgIGdldE9uZVNjaGVtYVxuICAgICk7XG4gICAgdGhpcy5yb3V0ZSgnUE9TVCcsICcvc2NoZW1hcycsIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsIGNyZWF0ZVNjaGVtYSk7XG4gICAgdGhpcy5yb3V0ZShcbiAgICAgICdQT1NUJyxcbiAgICAgICcvc2NoZW1hcy86Y2xhc3NOYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICBjcmVhdGVTY2hlbWFcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnUFVUJyxcbiAgICAgICcvc2NoZW1hcy86Y2xhc3NOYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICBtb2RpZnlTY2hlbWFcbiAgICApO1xuICAgIHRoaXMucm91dGUoXG4gICAgICAnREVMRVRFJyxcbiAgICAgICcvc2NoZW1hcy86Y2xhc3NOYW1lJyxcbiAgICAgIG1pZGRsZXdhcmUucHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MsXG4gICAgICBkZWxldGVTY2hlbWFcbiAgICApO1xuICB9XG59XG4iXX0= \ No newline at end of file diff --git a/lib/Routers/SessionsRouter.js b/lib/Routers/SessionsRouter.js deleted file mode 100644 index de4bdcd2e0..0000000000 --- a/lib/Routers/SessionsRouter.js +++ /dev/null @@ -1,107 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.SessionsRouter = void 0; - -var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); - -var _node = _interopRequireDefault(require("parse/node")); - -var _rest = _interopRequireDefault(require("../rest")); - -var _Auth = _interopRequireDefault(require("../Auth")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -class SessionsRouter extends _ClassesRouter.default { - className() { - return '_Session'; - } - - handleMe(req) { - // TODO: Verify correct behavior - if (!req.info || !req.info.sessionToken) { - throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Session token required.'); - } - - return _rest.default.find(req.config, _Auth.default.master(req.config), '_Session', { - sessionToken: req.info.sessionToken - }, undefined, req.info.clientSDK, req.info.context).then(response => { - if (!response.results || response.results.length == 0) { - throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Session token not found.'); - } - - return { - response: response.results[0] - }; - }); - } - - handleUpdateToRevocableSession(req) { - const config = req.config; - const user = req.auth.user; // Issue #2720 - // Calling without a session token would result in a not found user - - if (!user) { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'invalid session'); - } - - const { - sessionData, - createSession - } = _Auth.default.createSession(config, { - userId: user.id, - createdWith: { - action: 'upgrade' - }, - installationId: req.auth.installationId - }); - - return createSession().then(() => { - // delete the session token, use the db to skip beforeSave - return config.database.update('_User', { - objectId: user.id - }, { - sessionToken: { - __op: 'Delete' - } - }); - }).then(() => { - return Promise.resolve({ - response: sessionData - }); - }); - } - - mountRoutes() { - this.route('GET', '/sessions/me', req => { - return this.handleMe(req); - }); - this.route('GET', '/sessions', req => { - return this.handleFind(req); - }); - this.route('GET', '/sessions/:objectId', req => { - return this.handleGet(req); - }); - this.route('POST', '/sessions', req => { - return this.handleCreate(req); - }); - this.route('PUT', '/sessions/:objectId', req => { - return this.handleUpdate(req); - }); - this.route('DELETE', '/sessions/:objectId', req => { - return this.handleDelete(req); - }); - this.route('POST', '/upgradeToRevocableSession', req => { - return this.handleUpdateToRevocableSession(req); - }); - } - -} - -exports.SessionsRouter = SessionsRouter; -var _default = SessionsRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1Nlc3Npb25zUm91dGVyLmpzIl0sIm5hbWVzIjpbIlNlc3Npb25zUm91dGVyIiwiQ2xhc3Nlc1JvdXRlciIsImNsYXNzTmFtZSIsImhhbmRsZU1lIiwicmVxIiwiaW5mbyIsInNlc3Npb25Ub2tlbiIsIlBhcnNlIiwiRXJyb3IiLCJJTlZBTElEX1NFU1NJT05fVE9LRU4iLCJyZXN0IiwiZmluZCIsImNvbmZpZyIsIkF1dGgiLCJtYXN0ZXIiLCJ1bmRlZmluZWQiLCJjbGllbnRTREsiLCJjb250ZXh0IiwidGhlbiIsInJlc3BvbnNlIiwicmVzdWx0cyIsImxlbmd0aCIsImhhbmRsZVVwZGF0ZVRvUmV2b2NhYmxlU2Vzc2lvbiIsInVzZXIiLCJhdXRoIiwiT0JKRUNUX05PVF9GT1VORCIsInNlc3Npb25EYXRhIiwiY3JlYXRlU2Vzc2lvbiIsInVzZXJJZCIsImlkIiwiY3JlYXRlZFdpdGgiLCJhY3Rpb24iLCJpbnN0YWxsYXRpb25JZCIsImRhdGFiYXNlIiwidXBkYXRlIiwib2JqZWN0SWQiLCJfX29wIiwiUHJvbWlzZSIsInJlc29sdmUiLCJtb3VudFJvdXRlcyIsInJvdXRlIiwiaGFuZGxlRmluZCIsImhhbmRsZUdldCIsImhhbmRsZUNyZWF0ZSIsImhhbmRsZVVwZGF0ZSIsImhhbmRsZURlbGV0ZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRU8sTUFBTUEsY0FBTixTQUE2QkMsc0JBQTdCLENBQTJDO0FBQ2hEQyxFQUFBQSxTQUFTLEdBQUc7QUFDVixXQUFPLFVBQVA7QUFDRDs7QUFFREMsRUFBQUEsUUFBUSxDQUFDQyxHQUFELEVBQU07QUFDWjtBQUNBLFFBQUksQ0FBQ0EsR0FBRyxDQUFDQyxJQUFMLElBQWEsQ0FBQ0QsR0FBRyxDQUFDQyxJQUFKLENBQVNDLFlBQTNCLEVBQXlDO0FBQ3ZDLFlBQU0sSUFBSUMsY0FBTUMsS0FBVixDQUFnQkQsY0FBTUMsS0FBTixDQUFZQyxx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QUFJO0FBQ3JDLGFBQU8sS0FBS3VDLFlBQUwsQ0FBa0J2QyxHQUFsQixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUtvQyxLQUFMLENBQVcsS0FBWCxFQUFrQixxQkFBbEIsRUFBeUNwQyxHQUFHLElBQUk7QUFDOUMsYUFBTyxLQUFLd0MsWUFBTCxDQUFrQnhDLEdBQWxCLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBS29DLEtBQUwsQ0FBVyxRQUFYLEVBQXFCLHFCQUFyQixFQUE0Q3BDLEdBQUcsSUFBSTtBQUNqRCxhQUFPLEtBQUt5QyxZQUFMLENBQWtCekMsR0FBbEIsQ0FBUDtBQUNELEtBRkQ7QUFHQSxTQUFLb0MsS0FBTCxDQUFXLE1BQVgsRUFBbUIsNEJBQW5CLEVBQWlEcEMsR0FBRyxJQUFJO0FBQ3RELGFBQU8sS0FBS2tCLDhCQUFMLENBQW9DbEIsR0FBcEMsQ0FBUDtBQUNELEtBRkQ7QUFHRDs7QUF0RitDOzs7ZUF5Rm5DSixjIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IENsYXNzZXNSb3V0ZXIgZnJvbSAnLi9DbGFzc2VzUm91dGVyJztcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCByZXN0IGZyb20gJy4uL3Jlc3QnO1xuaW1wb3J0IEF1dGggZnJvbSAnLi4vQXV0aCc7XG5cbmV4cG9ydCBjbGFzcyBTZXNzaW9uc1JvdXRlciBleHRlbmRzIENsYXNzZXNSb3V0ZXIge1xuICBjbGFzc05hbWUoKSB7XG4gICAgcmV0dXJuICdfU2Vzc2lvbic7XG4gIH1cblxuICBoYW5kbGVNZShyZXEpIHtcbiAgICAvLyBUT0RPOiBWZXJpZnkgY29ycmVjdCBiZWhhdmlvclxuICAgIGlmICghcmVxLmluZm8gfHwgIXJlcS5pbmZvLnNlc3Npb25Ub2tlbikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTiwgJ1Nlc3Npb24gdG9rZW4gcmVxdWlyZWQuJyk7XG4gICAgfVxuICAgIHJldHVybiByZXN0XG4gICAgICAuZmluZChcbiAgICAgICAgcmVxLmNvbmZpZyxcbiAgICAgICAgQXV0aC5tYXN0ZXIocmVxLmNvbmZpZyksXG4gICAgICAgICdfU2Vzc2lvbicsXG4gICAgICAgIHsgc2Vzc2lvblRva2VuOiByZXEuaW5mby5zZXNzaW9uVG9rZW4gfSxcbiAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICByZXEuaW5mby5jbGllbnRTREssXG4gICAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgaWYgKCFyZXNwb25zZS5yZXN1bHRzIHx8IHJlc3BvbnNlLnJlc3VsdHMubGVuZ3RoID09IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOLCAnU2Vzc2lvbiB0b2tlbiBub3QgZm91bmQuJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICByZXNwb25zZTogcmVzcG9uc2UucmVzdWx0c1swXSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICB9XG5cbiAgaGFuZGxlVXBkYXRlVG9SZXZvY2FibGVTZXNzaW9uKHJlcSkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHJlcS5jb25maWc7XG4gICAgY29uc3QgdXNlciA9IHJlcS5hdXRoLnVzZXI7XG4gICAgLy8gSXNzdWUgIzI3MjBcbiAgICAvLyBDYWxsaW5nIHdpdGhvdXQgYSBzZXNzaW9uIHRva2VuIHdvdWxkIHJlc3VsdCBpbiBhIG5vdCBmb3VuZCB1c2VyXG4gICAgaWYgKCF1c2VyKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ2ludmFsaWQgc2Vzc2lvbicpO1xuICAgIH1cbiAgICBjb25zdCB7IHNlc3Npb25EYXRhLCBjcmVhdGVTZXNzaW9uIH0gPSBBdXRoLmNyZWF0ZVNlc3Npb24oY29uZmlnLCB7XG4gICAgICB1c2VySWQ6IHVzZXIuaWQsXG4gICAgICBjcmVhdGVkV2l0aDoge1xuICAgICAgICBhY3Rpb246ICd1cGdyYWRlJyxcbiAgICAgIH0sXG4gICAgICBpbnN0YWxsYXRpb25JZDogcmVxLmF1dGguaW5zdGFsbGF0aW9uSWQsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gY3JlYXRlU2Vzc2lvbigpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIC8vIGRlbGV0ZSB0aGUgc2Vzc2lvbiB0b2tlbiwgdXNlIHRoZSBkYiB0byBza2lwIGJlZm9yZVNhdmVcbiAgICAgICAgcmV0dXJuIGNvbmZpZy5kYXRhYmFzZS51cGRhdGUoXG4gICAgICAgICAgJ19Vc2VyJyxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBvYmplY3RJZDogdXNlci5pZCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNlc3Npb25Ub2tlbjogeyBfX29wOiAnRGVsZXRlJyB9LFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoeyByZXNwb25zZTogc2Vzc2lvbkRhdGEgfSk7XG4gICAgICB9KTtcbiAgfVxuXG4gIG1vdW50Um91dGVzKCkge1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvc2Vzc2lvbnMvbWUnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTWUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3Nlc3Npb25zJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZpbmQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3Nlc3Npb25zLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9zZXNzaW9ucycsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVDcmVhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQVVQnLCAnL3Nlc3Npb25zLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVVcGRhdGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdERUxFVEUnLCAnL3Nlc3Npb25zLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVEZWxldGUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy91cGdyYWRlVG9SZXZvY2FibGVTZXNzaW9uJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZVVwZGF0ZVRvUmV2b2NhYmxlU2Vzc2lvbihyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFNlc3Npb25zUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/Routers/UsersRouter.js b/lib/Routers/UsersRouter.js deleted file mode 100644 index c37fdc404f..0000000000 --- a/lib/Routers/UsersRouter.js +++ /dev/null @@ -1,470 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.UsersRouter = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _Config = _interopRequireDefault(require("../Config")); - -var _AccountLockout = _interopRequireDefault(require("../AccountLockout")); - -var _ClassesRouter = _interopRequireDefault(require("./ClassesRouter")); - -var _rest = _interopRequireDefault(require("../rest")); - -var _Auth = _interopRequireDefault(require("../Auth")); - -var _password = _interopRequireDefault(require("../password")); - -var _triggers = require("../triggers"); - -var _middlewares = require("../middlewares"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -class UsersRouter extends _ClassesRouter.default { - className() { - return '_User'; - } - /** - * Removes all "_" prefixed properties from an object, except "__type" - * @param {Object} obj An object. - */ - - - static removeHiddenProperties(obj) { - for (var key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - // Regexp comes from Parse.Object.prototype.validate - if (key !== '__type' && !/^[A-Za-z][0-9A-Za-z_]*$/.test(key)) { - delete obj[key]; - } - } - } - } - /** - * Validates a password request in login and verifyPassword - * @param {Object} req The request - * @returns {Object} User object - * @private - */ - - - _authenticateUserFromRequest(req) { - return new Promise((resolve, reject) => { - // Use query parameters instead if provided in url - let payload = req.body; - - if (!payload.username && req.query && req.query.username || !payload.email && req.query && req.query.email) { - payload = req.query; - } - - const { - username, - email, - password - } = payload; // TODO: use the right error codes / descriptions. - - if (!username && !email) { - throw new _node.default.Error(_node.default.Error.USERNAME_MISSING, 'username/email is required.'); - } - - if (!password) { - throw new _node.default.Error(_node.default.Error.PASSWORD_MISSING, 'password is required.'); - } - - if (typeof password !== 'string' || email && typeof email !== 'string' || username && typeof username !== 'string') { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); - } - - let user; - let isValidPassword = false; - let query; - - if (email && username) { - query = { - email, - username - }; - } else if (email) { - query = { - email - }; - } else { - query = { - $or: [{ - username - }, { - email: username - }] - }; - } - - return req.config.database.find('_User', query).then(results => { - if (!results.length) { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); - } - - if (results.length > 1) { - // corner case where user1 has username == user2 email - req.config.loggerController.warn("There is a user which email is the same as another user's username, logging in based on username"); - user = results.filter(user => user.username === username)[0]; - } else { - user = results[0]; - } - - return _password.default.compare(password, user.password); - }).then(correct => { - isValidPassword = correct; - const accountLockoutPolicy = new _AccountLockout.default(user, req.config); - return accountLockoutPolicy.handleLoginAttempt(isValidPassword); - }).then(() => { - if (!isValidPassword) { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); - } // Ensure the user isn't locked out - // A locked out user won't be able to login - // To lock a user out, just set the ACL to `masterKey` only ({}). - // Empty ACL is OK - - - if (!req.auth.isMaster && user.ACL && Object.keys(user.ACL).length == 0) { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); - } - - if (req.config.verifyUserEmails && req.config.preventLoginWithUnverifiedEmail && !user.emailVerified) { - throw new _node.default.Error(_node.default.Error.EMAIL_NOT_FOUND, 'User email is not verified.'); - } - - delete user.password; // Sometimes the authData still has null on that keys - // https://github.com/parse-community/parse-server/issues/935 - - if (user.authData) { - Object.keys(user.authData).forEach(provider => { - if (user.authData[provider] === null) { - delete user.authData[provider]; - } - }); - - if (Object.keys(user.authData).length == 0) { - delete user.authData; - } - } - - return resolve(user); - }).catch(error => { - return reject(error); - }); - }); - } - /** - * Validates JWT bearer token and looks up user `req.userFromJWT`. CRITICALLY IMPORTANT that the JWT has already been validated by this point (eg: express middleware, AWS API Gateway Authorizer) - * @param {Object} req The request - * @returns {Object} User object - */ - - - _authenticateUserFromRequestWithJwt(req) { - return new Promise((resolve, reject) => { - if (!req.userFromJWT) { - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid credentials.'); - } - - const query = { - objectId: req.userFromJWT.id - }; - return req.config.database.find('_User', query).then(results => { - if (!results.length) throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Invalid credentials.'); - const user = results[0]; - resolve(user); - }).catch(error => { - return reject(error); - }); - }); - } - - handleMe(req) { - if (!req.info || !req.info.sessionToken) { - throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); - } - - const sessionToken = req.info.sessionToken; - return _rest.default.find(req.config, _Auth.default.master(req.config), '_Session', { - sessionToken - }, { - include: 'user' - }, req.info.clientSDK, req.info.context).then(response => { - if (!response.results || response.results.length == 0 || !response.results[0].user) { - throw new _node.default.Error(_node.default.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); - } else { - const user = response.results[0].user; // Send token back on the login, because SDKs expect that. - - user.sessionToken = sessionToken; // Remove hidden properties. - - UsersRouter.removeHiddenProperties(user); - return { - response: user - }; - } - }); - } - - async handleLogIn(req) { - let userFromJWT; - - if (req.userFromJWT) { - // Could be just used `req.userFromJWT`, but the forced lookup - // Ensures the user hasn't been deleted since the the JWT was granted - userFromJWT = await this._authenticateUserFromRequestWithJwt(req); - } - - const user = userFromJWT || (await this._authenticateUserFromRequest(req)); // handle password expiry policy - ignore if user is managed in SSO (provided by JWT) - - if (!userFromJWT && req.config.passwordPolicy && req.config.passwordPolicy.maxPasswordAge) { - let changedAt = user._password_changed_at; - - if (!changedAt) { - // password was created before expiry policy was enabled. - // simply update _User object so that it will start enforcing from now - changedAt = new Date(); - req.config.database.update('_User', { - username: user.username - }, { - _password_changed_at: _node.default._encode(changedAt) - }); - } else { - // check whether the password has expired - if (changedAt.__type == 'Date') { - changedAt = new Date(changedAt.iso); - } // Calculate the expiry time. - - - const expiresAt = new Date(changedAt.getTime() + 86400000 * req.config.passwordPolicy.maxPasswordAge); - if (expiresAt < new Date()) // fail of current time is past password expiry time - throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Your password has expired. Please reset your password.'); - } - } // Remove hidden properties. - - - UsersRouter.removeHiddenProperties(user); - req.config.filesController.expandFilesInObject(req.config, user); // Before login trigger; throws if failure - - await (0, _triggers.maybeRunTrigger)(_triggers.Types.beforeLogin, req.auth, _node.default.User.fromJSON(Object.assign({ - className: '_User' - }, user)), null, req.config); - - const { - sessionData, - createSession - } = _Auth.default.createSession(req.config, { - userId: user.objectId, - createdWith: { - action: 'login', - authProvider: 'password' - }, - installationId: req.info.installationId - }); - - user.sessionToken = sessionData.sessionToken; - await createSession(); - - const afterLoginUser = _node.default.User.fromJSON(Object.assign({ - className: '_User' - }, user)); - - (0, _triggers.maybeRunTrigger)(_triggers.Types.afterLogin, _objectSpread(_objectSpread({}, req.auth), {}, { - user: afterLoginUser - }), afterLoginUser, null, req.config); - return { - response: user - }; - } - - handleVerifyPassword(req) { - return this._authenticateUserFromRequest(req).then(user => { - // Remove hidden properties. - UsersRouter.removeHiddenProperties(user); - return { - response: user - }; - }).catch(error => { - throw error; - }); - } - - handleLogOut(req) { - const success = { - response: {} - }; - - if (req.info && req.info.sessionToken) { - return _rest.default.find(req.config, _Auth.default.master(req.config), '_Session', { - sessionToken: req.info.sessionToken - }, undefined, req.info.clientSDK, req.info.context).then(records => { - if (records.results && records.results.length) { - return _rest.default.del(req.config, _Auth.default.master(req.config), '_Session', records.results[0].objectId, req.info.context).then(() => { - this._runAfterLogoutTrigger(req, records.results[0]); - - return Promise.resolve(success); - }); - } - - return Promise.resolve(success); - }); - } - - return Promise.resolve(success); - } - - _runAfterLogoutTrigger(req, session) { - // After logout trigger - (0, _triggers.maybeRunTrigger)(_triggers.Types.afterLogout, req.auth, _node.default.Session.fromJSON(Object.assign({ - className: '_Session' - }, session)), null, req.config); - } - - _throwOnBadEmailConfig(req) { - try { - _Config.default.validateEmailConfiguration({ - emailAdapter: req.config.userController.adapter, - appName: req.config.appName, - publicServerURL: req.config.publicServerURL, - emailVerifyTokenValidityDuration: req.config.emailVerifyTokenValidityDuration, - emailVerifyTokenReuseIfValid: req.config.emailVerifyTokenReuseIfValid - }); - } catch (e) { - if (typeof e === 'string') { - // Maybe we need a Bad Configuration error, but the SDKs won't understand it. For now, Internal Server Error. - throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'An appName, publicServerURL, and emailAdapter are required for password reset and email verification functionality.'); - } else { - throw e; - } - } - } - - handleResetRequest(req) { - this._throwOnBadEmailConfig(req); - - const { - email - } = req.body; - - if (!email) { - throw new _node.default.Error(_node.default.Error.EMAIL_MISSING, 'you must provide an email'); - } - - if (typeof email !== 'string') { - throw new _node.default.Error(_node.default.Error.INVALID_EMAIL_ADDRESS, 'you must provide a valid email string'); - } - - const userController = req.config.userController; - return userController.sendPasswordResetEmail(email).then(() => { - return Promise.resolve({ - response: {} - }); - }, err => { - if (err.code === _node.default.Error.OBJECT_NOT_FOUND) { - // Return success so that this endpoint can't - // be used to enumerate valid emails - return Promise.resolve({ - response: {} - }); - } else { - throw err; - } - }); - } - - handleVerificationEmailRequest(req) { - this._throwOnBadEmailConfig(req); - - const { - email - } = req.body; - - if (!email) { - throw new _node.default.Error(_node.default.Error.EMAIL_MISSING, 'you must provide an email'); - } - - if (typeof email !== 'string') { - throw new _node.default.Error(_node.default.Error.INVALID_EMAIL_ADDRESS, 'you must provide a valid email string'); - } - - return req.config.database.find('_User', { - email: email - }).then(results => { - if (!results.length || results.length < 1) { - throw new _node.default.Error(_node.default.Error.EMAIL_NOT_FOUND, `No user found with email ${email}`); - } - - const user = results[0]; // remove password field, messes with saving on postgres - - delete user.password; - - if (user.emailVerified) { - throw new _node.default.Error(_node.default.Error.OTHER_CAUSE, `Email ${email} is already verified.`); - } - - const userController = req.config.userController; - return userController.regenerateEmailVerifyToken(user).then(() => { - userController.sendVerificationEmail(user); - return { - response: {} - }; - }); - }); - } - - mountRoutes() { - this.route('GET', '/users', req => { - return this.handleFind(req); - }); - this.route('POST', '/users', _middlewares.promiseEnsureIdempotency, req => { - return this.handleCreate(req); - }); - this.route('GET', '/users/me', req => { - return this.handleMe(req); - }); - this.route('GET', '/users/:objectId', req => { - return this.handleGet(req); - }); - this.route('PUT', '/users/:objectId', _middlewares.promiseEnsureIdempotency, req => { - return this.handleUpdate(req); - }); - this.route('DELETE', '/users/:objectId', req => { - return this.handleDelete(req); - }); - this.route('GET', '/login', req => { - return this.handleLogIn(req); - }); - this.route('POST', '/login', req => { - return this.handleLogIn(req); - }); - this.route('POST', '/logout', req => { - return this.handleLogOut(req); - }); - this.route('POST', '/requestPasswordReset', req => { - return this.handleResetRequest(req); - }); - this.route('POST', '/verificationEmailRequest', req => { - return this.handleVerificationEmailRequest(req); - }); - this.route('GET', '/verifyPassword', req => { - return this.handleVerifyPassword(req); - }); - } - -} - -exports.UsersRouter = UsersRouter; -var _default = UsersRouter; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Sb3V0ZXJzL1VzZXJzUm91dGVyLmpzIl0sIm5hbWVzIjpbIlVzZXJzUm91dGVyIiwiQ2xhc3Nlc1JvdXRlciIsImNsYXNzTmFtZSIsInJlbW92ZUhpZGRlblByb3BlcnRpZXMiLCJvYmoiLCJrZXkiLCJPYmplY3QiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJ0ZXN0IiwiX2F1dGhlbnRpY2F0ZVVzZXJGcm9tUmVxdWVzdCIsInJlcSIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwicGF5bG9hZCIsImJvZHkiLCJ1c2VybmFtZSIsInF1ZXJ5IiwiZW1haWwiLCJwYXNzd29yZCIsIlBhcnNlIiwiRXJyb3IiLCJVU0VSTkFNRV9NSVNTSU5HIiwiUEFTU1dPUkRfTUlTU0lORyIsIk9CSkVDVF9OT1RfRk9VTkQiLCJ1c2VyIiwiaXNWYWxpZFBhc3N3b3JkIiwiJG9yIiwiY29uZmlnIiwiZGF0YWJhc2UiLCJmaW5kIiwidGhlbiIsInJlc3VsdHMiLCJsZW5ndGgiLCJsb2dnZXJDb250cm9sbGVyIiwid2FybiIsImZpbHRlciIsInBhc3N3b3JkQ3J5cHRvIiwiY29tcGFyZSIsImNvcnJlY3QiLCJhY2NvdW50TG9ja291dFBvbGljeSIsIkFjY291bnRMb2Nrb3V0IiwiaGFuZGxlTG9naW5BdHRlbXB0IiwiYXV0aCIsImlzTWFzdGVyIiwiQUNMIiwia2V5cyIsInZlcmlmeVVzZXJFbWFpbHMiLCJwcmV2ZW50TG9naW5XaXRoVW52ZXJpZmllZEVtYWlsIiwiZW1haWxWZXJpZmllZCIsIkVNQUlMX05PVF9GT1VORCIsImF1dGhEYXRhIiwiZm9yRWFjaCIsInByb3ZpZGVyIiwiY2F0Y2giLCJlcnJvciIsIl9hdXRoZW50aWNhdGVVc2VyRnJvbVJlcXVlc3RXaXRoSnd0IiwidXNlckZyb21KV1QiLCJvYmplY3RJZCIsImlkIiwiaGFuZGxlTWUiLCJpbmZvIiwic2Vzc2lvblRva2VuIiwiSU5WQUxJRF9TRVNTSU9OX1RPS0VOIiwicmVzdCIsIkF1dGgiLCJtYXN0ZXIiLCJpbmNsdWRlIiwiY2xpZW50U0RLIiwiY29udGV4dCIsInJlc3BvbnNlIiwiaGFuZGxlTG9nSW4iLCJwYXNzd29yZFBvbGljeSIsIm1heFBhc3N3b3JkQWdlIiwiY2hhbmdlZEF0IiwiX3Bhc3N3b3JkX2NoYW5nZWRfYXQiLCJEYXRlIiwidXBkYXRlIiwiX2VuY29kZSIsIl9fdHlwZSIsImlzbyIsImV4cGlyZXNBdCIsImdldFRpbWUiLCJmaWxlc0NvbnRyb2xsZXIiLCJleHBhbmRGaWxlc0luT2JqZWN0IiwiVHJpZ2dlclR5cGVzIiwiYmVmb3JlTG9naW4iLCJVc2VyIiwiZnJvbUpTT04iLCJhc3NpZ24iLCJzZXNzaW9uRGF0YSIsImNyZWF0ZVNlc3Npb24iLCJ1c2VySWQiLCJjcmVhdGVkV2l0aCIsImFjdGlvbiIsImF1dGhQcm92aWRlciIsImluc3RhbGxhdGlvbklkIiwiYWZ0ZXJMb2dpblVzZXIiLCJhZnRlckxvZ2luIiwiaGFuZGxlVmVyaWZ5UGFzc3dvcmQiLCJoYW5kbGVMb2dPdXQiLCJzdWNjZXNzIiwidW5kZWZpbmVkIiwicmVjb3JkcyIsImRlbCIsIl9ydW5BZnRlckxvZ291dFRyaWdnZXIiLCJzZXNzaW9uIiwiYWZ0ZXJMb2dvdXQiLCJTZXNzaW9uIiwiX3Rocm93T25CYWRFbWFpbENvbmZpZyIsIkNvbmZpZyIsInZhbGlkYXRlRW1haWxDb25maWd1cmF0aW9uIiwiZW1haWxBZGFwdGVyIiwidXNlckNvbnRyb2xsZXIiLCJhZGFwdGVyIiwiYXBwTmFtZSIsInB1YmxpY1NlcnZlclVSTCIsImVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uIiwiZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZCIsImUiLCJJTlRFUk5BTF9TRVJWRVJfRVJST1IiLCJoYW5kbGVSZXNldFJlcXVlc3QiLCJFTUFJTF9NSVNTSU5HIiwiSU5WQUxJRF9FTUFJTF9BRERSRVNTIiwic2VuZFBhc3N3b3JkUmVzZXRFbWFpbCIsImVyciIsImNvZGUiLCJoYW5kbGVWZXJpZmljYXRpb25FbWFpbFJlcXVlc3QiLCJPVEhFUl9DQVVTRSIsInJlZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuIiwic2VuZFZlcmlmaWNhdGlvbkVtYWlsIiwibW91bnRSb3V0ZXMiLCJyb3V0ZSIsImhhbmRsZUZpbmQiLCJwcm9taXNlRW5zdXJlSWRlbXBvdGVuY3kiLCJoYW5kbGVDcmVhdGUiLCJoYW5kbGVHZXQiLCJoYW5kbGVVcGRhdGUiLCJoYW5kbGVEZWxldGUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFFQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7OztBQUVPLE1BQU1BLFdBQU4sU0FBMEJDLHNCQUExQixDQUF3QztBQUM3Q0MsRUFBQUEsU0FBUyxHQUFHO0FBQ1YsV0FBTyxPQUFQO0FBQ0Q7QUFFRDtBQUNGO0FBQ0E7QUFDQTs7O0FBQ0UsU0FBT0Msc0JBQVAsQ0FBOEJDLEdBQTlCLEVBQW1DO0FBQ2pDLFNBQUssSUFBSUMsR0FBVCxJQUFnQkQsR0FBaEIsRUFBcUI7QUFDbkIsVUFBSUUsTUFBTSxDQUFDQyxTQUFQLENBQWlCQyxjQUFqQixDQUFnQ0MsSUFBaEMsQ0FBcUNMLEdBQXJDLEVBQTBDQyxHQUExQyxDQUFKLEVBQW9EO0FBQ2xEO0FBQ0EsWUFBSUEsR0FBRyxLQUFLLFFBQVIsSUFBb0IsQ0FBQywwQkFBMEJLLElBQTFCLENBQStCTCxHQUEvQixDQUF6QixFQUE4RDtBQUM1RCxpQkFBT0QsR0FBRyxDQUFDQyxHQUFELENBQVY7QUFDRDtBQUNGO0FBQ0Y7QUFDRjtBQUVEO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0VNLEVBQUFBLDRCQUE0QixDQUFDQyxHQUFELEVBQU07QUFDaEMsV0FBTyxJQUFJQyxPQUFKLENBQVksQ0FBQ0MsT0FBRCxFQUFVQyxNQUFWLEtBQXFCO0FBQ3RDO0FBQ0EsVUFBSUMsT0FBTyxHQUFHSixHQUFHLENBQUNLLElBQWxCOztBQUNBLFVBQ0csQ0FBQ0QsT0FBTyxDQUFDRSxRQUFU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RUFBbUIsUUFBbkIsRUFBNkIxSCxHQUFHLElBQUk7QUFDbEMsYUFBTyxLQUFLNkQsV0FBTCxDQUFpQjdELEdBQWpCLENBQVA7QUFDRCxLQUZEO0FBR0EsU0FBSzBILEtBQUwsQ0FBVyxNQUFYLEVBQW1CLFNBQW5CLEVBQThCMUgsR0FBRyxJQUFJO0FBQ25DLGFBQU8sS0FBSzBGLFlBQUwsQ0FBa0IxRixHQUFsQixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUswSCxLQUFMLENBQVcsTUFBWCxFQUFtQix1QkFBbkIsRUFBNEMxSCxHQUFHLElBQUk7QUFDakQsYUFBTyxLQUFLK0csa0JBQUwsQ0FBd0IvRyxHQUF4QixDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUswSCxLQUFMLENBQVcsTUFBWCxFQUFtQiwyQkFBbkIsRUFBZ0QxSCxHQUFHLElBQUk7QUFDckQsYUFBTyxLQUFLcUgsOEJBQUwsQ0FBb0NySCxHQUFwQyxDQUFQO0FBQ0QsS0FGRDtBQUdBLFNBQUswSCxLQUFMLENBQVcsS0FBWCxFQUFrQixpQkFBbEIsRUFBcUMxSCxHQUFHLElBQUk7QUFDMUMsYUFBTyxLQUFLeUYsb0JBQUwsQ0FBMEJ6RixHQUExQixDQUFQO0FBQ0QsS0FGRDtBQUdEOztBQXRjNEM7OztlQXljaENaLFciLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGVzZSBtZXRob2RzIGhhbmRsZSB0aGUgVXNlci1yZWxhdGVkIHJvdXRlcy5cblxuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuLi9Db25maWcnO1xuaW1wb3J0IEFjY291bnRMb2Nrb3V0IGZyb20gJy4uL0FjY291bnRMb2Nrb3V0JztcbmltcG9ydCBDbGFzc2VzUm91dGVyIGZyb20gJy4vQ2xhc3Nlc1JvdXRlcic7XG5pbXBvcnQgcmVzdCBmcm9tICcuLi9yZXN0JztcbmltcG9ydCBBdXRoIGZyb20gJy4uL0F1dGgnO1xuaW1wb3J0IHBhc3N3b3JkQ3J5cHRvIGZyb20gJy4uL3Bhc3N3b3JkJztcbmltcG9ydCB7IG1heWJlUnVuVHJpZ2dlciwgVHlwZXMgYXMgVHJpZ2dlclR5cGVzIH0gZnJvbSAnLi4vdHJpZ2dlcnMnO1xuaW1wb3J0IHsgcHJvbWlzZUVuc3VyZUlkZW1wb3RlbmN5IH0gZnJvbSAnLi4vbWlkZGxld2FyZXMnO1xuXG5leHBvcnQgY2xhc3MgVXNlcnNSb3V0ZXIgZXh0ZW5kcyBDbGFzc2VzUm91dGVyIHtcbiAgY2xhc3NOYW1lKCkge1xuICAgIHJldHVybiAnX1VzZXInO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYWxsIFwiX1wiIHByZWZpeGVkIHByb3BlcnRpZXMgZnJvbSBhbiBvYmplY3QsIGV4Y2VwdCBcIl9fdHlwZVwiXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvYmogQW4gb2JqZWN0LlxuICAgKi9cbiAgc3RhdGljIHJlbW92ZUhpZGRlblByb3BlcnRpZXMob2JqKSB7XG4gICAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkpIHtcbiAgICAgICAgLy8gUmVnZXhwIGNvbWVzIGZyb20gUGFyc2UuT2JqZWN0LnByb3RvdHlwZS52YWxpZGF0ZVxuICAgICAgICBpZiAoa2V5ICE9PSAnX190eXBlJyAmJiAhL15bQS1aYS16XVswLTlBLVphLXpfXSokLy50ZXN0KGtleSkpIHtcbiAgICAgICAgICBkZWxldGUgb2JqW2tleV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGVzIGEgcGFzc3dvcmQgcmVxdWVzdCBpbiBsb2dpbiBhbmQgdmVyaWZ5UGFzc3dvcmRcbiAgICogQHBhcmFtIHtPYmplY3R9IHJlcSBUaGUgcmVxdWVzdFxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBVc2VyIG9iamVjdFxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgX2F1dGhlbnRpY2F0ZVVzZXJGcm9tUmVxdWVzdChyZXEpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgLy8gVXNlIHF1ZXJ5IHBhcmFtZXRlcnMgaW5zdGVhZCBpZiBwcm92aWRlZCBpbiB1cmxcbiAgICAgIGxldCBwYXlsb2FkID0gcmVxLmJvZHk7XG4gICAgICBpZiAoXG4gICAgICAgICghcGF5bG9hZC51c2VybmFtZSAmJiByZXEucXVlcnkgJiYgcmVxLnF1ZXJ5LnVzZXJuYW1lKSB8fFxuICAgICAgICAoIXBheWxvYWQuZW1haWwgJiYgcmVxLnF1ZXJ5ICYmIHJlcS5xdWVyeS5lbWFpbClcbiAgICAgICkge1xuICAgICAgICBwYXlsb2FkID0gcmVxLnF1ZXJ5O1xuICAgICAgfVxuICAgICAgY29uc3QgeyB1c2VybmFtZSwgZW1haWwsIHBhc3N3b3JkIH0gPSBwYXlsb2FkO1xuXG4gICAgICAvLyBUT0RPOiB1c2UgdGhlIHJpZ2h0IGVycm9yIGNvZGVzIC8gZGVzY3JpcHRpb25zLlxuICAgICAgaWYgKCF1c2VybmFtZSAmJiAhZW1haWwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlVTRVJOQU1FX01JU1NJTkcsICd1c2VybmFtZS9lbWFpbCBpcyByZXF1aXJlZC4nKTtcbiAgICAgIH1cbiAgICAgIGlmICghcGFzc3dvcmQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlBBU1NXT1JEX01JU1NJTkcsICdwYXNzd29yZCBpcyByZXF1aXJlZC4nKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgdHlwZW9mIHBhc3N3b3JkICE9PSAnc3RyaW5nJyB8fFxuICAgICAgICAoZW1haWwgJiYgdHlwZW9mIGVtYWlsICE9PSAnc3RyaW5nJykgfHxcbiAgICAgICAgKHVzZXJuYW1lICYmIHR5cGVvZiB1c2VybmFtZSAhPT0gJ3N0cmluZycpXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdJbnZhbGlkIHVzZXJuYW1lL3Bhc3N3b3JkLicpO1xuICAgICAgfVxuXG4gICAgICBsZXQgdXNlcjtcbiAgICAgIGxldCBpc1ZhbGlkUGFzc3dvcmQgPSBmYWxzZTtcbiAgICAgIGxldCBxdWVyeTtcbiAgICAgIGlmIChlbWFpbCAmJiB1c2VybmFtZSkge1xuICAgICAgICBxdWVyeSA9IHsgZW1haWwsIHVzZXJuYW1lIH07XG4gICAgICB9IGVsc2UgaWYgKGVtYWlsKSB7XG4gICAgICAgIHF1ZXJ5ID0geyBlbWFpbCB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcXVlcnkgPSB7ICRvcjogW3sgdXNlcm5hbWUgfSwgeyBlbWFpbDogdXNlcm5hbWUgfV0gfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXEuY29uZmlnLmRhdGFiYXNlXG4gICAgICAgIC5maW5kKCdfVXNlcicsIHF1ZXJ5KVxuICAgICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgICBpZiAoIXJlc3VsdHMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0ludmFsaWQgdXNlcm5hbWUvcGFzc3dvcmQuJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgLy8gY29ybmVyIGNhc2Ugd2hlcmUgdXNlcjEgaGFzIHVzZXJuYW1lID09IHVzZXIyIGVtYWlsXG4gICAgICAgICAgICByZXEuY29uZmlnLmxvZ2dlckNvbnRyb2xsZXIud2FybihcbiAgICAgICAgICAgICAgXCJUaGVyZSBpcyBhIHVzZXIgd2hpY2ggZW1haWwgaXMgdGhlIHNhbWUgYXMgYW5vdGhlciB1c2VyJ3MgdXNlcm5hbWUsIGxvZ2dpbmcgaW4gYmFzZWQgb24gdXNlcm5hbWVcIlxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHVzZXIgPSByZXN1bHRzLmZpbHRlcih1c2VyID0+IHVzZXIudXNlcm5hbWUgPT09IHVzZXJuYW1lKVswXTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdXNlciA9IHJlc3VsdHNbMF07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHBhc3N3b3JkQ3J5cHRvLmNvbXBhcmUocGFzc3dvcmQsIHVzZXIucGFzc3dvcmQpO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihjb3JyZWN0ID0+IHtcbiAgICAgICAgICBpc1ZhbGlkUGFzc3dvcmQgPSBjb3JyZWN0O1xuICAgICAgICAgIGNvbnN0IGFjY291bnRMb2Nrb3V0UG9saWN5ID0gbmV3IEFjY291bnRMb2Nrb3V0KHVzZXIsIHJlcS5jb25maWcpO1xuICAgICAgICAgIHJldHVybiBhY2NvdW50TG9ja291dFBvbGljeS5oYW5kbGVMb2dpbkF0dGVtcHQoaXNWYWxpZFBhc3N3b3JkKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIGlmICghaXNWYWxpZFBhc3N3b3JkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0ludmFsaWQgdXNlcm5hbWUvcGFzc3dvcmQuJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIEVuc3VyZSB0aGUgdXNlciBpc24ndCBsb2NrZWQgb3V0XG4gICAgICAgICAgLy8gQSBsb2NrZWQgb3V0IHVzZXIgd29uJ3QgYmUgYWJsZSB0byBsb2dpblxuICAgICAgICAgIC8vIFRvIGxvY2sgYSB1c2VyIG91dCwganVzdCBzZXQgdGhlIEFDTCB0byBgbWFzdGVyS2V5YCBvbmx5ICAoe30pLlxuICAgICAgICAgIC8vIEVtcHR5IEFDTCBpcyBPS1xuICAgICAgICAgIGlmICghcmVxLmF1dGguaXNNYXN0ZXIgJiYgdXNlci5BQ0wgJiYgT2JqZWN0LmtleXModXNlci5BQ0wpLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0ludmFsaWQgdXNlcm5hbWUvcGFzc3dvcmQuJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHJlcS5jb25maWcudmVyaWZ5VXNlckVtYWlscyAmJlxuICAgICAgICAgICAgcmVxLmNvbmZpZy5wcmV2ZW50TG9naW5XaXRoVW52ZXJpZmllZEVtYWlsICYmXG4gICAgICAgICAgICAhdXNlci5lbWFpbFZlcmlmaWVkXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRU1BSUxfTk9UX0ZPVU5ELCAnVXNlciBlbWFpbCBpcyBub3QgdmVyaWZpZWQuJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZGVsZXRlIHVzZXIucGFzc3dvcmQ7XG5cbiAgICAgICAgICAvLyBTb21ldGltZXMgdGhlIGF1dGhEYXRhIHN0aWxsIGhhcyBudWxsIG9uIHRoYXQga2V5c1xuICAgICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9wYXJzZS1jb21tdW5pdHkvcGFyc2Utc2VydmVyL2lzc3Vlcy85MzVcbiAgICAgICAgICBpZiAodXNlci5hdXRoRGF0YSkge1xuICAgICAgICAgICAgT2JqZWN0LmtleXModXNlci5hdXRoRGF0YSkuZm9yRWFjaChwcm92aWRlciA9PiB7XG4gICAgICAgICAgICAgIGlmICh1c2VyLmF1dGhEYXRhW3Byb3ZpZGVyXSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB1c2VyLmF1dGhEYXRhW3Byb3ZpZGVyXTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoT2JqZWN0LmtleXModXNlci5hdXRoRGF0YSkubGVuZ3RoID09IDApIHtcbiAgICAgICAgICAgICAgZGVsZXRlIHVzZXIuYXV0aERhdGE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHJlc29sdmUodXNlcik7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBKV1QgYmVhcmVyIHRva2VuIGFuZCBsb29rcyB1cCB1c2VyIGByZXEudXNlckZyb21KV1RgLiBDUklUSUNBTExZIElNUE9SVEFOVCB0aGF0IHRoZSBKV1QgaGFzIGFscmVhZHkgYmVlbiB2YWxpZGF0ZWQgYnkgdGhpcyBwb2ludCAoZWc6IGV4cHJlc3MgbWlkZGxld2FyZSwgQVdTIEFQSSBHYXRld2F5IEF1dGhvcml6ZXIpXG4gICAqIEBwYXJhbSB7T2JqZWN0fSByZXEgVGhlIHJlcXVlc3RcbiAgICogQHJldHVybnMge09iamVjdH0gVXNlciBvYmplY3RcbiAgICovXG4gIF9hdXRoZW50aWNhdGVVc2VyRnJvbVJlcXVlc3RXaXRoSnd0KHJlcSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBpZiAoIXJlcS51c2VyRnJvbUpXVCkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0ludmFsaWQgY3JlZGVudGlhbHMuJyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHF1ZXJ5ID0ge1xuICAgICAgICBvYmplY3RJZDogcmVxLnVzZXJGcm9tSldULmlkLFxuICAgICAgfTtcbiAgICAgIHJldHVybiByZXEuY29uZmlnLmRhdGFiYXNlXG4gICAgICAgIC5maW5kKCdfVXNlcicsIHF1ZXJ5KVxuICAgICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgICBpZiAoIXJlc3VsdHMubGVuZ3RoKVxuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdJbnZhbGlkIGNyZWRlbnRpYWxzLicpO1xuICAgICAgICAgIGNvbnN0IHVzZXIgPSByZXN1bHRzWzBdO1xuICAgICAgICAgIHJlc29sdmUodXNlcik7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmV0dXJuIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgaGFuZGxlTWUocmVxKSB7XG4gICAgaWYgKCFyZXEuaW5mbyB8fCAhcmVxLmluZm8uc2Vzc2lvblRva2VuKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOLCAnSW52YWxpZCBzZXNzaW9uIHRva2VuJyk7XG4gICAgfVxuICAgIGNvbnN0IHNlc3Npb25Ub2tlbiA9IHJlcS5pbmZvLnNlc3Npb25Ub2tlbjtcbiAgICByZXR1cm4gcmVzdFxuICAgICAgLmZpbmQoXG4gICAgICAgIHJlcS5jb25maWcsXG4gICAgICAgIEF1dGgubWFzdGVyKHJlcS5jb25maWcpLFxuICAgICAgICAnX1Nlc3Npb24nLFxuICAgICAgICB7IHNlc3Npb25Ub2tlbiB9LFxuICAgICAgICB7IGluY2x1ZGU6ICd1c2VyJyB9LFxuICAgICAgICByZXEuaW5mby5jbGllbnRTREssXG4gICAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICAgIClcbiAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgaWYgKCFyZXNwb25zZS5yZXN1bHRzIHx8IHJlc3BvbnNlLnJlc3VsdHMubGVuZ3RoID09IDAgfHwgIXJlc3BvbnNlLnJlc3VsdHNbMF0udXNlcikge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1NFU1NJT05fVE9LRU4sICdJbnZhbGlkIHNlc3Npb24gdG9rZW4nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCB1c2VyID0gcmVzcG9uc2UucmVzdWx0c1swXS51c2VyO1xuICAgICAgICAgIC8vIFNlbmQgdG9rZW4gYmFjayBvbiB0aGUgbG9naW4sIGJlY2F1c2UgU0RLcyBleHBlY3QgdGhhdC5cbiAgICAgICAgICB1c2VyLnNlc3Npb25Ub2tlbiA9IHNlc3Npb25Ub2tlbjtcblxuICAgICAgICAgIC8vIFJlbW92ZSBoaWRkZW4gcHJvcGVydGllcy5cbiAgICAgICAgICBVc2Vyc1JvdXRlci5yZW1vdmVIaWRkZW5Qcm9wZXJ0aWVzKHVzZXIpO1xuXG4gICAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHVzZXIgfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICBhc3luYyBoYW5kbGVMb2dJbihyZXEpIHtcbiAgICBsZXQgdXNlckZyb21KV1Q7XG4gICAgaWYgKHJlcS51c2VyRnJvbUpXVCkge1xuICAgICAgLy8gQ291bGQgYmUganVzdCB1c2VkIGByZXEudXNlckZyb21KV1RgLCBidXQgdGhlIGZvcmNlZCBsb29rdXBcbiAgICAgIC8vIEVuc3VyZXMgdGhlIHVzZXIgaGFzbid0IGJlZW4gZGVsZXRlZCBzaW5jZSB0aGUgdGhlIEpXVCB3YXMgZ3JhbnRlZFxuICAgICAgdXNlckZyb21KV1QgPSBhd2FpdCB0aGlzLl9hdXRoZW50aWNhdGVVc2VyRnJvbVJlcXVlc3RXaXRoSnd0KHJlcSk7XG4gICAgfVxuXG4gICAgY29uc3QgdXNlciA9IHVzZXJGcm9tSldUIHx8IChhd2FpdCB0aGlzLl9hdXRoZW50aWNhdGVVc2VyRnJvbVJlcXVlc3QocmVxKSk7XG5cbiAgICAvLyBoYW5kbGUgcGFzc3dvcmQgZXhwaXJ5IHBvbGljeSAtIGlnbm9yZSBpZiB1c2VyIGlzIG1hbmFnZWQgaW4gU1NPIChwcm92aWRlZCBieSBKV1QpXG4gICAgaWYgKCF1c2VyRnJvbUpXVCAmJiByZXEuY29uZmlnLnBhc3N3b3JkUG9saWN5ICYmIHJlcS5jb25maWcucGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRBZ2UpIHtcbiAgICAgIGxldCBjaGFuZ2VkQXQgPSB1c2VyLl9wYXNzd29yZF9jaGFuZ2VkX2F0O1xuXG4gICAgICBpZiAoIWNoYW5nZWRBdCkge1xuICAgICAgICAvLyBwYXNzd29yZCB3YXMgY3JlYXRlZCBiZWZvcmUgZXhwaXJ5IHBvbGljeSB3YXMgZW5hYmxlZC5cbiAgICAgICAgLy8gc2ltcGx5IHVwZGF0ZSBfVXNlciBvYmplY3Qgc28gdGhhdCBpdCB3aWxsIHN0YXJ0IGVuZm9yY2luZyBmcm9tIG5vd1xuICAgICAgICBjaGFuZ2VkQXQgPSBuZXcgRGF0ZSgpO1xuICAgICAgICByZXEuY29uZmlnLmRhdGFiYXNlLnVwZGF0ZShcbiAgICAgICAgICAnX1VzZXInLFxuICAgICAgICAgIHsgdXNlcm5hbWU6IHVzZXIudXNlcm5hbWUgfSxcbiAgICAgICAgICB7IF9wYXNzd29yZF9jaGFuZ2VkX2F0OiBQYXJzZS5fZW5jb2RlKGNoYW5nZWRBdCkgfVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gY2hlY2sgd2hldGhlciB0aGUgcGFzc3dvcmQgaGFzIGV4cGlyZWRcbiAgICAgICAgaWYgKGNoYW5nZWRBdC5fX3R5cGUgPT0gJ0RhdGUnKSB7XG4gICAgICAgICAgY2hhbmdlZEF0ID0gbmV3IERhdGUoY2hhbmdlZEF0Lmlzbyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBleHBpcnkgdGltZS5cbiAgICAgICAgY29uc3QgZXhwaXJlc0F0ID0gbmV3IERhdGUoXG4gICAgICAgICAgY2hhbmdlZEF0LmdldFRpbWUoKSArIDg2NDAwMDAwICogcmVxLmNvbmZpZy5wYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEFnZVxuICAgICAgICApO1xuICAgICAgICBpZiAoZXhwaXJlc0F0IDwgbmV3IERhdGUoKSlcbiAgICAgICAgICAvLyBmYWlsIG9mIGN1cnJlbnQgdGltZSBpcyBwYXN0IHBhc3N3b3JkIGV4cGlyeSB0aW1lXG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCxcbiAgICAgICAgICAgICdZb3VyIHBhc3N3b3JkIGhhcyBleHBpcmVkLiBQbGVhc2UgcmVzZXQgeW91ciBwYXNzd29yZC4nXG4gICAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZW1vdmUgaGlkZGVuIHByb3BlcnRpZXMuXG4gICAgVXNlcnNSb3V0ZXIucmVtb3ZlSGlkZGVuUHJvcGVydGllcyh1c2VyKTtcblxuICAgIHJlcS5jb25maWcuZmlsZXNDb250cm9sbGVyLmV4cGFuZEZpbGVzSW5PYmplY3QocmVxLmNvbmZpZywgdXNlcik7XG5cbiAgICAvLyBCZWZvcmUgbG9naW4gdHJpZ2dlcjsgdGhyb3dzIGlmIGZhaWx1cmVcbiAgICBhd2FpdCBtYXliZVJ1blRyaWdnZXIoXG4gICAgICBUcmlnZ2VyVHlwZXMuYmVmb3JlTG9naW4sXG4gICAgICByZXEuYXV0aCxcbiAgICAgIFBhcnNlLlVzZXIuZnJvbUpTT04oT2JqZWN0LmFzc2lnbih7IGNsYXNzTmFtZTogJ19Vc2VyJyB9LCB1c2VyKSksXG4gICAgICBudWxsLFxuICAgICAgcmVxLmNvbmZpZ1xuICAgICk7XG5cbiAgICBjb25zdCB7IHNlc3Npb25EYXRhLCBjcmVhdGVTZXNzaW9uIH0gPSBBdXRoLmNyZWF0ZVNlc3Npb24ocmVxLmNvbmZpZywge1xuICAgICAgdXNlcklkOiB1c2VyLm9iamVjdElkLFxuICAgICAgY3JlYXRlZFdpdGg6IHtcbiAgICAgICAgYWN0aW9uOiAnbG9naW4nLFxuICAgICAgICBhdXRoUHJvdmlkZXI6ICdwYXNzd29yZCcsXG4gICAgICB9LFxuICAgICAgaW5zdGFsbGF0aW9uSWQ6IHJlcS5pbmZvLmluc3RhbGxhdGlvbklkLFxuICAgIH0pO1xuXG4gICAgdXNlci5zZXNzaW9uVG9rZW4gPSBzZXNzaW9uRGF0YS5zZXNzaW9uVG9rZW47XG5cbiAgICBhd2FpdCBjcmVhdGVTZXNzaW9uKCk7XG5cbiAgICBjb25zdCBhZnRlckxvZ2luVXNlciA9IFBhcnNlLlVzZXIuZnJvbUpTT04oT2JqZWN0LmFzc2lnbih7IGNsYXNzTmFtZTogJ19Vc2VyJyB9LCB1c2VyKSk7XG4gICAgbWF5YmVSdW5UcmlnZ2VyKFxuICAgICAgVHJpZ2dlclR5cGVzLmFmdGVyTG9naW4sXG4gICAgICB7IC4uLnJlcS5hdXRoLCB1c2VyOiBhZnRlckxvZ2luVXNlciB9LFxuICAgICAgYWZ0ZXJMb2dpblVzZXIsXG4gICAgICBudWxsLFxuICAgICAgcmVxLmNvbmZpZ1xuICAgICk7XG5cbiAgICByZXR1cm4geyByZXNwb25zZTogdXNlciB9O1xuICB9XG5cbiAgaGFuZGxlVmVyaWZ5UGFzc3dvcmQocmVxKSB7XG4gICAgcmV0dXJuIHRoaXMuX2F1dGhlbnRpY2F0ZVVzZXJGcm9tUmVxdWVzdChyZXEpXG4gICAgICAudGhlbih1c2VyID0+IHtcbiAgICAgICAgLy8gUmVtb3ZlIGhpZGRlbiBwcm9wZXJ0aWVzLlxuICAgICAgICBVc2Vyc1JvdXRlci5yZW1vdmVIaWRkZW5Qcm9wZXJ0aWVzKHVzZXIpO1xuXG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB1c2VyIH07XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcbiAgfVxuXG4gIGhhbmRsZUxvZ091dChyZXEpIHtcbiAgICBjb25zdCBzdWNjZXNzID0geyByZXNwb25zZToge30gfTtcbiAgICBpZiAocmVxLmluZm8gJiYgcmVxLmluZm8uc2Vzc2lvblRva2VuKSB7XG4gICAgICByZXR1cm4gcmVzdFxuICAgICAgICAuZmluZChcbiAgICAgICAgICByZXEuY29uZmlnLFxuICAgICAgICAgIEF1dGgubWFzdGVyKHJlcS5jb25maWcpLFxuICAgICAgICAgICdfU2Vzc2lvbicsXG4gICAgICAgICAgeyBzZXNzaW9uVG9rZW46IHJlcS5pbmZvLnNlc3Npb25Ub2tlbiB9LFxuICAgICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgICByZXEuaW5mby5jbGllbnRTREssXG4gICAgICAgICAgcmVxLmluZm8uY29udGV4dFxuICAgICAgICApXG4gICAgICAgIC50aGVuKHJlY29yZHMgPT4ge1xuICAgICAgICAgIGlmIChyZWNvcmRzLnJlc3VsdHMgJiYgcmVjb3Jkcy5yZXN1bHRzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3RcbiAgICAgICAgICAgICAgLmRlbChcbiAgICAgICAgICAgICAgICByZXEuY29uZmlnLFxuICAgICAgICAgICAgICAgIEF1dGgubWFzdGVyKHJlcS5jb25maWcpLFxuICAgICAgICAgICAgICAgICdfU2Vzc2lvbicsXG4gICAgICAgICAgICAgICAgcmVjb3Jkcy5yZXN1bHRzWzBdLm9iamVjdElkLFxuICAgICAgICAgICAgICAgIHJlcS5pbmZvLmNvbnRleHRcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcnVuQWZ0ZXJMb2dvdXRUcmlnZ2VyKHJlcSwgcmVjb3Jkcy5yZXN1bHRzWzBdKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHN1Y2Nlc3MpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShzdWNjZXNzKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoc3VjY2Vzcyk7XG4gIH1cblxuICBfcnVuQWZ0ZXJMb2dvdXRUcmlnZ2VyKHJlcSwgc2Vzc2lvbikge1xuICAgIC8vIEFmdGVyIGxvZ291dCB0cmlnZ2VyXG4gICAgbWF5YmVSdW5UcmlnZ2VyKFxuICAgICAgVHJpZ2dlclR5cGVzLmFmdGVyTG9nb3V0LFxuICAgICAgcmVxLmF1dGgsXG4gICAgICBQYXJzZS5TZXNzaW9uLmZyb21KU09OKE9iamVjdC5hc3NpZ24oeyBjbGFzc05hbWU6ICdfU2Vzc2lvbicgfSwgc2Vzc2lvbikpLFxuICAgICAgbnVsbCxcbiAgICAgIHJlcS5jb25maWdcbiAgICApO1xuICB9XG5cbiAgX3Rocm93T25CYWRFbWFpbENvbmZpZyhyZXEpIHtcbiAgICB0cnkge1xuICAgICAgQ29uZmlnLnZhbGlkYXRlRW1haWxDb25maWd1cmF0aW9uKHtcbiAgICAgICAgZW1haWxBZGFwdGVyOiByZXEuY29uZmlnLnVzZXJDb250cm9sbGVyLmFkYXB0ZXIsXG4gICAgICAgIGFwcE5hbWU6IHJlcS5jb25maWcuYXBwTmFtZSxcbiAgICAgICAgcHVibGljU2VydmVyVVJMOiByZXEuY29uZmlnLnB1YmxpY1NlcnZlclVSTCxcbiAgICAgICAgZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb246IHJlcS5jb25maWcuZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24sXG4gICAgICAgIGVtYWlsVmVyaWZ5VG9rZW5SZXVzZUlmVmFsaWQ6IHJlcS5jb25maWcuZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZCxcbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmICh0eXBlb2YgZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgLy8gTWF5YmUgd2UgbmVlZCBhIEJhZCBDb25maWd1cmF0aW9uIGVycm9yLCBidXQgdGhlIFNES3Mgd29uJ3QgdW5kZXJzdGFuZCBpdC4gRm9yIG5vdywgSW50ZXJuYWwgU2VydmVyIEVycm9yLlxuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLFxuICAgICAgICAgICdBbiBhcHBOYW1lLCBwdWJsaWNTZXJ2ZXJVUkwsIGFuZCBlbWFpbEFkYXB0ZXIgYXJlIHJlcXVpcmVkIGZvciBwYXNzd29yZCByZXNldCBhbmQgZW1haWwgdmVyaWZpY2F0aW9uIGZ1bmN0aW9uYWxpdHkuJ1xuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBoYW5kbGVSZXNldFJlcXVlc3QocmVxKSB7XG4gICAgdGhpcy5fdGhyb3dPbkJhZEVtYWlsQ29uZmlnKHJlcSk7XG5cbiAgICBjb25zdCB7IGVtYWlsIH0gPSByZXEuYm9keTtcbiAgICBpZiAoIWVtYWlsKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRU1BSUxfTUlTU0lORywgJ3lvdSBtdXN0IHByb3ZpZGUgYW4gZW1haWwnKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBlbWFpbCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9FTUFJTF9BRERSRVNTLFxuICAgICAgICAneW91IG11c3QgcHJvdmlkZSBhIHZhbGlkIGVtYWlsIHN0cmluZydcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IHVzZXJDb250cm9sbGVyID0gcmVxLmNvbmZpZy51c2VyQ29udHJvbGxlcjtcbiAgICByZXR1cm4gdXNlckNvbnRyb2xsZXIuc2VuZFBhc3N3b3JkUmVzZXRFbWFpbChlbWFpbCkudGhlbihcbiAgICAgICgpID0+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICAgICAgcmVzcG9uc2U6IHt9LFxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICBlcnIgPT4ge1xuICAgICAgICBpZiAoZXJyLmNvZGUgPT09IFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQpIHtcbiAgICAgICAgICAvLyBSZXR1cm4gc3VjY2VzcyBzbyB0aGF0IHRoaXMgZW5kcG9pbnQgY2FuJ3RcbiAgICAgICAgICAvLyBiZSB1c2VkIHRvIGVudW1lcmF0ZSB2YWxpZCBlbWFpbHNcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgICAgIHJlc3BvbnNlOiB7fSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgaGFuZGxlVmVyaWZpY2F0aW9uRW1haWxSZXF1ZXN0KHJlcSkge1xuICAgIHRoaXMuX3Rocm93T25CYWRFbWFpbENvbmZpZyhyZXEpO1xuXG4gICAgY29uc3QgeyBlbWFpbCB9ID0gcmVxLmJvZHk7XG4gICAgaWYgKCFlbWFpbCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkVNQUlMX01JU1NJTkcsICd5b3UgbXVzdCBwcm92aWRlIGFuIGVtYWlsJyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZW1haWwgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfRU1BSUxfQUREUkVTUyxcbiAgICAgICAgJ3lvdSBtdXN0IHByb3ZpZGUgYSB2YWxpZCBlbWFpbCBzdHJpbmcnXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiByZXEuY29uZmlnLmRhdGFiYXNlLmZpbmQoJ19Vc2VyJywgeyBlbWFpbDogZW1haWwgfSkudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIGlmICghcmVzdWx0cy5sZW5ndGggfHwgcmVzdWx0cy5sZW5ndGggPCAxKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5FTUFJTF9OT1RfRk9VTkQsIGBObyB1c2VyIGZvdW5kIHdpdGggZW1haWwgJHtlbWFpbH1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHVzZXIgPSByZXN1bHRzWzBdO1xuXG4gICAgICAvLyByZW1vdmUgcGFzc3dvcmQgZmllbGQsIG1lc3NlcyB3aXRoIHNhdmluZyBvbiBwb3N0Z3Jlc1xuICAgICAgZGVsZXRlIHVzZXIucGFzc3dvcmQ7XG5cbiAgICAgIGlmICh1c2VyLmVtYWlsVmVyaWZpZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9USEVSX0NBVVNFLCBgRW1haWwgJHtlbWFpbH0gaXMgYWxyZWFkeSB2ZXJpZmllZC5gKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdXNlckNvbnRyb2xsZXIgPSByZXEuY29uZmlnLnVzZXJDb250cm9sbGVyO1xuICAgICAgcmV0dXJuIHVzZXJDb250cm9sbGVyLnJlZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuKHVzZXIpLnRoZW4oKCkgPT4ge1xuICAgICAgICB1c2VyQ29udHJvbGxlci5zZW5kVmVyaWZpY2F0aW9uRW1haWwodXNlcik7XG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlOiB7fSB9O1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBtb3VudFJvdXRlcygpIHtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3VzZXJzJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZpbmQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy91c2VycycsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSwgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUNyZWF0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvdXNlcnMvbWUnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTWUocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdHRVQnLCAnL3VzZXJzLzpvYmplY3RJZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVHZXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQVVQnLCAnL3VzZXJzLzpvYmplY3RJZCcsIHByb21pc2VFbnN1cmVJZGVtcG90ZW5jeSwgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZVVwZGF0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0RFTEVURScsICcvdXNlcnMvOm9iamVjdElkJywgcmVxID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZURlbGV0ZShyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ0dFVCcsICcvbG9naW4nLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlTG9nSW4ocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9sb2dpbicsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVMb2dJbihyZXEpO1xuICAgIH0pO1xuICAgIHRoaXMucm91dGUoJ1BPU1QnLCAnL2xvZ291dCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVMb2dPdXQocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy9yZXF1ZXN0UGFzc3dvcmRSZXNldCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVSZXNldFJlcXVlc3QocmVxKTtcbiAgICB9KTtcbiAgICB0aGlzLnJvdXRlKCdQT1NUJywgJy92ZXJpZmljYXRpb25FbWFpbFJlcXVlc3QnLCByZXEgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlVmVyaWZpY2F0aW9uRW1haWxSZXF1ZXN0KHJlcSk7XG4gICAgfSk7XG4gICAgdGhpcy5yb3V0ZSgnR0VUJywgJy92ZXJpZnlQYXNzd29yZCcsIHJlcSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5oYW5kbGVWZXJpZnlQYXNzd29yZChyZXEpO1xuICAgIH0pO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFVzZXJzUm91dGVyO1xuIl19 \ No newline at end of file diff --git a/lib/StatusHandler.js b/lib/StatusHandler.js deleted file mode 100644 index 708d04b1b0..0000000000 --- a/lib/StatusHandler.js +++ /dev/null @@ -1,386 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.flatten = flatten; -exports.jobStatusHandler = jobStatusHandler; -exports.pushStatusHandler = pushStatusHandler; - -var _cryptoUtils = require("./cryptoUtils"); - -var _logger = require("./logger"); - -var _rest = _interopRequireDefault(require("./rest")); - -var _Auth = _interopRequireDefault(require("./Auth")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const PUSH_STATUS_COLLECTION = '_PushStatus'; -const JOB_STATUS_COLLECTION = '_JobStatus'; - -const incrementOp = function (object = {}, key, amount = 1) { - if (!object[key]) { - object[key] = { - __op: 'Increment', - amount: amount - }; - } else { - object[key].amount += amount; - } - - return object[key]; -}; - -function flatten(array) { - var flattened = []; - - for (var i = 0; i < array.length; i++) { - if (Array.isArray(array[i])) { - flattened = flattened.concat(flatten(array[i])); - } else { - flattened.push(array[i]); - } - } - - return flattened; -} - -function statusHandler(className, database) { - let lastPromise = Promise.resolve(); - - function create(object) { - lastPromise = lastPromise.then(() => { - return database.create(className, object).then(() => { - return Promise.resolve(object); - }); - }); - return lastPromise; - } - - function update(where, object) { - lastPromise = lastPromise.then(() => { - return database.update(className, where, object); - }); - return lastPromise; - } - - return Object.freeze({ - create, - update - }); -} - -function restStatusHandler(className, config) { - let lastPromise = Promise.resolve(); - - const auth = _Auth.default.master(config); - - function create(object) { - lastPromise = lastPromise.then(() => { - return _rest.default.create(config, auth, className, object).then(({ - response - }) => { - // merge the objects - return Promise.resolve(Object.assign({}, object, response)); - }); - }); - return lastPromise; - } - - function update(where, object) { - // TODO: when we have updateWhere, use that for proper interfacing - lastPromise = lastPromise.then(() => { - return _rest.default.update(config, auth, className, { - objectId: where.objectId - }, object).then(({ - response - }) => { - // merge the objects - return Promise.resolve(Object.assign({}, object, response)); - }); - }); - return lastPromise; - } - - return Object.freeze({ - create, - update - }); -} - -function jobStatusHandler(config) { - let jobStatus; - const objectId = (0, _cryptoUtils.newObjectId)(config.objectIdSize); - const database = config.database; - const handler = statusHandler(JOB_STATUS_COLLECTION, database); - - const setRunning = function (jobName, params) { - const now = new Date(); - jobStatus = { - objectId, - jobName, - params, - status: 'running', - source: 'api', - createdAt: now, - // lockdown! - ACL: {} - }; - return handler.create(jobStatus); - }; - - const setMessage = function (message) { - if (!message || typeof message !== 'string') { - return Promise.resolve(); - } - - return handler.update({ - objectId - }, { - message - }); - }; - - const setSucceeded = function (message) { - return setFinalStatus('succeeded', message); - }; - - const setFailed = function (message) { - return setFinalStatus('failed', message); - }; - - const setFinalStatus = function (status, message = undefined) { - const finishedAt = new Date(); - const update = { - status, - finishedAt - }; - - if (message && typeof message === 'string') { - update.message = message; - } - - if (message instanceof Error && typeof message.message === 'string') { - update.message = message.message; - } - - return handler.update({ - objectId - }, update); - }; - - return Object.freeze({ - setRunning, - setSucceeded, - setMessage, - setFailed - }); -} - -function pushStatusHandler(config, existingObjectId) { - let pushStatus; - const database = config.database; - const handler = restStatusHandler(PUSH_STATUS_COLLECTION, config); - let objectId = existingObjectId; - - const setInitial = function (body = {}, where, options = { - source: 'rest' - }) { - const now = new Date(); - let pushTime = now.toISOString(); - let status = 'pending'; - - if (Object.prototype.hasOwnProperty.call(body, 'push_time')) { - if (config.hasPushScheduledSupport) { - pushTime = body.push_time; - status = 'scheduled'; - } else { - _logger.logger.warn('Trying to schedule a push while server is not configured.'); - - _logger.logger.warn('Push will be sent immediately'); - } - } - - const data = body.data || {}; - const payloadString = JSON.stringify(data); - let pushHash; - - if (typeof data.alert === 'string') { - pushHash = (0, _cryptoUtils.md5Hash)(data.alert); - } else if (typeof data.alert === 'object') { - pushHash = (0, _cryptoUtils.md5Hash)(JSON.stringify(data.alert)); - } else { - pushHash = 'd41d8cd98f00b204e9800998ecf8427e'; - } - - const object = { - pushTime, - query: JSON.stringify(where), - payload: payloadString, - source: options.source, - title: options.title, - expiry: body.expiration_time, - expiration_interval: body.expiration_interval, - status: status, - numSent: 0, - pushHash, - // lockdown! - ACL: {} - }; - return handler.create(object).then(result => { - objectId = result.objectId; - pushStatus = { - objectId - }; - return Promise.resolve(pushStatus); - }); - }; - - const setRunning = function (batches) { - _logger.logger.verbose(`_PushStatus ${objectId}: sending push to installations with %d batches`, batches); - - return handler.update({ - status: 'pending', - objectId: objectId - }, { - status: 'running', - count: batches - }); - }; - - const trackSent = function (results, UTCOffset, cleanupInstallations = process.env.PARSE_SERVER_CLEANUP_INVALID_INSTALLATIONS) { - const update = { - numSent: 0, - numFailed: 0 - }; - const devicesToRemove = []; - - if (Array.isArray(results)) { - results = flatten(results); - results.reduce((memo, result) => { - // Cannot handle that - if (!result || !result.device || !result.device.deviceType) { - return memo; - } - - const deviceType = result.device.deviceType; - const key = result.transmitted ? `sentPerType.${deviceType}` : `failedPerType.${deviceType}`; - memo[key] = incrementOp(memo, key); - - if (typeof UTCOffset !== 'undefined') { - const offsetKey = result.transmitted ? `sentPerUTCOffset.${UTCOffset}` : `failedPerUTCOffset.${UTCOffset}`; - memo[offsetKey] = incrementOp(memo, offsetKey); - } - - if (result.transmitted) { - memo.numSent++; - } else { - if (result && result.response && result.response.error && result.device && result.device.deviceToken) { - const token = result.device.deviceToken; - const error = result.response.error; // GCM errors - - if (error === 'NotRegistered' || error === 'InvalidRegistration') { - devicesToRemove.push(token); - } // APNS errors - - - if (error === 'Unregistered' || error === 'BadDeviceToken') { - devicesToRemove.push(token); - } - } - - memo.numFailed++; - } - - return memo; - }, update); - } - - _logger.logger.verbose(`_PushStatus ${objectId}: sent push! %d success, %d failures`, update.numSent, update.numFailed); - - _logger.logger.verbose(`_PushStatus ${objectId}: needs cleanup`, { - devicesToRemove - }); - - ['numSent', 'numFailed'].forEach(key => { - if (update[key] > 0) { - update[key] = { - __op: 'Increment', - amount: update[key] - }; - } else { - delete update[key]; - } - }); - - if (devicesToRemove.length > 0 && cleanupInstallations) { - _logger.logger.info(`Removing device tokens on ${devicesToRemove.length} _Installations`); - - database.update('_Installation', { - deviceToken: { - $in: devicesToRemove - } - }, { - deviceToken: { - __op: 'Delete' - } - }, { - acl: undefined, - many: true - }); - } // indicate this batch is complete - - - incrementOp(update, 'count', -1); - return handler.update({ - objectId - }, update).then(res => { - if (res && res.count === 0) { - return this.complete(); - } - }); - }; - - const complete = function () { - return handler.update({ - objectId - }, { - status: 'succeeded', - count: { - __op: 'Delete' - } - }); - }; - - const fail = function (err) { - if (typeof err === 'string') { - err = { - message: err - }; - } - - const update = { - errorMessage: err, - status: 'failed' - }; - return handler.update({ - objectId - }, update); - }; - - const rval = { - setInitial, - setRunning, - trackSent, - complete, - fail - }; // define objectId to be dynamic - - Object.defineProperty(rval, 'objectId', { - get: () => objectId - }); - return Object.freeze(rval); -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9TdGF0dXNIYW5kbGVyLmpzIl0sIm5hbWVzIjpbIlBVU0hfU1RBVFVTX0NPTExFQ1RJT04iLCJKT0JfU1RBVFVTX0NPTExFQ1RJT04iLCJpbmNyZW1lbnRPcCIsIm9iamVjdCIsImtleSIsImFtb3VudCIsIl9fb3AiLCJmbGF0dGVuIiwiYXJyYXkiLCJmbGF0dGVuZWQiLCJpIiwibGVuZ3RoIiwiQXJyYXkiLCJpc0FycmF5IiwiY29uY2F0IiwicHVzaCIsInN0YXR1c0hhbmRsZXIiLCJjbGFzc05hbWUiLCJkYXRhYmFzZSIsImxhc3RQcm9taXNlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJjcmVhdGUiLCJ0aGVuIiwidXBkYXRlIiwid2hlcmUiLCJPYmplY3QiLCJmcmVlemUiLCJyZXN0U3RhdHVzSGFuZGxlciIsImNvbmZpZyIsImF1dGgiLCJBdXRoIiwibWFzdGVyIiwicmVzdCIsInJlc3BvbnNlIiwiYXNzaWduIiwib2JqZWN0SWQiLCJqb2JTdGF0dXNIYW5kbGVyIiwiam9iU3RhdHVzIiwib2JqZWN0SWRTaXplIiwiaGFuZGxlciIsInNldFJ1bm5pbmciLCJqb2JOYW1lIiwicGFyYW1zIiwibm93IiwiRGF0ZSIsInN0YXR1cyIsInNvdXJjZSIsImNyZWF0ZWRBdCIsIkFDTCIsInNldE1lc3NhZ2UiLCJtZXNzYWdlIiwic2V0U3VjY2VlZGVkIiwic2V0RmluYWxTdGF0dXMiLCJzZXRGYWlsZWQiLCJ1bmRlZmluZWQiLCJmaW5pc2hlZEF0IiwiRXJyb3IiLCJwdXNoU3RhdHVzSGFuZGxlciIsImV4aXN0aW5nT2JqZWN0SWQiLCJwdXNoU3RhdHVzIiwic2V0SW5pdGlhbCIsImJvZHkiLCJvcHRpb25zIiwicHVzaFRpbWUiLCJ0b0lTT1N0cmluZyIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImhhc1B1c2hTY2hlZHVsZWRTdXBwb3J0IiwicHVzaF90aW1lIiwibG9nZ2VyIiwid2FybiIsImRhdGEiLCJwYXlsb2FkU3RyaW5nIiwiSlNPTiIsInN0cmluZ2lmeSIsInB1c2hIYXNoIiwiYWxlcnQiLCJxdWVyeSIsInBheWxvYWQiLCJ0aXRsZSIsImV4cGlyeSIsImV4cGlyYXRpb25fdGltZSIsImV4cGlyYXRpb25faW50ZXJ2YWwiLCJudW1TZW50IiwicmVzdWx0IiwiYmF0Y2hlcyIsInZlcmJvc2UiLCJjb3VudCIsInRyYWNrU2VudCIsInJlc3VsdHMiLCJVVENPZmZzZXQiLCJjbGVhbnVwSW5zdGFsbGF0aW9ucyIsInByb2Nlc3MiLCJlbnYiLCJQQVJTRV9TRVJWRVJfQ0xFQU5VUF9JTlZBTElEX0lOU1RBTExBVElPTlMiLCJudW1GYWlsZWQiLCJkZXZpY2VzVG9SZW1vdmUiLCJyZWR1Y2UiLCJtZW1vIiwiZGV2aWNlIiwiZGV2aWNlVHlwZSIsInRyYW5zbWl0dGVkIiwib2Zmc2V0S2V5IiwiZXJyb3IiLCJkZXZpY2VUb2tlbiIsInRva2VuIiwiZm9yRWFjaCIsImluZm8iLCIkaW4iLCJhY2wiLCJtYW55IiwicmVzIiwiY29tcGxldGUiLCJmYWlsIiwiZXJyIiwiZXJyb3JNZXNzYWdlIiwicnZhbCIsImRlZmluZVByb3BlcnR5IiwiZ2V0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUVBLE1BQU1BLHNCQUFzQixHQUFHLGFBQS9CO0FBQ0EsTUFBTUMscUJBQXFCLEdBQUcsWUFBOUI7O0FBRUEsTUFBTUMsV0FBVyxHQUFHLFVBQVVDLE1BQU0sR0FBRyxFQUFuQixFQUF1QkMsR0FBdkIsRUFBNEJDLE1BQU0sR0FBRyxDQUFyQyxFQUF3QztBQUMxRCxNQUFJLENBQUNGLE1BQU0sQ0FBQ0MsR0FBRCxDQUFYLEVBQWtCO0FBQ2hCRCxJQUFBQSxNQUFNLENBQUNDLEdBQUQsQ0FBTixHQUFjO0FBQUVFLE1BQUFBLElBQUksRUFBRSxXQUFSO0FBQXFCRCxNQUFBQSxNQUFNLEVBQUVBO0FBQTdCLEtBQWQ7QUFDRCxHQUZELE1BRU87QUFDTEYsSUFBQUEsTUFBTSxDQUFDQyxHQUFELENBQU4s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QUFNOEYsSUFBSSxHQUFHO0FBQ1h6RCxJQUFBQSxVQURXO0FBRVhwQixJQUFBQSxVQUZXO0FBR1hpRCxJQUFBQSxTQUhXO0FBSVh3QixJQUFBQSxRQUpXO0FBS1hDLElBQUFBO0FBTFcsR0FBYixDQTNMMEQsQ0FtTTFEOztBQUNBekYsRUFBQUEsTUFBTSxDQUFDNkYsY0FBUCxDQUFzQkQsSUFBdEIsRUFBNEIsVUFBNUIsRUFBd0M7QUFDdENFLElBQUFBLEdBQUcsRUFBRSxNQUFNcEY7QUFEMkIsR0FBeEM7QUFJQSxTQUFPVixNQUFNLENBQUNDLE1BQVAsQ0FBYzJGLElBQWQsQ0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgbWQ1SGFzaCwgbmV3T2JqZWN0SWQgfSBmcm9tICcuL2NyeXB0b1V0aWxzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4vbG9nZ2VyJztcbmltcG9ydCByZXN0IGZyb20gJy4vcmVzdCc7XG5pbXBvcnQgQXV0aCBmcm9tICcuL0F1dGgnO1xuXG5jb25zdCBQVVNIX1NUQVRVU19DT0xMRUNUSU9OID0gJ19QdXNoU3RhdHVzJztcbmNvbnN0IEpPQl9TVEFUVVNfQ09MTEVDVElPTiA9ICdfSm9iU3RhdHVzJztcblxuY29uc3QgaW5jcmVtZW50T3AgPSBmdW5jdGlvbiAob2JqZWN0ID0ge30sIGtleSwgYW1vdW50ID0gMSkge1xuICBpZiAoIW9iamVjdFtrZXldKSB7XG4gICAgb2JqZWN0W2tleV0gPSB7IF9fb3A6ICdJbmNyZW1lbnQnLCBhbW91bnQ6IGFtb3VudCB9O1xuICB9IGVsc2Uge1xuICAgIG9iamVjdFtrZXldLmFtb3VudCArPSBhbW91bnQ7XG4gIH1cbiAgcmV0dXJuIG9iamVjdFtrZXldO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGZsYXR0ZW4oYXJyYXkpIHtcbiAgdmFyIGZsYXR0ZW5lZCA9IFtdO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYXJyYXlbaV0pKSB7XG4gICAgICBmbGF0dGVuZWQgPSBmbGF0dGVuZWQuY29uY2F0KGZsYXR0ZW4oYXJyYXlbaV0pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZmxhdHRlbmVkLnB1c2goYXJyYXlbaV0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmxhdHRlbmVkO1xufVxuXG5mdW5jdGlvbiBzdGF0dXNIYW5kbGVyKGNsYXNzTmFtZSwgZGF0YWJhc2UpIHtcbiAgbGV0IGxhc3RQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG5cbiAgZnVuY3Rpb24gY3JlYXRlKG9iamVjdCkge1xuICAgIGxhc3RQcm9taXNlID0gbGFzdFByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gZGF0YWJhc2UuY3JlYXRlKGNsYXNzTmFtZSwgb2JqZWN0KS50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShvYmplY3QpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGxhc3RQcm9taXNlO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlKHdoZXJlLCBvYmplY3QpIHtcbiAgICBsYXN0UHJvbWlzZSA9IGxhc3RQcm9taXNlLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIGRhdGFiYXNlLnVwZGF0ZShjbGFzc05hbWUsIHdoZXJlLCBvYmplY3QpO1xuICAgIH0pO1xuICAgIHJldHVybiBsYXN0UHJvbWlzZTtcbiAgfVxuXG4gIHJldHVybiBPYmplY3QuZnJlZXplKHtcbiAgICBjcmVhdGUsXG4gICAgdXBkYXRlLFxuICB9KTtcbn1cblxuZnVuY3Rpb24gcmVzdFN0YXR1c0hhbmRsZXIoY2xhc3NOYW1lLCBjb25maWcpIHtcbiAgbGV0IGxhc3RQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIGNvbnN0IGF1dGggPSBBdXRoLm1hc3Rlcihjb25maWcpO1xuICBmdW5jdGlvbiBjcmVhdGUob2JqZWN0KSB7XG4gICAgbGFzdFByb21pc2UgPSBsYXN0UHJvbWlzZS50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiByZXN0LmNyZWF0ZShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgb2JqZWN0KS50aGVuKCh7IHJlc3BvbnNlIH0pID0+IHtcbiAgICAgICAgLy8gbWVyZ2UgdGhlIG9iamVjdHNcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShPYmplY3QuYXNzaWduKHt9LCBvYmplY3QsIHJlc3BvbnNlKSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICByZXR1cm4gbGFzdFByb21pc2U7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGUod2hlcmUsIG9iamVjdCkge1xuICAgIC8vIFRPRE86IHdoZW4gd2UgaGF2ZSB1cGRhdGVXaGVyZSwgdXNlIHRoYXQgZm9yIHByb3BlciBpbnRlcmZhY2luZ1xuICAgIGxhc3RQcm9taXNlID0gbGFzdFByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gcmVzdFxuICAgICAgICAudXBkYXRlKGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCB7IG9iamVjdElkOiB3aGVyZS5vYmplY3RJZCB9LCBvYmplY3QpXG4gICAgICAgIC50aGVuKCh7IHJlc3BvbnNlIH0pID0+IHtcbiAgICAgICAgICAvLyBtZXJnZSB0aGUgb2JqZWN0c1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoT2JqZWN0LmFzc2lnbih7fSwgb2JqZWN0LCByZXNwb25zZSkpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICByZXR1cm4gbGFzdFByb21pc2U7XG4gIH1cblxuICByZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG4gICAgY3JlYXRlLFxuICAgIHVwZGF0ZSxcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBqb2JTdGF0dXNIYW5kbGVyKGNvbmZpZykge1xuICBsZXQgam9iU3RhdHVzO1xuICBjb25zdCBvYmplY3RJZCA9IG5ld09iamVjdElkKGNvbmZpZy5vYmplY3RJZFNpemUpO1xuICBjb25zdCBkYXRhYmFzZSA9IGNvbmZpZy5kYXRhYmFzZTtcbiAgY29uc3QgaGFuZGxlciA9IHN0YXR1c0hhbmRsZXIoSk9CX1NUQVRVU19DT0xMRUNUSU9OLCBkYXRhYmFzZSk7XG4gIGNvbnN0IHNldFJ1bm5pbmcgPSBmdW5jdGlvbiAoam9iTmFtZSwgcGFyYW1zKSB7XG4gICAgY29uc3Qgbm93ID0gbmV3IERhdGUoKTtcbiAgICBqb2JTdGF0dXMgPSB7XG4gICAgICBvYmplY3RJZCxcbiAgICAgIGpvYk5hbWUsXG4gICAgICBwYXJhbXMsXG4gICAgICBzdGF0dXM6ICdydW5uaW5nJyxcbiAgICAgIHNvdXJjZTogJ2FwaScsXG4gICAgICBjcmVhdGVkQXQ6IG5vdyxcbiAgICAgIC8vIGxvY2tkb3duIVxuICAgICAgQUNMOiB7fSxcbiAgICB9O1xuXG4gICAgcmV0dXJuIGhhbmRsZXIuY3JlYXRlKGpvYlN0YXR1cyk7XG4gIH07XG5cbiAgY29uc3Qgc2V0TWVzc2FnZSA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgaWYgKCFtZXNzYWdlIHx8IHR5cGVvZiBtZXNzYWdlICE9PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICByZXR1cm4gaGFuZGxlci51cGRhdGUoeyBvYmplY3RJZCB9LCB7IG1lc3NhZ2UgfSk7XG4gIH07XG5cbiAgY29uc3Qgc2V0U3VjY2VlZGVkID0gZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICByZXR1cm4gc2V0RmluYWxTdGF0dXMoJ3N1Y2NlZWRlZCcsIG1lc3NhZ2UpO1xuICB9O1xuXG4gIGNvbnN0IHNldEZhaWxlZCA9IGZ1bmN0aW9uIChtZXNzYWdlKSB7XG4gICAgcmV0dXJuIHNldEZpbmFsU3RhdHVzKCdmYWlsZWQnLCBtZXNzYWdlKTtcbiAgfTtcblxuICBjb25zdCBzZXRGaW5hbFN0YXR1cyA9IGZ1bmN0aW9uIChzdGF0dXMsIG1lc3NhZ2UgPSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBmaW5pc2hlZEF0ID0gbmV3IERhdGUoKTtcbiAgICBjb25zdCB1cGRhdGUgPSB7IHN0YXR1cywgZmluaXNoZWRBdCB9O1xuICAgIGlmIChtZXNzYWdlICYmIHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJykge1xuICAgICAgdXBkYXRlLm1lc3NhZ2UgPSBtZXNzYWdlO1xuICAgIH1cbiAgICBpZiAobWVzc2FnZSBpbnN0YW5jZW9mIEVycm9yICYmIHR5cGVvZiBtZXNzYWdlLm1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICB1cGRhdGUubWVzc2FnZSA9IG1lc3NhZ2UubWVzc2FnZTtcbiAgICB9XG4gICAgcmV0dXJuIGhhbmRsZXIudXBkYXRlKHsgb2JqZWN0SWQgfSwgdXBkYXRlKTtcbiAgfTtcblxuICByZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG4gICAgc2V0UnVubmluZyxcbiAgICBzZXRTdWNjZWVkZWQsXG4gICAgc2V0TWVzc2FnZSxcbiAgICBzZXRGYWlsZWQsXG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHVzaFN0YXR1c0hhbmRsZXIoY29uZmlnLCBleGlzdGluZ09iamVjdElkKSB7XG4gIGxldCBwdXNoU3RhdHVzO1xuICBjb25zdCBkYXRhYmFzZSA9IGNvbmZpZy5kYXRhYmFzZTtcbiAgY29uc3QgaGFuZGxlciA9IHJlc3RTdGF0dXNIYW5kbGVyKFBVU0hfU1RBVFVTX0NPTExFQ1RJT04sIGNvbmZpZyk7XG4gIGxldCBvYmplY3RJZCA9IGV4aXN0aW5nT2JqZWN0SWQ7XG4gIGNvbnN0IHNldEluaXRpYWwgPSBmdW5jdGlvbiAoYm9keSA9IHt9LCB3aGVyZSwgb3B0aW9ucyA9IHsgc291cmNlOiAncmVzdCcgfSkge1xuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgbGV0IHB1c2hUaW1lID0gbm93LnRvSVNPU3RyaW5nKCk7XG4gICAgbGV0IHN0YXR1cyA9ICdwZW5kaW5nJztcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGJvZHksICdwdXNoX3RpbWUnKSkge1xuICAgICAgaWYgKGNvbmZpZy5oYXNQdXNoU2NoZWR1bGVkU3VwcG9ydCkge1xuICAgICAgICBwdXNoVGltZSA9IGJvZHkucHVzaF90aW1lO1xuICAgICAgICBzdGF0dXMgPSAnc2NoZWR1bGVkJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZ2dlci53YXJuKCdUcnlpbmcgdG8gc2NoZWR1bGUgYSBwdXNoIHdoaWxlIHNlcnZlciBpcyBub3QgY29uZmlndXJlZC4nKTtcbiAgICAgICAgbG9nZ2VyLndhcm4oJ1B1c2ggd2lsbCBiZSBzZW50IGltbWVkaWF0ZWx5Jyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgZGF0YSA9IGJvZHkuZGF0YSB8fCB7fTtcbiAgICBjb25zdCBwYXlsb2FkU3RyaW5nID0gSlNPTi5zdHJpbmdpZnkoZGF0YSk7XG4gICAgbGV0IHB1c2hIYXNoO1xuICAgIGlmICh0eXBlb2YgZGF0YS5hbGVydCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHB1c2hIYXNoID0gbWQ1SGFzaChkYXRhLmFsZXJ0KTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBkYXRhLmFsZXJ0ID09PSAnb2JqZWN0Jykge1xuICAgICAgcHVzaEhhc2ggPSBtZDVIYXNoKEpTT04uc3RyaW5naWZ5KGRhdGEuYWxlcnQpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcHVzaEhhc2ggPSAnZDQxZDhjZDk4ZjAwYjIwNGU5ODAwOTk4ZWNmODQyN2UnO1xuICAgIH1cbiAgICBjb25zdCBvYmplY3QgPSB7XG4gICAgICBwdXNoVGltZSxcbiAgICAgIHF1ZXJ5OiBKU09OLnN0cmluZ2lmeSh3aGVyZSksXG4gICAgICBwYXlsb2FkOiBwYXlsb2FkU3RyaW5nLFxuICAgICAgc291cmNlOiBvcHRpb25zLnNvdXJjZSxcbiAgICAgIHRpdGxlOiBvcHRpb25zLnRpdGxlLFxuICAgICAgZXhwaXJ5OiBib2R5LmV4cGlyYXRpb25fdGltZSxcbiAgICAgIGV4cGlyYXRpb25faW50ZXJ2YWw6IGJvZHkuZXhwaXJhdGlvbl9pbnRlcnZhbCxcbiAgICAgIHN0YXR1czogc3RhdHVzLFxuICAgICAgbnVtU2VudDogMCxcbiAgICAgIHB1c2hIYXNoLFxuICAgICAgLy8gbG9ja2Rvd24hXG4gICAgICBBQ0w6IHt9LFxuICAgIH07XG4gICAgcmV0dXJuIGhhbmRsZXIuY3JlYXRlKG9iamVjdCkudGhlbihyZXN1bHQgPT4ge1xuICAgICAgb2JqZWN0SWQgPSByZXN1bHQub2JqZWN0SWQ7XG4gICAgICBwdXNoU3RhdHVzID0ge1xuICAgICAgICBvYmplY3RJZCxcbiAgICAgIH07XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHB1c2hTdGF0dXMpO1xuICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IHNldFJ1bm5pbmcgPSBmdW5jdGlvbiAoYmF0Y2hlcykge1xuICAgIGxvZ2dlci52ZXJib3NlKFxuICAgICAgYF9QdXNoU3RhdHVzICR7b2JqZWN0SWR9OiBzZW5kaW5nIHB1c2ggdG8gaW5zdGFsbGF0aW9ucyB3aXRoICVkIGJhdGNoZXNgLFxuICAgICAgYmF0Y2hlc1xuICAgICk7XG4gICAgcmV0dXJuIGhhbmRsZXIudXBkYXRlKFxuICAgICAge1xuICAgICAgICBzdGF0dXM6ICdwZW5kaW5nJyxcbiAgICAgICAgb2JqZWN0SWQ6IG9iamVjdElkLFxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgc3RhdHVzOiAncnVubmluZycsXG4gICAgICAgIGNvdW50OiBiYXRjaGVzLFxuICAgICAgfVxuICAgICk7XG4gIH07XG5cbiAgY29uc3QgdHJhY2tTZW50ID0gZnVuY3Rpb24gKFxuICAgIHJlc3VsdHMsXG4gICAgVVRDT2Zmc2V0LFxuICAgIGNsZWFudXBJbnN0YWxsYXRpb25zID0gcHJvY2Vzcy5lbnYuUEFSU0VfU0VSVkVSX0NMRUFOVVBfSU5WQUxJRF9JTlNUQUxMQVRJT05TXG4gICkge1xuICAgIGNvbnN0IHVwZGF0ZSA9IHtcbiAgICAgIG51bVNlbnQ6IDAsXG4gICAgICBudW1GYWlsZWQ6IDAsXG4gICAgfTtcbiAgICBjb25zdCBkZXZpY2VzVG9SZW1vdmUgPSBbXTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHRzKSkge1xuICAgICAgcmVzdWx0cyA9IGZsYXR0ZW4ocmVzdWx0cyk7XG4gICAgICByZXN1bHRzLnJlZHVjZSgobWVtbywgcmVzdWx0KSA9PiB7XG4gICAgICAgIC8vIENhbm5vdCBoYW5kbGUgdGhhdFxuICAgICAgICBpZiAoIXJlc3VsdCB8fCAhcmVzdWx0LmRldmljZSB8fCAhcmVzdWx0LmRldmljZS5kZXZpY2VUeXBlKSB7XG4gICAgICAgICAgcmV0dXJuIG1lbW87XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGV2aWNlVHlwZSA9IHJlc3VsdC5kZXZpY2UuZGV2aWNlVHlwZTtcbiAgICAgICAgY29uc3Qga2V5ID0gcmVzdWx0LnRyYW5zbWl0dGVkXG4gICAgICAgICAgPyBgc2VudFBlclR5cGUuJHtkZXZpY2VUeXBlfWBcbiAgICAgICAgICA6IGBmYWlsZWRQZXJUeXBlLiR7ZGV2aWNlVHlwZX1gO1xuICAgICAgICBtZW1vW2tleV0gPSBpbmNyZW1lbnRPcChtZW1vLCBrZXkpO1xuICAgICAgICBpZiAodHlwZW9mIFVUQ09mZnNldCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBjb25zdCBvZmZzZXRLZXkgPSByZXN1bHQudHJhbnNtaXR0ZWRcbiAgICAgICAgICAgID8gYHNlbnRQZXJVVENPZmZzZXQuJHtVVENPZmZzZXR9YFxuICAgICAgICAgICAgOiBgZmFpbGVkUGVyVVRDT2Zmc2V0LiR7VVRDT2Zmc2V0fWA7XG4gICAgICAgICAgbWVtb1tvZmZzZXRLZXldID0gaW5jcmVtZW50T3AobWVtbywgb2Zmc2V0S2V5KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzdWx0LnRyYW5zbWl0dGVkKSB7XG4gICAgICAgICAgbWVtby5udW1TZW50Kys7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgcmVzdWx0ICYmXG4gICAgICAgICAgICByZXN1bHQucmVzcG9uc2UgJiZcbiAgICAgICAgICAgIHJlc3VsdC5yZXNwb25zZS5lcnJvciAmJlxuICAgICAgICAgICAgcmVzdWx0LmRldmljZSAmJlxuICAgICAgICAgICAgcmVzdWx0LmRldmljZS5kZXZpY2VUb2tlblxuICAgICAgICAgICkge1xuICAgICAgICAgICAgY29uc3QgdG9rZW4gPSByZXN1bHQuZGV2aWNlLmRldmljZVRva2VuO1xuICAgICAgICAgICAgY29uc3QgZXJyb3IgPSByZXN1bHQucmVzcG9uc2UuZXJyb3I7XG4gICAgICAgICAgICAvLyBHQ00gZXJyb3JzXG4gICAgICAgICAgICBpZiAoZXJyb3IgPT09ICdOb3RSZWdpc3RlcmVkJyB8fCBlcnJvciA9PT0gJ0ludmFsaWRSZWdpc3RyYXRpb24nKSB7XG4gICAgICAgICAgICAgIGRldmljZXNUb1JlbW92ZS5wdXNoKHRva2VuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIEFQTlMgZXJyb3JzXG4gICAgICAgICAgICBpZiAoZXJyb3IgPT09ICdVbnJlZ2lzdGVyZWQnIHx8IGVycm9yID09PSAnQmFkRGV2aWNlVG9rZW4nKSB7XG4gICAgICAgICAgICAgIGRldmljZXNUb1JlbW92ZS5wdXNoKHRva2VuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgbWVtby5udW1GYWlsZWQrKztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVtbztcbiAgICAgIH0sIHVwZGF0ZSk7XG4gICAgfVxuXG4gICAgbG9nZ2VyLnZlcmJvc2UoXG4gICAgICBgX1B1c2hTdGF0dXMgJHtvYmplY3RJZH06IHNlbnQgcHVzaCEgJWQgc3VjY2VzcywgJWQgZmFpbHVyZXNgLFxuICAgICAgdXBkYXRlLm51bVNlbnQsXG4gICAgICB1cGRhdGUubnVtRmFpbGVkXG4gICAgKTtcbiAgICBsb2dnZXIudmVyYm9zZShgX1B1c2hTdGF0dXMgJHtvYmplY3RJZH06IG5lZWRzIGNsZWFudXBgLCB7XG4gICAgICBkZXZpY2VzVG9SZW1vdmUsXG4gICAgfSk7XG4gICAgWydudW1TZW50JywgJ251bUZhaWxlZCddLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGlmICh1cGRhdGVba2V5XSA+IDApIHtcbiAgICAgICAgdXBkYXRlW2tleV0gPSB7XG4gICAgICAgICAgX19vcDogJ0luY3JlbWVudCcsXG4gICAgICAgICAgYW1vdW50OiB1cGRhdGVba2V5XSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlbGV0ZSB1cGRhdGVba2V5XTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChkZXZpY2VzVG9SZW1vdmUubGVuZ3RoID4gMCAmJiBjbGVhbnVwSW5zdGFsbGF0aW9ucykge1xuICAgICAgbG9nZ2VyLmluZm8oYFJlbW92aW5nIGRldmljZSB0b2tlbnMgb24gJHtkZXZpY2VzVG9SZW1vdmUubGVuZ3RofSBfSW5zdGFsbGF0aW9uc2ApO1xuICAgICAgZGF0YWJhc2UudXBkYXRlKFxuICAgICAgICAnX0luc3RhbGxhdGlvbicsXG4gICAgICAgIHsgZGV2aWNlVG9rZW46IHsgJGluOiBkZXZpY2VzVG9SZW1vdmUgfSB9LFxuICAgICAgICB7IGRldmljZVRva2VuOiB7IF9fb3A6ICdEZWxldGUnIH0gfSxcbiAgICAgICAge1xuICAgICAgICAgIGFjbDogdW5kZWZpbmVkLFxuICAgICAgICAgIG1hbnk6IHRydWUsXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gaW5kaWNhdGUgdGhpcyBiYXRjaCBpcyBjb21wbGV0ZVxuICAgIGluY3JlbWVudE9wKHVwZGF0ZSwgJ2NvdW50JywgLTEpO1xuXG4gICAgcmV0dXJuIGhhbmRsZXIudXBkYXRlKHsgb2JqZWN0SWQgfSwgdXBkYXRlKS50aGVuKHJlcyA9PiB7XG4gICAgICBpZiAocmVzICYmIHJlcy5jb3VudCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jb21wbGV0ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIGNvbnN0IGNvbXBsZXRlID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBoYW5kbGVyLnVwZGF0ZShcbiAgICAgIHsgb2JqZWN0SWQgfSxcbiAgICAgIHtcbiAgICAgICAgc3RhdHVzOiAnc3VjY2VlZGVkJyxcbiAgICAgICAgY291bnQ6IHsgX19vcDogJ0RlbGV0ZScgfSxcbiAgICAgIH1cbiAgICApO1xuICB9O1xuXG4gIGNvbnN0IGZhaWwgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgaWYgKHR5cGVvZiBlcnIgPT09ICdzdHJpbmcnKSB7XG4gICAgICBlcnIgPSB7IG1lc3NhZ2U6IGVyciB9O1xuICAgIH1cbiAgICBjb25zdCB1cGRhdGUgPSB7XG4gICAgICBlcnJvck1lc3NhZ2U6IGVycixcbiAgICAgIHN0YXR1czogJ2ZhaWxlZCcsXG4gICAgfTtcbiAgICByZXR1cm4gaGFuZGxlci51cGRhdGUoeyBvYmplY3RJZCB9LCB1cGRhdGUpO1xuICB9O1xuXG4gIGNvbnN0IHJ2YWwgPSB7XG4gICAgc2V0SW5pdGlhbCxcbiAgICBzZXRSdW5uaW5nLFxuICAgIHRyYWNrU2VudCxcbiAgICBjb21wbGV0ZSxcbiAgICBmYWlsLFxuICB9O1xuXG4gIC8vIGRlZmluZSBvYmplY3RJZCB0byBiZSBkeW5hbWljXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShydmFsLCAnb2JqZWN0SWQnLCB7XG4gICAgZ2V0OiAoKSA9PiBvYmplY3RJZCxcbiAgfSk7XG5cbiAgcmV0dXJuIE9iamVjdC5mcmVlemUocnZhbCk7XG59XG4iXX0= \ No newline at end of file diff --git a/lib/TestUtils.js b/lib/TestUtils.js deleted file mode 100644 index 9aaccbe172..0000000000 --- a/lib/TestUtils.js +++ /dev/null @@ -1,31 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.destroyAllDataPermanently = destroyAllDataPermanently; - -var _cache = _interopRequireDefault(require("./cache")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - * Destroys all data in the database - * @param {boolean} fast set to true if it's ok to just drop objects and not indexes. - */ -function destroyAllDataPermanently(fast) { - if (!process.env.TESTING) { - throw 'Only supported in test environment'; - } - - return Promise.all(Object.keys(_cache.default.cache).map(appId => { - const app = _cache.default.get(appId); - - if (app.databaseController) { - return app.databaseController.deleteEverything(fast); - } else { - return Promise.resolve(); - } - })); -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9UZXN0VXRpbHMuanMiXSwibmFtZXMiOlsiZGVzdHJveUFsbERhdGFQZXJtYW5lbnRseSIsImZhc3QiLCJwcm9jZXNzIiwiZW52IiwiVEVTVElORyIsIlByb21pc2UiLCJhbGwiLCJPYmplY3QiLCJrZXlzIiwiQXBwQ2FjaGUiLCJjYWNoZSIsIm1hcCIsImFwcElkIiwiYXBwIiwiZ2V0IiwiZGF0YWJhc2VDb250cm9sbGVyIiwiZGVsZXRlRXZlcnl0aGluZyIsInJlc29sdmUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7OztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU0EseUJBQVQsQ0FBbUNDLElBQW5DLEVBQXlDO0FBQzlDLE1BQUksQ0FBQ0MsT0FBTyxDQUFDQyxHQUFSLENBQVlDLE9BQWpCLEVBQTBCO0FBQ3hCLFVBQU0sb0NBQU47QUFDRDs7QUFDRCxTQUFPQyxPQUFPLENBQUNDLEdBQVIsQ0FDTEMsTUFBTSxDQUFDQyxJQUFQLENBQVlDLGVBQVNDLEtBQXJCLEVBQTRCQyxHQUE1QixDQUFnQ0MsS0FBSyxJQUFJO0FBQ3ZDLFVBQU1DLEdBQUcsR0FBR0osZUFBU0ssR0FBVCxDQUFhRixLQUFiLENBQVo7O0FBQ0EsUUFBSUMsR0FBRyxDQUFDRSxrQkFBUixFQUE0QjtBQUMxQixhQUFPRixHQUFHLENBQUNFLGtCQUFKLENBQXVCQyxnQkFBdkIsQ0FBd0NmLElBQXhDLENBQVA7QUFDRCxLQUZELE1BRU87QUFDTCxhQUFPSSxPQUFPLENBQUNZLE9BQVIsRUFBUDtBQUNEO0FBQ0YsR0FQRCxDQURLLENBQVA7QUFVRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBBcHBDYWNoZSBmcm9tICcuL2NhY2hlJztcblxuLyoqXG4gKiBEZXN0cm95cyBhbGwgZGF0YSBpbiB0aGUgZGF0YWJhc2VcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gZmFzdCBzZXQgdG8gdHJ1ZSBpZiBpdCdzIG9rIHRvIGp1c3QgZHJvcCBvYmplY3RzIGFuZCBub3QgaW5kZXhlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlc3Ryb3lBbGxEYXRhUGVybWFuZW50bHkoZmFzdCkge1xuICBpZiAoIXByb2Nlc3MuZW52LlRFU1RJTkcpIHtcbiAgICB0aHJvdyAnT25seSBzdXBwb3J0ZWQgaW4gdGVzdCBlbnZpcm9ubWVudCc7XG4gIH1cbiAgcmV0dXJuIFByb21pc2UuYWxsKFxuICAgIE9iamVjdC5rZXlzKEFwcENhY2hlLmNhY2hlKS5tYXAoYXBwSWQgPT4ge1xuICAgICAgY29uc3QgYXBwID0gQXBwQ2FjaGUuZ2V0KGFwcElkKTtcbiAgICAgIGlmIChhcHAuZGF0YWJhc2VDb250cm9sbGVyKSB7XG4gICAgICAgIHJldHVybiBhcHAuZGF0YWJhc2VDb250cm9sbGVyLmRlbGV0ZUV2ZXJ5dGhpbmcoZmFzdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfSlcbiAgKTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/Utils.js b/lib/Utils.js deleted file mode 100644 index 387a6e5564..0000000000 --- a/lib/Utils.js +++ /dev/null @@ -1,139 +0,0 @@ -"use strict"; - -/** - * utils.js - * @file General purpose utilities - * @description General purpose utilities. - */ -const path = require('path'); - -const fs = require('fs').promises; -/** - * The general purpose utilities. - */ - - -class Utils { - /** - * @function getLocalizedPath - * @description Returns a localized file path accoring to the locale. - * - * Localized files are searched in subfolders of a given path, e.g. - * - * root/ - * ├── base/ // base path to files - * │ ├── example.html // default file - * │ └── de/ // de language folder - * │ │ └── example.html // de localized file - * │ └── de-AT/ // de-AT locale folder - * │ │ └── example.html // de-AT localized file - * - * Files are matched with the locale in the following order: - * 1. Locale match, e.g. locale `de-AT` matches file in folder `de-AT`. - * 2. Language match, e.g. locale `de-AT` matches file in folder `de`. - * 3. Default; file in base folder is returned. - * - * @param {String} defaultPath The absolute file path, which is also - * the default path returned if localization is not available. - * @param {String} locale The locale. - * @returns {Promise} The object contains: - * - `path`: The path to the localized file, or the original path if - * localization is not available. - * - `subdir`: The subdirectory of the localized file, or undefined if - * there is no matching localized file. - */ - static async getLocalizedPath(defaultPath, locale) { - // Get file name and paths - const file = path.basename(defaultPath); - const basePath = path.dirname(defaultPath); // If locale is not set return default file - - if (!locale) { - return { - path: defaultPath - }; - } // Check file for locale exists - - - const localePath = path.join(basePath, locale, file); - const localeFileExists = await Utils.fileExists(localePath); // If file for locale exists return file - - if (localeFileExists) { - return { - path: localePath, - subdir: locale - }; - } // Check file for language exists - - - const language = locale.split('-')[0]; - const languagePath = path.join(basePath, language, file); - const languageFileExists = await Utils.fileExists(languagePath); // If file for language exists return file - - if (languageFileExists) { - return { - path: languagePath, - subdir: language - }; - } // Return default file - - - return { - path: defaultPath - }; - } - /** - * @function fileExists - * @description Checks whether a file exists. - * @param {String} path The file path. - * @returns {Promise} Is true if the file can be accessed, false otherwise. - */ - - - static async fileExists(path) { - try { - await fs.access(path); - return true; - } catch (e) { - return false; - } - } - /** - * @function isPath - * @description Evaluates whether a string is a file path (as opposed to a URL for example). - * @param {String} s The string to evaluate. - * @returns {Boolean} Returns true if the evaluated string is a path. - */ - - - static isPath(s) { - return /(^\/)|(^\.\/)|(^\.\.\/)/.test(s); - } - /** - * Flattens an object and crates new keys with custom delimiters. - * @param {Object} obj The object to flatten. - * @param {String} [delimiter='.'] The delimiter of the newly generated keys. - * @param {Object} result - * @returns {Object} The flattened object. - **/ - - - static flattenObject(obj, parentKey, delimiter = '.', result = {}) { - for (const key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - const newKey = parentKey ? parentKey + delimiter + key : key; - - if (typeof obj[key] === 'object' && obj[key] !== null) { - this.flattenObject(obj[key], newKey, delimiter, result); - } else { - result[newKey] = obj[key]; - } - } - } - - return result; - } - -} - -module.exports = Utils; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9VdGlscy5qcyJdLCJuYW1lcyI6WyJwYXRoIiwicmVxdWlyZSIsImZzIiwicHJvbWlzZXMiLCJVdGlscyIsImdldExvY2FsaXplZFBhdGgiLCJkZWZhdWx0UGF0aCIsImxvY2FsZSIsImZpbGUiLCJiYXNlbmFtZSIsImJhc2VQYXRoIiwiZGlybmFtZSIsImxvY2FsZVBhdGgiLCJqb2luIiwibG9jYWxlRmlsZUV4aXN0cyIsImZpbGVFeGlzdHMiLCJzdWJkaXIiLCJsYW5ndWFnZSIsInNwbGl0IiwibGFuZ3VhZ2VQYXRoIiwibGFuZ3VhZ2VGaWxlRXhpc3RzIiwiYWNjZXNzIiwiZSIsImlzUGF0aCIsInMiLCJ0ZXN0IiwiZmxhdHRlbk9iamVjdCIsIm9iaiIsInBhcmVudEtleSIsImRlbGltaXRlciIsInJlc3VsdCIsImtleSIsIk9iamVjdCIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIm5ld0tleSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBLE1BQU1BLElBQUksR0FBR0MsT0FBTyxDQUFDLE1BQUQsQ0FBcEI7O0FBQ0EsTUFBTUMsRUFBRSxHQUFHRCxPQUFPLENBQUMsSUFBRCxDQUFQLENBQWNFLFFBQXpCO0FBRUE7QUFDQTtBQUNBOzs7QUFDQSxNQUFNQyxLQUFOLENBQVk7QUFDVjtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNFLGVBQWFDLGdCQUFiLENBQThCQyxXQUE5QixFQUEyQ0MsTUFBM0MsRUFBbUQ7QUFDakQ7QUFDQSxVQUFNQyxJQUFJLEdBQUdSLElBQUksQ0FBQ1MsUUFBTCxDQUFjSCxXQUFkLENBQWI7QUFDQSxVQUFNSSxRQUFRLEdB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dXJjZXNDb250ZW50IjpbIi8qKlxuICogdXRpbHMuanNcbiAqIEBmaWxlIEdlbmVyYWwgcHVycG9zZSB1dGlsaXRpZXNcbiAqIEBkZXNjcmlwdGlvbiBHZW5lcmFsIHB1cnBvc2UgdXRpbGl0aWVzLlxuICovXG5cbmNvbnN0IHBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG5jb25zdCBmcyA9IHJlcXVpcmUoJ2ZzJykucHJvbWlzZXM7XG5cbi8qKlxuICogVGhlIGdlbmVyYWwgcHVycG9zZSB1dGlsaXRpZXMuXG4gKi9cbmNsYXNzIFV0aWxzIHtcbiAgLyoqXG4gICAqIEBmdW5jdGlvbiBnZXRMb2NhbGl6ZWRQYXRoXG4gICAqIEBkZXNjcmlwdGlvbiBSZXR1cm5zIGEgbG9jYWxpemVkIGZpbGUgcGF0aCBhY2NvcmluZyB0byB0aGUgbG9jYWxlLlxuICAgKlxuICAgKiBMb2NhbGl6ZWQgZmlsZXMgYXJlIHNlYXJjaGVkIGluIHN1YmZvbGRlcnMgb2YgYSBnaXZlbiBwYXRoLCBlLmcuXG4gICAqXG4gICAqIHJvb3QvXG4gICAqIOKUnOKUgOKUgCBiYXNlLyAgICAgICAgICAgICAgICAgICAgLy8gYmFzZSBwYXRoIHRvIGZpbGVzXG4gICAqIOKUgiAgIOKUnOKUgOKUgCBleGFtcGxlLmh0bWwgICAgICAgICAvLyBkZWZhdWx0IGZpbGVcbiAgICog4pSCICAg4pSU4pSA4pSAIGRlLyAgICAgICAgICAgICAgICAgIC8vIGRlIGxhbmd1YWdlIGZvbGRlclxuICAgKiDilIIgICDilIIgICDilJTilIDilIAgZXhhbXBsZS5odG1sICAgICAvLyBkZSBsb2NhbGl6ZWQgZmlsZVxuICAgKiDilIIgICDilJTilIDilIAgZGUtQVQvICAgICAgICAgICAgICAgLy8gZGUtQVQgbG9jYWxlIGZvbGRlclxuICAgKiDilIIgICDilIIgICDilJTilIDilIAgZXhhbXBsZS5odG1sICAgICAvLyBkZS1BVCBsb2NhbGl6ZWQgZmlsZVxuICAgKlxuICAgKiBGaWxlcyBhcmUgbWF0Y2hlZCB3aXRoIHRoZSBsb2NhbGUgaW4gdGhlIGZvbGxvd2luZyBvcmRlcjpcbiAgICogMS4gTG9jYWxlIG1hdGNoLCBlLmcuIGxvY2FsZSBgZGUtQVRgIG1hdGNoZXMgZmlsZSBpbiBmb2xkZXIgYGRlLUFUYC5cbiAgICogMi4gTGFuZ3VhZ2UgbWF0Y2gsIGUuZy4gbG9jYWxlIGBkZS1BVGAgbWF0Y2hlcyBmaWxlIGluIGZvbGRlciBgZGVgLlxuICAgKiAzLiBEZWZhdWx0OyBmaWxlIGluIGJhc2UgZm9sZGVyIGlzIHJldHVybmVkLlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gZGVmYXVsdFBhdGggVGhlIGFic29sdXRlIGZpbGUgcGF0aCwgd2hpY2ggaXMgYWxzb1xuICAgKiB0aGUgZGVmYXVsdCBwYXRoIHJldHVybmVkIGlmIGxvY2FsaXphdGlvbiBpcyBub3QgYXZhaWxhYmxlLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gbG9jYWxlIFRoZSBsb2NhbGUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPE9iamVjdD59IFRoZSBvYmplY3QgY29udGFpbnM6XG4gICAqIC0gYHBhdGhgOiBUaGUgcGF0aCB0byB0aGUgbG9jYWxpemVkIGZpbGUsIG9yIHRoZSBvcmlnaW5hbCBwYXRoIGlmXG4gICAqICAgbG9jYWxpemF0aW9uIGlzIG5vdCBhdmFpbGFibGUuXG4gICAqIC0gYHN1YmRpcmA6IFRoZSBzdWJkaXJlY3Rvcnkgb2YgdGhlIGxvY2FsaXplZCBmaWxlLCBvciB1bmRlZmluZWQgaWZcbiAgICogICB0aGVyZSBpcyBubyBtYXRjaGluZyBsb2NhbGl6ZWQgZmlsZS5cbiAgICovXG4gIHN0YXRpYyBhc3luYyBnZXRMb2NhbGl6ZWRQYXRoKGRlZmF1bHRQYXRoLCBsb2NhbGUpIHtcbiAgICAvLyBHZXQgZmlsZSBuYW1lIGFuZCBwYXRoc1xuICAgIGNvbnN0IGZpbGUgPSBwYXRoLmJhc2VuYW1lKGRlZmF1bHRQYXRoKTtcbiAgICBjb25zdCBiYXNlUGF0aCA9IHBhdGguZGlybmFtZShkZWZhdWx0UGF0aCk7XG5cbiAgICAvLyBJZiBsb2NhbGUgaXMgbm90IHNldCByZXR1cm4gZGVmYXVsdCBmaWxlXG4gICAgaWYgKCFsb2NhbGUpIHtcbiAgICAgIHJldHVybiB7IHBhdGg6IGRlZmF1bHRQYXRoIH07XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZmlsZSBmb3IgbG9jYWxlIGV4aXN0c1xuICAgIGNvbnN0IGxvY2FsZVBhdGggPSBwYXRoLmpvaW4oYmFzZVBhdGgsIGxvY2FsZSwgZmlsZSk7XG4gICAgY29uc3QgbG9jYWxlRmlsZUV4aXN0cyA9IGF3YWl0IFV0aWxzLmZpbGVFeGlzdHMobG9jYWxlUGF0aCk7XG5cbiAgICAvLyBJZiBmaWxlIGZvciBsb2NhbGUgZXhpc3RzIHJldHVybiBmaWxlXG4gICAgaWYgKGxvY2FsZUZpbGVFeGlzdHMpIHtcbiAgICAgIHJldHVybiB7IHBhdGg6IGxvY2FsZVBhdGgsIHN1YmRpcjogbG9jYWxlIH07XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZmlsZSBmb3IgbGFuZ3VhZ2UgZXhpc3RzXG4gICAgY29uc3QgbGFuZ3VhZ2UgPSBsb2NhbGUuc3BsaXQoJy0nKVswXTtcbiAgICBjb25zdCBsYW5ndWFnZVBhdGggPSBwYXRoLmpvaW4oYmFzZVBhdGgsIGxhbmd1YWdlLCBmaWxlKTtcbiAgICBjb25zdCBsYW5ndWFnZUZpbGVFeGlzdHMgPSBhd2FpdCBVdGlscy5maWxlRXhpc3RzKGxhbmd1YWdlUGF0aCk7XG5cbiAgICAvLyBJZiBmaWxlIGZvciBsYW5ndWFnZSBleGlzdHMgcmV0dXJuIGZpbGVcbiAgICBpZiAobGFuZ3VhZ2VGaWxlRXhpc3RzKSB7XG4gICAgICByZXR1cm4geyBwYXRoOiBsYW5ndWFnZVBhdGgsIHN1YmRpcjogbGFuZ3VhZ2UgfTtcbiAgICB9XG5cbiAgICAvLyBSZXR1cm4gZGVmYXVsdCBmaWxlXG4gICAgcmV0dXJuIHsgcGF0aDogZGVmYXVsdFBhdGggfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZnVuY3Rpb24gZmlsZUV4aXN0c1xuICAgKiBAZGVzY3JpcHRpb24gQ2hlY2tzIHdoZXRoZXIgYSBmaWxlIGV4aXN0cy5cbiAgICogQHBhcmFtIHtTdHJpbmd9IHBhdGggVGhlIGZpbGUgcGF0aC5cbiAgICogQHJldHVybnMge1Byb21pc2U8Qm9vbGVhbj59IElzIHRydWUgaWYgdGhlIGZpbGUgY2FuIGJlIGFjY2Vzc2VkLCBmYWxzZSBvdGhlcndpc2UuXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgZmlsZUV4aXN0cyhwYXRoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGZzLmFjY2VzcyhwYXRoKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGZ1bmN0aW9uIGlzUGF0aFxuICAgKiBAZGVzY3JpcHRpb24gRXZhbHVhdGVzIHdoZXRoZXIgYSBzdHJpbmcgaXMgYSBmaWxlIHBhdGggKGFzIG9wcG9zZWQgdG8gYSBVUkwgZm9yIGV4YW1wbGUpLlxuICAgKiBAcGFyYW0ge1N0cmluZ30gcyBUaGUgc3RyaW5nIHRvIGV2YWx1YXRlLlxuICAgKiBAcmV0dXJucyB7Qm9vbGVhbn0gUmV0dXJucyB0cnVlIGlmIHRoZSBldmFsdWF0ZWQgc3RyaW5nIGlzIGEgcGF0aC5cbiAgICovXG4gIHN0YXRpYyBpc1BhdGgocykge1xuICAgIHJldHVybiAvKF5cXC8pfCheXFwuXFwvKXwoXlxcLlxcLlxcLykvLnRlc3Qocyk7XG4gIH1cblxuICAvKipcbiAgICogRmxhdHRlbnMgYW4gb2JqZWN0IGFuZCBjcmF0ZXMgbmV3IGtleXMgd2l0aCBjdXN0b20gZGVsaW1pdGVycy5cbiAgICogQHBhcmFtIHtPYmplY3R9IG9iaiBUaGUgb2JqZWN0IHRvIGZsYXR0ZW4uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBbZGVsaW1pdGVyPScuJ10gVGhlIGRlbGltaXRlciBvZiB0aGUgbmV3bHkgZ2VuZXJhdGVkIGtleXMuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSByZXN1bHRcbiAgICogQHJldHVybnMge09iamVjdH0gVGhlIGZsYXR0ZW5lZCBvYmplY3QuXG4gICAqKi9cbiAgc3RhdGljIGZsYXR0ZW5PYmplY3Qob2JqLCBwYXJlbnRLZXksIGRlbGltaXRlciA9ICcuJywgcmVzdWx0ID0ge30pIHtcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBvYmopIHtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSB7XG4gICAgICAgIGNvbnN0IG5ld0tleSA9IHBhcmVudEtleSA/IHBhcmVudEtleSArIGRlbGltaXRlciArIGtleSA6IGtleTtcblxuICAgICAgICBpZiAodHlwZW9mIG9ialtrZXldID09PSAnb2JqZWN0JyAmJiBvYmpba2V5XSAhPT0gbnVsbCkge1xuICAgICAgICAgIHRoaXMuZmxhdHRlbk9iamVjdChvYmpba2V5XSwgbmV3S2V5LCBkZWxpbWl0ZXIsIHJlc3VsdCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdWx0W25ld0tleV0gPSBvYmpba2V5XTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gVXRpbHM7XG4iXX0= \ No newline at end of file diff --git a/lib/batch.js b/lib/batch.js deleted file mode 100644 index 1e8ede10ab..0000000000 --- a/lib/batch.js +++ /dev/null @@ -1,135 +0,0 @@ -"use strict"; - -const Parse = require('parse/node').Parse; - -const url = require('url'); - -const path = require('path'); // These methods handle batch requests. - - -const batchPath = '/batch'; // Mounts a batch-handler onto a PromiseRouter. - -function mountOnto(router) { - router.route('POST', batchPath, req => { - return handleBatch(router, req); - }); -} - -function parseURL(URL) { - if (typeof URL === 'string') { - return url.parse(URL); - } - - return undefined; -} - -function makeBatchRoutingPathFunction(originalUrl, serverURL, publicServerURL) { - serverURL = serverURL ? parseURL(serverURL) : undefined; - publicServerURL = publicServerURL ? parseURL(publicServerURL) : undefined; - const apiPrefixLength = originalUrl.length - batchPath.length; - let apiPrefix = originalUrl.slice(0, apiPrefixLength); - - const makeRoutablePath = function (requestPath) { - // The routablePath is the path minus the api prefix - if (requestPath.slice(0, apiPrefix.length) != apiPrefix) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'cannot route batch path ' + requestPath); - } - - return path.posix.join('/', requestPath.slice(apiPrefix.length)); - }; - - if (serverURL && publicServerURL && serverURL.path != publicServerURL.path) { - const localPath = serverURL.path; - const publicPath = publicServerURL.path; // Override the api prefix - - apiPrefix = localPath; - return function (requestPath) { - // Figure out which server url was used by figuring out which - // path more closely matches requestPath - const startsWithLocal = requestPath.startsWith(localPath); - const startsWithPublic = requestPath.startsWith(publicPath); - const pathLengthToUse = startsWithLocal && startsWithPublic ? Math.max(localPath.length, publicPath.length) : startsWithLocal ? localPath.length : publicPath.length; - const newPath = path.posix.join('/', localPath, '/', requestPath.slice(pathLengthToUse)); // Use the method for local routing - - return makeRoutablePath(newPath); - }; - } - - return makeRoutablePath; -} // Returns a promise for a {response} object. -// TODO: pass along auth correctly - - -function handleBatch(router, req) { - if (!Array.isArray(req.body.requests)) { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'requests must be an array'); - } // The batch paths are all from the root of our domain. - // That means they include the API prefix, that the API is mounted - // to. However, our promise router does not route the api prefix. So - // we need to figure out the API prefix, so that we can strip it - // from all the subrequests. - - - if (!req.originalUrl.endsWith(batchPath)) { - throw 'internal routing problem - expected url to end with batch'; - } - - const makeRoutablePath = makeBatchRoutingPathFunction(req.originalUrl, req.config.serverURL, req.config.publicServerURL); - let initialPromise = Promise.resolve(); - - if (req.body.transaction === true) { - initialPromise = req.config.database.createTransactionalSession(); - } - - return initialPromise.then(() => { - const promises = req.body.requests.map(restRequest => { - const routablePath = makeRoutablePath(restRequest.path); // Construct a request that we can send to a handler - - const request = { - body: restRequest.body, - config: req.config, - auth: req.auth, - info: req.info - }; - return router.tryRouteRequest(restRequest.method, routablePath, request).then(response => { - return { - success: response.response - }; - }, error => { - return { - error: { - code: error.code, - error: error.message - } - }; - }); - }); - return Promise.all(promises).then(results => { - if (req.body.transaction === true) { - if (results.find(result => typeof result.error === 'object')) { - return req.config.database.abortTransactionalSession().then(() => { - return Promise.reject({ - response: results - }); - }); - } else { - return req.config.database.commitTransactionalSession().then(() => { - return { - response: results - }; - }); - } - } else { - return { - response: results - }; - } - }); - }); -} - -module.exports = { - mountOnto, - makeBatchRoutingPathFunction -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9iYXRjaC5qcyJdLCJuYW1lcyI6WyJQYXJzZSIsInJlcXVpcmUiLCJ1cmwiLCJwYXRoIiwiYmF0Y2hQYXRoIiwibW91bnRPbnRvIiwicm91dGVyIiwicm91dGUiLCJyZXEiLCJoYW5kbGVCYXRjaCIsInBhcnNlVVJMIiwiVVJMIiwicGFyc2UiLCJ1bmRlZmluZWQiLCJtYWtlQmF0Y2hSb3V0aW5nUGF0aEZ1bmN0aW9uIiwib3JpZ2luYWxVcmwiLCJzZXJ2ZXJVUkwiLCJwdWJsaWNTZXJ2ZXJVUkwiLCJhcGlQcmVmaXhMZW5ndGgiLCJsZW5ndGgiLCJhcGlQcmVmaXgiLCJzbGljZSIsIm1ha2VSb3V0YWJsZVBhdGgiLCJyZXF1ZXN0UGF0aCIsIkVycm9yIiwiSU5WQUxJRF9KU09OIiwicG9zaXgiLCJqb2luIiwibG9jYWxQYXRoIiwicHVibGljUGF0aCIsInN0YXJ0c1dpdGhMb2NhbCIsInN0YXJ0c1dpdGgiLCJzdGFydHNXaXRoUHVibGljIiwicGF0aExlbmd0aFRvVXNlIiwiTWF0aCIsIm1heCIsIm5ld1BhdGgiLCJBcnJheSIsImlzQXJyYXkiLCJib2R5IiwicmVxdWVzdHMiLCJlbmRzV2l0aCIsImNvbmZpZyIsImluaXRpYWxQcm9taXNlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ0cmFuc2FjdGlvbiIsImRhdGFiYXNlIiwiY3JlYXRlVHJhbnNhY3Rpb25hbFNlc3Npb24iLCJ0aGVuIiwicHJvbWlzZXMiLCJtYXAiLCJyZXN0UmVxdWVzdCIsInJvdXRhYmxlUGF0aCIsInJlcXVlc3QiLCJhdXRoIiwiaW5mbyIsInRyeVJvdXRlUmVxdWVzdCIsIm1ldGhvZCIsInJlc3BvbnNlIiwic3VjY2VzcyIsImVycm9yIiwiY29kZSIsIm1lc3NhZ2UiLCJhbGwiLCJyZXN1bHRzIiwiZmluZCIsInJlc3VsdCIsImFib3J0VHJhbnNhY3Rpb25hbFNlc3Npb24iLCJyZWplY3QiLCJjb21taXRUcmFuc2FjdGlvbmFsU2Vzc2lvbiIsIm1vZHVsZSIsImV4cG9y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RCxHQUFHLENBQUNrQyxNQUFKLENBQVdLLFFBQVgsQ0FBb0JxQix5QkFBcEIsR0FBZ0RuQixJQUFoRCxDQUFxRCxNQUFNO0FBQ2hFLG1CQUFPTCxPQUFPLENBQUN5QixNQUFSLENBQWU7QUFBRVYsY0FBQUEsUUFBUSxFQUFFTTtBQUFaLGFBQWYsQ0FBUDtBQUNELFdBRk0sQ0FBUDtBQUdELFNBSkQsTUFJTztBQUNMLGlCQUFPekQsR0FBRyxDQUFDa0MsTUFBSixDQUFXSyxRQUFYLENBQW9CdUIsMEJBQXBCLEdBQWlEckIsSUFBakQsQ0FBc0QsTUFBTTtBQUNqRSxtQkFBTztBQUFFVSxjQUFBQSxRQUFRLEVBQUVNO0FBQVosYUFBUDtBQUNELFdBRk0sQ0FBUDtBQUdEO0FBQ0YsT0FWRCxNQVVPO0FBQ0wsZUFBTztBQUFFTixVQUFBQSxRQUFRLEVBQUVNO0FBQVosU0FBUDtBQUNEO0FBQ0YsS0FkTSxDQUFQO0FBZUQsR0FyQ00sQ0FBUDtBQXNDRDs7QUFFRE0sTUFBTSxDQUFDQyxPQUFQLEdBQWlCO0FBQ2ZuRSxFQUFBQSxTQURlO0FBRWZTLEVBQUFBO0FBRmUsQ0FBakIiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmNvbnN0IHVybCA9IHJlcXVpcmUoJ3VybCcpO1xuY29uc3QgcGF0aCA9IHJlcXVpcmUoJ3BhdGgnKTtcbi8vIFRoZXNlIG1ldGhvZHMgaGFuZGxlIGJhdGNoIHJlcXVlc3RzLlxuY29uc3QgYmF0Y2hQYXRoID0gJy9iYXRjaCc7XG5cbi8vIE1vdW50cyBhIGJhdGNoLWhhbmRsZXIgb250byBhIFByb21pc2VSb3V0ZXIuXG5mdW5jdGlvbiBtb3VudE9udG8ocm91dGVyKSB7XG4gIHJvdXRlci5yb3V0ZSgnUE9TVCcsIGJhdGNoUGF0aCwgcmVxID0+IHtcbiAgICByZXR1cm4gaGFuZGxlQmF0Y2gocm91dGVyLCByZXEpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gcGFyc2VVUkwoVVJMKSB7XG4gIGlmICh0eXBlb2YgVVJMID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB1cmwucGFyc2UoVVJMKTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBtYWtlQmF0Y2hSb3V0aW5nUGF0aEZ1bmN0aW9uKG9yaWdpbmFsVXJsLCBzZXJ2ZXJVUkwsIHB1YmxpY1NlcnZlclVSTCkge1xuICBzZXJ2ZXJVUkwgPSBzZXJ2ZXJVUkwgPyBwYXJzZVVSTChzZXJ2ZXJVUkwpIDogdW5kZWZpbmVkO1xuICBwdWJsaWNTZXJ2ZXJVUkwgPSBwdWJsaWNTZXJ2ZXJVUkwgPyBwYXJzZVVSTChwdWJsaWNTZXJ2ZXJVUkwpIDogdW5kZWZpbmVkO1xuXG4gIGNvbnN0IGFwaVByZWZpeExlbmd0aCA9IG9yaWdpbmFsVXJsLmxlbmd0aCAtIGJhdGNoUGF0aC5sZW5ndGg7XG4gIGxldCBhcGlQcmVmaXggPSBvcmlnaW5hbFVybC5zbGljZSgwLCBhcGlQcmVmaXhMZW5ndGgpO1xuXG4gIGNvbnN0IG1ha2VSb3V0YWJsZVBhdGggPSBmdW5jdGlvbiAocmVxdWVzdFBhdGgpIHtcbiAgICAvLyBUaGUgcm91dGFibGVQYXRoIGlzIHRoZSBwYXRoIG1pbnVzIHRoZSBhcGkgcHJlZml4XG4gICAgaWYgKHJlcXVlc3RQYXRoLnNsaWNlKDAsIGFwaVByZWZpeC5sZW5ndGgpICE9IGFwaVByZWZpeCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ2Nhbm5vdCByb3V0ZSBiYXRjaCBwYXRoICcgKyByZXF1ZXN0UGF0aCk7XG4gICAgfVxuICAgIHJldHVybiBwYXRoLnBvc2l4LmpvaW4oJy8nLCByZXF1ZXN0UGF0aC5zbGljZShhcGlQcmVmaXgubGVuZ3RoKSk7XG4gIH07XG5cbiAgaWYgKHNlcnZlclVSTCAmJiBwdWJsaWNTZXJ2ZXJVUkwgJiYgc2VydmVyVVJMLnBhdGggIT0gcHVibGljU2VydmVyVVJMLnBhdGgpIHtcbiAgICBjb25zdCBsb2NhbFBhdGggPSBzZXJ2ZXJVUkwucGF0aDtcbiAgICBjb25zdCBwdWJsaWNQYXRoID0gcHVibGljU2VydmVyVVJMLnBhdGg7XG5cbiAgICAvLyBPdmVycmlkZSB0aGUgYXBpIHByZWZpeFxuICAgIGFwaVByZWZpeCA9IGxvY2FsUGF0aDtcbiAgICByZXR1cm4gZnVuY3Rpb24gKHJlcXVlc3RQYXRoKSB7XG4gICAgICAvLyBGaWd1cmUgb3V0IHdoaWNoIHNlcnZlciB1cmwgd2FzIHVzZWQgYnkgZmlndXJpbmcgb3V0IHdoaWNoXG4gICAgICAvLyBwYXRoIG1vcmUgY2xvc2VseSBtYXRjaGVzIHJlcXVlc3RQYXRoXG4gICAgICBjb25zdCBzdGFydHNXaXRoTG9jYWwgPSByZXF1ZXN0UGF0aC5zdGFydHNXaXRoKGxvY2FsUGF0aCk7XG4gICAgICBjb25zdCBzdGFydHNXaXRoUHVibGljID0gcmVxdWVzdFBhdGguc3RhcnRzV2l0aChwdWJsaWNQYXRoKTtcbiAgICAgIGNvbnN0IHBhdGhMZW5ndGhUb1VzZSA9XG4gICAgICAgIHN0YXJ0c1dpdGhMb2NhbCAmJiBzdGFydHNXaXRoUHVibGljXG4gICAgICAgICAgPyBNYXRoLm1heChsb2NhbFBhdGgubGVuZ3RoLCBwdWJsaWNQYXRoLmxlbmd0aClcbiAgICAgICAgICA6IHN0YXJ0c1dpdGhMb2NhbFxuICAgICAgICAgICAgPyBsb2NhbFBhdGgubGVuZ3RoXG4gICAgICAgICAgICA6IHB1YmxpY1BhdGgubGVuZ3RoO1xuXG4gICAgICBjb25zdCBuZXdQYXRoID0gcGF0aC5wb3NpeC5qb2luKCcvJywgbG9jYWxQYXRoLCAnLycsIHJlcXVlc3RQYXRoLnNsaWNlKHBhdGhMZW5ndGhUb1VzZSkpO1xuXG4gICAgICAvLyBVc2UgdGhlIG1ldGhvZCBmb3IgbG9jYWwgcm91dGluZ1xuICAgICAgcmV0dXJuIG1ha2VSb3V0YWJsZVBhdGgobmV3UGF0aCk7XG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiBtYWtlUm91dGFibGVQYXRoO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYSB7cmVzcG9uc2V9IG9iamVjdC5cbi8vIFRPRE86IHBhc3MgYWxvbmcgYXV0aCBjb3JyZWN0bHlcbmZ1bmN0aW9uIGhhbmRsZUJhdGNoKHJvdXRlciwgcmVxKSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShyZXEuYm9keS5yZXF1ZXN0cykpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAncmVxdWVzdHMgbXVzdCBiZSBhbiBhcnJheScpO1xuICB9XG5cbiAgLy8gVGhlIGJhdGNoIHBhdGhzIGFyZSBhbGwgZnJvbSB0aGUgcm9vdCBvZiBvdXIgZG9tYWluLlxuICAvLyBUaGF0IG1lYW5zIHRoZXkgaW5jbHVkZSB0aGUgQVBJIHByZWZpeCwgdGhhdCB0aGUgQVBJIGlzIG1vdW50ZWRcbiAgLy8gdG8uIEhvd2V2ZXIsIG91ciBwcm9taXNlIHJvdXRlciBkb2VzIG5vdCByb3V0ZSB0aGUgYXBpIHByZWZpeC4gU29cbiAgLy8gd2UgbmVlZCB0byBmaWd1cmUgb3V0IHRoZSBBUEkgcHJlZml4LCBzbyB0aGF0IHdlIGNhbiBzdHJpcCBpdFxuICAvLyBmcm9tIGFsbCB0aGUgc3VicmVxdWVzdHMuXG4gIGlmICghcmVxLm9yaWdpbmFsVXJsLmVuZHNXaXRoKGJhdGNoUGF0aCkpIHtcbiAgICB0aHJvdyAnaW50ZXJuYWwgcm91dGluZyBwcm9ibGVtIC0gZXhwZWN0ZWQgdXJsIHRvIGVuZCB3aXRoIGJhdGNoJztcbiAgfVxuXG4gIGNvbnN0IG1ha2VSb3V0YWJsZVBhdGggPSBtYWtlQmF0Y2hSb3V0aW5nUGF0aEZ1bmN0aW9uKFxuICAgIHJlcS5vcmlnaW5hbFVybCxcbiAgICByZXEuY29uZmlnLnNlcnZlclVSTCxcbiAgICByZXEuY29uZmlnLnB1YmxpY1NlcnZlclVSTFxuICApO1xuXG4gIGxldCBpbml0aWFsUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSgpO1xuICBpZiAocmVxLmJvZHkudHJhbnNhY3Rpb24gPT09IHRydWUpIHtcbiAgICBpbml0aWFsUHJvbWlzZSA9IHJlcS5jb25maWcuZGF0YWJhc2UuY3JlYXRlVHJhbnNhY3Rpb25hbFNlc3Npb24oKTtcbiAgfVxuXG4gIHJldHVybiBpbml0aWFsUHJvbWlzZS50aGVuKCgpID0+IHtcbiAgICBjb25zdCBwcm9taXNlcyA9IHJlcS5ib2R5LnJlcXVlc3RzLm1hcChyZXN0UmVxdWVzdCA9PiB7XG4gICAgICBjb25zdCByb3V0YWJsZVBhdGggPSBtYWtlUm91dGFibGVQYXRoKHJlc3RSZXF1ZXN0LnBhdGgpO1xuXG4gICAgICAvLyBDb25zdHJ1Y3QgYSByZXF1ZXN0IHRoYXQgd2UgY2FuIHNlbmQgdG8gYSBoYW5kbGVyXG4gICAgICBjb25zdCByZXF1ZXN0ID0ge1xuICAgICAgICBib2R5OiByZXN0UmVxdWVzdC5ib2R5LFxuICAgICAgICBjb25maWc6IHJlcS5jb25maWcsXG4gICAgICAgIGF1dGg6IHJlcS5hdXRoLFxuICAgICAgICBpbmZvOiByZXEuaW5mbyxcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiByb3V0ZXIudHJ5Um91dGVSZXF1ZXN0KHJlc3RSZXF1ZXN0Lm1ldGhvZCwgcm91dGFibGVQYXRoLCByZXF1ZXN0KS50aGVuKFxuICAgICAgICByZXNwb25zZSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogcmVzcG9uc2UucmVzcG9uc2UgfTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3IgPT4ge1xuICAgICAgICAgIHJldHVybiB7IGVycm9yOiB7IGNvZGU6IGVycm9yLmNvZGUsIGVycm9yOiBlcnJvci5tZXNzYWdlIH0gfTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbihyZXN1bHRzID0+IHtcbiAgICAgIGlmIChyZXEuYm9keS50cmFuc2FjdGlvbiA9PT0gdHJ1ZSkge1xuICAgICAgICBpZiAocmVzdWx0cy5maW5kKHJlc3VsdCA9PiB0eXBlb2YgcmVzdWx0LmVycm9yID09PSAnb2JqZWN0JykpIHtcbiAgICAgICAgICByZXR1cm4gcmVxLmNvbmZpZy5kYXRhYmFzZS5hYm9ydFRyYW5zYWN0aW9uYWxTZXNzaW9uKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoeyByZXNwb25zZTogcmVzdWx0cyB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gcmVxLmNvbmZpZy5kYXRhYmFzZS5jb21taXRUcmFuc2FjdGlvbmFsU2Vzc2lvbigpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHJlc3VsdHMgfTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHsgcmVzcG9uc2U6IHJlc3VsdHMgfTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBtb3VudE9udG8sXG4gIG1ha2VCYXRjaFJvdXRpbmdQYXRoRnVuY3Rpb24sXG59O1xuIl19 \ No newline at end of file diff --git a/lib/cache.js b/lib/cache.js deleted file mode 100644 index ddeda818f9..0000000000 --- a/lib/cache.js +++ /dev/null @@ -1,16 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.AppCache = void 0; - -var _InMemoryCache = require("./Adapters/Cache/InMemoryCache"); - -var AppCache = new _InMemoryCache.InMemoryCache({ - ttl: NaN -}); -exports.AppCache = AppCache; -var _default = AppCache; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jYWNoZS5qcyJdLCJuYW1lcyI6WyJBcHBDYWNoZSIsIkluTWVtb3J5Q2FjaGUiLCJ0dGwiLCJOYU4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFFTyxJQUFJQSxRQUFRLEdBQUcsSUFBSUMsNEJBQUosQ0FBa0I7QUFBRUMsRUFBQUEsR0FBRyxFQUFFQztBQUFQLENBQWxCLENBQWY7O2VBQ1FILFEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbk1lbW9yeUNhY2hlIH0gZnJvbSAnLi9BZGFwdGVycy9DYWNoZS9Jbk1lbW9yeUNhY2hlJztcblxuZXhwb3J0IHZhciBBcHBDYWNoZSA9IG5ldyBJbk1lbW9yeUNhY2hlKHsgdHRsOiBOYU4gfSk7XG5leHBvcnQgZGVmYXVsdCBBcHBDYWNoZTtcbiJdfQ== \ No newline at end of file diff --git a/lib/cli/definitions/parse-live-query-server.js b/lib/cli/definitions/parse-live-query-server.js deleted file mode 100644 index cc12de8412..0000000000 --- a/lib/cli/definitions/parse-live-query-server.js +++ /dev/null @@ -1,12 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -const LiveQueryServerOptions = require('../../Options/Definitions').LiveQueryServerOptions; - -var _default = LiveQueryServerOptions; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGkvZGVmaW5pdGlvbnMvcGFyc2UtbGl2ZS1xdWVyeS1zZXJ2ZXIuanMiXSwibmFtZXMiOlsiTGl2ZVF1ZXJ5U2VydmVyT3B0aW9ucyIsInJlcXVpcmUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQSxNQUFNQSxzQkFBc0IsR0FBR0MsT0FBTyxDQUFDLDJCQUFELENBQVAsQ0FBcUNELHNCQUFwRTs7ZUFDZUEsc0IiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBMaXZlUXVlcnlTZXJ2ZXJPcHRpb25zID0gcmVxdWlyZSgnLi4vLi4vT3B0aW9ucy9EZWZpbml0aW9ucycpLkxpdmVRdWVyeVNlcnZlck9wdGlvbnM7XG5leHBvcnQgZGVmYXVsdCBMaXZlUXVlcnlTZXJ2ZXJPcHRpb25zO1xuIl19 \ No newline at end of file diff --git a/lib/cli/definitions/parse-server.js b/lib/cli/definitions/parse-server.js deleted file mode 100644 index 0bd5a64da5..0000000000 --- a/lib/cli/definitions/parse-server.js +++ /dev/null @@ -1,12 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -const ParseServerDefinitions = require('../../Options/Definitions').ParseServerOptions; - -var _default = ParseServerDefinitions; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGkvZGVmaW5pdGlvbnMvcGFyc2Utc2VydmVyLmpzIl0sIm5hbWVzIjpbIlBhcnNlU2VydmVyRGVmaW5pdGlvbnMiLCJyZXF1aXJlIiwiUGFyc2VTZXJ2ZXJPcHRpb25zIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUEsTUFBTUEsc0JBQXNCLEdBQUdDLE9BQU8sQ0FBQywyQkFBRCxDQUFQLENBQXFDQyxrQkFBcEU7O2VBQ2VGLHNCIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgUGFyc2VTZXJ2ZXJEZWZpbml0aW9ucyA9IHJlcXVpcmUoJy4uLy4uL09wdGlvbnMvRGVmaW5pdGlvbnMnKS5QYXJzZVNlcnZlck9wdGlvbnM7XG5leHBvcnQgZGVmYXVsdCBQYXJzZVNlcnZlckRlZmluaXRpb25zO1xuIl19 \ No newline at end of file diff --git a/lib/cli/parse-live-query-server.js b/lib/cli/parse-live-query-server.js deleted file mode 100644 index 346727035d..0000000000 --- a/lib/cli/parse-live-query-server.js +++ /dev/null @@ -1,19 +0,0 @@ -"use strict"; - -var _parseLiveQueryServer = _interopRequireDefault(require("./definitions/parse-live-query-server")); - -var _runner = _interopRequireDefault(require("./utils/runner")); - -var _index = require("../index"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -(0, _runner.default)({ - definitions: _parseLiveQueryServer.default, - start: function (program, options, logOptions) { - logOptions(); - - _index.ParseServer.createLiveQueryServer(undefined, options); - } -}); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGkvcGFyc2UtbGl2ZS1xdWVyeS1zZXJ2ZXIuanMiXSwibmFtZXMiOlsiZGVmaW5pdGlvbnMiLCJzdGFydCIsInByb2dyYW0iLCJvcHRpb25zIiwibG9nT3B0aW9ucyIsIlBhcnNlU2VydmVyIiwiY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyIiwidW5kZWZpbmVkIl0sIm1hcHBpbmdzIjoiOztBQUFBOztBQUNBOztBQUNBOzs7O0FBRUEscUJBQU87QUFDTEEsRUFBQUEsV0FBVyxFQUFYQSw2QkFESztBQUVMQyxFQUFBQSxLQUFLLEVBQUUsVUFBVUMsT0FBVixFQUFtQkMsT0FBbkIsRUFBNEJDLFVBQTVCLEVBQXdDO0FBQzdDQSxJQUFBQSxVQUFVOztBQUNWQyx1QkFBWUMscUJBQVosQ0FBa0NDLFNBQWxDLEVBQTZDSixPQUE3QztBQUNEO0FBTEksQ0FBUCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBkZWZpbml0aW9ucyBmcm9tICcuL2RlZmluaXRpb25zL3BhcnNlLWxpdmUtcXVlcnktc2VydmVyJztcbmltcG9ydCBydW5uZXIgZnJvbSAnLi91dGlscy9ydW5uZXInO1xuaW1wb3J0IHsgUGFyc2VTZXJ2ZXIgfSBmcm9tICcuLi9pbmRleCc7XG5cbnJ1bm5lcih7XG4gIGRlZmluaXRpb25zLFxuICBzdGFydDogZnVuY3Rpb24gKHByb2dyYW0sIG9wdGlvbnMsIGxvZ09wdGlvbnMpIHtcbiAgICBsb2dPcHRpb25zKCk7XG4gICAgUGFyc2VTZXJ2ZXIuY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyKHVuZGVmaW5lZCwgb3B0aW9ucyk7XG4gIH0sXG59KTtcbiJdfQ== \ No newline at end of file diff --git a/lib/cli/parse-server.js b/lib/cli/parse-server.js deleted file mode 100755 index 188991e3fe..0000000000 --- a/lib/cli/parse-server.js +++ /dev/null @@ -1,111 +0,0 @@ -"use strict"; - -var _index = _interopRequireDefault(require("../index")); - -var _parseServer = _interopRequireDefault(require("./definitions/parse-server")); - -var _cluster = _interopRequireDefault(require("cluster")); - -var _os = _interopRequireDefault(require("os")); - -var _runner = _interopRequireDefault(require("./utils/runner")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/* eslint-disable no-console */ -const help = function () { - console.log(' Get Started guide:'); - console.log(''); - console.log(' Please have a look at the get started guide!'); - console.log(' http://docs.parseplatform.org/parse-server/guide/'); - console.log(''); - console.log(''); - console.log(' Usage with npm start'); - console.log(''); - console.log(' $ npm start -- path/to/config.json'); - console.log(' $ npm start -- --appId APP_ID --masterKey MASTER_KEY --serverURL serverURL'); - console.log(' $ npm start -- --appId APP_ID --masterKey MASTER_KEY --serverURL serverURL'); - console.log(''); - console.log(''); - console.log(' Usage:'); - console.log(''); - console.log(' $ parse-server path/to/config.json'); - console.log(' $ parse-server -- --appId APP_ID --masterKey MASTER_KEY --serverURL serverURL'); - console.log(' $ parse-server -- --appId APP_ID --masterKey MASTER_KEY --serverURL serverURL'); - console.log(''); -}; - -(0, _runner.default)({ - definitions: _parseServer.default, - help, - usage: '[options] ', - start: function (program, options, logOptions) { - if (!options.appId || !options.masterKey) { - program.outputHelp(); - console.error(''); - console.error('\u001b[31mERROR: appId and masterKey are required\u001b[0m'); - console.error(''); - process.exit(1); - } - - if (options['liveQuery.classNames']) { - options.liveQuery = options.liveQuery || {}; - options.liveQuery.classNames = options['liveQuery.classNames']; - delete options['liveQuery.classNames']; - } - - if (options['liveQuery.redisURL']) { - options.liveQuery = options.liveQuery || {}; - options.liveQuery.redisURL = options['liveQuery.redisURL']; - delete options['liveQuery.redisURL']; - } - - if (options['liveQuery.redisOptions']) { - options.liveQuery = options.liveQuery || {}; - options.liveQuery.redisOptions = options['liveQuery.redisOptions']; - delete options['liveQuery.redisOptions']; - } - - if (options.cluster) { - const numCPUs = typeof options.cluster === 'number' ? options.cluster : _os.default.cpus().length; - - if (_cluster.default.isMaster) { - logOptions(); - - for (let i = 0; i < numCPUs; i++) { - _cluster.default.fork(); - } - - _cluster.default.on('exit', (worker, code) => { - console.log(`worker ${worker.process.pid} died (${code})... Restarting`); - - _cluster.default.fork(); - }); - } else { - _index.default.start(options, () => { - printSuccessMessage(); - }); - } - } else { - _index.default.start(options, () => { - logOptions(); - console.log(''); - printSuccessMessage(); - }); - } - - function printSuccessMessage() { - console.log('[' + process.pid + '] parse-server running on ' + options.serverURL); - - if (options.mountGraphQL) { - console.log('[' + process.pid + '] GraphQL running on http://localhost:' + options.port + options.graphQLPath); - } - - if (options.mountPlayground) { - console.log('[' + process.pid + '] Playground running on http://localhost:' + options.port + options.playgroundPath); - } - } - } -}); -/* eslint-enable no-console */ -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGkvcGFyc2Utc2VydmVyLmpzIl0sIm5hbWVzIjpbImhlbHAiLCJjb25zb2xlIiwibG9nIiwiZGVmaW5pdGlvbnMiLCJ1c2FnZSIsInN0YXJ0IiwicHJvZ3JhbSIsIm9wdGlvbnMiLCJsb2dPcHRpb25zIiwiYXBwSWQiLCJtYXN0ZXJLZXkiLCJvdXRwdXRIZWxwIiwiZXJyb3IiLCJwcm9jZXNzIiwiZXhpdCIsImxpdmVRdWVyeSIsImNsYXNzTmFtZXMiLCJyZWRpc1VSTCIsInJlZGlzT3B0aW9ucyIsImNsdXN0ZXIiLCJudW1DUFVzIiwib3MiLCJjcHVzIiwibGVuZ3RoIiwiaXNNYXN0ZXIiLCJpIiwiZm9yayIsIm9uIiwid29ya2VyIiwiY29kZSIsInBpZCIsIlBhcnNlU2VydmVyIiwicHJpbnRTdWNjZXNzTWVzc2FnZSIsInNlcnZlclVSTCIsIm1vdW50R3JhcGhRTCIsInBvcnQiLCJncmFwaFFMUGF0aCIsIm1vdW50UGxheWdyb3VuZCIsInBsYXlncm91bmRQYXRoIl0sIm1hcHBpbmdzIjoiOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBTEE7QUFPQSxNQUFNQSxJQUFJLEdBQUcsWUFBWTtBQUN2QkMsRUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksc0JBQVo7QUFDQUQsRUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksRUFBWjtBQUNBRCxFQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSxrREFBWjtBQUNBRCxFQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSx1REFBWjtBQUNBRCxFQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSxFQUFaO0FBQ0FELEVBQUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFZLEVBQVo7QUFDQUQsRUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksd0JBQVo7QUFDQUQsRUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQVksRUFBWjtBQUNBRCxFQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSx3Q0FBWjtBQUNB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QUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFhLFVBQVMwQixNQUFNLENBQUNmLE9BQVAsQ0FBZWlCLEdBQUksVUFBU0QsSUFBSyxpQkFBdkQ7O0FBQ0FWLDJCQUFRTyxJQUFSO0FBQ0QsU0FIRDtBQUlELE9BVEQsTUFTTztBQUNMSyx1QkFBWTFCLEtBQVosQ0FBa0JFLE9BQWxCLEVBQTJCLE1BQU07QUFDL0J5QixVQUFBQSxtQkFBbUI7QUFDcEIsU0FGRDtBQUdEO0FBQ0YsS0FoQkQsTUFnQk87QUFDTEQscUJBQVkxQixLQUFaLENBQWtCRSxPQUFsQixFQUEyQixNQUFNO0FBQy9CQyxRQUFBQSxVQUFVO0FBQ1ZQLFFBQUFBLE9BQU8sQ0FBQ0MsR0FBUixDQUFZLEVBQVo7QUFDQThCLFFBQUFBLG1CQUFtQjtBQUNwQixPQUpEO0FBS0Q7O0FBRUQsYUFBU0EsbUJBQVQsR0FBK0I7QUFDN0IvQixNQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBWSxNQUFNVyxPQUFPLENBQUNpQixHQUFkLEdBQW9CLDRCQUFwQixHQUFtRHZCLE9BQU8sQ0FBQzBCLFNBQXZFOztBQUNBLFVBQUkxQixPQUFPLENBQUMyQixZQUFaLEVBQTBCO0FBQ3hCakMsUUFBQUEsT0FBTyxDQUFDQyxHQUFSLENBQ0UsTUFDRVcsT0FBTyxDQUFDaUIsR0FEVixHQUVFLHdDQUZGLEdBR0V2QixPQUFPLENBQUM0QixJQUhWLEdBSUU1QixPQUFPLENBQUM2QixXQUxaO0FBT0Q7O0FBQ0QsVUFBSTdCLE9BQU8sQ0FBQzhCLGVBQVosRUFBNkI7QUFDM0JwQyxRQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FDRSxNQUNFVyxPQUFPLENBQUNpQixHQURWLEdBRUUsMkNBRkYsR0FHRXZCLE9BQU8sQ0FBQzRCLElBSFYsR0FJRTVCLE9BQU8sQ0FBQytCLGNBTFo7QUFPRDtBQUNGO0FBQ0Y7QUExRUksQ0FBUDtBQTZFQSIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbmltcG9ydCBQYXJzZVNlcnZlciBmcm9tICcuLi9pbmRleCc7XG5pbXBvcnQgZGVmaW5pdGlvbnMgZnJvbSAnLi9kZWZpbml0aW9ucy9wYXJzZS1zZXJ2ZXInO1xuaW1wb3J0IGNsdXN0ZXIgZnJvbSAnY2x1c3Rlcic7XG5pbXBvcnQgb3MgZnJvbSAnb3MnO1xuaW1wb3J0IHJ1bm5lciBmcm9tICcuL3V0aWxzL3J1bm5lcic7XG5cbmNvbnN0IGhlbHAgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnNvbGUubG9nKCcgIEdldCBTdGFydGVkIGd1aWRlOicpO1xuICBjb25zb2xlLmxvZygnJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgUGxlYXNlIGhhdmUgYSBsb29rIGF0IHRoZSBnZXQgc3RhcnRlZCBndWlkZSEnKTtcbiAgY29uc29sZS5sb2coJyAgICBodHRwOi8vZG9jcy5wYXJzZXBsYXRmb3JtLm9yZy9wYXJzZS1zZXJ2ZXIvZ3VpZGUvJyk7XG4gIGNvbnNvbGUubG9nKCcnKTtcbiAgY29uc29sZS5sb2coJycpO1xuICBjb25zb2xlLmxvZygnICBVc2FnZSB3aXRoIG5wbSBzdGFydCcpO1xuICBjb25zb2xlLmxvZygnJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgJCBucG0gc3RhcnQgLS0gcGF0aC90by9jb25maWcuanNvbicpO1xuICBjb25zb2xlLmxvZygnICAgICQgbnBtIHN0YXJ0IC0tIC0tYXBwSWQgQVBQX0lEIC0tbWFzdGVyS2V5IE1BU1RFUl9LRVkgLS1zZXJ2ZXJVUkwgc2VydmVyVVJMJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgJCBucG0gc3RhcnQgLS0gLS1hcHBJZCBBUFBfSUQgLS1tYXN0ZXJLZXkgTUFTVEVSX0tFWSAtLXNlcnZlclVSTCBzZXJ2ZXJVUkwnKTtcbiAgY29uc29sZS5sb2coJycpO1xuICBjb25zb2xlLmxvZygnJyk7XG4gIGNvbnNvbGUubG9nKCcgIFVzYWdlOicpO1xuICBjb25zb2xlLmxvZygnJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgJCBwYXJzZS1zZXJ2ZXIgcGF0aC90by9jb25maWcuanNvbicpO1xuICBjb25zb2xlLmxvZygnICAgICQgcGFyc2Utc2VydmVyIC0tIC0tYXBwSWQgQVBQX0lEIC0tbWFzdGVyS2V5IE1BU1RFUl9LRVkgLS1zZXJ2ZXJVUkwgc2VydmVyVVJMJyk7XG4gIGNvbnNvbGUubG9nKCcgICAgJCBwYXJzZS1zZXJ2ZXIgLS0gLS1hcHBJZCBBUFBfSUQgLS1tYXN0ZXJLZXkgTUFTVEVSX0tFWSAtLXNlcnZlclVSTCBzZXJ2ZXJVUkwnKTtcbiAgY29uc29sZS5sb2coJycpO1xufTtcblxucnVubmVyKHtcbiAgZGVmaW5pdGlvbnMsXG4gIGhlbHAsXG4gIHVzYWdlOiAnW29wdGlvbnNdIDxwYXRoL3RvL2NvbmZpZ3VyYXRpb24uanNvbj4nLFxuICBzdGFydDogZnVuY3Rpb24gKHByb2dyYW0sIG9wdGlvbnMsIGxvZ09wdGlvbnMpIHtcbiAgICBpZiAoIW9wdGlvbnMuYXBwSWQgfHwgIW9wdGlvbnMubWFzdGVyS2V5KSB7XG4gICAgICBwcm9ncmFtLm91dHB1dEhlbHAoKTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJycpO1xuICAgICAgY29uc29sZS5lcnJvcignXFx1MDAxYlszMW1FUlJPUjogYXBwSWQgYW5kIG1hc3RlcktleSBhcmUgcmVxdWlyZWRcXHUwMDFiWzBtJyk7XG4gICAgICBjb25zb2xlLmVycm9yKCcnKTtcbiAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9uc1snbGl2ZVF1ZXJ5LmNsYXNzTmFtZXMnXSkge1xuICAgICAgb3B0aW9ucy5saXZlUXVlcnkgPSBvcHRpb25zLmxpdmVRdWVyeSB8fCB7fTtcbiAgICAgIG9wdGlvbnMubGl2ZVF1ZXJ5LmNsYXNzTmFtZXMgPSBvcHRpb25zWydsaXZlUXVlcnkuY2xhc3NOYW1lcyddO1xuICAgICAgZGVsZXRlIG9wdGlvbnNbJ2xpdmVRdWVyeS5jbGFzc05hbWVzJ107XG4gICAgfVxuICAgIGlmIChvcHRpb25zWydsaXZlUXVlcnkucmVkaXNVUkwnXSkge1xuICAgICAgb3B0aW9ucy5saXZlUXVlcnkgPSBvcHRpb25zLmxpdmVRdWVyeSB8fCB7fTtcbiAgICAgIG9wdGlvbnMubGl2ZVF1ZXJ5LnJlZGlzVVJMID0gb3B0aW9uc1snbGl2ZVF1ZXJ5LnJlZGlzVVJMJ107XG4gICAgICBkZWxldGUgb3B0aW9uc1snbGl2ZVF1ZXJ5LnJlZGlzVVJMJ107XG4gICAgfVxuICAgIGlmIChvcHRpb25zWydsaXZlUXVlcnkucmVkaXNPcHRpb25zJ10pIHtcbiAgICAgIG9wdGlvbnMubGl2ZVF1ZXJ5ID0gb3B0aW9ucy5saXZlUXVlcnkgfHwge307XG4gICAgICBvcHRpb25zLmxpdmVRdWVyeS5yZWRpc09wdGlvbnMgPSBvcHRpb25zWydsaXZlUXVlcnkucmVkaXNPcHRpb25zJ107XG4gICAgICBkZWxldGUgb3B0aW9uc1snbGl2ZVF1ZXJ5LnJlZGlzT3B0aW9ucyddO1xuICAgIH1cblxuICAgIGlmIChvcHRpb25zLmNsdXN0ZXIpIHtcbiAgICAgIGNvbnN0IG51bUNQVXMgPSB0eXBlb2Ygb3B0aW9ucy5jbHVzdGVyID09PSAnbnVtYmVyJyA/IG9wdGlvbnMuY2x1c3RlciA6IG9zLmNwdXMoKS5sZW5ndGg7XG4gICAgICBpZiAoY2x1c3Rlci5pc01hc3Rlcikge1xuICAgICAgICBsb2dPcHRpb25zKCk7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtQ1BVczsgaSsrKSB7XG4gICAgICAgICAgY2x1c3Rlci5mb3JrKCk7XG4gICAgICAgIH1cbiAgICAgICAgY2x1c3Rlci5vbignZXhpdCcsICh3b3JrZXIsIGNvZGUpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgd29ya2VyICR7d29ya2VyLnByb2Nlc3MucGlkfSBkaWVkICgke2NvZGV9KS4uLiBSZXN0YXJ0aW5nYCk7XG4gICAgICAgICAgY2x1c3Rlci5mb3JrKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgUGFyc2VTZXJ2ZXIuc3RhcnQob3B0aW9ucywgKCkgPT4ge1xuICAgICAgICAgIHByaW50U3VjY2Vzc01lc3NhZ2UoKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIFBhcnNlU2VydmVyLnN0YXJ0KG9wdGlvbnMsICgpID0+IHtcbiAgICAgICAgbG9nT3B0aW9ucygpO1xuICAgICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICAgIHByaW50U3VjY2Vzc01lc3NhZ2UoKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHByaW50U3VjY2Vzc01lc3NhZ2UoKSB7XG4gICAgICBjb25zb2xlLmxvZygnWycgKyBwcm9jZXNzLnBpZCArICddIHBhcnNlLXNlcnZlciBydW5uaW5nIG9uICcgKyBvcHRpb25zLnNlcnZlclVSTCk7XG4gICAgICBpZiAob3B0aW9ucy5tb3VudEdyYXBoUUwpIHtcbiAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgJ1snICtcbiAgICAgICAgICAgIHByb2Nlc3MucGlkICtcbiAgICAgICAgICAgICddIEdyYXBoUUwgcnVubmluZyBvbiBodHRwOi8vbG9jYWxob3N0OicgK1xuICAgICAgICAgICAgb3B0aW9ucy5wb3J0ICtcbiAgICAgICAgICAgIG9wdGlvbnMuZ3JhcGhRTFBhdGhcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHRpb25zLm1vdW50UGxheWdyb3VuZCkge1xuICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAnWycgK1xuICAgICAgICAgICAgcHJvY2Vzcy5waWQgK1xuICAgICAgICAgICAgJ10gUGxheWdyb3VuZCBydW5uaW5nIG9uIGh0dHA6Ly9sb2NhbGhvc3Q6JyArXG4gICAgICAgICAgICBvcHRpb25zLnBvcnQgK1xuICAgICAgICAgICAgb3B0aW9ucy5wbGF5Z3JvdW5kUGF0aFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbn0pO1xuXG4vKiBlc2xpbnQtZW5hYmxlIG5vLWNvbnNvbGUgKi9cbiJdfQ== \ No newline at end of file diff --git a/lib/cli/utils/commander.js b/lib/cli/utils/commander.js deleted file mode 100644 index d1164c5c63..0000000000 --- a/lib/cli/utils/commander.js +++ /dev/null @@ -1,163 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _commander = require("commander"); - -var _path = _interopRequireDefault(require("path")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/* eslint-disable no-console */ -let _definitions; - -let _reverseDefinitions; - -let _defaults; - -_commander.Command.prototype.loadDefinitions = function (definitions) { - _definitions = definitions; - Object.keys(definitions).reduce((program, opt) => { - if (typeof definitions[opt] == 'object') { - const additionalOptions = definitions[opt]; - - if (additionalOptions.required === true) { - return program.option(`--${opt} <${opt}>`, additionalOptions.help, additionalOptions.action); - } else { - return program.option(`--${opt} [${opt}]`, additionalOptions.help, additionalOptions.action); - } - } - - return program.option(`--${opt} [${opt}]`); - }, this); - _reverseDefinitions = Object.keys(definitions).reduce((object, key) => { - let value = definitions[key]; - - if (typeof value == 'object') { - value = value.env; - } - - if (value) { - object[value] = key; - } - - return object; - }, {}); - _defaults = Object.keys(definitions).reduce((defs, opt) => { - if (_definitions[opt].default) { - defs[opt] = _definitions[opt].default; - } - - return defs; - }, {}); - /* istanbul ignore next */ - - this.on('--help', function () { - console.log(' Configure From Environment:'); - console.log(''); - Object.keys(_reverseDefinitions).forEach(key => { - console.log(` $ ${key}='${_reverseDefinitions[key]}'`); - }); - console.log(''); - }); -}; - -function parseEnvironment(env = {}) { - return Object.keys(_reverseDefinitions).reduce((options, key) => { - if (env[key]) { - const originalKey = _reverseDefinitions[key]; - - let action = option => option; - - if (typeof _definitions[originalKey] === 'object') { - action = _definitions[originalKey].action || action; - } - - options[_reverseDefinitions[key]] = action(env[key]); - } - - return options; - }, {}); -} - -function parseConfigFile(program) { - let options = {}; - - if (program.args.length > 0) { - let jsonPath = program.args[0]; - jsonPath = _path.default.resolve(jsonPath); - - const jsonConfig = require(jsonPath); - - if (jsonConfig.apps) { - if (jsonConfig.apps.length > 1) { - throw 'Multiple apps are not supported'; - } - - options = jsonConfig.apps[0]; - } else { - options = jsonConfig; - } - - Object.keys(options).forEach(key => { - const value = options[key]; - - if (!_definitions[key]) { - throw `error: unknown option ${key}`; - } - - const action = _definitions[key].action; - - if (action) { - options[key] = action(value); - } - }); - console.log(`Configuration loaded from ${jsonPath}`); - } - - return options; -} - -_commander.Command.prototype.setValuesIfNeeded = function (options) { - Object.keys(options).forEach(key => { - if (!Object.prototype.hasOwnProperty.call(this, key)) { - this[key] = options[key]; - } - }); -}; - -_commander.Command.prototype._parse = _commander.Command.prototype.parse; - -_commander.Command.prototype.parse = function (args, env) { - this._parse(args); // Parse the environment first - - - const envOptions = parseEnvironment(env); - const fromFile = parseConfigFile(this); // Load the env if not passed from command line - - this.setValuesIfNeeded(envOptions); // Load from file to override - - this.setValuesIfNeeded(fromFile); // Last set the defaults - - this.setValuesIfNeeded(_defaults); -}; - -_commander.Command.prototype.getOptions = function () { - return Object.keys(_definitions).reduce((options, key) => { - if (typeof this[key] !== 'undefined') { - options[key] = this[key]; - } - - return options; - }, {}); -}; - -var _default = new _commander.Command(); -/* eslint-enable no-console */ - - -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGkvdXRpbHMvY29tbWFuZGVyLmpzIl0sIm5hbWVzIjpbIl9kZWZpbml0aW9ucyIsIl9yZXZlcnNlRGVmaW5pdGlvbnMiLCJfZGVmYXVsdHMiLCJDb21tYW5kIiwicHJvdG90eXBlIiwibG9hZERlZmluaXRpb25zIiwiZGVmaW5pdGlvbnMiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwicHJvZ3JhbSIsIm9wdCIsImFkZGl0aW9uYWxPcHRpb25zIiwicmVxdWlyZWQiLCJvcHRpb24iLCJoZWxwIiwiYWN0aW9uIiwib2JqZWN0Iiwia2V5IiwidmFsdWUiLCJlbnYiLCJkZWZzIiwiZGVmYXVsdCIsIm9uIiwiY29uc29sZSIsImxvZyIsImZvckVhY2giLCJwYXJzZUVudmlyb25tZW50Iiwib3B0aW9ucyIsIm9yaWdpbmFsS2V5IiwicGFyc2VDb25maWdGaWxlIiwiYXJncyIsImxlbmd0aCIsImpzb25QYXRoIiwicGF0aCIsInJlc29sdmUiLCJqc29uQ29uZmlnIiwicmVxdWlyZSIsImFwcHMiLCJzZXRWYWx1ZXNJZk5lZWRlZCIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIl9wYXJzZSIsInBhcnNlIiwiZW52T3B0aW9ucyIsImZyb21GaWxlIiwiZ2V0T3B0aW9ucyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUNBOztBQUNBOzs7O0FBRkE7QUFHQSxJQUFJQSxZQUFKOztBQUNBLElBQUlDLG1CQUFKOztBQUNBLElBQUlDLFNBQUo7O0FBRUFDLG1CQUFRQyxTQUFSLENBQWtCQyxlQUFsQixHQUFvQyxVQUFVQyxXQUFWLEVBQXVCO0FBQ3pETixFQUFBQSxZQUFZLEdBQUdNLFdBQWY7QUFFQUMsRUFBQUEsTUFBTSxDQUFDQyxJQUFQLENBQVlGLFdBQVosRUFBeUJHLE1BQXpCLENBQWdDLENBQUNDLE9BQUQsRUFBVUMsR0FBVixLQUFrQjtBQUNoRCxRQUFJLE9BQU9MLFdBQVcsQ0FBQ0ssR0FBRCxDQUFsQixJQUEyQixRQUEvQixFQUF5QztB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QUFSLENBQWtCMEMsVUFBbEIsR0FBK0IsWUFBWTtBQUN6QyxTQUFPdkMsTUFBTSxDQUFDQyxJQUFQLENBQVlSLFlBQVosRUFBMEJTLE1BQTFCLENBQWlDLENBQUNtQixPQUFELEVBQVVWLEdBQVYsS0FBa0I7QUFDeEQsUUFBSSxPQUFPLEtBQUtBLEdBQUwsQ0FBUCxLQUFxQixXQUF6QixFQUFzQztBQUNwQ1UsTUFBQUEsT0FBTyxDQUFDVixHQUFELENBQVAsR0FBZSxLQUFLQSxHQUFMLENBQWY7QUFDRDs7QUFDRCxXQUFPVSxPQUFQO0FBQ0QsR0FMTSxFQUtKLEVBTEksQ0FBUDtBQU1ELENBUEQ7O2VBU2UsSUFBSXpCLGtCQUFKLEU7QUFDZiIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cbmltcG9ydCB7IENvbW1hbmQgfSBmcm9tICdjb21tYW5kZXInO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5sZXQgX2RlZmluaXRpb25zO1xubGV0IF9yZXZlcnNlRGVmaW5pdGlvbnM7XG5sZXQgX2RlZmF1bHRzO1xuXG5Db21tYW5kLnByb3RvdHlwZS5sb2FkRGVmaW5pdGlvbnMgPSBmdW5jdGlvbiAoZGVmaW5pdGlvbnMpIHtcbiAgX2RlZmluaXRpb25zID0gZGVmaW5pdGlvbnM7XG5cbiAgT2JqZWN0LmtleXMoZGVmaW5pdGlvbnMpLnJlZHVjZSgocHJvZ3JhbSwgb3B0KSA9PiB7XG4gICAgaWYgKHR5cGVvZiBkZWZpbml0aW9uc1tvcHRdID09ICdvYmplY3QnKSB7XG4gICAgICBjb25zdCBhZGRpdGlvbmFsT3B0aW9ucyA9IGRlZmluaXRpb25zW29wdF07XG4gICAgICBpZiAoYWRkaXRpb25hbE9wdGlvbnMucmVxdWlyZWQgPT09IHRydWUpIHtcbiAgICAgICAgcmV0dXJuIHByb2dyYW0ub3B0aW9uKFxuICAgICAgICAgIGAtLSR7b3B0fSA8JHtvcHR9PmAsXG4gICAgICAgICAgYWRkaXRpb25hbE9wdGlvbnMuaGVscCxcbiAgICAgICAgICBhZGRpdGlvbmFsT3B0aW9ucy5hY3Rpb25cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBwcm9ncmFtLm9wdGlvbihcbiAgICAgICAgICBgLS0ke29wdH0gWyR7b3B0fV1gLFxuICAgICAgICAgIGFkZGl0aW9uYWxPcHRpb25zLmhlbHAsXG4gICAgICAgICAgYWRkaXRpb25hbE9wdGlvbnMuYWN0aW9uXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwcm9ncmFtLm9wdGlvbihgLS0ke29wdH0gWyR7b3B0fV1gKTtcbiAgfSwgdGhpcyk7XG5cbiAgX3JldmVyc2VEZWZpbml0aW9ucyA9IE9iamVjdC5rZXlzKGRlZmluaXRpb25zKS5yZWR1Y2UoKG9iamVjdCwga2V5KSA9PiB7XG4gICAgbGV0IHZhbHVlID0gZGVmaW5pdGlvbnNba2V5XTtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09ICdvYmplY3QnKSB7XG4gICAgICB2YWx1ZSA9IHZhbHVlLmVudjtcbiAgICB9XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICBvYmplY3RbdmFsdWVdID0ga2V5O1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0O1xuICB9LCB7fSk7XG5cbiAgX2RlZmF1bHRzID0gT2JqZWN0LmtleXMoZGVmaW5pdGlvbnMpLnJlZHVjZSgoZGVmcywgb3B0KSA9PiB7XG4gICAgaWYgKF9kZWZpbml0aW9uc1tvcHRdLmRlZmF1bHQpIHtcbiAgICAgIGRlZnNbb3B0XSA9IF9kZWZpbml0aW9uc1tvcHRdLmRlZmF1bHQ7XG4gICAgfVxuICAgIHJldHVybiBkZWZzO1xuICB9LCB7fSk7XG5cbiAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cbiAgdGhpcy5vbignLS1oZWxwJywgZnVuY3Rpb24gKCkge1xuICAgIGNvbnNvbGUubG9nKCcgIENvbmZpZ3VyZSBGcm9tIEVudmlyb25tZW50OicpO1xuICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICBPYmplY3Qua2V5cyhfcmV2ZXJzZURlZmluaXRpb25zKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBjb25zb2xlLmxvZyhgICAgICQgJHtrZXl9PScke19yZXZlcnNlRGVmaW5pdGlvbnNba2V5XX0nYCk7XG4gICAgfSk7XG4gICAgY29uc29sZS5sb2coJycpO1xuICB9KTtcbn07XG5cbmZ1bmN0aW9uIHBhcnNlRW52aXJvbm1lbnQoZW52ID0ge30pIHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKF9yZXZlcnNlRGVmaW5pdGlvbnMpLnJlZHVjZSgob3B0aW9ucywga2V5KSA9PiB7XG4gICAgaWYgKGVudltrZXldKSB7XG4gICAgICBjb25zdCBvcmlnaW5hbEtleSA9IF9yZXZlcnNlRGVmaW5pdGlvbnNba2V5XTtcbiAgICAgIGxldCBhY3Rpb24gPSBvcHRpb24gPT4gb3B0aW9uO1xuICAgICAgaWYgKHR5cGVvZiBfZGVmaW5pdGlvbnNbb3JpZ2luYWxLZXldID09PSAnb2JqZWN0Jykge1xuICAgICAgICBhY3Rpb24gPSBfZGVmaW5pdGlvbnNbb3JpZ2luYWxLZXldLmFjdGlvbiB8fCBhY3Rpb247XG4gICAgICB9XG4gICAgICBvcHRpb25zW19yZXZlcnNlRGVmaW5pdGlvbnNba2V5XV0gPSBhY3Rpb24oZW52W2tleV0pO1xuICAgIH1cbiAgICByZXR1cm4gb3B0aW9ucztcbiAgfSwge30pO1xufVxuXG5mdW5jdGlvbiBwYXJzZUNvbmZpZ0ZpbGUocHJvZ3JhbSkge1xuICBsZXQgb3B0aW9ucyA9IHt9O1xuICBpZiAocHJvZ3JhbS5hcmdzLmxlbmd0aCA+IDApIHtcbiAgICBsZXQganNvblBhdGggPSBwcm9ncmFtLmFyZ3NbMF07XG4gICAganNvblBhdGggPSBwYXRoLnJlc29sdmUoanNvblBhdGgpO1xuICAgIGNvbnN0IGpzb25Db25maWcgPSByZXF1aXJlKGpzb25QYXRoKTtcbiAgICBpZiAoanNvbkNvbmZpZy5hcHBzKSB7XG4gICAgICBpZiAoanNvbkNvbmZpZy5hcHBzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgdGhyb3cgJ011bHRpcGxlIGFwcHMgYXJlIG5vdCBzdXBwb3J0ZWQnO1xuICAgICAgfVxuICAgICAgb3B0aW9ucyA9IGpzb25Db25maWcuYXBwc1swXTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3B0aW9ucyA9IGpzb25Db25maWc7XG4gICAgfVxuICAgIE9iamVjdC5rZXlzKG9wdGlvbnMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gb3B0aW9uc1trZXldO1xuICAgICAgaWYgKCFfZGVmaW5pdGlvbnNba2V5XSkge1xuICAgICAgICB0aHJvdyBgZXJyb3I6IHVua25vd24gb3B0aW9uICR7a2V5fWA7XG4gICAgICB9XG4gICAgICBjb25zdCBhY3Rpb24gPSBfZGVmaW5pdGlvbnNba2V5XS5hY3Rpb247XG4gICAgICBpZiAoYWN0aW9uKSB7XG4gICAgICAgIG9wdGlvbnNba2V5XSA9IGFjdGlvbih2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc29sZS5sb2coYENvbmZpZ3VyYXRpb24gbG9hZGVkIGZyb20gJHtqc29uUGF0aH1gKTtcbiAgfVxuICByZXR1cm4gb3B0aW9ucztcbn1cblxuQ29tbWFuZC5wcm90b3R5cGUuc2V0VmFsdWVzSWZOZWVkZWQgPSBmdW5jdGlvbiAob3B0aW9ucykge1xuICBPYmplY3Qua2V5cyhvcHRpb25zKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcywga2V5KSkge1xuICAgICAgdGhpc1trZXldID0gb3B0aW9uc1trZXldO1xuICAgIH1cbiAgfSk7XG59O1xuXG5Db21tYW5kLnByb3RvdHlwZS5fcGFyc2UgPSBDb21tYW5kLnByb3RvdHlwZS5wYXJzZTtcblxuQ29tbWFuZC5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbiAoYXJncywgZW52KSB7XG4gIHRoaXMuX3BhcnNlKGFyZ3MpO1xuICAvLyBQYXJzZSB0aGUgZW52aXJvbm1lbnQgZmlyc3RcbiAgY29uc3QgZW52T3B0aW9ucyA9IHBhcnNlRW52aXJvbm1lbnQoZW52KTtcbiAgY29uc3QgZnJvbUZpbGUgPSBwYXJzZUNvbmZpZ0ZpbGUodGhpcyk7XG4gIC8vIExvYWQgdGhlIGVudiBpZiBub3QgcGFzc2VkIGZyb20gY29tbWFuZCBsaW5lXG4gIHRoaXMuc2V0VmFsdWVzSWZOZWVkZWQoZW52T3B0aW9ucyk7XG4gIC8vIExvYWQgZnJvbSBmaWxlIHRvIG92ZXJyaWRlXG4gIHRoaXMuc2V0VmFsdWVzSWZOZWVkZWQoZnJvbUZpbGUpO1xuICAvLyBMYXN0IHNldCB0aGUgZGVmYXVsdHNcbiAgdGhpcy5zZXRWYWx1ZXNJZk5lZWRlZChfZGVmYXVsdHMpO1xufTtcblxuQ29tbWFuZC5wcm90b3R5cGUuZ2V0T3B0aW9ucyA9IGZ1bmN0aW9uICgpIHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKF9kZWZpbml0aW9ucykucmVkdWNlKChvcHRpb25zLCBrZXkpID0+IHtcbiAgICBpZiAodHlwZW9mIHRoaXNba2V5XSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIG9wdGlvbnNba2V5XSA9IHRoaXNba2V5XTtcbiAgICB9XG4gICAgcmV0dXJuIG9wdGlvbnM7XG4gIH0sIHt9KTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IG5ldyBDb21tYW5kKCk7XG4vKiBlc2xpbnQtZW5hYmxlIG5vLWNvbnNvbGUgKi9cbiJdfQ== \ No newline at end of file diff --git a/lib/cli/utils/runner.js b/lib/cli/utils/runner.js deleted file mode 100644 index 38d680d58e..0000000000 --- a/lib/cli/utils/runner.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = _default; - -var _commander = _interopRequireDefault(require("./commander")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function logStartupOptions(options) { - for (const key in options) { - let value = options[key]; - - if (key == 'masterKey') { - value = '***REDACTED***'; - } - - if (key == 'push' && options.verbose != true) { - value = '***REDACTED***'; - } - - if (typeof value === 'object') { - try { - value = JSON.stringify(value); - } catch (e) { - if (value && value.constructor && value.constructor.name) { - value = value.constructor.name; - } - } - } - /* eslint-disable no-console */ - - - console.log(`${key}: ${value}`); - /* eslint-enable no-console */ - } -} - -function _default({ - definitions, - help, - usage, - start -}) { - _commander.default.loadDefinitions(definitions); - - if (usage) { - _commander.default.usage(usage); - } - - if (help) { - _commander.default.on('--help', help); - } - - _commander.default.parse(process.argv, process.env); - - const options = _commander.default.getOptions(); - - start(_commander.default, options, function () { - logStartupOptions(options); - }); -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jbGkvdXRpbHMvcnVubmVyLmpzIl0sIm5hbWVzIjpbImxvZ1N0YXJ0dXBPcHRpb25zIiwib3B0aW9ucyIsImtleSIsInZhbHVlIiwidmVyYm9zZSIsIkpTT04iLCJzdHJpbmdpZnkiLCJlIiwiY29uc3RydWN0b3IiLCJuYW1lIiwiY29uc29sZSIsImxvZyIsImRlZmluaXRpb25zIiwiaGVscCIsInVzYWdlIiwic3RhcnQiLCJwcm9ncmFtIiwibG9hZERlZmluaXRpb25zIiwib24iLCJwYXJzZSIsInByb2Nlc3MiLCJhcmd2IiwiZW52IiwiZ2V0T3B0aW9ucyJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFBOzs7O0FBRUEsU0FBU0EsaUJBQVQsQ0FBMkJDLE9BQTNCLEVBQW9DO0FBQ2xDLE9BQUssTUFBTUMsR0FBWCxJQUFrQkQsT0FBbEIsRUFBMkI7QUFDekIsUUFBSUUsS0FBSyxHQUFHRixPQUFPLENBQUNDLEdBQUQsQ0FBbkI7O0FBQ0EsUUFBSUEsR0FBRyxJQUFJLFdBQVgsRUFBd0I7QUFDdEJDLE1BQUFBLEtBQUssR0FBRyxnQkFBUjtBQUNEOztBQUNELFFBQUlELEdBQUcsSUFBSSxNQUFQLElBQWlCRCxPQUFPLENBQUNHLE9BQVIsSUFBbUIsSUFBeEMsRUFBOEM7QUFDNUNELE1BQUFBLEtBQUssR0FBRyxnQkFBUjtBQUNEOztBQUNELFFBQUksT0FBT0EsS0FBUCxLQUFpQixRQUFyQixFQUErQjtBQUM3QixVQUFJO0FBQ0ZBLFFBQUFBLEtBQUssR0FBR0UsSUFBSSxDQUFDQyxTQUFMLENBQWVILEtBQWYsQ0FBUjtBQUNELE9BRkQsQ0FFRSxPQUFPSSxDQUFQLEVBQVU7QUFDVixZQUFJSixLQUFLLElBQUlBLEtBQUssQ0FBQ0ssV0FBZixJQUE4QkwsS0FBSyxDQUFDSyxXQUFOLENBQWtCQyxJQUFwRCxFQUEwRDtBQUN4RE4sVUFBQUEsS0FBSyxHQUFHQSxLQUFLLENBQUNLLFdBQU4sQ0FBa0JDLElBQTFCO0FBQ0Q7QUFDRjtBQUNGO0FBQ0Q7OztBQUNBQyxJQUFBQSxPQUFPLENBQUNDLEdBQVIsQ0FBYSxHQUFFVCxHQUFJLEtBQUlDLEtBQU0sRUFBN0I7QUFDQTtBQUNEO0FBQ0Y7O0FBRWMsa0JBQVU7QUFBRVMsRUFBQUEsV0FBRjtBQUFlQyxFQUFBQSxJQUFmO0FBQXFCQyxFQUFBQSxLQUFyQjtBQUE0QkMsRUFBQUE7QUFBNUIsQ0FBVixFQUErQztBQUM1REMscUJBQVFDLGVBQVIsQ0FBd0JMLFdBQXhCOztBQUNBLE1BQUlFLEtBQUosRUFBVztBQUNURSx1QkFBUUYsS0FBUixDQUFjQSxLQUFkO0FBQ0Q7O0FBQ0QsTUFBSUQsSUFBSixFQUFVO0FBQ1JHLHVCQUFRRSxFQUFSLENBQVcsUUFBWCxFQUFxQkwsSUFBckI7QUFDRDs7QUFDREcscUJBQVFHLEtBQVIsQ0FBY0MsT0FBTyxDQUFDQyxJQUF0QixFQUE0QkQsT0FBTyxDQUFDRSxHQUFwQzs7QUFFQSxRQUFNckIsT0FBTyxHQUFHZSxtQkFBUU8sVUFBUixFQUFoQjs7QUFDQVIsRUFBQUEsS0FBSyxDQUFDQyxrQkFBRCxFQUFVZixPQUFWLEVBQW1CLFlBQVk7QUFDbENELElBQUFBLGlCQUFpQixDQUFDQyxPQUFELENBQWpCO0FBQ0QsR0FGSSxDQUFMO0FBR0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcHJvZ3JhbSBmcm9tICcuL2NvbW1hbmRlcic7XG5cbmZ1bmN0aW9uIGxvZ1N0YXJ0dXBPcHRpb25zKG9wdGlvbnMpIHtcbiAgZm9yIChjb25zdCBrZXkgaW4gb3B0aW9ucykge1xuICAgIGxldCB2YWx1ZSA9IG9wdGlvbnNba2V5XTtcbiAgICBpZiAoa2V5ID09ICdtYXN0ZXJLZXknKSB7XG4gICAgICB2YWx1ZSA9ICcqKipSRURBQ1RFRCoqKic7XG4gICAgfVxuICAgIGlmIChrZXkgPT0gJ3B1c2gnICYmIG9wdGlvbnMudmVyYm9zZSAhPSB0cnVlKSB7XG4gICAgICB2YWx1ZSA9ICcqKipSRURBQ1RFRCoqKic7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICB0cnkge1xuICAgICAgICB2YWx1ZSA9IEpTT04uc3RyaW5naWZ5KHZhbHVlKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKHZhbHVlICYmIHZhbHVlLmNvbnN0cnVjdG9yICYmIHZhbHVlLmNvbnN0cnVjdG9yLm5hbWUpIHtcbiAgICAgICAgICB2YWx1ZSA9IHZhbHVlLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuICAgIGNvbnNvbGUubG9nKGAke2tleX06ICR7dmFsdWV9YCk7XG4gICAgLyogZXNsaW50LWVuYWJsZSBuby1jb25zb2xlICovXG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHsgZGVmaW5pdGlvbnMsIGhlbHAsIHVzYWdlLCBzdGFydCB9KSB7XG4gIHByb2dyYW0ubG9hZERlZmluaXRpb25zKGRlZmluaXRpb25zKTtcbiAgaWYgKHVzYWdlKSB7XG4gICAgcHJvZ3JhbS51c2FnZSh1c2FnZSk7XG4gIH1cbiAgaWYgKGhlbHApIHtcbiAgICBwcm9ncmFtLm9uKCctLWhlbHAnLCBoZWxwKTtcbiAgfVxuICBwcm9ncmFtLnBhcnNlKHByb2Nlc3MuYXJndiwgcHJvY2Vzcy5lbnYpO1xuXG4gIGNvbnN0IG9wdGlvbnMgPSBwcm9ncmFtLmdldE9wdGlvbnMoKTtcbiAgc3RhcnQocHJvZ3JhbSwgb3B0aW9ucywgZnVuY3Rpb24gKCkge1xuICAgIGxvZ1N0YXJ0dXBPcHRpb25zKG9wdGlvbnMpO1xuICB9KTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/cloud-code/HTTPResponse.js b/lib/cloud-code/HTTPResponse.js deleted file mode 100644 index 0bcf174da1..0000000000 --- a/lib/cloud-code/HTTPResponse.js +++ /dev/null @@ -1,73 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -/** - * @typedef Parse.Cloud.HTTPResponse - * @property {Buffer} buffer The raw byte representation of the response body. Use this to receive binary data. See Buffer for more details. - * @property {Object} cookies The cookies sent by the server. The keys in this object are the names of the cookies. The values are Parse.Cloud.Cookie objects. - * @property {Object} data The parsed response body as a JavaScript object. This is only available when the response Content-Type is application/x-www-form-urlencoded or application/json. - * @property {Object} headers The headers sent by the server. The keys in this object are the names of the headers. We do not support multiple response headers with the same name. In the common case of Set-Cookie headers, please use the cookies field instead. - * @property {Number} status The status code. - * @property {String} text The raw text representation of the response body. - */ -class HTTPResponse { - constructor(response, body) { - let _text, _data; - - this.status = response.statusCode; - this.headers = response.headers || {}; - this.cookies = this.headers['set-cookie']; - - if (typeof body == 'string') { - _text = body; - } else if (Buffer.isBuffer(body)) { - this.buffer = body; - } else if (typeof body == 'object') { - _data = body; - } - - const getText = () => { - if (!_text && this.buffer) { - _text = this.buffer.toString('utf-8'); - } else if (!_text && _data) { - _text = JSON.stringify(_data); - } - - return _text; - }; - - const getData = () => { - if (!_data) { - try { - _data = JSON.parse(getText()); - } catch (e) { - /* */ - } - } - - return _data; - }; - - Object.defineProperty(this, 'body', { - get: () => { - return body; - } - }); - Object.defineProperty(this, 'text', { - enumerable: true, - get: getText - }); - Object.defineProperty(this, 'data', { - enumerable: true, - get: getData - }); - } - -} - -exports.default = HTTPResponse; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbG91ZC1jb2RlL0hUVFBSZXNwb25zZS5qcyJdLCJuYW1lcyI6WyJIVFRQUmVzcG9uc2UiLCJjb25zdHJ1Y3RvciIsInJlc3BvbnNlIiwiYm9keSIsIl90ZXh0IiwiX2RhdGEiLCJzdGF0dXMiLCJzdGF0dXNDb2RlIiwiaGVhZGVycyIsImNvb2tpZXMiLCJCdWZmZXIiLCJpc0J1ZmZlciIsImJ1ZmZlciIsImdldFRleHQiLCJ0b1N0cmluZyIsIkpTT04iLCJzdHJpbmdpZnkiLCJnZXREYXRhIiwicGFyc2UiLCJlIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXQiLCJlbnVtZXJhYmxlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ2UsTUFBTUEsWUFBTixDQUFtQjtBQUNoQ0MsRUFBQUEsV0FBVyxDQUFDQyxRQUFELEVBQVdDLElBQVgsRUFBaUI7QUFDMUIsUUFBSUMsS0FBSixFQUFXQyxLQUFYOztBQUNBLFNBQUtDLE1BQUwsR0FBY0osUUFBUSxDQUFDSyxVQUF2QjtBQUNBLFNBQUtDLE9BQUwsR0FBZU4sUUFBUSxDQUFDTSxPQUFULElBQW9CLEVBQW5DO0FBQ0EsU0FBS0MsT0FBTCxHQUFlLEtBQUtELE9BQUwsQ0FBYSxZQUFiLENBQWY7O0FBRUEsUUFBSSxPQUFPTCxJQUFQLElBQWUsUUFBbkIsRUFBNkI7QUFDM0JDLE1BQUFBLEtBQUssR0FBR0QsSUFBUjtBQUNELEtBRkQsTUFFTyxJQUFJTyxNQUFNLENBQUNDLFFBQVAsQ0FBZ0JSLElBQWhCLENBQUosRUFBMkI7QUFDaEMsV0FBS1MsTUFBTCxHQUFjVCxJQUFkO0FBQ0QsS0FGTSxNQUVBLElBQUksT0FBT0EsSUFBUCxJQUFlLFFBQW5CLEVBQTZCO0FBQ2xDRSxNQUFBQSxLQUFLLEdBQUdGLElBQVI7QUFDRDs7QUFFRCxVQUFNVSxPQUFPLEdBQUcsTUFBTTtBQUNwQixVQUFJLENBQUNULEtBQUQsSUFBVSxLQUFLUSxNQUFuQixFQUEyQjtBQUN6QlIsUUFBQUEsS0FBSyxHQUFHLEtBQUtRLE1BQUwsQ0FBWUUsUUFBWixDQUFxQixPQUFyQixDQUFSO0FBQ0QsT0FGRCxNQUVPLElBQUksQ0FBQ1YsS0FBRCxJQUFVQyxLQUFkLEVBQXFCO0FBQzFCRCxRQUFBQSxLQUFLLEdBQUdXLElBQUksQ0FBQ0MsU0FBTCxDQUFlWCxLQUFmLENBQVI7QUFDRDs7QUFDRCxhQUFPRCxLQUFQO0FBQ0QsS0FQRDs7QUFTQSxVQUFNYSxPQUFPLEdBQUcsTUFBTTtBQUNwQixVQUFJLENBQUNaLEtBQUwsRUFBWTtBQUNWLFlBQUk7QUFDRkEsVUFBQUEsS0FBSyxHQUFHVSxJQUFJLENBQUNHLEtBQUwsQ0FBV0wsT0FBTyxFQUFsQixDQUFSO0FBQ0QsU0FGRCxDQUVFLE9BQU9NLENBQVAsRUFBVTtBQUNWO0FBQ0Q7QUFDRjs7QUFDRCxhQUFPZCxLQUFQO0FBQ0QsS0FURDs7QUFXQWUsSUFBQUEsTUFBTSxDQUFDQyxjQUFQLENBQXNCLElBQXRCLEVBQTRCLE1BQTVCLEVBQW9DO0FBQ2xDQyxNQUFBQSxHQUFHLEVBQUUsTUFBTTtBQUNULGVBQU9uQixJQUFQO0FBQ0Q7QUFIaUMsS0FBcEM7QUFNQWlCLElBQUFBLE1BQU0sQ0FBQ0MsY0FBUCxDQUFzQixJQUF0QixFQUE0QixNQUE1QixFQUFvQztBQUNsQ0UsTUFBQUEsVUFBVSxFQUFFLElBRHNCO0FBRWxDRCxNQUFBQSxHQUFHLEVBQUVUO0FBRjZCLEtBQXBDO0FBS0FPLElBQUFBLE1BQU0sQ0FBQ0MsY0FBUCxDQUFzQixJQUF0QixFQUE0QixNQUE1QixFQUFvQztBQUNsQ0UsTUFBQUEsVUFBVSxFQUFFLElBRHNCO0FBRWxDRCxNQUFBQSxHQUFHLEVBQUVMO0FBRjZCLEtBQXBDO0FBSUQ7O0FBbEQrQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQHR5cGVkZWYgUGFyc2UuQ2xvdWQuSFRUUFJlc3BvbnNlXG4gKiBAcHJvcGVydHkge0J1ZmZlcn0gYnVmZmVyIFRoZSByYXcgYnl0ZSByZXByZXNlbnRhdGlvbiBvZiB0aGUgcmVzcG9uc2UgYm9keS4gVXNlIHRoaXMgdG8gcmVjZWl2ZSBiaW5hcnkgZGF0YS4gU2VlIEJ1ZmZlciBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHByb3BlcnR5IHtPYmplY3R9IGNvb2tpZXMgVGhlIGNvb2tpZXMgc2VudCBieSB0aGUgc2VydmVyLiBUaGUga2V5cyBpbiB0aGlzIG9iamVjdCBhcmUgdGhlIG5hbWVzIG9mIHRoZSBjb29raWVzLiBUaGUgdmFsdWVzIGFyZSBQYXJzZS5DbG91ZC5Db29raWUgb2JqZWN0cy5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBkYXRhIFRoZSBwYXJzZWQgcmVzcG9uc2UgYm9keSBhcyBhIEphdmFTY3JpcHQgb2JqZWN0LiBUaGlzIGlzIG9ubHkgYXZhaWxhYmxlIHdoZW4gdGhlIHJlc3BvbnNlIENvbnRlbnQtVHlwZSBpcyBhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQgb3IgYXBwbGljYXRpb24vanNvbi5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBoZWFkZXJzIFRoZSBoZWFkZXJzIHNlbnQgYnkgdGhlIHNlcnZlci4gVGhlIGtleXMgaW4gdGhpcyBvYmplY3QgYXJlIHRoZSBuYW1lcyBvZiB0aGUgaGVhZGVycy4gV2UgZG8gbm90IHN1cHBvcnQgbXVsdGlwbGUgcmVzcG9uc2UgaGVhZGVycyB3aXRoIHRoZSBzYW1lIG5hbWUuIEluIHRoZSBjb21tb24gY2FzZSBvZiBTZXQtQ29va2llIGhlYWRlcnMsIHBsZWFzZSB1c2UgdGhlIGNvb2tpZXMgZmllbGQgaW5zdGVhZC5cbiAqIEBwcm9wZXJ0eSB7TnVtYmVyfSBzdGF0dXMgVGhlIHN0YXR1cyBjb2RlLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IHRleHQgVGhlIHJhdyB0ZXh0IHJlcHJlc2VudGF0aW9uIG9mIHRoZSByZXNwb25zZSBib2R5LlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBIVFRQUmVzcG9uc2Uge1xuICBjb25zdHJ1Y3RvcihyZXNwb25zZSwgYm9keSkge1xuICAgIGxldCBfdGV4dCwgX2RhdGE7XG4gICAgdGhpcy5zdGF0dXMgPSByZXNwb25zZS5zdGF0dXNDb2RlO1xuICAgIHRoaXMuaGVhZGVycyA9IHJlc3BvbnNlLmhlYWRlcnMgfHwge307XG4gICAgdGhpcy5jb29raWVzID0gdGhpcy5oZWFkZXJzWydzZXQtY29va2llJ107XG5cbiAgICBpZiAodHlwZW9mIGJvZHkgPT0gJ3N0cmluZycpIHtcbiAgICAgIF90ZXh0ID0gYm9keTtcbiAgICB9IGVsc2UgaWYgKEJ1ZmZlci5pc0J1ZmZlcihib2R5KSkge1xuICAgICAgdGhpcy5idWZmZXIgPSBib2R5O1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGJvZHkgPT0gJ29iamVjdCcpIHtcbiAgICAgIF9kYXRhID0gYm9keTtcbiAgICB9XG5cbiAgICBjb25zdCBnZXRUZXh0ID0gKCkgPT4ge1xuICAgICAgaWYgKCFfdGV4dCAmJiB0aGlzLmJ1ZmZlcikge1xuICAgICAgICBfdGV4dCA9IHRoaXMuYnVmZmVyLnRvU3RyaW5nKCd1dGYtOCcpO1xuICAgICAgfSBlbHNlIGlmICghX3RleHQgJiYgX2RhdGEpIHtcbiAgICAgICAgX3RleHQgPSBKU09OLnN0cmluZ2lmeShfZGF0YSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gX3RleHQ7XG4gICAgfTtcblxuICAgIGNvbnN0IGdldERhdGEgPSAoKSA9PiB7XG4gICAgICBpZiAoIV9kYXRhKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgX2RhdGEgPSBKU09OLnBhcnNlKGdldFRleHQoKSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAvKiAqL1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gX2RhdGE7XG4gICAgfTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnYm9keScsIHtcbiAgICAgIGdldDogKCkgPT4ge1xuICAgICAgICByZXR1cm4gYm9keTtcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ3RleHQnLCB7XG4gICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgZ2V0OiBnZXRUZXh0LFxuICAgIH0pO1xuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsICdkYXRhJywge1xuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIGdldDogZ2V0RGF0YSxcbiAgICB9KTtcbiAgfVxufVxuIl19 \ No newline at end of file diff --git a/lib/cloud-code/Parse.Cloud.js b/lib/cloud-code/Parse.Cloud.js deleted file mode 100644 index 11bf1def54..0000000000 --- a/lib/cloud-code/Parse.Cloud.js +++ /dev/null @@ -1,719 +0,0 @@ -"use strict"; - -var _node = require("parse/node"); - -var triggers = _interopRequireWildcard(require("../triggers")); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -const Config = require('../Config'); - -function isParseObjectConstructor(object) { - return typeof object === 'function' && Object.prototype.hasOwnProperty.call(object, 'className'); -} - -function getClassName(parseClass) { - if (parseClass && parseClass.className) { - return parseClass.className; - } - - return parseClass; -} -/** @namespace - * @name Parse - * @description The Parse SDK. - * see [api docs](https://docs.parseplatform.org/js/api) and [guide](https://docs.parseplatform.org/js/guide) - */ - -/** @namespace - * @name Parse.Cloud - * @memberof Parse - * @description The Parse Cloud Code SDK. - */ - - -var ParseCloud = {}; -/** - * Defines a Cloud Function. - * - * **Available in Cloud Code only.** - * - * ``` - * Parse.Cloud.define('functionName', (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.define('functionName', (request) => { - * // code here - * }, { ...validationObject }); - * ``` - * - * @static - * @memberof Parse.Cloud - * @param {String} name The name of the Cloud Function - * @param {Function} data The Cloud Function to register. This function can be an async function and should take one parameter a {@link Parse.Cloud.FunctionRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FunctionRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - -ParseCloud.define = function (functionName, handler, validationHandler) { - triggers.addFunction(functionName, handler, validationHandler, _node.Parse.applicationId); -}; -/** - * Defines a Background Job. - * - * **Available in Cloud Code only.** - * - * @method job - * @name Parse.Cloud.job - * @param {String} name The name of the Background Job - * @param {Function} func The Background Job to register. This function can be async should take a single parameters a {@link Parse.Cloud.JobRequest} - * - */ - - -ParseCloud.job = function (functionName, handler) { - triggers.addJob(functionName, handler, _node.Parse.applicationId); -}; -/** - * - * Registers a before save function. - * - * **Available in Cloud Code only.** - * - * If you want to use beforeSave for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. - * - * ``` - * Parse.Cloud.beforeSave('MyCustomClass', (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.beforeSave(Parse.User, (request) => { - * // code here - * }, { ...validationObject }) - * ``` - * - * @method beforeSave - * @name Parse.Cloud.beforeSave - * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after save function for. This can instead be a String that is the className of the subclass. - * @param {Function} func The function to run before a save. This function can be async and should take one parameter a {@link Parse.Cloud.TriggerRequest}; - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.beforeSave = function (parseClass, handler, validationHandler) { - var className = getClassName(parseClass); - triggers.addTrigger(triggers.Types.beforeSave, className, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Registers a before delete function. - * - * **Available in Cloud Code only.** - * - * If you want to use beforeDelete for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. - * ``` - * Parse.Cloud.beforeDelete('MyCustomClass', (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.beforeDelete(Parse.User, (request) => { - * // code here - * }, { ...validationObject }) - *``` - * - * @method beforeDelete - * @name Parse.Cloud.beforeDelete - * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the before delete function for. This can instead be a String that is the className of the subclass. - * @param {Function} func The function to run before a delete. This function can be async and should take one parameter, a {@link Parse.Cloud.TriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.beforeDelete = function (parseClass, handler, validationHandler) { - var className = getClassName(parseClass); - triggers.addTrigger(triggers.Types.beforeDelete, className, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * - * Registers the before login function. - * - * **Available in Cloud Code only.** - * - * This function provides further control - * in validating a login attempt. Specifically, - * it is triggered after a user enters - * correct credentials (or other valid authData), - * but prior to a session being generated. - * - * ``` - * Parse.Cloud.beforeLogin((request) => { - * // code here - * }) - * - * ``` - * - * @method beforeLogin - * @name Parse.Cloud.beforeLogin - * @param {Function} func The function to run before a login. This function can be async and should take one parameter a {@link Parse.Cloud.TriggerRequest}; - */ - - -ParseCloud.beforeLogin = function (handler) { - let className = '_User'; - - if (typeof handler === 'string' || isParseObjectConstructor(handler)) { - // validation will occur downstream, this is to maintain internal - // code consistency with the other hook types. - className = getClassName(handler); - handler = arguments[1]; - } - - triggers.addTrigger(triggers.Types.beforeLogin, className, handler, _node.Parse.applicationId); -}; -/** - * - * Registers the after login function. - * - * **Available in Cloud Code only.** - * - * This function is triggered after a user logs in successfully, - * and after a _Session object has been created. - * - * ``` - * Parse.Cloud.afterLogin((request) => { - * // code here - * }); - * ``` - * - * @method afterLogin - * @name Parse.Cloud.afterLogin - * @param {Function} func The function to run after a login. This function can be async and should take one parameter a {@link Parse.Cloud.TriggerRequest}; - */ - - -ParseCloud.afterLogin = function (handler) { - let className = '_User'; - - if (typeof handler === 'string' || isParseObjectConstructor(handler)) { - // validation will occur downstream, this is to maintain internal - // code consistency with the other hook types. - className = getClassName(handler); - handler = arguments[1]; - } - - triggers.addTrigger(triggers.Types.afterLogin, className, handler, _node.Parse.applicationId); -}; -/** - * - * Registers the after logout function. - * - * **Available in Cloud Code only.** - * - * This function is triggered after a user logs out. - * - * ``` - * Parse.Cloud.afterLogout((request) => { - * // code here - * }); - * ``` - * - * @method afterLogout - * @name Parse.Cloud.afterLogout - * @param {Function} func The function to run after a logout. This function can be async and should take one parameter a {@link Parse.Cloud.TriggerRequest}; - */ - - -ParseCloud.afterLogout = function (handler) { - let className = '_Session'; - - if (typeof handler === 'string' || isParseObjectConstructor(handler)) { - // validation will occur downstream, this is to maintain internal - // code consistency with the other hook types. - className = getClassName(handler); - handler = arguments[1]; - } - - triggers.addTrigger(triggers.Types.afterLogout, className, handler, _node.Parse.applicationId); -}; -/** - * Registers an after save function. - * - * **Available in Cloud Code only.** - * - * If you want to use afterSave for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. - * - * ``` - * Parse.Cloud.afterSave('MyCustomClass', async function(request) { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.afterSave(Parse.User, async function(request) { - * // code here - * }, { ...validationObject }); - * ``` - * - * @method afterSave - * @name Parse.Cloud.afterSave - * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after save function for. This can instead be a String that is the className of the subclass. - * @param {Function} func The function to run after a save. This function can be an async function and should take just one parameter, {@link Parse.Cloud.TriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.afterSave = function (parseClass, handler, validationHandler) { - var className = getClassName(parseClass); - triggers.addTrigger(triggers.Types.afterSave, className, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Registers an after delete function. - * - * **Available in Cloud Code only.** - * - * If you want to use afterDelete for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. - * ``` - * Parse.Cloud.afterDelete('MyCustomClass', async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.afterDelete(Parse.User, async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method afterDelete - * @name Parse.Cloud.afterDelete - * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after delete function for. This can instead be a String that is the className of the subclass. - * @param {Function} func The function to run after a delete. This function can be async and should take just one parameter, {@link Parse.Cloud.TriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.afterDelete = function (parseClass, handler, validationHandler) { - var className = getClassName(parseClass); - triggers.addTrigger(triggers.Types.afterDelete, className, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Registers a before find function. - * - * **Available in Cloud Code only.** - * - * If you want to use beforeFind for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. - * ``` - * Parse.Cloud.beforeFind('MyCustomClass', async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.beforeFind(Parse.User, async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method beforeFind - * @name Parse.Cloud.beforeFind - * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the before find function for. This can instead be a String that is the className of the subclass. - * @param {Function} func The function to run before a find. This function can be async and should take just one parameter, {@link Parse.Cloud.BeforeFindRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.BeforeFindRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.beforeFind = function (parseClass, handler, validationHandler) { - var className = getClassName(parseClass); - triggers.addTrigger(triggers.Types.beforeFind, className, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Registers an after find function. - * - * **Available in Cloud Code only.** - * - * If you want to use afterFind for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. - * ``` - * Parse.Cloud.afterFind('MyCustomClass', async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.afterFind(Parse.User, async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method afterFind - * @name Parse.Cloud.afterFind - * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after find function for. This can instead be a String that is the className of the subclass. - * @param {Function} func The function to run before a find. This function can be async and should take just one parameter, {@link Parse.Cloud.AfterFindRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.AfterFindRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.afterFind = function (parseClass, handler, validationHandler) { - const className = getClassName(parseClass); - triggers.addTrigger(triggers.Types.afterFind, className, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Registers a before save file function. - * - * **Available in Cloud Code only.** - * - * ``` - * Parse.Cloud.beforeSaveFile(async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.beforeSaveFile(async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method beforeSaveFile - * @name Parse.Cloud.beforeSaveFile - * @param {Function} func The function to run before saving a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.beforeSaveFile = function (handler, validationHandler) { - triggers.addFileTrigger(triggers.Types.beforeSaveFile, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Registers an after save file function. - * - * **Available in Cloud Code only.** - * - * ``` - * Parse.Cloud.afterSaveFile(async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.afterSaveFile(async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method afterSaveFile - * @name Parse.Cloud.afterSaveFile - * @param {Function} func The function to run after saving a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.afterSaveFile = function (handler, validationHandler) { - triggers.addFileTrigger(triggers.Types.afterSaveFile, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Registers a before delete file function. - * - * **Available in Cloud Code only.** - * - * ``` - * Parse.Cloud.beforeDeleteFile(async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.beforeDeleteFile(async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method beforeDeleteFile - * @name Parse.Cloud.beforeDeleteFile - * @param {Function} func The function to run before deleting a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.beforeDeleteFile = function (handler, validationHandler) { - triggers.addFileTrigger(triggers.Types.beforeDeleteFile, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Registers an after delete file function. - * - * **Available in Cloud Code only.** - * - * ``` - * Parse.Cloud.afterDeleteFile(async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.afterDeleteFile(async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method afterDeleteFile - * @name Parse.Cloud.afterDeleteFile - * @param {Function} func The function to after before deleting a file. This function can be async and should take just one parameter, {@link Parse.Cloud.FileTriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.FileTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.afterDeleteFile = function (handler, validationHandler) { - triggers.addFileTrigger(triggers.Types.afterDeleteFile, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Registers a before live query server connect function. - * - * **Available in Cloud Code only.** - * - * ``` - * Parse.Cloud.beforeConnect(async (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.beforeConnect(async (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method beforeConnect - * @name Parse.Cloud.beforeConnect - * @param {Function} func The function to before connection is made. This function can be async and should take just one parameter, {@link Parse.Cloud.ConnectTriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.ConnectTriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.beforeConnect = function (handler, validationHandler) { - triggers.addConnectTrigger(triggers.Types.beforeConnect, handler, _node.Parse.applicationId, validationHandler); -}; -/** - * Sends an email through the Parse Server mail adapter. - * - * **Available in Cloud Code only.** - * **Requires a mail adapter to be configured for Parse Server.** - * - * ``` - * Parse.Cloud.sendEmail({ - * from: 'Example ', - * to: 'contact@example.com', - * subject: 'Test email', - * text: 'This email is a test.' - * }); - *``` - * - * @method sendEmail - * @name Parse.Cloud.sendEmail - * @param {Object} data The object of the mail data to send. - */ - - -ParseCloud.sendEmail = function (data) { - const config = Config.get(_node.Parse.applicationId); - const emailAdapter = config.userController.adapter; - - if (!emailAdapter) { - config.loggerController.error('Failed to send email because no mail adapter is configured for Parse Server.'); - return; - } - - return emailAdapter.sendMail(data); -}; -/** - * Registers a before live query subscription function. - * - * **Available in Cloud Code only.** - * - * If you want to use beforeSubscribe for a predefined class in the Parse JavaScript SDK (e.g. {@link Parse.User}), you should pass the class itself and not the String for arg1. - * ``` - * Parse.Cloud.beforeSubscribe('MyCustomClass', (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.beforeSubscribe(Parse.User, (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method beforeSubscribe - * @name Parse.Cloud.beforeSubscribe - * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the before subscription function for. This can instead be a String that is the className of the subclass. - * @param {Function} func The function to run before a subscription. This function can be async and should take one parameter, a {@link Parse.Cloud.TriggerRequest}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.TriggerRequest}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.beforeSubscribe = function (parseClass, handler, validationHandler) { - var className = getClassName(parseClass); - triggers.addTrigger(triggers.Types.beforeSubscribe, className, handler, _node.Parse.applicationId, validationHandler); -}; - -ParseCloud.onLiveQueryEvent = function (handler) { - triggers.addLiveQueryEventHandler(handler, _node.Parse.applicationId); -}; -/** - * Registers an after live query server event function. - * - * **Available in Cloud Code only.** - * - * ``` - * Parse.Cloud.afterLiveQueryEvent('MyCustomClass', (request) => { - * // code here - * }, (request) => { - * // validation code here - * }); - * - * Parse.Cloud.afterLiveQueryEvent('MyCustomClass', (request) => { - * // code here - * }, { ...validationObject }); - *``` - * - * @method afterLiveQueryEvent - * @name Parse.Cloud.afterLiveQueryEvent - * @param {(String|Parse.Object)} arg1 The Parse.Object subclass to register the after live query event function for. This can instead be a String that is the className of the subclass. - * @param {Function} func The function to run after a live query event. This function can be async and should take one parameter, a {@link Parse.Cloud.LiveQueryEventTrigger}. - * @param {(Object|Function)} validator An optional function to help validating cloud code. This function can be an async function and should take one parameter a {@link Parse.Cloud.LiveQueryEventTrigger}, or a {@link Parse.Cloud.ValidatorObject}. - */ - - -ParseCloud.afterLiveQueryEvent = function (parseClass, handler, validationHandler) { - const className = getClassName(parseClass); - triggers.addTrigger(triggers.Types.afterEvent, className, handler, _node.Parse.applicationId, validationHandler); -}; - -ParseCloud._removeAllHooks = () => { - triggers._unregisterAll(); -}; - -ParseCloud.useMasterKey = () => { - // eslint-disable-next-line - console.warn('Parse.Cloud.useMasterKey is deprecated (and has no effect anymore) on parse-server, please refer to the cloud code migration notes: http://docs.parseplatform.org/parse-server/guide/#master-key-must-be-passed-explicitly'); -}; - -ParseCloud.httpRequest = require('./httpRequest'); -module.exports = ParseCloud; -/** - * @interface Parse.Cloud.TriggerRequest - * @property {String} installationId If set, the installationId triggering the request. - * @property {Boolean} master If true, means the master key was used. - * @property {Parse.User} user If set, the user that made the request. - * @property {Parse.Object} object The object triggering the hook. - * @property {String} ip The IP address of the client making the request. - * @property {Object} headers The original HTTP headers for the request. - * @property {String} triggerName The name of the trigger (`beforeSave`, `afterSave`, ...) - * @property {Object} log The current logger inside Parse Server. - * @property {Parse.Object} original If set, the object, as currently stored. - */ - -/** - * @interface Parse.Cloud.FileTriggerRequest - * @property {String} installationId If set, the installationId triggering the request. - * @property {Boolean} master If true, means the master key was used. - * @property {Parse.User} user If set, the user that made the request. - * @property {Parse.File} file The file that triggered the hook. - * @property {Integer} fileSize The size of the file in bytes. - * @property {Integer} contentLength The value from Content-Length header - * @property {String} ip The IP address of the client making the request. - * @property {Object} headers The original HTTP headers for the request. - * @property {String} triggerName The name of the trigger (`beforeSaveFile`, `afterSaveFile`) - * @property {Object} log The current logger inside Parse Server. - */ - -/** - * @interface Parse.Cloud.ConnectTriggerRequest - * @property {String} installationId If set, the installationId triggering the request. - * @property {Boolean} useMasterKey If true, means the master key was used. - * @property {Parse.User} user If set, the user that made the request. - * @property {Integer} clients The number of clients connected. - * @property {Integer} subscriptions The number of subscriptions connected. - * @property {String} sessionToken If set, the session of the user that made the request. - */ - -/** - * @interface Parse.Cloud.LiveQueryEventTrigger - * @property {String} installationId If set, the installationId triggering the request. - * @property {Boolean} useMasterKey If true, means the master key was used. - * @property {Parse.User} user If set, the user that made the request. - * @property {String} sessionToken If set, the session of the user that made the request. - * @property {String} event The live query event that triggered the request. - * @property {Parse.Object} object The object triggering the hook. - * @property {Parse.Object} original If set, the object, as currently stored. - * @property {Integer} clients The number of clients connected. - * @property {Integer} subscriptions The number of subscriptions connected. - * @property {Boolean} sendEvent If the LiveQuery event should be sent to the client. Set to false to prevent LiveQuery from pushing to the client. - */ - -/** - * @interface Parse.Cloud.BeforeFindRequest - * @property {String} installationId If set, the installationId triggering the request. - * @property {Boolean} master If true, means the master key was used. - * @property {Parse.User} user If set, the user that made the request. - * @property {Parse.Query} query The query triggering the hook. - * @property {String} ip The IP address of the client making the request. - * @property {Object} headers The original HTTP headers for the request. - * @property {String} triggerName The name of the trigger (`beforeSave`, `afterSave`, ...) - * @property {Object} log The current logger inside Parse Server. - * @property {Boolean} isGet wether the query a `get` or a `find` - */ - -/** - * @interface Parse.Cloud.AfterFindRequest - * @property {String} installationId If set, the installationId triggering the request. - * @property {Boolean} master If true, means the master key was used. - * @property {Parse.User} user If set, the user that made the request. - * @property {Parse.Query} query The query triggering the hook. - * @property {Array} results The results the query yielded. - * @property {String} ip The IP address of the client making the request. - * @property {Object} headers The original HTTP headers for the request. - * @property {String} triggerName The name of the trigger (`beforeSave`, `afterSave`, ...) - * @property {Object} log The current logger inside Parse Server. - */ - -/** - * @interface Parse.Cloud.FunctionRequest - * @property {String} installationId If set, the installationId triggering the request. - * @property {Boolean} master If true, means the master key was used. - * @property {Parse.User} user If set, the user that made the request. - * @property {Object} params The params passed to the cloud function. - */ - -/** - * @interface Parse.Cloud.JobRequest - * @property {Object} params The params passed to the background job. - * @property {function} message If message is called with a string argument, will update the current message to be stored in the job status. - */ - -/** - * @interface Parse.Cloud.ValidatorObject - * @property {Boolean} requireUser whether the cloud trigger requires a user. - * @property {Boolean} requireMaster whether the cloud trigger requires a master key. - * @property {Boolean} validateMasterKey whether the validator should run if masterKey is provided. Defaults to false. - * @property {Boolean} skipWithMasterKey whether the cloud code function should be ignored using a masterKey. - * - * @property {Array|Object} requireUserKeys If set, keys required on request.user to make the request. - * @property {String} requireUserKeys.field If requireUserKeys is an object, name of field to validate on request user - * @property {Array|function|Any} requireUserKeys.field.options array of options that the field can be, function to validate field, or single value. Throw an error if value is invalid. - * @property {String} requireUserKeys.field.error custom error message if field is invalid. - * - * @property {Object|Array} fields if an array of strings, validator will look for keys in request.params, and throw if not provided. If Object, fields to validate. If the trigger is a cloud function, `request.params` will be validated, otherwise `request.object`. - * @property {String} fields.field name of field to validate. - * @property {String} fields.field.type expected type of data for field. - * @property {Boolean} fields.field.constant whether the field can be modified on the object. - * @property {Any} fields.field.default default value if field is `null`, or initial value `constant` is `true`. - * @property {Array|function|Any} fields.field.options array of options that the field can be, function to validate field, or single value. Throw an error if value is invalid. - * @property {String} fields.field.error custom error message if field is invalid. - */ -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbG91ZC1jb2RlL1BhcnNlLkNsb3VkLmpzIl0sIm5hbWVzIjpbIkNvbmZpZyIsInJlcXVpcmUiLCJpc1BhcnNlT2JqZWN0Q29uc3RydWN0b3IiLCJvYmplY3QiLCJPYmplY3QiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJnZXRDbGFzc05hbWUiLCJwYXJzZUNsYXNzIiwiY2xhc3NOYW1lIiwiUGFyc2VDbG91ZCIsImRlZmluZSIsImZ1bmN0aW9uTmFtZSIsImhhbmRsZXIiLCJ2YWxpZGF0aW9uSGFuZGxlciIsInRyaWdnZXJzIiwiYWRkRnVuY3Rpb24iLCJQYXJzZSIsImFwcGxpY2F0aW9uSWQiLCJqb2IiLCJhZGRKb2IiLCJiZWZvcmVTYXZlIiwiYWRkVHJpZ2dlciIsIlR5cGVzIiwiYmVmb3JlRGVsZXRlIiwiYmVmb3JlTG9naW4iLCJhcmd1bWVudHMiLCJhZnRlckxvZ2luIiwiYWZ0ZXJMb2dvdXQiLCJhZnRlclNhdmUiLCJhZnRlckRlbGV0ZSIsImJlZm9yZUZpbmQiLCJhZnRlckZpbmQiLCJiZWZvcmVTYXZlRmlsZSIsImFkZEZpbGVUcmlnZ2VyIiwiYWZ0ZXJTYXZlRmlsZSIsImJlZm9yZURlbGV0ZUZpbGUiLCJhZnRlckRlbGV0ZUZpbGUiLCJiZWZvcmVDb25uZWN0IiwiYWRkQ29ubmVjdFRyaWdnZXIiLCJzZW5kRW1haWwiLCJkYXRhIiwiY29uZmlnIiwiZ2V0IiwiZW1haWxBZGFwdGVyIiwidXNlckNvbnRyb2xsZXIiLCJhZGFwdGVyIiwibG9nZ2VyQ29udHJvbGxlciIsImVycm9yIiwic2VuZE1haWwiLCJiZWZvcmVTdWJzY3JpYmUiLCJvbkxpdmVRdWVyeUV2ZW50IiwiYWRkTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVyIiwiYWZ0ZXJMaXZlUXVlcnlFdmVudCIsImFmdGVyRXZlbnQiLCJfcmVtb3ZlQWxsSG9va3MiLCJfdW5yZWdpc3RlckFsbCIsInVzZU1hc3RlcktleSIsImNvbnNvbGUiLCJ3YXJuIiwi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cnNlIH0gZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgKiBhcyB0cmlnZ2VycyBmcm9tICcuLi90cmlnZ2Vycyc7XG5jb25zdCBDb25maWcgPSByZXF1aXJlKCcuLi9Db25maWcnKTtcblxuZnVuY3Rpb24gaXNQYXJzZU9iamVjdENvbnN0cnVjdG9yKG9iamVjdCkge1xuICByZXR1cm4gdHlwZW9mIG9iamVjdCA9PT0gJ2Z1bmN0aW9uJyAmJiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCAnY2xhc3NOYW1lJyk7XG59XG5cbmZ1bmN0aW9uIGdldENsYXNzTmFtZShwYXJzZUNsYXNzKSB7XG4gIGlmIChwYXJzZUNsYXNzICYmIHBhcnNlQ2xhc3MuY2xhc3NOYW1lKSB7XG4gICAgcmV0dXJuIHBhcnNlQ2xhc3MuY2xhc3NOYW1lO1xuICB9XG4gIHJldHVybiBwYXJzZUNsYXNzO1xufVxuXG4vKiogQG5hbWVzcGFjZVxuICogQG5hbWUgUGFyc2VcbiAqIEBkZXNjcmlwdGlvbiBUaGUgUGFyc2UgU0RLLlxuICogIHNlZSBbYXBpIGRvY3NdKGh0dHBzOi8vZG9jcy5wYXJzZXBsYXRmb3JtLm9yZy9qcy9hcGkpIGFuZCBbZ3VpZGVdKGh0dHBzOi8vZG9jcy5wYXJzZXBsYXRmb3JtLm9yZy9qcy9ndWlkZSlcbiAqL1xuXG4vKiogQG5hbWVzcGFjZVxuICogQG5hbWUgUGFyc2UuQ2xvdWRcbiAqIEBtZW1iZXJvZiBQYXJzZVxuICogQGRlc2NyaXB0aW9uIFRoZSBQYXJzZSBDbG91ZCBDb2RlIFNESy5cbiAqL1xuXG52YXIgUGFyc2VDbG91ZCA9IHt9O1xuLyoqXG4gKiBEZWZpbmVzIGEgQ2xvdWQgRnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogYGBgXG4gKiBQYXJzZS5DbG91ZC5kZWZpbmUoJ2Z1bmN0aW9uTmFtZScsIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gdmFsaWRhdGlvbiBjb2RlIGhlcmVcbiAqIH0pO1xuICpcbiAqIFBhcnNlLkNsb3VkLmRlZmluZSgnZnVuY3Rpb25OYW1lJywgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCB7IC4uLnZhbGlkYXRpb25PYmplY3QgfSk7XG4gKiBgYGBcbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyb2YgUGFyc2UuQ2xvdWRcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIFRoZSBuYW1lIG9mIHRoZSBDbG91ZCBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZGF0YSBUaGUgQ2xvdWQgRnVuY3Rpb24gdG8gcmVnaXN0ZXIuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFuIGFzeW5jIGZ1bmN0aW9uIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLkZ1bmN0aW9uUmVxdWVzdH0uXG4gKiBAcGFyYW0geyhPYmplY3R8RnVuY3Rpb24pfSB2YWxpZGF0b3IgQW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gaGVscCB2YWxpZGF0aW5nIGNsb3VkIGNvZGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFuIGFzeW5jIGZ1bmN0aW9uIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLkZ1bmN0aW9uUmVxdWVzdH0sIG9yIGEge0BsaW5rIFBhcnNlLkNsb3VkLlZhbGlkYXRvck9iamVjdH0uXG4gKi9cblBhcnNlQ2xvdWQuZGVmaW5lID0gZnVuY3Rpb24gKGZ1bmN0aW9uTmFtZSwgaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgdHJpZ2dlcnMuYWRkRnVuY3Rpb24oZnVuY3Rpb25OYW1lLCBoYW5kbGVyLCB2YWxpZGF0aW9uSGFuZGxlciwgUGFyc2UuYXBwbGljYXRpb25JZCk7XG59O1xuXG4vKipcbiAqIERlZmluZXMgYSBCYWNrZ3JvdW5kIEpvYi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBAbWV0aG9kIGpvYlxuICogQG5hbWUgUGFyc2UuQ2xvdWQuam9iXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZSBUaGUgbmFtZSBvZiB0aGUgQmFja2dyb3VuZCBKb2JcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIEJhY2tncm91bmQgSm9iIHRvIHJlZ2lzdGVyLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBzaG91bGQgdGFrZSBhIHNpbmdsZSBwYXJhbWV0ZXJzIGEge0BsaW5rIFBhcnNlLkNsb3VkLkpvYlJlcXVlc3R9XG4gKlxuICovXG5QYXJzZUNsb3VkLmpvYiA9IGZ1bmN0aW9uIChmdW5jdGlvbk5hbWUsIGhhbmRsZXIpIHtcbiAgdHJpZ2dlcnMuYWRkSm9iKGZ1bmN0aW9uTmFtZSwgaGFuZGxlciwgUGFyc2UuYXBwbGljYXRpb25JZCk7XG59O1xuXG4vKipcbiAqXG4gKiBSZWdpc3RlcnMgYSBiZWZvcmUgc2F2ZSBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBJZiB5b3Ugd2FudCB0byB1c2UgYmVmb3JlU2F2ZSBmb3IgYSBwcmVkZWZpbmVkIGNsYXNzIGluIHRoZSBQYXJzZSBKYXZhU2NyaXB0IFNESyAoZS5nLiB7QGxpbmsgUGFyc2UuVXNlcn0pLCB5b3Ugc2hvdWxkIHBhc3MgdGhlIGNsYXNzIGl0c2VsZiBhbmQgbm90IHRoZSBTdHJpbmcgZm9yIGFyZzEuXG4gKlxuICogYGBgXG4gKiBQYXJzZS5DbG91ZC5iZWZvcmVTYXZlKCdNeUN1c3RvbUNsYXNzJywgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYmVmb3JlU2F2ZShQYXJzZS5Vc2VyLCAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIHsgLi4udmFsaWRhdGlvbk9iamVjdCB9KVxuICogYGBgXG4gKlxuICogQG1ldGhvZCBiZWZvcmVTYXZlXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5iZWZvcmVTYXZlXG4gKiBAcGFyYW0geyhTdHJpbmd8UGFyc2UuT2JqZWN0KX0gYXJnMSBUaGUgUGFyc2UuT2JqZWN0IHN1YmNsYXNzIHRvIHJlZ2lzdGVyIHRoZSBhZnRlciBzYXZlIGZ1bmN0aW9uIGZvci4gVGhpcyBjYW4gaW5zdGVhZCBiZSBhIFN0cmluZyB0aGF0IGlzIHRoZSBjbGFzc05hbWUgb2YgdGhlIHN1YmNsYXNzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcnVuIGJlZm9yZSBhIHNhdmUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fTtcbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVHJpZ2dlclJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmJlZm9yZVNhdmUgPSBmdW5jdGlvbiAocGFyc2VDbGFzcywgaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgdmFyIGNsYXNzTmFtZSA9IGdldENsYXNzTmFtZShwYXJzZUNsYXNzKTtcbiAgdHJpZ2dlcnMuYWRkVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5iZWZvcmVTYXZlLFxuICAgIGNsYXNzTmFtZSxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgYmVmb3JlIGRlbGV0ZSBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBJZiB5b3Ugd2FudCB0byB1c2UgYmVmb3JlRGVsZXRlIGZvciBhIHByZWRlZmluZWQgY2xhc3MgaW4gdGhlIFBhcnNlIEphdmFTY3JpcHQgU0RLIChlLmcuIHtAbGluayBQYXJzZS5Vc2VyfSksIHlvdSBzaG91bGQgcGFzcyB0aGUgY2xhc3MgaXRzZWxmIGFuZCBub3QgdGhlIFN0cmluZyBmb3IgYXJnMS5cbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYmVmb3JlRGVsZXRlKCdNeUN1c3RvbUNsYXNzJywgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYmVmb3JlRGVsZXRlKFBhcnNlLlVzZXIsIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pXG4gKmBgYFxuICpcbiAqIEBtZXRob2QgYmVmb3JlRGVsZXRlXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5iZWZvcmVEZWxldGVcbiAqIEBwYXJhbSB7KFN0cmluZ3xQYXJzZS5PYmplY3QpfSBhcmcxIFRoZSBQYXJzZS5PYmplY3Qgc3ViY2xhc3MgdG8gcmVnaXN0ZXIgdGhlIGJlZm9yZSBkZWxldGUgZnVuY3Rpb24gZm9yLiBUaGlzIGNhbiBpbnN0ZWFkIGJlIGEgU3RyaW5nIHRoYXQgaXMgdGhlIGNsYXNzTmFtZSBvZiB0aGUgc3ViY2xhc3MuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYmVmb3JlIGEgZGVsZXRlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciwgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVHJpZ2dlclJlcXVlc3R9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5UcmlnZ2VyUmVxdWVzdH0sIG9yIGEge0BsaW5rIFBhcnNlLkNsb3VkLlZhbGlkYXRvck9iamVjdH0uXG4gKi9cblBhcnNlQ2xvdWQuYmVmb3JlRGVsZXRlID0gZnVuY3Rpb24gKHBhcnNlQ2xhc3MsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIHZhciBjbGFzc05hbWUgPSBnZXRDbGFzc05hbWUocGFyc2VDbGFzcyk7XG4gIHRyaWdnZXJzLmFkZFRyaWdnZXIoXG4gICAgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlRGVsZXRlLFxuICAgIGNsYXNzTmFtZSxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cbi8qKlxuICpcbiAqIFJlZ2lzdGVycyB0aGUgYmVmb3JlIGxvZ2luIGZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gcHJvdmlkZXMgZnVydGhlciBjb250cm9sXG4gKiBpbiB2YWxpZGF0aW5nIGEgbG9naW4gYXR0ZW1wdC4gU3BlY2lmaWNhbGx5LFxuICogaXQgaXMgdHJpZ2dlcmVkIGFmdGVyIGEgdXNlciBlbnRlcnNcbiAqIGNvcnJlY3QgY3JlZGVudGlhbHMgKG9yIG90aGVyIHZhbGlkIGF1dGhEYXRhKSxcbiAqIGJ1dCBwcmlvciB0byBhIHNlc3Npb24gYmVpbmcgZ2VuZXJhdGVkLlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYmVmb3JlTG9naW4oKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9KVxuICpcbiAqIGBgYFxuICpcbiAqIEBtZXRob2QgYmVmb3JlTG9naW5cbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmJlZm9yZUxvZ2luXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYmVmb3JlIGEgbG9naW4uIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fTtcbiAqL1xuUGFyc2VDbG91ZC5iZWZvcmVMb2dpbiA9IGZ1bmN0aW9uIChoYW5kbGVyKSB7XG4gIGxldCBjbGFzc05hbWUgPSAnX1VzZXInO1xuICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICdzdHJpbmcnIHx8IGlzUGFyc2VPYmplY3RDb25zdHJ1Y3RvcihoYW5kbGVyKSkge1xuICAgIC8vIHZhbGlkYXRpb24gd2lsbCBvY2N1ciBkb3duc3RyZWFtLCB0aGlzIGlzIHRvIG1haW50YWluIGludGVybmFsXG4gICAgLy8gY29kZSBjb25zaXN0ZW5jeSB3aXRoIHRoZSBvdGhlciBob29rIHR5cGVzLlxuICAgIGNsYXNzTmFtZSA9IGdldENsYXNzTmFtZShoYW5kbGVyKTtcbiAgICBoYW5kbGVyID0gYXJndW1lbnRzWzFdO1xuICB9XG4gIHRyaWdnZXJzLmFkZFRyaWdnZXIodHJpZ2dlcnMuVHlwZXMuYmVmb3JlTG9naW4sIGNsYXNzTmFtZSwgaGFuZGxlciwgUGFyc2UuYXBwbGljYXRpb25JZCk7XG59O1xuXG4vKipcbiAqXG4gKiBSZWdpc3RlcnMgdGhlIGFmdGVyIGxvZ2luIGZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gaXMgdHJpZ2dlcmVkIGFmdGVyIGEgdXNlciBsb2dzIGluIHN1Y2Nlc3NmdWxseSxcbiAqIGFuZCBhZnRlciBhIF9TZXNzaW9uIG9iamVjdCBoYXMgYmVlbiBjcmVhdGVkLlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJMb2dpbigocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0pO1xuICogYGBgXG4gKlxuICogQG1ldGhvZCBhZnRlckxvZ2luXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5hZnRlckxvZ2luXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYWZ0ZXIgYSBsb2dpbi4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYXN5bmMgYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVHJpZ2dlclJlcXVlc3R9O1xuICovXG5QYXJzZUNsb3VkLmFmdGVyTG9naW4gPSBmdW5jdGlvbiAoaGFuZGxlcikge1xuICBsZXQgY2xhc3NOYW1lID0gJ19Vc2VyJztcbiAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSAnc3RyaW5nJyB8fCBpc1BhcnNlT2JqZWN0Q29uc3RydWN0b3IoaGFuZGxlcikpIHtcbiAgICAvLyB2YWxpZGF0aW9uIHdpbGwgb2NjdXIgZG93bnN0cmVhbSwgdGhpcyBpcyB0byBtYWludGFpbiBpbnRlcm5hbFxuICAgIC8vIGNvZGUgY29uc2lzdGVuY3kgd2l0aCB0aGUgb3RoZXIgaG9vayB0eXBlcy5cbiAgICBjbGFzc05hbWUgPSBnZXRDbGFzc05hbWUoaGFuZGxlcik7XG4gICAgaGFuZGxlciA9IGFyZ3VtZW50c1sxXTtcbiAgfVxuICB0cmlnZ2Vycy5hZGRUcmlnZ2VyKHRyaWdnZXJzLlR5cGVzLmFmdGVyTG9naW4sIGNsYXNzTmFtZSwgaGFuZGxlciwgUGFyc2UuYXBwbGljYXRpb25JZCk7XG59O1xuXG4vKipcbiAqXG4gKiBSZWdpc3RlcnMgdGhlIGFmdGVyIGxvZ291dCBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIHRyaWdnZXJlZCBhZnRlciBhIHVzZXIgbG9ncyBvdXQuXG4gKlxuICogYGBgXG4gKiBQYXJzZS5DbG91ZC5hZnRlckxvZ291dCgocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0pO1xuICogYGBgXG4gKlxuICogQG1ldGhvZCBhZnRlckxvZ291dFxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYWZ0ZXJMb2dvdXRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJ1biBhZnRlciBhIGxvZ291dC4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYXN5bmMgYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVHJpZ2dlclJlcXVlc3R9O1xuICovXG5QYXJzZUNsb3VkLmFmdGVyTG9nb3V0ID0gZnVuY3Rpb24gKGhhbmRsZXIpIHtcbiAgbGV0IGNsYXNzTmFtZSA9ICdfU2Vzc2lvbic7XG4gIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gJ3N0cmluZycgfHwgaXNQYXJzZU9iamVjdENvbnN0cnVjdG9yKGhhbmRsZXIpKSB7XG4gICAgLy8gdmFsaWRhdGlvbiB3aWxsIG9jY3VyIGRvd25zdHJlYW0sIHRoaXMgaXMgdG8gbWFpbnRhaW4gaW50ZXJuYWxcbiAgICAvLyBjb2RlIGNvbnNpc3RlbmN5IHdpdGggdGhlIG90aGVyIGhvb2sgdHlwZXMuXG4gICAgY2xhc3NOYW1lID0gZ2V0Q2xhc3NOYW1lKGhhbmRsZXIpO1xuICAgIGhhbmRsZXIgPSBhcmd1bWVudHNbMV07XG4gIH1cbiAgdHJpZ2dlcnMuYWRkVHJpZ2dlcih0cmlnZ2Vycy5UeXBlcy5hZnRlckxvZ291dCwgY2xhc3NOYW1lLCBoYW5kbGVyLCBQYXJzZS5hcHBsaWNhdGlvbklkKTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGFuIGFmdGVyIHNhdmUgZnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogSWYgeW91IHdhbnQgdG8gdXNlIGFmdGVyU2F2ZSBmb3IgYSBwcmVkZWZpbmVkIGNsYXNzIGluIHRoZSBQYXJzZSBKYXZhU2NyaXB0IFNESyAoZS5nLiB7QGxpbmsgUGFyc2UuVXNlcn0pLCB5b3Ugc2hvdWxkIHBhc3MgdGhlIGNsYXNzIGl0c2VsZiBhbmQgbm90IHRoZSBTdHJpbmcgZm9yIGFyZzEuXG4gKlxuICogYGBgXG4gKiBQYXJzZS5DbG91ZC5hZnRlclNhdmUoJ015Q3VzdG9tQ2xhc3MnLCBhc3luYyBmdW5jdGlvbihyZXF1ZXN0KSB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gdmFsaWRhdGlvbiBjb2RlIGhlcmVcbiAqIH0pO1xuICpcbiAqIFBhcnNlLkNsb3VkLmFmdGVyU2F2ZShQYXJzZS5Vc2VyLCBhc3luYyBmdW5jdGlvbihyZXF1ZXN0KSB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICogYGBgXG4gKlxuICogQG1ldGhvZCBhZnRlclNhdmVcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmFmdGVyU2F2ZVxuICogQHBhcmFtIHsoU3RyaW5nfFBhcnNlLk9iamVjdCl9IGFyZzEgVGhlIFBhcnNlLk9iamVjdCBzdWJjbGFzcyB0byByZWdpc3RlciB0aGUgYWZ0ZXIgc2F2ZSBmdW5jdGlvbiBmb3IuIFRoaXMgY2FuIGluc3RlYWQgYmUgYSBTdHJpbmcgdGhhdCBpcyB0aGUgY2xhc3NOYW1lIG9mIHRoZSBzdWJjbGFzcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJ1biBhZnRlciBhIHNhdmUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFuIGFzeW5jIGZ1bmN0aW9uIGFuZCBzaG91bGQgdGFrZSBqdXN0IG9uZSBwYXJhbWV0ZXIsIHtAbGluayBQYXJzZS5DbG91ZC5UcmlnZ2VyUmVxdWVzdH0uXG4gKiBAcGFyYW0geyhPYmplY3R8RnVuY3Rpb24pfSB2YWxpZGF0b3IgQW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gaGVscCB2YWxpZGF0aW5nIGNsb3VkIGNvZGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFuIGFzeW5jIGZ1bmN0aW9uIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5hZnRlclNhdmUgPSBmdW5jdGlvbiAocGFyc2VDbGFzcywgaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgdmFyIGNsYXNzTmFtZSA9IGdldENsYXNzTmFtZShwYXJzZUNsYXNzKTtcbiAgdHJpZ2dlcnMuYWRkVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlclNhdmUsXG4gICAgY2xhc3NOYW1lLFxuICAgIGhhbmRsZXIsXG4gICAgUGFyc2UuYXBwbGljYXRpb25JZCxcbiAgICB2YWxpZGF0aW9uSGFuZGxlclxuICApO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYW4gYWZ0ZXIgZGVsZXRlIGZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIElmIHlvdSB3YW50IHRvIHVzZSBhZnRlckRlbGV0ZSBmb3IgYSBwcmVkZWZpbmVkIGNsYXNzIGluIHRoZSBQYXJzZSBKYXZhU2NyaXB0IFNESyAoZS5nLiB7QGxpbmsgUGFyc2UuVXNlcn0pLCB5b3Ugc2hvdWxkIHBhc3MgdGhlIGNsYXNzIGl0c2VsZiBhbmQgbm90IHRoZSBTdHJpbmcgZm9yIGFyZzEuXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmFmdGVyRGVsZXRlKCdNeUN1c3RvbUNsYXNzJywgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJEZWxldGUoUGFyc2UuVXNlciwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCB7IC4uLnZhbGlkYXRpb25PYmplY3QgfSk7XG4gKmBgYFxuICpcbiAqIEBtZXRob2QgYWZ0ZXJEZWxldGVcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmFmdGVyRGVsZXRlXG4gKiBAcGFyYW0geyhTdHJpbmd8UGFyc2UuT2JqZWN0KX0gYXJnMSBUaGUgUGFyc2UuT2JqZWN0IHN1YmNsYXNzIHRvIHJlZ2lzdGVyIHRoZSBhZnRlciBkZWxldGUgZnVuY3Rpb24gZm9yLiBUaGlzIGNhbiBpbnN0ZWFkIGJlIGEgU3RyaW5nIHRoYXQgaXMgdGhlIGNsYXNzTmFtZSBvZiB0aGUgc3ViY2xhc3MuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYWZ0ZXIgYSBkZWxldGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBqdXN0IG9uZSBwYXJhbWV0ZXIsIHtAbGluayBQYXJzZS5DbG91ZC5UcmlnZ2VyUmVxdWVzdH0uXG4gKiBAcGFyYW0geyhPYmplY3R8RnVuY3Rpb24pfSB2YWxpZGF0b3IgQW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gaGVscCB2YWxpZGF0aW5nIGNsb3VkIGNvZGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFuIGFzeW5jIGZ1bmN0aW9uIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5hZnRlckRlbGV0ZSA9IGZ1bmN0aW9uIChwYXJzZUNsYXNzLCBoYW5kbGVyLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB2YXIgY2xhc3NOYW1lID0gZ2V0Q2xhc3NOYW1lKHBhcnNlQ2xhc3MpO1xuICB0cmlnZ2Vycy5hZGRUcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmFmdGVyRGVsZXRlLFxuICAgIGNsYXNzTmFtZSxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgYmVmb3JlIGZpbmQgZnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogSWYgeW91IHdhbnQgdG8gdXNlIGJlZm9yZUZpbmQgZm9yIGEgcHJlZGVmaW5lZCBjbGFzcyBpbiB0aGUgUGFyc2UgSmF2YVNjcmlwdCBTREsgKGUuZy4ge0BsaW5rIFBhcnNlLlVzZXJ9KSwgeW91IHNob3VsZCBwYXNzIHRoZSBjbGFzcyBpdHNlbGYgYW5kIG5vdCB0aGUgU3RyaW5nIGZvciBhcmcxLlxuICogYGBgXG4gKiBQYXJzZS5DbG91ZC5iZWZvcmVGaW5kKCdNeUN1c3RvbUNsYXNzJywgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYmVmb3JlRmluZChQYXJzZS5Vc2VyLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIHsgLi4udmFsaWRhdGlvbk9iamVjdCB9KTtcbiAqYGBgXG4gKlxuICogQG1ldGhvZCBiZWZvcmVGaW5kXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5iZWZvcmVGaW5kXG4gKiBAcGFyYW0geyhTdHJpbmd8UGFyc2UuT2JqZWN0KX0gYXJnMSBUaGUgUGFyc2UuT2JqZWN0IHN1YmNsYXNzIHRvIHJlZ2lzdGVyIHRoZSBiZWZvcmUgZmluZCBmdW5jdGlvbiBmb3IuIFRoaXMgY2FuIGluc3RlYWQgYmUgYSBTdHJpbmcgdGhhdCBpcyB0aGUgY2xhc3NOYW1lIG9mIHRoZSBzdWJjbGFzcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJ1biBiZWZvcmUgYSBmaW5kLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2UganVzdCBvbmUgcGFyYW1ldGVyLCB7QGxpbmsgUGFyc2UuQ2xvdWQuQmVmb3JlRmluZFJlcXVlc3R9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5CZWZvcmVGaW5kUmVxdWVzdH0sIG9yIGEge0BsaW5rIFBhcnNlLkNsb3VkLlZhbGlkYXRvck9iamVjdH0uXG4gKi9cblBhcnNlQ2xvdWQuYmVmb3JlRmluZCA9IGZ1bmN0aW9uIChwYXJzZUNsYXNzLCBoYW5kbGVyLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB2YXIgY2xhc3NOYW1lID0gZ2V0Q2xhc3NOYW1lKHBhcnNlQ2xhc3MpO1xuICB0cmlnZ2Vycy5hZGRUcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZUZpbmQsXG4gICAgY2xhc3NOYW1lLFxuICAgIGhhbmRsZXIsXG4gICAgUGFyc2UuYXBwbGljYXRpb25JZCxcbiAgICB2YWxpZGF0aW9uSGFuZGxlclxuICApO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYW4gYWZ0ZXIgZmluZCBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBJZiB5b3Ugd2FudCB0byB1c2UgYWZ0ZXJGaW5kIGZvciBhIHByZWRlZmluZWQgY2xhc3MgaW4gdGhlIFBhcnNlIEphdmFTY3JpcHQgU0RLIChlLmcuIHtAbGluayBQYXJzZS5Vc2VyfSksIHlvdSBzaG91bGQgcGFzcyB0aGUgY2xhc3MgaXRzZWxmIGFuZCBub3QgdGhlIFN0cmluZyBmb3IgYXJnMS5cbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJGaW5kKCdNeUN1c3RvbUNsYXNzJywgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJGaW5kKFBhcnNlLlVzZXIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGFmdGVyRmluZFxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYWZ0ZXJGaW5kXG4gKiBAcGFyYW0geyhTdHJpbmd8UGFyc2UuT2JqZWN0KX0gYXJnMSBUaGUgUGFyc2UuT2JqZWN0IHN1YmNsYXNzIHRvIHJlZ2lzdGVyIHRoZSBhZnRlciBmaW5kIGZ1bmN0aW9uIGZvci4gVGhpcyBjYW4gaW5zdGVhZCBiZSBhIFN0cmluZyB0aGF0IGlzIHRoZSBjbGFzc05hbWUgb2YgdGhlIHN1YmNsYXNzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcnVuIGJlZm9yZSBhIGZpbmQuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBqdXN0IG9uZSBwYXJhbWV0ZXIsIHtAbGluayBQYXJzZS5DbG91ZC5BZnRlckZpbmRSZXF1ZXN0fS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuQWZ0ZXJGaW5kUmVxdWVzdH0sIG9yIGEge0BsaW5rIFBhcnNlLkNsb3VkLlZhbGlkYXRvck9iamVjdH0uXG4gKi9cblBhcnNlQ2xvdWQuYWZ0ZXJGaW5kID0gZnVuY3Rpb24gKHBhcnNlQ2xhc3MsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIGNvbnN0IGNsYXNzTmFtZSA9IGdldENsYXNzTmFtZShwYXJzZUNsYXNzKTtcbiAgdHJpZ2dlcnMuYWRkVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlckZpbmQsXG4gICAgY2xhc3NOYW1lLFxuICAgIGhhbmRsZXIsXG4gICAgUGFyc2UuYXBwbGljYXRpb25JZCxcbiAgICB2YWxpZGF0aW9uSGFuZGxlclxuICApO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYSBiZWZvcmUgc2F2ZSBmaWxlIGZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYmVmb3JlU2F2ZUZpbGUoYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYmVmb3JlU2F2ZUZpbGUoYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCB7IC4uLnZhbGlkYXRpb25PYmplY3QgfSk7XG4gKmBgYFxuICpcbiAqIEBtZXRob2QgYmVmb3JlU2F2ZUZpbGVcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmJlZm9yZVNhdmVGaWxlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYmVmb3JlIHNhdmluZyBhIGZpbGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBqdXN0IG9uZSBwYXJhbWV0ZXIsIHtAbGluayBQYXJzZS5DbG91ZC5GaWxlVHJpZ2dlclJlcXVlc3R9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5GaWxlVHJpZ2dlclJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmJlZm9yZVNhdmVGaWxlID0gZnVuY3Rpb24gKGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIHRyaWdnZXJzLmFkZEZpbGVUcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZVNhdmVGaWxlLFxuICAgIGhhbmRsZXIsXG4gICAgUGFyc2UuYXBwbGljYXRpb25JZCxcbiAgICB2YWxpZGF0aW9uSGFuZGxlclxuICApO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYW4gYWZ0ZXIgc2F2ZSBmaWxlIGZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJTYXZlRmlsZShhc3luYyAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIHZhbGlkYXRpb24gY29kZSBoZXJlXG4gKiB9KTtcbiAqXG4gKiBQYXJzZS5DbG91ZC5hZnRlclNhdmVGaWxlKGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgLy8gY29kZSBoZXJlXG4gKiB9LCB7IC4uLnZhbGlkYXRpb25PYmplY3QgfSk7XG4gKmBgYFxuICpcbiAqIEBtZXRob2QgYWZ0ZXJTYXZlRmlsZVxuICogQG5hbWUgUGFyc2UuQ2xvdWQuYWZ0ZXJTYXZlRmlsZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gcnVuIGFmdGVyIHNhdmluZyBhIGZpbGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBqdXN0IG9uZSBwYXJhbWV0ZXIsIHtAbGluayBQYXJzZS5DbG91ZC5GaWxlVHJpZ2dlclJlcXVlc3R9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5GaWxlVHJpZ2dlclJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmFmdGVyU2F2ZUZpbGUgPSBmdW5jdGlvbiAoaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgdHJpZ2dlcnMuYWRkRmlsZVRyaWdnZXIoXG4gICAgdHJpZ2dlcnMuVHlwZXMuYWZ0ZXJTYXZlRmlsZSxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgYmVmb3JlIGRlbGV0ZSBmaWxlIGZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYmVmb3JlRGVsZXRlRmlsZShhc3luYyAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIHZhbGlkYXRpb24gY29kZSBoZXJlXG4gKiB9KTtcbiAqXG4gKiBQYXJzZS5DbG91ZC5iZWZvcmVEZWxldGVGaWxlKGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGJlZm9yZURlbGV0ZUZpbGVcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmJlZm9yZURlbGV0ZUZpbGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJ1biBiZWZvcmUgZGVsZXRpbmcgYSBmaWxlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2UganVzdCBvbmUgcGFyYW1ldGVyLCB7QGxpbmsgUGFyc2UuQ2xvdWQuRmlsZVRyaWdnZXJSZXF1ZXN0fS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuRmlsZVRyaWdnZXJSZXF1ZXN0fSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5iZWZvcmVEZWxldGVGaWxlID0gZnVuY3Rpb24gKGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIHRyaWdnZXJzLmFkZEZpbGVUcmlnZ2VyKFxuICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZURlbGV0ZUZpbGUsXG4gICAgaGFuZGxlcixcbiAgICBQYXJzZS5hcHBsaWNhdGlvbklkLFxuICAgIHZhbGlkYXRpb25IYW5kbGVyXG4gICk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBhZnRlciBkZWxldGUgZmlsZSBmdW5jdGlvbi5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmFmdGVyRGVsZXRlRmlsZShhc3luYyAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIHZhbGlkYXRpb24gY29kZSBoZXJlXG4gKiB9KTtcbiAqXG4gKiBQYXJzZS5DbG91ZC5hZnRlckRlbGV0ZUZpbGUoYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCB7IC4uLnZhbGlkYXRpb25PYmplY3QgfSk7XG4gKmBgYFxuICpcbiAqIEBtZXRob2QgYWZ0ZXJEZWxldGVGaWxlXG4gKiBAbmFtZSBQYXJzZS5DbG91ZC5hZnRlckRlbGV0ZUZpbGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFmdGVyIGJlZm9yZSBkZWxldGluZyBhIGZpbGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBqdXN0IG9uZSBwYXJhbWV0ZXIsIHtAbGluayBQYXJzZS5DbG91ZC5GaWxlVHJpZ2dlclJlcXVlc3R9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5GaWxlVHJpZ2dlclJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmFmdGVyRGVsZXRlRmlsZSA9IGZ1bmN0aW9uIChoYW5kbGVyLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB0cmlnZ2Vycy5hZGRGaWxlVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlckRlbGV0ZUZpbGUsXG4gICAgaGFuZGxlcixcbiAgICBQYXJzZS5hcHBsaWNhdGlvbklkLFxuICAgIHZhbGlkYXRpb25IYW5kbGVyXG4gICk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGJlZm9yZSBsaXZlIHF1ZXJ5IHNlcnZlciBjb25uZWN0IGZ1bmN0aW9uLlxuICpcbiAqICoqQXZhaWxhYmxlIGluIENsb3VkIENvZGUgb25seS4qKlxuICpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuYmVmb3JlQ29ubmVjdChhc3luYyAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIHZhbGlkYXRpb24gY29kZSBoZXJlXG4gKiB9KTtcbiAqXG4gKiBQYXJzZS5DbG91ZC5iZWZvcmVDb25uZWN0KGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGJlZm9yZUNvbm5lY3RcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmJlZm9yZUNvbm5lY3RcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJlZm9yZSBjb25uZWN0aW9uIGlzIG1hZGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBqdXN0IG9uZSBwYXJhbWV0ZXIsIHtAbGluayBQYXJzZS5DbG91ZC5Db25uZWN0VHJpZ2dlclJlcXVlc3R9LlxuICogQHBhcmFtIHsoT2JqZWN0fEZ1bmN0aW9uKX0gdmFsaWRhdG9yIEFuIG9wdGlvbmFsIGZ1bmN0aW9uIHRvIGhlbHAgdmFsaWRhdGluZyBjbG91ZCBjb2RlLiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhbiBhc3luYyBmdW5jdGlvbiBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciBhIHtAbGluayBQYXJzZS5DbG91ZC5Db25uZWN0VHJpZ2dlclJlcXVlc3R9LCBvciBhIHtAbGluayBQYXJzZS5DbG91ZC5WYWxpZGF0b3JPYmplY3R9LlxuICovXG5QYXJzZUNsb3VkLmJlZm9yZUNvbm5lY3QgPSBmdW5jdGlvbiAoaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgdHJpZ2dlcnMuYWRkQ29ubmVjdFRyaWdnZXIoXG4gICAgdHJpZ2dlcnMuVHlwZXMuYmVmb3JlQ29ubmVjdCxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cbi8qKlxuICogU2VuZHMgYW4gZW1haWwgdGhyb3VnaCB0aGUgUGFyc2UgU2VydmVyIG1haWwgYWRhcHRlci5cbiAqXG4gKiAqKkF2YWlsYWJsZSBpbiBDbG91ZCBDb2RlIG9ubHkuKipcbiAqICoqUmVxdWlyZXMgYSBtYWlsIGFkYXB0ZXIgdG8gYmUgY29uZmlndXJlZCBmb3IgUGFyc2UgU2VydmVyLioqXG4gKlxuICogYGBgXG4gKiBQYXJzZS5DbG91ZC5zZW5kRW1haWwoe1xuICogICBmcm9tOiAnRXhhbXBsZSA8dGVzdEBleGFtcGxlLmNvbT4nLFxuICogICB0bzogJ2NvbnRhY3RAZXhhbXBsZS5jb20nLFxuICogICBzdWJqZWN0OiAnVGVzdCBlbWFpbCcsXG4gKiAgIHRleHQ6ICdUaGlzIGVtYWlsIGlzIGEgdGVzdC4nXG4gKiB9KTtcbiAqYGBgXG4gKlxuICogQG1ldGhvZCBzZW5kRW1haWxcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLnNlbmRFbWFpbFxuICogQHBhcmFtIHtPYmplY3R9IGRhdGEgVGhlIG9iamVjdCBvZiB0aGUgbWFpbCBkYXRhIHRvIHNlbmQuXG4gKi9cblBhcnNlQ2xvdWQuc2VuZEVtYWlsID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgY29uc3QgY29uZmlnID0gQ29uZmlnLmdldChQYXJzZS5hcHBsaWNhdGlvbklkKTtcbiAgY29uc3QgZW1haWxBZGFwdGVyID0gY29uZmlnLnVzZXJDb250cm9sbGVyLmFkYXB0ZXI7XG4gIGlmICghZW1haWxBZGFwdGVyKSB7XG4gICAgY29uZmlnLmxvZ2dlckNvbnRyb2xsZXIuZXJyb3IoXG4gICAgICAnRmFpbGVkIHRvIHNlbmQgZW1haWwgYmVjYXVzZSBubyBtYWlsIGFkYXB0ZXIgaXMgY29uZmlndXJlZCBmb3IgUGFyc2UgU2VydmVyLidcbiAgICApO1xuICAgIHJldHVybjtcbiAgfVxuICByZXR1cm4gZW1haWxBZGFwdGVyLnNlbmRNYWlsKGRhdGEpO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYSBiZWZvcmUgbGl2ZSBxdWVyeSBzdWJzY3JpcHRpb24gZnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogSWYgeW91IHdhbnQgdG8gdXNlIGJlZm9yZVN1YnNjcmliZSBmb3IgYSBwcmVkZWZpbmVkIGNsYXNzIGluIHRoZSBQYXJzZSBKYXZhU2NyaXB0IFNESyAoZS5nLiB7QGxpbmsgUGFyc2UuVXNlcn0pLCB5b3Ugc2hvdWxkIHBhc3MgdGhlIGNsYXNzIGl0c2VsZiBhbmQgbm90IHRoZSBTdHJpbmcgZm9yIGFyZzEuXG4gKiBgYGBcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZVN1YnNjcmliZSgnTXlDdXN0b21DbGFzcycsIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gdmFsaWRhdGlvbiBjb2RlIGhlcmVcbiAqIH0pO1xuICpcbiAqIFBhcnNlLkNsb3VkLmJlZm9yZVN1YnNjcmliZShQYXJzZS5Vc2VyLCAocmVxdWVzdCkgPT4ge1xuICogICAvLyBjb2RlIGhlcmVcbiAqIH0sIHsgLi4udmFsaWRhdGlvbk9iamVjdCB9KTtcbiAqYGBgXG4gKlxuICogQG1ldGhvZCBiZWZvcmVTdWJzY3JpYmVcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmJlZm9yZVN1YnNjcmliZVxuICogQHBhcmFtIHsoU3RyaW5nfFBhcnNlLk9iamVjdCl9IGFyZzEgVGhlIFBhcnNlLk9iamVjdCBzdWJjbGFzcyB0byByZWdpc3RlciB0aGUgYmVmb3JlIHN1YnNjcmlwdGlvbiBmdW5jdGlvbiBmb3IuIFRoaXMgY2FuIGluc3RlYWQgYmUgYSBTdHJpbmcgdGhhdCBpcyB0aGUgY2xhc3NOYW1lIG9mIHRoZSBzdWJjbGFzcy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJ1biBiZWZvcmUgYSBzdWJzY3JpcHRpb24uIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFzeW5jIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyLCBhIHtAbGluayBQYXJzZS5DbG91ZC5UcmlnZ2VyUmVxdWVzdH0uXG4gKiBAcGFyYW0geyhPYmplY3R8RnVuY3Rpb24pfSB2YWxpZGF0b3IgQW4gb3B0aW9uYWwgZnVuY3Rpb24gdG8gaGVscCB2YWxpZGF0aW5nIGNsb3VkIGNvZGUuIFRoaXMgZnVuY3Rpb24gY2FuIGJlIGFuIGFzeW5jIGZ1bmN0aW9uIGFuZCBzaG91bGQgdGFrZSBvbmUgcGFyYW1ldGVyIGEge0BsaW5rIFBhcnNlLkNsb3VkLlRyaWdnZXJSZXF1ZXN0fSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5iZWZvcmVTdWJzY3JpYmUgPSBmdW5jdGlvbiAocGFyc2VDbGFzcywgaGFuZGxlciwgdmFsaWRhdGlvbkhhbmRsZXIpIHtcbiAgdmFyIGNsYXNzTmFtZSA9IGdldENsYXNzTmFtZShwYXJzZUNsYXNzKTtcbiAgdHJpZ2dlcnMuYWRkVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5iZWZvcmVTdWJzY3JpYmUsXG4gICAgY2xhc3NOYW1lLFxuICAgIGhhbmRsZXIsXG4gICAgUGFyc2UuYXBwbGljYXRpb25JZCxcbiAgICB2YWxpZGF0aW9uSGFuZGxlclxuICApO1xufTtcblxuUGFyc2VDbG91ZC5vbkxpdmVRdWVyeUV2ZW50ID0gZnVuY3Rpb24gKGhhbmRsZXIpIHtcbiAgdHJpZ2dlcnMuYWRkTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVyKGhhbmRsZXIsIFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlcnMgYW4gYWZ0ZXIgbGl2ZSBxdWVyeSBzZXJ2ZXIgZXZlbnQgZnVuY3Rpb24uXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogYGBgXG4gKiBQYXJzZS5DbG91ZC5hZnRlckxpdmVRdWVyeUV2ZW50KCdNeUN1c3RvbUNsYXNzJywgKHJlcXVlc3QpID0+IHtcbiAqICAgLy8gY29kZSBoZXJlXG4gKiB9LCAocmVxdWVzdCkgPT4ge1xuICogICAvLyB2YWxpZGF0aW9uIGNvZGUgaGVyZVxuICogfSk7XG4gKlxuICogUGFyc2UuQ2xvdWQuYWZ0ZXJMaXZlUXVlcnlFdmVudCgnTXlDdXN0b21DbGFzcycsIChyZXF1ZXN0KSA9PiB7XG4gKiAgIC8vIGNvZGUgaGVyZVxuICogfSwgeyAuLi52YWxpZGF0aW9uT2JqZWN0IH0pO1xuICpgYGBcbiAqXG4gKiBAbWV0aG9kIGFmdGVyTGl2ZVF1ZXJ5RXZlbnRcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmFmdGVyTGl2ZVF1ZXJ5RXZlbnRcbiAqIEBwYXJhbSB7KFN0cmluZ3xQYXJzZS5PYmplY3QpfSBhcmcxIFRoZSBQYXJzZS5PYmplY3Qgc3ViY2xhc3MgdG8gcmVnaXN0ZXIgdGhlIGFmdGVyIGxpdmUgcXVlcnkgZXZlbnQgZnVuY3Rpb24gZm9yLiBUaGlzIGNhbiBpbnN0ZWFkIGJlIGEgU3RyaW5nIHRoYXQgaXMgdGhlIGNsYXNzTmFtZSBvZiB0aGUgc3ViY2xhc3MuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBydW4gYWZ0ZXIgYSBsaXZlIHF1ZXJ5IGV2ZW50LiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSBhc3luYyBhbmQgc2hvdWxkIHRha2Ugb25lIHBhcmFtZXRlciwgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuTGl2ZVF1ZXJ5RXZlbnRUcmlnZ2VyfS5cbiAqIEBwYXJhbSB7KE9iamVjdHxGdW5jdGlvbil9IHZhbGlkYXRvciBBbiBvcHRpb25hbCBmdW5jdGlvbiB0byBoZWxwIHZhbGlkYXRpbmcgY2xvdWQgY29kZS4gVGhpcyBmdW5jdGlvbiBjYW4gYmUgYW4gYXN5bmMgZnVuY3Rpb24gYW5kIHNob3VsZCB0YWtlIG9uZSBwYXJhbWV0ZXIgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuTGl2ZVF1ZXJ5RXZlbnRUcmlnZ2VyfSwgb3IgYSB7QGxpbmsgUGFyc2UuQ2xvdWQuVmFsaWRhdG9yT2JqZWN0fS5cbiAqL1xuUGFyc2VDbG91ZC5hZnRlckxpdmVRdWVyeUV2ZW50ID0gZnVuY3Rpb24gKHBhcnNlQ2xhc3MsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyKSB7XG4gIGNvbnN0IGNsYXNzTmFtZSA9IGdldENsYXNzTmFtZShwYXJzZUNsYXNzKTtcbiAgdHJpZ2dlcnMuYWRkVHJpZ2dlcihcbiAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlckV2ZW50LFxuICAgIGNsYXNzTmFtZSxcbiAgICBoYW5kbGVyLFxuICAgIFBhcnNlLmFwcGxpY2F0aW9uSWQsXG4gICAgdmFsaWRhdGlvbkhhbmRsZXJcbiAgKTtcbn07XG5cblBhcnNlQ2xvdWQuX3JlbW92ZUFsbEhvb2tzID0gKCkgPT4ge1xuICB0cmlnZ2Vycy5fdW5yZWdpc3RlckFsbCgpO1xufTtcblxuUGFyc2VDbG91ZC51c2VNYXN0ZXJLZXkgPSAoKSA9PiB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICBjb25zb2xlLndhcm4oXG4gICAgJ1BhcnNlLkNsb3VkLnVzZU1hc3RlcktleSBpcyBkZXByZWNhdGVkIChhbmQgaGFzIG5vIGVmZmVjdCBhbnltb3JlKSBvbiBwYXJzZS1zZXJ2ZXIsIHBsZWFzZSByZWZlciB0byB0aGUgY2xvdWQgY29kZSBtaWdyYXRpb24gbm90ZXM6IGh0dHA6Ly9kb2NzLnBhcnNlcGxhdGZvcm0ub3JnL3BhcnNlLXNlcnZlci9ndWlkZS8jbWFzdGVyLWtleS1tdXN0LWJlLXBhc3NlZC1leHBsaWNpdGx5J1xuICApO1xufTtcblxuUGFyc2VDbG91ZC5odHRwUmVxdWVzdCA9IHJlcXVpcmUoJy4vaHR0cFJlcXVlc3QnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBQYXJzZUNsb3VkO1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgUGFyc2UuQ2xvdWQuVHJpZ2dlclJlcXVlc3RcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpbnN0YWxsYXRpb25JZCBJZiBzZXQsIHRoZSBpbnN0YWxsYXRpb25JZCB0cmlnZ2VyaW5nIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtCb29sZWFufSBtYXN0ZXIgSWYgdHJ1ZSwgbWVhbnMgdGhlIG1hc3RlciBrZXkgd2FzIHVzZWQuXG4gKiBAcHJvcGVydHkge1BhcnNlLlVzZXJ9IHVzZXIgSWYgc2V0LCB0aGUgdXNlciB0aGF0IG1hZGUgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1BhcnNlLk9iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdHJpZ2dlcmluZyB0aGUgaG9vay5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpcCBUaGUgSVAgYWRkcmVzcyBvZiB0aGUgY2xpZW50IG1ha2luZyB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBoZWFkZXJzIFRoZSBvcmlnaW5hbCBIVFRQIGhlYWRlcnMgZm9yIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtTdHJpbmd9IHRyaWdnZXJOYW1lIFRoZSBuYW1lIG9mIHRoZSB0cmlnZ2VyIChgYmVmb3JlU2F2ZWAsIGBhZnRlclNhdmVgLCAuLi4pXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nIFRoZSBjdXJyZW50IGxvZ2dlciBpbnNpZGUgUGFyc2UgU2VydmVyLlxuICogQHByb3BlcnR5IHtQYXJzZS5PYmplY3R9IG9yaWdpbmFsIElmIHNldCwgdGhlIG9iamVjdCwgYXMgY3VycmVudGx5IHN0b3JlZC5cbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgUGFyc2UuQ2xvdWQuRmlsZVRyaWdnZXJSZXF1ZXN0XG4gKiBAcHJvcGVydHkge1N0cmluZ30gaW5zdGFsbGF0aW9uSWQgSWYgc2V0LCB0aGUgaW5zdGFsbGF0aW9uSWQgdHJpZ2dlcmluZyB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gbWFzdGVyIElmIHRydWUsIG1lYW5zIHRoZSBtYXN0ZXIga2V5IHdhcyB1c2VkLlxuICogQHByb3BlcnR5IHtQYXJzZS5Vc2VyfSB1c2VyIElmIHNldCwgdGhlIHVzZXIgdGhhdCBtYWRlIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtQYXJzZS5GaWxlfSBmaWxlIFRoZSBmaWxlIHRoYXQgdHJpZ2dlcmVkIHRoZSBob29rLlxuICogQHByb3BlcnR5IHtJbnRlZ2VyfSBmaWxlU2l6ZSBUaGUgc2l6ZSBvZiB0aGUgZmlsZSBpbiBieXRlcy5cbiAqIEBwcm9wZXJ0eSB7SW50ZWdlcn0gY29udGVudExlbmd0aCBUaGUgdmFsdWUgZnJvbSBDb250ZW50LUxlbmd0aCBoZWFkZXJcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpcCBUaGUgSVAgYWRkcmVzcyBvZiB0aGUgY2xpZW50IG1ha2luZyB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBoZWFkZXJzIFRoZSBvcmlnaW5hbCBIVFRQIGhlYWRlcnMgZm9yIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtTdHJpbmd9IHRyaWdnZXJOYW1lIFRoZSBuYW1lIG9mIHRoZSB0cmlnZ2VyIChgYmVmb3JlU2F2ZUZpbGVgLCBgYWZ0ZXJTYXZlRmlsZWApXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nIFRoZSBjdXJyZW50IGxvZ2dlciBpbnNpZGUgUGFyc2UgU2VydmVyLlxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBQYXJzZS5DbG91ZC5Db25uZWN0VHJpZ2dlclJlcXVlc3RcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpbnN0YWxsYXRpb25JZCBJZiBzZXQsIHRoZSBpbnN0YWxsYXRpb25JZCB0cmlnZ2VyaW5nIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtCb29sZWFufSB1c2VNYXN0ZXJLZXkgSWYgdHJ1ZSwgbWVhbnMgdGhlIG1hc3RlciBrZXkgd2FzIHVzZWQuXG4gKiBAcHJvcGVydHkge1BhcnNlLlVzZXJ9IHVzZXIgSWYgc2V0LCB0aGUgdXNlciB0aGF0IG1hZGUgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge0ludGVnZXJ9IGNsaWVudHMgVGhlIG51bWJlciBvZiBjbGllbnRzIGNvbm5lY3RlZC5cbiAqIEBwcm9wZXJ0eSB7SW50ZWdlcn0gc3Vic2NyaXB0aW9ucyBUaGUgbnVtYmVyIG9mIHN1YnNjcmlwdGlvbnMgY29ubmVjdGVkLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IHNlc3Npb25Ub2tlbiBJZiBzZXQsIHRoZSBzZXNzaW9uIG9mIHRoZSB1c2VyIHRoYXQgbWFkZSB0aGUgcmVxdWVzdC5cbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgUGFyc2UuQ2xvdWQuTGl2ZVF1ZXJ5RXZlbnRUcmlnZ2VyXG4gKiBAcHJvcGVydHkge1N0cmluZ30gaW5zdGFsbGF0aW9uSWQgSWYgc2V0LCB0aGUgaW5zdGFsbGF0aW9uSWQgdHJpZ2dlcmluZyB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gdXNlTWFzdGVyS2V5IElmIHRydWUsIG1lYW5zIHRoZSBtYXN0ZXIga2V5IHdhcyB1c2VkLlxuICogQHByb3BlcnR5IHtQYXJzZS5Vc2VyfSB1c2VyIElmIHNldCwgdGhlIHVzZXIgdGhhdCBtYWRlIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtTdHJpbmd9IHNlc3Npb25Ub2tlbiBJZiBzZXQsIHRoZSBzZXNzaW9uIG9mIHRoZSB1c2VyIHRoYXQgbWFkZSB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBldmVudCBUaGUgbGl2ZSBxdWVyeSBldmVudCB0aGF0IHRyaWdnZXJlZCB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7UGFyc2UuT2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0cmlnZ2VyaW5nIHRoZSBob29rLlxuICogQHByb3BlcnR5IHtQYXJzZS5PYmplY3R9IG9yaWdpbmFsIElmIHNldCwgdGhlIG9iamVjdCwgYXMgY3VycmVudGx5IHN0b3JlZC5cbiAqIEBwcm9wZXJ0eSB7SW50ZWdlcn0gY2xpZW50cyBUaGUgbnVtYmVyIG9mIGNsaWVudHMgY29ubmVjdGVkLlxuICogQHByb3BlcnR5IHtJbnRlZ2VyfSBzdWJzY3JpcHRpb25zIFRoZSBudW1iZXIgb2Ygc3Vic2NyaXB0aW9ucyBjb25uZWN0ZWQuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IHNlbmRFdmVudCBJZiB0aGUgTGl2ZVF1ZXJ5IGV2ZW50IHNob3VsZCBiZSBzZW50IHRvIHRoZSBjbGllbnQuIFNldCB0byBmYWxzZSB0byBwcmV2ZW50IExpdmVRdWVyeSBmcm9tIHB1c2hpbmcgdG8gdGhlIGNsaWVudC5cbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgUGFyc2UuQ2xvdWQuQmVmb3JlRmluZFJlcXVlc3RcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpbnN0YWxsYXRpb25JZCBJZiBzZXQsIHRoZSBpbnN0YWxsYXRpb25JZCB0cmlnZ2VyaW5nIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtCb29sZWFufSBtYXN0ZXIgSWYgdHJ1ZSwgbWVhbnMgdGhlIG1hc3RlciBrZXkgd2FzIHVzZWQuXG4gKiBAcHJvcGVydHkge1BhcnNlLlVzZXJ9IHVzZXIgSWYgc2V0LCB0aGUgdXNlciB0aGF0IG1hZGUgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1BhcnNlLlF1ZXJ5fSBxdWVyeSBUaGUgcXVlcnkgdHJpZ2dlcmluZyB0aGUgaG9vay5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBpcCBUaGUgSVAgYWRkcmVzcyBvZiB0aGUgY2xpZW50IG1ha2luZyB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBoZWFkZXJzIFRoZSBvcmlnaW5hbCBIVFRQIGhlYWRlcnMgZm9yIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtTdHJpbmd9IHRyaWdnZXJOYW1lIFRoZSBuYW1lIG9mIHRoZSB0cmlnZ2VyIChgYmVmb3JlU2F2ZWAsIGBhZnRlclNhdmVgLCAuLi4pXG4gKiBAcHJvcGVydHkge09iamVjdH0gbG9nIFRoZSBjdXJyZW50IGxvZ2dlciBpbnNpZGUgUGFyc2UgU2VydmVyLlxuICogQHByb3BlcnR5IHtCb29sZWFufSBpc0dldCB3ZXRoZXIgdGhlIHF1ZXJ5IGEgYGdldGAgb3IgYSBgZmluZGBcbiAqL1xuXG4vKipcbiAqIEBpbnRlcmZhY2UgUGFyc2UuQ2xvdWQuQWZ0ZXJGaW5kUmVxdWVzdFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGluc3RhbGxhdGlvbklkIElmIHNldCwgdGhlIGluc3RhbGxhdGlvbklkIHRyaWdnZXJpbmcgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IG1hc3RlciBJZiB0cnVlLCBtZWFucyB0aGUgbWFzdGVyIGtleSB3YXMgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7UGFyc2UuVXNlcn0gdXNlciBJZiBzZXQsIHRoZSB1c2VyIHRoYXQgbWFkZSB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7UGFyc2UuUXVlcnl9IHF1ZXJ5IFRoZSBxdWVyeSB0cmlnZ2VyaW5nIHRoZSBob29rLlxuICogQHByb3BlcnR5IHtBcnJheTxQYXJzZS5PYmplY3Q+fSByZXN1bHRzIFRoZSByZXN1bHRzIHRoZSBxdWVyeSB5aWVsZGVkLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGlwIFRoZSBJUCBhZGRyZXNzIG9mIHRoZSBjbGllbnQgbWFraW5nIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtPYmplY3R9IGhlYWRlcnMgVGhlIG9yaWdpbmFsIEhUVFAgaGVhZGVycyBmb3IgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gdHJpZ2dlck5hbWUgVGhlIG5hbWUgb2YgdGhlIHRyaWdnZXIgKGBiZWZvcmVTYXZlYCwgYGFmdGVyU2F2ZWAsIC4uLilcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBsb2cgVGhlIGN1cnJlbnQgbG9nZ2VyIGluc2lkZSBQYXJzZSBTZXJ2ZXIuXG4gKi9cblxuLyoqXG4gKiBAaW50ZXJmYWNlIFBhcnNlLkNsb3VkLkZ1bmN0aW9uUmVxdWVzdFxuICogQHByb3BlcnR5IHtTdHJpbmd9IGluc3RhbGxhdGlvbklkIElmIHNldCwgdGhlIGluc3RhbGxhdGlvbklkIHRyaWdnZXJpbmcgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IG1hc3RlciBJZiB0cnVlLCBtZWFucyB0aGUgbWFzdGVyIGtleSB3YXMgdXNlZC5cbiAqIEBwcm9wZXJ0eSB7UGFyc2UuVXNlcn0gdXNlciBJZiBzZXQsIHRoZSB1c2VyIHRoYXQgbWFkZSB0aGUgcmVxdWVzdC5cbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBwYXJhbXMgVGhlIHBhcmFtcyBwYXNzZWQgdG8gdGhlIGNsb3VkIGZ1bmN0aW9uLlxuICovXG5cbi8qKlxuICogQGludGVyZmFjZSBQYXJzZS5DbG91ZC5Kb2JSZXF1ZXN0XG4gKiBAcHJvcGVydHkge09iamVjdH0gcGFyYW1zIFRoZSBwYXJhbXMgcGFzc2VkIHRvIHRoZSBiYWNrZ3JvdW5kIGpvYi5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IG1lc3NhZ2UgSWYgbWVzc2FnZSBpcyBjYWxsZWQgd2l0aCBhIHN0cmluZyBhcmd1bWVudCwgd2lsbCB1cGRhdGUgdGhlIGN1cnJlbnQgbWVzc2FnZSB0byBiZSBzdG9yZWQgaW4gdGhlIGpvYiBzdGF0dXMuXG4gKi9cblxuLyoqXG4gKiBAaW50ZXJmYWNlIFBhcnNlLkNsb3VkLlZhbGlkYXRvck9iamVjdFxuICogQHByb3BlcnR5IHtCb29sZWFufSByZXF1aXJlVXNlciB3aGV0aGVyIHRoZSBjbG91ZCB0cmlnZ2VyIHJlcXVpcmVzIGEgdXNlci5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gcmVxdWlyZU1hc3RlciB3aGV0aGVyIHRoZSBjbG91ZCB0cmlnZ2VyIHJlcXVpcmVzIGEgbWFzdGVyIGtleS5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gdmFsaWRhdGVNYXN0ZXJLZXkgd2hldGhlciB0aGUgdmFsaWRhdG9yIHNob3VsZCBydW4gaWYgbWFzdGVyS2V5IGlzIHByb3ZpZGVkLiBEZWZhdWx0cyB0byBmYWxzZS5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gc2tpcFdpdGhNYXN0ZXJLZXkgd2hldGhlciB0aGUgY2xvdWQgY29kZSBmdW5jdGlvbiBzaG91bGQgYmUgaWdub3JlZCB1c2luZyBhIG1hc3RlcktleS5cbiAqXG4gKiBAcHJvcGVydHkge0FycmF5PFN0cmluZz58T2JqZWN0fSByZXF1aXJlVXNlcktleXMgSWYgc2V0LCBrZXlzIHJlcXVpcmVkIG9uIHJlcXVlc3QudXNlciB0byBtYWtlIHRoZSByZXF1ZXN0LlxuICogQHByb3BlcnR5IHtTdHJpbmd9IHJlcXVpcmVVc2VyS2V5cy5maWVsZCBJZiByZXF1aXJlVXNlcktleXMgaXMgYW4gb2JqZWN0LCBuYW1lIG9mIGZpZWxkIHRvIHZhbGlkYXRlIG9uIHJlcXVlc3QgdXNlclxuICogQHByb3BlcnR5IHtBcnJheXxmdW5jdGlvbnxBbnl9IHJlcXVpcmVVc2VyS2V5cy5maWVsZC5vcHRpb25zIGFycmF5IG9mIG9wdGlvbnMgdGhhdCB0aGUgZmllbGQgY2FuIGJlLCBmdW5jdGlvbiB0byB2YWxpZGF0ZSBmaWVsZCwgb3Igc2luZ2xlIHZhbHVlLiBUaHJvdyBhbiBlcnJvciBpZiB2YWx1ZSBpcyBpbnZhbGlkLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IHJlcXVpcmVVc2VyS2V5cy5maWVsZC5lcnJvciBjdXN0b20gZXJyb3IgbWVzc2FnZSBpZiBmaWVsZCBpcyBpbnZhbGlkLlxuICpcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fEFycmF5PFN0cmluZz59IGZpZWxkcyBpZiBhbiBhcnJheSBvZiBzdHJpbmdzLCB2YWxpZGF0b3Igd2lsbCBsb29rIGZvciBrZXlzIGluIHJlcXVlc3QucGFyYW1zLCBhbmQgdGhyb3cgaWYgbm90IHByb3ZpZGVkLiBJZiBPYmplY3QsIGZpZWxkcyB0byB2YWxpZGF0ZS4gSWYgdGhlIHRyaWdnZXIgaXMgYSBjbG91ZCBmdW5jdGlvbiwgYHJlcXVlc3QucGFyYW1zYCB3aWxsIGJlIHZhbGlkYXRlZCwgb3RoZXJ3aXNlIGByZXF1ZXN0Lm9iamVjdGAuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gZmllbGRzLmZpZWxkIG5hbWUgb2YgZmllbGQgdG8gdmFsaWRhdGUuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gZmllbGRzLmZpZWxkLnR5cGUgZXhwZWN0ZWQgdHlwZSBvZiBkYXRhIGZvciBmaWVsZC5cbiAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gZmllbGRzLmZpZWxkLmNvbnN0YW50IHdoZXRoZXIgdGhlIGZpZWxkIGNhbiBiZSBtb2RpZmllZCBvbiB0aGUgb2JqZWN0LlxuICogQHByb3BlcnR5IHtBbnl9IGZpZWxkcy5maWVsZC5kZWZhdWx0IGRlZmF1bHQgdmFsdWUgaWYgZmllbGQgaXMgYG51bGxgLCBvciBpbml0aWFsIHZhbHVlIGBjb25zdGFudGAgaXMgYHRydWVgLlxuICogQHByb3BlcnR5IHtBcnJheXxmdW5jdGlvbnxBbnl9IGZpZWxkcy5maWVsZC5vcHRpb25zIGFycmF5IG9mIG9wdGlvbnMgdGhhdCB0aGUgZmllbGQgY2FuIGJlLCBmdW5jdGlvbiB0byB2YWxpZGF0ZSBmaWVsZCwgb3Igc2luZ2xlIHZhbHVlLiBUaHJvdyBhbiBlcnJvciBpZiB2YWx1ZSBpcyBpbnZhbGlkLlxuICogQHByb3BlcnR5IHtTdHJpbmd9IGZpZWxkcy5maWVsZC5lcnJvciBjdXN0b20gZXJyb3IgbWVzc2FnZSBpZiBmaWVsZCBpcyBpbnZhbGlkLlxuICovXG4iXX0= \ No newline at end of file diff --git a/lib/cloud-code/httpRequest.js b/lib/cloud-code/httpRequest.js deleted file mode 100644 index fc4f62a517..0000000000 --- a/lib/cloud-code/httpRequest.js +++ /dev/null @@ -1,192 +0,0 @@ -"use strict"; - -var _HTTPResponse = _interopRequireDefault(require("./HTTPResponse")); - -var _querystring = _interopRequireDefault(require("querystring")); - -var _logger = _interopRequireDefault(require("../logger")); - -var _followRedirects = require("follow-redirects"); - -var _url = require("url"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const clients = { - 'http:': _followRedirects.http, - 'https:': _followRedirects.https -}; - -function makeCallback(resolve, reject) { - return function (response) { - const chunks = []; - response.on('data', chunk => { - chunks.push(chunk); - }); - response.on('end', () => { - const body = Buffer.concat(chunks); - const httpResponse = new _HTTPResponse.default(response, body); // Consider <200 && >= 400 as errors - - if (httpResponse.status < 200 || httpResponse.status >= 400) { - return reject(httpResponse); - } else { - return resolve(httpResponse); - } - }); - response.on('error', reject); - }; -} - -const encodeBody = function ({ - body, - headers = {} -}) { - if (typeof body !== 'object') { - return { - body, - headers - }; - } - - var contentTypeKeys = Object.keys(headers).filter(key => { - return key.match(/content-type/i) != null; - }); - - if (contentTypeKeys.length == 0) { - // no content type - // As per https://parse.com/docs/cloudcode/guide#cloud-code-advanced-sending-a-post-request the default encoding is supposedly x-www-form-urlencoded - body = _querystring.default.stringify(body); - headers['Content-Type'] = 'application/x-www-form-urlencoded'; - } else { - /* istanbul ignore next */ - if (contentTypeKeys.length > 1) { - _logger.default.error('Parse.Cloud.httpRequest', 'multiple content-type headers are set.'); - } // There maybe many, we'll just take the 1st one - - - var contentType = contentTypeKeys[0]; - - if (headers[contentType].match(/application\/json/i)) { - body = JSON.stringify(body); - } else if (headers[contentType].match(/application\/x-www-form-urlencoded/i)) { - body = _querystring.default.stringify(body); - } - } - - return { - body, - headers - }; -}; -/** - * Makes an HTTP Request. - * - * **Available in Cloud Code only.** - * - * By default, Parse.Cloud.httpRequest does not follow redirects caused by HTTP 3xx response codes. You can use the followRedirects option in the {@link Parse.Cloud.HTTPOptions} object to change this behavior. - * - * Sample request: - * ``` - * Parse.Cloud.httpRequest({ - * url: 'http://www.parse.com/' - * }).then(function(httpResponse) { - * // success - * console.log(httpResponse.text); - * },function(httpResponse) { - * // error - * console.error('Request failed with response code ' + httpResponse.status); - * }); - * ``` - * - * @method httpRequest - * @name Parse.Cloud.httpRequest - * @param {Parse.Cloud.HTTPOptions} options The Parse.Cloud.HTTPOptions object that makes the request. - * @return {Promise} A promise that will be resolved with a {@link Parse.Cloud.HTTPResponse} object when the request completes. - */ - - -module.exports = function httpRequest(options) { - let url; - - try { - url = (0, _url.parse)(options.url); - } catch (e) { - return Promise.reject(e); - } - - options = Object.assign(options, encodeBody(options)); // support params options - - if (typeof options.params === 'object') { - options.qs = options.params; - } else if (typeof options.params === 'string') { - options.qs = _querystring.default.parse(options.params); - } - - const client = clients[url.protocol]; - - if (!client) { - return Promise.reject(`Unsupported protocol ${url.protocol}`); - } - - const requestOptions = { - method: options.method, - port: Number(url.port), - path: url.pathname, - hostname: url.hostname, - headers: options.headers, - encoding: null, - followRedirects: options.followRedirects === true - }; - - if (requestOptions.headers) { - Object.keys(requestOptions.headers).forEach(key => { - if (typeof requestOptions.headers[key] === 'undefined') { - delete requestOptions.headers[key]; - } - }); - } - - if (url.search) { - options.qs = Object.assign({}, options.qs, _querystring.default.parse(url.query)); - } - - if (url.auth) { - requestOptions.auth = url.auth; - } - - if (options.qs) { - requestOptions.path += `?${_querystring.default.stringify(options.qs)}`; - } - - if (options.agent) { - requestOptions.agent = options.agent; - } - - return new Promise((resolve, reject) => { - const req = client.request(requestOptions, makeCallback(resolve, reject, options)); - - if (options.body) { - req.write(options.body); - } - - req.on('error', error => { - reject(error); - }); - req.end(); - }); -}; -/** - * @typedef Parse.Cloud.HTTPOptions - * @property {String|Object} body The body of the request. If it is a JSON object, then the Content-Type set in the headers must be application/x-www-form-urlencoded or application/json. You can also set this to a {@link Buffer} object to send raw bytes. If you use a Buffer, you should also set the Content-Type header explicitly to describe what these bytes represent. - * @property {function} error The function that is called when the request fails. It will be passed a Parse.Cloud.HTTPResponse object. - * @property {Boolean} followRedirects Whether to follow redirects caused by HTTP 3xx responses. Defaults to false. - * @property {Object} headers The headers for the request. - * @property {String} method The method of the request. GET, POST, PUT, DELETE, HEAD, and OPTIONS are supported. Will default to GET if not specified. - * @property {String|Object} params The query portion of the url. You can pass a JSON object of key value pairs like params: {q : 'Sean Plott'} or a raw string like params:q=Sean Plott. - * @property {function} success The function that is called when the request successfully completes. It will be passed a Parse.Cloud.HTTPResponse object. - * @property {string} url The url to send the request to. - */ - - -module.exports.encodeBody = encodeBody; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbG91ZC1jb2RlL2h0dHBSZXF1ZXN0LmpzIl0sIm5hbWVzIjpbImNsaWVudHMiLCJodHRwIiwiaHR0cHMiLCJtYWtlQ2FsbGJhY2siLCJyZXNvbHZlIiwicmVqZWN0IiwicmVzcG9uc2UiLCJjaHVua3MiLCJvbiIsImNodW5rIiwicHVzaCIsImJvZHkiLCJCdWZmZXIiLCJjb25jYXQiLCJodHRwUmVzcG9uc2UiLCJIVFRQUmVzcG9uc2UiLCJzdGF0dXMiLCJlbmNvZGVCb2R5IiwiaGVhZGVycyIsImNvbnRlbnRUeXBlS2V5cyIsIk9iamVjdCIsImtleXMiLCJmaWx0ZXIiLCJrZXkiLCJtYXRjaCIsImxlbmd0aCIsInF1ZXJ5c3RyaW5nIiwic3RyaW5naWZ5IiwibG9nIiwiZXJyb3IiLCJjb250ZW50VHlwZSIsIkpTT04iLCJtb2R1bGUiLCJleHBvcnRzIiwiaHR0cFJlcXVlc3QiLCJvcHRpb25zIiwidXJsIiwiZSIsIlByb21pc2UiLCJhc3NpZ24iLCJwYXJhbXMiLCJxcyIsInBhcnNlIiwiY2xpZW50IiwicHJvdG9jb2wiLCJyZXF1ZXN0T3B0aW9ucyIsIm1ldGhvZCIsInBvcnQiLCJOdW1iZXIiLCJwYXRoIiwicGF0aG5hbWUiLCJob3N0bmFtZSIsImVuY29kaW5nIiwiZm9sbG93UmVkaXJlY3RzIiwiZm9yRWFjaCIsInNlYXJjaCIsInF1ZXJ5IiwiYXV0aCIsImFnZW50IiwicmVxIiwicmVxdWVzdCIsIndyaXRlIiwiZW5kIl0sIm1hcHBpbmdzIjoiOztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRUEsTUFBTUEsT0FBTyxHQUFHO0FBQ2QsV0FBU0MscUJBREs7QUFFZCxZQUFVQztBQUZJLENBQWhCOztBQUtBLFNBQVNDLFlBQVQsQ0FBc0JDLE9BQXRCLEVBQStCQyxNQUEvQixFQUF1QztBQUNyQyxTQUFPLFVBQVVDLFFBQVYsRUFBb0I7QUFDekIsVUFBTUMsTUFBTSxHQUFHLEVBQWY7QUFDQUQsSUFBQUEsUUFBUSxD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M0MsQ0FBWjs7QUFDQSxRQUFJQSxPQUFPLENBQUN4QixJQUFaLEVBQWtCO0FBQ2hCZ0QsTUFBQUEsR0FBRyxDQUFDRSxLQUFKLENBQVUxQixPQUFPLENBQUN4QixJQUFsQjtBQUNEOztBQUNEZ0QsSUFBQUEsR0FBRyxDQUFDbkQsRUFBSixDQUFPLE9BQVAsRUFBZ0JxQixLQUFLLElBQUk7QUFDdkJ4QixNQUFBQSxNQUFNLENBQUN3QixLQUFELENBQU47QUFDRCxLQUZEO0FBR0E4QixJQUFBQSxHQUFHLENBQUNHLEdBQUo7QUFDRCxHQVRNLENBQVA7QUFVRCxDQXhERDtBQTBEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFFQTlCLE1BQU0sQ0FBQ0MsT0FBUCxDQUFlaEIsVUFBZixHQUE0QkEsVUFBNUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgSFRUUFJlc3BvbnNlIGZyb20gJy4vSFRUUFJlc3BvbnNlJztcbmltcG9ydCBxdWVyeXN0cmluZyBmcm9tICdxdWVyeXN0cmluZyc7XG5pbXBvcnQgbG9nIGZyb20gJy4uL2xvZ2dlcic7XG5pbXBvcnQgeyBodHRwLCBodHRwcyB9IGZyb20gJ2ZvbGxvdy1yZWRpcmVjdHMnO1xuaW1wb3J0IHsgcGFyc2UgfSBmcm9tICd1cmwnO1xuXG5jb25zdCBjbGllbnRzID0ge1xuICAnaHR0cDonOiBodHRwLFxuICAnaHR0cHM6JzogaHR0cHMsXG59O1xuXG5mdW5jdGlvbiBtYWtlQ2FsbGJhY2socmVzb2x2ZSwgcmVqZWN0KSB7XG4gIHJldHVybiBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICBjb25zdCBjaHVua3MgPSBbXTtcbiAgICByZXNwb25zZS5vbignZGF0YScsIGNodW5rID0+IHtcbiAgICAgIGNodW5rcy5wdXNoKGNodW5rKTtcbiAgICB9KTtcbiAgICByZXNwb25zZS5vbignZW5kJywgKCkgPT4ge1xuICAgICAgY29uc3QgYm9keSA9IEJ1ZmZlci5jb25jYXQoY2h1bmtzKTtcbiAgICAgIGNvbnN0IGh0dHBSZXNwb25zZSA9IG5ldyBIVFRQUmVzcG9uc2UocmVzcG9uc2UsIGJvZHkpO1xuXG4gICAgICAvLyBDb25zaWRlciA8MjAwICYmID49IDQwMCBhcyBlcnJvcnNcbiAgICAgIGlmIChodHRwUmVzcG9uc2Uuc3RhdHVzIDwgMjAwIHx8IGh0dHBSZXNwb25zZS5zdGF0dXMgPj0gNDAwKSB7XG4gICAgICAgIHJldHVybiByZWplY3QoaHR0cFJlc3BvbnNlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlKGh0dHBSZXNwb25zZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmVzcG9uc2Uub24oJ2Vycm9yJywgcmVqZWN0KTtcbiAgfTtcbn1cblxuY29uc3QgZW5jb2RlQm9keSA9IGZ1bmN0aW9uICh7IGJvZHksIGhlYWRlcnMgPSB7fSB9KSB7XG4gIGlmICh0eXBlb2YgYm9keSAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4geyBib2R5LCBoZWFkZXJzIH07XG4gIH1cbiAgdmFyIGNvbnRlbnRUeXBlS2V5cyA9IE9iamVjdC5rZXlzKGhlYWRlcnMpLmZpbHRlcihrZXkgPT4ge1xuICAgIHJldHVybiBrZXkubWF0Y2goL2NvbnRlbnQtdHlwZS9pKSAhPSBudWxsO1xuICB9KTtcblxuICBpZiAoY29udGVudFR5cGVLZXlzLmxlbmd0aCA9PSAwKSB7XG4gICAgLy8gbm8gY29udGVudCB0eXBlXG4gICAgLy8gIEFzIHBlciBodHRwczovL3BhcnNlLmNvbS9kb2NzL2Nsb3VkY29kZS9ndWlkZSNjbG91ZC1jb2RlLWFkdmFuY2VkLXNlbmRpbmctYS1wb3N0LXJlcXVlc3QgdGhlIGRlZmF1bHQgZW5jb2RpbmcgaXMgc3VwcG9zZWRseSB4LXd3dy1mb3JtLXVybGVuY29kZWRcblxuICAgIGJvZHkgPSBxdWVyeXN0cmluZy5zdHJpbmdpZnkoYm9keSk7XG4gICAgaGVhZGVyc1snQ29udGVudC1UeXBlJ10gPSAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkJztcbiAgfSBlbHNlIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIGlmIChjb250ZW50VHlwZUtleXMubGVuZ3RoID4gMSkge1xuICAgICAgbG9nLmVycm9yKCdQYXJzZS5DbG91ZC5odHRwUmVxdWVzdCcsICdtdWx0aXBsZSBjb250ZW50LXR5cGUgaGVhZGVycyBhcmUgc2V0LicpO1xuICAgIH1cbiAgICAvLyBUaGVyZSBtYXliZSBtYW55LCB3ZSdsbCBqdXN0IHRha2UgdGhlIDFzdCBvbmVcbiAgICB2YXIgY29udGVudFR5cGUgPSBjb250ZW50VHlwZUtleXNbMF07XG4gICAgaWYgKGhlYWRlcnNbY29udGVudFR5cGVdLm1hdGNoKC9hcHBsaWNhdGlvblxcL2pzb24vaSkpIHtcbiAgICAgIGJvZHkgPSBKU09OLnN0cmluZ2lmeShib2R5KTtcbiAgICB9IGVsc2UgaWYgKGhlYWRlcnNbY29udGVudFR5cGVdLm1hdGNoKC9hcHBsaWNhdGlvblxcL3gtd3d3LWZvcm0tdXJsZW5jb2RlZC9pKSkge1xuICAgICAgYm9keSA9IHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeShib2R5KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHsgYm9keSwgaGVhZGVycyB9O1xufTtcblxuLyoqXG4gKiBNYWtlcyBhbiBIVFRQIFJlcXVlc3QuXG4gKlxuICogKipBdmFpbGFibGUgaW4gQ2xvdWQgQ29kZSBvbmx5LioqXG4gKlxuICogQnkgZGVmYXVsdCwgUGFyc2UuQ2xvdWQuaHR0cFJlcXVlc3QgZG9lcyBub3QgZm9sbG93IHJlZGlyZWN0cyBjYXVzZWQgYnkgSFRUUCAzeHggcmVzcG9uc2UgY29kZXMuIFlvdSBjYW4gdXNlIHRoZSBmb2xsb3dSZWRpcmVjdHMgb3B0aW9uIGluIHRoZSB7QGxpbmsgUGFyc2UuQ2xvdWQuSFRUUE9wdGlvbnN9IG9iamVjdCB0byBjaGFuZ2UgdGhpcyBiZWhhdmlvci5cbiAqXG4gKiBTYW1wbGUgcmVxdWVzdDpcbiAqIGBgYFxuICogUGFyc2UuQ2xvdWQuaHR0cFJlcXVlc3Qoe1xuICogICB1cmw6ICdodHRwOi8vd3d3LnBhcnNlLmNvbS8nXG4gKiB9KS50aGVuKGZ1bmN0aW9uKGh0dHBSZXNwb25zZSkge1xuICogICAvLyBzdWNjZXNzXG4gKiAgIGNvbnNvbGUubG9nKGh0dHBSZXNwb25zZS50ZXh0KTtcbiAqIH0sZnVuY3Rpb24oaHR0cFJlc3BvbnNlKSB7XG4gKiAgIC8vIGVycm9yXG4gKiAgIGNvbnNvbGUuZXJyb3IoJ1JlcXVlc3QgZmFpbGVkIHdpdGggcmVzcG9uc2UgY29kZSAnICsgaHR0cFJlc3BvbnNlLnN0YXR1cyk7XG4gKiB9KTtcbiAqIGBgYFxuICpcbiAqIEBtZXRob2QgaHR0cFJlcXVlc3RcbiAqIEBuYW1lIFBhcnNlLkNsb3VkLmh0dHBSZXF1ZXN0XG4gKiBAcGFyYW0ge1BhcnNlLkNsb3VkLkhUVFBPcHRpb25zfSBvcHRpb25zIFRoZSBQYXJzZS5DbG91ZC5IVFRQT3B0aW9ucyBvYmplY3QgdGhhdCBtYWtlcyB0aGUgcmVxdWVzdC5cbiAqIEByZXR1cm4ge1Byb21pc2U8UGFyc2UuQ2xvdWQuSFRUUFJlc3BvbnNlPn0gQSBwcm9taXNlIHRoYXQgd2lsbCBiZSByZXNvbHZlZCB3aXRoIGEge0BsaW5rIFBhcnNlLkNsb3VkLkhUVFBSZXNwb25zZX0gb2JqZWN0IHdoZW4gdGhlIHJlcXVlc3QgY29tcGxldGVzLlxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGh0dHBSZXF1ZXN0KG9wdGlvbnMpIHtcbiAgbGV0IHVybDtcbiAgdHJ5IHtcbiAgICB1cmwgPSBwYXJzZShvcHRpb25zLnVybCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZSk7XG4gIH1cbiAgb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24ob3B0aW9ucywgZW5jb2RlQm9keShvcHRpb25zKSk7XG4gIC8vIHN1cHBvcnQgcGFyYW1zIG9wdGlvbnNcbiAgaWYgKHR5cGVvZiBvcHRpb25zLnBhcmFtcyA9PT0gJ29iamVjdCcpIHtcbiAgICBvcHRpb25zLnFzID0gb3B0aW9ucy5wYXJhbXM7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG9wdGlvbnMucGFyYW1zID09PSAnc3RyaW5nJykge1xuICAgIG9wdGlvbnMucXMgPSBxdWVyeXN0cmluZy5wYXJzZShvcHRpb25zLnBhcmFtcyk7XG4gIH1cbiAgY29uc3QgY2xpZW50ID0gY2xpZW50c1t1cmwucHJvdG9jb2xdO1xuICBpZiAoIWNsaWVudCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlamVjdChgVW5zdXBwb3J0ZWQgcHJvdG9jb2wgJHt1cmwucHJvdG9jb2x9YCk7XG4gIH1cbiAgY29uc3QgcmVxdWVzdE9wdGlvbnMgPSB7XG4gICAgbWV0aG9kOiBvcHRpb25zLm1ldGhvZCxcbiAgICBwb3J0OiBOdW1iZXIodXJsLnBvcnQpLFxuICAgIHBhdGg6IHVybC5wYXRobmFtZSxcbiAgICBob3N0bmFtZTogdXJsLmhvc3RuYW1lLFxuICAgIGhlYWRlcnM6IG9wdGlvbnMuaGVhZGVycyxcbiAgICBlbmNvZGluZzogbnVsbCxcbiAgICBmb2xsb3dSZWRpcmVjdHM6IG9wdGlvbnMuZm9sbG93UmVkaXJlY3RzID09PSB0cnVlLFxuICB9O1xuICBpZiAocmVxdWVzdE9wdGlvbnMuaGVhZGVycykge1xuICAgIE9iamVjdC5rZXlzKHJlcXVlc3RPcHRpb25zLmhlYWRlcnMpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGlmICh0eXBlb2YgcmVxdWVzdE9wdGlvbnMuaGVhZGVyc1trZXldID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBkZWxldGUgcmVxdWVzdE9wdGlvbnMuaGVhZGVyc1trZXldO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIGlmICh1cmwuc2VhcmNoKSB7XG4gICAgb3B0aW9ucy5xcyA9IE9iamVjdC5hc3NpZ24oe30sIG9wdGlvbnMucXMsIHF1ZXJ5c3RyaW5nLnBhcnNlKHVybC5xdWVyeSkpO1xuICB9XG4gIGlmICh1cmwuYXV0aCkge1xuICAgIHJlcXVlc3RPcHRpb25zLmF1dGggPSB1cmwuYXV0aDtcbiAgfVxuICBpZiAob3B0aW9ucy5xcykge1xuICAgIHJlcXVlc3RPcHRpb25zLnBhdGggKz0gYD8ke3F1ZXJ5c3RyaW5nLnN0cmluZ2lmeShvcHRpb25zLnFzKX1gO1xuICB9XG4gIGlmIChvcHRpb25zLmFnZW50KSB7XG4gICAgcmVxdWVzdE9wdGlvbnMuYWdlbnQgPSBvcHRpb25zLmFnZW50O1xuICB9XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgcmVxID0gY2xpZW50LnJlcXVlc3QocmVxdWVzdE9wdGlvbnMsIG1ha2VDYWxsYmFjayhyZXNvbHZlLCByZWplY3QsIG9wdGlvbnMpKTtcbiAgICBpZiAob3B0aW9ucy5ib2R5KSB7XG4gICAgICByZXEud3JpdGUob3B0aW9ucy5ib2R5KTtcbiAgICB9XG4gICAgcmVxLm9uKCdlcnJvcicsIGVycm9yID0+IHtcbiAgICAgIHJlamVjdChlcnJvcik7XG4gICAgfSk7XG4gICAgcmVxLmVuZCgpO1xuICB9KTtcbn07XG5cbi8qKlxuICogQHR5cGVkZWYgUGFyc2UuQ2xvdWQuSFRUUE9wdGlvbnNcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfE9iamVjdH0gYm9keSBUaGUgYm9keSBvZiB0aGUgcmVxdWVzdC4gSWYgaXQgaXMgYSBKU09OIG9iamVjdCwgdGhlbiB0aGUgQ29udGVudC1UeXBlIHNldCBpbiB0aGUgaGVhZGVycyBtdXN0IGJlIGFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCBvciBhcHBsaWNhdGlvbi9qc29uLiBZb3UgY2FuIGFsc28gc2V0IHRoaXMgdG8gYSB7QGxpbmsgQnVmZmVyfSBvYmplY3QgdG8gc2VuZCByYXcgYnl0ZXMuIElmIHlvdSB1c2UgYSBCdWZmZXIsIHlvdSBzaG91bGQgYWxzbyBzZXQgdGhlIENvbnRlbnQtVHlwZSBoZWFkZXIgZXhwbGljaXRseSB0byBkZXNjcmliZSB3aGF0IHRoZXNlIGJ5dGVzIHJlcHJlc2VudC5cbiAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb259IGVycm9yIFRoZSBmdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSByZXF1ZXN0IGZhaWxzLiBJdCB3aWxsIGJlIHBhc3NlZCBhIFBhcnNlLkNsb3VkLkhUVFBSZXNwb25zZSBvYmplY3QuXG4gKiBAcHJvcGVydHkge0Jvb2xlYW59IGZvbGxvd1JlZGlyZWN0cyBXaGV0aGVyIHRvIGZvbGxvdyByZWRpcmVjdHMgY2F1c2VkIGJ5IEhUVFAgM3h4IHJlc3BvbnNlcy4gRGVmYXVsdHMgdG8gZmFsc2UuXG4gKiBAcHJvcGVydHkge09iamVjdH0gaGVhZGVycyBUaGUgaGVhZGVycyBmb3IgdGhlIHJlcXVlc3QuXG4gKiBAcHJvcGVydHkge1N0cmluZ30gbWV0aG9kIFRoZSBtZXRob2Qgb2YgdGhlIHJlcXVlc3QuIEdFVCwgUE9TVCwgUFVULCBERUxFVEUsIEhFQUQsIGFuZCBPUFRJT05TIGFyZSBzdXBwb3J0ZWQuIFdpbGwgZGVmYXVsdCB0byBHRVQgaWYgbm90IHNwZWNpZmllZC5cbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfE9iamVjdH0gcGFyYW1zIFRoZSBxdWVyeSBwb3J0aW9uIG9mIHRoZSB1cmwuIFlvdSBjYW4gcGFzcyBhIEpTT04gb2JqZWN0IG9mIGtleSB2YWx1ZSBwYWlycyBsaWtlIHBhcmFtczoge3EgOiAnU2VhbiBQbG90dCd9IG9yIGEgcmF3IHN0cmluZyBsaWtlIHBhcmFtczpxPVNlYW4gUGxvdHQuXG4gKiBAcHJvcGVydHkge2Z1bmN0aW9ufSBzdWNjZXNzIFRoZSBmdW5jdGlvbiB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSByZXF1ZXN0IHN1Y2Nlc3NmdWxseSBjb21wbGV0ZXMuIEl0IHdpbGwgYmUgcGFzc2VkIGEgUGFyc2UuQ2xvdWQuSFRUUFJlc3BvbnNlIG9iamVjdC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB1cmwgVGhlIHVybCB0byBzZW5kIHRoZSByZXF1ZXN0IHRvLlxuICovXG5cbm1vZHVsZS5leHBvcnRzLmVuY29kZUJvZHkgPSBlbmNvZGVCb2R5O1xuIl19 \ No newline at end of file diff --git a/lib/cryptoUtils.js b/lib/cryptoUtils.js deleted file mode 100644 index 5267fc1838..0000000000 --- a/lib/cryptoUtils.js +++ /dev/null @@ -1,62 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.randomHexString = randomHexString; -exports.randomString = randomString; -exports.newObjectId = newObjectId; -exports.newToken = newToken; -exports.md5Hash = md5Hash; - -var _crypto = require("crypto"); - -// Returns a new random hex string of the given even size. -function randomHexString(size) { - if (size === 0) { - throw new Error('Zero-length randomHexString is useless.'); - } - - if (size % 2 !== 0) { - throw new Error('randomHexString size must be divisible by 2.'); - } - - return (0, _crypto.randomBytes)(size / 2).toString('hex'); -} // Returns a new random alphanumeric string of the given size. -// -// Note: to simplify implementation, the result has slight modulo bias, -// because chars length of 62 doesn't divide the number of all bytes -// (256) evenly. Such bias is acceptable for most cases when the output -// length is long enough and doesn't need to be uniform. - - -function randomString(size) { - if (size === 0) { - throw new Error('Zero-length randomString is useless.'); - } - - const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789'; - let objectId = ''; - const bytes = (0, _crypto.randomBytes)(size); - - for (let i = 0; i < bytes.length; ++i) { - objectId += chars[bytes.readUInt8(i) % chars.length]; - } - - return objectId; -} // Returns a new random alphanumeric string suitable for object ID. - - -function newObjectId(size = 10) { - return randomString(size); -} // Returns a new random hex string suitable for secure tokens. - - -function newToken() { - return randomHexString(32); -} - -function md5Hash(string) { - return (0, _crypto.createHash)('md5').update(string).digest('hex'); -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jcnlwdG9VdGlscy5qcyJdLCJuYW1lcyI6WyJyYW5kb21IZXhTdHJpbmciLCJzaXplIiwiRXJyb3IiLCJ0b1N0cmluZyIsInJhbmRvbVN0cmluZyIsImNoYXJzIiwib2JqZWN0SWQiLCJieXRlcyIsImkiLCJsZW5ndGgiLCJyZWFkVUludDgiLCJuZXdPYmplY3RJZCIsIm5ld1Rva2VuIiwibWQ1SGFzaCIsInN0cmluZyIsInVwZGF0ZSIsImRpZ2VzdCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFFQTs7QUFFQTtBQUNPLFNBQVNBLGVBQVQsQ0FBeUJDLElBQXpCLEVBQStDO0FBQ3BELE1BQUlBLElBQUksS0FBSyxDQUFiLEVBQWdCO0FBQ2QsVUFBTSxJQUFJQyxLQUFKLENBQVUseUNBQVYsQ0FBTjtBQUNEOztBQUNELE1BQUlELElBQUksR0FBRyxDQUFQLEtBQWEsQ0FBakIsRUFBb0I7QUFDbEIsVUFBTSxJQUFJQyxLQUFKLENBQVUsOENBQVYsQ0FBTjtBQUNEOztBQUNELFNBQU8seUJBQVlELElBQUksR0FBRyxDQUFuQixFQUFzQkUsUUFBdEIsQ0FBK0IsS0FBL0IsQ0FBUDtBQUNELEMsQ0FFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNPLFNBQVNDLFlBQVQsQ0FBc0JILElBQXRCLEVBQTRDO0FBQ2pELE1BQUlBLElBQUksS0FBSyxDQUFiLEVBQWdCO0FBQ2QsVUFBTSxJQUFJQyxLQUFKLENBQVUsc0NBQVYsQ0FBTjtBQUNEOztBQUNELFFBQU1HLEtBQUssR0FBRywrQkFBK0IsNEJBQS9CLEdBQThELFlBQTVFO0FBQ0EsTUFBSUMsUUFBUSxHQUFHLEVBQWY7QUFDQSxRQUFNQyxLQUFLLEdBQUcseUJBQVlOLElBQVosQ0FBZDs7QUFDQSxPQUFLLElBQUlPLENBQUMsR0FBRyxDQUFiLEVBQWdCQSxDQUFDLEdBQUdELEtBQUssQ0FBQ0UsTUFBMUIsRUFBa0MsRUFBRUQsQ0FBcEMsRUFBdUM7QUFDckNGLElBQUFBLFFBQVEsSUFBSUQsS0FBSyxDQUFDRSxLQUFLLENBQUNHLFNBQU4sQ0FBZ0JGLENBQWhCLElBQXFCSCxLQUFLLENBQUNJLE1BQTVCLENBQWpCO0FBQ0Q7O0FBQ0QsU0FBT0gsUUFBUDtBQUNELEMsQ0FFRDs7O0FBQ08sU0FBU0ssV0FBVCxDQUFxQlYsSUFBWSxHQUFHLEVBQXBDLEVBQWdEO0FBQ3JELFNBQU9HLFlBQVksQ0FBQ0gsSUFBRCxDQUFuQjtBQUNELEMsQ0FFRDs7O0FBQ08sU0FBU1csUUFBVCxHQUE0QjtBQUNqQyxTQUFPWixlQUFlLENBQUMsRUFBRCxDQUF0QjtBQUNEOztBQUVNLFNBQVNhLE9BQVQsQ0FBaUJDLE1BQWpCLEVBQXlDO0FBQzlDLFNBQU8sd0JBQVcsS0FBWCxFQUFrQkMsTUFBbEIsQ0FBeUJELE1BQXpCLEVBQWlDRSxNQUFqQyxDQUF3QyxLQUF4QyxDQUFQO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBAZmxvdyAqL1xuXG5pbXBvcnQgeyByYW5kb21CeXRlcywgY3JlYXRlSGFzaCB9IGZyb20gJ2NyeXB0byc7XG5cbi8vIFJldHVybnMgYSBuZXcgcmFuZG9tIGhleCBzdHJpbmcgb2YgdGhlIGdpdmVuIGV2ZW4gc2l6ZS5cbmV4cG9ydCBmdW5jdGlvbiByYW5kb21IZXhTdHJpbmcoc2l6ZTogbnVtYmVyKTogc3RyaW5nIHtcbiAgaWYgKHNpemUgPT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1plcm8tbGVuZ3RoIHJhbmRvbUhleFN0cmluZyBpcyB1c2VsZXNzLicpO1xuICB9XG4gIGlmIChzaXplICUgMiAhPT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcigncmFuZG9tSGV4U3RyaW5nIHNpemUgbXVzdCBiZSBkaXZpc2libGUgYnkgMi4nKTtcbiAgfVxuICByZXR1cm4gcmFuZG9tQnl0ZXMoc2l6ZSAvIDIpLnRvU3RyaW5nKCdoZXgnKTtcbn1cblxuLy8gUmV0dXJucyBhIG5ldyByYW5kb20gYWxwaGFudW1lcmljIHN0cmluZyBvZiB0aGUgZ2l2ZW4gc2l6ZS5cbi8vXG4vLyBOb3RlOiB0byBzaW1wbGlmeSBpbXBsZW1lbnRhdGlvbiwgdGhlIHJlc3VsdCBoYXMgc2xpZ2h0IG1vZHVsbyBiaWFzLFxuLy8gYmVjYXVzZSBjaGFycyBsZW5ndGggb2YgNjIgZG9lc24ndCBkaXZpZGUgdGhlIG51bWJlciBvZiBhbGwgYnl0ZXNcbi8vICgyNTYpIGV2ZW5seS4gU3VjaCBiaWFzIGlzIGFjY2VwdGFibGUgZm9yIG1vc3QgY2FzZXMgd2hlbiB0aGUgb3V0cHV0XG4vLyBsZW5ndGggaXMgbG9uZyBlbm91Z2ggYW5kIGRvZXNuJ3QgbmVlZCB0byBiZSB1bmlmb3JtLlxuZXhwb3J0IGZ1bmN0aW9uIHJhbmRvbVN0cmluZyhzaXplOiBudW1iZXIpOiBzdHJpbmcge1xuICBpZiAoc2l6ZSA9PT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignWmVyby1sZW5ndGggcmFuZG9tU3RyaW5nIGlzIHVzZWxlc3MuJyk7XG4gIH1cbiAgY29uc3QgY2hhcnMgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVonICsgJ2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6JyArICcwMTIzNDU2Nzg5JztcbiAgbGV0IG9iamVjdElkID0gJyc7XG4gIGNvbnN0IGJ5dGVzID0gcmFuZG9tQnl0ZXMoc2l6ZSk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyArK2kpIHtcbiAgICBvYmplY3RJZCArPSBjaGFyc1tieXRlcy5yZWFkVUludDgoaSkgJSBjaGFycy5sZW5ndGhdO1xuICB9XG4gIHJldHVybiBvYmplY3RJZDtcbn1cblxuLy8gUmV0dXJucyBhIG5ldyByYW5kb20gYWxwaGFudW1lcmljIHN0cmluZyBzdWl0YWJsZSBmb3Igb2JqZWN0IElELlxuZXhwb3J0IGZ1bmN0aW9uIG5ld09iamVjdElkKHNpemU6IG51bWJlciA9IDEwKTogc3RyaW5nIHtcbiAgcmV0dXJuIHJhbmRvbVN0cmluZyhzaXplKTtcbn1cblxuLy8gUmV0dXJucyBhIG5ldyByYW5kb20gaGV4IHN0cmluZyBzdWl0YWJsZSBmb3Igc2VjdXJlIHRva2Vucy5cbmV4cG9ydCBmdW5jdGlvbiBuZXdUb2tlbigpOiBzdHJpbmcge1xuICByZXR1cm4gcmFuZG9tSGV4U3RyaW5nKDMyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1kNUhhc2goc3RyaW5nOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gY3JlYXRlSGFzaCgnbWQ1JykudXBkYXRlKHN0cmluZykuZGlnZXN0KCdoZXgnKTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/defaults.js b/lib/defaults.js deleted file mode 100644 index d824d3ba1d..0000000000 --- a/lib/defaults.js +++ /dev/null @@ -1,60 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.DefaultMongoURI = exports.default = void 0; - -var _parsers = require("./Options/parsers"); - -const { - ParseServerOptions -} = require('./Options/Definitions'); - -const logsFolder = (() => { - let folder = './logs/'; - - if (typeof process !== 'undefined' && process.env.TESTING === '1') { - folder = './test_logs/'; - } - - if (process.env.PARSE_SERVER_LOGS_FOLDER) { - folder = (0, _parsers.nullParser)(process.env.PARSE_SERVER_LOGS_FOLDER); - } - - return folder; -})(); - -const { - verbose, - level -} = (() => { - const verbose = process.env.VERBOSE ? true : false; - return { - verbose, - level: verbose ? 'verbose' : undefined - }; -})(); - -const DefinitionDefaults = Object.keys(ParseServerOptions).reduce((memo, key) => { - const def = ParseServerOptions[key]; - - if (Object.prototype.hasOwnProperty.call(def, 'default')) { - memo[key] = def.default; - } - - return memo; -}, {}); -const computedDefaults = { - jsonLogs: process.env.JSON_LOGS || false, - logsFolder, - verbose, - level -}; - -var _default = Object.assign({}, DefinitionDefaults, computedDefaults); - -exports.default = _default; -const DefaultMongoURI = DefinitionDefaults.databaseURI; -exports.DefaultMongoURI = DefaultMongoURI; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9kZWZhdWx0cy5qcyJdLCJuYW1lcyI6WyJQYXJzZVNlcnZlck9wdGlvbnMiLCJyZXF1aXJlIiwibG9nc0ZvbGRlciIsImZvbGRlciIsInByb2Nlc3MiLCJlbnYiLCJURVNUSU5HIiwiUEFSU0VfU0VSVkVSX0xPR1NfRk9MREVSIiwidmVyYm9zZSIsImxldmVsIiwiVkVSQk9TRSIsInVuZGVmaW5lZCIsIkRlZmluaXRpb25EZWZhdWx0cyIsIk9iamVjdCIsImtleXMiLCJyZWR1Y2UiLCJtZW1vIiwia2V5IiwiZGVmIiwicHJvdG90eXBlIiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiZGVmYXVsdCIsImNvbXB1dGVkRGVmYXVsdHMiLCJqc29uTG9ncyIsIkpTT05fTE9HUyIsImFzc2lnbiIsIkRlZmF1bHRNb25nb1VSSSIsImRhdGFiYXNlVVJJIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBQ0EsTUFBTTtBQUFFQSxFQUFBQTtBQUFGLElBQXlCQyxPQUFPLENBQUMsdUJBQUQsQ0FBdEM7O0FBQ0EsTUFBTUMsVUFBVSxHQUFHLENBQUMsTUFBTTtBQUN4QixNQUFJQyxNQUFNLEdBQUcsU0FBYjs7QUFDQSxNQUFJLE9BQU9DLE9BQVAsS0FBbUIsV0FBbkIsSUFBa0NBLE9BQU8sQ0FBQ0MsR0FBUixDQUFZQyxPQUFaLEtBQXdCLEdBQTlELEVBQW1FO0FBQ2pFSCxJQUFBQSxNQUFNLEdBQUcsY0FBVDtBQUNEOztBQUNELE1BQUlDLE9BQU8sQ0FBQ0MsR0FBUixDQUFZRSx3QkFBaEIsRUFBMEM7QUFDeENKLElBQUFBLE1BQU0sR0FBRyx5QkFBV0MsT0FBTyxDQUFDQyxHQUFSLENBQVlFLHdCQUF2QixDQUFUO0FBQ0Q7O0FBQ0QsU0FBT0osTUFBUDtBQUNELENBVGtCLEdBQW5COztBQVdBLE1BQU07QUFBRUssRUFBQUEsT0FBRjtBQUFXQyxFQUFBQTtBQUFYLElBQXFCLENBQUMsTUFBTTtBQUNoQyxRQUFNRCxPQUFPLEdBQUdKLE9BQU8sQ0FBQ0MsR0FBUixDQUFZSyxPQUFaLEdBQXNCLElBQXRCLEdBQTZCLEtBQTdDO0FBQ0EsU0FBTztBQUFFRixJQUFBQSxPQUFGO0FBQVdDLElBQUFBLEtBQUssRUFBRUQsT0FBTyxHQUFHLFNBQUgsR0FBZUc7QUFBeEMsR0FBUDtBQUNELENBSDBCLEdBQTNCOztBQUtBLE1BQU1DLGtCQUFrQixHQUFHQyxNQUFNLENBQUNDLElBQVAsQ0FBWWQsa0JBQVosRUFBZ0NlLE1BQWhDLENBQXVDLENBQUNDLElBQUQsRUFBT0MsR0FBUCxLQUFlO0FBQy9FLFFBQU1DLEdBQUcsR0FBR2xCLGtCQUFrQixDQUFDaUIsR0FBRCxDQUE5Qjs7QUFDQSxNQUFJSixNQUFNLENBQUNNLFNBQVAsQ0FBaUJDLGNBQWpCLENBQWdDQyxJQUFoQyxDQUFxQ0gsR0FBckMsRUFBMEMsU0FBMUMsQ0FBSixFQUEwRDtBQUN4REYsSUFBQUEsSUFBSSxDQUFDQyxHQUFELENBQUosR0FBWUMsR0FBRyxDQUFDSSxPQUFoQjtBQUNEOztBQUNELFNBQU9OLElBQVA7QUFDRCxDQU4wQixFQU14QixFQU53QixDQUEzQjtBQVFBLE1BQU1PLGdCQUFnQixHQUFHO0FBQ3ZCQyxFQUFBQSxRQUFRLEVBQUVwQixPQUFPLENBQUNDLEdBQVIsQ0FBWW9CLFNBQVosSUFBeUIsS0FEWjtBQUV2QnZCLEVBQUFBLFVBRnVCO0FBR3ZCTSxFQUFBQSxPQUh1QjtBQUl2QkMsRUFBQUE7QUFKdUIsQ0FBekI7O2VBT2VJLE1BQU0sQ0FBQ2EsTUFBUCxDQUFjLEVBQWQsRUFBa0JkLGtCQUFsQixFQUFzQ1csZ0JBQXRDLEM7OztBQUNSLE1BQU1JLGVBQWUsR0FBR2Ysa0JBQWtCLENBQUNnQixXQUEzQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IG51bGxQYXJzZXIgfSBmcm9tICcuL09wdGlvbnMvcGFyc2Vycyc7XG5jb25zdCB7IFBhcnNlU2VydmVyT3B0aW9ucyB9ID0gcmVxdWlyZSgnLi9PcHRpb25zL0RlZmluaXRpb25zJyk7XG5jb25zdCBsb2dzRm9sZGVyID0gKCgpID0+IHtcbiAgbGV0IGZvbGRlciA9ICcuL2xvZ3MvJztcbiAgaWYgKHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLmVudi5URVNUSU5HID09PSAnMScpIHtcbiAgICBmb2xkZXIgPSAnLi90ZXN0X2xvZ3MvJztcbiAgfVxuICBpZiAocHJvY2Vzcy5lbnYuUEFSU0VfU0VSVkVSX0xPR1NfRk9MREVSKSB7XG4gICAgZm9sZGVyID0gbnVsbFBhcnNlcihwcm9jZXNzLmVudi5QQVJTRV9TRVJWRVJfTE9HU19GT0xERVIpO1xuICB9XG4gIHJldHVybiBmb2xkZXI7XG59KSgpO1xuXG5jb25zdCB7IHZlcmJvc2UsIGxldmVsIH0gPSAoKCkgPT4ge1xuICBjb25zdCB2ZXJib3NlID0gcHJvY2Vzcy5lbnYuVkVSQk9TRSA/IHRydWUgOiBmYWxzZTtcbiAgcmV0dXJuIHsgdmVyYm9zZSwgbGV2ZWw6IHZlcmJvc2UgPyAndmVyYm9zZScgOiB1bmRlZmluZWQgfTtcbn0pKCk7XG5cbmNvbnN0IERlZmluaXRpb25EZWZhdWx0cyA9IE9iamVjdC5rZXlzKFBhcnNlU2VydmVyT3B0aW9ucykucmVkdWNlKChtZW1vLCBrZXkpID0+IHtcbiAgY29uc3QgZGVmID0gUGFyc2VTZXJ2ZXJPcHRpb25zW2tleV07XG4gIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZGVmLCAnZGVmYXVsdCcpKSB7XG4gICAgbWVtb1trZXldID0gZGVmLmRlZmF1bHQ7XG4gIH1cbiAgcmV0dXJuIG1lbW87XG59LCB7fSk7XG5cbmNvbnN0IGNvbXB1dGVkRGVmYXVsdHMgPSB7XG4gIGpzb25Mb2dzOiBwcm9jZXNzLmVudi5KU09OX0xPR1MgfHwgZmFsc2UsXG4gIGxvZ3NGb2xkZXIsXG4gIHZlcmJvc2UsXG4gIGxldmVsLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgT2JqZWN0LmFzc2lnbih7fSwgRGVmaW5pdGlvbkRlZmF1bHRzLCBjb21wdXRlZERlZmF1bHRzKTtcbmV4cG9ydCBjb25zdCBEZWZhdWx0TW9uZ29VUkkgPSBEZWZpbml0aW9uRGVmYXVsdHMuZGF0YWJhc2VVUkk7XG4iXX0= \ No newline at end of file diff --git a/lib/deprecated.js b/lib/deprecated.js deleted file mode 100644 index ea008a18d6..0000000000 --- a/lib/deprecated.js +++ /dev/null @@ -1,13 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.useExternal = useExternal; - -function useExternal(name, moduleName) { - return function () { - throw `${name} is not provided by parse-server anymore; please install ${moduleName}`; - }; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9kZXByZWNhdGVkLmpzIl0sIm5hbWVzIjpbInVzZUV4dGVybmFsIiwibmFtZSIsIm1vZHVsZU5hbWUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBTyxTQUFTQSxXQUFULENBQXFCQyxJQUFyQixFQUEyQkMsVUFBM0IsRUFBdUM7QUFDNUMsU0FBTyxZQUFZO0FBQ2pCLFVBQU8sR0FBRUQsSUFBSyw0REFBMkRDLFVBQVcsRUFBcEY7QUFDRCxHQUZEO0FBR0QiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZnVuY3Rpb24gdXNlRXh0ZXJuYWwobmFtZSwgbW9kdWxlTmFtZSkge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHRocm93IGAke25hbWV9IGlzIG5vdCBwcm92aWRlZCBieSBwYXJzZS1zZXJ2ZXIgYW55bW9yZTsgcGxlYXNlIGluc3RhbGwgJHttb2R1bGVOYW1lfWA7XG4gIH07XG59XG4iXX0= \ No newline at end of file diff --git a/lib/index.js b/lib/index.js deleted file mode 100644 index e34f529164..0000000000 --- a/lib/index.js +++ /dev/null @@ -1,107 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "S3Adapter", { - enumerable: true, - get: function () { - return _s3FilesAdapter.default; - } -}); -Object.defineProperty(exports, "FileSystemAdapter", { - enumerable: true, - get: function () { - return _fsFilesAdapter.default; - } -}); -Object.defineProperty(exports, "InMemoryCacheAdapter", { - enumerable: true, - get: function () { - return _InMemoryCacheAdapter.default; - } -}); -Object.defineProperty(exports, "NullCacheAdapter", { - enumerable: true, - get: function () { - return _NullCacheAdapter.default; - } -}); -Object.defineProperty(exports, "RedisCacheAdapter", { - enumerable: true, - get: function () { - return _RedisCacheAdapter.default; - } -}); -Object.defineProperty(exports, "LRUCacheAdapter", { - enumerable: true, - get: function () { - return _LRUCache.default; - } -}); -Object.defineProperty(exports, "PushWorker", { - enumerable: true, - get: function () { - return _PushWorker.PushWorker; - } -}); -Object.defineProperty(exports, "ParseGraphQLServer", { - enumerable: true, - get: function () { - return _ParseGraphQLServer.ParseGraphQLServer; - } -}); -exports.TestUtils = exports.ParseServer = exports.GCSAdapter = exports.default = void 0; - -var _ParseServer2 = _interopRequireDefault(require("./ParseServer")); - -var _s3FilesAdapter = _interopRequireDefault(require("@parse/s3-files-adapter")); - -var _fsFilesAdapter = _interopRequireDefault(require("@parse/fs-files-adapter")); - -var _InMemoryCacheAdapter = _interopRequireDefault(require("./Adapters/Cache/InMemoryCacheAdapter")); - -var _NullCacheAdapter = _interopRequireDefault(require("./Adapters/Cache/NullCacheAdapter")); - -var _RedisCacheAdapter = _interopRequireDefault(require("./Adapters/Cache/RedisCacheAdapter")); - -var _LRUCache = _interopRequireDefault(require("./Adapters/Cache/LRUCache.js")); - -var TestUtils = _interopRequireWildcard(require("./TestUtils")); - -exports.TestUtils = TestUtils; - -var _deprecated = require("./deprecated"); - -var _logger = require("./logger"); - -var _PushWorker = require("./Push/PushWorker"); - -var _Options = require("./Options"); - -var _ParseGraphQLServer = require("./GraphQL/ParseGraphQLServer"); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// Factory function -const _ParseServer = function (options) { - const server = new _ParseServer2.default(options); - return server.app; -}; // Mount the create liveQueryServer - - -exports.ParseServer = _ParseServer; -_ParseServer.createLiveQueryServer = _ParseServer2.default.createLiveQueryServer; -_ParseServer.start = _ParseServer2.default.start; -const GCSAdapter = (0, _deprecated.useExternal)('GCSAdapter', '@parse/gcs-files-adapter'); -exports.GCSAdapter = GCSAdapter; -Object.defineProperty(module.exports, 'logger', { - get: _logger.getLogger -}); -var _default = _ParseServer2.default; -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC5qcyJdLCJuYW1lcyI6WyJfUGFyc2VTZXJ2ZXIiLCJvcHRpb25zIiwic2VydmVyIiwiUGFyc2VTZXJ2ZXIiLCJhcHAiLCJjcmVhdGVMaXZlUXVlcnlTZXJ2ZXIiLCJzdGFydCIsIkdDU0FkYXB0ZXIiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsIm1vZHVsZSIsImV4cG9ydHMiLCJnZXQiLCJnZXRMb2dnZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7OztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7Ozs7OztBQUVBO0FBQ0EsTUFBTUEsWUFBWSxHQUFHLFVBQVVDLE9BQVYsRUFBdUM7QUFDMUQsUUFBTUMsTUFBTSxHQUFHLElBQUlDLHFCQUFKLENBQWdCRixPQUFoQixDQUFmO0FBQ0EsU0FBT0MsTUFBTSxDQUFDRSxHQUFkO0FBQ0QsQ0FIRCxDLENBSUE7Ozs7QUFDQUosWUFBWSxDQUFDSyxxQkFBYixHQUFxQ0Ysc0JBQVlFLHFCQUFqRDtBQUNBTCxZQUFZLENBQUNNLEtBQWIsR0FBcUJILHNCQUFZRyxLQUFqQztBQUVBLE1BQU1DLFVBQVUsR0FBRyw2QkFBWSxZQUFaLEVBQTBCLDBCQUExQixDQUFuQjs7QUFFQUMsTUFBTSxDQUFDQyxjQUFQLENBQXNCQyxNQUFNLENBQUNDLE9BQTdCLEVBQXNDLFFBQXRDLEVBQWdEO0FBQzlDQyxFQUFBQSxHQUFHLEVBQUVDO0FBRHlDLENBQWhEO2VBSWVWLHFCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFBhcnNlU2VydmVyIGZyb20gJy4vUGFyc2VTZXJ2ZXInO1xuaW1wb3J0IFMzQWRhcHRlciBmcm9tICdAcGFyc2UvczMtZmlsZXMtYWRhcHRlcic7XG5pbXBvcnQgRmlsZVN5c3RlbUFkYXB0ZXIgZnJvbSAnQHBhcnNlL2ZzLWZpbGVzLWFkYXB0ZXInO1xuaW1wb3J0IEluTWVtb3J5Q2FjaGVBZGFwdGVyIGZyb20gJy4vQWRhcHRlcnMvQ2FjaGUvSW5NZW1vcnlDYWNoZUFkYXB0ZXInO1xuaW1wb3J0IE51bGxDYWNoZUFkYXB0ZXIgZnJvbSAnLi9BZGFwdGVycy9DYWNoZS9OdWxsQ2FjaGVBZGFwdGVyJztcbmltcG9ydCBSZWRpc0NhY2hlQWRhcHRlciBmcm9tICcuL0FkYXB0ZXJzL0NhY2hlL1JlZGlzQ2FjaGVBZGFwdGVyJztcbmltcG9ydCBMUlVDYWNoZUFkYXB0ZXIgZnJvbSAnLi9BZGFwdGVycy9DYWNoZS9MUlVDYWNoZS5qcyc7XG5pbXBvcnQgKiBhcyBUZXN0VXRpbHMgZnJvbSAnLi9UZXN0VXRpbHMnO1xuaW1wb3J0IHsgdXNlRXh0ZXJuYWwgfSBmcm9tICcuL2RlcHJlY2F0ZWQnO1xuaW1wb3J0IHsgZ2V0TG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXInO1xuaW1wb3J0IHsgUHVzaFdvcmtlciB9IGZyb20gJy4vUHVzaC9QdXNoV29ya2VyJztcbmltcG9ydCB7IFBhcnNlU2VydmVyT3B0aW9ucyB9IGZyb20gJy4vT3B0aW9ucyc7XG5pbXBvcnQgeyBQYXJzZUdyYXBoUUxTZXJ2ZXIgfSBmcm9tICcuL0dyYXBoUUwvUGFyc2VHcmFwaFFMU2VydmVyJztcblxuLy8gRmFjdG9yeSBmdW5jdGlvblxuY29uc3QgX1BhcnNlU2VydmVyID0gZnVuY3Rpb24gKG9wdGlvbnM6IFBhcnNlU2VydmVyT3B0aW9ucykge1xuICBjb25zdCBzZXJ2ZXIgPSBuZXcgUGFyc2VTZXJ2ZXIob3B0aW9ucyk7XG4gIHJldHVybiBzZXJ2ZXIuYXBwO1xufTtcbi8vIE1vdW50IHRoZSBjcmVhdGUgbGl2ZVF1ZXJ5U2VydmVyXG5fUGFyc2VTZXJ2ZXIuY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyID0gUGFyc2VTZXJ2ZXIuY3JlYXRlTGl2ZVF1ZXJ5U2VydmVyO1xuX1BhcnNlU2VydmVyLnN0YXJ0ID0gUGFyc2VTZXJ2ZXIuc3RhcnQ7XG5cbmNvbnN0IEdDU0FkYXB0ZXIgPSB1c2VFeHRlcm5hbCgnR0NTQWRhcHRlcicsICdAcGFyc2UvZ2NzLWZpbGVzLWFkYXB0ZXInKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnbG9nZ2VyJywge1xuICBnZXQ6IGdldExvZ2dlcixcbn0pO1xuXG5leHBvcnQgZGVmYXVsdCBQYXJzZVNlcnZlcjtcbmV4cG9ydCB7XG4gIFMzQWRhcHRlcixcbiAgR0NTQWRhcHRlcixcbiAgRmlsZVN5c3RlbUFkYXB0ZXIsXG4gIEluTWVtb3J5Q2FjaGVBZGFwdGVyLFxuICBOdWxsQ2FjaGVBZGFwdGVyLFxuICBSZWRpc0NhY2hlQWRhcHRlcixcbiAgTFJVQ2FjaGVBZGFwdGVyLFxuICBUZXN0VXRpbHMsXG4gIFB1c2hXb3JrZXIsXG4gIFBhcnNlR3JhcGhRTFNlcnZlcixcbiAgX1BhcnNlU2VydmVyIGFzIFBhcnNlU2VydmVyLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/logger.js b/lib/logger.js deleted file mode 100644 index bd58e6bce9..0000000000 --- a/lib/logger.js +++ /dev/null @@ -1,47 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.setLogger = setLogger; -exports.getLogger = getLogger; - -var _defaults = _interopRequireDefault(require("./defaults")); - -var _WinstonLoggerAdapter = require("./Adapters/Logger/WinstonLoggerAdapter"); - -var _LoggerController = require("./Controllers/LoggerController"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// Used for Separate Live Query Server -function defaultLogger() { - const options = { - logsFolder: _defaults.default.logsFolder, - jsonLogs: _defaults.default.jsonLogs, - verbose: _defaults.default.verbose, - silent: _defaults.default.silent - }; - const adapter = new _WinstonLoggerAdapter.WinstonLoggerAdapter(options); - return new _LoggerController.LoggerController(adapter, null, options); -} - -let logger = defaultLogger(); - -function setLogger(aLogger) { - logger = aLogger; -} - -function getLogger() { - return logger; -} // for: `import logger from './logger'` - - -Object.defineProperty(module.exports, 'default', { - get: getLogger -}); // for: `import { logger } from './logger'` - -Object.defineProperty(module.exports, 'logger', { - get: getLogger -}); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9sb2dnZXIuanMiXSwibmFtZXMiOlsiZGVmYXVsdExvZ2dlciIsIm9wdGlvbnMiLCJsb2dzRm9sZGVyIiwiZGVmYXVsdHMiLCJqc29uTG9ncyIsInZlcmJvc2UiLCJzaWxlbnQiLCJhZGFwdGVyIiwiV2luc3RvbkxvZ2dlckFkYXB0ZXIiLCJMb2dnZXJDb250cm9sbGVyIiwibG9nZ2VyIiwic2V0TG9nZ2VyIiwiYUxvZ2dlciIsImdldExvZ2dlciIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwibW9kdWxlIiwiZXhwb3J0cyIsImdldCJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFFQTtBQUNBLFNBQVNBLGFBQVQsR0FBeUI7QUFDdkIsUUFBTUMsT0FBTyxHQUFHO0FBQ2RDLElBQUFBLFVBQVUsRUFBRUMsa0JBQVNELFVBRFA7QUFFZEUsSUFBQUEsUUFBUSxFQUFFRCxrQkFBU0MsUUFGTDtBQUdkQyxJQUFBQSxPQUFPLEVBQUVGLGtCQUFTRSxPQUhKO0FBSWRDLElBQUFBLE1BQU0sRUFBRUgsa0JBQVNHO0FBSkgsR0FBaEI7QUFNQSxRQUFNQyxPQUFPLEdBQUcsSUFBSUMsMENBQUosQ0FBeUJQLE9BQXpCLENBQWhCO0FBQ0EsU0FBTyxJQUFJUSxrQ0FBSixDQUFxQkYsT0FBckIsRUFBOEIsSUFBOUIsRUFBb0NOLE9BQXBDLENBQVA7QUFDRDs7QUFFRCxJQUFJUyxNQUFNLEdBQUdWLGFBQWEsRUFBMUI7O0FBRU8sU0FBU1csU0FBVCxDQUFtQkMsT0FBbkIsRUFBNEI7QUFDakNGLEVBQUFBLE1BQU0sR0FBR0UsT0FBVDtBQUNEOztBQUVNLFNBQVNDLFNBQVQsR0FBcUI7QUFDMUIsU0FBT0gsTUFBUDtBQUNELEMsQ0FFRDs7O0FBQ0FJLE1BQU0sQ0FBQ0MsY0FBUCxDQUFzQkMsTUFBTSxDQUFDQyxPQUE3QixFQUFzQyxTQUF0QyxFQUFpRDtBQUMvQ0MsRUFBQUEsR0FBRyxFQUFFTDtBQUQwQyxDQUFqRCxFLENBSUE7O0FBQ0FDLE1BQU0sQ0FBQ0MsY0FBUCxDQUFzQkMsTUFBTSxDQUFDQyxPQUE3QixFQUFzQyxRQUF0QyxFQUFnRDtBQUM5Q0MsRUFBQUEsR0FBRyxFQUFFTDtBQUR5QyxDQUFoRCIsInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcbmltcG9ydCBkZWZhdWx0cyBmcm9tICcuL2RlZmF1bHRzJztcbmltcG9ydCB7IFdpbnN0b25Mb2dnZXJBZGFwdGVyIH0gZnJvbSAnLi9BZGFwdGVycy9Mb2dnZXIvV2luc3RvbkxvZ2dlckFkYXB0ZXInO1xuaW1wb3J0IHsgTG9nZ2VyQ29udHJvbGxlciB9IGZyb20gJy4vQ29udHJvbGxlcnMvTG9nZ2VyQ29udHJvbGxlcic7XG5cbi8vIFVzZWQgZm9yIFNlcGFyYXRlIExpdmUgUXVlcnkgU2VydmVyXG5mdW5jdGlvbiBkZWZhdWx0TG9nZ2VyKCkge1xuICBjb25zdCBvcHRpb25zID0ge1xuICAgIGxvZ3NGb2xkZXI6IGRlZmF1bHRzLmxvZ3NGb2xkZXIsXG4gICAganNvbkxvZ3M6IGRlZmF1bHRzLmpzb25Mb2dzLFxuICAgIHZlcmJvc2U6IGRlZmF1bHRzLnZlcmJvc2UsXG4gICAgc2lsZW50OiBkZWZhdWx0cy5zaWxlbnQsXG4gIH07XG4gIGNvbnN0IGFkYXB0ZXIgPSBuZXcgV2luc3RvbkxvZ2dlckFkYXB0ZXIob3B0aW9ucyk7XG4gIHJldHVybiBuZXcgTG9nZ2VyQ29udHJvbGxlcihhZGFwdGVyLCBudWxsLCBvcHRpb25zKTtcbn1cblxubGV0IGxvZ2dlciA9IGRlZmF1bHRMb2dnZXIoKTtcblxuZXhwb3J0IGZ1bmN0aW9uIHNldExvZ2dlcihhTG9nZ2VyKSB7XG4gIGxvZ2dlciA9IGFMb2dnZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRMb2dnZXIoKSB7XG4gIHJldHVybiBsb2dnZXI7XG59XG5cbi8vIGZvcjogYGltcG9ydCBsb2dnZXIgZnJvbSAnLi9sb2dnZXInYFxuT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnZGVmYXVsdCcsIHtcbiAgZ2V0OiBnZXRMb2dnZXIsXG59KTtcblxuLy8gZm9yOiBgaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXInYFxuT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZHVsZS5leHBvcnRzLCAnbG9nZ2VyJywge1xuICBnZXQ6IGdldExvZ2dlcixcbn0pO1xuIl19 \ No newline at end of file diff --git a/lib/middlewares.js b/lib/middlewares.js deleted file mode 100644 index ccaadd2ddc..0000000000 --- a/lib/middlewares.js +++ /dev/null @@ -1,492 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.handleParseHeaders = handleParseHeaders; -exports.allowCrossDomain = allowCrossDomain; -exports.allowMethodOverride = allowMethodOverride; -exports.handleParseErrors = handleParseErrors; -exports.enforceMasterKeyAccess = enforceMasterKeyAccess; -exports.promiseEnforceMasterKeyAccess = promiseEnforceMasterKeyAccess; -exports.promiseEnsureIdempotency = promiseEnsureIdempotency; -exports.DEFAULT_ALLOWED_HEADERS = void 0; - -var _cache = _interopRequireDefault(require("./cache")); - -var _node = _interopRequireDefault(require("parse/node")); - -var _Auth = _interopRequireDefault(require("./Auth")); - -var _Config = _interopRequireDefault(require("./Config")); - -var _ClientSDK = _interopRequireDefault(require("./ClientSDK")); - -var _logger = _interopRequireDefault(require("./logger")); - -var _rest = _interopRequireDefault(require("./rest")); - -var _MongoStorageAdapter = _interopRequireDefault(require("./Adapters/Storage/Mongo/MongoStorageAdapter")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const DEFAULT_ALLOWED_HEADERS = 'X-Parse-Master-Key, X-Parse-REST-API-Key, X-Parse-Javascript-Key, X-Parse-Application-Id, X-Parse-Client-Version, X-Parse-Session-Token, X-Requested-With, X-Parse-Revocable-Session, X-Parse-Request-Id, Content-Type, Pragma, Cache-Control'; -exports.DEFAULT_ALLOWED_HEADERS = DEFAULT_ALLOWED_HEADERS; - -const getMountForRequest = function (req) { - const mountPathLength = req.originalUrl.length - req.url.length; - const mountPath = req.originalUrl.slice(0, mountPathLength); - return req.protocol + '://' + req.get('host') + mountPath; -}; // Checks that the request is authorized for this app and checks user -// auth too. -// The bodyparser should run before this middleware. -// Adds info to the request: -// req.config - the Config for this app -// req.auth - the Auth for this request - - -function handleParseHeaders(req, res, next) { - var mount = getMountForRequest(req); - var info = { - appId: req.get('X-Parse-Application-Id'), - sessionToken: req.get('X-Parse-Session-Token'), - masterKey: req.get('X-Parse-Master-Key'), - installationId: req.get('X-Parse-Installation-Id'), - clientKey: req.get('X-Parse-Client-Key'), - javascriptKey: req.get('X-Parse-Javascript-Key'), - dotNetKey: req.get('X-Parse-Windows-Key'), - restAPIKey: req.get('X-Parse-REST-API-Key'), - clientVersion: req.get('X-Parse-Client-Version'), - context: {} - }; - var basicAuth = httpAuth(req); - - if (basicAuth) { - var basicAuthAppId = basicAuth.appId; - - if (_cache.default.get(basicAuthAppId)) { - info.appId = basicAuthAppId; - info.masterKey = basicAuth.masterKey || info.masterKey; - info.javascriptKey = basicAuth.javascriptKey || info.javascriptKey; - } - } - - if (req.body) { - // Unity SDK sends a _noBody key which needs to be removed. - // Unclear at this point if action needs to be taken. - delete req.body._noBody; - } - - var fileViaJSON = false; - - if (!info.appId || !_cache.default.get(info.appId)) { - // See if we can find the app id on the body. - if (req.body instanceof Buffer) { - // The only chance to find the app id is if this is a file - // upload that actually is a JSON body. So try to parse it. - // https://github.com/parse-community/parse-server/issues/6589 - // It is also possible that the client is trying to upload a file but forgot - // to provide x-parse-app-id in header and parse a binary file will fail - try { - req.body = JSON.parse(req.body); - } catch (e) { - return invalidRequest(req, res); - } - - fileViaJSON = true; - } - - if (req.body) { - delete req.body._RevocableSession; - } - - if (req.body && req.body._ApplicationId && _cache.default.get(req.body._ApplicationId) && (!info.masterKey || _cache.default.get(req.body._ApplicationId).masterKey === info.masterKey)) { - info.appId = req.body._ApplicationId; - info.javascriptKey = req.body._JavaScriptKey || ''; - delete req.body._ApplicationId; - delete req.body._JavaScriptKey; // TODO: test that the REST API formats generated by the other - // SDKs are handled ok - - if (req.body._ClientVersion) { - info.clientVersion = req.body._ClientVersion; - delete req.body._ClientVersion; - } - - if (req.body._InstallationId) { - info.installationId = req.body._InstallationId; - delete req.body._InstallationId; - } - - if (req.body._SessionToken) { - info.sessionToken = req.body._SessionToken; - delete req.body._SessionToken; - } - - if (req.body._MasterKey) { - info.masterKey = req.body._MasterKey; - delete req.body._MasterKey; - } - - if (req.body._context && req.body._context instanceof Object) { - info.context = req.body._context; - delete req.body._context; - } - - if (req.body._ContentType) { - req.headers['content-type'] = req.body._ContentType; - delete req.body._ContentType; - } - } else { - return invalidRequest(req, res); - } - } - - if (info.sessionToken && typeof info.sessionToken !== 'string') { - info.sessionToken = info.sessionToken.toString(); - } - - if (info.clientVersion) { - info.clientSDK = _ClientSDK.default.fromString(info.clientVersion); - } - - if (fileViaJSON) { - req.fileData = req.body.fileData; // We need to repopulate req.body with a buffer - - var base64 = req.body.base64; - req.body = Buffer.from(base64, 'base64'); - } - - const clientIp = getClientIp(req); - info.app = _cache.default.get(info.appId); - req.config = _Config.default.get(info.appId, mount); - req.config.headers = req.headers || {}; - req.config.ip = clientIp; - req.info = info; - - if (info.masterKey && req.config.masterKeyIps && req.config.masterKeyIps.length !== 0 && req.config.masterKeyIps.indexOf(clientIp) === -1) { - return invalidRequest(req, res); - } - - var isMaster = info.masterKey === req.config.masterKey; - - if (isMaster) { - req.auth = new _Auth.default.Auth({ - config: req.config, - installationId: info.installationId, - isMaster: true - }); - next(); - return; - } - - var isReadOnlyMaster = info.masterKey === req.config.readOnlyMasterKey; - - if (typeof req.config.readOnlyMasterKey != 'undefined' && req.config.readOnlyMasterKey && isReadOnlyMaster) { - req.auth = new _Auth.default.Auth({ - config: req.config, - installationId: info.installationId, - isMaster: true, - isReadOnly: true - }); - next(); - return; - } // Client keys are not required in parse-server, but if any have been configured in the server, validate them - // to preserve original behavior. - - - const keys = ['clientKey', 'javascriptKey', 'dotNetKey', 'restAPIKey']; - const oneKeyConfigured = keys.some(function (key) { - return req.config[key] !== undefined; - }); - const oneKeyMatches = keys.some(function (key) { - return req.config[key] !== undefined && info[key] === req.config[key]; - }); - - if (oneKeyConfigured && !oneKeyMatches) { - return invalidRequest(req, res); - } - - if (req.url == '/login') { - delete info.sessionToken; - } - - if (req.userFromJWT) { - req.auth = new _Auth.default.Auth({ - config: req.config, - installationId: info.installationId, - isMaster: false, - user: req.userFromJWT - }); - next(); - return; - } - - if (!info.sessionToken) { - req.auth = new _Auth.default.Auth({ - config: req.config, - installationId: info.installationId, - isMaster: false - }); - next(); - return; - } - - return Promise.resolve().then(() => { - // handle the upgradeToRevocableSession path on it's own - if (info.sessionToken && req.url === '/upgradeToRevocableSession' && info.sessionToken.indexOf('r:') != 0) { - return _Auth.default.getAuthForLegacySessionToken({ - config: req.config, - installationId: info.installationId, - sessionToken: info.sessionToken - }); - } else { - return _Auth.default.getAuthForSessionToken({ - config: req.config, - installationId: info.installationId, - sessionToken: info.sessionToken - }); - } - }).then(auth => { - if (auth) { - req.auth = auth; - next(); - } - }).catch(error => { - if (error instanceof _node.default.Error) { - next(error); - return; - } else { - // TODO: Determine the correct error scenario. - req.config.loggerController.error('error getting auth for sessionToken', error); - throw new _node.default.Error(_node.default.Error.UNKNOWN_ERROR, error); - } - }); -} - -function getClientIp(req) { - if (req.headers['x-forwarded-for']) { - // try to get from x-forwared-for if it set (behind reverse proxy) - return req.headers['x-forwarded-for'].split(',')[0]; - } else if (req.connection && req.connection.remoteAddress) { - // no proxy, try getting from connection.remoteAddress - return req.connection.remoteAddress; - } else if (req.socket) { - // try to get it from req.socket - return req.socket.remoteAddress; - } else if (req.connection && req.connection.socket) { - // try to get it form the connection.socket - return req.connection.socket.remoteAddress; - } else { - // if non above, fallback. - return req.ip; - } -} - -function httpAuth(req) { - if (!(req.req || req).headers.authorization) return; - var header = (req.req || req).headers.authorization; - var appId, masterKey, javascriptKey; // parse header - - var authPrefix = 'basic '; - var match = header.toLowerCase().indexOf(authPrefix); - - if (match == 0) { - var encodedAuth = header.substring(authPrefix.length, header.length); - var credentials = decodeBase64(encodedAuth).split(':'); - - if (credentials.length == 2) { - appId = credentials[0]; - var key = credentials[1]; - var jsKeyPrefix = 'javascript-key='; - var matchKey = key.indexOf(jsKeyPrefix); - - if (matchKey == 0) { - javascriptKey = key.substring(jsKeyPrefix.length, key.length); - } else { - masterKey = key; - } - } - } - - return { - appId: appId, - masterKey: masterKey, - javascriptKey: javascriptKey - }; -} - -function decodeBase64(str) { - return Buffer.from(str, 'base64').toString(); -} - -function allowCrossDomain(appId) { - return (req, res, next) => { - const config = _Config.default.get(appId, getMountForRequest(req)); - - let allowHeaders = DEFAULT_ALLOWED_HEADERS; - - if (config && config.allowHeaders) { - allowHeaders += `, ${config.allowHeaders.join(', ')}`; - } - - const allowOrigin = config && config.allowOrigin || '*'; - res.header('Access-Control-Allow-Origin', allowOrigin); - res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS'); - res.header('Access-Control-Allow-Headers', allowHeaders); - res.header('Access-Control-Expose-Headers', 'X-Parse-Job-Status-Id, X-Parse-Push-Status-Id'); // intercept OPTIONS method - - if ('OPTIONS' == req.method) { - res.sendStatus(200); - } else { - next(); - } - }; -} - -function allowMethodOverride(req, res, next) { - if (req.method === 'POST' && req.body._method) { - req.originalMethod = req.method; - req.method = req.body._method; - delete req.body._method; - } - - next(); -} - -function handleParseErrors(err, req, res, next) { - const log = req.config && req.config.loggerController || _logger.default; - - if (err instanceof _node.default.Error) { - if (req.config && req.config.enableExpressErrorHandler) { - return next(err); - } - - let httpStatus; // TODO: fill out this mapping - - switch (err.code) { - case _node.default.Error.INTERNAL_SERVER_ERROR: - httpStatus = 500; - break; - - case _node.default.Error.OBJECT_NOT_FOUND: - httpStatus = 404; - break; - - default: - httpStatus = 400; - } - - res.status(httpStatus); - res.json({ - code: err.code, - error: err.message - }); - log.error('Parse error: ', err); - } else if (err.status && err.message) { - res.status(err.status); - res.json({ - error: err.message - }); - - if (!(process && process.env.TESTING)) { - next(err); - } - } else { - log.error('Uncaught internal server error.', err, err.stack); - res.status(500); - res.json({ - code: _node.default.Error.INTERNAL_SERVER_ERROR, - message: 'Internal server error.' - }); - - if (!(process && process.env.TESTING)) { - next(err); - } - } -} - -function enforceMasterKeyAccess(req, res, next) { - if (!req.auth.isMaster) { - res.status(403); - res.end('{"error":"unauthorized: master key is required"}'); - return; - } - - next(); -} - -function promiseEnforceMasterKeyAccess(request) { - if (!request.auth.isMaster) { - const error = new Error(); - error.status = 403; - error.message = 'unauthorized: master key is required'; - throw error; - } - - return Promise.resolve(); -} -/** - * Deduplicates a request to ensure idempotency. Duplicates are determined by the request ID - * in the request header. If a request has no request ID, it is executed anyway. - * @param {*} req The request to evaluate. - * @returns Promise<{}> - */ - - -function promiseEnsureIdempotency(req) { - // Enable feature only for MongoDB - if (!(req.config.database.adapter instanceof _MongoStorageAdapter.default)) { - return Promise.resolve(); - } // Get parameters - - - const config = req.config; - const requestId = ((req || {}).headers || {})['x-parse-request-id']; - const { - paths, - ttl - } = config.idempotencyOptions; - - if (!requestId || !config.idempotencyOptions) { - return Promise.resolve(); - } // Request path may contain trailing slashes, depending on the original request, so remove - // leading and trailing slashes to make it easier to specify paths in the configuration - - - const reqPath = req.path.replace(/^\/|\/$/, ''); // Determine whether idempotency is enabled for current request path - - let match = false; - - for (const path of paths) { - // Assume one wants a path to always match from the beginning to prevent any mistakes - const regex = new RegExp(path.charAt(0) === '^' ? path : '^' + path); - - if (reqPath.match(regex)) { - match = true; - break; - } - } - - if (!match) { - return Promise.resolve(); - } // Try to store request - - - const expiryDate = new Date(new Date().setSeconds(new Date().getSeconds() + ttl)); - return _rest.default.create(config, _Auth.default.master(config), '_Idempotency', { - reqId: requestId, - expire: _node.default._encode(expiryDate) - }).catch(e => { - if (e.code == _node.default.Error.DUPLICATE_VALUE) { - throw new _node.default.Error(_node.default.Error.DUPLICATE_REQUEST, 'Duplicate request'); - } - - throw e; - }); -} - -function invalidRequest(req, res) { - res.status(403); - res.end('{"error":"unauthorized"}'); -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9taWRkbGV3YXJlcy5qcyJdLCJuYW1lcyI6WyJERUZBVUxUX0FMTE9XRURfSEVBREVSUyIsImdldE1vdW50Rm9yUmVxdWVzdCIsInJlcSIsIm1vdW50UGF0aExlbmd0aCIsIm9yaWdpbmFsVXJsIiwibGVuZ3RoIiwidXJsIiwibW91bnRQYXRoIiwic2xpY2UiLCJwcm90b2NvbCIsImdldCIsImhhbmRsZVBhcnNlSGVhZGVycyIsInJlcyIsIm5leHQiLCJtb3VudCIsImluZm8iLCJhcHBJZCIsInNlc3Npb25Ub2tlbiIsIm1hc3RlcktleSIsImluc3RhbGxhdGlvbklkIiwiY2xpZW50S2V5IiwiamF2YXNjcmlwdEtleSIsImRvdE5ldEtleSIsInJlc3RBUElLZXkiLCJjbGllbnRWZXJzaW9uIiwiY29udGV4dCIsImJhc2ljQXV0aCIsImh0dHBBdXRoIiwiYmFzaWNBdXRoQXBwSWQiLCJBcHBDYWNoZSIsImJvZHkiLCJfbm9Cb2R5IiwiZmlsZVZpYUpTT04iLCJCdWZmZXIiLCJKU09OIiwicGFyc2UiLCJlIiwiaW52YWxpZFJlcXVlc3QiLCJfUmV2b2NhYmxlU2Vzc2lvbiIsIl9BcHBsaWNhdGlvbklkIiwiX0phdmFTY3JpcHRLZXkiLCJfQ2xpZW50VmVyc2lvbiIsIl9JbnN0YWxsYXRpb25JZCIsIl9TZXNzaW9uVG9rZW4iLCJfTWFzdGVyS2V5IiwiX2NvbnRleHQiLCJPYmplY3QiLCJfQ29udGVudFR5cGUiLCJoZWFkZXJzIiwidG9TdHJpbmciLCJjbGllbnRTREsiLCJDbGllbnRTREsiLCJmcm9tU3RyaW5nIiwiZmlsZURhdGEiLCJiYXNlNjQiLCJmcm9tIiwiY2xpZW50SXAiLCJnZXRDbGllbnRJcCIsImFwcCIsImNvbmZpZyIsIkNvbmZpZyIsImlwIiwibWFzdGVyS2V5SXBzIiwiaW5kZXhPZiIsImlzTWFzdGVyIiwiYXV0aCIsIkF1dGgiLCJpc1JlYWRPbmx5TWFzdGVyIiwicmVhZE9ubHlNYXN0ZXJLZXkiLCJpc1JlYWRPbmx5Iiwia2V5cyIsIm9uZUtleUNvbmZpZ3VyZWQiLCJzb21lIiwia2V5IiwidW5kZWZpbmVkIiwib25lS2V5TWF0Y2hlcyIsInVzZXJGcm9tSldUIiwidXNlciIsIlByb21pc2UiLCJyZXNvbHZlIiwidGhlbiIsImdldEF1dGhGb3JMZWdhY3lTZXNzaW9uVG9rZW4iLCJnZXRBdXRoRm9yU2Vzc2lvblRva2VuIiwiY2F0Y2giLCJlcnJvciIsIlBhcnNlIiwiRXJyb3IiLCJsb2dnZXJDb250cm9sbGVyIiwiVU5LTk9XTl9FUlJPUiIsInNwbGl0IiwiY29ubmVjdGlvbiIsInJlbW90ZUFkZHJlc3MiLCJzb2NrZXQiLCJhdXRob3JpemF0aW9uIiwiaGVhZGVyIiwiYXV0aFByZWZpeCIsIm1hdGNoIiwidG9Mb3dlckNhc2UiLCJlbmNvZGVkQXV0aCIsInN1YnN0cmluZyIsImNyZWRlbnRpYWxzIiwiZGVjb2RlQmFzZTY0IiwianNLZXlQcmVmaXgiLCJtYXRjaEtleSIsInN0ciIsImFsbG93Q3Jvc3NEb21haW4iLCJhbGxvd0hlYWRlcnMiLCJqb2luIiwiYWxsb3dPcmlnaW4iLCJtZXRob2QiLCJzZW5kU3RhdHVzIiwiYWxsb3dNZXRob2RPdmVycmlkZSIsIl9tZXRob2QiLCJvcmlnaW5hbE1ldGhvZCIsImhhbmRsZVBhcnNlRXJyb3JzIiwiZXJyIiwibG9nIiwiZGVmYXVsdExvZ2dlciIsImVuYWJsZUV4cHJlc3NFcnJvckhhbmRsZXIiLCJodHRwU3RhdHVzIiwiY29kZSIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsIk9CSkVDVF9OT1RfRk9VTkQiLCJzdGF0dXMiLCJqc29uIiwibWVzc2FnZSIsInByb2Nlc3MiLCJlbnYiLCJURVNUSU5HIiwic3RhY2siLCJlbmZvcmNlTWFzdGVyS2V5QWNjZXNzIiwiZW5kIiwicHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MiLCJyZXF1ZXN0IiwicHJvbWlzZUVuc3VyZUlkZW1wb3RlbmN5IiwiZGF0YWJhc2UiLCJhZGFwdGVyIiwiTW9uZ29TdG9yYWdlQWRhcHRlciIsInJlcXVlc3RJZCIsInBhdGhzIiwidHRsIiwiaWRlbXBvdGVuY3lPcHRpb25zIiwicmVxUGF0aCIsInBhdGgiLCJyZXBsYWNlIiwicmVnZXgiLCJSZWdFeHAiLCJjaGFyQXQiLCJleHBpcnlEYXRlIiwiRGF0ZSIsInNldFNlY29uZHMiLCJnZXRTZWNvbmRzIiwicmVzdCIsImNyZWF0ZSIsIm1hc3RlciIsInJlcUlkIiwiZXhwaXJlIiwiX2VuY29kZSIsIkRVUExJQ0FURV9WQUxVRSIsIkRVUExJQ0FURV9SRVFVRVNUIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQUFBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOztBQUNBOzs7O0FBRU8sTUFBTUEsdUJBQXVCLEdBQ2xDLCtPQURLOzs7QUFHUCxNQUFNQyxrQkFBa0IsR0FBRyxVQUFVQyxHQUFWLEVBQWU7QUFDeEMsUUFBTUMsZUFBZSxHQUFHRCxHQUFHLENBQUNFLFdBQUosQ0FBZ0JDLE1BQWhCLEdBQXlCSCxHQUFHLENBQUNJLEdBQUosQ0FBUUQsTUFBekQ7QUFDQSxRQUFNRSxTQUFTLEdBQUdMLEdBQUcsQ0FBQ0UsV0FBSixDQUFnQkksS0FBaEIsQ0FBc0IsQ0FBdEIsRUFBeUJMLGVBQXpCLENBQWxCO0FBQ0EsU0FBT0QsR0FBRyxDQUFDTyxRQUFKLEdBQWUsS0FBZixHQUF1QlAsR0FBRyxDQUFDUSxHQUFKLENBQVEsTUFBUixDQUF2QixHQUF5Q0gsU0FBaEQ7QUFDRCxDQUpELEMsQ0FNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNPLFNBQVNJLGtCQUFULENBQTRCVCxHQUE1QixFQUFpQ1UsR0FBakMsRUFBc0NDLElBQXRDLEVBQTRDO0FBQ2pELE1BQUlDLEtBQUssR0FBR2Isa0JBQWtCLENBQUNDLEdBQUQsQ0FBOUI7QUFFQSxNQUFJYSxJQUFJLEdBQUc7QUFDVEMsSUFBQUEsS0FBSyxFQUFFZCxHQUFHLENBQUNRLEdBQUosQ0FBUSx3QkFBUixDQURFO0FBRVRPLElBQUFBLFlBQVksRUFBRWYsR0FBRyxDQUFDUSxH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QXBwQ2FjaGUgZnJvbSAnLi9jYWNoZSc7XG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgYXV0aCBmcm9tICcuL0F1dGgnO1xuaW1wb3J0IENvbmZpZyBmcm9tICcuL0NvbmZpZyc7XG5pbXBvcnQgQ2xpZW50U0RLIGZyb20gJy4vQ2xpZW50U0RLJztcbmltcG9ydCBkZWZhdWx0TG9nZ2VyIGZyb20gJy4vbG9nZ2VyJztcbmltcG9ydCByZXN0IGZyb20gJy4vcmVzdCc7XG5pbXBvcnQgTW9uZ29TdG9yYWdlQWRhcHRlciBmcm9tICcuL0FkYXB0ZXJzL1N0b3JhZ2UvTW9uZ28vTW9uZ29TdG9yYWdlQWRhcHRlcic7XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX0FMTE9XRURfSEVBREVSUyA9XG4gICdYLVBhcnNlLU1hc3Rlci1LZXksIFgtUGFyc2UtUkVTVC1BUEktS2V5LCBYLVBhcnNlLUphdmFzY3JpcHQtS2V5LCBYLVBhcnNlLUFwcGxpY2F0aW9uLUlkLCBYLVBhcnNlLUNsaWVudC1WZXJzaW9uLCBYLVBhcnNlLVNlc3Npb24tVG9rZW4sIFgtUmVxdWVzdGVkLVdpdGgsIFgtUGFyc2UtUmV2b2NhYmxlLVNlc3Npb24sIFgtUGFyc2UtUmVxdWVzdC1JZCwgQ29udGVudC1UeXBlLCBQcmFnbWEsIENhY2hlLUNvbnRyb2wnO1xuXG5jb25zdCBnZXRNb3VudEZvclJlcXVlc3QgPSBmdW5jdGlvbiAocmVxKSB7XG4gIGNvbnN0IG1vdW50UGF0aExlbmd0aCA9IHJlcS5vcmlnaW5hbFVybC5sZW5ndGggLSByZXEudXJsLmxlbmd0aDtcbiAgY29uc3QgbW91bnRQYXRoID0gcmVxLm9yaWdpbmFsVXJsLnNsaWNlKDAsIG1vdW50UGF0aExlbmd0aCk7XG4gIHJldHVybiByZXEucHJvdG9jb2wgKyAnOi8vJyArIHJlcS5nZXQoJ2hvc3QnKSArIG1vdW50UGF0aDtcbn07XG5cbi8vIENoZWNrcyB0aGF0IHRoZSByZXF1ZXN0IGlzIGF1dGhvcml6ZWQgZm9yIHRoaXMgYXBwIGFuZCBjaGVja3MgdXNlclxuLy8gYXV0aCB0b28uXG4vLyBUaGUgYm9keXBhcnNlciBzaG91bGQgcnVuIGJlZm9yZSB0aGlzIG1pZGRsZXdhcmUuXG4vLyBBZGRzIGluZm8gdG8gdGhlIHJlcXVlc3Q6XG4vLyByZXEuY29uZmlnIC0gdGhlIENvbmZpZyBmb3IgdGhpcyBhcHBcbi8vIHJlcS5hdXRoIC0gdGhlIEF1dGggZm9yIHRoaXMgcmVxdWVzdFxuZXhwb3J0IGZ1bmN0aW9uIGhhbmRsZVBhcnNlSGVhZGVycyhyZXEsIHJlcywgbmV4dCkge1xuICB2YXIgbW91bnQgPSBnZXRNb3VudEZvclJlcXVlc3QocmVxKTtcblxuICB2YXIgaW5mbyA9IHtcbiAgICBhcHBJZDogcmVxLmdldCgnWC1QYXJzZS1BcHBsaWNhdGlvbi1JZCcpLFxuICAgIHNlc3Npb25Ub2tlbjogcmVxLmdldCgnWC1QYXJzZS1TZXNzaW9uLVRva2VuJyksXG4gICAgbWFzdGVyS2V5OiByZXEuZ2V0KCdYLVBhcnNlLU1hc3Rlci1LZXknKSxcbiAgICBpbnN0YWxsYXRpb25JZDogcmVxLmdldCgnWC1QYXJzZS1JbnN0YWxsYXRpb24tSWQnKSxcbiAgICBjbGllbnRLZXk6IHJlcS5nZXQoJ1gtUGFyc2UtQ2xpZW50LUtleScpLFxuICAgIGphdmFzY3JpcHRLZXk6IHJlcS5nZXQoJ1gtUGFyc2UtSmF2YXNjcmlwdC1LZXknKSxcbiAgICBkb3ROZXRLZXk6IHJlcS5nZXQoJ1gtUGFyc2UtV2luZG93cy1LZXknKSxcbiAgICByZXN0QVBJS2V5OiByZXEuZ2V0KCdYLVBhcnNlLVJFU1QtQVBJLUtleScpLFxuICAgIGNsaWVudFZlcnNpb246IHJlcS5nZXQoJ1gtUGFyc2UtQ2xpZW50LVZlcnNpb24nKSxcbiAgICBjb250ZXh0OiB7fSxcbiAgfTtcblxuICB2YXIgYmFzaWNBdXRoID0gaHR0cEF1dGgocmVxKTtcblxuICBpZiAoYmFzaWNBdXRoKSB7XG4gICAgdmFyIGJhc2ljQXV0aEFwcElkID0gYmFzaWNBdXRoLmFwcElkO1xuICAgIGlmIChBcHBDYWNoZS5nZXQoYmFzaWNBdXRoQXBwSWQpKSB7XG4gICAgICBpbmZvLmFwcElkID0gYmFzaWNBdXRoQXBwSWQ7XG4gICAgICBpbmZvLm1hc3RlcktleSA9IGJhc2ljQXV0aC5tYXN0ZXJLZXkgfHwgaW5mby5tYXN0ZXJLZXk7XG4gICAgICBpbmZvLmphdmFzY3JpcHRLZXkgPSBiYXNpY0F1dGguamF2YXNjcmlwdEtleSB8fCBpbmZvLmphdmFzY3JpcHRLZXk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHJlcS5ib2R5KSB7XG4gICAgLy8gVW5pdHkgU0RLIHNlbmRzIGEgX25vQm9keSBrZXkgd2hpY2ggbmVlZHMgdG8gYmUgcmVtb3ZlZC5cbiAgICAvLyBVbmNsZWFyIGF0IHRoaXMgcG9pbnQgaWYgYWN0aW9uIG5lZWRzIHRvIGJlIHRha2VuLlxuICAgIGRlbGV0ZSByZXEuYm9keS5fbm9Cb2R5O1xuICB9XG5cbiAgdmFyIGZpbGVWaWFKU09OID0gZmFsc2U7XG5cbiAgaWYgKCFpbmZvLmFwcElkIHx8ICFBcHBDYWNoZS5nZXQoaW5mby5hcHBJZCkpIHtcbiAgICAvLyBTZWUgaWYgd2UgY2FuIGZpbmQgdGhlIGFwcCBpZCBvbiB0aGUgYm9keS5cbiAgICBpZiAocmVxLmJvZHkgaW5zdGFuY2VvZiBCdWZmZXIpIHtcbiAgICAgIC8vIFRoZSBvbmx5IGNoYW5jZSB0byBmaW5kIHRoZSBhcHAgaWQgaXMgaWYgdGhpcyBpcyBhIGZpbGVcbiAgICAgIC8vIHVwbG9hZCB0aGF0IGFjdHVhbGx5IGlzIGEgSlNPTiBib2R5LiBTbyB0cnkgdG8gcGFyc2UgaXQuXG4gICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vcGFyc2UtY29tbXVuaXR5L3BhcnNlLXNlcnZlci9pc3N1ZXMvNjU4OVxuICAgICAgLy8gSXQgaXMgYWxzbyBwb3NzaWJsZSB0aGF0IHRoZSBjbGllbnQgaXMgdHJ5aW5nIHRvIHVwbG9hZCBhIGZpbGUgYnV0IGZvcmdvdFxuICAgICAgLy8gdG8gcHJvdmlkZSB4LXBhcnNlLWFwcC1pZCBpbiBoZWFkZXIgYW5kIHBhcnNlIGEgYmluYXJ5IGZpbGUgd2lsbCBmYWlsXG4gICAgICB0cnkge1xuICAgICAgICByZXEuYm9keSA9IEpTT04ucGFyc2UocmVxLmJvZHkpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gaW52YWxpZFJlcXVlc3QocmVxLCByZXMpO1xuICAgICAgfVxuICAgICAgZmlsZVZpYUpTT04gPSB0cnVlO1xuICAgIH1cblxuICAgIGlmIChyZXEuYm9keSkge1xuICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9SZXZvY2FibGVTZXNzaW9uO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHJlcS5ib2R5ICYmXG4gICAgICByZXEuYm9keS5fQXBwbGljYXRpb25JZCAmJlxuICAgICAgQXBwQ2FjaGUuZ2V0KHJlcS5ib2R5Ll9BcHBsaWNhdGlvbklkKSAmJlxuICAgICAgKCFpbmZvLm1hc3RlcktleSB8fCBBcHBDYWNoZS5nZXQocmVxLmJvZHkuX0FwcGxpY2F0aW9uSWQpLm1hc3RlcktleSA9PT0gaW5mby5tYXN0ZXJLZXkpXG4gICAgKSB7XG4gICAgICBpbmZvLmFwcElkID0gcmVxLmJvZHkuX0FwcGxpY2F0aW9uSWQ7XG4gICAgICBpbmZvLmphdmFzY3JpcHRLZXkgPSByZXEuYm9keS5fSmF2YVNjcmlwdEtleSB8fCAnJztcbiAgICAgIGRlbGV0ZSByZXEuYm9keS5fQXBwbGljYXRpb25JZDtcbiAgICAgIGRlbGV0ZSByZXEuYm9keS5fSmF2YVNjcmlwdEtleTtcbiAgICAgIC8vIFRPRE86IHRlc3QgdGhhdCB0aGUgUkVTVCBBUEkgZm9ybWF0cyBnZW5lcmF0ZWQgYnkgdGhlIG90aGVyXG4gICAgICAvLyBTREtzIGFyZSBoYW5kbGVkIG9rXG4gICAgICBpZiAocmVxLmJvZHkuX0NsaWVudFZlcnNpb24pIHtcbiAgICAgICAgaW5mby5jbGllbnRWZXJzaW9uID0gcmVxLmJvZHkuX0NsaWVudFZlcnNpb247XG4gICAgICAgIGRlbGV0ZSByZXEuYm9keS5fQ2xpZW50VmVyc2lvbjtcbiAgICAgIH1cbiAgICAgIGlmIChyZXEuYm9keS5fSW5zdGFsbGF0aW9uSWQpIHtcbiAgICAgICAgaW5mby5pbnN0YWxsYXRpb25JZCA9IHJlcS5ib2R5Ll9JbnN0YWxsYXRpb25JZDtcbiAgICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9JbnN0YWxsYXRpb25JZDtcbiAgICAgIH1cbiAgICAgIGlmIChyZXEuYm9keS5fU2Vzc2lvblRva2VuKSB7XG4gICAgICAgIGluZm8uc2Vzc2lvblRva2VuID0gcmVxLmJvZHkuX1Nlc3Npb25Ub2tlbjtcbiAgICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9TZXNzaW9uVG9rZW47XG4gICAgICB9XG4gICAgICBpZiAocmVxLmJvZHkuX01hc3RlcktleSkge1xuICAgICAgICBpbmZvLm1hc3RlcktleSA9IHJlcS5ib2R5Ll9NYXN0ZXJLZXk7XG4gICAgICAgIGRlbGV0ZSByZXEuYm9keS5fTWFzdGVyS2V5O1xuICAgICAgfVxuICAgICAgaWYgKHJlcS5ib2R5Ll9jb250ZXh0ICYmIHJlcS5ib2R5Ll9jb250ZXh0IGluc3RhbmNlb2YgT2JqZWN0KSB7XG4gICAgICAgIGluZm8uY29udGV4dCA9IHJlcS5ib2R5Ll9jb250ZXh0O1xuICAgICAgICBkZWxldGUgcmVxLmJvZHkuX2NvbnRleHQ7XG4gICAgICB9XG4gICAgICBpZiAocmVxLmJvZHkuX0NvbnRlbnRUeXBlKSB7XG4gICAgICAgIHJlcS5oZWFkZXJzWydjb250ZW50LXR5cGUnXSA9IHJlcS5ib2R5Ll9Db250ZW50VHlwZTtcbiAgICAgICAgZGVsZXRlIHJlcS5ib2R5Ll9Db250ZW50VHlwZTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGludmFsaWRSZXF1ZXN0KHJlcSwgcmVzKTtcbiAgICB9XG4gIH1cblxuICBpZiAoaW5mby5zZXNzaW9uVG9rZW4gJiYgdHlwZW9mIGluZm8uc2Vzc2lvblRva2VuICE9PSAnc3RyaW5nJykge1xuICAgIGluZm8uc2Vzc2lvblRva2VuID0gaW5mby5zZXNzaW9uVG9rZW4udG9TdHJpbmcoKTtcbiAgfVxuXG4gIGlmIChpbmZvLmNsaWVudFZlcnNpb24pIHtcbiAgICBpbmZvLmNsaWVudFNESyA9IENsaWVudFNESy5mcm9tU3RyaW5nKGluZm8uY2xpZW50VmVyc2lvbik7XG4gIH1cblxuICBpZiAoZmlsZVZpYUpTT04pIHtcbiAgICByZXEuZmlsZURhdGEgPSByZXEuYm9keS5maWxlRGF0YTtcbiAgICAvLyBXZSBuZWVkIHRvIHJlcG9wdWxhdGUgcmVxLmJvZHkgd2l0aCBhIGJ1ZmZlclxuICAgIHZhciBiYXNlNjQgPSByZXEuYm9keS5iYXNlNjQ7XG4gICAgcmVxLmJvZHkgPSBCdWZmZXIuZnJvbShiYXNlNjQsICdiYXNlNjQnKTtcbiAgfVxuXG4gIGNvbnN0IGNsaWVudElwID0gZ2V0Q2xpZW50SXAocmVxKTtcblxuICBpbmZvLmFwcCA9IEFwcENhY2hlLmdldChpbmZvLmFwcElkKTtcbiAgcmVxLmNvbmZpZyA9IENvbmZpZy5nZXQoaW5mby5hcHBJZCwgbW91bnQpO1xuICByZXEuY29uZmlnLmhlYWRlcnMgPSByZXEuaGVhZGVycyB8fCB7fTtcbiAgcmVxLmNvbmZpZy5pcCA9IGNsaWVudElwO1xuICByZXEuaW5mbyA9IGluZm87XG5cbiAgaWYgKFxuICAgIGluZm8ubWFzdGVyS2V5ICYmXG4gICAgcmVxLmNvbmZpZy5tYXN0ZXJLZXlJcHMgJiZcbiAgICByZXEuY29uZmlnLm1hc3RlcktleUlwcy5sZW5ndGggIT09IDAgJiZcbiAgICByZXEuY29uZmlnLm1hc3RlcktleUlwcy5pbmRleE9mKGNsaWVudElwKSA9PT0gLTFcbiAgKSB7XG4gICAgcmV0dXJuIGludmFsaWRSZXF1ZXN0KHJlcSwgcmVzKTtcbiAgfVxuXG4gIHZhciBpc01hc3RlciA9IGluZm8ubWFzdGVyS2V5ID09PSByZXEuY29uZmlnLm1hc3RlcktleTtcblxuICBpZiAoaXNNYXN0ZXIpIHtcbiAgICByZXEuYXV0aCA9IG5ldyBhdXRoLkF1dGgoe1xuICAgICAgY29uZmlnOiByZXEuY29uZmlnLFxuICAgICAgaW5zdGFsbGF0aW9uSWQ6IGluZm8uaW5zdGFsbGF0aW9uSWQsXG4gICAgICBpc01hc3RlcjogdHJ1ZSxcbiAgICB9KTtcbiAgICBuZXh0KCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGlzUmVhZE9ubHlNYXN0ZXIgPSBpbmZvLm1hc3RlcktleSA9PT0gcmVxLmNvbmZpZy5yZWFkT25seU1hc3RlcktleTtcbiAgaWYgKFxuICAgIHR5cGVvZiByZXEuY29uZmlnLnJlYWRPbmx5TWFzdGVyS2V5ICE9ICd1bmRlZmluZWQnICYmXG4gICAgcmVxLmNvbmZpZy5yZWFkT25seU1hc3RlcktleSAmJlxuICAgIGlzUmVhZE9ubHlNYXN0ZXJcbiAgKSB7XG4gICAgcmVxLmF1dGggPSBuZXcgYXV0aC5BdXRoKHtcbiAgICAgIGNvbmZpZzogcmVxLmNvbmZpZyxcbiAgICAgIGluc3RhbGxhdGlvbklkOiBpbmZvLmluc3RhbGxhdGlvbklkLFxuICAgICAgaXNNYXN0ZXI6IHRydWUsXG4gICAgICBpc1JlYWRPbmx5OiB0cnVlLFxuICAgIH0pO1xuICAgIG5leHQoKTtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBDbGllbnQga2V5cyBhcmUgbm90IHJlcXVpcmVkIGluIHBhcnNlLXNlcnZlciwgYnV0IGlmIGFueSBoYXZlIGJlZW4gY29uZmlndXJlZCBpbiB0aGUgc2VydmVyLCB2YWxpZGF0ZSB0aGVtXG4gIC8vICB0byBwcmVzZXJ2ZSBvcmlnaW5hbCBiZWhhdmlvci5cbiAgY29uc3Qga2V5cyA9IFsnY2xpZW50S2V5JywgJ2phdmFzY3JpcHRLZXknLCAnZG90TmV0S2V5JywgJ3Jlc3RBUElLZXknXTtcbiAgY29uc3Qgb25lS2V5Q29uZmlndXJlZCA9IGtleXMuc29tZShmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIHJlcS5jb25maWdba2V5XSAhPT0gdW5kZWZpbmVkO1xuICB9KTtcbiAgY29uc3Qgb25lS2V5TWF0Y2hlcyA9IGtleXMuc29tZShmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIHJlcS5jb25maWdba2V5XSAhPT0gdW5kZWZpbmVkICYmIGluZm9ba2V5XSA9PT0gcmVxLmNvbmZpZ1trZXldO1xuICB9KTtcblxuICBpZiAob25lS2V5Q29uZmlndXJlZCAmJiAhb25lS2V5TWF0Y2hlcykge1xuICAgIHJldHVybiBpbnZhbGlkUmVxdWVzdChyZXEsIHJlcyk7XG4gIH1cblxuICBpZiAocmVxLnVybCA9PSAnL2xvZ2luJykge1xuICAgIGRlbGV0ZSBpbmZvLnNlc3Npb25Ub2tlbjtcbiAgfVxuXG4gIGlmIChyZXEudXNlckZyb21KV1QpIHtcbiAgICByZXEuYXV0aCA9IG5ldyBhdXRoLkF1dGgoe1xuICAgICAgY29uZmlnOiByZXEuY29uZmlnLFxuICAgICAgaW5zdGFsbGF0aW9uSWQ6IGluZm8uaW5zdGFsbGF0aW9uSWQsXG4gICAgICBpc01hc3RlcjogZmFsc2UsXG4gICAgICB1c2VyOiByZXEudXNlckZyb21KV1QsXG4gICAgfSk7XG4gICAgbmV4dCgpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICghaW5mby5zZXNzaW9uVG9rZW4pIHtcbiAgICByZXEuYXV0aCA9IG5ldyBhdXRoLkF1dGgoe1xuICAgICAgY29uZmlnOiByZXEuY29uZmlnLFxuICAgICAgaW5zdGFsbGF0aW9uSWQ6IGluZm8uaW5zdGFsbGF0aW9uSWQsXG4gICAgICBpc01hc3RlcjogZmFsc2UsXG4gICAgfSk7XG4gICAgbmV4dCgpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIC8vIGhhbmRsZSB0aGUgdXBncmFkZVRvUmV2b2NhYmxlU2Vzc2lvbiBwYXRoIG9uIGl0J3Mgb3duXG4gICAgICBpZiAoXG4gICAgICAgIGluZm8uc2Vzc2lvblRva2VuICYmXG4gICAgICAgIHJlcS51cmwgPT09ICcvdXBncmFkZVRvUmV2b2NhYmxlU2Vzc2lvbicgJiZcbiAgICAgICAgaW5mby5zZXNzaW9uVG9rZW4uaW5kZXhPZigncjonKSAhPSAwXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIGF1dGguZ2V0QXV0aEZvckxlZ2FjeVNlc3Npb25Ub2tlbih7XG4gICAgICAgICAgY29uZmlnOiByZXEuY29uZmlnLFxuICAgICAgICAgIGluc3RhbGxhdGlvbklkOiBpbmZvLmluc3RhbGxhdGlvbklkLFxuICAgICAgICAgIHNlc3Npb25Ub2tlbjogaW5mby5zZXNzaW9uVG9rZW4sXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGF1dGguZ2V0QXV0aEZvclNlc3Npb25Ub2tlbih7XG4gICAgICAgICAgY29uZmlnOiByZXEuY29uZmlnLFxuICAgICAgICAgIGluc3RhbGxhdGlvbklkOiBpbmZvLmluc3RhbGxhdGlvbklkLFxuICAgICAgICAgIHNlc3Npb25Ub2tlbjogaW5mby5zZXNzaW9uVG9rZW4sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pXG4gICAgLnRoZW4oYXV0aCA9PiB7XG4gICAgICBpZiAoYXV0aCkge1xuICAgICAgICByZXEuYXV0aCA9IGF1dGg7XG4gICAgICAgIG5leHQoKTtcbiAgICAgIH1cbiAgICB9KVxuICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBQYXJzZS5FcnJvcikge1xuICAgICAgICBuZXh0KGVycm9yKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gVE9ETzogRGV0ZXJtaW5lIHRoZSBjb3JyZWN0IGVycm9yIHNjZW5hcmlvLlxuICAgICAgICByZXEuY29uZmlnLmxvZ2dlckNvbnRyb2xsZXIuZXJyb3IoJ2Vycm9yIGdldHRpbmcgYXV0aCBmb3Igc2Vzc2lvblRva2VuJywgZXJyb3IpO1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuVU5LTk9XTl9FUlJPUiwgZXJyb3IpO1xuICAgICAgfVxuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBnZXRDbGllbnRJcChyZXEpIHtcbiAgaWYgKHJlcS5oZWFkZXJzWyd4LWZvcndhcmRlZC1mb3InXSkge1xuICAgIC8vIHRyeSB0byBnZXQgZnJvbSB4LWZvcndhcmVkLWZvciBpZiBpdCBzZXQgKGJlaGluZCByZXZlcnNlIHByb3h5KVxuICAgIHJldHVybiByZXEuaGVhZGVyc1sneC1mb3J3YXJkZWQtZm9yJ10uc3BsaXQoJywnKVswXTtcbiAgfSBlbHNlIGlmIChyZXEuY29ubmVjdGlvbiAmJiByZXEuY29ubmVjdGlvbi5yZW1vdGVBZGRyZXNzKSB7XG4gICAgLy8gbm8gcHJveHksIHRyeSBnZXR0aW5nIGZyb20gY29ubmVjdGlvbi5yZW1vdGVBZGRyZXNzXG4gICAgcmV0dXJuIHJlcS5jb25uZWN0aW9uLnJlbW90ZUFkZHJlc3M7XG4gIH0gZWxzZSBpZiAocmVxLnNvY2tldCkge1xuICAgIC8vIHRyeSB0byBnZXQgaXQgZnJvbSByZXEuc29ja2V0XG4gICAgcmV0dXJuIHJlcS5zb2NrZXQucmVtb3RlQWRkcmVzcztcbiAgfSBlbHNlIGlmIChyZXEuY29ubmVjdGlvbiAmJiByZXEuY29ubmVjdGlvbi5zb2NrZXQpIHtcbiAgICAvLyB0cnkgdG8gZ2V0IGl0IGZvcm0gdGhlIGNvbm5lY3Rpb24uc29ja2V0XG4gICAgcmV0dXJuIHJlcS5jb25uZWN0aW9uLnNvY2tldC5yZW1vdGVBZGRyZXNzO1xuICB9IGVsc2Uge1xuICAgIC8vIGlmIG5vbiBhYm92ZSwgZmFsbGJhY2suXG4gICAgcmV0dXJuIHJlcS5pcDtcbiAgfVxufVxuXG5mdW5jdGlvbiBodHRwQXV0aChyZXEpIHtcbiAgaWYgKCEocmVxLnJlcSB8fCByZXEpLmhlYWRlcnMuYXV0aG9yaXphdGlvbikgcmV0dXJuO1xuXG4gIHZhciBoZWFkZXIgPSAocmVxLnJlcSB8fCByZXEpLmhlYWRlcnMuYXV0aG9yaXphdGlvbjtcbiAgdmFyIGFwcElkLCBtYXN0ZXJLZXksIGphdmFzY3JpcHRLZXk7XG5cbiAgLy8gcGFyc2UgaGVhZGVyXG4gIHZhciBhdXRoUHJlZml4ID0gJ2Jhc2ljICc7XG5cbiAgdmFyIG1hdGNoID0gaGVhZGVyLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihhdXRoUHJlZml4KTtcblxuICBpZiAobWF0Y2ggPT0gMCkge1xuICAgIHZhciBlbmNvZGVkQXV0aCA9IGhlYWRlci5zdWJzdHJpbmcoYXV0aFByZWZpeC5sZW5ndGgsIGhlYWRlci5sZW5ndGgpO1xuICAgIHZhciBjcmVkZW50aWFscyA9IGRlY29kZUJhc2U2NChlbmNvZGVkQXV0aCkuc3BsaXQoJzonKTtcblxuICAgIGlmIChjcmVkZW50aWFscy5sZW5ndGggPT0gMikge1xuICAgICAgYXBwSWQgPSBjcmVkZW50aWFsc1swXTtcbiAgICAgIHZhciBrZXkgPSBjcmVkZW50aWFsc1sxXTtcblxuICAgICAgdmFyIGpzS2V5UHJlZml4ID0gJ2phdmFzY3JpcHQta2V5PSc7XG5cbiAgICAgIHZhciBtYXRjaEtleSA9IGtleS5pbmRleE9mKGpzS2V5UHJlZml4KTtcbiAgICAgIGlmIChtYXRjaEtleSA9PSAwKSB7XG4gICAgICAgIGphdmFzY3JpcHRLZXkgPSBrZXkuc3Vic3RyaW5nKGpzS2V5UHJlZml4Lmxlbmd0aCwga2V5Lmxlbmd0aCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtYXN0ZXJLZXkgPSBrZXk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgYXBwSWQ6IGFwcElkLCBtYXN0ZXJLZXk6IG1hc3RlcktleSwgamF2YXNjcmlwdEtleTogamF2YXNjcmlwdEtleSB9O1xufVxuXG5mdW5jdGlvbiBkZWNvZGVCYXNlNjQoc3RyKSB7XG4gIHJldHVybiBCdWZmZXIuZnJvbShzdHIsICdiYXNlNjQnKS50b1N0cmluZygpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYWxsb3dDcm9zc0RvbWFpbihhcHBJZCkge1xuICByZXR1cm4gKHJlcSwgcmVzLCBuZXh0KSA9PiB7XG4gICAgY29uc3QgY29uZmlnID0gQ29uZmlnLmdldChhcHBJZCwgZ2V0TW91bnRGb3JSZXF1ZXN0KHJlcSkpO1xuICAgIGxldCBhbGxvd0hlYWRlcnMgPSBERUZBVUxUX0FMTE9XRURfSEVBREVSUztcbiAgICBpZiAoY29uZmlnICYmIGNvbmZpZy5hbGxvd0hlYWRlcnMpIHtcbiAgICAgIGFsbG93SGVhZGVycyArPSBgLCAke2NvbmZpZy5hbGxvd0hlYWRlcnMuam9pbignLCAnKX1gO1xuICAgIH1cbiAgICBjb25zdCBhbGxvd09yaWdpbiA9IChjb25maWcgJiYgY29uZmlnLmFsbG93T3JpZ2luKSB8fCAnKic7XG4gICAgcmVzLmhlYWRlcignQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luJywgYWxsb3dPcmlnaW4pO1xuICAgIHJlcy5oZWFkZXIoJ0FjY2Vzcy1Db250cm9sLUFsbG93LU1ldGhvZHMnLCAnR0VULFBVVCxQT1NULERFTEVURSxPUFRJT05TJyk7XG4gICAgcmVzLmhlYWRlcignQWNjZXNzLUNvbnRyb2wtQWxsb3ctSGVhZGVycycsIGFsbG93SGVhZGVycyk7XG4gICAgcmVzLmhlYWRlcignQWNjZXNzLUNvbnRyb2wtRXhwb3NlLUhlYWRlcnMnLCAnWC1QYXJzZS1Kb2ItU3RhdHVzLUlkLCBYLVBhcnNlLVB1c2gtU3RhdHVzLUlkJyk7XG4gICAgLy8gaW50ZXJjZXB0IE9QVElPTlMgbWV0aG9kXG4gICAgaWYgKCdPUFRJT05TJyA9PSByZXEubWV0aG9kKSB7XG4gICAgICByZXMuc2VuZFN0YXR1cygyMDApO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXh0KCk7XG4gICAgfVxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYWxsb3dNZXRob2RPdmVycmlkZShyZXEsIHJlcywgbmV4dCkge1xuICBpZiAocmVxLm1ldGhvZCA9PT0gJ1BPU1QnICYmIHJlcS5ib2R5Ll9tZXRob2QpIHtcbiAgICByZXEub3JpZ2luYWxNZXRob2QgPSByZXEubWV0aG9kO1xuICAgIHJlcS5tZXRob2QgPSByZXEuYm9keS5fbWV0aG9kO1xuICAgIGRlbGV0ZSByZXEuYm9keS5fbWV0aG9kO1xuICB9XG4gIG5leHQoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhbmRsZVBhcnNlRXJyb3JzKGVyciwgcmVxLCByZXMsIG5leHQpIHtcbiAgY29uc3QgbG9nID0gKHJlcS5jb25maWcgJiYgcmVxLmNvbmZpZy5sb2dnZXJDb250cm9sbGVyKSB8fCBkZWZhdWx0TG9nZ2VyO1xuICBpZiAoZXJyIGluc3RhbmNlb2YgUGFyc2UuRXJyb3IpIHtcbiAgICBpZiAocmVxLmNvbmZpZyAmJiByZXEuY29uZmlnLmVuYWJsZUV4cHJlc3NFcnJvckhhbmRsZXIpIHtcbiAgICAgIHJldHVybiBuZXh0KGVycik7XG4gICAgfVxuICAgIGxldCBodHRwU3RhdHVzO1xuICAgIC8vIFRPRE86IGZpbGwgb3V0IHRoaXMgbWFwcGluZ1xuICAgIHN3aXRjaCAoZXJyLmNvZGUpIHtcbiAgICAgIGNhc2UgUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SOlxuICAgICAgICBodHRwU3RhdHVzID0gNTAwO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORDpcbiAgICAgICAgaHR0cFN0YXR1cyA9IDQwNDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBodHRwU3RhdHVzID0gNDAwO1xuICAgIH1cbiAgICByZXMuc3RhdHVzKGh0dHBTdGF0dXMpO1xuICAgIHJlcy5qc29uKHsgY29kZTogZXJyLmNvZGUsIGVycm9yOiBlcnIubWVzc2FnZSB9KTtcbiAgICBsb2cuZXJyb3IoJ1BhcnNlIGVycm9yOiAnLCBlcnIpO1xuICB9IGVsc2UgaWYgKGVyci5zdGF0dXMgJiYgZXJyLm1lc3NhZ2UpIHtcbiAgICByZXMuc3RhdHVzKGVyci5zdGF0dXMpO1xuICAgIHJlcy5qc29uKHsgZXJyb3I6IGVyci5tZXNzYWdlIH0pO1xuICAgIGlmICghKHByb2Nlc3MgJiYgcHJvY2Vzcy5lbnYuVEVTVElORykpIHtcbiAgICAgIG5leHQoZXJyKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgbG9nLmVycm9yKCdVbmNhdWdodCBpbnRlcm5hbCBzZXJ2ZXIgZXJyb3IuJywgZXJyLCBlcnIuc3RhY2spO1xuICAgIHJlcy5zdGF0dXMoNTAwKTtcbiAgICByZXMuanNvbih7XG4gICAgICBjb2RlOiBQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsXG4gICAgICBtZXNzYWdlOiAnSW50ZXJuYWwgc2VydmVyIGVycm9yLicsXG4gICAgfSk7XG4gICAgaWYgKCEocHJvY2VzcyAmJiBwcm9jZXNzLmVudi5URVNUSU5HKSkge1xuICAgICAgbmV4dChlcnIpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZW5mb3JjZU1hc3RlcktleUFjY2VzcyhyZXEsIHJlcywgbmV4dCkge1xuICBpZiAoIXJlcS5hdXRoLmlzTWFzdGVyKSB7XG4gICAgcmVzLnN0YXR1cyg0MDMpO1xuICAgIHJlcy5lbmQoJ3tcImVycm9yXCI6XCJ1bmF1dGhvcml6ZWQ6IG1hc3RlciBrZXkgaXMgcmVxdWlyZWRcIn0nKTtcbiAgICByZXR1cm47XG4gIH1cbiAgbmV4dCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHJvbWlzZUVuZm9yY2VNYXN0ZXJLZXlBY2Nlc3MocmVxdWVzdCkge1xuICBpZiAoIXJlcXVlc3QuYXV0aC5pc01hc3Rlcikge1xuICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKCk7XG4gICAgZXJyb3Iuc3RhdHVzID0gNDAzO1xuICAgIGVycm9yLm1lc3NhZ2UgPSAndW5hdXRob3JpemVkOiBtYXN0ZXIga2V5IGlzIHJlcXVpcmVkJztcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG59XG5cbi8qKlxuICogRGVkdXBsaWNhdGVzIGEgcmVxdWVzdCB0byBlbnN1cmUgaWRlbXBvdGVuY3kuIER1cGxpY2F0ZXMgYXJlIGRldGVybWluZWQgYnkgdGhlIHJlcXVlc3QgSURcbiAqIGluIHRoZSByZXF1ZXN0IGhlYWRlci4gSWYgYSByZXF1ZXN0IGhhcyBubyByZXF1ZXN0IElELCBpdCBpcyBleGVjdXRlZCBhbnl3YXkuXG4gKiBAcGFyYW0geyp9IHJlcSBUaGUgcmVxdWVzdCB0byBldmFsdWF0ZS5cbiAqIEByZXR1cm5zIFByb21pc2U8e30+XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcm9taXNlRW5zdXJlSWRlbXBvdGVuY3kocmVxKSB7XG4gIC8vIEVuYWJsZSBmZWF0dXJlIG9ubHkgZm9yIE1vbmdvREJcbiAgaWYgKCEocmVxLmNvbmZpZy5kYXRhYmFzZS5hZGFwdGVyIGluc3RhbmNlb2YgTW9uZ29TdG9yYWdlQWRhcHRlcikpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cbiAgLy8gR2V0IHBhcmFtZXRlcnNcbiAgY29uc3QgY29uZmlnID0gcmVxLmNvbmZpZztcbiAgY29uc3QgcmVxdWVzdElkID0gKChyZXEgfHwge30pLmhlYWRlcnMgfHwge30pWyd4LXBhcnNlLXJlcXVlc3QtaWQnXTtcbiAgY29uc3QgeyBwYXRocywgdHRsIH0gPSBjb25maWcuaWRlbXBvdGVuY3lPcHRpb25zO1xuICBpZiAoIXJlcXVlc3RJZCB8fCAhY29uZmlnLmlkZW1wb3RlbmN5T3B0aW9ucykge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuICAvLyBSZXF1ZXN0IHBhdGggbWF5IGNvbnRhaW4gdHJhaWxpbmcgc2xhc2hlcywgZGVwZW5kaW5nIG9uIHRoZSBvcmlnaW5hbCByZXF1ZXN0LCBzbyByZW1vdmVcbiAgLy8gbGVhZGluZyBhbmQgdHJhaWxpbmcgc2xhc2hlcyB0byBtYWtlIGl0IGVhc2llciB0byBzcGVjaWZ5IHBhdGhzIGluIHRoZSBjb25maWd1cmF0aW9uXG4gIGNvbnN0IHJlcVBhdGggPSByZXEucGF0aC5yZXBsYWNlKC9eXFwvfFxcLyQvLCAnJyk7XG4gIC8vIERldGVybWluZSB3aGV0aGVyIGlkZW1wb3RlbmN5IGlzIGVuYWJsZWQgZm9yIGN1cnJlbnQgcmVxdWVzdCBwYXRoXG4gIGxldCBtYXRjaCA9IGZhbHNlO1xuICBmb3IgKGNvbnN0IHBhdGggb2YgcGF0aHMpIHtcbiAgICAvLyBBc3N1bWUgb25lIHdhbnRzIGEgcGF0aCB0byBhbHdheXMgbWF0Y2ggZnJvbSB0aGUgYmVnaW5uaW5nIHRvIHByZXZlbnQgYW55IG1pc3Rha2VzXG4gICAgY29uc3QgcmVnZXggPSBuZXcgUmVnRXhwKHBhdGguY2hhckF0KDApID09PSAnXicgPyBwYXRoIDogJ14nICsgcGF0aCk7XG4gICAgaWYgKHJlcVBhdGgubWF0Y2gocmVnZXgpKSB7XG4gICAgICBtYXRjaCA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgaWYgKCFtYXRjaCkge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuICAvLyBUcnkgdG8gc3RvcmUgcmVxdWVzdFxuICBjb25zdCBleHBpcnlEYXRlID0gbmV3IERhdGUobmV3IERhdGUoKS5zZXRTZWNvbmRzKG5ldyBEYXRlKCkuZ2V0U2Vjb25kcygpICsgdHRsKSk7XG4gIHJldHVybiByZXN0XG4gICAgLmNyZWF0ZShjb25maWcsIGF1dGgubWFzdGVyKGNvbmZpZyksICdfSWRlbXBvdGVuY3knLCB7XG4gICAgICByZXFJZDogcmVxdWVzdElkLFxuICAgICAgZXhwaXJlOiBQYXJzZS5fZW5jb2RlKGV4cGlyeURhdGUpLFxuICAgIH0pXG4gICAgLmNhdGNoKGUgPT4ge1xuICAgICAgaWYgKGUuY29kZSA9PSBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLkRVUExJQ0FURV9SRVFVRVNULCAnRHVwbGljYXRlIHJlcXVlc3QnKTtcbiAgICAgIH1cbiAgICAgIHRocm93IGU7XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGludmFsaWRSZXF1ZXN0KHJlcSwgcmVzKSB7XG4gIHJlcy5zdGF0dXMoNDAzKTtcbiAgcmVzLmVuZCgne1wiZXJyb3JcIjpcInVuYXV0aG9yaXplZFwifScpO1xufVxuIl19 \ No newline at end of file diff --git a/lib/password.js b/lib/password.js deleted file mode 100644 index 6091ae5d2d..0000000000 --- a/lib/password.js +++ /dev/null @@ -1,38 +0,0 @@ -"use strict"; - -// Tools for encrypting and decrypting passwords. -// Basically promise-friendly wrappers for bcrypt. -var bcrypt = require('bcryptjs'); - -try { - const _bcrypt = require('@node-rs/bcrypt'); - - bcrypt = { - hash: _bcrypt.hash, - compare: _bcrypt.verify - }; -} catch (e) { - /* */ -} // Returns a promise for a hashed password string. - - -function hash(password) { - return bcrypt.hash(password, 10); -} // Returns a promise for whether this password compares to equal this -// hashed password. - - -function compare(password, hashedPassword) { - // Cannot bcrypt compare when one is undefined - if (!password || !hashedPassword) { - return Promise.resolve(false); - } - - return bcrypt.compare(password, hashedPassword); -} - -module.exports = { - hash: hash, - compare: compare -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9wYXNzd29yZC5qcyJdLCJuYW1lcyI6WyJiY3J5cHQiLCJyZXF1aXJlIiwiX2JjcnlwdCIsImhhc2giLCJjb21wYXJlIiwidmVyaWZ5IiwiZSIsInBhc3N3b3JkIiwiaGFzaGVkUGFzc3dvcmQiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUNBLElBQUlBLE1BQU0sR0FBR0MsT0FBTyxDQUFDLFVBQUQsQ0FBcEI7O0FBRUEsSUFBSTtBQUNGLFFBQU1DLE9BQU8sR0FBR0QsT0FBTyxDQUFDLGlCQUFELENBQXZCOztBQUNBRCxFQUFBQSxNQUFNLEdBQUc7QUFDUEcsSUFBQUEsSUFBSSxFQUFFRCxPQUFPLENBQUNDLElBRFA7QUFFUEMsSUFBQUEsT0FBTyxFQUFFRixPQUFPLENBQUNHO0FBRlYsR0FBVDtBQUlELENBTkQsQ0FNRSxPQUFPQyxDQUFQLEVBQVU7QUFDVjtBQUNELEMsQ0FFRDs7O0FBQ0EsU0FBU0gsSUFBVCxDQUFjSSxRQUFkLEVBQXdCO0FBQ3RCLFNBQU9QLE1BQU0sQ0FBQ0csSUFBUCxDQUFZSSxRQUFaLEVBQXNCLEVBQXRCLENBQVA7QUFDRCxDLENBRUQ7QUFDQTs7O0FBQ0EsU0FBU0gsT0FBVCxDQUFpQkcsUUFBakIsRUFBMkJDLGNBQTNCLEVBQTJDO0FBQ3pDO0FBQ0EsTUFBSSxDQUFDRCxRQUFELElBQWEsQ0FBQ0MsY0FBbEIsRUFBa0M7QUFDaEMsV0FBT0MsT0FBTyxDQUFDQyxPQUFSLENBQWdCLEtBQWhCLENBQVA7QUFDRDs7QUFDRCxTQUFPVixNQUFNLENBQUNJLE9BQVAsQ0FBZUcsUUFBZixFQUF5QkMsY0FBekIsQ0FBUDtBQUNEOztBQUVERyxNQUFNLENBQUNDLE9BQVAsR0FBaUI7QUFDZlQsRUFBQUEsSUFBSSxFQUFFQSxJQURTO0FBRWZDLEVBQUFBLE9BQU8sRUFBRUE7QUFGTSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbIi8vIFRvb2xzIGZvciBlbmNyeXB0aW5nIGFuZCBkZWNyeXB0aW5nIHBhc3N3b3Jkcy5cbi8vIEJhc2ljYWxseSBwcm9taXNlLWZyaWVuZGx5IHdyYXBwZXJzIGZvciBiY3J5cHQuXG52YXIgYmNyeXB0ID0gcmVxdWlyZSgnYmNyeXB0anMnKTtcblxudHJ5IHtcbiAgY29uc3QgX2JjcnlwdCA9IHJlcXVpcmUoJ0Bub2RlLXJzL2JjcnlwdCcpO1xuICBiY3J5cHQgPSB7XG4gICAgaGFzaDogX2JjcnlwdC5oYXNoLFxuICAgIGNvbXBhcmU6IF9iY3J5cHQudmVyaWZ5LFxuICB9O1xufSBjYXRjaCAoZSkge1xuICAvKiAqL1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYSBoYXNoZWQgcGFzc3dvcmQgc3RyaW5nLlxuZnVuY3Rpb24gaGFzaChwYXNzd29yZCkge1xuICByZXR1cm4gYmNyeXB0Lmhhc2gocGFzc3dvcmQsIDEwKTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIHdoZXRoZXIgdGhpcyBwYXNzd29yZCBjb21wYXJlcyB0byBlcXVhbCB0aGlzXG4vLyBoYXNoZWQgcGFzc3dvcmQuXG5mdW5jdGlvbiBjb21wYXJlKHBhc3N3b3JkLCBoYXNoZWRQYXNzd29yZCkge1xuICAvLyBDYW5ub3QgYmNyeXB0IGNvbXBhcmUgd2hlbiBvbmUgaXMgdW5kZWZpbmVkXG4gIGlmICghcGFzc3dvcmQgfHwgIWhhc2hlZFBhc3N3b3JkKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShmYWxzZSk7XG4gIH1cbiAgcmV0dXJuIGJjcnlwdC5jb21wYXJlKHBhc3N3b3JkLCBoYXNoZWRQYXNzd29yZCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBoYXNoOiBoYXNoLFxuICBjb21wYXJlOiBjb21wYXJlLFxufTtcbiJdfQ== \ No newline at end of file diff --git a/lib/request.js b/lib/request.js deleted file mode 100644 index 47dae80852..0000000000 --- a/lib/request.js +++ /dev/null @@ -1,4 +0,0 @@ -"use strict"; - -module.exports = require('./cloud-code/httpRequest'); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9yZXF1ZXN0LmpzIl0sIm5hbWVzIjpbIm1vZHVsZSIsImV4cG9ydHMiLCJyZXF1aXJlIl0sIm1hcHBpbmdzIjoiOztBQUFBQSxNQUFNLENBQUNDLE9BQVAsR0FBaUJDLE9BQU8sQ0FBQywwQkFBRCxDQUF4QiIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9jbG91ZC1jb2RlL2h0dHBSZXF1ZXN0Jyk7XG4iXX0= \ No newline at end of file diff --git a/lib/requiredParameter.js b/lib/requiredParameter.js deleted file mode 100644 index 2a657ca91b..0000000000 --- a/lib/requiredParameter.js +++ /dev/null @@ -1,13 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _default = errorMessage => { - throw errorMessage; -}; - -exports.default = _default; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9yZXF1aXJlZFBhcmFtZXRlci5qcyJdLCJuYW1lcyI6WyJlcnJvck1lc3NhZ2UiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7ZUFDZ0JBLFlBQUQsSUFBK0I7QUFDNUMsUUFBTUEsWUFBTjtBQUNELEMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiogQGZsb3cgKi9cbmV4cG9ydCBkZWZhdWx0IChlcnJvck1lc3NhZ2U6IHN0cmluZyk6IGFueSA9PiB7XG4gIHRocm93IGVycm9yTWVzc2FnZTtcbn07XG4iXX0= \ No newline at end of file diff --git a/lib/rest.js b/lib/rest.js deleted file mode 100644 index 1d822db8d3..0000000000 --- a/lib/rest.js +++ /dev/null @@ -1,208 +0,0 @@ -"use strict"; - -// This file contains helpers for running operations in REST format. -// The goal is that handlers that explicitly handle an express route -// should just be shallow wrappers around things in this file, but -// these functions should not explicitly depend on the request -// object. -// This means that one of these handlers can support multiple -// routes. That's useful for the routes that do really similar -// things. -var Parse = require('parse/node').Parse; - -var RestQuery = require('./RestQuery'); - -var RestWrite = require('./RestWrite'); - -var triggers = require('./triggers'); - -function checkTriggers(className, config, types) { - return types.some(triggerType => { - return triggers.getTrigger(className, triggers.Types[triggerType], config.applicationId); - }); -} - -function checkLiveQuery(className, config) { - return config.liveQueryController && config.liveQueryController.hasLiveQuery(className); -} // Returns a promise for an object with optional keys 'results' and 'count'. - - -function find(config, auth, className, restWhere, restOptions, clientSDK, context) { - enforceRoleSecurity('find', className, auth); - return triggers.maybeRunQueryTrigger(triggers.Types.beforeFind, className, restWhere, restOptions, config, auth, context).then(result => { - restWhere = result.restWhere || restWhere; - restOptions = result.restOptions || restOptions; - const query = new RestQuery(config, auth, className, restWhere, restOptions, clientSDK, true, context); - return query.execute(); - }); -} // get is just like find but only queries an objectId. - - -const get = (config, auth, className, objectId, restOptions, clientSDK, context) => { - var restWhere = { - objectId - }; - enforceRoleSecurity('get', className, auth); - return triggers.maybeRunQueryTrigger(triggers.Types.beforeFind, className, restWhere, restOptions, config, auth, context, true).then(result => { - restWhere = result.restWhere || restWhere; - restOptions = result.restOptions || restOptions; - const query = new RestQuery(config, auth, className, restWhere, restOptions, clientSDK, true, context); - return query.execute(); - }); -}; // Returns a promise that doesn't resolve to any useful value. - - -function del(config, auth, className, objectId, context) { - if (typeof objectId !== 'string') { - throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad objectId'); - } - - if (className === '_User' && auth.isUnauthenticated()) { - throw new Parse.Error(Parse.Error.SESSION_MISSING, 'Insufficient auth to delete user'); - } - - enforceRoleSecurity('delete', className, auth); - let inflatedObject; - let schemaController; - return Promise.resolve().then(() => { - const hasTriggers = checkTriggers(className, config, ['beforeDelete', 'afterDelete']); - const hasLiveQuery = checkLiveQuery(className, config); - - if (hasTriggers || hasLiveQuery || className == '_Session') { - return new RestQuery(config, auth, className, { - objectId - }).execute({ - op: 'delete' - }).then(response => { - if (response && response.results && response.results.length) { - const firstResult = response.results[0]; - firstResult.className = className; - - if (className === '_Session' && !auth.isMaster) { - if (!auth.user || firstResult.user.objectId !== auth.user.id) { - throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token'); - } - } - - var cacheAdapter = config.cacheController; - cacheAdapter.user.del(firstResult.sessionToken); - inflatedObject = Parse.Object.fromJSON(firstResult); - return triggers.maybeRunTrigger(triggers.Types.beforeDelete, auth, inflatedObject, null, config, context); - } - - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found for delete.'); - }); - } - - return Promise.resolve({}); - }).then(() => { - if (!auth.isMaster) { - return auth.getUserRoles(); - } else { - return; - } - }).then(() => config.database.loadSchema()).then(s => { - schemaController = s; - const options = {}; - - if (!auth.isMaster) { - options.acl = ['*']; - - if (auth.user) { - options.acl.push(auth.user.id); - options.acl = options.acl.concat(auth.userRoles); - } - } - - return config.database.destroy(className, { - objectId: objectId - }, options, schemaController); - }).then(() => { - // Notify LiveQuery server if possible - const perms = schemaController.getClassLevelPermissions(className); - config.liveQueryController.onAfterDelete(className, inflatedObject, null, perms); - return triggers.maybeRunTrigger(triggers.Types.afterDelete, auth, inflatedObject, null, config, context); - }).catch(error => { - handleSessionMissingError(error, className, auth); - }); -} // Returns a promise for a {response, status, location} object. - - -function create(config, auth, className, restObject, clientSDK, context) { - enforceRoleSecurity('create', className, auth); - var write = new RestWrite(config, auth, className, null, restObject, null, clientSDK, context); - return write.execute(); -} // Returns a promise that contains the fields of the update that the -// REST API is supposed to return. -// Usually, this is just updatedAt. - - -function update(config, auth, className, restWhere, restObject, clientSDK, context) { - enforceRoleSecurity('update', className, auth); - return Promise.resolve().then(() => { - const hasTriggers = checkTriggers(className, config, ['beforeSave', 'afterSave']); - const hasLiveQuery = checkLiveQuery(className, config); - - if (hasTriggers || hasLiveQuery) { - // Do not use find, as it runs the before finds - return new RestQuery(config, auth, className, restWhere, undefined, undefined, false, context).execute({ - op: 'update' - }); - } - - return Promise.resolve({}); - }).then(({ - results - }) => { - var originalRestObject; - - if (results && results.length) { - originalRestObject = results[0]; - } - - return new RestWrite(config, auth, className, restWhere, restObject, originalRestObject, clientSDK, context, 'update').execute(); - }).catch(error => { - handleSessionMissingError(error, className, auth); - }); -} - -function handleSessionMissingError(error, className, auth) { - // If we're trying to update a user without / with bad session token - if (className === '_User' && error.code === Parse.Error.OBJECT_NOT_FOUND && !auth.isMaster) { - throw new Parse.Error(Parse.Error.SESSION_MISSING, 'Insufficient auth.'); - } - - throw error; -} - -const classesWithMasterOnlyAccess = ['_JobStatus', '_PushStatus', '_Hooks', '_GlobalConfig', '_JobSchedule', '_Idempotency']; // Disallowing access to the _Role collection except by master key - -function enforceRoleSecurity(method, className, auth) { - if (className === '_Installation' && !auth.isMaster) { - if (method === 'delete' || method === 'find') { - const error = `Clients aren't allowed to perform the ${method} operation on the installation collection.`; - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); - } - } //all volatileClasses are masterKey only - - - if (classesWithMasterOnlyAccess.indexOf(className) >= 0 && !auth.isMaster) { - const error = `Clients aren't allowed to perform the ${method} operation on the ${className} collection.`; - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); - } // readOnly masterKey is not allowed - - - if (auth.isReadOnly && (method === 'delete' || method === 'create' || method === 'update')) { - const error = `read-only masterKey isn't allowed to perform the ${method} operation.`; - throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error); - } -} - -module.exports = { - create, - del, - find, - get, - update -}; -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9yZXN0LmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsIlJlc3RRdWVyeSIsIlJlc3RXcml0ZSIsInRyaWdnZXJzIiwiY2hlY2tUcmlnZ2VycyIsImNsYXNzTmFtZSIsImNvbmZpZyIsInR5cGVzIiwic29tZSIsInRyaWdnZXJUeXBlIiwiZ2V0VHJpZ2dlciIsIlR5cGVzIiwiYXBwbGljYXRpb25JZCIsImNoZWNrTGl2ZVF1ZXJ5IiwibGl2ZVF1ZXJ5Q29udHJvbGxlciIsImhhc0xpdmVRdWVyeSIsImZpbmQiLCJhdXRoIiwicmVzdFdoZXJlIiwicmVzdE9wdGlvbnMiLCJjbGllbnRTREsiLCJjb250ZXh0IiwiZW5mb3JjZVJvbGVTZWN1cml0eSIsIm1heWJlUnVuUXVlcnlUcmlnZ2VyIiwiYmVmb3JlRmluZCIsInRoZW4iLCJyZXN1bHQiLCJxdWVyeSIsImV4ZWN1dGUiLCJnZXQiLCJvYmplY3RJZCIsImRlbCIsIkVycm9yIiwiSU5WQUxJRF9KU09OIiwiaXNVbmF1dGhlbnRpY2F0ZWQiLCJTRVNTSU9OX01JU1NJTkciLCJpbmZsYXRlZE9iamVjdCIsInNjaGVtYUNvbnRyb2xsZXIiLCJQcm9taXNlIiwicmVzb2x2ZSIsImhhc1RyaWdnZXJzIiwib3AiLCJyZXNwb25zZSIsInJlc3VsdHMiLCJsZW5ndGgiLCJmaXJzdFJlc3VsdCIsImlzTWFzdGVyIiwidXNlciIsImlkIiwiSU5WQUxJRF9TRVNTSU9OX1RPS0VOIiwiY2FjaGVBZGFwdGVyIiwiY2FjaGVDb250cm9sbGVyIiwic2Vzc2lvblRva2VuIiwiT2JqZWN0IiwiZnJvbUpTT04iLCJtYXliZVJ1blRyaWdnZXIiLCJiZWZvcmVEZWxldGUiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiZ2V0VXNlclJvbGVzIiwiZGF0YWJhc2UiLCJsb2FkU2NoZW1hIiwicyIsIm9wdGlvbnMiLCJhY2wiLCJwdXNoIiwiY29uY2F0IiwidXNlclJvbGVzIiwiZGVzdHJveSIsInBlcm1zIiwiZ2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zIiwib25BZnRlckRlbGV0ZSIsImFmdGVyRGVsZXRlIiwiY2F0Y2giLCJlcnJvciIsImhhbmRsZVNlc3Npb25NaXNzaW5nRXJyb3IiLCJjcmVhdGUiLCJyZXN0T2JqZWN0Iiwid3JpdGUiLCJ1cGRhdGUiLCJ1bmRlZmluZWQiLCJvcmlnaW5hbFJlc3RPYmplY3QiLCJjb2RlIiwiY2xhc3Nlc1dpdGhNYXN0ZXJPbmx5QWNjZXNzIiwibWV0aG9kIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsImluZGV4T2YiLCJpc1JlYWRPbmx5IiwibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBRUEsSUFBSUEsS0FBSyxHQUFHQyxPQUFPLENBQUMsWUFBRCxDQUFQLENBQXNCRCxLQUFsQzs7QUFFQSxJQUFJRSxTQUFTLEdBQUdELE9BQU8sQ0FBQyxhQUFELENBQXZCOztBQUNBLElBQUlFLFNBQVMsR0FBR0YsT0FBTyxDQUFDLGFBQUQsQ0FBdkI7O0FBQ0EsSUFBSUcsUUFBUSxHQUFHSCxPQUFPLENBQUMsWUFBRCxDQUF0Qjs7QUFFQSxTQUFTSSxhQUFULENBQXVCQyxTQUF2QixFQUFrQ0MsTUFBbEMsRUFBMENDLEtBQTFDLEVBQWlEO0FBQy9DLFNBQU9BLEtBQUssQ0FBQ0MsSUFBTixDQUFXQyxXQUFXLElBQUk7QUFDL0IsV0FBT04sUUFBUSxDQUFDTyxVQUFULENBQW9CTCxTQUFwQixFQUErQkYsUUFBUSxDQUFDUSxLQUFULENBQWVGLFdBQWYsQ0FBL0IsRUFBNERILE1BQU0sQ0FBQ00sYUFBbkUsQ0FBUDtBQUNELEdBRk0sQ0FBUDtBQUdEOztBQUVELFNBQVNDLGNBQVQsQ0FBd0JSLFNBQXhCLEVBQW1DQyxNQUFuQyxFQUEyQztBQUN6QyxTQUFPQSxNQUFNLENBQUNRLG1CQUFQLElBQThCUixNQUFNLENBQUNRLG1CQUFQLENBQTJCQyxZQUEzQixDQUF3Q1YsU0FBeEMsQ0FBckM7QUFDRCxDLENBRUQ7OztB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bHBlcnMgZm9yIHJ1bm5pbmcgb3BlcmF0aW9ucyBpbiBSRVNUIGZvcm1hdC5cbi8vIFRoZSBnb2FsIGlzIHRoYXQgaGFuZGxlcnMgdGhhdCBleHBsaWNpdGx5IGhhbmRsZSBhbiBleHByZXNzIHJvdXRlXG4vLyBzaG91bGQganVzdCBiZSBzaGFsbG93IHdyYXBwZXJzIGFyb3VuZCB0aGluZ3MgaW4gdGhpcyBmaWxlLCBidXRcbi8vIHRoZXNlIGZ1bmN0aW9ucyBzaG91bGQgbm90IGV4cGxpY2l0bHkgZGVwZW5kIG9uIHRoZSByZXF1ZXN0XG4vLyBvYmplY3QuXG4vLyBUaGlzIG1lYW5zIHRoYXQgb25lIG9mIHRoZXNlIGhhbmRsZXJzIGNhbiBzdXBwb3J0IG11bHRpcGxlXG4vLyByb3V0ZXMuIFRoYXQncyB1c2VmdWwgZm9yIHRoZSByb3V0ZXMgdGhhdCBkbyByZWFsbHkgc2ltaWxhclxuLy8gdGhpbmdzLlxuXG52YXIgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJykuUGFyc2U7XG5cbnZhciBSZXN0UXVlcnkgPSByZXF1aXJlKCcuL1Jlc3RRdWVyeScpO1xudmFyIFJlc3RXcml0ZSA9IHJlcXVpcmUoJy4vUmVzdFdyaXRlJyk7XG52YXIgdHJpZ2dlcnMgPSByZXF1aXJlKCcuL3RyaWdnZXJzJyk7XG5cbmZ1bmN0aW9uIGNoZWNrVHJpZ2dlcnMoY2xhc3NOYW1lLCBjb25maWcsIHR5cGVzKSB7XG4gIHJldHVybiB0eXBlcy5zb21lKHRyaWdnZXJUeXBlID0+IHtcbiAgICByZXR1cm4gdHJpZ2dlcnMuZ2V0VHJpZ2dlcihjbGFzc05hbWUsIHRyaWdnZXJzLlR5cGVzW3RyaWdnZXJUeXBlXSwgY29uZmlnLmFwcGxpY2F0aW9uSWQpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gY2hlY2tMaXZlUXVlcnkoY2xhc3NOYW1lLCBjb25maWcpIHtcbiAgcmV0dXJuIGNvbmZpZy5saXZlUXVlcnlDb250cm9sbGVyICYmIGNvbmZpZy5saXZlUXVlcnlDb250cm9sbGVyLmhhc0xpdmVRdWVyeShjbGFzc05hbWUpO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYW4gb2JqZWN0IHdpdGggb3B0aW9uYWwga2V5cyAncmVzdWx0cycgYW5kICdjb3VudCcuXG5mdW5jdGlvbiBmaW5kKGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCByZXN0V2hlcmUsIHJlc3RPcHRpb25zLCBjbGllbnRTREssIGNvbnRleHQpIHtcbiAgZW5mb3JjZVJvbGVTZWN1cml0eSgnZmluZCcsIGNsYXNzTmFtZSwgYXV0aCk7XG4gIHJldHVybiB0cmlnZ2Vyc1xuICAgIC5tYXliZVJ1blF1ZXJ5VHJpZ2dlcihcbiAgICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZUZpbmQsXG4gICAgICBjbGFzc05hbWUsXG4gICAgICByZXN0V2hlcmUsXG4gICAgICByZXN0T3B0aW9ucyxcbiAgICAgIGNvbmZpZyxcbiAgICAgIGF1dGgsXG4gICAgICBjb250ZXh0XG4gICAgKVxuICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICByZXN0V2hlcmUgPSByZXN1bHQucmVzdFdoZXJlIHx8IHJlc3RXaGVyZTtcbiAgICAgIHJlc3RPcHRpb25zID0gcmVzdWx0LnJlc3RPcHRpb25zIHx8IHJlc3RPcHRpb25zO1xuICAgICAgY29uc3QgcXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KFxuICAgICAgICBjb25maWcsXG4gICAgICAgIGF1dGgsXG4gICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgcmVzdFdoZXJlLFxuICAgICAgICByZXN0T3B0aW9ucyxcbiAgICAgICAgY2xpZW50U0RLLFxuICAgICAgICB0cnVlLFxuICAgICAgICBjb250ZXh0XG4gICAgICApO1xuICAgICAgcmV0dXJuIHF1ZXJ5LmV4ZWN1dGUoKTtcbiAgICB9KTtcbn1cblxuLy8gZ2V0IGlzIGp1c3QgbGlrZSBmaW5kIGJ1dCBvbmx5IHF1ZXJpZXMgYW4gb2JqZWN0SWQuXG5jb25zdCBnZXQgPSAoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIG9iamVjdElkLCByZXN0T3B0aW9ucywgY2xpZW50U0RLLCBjb250ZXh0KSA9PiB7XG4gIHZhciByZXN0V2hlcmUgPSB7IG9iamVjdElkIH07XG4gIGVuZm9yY2VSb2xlU2VjdXJpdHkoJ2dldCcsIGNsYXNzTmFtZSwgYXV0aCk7XG4gIHJldHVybiB0cmlnZ2Vyc1xuICAgIC5tYXliZVJ1blF1ZXJ5VHJpZ2dlcihcbiAgICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZUZpbmQsXG4gICAgICBjbGFzc05hbWUsXG4gICAgICByZXN0V2hlcmUsXG4gICAgICByZXN0T3B0aW9ucyxcbiAgICAgIGNvbmZpZyxcbiAgICAgIGF1dGgsXG4gICAgICBjb250ZXh0LFxuICAgICAgdHJ1ZVxuICAgIClcbiAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgcmVzdFdoZXJlID0gcmVzdWx0LnJlc3RXaGVyZSB8fCByZXN0V2hlcmU7XG4gICAgICByZXN0T3B0aW9ucyA9IHJlc3VsdC5yZXN0T3B0aW9ucyB8fCByZXN0T3B0aW9ucztcbiAgICAgIGNvbnN0IHF1ZXJ5ID0gbmV3IFJlc3RRdWVyeShcbiAgICAgICAgY29uZmlnLFxuICAgICAgICBhdXRoLFxuICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgIHJlc3RXaGVyZSxcbiAgICAgICAgcmVzdE9wdGlvbnMsXG4gICAgICAgIGNsaWVudFNESyxcbiAgICAgICAgdHJ1ZSxcbiAgICAgICAgY29udGV4dFxuICAgICAgKTtcbiAgICAgIHJldHVybiBxdWVyeS5leGVjdXRlKCk7XG4gICAgfSk7XG59O1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IGRvZXNuJ3QgcmVzb2x2ZSB0byBhbnkgdXNlZnVsIHZhbHVlLlxuZnVuY3Rpb24gZGVsKGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCBvYmplY3RJZCwgY29udGV4dCkge1xuICBpZiAodHlwZW9mIG9iamVjdElkICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sICdiYWQgb2JqZWN0SWQnKTtcbiAgfVxuXG4gIGlmIChjbGFzc05hbWUgPT09ICdfVXNlcicgJiYgYXV0aC5pc1VuYXV0aGVudGljYXRlZCgpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlNFU1NJT05fTUlTU0lORywgJ0luc3VmZmljaWVudCBhdXRoIHRvIGRlbGV0ZSB1c2VyJyk7XG4gIH1cblxuICBlbmZvcmNlUm9sZVNlY3VyaXR5KCdkZWxldGUnLCBjbGFzc05hbWUsIGF1dGgpO1xuXG4gIGxldCBpbmZsYXRlZE9iamVjdDtcbiAgbGV0IHNjaGVtYUNvbnRyb2xsZXI7XG5cbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgY29uc3QgaGFzVHJpZ2dlcnMgPSBjaGVja1RyaWdnZXJzKGNsYXNzTmFtZSwgY29uZmlnLCBbJ2JlZm9yZURlbGV0ZScsICdhZnRlckRlbGV0ZSddKTtcbiAgICAgIGNvbnN0IGhhc0xpdmVRdWVyeSA9IGNoZWNrTGl2ZVF1ZXJ5KGNsYXNzTmFtZSwgY29uZmlnKTtcbiAgICAgIGlmIChoYXNUcmlnZ2VycyB8fCBoYXNMaXZlUXVlcnkgfHwgY2xhc3NOYW1lID09ICdfU2Vzc2lvbicpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXN0UXVlcnkoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIHsgb2JqZWN0SWQgfSlcbiAgICAgICAgICAuZXhlY3V0ZSh7IG9wOiAnZGVsZXRlJyB9KVxuICAgICAgICAgIC50aGVuKHJlc3BvbnNlID0+IHtcbiAgICAgICAgICAgIGlmIChyZXNwb25zZSAmJiByZXNwb25zZS5yZXN1bHRzICYmIHJlc3BvbnNlLnJlc3VsdHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGZpcnN0UmVzdWx0ID0gcmVzcG9uc2UucmVzdWx0c1swXTtcbiAgICAgICAgICAgICAgZmlyc3RSZXN1bHQuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xuICAgICAgICAgICAgICBpZiAoY2xhc3NOYW1lID09PSAnX1Nlc3Npb24nICYmICFhdXRoLmlzTWFzdGVyKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFhdXRoLnVzZXIgfHwgZmlyc3RSZXN1bHQudXNlci5vYmplY3RJZCAhPT0gYXV0aC51c2VyLmlkKSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOLCAnSW52YWxpZCBzZXNzaW9uIHRva2VuJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHZhciBjYWNoZUFkYXB0ZXIgPSBjb25maWcuY2FjaGVDb250cm9sbGVyO1xuICAgICAgICAgICAgICBjYWNoZUFkYXB0ZXIudXNlci5kZWwoZmlyc3RSZXN1bHQuc2Vzc2lvblRva2VuKTtcbiAgICAgICAgICAgICAgaW5mbGF0ZWRPYmplY3QgPSBQYXJzZS5PYmplY3QuZnJvbUpTT04oZmlyc3RSZXN1bHQpO1xuICAgICAgICAgICAgICByZXR1cm4gdHJpZ2dlcnMubWF5YmVSdW5UcmlnZ2VyKFxuICAgICAgICAgICAgICAgIHRyaWdnZXJzLlR5cGVzLmJlZm9yZURlbGV0ZSxcbiAgICAgICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgICAgIGluZmxhdGVkT2JqZWN0LFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgICAgIGNvbnRleHRcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnT2JqZWN0IG5vdCBmb3VuZCBmb3IgZGVsZXRlLicpO1xuICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICBpZiAoIWF1dGguaXNNYXN0ZXIpIHtcbiAgICAgICAgcmV0dXJuIGF1dGguZ2V0VXNlclJvbGVzKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiBjb25maWcuZGF0YWJhc2UubG9hZFNjaGVtYSgpKVxuICAgIC50aGVuKHMgPT4ge1xuICAgICAgc2NoZW1hQ29udHJvbGxlciA9IHM7XG4gICAgICBjb25zdCBvcHRpb25zID0ge307XG4gICAgICBpZiAoIWF1dGguaXNNYXN0ZXIpIHtcbiAgICAgICAgb3B0aW9ucy5hY2wgPSBbJyonXTtcbiAgICAgICAgaWYgKGF1dGgudXNlcikge1xuICAgICAgICAgIG9wdGlvbnMuYWNsLnB1c2goYXV0aC51c2VyLmlkKTtcbiAgICAgICAgICBvcHRpb25zLmFjbCA9IG9wdGlvbnMuYWNsLmNvbmNhdChhdXRoLnVzZXJSb2xlcyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNvbmZpZy5kYXRhYmFzZS5kZXN0cm95KFxuICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgIHtcbiAgICAgICAgICBvYmplY3RJZDogb2JqZWN0SWQsXG4gICAgICAgIH0sXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIHNjaGVtYUNvbnRyb2xsZXJcbiAgICAgICk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICAvLyBOb3RpZnkgTGl2ZVF1ZXJ5IHNlcnZlciBpZiBwb3NzaWJsZVxuICAgICAgY29uc3QgcGVybXMgPSBzY2hlbWFDb250cm9sbGVyLmdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyhjbGFzc05hbWUpO1xuICAgICAgY29uZmlnLmxpdmVRdWVyeUNvbnRyb2xsZXIub25BZnRlckRlbGV0ZShjbGFzc05hbWUsIGluZmxhdGVkT2JqZWN0LCBudWxsLCBwZXJtcyk7XG4gICAgICByZXR1cm4gdHJpZ2dlcnMubWF5YmVSdW5UcmlnZ2VyKFxuICAgICAgICB0cmlnZ2Vycy5UeXBlcy5hZnRlckRlbGV0ZSxcbiAgICAgICAgYXV0aCxcbiAgICAgICAgaW5mbGF0ZWRPYmplY3QsXG4gICAgICAgIG51bGwsXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgY29udGV4dFxuICAgICAgKTtcbiAgICB9KVxuICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICBoYW5kbGVTZXNzaW9uTWlzc2luZ0Vycm9yKGVycm9yLCBjbGFzc05hbWUsIGF1dGgpO1xuICAgIH0pO1xufVxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYSB7cmVzcG9uc2UsIHN0YXR1cywgbG9jYXRpb259IG9iamVjdC5cbmZ1bmN0aW9uIGNyZWF0ZShjb25maWcsIGF1dGgsIGNsYXNzTmFtZSwgcmVzdE9iamVjdCwgY2xpZW50U0RLLCBjb250ZXh0KSB7XG4gIGVuZm9yY2VSb2xlU2VjdXJpdHkoJ2NyZWF0ZScsIGNsYXNzTmFtZSwgYXV0aCk7XG4gIHZhciB3cml0ZSA9IG5ldyBSZXN0V3JpdGUoY29uZmlnLCBhdXRoLCBjbGFzc05hbWUsIG51bGwsIHJlc3RPYmplY3QsIG51bGwsIGNsaWVudFNESywgY29udGV4dCk7XG4gIHJldHVybiB3cml0ZS5leGVjdXRlKCk7XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgY29udGFpbnMgdGhlIGZpZWxkcyBvZiB0aGUgdXBkYXRlIHRoYXQgdGhlXG4vLyBSRVNUIEFQSSBpcyBzdXBwb3NlZCB0byByZXR1cm4uXG4vLyBVc3VhbGx5LCB0aGlzIGlzIGp1c3QgdXBkYXRlZEF0LlxuZnVuY3Rpb24gdXBkYXRlKGNvbmZpZywgYXV0aCwgY2xhc3NOYW1lLCByZXN0V2hlcmUsIHJlc3RPYmplY3QsIGNsaWVudFNESywgY29udGV4dCkge1xuICBlbmZvcmNlUm9sZVNlY3VyaXR5KCd1cGRhdGUnLCBjbGFzc05hbWUsIGF1dGgpO1xuXG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIGNvbnN0IGhhc1RyaWdnZXJzID0gY2hlY2tUcmlnZ2VycyhjbGFzc05hbWUsIGNvbmZpZywgWydiZWZvcmVTYXZlJywgJ2FmdGVyU2F2ZSddKTtcbiAgICAgIGNvbnN0IGhhc0xpdmVRdWVyeSA9IGNoZWNrTGl2ZVF1ZXJ5KGNsYXNzTmFtZSwgY29uZmlnKTtcbiAgICAgIGlmIChoYXNUcmlnZ2VycyB8fCBoYXNMaXZlUXVlcnkpIHtcbiAgICAgICAgLy8gRG8gbm90IHVzZSBmaW5kLCBhcyBpdCBydW5zIHRoZSBiZWZvcmUgZmluZHNcbiAgICAgICAgcmV0dXJuIG5ldyBSZXN0UXVlcnkoXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIGF1dGgsXG4gICAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICAgIHJlc3RXaGVyZSxcbiAgICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgIGNvbnRleHRcbiAgICAgICAgKS5leGVjdXRlKHtcbiAgICAgICAgICBvcDogJ3VwZGF0ZScsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gICAgfSlcbiAgICAudGhlbigoeyByZXN1bHRzIH0pID0+IHtcbiAgICAgIHZhciBvcmlnaW5hbFJlc3RPYmplY3Q7XG4gICAgICBpZiAocmVzdWx0cyAmJiByZXN1bHRzLmxlbmd0aCkge1xuICAgICAgICBvcmlnaW5hbFJlc3RPYmplY3QgPSByZXN1bHRzWzBdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5ldyBSZXN0V3JpdGUoXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgYXV0aCxcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICByZXN0V2hlcmUsXG4gICAgICAgIHJlc3RPYmplY3QsXG4gICAgICAgIG9yaWdpbmFsUmVzdE9iamVjdCxcbiAgICAgICAgY2xpZW50U0RLLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgICAndXBkYXRlJ1xuICAgICAgKS5leGVjdXRlKCk7XG4gICAgfSlcbiAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgaGFuZGxlU2Vzc2lvbk1pc3NpbmdFcnJvcihlcnJvciwgY2xhc3NOYW1lLCBhdXRoKTtcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gaGFuZGxlU2Vzc2lvbk1pc3NpbmdFcnJvcihlcnJvciwgY2xhc3NOYW1lLCBhdXRoKSB7XG4gIC8vIElmIHdlJ3JlIHRyeWluZyB0byB1cGRhdGUgYSB1c2VyIHdpdGhvdXQgLyB3aXRoIGJhZCBzZXNzaW9uIHRva2VuXG4gIGlmIChjbGFzc05hbWUgPT09ICdfVXNlcicgJiYgZXJyb3IuY29kZSA9PT0gUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCAmJiAhYXV0aC5pc01hc3Rlcikge1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5TRVNTSU9OX01JU1NJTkcsICdJbnN1ZmZpY2llbnQgYXV0aC4nKTtcbiAgfVxuICB0aHJvdyBlcnJvcjtcbn1cblxuY29uc3QgY2xhc3Nlc1dpdGhNYXN0ZXJPbmx5QWNjZXNzID0gW1xuICAnX0pvYlN0YXR1cycsXG4gICdfUHVzaFN0YXR1cycsXG4gICdfSG9va3MnLFxuICAnX0dsb2JhbENvbmZpZycsXG4gICdfSm9iU2NoZWR1bGUnLFxuICAnX0lkZW1wb3RlbmN5Jyxcbl07XG4vLyBEaXNhbGxvd2luZyBhY2Nlc3MgdG8gdGhlIF9Sb2xlIGNvbGxlY3Rpb24gZXhjZXB0IGJ5IG1hc3RlciBrZXlcbmZ1bmN0aW9uIGVuZm9yY2VSb2xlU2VjdXJpdHkobWV0aG9kLCBjbGFzc05hbWUsIGF1dGgpIHtcbiAgaWYgKGNsYXNzTmFtZSA9PT0gJ19JbnN0YWxsYXRpb24nICYmICFhdXRoLmlzTWFzdGVyKSB7XG4gICAgaWYgKG1ldGhvZCA9PT0gJ2RlbGV0ZScgfHwgbWV0aG9kID09PSAnZmluZCcpIHtcbiAgICAgIGNvbnN0IGVycm9yID0gYENsaWVudHMgYXJlbid0IGFsbG93ZWQgdG8gcGVyZm9ybSB0aGUgJHttZXRob2R9IG9wZXJhdGlvbiBvbiB0aGUgaW5zdGFsbGF0aW9uIGNvbGxlY3Rpb24uYDtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLCBlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgLy9hbGwgdm9sYXRpbGVDbGFzc2VzIGFyZSBtYXN0ZXJLZXkgb25seVxuICBpZiAoY2xhc3Nlc1dpdGhNYXN0ZXJPbmx5QWNjZXNzLmluZGV4T2YoY2xhc3NOYW1lKSA+PSAwICYmICFhdXRoLmlzTWFzdGVyKSB7XG4gICAgY29uc3QgZXJyb3IgPSBgQ2xpZW50cyBhcmVuJ3QgYWxsb3dlZCB0byBwZXJmb3JtIHRoZSAke21ldGhvZH0gb3BlcmF0aW9uIG9uIHRoZSAke2NsYXNzTmFtZX0gY29sbGVjdGlvbi5gO1xuICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLCBlcnJvcik7XG4gIH1cblxuICAvLyByZWFkT25seSBtYXN0ZXJLZXkgaXMgbm90IGFsbG93ZWRcbiAgaWYgKGF1dGguaXNSZWFkT25seSAmJiAobWV0aG9kID09PSAnZGVsZXRlJyB8fCBtZXRob2QgPT09ICdjcmVhdGUnIHx8IG1ldGhvZCA9PT0gJ3VwZGF0ZScpKSB7XG4gICAgY29uc3QgZXJyb3IgPSBgcmVhZC1vbmx5IG1hc3RlcktleSBpc24ndCBhbGxvd2VkIHRvIHBlcmZvcm0gdGhlICR7bWV0aG9kfSBvcGVyYXRpb24uYDtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTiwgZXJyb3IpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBjcmVhdGUsXG4gIGRlbCxcbiAgZmluZCxcbiAgZ2V0LFxuICB1cGRhdGUsXG59O1xuIl19 \ No newline at end of file diff --git a/lib/triggers.js b/lib/triggers.js deleted file mode 100644 index 094d75346c..0000000000 --- a/lib/triggers.js +++ /dev/null @@ -1,1032 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.addFunction = addFunction; -exports.addJob = addJob; -exports.addTrigger = addTrigger; -exports.addFileTrigger = addFileTrigger; -exports.addConnectTrigger = addConnectTrigger; -exports.addLiveQueryEventHandler = addLiveQueryEventHandler; -exports.removeFunction = removeFunction; -exports.removeTrigger = removeTrigger; -exports._unregisterAll = _unregisterAll; -exports.getTrigger = getTrigger; -exports.getFileTrigger = getFileTrigger; -exports.triggerExists = triggerExists; -exports.getFunction = getFunction; -exports.getFunctionNames = getFunctionNames; -exports.getJob = getJob; -exports.getJobs = getJobs; -exports.getValidator = getValidator; -exports.getRequestObject = getRequestObject; -exports.getRequestQueryObject = getRequestQueryObject; -exports.getResponseObject = getResponseObject; -exports.maybeRunAfterFindTrigger = maybeRunAfterFindTrigger; -exports.maybeRunQueryTrigger = maybeRunQueryTrigger; -exports.resolveError = resolveError; -exports.maybeRunValidator = maybeRunValidator; -exports.maybeRunTrigger = maybeRunTrigger; -exports.inflate = inflate; -exports.runLiveQueryEventHandlers = runLiveQueryEventHandlers; -exports.getRequestFileObject = getRequestFileObject; -exports.maybeRunFileTrigger = maybeRunFileTrigger; -exports.maybeRunConnectTrigger = maybeRunConnectTrigger; -exports.maybeRunSubscribeTrigger = maybeRunSubscribeTrigger; -exports.maybeRunAfterEventTrigger = maybeRunAfterEventTrigger; -exports.Types = void 0; - -var _node = _interopRequireDefault(require("parse/node")); - -var _logger = require("./logger"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -const Types = { - beforeLogin: 'beforeLogin', - afterLogin: 'afterLogin', - afterLogout: 'afterLogout', - beforeSave: 'beforeSave', - afterSave: 'afterSave', - beforeDelete: 'beforeDelete', - afterDelete: 'afterDelete', - beforeFind: 'beforeFind', - afterFind: 'afterFind', - beforeSaveFile: 'beforeSaveFile', - afterSaveFile: 'afterSaveFile', - beforeDeleteFile: 'beforeDeleteFile', - afterDeleteFile: 'afterDeleteFile', - beforeConnect: 'beforeConnect', - beforeSubscribe: 'beforeSubscribe', - afterEvent: 'afterEvent' -}; -exports.Types = Types; -const FileClassName = '@File'; -const ConnectClassName = '@Connect'; - -const baseStore = function () { - const Validators = Object.keys(Types).reduce(function (base, key) { - base[key] = {}; - return base; - }, {}); - const Functions = {}; - const Jobs = {}; - const LiveQuery = []; - const Triggers = Object.keys(Types).reduce(function (base, key) { - base[key] = {}; - return base; - }, {}); - return Object.freeze({ - Functions, - Jobs, - Validators, - Triggers, - LiveQuery - }); -}; - -function validateClassNameForTriggers(className, type) { - if (type == Types.beforeSave && className === '_PushStatus') { - // _PushStatus uses undocumented nested key increment ops - // allowing beforeSave would mess up the objects big time - // TODO: Allow proper documented way of using nested increment ops - throw 'Only afterSave is allowed on _PushStatus'; - } - - if ((type === Types.beforeLogin || type === Types.afterLogin) && className !== '_User') { - // TODO: check if upstream code will handle `Error` instance rather - // than this anti-pattern of throwing strings - throw 'Only the _User class is allowed for the beforeLogin and afterLogin triggers'; - } - - if (type === Types.afterLogout && className !== '_Session') { - // TODO: check if upstream code will handle `Error` instance rather - // than this anti-pattern of throwing strings - throw 'Only the _Session class is allowed for the afterLogout trigger.'; - } - - if (className === '_Session' && type !== Types.afterLogout) { - // TODO: check if upstream code will handle `Error` instance rather - // than this anti-pattern of throwing strings - throw 'Only the afterLogout trigger is allowed for the _Session class.'; - } - - return className; -} - -const _triggerStore = {}; -const Category = { - Functions: 'Functions', - Validators: 'Validators', - Jobs: 'Jobs', - Triggers: 'Triggers' -}; - -function getStore(category, name, applicationId) { - const path = name.split('.'); - path.splice(-1); // remove last component - - applicationId = applicationId || _node.default.applicationId; - _triggerStore[applicationId] = _triggerStore[applicationId] || baseStore(); - let store = _triggerStore[applicationId][category]; - - for (const component of path) { - store = store[component]; - - if (!store) { - return undefined; - } - } - - return store; -} - -function add(category, name, handler, applicationId) { - const lastComponent = name.split('.').splice(-1); - const store = getStore(category, name, applicationId); - - if (store[lastComponent]) { - _logger.logger.warn(`Warning: Duplicate cloud functions exist for ${lastComponent}. Only the last one will be used and the others will be ignored.`); - } - - store[lastComponent] = handler; -} - -function remove(category, name, applicationId) { - const lastComponent = name.split('.').splice(-1); - const store = getStore(category, name, applicationId); - delete store[lastComponent]; -} - -function get(category, name, applicationId) { - const lastComponent = name.split('.').splice(-1); - const store = getStore(category, name, applicationId); - return store[lastComponent]; -} - -function addFunction(functionName, handler, validationHandler, applicationId) { - add(Category.Functions, functionName, handler, applicationId); - add(Category.Validators, functionName, validationHandler, applicationId); -} - -function addJob(jobName, handler, applicationId) { - add(Category.Jobs, jobName, handler, applicationId); -} - -function addTrigger(type, className, handler, applicationId, validationHandler) { - validateClassNameForTriggers(className, type); - add(Category.Triggers, `${type}.${className}`, handler, applicationId); - add(Category.Validators, `${type}.${className}`, validationHandler, applicationId); -} - -function addFileTrigger(type, handler, applicationId, validationHandler) { - add(Category.Triggers, `${type}.${FileClassName}`, handler, applicationId); - add(Category.Validators, `${type}.${FileClassName}`, validationHandler, applicationId); -} - -function addConnectTrigger(type, handler, applicationId, validationHandler) { - add(Category.Triggers, `${type}.${ConnectClassName}`, handler, applicationId); - add(Category.Validators, `${type}.${ConnectClassName}`, validationHandler, applicationId); -} - -function addLiveQueryEventHandler(handler, applicationId) { - applicationId = applicationId || _node.default.applicationId; - _triggerStore[applicationId] = _triggerStore[applicationId] || baseStore(); - - _triggerStore[applicationId].LiveQuery.push(handler); -} - -function removeFunction(functionName, applicationId) { - remove(Category.Functions, functionName, applicationId); -} - -function removeTrigger(type, className, applicationId) { - remove(Category.Triggers, `${type}.${className}`, applicationId); -} - -function _unregisterAll() { - Object.keys(_triggerStore).forEach(appId => delete _triggerStore[appId]); -} - -function getTrigger(className, triggerType, applicationId) { - if (!applicationId) { - throw 'Missing ApplicationID'; - } - - return get(Category.Triggers, `${triggerType}.${className}`, applicationId); -} - -function getFileTrigger(type, applicationId) { - return getTrigger(FileClassName, type, applicationId); -} - -function triggerExists(className, type, applicationId) { - return getTrigger(className, type, applicationId) != undefined; -} - -function getFunction(functionName, applicationId) { - return get(Category.Functions, functionName, applicationId); -} - -function getFunctionNames(applicationId) { - const store = _triggerStore[applicationId] && _triggerStore[applicationId][Category.Functions] || {}; - const functionNames = []; - - const extractFunctionNames = (namespace, store) => { - Object.keys(store).forEach(name => { - const value = store[name]; - - if (namespace) { - name = `${namespace}.${name}`; - } - - if (typeof value === 'function') { - functionNames.push(name); - } else { - extractFunctionNames(name, value); - } - }); - }; - - extractFunctionNames(null, store); - return functionNames; -} - -function getJob(jobName, applicationId) { - return get(Category.Jobs, jobName, applicationId); -} - -function getJobs(applicationId) { - var manager = _triggerStore[applicationId]; - - if (manager && manager.Jobs) { - return manager.Jobs; - } - - return undefined; -} - -function getValidator(functionName, applicationId) { - return get(Category.Validators, functionName, applicationId); -} - -function getRequestObject(triggerType, auth, parseObject, originalParseObject, config, context) { - const request = { - triggerName: triggerType, - object: parseObject, - master: false, - log: config.loggerController, - headers: config.headers, - ip: config.ip - }; - - if (originalParseObject) { - request.original = originalParseObject; - } - - if (triggerType === Types.beforeSave || triggerType === Types.afterSave || triggerType === Types.beforeDelete || triggerType === Types.afterDelete || triggerType === Types.afterFind) { - // Set a copy of the context on the request object. - request.context = Object.assign({}, context); - } - - if (!auth) { - return request; - } - - if (auth.isMaster) { - request['master'] = true; - } - - if (auth.user) { - request['user'] = auth.user; - } - - if (auth.installationId) { - request['installationId'] = auth.installationId; - } - - return request; -} - -function getRequestQueryObject(triggerType, auth, query, count, config, context, isGet) { - isGet = !!isGet; - var request = { - triggerName: triggerType, - query, - master: false, - count, - log: config.loggerController, - isGet, - headers: config.headers, - ip: config.ip, - context: context || {} - }; - - if (!auth) { - return request; - } - - if (auth.isMaster) { - request['master'] = true; - } - - if (auth.user) { - request['user'] = auth.user; - } - - if (auth.installationId) { - request['installationId'] = auth.installationId; - } - - return request; -} // Creates the response object, and uses the request object to pass data -// The API will call this with REST API formatted objects, this will -// transform them to Parse.Object instances expected by Cloud Code. -// Any changes made to the object in a beforeSave will be included. - - -function getResponseObject(request, resolve, reject) { - return { - success: function (response) { - if (request.triggerName === Types.afterFind) { - if (!response) { - response = request.objects; - } - - response = response.map(object => { - return object.toJSON(); - }); - return resolve(response); - } // Use the JSON response - - - if (response && typeof response === 'object' && !request.object.equals(response) && request.triggerName === Types.beforeSave) { - return resolve(response); - } - - if (response && typeof response === 'object' && request.triggerName === Types.afterSave) { - return resolve(response); - } - - if (request.triggerName === Types.afterSave) { - return resolve(); - } - - response = {}; - - if (request.triggerName === Types.beforeSave) { - response['object'] = request.object._getSaveJSON(); - } - - return resolve(response); - }, - error: function (error) { - const e = resolveError(error, { - code: _node.default.Error.SCRIPT_FAILED, - message: 'Script failed. Unknown error.' - }); - reject(e); - } - }; -} - -function userIdForLog(auth) { - return auth && auth.user ? auth.user.id : undefined; -} - -function logTriggerAfterHook(triggerType, className, input, auth) { - const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(input)); - - _logger.logger.info(`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}`, { - className, - triggerType, - user: userIdForLog(auth) - }); -} - -function logTriggerSuccessBeforeHook(triggerType, className, input, result, auth) { - const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(input)); - - const cleanResult = _logger.logger.truncateLogMessage(JSON.stringify(result)); - - _logger.logger.info(`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Result: ${cleanResult}`, { - className, - triggerType, - user: userIdForLog(auth) - }); -} - -function logTriggerErrorBeforeHook(triggerType, className, input, auth, error) { - const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(input)); - - _logger.logger.error(`${triggerType} failed for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Error: ${JSON.stringify(error)}`, { - className, - triggerType, - error, - user: userIdForLog(auth) - }); -} - -function maybeRunAfterFindTrigger(triggerType, auth, className, objects, config, query, context) { - return new Promise((resolve, reject) => { - const trigger = getTrigger(className, triggerType, config.applicationId); - - if (!trigger) { - return resolve(); - } - - const request = getRequestObject(triggerType, auth, null, null, config, context); - - if (query) { - request.query = query; - } - - const { - success, - error - } = getResponseObject(request, object => { - resolve(object); - }, error => { - reject(error); - }); - logTriggerSuccessBeforeHook(triggerType, className, 'AfterFind', JSON.stringify(objects), auth); - request.objects = objects.map(object => { - //setting the class name to transform into parse object - object.className = className; - return _node.default.Object.fromJSON(object); - }); - return Promise.resolve().then(() => { - return maybeRunValidator(request, `${triggerType}.${className}`); - }).then(() => { - if (request.skipWithMasterKey) { - return request.objects; - } - - const response = trigger(request); - - if (response && typeof response.then === 'function') { - return response.then(results => { - if (!results) { - throw new _node.default.Error(_node.default.Error.SCRIPT_FAILED, 'AfterFind expect results to be returned in the promise'); - } - - return results; - }); - } - - return response; - }).then(success, error); - }).then(results => { - logTriggerAfterHook(triggerType, className, JSON.stringify(results), auth); - return results; - }); -} - -function maybeRunQueryTrigger(triggerType, className, restWhere, restOptions, config, auth, context, isGet) { - const trigger = getTrigger(className, triggerType, config.applicationId); - - if (!trigger) { - return Promise.resolve({ - restWhere, - restOptions - }); - } - - const json = Object.assign({}, restOptions); - json.where = restWhere; - const parseQuery = new _node.default.Query(className); - parseQuery.withJSON(json); - let count = false; - - if (restOptions) { - count = !!restOptions.count; - } - - const requestObject = getRequestQueryObject(triggerType, auth, parseQuery, count, config, context, isGet); - return Promise.resolve().then(() => { - return maybeRunValidator(requestObject, `${triggerType}.${className}`); - }).then(() => { - if (requestObject.skipWithMasterKey) { - return requestObject.query; - } - - return trigger(requestObject); - }).then(result => { - let queryResult = parseQuery; - - if (result && result instanceof _node.default.Query) { - queryResult = result; - } - - const jsonQuery = queryResult.toJSON(); - - if (jsonQuery.where) { - restWhere = jsonQuery.where; - } - - if (jsonQuery.limit) { - restOptions = restOptions || {}; - restOptions.limit = jsonQuery.limit; - } - - if (jsonQuery.skip) { - restOptions = restOptions || {}; - restOptions.skip = jsonQuery.skip; - } - - if (jsonQuery.include) { - restOptions = restOptions || {}; - restOptions.include = jsonQuery.include; - } - - if (jsonQuery.excludeKeys) { - restOptions = restOptions || {}; - restOptions.excludeKeys = jsonQuery.excludeKeys; - } - - if (jsonQuery.explain) { - restOptions = restOptions || {}; - restOptions.explain = jsonQuery.explain; - } - - if (jsonQuery.keys) { - restOptions = restOptions || {}; - restOptions.keys = jsonQuery.keys; - } - - if (jsonQuery.order) { - restOptions = restOptions || {}; - restOptions.order = jsonQuery.order; - } - - if (jsonQuery.hint) { - restOptions = restOptions || {}; - restOptions.hint = jsonQuery.hint; - } - - if (requestObject.readPreference) { - restOptions = restOptions || {}; - restOptions.readPreference = requestObject.readPreference; - } - - if (requestObject.includeReadPreference) { - restOptions = restOptions || {}; - restOptions.includeReadPreference = requestObject.includeReadPreference; - } - - if (requestObject.subqueryReadPreference) { - restOptions = restOptions || {}; - restOptions.subqueryReadPreference = requestObject.subqueryReadPreference; - } - - return { - restWhere, - restOptions - }; - }, err => { - const error = resolveError(err, { - code: _node.default.Error.SCRIPT_FAILED, - message: 'Script failed. Unknown error.' - }); - throw error; - }); -} - -function resolveError(message, defaultOpts) { - if (!defaultOpts) { - defaultOpts = {}; - } - - if (!message) { - return new _node.default.Error(defaultOpts.code || _node.default.Error.SCRIPT_FAILED, defaultOpts.message || 'Script failed.'); - } - - if (message instanceof _node.default.Error) { - return message; - } - - const code = defaultOpts.code || _node.default.Error.SCRIPT_FAILED; // If it's an error, mark it as a script failed - - if (typeof message === 'string') { - return new _node.default.Error(code, message); - } - - const error = new _node.default.Error(code, message.message || message); - - if (message instanceof Error) { - error.stack = message.stack; - } - - return error; -} - -function maybeRunValidator(request, functionName) { - const theValidator = getValidator(functionName, _node.default.applicationId); - - if (!theValidator) { - return; - } - - if (typeof theValidator === 'object' && theValidator.skipWithMasterKey && request.master) { - request.skipWithMasterKey = true; - } - - return new Promise((resolve, reject) => { - return Promise.resolve().then(() => { - return typeof theValidator === 'object' ? builtInTriggerValidator(theValidator, request) : theValidator(request); - }).then(() => { - resolve(); - }).catch(e => { - const error = resolveError(e, { - code: _node.default.Error.VALIDATION_ERROR, - message: 'Validation failed.' - }); - reject(error); - }); - }); -} - -function builtInTriggerValidator(options, request) { - if (request.master && !options.validateMasterKey) { - return; - } - - let reqUser = request.user; - - if (!reqUser && request.object && request.object.className === '_User' && !request.object.existed()) { - reqUser = request.object; - } - - if (options.requireUser && !reqUser) { - throw 'Validation failed. Please login to continue.'; - } - - if (options.requireMaster && !request.master) { - throw 'Validation failed. Master key is required to complete this request.'; - } - - let params = request.params || {}; - - if (request.object) { - params = request.object.toJSON(); - } - - const requiredParam = key => { - const value = params[key]; - - if (value == null) { - throw `Validation failed. Please specify data for ${key}.`; - } - }; - - const validateOptions = (opt, key, val) => { - let opts = opt.options; - - if (typeof opts === 'function') { - try { - const result = opts(val); - - if (!result && result != null) { - throw opt.error || `Validation failed. Invalid value for ${key}.`; - } - } catch (e) { - if (!e) { - throw opt.error || `Validation failed. Invalid value for ${key}.`; - } - - throw opt.error || e.message || e; - } - - return; - } - - if (!Array.isArray(opts)) { - opts = [opt.options]; - } - - if (!opts.includes(val)) { - throw opt.error || `Validation failed. Invalid option for ${key}. Expected: ${opts.join(', ')}`; - } - }; - - const getType = fn => { - const match = fn && fn.toString().match(/^\s*function (\w+)/); - return (match ? match[1] : '').toLowerCase(); - }; - - if (Array.isArray(options.fields)) { - for (const key of options.fields) { - requiredParam(key); - } - } else { - for (const key in options.fields) { - const opt = options.fields[key]; - let val = params[key]; - - if (typeof opt === 'string') { - requiredParam(opt); - } - - if (typeof opt === 'object') { - if (opt.default != null && val == null) { - val = opt.default; - params[key] = val; - - if (request.object) { - request.object.set(key, val); - } - } - - if (opt.constant && request.object) { - if (request.original) { - request.object.set(key, request.original.get(key)); - } else if (opt.default != null) { - request.object.set(key, opt.default); - } - } - - if (opt.required) { - requiredParam(key); - } - - if (opt.type) { - const type = getType(opt.type); - - if (type == 'array' && !Array.isArray(val)) { - throw `Validation failed. Invalid type for ${key}. Expected: array`; - } else if (typeof val !== type) { - throw `Validation failed. Invalid type for ${key}. Expected: ${type}`; - } - } - - if (opt.options) { - validateOptions(opt, key, val); - } - } - } - } - - const userKeys = options.requireUserKeys || []; - - if (Array.isArray(userKeys)) { - for (const key of userKeys) { - if (!reqUser) { - throw 'Please login to make this request.'; - } - - if (reqUser.get(key) == null) { - throw `Validation failed. Please set data for ${key} on your account.`; - } - } - } else if (typeof userKeys === 'object') { - for (const key in options.requireUserKeys) { - const opt = options.requireUserKeys[key]; - - if (opt.options) { - validateOptions(opt, key, reqUser.get(key)); - } - } - } -} // To be used as part of the promise chain when saving/deleting an object -// Will resolve successfully if no trigger is configured -// Resolves to an object, empty or containing an object key. A beforeSave -// trigger will set the object key to the rest format object to save. -// originalParseObject is optional, we only need that for before/afterSave functions - - -function maybeRunTrigger(triggerType, auth, parseObject, originalParseObject, config, context) { - if (!parseObject) { - return Promise.resolve({}); - } - - return new Promise(function (resolve, reject) { - var trigger = getTrigger(parseObject.className, triggerType, config.applicationId); - if (!trigger) return resolve(); - var request = getRequestObject(triggerType, auth, parseObject, originalParseObject, config, context); - var { - success, - error - } = getResponseObject(request, object => { - logTriggerSuccessBeforeHook(triggerType, parseObject.className, parseObject.toJSON(), object, auth); - - if (triggerType === Types.beforeSave || triggerType === Types.afterSave || triggerType === Types.beforeDelete || triggerType === Types.afterDelete) { - Object.assign(context, request.context); - } - - resolve(object); - }, error => { - logTriggerErrorBeforeHook(triggerType, parseObject.className, parseObject.toJSON(), auth, error); - reject(error); - }); // AfterSave and afterDelete triggers can return a promise, which if they - // do, needs to be resolved before this promise is resolved, - // so trigger execution is synced with RestWrite.execute() call. - // If triggers do not return a promise, they can run async code parallel - // to the RestWrite.execute() call. - - return Promise.resolve().then(() => { - return maybeRunValidator(request, `${triggerType}.${parseObject.className}`); - }).then(() => { - if (request.skipWithMasterKey) { - return Promise.resolve(); - } - - const promise = trigger(request); - - if (triggerType === Types.afterSave || triggerType === Types.afterDelete || triggerType === Types.afterLogin) { - logTriggerAfterHook(triggerType, parseObject.className, parseObject.toJSON(), auth); - } // beforeSave is expected to return null (nothing) - - - if (triggerType === Types.beforeSave) { - if (promise && typeof promise.then === 'function') { - return promise.then(response => { - // response.object may come from express routing before hook - if (response && response.object) { - return response; - } - - return null; - }); - } - - return null; - } - - return promise; - }).then(success, error); - }); -} // Converts a REST-format object to a Parse.Object -// data is either className or an object - - -function inflate(data, restObject) { - var copy = typeof data == 'object' ? data : { - className: data - }; - - for (var key in restObject) { - copy[key] = restObject[key]; - } - - return _node.default.Object.fromJSON(copy); -} - -function runLiveQueryEventHandlers(data, applicationId = _node.default.applicationId) { - if (!_triggerStore || !_triggerStore[applicationId] || !_triggerStore[applicationId].LiveQuery) { - return; - } - - _triggerStore[applicationId].LiveQuery.forEach(handler => handler(data)); -} - -function getRequestFileObject(triggerType, auth, fileObject, config) { - const request = _objectSpread(_objectSpread({}, fileObject), {}, { - triggerName: triggerType, - master: false, - log: config.loggerController, - headers: config.headers, - ip: config.ip - }); - - if (!auth) { - return request; - } - - if (auth.isMaster) { - request['master'] = true; - } - - if (auth.user) { - request['user'] = auth.user; - } - - if (auth.installationId) { - request['installationId'] = auth.installationId; - } - - return request; -} - -async function maybeRunFileTrigger(triggerType, fileObject, config, auth) { - const fileTrigger = getFileTrigger(triggerType, config.applicationId); - - if (typeof fileTrigger === 'function') { - try { - const request = getRequestFileObject(triggerType, auth, fileObject, config); - await maybeRunValidator(request, `${triggerType}.${FileClassName}`); - - if (request.skipWithMasterKey) { - return fileObject; - } - - const result = await fileTrigger(request); - logTriggerSuccessBeforeHook(triggerType, 'Parse.File', _objectSpread(_objectSpread({}, fileObject.file.toJSON()), {}, { - fileSize: fileObject.fileSize - }), result, auth); - return result || fileObject; - } catch (error) { - logTriggerErrorBeforeHook(triggerType, 'Parse.File', _objectSpread(_objectSpread({}, fileObject.file.toJSON()), {}, { - fileSize: fileObject.fileSize - }), auth, error); - throw error; - } - } - - return fileObject; -} - -async function maybeRunConnectTrigger(triggerType, request) { - const trigger = getTrigger(ConnectClassName, triggerType, _node.default.applicationId); - - if (!trigger) { - return; - } - - request.user = await userForSessionToken(request.sessionToken); - await maybeRunValidator(request, `${triggerType}.${ConnectClassName}`); - - if (request.skipWithMasterKey) { - return; - } - - return trigger(request); -} - -async function maybeRunSubscribeTrigger(triggerType, className, request) { - const trigger = getTrigger(className, triggerType, _node.default.applicationId); - - if (!trigger) { - return; - } - - const parseQuery = new _node.default.Query(className); - parseQuery.withJSON(request.query); - request.query = parseQuery; - request.user = await userForSessionToken(request.sessionToken); - await maybeRunValidator(request, `${triggerType}.${className}`); - - if (request.skipWithMasterKey) { - return; - } - - await trigger(request); - const query = request.query.toJSON(); - - if (query.keys) { - query.fields = query.keys.split(','); - } - - request.query = query; -} - -async function maybeRunAfterEventTrigger(triggerType, className, request) { - const trigger = getTrigger(className, triggerType, _node.default.applicationId); - - if (!trigger) { - return; - } - - if (request.object) { - request.object = _node.default.Object.fromJSON(request.object); - } - - if (request.original) { - request.original = _node.default.Object.fromJSON(request.original); - } - - request.user = await userForSessionToken(request.sessionToken); - await maybeRunValidator(request, `${triggerType}.${className}`); - - if (request.skipWithMasterKey) { - return; - } - - return trigger(request); -} - -async function userForSessionToken(sessionToken) { - if (!sessionToken) { - return; - } - - const q = new _node.default.Query('_Session'); - q.equalTo('sessionToken', sessionToken); - q.include('user'); - const session = await q.first({ - useMasterKey: true - }); - - if (!session) { - return; - } - - return session.get('user'); -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy90cmlnZ2Vycy5qcyJdLCJuYW1lcyI6WyJUeXBlcyIsImJlZm9yZUxvZ2luIiwiYWZ0ZXJMb2dpbiIsImFmdGVyTG9nb3V0IiwiYmVmb3JlU2F2ZSIsImFmdGVyU2F2ZSIsImJlZm9yZURlbGV0ZSIsImFmdGVyRGVsZXRlIiwiYmVmb3JlRmluZCIsImFmdGVyRmluZCIsImJlZm9yZVNhdmVGaWxlIiwiYWZ0ZXJTYXZlRmlsZSIsImJlZm9yZURlbGV0ZUZpbGUiLCJhZnRlckRlbGV0ZUZpbGUiLCJiZWZvcmVDb25uZWN0IiwiYmVmb3JlU3Vic2NyaWJlIiwiYWZ0ZXJFdmVudCIsIkZpbGVDbGFzc05hbWUiLCJDb25uZWN0Q2xhc3NOYW1lIiwiYmFzZVN0b3JlIiwiVmFsaWRhdG9ycyIsIk9iamVjdCIsImtleXMiLCJyZWR1Y2UiLCJiYXNlIiwia2V5IiwiRnVuY3Rpb25zIiwiSm9icyIsIkxpdmVRdWVyeSIsIlRyaWdnZXJzIiwiZnJlZXplIiwidmFsaWRhdGVDbGFzc05hbWVGb3JUcmlnZ2VycyIsImNsYXNzTmFtZSIsInR5cGUiLCJfdHJpZ2dlclN0b3JlIiwiQ2F0ZWdvcnkiLCJnZXRTdG9yZSIsImNhdGVnb3J5IiwibmFtZSIsImFwcGxpY2F0aW9uSWQiLCJwYXRoIiwic3BsaXQiLCJzcGxpY2UiLCJQYXJzZSIsInN0b3JlIiwiY29tcG9uZW50IiwidW5kZWZpbmVkIiwiYWRkIiwiaGFuZGxlciIsImxhc3RDb21wb25lbnQiLCJsb2dnZXIiLCJ3YXJuIiwicmVtb3ZlIiwiZ2V0IiwiYWRkRnVuY3Rpb24iLCJmdW5jdGlvbk5hbWUiLCJ2YWxpZGF0aW9uSGFuZGxlciIsImFkZEpvYiIsImpvYk5hbWUiLCJhZGRUcmlnZ2VyIiwiYWRkRmlsZVRyaWdnZXIiLCJhZGRDb25uZWN0VHJpZ2dlciIsImFkZExpdmVRdWVyeUV2ZW50SGFuZGxlciIsInB1c2giLCJyZW1vdmVGdW5jdGlvbiIsInJlbW92ZVRyaWdnZXIiLCJfdW5yZWdpc3RlckFsbCIsImZvckVhY2giLCJhcHBJZCIsImdldFRyaWdnZXIiLCJ0cmlnZ2VyVHlwZSIsImdldEZpbGVUcmlnZ2VyIiwidHJpZ2dlckV4aXN0cyIsImdldEZ1bmN0aW9uIiwiZ2V0RnVuY3Rpb25OYW1lcyIsImZ1bmN0aW9uTmFtZXMiLCJleHRyYWN0RnVuY3Rpb25OYW1lcyIsIm5hbWVzcGFjZSIsInZhbHVlIiwiZ2V0Sm9iIiwiZ2V0Sm9icyIsIm1hbmFnZXIiLCJnZXRWYWxpZGF0b3IiLCJnZXRSZXF1ZXN0T2JqZWN0IiwiYXV0aCIsInBhcnNlT2JqZWN0Iiwib3JpZ2luYWxQYXJzZU9iamVjdCIsImNvbmZpZyIsImNvbnRleHQiLCJyZXF1ZXN0IiwidHJpZ2dlck5hbWUiLCJvYmplY3QiLCJtYXN0ZXIiLCJsb2ciLCJsb2dnZXJDb250cm9sbGVyIiwiaGVhZGVycyIsImlwIiwib3JpZ2luYWwiLCJhc3NpZ24iLCJpc01hc3RlciIsInVzZXIiLCJpbnN0YWxsYXRpb25JZCIsImdldFJlcXVlc3RRdWVyeU9iamVjdCIsInF1ZXJ5IiwiY291bnQiLCJpc0dldCIsImdldFJlc3BvbnNlT2JqZWN0IiwicmVzb2x2ZSIsInJlamVjdCIsInN1Y2Nlc3MiLCJyZXNwb25zZSIsIm9iamVjdHMiLCJtYXAiLCJ0b0pTT04iLCJlcXVhbHMiLCJfZ2V0U2F2ZUpTT04iLCJlcnJvciIsImUiLCJyZXNvbHZlRXJyb3IiLCJjb2RlIiwiRXJyb3IiLCJTQ1JJUFRfRkFJTEVEIiwibWVzc2FnZSIsInVzZXJJZEZvckxvZyIsImlkIiwibG9nVHJpZ2dlckFmdGVySG9vayIsImlucHV0IiwiY2xlYW5JbnB1dCIsInRydW5jYXRlTG9nTWVzc2FnZSIsIkpTT04iLCJzdHJpbmdpZnkiLCJpbmZvIiwibG9nVHJpZ2dlclN1Y2Nlc3NCZWZvcmVIb29rIiwicmVzdWx0IiwiY2xlYW5SZXN1bHQiLCJsb2dUcmlnZ2VyRXJyb3JCZWZvcmVIb29rIiwibWF5YmVSdW5BZnRlckZpbmRUcmlnZ2VyIiwiUHJvbWlzZSIsInRyaWdnZXIiLCJmcm9tSlNPTiIsInRoZW4iLCJtYXliZVJ1blZhbGlkYXRvciIsInNraXBXaXRoTWFzdGVyS2V5IiwicmVzdWx0cyIsIm1heWJlUnVuUXVlcnlUcmlnZ2VyIiwicmVzdFdoZXJlIiwicmVzdE9wdGlvbnMiLCJqc29uIiwid2hlcmUiLCJwYXJzZVF1ZXJ5IiwiUXVlcnkiLCJ3aXRoSlNPTiIsInJlcXVlc3RPYmplY3QiLCJxdWVyeVJlc3VsdCIsImpzb25RdWVyeSIsImxpbWl0Iiwic2tpcCIsImluY2x1ZGUiLCJleGNsdWRlS2V5cyIsImV4cGxhaW4iLCJvcmRlciIsImhpbnQiLCJyZWFkUHJlZmVyZW5jZSIsImluY2x1ZGVSZWFkUHJlZmVyZW5jZSIsInN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UiLCJlcnIiLCJkZWZhdWx0T3B0cyIsInN0YWNrIiwidGhlVmFsaWRhdG9yIiwiYnVpbHRJblRyaWdnZXJWYWxpZGF0b3IiLCJjYXRjaCIsIlZBTElEQVRJT05fRVJST1IiLCJvcHRpb25zIiwidmFsaWRhdGVNYXN0ZXJLZXkiLCJyZXFVc2VyIiwiZXhpc3RlZCIsInJlcXVpcmVVc2VyIiwicmVxdWlyZU1hc3RlciIsInBhcmFtcyIsInJlcXVpcmVkUGFyYW0iLCJ2YWxpZGF0ZU9wdGlvbnMiLCJvcHQiLCJ2YWwiLCJvcHRzIiwiQXJyYXkiLCJpc0FycmF5IiwiaW5jbHVkZXMiLCJqb2luIiwiZ2V0VHlwZSIsImZuIiwibWF0Y2giLCJ0b1N0cmluZyIsInRvTG93ZXJDYXNlIiwiZmllbGRzIiwiZGVmYXVsdCIsInNldCIsImNvbnN0YW50IiwicmVxdWlyZWQiLCJ1c2VyS2V5cyIsInJlcXVpcmVVc2VyS2V5cyIsIm1heWJlUnVuVHJpZ2dlciIsInByb21pc2UiLCJpbmZsYXRlIiwiZGF0YSIsInJlc3RPYmplY3QiLCJjb3B5IiwicnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyIsImdldFJlcXVlc3RGaWxlT2JqZWN0IiwiZmlsZU9iamVjdCIsIm1heWJlUnVuRmlsZVRyaWdnZXIiLCJmaWxlVHJpZ2dlciIsImZpbGUiLCJmaWxlU2l6ZSIsIm1heWJlUnVuQ29ubmVjdFRyaWdnZXIiLCJ1c2VyRm9yU2Vzc2lvblRva2VuIiwic2Vzc2lvblRva2VuIiwibWF5YmVSdW5TdWJzY3JpYmVUcmlnZ2VyIiwibWF5YmVSdW5BZnRlckV2ZW50VHJpZ2dlciIsInEiLCJlcXVhbFRvIiwic2Vzc2lvbiIsImZpcnN0IiwidXNlTWFzdGVyS2V5Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFDQTs7QUFDQTs7Ozs7Ozs7OztBQUVPLE1BQU1BLEtBQUssR0FBRztBQUNuQkMsRUFBQUEsV0FBVyxFQUFFLGFBRE07QUFFbkJDLEVBQUFBLFVBQVUsRUFBRSxZQUZPO0FBR25CQyxFQUFBQSxXQUFXLEVBQUUsYUFITTtBQUluQkMsRUFBQUEsVUFBVSxFQUFFLFlBSk87QUFLbkJDLEVBQUFBLFNBQVMsRUFBRSxXQUxRO0FBTW5CQyxFQUFBQSxZQUFZLEVBQUUsY0FOSztBQU9uQkMsRUFBQUEsV0FBVyxFQUFFLGFBUE07QUFRbkJDLEVBQUFBLFVBQVUsRUFBRSxZQVJPO0FBU25CQyxFQUFBQSxTQUFTLEVBQUUsV0FUUTtBQVVuQkMsRUFBQUEsY0FBYyxFQUFFLGdCQVZHO0FBV25CQyxFQUFBQSxhQUFhLEVBQUUsZUFYSTtBQVluQkMsRUFBQUEsZ0JBQWdCLEVBQUUsa0JBWkM7QUFhbkJDLEVBQUFBLGVBQWUsRUFBRSxpQkFiRTtBQWNuQkMsRUFBQUEsYUFBYSxFQUFFLGVBZEk7QUFlbkJDLEVBQUFBLGVBQWUsRUFBRSxpQkFmRTtBQWdCbkJDLEVBQUFBLFVBQVUsRUFBRTtBQWhCTyxDQUFkOztBQW1CUCxNQUFNQyxhQUFhLEdBQUcsT0FBdEI7QUFDQSxNQUFNQyxnQkFBZ0IsR0FBRyxVQUF6Qjs7QUFFQSxNQUFNQyxTQUFTLEdBQUcsWUFBWTtBQUM1QixRQUFNQyxVQUFVLEdBQUdDLE1BQU0sQ0FBQ0MsSUFBUCxDQUFZdEIsS0FBWixFQUFtQnVCLE1BQW5CLENBQTBCLFVBQVVDLElBQVYsRUFB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IjpbIi8vIHRyaWdnZXJzLmpzXG5pbXBvcnQgUGFyc2UgZnJvbSAncGFyc2Uvbm9kZSc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuL2xvZ2dlcic7XG5cbmV4cG9ydCBjb25zdCBUeXBlcyA9IHtcbiAgYmVmb3JlTG9naW46ICdiZWZvcmVMb2dpbicsXG4gIGFmdGVyTG9naW46ICdhZnRlckxvZ2luJyxcbiAgYWZ0ZXJMb2dvdXQ6ICdhZnRlckxvZ291dCcsXG4gIGJlZm9yZVNhdmU6ICdiZWZvcmVTYXZlJyxcbiAgYWZ0ZXJTYXZlOiAnYWZ0ZXJTYXZlJyxcbiAgYmVmb3JlRGVsZXRlOiAnYmVmb3JlRGVsZXRlJyxcbiAgYWZ0ZXJEZWxldGU6ICdhZnRlckRlbGV0ZScsXG4gIGJlZm9yZUZpbmQ6ICdiZWZvcmVGaW5kJyxcbiAgYWZ0ZXJGaW5kOiAnYWZ0ZXJGaW5kJyxcbiAgYmVmb3JlU2F2ZUZpbGU6ICdiZWZvcmVTYXZlRmlsZScsXG4gIGFmdGVyU2F2ZUZpbGU6ICdhZnRlclNhdmVGaWxlJyxcbiAgYmVmb3JlRGVsZXRlRmlsZTogJ2JlZm9yZURlbGV0ZUZpbGUnLFxuICBhZnRlckRlbGV0ZUZpbGU6ICdhZnRlckRlbGV0ZUZpbGUnLFxuICBiZWZvcmVDb25uZWN0OiAnYmVmb3JlQ29ubmVjdCcsXG4gIGJlZm9yZVN1YnNjcmliZTogJ2JlZm9yZVN1YnNjcmliZScsXG4gIGFmdGVyRXZlbnQ6ICdhZnRlckV2ZW50Jyxcbn07XG5cbmNvbnN0IEZpbGVDbGFzc05hbWUgPSAnQEZpbGUnO1xuY29uc3QgQ29ubmVjdENsYXNzTmFtZSA9ICdAQ29ubmVjdCc7XG5cbmNvbnN0IGJhc2VTdG9yZSA9IGZ1bmN0aW9uICgpIHtcbiAgY29uc3QgVmFsaWRhdG9ycyA9IE9iamVjdC5rZXlzKFR5cGVzKS5yZWR1Y2UoZnVuY3Rpb24gKGJhc2UsIGtleSkge1xuICAgIGJhc2Vba2V5XSA9IHt9O1xuICAgIHJldHVybiBiYXNlO1xuICB9LCB7fSk7XG4gIGNvbnN0IEZ1bmN0aW9ucyA9IHt9O1xuICBjb25zdCBKb2JzID0ge307XG4gIGNvbnN0IExpdmVRdWVyeSA9IFtdO1xuICBjb25zdCBUcmlnZ2VycyA9IE9iamVjdC5rZXlzKFR5cGVzKS5yZWR1Y2UoZnVuY3Rpb24gKGJhc2UsIGtleSkge1xuICAgIGJhc2Vba2V5XSA9IHt9O1xuICAgIHJldHVybiBiYXNlO1xuICB9LCB7fSk7XG5cbiAgcmV0dXJuIE9iamVjdC5mcmVlemUoe1xuICAgIEZ1bmN0aW9ucyxcbiAgICBKb2JzLFxuICAgIFZhbGlkYXRvcnMsXG4gICAgVHJpZ2dlcnMsXG4gICAgTGl2ZVF1ZXJ5LFxuICB9KTtcbn07XG5cbmZ1bmN0aW9uIHZhbGlkYXRlQ2xhc3NOYW1lRm9yVHJpZ2dlcnMoY2xhc3NOYW1lLCB0eXBlKSB7XG4gIGlmICh0eXBlID09IFR5cGVzLmJlZm9yZVNhdmUgJiYgY2xhc3NOYW1lID09PSAnX1B1c2hTdGF0dXMnKSB7XG4gICAgLy8gX1B1c2hTdGF0dXMgdXNlcyB1bmRvY3VtZW50ZWQgbmVzdGVkIGtleSBpbmNyZW1lbnQgb3BzXG4gICAgLy8gYWxsb3dpbmcgYmVmb3JlU2F2ZSB3b3VsZCBtZXNzIHVwIHRoZSBvYmplY3RzIGJpZyB0aW1lXG4gICAgLy8gVE9ETzogQWxsb3cgcHJvcGVyIGRvY3VtZW50ZWQgd2F5IG9mIHVzaW5nIG5lc3RlZCBpbmNyZW1lbnQgb3BzXG4gICAgdGhyb3cgJ09ubHkgYWZ0ZXJTYXZlIGlzIGFsbG93ZWQgb24gX1B1c2hTdGF0dXMnO1xuICB9XG4gIGlmICgodHlwZSA9PT0gVHlwZXMuYmVmb3JlTG9naW4gfHwgdHlwZSA9PT0gVHlwZXMuYWZ0ZXJMb2dpbikgJiYgY2xhc3NOYW1lICE9PSAnX1VzZXInKSB7XG4gICAgLy8gVE9ETzogY2hlY2sgaWYgdXBzdHJlYW0gY29kZSB3aWxsIGhhbmRsZSBgRXJyb3JgIGluc3RhbmNlIHJhdGhlclxuICAgIC8vIHRoYW4gdGhpcyBhbnRpLXBhdHRlcm4gb2YgdGhyb3dpbmcgc3RyaW5nc1xuICAgIHRocm93ICdPbmx5IHRoZSBfVXNlciBjbGFzcyBpcyBhbGxvd2VkIGZvciB0aGUgYmVmb3JlTG9naW4gYW5kIGFmdGVyTG9naW4gdHJpZ2dlcnMnO1xuICB9XG4gIGlmICh0eXBlID09PSBUeXBlcy5hZnRlckxvZ291dCAmJiBjbGFzc05hbWUgIT09ICdfU2Vzc2lvbicpIHtcbiAgICAvLyBUT0RPOiBjaGVjayBpZiB1cHN0cmVhbSBjb2RlIHdpbGwgaGFuZGxlIGBFcnJvcmAgaW5zdGFuY2UgcmF0aGVyXG4gICAgLy8gdGhhbiB0aGlzIGFudGktcGF0dGVybiBvZiB0aHJvd2luZyBzdHJpbmdzXG4gICAgdGhyb3cgJ09ubHkgdGhlIF9TZXNzaW9uIGNsYXNzIGlzIGFsbG93ZWQgZm9yIHRoZSBhZnRlckxvZ291dCB0cmlnZ2VyLic7XG4gIH1cbiAgaWYgKGNsYXNzTmFtZSA9PT0gJ19TZXNzaW9uJyAmJiB0eXBlICE9PSBUeXBlcy5hZnRlckxvZ291dCkge1xuICAgIC8vIFRPRE86IGNoZWNrIGlmIHVwc3RyZWFtIGNvZGUgd2lsbCBoYW5kbGUgYEVycm9yYCBpbnN0YW5jZSByYXRoZXJcbiAgICAvLyB0aGFuIHRoaXMgYW50aS1wYXR0ZXJuIG9mIHRocm93aW5nIHN0cmluZ3NcbiAgICB0aHJvdyAnT25seSB0aGUgYWZ0ZXJMb2dvdXQgdHJpZ2dlciBpcyBhbGxvd2VkIGZvciB0aGUgX1Nlc3Npb24gY2xhc3MuJztcbiAgfVxuICByZXR1cm4gY2xhc3NOYW1lO1xufVxuXG5jb25zdCBfdHJpZ2dlclN0b3JlID0ge307XG5cbmNvbnN0IENhdGVnb3J5ID0ge1xuICBGdW5jdGlvbnM6ICdGdW5jdGlvbnMnLFxuICBWYWxpZGF0b3JzOiAnVmFsaWRhdG9ycycsXG4gIEpvYnM6ICdKb2JzJyxcbiAgVHJpZ2dlcnM6ICdUcmlnZ2VycycsXG59O1xuXG5mdW5jdGlvbiBnZXRTdG9yZShjYXRlZ29yeSwgbmFtZSwgYXBwbGljYXRpb25JZCkge1xuICBjb25zdCBwYXRoID0gbmFtZS5zcGxpdCgnLicpO1xuICBwYXRoLnNwbGljZSgtMSk7IC8vIHJlbW92ZSBsYXN0IGNvbXBvbmVudFxuICBhcHBsaWNhdGlvbklkID0gYXBwbGljYXRpb25JZCB8fCBQYXJzZS5hcHBsaWNhdGlvbklkO1xuICBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCBiYXNlU3RvcmUoKTtcbiAgbGV0IHN0b3JlID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXVtjYXRlZ29yeV07XG4gIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGgpIHtcbiAgICBzdG9yZSA9IHN0b3JlW2NvbXBvbmVudF07XG4gICAgaWYgKCFzdG9yZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0b3JlO1xufVxuXG5mdW5jdGlvbiBhZGQoY2F0ZWdvcnksIG5hbWUsIGhhbmRsZXIsIGFwcGxpY2F0aW9uSWQpIHtcbiAgY29uc3QgbGFzdENvbXBvbmVudCA9IG5hbWUuc3BsaXQoJy4nKS5zcGxpY2UoLTEpO1xuICBjb25zdCBzdG9yZSA9IGdldFN0b3JlKGNhdGVnb3J5LCBuYW1lLCBhcHBsaWNhdGlvbklkKTtcbiAgaWYgKHN0b3JlW2xhc3RDb21wb25lbnRdKSB7XG4gICAgbG9nZ2VyLndhcm4oXG4gICAgICBgV2FybmluZzogRHVwbGljYXRlIGNsb3VkIGZ1bmN0aW9ucyBleGlzdCBmb3IgJHtsYXN0Q29tcG9uZW50fS4gT25seSB0aGUgbGFzdCBvbmUgd2lsbCBiZSB1c2VkIGFuZCB0aGUgb3RoZXJzIHdpbGwgYmUgaWdub3JlZC5gXG4gICAgKTtcbiAgfVxuICBzdG9yZVtsYXN0Q29tcG9uZW50XSA9IGhhbmRsZXI7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZShjYXRlZ29yeSwgbmFtZSwgYXBwbGljYXRpb25JZCkge1xuICBjb25zdCBsYXN0Q29tcG9uZW50ID0gbmFtZS5zcGxpdCgnLicpLnNwbGljZSgtMSk7XG4gIGNvbnN0IHN0b3JlID0gZ2V0U3RvcmUoY2F0ZWdvcnksIG5hbWUsIGFwcGxpY2F0aW9uSWQpO1xuICBkZWxldGUgc3RvcmVbbGFzdENvbXBvbmVudF07XG59XG5cbmZ1bmN0aW9uIGdldChjYXRlZ29yeSwgbmFtZSwgYXBwbGljYXRpb25JZCkge1xuICBjb25zdCBsYXN0Q29tcG9uZW50ID0gbmFtZS5zcGxpdCgnLicpLnNwbGljZSgtMSk7XG4gIGNvbnN0IHN0b3JlID0gZ2V0U3RvcmUoY2F0ZWdvcnksIG5hbWUsIGFwcGxpY2F0aW9uSWQpO1xuICByZXR1cm4gc3RvcmVbbGFzdENvbXBvbmVudF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRGdW5jdGlvbihmdW5jdGlvbk5hbWUsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyLCBhcHBsaWNhdGlvbklkKSB7XG4gIGFkZChDYXRlZ29yeS5GdW5jdGlvbnMsIGZ1bmN0aW9uTmFtZSwgaGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG4gIGFkZChDYXRlZ29yeS5WYWxpZGF0b3JzLCBmdW5jdGlvbk5hbWUsIHZhbGlkYXRpb25IYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZEpvYihqb2JOYW1lLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKSB7XG4gIGFkZChDYXRlZ29yeS5Kb2JzLCBqb2JOYW1lLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFRyaWdnZXIodHlwZSwgY2xhc3NOYW1lLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB2YWxpZGF0ZUNsYXNzTmFtZUZvclRyaWdnZXJzKGNsYXNzTmFtZSwgdHlwZSk7XG4gIGFkZChDYXRlZ29yeS5UcmlnZ2VycywgYCR7dHlwZX0uJHtjbGFzc05hbWV9YCwgaGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG4gIGFkZChDYXRlZ29yeS5WYWxpZGF0b3JzLCBgJHt0eXBlfS4ke2NsYXNzTmFtZX1gLCB2YWxpZGF0aW9uSGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRGaWxlVHJpZ2dlcih0eXBlLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICBhZGQoQ2F0ZWdvcnkuVHJpZ2dlcnMsIGAke3R5cGV9LiR7RmlsZUNsYXNzTmFtZX1gLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbiAgYWRkKENhdGVnb3J5LlZhbGlkYXRvcnMsIGAke3R5cGV9LiR7RmlsZUNsYXNzTmFtZX1gLCB2YWxpZGF0aW9uSGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRDb25uZWN0VHJpZ2dlcih0eXBlLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICBhZGQoQ2F0ZWdvcnkuVHJpZ2dlcnMsIGAke3R5cGV9LiR7Q29ubmVjdENsYXNzTmFtZX1gLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbiAgYWRkKENhdGVnb3J5LlZhbGlkYXRvcnMsIGAke3R5cGV9LiR7Q29ubmVjdENsYXNzTmFtZX1gLCB2YWxpZGF0aW9uSGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRMaXZlUXVlcnlFdmVudEhhbmRsZXIoaGFuZGxlciwgYXBwbGljYXRpb25JZCkge1xuICBhcHBsaWNhdGlvbklkID0gYXBwbGljYXRpb25JZCB8fCBQYXJzZS5hcHBsaWNhdGlvbklkO1xuICBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCBiYXNlU3RvcmUoKTtcbiAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5MaXZlUXVlcnkucHVzaChoYW5kbGVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICByZW1vdmUoQ2F0ZWdvcnkuRnVuY3Rpb25zLCBmdW5jdGlvbk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlVHJpZ2dlcih0eXBlLCBjbGFzc05hbWUsIGFwcGxpY2F0aW9uSWQpIHtcbiAgcmVtb3ZlKENhdGVnb3J5LlRyaWdnZXJzLCBgJHt0eXBlfS4ke2NsYXNzTmFtZX1gLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF91bnJlZ2lzdGVyQWxsKCkge1xuICBPYmplY3Qua2V5cyhfdHJpZ2dlclN0b3JlKS5mb3JFYWNoKGFwcElkID0+IGRlbGV0ZSBfdHJpZ2dlclN0b3JlW2FwcElkXSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHJpZ2dlclR5cGUsIGFwcGxpY2F0aW9uSWQpIHtcbiAgaWYgKCFhcHBsaWNhdGlvbklkKSB7XG4gICAgdGhyb3cgJ01pc3NpbmcgQXBwbGljYXRpb25JRCc7XG4gIH1cbiAgcmV0dXJuIGdldChDYXRlZ29yeS5UcmlnZ2VycywgYCR7dHJpZ2dlclR5cGV9LiR7Y2xhc3NOYW1lfWAsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmlsZVRyaWdnZXIodHlwZSwgYXBwbGljYXRpb25JZCkge1xuICByZXR1cm4gZ2V0VHJpZ2dlcihGaWxlQ2xhc3NOYW1lLCB0eXBlLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRyaWdnZXJFeGlzdHMoY2xhc3NOYW1lOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgYXBwbGljYXRpb25JZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHlwZSwgYXBwbGljYXRpb25JZCkgIT0gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RnVuY3Rpb24oZnVuY3Rpb25OYW1lLCBhcHBsaWNhdGlvbklkKSB7XG4gIHJldHVybiBnZXQoQ2F0ZWdvcnkuRnVuY3Rpb25zLCBmdW5jdGlvbk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RnVuY3Rpb25OYW1lcyhhcHBsaWNhdGlvbklkKSB7XG4gIGNvbnN0IHN0b3JlID1cbiAgICAoX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSAmJiBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdW0NhdGVnb3J5LkZ1bmN0aW9uc10pIHx8IHt9O1xuICBjb25zdCBmdW5jdGlvbk5hbWVzID0gW107XG4gIGNvbnN0IGV4dHJhY3RGdW5jdGlvbk5hbWVzID0gKG5hbWVzcGFjZSwgc3RvcmUpID0+IHtcbiAgICBPYmplY3Qua2V5cyhzdG9yZSkuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gc3RvcmVbbmFtZV07XG4gICAgICBpZiAobmFtZXNwYWNlKSB7XG4gICAgICAgIG5hbWUgPSBgJHtuYW1lc3BhY2V9LiR7bmFtZX1gO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICBmdW5jdGlvbk5hbWVzLnB1c2gobmFtZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBleHRyYWN0RnVuY3Rpb25OYW1lcyhuYW1lLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG4gIGV4dHJhY3RGdW5jdGlvbk5hbWVzKG51bGwsIHN0b3JlKTtcbiAgcmV0dXJuIGZ1bmN0aW9uTmFtZXM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRKb2Ioam9iTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICByZXR1cm4gZ2V0KENhdGVnb3J5LkpvYnMsIGpvYk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Sm9icyhhcHBsaWNhdGlvbklkKSB7XG4gIHZhciBtYW5hZ2VyID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXTtcbiAgaWYgKG1hbmFnZXIgJiYgbWFuYWdlci5Kb2JzKSB7XG4gICAgcmV0dXJuIG1hbmFnZXIuSm9icztcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmFsaWRhdG9yKGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICByZXR1cm4gZ2V0KENhdGVnb3J5LlZhbGlkYXRvcnMsIGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXF1ZXN0T2JqZWN0KFxuICB0cmlnZ2VyVHlwZSxcbiAgYXV0aCxcbiAgcGFyc2VPYmplY3QsXG4gIG9yaWdpbmFsUGFyc2VPYmplY3QsXG4gIGNvbmZpZyxcbiAgY29udGV4dFxuKSB7XG4gIGNvbnN0IHJlcXVlc3QgPSB7XG4gICAgdHJpZ2dlck5hbWU6IHRyaWdnZXJUeXBlLFxuICAgIG9iamVjdDogcGFyc2VPYmplY3QsXG4gICAgbWFzdGVyOiBmYWxzZSxcbiAgICBsb2c6IGNvbmZpZy5sb2dnZXJDb250cm9sbGVyLFxuICAgIGhlYWRlcnM6IGNvbmZpZy5oZWFkZXJzLFxuICAgIGlwOiBjb25maWcuaXAsXG4gIH07XG5cbiAgaWYgKG9yaWdpbmFsUGFyc2VPYmplY3QpIHtcbiAgICByZXF1ZXN0Lm9yaWdpbmFsID0gb3JpZ2luYWxQYXJzZU9iamVjdDtcbiAgfVxuICBpZiAoXG4gICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmJlZm9yZVNhdmUgfHxcbiAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYWZ0ZXJTYXZlIHx8XG4gICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmJlZm9yZURlbGV0ZSB8fFxuICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlckRlbGV0ZSB8fFxuICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlckZpbmRcbiAgKSB7XG4gICAgLy8gU2V0IGEgY29weSBvZiB0aGUgY29udGV4dCBvbiB0aGUgcmVxdWVzdCBvYmplY3QuXG4gICAgcmVxdWVzdC5jb250ZXh0ID0gT2JqZWN0LmFzc2lnbih7fSwgY29udGV4dCk7XG4gIH1cblxuICBpZiAoIWF1dGgpIHtcbiAgICByZXR1cm4gcmVxdWVzdDtcbiAgfVxuICBpZiAoYXV0aC5pc01hc3Rlcikge1xuICAgIHJlcXVlc3RbJ21hc3RlciddID0gdHJ1ZTtcbiAgfVxuICBpZiAoYXV0aC51c2VyKSB7XG4gICAgcmVxdWVzdFsndXNlciddID0gYXV0aC51c2VyO1xuICB9XG4gIGlmIChhdXRoLmluc3RhbGxhdGlvbklkKSB7XG4gICAgcmVxdWVzdFsnaW5zdGFsbGF0aW9uSWQnXSA9IGF1dGguaW5zdGFsbGF0aW9uSWQ7XG4gIH1cbiAgcmV0dXJuIHJlcXVlc3Q7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXF1ZXN0UXVlcnlPYmplY3QodHJpZ2dlclR5cGUsIGF1dGgsIHF1ZXJ5LCBjb3VudCwgY29uZmlnLCBjb250ZXh0LCBpc0dldCkge1xuICBpc0dldCA9ICEhaXNHZXQ7XG5cbiAgdmFyIHJlcXVlc3QgPSB7XG4gICAgdHJpZ2dlck5hbWU6IHRyaWdnZXJUeXBlLFxuICAgIHF1ZXJ5LFxuICAgIG1hc3RlcjogZmFsc2UsXG4gICAgY291bnQsXG4gICAgbG9nOiBjb25maWcubG9nZ2VyQ29udHJvbGxlcixcbiAgICBpc0dldCxcbiAgICBoZWFkZXJzOiBjb25maWcuaGVhZGVycyxcbiAgICBpcDogY29uZmlnLmlwLFxuICAgIGNvbnRleHQ6IGNvbnRleHQgfHwge30sXG4gIH07XG5cbiAgaWYgKCFhdXRoKSB7XG4gICAgcmV0dXJuIHJlcXVlc3Q7XG4gIH1cbiAgaWYgKGF1dGguaXNNYXN0ZXIpIHtcbiAgICByZXF1ZXN0WydtYXN0ZXInXSA9IHRydWU7XG4gIH1cbiAgaWYgKGF1dGgudXNlcikge1xuICAgIHJlcXVlc3RbJ3VzZXInXSA9IGF1dGgudXNlcjtcbiAgfVxuICBpZiAoYXV0aC5pbnN0YWxsYXRpb25JZCkge1xuICAgIHJlcXVlc3RbJ2luc3RhbGxhdGlvbklkJ10gPSBhdXRoLmluc3RhbGxhdGlvbklkO1xuICB9XG4gIHJldHVybiByZXF1ZXN0O1xufVxuXG4vLyBDcmVhdGVzIHRoZSByZXNwb25zZSBvYmplY3QsIGFuZCB1c2VzIHRoZSByZXF1ZXN0IG9iamVjdCB0byBwYXNzIGRhdGFcbi8vIFRoZSBBUEkgd2lsbCBjYWxsIHRoaXMgd2l0aCBSRVNUIEFQSSBmb3JtYXR0ZWQgb2JqZWN0cywgdGhpcyB3aWxsXG4vLyB0cmFuc2Zvcm0gdGhlbSB0byBQYXJzZS5PYmplY3QgaW5zdGFuY2VzIGV4cGVjdGVkIGJ5IENsb3VkIENvZGUuXG4vLyBBbnkgY2hhbmdlcyBtYWRlIHRvIHRoZSBvYmplY3QgaW4gYSBiZWZvcmVTYXZlIHdpbGwgYmUgaW5jbHVkZWQuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVzcG9uc2VPYmplY3QocmVxdWVzdCwgcmVzb2x2ZSwgcmVqZWN0KSB7XG4gIHJldHVybiB7XG4gICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICBpZiAocmVxdWVzdC50cmlnZ2VyTmFtZSA9PT0gVHlwZXMuYWZ0ZXJGaW5kKSB7XG4gICAgICAgIGlmICghcmVzcG9uc2UpIHtcbiAgICAgICAgICByZXNwb25zZSA9IHJlcXVlc3Qub2JqZWN0cztcbiAgICAgICAgfVxuICAgICAgICByZXNwb25zZSA9IHJlc3BvbnNlLm1hcChvYmplY3QgPT4ge1xuICAgICAgICAgIHJldHVybiBvYmplY3QudG9KU09OKCk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcmVzb2x2ZShyZXNwb25zZSk7XG4gICAgICB9XG4gICAgICAvLyBVc2UgdGhlIEpTT04gcmVzcG9uc2VcbiAgICAgIGlmIChcbiAgICAgICAgcmVzcG9uc2UgJiZcbiAgICAgICAgdHlwZW9mIHJlc3BvbnNlID09PSAnb2JqZWN0JyAmJlxuICAgICAgICAhcmVxdWVzdC5vYmplY3QuZXF1YWxzKHJlc3BvbnNlKSAmJlxuICAgICAgICByZXF1ZXN0LnRyaWdnZXJOYW1lID09PSBUeXBlcy5iZWZvcmVTYXZlXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgfVxuICAgICAgaWYgKHJlc3BvbnNlICYmIHR5cGVvZiByZXNwb25zZSA9PT0gJ29iamVjdCcgJiYgcmVxdWVzdC50cmlnZ2VyTmFtZSA9PT0gVHlwZXMuYWZ0ZXJTYXZlKSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICAgIH1cbiAgICAgIGlmIChyZXF1ZXN0LnRyaWdnZXJOYW1lID09PSBUeXBlcy5hZnRlclNhdmUpIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICAgIH1cbiAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICBpZiAocmVxdWVzdC50cmlnZ2VyTmFtZSA9PT0gVHlwZXMuYmVmb3JlU2F2ZSkge1xuICAgICAgICByZXNwb25zZVsnb2JqZWN0J10gPSByZXF1ZXN0Lm9iamVjdC5fZ2V0U2F2ZUpTT04oKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICB9LFxuICAgIGVycm9yOiBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIGNvbnN0IGUgPSByZXNvbHZlRXJyb3IoZXJyb3IsIHtcbiAgICAgICAgY29kZTogUGFyc2UuRXJyb3IuU0NSSVBUX0ZBSUxFRCxcbiAgICAgICAgbWVzc2FnZTogJ1NjcmlwdCBmYWlsZWQuIFVua25vd24gZXJyb3IuJyxcbiAgICAgIH0pO1xuICAgICAgcmVqZWN0KGUpO1xuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIHVzZXJJZEZvckxvZyhhdXRoKSB7XG4gIHJldHVybiBhdXRoICYmIGF1dGgudXNlciA/IGF1dGgudXNlci5pZCA6IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gbG9nVHJpZ2dlckFmdGVySG9vayh0cmlnZ2VyVHlwZSwgY2xhc3NOYW1lLCBpbnB1dCwgYXV0aCkge1xuICBjb25zdCBjbGVhbklucHV0ID0gbG9nZ2VyLnRydW5jYXRlTG9nTWVzc2FnZShKU09OLnN0cmluZ2lmeShpbnB1dCkpO1xuICBsb2dnZXIuaW5mbyhcbiAgICBgJHt0cmlnZ2VyVHlwZX0gdHJpZ2dlcmVkIGZvciAke2NsYXNzTmFtZX0gZm9yIHVzZXIgJHt1c2VySWRGb3JMb2coXG4gICAgICBhdXRoXG4gICAgKX06XFxuICBJbnB1dDogJHtjbGVhbklucHV0fWAsXG4gICAge1xuICAgICAgY2xhc3NOYW1lLFxuICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICB1c2VyOiB1c2VySWRGb3JMb2coYXV0aCksXG4gICAgfVxuICApO1xufVxuXG5mdW5jdGlvbiBsb2dUcmlnZ2VyU3VjY2Vzc0JlZm9yZUhvb2sodHJpZ2dlclR5cGUsIGNsYXNzTmFtZSwgaW5wdXQsIHJlc3VsdCwgYXV0aCkge1xuICBjb25zdCBjbGVhbklucHV0ID0gbG9nZ2VyLnRydW5jYXRlTG9nTWVzc2FnZShKU09OLnN0cmluZ2lmeShpbnB1dCkpO1xuICBjb25zdCBjbGVhblJlc3VsdCA9IGxvZ2dlci50cnVuY2F0ZUxvZ01lc3NhZ2UoSlNPTi5zdHJpbmdpZnkocmVzdWx0KSk7XG4gIGxvZ2dlci5pbmZvKFxuICAgIGAke3RyaWdnZXJUeXBlfSB0cmlnZ2VyZWQgZm9yICR7Y2xhc3NOYW1lfSBmb3IgdXNlciAke3VzZXJJZEZvckxvZyhcbiAgICAgIGF1dGhcbiAgICApfTpcXG4gIElucHV0OiAke2NsZWFuSW5wdXR9XFxuICBSZXN1bHQ6ICR7Y2xlYW5SZXN1bHR9YCxcbiAgICB7XG4gICAgICBjbGFzc05hbWUsXG4gICAgICB0cmlnZ2VyVHlwZSxcbiAgICAgIHVzZXI6IHVzZXJJZEZvckxvZyhhdXRoKSxcbiAgICB9XG4gICk7XG59XG5cbmZ1bmN0aW9uIGxvZ1RyaWdnZXJFcnJvckJlZm9yZUhvb2sodHJpZ2dlclR5cGUsIGNsYXNzTmFtZSwgaW5wdXQsIGF1dGgsIGVycm9yKSB7XG4gIGNvbnN0IGNsZWFuSW5wdXQgPSBsb2dnZXIudHJ1bmNhdGVMb2dNZXNzYWdlKEpTT04uc3RyaW5naWZ5KGlucHV0KSk7XG4gIGxvZ2dlci5lcnJvcihcbiAgICBgJHt0cmlnZ2VyVHlwZX0gZmFpbGVkIGZvciAke2NsYXNzTmFtZX0gZm9yIHVzZXIgJHt1c2VySWRGb3JMb2coXG4gICAgICBhdXRoXG4gICAgKX06XFxuICBJbnB1dDogJHtjbGVhbklucHV0fVxcbiAgRXJyb3I6ICR7SlNPTi5zdHJpbmdpZnkoZXJyb3IpfWAsXG4gICAge1xuICAgICAgY2xhc3NOYW1lLFxuICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICBlcnJvcixcbiAgICAgIHVzZXI6IHVzZXJJZEZvckxvZyhhdXRoKSxcbiAgICB9XG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtYXliZVJ1bkFmdGVyRmluZFRyaWdnZXIoXG4gIHRyaWdnZXJUeXBlLFxuICBhdXRoLFxuICBjbGFzc05hbWUsXG4gIG9iamVjdHMsXG4gIGNvbmZpZyxcbiAgcXVlcnksXG4gIGNvbnRleHRcbikge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHRyaWdnZXIgPSBnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHJpZ2dlclR5cGUsIGNvbmZpZy5hcHBsaWNhdGlvbklkKTtcbiAgICBpZiAoIXRyaWdnZXIpIHtcbiAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgfVxuICAgIGNvbnN0IHJlcXVlc3QgPSBnZXRSZXF1ZXN0T2JqZWN0KHRyaWdnZXJUeXBlLCBhdXRoLCBudWxsLCBudWxsLCBjb25maWcsIGNvbnRleHQpO1xuICAgIGlmIChxdWVyeSkge1xuICAgICAgcmVxdWVzdC5xdWVyeSA9IHF1ZXJ5O1xuICAgIH1cbiAgICBjb25zdCB7IHN1Y2Nlc3MsIGVycm9yIH0gPSBnZXRSZXNwb25zZU9iamVjdChcbiAgICAgIHJlcXVlc3QsXG4gICAgICBvYmplY3QgPT4ge1xuICAgICAgICByZXNvbHZlKG9iamVjdCk7XG4gICAgICB9LFxuICAgICAgZXJyb3IgPT4ge1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfVxuICAgICk7XG4gICAgbG9nVHJpZ2dlclN1Y2Nlc3NCZWZvcmVIb29rKHRyaWdnZXJUeXBlLCBjbGFzc05hbWUsICdBZnRlckZpbmQnLCBKU09OLnN0cmluZ2lmeShvYmplY3RzKSwgYXV0aCk7XG4gICAgcmVxdWVzdC5vYmplY3RzID0gb2JqZWN0cy5tYXAob2JqZWN0ID0+IHtcbiAgICAgIC8vc2V0dGluZyB0aGUgY2xhc3MgbmFtZSB0byB0cmFuc2Zvcm0gaW50byBwYXJzZSBvYmplY3RcbiAgICAgIG9iamVjdC5jbGFzc05hbWUgPSBjbGFzc05hbWU7XG4gICAgICByZXR1cm4gUGFyc2UuT2JqZWN0LmZyb21KU09OKG9iamVjdCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiBtYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0LCBgJHt0cmlnZ2VyVHlwZX0uJHtjbGFzc05hbWV9YCk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBpZiAocmVxdWVzdC5za2lwV2l0aE1hc3RlcktleSkge1xuICAgICAgICAgIHJldHVybiByZXF1ZXN0Lm9iamVjdHM7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSB0cmlnZ2VyKHJlcXVlc3QpO1xuICAgICAgICBpZiAocmVzcG9uc2UgJiYgdHlwZW9mIHJlc3BvbnNlLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICByZXR1cm4gcmVzcG9uc2UudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgICAgIGlmICghcmVzdWx0cykge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuU0NSSVBUX0ZBSUxFRCxcbiAgICAgICAgICAgICAgICAnQWZ0ZXJGaW5kIGV4cGVjdCByZXN1bHRzIHRvIGJlIHJldHVybmVkIGluIHRoZSBwcm9taXNlJ1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xuICAgICAgfSlcbiAgICAgIC50aGVuKHN1Y2Nlc3MsIGVycm9yKTtcbiAgfSkudGhlbihyZXN1bHRzID0+IHtcbiAgICBsb2dUcmlnZ2VyQWZ0ZXJIb29rKHRyaWdnZXJUeXBlLCBjbGFzc05hbWUsIEpTT04uc3RyaW5naWZ5KHJlc3VsdHMpLCBhdXRoKTtcbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtYXliZVJ1blF1ZXJ5VHJpZ2dlcihcbiAgdHJpZ2dlclR5cGUsXG4gIGNsYXNzTmFtZSxcbiAgcmVzdFdoZXJlLFxuICByZXN0T3B0aW9ucyxcbiAgY29uZmlnLFxuICBhdXRoLFxuICBjb250ZXh0LFxuICBpc0dldFxuKSB7XG4gIGNvbnN0IHRyaWdnZXIgPSBnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHJpZ2dlclR5cGUsIGNvbmZpZy5hcHBsaWNhdGlvbklkKTtcbiAgaWYgKCF0cmlnZ2VyKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7XG4gICAgICByZXN0V2hlcmUsXG4gICAgICByZXN0T3B0aW9ucyxcbiAgICB9KTtcbiAgfVxuICBjb25zdCBqc29uID0gT2JqZWN0LmFzc2lnbih7fSwgcmVzdE9wdGlvbnMpO1xuICBqc29uLndoZXJlID0gcmVzdFdoZXJlO1xuXG4gIGNvbnN0IHBhcnNlUXVlcnkgPSBuZXcgUGFyc2UuUXVlcnkoY2xhc3NOYW1lKTtcbiAgcGFyc2VRdWVyeS53aXRoSlNPTihqc29uKTtcblxuICBsZXQgY291bnQgPSBmYWxzZTtcbiAgaWYgKHJlc3RPcHRpb25zKSB7XG4gICAgY291bnQgPSAhIXJlc3RPcHRpb25zLmNvdW50O1xuICB9XG4gIGNvbnN0IHJlcXVlc3RPYmplY3QgPSBnZXRSZXF1ZXN0UXVlcnlPYmplY3QoXG4gICAgdHJpZ2dlclR5cGUsXG4gICAgYXV0aCxcbiAgICBwYXJzZVF1ZXJ5LFxuICAgIGNvdW50LFxuICAgIGNvbmZpZyxcbiAgICBjb250ZXh0LFxuICAgIGlzR2V0XG4gICk7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiBtYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0T2JqZWN0LCBgJHt0cmlnZ2VyVHlwZX0uJHtjbGFzc05hbWV9YCk7XG4gICAgfSlcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICBpZiAocmVxdWVzdE9iamVjdC5za2lwV2l0aE1hc3RlcktleSkge1xuICAgICAgICByZXR1cm4gcmVxdWVzdE9iamVjdC5xdWVyeTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cmlnZ2VyKHJlcXVlc3RPYmplY3QpO1xuICAgIH0pXG4gICAgLnRoZW4oXG4gICAgICByZXN1bHQgPT4ge1xuICAgICAgICBsZXQgcXVlcnlSZXN1bHQgPSBwYXJzZVF1ZXJ5O1xuICAgICAgICBpZiAocmVzdWx0ICYmIHJlc3VsdCBpbnN0YW5jZW9mIFBhcnNlLlF1ZXJ5KSB7XG4gICAgICAgICAgcXVlcnlSZXN1bHQgPSByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QganNvblF1ZXJ5ID0gcXVlcnlSZXN1bHQudG9KU09OKCk7XG4gICAgICAgIGlmIChqc29uUXVlcnkud2hlcmUpIHtcbiAgICAgICAgICByZXN0V2hlcmUgPSBqc29uUXVlcnkud2hlcmU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGpzb25RdWVyeS5saW1pdCkge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMubGltaXQgPSBqc29uUXVlcnkubGltaXQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGpzb25RdWVyeS5za2lwKSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5za2lwID0ganNvblF1ZXJ5LnNraXA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGpzb25RdWVyeS5pbmNsdWRlKSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5pbmNsdWRlID0ganNvblF1ZXJ5LmluY2x1ZGU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGpzb25RdWVyeS5leGNsdWRlS2V5cykge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMuZXhjbHVkZUtleXMgPSBqc29uUXVlcnkuZXhjbHVkZUtleXM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGpzb25RdWVyeS5leHBsYWluKSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5leHBsYWluID0ganNvblF1ZXJ5LmV4cGxhaW47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGpzb25RdWVyeS5rZXlzKSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5rZXlzID0ganNvblF1ZXJ5LmtleXM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGpzb25RdWVyeS5vcmRlcikge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMub3JkZXIgPSBqc29uUXVlcnkub3JkZXI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGpzb25RdWVyeS5oaW50KSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5oaW50ID0ganNvblF1ZXJ5LmhpbnQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlcXVlc3RPYmplY3QucmVhZFByZWZlcmVuY2UpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gcmVxdWVzdE9iamVjdC5yZWFkUHJlZmVyZW5jZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVxdWVzdE9iamVjdC5pbmNsdWRlUmVhZFByZWZlcmVuY2UpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLmluY2x1ZGVSZWFkUHJlZmVyZW5jZSA9IHJlcXVlc3RPYmplY3QuaW5jbHVkZVJlYWRQcmVmZXJlbmNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXF1ZXN0T2JqZWN0LnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UgPSByZXF1ZXN0T2JqZWN0LnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICByZXN0V2hlcmUsXG4gICAgICAgICAgcmVzdE9wdGlvbnMsXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgICAgZXJyID0+IHtcbiAgICAgICAgY29uc3QgZXJyb3IgPSByZXNvbHZlRXJyb3IoZXJyLCB7XG4gICAgICAgICAgY29kZTogUGFyc2UuRXJyb3IuU0NSSVBUX0ZBSUxFRCxcbiAgICAgICAgICBtZXNzYWdlOiAnU2NyaXB0IGZhaWxlZC4gVW5rbm93biBlcnJvci4nLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVFcnJvcihtZXNzYWdlLCBkZWZhdWx0T3B0cykge1xuICBpZiAoIWRlZmF1bHRPcHRzKSB7XG4gICAgZGVmYXVsdE9wdHMgPSB7fTtcbiAgfVxuICBpZiAoIW1lc3NhZ2UpIHtcbiAgICByZXR1cm4gbmV3IFBhcnNlLkVycm9yKFxuICAgICAgZGVmYXVsdE9wdHMuY29kZSB8fCBQYXJzZS5FcnJvci5TQ1JJUFRfRkFJTEVELFxuICAgICAgZGVmYXVsdE9wdHMubWVzc2FnZSB8fCAnU2NyaXB0IGZhaWxlZC4nXG4gICAgKTtcbiAgfVxuICBpZiAobWVzc2FnZSBpbnN0YW5jZW9mIFBhcnNlLkVycm9yKSB7XG4gICAgcmV0dXJuIG1lc3NhZ2U7XG4gIH1cblxuICBjb25zdCBjb2RlID0gZGVmYXVsdE9wdHMuY29kZSB8fCBQYXJzZS5FcnJvci5TQ1JJUFRfRkFJTEVEO1xuICAvLyBJZiBpdCdzIGFuIGVycm9yLCBtYXJrIGl0IGFzIGEgc2NyaXB0IGZhaWxlZFxuICBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIG5ldyBQYXJzZS5FcnJvcihjb2RlLCBtZXNzYWdlKTtcbiAgfVxuICBjb25zdCBlcnJvciA9IG5ldyBQYXJzZS5FcnJvcihjb2RlLCBtZXNzYWdlLm1lc3NhZ2UgfHwgbWVzc2FnZSk7XG4gIGlmIChtZXNzYWdlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICBlcnJvci5zdGFjayA9IG1lc3NhZ2Uuc3RhY2s7XG4gIH1cbiAgcmV0dXJuIGVycm9yO1xufVxuZXhwb3J0IGZ1bmN0aW9uIG1heWJlUnVuVmFsaWRhdG9yKHJlcXVlc3QsIGZ1bmN0aW9uTmFtZSkge1xuICBjb25zdCB0aGVWYWxpZGF0b3IgPSBnZXRWYWxpZGF0b3IoZnVuY3Rpb25OYW1lLCBQYXJzZS5hcHBsaWNhdGlvbklkKTtcbiAgaWYgKCF0aGVWYWxpZGF0b3IpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHR5cGVvZiB0aGVWYWxpZGF0b3IgPT09ICdvYmplY3QnICYmIHRoZVZhbGlkYXRvci5za2lwV2l0aE1hc3RlcktleSAmJiByZXF1ZXN0Lm1hc3Rlcikge1xuICAgIHJlcXVlc3Quc2tpcFdpdGhNYXN0ZXJLZXkgPSB0cnVlO1xuICB9XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdGhlVmFsaWRhdG9yID09PSAnb2JqZWN0J1xuICAgICAgICAgID8gYnVpbHRJblRyaWdnZXJWYWxpZGF0b3IodGhlVmFsaWRhdG9yLCByZXF1ZXN0KVxuICAgICAgICAgIDogdGhlVmFsaWRhdG9yKHJlcXVlc3QpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlID0+IHtcbiAgICAgICAgY29uc3QgZXJyb3IgPSByZXNvbHZlRXJyb3IoZSwge1xuICAgICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLlZBTElEQVRJT05fRVJST1IsXG4gICAgICAgICAgbWVzc2FnZTogJ1ZhbGlkYXRpb24gZmFpbGVkLicsXG4gICAgICAgIH0pO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gIH0pO1xufVxuZnVuY3Rpb24gYnVpbHRJblRyaWdnZXJWYWxpZGF0b3Iob3B0aW9ucywgcmVxdWVzdCkge1xuICBpZiAocmVxdWVzdC5tYXN0ZXIgJiYgIW9wdGlvbnMudmFsaWRhdGVNYXN0ZXJLZXkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgbGV0IHJlcVVzZXIgPSByZXF1ZXN0LnVzZXI7XG4gIGlmIChcbiAgICAhcmVxVXNlciAmJlxuICAgIHJlcXVlc3Qub2JqZWN0ICYmXG4gICAgcmVxdWVzdC5vYmplY3QuY2xhc3NOYW1lID09PSAnX1VzZXInICYmXG4gICAgIXJlcXVlc3Qub2JqZWN0LmV4aXN0ZWQoKVxuICApIHtcbiAgICByZXFVc2VyID0gcmVxdWVzdC5vYmplY3Q7XG4gIH1cbiAgaWYgKG9wdGlvbnMucmVxdWlyZVVzZXIgJiYgIXJlcVVzZXIpIHtcbiAgICB0aHJvdyAnVmFsaWRhdGlvbiBmYWlsZWQuIFBsZWFzZSBsb2dpbiB0byBjb250aW51ZS4nO1xuICB9XG4gIGlmIChvcHRpb25zLnJlcXVpcmVNYXN0ZXIgJiYgIXJlcXVlc3QubWFzdGVyKSB7XG4gICAgdGhyb3cgJ1ZhbGlkYXRpb24gZmFpbGVkLiBNYXN0ZXIga2V5IGlzIHJlcXVpcmVkIHRvIGNvbXBsZXRlIHRoaXMgcmVxdWVzdC4nO1xuICB9XG4gIGxldCBwYXJhbXMgPSByZXF1ZXN0LnBhcmFtcyB8fCB7fTtcbiAgaWYgKHJlcXVlc3Qub2JqZWN0KSB7XG4gICAgcGFyYW1zID0gcmVxdWVzdC5vYmplY3QudG9KU09OKCk7XG4gIH1cbiAgY29uc3QgcmVxdWlyZWRQYXJhbSA9IGtleSA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBwYXJhbXNba2V5XTtcbiAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgdGhyb3cgYFZhbGlkYXRpb24gZmFpbGVkLiBQbGVhc2Ugc3BlY2lmeSBkYXRhIGZvciAke2tleX0uYDtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgdmFsaWRhdGVPcHRpb25zID0gKG9wdCwga2V5LCB2YWwpID0+IHtcbiAgICBsZXQgb3B0cyA9IG9wdC5vcHRpb25zO1xuICAgIGlmICh0eXBlb2Ygb3B0cyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gb3B0cyh2YWwpO1xuICAgICAgICBpZiAoIXJlc3VsdCAmJiByZXN1bHQgIT0gbnVsbCkge1xuICAgICAgICAgIHRocm93IG9wdC5lcnJvciB8fCBgVmFsaWRhdGlvbiBmYWlsZWQuIEludmFsaWQgdmFsdWUgZm9yICR7a2V5fS5gO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmICghZSkge1xuICAgICAgICAgIHRocm93IG9wdC5lcnJvciB8fCBgVmFsaWRhdGlvbiBmYWlsZWQuIEludmFsaWQgdmFsdWUgZm9yICR7a2V5fS5gO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhyb3cgb3B0LmVycm9yIHx8IGUubWVzc2FnZSB8fCBlO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkob3B0cykpIHtcbiAgICAgIG9wdHMgPSBbb3B0Lm9wdGlvbnNdO1xuICAgIH1cblxuICAgIGlmICghb3B0cy5pbmNsdWRlcyh2YWwpKSB7XG4gICAgICB0aHJvdyAoXG4gICAgICAgIG9wdC5lcnJvciB8fCBgVmFsaWRhdGlvbiBmYWlsZWQuIEludmFsaWQgb3B0aW9uIGZvciAke2tleX0uIEV4cGVjdGVkOiAke29wdHMuam9pbignLCAnKX1gXG4gICAgICApO1xuICAgIH1cbiAgfTtcblxuICBjb25zdCBnZXRUeXBlID0gZm4gPT4ge1xuICAgIGNvbnN0IG1hdGNoID0gZm4gJiYgZm4udG9TdHJpbmcoKS5tYXRjaCgvXlxccypmdW5jdGlvbiAoXFx3KykvKTtcbiAgICByZXR1cm4gKG1hdGNoID8gbWF0Y2hbMV0gOiAnJykudG9Mb3dlckNhc2UoKTtcbiAgfTtcbiAgaWYgKEFycmF5LmlzQXJyYXkob3B0aW9ucy5maWVsZHMpKSB7XG4gICAgZm9yIChjb25zdCBrZXkgb2Ygb3B0aW9ucy5maWVsZHMpIHtcbiAgICAgIHJlcXVpcmVkUGFyYW0oa2V5KTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gb3B0aW9ucy5maWVsZHMpIHtcbiAgICAgIGNvbnN0IG9wdCA9IG9wdGlvbnMuZmllbGRzW2tleV07XG4gICAgICBsZXQgdmFsID0gcGFyYW1zW2tleV07XG4gICAgICBpZiAodHlwZW9mIG9wdCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmVxdWlyZWRQYXJhbShvcHQpO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBvcHQgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGlmIChvcHQuZGVmYXVsdCAhPSBudWxsICYmIHZhbCA9PSBudWxsKSB7XG4gICAgICAgICAgdmFsID0gb3B0LmRlZmF1bHQ7XG4gICAgICAgICAgcGFyYW1zW2tleV0gPSB2YWw7XG4gICAgICAgICAgaWYgKHJlcXVlc3Qub2JqZWN0KSB7XG4gICAgICAgICAgICByZXF1ZXN0Lm9iamVjdC5zZXQoa2V5LCB2YWwpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0LmNvbnN0YW50ICYmIHJlcXVlc3Qub2JqZWN0KSB7XG4gICAgICAgICAgaWYgKHJlcXVlc3Qub3JpZ2luYWwpIHtcbiAgICAgICAgICAgIHJlcXVlc3Qub2JqZWN0LnNldChrZXksIHJlcXVlc3Qub3JpZ2luYWwuZ2V0KGtleSkpO1xuICAgICAgICAgIH0gZWxzZSBpZiAob3B0LmRlZmF1bHQgIT0gbnVsbCkge1xuICAgICAgICAgICAgcmVxdWVzdC5vYmplY3Quc2V0KGtleSwgb3B0LmRlZmF1bHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0LnJlcXVpcmVkKSB7XG4gICAgICAgICAgcmVxdWlyZWRQYXJhbShrZXkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChvcHQudHlwZSkge1xuICAgICAgICAgIGNvbnN0IHR5cGUgPSBnZXRUeXBlKG9wdC50eXBlKTtcbiAgICAgICAgICBpZiAodHlwZSA9PSAnYXJyYXknICYmICFBcnJheS5pc0FycmF5KHZhbCkpIHtcbiAgICAgICAgICAgIHRocm93IGBWYWxpZGF0aW9uIGZhaWxlZC4gSW52YWxpZCB0eXBlIGZvciAke2tleX0uIEV4cGVjdGVkOiBhcnJheWA7XG4gICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsICE9PSB0eXBlKSB7XG4gICAgICAgICAgICB0aHJvdyBgVmFsaWRhdGlvbiBmYWlsZWQuIEludmFsaWQgdHlwZSBmb3IgJHtrZXl9LiBFeHBlY3RlZDogJHt0eXBlfWA7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChvcHQub3B0aW9ucykge1xuICAgICAgICAgIHZhbGlkYXRlT3B0aW9ucyhvcHQsIGtleSwgdmFsKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuICBjb25zdCB1c2VyS2V5cyA9IG9wdGlvbnMucmVxdWlyZVVzZXJLZXlzIHx8IFtdO1xuICBpZiAoQXJyYXkuaXNBcnJheSh1c2VyS2V5cykpIHtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiB1c2VyS2V5cykge1xuICAgICAgaWYgKCFyZXFVc2VyKSB7XG4gICAgICAgIHRocm93ICdQbGVhc2UgbG9naW4gdG8gbWFrZSB0aGlzIHJlcXVlc3QuJztcbiAgICAgIH1cblxuICAgICAgaWYgKHJlcVVzZXIuZ2V0KGtleSkgPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBgVmFsaWRhdGlvbiBmYWlsZWQuIFBsZWFzZSBzZXQgZGF0YSBmb3IgJHtrZXl9IG9uIHlvdXIgYWNjb3VudC5gO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgdXNlcktleXMgPT09ICdvYmplY3QnKSB7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gb3B0aW9ucy5yZXF1aXJlVXNlcktleXMpIHtcbiAgICAgIGNvbnN0IG9wdCA9IG9wdGlvbnMucmVxdWlyZVVzZXJLZXlzW2tleV07XG4gICAgICBpZiAob3B0Lm9wdGlvbnMpIHtcbiAgICAgICAgdmFsaWRhdGVPcHRpb25zKG9wdCwga2V5LCByZXFVc2VyLmdldChrZXkpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLy8gVG8gYmUgdXNlZCBhcyBwYXJ0IG9mIHRoZSBwcm9taXNlIGNoYWluIHdoZW4gc2F2aW5nL2RlbGV0aW5nIGFuIG9iamVjdFxuLy8gV2lsbCByZXNvbHZlIHN1Y2Nlc3NmdWxseSBpZiBubyB0cmlnZ2VyIGlzIGNvbmZpZ3VyZWRcbi8vIFJlc29sdmVzIHRvIGFuIG9iamVjdCwgZW1wdHkgb3IgY29udGFpbmluZyBhbiBvYmplY3Qga2V5LiBBIGJlZm9yZVNhdmVcbi8vIHRyaWdnZXIgd2lsbCBzZXQgdGhlIG9iamVjdCBrZXkgdG8gdGhlIHJlc3QgZm9ybWF0IG9iamVjdCB0byBzYXZlLlxuLy8gb3JpZ2luYWxQYXJzZU9iamVjdCBpcyBvcHRpb25hbCwgd2Ugb25seSBuZWVkIHRoYXQgZm9yIGJlZm9yZS9hZnRlclNhdmUgZnVuY3Rpb25zXG5leHBvcnQgZnVuY3Rpb24gbWF5YmVSdW5UcmlnZ2VyKFxuICB0cmlnZ2VyVHlwZSxcbiAgYXV0aCxcbiAgcGFyc2VPYmplY3QsXG4gIG9yaWdpbmFsUGFyc2VPYmplY3QsXG4gIGNvbmZpZyxcbiAgY29udGV4dFxuKSB7XG4gIGlmICghcGFyc2VPYmplY3QpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgfVxuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIHZhciB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihwYXJzZU9iamVjdC5jbGFzc05hbWUsIHRyaWdnZXJUeXBlLCBjb25maWcuYXBwbGljYXRpb25JZCk7XG4gICAgaWYgKCF0cmlnZ2VyKSByZXR1cm4gcmVzb2x2ZSgpO1xuICAgIHZhciByZXF1ZXN0ID0gZ2V0UmVxdWVzdE9iamVjdChcbiAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgYXV0aCxcbiAgICAgIHBhcnNlT2JqZWN0LFxuICAgICAgb3JpZ2luYWxQYXJzZU9iamVjdCxcbiAgICAgIGNvbmZpZyxcbiAgICAgIGNvbnRleHRcbiAgICApO1xuICAgIHZhciB7IHN1Y2Nlc3MsIGVycm9yIH0gPSBnZXRSZXNwb25zZU9iamVjdChcbiAgICAgIHJlcXVlc3QsXG4gICAgICBvYmplY3QgPT4ge1xuICAgICAgICBsb2dUcmlnZ2VyU3VjY2Vzc0JlZm9yZUhvb2soXG4gICAgICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICAgICAgcGFyc2VPYmplY3QuY2xhc3NOYW1lLFxuICAgICAgICAgIHBhcnNlT2JqZWN0LnRvSlNPTigpLFxuICAgICAgICAgIG9iamVjdCxcbiAgICAgICAgICBhdXRoXG4gICAgICAgICk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYmVmb3JlU2F2ZSB8fFxuICAgICAgICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlclNhdmUgfHxcbiAgICAgICAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYmVmb3JlRGVsZXRlIHx8XG4gICAgICAgICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmFmdGVyRGVsZXRlXG4gICAgICAgICkge1xuICAgICAgICAgIE9iamVjdC5hc3NpZ24oY29udGV4dCwgcmVxdWVzdC5jb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICByZXNvbHZlKG9iamVjdCk7XG4gICAgICB9LFxuICAgICAgZXJyb3IgPT4ge1xuICAgICAgICBsb2dUcmlnZ2VyRXJyb3JCZWZvcmVIb29rKFxuICAgICAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgICAgIHBhcnNlT2JqZWN0LmNsYXNzTmFtZSxcbiAgICAgICAgICBwYXJzZU9iamVjdC50b0pTT04oKSxcbiAgICAgICAgICBhdXRoLFxuICAgICAgICAgIGVycm9yXG4gICAgICAgICk7XG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICB9XG4gICAgKTtcblxuICAgIC8vIEFmdGVyU2F2ZSBhbmQgYWZ0ZXJEZWxldGUgdHJpZ2dlcnMgY2FuIHJldHVybiBhIHByb21pc2UsIHdoaWNoIGlmIHRoZXlcbiAgICAvLyBkbywgbmVlZHMgdG8gYmUgcmVzb2x2ZWQgYmVmb3JlIHRoaXMgcHJvbWlzZSBpcyByZXNvbHZlZCxcbiAgICAvLyBzbyB0cmlnZ2VyIGV4ZWN1dGlvbiBpcyBzeW5jZWQgd2l0aCBSZXN0V3JpdGUuZXhlY3V0ZSgpIGNhbGwuXG4gICAgLy8gSWYgdHJpZ2dlcnMgZG8gbm90IHJldHVybiBhIHByb21pc2UsIHRoZXkgY2FuIHJ1biBhc3luYyBjb2RlIHBhcmFsbGVsXG4gICAgLy8gdG8gdGhlIFJlc3RXcml0ZS5leGVjdXRlKCkgY2FsbC5cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIG1heWJlUnVuVmFsaWRhdG9yKHJlcXVlc3QsIGAke3RyaWdnZXJUeXBlfS4ke3BhcnNlT2JqZWN0LmNsYXNzTmFtZX1gKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIGlmIChyZXF1ZXN0LnNraXBXaXRoTWFzdGVyS2V5KSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSB0cmlnZ2VyKHJlcXVlc3QpO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmFmdGVyU2F2ZSB8fFxuICAgICAgICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlckRlbGV0ZSB8fFxuICAgICAgICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlckxvZ2luXG4gICAgICAgICkge1xuICAgICAgICAgIGxvZ1RyaWdnZXJBZnRlckhvb2sodHJpZ2dlclR5cGUsIHBhcnNlT2JqZWN0LmNsYXNzTmFtZSwgcGFyc2VPYmplY3QudG9KU09OKCksIGF1dGgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGJlZm9yZVNhdmUgaXMgZXhwZWN0ZWQgdG8gcmV0dXJuIG51bGwgKG5vdGhpbmcpXG4gICAgICAgIGlmICh0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYmVmb3JlU2F2ZSkge1xuICAgICAgICAgIGlmIChwcm9taXNlICYmIHR5cGVvZiBwcm9taXNlLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAvLyByZXNwb25zZS5vYmplY3QgbWF5IGNvbWUgZnJvbSBleHByZXNzIHJvdXRpbmcgYmVmb3JlIGhvb2tcbiAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLm9iamVjdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgICAgfSlcbiAgICAgIC50aGVuKHN1Y2Nlc3MsIGVycm9yKTtcbiAgfSk7XG59XG5cbi8vIENvbnZlcnRzIGEgUkVTVC1mb3JtYXQgb2JqZWN0IHRvIGEgUGFyc2UuT2JqZWN0XG4vLyBkYXRhIGlzIGVpdGhlciBjbGFzc05hbWUgb3IgYW4gb2JqZWN0XG5leHBvcnQgZnVuY3Rpb24gaW5mbGF0ZShkYXRhLCByZXN0T2JqZWN0KSB7XG4gIHZhciBjb3B5ID0gdHlwZW9mIGRhdGEgPT0gJ29iamVjdCcgPyBkYXRhIDogeyBjbGFzc05hbWU6IGRhdGEgfTtcbiAgZm9yICh2YXIga2V5IGluIHJlc3RPYmplY3QpIHtcbiAgICBjb3B5W2tleV0gPSByZXN0T2JqZWN0W2tleV07XG4gIH1cbiAgcmV0dXJuIFBhcnNlLk9iamVjdC5mcm9tSlNPTihjb3B5KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJ1bkxpdmVRdWVyeUV2ZW50SGFuZGxlcnMoZGF0YSwgYXBwbGljYXRpb25JZCA9IFBhcnNlLmFwcGxpY2F0aW9uSWQpIHtcbiAgaWYgKCFfdHJpZ2dlclN0b3JlIHx8ICFfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdIHx8ICFfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdLkxpdmVRdWVyeSkge1xuICAgIHJldHVybjtcbiAgfVxuICBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdLkxpdmVRdWVyeS5mb3JFYWNoKGhhbmRsZXIgPT4gaGFuZGxlcihkYXRhKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXF1ZXN0RmlsZU9iamVjdCh0cmlnZ2VyVHlwZSwgYXV0aCwgZmlsZU9iamVjdCwgY29uZmlnKSB7XG4gIGNvbnN0IHJlcXVlc3QgPSB7XG4gICAgLi4uZmlsZU9iamVjdCxcbiAgICB0cmlnZ2VyTmFtZTogdHJpZ2dlclR5cGUsXG4gICAgbWFzdGVyOiBmYWxzZSxcbiAgICBsb2c6IGNvbmZpZy5sb2dnZXJDb250cm9sbGVyLFxuICAgIGhlYWRlcnM6IGNvbmZpZy5oZWFkZXJzLFxuICAgIGlwOiBjb25maWcuaXAsXG4gIH07XG5cbiAgaWYgKCFhdXRoKSB7XG4gICAgcmV0dXJuIHJlcXVlc3Q7XG4gIH1cbiAgaWYgKGF1dGguaXNNYXN0ZXIpIHtcbiAgICByZXF1ZXN0WydtYXN0ZXInXSA9IHRydWU7XG4gIH1cbiAgaWYgKGF1dGgudXNlcikge1xuICAgIHJlcXVlc3RbJ3VzZXInXSA9IGF1dGgudXNlcjtcbiAgfVxuICBpZiAoYXV0aC5pbnN0YWxsYXRpb25JZCkge1xuICAgIHJlcXVlc3RbJ2luc3RhbGxhdGlvbklkJ10gPSBhdXRoLmluc3RhbGxhdGlvbklkO1xuICB9XG4gIHJldHVybiByZXF1ZXN0O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbWF5YmVSdW5GaWxlVHJpZ2dlcih0cmlnZ2VyVHlwZSwgZmlsZU9iamVjdCwgY29uZmlnLCBhdXRoKSB7XG4gIGNvbnN0IGZpbGVUcmlnZ2VyID0gZ2V0RmlsZVRyaWdnZXIodHJpZ2dlclR5cGUsIGNvbmZpZy5hcHBsaWNhdGlvbklkKTtcbiAgaWYgKHR5cGVvZiBmaWxlVHJpZ2dlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXF1ZXN0ID0gZ2V0UmVxdWVzdEZpbGVPYmplY3QodHJpZ2dlclR5cGUsIGF1dGgsIGZpbGVPYmplY3QsIGNvbmZpZyk7XG4gICAgICBhd2FpdCBtYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0LCBgJHt0cmlnZ2VyVHlwZX0uJHtGaWxlQ2xhc3NOYW1lfWApO1xuICAgICAgaWYgKHJlcXVlc3Quc2tpcFdpdGhNYXN0ZXJLZXkpIHtcbiAgICAgICAgcmV0dXJuIGZpbGVPYmplY3Q7XG4gICAgICB9XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBmaWxlVHJpZ2dlcihyZXF1ZXN0KTtcbiAgICAgIGxvZ1RyaWdnZXJTdWNjZXNzQmVmb3JlSG9vayhcbiAgICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICAgICdQYXJzZS5GaWxlJyxcbiAgICAgICAgeyAuLi5maWxlT2JqZWN0LmZpbGUudG9KU09OKCksIGZpbGVTaXplOiBmaWxlT2JqZWN0LmZpbGVTaXplIH0sXG4gICAgICAgIHJlc3VsdCxcbiAgICAgICAgYXV0aFxuICAgICAgKTtcbiAgICAgIHJldHVybiByZXN1bHQgfHwgZmlsZU9iamVjdDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nVHJpZ2dlckVycm9yQmVmb3JlSG9vayhcbiAgICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICAgICdQYXJzZS5GaWxlJyxcbiAgICAgICAgeyAuLi5maWxlT2JqZWN0LmZpbGUudG9KU09OKCksIGZpbGVTaXplOiBmaWxlT2JqZWN0LmZpbGVTaXplIH0sXG4gICAgICAgIGF1dGgsXG4gICAgICAgIGVycm9yXG4gICAgICApO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG4gIHJldHVybiBmaWxlT2JqZWN0O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbWF5YmVSdW5Db25uZWN0VHJpZ2dlcih0cmlnZ2VyVHlwZSwgcmVxdWVzdCkge1xuICBjb25zdCB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihDb25uZWN0Q2xhc3NOYW1lLCB0cmlnZ2VyVHlwZSwgUGFyc2UuYXBwbGljYXRpb25JZCk7XG4gIGlmICghdHJpZ2dlcikge1xuICAgIHJldHVybjtcbiAgfVxuICByZXF1ZXN0LnVzZXIgPSBhd2FpdCB1c2VyRm9yU2Vzc2lvblRva2VuKHJlcXVlc3Quc2Vzc2lvblRva2VuKTtcbiAgYXdhaXQgbWF5YmVSdW5WYWxpZGF0b3IocmVxdWVzdCwgYCR7dHJpZ2dlclR5cGV9LiR7Q29ubmVjdENsYXNzTmFtZX1gKTtcbiAgaWYgKHJlcXVlc3Quc2tpcFdpdGhNYXN0ZXJLZXkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgcmV0dXJuIHRyaWdnZXIocmVxdWVzdCk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBtYXliZVJ1blN1YnNjcmliZVRyaWdnZXIodHJpZ2dlclR5cGUsIGNsYXNzTmFtZSwgcmVxdWVzdCkge1xuICBjb25zdCB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihjbGFzc05hbWUsIHRyaWdnZXJUeXBlLCBQYXJzZS5hcHBsaWNhdGlvbklkKTtcbiAgaWYgKCF0cmlnZ2VyKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnN0IHBhcnNlUXVlcnkgPSBuZXcgUGFyc2UuUXVlcnkoY2xhc3NOYW1lKTtcbiAgcGFyc2VRdWVyeS53aXRoSlNPTihyZXF1ZXN0LnF1ZXJ5KTtcbiAgcmVxdWVzdC5xdWVyeSA9IHBhcnNlUXVlcnk7XG4gIHJlcXVlc3QudXNlciA9IGF3YWl0IHVzZXJGb3JTZXNzaW9uVG9rZW4ocmVxdWVzdC5zZXNzaW9uVG9rZW4pO1xuICBhd2FpdCBtYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0LCBgJHt0cmlnZ2VyVHlwZX0uJHtjbGFzc05hbWV9YCk7XG4gIGlmIChyZXF1ZXN0LnNraXBXaXRoTWFzdGVyS2V5KSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGF3YWl0IHRyaWdnZXIocmVxdWVzdCk7XG4gIGNvbnN0IHF1ZXJ5ID0gcmVxdWVzdC5xdWVyeS50b0pTT04oKTtcbiAgaWYgKHF1ZXJ5LmtleXMpIHtcbiAgICBxdWVyeS5maWVsZHMgPSBxdWVyeS5rZXlzLnNwbGl0KCcsJyk7XG4gIH1cbiAgcmVxdWVzdC5xdWVyeSA9IHF1ZXJ5O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbWF5YmVSdW5BZnRlckV2ZW50VHJpZ2dlcih0cmlnZ2VyVHlwZSwgY2xhc3NOYW1lLCByZXF1ZXN0KSB7XG4gIGNvbnN0IHRyaWdnZXIgPSBnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHJpZ2dlclR5cGUsIFBhcnNlLmFwcGxpY2F0aW9uSWQpO1xuICBpZiAoIXRyaWdnZXIpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHJlcXVlc3Qub2JqZWN0KSB7XG4gICAgcmVxdWVzdC5vYmplY3QgPSBQYXJzZS5PYmplY3QuZnJvbUpTT04ocmVxdWVzdC5vYmplY3QpO1xuICB9XG4gIGlmIChyZXF1ZXN0Lm9yaWdpbmFsKSB7XG4gICAgcmVxdWVzdC5vcmlnaW5hbCA9IFBhcnNlLk9iamVjdC5mcm9tSlNPTihyZXF1ZXN0Lm9yaWdpbmFsKTtcbiAgfVxuICByZXF1ZXN0LnVzZXIgPSBhd2FpdCB1c2VyRm9yU2Vzc2lvblRva2VuKHJlcXVlc3Quc2Vzc2lvblRva2VuKTtcbiAgYXdhaXQgbWF5YmVSdW5WYWxpZGF0b3IocmVxdWVzdCwgYCR7dHJpZ2dlclR5cGV9LiR7Y2xhc3NOYW1lfWApO1xuICBpZiAocmVxdWVzdC5za2lwV2l0aE1hc3RlcktleSkge1xuICAgIHJldHVybjtcbiAgfVxuICByZXR1cm4gdHJpZ2dlcihyZXF1ZXN0KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gdXNlckZvclNlc3Npb25Ub2tlbihzZXNzaW9uVG9rZW4pIHtcbiAgaWYgKCFzZXNzaW9uVG9rZW4pIHtcbiAgICByZXR1cm47XG4gIH1cbiAgY29uc3QgcSA9IG5ldyBQYXJzZS5RdWVyeSgnX1Nlc3Npb24nKTtcbiAgcS5lcXVhbFRvKCdzZXNzaW9uVG9rZW4nLCBzZXNzaW9uVG9rZW4pO1xuICBxLmluY2x1ZGUoJ3VzZXInKTtcbiAgY29uc3Qgc2Vzc2lvbiA9IGF3YWl0IHEuZmlyc3QoeyB1c2VNYXN0ZXJLZXk6IHRydWUgfSk7XG4gIGlmICghc2Vzc2lvbikge1xuICAgIHJldHVybjtcbiAgfVxuICByZXR1cm4gc2Vzc2lvbi5nZXQoJ3VzZXInKTtcbn1cbiJdfQ== \ No newline at end of file diff --git a/lib/vendor/README.md b/lib/vendor/README.md deleted file mode 100644 index 04e3256f72..0000000000 --- a/lib/vendor/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# mongoUrl - -A fork of node's `url` module, with the modification that commas and colons are -allowed in hostnames. While this results in a slightly incorrect parsed result, -as the hostname field for a mongodb should be an array of replica sets, it's -good enough to let us pull out and escape the auth portion of the URL. - -https://github.com/parse-community/parse-server/pull/986 diff --git a/lib/vendor/mongodbUrl.js b/lib/vendor/mongodbUrl.js deleted file mode 100644 index 6b95552f05..0000000000 --- a/lib/vendor/mongodbUrl.js +++ /dev/null @@ -1,1064 +0,0 @@ -// A slightly patched version of node's url module, with support for mongodb:// -// uris. -// -// See https://github.com/nodejs/node/blob/master/LICENSE for licensing -// information -'use strict'; - -const punycode = require('punycode'); - -exports.parse = urlParse; -exports.resolve = urlResolve; -exports.resolveObject = urlResolveObject; -exports.format = urlFormat; -exports.Url = Url; - -function Url() { - this.protocol = null; - this.slashes = null; - this.auth = null; - this.host = null; - this.port = null; - this.hostname = null; - this.hash = null; - this.search = null; - this.query = null; - this.pathname = null; - this.path = null; - this.href = null; -} // Reference: RFC 3986, RFC 1808, RFC 2396 -// define these here so at least they only have to be -// compiled once on the first module load. - - -const protocolPattern = /^([a-z0-9.+-]+:)/i; -const portPattern = /:[0-9]*$/; // Special case for a simple path URL - -const simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/; // protocols that can allow "unsafe" and "unwise" chars. - -const unsafeProtocol = { - javascript: true, - 'javascript:': true -}; // protocols that never have a hostname. - -const hostlessProtocol = { - javascript: true, - 'javascript:': true -}; // protocols that always contain a // bit. - -const slashedProtocol = { - http: true, - 'http:': true, - https: true, - 'https:': true, - ftp: true, - 'ftp:': true, - gopher: true, - 'gopher:': true, - file: true, - 'file:': true -}; - -const querystring = require('querystring'); -/* istanbul ignore next: improve coverage */ - - -function urlParse(url, parseQueryString, slashesDenoteHost) { - if (url instanceof Url) return url; - var u = new Url(); - u.parse(url, parseQueryString, slashesDenoteHost); - return u; -} -/* istanbul ignore next: improve coverage */ - - -Url.prototype.parse = function (url, parseQueryString, slashesDenoteHost) { - if (typeof url !== 'string') { - throw new TypeError('Parameter "url" must be a string, not ' + typeof url); - } // Copy chrome, IE, opera backslash-handling behavior. - // Back slashes before the query string get converted to forward slashes - // See: https://code.google.com/p/chromium/issues/detail?id=25916 - - - var hasHash = false; - var start = -1; - var end = -1; - var rest = ''; - var lastPos = 0; - var i = 0; - - for (var inWs = false, split = false; i < url.length; ++i) { - const code = url.charCodeAt(i); // Find first and last non-whitespace characters for trimming - - const isWs = code === 32 - /* */ - || code === 9 - /*\t*/ - || code === 13 - /*\r*/ - || code === 10 - /*\n*/ - || code === 12 - /*\f*/ - || code === 160 - /*\u00A0*/ - || code === 65279; - /*\uFEFF*/ - - if (start === -1) { - if (isWs) continue; - lastPos = start = i; - } else { - if (inWs) { - if (!isWs) { - end = -1; - inWs = false; - } - } else if (isWs) { - end = i; - inWs = true; - } - } // Only convert backslashes while we haven't seen a split character - - - if (!split) { - switch (code) { - case 35: - // '#' - hasHash = true; - // Fall through - - case 63: - // '?' - split = true; - break; - - case 92: - // '\\' - if (i - lastPos > 0) rest += url.slice(lastPos, i); - rest += '/'; - lastPos = i + 1; - break; - } - } else if (!hasHash && code === 35 - /*#*/ - ) { - hasHash = true; - } - } // Check if string was non-empty (including strings with only whitespace) - - - if (start !== -1) { - if (lastPos === start) { - // We didn't convert any backslashes - if (end === -1) { - if (start === 0) rest = url;else rest = url.slice(start); - } else { - rest = url.slice(start, end); - } - } else if (end === -1 && lastPos < url.length) { - // We converted some backslashes and have only part of the entire string - rest += url.slice(lastPos); - } else if (end !== -1 && lastPos < end) { - // We converted some backslashes and have only part of the entire string - rest += url.slice(lastPos, end); - } - } - - if (!slashesDenoteHost && !hasHash) { - // Try fast path regexp - const simplePath = simplePathPattern.exec(rest); - - if (simplePath) { - this.path = rest; - this.href = rest; - this.pathname = simplePath[1]; - - if (simplePath[2]) { - this.search = simplePath[2]; - - if (parseQueryString) { - this.query = querystring.parse(this.search.slice(1)); - } else { - this.query = this.search.slice(1); - } - } else if (parseQueryString) { - this.search = ''; - this.query = {}; - } - - return this; - } - } - - var proto = protocolPattern.exec(rest); - - if (proto) { - proto = proto[0]; - var lowerProto = proto.toLowerCase(); - this.protocol = lowerProto; - rest = rest.slice(proto.length); - } // figure out if it's got a host - // user@server is *always* interpreted as a hostname, and url - // resolution will treat //foo/bar as host=foo,path=bar because that's - // how the browser resolves relative URLs. - - - if (slashesDenoteHost || proto || /^\/\/[^@\/]+@[^@\/]+/.test(rest)) { - var slashes = rest.charCodeAt(0) === 47 - /*/*/ - && rest.charCodeAt(1) === 47; - /*/*/ - - if (slashes && !(proto && hostlessProtocol[proto])) { - rest = rest.slice(2); - this.slashes = true; - } - } - - if (!hostlessProtocol[proto] && (slashes || proto && !slashedProtocol[proto])) { - // there's a hostname. - // the first instance of /, ?, ;, or # ends the host. - // - // If there is an @ in the hostname, then non-host chars *are* allowed - // to the left of the last @ sign, unless some host-ending character - // comes *before* the @-sign. - // URLs are obnoxious. - // - // ex: - // http://a@b@c/ => user:a@b host:c - // http://a@b?@c => user:a host:b path:/?@c - // v0.12 TODO(isaacs): This is not quite how Chrome does things. - // Review our test case against browsers more comprehensively. - var hostEnd = -1; - var atSign = -1; - var nonHost = -1; - - for (i = 0; i < rest.length; ++i) { - switch (rest.charCodeAt(i)) { - case 9: // '\t' - - case 10: // '\n' - - case 13: // '\r' - - case 32: // ' ' - - case 34: // '"' - - case 37: // '%' - - case 39: // '\'' - - case 59: // ';' - - case 60: // '<' - - case 62: // '>' - - case 92: // '\\' - - case 94: // '^' - - case 96: // '`' - - case 123: // '{' - - case 124: // '|' - - case 125: - // '}' - // Characters that are never ever allowed in a hostname from RFC 2396 - if (nonHost === -1) nonHost = i; - break; - - case 35: // '#' - - case 47: // '/' - - case 63: - // '?' - // Find the first instance of any host-ending characters - if (nonHost === -1) nonHost = i; - hostEnd = i; - break; - - case 64: - // '@' - // At this point, either we have an explicit point where the - // auth portion cannot go past, or the last @ char is the decider. - atSign = i; - nonHost = -1; - break; - } - - if (hostEnd !== -1) break; - } - - start = 0; - - if (atSign !== -1) { - this.auth = decodeURIComponent(rest.slice(0, atSign)); - start = atSign + 1; - } - - if (nonHost === -1) { - this.host = rest.slice(start); - rest = ''; - } else { - this.host = rest.slice(start, nonHost); - rest = rest.slice(nonHost); - } // pull out port. - - - this.parseHost(); // we've indicated that there is a hostname, - // so even if it's empty, it has to be present. - - if (typeof this.hostname !== 'string') this.hostname = ''; - var hostname = this.hostname; // if hostname begins with [ and ends with ] - // assume that it's an IPv6 address. - - var ipv6Hostname = hostname.charCodeAt(0) === 91 - /*[*/ - && hostname.charCodeAt(hostname.length - 1) === 93; - /*]*/ - // validate a little. - - if (!ipv6Hostname) { - const result = validateHostname(this, rest, hostname); - if (result !== undefined) rest = result; - } // hostnames are always lower case. - - - this.hostname = this.hostname.toLowerCase(); - - if (!ipv6Hostname) { - // IDNA Support: Returns a punycoded representation of "domain". - // It only converts parts of the domain name that - // have non-ASCII characters, i.e. it doesn't matter if - // you call it with a domain that already is ASCII-only. - this.hostname = punycode.toASCII(this.hostname); - } - - var p = this.port ? ':' + this.port : ''; - var h = this.hostname || ''; - this.host = h + p; // strip [ and ] from the hostname - // the host field still retains them, though - - if (ipv6Hostname) { - this.hostname = this.hostname.slice(1, -1); - - if (rest[0] !== '/') { - rest = '/' + rest; - } - } - } // now rest is set to the post-host stuff. - // chop off any delim chars. - - - if (!unsafeProtocol[lowerProto]) { - // First, make 100% sure that any "autoEscape" chars get - // escaped, even if encodeURIComponent doesn't think they - // need to be. - const result = autoEscapeStr(rest); - if (result !== undefined) rest = result; - } - - var questionIdx = -1; - var hashIdx = -1; - - for (i = 0; i < rest.length; ++i) { - const code = rest.charCodeAt(i); - - if (code === 35 - /*#*/ - ) { - this.hash = rest.slice(i); - hashIdx = i; - break; - } else if (code === 63 - /*?*/ - && questionIdx === -1) { - questionIdx = i; - } - } - - if (questionIdx !== -1) { - if (hashIdx === -1) { - this.search = rest.slice(questionIdx); - this.query = rest.slice(questionIdx + 1); - } else { - this.search = rest.slice(questionIdx, hashIdx); - this.query = rest.slice(questionIdx + 1, hashIdx); - } - - if (parseQueryString) { - this.query = querystring.parse(this.query); - } - } else if (parseQueryString) { - // no query string, but parseQueryString still requested - this.search = ''; - this.query = {}; - } - - var firstIdx = questionIdx !== -1 && (hashIdx === -1 || questionIdx < hashIdx) ? questionIdx : hashIdx; - - if (firstIdx === -1) { - if (rest.length > 0) this.pathname = rest; - } else if (firstIdx > 0) { - this.pathname = rest.slice(0, firstIdx); - } - - if (slashedProtocol[lowerProto] && this.hostname && !this.pathname) { - this.pathname = '/'; - } // to support http.request - - - if (this.pathname || this.search) { - const p = this.pathname || ''; - const s = this.search || ''; - this.path = p + s; - } // finally, reconstruct the href based on what has been validated. - - - this.href = this.format(); - return this; -}; -/* istanbul ignore next: improve coverage */ - - -function validateHostname(self, rest, hostname) { - for (var i = 0, lastPos; i <= hostname.length; ++i) { - var code; - if (i < hostname.length) code = hostname.charCodeAt(i); - - if (code === 46 - /*.*/ - || i === hostname.length) { - if (i - lastPos > 0) { - if (i - lastPos > 63) { - self.hostname = hostname.slice(0, lastPos + 63); - return '/' + hostname.slice(lastPos + 63) + rest; - } - } - - lastPos = i + 1; - continue; - } else if (code >= 48 - /*0*/ - && code <= 57 || - /*9*/ - code >= 97 - /*a*/ - && code <= 122 - /*z*/ - || code === 45 - /*-*/ - || code >= 65 - /*A*/ - && code <= 90 - /*Z*/ - || code === 43 - /*+*/ - || code === 95 - /*_*/ - || - /* BEGIN MONGO URI PATCH */ - code === 44 - /*,*/ - || code === 58 - /*:*/ - || - /* END MONGO URI PATCH */ - code > 127) { - continue; - } // Invalid host character - - - self.hostname = hostname.slice(0, i); - if (i < hostname.length) return '/' + hostname.slice(i) + rest; - break; - } -} -/* istanbul ignore next: improve coverage */ - - -function autoEscapeStr(rest) { - var newRest = ''; - var lastPos = 0; - - for (var i = 0; i < rest.length; ++i) { - // Automatically escape all delimiters and unwise characters from RFC 2396 - // Also escape single quotes in case of an XSS attack - switch (rest.charCodeAt(i)) { - case 9: - // '\t' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%09'; - lastPos = i + 1; - break; - - case 10: - // '\n' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%0A'; - lastPos = i + 1; - break; - - case 13: - // '\r' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%0D'; - lastPos = i + 1; - break; - - case 32: - // ' ' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%20'; - lastPos = i + 1; - break; - - case 34: - // '"' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%22'; - lastPos = i + 1; - break; - - case 39: - // '\'' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%27'; - lastPos = i + 1; - break; - - case 60: - // '<' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%3C'; - lastPos = i + 1; - break; - - case 62: - // '>' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%3E'; - lastPos = i + 1; - break; - - case 92: - // '\\' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%5C'; - lastPos = i + 1; - break; - - case 94: - // '^' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%5E'; - lastPos = i + 1; - break; - - case 96: - // '`' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%60'; - lastPos = i + 1; - break; - - case 123: - // '{' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%7B'; - lastPos = i + 1; - break; - - case 124: - // '|' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%7C'; - lastPos = i + 1; - break; - - case 125: - // '}' - if (i - lastPos > 0) newRest += rest.slice(lastPos, i); - newRest += '%7D'; - lastPos = i + 1; - break; - } - } - - if (lastPos === 0) return; - if (lastPos < rest.length) return newRest + rest.slice(lastPos);else return newRest; -} // format a parsed object into a url string - -/* istanbul ignore next: improve coverage */ - - -function urlFormat(obj) { - // ensure it's an object, and not a string url. - // If it's an obj, this is a no-op. - // this way, you can call url_format() on strings - // to clean up potentially wonky urls. - if (typeof obj === 'string') obj = urlParse(obj);else if (typeof obj !== 'object' || obj === null) throw new TypeError('Parameter "urlObj" must be an object, not ' + obj === null ? 'null' : typeof obj);else if (!(obj instanceof Url)) return Url.prototype.format.call(obj); - return obj.format(); -} -/* istanbul ignore next: improve coverage */ - - -Url.prototype.format = function () { - var auth = this.auth || ''; - - if (auth) { - auth = encodeAuth(auth); - auth += '@'; - } - - var protocol = this.protocol || ''; - var pathname = this.pathname || ''; - var hash = this.hash || ''; - var host = false; - var query = ''; - - if (this.host) { - host = auth + this.host; - } else if (this.hostname) { - host = auth + (this.hostname.indexOf(':') === -1 ? this.hostname : '[' + this.hostname + ']'); - - if (this.port) { - host += ':' + this.port; - } - } - - if (this.query !== null && typeof this.query === 'object') query = querystring.stringify(this.query); - var search = this.search || query && '?' + query || ''; - if (protocol && protocol.charCodeAt(protocol.length - 1) !== 58 - /*:*/ - ) protocol += ':'; - var newPathname = ''; - var lastPos = 0; - - for (var i = 0; i < pathname.length; ++i) { - switch (pathname.charCodeAt(i)) { - case 35: - // '#' - if (i - lastPos > 0) newPathname += pathname.slice(lastPos, i); - newPathname += '%23'; - lastPos = i + 1; - break; - - case 63: - // '?' - if (i - lastPos > 0) newPathname += pathname.slice(lastPos, i); - newPathname += '%3F'; - lastPos = i + 1; - break; - } - } - - if (lastPos > 0) { - if (lastPos !== pathname.length) pathname = newPathname + pathname.slice(lastPos);else pathname = newPathname; - } // only the slashedProtocols get the //. Not mailto:, xmpp:, etc. - // unless they had them to begin with. - - - if (this.slashes || (!protocol || slashedProtocol[protocol]) && host !== false) { - host = '//' + (host || ''); - if (pathname && pathname.charCodeAt(0) !== 47 - /*/*/ - ) pathname = '/' + pathname; - } else if (!host) { - host = ''; - } - - search = search.replace('#', '%23'); - if (hash && hash.charCodeAt(0) !== 35 - /*#*/ - ) hash = '#' + hash; - if (search && search.charCodeAt(0) !== 63 - /*?*/ - ) search = '?' + search; - return protocol + host + pathname + search + hash; -}; -/* istanbul ignore next: improve coverage */ - - -function urlResolve(source, relative) { - return urlParse(source, false, true).resolve(relative); -} -/* istanbul ignore next: improve coverage */ - - -Url.prototype.resolve = function (relative) { - return this.resolveObject(urlParse(relative, false, true)).format(); -}; -/* istanbul ignore next: improve coverage */ - - -function urlResolveObject(source, relative) { - if (!source) return relative; - return urlParse(source, false, true).resolveObject(relative); -} -/* istanbul ignore next: improve coverage */ - - -Url.prototype.resolveObject = function (relative) { - if (typeof relative === 'string') { - var rel = new Url(); - rel.parse(relative, false, true); - relative = rel; - } - - var result = new Url(); - var tkeys = Object.keys(this); - - for (var tk = 0; tk < tkeys.length; tk++) { - var tkey = tkeys[tk]; - result[tkey] = this[tkey]; - } // hash is always overridden, no matter what. - // even href="" will remove it. - - - result.hash = relative.hash; // if the relative url is empty, then there's nothing left to do here. - - if (relative.href === '') { - result.href = result.format(); - return result; - } // hrefs like //foo/bar always cut to the protocol. - - - if (relative.slashes && !relative.protocol) { - // take everything except the protocol from relative - var rkeys = Object.keys(relative); - - for (var rk = 0; rk < rkeys.length; rk++) { - var rkey = rkeys[rk]; - if (rkey !== 'protocol') result[rkey] = relative[rkey]; - } //urlParse appends trailing / to urls like http://www.example.com - - - if (slashedProtocol[result.protocol] && result.hostname && !result.pathname) { - result.path = result.pathname = '/'; - } - - result.href = result.format(); - return result; - } - - if (relative.protocol && relative.protocol !== result.protocol) { - // if it's a known url protocol, then changing - // the protocol does weird things - // first, if it's not file:, then we MUST have a host, - // and if there was a path - // to begin with, then we MUST have a path. - // if it is file:, then the host is dropped, - // because that's known to be hostless. - // anything else is assumed to be absolute. - if (!slashedProtocol[relative.protocol]) { - var keys = Object.keys(relative); - - for (var v = 0; v < keys.length; v++) { - var k = keys[v]; - result[k] = relative[k]; - } - - result.href = result.format(); - return result; - } - - result.protocol = relative.protocol; - - if (!relative.host && !/^file:?$/.test(relative.protocol) && !hostlessProtocol[relative.protocol]) { - const relPath = (relative.pathname || '').split('/'); - - while (relPath.length && !(relative.host = relPath.shift())); - - if (!relative.host) relative.host = ''; - if (!relative.hostname) relative.hostname = ''; - if (relPath[0] !== '') relPath.unshift(''); - if (relPath.length < 2) relPath.unshift(''); - result.pathname = relPath.join('/'); - } else { - result.pathname = relative.pathname; - } - - result.search = relative.search; - result.query = relative.query; - result.host = relative.host || ''; - result.auth = relative.auth; - result.hostname = relative.hostname || relative.host; - result.port = relative.port; // to support http.request - - if (result.pathname || result.search) { - var p = result.pathname || ''; - var s = result.search || ''; - result.path = p + s; - } - - result.slashes = result.slashes || relative.slashes; - result.href = result.format(); - return result; - } - - var isSourceAbs = result.pathname && result.pathname.charAt(0) === '/'; - var isRelAbs = relative.host || relative.pathname && relative.pathname.charAt(0) === '/'; - var mustEndAbs = isRelAbs || isSourceAbs || result.host && relative.pathname; - var removeAllDots = mustEndAbs; - var srcPath = result.pathname && result.pathname.split('/') || []; - var relPath = relative.pathname && relative.pathname.split('/') || []; - var psychotic = result.protocol && !slashedProtocol[result.protocol]; // if the url is a non-slashed url, then relative - // links like ../.. should be able - // to crawl up to the hostname, as well. This is strange. - // result.protocol has already been set by now. - // Later on, put the first path part into the host field. - - if (psychotic) { - result.hostname = ''; - result.port = null; - - if (result.host) { - if (srcPath[0] === '') srcPath[0] = result.host;else srcPath.unshift(result.host); - } - - result.host = ''; - - if (relative.protocol) { - relative.hostname = null; - relative.port = null; - - if (relative.host) { - if (relPath[0] === '') relPath[0] = relative.host;else relPath.unshift(relative.host); - } - - relative.host = null; - } - - mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === ''); - } - - if (isRelAbs) { - // it's absolute. - result.host = relative.host || relative.host === '' ? relative.host : result.host; - result.hostname = relative.hostname || relative.hostname === '' ? relative.hostname : result.hostname; - result.search = relative.search; - result.query = relative.query; - srcPath = relPath; // fall through to the dot-handling below. - } else if (relPath.length) { - // it's relative - // throw away the existing file, and take the new path instead. - if (!srcPath) srcPath = []; - srcPath.pop(); - srcPath = srcPath.concat(relPath); - result.search = relative.search; - result.query = relative.query; - } else if (relative.search !== null && relative.search !== undefined) { - // just pull out the search. - // like href='?foo'. - // Put this after the other two cases because it simplifies the booleans - if (psychotic) { - result.hostname = result.host = srcPath.shift(); //occasionally the auth can get stuck only in host - //this especially happens in cases like - //url.resolveObject('mailto:local1@domain1', 'local2@domain2') - - const authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; - - if (authInHost) { - result.auth = authInHost.shift(); - result.host = result.hostname = authInHost.shift(); - } - } - - result.search = relative.search; - result.query = relative.query; //to support http.request - - if (result.pathname !== null || result.search !== null) { - result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); - } - - result.href = result.format(); - return result; - } - - if (!srcPath.length) { - // no path at all. easy. - // we've already handled the other stuff above. - result.pathname = null; //to support http.request - - if (result.search) { - result.path = '/' + result.search; - } else { - result.path = null; - } - - result.href = result.format(); - return result; - } // if a url ENDs in . or .., then it must get a trailing slash. - // however, if it ends in anything else non-slashy, - // then it must NOT get a trailing slash. - - - var last = srcPath.slice(-1)[0]; - var hasTrailingSlash = (result.host || relative.host || srcPath.length > 1) && (last === '.' || last === '..') || last === ''; // strip single dots, resolve double dots to parent dir - // if the path tries to go above the root, `up` ends up > 0 - - var up = 0; - - for (var i = srcPath.length; i >= 0; i--) { - last = srcPath[i]; - - if (last === '.') { - spliceOne(srcPath, i); - } else if (last === '..') { - spliceOne(srcPath, i); - up++; - } else if (up) { - spliceOne(srcPath, i); - up--; - } - } // if the path is allowed to go above the root, restore leading ..s - - - if (!mustEndAbs && !removeAllDots) { - for (; up--; up) { - srcPath.unshift('..'); - } - } - - if (mustEndAbs && srcPath[0] !== '' && (!srcPath[0] || srcPath[0].charAt(0) !== '/')) { - srcPath.unshift(''); - } - - if (hasTrailingSlash && srcPath.join('/').substr(-1) !== '/') { - srcPath.push(''); - } - - var isAbsolute = srcPath[0] === '' || srcPath[0] && srcPath[0].charAt(0) === '/'; // put the host back - - if (psychotic) { - if (isAbsolute) { - result.hostname = result.host = ''; - } else { - result.hostname = result.host = srcPath.length ? srcPath.shift() : ''; - } //occasionally the auth can get stuck only in host - //this especially happens in cases like - //url.resolveObject('mailto:local1@domain1', 'local2@domain2') - - - const authInHost = result.host && result.host.indexOf('@') > 0 ? result.host.split('@') : false; - - if (authInHost) { - result.auth = authInHost.shift(); - result.host = result.hostname = authInHost.shift(); - } - } - - mustEndAbs = mustEndAbs || result.host && srcPath.length; - - if (mustEndAbs && !isAbsolute) { - srcPath.unshift(''); - } - - if (!srcPath.length) { - result.pathname = null; - result.path = null; - } else { - result.pathname = srcPath.join('/'); - } //to support request.http - - - if (result.pathname !== null || result.search !== null) { - result.path = (result.pathname ? result.pathname : '') + (result.search ? result.search : ''); - } - - result.auth = relative.auth || result.auth; - result.slashes = result.slashes || relative.slashes; - result.href = result.format(); - return result; -}; -/* istanbul ignore next: improve coverage */ - - -Url.prototype.parseHost = function () { - var host = this.host; - var port = portPattern.exec(host); - - if (port) { - port = port[0]; - - if (port !== ':') { - this.port = port.slice(1); - } - - host = host.slice(0, host.length - port.length); - } - - if (host) this.hostname = host; -}; // About 1.5x faster than the two-arg version of Array#splice(). - -/* istanbul ignore next: improve coverage */ - - -function spliceOne(list, index) { - for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) list[i] = list[k]; - - list.pop(); -} - -var hexTable = new Array(256); - -for (var i = 0; i < 256; ++i) hexTable[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase(); -/* istanbul ignore next: improve coverage */ - - -function encodeAuth(str) { - // faster encodeURIComponent alternative for encoding auth uri components - var out = ''; - var lastPos = 0; - - for (var i = 0; i < str.length; ++i) { - var c = str.charCodeAt(i); // These characters do not need escaping: - // ! - . _ ~ - // ' ( ) * : - // digits - // alpha (uppercase) - // alpha (lowercase) - - if (c === 0x21 || c === 0x2d || c === 0x2e || c === 0x5f || c === 0x7e || c >= 0x27 && c <= 0x2a || c >= 0x30 && c <= 0x3a || c >= 0x41 && c <= 0x5a || c >= 0x61 && c <= 0x7a) { - continue; - } - - if (i - lastPos > 0) out += str.slice(lastPos, i); - lastPos = i + 1; // Other ASCII characters - - if (c < 0x80) { - out += hexTable[c]; - continue; - } // Multi-byte characters ... - - - if (c < 0x800) { - out += hexTable[0xc0 | c >> 6] + hexTable[0x80 | c & 0x3f]; - continue; - } - - if (c < 0xd800 || c >= 0xe000) { - out += hexTable[0xe0 | c >> 12] + hexTable[0x80 | c >> 6 & 0x3f] + hexTable[0x80 | c & 0x3f]; - continue; - } // Surrogate pair - - - ++i; - var c2; - if (i < str.length) c2 = str.charCodeAt(i) & 0x3ff;else c2 = 0; - c = 0x10000 + ((c & 0x3ff) << 10 | c2); - out += hexTable[0xf0 | c >> 18] + hexTable[0x80 | c >> 12 & 0x3f] + hexTable[0x80 | c >> 6 & 0x3f] + hexTable[0x80 | c & 0x3f]; - } - - if (lastPos === 0) return str; - if (lastPos < str.length) return out + str.slice(lastPos); - return out; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92ZW5kb3IvbW9uZ29kYlVybC5qcyJdLCJuYW1lcyI6WyJwdW55Y29kZSIsInJlcXVpcmUiLCJleHBvcnRzIiwicGFyc2UiLCJ1cmxQYXJzZSIsInJlc29sdmUiLCJ1cmxSZXNvbHZlIiwicmVzb2x2ZU9iamVjdCIsInVybFJlc29sdmVPYmplY3QiLCJmb3JtYXQiLCJ1cmxGb3JtYXQiLCJVcmwiLCJwcm90b2NvbCIsInNsYXNoZXMiLCJhdXRoIiwiaG9zdCIsInBvcnQiLCJob3N0bmFtZSIsImhhc2giLCJzZWFyY2giLCJxdWVyeSIsInBhdGhuYW1lIiwicGF0aCIsImhyZWYiLCJwcm90b2NvbFBhdHRlcm4iLCJwb3J0UGF0dGVybiIsInNpbXBsZVBhdGhQYXR0ZXJuIiwidW5zYWZlUHJvdG9jb2wiLCJqYXZhc2NyaXB0IiwiaG9zdGxlc3NQcm90b2NvbCIsInNsYXNoZWRQcm90b2NvbCIsImh0dHAiLCJodHRwcyIsImZ0cCIsImdvcGhlciIsImZpbGUiLCJxdWVyeXN0cmluZyIsInVybCIsInBhcnNlUXVlcnlTdHJpbmciLCJzbGFzaGVzRGVub3RlSG9zdCIsInUiLCJwcm90b3R5cGUiLCJUeXBlRXJyb3IiLCJoYXNIYXNoIiwic3RhcnQiLCJlbmQiLCJyZXN0IiwibGFzdFBvcyIsImkiLCJpbldzIiwic3BsaXQiLCJsZW5ndGgiLCJjb2RlIiwiY2hhckNvZGVBdCIsImlzV3MiLCJzbGljZSIsInNpbXBsZVBhdGgiLCJleGVjIiwicHJvdG8iLCJsb3dlclByb3RvIiwidG9Mb3dlckNhc2UiLCJ0ZXN0IiwiaG9zdEVuZCIsImF0U2lnbiIsIm5vbkhvc3QiLCJkZWNvZGVVUklDb21wb25lbnQiLCJwYXJzZUhvc3QiLCJpcHY2SG9zdG5hbWUiLCJyZXN1bHQiLCJ2YWxpZGF0ZUhvc3RuYW1lIiwidW5kZWZpbmVkIiwidG9BU0NJSSIsInAiLCJoIiwiYXV0b0VzY2FwZVN0ciIsInF1ZXN0aW9uSWR4IiwiaGFzaElkeCIsImZpcnN0SWR4IiwicyIsInNlbGYiLCJuZXdSZXN0Iiwib2JqIiwiY2FsbCIsImVuY29kZUF1dGgiLCJpbmRleE9mIiwic3RyaW5naWZ5IiwibmV3UGF0aG5hbWUiLCJyZXBsYWNlIiwic291cmNlIiwicmVsYXRpdmUiLCJyZWwiLCJ0a2V5cyIsIk9iamVjdCIsImtleXMiLCJ0ayIsInRrZXkiLCJya2V5cyIsInJrIiwicmtleSIsInYiLCJrIiwicmVsUGF0aCIsInNoaWZ0IiwidW5zaGlmdCIsImpvaW4iLCJpc1NvdXJjZUFicyIsImNoYXJBdCIsImlzUmVsQWJzIiwibXVzdEVuZEFicyIsInJlbW92ZUFsbERvdHMiLCJzcmNQYXRoIiwicHN5Y2hvdGljIiwicG9wIiwiY29uY2F0IiwiYXV0aEluSG9zdCIsImxhc3QiLCJoYXNUcmFpbGluZ1NsYXNoIiwidXAiLCJzcGxpY2VPbmUiLCJzdWJzdHIiLCJwdXNoIiwiaXNBYnNvbHV0ZSIsImxpc3QiLCJpbmRleCIsIm4iLCJoZXhUYWJsZSIsIkFycmF5IiwidG9TdHJpbmciLCJ0b1VwcGVyQ2FzZSIsInN0ciIsIm91dCIsImMiLCJjMiJdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUVBOztBQUVBLE1BQU1BLFFBQVEsR0FBR0MsT0FBTyxDQUFDLFVBQUQsQ0FBeEI7O0FBRUFDLE9BQU8sQ0FBQ0MsS0FBUixHQUFnQkMsUUFBaEI7QUFDQUYsT0FBTyxDQUFDRyxPQUFSLEdBQWtCQyxVQUFsQjtBQUNBSixPQUFPLENBQUNLLGFBQVIsR0FBd0JDLGdCQUF4QjtBQUNBTixPQUFPLENBQUNPLE1BQVIsR0FBaUJDLFNBQWpCO0FBRUFSLE9BQU8sQ0FBQ1MsR0FBUixHQUFjQSxHQUFkOztBQUVBLFNBQVNBLEdBQVQsR0FBZTtBQUNiLE9BQUtDLFFBQUwsR0FBZ0IsSUFBaEI7QUFDQSxPQUFLQyxPQUFMLEdBQWUsSUFBZjtBQUNBLE9BQUtDLElBQUwsR0FBWSxJQUFaO0FBQ0EsT0FBS0MsSUFBTCxHQUFZLElBQVo7QUFDQSxPQUFLQyxJQUFMLEdBQVksSUFB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QUFZLENBQUNBLENBQUMsR0FBRyxLQUFMLEtBQWUsRUFBaEIsR0FBc0JDLEVBQWpDLENBQUo7QUFDQUYsSUFBQUEsR0FBRyxJQUNETCxRQUFRLENBQUMsT0FBUU0sQ0FBQyxJQUFJLEVBQWQsQ0FBUixHQUNBTixRQUFRLENBQUMsT0FBU00sQ0FBQyxJQUFJLEVBQU4sR0FBWSxJQUFyQixDQURSLEdBRUFOLFFBQVEsQ0FBQyxPQUFTTSxDQUFDLElBQUksQ0FBTixHQUFXLElBQXBCLENBRlIsR0FHQU4sUUFBUSxDQUFDLE9BQVFNLENBQUMsR0FBRyxJQUFiLENBSlY7QUFLRDs7QUFDRCxNQUFJcEYsT0FBTyxLQUFLLENBQWhCLEVBQW1CLE9BQU9rRixHQUFQO0FBQ25CLE1BQUlsRixPQUFPLEdBQUdrRixHQUFHLENBQUM5RSxNQUFsQixFQUEwQixPQUFPK0UsR0FBRyxHQUFHRCxHQUFHLENBQUMxRSxLQUFKLENBQVVSLE9BQVYsQ0FBYjtBQUMxQixTQUFPbUYsR0FBUDtBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQSBzbGlnaHRseSBwYXRjaGVkIHZlcnNpb24gb2Ygbm9kZSdzIHVybCBtb2R1bGUsIHdpdGggc3VwcG9ydCBmb3IgbW9uZ29kYjovL1xuLy8gdXJpcy5cbi8vXG4vLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL25vZGVqcy9ub2RlL2Jsb2IvbWFzdGVyL0xJQ0VOU0UgZm9yIGxpY2Vuc2luZ1xuLy8gaW5mb3JtYXRpb25cblxuJ3VzZSBzdHJpY3QnO1xuXG5jb25zdCBwdW55Y29kZSA9IHJlcXVpcmUoJ3B1bnljb2RlJyk7XG5cbmV4cG9ydHMucGFyc2UgPSB1cmxQYXJzZTtcbmV4cG9ydHMucmVzb2x2ZSA9IHVybFJlc29sdmU7XG5leHBvcnRzLnJlc29sdmVPYmplY3QgPSB1cmxSZXNvbHZlT2JqZWN0O1xuZXhwb3J0cy5mb3JtYXQgPSB1cmxGb3JtYXQ7XG5cbmV4cG9ydHMuVXJsID0gVXJsO1xuXG5mdW5jdGlvbiBVcmwoKSB7XG4gIHRoaXMucHJvdG9jb2wgPSBudWxsO1xuICB0aGlzLnNsYXNoZXMgPSBudWxsO1xuICB0aGlzLmF1dGggPSBudWxsO1xuICB0aGlzLmhvc3QgPSBudWxsO1xuICB0aGlzLnBvcnQgPSBudWxsO1xuICB0aGlzLmhvc3RuYW1lID0gbnVsbDtcbiAgdGhpcy5oYXNoID0gbnVsbDtcbiAgdGhpcy5zZWFyY2ggPSBudWxsO1xuICB0aGlzLnF1ZXJ5ID0gbnVsbDtcbiAgdGhpcy5wYXRobmFtZSA9IG51bGw7XG4gIHRoaXMucGF0aCA9IG51bGw7XG4gIHRoaXMuaHJlZiA9IG51bGw7XG59XG5cbi8vIFJlZmVyZW5jZTogUkZDIDM5ODYsIFJGQyAxODA4LCBSRkMgMjM5NlxuXG4vLyBkZWZpbmUgdGhlc2UgaGVyZSBzbyBhdCBsZWFzdCB0aGV5IG9ubHkgaGF2ZSB0byBiZVxuLy8gY29tcGlsZWQgb25jZSBvbiB0aGUgZmlyc3QgbW9kdWxlIGxvYWQuXG5jb25zdCBwcm90b2NvbFBhdHRlcm4gPSAvXihbYS16MC05ListXSs6KS9pO1xuY29uc3QgcG9ydFBhdHRlcm4gPSAvOlswLTldKiQvO1xuXG4vLyBTcGVjaWFsIGNhc2UgZm9yIGEgc2ltcGxlIHBhdGggVVJMXG5jb25zdCBzaW1wbGVQYXRoUGF0dGVybiA9IC9eKFxcL1xcLz8oPyFcXC8pW15cXD9cXHNdKikoXFw/W15cXHNdKik/JC87XG5cbi8vIHByb3RvY29scyB0aGF0IGNhbiBhbGxvdyBcInVuc2FmZVwiIGFuZCBcInVud2lzZVwiIGNoYXJzLlxuY29uc3QgdW5zYWZlUHJvdG9jb2wgPSB7XG4gIGphdmFzY3JpcHQ6IHRydWUsXG4gICdqYXZhc2NyaXB0Oic6IHRydWUsXG59O1xuLy8gcHJvdG9jb2xzIHRoYXQgbmV2ZXIgaGF2ZSBhIGhvc3RuYW1lLlxuY29uc3QgaG9zdGxlc3NQcm90b2NvbCA9IHtcbiAgamF2YXNjcmlwdDogdHJ1ZSxcbiAgJ2phdmFzY3JpcHQ6JzogdHJ1ZSxcbn07XG4vLyBwcm90b2NvbHMgdGhhdCBhbHdheXMgY29udGFpbiBhIC8vIGJpdC5cbmNvbnN0IHNsYXNoZWRQcm90b2NvbCA9IHtcbiAgaHR0cDogdHJ1ZSxcbiAgJ2h0dHA6JzogdHJ1ZSxcbiAgaHR0cHM6IHRydWUsXG4gICdodHRwczonOiB0cnVlLFxuICBmdHA6IHRydWUsXG4gICdmdHA6JzogdHJ1ZSxcbiAgZ29waGVyOiB0cnVlLFxuICAnZ29waGVyOic6IHRydWUsXG4gIGZpbGU6IHRydWUsXG4gICdmaWxlOic6IHRydWUsXG59O1xuY29uc3QgcXVlcnlzdHJpbmcgPSByZXF1aXJlKCdxdWVyeXN0cmluZycpO1xuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogaW1wcm92ZSBjb3ZlcmFnZSAqL1xuZnVuY3Rpb24gdXJsUGFyc2UodXJsLCBwYXJzZVF1ZXJ5U3RyaW5nLCBzbGFzaGVzRGVub3RlSG9zdCkge1xuICBpZiAodXJsIGluc3RhbmNlb2YgVXJsKSByZXR1cm4gdXJsO1xuXG4gIHZhciB1ID0gbmV3IFVybCgpO1xuICB1LnBhcnNlKHVybCwgcGFyc2VRdWVyeVN0cmluZywgc2xhc2hlc0Rlbm90ZUhvc3QpO1xuICByZXR1cm4gdTtcbn1cblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cblVybC5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbiAodXJsLCBwYXJzZVF1ZXJ5U3RyaW5nLCBzbGFzaGVzRGVub3RlSG9zdCkge1xuICBpZiAodHlwZW9mIHVybCAhPT0gJ3N0cmluZycpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdQYXJhbWV0ZXIgXCJ1cmxcIiBtdXN0IGJlIGEgc3RyaW5nLCBub3QgJyArIHR5cGVvZiB1cmwpO1xuICB9XG5cbiAgLy8gQ29weSBjaHJvbWUsIElFLCBvcGVyYSBiYWNrc2xhc2gtaGFuZGxpbmcgYmVoYXZpb3IuXG4gIC8vIEJhY2sgc2xhc2hlcyBiZWZvcmUgdGhlIHF1ZXJ5IHN0cmluZyBnZXQgY29udmVydGVkIHRvIGZvcndhcmQgc2xhc2hlc1xuICAvLyBTZWU6IGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD0yNTkxNlxuICB2YXIgaGFzSGFzaCA9IGZhbHNlO1xuICB2YXIgc3RhcnQgPSAtMTtcbiAgdmFyIGVuZCA9IC0xO1xuICB2YXIgcmVzdCA9ICcnO1xuICB2YXIgbGFzdFBvcyA9IDA7XG4gIHZhciBpID0gMDtcbiAgZm9yICh2YXIgaW5XcyA9IGZhbHNlLCBzcGxpdCA9IGZhbHNlOyBpIDwgdXJsLmxlbmd0aDsgKytpKSB7XG4gICAgY29uc3QgY29kZSA9IHVybC5jaGFyQ29kZUF0KGkpO1xuXG4gICAgLy8gRmluZCBmaXJzdCBhbmQgbGFzdCBub24td2hpdGVzcGFjZSBjaGFyYWN0ZXJzIGZvciB0cmltbWluZ1xuICAgIGNvbnN0IGlzV3MgPVxuICAgICAgY29kZSA9PT0gMzIgLyogKi8gfHxcbiAgICAgIGNvZGUgPT09IDkgLypcXHQqLyB8fFxuICAgICAgY29kZSA9PT0gMTMgLypcXHIqLyB8fFxuICAgICAgY29kZSA9PT0gMTAgLypcXG4qLyB8fFxuICAgICAgY29kZSA9PT0gMTIgLypcXGYqLyB8fFxuICAgICAgY29kZSA9PT0gMTYwIC8qXFx1MDBBMCovIHx8XG4gICAgICBjb2RlID09PSA2NTI3OTsgLypcXHVGRUZGKi9cbiAgICBpZiAoc3RhcnQgPT09IC0xKSB7XG4gICAgICBpZiAoaXNXcykgY29udGludWU7XG4gICAgICBsYXN0UG9zID0gc3RhcnQgPSBpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoaW5Xcykge1xuICAgICAgICBpZiAoIWlzV3MpIHtcbiAgICAgICAgICBlbmQgPSAtMTtcbiAgICAgICAgICBpbldzID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoaXNXcykge1xuICAgICAgICBlbmQgPSBpO1xuICAgICAgICBpbldzID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBPbmx5IGNvbnZlcnQgYmFja3NsYXNoZXMgd2hpbGUgd2UgaGF2ZW4ndCBzZWVuIGEgc3BsaXQgY2hhcmFjdGVyXG4gICAgaWYgKCFzcGxpdCkge1xuICAgICAgc3dpdGNoIChjb2RlKSB7XG4gICAgICAgIGNhc2UgMzU6IC8vICcjJ1xuICAgICAgICAgIGhhc0hhc2ggPSB0cnVlO1xuICAgICAgICAvLyBGYWxsIHRocm91Z2hcbiAgICAgICAgY2FzZSA2MzogLy8gJz8nXG4gICAgICAgICAgc3BsaXQgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDkyOiAvLyAnXFxcXCdcbiAgICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSByZXN0ICs9IHVybC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgICByZXN0ICs9ICcvJztcbiAgICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICghaGFzSGFzaCAmJiBjb2RlID09PSAzNSAvKiMqLykge1xuICAgICAgaGFzSGFzaCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgLy8gQ2hlY2sgaWYgc3RyaW5nIHdhcyBub24tZW1wdHkgKGluY2x1ZGluZyBzdHJpbmdzIHdpdGggb25seSB3aGl0ZXNwYWNlKVxuICBpZiAoc3RhcnQgIT09IC0xKSB7XG4gICAgaWYgKGxhc3RQb3MgPT09IHN0YXJ0KSB7XG4gICAgICAvLyBXZSBkaWRuJ3QgY29udmVydCBhbnkgYmFja3NsYXNoZXNcblxuICAgICAgaWYgKGVuZCA9PT0gLTEpIHtcbiAgICAgICAgaWYgKHN0YXJ0ID09PSAwKSByZXN0ID0gdXJsO1xuICAgICAgICBlbHNlIHJlc3QgPSB1cmwuc2xpY2Uoc3RhcnQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdCA9IHVybC5zbGljZShzdGFydCwgZW5kKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGVuZCA9PT0gLTEgJiYgbGFzdFBvcyA8IHVybC5sZW5ndGgpIHtcbiAgICAgIC8vIFdlIGNvbnZlcnRlZCBzb21lIGJhY2tzbGFzaGVzIGFuZCBoYXZlIG9ubHkgcGFydCBvZiB0aGUgZW50aXJlIHN0cmluZ1xuICAgICAgcmVzdCArPSB1cmwuc2xpY2UobGFzdFBvcyk7XG4gICAgfSBlbHNlIGlmIChlbmQgIT09IC0xICYmIGxhc3RQb3MgPCBlbmQpIHtcbiAgICAgIC8vIFdlIGNvbnZlcnRlZCBzb21lIGJhY2tzbGFzaGVzIGFuZCBoYXZlIG9ubHkgcGFydCBvZiB0aGUgZW50aXJlIHN0cmluZ1xuICAgICAgcmVzdCArPSB1cmwuc2xpY2UobGFzdFBvcywgZW5kKTtcbiAgICB9XG4gIH1cblxuICBpZiAoIXNsYXNoZXNEZW5vdGVIb3N0ICYmICFoYXNIYXNoKSB7XG4gICAgLy8gVHJ5IGZhc3QgcGF0aCByZWdleHBcbiAgICBjb25zdCBzaW1wbGVQYXRoID0gc2ltcGxlUGF0aFBhdHRlcm4uZXhlYyhyZXN0KTtcbiAgICBpZiAoc2ltcGxlUGF0aCkge1xuICAgICAgdGhpcy5wYXRoID0gcmVzdDtcbiAgICAgIHRoaXMuaHJlZiA9IHJlc3Q7XG4gICAgICB0aGlzLnBhdGhuYW1lID0gc2ltcGxlUGF0aFsxXTtcbiAgICAgIGlmIChzaW1wbGVQYXRoWzJdKSB7XG4gICAgICAgIHRoaXMuc2VhcmNoID0gc2ltcGxlUGF0aFsyXTtcbiAgICAgICAgaWYgKHBhcnNlUXVlcnlTdHJpbmcpIHtcbiAgICAgICAgICB0aGlzLnF1ZXJ5ID0gcXVlcnlzdHJpbmcucGFyc2UodGhpcy5zZWFyY2guc2xpY2UoMSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMucXVlcnkgPSB0aGlzLnNlYXJjaC5zbGljZSgxKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChwYXJzZVF1ZXJ5U3RyaW5nKSB7XG4gICAgICAgIHRoaXMuc2VhcmNoID0gJyc7XG4gICAgICAgIHRoaXMucXVlcnkgPSB7fTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgfVxuXG4gIHZhciBwcm90byA9IHByb3RvY29sUGF0dGVybi5leGVjKHJlc3QpO1xuICBpZiAocHJvdG8pIHtcbiAgICBwcm90byA9IHByb3RvWzBdO1xuICAgIHZhciBsb3dlclByb3RvID0gcHJvdG8udG9Mb3dlckNhc2UoKTtcbiAgICB0aGlzLnByb3RvY29sID0gbG93ZXJQcm90bztcbiAgICByZXN0ID0gcmVzdC5zbGljZShwcm90by5sZW5ndGgpO1xuICB9XG5cbiAgLy8gZmlndXJlIG91dCBpZiBpdCdzIGdvdCBhIGhvc3RcbiAgLy8gdXNlckBzZXJ2ZXIgaXMgKmFsd2F5cyogaW50ZXJwcmV0ZWQgYXMgYSBob3N0bmFtZSwgYW5kIHVybFxuICAvLyByZXNvbHV0aW9uIHdpbGwgdHJlYXQgLy9mb28vYmFyIGFzIGhvc3Q9Zm9vLHBhdGg9YmFyIGJlY2F1c2UgdGhhdCdzXG4gIC8vIGhvdyB0aGUgYnJvd3NlciByZXNvbHZlcyByZWxhdGl2ZSBVUkxzLlxuICBpZiAoc2xhc2hlc0Rlbm90ZUhvc3QgfHwgcHJvdG8gfHwgL15cXC9cXC9bXkBcXC9dK0BbXkBcXC9dKy8udGVzdChyZXN0KSkge1xuICAgIHZhciBzbGFzaGVzID0gcmVzdC5jaGFyQ29kZUF0KDApID09PSA0NyAvKi8qLyAmJiByZXN0LmNoYXJDb2RlQXQoMSkgPT09IDQ3OyAvKi8qL1xuICAgIGlmIChzbGFzaGVzICYmICEocHJvdG8gJiYgaG9zdGxlc3NQcm90b2NvbFtwcm90b10pKSB7XG4gICAgICByZXN0ID0gcmVzdC5zbGljZSgyKTtcbiAgICAgIHRoaXMuc2xhc2hlcyA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgaWYgKCFob3N0bGVzc1Byb3RvY29sW3Byb3RvXSAmJiAoc2xhc2hlcyB8fCAocHJvdG8gJiYgIXNsYXNoZWRQcm90b2NvbFtwcm90b10pKSkge1xuICAgIC8vIHRoZXJlJ3MgYSBob3N0bmFtZS5cbiAgICAvLyB0aGUgZmlyc3QgaW5zdGFuY2Ugb2YgLywgPywgOywgb3IgIyBlbmRzIHRoZSBob3N0LlxuICAgIC8vXG4gICAgLy8gSWYgdGhlcmUgaXMgYW4gQCBpbiB0aGUgaG9zdG5hbWUsIHRoZW4gbm9uLWhvc3QgY2hhcnMgKmFyZSogYWxsb3dlZFxuICAgIC8vIHRvIHRoZSBsZWZ0IG9mIHRoZSBsYXN0IEAgc2lnbiwgdW5sZXNzIHNvbWUgaG9zdC1lbmRpbmcgY2hhcmFjdGVyXG4gICAgLy8gY29tZXMgKmJlZm9yZSogdGhlIEAtc2lnbi5cbiAgICAvLyBVUkxzIGFyZSBvYm5veGlvdXMuXG4gICAgLy9cbiAgICAvLyBleDpcbiAgICAvLyBodHRwOi8vYUBiQGMvID0+IHVzZXI6YUBiIGhvc3Q6Y1xuICAgIC8vIGh0dHA6Ly9hQGI/QGMgPT4gdXNlcjphIGhvc3Q6YiBwYXRoOi8/QGNcblxuICAgIC8vIHYwLjEyIFRPRE8oaXNhYWNzKTogVGhpcyBpcyBub3QgcXVpdGUgaG93IENocm9tZSBkb2VzIHRoaW5ncy5cbiAgICAvLyBSZXZpZXcgb3VyIHRlc3QgY2FzZSBhZ2FpbnN0IGJyb3dzZXJzIG1vcmUgY29tcHJlaGVuc2l2ZWx5LlxuXG4gICAgdmFyIGhvc3RFbmQgPSAtMTtcbiAgICB2YXIgYXRTaWduID0gLTE7XG4gICAgdmFyIG5vbkhvc3QgPSAtMTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgcmVzdC5sZW5ndGg7ICsraSkge1xuICAgICAgc3dpdGNoIChyZXN0LmNoYXJDb2RlQXQoaSkpIHtcbiAgICAgICAgY2FzZSA5OiAvLyAnXFx0J1xuICAgICAgICBjYXNlIDEwOiAvLyAnXFxuJ1xuICAgICAgICBjYXNlIDEzOiAvLyAnXFxyJ1xuICAgICAgICBjYXNlIDMyOiAvLyAnICdcbiAgICAgICAgY2FzZSAzNDogLy8gJ1wiJ1xuICAgICAgICBjYXNlIDM3OiAvLyAnJSdcbiAgICAgICAgY2FzZSAzOTogLy8gJ1xcJydcbiAgICAgICAgY2FzZSA1OTogLy8gJzsnXG4gICAgICAgIGNhc2UgNjA6IC8vICc8J1xuICAgICAgICBjYXNlIDYyOiAvLyAnPidcbiAgICAgICAgY2FzZSA5MjogLy8gJ1xcXFwnXG4gICAgICAgIGNhc2UgOTQ6IC8vICdeJ1xuICAgICAgICBjYXNlIDk2OiAvLyAnYCdcbiAgICAgICAgY2FzZSAxMjM6IC8vICd7J1xuICAgICAgICBjYXNlIDEyNDogLy8gJ3wnXG4gICAgICAgIGNhc2UgMTI1OiAvLyAnfSdcbiAgICAgICAgICAvLyBDaGFyYWN0ZXJzIHRoYXQgYXJlIG5ldmVyIGV2ZXIgYWxsb3dlZCBpbiBhIGhvc3RuYW1lIGZyb20gUkZDIDIzOTZcbiAgICAgICAgICBpZiAobm9uSG9zdCA9PT0gLTEpIG5vbkhvc3QgPSBpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIDM1OiAvLyAnIydcbiAgICAgICAgY2FzZSA0NzogLy8gJy8nXG4gICAgICAgIGNhc2UgNjM6IC8vICc/J1xuICAgICAgICAgIC8vIEZpbmQgdGhlIGZpcnN0IGluc3RhbmNlIG9mIGFueSBob3N0LWVuZGluZyBjaGFyYWN0ZXJzXG4gICAgICAgICAgaWYgKG5vbkhvc3QgPT09IC0xKSBub25Ib3N0ID0gaTtcbiAgICAgICAgICBob3N0RW5kID0gaTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSA2NDogLy8gJ0AnXG4gICAgICAgICAgLy8gQXQgdGhpcyBwb2ludCwgZWl0aGVyIHdlIGhhdmUgYW4gZXhwbGljaXQgcG9pbnQgd2hlcmUgdGhlXG4gICAgICAgICAgLy8gYXV0aCBwb3J0aW9uIGNhbm5vdCBnbyBwYXN0LCBvciB0aGUgbGFzdCBAIGNoYXIgaXMgdGhlIGRlY2lkZXIuXG4gICAgICAgICAgYXRTaWduID0gaTtcbiAgICAgICAgICBub25Ib3N0ID0gLTE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAoaG9zdEVuZCAhPT0gLTEpIGJyZWFrO1xuICAgIH1cbiAgICBzdGFydCA9IDA7XG4gICAgaWYgKGF0U2lnbiAhPT0gLTEpIHtcbiAgICAgIHRoaXMuYXV0aCA9IGRlY29kZVVSSUNvbXBvbmVudChyZXN0LnNsaWNlKDAsIGF0U2lnbikpO1xuICAgICAgc3RhcnQgPSBhdFNpZ24gKyAxO1xuICAgIH1cbiAgICBpZiAobm9uSG9zdCA9PT0gLTEpIHtcbiAgICAgIHRoaXMuaG9zdCA9IHJlc3Quc2xpY2Uoc3RhcnQpO1xuICAgICAgcmVzdCA9ICcnO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmhvc3QgPSByZXN0LnNsaWNlKHN0YXJ0LCBub25Ib3N0KTtcbiAgICAgIHJlc3QgPSByZXN0LnNsaWNlKG5vbkhvc3QpO1xuICAgIH1cblxuICAgIC8vIHB1bGwgb3V0IHBvcnQuXG4gICAgdGhpcy5wYXJzZUhvc3QoKTtcblxuICAgIC8vIHdlJ3ZlIGluZGljYXRlZCB0aGF0IHRoZXJlIGlzIGEgaG9zdG5hbWUsXG4gICAgLy8gc28gZXZlbiBpZiBpdCdzIGVtcHR5LCBpdCBoYXMgdG8gYmUgcHJlc2VudC5cbiAgICBpZiAodHlwZW9mIHRoaXMuaG9zdG5hbWUgIT09ICdzdHJpbmcnKSB0aGlzLmhvc3RuYW1lID0gJyc7XG5cbiAgICB2YXIgaG9zdG5hbWUgPSB0aGlzLmhvc3RuYW1lO1xuXG4gICAgLy8gaWYgaG9zdG5hbWUgYmVnaW5zIHdpdGggWyBhbmQgZW5kcyB3aXRoIF1cbiAgICAvLyBhc3N1bWUgdGhhdCBpdCdzIGFuIElQdjYgYWRkcmVzcy5cbiAgICB2YXIgaXB2Nkhvc3RuYW1lID1cbiAgICAgIGhvc3RuYW1lLmNoYXJDb2RlQXQoMCkgPT09IDkxIC8qWyovICYmIGhvc3RuYW1lLmNoYXJDb2RlQXQoaG9zdG5hbWUubGVuZ3RoIC0gMSkgPT09IDkzOyAvKl0qL1xuXG4gICAgLy8gdmFsaWRhdGUgYSBsaXR0bGUuXG4gICAgaWYgKCFpcHY2SG9zdG5hbWUpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHZhbGlkYXRlSG9zdG5hbWUodGhpcywgcmVzdCwgaG9zdG5hbWUpO1xuICAgICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSByZXN0ID0gcmVzdWx0O1xuICAgIH1cblxuICAgIC8vIGhvc3RuYW1lcyBhcmUgYWx3YXlzIGxvd2VyIGNhc2UuXG4gICAgdGhpcy5ob3N0bmFtZSA9IHRoaXMuaG9zdG5hbWUudG9Mb3dlckNhc2UoKTtcblxuICAgIGlmICghaXB2Nkhvc3RuYW1lKSB7XG4gICAgICAvLyBJRE5BIFN1cHBvcnQ6IFJldHVybnMgYSBwdW55Y29kZWQgcmVwcmVzZW50YXRpb24gb2YgXCJkb21haW5cIi5cbiAgICAgIC8vIEl0IG9ubHkgY29udmVydHMgcGFydHMgb2YgdGhlIGRvbWFpbiBuYW1lIHRoYXRcbiAgICAgIC8vIGhhdmUgbm9uLUFTQ0lJIGNoYXJhY3RlcnMsIGkuZS4gaXQgZG9lc24ndCBtYXR0ZXIgaWZcbiAgICAgIC8vIHlvdSBjYWxsIGl0IHdpdGggYSBkb21haW4gdGhhdCBhbHJlYWR5IGlzIEFTQ0lJLW9ubHkuXG4gICAgICB0aGlzLmhvc3RuYW1lID0gcHVueWNvZGUudG9BU0NJSSh0aGlzLmhvc3RuYW1lKTtcbiAgICB9XG5cbiAgICB2YXIgcCA9IHRoaXMucG9ydCA/ICc6JyArIHRoaXMucG9ydCA6ICcnO1xuICAgIHZhciBoID0gdGhpcy5ob3N0bmFtZSB8fCAnJztcbiAgICB0aGlzLmhvc3QgPSBoICsgcDtcblxuICAgIC8vIHN0cmlwIFsgYW5kIF0gZnJvbSB0aGUgaG9zdG5hbWVcbiAgICAvLyB0aGUgaG9zdCBmaWVsZCBzdGlsbCByZXRhaW5zIHRoZW0sIHRob3VnaFxuICAgIGlmIChpcHY2SG9zdG5hbWUpIHtcbiAgICAgIHRoaXMuaG9zdG5hbWUgPSB0aGlzLmhvc3RuYW1lLnNsaWNlKDEsIC0xKTtcbiAgICAgIGlmIChyZXN0WzBdICE9PSAnLycpIHtcbiAgICAgICAgcmVzdCA9ICcvJyArIHJlc3Q7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gbm93IHJlc3QgaXMgc2V0IHRvIHRoZSBwb3N0LWhvc3Qgc3R1ZmYuXG4gIC8vIGNob3Agb2ZmIGFueSBkZWxpbSBjaGFycy5cbiAgaWYgKCF1bnNhZmVQcm90b2NvbFtsb3dlclByb3RvXSkge1xuICAgIC8vIEZpcnN0LCBtYWtlIDEwMCUgc3VyZSB0aGF0IGFueSBcImF1dG9Fc2NhcGVcIiBjaGFycyBnZXRcbiAgICAvLyBlc2NhcGVkLCBldmVuIGlmIGVuY29kZVVSSUNvbXBvbmVudCBkb2Vzbid0IHRoaW5rIHRoZXlcbiAgICAvLyBuZWVkIHRvIGJlLlxuICAgIGNvbnN0IHJlc3VsdCA9IGF1dG9Fc2NhcGVTdHIocmVzdCk7XG4gICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSByZXN0ID0gcmVzdWx0O1xuICB9XG5cbiAgdmFyIHF1ZXN0aW9uSWR4ID0gLTE7XG4gIHZhciBoYXNoSWR4ID0gLTE7XG4gIGZvciAoaSA9IDA7IGkgPCByZXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgY29uc3QgY29kZSA9IHJlc3QuY2hhckNvZGVBdChpKTtcbiAgICBpZiAoY29kZSA9PT0gMzUgLyojKi8pIHtcbiAgICAgIHRoaXMuaGFzaCA9IHJlc3Quc2xpY2UoaSk7XG4gICAgICBoYXNoSWR4ID0gaTtcbiAgICAgIGJyZWFrO1xuICAgIH0gZWxzZSBpZiAoY29kZSA9PT0gNjMgLyo/Ki8gJiYgcXVlc3Rpb25JZHggPT09IC0xKSB7XG4gICAgICBxdWVzdGlvbklkeCA9IGk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHF1ZXN0aW9uSWR4ICE9PSAtMSkge1xuICAgIGlmIChoYXNoSWR4ID09PSAtMSkge1xuICAgICAgdGhpcy5zZWFyY2ggPSByZXN0LnNsaWNlKHF1ZXN0aW9uSWR4KTtcbiAgICAgIHRoaXMucXVlcnkgPSByZXN0LnNsaWNlKHF1ZXN0aW9uSWR4ICsgMSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2VhcmNoID0gcmVzdC5zbGljZShxdWVzdGlvbklkeCwgaGFzaElkeCk7XG4gICAgICB0aGlzLnF1ZXJ5ID0gcmVzdC5zbGljZShxdWVzdGlvbklkeCArIDEsIGhhc2hJZHgpO1xuICAgIH1cbiAgICBpZiAocGFyc2VRdWVyeVN0cmluZykge1xuICAgICAgdGhpcy5xdWVyeSA9IHF1ZXJ5c3RyaW5nLnBhcnNlKHRoaXMucXVlcnkpO1xuICAgIH1cbiAgfSBlbHNlIGlmIChwYXJzZVF1ZXJ5U3RyaW5nKSB7XG4gICAgLy8gbm8gcXVlcnkgc3RyaW5nLCBidXQgcGFyc2VRdWVyeVN0cmluZyBzdGlsbCByZXF1ZXN0ZWRcbiAgICB0aGlzLnNlYXJjaCA9ICcnO1xuICAgIHRoaXMucXVlcnkgPSB7fTtcbiAgfVxuXG4gIHZhciBmaXJzdElkeCA9XG4gICAgcXVlc3Rpb25JZHggIT09IC0xICYmIChoYXNoSWR4ID09PSAtMSB8fCBxdWVzdGlvbklkeCA8IGhhc2hJZHgpID8gcXVlc3Rpb25JZHggOiBoYXNoSWR4O1xuICBpZiAoZmlyc3RJZHggPT09IC0xKSB7XG4gICAgaWYgKHJlc3QubGVuZ3RoID4gMCkgdGhpcy5wYXRobmFtZSA9IHJlc3Q7XG4gIH0gZWxzZSBpZiAoZmlyc3RJZHggPiAwKSB7XG4gICAgdGhpcy5wYXRobmFtZSA9IHJlc3Quc2xpY2UoMCwgZmlyc3RJZHgpO1xuICB9XG4gIGlmIChzbGFzaGVkUHJvdG9jb2xbbG93ZXJQcm90b10gJiYgdGhpcy5ob3N0bmFtZSAmJiAhdGhpcy5wYXRobmFtZSkge1xuICAgIHRoaXMucGF0aG5hbWUgPSAnLyc7XG4gIH1cblxuICAvLyB0byBzdXBwb3J0IGh0dHAucmVxdWVzdFxuICBpZiAodGhpcy5wYXRobmFtZSB8fCB0aGlzLnNlYXJjaCkge1xuICAgIGNvbnN0IHAgPSB0aGlzLnBhdGhuYW1lIHx8ICcnO1xuICAgIGNvbnN0IHMgPSB0aGlzLnNlYXJjaCB8fCAnJztcbiAgICB0aGlzLnBhdGggPSBwICsgcztcbiAgfVxuXG4gIC8vIGZpbmFsbHksIHJlY29uc3RydWN0IHRoZSBocmVmIGJhc2VkIG9uIHdoYXQgaGFzIGJlZW4gdmFsaWRhdGVkLlxuICB0aGlzLmhyZWYgPSB0aGlzLmZvcm1hdCgpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5mdW5jdGlvbiB2YWxpZGF0ZUhvc3RuYW1lKHNlbGYsIHJlc3QsIGhvc3RuYW1lKSB7XG4gIGZvciAodmFyIGkgPSAwLCBsYXN0UG9zOyBpIDw9IGhvc3RuYW1lLmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIGNvZGU7XG4gICAgaWYgKGkgPCBob3N0bmFtZS5sZW5ndGgpIGNvZGUgPSBob3N0bmFtZS5jaGFyQ29kZUF0KGkpO1xuICAgIGlmIChjb2RlID09PSA0NiAvKi4qLyB8fCBpID09PSBob3N0bmFtZS5sZW5ndGgpIHtcbiAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIHtcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gNjMpIHtcbiAgICAgICAgICBzZWxmLmhvc3RuYW1lID0gaG9zdG5hbWUuc2xpY2UoMCwgbGFzdFBvcyArIDYzKTtcbiAgICAgICAgICByZXR1cm4gJy8nICsgaG9zdG5hbWUuc2xpY2UobGFzdFBvcyArIDYzKSArIHJlc3Q7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICAoY29kZSA+PSA0OCAvKjAqLyAmJiBjb2RlIDw9IDU3KSAvKjkqLyB8fFxuICAgICAgKGNvZGUgPj0gOTcgLyphKi8gJiYgY29kZSA8PSAxMjIpIC8qeiovIHx8XG4gICAgICBjb2RlID09PSA0NSAvKi0qLyB8fFxuICAgICAgKGNvZGUgPj0gNjUgLypBKi8gJiYgY29kZSA8PSA5MCkgLypaKi8gfHxcbiAgICAgIGNvZGUgPT09IDQzIC8qKyovIHx8XG4gICAgICBjb2RlID09PSA5NSAvKl8qLyB8fFxuICAgICAgLyogQkVHSU4gTU9OR08gVVJJIFBBVENIICovXG4gICAgICBjb2RlID09PSA0NCAvKiwqLyB8fFxuICAgICAgY29kZSA9PT0gNTggLyo6Ki8gfHxcbiAgICAgIC8qIEVORCBNT05HTyBVUkkgUEFUQ0ggKi9cbiAgICAgIGNvZGUgPiAxMjdcbiAgICApIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICAvLyBJbnZhbGlkIGhvc3QgY2hhcmFjdGVyXG4gICAgc2VsZi5ob3N0bmFtZSA9IGhvc3RuYW1lLnNsaWNlKDAsIGkpO1xuICAgIGlmIChpIDwgaG9zdG5hbWUubGVuZ3RoKSByZXR1cm4gJy8nICsgaG9zdG5hbWUuc2xpY2UoaSkgKyByZXN0O1xuICAgIGJyZWFrO1xuICB9XG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5mdW5jdGlvbiBhdXRvRXNjYXBlU3RyKHJlc3QpIHtcbiAgdmFyIG5ld1Jlc3QgPSAnJztcbiAgdmFyIGxhc3RQb3MgPSAwO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHJlc3QubGVuZ3RoOyArK2kpIHtcbiAgICAvLyBBdXRvbWF0aWNhbGx5IGVzY2FwZSBhbGwgZGVsaW1pdGVycyBhbmQgdW53aXNlIGNoYXJhY3RlcnMgZnJvbSBSRkMgMjM5NlxuICAgIC8vIEFsc28gZXNjYXBlIHNpbmdsZSBxdW90ZXMgaW4gY2FzZSBvZiBhbiBYU1MgYXR0YWNrXG4gICAgc3dpdGNoIChyZXN0LmNoYXJDb2RlQXQoaSkpIHtcbiAgICAgIGNhc2UgOTogLy8gJ1xcdCdcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMDknO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxMDogLy8gJ1xcbidcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMEEnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxMzogLy8gJ1xccidcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMEQnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzMjogLy8gJyAnXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1Jlc3QgKz0gcmVzdC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UmVzdCArPSAnJTIwJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzQ6IC8vICdcIidcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMjInO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAzOTogLy8gJ1xcJydcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclMjcnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA2MDogLy8gJzwnXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1Jlc3QgKz0gcmVzdC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UmVzdCArPSAnJTNDJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNjI6IC8vICc+J1xuICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBuZXdSZXN0ICs9IHJlc3Quc2xpY2UobGFzdFBvcywgaSk7XG4gICAgICAgIG5ld1Jlc3QgKz0gJyUzRSc7XG4gICAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDkyOiAvLyAnXFxcXCdcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclNUMnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSA5NDogLy8gJ14nXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1Jlc3QgKz0gcmVzdC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UmVzdCArPSAnJTVFJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgOTY6IC8vICdgJ1xuICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBuZXdSZXN0ICs9IHJlc3Quc2xpY2UobGFzdFBvcywgaSk7XG4gICAgICAgIG5ld1Jlc3QgKz0gJyU2MCc7XG4gICAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDEyMzogLy8gJ3snXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1Jlc3QgKz0gcmVzdC5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UmVzdCArPSAnJTdCJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMTI0OiAvLyAnfCdcbiAgICAgICAgaWYgKGkgLSBsYXN0UG9zID4gMCkgbmV3UmVzdCArPSByZXN0LnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdSZXN0ICs9ICclN0MnO1xuICAgICAgICBsYXN0UG9zID0gaSArIDE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAxMjU6IC8vICd9J1xuICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBuZXdSZXN0ICs9IHJlc3Quc2xpY2UobGFzdFBvcywgaSk7XG4gICAgICAgIG5ld1Jlc3QgKz0gJyU3RCc7XG4gICAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmIChsYXN0UG9zID09PSAwKSByZXR1cm47XG4gIGlmIChsYXN0UG9zIDwgcmVzdC5sZW5ndGgpIHJldHVybiBuZXdSZXN0ICsgcmVzdC5zbGljZShsYXN0UG9zKTtcbiAgZWxzZSByZXR1cm4gbmV3UmVzdDtcbn1cblxuLy8gZm9ybWF0IGEgcGFyc2VkIG9iamVjdCBpbnRvIGEgdXJsIHN0cmluZ1xuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cbmZ1bmN0aW9uIHVybEZvcm1hdChvYmopIHtcbiAgLy8gZW5zdXJlIGl0J3MgYW4gb2JqZWN0LCBhbmQgbm90IGEgc3RyaW5nIHVybC5cbiAgLy8gSWYgaXQncyBhbiBvYmosIHRoaXMgaXMgYSBuby1vcC5cbiAgLy8gdGhpcyB3YXksIHlvdSBjYW4gY2FsbCB1cmxfZm9ybWF0KCkgb24gc3RyaW5nc1xuICAvLyB0byBjbGVhbiB1cCBwb3RlbnRpYWxseSB3b25reSB1cmxzLlxuICBpZiAodHlwZW9mIG9iaiA9PT0gJ3N0cmluZycpIG9iaiA9IHVybFBhcnNlKG9iaik7XG4gIGVsc2UgaWYgKHR5cGVvZiBvYmogIT09ICdvYmplY3QnIHx8IG9iaiA9PT0gbnVsbClcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgJ1BhcmFtZXRlciBcInVybE9ialwiIG11c3QgYmUgYW4gb2JqZWN0LCBub3QgJyArIG9iaiA9PT0gbnVsbCA/ICdudWxsJyA6IHR5cGVvZiBvYmpcbiAgICApO1xuICBlbHNlIGlmICghKG9iaiBpbnN0YW5jZW9mIFVybCkpIHJldHVybiBVcmwucHJvdG90eXBlLmZvcm1hdC5jYWxsKG9iaik7XG5cbiAgcmV0dXJuIG9iai5mb3JtYXQoKTtcbn1cblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cblVybC5wcm90b3R5cGUuZm9ybWF0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgYXV0aCA9IHRoaXMuYXV0aCB8fCAnJztcbiAgaWYgKGF1dGgpIHtcbiAgICBhdXRoID0gZW5jb2RlQXV0aChhdXRoKTtcbiAgICBhdXRoICs9ICdAJztcbiAgfVxuXG4gIHZhciBwcm90b2NvbCA9IHRoaXMucHJvdG9jb2wgfHwgJyc7XG4gIHZhciBwYXRobmFtZSA9IHRoaXMucGF0aG5hbWUgfHwgJyc7XG4gIHZhciBoYXNoID0gdGhpcy5oYXNoIHx8ICcnO1xuICB2YXIgaG9zdCA9IGZhbHNlO1xuICB2YXIgcXVlcnkgPSAnJztcblxuICBpZiAodGhpcy5ob3N0KSB7XG4gICAgaG9zdCA9IGF1dGggKyB0aGlzLmhvc3Q7XG4gIH0gZWxzZSBpZiAodGhpcy5ob3N0bmFtZSkge1xuICAgIGhvc3QgPSBhdXRoICsgKHRoaXMuaG9zdG5hbWUuaW5kZXhPZignOicpID09PSAtMSA/IHRoaXMuaG9zdG5hbWUgOiAnWycgKyB0aGlzLmhvc3RuYW1lICsgJ10nKTtcbiAgICBpZiAodGhpcy5wb3J0KSB7XG4gICAgICBob3N0ICs9ICc6JyArIHRoaXMucG9ydDtcbiAgICB9XG4gIH1cblxuICBpZiAodGhpcy5xdWVyeSAhPT0gbnVsbCAmJiB0eXBlb2YgdGhpcy5xdWVyeSA9PT0gJ29iamVjdCcpXG4gICAgcXVlcnkgPSBxdWVyeXN0cmluZy5zdHJpbmdpZnkodGhpcy5xdWVyeSk7XG5cbiAgdmFyIHNlYXJjaCA9IHRoaXMuc2VhcmNoIHx8IChxdWVyeSAmJiAnPycgKyBxdWVyeSkgfHwgJyc7XG5cbiAgaWYgKHByb3RvY29sICYmIHByb3RvY29sLmNoYXJDb2RlQXQocHJvdG9jb2wubGVuZ3RoIC0gMSkgIT09IDU4IC8qOiovKSBwcm90b2NvbCArPSAnOic7XG5cbiAgdmFyIG5ld1BhdGhuYW1lID0gJyc7XG4gIHZhciBsYXN0UG9zID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYXRobmFtZS5sZW5ndGg7ICsraSkge1xuICAgIHN3aXRjaCAocGF0aG5hbWUuY2hhckNvZGVBdChpKSkge1xuICAgICAgY2FzZSAzNTogLy8gJyMnXG4gICAgICAgIGlmIChpIC0gbGFzdFBvcyA+IDApIG5ld1BhdGhuYW1lICs9IHBhdGhuYW1lLnNsaWNlKGxhc3RQb3MsIGkpO1xuICAgICAgICBuZXdQYXRobmFtZSArPSAnJTIzJztcbiAgICAgICAgbGFzdFBvcyA9IGkgKyAxO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgNjM6IC8vICc/J1xuICAgICAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBuZXdQYXRobmFtZSArPSBwYXRobmFtZS5zbGljZShsYXN0UG9zLCBpKTtcbiAgICAgICAgbmV3UGF0aG5hbWUgKz0gJyUzRic7XG4gICAgICAgIGxhc3RQb3MgPSBpICsgMTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmIChsYXN0UG9zID4gMCkge1xuICAgIGlmIChsYXN0UG9zICE9PSBwYXRobmFtZS5sZW5ndGgpIHBhdGhuYW1lID0gbmV3UGF0aG5hbWUgKyBwYXRobmFtZS5zbGljZShsYXN0UG9zKTtcbiAgICBlbHNlIHBhdGhuYW1lID0gbmV3UGF0aG5hbWU7XG4gIH1cblxuICAvLyBvbmx5IHRoZSBzbGFzaGVkUHJvdG9jb2xzIGdldCB0aGUgLy8uICBOb3QgbWFpbHRvOiwgeG1wcDosIGV0Yy5cbiAgLy8gdW5sZXNzIHRoZXkgaGFkIHRoZW0gdG8gYmVnaW4gd2l0aC5cbiAgaWYgKHRoaXMuc2xhc2hlcyB8fCAoKCFwcm90b2NvbCB8fCBzbGFzaGVkUHJvdG9jb2xbcHJvdG9jb2xdKSAmJiBob3N0ICE9PSBmYWxzZSkpIHtcbiAgICBob3N0ID0gJy8vJyArIChob3N0IHx8ICcnKTtcbiAgICBpZiAocGF0aG5hbWUgJiYgcGF0aG5hbWUuY2hhckNvZGVBdCgwKSAhPT0gNDcgLyovKi8pIHBhdGhuYW1lID0gJy8nICsgcGF0aG5hbWU7XG4gIH0gZWxzZSBpZiAoIWhvc3QpIHtcbiAgICBob3N0ID0gJyc7XG4gIH1cblxuICBzZWFyY2ggPSBzZWFyY2gucmVwbGFjZSgnIycsICclMjMnKTtcblxuICBpZiAoaGFzaCAmJiBoYXNoLmNoYXJDb2RlQXQoMCkgIT09IDM1IC8qIyovKSBoYXNoID0gJyMnICsgaGFzaDtcbiAgaWYgKHNlYXJjaCAmJiBzZWFyY2guY2hhckNvZGVBdCgwKSAhPT0gNjMgLyo/Ki8pIHNlYXJjaCA9ICc/JyArIHNlYXJjaDtcblxuICByZXR1cm4gcHJvdG9jb2wgKyBob3N0ICsgcGF0aG5hbWUgKyBzZWFyY2ggKyBoYXNoO1xufTtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cbmZ1bmN0aW9uIHVybFJlc29sdmUoc291cmNlLCByZWxhdGl2ZSkge1xuICByZXR1cm4gdXJsUGFyc2Uoc291cmNlLCBmYWxzZSwgdHJ1ZSkucmVzb2x2ZShyZWxhdGl2ZSk7XG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5VcmwucHJvdG90eXBlLnJlc29sdmUgPSBmdW5jdGlvbiAocmVsYXRpdmUpIHtcbiAgcmV0dXJuIHRoaXMucmVzb2x2ZU9iamVjdCh1cmxQYXJzZShyZWxhdGl2ZSwgZmFsc2UsIHRydWUpKS5mb3JtYXQoKTtcbn07XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5mdW5jdGlvbiB1cmxSZXNvbHZlT2JqZWN0KHNvdXJjZSwgcmVsYXRpdmUpIHtcbiAgaWYgKCFzb3VyY2UpIHJldHVybiByZWxhdGl2ZTtcbiAgcmV0dXJuIHVybFBhcnNlKHNvdXJjZSwgZmFsc2UsIHRydWUpLnJlc29sdmVPYmplY3QocmVsYXRpdmUpO1xufVxuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogaW1wcm92ZSBjb3ZlcmFnZSAqL1xuVXJsLnByb3RvdHlwZS5yZXNvbHZlT2JqZWN0ID0gZnVuY3Rpb24gKHJlbGF0aXZlKSB7XG4gIGlmICh0eXBlb2YgcmVsYXRpdmUgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFyIHJlbCA9IG5ldyBVcmwoKTtcbiAgICByZWwucGFyc2UocmVsYXRpdmUsIGZhbHNlLCB0cnVlKTtcbiAgICByZWxhdGl2ZSA9IHJlbDtcbiAgfVxuXG4gIHZhciByZXN1bHQgPSBuZXcgVXJsKCk7XG4gIHZhciB0a2V5cyA9IE9iamVjdC5rZXlzKHRoaXMpO1xuICBmb3IgKHZhciB0ayA9IDA7IHRrIDwgdGtleXMubGVuZ3RoOyB0aysrKSB7XG4gICAgdmFyIHRrZXkgPSB0a2V5c1t0a107XG4gICAgcmVzdWx0W3RrZXldID0gdGhpc1t0a2V5XTtcbiAgfVxuXG4gIC8vIGhhc2ggaXMgYWx3YXlzIG92ZXJyaWRkZW4sIG5vIG1hdHRlciB3aGF0LlxuICAvLyBldmVuIGhyZWY9XCJcIiB3aWxsIHJlbW92ZSBpdC5cbiAgcmVzdWx0Lmhhc2ggPSByZWxhdGl2ZS5oYXNoO1xuXG4gIC8vIGlmIHRoZSByZWxhdGl2ZSB1cmwgaXMgZW1wdHksIHRoZW4gdGhlcmUncyBub3RoaW5nIGxlZnQgdG8gZG8gaGVyZS5cbiAgaWYgKHJlbGF0aXZlLmhyZWYgPT09ICcnKSB7XG4gICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8vIGhyZWZzIGxpa2UgLy9mb28vYmFyIGFsd2F5cyBjdXQgdG8gdGhlIHByb3RvY29sLlxuICBpZiAocmVsYXRpdmUuc2xhc2hlcyAmJiAhcmVsYXRpdmUucHJvdG9jb2wpIHtcbiAgICAvLyB0YWtlIGV2ZXJ5dGhpbmcgZXhjZXB0IHRoZSBwcm90b2NvbCBmcm9tIHJlbGF0aXZlXG4gICAgdmFyIHJrZXlzID0gT2JqZWN0LmtleXMocmVsYXRpdmUpO1xuICAgIGZvciAodmFyIHJrID0gMDsgcmsgPCBya2V5cy5sZW5ndGg7IHJrKyspIHtcbiAgICAgIHZhciBya2V5ID0gcmtleXNbcmtdO1xuICAgICAgaWYgKHJrZXkgIT09ICdwcm90b2NvbCcpIHJlc3VsdFtya2V5XSA9IHJlbGF0aXZlW3JrZXldO1xuICAgIH1cblxuICAgIC8vdXJsUGFyc2UgYXBwZW5kcyB0cmFpbGluZyAvIHRvIHVybHMgbGlrZSBodHRwOi8vd3d3LmV4YW1wbGUuY29tXG4gICAgaWYgKHNsYXNoZWRQcm90b2NvbFtyZXN1bHQucHJvdG9jb2xdICYmIHJlc3VsdC5ob3N0bmFtZSAmJiAhcmVzdWx0LnBhdGhuYW1lKSB7XG4gICAgICByZXN1bHQucGF0aCA9IHJlc3VsdC5wYXRobmFtZSA9ICcvJztcbiAgICB9XG5cbiAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgaWYgKHJlbGF0aXZlLnByb3RvY29sICYmIHJlbGF0aXZlLnByb3RvY29sICE9PSByZXN1bHQucHJvdG9jb2wpIHtcbiAgICAvLyBpZiBpdCdzIGEga25vd24gdXJsIHByb3RvY29sLCB0aGVuIGNoYW5naW5nXG4gICAgLy8gdGhlIHByb3RvY29sIGRvZXMgd2VpcmQgdGhpbmdzXG4gICAgLy8gZmlyc3QsIGlmIGl0J3Mgbm90IGZpbGU6LCB0aGVuIHdlIE1VU1QgaGF2ZSBhIGhvc3QsXG4gICAgLy8gYW5kIGlmIHRoZXJlIHdhcyBhIHBhdGhcbiAgICAvLyB0byBiZWdpbiB3aXRoLCB0aGVuIHdlIE1VU1QgaGF2ZSBhIHBhdGguXG4gICAgLy8gaWYgaXQgaXMgZmlsZTosIHRoZW4gdGhlIGhvc3QgaXMgZHJvcHBlZCxcbiAgICAvLyBiZWNhdXNlIHRoYXQncyBrbm93biB0byBiZSBob3N0bGVzcy5cbiAgICAvLyBhbnl0aGluZyBlbHNlIGlzIGFzc3VtZWQgdG8gYmUgYWJzb2x1dGUuXG4gICAgaWYgKCFzbGFzaGVkUHJvdG9jb2xbcmVsYXRpdmUucHJvdG9jb2xdKSB7XG4gICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHJlbGF0aXZlKTtcbiAgICAgIGZvciAodmFyIHYgPSAwOyB2IDwga2V5cy5sZW5ndGg7IHYrKykge1xuICAgICAgICB2YXIgayA9IGtleXNbdl07XG4gICAgICAgIHJlc3VsdFtrXSA9IHJlbGF0aXZlW2tdO1xuICAgICAgfVxuICAgICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHJlc3VsdC5wcm90b2NvbCA9IHJlbGF0aXZlLnByb3RvY29sO1xuICAgIGlmIChcbiAgICAgICFyZWxhdGl2ZS5ob3N0ICYmXG4gICAgICAhL15maWxlOj8kLy50ZXN0KHJlbGF0aXZlLnByb3RvY29sKSAmJlxuICAgICAgIWhvc3RsZXNzUHJvdG9jb2xbcmVsYXRpdmUucHJvdG9jb2xdXG4gICAgKSB7XG4gICAgICBjb25zdCByZWxQYXRoID0gKHJlbGF0aXZlLnBhdGhuYW1lIHx8ICcnKS5zcGxpdCgnLycpO1xuICAgICAgd2hpbGUgKHJlbFBhdGgubGVuZ3RoICYmICEocmVsYXRpdmUuaG9zdCA9IHJlbFBhdGguc2hpZnQoKSkpO1xuICAgICAgaWYgKCFyZWxhdGl2ZS5ob3N0KSByZWxhdGl2ZS5ob3N0ID0gJyc7XG4gICAgICBpZiAoIXJlbGF0aXZlLmhvc3RuYW1lKSByZWxhdGl2ZS5ob3N0bmFtZSA9ICcnO1xuICAgICAgaWYgKHJlbFBhdGhbMF0gIT09ICcnKSByZWxQYXRoLnVuc2hpZnQoJycpO1xuICAgICAgaWYgKHJlbFBhdGgubGVuZ3RoIDwgMikgcmVsUGF0aC51bnNoaWZ0KCcnKTtcbiAgICAgIHJlc3VsdC5wYXRobmFtZSA9IHJlbFBhdGguam9pbignLycpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQucGF0aG5hbWUgPSByZWxhdGl2ZS5wYXRobmFtZTtcbiAgICB9XG4gICAgcmVzdWx0LnNlYXJjaCA9IHJlbGF0aXZlLnNlYXJjaDtcbiAgICByZXN1bHQucXVlcnkgPSByZWxhdGl2ZS5xdWVyeTtcbiAgICByZXN1bHQuaG9zdCA9IHJlbGF0aXZlLmhvc3QgfHwgJyc7XG4gICAgcmVzdWx0LmF1dGggPSByZWxhdGl2ZS5hdXRoO1xuICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlbGF0aXZlLmhvc3RuYW1lIHx8IHJlbGF0aXZlLmhvc3Q7XG4gICAgcmVzdWx0LnBvcnQgPSByZWxhdGl2ZS5wb3J0O1xuICAgIC8vIHRvIHN1cHBvcnQgaHR0cC5yZXF1ZXN0XG4gICAgaWYgKHJlc3VsdC5wYXRobmFtZSB8fCByZXN1bHQuc2VhcmNoKSB7XG4gICAgICB2YXIgcCA9IHJlc3VsdC5wYXRobmFtZSB8fCAnJztcbiAgICAgIHZhciBzID0gcmVzdWx0LnNlYXJjaCB8fCAnJztcbiAgICAgIHJlc3VsdC5wYXRoID0gcCArIHM7XG4gICAgfVxuICAgIHJlc3VsdC5zbGFzaGVzID0gcmVzdWx0LnNsYXNoZXMgfHwgcmVsYXRpdmUuc2xhc2hlcztcbiAgICByZXN1bHQuaHJlZiA9IHJlc3VsdC5mb3JtYXQoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgdmFyIGlzU291cmNlQWJzID0gcmVzdWx0LnBhdGhuYW1lICYmIHJlc3VsdC5wYXRobmFtZS5jaGFyQXQoMCkgPT09ICcvJztcbiAgdmFyIGlzUmVsQWJzID0gcmVsYXRpdmUuaG9zdCB8fCAocmVsYXRpdmUucGF0aG5hbWUgJiYgcmVsYXRpdmUucGF0aG5hbWUuY2hhckF0KDApID09PSAnLycpO1xuICB2YXIgbXVzdEVuZEFicyA9IGlzUmVsQWJzIHx8IGlzU291cmNlQWJzIHx8IChyZXN1bHQuaG9zdCAmJiByZWxhdGl2ZS5wYXRobmFtZSk7XG4gIHZhciByZW1vdmVBbGxEb3RzID0gbXVzdEVuZEFicztcbiAgdmFyIHNyY1BhdGggPSAocmVzdWx0LnBhdGhuYW1lICYmIHJlc3VsdC5wYXRobmFtZS5zcGxpdCgnLycpKSB8fCBbXTtcbiAgdmFyIHJlbFBhdGggPSAocmVsYXRpdmUucGF0aG5hbWUgJiYgcmVsYXRpdmUucGF0aG5hbWUuc3BsaXQoJy8nKSkgfHwgW107XG4gIHZhciBwc3ljaG90aWMgPSByZXN1bHQucHJvdG9jb2wgJiYgIXNsYXNoZWRQcm90b2NvbFtyZXN1bHQucHJvdG9jb2xdO1xuXG4gIC8vIGlmIHRoZSB1cmwgaXMgYSBub24tc2xhc2hlZCB1cmwsIHRoZW4gcmVsYXRpdmVcbiAgLy8gbGlua3MgbGlrZSAuLi8uLiBzaG91bGQgYmUgYWJsZVxuICAvLyB0byBjcmF3bCB1cCB0byB0aGUgaG9zdG5hbWUsIGFzIHdlbGwuICBUaGlzIGlzIHN0cmFuZ2UuXG4gIC8vIHJlc3VsdC5wcm90b2NvbCBoYXMgYWxyZWFkeSBiZWVuIHNldCBieSBub3cuXG4gIC8vIExhdGVyIG9uLCBwdXQgdGhlIGZpcnN0IHBhdGggcGFydCBpbnRvIHRoZSBob3N0IGZpZWxkLlxuICBpZiAocHN5Y2hvdGljKSB7XG4gICAgcmVzdWx0Lmhvc3RuYW1lID0gJyc7XG4gICAgcmVzdWx0LnBvcnQgPSBudWxsO1xuICAgIGlmIChyZXN1bHQuaG9zdCkge1xuICAgICAgaWYgKHNyY1BhdGhbMF0gPT09ICcnKSBzcmNQYXRoWzBdID0gcmVzdWx0Lmhvc3Q7XG4gICAgICBlbHNlIHNyY1BhdGgudW5zaGlmdChyZXN1bHQuaG9zdCk7XG4gICAgfVxuICAgIHJlc3VsdC5ob3N0ID0gJyc7XG4gICAgaWYgKHJlbGF0aXZlLnByb3RvY29sKSB7XG4gICAgICByZWxhdGl2ZS5ob3N0bmFtZSA9IG51bGw7XG4gICAgICByZWxhdGl2ZS5wb3J0ID0gbnVsbDtcbiAgICAgIGlmIChyZWxhdGl2ZS5ob3N0KSB7XG4gICAgICAgIGlmIChyZWxQYXRoWzBdID09PSAnJykgcmVsUGF0aFswXSA9IHJlbGF0aXZlLmhvc3Q7XG4gICAgICAgIGVsc2UgcmVsUGF0aC51bnNoaWZ0KHJlbGF0aXZlLmhvc3QpO1xuICAgICAgfVxuICAgICAgcmVsYXRpdmUuaG9zdCA9IG51bGw7XG4gICAgfVxuICAgIG11c3RFbmRBYnMgPSBtdXN0RW5kQWJzICYmIChyZWxQYXRoWzBdID09PSAnJyB8fCBzcmNQYXRoWzBdID09PSAnJyk7XG4gIH1cblxuICBpZiAoaXNSZWxBYnMpIHtcbiAgICAvLyBpdCdzIGFic29sdXRlLlxuICAgIHJlc3VsdC5ob3N0ID0gcmVsYXRpdmUuaG9zdCB8fCByZWxhdGl2ZS5ob3N0ID09PSAnJyA/IHJlbGF0aXZlLmhvc3QgOiByZXN1bHQuaG9zdDtcbiAgICByZXN1bHQuaG9zdG5hbWUgPVxuICAgICAgcmVsYXRpdmUuaG9zdG5hbWUgfHwgcmVsYXRpdmUuaG9zdG5hbWUgPT09ICcnID8gcmVsYXRpdmUuaG9zdG5hbWUgOiByZXN1bHQuaG9zdG5hbWU7XG4gICAgcmVzdWx0LnNlYXJjaCA9IHJlbGF0aXZlLnNlYXJjaDtcbiAgICByZXN1bHQucXVlcnkgPSByZWxhdGl2ZS5xdWVyeTtcbiAgICBzcmNQYXRoID0gcmVsUGF0aDtcbiAgICAvLyBmYWxsIHRocm91Z2ggdG8gdGhlIGRvdC1oYW5kbGluZyBiZWxvdy5cbiAgfSBlbHNlIGlmIChyZWxQYXRoLmxlbmd0aCkge1xuICAgIC8vIGl0J3MgcmVsYXRpdmVcbiAgICAvLyB0aHJvdyBhd2F5IHRoZSBleGlzdGluZyBmaWxlLCBhbmQgdGFrZSB0aGUgbmV3IHBhdGggaW5zdGVhZC5cbiAgICBpZiAoIXNyY1BhdGgpIHNyY1BhdGggPSBbXTtcbiAgICBzcmNQYXRoLnBvcCgpO1xuICAgIHNyY1BhdGggPSBzcmNQYXRoLmNvbmNhdChyZWxQYXRoKTtcbiAgICByZXN1bHQuc2VhcmNoID0gcmVsYXRpdmUuc2VhcmNoO1xuICAgIHJlc3VsdC5xdWVyeSA9IHJlbGF0aXZlLnF1ZXJ5O1xuICB9IGVsc2UgaWYgKHJlbGF0aXZlLnNlYXJjaCAhPT0gbnVsbCAmJiByZWxhdGl2ZS5zZWFyY2ggIT09IHVuZGVmaW5lZCkge1xuICAgIC8vIGp1c3QgcHVsbCBvdXQgdGhlIHNlYXJjaC5cbiAgICAvLyBsaWtlIGhyZWY9Jz9mb28nLlxuICAgIC8vIFB1dCB0aGlzIGFmdGVyIHRoZSBvdGhlciB0d28gY2FzZXMgYmVjYXVzZSBpdCBzaW1wbGlmaWVzIHRoZSBib29sZWFuc1xuICAgIGlmIChwc3ljaG90aWMpIHtcbiAgICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlc3VsdC5ob3N0ID0gc3JjUGF0aC5zaGlmdCgpO1xuICAgICAgLy9vY2Nhc2lvbmFsbHkgdGhlIGF1dGggY2FuIGdldCBzdHVjayBvbmx5IGluIGhvc3RcbiAgICAgIC8vdGhpcyBlc3BlY2lhbGx5IGhhcHBlbnMgaW4gY2FzZXMgbGlrZVxuICAgICAgLy91cmwucmVzb2x2ZU9iamVjdCgnbWFpbHRvOmxvY2FsMUBkb21haW4xJywgJ2xvY2FsMkBkb21haW4yJylcbiAgICAgIGNvbnN0IGF1dGhJbkhvc3QgPVxuICAgICAgICByZXN1bHQuaG9zdCAmJiByZXN1bHQuaG9zdC5pbmRleE9mKCdAJykgPiAwID8gcmVzdWx0Lmhvc3Quc3BsaXQoJ0AnKSA6IGZhbHNlO1xuICAgICAgaWYgKGF1dGhJbkhvc3QpIHtcbiAgICAgICAgcmVzdWx0LmF1dGggPSBhdXRoSW5Ib3N0LnNoaWZ0KCk7XG4gICAgICAgIHJlc3VsdC5ob3N0ID0gcmVzdWx0Lmhvc3RuYW1lID0gYXV0aEluSG9zdC5zaGlmdCgpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXN1bHQuc2VhcmNoID0gcmVsYXRpdmUuc2VhcmNoO1xuICAgIHJlc3VsdC5xdWVyeSA9IHJlbGF0aXZlLnF1ZXJ5O1xuICAgIC8vdG8gc3VwcG9ydCBodHRwLnJlcXVlc3RcbiAgICBpZiAocmVzdWx0LnBhdGhuYW1lICE9PSBudWxsIHx8IHJlc3VsdC5zZWFyY2ggIT09IG51bGwpIHtcbiAgICAgIHJlc3VsdC5wYXRoID0gKHJlc3VsdC5wYXRobmFtZSA/IHJlc3VsdC5wYXRobmFtZSA6ICcnKSArIChyZXN1bHQuc2VhcmNoID8gcmVzdWx0LnNlYXJjaCA6ICcnKTtcbiAgICB9XG4gICAgcmVzdWx0LmhyZWYgPSByZXN1bHQuZm9ybWF0KCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGlmICghc3JjUGF0aC5sZW5ndGgpIHtcbiAgICAvLyBubyBwYXRoIGF0IGFsbC4gIGVhc3kuXG4gICAgLy8gd2UndmUgYWxyZWFkeSBoYW5kbGVkIHRoZSBvdGhlciBzdHVmZiBhYm92ZS5cbiAgICByZXN1bHQucGF0aG5hbWUgPSBudWxsO1xuICAgIC8vdG8gc3VwcG9ydCBodHRwLnJlcXVlc3RcbiAgICBpZiAocmVzdWx0LnNlYXJjaCkge1xuICAgICAgcmVzdWx0LnBhdGggPSAnLycgKyByZXN1bHQuc2VhcmNoO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHQucGF0aCA9IG51bGw7XG4gICAgfVxuICAgIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvLyBpZiBhIHVybCBFTkRzIGluIC4gb3IgLi4sIHRoZW4gaXQgbXVzdCBnZXQgYSB0cmFpbGluZyBzbGFzaC5cbiAgLy8gaG93ZXZlciwgaWYgaXQgZW5kcyBpbiBhbnl0aGluZyBlbHNlIG5vbi1zbGFzaHksXG4gIC8vIHRoZW4gaXQgbXVzdCBOT1QgZ2V0IGEgdHJhaWxpbmcgc2xhc2guXG4gIHZhciBsYXN0ID0gc3JjUGF0aC5zbGljZSgtMSlbMF07XG4gIHZhciBoYXNUcmFpbGluZ1NsYXNoID1cbiAgICAoKHJlc3VsdC5ob3N0IHx8IHJlbGF0aXZlLmhvc3QgfHwgc3JjUGF0aC5sZW5ndGggPiAxKSAmJiAobGFzdCA9PT0gJy4nIHx8IGxhc3QgPT09ICcuLicpKSB8fFxuICAgIGxhc3QgPT09ICcnO1xuXG4gIC8vIHN0cmlwIHNpbmdsZSBkb3RzLCByZXNvbHZlIGRvdWJsZSBkb3RzIHRvIHBhcmVudCBkaXJcbiAgLy8gaWYgdGhlIHBhdGggdHJpZXMgdG8gZ28gYWJvdmUgdGhlIHJvb3QsIGB1cGAgZW5kcyB1cCA+IDBcbiAgdmFyIHVwID0gMDtcbiAgZm9yICh2YXIgaSA9IHNyY1BhdGgubGVuZ3RoOyBpID49IDA7IGktLSkge1xuICAgIGxhc3QgPSBzcmNQYXRoW2ldO1xuICAgIGlmIChsYXN0ID09PSAnLicpIHtcbiAgICAgIHNwbGljZU9uZShzcmNQYXRoLCBpKTtcbiAgICB9IGVsc2UgaWYgKGxhc3QgPT09ICcuLicpIHtcbiAgICAgIHNwbGljZU9uZShzcmNQYXRoLCBpKTtcbiAgICAgIHVwKys7XG4gICAgfSBlbHNlIGlmICh1cCkge1xuICAgICAgc3BsaWNlT25lKHNyY1BhdGgsIGkpO1xuICAgICAgdXAtLTtcbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGUgcGF0aCBpcyBhbGxvd2VkIHRvIGdvIGFib3ZlIHRoZSByb290LCByZXN0b3JlIGxlYWRpbmcgLi5zXG4gIGlmICghbXVzdEVuZEFicyAmJiAhcmVtb3ZlQWxsRG90cykge1xuICAgIGZvciAoOyB1cC0tOyB1cCkge1xuICAgICAgc3JjUGF0aC51bnNoaWZ0KCcuLicpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChtdXN0RW5kQWJzICYmIHNyY1BhdGhbMF0gIT09ICcnICYmICghc3JjUGF0aFswXSB8fCBzcmNQYXRoWzBdLmNoYXJBdCgwKSAhPT0gJy8nKSkge1xuICAgIHNyY1BhdGgudW5zaGlmdCgnJyk7XG4gIH1cblxuICBpZiAoaGFzVHJhaWxpbmdTbGFzaCAmJiBzcmNQYXRoLmpvaW4oJy8nKS5zdWJzdHIoLTEpICE9PSAnLycpIHtcbiAgICBzcmNQYXRoLnB1c2goJycpO1xuICB9XG5cbiAgdmFyIGlzQWJzb2x1dGUgPSBzcmNQYXRoWzBdID09PSAnJyB8fCAoc3JjUGF0aFswXSAmJiBzcmNQYXRoWzBdLmNoYXJBdCgwKSA9PT0gJy8nKTtcblxuICAvLyBwdXQgdGhlIGhvc3QgYmFja1xuICBpZiAocHN5Y2hvdGljKSB7XG4gICAgaWYgKGlzQWJzb2x1dGUpIHtcbiAgICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlc3VsdC5ob3N0ID0gJyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdC5ob3N0bmFtZSA9IHJlc3VsdC5ob3N0ID0gc3JjUGF0aC5sZW5ndGggPyBzcmNQYXRoLnNoaWZ0KCkgOiAnJztcbiAgICB9XG4gICAgLy9vY2Nhc2lvbmFsbHkgdGhlIGF1dGggY2FuIGdldCBzdHVjayBvbmx5IGluIGhvc3RcbiAgICAvL3RoaXMgZXNwZWNpYWxseSBoYXBwZW5zIGluIGNhc2VzIGxpa2VcbiAgICAvL3VybC5yZXNvbHZlT2JqZWN0KCdtYWlsdG86bG9jYWwxQGRvbWFpbjEnLCAnbG9jYWwyQGRvbWFpbjInKVxuICAgIGNvbnN0IGF1dGhJbkhvc3QgPSByZXN1bHQuaG9zdCAmJiByZXN1bHQuaG9zdC5pbmRleE9mKCdAJykgPiAwID8gcmVzdWx0Lmhvc3Quc3BsaXQoJ0AnKSA6IGZhbHNlO1xuICAgIGlmIChhdXRoSW5Ib3N0KSB7XG4gICAgICByZXN1bHQuYXV0aCA9IGF1dGhJbkhvc3Quc2hpZnQoKTtcbiAgICAgIHJlc3VsdC5ob3N0ID0gcmVzdWx0Lmhvc3RuYW1lID0gYXV0aEluSG9zdC5zaGlmdCgpO1xuICAgIH1cbiAgfVxuXG4gIG11c3RFbmRBYnMgPSBtdXN0RW5kQWJzIHx8IChyZXN1bHQuaG9zdCAmJiBzcmNQYXRoLmxlbmd0aCk7XG5cbiAgaWYgKG11c3RFbmRBYnMgJiYgIWlzQWJzb2x1dGUpIHtcbiAgICBzcmNQYXRoLnVuc2hpZnQoJycpO1xuICB9XG5cbiAgaWYgKCFzcmNQYXRoLmxlbmd0aCkge1xuICAgIHJlc3VsdC5wYXRobmFtZSA9IG51bGw7XG4gICAgcmVzdWx0LnBhdGggPSBudWxsO1xuICB9IGVsc2Uge1xuICAgIHJlc3VsdC5wYXRobmFtZSA9IHNyY1BhdGguam9pbignLycpO1xuICB9XG5cbiAgLy90byBzdXBwb3J0IHJlcXVlc3QuaHR0cFxuICBpZiAocmVzdWx0LnBhdGhuYW1lICE9PSBudWxsIHx8IHJlc3VsdC5zZWFyY2ggIT09IG51bGwpIHtcbiAgICByZXN1bHQucGF0aCA9IChyZXN1bHQucGF0aG5hbWUgPyByZXN1bHQucGF0aG5hbWUgOiAnJykgKyAocmVzdWx0LnNlYXJjaCA/IHJlc3VsdC5zZWFyY2ggOiAnJyk7XG4gIH1cbiAgcmVzdWx0LmF1dGggPSByZWxhdGl2ZS5hdXRoIHx8IHJlc3VsdC5hdXRoO1xuICByZXN1bHQuc2xhc2hlcyA9IHJlc3VsdC5zbGFzaGVzIHx8IHJlbGF0aXZlLnNsYXNoZXM7XG4gIHJlc3VsdC5ocmVmID0gcmVzdWx0LmZvcm1hdCgpO1xuICByZXR1cm4gcmVzdWx0O1xufTtcblxuLyogaXN0YW5idWwgaWdub3JlIG5leHQ6IGltcHJvdmUgY292ZXJhZ2UgKi9cblVybC5wcm90b3R5cGUucGFyc2VIb3N0ID0gZnVuY3Rpb24gKCkge1xuICB2YXIgaG9zdCA9IHRoaXMuaG9zdDtcbiAgdmFyIHBvcnQgPSBwb3J0UGF0dGVybi5leGVjKGhvc3QpO1xuICBpZiAocG9ydCkge1xuICAgIHBvcnQgPSBwb3J0WzBdO1xuICAgIGlmIChwb3J0ICE9PSAnOicpIHtcbiAgICAgIHRoaXMucG9ydCA9IHBvcnQuc2xpY2UoMSk7XG4gICAgfVxuICAgIGhvc3QgPSBob3N0LnNsaWNlKDAsIGhvc3QubGVuZ3RoIC0gcG9ydC5sZW5ndGgpO1xuICB9XG4gIGlmIChob3N0KSB0aGlzLmhvc3RuYW1lID0gaG9zdDtcbn07XG5cbi8vIEFib3V0IDEuNXggZmFzdGVyIHRoYW4gdGhlIHR3by1hcmcgdmVyc2lvbiBvZiBBcnJheSNzcGxpY2UoKS5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0OiBpbXByb3ZlIGNvdmVyYWdlICovXG5mdW5jdGlvbiBzcGxpY2VPbmUobGlzdCwgaW5kZXgpIHtcbiAgZm9yICh2YXIgaSA9IGluZGV4LCBrID0gaSArIDEsIG4gPSBsaXN0Lmxlbmd0aDsgayA8IG47IGkgKz0gMSwgayArPSAxKSBsaXN0W2ldID0gbGlzdFtrXTtcbiAgbGlzdC5wb3AoKTtcbn1cblxudmFyIGhleFRhYmxlID0gbmV3IEFycmF5KDI1Nik7XG5mb3IgKHZhciBpID0gMDsgaSA8IDI1NjsgKytpKVxuICBoZXhUYWJsZVtpXSA9ICclJyArICgoaSA8IDE2ID8gJzAnIDogJycpICsgaS50b1N0cmluZygxNikpLnRvVXBwZXJDYXNlKCk7XG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dDogaW1wcm92ZSBjb3ZlcmFnZSAqL1xuZnVuY3Rpb24gZW5jb2RlQXV0aChzdHIpIHtcbiAgLy8gZmFzdGVyIGVuY29kZVVSSUNvbXBvbmVudCBhbHRlcm5hdGl2ZSBmb3IgZW5jb2RpbmcgYXV0aCB1cmkgY29tcG9uZW50c1xuICB2YXIgb3V0ID0gJyc7XG4gIHZhciBsYXN0UG9zID0gMDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHtcbiAgICB2YXIgYyA9IHN0ci5jaGFyQ29kZUF0KGkpO1xuXG4gICAgLy8gVGhlc2UgY2hhcmFjdGVycyBkbyBub3QgbmVlZCBlc2NhcGluZzpcbiAgICAvLyAhIC0gLiBfIH5cbiAgICAvLyAnICggKSAqIDpcbiAgICAvLyBkaWdpdHNcbiAgICAvLyBhbHBoYSAodXBwZXJjYXNlKVxuICAgIC8vIGFscGhhIChsb3dlcmNhc2UpXG4gICAgaWYgKFxuICAgICAgYyA9PT0gMHgyMSB8fFxuICAgICAgYyA9PT0gMHgyZCB8fFxuICAgICAgYyA9PT0gMHgyZSB8fFxuICAgICAgYyA9PT0gMHg1ZiB8fFxuICAgICAgYyA9PT0gMHg3ZSB8fFxuICAgICAgKGMgPj0gMHgyNyAmJiBjIDw9IDB4MmEpIHx8XG4gICAgICAoYyA+PSAweDMwICYmIGMgPD0gMHgzYSkgfHxcbiAgICAgIChjID49IDB4NDEgJiYgYyA8PSAweDVhKSB8fFxuICAgICAgKGMgPj0gMHg2MSAmJiBjIDw9IDB4N2EpXG4gICAgKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpZiAoaSAtIGxhc3RQb3MgPiAwKSBvdXQgKz0gc3RyLnNsaWNlKGxhc3RQb3MsIGkpO1xuXG4gICAgbGFzdFBvcyA9IGkgKyAxO1xuXG4gICAgLy8gT3RoZXIgQVNDSUkgY2hhcmFjdGVyc1xuICAgIGlmIChjIDwgMHg4MCkge1xuICAgICAgb3V0ICs9IGhleFRhYmxlW2NdO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gTXVsdGktYnl0ZSBjaGFyYWN0ZXJzIC4uLlxuICAgIGlmIChjIDwgMHg4MDApIHtcbiAgICAgIG91dCArPSBoZXhUYWJsZVsweGMwIHwgKGMgPj4gNildICsgaGV4VGFibGVbMHg4MCB8IChjICYgMHgzZildO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChjIDwgMHhkODAwIHx8IGMgPj0gMHhlMDAwKSB7XG4gICAgICBvdXQgKz1cbiAgICAgICAgaGV4VGFibGVbMHhlMCB8IChjID4+IDEyKV0gK1xuICAgICAgICBoZXhUYWJsZVsweDgwIHwgKChjID4+IDYpICYgMHgzZildICtcbiAgICAgICAgaGV4VGFibGVbMHg4MCB8IChjICYgMHgzZildO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIC8vIFN1cnJvZ2F0ZSBwYWlyXG4gICAgKytpO1xuICAgIHZhciBjMjtcbiAgICBpZiAoaSA8IHN0ci5sZW5ndGgpIGMyID0gc3RyLmNoYXJDb2RlQXQoaSkgJiAweDNmZjtcbiAgICBlbHNlIGMyID0gMDtcbiAgICBjID0gMHgxMDAwMCArICgoKGMgJiAweDNmZikgPDwgMTApIHwgYzIpO1xuICAgIG91dCArPVxuICAgICAgaGV4VGFibGVbMHhmMCB8IChjID4+IDE4KV0gK1xuICAgICAgaGV4VGFibGVbMHg4MCB8ICgoYyA+PiAxMikgJiAweDNmKV0gK1xuICAgICAgaGV4VGFibGVbMHg4MCB8ICgoYyA+PiA2KSAmIDB4M2YpXSArXG4gICAgICBoZXhUYWJsZVsweDgwIHwgKGMgJiAweDNmKV07XG4gIH1cbiAgaWYgKGxhc3RQb3MgPT09IDApIHJldHVybiBzdHI7XG4gIGlmIChsYXN0UG9zIDwgc3RyLmxlbmd0aCkgcmV0dXJuIG91dCArIHN0ci5zbGljZShsYXN0UG9zKTtcbiAgcmV0dXJuIG91dDtcbn1cbiJdfQ== \ No newline at end of file From b2b525dbcc90afb129e90812fe5407d04838613c Mon Sep 17 00:00:00 2001 From: Jason Posthuma Date: Thu, 25 Feb 2021 14:49:24 +0100 Subject: [PATCH 6/6] Added test cases --- spec/ParseUser.spec.js | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/spec/ParseUser.spec.js b/spec/ParseUser.spec.js index a44926caa4..3502cdd50d 100644 --- a/spec/ParseUser.spec.js +++ b/spec/ParseUser.spec.js @@ -12,6 +12,7 @@ const request = require('../lib/request'); const passwordCrypto = require('../lib/password'); const Config = require('../lib/Config'); const cryptoUtils = require('../lib/cryptoUtils'); +const UsersRouter = require('../lib/Routers/UsersRouter'); function verifyACL(user) { const ACL = user.getACL(); @@ -3925,6 +3926,45 @@ describe('Parse.User testing', () => { } }); + describe('UsersRouter.handleLogIn', () => { + it('should work with valid userFromJWT', async done => { + const user = await Parse.User.signUp('some_user', 'some_password'); + + const fakeReq = { + userFromJWT: user, + config: Config.get('test'), + info: {}, + }; + + const { response = {} } = await new UsersRouter.UsersRouter().handleLogIn(fakeReq); + + expect(user.id).toEqual(response.objectId); + expect(response.sessionToken).toBeTruthy(); + done(); + }); + + it('should fail with non-existing userFromJWT', async done => { + const user = new Parse.User({ + username: 'not_a_real_user', + id: '1234567', + }); + + const fakeReq = { + userFromJWT: user, + config: Config.get('test'), + info: {}, + }; + + try { + await new UsersRouter.UsersRouter().handleLogIn(fakeReq); + fail('User login should not have succeeded'); + } catch (error) { + expect(error.code).toEqual(101); + } + done(); + }); + }); + describe('issue #4897', () => { it_only_db('mongo')('should be able to login with a legacy user (no ACL)', async () => { // This issue is a side effect of the locked users and legacy users which don't have ACL's