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/triggers.js
CHANGED
|
@@ -1,51 +1,66 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.Types =
|
|
6
|
+
exports.Types = void 0;
|
|
7
|
+
exports._unregisterAll = _unregisterAll;
|
|
8
|
+
exports.addConnectTrigger = addConnectTrigger;
|
|
7
9
|
exports.addFunction = addFunction;
|
|
8
10
|
exports.addJob = addJob;
|
|
9
|
-
exports.addTrigger = addTrigger;
|
|
10
11
|
exports.addLiveQueryEventHandler = addLiveQueryEventHandler;
|
|
11
|
-
exports.
|
|
12
|
-
exports.
|
|
13
|
-
exports._unregisterAll = _unregisterAll;
|
|
14
|
-
exports.getTrigger = getTrigger;
|
|
15
|
-
exports.triggerExists = triggerExists;
|
|
12
|
+
exports.addTrigger = addTrigger;
|
|
13
|
+
exports.getClassName = getClassName;
|
|
16
14
|
exports.getFunction = getFunction;
|
|
15
|
+
exports.getFunctionNames = getFunctionNames;
|
|
17
16
|
exports.getJob = getJob;
|
|
18
17
|
exports.getJobs = getJobs;
|
|
19
|
-
exports.
|
|
18
|
+
exports.getRequestFileObject = getRequestFileObject;
|
|
20
19
|
exports.getRequestObject = getRequestObject;
|
|
21
20
|
exports.getRequestQueryObject = getRequestQueryObject;
|
|
22
21
|
exports.getResponseObject = getResponseObject;
|
|
22
|
+
exports.getTrigger = getTrigger;
|
|
23
|
+
exports.getValidator = getValidator;
|
|
24
|
+
exports.inflate = inflate;
|
|
23
25
|
exports.maybeRunAfterFindTrigger = maybeRunAfterFindTrigger;
|
|
26
|
+
exports.maybeRunFileTrigger = maybeRunFileTrigger;
|
|
27
|
+
exports.maybeRunGlobalConfigTrigger = maybeRunGlobalConfigTrigger;
|
|
24
28
|
exports.maybeRunQueryTrigger = maybeRunQueryTrigger;
|
|
25
29
|
exports.maybeRunTrigger = maybeRunTrigger;
|
|
26
|
-
exports.
|
|
30
|
+
exports.maybeRunValidator = maybeRunValidator;
|
|
31
|
+
exports.removeFunction = removeFunction;
|
|
32
|
+
exports.removeTrigger = removeTrigger;
|
|
33
|
+
exports.resolveError = resolveError;
|
|
27
34
|
exports.runLiveQueryEventHandlers = runLiveQueryEventHandlers;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
var
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
36
|
-
|
|
35
|
+
exports.runTrigger = runTrigger;
|
|
36
|
+
exports.toJSONwithObjects = toJSONwithObjects;
|
|
37
|
+
exports.triggerExists = triggerExists;
|
|
38
|
+
var _node = _interopRequireDefault(require("parse/node"));
|
|
39
|
+
var _logger = require("./logger");
|
|
40
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
37
41
|
// triggers.js
|
|
42
|
+
|
|
38
43
|
const Types = exports.Types = {
|
|
44
|
+
beforeLogin: 'beforeLogin',
|
|
45
|
+
afterLogin: 'afterLogin',
|
|
46
|
+
afterLogout: 'afterLogout',
|
|
47
|
+
beforePasswordResetRequest: 'beforePasswordResetRequest',
|
|
39
48
|
beforeSave: 'beforeSave',
|
|
40
49
|
afterSave: 'afterSave',
|
|
41
50
|
beforeDelete: 'beforeDelete',
|
|
42
51
|
afterDelete: 'afterDelete',
|
|
43
52
|
beforeFind: 'beforeFind',
|
|
44
|
-
afterFind: 'afterFind'
|
|
53
|
+
afterFind: 'afterFind',
|
|
54
|
+
beforeConnect: 'beforeConnect',
|
|
55
|
+
beforeSubscribe: 'beforeSubscribe',
|
|
56
|
+
afterEvent: 'afterEvent'
|
|
45
57
|
};
|
|
46
|
-
|
|
58
|
+
const ConnectClassName = '@Connect';
|
|
47
59
|
const baseStore = function () {
|
|
48
|
-
const Validators = {
|
|
60
|
+
const Validators = Object.keys(Types).reduce(function (base, key) {
|
|
61
|
+
base[key] = {};
|
|
62
|
+
return base;
|
|
63
|
+
}, {});
|
|
49
64
|
const Functions = {};
|
|
50
65
|
const Jobs = {};
|
|
51
66
|
const LiveQuery = [];
|
|
@@ -53,7 +68,6 @@ const baseStore = function () {
|
|
|
53
68
|
base[key] = {};
|
|
54
69
|
return base;
|
|
55
70
|
}, {});
|
|
56
|
-
|
|
57
71
|
return Object.freeze({
|
|
58
72
|
Functions,
|
|
59
73
|
Jobs,
|
|
@@ -62,94 +76,180 @@ const baseStore = function () {
|
|
|
62
76
|
LiveQuery
|
|
63
77
|
});
|
|
64
78
|
};
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
79
|
+
function getClassName(parseClass) {
|
|
80
|
+
if (parseClass && parseClass.className) {
|
|
81
|
+
return parseClass.className;
|
|
82
|
+
}
|
|
83
|
+
if (parseClass && parseClass.name) {
|
|
84
|
+
return parseClass.name.replace('Parse', '@');
|
|
70
85
|
}
|
|
86
|
+
return parseClass;
|
|
87
|
+
}
|
|
88
|
+
function validateClassNameForTriggers(className, type) {
|
|
71
89
|
if (type == Types.beforeSave && className === '_PushStatus') {
|
|
72
90
|
// _PushStatus uses undocumented nested key increment ops
|
|
73
91
|
// allowing beforeSave would mess up the objects big time
|
|
74
92
|
// TODO: Allow proper documented way of using nested increment ops
|
|
75
93
|
throw 'Only afterSave is allowed on _PushStatus';
|
|
76
94
|
}
|
|
95
|
+
if ((type === Types.beforeLogin || type === Types.afterLogin || type === Types.beforePasswordResetRequest) && className !== '_User') {
|
|
96
|
+
// TODO: check if upstream code will handle `Error` instance rather
|
|
97
|
+
// than this anti-pattern of throwing strings
|
|
98
|
+
throw 'Only the _User class is allowed for the beforeLogin, afterLogin, and beforePasswordResetRequest triggers';
|
|
99
|
+
}
|
|
100
|
+
if (type === Types.afterLogout && className !== '_Session') {
|
|
101
|
+
// TODO: check if upstream code will handle `Error` instance rather
|
|
102
|
+
// than this anti-pattern of throwing strings
|
|
103
|
+
throw 'Only the _Session class is allowed for the afterLogout trigger.';
|
|
104
|
+
}
|
|
105
|
+
if (className === '_Session' && type !== Types.afterLogout) {
|
|
106
|
+
// TODO: check if upstream code will handle `Error` instance rather
|
|
107
|
+
// than this anti-pattern of throwing strings
|
|
108
|
+
throw 'Only the afterLogout trigger is allowed for the _Session class.';
|
|
109
|
+
}
|
|
77
110
|
return className;
|
|
78
111
|
}
|
|
79
|
-
|
|
80
112
|
const _triggerStore = {};
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
113
|
+
const Category = {
|
|
114
|
+
Functions: 'Functions',
|
|
115
|
+
Validators: 'Validators',
|
|
116
|
+
Jobs: 'Jobs',
|
|
117
|
+
Triggers: 'Triggers'
|
|
118
|
+
};
|
|
119
|
+
function getStore(category, name, applicationId) {
|
|
120
|
+
const invalidNameRegex = /['"`]/;
|
|
121
|
+
if (invalidNameRegex.test(name)) {
|
|
122
|
+
// Prevent a malicious user from injecting properties into the store
|
|
123
|
+
return {};
|
|
124
|
+
}
|
|
125
|
+
const path = name.split('.');
|
|
126
|
+
path.splice(-1); // remove last component
|
|
127
|
+
applicationId = applicationId || _node.default.applicationId;
|
|
84
128
|
_triggerStore[applicationId] = _triggerStore[applicationId] || baseStore();
|
|
85
|
-
_triggerStore[applicationId]
|
|
86
|
-
|
|
129
|
+
let store = _triggerStore[applicationId][category];
|
|
130
|
+
for (const component of path) {
|
|
131
|
+
store = store[component];
|
|
132
|
+
if (!store) {
|
|
133
|
+
return {};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return store;
|
|
137
|
+
}
|
|
138
|
+
function add(category, name, handler, applicationId) {
|
|
139
|
+
const lastComponent = name.split('.').splice(-1);
|
|
140
|
+
const store = getStore(category, name, applicationId);
|
|
141
|
+
if (store[lastComponent]) {
|
|
142
|
+
_logger.logger.warn(`Warning: Duplicate cloud functions exist for ${lastComponent}. Only the last one will be used and the others will be ignored.`);
|
|
143
|
+
}
|
|
144
|
+
store[lastComponent] = handler;
|
|
145
|
+
}
|
|
146
|
+
function remove(category, name, applicationId) {
|
|
147
|
+
const lastComponent = name.split('.').splice(-1);
|
|
148
|
+
const store = getStore(category, name, applicationId);
|
|
149
|
+
delete store[lastComponent];
|
|
150
|
+
}
|
|
151
|
+
function get(category, name, applicationId) {
|
|
152
|
+
const lastComponent = name.split('.').splice(-1);
|
|
153
|
+
const store = getStore(category, name, applicationId);
|
|
154
|
+
return store[lastComponent];
|
|
155
|
+
}
|
|
156
|
+
function addFunction(functionName, handler, validationHandler, applicationId) {
|
|
157
|
+
add(Category.Functions, functionName, handler, applicationId);
|
|
158
|
+
add(Category.Validators, functionName, validationHandler, applicationId);
|
|
87
159
|
}
|
|
88
|
-
|
|
89
160
|
function addJob(jobName, handler, applicationId) {
|
|
90
|
-
|
|
91
|
-
_triggerStore[applicationId] = _triggerStore[applicationId] || baseStore();
|
|
92
|
-
_triggerStore[applicationId].Jobs[jobName] = handler;
|
|
161
|
+
add(Category.Jobs, jobName, handler, applicationId);
|
|
93
162
|
}
|
|
94
|
-
|
|
95
|
-
function addTrigger(type, className, handler, applicationId) {
|
|
163
|
+
function addTrigger(type, className, handler, applicationId, validationHandler) {
|
|
96
164
|
validateClassNameForTriggers(className, type);
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
165
|
+
add(Category.Triggers, `${type}.${className}`, handler, applicationId);
|
|
166
|
+
add(Category.Validators, `${type}.${className}`, validationHandler, applicationId);
|
|
167
|
+
}
|
|
168
|
+
function addConnectTrigger(type, handler, applicationId, validationHandler) {
|
|
169
|
+
add(Category.Triggers, `${type}.${ConnectClassName}`, handler, applicationId);
|
|
170
|
+
add(Category.Validators, `${type}.${ConnectClassName}`, validationHandler, applicationId);
|
|
100
171
|
}
|
|
101
|
-
|
|
102
172
|
function addLiveQueryEventHandler(handler, applicationId) {
|
|
103
|
-
applicationId = applicationId ||
|
|
173
|
+
applicationId = applicationId || _node.default.applicationId;
|
|
104
174
|
_triggerStore[applicationId] = _triggerStore[applicationId] || baseStore();
|
|
105
175
|
_triggerStore[applicationId].LiveQuery.push(handler);
|
|
106
176
|
}
|
|
107
|
-
|
|
108
177
|
function removeFunction(functionName, applicationId) {
|
|
109
|
-
|
|
110
|
-
delete _triggerStore[applicationId].Functions[functionName];
|
|
178
|
+
remove(Category.Functions, functionName, applicationId);
|
|
111
179
|
}
|
|
112
|
-
|
|
113
180
|
function removeTrigger(type, className, applicationId) {
|
|
114
|
-
|
|
115
|
-
delete _triggerStore[applicationId].Triggers[type][className];
|
|
181
|
+
remove(Category.Triggers, `${type}.${className}`, applicationId);
|
|
116
182
|
}
|
|
117
|
-
|
|
118
183
|
function _unregisterAll() {
|
|
119
184
|
Object.keys(_triggerStore).forEach(appId => delete _triggerStore[appId]);
|
|
120
185
|
}
|
|
121
|
-
|
|
186
|
+
function toJSONwithObjects(object, className) {
|
|
187
|
+
if (!object || !object.toJSON) {
|
|
188
|
+
return {};
|
|
189
|
+
}
|
|
190
|
+
const toJSON = object.toJSON();
|
|
191
|
+
const stateController = _node.default.CoreManager.getObjectStateController();
|
|
192
|
+
const [pending] = stateController.getPendingOps(object._getStateIdentifier());
|
|
193
|
+
for (const key in pending) {
|
|
194
|
+
const val = object.get(key);
|
|
195
|
+
if (!val || !val._toFullJSON) {
|
|
196
|
+
toJSON[key] = val;
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
toJSON[key] = val._toFullJSON();
|
|
200
|
+
}
|
|
201
|
+
// Preserve original object's className if no override className is provided
|
|
202
|
+
if (className) {
|
|
203
|
+
toJSON.className = className;
|
|
204
|
+
} else if (object.className && !toJSON.className) {
|
|
205
|
+
toJSON.className = object.className;
|
|
206
|
+
}
|
|
207
|
+
return toJSON;
|
|
208
|
+
}
|
|
122
209
|
function getTrigger(className, triggerType, applicationId) {
|
|
123
210
|
if (!applicationId) {
|
|
124
|
-
throw
|
|
211
|
+
throw 'Missing ApplicationID';
|
|
125
212
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
213
|
+
return get(Category.Triggers, `${triggerType}.${className}`, applicationId);
|
|
214
|
+
}
|
|
215
|
+
async function runTrigger(trigger, name, request, auth) {
|
|
216
|
+
if (!trigger) {
|
|
217
|
+
return;
|
|
129
218
|
}
|
|
130
|
-
|
|
219
|
+
await maybeRunValidator(request, name, auth);
|
|
220
|
+
if (request.skipWithMasterKey) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
return await trigger(request);
|
|
131
224
|
}
|
|
132
|
-
|
|
133
225
|
function triggerExists(className, type, applicationId) {
|
|
134
226
|
return getTrigger(className, type, applicationId) != undefined;
|
|
135
227
|
}
|
|
136
|
-
|
|
137
228
|
function getFunction(functionName, applicationId) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
|
|
229
|
+
return get(Category.Functions, functionName, applicationId);
|
|
230
|
+
}
|
|
231
|
+
function getFunctionNames(applicationId) {
|
|
232
|
+
const store = _triggerStore[applicationId] && _triggerStore[applicationId][Category.Functions] || {};
|
|
233
|
+
const functionNames = [];
|
|
234
|
+
const extractFunctionNames = (namespace, store) => {
|
|
235
|
+
Object.keys(store).forEach(name => {
|
|
236
|
+
const value = store[name];
|
|
237
|
+
if (namespace) {
|
|
238
|
+
name = `${namespace}.${name}`;
|
|
239
|
+
}
|
|
240
|
+
if (typeof value === 'function') {
|
|
241
|
+
functionNames.push(name);
|
|
242
|
+
} else {
|
|
243
|
+
extractFunctionNames(name, value);
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
|
+
};
|
|
247
|
+
extractFunctionNames(null, store);
|
|
248
|
+
return functionNames;
|
|
143
249
|
}
|
|
144
|
-
|
|
145
250
|
function getJob(jobName, applicationId) {
|
|
146
|
-
|
|
147
|
-
if (manager && manager.Jobs) {
|
|
148
|
-
return manager.Jobs[jobName];
|
|
149
|
-
}
|
|
150
|
-
return undefined;
|
|
251
|
+
return get(Category.Jobs, jobName, applicationId);
|
|
151
252
|
}
|
|
152
|
-
|
|
153
253
|
function getJobs(applicationId) {
|
|
154
254
|
var manager = _triggerStore[applicationId];
|
|
155
255
|
if (manager && manager.Jobs) {
|
|
@@ -157,29 +257,29 @@ function getJobs(applicationId) {
|
|
|
157
257
|
}
|
|
158
258
|
return undefined;
|
|
159
259
|
}
|
|
160
|
-
|
|
161
260
|
function getValidator(functionName, applicationId) {
|
|
162
|
-
|
|
163
|
-
if (manager && manager.Validators) {
|
|
164
|
-
return manager.Validators[functionName];
|
|
165
|
-
}
|
|
166
|
-
return undefined;
|
|
261
|
+
return get(Category.Validators, functionName, applicationId);
|
|
167
262
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
var request = {
|
|
263
|
+
function getRequestObject(triggerType, auth, parseObject, originalParseObject, config, context, isGet) {
|
|
264
|
+
const request = {
|
|
171
265
|
triggerName: triggerType,
|
|
172
266
|
object: parseObject,
|
|
173
267
|
master: false,
|
|
174
268
|
log: config.loggerController,
|
|
175
269
|
headers: config.headers,
|
|
176
|
-
ip: config.ip
|
|
270
|
+
ip: config.ip,
|
|
271
|
+
config
|
|
177
272
|
};
|
|
178
|
-
|
|
273
|
+
if (isGet !== undefined) {
|
|
274
|
+
request.isGet = !!isGet;
|
|
275
|
+
}
|
|
179
276
|
if (originalParseObject) {
|
|
180
277
|
request.original = originalParseObject;
|
|
181
278
|
}
|
|
182
|
-
|
|
279
|
+
if (triggerType === Types.beforeSave || triggerType === Types.afterSave || triggerType === Types.beforeDelete || triggerType === Types.afterDelete || triggerType === Types.beforeLogin || triggerType === Types.afterLogin || triggerType === Types.beforePasswordResetRequest || triggerType === Types.afterFind) {
|
|
280
|
+
// Set a copy of the context on the request object.
|
|
281
|
+
request.context = Object.assign({}, context);
|
|
282
|
+
}
|
|
183
283
|
if (!auth) {
|
|
184
284
|
return request;
|
|
185
285
|
}
|
|
@@ -194,10 +294,8 @@ function getRequestObject(triggerType, auth, parseObject, originalParseObject, c
|
|
|
194
294
|
}
|
|
195
295
|
return request;
|
|
196
296
|
}
|
|
197
|
-
|
|
198
|
-
function getRequestQueryObject(triggerType, auth, query, count, config, isGet) {
|
|
297
|
+
function getRequestQueryObject(triggerType, auth, query, count, config, context, isGet) {
|
|
199
298
|
isGet = !!isGet;
|
|
200
|
-
|
|
201
299
|
var request = {
|
|
202
300
|
triggerName: triggerType,
|
|
203
301
|
query,
|
|
@@ -206,9 +304,10 @@ function getRequestQueryObject(triggerType, auth, query, count, config, isGet) {
|
|
|
206
304
|
log: config.loggerController,
|
|
207
305
|
isGet,
|
|
208
306
|
headers: config.headers,
|
|
209
|
-
ip: config.ip
|
|
307
|
+
ip: config.ip,
|
|
308
|
+
context: context || {},
|
|
309
|
+
config
|
|
210
310
|
};
|
|
211
|
-
|
|
212
311
|
if (!auth) {
|
|
213
312
|
return request;
|
|
214
313
|
}
|
|
@@ -236,102 +335,139 @@ function getResponseObject(request, resolve, reject) {
|
|
|
236
335
|
response = request.objects;
|
|
237
336
|
}
|
|
238
337
|
response = response.map(object => {
|
|
239
|
-
return object
|
|
338
|
+
return toJSONwithObjects(object);
|
|
240
339
|
});
|
|
241
340
|
return resolve(response);
|
|
242
341
|
}
|
|
243
342
|
// Use the JSON response
|
|
244
|
-
if (response && !request.object.equals(response) && request.triggerName === Types.beforeSave) {
|
|
343
|
+
if (response && typeof response === 'object' && !request.object.equals(response) && request.triggerName === Types.beforeSave) {
|
|
344
|
+
return resolve(response);
|
|
345
|
+
}
|
|
346
|
+
if (response && typeof response === 'object' && request.triggerName === Types.afterSave) {
|
|
245
347
|
return resolve(response);
|
|
246
348
|
}
|
|
349
|
+
if (request.triggerName === Types.afterSave) {
|
|
350
|
+
return resolve();
|
|
351
|
+
}
|
|
247
352
|
response = {};
|
|
248
353
|
if (request.triggerName === Types.beforeSave) {
|
|
249
354
|
response['object'] = request.object._getSaveJSON();
|
|
355
|
+
response['object']['objectId'] = request.object.id;
|
|
250
356
|
}
|
|
251
357
|
return resolve(response);
|
|
252
358
|
},
|
|
253
|
-
error: function (
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
code = _node2.default.Error.SCRIPT_FAILED;
|
|
260
|
-
}
|
|
261
|
-
var scriptError = new _node2.default.Error(code, message);
|
|
262
|
-
return reject(scriptError);
|
|
359
|
+
error: function (error) {
|
|
360
|
+
const e = resolveError(error, {
|
|
361
|
+
code: _node.default.Error.SCRIPT_FAILED,
|
|
362
|
+
message: 'Script failed. Unknown error.'
|
|
363
|
+
});
|
|
364
|
+
reject(e);
|
|
263
365
|
}
|
|
264
366
|
};
|
|
265
367
|
}
|
|
266
|
-
|
|
267
368
|
function userIdForLog(auth) {
|
|
268
369
|
return auth && auth.user ? auth.user.id : undefined;
|
|
269
370
|
}
|
|
270
|
-
|
|
271
|
-
|
|
371
|
+
function logTriggerAfterHook(triggerType, className, input, auth, logLevel) {
|
|
372
|
+
if (logLevel === 'silent') {
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
272
375
|
const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(input));
|
|
273
|
-
_logger.logger
|
|
376
|
+
_logger.logger[logLevel](`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}`, {
|
|
274
377
|
className,
|
|
275
378
|
triggerType,
|
|
276
379
|
user: userIdForLog(auth)
|
|
277
380
|
});
|
|
278
381
|
}
|
|
279
|
-
|
|
280
|
-
|
|
382
|
+
function logTriggerSuccessBeforeHook(triggerType, className, input, result, auth, logLevel) {
|
|
383
|
+
if (logLevel === 'silent') {
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
281
386
|
const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(input));
|
|
282
387
|
const cleanResult = _logger.logger.truncateLogMessage(JSON.stringify(result));
|
|
283
|
-
_logger.logger
|
|
388
|
+
_logger.logger[logLevel](`${triggerType} triggered for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Result: ${cleanResult}`, {
|
|
284
389
|
className,
|
|
285
390
|
triggerType,
|
|
286
391
|
user: userIdForLog(auth)
|
|
287
392
|
});
|
|
288
393
|
}
|
|
289
|
-
|
|
290
|
-
|
|
394
|
+
function logTriggerErrorBeforeHook(triggerType, className, input, auth, error, logLevel) {
|
|
395
|
+
if (logLevel === 'silent') {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
291
398
|
const cleanInput = _logger.logger.truncateLogMessage(JSON.stringify(input));
|
|
292
|
-
_logger.logger
|
|
399
|
+
_logger.logger[logLevel](`${triggerType} failed for ${className} for user ${userIdForLog(auth)}:\n Input: ${cleanInput}\n Error: ${JSON.stringify(error)}`, {
|
|
293
400
|
className,
|
|
294
401
|
triggerType,
|
|
295
402
|
error,
|
|
296
403
|
user: userIdForLog(auth)
|
|
297
404
|
});
|
|
298
405
|
}
|
|
299
|
-
|
|
300
|
-
function maybeRunAfterFindTrigger(triggerType, auth, className, objects, config) {
|
|
406
|
+
function maybeRunAfterFindTrigger(triggerType, auth, classNameQuery, objectsInput, config, query, context, isGet) {
|
|
301
407
|
return new Promise((resolve, reject) => {
|
|
302
|
-
const trigger = getTrigger(
|
|
408
|
+
const trigger = getTrigger(classNameQuery, triggerType, config.applicationId);
|
|
303
409
|
if (!trigger) {
|
|
304
|
-
|
|
410
|
+
if (objectsInput && objectsInput.length > 0 && objectsInput[0] instanceof _node.default.Object) {
|
|
411
|
+
return resolve(objectsInput.map(obj => toJSONwithObjects(obj)));
|
|
412
|
+
}
|
|
413
|
+
return resolve(objectsInput || []);
|
|
305
414
|
}
|
|
306
|
-
const request = getRequestObject(triggerType, auth, null, null, config);
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
415
|
+
const request = getRequestObject(triggerType, auth, null, null, config, context, isGet);
|
|
416
|
+
// Convert query parameter to Parse.Query instance
|
|
417
|
+
if (query instanceof _node.default.Query) {
|
|
418
|
+
request.query = query;
|
|
419
|
+
} else if (typeof query === 'object' && query !== null) {
|
|
420
|
+
const parseQueryInstance = new _node.default.Query(classNameQuery);
|
|
421
|
+
if (query.where) {
|
|
422
|
+
parseQueryInstance.withJSON(query);
|
|
423
|
+
}
|
|
424
|
+
request.query = parseQueryInstance;
|
|
425
|
+
} else {
|
|
426
|
+
request.query = new _node.default.Query(classNameQuery);
|
|
427
|
+
}
|
|
428
|
+
const {
|
|
429
|
+
success,
|
|
430
|
+
error
|
|
431
|
+
} = getResponseObject(request, processedObjectsJSON => {
|
|
432
|
+
resolve(processedObjectsJSON);
|
|
433
|
+
}, errorData => {
|
|
434
|
+
reject(errorData);
|
|
311
435
|
});
|
|
312
|
-
logTriggerSuccessBeforeHook(triggerType,
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
436
|
+
logTriggerSuccessBeforeHook(triggerType, classNameQuery, 'AfterFind Input (Pre-Transform)', JSON.stringify(objectsInput.map(o => o instanceof _node.default.Object ? o.id + ':' + o.className : o)), auth, config.logLevels.triggerBeforeSuccess);
|
|
437
|
+
|
|
438
|
+
// Convert plain objects to Parse.Object instances for trigger
|
|
439
|
+
request.objects = objectsInput.map(currentObject => {
|
|
440
|
+
if (currentObject instanceof _node.default.Object) {
|
|
441
|
+
return currentObject;
|
|
442
|
+
}
|
|
443
|
+
// Preserve the original className if it exists, otherwise use the query className
|
|
444
|
+
const originalClassName = currentObject.className || classNameQuery;
|
|
445
|
+
const tempObjectWithClassName = {
|
|
446
|
+
...currentObject,
|
|
447
|
+
className: originalClassName
|
|
448
|
+
};
|
|
449
|
+
return _node.default.Object.fromJSON(tempObjectWithClassName);
|
|
317
450
|
});
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
451
|
+
return Promise.resolve().then(() => {
|
|
452
|
+
return maybeRunValidator(request, `${triggerType}.${classNameQuery}`, auth);
|
|
453
|
+
}).then(() => {
|
|
454
|
+
if (request.skipWithMasterKey) {
|
|
455
|
+
return request.objects;
|
|
456
|
+
}
|
|
457
|
+
const responseFromTrigger = trigger(request);
|
|
458
|
+
if (responseFromTrigger && typeof responseFromTrigger.then === 'function') {
|
|
459
|
+
return responseFromTrigger.then(results => {
|
|
460
|
+
return results;
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
return responseFromTrigger;
|
|
464
|
+
}).then(success, error);
|
|
465
|
+
}).then(resultsAsJSON => {
|
|
466
|
+
logTriggerAfterHook(triggerType, classNameQuery, JSON.stringify(resultsAsJSON), auth, config.logLevels.triggerAfter);
|
|
467
|
+
return resultsAsJSON;
|
|
331
468
|
});
|
|
332
469
|
}
|
|
333
|
-
|
|
334
|
-
function maybeRunQueryTrigger(triggerType, className, restWhere, restOptions, config, auth, isGet) {
|
|
470
|
+
function maybeRunQueryTrigger(triggerType, className, restWhere, restOptions, config, auth, context, isGet) {
|
|
335
471
|
const trigger = getTrigger(className, triggerType, config.applicationId);
|
|
336
472
|
if (!trigger) {
|
|
337
473
|
return Promise.resolve({
|
|
@@ -339,30 +475,25 @@ function maybeRunQueryTrigger(triggerType, className, restWhere, restOptions, co
|
|
|
339
475
|
restOptions
|
|
340
476
|
});
|
|
341
477
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
}
|
|
478
|
+
const json = Object.assign({}, restOptions);
|
|
479
|
+
json.where = restWhere;
|
|
480
|
+
const parseQuery = new _node.default.Query(className);
|
|
481
|
+
parseQuery.withJSON(json);
|
|
347
482
|
let count = false;
|
|
348
483
|
if (restOptions) {
|
|
349
|
-
if (restOptions.include && restOptions.include.length > 0) {
|
|
350
|
-
parseQuery._include = restOptions.include.split(',');
|
|
351
|
-
}
|
|
352
|
-
if (restOptions.skip) {
|
|
353
|
-
parseQuery._skip = restOptions.skip;
|
|
354
|
-
}
|
|
355
|
-
if (restOptions.limit) {
|
|
356
|
-
parseQuery._limit = restOptions.limit;
|
|
357
|
-
}
|
|
358
484
|
count = !!restOptions.count;
|
|
359
485
|
}
|
|
360
|
-
const requestObject = getRequestQueryObject(triggerType, auth, parseQuery, count, config, isGet);
|
|
486
|
+
const requestObject = getRequestQueryObject(triggerType, auth, parseQuery, count, config, context, isGet);
|
|
361
487
|
return Promise.resolve().then(() => {
|
|
488
|
+
return maybeRunValidator(requestObject, `${triggerType}.${className}`, auth);
|
|
489
|
+
}).then(() => {
|
|
490
|
+
if (requestObject.skipWithMasterKey) {
|
|
491
|
+
return requestObject.query;
|
|
492
|
+
}
|
|
362
493
|
return trigger(requestObject);
|
|
363
494
|
}).then(result => {
|
|
364
495
|
let queryResult = parseQuery;
|
|
365
|
-
if (result && result instanceof
|
|
496
|
+
if (result && result instanceof _node.default.Query) {
|
|
366
497
|
queryResult = result;
|
|
367
498
|
}
|
|
368
499
|
const jsonQuery = queryResult.toJSON();
|
|
@@ -381,6 +512,14 @@ function maybeRunQueryTrigger(triggerType, className, restWhere, restOptions, co
|
|
|
381
512
|
restOptions = restOptions || {};
|
|
382
513
|
restOptions.include = jsonQuery.include;
|
|
383
514
|
}
|
|
515
|
+
if (jsonQuery.excludeKeys) {
|
|
516
|
+
restOptions = restOptions || {};
|
|
517
|
+
restOptions.excludeKeys = jsonQuery.excludeKeys;
|
|
518
|
+
}
|
|
519
|
+
if (jsonQuery.explain) {
|
|
520
|
+
restOptions = restOptions || {};
|
|
521
|
+
restOptions.explain = jsonQuery.explain;
|
|
522
|
+
}
|
|
384
523
|
if (jsonQuery.keys) {
|
|
385
524
|
restOptions = restOptions || {};
|
|
386
525
|
restOptions.keys = jsonQuery.keys;
|
|
@@ -389,6 +528,14 @@ function maybeRunQueryTrigger(triggerType, className, restWhere, restOptions, co
|
|
|
389
528
|
restOptions = restOptions || {};
|
|
390
529
|
restOptions.order = jsonQuery.order;
|
|
391
530
|
}
|
|
531
|
+
if (jsonQuery.hint) {
|
|
532
|
+
restOptions = restOptions || {};
|
|
533
|
+
restOptions.hint = jsonQuery.hint;
|
|
534
|
+
}
|
|
535
|
+
if (jsonQuery.comment) {
|
|
536
|
+
restOptions = restOptions || {};
|
|
537
|
+
restOptions.comment = jsonQuery.comment;
|
|
538
|
+
}
|
|
392
539
|
if (requestObject.readPreference) {
|
|
393
540
|
restOptions = restOptions || {};
|
|
394
541
|
restOptions.readPreference = requestObject.readPreference;
|
|
@@ -401,75 +548,370 @@ function maybeRunQueryTrigger(triggerType, className, restWhere, restOptions, co
|
|
|
401
548
|
restOptions = restOptions || {};
|
|
402
549
|
restOptions.subqueryReadPreference = requestObject.subqueryReadPreference;
|
|
403
550
|
}
|
|
551
|
+
let objects = undefined;
|
|
552
|
+
if (result instanceof _node.default.Object) {
|
|
553
|
+
objects = [result];
|
|
554
|
+
} else if (Array.isArray(result) && (!result.length || result.every(obj => obj instanceof _node.default.Object))) {
|
|
555
|
+
objects = result;
|
|
556
|
+
}
|
|
404
557
|
return {
|
|
405
558
|
restWhere,
|
|
406
|
-
restOptions
|
|
559
|
+
restOptions,
|
|
560
|
+
objects
|
|
407
561
|
};
|
|
408
562
|
}, err => {
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
563
|
+
const error = resolveError(err, {
|
|
564
|
+
code: _node.default.Error.SCRIPT_FAILED,
|
|
565
|
+
message: 'Script failed. Unknown error.'
|
|
566
|
+
});
|
|
567
|
+
throw error;
|
|
414
568
|
});
|
|
415
569
|
}
|
|
570
|
+
function resolveError(message, defaultOpts) {
|
|
571
|
+
if (!defaultOpts) {
|
|
572
|
+
defaultOpts = {};
|
|
573
|
+
}
|
|
574
|
+
if (!message) {
|
|
575
|
+
return new _node.default.Error(defaultOpts.code || _node.default.Error.SCRIPT_FAILED, defaultOpts.message || 'Script failed.');
|
|
576
|
+
}
|
|
577
|
+
if (message instanceof _node.default.Error) {
|
|
578
|
+
return message;
|
|
579
|
+
}
|
|
580
|
+
const code = defaultOpts.code || _node.default.Error.SCRIPT_FAILED;
|
|
581
|
+
// If it's an error, mark it as a script failed
|
|
582
|
+
if (typeof message === 'string') {
|
|
583
|
+
return new _node.default.Error(code, message);
|
|
584
|
+
}
|
|
585
|
+
const error = new _node.default.Error(code, message.message || message);
|
|
586
|
+
if (message instanceof Error) {
|
|
587
|
+
error.stack = message.stack;
|
|
588
|
+
}
|
|
589
|
+
return error;
|
|
590
|
+
}
|
|
591
|
+
function maybeRunValidator(request, functionName, auth) {
|
|
592
|
+
const theValidator = getValidator(functionName, _node.default.applicationId);
|
|
593
|
+
if (!theValidator) {
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
if (typeof theValidator === 'object' && theValidator.skipWithMasterKey && request.master) {
|
|
597
|
+
request.skipWithMasterKey = true;
|
|
598
|
+
}
|
|
599
|
+
return new Promise((resolve, reject) => {
|
|
600
|
+
return Promise.resolve().then(() => {
|
|
601
|
+
return typeof theValidator === 'object' ? builtInTriggerValidator(theValidator, request, auth) : theValidator(request);
|
|
602
|
+
}).then(() => {
|
|
603
|
+
resolve();
|
|
604
|
+
}).catch(e => {
|
|
605
|
+
const error = resolveError(e, {
|
|
606
|
+
code: _node.default.Error.VALIDATION_ERROR,
|
|
607
|
+
message: 'Validation failed.'
|
|
608
|
+
});
|
|
609
|
+
reject(error);
|
|
610
|
+
});
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
async function builtInTriggerValidator(options, request, auth) {
|
|
614
|
+
if (request.master && !options.validateMasterKey) {
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
let reqUser = request.user;
|
|
618
|
+
if (!reqUser && request.object && request.object.className === '_User' && !request.object.existed()) {
|
|
619
|
+
reqUser = request.object;
|
|
620
|
+
}
|
|
621
|
+
if ((options.requireUser || options.requireAnyUserRoles || options.requireAllUserRoles) && !reqUser) {
|
|
622
|
+
throw 'Validation failed. Please login to continue.';
|
|
623
|
+
}
|
|
624
|
+
if (options.requireMaster && !request.master) {
|
|
625
|
+
throw 'Validation failed. Master key is required to complete this request.';
|
|
626
|
+
}
|
|
627
|
+
let params = request.params || {};
|
|
628
|
+
if (request.object) {
|
|
629
|
+
params = request.object.toJSON();
|
|
630
|
+
}
|
|
631
|
+
const requiredParam = key => {
|
|
632
|
+
const value = params[key];
|
|
633
|
+
if (value == null) {
|
|
634
|
+
throw `Validation failed. Please specify data for ${key}.`;
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
const validateOptions = async (opt, key, val) => {
|
|
638
|
+
let opts = opt.options;
|
|
639
|
+
if (typeof opts === 'function') {
|
|
640
|
+
try {
|
|
641
|
+
const result = await opts(val);
|
|
642
|
+
if (!result && result != null) {
|
|
643
|
+
throw opt.error || `Validation failed. Invalid value for ${key}.`;
|
|
644
|
+
}
|
|
645
|
+
} catch (e) {
|
|
646
|
+
if (!e) {
|
|
647
|
+
throw opt.error || `Validation failed. Invalid value for ${key}.`;
|
|
648
|
+
}
|
|
649
|
+
throw opt.error || e.message || e;
|
|
650
|
+
}
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
if (!Array.isArray(opts)) {
|
|
654
|
+
opts = [opt.options];
|
|
655
|
+
}
|
|
656
|
+
if (!opts.includes(val)) {
|
|
657
|
+
throw opt.error || `Validation failed. Invalid option for ${key}. Expected: ${opts.join(', ')}`;
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
const getType = fn => {
|
|
661
|
+
const match = fn && fn.toString().match(/^\s*function (\w+)/);
|
|
662
|
+
return (match ? match[1] : '').toLowerCase();
|
|
663
|
+
};
|
|
664
|
+
if (Array.isArray(options.fields)) {
|
|
665
|
+
for (const key of options.fields) {
|
|
666
|
+
requiredParam(key);
|
|
667
|
+
}
|
|
668
|
+
} else {
|
|
669
|
+
const optionPromises = [];
|
|
670
|
+
for (const key in options.fields) {
|
|
671
|
+
const opt = options.fields[key];
|
|
672
|
+
let val = params[key];
|
|
673
|
+
if (typeof opt === 'string') {
|
|
674
|
+
requiredParam(opt);
|
|
675
|
+
}
|
|
676
|
+
if (typeof opt === 'object') {
|
|
677
|
+
if (opt.default != null && val == null) {
|
|
678
|
+
val = opt.default;
|
|
679
|
+
params[key] = val;
|
|
680
|
+
if (request.object) {
|
|
681
|
+
request.object.set(key, val);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
if (opt.constant && request.object) {
|
|
685
|
+
if (request.original) {
|
|
686
|
+
request.object.revert(key);
|
|
687
|
+
} else if (opt.default != null) {
|
|
688
|
+
request.object.set(key, opt.default);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
if (opt.required) {
|
|
692
|
+
requiredParam(key);
|
|
693
|
+
}
|
|
694
|
+
const optional = !opt.required && val === undefined;
|
|
695
|
+
if (!optional) {
|
|
696
|
+
if (opt.type) {
|
|
697
|
+
const type = getType(opt.type);
|
|
698
|
+
const valType = Array.isArray(val) ? 'array' : typeof val;
|
|
699
|
+
if (valType !== type) {
|
|
700
|
+
throw `Validation failed. Invalid type for ${key}. Expected: ${type}`;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
if (opt.options) {
|
|
704
|
+
optionPromises.push(validateOptions(opt, key, val));
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
await Promise.all(optionPromises);
|
|
710
|
+
}
|
|
711
|
+
let userRoles = options.requireAnyUserRoles;
|
|
712
|
+
let requireAllRoles = options.requireAllUserRoles;
|
|
713
|
+
const promises = [Promise.resolve(), Promise.resolve(), Promise.resolve()];
|
|
714
|
+
if (userRoles || requireAllRoles) {
|
|
715
|
+
promises[0] = auth.getUserRoles();
|
|
716
|
+
}
|
|
717
|
+
if (typeof userRoles === 'function') {
|
|
718
|
+
promises[1] = userRoles();
|
|
719
|
+
}
|
|
720
|
+
if (typeof requireAllRoles === 'function') {
|
|
721
|
+
promises[2] = requireAllRoles();
|
|
722
|
+
}
|
|
723
|
+
const [roles, resolvedUserRoles, resolvedRequireAll] = await Promise.all(promises);
|
|
724
|
+
if (resolvedUserRoles && Array.isArray(resolvedUserRoles)) {
|
|
725
|
+
userRoles = resolvedUserRoles;
|
|
726
|
+
}
|
|
727
|
+
if (resolvedRequireAll && Array.isArray(resolvedRequireAll)) {
|
|
728
|
+
requireAllRoles = resolvedRequireAll;
|
|
729
|
+
}
|
|
730
|
+
if (userRoles) {
|
|
731
|
+
const hasRole = userRoles.some(requiredRole => roles.includes(`role:${requiredRole}`));
|
|
732
|
+
if (!hasRole) {
|
|
733
|
+
throw `Validation failed. User does not match the required roles.`;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
if (requireAllRoles) {
|
|
737
|
+
for (const requiredRole of requireAllRoles) {
|
|
738
|
+
if (!roles.includes(`role:${requiredRole}`)) {
|
|
739
|
+
throw `Validation failed. User does not match all the required roles.`;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
const userKeys = options.requireUserKeys || [];
|
|
744
|
+
if (Array.isArray(userKeys)) {
|
|
745
|
+
for (const key of userKeys) {
|
|
746
|
+
if (!reqUser) {
|
|
747
|
+
throw 'Please login to make this request.';
|
|
748
|
+
}
|
|
749
|
+
if (reqUser.get(key) == null) {
|
|
750
|
+
throw `Validation failed. Please set data for ${key} on your account.`;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
} else if (typeof userKeys === 'object') {
|
|
754
|
+
const optionPromises = [];
|
|
755
|
+
for (const key in options.requireUserKeys) {
|
|
756
|
+
const opt = options.requireUserKeys[key];
|
|
757
|
+
if (opt.options) {
|
|
758
|
+
optionPromises.push(validateOptions(opt, key, reqUser.get(key)));
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
await Promise.all(optionPromises);
|
|
762
|
+
}
|
|
763
|
+
}
|
|
416
764
|
|
|
417
765
|
// To be used as part of the promise chain when saving/deleting an object
|
|
418
766
|
// Will resolve successfully if no trigger is configured
|
|
419
767
|
// Resolves to an object, empty or containing an object key. A beforeSave
|
|
420
768
|
// trigger will set the object key to the rest format object to save.
|
|
421
769
|
// originalParseObject is optional, we only need that for before/afterSave functions
|
|
422
|
-
function maybeRunTrigger(triggerType, auth, parseObject, originalParseObject, config) {
|
|
770
|
+
function maybeRunTrigger(triggerType, auth, parseObject, originalParseObject, config, context) {
|
|
423
771
|
if (!parseObject) {
|
|
424
772
|
return Promise.resolve({});
|
|
425
773
|
}
|
|
426
774
|
return new Promise(function (resolve, reject) {
|
|
427
775
|
var trigger = getTrigger(parseObject.className, triggerType, config.applicationId);
|
|
428
|
-
if (!trigger)
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
776
|
+
if (!trigger) {
|
|
777
|
+
return resolve();
|
|
778
|
+
}
|
|
779
|
+
var request = getRequestObject(triggerType, auth, parseObject, originalParseObject, config, context);
|
|
780
|
+
var {
|
|
781
|
+
success,
|
|
782
|
+
error
|
|
783
|
+
} = getResponseObject(request, object => {
|
|
784
|
+
logTriggerSuccessBeforeHook(triggerType, parseObject.className, parseObject.toJSON(), object, auth, triggerType.startsWith('after') ? config.logLevels.triggerAfter : config.logLevels.triggerBeforeSuccess);
|
|
785
|
+
if (triggerType === Types.beforeSave || triggerType === Types.afterSave || triggerType === Types.beforeDelete || triggerType === Types.afterDelete) {
|
|
786
|
+
Object.assign(context, request.context);
|
|
787
|
+
}
|
|
432
788
|
resolve(object);
|
|
433
789
|
}, error => {
|
|
434
|
-
logTriggerErrorBeforeHook(triggerType, parseObject.className, parseObject.toJSON(), auth, error);
|
|
790
|
+
logTriggerErrorBeforeHook(triggerType, parseObject.className, parseObject.toJSON(), auth, error, config.logLevels.triggerBeforeError);
|
|
435
791
|
reject(error);
|
|
436
792
|
});
|
|
437
|
-
// Force the current Parse app before the trigger
|
|
438
|
-
_node2.default.applicationId = config.applicationId;
|
|
439
|
-
_node2.default.javascriptKey = config.javascriptKey || '';
|
|
440
|
-
_node2.default.masterKey = config.masterKey;
|
|
441
793
|
|
|
442
794
|
// AfterSave and afterDelete triggers can return a promise, which if they
|
|
443
795
|
// do, needs to be resolved before this promise is resolved,
|
|
444
796
|
// so trigger execution is synced with RestWrite.execute() call.
|
|
445
797
|
// If triggers do not return a promise, they can run async code parallel
|
|
446
798
|
// to the RestWrite.execute() call.
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
if (
|
|
451
|
-
return
|
|
452
|
-
} else {
|
|
453
|
-
return resolve();
|
|
799
|
+
return Promise.resolve().then(() => {
|
|
800
|
+
return maybeRunValidator(request, `${triggerType}.${parseObject.className}`, auth);
|
|
801
|
+
}).then(() => {
|
|
802
|
+
if (request.skipWithMasterKey) {
|
|
803
|
+
return Promise.resolve();
|
|
454
804
|
}
|
|
455
|
-
|
|
805
|
+
const promise = trigger(request);
|
|
806
|
+
if (triggerType === Types.afterSave || triggerType === Types.afterDelete || triggerType === Types.afterLogin) {
|
|
807
|
+
logTriggerAfterHook(triggerType, parseObject.className, parseObject.toJSON(), auth, config.logLevels.triggerAfter);
|
|
808
|
+
}
|
|
809
|
+
// beforeSave is expected to return null (nothing)
|
|
810
|
+
if (triggerType === Types.beforeSave) {
|
|
811
|
+
if (promise && typeof promise.then === 'function') {
|
|
812
|
+
return promise.then(response => {
|
|
813
|
+
// response.object may come from express routing before hook
|
|
814
|
+
if (response && response.object) {
|
|
815
|
+
return response;
|
|
816
|
+
}
|
|
817
|
+
return null;
|
|
818
|
+
});
|
|
819
|
+
}
|
|
820
|
+
return null;
|
|
821
|
+
}
|
|
822
|
+
return promise;
|
|
823
|
+
}).then(success, error);
|
|
456
824
|
});
|
|
457
825
|
}
|
|
458
826
|
|
|
459
827
|
// Converts a REST-format object to a Parse.Object
|
|
460
828
|
// data is either className or an object
|
|
461
829
|
function inflate(data, restObject) {
|
|
462
|
-
var copy = typeof data == 'object' ? data : {
|
|
830
|
+
var copy = typeof data == 'object' ? data : {
|
|
831
|
+
className: data
|
|
832
|
+
};
|
|
463
833
|
for (var key in restObject) {
|
|
464
834
|
copy[key] = restObject[key];
|
|
465
835
|
}
|
|
466
|
-
return
|
|
836
|
+
return _node.default.Object.fromJSON(copy);
|
|
467
837
|
}
|
|
468
|
-
|
|
469
|
-
function runLiveQueryEventHandlers(data, applicationId = _node2.default.applicationId) {
|
|
838
|
+
function runLiveQueryEventHandlers(data, applicationId = _node.default.applicationId) {
|
|
470
839
|
if (!_triggerStore || !_triggerStore[applicationId] || !_triggerStore[applicationId].LiveQuery) {
|
|
471
840
|
return;
|
|
472
841
|
}
|
|
473
842
|
_triggerStore[applicationId].LiveQuery.forEach(handler => handler(data));
|
|
474
843
|
}
|
|
475
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy90cmlnZ2Vycy5qcyJdLCJuYW1lcyI6WyJhZGRGdW5jdGlvbiIsImFkZEpvYiIsImFkZFRyaWdnZXIiLCJhZGRMaXZlUXVlcnlFdmVudEhhbmRsZXIiLCJyZW1vdmVGdW5jdGlvbiIsInJlbW92ZVRyaWdnZXIiLCJfdW5yZWdpc3RlckFsbCIsImdldFRyaWdnZXIiLCJ0cmlnZ2VyRXhpc3RzIiwiZ2V0RnVuY3Rpb24iLCJnZXRKb2IiLCJnZXRKb2JzIiwiZ2V0VmFsaWRhdG9yIiwiZ2V0UmVxdWVzdE9iamVjdCIsImdldFJlcXVlc3RRdWVyeU9iamVjdCIsImdldFJlc3BvbnNlT2JqZWN0IiwibWF5YmVSdW5BZnRlckZpbmRUcmlnZ2VyIiwibWF5YmVSdW5RdWVyeVRyaWdnZXIiLCJtYXliZVJ1blRyaWdnZXIiLCJpbmZsYXRlIiwicnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyIsIlR5cGVzIiwiYmVmb3JlU2F2ZSIsImFmdGVyU2F2ZSIsImJlZm9yZURlbGV0ZSIsImFmdGVyRGVsZXRlIiwiYmVmb3JlRmluZCIsImFmdGVyRmluZCIsImJhc2VTdG9yZSIsIlZhbGlkYXRvcnMiLCJGdW5jdGlvbnMiLCJKb2JzIiwiTGl2ZVF1ZXJ5IiwiVHJpZ2dlcnMiLCJPYmplY3QiLCJrZXlzIiwicmVkdWNlIiwiYmFzZSIsImtleSIsImZyZWV6ZSIsInZhbGlkYXRlQ2xhc3NOYW1lRm9yVHJpZ2dlcnMiLCJjbGFzc05hbWUiLCJ0eXBlIiwicmVzdHJpY3RlZENsYXNzTmFtZXMiLCJpbmRleE9mIiwiX3RyaWdnZXJTdG9yZSIsImZ1bmN0aW9uTmFtZSIsImhhbmRsZXIiLCJ2YWxpZGF0aW9uSGFuZGxlciIsImFwcGxpY2F0aW9uSWQiLCJQYXJzZSIsImpvYk5hbWUiLCJwdXNoIiwiZm9yRWFjaCIsImFwcElkIiwidHJpZ2dlclR5cGUiLCJtYW5hZ2VyIiwidW5kZWZpbmVkIiwiYXV0aCIsInBhcnNlT2JqZWN0Iiwib3JpZ2luYWxQYXJzZU9iamVjdCIsImNvbmZpZyIsInJlcXVlc3QiLCJ0cmlnZ2VyTmFtZSIsIm9iamVjdCIsIm1hc3RlciIsImxvZyIsImxvZ2dlckNvbnRyb2xsZXIiLCJoZWFkZXJzIiwiaXAiLCJvcmlnaW5hbCIsImlzTWFzdGVyIiwidXNlciIsImluc3RhbGxhdGlvbklkIiwicXVlcnkiLCJjb3VudCIsImlzR2V0IiwicmVzb2x2ZSIsInJlamVjdCIsInN1Y2Nlc3MiLCJyZXNwb25zZSIsIm9iamVjdHMiLCJtYXAiLCJ0b0pTT04iLCJlcXVhbHMiLCJfZ2V0U2F2ZUpTT04iLCJlcnJvciIsImNvZGUiLCJtZXNzYWdlIiwiRXJyb3IiLCJTQ1JJUFRfRkFJTEVEIiwic2NyaXB0RXJyb3IiLCJ1c2VySWRGb3JMb2ciLCJpZCIsImxvZ1RyaWdnZXJBZnRlckhvb2siLCJpbnB1dCIsImNsZWFuSW5wdXQiLCJsb2dnZXIiLCJ0cnVuY2F0ZUxvZ01lc3NhZ2UiLCJKU09OIiwic3RyaW5naWZ5IiwiaW5mbyIsImxvZ1RyaWdnZXJTdWNjZXNzQmVmb3JlSG9vayIsInJlc3VsdCIsImNsZWFuUmVzdWx0IiwibG9nVHJpZ2dlckVycm9yQmVmb3JlSG9vayIsIlByb21pc2UiLCJ0cmlnZ2VyIiwiZnJvbUpTT04iLCJ0cmlnZ2VyUHJvbWlzZSIsInRoZW4iLCJwcm9taXNlUmVzdWx0cyIsInJlc3VsdHMiLCJyZXN0V2hlcmUiLCJyZXN0T3B0aW9ucyIsInBhcnNlUXVlcnkiLCJRdWVyeSIsIl93aGVyZSIsImluY2x1ZGUiLCJsZW5ndGgiLCJfaW5jbHVkZSIsInNwbGl0Iiwic2tpcCIsIl9za2lwIiwibGltaXQiLCJfbGltaXQiLCJyZXF1ZXN0T2JqZWN0IiwicXVlcnlSZXN1bHQiLCJqc29uUXVlcnkiLCJ3aGVyZSIsIm9yZGVyIiwicmVhZFByZWZlcmVuY2UiLCJpbmNsdWRlUmVhZFByZWZlcmVuY2UiLCJzdWJxdWVyeVJlYWRQcmVmZXJlbmNlIiwiZXJyIiwiamF2YXNjcmlwdEtleSIsIm1hc3RlcktleSIsImRhdGEiLCJyZXN0T2JqZWN0IiwiY29w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QUFaLEVBQXhELEVBQThFekIsSUFBOUU7QUFDQSxVQUFHbUQsa0JBQWtCLE9BQU9BLGVBQWVDLElBQXRCLEtBQStCLFVBQXBELEVBQWdFO0FBQzlELGVBQU9ELGVBQWVDLElBQWYsQ0FBb0JqQyxPQUFwQixFQUE2QkEsT0FBN0IsQ0FBUDtBQUNELE9BRkQsTUFHSztBQUNILGVBQU9BLFNBQVA7QUFDRDtBQUNGO0FBQ0YsR0FsQ00sQ0FBUDtBQW1DRDs7QUFFRDtBQUNBO0FBQ08sU0FBUzFELE9BQVQsQ0FBaUJzSCxJQUFqQixFQUF1QkMsVUFBdkIsRUFBbUM7QUFDeEMsTUFBSUMsT0FBTyxPQUFPRixJQUFQLElBQWUsUUFBZixHQUEwQkEsSUFBMUIsR0FBaUMsRUFBQ2hHLFdBQVdnRyxJQUFaLEVBQTVDO0FBQ0EsT0FBSyxJQUFJbkcsR0FBVCxJQUFnQm9HLFVBQWhCLEVBQTRCO0FBQzFCQyxTQUFLckcsR0FBTCxJQUFZb0csV0FBV3BHLEdBQVgsQ0FBWjtBQUNEO0FBQ0QsU0FBT1ksZUFBTWhCLE1BQU4sQ0FBYTBFLFFBQWIsQ0FBc0IrQixJQUF0QixDQUFQO0FBQ0Q7O0FBRU0sU0FBU3ZILHlCQUFULENBQW1DcUgsSUFBbkMsRUFBeUN4RixnQkFBZ0JDLGVBQU1ELGFBQS9ELEVBQThFO0FBQ25GLE1BQUksQ0FBQ0osYUFBRCxJQUFrQixDQUFDQSxjQUFjSSxhQUFkLENBQW5CLElBQW1ELENBQUNKLGNBQWNJLGFBQWQsRUFBNkJqQixTQUFyRixFQUFnRztBQUFFO0FBQVM7QUFDM0dhLGdCQUFjSSxhQUFkLEVBQTZCakIsU0FBN0IsQ0FBdUNxQixPQUF2QyxDQUFnRE4sT0FBRCxJQUFhQSxRQUFRMEYsSUFBUixDQUE1RDtBQUNEIiwiZmlsZSI6InRyaWdnZXJzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdHJpZ2dlcnMuanNcbmltcG9ydCBQYXJzZSAgICBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4vbG9nZ2VyJztcblxuZXhwb3J0IGNvbnN0IFR5cGVzID0ge1xuICBiZWZvcmVTYXZlOiAnYmVmb3JlU2F2ZScsXG4gIGFmdGVyU2F2ZTogJ2FmdGVyU2F2ZScsXG4gIGJlZm9yZURlbGV0ZTogJ2JlZm9yZURlbGV0ZScsXG4gIGFmdGVyRGVsZXRlOiAnYWZ0ZXJEZWxldGUnLFxuICBiZWZvcmVGaW5kOiAnYmVmb3JlRmluZCcsXG4gIGFmdGVyRmluZDogJ2FmdGVyRmluZCdcbn07XG5cbmNvbnN0IGJhc2VTdG9yZSA9IGZ1bmN0aW9uKCkge1xuICBjb25zdCBWYWxpZGF0b3JzID0ge307XG4gIGNvbnN0IEZ1bmN0aW9ucyA9IHt9O1xuICBjb25zdCBKb2JzID0ge307XG4gIGNvbnN0IExpdmVRdWVyeSA9IFtdO1xuICBjb25zdCBUcmlnZ2VycyA9IE9iamVjdC5rZXlzKFR5cGVzKS5yZWR1Y2UoZnVuY3Rpb24oYmFzZSwga2V5KXtcbiAgICBiYXNlW2tleV0gPSB7fTtcbiAgICByZXR1cm4gYmFzZTtcbiAgfSwge30pO1xuXG4gIHJldHVybiBPYmplY3QuZnJlZXplKHtcbiAgICBGdW5jdGlvbnMsXG4gICAgSm9icyxcbiAgICBWYWxpZGF0b3JzLFxuICAgIFRyaWdnZXJzLFxuICAgIExpdmVRdWVyeSxcbiAgfSk7XG59O1xuXG5mdW5jdGlvbiB2YWxpZGF0ZUNsYXNzTmFtZUZvclRyaWdnZXJzKGNsYXNzTmFtZSwgdHlwZSkge1xuICBjb25zdCByZXN0cmljdGVkQ2xhc3NOYW1lcyA9IFsgJ19TZXNzaW9uJyBdO1xuICBpZiAocmVzdHJpY3RlZENsYXNzTmFtZXMuaW5kZXhPZihjbGFzc05hbWUpICE9IC0xKSB7XG4gICAgdGhyb3cgYFRyaWdnZXJzIGFyZSBub3Qgc3VwcG9ydGVkIGZvciAke2NsYXNzTmFtZX0gY2xhc3MuYDtcbiAgfVxuICBpZiAodHlwZSA9PSBUeXBlcy5iZWZvcmVTYXZlICYmIGNsYXNzTmFtZSA9PT0gJ19QdXNoU3RhdHVzJykge1xuICAgIC8vIF9QdXNoU3RhdHVzIHVzZXMgdW5kb2N1bWVudGVkIG5lc3RlZCBrZXkgaW5jcmVtZW50IG9wc1xuICAgIC8vIGFsbG93aW5nIGJlZm9yZVNhdmUgd291bGQgbWVzcyB1cCB0aGUgb2JqZWN0cyBiaWcgdGltZVxuICAgIC8vIFRPRE86IEFsbG93IHByb3BlciBkb2N1bWVudGVkIHdheSBvZiB1c2luZyBuZXN0ZWQgaW5jcmVtZW50IG9wc1xuICAgIHRocm93ICdPbmx5IGFmdGVyU2F2ZSBpcyBhbGxvd2VkIG9uIF9QdXNoU3RhdHVzJztcbiAgfVxuICByZXR1cm4gY2xhc3NOYW1lO1xufVxuXG5jb25zdCBfdHJpZ2dlclN0b3JlID0ge307XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRGdW5jdGlvbihmdW5jdGlvbk5hbWUsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyLCBhcHBsaWNhdGlvbklkKSB7XG4gIGFwcGxpY2F0aW9uSWQgPSBhcHBsaWNhdGlvbklkIHx8IFBhcnNlLmFwcGxpY2F0aW9uSWQ7XG4gIF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0gPSAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCBiYXNlU3RvcmUoKTtcbiAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5GdW5jdGlvbnNbZnVuY3Rpb25OYW1lXSA9IGhhbmRsZXI7XG4gIF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0uVmFsaWRhdG9yc1tmdW5jdGlvbk5hbWVdID0gdmFsaWRhdGlvbkhhbmRsZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRKb2Ioam9iTmFtZSwgaGFuZGxlciwgYXBwbGljYXRpb25JZCkge1xuICBhcHBsaWNhdGlvbklkID0gYXBwbGljYXRpb25JZCB8fCBQYXJzZS5hcHBsaWNhdGlvbklkO1xuICBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdID0gIF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0gfHwgYmFzZVN0b3JlKCk7XG4gIF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0uSm9ic1tqb2JOYW1lXSA9IGhhbmRsZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRUcmlnZ2VyKHR5cGUsIGNsYXNzTmFtZSwgaGFuZGxlciwgYXBwbGljYXRpb25JZCkge1xuICB2YWxpZGF0ZUNsYXNzTmFtZUZvclRyaWdnZXJzKGNsYXNzTmFtZSwgdHlwZSk7XG4gIGFwcGxpY2F0aW9uSWQgPSBhcHBsaWNhdGlvbklkIHx8IFBhcnNlLmFwcGxpY2F0aW9uSWQ7XG4gIF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0gPSAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCBiYXNlU3RvcmUoKTtcbiAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5UcmlnZ2Vyc1t0eXBlXVtjbGFzc05hbWVdID0gaGFuZGxlcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZExpdmVRdWVyeUV2ZW50SGFuZGxlcihoYW5kbGVyLCBhcHBsaWNhdGlvbklkKSB7XG4gIGFwcGxpY2F0aW9uSWQgPSBhcHBsaWNhdGlvbklkIHx8IFBhcnNlLmFwcGxpY2F0aW9uSWQ7XG4gIF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0gPSAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCBiYXNlU3RvcmUoKTtcbiAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5MaXZlUXVlcnkucHVzaChoYW5kbGVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICBhcHBsaWNhdGlvbklkID0gYXBwbGljYXRpb25JZCB8fCBQYXJzZS5hcHBsaWNhdGlvbklkO1xuICBkZWxldGUgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5GdW5jdGlvbnNbZnVuY3Rpb25OYW1lXVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlVHJpZ2dlcih0eXBlLCBjbGFzc05hbWUsIGFwcGxpY2F0aW9uSWQpIHtcbiAgYXBwbGljYXRpb25JZCA9IGFwcGxpY2F0aW9uSWQgfHwgUGFyc2UuYXBwbGljYXRpb25JZDtcbiAgZGVsZXRlIF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0uVHJpZ2dlcnNbdHlwZV1bY2xhc3NOYW1lXVxufVxuXG5leHBvcnQgZnVuY3Rpb24gX3VucmVnaXN0ZXJBbGwoKSB7XG4gIE9iamVjdC5rZXlzKF90cmlnZ2VyU3RvcmUpLmZvckVhY2goYXBwSWQgPT4gZGVsZXRlIF90cmlnZ2VyU3RvcmVbYXBwSWRdKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRyaWdnZXIoY2xhc3NOYW1lLCB0cmlnZ2VyVHlwZSwgYXBwbGljYXRpb25JZCkge1xuICBpZiAoIWFwcGxpY2F0aW9uSWQpIHtcbiAgICB0aHJvdyBcIk1pc3NpbmcgQXBwbGljYXRpb25JRFwiO1xuICB9XG4gIHZhciBtYW5hZ2VyID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXVxuICBpZiAobWFuYWdlclxuICAgICYmIG1hbmFnZXIuVHJpZ2dlcnNcbiAgICAmJiBtYW5hZ2VyLlRyaWdnZXJzW3RyaWdnZXJUeXBlXVxuICAgICYmIG1hbmFnZXIuVHJpZ2dlcnNbdHJpZ2dlclR5cGVdW2NsYXNzTmFtZV0pIHtcbiAgICByZXR1cm4gbWFuYWdlci5UcmlnZ2Vyc1t0cmlnZ2VyVHlwZV1bY2xhc3NOYW1lXTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdHJpZ2dlckV4aXN0cyhjbGFzc05hbWU6IHN0cmluZywgdHlwZTogc3RyaW5nLCBhcHBsaWNhdGlvbklkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIChnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHlwZSwgYXBwbGljYXRpb25JZCkgIT0gdW5kZWZpbmVkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICB2YXIgbWFuYWdlciA9IF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF07XG4gIGlmIChtYW5hZ2VyICYmIG1hbmFnZXIuRnVuY3Rpb25zKSB7XG4gICAgcmV0dXJuIG1hbmFnZXIuRnVuY3Rpb25zW2Z1bmN0aW9uTmFtZV07XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEpvYihqb2JOYW1lLCBhcHBsaWNhdGlvbklkKSB7XG4gIHZhciBtYW5hZ2VyID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXTtcbiAgaWYgKG1hbmFnZXIgJiYgbWFuYWdlci5Kb2JzKSB7XG4gICAgcmV0dXJuIG1hbmFnZXIuSm9ic1tqb2JOYW1lXTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Sm9icyhhcHBsaWNhdGlvbklkKSB7XG4gIHZhciBtYW5hZ2VyID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXTtcbiAgaWYgKG1hbmFnZXIgJiYgbWFuYWdlci5Kb2JzKSB7XG4gICAgcmV0dXJuIG1hbmFnZXIuSm9icztcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRWYWxpZGF0b3IoZnVuY3Rpb25OYW1lLCBhcHBsaWNhdGlvbklkKSB7XG4gIHZhciBtYW5hZ2VyID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXTtcbiAgaWYgKG1hbmFnZXIgJiYgbWFuYWdlci5WYWxpZGF0b3JzKSB7XG4gICAgcmV0dXJuIG1hbmFnZXIuVmFsaWRhdG9yc1tmdW5jdGlvbk5hbWVdO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXF1ZXN0T2JqZWN0KHRyaWdnZXJUeXBlLCBhdXRoLCBwYXJzZU9iamVjdCwgb3JpZ2luYWxQYXJzZU9iamVjdCwgY29uZmlnKSB7XG4gIHZhciByZXF1ZXN0ID0ge1xuICAgIHRyaWdnZXJOYW1lOiB0cmlnZ2VyVHlwZSxcbiAgICBvYmplY3Q6IHBhcnNlT2JqZWN0LFxuICAgIG1hc3RlcjogZmFsc2UsXG4gICAgbG9nOiBjb25maWcubG9nZ2VyQ29udHJvbGxlcixcbiAgICBoZWFkZXJzOiBjb25maWcuaGVhZGVycyxcbiAgICBpcDogY29uZmlnLmlwLFxuICB9O1xuXG4gIGlmIChvcmlnaW5hbFBhcnNlT2JqZWN0KSB7XG4gICAgcmVxdWVzdC5vcmlnaW5hbCA9IG9yaWdpbmFsUGFyc2VPYmplY3Q7XG4gIH1cblxuICBpZiAoIWF1dGgpIHtcbiAgICByZXR1cm4gcmVxdWVzdDtcbiAgfVxuICBpZiAoYXV0aC5pc01hc3Rlcikge1xuICAgIHJlcXVlc3RbJ21hc3RlciddID0gdHJ1ZTtcbiAgfVxuICBpZiAoYXV0aC51c2VyKSB7XG4gICAgcmVxdWVzdFsndXNlciddID0gYXV0aC51c2VyO1xuICB9XG4gIGlmIChhdXRoLmluc3RhbGxhdGlvbklkKSB7XG4gICAgcmVxdWVzdFsnaW5zdGFsbGF0aW9uSWQnXSA9IGF1dGguaW5zdGFsbGF0aW9uSWQ7XG4gIH1cbiAgcmV0dXJuIHJlcXVlc3Q7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXF1ZXN0UXVlcnlPYmplY3QodHJpZ2dlclR5cGUsIGF1dGgsIHF1ZXJ5LCBjb3VudCwgY29uZmlnLCBpc0dldCkge1xuICBpc0dldCA9ICEhaXNHZXQ7XG5cbiAgdmFyIHJlcXVlc3QgPSB7XG4gICAgdHJpZ2dlck5hbWU6IHRyaWdnZXJUeXBlLFxuICAgIHF1ZXJ5LFxuICAgIG1hc3RlcjogZmFsc2UsXG4gICAgY291bnQsXG4gICAgbG9nOiBjb25maWcubG9nZ2VyQ29udHJvbGxlcixcbiAgICBpc0dldCxcbiAgICBoZWFkZXJzOiBjb25maWcuaGVhZGVycyxcbiAgICBpcDogY29uZmlnLmlwLFxuICB9O1xuXG4gIGlmICghYXV0aCkge1xuICAgIHJldHVybiByZXF1ZXN0O1xuICB9XG4gIGlmIChhdXRoLmlzTWFzdGVyKSB7XG4gICAgcmVxdWVzdFsnbWFzdGVyJ10gPSB0cnVlO1xuICB9XG4gIGlmIChhdXRoLnVzZXIpIHtcbiAgICByZXF1ZXN0Wyd1c2VyJ10gPSBhdXRoLnVzZXI7XG4gIH1cbiAgaWYgKGF1dGguaW5zdGFsbGF0aW9uSWQpIHtcbiAgICByZXF1ZXN0WydpbnN0YWxsYXRpb25JZCddID0gYXV0aC5pbnN0YWxsYXRpb25JZDtcbiAgfVxuICByZXR1cm4gcmVxdWVzdDtcbn1cblxuLy8gQ3JlYXRlcyB0aGUgcmVzcG9uc2Ugb2JqZWN0LCBhbmQgdXNlcyB0aGUgcmVxdWVzdCBvYmplY3QgdG8gcGFzcyBkYXRhXG4vLyBUaGUgQVBJIHdpbGwgY2FsbCB0aGlzIHdpdGggUkVTVCBBUEkgZm9ybWF0dGVkIG9iamVjdHMsIHRoaXMgd2lsbFxuLy8gdHJhbnNmb3JtIHRoZW0gdG8gUGFyc2UuT2JqZWN0IGluc3RhbmNlcyBleHBlY3RlZCBieSBDbG91ZCBDb2RlLlxuLy8gQW55IGNoYW5nZXMgbWFkZSB0byB0aGUgb2JqZWN0IGluIGEgYmVmb3JlU2F2ZSB3aWxsIGJlIGluY2x1ZGVkLlxuZXhwb3J0IGZ1bmN0aW9uIGdldFJlc3BvbnNlT2JqZWN0KHJlcXVlc3QsIHJlc29sdmUsIHJlamVjdCkge1xuICByZXR1cm4ge1xuICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uKHJlc3BvbnNlKSB7XG4gICAgICBpZiAocmVxdWVzdC50cmlnZ2VyTmFtZSA9PT0gVHlwZXMuYWZ0ZXJGaW5kKSB7XG4gICAgICAgIGlmKCFyZXNwb25zZSl7XG4gICAgICAgICAgcmVzcG9uc2UgPSByZXF1ZXN0Lm9iamVjdHM7XG4gICAgICAgIH1cbiAgICAgICAgcmVzcG9uc2UgPSByZXNwb25zZS5tYXAob2JqZWN0ID0+IHtcbiAgICAgICAgICByZXR1cm4gb2JqZWN0LnRvSlNPTigpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgfVxuICAgICAgLy8gVXNlIHRoZSBKU09OIHJlc3BvbnNlXG4gICAgICBpZiAocmVzcG9uc2UgJiYgIXJlcXVlc3Qub2JqZWN0LmVxdWFscyhyZXNwb25zZSlcbiAgICAgICAgICAmJiByZXF1ZXN0LnRyaWdnZXJOYW1lID09PSBUeXBlcy5iZWZvcmVTYXZlKSB7XG4gICAgICAgIHJldHVybiByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICAgIH1cbiAgICAgIHJlc3BvbnNlID0ge307XG4gICAgICBpZiAocmVxdWVzdC50cmlnZ2VyTmFtZSA9PT0gVHlwZXMuYmVmb3JlU2F2ZSkge1xuICAgICAgICByZXNwb25zZVsnb2JqZWN0J10gPSByZXF1ZXN0Lm9iamVjdC5fZ2V0U2F2ZUpTT04oKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICB9LFxuICAgIGVycm9yOiBmdW5jdGlvbihjb2RlLCBtZXNzYWdlKSB7XG4gICAgICBpZiAoIW1lc3NhZ2UpIHtcbiAgICAgICAgaWYgKGNvZGUgaW5zdGFuY2VvZiBQYXJzZS5FcnJvcikge1xuICAgICAgICAgIHJldHVybiByZWplY3QoY29kZSlcbiAgICAgICAgfVxuICAgICAgICBtZXNzYWdlID0gY29kZTtcbiAgICAgICAgY29kZSA9IFBhcnNlLkVycm9yLlNDUklQVF9GQUlMRUQ7XG4gICAgICB9XG4gICAgICB2YXIgc2NyaXB0RXJyb3IgPSBuZXcgUGFyc2UuRXJyb3IoY29kZSwgbWVzc2FnZSk7XG4gICAgICByZXR1cm4gcmVqZWN0KHNjcmlwdEVycm9yKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdXNlcklkRm9yTG9nKGF1dGgpIHtcbiAgcmV0dXJuIChhdXRoICYmIGF1dGgudXNlcikgPyBhdXRoLnVzZXIuaWQgOiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGxvZ1RyaWdnZXJBZnRlckhvb2sodHJpZ2dlclR5cGUsIGNsYXNzTmFtZSwgaW5wdXQsIGF1dGgpIHtcbiAgY29uc3QgY2xlYW5JbnB1dCA9IGxvZ2dlci50cnVuY2F0ZUxvZ01lc3NhZ2UoSlNPTi5zdHJpbmdpZnkoaW5wdXQpKTtcbiAgbG9nZ2VyLmluZm8oYCR7dHJpZ2dlclR5cGV9IHRyaWdnZXJlZCBmb3IgJHtjbGFzc05hbWV9IGZvciB1c2VyICR7dXNlcklkRm9yTG9nKGF1dGgpfTpcXG4gIElucHV0OiAke2NsZWFuSW5wdXR9YCwge1xuICAgIGNsYXNzTmFtZSxcbiAgICB0cmlnZ2VyVHlwZSxcbiAgICB1c2VyOiB1c2VySWRGb3JMb2coYXV0aClcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGxvZ1RyaWdnZXJTdWNjZXNzQmVmb3JlSG9vayh0cmlnZ2VyVHlwZSwgY2xhc3NOYW1lLCBpbnB1dCwgcmVzdWx0LCBhdXRoKSB7XG4gIGNvbnN0IGNsZWFuSW5wdXQgPSBsb2dnZXIudHJ1bmNhdGVMb2dNZXNzYWdlKEpTT04uc3RyaW5naWZ5KGlucHV0KSk7XG4gIGNvbnN0IGNsZWFuUmVzdWx0ID0gbG9nZ2VyLnRydW5jYXRlTG9nTWVzc2FnZShKU09OLnN0cmluZ2lmeShyZXN1bHQpKTtcbiAgbG9nZ2VyLmluZm8oYCR7dHJpZ2dlclR5cGV9IHRyaWdnZXJlZCBmb3IgJHtjbGFzc05hbWV9IGZvciB1c2VyICR7dXNlcklkRm9yTG9nKGF1dGgpfTpcXG4gIElucHV0OiAke2NsZWFuSW5wdXR9XFxuICBSZXN1bHQ6ICR7Y2xlYW5SZXN1bHR9YCwge1xuICAgIGNsYXNzTmFtZSxcbiAgICB0cmlnZ2VyVHlwZSxcbiAgICB1c2VyOiB1c2VySWRGb3JMb2coYXV0aClcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGxvZ1RyaWdnZXJFcnJvckJlZm9yZUhvb2sodHJpZ2dlclR5cGUsIGNsYXNzTmFtZSwgaW5wdXQsIGF1dGgsIGVycm9yKSB7XG4gIGNvbnN0IGNsZWFuSW5wdXQgPSBsb2dnZXIudHJ1bmNhdGVMb2dNZXNzYWdlKEpTT04uc3RyaW5naWZ5KGlucHV0KSk7XG4gIGxvZ2dlci5lcnJvcihgJHt0cmlnZ2VyVHlwZX0gZmFpbGVkIGZvciAke2NsYXNzTmFtZX0gZm9yIHVzZXIgJHt1c2VySWRGb3JMb2coYXV0aCl9OlxcbiAgSW5wdXQ6ICR7Y2xlYW5JbnB1dH1cXG4gIEVycm9yOiAke0pTT04uc3RyaW5naWZ5KGVycm9yKX1gLCB7XG4gICAgY2xhc3NOYW1lLFxuICAgIHRyaWdnZXJUeXBlLFxuICAgIGVycm9yLFxuICAgIHVzZXI6IHVzZXJJZEZvckxvZyhhdXRoKVxuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1heWJlUnVuQWZ0ZXJGaW5kVHJpZ2dlcih0cmlnZ2VyVHlwZSwgYXV0aCwgY2xhc3NOYW1lLCBvYmplY3RzLCBjb25maWcpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihjbGFzc05hbWUsIHRyaWdnZXJUeXBlLCBjb25maWcuYXBwbGljYXRpb25JZCk7XG4gICAgaWYgKCF0cmlnZ2VyKSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgIH1cbiAgICBjb25zdCByZXF1ZXN0ID0gZ2V0UmVxdWVzdE9iamVjdCh0cmlnZ2VyVHlwZSwgYXV0aCwgbnVsbCwgbnVsbCwgY29uZmlnKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGdldFJlc3BvbnNlT2JqZWN0KHJlcXVlc3QsXG4gICAgICBvYmplY3QgPT4ge1xuICAgICAgICByZXNvbHZlKG9iamVjdCk7XG4gICAgICB9LFxuICAgICAgZXJyb3IgPT4ge1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gICAgbG9nVHJpZ2dlclN1Y2Nlc3NCZWZvcmVIb29rKHRyaWdnZXJUeXBlLCBjbGFzc05hbWUsICdBZnRlckZpbmQnLCBKU09OLnN0cmluZ2lmeShvYmplY3RzKSwgYXV0aCk7XG4gICAgcmVxdWVzdC5vYmplY3RzID0gb2JqZWN0cy5tYXAob2JqZWN0ID0+IHtcbiAgICAgIC8vc2V0dGluZyB0aGUgY2xhc3MgbmFtZSB0byB0cmFuc2Zvcm0gaW50byBwYXJzZSBvYmplY3RcbiAgICAgIG9iamVjdC5jbGFzc05hbWUgPSBjbGFzc05hbWU7XG4gICAgICByZXR1cm4gUGFyc2UuT2JqZWN0LmZyb21KU09OKG9iamVjdCk7XG4gICAgfSk7XG4gICAgY29uc3QgdHJpZ2dlclByb21pc2UgPSB0cmlnZ2VyKHJlcXVlc3QsIHJlc3BvbnNlKTtcbiAgICBpZiAodHJpZ2dlclByb21pc2UgJiYgdHlwZW9mIHRyaWdnZXJQcm9taXNlLnRoZW4gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgcmV0dXJuIHRyaWdnZXJQcm9taXNlLnRoZW4ocHJvbWlzZVJlc3VsdHMgPT4ge1xuICAgICAgICBpZihwcm9taXNlUmVzdWx0cykge1xuICAgICAgICAgIHJlc29sdmUocHJvbWlzZVJlc3VsdHMpO1xuICAgICAgICB9ZWxzZXtcbiAgICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5TQ1JJUFRfRkFJTEVELCBcIkFmdGVyRmluZCBleHBlY3QgcmVzdWx0cyB0byBiZSByZXR1cm5lZCBpbiB0aGUgcHJvbWlzZVwiKSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfSkudGhlbigocmVzdWx0cykgPT4ge1xuICAgIGxvZ1RyaWdnZXJBZnRlckhvb2sodHJpZ2dlclR5cGUsIGNsYXNzTmFtZSwgSlNPTi5zdHJpbmdpZnkocmVzdWx0cyksIGF1dGgpO1xuICAgIHJldHVybiByZXN1bHRzO1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1heWJlUnVuUXVlcnlUcmlnZ2VyKHRyaWdnZXJUeXBlLCBjbGFzc05hbWUsIHJlc3RXaGVyZSwgcmVzdE9wdGlvbnMsIGNvbmZpZywgYXV0aCwgaXNHZXQpIHtcbiAgY29uc3QgdHJpZ2dlciA9IGdldFRyaWdnZXIoY2xhc3NOYW1lLCB0cmlnZ2VyVHlwZSwgY29uZmlnLmFwcGxpY2F0aW9uSWQpO1xuICBpZiAoIXRyaWdnZXIpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgIHJlc3RXaGVyZSxcbiAgICAgIHJlc3RPcHRpb25zXG4gICAgfSk7XG4gIH1cblxuICBjb25zdCBwYXJzZVF1ZXJ5ID0gbmV3IFBhcnNlLlF1ZXJ5KGNsYXNzTmFtZSk7XG4gIGlmIChyZXN0V2hlcmUpIHtcbiAgICBwYXJzZVF1ZXJ5Ll93aGVyZSA9IHJlc3RXaGVyZTtcbiAgfVxuICBsZXQgY291bnQgPSBmYWxzZTtcbiAgaWYgKHJlc3RPcHRpb25zKSB7XG4gICAgaWYgKHJlc3RPcHRpb25zLmluY2x1ZGUgJiYgcmVzdE9wdGlvbnMuaW5jbHVkZS5sZW5ndGggPiAwKSB7XG4gICAgICBwYXJzZVF1ZXJ5Ll9pbmNsdWRlID0gcmVzdE9wdGlvbnMuaW5jbHVkZS5zcGxpdCgnLCcpO1xuICAgIH1cbiAgICBpZiAocmVzdE9wdGlvbnMuc2tpcCkge1xuICAgICAgcGFyc2VRdWVyeS5fc2tpcCA9IHJlc3RPcHRpb25zLnNraXA7XG4gICAgfVxuICAgIGlmIChyZXN0T3B0aW9ucy5saW1pdCkge1xuICAgICAgcGFyc2VRdWVyeS5fbGltaXQgPSByZXN0T3B0aW9ucy5saW1pdDtcbiAgICB9XG4gICAgY291bnQgPSAhIXJlc3RPcHRpb25zLmNvdW50O1xuICB9XG4gIGNvbnN0IHJlcXVlc3RPYmplY3QgPSBnZXRSZXF1ZXN0UXVlcnlPYmplY3QodHJpZ2dlclR5cGUsIGF1dGgsIHBhcnNlUXVlcnksIGNvdW50LCBjb25maWcsIGlzR2V0KTtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCkgPT4ge1xuICAgIHJldHVybiB0cmlnZ2VyKHJlcXVlc3RPYmplY3QpO1xuICB9KS50aGVuKChyZXN1bHQpID0+IHtcbiAgICBsZXQgcXVlcnlSZXN1bHQgPSBwYXJzZVF1ZXJ5O1xuICAgIGlmIChyZXN1bHQgJiYgcmVzdWx0IGluc3RhbmNlb2YgUGFyc2UuUXVlcnkpIHtcbiAgICAgIHF1ZXJ5UmVzdWx0ID0gcmVzdWx0O1xuICAgIH1cbiAgICBjb25zdCBqc29uUXVlcnkgPSBxdWVyeVJlc3VsdC50b0pTT04oKTtcbiAgICBpZiAoanNvblF1ZXJ5LndoZXJlKSB7XG4gICAgICByZXN0V2hlcmUgPSBqc29uUXVlcnkud2hlcmU7XG4gICAgfVxuICAgIGlmIChqc29uUXVlcnkubGltaXQpIHtcbiAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICByZXN0T3B0aW9ucy5saW1pdCA9IGpzb25RdWVyeS5saW1pdDtcbiAgICB9XG4gICAgaWYgKGpzb25RdWVyeS5za2lwKSB7XG4gICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgcmVzdE9wdGlvbnMuc2tpcCA9IGpzb25RdWVyeS5za2lwO1xuICAgIH1cbiAgICBpZiAoanNvblF1ZXJ5LmluY2x1ZGUpIHtcbiAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICByZXN0T3B0aW9ucy5pbmNsdWRlID0ganNvblF1ZXJ5LmluY2x1ZGU7XG4gICAgfVxuICAgIGlmIChqc29uUXVlcnkua2V5cykge1xuICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgIHJlc3RPcHRpb25zLmtleXMgPSBqc29uUXVlcnkua2V5cztcbiAgICB9XG4gICAgaWYgKGpzb25RdWVyeS5vcmRlcikge1xuICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgIHJlc3RPcHRpb25zLm9yZGVyID0ganNvblF1ZXJ5Lm9yZGVyO1xuICAgIH1cbiAgICBpZiAocmVxdWVzdE9iamVjdC5yZWFkUHJlZmVyZW5jZSkge1xuICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgIHJlc3RPcHRpb25zLnJlYWRQcmVmZXJlbmNlID0gcmVxdWVzdE9iamVjdC5yZWFkUHJlZmVyZW5jZTtcbiAgICB9XG4gICAgaWYgKHJlcXVlc3RPYmplY3QuaW5jbHVkZVJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgcmVzdE9wdGlvbnMuaW5jbHVkZVJlYWRQcmVmZXJlbmNlID0gcmVxdWVzdE9iamVjdC5pbmNsdWRlUmVhZFByZWZlcmVuY2U7XG4gICAgfVxuICAgIGlmIChyZXF1ZXN0T2JqZWN0LnN1YnF1ZXJ5UmVhZFByZWZlcmVuY2UpIHtcbiAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICByZXN0T3B0aW9ucy5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlID0gcmVxdWVzdE9iamVjdC5zdWJxdWVyeVJlYWRQcmVmZXJlbmNlO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgcmVzdFdoZXJlLFxuICAgICAgcmVzdE9wdGlvbnNcbiAgICB9O1xuICB9LCAoZXJyKSA9PiB7XG4gICAgaWYgKHR5cGVvZiBlcnIgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMSwgZXJyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfSk7XG59XG5cbi8vIFRvIGJlIHVzZWQgYXMgcGFydCBvZiB0aGUgcHJvbWlzZSBjaGFpbiB3aGVuIHNhdmluZy9kZWxldGluZyBhbiBvYmplY3Rcbi8vIFdpbGwgcmVzb2x2ZSBzdWNjZXNzZnVsbHkgaWYgbm8gdHJpZ2dlciBpcyBjb25maWd1cmVkXG4vLyBSZXNvbHZlcyB0byBhbiBvYmplY3QsIGVtcHR5IG9yIGNvbnRhaW5pbmcgYW4gb2JqZWN0IGtleS4gQSBiZWZvcmVTYXZlXG4vLyB0cmlnZ2VyIHdpbGwgc2V0IHRoZSBvYmplY3Qga2V5IHRvIHRoZSByZXN0IGZvcm1hdCBvYmplY3QgdG8gc2F2ZS5cbi8vIG9yaWdpbmFsUGFyc2VPYmplY3QgaXMgb3B0aW9uYWwsIHdlIG9ubHkgbmVlZCB0aGF0IGZvciBiZWZvcmUvYWZ0ZXJTYXZlIGZ1bmN0aW9uc1xuZXhwb3J0IGZ1bmN0aW9uIG1heWJlUnVuVHJpZ2dlcih0cmlnZ2VyVHlwZSwgYXV0aCwgcGFyc2VPYmplY3QsIG9yaWdpbmFsUGFyc2VPYmplY3QsIGNvbmZpZykge1xuICBpZiAoIXBhcnNlT2JqZWN0KSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7fSk7XG4gIH1cbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICB2YXIgdHJpZ2dlciA9IGdldFRyaWdnZXIocGFyc2VPYmplY3QuY2xhc3NOYW1lLCB0cmlnZ2VyVHlwZSwgY29uZmlnLmFwcGxpY2F0aW9uSWQpO1xuICAgIGlmICghdHJpZ2dlcikgcmV0dXJuIHJlc29sdmUoKTtcbiAgICB2YXIgcmVxdWVzdCA9IGdldFJlcXVlc3RPYmplY3QodHJpZ2dlclR5cGUsIGF1dGgsIHBhcnNlT2JqZWN0LCBvcmlnaW5hbFBhcnNlT2JqZWN0LCBjb25maWcpO1xuICAgIHZhciByZXNwb25zZSA9IGdldFJlc3BvbnNlT2JqZWN0KHJlcXVlc3QsIChvYmplY3QpID0+IHtcbiAgICAgIGxvZ1RyaWdnZXJTdWNjZXNzQmVmb3JlSG9vayhcbiAgICAgICAgdHJpZ2dlclR5cGUsIHBhcnNlT2JqZWN0LmNsYXNzTmFtZSwgcGFyc2VPYmplY3QudG9KU09OKCksIG9iamVjdCwgYXV0aCk7XG4gICAgICByZXNvbHZlKG9iamVjdCk7XG4gICAgfSwgKGVycm9yKSA9PiB7XG4gICAgICBsb2dUcmlnZ2VyRXJyb3JCZWZvcmVIb29rKFxuICAgICAgICB0cmlnZ2VyVHlwZSwgcGFyc2VPYmplY3QuY2xhc3NOYW1lLCBwYXJzZU9iamVjdC50b0pTT04oKSwgYXV0aCwgZXJyb3IpO1xuICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICB9KTtcbiAgICAvLyBGb3JjZSB0aGUgY3VycmVudCBQYXJzZSBhcHAgYmVmb3JlIHRoZSB0cmlnZ2VyXG4gICAgUGFyc2UuYXBwbGljYXRpb25JZCA9IGNvbmZpZy5hcHBsaWNhdGlvbklkO1xuICAgIFBhcnNlLmphdmFzY3JpcHRLZXkgPSBjb25maWcuamF2YXNjcmlwdEtleSB8fCAnJztcbiAgICBQYXJzZS5tYXN0ZXJLZXkgPSBjb25maWcubWFzdGVyS2V5O1xuXG4gICAgLy8gQWZ0ZXJTYXZlIGFuZCBhZnRlckRlbGV0ZSB0cmlnZ2VycyBjYW4gcmV0dXJuIGEgcHJvbWlzZSwgd2hpY2ggaWYgdGhleVxuICAgIC8vIGRvLCBuZWVkcyB0byBiZSByZXNvbHZlZCBiZWZvcmUgdGhpcyBwcm9taXNlIGlzIHJlc29sdmVkLFxuICAgIC8vIHNvIHRyaWdnZXIgZXhlY3V0aW9uIGlzIHN5bmNlZCB3aXRoIFJlc3RXcml0ZS5leGVjdXRlKCkgY2FsbC5cbiAgICAvLyBJZiB0cmlnZ2VycyBkbyBub3QgcmV0dXJuIGEgcHJvbWlzZSwgdGhleSBjYW4gcnVuIGFzeW5jIGNvZGUgcGFyYWxsZWxcbiAgICAvLyB0byB0aGUgUmVzdFdyaXRlLmV4ZWN1dGUoKSBjYWxsLlxuICAgIHZhciB0cmlnZ2VyUHJvbWlzZSA9IHRyaWdnZXIocmVxdWVzdCwgcmVzcG9uc2UpO1xuICAgIGlmKHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlclNhdmUgfHwgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmFmdGVyRGVsZXRlKVxuICAgIHtcbiAgICAgIGxvZ1RyaWdnZXJBZnRlckhvb2sodHJpZ2dlclR5cGUsIHBhcnNlT2JqZWN0LmNsYXNzTmFtZSwgcGFyc2VPYmplY3QudG9KU09OKCksIGF1dGgpO1xuICAgICAgaWYodHJpZ2dlclByb21pc2UgJiYgdHlwZW9mIHRyaWdnZXJQcm9taXNlLnRoZW4gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gdHJpZ2dlclByb21pc2UudGhlbihyZXNvbHZlLCByZXNvbHZlKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG59XG5cbi8vIENvbnZlcnRzIGEgUkVTVC1mb3JtYXQgb2JqZWN0IHRvIGEgUGFyc2UuT2JqZWN0XG4vLyBkYXRhIGlzIGVpdGhlciBjbGFzc05hbWUgb3IgYW4gb2JqZWN0XG5leHBvcnQgZnVuY3Rpb24gaW5mbGF0ZShkYXRhLCByZXN0T2JqZWN0KSB7XG4gIHZhciBjb3B5ID0gdHlwZW9mIGRhdGEgPT0gJ29iamVjdCcgPyBkYXRhIDoge2NsYXNzTmFtZTogZGF0YX07XG4gIGZvciAodmFyIGtleSBpbiByZXN0T2JqZWN0KSB7XG4gICAgY29weVtrZXldID0gcmVzdE9iamVjdFtrZXldO1xuICB9XG4gIHJldHVybiBQYXJzZS5PYmplY3QuZnJvbUpTT04oY29weSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBydW5MaXZlUXVlcnlFdmVudEhhbmRsZXJzKGRhdGEsIGFwcGxpY2F0aW9uSWQgPSBQYXJzZS5hcHBsaWNhdGlvbklkKSB7XG4gIGlmICghX3RyaWdnZXJTdG9yZSB8fCAhX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCAhX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5MaXZlUXVlcnkpIHsgcmV0dXJuOyB9XG4gIF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0uTGl2ZVF1ZXJ5LmZvckVhY2goKGhhbmRsZXIpID0+IGhhbmRsZXIoZGF0YSkpO1xufVxuIl19
|
|
844
|
+
function getRequestFileObject(triggerType, auth, fileObject, config) {
|
|
845
|
+
const request = {
|
|
846
|
+
...fileObject,
|
|
847
|
+
triggerName: triggerType,
|
|
848
|
+
master: false,
|
|
849
|
+
log: config.loggerController,
|
|
850
|
+
headers: config.headers,
|
|
851
|
+
ip: config.ip,
|
|
852
|
+
config
|
|
853
|
+
};
|
|
854
|
+
if (!auth) {
|
|
855
|
+
return request;
|
|
856
|
+
}
|
|
857
|
+
if (auth.isMaster) {
|
|
858
|
+
request['master'] = true;
|
|
859
|
+
}
|
|
860
|
+
if (auth.user) {
|
|
861
|
+
request['user'] = auth.user;
|
|
862
|
+
}
|
|
863
|
+
if (auth.installationId) {
|
|
864
|
+
request['installationId'] = auth.installationId;
|
|
865
|
+
}
|
|
866
|
+
return request;
|
|
867
|
+
}
|
|
868
|
+
async function maybeRunFileTrigger(triggerType, fileObject, config, auth) {
|
|
869
|
+
const FileClassName = getClassName(_node.default.File);
|
|
870
|
+
const fileTrigger = getTrigger(FileClassName, triggerType, config.applicationId);
|
|
871
|
+
if (typeof fileTrigger === 'function') {
|
|
872
|
+
try {
|
|
873
|
+
const request = getRequestFileObject(triggerType, auth, fileObject, config);
|
|
874
|
+
await maybeRunValidator(request, `${triggerType}.${FileClassName}`, auth);
|
|
875
|
+
if (request.skipWithMasterKey) {
|
|
876
|
+
return fileObject;
|
|
877
|
+
}
|
|
878
|
+
const result = await fileTrigger(request);
|
|
879
|
+
if (request.forceDownload) {
|
|
880
|
+
fileObject.forceDownload = true;
|
|
881
|
+
}
|
|
882
|
+
logTriggerSuccessBeforeHook(triggerType, 'Parse.File', {
|
|
883
|
+
...fileObject.file.toJSON(),
|
|
884
|
+
fileSize: fileObject.fileSize
|
|
885
|
+
}, result, auth, config.logLevels.triggerBeforeSuccess);
|
|
886
|
+
return result || fileObject;
|
|
887
|
+
} catch (error) {
|
|
888
|
+
logTriggerErrorBeforeHook(triggerType, 'Parse.File', {
|
|
889
|
+
...fileObject.file.toJSON(),
|
|
890
|
+
fileSize: fileObject.fileSize
|
|
891
|
+
}, auth, error, config.logLevels.triggerBeforeError);
|
|
892
|
+
throw error;
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
return fileObject;
|
|
896
|
+
}
|
|
897
|
+
async function maybeRunGlobalConfigTrigger(triggerType, auth, configObject, originalConfigObject, config, context) {
|
|
898
|
+
const GlobalConfigClassName = getClassName(_node.default.Config);
|
|
899
|
+
const configTrigger = getTrigger(GlobalConfigClassName, triggerType, config.applicationId);
|
|
900
|
+
if (typeof configTrigger === 'function') {
|
|
901
|
+
try {
|
|
902
|
+
const request = getRequestObject(triggerType, auth, configObject, originalConfigObject, config, context);
|
|
903
|
+
await maybeRunValidator(request, `${triggerType}.${GlobalConfigClassName}`, auth);
|
|
904
|
+
if (request.skipWithMasterKey) {
|
|
905
|
+
return configObject;
|
|
906
|
+
}
|
|
907
|
+
const result = await configTrigger(request);
|
|
908
|
+
logTriggerSuccessBeforeHook(triggerType, 'Parse.Config', configObject, result, auth, config.logLevels.triggerBeforeSuccess);
|
|
909
|
+
return result || configObject;
|
|
910
|
+
} catch (error) {
|
|
911
|
+
logTriggerErrorBeforeHook(triggerType, 'Parse.Config', configObject, auth, error, config.logLevels.triggerBeforeError);
|
|
912
|
+
throw error;
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
return configObject;
|
|
916
|
+
}
|
|
917
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbm9kZSIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJyZXF1aXJlIiwiX2xvZ2dlciIsImUiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsIlR5cGVzIiwiZXhwb3J0cyIsImJlZm9yZUxvZ2luIiwiYWZ0ZXJMb2dpbiIsImFmdGVyTG9nb3V0IiwiYmVmb3JlUGFzc3dvcmRSZXNldFJlcXVlc3QiLCJiZWZvcmVTYXZlIiwiYWZ0ZXJTYXZlIiwiYmVmb3JlRGVsZXRlIiwiYWZ0ZXJEZWxldGUiLCJiZWZvcmVGaW5kIiwiYWZ0ZXJGaW5kIiwiYmVmb3JlQ29ubmVjdCIsImJlZm9yZVN1YnNjcmliZSIsImFmdGVyRXZlbnQiLCJDb25uZWN0Q2xhc3NOYW1lIiwiYmFzZVN0b3JlIiwiVmFsaWRhdG9ycyIsIk9iamVjdCIsImtleXMiLCJyZWR1Y2UiLCJiYXNlIiwia2V5IiwiRnVuY3Rpb25zIiwiSm9icyIsIkxpdmVRdWVyeSIsIlRyaWdnZXJzIiwiZnJlZXplIiwiZ2V0Q2xhc3NOYW1lIiwicGFyc2VDbGFzcyIsImNsYXNzTmFtZSIsIm5hbWUiLCJyZXBsYWNlIiwidmFsaWRhdGVDbGFzc05hbWVGb3JUcmlnZ2VycyIsInR5cGUiLCJfdHJpZ2dlclN0b3JlIiwiQ2F0ZWdvcnkiLCJnZXRTdG9yZSIsImNhdGVnb3J5IiwiYXBwbGljYXRpb25JZCIsImludmFsaWROYW1lUmVnZXgiLCJ0ZXN0IiwicGF0aCIsInNwbGl0Iiwic3BsaWNlIiwiUGFyc2UiLCJzdG9yZSIsImNvbXBvbmVudCIsImFkZCIsImhhbmRsZXIiLCJsYXN0Q29tcG9uZW50IiwibG9nZ2VyIiwid2FybiIsInJlbW92ZSIsImdldCIsImFkZEZ1bmN0aW9uIiwiZnVuY3Rpb25OYW1lIiwidmFsaWRhdGlvbkhhbmRsZXIiLCJhZGRKb2IiLCJqb2JOYW1lIiwiYWRkVHJpZ2dlciIsImFkZENvbm5lY3RUcmlnZ2VyIiwiYWRkTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVyIiwicHVzaCIsInJlbW92ZUZ1bmN0aW9uIiwicmVtb3ZlVHJpZ2dlciIsIl91bnJlZ2lzdGVyQWxsIiwiZm9yRWFjaCIsImFwcElkIiwidG9KU09Od2l0aE9iamVjdHMiLCJvYmplY3QiLCJ0b0pTT04iLCJzdGF0ZUNvbnRyb2xsZXIiLCJDb3JlTWFuYWdlciIsImdldE9iamVjdFN0YXRlQ29udHJvbGxlciIsInBlbmRpbmciLCJnZXRQZW5kaW5nT3BzIiwiX2dldFN0YXRlSWRlbnRpZmllciIsInZhbCIsIl90b0Z1bGxKU09OIiwiZ2V0VHJpZ2dlciIsInRyaWdnZXJUeXBlIiwicnVuVHJpZ2dlciIsInRyaWdnZXIiLCJyZXF1ZXN0IiwiYXV0aCIsIm1heWJlUnVuVmFsaWRhdG9yIiwic2tpcFdpdGhNYXN0ZXJLZXkiLCJ0cmlnZ2VyRXhpc3RzIiwidW5kZWZpbmVkIiwiZ2V0RnVuY3Rpb24iLCJnZXRGdW5jdGlvbk5hbWVzIiwiZnVuY3Rpb25OYW1lcyIsImV4dHJhY3RGdW5jdGlvbk5hbWVzIiwibmFtZXNwYWNlIiwidmFsdWUiLCJnZXRKb2IiLCJnZXRKb2JzIiwibWFuYWdlciIsImdldFZhbGlkYXRvciIsImdldFJlcXVlc3RPYmplY3QiLCJwYXJzZU9iamVjdCIsIm9yaWdpbmFsUGFyc2VPYmplY3QiLCJjb25maWciLCJjb250ZXh0IiwiaXNHZXQiLCJ0cmlnZ2VyTmFtZSIsIm1hc3RlciIsImxvZyIsImxvZ2dlckNvbnRyb2xsZXIiLCJoZWFkZXJzIiwiaXAiLCJvcmlnaW5hbCIsImFzc2lnbiIsImlzTWFzdGVyIiwidXNlciIsImluc3RhbGxhdGlvbklkIiwiZ2V0UmVxdWVzdFF1ZXJ5T2JqZWN0IiwicXVlcnkiLCJjb3VudCIsImdldFJlc3BvbnNlT2JqZWN0IiwicmVzb2x2ZSIsInJlamVjdCIsInN1Y2Nlc3MiLCJyZXNwb25zZSIsIm9iamVjdHMiLCJtYXAiLCJlcXVhbHMiLCJfZ2V0U2F2ZUpTT04iLCJpZCIsImVycm9yIiwicmVzb2x2ZUVycm9yIiwiY29kZSIsIkVycm9yIiwiU0NSSVBUX0ZBSUxFRCIsIm1lc3NhZ2UiLCJ1c2VySWRGb3JMb2ciLCJsb2dUcmlnZ2VyQWZ0ZXJIb29rIiwiaW5wdXQiLCJsb2dMZXZlbCIsImNsZWFuSW5wdXQiLCJ0cnVuY2F0ZUxvZ01lc3NhZ2UiLCJKU09OIiwic3RyaW5naWZ5IiwibG9nVHJpZ2dlclN1Y2Nlc3NCZWZvcmVIb29rIiwicmVzdWx0IiwiY2xlYW5SZXN1bHQiLCJsb2dUcmlnZ2VyRXJyb3JCZWZvcmVIb29rIiwibWF5YmVSdW5BZnRlckZpbmRUcmlnZ2VyIiwiY2xhc3NOYW1lUXVlcnkiLCJvYmplY3RzSW5wdXQiLCJQcm9taXNlIiwibGVuZ3RoIiwib2JqIiwiUXVlcnkiLCJwYXJzZVF1ZXJ5SW5zdGFuY2UiLCJ3aGVyZSIsIndpdGhKU09OIiwicHJvY2Vzc2VkT2JqZWN0c0pTT04iLCJlcnJvckRhdGEiLCJvIiwibG9nTGV2ZWxzIiwidHJpZ2dlckJlZm9yZVN1Y2Nlc3MiLCJjdXJyZW50T2JqZWN0Iiwib3JpZ2luYWxDbGFzc05hbWUiLCJ0ZW1wT2JqZWN0V2l0aENsYXNzTmFtZSIsImZyb21KU09OIiwidGhlbiIsInJlc3BvbnNlRnJvbVRyaWdnZXIiLCJyZXN1bHRzIiwicmVzdWx0c0FzSlNPTiIsInRyaWdnZXJBZnRlciIsIm1heWJlUnVuUXVlcnlUcmlnZ2VyIiwicmVzdFdoZXJlIiwicmVzdE9wdGlvbnMiLCJqc29uIiwicGFyc2VRdWVyeSIsInJlcXVlc3RPYmplY3QiLCJxdWVyeVJlc3VsdCIsImpzb25RdWVyeSIsImxpbWl0Iiwic2tpcCIsImluY2x1ZGUiLCJleGNsdWRlS2V5cyIsImV4cGxhaW4iLCJvcmRlciIsImhpbnQiLCJjb21tZW50IiwicmVhZFByZWZlcmVuY2UiLCJpbmNsdWRlUmVhZFByZWZlcmVuY2UiLCJzdWJxdWVyeVJlYWRQcmVmZXJlbmNlIiwiQXJyYXkiLCJpc0FycmF5IiwiZXZlcnkiLCJlcnIiLCJkZWZhdWx0T3B0cyIsInN0YWNrIiwidGhlVmFsaWRhdG9yIiwiYnVpbHRJblRyaWdnZXJWYWxpZGF0b3IiLCJjYXRjaCIsIlZBTElEQVRJT05fRVJST1IiLCJvcHRpb25zIiwidmFsaWRhdGVNYXN0ZXJLZXkiLCJyZXFVc2VyIiwiZXhpc3RlZCIsInJlcXVpcmVVc2VyIiwicmVxdWlyZUFueVVzZXJSb2xlcyIsInJlcXVpcmVBbGxVc2VyUm9sZXMiLCJyZXF1aXJlTWFzdGVyIiwicGFyYW1zIiwicmVxdWlyZWRQYXJhbSIsInZhbGlkYXRlT3B0aW9ucyIsIm9wdCIsIm9wdHMiLCJpbmNsdWRlcyIsImpvaW4iLCJnZXRUeXBlIiwiZm4iLCJtYXRjaCIsInRvU3RyaW5nIiwidG9Mb3dlckNhc2UiLCJmaWVsZHMiLCJvcHRpb25Qcm9taXNlcyIsInNldCIsImNvbnN0YW50IiwicmV2ZXJ0IiwicmVxdWlyZWQiLCJvcHRpb25hbCIsInZhbFR5cGUiLCJhbGwiLCJ1c2VyUm9sZXMiLCJyZXF1aXJlQWxsUm9sZXMiLCJwcm9taXNlcyIsImdldFVzZXJSb2xlcyIsInJvbGVzIiwicmVzb2x2ZWRVc2VyUm9sZXMiLCJyZXNvbHZlZFJlcXVpcmVBbGwiLCJoYXNSb2xlIiwic29tZSIsInJlcXVpcmVkUm9sZSIsInVzZXJLZXlzIiwicmVxdWlyZVVzZXJLZXlzIiwibWF5YmVSdW5UcmlnZ2VyIiwic3RhcnRzV2l0aCIsInRyaWdnZXJCZWZvcmVFcnJvciIsInByb21pc2UiLCJpbmZsYXRlIiwiZGF0YSIsInJlc3RPYmplY3QiLCJjb3B5IiwicnVuTGl2ZVF1ZXJ5RXZlbnRIYW5kbGVycyIsImdldFJlcXVlc3RGaWxlT2JqZWN0IiwiZmlsZU9iamVjdCIsIm1heWJlUnVuRmlsZVRyaWdnZXIiLCJGaWxlQ2xhc3NOYW1lIiwiRmlsZSIsImZpbGVUcmlnZ2VyIiwiZm9yY2VEb3dubG9hZCIsImZpbGUiLCJmaWxlU2l6ZSIsIm1heWJlUnVuR2xvYmFsQ29uZmlnVHJpZ2dlciIsImNvbmZpZ09iamVjdCIsIm9yaWdpbmFsQ29uZmlnT2JqZWN0IiwiR2xvYmFsQ29uZmlnQ2xhc3NOYW1lIiwiQ29uZmlnIiwiY29uZmlnVHJpZ2dlciJdLCJzb3VyY2VzIjpbIi4uL3NyYy90cmlnZ2Vycy5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyB0cmlnZ2Vycy5qc1xuaW1wb3J0IFBhcnNlIGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXInO1xuXG5leHBvcnQgY29uc3QgVHlwZXMgPSB7XG4gIGJlZm9yZUxvZ2luOiAnYmVmb3JlTG9naW4nLFxuICBhZnRlckxvZ2luOiAnYWZ0ZXJMb2dpbicsXG4gIGFmdGVyTG9nb3V0OiAnYWZ0ZXJMb2dvdXQnLFxuICBiZWZvcmVQYXNzd29yZFJlc2V0UmVxdWVzdDogJ2JlZm9yZVBhc3N3b3JkUmVzZXRSZXF1ZXN0JyxcbiAgYmVmb3JlU2F2ZTogJ2JlZm9yZVNhdmUnLFxuICBhZnRlclNhdmU6ICdhZnRlclNhdmUnLFxuICBiZWZvcmVEZWxldGU6ICdiZWZvcmVEZWxldGUnLFxuICBhZnRlckRlbGV0ZTogJ2FmdGVyRGVsZXRlJyxcbiAgYmVmb3JlRmluZDogJ2JlZm9yZUZpbmQnLFxuICBhZnRlckZpbmQ6ICdhZnRlckZpbmQnLFxuICBiZWZvcmVDb25uZWN0OiAnYmVmb3JlQ29ubmVjdCcsXG4gIGJlZm9yZVN1YnNjcmliZTogJ2JlZm9yZVN1YnNjcmliZScsXG4gIGFmdGVyRXZlbnQ6ICdhZnRlckV2ZW50Jyxcbn07XG5cbmNvbnN0IENvbm5lY3RDbGFzc05hbWUgPSAnQENvbm5lY3QnO1xuXG5jb25zdCBiYXNlU3RvcmUgPSBmdW5jdGlvbiAoKSB7XG4gIGNvbnN0IFZhbGlkYXRvcnMgPSBPYmplY3Qua2V5cyhUeXBlcykucmVkdWNlKGZ1bmN0aW9uIChiYXNlLCBrZXkpIHtcbiAgICBiYXNlW2tleV0gPSB7fTtcbiAgICByZXR1cm4gYmFzZTtcbiAgfSwge30pO1xuICBjb25zdCBGdW5jdGlvbnMgPSB7fTtcbiAgY29uc3QgSm9icyA9IHt9O1xuICBjb25zdCBMaXZlUXVlcnkgPSBbXTtcbiAgY29uc3QgVHJpZ2dlcnMgPSBPYmplY3Qua2V5cyhUeXBlcykucmVkdWNlKGZ1bmN0aW9uIChiYXNlLCBrZXkpIHtcbiAgICBiYXNlW2tleV0gPSB7fTtcbiAgICByZXR1cm4gYmFzZTtcbiAgfSwge30pO1xuXG4gIHJldHVybiBPYmplY3QuZnJlZXplKHtcbiAgICBGdW5jdGlvbnMsXG4gICAgSm9icyxcbiAgICBWYWxpZGF0b3JzLFxuICAgIFRyaWdnZXJzLFxuICAgIExpdmVRdWVyeSxcbiAgfSk7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2xhc3NOYW1lKHBhcnNlQ2xhc3MpIHtcbiAgaWYgKHBhcnNlQ2xhc3MgJiYgcGFyc2VDbGFzcy5jbGFzc05hbWUpIHtcbiAgICByZXR1cm4gcGFyc2VDbGFzcy5jbGFzc05hbWU7XG4gIH1cbiAgaWYgKHBhcnNlQ2xhc3MgJiYgcGFyc2VDbGFzcy5uYW1lKSB7XG4gICAgcmV0dXJuIHBhcnNlQ2xhc3MubmFtZS5yZXBsYWNlKCdQYXJzZScsICdAJyk7XG4gIH1cbiAgcmV0dXJuIHBhcnNlQ2xhc3M7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlQ2xhc3NOYW1lRm9yVHJpZ2dlcnMoY2xhc3NOYW1lLCB0eXBlKSB7XG4gIGlmICh0eXBlID09IFR5cGVzLmJlZm9yZVNhdmUgJiYgY2xhc3NOYW1lID09PSAnX1B1c2hTdGF0dXMnKSB7XG4gICAgLy8gX1B1c2hTdGF0dXMgdXNlcyB1bmRvY3VtZW50ZWQgbmVzdGVkIGtleSBpbmNyZW1lbnQgb3BzXG4gICAgLy8gYWxsb3dpbmcgYmVmb3JlU2F2ZSB3b3VsZCBtZXNzIHVwIHRoZSBvYmplY3RzIGJpZyB0aW1lXG4gICAgLy8gVE9ETzogQWxsb3cgcHJvcGVyIGRvY3VtZW50ZWQgd2F5IG9mIHVzaW5nIG5lc3RlZCBpbmNyZW1lbnQgb3BzXG4gICAgdGhyb3cgJ09ubHkgYWZ0ZXJTYXZlIGlzIGFsbG93ZWQgb24gX1B1c2hTdGF0dXMnO1xuICB9XG4gIGlmICgodHlwZSA9PT0gVHlwZXMuYmVmb3JlTG9naW4gfHwgdHlwZSA9PT0gVHlwZXMuYWZ0ZXJMb2dpbiB8fCB0eXBlID09PSBUeXBlcy5iZWZvcmVQYXNzd29yZFJlc2V0UmVxdWVzdCkgJiYgY2xhc3NOYW1lICE9PSAnX1VzZXInKSB7XG4gICAgLy8gVE9ETzogY2hlY2sgaWYgdXBzdHJlYW0gY29kZSB3aWxsIGhhbmRsZSBgRXJyb3JgIGluc3RhbmNlIHJhdGhlclxuICAgIC8vIHRoYW4gdGhpcyBhbnRpLXBhdHRlcm4gb2YgdGhyb3dpbmcgc3RyaW5nc1xuICAgIHRocm93ICdPbmx5IHRoZSBfVXNlciBjbGFzcyBpcyBhbGxvd2VkIGZvciB0aGUgYmVmb3JlTG9naW4sIGFmdGVyTG9naW4sIGFuZCBiZWZvcmVQYXNzd29yZFJlc2V0UmVxdWVzdCB0cmlnZ2Vycyc7XG4gIH1cbiAgaWYgKHR5cGUgPT09IFR5cGVzLmFmdGVyTG9nb3V0ICYmIGNsYXNzTmFtZSAhPT0gJ19TZXNzaW9uJykge1xuICAgIC8vIFRPRE86IGNoZWNrIGlmIHVwc3RyZWFtIGNvZGUgd2lsbCBoYW5kbGUgYEVycm9yYCBpbnN0YW5jZSByYXRoZXJcbiAgICAvLyB0aGFuIHRoaXMgYW50aS1wYXR0ZXJuIG9mIHRocm93aW5nIHN0cmluZ3NcbiAgICB0aHJvdyAnT25seSB0aGUgX1Nlc3Npb24gY2xhc3MgaXMgYWxsb3dlZCBmb3IgdGhlIGFmdGVyTG9nb3V0IHRyaWdnZXIuJztcbiAgfVxuICBpZiAoY2xhc3NOYW1lID09PSAnX1Nlc3Npb24nICYmIHR5cGUgIT09IFR5cGVzLmFmdGVyTG9nb3V0KSB7XG4gICAgLy8gVE9ETzogY2hlY2sgaWYgdXBzdHJlYW0gY29kZSB3aWxsIGhhbmRsZSBgRXJyb3JgIGluc3RhbmNlIHJhdGhlclxuICAgIC8vIHRoYW4gdGhpcyBhbnRpLXBhdHRlcm4gb2YgdGhyb3dpbmcgc3RyaW5nc1xuICAgIHRocm93ICdPbmx5IHRoZSBhZnRlckxvZ291dCB0cmlnZ2VyIGlzIGFsbG93ZWQgZm9yIHRoZSBfU2Vzc2lvbiBjbGFzcy4nO1xuICB9XG4gIHJldHVybiBjbGFzc05hbWU7XG59XG5cbmNvbnN0IF90cmlnZ2VyU3RvcmUgPSB7fTtcblxuY29uc3QgQ2F0ZWdvcnkgPSB7XG4gIEZ1bmN0aW9uczogJ0Z1bmN0aW9ucycsXG4gIFZhbGlkYXRvcnM6ICdWYWxpZGF0b3JzJyxcbiAgSm9iczogJ0pvYnMnLFxuICBUcmlnZ2VyczogJ1RyaWdnZXJzJyxcbn07XG5cbmZ1bmN0aW9uIGdldFN0b3JlKGNhdGVnb3J5LCBuYW1lLCBhcHBsaWNhdGlvbklkKSB7XG4gIGNvbnN0IGludmFsaWROYW1lUmVnZXggPSAvWydcImBdLztcbiAgaWYgKGludmFsaWROYW1lUmVnZXgudGVzdChuYW1lKSkge1xuICAgIC8vIFByZXZlbnQgYSBtYWxpY2lvdXMgdXNlciBmcm9tIGluamVjdGluZyBwcm9wZXJ0aWVzIGludG8gdGhlIHN0b3JlXG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgY29uc3QgcGF0aCA9IG5hbWUuc3BsaXQoJy4nKTtcbiAgcGF0aC5zcGxpY2UoLTEpOyAvLyByZW1vdmUgbGFzdCBjb21wb25lbnRcbiAgYXBwbGljYXRpb25JZCA9IGFwcGxpY2F0aW9uSWQgfHwgUGFyc2UuYXBwbGljYXRpb25JZDtcbiAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSA9IF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0gfHwgYmFzZVN0b3JlKCk7XG4gIGxldCBzdG9yZSA9IF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF1bY2F0ZWdvcnldO1xuICBmb3IgKGNvbnN0IGNvbXBvbmVudCBvZiBwYXRoKSB7XG4gICAgc3RvcmUgPSBzdG9yZVtjb21wb25lbnRdO1xuICAgIGlmICghc3RvcmUpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHN0b3JlO1xufVxuXG5mdW5jdGlvbiBhZGQoY2F0ZWdvcnksIG5hbWUsIGhhbmRsZXIsIGFwcGxpY2F0aW9uSWQpIHtcbiAgY29uc3QgbGFzdENvbXBvbmVudCA9IG5hbWUuc3BsaXQoJy4nKS5zcGxpY2UoLTEpO1xuICBjb25zdCBzdG9yZSA9IGdldFN0b3JlKGNhdGVnb3J5LCBuYW1lLCBhcHBsaWNhdGlvbklkKTtcbiAgaWYgKHN0b3JlW2xhc3RDb21wb25lbnRdKSB7XG4gICAgbG9nZ2VyLndhcm4oXG4gICAgICBgV2FybmluZzogRHVwbGljYXRlIGNsb3VkIGZ1bmN0aW9ucyBleGlzdCBmb3IgJHtsYXN0Q29tcG9uZW50fS4gT25seSB0aGUgbGFzdCBvbmUgd2lsbCBiZSB1c2VkIGFuZCB0aGUgb3RoZXJzIHdpbGwgYmUgaWdub3JlZC5gXG4gICAgKTtcbiAgfVxuICBzdG9yZVtsYXN0Q29tcG9uZW50XSA9IGhhbmRsZXI7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZShjYXRlZ29yeSwgbmFtZSwgYXBwbGljYXRpb25JZCkge1xuICBjb25zdCBsYXN0Q29tcG9uZW50ID0gbmFtZS5zcGxpdCgnLicpLnNwbGljZSgtMSk7XG4gIGNvbnN0IHN0b3JlID0gZ2V0U3RvcmUoY2F0ZWdvcnksIG5hbWUsIGFwcGxpY2F0aW9uSWQpO1xuICBkZWxldGUgc3RvcmVbbGFzdENvbXBvbmVudF07XG59XG5cbmZ1bmN0aW9uIGdldChjYXRlZ29yeSwgbmFtZSwgYXBwbGljYXRpb25JZCkge1xuICBjb25zdCBsYXN0Q29tcG9uZW50ID0gbmFtZS5zcGxpdCgnLicpLnNwbGljZSgtMSk7XG4gIGNvbnN0IHN0b3JlID0gZ2V0U3RvcmUoY2F0ZWdvcnksIG5hbWUsIGFwcGxpY2F0aW9uSWQpO1xuICByZXR1cm4gc3RvcmVbbGFzdENvbXBvbmVudF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRGdW5jdGlvbihmdW5jdGlvbk5hbWUsIGhhbmRsZXIsIHZhbGlkYXRpb25IYW5kbGVyLCBhcHBsaWNhdGlvbklkKSB7XG4gIGFkZChDYXRlZ29yeS5GdW5jdGlvbnMsIGZ1bmN0aW9uTmFtZSwgaGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG4gIGFkZChDYXRlZ29yeS5WYWxpZGF0b3JzLCBmdW5jdGlvbk5hbWUsIHZhbGlkYXRpb25IYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZEpvYihqb2JOYW1lLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKSB7XG4gIGFkZChDYXRlZ29yeS5Kb2JzLCBqb2JOYW1lLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFRyaWdnZXIodHlwZSwgY2xhc3NOYW1lLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICB2YWxpZGF0ZUNsYXNzTmFtZUZvclRyaWdnZXJzKGNsYXNzTmFtZSwgdHlwZSk7XG4gIGFkZChDYXRlZ29yeS5UcmlnZ2VycywgYCR7dHlwZX0uJHtjbGFzc05hbWV9YCwgaGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG4gIGFkZChDYXRlZ29yeS5WYWxpZGF0b3JzLCBgJHt0eXBlfS4ke2NsYXNzTmFtZX1gLCB2YWxpZGF0aW9uSGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRDb25uZWN0VHJpZ2dlcih0eXBlLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkLCB2YWxpZGF0aW9uSGFuZGxlcikge1xuICBhZGQoQ2F0ZWdvcnkuVHJpZ2dlcnMsIGAke3R5cGV9LiR7Q29ubmVjdENsYXNzTmFtZX1gLCBoYW5kbGVyLCBhcHBsaWNhdGlvbklkKTtcbiAgYWRkKENhdGVnb3J5LlZhbGlkYXRvcnMsIGAke3R5cGV9LiR7Q29ubmVjdENsYXNzTmFtZX1gLCB2YWxpZGF0aW9uSGFuZGxlciwgYXBwbGljYXRpb25JZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRMaXZlUXVlcnlFdmVudEhhbmRsZXIoaGFuZGxlciwgYXBwbGljYXRpb25JZCkge1xuICBhcHBsaWNhdGlvbklkID0gYXBwbGljYXRpb25JZCB8fCBQYXJzZS5hcHBsaWNhdGlvbklkO1xuICBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdID0gX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXSB8fCBiYXNlU3RvcmUoKTtcbiAgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXS5MaXZlUXVlcnkucHVzaChoYW5kbGVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICByZW1vdmUoQ2F0ZWdvcnkuRnVuY3Rpb25zLCBmdW5jdGlvbk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlVHJpZ2dlcih0eXBlLCBjbGFzc05hbWUsIGFwcGxpY2F0aW9uSWQpIHtcbiAgcmVtb3ZlKENhdGVnb3J5LlRyaWdnZXJzLCBgJHt0eXBlfS4ke2NsYXNzTmFtZX1gLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIF91bnJlZ2lzdGVyQWxsKCkge1xuICBPYmplY3Qua2V5cyhfdHJpZ2dlclN0b3JlKS5mb3JFYWNoKGFwcElkID0+IGRlbGV0ZSBfdHJpZ2dlclN0b3JlW2FwcElkXSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0b0pTT053aXRoT2JqZWN0cyhvYmplY3QsIGNsYXNzTmFtZSkge1xuICBpZiAoIW9iamVjdCB8fCAhb2JqZWN0LnRvSlNPTikge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICBjb25zdCB0b0pTT04gPSBvYmplY3QudG9KU09OKCk7XG4gIGNvbnN0IHN0YXRlQ29udHJvbGxlciA9IFBhcnNlLkNvcmVNYW5hZ2VyLmdldE9iamVjdFN0YXRlQ29udHJvbGxlcigpO1xuICBjb25zdCBbcGVuZGluZ10gPSBzdGF0ZUNvbnRyb2xsZXIuZ2V0UGVuZGluZ09wcyhvYmplY3QuX2dldFN0YXRlSWRlbnRpZmllcigpKTtcbiAgZm9yIChjb25zdCBrZXkgaW4gcGVuZGluZykge1xuICAgIGNvbnN0IHZhbCA9IG9iamVjdC5nZXQoa2V5KTtcbiAgICBpZiAoIXZhbCB8fCAhdmFsLl90b0Z1bGxKU09OKSB7XG4gICAgICB0b0pTT05ba2V5XSA9IHZhbDtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB0b0pTT05ba2V5XSA9IHZhbC5fdG9GdWxsSlNPTigpO1xuICB9XG4gIC8vIFByZXNlcnZlIG9yaWdpbmFsIG9iamVjdCdzIGNsYXNzTmFtZSBpZiBubyBvdmVycmlkZSBjbGFzc05hbWUgaXMgcHJvdmlkZWRcbiAgaWYgKGNsYXNzTmFtZSkge1xuICAgIHRvSlNPTi5jbGFzc05hbWUgPSBjbGFzc05hbWU7XG4gIH0gZWxzZSBpZiAob2JqZWN0LmNsYXNzTmFtZSAmJiAhdG9KU09OLmNsYXNzTmFtZSkge1xuICAgIHRvSlNPTi5jbGFzc05hbWUgPSBvYmplY3QuY2xhc3NOYW1lO1xuICB9XG4gIHJldHVybiB0b0pTT047XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUcmlnZ2VyKGNsYXNzTmFtZSwgdHJpZ2dlclR5cGUsIGFwcGxpY2F0aW9uSWQpIHtcbiAgaWYgKCFhcHBsaWNhdGlvbklkKSB7XG4gICAgdGhyb3cgJ01pc3NpbmcgQXBwbGljYXRpb25JRCc7XG4gIH1cbiAgcmV0dXJuIGdldChDYXRlZ29yeS5UcmlnZ2VycywgYCR7dHJpZ2dlclR5cGV9LiR7Y2xhc3NOYW1lfWAsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuVHJpZ2dlcih0cmlnZ2VyLCBuYW1lLCByZXF1ZXN0LCBhdXRoKSB7XG4gIGlmICghdHJpZ2dlcikge1xuICAgIHJldHVybjtcbiAgfVxuICBhd2FpdCBtYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0LCBuYW1lLCBhdXRoKTtcbiAgaWYgKHJlcXVlc3Quc2tpcFdpdGhNYXN0ZXJLZXkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgcmV0dXJuIGF3YWl0IHRyaWdnZXIocmVxdWVzdCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0cmlnZ2VyRXhpc3RzKGNsYXNzTmFtZTogc3RyaW5nLCB0eXBlOiBzdHJpbmcsIGFwcGxpY2F0aW9uSWQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gZ2V0VHJpZ2dlcihjbGFzc05hbWUsIHR5cGUsIGFwcGxpY2F0aW9uSWQpICE9IHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZ1bmN0aW9uKGZ1bmN0aW9uTmFtZSwgYXBwbGljYXRpb25JZCkge1xuICByZXR1cm4gZ2V0KENhdGVnb3J5LkZ1bmN0aW9ucywgZnVuY3Rpb25OYW1lLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZ1bmN0aW9uTmFtZXMoYXBwbGljYXRpb25JZCkge1xuICBjb25zdCBzdG9yZSA9XG4gICAgKF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF0gJiYgX3RyaWdnZXJTdG9yZVthcHBsaWNhdGlvbklkXVtDYXRlZ29yeS5GdW5jdGlvbnNdKSB8fCB7fTtcbiAgY29uc3QgZnVuY3Rpb25OYW1lcyA9IFtdO1xuICBjb25zdCBleHRyYWN0RnVuY3Rpb25OYW1lcyA9IChuYW1lc3BhY2UsIHN0b3JlKSA9PiB7XG4gICAgT2JqZWN0LmtleXMoc3RvcmUpLmZvckVhY2gobmFtZSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHN0b3JlW25hbWVdO1xuICAgICAgaWYgKG5hbWVzcGFjZSkge1xuICAgICAgICBuYW1lID0gYCR7bmFtZXNwYWNlfS4ke25hbWV9YDtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgZnVuY3Rpb25OYW1lcy5wdXNoKG5hbWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZXh0cmFjdEZ1bmN0aW9uTmFtZXMobmFtZSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuICBleHRyYWN0RnVuY3Rpb25OYW1lcyhudWxsLCBzdG9yZSk7XG4gIHJldHVybiBmdW5jdGlvbk5hbWVzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Sm9iKGpvYk5hbWUsIGFwcGxpY2F0aW9uSWQpIHtcbiAgcmV0dXJuIGdldChDYXRlZ29yeS5Kb2JzLCBqb2JOYW1lLCBhcHBsaWNhdGlvbklkKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEpvYnMoYXBwbGljYXRpb25JZCkge1xuICB2YXIgbWFuYWdlciA9IF90cmlnZ2VyU3RvcmVbYXBwbGljYXRpb25JZF07XG4gIGlmIChtYW5hZ2VyICYmIG1hbmFnZXIuSm9icykge1xuICAgIHJldHVybiBtYW5hZ2VyLkpvYnM7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFZhbGlkYXRvcihmdW5jdGlvbk5hbWUsIGFwcGxpY2F0aW9uSWQpIHtcbiAgcmV0dXJuIGdldChDYXRlZ29yeS5WYWxpZGF0b3JzLCBmdW5jdGlvbk5hbWUsIGFwcGxpY2F0aW9uSWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVxdWVzdE9iamVjdChcbiAgdHJpZ2dlclR5cGUsXG4gIGF1dGgsXG4gIHBhcnNlT2JqZWN0LFxuICBvcmlnaW5hbFBhcnNlT2JqZWN0LFxuICBjb25maWcsXG4gIGNvbnRleHQsXG4gIGlzR2V0XG4pIHtcbiAgY29uc3QgcmVxdWVzdCA9IHtcbiAgICB0cmlnZ2VyTmFtZTogdHJpZ2dlclR5cGUsXG4gICAgb2JqZWN0OiBwYXJzZU9iamVjdCxcbiAgICBtYXN0ZXI6IGZhbHNlLFxuICAgIGxvZzogY29uZmlnLmxvZ2dlckNvbnRyb2xsZXIsXG4gICAgaGVhZGVyczogY29uZmlnLmhlYWRlcnMsXG4gICAgaXA6IGNvbmZpZy5pcCxcbiAgICBjb25maWcsXG4gIH07XG5cbiAgaWYgKGlzR2V0ICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXF1ZXN0LmlzR2V0ID0gISFpc0dldDtcbiAgfVxuXG4gIGlmIChvcmlnaW5hbFBhcnNlT2JqZWN0KSB7XG4gICAgcmVxdWVzdC5vcmlnaW5hbCA9IG9yaWdpbmFsUGFyc2VPYmplY3Q7XG4gIH1cbiAgaWYgKFxuICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5iZWZvcmVTYXZlIHx8XG4gICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmFmdGVyU2F2ZSB8fFxuICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5iZWZvcmVEZWxldGUgfHxcbiAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYWZ0ZXJEZWxldGUgfHxcbiAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYmVmb3JlTG9naW4gfHxcbiAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYWZ0ZXJMb2dpbiB8fFxuICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5iZWZvcmVQYXNzd29yZFJlc2V0UmVxdWVzdCB8fFxuICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5hZnRlckZpbmRcbiAgKSB7XG4gICAgLy8gU2V0IGEgY29weSBvZiB0aGUgY29udGV4dCBvbiB0aGUgcmVxdWVzdCBvYmplY3QuXG4gICAgcmVxdWVzdC5jb250ZXh0ID0gT2JqZWN0LmFzc2lnbih7fSwgY29udGV4dCk7XG4gIH1cblxuICBpZiAoIWF1dGgpIHtcbiAgICByZXR1cm4gcmVxdWVzdDtcbiAgfVxuICBpZiAoYXV0aC5pc01hc3Rlcikge1xuICAgIHJlcXVlc3RbJ21hc3RlciddID0gdHJ1ZTtcbiAgfVxuICBpZiAoYXV0aC51c2VyKSB7XG4gICAgcmVxdWVzdFsndXNlciddID0gYXV0aC51c2VyO1xuICB9XG4gIGlmIChhdXRoLmluc3RhbGxhdGlvbklkKSB7XG4gICAgcmVxdWVzdFsnaW5zdGFsbGF0aW9uSWQnXSA9IGF1dGguaW5zdGFsbGF0aW9uSWQ7XG4gIH1cbiAgcmV0dXJuIHJlcXVlc3Q7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXF1ZXN0UXVlcnlPYmplY3QodHJpZ2dlclR5cGUsIGF1dGgsIHF1ZXJ5LCBjb3VudCwgY29uZmlnLCBjb250ZXh0LCBpc0dldCkge1xuICBpc0dldCA9ICEhaXNHZXQ7XG5cbiAgdmFyIHJlcXVlc3QgPSB7XG4gICAgdHJpZ2dlck5hbWU6IHRyaWdnZXJUeXBlLFxuICAgIHF1ZXJ5LFxuICAgIG1hc3RlcjogZmFsc2UsXG4gICAgY291bnQsXG4gICAgbG9nOiBjb25maWcubG9nZ2VyQ29udHJvbGxlcixcbiAgICBpc0dldCxcbiAgICBoZWFkZXJzOiBjb25maWcuaGVhZGVycyxcbiAgICBpcDogY29uZmlnLmlwLFxuICAgIGNvbnRleHQ6IGNvbnRleHQgfHwge30sXG4gICAgY29uZmlnLFxuICB9O1xuXG4gIGlmICghYXV0aCkge1xuICAgIHJldHVybiByZXF1ZXN0O1xuICB9XG4gIGlmIChhdXRoLmlzTWFzdGVyKSB7XG4gICAgcmVxdWVzdFsnbWFzdGVyJ10gPSB0cnVlO1xuICB9XG4gIGlmIChhdXRoLnVzZXIpIHtcbiAgICByZXF1ZXN0Wyd1c2VyJ10gPSBhdXRoLnVzZXI7XG4gIH1cbiAgaWYgKGF1dGguaW5zdGFsbGF0aW9uSWQpIHtcbiAgICByZXF1ZXN0WydpbnN0YWxsYXRpb25JZCddID0gYXV0aC5pbnN0YWxsYXRpb25JZDtcbiAgfVxuICByZXR1cm4gcmVxdWVzdDtcbn1cblxuLy8gQ3JlYXRlcyB0aGUgcmVzcG9uc2Ugb2JqZWN0LCBhbmQgdXNlcyB0aGUgcmVxdWVzdCBvYmplY3QgdG8gcGFzcyBkYXRhXG4vLyBUaGUgQVBJIHdpbGwgY2FsbCB0aGlzIHdpdGggUkVTVCBBUEkgZm9ybWF0dGVkIG9iamVjdHMsIHRoaXMgd2lsbFxuLy8gdHJhbnNmb3JtIHRoZW0gdG8gUGFyc2UuT2JqZWN0IGluc3RhbmNlcyBleHBlY3RlZCBieSBDbG91ZCBDb2RlLlxuLy8gQW55IGNoYW5nZXMgbWFkZSB0byB0aGUgb2JqZWN0IGluIGEgYmVmb3JlU2F2ZSB3aWxsIGJlIGluY2x1ZGVkLlxuZXhwb3J0IGZ1bmN0aW9uIGdldFJlc3BvbnNlT2JqZWN0KHJlcXVlc3QsIHJlc29sdmUsIHJlamVjdCkge1xuICByZXR1cm4ge1xuICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgaWYgKHJlcXVlc3QudHJpZ2dlck5hbWUgPT09IFR5cGVzLmFmdGVyRmluZCkge1xuICAgICAgICBpZiAoIXJlc3BvbnNlKSB7XG4gICAgICAgICAgcmVzcG9uc2UgPSByZXF1ZXN0Lm9iamVjdHM7XG4gICAgICAgIH1cbiAgICAgICAgcmVzcG9uc2UgPSByZXNwb25zZS5tYXAob2JqZWN0ID0+IHtcbiAgICAgICAgICByZXR1cm4gdG9KU09Od2l0aE9iamVjdHMob2JqZWN0KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICAgIH1cbiAgICAgIC8vIFVzZSB0aGUgSlNPTiByZXNwb25zZVxuICAgICAgaWYgKFxuICAgICAgICByZXNwb25zZSAmJlxuICAgICAgICB0eXBlb2YgcmVzcG9uc2UgPT09ICdvYmplY3QnICYmXG4gICAgICAgICFyZXF1ZXN0Lm9iamVjdC5lcXVhbHMocmVzcG9uc2UpICYmXG4gICAgICAgIHJlcXVlc3QudHJpZ2dlck5hbWUgPT09IFR5cGVzLmJlZm9yZVNhdmVcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZShyZXNwb25zZSk7XG4gICAgICB9XG4gICAgICBpZiAocmVzcG9uc2UgJiYgdHlwZW9mIHJlc3BvbnNlID09PSAnb2JqZWN0JyAmJiByZXF1ZXN0LnRyaWdnZXJOYW1lID09PSBUeXBlcy5hZnRlclNhdmUpIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzcG9uc2UpO1xuICAgICAgfVxuICAgICAgaWYgKHJlcXVlc3QudHJpZ2dlck5hbWUgPT09IFR5cGVzLmFmdGVyU2F2ZSkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgfVxuICAgICAgcmVzcG9uc2UgPSB7fTtcbiAgICAgIGlmIChyZXF1ZXN0LnRyaWdnZXJOYW1lID09PSBUeXBlcy5iZWZvcmVTYXZlKSB7XG4gICAgICAgIHJlc3BvbnNlWydvYmplY3QnXSA9IHJlcXVlc3Qub2JqZWN0Ll9nZXRTYXZlSlNPTigpO1xuICAgICAgICByZXNwb25zZVsnb2JqZWN0J11bJ29iamVjdElkJ10gPSByZXF1ZXN0Lm9iamVjdC5pZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXNvbHZlKHJlc3BvbnNlKTtcbiAgICB9LFxuICAgIGVycm9yOiBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgIGNvbnN0IGUgPSByZXNvbHZlRXJyb3IoZXJyb3IsIHtcbiAgICAgICAgY29kZTogUGFyc2UuRXJyb3IuU0NSSVBUX0ZBSUxFRCxcbiAgICAgICAgbWVzc2FnZTogJ1NjcmlwdCBmYWlsZWQuIFVua25vd24gZXJyb3IuJyxcbiAgICAgIH0pO1xuICAgICAgcmVqZWN0KGUpO1xuICAgIH0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIHVzZXJJZEZvckxvZyhhdXRoKSB7XG4gIHJldHVybiBhdXRoICYmIGF1dGgudXNlciA/IGF1dGgudXNlci5pZCA6IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gbG9nVHJpZ2dlckFmdGVySG9vayh0cmlnZ2VyVHlwZSwgY2xhc3NOYW1lLCBpbnB1dCwgYXV0aCwgbG9nTGV2ZWwpIHtcbiAgaWYgKGxvZ0xldmVsID09PSAnc2lsZW50Jykge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCBjbGVhbklucHV0ID0gbG9nZ2VyLnRydW5jYXRlTG9nTWVzc2FnZShKU09OLnN0cmluZ2lmeShpbnB1dCkpO1xuICBsb2dnZXJbbG9nTGV2ZWxdKFxuICAgIGAke3RyaWdnZXJUeXBlfSB0cmlnZ2VyZWQgZm9yICR7Y2xhc3NOYW1lfSBmb3IgdXNlciAke3VzZXJJZEZvckxvZyhcbiAgICAgIGF1dGhcbiAgICApfTpcXG4gIElucHV0OiAke2NsZWFuSW5wdXR9YCxcbiAgICB7XG4gICAgICBjbGFzc05hbWUsXG4gICAgICB0cmlnZ2VyVHlwZSxcbiAgICAgIHVzZXI6IHVzZXJJZEZvckxvZyhhdXRoKSxcbiAgICB9XG4gICk7XG59XG5cbmZ1bmN0aW9uIGxvZ1RyaWdnZXJTdWNjZXNzQmVmb3JlSG9vayh0cmlnZ2VyVHlwZSwgY2xhc3NOYW1lLCBpbnB1dCwgcmVzdWx0LCBhdXRoLCBsb2dMZXZlbCkge1xuICBpZiAobG9nTGV2ZWwgPT09ICdzaWxlbnQnKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGNvbnN0IGNsZWFuSW5wdXQgPSBsb2dnZXIudHJ1bmNhdGVMb2dNZXNzYWdlKEpTT04uc3RyaW5naWZ5KGlucHV0KSk7XG4gIGNvbnN0IGNsZWFuUmVzdWx0ID0gbG9nZ2VyLnRydW5jYXRlTG9nTWVzc2FnZShKU09OLnN0cmluZ2lmeShyZXN1bHQpKTtcbiAgbG9nZ2VyW2xvZ0xldmVsXShcbiAgICBgJHt0cmlnZ2VyVHlwZX0gdHJpZ2dlcmVkIGZvciAke2NsYXNzTmFtZX0gZm9yIHVzZXIgJHt1c2VySWRGb3JMb2coXG4gICAgICBhdXRoXG4gICAgKX06XFxuICBJbnB1dDogJHtjbGVhbklucHV0fVxcbiAgUmVzdWx0OiAke2NsZWFuUmVzdWx0fWAsXG4gICAge1xuICAgICAgY2xhc3NOYW1lLFxuICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICB1c2VyOiB1c2VySWRGb3JMb2coYXV0aCksXG4gICAgfVxuICApO1xufVxuXG5mdW5jdGlvbiBsb2dUcmlnZ2VyRXJyb3JCZWZvcmVIb29rKHRyaWdnZXJUeXBlLCBjbGFzc05hbWUsIGlucHV0LCBhdXRoLCBlcnJvciwgbG9nTGV2ZWwpIHtcbiAgaWYgKGxvZ0xldmVsID09PSAnc2lsZW50Jykge1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCBjbGVhbklucHV0ID0gbG9nZ2VyLnRydW5jYXRlTG9nTWVzc2FnZShKU09OLnN0cmluZ2lmeShpbnB1dCkpO1xuICBsb2dnZXJbbG9nTGV2ZWxdKFxuICAgIGAke3RyaWdnZXJUeXBlfSBmYWlsZWQgZm9yICR7Y2xhc3NOYW1lfSBmb3IgdXNlciAke3VzZXJJZEZvckxvZyhcbiAgICAgIGF1dGhcbiAgICApfTpcXG4gIElucHV0OiAke2NsZWFuSW5wdXR9XFxuICBFcnJvcjogJHtKU09OLnN0cmluZ2lmeShlcnJvcil9YCxcbiAgICB7XG4gICAgICBjbGFzc05hbWUsXG4gICAgICB0cmlnZ2VyVHlwZSxcbiAgICAgIGVycm9yLFxuICAgICAgdXNlcjogdXNlcklkRm9yTG9nKGF1dGgpLFxuICAgIH1cbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1heWJlUnVuQWZ0ZXJGaW5kVHJpZ2dlcihcbiAgdHJpZ2dlclR5cGUsXG4gIGF1dGgsXG4gIGNsYXNzTmFtZVF1ZXJ5LFxuICBvYmplY3RzSW5wdXQsXG4gIGNvbmZpZyxcbiAgcXVlcnksXG4gIGNvbnRleHQsXG4gIGlzR2V0XG4pIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjb25zdCB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihjbGFzc05hbWVRdWVyeSwgdHJpZ2dlclR5cGUsIGNvbmZpZy5hcHBsaWNhdGlvbklkKTtcblxuICAgIGlmICghdHJpZ2dlcikge1xuICAgICAgaWYgKG9iamVjdHNJbnB1dCAmJiBvYmplY3RzSW5wdXQubGVuZ3RoID4gMCAmJiBvYmplY3RzSW5wdXRbMF0gaW5zdGFuY2VvZiBQYXJzZS5PYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIHJlc29sdmUob2JqZWN0c0lucHV0Lm1hcChvYmogPT4gdG9KU09Od2l0aE9iamVjdHMob2JqKSkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc29sdmUob2JqZWN0c0lucHV0IHx8IFtdKTtcbiAgICB9XG5cbiAgICBjb25zdCByZXF1ZXN0ID0gZ2V0UmVxdWVzdE9iamVjdCh0cmlnZ2VyVHlwZSwgYXV0aCwgbnVsbCwgbnVsbCwgY29uZmlnLCBjb250ZXh0LCBpc0dldCk7XG4gICAgLy8gQ29udmVydCBxdWVyeSBwYXJhbWV0ZXIgdG8gUGFyc2UuUXVlcnkgaW5zdGFuY2VcbiAgICBpZiAocXVlcnkgaW5zdGFuY2VvZiBQYXJzZS5RdWVyeSkge1xuICAgICAgcmVxdWVzdC5xdWVyeSA9IHF1ZXJ5O1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHF1ZXJ5ID09PSAnb2JqZWN0JyAmJiBxdWVyeSAhPT0gbnVsbCkge1xuICAgICAgY29uc3QgcGFyc2VRdWVyeUluc3RhbmNlID0gbmV3IFBhcnNlLlF1ZXJ5KGNsYXNzTmFtZVF1ZXJ5KTtcbiAgICAgIGlmIChxdWVyeS53aGVyZSkge1xuICAgICAgICBwYXJzZVF1ZXJ5SW5zdGFuY2Uud2l0aEpTT04ocXVlcnkpO1xuICAgICAgfVxuICAgICAgcmVxdWVzdC5xdWVyeSA9IHBhcnNlUXVlcnlJbnN0YW5jZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVxdWVzdC5xdWVyeSA9IG5ldyBQYXJzZS5RdWVyeShjbGFzc05hbWVRdWVyeSk7XG4gICAgfVxuXG4gICAgY29uc3QgeyBzdWNjZXNzLCBlcnJvciB9ID0gZ2V0UmVzcG9uc2VPYmplY3QoXG4gICAgICByZXF1ZXN0LFxuICAgICAgcHJvY2Vzc2VkT2JqZWN0c0pTT04gPT4ge1xuICAgICAgICByZXNvbHZlKHByb2Nlc3NlZE9iamVjdHNKU09OKTtcbiAgICAgIH0sXG4gICAgICBlcnJvckRhdGEgPT4ge1xuICAgICAgICByZWplY3QoZXJyb3JEYXRhKTtcbiAgICAgIH1cbiAgICApO1xuICAgIGxvZ1RyaWdnZXJTdWNjZXNzQmVmb3JlSG9vayhcbiAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgY2xhc3NOYW1lUXVlcnksXG4gICAgICAnQWZ0ZXJGaW5kIElucHV0IChQcmUtVHJhbnNmb3JtKScsXG4gICAgICBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgb2JqZWN0c0lucHV0Lm1hcChvID0+IChvIGluc3RhbmNlb2YgUGFyc2UuT2JqZWN0ID8gby5pZCArICc6JyArIG8uY2xhc3NOYW1lIDogbykpXG4gICAgICApLFxuICAgICAgYXV0aCxcbiAgICAgIGNvbmZpZy5sb2dMZXZlbHMudHJpZ2dlckJlZm9yZVN1Y2Nlc3NcbiAgICApO1xuXG4gICAgLy8gQ29udmVydCBwbGFpbiBvYmplY3RzIHRvIFBhcnNlLk9iamVjdCBpbnN0YW5jZXMgZm9yIHRyaWdnZXJcbiAgICByZXF1ZXN0Lm9iamVjdHMgPSBvYmplY3RzSW5wdXQubWFwKGN1cnJlbnRPYmplY3QgPT4ge1xuICAgICAgaWYgKGN1cnJlbnRPYmplY3QgaW5zdGFuY2VvZiBQYXJzZS5PYmplY3QpIHtcbiAgICAgICAgcmV0dXJuIGN1cnJlbnRPYmplY3Q7XG4gICAgICB9XG4gICAgICAvLyBQcmVzZXJ2ZSB0aGUgb3JpZ2luYWwgY2xhc3NOYW1lIGlmIGl0IGV4aXN0cywgb3RoZXJ3aXNlIHVzZSB0aGUgcXVlcnkgY2xhc3NOYW1lXG4gICAgICBjb25zdCBvcmlnaW5hbENsYXNzTmFtZSA9IGN1cnJlbnRPYmplY3QuY2xhc3NOYW1lIHx8IGNsYXNzTmFtZVF1ZXJ5O1xuICAgICAgY29uc3QgdGVtcE9iamVjdFdpdGhDbGFzc05hbWUgPSB7IC4uLmN1cnJlbnRPYmplY3QsIGNsYXNzTmFtZTogb3JpZ2luYWxDbGFzc05hbWUgfTtcbiAgICAgIHJldHVybiBQYXJzZS5PYmplY3QuZnJvbUpTT04odGVtcE9iamVjdFdpdGhDbGFzc05hbWUpO1xuICAgIH0pO1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gbWF5YmVSdW5WYWxpZGF0b3IocmVxdWVzdCwgYCR7dHJpZ2dlclR5cGV9LiR7Y2xhc3NOYW1lUXVlcnl9YCwgYXV0aCk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBpZiAocmVxdWVzdC5za2lwV2l0aE1hc3RlcktleSkge1xuICAgICAgICAgIHJldHVybiByZXF1ZXN0Lm9iamVjdHM7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVzcG9uc2VGcm9tVHJpZ2dlciA9IHRyaWdnZXIocmVxdWVzdCk7XG4gICAgICAgIGlmIChyZXNwb25zZUZyb21UcmlnZ2VyICYmIHR5cGVvZiByZXNwb25zZUZyb21UcmlnZ2VyLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICByZXR1cm4gcmVzcG9uc2VGcm9tVHJpZ2dlci50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlRnJvbVRyaWdnZXI7XG4gICAgICB9KVxuICAgICAgLnRoZW4oc3VjY2VzcywgZXJyb3IpO1xuICB9KS50aGVuKHJlc3VsdHNBc0pTT04gPT4ge1xuICAgIGxvZ1RyaWdnZXJBZnRlckhvb2soXG4gICAgICB0cmlnZ2VyVHlwZSxcbiAgICAgIGNsYXNzTmFtZVF1ZXJ5LFxuICAgICAgSlNPTi5zdHJpbmdpZnkocmVzdWx0c0FzSlNPTiksXG4gICAgICBhdXRoLFxuICAgICAgY29uZmlnLmxvZ0xldmVscy50cmlnZ2VyQWZ0ZXJcbiAgICApO1xuICAgIHJldHVybiByZXN1bHRzQXNKU09OO1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1heWJlUnVuUXVlcnlUcmlnZ2VyKFxuICB0cmlnZ2VyVHlwZSxcbiAgY2xhc3NOYW1lLFxuICByZXN0V2hlcmUsXG4gIHJlc3RPcHRpb25zLFxuICBjb25maWcsXG4gIGF1dGgsXG4gIGNvbnRleHQsXG4gIGlzR2V0XG4pIHtcbiAgY29uc3QgdHJpZ2dlciA9IGdldFRyaWdnZXIoY2xhc3NOYW1lLCB0cmlnZ2VyVHlwZSwgY29uZmlnLmFwcGxpY2F0aW9uSWQpO1xuICBpZiAoIXRyaWdnZXIpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgIHJlc3RXaGVyZSxcbiAgICAgIHJlc3RPcHRpb25zLFxuICAgIH0pO1xuICB9XG4gIGNvbnN0IGpzb24gPSBPYmplY3QuYXNzaWduKHt9LCByZXN0T3B0aW9ucyk7XG4gIGpzb24ud2hlcmUgPSByZXN0V2hlcmU7XG5cbiAgY29uc3QgcGFyc2VRdWVyeSA9IG5ldyBQYXJzZS5RdWVyeShjbGFzc05hbWUpO1xuICBwYXJzZVF1ZXJ5LndpdGhKU09OKGpzb24pO1xuXG4gIGxldCBjb3VudCA9IGZhbHNlO1xuICBpZiAocmVzdE9wdGlvbnMpIHtcbiAgICBjb3VudCA9ICEhcmVzdE9wdGlvbnMuY291bnQ7XG4gIH1cbiAgY29uc3QgcmVxdWVzdE9iamVjdCA9IGdldFJlcXVlc3RRdWVyeU9iamVjdChcbiAgICB0cmlnZ2VyVHlwZSxcbiAgICBhdXRoLFxuICAgIHBhcnNlUXVlcnksXG4gICAgY291bnQsXG4gICAgY29uZmlnLFxuICAgIGNvbnRleHQsXG4gICAgaXNHZXRcbiAgKTtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIG1heWJlUnVuVmFsaWRhdG9yKHJlcXVlc3RPYmplY3QsIGAke3RyaWdnZXJUeXBlfS4ke2NsYXNzTmFtZX1gLCBhdXRoKTtcbiAgICB9KVxuICAgIC50aGVuKCgpID0+IHtcbiAgICAgIGlmIChyZXF1ZXN0T2JqZWN0LnNraXBXaXRoTWFzdGVyS2V5KSB7XG4gICAgICAgIHJldHVybiByZXF1ZXN0T2JqZWN0LnF1ZXJ5O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRyaWdnZXIocmVxdWVzdE9iamVjdCk7XG4gICAgfSlcbiAgICAudGhlbihcbiAgICAgIHJlc3VsdCA9PiB7XG4gICAgICAgIGxldCBxdWVyeVJlc3VsdCA9IHBhcnNlUXVlcnk7XG4gICAgICAgIGlmIChyZXN1bHQgJiYgcmVzdWx0IGluc3RhbmNlb2YgUGFyc2UuUXVlcnkpIHtcbiAgICAgICAgICBxdWVyeVJlc3VsdCA9IHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBqc29uUXVlcnkgPSBxdWVyeVJlc3VsdC50b0pTT04oKTtcbiAgICAgICAgaWYgKGpzb25RdWVyeS53aGVyZSkge1xuICAgICAgICAgIHJlc3RXaGVyZSA9IGpzb25RdWVyeS53aGVyZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoanNvblF1ZXJ5LmxpbWl0KSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5saW1pdCA9IGpzb25RdWVyeS5saW1pdDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoanNvblF1ZXJ5LnNraXApIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLnNraXAgPSBqc29uUXVlcnkuc2tpcDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoanNvblF1ZXJ5LmluY2x1ZGUpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLmluY2x1ZGUgPSBqc29uUXVlcnkuaW5jbHVkZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoanNvblF1ZXJ5LmV4Y2x1ZGVLZXlzKSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5leGNsdWRlS2V5cyA9IGpzb25RdWVyeS5leGNsdWRlS2V5cztcbiAgICAgICAgfVxuICAgICAgICBpZiAoanNvblF1ZXJ5LmV4cGxhaW4pIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLmV4cGxhaW4gPSBqc29uUXVlcnkuZXhwbGFpbjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoanNvblF1ZXJ5LmtleXMpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLmtleXMgPSBqc29uUXVlcnkua2V5cztcbiAgICAgICAgfVxuICAgICAgICBpZiAoanNvblF1ZXJ5Lm9yZGVyKSB7XG4gICAgICAgICAgcmVzdE9wdGlvbnMgPSByZXN0T3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICByZXN0T3B0aW9ucy5vcmRlciA9IGpzb25RdWVyeS5vcmRlcjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoanNvblF1ZXJ5LmhpbnQpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLmhpbnQgPSBqc29uUXVlcnkuaGludDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoanNvblF1ZXJ5LmNvbW1lbnQpIHtcbiAgICAgICAgICByZXN0T3B0aW9ucyA9IHJlc3RPcHRpb25zIHx8IHt9O1xuICAgICAgICAgIHJlc3RPcHRpb25zLmNvbW1lbnQgPSBqc29uUXVlcnkuY29tbWVudDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVxdWVzdE9iamVjdC5yZWFkUHJlZmVyZW5jZSkge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMucmVhZFByZWZlcmVuY2UgPSByZXF1ZXN0T2JqZWN0LnJlYWRQcmVmZXJlbmNlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXF1ZXN0T2JqZWN0LmluY2x1ZGVSZWFkUHJlZmVyZW5jZSkge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMuaW5jbHVkZVJlYWRQcmVmZXJlbmNlID0gcmVxdWVzdE9iamVjdC5pbmNsdWRlUmVhZFByZWZlcmVuY2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlcXVlc3RPYmplY3Quc3VicXVlcnlSZWFkUHJlZmVyZW5jZSkge1xuICAgICAgICAgIHJlc3RPcHRpb25zID0gcmVzdE9wdGlvbnMgfHwge307XG4gICAgICAgICAgcmVzdE9wdGlvbnMuc3VicXVlcnlSZWFkUHJlZmVyZW5jZSA9IHJlcXVlc3RPYmplY3Quc3VicXVlcnlSZWFkUHJlZmVyZW5jZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgb2JqZWN0cyA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIFBhcnNlLk9iamVjdCkge1xuICAgICAgICAgIG9iamVjdHMgPSBbcmVzdWx0XTtcbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBBcnJheS5pc0FycmF5KHJlc3VsdCkgJiZcbiAgICAgICAgICAoIXJlc3VsdC5sZW5ndGggfHwgcmVzdWx0LmV2ZXJ5KG9iaiA9PiBvYmogaW5zdGFuY2VvZiBQYXJzZS5PYmplY3QpKVxuICAgICAgICApIHtcbiAgICAgICAgICBvYmplY3RzID0gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcmVzdFdoZXJlLFxuICAgICAgICAgIHJlc3RPcHRpb25zLFxuICAgICAgICAgIG9iamVjdHMsXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgICAgZXJyID0+IHtcbiAgICAgICAgY29uc3QgZXJyb3IgPSByZXNvbHZlRXJyb3IoZXJyLCB7XG4gICAgICAgICAgY29kZTogUGFyc2UuRXJyb3IuU0NSSVBUX0ZBSUxFRCxcbiAgICAgICAgICBtZXNzYWdlOiAnU2NyaXB0IGZhaWxlZC4gVW5rbm93biBlcnJvci4nLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVFcnJvcihtZXNzYWdlLCBkZWZhdWx0T3B0cykge1xuICBpZiAoIWRlZmF1bHRPcHRzKSB7XG4gICAgZGVmYXVsdE9wdHMgPSB7fTtcbiAgfVxuICBpZiAoIW1lc3NhZ2UpIHtcbiAgICByZXR1cm4gbmV3IFBhcnNlLkVycm9yKFxuICAgICAgZGVmYXVsdE9wdHMuY29kZSB8fCBQYXJzZS5FcnJvci5TQ1JJUFRfRkFJTEVELFxuICAgICAgZGVmYXVsdE9wdHMubWVzc2FnZSB8fCAnU2NyaXB0IGZhaWxlZC4nXG4gICAgKTtcbiAgfVxuICBpZiAobWVzc2FnZSBpbnN0YW5jZW9mIFBhcnNlLkVycm9yKSB7XG4gICAgcmV0dXJuIG1lc3NhZ2U7XG4gIH1cblxuICBjb25zdCBjb2RlID0gZGVmYXVsdE9wdHMuY29kZSB8fCBQYXJzZS5FcnJvci5TQ1JJUFRfRkFJTEVEO1xuICAvLyBJZiBpdCdzIGFuIGVycm9yLCBtYXJrIGl0IGFzIGEgc2NyaXB0IGZhaWxlZFxuICBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIG5ldyBQYXJzZS5FcnJvcihjb2RlLCBtZXNzYWdlKTtcbiAgfVxuICBjb25zdCBlcnJvciA9IG5ldyBQYXJzZS5FcnJvcihjb2RlLCBtZXNzYWdlLm1lc3NhZ2UgfHwgbWVzc2FnZSk7XG4gIGlmIChtZXNzYWdlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICBlcnJvci5zdGFjayA9IG1lc3NhZ2Uuc3RhY2s7XG4gIH1cbiAgcmV0dXJuIGVycm9yO1xufVxuZXhwb3J0IGZ1bmN0aW9uIG1heWJlUnVuVmFsaWRhdG9yKHJlcXVlc3QsIGZ1bmN0aW9uTmFtZSwgYXV0aCkge1xuICBjb25zdCB0aGVWYWxpZGF0b3IgPSBnZXRWYWxpZGF0b3IoZnVuY3Rpb25OYW1lLCBQYXJzZS5hcHBsaWNhdGlvbklkKTtcbiAgaWYgKCF0aGVWYWxpZGF0b3IpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHR5cGVvZiB0aGVWYWxpZGF0b3IgPT09ICdvYmplY3QnICYmIHRoZVZhbGlkYXRvci5za2lwV2l0aE1hc3RlcktleSAmJiByZXF1ZXN0Lm1hc3Rlcikge1xuICAgIHJlcXVlc3Quc2tpcFdpdGhNYXN0ZXJLZXkgPSB0cnVlO1xuICB9XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHJldHVybiB0eXBlb2YgdGhlVmFsaWRhdG9yID09PSAnb2JqZWN0J1xuICAgICAgICAgID8gYnVpbHRJblRyaWdnZXJWYWxpZGF0b3IodGhlVmFsaWRhdG9yLCByZXF1ZXN0LCBhdXRoKVxuICAgICAgICAgIDogdGhlVmFsaWRhdG9yKHJlcXVlc3QpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlID0+IHtcbiAgICAgICAgY29uc3QgZXJyb3IgPSByZXNvbHZlRXJyb3IoZSwge1xuICAgICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLlZBTElEQVRJT05fRVJST1IsXG4gICAgICAgICAgbWVzc2FnZTogJ1ZhbGlkYXRpb24gZmFpbGVkLicsXG4gICAgICAgIH0pO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gIH0pO1xufVxuYXN5bmMgZnVuY3Rpb24gYnVpbHRJblRyaWdnZXJWYWxpZGF0b3Iob3B0aW9ucywgcmVxdWVzdCwgYXV0aCkge1xuICBpZiAocmVxdWVzdC5tYXN0ZXIgJiYgIW9wdGlvbnMudmFsaWRhdGVNYXN0ZXJLZXkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgbGV0IHJlcVVzZXIgPSByZXF1ZXN0LnVzZXI7XG4gIGlmIChcbiAgICAhcmVxVXNlciAmJlxuICAgIHJlcXVlc3Qub2JqZWN0ICYmXG4gICAgcmVxdWVzdC5vYmplY3QuY2xhc3NOYW1lID09PSAnX1VzZXInICYmXG4gICAgIXJlcXVlc3Qub2JqZWN0LmV4aXN0ZWQoKVxuICApIHtcbiAgICByZXFVc2VyID0gcmVxdWVzdC5vYmplY3Q7XG4gIH1cbiAgaWYgKFxuICAgIChvcHRpb25zLnJlcXVpcmVVc2VyIHx8IG9wdGlvbnMucmVxdWlyZUFueVVzZXJSb2xlcyB8fCBvcHRpb25zLnJlcXVpcmVBbGxVc2VyUm9sZXMpICYmXG4gICAgIXJlcVVzZXJcbiAgKSB7XG4gICAgdGhyb3cgJ1ZhbGlkYXRpb24gZmFpbGVkLiBQbGVhc2UgbG9naW4gdG8gY29udGludWUuJztcbiAgfVxuICBpZiAob3B0aW9ucy5yZXF1aXJlTWFzdGVyICYmICFyZXF1ZXN0Lm1hc3Rlcikge1xuICAgIHRocm93ICdWYWxpZGF0aW9uIGZhaWxlZC4gTWFzdGVyIGtleSBpcyByZXF1aXJlZCB0byBjb21wbGV0ZSB0aGlzIHJlcXVlc3QuJztcbiAgfVxuICBsZXQgcGFyYW1zID0gcmVxdWVzdC5wYXJhbXMgfHwge307XG4gIGlmIChyZXF1ZXN0Lm9iamVjdCkge1xuICAgIHBhcmFtcyA9IHJlcXVlc3Qub2JqZWN0LnRvSlNPTigpO1xuICB9XG4gIGNvbnN0IHJlcXVpcmVkUGFyYW0gPSBrZXkgPT4ge1xuICAgIGNvbnN0IHZhbHVlID0gcGFyYW1zW2tleV07XG4gICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgIHRocm93IGBWYWxpZGF0aW9uIGZhaWxlZC4gUGxlYXNlIHNwZWNpZnkgZGF0YSBmb3IgJHtrZXl9LmA7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IHZhbGlkYXRlT3B0aW9ucyA9IGFzeW5jIChvcHQsIGtleSwgdmFsKSA9PiB7XG4gICAgbGV0IG9wdHMgPSBvcHQub3B0aW9ucztcbiAgICBpZiAodHlwZW9mIG9wdHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG9wdHModmFsKTtcbiAgICAgICAgaWYgKCFyZXN1bHQgJiYgcmVzdWx0ICE9IG51bGwpIHtcbiAgICAgICAgICB0aHJvdyBvcHQuZXJyb3IgfHwgYFZhbGlkYXRpb24gZmFpbGVkLiBJbnZhbGlkIHZhbHVlIGZvciAke2tleX0uYDtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoIWUpIHtcbiAgICAgICAgICB0aHJvdyBvcHQuZXJyb3IgfHwgYFZhbGlkYXRpb24gZmFpbGVkLiBJbnZhbGlkIHZhbHVlIGZvciAke2tleX0uYDtcbiAgICAgICAgfVxuXG4gICAgICAgIHRocm93IG9wdC5lcnJvciB8fCBlLm1lc3NhZ2UgfHwgZTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KG9wdHMpKSB7XG4gICAgICBvcHRzID0gW29wdC5vcHRpb25zXTtcbiAgICB9XG5cbiAgICBpZiAoIW9wdHMuaW5jbHVkZXModmFsKSkge1xuICAgICAgdGhyb3cgKFxuICAgICAgICBvcHQuZXJyb3IgfHwgYFZhbGlkYXRpb24gZmFpbGVkLiBJbnZhbGlkIG9wdGlvbiBmb3IgJHtrZXl9LiBFeHBlY3RlZDogJHtvcHRzLmpvaW4oJywgJyl9YFxuICAgICAgKTtcbiAgICB9XG4gIH07XG5cbiAgY29uc3QgZ2V0VHlwZSA9IGZuID0+IHtcbiAgICBjb25zdCBtYXRjaCA9IGZuICYmIGZuLnRvU3RyaW5nKCkubWF0Y2goL15cXHMqZnVuY3Rpb24gKFxcdyspLyk7XG4gICAgcmV0dXJuIChtYXRjaCA/IG1hdGNoWzFdIDogJycpLnRvTG93ZXJDYXNlKCk7XG4gIH07XG4gIGlmIChBcnJheS5pc0FycmF5KG9wdGlvbnMuZmllbGRzKSkge1xuICAgIGZvciAoY29uc3Qga2V5IG9mIG9wdGlvbnMuZmllbGRzKSB7XG4gICAgICByZXF1aXJlZFBhcmFtKGtleSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGNvbnN0IG9wdGlvblByb21pc2VzID0gW107XG4gICAgZm9yIChjb25zdCBrZXkgaW4gb3B0aW9ucy5maWVsZHMpIHtcbiAgICAgIGNvbnN0IG9wdCA9IG9wdGlvbnMuZmllbGRzW2tleV07XG4gICAgICBsZXQgdmFsID0gcGFyYW1zW2tleV07XG4gICAgICBpZiAodHlwZW9mIG9wdCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmVxdWlyZWRQYXJhbShvcHQpO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBvcHQgPT09ICdvYmplY3QnKSB7XG4gICAgICAgIGlmIChvcHQuZGVmYXVsdCAhPSBudWxsICYmIHZhbCA9PSBudWxsKSB7XG4gICAgICAgICAgdmFsID0gb3B0LmRlZmF1bHQ7XG4gICAgICAgICAgcGFyYW1zW2tleV0gPSB2YWw7XG4gICAgICAgICAgaWYgKHJlcXVlc3Qub2JqZWN0KSB7XG4gICAgICAgICAgICByZXF1ZXN0Lm9iamVjdC5zZXQoa2V5LCB2YWwpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0LmNvbnN0YW50ICYmIHJlcXVlc3Qub2JqZWN0KSB7XG4gICAgICAgICAgaWYgKHJlcXVlc3Qub3JpZ2luYWwpIHtcbiAgICAgICAgICAgIHJlcXVlc3Qub2JqZWN0LnJldmVydChrZXkpO1xuICAgICAgICAgIH0gZWxzZSBpZiAob3B0LmRlZmF1bHQgIT0gbnVsbCkge1xuICAgICAgICAgICAgcmVxdWVzdC5vYmplY3Quc2V0KGtleSwgb3B0LmRlZmF1bHQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAob3B0LnJlcXVpcmVkKSB7XG4gICAgICAgICAgcmVxdWlyZWRQYXJhbShrZXkpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG9wdGlvbmFsID0gIW9wdC5yZXF1aXJlZCAmJiB2YWwgPT09IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKCFvcHRpb25hbCkge1xuICAgICAgICAgIGlmIChvcHQudHlwZSkge1xuICAgICAgICAgICAgY29uc3QgdHlwZSA9IGdldFR5cGUob3B0LnR5cGUpO1xuICAgICAgICAgICAgY29uc3QgdmFsVHlwZSA9IEFycmF5LmlzQXJyYXkodmFsKSA/ICdhcnJheScgOiB0eXBlb2YgdmFsO1xuICAgICAgICAgICAgaWYgKHZhbFR5cGUgIT09IHR5cGUpIHtcbiAgICAgICAgICAgICAgdGhyb3cgYFZhbGlkYXRpb24gZmFpbGVkLiBJbnZhbGlkIHR5cGUgZm9yICR7a2V5fS4gRXhwZWN0ZWQ6ICR7dHlwZX1gO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAob3B0Lm9wdGlvbnMpIHtcbiAgICAgICAgICAgIG9wdGlvblByb21pc2VzLnB1c2godmFsaWRhdGVPcHRpb25zKG9wdCwga2V5LCB2YWwpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwob3B0aW9uUHJvbWlzZXMpO1xuICB9XG4gIGxldCB1c2VyUm9sZXMgPSBvcHRpb25zLnJlcXVpcmVBbnlVc2VyUm9sZXM7XG4gIGxldCByZXF1aXJlQWxsUm9sZXMgPSBvcHRpb25zLnJlcXVpcmVBbGxVc2VyUm9sZXM7XG4gIGNvbnN0IHByb21pc2VzID0gW1Byb21pc2UucmVzb2x2ZSgpLCBQcm9taXNlLnJlc29sdmUoKSwgUHJvbWlzZS5yZXNvbHZlKCldO1xuICBpZiAodXNlclJvbGVzIHx8IHJlcXVpcmVBbGxSb2xlcykge1xuICAgIHByb21pc2VzWzBdID0gYXV0aC5nZXRVc2VyUm9sZXMoKTtcbiAgfVxuICBpZiAodHlwZW9mIHVzZXJSb2xlcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHByb21pc2VzWzFdID0gdXNlclJvbGVzKCk7XG4gIH1cbiAgaWYgKHR5cGVvZiByZXF1aXJlQWxsUm9sZXMgPT09ICdmdW5jdGlvbicpIHtcbiAgICBwcm9taXNlc1syXSA9IHJlcXVpcmVBbGxSb2xlcygpO1xuICB9XG4gIGNvbnN0IFtyb2xlcywgcmVzb2x2ZWRVc2VyUm9sZXMsIHJlc29sdmVkUmVxdWlyZUFsbF0gPSBhd2FpdCBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gIGlmIChyZXNvbHZlZFVzZXJSb2xlcyAmJiBBcnJheS5pc0FycmF5KHJlc29sdmVkVXNlclJvbGVzKSkge1xuICAgIHVzZXJSb2xlcyA9IHJlc29sdmVkVXNlclJvbGVzO1xuICB9XG4gIGlmIChyZXNvbHZlZFJlcXVpcmVBbGwgJiYgQXJyYXkuaXNBcnJheShyZXNvbHZlZFJlcXVpcmVBbGwpKSB7XG4gICAgcmVxdWlyZUFsbFJvbGVzID0gcmVzb2x2ZWRSZXF1aXJlQWxsO1xuICB9XG4gIGlmICh1c2VyUm9sZXMpIHtcbiAgICBjb25zdCBoYXNSb2xlID0gdXNlclJvbGVzLnNvbWUocmVxdWlyZWRSb2xlID0+IHJvbGVzLmluY2x1ZGVzKGByb2xlOiR7cmVxdWlyZWRSb2xlfWApKTtcbiAgICBpZiAoIWhhc1JvbGUpIHtcbiAgICAgIHRocm93IGBWYWxpZGF0aW9uIGZhaWxlZC4gVXNlciBkb2VzIG5vdCBtYXRjaCB0aGUgcmVxdWlyZWQgcm9sZXMuYDtcbiAgICB9XG4gIH1cbiAgaWYgKHJlcXVpcmVBbGxSb2xlcykge1xuICAgIGZvciAoY29uc3QgcmVxdWlyZWRSb2xlIG9mIHJlcXVpcmVBbGxSb2xlcykge1xuICAgICAgaWYgKCFyb2xlcy5pbmNsdWRlcyhgcm9sZToke3JlcXVpcmVkUm9sZX1gKSkge1xuICAgICAgICB0aHJvdyBgVmFsaWRhdGlvbiBmYWlsZWQuIFVzZXIgZG9lcyBub3QgbWF0Y2ggYWxsIHRoZSByZXF1aXJlZCByb2xlcy5gO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBjb25zdCB1c2VyS2V5cyA9IG9wdGlvbnMucmVxdWlyZVVzZXJLZXlzIHx8IFtdO1xuICBpZiAoQXJyYXkuaXNBcnJheSh1c2VyS2V5cykpIHtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiB1c2VyS2V5cykge1xuICAgICAgaWYgKCFyZXFVc2VyKSB7XG4gICAgICAgIHRocm93ICdQbGVhc2UgbG9naW4gdG8gbWFrZSB0aGlzIHJlcXVlc3QuJztcbiAgICAgIH1cblxuICAgICAgaWYgKHJlcVVzZXIuZ2V0KGtleSkgPT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBgVmFsaWRhdGlvbiBmYWlsZWQuIFBsZWFzZSBzZXQgZGF0YSBmb3IgJHtrZXl9IG9uIHlvdXIgYWNjb3VudC5gO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmICh0eXBlb2YgdXNlcktleXMgPT09ICdvYmplY3QnKSB7XG4gICAgY29uc3Qgb3B0aW9uUHJvbWlzZXMgPSBbXTtcbiAgICBmb3IgKGNvbnN0IGtleSBpbiBvcHRpb25zLnJlcXVpcmVVc2VyS2V5cykge1xuICAgICAgY29uc3Qgb3B0ID0gb3B0aW9ucy5yZXF1aXJlVXNlcktleXNba2V5XTtcbiAgICAgIGlmIChvcHQub3B0aW9ucykge1xuICAgICAgICBvcHRpb25Qcm9taXNlcy5wdXNoKHZhbGlkYXRlT3B0aW9ucyhvcHQsIGtleSwgcmVxVXNlci5nZXQoa2V5KSkpO1xuICAgICAgfVxuICAgIH1cbiAgICBhd2FpdCBQcm9taXNlLmFsbChvcHRpb25Qcm9taXNlcyk7XG4gIH1cbn1cblxuLy8gVG8gYmUgdXNlZCBhcyBwYXJ0IG9mIHRoZSBwcm9taXNlIGNoYWluIHdoZW4gc2F2aW5nL2RlbGV0aW5nIGFuIG9iamVjdFxuLy8gV2lsbCByZXNvbHZlIHN1Y2Nlc3NmdWxseSBpZiBubyB0cmlnZ2VyIGlzIGNvbmZpZ3VyZWRcbi8vIFJlc29sdmVzIHRvIGFuIG9iamVjdCwgZW1wdHkgb3IgY29udGFpbmluZyBhbiBvYmplY3Qga2V5LiBBIGJlZm9yZVNhdmVcbi8vIHRyaWdnZXIgd2lsbCBzZXQgdGhlIG9iamVjdCBrZXkgdG8gdGhlIHJlc3QgZm9ybWF0IG9iamVjdCB0byBzYXZlLlxuLy8gb3JpZ2luYWxQYXJzZU9iamVjdCBpcyBvcHRpb25hbCwgd2Ugb25seSBuZWVkIHRoYXQgZm9yIGJlZm9yZS9hZnRlclNhdmUgZnVuY3Rpb25zXG5leHBvcnQgZnVuY3Rpb24gbWF5YmVSdW5UcmlnZ2VyKFxuICB0cmlnZ2VyVHlwZSxcbiAgYXV0aCxcbiAgcGFyc2VPYmplY3QsXG4gIG9yaWdpbmFsUGFyc2VPYmplY3QsXG4gIGNvbmZpZyxcbiAgY29udGV4dFxuKSB7XG4gIGlmICghcGFyc2VPYmplY3QpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHt9KTtcbiAgfVxuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuICAgIHZhciB0cmlnZ2VyID0gZ2V0VHJpZ2dlcihwYXJzZU9iamVjdC5jbGFzc05hbWUsIHRyaWdnZXJUeXBlLCBjb25maWcuYXBwbGljYXRpb25JZCk7XG4gICAgaWYgKCF0cmlnZ2VyKSB7IHJldHVybiByZXNvbHZlKCk7IH1cbiAgICB2YXIgcmVxdWVzdCA9IGdldFJlcXVlc3RPYmplY3QoXG4gICAgICB0cmlnZ2VyVHlwZSxcbiAgICAgIGF1dGgsXG4gICAgICBwYXJzZU9iamVjdCxcbiAgICAgIG9yaWdpbmFsUGFyc2VPYmplY3QsXG4gICAgICBjb25maWcsXG4gICAgICBjb250ZXh0XG4gICAgKTtcbiAgICB2YXIgeyBzdWNjZXNzLCBlcnJvciB9ID0gZ2V0UmVzcG9uc2VPYmplY3QoXG4gICAgICByZXF1ZXN0LFxuICAgICAgb2JqZWN0ID0+IHtcbiAgICAgICAgbG9nVHJpZ2dlclN1Y2Nlc3NCZWZvcmVIb29rKFxuICAgICAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgICAgIHBhcnNlT2JqZWN0LmNsYXNzTmFtZSxcbiAgICAgICAgICBwYXJzZU9iamVjdC50b0pTT04oKSxcbiAgICAgICAgICBvYmplY3QsXG4gICAgICAgICAgYXV0aCxcbiAgICAgICAgICB0cmlnZ2VyVHlwZS5zdGFydHNXaXRoKCdhZnRlcicpXG4gICAgICAgICAgICA/IGNvbmZpZy5sb2dMZXZlbHMudHJpZ2dlckFmdGVyXG4gICAgICAgICAgICA6IGNvbmZpZy5sb2dMZXZlbHMudHJpZ2dlckJlZm9yZVN1Y2Nlc3NcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5iZWZvcmVTYXZlIHx8XG4gICAgICAgICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmFmdGVyU2F2ZSB8fFxuICAgICAgICAgIHRyaWdnZXJUeXBlID09PSBUeXBlcy5iZWZvcmVEZWxldGUgfHxcbiAgICAgICAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYWZ0ZXJEZWxldGVcbiAgICAgICAgKSB7XG4gICAgICAgICAgT2JqZWN0LmFzc2lnbihjb250ZXh0LCByZXF1ZXN0LmNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICAgIHJlc29sdmUob2JqZWN0KTtcbiAgICAgIH0sXG4gICAgICBlcnJvciA9PiB7XG4gICAgICAgIGxvZ1RyaWdnZXJFcnJvckJlZm9yZUhvb2soXG4gICAgICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICAgICAgcGFyc2VPYmplY3QuY2xhc3NOYW1lLFxuICAgICAgICAgIHBhcnNlT2JqZWN0LnRvSlNPTigpLFxuICAgICAgICAgIGF1dGgsXG4gICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgY29uZmlnLmxvZ0xldmVscy50cmlnZ2VyQmVmb3JlRXJyb3JcbiAgICAgICAgKTtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgLy8gQWZ0ZXJTYXZlIGFuZCBhZnRlckRlbGV0ZSB0cmlnZ2VycyBjYW4gcmV0dXJuIGEgcHJvbWlzZSwgd2hpY2ggaWYgdGhleVxuICAgIC8vIGRvLCBuZWVkcyB0byBiZSByZXNvbHZlZCBiZWZvcmUgdGhpcyBwcm9taXNlIGlzIHJlc29sdmVkLFxuICAgIC8vIHNvIHRyaWdnZXIgZXhlY3V0aW9uIGlzIHN5bmNlZCB3aXRoIFJlc3RXcml0ZS5leGVjdXRlKCkgY2FsbC5cbiAgICAvLyBJZiB0cmlnZ2VycyBkbyBub3QgcmV0dXJuIGEgcHJvbWlzZSwgdGhleSBjYW4gcnVuIGFzeW5jIGNvZGUgcGFyYWxsZWxcbiAgICAvLyB0byB0aGUgUmVzdFdyaXRlLmV4ZWN1dGUoKSBjYWxsLlxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gbWF5YmVSdW5WYWxpZGF0b3IocmVxdWVzdCwgYCR7dHJpZ2dlclR5cGV9LiR7cGFyc2VPYmplY3QuY2xhc3NOYW1lfWAsIGF1dGgpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgaWYgKHJlcXVlc3Quc2tpcFdpdGhNYXN0ZXJLZXkpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcHJvbWlzZSA9IHRyaWdnZXIocmVxdWVzdCk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYWZ0ZXJTYXZlIHx8XG4gICAgICAgICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmFmdGVyRGVsZXRlIHx8XG4gICAgICAgICAgdHJpZ2dlclR5cGUgPT09IFR5cGVzLmFmdGVyTG9naW5cbiAgICAgICAgKSB7XG4gICAgICAgICAgbG9nVHJpZ2dlckFmdGVySG9vayhcbiAgICAgICAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgICAgICAgcGFyc2VPYmplY3QuY2xhc3NOYW1lLFxuICAgICAgICAgICAgcGFyc2VPYmplY3QudG9KU09OKCksXG4gICAgICAgICAgICBhdXRoLFxuICAgICAgICAgICAgY29uZmlnLmxvZ0xldmVscy50cmlnZ2VyQWZ0ZXJcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIC8vIGJlZm9yZVNhdmUgaXMgZXhwZWN0ZWQgdG8gcmV0dXJuIG51bGwgKG5vdGhpbmcpXG4gICAgICAgIGlmICh0cmlnZ2VyVHlwZSA9PT0gVHlwZXMuYmVmb3JlU2F2ZSkge1xuICAgICAgICAgIGlmIChwcm9taXNlICYmIHR5cGVvZiBwcm9taXNlLnRoZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9taXNlLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAvLyByZXNwb25zZS5vYmplY3QgbWF5IGNvbWUgZnJvbSBleHByZXNzIHJvdXRpbmcgYmVmb3JlIGhvb2tcbiAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlICYmIHJlc3BvbnNlLm9iamVjdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgICAgfSlcbiAgICAgIC50aGVuKHN1Y2Nlc3MsIGVycm9yKTtcbiAgfSk7XG59XG5cbi8vIENvbnZlcnRzIGEgUkVTVC1mb3JtYXQgb2JqZWN0IHRvIGEgUGFyc2UuT2JqZWN0XG4vLyBkYXRhIGlzIGVpdGhlciBjbGFzc05hbWUgb3IgYW4gb2JqZWN0XG5leHBvcnQgZnVuY3Rpb24gaW5mbGF0ZShkYXRhLCByZXN0T2JqZWN0KSB7XG4gIHZhciBjb3B5ID0gdHlwZW9mIGRhdGEgPT0gJ29iamVjdCcgPyBkYXRhIDogeyBjbGFzc05hbWU6IGRhdGEgfTtcbiAgZm9yICh2YXIga2V5IGluIHJlc3RPYmplY3QpIHtcbiAgICBjb3B5W2tleV0gPSByZXN0T2JqZWN0W2tleV07XG4gIH1cbiAgcmV0dXJuIFBhcnNlLk9iamVjdC5mcm9tSlNPTihjb3B5KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJ1bkxpdmVRdWVyeUV2ZW50SGFuZGxlcnMoZGF0YSwgYXBwbGljYXRpb25JZCA9IFBhcnNlLmFwcGxpY2F0aW9uSWQpIHtcbiAgaWYgKCFfdHJpZ2dlclN0b3JlIHx8ICFfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdIHx8ICFfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdLkxpdmVRdWVyeSkge1xuICAgIHJldHVybjtcbiAgfVxuICBfdHJpZ2dlclN0b3JlW2FwcGxpY2F0aW9uSWRdLkxpdmVRdWVyeS5mb3JFYWNoKGhhbmRsZXIgPT4gaGFuZGxlcihkYXRhKSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZXF1ZXN0RmlsZU9iamVjdCh0cmlnZ2VyVHlwZSwgYXV0aCwgZmlsZU9iamVjdCwgY29uZmlnKSB7XG4gIGNvbnN0IHJlcXVlc3QgPSB7XG4gICAgLi4uZmlsZU9iamVjdCxcbiAgICB0cmlnZ2VyTmFtZTogdHJpZ2dlclR5cGUsXG4gICAgbWFzdGVyOiBmYWxzZSxcbiAgICBsb2c6IGNvbmZpZy5sb2dnZXJDb250cm9sbGVyLFxuICAgIGhlYWRlcnM6IGNvbmZpZy5oZWFkZXJzLFxuICAgIGlwOiBjb25maWcuaXAsXG4gICAgY29uZmlnLFxuICB9O1xuXG4gIGlmICghYXV0aCkge1xuICAgIHJldHVybiByZXF1ZXN0O1xuICB9XG4gIGlmIChhdXRoLmlzTWFzdGVyKSB7XG4gICAgcmVxdWVzdFsnbWFzdGVyJ10gPSB0cnVlO1xuICB9XG4gIGlmIChhdXRoLnVzZXIpIHtcbiAgICByZXF1ZXN0Wyd1c2VyJ10gPSBhdXRoLnVzZXI7XG4gIH1cbiAgaWYgKGF1dGguaW5zdGFsbGF0aW9uSWQpIHtcbiAgICByZXF1ZXN0WydpbnN0YWxsYXRpb25JZCddID0gYXV0aC5pbnN0YWxsYXRpb25JZDtcbiAgfVxuICByZXR1cm4gcmVxdWVzdDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1heWJlUnVuRmlsZVRyaWdnZXIodHJpZ2dlclR5cGUsIGZpbGVPYmplY3QsIGNvbmZpZywgYXV0aCkge1xuICBjb25zdCBGaWxlQ2xhc3NOYW1lID0gZ2V0Q2xhc3NOYW1lKFBhcnNlLkZpbGUpO1xuICBjb25zdCBmaWxlVHJpZ2dlciA9IGdldFRyaWdnZXIoRmlsZUNsYXNzTmFtZSwgdHJpZ2dlclR5cGUsIGNvbmZpZy5hcHBsaWNhdGlvbklkKTtcbiAgaWYgKHR5cGVvZiBmaWxlVHJpZ2dlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXF1ZXN0ID0gZ2V0UmVxdWVzdEZpbGVPYmplY3QodHJpZ2dlclR5cGUsIGF1dGgsIGZpbGVPYmplY3QsIGNvbmZpZyk7XG4gICAgICBhd2FpdCBtYXliZVJ1blZhbGlkYXRvcihyZXF1ZXN0LCBgJHt0cmlnZ2VyVHlwZX0uJHtGaWxlQ2xhc3NOYW1lfWAsIGF1dGgpO1xuICAgICAgaWYgKHJlcXVlc3Quc2tpcFdpdGhNYXN0ZXJLZXkpIHtcbiAgICAgICAgcmV0dXJuIGZpbGVPYmplY3Q7XG4gICAgICB9XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBmaWxlVHJpZ2dlcihyZXF1ZXN0KTtcbiAgICAgIGlmIChyZXF1ZXN0LmZvcmNlRG93bmxvYWQpIHtcbiAgICAgICAgZmlsZU9iamVjdC5mb3JjZURvd25sb2FkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGxvZ1RyaWdnZXJTdWNjZXNzQmVmb3JlSG9vayhcbiAgICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICAgICdQYXJzZS5GaWxlJyxcbiAgICAgICAgeyAuLi5maWxlT2JqZWN0LmZpbGUudG9KU09OKCksIGZpbGVTaXplOiBmaWxlT2JqZWN0LmZpbGVTaXplIH0sXG4gICAgICAgIHJlc3VsdCxcbiAgICAgICAgYXV0aCxcbiAgICAgICAgY29uZmlnLmxvZ0xldmVscy50cmlnZ2VyQmVmb3JlU3VjY2Vzc1xuICAgICAgKTtcbiAgICAgIHJldHVybiByZXN1bHQgfHwgZmlsZU9iamVjdDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nVHJpZ2dlckVycm9yQmVmb3JlSG9vayhcbiAgICAgICAgdHJpZ2dlclR5cGUsXG4gICAgICAgICdQYXJzZS5GaWxlJyxcbiAgICAgICAgeyAuLi5maWxlT2JqZWN0LmZpbGUudG9KU09OKCksIGZpbGVTaXplOiBmaWxlT2JqZWN0LmZpbGVTaXplIH0sXG4gICAgICAgIGF1dGgsXG4gICAgICAgIGVycm9yLFxuICAgICAgICBjb25maWcubG9nTGV2ZWxzLnRyaWdnZXJCZWZvcmVFcnJvclxuICAgICAgKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmlsZU9iamVjdDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG1heWJlUnVuR2xvYmFsQ29uZmlnVHJpZ2dlcih0cmlnZ2VyVHlwZSwgYXV0aCwgY29uZmlnT2JqZWN0LCBvcmlnaW5hbENvbmZpZ09iamVjdCwgY29uZmlnLCBjb250ZXh0KSB7XG4gIGNvbnN0IEdsb2JhbENvbmZpZ0NsYXNzTmFtZSA9IGdldENsYXNzTmFtZShQYXJzZS5Db25maWcpO1xuICBjb25zdCBjb25maWdUcmlnZ2VyID0gZ2V0VHJpZ2dlcihHbG9iYWxDb25maWdDbGFzc05hbWUsIHRyaWdnZXJUeXBlLCBjb25maWcuYXBwbGljYXRpb25JZCk7XG4gIGlmICh0eXBlb2YgY29uZmlnVHJpZ2dlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXF1ZXN0ID0gZ2V0UmVxdWVzdE9iamVjdCh0cmlnZ2VyVHlwZSwgYXV0aCwgY29uZmlnT2JqZWN0LCBvcmlnaW5hbENvbmZpZ09iamVjdCwgY29uZmlnLCBjb250ZXh0KTtcbiAgICAgIGF3YWl0IG1heWJlUnVuVmFsaWRhdG9yKHJlcXVlc3QsIGAke3RyaWdnZXJUeXBlfS4ke0dsb2JhbENvbmZpZ0NsYXNzTmFtZX1gLCBhdXRoKTtcbiAgICAgIGlmIChyZXF1ZXN0LnNraXBXaXRoTWFzdGVyS2V5KSB7XG4gICAgICAgIHJldHVybiBjb25maWdPYmplY3Q7XG4gICAgICB9XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjb25maWdUcmlnZ2VyKHJlcXVlc3QpO1xuICAgICAgbG9nVHJpZ2dlclN1Y2Nlc3NCZWZvcmVIb29rKFxuICAgICAgICB0cmlnZ2VyVHlwZSxcbiAgICAgICAgJ1BhcnNlLkNvbmZpZycsXG4gICAgICAgIGNvbmZpZ09iamVjdCxcbiAgICAgICAgcmVzdWx0LFxuICAgICAgICBhdXRoLFxuICAgICAgICBjb25maWcubG9nTGV2ZWxzLnRyaWdnZXJCZWZvcmVTdWNjZXNzXG4gICAgICApO1xuICAgICAgcmV0dXJuIHJlc3VsdCB8fCBjb25maWdPYmplY3Q7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ1RyaWdnZXJFcnJvckJlZm9yZUhvb2soXG4gICAgICAgIHRyaWdnZXJUeXBlLFxuICAgICAgICAnUGFyc2UuQ29uZmlnJyxcbiAgICAgICAgY29uZmlnT2JqZWN0LFxuICAgICAgICBhdXRoLFxuICAgICAgICBlcnJvcixcbiAgICAgICAgY29uZmlnLmxvZ0xldmVscy50cmlnZ2VyQmVmb3JlRXJyb3JcbiAgICAgICk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNvbmZpZ09iamVjdDtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUNBLElBQUFBLEtBQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLE9BQUEsR0FBQUQsT0FBQTtBQUFrQyxTQUFBRCx1QkFBQUcsQ0FBQSxXQUFBQSxDQUFBLElBQUFBLENBQUEsQ0FBQUMsVUFBQSxHQUFBRCxDQUFBLEtBQUFFLE9B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
|