parse-server 2.8.4 → 8.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +167 -25
- package/NOTICE +10 -0
- package/README.md +929 -278
- package/lib/AccountLockout.js +47 -30
- package/lib/Adapters/AdapterLoader.js +21 -6
- package/lib/Adapters/Analytics/AnalyticsAdapter.js +15 -12
- package/lib/Adapters/Auth/AuthAdapter.js +116 -13
- package/lib/Adapters/Auth/BaseCodeAuthAdapter.js +99 -0
- package/lib/Adapters/Auth/OAuth1Client.js +27 -46
- package/lib/Adapters/Auth/apple.js +123 -0
- package/lib/Adapters/Auth/facebook.js +162 -35
- package/lib/Adapters/Auth/gcenter.js +217 -0
- package/lib/Adapters/Auth/github.js +118 -48
- package/lib/Adapters/Auth/google.js +160 -51
- package/lib/Adapters/Auth/gpgames.js +125 -0
- package/lib/Adapters/Auth/httpsRequest.js +6 -7
- package/lib/Adapters/Auth/index.js +170 -62
- package/lib/Adapters/Auth/instagram.js +114 -40
- package/lib/Adapters/Auth/janraincapture.js +52 -23
- package/lib/Adapters/Auth/janrainengage.js +19 -36
- package/lib/Adapters/Auth/keycloak.js +148 -0
- package/lib/Adapters/Auth/ldap.js +167 -0
- package/lib/Adapters/Auth/line.js +125 -0
- package/lib/Adapters/Auth/linkedin.js +111 -55
- package/lib/Adapters/Auth/meetup.js +24 -34
- package/lib/Adapters/Auth/mfa.js +324 -0
- package/lib/Adapters/Auth/microsoft.js +111 -0
- package/lib/Adapters/Auth/oauth2.js +97 -162
- package/lib/Adapters/Auth/phantauth.js +53 -0
- package/lib/Adapters/Auth/qq.js +108 -49
- package/lib/Adapters/Auth/spotify.js +107 -55
- package/lib/Adapters/Auth/twitter.js +188 -48
- package/lib/Adapters/Auth/utils.js +28 -0
- package/lib/Adapters/Auth/vkontakte.js +26 -39
- package/lib/Adapters/Auth/wechat.js +106 -44
- package/lib/Adapters/Auth/weibo.js +132 -58
- package/lib/Adapters/Cache/CacheAdapter.js +13 -8
- package/lib/Adapters/Cache/InMemoryCache.js +3 -13
- package/lib/Adapters/Cache/InMemoryCacheAdapter.js +5 -13
- package/lib/Adapters/Cache/LRUCache.js +13 -27
- package/lib/Adapters/Cache/NullCacheAdapter.js +3 -8
- package/lib/Adapters/Cache/RedisCacheAdapter.js +85 -76
- package/lib/Adapters/Cache/SchemaCache.js +25 -0
- package/lib/Adapters/Email/MailAdapter.js +10 -8
- package/lib/Adapters/Files/FilesAdapter.js +83 -25
- package/lib/Adapters/Files/GridFSBucketAdapter.js +231 -0
- package/lib/Adapters/Files/GridStoreAdapter.js +4 -91
- package/lib/Adapters/Logger/LoggerAdapter.js +18 -14
- package/lib/Adapters/Logger/WinstonLogger.js +69 -88
- package/lib/Adapters/Logger/WinstonLoggerAdapter.js +7 -16
- package/lib/Adapters/MessageQueue/EventEmitterMQ.js +8 -26
- package/lib/Adapters/PubSub/EventEmitterPubSub.js +12 -25
- package/lib/Adapters/PubSub/PubSubAdapter.js +34 -0
- package/lib/Adapters/PubSub/RedisPubSub.js +42 -19
- package/lib/Adapters/Push/PushAdapter.js +14 -7
- package/lib/Adapters/Storage/Mongo/MongoCollection.js +137 -45
- package/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js +158 -63
- package/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js +320 -168
- package/lib/Adapters/Storage/Mongo/MongoTransform.js +279 -306
- package/lib/Adapters/Storage/Postgres/PostgresClient.js +14 -10
- package/lib/Adapters/Storage/Postgres/PostgresConfigParser.js +47 -21
- package/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js +854 -468
- package/lib/Adapters/Storage/Postgres/sql/index.js +4 -6
- package/lib/Adapters/Storage/StorageAdapter.js +1 -1
- package/lib/Adapters/WebSocketServer/WSAdapter.js +35 -0
- package/lib/Adapters/WebSocketServer/WSSAdapter.js +66 -0
- package/lib/Auth.js +488 -125
- package/lib/ClientSDK.js +2 -6
- package/lib/Config.js +525 -94
- package/lib/Controllers/AdaptableController.js +5 -25
- package/lib/Controllers/AnalyticsController.js +22 -23
- package/lib/Controllers/CacheController.js +10 -31
- package/lib/Controllers/DatabaseController.js +767 -313
- package/lib/Controllers/FilesController.js +49 -54
- package/lib/Controllers/HooksController.js +80 -84
- package/lib/Controllers/LiveQueryController.js +35 -22
- package/lib/Controllers/LoggerController.js +22 -58
- package/lib/Controllers/ParseGraphQLController.js +293 -0
- package/lib/Controllers/PushController.js +58 -49
- package/lib/Controllers/SchemaController.js +916 -422
- package/lib/Controllers/UserController.js +265 -180
- package/lib/Controllers/index.js +90 -125
- package/lib/Controllers/types.js +1 -1
- package/lib/Deprecator/Deprecations.js +30 -0
- package/lib/Deprecator/Deprecator.js +127 -0
- package/lib/Error.js +48 -0
- package/lib/GraphQL/ParseGraphQLSchema.js +375 -0
- package/lib/GraphQL/ParseGraphQLServer.js +214 -0
- package/lib/GraphQL/helpers/objectsMutations.js +30 -0
- package/lib/GraphQL/helpers/objectsQueries.js +246 -0
- package/lib/GraphQL/loaders/configMutations.js +87 -0
- package/lib/GraphQL/loaders/configQueries.js +79 -0
- package/lib/GraphQL/loaders/defaultGraphQLMutations.js +21 -0
- package/lib/GraphQL/loaders/defaultGraphQLQueries.js +23 -0
- package/lib/GraphQL/loaders/defaultGraphQLTypes.js +1098 -0
- package/lib/GraphQL/loaders/defaultRelaySchema.js +53 -0
- package/lib/GraphQL/loaders/filesMutations.js +107 -0
- package/lib/GraphQL/loaders/functionsMutations.js +78 -0
- package/lib/GraphQL/loaders/parseClassMutations.js +268 -0
- package/lib/GraphQL/loaders/parseClassQueries.js +127 -0
- package/lib/GraphQL/loaders/parseClassTypes.js +493 -0
- package/lib/GraphQL/loaders/schemaDirectives.js +62 -0
- package/lib/GraphQL/loaders/schemaMutations.js +162 -0
- package/lib/GraphQL/loaders/schemaQueries.js +81 -0
- package/lib/GraphQL/loaders/schemaTypes.js +341 -0
- package/lib/GraphQL/loaders/usersMutations.js +433 -0
- package/lib/GraphQL/loaders/usersQueries.js +90 -0
- package/lib/GraphQL/parseGraphQLUtils.js +63 -0
- package/lib/GraphQL/transformers/className.js +14 -0
- package/lib/GraphQL/transformers/constraintType.js +53 -0
- package/lib/GraphQL/transformers/inputType.js +51 -0
- package/lib/GraphQL/transformers/mutation.js +274 -0
- package/lib/GraphQL/transformers/outputType.js +51 -0
- package/lib/GraphQL/transformers/query.js +237 -0
- package/lib/GraphQL/transformers/schemaFields.js +99 -0
- package/lib/KeyPromiseQueue.js +48 -0
- package/lib/LiveQuery/Client.js +25 -33
- package/lib/LiveQuery/Id.js +2 -5
- package/lib/LiveQuery/ParseCloudCodePublisher.js +26 -23
- package/lib/LiveQuery/ParseLiveQueryServer.js +560 -285
- package/lib/LiveQuery/ParsePubSub.js +7 -16
- package/lib/LiveQuery/ParseWebSocketServer.js +42 -39
- package/lib/LiveQuery/QueryTools.js +76 -15
- package/lib/LiveQuery/RequestSchema.js +111 -97
- package/lib/LiveQuery/SessionTokenCache.js +23 -36
- package/lib/LiveQuery/Subscription.js +8 -17
- package/lib/LiveQuery/equalObjects.js +2 -3
- package/lib/Options/Definitions.js +1355 -382
- package/lib/Options/docs.js +301 -62
- package/lib/Options/index.js +11 -1
- package/lib/Options/parsers.js +14 -10
- package/lib/Page.js +44 -0
- package/lib/ParseMessageQueue.js +6 -13
- package/lib/ParseServer.js +474 -235
- package/lib/ParseServerRESTController.js +102 -40
- package/lib/PromiseRouter.js +39 -50
- package/lib/Push/PushQueue.js +24 -30
- package/lib/Push/PushWorker.js +32 -56
- package/lib/Push/utils.js +22 -35
- package/lib/RestQuery.js +361 -139
- package/lib/RestWrite.js +713 -344
- package/lib/Routers/AggregateRouter.js +97 -71
- package/lib/Routers/AnalyticsRouter.js +8 -14
- package/lib/Routers/AudiencesRouter.js +16 -35
- package/lib/Routers/ClassesRouter.js +86 -72
- package/lib/Routers/CloudCodeRouter.js +28 -37
- package/lib/Routers/FeaturesRouter.js +22 -25
- package/lib/Routers/FilesRouter.js +266 -171
- package/lib/Routers/FunctionsRouter.js +87 -103
- package/lib/Routers/GlobalConfigRouter.js +94 -33
- package/lib/Routers/GraphQLRouter.js +41 -0
- package/lib/Routers/HooksRouter.js +43 -47
- package/lib/Routers/IAPValidationRouter.js +57 -70
- package/lib/Routers/InstallationsRouter.js +17 -25
- package/lib/Routers/LogsRouter.js +10 -25
- package/lib/Routers/PagesRouter.js +647 -0
- package/lib/Routers/PublicAPIRouter.js +104 -112
- package/lib/Routers/PurgeRouter.js +19 -29
- package/lib/Routers/PushRouter.js +14 -28
- package/lib/Routers/RolesRouter.js +7 -14
- package/lib/Routers/SchemasRouter.js +63 -42
- package/lib/Routers/SecurityRouter.js +34 -0
- package/lib/Routers/SessionsRouter.js +25 -38
- package/lib/Routers/UsersRouter.js +463 -190
- package/lib/SchemaMigrations/DefinedSchemas.js +379 -0
- package/lib/SchemaMigrations/Migrations.js +30 -0
- package/lib/Security/Check.js +109 -0
- package/lib/Security/CheckGroup.js +44 -0
- package/lib/Security/CheckGroups/CheckGroupDatabase.js +44 -0
- package/lib/Security/CheckGroups/CheckGroupServerConfig.js +96 -0
- package/lib/Security/CheckGroups/CheckGroups.js +21 -0
- package/lib/Security/CheckRunner.js +213 -0
- package/lib/SharedRest.js +29 -0
- package/lib/StatusHandler.js +96 -93
- package/lib/TestUtils.js +70 -14
- package/lib/Utils.js +468 -0
- package/lib/batch.js +74 -40
- package/lib/cache.js +8 -8
- package/lib/cli/definitions/parse-live-query-server.js +4 -3
- package/lib/cli/definitions/parse-server.js +4 -3
- package/lib/cli/parse-live-query-server.js +9 -17
- package/lib/cli/parse-server.js +49 -47
- package/lib/cli/utils/commander.js +20 -29
- package/lib/cli/utils/runner.js +31 -32
- package/lib/cloud-code/Parse.Cloud.js +711 -36
- package/lib/cloud-code/Parse.Server.js +21 -0
- package/lib/cryptoUtils.js +6 -11
- package/lib/defaults.js +21 -15
- package/lib/deprecated.js +1 -1
- package/lib/index.js +78 -67
- package/lib/logger.js +12 -20
- package/lib/middlewares.js +484 -160
- package/lib/password.js +10 -6
- package/lib/request.js +175 -0
- package/lib/requiredParameter.js +4 -3
- package/lib/rest.js +157 -82
- package/lib/triggers.js +627 -185
- package/lib/vendor/README.md +3 -3
- package/lib/vendor/mongodbUrl.js +224 -137
- package/package.json +135 -57
- package/postinstall.js +38 -50
- package/public_html/invalid_verification_link.html +3 -3
- package/types/@types/@parse/fs-files-adapter/index.d.ts +5 -0
- package/types/@types/deepcopy/index.d.ts +5 -0
- package/types/LiveQuery/ParseLiveQueryServer.d.ts +40 -0
- package/types/Options/index.d.ts +301 -0
- package/types/ParseServer.d.ts +65 -0
- package/types/eslint.config.mjs +30 -0
- package/types/index.d.ts +21 -0
- package/types/logger.d.ts +2 -0
- package/types/tests.ts +44 -0
- package/types/tsconfig.json +24 -0
- package/CHANGELOG.md +0 -1246
- package/PATENTS +0 -37
- package/bin/dev +0 -37
- package/lib/.DS_Store +0 -0
- package/lib/Adapters/Auth/common.js +0 -2
- package/lib/Adapters/Auth/facebookaccountkit.js +0 -69
- package/lib/Controllers/SchemaCache.js +0 -97
- package/lib/LiveQuery/.DS_Store +0 -0
- package/lib/cli/utils/parsers.js +0 -77
- package/lib/cloud-code/.DS_Store +0 -0
- package/lib/cloud-code/HTTPResponse.js +0 -57
- package/lib/cloud-code/Untitled-1 +0 -123
- package/lib/cloud-code/httpRequest.js +0 -102
- package/lib/cloud-code/team.html +0 -123
- package/lib/graphql/ParseClass.js +0 -234
- package/lib/graphql/Schema.js +0 -197
- package/lib/graphql/index.js +0 -1
- package/lib/graphql/types/ACL.js +0 -35
- package/lib/graphql/types/Date.js +0 -25
- package/lib/graphql/types/File.js +0 -24
- package/lib/graphql/types/GeoPoint.js +0 -35
- package/lib/graphql/types/JSONObject.js +0 -30
- package/lib/graphql/types/NumberInput.js +0 -43
- package/lib/graphql/types/NumberQuery.js +0 -42
- package/lib/graphql/types/Pointer.js +0 -35
- package/lib/graphql/types/QueryConstraint.js +0 -61
- package/lib/graphql/types/StringQuery.js +0 -39
- package/lib/graphql/types/index.js +0 -110
package/lib/Auth.js
CHANGED
|
@@ -1,16 +1,30 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
var _util = require("util");
|
|
4
|
+
var _triggers = require("./triggers");
|
|
5
|
+
var _logger = require("./logger");
|
|
6
|
+
var _lruCache = require("lru-cache");
|
|
7
|
+
var _RestQuery = _interopRequireDefault(require("./RestQuery"));
|
|
8
|
+
var _RestWrite = _interopRequireDefault(require("./RestWrite"));
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
5
10
|
const Parse = require('parse/node');
|
|
6
|
-
|
|
7
11
|
// An Auth object tells you who is requesting something and whether
|
|
8
12
|
// the master key was used.
|
|
9
13
|
// userObject is a Parse.User and can be null if there's no user.
|
|
10
|
-
function Auth({
|
|
14
|
+
function Auth({
|
|
15
|
+
config,
|
|
16
|
+
cacheController = undefined,
|
|
17
|
+
isMaster = false,
|
|
18
|
+
isMaintenance = false,
|
|
19
|
+
isReadOnly = false,
|
|
20
|
+
user,
|
|
21
|
+
installationId
|
|
22
|
+
}) {
|
|
11
23
|
this.config = config;
|
|
24
|
+
this.cacheController = cacheController || config && config.cacheController;
|
|
12
25
|
this.installationId = installationId;
|
|
13
26
|
this.isMaster = isMaster;
|
|
27
|
+
this.isMaintenance = isMaintenance;
|
|
14
28
|
this.user = user;
|
|
15
29
|
this.isReadOnly = isReadOnly;
|
|
16
30
|
|
|
@@ -27,6 +41,9 @@ Auth.prototype.isUnauthenticated = function () {
|
|
|
27
41
|
if (this.isMaster) {
|
|
28
42
|
return false;
|
|
29
43
|
}
|
|
44
|
+
if (this.isMaintenance) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
30
47
|
if (this.user) {
|
|
31
48
|
return false;
|
|
32
49
|
}
|
|
@@ -35,60 +52,200 @@ Auth.prototype.isUnauthenticated = function () {
|
|
|
35
52
|
|
|
36
53
|
// A helper to get a master-level Auth object
|
|
37
54
|
function master(config) {
|
|
38
|
-
return new Auth({
|
|
55
|
+
return new Auth({
|
|
56
|
+
config,
|
|
57
|
+
isMaster: true
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// A helper to get a maintenance-level Auth object
|
|
62
|
+
function maintenance(config) {
|
|
63
|
+
return new Auth({
|
|
64
|
+
config,
|
|
65
|
+
isMaintenance: true
|
|
66
|
+
});
|
|
39
67
|
}
|
|
40
68
|
|
|
41
69
|
// A helper to get a master-level Auth object
|
|
42
70
|
function readOnly(config) {
|
|
43
|
-
return new Auth({
|
|
71
|
+
return new Auth({
|
|
72
|
+
config,
|
|
73
|
+
isMaster: true,
|
|
74
|
+
isReadOnly: true
|
|
75
|
+
});
|
|
44
76
|
}
|
|
45
77
|
|
|
46
78
|
// A helper to get a nobody-level Auth object
|
|
47
79
|
function nobody(config) {
|
|
48
|
-
return new Auth({
|
|
80
|
+
return new Auth({
|
|
81
|
+
config,
|
|
82
|
+
isMaster: false
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
const throttle = new _lruCache.LRUCache({
|
|
86
|
+
max: 10000,
|
|
87
|
+
ttl: 500
|
|
88
|
+
});
|
|
89
|
+
/**
|
|
90
|
+
* Checks whether session should be updated based on last update time & session length.
|
|
91
|
+
*/
|
|
92
|
+
function shouldUpdateSessionExpiry(config, session) {
|
|
93
|
+
const resetAfter = config.sessionLength / 2;
|
|
94
|
+
const lastUpdated = new Date(session?.updatedAt);
|
|
95
|
+
const skipRange = new Date();
|
|
96
|
+
skipRange.setTime(skipRange.getTime() - resetAfter * 1000);
|
|
97
|
+
return lastUpdated <= skipRange;
|
|
49
98
|
}
|
|
99
|
+
const renewSessionIfNeeded = async ({
|
|
100
|
+
config,
|
|
101
|
+
session,
|
|
102
|
+
sessionToken
|
|
103
|
+
}) => {
|
|
104
|
+
if (!config?.extendSessionOnUse) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (throttle.get(sessionToken)) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
throttle.set(sessionToken, true);
|
|
111
|
+
try {
|
|
112
|
+
if (!session) {
|
|
113
|
+
const query = await (0, _RestQuery.default)({
|
|
114
|
+
method: _RestQuery.default.Method.get,
|
|
115
|
+
config,
|
|
116
|
+
auth: master(config),
|
|
117
|
+
runBeforeFind: false,
|
|
118
|
+
className: '_Session',
|
|
119
|
+
restWhere: {
|
|
120
|
+
sessionToken
|
|
121
|
+
},
|
|
122
|
+
restOptions: {
|
|
123
|
+
limit: 1
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
const {
|
|
127
|
+
results
|
|
128
|
+
} = await query.execute();
|
|
129
|
+
session = results[0];
|
|
130
|
+
}
|
|
131
|
+
if (!shouldUpdateSessionExpiry(config, session) || !session) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const expiresAt = config.generateSessionExpiresAt();
|
|
135
|
+
await new _RestWrite.default(config, master(config), '_Session', {
|
|
136
|
+
objectId: session.objectId
|
|
137
|
+
}, {
|
|
138
|
+
expiresAt: Parse._encode(expiresAt)
|
|
139
|
+
}).execute();
|
|
140
|
+
} catch (e) {
|
|
141
|
+
if (e?.code !== Parse.Error.OBJECT_NOT_FOUND) {
|
|
142
|
+
_logger.logger.error('Could not update session expiry: ', e);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
};
|
|
50
146
|
|
|
51
147
|
// Returns a promise that resolves to an Auth object
|
|
52
|
-
|
|
53
|
-
|
|
148
|
+
const getAuthForSessionToken = async function ({
|
|
149
|
+
config,
|
|
150
|
+
cacheController,
|
|
151
|
+
sessionToken,
|
|
152
|
+
installationId
|
|
153
|
+
}) {
|
|
154
|
+
cacheController = cacheController || config && config.cacheController;
|
|
155
|
+
if (cacheController) {
|
|
156
|
+
const userJSON = await cacheController.user.get(sessionToken);
|
|
54
157
|
if (userJSON) {
|
|
55
158
|
const cachedUser = Parse.Object.fromJSON(userJSON);
|
|
56
|
-
|
|
159
|
+
renewSessionIfNeeded({
|
|
160
|
+
config,
|
|
161
|
+
sessionToken
|
|
162
|
+
});
|
|
163
|
+
return Promise.resolve(new Auth({
|
|
164
|
+
config,
|
|
165
|
+
cacheController,
|
|
166
|
+
isMaster: false,
|
|
167
|
+
installationId,
|
|
168
|
+
user: cachedUser
|
|
169
|
+
}));
|
|
57
170
|
}
|
|
58
|
-
|
|
59
|
-
|
|
171
|
+
}
|
|
172
|
+
let results;
|
|
173
|
+
if (config) {
|
|
174
|
+
const restOptions = {
|
|
60
175
|
limit: 1,
|
|
61
176
|
include: 'user'
|
|
62
177
|
};
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Session token is expired.');
|
|
75
|
-
}
|
|
76
|
-
var obj = results[0]['user'];
|
|
77
|
-
delete obj.password;
|
|
78
|
-
obj['className'] = '_User';
|
|
79
|
-
obj['sessionToken'] = sessionToken;
|
|
80
|
-
config.cacheController.user.put(sessionToken, obj);
|
|
81
|
-
const userObject = Parse.Object.fromJSON(obj);
|
|
82
|
-
return new Auth({ config, isMaster: false, installationId, user: userObject });
|
|
178
|
+
const RestQuery = require('./RestQuery');
|
|
179
|
+
const query = await RestQuery({
|
|
180
|
+
method: RestQuery.Method.get,
|
|
181
|
+
config,
|
|
182
|
+
runBeforeFind: false,
|
|
183
|
+
auth: master(config),
|
|
184
|
+
className: '_Session',
|
|
185
|
+
restWhere: {
|
|
186
|
+
sessionToken
|
|
187
|
+
},
|
|
188
|
+
restOptions
|
|
83
189
|
});
|
|
190
|
+
results = (await query.execute()).results;
|
|
191
|
+
} else {
|
|
192
|
+
results = (await new Parse.Query(Parse.Session).limit(1).include('user').equalTo('sessionToken', sessionToken).find({
|
|
193
|
+
useMasterKey: true
|
|
194
|
+
})).map(obj => obj.toJSON());
|
|
195
|
+
}
|
|
196
|
+
if (results.length !== 1 || !results[0]['user']) {
|
|
197
|
+
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Invalid session token');
|
|
198
|
+
}
|
|
199
|
+
const session = results[0];
|
|
200
|
+
const now = new Date(),
|
|
201
|
+
expiresAt = session.expiresAt ? new Date(session.expiresAt.iso) : undefined;
|
|
202
|
+
if (expiresAt < now) {
|
|
203
|
+
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Session token is expired.');
|
|
204
|
+
}
|
|
205
|
+
const obj = session.user;
|
|
206
|
+
if (typeof obj['objectId'] === 'string' && obj['objectId'].startsWith('role:')) {
|
|
207
|
+
throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Invalid object ID.');
|
|
208
|
+
}
|
|
209
|
+
delete obj.password;
|
|
210
|
+
obj['className'] = '_User';
|
|
211
|
+
obj['sessionToken'] = sessionToken;
|
|
212
|
+
if (cacheController) {
|
|
213
|
+
cacheController.user.put(sessionToken, obj);
|
|
214
|
+
}
|
|
215
|
+
renewSessionIfNeeded({
|
|
216
|
+
config,
|
|
217
|
+
session,
|
|
218
|
+
sessionToken
|
|
219
|
+
});
|
|
220
|
+
const userObject = Parse.Object.fromJSON(obj);
|
|
221
|
+
return new Auth({
|
|
222
|
+
config,
|
|
223
|
+
cacheController,
|
|
224
|
+
isMaster: false,
|
|
225
|
+
installationId,
|
|
226
|
+
user: userObject
|
|
84
227
|
});
|
|
85
228
|
};
|
|
86
|
-
|
|
87
|
-
|
|
229
|
+
var getAuthForLegacySessionToken = async function ({
|
|
230
|
+
config,
|
|
231
|
+
sessionToken,
|
|
232
|
+
installationId
|
|
233
|
+
}) {
|
|
88
234
|
var restOptions = {
|
|
89
235
|
limit: 1
|
|
90
236
|
};
|
|
91
|
-
|
|
237
|
+
const RestQuery = require('./RestQuery');
|
|
238
|
+
var query = await RestQuery({
|
|
239
|
+
method: RestQuery.Method.get,
|
|
240
|
+
config,
|
|
241
|
+
runBeforeFind: false,
|
|
242
|
+
auth: master(config),
|
|
243
|
+
className: '_User',
|
|
244
|
+
restWhere: {
|
|
245
|
+
_session_token: sessionToken
|
|
246
|
+
},
|
|
247
|
+
restOptions
|
|
248
|
+
});
|
|
92
249
|
return query.execute().then(response => {
|
|
93
250
|
var results = response.results;
|
|
94
251
|
if (results.length !== 1) {
|
|
@@ -97,13 +254,18 @@ var getAuthForLegacySessionToken = function ({ config, sessionToken, installatio
|
|
|
97
254
|
const obj = results[0];
|
|
98
255
|
obj.className = '_User';
|
|
99
256
|
const userObject = Parse.Object.fromJSON(obj);
|
|
100
|
-
return new Auth({
|
|
257
|
+
return new Auth({
|
|
258
|
+
config,
|
|
259
|
+
isMaster: false,
|
|
260
|
+
installationId,
|
|
261
|
+
user: userObject
|
|
262
|
+
});
|
|
101
263
|
});
|
|
102
264
|
};
|
|
103
265
|
|
|
104
266
|
// Returns a promise that resolves to an array of role names
|
|
105
267
|
Auth.prototype.getUserRoles = function () {
|
|
106
|
-
if (this.isMaster || !this.user) {
|
|
268
|
+
if (this.isMaster || this.isMaintenance || !this.user) {
|
|
107
269
|
return Promise.resolve([]);
|
|
108
270
|
}
|
|
109
271
|
if (this.fetchedRoles) {
|
|
@@ -115,84 +277,140 @@ Auth.prototype.getUserRoles = function () {
|
|
|
115
277
|
this.rolePromise = this._loadRoles();
|
|
116
278
|
return this.rolePromise;
|
|
117
279
|
};
|
|
280
|
+
Auth.prototype.getRolesForUser = async function () {
|
|
281
|
+
//Stack all Parse.Role
|
|
282
|
+
const results = [];
|
|
283
|
+
if (this.config) {
|
|
284
|
+
const restWhere = {
|
|
285
|
+
users: {
|
|
286
|
+
__type: 'Pointer',
|
|
287
|
+
className: '_User',
|
|
288
|
+
objectId: this.user.id
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
const RestQuery = require('./RestQuery');
|
|
292
|
+
const query = await RestQuery({
|
|
293
|
+
method: RestQuery.Method.find,
|
|
294
|
+
runBeforeFind: false,
|
|
295
|
+
config: this.config,
|
|
296
|
+
auth: master(this.config),
|
|
297
|
+
className: '_Role',
|
|
298
|
+
restWhere
|
|
299
|
+
});
|
|
300
|
+
await query.each(result => results.push(result));
|
|
301
|
+
} else {
|
|
302
|
+
await new Parse.Query(Parse.Role).equalTo('users', this.user).each(result => results.push(result.toJSON()), {
|
|
303
|
+
useMasterKey: true
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
return results;
|
|
307
|
+
};
|
|
118
308
|
|
|
119
|
-
// Iterates through the role tree and compiles a
|
|
120
|
-
Auth.prototype._loadRoles = function () {
|
|
121
|
-
|
|
122
|
-
|
|
309
|
+
// Iterates through the role tree and compiles a user's roles
|
|
310
|
+
Auth.prototype._loadRoles = async function () {
|
|
311
|
+
if (this.cacheController) {
|
|
312
|
+
const cachedRoles = await this.cacheController.role.get(this.user.id);
|
|
123
313
|
if (cachedRoles != null) {
|
|
124
314
|
this.fetchedRoles = true;
|
|
125
315
|
this.userRoles = cachedRoles;
|
|
126
|
-
return
|
|
316
|
+
return cachedRoles;
|
|
127
317
|
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// First get the role ids this user is directly a member of
|
|
321
|
+
const results = await this.getRolesForUser();
|
|
322
|
+
if (!results.length) {
|
|
323
|
+
this.userRoles = [];
|
|
324
|
+
this.fetchedRoles = true;
|
|
325
|
+
this.rolePromise = null;
|
|
326
|
+
this.cacheRoles();
|
|
327
|
+
return this.userRoles;
|
|
328
|
+
}
|
|
329
|
+
const rolesMap = results.reduce((m, r) => {
|
|
330
|
+
m.names.push(r.name);
|
|
331
|
+
m.ids.push(r.objectId);
|
|
332
|
+
return m;
|
|
333
|
+
}, {
|
|
334
|
+
ids: [],
|
|
335
|
+
names: []
|
|
336
|
+
});
|
|
128
337
|
|
|
129
|
-
|
|
130
|
-
|
|
338
|
+
// run the recursive finding
|
|
339
|
+
const roleNames = await this._getAllRolesNamesForRoleIds(rolesMap.ids, rolesMap.names);
|
|
340
|
+
this.userRoles = roleNames.map(r => {
|
|
341
|
+
return 'role:' + r;
|
|
342
|
+
});
|
|
343
|
+
this.fetchedRoles = true;
|
|
344
|
+
this.rolePromise = null;
|
|
345
|
+
this.cacheRoles();
|
|
346
|
+
return this.userRoles;
|
|
347
|
+
};
|
|
348
|
+
Auth.prototype.cacheRoles = function () {
|
|
349
|
+
if (!this.cacheController) {
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
this.cacheController.role.put(this.user.id, Array(...this.userRoles));
|
|
353
|
+
return true;
|
|
354
|
+
};
|
|
355
|
+
Auth.prototype.clearRoleCache = function (sessionToken) {
|
|
356
|
+
if (!this.cacheController) {
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
359
|
+
this.cacheController.role.del(this.user.id);
|
|
360
|
+
this.cacheController.user.del(sessionToken);
|
|
361
|
+
return true;
|
|
362
|
+
};
|
|
363
|
+
Auth.prototype.getRolesByIds = async function (ins) {
|
|
364
|
+
const results = [];
|
|
365
|
+
// Build an OR query across all parentRoles
|
|
366
|
+
if (!this.config) {
|
|
367
|
+
await new Parse.Query(Parse.Role).containedIn('roles', ins.map(id => {
|
|
368
|
+
const role = new Parse.Object(Parse.Role);
|
|
369
|
+
role.id = id;
|
|
370
|
+
return role;
|
|
371
|
+
})).each(result => results.push(result.toJSON()), {
|
|
372
|
+
useMasterKey: true
|
|
373
|
+
});
|
|
374
|
+
} else {
|
|
375
|
+
const roles = ins.map(id => {
|
|
376
|
+
return {
|
|
131
377
|
__type: 'Pointer',
|
|
132
|
-
className: '
|
|
133
|
-
objectId:
|
|
378
|
+
className: '_Role',
|
|
379
|
+
objectId: id
|
|
380
|
+
};
|
|
381
|
+
});
|
|
382
|
+
const restWhere = {
|
|
383
|
+
roles: {
|
|
384
|
+
$in: roles
|
|
134
385
|
}
|
|
135
386
|
};
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
cacheAdapter.role.put(this.user.id, Array(...this.userRoles));
|
|
146
|
-
return Promise.resolve(this.userRoles);
|
|
147
|
-
}
|
|
148
|
-
var rolesMap = results.reduce((m, r) => {
|
|
149
|
-
m.names.push(r.name);
|
|
150
|
-
m.ids.push(r.objectId);
|
|
151
|
-
return m;
|
|
152
|
-
}, { ids: [], names: [] });
|
|
153
|
-
|
|
154
|
-
// run the recursive finding
|
|
155
|
-
return this._getAllRolesNamesForRoleIds(rolesMap.ids, rolesMap.names).then(roleNames => {
|
|
156
|
-
this.userRoles = roleNames.map(r => {
|
|
157
|
-
return 'role:' + r;
|
|
158
|
-
});
|
|
159
|
-
this.fetchedRoles = true;
|
|
160
|
-
this.rolePromise = null;
|
|
161
|
-
cacheAdapter.role.put(this.user.id, Array(...this.userRoles));
|
|
162
|
-
return Promise.resolve(this.userRoles);
|
|
163
|
-
});
|
|
387
|
+
const RestQuery = require('./RestQuery');
|
|
388
|
+
const query = await RestQuery({
|
|
389
|
+
method: RestQuery.Method.find,
|
|
390
|
+
config: this.config,
|
|
391
|
+
runBeforeFind: false,
|
|
392
|
+
auth: master(this.config),
|
|
393
|
+
className: '_Role',
|
|
394
|
+
restWhere
|
|
164
395
|
});
|
|
165
|
-
|
|
396
|
+
await query.each(result => results.push(result));
|
|
397
|
+
}
|
|
398
|
+
return results;
|
|
166
399
|
};
|
|
167
400
|
|
|
168
401
|
// Given a list of roleIds, find all the parent roles, returns a promise with all names
|
|
169
402
|
Auth.prototype._getAllRolesNamesForRoleIds = function (roleIDs, names = [], queriedRoles = {}) {
|
|
170
403
|
const ins = roleIDs.filter(roleID => {
|
|
171
|
-
|
|
172
|
-
}).map(roleID => {
|
|
173
|
-
// mark as queried
|
|
404
|
+
const wasQueried = queriedRoles[roleID] !== true;
|
|
174
405
|
queriedRoles[roleID] = true;
|
|
175
|
-
return
|
|
176
|
-
__type: 'Pointer',
|
|
177
|
-
className: '_Role',
|
|
178
|
-
objectId: roleID
|
|
179
|
-
};
|
|
406
|
+
return wasQueried;
|
|
180
407
|
});
|
|
181
408
|
|
|
182
409
|
// all roles are accounted for, return the names
|
|
183
410
|
if (ins.length == 0) {
|
|
184
411
|
return Promise.resolve([...new Set(names)]);
|
|
185
412
|
}
|
|
186
|
-
|
|
187
|
-
let restWhere;
|
|
188
|
-
if (ins.length == 1) {
|
|
189
|
-
restWhere = { 'roles': ins[0] };
|
|
190
|
-
} else {
|
|
191
|
-
restWhere = { 'roles': { '$in': ins } };
|
|
192
|
-
}
|
|
193
|
-
const query = new RestQuery(this.config, master(this.config), '_Role', restWhere, {});
|
|
194
|
-
return query.execute().then(response => {
|
|
195
|
-
var results = response.results;
|
|
413
|
+
return this.getRolesByIds(ins).then(results => {
|
|
196
414
|
// Nothing found
|
|
197
415
|
if (!results.length) {
|
|
198
416
|
return Promise.resolve(names);
|
|
@@ -202,7 +420,10 @@ Auth.prototype._getAllRolesNamesForRoleIds = function (roleIDs, names = [], quer
|
|
|
202
420
|
memo.names.push(role.name);
|
|
203
421
|
memo.ids.push(role.objectId);
|
|
204
422
|
return memo;
|
|
205
|
-
}, {
|
|
423
|
+
}, {
|
|
424
|
+
ids: [],
|
|
425
|
+
names: []
|
|
426
|
+
});
|
|
206
427
|
// store the new found names
|
|
207
428
|
names = names.concat(resultMap.names);
|
|
208
429
|
// find the next ones, circular roles will be cut
|
|
@@ -211,48 +432,190 @@ Auth.prototype._getAllRolesNamesForRoleIds = function (roleIDs, names = [], quer
|
|
|
211
432
|
return Promise.resolve([...new Set(names)]);
|
|
212
433
|
});
|
|
213
434
|
};
|
|
435
|
+
const findUsersWithAuthData = async (config, authData, beforeFind) => {
|
|
436
|
+
const providers = Object.keys(authData);
|
|
437
|
+
const queries = await Promise.all(providers.map(async provider => {
|
|
438
|
+
const providerAuthData = authData[provider];
|
|
439
|
+
const adapter = config.authDataManager.getValidatorForProvider(provider)?.adapter;
|
|
440
|
+
if (beforeFind && typeof adapter?.beforeFind === 'function') {
|
|
441
|
+
await adapter.beforeFind(providerAuthData);
|
|
442
|
+
}
|
|
443
|
+
if (!providerAuthData?.id) {
|
|
444
|
+
return null;
|
|
445
|
+
}
|
|
446
|
+
return {
|
|
447
|
+
[`authData.${provider}.id`]: providerAuthData.id
|
|
448
|
+
};
|
|
449
|
+
}));
|
|
214
450
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
additionalSessionData
|
|
220
|
-
}) {
|
|
221
|
-
const token = 'r:' + cryptoUtils.newToken();
|
|
222
|
-
const expiresAt = config.generateSessionExpiresAt();
|
|
223
|
-
const sessionData = {
|
|
224
|
-
sessionToken: token,
|
|
225
|
-
user: {
|
|
226
|
-
__type: 'Pointer',
|
|
227
|
-
className: '_User',
|
|
228
|
-
objectId: userId
|
|
229
|
-
},
|
|
230
|
-
createdWith,
|
|
231
|
-
restricted: false,
|
|
232
|
-
expiresAt: Parse._encode(expiresAt)
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
if (installationId) {
|
|
236
|
-
sessionData.installationId = installationId;
|
|
451
|
+
// Filter out null queries
|
|
452
|
+
const validQueries = queries.filter(query => query !== null);
|
|
453
|
+
if (!validQueries.length) {
|
|
454
|
+
return [];
|
|
237
455
|
}
|
|
238
456
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
457
|
+
// Perform database query
|
|
458
|
+
return config.database.find('_User', {
|
|
459
|
+
$or: validQueries
|
|
460
|
+
}, {
|
|
461
|
+
limit: 2
|
|
462
|
+
});
|
|
463
|
+
};
|
|
464
|
+
const hasMutatedAuthData = (authData, userAuthData) => {
|
|
465
|
+
if (!userAuthData) {
|
|
466
|
+
return {
|
|
467
|
+
hasMutatedAuthData: true,
|
|
468
|
+
mutatedAuthData: authData
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
const mutatedAuthData = {};
|
|
472
|
+
Object.keys(authData).forEach(provider => {
|
|
473
|
+
// Anonymous provider is not handled this way
|
|
474
|
+
if (provider === 'anonymous') {
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
const providerData = authData[provider];
|
|
478
|
+
const userProviderAuthData = userAuthData[provider];
|
|
479
|
+
if (!(0, _util.isDeepStrictEqual)(providerData, userProviderAuthData)) {
|
|
480
|
+
mutatedAuthData[provider] = providerData;
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
const hasMutatedAuthData = Object.keys(mutatedAuthData).length !== 0;
|
|
243
484
|
return {
|
|
244
|
-
|
|
245
|
-
|
|
485
|
+
hasMutatedAuthData,
|
|
486
|
+
mutatedAuthData
|
|
246
487
|
};
|
|
247
488
|
};
|
|
489
|
+
const checkIfUserHasProvidedConfiguredProvidersForLogin = (req = {}, authData = {}, userAuthData = {}, config) => {
|
|
490
|
+
const savedUserProviders = Object.keys(userAuthData).map(provider => ({
|
|
491
|
+
name: provider,
|
|
492
|
+
adapter: config.authDataManager.getValidatorForProvider(provider).adapter
|
|
493
|
+
}));
|
|
494
|
+
const hasProvidedASoloProvider = savedUserProviders.some(provider => provider && provider.adapter && provider.adapter.policy === 'solo' && authData[provider.name]);
|
|
495
|
+
|
|
496
|
+
// Solo providers can be considered as safe, so we do not have to check if the user needs
|
|
497
|
+
// to provide an additional provider to login. An auth adapter with "solo" (like webauthn) means
|
|
498
|
+
// no "additional" auth needs to be provided to login (like OTP, MFA)
|
|
499
|
+
if (hasProvidedASoloProvider) {
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
const additionProvidersNotFound = [];
|
|
503
|
+
const hasProvidedAtLeastOneAdditionalProvider = savedUserProviders.some(provider => {
|
|
504
|
+
let policy = provider.adapter.policy;
|
|
505
|
+
if (typeof policy === 'function') {
|
|
506
|
+
const requestObject = {
|
|
507
|
+
ip: req.config.ip,
|
|
508
|
+
user: req.auth.user,
|
|
509
|
+
master: req.auth.isMaster
|
|
510
|
+
};
|
|
511
|
+
policy = policy.call(provider.adapter, requestObject, userAuthData[provider.name]);
|
|
512
|
+
}
|
|
513
|
+
if (policy === 'additional') {
|
|
514
|
+
if (authData[provider.name]) {
|
|
515
|
+
return true;
|
|
516
|
+
} else {
|
|
517
|
+
// Push missing provider for error message
|
|
518
|
+
additionProvidersNotFound.push(provider.name);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
if (hasProvidedAtLeastOneAdditionalProvider || !additionProvidersNotFound.length) {
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
throw new Parse.Error(Parse.Error.OTHER_CAUSE, `Missing additional authData ${additionProvidersNotFound.join(',')}`);
|
|
526
|
+
};
|
|
248
527
|
|
|
528
|
+
// Validate each authData step-by-step and return the provider responses
|
|
529
|
+
const handleAuthDataValidation = async (authData, req, foundUser) => {
|
|
530
|
+
let user;
|
|
531
|
+
if (foundUser) {
|
|
532
|
+
user = Parse.User.fromJSON({
|
|
533
|
+
className: '_User',
|
|
534
|
+
...foundUser
|
|
535
|
+
});
|
|
536
|
+
// Find user by session and current objectId; only pass user if it's the current user or master key is provided
|
|
537
|
+
} else if (req.auth && req.auth.user && typeof req.getUserId === 'function' && req.getUserId() === req.auth.user.id || req.auth && req.auth.isMaster && typeof req.getUserId === 'function' && req.getUserId()) {
|
|
538
|
+
user = new Parse.User();
|
|
539
|
+
user.id = req.auth.isMaster ? req.getUserId() : req.auth.user.id;
|
|
540
|
+
await user.fetch({
|
|
541
|
+
useMasterKey: true
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
const {
|
|
545
|
+
updatedObject
|
|
546
|
+
} = req.buildParseObjects();
|
|
547
|
+
const requestObject = (0, _triggers.getRequestObject)(undefined, req.auth, updatedObject, user, req.config);
|
|
548
|
+
// Perform validation as step-by-step pipeline for better error consistency
|
|
549
|
+
// and also to avoid to trigger a provider (like OTP SMS) if another one fails
|
|
550
|
+
const acc = {
|
|
551
|
+
authData: {},
|
|
552
|
+
authDataResponse: {}
|
|
553
|
+
};
|
|
554
|
+
const authKeys = Object.keys(authData).sort();
|
|
555
|
+
for (const provider of authKeys) {
|
|
556
|
+
let method = '';
|
|
557
|
+
try {
|
|
558
|
+
if (authData[provider] === null) {
|
|
559
|
+
acc.authData[provider] = null;
|
|
560
|
+
continue;
|
|
561
|
+
}
|
|
562
|
+
const {
|
|
563
|
+
validator
|
|
564
|
+
} = req.config.authDataManager.getValidatorForProvider(provider) || {};
|
|
565
|
+
const authProvider = (req.config.auth || {})[provider] || {};
|
|
566
|
+
if (!validator || authProvider.enabled === false) {
|
|
567
|
+
throw new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE, 'This authentication method is unsupported.');
|
|
568
|
+
}
|
|
569
|
+
let validationResult = await validator(authData[provider], req, user, requestObject);
|
|
570
|
+
method = validationResult && validationResult.method;
|
|
571
|
+
requestObject.triggerName = method;
|
|
572
|
+
if (validationResult && validationResult.validator) {
|
|
573
|
+
validationResult = await validationResult.validator();
|
|
574
|
+
}
|
|
575
|
+
if (!validationResult) {
|
|
576
|
+
acc.authData[provider] = authData[provider];
|
|
577
|
+
continue;
|
|
578
|
+
}
|
|
579
|
+
if (!Object.keys(validationResult).length) {
|
|
580
|
+
acc.authData[provider] = authData[provider];
|
|
581
|
+
continue;
|
|
582
|
+
}
|
|
583
|
+
if (validationResult.response) {
|
|
584
|
+
acc.authDataResponse[provider] = validationResult.response;
|
|
585
|
+
}
|
|
586
|
+
// Some auth providers after initialization will avoid to replace authData already stored
|
|
587
|
+
if (!validationResult.doNotSave) {
|
|
588
|
+
acc.authData[provider] = validationResult.save || authData[provider];
|
|
589
|
+
}
|
|
590
|
+
} catch (err) {
|
|
591
|
+
const e = (0, _triggers.resolveError)(err, {
|
|
592
|
+
code: Parse.Error.SCRIPT_FAILED,
|
|
593
|
+
message: 'Auth failed. Unknown error.'
|
|
594
|
+
});
|
|
595
|
+
const userString = req.auth && req.auth.user ? req.auth.user.id : req.data.objectId || undefined;
|
|
596
|
+
_logger.logger.error(`Failed running auth step ${method} for ${provider} for user ${userString} with Error: ` + JSON.stringify(e), {
|
|
597
|
+
authenticationStep: method,
|
|
598
|
+
error: e,
|
|
599
|
+
user: userString,
|
|
600
|
+
provider
|
|
601
|
+
});
|
|
602
|
+
throw e;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
return acc;
|
|
606
|
+
};
|
|
249
607
|
module.exports = {
|
|
250
608
|
Auth,
|
|
251
609
|
master,
|
|
610
|
+
maintenance,
|
|
252
611
|
nobody,
|
|
253
612
|
readOnly,
|
|
613
|
+
shouldUpdateSessionExpiry,
|
|
254
614
|
getAuthForSessionToken,
|
|
255
615
|
getAuthForLegacySessionToken,
|
|
256
|
-
|
|
616
|
+
findUsersWithAuthData,
|
|
617
|
+
hasMutatedAuthData,
|
|
618
|
+
checkIfUserHasProvidedConfiguredProvidersForLogin,
|
|
619
|
+
handleAuthDataValidation
|
|
257
620
|
};
|
|
258
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9BdXRoLmpzIl0sIm5hbWVzIjpbImNyeXB0b1V0aWxzIiwicmVxdWlyZSIsIlJlc3RRdWVyeSIsIlBhcnNlIiwiQXV0aCIsImNvbmZpZyIsImlzTWFzdGVyIiwiaXNSZWFkT25seSIsInVzZXIiLCJpbnN0YWxsYXRpb25JZCIsInVzZXJSb2xlcyIsImZldGNoZWRSb2xlcyIsInJvbGVQcm9taXNlIiwicHJvdG90eXBlIiwiaXNVbmF1dGhlbnRpY2F0ZWQiLCJtYXN0ZXIiLCJyZWFkT25seSIsIm5vYm9keSIsImdldEF1dGhGb3JTZXNzaW9uVG9rZW4iLCJzZXNzaW9uVG9rZW4iLCJjYWNoZUNvbnRyb2xsZXIiLCJnZXQiLCJ0aGVuIiwidXNlckpTT04iLCJjYWNoZWRVc2VyIiwiT2JqZWN0IiwiZnJvbUpTT04iLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlc3RPcHRpb25zIiwibGltaXQiLCJpbmNsdWRlIiwicXVlcnkiLCJleGVjdXRlIiwicmVzcG9uc2UiLCJyZXN1bHRzIiwibGVuZ3RoIiwiRXJyb3IiLCJJTlZBTElEX1NFU1NJT05fVE9LRU4iLCJub3ciLCJEYXRlIiwiZXhwaXJlc0F0IiwiaXNvIiwidW5kZWZpbmVkIiwib2JqIiwicGFzc3dvcmQiLCJwdXQiLCJ1c2VyT2JqZWN0IiwiZ2V0QXV0aEZvckxlZ2FjeVNlc3Npb25Ub2tlbiIsImNsYXNzTmFtZSIsImdldFVzZXJSb2xlcyIsIl9sb2FkUm9sZXMiLCJjYWNoZUFkYXB0ZXIiLCJyb2xlIiwiaWQiLCJjYWNoZWRSb2xlcyIsInJlc3RXaGVyZSIsIl9fdHlwZSIsIm9iamVjdElkIiwiQXJyYXkiLCJyb2xlc01hcCIsInJlZHVjZSIsIm0iLCJyIiwibmFtZXMiLCJwdXNoIiwibmFtZSIsImlkcyIsIl9nZXRBbGxSb2xlc05hbWVzRm9yUm9sZUlkcyIsInJvbGVOYW1lcyIsIm1hcCIsInJvbGVJRHMiLCJxdWVyaWVkUm9sZXMiLCJpbnMiLCJmaWx0ZXIiLCJyb2xlSUQiLCJTZXQiLCJyZXN1bHRNYXAiLCJtZW1vIiwiY29uY2F0IiwiY3JlYXRlU2Vzc2lvbiIsInVzZXJJZCIsImNyZWF0ZWRXaXRoIiwiYWRkaXRpb25hbFNlc3Npb25EYXRhIiwidG9rZW4iLCJuZXdUb2tlbiIsImdlbmVyYXRlU2Vzc2lvbkV4cGlyZXNBdCIsInNlc3Npb25EYXRhIiwicmVzdHJpY3RlZCIsIl9lbmNvZGUiLCJhc3NpZ24iLCJSZXN0V3JpdGUiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBLE1BQU1BLGNBQWNDLFFBQVEsZUFBUixDQUFwQjtBQUNBLE1BQU1DLFlBQVlELFFBQVEsYUFBUixDQUFsQjtBQUNBLE1BQU1FLFFBQVFGLFFBQVEsWUFBUixDQUFkOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVNHLElBQVQsQ0FBYyxFQUFFQyxNQUFGLEVBQVVDLFdBQVcsS0FBckIsRUFBNEJDLGFBQWEsS0FBekMsRUFBZ0RDLElBQWhELEVBQXNEQyxjQUF0RCxLQUF5RSxFQUF2RixFQUEyRjtBQUN6RixPQUFLSixNQUFMLEdBQWNBLE1BQWQ7QUFDQSxPQUFLSSxjQUFMLEdBQXNCQSxjQUF0QjtBQUNBLE9BQUtILFFBQUwsR0FBZ0JBLFFBQWhCO0FBQ0EsT0FBS0UsSUFBTCxHQUFZQSxJQUFaO0FBQ0EsT0FBS0QsVUFBTCxHQUFrQkEsVUFBbEI7O0FBRUE7QUFDQTtBQUNBLE9BQUtHLFNBQUwsR0FBaUIsRUFBakI7QUFDQSxPQUFLQyxZQUFMLEdBQW9CLEtBQXBCO0FBQ0EsT0FBS0MsV0FBTCxHQUFtQixJQUFuQjtBQUNEOztBQUVEO0FBQ0E7QUFDQVIsS0FBS1MsU0FBTCxDQUFlQyxpQkFBZixHQUFtQyxZQUFXO0FBQzVDLE1BQUksS0FBS1IsUUFBVCxFQUFtQjtBQUNqQixXQUFPLEtBQVA7QUFDRDtBQUNELE1BQUksS0FBS0UsSUFBVCxFQUFlO0FBQ2IsV0FBTyxLQUFQO0FBQ0Q7QUFDRCxTQUFPLElBQVA7QUFDRCxDQVJEOztBQVVBO0FBQ0EsU0FBU08sTUFBVCxDQUFnQlYsTUFBaEIs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RGdCLFNBQU9pRSxNQUFQLENBQWNILFdBQWQsRUFBMkJKLHFCQUEzQjtBQUNBO0FBQ0EsUUFBTVEsWUFBWTFGLFFBQVEsYUFBUixDQUFsQjs7QUFFQSxTQUFPO0FBQ0xzRixlQURLO0FBRUxQLG1CQUFlLE1BQU0sSUFBSVcsU0FBSixDQUFjdEYsTUFBZCxFQUFzQlUsT0FBT1YsTUFBUCxDQUF0QixFQUFzQyxVQUF0QyxFQUFrRCxJQUFsRCxFQUF3RGtGLFdBQXhELEVBQXFFdEQsT0FBckU7QUFGaEIsR0FBUDtBQUlELENBaENEOztBQWtDQTJELE9BQU9DLE9BQVAsR0FBaUI7QUFDZnpGLE1BRGU7QUFFZlcsUUFGZTtBQUdmRSxRQUhlO0FBSWZELFVBSmU7QUFLZkUsd0JBTGU7QUFNZjhCLDhCQU5lO0FBT2ZnQztBQVBlLENBQWpCIiwiZmlsZSI6IkF1dGguanMiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBjcnlwdG9VdGlscyA9IHJlcXVpcmUoJy4vY3J5cHRvVXRpbHMnKTtcbmNvbnN0IFJlc3RRdWVyeSA9IHJlcXVpcmUoJy4vUmVzdFF1ZXJ5Jyk7XG5jb25zdCBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKTtcblxuLy8gQW4gQXV0aCBvYmplY3QgdGVsbHMgeW91IHdobyBpcyByZXF1ZXN0aW5nIHNvbWV0aGluZyBhbmQgd2hldGhlclxuLy8gdGhlIG1hc3RlciBrZXkgd2FzIHVzZWQuXG4vLyB1c2VyT2JqZWN0IGlzIGEgUGFyc2UuVXNlciBhbmQgY2FuIGJlIG51bGwgaWYgdGhlcmUncyBubyB1c2VyLlxuZnVuY3Rpb24gQXV0aCh7IGNvbmZpZywgaXNNYXN0ZXIgPSBmYWxzZSwgaXNSZWFkT25seSA9IGZhbHNlLCB1c2VyLCBpbnN0YWxsYXRpb25JZCB9ID0ge30pIHtcbiAgdGhpcy5jb25maWcgPSBjb25maWc7XG4gIHRoaXMuaW5zdGFsbGF0aW9uSWQgPSBpbnN0YWxsYXRpb25JZDtcbiAgdGhpcy5pc01hc3RlciA9IGlzTWFzdGVyO1xuICB0aGlzLnVzZXIgPSB1c2VyO1xuICB0aGlzLmlzUmVhZE9ubHkgPSBpc1JlYWRPbmx5O1xuXG4gIC8vIEFzc3VtaW5nIGEgdXNlcnMgcm9sZXMgd29uJ3QgY2hhbmdlIGR1cmluZyBhIHNpbmdsZSByZXF1ZXN0LCB3ZSdsbFxuICAvLyBvbmx5IGxvYWQgdGhlbSBvbmNlLlxuICB0aGlzLnVzZXJSb2xlcyA9IFtdO1xuICB0aGlzLmZldGNoZWRSb2xlcyA9IGZhbHNlO1xuICB0aGlzLnJvbGVQcm9taXNlID0gbnVsbDtcbn1cblxuLy8gV2hldGhlciB0aGlzIGF1dGggY291bGQgcG9zc2libHkgbW9kaWZ5IHRoZSBnaXZlbiB1c2VyIGlkLlxuLy8gSXQgc3RpbGwgY291bGQgYmUgZm9yYmlkZGVuIHZpYSBBQ0xzIGV2ZW4gaWYgdGhpcyByZXR1cm5zIHRydWUuXG5BdXRoLnByb3RvdHlwZS5pc1VuYXV0aGVudGljYXRlZCA9IGZ1bmN0aW9uKCkge1xuICBpZiAodGhpcy5pc01hc3Rlcikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodGhpcy51c2VyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufTtcblxuLy8gQSBoZWxwZXIgdG8gZ2V0IGEgbWFzdGVyLWxldmVsIEF1dGggb2JqZWN0XG5mdW5jdGlvbiBtYXN0ZXIoY29uZmlnKSB7XG4gIHJldHVybiBuZXcgQXV0aCh7IGNvbmZpZywgaXNNYXN0ZXI6IHRydWUgfSk7XG59XG5cbi8vIEEgaGVscGVyIHRvIGdldCBhIG1hc3Rlci1sZXZlbCBBdXRoIG9iamVjdFxuZnVuY3Rpb24gcmVhZE9ubHkoY29uZmlnKSB7XG4gIHJldHVybiBuZXcgQXV0aCh7IGNvbmZpZywgaXNNYXN0ZXI6IHRydWUsIGlzUmVhZE9ubHk6IHRydWUgfSk7XG59XG5cbi8vIEEgaGVscGVyIHRvIGdldCBhIG5vYm9keS1sZXZlbCBBdXRoIG9iamVjdFxuZnVuY3Rpb24gbm9ib2R5KGNvbmZpZykge1xuICByZXR1cm4gbmV3IEF1dGgoeyBjb25maWcsIGlzTWFzdGVyOiBmYWxzZSB9KTtcbn1cblxuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIEF1dGggb2JqZWN0XG52YXIgZ2V0QXV0aEZvclNlc3Npb25Ub2tlbiA9IGZ1bmN0aW9uKHsgY29uZmlnLCBzZXNzaW9uVG9rZW4sIGluc3RhbGxhdGlvbklkIH0gPSB7fSkge1xuICByZXR1cm4gY29uZmlnLmNhY2hlQ29udHJvbGxlci51c2VyLmdldChzZXNzaW9uVG9rZW4pLnRoZW4oKHVzZXJKU09OKSA9PiB7XG4gICAgaWYgKHVzZXJKU09OKSB7XG4gICAgICBjb25zdCBjYWNoZWRVc2VyID0gUGFyc2UuT2JqZWN0LmZyb21KU09OKHVzZXJKU09OKTtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUobmV3IEF1dGgoe2NvbmZpZywgaXNNYXN0ZXI6IGZhbHNlLCBpbnN0YWxsYXRpb25JZCwgdXNlcjogY2FjaGVkVXNlcn0pKTtcbiAgICB9XG5cbiAgICB2YXIgcmVzdE9wdGlvbnMgPSB7XG4gICAgICBsaW1pdDogMSxcbiAgICAgIGluY2x1ZGU6ICd1c2VyJ1xuICAgIH07XG5cbiAgICB2YXIgcXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KGNvbmZpZywgbWFzdGVyKGNvbmZpZyksICdfU2Vzc2lvbicsIHtzZXNzaW9uVG9rZW59LCByZXN0T3B0aW9ucyk7XG4gICAgcmV0dXJuIHF1ZXJ5LmV4ZWN1dGUoKS50aGVuKChyZXNwb25zZSkgPT4ge1xuICAgICAgdmFyIHJlc3VsdHMgPSByZXNwb25zZS5yZXN1bHRzO1xuICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoICE9PSAxIHx8ICFyZXN1bHRzWzBdWyd1c2VyJ10pIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTiwgJ0ludmFsaWQgc2Vzc2lvbiB0b2tlbicpO1xuICAgICAgfVxuXG4gICAgICB2YXIgbm93ID0gbmV3IERhdGUoKSxcbiAgICAgICAgZXhwaXJlc0F0ID0gcmVzdWx0c1swXS5leHBpcmVzQXQgPyBuZXcgRGF0ZShyZXN1bHRzWzBdLmV4cGlyZXNBdC5pc28pIDogdW5kZWZpbmVkO1xuICAgICAgaWYgKGV4cGlyZXNBdCA8IG5vdykge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOLFxuICAgICAgICAgICdTZXNzaW9uIHRva2VuIGlzIGV4cGlyZWQuJyk7XG4gICAgICB9XG4gICAgICB2YXIgb2JqID0gcmVzdWx0c1swXVsndXNlciddO1xuICAgICAgZGVsZXRlIG9iai5wYXNzd29yZDtcbiAgICAgIG9ialsnY2xhc3NOYW1lJ10gPSAnX1VzZXInO1xuICAgICAgb2JqWydzZXNzaW9uVG9rZW4nXSA9IHNlc3Npb25Ub2tlbjtcbiAgICAgIGNvbmZpZy5jYWNoZUNvbnRyb2xsZXIudXNlci5wdXQoc2Vzc2lvblRva2VuLCBvYmopO1xuICAgICAgY29uc3QgdXNlck9iamVjdCA9IFBhcnNlLk9iamVjdC5mcm9tSlNPTihvYmopO1xuICAgICAgcmV0dXJuIG5ldyBBdXRoKHtjb25maWcsIGlzTWFzdGVyOiBmYWxzZSwgaW5zdGFsbGF0aW9uSWQsIHVzZXI6IHVzZXJPYmplY3R9KTtcbiAgICB9KTtcbiAgfSk7XG59O1xuXG52YXIgZ2V0QXV0aEZvckxlZ2FjeVNlc3Npb25Ub2tlbiA9IGZ1bmN0aW9uKHtjb25maWcsIHNlc3Npb25Ub2tlbiwgaW5zdGFsbGF0aW9uSWQgfSA9IHt9KSB7XG4gIHZhciByZXN0T3B0aW9ucyA9IHtcbiAgICBsaW1pdDogMVxuICB9O1xuICB2YXIgcXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KGNvbmZpZywgbWFzdGVyKGNvbmZpZyksICdfVXNlcicsIHsgc2Vzc2lvblRva2VuOiBzZXNzaW9uVG9rZW59LCByZXN0T3B0aW9ucyk7XG4gIHJldHVybiBxdWVyeS5leGVjdXRlKCkudGhlbigocmVzcG9uc2UpID0+IHtcbiAgICB2YXIgcmVzdWx0cyA9IHJlc3BvbnNlLnJlc3VsdHM7XG4gICAgaWYgKHJlc3VsdHMubGVuZ3RoICE9PSAxKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOLCAnaW52YWxpZCBsZWdhY3kgc2Vzc2lvbiB0b2tlbicpO1xuICAgIH1cbiAgICBjb25zdCBvYmogPSByZXN1bHRzWzBdO1xuICAgIG9iai5jbGFzc05hbWUgPSAnX1VzZXInO1xuICAgIGNvbnN0IHVzZXJPYmplY3QgPSBQYXJzZS5PYmplY3QuZnJvbUpTT04ob2JqKTtcbiAgICByZXR1cm4gbmV3IEF1dGgoe2NvbmZpZywgaXNNYXN0ZXI6IGZhbHNlLCBpbnN0YWxsYXRpb25JZCwgdXNlcjogdXNlck9iamVjdH0pO1xuICB9KTtcbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBvZiByb2xlIG5hbWVzXG5BdXRoLnByb3RvdHlwZS5nZXRVc2VyUm9sZXMgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuaXNNYXN0ZXIgfHwgIXRoaXMudXNlcikge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoW10pO1xuICB9XG4gIGlmICh0aGlzLmZldGNoZWRSb2xlcykge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy51c2VyUm9sZXMpO1xuICB9XG4gIGlmICh0aGlzLnJvbGVQcm9taXNlKSB7XG4gICAgcmV0dXJuIHRoaXMucm9sZVByb21pc2U7XG4gIH1cbiAgdGhpcy5yb2xlUHJvbWlzZSA9IHRoaXMuX2xvYWRSb2xlcygpO1xuICByZXR1cm4gdGhpcy5yb2xlUHJvbWlzZTtcbn07XG5cbi8vIEl0ZXJhdGVzIHRocm91Z2ggdGhlIHJvbGUgdHJlZSBhbmQgY29tcGlsZXMgYSB1c2VycyByb2xlc1xuQXV0aC5wcm90b3R5cGUuX2xvYWRSb2xlcyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY2FjaGVBZGFwdGVyID0gdGhpcy5jb25maWcuY2FjaGVDb250cm9sbGVyO1xuICByZXR1cm4gY2FjaGVBZGFwdGVyLnJvbGUuZ2V0KHRoaXMudXNlci5pZCkudGhlbigoY2FjaGVkUm9sZXMpID0+IHtcbiAgICBpZiAoY2FjaGVkUm9sZXMgIT0gbnVsbCkge1xuICAgICAgdGhpcy5mZXRjaGVkUm9sZXMgPSB0cnVlO1xuICAgICAgdGhpcy51c2VyUm9sZXMgPSBjYWNoZWRSb2xlcztcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoY2FjaGVkUm9sZXMpO1xuICAgIH1cblxuICAgIHZhciByZXN0V2hlcmUgPSB7XG4gICAgICAndXNlcnMnOiB7XG4gICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICBjbGFzc05hbWU6ICdfVXNlcicsXG4gICAgICAgIG9iamVjdElkOiB0aGlzLnVzZXIuaWRcbiAgICAgIH1cbiAgICB9O1xuICAgIC8vIEZpcnN0IGdldCB0aGUgcm9sZSBpZHMgdGhpcyB1c2VyIGlzIGRpcmVjdGx5IGEgbWVtYmVyIG9mXG4gICAgdmFyIHF1ZXJ5ID0gbmV3IFJlc3RRdWVyeSh0aGlzLmNvbmZpZywgbWFzdGVyKHRoaXMuY29uZmlnKSwgJ19Sb2xlJywgcmVzdFdoZXJlLCB7fSk7XG4gICAgcmV0dXJuIHF1ZXJ5LmV4ZWN1dGUoKS50aGVuKChyZXNwb25zZSkgPT4ge1xuICAgICAgdmFyIHJlc3VsdHMgPSByZXNwb25zZS5yZXN1bHRzO1xuICAgICAgaWYgKCFyZXN1bHRzLmxlbmd0aCkge1xuICAgICAgICB0aGlzLnVzZXJSb2xlcyA9IFtdO1xuICAgICAgICB0aGlzLmZldGNoZWRSb2xlcyA9IHRydWU7XG4gICAgICAgIHRoaXMucm9sZVByb21pc2UgPSBudWxsO1xuXG4gICAgICAgIGNhY2hlQWRhcHRlci5yb2xlLnB1dCh0aGlzLnVzZXIuaWQsIEFycmF5KC4uLnRoaXMudXNlclJvbGVzKSk7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy51c2VyUm9sZXMpO1xuICAgICAgfVxuICAgICAgdmFyIHJvbGVzTWFwID0gcmVzdWx0cy5yZWR1Y2UoKG0sIHIpID0+IHtcbiAgICAgICAgbS5uYW1lcy5wdXNoKHIubmFtZSk7XG4gICAgICAgIG0uaWRzLnB1c2goci5vYmplY3RJZCk7XG4gICAgICAgIHJldHVybiBtO1xuICAgICAgfSwge2lkczogW10sIG5hbWVzOiBbXX0pO1xuXG4gICAgICAvLyBydW4gdGhlIHJlY3Vyc2l2ZSBmaW5kaW5nXG4gICAgICByZXR1cm4gdGhpcy5fZ2V0QWxsUm9sZXNOYW1lc0ZvclJvbGVJZHMocm9sZXNNYXAuaWRzLCByb2xlc01hcC5uYW1lcylcbiAgICAgICAgLnRoZW4oKHJvbGVOYW1lcykgPT4ge1xuICAgICAgICAgIHRoaXMudXNlclJvbGVzID0gcm9sZU5hbWVzLm1hcCgocikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuICdyb2xlOicgKyByO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRoaXMuZmV0Y2hlZFJvbGVzID0gdHJ1ZTtcbiAgICAgICAgICB0aGlzLnJvbGVQcm9taXNlID0gbnVsbDtcbiAgICAgICAgICBjYWNoZUFkYXB0ZXIucm9sZS5wdXQodGhpcy51c2VyLmlkLCBBcnJheSguLi50aGlzLnVzZXJSb2xlcykpO1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy51c2VyUm9sZXMpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59O1xuXG4vLyBHaXZlbiBhIGxpc3Qgb2Ygcm9sZUlkcywgZmluZCBhbGwgdGhlIHBhcmVudCByb2xlcywgcmV0dXJucyBhIHByb21pc2Ugd2l0aCBhbGwgbmFtZXNcbkF1dGgucHJvdG90eXBlLl9nZXRBbGxSb2xlc05hbWVzRm9yUm9sZUlkcyA9IGZ1bmN0aW9uKHJvbGVJRHMsIG5hbWVzID0gW10sIHF1ZXJpZWRSb2xlcyA9IHt9KSB7XG4gIGNvbnN0IGlucyA9IHJvbGVJRHMuZmlsdGVyKChyb2xlSUQpID0+IHtcbiAgICByZXR1cm4gcXVlcmllZFJvbGVzW3JvbGVJRF0gIT09IHRydWU7XG4gIH0pLm1hcCgocm9sZUlEKSA9PiB7XG4gICAgLy8gbWFyayBhcyBxdWVyaWVkXG4gICAgcXVlcmllZFJvbGVzW3JvbGVJRF0gPSB0cnVlO1xuICAgIHJldHVybiB7XG4gICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgIGNsYXNzTmFtZTogJ19Sb2xlJyxcbiAgICAgIG9iamVjdElkOiByb2xlSURcbiAgICB9XG4gIH0pO1xuXG4gIC8vIGFsbCByb2xlcyBhcmUgYWNjb3VudGVkIGZvciwgcmV0dXJuIHRoZSBuYW1lc1xuICBpZiAoaW5zLmxlbmd0aCA9PSAwKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShbLi4ubmV3IFNldChuYW1lcyldKTtcbiAgfVxuICAvLyBCdWlsZCBhbiBPUiBxdWVyeSBhY3Jvc3MgYWxsIHBhcmVudFJvbGVzXG4gIGxldCByZXN0V2hlcmU7XG4gIGlmIChpbnMubGVuZ3RoID09IDEpIHtcbiAgICByZXN0V2hlcmUgPSB7ICdyb2xlcyc6IGluc1swXSB9O1xuICB9IGVsc2Uge1xuICAgIHJlc3RXaGVyZSA9IHsgJ3JvbGVzJzogeyAnJGluJzogaW5zIH19XG4gIH1cbiAgY29uc3QgcXVlcnkgPSBuZXcgUmVzdFF1ZXJ5KHRoaXMuY29uZmlnLCBtYXN0ZXIodGhpcy5jb25maWcpLCAnX1JvbGUnLCByZXN0V2hlcmUsIHt9KTtcbiAgcmV0dXJuIHF1ZXJ5LmV4ZWN1dGUoKS50aGVuKChyZXNwb25zZSkgPT4ge1xuICAgIHZhciByZXN1bHRzID0gcmVzcG9uc2UucmVzdWx0cztcbiAgICAvLyBOb3RoaW5nIGZvdW5kXG4gICAgaWYgKCFyZXN1bHRzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuYW1lcyk7XG4gICAgfVxuICAgIC8vIE1hcCB0aGUgcmVzdWx0cyB3aXRoIGFsbCBJZHMgYW5kIG5hbWVzXG4gICAgY29uc3QgcmVzdWx0TWFwID0gcmVzdWx0cy5yZWR1Y2UoKG1lbW8sIHJvbGUpID0+IHtcbiAgICAgIG1lbW8ubmFtZXMucHVzaChyb2xlLm5hbWUpO1xuICAgICAgbWVtby5pZHMucHVzaChyb2xlLm9iamVjdElkKTtcbiAgICAgIHJldHVybiBtZW1vO1xuICAgIH0sIHtpZHM6IFtdLCBuYW1lczogW119KTtcbiAgICAvLyBzdG9yZSB0aGUgbmV3IGZvdW5kIG5hbWVzXG4gICAgbmFtZXMgPSBuYW1lcy5jb25jYXQocmVzdWx0TWFwLm5hbWVzKTtcbiAgICAvLyBmaW5kIHRoZSBuZXh0IG9uZXMsIGNpcmN1bGFyIHJvbGVzIHdpbGwgYmUgY3V0XG4gICAgcmV0dXJuIHRoaXMuX2dldEFsbFJvbGVzTmFtZXNGb3JSb2xlSWRzKHJlc3VsdE1hcC5pZHMsIG5hbWVzLCBxdWVyaWVkUm9sZXMpXG4gIH0pLnRoZW4oKG5hbWVzKSA9PiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShbLi4ubmV3IFNldChuYW1lcyldKVxuICB9KVxufVxuXG5jb25zdCBjcmVhdGVTZXNzaW9uID0gZnVuY3Rpb24oY29uZmlnLCB7XG4gIHVzZXJJZCxcbiAgY3JlYXRlZFdpdGgsXG4gIGluc3RhbGxhdGlvbklkLFxuICBhZGRpdGlvbmFsU2Vzc2lvbkRhdGEsXG59KSB7XG4gIGNvbnN0IHRva2VuID0gJ3I6JyArIGNyeXB0b1V0aWxzLm5ld1Rva2VuKCk7XG4gIGNvbnN0IGV4cGlyZXNBdCA9IGNvbmZpZy5nZW5lcmF0ZVNlc3Npb25FeHBpcmVzQXQoKTtcbiAgY29uc3Qgc2Vzc2lvbkRhdGEgPSB7XG4gICAgc2Vzc2lvblRva2VuOiB0b2tlbixcbiAgICB1c2VyOiB7XG4gICAgICBfX3R5cGU6ICdQb2ludGVyJyxcbiAgICAgIGNsYXNzTmFtZTogJ19Vc2VyJyxcbiAgICAgIG9iamVjdElkOiB1c2VySWRcbiAgICB9LFxuICAgIGNyZWF0ZWRXaXRoLFxuICAgIHJlc3RyaWN0ZWQ6IGZhbHNlLFxuICAgIGV4cGlyZXNBdDogUGFyc2UuX2VuY29kZShleHBpcmVzQXQpXG4gIH07XG5cbiAgaWYgKGluc3RhbGxhdGlvbklkKSB7XG4gICAgc2Vzc2lvbkRhdGEuaW5zdGFsbGF0aW9uSWQgPSBpbnN0YWxsYXRpb25JZFxuICB9XG5cbiAgT2JqZWN0LmFzc2lnbihzZXNzaW9uRGF0YSwgYWRkaXRpb25hbFNlc3Npb25EYXRhKTtcbiAgLy8gV2UgbmVlZCB0byBpbXBvcnQgUmVzdFdyaXRlIGF0IHRoaXMgcG9pbnQgZm9yIHRoZSBjeWNsaWMgZGVwZW5kZW5jeSBpdCBoYXMgdG8gaXRcbiAgY29uc3QgUmVzdFdyaXRlID0gcmVxdWlyZSgnLi9SZXN0V3JpdGUnKTtcblxuICByZXR1cm4ge1xuICAgIHNlc3Npb25EYXRhLFxuICAgIGNyZWF0ZVNlc3Npb246ICgpID0+IG5ldyBSZXN0V3JpdGUoY29uZmlnLCBtYXN0ZXIoY29uZmlnKSwgJ19TZXNzaW9uJywgbnVsbCwgc2Vzc2lvbkRhdGEpLmV4ZWN1dGUoKVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBBdXRoLFxuICBtYXN0ZXIsXG4gIG5vYm9keSxcbiAgcmVhZE9ubHksXG4gIGdldEF1dGhGb3JTZXNzaW9uVG9rZW4sXG4gIGdldEF1dGhGb3JMZWdhY3lTZXNzaW9uVG9rZW4sXG4gIGNyZWF0ZVNlc3Npb24sXG59O1xuIl19
|
|
621
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfdXRpbCIsInJlcXVpcmUiLCJfdHJpZ2dlcnMiLCJfbG9nZ2VyIiwiX2xydUNhY2hlIiwiX1Jlc3RRdWVyeSIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfUmVzdFdyaXRlIiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiUGFyc2UiLCJBdXRoIiwiY29uZmlnIiwiY2FjaGVDb250cm9sbGVyIiwidW5kZWZpbmVkIiwiaXNNYXN0ZXIiLCJpc01haW50ZW5hbmNlIiwiaXNSZWFkT25seSIsInVzZXIiLCJpbnN0YWxsYXRpb25JZCIsInVzZXJSb2xlcyIsImZldGNoZWRSb2xlcyIsInJvbGVQcm9taXNlIiwicHJvdG90eXBlIiwiaXNVbmF1dGhlbnRpY2F0ZWQiLCJtYXN0ZXIiLCJtYWludGVuYW5jZSIsInJlYWRPbmx5Iiwibm9ib2R5IiwidGhyb3R0bGUiLCJMUlUiLCJtYXgiLCJ0dGwiLCJzaG91bGRVcGRhdGVTZXNzaW9uRXhwaXJ5Iiwic2Vzc2lvbiIsInJlc2V0QWZ0ZXIiLCJzZXNzaW9uTGVuZ3RoIiwibGFzdFVwZGF0ZWQiLCJEYXRlIiwidXBkYXRlZEF0Iiwic2tpcFJhbmdlIiwic2V0VGltZSIsImdldFRpbWUiLCJyZW5ld1Nlc3Npb25JZk5lZWRlZCIsInNlc3Npb25Ub2tlbiIsImV4dGVuZFNlc3Npb25PblVzZSIsImdldCIsInNldCIsInF1ZXJ5IiwiUmVzdFF1ZXJ5IiwibWV0aG9kIiwiTWV0aG9kIiwiYXV0aCIsInJ1bkJlZm9yZUZpbmQiLCJjbGFzc05hbWUiLCJyZXN0V2hlcmUiLCJyZXN0T3B0aW9ucyIsImxpbWl0IiwicmVzdWx0cyIsImV4ZWN1dGUiLCJleHBpcmVzQXQiLCJnZW5lcmF0ZVNlc3Npb25FeHBpcmVzQXQiLCJSZXN0V3JpdGUiLCJvYmplY3RJZCIsIl9lbmNvZGUiLCJjb2RlIiwiRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwibG9nZ2VyIiwiZXJyb3IiLCJnZXRBdXRoRm9yU2Vzc2lvblRva2VuIiwidXNlckpTT04iLCJjYWNoZWRVc2VyIiwiT2JqZWN0IiwiZnJvbUpTT04iLCJQcm9taXNlIiwicmVzb2x2ZSIsImluY2x1ZGUiLCJRdWVyeSIsIlNlc3Npb24iLCJlcXVhbFRvIiwiZmluZCIsInVzZU1hc3RlcktleSIsIm1hcCIsIm9iaiIsInRvSlNPTiIsImxlbmd0aCIsIklOVkFMSURfU0VTU0lPTl9UT0tFTiIsIm5vdyIsImlzbyIsInN0YXJ0c1dpdGgiLCJJTlRFUk5BTF9TRVJWRVJfRVJST1IiLCJwYXNzd29yZCIsInB1dCIsInVzZXJPYmplY3QiLCJnZXRBdXRoRm9yTGVnYWN5U2Vzc2lvblRva2VuIiwiX3Nlc3Npb25fdG9rZW4iLCJ0aGVuIiwicmVzcG9uc2UiLCJnZXRVc2VyUm9sZXMiLCJfbG9hZFJvbGVzIiwiZ2V0Um9sZXNGb3JVc2VyIiwidXNlcnMiLCJfX3R5cGUiLCJpZCIsImVhY2giLCJyZXN1bHQiLCJwdXNoIiwiUm9sZSIsImNhY2hlZFJvbGVzIiwicm9sZSIsImNhY2hlUm9sZXMiLCJyb2xlc01hcCIsInJlZHVjZSIsIm0iLCJyIiwibmFtZXMiLCJuYW1lIiwiaWRzIiwicm9sZU5hbWVzIiwiX2dldEFsbFJvbGVzTmFtZXNGb3JSb2xlSWRzIiwiQXJyYXkiLCJjbGVhclJvbGVDYWNoZSIsImRlbCIsImdldFJvbGVzQnlJZHMiLCJpbnMiLCJjb250YWluZWRJbiIsInJvbGVzIiwiJGluIiwicm9sZUlEcyIsInF1ZXJpZWRSb2xlcyIsImZpbHRlciIsInJvbGVJRCIsIndhc1F1ZXJpZWQiLCJTZXQiLCJyZXN1bHRNYXAiLCJtZW1vIiwiY29uY2F0IiwiZmluZFVzZXJzV2l0aEF1dGhEYXRhIiwiYXV0aERhdGEiLCJiZWZvcmVGaW5kIiwicHJvdmlkZXJzIiwia2V5cyIsInF1ZXJpZXMiLCJhbGwiLCJwcm92aWRlciIsInByb3ZpZGVyQXV0aERhdGEiLCJhZGFwdGVyIiwiYXV0aERhdGFNYW5hZ2VyIiwiZ2V0VmFsaWRhdG9yRm9yUHJvdmlkZXIiLCJ2YWxpZFF1ZXJpZXMiLCJkYXRhYmFzZSIsIiRvciIsImhhc011dGF0ZWRBdXRoRGF0YSIsInVzZXJBdXRoRGF0YSIsIm11dGF0ZWRBdXRoRGF0YSIsImZvckVhY2giLCJwcm92aWRlckRhdGEiLCJ1c2VyUHJvdmlkZXJBdXRoRGF0YSIsImlzRGVlcFN0cmljdEVxdWFsIiwiY2hlY2tJZlVzZXJIYXNQcm92aWRlZENvbmZpZ3VyZWRQcm92aWRlcnNGb3JMb2dpbiIsInJlcSIsInNhdmVkVXNlclByb3ZpZGVycyIsImhhc1Byb3ZpZGVkQVNvbG9Qcm92aWRlciIsInNvbWUiLCJwb2xpY3kiLCJhZGRpdGlvblByb3ZpZGVyc05vdEZvdW5kIiwiaGFzUHJvdmlkZWRBdExlYXN0T25lQWRkaXRpb25hbFByb3ZpZGVyIiwicmVxdWVzdE9iamVjdCIsImlwIiwiY2FsbCIsIk9USEVSX0NBVVNFIiwiam9pbiIsImhhbmRsZUF1dGhEYXRhVmFsaWRhdGlvbiIsImZvdW5kVXNlciIsIlVzZXIiLCJnZXRVc2VySWQiLCJmZXRjaCIsInVwZGF0ZWRPYmplY3QiLCJidWlsZFBhcnNlT2JqZWN0cyIsImdldFJlcXVlc3RPYmplY3QiLCJhY2MiLCJhdXRoRGF0YVJlc3BvbnNlIiwiYXV0aEtleXMiLCJzb3J0IiwidmFsaWRhdG9yIiwiYXV0aFByb3ZpZGVyIiwiZW5hYmxlZCIsIlVOU1VQUE9SVEVEX1NFUlZJQ0UiLCJ2YWxpZGF0aW9uUmVzdWx0IiwidHJpZ2dlck5hbWUiLCJkb05vdFNhdmUiLCJzYXZlIiwiZXJyIiwicmVzb2x2ZUVycm9yIiwiU0NSSVBUX0ZBSUxFRCIsIm1lc3NhZ2UiLCJ1c2VyU3RyaW5nIiwiZGF0YSIsIkpTT04iLCJzdHJpbmdpZnkiLCJhdXRoZW50aWNhdGlvblN0ZXAiLCJtb2R1bGUiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vc3JjL0F1dGguanMiXSwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgUGFyc2UgPSByZXF1aXJlKCdwYXJzZS9ub2RlJyk7XG5pbXBvcnQgeyBpc0RlZXBTdHJpY3RFcXVhbCB9IGZyb20gJ3V0aWwnO1xuaW1wb3J0IHsgZ2V0UmVxdWVzdE9iamVjdCwgcmVzb2x2ZUVycm9yIH0gZnJvbSAnLi90cmlnZ2Vycyc7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tICcuL2xvZ2dlcic7XG5pbXBvcnQgeyBMUlVDYWNoZSBhcyBMUlUgfSBmcm9tICdscnUtY2FjaGUnO1xuaW1wb3J0IFJlc3RRdWVyeSBmcm9tICcuL1Jlc3RRdWVyeSc7XG5pbXBvcnQgUmVzdFdyaXRlIGZyb20gJy4vUmVzdFdyaXRlJztcblxuLy8gQW4gQXV0aCBvYmplY3QgdGVsbHMgeW91IHdobyBpcyByZXF1ZXN0aW5nIHNvbWV0aGluZyBhbmQgd2hldGhlclxuLy8gdGhlIG1hc3RlciBrZXkgd2FzIHVzZWQuXG4vLyB1c2VyT2JqZWN0IGlzIGEgUGFyc2UuVXNlciBhbmQgY2FuIGJlIG51bGwgaWYgdGhlcmUncyBubyB1c2VyLlxuZnVuY3Rpb24gQXV0aCh7XG4gIGNvbmZpZyxcbiAgY2FjaGVDb250cm9sbGVyID0gdW5kZWZpbmVkLFxuICBpc01hc3RlciA9IGZhbHNlLFxuICBpc01haW50ZW5hbmNlID0gZmFsc2UsXG4gIGlzUmVhZE9ubHkgPSBmYWxzZSxcbiAgdXNlcixcbiAgaW5zdGFsbGF0aW9uSWQsXG59KSB7XG4gIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICB0aGlzLmNhY2hlQ29udHJvbGxlciA9IGNhY2hlQ29udHJvbGxlciB8fCAoY29uZmlnICYmIGNvbmZpZy5jYWNoZUNvbnRyb2xsZXIpO1xuICB0aGlzLmluc3RhbGxhdGlvbklkID0gaW5zdGFsbGF0aW9uSWQ7XG4gIHRoaXMuaXNNYXN0ZXIgPSBpc01hc3RlcjtcbiAgdGhpcy5pc01haW50ZW5hbmNlID0gaXNNYWludGVuYW5jZTtcbiAgdGhpcy51c2VyID0gdXNlcjtcbiAgdGhpcy5pc1JlYWRPbmx5ID0gaXNSZWFkT25seTtcblxuICAvLyBBc3N1bWluZyBhIHVzZXJzIHJvbGVzIHdvbid0IGNoYW5nZSBkdXJpbmcgYSBzaW5nbGUgcmVxdWVzdCwgd2UnbGxcbiAgLy8gb25seSBsb2FkIHRoZW0gb25jZS5cbiAgdGhpcy51c2VyUm9sZXMgPSBbXTtcbiAgdGhpcy5mZXRjaGVkUm9sZXMgPSBmYWxzZTtcbiAgdGhpcy5yb2xlUHJvbWlzZSA9IG51bGw7XG59XG5cbi8vIFdoZXRoZXIgdGhpcyBhdXRoIGNvdWxkIHBvc3NpYmx5IG1vZGlmeSB0aGUgZ2l2ZW4gdXNlciBpZC5cbi8vIEl0IHN0aWxsIGNvdWxkIGJlIGZvcmJpZGRlbiB2aWEgQUNMcyBldmVuIGlmIHRoaXMgcmV0dXJucyB0cnVlLlxuQXV0aC5wcm90b3R5cGUuaXNVbmF1dGhlbnRpY2F0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmlzTWFzdGVyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICh0aGlzLmlzTWFpbnRlbmFuY2UpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHRoaXMudXNlcikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8vIEEgaGVscGVyIHRvIGdldCBhIG1hc3Rlci1sZXZlbCBBdXRoIG9iamVjdFxuZnVuY3Rpb24gbWFzdGVyKGNvbmZpZykge1xuICByZXR1cm4gbmV3IEF1dGgoeyBjb25maWcsIGlzTWFzdGVyOiB0cnVlIH0pO1xufVxuXG4vLyBBIGhlbHBlciB0byBnZXQgYSBtYWludGVuYW5jZS1sZXZlbCBBdXRoIG9iamVjdFxuZnVuY3Rpb24gbWFpbnRlbmFuY2UoY29uZmlnKSB7XG4gIHJldHVybiBuZXcgQXV0aCh7IGNvbmZpZywgaXNNYWludGVuYW5jZTogdHJ1ZSB9KTtcbn1cblxuLy8gQSBoZWxwZXIgdG8gZ2V0IGEgbWFzdGVyLWxldmVsIEF1dGggb2JqZWN0XG5mdW5jdGlvbiByZWFkT25seShjb25maWcpIHtcbiAgcmV0dXJuIG5ldyBBdXRoKHsgY29uZmlnLCBpc01hc3RlcjogdHJ1ZSwgaXNSZWFkT25seTogdHJ1ZSB9KTtcbn1cblxuLy8gQSBoZWxwZXIgdG8gZ2V0IGEgbm9ib2R5LWxldmVsIEF1dGggb2JqZWN0XG5mdW5jdGlvbiBub2JvZHkoY29uZmlnKSB7XG4gIHJldHVybiBuZXcgQXV0aCh7IGNvbmZpZywgaXNNYXN0ZXI6IGZhbHNlIH0pO1xufVxuXG5jb25zdCB0aHJvdHRsZSA9IG5ldyBMUlUoe1xuICBtYXg6IDEwMDAwLFxuICB0dGw6IDUwMCxcbn0pO1xuLyoqXG4gKiBDaGVja3Mgd2hldGhlciBzZXNzaW9uIHNob3VsZCBiZSB1cGRhdGVkIGJhc2VkIG9uIGxhc3QgdXBkYXRlIHRpbWUgJiBzZXNzaW9uIGxlbmd0aC5cbiAqL1xuZnVuY3Rpb24gc2hvdWxkVXBkYXRlU2Vzc2lvbkV4cGlyeShjb25maWcsIHNlc3Npb24pIHtcbiAgY29uc3QgcmVzZXRBZnRlciA9IGNvbmZpZy5zZXNzaW9uTGVuZ3RoIC8gMjtcbiAgY29uc3QgbGFzdFVwZGF0ZWQgPSBuZXcgRGF0ZShzZXNzaW9uPy51cGRhdGVkQXQpO1xuICBjb25zdCBza2lwUmFuZ2UgPSBuZXcgRGF0ZSgpO1xuICBza2lwUmFuZ2Uuc2V0VGltZShza2lwUmFuZ2UuZ2V0VGltZSgpIC0gcmVzZXRBZnRlciAqIDEwMDApO1xuICByZXR1cm4gbGFzdFVwZGF0ZWQgPD0gc2tpcFJhbmdlO1xufVxuXG5jb25zdCByZW5ld1Nlc3Npb25JZk5lZWRlZCA9IGFzeW5jICh7IGNvbmZpZywgc2Vzc2lvbiwgc2Vzc2lvblRva2VuIH0pID0+IHtcbiAgaWYgKCFjb25maWc/LmV4dGVuZFNlc3Npb25PblVzZSkge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAodGhyb3R0bGUuZ2V0KHNlc3Npb25Ub2tlbikpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdGhyb3R0bGUuc2V0KHNlc3Npb25Ub2tlbiwgdHJ1ZSk7XG4gIHRyeSB7XG4gICAgaWYgKCFzZXNzaW9uKSB7XG4gICAgICBjb25zdCBxdWVyeSA9IGF3YWl0IFJlc3RRdWVyeSh7XG4gICAgICAgIG1ldGhvZDogUmVzdFF1ZXJ5Lk1ldGhvZC5nZXQsXG4gICAgICAgIGNvbmZpZyxcbiAgICAgICAgYXV0aDogbWFzdGVyKGNvbmZpZyksXG4gICAgICAgIHJ1bkJlZm9yZUZpbmQ6IGZhbHNlLFxuICAgICAgICBjbGFzc05hbWU6ICdfU2Vzc2lvbicsXG4gICAgICAgIHJlc3RXaGVyZTogeyBzZXNzaW9uVG9rZW4gfSxcbiAgICAgICAgcmVzdE9wdGlvbnM6IHsgbGltaXQ6IDEgfSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgeyByZXN1bHRzIH0gPSBhd2FpdCBxdWVyeS5leGVjdXRlKCk7XG4gICAgICBzZXNzaW9uID0gcmVzdWx0c1swXTtcbiAgICB9XG5cbiAgICBpZiAoIXNob3VsZFVwZGF0ZVNlc3Npb25FeHBpcnkoY29uZmlnLCBzZXNzaW9uKSB8fCAhc2Vzc2lvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBleHBpcmVzQXQgPSBjb25maWcuZ2VuZXJhdGVTZXNzaW9uRXhwaXJlc0F0KCk7XG4gICAgYXdhaXQgbmV3IFJlc3RXcml0ZShcbiAgICAgIGNvbmZpZyxcbiAgICAgIG1hc3Rlcihjb25maWcpLFxuICAgICAgJ19TZXNzaW9uJyxcbiAgICAgIHsgb2JqZWN0SWQ6IHNlc3Npb24ub2JqZWN0SWQgfSxcbiAgICAgIHsgZXhwaXJlc0F0OiBQYXJzZS5fZW5jb2RlKGV4cGlyZXNBdCkgfVxuICAgICkuZXhlY3V0ZSgpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgaWYgKGU/LmNvZGUgIT09IFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQpIHtcbiAgICAgIGxvZ2dlci5lcnJvcignQ291bGQgbm90IHVwZGF0ZSBzZXNzaW9uIGV4cGlyeTogJywgZSk7XG4gICAgfVxuICB9XG59O1xuXG4vLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIEF1dGggb2JqZWN0XG5jb25zdCBnZXRBdXRoRm9yU2Vzc2lvblRva2VuID0gYXN5bmMgZnVuY3Rpb24gKHtcbiAgY29uZmlnLFxuICBjYWNoZUNvbnRyb2xsZXIsXG4gIHNlc3Npb25Ub2tlbixcbiAgaW5zdGFsbGF0aW9uSWQsXG59KSB7XG4gIGNhY2hlQ29udHJvbGxlciA9IGNhY2hlQ29udHJvbGxlciB8fCAoY29uZmlnICYmIGNvbmZpZy5jYWNoZUNvbnRyb2xsZXIpO1xuICBpZiAoY2FjaGVDb250cm9sbGVyKSB7XG4gICAgY29uc3QgdXNlckpTT04gPSBhd2FpdCBjYWNoZUNvbnRyb2xsZXIudXNlci5nZXQoc2Vzc2lvblRva2VuKTtcbiAgICBpZiAodXNlckpTT04pIHtcbiAgICAgIGNvbnN0IGNhY2hlZFVzZXIgPSBQYXJzZS5PYmplY3QuZnJvbUpTT04odXNlckpTT04pO1xuICAgICAgcmVuZXdTZXNzaW9uSWZOZWVkZWQoeyBjb25maWcsIHNlc3Npb25Ub2tlbiB9KTtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoXG4gICAgICAgIG5ldyBBdXRoKHtcbiAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgY2FjaGVDb250cm9sbGVyLFxuICAgICAgICAgIGlzTWFzdGVyOiBmYWxzZSxcbiAgICAgICAgICBpbnN0YWxsYXRpb25JZCxcbiAgICAgICAgICB1c2VyOiBjYWNoZWRVc2VyLFxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBsZXQgcmVzdWx0cztcbiAgaWYgKGNvbmZpZykge1xuICAgIGNvbnN0IHJlc3RPcHRpb25zID0ge1xuICAgICAgbGltaXQ6IDEsXG4gICAgICBpbmNsdWRlOiAndXNlcicsXG4gICAgfTtcbiAgICBjb25zdCBSZXN0UXVlcnkgPSByZXF1aXJlKCcuL1Jlc3RRdWVyeScpO1xuICAgIGNvbnN0IHF1ZXJ5ID0gYXdhaXQgUmVzdFF1ZXJ5KHtcbiAgICAgIG1ldGhvZDogUmVzdFF1ZXJ5Lk1ldGhvZC5nZXQsXG4gICAgICBjb25maWcsXG4gICAgICBydW5CZWZvcmVGaW5kOiBmYWxzZSxcbiAgICAgIGF1dGg6IG1hc3Rlcihjb25maWcpLFxuICAgICAgY2xhc3NOYW1lOiAnX1Nlc3Npb24nLFxuICAgICAgcmVzdFdoZXJlOiB7IHNlc3Npb25Ub2tlbiB9LFxuICAgICAgcmVzdE9wdGlvbnMsXG4gICAgfSk7XG4gICAgcmVzdWx0cyA9IChhd2FpdCBxdWVyeS5leGVjdXRlKCkpLnJlc3VsdHM7XG4gIH0gZWxzZSB7XG4gICAgcmVzdWx0cyA9IChcbiAgICAgIGF3YWl0IG5ldyBQYXJzZS5RdWVyeShQYXJzZS5TZXNzaW9uKVxuICAgICAgICAubGltaXQoMSlcbiAgICAgICAgLmluY2x1ZGUoJ3VzZXInKVxuICAgICAgICAuZXF1YWxUbygnc2Vzc2lvblRva2VuJywgc2Vzc2lvblRva2VuKVxuICAgICAgICAuZmluZCh7IHVzZU1hc3RlcktleTogdHJ1ZSB9KVxuICAgICkubWFwKG9iaiA9PiBvYmoudG9KU09OKCkpO1xuICB9XG5cbiAgaWYgKHJlc3VsdHMubGVuZ3RoICE9PSAxIHx8ICFyZXN1bHRzWzBdWyd1c2VyJ10pIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOLCAnSW52YWxpZCBzZXNzaW9uIHRva2VuJyk7XG4gIH1cbiAgY29uc3Qgc2Vzc2lvbiA9IHJlc3VsdHNbMF07XG4gIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCksXG4gICAgZXhwaXJlc0F0ID0gc2Vzc2lvbi5leHBpcmVzQXQgPyBuZXcgRGF0ZShzZXNzaW9uLmV4cGlyZXNBdC5pc28pIDogdW5kZWZpbmVkO1xuICBpZiAoZXhwaXJlc0F0IDwgbm93KSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfU0VTU0lPTl9UT0tFTiwgJ1Nlc3Npb24gdG9rZW4gaXMgZXhwaXJlZC4nKTtcbiAgfVxuICBjb25zdCBvYmogPSBzZXNzaW9uLnVzZXI7XG5cbiAgaWYgKHR5cGVvZiBvYmpbJ29iamVjdElkJ10gPT09ICdzdHJpbmcnICYmIG9ialsnb2JqZWN0SWQnXS5zdGFydHNXaXRoKCdyb2xlOicpKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUiwgJ0ludmFsaWQgb2JqZWN0IElELicpO1xuICB9XG5cbiAgZGVsZXRlIG9iai5wYXNzd29yZDtcbiAgb2JqWydjbGFzc05hbWUnXSA9ICdfVXNlcic7XG4gIG9ialsnc2Vzc2lvblRva2VuJ10gPSBzZXNzaW9uVG9rZW47XG4gIGlmIChjYWNoZUNvbnRyb2xsZXIpIHtcbiAgICBjYWNoZUNvbnRyb2xsZXIudXNlci5wdXQoc2Vzc2lvblRva2VuLCBvYmopO1xuICB9XG4gIHJlbmV3U2Vzc2lvbklmTmVlZGVkKHsgY29uZmlnLCBzZXNzaW9uLCBzZXNzaW9uVG9rZW4gfSk7XG4gIGNvbnN0IHVzZXJPYmplY3QgPSBQYXJzZS5PYmplY3QuZnJvbUpTT04ob2JqKTtcbiAgcmV0dXJuIG5ldyBBdXRoKHtcbiAgICBjb25maWcsXG4gICAgY2FjaGVDb250cm9sbGVyLFxuICAgIGlzTWFzdGVyOiBmYWxzZSxcbiAgICBpbnN0YWxsYXRpb25JZCxcbiAgICB1c2VyOiB1c2VyT2JqZWN0LFxuICB9KTtcbn07XG5cbnZhciBnZXRBdXRoRm9yTGVnYWN5U2Vzc2lvblRva2VuID0gYXN5bmMgZnVuY3Rpb24gKHsgY29uZmlnLCBzZXNzaW9uVG9rZW4sIGluc3RhbGxhdGlvbklkIH0pIHtcbiAgdmFyIHJlc3RPcHRpb25zID0ge1xuICAgIGxpbWl0OiAxLFxuICB9O1xuICBjb25zdCBSZXN0UXVlcnkgPSByZXF1aXJlKCcuL1Jlc3RRdWVyeScpO1xuICB2YXIgcXVlcnkgPSBhd2FpdCBSZXN0UXVlcnkoe1xuICAgIG1ldGhvZDogUmVzdFF1ZXJ5Lk1ldGhvZC5nZXQsXG4gICAgY29uZmlnLFxuICAgIHJ1bkJlZm9yZUZpbmQ6IGZhbHNlLFxuICAgIGF1dGg6IG1hc3Rlcihjb25maWcpLFxuICAgIGNsYXNzTmFtZTogJ19Vc2VyJyxcbiAgICByZXN0V2hlcmU6IHsgX3Nlc3Npb25fdG9rZW46IHNlc3Npb25Ub2tlbiB9LFxuICAgIHJlc3RPcHRpb25zLFxuICB9KTtcbiAgcmV0dXJuIHF1ZXJ5LmV4ZWN1dGUoKS50aGVuKHJlc3BvbnNlID0+IHtcbiAgICB2YXIgcmVzdWx0cyA9IHJlc3BvbnNlLnJlc3VsdHM7XG4gICAgaWYgKHJlc3VsdHMubGVuZ3RoICE9PSAxKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9TRVNTSU9OX1RPS0VOLCAnaW52YWxpZCBsZWdhY3kgc2Vzc2lvbiB0b2tlbicpO1xuICAgIH1cbiAgICBjb25zdCBvYmogPSByZXN1bHRzWzBdO1xuICAgIG9iai5jbGFzc05hbWUgPSAnX1VzZXInO1xuICAgIGNvbnN0IHVzZXJPYmplY3QgPSBQYXJzZS5PYmplY3QuZnJvbUpTT04ob2JqKTtcbiAgICByZXR1cm4gbmV3IEF1dGgoe1xuICAgICAgY29uZmlnLFxuICAgICAgaXNNYXN0ZXI6IGZhbHNlLFxuICAgICAgaW5zdGFsbGF0aW9uSWQsXG4gICAgICB1c2VyOiB1c2VyT2JqZWN0LFxuICAgIH0pO1xuICB9KTtcbn07XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gYXJyYXkgb2Ygcm9sZSBuYW1lc1xuQXV0aC5wcm90b3R5cGUuZ2V0VXNlclJvbGVzID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5pc01hc3RlciB8fCB0aGlzLmlzTWFpbnRlbmFuY2UgfHwgIXRoaXMudXNlcikge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoW10pO1xuICB9XG4gIGlmICh0aGlzLmZldGNoZWRSb2xlcykge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcy51c2VyUm9sZXMpO1xuICB9XG4gIGlmICh0aGlzLnJvbGVQcm9taXNlKSB7XG4gICAgcmV0dXJuIHRoaXMucm9sZVByb21pc2U7XG4gIH1cbiAgdGhpcy5yb2xlUHJvbWlzZSA9IHRoaXMuX2xvYWRSb2xlcygpO1xuICByZXR1cm4gdGhpcy5yb2xlUHJvbWlzZTtcbn07XG5cbkF1dGgucHJvdG90eXBlLmdldFJvbGVzRm9yVXNlciA9IGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgLy9TdGFjayBhbGwgUGFyc2UuUm9sZVxuICBjb25zdCByZXN1bHRzID0gW107XG4gIGlmICh0aGlzLmNvbmZpZykge1xuICAgIGNvbnN0IHJlc3RXaGVyZSA9IHtcbiAgICAgIHVzZXJzOiB7XG4gICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICBjbGFzc05hbWU6ICdfVXNlcicsXG4gICAgICAgIG9iamVjdElkOiB0aGlzLnVzZXIuaWQsXG4gICAgICB9LFxuICAgIH07XG4gICAgY29uc3QgUmVzdFF1ZXJ5ID0gcmVxdWlyZSgnLi9SZXN0UXVlcnknKTtcbiAgICBjb25zdCBxdWVyeSA9IGF3YWl0IFJlc3RRdWVyeSh7XG4gICAgICBtZXRob2Q6IFJlc3RRdWVyeS5NZXRob2QuZmluZCxcbiAgICAgIHJ1bkJlZm9yZUZpbmQ6IGZhbHNlLFxuICAgICAgY29uZmlnOiB0aGlzLmNvbmZpZyxcbiAgICAgIGF1dGg6IG1hc3Rlcih0aGlzLmNvbmZpZyksXG4gICAgICBjbGFzc05hbWU6ICdfUm9sZScsXG4gICAgICByZXN0V2hlcmUsXG4gICAgfSk7XG4gICAgYXdhaXQgcXVlcnkuZWFjaChyZXN1bHQgPT4gcmVzdWx0cy5wdXNoKHJlc3VsdCkpO1xuICB9IGVsc2Uge1xuICAgIGF3YWl0IG5ldyBQYXJzZS5RdWVyeShQYXJzZS5Sb2xlKVxuICAgICAgLmVxdWFsVG8oJ3VzZXJzJywgdGhpcy51c2VyKVxuICAgICAgLmVhY2gocmVzdWx0ID0+IHJlc3VsdHMucHVzaChyZXN1bHQudG9KU09OKCkpLCB7IHVzZU1hc3RlcktleTogdHJ1ZSB9KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0cztcbn07XG5cbi8vIEl0ZXJhdGVzIHRocm91Z2ggdGhlIHJvbGUgdHJlZSBhbmQgY29tcGlsZXMgYSB1c2VyJ3Mgcm9sZXNcbkF1dGgucHJvdG90eXBlLl9sb2FkUm9sZXMgPSBhc3luYyBmdW5jdGlvbiAoKSB7XG4gIGlmICh0aGlzLmNhY2hlQ29udHJvbGxlcikge1xuICAgIGNvbnN0IGNhY2hlZFJvbGVzID0gYXdhaXQgdGhpcy5jYWNoZUNvbnRyb2xsZXIucm9sZS5nZXQodGhpcy51c2VyLmlkKTtcbiAgICBpZiAoY2FjaGVkUm9sZXMgIT0gbnVsbCkge1xuICAgICAgdGhpcy5mZXRjaGVkUm9sZXMgPSB0cnVlO1xuICAgICAgdGhpcy51c2VyUm9sZXMgPSBjYWNoZWRSb2xlcztcbiAgICAgIHJldHVybiBjYWNoZWRSb2xlcztcbiAgICB9XG4gIH1cblxuICAvLyBGaXJzdCBnZXQgdGhlIHJvbGUgaWRzIHRoaXMgdXNlciBpcyBkaXJlY3RseSBhIG1lbWJlciBvZlxuICBjb25zdCByZXN1bHRzID0gYXdhaXQgdGhpcy5nZXRSb2xlc0ZvclVzZXIoKTtcbiAgaWYgKCFyZXN1bHRzLmxlbmd0aCkge1xuICAgIHRoaXMudXNlclJvbGVzID0gW107XG4gICAgdGhpcy5mZXRjaGVkUm9sZXMgPSB0cnVlO1xuICAgIHRoaXMucm9sZVByb21pc2UgPSBudWxsO1xuXG4gICAgdGhpcy5jYWNoZVJvbGVzKCk7XG4gICAgcmV0dXJuIHRoaXMudXNlclJvbGVzO1xuICB9XG5cbiAgY29uc3Qgcm9sZXNNYXAgPSByZXN1bHRzLnJlZHVjZShcbiAgICAobSwgcikgPT4ge1xuICAgICAgbS5uYW1lcy5wdXNoKHIubmFtZSk7XG4gICAgICBtLmlkcy5wdXNoKHIub2JqZWN0SWQpO1xuICAgICAgcmV0dXJuIG07XG4gICAgfSxcbiAgICB7IGlkczogW10sIG5hbWVzOiBbXSB9XG4gICk7XG5cbiAgLy8gcnVuIHRoZSByZWN1cnNpdmUgZmluZGluZ1xuICBjb25zdCByb2xlTmFtZXMgPSBhd2FpdCB0aGlzLl9nZXRBbGxSb2xlc05hbWVzRm9yUm9sZUlkcyhyb2xlc01hcC5pZHMsIHJvbGVzTWFwLm5hbWVzKTtcbiAgdGhpcy51c2VyUm9sZXMgPSByb2xlTmFtZXMubWFwKHIgPT4ge1xuICAgIHJldHVybiAncm9sZTonICsgcjtcbiAgfSk7XG4gIHRoaXMuZmV0Y2hlZFJvbGVzID0gdHJ1ZTtcbiAgdGhpcy5yb2xlUHJvbWlzZSA9IG51bGw7XG4gIHRoaXMuY2FjaGVSb2xlcygpO1xuICByZXR1cm4gdGhpcy51c2VyUm9sZXM7XG59O1xuXG5BdXRoLnByb3RvdHlwZS5jYWNoZVJvbGVzID0gZnVuY3Rpb24gKCkge1xuICBpZiAoIXRoaXMuY2FjaGVDb250cm9sbGVyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHRoaXMuY2FjaGVDb250cm9sbGVyLnJvbGUucHV0KHRoaXMudXNlci5pZCwgQXJyYXkoLi4udGhpcy51c2VyUm9sZXMpKTtcbiAgcmV0dXJuIHRydWU7XG59O1xuXG5BdXRoLnByb3RvdHlwZS5jbGVhclJvbGVDYWNoZSA9IGZ1bmN0aW9uIChzZXNzaW9uVG9rZW4pIHtcbiAgaWYgKCF0aGlzLmNhY2hlQ29udHJvbGxlcikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB0aGlzLmNhY2hlQ29udHJvbGxlci5yb2xlLmRlbCh0aGlzLnVzZXIuaWQpO1xuICB0aGlzLmNhY2hlQ29udHJvbGxlci51c2VyLmRlbChzZXNzaW9uVG9rZW4pO1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkF1dGgucHJvdG90eXBlLmdldFJvbGVzQnlJZHMgPSBhc3luYyBmdW5jdGlvbiAoaW5zKSB7XG4gIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgLy8gQnVpbGQgYW4gT1IgcXVlcnkgYWNyb3NzIGFsbCBwYXJlbnRSb2xlc1xuICBpZiAoIXRoaXMuY29uZmlnKSB7XG4gICAgYXdhaXQgbmV3IFBhcnNlLlF1ZXJ5KFBhcnNlLlJvbGUpXG4gICAgICAuY29udGFpbmVkSW4oXG4gICAgICAgICdyb2xlcycsXG4gICAgICAgIGlucy5tYXAoaWQgPT4ge1xuICAgICAgICAgIGNvbnN0IHJvbGUgPSBuZXcgUGFyc2UuT2JqZWN0KFBhcnNlLlJvbGUpO1xuICAgICAgICAgIHJvbGUuaWQgPSBpZDtcbiAgICAgICAgICByZXR1cm4gcm9sZTtcbiAgICAgICAgfSlcbiAgICAgIClcbiAgICAgIC5lYWNoKHJlc3VsdCA9PiByZXN1bHRzLnB1c2gocmVzdWx0LnRvSlNPTigpKSwgeyB1c2VNYXN0ZXJLZXk6IHRydWUgfSk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3Qgcm9sZXMgPSBpbnMubWFwKGlkID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICBjbGFzc05hbWU6ICdfUm9sZScsXG4gICAgICAgIG9iamVjdElkOiBpZCxcbiAgICAgIH07XG4gICAgfSk7XG4gICAgY29uc3QgcmVzdFdoZXJlID0geyByb2xlczogeyAkaW46IHJvbGVzIH0gfTtcbiAgICBjb25zdCBSZXN0UXVlcnkgPSByZXF1aXJlKCcuL1Jlc3RRdWVyeScpO1xuICAgIGNvbnN0IHF1ZXJ5ID0gYXdhaXQgUmVzdFF1ZXJ5KHtcbiAgICAgIG1ldGhvZDogUmVzdFF1ZXJ5Lk1ldGhvZC5maW5kLFxuICAgICAgY29uZmlnOiB0aGlzLmNvbmZpZyxcbiAgICAgIHJ1bkJlZm9yZUZpbmQ6IGZhbHNlLFxuICAgICAgYXV0aDogbWFzdGVyKHRoaXMuY29uZmlnKSxcbiAgICAgIGNsYXNzTmFtZTogJ19Sb2xlJyxcbiAgICAgIHJlc3RXaGVyZSxcbiAgICB9KTtcbiAgICBhd2FpdCBxdWVyeS5lYWNoKHJlc3VsdCA9PiByZXN1bHRzLnB1c2gocmVzdWx0KSk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdHM7XG59O1xuXG4vLyBHaXZlbiBhIGxpc3Qgb2Ygcm9sZUlkcywgZmluZCBhbGwgdGhlIHBhcmVudCByb2xlcywgcmV0dXJucyBhIHByb21pc2Ugd2l0aCBhbGwgbmFtZXNcbkF1dGgucHJvdG90eXBlLl9nZXRBbGxSb2xlc05hbWVzRm9yUm9sZUlkcyA9IGZ1bmN0aW9uIChyb2xlSURzLCBuYW1lcyA9IFtdLCBxdWVyaWVkUm9sZXMgPSB7fSkge1xuICBjb25zdCBpbnMgPSByb2xlSURzLmZpbHRlcihyb2xlSUQgPT4ge1xuICAgIGNvbnN0IHdhc1F1ZXJpZWQgPSBxdWVyaWVkUm9sZXNbcm9sZUlEXSAhPT0gdHJ1ZTtcbiAgICBxdWVyaWVkUm9sZXNbcm9sZUlEXSA9IHRydWU7XG4gICAgcmV0dXJuIHdhc1F1ZXJpZWQ7XG4gIH0pO1xuXG4gIC8vIGFsbCByb2xlcyBhcmUgYWNjb3VudGVkIGZvciwgcmV0dXJuIHRoZSBuYW1lc1xuICBpZiAoaW5zLmxlbmd0aCA9PSAwKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShbLi4ubmV3IFNldChuYW1lcyldKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLmdldFJvbGVzQnlJZHMoaW5zKVxuICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgLy8gTm90aGluZyBmb3VuZFxuICAgICAgaWYgKCFyZXN1bHRzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5hbWVzKTtcbiAgICAgIH1cbiAgICAgIC8vIE1hcCB0aGUgcmVzdWx0cyB3aXRoIGFsbCBJZHMgYW5kIG5hbWVzXG4gICAgICBjb25zdCByZXN1bHRNYXAgPSByZXN1bHRzLnJlZHVjZShcbiAgICAgICAgKG1lbW8sIHJvbGUpID0+IHtcbiAgICAgICAgICBtZW1vLm5hbWVzLnB1c2gocm9sZS5uYW1lKTtcbiAgICAgICAgICBtZW1vLmlkcy5wdXNoKHJvbGUub2JqZWN0SWQpO1xuICAgICAgICAgIHJldHVybiBtZW1vO1xuICAgICAgICB9LFxuICAgICAgICB7IGlkczogW10sIG5hbWVzOiBbXSB9XG4gICAgICApO1xuICAgICAgLy8gc3RvcmUgdGhlIG5ldyBmb3VuZCBuYW1lc1xuICAgICAgbmFtZXMgPSBuYW1lcy5jb25jYXQocmVzdWx0TWFwLm5hbWVzKTtcbiAgICAgIC8vIGZpbmQgdGhlIG5leHQgb25lcywgY2lyY3VsYXIgcm9sZXMgd2lsbCBiZSBjdXRcbiAgICAgIHJldHVybiB0aGlzLl9nZXRBbGxSb2xlc05hbWVzRm9yUm9sZUlkcyhyZXN1bHRNYXAuaWRzLCBuYW1lcywgcXVlcmllZFJvbGVzKTtcbiAgICB9KVxuICAgIC50aGVuKG5hbWVzID0+IHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoWy4uLm5ldyBTZXQobmFtZXMpXSk7XG4gICAgfSk7XG59O1xuXG5jb25zdCBmaW5kVXNlcnNXaXRoQXV0aERhdGEgPSBhc3luYyAoY29uZmlnLCBhdXRoRGF0YSwgYmVmb3JlRmluZCkgPT4ge1xuICBjb25zdCBwcm92aWRlcnMgPSBPYmplY3Qua2V5cyhhdXRoRGF0YSk7XG5cbiAgY29uc3QgcXVlcmllcyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgIHByb3ZpZGVycy5tYXAoYXN5bmMgcHJvdmlkZXIgPT4ge1xuICAgICAgY29uc3QgcHJvdmlkZXJBdXRoRGF0YSA9IGF1dGhEYXRhW3Byb3ZpZGVyXTtcblxuICAgICAgY29uc3QgYWRhcHRlciA9IGNvbmZpZy5hdXRoRGF0YU1hbmFnZXIuZ2V0VmFsaWRhdG9yRm9yUHJvdmlkZXIocHJvdmlkZXIpPy5hZGFwdGVyO1xuICAgICAgaWYgKGJlZm9yZUZpbmQgJiYgdHlwZW9mIGFkYXB0ZXI/LmJlZm9yZUZpbmQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgYXdhaXQgYWRhcHRlci5iZWZvcmVGaW5kKHByb3ZpZGVyQXV0aERhdGEpO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXByb3ZpZGVyQXV0aERhdGE/LmlkKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4geyBbYGF1dGhEYXRhLiR7cHJvdmlkZXJ9LmlkYF06IHByb3ZpZGVyQXV0aERhdGEuaWQgfTtcbiAgICB9KVxuICApO1xuXG4gIC8vIEZpbHRlciBvdXQgbnVsbCBxdWVyaWVzXG4gIGNvbnN0IHZhbGlkUXVlcmllcyA9IHF1ZXJpZXMuZmlsdGVyKHF1ZXJ5ID0+IHF1ZXJ5ICE9PSBudWxsKTtcblxuICBpZiAoIXZhbGlkUXVlcmllcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICAvLyBQZXJmb3JtIGRhdGFiYXNlIHF1ZXJ5XG4gIHJldHVybiBjb25maWcuZGF0YWJhc2UuZmluZCgnX1VzZXInLCB7ICRvcjogdmFsaWRRdWVyaWVzIH0sIHsgbGltaXQ6IDIgfSk7XG59O1xuXG5jb25zdCBoYXNNdXRhdGVkQXV0aERhdGEgPSAoYXV0aERhdGEsIHVzZXJBdXRoRGF0YSkgPT4ge1xuICBpZiAoIXVzZXJBdXRoRGF0YSkgeyByZXR1cm4geyBoYXNNdXRhdGVkQXV0aERhdGE6IHRydWUsIG11dGF0ZWRBdXRoRGF0YTogYXV0aERhdGEgfTsgfVxuICBjb25zdCBtdXRhdGVkQXV0aERhdGEgPSB7fTtcbiAgT2JqZWN0LmtleXMoYXV0aERhdGEpLmZvckVhY2gocHJvdmlkZXIgPT4ge1xuICAgIC8vIEFub255bW91cyBwcm92aWRlciBpcyBub3QgaGFuZGxlZCB0aGlzIHdheVxuICAgIGlmIChwcm92aWRlciA9PT0gJ2Fub255bW91cycpIHsgcmV0dXJuOyB9XG4gICAgY29uc3QgcHJvdmlkZXJEYXRhID0gYXV0aERhdGFbcHJvdmlkZXJdO1xuICAgIGNvbnN0IHVzZXJQcm92aWRlckF1dGhEYXRhID0gdXNlckF1dGhEYXRhW3Byb3ZpZGVyXTtcbiAgICBpZiAoIWlzRGVlcFN0cmljdEVxdWFsKHByb3ZpZGVyRGF0YSwgdXNlclByb3ZpZGVyQXV0aERhdGEpKSB7XG4gICAgICBtdXRhdGVkQXV0aERhdGFbcHJvdmlkZXJdID0gcHJvdmlkZXJEYXRhO1xuICAgIH1cbiAgfSk7XG4gIGNvbnN0IGhhc011dGF0ZWRBdXRoRGF0YSA9IE9iamVjdC5rZXlzKG11dGF0ZWRBdXRoRGF0YSkubGVuZ3RoICE9PSAwO1xuICByZXR1cm4geyBoYXNNdXRhdGVkQXV0aERhdGEsIG11dGF0ZWRBdXRoRGF0YSB9O1xufTtcblxuY29uc3QgY2hlY2tJZlVzZXJIYXNQcm92aWRlZENvbmZpZ3VyZWRQcm92aWRlcnNGb3JMb2dpbiA9IChcbiAgcmVxID0ge30sXG4gIGF1dGhEYXRhID0ge30sXG4gIHVzZXJBdXRoRGF0YSA9IHt9LFxuICBjb25maWdcbikgPT4ge1xuICBjb25zdCBzYXZlZFVzZXJQcm92aWRlcnMgPSBPYmplY3Qua2V5cyh1c2VyQXV0aERhdGEpLm1hcChwcm92aWRlciA9PiAoe1xuICAgIG5hbWU6IHByb3ZpZGVyLFxuICAgIGFkYXB0ZXI6IGNvbmZpZy5hdXRoRGF0YU1hbmFnZXIuZ2V0VmFsaWRhdG9yRm9yUHJvdmlkZXIocHJvdmlkZXIpLmFkYXB0ZXIsXG4gIH0pKTtcblxuICBjb25zdCBoYXNQcm92aWRlZEFTb2xvUHJvdmlkZXIgPSBzYXZlZFVzZXJQcm92aWRlcnMuc29tZShcbiAgICBwcm92aWRlciA9PlxuICAgICAgcHJvdmlkZXIgJiYgcHJvdmlkZXIuYWRhcHRlciAmJiBwcm92aWRlci5hZGFwdGVyLnBvbGljeSA9PT0gJ3NvbG8nICYmIGF1dGhEYXRhW3Byb3ZpZGVyLm5hbWVdXG4gICk7XG5cbiAgLy8gU29sbyBwcm92aWRlcnMgY2FuIGJlIGNvbnNpZGVyZWQgYXMgc2FmZSwgc28gd2UgZG8gbm90IGhhdmUgdG8gY2hlY2sgaWYgdGhlIHVzZXIgbmVlZHNcbiAgLy8gdG8gcHJvdmlkZSBhbiBhZGRpdGlvbmFsIHByb3ZpZGVyIHRvIGxvZ2luLiBBbiBhdXRoIGFkYXB0ZXIgd2l0aCBcInNvbG9cIiAobGlrZSB3ZWJhdXRobikgbWVhbnNcbiAgLy8gbm8gXCJhZGRpdGlvbmFsXCIgYXV0aCBuZWVkcyB0byBiZSBwcm92aWRlZCB0byBsb2dpbiAobGlrZSBPVFAsIE1GQSlcbiAgaWYgKGhhc1Byb3ZpZGVkQVNvbG9Qcm92aWRlcikge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGFkZGl0aW9uUHJvdmlkZXJzTm90Rm91bmQgPSBbXTtcbiAgY29uc3QgaGFzUHJvdmlkZWRBdExlYXN0T25lQWRkaXRpb25hbFByb3ZpZGVyID0gc2F2ZWRVc2VyUHJvdmlkZXJzLnNvbWUocHJvdmlkZXIgPT4ge1xuICAgIGxldCBwb2xpY3kgPSBwcm92aWRlci5hZGFwdGVyLnBvbGljeTtcbiAgICBpZiAodHlwZW9mIHBvbGljeSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29uc3QgcmVxdWVzdE9iamVjdCA9IHtcbiAgICAgICAgaXA6IHJlcS5jb25maWcuaXAsXG4gICAgICAgIHVzZXI6IHJlcS5hdXRoLnVzZXIsXG4gICAgICAgIG1hc3RlcjogcmVxLmF1dGguaXNNYXN0ZXIsXG4gICAgICB9O1xuICAgICAgcG9saWN5ID0gcG9saWN5LmNhbGwocHJvdmlkZXIuYWRhcHRlciwgcmVxdWVzdE9iamVjdCwgdXNlckF1dGhEYXRhW3Byb3ZpZGVyLm5hbWVdKTtcbiAgICB9XG4gICAgaWYgKHBvbGljeSA9PT0gJ2FkZGl0aW9uYWwnKSB7XG4gICAgICBpZiAoYXV0aERhdGFbcHJvdmlkZXIubmFtZV0pIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBQdXNoIG1pc3NpbmcgcHJvdmlkZXIgZm9yIGVycm9yIG1lc3NhZ2VcbiAgICAgICAgYWRkaXRpb25Qcm92aWRlcnNOb3RGb3VuZC5wdXNoKHByb3ZpZGVyLm5hbWUpO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIGlmIChoYXNQcm92aWRlZEF0TGVhc3RPbmVBZGRpdGlvbmFsUHJvdmlkZXIgfHwgIWFkZGl0aW9uUHJvdmlkZXJzTm90Rm91bmQubGVuZ3RoKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgIFBhcnNlLkVycm9yLk9USEVSX0NBVVNFLFxuICAgIGBNaXNzaW5nIGFkZGl0aW9uYWwgYXV0aERhdGEgJHthZGRpdGlvblByb3ZpZGVyc05vdEZvdW5kLmpvaW4oJywnKX1gXG4gICk7XG59O1xuXG4vLyBWYWxpZGF0ZSBlYWNoIGF1dGhEYXRhIHN0ZXAtYnktc3RlcCBhbmQgcmV0dXJuIHRoZSBwcm92aWRlciByZXNwb25zZXNcbmNvbnN0IGhhbmRsZUF1dGhEYXRhVmFsaWRhdGlvbiA9IGFzeW5jIChhdXRoRGF0YSwgcmVxLCBmb3VuZFVzZXIpID0+IHtcbiAgbGV0IHVzZXI7XG4gIGlmIChmb3VuZFVzZXIpIHtcbiAgICB1c2VyID0gUGFyc2UuVXNlci5mcm9tSlNPTih7IGNsYXNzTmFtZTogJ19Vc2VyJywgLi4uZm91bmRVc2VyIH0pO1xuICAgIC8vIEZpbmQgdXNlciBieSBzZXNzaW9uIGFuZCBjdXJyZW50IG9iamVjdElkOyBvbmx5IHBhc3MgdXNlciBpZiBpdCdzIHRoZSBjdXJyZW50IHVzZXIgb3IgbWFzdGVyIGtleSBpcyBwcm92aWRlZFxuICB9IGVsc2UgaWYgKFxuICAgIChyZXEuYXV0aCAmJlxuICAgICAgcmVxLmF1dGgudXNlciAmJlxuICAgICAgdHlwZW9mIHJlcS5nZXRVc2VySWQgPT09ICdmdW5jdGlvbicgJiZcbiAgICAgIHJlcS5nZXRVc2VySWQoKSA9PT0gcmVxLmF1dGgudXNlci5pZCkgfHxcbiAgICAocmVxLmF1dGggJiYgcmVxLmF1dGguaXNNYXN0ZXIgJiYgdHlwZW9mIHJlcS5nZXRVc2VySWQgPT09ICdmdW5jdGlvbicgJiYgcmVxLmdldFVzZXJJZCgpKVxuICApIHtcbiAgICB1c2VyID0gbmV3IFBhcnNlLlVzZXIoKTtcbiAgICB1c2VyLmlkID0gcmVxLmF1dGguaXNNYXN0ZXIgPyByZXEuZ2V0VXNlcklkKCkgOiByZXEuYXV0aC51c2VyLmlkO1xuICAgIGF3YWl0IHVzZXIuZmV0Y2goeyB1c2VNYXN0ZXJLZXk6IHRydWUgfSk7XG4gIH1cblxuICBjb25zdCB7IHVwZGF0ZWRPYmplY3QgfSA9IHJlcS5idWlsZFBhcnNlT2JqZWN0cygpO1xuICBjb25zdCByZXF1ZXN0T2JqZWN0ID0gZ2V0UmVxdWVzdE9iamVjdCh1bmRlZmluZWQsIHJlcS5hdXRoLCB1cGRhdGVkT2JqZWN0LCB1c2VyLCByZXEuY29uZmlnKTtcbiAgLy8gUGVyZm9ybSB2YWxpZGF0aW9uIGFzIHN0ZXAtYnktc3RlcCBwaXBlbGluZSBmb3IgYmV0dGVyIGVycm9yIGNvbnNpc3RlbmN5XG4gIC8vIGFuZCBhbHNvIHRvIGF2b2lkIHRvIHRyaWdnZXIgYSBwcm92aWRlciAobGlrZSBPVFAgU01TKSBpZiBhbm90aGVyIG9uZSBmYWlsc1xuICBjb25zdCBhY2MgPSB7IGF1dGhEYXRhOiB7fSwgYXV0aERhdGFSZXNwb25zZToge30gfTtcbiAgY29uc3QgYXV0aEtleXMgPSBPYmplY3Qua2V5cyhhdXRoRGF0YSkuc29ydCgpO1xuICBmb3IgKGNvbnN0IHByb3ZpZGVyIG9mIGF1dGhLZXlzKSB7XG4gICAgbGV0IG1ldGhvZCA9ICcnO1xuICAgIHRyeSB7XG4gICAgICBpZiAoYXV0aERhdGFbcHJvdmlkZXJdID09PSBudWxsKSB7XG4gICAgICAgIGFjYy5hdXRoRGF0YVtwcm92aWRlcl0gPSBudWxsO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHsgdmFsaWRhdG9yIH0gPSByZXEuY29uZmlnLmF1dGhEYXRhTWFuYWdlci5nZXRWYWxpZGF0b3JGb3JQcm92aWRlcihwcm92aWRlcikgfHwge307XG4gICAgICBjb25zdCBhdXRoUHJvdmlkZXIgPSAocmVxLmNvbmZpZy5hdXRoIHx8IHt9KVtwcm92aWRlcl0gfHwge307XG4gICAgICBpZiAoIXZhbGlkYXRvciB8fCBhdXRoUHJvdmlkZXIuZW5hYmxlZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLlVOU1VQUE9SVEVEX1NFUlZJQ0UsXG4gICAgICAgICAgJ1RoaXMgYXV0aGVudGljYXRpb24gbWV0aG9kIGlzIHVuc3VwcG9ydGVkLidcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGxldCB2YWxpZGF0aW9uUmVzdWx0ID0gYXdhaXQgdmFsaWRhdG9yKGF1dGhEYXRhW3Byb3ZpZGVyXSwgcmVxLCB1c2VyLCByZXF1ZXN0T2JqZWN0KTtcbiAgICAgIG1ldGhvZCA9IHZhbGlkYXRpb25SZXN1bHQgJiYgdmFsaWRhdGlvblJlc3VsdC5tZXRob2Q7XG4gICAgICByZXF1ZXN0T2JqZWN0LnRyaWdnZXJOYW1lID0gbWV0aG9kO1xuICAgICAgaWYgKHZhbGlkYXRpb25SZXN1bHQgJiYgdmFsaWRhdGlvblJlc3VsdC52YWxpZGF0b3IpIHtcbiAgICAgICAgdmFsaWRhdGlvblJlc3VsdCA9IGF3YWl0IHZhbGlkYXRpb25SZXN1bHQudmFsaWRhdG9yKCk7XG4gICAgICB9XG4gICAgICBpZiAoIXZhbGlkYXRpb25SZXN1bHQpIHtcbiAgICAgICAgYWNjLmF1dGhEYXRhW3Byb3ZpZGVyXSA9IGF1dGhEYXRhW3Byb3ZpZGVyXTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoIU9iamVjdC5rZXlzKHZhbGlkYXRpb25SZXN1bHQpLmxlbmd0aCkge1xuICAgICAgICBhY2MuYXV0aERhdGFbcHJvdmlkZXJdID0gYXV0aERhdGFbcHJvdmlkZXJdO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHZhbGlkYXRpb25SZXN1bHQucmVzcG9uc2UpIHtcbiAgICAgICAgYWNjLmF1dGhEYXRhUmVzcG9uc2VbcHJvdmlkZXJdID0gdmFsaWRhdGlvblJlc3VsdC5yZXNwb25zZTtcbiAgICAgIH1cbiAgICAgIC8vIFNvbWUgYXV0aCBwcm92aWRlcnMgYWZ0ZXIgaW5pdGlhbGl6YXRpb24gd2lsbCBhdm9pZCB0byByZXBsYWNlIGF1dGhEYXRhIGFscmVhZHkgc3RvcmVkXG4gICAgICBpZiAoIXZhbGlkYXRpb25SZXN1bHQuZG9Ob3RTYXZlKSB7XG4gICAgICAgIGFjYy5hdXRoRGF0YVtwcm92aWRlcl0gPSB2YWxpZGF0aW9uUmVzdWx0LnNhdmUgfHwgYXV0aERhdGFbcHJvdmlkZXJdO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc3QgZSA9IHJlc29sdmVFcnJvcihlcnIsIHtcbiAgICAgICAgY29kZTogUGFyc2UuRXJyb3IuU0NSSVBUX0ZBSUxFRCxcbiAgICAgICAgbWVzc2FnZTogJ0F1dGggZmFpbGVkLiBVbmtub3duIGVycm9yLicsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHVzZXJTdHJpbmcgPVxuICAgICAgICByZXEuYXV0aCAmJiByZXEuYXV0aC51c2VyID8gcmVxLmF1dGgudXNlci5pZCA6IHJlcS5kYXRhLm9iamVjdElkIHx8IHVuZGVmaW5lZDtcbiAgICAgIGxvZ2dlci5lcnJvcihcbiAgICAgICAgYEZhaWxlZCBydW5uaW5nIGF1dGggc3RlcCAke21ldGhvZH0gZm9yICR7cHJvdmlkZXJ9IGZvciB1c2VyICR7dXNlclN0cmluZ30gd2l0aCBFcnJvcjogYCArXG4gICAgICAgICAgSlNPTi5zdHJpbmdpZnkoZSksXG4gICAgICAgIHtcbiAgICAgICAgICBhdXRoZW50aWNhdGlvblN0ZXA6IG1ldGhvZCxcbiAgICAgICAgICBlcnJvcjogZSxcbiAgICAgICAgICB1c2VyOiB1c2VyU3RyaW5nLFxuICAgICAgICAgIHByb3ZpZGVyLFxuICAgICAgICB9XG4gICAgICApO1xuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGFjYztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBBdXRoLFxuICBtYXN0ZXIsXG4gIG1haW50ZW5hbmNlLFxuICBub2JvZHksXG4gIHJlYWRPbmx5LFxuICBzaG91bGRVcGRhdGVTZXNzaW9uRXhwaXJ5LFxuICBnZXRBdXRoRm9yU2Vzc2lvblRva2VuLFxuICBnZXRBdXRoRm9yTGVnYWN5U2Vzc2lvblRva2VuLFxuICBmaW5kVXNlcnNXaXRoQXV0aERhdGEsXG4gIGhhc011dGF0ZWRBdXRoRGF0YSxcbiAgY2hlY2tJZlVzZXJIYXNQcm92aWRlZENvbmZpZ3VyZWRQcm92aWRlcnNGb3JMb2dpbixcbiAgaGFuZGxlQXV0aERhdGFWYWxpZGF0aW9uLFxufTtcbiJdLCJtYXBwaW5ncyI6Ijs7QUFDQSxJQUFBQSxLQUFBLEdBQUFDLE9BQUE7QUFDQSxJQUFBQyxTQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxPQUFBLEdBQUFGLE9BQUE7QUFDQSxJQUFBRyxTQUFBLEdBQUFILE9BQUE7QUFDQSxJQUFBSSxVQUFBLEdBQUFDLHNCQUFBLENB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QyxDQUFDdkcsTUFBTSxFQUFFO1FBQ3pDK0YsR0FBRyxDQUFDMUMsUUFBUSxDQUFDTSxRQUFRLENBQUMsR0FBR04sUUFBUSxDQUFDTSxRQUFRLENBQUM7UUFDM0M7TUFDRjtNQUVBLElBQUk0QyxnQkFBZ0IsQ0FBQzNGLFFBQVEsRUFBRTtRQUM3Qm1GLEdBQUcsQ0FBQ0MsZ0JBQWdCLENBQUNyQyxRQUFRLENBQUMsR0FBRzRDLGdCQUFnQixDQUFDM0YsUUFBUTtNQUM1RDtNQUNBO01BQ0EsSUFBSSxDQUFDMkYsZ0JBQWdCLENBQUNFLFNBQVMsRUFBRTtRQUMvQlYsR0FBRyxDQUFDMUMsUUFBUSxDQUFDTSxRQUFRLENBQUMsR0FBRzRDLGdCQUFnQixDQUFDRyxJQUFJLElBQUlyRCxRQUFRLENBQUNNLFFBQVEsQ0FBQztNQUN0RTtJQUNGLENBQUMsQ0FBQyxPQUFPZ0QsR0FBRyxFQUFFO01BQ1osTUFBTTFMLENBQUMsR0FBRyxJQUFBMkwsc0JBQVksRUFBQ0QsR0FBRyxFQUFFO1FBQzFCaEksSUFBSSxFQUFFdkQsS0FBSyxDQUFDd0QsS0FBSyxDQUFDaUksYUFBYTtRQUMvQkMsT0FBTyxFQUFFO01BQ1gsQ0FBQyxDQUFDO01BQ0YsTUFBTUMsVUFBVSxHQUNkcEMsR0FBRyxDQUFDN0csSUFBSSxJQUFJNkcsR0FBRyxDQUFDN0csSUFBSSxDQUFDbEMsSUFBSSxHQUFHK0ksR0FBRyxDQUFDN0csSUFBSSxDQUFDbEMsSUFBSSxDQUFDc0YsRUFBRSxHQUFHeUQsR0FBRyxDQUFDcUMsSUFBSSxDQUFDdkksUUFBUSxJQUFJakQsU0FBUztNQUMvRXNELGNBQU0sQ0FBQ0MsS0FBSyxDQUNWLDRCQUE0Qm5CLE1BQU0sUUFBUStGLFFBQVEsYUFBYW9ELFVBQVUsZUFBZSxHQUN0RkUsSUFBSSxDQUFDQyxTQUFTLENBQUNqTSxDQUFDLENBQUMsRUFDbkI7UUFDRWtNLGtCQUFrQixFQUFFdkosTUFBTTtRQUMxQm1CLEtBQUssRUFBRTlELENBQUM7UUFDUlcsSUFBSSxFQUFFbUwsVUFBVTtRQUNoQnBEO01BQ0YsQ0FDRixDQUFDO01BQ0QsTUFBTTFJLENBQUM7SUFDVDtFQUNGO0VBQ0EsT0FBTzhLLEdBQUc7QUFDWixDQUFDO0FBRURxQixNQUFNLENBQUNDLE9BQU8sR0FBRztFQUNmaE0sSUFBSTtFQUNKYyxNQUFNO0VBQ05DLFdBQVc7RUFDWEUsTUFBTTtFQUNORCxRQUFRO0VBQ1JNLHlCQUF5QjtFQUN6QnFDLHNCQUFzQjtFQUN0QnlCLDRCQUE0QjtFQUM1QjJDLHFCQUFxQjtFQUNyQmUsa0JBQWtCO0VBQ2xCTyxpREFBaUQ7RUFDakRhO0FBQ0YsQ0FBQyIsImlnbm9yZUxpc3QiOltdfQ==
|