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
|
@@ -1,55 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.MongoStorageAdapter =
|
|
7
|
-
|
|
8
|
-
var
|
|
9
|
-
|
|
10
|
-
var
|
|
11
|
-
|
|
12
|
-
var
|
|
13
|
-
|
|
14
|
-
var
|
|
15
|
-
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
var _MongoTransform = require('./MongoTransform');
|
|
21
|
-
|
|
22
|
-
var _node = require('parse/node');
|
|
23
|
-
|
|
24
|
-
var _node2 = _interopRequireDefault(_node);
|
|
25
|
-
|
|
26
|
-
var _lodash = require('lodash');
|
|
27
|
-
|
|
28
|
-
var _lodash2 = _interopRequireDefault(_lodash);
|
|
29
|
-
|
|
30
|
-
var _defaults = require('../../../defaults');
|
|
31
|
-
|
|
32
|
-
var _defaults2 = _interopRequireDefault(_defaults);
|
|
33
|
-
|
|
34
|
-
var _logger = require('../../../logger');
|
|
35
|
-
|
|
36
|
-
var _logger2 = _interopRequireDefault(_logger);
|
|
37
|
-
|
|
38
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
39
|
-
|
|
40
|
-
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
|
|
6
|
+
exports.default = exports.MongoStorageAdapter = void 0;
|
|
7
|
+
var _mongodbUrl = require("../../../vendor/mongodbUrl");
|
|
8
|
+
var _StorageAdapter = require("../StorageAdapter");
|
|
9
|
+
var _MongoCollection = _interopRequireDefault(require("./MongoCollection"));
|
|
10
|
+
var _MongoSchemaCollection = _interopRequireDefault(require("./MongoSchemaCollection"));
|
|
11
|
+
var _MongoTransform = require("./MongoTransform");
|
|
12
|
+
var _node = _interopRequireDefault(require("parse/node"));
|
|
13
|
+
var _lodash = _interopRequireDefault(require("lodash"));
|
|
14
|
+
var _defaults = _interopRequireWildcard(require("../../../defaults"));
|
|
15
|
+
var _logger = _interopRequireDefault(require("../../../logger"));
|
|
16
|
+
var _Utils = _interopRequireDefault(require("../../../Utils"));
|
|
17
|
+
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); }
|
|
18
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
41
19
|
// -disable-next
|
|
42
|
-
|
|
43
20
|
// -disable-next
|
|
44
|
-
|
|
45
|
-
|
|
46
21
|
// -disable-next
|
|
47
22
|
const mongodb = require('mongodb');
|
|
48
23
|
const MongoClient = mongodb.MongoClient;
|
|
49
24
|
const ReadPreference = mongodb.ReadPreference;
|
|
50
|
-
|
|
51
25
|
const MongoSchemaCollectionName = '_SCHEMA';
|
|
52
|
-
|
|
53
26
|
const storageAdapterAllCollections = mongoAdapter => {
|
|
54
27
|
return mongoAdapter.connect().then(() => mongoAdapter.database.collections()).then(collections => {
|
|
55
28
|
return collections.filter(collection => {
|
|
@@ -62,13 +35,11 @@ const storageAdapterAllCollections = mongoAdapter => {
|
|
|
62
35
|
});
|
|
63
36
|
});
|
|
64
37
|
};
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
38
|
+
const convertParseSchemaToMongoSchema = ({
|
|
39
|
+
...schema
|
|
40
|
+
}) => {
|
|
69
41
|
delete schema.fields._rperm;
|
|
70
42
|
delete schema.fields._wperm;
|
|
71
|
-
|
|
72
43
|
if (schema.className === '_User') {
|
|
73
44
|
// Legacy mongo adapter knows about the difference between password and _hashed_password.
|
|
74
45
|
// Future database adapters will only know about _hashed_password.
|
|
@@ -76,7 +47,6 @@ const convertParseSchemaToMongoSchema = (_ref) => {
|
|
|
76
47
|
// to add _hashed_password back ever.
|
|
77
48
|
delete schema.fields._hashed_password;
|
|
78
49
|
}
|
|
79
|
-
|
|
80
50
|
return schema;
|
|
81
51
|
};
|
|
82
52
|
|
|
@@ -90,11 +60,22 @@ const mongoSchemaFromFieldsAndClassNameAndCLP = (fields, className, classLevelPe
|
|
|
90
60
|
createdAt: 'string',
|
|
91
61
|
_metadata: undefined
|
|
92
62
|
};
|
|
93
|
-
|
|
94
63
|
for (const fieldName in fields) {
|
|
95
|
-
|
|
64
|
+
const {
|
|
65
|
+
type,
|
|
66
|
+
targetClass,
|
|
67
|
+
...fieldOptions
|
|
68
|
+
} = fields[fieldName];
|
|
69
|
+
mongoObject[fieldName] = _MongoSchemaCollection.default.parseFieldTypeToMongoFieldType({
|
|
70
|
+
type,
|
|
71
|
+
targetClass
|
|
72
|
+
});
|
|
73
|
+
if (fieldOptions && Object.keys(fieldOptions).length > 0) {
|
|
74
|
+
mongoObject._metadata = mongoObject._metadata || {};
|
|
75
|
+
mongoObject._metadata.fields_options = mongoObject._metadata.fields_options || {};
|
|
76
|
+
mongoObject._metadata.fields_options[fieldName] = fieldOptions;
|
|
77
|
+
}
|
|
96
78
|
}
|
|
97
|
-
|
|
98
79
|
if (typeof classLevelPermissions !== 'undefined') {
|
|
99
80
|
mongoObject._metadata = mongoObject._metadata || {};
|
|
100
81
|
if (!classLevelPermissions) {
|
|
@@ -103,39 +84,61 @@ const mongoSchemaFromFieldsAndClassNameAndCLP = (fields, className, classLevelPe
|
|
|
103
84
|
mongoObject._metadata.class_permissions = classLevelPermissions;
|
|
104
85
|
}
|
|
105
86
|
}
|
|
106
|
-
|
|
107
87
|
if (indexes && typeof indexes === 'object' && Object.keys(indexes).length > 0) {
|
|
108
88
|
mongoObject._metadata = mongoObject._metadata || {};
|
|
109
89
|
mongoObject._metadata.indexes = indexes;
|
|
110
90
|
}
|
|
111
|
-
|
|
112
91
|
if (!mongoObject._metadata) {
|
|
113
92
|
// cleanup the unused _metadata
|
|
114
93
|
delete mongoObject._metadata;
|
|
115
94
|
}
|
|
116
|
-
|
|
117
95
|
return mongoObject;
|
|
118
96
|
};
|
|
119
|
-
|
|
97
|
+
function validateExplainValue(explain) {
|
|
98
|
+
if (explain) {
|
|
99
|
+
// The list of allowed explain values is from node-mongodb-native/lib/explain.js
|
|
100
|
+
const explainAllowedValues = ['queryPlanner', 'queryPlannerExtended', 'executionStats', 'allPlansExecution', false, true];
|
|
101
|
+
if (!explainAllowedValues.includes(explain)) {
|
|
102
|
+
throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Invalid value for explain');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
120
106
|
class MongoStorageAdapter {
|
|
121
107
|
// Private
|
|
108
|
+
|
|
109
|
+
// Public
|
|
110
|
+
|
|
122
111
|
constructor({
|
|
123
|
-
uri =
|
|
112
|
+
uri = _defaults.default.DefaultMongoURI,
|
|
124
113
|
collectionPrefix = '',
|
|
125
114
|
mongoOptions = {}
|
|
126
115
|
}) {
|
|
127
116
|
this._uri = uri;
|
|
128
117
|
this._collectionPrefix = collectionPrefix;
|
|
129
|
-
this.
|
|
118
|
+
this._onchange = () => {};
|
|
130
119
|
|
|
131
120
|
// MaxTimeMS is not a global MongoDB client option, it is applied per operation.
|
|
132
121
|
this._maxTimeMS = mongoOptions.maxTimeMS;
|
|
133
122
|
this.canSortOnJoinTables = true;
|
|
134
|
-
|
|
123
|
+
this.enableSchemaHooks = !!mongoOptions.enableSchemaHooks;
|
|
124
|
+
this.schemaCacheTtl = mongoOptions.schemaCacheTtl;
|
|
125
|
+
this.disableIndexFieldValidation = !!mongoOptions.disableIndexFieldValidation;
|
|
126
|
+
this._logClientEvents = mongoOptions.logClientEvents;
|
|
127
|
+
|
|
128
|
+
// Create a copy of mongoOptions and remove Parse Server-specific options that should not
|
|
129
|
+
// be passed to MongoDB client. Note: We only delete from this._mongoOptions, not from the
|
|
130
|
+
// original mongoOptions object, because other components (like DatabaseController) need
|
|
131
|
+
// access to these options.
|
|
132
|
+
this._mongoOptions = {
|
|
133
|
+
...mongoOptions
|
|
134
|
+
};
|
|
135
|
+
for (const key of _defaults.ParseServerDatabaseOptions) {
|
|
136
|
+
delete this._mongoOptions[key];
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
watch(callback) {
|
|
140
|
+
this._onchange = callback;
|
|
135
141
|
}
|
|
136
|
-
// Public
|
|
137
|
-
|
|
138
|
-
|
|
139
142
|
connect() {
|
|
140
143
|
if (this.connectionPromise) {
|
|
141
144
|
return this.connectionPromise;
|
|
@@ -144,7 +147,6 @@ class MongoStorageAdapter {
|
|
|
144
147
|
// parsing and re-formatting causes the auth value (if there) to get URI
|
|
145
148
|
// encoded
|
|
146
149
|
const encodedUri = (0, _mongodbUrl.format)((0, _mongodbUrl.parse)(this._uri));
|
|
147
|
-
|
|
148
150
|
this.connectionPromise = MongoClient.connect(encodedUri, this._mongoOptions).then(client => {
|
|
149
151
|
// Starting mongoDB 3.0, the MongoClient.connect don't return a DB anymore but a client
|
|
150
152
|
// Fortunately, we can get back the options and use them to select the proper DB.
|
|
@@ -155,78 +157,110 @@ class MongoStorageAdapter {
|
|
|
155
157
|
delete this.connectionPromise;
|
|
156
158
|
return;
|
|
157
159
|
}
|
|
158
|
-
|
|
160
|
+
client.on('error', () => {
|
|
159
161
|
delete this.connectionPromise;
|
|
160
162
|
});
|
|
161
|
-
|
|
163
|
+
client.on('close', () => {
|
|
162
164
|
delete this.connectionPromise;
|
|
163
165
|
});
|
|
166
|
+
|
|
167
|
+
// Set up client event logging if configured
|
|
168
|
+
if (this._logClientEvents && Array.isArray(this._logClientEvents)) {
|
|
169
|
+
this._logClientEvents.forEach(eventConfig => {
|
|
170
|
+
client.on(eventConfig.name, event => {
|
|
171
|
+
let logData = {};
|
|
172
|
+
if (!eventConfig.keys || eventConfig.keys.length === 0) {
|
|
173
|
+
logData = event;
|
|
174
|
+
} else {
|
|
175
|
+
eventConfig.keys.forEach(keyPath => {
|
|
176
|
+
logData[keyPath] = _lodash.default.get(event, keyPath);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Validate log level exists, fallback to 'info'
|
|
181
|
+
const logLevel = typeof _logger.default[eventConfig.logLevel] === 'function' ? eventConfig.logLevel : 'info';
|
|
182
|
+
|
|
183
|
+
// Safe JSON serialization with Map/Set and circular reference support
|
|
184
|
+
const logMessage = `MongoDB client event ${eventConfig.name}: ${JSON.stringify(logData, _Utils.default.getCircularReplacer())}`;
|
|
185
|
+
_logger.default[logLevel](logMessage);
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
}
|
|
164
189
|
this.client = client;
|
|
165
190
|
this.database = database;
|
|
166
191
|
}).catch(err => {
|
|
167
192
|
delete this.connectionPromise;
|
|
168
193
|
return Promise.reject(err);
|
|
169
194
|
});
|
|
170
|
-
|
|
171
195
|
return this.connectionPromise;
|
|
172
196
|
}
|
|
173
|
-
|
|
174
197
|
handleError(error) {
|
|
175
198
|
if (error && error.code === 13) {
|
|
176
199
|
// Unauthorized error
|
|
177
200
|
delete this.client;
|
|
178
201
|
delete this.database;
|
|
179
202
|
delete this.connectionPromise;
|
|
180
|
-
|
|
203
|
+
_logger.default.error('Received unauthorized error', {
|
|
204
|
+
error: error
|
|
205
|
+
});
|
|
181
206
|
}
|
|
182
207
|
throw error;
|
|
183
208
|
}
|
|
184
|
-
|
|
185
|
-
handleShutdown() {
|
|
209
|
+
async handleShutdown() {
|
|
186
210
|
if (!this.client) {
|
|
187
211
|
return;
|
|
188
212
|
}
|
|
189
|
-
this.client.close(false);
|
|
213
|
+
await this.client.close(false);
|
|
214
|
+
delete this.connectionPromise;
|
|
190
215
|
}
|
|
191
|
-
|
|
192
216
|
_adaptiveCollection(name) {
|
|
193
|
-
return this.connect().then(() => this.database.collection(this._collectionPrefix + name)).then(rawCollection => new
|
|
217
|
+
return this.connect().then(() => this.database.collection(this._collectionPrefix + name)).then(rawCollection => new _MongoCollection.default(rawCollection)).catch(err => this.handleError(err));
|
|
194
218
|
}
|
|
195
|
-
|
|
196
219
|
_schemaCollection() {
|
|
197
|
-
return this.connect().then(() => this._adaptiveCollection(MongoSchemaCollectionName)).then(collection =>
|
|
220
|
+
return this.connect().then(() => this._adaptiveCollection(MongoSchemaCollectionName)).then(collection => {
|
|
221
|
+
if (!this._stream && this.enableSchemaHooks) {
|
|
222
|
+
this._stream = collection._mongoCollection.watch();
|
|
223
|
+
this._stream.on('change', () => this._onchange());
|
|
224
|
+
}
|
|
225
|
+
return new _MongoSchemaCollection.default(collection);
|
|
226
|
+
});
|
|
198
227
|
}
|
|
199
|
-
|
|
200
228
|
classExists(name) {
|
|
201
229
|
return this.connect().then(() => {
|
|
202
|
-
return this.database.listCollections({
|
|
230
|
+
return this.database.listCollections({
|
|
231
|
+
name: this._collectionPrefix + name
|
|
232
|
+
}).toArray();
|
|
203
233
|
}).then(collections => {
|
|
204
234
|
return collections.length > 0;
|
|
205
235
|
}).catch(err => this.handleError(err));
|
|
206
236
|
}
|
|
207
|
-
|
|
208
237
|
setClassLevelPermissions(className, CLPs) {
|
|
209
238
|
return this._schemaCollection().then(schemaCollection => schemaCollection.updateSchema(className, {
|
|
210
|
-
$set: {
|
|
239
|
+
$set: {
|
|
240
|
+
'_metadata.class_permissions': CLPs
|
|
241
|
+
}
|
|
211
242
|
})).catch(err => this.handleError(err));
|
|
212
243
|
}
|
|
213
|
-
|
|
214
244
|
setIndexesWithSchemaFormat(className, submittedIndexes, existingIndexes = {}, fields) {
|
|
215
245
|
if (submittedIndexes === undefined) {
|
|
216
246
|
return Promise.resolve();
|
|
217
247
|
}
|
|
218
248
|
if (Object.keys(existingIndexes).length === 0) {
|
|
219
|
-
existingIndexes = {
|
|
249
|
+
existingIndexes = {
|
|
250
|
+
_id_: {
|
|
251
|
+
_id: 1
|
|
252
|
+
}
|
|
253
|
+
};
|
|
220
254
|
}
|
|
221
255
|
const deletePromises = [];
|
|
222
256
|
const insertedIndexes = [];
|
|
223
257
|
Object.keys(submittedIndexes).forEach(name => {
|
|
224
258
|
const field = submittedIndexes[name];
|
|
225
259
|
if (existingIndexes[name] && field.__op !== 'Delete') {
|
|
226
|
-
throw new
|
|
260
|
+
throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Index ${name} exists, cannot update.`);
|
|
227
261
|
}
|
|
228
262
|
if (!existingIndexes[name] && field.__op === 'Delete') {
|
|
229
|
-
throw new
|
|
263
|
+
throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Index ${name} does not exist, cannot delete.`);
|
|
230
264
|
}
|
|
231
265
|
if (field.__op === 'Delete') {
|
|
232
266
|
const promise = this.dropIndex(className, name);
|
|
@@ -234,8 +268,8 @@ class MongoStorageAdapter {
|
|
|
234
268
|
delete existingIndexes[name];
|
|
235
269
|
} else {
|
|
236
270
|
Object.keys(field).forEach(key => {
|
|
237
|
-
if (!
|
|
238
|
-
throw new
|
|
271
|
+
if (!this.disableIndexFieldValidation && !Object.prototype.hasOwnProperty.call(fields, key.indexOf('_p_') === 0 ? key.replace('_p_', '') : key)) {
|
|
272
|
+
throw new _node.default.Error(_node.default.Error.INVALID_QUERY, `Field ${key} does not exist, cannot add index.`);
|
|
239
273
|
}
|
|
240
274
|
});
|
|
241
275
|
existingIndexes[name] = field;
|
|
@@ -250,10 +284,11 @@ class MongoStorageAdapter {
|
|
|
250
284
|
insertPromise = this.createIndexes(className, insertedIndexes);
|
|
251
285
|
}
|
|
252
286
|
return Promise.all(deletePromises).then(() => insertPromise).then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.updateSchema(className, {
|
|
253
|
-
$set: {
|
|
287
|
+
$set: {
|
|
288
|
+
'_metadata.indexes': existingIndexes
|
|
289
|
+
}
|
|
254
290
|
})).catch(err => this.handleError(err));
|
|
255
291
|
}
|
|
256
|
-
|
|
257
292
|
setIndexesFromMongo(className) {
|
|
258
293
|
return this.getIndexes(className).then(indexes => {
|
|
259
294
|
indexes = indexes.reduce((obj, index) => {
|
|
@@ -268,21 +303,25 @@ class MongoStorageAdapter {
|
|
|
268
303
|
return obj;
|
|
269
304
|
}, {});
|
|
270
305
|
return this._schemaCollection().then(schemaCollection => schemaCollection.updateSchema(className, {
|
|
271
|
-
$set: {
|
|
306
|
+
$set: {
|
|
307
|
+
'_metadata.indexes': indexes
|
|
308
|
+
}
|
|
272
309
|
}));
|
|
273
310
|
}).catch(err => this.handleError(err)).catch(() => {
|
|
274
311
|
// Ignore if collection not found
|
|
275
312
|
return Promise.resolve();
|
|
276
313
|
});
|
|
277
314
|
}
|
|
278
|
-
|
|
279
315
|
createClass(className, schema) {
|
|
280
316
|
schema = convertParseSchemaToMongoSchema(schema);
|
|
281
317
|
const mongoObject = mongoSchemaFromFieldsAndClassNameAndCLP(schema.fields, className, schema.classLevelPermissions, schema.indexes);
|
|
282
318
|
mongoObject._id = className;
|
|
283
319
|
return this.setIndexesWithSchemaFormat(className, schema.indexes, {}, schema.fields).then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.insertSchema(mongoObject)).catch(err => this.handleError(err));
|
|
284
320
|
}
|
|
285
|
-
|
|
321
|
+
async updateFieldOptions(className, fieldName, type) {
|
|
322
|
+
const schemaCollection = await this._schemaCollection();
|
|
323
|
+
await schemaCollection.updateFieldOptions(className, fieldName, type);
|
|
324
|
+
}
|
|
286
325
|
addFieldIfNotExists(className, fieldName, type) {
|
|
287
326
|
return this._schemaCollection().then(schemaCollection => schemaCollection.addFieldIfNotExists(className, fieldName, type)).then(() => this.createIndexesIfNeeded(className, fieldName, type)).catch(err => this.handleError(err));
|
|
288
327
|
}
|
|
@@ -300,9 +339,8 @@ class MongoStorageAdapter {
|
|
|
300
339
|
// We've dropped the collection, now remove the _SCHEMA document
|
|
301
340
|
.then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.findAndDeleteSchema(className)).catch(err => this.handleError(err));
|
|
302
341
|
}
|
|
303
|
-
|
|
304
342
|
deleteAllClasses(fast) {
|
|
305
|
-
return storageAdapterAllCollections(this).then(collections => Promise.all(collections.map(collection => fast ? collection.
|
|
343
|
+
return storageAdapterAllCollections(this).then(collections => Promise.all(collections.map(collection => fast ? collection.deleteMany({}) : collection.drop())));
|
|
306
344
|
}
|
|
307
345
|
|
|
308
346
|
// Remove the column and all the data. For Relations, the _Join collection is handled
|
|
@@ -333,17 +371,30 @@ class MongoStorageAdapter {
|
|
|
333
371
|
return fieldName;
|
|
334
372
|
}
|
|
335
373
|
});
|
|
336
|
-
const collectionUpdate = {
|
|
374
|
+
const collectionUpdate = {
|
|
375
|
+
$unset: {}
|
|
376
|
+
};
|
|
337
377
|
mongoFormatNames.forEach(name => {
|
|
338
378
|
collectionUpdate['$unset'][name] = null;
|
|
339
379
|
});
|
|
340
|
-
|
|
341
|
-
|
|
380
|
+
const collectionFilter = {
|
|
381
|
+
$or: []
|
|
382
|
+
};
|
|
383
|
+
mongoFormatNames.forEach(name => {
|
|
384
|
+
collectionFilter['$or'].push({
|
|
385
|
+
[name]: {
|
|
386
|
+
$exists: true
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
});
|
|
390
|
+
const schemaUpdate = {
|
|
391
|
+
$unset: {}
|
|
392
|
+
};
|
|
342
393
|
fieldNames.forEach(name => {
|
|
343
394
|
schemaUpdate['$unset'][name] = null;
|
|
395
|
+
schemaUpdate['$unset'][`_metadata.fields_options.${name}`] = null;
|
|
344
396
|
});
|
|
345
|
-
|
|
346
|
-
return this._adaptiveCollection(className).then(collection => collection.updateMany({}, collectionUpdate)).then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.updateSchema(className, schemaUpdate)).catch(err => this.handleError(err));
|
|
397
|
+
return this._adaptiveCollection(className).then(collection => collection.updateMany(collectionFilter, collectionUpdate)).then(() => this._schemaCollection()).then(schemaCollection => schemaCollection.updateSchema(className, schemaUpdate)).catch(err => this.handleError(err));
|
|
347
398
|
}
|
|
348
399
|
|
|
349
400
|
// Return a promise for all schemas known to this adapter, in Parse format. In case the
|
|
@@ -363,18 +414,22 @@ class MongoStorageAdapter {
|
|
|
363
414
|
// TODO: As yet not particularly well specified. Creates an object. Maybe shouldn't even need the schema,
|
|
364
415
|
// and should infer from the type. Or maybe does need the schema for validations. Or maybe needs
|
|
365
416
|
// the schema only for the legacy mongo format. We'll figure that out later.
|
|
366
|
-
createObject(className, schema, object) {
|
|
417
|
+
createObject(className, schema, object, transactionalSession) {
|
|
367
418
|
schema = convertParseSchemaToMongoSchema(schema);
|
|
368
419
|
const mongoObject = (0, _MongoTransform.parseObjectToMongoObjectForCreate)(className, object, schema);
|
|
369
|
-
return this._adaptiveCollection(className).then(collection => collection.insertOne(mongoObject)).
|
|
420
|
+
return this._adaptiveCollection(className).then(collection => collection.insertOne(mongoObject, transactionalSession)).then(() => ({
|
|
421
|
+
ops: [mongoObject]
|
|
422
|
+
})).catch(error => {
|
|
370
423
|
if (error.code === 11000) {
|
|
371
424
|
// Duplicate value
|
|
372
|
-
const err = new
|
|
425
|
+
const err = new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided');
|
|
373
426
|
err.underlyingError = error;
|
|
374
427
|
if (error.message) {
|
|
375
428
|
const matches = error.message.match(/index:[\sa-zA-Z0-9_\-\.]+\$?([a-zA-Z_-]+)_1/);
|
|
376
429
|
if (matches && Array.isArray(matches)) {
|
|
377
|
-
err.userInfo = {
|
|
430
|
+
err.userInfo = {
|
|
431
|
+
duplicated_field: matches[1]
|
|
432
|
+
};
|
|
378
433
|
}
|
|
379
434
|
}
|
|
380
435
|
throw err;
|
|
@@ -386,61 +441,88 @@ class MongoStorageAdapter {
|
|
|
386
441
|
// Remove all objects that match the given Parse Query.
|
|
387
442
|
// If no objects match, reject with OBJECT_NOT_FOUND. If objects are found and deleted, resolve with undefined.
|
|
388
443
|
// If there is some other error, reject with INTERNAL_SERVER_ERROR.
|
|
389
|
-
deleteObjectsByQuery(className, schema, query) {
|
|
444
|
+
deleteObjectsByQuery(className, schema, query, transactionalSession) {
|
|
390
445
|
schema = convertParseSchemaToMongoSchema(schema);
|
|
391
446
|
return this._adaptiveCollection(className).then(collection => {
|
|
392
447
|
const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema);
|
|
393
|
-
return collection.deleteMany(mongoWhere);
|
|
394
|
-
}).catch(err => this.handleError(err)).then(({
|
|
395
|
-
|
|
396
|
-
|
|
448
|
+
return collection.deleteMany(mongoWhere, transactionalSession);
|
|
449
|
+
}).catch(err => this.handleError(err)).then(({
|
|
450
|
+
deletedCount
|
|
451
|
+
}) => {
|
|
452
|
+
if (deletedCount === 0) {
|
|
453
|
+
throw new _node.default.Error(_node.default.Error.OBJECT_NOT_FOUND, 'Object not found.');
|
|
397
454
|
}
|
|
398
455
|
return Promise.resolve();
|
|
399
456
|
}, () => {
|
|
400
|
-
throw new
|
|
457
|
+
throw new _node.default.Error(_node.default.Error.INTERNAL_SERVER_ERROR, 'Database adapter error');
|
|
401
458
|
});
|
|
402
459
|
}
|
|
403
460
|
|
|
404
461
|
// Apply the update to all objects that match the given Parse Query.
|
|
405
|
-
updateObjectsByQuery(className, schema, query, update) {
|
|
462
|
+
updateObjectsByQuery(className, schema, query, update, transactionalSession) {
|
|
406
463
|
schema = convertParseSchemaToMongoSchema(schema);
|
|
407
464
|
const mongoUpdate = (0, _MongoTransform.transformUpdate)(className, update, schema);
|
|
408
465
|
const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema);
|
|
409
|
-
return this._adaptiveCollection(className).then(collection => collection.updateMany(mongoWhere, mongoUpdate)).catch(err => this.handleError(err));
|
|
466
|
+
return this._adaptiveCollection(className).then(collection => collection.updateMany(mongoWhere, mongoUpdate, transactionalSession)).catch(err => this.handleError(err));
|
|
410
467
|
}
|
|
411
468
|
|
|
412
469
|
// Atomically finds and updates an object based on query.
|
|
413
470
|
// Return value not currently well specified.
|
|
414
|
-
findOneAndUpdate(className, schema, query, update) {
|
|
471
|
+
findOneAndUpdate(className, schema, query, update, transactionalSession) {
|
|
415
472
|
schema = convertParseSchemaToMongoSchema(schema);
|
|
416
473
|
const mongoUpdate = (0, _MongoTransform.transformUpdate)(className, update, schema);
|
|
417
474
|
const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema);
|
|
418
|
-
return this._adaptiveCollection(className).then(collection => collection._mongoCollection.
|
|
475
|
+
return this._adaptiveCollection(className).then(collection => collection._mongoCollection.findOneAndUpdate(mongoWhere, mongoUpdate, {
|
|
476
|
+
returnDocument: 'after',
|
|
477
|
+
session: transactionalSession || undefined
|
|
478
|
+
})).then(result => (0, _MongoTransform.mongoObjectToParseObject)(className, result, schema)).catch(error => {
|
|
419
479
|
if (error.code === 11000) {
|
|
420
|
-
throw new
|
|
480
|
+
throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'A duplicate value for a field with unique values was provided');
|
|
421
481
|
}
|
|
422
482
|
throw error;
|
|
423
483
|
}).catch(err => this.handleError(err));
|
|
424
484
|
}
|
|
425
485
|
|
|
426
486
|
// Hopefully we can get rid of this. It's only used for config and hooks.
|
|
427
|
-
upsertOneObject(className, schema, query, update) {
|
|
487
|
+
upsertOneObject(className, schema, query, update, transactionalSession) {
|
|
428
488
|
schema = convertParseSchemaToMongoSchema(schema);
|
|
429
489
|
const mongoUpdate = (0, _MongoTransform.transformUpdate)(className, update, schema);
|
|
430
490
|
const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema);
|
|
431
|
-
return this._adaptiveCollection(className).then(collection => collection.upsertOne(mongoWhere, mongoUpdate)).catch(err => this.handleError(err));
|
|
491
|
+
return this._adaptiveCollection(className).then(collection => collection.upsertOne(mongoWhere, mongoUpdate, transactionalSession)).catch(err => this.handleError(err));
|
|
432
492
|
}
|
|
433
493
|
|
|
434
494
|
// Executes a find. Accepts: className, query in Parse format, and { skip, limit, sort }.
|
|
435
|
-
find(className, schema, query, {
|
|
495
|
+
find(className, schema, query, {
|
|
496
|
+
skip,
|
|
497
|
+
limit,
|
|
498
|
+
sort,
|
|
499
|
+
keys,
|
|
500
|
+
readPreference,
|
|
501
|
+
hint,
|
|
502
|
+
caseInsensitive,
|
|
503
|
+
explain,
|
|
504
|
+
comment
|
|
505
|
+
}) {
|
|
506
|
+
validateExplainValue(explain);
|
|
436
507
|
schema = convertParseSchemaToMongoSchema(schema);
|
|
437
508
|
const mongoWhere = (0, _MongoTransform.transformWhere)(className, query, schema);
|
|
438
|
-
const mongoSort =
|
|
439
|
-
const mongoKeys =
|
|
440
|
-
|
|
509
|
+
const mongoSort = _lodash.default.mapKeys(sort, (value, fieldName) => (0, _MongoTransform.transformKey)(className, fieldName, schema));
|
|
510
|
+
const mongoKeys = _lodash.default.reduce(keys, (memo, key) => {
|
|
511
|
+
if (key === 'ACL') {
|
|
512
|
+
memo['_rperm'] = 1;
|
|
513
|
+
memo['_wperm'] = 1;
|
|
514
|
+
} else {
|
|
515
|
+
memo[(0, _MongoTransform.transformKey)(className, key, schema)] = 1;
|
|
516
|
+
}
|
|
441
517
|
return memo;
|
|
442
518
|
}, {});
|
|
443
519
|
|
|
520
|
+
// If we aren't requesting the `_id` field, we need to explicitly opt out
|
|
521
|
+
// of it. Doing so in parse-server is unusual, but it can allow us to
|
|
522
|
+
// optimize some queries with covering indexes.
|
|
523
|
+
if (keys && !mongoKeys._id) {
|
|
524
|
+
mongoKeys._id = 0;
|
|
525
|
+
}
|
|
444
526
|
readPreference = this._parseReadPreference(readPreference);
|
|
445
527
|
return this.createTextIndexesIfNeeded(className, query, schema).then(() => this._adaptiveCollection(className)).then(collection => collection.find(mongoWhere, {
|
|
446
528
|
skip,
|
|
@@ -448,8 +530,49 @@ class MongoStorageAdapter {
|
|
|
448
530
|
sort: mongoSort,
|
|
449
531
|
keys: mongoKeys,
|
|
450
532
|
maxTimeMS: this._maxTimeMS,
|
|
451
|
-
readPreference
|
|
452
|
-
|
|
533
|
+
readPreference,
|
|
534
|
+
hint,
|
|
535
|
+
caseInsensitive,
|
|
536
|
+
explain,
|
|
537
|
+
comment
|
|
538
|
+
})).then(objects => {
|
|
539
|
+
if (explain) {
|
|
540
|
+
return objects;
|
|
541
|
+
}
|
|
542
|
+
return objects.map(object => (0, _MongoTransform.mongoObjectToParseObject)(className, object, schema));
|
|
543
|
+
}).catch(err => this.handleError(err));
|
|
544
|
+
}
|
|
545
|
+
ensureIndex(className, schema, fieldNames, indexName, caseInsensitive = false, options = {}) {
|
|
546
|
+
schema = convertParseSchemaToMongoSchema(schema);
|
|
547
|
+
const indexCreationRequest = {};
|
|
548
|
+
const mongoFieldNames = fieldNames.map(fieldName => (0, _MongoTransform.transformKey)(className, fieldName, schema));
|
|
549
|
+
mongoFieldNames.forEach(fieldName => {
|
|
550
|
+
indexCreationRequest[fieldName] = options.indexType !== undefined ? options.indexType : 1;
|
|
551
|
+
});
|
|
552
|
+
const defaultOptions = {
|
|
553
|
+
background: true,
|
|
554
|
+
sparse: true
|
|
555
|
+
};
|
|
556
|
+
const indexNameOptions = indexName ? {
|
|
557
|
+
name: indexName
|
|
558
|
+
} : {};
|
|
559
|
+
const ttlOptions = options.ttl !== undefined ? {
|
|
560
|
+
expireAfterSeconds: options.ttl
|
|
561
|
+
} : {};
|
|
562
|
+
const sparseOptions = options.sparse !== undefined ? {
|
|
563
|
+
sparse: options.sparse
|
|
564
|
+
} : {};
|
|
565
|
+
const caseInsensitiveOptions = caseInsensitive ? {
|
|
566
|
+
collation: _MongoCollection.default.caseInsensitiveCollation()
|
|
567
|
+
} : {};
|
|
568
|
+
const indexOptions = {
|
|
569
|
+
...defaultOptions,
|
|
570
|
+
...caseInsensitiveOptions,
|
|
571
|
+
...indexNameOptions,
|
|
572
|
+
...ttlOptions,
|
|
573
|
+
...sparseOptions
|
|
574
|
+
};
|
|
575
|
+
return this._adaptiveCollection(className).then(collection => collection._mongoCollection.createIndex(indexCreationRequest, indexOptions)).catch(err => this.handleError(err));
|
|
453
576
|
}
|
|
454
577
|
|
|
455
578
|
// Create a unique index. Unique indexes on nullable fields are not allowed. Since we don't
|
|
@@ -466,7 +589,7 @@ class MongoStorageAdapter {
|
|
|
466
589
|
});
|
|
467
590
|
return this._adaptiveCollection(className).then(collection => collection._ensureSparseUniqueIndexInBackground(indexCreationRequest)).catch(error => {
|
|
468
591
|
if (error.code === 11000) {
|
|
469
|
-
throw new
|
|
592
|
+
throw new _node.default.Error(_node.default.Error.DUPLICATE_VALUE, 'Tried to ensure field uniqueness for a class that already has duplicates.');
|
|
470
593
|
}
|
|
471
594
|
throw error;
|
|
472
595
|
}).catch(err => this.handleError(err));
|
|
@@ -480,34 +603,32 @@ class MongoStorageAdapter {
|
|
|
480
603
|
}
|
|
481
604
|
|
|
482
605
|
// Executes a count.
|
|
483
|
-
count(className, schema, query, readPreference) {
|
|
606
|
+
count(className, schema, query, readPreference, _estimate, hint, comment) {
|
|
484
607
|
schema = convertParseSchemaToMongoSchema(schema);
|
|
485
608
|
readPreference = this._parseReadPreference(readPreference);
|
|
486
|
-
return this._adaptiveCollection(className).then(collection => collection.count((0, _MongoTransform.transformWhere)(className, query, schema), {
|
|
609
|
+
return this._adaptiveCollection(className).then(collection => collection.count((0, _MongoTransform.transformWhere)(className, query, schema, true), {
|
|
487
610
|
maxTimeMS: this._maxTimeMS,
|
|
488
|
-
readPreference
|
|
611
|
+
readPreference,
|
|
612
|
+
hint,
|
|
613
|
+
comment
|
|
489
614
|
})).catch(err => this.handleError(err));
|
|
490
615
|
}
|
|
491
|
-
|
|
492
616
|
distinct(className, schema, query, fieldName) {
|
|
493
617
|
schema = convertParseSchemaToMongoSchema(schema);
|
|
494
618
|
const isPointerField = schema.fields[fieldName] && schema.fields[fieldName].type === 'Pointer';
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
}
|
|
498
|
-
return this._adaptiveCollection(className).then(collection => collection.distinct(fieldName, (0, _MongoTransform.transformWhere)(className, query, schema))).then(objects => {
|
|
619
|
+
const transformField = (0, _MongoTransform.transformKey)(className, fieldName, schema);
|
|
620
|
+
return this._adaptiveCollection(className).then(collection => collection.distinct(transformField, (0, _MongoTransform.transformWhere)(className, query, schema))).then(objects => {
|
|
499
621
|
objects = objects.filter(obj => obj != null);
|
|
500
622
|
return objects.map(object => {
|
|
501
623
|
if (isPointerField) {
|
|
502
|
-
|
|
503
|
-
return (0, _MongoTransform.transformPointerString)(schema, field, object);
|
|
624
|
+
return (0, _MongoTransform.transformPointerString)(schema, fieldName, object);
|
|
504
625
|
}
|
|
505
626
|
return (0, _MongoTransform.mongoObjectToParseObject)(className, object, schema);
|
|
506
627
|
});
|
|
507
628
|
}).catch(err => this.handleError(err));
|
|
508
629
|
}
|
|
509
|
-
|
|
510
|
-
|
|
630
|
+
aggregate(className, schema, pipeline, readPreference, hint, explain, comment) {
|
|
631
|
+
validateExplainValue(explain);
|
|
511
632
|
let isPointerField = false;
|
|
512
633
|
pipeline = pipeline.map(stage => {
|
|
513
634
|
if (stage.$group) {
|
|
@@ -522,21 +643,25 @@ class MongoStorageAdapter {
|
|
|
522
643
|
if (stage.$project) {
|
|
523
644
|
stage.$project = this._parseAggregateProjectArgs(schema, stage.$project);
|
|
524
645
|
}
|
|
646
|
+
if (stage.$geoNear && stage.$geoNear.query) {
|
|
647
|
+
stage.$geoNear.query = this._parseAggregateArgs(schema, stage.$geoNear.query);
|
|
648
|
+
}
|
|
525
649
|
return stage;
|
|
526
650
|
});
|
|
527
651
|
readPreference = this._parseReadPreference(readPreference);
|
|
528
|
-
return this._adaptiveCollection(className).then(collection => collection.aggregate(pipeline, {
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
652
|
+
return this._adaptiveCollection(className).then(collection => collection.aggregate(pipeline, {
|
|
653
|
+
readPreference,
|
|
654
|
+
maxTimeMS: this._maxTimeMS,
|
|
655
|
+
hint,
|
|
656
|
+
explain,
|
|
657
|
+
comment
|
|
658
|
+
})).then(results => {
|
|
534
659
|
results.forEach(result => {
|
|
535
|
-
if (
|
|
660
|
+
if (Object.prototype.hasOwnProperty.call(result, '_id')) {
|
|
536
661
|
if (isPointerField && result._id) {
|
|
537
662
|
result._id = result._id.split('$')[1];
|
|
538
663
|
}
|
|
539
|
-
if (result._id == null ||
|
|
664
|
+
if (result._id == null || result._id == undefined || ['object', 'string'].includes(typeof result._id) && _lodash.default.isEmpty(result._id)) {
|
|
540
665
|
result._id = null;
|
|
541
666
|
}
|
|
542
667
|
result.objectId = result._id;
|
|
@@ -567,7 +692,9 @@ class MongoStorageAdapter {
|
|
|
567
692
|
// As much as I hate recursion...this seemed like a good fit for it. We're essentially traversing
|
|
568
693
|
// down a tree to find a "leaf node" and checking to see if it needs to be converted.
|
|
569
694
|
_parseAggregateArgs(schema, pipeline) {
|
|
570
|
-
if (
|
|
695
|
+
if (pipeline === null) {
|
|
696
|
+
return null;
|
|
697
|
+
} else if (Array.isArray(pipeline)) {
|
|
571
698
|
return pipeline.map(value => this._parseAggregateArgs(schema, value));
|
|
572
699
|
} else if (typeof pipeline === 'object') {
|
|
573
700
|
const returnValue = {};
|
|
@@ -584,7 +711,6 @@ class MongoStorageAdapter {
|
|
|
584
711
|
} else {
|
|
585
712
|
returnValue[field] = this._parseAggregateArgs(schema, pipeline[field]);
|
|
586
713
|
}
|
|
587
|
-
|
|
588
714
|
if (field === 'objectId') {
|
|
589
715
|
returnValue['_id'] = returnValue[field];
|
|
590
716
|
delete returnValue[field];
|
|
@@ -613,7 +739,6 @@ class MongoStorageAdapter {
|
|
|
613
739
|
} else {
|
|
614
740
|
returnValue[field] = this._parseAggregateArgs(schema, pipeline[field]);
|
|
615
741
|
}
|
|
616
|
-
|
|
617
742
|
if (field === 'objectId') {
|
|
618
743
|
returnValue['_id'] = returnValue[field];
|
|
619
744
|
delete returnValue[field];
|
|
@@ -655,23 +780,33 @@ class MongoStorageAdapter {
|
|
|
655
780
|
return pipeline;
|
|
656
781
|
}
|
|
657
782
|
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
783
|
+
/**
|
|
784
|
+
* Recursively converts values to Date objects. Since the passed object is part of an aggregation
|
|
785
|
+
* pipeline and can contain various logic operators (like $gt, $lt, etc), this function will
|
|
786
|
+
* traverse the object and convert any strings that can be parsed as dates into Date objects.
|
|
787
|
+
* @param {any} value The value to convert.
|
|
788
|
+
* @returns {any} The original value if not convertible to Date, or a Date object if it is.
|
|
789
|
+
*/
|
|
662
790
|
_convertToDate(value) {
|
|
791
|
+
if (value instanceof Date) {
|
|
792
|
+
return value;
|
|
793
|
+
}
|
|
663
794
|
if (typeof value === 'string') {
|
|
664
|
-
return new Date(value);
|
|
795
|
+
return isNaN(Date.parse(value)) ? value : new Date(value);
|
|
665
796
|
}
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
797
|
+
if (typeof value === 'object') {
|
|
798
|
+
const returnValue = {};
|
|
799
|
+
for (const field in value) {
|
|
800
|
+
returnValue[field] = this._convertToDate(value[field]);
|
|
801
|
+
}
|
|
802
|
+
return returnValue;
|
|
670
803
|
}
|
|
671
|
-
return
|
|
804
|
+
return value;
|
|
672
805
|
}
|
|
673
|
-
|
|
674
806
|
_parseReadPreference(readPreference) {
|
|
807
|
+
if (readPreference) {
|
|
808
|
+
readPreference = readPreference.toUpperCase();
|
|
809
|
+
}
|
|
675
810
|
switch (readPreference) {
|
|
676
811
|
case 'PRIMARY':
|
|
677
812
|
readPreference = ReadPreference.PRIMARY;
|
|
@@ -689,25 +824,23 @@ class MongoStorageAdapter {
|
|
|
689
824
|
readPreference = ReadPreference.NEAREST;
|
|
690
825
|
break;
|
|
691
826
|
case undefined:
|
|
827
|
+
case null:
|
|
828
|
+
case '':
|
|
692
829
|
break;
|
|
693
830
|
default:
|
|
694
|
-
throw new
|
|
831
|
+
throw new _node.default.Error(_node.default.Error.INVALID_QUERY, 'Not supported read preference.');
|
|
695
832
|
}
|
|
696
833
|
return readPreference;
|
|
697
834
|
}
|
|
698
|
-
|
|
699
835
|
performInitialization() {
|
|
700
836
|
return Promise.resolve();
|
|
701
837
|
}
|
|
702
|
-
|
|
703
838
|
createIndex(className, index) {
|
|
704
839
|
return this._adaptiveCollection(className).then(collection => collection._mongoCollection.createIndex(index)).catch(err => this.handleError(err));
|
|
705
840
|
}
|
|
706
|
-
|
|
707
841
|
createIndexes(className, indexes) {
|
|
708
842
|
return this._adaptiveCollection(className).then(collection => collection._mongoCollection.createIndexes(indexes)).catch(err => this.handleError(err));
|
|
709
843
|
}
|
|
710
|
-
|
|
711
844
|
createIndexesIfNeeded(className, fieldName, type) {
|
|
712
845
|
if (type && type.type === 'Polygon') {
|
|
713
846
|
const index = {
|
|
@@ -717,7 +850,6 @@ class MongoStorageAdapter {
|
|
|
717
850
|
}
|
|
718
851
|
return Promise.resolve();
|
|
719
852
|
}
|
|
720
|
-
|
|
721
853
|
createTextIndexesIfNeeded(className, query, schema) {
|
|
722
854
|
for (const fieldName in query) {
|
|
723
855
|
if (!query[fieldName] || !query[fieldName].$text) {
|
|
@@ -726,13 +858,15 @@ class MongoStorageAdapter {
|
|
|
726
858
|
const existingIndexes = schema.indexes;
|
|
727
859
|
for (const key in existingIndexes) {
|
|
728
860
|
const index = existingIndexes[key];
|
|
729
|
-
if (
|
|
861
|
+
if (Object.prototype.hasOwnProperty.call(index, fieldName)) {
|
|
730
862
|
return Promise.resolve();
|
|
731
863
|
}
|
|
732
864
|
}
|
|
733
865
|
const indexName = `${fieldName}_text`;
|
|
734
866
|
const textIndex = {
|
|
735
|
-
[indexName]: {
|
|
867
|
+
[indexName]: {
|
|
868
|
+
[fieldName]: 'text'
|
|
869
|
+
}
|
|
736
870
|
};
|
|
737
871
|
return this.setIndexesWithSchemaFormat(className, textIndex, existingIndexes, schema.fields).catch(error => {
|
|
738
872
|
if (error.code === 85) {
|
|
@@ -744,19 +878,15 @@ class MongoStorageAdapter {
|
|
|
744
878
|
}
|
|
745
879
|
return Promise.resolve();
|
|
746
880
|
}
|
|
747
|
-
|
|
748
881
|
getIndexes(className) {
|
|
749
882
|
return this._adaptiveCollection(className).then(collection => collection._mongoCollection.indexes()).catch(err => this.handleError(err));
|
|
750
883
|
}
|
|
751
|
-
|
|
752
884
|
dropIndex(className, index) {
|
|
753
885
|
return this._adaptiveCollection(className).then(collection => collection._mongoCollection.dropIndex(index)).catch(err => this.handleError(err));
|
|
754
886
|
}
|
|
755
|
-
|
|
756
887
|
dropAllIndexes(className) {
|
|
757
888
|
return this._adaptiveCollection(className).then(collection => collection._mongoCollection.dropIndexes()).catch(err => this.handleError(err));
|
|
758
889
|
}
|
|
759
|
-
|
|
760
890
|
updateSchemaWithIndexes() {
|
|
761
891
|
return this.getAllClasses().then(classes => {
|
|
762
892
|
const promises = classes.map(schema => {
|
|
@@ -765,8 +895,30 @@ class MongoStorageAdapter {
|
|
|
765
895
|
return Promise.all(promises);
|
|
766
896
|
}).catch(err => this.handleError(err));
|
|
767
897
|
}
|
|
898
|
+
createTransactionalSession() {
|
|
899
|
+
const transactionalSection = this.client.startSession();
|
|
900
|
+
transactionalSection.startTransaction();
|
|
901
|
+
return Promise.resolve(transactionalSection);
|
|
902
|
+
}
|
|
903
|
+
commitTransactionalSession(transactionalSection) {
|
|
904
|
+
const commit = retries => {
|
|
905
|
+
return transactionalSection.commitTransaction().catch(error => {
|
|
906
|
+
if (error && error.hasErrorLabel('TransientTransactionError') && retries > 0) {
|
|
907
|
+
return commit(retries - 1);
|
|
908
|
+
}
|
|
909
|
+
throw error;
|
|
910
|
+
}).then(() => {
|
|
911
|
+
transactionalSection.endSession();
|
|
912
|
+
});
|
|
913
|
+
};
|
|
914
|
+
return commit(5);
|
|
915
|
+
}
|
|
916
|
+
abortTransactionalSession(transactionalSection) {
|
|
917
|
+
return transactionalSection.abortTransaction().then(() => {
|
|
918
|
+
transactionalSection.endSession();
|
|
919
|
+
});
|
|
920
|
+
}
|
|
768
921
|
}
|
|
769
|
-
|
|
770
922
|
exports.MongoStorageAdapter = MongoStorageAdapter;
|
|
771
|
-
exports.default = MongoStorageAdapter;
|
|
772
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvU3RvcmFnZUFkYXB0ZXIuanMiXSwibmFtZXMiOlsibW9uZ29kYiIsInJlcXVpcmUiLCJNb25nb0NsaWVudCIsIlJlYWRQcmVmZXJlbmNlIiwiTW9uZ29TY2hlbWFDb2xsZWN0aW9uTmFtZSIsInN0b3JhZ2VBZGFwdGVyQWxsQ29sbGVjdGlvbnMiLCJtb25nb0FkYXB0ZXIiLCJjb25uZWN0IiwidGhlbiIsImRhdGFiYXNlIiwiY29sbGVjdGlvbnMiLCJmaWx0ZXIiLCJjb2xsZWN0aW9uIiwibmFtZXNwYWNlIiwibWF0Y2giLCJjb2xsZWN0aW9uTmFtZSIsImluZGV4T2YiLCJfY29sbGVjdGlvblByZWZpeCIsImNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEiLCJzY2hlbWEiLCJmaWVsZHMiLCJfcnBlcm0iLCJfd3Blcm0iLCJjbGFzc05hbWUiLCJfaGFzaGVkX3Bhc3N3b3JkIiwibW9uZ29TY2hlbWFGcm9tRmllbGRzQW5kQ2xhc3NOYW1lQW5kQ0xQIiwiY2xhc3NMZXZlbFBlcm1pc3Npb25zIiwiaW5kZXhlcyIsIm1vbmdvT2JqZWN0IiwiX2lkIiwib2JqZWN0SWQiLCJ1cGRhdGVkQXQiLCJjcmVhdGVkQXQiLCJfbWV0YWRhdGEiLCJ1bmRlZmluZWQiLCJmaWVsZE5hbWUiLCJNb25nb1NjaGVtYUNvbGxlY3Rpb24iLCJwYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUiLCJjbGFzc19wZXJtaXNzaW9ucyIsIk9iamVjdCIsImtleXMiLCJsZW5ndGgiLCJNb25nb1N0b3JhZ2VBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJ1cmkiLCJkZWZhdWx0cyIsIkRlZmF1bHRNb25nb1VSSSIsImNvbGxlY3Rpb25QcmVmaXgiLCJtb25nb09wdGlvbnMiLCJfdXJpIiwiX21vbmdvT3B0aW9ucyIsIl9tYXhUaW1lTVMiLCJtYXhUaW1lTVMiLCJjYW5Tb3J0T25Kb2luVGFibGVzIiwiY29ubmVjdGlvblByb21pc2UiLCJlbmNvZGVkVXJpIiwiY2xpZW50Iiwib3B0aW9ucyIsInMiLCJkYiIsImRiTmFtZSIsIm9uIiwiY2F0Y2giLCJlcnIiLCJQcm9taXNlIiwicmVqZWN0IiwiaGFuZGxlRXJyb3IiLCJlcnJvciIsImNvZGUiLCJsb2dnZXIiLCJoYW5kbGVTaHV0ZG93biIsImNsb3NlIiwiX2FkYXB0aXZlQ29sbGVjdGlvbiIsIm5hbWUiLCJyYXdDb2xsZWN0aW9uIiwiTW9uZ29Db2xsZWN0aW9uIiwiX3NjaGVtYUNvbGxlY3Rpb24iLCJjbGFzc0V4aXN0cyIsImxpc3RDb2xsZWN0aW9ucyIsInRvQXJyYXkiLCJzZXRDbGFzc0xldmVsUGVybWlzc2lvbnMiLCJDTFBzIiwic2NoZW1hQ29sbGVjdGlvbiIsInVwZGF0ZVNjaGVtYSIsIiRzZXQiLCJzZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdCIsInN1Ym1pdHRlZEluZGV4ZXMiLCJleGlzdGluZ0luZGV4ZXMiLCJyZXNvbHZlIiwiX2lkXyIsImRlbGV0ZVByb21pc2VzIiwiaW5zZXJ0ZWRJbmRleGVzIiwiZm9yRWFjaCIsImZpZWxkIiwiX19vcCIsIlBhcnNlIiwiRXJyb3IiLCJJTlZBTElEX1FVRVJZIiwicHJvbWlzZSIsImRyb3BJbmRleCIsInB1c2giLCJrZXkiLCJoYXNPd25Qcm9wZXJ0eSIsImluc2VydFByb21pc2UiLCJjcmVhdGVJbmRleGVzIiwiYWxsIiwic2V0SW5kZXhlc0Zyb21Nb25nbyIsImdldEluZGV4ZXMiLCJyZWR1Y2UiLCJvYmoiLCJpbmRleCIsIl9mdHMiLCJfZnRzeCIsIndlaWdodHMiLCJjcmVhdGVDbGFzcyIsImluc2VydFNjaGVtYSIsImFkZEZpZWxkSWZOb3RFeGlzdHMiLCJ0eXBlIiwiY3JlYXRlSW5kZXhlc0lmTmVlZGVkIiwiZGVsZXRlQ2xhc3MiLCJkcm9wIiwibWVzc2FnZSIsImZpbmRBbmREZWxldGVTY2hlbWEiLCJkZWxldGVBbGxDbGFzc2VzIiwiZmFzdCIsIm1hcCIsInJlbW92ZSIsImRlbGV0ZUZpZWxkcyIsImZpZWxkTmFtZXMiLCJtb25nb0Zvcm1hdE5hbWVzIiwiY29sbGVjdGlvblVwZGF0ZSIsInNjaGVtYVVwZGF0ZSIsInVwZGF0ZU1hbnkiLCJnZXRBbGxDbGFzc2VzIiwic2NoZW1hc0NvbGxlY3Rpb24iLCJfZmV0Y2hBbGxTY2hlbWFzRnJvbV9TQ0hFTUEiLCJnZXRDbGFzcyIsIl9mZXRjaE9uZVNjaGVtYUZyb21fU0NIRU1BIiwiY3JlYXRlT2JqZWN0Iiwib2JqZWN0IiwiaW5zZXJ0T25lIiwiRFVQTElDQVRFX1ZBTFVFIiwidW5kZXJseWluZ0Vycm9yIiwibWF0Y2hlcyIsIkFycmF5IiwiaXNBcnJheSIsInVzZXJJbmZvIiwiZHVwbGljYXRlZF9maWVsZCIsImRlbGV0ZU9iamVjdHNCeVF1ZXJ5IiwicXVlcnkiLCJtb25nb1doZXJlIiwiZGVsZXRlTWFueSIsInJlc3VsdCIsIm4iLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwidXBkYXRlT2JqZWN0c0J5UXVlcnkiLCJ1cGRhdGUiLCJtb25nb1VwZGF0ZSIsImZpbmRPbmVBbmRVcGRhdGUiLCJfbW9uZ29Db2xsZWN0aW9uIiwiZmluZEFuZE1vZGlmeSIsIm5ldyIsInZhbHVlIiwidXBzZXJ0T25lT2JqZWN0IiwidXBzZXJ0T25lIiwiZmluZCIsInNraXAiLCJsaW1pdCIsInNvcnQiLCJyZWFkUHJlZmVyZW5jZSIsIm1vbmdvU29ydCIsIl8iLCJtYXBLZXlzIiwibW9uZ29LZXlzIiwibWVtbyIsIl9wYXJzZVJlYWRQcmVmZXJlbmNlIiwiY3JlYXRlVGV4dEluZGV4ZXNJZk5lZWRlZCIsIm9iamVjdHMiLCJlbnN1cmVVbmlxdWVuZXNzIiwiaW5kZXhDcmVhdGlvblJlcXVlc3QiLCJtb25nb0ZpZWxkTmFtZXMiLCJfZW5zdXJlU3BhcnNlVW5pcXVlSW5kZXhJbkJhY2tncm91bmQiLCJfcmF3RmluZCIsImNvdW50IiwiZGlzdGluY3QiLCJpc1BvaW50ZXJGaWVsZCIsInN1YnN0cmluZyIsImFnZ3JlZ2F0ZSIsInBpcGVsaW5lIiwic3RhZ2UiLCIkZ3JvdXAiLCJfcGFyc2VBZ2dyZWdhdGVHcm91cEFyZ3MiLCIkbWF0Y2giLCJfcGFyc2VBZ2dyZWdhdGVBcmdzIiwiJHByb2plY3QiLCJfcGFyc2VBZ2dyZWdhdGVQcm9qZWN0QXJncyIsInJlc3VsdHMiLCJzcGxpdCIsImlzRW1wdHkiLCJyZXR1cm5WYWx1ZSIsInRhcmdldENsYXNzIiwiX2NvbnZlcnRUb0RhdGUiLCJEYXRlIiwiUFJJTUFSWSIsIlBSSU1BUllfUFJFRkVSUkVEIiwiU0VDT05EQVJZIiwiU0VDT05EQVJZX1BSRUZFUlJFRCIsIk5FQVJFU1QiLCJwZXJmb3JtSW5pdGlhbGl6YXRpb24iLCJjcmVhdGVJbmRleCIsIiR0ZXh0IiwiaW5kZXhOYW1lIiwidGV4dEluZGV4IiwiZHJvcEFsbEluZGV4ZXMiLCJkcm9wSW5kZXhlcyIsInVwZGF0ZVNjaGVtYVdpdGhJbmRleGVzIiwiY2xhc3NlcyIsInByb21pc2VzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOztBQUtBOztBQUlBOztBQVNBOzs7O0FBRUE7Ozs7QUFDQTs7OztBQUNBOzs7Ozs7O0FBTEE7O0FBRUE7OztBQUtBO0FBQ0EsTUFBTUEsVUFBVUMsUUFBUSxTQUFSLENBQWhCO0FBQ0EsTUFBTUMsY0FBY0YsUUFBUUUsV0FBNUI7QUFDQSxNQUFNQyxpQkFBaUJILFFBQVFHLGNBQS9COztBQUVBLE1BQU1DLDRCQUE0QixTQUFsQzs7QUFFQSxNQUFNQywrQkFBK0JDLGdCQUFnQjtBQUNuRCxTQUFPQSxhQUFhQyxPQUFiLEdBQ0pDLElBREksQ0FDQyxNQUFNRixhQUFhRyxRQUFiLENBQXNCQyxXQUF0QixFQURQLEVBRUpGLElBRkksQ0FFQ0UsZUFBZTtBQUNuQixXQUFPQSxZQUFZQyxNQUFaLENBQW1CQyxjQUFjO0FBQ3RDLFVBQUlBLFdBQVdDLFNBQVgsQ0FBcUJDLEtBQXJCLENBQTJCLFlBQTNCLENBQUosRUFBOEM7QUFDNUMsZUFBTyxLQUFQO0FBQ0Q7QUFDRDtB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QUN2QyxXQUFPLEtBQUt0QyxtQkFBTCxDQUF5QmpELFNBQXpCLEVBQ0pmLElBREksQ0FDQ0ksY0FBY0EsV0FBV29KLGdCQUFYLENBQTRCN0QsU0FBNUIsQ0FBc0NXLEtBQXRDLENBRGYsRUFFSmhELEtBRkksQ0FFRUMsT0FBTyxLQUFLRyxXQUFMLENBQWlCSCxHQUFqQixDQUZULENBQVA7QUFHRDs7QUFFRHVKLGlCQUFlL0wsU0FBZixFQUFrQztBQUNoQyxXQUFPLEtBQUtpRCxtQkFBTCxDQUF5QmpELFNBQXpCLEVBQ0pmLElBREksQ0FDQ0ksY0FBY0EsV0FBV29KLGdCQUFYLENBQTRCdUQsV0FBNUIsRUFEZixFQUVKekosS0FGSSxDQUVFQyxPQUFPLEtBQUtHLFdBQUwsQ0FBaUJILEdBQWpCLENBRlQsQ0FBUDtBQUdEOztBQUVEeUosNEJBQXdDO0FBQ3RDLFdBQU8sS0FBS25GLGFBQUwsR0FDSjdILElBREksQ0FDRWlOLE9BQUQsSUFBYTtBQUNqQixZQUFNQyxXQUFXRCxRQUFRNUYsR0FBUixDQUFhMUcsTUFBRCxJQUFZO0FBQ3ZDLGVBQU8sS0FBS3VGLG1CQUFMLENBQXlCdkYsT0FBT0ksU0FBaEMsQ0FBUDtBQUNELE9BRmdCLENBQWpCO0FBR0EsYUFBT3lDLFFBQVF5QyxHQUFSLENBQVlpSCxRQUFaLENBQVA7QUFDRCxLQU5JLEVBT0o1SixLQVBJLENBT0VDLE9BQU8sS0FBS0csV0FBTCxDQUFpQkgsR0FBakIsQ0FQVCxDQUFQO0FBUUQ7QUF2dEJ3RDs7UUFBOUNyQixtQixHQUFBQSxtQjtrQkEwdEJFQSxtQiIsImZpbGUiOiJNb25nb1N0b3JhZ2VBZGFwdGVyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCBNb25nb0NvbGxlY3Rpb24gICAgICAgZnJvbSAnLi9Nb25nb0NvbGxlY3Rpb24nO1xuaW1wb3J0IE1vbmdvU2NoZW1hQ29sbGVjdGlvbiBmcm9tICcuL01vbmdvU2NoZW1hQ29sbGVjdGlvbic7XG5pbXBvcnQgeyBTdG9yYWdlQWRhcHRlciB9ICAgIGZyb20gJy4uL1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCB0eXBlIHsgU2NoZW1hVHlwZSxcbiAgUXVlcnlUeXBlLFxuICBTdG9yYWdlQ2xhc3MsXG4gIFF1ZXJ5T3B0aW9ucyB9IGZyb20gJy4uL1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCB7XG4gIHBhcnNlIGFzIHBhcnNlVXJsLFxuICBmb3JtYXQgYXMgZm9ybWF0VXJsLFxufSBmcm9tICcuLi8uLi8uLi92ZW5kb3IvbW9uZ29kYlVybCc7XG5pbXBvcnQge1xuICBwYXJzZU9iamVjdFRvTW9uZ29PYmplY3RGb3JDcmVhdGUsXG4gIG1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdCxcbiAgdHJhbnNmb3JtS2V5LFxuICB0cmFuc2Zvcm1XaGVyZSxcbiAgdHJhbnNmb3JtVXBkYXRlLFxuICB0cmFuc2Zvcm1Qb2ludGVyU3RyaW5nLFxufSBmcm9tICcuL01vbmdvVHJhbnNmb3JtJztcbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuaW1wb3J0IFBhcnNlICAgICAgICAgICAgICAgICBmcm9tICdwYXJzZS9ub2RlJztcbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuaW1wb3J0IF8gICAgICAgICAgICAgICAgICAgICBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IGRlZmF1bHRzICAgICAgICAgICAgICBmcm9tICcuLi8uLi8uLi9kZWZhdWx0cyc7XG5pbXBvcnQgbG9nZ2VyICAgICAgICAgICAgICAgIGZyb20gJy4uLy4uLy4uL2xvZ2dlcic7XG5cbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuY29uc3QgbW9uZ29kYiA9IHJlcXVpcmUoJ21vbmdvZGInKTtcbmNvbnN0IE1vbmdvQ2xpZW50ID0gbW9uZ29kYi5Nb25nb0NsaWVudDtcbmNvbnN0IFJlYWRQcmVmZXJlbmNlID0gbW9uZ29kYi5SZWFkUHJlZmVyZW5jZTtcblxuY29uc3QgTW9uZ29TY2hlbWFDb2xsZWN0aW9uTmFtZSA9ICdfU0NIRU1BJztcblxuY29uc3Qgc3RvcmFnZUFkYXB0ZXJBbGxDb2xsZWN0aW9ucyA9IG1vbmdvQWRhcHRlciA9PiB7XG4gIHJldHVybiBtb25nb0FkYXB0ZXIuY29ubmVjdCgpXG4gICAgLnRoZW4oKCkgPT4gbW9uZ29BZGFwdGVyLmRhdGFiYXNlLmNvbGxlY3Rpb25zKCkpXG4gICAgLnRoZW4oY29sbGVjdGlvbnMgPT4ge1xuICAgICAgcmV0dXJuIGNvbGxlY3Rpb25zLmZpbHRlcihjb2xsZWN0aW9uID0+IHtcbiAgICAgICAgaWYgKGNvbGxlY3Rpb24ubmFtZXNwYWNlLm1hdGNoKC9cXC5zeXN0ZW1cXC4vKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBUT0RPOiBJZiB5b3UgaGF2ZSBvbmUgYXBwIHdpdGggYSBjb2xsZWN0aW9uIHByZWZpeCB0aGF0IGhhcHBlbnMgdG8gYmUgYSBwcmVmaXggb2YgYW5vdGhlclxuICAgICAgICAvLyBhcHBzIHByZWZpeCwgdGhpcyB3aWxsIGdvIHZlcnkgdmVyeSBiYWRseS4gV2Ugc2hvdWxkIGZpeCB0aGF0IHNvbWVob3cuXG4gICAgICAgIHJldHVybiAoY29sbGVjdGlvbi5jb2xsZWN0aW9uTmFtZS5pbmRleE9mKG1vbmdvQWRhcHRlci5fY29sbGVjdGlvblByZWZpeCkgPT0gMCk7XG4gICAgICB9KTtcbiAgICB9KTtcbn1cblxuY29uc3QgY29udmVydFBhcnNlU2NoZW1hVG9Nb25nb1NjaGVtYSA9ICh7Li4uc2NoZW1hfSkgPT4ge1xuICBkZWxldGUgc2NoZW1hLmZpZWxkcy5fcnBlcm07XG4gIGRlbGV0ZSBzY2hlbWEuZmllbGRzLl93cGVybTtcblxuICBpZiAoc2NoZW1hLmNsYXNzTmFtZSA9PT0gJ19Vc2VyJykge1xuICAgIC8vIExlZ2FjeSBtb25nbyBhZGFwdGVyIGtub3dzIGFib3V0IHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gcGFzc3dvcmQgYW5kIF9oYXNoZWRfcGFzc3dvcmQuXG4gICAgLy8gRnV0dXJlIGRhdGFiYXNlIGFkYXB0ZXJzIHdpbGwgb25seSBrbm93IGFib3V0IF9oYXNoZWRfcGFzc3dvcmQuXG4gICAgLy8gTm90ZTogUGFyc2UgU2VydmVyIHdpbGwgYnJpbmcgYmFjayBwYXNzd29yZCB3aXRoIGluamVjdERlZmF1bHRTY2hlbWEsIHNvIHdlIGRvbid0IG5lZWRcbiAgICAvLyB0byBhZGQgX2hhc2hlZF9wYXNzd29yZCBiYWNrIGV2ZXIuXG4gICAgZGVsZXRlIHNjaGVtYS5maWVsZHMuX2hhc2hlZF9wYXNzd29yZDtcbiAgfVxuXG4gIHJldHVybiBzY2hlbWE7XG59XG5cbi8vIFJldHVybnMgeyBjb2RlLCBlcnJvciB9IGlmIGludmFsaWQsIG9yIHsgcmVzdWx0IH0sIGFuIG9iamVjdFxuLy8gc3VpdGFibGUgZm9yIGluc2VydGluZyBpbnRvIF9TQ0hFTUEgY29sbGVjdGlvbiwgb3RoZXJ3aXNlLlxuY29uc3QgbW9uZ29TY2hlbWFGcm9tRmllbGRzQW5kQ2xhc3NOYW1lQW5kQ0xQID0gKGZpZWxkcywgY2xhc3NOYW1lLCBjbGFzc0xldmVsUGVybWlzc2lvbnMsIGluZGV4ZXMpID0+IHtcbiAgY29uc3QgbW9uZ29PYmplY3QgPSB7XG4gICAgX2lkOiBjbGFzc05hbWUsXG4gICAgb2JqZWN0SWQ6ICdzdHJpbmcnLFxuICAgIHVwZGF0ZWRBdDogJ3N0cmluZycsXG4gICAgY3JlYXRlZEF0OiAnc3RyaW5nJyxcbiAgICBfbWV0YWRhdGE6IHVuZGVmaW5lZCxcbiAgfTtcblxuICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBpbiBmaWVsZHMpIHtcbiAgICBtb25nb09iamVjdFtmaWVsZE5hbWVdID0gTW9uZ29TY2hlbWFDb2xsZWN0aW9uLnBhcnNlRmllbGRUeXBlVG9Nb25nb0ZpZWxkVHlwZShmaWVsZHNbZmllbGROYW1lXSk7XG4gIH1cblxuICBpZiAodHlwZW9mIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBtb25nb09iamVjdC5fbWV0YWRhdGEgPSBtb25nb09iamVjdC5fbWV0YWRhdGEgfHwge307XG4gICAgaWYgKCFjbGFzc0xldmVsUGVybWlzc2lvbnMpIHtcbiAgICAgIGRlbGV0ZSBtb25nb09iamVjdC5fbWV0YWRhdGEuY2xhc3NfcGVybWlzc2lvbnM7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1vbmdvT2JqZWN0Ll9tZXRhZGF0YS5jbGFzc19wZXJtaXNzaW9ucyA9IGNsYXNzTGV2ZWxQZXJtaXNzaW9ucztcbiAgICB9XG4gIH1cblxuICBpZiAoaW5kZXhlcyAmJiB0eXBlb2YgaW5kZXhlcyA9PT0gJ29iamVjdCcgJiYgT2JqZWN0LmtleXMoaW5kZXhlcykubGVuZ3RoID4gMCkge1xuICAgIG1vbmdvT2JqZWN0Ll9tZXRhZGF0YSA9IG1vbmdvT2JqZWN0Ll9tZXRhZGF0YSB8fCB7fTtcbiAgICBtb25nb09iamVjdC5fbWV0YWRhdGEuaW5kZXhlcyA9IGluZGV4ZXM7XG4gIH1cblxuICBpZiAoIW1vbmdvT2JqZWN0Ll9tZXRhZGF0YSkgeyAvLyBjbGVhbnVwIHRoZSB1bnVzZWQgX21ldGFkYXRhXG4gICAgZGVsZXRlIG1vbmdvT2JqZWN0Ll9tZXRhZGF0YTtcbiAgfVxuXG4gIHJldHVybiBtb25nb09iamVjdDtcbn1cblxuXG5leHBvcnQgY2xhc3MgTW9uZ29TdG9yYWdlQWRhcHRlciBpbXBsZW1lbnRzIFN0b3JhZ2VBZGFwdGVyIHtcbiAgLy8gUHJpdmF0ZVxuICBfdXJpOiBzdHJpbmc7XG4gIF9jb2xsZWN0aW9uUHJlZml4OiBzdHJpbmc7XG4gIF9tb25nb09wdGlvbnM6IE9iamVjdDtcbiAgLy8gUHVibGljXG4gIGNvbm5lY3Rpb25Qcm9taXNlOiBQcm9taXNlPGFueT47XG4gIGRhdGFiYXNlOiBhbnk7XG4gIGNsaWVudDogTW9uZ29DbGllbnQ7XG4gIF9tYXhUaW1lTVM6ID9udW1iZXI7XG4gIGNhblNvcnRPbkpvaW5UYWJsZXM6IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIHVyaSA9IGRlZmF1bHRzLkRlZmF1bHRNb25nb1VSSSxcbiAgICBjb2xsZWN0aW9uUHJlZml4ID0gJycsXG4gICAgbW9uZ29PcHRpb25zID0ge30sXG4gIH06IGFueSkge1xuICAgIHRoaXMuX3VyaSA9IHVyaTtcbiAgICB0aGlzLl9jb2xsZWN0aW9uUHJlZml4ID0gY29sbGVjdGlvblByZWZpeDtcbiAgICB0aGlzLl9tb25nb09wdGlvbnMgPSBtb25nb09wdGlvbnM7XG5cbiAgICAvLyBNYXhUaW1lTVMgaXMgbm90IGEgZ2xvYmFsIE1vbmdvREIgY2xpZW50IG9wdGlvbiwgaXQgaXMgYXBwbGllZCBwZXIgb3BlcmF0aW9uLlxuICAgIHRoaXMuX21heFRpbWVNUyA9IG1vbmdvT3B0aW9ucy5tYXhUaW1lTVM7XG4gICAgdGhpcy5jYW5Tb3J0T25Kb2luVGFibGVzID0gdHJ1ZTtcbiAgICBkZWxldGUgbW9uZ29PcHRpb25zLm1heFRpbWVNUztcbiAgfVxuXG4gIGNvbm5lY3QoKSB7XG4gICAgaWYgKHRoaXMuY29ubmVjdGlvblByb21pc2UpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb25Qcm9taXNlO1xuICAgIH1cblxuICAgIC8vIHBhcnNpbmcgYW5kIHJlLWZvcm1hdHRpbmcgY2F1c2VzIHRoZSBhdXRoIHZhbHVlIChpZiB0aGVyZSkgdG8gZ2V0IFVSSVxuICAgIC8vIGVuY29kZWRcbiAgICBjb25zdCBlbmNvZGVkVXJpID0gZm9ybWF0VXJsKHBhcnNlVXJsKHRoaXMuX3VyaSkpO1xuXG4gICAgdGhpcy5jb25uZWN0aW9uUHJvbWlzZSA9IE1vbmdvQ2xpZW50LmNvbm5lY3QoZW5jb2RlZFVyaSwgdGhpcy5fbW9uZ29PcHRpb25zKS50aGVuKGNsaWVudCA9PiB7XG4gICAgICAvLyBTdGFydGluZyBtb25nb0RCIDMuMCwgdGhlIE1vbmdvQ2xpZW50LmNvbm5lY3QgZG9uJ3QgcmV0dXJuIGEgREIgYW55bW9yZSBidXQgYSBjbGllbnRcbiAgICAgIC8vIEZvcnR1bmF0ZWx5LCB3ZSBjYW4gZ2V0IGJhY2sgdGhlIG9wdGlvbnMgYW5kIHVzZSB0aGVtIHRvIHNlbGVjdCB0aGUgcHJvcGVyIERCLlxuICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21vbmdvZGIvbm9kZS1tb25nb2RiLW5hdGl2ZS9ibG9iLzJjMzVkNzZmMDg1NzQyMjViOGRiMDJkN2JlZjY4NzEyM2U2YmIwMTgvbGliL21vbmdvX2NsaWVudC5qcyNMODg1XG4gICAgICBjb25zdCBvcHRpb25zID0gY2xpZW50LnMub3B0aW9ucztcbiAgICAgIGNvbnN0IGRhdGFiYXNlID0gY2xpZW50LmRiKG9wdGlvbnMuZGJOYW1lKTtcbiAgICAgIGlmICghZGF0YWJhc2UpIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuY29ubmVjdGlvblByb21pc2U7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGRhdGFiYXNlLm9uKCdlcnJvcicsICgpID0+IHtcbiAgICAgICAgZGVsZXRlIHRoaXMuY29ubmVjdGlvblByb21pc2U7XG4gICAgICB9KTtcbiAgICAgIGRhdGFiYXNlLm9uKCdjbG9zZScsICgpID0+IHtcbiAgICAgICAgZGVsZXRlIHRoaXMuY29ubmVjdGlvblByb21pc2U7XG4gICAgICB9KTtcbiAgICAgIHRoaXMuY2xpZW50ID0gY2xpZW50O1xuICAgICAgdGhpcy5kYXRhYmFzZSA9IGRhdGFiYXNlO1xuICAgIH0pLmNhdGNoKChlcnIpID0+IHtcbiAgICAgIGRlbGV0ZSB0aGlzLmNvbm5lY3Rpb25Qcm9taXNlO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycik7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9uUHJvbWlzZTtcbiAgfVxuXG4gIGhhbmRsZUVycm9yPFQ+KGVycm9yOiA/KEVycm9yIHwgUGFyc2UuRXJyb3IpKTogUHJvbWlzZTxUPiB7XG4gICAgaWYgKGVycm9yICYmIGVycm9yLmNvZGUgPT09IDEzKSB7IC8vIFVuYXV0aG9yaXplZCBlcnJvclxuICAgICAgZGVsZXRlIHRoaXMuY2xpZW50O1xuICAgICAgZGVsZXRlIHRoaXMuZGF0YWJhc2U7XG4gICAgICBkZWxldGUgdGhpcy5jb25uZWN0aW9uUHJvbWlzZTtcbiAgICAgIGxvZ2dlci5lcnJvcignUmVjZWl2ZWQgdW5hdXRob3JpemVkIGVycm9yJywgeyBlcnJvcjogZXJyb3IgfSk7XG4gICAgfVxuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgaGFuZGxlU2h1dGRvd24oKSB7XG4gICAgaWYgKCF0aGlzLmNsaWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNsaWVudC5jbG9zZShmYWxzZSk7XG4gIH1cblxuICBfYWRhcHRpdmVDb2xsZWN0aW9uKG5hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmNvbm5lY3QoKVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5kYXRhYmFzZS5jb2xsZWN0aW9uKHRoaXMuX2NvbGxlY3Rpb25QcmVmaXggKyBuYW1lKSlcbiAgICAgIC50aGVuKHJhd0NvbGxlY3Rpb24gPT4gbmV3IE1vbmdvQ29sbGVjdGlvbihyYXdDb2xsZWN0aW9uKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIF9zY2hlbWFDb2xsZWN0aW9uKCk6IFByb21pc2U8TW9uZ29TY2hlbWFDb2xsZWN0aW9uPiB7XG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdCgpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oTW9uZ29TY2hlbWFDb2xsZWN0aW9uTmFtZSkpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IG5ldyBNb25nb1NjaGVtYUNvbGxlY3Rpb24oY29sbGVjdGlvbikpO1xuICB9XG5cbiAgY2xhc3NFeGlzdHMobmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdCgpLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuZGF0YWJhc2UubGlzdENvbGxlY3Rpb25zKHsgbmFtZTogdGhpcy5fY29sbGVjdGlvblByZWZpeCArIG5hbWUgfSkudG9BcnJheSgpO1xuICAgIH0pLnRoZW4oY29sbGVjdGlvbnMgPT4ge1xuICAgICAgcmV0dXJuIGNvbGxlY3Rpb25zLmxlbmd0aCA+IDA7XG4gICAgfSkuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBzZXRDbGFzc0xldmVsUGVybWlzc2lvbnMoY2xhc3NOYW1lOiBzdHJpbmcsIENMUHM6IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKClcbiAgICAgIC50aGVuKHNjaGVtYUNvbGxlY3Rpb24gPT4gc2NoZW1hQ29sbGVjdGlvbi51cGRhdGVTY2hlbWEoY2xhc3NOYW1lLCB7XG4gICAgICAgICRzZXQ6IHsgJ19tZXRhZGF0YS5jbGFzc19wZXJtaXNzaW9ucyc6IENMUHMgfVxuICAgICAgfSkpLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgc2V0SW5kZXhlc1dpdGhTY2hlbWFGb3JtYXQoY2xhc3NOYW1lOiBzdHJpbmcsIHN1Ym1pdHRlZEluZGV4ZXM6IGFueSwgZXhpc3RpbmdJbmRleGVzOiBhbnkgPSB7fSwgZmllbGRzOiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoc3VibWl0dGVkSW5kZXhlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIGlmIChPYmplY3Qua2V5cyhleGlzdGluZ0luZGV4ZXMpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgZXhpc3RpbmdJbmRleGVzID0geyBfaWRfOiB7IF9pZDogMX0gfTtcbiAgICB9XG4gICAgY29uc3QgZGVsZXRlUHJvbWlzZXMgPSBbXTtcbiAgICBjb25zdCBpbnNlcnRlZEluZGV4ZXMgPSBbXTtcbiAgICBPYmplY3Qua2V5cyhzdWJtaXR0ZWRJbmRleGVzKS5mb3JFYWNoKG5hbWUgPT4ge1xuICAgICAgY29uc3QgZmllbGQgPSBzdWJtaXR0ZWRJbmRleGVzW25hbWVdO1xuICAgICAgaWYgKGV4aXN0aW5nSW5kZXhlc1tuYW1lXSAmJiBmaWVsZC5fX29wICE9PSAnRGVsZXRlJykge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSwgYEluZGV4ICR7bmFtZX0gZXhpc3RzLCBjYW5ub3QgdXBkYXRlLmApO1xuICAgICAgfVxuICAgICAgaWYgKCFleGlzdGluZ0luZGV4ZXNbbmFtZV0gJiYgZmllbGQuX19vcCA9PT0gJ0RlbGV0ZScpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksIGBJbmRleCAke25hbWV9IGRvZXMgbm90IGV4aXN0LCBjYW5ub3QgZGVsZXRlLmApO1xuICAgICAgfVxuICAgICAgaWYgKGZpZWxkLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLmRyb3BJbmRleChjbGFzc05hbWUsIG5hbWUpO1xuICAgICAgICBkZWxldGVQcm9taXNlcy5wdXNoKHByb21pc2UpO1xuICAgICAgICBkZWxldGUgZXhpc3RpbmdJbmRleGVzW25hbWVdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgT2JqZWN0LmtleXMoZmllbGQpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICBpZiAoIWZpZWxkcy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSwgYEZpZWxkICR7a2V5fSBkb2VzIG5vdCBleGlzdCwgY2Fubm90IGFkZCBpbmRleC5gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBleGlzdGluZ0luZGV4ZXNbbmFtZV0gPSBmaWVsZDtcbiAgICAgICAgaW5zZXJ0ZWRJbmRleGVzLnB1c2goe1xuICAgICAgICAgIGtleTogZmllbGQsXG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgbGV0IGluc2VydFByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgICBpZiAoaW5zZXJ0ZWRJbmRleGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGluc2VydFByb21pc2UgPSB0aGlzLmNyZWF0ZUluZGV4ZXMoY2xhc3NOYW1lLCBpbnNlcnRlZEluZGV4ZXMpO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoZGVsZXRlUHJvbWlzZXMpXG4gICAgICAudGhlbigoKSA9PiBpbnNlcnRQcm9taXNlKVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpKVxuICAgICAgLnRoZW4oc2NoZW1hQ29sbGVjdGlvbiA9PiBzY2hlbWFDb2xsZWN0aW9uLnVwZGF0ZVNjaGVtYShjbGFzc05hbWUsIHtcbiAgICAgICAgJHNldDogeyAnX21ldGFkYXRhLmluZGV4ZXMnOiAgZXhpc3RpbmdJbmRleGVzIH1cbiAgICAgIH0pKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgc2V0SW5kZXhlc0Zyb21Nb25nbyhjbGFzc05hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmdldEluZGV4ZXMoY2xhc3NOYW1lKS50aGVuKChpbmRleGVzKSA9PiB7XG4gICAgICBpbmRleGVzID0gaW5kZXhlcy5yZWR1Y2UoKG9iaiwgaW5kZXgpID0+IHtcbiAgICAgICAgaWYgKGluZGV4LmtleS5fZnRzKSB7XG4gICAgICAgICAgZGVsZXRlIGluZGV4LmtleS5fZnRzO1xuICAgICAgICAgIGRlbGV0ZSBpbmRleC5rZXkuX2Z0c3g7XG4gICAgICAgICAgZm9yIChjb25zdCBmaWVsZCBpbiBpbmRleC53ZWlnaHRzKSB7XG4gICAgICAgICAgICBpbmRleC5rZXlbZmllbGRdID0gJ3RleHQnO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBvYmpbaW5kZXgubmFtZV0gPSBpbmRleC5rZXk7XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgICB9LCB7fSk7XG4gICAgICByZXR1cm4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpXG4gICAgICAgIC50aGVuKHNjaGVtYUNvbGxlY3Rpb24gPT4gc2NoZW1hQ29sbGVjdGlvbi51cGRhdGVTY2hlbWEoY2xhc3NOYW1lLCB7XG4gICAgICAgICAgJHNldDogeyAnX21ldGFkYXRhLmluZGV4ZXMnOiBpbmRleGVzIH1cbiAgICAgICAgfSkpO1xuICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSlcbiAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgIC8vIElnbm9yZSBpZiBjb2xsZWN0aW9uIG5vdCBmb3VuZFxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZUNsYXNzKGNsYXNzTmFtZTogc3RyaW5nLCBzY2hlbWE6IFNjaGVtYVR5cGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29PYmplY3QgPSBtb25nb1NjaGVtYUZyb21GaWVsZHNBbmRDbGFzc05hbWVBbmRDTFAoc2NoZW1hLmZpZWxkcywgY2xhc3NOYW1lLCBzY2hlbWEuY2xhc3NMZXZlbFBlcm1pc3Npb25zLCBzY2hlbWEuaW5kZXhlcyk7XG4gICAgbW9uZ29PYmplY3QuX2lkID0gY2xhc3NOYW1lO1xuICAgIHJldHVybiB0aGlzLnNldEluZGV4ZXNXaXRoU2NoZW1hRm9ybWF0KGNsYXNzTmFtZSwgc2NoZW1hLmluZGV4ZXMsIHt9LCBzY2hlbWEuZmllbGRzKVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpKVxuICAgICAgLnRoZW4oc2NoZW1hQ29sbGVjdGlvbiA9PiBzY2hlbWFDb2xsZWN0aW9uLmluc2VydFNjaGVtYShtb25nb09iamVjdCkpXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBhZGRGaWVsZElmTm90RXhpc3RzKGNsYXNzTmFtZTogc3RyaW5nLCBmaWVsZE5hbWU6IHN0cmluZywgdHlwZTogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuX3NjaGVtYUNvbGxlY3Rpb24oKVxuICAgICAgLnRoZW4oc2NoZW1hQ29sbGVjdGlvbiA9PiBzY2hlbWFDb2xsZWN0aW9uLmFkZEZpZWxkSWZOb3RFeGlzdHMoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHR5cGUpKVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5jcmVhdGVJbmRleGVzSWZOZWVkZWQoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHR5cGUpKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gRHJvcHMgYSBjb2xsZWN0aW9uLiBSZXNvbHZlcyB3aXRoIHRydWUgaWYgaXQgd2FzIGEgUGFyc2UgU2NoZW1hIChlZy4gX1VzZXIsIEN1c3RvbSwgZXRjLilcbiAgLy8gYW5kIHJlc29sdmVzIHdpdGggZmFsc2UgaWYgaXQgd2Fzbid0IChlZy4gYSBqb2luIHRhYmxlKS4gUmVqZWN0cyBpZiBkZWxldGlvbiB3YXMgaW1wb3NzaWJsZS5cbiAgZGVsZXRlQ2xhc3MoY2xhc3NOYW1lOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5kcm9wKCkpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgLy8gJ25zIG5vdCBmb3VuZCcgbWVhbnMgY29sbGVjdGlvbiB3YXMgYWxyZWFkeSBnb25lLiBJZ25vcmUgZGVsZXRpb24gYXR0ZW1wdC5cbiAgICAgICAgaWYgKGVycm9yLm1lc3NhZ2UgPT0gJ25zIG5vdCBmb3VuZCcpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KVxuICAgIC8vIFdlJ3ZlIGRyb3BwZWQgdGhlIGNvbGxlY3Rpb24sIG5vdyByZW1vdmUgdGhlIF9TQ0hFTUEgZG9jdW1lbnRcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuX3NjaGVtYUNvbGxlY3Rpb24oKSlcbiAgICAgIC50aGVuKHNjaGVtYUNvbGxlY3Rpb24gPT4gc2NoZW1hQ29sbGVjdGlvbi5maW5kQW5kRGVsZXRlU2NoZW1hKGNsYXNzTmFtZSkpXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBkZWxldGVBbGxDbGFzc2VzKGZhc3Q6IGJvb2xlYW4pIHtcbiAgICByZXR1cm4gc3RvcmFnZUFkYXB0ZXJBbGxDb2xsZWN0aW9ucyh0aGlzKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbnMgPT4gUHJvbWlzZS5hbGwoY29sbGVjdGlvbnMubWFwKGNvbGxlY3Rpb24gPT4gZmFzdCA/IGNvbGxlY3Rpb24ucmVtb3ZlKHt9KSA6IGNvbGxlY3Rpb24uZHJvcCgpKSkpO1xuICB9XG5cbiAgLy8gUmVtb3ZlIHRoZSBjb2x1bW4gYW5kIGFsbCB0aGUgZGF0YS4gRm9yIFJlbGF0aW9ucywgdGhlIF9Kb2luIGNvbGxlY3Rpb24gaXMgaGFuZGxlZFxuICAvLyBzcGVjaWFsbHksIHRoaXMgZnVuY3Rpb24gZG9lcyBub3QgZGVsZXRlIF9Kb2luIGNvbHVtbnMuIEl0IHNob3VsZCwgaG93ZXZlciwgaW5kaWNhdGVcbiAgLy8gdGhhdCB0aGUgcmVsYXRpb24gZmllbGRzIGRvZXMgbm90IGV4aXN0IGFueW1vcmUuIEluIG1vbmdvLCB0aGlzIG1lYW5zIHJlbW92aW5nIGl0IGZyb21cbiAgLy8gdGhlIF9TQ0hFTUEgY29sbGVjdGlvbi4gIFRoZXJlIHNob3VsZCBiZSBubyBhY3R1YWwgZGF0YSBpbiB0aGUgY29sbGVjdGlvbiB1bmRlciB0aGUgc2FtZSBuYW1lXG4gIC8vIGFzIHRoZSByZWxhdGlvbiBjb2x1bW4sIHNvIGl0J3MgZmluZSB0byBhdHRlbXB0IHRvIGRlbGV0ZSBpdC4gSWYgdGhlIGZpZWxkcyBsaXN0ZWQgdG8gYmVcbiAgLy8gZGVsZXRlZCBkbyBub3QgZXhpc3QsIHRoaXMgZnVuY3Rpb24gc2hvdWxkIHJldHVybiBzdWNjZXNzZnVsbHkgYW55d2F5cy4gQ2hlY2tpbmcgZm9yXG4gIC8vIGF0dGVtcHRzIHRvIGRlbGV0ZSBub24tZXhpc3RlbnQgZmllbGRzIGlzIHRoZSByZXNwb25zaWJpbGl0eSBvZiBQYXJzZSBTZXJ2ZXIuXG5cbiAgLy8gUG9pbnRlciBmaWVsZCBuYW1lcyBhcmUgcGFzc2VkIGZvciBsZWdhY3kgcmVhc29uczogdGhlIG9yaWdpbmFsIG1vbmdvXG4gIC8vIGZvcm1hdCBzdG9yZWQgcG9pbnRlciBmaWVsZCBuYW1lcyBkaWZmZXJlbnRseSBpbiB0aGUgZGF0YWJhc2UsIGFuZCB0aGVyZWZvcmVcbiAgLy8gbmVlZGVkIHRvIGtub3cgdGhlIHR5cGUgb2YgdGhlIGZpZWxkIGJlZm9yZSBpdCBjb3VsZCBkZWxldGUgaXQuIEZ1dHVyZSBkYXRhYmFzZVxuICAvLyBhZGFwdGVycyBzaG91bGQgaWdub3JlIHRoZSBwb2ludGVyRmllbGROYW1lcyBhcmd1bWVudC4gQWxsIHRoZSBmaWVsZCBuYW1lcyBhcmUgaW5cbiAgLy8gZmllbGROYW1lcywgdGhleSBzaG93IHVwIGFkZGl0aW9uYWxseSBpbiB0aGUgcG9pbnRlckZpZWxkTmFtZXMgZGF0YWJhc2UgZm9yIHVzZVxuICAvLyBieSB0aGUgbW9uZ28gYWRhcHRlciwgd2hpY2ggZGVhbHMgd2l0aCB0aGUgbGVnYWN5IG1vbmdvIGZvcm1hdC5cblxuICAvLyBUaGlzIGZ1bmN0aW9uIGlzIG5vdCBvYmxpZ2F0ZWQgdG8gZGVsZXRlIGZpZWxkcyBhdG9taWNhbGx5LiBJdCBpcyBnaXZlbiB0aGUgZmllbGRcbiAgLy8gbmFtZXMgaW4gYSBsaXN0IHNvIHRoYXQgZGF0YWJhc2VzIHRoYXQgYXJlIGNhcGFibGUgb2YgZGVsZXRpbmcgZmllbGRzIGF0b21pY2FsbHlcbiAgLy8gbWF5IGRvIHNvLlxuXG4gIC8vIFJldHVybnMgYSBQcm9taXNlLlxuICBkZWxldGVGaWVsZHMoY2xhc3NOYW1lOiBzdHJpbmcsIHNjaGVtYTogU2NoZW1hVHlwZSwgZmllbGROYW1lczogc3RyaW5nW10pIHtcbiAgICBjb25zdCBtb25nb0Zvcm1hdE5hbWVzID0gZmllbGROYW1lcy5tYXAoZmllbGROYW1lID0+IHtcbiAgICAgIGlmIChzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PT0gJ1BvaW50ZXInKSB7XG4gICAgICAgIHJldHVybiBgX3BfJHtmaWVsZE5hbWV9YFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZpZWxkTmFtZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBjb2xsZWN0aW9uVXBkYXRlID0geyAnJHVuc2V0JyA6IHt9IH07XG4gICAgbW9uZ29Gb3JtYXROYW1lcy5mb3JFYWNoKG5hbWUgPT4ge1xuICAgICAgY29sbGVjdGlvblVwZGF0ZVsnJHVuc2V0J11bbmFtZV0gPSBudWxsO1xuICAgIH0pO1xuXG4gICAgY29uc3Qgc2NoZW1hVXBkYXRlID0geyAnJHVuc2V0JyA6IHt9IH07XG4gICAgZmllbGROYW1lcy5mb3JFYWNoKG5hbWUgPT4ge1xuICAgICAgc2NoZW1hVXBkYXRlWyckdW5zZXQnXVtuYW1lXSA9IG51bGw7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi51cGRhdGVNYW55KHt9LCBjb2xsZWN0aW9uVXBkYXRlKSlcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuX3NjaGVtYUNvbGxlY3Rpb24oKSlcbiAgICAgIC50aGVuKHNjaGVtYUNvbGxlY3Rpb24gPT4gc2NoZW1hQ29sbGVjdGlvbi51cGRhdGVTY2hlbWEoY2xhc3NOYW1lLCBzY2hlbWFVcGRhdGUpKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gUmV0dXJuIGEgcHJvbWlzZSBmb3IgYWxsIHNjaGVtYXMga25vd24gdG8gdGhpcyBhZGFwdGVyLCBpbiBQYXJzZSBmb3JtYXQuIEluIGNhc2UgdGhlXG4gIC8vIHNjaGVtYXMgY2Fubm90IGJlIHJldHJpZXZlZCwgcmV0dXJucyBhIHByb21pc2UgdGhhdCByZWplY3RzLiBSZXF1aXJlbWVudHMgZm9yIHRoZVxuICAvLyByZWplY3Rpb24gcmVhc29uIGFyZSBUQkQuXG4gIGdldEFsbENsYXNzZXMoKTogUHJvbWlzZTxTdG9yYWdlQ2xhc3NbXT4ge1xuICAgIHJldHVybiB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKCkudGhlbihzY2hlbWFzQ29sbGVjdGlvbiA9PiBzY2hlbWFzQ29sbGVjdGlvbi5fZmV0Y2hBbGxTY2hlbWFzRnJvbV9TQ0hFTUEoKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIFJldHVybiBhIHByb21pc2UgZm9yIHRoZSBzY2hlbWEgd2l0aCB0aGUgZ2l2ZW4gbmFtZSwgaW4gUGFyc2UgZm9ybWF0LiBJZlxuICAvLyB0aGlzIGFkYXB0ZXIgZG9lc24ndCBrbm93IGFib3V0IHRoZSBzY2hlbWEsIHJldHVybiBhIHByb21pc2UgdGhhdCByZWplY3RzIHdpdGhcbiAgLy8gdW5kZWZpbmVkIGFzIHRoZSByZWFzb24uXG4gIGdldENsYXNzKGNsYXNzTmFtZTogc3RyaW5nKTogUHJvbWlzZTxTdG9yYWdlQ2xhc3M+IHtcbiAgICByZXR1cm4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpXG4gICAgICAudGhlbihzY2hlbWFzQ29sbGVjdGlvbiA9PiBzY2hlbWFzQ29sbGVjdGlvbi5fZmV0Y2hPbmVTY2hlbWFGcm9tX1NDSEVNQShjbGFzc05hbWUpKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gVE9ETzogQXMgeWV0IG5vdCBwYXJ0aWN1bGFybHkgd2VsbCBzcGVjaWZpZWQuIENyZWF0ZXMgYW4gb2JqZWN0LiBNYXliZSBzaG91bGRuJ3QgZXZlbiBuZWVkIHRoZSBzY2hlbWEsXG4gIC8vIGFuZCBzaG91bGQgaW5mZXIgZnJvbSB0aGUgdHlwZS4gT3IgbWF5YmUgZG9lcyBuZWVkIHRoZSBzY2hlbWEgZm9yIHZhbGlkYXRpb25zLiBPciBtYXliZSBuZWVkc1xuICAvLyB0aGUgc2NoZW1hIG9ubHkgZm9yIHRoZSBsZWdhY3kgbW9uZ28gZm9ybWF0LiBXZSdsbCBmaWd1cmUgdGhhdCBvdXQgbGF0ZXIuXG4gIGNyZWF0ZU9iamVjdChjbGFzc05hbWU6IHN0cmluZywgc2NoZW1hOiBTY2hlbWFUeXBlLCBvYmplY3Q6IGFueSkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb09iamVjdCA9IHBhcnNlT2JqZWN0VG9Nb25nb09iamVjdEZvckNyZWF0ZShjbGFzc05hbWUsIG9iamVjdCwgc2NoZW1hKTtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5pbnNlcnRPbmUobW9uZ29PYmplY3QpKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDExMDAwKSB7IC8vIER1cGxpY2F0ZSB2YWx1ZVxuICAgICAgICAgIGNvbnN0IGVyciA9IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUsICdBIGR1cGxpY2F0ZSB2YWx1ZSBmb3IgYSBmaWVsZCB3aXRoIHVuaXF1ZSB2YWx1ZXMgd2FzIHByb3ZpZGVkJyk7XG4gICAgICAgICAgZXJyLnVuZGVybHlpbmdFcnJvciA9IGVycm9yO1xuICAgICAgICAgIGlmIChlcnJvci5tZXNzYWdlKSB7XG4gICAgICAgICAgICBjb25zdCBtYXRjaGVzID0gZXJyb3IubWVzc2FnZS5tYXRjaCgvaW5kZXg6W1xcc2EtekEtWjAtOV9cXC1cXC5dK1xcJD8oW2EtekEtWl8tXSspXzEvKTtcbiAgICAgICAgICAgIGlmIChtYXRjaGVzICYmIEFycmF5LmlzQXJyYXkobWF0Y2hlcykpIHtcbiAgICAgICAgICAgICAgZXJyLnVzZXJJbmZvID0geyBkdXBsaWNhdGVkX2ZpZWxkOiBtYXRjaGVzWzFdIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICAvLyBSZW1vdmUgYWxsIG9iamVjdHMgdGhhdCBtYXRjaCB0aGUgZ2l2ZW4gUGFyc2UgUXVlcnkuXG4gIC8vIElmIG5vIG9iamVjdHMgbWF0Y2gsIHJlamVjdCB3aXRoIE9CSkVDVF9OT1RfRk9VTkQuIElmIG9iamVjdHMgYXJlIGZvdW5kIGFuZCBkZWxldGVkLCByZXNvbHZlIHdpdGggdW5kZWZpbmVkLlxuICAvLyBJZiB0aGVyZSBpcyBzb21lIG90aGVyIGVycm9yLCByZWplY3Qgd2l0aCBJTlRFUk5BTF9TRVJWRVJfRVJST1IuXG4gIGRlbGV0ZU9iamVjdHNCeVF1ZXJ5KGNsYXNzTmFtZTogc3RyaW5nLCBzY2hlbWE6IFNjaGVtYVR5cGUsIHF1ZXJ5OiBRdWVyeVR5cGUpIHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IHtcbiAgICAgICAgY29uc3QgbW9uZ29XaGVyZSA9IHRyYW5zZm9ybVdoZXJlKGNsYXNzTmFtZSwgcXVlcnksIHNjaGVtYSk7XG4gICAgICAgIHJldHVybiBjb2xsZWN0aW9uLmRlbGV0ZU1hbnkobW9uZ29XaGVyZSlcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSlcbiAgICAgIC50aGVuKCh7IHJlc3VsdCB9KSA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQubiA9PT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELCAnT2JqZWN0IG5vdCBmb3VuZC4nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9LCAoKSA9PiB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlRFUk5BTF9TRVJWRVJfRVJST1IsICdEYXRhYmFzZSBhZGFwdGVyIGVycm9yJyk7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8vIEFwcGx5IHRoZSB1cGRhdGUgdG8gYWxsIG9iamVjdHMgdGhhdCBtYXRjaCB0aGUgZ2l2ZW4gUGFyc2UgUXVlcnkuXG4gIHVwZGF0ZU9iamVjdHNCeVF1ZXJ5KGNsYXNzTmFtZTogc3RyaW5nLCBzY2hlbWE6IFNjaGVtYVR5cGUsIHF1ZXJ5OiBRdWVyeVR5cGUsIHVwZGF0ZTogYW55KSB7XG4gICAgc2NoZW1hID0gY29udmVydFBhcnNlU2NoZW1hVG9Nb25nb1NjaGVtYShzY2hlbWEpO1xuICAgIGNvbnN0IG1vbmdvVXBkYXRlID0gdHJhbnNmb3JtVXBkYXRlKGNsYXNzTmFtZSwgdXBkYXRlLCBzY2hlbWEpO1xuICAgIGNvbnN0IG1vbmdvV2hlcmUgPSB0cmFuc2Zvcm1XaGVyZShjbGFzc05hbWUsIHF1ZXJ5LCBzY2hlbWEpO1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLnVwZGF0ZU1hbnkobW9uZ29XaGVyZSwgbW9uZ29VcGRhdGUpKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gQXRvbWljYWxseSBmaW5kcyBhbmQgdXBkYXRlcyBhbiBvYmplY3QgYmFzZWQgb24gcXVlcnkuXG4gIC8vIFJldHVybiB2YWx1ZSBub3QgY3VycmVudGx5IHdlbGwgc3BlY2lmaWVkLlxuICBmaW5kT25lQW5kVXBkYXRlKGNsYXNzTmFtZTogc3RyaW5nLCBzY2hlbWE6IFNjaGVtYVR5cGUsIHF1ZXJ5OiBRdWVyeVR5cGUsIHVwZGF0ZTogYW55KSB7XG4gICAgc2NoZW1hID0gY29udmVydFBhcnNlU2NoZW1hVG9Nb25nb1NjaGVtYShzY2hlbWEpO1xuICAgIGNvbnN0IG1vbmdvVXBkYXRlID0gdHJhbnNmb3JtVXBkYXRlKGNsYXNzTmFtZSwgdXBkYXRlLCBzY2hlbWEpO1xuICAgIGNvbnN0IG1vbmdvV2hlcmUgPSB0cmFuc2Zvcm1XaGVyZShjbGFzc05hbWUsIHF1ZXJ5LCBzY2hlbWEpO1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLl9tb25nb0NvbGxlY3Rpb24uZmluZEFuZE1vZGlmeShtb25nb1doZXJlLCBbXSwgbW9uZ29VcGRhdGUsIHsgbmV3OiB0cnVlIH0pKVxuICAgICAgLnRoZW4ocmVzdWx0ID0+IG1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdChjbGFzc05hbWUsIHJlc3VsdC52YWx1ZSwgc2NoZW1hKSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvci5jb2RlID09PSAxMTAwMCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUsICdBIGR1cGxpY2F0ZSB2YWx1ZSBmb3IgYSBmaWVsZCB3aXRoIHVuaXF1ZSB2YWx1ZXMgd2FzIHByb3ZpZGVkJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gSG9wZWZ1bGx5IHdlIGNhbiBnZXQgcmlkIG9mIHRoaXMuIEl0J3Mgb25seSB1c2VkIGZvciBjb25maWcgYW5kIGhvb2tzLlxuICB1cHNlcnRPbmVPYmplY3QoY2xhc3NOYW1lOiBzdHJpbmcsIHNjaGVtYTogU2NoZW1hVHlwZSwgcXVlcnk6IFF1ZXJ5VHlwZSwgdXBkYXRlOiBhbnkpIHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29VcGRhdGUgPSB0cmFuc2Zvcm1VcGRhdGUoY2xhc3NOYW1lLCB1cGRhdGUsIHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29XaGVyZSA9IHRyYW5zZm9ybVdoZXJlKGNsYXNzTmFtZSwgcXVlcnksIHNjaGVtYSk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24udXBzZXJ0T25lKG1vbmdvV2hlcmUsIG1vbmdvVXBkYXRlKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIEV4ZWN1dGVzIGEgZmluZC4gQWNjZXB0czogY2xhc3NOYW1lLCBxdWVyeSBpbiBQYXJzZSBmb3JtYXQsIGFuZCB7IHNraXAsIGxpbWl0LCBzb3J0IH0uXG4gIGZpbmQoY2xhc3NOYW1lOiBzdHJpbmcsIHNjaGVtYTogU2NoZW1hVHlwZSwgcXVlcnk6IFF1ZXJ5VHlwZSwgeyBza2lwLCBsaW1pdCwgc29ydCwga2V5cywgcmVhZFByZWZlcmVuY2UgfTogUXVlcnlPcHRpb25zKTogUHJvbWlzZTxhbnk+IHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29XaGVyZSA9IHRyYW5zZm9ybVdoZXJlKGNsYXNzTmFtZSwgcXVlcnksIHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29Tb3J0ID0gXy5tYXBLZXlzKHNvcnQsICh2YWx1ZSwgZmllbGROYW1lKSA9PiB0cmFuc2Zvcm1LZXkoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHNjaGVtYSkpO1xuICAgIGNvbnN0IG1vbmdvS2V5cyA9IF8ucmVkdWNlKGtleXMsIChtZW1vLCBrZXkpID0+IHtcbiAgICAgIG1lbW9bdHJhbnNmb3JtS2V5KGNsYXNzTmFtZSwga2V5LCBzY2hlbWEpXSA9IDE7XG4gICAgICByZXR1cm4gbWVtbztcbiAgICB9LCB7fSk7XG5cbiAgICByZWFkUHJlZmVyZW5jZSA9IHRoaXMuX3BhcnNlUmVhZFByZWZlcmVuY2UocmVhZFByZWZlcmVuY2UpO1xuICAgIHJldHVybiB0aGlzLmNyZWF0ZVRleHRJbmRleGVzSWZOZWVkZWQoY2xhc3NOYW1lLCBxdWVyeSwgc2NoZW1hKVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSkpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24uZmluZChtb25nb1doZXJlLCB7XG4gICAgICAgIHNraXAsXG4gICAgICAgIGxpbWl0LFxuICAgICAgICBzb3J0OiBtb25nb1NvcnQsXG4gICAgICAgIGtleXM6IG1vbmdvS2V5cyxcbiAgICAgICAgbWF4VGltZU1TOiB0aGlzLl9tYXhUaW1lTVMsXG4gICAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgfSkpXG4gICAgICAudGhlbihvYmplY3RzID0+IG9iamVjdHMubWFwKG9iamVjdCA9PiBtb25nb09iamVjdFRvUGFyc2VPYmplY3QoY2xhc3NOYW1lLCBvYmplY3QsIHNjaGVtYSkpKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gQ3JlYXRlIGEgdW5pcXVlIGluZGV4LiBVbmlxdWUgaW5kZXhlcyBvbiBudWxsYWJsZSBmaWVsZHMgYXJlIG5vdCBhbGxvd2VkLiBTaW5jZSB3ZSBkb24ndFxuICAvLyBjdXJyZW50bHkga25vdyB3aGljaCBmaWVsZHMgYXJlIG51bGxhYmxlIGFuZCB3aGljaCBhcmVuJ3QsIHdlIGlnbm9yZSB0aGF0IGNyaXRlcmlhLlxuICAvLyBBcyBzdWNoLCB3ZSBzaG91bGRuJ3QgZXhwb3NlIHRoaXMgZnVuY3Rpb24gdG8gdXNlcnMgb2YgcGFyc2UgdW50aWwgd2UgaGF2ZSBhbiBvdXQtb2YtYmFuZFxuICAvLyBXYXkgb2YgZGV0ZXJtaW5pbmcgaWYgYSBmaWVsZCBpcyBudWxsYWJsZS4gVW5kZWZpbmVkIGRvZXNuJ3QgY291bnQgYWdhaW5zdCB1bmlxdWVuZXNzLFxuICAvLyB3aGljaCBpcyB3aHkgd2UgdXNlIHNwYXJzZSBpbmRleGVzLlxuICBlbnN1cmVVbmlxdWVuZXNzKGNsYXNzTmFtZTogc3RyaW5nLCBzY2hlbWE6IFNjaGVtYVR5cGUsIGZpZWxkTmFtZXM6IHN0cmluZ1tdKSB7XG4gICAgc2NoZW1hID0gY29udmVydFBhcnNlU2NoZW1hVG9Nb25nb1NjaGVtYShzY2hlbWEpO1xuICAgIGNvbnN0IGluZGV4Q3JlYXRpb25SZXF1ZXN0ID0ge307XG4gICAgY29uc3QgbW9uZ29GaWVsZE5hbWVzID0gZmllbGROYW1lcy5tYXAoZmllbGROYW1lID0+IHRyYW5zZm9ybUtleShjbGFzc05hbWUsIGZpZWxkTmFtZSwgc2NoZW1hKSk7XG4gICAgbW9uZ29GaWVsZE5hbWVzLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgIGluZGV4Q3JlYXRpb25SZXF1ZXN0W2ZpZWxkTmFtZV0gPSAxO1xuICAgIH0pO1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLl9lbnN1cmVTcGFyc2VVbmlxdWVJbmRleEluQmFja2dyb3VuZChpbmRleENyZWF0aW9uUmVxdWVzdCkpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gMTEwMDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFLCAnVHJpZWQgdG8gZW5zdXJlIGZpZWxkIHVuaXF1ZW5lc3MgZm9yIGEgY2xhc3MgdGhhdCBhbHJlYWR5IGhhcyBkdXBsaWNhdGVzLicpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIFVzZWQgaW4gdGVzdHNcbiAgX3Jhd0ZpbmQoY2xhc3NOYW1lOiBzdHJpbmcsIHF1ZXJ5OiBRdWVyeVR5cGUpIHtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSkudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24uZmluZChxdWVyeSwge1xuICAgICAgbWF4VGltZU1TOiB0aGlzLl9tYXhUaW1lTVMsXG4gICAgfSkpLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gRXhlY3V0ZXMgYSBjb3VudC5cbiAgY291bnQoY2xhc3NOYW1lOiBzdHJpbmcsIHNjaGVtYTogU2NoZW1hVHlwZSwgcXVlcnk6IFF1ZXJ5VHlwZSwgcmVhZFByZWZlcmVuY2U6ID9zdHJpbmcpIHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgcmVhZFByZWZlcmVuY2UgPSB0aGlzLl9wYXJzZVJlYWRQcmVmZXJlbmNlKHJlYWRQcmVmZXJlbmNlKTtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5jb3VudCh0cmFuc2Zvcm1XaGVyZShjbGFzc05hbWUsIHF1ZXJ5LCBzY2hlbWEpLCB7XG4gICAgICAgIG1heFRpbWVNUzogdGhpcy5fbWF4VGltZU1TLFxuICAgICAgICByZWFkUHJlZmVyZW5jZSxcbiAgICAgIH0pKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgZGlzdGluY3QoY2xhc3NOYW1lOiBzdHJpbmcsIHNjaGVtYTogU2NoZW1hVHlwZSwgcXVlcnk6IFF1ZXJ5VHlwZSwgZmllbGROYW1lOiBzdHJpbmcpIHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgY29uc3QgaXNQb2ludGVyRmllbGQgPSBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiYgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdQb2ludGVyJztcbiAgICBpZiAoaXNQb2ludGVyRmllbGQpIHtcbiAgICAgIGZpZWxkTmFtZSA9IGBfcF8ke2ZpZWxkTmFtZX1gXG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLmRpc3RpbmN0KGZpZWxkTmFtZSwgdHJhbnNmb3JtV2hlcmUoY2xhc3NOYW1lLCBxdWVyeSwgc2NoZW1hKSkpXG4gICAgICAudGhlbihvYmplY3RzID0+IHtcbiAgICAgICAgb2JqZWN0cyA9IG9iamVjdHMuZmlsdGVyKChvYmopID0+IG9iaiAhPSBudWxsKTtcbiAgICAgICAgcmV0dXJuIG9iamVjdHMubWFwKG9iamVjdCA9PiB7XG4gICAgICAgICAgaWYgKGlzUG9pbnRlckZpZWxkKSB7XG4gICAgICAgICAgICBjb25zdCBmaWVsZCA9IGZpZWxkTmFtZS5zdWJzdHJpbmcoMyk7XG4gICAgICAgICAgICByZXR1cm4gdHJhbnNmb3JtUG9pbnRlclN0cmluZyhzY2hlbWEsIGZpZWxkLCBvYmplY3QpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbW9uZ29PYmplY3RUb1BhcnNlT2JqZWN0KGNsYXNzTmFtZSwgb2JqZWN0LCBzY2hlbWEpO1xuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBhZ2dyZWdhdGUoY2xhc3NOYW1lOiBzdHJpbmcsIHNjaGVtYTogYW55LCBwaXBlbGluZTogYW55LCByZWFkUHJlZmVyZW5jZTogP3N0cmluZykge1xuICAgIGxldCBpc1BvaW50ZXJGaWVsZCA9IGZhbHNlO1xuICAgIHBpcGVsaW5lID0gcGlwZWxpbmUubWFwKChzdGFnZSkgPT4ge1xuICAgICAgaWYgKHN0YWdlLiRncm91cCkge1xuICAgICAgICBzdGFnZS4kZ3JvdXAgPSB0aGlzLl9wYXJzZUFnZ3JlZ2F0ZUdyb3VwQXJncyhzY2hlbWEsIHN0YWdlLiRncm91cCk7XG4gICAgICAgIGlmIChzdGFnZS4kZ3JvdXAuX2lkICYmICh0eXBlb2Ygc3RhZ2UuJGdyb3VwLl9pZCA9PT0gJ3N0cmluZycpICYmIHN0YWdlLiRncm91cC5faWQuaW5kZXhPZignJF9wXycpID49IDApIHtcbiAgICAgICAgICBpc1BvaW50ZXJGaWVsZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChzdGFnZS4kbWF0Y2gpIHtcbiAgICAgICAgc3RhZ2UuJG1hdGNoID0gdGhpcy5fcGFyc2VBZ2dyZWdhdGVBcmdzKHNjaGVtYSwgc3RhZ2UuJG1hdGNoKTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFnZS4kcHJvamVjdCkge1xuICAgICAgICBzdGFnZS4kcHJvamVjdCA9IHRoaXMuX3BhcnNlQWdncmVnYXRlUHJvamVjdEFyZ3Moc2NoZW1hLCBzdGFnZS4kcHJvamVjdCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gc3RhZ2U7XG4gICAgfSk7XG4gICAgcmVhZFByZWZlcmVuY2UgPSB0aGlzLl9wYXJzZVJlYWRQcmVmZXJlbmNlKHJlYWRQcmVmZXJlbmNlKTtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5hZ2dyZWdhdGUocGlwZWxpbmUsIHsgcmVhZFByZWZlcmVuY2UsIG1heFRpbWVNUzogdGhpcy5fbWF4VGltZU1TIH0pKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDE2MDA2KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksIGVycm9yLm1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSlcbiAgICAgIC50aGVuKHJlc3VsdHMgPT4ge1xuICAgICAgICByZXN1bHRzLmZvckVhY2gocmVzdWx0ID0+IHtcbiAgICAgICAgICBpZiAocmVzdWx0Lmhhc093blByb3BlcnR5KCdfaWQnKSkge1xuICAgICAgICAgICAgaWYgKGlzUG9pbnRlckZpZWxkICYmIHJlc3VsdC5faWQpIHtcbiAgICAgICAgICAgICAgcmVzdWx0Ll9pZCA9IHJlc3VsdC5faWQuc3BsaXQoJyQnKVsxXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZXN1bHQuX2lkID09IG51bGwgfHwgXy5pc0VtcHR5KHJlc3VsdC5faWQpKSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5faWQgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzdWx0Lm9iamVjdElkID0gcmVzdWx0Ll9pZDtcbiAgICAgICAgICAgIGRlbGV0ZSByZXN1bHQuX2lkO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgfSlcbiAgICAgIC50aGVuKG9iamVjdHMgPT4gb2JqZWN0cy5tYXAob2JqZWN0ID0+IG1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdChjbGFzc05hbWUsIG9iamVjdCwgc2NoZW1hKSkpXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICAvLyBUaGlzIGZ1bmN0aW9uIHdpbGwgcmVjdXJzaXZlbHkgdHJhdmVyc2UgdGhlIHBpcGVsaW5lIGFuZCBjb252ZXJ0IGFueSBQb2ludGVyIG9yIERhdGUgY29sdW1ucy5cbiAgLy8gSWYgd2UgZGV0ZWN0IGEgcG9pbnRlciBjb2x1bW4gd2Ugd2lsbCByZW5hbWUgdGhlIGNvbHVtbiBiZWluZyBxdWVyaWVkIGZvciB0byBtYXRjaCB0aGUgY29sdW1uXG4gIC8vIGluIHRoZSBkYXRhYmFzZS4gV2UgYWxzbyBtb2RpZnkgdGhlIHZhbHVlIHRvIHdoYXQgd2UgZXhwZWN0IHRoZSB2YWx1ZSB0byBiZSBpbiB0aGUgZGF0YWJhc2VcbiAgLy8gYXMgd2VsbC5cbiAgLy8gRm9yIGRhdGVzLCB0aGUgZHJpdmVyIGV4cGVjdHMgYSBEYXRlIG9iamVjdCwgYnV0IHdlIGhhdmUgYSBzdHJpbmcgY29taW5nIGluLiBTbyB3ZSdsbCBjb252ZXJ0XG4gIC8vIHRoZSBzdHJpbmcgdG8gYSBEYXRlIHNvIHRoZSBkcml2ZXIgY2FuIHBlcmZvcm0gdGhlIG5lY2Vzc2FyeSBjb21wYXJpc29uLlxuICAvL1xuICAvLyBUaGUgZ29hbCBvZiB0aGlzIG1ldGhvZCBpcyB0byBsb29rIGZvciB0aGUgXCJsZWF2ZXNcIiBvZiB0aGUgcGlwZWxpbmUgYW5kIGRldGVybWluZSBpZiBpdCBuZWVkc1xuICAvLyB0byBiZSBjb252ZXJ0ZWQuIFRoZSBwaXBlbGluZSBjYW4gaGF2ZSBhIGZldyBkaWZmZXJlbnQgZm9ybXMuIEZvciBtb3JlIGRldGFpbHMsIHNlZTpcbiAgLy8gICAgIGh0dHBzOi8vZG9jcy5tb25nb2RiLmNvbS9tYW51YWwvcmVmZXJlbmNlL29wZXJhdG9yL2FnZ3JlZ2F0aW9uL1xuICAvL1xuICAvLyBJZiB0aGUgcGlwZWxpbmUgaXMgYW4gYXJyYXksIGl0IG1lYW5zIHdlIGFyZSBwcm9iYWJseSBwYXJzaW5nIGFuICckYW5kJyBvciAnJG9yJyBvcGVyYXRvci4gSW5cbiAgLy8gdGhhdCBjYXNlIHdlIG5lZWQgdG8gbG9vcCB0aHJvdWdoIGFsbCBvZiBpdCdzIGNoaWxkcmVuIHRvIGZpbmQgdGhlIGNvbHVtbnMgYmVpbmcgb3BlcmF0ZWQgb24uXG4gIC8vIElmIHRoZSBwaXBlbGluZSBpcyBhbiBvYmplY3QsIHRoZW4gd2UnbGwgbG9vcCB0aHJvdWdoIHRoZSBrZXlzIGNoZWNraW5nIHRvIHNlZSBpZiB0aGUga2V5IG5hbWVcbiAgLy8gbWF0Y2hlcyBvbmUgb2YgdGhlIHNjaGVtYSBjb2x1bW5zLiBJZiBpdCBkb2VzIG1hdGNoIGEgY29sdW1uIGFuZCB0aGUgY29sdW1uIGlzIGEgUG9pbnRlciBvclxuICAvLyBhIERhdGUsIHRoZW4gd2UnbGwgY29udmVydCB0aGUgdmFsdWUgYXMgZGVzY3JpYmVkIGFib3ZlLlxuICAvL1xuICAvLyBBcyBtdWNoIGFzIEkgaGF0ZSByZWN1cnNpb24uLi50aGlzIHNlZW1lZCBsaWtlIGEgZ29vZCBmaXQgZm9yIGl0LiBXZSdyZSBlc3NlbnRpYWxseSB0cmF2ZXJzaW5nXG4gIC8vIGRvd24gYSB0cmVlIHRvIGZpbmQgYSBcImxlYWYgbm9kZVwiIGFuZCBjaGVja2luZyB0byBzZWUgaWYgaXQgbmVlZHMgdG8gYmUgY29udmVydGVkLlxuICBfcGFyc2VBZ2dyZWdhdGVBcmdzKHNjaGVtYTogYW55LCBwaXBlbGluZTogYW55KTogYW55IHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShwaXBlbGluZSkpIHtcbiAgICAgIHJldHVybiBwaXBlbGluZS5tYXAoKHZhbHVlKSA9PiB0aGlzLl9wYXJzZUFnZ3JlZ2F0ZUFyZ3Moc2NoZW1hLCB2YWx1ZSkpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHBpcGVsaW5lID09PSAnb2JqZWN0Jykge1xuICAgICAgY29uc3QgcmV0dXJuVmFsdWUgPSB7fTtcbiAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gcGlwZWxpbmUpIHtcbiAgICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGRdICYmIHNjaGVtYS5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgICAgIGlmICh0eXBlb2YgcGlwZWxpbmVbZmllbGRdID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgLy8gUGFzcyBvYmplY3RzIGRvd24gdG8gTW9uZ29EQi4uLnRoaXMgaXMgbW9yZSB0aGFuIGxpa2VseSBhbiAkZXhpc3RzIG9wZXJhdG9yLlxuICAgICAgICAgICAgcmV0dXJuVmFsdWVbYF9wXyR7ZmllbGR9YF0gPSBwaXBlbGluZVtmaWVsZF07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVyblZhbHVlW2BfcF8ke2ZpZWxkfWBdID0gYCR7c2NoZW1hLmZpZWxkc1tmaWVsZF0udGFyZ2V0Q2xhc3N9JCR7cGlwZWxpbmVbZmllbGRdfWA7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHNjaGVtYS5maWVsZHNbZmllbGRdICYmIHNjaGVtYS5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdEYXRlJykge1xuICAgICAgICAgIHJldHVyblZhbHVlW2ZpZWxkXSA9IHRoaXMuX2NvbnZlcnRUb0RhdGUocGlwZWxpbmVbZmllbGRdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm5WYWx1ZVtmaWVsZF0gPSB0aGlzLl9wYXJzZUFnZ3JlZ2F0ZUFyZ3Moc2NoZW1hLCBwaXBlbGluZVtmaWVsZF0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZpZWxkID09PSAnb2JqZWN0SWQnKSB7XG4gICAgICAgICAgcmV0dXJuVmFsdWVbJ19pZCddID0gcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgICAgIGRlbGV0ZSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICAgIH0gZWxzZSBpZiAoZmllbGQgPT09ICdjcmVhdGVkQXQnKSB7XG4gICAgICAgICAgcmV0dXJuVmFsdWVbJ19jcmVhdGVkX2F0J10gPSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICAgICAgZGVsZXRlIHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgICAgfSBlbHNlIGlmIChmaWVsZCA9PT0gJ3VwZGF0ZWRBdCcpIHtcbiAgICAgICAgICByZXR1cm5WYWx1ZVsnX3VwZGF0ZWRfYXQnXSA9IHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgICAgICBkZWxldGUgcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gICAgfVxuICAgIHJldHVybiBwaXBlbGluZTtcbiAgfVxuXG4gIC8vIFRoaXMgZnVuY3Rpb24gaXMgc2xpZ2h0bHkgZGlmZmVyZW50IHRoYW4gdGhlIG9uZSBhYm92ZS4gUmF0aGVyIHRoYW4gdHJ5aW5nIHRvIGNvbWJpbmUgdGhlc2VcbiAgLy8gdHdvIGZ1bmN0aW9ucyBhbmQgbWFraW5nIHRoZSBjb2RlIGV2ZW4gaGFyZGVyIHRvIHVuZGVyc3RhbmQsIEkgZGVjaWRlZCB0byBzcGxpdCBpdCB1cC4gVGhlXG4gIC8vIGRpZmZlcmVuY2Ugd2l0aCB0aGlzIGZ1bmN0aW9uIGlzIHdlIGFyZSBub3QgdHJhbnNmb3JtaW5nIHRoZSB2YWx1ZXMsIG9ubHkgdGhlIGtleXMgb2YgdGhlXG4gIC8vIHBpcGVsaW5lLlxuICBfcGFyc2VBZ2dyZWdhdGVQcm9qZWN0QXJncyhzY2hlbWE6IGFueSwgcGlwZWxpbmU6IGFueSk6IGFueSB7XG4gICAgY29uc3QgcmV0dXJuVmFsdWUgPSB7fTtcbiAgICBmb3IgKGNvbnN0IGZpZWxkIGluIHBpcGVsaW5lKSB7XG4gICAgICBpZiAoc2NoZW1hLmZpZWxkc1tmaWVsZF0gJiYgc2NoZW1hLmZpZWxkc1tmaWVsZF0udHlwZSA9PT0gJ1BvaW50ZXInKSB7XG4gICAgICAgIHJldHVyblZhbHVlW2BfcF8ke2ZpZWxkfWBdID0gcGlwZWxpbmVbZmllbGRdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuVmFsdWVbZmllbGRdID0gdGhpcy5fcGFyc2VBZ2dyZWdhdGVBcmdzKHNjaGVtYSwgcGlwZWxpbmVbZmllbGRdKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGZpZWxkID09PSAnb2JqZWN0SWQnKSB7XG4gICAgICAgIHJldHVyblZhbHVlWydfaWQnXSA9IHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgICAgZGVsZXRlIHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgIH0gZWxzZSBpZiAoZmllbGQgPT09ICdjcmVhdGVkQXQnKSB7XG4gICAgICAgIHJldHVyblZhbHVlWydfY3JlYXRlZF9hdCddID0gcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgICBkZWxldGUgcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZCA9PT0gJ3VwZGF0ZWRBdCcpIHtcbiAgICAgICAgcmV0dXJuVmFsdWVbJ191cGRhdGVkX2F0J10gPSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICAgIGRlbGV0ZSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgfVxuXG4gIC8vIFRoaXMgZnVuY3Rpb24gaXMgc2xpZ2h0bHkgZGlmZmVyZW50IHRoYW4gdGhlIHR3byBhYm92ZS4gTW9uZ29EQiAkZ3JvdXAgYWdncmVnYXRlIGxvb2tzIGxpa2U6XG4gIC8vICAgICB7ICRncm91cDogeyBfaWQ6IDxleHByZXNzaW9uPiwgPGZpZWxkMT46IHsgPGFjY3VtdWxhdG9yMT4gOiA8ZXhwcmVzc2lvbjE+IH0sIC4uLiB9IH1cbiAgLy8gVGhlIDxleHByZXNzaW9uPiBjb3VsZCBiZSBhIGNvbHVtbiBuYW1lLCBwcmVmaXhlZCB3aXRoIHRoZSAnJCcgY2hhcmFjdGVyLiBXZSdsbCBsb29rIGZvclxuICAvLyB0aGVzZSA8ZXhwcmVzc2lvbj4gYW5kIGNoZWNrIHRvIHNlZSBpZiBpdCBpcyBhICdQb2ludGVyJyBvciBpZiBpdCdzIG9uZSBvZiBjcmVhdGVkQXQsXG4gIC8vIHVwZGF0ZWRBdCBvciBvYmplY3RJZCBhbmQgY2hhbmdlIGl0IGFjY29yZGluZ2x5LlxuICBfcGFyc2VBZ2dyZWdhdGVHcm91cEFyZ3Moc2NoZW1hOiBhbnksIHBpcGVsaW5lOiBhbnkpOiBhbnkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHBpcGVsaW5lKSkge1xuICAgICAgcmV0dXJuIHBpcGVsaW5lLm1hcCgodmFsdWUpID0+IHRoaXMuX3BhcnNlQWdncmVnYXRlR3JvdXBBcmdzKHNjaGVtYSwgdmFsdWUpKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBwaXBlbGluZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGNvbnN0IHJldHVyblZhbHVlID0ge307XG4gICAgICBmb3IgKGNvbnN0IGZpZWxkIGluIHBpcGVsaW5lKSB7XG4gICAgICAgIHJldHVyblZhbHVlW2ZpZWxkXSA9IHRoaXMuX3BhcnNlQWdncmVnYXRlR3JvdXBBcmdzKHNjaGVtYSwgcGlwZWxpbmVbZmllbGRdKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBwaXBlbGluZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbnN0IGZpZWxkID0gcGlwZWxpbmUuc3Vic3RyaW5nKDEpO1xuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGRdICYmIHNjaGVtYS5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgICByZXR1cm4gYCRfcF8ke2ZpZWxkfWA7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkID09ICdjcmVhdGVkQXQnKSB7XG4gICAgICAgIHJldHVybiAnJF9jcmVhdGVkX2F0JztcbiAgICAgIH0gZWxzZSBpZiAoZmllbGQgPT0gJ3VwZGF0ZWRBdCcpIHtcbiAgICAgICAgcmV0dXJuICckX3VwZGF0ZWRfYXQnO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcGlwZWxpbmU7XG4gIH1cblxuICAvLyBUaGlzIGZ1bmN0aW9uIHdpbGwgYXR0ZW1wdCB0byBjb252ZXJ0IHRoZSBwcm92aWRlZCB2YWx1ZSB0byBhIERhdGUgb2JqZWN0LiBTaW5jZSB0aGlzIGlzIHBhcnRcbiAgLy8gb2YgYW4gYWdncmVnYXRpb24gcGlwZWxpbmUsIHRoZSB2YWx1ZSBjYW4gZWl0aGVyIGJlIGEgc3RyaW5nIG9yIGl0IGNhbiBiZSBhbm90aGVyIG9iamVjdCB3aXRoXG4gIC8vIGFuIG9wZXJhdG9yIGluIGl0IChsaWtlICRndCwgJGx0LCBldGMpLiBCZWNhdXNlIG9mIHRoaXMgSSBmZWx0IGl0IHdhcyBlYXNpZXIgdG8gbWFrZSB0aGlzIGFcbiAgLy8gcmVjdXJzaXZlIG1ldGhvZCB0byB0cmF2ZXJzZSBkb3duIHRvIHRoZSBcImxlYWYgbm9kZVwiIHdoaWNoIGlzIGdvaW5nIHRvIGJlIHRoZSBzdHJpbmcuXG4gIF9jb252ZXJ0VG9EYXRlKHZhbHVlOiBhbnkpOiBhbnkge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gbmV3IERhdGUodmFsdWUpO1xuICAgIH1cblxuICAgIGNvbnN0IHJldHVyblZhbHVlID0ge31cbiAgICBmb3IgKGNvbnN0IGZpZWxkIGluIHZhbHVlKSB7XG4gICAgICByZXR1cm5WYWx1ZVtmaWVsZF0gPSB0aGlzLl9jb252ZXJ0VG9EYXRlKHZhbHVlW2ZpZWxkXSlcbiAgICB9XG4gICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICB9XG5cbiAgX3BhcnNlUmVhZFByZWZlcmVuY2UocmVhZFByZWZlcmVuY2U6ID9zdHJpbmcpOiA/c3RyaW5nIHtcbiAgICBzd2l0Y2ggKHJlYWRQcmVmZXJlbmNlKSB7XG4gICAgY2FzZSAnUFJJTUFSWSc6XG4gICAgICByZWFkUHJlZmVyZW5jZSA9IFJlYWRQcmVmZXJlbmNlLlBSSU1BUlk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdQUklNQVJZX1BSRUZFUlJFRCc6XG4gICAgICByZWFkUHJlZmVyZW5jZSA9IFJlYWRQcmVmZXJlbmNlLlBSSU1BUllfUFJFRkVSUkVEO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnU0VDT05EQVJZJzpcbiAgICAgIHJlYWRQcmVmZXJlbmNlID0gUmVhZFByZWZlcmVuY2UuU0VDT05EQVJZO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnU0VDT05EQVJZX1BSRUZFUlJFRCc6XG4gICAgICByZWFkUHJlZmVyZW5jZSA9IFJlYWRQcmVmZXJlbmNlLlNFQ09OREFSWV9QUkVGRVJSRUQ7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdORUFSRVNUJzpcbiAgICAgIHJlYWRQcmVmZXJlbmNlID0gUmVhZFByZWZlcmVuY2UuTkVBUkVTVDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgdW5kZWZpbmVkOlxuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnTm90IHN1cHBvcnRlZCByZWFkIHByZWZlcmVuY2UuJyk7XG4gICAgfVxuICAgIHJldHVybiByZWFkUHJlZmVyZW5jZTtcbiAgfVxuXG4gIHBlcmZvcm1Jbml0aWFsaXphdGlvbigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBjcmVhdGVJbmRleChjbGFzc05hbWU6IHN0cmluZywgaW5kZXg6IGFueSkge1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLl9tb25nb0NvbGxlY3Rpb24uY3JlYXRlSW5kZXgoaW5kZXgpKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgY3JlYXRlSW5kZXhlcyhjbGFzc05hbWU6IHN0cmluZywgaW5kZXhlczogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24uX21vbmdvQ29sbGVjdGlvbi5jcmVhdGVJbmRleGVzKGluZGV4ZXMpKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgY3JlYXRlSW5kZXhlc0lmTmVlZGVkKGNsYXNzTmFtZTogc3RyaW5nLCBmaWVsZE5hbWU6IHN0cmluZywgdHlwZTogYW55KSB7XG4gICAgaWYgKHR5cGUgJiYgdHlwZS50eXBlID09PSAnUG9seWdvbicpIHtcbiAgICAgIGNvbnN0IGluZGV4ID0ge1xuICAgICAgICBbZmllbGROYW1lXTogJzJkc3BoZXJlJ1xuICAgICAgfTtcbiAgICAgIHJldHVybiB0aGlzLmNyZWF0ZUluZGV4KGNsYXNzTmFtZSwgaW5kZXgpO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBjcmVhdGVUZXh0SW5kZXhlc0lmTmVlZGVkKGNsYXNzTmFtZTogc3RyaW5nLCBxdWVyeTogUXVlcnlUeXBlLCBzY2hlbWE6IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGZvcihjb25zdCBmaWVsZE5hbWUgaW4gcXVlcnkpIHtcbiAgICAgIGlmICghcXVlcnlbZmllbGROYW1lXSB8fCAhcXVlcnlbZmllbGROYW1lXS4kdGV4dCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGV4aXN0aW5nSW5kZXhlcyA9IHNjaGVtYS5pbmRleGVzO1xuICAgICAgZm9yIChjb25zdCBrZXkgaW4gZXhpc3RpbmdJbmRleGVzKSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gZXhpc3RpbmdJbmRleGVzW2tleV07XG4gICAgICAgIGlmIChpbmRleC5oYXNPd25Qcm9wZXJ0eShmaWVsZE5hbWUpKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCBpbmRleE5hbWUgPSBgJHtmaWVsZE5hbWV9X3RleHRgO1xuICAgICAgY29uc3QgdGV4dEluZGV4ID0ge1xuICAgICAgICBbaW5kZXhOYW1lXTogeyBbZmllbGROYW1lXTogJ3RleHQnIH1cbiAgICAgIH07XG4gICAgICByZXR1cm4gdGhpcy5zZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdChjbGFzc05hbWUsIHRleHRJbmRleCwgZXhpc3RpbmdJbmRleGVzLCBzY2hlbWEuZmllbGRzKVxuICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDg1KSB7IC8vIEluZGV4IGV4aXN0IHdpdGggZGlmZmVyZW50IG9wdGlvbnNcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNldEluZGV4ZXNGcm9tTW9uZ28oY2xhc3NOYW1lKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBnZXRJbmRleGVzKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24uX21vbmdvQ29sbGVjdGlvbi5pbmRleGVzKCkpXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBkcm9wSW5kZXgoY2xhc3NOYW1lOiBzdHJpbmcsIGluZGV4OiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5fbW9uZ29Db2xsZWN0aW9uLmRyb3BJbmRleChpbmRleCkpXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBkcm9wQWxsSW5kZXhlcyhjbGFzc05hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLl9tb25nb0NvbGxlY3Rpb24uZHJvcEluZGV4ZXMoKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIHVwZGF0ZVNjaGVtYVdpdGhJbmRleGVzKCk6IFByb21pc2U8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0QWxsQ2xhc3NlcygpXG4gICAgICAudGhlbigoY2xhc3NlcykgPT4ge1xuICAgICAgICBjb25zdCBwcm9taXNlcyA9IGNsYXNzZXMubWFwKChzY2hlbWEpID0+IHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5zZXRJbmRleGVzRnJvbU1vbmdvKHNjaGVtYS5jbGFzc05hbWUpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTW9uZ29TdG9yYWdlQWRhcHRlcjtcbiJdfQ==
|
|
923
|
+
var _default = exports.default = MongoStorageAdapter;
|
|
924
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbW9uZ29kYlVybCIsInJlcXVpcmUiLCJfU3RvcmFnZUFkYXB0ZXIiLCJfTW9uZ29Db2xsZWN0aW9uIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl9Nb25nb1NjaGVtYUNvbGxlY3Rpb24iLCJfTW9uZ29UcmFuc2Zvcm0iLCJfbm9kZSIsIl9sb2Rhc2giLCJfZGVmYXVsdHMiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsIl9sb2dnZXIiLCJfVXRpbHMiLCJlIiwidCIsIldlYWtNYXAiLCJyIiwibiIsIl9fZXNNb2R1bGUiLCJvIiwiaSIsImYiLCJfX3Byb3RvX18iLCJkZWZhdWx0IiwiaGFzIiwiZ2V0Iiwic2V0IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJtb25nb2RiIiwiTW9uZ29DbGllbnQiLCJSZWFkUHJlZmVyZW5jZSIsIk1vbmdvU2NoZW1hQ29sbGVjdGlvbk5hbWUiLCJzdG9yYWdlQWRhcHRlckFsbENvbGxlY3Rpb25zIiwibW9uZ29BZGFwdGVyIiwiY29ubmVjdCIsInRoZW4iLCJkYXRhYmFzZSIsImNvbGxlY3Rpb25zIiwiZmlsdGVyIiwiY29sbGVjdGlvbiIsIm5hbWVzcGFjZSIsIm1hdGNoIiwiY29sbGVjdGlvbk5hbWUiLCJpbmRleE9mIiwiX2NvbGxlY3Rpb25QcmVmaXgiLCJjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hIiwic2NoZW1hIiwiZmllbGRzIiwiX3JwZXJtIiwiX3dwZXJtIiwiY2xhc3NOYW1lIiwiX2hhc2hlZF9wYXNzd29yZCIsIm1vbmdvU2NoZW1hRnJvbUZpZWxkc0FuZENsYXNzTmFtZUFuZENMUCIsImNsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsImluZGV4ZXMiLCJtb25nb09iamVjdCIsIl9pZCIsIm9iamVjdElkIiwidXBkYXRlZEF0IiwiY3JlYXRlZEF0IiwiX21ldGFkYXRhIiwidW5kZWZpbmVkIiwiZmllbGROYW1lIiwidHlwZSIsInRhcmdldENsYXNzIiwiZmllbGRPcHRpb25zIiwiTW9uZ29TY2hlbWFDb2xsZWN0aW9uIiwicGFyc2VGaWVsZFR5cGVUb01vbmdvRmllbGRUeXBlIiwia2V5cyIsImxlbmd0aCIsImZpZWxkc19vcHRpb25zIiwiY2xhc3NfcGVybWlzc2lvbnMiLCJ2YWxpZGF0ZUV4cGxhaW5WYWx1ZSIsImV4cGxhaW4iLCJleHBsYWluQWxsb3dlZFZhbHVlcyIsImluY2x1ZGVzIiwiUGFyc2UiLCJFcnJvciIsIklOVkFMSURfUVVFUlkiLCJNb25nb1N0b3JhZ2VBZGFwdGVyIiwiY29uc3RydWN0b3IiLCJ1cmkiLCJkZWZhdWx0cyIsIkRlZmF1bHRNb25nb1VSSSIsImNvbGxlY3Rpb25QcmVmaXgiLCJtb25nb09wdGlvbnMiLCJfdXJpIiwiX29uY2hhbmdlIiwiX21heFRpbWVNUyIsIm1heFRpbWVNUyIsImNhblNvcnRPbkpvaW5UYWJsZXMiLCJlbmFibGVTY2hlbWFIb29rcyIsInNjaGVtYUNhY2hlVHRsIiwiZGlzYWJsZUluZGV4RmllbGRWYWxpZGF0aW9uIiwiX2xvZ0NsaWVudEV2ZW50cyIsImxvZ0NsaWVudEV2ZW50cyIsIl9tb25nb09wdGlvbnMiLCJrZXkiLCJQYXJzZVNlcnZlckRhdGFiYXNlT3B0aW9ucyIsIndhdGNoIiwiY2FsbGJhY2siLCJjb25uZWN0aW9uUHJvbWlzZSIsImVuY29kZWRVcmkiLCJmb3JtYXRVcmwiLCJwYXJzZVVybCIsImNsaWVudCIsIm9wdGlvbnMiLCJzIiwiZGIiLCJkYk5hbWUiLCJvbiIsIkFycmF5IiwiaXNBcnJheSIsImZvckVhY2giLCJldmVudENvbmZpZyIsIm5hbWUiLCJldmVudCIsImxvZ0RhdGEiLCJrZXlQYXRoIiwiXyIsImxvZ0xldmVsIiwibG9nZ2VyIiwibG9nTWVzc2FnZSIsIkpTT04iLCJzdHJpbmdpZnkiLCJVdGlscyIsImdldENpcmN1bGFyUmVwbGFjZXIiLCJjYXRjaCIsImVyciIsIlByb21pc2UiLCJyZWplY3QiLCJoYW5kbGVFcnJvciIsImVycm9yIiwiY29kZSIsImhhbmRsZVNodXRkb3duIiwiY2xvc2UiLCJfYWRhcHRpdmVDb2xsZWN0aW9uIiwicmF3Q29sbGVjdGlvbiIsIk1vbmdvQ29sbGVjdGlvbiIsIl9zY2hlbWFDb2xsZWN0aW9uIiwiX3N0cmVhbSIsIl9tb25nb0NvbGxlY3Rpb24iLCJjbGFzc0V4aXN0cyIsImxpc3RDb2xsZWN0aW9ucyIsInRvQXJyYXkiLCJzZXRDbGFzc0xldmVsUGVybWlzc2lvbnMiLCJDTFBzIiwic2NoZW1hQ29sbGVjdGlvbiIsInVwZGF0ZVNjaGVtYSIsIiRzZXQiLCJzZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdCIsInN1Ym1pdHRlZEluZGV4ZXMiLCJleGlzdGluZ0luZGV4ZXMiLCJyZXNvbHZlIiwiX2lkXyIsImRlbGV0ZVByb21pc2VzIiwiaW5zZXJ0ZWRJbmRleGVzIiwiZmllbGQiLCJfX29wIiwicHJvbWlzZSIsImRyb3BJbmRleCIsInB1c2giLCJwcm90b3R5cGUiLCJyZXBsYWNlIiwiaW5zZXJ0UHJvbWlzZSIsImNyZWF0ZUluZGV4ZXMiLCJhbGwiLCJzZXRJbmRleGVzRnJvbU1vbmdvIiwiZ2V0SW5kZXhlcyIsInJlZHVjZSIsIm9iaiIsImluZGV4IiwiX2Z0cyIsIl9mdHN4Iiwid2VpZ2h0cyIsImNyZWF0ZUNsYXNzIiwiaW5zZXJ0U2NoZW1hIiwidXBkYXRlRmllbGRPcHRpb25zIiwiYWRkRmllbGRJZk5vdEV4aXN0cyIsImNyZWF0ZUluZGV4ZXNJZk5lZWRlZCIsImRlbGV0ZUNsYXNzIiwiZHJvcCIsIm1lc3NhZ2UiLCJmaW5kQW5kRGVsZXRlU2NoZW1hIiwiZGVsZXRlQWxsQ2xhc3NlcyIsImZhc3QiLCJtYXAiLCJkZWxldGVNYW55IiwiZGVsZXRlRmllbGRzIiwiZmllbGROYW1lcyIsIm1vbmdvRm9ybWF0TmFtZXMiLCJjb2xsZWN0aW9uVXBkYXRlIiwiJHVuc2V0IiwiY29sbGVjdGlvbkZpbHRlciIsIiRvciIsIiRleGlzdHMiLCJzY2hlbWFVcGRhdGUiLCJ1cGRhdGVNYW55IiwiZ2V0QWxsQ2xhc3NlcyIsInNjaGVtYXNDb2xsZWN0aW9uIiwiX2ZldGNoQWxsU2NoZW1hc0Zyb21fU0NIRU1BIiwiZ2V0Q2xhc3MiLCJfZmV0Y2hPbmVTY2hlbWFGcm9tX1NDSEVNQSIsImNyZWF0ZU9iamVjdCIsIm9iamVjdCIsInRyYW5zYWN0aW9uYWxTZXNzaW9uIiwicGFyc2VPYmplY3RUb01vbmdvT2JqZWN0Rm9yQ3JlYXRlIiwiaW5zZXJ0T25lIiwib3BzIiwiRFVQTElDQVRFX1ZBTFVFIiwidW5kZXJseWluZ0Vycm9yIiwibWF0Y2hlcyIsInVzZXJJbmZvIiwiZHVwbGljYXRlZF9maWVsZCIsImRlbGV0ZU9iamVjdHNCeVF1ZXJ5IiwicXVlcnkiLCJtb25nb1doZXJlIiwidHJhbnNmb3JtV2hlcmUiLCJkZWxldGVkQ291bnQiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwiSU5URVJOQUxfU0VSVkVSX0VSUk9SIiwidXBkYXRlT2JqZWN0c0J5UXVlcnkiLCJ1cGRhdGUiLCJtb25nb1VwZGF0ZSIsInRyYW5zZm9ybVVwZGF0ZSIsImZpbmRPbmVBbmRVcGRhdGUiLCJyZXR1cm5Eb2N1bWVudCIsInNlc3Npb24iLCJyZXN1bHQiLCJtb25nb09iamVjdFRvUGFyc2VPYmplY3QiLCJ1cHNlcnRPbmVPYmplY3QiLCJ1cHNlcnRPbmUiLCJmaW5kIiwic2tpcCIsImxpbWl0Iiwic29ydCIsInJlYWRQcmVmZXJlbmNlIiwiaGludCIsImNhc2VJbnNlbnNpdGl2ZSIsImNvbW1lbnQiLCJtb25nb1NvcnQiLCJtYXBLZXlzIiwidmFsdWUiLCJ0cmFuc2Zvcm1LZXkiLCJtb25nb0tleXMiLCJtZW1vIiwiX3BhcnNlUmVhZFByZWZlcmVuY2UiLCJjcmVhdGVUZXh0SW5kZXhlc0lmTmVlZGVkIiwib2JqZWN0cyIsImVuc3VyZUluZGV4IiwiaW5kZXhOYW1lIiwiaW5kZXhDcmVhdGlvblJlcXVlc3QiLCJtb25nb0ZpZWxkTmFtZXMiLCJpbmRleFR5cGUiLCJkZWZhdWx0T3B0aW9ucyIsImJhY2tncm91bmQiLCJzcGFyc2UiLCJpbmRleE5hbWVPcHRpb25zIiwidHRsT3B0aW9ucyIsInR0bCIsImV4cGlyZUFmdGVyU2Vjb25kcyIsInNwYXJzZU9wdGlvbnMiLCJjYXNlSW5zZW5zaXRpdmVPcHRpb25zIiwiY29sbGF0aW9uIiwiY2FzZUluc2Vuc2l0aXZlQ29sbGF0aW9uIiwiaW5kZXhPcHRpb25zIiwiY3JlYXRlSW5kZXgiLCJlbnN1cmVVbmlxdWVuZXNzIiwiX2Vuc3VyZVNwYXJzZVVuaXF1ZUluZGV4SW5CYWNrZ3JvdW5kIiwiX3Jhd0ZpbmQiLCJjb3VudCIsIl9lc3RpbWF0ZSIsImRpc3RpbmN0IiwiaXNQb2ludGVyRmllbGQiLCJ0cmFuc2Zvcm1GaWVsZCIsInRyYW5zZm9ybVBvaW50ZXJTdHJpbmciLCJhZ2dyZWdhdGUiLCJwaXBlbGluZSIsInN0YWdlIiwiJGdyb3VwIiwiX3BhcnNlQWdncmVnYXRlR3JvdXBBcmdzIiwiJG1hdGNoIiwiX3BhcnNlQWdncmVnYXRlQXJncyIsIiRwcm9qZWN0IiwiX3BhcnNlQWdncmVnYXRlUHJvamVjdEFyZ3MiLCIkZ2VvTmVhciIsInJlc3VsdHMiLCJzcGxpdCIsImlzRW1wdHkiLCJyZXR1cm5WYWx1ZSIsIl9jb252ZXJ0VG9EYXRlIiwic3Vic3RyaW5nIiwiRGF0ZSIsImlzTmFOIiwicGFyc2UiLCJ0b1VwcGVyQ2FzZSIsIlBSSU1BUlkiLCJQUklNQVJZX1BSRUZFUlJFRCIsIlNFQ09OREFSWSIsIlNFQ09OREFSWV9QUkVGRVJSRUQiLCJORUFSRVNUIiwicGVyZm9ybUluaXRpYWxpemF0aW9uIiwiJHRleHQiLCJ0ZXh0SW5kZXgiLCJkcm9wQWxsSW5kZXhlcyIsImRyb3BJbmRleGVzIiwidXBkYXRlU2NoZW1hV2l0aEluZGV4ZXMiLCJjbGFzc2VzIiwicHJvbWlzZXMiLCJjcmVhdGVUcmFuc2FjdGlvbmFsU2Vzc2lvbiIsInRyYW5zYWN0aW9uYWxTZWN0aW9uIiwic3RhcnRTZXNzaW9uIiwic3RhcnRUcmFuc2FjdGlvbiIsImNvbW1pdFRyYW5zYWN0aW9uYWxTZXNzaW9uIiwiY29tbWl0IiwicmV0cmllcyIsImNvbW1pdFRyYW5zYWN0aW9uIiwiaGFzRXJyb3JMYWJlbCIsImVuZFNlc3Npb24iLCJhYm9ydFRyYW5zYWN0aW9uYWxTZXNzaW9uIiwiYWJvcnRUcmFuc2FjdGlvbiIsImV4cG9ydHMiLCJfZGVmYXVsdCJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9BZGFwdGVycy9TdG9yYWdlL01vbmdvL01vbmdvU3RvcmFnZUFkYXB0ZXIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCB7IGZvcm1hdCBhcyBmb3JtYXRVcmwsIHBhcnNlIGFzIHBhcnNlVXJsIH0gZnJvbSAnLi4vLi4vLi4vdmVuZG9yL21vbmdvZGJVcmwnO1xuaW1wb3J0IHR5cGUgeyBRdWVyeU9wdGlvbnMsIFF1ZXJ5VHlwZSwgU2NoZW1hVHlwZSwgU3RvcmFnZUNsYXNzIH0gZnJvbSAnLi4vU3RvcmFnZUFkYXB0ZXInO1xuaW1wb3J0IHsgU3RvcmFnZUFkYXB0ZXIgfSBmcm9tICcuLi9TdG9yYWdlQWRhcHRlcic7XG5pbXBvcnQgTW9uZ29Db2xsZWN0aW9uIGZyb20gJy4vTW9uZ29Db2xsZWN0aW9uJztcbmltcG9ydCBNb25nb1NjaGVtYUNvbGxlY3Rpb24gZnJvbSAnLi9Nb25nb1NjaGVtYUNvbGxlY3Rpb24nO1xuaW1wb3J0IHtcbiAgbW9uZ29PYmplY3RUb1BhcnNlT2JqZWN0LFxuICBwYXJzZU9iamVjdFRvTW9uZ29PYmplY3RGb3JDcmVhdGUsXG4gIHRyYW5zZm9ybUtleSxcbiAgdHJhbnNmb3JtUG9pbnRlclN0cmluZyxcbiAgdHJhbnNmb3JtVXBkYXRlLFxuICB0cmFuc2Zvcm1XaGVyZSxcbn0gZnJvbSAnLi9Nb25nb1RyYW5zZm9ybSc7XG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmltcG9ydCBQYXJzZSBmcm9tICdwYXJzZS9ub2RlJztcbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBkZWZhdWx0cywgeyBQYXJzZVNlcnZlckRhdGFiYXNlT3B0aW9ucyB9IGZyb20gJy4uLy4uLy4uL2RlZmF1bHRzJztcbmltcG9ydCBsb2dnZXIgZnJvbSAnLi4vLi4vLi4vbG9nZ2VyJztcbmltcG9ydCBVdGlscyBmcm9tICcuLi8uLi8uLi9VdGlscyc7XG5cbi8vIEBmbG93LWRpc2FibGUtbmV4dFxuY29uc3QgbW9uZ29kYiA9IHJlcXVpcmUoJ21vbmdvZGInKTtcbmNvbnN0IE1vbmdvQ2xpZW50ID0gbW9uZ29kYi5Nb25nb0NsaWVudDtcbmNvbnN0IFJlYWRQcmVmZXJlbmNlID0gbW9uZ29kYi5SZWFkUHJlZmVyZW5jZTtcblxuY29uc3QgTW9uZ29TY2hlbWFDb2xsZWN0aW9uTmFtZSA9ICdfU0NIRU1BJztcblxuY29uc3Qgc3RvcmFnZUFkYXB0ZXJBbGxDb2xsZWN0aW9ucyA9IG1vbmdvQWRhcHRlciA9PiB7XG4gIHJldHVybiBtb25nb0FkYXB0ZXJcbiAgICAuY29ubmVjdCgpXG4gICAgLnRoZW4oKCkgPT4gbW9uZ29BZGFwdGVyLmRhdGFiYXNlLmNvbGxlY3Rpb25zKCkpXG4gICAgLnRoZW4oY29sbGVjdGlvbnMgPT4ge1xuICAgICAgcmV0dXJuIGNvbGxlY3Rpb25zLmZpbHRlcihjb2xsZWN0aW9uID0+IHtcbiAgICAgICAgaWYgKGNvbGxlY3Rpb24ubmFtZXNwYWNlLm1hdGNoKC9cXC5zeXN0ZW1cXC4vKSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBUT0RPOiBJZiB5b3UgaGF2ZSBvbmUgYXBwIHdpdGggYSBjb2xsZWN0aW9uIHByZWZpeCB0aGF0IGhhcHBlbnMgdG8gYmUgYSBwcmVmaXggb2YgYW5vdGhlclxuICAgICAgICAvLyBhcHBzIHByZWZpeCwgdGhpcyB3aWxsIGdvIHZlcnkgdmVyeSBiYWRseS4gV2Ugc2hvdWxkIGZpeCB0aGF0IHNvbWVob3cuXG4gICAgICAgIHJldHVybiBjb2xsZWN0aW9uLmNvbGxlY3Rpb25OYW1lLmluZGV4T2YobW9uZ29BZGFwdGVyLl9jb2xsZWN0aW9uUHJlZml4KSA9PSAwO1xuICAgICAgfSk7XG4gICAgfSk7XG59O1xuXG5jb25zdCBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hID0gKHsgLi4uc2NoZW1hIH0pID0+IHtcbiAgZGVsZXRlIHNjaGVtYS5maWVsZHMuX3JwZXJtO1xuICBkZWxldGUgc2NoZW1hLmZpZWxkcy5fd3Blcm07XG5cbiAgaWYgKHNjaGVtYS5jbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICAvLyBMZWdhY3kgbW9uZ28gYWRhcHRlciBrbm93cyBhYm91dCB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHBhc3N3b3JkIGFuZCBfaGFzaGVkX3Bhc3N3b3JkLlxuICAgIC8vIEZ1dHVyZSBkYXRhYmFzZSBhZGFwdGVycyB3aWxsIG9ubHkga25vdyBhYm91dCBfaGFzaGVkX3Bhc3N3b3JkLlxuICAgIC8vIE5vdGU6IFBhcnNlIFNlcnZlciB3aWxsIGJyaW5nIGJhY2sgcGFzc3dvcmQgd2l0aCBpbmplY3REZWZhdWx0U2NoZW1hLCBzbyB3ZSBkb24ndCBuZWVkXG4gICAgLy8gdG8gYWRkIF9oYXNoZWRfcGFzc3dvcmQgYmFjayBldmVyLlxuICAgIGRlbGV0ZSBzY2hlbWEuZmllbGRzLl9oYXNoZWRfcGFzc3dvcmQ7XG4gIH1cblxuICByZXR1cm4gc2NoZW1hO1xufTtcblxuLy8gUmV0dXJucyB7IGNvZGUsIGVycm9yIH0gaWYgaW52YWxpZCwgb3IgeyByZXN1bHQgfSwgYW4gb2JqZWN0XG4vLyBzdWl0YWJsZSBmb3IgaW5zZXJ0aW5nIGludG8gX1NDSEVNQSBjb2xsZWN0aW9uLCBvdGhlcndpc2UuXG5jb25zdCBtb25nb1NjaGVtYUZyb21GaWVsZHNBbmRDbGFzc05hbWVBbmRDTFAgPSAoXG4gIGZpZWxkcyxcbiAgY2xhc3NOYW1lLFxuICBjbGFzc0xldmVsUGVybWlzc2lvbnMsXG4gIGluZGV4ZXNcbikgPT4ge1xuICBjb25zdCBtb25nb09iamVjdCA9IHtcbiAgICBfaWQ6IGNsYXNzTmFtZSxcbiAgICBvYmplY3RJZDogJ3N0cmluZycsXG4gICAgdXBkYXRlZEF0OiAnc3RyaW5nJyxcbiAgICBjcmVhdGVkQXQ6ICdzdHJpbmcnLFxuICAgIF9tZXRhZGF0YTogdW5kZWZpbmVkLFxuICB9O1xuXG4gIGZvciAoY29uc3QgZmllbGROYW1lIGluIGZpZWxkcykge1xuICAgIGNvbnN0IHsgdHlwZSwgdGFyZ2V0Q2xhc3MsIC4uLmZpZWxkT3B0aW9ucyB9ID0gZmllbGRzW2ZpZWxkTmFtZV07XG4gICAgbW9uZ29PYmplY3RbZmllbGROYW1lXSA9IE1vbmdvU2NoZW1hQ29sbGVjdGlvbi5wYXJzZUZpZWxkVHlwZVRvTW9uZ29GaWVsZFR5cGUoe1xuICAgICAgdHlwZSxcbiAgICAgIHRhcmdldENsYXNzLFxuICAgIH0pO1xuICAgIGlmIChmaWVsZE9wdGlvbnMgJiYgT2JqZWN0LmtleXMoZmllbGRPcHRpb25zKS5sZW5ndGggPiAwKSB7XG4gICAgICBtb25nb09iamVjdC5fbWV0YWRhdGEgPSBtb25nb09iamVjdC5fbWV0YWRhdGEgfHwge307XG4gICAgICBtb25nb09iamVjdC5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnMgPSBtb25nb09iamVjdC5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnMgfHwge307XG4gICAgICBtb25nb09iamVjdC5fbWV0YWRhdGEuZmllbGRzX29wdGlvbnNbZmllbGROYW1lXSA9IGZpZWxkT3B0aW9ucztcbiAgICB9XG4gIH1cblxuICBpZiAodHlwZW9mIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBtb25nb09iamVjdC5fbWV0YWRhdGEgPSBtb25nb09iamVjdC5fbWV0YWRhdGEgfHwge307XG4gICAgaWYgKCFjbGFzc0xldmVsUGVybWlzc2lvbnMpIHtcbiAgICAgIGRlbGV0ZSBtb25nb09iamVjdC5fbWV0YWRhdGEuY2xhc3NfcGVybWlzc2lvbnM7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1vbmdvT2JqZWN0Ll9tZXRhZGF0YS5jbGFzc19wZXJtaXNzaW9ucyA9IGNsYXNzTGV2ZWxQZXJtaXNzaW9ucztcbiAgICB9XG4gIH1cblxuICBpZiAoaW5kZXhlcyAmJiB0eXBlb2YgaW5kZXhlcyA9PT0gJ29iamVjdCcgJiYgT2JqZWN0LmtleXMoaW5kZXhlcykubGVuZ3RoID4gMCkge1xuICAgIG1vbmdvT2JqZWN0Ll9tZXRhZGF0YSA9IG1vbmdvT2JqZWN0Ll9tZXRhZGF0YSB8fCB7fTtcbiAgICBtb25nb09iamVjdC5fbWV0YWRhdGEuaW5kZXhlcyA9IGluZGV4ZXM7XG4gIH1cblxuICBpZiAoIW1vbmdvT2JqZWN0Ll9tZXRhZGF0YSkge1xuICAgIC8vIGNsZWFudXAgdGhlIHVudXNlZCBfbWV0YWRhdGFcbiAgICBkZWxldGUgbW9uZ29PYmplY3QuX21ldGFkYXRhO1xuICB9XG5cbiAgcmV0dXJuIG1vbmdvT2JqZWN0O1xufTtcblxuZnVuY3Rpb24gdmFsaWRhdGVFeHBsYWluVmFsdWUoZXhwbGFpbikge1xuICBpZiAoZXhwbGFpbikge1xuICAgIC8vIFRoZSBsaXN0IG9mIGFsbG93ZWQgZXhwbGFpbiB2YWx1ZXMgaXMgZnJvbSBub2RlLW1vbmdvZGItbmF0aXZlL2xpYi9leHBsYWluLmpzXG4gICAgY29uc3QgZXhwbGFpbkFsbG93ZWRWYWx1ZXMgPSBbXG4gICAgICAncXVlcnlQbGFubmVyJyxcbiAgICAgICdxdWVyeVBsYW5uZXJFeHRlbmRlZCcsXG4gICAgICAnZXhlY3V0aW9uU3RhdHMnLFxuICAgICAgJ2FsbFBsYW5zRXhlY3V0aW9uJyxcbiAgICAgIGZhbHNlLFxuICAgICAgdHJ1ZSxcbiAgICBdO1xuICAgIGlmICghZXhwbGFpbkFsbG93ZWRWYWx1ZXMuaW5jbHVkZXMoZXhwbGFpbikpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCAnSW52YWxpZCB2YWx1ZSBmb3IgZXhwbGFpbicpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgTW9uZ29TdG9yYWdlQWRhcHRlciBpbXBsZW1lbnRzIFN0b3JhZ2VBZGFwdGVyIHtcbiAgLy8gUHJpdmF0ZVxuICBfdXJpOiBzdHJpbmc7XG4gIF9jb2xsZWN0aW9uUHJlZml4OiBzdHJpbmc7XG4gIF9tb25nb09wdGlvbnM6IE9iamVjdDtcbiAgX29uY2hhbmdlOiBhbnk7XG4gIF9zdHJlYW06IGFueTtcbiAgX2xvZ0NsaWVudEV2ZW50czogP0FycmF5PGFueT47XG4gIC8vIFB1YmxpY1xuICBjb25uZWN0aW9uUHJvbWlzZTogP1Byb21pc2U8YW55PjtcbiAgZGF0YWJhc2U6IGFueTtcbiAgY2xpZW50OiBNb25nb0NsaWVudDtcbiAgX21heFRpbWVNUzogP251bWJlcjtcbiAgY2FuU29ydE9uSm9pblRhYmxlczogYm9vbGVhbjtcbiAgZW5hYmxlU2NoZW1hSG9va3M6IGJvb2xlYW47XG4gIHNjaGVtYUNhY2hlVHRsOiA/bnVtYmVyO1xuICBkaXNhYmxlSW5kZXhGaWVsZFZhbGlkYXRpb246IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IoeyB1cmkgPSBkZWZhdWx0cy5EZWZhdWx0TW9uZ29VUkksIGNvbGxlY3Rpb25QcmVmaXggPSAnJywgbW9uZ29PcHRpb25zID0ge30gfTogYW55KSB7XG4gICAgdGhpcy5fdXJpID0gdXJpO1xuICAgIHRoaXMuX2NvbGxlY3Rpb25QcmVmaXggPSBjb2xsZWN0aW9uUHJlZml4O1xuICAgIHRoaXMuX29uY2hhbmdlID0gKCkgPT4ge307XG5cbiAgICAvLyBNYXhUaW1lTVMgaXMgbm90IGEgZ2xvYmFsIE1vbmdvREIgY2xpZW50IG9wdGlvbiwgaXQgaXMgYXBwbGllZCBwZXIgb3BlcmF0aW9uLlxuICAgIHRoaXMuX21heFRpbWVNUyA9IG1vbmdvT3B0aW9ucy5tYXhUaW1lTVM7XG4gICAgdGhpcy5jYW5Tb3J0T25Kb2luVGFibGVzID0gdHJ1ZTtcbiAgICB0aGlzLmVuYWJsZVNjaGVtYUhvb2tzID0gISFtb25nb09wdGlvbnMuZW5hYmxlU2NoZW1hSG9va3M7XG4gICAgdGhpcy5zY2hlbWFDYWNoZVR0bCA9IG1vbmdvT3B0aW9ucy5zY2hlbWFDYWNoZVR0bDtcbiAgICB0aGlzLmRpc2FibGVJbmRleEZpZWxkVmFsaWRhdGlvbiA9ICEhbW9uZ29PcHRpb25zLmRpc2FibGVJbmRleEZpZWxkVmFsaWRhdGlvbjtcbiAgICB0aGlzLl9sb2dDbGllbnRFdmVudHMgPSBtb25nb09wdGlvbnMubG9nQ2xpZW50RXZlbnRzO1xuXG4gICAgLy8gQ3JlYXRlIGEgY29weSBvZiBtb25nb09wdGlvbnMgYW5kIHJlbW92ZSBQYXJzZSBTZXJ2ZXItc3BlY2lmaWMgb3B0aW9ucyB0aGF0IHNob3VsZCBub3RcbiAgICAvLyBiZSBwYXNzZWQgdG8gTW9uZ29EQiBjbGllbnQuIE5vdGU6IFdlIG9ubHkgZGVsZXRlIGZyb20gdGhpcy5fbW9uZ29PcHRpb25zLCBub3QgZnJvbSB0aGVcbiAgICAvLyBvcmlnaW5hbCBtb25nb09wdGlvbnMgb2JqZWN0LCBiZWNhdXNlIG90aGVyIGNvbXBvbmVudHMgKGxpa2UgRGF0YWJhc2VDb250cm9sbGVyKSBuZWVkXG4gICAgLy8gYWNjZXNzIHRvIHRoZXNlIG9wdGlvbnMuXG4gICAgdGhpcy5fbW9uZ29PcHRpb25zID0geyAuLi5tb25nb09wdGlvbnMgfTtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBQYXJzZVNlcnZlckRhdGFiYXNlT3B0aW9ucykge1xuICAgICAgZGVsZXRlIHRoaXMuX21vbmdvT3B0aW9uc1trZXldO1xuICAgIH1cbiAgfVxuXG4gIHdhdGNoKGNhbGxiYWNrOiAoKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgdGhpcy5fb25jaGFuZ2UgPSBjYWxsYmFjaztcbiAgfVxuXG4gIGNvbm5lY3QoKSB7XG4gICAgaWYgKHRoaXMuY29ubmVjdGlvblByb21pc2UpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb25Qcm9taXNlO1xuICAgIH1cblxuICAgIC8vIHBhcnNpbmcgYW5kIHJlLWZvcm1hdHRpbmcgY2F1c2VzIHRoZSBhdXRoIHZhbHVlIChpZiB0aGVyZSkgdG8gZ2V0IFVSSVxuICAgIC8vIGVuY29kZWRcbiAgICBjb25zdCBlbmNvZGVkVXJpID0gZm9ybWF0VXJsKHBhcnNlVXJsKHRoaXMuX3VyaSkpO1xuICAgIHRoaXMuY29ubmVjdGlvblByb21pc2UgPSBNb25nb0NsaWVudC5jb25uZWN0KGVuY29kZWRVcmksIHRoaXMuX21vbmdvT3B0aW9ucylcbiAgICAgIC50aGVuKGNsaWVudCA9PiB7XG4gICAgICAgIC8vIFN0YXJ0aW5nIG1vbmdvREIgMy4wLCB0aGUgTW9uZ29DbGllbnQuY29ubmVjdCBkb24ndCByZXR1cm4gYSBEQiBhbnltb3JlIGJ1dCBhIGNsaWVudFxuICAgICAgICAvLyBGb3J0dW5hdGVseSwgd2UgY2FuIGdldCBiYWNrIHRoZSBvcHRpb25zIGFuZCB1c2UgdGhlbSB0byBzZWxlY3QgdGhlIHByb3BlciBEQi5cbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21vbmdvZGIvbm9kZS1tb25nb2RiLW5hdGl2ZS9ibG9iLzJjMzVkNzZmMDg1NzQyMjViOGRiMDJkN2JlZjY4NzEyM2U2YmIwMTgvbGliL21vbmdvX2NsaWVudC5qcyNMODg1XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBjbGllbnQucy5vcHRpb25zO1xuICAgICAgICBjb25zdCBkYXRhYmFzZSA9IGNsaWVudC5kYihvcHRpb25zLmRiTmFtZSk7XG4gICAgICAgIGlmICghZGF0YWJhc2UpIHtcbiAgICAgICAgICBkZWxldGUgdGhpcy5jb25uZWN0aW9uUHJvbWlzZTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY2xpZW50Lm9uKCdlcnJvcicsICgpID0+IHtcbiAgICAgICAgICBkZWxldGUgdGhpcy5jb25uZWN0aW9uUHJvbWlzZTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNsaWVudC5vbignY2xvc2UnLCAoKSA9PiB7XG4gICAgICAgICAgZGVsZXRlIHRoaXMuY29ubmVjdGlvblByb21pc2U7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNldCB1cCBjbGllbnQgZXZlbnQgbG9nZ2luZyBpZiBjb25maWd1cmVkXG4gICAgICAgIGlmICh0aGlzLl9sb2dDbGllbnRFdmVudHMgJiYgQXJyYXkuaXNBcnJheSh0aGlzLl9sb2dDbGllbnRFdmVudHMpKSB7XG4gICAgICAgICAgdGhpcy5fbG9nQ2xpZW50RXZlbnRzLmZvckVhY2goZXZlbnRDb25maWcgPT4ge1xuICAgICAgICAgICAgY2xpZW50Lm9uKGV2ZW50Q29uZmlnLm5hbWUsIGV2ZW50ID0+IHtcbiAgICAgICAgICAgICAgbGV0IGxvZ0RhdGEgPSB7fTtcbiAgICAgICAgICAgICAgaWYgKCFldmVudENvbmZpZy5rZXlzIHx8IGV2ZW50Q29uZmlnLmtleXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgbG9nRGF0YSA9IGV2ZW50O1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGV2ZW50Q29uZmlnLmtleXMuZm9yRWFjaChrZXlQYXRoID0+IHtcbiAgICAgICAgICAgICAgICAgIGxvZ0RhdGFba2V5UGF0aF0gPSBfLmdldChldmVudCwga2V5UGF0aCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyBWYWxpZGF0ZSBsb2cgbGV2ZWwgZXhpc3RzLCBmYWxsYmFjayB0byAnaW5mbydcbiAgICAgICAgICAgICAgY29uc3QgbG9nTGV2ZWwgPSB0eXBlb2YgbG9nZ2VyW2V2ZW50Q29uZmlnLmxvZ0xldmVsXSA9PT0gJ2Z1bmN0aW9uJyA/IGV2ZW50Q29uZmlnLmxvZ0xldmVsIDogJ2luZm8nO1xuXG4gICAgICAgICAgICAgIC8vIFNhZmUgSlNPTiBzZXJpYWxpemF0aW9uIHdpdGggTWFwL1NldCBhbmQgY2lyY3VsYXIgcmVmZXJlbmNlIHN1cHBvcnRcbiAgICAgICAgICAgICAgY29uc3QgbG9nTWVzc2FnZSA9IGBNb25nb0RCIGNsaWVudCBldmVudCAke2V2ZW50Q29uZmlnLm5hbWV9OiAke0pTT04uc3RyaW5naWZ5KGxvZ0RhdGEsIFV0aWxzLmdldENpcmN1bGFyUmVwbGFjZXIoKSl9YDtcblxuICAgICAgICAgICAgICBsb2dnZXJbbG9nTGV2ZWxdKGxvZ01lc3NhZ2UpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmNsaWVudCA9IGNsaWVudDtcbiAgICAgICAgdGhpcy5kYXRhYmFzZSA9IGRhdGFiYXNlO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4ge1xuICAgICAgICBkZWxldGUgdGhpcy5jb25uZWN0aW9uUHJvbWlzZTtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycik7XG4gICAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb25Qcm9taXNlO1xuICB9XG5cbiAgaGFuZGxlRXJyb3I8VD4oZXJyb3I6ID8oRXJyb3IgfCBQYXJzZS5FcnJvcikpOiBQcm9taXNlPFQ+IHtcbiAgICBpZiAoZXJyb3IgJiYgZXJyb3IuY29kZSA9PT0gMTMpIHtcbiAgICAgIC8vIFVuYXV0aG9yaXplZCBlcnJvclxuICAgICAgZGVsZXRlIHRoaXMuY2xpZW50O1xuICAgICAgZGVsZXRlIHRoaXMuZGF0YWJhc2U7XG4gICAgICBkZWxldGUgdGhpcy5jb25uZWN0aW9uUHJvbWlzZTtcbiAgICAgIGxvZ2dlci5lcnJvcignUmVjZWl2ZWQgdW5hdXRob3JpemVkIGVycm9yJywgeyBlcnJvcjogZXJyb3IgfSk7XG4gICAgfVxuICAgIHRocm93IGVycm9yO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlU2h1dGRvd24oKSB7XG4gICAgaWYgKCF0aGlzLmNsaWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBhd2FpdCB0aGlzLmNsaWVudC5jbG9zZShmYWxzZSk7XG4gICAgZGVsZXRlIHRoaXMuY29ubmVjdGlvblByb21pc2U7XG4gIH1cblxuICBfYWRhcHRpdmVDb2xsZWN0aW9uKG5hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmNvbm5lY3QoKVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5kYXRhYmFzZS5jb2xsZWN0aW9uKHRoaXMuX2NvbGxlY3Rpb25QcmVmaXggKyBuYW1lKSlcbiAgICAgIC50aGVuKHJhd0NvbGxlY3Rpb24gPT4gbmV3IE1vbmdvQ29sbGVjdGlvbihyYXdDb2xsZWN0aW9uKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIF9zY2hlbWFDb2xsZWN0aW9uKCk6IFByb21pc2U8TW9uZ29TY2hlbWFDb2xsZWN0aW9uPiB7XG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdCgpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oTW9uZ29TY2hlbWFDb2xsZWN0aW9uTmFtZSkpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLl9zdHJlYW0gJiYgdGhpcy5lbmFibGVTY2hlbWFIb29rcykge1xuICAgICAgICAgIHRoaXMuX3N0cmVhbSA9IGNvbGxlY3Rpb24uX21vbmdvQ29sbGVjdGlvbi53YXRjaCgpO1xuICAgICAgICAgIHRoaXMuX3N0cmVhbS5vbignY2hhbmdlJywgKCkgPT4gdGhpcy5fb25jaGFuZ2UoKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBNb25nb1NjaGVtYUNvbGxlY3Rpb24oY29sbGVjdGlvbik7XG4gICAgICB9KTtcbiAgfVxuXG4gIGNsYXNzRXhpc3RzKG5hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmNvbm5lY3QoKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5kYXRhYmFzZS5saXN0Q29sbGVjdGlvbnMoeyBuYW1lOiB0aGlzLl9jb2xsZWN0aW9uUHJlZml4ICsgbmFtZSB9KS50b0FycmF5KCk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oY29sbGVjdGlvbnMgPT4ge1xuICAgICAgICByZXR1cm4gY29sbGVjdGlvbnMubGVuZ3RoID4gMDtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBzZXRDbGFzc0xldmVsUGVybWlzc2lvbnMoY2xhc3NOYW1lOiBzdHJpbmcsIENMUHM6IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKClcbiAgICAgIC50aGVuKHNjaGVtYUNvbGxlY3Rpb24gPT5cbiAgICAgICAgc2NoZW1hQ29sbGVjdGlvbi51cGRhdGVTY2hlbWEoY2xhc3NOYW1lLCB7XG4gICAgICAgICAgJHNldDogeyAnX21ldGFkYXRhLmNsYXNzX3Blcm1pc3Npb25zJzogQ0xQcyB9LFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgc2V0SW5kZXhlc1dpdGhTY2hlbWFGb3JtYXQoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc3VibWl0dGVkSW5kZXhlczogYW55LFxuICAgIGV4aXN0aW5nSW5kZXhlczogYW55ID0ge30sXG4gICAgZmllbGRzOiBhbnlcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHN1Ym1pdHRlZEluZGV4ZXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICBpZiAoT2JqZWN0LmtleXMoZXhpc3RpbmdJbmRleGVzKS5sZW5ndGggPT09IDApIHtcbiAgICAgIGV4aXN0aW5nSW5kZXhlcyA9IHsgX2lkXzogeyBfaWQ6IDEgfSB9O1xuICAgIH1cbiAgICBjb25zdCBkZWxldGVQcm9taXNlcyA9IFtdO1xuICAgIGNvbnN0IGluc2VydGVkSW5kZXhlcyA9IFtdO1xuICAgIE9iamVjdC5rZXlzKHN1Ym1pdHRlZEluZGV4ZXMpLmZvckVhY2gobmFtZSA9PiB7XG4gICAgICBjb25zdCBmaWVsZCA9IHN1Ym1pdHRlZEluZGV4ZXNbbmFtZV07XG4gICAgICBpZiAoZXhpc3RpbmdJbmRleGVzW25hbWVdICYmIGZpZWxkLl9fb3AgIT09ICdEZWxldGUnKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX1FVRVJZLCBgSW5kZXggJHtuYW1lfSBleGlzdHMsIGNhbm5vdCB1cGRhdGUuYCk7XG4gICAgICB9XG4gICAgICBpZiAoIWV4aXN0aW5nSW5kZXhlc1tuYW1lXSAmJiBmaWVsZC5fX29wID09PSAnRGVsZXRlJykge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9RVUVSWSxcbiAgICAgICAgICBgSW5kZXggJHtuYW1lfSBkb2VzIG5vdCBleGlzdCwgY2Fubm90IGRlbGV0ZS5gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoZmllbGQuX19vcCA9PT0gJ0RlbGV0ZScpIHtcbiAgICAgICAgY29uc3QgcHJvbWlzZSA9IHRoaXMuZHJvcEluZGV4KGNsYXNzTmFtZSwgbmFtZSk7XG4gICAgICAgIGRlbGV0ZVByb21pc2VzLnB1c2gocHJvbWlzZSk7XG4gICAgICAgIGRlbGV0ZSBleGlzdGluZ0luZGV4ZXNbbmFtZV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBPYmplY3Qua2V5cyhmaWVsZCkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICF0aGlzLmRpc2FibGVJbmRleEZpZWxkVmFsaWRhdGlvbiAmJlxuICAgICAgICAgICAgIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChcbiAgICAgICAgICAgICAgZmllbGRzLFxuICAgICAgICAgICAgICBrZXkuaW5kZXhPZignX3BfJykgPT09IDAgPyBrZXkucmVwbGFjZSgnX3BfJywgJycpIDoga2V5XG4gICAgICAgICAgICApXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksXG4gICAgICAgICAgICAgIGBGaWVsZCAke2tleX0gZG9lcyBub3QgZXhpc3QsIGNhbm5vdCBhZGQgaW5kZXguYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBleGlzdGluZ0luZGV4ZXNbbmFtZV0gPSBmaWVsZDtcbiAgICAgICAgaW5zZXJ0ZWRJbmRleGVzLnB1c2goe1xuICAgICAgICAgIGtleTogZmllbGQsXG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgbGV0IGluc2VydFByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgICBpZiAoaW5zZXJ0ZWRJbmRleGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGluc2VydFByb21pc2UgPSB0aGlzLmNyZWF0ZUluZGV4ZXMoY2xhc3NOYW1lLCBpbnNlcnRlZEluZGV4ZXMpO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoZGVsZXRlUHJvbWlzZXMpXG4gICAgICAudGhlbigoKSA9PiBpbnNlcnRQcm9taXNlKVxuICAgICAgLnRoZW4oKCkgPT4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpKVxuICAgICAgLnRoZW4oc2NoZW1hQ29sbGVjdGlvbiA9PlxuICAgICAgICBzY2hlbWFDb2xsZWN0aW9uLnVwZGF0ZVNjaGVtYShjbGFzc05hbWUsIHtcbiAgICAgICAgICAkc2V0OiB7ICdfbWV0YWRhdGEuaW5kZXhlcyc6IGV4aXN0aW5nSW5kZXhlcyB9LFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgc2V0SW5kZXhlc0Zyb21Nb25nbyhjbGFzc05hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmdldEluZGV4ZXMoY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oaW5kZXhlcyA9PiB7XG4gICAgICAgIGluZGV4ZXMgPSBpbmRleGVzLnJlZHVjZSgob2JqLCBpbmRleCkgPT4ge1xuICAgICAgICAgIGlmIChpbmRleC5rZXkuX2Z0cykge1xuICAgICAgICAgICAgZGVsZXRlIGluZGV4LmtleS5fZnRzO1xuICAgICAgICAgICAgZGVsZXRlIGluZGV4LmtleS5fZnRzeDtcbiAgICAgICAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gaW5kZXgud2VpZ2h0cykge1xuICAgICAgICAgICAgICBpbmRleC5rZXlbZmllbGRdID0gJ3RleHQnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBvYmpbaW5kZXgubmFtZV0gPSBpbmRleC5rZXk7XG4gICAgICAgICAgcmV0dXJuIG9iajtcbiAgICAgICAgfSwge30pO1xuICAgICAgICByZXR1cm4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpLnRoZW4oc2NoZW1hQ29sbGVjdGlvbiA9PlxuICAgICAgICAgIHNjaGVtYUNvbGxlY3Rpb24udXBkYXRlU2NoZW1hKGNsYXNzTmFtZSwge1xuICAgICAgICAgICAgJHNldDogeyAnX21ldGFkYXRhLmluZGV4ZXMnOiBpbmRleGVzIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSlcbiAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgIC8vIElnbm9yZSBpZiBjb2xsZWN0aW9uIG5vdCBmb3VuZFxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIGNyZWF0ZUNsYXNzKGNsYXNzTmFtZTogc3RyaW5nLCBzY2hlbWE6IFNjaGVtYVR5cGUpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29PYmplY3QgPSBtb25nb1NjaGVtYUZyb21GaWVsZHNBbmRDbGFzc05hbWVBbmRDTFAoXG4gICAgICBzY2hlbWEuZmllbGRzLFxuICAgICAgY2xhc3NOYW1lLFxuICAgICAgc2NoZW1hLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgIHNjaGVtYS5pbmRleGVzXG4gICAgKTtcbiAgICBtb25nb09iamVjdC5faWQgPSBjbGFzc05hbWU7XG4gICAgcmV0dXJuIHRoaXMuc2V0SW5kZXhlc1dpdGhTY2hlbWFGb3JtYXQoY2xhc3NOYW1lLCBzY2hlbWEuaW5kZXhlcywge30sIHNjaGVtYS5maWVsZHMpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKCkpXG4gICAgICAudGhlbihzY2hlbWFDb2xsZWN0aW9uID0+IHNjaGVtYUNvbGxlY3Rpb24uaW5zZXJ0U2NoZW1hKG1vbmdvT2JqZWN0KSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIGFzeW5jIHVwZGF0ZUZpZWxkT3B0aW9ucyhjbGFzc05hbWU6IHN0cmluZywgZmllbGROYW1lOiBzdHJpbmcsIHR5cGU6IGFueSkge1xuICAgIGNvbnN0IHNjaGVtYUNvbGxlY3Rpb24gPSBhd2FpdCB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKCk7XG4gICAgYXdhaXQgc2NoZW1hQ29sbGVjdGlvbi51cGRhdGVGaWVsZE9wdGlvbnMoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHR5cGUpO1xuICB9XG5cbiAgYWRkRmllbGRJZk5vdEV4aXN0cyhjbGFzc05hbWU6IHN0cmluZywgZmllbGROYW1lOiBzdHJpbmcsIHR5cGU6IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKClcbiAgICAgIC50aGVuKHNjaGVtYUNvbGxlY3Rpb24gPT4gc2NoZW1hQ29sbGVjdGlvbi5hZGRGaWVsZElmTm90RXhpc3RzKGNsYXNzTmFtZSwgZmllbGROYW1lLCB0eXBlKSlcbiAgICAgIC50aGVuKCgpID0+IHRoaXMuY3JlYXRlSW5kZXhlc0lmTmVlZGVkKGNsYXNzTmFtZSwgZmllbGROYW1lLCB0eXBlKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIERyb3BzIGEgY29sbGVjdGlvbi4gUmVzb2x2ZXMgd2l0aCB0cnVlIGlmIGl0IHdhcyBhIFBhcnNlIFNjaGVtYSAoZWcuIF9Vc2VyLCBDdXN0b20sIGV0Yy4pXG4gIC8vIGFuZCByZXNvbHZlcyB3aXRoIGZhbHNlIGlmIGl0IHdhc24ndCAoZWcuIGEgam9pbiB0YWJsZSkuIFJlamVjdHMgaWYgZGVsZXRpb24gd2FzIGltcG9zc2libGUuXG4gIGRlbGV0ZUNsYXNzKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5kcm9wKCkpXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgLy8gJ25zIG5vdCBmb3VuZCcgbWVhbnMgY29sbGVjdGlvbiB3YXMgYWxyZWFkeSBnb25lLiBJZ25vcmUgZGVsZXRpb24gYXR0ZW1wdC5cbiAgICAgICAgICBpZiAoZXJyb3IubWVzc2FnZSA9PSAnbnMgbm90IGZvdW5kJykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfSlcbiAgICAgICAgLy8gV2UndmUgZHJvcHBlZCB0aGUgY29sbGVjdGlvbiwgbm93IHJlbW92ZSB0aGUgX1NDSEVNQSBkb2N1bWVudFxuICAgICAgICAudGhlbigoKSA9PiB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKCkpXG4gICAgICAgIC50aGVuKHNjaGVtYUNvbGxlY3Rpb24gPT4gc2NoZW1hQ29sbGVjdGlvbi5maW5kQW5kRGVsZXRlU2NoZW1hKGNsYXNzTmFtZSkpXG4gICAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKVxuICAgICk7XG4gIH1cblxuICBkZWxldGVBbGxDbGFzc2VzKGZhc3Q6IGJvb2xlYW4pIHtcbiAgICByZXR1cm4gc3RvcmFnZUFkYXB0ZXJBbGxDb2xsZWN0aW9ucyh0aGlzKS50aGVuKGNvbGxlY3Rpb25zID0+XG4gICAgICBQcm9taXNlLmFsbChcbiAgICAgICAgY29sbGVjdGlvbnMubWFwKGNvbGxlY3Rpb24gPT4gKGZhc3QgPyBjb2xsZWN0aW9uLmRlbGV0ZU1hbnkoe30pIDogY29sbGVjdGlvbi5kcm9wKCkpKVxuICAgICAgKVxuICAgICk7XG4gIH1cblxuICAvLyBSZW1vdmUgdGhlIGNvbHVtbiBhbmQgYWxsIHRoZSBkYXRhLiBGb3IgUmVsYXRpb25zLCB0aGUgX0pvaW4gY29sbGVjdGlvbiBpcyBoYW5kbGVkXG4gIC8vIHNwZWNpYWxseSwgdGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBkZWxldGUgX0pvaW4gY29sdW1ucy4gSXQgc2hvdWxkLCBob3dldmVyLCBpbmRpY2F0ZVxuICAvLyB0aGF0IHRoZSByZWxhdGlvbiBmaWVsZHMgZG9lcyBub3QgZXhpc3QgYW55bW9yZS4gSW4gbW9uZ28sIHRoaXMgbWVhbnMgcmVtb3ZpbmcgaXQgZnJvbVxuICAvLyB0aGUgX1NDSEVNQSBjb2xsZWN0aW9uLiAgVGhlcmUgc2hvdWxkIGJlIG5vIGFjdHVhbCBkYXRhIGluIHRoZSBjb2xsZWN0aW9uIHVuZGVyIHRoZSBzYW1lIG5hbWVcbiAgLy8gYXMgdGhlIHJlbGF0aW9uIGNvbHVtbiwgc28gaXQncyBmaW5lIHRvIGF0dGVtcHQgdG8gZGVsZXRlIGl0LiBJZiB0aGUgZmllbGRzIGxpc3RlZCB0byBiZVxuICAvLyBkZWxldGVkIGRvIG5vdCBleGlzdCwgdGhpcyBmdW5jdGlvbiBzaG91bGQgcmV0dXJuIHN1Y2Nlc3NmdWxseSBhbnl3YXlzLiBDaGVja2luZyBmb3JcbiAgLy8gYXR0ZW1wdHMgdG8gZGVsZXRlIG5vbi1leGlzdGVudCBmaWVsZHMgaXMgdGhlIHJlc3BvbnNpYmlsaXR5IG9mIFBhcnNlIFNlcnZlci5cblxuICAvLyBQb2ludGVyIGZpZWxkIG5hbWVzIGFyZSBwYXNzZWQgZm9yIGxlZ2FjeSByZWFzb25zOiB0aGUgb3JpZ2luYWwgbW9uZ29cbiAgLy8gZm9ybWF0IHN0b3JlZCBwb2ludGVyIGZpZWxkIG5hbWVzIGRpZmZlcmVudGx5IGluIHRoZSBkYXRhYmFzZSwgYW5kIHRoZXJlZm9yZVxuICAvLyBuZWVkZWQgdG8ga25vdyB0aGUgdHlwZSBvZiB0aGUgZmllbGQgYmVmb3JlIGl0IGNvdWxkIGRlbGV0ZSBpdC4gRnV0dXJlIGRhdGFiYXNlXG4gIC8vIGFkYXB0ZXJzIHNob3VsZCBpZ25vcmUgdGhlIHBvaW50ZXJGaWVsZE5hbWVzIGFyZ3VtZW50LiBBbGwgdGhlIGZpZWxkIG5hbWVzIGFyZSBpblxuICAvLyBmaWVsZE5hbWVzLCB0aGV5IHNob3cgdXAgYWRkaXRpb25hbGx5IGluIHRoZSBwb2ludGVyRmllbGROYW1lcyBkYXRhYmFzZSBmb3IgdXNlXG4gIC8vIGJ5IHRoZSBtb25nbyBhZGFwdGVyLCB3aGljaCBkZWFscyB3aXRoIHRoZSBsZWdhY3kgbW9uZ28gZm9ybWF0LlxuXG4gIC8vIFRoaXMgZnVuY3Rpb24gaXMgbm90IG9ibGlnYXRlZCB0byBkZWxldGUgZmllbGRzIGF0b21pY2FsbHkuIEl0IGlzIGdpdmVuIHRoZSBmaWVsZFxuICAvLyBuYW1lcyBpbiBhIGxpc3Qgc28gdGhhdCBkYXRhYmFzZXMgdGhhdCBhcmUgY2FwYWJsZSBvZiBkZWxldGluZyBmaWVsZHMgYXRvbWljYWxseVxuICAvLyBtYXkgZG8gc28uXG5cbiAgLy8gUmV0dXJucyBhIFByb21pc2UuXG4gIGRlbGV0ZUZpZWxkcyhjbGFzc05hbWU6IHN0cmluZywgc2NoZW1hOiBTY2hlbWFUeXBlLCBmaWVsZE5hbWVzOiBzdHJpbmdbXSkge1xuICAgIGNvbnN0IG1vbmdvRm9ybWF0TmFtZXMgPSBmaWVsZE5hbWVzLm1hcChmaWVsZE5hbWUgPT4ge1xuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGROYW1lXS50eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgICAgcmV0dXJuIGBfcF8ke2ZpZWxkTmFtZX1gO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGZpZWxkTmFtZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBjb25zdCBjb2xsZWN0aW9uVXBkYXRlID0geyAkdW5zZXQ6IHt9IH07XG4gICAgbW9uZ29Gb3JtYXROYW1lcy5mb3JFYWNoKG5hbWUgPT4ge1xuICAgICAgY29sbGVjdGlvblVwZGF0ZVsnJHVuc2V0J11bbmFtZV0gPSBudWxsO1xuICAgIH0pO1xuXG4gICAgY29uc3QgY29sbGVjdGlvbkZpbHRlciA9IHsgJG9yOiBbXSB9O1xuICAgIG1vbmdvRm9ybWF0TmFtZXMuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgIGNvbGxlY3Rpb25GaWx0ZXJbJyRvciddLnB1c2goeyBbbmFtZV06IHsgJGV4aXN0czogdHJ1ZSB9IH0pO1xuICAgIH0pO1xuXG4gICAgY29uc3Qgc2NoZW1hVXBkYXRlID0geyAkdW5zZXQ6IHt9IH07XG4gICAgZmllbGROYW1lcy5mb3JFYWNoKG5hbWUgPT4ge1xuICAgICAgc2NoZW1hVXBkYXRlWyckdW5zZXQnXVtuYW1lXSA9IG51bGw7XG4gICAgICBzY2hlbWFVcGRhdGVbJyR1bnNldCddW2BfbWV0YWRhdGEuZmllbGRzX29wdGlvbnMuJHtuYW1lfWBdID0gbnVsbDtcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLnVwZGF0ZU1hbnkoY29sbGVjdGlvbkZpbHRlciwgY29sbGVjdGlvblVwZGF0ZSkpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLl9zY2hlbWFDb2xsZWN0aW9uKCkpXG4gICAgICAudGhlbihzY2hlbWFDb2xsZWN0aW9uID0+IHNjaGVtYUNvbGxlY3Rpb24udXBkYXRlU2NoZW1hKGNsYXNzTmFtZSwgc2NoZW1hVXBkYXRlKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIFJldHVybiBhIHByb21pc2UgZm9yIGFsbCBzY2hlbWFzIGtub3duIHRvIHRoaXMgYWRhcHRlciwgaW4gUGFyc2UgZm9ybWF0LiBJbiBjYXNlIHRoZVxuICAvLyBzY2hlbWFzIGNhbm5vdCBiZSByZXRyaWV2ZWQsIHJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVqZWN0cy4gUmVxdWlyZW1lbnRzIGZvciB0aGVcbiAgLy8gcmVqZWN0aW9uIHJlYXNvbiBhcmUgVEJELlxuICBnZXRBbGxDbGFzc2VzKCk6IFByb21pc2U8U3RvcmFnZUNsYXNzW10+IHtcbiAgICByZXR1cm4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpXG4gICAgICAudGhlbihzY2hlbWFzQ29sbGVjdGlvbiA9PiBzY2hlbWFzQ29sbGVjdGlvbi5fZmV0Y2hBbGxTY2hlbWFzRnJvbV9TQ0hFTUEoKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIFJldHVybiBhIHByb21pc2UgZm9yIHRoZSBzY2hlbWEgd2l0aCB0aGUgZ2l2ZW4gbmFtZSwgaW4gUGFyc2UgZm9ybWF0LiBJZlxuICAvLyB0aGlzIGFkYXB0ZXIgZG9lc24ndCBrbm93IGFib3V0IHRoZSBzY2hlbWEsIHJldHVybiBhIHByb21pc2UgdGhhdCByZWplY3RzIHdpdGhcbiAgLy8gdW5kZWZpbmVkIGFzIHRoZSByZWFzb24uXG4gIGdldENsYXNzKGNsYXNzTmFtZTogc3RyaW5nKTogUHJvbWlzZTxTdG9yYWdlQ2xhc3M+IHtcbiAgICByZXR1cm4gdGhpcy5fc2NoZW1hQ29sbGVjdGlvbigpXG4gICAgICAudGhlbihzY2hlbWFzQ29sbGVjdGlvbiA9PiBzY2hlbWFzQ29sbGVjdGlvbi5fZmV0Y2hPbmVTY2hlbWFGcm9tX1NDSEVNQShjbGFzc05hbWUpKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gVE9ETzogQXMgeWV0IG5vdCBwYXJ0aWN1bGFybHkgd2VsbCBzcGVjaWZpZWQuIENyZWF0ZXMgYW4gb2JqZWN0LiBNYXliZSBzaG91bGRuJ3QgZXZlbiBuZWVkIHRoZSBzY2hlbWEsXG4gIC8vIGFuZCBzaG91bGQgaW5mZXIgZnJvbSB0aGUgdHlwZS4gT3IgbWF5YmUgZG9lcyBuZWVkIHRoZSBzY2hlbWEgZm9yIHZhbGlkYXRpb25zLiBPciBtYXliZSBuZWVkc1xuICAvLyB0aGUgc2NoZW1hIG9ubHkgZm9yIHRoZSBsZWdhY3kgbW9uZ28gZm9ybWF0LiBXZSdsbCBmaWd1cmUgdGhhdCBvdXQgbGF0ZXIuXG4gIGNyZWF0ZU9iamVjdChjbGFzc05hbWU6IHN0cmluZywgc2NoZW1hOiBTY2hlbWFUeXBlLCBvYmplY3Q6IGFueSwgdHJhbnNhY3Rpb25hbFNlc3Npb246ID9hbnkpIHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29PYmplY3QgPSBwYXJzZU9iamVjdFRvTW9uZ29PYmplY3RGb3JDcmVhdGUoY2xhc3NOYW1lLCBvYmplY3QsIHNjaGVtYSk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24uaW5zZXJ0T25lKG1vbmdvT2JqZWN0LCB0cmFuc2FjdGlvbmFsU2Vzc2lvbikpXG4gICAgICAudGhlbigoKSA9PiAoeyBvcHM6IFttb25nb09iamVjdF0gfSkpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gMTEwMDApIHtcbiAgICAgICAgICAvLyBEdXBsaWNhdGUgdmFsdWVcbiAgICAgICAgICBjb25zdCBlcnIgPSBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUsXG4gICAgICAgICAgICAnQSBkdXBsaWNhdGUgdmFsdWUgZm9yIGEgZmllbGQgd2l0aCB1bmlxdWUgdmFsdWVzIHdhcyBwcm92aWRlZCdcbiAgICAgICAgICApO1xuICAgICAgICAgIGVyci51bmRlcmx5aW5nRXJyb3IgPSBlcnJvcjtcbiAgICAgICAgICBpZiAoZXJyb3IubWVzc2FnZSkge1xuICAgICAgICAgICAgY29uc3QgbWF0Y2hlcyA9IGVycm9yLm1lc3NhZ2UubWF0Y2goL2luZGV4OltcXHNhLXpBLVowLTlfXFwtXFwuXStcXCQ/KFthLXpBLVpfLV0rKV8xLyk7XG4gICAgICAgICAgICBpZiAobWF0Y2hlcyAmJiBBcnJheS5pc0FycmF5KG1hdGNoZXMpKSB7XG4gICAgICAgICAgICAgIGVyci51c2VySW5mbyA9IHsgZHVwbGljYXRlZF9maWVsZDogbWF0Y2hlc1sxXSB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gUmVtb3ZlIGFsbCBvYmplY3RzIHRoYXQgbWF0Y2ggdGhlIGdpdmVuIFBhcnNlIFF1ZXJ5LlxuICAvLyBJZiBubyBvYmplY3RzIG1hdGNoLCByZWplY3Qgd2l0aCBPQkpFQ1RfTk9UX0ZPVU5ELiBJZiBvYmplY3RzIGFyZSBmb3VuZCBhbmQgZGVsZXRlZCwgcmVzb2x2ZSB3aXRoIHVuZGVmaW5lZC5cbiAgLy8gSWYgdGhlcmUgaXMgc29tZSBvdGhlciBlcnJvciwgcmVqZWN0IHdpdGggSU5URVJOQUxfU0VSVkVSX0VSUk9SLlxuICBkZWxldGVPYmplY3RzQnlRdWVyeShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbjogP2FueVxuICApIHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IHtcbiAgICAgICAgY29uc3QgbW9uZ29XaGVyZSA9IHRyYW5zZm9ybVdoZXJlKGNsYXNzTmFtZSwgcXVlcnksIHNjaGVtYSk7XG4gICAgICAgIHJldHVybiBjb2xsZWN0aW9uLmRlbGV0ZU1hbnkobW9uZ29XaGVyZSwgdHJhbnNhY3Rpb25hbFNlc3Npb24pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKVxuICAgICAgLnRoZW4oXG4gICAgICAgICh7IGRlbGV0ZWRDb3VudCB9KSA9PiB7XG4gICAgICAgICAgaWYgKGRlbGV0ZWRDb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsICdPYmplY3Qgbm90IGZvdW5kLicpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIH0sXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLCAnRGF0YWJhc2UgYWRhcHRlciBlcnJvcicpO1xuICAgICAgICB9XG4gICAgICApO1xuICB9XG5cbiAgLy8gQXBwbHkgdGhlIHVwZGF0ZSB0byBhbGwgb2JqZWN0cyB0aGF0IG1hdGNoIHRoZSBnaXZlbiBQYXJzZSBRdWVyeS5cbiAgdXBkYXRlT2JqZWN0c0J5UXVlcnkoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIHF1ZXJ5OiBRdWVyeVR5cGUsXG4gICAgdXBkYXRlOiBhbnksXG4gICAgdHJhbnNhY3Rpb25hbFNlc3Npb246ID9hbnlcbiAgKSB7XG4gICAgc2NoZW1hID0gY29udmVydFBhcnNlU2NoZW1hVG9Nb25nb1NjaGVtYShzY2hlbWEpO1xuICAgIGNvbnN0IG1vbmdvVXBkYXRlID0gdHJhbnNmb3JtVXBkYXRlKGNsYXNzTmFtZSwgdXBkYXRlLCBzY2hlbWEpO1xuICAgIGNvbnN0IG1vbmdvV2hlcmUgPSB0cmFuc2Zvcm1XaGVyZShjbGFzc05hbWUsIHF1ZXJ5LCBzY2hlbWEpO1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLnVwZGF0ZU1hbnkobW9uZ29XaGVyZSwgbW9uZ29VcGRhdGUsIHRyYW5zYWN0aW9uYWxTZXNzaW9uKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIEF0b21pY2FsbHkgZmluZHMgYW5kIHVwZGF0ZXMgYW4gb2JqZWN0IGJhc2VkIG9uIHF1ZXJ5LlxuICAvLyBSZXR1cm4gdmFsdWUgbm90IGN1cnJlbnRseSB3ZWxsIHNwZWNpZmllZC5cbiAgZmluZE9uZUFuZFVwZGF0ZShcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICB1cGRhdGU6IGFueSxcbiAgICB0cmFuc2FjdGlvbmFsU2Vzc2lvbjogP2FueVxuICApIHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29VcGRhdGUgPSB0cmFuc2Zvcm1VcGRhdGUoY2xhc3NOYW1lLCB1cGRhdGUsIHNjaGVtYSk7XG4gICAgY29uc3QgbW9uZ29XaGVyZSA9IHRyYW5zZm9ybVdoZXJlKGNsYXNzTmFtZSwgcXVlcnksIHNjaGVtYSk7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+XG4gICAgICAgIGNvbGxlY3Rpb24uX21vbmdvQ29sbGVjdGlvbi5maW5kT25lQW5kVXBkYXRlKG1vbmdvV2hlcmUsIG1vbmdvVXBkYXRlLCB7XG4gICAgICAgICAgcmV0dXJuRG9jdW1lbnQ6ICdhZnRlcicsXG4gICAgICAgICAgc2Vzc2lvbjogdHJhbnNhY3Rpb25hbFNlc3Npb24gfHwgdW5kZWZpbmVkLFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzdWx0ID0+IG1vbmdvT2JqZWN0VG9QYXJzZU9iamVjdChjbGFzc05hbWUsIHJlc3VsdCwgc2NoZW1hKSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvci5jb2RlID09PSAxMTAwMCkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLkRVUExJQ0FURV9WQUxVRSxcbiAgICAgICAgICAgICdBIGR1cGxpY2F0ZSB2YWx1ZSBmb3IgYSBmaWVsZCB3aXRoIHVuaXF1ZSB2YWx1ZXMgd2FzIHByb3ZpZGVkJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gSG9wZWZ1bGx5IHdlIGNhbiBnZXQgcmlkIG9mIHRoaXMuIEl0J3Mgb25seSB1c2VkIGZvciBjb25maWcgYW5kIGhvb2tzLlxuICB1cHNlcnRPbmVPYmplY3QoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIHF1ZXJ5OiBRdWVyeVR5cGUsXG4gICAgdXBkYXRlOiBhbnksXG4gICAgdHJhbnNhY3Rpb25hbFNlc3Npb246ID9hbnlcbiAgKSB7XG4gICAgc2NoZW1hID0gY29udmVydFBhcnNlU2NoZW1hVG9Nb25nb1NjaGVtYShzY2hlbWEpO1xuICAgIGNvbnN0IG1vbmdvVXBkYXRlID0gdHJhbnNmb3JtVXBkYXRlKGNsYXNzTmFtZSwgdXBkYXRlLCBzY2hlbWEpO1xuICAgIGNvbnN0IG1vbmdvV2hlcmUgPSB0cmFuc2Zvcm1XaGVyZShjbGFzc05hbWUsIHF1ZXJ5LCBzY2hlbWEpO1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLnVwc2VydE9uZShtb25nb1doZXJlLCBtb25nb1VwZGF0ZSwgdHJhbnNhY3Rpb25hbFNlc3Npb24pKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gRXhlY3V0ZXMgYSBmaW5kLiBBY2NlcHRzOiBjbGFzc05hbWUsIHF1ZXJ5IGluIFBhcnNlIGZvcm1hdCwgYW5kIHsgc2tpcCwgbGltaXQsIHNvcnQgfS5cbiAgZmluZChcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBzY2hlbWE6IFNjaGVtYVR5cGUsXG4gICAgcXVlcnk6IFF1ZXJ5VHlwZSxcbiAgICB7XG4gICAgICBza2lwLFxuICAgICAgbGltaXQsXG4gICAgICBzb3J0LFxuICAgICAga2V5cyxcbiAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgaGludCxcbiAgICAgIGNhc2VJbnNlbnNpdGl2ZSxcbiAgICAgIGV4cGxhaW4sXG4gICAgICBjb21tZW50LFxuICAgIH06IFF1ZXJ5T3B0aW9uc1xuICApOiBQcm9taXNlPGFueT4ge1xuICAgIHZhbGlkYXRlRXhwbGFpblZhbHVlKGV4cGxhaW4pO1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb1doZXJlID0gdHJhbnNmb3JtV2hlcmUoY2xhc3NOYW1lLCBxdWVyeSwgc2NoZW1hKTtcbiAgICBjb25zdCBtb25nb1NvcnQgPSBfLm1hcEtleXMoc29ydCwgKHZhbHVlLCBmaWVsZE5hbWUpID0+XG4gICAgICB0cmFuc2Zvcm1LZXkoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHNjaGVtYSlcbiAgICApO1xuICAgIGNvbnN0IG1vbmdvS2V5cyA9IF8ucmVkdWNlKFxuICAgICAga2V5cyxcbiAgICAgIChtZW1vLCBrZXkpID0+IHtcbiAgICAgICAgaWYgKGtleSA9PT0gJ0FDTCcpIHtcbiAgICAgICAgICBtZW1vWydfcnBlcm0nXSA9IDE7XG4gICAgICAgICAgbWVtb1snX3dwZXJtJ10gPSAxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG1lbW9bdHJhbnNmb3JtS2V5KGNsYXNzTmFtZSwga2V5LCBzY2hlbWEpXSA9IDE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lbW87XG4gICAgICB9LFxuICAgICAge31cbiAgICApO1xuXG4gICAgLy8gSWYgd2UgYXJlbid0IHJlcXVlc3RpbmcgdGhlIGBfaWRgIGZpZWxkLCB3ZSBuZWVkIHRvIGV4cGxpY2l0bHkgb3B0IG91dFxuICAgIC8vIG9mIGl0LiBEb2luZyBzbyBpbiBwYXJzZS1zZXJ2ZXIgaXMgdW51c3VhbCwgYnV0IGl0IGNhbiBhbGxvdyB1cyB0b1xuICAgIC8vIG9wdGltaXplIHNvbWUgcXVlcmllcyB3aXRoIGNvdmVyaW5nIGluZGV4ZXMuXG4gICAgaWYgKGtleXMgJiYgIW1vbmdvS2V5cy5faWQpIHtcbiAgICAgIG1vbmdvS2V5cy5faWQgPSAwO1xuICAgIH1cblxuICAgIHJlYWRQcmVmZXJlbmNlID0gdGhpcy5fcGFyc2VSZWFkUHJlZmVyZW5jZShyZWFkUHJlZmVyZW5jZSk7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlVGV4dEluZGV4ZXNJZk5lZWRlZChjbGFzc05hbWUsIHF1ZXJ5LCBzY2hlbWEpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT5cbiAgICAgICAgY29sbGVjdGlvbi5maW5kKG1vbmdvV2hlcmUsIHtcbiAgICAgICAgICBza2lwLFxuICAgICAgICAgIGxpbWl0LFxuICAgICAgICAgIHNvcnQ6IG1vbmdvU29ydCxcbiAgICAgICAgICBrZXlzOiBtb25nb0tleXMsXG4gICAgICAgICAgbWF4VGltZU1TOiB0aGlzLl9tYXhUaW1lTVMsXG4gICAgICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgaGludCxcbiAgICAgICAgICBjYXNlSW5zZW5zaXRpdmUsXG4gICAgICAgICAgZXhwbGFpbixcbiAgICAgICAgICBjb21tZW50LFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLnRoZW4ob2JqZWN0cyA9PiB7XG4gICAgICAgIGlmIChleHBsYWluKSB7XG4gICAgICAgICAgcmV0dXJuIG9iamVjdHM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iamVjdHMubWFwKG9iamVjdCA9PiBtb25nb09iamVjdFRvUGFyc2VPYmplY3QoY2xhc3NOYW1lLCBvYmplY3QsIHNjaGVtYSkpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIGVuc3VyZUluZGV4KFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHNjaGVtYTogU2NoZW1hVHlwZSxcbiAgICBmaWVsZE5hbWVzOiBzdHJpbmdbXSxcbiAgICBpbmRleE5hbWU6ID9zdHJpbmcsXG4gICAgY2FzZUluc2Vuc2l0aXZlOiBib29sZWFuID0gZmFsc2UsXG4gICAgb3B0aW9ucz86IE9iamVjdCA9IHt9XG4gICk6IFByb21pc2U8YW55PiB7XG4gICAgc2NoZW1hID0gY29udmVydFBhcnNlU2NoZW1hVG9Nb25nb1NjaGVtYShzY2hlbWEpO1xuICAgIGNvbnN0IGluZGV4Q3JlYXRpb25SZXF1ZXN0ID0ge307XG4gICAgY29uc3QgbW9uZ29GaWVsZE5hbWVzID0gZmllbGROYW1lcy5tYXAoZmllbGROYW1lID0+IHRyYW5zZm9ybUtleShjbGFzc05hbWUsIGZpZWxkTmFtZSwgc2NoZW1hKSk7XG4gICAgbW9uZ29GaWVsZE5hbWVzLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgIGluZGV4Q3JlYXRpb25SZXF1ZXN0W2ZpZWxkTmFtZV0gPSBvcHRpb25zLmluZGV4VHlwZSAhPT0gdW5kZWZpbmVkID8gb3B0aW9ucy5pbmRleFR5cGUgOiAxO1xuICAgIH0pO1xuXG4gICAgY29uc3QgZGVmYXVsdE9wdGlvbnM6IE9iamVjdCA9IHsgYmFja2dyb3VuZDogdHJ1ZSwgc3BhcnNlOiB0cnVlIH07XG4gICAgY29uc3QgaW5kZXhOYW1lT3B0aW9uczogT2JqZWN0ID0gaW5kZXhOYW1lID8geyBuYW1lOiBpbmRleE5hbWUgfSA6IHt9O1xuICAgIGNvbnN0IHR0bE9wdGlvbnM6IE9iamVjdCA9IG9wdGlvbnMudHRsICE9PSB1bmRlZmluZWQgPyB7IGV4cGlyZUFmdGVyU2Vjb25kczogb3B0aW9ucy50dGwgfSA6IHt9O1xuICAgIGNvbnN0IHNwYXJzZU9wdGlvbnM6IE9iamVjdCA9IG9wdGlvbnMuc3BhcnNlICE9PSB1bmRlZmluZWQgPyB7IHNwYXJzZTogb3B0aW9ucy5zcGFyc2UgfSA6IHt9O1xuICAgIGNvbnN0IGNhc2VJbnNlbnNpdGl2ZU9wdGlvbnM6IE9iamVjdCA9IGNhc2VJbnNlbnNpdGl2ZVxuICAgICAgPyB7IGNvbGxhdGlvbjogTW9uZ29Db2xsZWN0aW9uLmNhc2VJbnNlbnNpdGl2ZUNvbGxhdGlvbigpIH1cbiAgICAgIDoge307XG4gICAgY29uc3QgaW5kZXhPcHRpb25zOiBPYmplY3QgPSB7XG4gICAgICAuLi5kZWZhdWx0T3B0aW9ucyxcbiAgICAgIC4uLmNhc2VJbnNlbnNpdGl2ZU9wdGlvbnMsXG4gICAgICAuLi5pbmRleE5hbWVPcHRpb25zLFxuICAgICAgLi4udHRsT3B0aW9ucyxcbiAgICAgIC4uLnNwYXJzZU9wdGlvbnMsXG4gICAgfTtcblxuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PlxuICAgICAgICBjb2xsZWN0aW9uLl9tb25nb0NvbGxlY3Rpb24uY3JlYXRlSW5kZXgoaW5kZXhDcmVhdGlvblJlcXVlc3QsIGluZGV4T3B0aW9ucylcbiAgICAgIClcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIC8vIENyZWF0ZSBhIHVuaXF1ZSBpbmRleC4gVW5pcXVlIGluZGV4ZXMgb24gbnVsbGFibGUgZmllbGRzIGFyZSBub3QgYWxsb3dlZC4gU2luY2Ugd2UgZG9uJ3RcbiAgLy8gY3VycmVudGx5IGtub3cgd2hpY2ggZmllbGRzIGFyZSBudWxsYWJsZSBhbmQgd2hpY2ggYXJlbid0LCB3ZSBpZ25vcmUgdGhhdCBjcml0ZXJpYS5cbiAgLy8gQXMgc3VjaCwgd2Ugc2hvdWxkbid0IGV4cG9zZSB0aGlzIGZ1bmN0aW9uIHRvIHVzZXJzIG9mIHBhcnNlIHVudGlsIHdlIGhhdmUgYW4gb3V0LW9mLWJhbmRcbiAgLy8gV2F5IG9mIGRldGVybWluaW5nIGlmIGEgZmllbGQgaXMgbnVsbGFibGUuIFVuZGVmaW5lZCBkb2Vzbid0IGNvdW50IGFnYWluc3QgdW5pcXVlbmVzcyxcbiAgLy8gd2hpY2ggaXMgd2h5IHdlIHVzZSBzcGFyc2UgaW5kZXhlcy5cbiAgZW5zdXJlVW5pcXVlbmVzcyhjbGFzc05hbWU6IHN0cmluZywgc2NoZW1hOiBTY2hlbWFUeXBlLCBmaWVsZE5hbWVzOiBzdHJpbmdbXSkge1xuICAgIHNjaGVtYSA9IGNvbnZlcnRQYXJzZVNjaGVtYVRvTW9uZ29TY2hlbWEoc2NoZW1hKTtcbiAgICBjb25zdCBpbmRleENyZWF0aW9uUmVxdWVzdCA9IHt9O1xuICAgIGNvbnN0IG1vbmdvRmllbGROYW1lcyA9IGZpZWxkTmFtZXMubWFwKGZpZWxkTmFtZSA9PiB0cmFuc2Zvcm1LZXkoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHNjaGVtYSkpO1xuICAgIG1vbmdvRmllbGROYW1lcy5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICBpbmRleENyZWF0aW9uUmVxdWVzdFtmaWVsZE5hbWVdID0gMTtcbiAgICB9KTtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5fZW5zdXJlU3BhcnNlVW5pcXVlSW5kZXhJbkJhY2tncm91bmQoaW5kZXhDcmVhdGlvblJlcXVlc3QpKVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDExMDAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuRFVQTElDQVRFX1ZBTFVFLFxuICAgICAgICAgICAgJ1RyaWVkIHRvIGVuc3VyZSBmaWVsZCB1bmlxdWVuZXNzIGZvciBhIGNsYXNzIHRoYXQgYWxyZWFkeSBoYXMgZHVwbGljYXRlcy4nXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICAvLyBVc2VkIGluIHRlc3RzXG4gIF9yYXdGaW5kKGNsYXNzTmFtZTogc3RyaW5nLCBxdWVyeTogUXVlcnlUeXBlKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+XG4gICAgICAgIGNvbGxlY3Rpb24uZmluZChxdWVyeSwge1xuICAgICAgICAgIG1heFRpbWVNUzogdGhpcy5fbWF4VGltZU1TLFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gRXhlY3V0ZXMgYSBjb3VudC5cbiAgY291bnQoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBTY2hlbWFUeXBlLFxuICAgIHF1ZXJ5OiBRdWVyeVR5cGUsXG4gICAgcmVhZFByZWZlcmVuY2U6ID9zdHJpbmcsXG4gICAgX2VzdGltYXRlOiA/Ym9vbGVhbixcbiAgICBoaW50OiA/bWl4ZWQsXG4gICAgY29tbWVudDogP3N0cmluZ1xuICApIHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgcmVhZFByZWZlcmVuY2UgPSB0aGlzLl9wYXJzZVJlYWRQcmVmZXJlbmNlKHJlYWRQcmVmZXJlbmNlKTtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT5cbiAgICAgICAgY29sbGVjdGlvbi5jb3VudCh0cmFuc2Zvcm1XaGVyZShjbGFzc05hbWUsIHF1ZXJ5LCBzY2hlbWEsIHRydWUpLCB7XG4gICAgICAgICAgbWF4VGltZU1TOiB0aGlzLl9tYXhUaW1lTVMsXG4gICAgICAgICAgcmVhZFByZWZlcmVuY2UsXG4gICAgICAgICAgaGludCxcbiAgICAgICAgICBjb21tZW50LFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgZGlzdGluY3QoY2xhc3NOYW1lOiBzdHJpbmcsIHNjaGVtYTogU2NoZW1hVHlwZSwgcXVlcnk6IFF1ZXJ5VHlwZSwgZmllbGROYW1lOiBzdHJpbmcpIHtcbiAgICBzY2hlbWEgPSBjb252ZXJ0UGFyc2VTY2hlbWFUb01vbmdvU2NoZW1hKHNjaGVtYSk7XG4gICAgY29uc3QgaXNQb2ludGVyRmllbGQgPSBzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0gJiYgc2NoZW1hLmZpZWxkc1tmaWVsZE5hbWVdLnR5cGUgPT09ICdQb2ludGVyJztcbiAgICBjb25zdCB0cmFuc2Zvcm1GaWVsZCA9IHRyYW5zZm9ybUtleShjbGFzc05hbWUsIGZpZWxkTmFtZSwgc2NoZW1hKTtcblxuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PlxuICAgICAgICBjb2xsZWN0aW9uLmRpc3RpbmN0KHRyYW5zZm9ybUZpZWxkLCB0cmFuc2Zvcm1XaGVyZShjbGFzc05hbWUsIHF1ZXJ5LCBzY2hlbWEpKVxuICAgICAgKVxuICAgICAgLnRoZW4ob2JqZWN0cyA9PiB7XG4gICAgICAgIG9iamVjdHMgPSBvYmplY3RzLmZpbHRlcihvYmogPT4gb2JqICE9IG51bGwpO1xuICAgICAgICByZXR1cm4gb2JqZWN0cy5tYXAob2JqZWN0ID0+IHtcbiAgICAgICAgICBpZiAoaXNQb2ludGVyRmllbGQpIHtcbiAgICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1Qb2ludGVyU3RyaW5nKHNjaGVtYSwgZmllbGROYW1lLCBvYmplY3QpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbW9uZ29PYmplY3RUb1BhcnNlT2JqZWN0KGNsYXNzTmFtZSwgb2JqZWN0LCBzY2hlbWEpO1xuICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBhZ2dyZWdhdGUoXG4gICAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gICAgc2NoZW1hOiBhbnksXG4gICAgcGlwZWxpbmU6IGFueSxcbiAgICByZWFkUHJlZmVyZW5jZTogP3N0cmluZyxcbiAgICBoaW50OiA/bWl4ZWQsXG4gICAgZXhwbGFpbj86IGJvb2xlYW4sXG4gICAgY29tbWVudDogP3N0cmluZ1xuICApIHtcbiAgICB2YWxpZGF0ZUV4cGxhaW5WYWx1ZShleHBsYWluKTtcbiAgICBsZXQgaXNQb2ludGVyRmllbGQgPSBmYWxzZTtcbiAgICBwaXBlbGluZSA9IHBpcGVsaW5lLm1hcChzdGFnZSA9PiB7XG4gICAgICBpZiAoc3RhZ2UuJGdyb3VwKSB7XG4gICAgICAgIHN0YWdlLiRncm91cCA9IHRoaXMuX3BhcnNlQWdncmVnYXRlR3JvdXBBcmdzKHNjaGVtYSwgc3RhZ2UuJGdyb3VwKTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHN0YWdlLiRncm91cC5faWQgJiZcbiAgICAgICAgICB0eXBlb2Ygc3RhZ2UuJGdyb3VwLl9pZCA9PT0gJ3N0cmluZycgJiZcbiAgICAgICAgICBzdGFnZS4kZ3JvdXAuX2lkLmluZGV4T2YoJyRfcF8nKSA+PSAwXG4gICAgICAgICkge1xuICAgICAgICAgIGlzUG9pbnRlckZpZWxkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHN0YWdlLiRtYXRjaCkge1xuICAgICAgICBzdGFnZS4kbWF0Y2ggPSB0aGlzLl9wYXJzZUFnZ3JlZ2F0ZUFyZ3Moc2NoZW1hLCBzdGFnZS4kbWF0Y2gpO1xuICAgICAgfVxuICAgICAgaWYgKHN0YWdlLiRwcm9qZWN0KSB7XG4gICAgICAgIHN0YWdlLiRwcm9qZWN0ID0gdGhpcy5fcGFyc2VBZ2dyZWdhdGVQcm9qZWN0QXJncyhzY2hlbWEsIHN0YWdlLiRwcm9qZWN0KTtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFnZS4kZ2VvTmVhciAmJiBzdGFnZS4kZ2VvTmVhci5xdWVyeSkge1xuICAgICAgICBzdGFnZS4kZ2VvTmVhci5xdWVyeSA9IHRoaXMuX3BhcnNlQWdncmVnYXRlQXJncyhzY2hlbWEsIHN0YWdlLiRnZW9OZWFyLnF1ZXJ5KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzdGFnZTtcbiAgICB9KTtcbiAgICByZWFkUHJlZmVyZW5jZSA9IHRoaXMuX3BhcnNlUmVhZFByZWZlcmVuY2UocmVhZFByZWZlcmVuY2UpO1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PlxuICAgICAgICBjb2xsZWN0aW9uLmFnZ3JlZ2F0ZShwaXBlbGluZSwge1xuICAgICAgICAgIHJlYWRQcmVmZXJlbmNlLFxuICAgICAgICAgIG1heFRpbWVNUzogdGhpcy5fbWF4VGltZU1TLFxuICAgICAgICAgIGhpbnQsXG4gICAgICAgICAgZXhwbGFpbixcbiAgICAgICAgICBjb21tZW50LFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLnRoZW4ocmVzdWx0cyA9PiB7XG4gICAgICAgIHJlc3VsdHMuZm9yRWFjaChyZXN1bHQgPT4ge1xuICAgICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwocmVzdWx0LCAnX2lkJykpIHtcbiAgICAgICAgICAgIGlmIChpc1BvaW50ZXJGaWVsZCAmJiByZXN1bHQuX2lkKSB7XG4gICAgICAgICAgICAgIHJlc3VsdC5faWQgPSByZXN1bHQuX2lkLnNwbGl0KCckJylbMV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgIHJlc3VsdC5faWQgPT0gbnVsbCB8fFxuICAgICAgICAgICAgICByZXN1bHQuX2lkID09IHVuZGVmaW5lZCB8fFxuICAgICAgICAgICAgICAoWydvYmplY3QnLCAnc3RyaW5nJ10uaW5jbHVkZXModHlwZW9mIHJlc3VsdC5faWQpICYmIF8uaXNFbXB0eShyZXN1bHQuX2lkKSlcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICByZXN1bHQuX2lkID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc3VsdC5vYmplY3RJZCA9IHJlc3VsdC5faWQ7XG4gICAgICAgICAgICBkZWxldGUgcmVzdWx0Ll9pZDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgIH0pXG4gICAgICAudGhlbihvYmplY3RzID0+IG9iamVjdHMubWFwKG9iamVjdCA9PiBtb25nb09iamVjdFRvUGFyc2VPYmplY3QoY2xhc3NOYW1lLCBvYmplY3QsIHNjaGVtYSkpKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgLy8gVGhpcyBmdW5jdGlvbiB3aWxsIHJlY3Vyc2l2ZWx5IHRyYXZlcnNlIHRoZSBwaXBlbGluZSBhbmQgY29udmVydCBhbnkgUG9pbnRlciBvciBEYXRlIGNvbHVtbnMuXG4gIC8vIElmIHdlIGRldGVjdCBhIHBvaW50ZXIgY29sdW1uIHdlIHdpbGwgcmVuYW1lIHRoZSBjb2x1bW4gYmVpbmcgcXVlcmllZCBmb3IgdG8gbWF0Y2ggdGhlIGNvbHVtblxuICAvLyBpbiB0aGUgZGF0YWJhc2UuIFdlIGFsc28gbW9kaWZ5IHRoZSB2YWx1ZSB0byB3aGF0IHdlIGV4cGVjdCB0aGUgdmFsdWUgdG8gYmUgaW4gdGhlIGRhdGFiYXNlXG4gIC8vIGFzIHdlbGwuXG4gIC8vIEZvciBkYXRlcywgdGhlIGRyaXZlciBleHBlY3RzIGEgRGF0ZSBvYmplY3QsIGJ1dCB3ZSBoYXZlIGEgc3RyaW5nIGNvbWluZyBpbi4gU28gd2UnbGwgY29udmVydFxuICAvLyB0aGUgc3RyaW5nIHRvIGEgRGF0ZSBzbyB0aGUgZHJpdmVyIGNhbiBwZXJmb3JtIHRoZSBuZWNlc3NhcnkgY29tcGFyaXNvbi5cbiAgLy9cbiAgLy8gVGhlIGdvYWwgb2YgdGhpcyBtZXRob2QgaXMgdG8gbG9vayBmb3IgdGhlIFwibGVhdmVzXCIgb2YgdGhlIHBpcGVsaW5lIGFuZCBkZXRlcm1pbmUgaWYgaXQgbmVlZHNcbiAgLy8gdG8gYmUgY29udmVydGVkLiBUaGUgcGlwZWxpbmUgY2FuIGhhdmUgYSBmZXcgZGlmZmVyZW50IGZvcm1zLiBGb3IgbW9yZSBkZXRhaWxzLCBzZWU6XG4gIC8vICAgICBodHRwczovL2RvY3MubW9uZ29kYi5jb20vbWFudWFsL3JlZmVyZW5jZS9vcGVyYXRvci9hZ2dyZWdhdGlvbi9cbiAgLy9cbiAgLy8gSWYgdGhlIHBpcGVsaW5lIGlzIGFuIGFycmF5LCBpdCBtZWFucyB3ZSBhcmUgcHJvYmFibHkgcGFyc2luZyBhbiAnJGFuZCcgb3IgJyRvcicgb3BlcmF0b3IuIEluXG4gIC8vIHRoYXQgY2FzZSB3ZSBuZWVkIHRvIGxvb3AgdGhyb3VnaCBhbGwgb2YgaXQncyBjaGlsZHJlbiB0byBmaW5kIHRoZSBjb2x1bW5zIGJlaW5nIG9wZXJhdGVkIG9uLlxuICAvLyBJZiB0aGUgcGlwZWxpbmUgaXMgYW4gb2JqZWN0LCB0aGVuIHdlJ2xsIGxvb3AgdGhyb3VnaCB0aGUga2V5cyBjaGVja2luZyB0byBzZWUgaWYgdGhlIGtleSBuYW1lXG4gIC8vIG1hdGNoZXMgb25lIG9mIHRoZSBzY2hlbWEgY29sdW1ucy4gSWYgaXQgZG9lcyBtYXRjaCBhIGNvbHVtbiBhbmQgdGhlIGNvbHVtbiBpcyBhIFBvaW50ZXIgb3JcbiAgLy8gYSBEYXRlLCB0aGVuIHdlJ2xsIGNvbnZlcnQgdGhlIHZhbHVlIGFzIGRlc2NyaWJlZCBhYm92ZS5cbiAgLy9cbiAgLy8gQXMgbXVjaCBhcyBJIGhhdGUgcmVjdXJzaW9uLi4udGhpcyBzZWVtZWQgbGlrZSBhIGdvb2QgZml0IGZvciBpdC4gV2UncmUgZXNzZW50aWFsbHkgdHJhdmVyc2luZ1xuICAvLyBkb3duIGEgdHJlZSB0byBmaW5kIGEgXCJsZWFmIG5vZGVcIiBhbmQgY2hlY2tpbmcgdG8gc2VlIGlmIGl0IG5lZWRzIHRvIGJlIGNvbnZlcnRlZC5cbiAgX3BhcnNlQWdncmVnYXRlQXJncyhzY2hlbWE6IGFueSwgcGlwZWxpbmU6IGFueSk6IGFueSB7XG4gICAgaWYgKHBpcGVsaW5lID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkocGlwZWxpbmUpKSB7XG4gICAgICByZXR1cm4gcGlwZWxpbmUubWFwKHZhbHVlID0+IHRoaXMuX3BhcnNlQWdncmVnYXRlQXJncyhzY2hlbWEsIHZhbHVlKSk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgcGlwZWxpbmUgPT09ICdvYmplY3QnKSB7XG4gICAgICBjb25zdCByZXR1cm5WYWx1ZSA9IHt9O1xuICAgICAgZm9yIChjb25zdCBmaWVsZCBpbiBwaXBlbGluZSkge1xuICAgICAgICBpZiAoc2NoZW1hLmZpZWxkc1tmaWVsZF0gJiYgc2NoZW1hLmZpZWxkc1tmaWVsZF0udHlwZSA9PT0gJ1BvaW50ZXInKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBwaXBlbGluZVtmaWVsZF0gPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAvLyBQYXNzIG9iamVjdHMgZG93biB0byBNb25nb0RCLi4udGhpcyBpcyBtb3JlIHRoYW4gbGlrZWx5IGFuICRleGlzdHMgb3BlcmF0b3IuXG4gICAgICAgICAgICByZXR1cm5WYWx1ZVtgX3BfJHtmaWVsZH1gXSA9IHBpcGVsaW5lW2ZpZWxkXTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuVmFsdWVbYF9wXyR7ZmllbGR9YF0gPSBgJHtzY2hlbWEuZmllbGRzW2ZpZWxkXS50YXJnZXRDbGFzc30kJHtwaXBlbGluZVtmaWVsZF19YDtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoc2NoZW1hLmZpZWxkc1tmaWVsZF0gJiYgc2NoZW1hLmZpZWxkc1tmaWVsZF0udHlwZSA9PT0gJ0RhdGUnKSB7XG4gICAgICAgICAgcmV0dXJuVmFsdWVbZmllbGRdID0gdGhpcy5fY29udmVydFRvRGF0ZShwaXBlbGluZVtmaWVsZF0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVyblZhbHVlW2ZpZWxkXSA9IHRoaXMuX3BhcnNlQWdncmVnYXRlQXJncyhzY2hlbWEsIHBpcGVsaW5lW2ZpZWxkXSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZmllbGQgPT09ICdvYmplY3RJZCcpIHtcbiAgICAgICAgICByZXR1cm5WYWx1ZVsnX2lkJ10gPSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICAgICAgZGVsZXRlIHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgICAgfSBlbHNlIGlmIChmaWVsZCA9PT0gJ2NyZWF0ZWRBdCcpIHtcbiAgICAgICAgICByZXR1cm5WYWx1ZVsnX2NyZWF0ZWRfYXQnXSA9IHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgICAgICBkZWxldGUgcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgICB9IGVsc2UgaWYgKGZpZWxkID09PSAndXBkYXRlZEF0Jykge1xuICAgICAgICAgIHJldHVyblZhbHVlWydfdXBkYXRlZF9hdCddID0gcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgICAgIGRlbGV0ZSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuIHBpcGVsaW5lO1xuICB9XG5cbiAgLy8gVGhpcyBmdW5jdGlvbiBpcyBzbGlnaHRseSBkaWZmZXJlbnQgdGhhbiB0aGUgb25lIGFib3ZlLiBSYXRoZXIgdGhhbiB0cnlpbmcgdG8gY29tYmluZSB0aGVzZVxuICAvLyB0d28gZnVuY3Rpb25zIGFuZCBtYWtpbmcgdGhlIGNvZGUgZXZlbiBoYXJkZXIgdG8gdW5kZXJzdGFuZCwgSSBkZWNpZGVkIHRvIHNwbGl0IGl0IHVwLiBUaGVcbiAgLy8gZGlmZmVyZW5jZSB3aXRoIHRoaXMgZnVuY3Rpb24gaXMgd2UgYXJlIG5vdCB0cmFuc2Zvcm1pbmcgdGhlIHZhbHVlcywgb25seSB0aGUga2V5cyBvZiB0aGVcbiAgLy8gcGlwZWxpbmUuXG4gIF9wYXJzZUFnZ3JlZ2F0ZVByb2plY3RBcmdzKHNjaGVtYTogYW55LCBwaXBlbGluZTogYW55KTogYW55IHtcbiAgICBjb25zdCByZXR1cm5WYWx1ZSA9IHt9O1xuICAgIGZvciAoY29uc3QgZmllbGQgaW4gcGlwZWxpbmUpIHtcbiAgICAgIGlmIChzY2hlbWEuZmllbGRzW2ZpZWxkXSAmJiBzY2hlbWEuZmllbGRzW2ZpZWxkXS50eXBlID09PSAnUG9pbnRlcicpIHtcbiAgICAgICAgcmV0dXJuVmFsdWVbYF9wXyR7ZmllbGR9YF0gPSBwaXBlbGluZVtmaWVsZF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm5WYWx1ZVtmaWVsZF0gPSB0aGlzLl9wYXJzZUFnZ3JlZ2F0ZUFyZ3Moc2NoZW1hLCBwaXBlbGluZVtmaWVsZF0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoZmllbGQgPT09ICdvYmplY3RJZCcpIHtcbiAgICAgICAgcmV0dXJuVmFsdWVbJ19pZCddID0gcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgICBkZWxldGUgcmV0dXJuVmFsdWVbZmllbGRdO1xuICAgICAgfSBlbHNlIGlmIChmaWVsZCA9PT0gJ2NyZWF0ZWRBdCcpIHtcbiAgICAgICAgcmV0dXJuVmFsdWVbJ19jcmVhdGVkX2F0J10gPSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICAgIGRlbGV0ZSByZXR1cm5WYWx1ZVtmaWVsZF07XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkID09PSAndXBkYXRlZEF0Jykge1xuICAgICAgICByZXR1cm5WYWx1ZVsnX3VwZGF0ZWRfYXQnXSA9IHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgICAgZGVsZXRlIHJldHVyblZhbHVlW2ZpZWxkXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJldHVyblZhbHVlO1xuICB9XG5cbiAgLy8gVGhpcyBmdW5jdGlvbiBpcyBzbGlnaHRseSBkaWZmZXJlbnQgdGhhbiB0aGUgdHdvIGFib3ZlLiBNb25nb0RCICRncm91cCBhZ2dyZWdhdGUgbG9va3MgbGlrZTpcbiAgLy8gICAgIHsgJGdyb3VwOiB7IF9pZDogPGV4cHJlc3Npb24+LCA8ZmllbGQxPjogeyA8YWNjdW11bGF0b3IxPiA6IDxleHByZXNzaW9uMT4gfSwgLi4uIH0gfVxuICAvLyBUaGUgPGV4cHJlc3Npb24+IGNvdWxkIGJlIGEgY29sdW1uIG5hbWUsIHByZWZpeGVkIHdpdGggdGhlICckJyBjaGFyYWN0ZXIuIFdlJ2xsIGxvb2sgZm9yXG4gIC8vIHRoZXNlIDxleHByZXNzaW9uPiBhbmQgY2hlY2sgdG8gc2VlIGlmIGl0IGlzIGEgJ1BvaW50ZXInIG9yIGlmIGl0J3Mgb25lIG9mIGNyZWF0ZWRBdCxcbiAgLy8gdXBkYXRlZEF0IG9yIG9iamVjdElkIGFuZCBjaGFuZ2UgaXQgYWNjb3JkaW5nbHkuXG4gIF9wYXJzZUFnZ3JlZ2F0ZUdyb3VwQXJncyhzY2hlbWE6IGFueSwgcGlwZWxpbmU6IGFueSk6IGFueSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocGlwZWxpbmUpKSB7XG4gICAgICByZXR1cm4gcGlwZWxpbmUubWFwKHZhbHVlID0+IHRoaXMuX3BhcnNlQWdncmVnYXRlR3JvdXBBcmdzKHNjaGVtYSwgdmFsdWUpKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBwaXBlbGluZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGNvbnN0IHJldHVyblZhbHVlID0ge307XG4gICAgICBmb3IgKGNvbnN0IGZpZWxkIGluIHBpcGVsaW5lKSB7XG4gICAgICAgIHJldHVyblZhbHVlW2ZpZWxkXSA9IHRoaXMuX3BhcnNlQWdncmVnYXRlR3JvdXBBcmdzKHNjaGVtYSwgcGlwZWxpbmVbZmllbGRdKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBwaXBlbGluZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGNvbnN0IGZpZWxkID0gcGlwZWxpbmUuc3Vic3RyaW5nKDEpO1xuICAgICAgaWYgKHNjaGVtYS5maWVsZHNbZmllbGRdICYmIHNjaGVtYS5maWVsZHNbZmllbGRdLnR5cGUgPT09ICdQb2ludGVyJykge1xuICAgICAgICByZXR1cm4gYCRfcF8ke2ZpZWxkfWA7XG4gICAgICB9IGVsc2UgaWYgKGZpZWxkID09ICdjcmVhdGVkQXQnKSB7XG4gICAgICAgIHJldHVybiAnJF9jcmVhdGVkX2F0JztcbiAgICAgIH0gZWxzZSBpZiAoZmllbGQgPT0gJ3VwZGF0ZWRBdCcpIHtcbiAgICAgICAgcmV0dXJuICckX3VwZGF0ZWRfYXQnO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcGlwZWxpbmU7XG4gIH1cblxuICAvKipcbiAgICogUmVjdXJzaXZlbHkgY29udmVydHMgdmFsdWVzIHRvIERhdGUgb2JqZWN0cy4gU2luY2UgdGhlIHBhc3NlZCBvYmplY3QgaXMgcGFydCBvZiBhbiBhZ2dyZWdhdGlvblxuICAgKiBwaXBlbGluZSBhbmQgY2FuIGNvbnRhaW4gdmFyaW91cyBsb2dpYyBvcGVyYXRvcnMgKGxpa2UgJGd0LCAkbHQsIGV0YyksIHRoaXMgZnVuY3Rpb24gd2lsbFxuICAgKiB0cmF2ZXJzZSB0aGUgb2JqZWN0IGFuZCBjb252ZXJ0IGFueSBzdHJpbmdzIHRoYXQgY2FuIGJlIHBhcnNlZCBhcyBkYXRlcyBpbnRvIERhdGUgb2JqZWN0cy5cbiAgICogQHBhcmFtIHthbnl9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICAgKiBAcmV0dXJucyB7YW55fSBUaGUgb3JpZ2luYWwgdmFsdWUgaWYgbm90IGNvbnZlcnRpYmxlIHRvIERhdGUsIG9yIGEgRGF0ZSBvYmplY3QgaWYgaXQgaXMuXG4gICAqL1xuICBfY29udmVydFRvRGF0ZSh2YWx1ZTogYW55KTogYW55IHtcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gaXNOYU4oRGF0ZS5wYXJzZSh2YWx1ZSkpID8gdmFsdWUgOiBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICBjb25zdCByZXR1cm5WYWx1ZSA9IHt9O1xuICAgICAgZm9yIChjb25zdCBmaWVsZCBpbiB2YWx1ZSkge1xuICAgICAgICByZXR1cm5WYWx1ZVtmaWVsZF0gPSB0aGlzLl9jb252ZXJ0VG9EYXRlKHZhbHVlW2ZpZWxkXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIF9wYXJzZVJlYWRQcmVmZXJlbmNlKHJlYWRQcmVmZXJlbmNlOiA/c3RyaW5nKTogP3N0cmluZyB7XG4gICAgaWYgKHJlYWRQcmVmZXJlbmNlKSB7XG4gICAgICByZWFkUHJlZmVyZW5jZSA9IHJlYWRQcmVmZXJlbmNlLnRvVXBwZXJDYXNlKCk7XG4gICAgfVxuICAgIHN3aXRjaCAocmVhZFByZWZlcmVuY2UpIHtcbiAgICAgIGNhc2UgJ1BSSU1BUlknOlxuICAgICAgICByZWFkUHJlZmVyZW5jZSA9IFJlYWRQcmVmZXJlbmNlLlBSSU1BUlk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnUFJJTUFSWV9QUkVGRVJSRUQnOlxuICAgICAgICByZWFkUHJlZmVyZW5jZSA9IFJlYWRQcmVmZXJlbmNlLlBSSU1BUllfUFJFRkVSUkVEO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ1NFQ09OREFSWSc6XG4gICAgICAgIHJlYWRQcmVmZXJlbmNlID0gUmVhZFByZWZlcmVuY2UuU0VDT05EQVJZO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ1NFQ09OREFSWV9QUkVGRVJSRUQnOlxuICAgICAgICByZWFkUHJlZmVyZW5jZSA9IFJlYWRQcmVmZXJlbmNlLlNFQ09OREFSWV9QUkVGRVJSRUQ7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnTkVBUkVTVCc6XG4gICAgICAgIHJlYWRQcmVmZXJlbmNlID0gUmVhZFByZWZlcmVuY2UuTkVBUkVTVDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIHVuZGVmaW5lZDpcbiAgICAgIGNhc2UgbnVsbDpcbiAgICAgIGNhc2UgJyc6XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfUVVFUlksICdOb3Qgc3VwcG9ydGVkIHJlYWQgcHJlZmVyZW5jZS4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlYWRQcmVmZXJlbmNlO1xuICB9XG5cbiAgcGVyZm9ybUluaXRpYWxpemF0aW9uKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGNyZWF0ZUluZGV4KGNsYXNzTmFtZTogc3RyaW5nLCBpbmRleDogYW55KSB7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24uX21vbmdvQ29sbGVjdGlvbi5jcmVhdGVJbmRleChpbmRleCkpXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBjcmVhdGVJbmRleGVzKGNsYXNzTmFtZTogc3RyaW5nLCBpbmRleGVzOiBhbnkpIHtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5fbW9uZ29Db2xsZWN0aW9uLmNyZWF0ZUluZGV4ZXMoaW5kZXhlcykpXG4gICAgICAuY2F0Y2goZXJyID0+IHRoaXMuaGFuZGxlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBjcmVhdGVJbmRleGVzSWZOZWVkZWQoY2xhc3NOYW1lOiBzdHJpbmcsIGZpZWxkTmFtZTogc3RyaW5nLCB0eXBlOiBhbnkpIHtcbiAgICBpZiAodHlwZSAmJiB0eXBlLnR5cGUgPT09ICdQb2x5Z29uJykge1xuICAgICAgY29uc3QgaW5kZXggPSB7XG4gICAgICAgIFtmaWVsZE5hbWVdOiAnMmRzcGhlcmUnLFxuICAgICAgfTtcbiAgICAgIHJldHVybiB0aGlzLmNyZWF0ZUluZGV4KGNsYXNzTmFtZSwgaW5kZXgpO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gIH1cblxuICBjcmVhdGVUZXh0SW5kZXhlc0lmTmVlZGVkKGNsYXNzTmFtZTogc3RyaW5nLCBxdWVyeTogUXVlcnlUeXBlLCBzY2hlbWE6IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGZvciAoY29uc3QgZmllbGROYW1lIGluIHF1ZXJ5KSB7XG4gICAgICBpZiAoIXF1ZXJ5W2ZpZWxkTmFtZV0gfHwgIXF1ZXJ5W2ZpZWxkTmFtZV0uJHRleHQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBleGlzdGluZ0luZGV4ZXMgPSBzY2hlbWEuaW5kZXhlcztcbiAgICAgIGZvciAoY29uc3Qga2V5IGluIGV4aXN0aW5nSW5kZXhlcykge1xuICAgICAgICBjb25zdCBpbmRleCA9IGV4aXN0aW5nSW5kZXhlc1trZXldO1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGluZGV4LCBmaWVsZE5hbWUpKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCBpbmRleE5hbWUgPSBgJHtmaWVsZE5hbWV9X3RleHRgO1xuICAgICAgY29uc3QgdGV4dEluZGV4ID0ge1xuICAgICAgICBbaW5kZXhOYW1lXTogeyBbZmllbGROYW1lXTogJ3RleHQnIH0sXG4gICAgICB9O1xuICAgICAgcmV0dXJuIHRoaXMuc2V0SW5kZXhlc1dpdGhTY2hlbWFGb3JtYXQoXG4gICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgdGV4dEluZGV4LFxuICAgICAgICBleGlzdGluZ0luZGV4ZXMsXG4gICAgICAgIHNjaGVtYS5maWVsZHNcbiAgICAgICkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PT0gODUpIHtcbiAgICAgICAgICAvLyBJbmRleCBleGlzdCB3aXRoIGRpZmZlcmVudCBvcHRpb25zXG4gICAgICAgICAgcmV0dXJuIHRoaXMuc2V0SW5kZXhlc0Zyb21Nb25nbyhjbGFzc05hbWUpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIGdldEluZGV4ZXMoY2xhc3NOYW1lOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRpdmVDb2xsZWN0aW9uKGNsYXNzTmFtZSlcbiAgICAgIC50aGVuKGNvbGxlY3Rpb24gPT4gY29sbGVjdGlvbi5fbW9uZ29Db2xsZWN0aW9uLmluZGV4ZXMoKSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIGRyb3BJbmRleChjbGFzc05hbWU6IHN0cmluZywgaW5kZXg6IGFueSkge1xuICAgIHJldHVybiB0aGlzLl9hZGFwdGl2ZUNvbGxlY3Rpb24oY2xhc3NOYW1lKVxuICAgICAgLnRoZW4oY29sbGVjdGlvbiA9PiBjb2xsZWN0aW9uLl9tb25nb0NvbGxlY3Rpb24uZHJvcEluZGV4KGluZGV4KSlcbiAgICAgIC5jYXRjaChlcnIgPT4gdGhpcy5oYW5kbGVFcnJvcihlcnIpKTtcbiAgfVxuXG4gIGRyb3BBbGxJbmRleGVzKGNsYXNzTmFtZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0aXZlQ29sbGVjdGlvbihjbGFzc05hbWUpXG4gICAgICAudGhlbihjb2xsZWN0aW9uID0+IGNvbGxlY3Rpb24uX21vbmdvQ29sbGVjdGlvbi5kcm9wSW5kZXhlcygpKVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgdXBkYXRlU2NoZW1hV2l0aEluZGV4ZXMoKTogUHJvbWlzZTxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy5nZXRBbGxDbGFzc2VzKClcbiAgICAgIC50aGVuKGNsYXNzZXMgPT4ge1xuICAgICAgICBjb25zdCBwcm9taXNlcyA9IGNsYXNzZXMubWFwKHNjaGVtYSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuc2V0SW5kZXhlc0Zyb21Nb25nbyhzY2hlbWEuY2xhc3NOYW1lKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVyciA9PiB0aGlzLmhhbmRsZUVycm9yKGVycikpO1xuICB9XG5cbiAgY3JlYXRlVHJhbnNhY3Rpb25hbFNlc3Npb24oKTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCB0cmFuc2FjdGlvbmFsU2VjdGlvbiA9IHRoaXMuY2xpZW50LnN0YXJ0U2Vzc2lvbigpO1xuICAgIHRyYW5zYWN0aW9uYWxTZWN0aW9uLnN0YXJ0VHJhbnNhY3Rpb24oKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRyYW5zYWN0aW9uYWxTZWN0aW9uKTtcbiAgfVxuXG4gIGNvbW1pdFRyYW5zYWN0aW9uYWxTZXNzaW9uKHRyYW5zYWN0aW9uYWxTZWN0aW9uOiBhbnkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBjb21taXQgPSByZXRyaWVzID0+IHtcbiAgICAgIHJldHVybiB0cmFuc2FjdGlvbmFsU2VjdGlvblxuICAgICAgICAuY29tbWl0VHJhbnNhY3Rpb24oKVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIGlmIChlcnJvciAmJiBlcnJvci5oYXNFcnJvckxhYmVsKCdUcmFuc2llbnRUcmFuc2FjdGlvbkVycm9yJykgJiYgcmV0cmllcyA+IDApIHtcbiAgICAgICAgICAgIHJldHVybiBjb21taXQocmV0cmllcyAtIDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgIHRyYW5zYWN0aW9uYWxTZWN0aW9uLmVuZFNlc3Npb24oKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICByZXR1cm4gY29tbWl0KDUpO1xuICB9XG5cbiAgYWJvcnRUcmFuc2FjdGlvbmFsU2Vzc2lvbih0cmFuc2FjdGlvbmFsU2VjdGlvbjogYW55KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRyYW5zYWN0aW9uYWxTZWN0aW9uLmFib3J0VHJhbnNhY3Rpb24oKS50aGVuKCgpID0+IHtcbiAgICAgIHRyYW5zYWN0aW9uYWxTZWN0aW9uLmVuZFNlc3Npb24oKTtcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBNb25nb1N0b3JhZ2VBZGFwdGVyO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFDQSxJQUFBQSxXQUFBLEdBQUFDLE9BQUE7QUFFQSxJQUFBQyxlQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxnQkFBQSxHQUFBQyxzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQUksc0JBQUEsR0FBQUQsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFLLGVBQUEsR0FBQUwsT0FBQTtBQVNBLElBQUFNLEtBQUEsR0FBQUgsc0JBQUEsQ0FBQUgsT0FBQTtBQUVBLElBQUFPLE9BQUEsR0FBQUosc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFRLFNBQUEsR0FBQUMsdUJBQUEsQ0FBQVQsT0FBQTtBQUNBLElBQUFVLE9BQUEsR0FBQVAsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFXLE1BQUEsR0FBQVIsc0JBQUEsQ0FBQUgsT0FBQTtBQUFtQyxTQUFBUyx3QkFBQUcsQ0FBQSxFQUFBQyxDQUFBLDZCQUFBQyxPQUFBLE1BQUFDLENBQUEsT0FBQUQsT0FBQSxJQUFBRSxDQUFBLE9BQUFGLE9BQUEsWUFBQUwsdUJBQUEsWUFBQUEsQ0FBQUcsQ0FBQSxFQUFBQyxDQUFBLFNBQUFBLENBQUEsSUFBQUQsQ0FBQSxJQUFBQSxDQUFBLENBQUFLLFVBQUEsU0FBQUwsQ0FBQSxNQUFBTSxDQUFBLEVBQUFDLENBQUEsRUFBQUMsQ0FBQSxLQUFBQyxTQUFBLFFBQUFDLE9BQUEsRUFBQVYsQ0FBQSxpQkFBQUEsQ0FBQSx1QkFBQUEsQ0FBQSx5QkFBQUEsQ0FBQSxTQUFBUSxDQUFBLE1BQUFGLENBQUEsR0FBQUwsQ0FBQSxHQUFBRyxDQUFBLEdBQUFELENBQUEsUUFBQUcsQ0FBQSxDQUFBSyxHQUFBLENBQUFYLENBQUEsVUFBQU0sQ0FBQSxDQUFBTSxHQUFBLENBQUFaLENBQUEsR0FBQU0sQ0FBQSxDQUFBTyxHQUFBLENBQUFiLENBQUEsRUFBQVEsQ0FB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
|