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
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "extractKeysAndInclude", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _parseGraphQLUtils.extractKeysAndInclude;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
exports.load = void 0;
|
|
13
|
+
var _graphql = require("graphql");
|
|
14
|
+
var _graphqlRelay = require("graphql-relay");
|
|
15
|
+
var _graphqlListFields = _interopRequireDefault(require("graphql-list-fields"));
|
|
16
|
+
var defaultGraphQLTypes = _interopRequireWildcard(require("./defaultGraphQLTypes"));
|
|
17
|
+
var objectsQueries = _interopRequireWildcard(require("../helpers/objectsQueries"));
|
|
18
|
+
var _ParseGraphQLController = require("../../Controllers/ParseGraphQLController");
|
|
19
|
+
var _className = require("../transformers/className");
|
|
20
|
+
var _inputType = require("../transformers/inputType");
|
|
21
|
+
var _outputType = require("../transformers/outputType");
|
|
22
|
+
var _constraintType = require("../transformers/constraintType");
|
|
23
|
+
var _parseGraphQLUtils = require("../parseGraphQLUtils");
|
|
24
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
25
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
26
|
+
/* eslint-disable indent */
|
|
27
|
+
|
|
28
|
+
const getParseClassTypeConfig = function (parseClassConfig) {
|
|
29
|
+
return parseClassConfig && parseClassConfig.type || {};
|
|
30
|
+
};
|
|
31
|
+
const getInputFieldsAndConstraints = function (parseClass, parseClassConfig) {
|
|
32
|
+
const classFields = Object.keys(parseClass.fields).concat('id');
|
|
33
|
+
const {
|
|
34
|
+
inputFields: allowedInputFields,
|
|
35
|
+
outputFields: allowedOutputFields,
|
|
36
|
+
constraintFields: allowedConstraintFields,
|
|
37
|
+
sortFields: allowedSortFields
|
|
38
|
+
} = getParseClassTypeConfig(parseClassConfig);
|
|
39
|
+
let classOutputFields;
|
|
40
|
+
let classCreateFields;
|
|
41
|
+
let classUpdateFields;
|
|
42
|
+
let classConstraintFields;
|
|
43
|
+
let classSortFields;
|
|
44
|
+
|
|
45
|
+
// All allowed customs fields
|
|
46
|
+
const classCustomFields = classFields.filter(field => {
|
|
47
|
+
return !Object.keys(defaultGraphQLTypes.PARSE_OBJECT_FIELDS).includes(field) && field !== 'id';
|
|
48
|
+
});
|
|
49
|
+
if (allowedInputFields && allowedInputFields.create) {
|
|
50
|
+
classCreateFields = classCustomFields.filter(field => {
|
|
51
|
+
return allowedInputFields.create.includes(field);
|
|
52
|
+
});
|
|
53
|
+
} else {
|
|
54
|
+
classCreateFields = classCustomFields;
|
|
55
|
+
}
|
|
56
|
+
if (allowedInputFields && allowedInputFields.update) {
|
|
57
|
+
classUpdateFields = classCustomFields.filter(field => {
|
|
58
|
+
return allowedInputFields.update.includes(field);
|
|
59
|
+
});
|
|
60
|
+
} else {
|
|
61
|
+
classUpdateFields = classCustomFields;
|
|
62
|
+
}
|
|
63
|
+
if (allowedOutputFields) {
|
|
64
|
+
classOutputFields = classCustomFields.filter(field => {
|
|
65
|
+
return allowedOutputFields.includes(field);
|
|
66
|
+
});
|
|
67
|
+
} else {
|
|
68
|
+
classOutputFields = classCustomFields;
|
|
69
|
+
}
|
|
70
|
+
// Filters the "password" field from class _User
|
|
71
|
+
if (parseClass.className === '_User') {
|
|
72
|
+
classOutputFields = classOutputFields.filter(outputField => outputField !== 'password');
|
|
73
|
+
}
|
|
74
|
+
if (allowedConstraintFields) {
|
|
75
|
+
classConstraintFields = classCustomFields.filter(field => {
|
|
76
|
+
return allowedConstraintFields.includes(field);
|
|
77
|
+
});
|
|
78
|
+
} else {
|
|
79
|
+
classConstraintFields = classFields;
|
|
80
|
+
}
|
|
81
|
+
if (allowedSortFields) {
|
|
82
|
+
classSortFields = allowedSortFields;
|
|
83
|
+
if (!classSortFields.length) {
|
|
84
|
+
// must have at least 1 order field
|
|
85
|
+
// otherwise the FindArgs Input Type will throw.
|
|
86
|
+
classSortFields.push({
|
|
87
|
+
field: 'id',
|
|
88
|
+
asc: true,
|
|
89
|
+
desc: true
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
classSortFields = classFields.map(field => {
|
|
94
|
+
return {
|
|
95
|
+
field,
|
|
96
|
+
asc: true,
|
|
97
|
+
desc: true
|
|
98
|
+
};
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
classCreateFields,
|
|
103
|
+
classUpdateFields,
|
|
104
|
+
classConstraintFields,
|
|
105
|
+
classOutputFields,
|
|
106
|
+
classSortFields
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
const load = (parseGraphQLSchema, parseClass, parseClassConfig) => {
|
|
110
|
+
const className = parseClass.className;
|
|
111
|
+
const graphQLClassName = (0, _className.transformClassNameToGraphQL)(className);
|
|
112
|
+
const {
|
|
113
|
+
classCreateFields,
|
|
114
|
+
classUpdateFields,
|
|
115
|
+
classOutputFields,
|
|
116
|
+
classConstraintFields,
|
|
117
|
+
classSortFields
|
|
118
|
+
} = getInputFieldsAndConstraints(parseClass, parseClassConfig);
|
|
119
|
+
const {
|
|
120
|
+
create: isCreateEnabled = true,
|
|
121
|
+
update: isUpdateEnabled = true
|
|
122
|
+
} = (0, _parseGraphQLUtils.getParseClassMutationConfig)(parseClassConfig);
|
|
123
|
+
const classGraphQLCreateTypeName = `Create${graphQLClassName}FieldsInput`;
|
|
124
|
+
let classGraphQLCreateType = new _graphql.GraphQLInputObjectType({
|
|
125
|
+
name: classGraphQLCreateTypeName,
|
|
126
|
+
description: `The ${classGraphQLCreateTypeName} input type is used in operations that involve creation of objects in the ${graphQLClassName} class.`,
|
|
127
|
+
fields: () => classCreateFields.reduce((fields, field) => {
|
|
128
|
+
const type = (0, _inputType.transformInputTypeToGraphQL)(parseClass.fields[field].type, parseClass.fields[field].targetClass, parseGraphQLSchema.parseClassTypes);
|
|
129
|
+
if (type) {
|
|
130
|
+
return {
|
|
131
|
+
...fields,
|
|
132
|
+
[field]: {
|
|
133
|
+
description: `This is the object ${field}.`,
|
|
134
|
+
type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
} else {
|
|
138
|
+
return fields;
|
|
139
|
+
}
|
|
140
|
+
}, {
|
|
141
|
+
ACL: {
|
|
142
|
+
type: defaultGraphQLTypes.ACL_INPUT
|
|
143
|
+
}
|
|
144
|
+
})
|
|
145
|
+
});
|
|
146
|
+
classGraphQLCreateType = parseGraphQLSchema.addGraphQLType(classGraphQLCreateType);
|
|
147
|
+
const classGraphQLUpdateTypeName = `Update${graphQLClassName}FieldsInput`;
|
|
148
|
+
let classGraphQLUpdateType = new _graphql.GraphQLInputObjectType({
|
|
149
|
+
name: classGraphQLUpdateTypeName,
|
|
150
|
+
description: `The ${classGraphQLUpdateTypeName} input type is used in operations that involve creation of objects in the ${graphQLClassName} class.`,
|
|
151
|
+
fields: () => classUpdateFields.reduce((fields, field) => {
|
|
152
|
+
const type = (0, _inputType.transformInputTypeToGraphQL)(parseClass.fields[field].type, parseClass.fields[field].targetClass, parseGraphQLSchema.parseClassTypes);
|
|
153
|
+
if (type) {
|
|
154
|
+
return {
|
|
155
|
+
...fields,
|
|
156
|
+
[field]: {
|
|
157
|
+
description: `This is the object ${field}.`,
|
|
158
|
+
type
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
} else {
|
|
162
|
+
return fields;
|
|
163
|
+
}
|
|
164
|
+
}, {
|
|
165
|
+
ACL: {
|
|
166
|
+
type: defaultGraphQLTypes.ACL_INPUT
|
|
167
|
+
}
|
|
168
|
+
})
|
|
169
|
+
});
|
|
170
|
+
classGraphQLUpdateType = parseGraphQLSchema.addGraphQLType(classGraphQLUpdateType);
|
|
171
|
+
const classGraphQLPointerTypeName = `${graphQLClassName}PointerInput`;
|
|
172
|
+
let classGraphQLPointerType = new _graphql.GraphQLInputObjectType({
|
|
173
|
+
name: classGraphQLPointerTypeName,
|
|
174
|
+
description: `Allow to link OR add and link an object of the ${graphQLClassName} class.`,
|
|
175
|
+
fields: () => {
|
|
176
|
+
const fields = {
|
|
177
|
+
link: {
|
|
178
|
+
description: `Link an existing object from ${graphQLClassName} class. You can use either the global or the object id.`,
|
|
179
|
+
type: _graphql.GraphQLID
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
if (isCreateEnabled) {
|
|
183
|
+
fields['createAndLink'] = {
|
|
184
|
+
description: `Create and link an object from ${graphQLClassName} class.`,
|
|
185
|
+
type: classGraphQLCreateType
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
return fields;
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
classGraphQLPointerType = parseGraphQLSchema.addGraphQLType(classGraphQLPointerType) || defaultGraphQLTypes.OBJECT;
|
|
192
|
+
const classGraphQLRelationTypeName = `${graphQLClassName}RelationInput`;
|
|
193
|
+
let classGraphQLRelationType = new _graphql.GraphQLInputObjectType({
|
|
194
|
+
name: classGraphQLRelationTypeName,
|
|
195
|
+
description: `Allow to add, remove, createAndAdd objects of the ${graphQLClassName} class into a relation field.`,
|
|
196
|
+
fields: () => {
|
|
197
|
+
const fields = {
|
|
198
|
+
add: {
|
|
199
|
+
description: `Add existing objects from the ${graphQLClassName} class into the relation. You can use either the global or the object ids.`,
|
|
200
|
+
type: new _graphql.GraphQLList(defaultGraphQLTypes.OBJECT_ID)
|
|
201
|
+
},
|
|
202
|
+
remove: {
|
|
203
|
+
description: `Remove existing objects from the ${graphQLClassName} class out of the relation. You can use either the global or the object ids.`,
|
|
204
|
+
type: new _graphql.GraphQLList(defaultGraphQLTypes.OBJECT_ID)
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
if (isCreateEnabled) {
|
|
208
|
+
fields['createAndAdd'] = {
|
|
209
|
+
description: `Create and add objects of the ${graphQLClassName} class into the relation.`,
|
|
210
|
+
type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLCreateType))
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
return fields;
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
classGraphQLRelationType = parseGraphQLSchema.addGraphQLType(classGraphQLRelationType) || defaultGraphQLTypes.OBJECT;
|
|
217
|
+
const classGraphQLConstraintsTypeName = `${graphQLClassName}WhereInput`;
|
|
218
|
+
let classGraphQLConstraintsType = new _graphql.GraphQLInputObjectType({
|
|
219
|
+
name: classGraphQLConstraintsTypeName,
|
|
220
|
+
description: `The ${classGraphQLConstraintsTypeName} input type is used in operations that involve filtering objects of ${graphQLClassName} class.`,
|
|
221
|
+
fields: () => ({
|
|
222
|
+
...classConstraintFields.reduce((fields, field) => {
|
|
223
|
+
if (['OR', 'AND', 'NOR'].includes(field)) {
|
|
224
|
+
parseGraphQLSchema.log.warn(`Field ${field} could not be added to the auto schema ${classGraphQLConstraintsTypeName} because it collided with an existing one.`);
|
|
225
|
+
return fields;
|
|
226
|
+
}
|
|
227
|
+
const parseField = field === 'id' ? 'objectId' : field;
|
|
228
|
+
const type = (0, _constraintType.transformConstraintTypeToGraphQL)(parseClass.fields[parseField].type, parseClass.fields[parseField].targetClass, parseGraphQLSchema.parseClassTypes, field);
|
|
229
|
+
if (type) {
|
|
230
|
+
return {
|
|
231
|
+
...fields,
|
|
232
|
+
[field]: {
|
|
233
|
+
description: `This is the object ${field}.`,
|
|
234
|
+
type
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
} else {
|
|
238
|
+
return fields;
|
|
239
|
+
}
|
|
240
|
+
}, {}),
|
|
241
|
+
OR: {
|
|
242
|
+
description: 'This is the OR operator to compound constraints.',
|
|
243
|
+
type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLConstraintsType))
|
|
244
|
+
},
|
|
245
|
+
AND: {
|
|
246
|
+
description: 'This is the AND operator to compound constraints.',
|
|
247
|
+
type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLConstraintsType))
|
|
248
|
+
},
|
|
249
|
+
NOR: {
|
|
250
|
+
description: 'This is the NOR operator to compound constraints.',
|
|
251
|
+
type: new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLConstraintsType))
|
|
252
|
+
}
|
|
253
|
+
})
|
|
254
|
+
});
|
|
255
|
+
classGraphQLConstraintsType = parseGraphQLSchema.addGraphQLType(classGraphQLConstraintsType) || defaultGraphQLTypes.OBJECT;
|
|
256
|
+
const classGraphQLRelationConstraintsTypeName = `${graphQLClassName}RelationWhereInput`;
|
|
257
|
+
let classGraphQLRelationConstraintsType = new _graphql.GraphQLInputObjectType({
|
|
258
|
+
name: classGraphQLRelationConstraintsTypeName,
|
|
259
|
+
description: `The ${classGraphQLRelationConstraintsTypeName} input type is used in operations that involve filtering objects of ${graphQLClassName} class.`,
|
|
260
|
+
fields: () => ({
|
|
261
|
+
have: {
|
|
262
|
+
description: 'Run a relational/pointer query where at least one child object can match.',
|
|
263
|
+
type: classGraphQLConstraintsType
|
|
264
|
+
},
|
|
265
|
+
haveNot: {
|
|
266
|
+
description: 'Run an inverted relational/pointer query where at least one child object can match.',
|
|
267
|
+
type: classGraphQLConstraintsType
|
|
268
|
+
},
|
|
269
|
+
exists: {
|
|
270
|
+
description: 'Check if the relation/pointer contains objects.',
|
|
271
|
+
type: _graphql.GraphQLBoolean
|
|
272
|
+
}
|
|
273
|
+
})
|
|
274
|
+
});
|
|
275
|
+
classGraphQLRelationConstraintsType = parseGraphQLSchema.addGraphQLType(classGraphQLRelationConstraintsType) || defaultGraphQLTypes.OBJECT;
|
|
276
|
+
const classGraphQLOrderTypeName = `${graphQLClassName}Order`;
|
|
277
|
+
let classGraphQLOrderType = new _graphql.GraphQLEnumType({
|
|
278
|
+
name: classGraphQLOrderTypeName,
|
|
279
|
+
description: `The ${classGraphQLOrderTypeName} input type is used when sorting objects of the ${graphQLClassName} class.`,
|
|
280
|
+
values: classSortFields.reduce((sortFields, fieldConfig) => {
|
|
281
|
+
const {
|
|
282
|
+
field,
|
|
283
|
+
asc,
|
|
284
|
+
desc
|
|
285
|
+
} = fieldConfig;
|
|
286
|
+
const updatedSortFields = {
|
|
287
|
+
...sortFields
|
|
288
|
+
};
|
|
289
|
+
const value = field === 'id' ? 'objectId' : field;
|
|
290
|
+
if (asc) {
|
|
291
|
+
updatedSortFields[`${field}_ASC`] = {
|
|
292
|
+
value
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
if (desc) {
|
|
296
|
+
updatedSortFields[`${field}_DESC`] = {
|
|
297
|
+
value: `-${value}`
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
return updatedSortFields;
|
|
301
|
+
}, {})
|
|
302
|
+
});
|
|
303
|
+
classGraphQLOrderType = parseGraphQLSchema.addGraphQLType(classGraphQLOrderType);
|
|
304
|
+
const classGraphQLFindArgs = {
|
|
305
|
+
where: {
|
|
306
|
+
description: 'These are the conditions that the objects need to match in order to be found.',
|
|
307
|
+
type: classGraphQLConstraintsType
|
|
308
|
+
},
|
|
309
|
+
order: {
|
|
310
|
+
description: 'The fields to be used when sorting the data fetched.',
|
|
311
|
+
type: classGraphQLOrderType ? new _graphql.GraphQLList(new _graphql.GraphQLNonNull(classGraphQLOrderType)) : _graphql.GraphQLString
|
|
312
|
+
},
|
|
313
|
+
skip: defaultGraphQLTypes.SKIP_ATT,
|
|
314
|
+
..._graphqlRelay.connectionArgs,
|
|
315
|
+
options: defaultGraphQLTypes.READ_OPTIONS_ATT
|
|
316
|
+
};
|
|
317
|
+
const classGraphQLOutputTypeName = `${graphQLClassName}`;
|
|
318
|
+
const interfaces = [defaultGraphQLTypes.PARSE_OBJECT, parseGraphQLSchema.relayNodeInterface];
|
|
319
|
+
const parseObjectFields = {
|
|
320
|
+
id: (0, _graphqlRelay.globalIdField)(className, obj => obj.objectId),
|
|
321
|
+
...defaultGraphQLTypes.PARSE_OBJECT_FIELDS,
|
|
322
|
+
...(className === '_User' ? {
|
|
323
|
+
authDataResponse: {
|
|
324
|
+
description: `auth provider response when triggered on signUp/logIn.`,
|
|
325
|
+
type: defaultGraphQLTypes.OBJECT
|
|
326
|
+
}
|
|
327
|
+
} : {})
|
|
328
|
+
};
|
|
329
|
+
const outputFields = () => {
|
|
330
|
+
return classOutputFields.reduce((fields, field) => {
|
|
331
|
+
const type = (0, _outputType.transformOutputTypeToGraphQL)(parseClass.fields[field].type, parseClass.fields[field].targetClass, parseGraphQLSchema.parseClassTypes);
|
|
332
|
+
if (parseClass.fields[field].type === 'Relation') {
|
|
333
|
+
const targetParseClassTypes = parseGraphQLSchema.parseClassTypes[parseClass.fields[field].targetClass];
|
|
334
|
+
const args = targetParseClassTypes ? targetParseClassTypes.classGraphQLFindArgs : undefined;
|
|
335
|
+
return {
|
|
336
|
+
...fields,
|
|
337
|
+
[field]: {
|
|
338
|
+
description: `This is the object ${field}.`,
|
|
339
|
+
args,
|
|
340
|
+
type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type,
|
|
341
|
+
async resolve(source, args, context, queryInfo) {
|
|
342
|
+
try {
|
|
343
|
+
const {
|
|
344
|
+
where,
|
|
345
|
+
order,
|
|
346
|
+
skip,
|
|
347
|
+
first,
|
|
348
|
+
after,
|
|
349
|
+
last,
|
|
350
|
+
before,
|
|
351
|
+
options
|
|
352
|
+
} = args;
|
|
353
|
+
const {
|
|
354
|
+
readPreference,
|
|
355
|
+
includeReadPreference,
|
|
356
|
+
subqueryReadPreference
|
|
357
|
+
} = options || {};
|
|
358
|
+
const {
|
|
359
|
+
config,
|
|
360
|
+
auth,
|
|
361
|
+
info
|
|
362
|
+
} = context;
|
|
363
|
+
const selectedFields = (0, _graphqlListFields.default)(queryInfo);
|
|
364
|
+
const {
|
|
365
|
+
keys,
|
|
366
|
+
include
|
|
367
|
+
} = (0, _parseGraphQLUtils.extractKeysAndInclude)(selectedFields.filter(field => field.startsWith('edges.node.')).map(field => field.replace('edges.node.', '')).filter(field => field.indexOf('edges.node') < 0));
|
|
368
|
+
const parseOrder = order && order.join(',');
|
|
369
|
+
return objectsQueries.findObjects(source[field].className, {
|
|
370
|
+
$relatedTo: {
|
|
371
|
+
object: {
|
|
372
|
+
__type: 'Pointer',
|
|
373
|
+
className: className,
|
|
374
|
+
objectId: source.objectId
|
|
375
|
+
},
|
|
376
|
+
key: field
|
|
377
|
+
},
|
|
378
|
+
...(where || {})
|
|
379
|
+
}, parseOrder, skip, first, after, last, before, keys, include, false, readPreference, includeReadPreference, subqueryReadPreference, config, auth, info, selectedFields, parseGraphQLSchema.parseClasses);
|
|
380
|
+
} catch (e) {
|
|
381
|
+
parseGraphQLSchema.handleError(e);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
} else if (parseClass.fields[field].type === 'Polygon') {
|
|
387
|
+
return {
|
|
388
|
+
...fields,
|
|
389
|
+
[field]: {
|
|
390
|
+
description: `This is the object ${field}.`,
|
|
391
|
+
type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type,
|
|
392
|
+
async resolve(source) {
|
|
393
|
+
if (source[field] && source[field].coordinates) {
|
|
394
|
+
return source[field].coordinates.map(coordinate => ({
|
|
395
|
+
latitude: coordinate[0],
|
|
396
|
+
longitude: coordinate[1]
|
|
397
|
+
}));
|
|
398
|
+
} else {
|
|
399
|
+
return null;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
};
|
|
404
|
+
} else if (parseClass.fields[field].type === 'Array') {
|
|
405
|
+
return {
|
|
406
|
+
...fields,
|
|
407
|
+
[field]: {
|
|
408
|
+
description: `Use Inline Fragment on Array to get results: https://graphql.org/learn/queries/#inline-fragments`,
|
|
409
|
+
type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type,
|
|
410
|
+
async resolve(source) {
|
|
411
|
+
if (!source[field]) {
|
|
412
|
+
return null;
|
|
413
|
+
}
|
|
414
|
+
return source[field].map(async elem => {
|
|
415
|
+
if (elem.className && elem.objectId && elem.__type === 'Object') {
|
|
416
|
+
return elem;
|
|
417
|
+
} else {
|
|
418
|
+
return {
|
|
419
|
+
value: elem
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
} else if (type) {
|
|
427
|
+
return {
|
|
428
|
+
...fields,
|
|
429
|
+
[field]: {
|
|
430
|
+
description: `This is the object ${field}.`,
|
|
431
|
+
type: parseClass.fields[field].required ? new _graphql.GraphQLNonNull(type) : type
|
|
432
|
+
}
|
|
433
|
+
};
|
|
434
|
+
} else {
|
|
435
|
+
return fields;
|
|
436
|
+
}
|
|
437
|
+
}, parseObjectFields);
|
|
438
|
+
};
|
|
439
|
+
let classGraphQLOutputType = new _graphql.GraphQLObjectType({
|
|
440
|
+
name: classGraphQLOutputTypeName,
|
|
441
|
+
description: `The ${classGraphQLOutputTypeName} object type is used in operations that involve outputting objects of ${graphQLClassName} class.`,
|
|
442
|
+
interfaces,
|
|
443
|
+
fields: outputFields
|
|
444
|
+
});
|
|
445
|
+
classGraphQLOutputType = parseGraphQLSchema.addGraphQLType(classGraphQLOutputType);
|
|
446
|
+
const {
|
|
447
|
+
connectionType,
|
|
448
|
+
edgeType
|
|
449
|
+
} = (0, _graphqlRelay.connectionDefinitions)({
|
|
450
|
+
name: graphQLClassName,
|
|
451
|
+
connectionFields: {
|
|
452
|
+
count: defaultGraphQLTypes.COUNT_ATT
|
|
453
|
+
},
|
|
454
|
+
nodeType: classGraphQLOutputType || defaultGraphQLTypes.OBJECT
|
|
455
|
+
});
|
|
456
|
+
let classGraphQLFindResultType = undefined;
|
|
457
|
+
if (parseGraphQLSchema.addGraphQLType(edgeType) && parseGraphQLSchema.addGraphQLType(connectionType, false, false, true)) {
|
|
458
|
+
classGraphQLFindResultType = connectionType;
|
|
459
|
+
}
|
|
460
|
+
parseGraphQLSchema.parseClassTypes[className] = {
|
|
461
|
+
classGraphQLPointerType,
|
|
462
|
+
classGraphQLRelationType,
|
|
463
|
+
classGraphQLCreateType,
|
|
464
|
+
classGraphQLUpdateType,
|
|
465
|
+
classGraphQLConstraintsType,
|
|
466
|
+
classGraphQLRelationConstraintsType,
|
|
467
|
+
classGraphQLFindArgs,
|
|
468
|
+
classGraphQLOutputType,
|
|
469
|
+
classGraphQLFindResultType,
|
|
470
|
+
config: {
|
|
471
|
+
parseClassConfig,
|
|
472
|
+
isCreateEnabled,
|
|
473
|
+
isUpdateEnabled
|
|
474
|
+
}
|
|
475
|
+
};
|
|
476
|
+
if (className === '_User') {
|
|
477
|
+
const viewerType = new _graphql.GraphQLObjectType({
|
|
478
|
+
name: 'Viewer',
|
|
479
|
+
description: `The Viewer object type is used in operations that involve outputting the current user data.`,
|
|
480
|
+
fields: () => ({
|
|
481
|
+
sessionToken: defaultGraphQLTypes.SESSION_TOKEN_ATT,
|
|
482
|
+
user: {
|
|
483
|
+
description: 'This is the current user.',
|
|
484
|
+
type: new _graphql.GraphQLNonNull(classGraphQLOutputType)
|
|
485
|
+
}
|
|
486
|
+
})
|
|
487
|
+
});
|
|
488
|
+
parseGraphQLSchema.addGraphQLType(viewerType, true, true);
|
|
489
|
+
parseGraphQLSchema.viewerType = viewerType;
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
exports.load = load;
|
|
493
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZ3JhcGhxbCIsInJlcXVpcmUiLCJfZ3JhcGhxbFJlbGF5IiwiX2dyYXBocWxMaXN0RmllbGRzIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsImRlZmF1bHRHcmFwaFFMVHlwZXMiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsIm9iamVjdHNRdWVyaWVzIiwiX1BhcnNlR3JhcGhRTENvbnRyb2xsZXIiLCJfY2xhc3NOYW1lIiwiX2lucHV0VHlwZSIsIl9vdXRwdXRUeXBlIiwiX2NvbnN0cmFpbnRUeXBlIiwiX3BhcnNlR3JhcGhRTFV0aWxzIiwiZSIsInQiLCJXZWFrTWFwIiwiciIsIm4iLCJfX2VzTW9kdWxlIiwibyIsImkiLCJmIiwiX19wcm90b19fIiwiZGVmYXVsdCIsImhhcyIsImdldCIsInNldCIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwiZ2V0UGFyc2VDbGFzc1R5cGVDb25maWciLCJwYXJzZUNsYXNzQ29uZmlnIiwidHlwZSIsImdldElucHV0RmllbGRzQW5kQ29uc3RyYWludHMiLCJwYXJzZUNsYXNzIiwiY2xhc3NGaWVsZHMiLCJrZXlzIiwiZmllbGRzIiwiY29uY2F0IiwiaW5wdXRGaWVsZHMiLCJhbGxvd2VkSW5wdXRGaWVsZHMiLCJvdXRwdXRGaWVsZHMiLCJhbGxvd2VkT3V0cHV0RmllbGRzIiwiY29uc3RyYWludEZpZWxkcyIsImFsbG93ZWRDb25zdHJhaW50RmllbGRzIiwic29ydEZpZWxkcyIsImFsbG93ZWRTb3J0RmllbGRzIiwiY2xhc3NPdXRwdXRGaWVsZHMiLCJjbGFzc0NyZWF0ZUZpZWxkcyIsImNsYXNzVXBkYXRlRmllbGRzIiwiY2xhc3NDb25zdHJhaW50RmllbGRzIiwiY2xhc3NTb3J0RmllbGRzIiwiY2xhc3NDdXN0b21GaWVsZHMiLCJmaWx0ZXIiLCJmaWVsZCIsIlBBUlNFX09CSkVDVF9GSUVMRFMiLCJpbmNsdWRlcyIsImNyZWF0ZSIsInVwZGF0ZSIsImNsYXNzTmFtZSIsIm91dHB1dEZpZWxkIiwibGVuZ3RoIiwicHVzaCIsImFzYyIsImRlc2MiLCJtYXAiLCJsb2FkIiwicGFyc2VHcmFwaFFMU2NoZW1hIiwiZ3JhcGhRTENsYXNzTmFtZSIsInRyYW5zZm9ybUNsYXNzTmFtZVRvR3JhcGhRTCIsImlzQ3JlYXRlRW5hYmxlZCIsImlzVXBkYXRlRW5hYmxlZCIsImdldFBhcnNlQ2xhc3NNdXRhdGlvbkNvbmZpZyIsImNsYXNzR3JhcGhRTENyZWF0ZVR5cGVOYW1lIiwiY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSIsIkdyYXBoUUxJbnB1dE9iamVjdFR5cGUiLCJuYW1lIiwiZGVzY3JpcHRpb24iLCJyZWR1Y2UiLCJ0cmFuc2Zvcm1JbnB1dFR5cGVUb0dyYXBoUUwiLCJ0YXJnZXRDbGFzcyIsInBhcnNlQ2xhc3NUeXBlcyIsInJlcXVpcmVkIiwiR3JhcGhRTE5vbk51bGwiLCJBQ0wiLCJBQ0xfSU5QVVQiLCJhZGRHcmFwaFFMVHlwZSIsImNsYXNzR3JhcGhRTFVwZGF0ZVR5cGVOYW1lIiwiY2xhc3NHcmFwaFFMVXBkYXRlVHlwZSIsImNsYXNzR3JhcGhRTFBvaW50ZXJUeXBlTmFtZSIsImNsYXNzR3JhcGhRTFBvaW50ZXJUeXBlIiwibGluayIsIkdyYXBoUUxJRCIsIk9CSkVDVCIsImNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZU5hbWUiLCJjbGFzc0dyYXBoUUxSZWxhdGlvblR5cGUiLCJhZGQiLCJHcmFwaFFMTGlzdCIsIk9CSkVDVF9JRCIsInJlbW92ZSIsImNsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZU5hbWUiLCJjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGUiLCJsb2ciLCJ3YXJuIiwicGFyc2VGaWVsZCIsInRyYW5zZm9ybUNvbnN0cmFpbnRUeXBlVG9HcmFwaFFMIiwiT1IiLCJBTkQiLCJOT1IiLCJjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZU5hbWUiLCJjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZSIsImhhdmUiLCJoYXZlTm90IiwiZXhpc3RzIiwiR3JhcGhRTEJvb2xlYW4iLCJjbGFzc0dyYXBoUUxPcmRlclR5cGVOYW1lIiwiY2xhc3NHcmFwaFFMT3JkZXJUeXBlIiwiR3JhcGhRTEVudW1UeXBlIiwidmFsdWVzIiwiZmllbGRDb25maWciLCJ1cGRhdGVkU29ydEZpZWxkcyIsInZhbHVlIiwiY2xhc3NHcmFwaFFMRmluZEFyZ3MiLCJ3aGVyZSIsIm9yZGVyIiwiR3JhcGhRTFN0cmluZyIsInNraXAiLCJTS0lQX0FUVCIsImNvbm5lY3Rpb25BcmdzIiwib3B0aW9ucyIsIlJFQURfT1BUSU9OU19BVFQiLCJjbGFzc0dyYXBoUUxPdXRwdXRUeXBlTmFtZSIsImludGVyZmFjZXMiLCJQQVJTRV9PQkpFQ1QiLCJyZWxheU5vZGVJbnRlcmZhY2UiLCJwYXJzZU9iamVjdEZpZWxkcyIsImlkIiwiZ2xvYmFsSWRGaWVsZCIsIm9iaiIsIm9iamVjdElkIiwiYXV0aERhdGFSZXNwb25zZSIsInRyYW5zZm9ybU91dHB1dFR5cGVUb0dyYXBoUUwiLCJ0YXJnZXRQYXJzZUNsYXNzVHlwZXMiLCJhcmdzIiwidW5kZWZpbmVkIiwicmVzb2x2ZSIsInNvdXJjZSIsImNvbnRleHQiLCJxdWVyeUluZm8iLCJmaXJzdCIsImFmdGVyIiwibGFzdCIsImJlZm9yZSIsInJlYWRQcmVmZXJlbmNlIiwiaW5jbHVkZVJlYWRQcmVmZXJlbmNlIiwic3VicXVlcnlSZWFkUHJlZmVyZW5jZSIsImNvbmZpZyIsImF1dGgiLCJpbmZvIiwic2VsZWN0ZWRGaWVsZHMiLCJnZXRGaWVsZE5hbWVzIiwiaW5jbHVkZSIsImV4dHJhY3RLZXlzQW5kSW5jbHVkZSIsInN0YXJ0c1dpdGgiLCJyZXBsYWNlIiwiaW5kZXhPZiIsInBhcnNlT3JkZXIiLCJqb2luIiwiZmluZE9iamVjdHMiLCIkcmVsYXRlZFRvIiwib2JqZWN0IiwiX190eXBlIiwia2V5IiwicGFyc2VDbGFzc2VzIiwiaGFuZGxlRXJyb3IiLCJjb29yZGluYXRlcyIsImNvb3JkaW5hdGUiLCJsYXRpdHVkZSIsImxvbmdpdHVkZSIsImVsZW0iLCJjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIiwiR3JhcGhRTE9iamVjdFR5cGUiLCJjb25uZWN0aW9uVHlwZSIsImVkZ2VUeXBlIiwiY29ubmVjdGlvbkRlZmluaXRpb25zIiwiY29ubmVjdGlvbkZpZWxkcyIsImNvdW50IiwiQ09VTlRfQVRUIiwibm9kZVR5cGUiLCJjbGFzc0dyYXBoUUxGaW5kUmVzdWx0VHlwZSIsInZpZXdlclR5cGUiLCJzZXNzaW9uVG9rZW4iLCJTRVNTSU9OX1RPS0VOX0FUVCIsInVzZXIiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL0dyYXBoUUwvbG9hZGVycy9wYXJzZUNsYXNzVHlwZXMuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgaW5kZW50ICovXG5pbXBvcnQge1xuICBHcmFwaFFMSUQsXG4gIEdyYXBoUUxPYmplY3RUeXBlLFxuICBHcmFwaFFMU3RyaW5nLFxuICBHcmFwaFFMTGlzdCxcbiAgR3JhcGhRTElucHV0T2JqZWN0VHlwZSxcbiAgR3JhcGhRTE5vbk51bGwsXG4gIEdyYXBoUUxCb29sZWFuLFxuICBHcmFwaFFMRW51bVR5cGUsXG59IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgZ2xvYmFsSWRGaWVsZCwgY29ubmVjdGlvbkFyZ3MsIGNvbm5lY3Rpb25EZWZpbml0aW9ucyB9IGZyb20gJ2dyYXBocWwtcmVsYXknO1xuaW1wb3J0IGdldEZpZWxkTmFtZXMgZnJvbSAnZ3JhcGhxbC1saXN0LWZpZWxkcyc7XG5pbXBvcnQgKiBhcyBkZWZhdWx0R3JhcGhRTFR5cGVzIGZyb20gJy4vZGVmYXVsdEdyYXBoUUxUeXBlcyc7XG5pbXBvcnQgKiBhcyBvYmplY3RzUXVlcmllcyBmcm9tICcuLi9oZWxwZXJzL29iamVjdHNRdWVyaWVzJztcbmltcG9ydCB7IFBhcnNlR3JhcGhRTENsYXNzQ29uZmlnIH0gZnJvbSAnLi4vLi4vQ29udHJvbGxlcnMvUGFyc2VHcmFwaFFMQ29udHJvbGxlcic7XG5pbXBvcnQgeyB0cmFuc2Zvcm1DbGFzc05hbWVUb0dyYXBoUUwgfSBmcm9tICcuLi90cmFuc2Zvcm1lcnMvY2xhc3NOYW1lJztcbmltcG9ydCB7IHRyYW5zZm9ybUlucHV0VHlwZVRvR3JhcGhRTCB9IGZyb20gJy4uL3RyYW5zZm9ybWVycy9pbnB1dFR5cGUnO1xuaW1wb3J0IHsgdHJhbnNmb3JtT3V0cHV0VHlwZVRvR3JhcGhRTCB9IGZyb20gJy4uL3RyYW5zZm9ybWVycy9vdXRwdXRUeXBlJztcbmltcG9ydCB7IHRyYW5zZm9ybUNvbnN0cmFpbnRUeXBlVG9HcmFwaFFMIH0gZnJvbSAnLi4vdHJhbnNmb3JtZXJzL2NvbnN0cmFpbnRUeXBlJztcbmltcG9ydCB7IGV4dHJhY3RLZXlzQW5kSW5jbHVkZSwgZ2V0UGFyc2VDbGFzc011dGF0aW9uQ29uZmlnIH0gZnJvbSAnLi4vcGFyc2VHcmFwaFFMVXRpbHMnO1xuXG5jb25zdCBnZXRQYXJzZUNsYXNzVHlwZUNvbmZpZyA9IGZ1bmN0aW9uIChwYXJzZUNsYXNzQ29uZmlnOiA/UGFyc2VHcmFwaFFMQ2xhc3NDb25maWcpIHtcbiAgcmV0dXJuIChwYXJzZUNsYXNzQ29uZmlnICYmIHBhcnNlQ2xhc3NDb25maWcudHlwZSkgfHwge307XG59O1xuXG5jb25zdCBnZXRJbnB1dEZpZWxkc0FuZENvbnN0cmFpbnRzID0gZnVuY3Rpb24gKFxuICBwYXJzZUNsYXNzLFxuICBwYXJzZUNsYXNzQ29uZmlnOiA/UGFyc2VHcmFwaFFMQ2xhc3NDb25maWdcbikge1xuICBjb25zdCBjbGFzc0ZpZWxkcyA9IE9iamVjdC5rZXlzKHBhcnNlQ2xhc3MuZmllbGRzKS5jb25jYXQoJ2lkJyk7XG4gIGNvbnN0IHtcbiAgICBpbnB1dEZpZWxkczogYWxsb3dlZElucHV0RmllbGRzLFxuICAgIG91dHB1dEZpZWxkczogYWxsb3dlZE91dHB1dEZpZWxkcyxcbiAgICBjb25zdHJhaW50RmllbGRzOiBhbGxvd2VkQ29uc3RyYWludEZpZWxkcyxcbiAgICBzb3J0RmllbGRzOiBhbGxvd2VkU29ydEZpZWxkcyxcbiAgfSA9IGdldFBhcnNlQ2xhc3NUeXBlQ29uZmlnKHBhcnNlQ2xhc3NDb25maWcpO1xuXG4gIGxldCBjbGFzc091dHB1dEZpZWxkcztcbiAgbGV0IGNsYXNzQ3JlYXRlRmllbGRzO1xuICBsZXQgY2xhc3NVcGRhdGVGaWVsZHM7XG4gIGxldCBjbGFzc0NvbnN0cmFpbnRGaWVsZHM7XG4gIGxldCBjbGFzc1NvcnRGaWVsZHM7XG5cbiAgLy8gQWxsIGFsbG93ZWQgY3VzdG9tcyBmaWVsZHNcbiAgY29uc3QgY2xhc3NDdXN0b21GaWVsZHMgPSBjbGFzc0ZpZWxkcy5maWx0ZXIoZmllbGQgPT4ge1xuICAgIHJldHVybiAhT2JqZWN0LmtleXMoZGVmYXVsdEdyYXBoUUxUeXBlcy5QQVJTRV9PQkpFQ1RfRklFTERTKS5pbmNsdWRlcyhmaWVsZCkgJiYgZmllbGQgIT09ICdpZCc7XG4gIH0pO1xuXG4gIGlmIChhbGxvd2VkSW5wdXRGaWVsZHMgJiYgYWxsb3dlZElucHV0RmllbGRzLmNyZWF0ZSkge1xuICAgIGNsYXNzQ3JlYXRlRmllbGRzID0gY2xhc3NDdXN0b21GaWVsZHMuZmlsdGVyKGZpZWxkID0+IHtcbiAgICAgIHJldHVybiBhbGxvd2VkSW5wdXRGaWVsZHMuY3JlYXRlLmluY2x1ZGVzKGZpZWxkKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBjbGFzc0NyZWF0ZUZpZWxkcyA9IGNsYXNzQ3VzdG9tRmllbGRzO1xuICB9XG4gIGlmIChhbGxvd2VkSW5wdXRGaWVsZHMgJiYgYWxsb3dlZElucHV0RmllbGRzLnVwZGF0ZSkge1xuICAgIGNsYXNzVXBkYXRlRmllbGRzID0gY2xhc3NDdXN0b21GaWVsZHMuZmlsdGVyKGZpZWxkID0+IHtcbiAgICAgIHJldHVybiBhbGxvd2VkSW5wdXRGaWVsZHMudXBkYXRlLmluY2x1ZGVzKGZpZWxkKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBjbGFzc1VwZGF0ZUZpZWxkcyA9IGNsYXNzQ3VzdG9tRmllbGRzO1xuICB9XG5cbiAgaWYgKGFsbG93ZWRPdXRwdXRGaWVsZHMpIHtcbiAgICBjbGFzc091dHB1dEZpZWxkcyA9IGNsYXNzQ3VzdG9tRmllbGRzLmZpbHRlcihmaWVsZCA9PiB7XG4gICAgICByZXR1cm4gYWxsb3dlZE91dHB1dEZpZWxkcy5pbmNsdWRlcyhmaWVsZCk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgY2xhc3NPdXRwdXRGaWVsZHMgPSBjbGFzc0N1c3RvbUZpZWxkcztcbiAgfVxuICAvLyBGaWx0ZXJzIHRoZSBcInBhc3N3b3JkXCIgZmllbGQgZnJvbSBjbGFzcyBfVXNlclxuICBpZiAocGFyc2VDbGFzcy5jbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICBjbGFzc091dHB1dEZpZWxkcyA9IGNsYXNzT3V0cHV0RmllbGRzLmZpbHRlcihvdXRwdXRGaWVsZCA9PiBvdXRwdXRGaWVsZCAhPT0gJ3Bhc3N3b3JkJyk7XG4gIH1cblxuICBpZiAoYWxsb3dlZENvbnN0cmFpbnRGaWVsZHMpIHtcbiAgICBjbGFzc0NvbnN0cmFpbnRGaWVsZHMgPSBjbGFzc0N1c3RvbUZpZWxkcy5maWx0ZXIoZmllbGQgPT4ge1xuICAgICAgcmV0dXJuIGFsbG93ZWRDb25zdHJhaW50RmllbGRzLmluY2x1ZGVzKGZpZWxkKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBjbGFzc0NvbnN0cmFpbnRGaWVsZHMgPSBjbGFzc0ZpZWxkcztcbiAgfVxuXG4gIGlmIChhbGxvd2VkU29ydEZpZWxkcykge1xuICAgIGNsYXNzU29ydEZpZWxkcyA9IGFsbG93ZWRTb3J0RmllbGRzO1xuICAgIGlmICghY2xhc3NTb3J0RmllbGRzLmxlbmd0aCkge1xuICAgICAgLy8gbXVzdCBoYXZlIGF0IGxlYXN0IDEgb3JkZXIgZmllbGRcbiAgICAgIC8vIG90aGVyd2lzZSB0aGUgRmluZEFyZ3MgSW5wdXQgVHlwZSB3aWxsIHRocm93LlxuICAgICAgY2xhc3NTb3J0RmllbGRzLnB1c2goe1xuICAgICAgICBmaWVsZDogJ2lkJyxcbiAgICAgICAgYXNjOiB0cnVlLFxuICAgICAgICBkZXNjOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGNsYXNzU29ydEZpZWxkcyA9IGNsYXNzRmllbGRzLm1hcChmaWVsZCA9PiB7XG4gICAgICByZXR1cm4geyBmaWVsZCwgYXNjOiB0cnVlLCBkZXNjOiB0cnVlIH07XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIGNsYXNzQ3JlYXRlRmllbGRzLFxuICAgIGNsYXNzVXBkYXRlRmllbGRzLFxuICAgIGNsYXNzQ29uc3RyYWludEZpZWxkcyxcbiAgICBjbGFzc091dHB1dEZpZWxkcyxcbiAgICBjbGFzc1NvcnRGaWVsZHMsXG4gIH07XG59O1xuXG5jb25zdCBsb2FkID0gKHBhcnNlR3JhcGhRTFNjaGVtYSwgcGFyc2VDbGFzcywgcGFyc2VDbGFzc0NvbmZpZzogP1BhcnNlR3JhcGhRTENsYXNzQ29uZmlnKSA9PiB7XG4gIGNvbnN0IGNsYXNzTmFtZSA9IHBhcnNlQ2xhc3MuY2xhc3NOYW1lO1xuICBjb25zdCBncmFwaFFMQ2xhc3NOYW1lID0gdHJhbnNmb3JtQ2xhc3NOYW1lVG9HcmFwaFFMKGNsYXNzTmFtZSk7XG4gIGNvbnN0IHtcbiAgICBjbGFzc0NyZWF0ZUZpZWxkcyxcbiAgICBjbGFzc1VwZGF0ZUZpZWxkcyxcbiAgICBjbGFzc091dHB1dEZpZWxkcyxcbiAgICBjbGFzc0NvbnN0cmFpbnRGaWVsZHMsXG4gICAgY2xhc3NTb3J0RmllbGRzLFxuICB9ID0gZ2V0SW5wdXRGaWVsZHNBbmRDb25zdHJhaW50cyhwYXJzZUNsYXNzLCBwYXJzZUNsYXNzQ29uZmlnKTtcblxuICBjb25zdCB7XG4gICAgY3JlYXRlOiBpc0NyZWF0ZUVuYWJsZWQgPSB0cnVlLFxuICAgIHVwZGF0ZTogaXNVcGRhdGVFbmFibGVkID0gdHJ1ZSxcbiAgfSA9IGdldFBhcnNlQ2xhc3NNdXRhdGlvbkNvbmZpZyhwYXJzZUNsYXNzQ29uZmlnKTtcblxuICBjb25zdCBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlTmFtZSA9IGBDcmVhdGUke2dyYXBoUUxDbGFzc05hbWV9RmllbGRzSW5wdXRgO1xuICBsZXQgY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgICBuYW1lOiBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlTmFtZSxcbiAgICBkZXNjcmlwdGlvbjogYFRoZSAke2NsYXNzR3JhcGhRTENyZWF0ZVR5cGVOYW1lfSBpbnB1dCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgY3JlYXRpb24gb2Ygb2JqZWN0cyBpbiB0aGUgJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgIGZpZWxkczogKCkgPT5cbiAgICAgIGNsYXNzQ3JlYXRlRmllbGRzLnJlZHVjZShcbiAgICAgICAgKGZpZWxkcywgZmllbGQpID0+IHtcbiAgICAgICAgICBjb25zdCB0eXBlID0gdHJhbnNmb3JtSW5wdXRUeXBlVG9HcmFwaFFMKFxuICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnR5cGUsXG4gICAgICAgICAgICBwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0udGFyZ2V0Q2xhc3MsXG4gICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAodHlwZSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgLi4uZmllbGRzLFxuICAgICAgICAgICAgICBbZmllbGRdOiB7XG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IGBUaGlzIGlzIHRoZSBvYmplY3QgJHtmaWVsZH0uYCxcbiAgICAgICAgICAgICAgICB0eXBlOiBwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0ucmVxdWlyZWQgPyBuZXcgR3JhcGhRTE5vbk51bGwodHlwZSkgOiB0eXBlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGZpZWxkcztcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBBQ0w6IHsgdHlwZTogZGVmYXVsdEdyYXBoUUxUeXBlcy5BQ0xfSU5QVVQgfSxcbiAgICAgICAgfVxuICAgICAgKSxcbiAgfSk7XG4gIGNsYXNzR3JhcGhRTENyZWF0ZVR5cGUgPSBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSk7XG5cbiAgY29uc3QgY2xhc3NHcmFwaFFMVXBkYXRlVHlwZU5hbWUgPSBgVXBkYXRlJHtncmFwaFFMQ2xhc3NOYW1lfUZpZWxkc0lucHV0YDtcbiAgbGV0IGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGUgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gICAgbmFtZTogY2xhc3NHcmFwaFFMVXBkYXRlVHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBUaGUgJHtjbGFzc0dyYXBoUUxVcGRhdGVUeXBlTmFtZX0gaW5wdXQgdHlwZSBpcyB1c2VkIGluIG9wZXJhdGlvbnMgdGhhdCBpbnZvbHZlIGNyZWF0aW9uIG9mIG9iamVjdHMgaW4gdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuYCxcbiAgICBmaWVsZHM6ICgpID0+XG4gICAgICBjbGFzc1VwZGF0ZUZpZWxkcy5yZWR1Y2UoXG4gICAgICAgIChmaWVsZHMsIGZpZWxkKSA9PiB7XG4gICAgICAgICAgY29uc3QgdHlwZSA9IHRyYW5zZm9ybUlucHV0VHlwZVRvR3JhcGhRTChcbiAgICAgICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50eXBlLFxuICAgICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnRhcmdldENsYXNzLFxuICAgICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1xuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKHR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIC4uLmZpZWxkcyxcbiAgICAgICAgICAgICAgW2ZpZWxkXToge1xuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgVGhpcyBpcyB0aGUgb2JqZWN0ICR7ZmllbGR9LmAsXG4gICAgICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmaWVsZHM7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgQUNMOiB7IHR5cGU6IGRlZmF1bHRHcmFwaFFMVHlwZXMuQUNMX0lOUFVUIH0sXG4gICAgICAgIH1cbiAgICAgICksXG4gIH0pO1xuICBjbGFzc0dyYXBoUUxVcGRhdGVUeXBlID0gcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGUpO1xuXG4gIGNvbnN0IGNsYXNzR3JhcGhRTFBvaW50ZXJUeXBlTmFtZSA9IGAke2dyYXBoUUxDbGFzc05hbWV9UG9pbnRlcklucHV0YDtcbiAgbGV0IGNsYXNzR3JhcGhRTFBvaW50ZXJUeXBlID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICAgIG5hbWU6IGNsYXNzR3JhcGhRTFBvaW50ZXJUeXBlTmFtZSxcbiAgICBkZXNjcmlwdGlvbjogYEFsbG93IHRvIGxpbmsgT1IgYWRkIGFuZCBsaW5rIGFuIG9iamVjdCBvZiB0aGUgJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcy5gLFxuICAgIGZpZWxkczogKCkgPT4ge1xuICAgICAgY29uc3QgZmllbGRzID0ge1xuICAgICAgICBsaW5rOiB7XG4gICAgICAgICAgZGVzY3JpcHRpb246IGBMaW5rIGFuIGV4aXN0aW5nIG9iamVjdCBmcm9tICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuIFlvdSBjYW4gdXNlIGVpdGhlciB0aGUgZ2xvYmFsIG9yIHRoZSBvYmplY3QgaWQuYCxcbiAgICAgICAgICB0eXBlOiBHcmFwaFFMSUQsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgaWYgKGlzQ3JlYXRlRW5hYmxlZCkge1xuICAgICAgICBmaWVsZHNbJ2NyZWF0ZUFuZExpbmsnXSA9IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogYENyZWF0ZSBhbmQgbGluayBhbiBvYmplY3QgZnJvbSAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLmAsXG4gICAgICAgICAgdHlwZTogY2xhc3NHcmFwaFFMQ3JlYXRlVHlwZSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmaWVsZHM7XG4gICAgfSxcbiAgfSk7XG4gIGNsYXNzR3JhcGhRTFBvaW50ZXJUeXBlID1cbiAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoY2xhc3NHcmFwaFFMUG9pbnRlclR5cGUpIHx8IGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUO1xuXG4gIGNvbnN0IGNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZU5hbWUgPSBgJHtncmFwaFFMQ2xhc3NOYW1lfVJlbGF0aW9uSW5wdXRgO1xuICBsZXQgY2xhc3NHcmFwaFFMUmVsYXRpb25UeXBlID0gbmV3IEdyYXBoUUxJbnB1dE9iamVjdFR5cGUoe1xuICAgIG5hbWU6IGNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBBbGxvdyB0byBhZGQsIHJlbW92ZSwgY3JlYXRlQW5kQWRkIG9iamVjdHMgb2YgdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MgaW50byBhIHJlbGF0aW9uIGZpZWxkLmAsXG4gICAgZmllbGRzOiAoKSA9PiB7XG4gICAgICBjb25zdCBmaWVsZHMgPSB7XG4gICAgICAgIGFkZDoge1xuICAgICAgICAgIGRlc2NyaXB0aW9uOiBgQWRkIGV4aXN0aW5nIG9iamVjdHMgZnJvbSB0aGUgJHtncmFwaFFMQ2xhc3NOYW1lfSBjbGFzcyBpbnRvIHRoZSByZWxhdGlvbi4gWW91IGNhbiB1c2UgZWl0aGVyIHRoZSBnbG9iYWwgb3IgdGhlIG9iamVjdCBpZHMuYCxcbiAgICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QoZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1RfSUQpLFxuICAgICAgICB9LFxuICAgICAgICByZW1vdmU6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogYFJlbW92ZSBleGlzdGluZyBvYmplY3RzIGZyb20gdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3Mgb3V0IG9mIHRoZSByZWxhdGlvbi4gWW91IGNhbiB1c2UgZWl0aGVyIHRoZSBnbG9iYWwgb3IgdGhlIG9iamVjdCBpZHMuYCxcbiAgICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QoZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1RfSUQpLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICAgIGlmIChpc0NyZWF0ZUVuYWJsZWQpIHtcbiAgICAgICAgZmllbGRzWydjcmVhdGVBbmRBZGQnXSA9IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogYENyZWF0ZSBhbmQgYWRkIG9iamVjdHMgb2YgdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MgaW50byB0aGUgcmVsYXRpb24uYCxcbiAgICAgICAgICB0eXBlOiBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKGNsYXNzR3JhcGhRTENyZWF0ZVR5cGUpKSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmaWVsZHM7XG4gICAgfSxcbiAgfSk7XG4gIGNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZSA9XG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZSkgfHwgZGVmYXVsdEdyYXBoUUxUeXBlcy5PQkpFQ1Q7XG5cbiAgY29uc3QgY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlTmFtZSA9IGAke2dyYXBoUUxDbGFzc05hbWV9V2hlcmVJbnB1dGA7XG4gIGxldCBjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGUgPSBuZXcgR3JhcGhRTElucHV0T2JqZWN0VHlwZSh7XG4gICAgbmFtZTogY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlTmFtZSxcbiAgICBkZXNjcmlwdGlvbjogYFRoZSAke2NsYXNzR3JhcGhRTENvbnN0cmFpbnRzVHlwZU5hbWV9IGlucHV0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBmaWx0ZXJpbmcgb2JqZWN0cyBvZiAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLmAsXG4gICAgZmllbGRzOiAoKSA9PiAoe1xuICAgICAgLi4uY2xhc3NDb25zdHJhaW50RmllbGRzLnJlZHVjZSgoZmllbGRzLCBmaWVsZCkgPT4ge1xuICAgICAgICBpZiAoWydPUicsICdBTkQnLCAnTk9SJ10uaW5jbHVkZXMoZmllbGQpKSB7XG4gICAgICAgICAgcGFyc2VHcmFwaFFMU2NoZW1hLmxvZy53YXJuKFxuICAgICAgICAgICAgYEZpZWxkICR7ZmllbGR9IGNvdWxkIG5vdCBiZSBhZGRlZCB0byB0aGUgYXV0byBzY2hlbWEgJHtjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGVOYW1lfSBiZWNhdXNlIGl0IGNvbGxpZGVkIHdpdGggYW4gZXhpc3Rpbmcgb25lLmBcbiAgICAgICAgICApO1xuICAgICAgICAgIHJldHVybiBmaWVsZHM7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGFyc2VGaWVsZCA9IGZpZWxkID09PSAnaWQnID8gJ29iamVjdElkJyA6IGZpZWxkO1xuICAgICAgICBjb25zdCB0eXBlID0gdHJhbnNmb3JtQ29uc3RyYWludFR5cGVUb0dyYXBoUUwoXG4gICAgICAgICAgcGFyc2VDbGFzcy5maWVsZHNbcGFyc2VGaWVsZF0udHlwZSxcbiAgICAgICAgICBwYXJzZUNsYXNzLmZpZWxkc1twYXJzZUZpZWxkXS50YXJnZXRDbGFzcyxcbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzLFxuICAgICAgICAgIGZpZWxkXG4gICAgICAgICk7XG4gICAgICAgIGlmICh0eXBlKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmZpZWxkcyxcbiAgICAgICAgICAgIFtmaWVsZF06IHtcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb246IGBUaGlzIGlzIHRoZSBvYmplY3QgJHtmaWVsZH0uYCxcbiAgICAgICAgICAgICAgdHlwZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gZmllbGRzO1xuICAgICAgICB9XG4gICAgICB9LCB7fSksXG4gICAgICBPUjoge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIE9SIG9wZXJhdG9yIHRvIGNvbXBvdW5kIGNvbnN0cmFpbnRzLicsXG4gICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlKSksXG4gICAgICB9LFxuICAgICAgQU5EOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgQU5EIG9wZXJhdG9yIHRvIGNvbXBvdW5kIGNvbnN0cmFpbnRzLicsXG4gICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlKSksXG4gICAgICB9LFxuICAgICAgTk9SOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnVGhpcyBpcyB0aGUgTk9SIG9wZXJhdG9yIHRvIGNvbXBvdW5kIGNvbnN0cmFpbnRzLicsXG4gICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTGlzdChuZXcgR3JhcGhRTE5vbk51bGwoY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlKSksXG4gICAgICB9LFxuICAgIH0pLFxuICB9KTtcbiAgY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlID1cbiAgICBwYXJzZUdyYXBoUUxTY2hlbWEuYWRkR3JhcGhRTFR5cGUoY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlKSB8fCBkZWZhdWx0R3JhcGhRTFR5cGVzLk9CSkVDVDtcblxuICBjb25zdCBjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZU5hbWUgPSBgJHtncmFwaFFMQ2xhc3NOYW1lfVJlbGF0aW9uV2hlcmVJbnB1dGA7XG4gIGxldCBjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZSA9IG5ldyBHcmFwaFFMSW5wdXRPYmplY3RUeXBlKHtcbiAgICBuYW1lOiBjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBUaGUgJHtjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZU5hbWV9IGlucHV0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBmaWx0ZXJpbmcgb2JqZWN0cyBvZiAke2dyYXBoUUxDbGFzc05hbWV9IGNsYXNzLmAsXG4gICAgZmllbGRzOiAoKSA9PiAoe1xuICAgICAgaGF2ZToge1xuICAgICAgICBkZXNjcmlwdGlvbjogJ1J1biBhIHJlbGF0aW9uYWwvcG9pbnRlciBxdWVyeSB3aGVyZSBhdCBsZWFzdCBvbmUgY2hpbGQgb2JqZWN0IGNhbiBtYXRjaC4nLFxuICAgICAgICB0eXBlOiBjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGUsXG4gICAgICB9LFxuICAgICAgaGF2ZU5vdDoge1xuICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAnUnVuIGFuIGludmVydGVkIHJlbGF0aW9uYWwvcG9pbnRlciBxdWVyeSB3aGVyZSBhdCBsZWFzdCBvbmUgY2hpbGQgb2JqZWN0IGNhbiBtYXRjaC4nLFxuICAgICAgICB0eXBlOiBjbGFzc0dyYXBoUUxDb25zdHJhaW50c1R5cGUsXG4gICAgICB9LFxuICAgICAgZXhpc3RzOiB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiAnQ2hlY2sgaWYgdGhlIHJlbGF0aW9uL3BvaW50ZXIgY29udGFpbnMgb2JqZWN0cy4nLFxuICAgICAgICB0eXBlOiBHcmFwaFFMQm9vbGVhbixcbiAgICAgIH0sXG4gICAgfSksXG4gIH0pO1xuICBjbGFzc0dyYXBoUUxSZWxhdGlvbkNvbnN0cmFpbnRzVHlwZSA9XG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNsYXNzR3JhcGhRTFJlbGF0aW9uQ29uc3RyYWludHNUeXBlKSB8fFxuICAgIGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNUO1xuXG4gIGNvbnN0IGNsYXNzR3JhcGhRTE9yZGVyVHlwZU5hbWUgPSBgJHtncmFwaFFMQ2xhc3NOYW1lfU9yZGVyYDtcbiAgbGV0IGNsYXNzR3JhcGhRTE9yZGVyVHlwZSA9IG5ldyBHcmFwaFFMRW51bVR5cGUoe1xuICAgIG5hbWU6IGNsYXNzR3JhcGhRTE9yZGVyVHlwZU5hbWUsXG4gICAgZGVzY3JpcHRpb246IGBUaGUgJHtjbGFzc0dyYXBoUUxPcmRlclR5cGVOYW1lfSBpbnB1dCB0eXBlIGlzIHVzZWQgd2hlbiBzb3J0aW5nIG9iamVjdHMgb2YgdGhlICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuYCxcbiAgICB2YWx1ZXM6IGNsYXNzU29ydEZpZWxkcy5yZWR1Y2UoKHNvcnRGaWVsZHMsIGZpZWxkQ29uZmlnKSA9PiB7XG4gICAgICBjb25zdCB7IGZpZWxkLCBhc2MsIGRlc2MgfSA9IGZpZWxkQ29uZmlnO1xuICAgICAgY29uc3QgdXBkYXRlZFNvcnRGaWVsZHMgPSB7XG4gICAgICAgIC4uLnNvcnRGaWVsZHMsXG4gICAgICB9O1xuICAgICAgY29uc3QgdmFsdWUgPSBmaWVsZCA9PT0gJ2lkJyA/ICdvYmplY3RJZCcgOiBmaWVsZDtcbiAgICAgIGlmIChhc2MpIHtcbiAgICAgICAgdXBkYXRlZFNvcnRGaWVsZHNbYCR7ZmllbGR9X0FTQ2BdID0geyB2YWx1ZSB9O1xuICAgICAgfVxuICAgICAgaWYgKGRlc2MpIHtcbiAgICAgICAgdXBkYXRlZFNvcnRGaWVsZHNbYCR7ZmllbGR9X0RFU0NgXSA9IHsgdmFsdWU6IGAtJHt2YWx1ZX1gIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gdXBkYXRlZFNvcnRGaWVsZHM7XG4gICAgfSwge30pLFxuICB9KTtcbiAgY2xhc3NHcmFwaFFMT3JkZXJUeXBlID0gcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGNsYXNzR3JhcGhRTE9yZGVyVHlwZSk7XG5cbiAgY29uc3QgY2xhc3NHcmFwaFFMRmluZEFyZ3MgPSB7XG4gICAgd2hlcmU6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlc2UgYXJlIHRoZSBjb25kaXRpb25zIHRoYXQgdGhlIG9iamVjdHMgbmVlZCB0byBtYXRjaCBpbiBvcmRlciB0byBiZSBmb3VuZC4nLFxuICAgICAgdHlwZTogY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlLFxuICAgIH0sXG4gICAgb3JkZXI6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIGZpZWxkcyB0byBiZSB1c2VkIHdoZW4gc29ydGluZyB0aGUgZGF0YSBmZXRjaGVkLicsXG4gICAgICB0eXBlOiBjbGFzc0dyYXBoUUxPcmRlclR5cGVcbiAgICAgICAgPyBuZXcgR3JhcGhRTExpc3QobmV3IEdyYXBoUUxOb25OdWxsKGNsYXNzR3JhcGhRTE9yZGVyVHlwZSkpXG4gICAgICAgIDogR3JhcGhRTFN0cmluZyxcbiAgICB9LFxuICAgIHNraXA6IGRlZmF1bHRHcmFwaFFMVHlwZXMuU0tJUF9BVFQsXG4gICAgLi4uY29ubmVjdGlvbkFyZ3MsXG4gICAgb3B0aW9uczogZGVmYXVsdEdyYXBoUUxUeXBlcy5SRUFEX09QVElPTlNfQVRULFxuICB9O1xuICBjb25zdCBjbGFzc0dyYXBoUUxPdXRwdXRUeXBlTmFtZSA9IGAke2dyYXBoUUxDbGFzc05hbWV9YDtcbiAgY29uc3QgaW50ZXJmYWNlcyA9IFtkZWZhdWx0R3JhcGhRTFR5cGVzLlBBUlNFX09CSkVDVCwgcGFyc2VHcmFwaFFMU2NoZW1hLnJlbGF5Tm9kZUludGVyZmFjZV07XG4gIGNvbnN0IHBhcnNlT2JqZWN0RmllbGRzID0ge1xuICAgIGlkOiBnbG9iYWxJZEZpZWxkKGNsYXNzTmFtZSwgb2JqID0+IG9iai5vYmplY3RJZCksXG4gICAgLi4uZGVmYXVsdEdyYXBoUUxUeXBlcy5QQVJTRV9PQkpFQ1RfRklFTERTLFxuICAgIC4uLihjbGFzc05hbWUgPT09ICdfVXNlcidcbiAgICAgID8ge1xuICAgICAgICAgIGF1dGhEYXRhUmVzcG9uc2U6IHtcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgYXV0aCBwcm92aWRlciByZXNwb25zZSB3aGVuIHRyaWdnZXJlZCBvbiBzaWduVXAvbG9nSW4uYCxcbiAgICAgICAgICAgIHR5cGU6IGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNULFxuICAgICAgICAgIH0sXG4gICAgICAgIH1cbiAgICAgIDoge30pLFxuICB9O1xuICBjb25zdCBvdXRwdXRGaWVsZHMgPSAoKSA9PiB7XG4gICAgcmV0dXJuIGNsYXNzT3V0cHV0RmllbGRzLnJlZHVjZSgoZmllbGRzLCBmaWVsZCkgPT4ge1xuICAgICAgY29uc3QgdHlwZSA9IHRyYW5zZm9ybU91dHB1dFR5cGVUb0dyYXBoUUwoXG4gICAgICAgIHBhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50eXBlLFxuICAgICAgICBwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0udGFyZ2V0Q2xhc3MsXG4gICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5wYXJzZUNsYXNzVHlwZXNcbiAgICAgICk7XG4gICAgICBpZiAocGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdSZWxhdGlvbicpIHtcbiAgICAgICAgY29uc3QgdGFyZ2V0UGFyc2VDbGFzc1R5cGVzID1cbiAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc1R5cGVzW3BhcnNlQ2xhc3MuZmllbGRzW2ZpZWxkXS50YXJnZXRDbGFzc107XG4gICAgICAgIGNvbnN0IGFyZ3MgPSB0YXJnZXRQYXJzZUNsYXNzVHlwZXMgPyB0YXJnZXRQYXJzZUNsYXNzVHlwZXMuY2xhc3NHcmFwaFFMRmluZEFyZ3MgOiB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4uZmllbGRzLFxuICAgICAgICAgIFtmaWVsZF06IHtcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgVGhpcyBpcyB0aGUgb2JqZWN0ICR7ZmllbGR9LmAsXG4gICAgICAgICAgICBhcmdzLFxuICAgICAgICAgICAgdHlwZTogcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnJlcXVpcmVkID8gbmV3IEdyYXBoUUxOb25OdWxsKHR5cGUpIDogdHlwZSxcbiAgICAgICAgICAgIGFzeW5jIHJlc29sdmUoc291cmNlLCBhcmdzLCBjb250ZXh0LCBxdWVyeUluZm8pIHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb25zdCB7IHdoZXJlLCBvcmRlciwgc2tpcCwgZmlyc3QsIGFmdGVyLCBsYXN0LCBiZWZvcmUsIG9wdGlvbnMgfSA9IGFyZ3M7XG4gICAgICAgICAgICAgICAgY29uc3QgeyByZWFkUHJlZmVyZW5jZSwgaW5jbHVkZVJlYWRQcmVmZXJlbmNlLCBzdWJxdWVyeVJlYWRQcmVmZXJlbmNlIH0gPVxuICAgICAgICAgICAgICAgICAgb3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICAgICAgICBjb25zdCB7IGNvbmZpZywgYXV0aCwgaW5mbyB9ID0gY29udGV4dDtcbiAgICAgICAgICAgICAgICBjb25zdCBzZWxlY3RlZEZpZWxkcyA9IGdldEZpZWxkTmFtZXMocXVlcnlJbmZvKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHsga2V5cywgaW5jbHVkZSB9ID0gZXh0cmFjdEtleXNBbmRJbmNsdWRlKFxuICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRGaWVsZHNcbiAgICAgICAgICAgICAgICAgICAgLmZpbHRlcihmaWVsZCA9PiBmaWVsZC5zdGFydHNXaXRoKCdlZGdlcy5ub2RlLicpKVxuICAgICAgICAgICAgICAgICAgICAubWFwKGZpZWxkID0+IGZpZWxkLnJlcGxhY2UoJ2VkZ2VzLm5vZGUuJywgJycpKVxuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKGZpZWxkID0+IGZpZWxkLmluZGV4T2YoJ2VkZ2VzLm5vZGUnKSA8IDApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJzZU9yZGVyID0gb3JkZXIgJiYgb3JkZXIuam9pbignLCcpO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9iamVjdHNRdWVyaWVzLmZpbmRPYmplY3RzKFxuICAgICAgICAgICAgICAgICAgc291cmNlW2ZpZWxkXS5jbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICRyZWxhdGVkVG86IHtcbiAgICAgICAgICAgICAgICAgICAgICBvYmplY3Q6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF9fdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBjbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBvYmplY3RJZDogc291cmNlLm9iamVjdElkLFxuICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAga2V5OiBmaWVsZCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgLi4uKHdoZXJlIHx8IHt9KSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBwYXJzZU9yZGVyLFxuICAgICAgICAgICAgICAgICAgc2tpcCxcbiAgICAgICAgICAgICAgICAgIGZpcnN0LFxuICAgICAgICAgICAgICAgICAgYWZ0ZXIsXG4gICAgICAgICAgICAgICAgICBsYXN0LFxuICAgICAgICAgICAgICAgICAgYmVmb3JlLFxuICAgICAgICAgICAgICAgICAga2V5cyxcbiAgICAgICAgICAgICAgICAgIGluY2x1ZGUsXG4gICAgICAgICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgICAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgICAgICAgICAgICAgaW5jbHVkZVJlYWRQcmVmZXJlbmNlLFxuICAgICAgICAgICAgICAgICAgc3VicXVlcnlSZWFkUHJlZmVyZW5jZSxcbiAgICAgICAgICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICAgICAgICAgIGF1dGgsXG4gICAgICAgICAgICAgICAgICBpbmZvLFxuICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRGaWVsZHMsXG4gICAgICAgICAgICAgICAgICBwYXJzZUdyYXBoUUxTY2hlbWEucGFyc2VDbGFzc2VzXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5oYW5kbGVFcnJvcihlKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIGlmIChwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0udHlwZSA9PT0gJ1BvbHlnb24nKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4uZmllbGRzLFxuICAgICAgICAgIFtmaWVsZF06IHtcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgVGhpcyBpcyB0aGUgb2JqZWN0ICR7ZmllbGR9LmAsXG4gICAgICAgICAgICB0eXBlOiBwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0ucmVxdWlyZWQgPyBuZXcgR3JhcGhRTE5vbk51bGwodHlwZSkgOiB0eXBlLFxuICAgICAgICAgICAgYXN5bmMgcmVzb2x2ZShzb3VyY2UpIHtcbiAgICAgICAgICAgICAgaWYgKHNvdXJjZVtmaWVsZF0gJiYgc291cmNlW2ZpZWxkXS5jb29yZGluYXRlcykge1xuICAgICAgICAgICAgICAgIHJldHVybiBzb3VyY2VbZmllbGRdLmNvb3JkaW5hdGVzLm1hcChjb29yZGluYXRlID0+ICh7XG4gICAgICAgICAgICAgICAgICBsYXRpdHVkZTogY29vcmRpbmF0ZVswXSxcbiAgICAgICAgICAgICAgICAgIGxvbmdpdHVkZTogY29vcmRpbmF0ZVsxXSxcbiAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSBpZiAocGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdBcnJheScpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAuLi5maWVsZHMsXG4gICAgICAgICAgW2ZpZWxkXToge1xuICAgICAgICAgICAgZGVzY3JpcHRpb246IGBVc2UgSW5saW5lIEZyYWdtZW50IG9uIEFycmF5IHRvIGdldCByZXN1bHRzOiBodHRwczovL2dyYXBocWwub3JnL2xlYXJuL3F1ZXJpZXMvI2lubGluZS1mcmFnbWVudHNgLFxuICAgICAgICAgICAgdHlwZTogcGFyc2VDbGFzcy5maWVsZHNbZmllbGRdLnJlcXVpcmVkID8gbmV3IEdyYXBoUUxOb25OdWxsKHR5cGUpIDogdHlwZSxcbiAgICAgICAgICAgIGFzeW5jIHJlc29sdmUoc291cmNlKSB7XG4gICAgICAgICAgICAgIGlmICghc291cmNlW2ZpZWxkXSkgeyByZXR1cm4gbnVsbDsgfVxuICAgICAgICAgICAgICByZXR1cm4gc291cmNlW2ZpZWxkXS5tYXAoYXN5bmMgZWxlbSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGVsZW0uY2xhc3NOYW1lICYmIGVsZW0ub2JqZWN0SWQgJiYgZWxlbS5fX3R5cGUgPT09ICdPYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gZWxlbTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgdmFsdWU6IGVsZW0gfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIGlmICh0eXBlKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4uZmllbGRzLFxuICAgICAgICAgIFtmaWVsZF06IHtcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgVGhpcyBpcyB0aGUgb2JqZWN0ICR7ZmllbGR9LmAsXG4gICAgICAgICAgICB0eXBlOiBwYXJzZUNsYXNzLmZpZWxkc1tmaWVsZF0ucmVxdWlyZWQgPyBuZXcgR3JhcGhRTE5vbk51bGwodHlwZSkgOiB0eXBlLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmllbGRzO1xuICAgICAgfVxuICAgIH0sIHBhcnNlT2JqZWN0RmllbGRzKTtcbiAgfTtcbiAgbGV0IGNsYXNzR3JhcGhRTE91dHB1dFR5cGUgPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICAgIG5hbWU6IGNsYXNzR3JhcGhRTE91dHB1dFR5cGVOYW1lLFxuICAgIGRlc2NyaXB0aW9uOiBgVGhlICR7Y2xhc3NHcmFwaFFMT3V0cHV0VHlwZU5hbWV9IG9iamVjdCB0eXBlIGlzIHVzZWQgaW4gb3BlcmF0aW9ucyB0aGF0IGludm9sdmUgb3V0cHV0dGluZyBvYmplY3RzIG9mICR7Z3JhcGhRTENsYXNzTmFtZX0gY2xhc3MuYCxcbiAgICBpbnRlcmZhY2VzLFxuICAgIGZpZWxkczogb3V0cHV0RmllbGRzLFxuICB9KTtcbiAgY2xhc3NHcmFwaFFMT3V0cHV0VHlwZSA9IHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjbGFzc0dyYXBoUUxPdXRwdXRUeXBlKTtcblxuICBjb25zdCB7IGNvbm5lY3Rpb25UeXBlLCBlZGdlVHlwZSB9ID0gY29ubmVjdGlvbkRlZmluaXRpb25zKHtcbiAgICBuYW1lOiBncmFwaFFMQ2xhc3NOYW1lLFxuICAgIGNvbm5lY3Rpb25GaWVsZHM6IHtcbiAgICAgIGNvdW50OiBkZWZhdWx0R3JhcGhRTFR5cGVzLkNPVU5UX0FUVCxcbiAgICB9LFxuICAgIG5vZGVUeXBlOiBjbGFzc0dyYXBoUUxPdXRwdXRUeXBlIHx8IGRlZmF1bHRHcmFwaFFMVHlwZXMuT0JKRUNULFxuICB9KTtcbiAgbGV0IGNsYXNzR3JhcGhRTEZpbmRSZXN1bHRUeXBlID0gdW5kZWZpbmVkO1xuICBpZiAoXG4gICAgcGFyc2VHcmFwaFFMU2NoZW1hLmFkZEdyYXBoUUxUeXBlKGVkZ2VUeXBlKSAmJlxuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZShjb25uZWN0aW9uVHlwZSwgZmFsc2UsIGZhbHNlLCB0cnVlKVxuICApIHtcbiAgICBjbGFzc0dyYXBoUUxGaW5kUmVzdWx0VHlwZSA9IGNvbm5lY3Rpb25UeXBlO1xuICB9XG5cbiAgcGFyc2VHcmFwaFFMU2NoZW1hLnBhcnNlQ2xhc3NUeXBlc1tjbGFzc05hbWVdID0ge1xuICAgIGNsYXNzR3JhcGhRTFBvaW50ZXJUeXBlLFxuICAgIGNsYXNzR3JhcGhRTFJlbGF0aW9uVHlwZSxcbiAgICBjbGFzc0dyYXBoUUxDcmVhdGVUeXBlLFxuICAgIGNsYXNzR3JhcGhRTFVwZGF0ZVR5cGUsXG4gICAgY2xhc3NHcmFwaFFMQ29uc3RyYWludHNUeXBlLFxuICAgIGNsYXNzR3JhcGhRTFJlbGF0aW9uQ29uc3RyYWludHNUeXBlLFxuICAgIGNsYXNzR3JhcGhRTEZpbmRBcmdzLFxuICAgIGNsYXNzR3JhcGhRTE91dHB1dFR5cGUsXG4gICAgY2xhc3NHcmFwaFFMRmluZFJlc3VsdFR5cGUsXG4gICAgY29uZmlnOiB7XG4gICAgICBwYXJzZUNsYXNzQ29uZmlnLFxuICAgICAgaXNDcmVhdGVFbmFibGVkLFxuICAgICAgaXNVcGRhdGVFbmFibGVkLFxuICAgIH0sXG4gIH07XG5cbiAgaWYgKGNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIGNvbnN0IHZpZXdlclR5cGUgPSBuZXcgR3JhcGhRTE9iamVjdFR5cGUoe1xuICAgICAgbmFtZTogJ1ZpZXdlcicsXG4gICAgICBkZXNjcmlwdGlvbjogYFRoZSBWaWV3ZXIgb2JqZWN0IHR5cGUgaXMgdXNlZCBpbiBvcGVyYXRpb25zIHRoYXQgaW52b2x2ZSBvdXRwdXR0aW5nIHRoZSBjdXJyZW50IHVzZXIgZGF0YS5gLFxuICAgICAgZmllbGRzOiAoKSA9PiAoe1xuICAgICAgICBzZXNzaW9uVG9rZW46IGRlZmF1bHRHcmFwaFFMVHlwZXMuU0VTU0lPTl9UT0tFTl9BVFQsXG4gICAgICAgIHVzZXI6IHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgdGhlIGN1cnJlbnQgdXNlci4nLFxuICAgICAgICAgIHR5cGU6IG5ldyBHcmFwaFFMTm9uTnVsbChjbGFzc0dyYXBoUUxPdXRwdXRUeXBlKSxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIH0pO1xuICAgIHBhcnNlR3JhcGhRTFNjaGVtYS5hZGRHcmFwaFFMVHlwZSh2aWV3ZXJUeXBlLCB0cnVlLCB0cnVlKTtcbiAgICBwYXJzZUdyYXBoUUxTY2hlbWEudmlld2VyVHlwZSA9IHZpZXdlclR5cGU7XG4gIH1cbn07XG5cbmV4cG9ydCB7IGV4dHJhY3RLZXlzQW5kSW5jbHVkZSwgbG9hZCB9O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFDQSxJQUFBQSxRQUFBLEdBQUFDLE9BQUE7QUFVQSxJQUFBQyxhQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxrQkFBQSxHQUFBQyxzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQUksbUJBQUEsR0FBQUMsdUJBQUEsQ0FBQUwsT0FBQTtBQUNBLElBQUFNLGNBQUEsR0FBQUQsdUJBQUEsQ0FBQUwsT0FBQTtBQUNBLElBQUFPLHVCQUFBLEdBQUFQLE9BQUE7QUFDQSxJQUFBUSxVQUFBLEdBQUFSLE9BQUE7QUFDQSxJQUFBUyxVQUFBLEdBQUFULE9BQUE7QUFDQSxJQUFBVSxXQUFBLEdBQUFWLE9B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QUFHakgsa0JBQWtCLENBQUNtQixjQUFjLENBQUM4RixzQkFBc0IsQ0FBQztFQUVsRixNQUFNO0lBQUVFLGNBQWM7SUFBRUM7RUFBUyxDQUFDLEdBQUcsSUFBQUMsbUNBQXFCLEVBQUM7SUFDekQ1RyxJQUFJLEVBQUVSLGdCQUFnQjtJQUN0QnFILGdCQUFnQixFQUFFO01BQ2hCQyxLQUFLLEVBQUV4TCxtQkFBbUIsQ0FBQ3lMO0lBQzdCLENBQUM7SUFDREMsUUFBUSxFQUFFUixzQkFBc0IsSUFBSWxMLG1CQUFtQixDQUFDMkY7RUFDMUQsQ0FBQyxDQUFDO0VBQ0YsSUFBSWdHLDBCQUEwQixHQUFHN0MsU0FBUztFQUMxQyxJQUNFN0Usa0JBQWtCLENBQUNtQixjQUFjLENBQUNpRyxRQUFRLENBQUMsSUFDM0NwSCxrQkFBa0IsQ0FBQ21CLGNBQWMsQ0FBQ2dHLGNBQWMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxFQUNyRTtJQUNBTywwQkFBMEIsR0FBR1AsY0FBYztFQUM3QztFQUVBbkgsa0JBQWtCLENBQUNjLGVBQWUsQ0FBQ3RCLFNBQVMsQ0FBQyxHQUFHO0lBQzlDK0IsdUJBQXVCO0lBQ3ZCSyx3QkFBd0I7SUFDeEJyQixzQkFBc0I7SUFDdEJjLHNCQUFzQjtJQUN0QmEsMkJBQTJCO0lBQzNCUyxtQ0FBbUM7SUFDbkNZLG9CQUFvQjtJQUNwQjBELHNCQUFzQjtJQUN0QlMsMEJBQTBCO0lBQzFCakMsTUFBTSxFQUFFO01BQ043SCxnQkFBZ0I7TUFDaEJ1QyxlQUFlO01BQ2ZDO0lBQ0Y7RUFDRixDQUFDO0VBRUQsSUFBSVosU0FBUyxLQUFLLE9BQU8sRUFBRTtJQUN6QixNQUFNbUksVUFBVSxHQUFHLElBQUlULDBCQUFpQixDQUFDO01BQ3ZDekcsSUFBSSxFQUFFLFFBQVE7TUFDZEMsV0FBVyxFQUFFLDZGQUE2RjtNQUMxR3hDLE1BQU0sRUFBRUEsQ0FBQSxNQUFPO1FBQ2IwSixZQUFZLEVBQUU3TCxtQkFBbUIsQ0FBQzhMLGlCQUFpQjtRQUNuREMsSUFBSSxFQUFFO1VBQ0pwSCxXQUFXLEVBQUUsMkJBQTJCO1VBQ3hDN0MsSUFBSSxFQUFFLElBQUltRCx1QkFBYyxDQUFDaUcsc0JBQXNCO1FBQ2pEO01BQ0YsQ0FBQztJQUNILENBQUMsQ0FBQztJQUNGakgsa0JBQWtCLENBQUNtQixjQUFjLENBQUN3RyxVQUFVLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQztJQUN6RDNILGtCQUFrQixDQUFDMkgsVUFBVSxHQUFHQSxVQUFVO0VBQzVDO0FBQ0YsQ0FBQztBQUFDSSxPQUFBLENBQUFoSSxJQUFBLEdBQUFBLElBQUEiLCJpZ25vcmVMaXN0IjpbXX0=
|