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,22 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
var
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
6
|
+
exports.VolatileClassesSchemas = exports.SchemaController = void 0;
|
|
7
|
+
exports.buildMergedSchemaObject = buildMergedSchemaObject;
|
|
8
|
+
exports.classNameIsValid = classNameIsValid;
|
|
9
|
+
exports.defaultColumns = exports.default = exports.convertSchemaToAdapterSchema = void 0;
|
|
10
|
+
exports.fieldNameIsValid = fieldNameIsValid;
|
|
11
|
+
exports.invalidClassNameMessage = invalidClassNameMessage;
|
|
12
|
+
exports.systemClasses = exports.requiredColumns = exports.load = void 0;
|
|
13
|
+
var _StorageAdapter = require("../Adapters/Storage/StorageAdapter");
|
|
14
|
+
var _SchemaCache = _interopRequireDefault(require("../Adapters/Cache/SchemaCache"));
|
|
15
|
+
var _DatabaseController = _interopRequireDefault(require("./DatabaseController"));
|
|
16
|
+
var _Config = _interopRequireDefault(require("../Config"));
|
|
17
|
+
var _Error = require("../Error");
|
|
18
|
+
var _deepcopy = _interopRequireDefault(require("deepcopy"));
|
|
19
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
20
20
|
// This class handles schema validation, persistence, and modification.
|
|
21
21
|
//
|
|
22
22
|
// Each individual Schema object should be immutable. The helpers to
|
|
@@ -35,187 +35,485 @@ function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in ob
|
|
|
35
35
|
// -disable-next
|
|
36
36
|
const Parse = require('parse/node').Parse;
|
|
37
37
|
|
|
38
|
+
// -disable-next
|
|
38
39
|
|
|
39
|
-
const defaultColumns = Object.freeze({
|
|
40
|
+
const defaultColumns = exports.defaultColumns = Object.freeze({
|
|
40
41
|
// Contain the default columns for every parse object type (except _Join collection)
|
|
41
42
|
_Default: {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
objectId: {
|
|
44
|
+
type: 'String'
|
|
45
|
+
},
|
|
46
|
+
createdAt: {
|
|
47
|
+
type: 'Date'
|
|
48
|
+
},
|
|
49
|
+
updatedAt: {
|
|
50
|
+
type: 'Date'
|
|
51
|
+
},
|
|
52
|
+
ACL: {
|
|
53
|
+
type: 'ACL'
|
|
54
|
+
}
|
|
46
55
|
},
|
|
47
56
|
// The additional default columns for the _User collection (in addition to DefaultCols)
|
|
48
57
|
_User: {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
58
|
+
username: {
|
|
59
|
+
type: 'String'
|
|
60
|
+
},
|
|
61
|
+
password: {
|
|
62
|
+
type: 'String'
|
|
63
|
+
},
|
|
64
|
+
email: {
|
|
65
|
+
type: 'String'
|
|
66
|
+
},
|
|
67
|
+
emailVerified: {
|
|
68
|
+
type: 'Boolean'
|
|
69
|
+
},
|
|
70
|
+
authData: {
|
|
71
|
+
type: 'Object'
|
|
72
|
+
}
|
|
54
73
|
},
|
|
55
74
|
// The additional default columns for the _Installation collection (in addition to DefaultCols)
|
|
56
75
|
_Installation: {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
76
|
+
installationId: {
|
|
77
|
+
type: 'String'
|
|
78
|
+
},
|
|
79
|
+
deviceToken: {
|
|
80
|
+
type: 'String'
|
|
81
|
+
},
|
|
82
|
+
channels: {
|
|
83
|
+
type: 'Array'
|
|
84
|
+
},
|
|
85
|
+
deviceType: {
|
|
86
|
+
type: 'String'
|
|
87
|
+
},
|
|
88
|
+
pushType: {
|
|
89
|
+
type: 'String'
|
|
90
|
+
},
|
|
91
|
+
GCMSenderId: {
|
|
92
|
+
type: 'String'
|
|
93
|
+
},
|
|
94
|
+
timeZone: {
|
|
95
|
+
type: 'String'
|
|
96
|
+
},
|
|
97
|
+
localeIdentifier: {
|
|
98
|
+
type: 'String'
|
|
99
|
+
},
|
|
100
|
+
badge: {
|
|
101
|
+
type: 'Number'
|
|
102
|
+
},
|
|
103
|
+
appVersion: {
|
|
104
|
+
type: 'String'
|
|
105
|
+
},
|
|
106
|
+
appName: {
|
|
107
|
+
type: 'String'
|
|
108
|
+
},
|
|
109
|
+
appIdentifier: {
|
|
110
|
+
type: 'String'
|
|
111
|
+
},
|
|
112
|
+
parseVersion: {
|
|
113
|
+
type: 'String'
|
|
114
|
+
}
|
|
70
115
|
},
|
|
71
116
|
// The additional default columns for the _Role collection (in addition to DefaultCols)
|
|
72
117
|
_Role: {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
118
|
+
name: {
|
|
119
|
+
type: 'String'
|
|
120
|
+
},
|
|
121
|
+
users: {
|
|
122
|
+
type: 'Relation',
|
|
123
|
+
targetClass: '_User'
|
|
124
|
+
},
|
|
125
|
+
roles: {
|
|
126
|
+
type: 'Relation',
|
|
127
|
+
targetClass: '_Role'
|
|
128
|
+
}
|
|
76
129
|
},
|
|
77
130
|
// The additional default columns for the _Session collection (in addition to DefaultCols)
|
|
78
131
|
_Session: {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
132
|
+
user: {
|
|
133
|
+
type: 'Pointer',
|
|
134
|
+
targetClass: '_User'
|
|
135
|
+
},
|
|
136
|
+
installationId: {
|
|
137
|
+
type: 'String'
|
|
138
|
+
},
|
|
139
|
+
sessionToken: {
|
|
140
|
+
type: 'String'
|
|
141
|
+
},
|
|
142
|
+
expiresAt: {
|
|
143
|
+
type: 'Date'
|
|
144
|
+
},
|
|
145
|
+
createdWith: {
|
|
146
|
+
type: 'Object'
|
|
147
|
+
}
|
|
85
148
|
},
|
|
86
149
|
_Product: {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
150
|
+
productIdentifier: {
|
|
151
|
+
type: 'String'
|
|
152
|
+
},
|
|
153
|
+
download: {
|
|
154
|
+
type: 'File'
|
|
155
|
+
},
|
|
156
|
+
downloadName: {
|
|
157
|
+
type: 'String'
|
|
158
|
+
},
|
|
159
|
+
icon: {
|
|
160
|
+
type: 'File'
|
|
161
|
+
},
|
|
162
|
+
order: {
|
|
163
|
+
type: 'Number'
|
|
164
|
+
},
|
|
165
|
+
title: {
|
|
166
|
+
type: 'String'
|
|
167
|
+
},
|
|
168
|
+
subtitle: {
|
|
169
|
+
type: 'String'
|
|
170
|
+
}
|
|
94
171
|
},
|
|
95
172
|
_PushStatus: {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
173
|
+
pushTime: {
|
|
174
|
+
type: 'String'
|
|
175
|
+
},
|
|
176
|
+
source: {
|
|
177
|
+
type: 'String'
|
|
178
|
+
},
|
|
179
|
+
// rest or webui
|
|
180
|
+
query: {
|
|
181
|
+
type: 'String'
|
|
182
|
+
},
|
|
183
|
+
// the stringified JSON query
|
|
184
|
+
payload: {
|
|
185
|
+
type: 'String'
|
|
186
|
+
},
|
|
187
|
+
// the stringified JSON payload,
|
|
188
|
+
title: {
|
|
189
|
+
type: 'String'
|
|
190
|
+
},
|
|
191
|
+
expiry: {
|
|
192
|
+
type: 'Number'
|
|
193
|
+
},
|
|
194
|
+
expiration_interval: {
|
|
195
|
+
type: 'Number'
|
|
196
|
+
},
|
|
197
|
+
status: {
|
|
198
|
+
type: 'String'
|
|
199
|
+
},
|
|
200
|
+
numSent: {
|
|
201
|
+
type: 'Number'
|
|
202
|
+
},
|
|
203
|
+
numFailed: {
|
|
204
|
+
type: 'Number'
|
|
205
|
+
},
|
|
206
|
+
pushHash: {
|
|
207
|
+
type: 'String'
|
|
208
|
+
},
|
|
209
|
+
errorMessage: {
|
|
210
|
+
type: 'Object'
|
|
211
|
+
},
|
|
212
|
+
sentPerType: {
|
|
213
|
+
type: 'Object'
|
|
214
|
+
},
|
|
215
|
+
failedPerType: {
|
|
216
|
+
type: 'Object'
|
|
217
|
+
},
|
|
218
|
+
sentPerUTCOffset: {
|
|
219
|
+
type: 'Object'
|
|
220
|
+
},
|
|
221
|
+
failedPerUTCOffset: {
|
|
222
|
+
type: 'Object'
|
|
223
|
+
},
|
|
224
|
+
count: {
|
|
225
|
+
type: 'Number'
|
|
226
|
+
} // tracks # of batches queued and pending
|
|
227
|
+
},
|
|
114
228
|
_JobStatus: {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
229
|
+
jobName: {
|
|
230
|
+
type: 'String'
|
|
231
|
+
},
|
|
232
|
+
source: {
|
|
233
|
+
type: 'String'
|
|
234
|
+
},
|
|
235
|
+
status: {
|
|
236
|
+
type: 'String'
|
|
237
|
+
},
|
|
238
|
+
message: {
|
|
239
|
+
type: 'String'
|
|
240
|
+
},
|
|
241
|
+
params: {
|
|
242
|
+
type: 'Object'
|
|
243
|
+
},
|
|
244
|
+
// params received when calling the job
|
|
245
|
+
finishedAt: {
|
|
246
|
+
type: 'Date'
|
|
247
|
+
}
|
|
121
248
|
},
|
|
122
249
|
_JobSchedule: {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
250
|
+
jobName: {
|
|
251
|
+
type: 'String'
|
|
252
|
+
},
|
|
253
|
+
description: {
|
|
254
|
+
type: 'String'
|
|
255
|
+
},
|
|
256
|
+
params: {
|
|
257
|
+
type: 'String'
|
|
258
|
+
},
|
|
259
|
+
startAfter: {
|
|
260
|
+
type: 'String'
|
|
261
|
+
},
|
|
262
|
+
daysOfWeek: {
|
|
263
|
+
type: 'Array'
|
|
264
|
+
},
|
|
265
|
+
timeOfDay: {
|
|
266
|
+
type: 'String'
|
|
267
|
+
},
|
|
268
|
+
lastRun: {
|
|
269
|
+
type: 'Number'
|
|
270
|
+
},
|
|
271
|
+
repeatMinutes: {
|
|
272
|
+
type: 'Number'
|
|
273
|
+
}
|
|
131
274
|
},
|
|
132
275
|
_Hooks: {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
276
|
+
functionName: {
|
|
277
|
+
type: 'String'
|
|
278
|
+
},
|
|
279
|
+
className: {
|
|
280
|
+
type: 'String'
|
|
281
|
+
},
|
|
282
|
+
triggerName: {
|
|
283
|
+
type: 'String'
|
|
284
|
+
},
|
|
285
|
+
url: {
|
|
286
|
+
type: 'String'
|
|
287
|
+
}
|
|
137
288
|
},
|
|
138
289
|
_GlobalConfig: {
|
|
139
|
-
|
|
140
|
-
|
|
290
|
+
objectId: {
|
|
291
|
+
type: 'String'
|
|
292
|
+
},
|
|
293
|
+
params: {
|
|
294
|
+
type: 'Object'
|
|
295
|
+
},
|
|
296
|
+
masterKeyOnly: {
|
|
297
|
+
type: 'Object'
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
_GraphQLConfig: {
|
|
301
|
+
objectId: {
|
|
302
|
+
type: 'String'
|
|
303
|
+
},
|
|
304
|
+
config: {
|
|
305
|
+
type: 'Object'
|
|
306
|
+
}
|
|
141
307
|
},
|
|
142
308
|
_Audience: {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
309
|
+
objectId: {
|
|
310
|
+
type: 'String'
|
|
311
|
+
},
|
|
312
|
+
name: {
|
|
313
|
+
type: 'String'
|
|
314
|
+
},
|
|
315
|
+
query: {
|
|
316
|
+
type: 'String'
|
|
317
|
+
},
|
|
318
|
+
//storing query as JSON string to prevent "Nested keys should not contain the '$' or '.' characters" error
|
|
319
|
+
lastUsed: {
|
|
320
|
+
type: 'Date'
|
|
321
|
+
},
|
|
322
|
+
timesUsed: {
|
|
323
|
+
type: 'Number'
|
|
324
|
+
}
|
|
325
|
+
},
|
|
326
|
+
_Idempotency: {
|
|
327
|
+
reqId: {
|
|
328
|
+
type: 'String'
|
|
329
|
+
},
|
|
330
|
+
expire: {
|
|
331
|
+
type: 'Date'
|
|
332
|
+
}
|
|
148
333
|
}
|
|
149
334
|
});
|
|
150
335
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
336
|
+
// fields required for read or write operations on their respective classes.
|
|
337
|
+
const requiredColumns = exports.requiredColumns = Object.freeze({
|
|
338
|
+
read: {
|
|
339
|
+
_User: ['username']
|
|
340
|
+
},
|
|
341
|
+
write: {
|
|
342
|
+
_Product: ['productIdentifier', 'icon', 'order', 'title', 'subtitle'],
|
|
343
|
+
_Role: ['name', 'ACL']
|
|
344
|
+
}
|
|
154
345
|
});
|
|
346
|
+
const invalidColumns = ['length'];
|
|
347
|
+
const systemClasses = exports.systemClasses = Object.freeze(['_User', '_Installation', '_Role', '_Session', '_Product', '_PushStatus', '_JobStatus', '_JobSchedule', '_Audience', '_Idempotency']);
|
|
348
|
+
const volatileClasses = Object.freeze(['_JobStatus', '_PushStatus', '_Hooks', '_GlobalConfig', '_GraphQLConfig', '_JobSchedule', '_Audience', '_Idempotency']);
|
|
155
349
|
|
|
156
|
-
const systemClasses = Object.freeze(['_User', '_Installation', '_Role', '_Session', '_Product', '_PushStatus', '_JobStatus', '_JobSchedule', '_Audience']);
|
|
157
|
-
|
|
158
|
-
const volatileClasses = Object.freeze(['_JobStatus', '_PushStatus', '_Hooks', '_GlobalConfig', '_JobSchedule', '_Audience']);
|
|
159
|
-
|
|
160
|
-
// 10 alpha numberic chars + uppercase
|
|
161
|
-
const userIdRegex = /^[a-zA-Z0-9]{10}$/;
|
|
162
350
|
// Anything that start with role
|
|
163
351
|
const roleRegex = /^role:.*/;
|
|
352
|
+
// Anything that starts with userField (allowed for protected fields only)
|
|
353
|
+
const protectedFieldsPointerRegex = /^userField:.*/;
|
|
164
354
|
// * permission
|
|
165
355
|
const publicRegex = /^\*$/;
|
|
356
|
+
const authenticatedRegex = /^authenticated$/;
|
|
357
|
+
const requiresAuthenticationRegex = /^requiresAuthentication$/;
|
|
358
|
+
const clpPointerRegex = /^pointerFields$/;
|
|
359
|
+
|
|
360
|
+
// regex for validating entities in protectedFields object
|
|
361
|
+
const protectedFieldsRegex = Object.freeze([protectedFieldsPointerRegex, publicRegex, authenticatedRegex, roleRegex]);
|
|
362
|
+
|
|
363
|
+
// clp regex
|
|
364
|
+
const clpFieldsRegex = Object.freeze([clpPointerRegex, publicRegex, requiresAuthenticationRegex, roleRegex]);
|
|
365
|
+
function validatePermissionKey(key, userIdRegExp) {
|
|
366
|
+
let matchesSome = false;
|
|
367
|
+
for (const regEx of clpFieldsRegex) {
|
|
368
|
+
if (key.match(regEx) !== null) {
|
|
369
|
+
matchesSome = true;
|
|
370
|
+
break;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
166
373
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
374
|
+
// userId depends on startup options so it's dynamic
|
|
375
|
+
const valid = matchesSome || key.match(userIdRegExp) !== null;
|
|
376
|
+
if (!valid) {
|
|
377
|
+
throw new Parse.Error(Parse.Error.INVALID_JSON, `'${key}' is not a valid key for class level permissions`);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
function validateProtectedFieldsKey(key, userIdRegExp) {
|
|
381
|
+
let matchesSome = false;
|
|
382
|
+
for (const regEx of protectedFieldsRegex) {
|
|
383
|
+
if (key.match(regEx) !== null) {
|
|
384
|
+
matchesSome = true;
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
170
388
|
|
|
171
|
-
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
return isGood;
|
|
175
|
-
}, false);
|
|
176
|
-
if (!result) {
|
|
389
|
+
// userId regex depends on launch options so it's dynamic
|
|
390
|
+
const valid = matchesSome || key.match(userIdRegExp) !== null;
|
|
391
|
+
if (!valid) {
|
|
177
392
|
throw new Parse.Error(Parse.Error.INVALID_JSON, `'${key}' is not a valid key for class level permissions`);
|
|
178
393
|
}
|
|
179
394
|
}
|
|
395
|
+
const CLPValidKeys = Object.freeze(['ACL', 'find', 'count', 'get', 'create', 'update', 'delete', 'addField', 'readUserFields', 'writeUserFields', 'protectedFields']);
|
|
180
396
|
|
|
181
|
-
|
|
182
|
-
function validateCLP(perms, fields) {
|
|
397
|
+
// validation before setting class-level permissions on collection
|
|
398
|
+
function validateCLP(perms, fields, userIdRegExp) {
|
|
183
399
|
if (!perms) {
|
|
184
400
|
return;
|
|
185
401
|
}
|
|
186
|
-
|
|
187
|
-
if (CLPValidKeys.indexOf(
|
|
188
|
-
throw new Parse.Error(Parse.Error.INVALID_JSON, `${
|
|
402
|
+
for (const operationKey in perms) {
|
|
403
|
+
if (CLPValidKeys.indexOf(operationKey) == -1) {
|
|
404
|
+
throw new Parse.Error(Parse.Error.INVALID_JSON, `${operationKey} is not a valid operation for class level permissions`);
|
|
189
405
|
}
|
|
190
|
-
|
|
191
|
-
|
|
406
|
+
const operation = perms[operationKey];
|
|
407
|
+
// proceed with next operationKey
|
|
408
|
+
|
|
409
|
+
// throws when root fields are of wrong type
|
|
410
|
+
validateCLPjson(operation, operationKey);
|
|
411
|
+
if (operationKey === 'readUserFields' || operationKey === 'writeUserFields') {
|
|
412
|
+
// validate grouped pointer permissions
|
|
413
|
+
// must be an array with field names
|
|
414
|
+
for (const fieldName of operation) {
|
|
415
|
+
validatePointerPermission(fieldName, fields, operationKey);
|
|
416
|
+
}
|
|
417
|
+
// readUserFields and writerUserFields do not have nesdted fields
|
|
418
|
+
// proceed with next operationKey
|
|
419
|
+
continue;
|
|
192
420
|
}
|
|
193
421
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
422
|
+
// validate protected fields
|
|
423
|
+
if (operationKey === 'protectedFields') {
|
|
424
|
+
for (const entity in operation) {
|
|
425
|
+
// throws on unexpected key
|
|
426
|
+
validateProtectedFieldsKey(entity, userIdRegExp);
|
|
427
|
+
const protectedFields = operation[entity];
|
|
428
|
+
if (!Array.isArray(protectedFields)) {
|
|
429
|
+
throw new Parse.Error(Parse.Error.INVALID_JSON, `'${protectedFields}' is not a valid value for protectedFields[${entity}] - expected an array.`);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// if the field is in form of array
|
|
433
|
+
for (const field of protectedFields) {
|
|
434
|
+
// do not alloow to protect default fields
|
|
435
|
+
if (defaultColumns._Default[field]) {
|
|
436
|
+
throw new Parse.Error(Parse.Error.INVALID_JSON, `Default field '${field}' can not be protected`);
|
|
202
437
|
}
|
|
203
|
-
|
|
438
|
+
// field should exist on collection
|
|
439
|
+
if (!Object.prototype.hasOwnProperty.call(fields, field)) {
|
|
440
|
+
throw new Parse.Error(Parse.Error.INVALID_JSON, `Field '${field}' in protectedFields:${entity} does not exist`);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
204
443
|
}
|
|
205
|
-
|
|
444
|
+
// proceed with next operationKey
|
|
445
|
+
continue;
|
|
206
446
|
}
|
|
207
447
|
|
|
208
|
-
//
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
448
|
+
// validate other fields
|
|
449
|
+
// Entity can be:
|
|
450
|
+
// "*" - Public,
|
|
451
|
+
// "requiresAuthentication" - authenticated users,
|
|
452
|
+
// "objectId" - _User id,
|
|
453
|
+
// "role:rolename",
|
|
454
|
+
// "pointerFields" - array of field names containing pointers to users
|
|
455
|
+
for (const entity in operation) {
|
|
456
|
+
// throws on unexpected key
|
|
457
|
+
validatePermissionKey(entity, userIdRegExp);
|
|
458
|
+
|
|
459
|
+
// entity can be either:
|
|
460
|
+
// "pointerFields": string[]
|
|
461
|
+
if (entity === 'pointerFields') {
|
|
462
|
+
const pointerFields = operation[entity];
|
|
463
|
+
if (Array.isArray(pointerFields)) {
|
|
464
|
+
for (const pointerField of pointerFields) {
|
|
465
|
+
validatePointerPermission(pointerField, fields, operation);
|
|
466
|
+
}
|
|
467
|
+
} else {
|
|
468
|
+
throw new Parse.Error(Parse.Error.INVALID_JSON, `'${pointerFields}' is not a valid value for ${operationKey}[${entity}] - expected an array.`);
|
|
469
|
+
}
|
|
470
|
+
// proceed with next entity key
|
|
471
|
+
continue;
|
|
216
472
|
}
|
|
217
|
-
|
|
218
|
-
|
|
473
|
+
const permit = operation[entity];
|
|
474
|
+
if (operationKey === 'ACL') {
|
|
475
|
+
if (Object.prototype.toString.call(permit) !== '[object Object]') {
|
|
476
|
+
throw new Parse.Error(Parse.Error.INVALID_JSON, `'${permit}' is not a valid value for class level permissions acl`);
|
|
477
|
+
}
|
|
478
|
+
const invalidKeys = Object.keys(permit).filter(key => !['read', 'write'].includes(key));
|
|
479
|
+
const invalidValues = Object.values(permit).filter(key => typeof key !== 'boolean');
|
|
480
|
+
if (invalidKeys.length) {
|
|
481
|
+
throw new Parse.Error(Parse.Error.INVALID_JSON, `'${invalidKeys.join(',')}' is not a valid key for class level permissions acl`);
|
|
482
|
+
}
|
|
483
|
+
if (invalidValues.length) {
|
|
484
|
+
throw new Parse.Error(Parse.Error.INVALID_JSON, `'${invalidValues.join(',')}' is not a valid value for class level permissions acl`);
|
|
485
|
+
}
|
|
486
|
+
} else if (permit !== true) {
|
|
487
|
+
throw new Parse.Error(Parse.Error.INVALID_JSON, `'${permit}' is not a valid value for class level permissions acl ${operationKey}:${entity}`);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
function validateCLPjson(operation, operationKey) {
|
|
493
|
+
if (operationKey === 'readUserFields' || operationKey === 'writeUserFields') {
|
|
494
|
+
if (!Array.isArray(operation)) {
|
|
495
|
+
throw new Parse.Error(Parse.Error.INVALID_JSON, `'${operation}' is not a valid value for class level permissions ${operationKey} - must be an array`);
|
|
496
|
+
}
|
|
497
|
+
} else {
|
|
498
|
+
if (typeof operation === 'object' && operation !== null) {
|
|
499
|
+
// ok to proceed
|
|
500
|
+
return;
|
|
501
|
+
} else {
|
|
502
|
+
throw new Parse.Error(Parse.Error.INVALID_JSON, `'${operation}' is not a valid value for class level permissions ${operationKey} - must be an object`);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
function validatePointerPermission(fieldName, fields, operation) {
|
|
507
|
+
// Uses collection schema to ensure the field is of type:
|
|
508
|
+
// - Pointer<_User> (pointers)
|
|
509
|
+
// - Array
|
|
510
|
+
//
|
|
511
|
+
// It's not possible to enforce type on Array's items in schema
|
|
512
|
+
// so we accept any Array field, and later when applying permissions
|
|
513
|
+
// only items that are pointers to _User are considered.
|
|
514
|
+
if (!(fields[fieldName] && (fields[fieldName].type == 'Pointer' && fields[fieldName].targetClass == '_User' || fields[fieldName].type == 'Array'))) {
|
|
515
|
+
throw new Parse.Error(Parse.Error.INVALID_JSON, `'${fieldName}' is not a valid column for class level pointer permissions ${operation}`);
|
|
516
|
+
}
|
|
219
517
|
}
|
|
220
518
|
const joinClassRegex = /^_Join:[A-Za-z0-9_]+:[A-Za-z0-9_]+/;
|
|
221
519
|
const classAndFieldRegex = /^[A-Za-z][A-Za-z0-9_]*$/;
|
|
@@ -227,18 +525,24 @@ function classNameIsValid(className) {
|
|
|
227
525
|
// Be a join table OR
|
|
228
526
|
joinClassRegex.test(className) ||
|
|
229
527
|
// Include only alpha-numeric and underscores, and not start with an underscore or number
|
|
230
|
-
fieldNameIsValid(className)
|
|
528
|
+
fieldNameIsValid(className, className)
|
|
231
529
|
);
|
|
232
530
|
}
|
|
233
531
|
|
|
234
532
|
// Valid fields must be alpha-numeric, and not start with an underscore or number
|
|
235
|
-
|
|
236
|
-
|
|
533
|
+
// must not be a reserved key
|
|
534
|
+
function fieldNameIsValid(fieldName, className) {
|
|
535
|
+
if (className && className !== '_Hooks') {
|
|
536
|
+
if (fieldName === 'className') {
|
|
537
|
+
return false;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
return classAndFieldRegex.test(fieldName) && !invalidColumns.includes(fieldName);
|
|
237
541
|
}
|
|
238
542
|
|
|
239
543
|
// Checks that it's not trying to clobber one of the default fields of the class.
|
|
240
544
|
function fieldNameIsValidForClass(fieldName, className) {
|
|
241
|
-
if (!fieldNameIsValid(fieldName)) {
|
|
545
|
+
if (!fieldNameIsValid(fieldName, className)) {
|
|
242
546
|
return false;
|
|
243
547
|
}
|
|
244
548
|
if (defaultColumns._Default[fieldName]) {
|
|
@@ -249,15 +553,16 @@ function fieldNameIsValidForClass(fieldName, className) {
|
|
|
249
553
|
}
|
|
250
554
|
return true;
|
|
251
555
|
}
|
|
252
|
-
|
|
253
556
|
function invalidClassNameMessage(className) {
|
|
254
557
|
return 'Invalid classname: ' + className + ', classnames can only have alphanumeric characters and _, and must start with an alpha character ';
|
|
255
558
|
}
|
|
256
|
-
|
|
257
|
-
const invalidJsonError = new Parse.Error(Parse.Error.INVALID_JSON, "invalid JSON");
|
|
559
|
+
const invalidJsonError = new Parse.Error(Parse.Error.INVALID_JSON, 'invalid JSON');
|
|
258
560
|
const validNonRelationOrPointerTypes = ['Number', 'String', 'Boolean', 'Date', 'Object', 'Array', 'GeoPoint', 'File', 'Bytes', 'Polygon'];
|
|
259
561
|
// Returns an error suitable for throwing if the type is invalid
|
|
260
|
-
const fieldTypeIsInvalid = ({
|
|
562
|
+
const fieldTypeIsInvalid = ({
|
|
563
|
+
type,
|
|
564
|
+
targetClass
|
|
565
|
+
}) => {
|
|
261
566
|
if (['Pointer', 'Relation'].indexOf(type) >= 0) {
|
|
262
567
|
if (!targetClass) {
|
|
263
568
|
return new Parse.Error(135, `type ${type} needs a class name`);
|
|
@@ -277,46 +582,108 @@ const fieldTypeIsInvalid = ({ type, targetClass }) => {
|
|
|
277
582
|
}
|
|
278
583
|
return undefined;
|
|
279
584
|
};
|
|
280
|
-
|
|
281
585
|
const convertSchemaToAdapterSchema = schema => {
|
|
282
586
|
schema = injectDefaultSchema(schema);
|
|
283
587
|
delete schema.fields.ACL;
|
|
284
|
-
schema.fields._rperm = {
|
|
285
|
-
|
|
286
|
-
|
|
588
|
+
schema.fields._rperm = {
|
|
589
|
+
type: 'Array'
|
|
590
|
+
};
|
|
591
|
+
schema.fields._wperm = {
|
|
592
|
+
type: 'Array'
|
|
593
|
+
};
|
|
287
594
|
if (schema.className === '_User') {
|
|
288
595
|
delete schema.fields.password;
|
|
289
|
-
schema.fields._hashed_password = {
|
|
596
|
+
schema.fields._hashed_password = {
|
|
597
|
+
type: 'String'
|
|
598
|
+
};
|
|
290
599
|
}
|
|
291
|
-
|
|
292
600
|
return schema;
|
|
293
601
|
};
|
|
294
|
-
|
|
295
|
-
const convertAdapterSchemaToParseSchema = (
|
|
296
|
-
|
|
297
|
-
|
|
602
|
+
exports.convertSchemaToAdapterSchema = convertSchemaToAdapterSchema;
|
|
603
|
+
const convertAdapterSchemaToParseSchema = ({
|
|
604
|
+
...schema
|
|
605
|
+
}) => {
|
|
298
606
|
delete schema.fields._rperm;
|
|
299
607
|
delete schema.fields._wperm;
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
608
|
+
schema.fields.ACL = {
|
|
609
|
+
type: 'ACL'
|
|
610
|
+
};
|
|
303
611
|
if (schema.className === '_User') {
|
|
304
612
|
delete schema.fields.authData; //Auth data is implicit
|
|
305
613
|
delete schema.fields._hashed_password;
|
|
306
|
-
schema.fields.password = {
|
|
614
|
+
schema.fields.password = {
|
|
615
|
+
type: 'String'
|
|
616
|
+
};
|
|
307
617
|
}
|
|
308
|
-
|
|
309
618
|
if (schema.indexes && Object.keys(schema.indexes).length === 0) {
|
|
310
619
|
delete schema.indexes;
|
|
311
620
|
}
|
|
312
|
-
|
|
313
621
|
return schema;
|
|
314
622
|
};
|
|
623
|
+
class SchemaData {
|
|
624
|
+
constructor(allSchemas = [], protectedFields = {}) {
|
|
625
|
+
this.__data = {};
|
|
626
|
+
this.__protectedFields = protectedFields;
|
|
627
|
+
allSchemas.forEach(schema => {
|
|
628
|
+
if (volatileClasses.includes(schema.className)) {
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
Object.defineProperty(this, schema.className, {
|
|
632
|
+
get: () => {
|
|
633
|
+
if (!this.__data[schema.className]) {
|
|
634
|
+
const data = {};
|
|
635
|
+
data.fields = injectDefaultSchema(schema).fields;
|
|
636
|
+
data.classLevelPermissions = (0, _deepcopy.default)(schema.classLevelPermissions);
|
|
637
|
+
data.indexes = schema.indexes;
|
|
638
|
+
const classProtectedFields = this.__protectedFields[schema.className];
|
|
639
|
+
if (classProtectedFields) {
|
|
640
|
+
for (const key in classProtectedFields) {
|
|
641
|
+
const unq = new Set([...(data.classLevelPermissions.protectedFields[key] || []), ...classProtectedFields[key]]);
|
|
642
|
+
data.classLevelPermissions.protectedFields[key] = Array.from(unq);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
this.__data[schema.className] = data;
|
|
646
|
+
}
|
|
647
|
+
return this.__data[schema.className];
|
|
648
|
+
}
|
|
649
|
+
});
|
|
650
|
+
});
|
|
315
651
|
|
|
316
|
-
|
|
652
|
+
// Inject the in-memory classes
|
|
653
|
+
volatileClasses.forEach(className => {
|
|
654
|
+
Object.defineProperty(this, className, {
|
|
655
|
+
get: () => {
|
|
656
|
+
if (!this.__data[className]) {
|
|
657
|
+
const schema = injectDefaultSchema({
|
|
658
|
+
className,
|
|
659
|
+
fields: {},
|
|
660
|
+
classLevelPermissions: {}
|
|
661
|
+
});
|
|
662
|
+
const data = {};
|
|
663
|
+
data.fields = schema.fields;
|
|
664
|
+
data.classLevelPermissions = schema.classLevelPermissions;
|
|
665
|
+
data.indexes = schema.indexes;
|
|
666
|
+
this.__data[className] = data;
|
|
667
|
+
}
|
|
668
|
+
return this.__data[className];
|
|
669
|
+
}
|
|
670
|
+
});
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
const injectDefaultSchema = ({
|
|
675
|
+
className,
|
|
676
|
+
fields,
|
|
677
|
+
classLevelPermissions,
|
|
678
|
+
indexes
|
|
679
|
+
}) => {
|
|
317
680
|
const defaultSchema = {
|
|
318
681
|
className,
|
|
319
|
-
fields:
|
|
682
|
+
fields: {
|
|
683
|
+
...defaultColumns._Default,
|
|
684
|
+
...(defaultColumns[className] || {}),
|
|
685
|
+
...fields
|
|
686
|
+
},
|
|
320
687
|
classLevelPermissions
|
|
321
688
|
};
|
|
322
689
|
if (indexes && Object.keys(indexes).length !== 0) {
|
|
@@ -324,39 +691,59 @@ const injectDefaultSchema = ({ className, fields, classLevelPermissions, indexes
|
|
|
324
691
|
}
|
|
325
692
|
return defaultSchema;
|
|
326
693
|
};
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
694
|
+
const _HooksSchema = {
|
|
695
|
+
className: '_Hooks',
|
|
696
|
+
fields: defaultColumns._Hooks
|
|
697
|
+
};
|
|
698
|
+
const _GlobalConfigSchema = {
|
|
699
|
+
className: '_GlobalConfig',
|
|
700
|
+
fields: defaultColumns._GlobalConfig
|
|
701
|
+
};
|
|
702
|
+
const _GraphQLConfigSchema = {
|
|
703
|
+
className: '_GraphQLConfig',
|
|
704
|
+
fields: defaultColumns._GraphQLConfig
|
|
705
|
+
};
|
|
330
706
|
const _PushStatusSchema = convertSchemaToAdapterSchema(injectDefaultSchema({
|
|
331
|
-
className:
|
|
707
|
+
className: '_PushStatus',
|
|
332
708
|
fields: {},
|
|
333
709
|
classLevelPermissions: {}
|
|
334
710
|
}));
|
|
335
711
|
const _JobStatusSchema = convertSchemaToAdapterSchema(injectDefaultSchema({
|
|
336
|
-
className:
|
|
712
|
+
className: '_JobStatus',
|
|
337
713
|
fields: {},
|
|
338
714
|
classLevelPermissions: {}
|
|
339
715
|
}));
|
|
340
716
|
const _JobScheduleSchema = convertSchemaToAdapterSchema(injectDefaultSchema({
|
|
341
|
-
className:
|
|
717
|
+
className: '_JobSchedule',
|
|
342
718
|
fields: {},
|
|
343
719
|
classLevelPermissions: {}
|
|
344
720
|
}));
|
|
345
721
|
const _AudienceSchema = convertSchemaToAdapterSchema(injectDefaultSchema({
|
|
346
|
-
className:
|
|
722
|
+
className: '_Audience',
|
|
347
723
|
fields: defaultColumns._Audience,
|
|
348
724
|
classLevelPermissions: {}
|
|
349
725
|
}));
|
|
350
|
-
const
|
|
351
|
-
|
|
726
|
+
const _IdempotencySchema = convertSchemaToAdapterSchema(injectDefaultSchema({
|
|
727
|
+
className: '_Idempotency',
|
|
728
|
+
fields: defaultColumns._Idempotency,
|
|
729
|
+
classLevelPermissions: {}
|
|
730
|
+
}));
|
|
731
|
+
const VolatileClassesSchemas = exports.VolatileClassesSchemas = [_HooksSchema, _JobStatusSchema, _JobScheduleSchema, _PushStatusSchema, _GlobalConfigSchema, _GraphQLConfigSchema, _AudienceSchema, _IdempotencySchema];
|
|
352
732
|
const dbTypeMatchesObjectType = (dbType, objectType) => {
|
|
353
|
-
if (dbType.type !== objectType.type)
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
if (dbType.
|
|
733
|
+
if (dbType.type !== objectType.type) {
|
|
734
|
+
return false;
|
|
735
|
+
}
|
|
736
|
+
if (dbType.targetClass !== objectType.targetClass) {
|
|
737
|
+
return false;
|
|
738
|
+
}
|
|
739
|
+
if (dbType === objectType.type) {
|
|
740
|
+
return true;
|
|
741
|
+
}
|
|
742
|
+
if (dbType.type === objectType.type) {
|
|
743
|
+
return true;
|
|
744
|
+
}
|
|
357
745
|
return false;
|
|
358
746
|
};
|
|
359
|
-
|
|
360
747
|
const typeToString = type => {
|
|
361
748
|
if (typeof type === 'string') {
|
|
362
749
|
return type;
|
|
@@ -366,108 +753,108 @@ const typeToString = type => {
|
|
|
366
753
|
}
|
|
367
754
|
return `${type.type}`;
|
|
368
755
|
};
|
|
756
|
+
const ttl = {
|
|
757
|
+
date: Date.now(),
|
|
758
|
+
duration: undefined
|
|
759
|
+
};
|
|
369
760
|
|
|
370
761
|
// Stores the entire schema of the app in a weird hybrid format somewhere between
|
|
371
762
|
// the mongo format and the Parse format. Soon, this will all be Parse format.
|
|
372
763
|
class SchemaController {
|
|
373
|
-
|
|
374
|
-
constructor(databaseAdapter, schemaCache) {
|
|
764
|
+
constructor(databaseAdapter) {
|
|
375
765
|
this._dbAdapter = databaseAdapter;
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
this.
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
this.
|
|
766
|
+
const config = _Config.default.get(Parse.applicationId);
|
|
767
|
+
this.schemaData = new SchemaData(_SchemaCache.default.all(), this.protectedFields);
|
|
768
|
+
this.protectedFields = config.protectedFields;
|
|
769
|
+
const customIds = config.allowCustomObjectId;
|
|
770
|
+
const customIdRegEx = /^.{1,}$/u; // 1+ chars
|
|
771
|
+
const autoIdRegEx = /^[a-zA-Z0-9]{1,}$/;
|
|
772
|
+
this.userIdRegEx = customIds ? customIdRegEx : autoIdRegEx;
|
|
773
|
+
this._dbAdapter.watch(() => {
|
|
774
|
+
this.reloadData({
|
|
775
|
+
clearCache: true
|
|
776
|
+
});
|
|
777
|
+
});
|
|
383
778
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
779
|
+
async reloadDataIfNeeded() {
|
|
780
|
+
if (this._dbAdapter.enableSchemaHooks) {
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
const {
|
|
784
|
+
date,
|
|
785
|
+
duration
|
|
786
|
+
} = ttl || {};
|
|
787
|
+
if (!duration) {
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
const now = Date.now();
|
|
791
|
+
if (now - date > duration) {
|
|
792
|
+
ttl.date = now;
|
|
793
|
+
await this.reloadData({
|
|
794
|
+
clearCache: true
|
|
390
795
|
});
|
|
391
796
|
}
|
|
797
|
+
}
|
|
798
|
+
reloadData(options = {
|
|
799
|
+
clearCache: false
|
|
800
|
+
}) {
|
|
392
801
|
if (this.reloadDataPromise && !options.clearCache) {
|
|
393
802
|
return this.reloadDataPromise;
|
|
394
803
|
}
|
|
395
|
-
this.reloadDataPromise =
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
perms[schema.className] = schema.classLevelPermissions;
|
|
403
|
-
indexes[schema.className] = schema.indexes;
|
|
404
|
-
});
|
|
405
|
-
|
|
406
|
-
// Inject the in-memory classes
|
|
407
|
-
volatileClasses.forEach(className => {
|
|
408
|
-
const schema = injectDefaultSchema({ className, fields: {}, classLevelPermissions: {} });
|
|
409
|
-
data[className] = schema.fields;
|
|
410
|
-
perms[className] = schema.classLevelPermissions;
|
|
411
|
-
indexes[className] = schema.indexes;
|
|
412
|
-
});
|
|
413
|
-
this.data = data;
|
|
414
|
-
this.perms = perms;
|
|
415
|
-
this.indexes = indexes;
|
|
416
|
-
delete this.reloadDataPromise;
|
|
417
|
-
}, err => {
|
|
418
|
-
this.data = {};
|
|
419
|
-
this.perms = {};
|
|
420
|
-
this.indexes = {};
|
|
421
|
-
delete this.reloadDataPromise;
|
|
422
|
-
throw err;
|
|
423
|
-
});
|
|
804
|
+
this.reloadDataPromise = this.getAllClasses(options).then(allSchemas => {
|
|
805
|
+
this.schemaData = new SchemaData(allSchemas, this.protectedFields);
|
|
806
|
+
delete this.reloadDataPromise;
|
|
807
|
+
}, err => {
|
|
808
|
+
this.schemaData = new SchemaData();
|
|
809
|
+
delete this.reloadDataPromise;
|
|
810
|
+
throw err;
|
|
424
811
|
}).then(() => {});
|
|
425
812
|
return this.reloadDataPromise;
|
|
426
813
|
}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
814
|
+
async getAllClasses(options = {
|
|
815
|
+
clearCache: false
|
|
816
|
+
}) {
|
|
430
817
|
if (options.clearCache) {
|
|
431
|
-
|
|
818
|
+
return this.setAllClasses();
|
|
432
819
|
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
820
|
+
await this.reloadDataIfNeeded();
|
|
821
|
+
const cached = _SchemaCache.default.all();
|
|
822
|
+
if (cached && cached.length) {
|
|
823
|
+
return Promise.resolve(cached);
|
|
824
|
+
}
|
|
825
|
+
return this.setAllClasses();
|
|
826
|
+
}
|
|
827
|
+
setAllClasses() {
|
|
828
|
+
return this._dbAdapter.getAllClasses().then(allSchemas => allSchemas.map(injectDefaultSchema)).then(allSchemas => {
|
|
829
|
+
_SchemaCache.default.put(allSchemas);
|
|
830
|
+
return allSchemas;
|
|
444
831
|
});
|
|
445
832
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
833
|
+
getOneSchema(className, allowVolatileClasses = false, options = {
|
|
834
|
+
clearCache: false
|
|
835
|
+
}) {
|
|
449
836
|
if (options.clearCache) {
|
|
450
|
-
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
});
|
|
460
|
-
}
|
|
461
|
-
return this._cache.getOneSchema(className).then(cached => {
|
|
462
|
-
if (cached && !options.clearCache) {
|
|
463
|
-
return Promise.resolve(cached);
|
|
464
|
-
}
|
|
465
|
-
return this._dbAdapter.getClass(className).then(injectDefaultSchema).then(result => {
|
|
466
|
-
return this._cache.setOneSchema(className, result).then(() => {
|
|
467
|
-
return result;
|
|
468
|
-
});
|
|
469
|
-
});
|
|
837
|
+
_SchemaCache.default.clear();
|
|
838
|
+
}
|
|
839
|
+
if (allowVolatileClasses && volatileClasses.indexOf(className) > -1) {
|
|
840
|
+
const data = this.schemaData[className];
|
|
841
|
+
return Promise.resolve({
|
|
842
|
+
className,
|
|
843
|
+
fields: data.fields,
|
|
844
|
+
classLevelPermissions: data.classLevelPermissions,
|
|
845
|
+
indexes: data.indexes
|
|
470
846
|
});
|
|
847
|
+
}
|
|
848
|
+
const cached = _SchemaCache.default.get(className);
|
|
849
|
+
if (cached && !options.clearCache) {
|
|
850
|
+
return Promise.resolve(cached);
|
|
851
|
+
}
|
|
852
|
+
return this.setAllClasses().then(allSchemas => {
|
|
853
|
+
const oneSchema = allSchemas.find(schema => schema.className === className);
|
|
854
|
+
if (!oneSchema) {
|
|
855
|
+
return Promise.reject(undefined);
|
|
856
|
+
}
|
|
857
|
+
return oneSchema;
|
|
471
858
|
});
|
|
472
859
|
}
|
|
473
860
|
|
|
@@ -478,38 +865,49 @@ class SchemaController {
|
|
|
478
865
|
// on success, and rejects with an error on fail. Ensure you
|
|
479
866
|
// have authorization (master key, or client class creation
|
|
480
867
|
// enabled) before calling this function.
|
|
481
|
-
addClassIfNotExists(className, fields = {}, classLevelPermissions, indexes = {}) {
|
|
868
|
+
async addClassIfNotExists(className, fields = {}, classLevelPermissions, indexes = {}) {
|
|
482
869
|
var validationError = this.validateNewClass(className, fields, classLevelPermissions);
|
|
483
870
|
if (validationError) {
|
|
871
|
+
if (validationError instanceof Parse.Error) {
|
|
872
|
+
return Promise.reject(validationError);
|
|
873
|
+
} else if (validationError.code && validationError.error) {
|
|
874
|
+
return Promise.reject(new Parse.Error(validationError.code, validationError.error));
|
|
875
|
+
}
|
|
484
876
|
return Promise.reject(validationError);
|
|
485
877
|
}
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
878
|
+
try {
|
|
879
|
+
const adapterSchema = await this._dbAdapter.createClass(className, convertSchemaToAdapterSchema({
|
|
880
|
+
fields,
|
|
881
|
+
classLevelPermissions,
|
|
882
|
+
indexes,
|
|
883
|
+
className
|
|
884
|
+
}));
|
|
885
|
+
// TODO: Remove by updating schema cache directly
|
|
886
|
+
await this.reloadData({
|
|
887
|
+
clearCache: true
|
|
490
888
|
});
|
|
491
|
-
|
|
889
|
+
const parseSchema = convertAdapterSchemaToParseSchema(adapterSchema);
|
|
890
|
+
return parseSchema;
|
|
891
|
+
} catch (error) {
|
|
492
892
|
if (error && error.code === Parse.Error.DUPLICATE_VALUE) {
|
|
493
893
|
throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} already exists.`);
|
|
494
894
|
} else {
|
|
495
895
|
throw error;
|
|
496
896
|
}
|
|
497
|
-
}
|
|
897
|
+
}
|
|
498
898
|
}
|
|
499
|
-
|
|
500
899
|
updateClass(className, submittedFields, classLevelPermissions, indexes, database) {
|
|
501
900
|
return this.getOneSchema(className).then(schema => {
|
|
502
901
|
const existingFields = schema.fields;
|
|
503
902
|
Object.keys(submittedFields).forEach(name => {
|
|
504
903
|
const field = submittedFields[name];
|
|
505
|
-
if (existingFields[name] && field.__op !== 'Delete') {
|
|
904
|
+
if (existingFields[name] && existingFields[name].type !== field.type && field.__op !== 'Delete') {
|
|
506
905
|
throw new Parse.Error(255, `Field ${name} exists, cannot update.`);
|
|
507
906
|
}
|
|
508
907
|
if (!existingFields[name] && field.__op === 'Delete') {
|
|
509
908
|
throw new Parse.Error(255, `Field ${name} does not exist, cannot delete.`);
|
|
510
909
|
}
|
|
511
910
|
});
|
|
512
|
-
|
|
513
911
|
delete existingFields._rperm;
|
|
514
912
|
delete existingFields._wperm;
|
|
515
913
|
const newSchema = buildMergedSchemaObject(existingFields, submittedFields);
|
|
@@ -531,29 +929,38 @@ class SchemaController {
|
|
|
531
929
|
insertedFields.push(fieldName);
|
|
532
930
|
}
|
|
533
931
|
});
|
|
534
|
-
|
|
535
932
|
let deletePromise = Promise.resolve();
|
|
536
933
|
if (deletedFields.length > 0) {
|
|
537
934
|
deletePromise = this.deleteFields(deletedFields, className, database);
|
|
538
935
|
}
|
|
936
|
+
let enforceFields = [];
|
|
539
937
|
return deletePromise // Delete Everything
|
|
540
|
-
.then(() => this.reloadData({
|
|
938
|
+
.then(() => this.reloadData({
|
|
939
|
+
clearCache: true
|
|
940
|
+
})) // Reload our Schema, so we have all the new values
|
|
541
941
|
.then(() => {
|
|
542
942
|
const promises = insertedFields.map(fieldName => {
|
|
543
943
|
const type = submittedFields[fieldName];
|
|
544
944
|
return this.enforceFieldExists(className, fieldName, type);
|
|
545
945
|
});
|
|
546
946
|
return Promise.all(promises);
|
|
547
|
-
}).then(
|
|
947
|
+
}).then(results => {
|
|
948
|
+
enforceFields = results.filter(result => !!result);
|
|
949
|
+
return this.setPermissions(className, classLevelPermissions, newSchema);
|
|
950
|
+
}).then(() => this._dbAdapter.setIndexesWithSchemaFormat(className, indexes, schema.indexes, fullNewSchema)).then(() => this.reloadData({
|
|
951
|
+
clearCache: true
|
|
952
|
+
}))
|
|
548
953
|
//TODO: Move this logic into the database adapter
|
|
549
954
|
.then(() => {
|
|
955
|
+
this.ensureFields(enforceFields);
|
|
956
|
+
const schema = this.schemaData[className];
|
|
550
957
|
const reloadedSchema = {
|
|
551
958
|
className: className,
|
|
552
|
-
fields:
|
|
553
|
-
classLevelPermissions:
|
|
959
|
+
fields: schema.fields,
|
|
960
|
+
classLevelPermissions: schema.classLevelPermissions
|
|
554
961
|
};
|
|
555
|
-
if (
|
|
556
|
-
reloadedSchema.indexes =
|
|
962
|
+
if (schema.indexes && Object.keys(schema.indexes).length !== 0) {
|
|
963
|
+
reloadedSchema.indexes = schema.indexes;
|
|
557
964
|
}
|
|
558
965
|
return reloadedSchema;
|
|
559
966
|
});
|
|
@@ -569,33 +976,35 @@ class SchemaController {
|
|
|
569
976
|
// Returns a promise that resolves successfully to the new schema
|
|
570
977
|
// object or fails with a reason.
|
|
571
978
|
enforceClassExists(className) {
|
|
572
|
-
if (this.
|
|
979
|
+
if (this.schemaData[className]) {
|
|
573
980
|
return Promise.resolve(this);
|
|
574
981
|
}
|
|
575
982
|
// We don't have this class. Update the schema
|
|
576
|
-
return
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
983
|
+
return (
|
|
984
|
+
// The schema update succeeded. Reload the schema
|
|
985
|
+
this.addClassIfNotExists(className).catch(() => {
|
|
986
|
+
// The schema update failed. This can be okay - it might
|
|
987
|
+
// have failed because there's a race condition and a different
|
|
988
|
+
// client is making the exact same schema update that we want.
|
|
989
|
+
// So just reload the schema.
|
|
990
|
+
return this.reloadData({
|
|
991
|
+
clearCache: true
|
|
992
|
+
});
|
|
993
|
+
}).then(() => {
|
|
994
|
+
// Ensure that the schema now validates
|
|
995
|
+
if (this.schemaData[className]) {
|
|
996
|
+
return this;
|
|
997
|
+
} else {
|
|
998
|
+
throw new Parse.Error(Parse.Error.INVALID_JSON, `Failed to add ${className}`);
|
|
999
|
+
}
|
|
1000
|
+
}).catch(() => {
|
|
1001
|
+
// The schema still doesn't validate. Give up
|
|
1002
|
+
throw new Parse.Error(Parse.Error.INVALID_JSON, 'schema class name does not revalidate');
|
|
1003
|
+
})
|
|
1004
|
+
);
|
|
595
1005
|
}
|
|
596
|
-
|
|
597
1006
|
validateNewClass(className, fields = {}, classLevelPermissions) {
|
|
598
|
-
if (this.
|
|
1007
|
+
if (this.schemaData[className]) {
|
|
599
1008
|
throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} already exists.`);
|
|
600
1009
|
}
|
|
601
1010
|
if (!classNameIsValid(className)) {
|
|
@@ -606,11 +1015,10 @@ class SchemaController {
|
|
|
606
1015
|
}
|
|
607
1016
|
return this.validateSchemaData(className, fields, classLevelPermissions, []);
|
|
608
1017
|
}
|
|
609
|
-
|
|
610
1018
|
validateSchemaData(className, fields, classLevelPermissions, existingFieldNames) {
|
|
611
1019
|
for (const fieldName in fields) {
|
|
612
1020
|
if (existingFieldNames.indexOf(fieldName) < 0) {
|
|
613
|
-
if (!fieldNameIsValid(fieldName)) {
|
|
1021
|
+
if (!fieldNameIsValid(fieldName, className)) {
|
|
614
1022
|
return {
|
|
615
1023
|
code: Parse.Error.INVALID_KEY_NAME,
|
|
616
1024
|
error: 'invalid field name: ' + fieldName
|
|
@@ -622,15 +1030,45 @@ class SchemaController {
|
|
|
622
1030
|
error: 'field ' + fieldName + ' cannot be added'
|
|
623
1031
|
};
|
|
624
1032
|
}
|
|
625
|
-
const
|
|
626
|
-
|
|
1033
|
+
const fieldType = fields[fieldName];
|
|
1034
|
+
const error = fieldTypeIsInvalid(fieldType);
|
|
1035
|
+
if (error) {
|
|
1036
|
+
return {
|
|
1037
|
+
code: error.code,
|
|
1038
|
+
error: error.message
|
|
1039
|
+
};
|
|
1040
|
+
}
|
|
1041
|
+
if (fieldType.defaultValue !== undefined) {
|
|
1042
|
+
let defaultValueType = getType(fieldType.defaultValue);
|
|
1043
|
+
if (typeof defaultValueType === 'string') {
|
|
1044
|
+
defaultValueType = {
|
|
1045
|
+
type: defaultValueType
|
|
1046
|
+
};
|
|
1047
|
+
} else if (typeof defaultValueType === 'object' && fieldType.type === 'Relation') {
|
|
1048
|
+
return {
|
|
1049
|
+
code: Parse.Error.INCORRECT_TYPE,
|
|
1050
|
+
error: `The 'default value' option is not applicable for ${typeToString(fieldType)}`
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
1053
|
+
if (!dbTypeMatchesObjectType(fieldType, defaultValueType)) {
|
|
1054
|
+
return {
|
|
1055
|
+
code: Parse.Error.INCORRECT_TYPE,
|
|
1056
|
+
error: `schema mismatch for ${className}.${fieldName} default value; expected ${typeToString(fieldType)} but got ${typeToString(defaultValueType)}`
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
1059
|
+
} else if (fieldType.required) {
|
|
1060
|
+
if (typeof fieldType === 'object' && fieldType.type === 'Relation') {
|
|
1061
|
+
return {
|
|
1062
|
+
code: Parse.Error.INCORRECT_TYPE,
|
|
1063
|
+
error: `The 'required' option is not applicable for ${typeToString(fieldType)}`
|
|
1064
|
+
};
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
627
1067
|
}
|
|
628
1068
|
}
|
|
629
|
-
|
|
630
1069
|
for (const fieldName in defaultColumns[className]) {
|
|
631
1070
|
fields[fieldName] = defaultColumns[className][fieldName];
|
|
632
1071
|
}
|
|
633
|
-
|
|
634
1072
|
const geoPoints = Object.keys(fields).filter(key => fields[key] && fields[key].type === 'GeoPoint');
|
|
635
1073
|
if (geoPoints.length > 1) {
|
|
636
1074
|
return {
|
|
@@ -638,76 +1076,118 @@ class SchemaController {
|
|
|
638
1076
|
error: 'currently, only one GeoPoint field may exist in an object. Adding ' + geoPoints[1] + ' when ' + geoPoints[0] + ' already exists.'
|
|
639
1077
|
};
|
|
640
1078
|
}
|
|
641
|
-
validateCLP(classLevelPermissions, fields);
|
|
1079
|
+
validateCLP(classLevelPermissions, fields, this.userIdRegEx);
|
|
642
1080
|
}
|
|
643
1081
|
|
|
644
1082
|
// Sets the Class-level permissions for a given className, which must exist.
|
|
645
|
-
setPermissions(className, perms, newSchema) {
|
|
1083
|
+
async setPermissions(className, perms, newSchema) {
|
|
646
1084
|
if (typeof perms === 'undefined') {
|
|
647
1085
|
return Promise.resolve();
|
|
648
1086
|
}
|
|
649
|
-
validateCLP(perms, newSchema);
|
|
650
|
-
|
|
1087
|
+
validateCLP(perms, newSchema, this.userIdRegEx);
|
|
1088
|
+
await this._dbAdapter.setClassLevelPermissions(className, perms);
|
|
1089
|
+
const cached = _SchemaCache.default.get(className);
|
|
1090
|
+
if (cached) {
|
|
1091
|
+
cached.classLevelPermissions = perms;
|
|
1092
|
+
}
|
|
651
1093
|
}
|
|
652
1094
|
|
|
653
1095
|
// Returns a promise that resolves successfully to the new schema
|
|
654
1096
|
// object if the provided className-fieldName-type tuple is valid.
|
|
655
1097
|
// The className must already be validated.
|
|
656
1098
|
// If 'freeze' is true, refuse to update the schema for this field.
|
|
657
|
-
enforceFieldExists(className, fieldName, type) {
|
|
658
|
-
if (fieldName.indexOf(
|
|
659
|
-
//
|
|
660
|
-
|
|
661
|
-
|
|
1099
|
+
enforceFieldExists(className, fieldName, type, isValidation, maintenance) {
|
|
1100
|
+
if (fieldName.indexOf('.') > 0) {
|
|
1101
|
+
// "<array>.<index>" for Nested Arrays
|
|
1102
|
+
// "<embedded document>.<field>" for Nested Objects
|
|
1103
|
+
// JSON Arrays are treated as Nested Objects
|
|
1104
|
+
const [x, y] = fieldName.split('.');
|
|
1105
|
+
fieldName = x;
|
|
1106
|
+
const isArrayIndex = Array.from(y).every(c => c >= '0' && c <= '9');
|
|
1107
|
+
if (isArrayIndex && !['sentPerUTCOffset', 'failedPerUTCOffset'].includes(fieldName)) {
|
|
1108
|
+
type = 'Array';
|
|
1109
|
+
} else {
|
|
1110
|
+
type = 'Object';
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
let fieldNameToValidate = `${fieldName}`;
|
|
1114
|
+
if (maintenance && fieldNameToValidate.charAt(0) === '_') {
|
|
1115
|
+
fieldNameToValidate = fieldNameToValidate.substring(1);
|
|
662
1116
|
}
|
|
663
|
-
if (!fieldNameIsValid(
|
|
1117
|
+
if (!fieldNameIsValid(fieldNameToValidate, className)) {
|
|
664
1118
|
throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, `Invalid field name: ${fieldName}.`);
|
|
665
1119
|
}
|
|
666
1120
|
|
|
667
1121
|
// If someone tries to create a new field with null/undefined as the value, return;
|
|
668
1122
|
if (!type) {
|
|
669
|
-
return
|
|
1123
|
+
return undefined;
|
|
670
1124
|
}
|
|
671
|
-
|
|
672
|
-
|
|
1125
|
+
const expectedType = this.getExpectedType(className, fieldName);
|
|
1126
|
+
if (typeof type === 'string') {
|
|
1127
|
+
type = {
|
|
1128
|
+
type
|
|
1129
|
+
};
|
|
1130
|
+
}
|
|
1131
|
+
if (type.defaultValue !== undefined) {
|
|
1132
|
+
let defaultValueType = getType(type.defaultValue);
|
|
1133
|
+
if (typeof defaultValueType === 'string') {
|
|
1134
|
+
defaultValueType = {
|
|
1135
|
+
type: defaultValueType
|
|
1136
|
+
};
|
|
1137
|
+
}
|
|
1138
|
+
if (!dbTypeMatchesObjectType(type, defaultValueType)) {
|
|
1139
|
+
throw new Parse.Error(Parse.Error.INCORRECT_TYPE, `schema mismatch for ${className}.${fieldName} default value; expected ${typeToString(type)} but got ${typeToString(defaultValueType)}`);
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
if (expectedType) {
|
|
1143
|
+
if (!dbTypeMatchesObjectType(expectedType, type)) {
|
|
1144
|
+
throw new Parse.Error(Parse.Error.INCORRECT_TYPE, `schema mismatch for ${className}.${fieldName}; expected ${typeToString(expectedType)} but got ${typeToString(type)}`);
|
|
1145
|
+
}
|
|
1146
|
+
// If type options do not change
|
|
1147
|
+
// we can safely return
|
|
1148
|
+
if (isValidation || JSON.stringify(expectedType) === JSON.stringify(type)) {
|
|
1149
|
+
return undefined;
|
|
1150
|
+
}
|
|
1151
|
+
// Field options are may be changed
|
|
1152
|
+
// ensure to have an update to date schema field
|
|
1153
|
+
return this._dbAdapter.updateFieldOptions(className, fieldName, type);
|
|
1154
|
+
}
|
|
1155
|
+
return this._dbAdapter.addFieldIfNotExists(className, fieldName, type).catch(error => {
|
|
1156
|
+
if (error.code == Parse.Error.INCORRECT_TYPE) {
|
|
1157
|
+
// Make sure that we throw errors when it is appropriate to do so.
|
|
1158
|
+
throw error;
|
|
1159
|
+
}
|
|
1160
|
+
// The update failed. This can be okay - it might have been a race
|
|
1161
|
+
// condition where another client updated the schema in the same
|
|
1162
|
+
// way that we wanted to. So, just reload the schema
|
|
1163
|
+
return Promise.resolve();
|
|
1164
|
+
}).then(() => {
|
|
1165
|
+
return {
|
|
1166
|
+
className,
|
|
1167
|
+
fieldName,
|
|
1168
|
+
type
|
|
1169
|
+
};
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1172
|
+
ensureFields(fields) {
|
|
1173
|
+
for (let i = 0; i < fields.length; i += 1) {
|
|
1174
|
+
const {
|
|
1175
|
+
className,
|
|
1176
|
+
fieldName
|
|
1177
|
+
} = fields[i];
|
|
1178
|
+
let {
|
|
1179
|
+
type
|
|
1180
|
+
} = fields[i];
|
|
673
1181
|
const expectedType = this.getExpectedType(className, fieldName);
|
|
674
1182
|
if (typeof type === 'string') {
|
|
675
|
-
type = {
|
|
1183
|
+
type = {
|
|
1184
|
+
type: type
|
|
1185
|
+
};
|
|
676
1186
|
}
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
if (!dbTypeMatchesObjectType(expectedType, type)) {
|
|
680
|
-
throw new Parse.Error(Parse.Error.INCORRECT_TYPE, `schema mismatch for ${className}.${fieldName}; expected ${typeToString(expectedType)} but got ${typeToString(type)}`);
|
|
681
|
-
}
|
|
682
|
-
return this;
|
|
1187
|
+
if (!expectedType || !dbTypeMatchesObjectType(expectedType, type)) {
|
|
1188
|
+
throw new Parse.Error(Parse.Error.INVALID_JSON, `Could not add field ${fieldName}`);
|
|
683
1189
|
}
|
|
684
|
-
|
|
685
|
-
return this._dbAdapter.addFieldIfNotExists(className, fieldName, type).then(() => {
|
|
686
|
-
// The update succeeded. Reload the schema
|
|
687
|
-
return this.reloadData({ clearCache: true });
|
|
688
|
-
}, error => {
|
|
689
|
-
if (error.code == Parse.Error.INCORRECT_TYPE) {
|
|
690
|
-
// Make sure that we throw errors when it is appropriate to do so.
|
|
691
|
-
throw error;
|
|
692
|
-
}
|
|
693
|
-
// The update failed. This can be okay - it might have been a race
|
|
694
|
-
// condition where another client updated the schema in the same
|
|
695
|
-
// way that we wanted to. So, just reload the schema
|
|
696
|
-
return this.reloadData({ clearCache: true });
|
|
697
|
-
}).then(() => {
|
|
698
|
-
// Ensure that the schema now validates
|
|
699
|
-
const expectedType = this.getExpectedType(className, fieldName);
|
|
700
|
-
if (typeof type === 'string') {
|
|
701
|
-
type = { type };
|
|
702
|
-
}
|
|
703
|
-
if (!expectedType || !dbTypeMatchesObjectType(expectedType, type)) {
|
|
704
|
-
throw new Parse.Error(Parse.Error.INVALID_JSON, `Could not add field ${fieldName}`);
|
|
705
|
-
}
|
|
706
|
-
// Remove the cached schema
|
|
707
|
-
this._cache.clear();
|
|
708
|
-
return this;
|
|
709
|
-
});
|
|
710
|
-
});
|
|
1190
|
+
}
|
|
711
1191
|
}
|
|
712
1192
|
|
|
713
1193
|
// maintain compatibility
|
|
@@ -726,9 +1206,8 @@ class SchemaController {
|
|
|
726
1206
|
if (!classNameIsValid(className)) {
|
|
727
1207
|
throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, invalidClassNameMessage(className));
|
|
728
1208
|
}
|
|
729
|
-
|
|
730
1209
|
fieldNames.forEach(fieldName => {
|
|
731
|
-
if (!fieldNameIsValid(fieldName)) {
|
|
1210
|
+
if (!fieldNameIsValid(fieldName, className)) {
|
|
732
1211
|
throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, `invalid field name: ${fieldName}`);
|
|
733
1212
|
}
|
|
734
1213
|
//Don't allow deleting the default fields.
|
|
@@ -736,8 +1215,9 @@ class SchemaController {
|
|
|
736
1215
|
throw new Parse.Error(136, `field ${fieldName} cannot be changed`);
|
|
737
1216
|
}
|
|
738
1217
|
});
|
|
739
|
-
|
|
740
|
-
|
|
1218
|
+
return this.getOneSchema(className, false, {
|
|
1219
|
+
clearCache: true
|
|
1220
|
+
}).catch(error => {
|
|
741
1221
|
if (error === undefined) {
|
|
742
1222
|
throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} does not exist.`);
|
|
743
1223
|
} else {
|
|
@@ -749,8 +1229,9 @@ class SchemaController {
|
|
|
749
1229
|
throw new Parse.Error(255, `Field ${fieldName} does not exist, cannot delete.`);
|
|
750
1230
|
}
|
|
751
1231
|
});
|
|
752
|
-
|
|
753
|
-
|
|
1232
|
+
const schemaFields = {
|
|
1233
|
+
...schema.fields
|
|
1234
|
+
};
|
|
754
1235
|
return database.adapter.deleteFields(className, schema, fieldNames).then(() => {
|
|
755
1236
|
return Promise.all(fieldNames.map(fieldName => {
|
|
756
1237
|
const field = schemaFields[fieldName];
|
|
@@ -762,31 +1243,30 @@ class SchemaController {
|
|
|
762
1243
|
}));
|
|
763
1244
|
});
|
|
764
1245
|
}).then(() => {
|
|
765
|
-
|
|
1246
|
+
_SchemaCache.default.clear();
|
|
766
1247
|
});
|
|
767
1248
|
}
|
|
768
1249
|
|
|
769
1250
|
// Validates an object provided in REST format.
|
|
770
1251
|
// Returns a promise that resolves to the new schema if this object is
|
|
771
1252
|
// valid.
|
|
772
|
-
validateObject(className, object, query) {
|
|
1253
|
+
async validateObject(className, object, query, maintenance) {
|
|
773
1254
|
let geocount = 0;
|
|
774
|
-
|
|
1255
|
+
const schema = await this.enforceClassExists(className);
|
|
1256
|
+
const promises = [];
|
|
775
1257
|
for (const fieldName in object) {
|
|
776
|
-
if (object[fieldName] ===
|
|
777
|
-
continue;
|
|
778
|
-
}
|
|
779
|
-
const expected = getType(object[fieldName]);
|
|
780
|
-
if (expected === 'GeoPoint') {
|
|
1258
|
+
if (object[fieldName] && getType(object[fieldName]) === 'GeoPoint') {
|
|
781
1259
|
geocount++;
|
|
782
1260
|
}
|
|
783
1261
|
if (geocount > 1) {
|
|
784
|
-
|
|
785
|
-
// If not - we are continuing to run logic, but already provided response from the server.
|
|
786
|
-
return promise.then(() => {
|
|
787
|
-
return Promise.reject(new Parse.Error(Parse.Error.INCORRECT_TYPE, 'there can only be one geopoint field in a class'));
|
|
788
|
-
});
|
|
1262
|
+
return Promise.reject(new Parse.Error(Parse.Error.INCORRECT_TYPE, 'there can only be one geopoint field in a class'));
|
|
789
1263
|
}
|
|
1264
|
+
}
|
|
1265
|
+
for (const fieldName in object) {
|
|
1266
|
+
if (object[fieldName] === undefined) {
|
|
1267
|
+
continue;
|
|
1268
|
+
}
|
|
1269
|
+
const expected = getType(object[fieldName]);
|
|
790
1270
|
if (!expected) {
|
|
791
1271
|
continue;
|
|
792
1272
|
}
|
|
@@ -794,23 +1274,30 @@ class SchemaController {
|
|
|
794
1274
|
// Every object has ACL implicitly.
|
|
795
1275
|
continue;
|
|
796
1276
|
}
|
|
797
|
-
|
|
798
|
-
|
|
1277
|
+
promises.push(schema.enforceFieldExists(className, fieldName, expected, true, maintenance));
|
|
1278
|
+
}
|
|
1279
|
+
const results = await Promise.all(promises);
|
|
1280
|
+
const enforceFields = results.filter(result => !!result);
|
|
1281
|
+
if (enforceFields.length !== 0) {
|
|
1282
|
+
// TODO: Remove by updating schema cache directly
|
|
1283
|
+
await this.reloadData({
|
|
1284
|
+
clearCache: true
|
|
1285
|
+
});
|
|
799
1286
|
}
|
|
800
|
-
|
|
801
|
-
|
|
1287
|
+
this.ensureFields(enforceFields);
|
|
1288
|
+
const promise = Promise.resolve(schema);
|
|
1289
|
+
return thenValidateRequiredColumns(promise, className, object, query);
|
|
802
1290
|
}
|
|
803
1291
|
|
|
804
1292
|
// Validates that all the properties are set for the object
|
|
805
1293
|
validateRequiredColumns(className, object, query) {
|
|
806
|
-
const columns = requiredColumns[className];
|
|
1294
|
+
const columns = requiredColumns.write[className];
|
|
807
1295
|
if (!columns || columns.length == 0) {
|
|
808
1296
|
return Promise.resolve(this);
|
|
809
1297
|
}
|
|
810
|
-
|
|
811
1298
|
const missingColumns = columns.filter(function (column) {
|
|
812
1299
|
if (query && query.objectId) {
|
|
813
|
-
if (object[column] && typeof object[column] ===
|
|
1300
|
+
if (object[column] && typeof object[column] === 'object') {
|
|
814
1301
|
// Trying to delete a required column
|
|
815
1302
|
return object[column].__op == 'Delete';
|
|
816
1303
|
}
|
|
@@ -819,21 +1306,21 @@ class SchemaController {
|
|
|
819
1306
|
}
|
|
820
1307
|
return !object[column];
|
|
821
1308
|
});
|
|
822
|
-
|
|
823
1309
|
if (missingColumns.length > 0) {
|
|
824
1310
|
throw new Parse.Error(Parse.Error.INCORRECT_TYPE, missingColumns[0] + ' is required.');
|
|
825
1311
|
}
|
|
826
1312
|
return Promise.resolve(this);
|
|
827
1313
|
}
|
|
1314
|
+
testPermissionsForClassName(className, aclGroup, operation) {
|
|
1315
|
+
return SchemaController.testPermissions(this.getClassLevelPermissions(className), aclGroup, operation);
|
|
1316
|
+
}
|
|
828
1317
|
|
|
829
|
-
//
|
|
830
|
-
|
|
831
|
-
if (!
|
|
1318
|
+
// Tests that the class level permission let pass the operation for a given aclGroup
|
|
1319
|
+
static testPermissions(classPermissions, aclGroup, operation) {
|
|
1320
|
+
if (!classPermissions || !classPermissions[operation]) {
|
|
832
1321
|
return true;
|
|
833
1322
|
}
|
|
834
|
-
const
|
|
835
|
-
const perms = classPerms[operation];
|
|
836
|
-
// Handle the public scenario quickly
|
|
1323
|
+
const perms = classPermissions[operation];
|
|
837
1324
|
if (perms['*']) {
|
|
838
1325
|
return true;
|
|
839
1326
|
}
|
|
@@ -847,26 +1334,23 @@ class SchemaController {
|
|
|
847
1334
|
}
|
|
848
1335
|
|
|
849
1336
|
// Validates an operation passes class-level-permissions set in the schema
|
|
850
|
-
validatePermission(className, aclGroup, operation) {
|
|
851
|
-
|
|
852
|
-
if (this.testBaseCLP(className, aclGroup, operation)) {
|
|
1337
|
+
static validatePermission(classPermissions, className, aclGroup, operation, action) {
|
|
1338
|
+
if (SchemaController.testPermissions(classPermissions, aclGroup, operation)) {
|
|
853
1339
|
return Promise.resolve();
|
|
854
1340
|
}
|
|
855
|
-
|
|
856
|
-
if (!this.perms[className] || !this.perms[className][operation]) {
|
|
1341
|
+
if (!classPermissions || !classPermissions[operation]) {
|
|
857
1342
|
return true;
|
|
858
1343
|
}
|
|
859
|
-
const
|
|
860
|
-
const
|
|
861
|
-
|
|
1344
|
+
const perms = classPermissions[operation];
|
|
1345
|
+
const config = _Config.default.get(Parse.applicationId);
|
|
862
1346
|
// If only for authenticated users
|
|
863
1347
|
// make sure we have an aclGroup
|
|
864
1348
|
if (perms['requiresAuthentication']) {
|
|
865
1349
|
// If aclGroup has * (public)
|
|
866
1350
|
if (!aclGroup || aclGroup.length == 0) {
|
|
867
|
-
throw
|
|
1351
|
+
throw (0, _Error.createSanitizedError)(Parse.Error.OBJECT_NOT_FOUND, 'Permission denied, user needs to be authenticated.', config);
|
|
868
1352
|
} else if (aclGroup.indexOf('*') > -1 && aclGroup.length == 1) {
|
|
869
|
-
throw
|
|
1353
|
+
throw (0, _Error.createSanitizedError)(Parse.Error.OBJECT_NOT_FOUND, 'Permission denied, user needs to be authenticated.', config);
|
|
870
1354
|
}
|
|
871
1355
|
// requiresAuthentication passed, just move forward
|
|
872
1356
|
// probably would be wise at some point to rename to 'authenticatedUser'
|
|
@@ -879,21 +1363,37 @@ class SchemaController {
|
|
|
879
1363
|
|
|
880
1364
|
// Reject create when write lockdown
|
|
881
1365
|
if (permissionField == 'writeUserFields' && operation == 'create') {
|
|
882
|
-
throw
|
|
1366
|
+
throw (0, _Error.createSanitizedError)(Parse.Error.OPERATION_FORBIDDEN, `Permission denied for action ${operation} on class ${className}.`, config);
|
|
883
1367
|
}
|
|
884
1368
|
|
|
885
1369
|
// Process the readUserFields later
|
|
886
|
-
if (Array.isArray(
|
|
1370
|
+
if (Array.isArray(classPermissions[permissionField]) && classPermissions[permissionField].length > 0) {
|
|
887
1371
|
return Promise.resolve();
|
|
888
1372
|
}
|
|
889
|
-
|
|
1373
|
+
const pointerFields = classPermissions[operation].pointerFields;
|
|
1374
|
+
if (Array.isArray(pointerFields) && pointerFields.length > 0) {
|
|
1375
|
+
// any op except 'addField as part of create' is ok.
|
|
1376
|
+
if (operation !== 'addField' || action === 'update') {
|
|
1377
|
+
// We can allow adding field on update flow only.
|
|
1378
|
+
return Promise.resolve();
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
throw (0, _Error.createSanitizedError)(Parse.Error.OPERATION_FORBIDDEN, `Permission denied for action ${operation} on class ${className}.`, config);
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
// Validates an operation passes class-level-permissions set in the schema
|
|
1385
|
+
validatePermission(className, aclGroup, operation, action) {
|
|
1386
|
+
return SchemaController.validatePermission(this.getClassLevelPermissions(className), className, aclGroup, operation, action);
|
|
1387
|
+
}
|
|
1388
|
+
getClassLevelPermissions(className) {
|
|
1389
|
+
return this.schemaData[className] && this.schemaData[className].classLevelPermissions;
|
|
890
1390
|
}
|
|
891
1391
|
|
|
892
1392
|
// Returns the expected type for a className+key combination
|
|
893
1393
|
// or undefined if the schema is not set
|
|
894
1394
|
getExpectedType(className, fieldName) {
|
|
895
|
-
if (this.
|
|
896
|
-
const expectedType = this.
|
|
1395
|
+
if (this.schemaData[className]) {
|
|
1396
|
+
const expectedType = this.schemaData[className].fields[fieldName];
|
|
897
1397
|
return expectedType === 'map' ? 'Object' : expectedType;
|
|
898
1398
|
}
|
|
899
1399
|
return undefined;
|
|
@@ -901,14 +1401,18 @@ class SchemaController {
|
|
|
901
1401
|
|
|
902
1402
|
// Checks if a given class is in the schema.
|
|
903
1403
|
hasClass(className) {
|
|
904
|
-
|
|
1404
|
+
if (this.schemaData[className]) {
|
|
1405
|
+
return Promise.resolve(true);
|
|
1406
|
+
}
|
|
1407
|
+
return this.reloadData().then(() => !!this.schemaData[className]);
|
|
905
1408
|
}
|
|
906
1409
|
}
|
|
907
1410
|
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
const load = (dbAdapter,
|
|
911
|
-
const schema = new SchemaController(dbAdapter
|
|
1411
|
+
// Returns a promise for a new Schema.
|
|
1412
|
+
exports.SchemaController = exports.default = SchemaController;
|
|
1413
|
+
const load = (dbAdapter, options) => {
|
|
1414
|
+
const schema = new SchemaController(dbAdapter);
|
|
1415
|
+
ttl.duration = dbAdapter.schemaCacheTtl;
|
|
912
1416
|
return schema.reloadData(options).then(() => schema);
|
|
913
1417
|
};
|
|
914
1418
|
|
|
@@ -917,6 +1421,7 @@ const load = (dbAdapter, schemaCache, options) => {
|
|
|
917
1421
|
// does not include the default fields, as it is intended to be passed
|
|
918
1422
|
// to mongoSchemaFromFieldsAndClassName. No validation is done here, it
|
|
919
1423
|
// is done in mongoSchemaFromFieldsAndClassName.
|
|
1424
|
+
exports.load = load;
|
|
920
1425
|
function buildMergedSchemaObject(existingFields, putRequest) {
|
|
921
1426
|
const newSchema = {};
|
|
922
1427
|
// -disable-next
|
|
@@ -1030,7 +1535,7 @@ function getObjectType(obj) {
|
|
|
1030
1535
|
}
|
|
1031
1536
|
break;
|
|
1032
1537
|
}
|
|
1033
|
-
throw new Parse.Error(Parse.Error.INCORRECT_TYPE,
|
|
1538
|
+
throw new Parse.Error(Parse.Error.INCORRECT_TYPE, 'This is not a valid ' + obj.__type);
|
|
1034
1539
|
}
|
|
1035
1540
|
if (obj['$ne']) {
|
|
1036
1541
|
return getObjectType(obj['$ne']);
|
|
@@ -1059,15 +1564,4 @@ function getObjectType(obj) {
|
|
|
1059
1564
|
}
|
|
1060
1565
|
return 'Object';
|
|
1061
1566
|
}
|
|
1062
|
-
|
|
1063
|
-
exports.load = load;
|
|
1064
|
-
exports.classNameIsValid = classNameIsValid;
|
|
1065
|
-
exports.fieldNameIsValid = fieldNameIsValid;
|
|
1066
|
-
exports.invalidClassNameMessage = invalidClassNameMessage;
|
|
1067
|
-
exports.buildMergedSchemaObject = buildMergedSchemaObject;
|
|
1068
|
-
exports.systemClasses = systemClasses;
|
|
1069
|
-
exports.defaultColumns = defaultColumns;
|
|
1070
|
-
exports.convertSchemaToAdapterSchema = convertSchemaToAdapterSchema;
|
|
1071
|
-
exports.VolatileClassesSchemas = VolatileClassesSchemas;
|
|
1072
|
-
exports.SchemaController = SchemaController;
|
|
1073
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9TY2hlbWFDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIlBhcnNlIiwicmVxdWlyZSIsImRlZmF1bHRDb2x1bW5zIiwiT2JqZWN0IiwiZnJlZXplIiwiX0RlZmF1bHQiLCJ0eXBlIiwiX1VzZXIiLCJfSW5zdGFsbGF0aW9uIiwiX1JvbGUiLCJ0YXJnZXRDbGFzcyIsIl9TZXNzaW9uIiwiX1Byb2R1Y3QiLCJfUHVzaFN0YXR1cyIsIl9Kb2JTdGF0dXMiLCJfSm9iU2NoZWR1bGUiLCJfSG9va3MiLCJfR2xvYmFsQ29uZmlnIiwiX0F1ZGllbmNlIiwicmVxdWlyZWRDb2x1bW5zIiwic3lzdGVtQ2xhc3NlcyIsInZvbGF0aWxlQ2xhc3NlcyIsInVzZXJJZFJlZ2V4Iiwicm9sZVJlZ2V4IiwicHVibGljUmVnZXgiLCJyZXF1aXJlQXV0aGVudGljYXRpb25SZWdleCIsInBlcm1pc3Npb25LZXlSZWdleCIsInZlcmlmeVBlcm1pc3Npb25LZXkiLCJrZXkiLCJyZXN1bHQiLCJyZWR1Y2UiLCJpc0dvb2QiLCJyZWdFeCIsIm1hdGNoIiwiRXJyb3IiLCJJTlZBTElEX0pTT04iLCJDTFBWYWxpZEtleXMiLCJ2YWxpZGF0ZUNMUCIsInBlcm1zIiwiZmllbGRzIiwia2V5cyIsImZvckVhY2giLCJvcGVyYXRpb24iLCJpbmRleE9mIiwiQXJyYXkiLCJpc0FycmF5IiwicGVybSIsImpvaW5DbGFzc1JlZ2V4IiwiY2xhc3NBbmRGaWVsZFJlZ2V4IiwiY2xhc3NOYW1lSXNWYWxpZCIsImNsYXNzTmFtZSIsInRlc3QiLCJmaWVsZE5hbWVJc1ZhbGlkIiwiZmllbGROYW1lIiwiZmllbGROYW1lSXNWYWxpZEZvckNsYXNzIiwiaW52YWxpZENsYXNzTmFtZU1lc3NhZ2UiLCJpbnZhbGlkSnNvbkVycm9yIiwidmFsaWROb25SZWxhdGlvbk9yUG9pbnRlclR5cGVzIiwiZmllbGRUeXBlSXNJbnZhbGlkIiwiSU5WQUxJRF9DTEFTU19OQU1FIiwidW5kZWZpbmVkIiwiSU5DT1JSRUNUX1RZUEUiLCJjb252ZXJ0U2NoZW1hVG9BZGFwdGVyU2NoZW1hIiwic2NoZW1hIiwiaW5qZWN0RGVmYXVsdFNjaGVtYSIsIkFDTCIsIl9ycGVybSIsIl93cGVybSIsInBhc3N3b3JkIiwiX2hhc2hlZF9wYXNzd29yZCIsImNvbnZlcnRBZGFwdGVyU2NoZW1hVG9QYXJzZVNjaGVtYSIsImF1dGhEYXRhIiwiaW5kZXhlcyIsImxlbmd0aCIsImNsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsImRlZmF1bHRTY2hlbWEiLCJfSG9va3NTY2hlbWEiLCJfR2xvYmFsQ29uZmlnU2NoZW1hIiwiX1B1c2hTdGF0dXNTY2hlbWEiLCJfSm9iU3RhdHVzU2NoZW1hIiwiX0pvYlNjaGVkdWxlU2NoZW1hIiwiX0F1ZGllbmNlU2NoZW1hIiwiVm9sYXRpbGVDbGFzc2VzU2NoZW1hcyIsImRiVHlwZU1hdGNoZXNPYmplY3RUeXBlIiwiZGJUeXBlIiwib2JqZWN0VHlwZSIsInR5cGVUb1N0cmluZyIsIlNjaGVtYUNvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImRhdGFiYXNlQWRhcHRlciIsInNjaGVtYUNhY2hlIiwiX2RiQWRhcHRlciIsIl9jYWNoZSIsImRhdGEiLCJyZWxvYWREYXRhIiwib3B0aW9ucyIsImNsZWFyQ2FjaGUiLCJwcm9taXNlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ0aGVuIiwiY2xlYXIiLCJyZWxvYWREYXRhUHJvbWlzZSIsImdldEFsbENsYXNzZXMiLCJhbGxTY2hlbWFzIiwiZXJyIiwiYWxsQ2xhc3NlcyIsIm1hcCIsInNldEFsbENsYXNzZXMiLCJnZXRPbmVTY2hlbWEiLCJhbGxvd1ZvbGF0aWxlQ2xhc3NlcyIsImNhY2hlZCIsImdldENsYXNzIiwic2V0T25lU2NoZW1hIiwiYWRkQ2xhc3NJZk5vdEV4aXN0cyIsInZhbGlkYXRpb25FcnJvciIsInZhbGlkYXRlTmV3Q2xhc3MiLCJyZWplY3QiLCJjcmVhdGVDbGFzcyIsInJlcyIsImNhdGNoIiwiZXJyb3IiLCJjb2RlIiwiRFVQTElDQVRFX1ZBTFVFIiwidXBkYXRlQ2xhc3MiLCJzdWJtaXR0ZWRGaWVsZHMiLCJkYXRhYmFzZSIsImV4aXN0aW5nRmllbGRzIiwibmFtZSIsImZpZWxkIiwiX19vcCIsIm5ld1NjaGVtYSIsImJ1aWxkTWVyZ2VkU2NoZW1hT2JqZWN0IiwiZGVmYXVsdEZpZWxkcyIsImZ1bGxOZXdTY2hlbWEiLCJhc3NpZ24iLCJ2YWxpZGF0ZVNjaGVtYURhdGEiLCJkZWxldGVkRmllbGRzIiwiaW5zZXJ0ZWRGaWVsZHMiLCJwdXNoIiwiZGVsZXRlUHJvbWlzZSIsImRlbGV0ZUZpZWxkcyIsInByb21pc2VzIiwiZW5mb3JjZUZpZWxkRXhpc3RzIiwiYWxsIiwic2V0UGVybWlzc2lvbnMiLCJzZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdCIsInJlbG9hZGVkU2NoZW1hIiwiZW5mb3JjZUNsYXNzRXhpc3RzIiwiZXhpc3RpbmdGaWVsZE5hbWVzIiwiSU5WQUxJRF9LRVlfTkFNRSIsIm1lc3NhZ2UiLCJnZW9Qb2ludHMiLCJmaWx0ZXIiLCJzZXRDbGFzc0xldmVsUGVybWlzc2lvbnMiLCJzcGxpdCIsImV4cGVjdGVkVHlwZSIsImdldEV4cGVjdGVkVHlwZSIsImFkZEZpZWxkSWZOb3RFeGlzdHMiLCJkZWxldGVGaWVsZCIsImZpZWxkTmFtZXMiLCJzY2hlbWFGaWVsZHMiLCJhZGFwdGVyIiwiZGVsZXRlQ2xhc3MiLCJ2YWxpZGF0ZU9iamVjdCIsIm9iamVjdCIsInF1ZXJ5IiwiZ2VvY291bnQiLCJleHBlY3RlZCIsImdldFR5cGUiLCJ0aGVuVmFsaWRhdGVSZXF1aXJlZENvbHVtbnMiLCJ2YWxpZGF0ZVJlcXVpcmVkQ29sdW1ucyIsImNvbHVtbnMiLCJtaXNzaW5nQ29sdW1ucyIsImNvbHVtbiIsIm9iamVjdElkIiwidGVzdEJhc2VDTFAiLCJhY2xHcm91cCIsImNsYXNzUGVybXMiLCJzb21lIiwiYWNsIiwidmFsaWRhdGVQZXJtaXNzaW9uIiwiT0JKRUNUX05PVF9GT1VORCIsInBlcm1pc3Npb25GaWVsZCIsIk9QRVJBVElPTl9GT1JCSURERU4iLCJoYXNDbGFzcyIsImxvYWQiLCJkYkFkYXB0ZXIiLCJwdXRSZXF1ZXN0Iiwic3lzU2NoZW1hRmllbGQiLCJfaWQiLCJvbGRGaWVsZCIsImZpZWxkSXNEZWxldGVkIiwibmV3RmllbGQiLCJzY2hlbWFQcm9taXNlIiwib2JqIiwiZ2V0T2JqZWN0VHlwZSIsIl9fdHlwZSIsImlzbyIsImxhdGl0dWRlIiwibG9uZ2l0dWRlIiwiYmFzZTY0IiwiY29vcmRpbmF0ZXMiLCJvYmplY3RzIiwib3BzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFrQkE7O0FBQ0E7Ozs7Ozs7O0FBbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTUEsUUFBUUMsUUFBUSxZQUFSLEVBQXNCRCxLQUFwQzs7O0FBV0EsTUFBTUUsaUJBQTJDQyxPQUFPQyxNQUFQLENBQWM7QUFDN0Q7QUFDQUMsWUFBVTtBQUNSLGdCQUFhLEVBQUNDLE1BQUssUUFBTixFQURMO0FBRVIsaUJBQWEsRUFBQ0EsTUFBSyxNQUFOLEVBRkw7QUFHUixpQkFBYSxFQUFDQSxNQUFLLE1BQU4sRUFITDtBQUlSLFdBQWEsRUFBQ0EsTUFBSyxLQUFOO0FBSkwsR0FGbUQ7QUFRN0Q7QUFDQUMsU0FBTztBQUNMLGdCQUFpQixFQUFDRCxNQUFLLFFBQU4sRUFEWjtBQUVMLGdCQUFpQixFQUFDQSxNQUFLLFFBQU4sRUFGWjtBQUdMLGFBQWlCLEVBQUNBLE1BQUssUUFBTixFQUhaO0FBSUwscUJBQWlCLEVBQUNBLE1BQUssU0FBTixFQUpaO0FBS0wsZ0JBQWlCLEVBQUNBLE1BQUssUUFBTjtBQUxaLEdBVHNEO0FBZ0I3RDtBQUNBRSxpQkFBZTtBQUNiLHNCQUFvQixFQUFDRixNQUFLLFFBQU4sRUFEUDtBQUViLG1CQUFvQixFQUFDQSxNQUFLLFFBQU4sRUFGUDtBQUdiLGdCQUFvQixFQUFDQSxNQUFLLE9BQU4sRUFIUDtBQUliLGtC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TDVILGdCQUFNLFVBREQ7QUFFTEksdUJBQWF5TCxJQUFJUSxPQUFKLENBQVksQ0FBWixFQUFleko7QUFGdkIsU0FBUDtBQUlGLFdBQUssT0FBTDtBQUNFLGVBQU9rSixjQUFjRCxJQUFJUyxHQUFKLENBQVEsQ0FBUixDQUFkLENBQVA7QUFDRjtBQUNFLGNBQU0sb0JBQW9CVCxJQUFJakUsSUFBOUI7QUFsQkY7QUFvQkQ7QUFDRCxTQUFPLFFBQVA7QUFDRDs7UUFHQ3dELEksR0FBQUEsSTtRQUNBekksZ0IsR0FBQUEsZ0I7UUFDQUcsZ0IsR0FBQUEsZ0I7UUFDQUcsdUIsR0FBQUEsdUI7UUFDQTZFLHVCLEdBQUFBLHVCO1FBQ0FoSCxhLEdBQUFBLGE7UUFDQWxCLGMsR0FBQUEsYztRQUNBNEQsNEIsR0FBQUEsNEI7UUFDQW9CLHNCLEdBQUFBLHNCO1FBQ0FLLGdCLEdBQUFBLGdCIiwiZmlsZSI6IlNjaGVtYUNvbnRyb2xsZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAZmxvd1xuLy8gVGhpcyBjbGFzcyBoYW5kbGVzIHNjaGVtYSB2YWxpZGF0aW9uLCBwZXJzaXN0ZW5jZSwgYW5kIG1vZGlmaWNhdGlvbi5cbi8vXG4vLyBFYWNoIGluZGl2aWR1YWwgU2NoZW1hIG9iamVjdCBzaG91bGQgYmUgaW1tdXRhYmxlLiBUaGUgaGVscGVycyB0b1xuLy8gZG8gdGhpbmdzIHdpdGggdGhlIFNjaGVtYSBqdXN0IHJldHVybiBhIG5ldyBzY2hlbWEgd2hlbiB0aGUgc2NoZW1hXG4vLyBpcyBjaGFuZ2VkLlxuLy9cbi8vIFRoZSBjYW5vbmljYWwgcGxhY2UgdG8gc3RvcmUgdGhpcyBTY2hlbWEgaXMgaW4gdGhlIGRhdGFiYXNlIGl0c2VsZixcbi8vIGluIGEgX1NDSEVNQSBjb2xsZWN0aW9uLiBUaGlzIGlzIG5vdCB0aGUgcmlnaHQgd2F5IHRvIGRvIGl0IGZvciBhblxuLy8gb3BlbiBzb3VyY2UgZnJhbWV3b3JrLCBidXQgaXQncyBiYWNrd2FyZCBjb21wYXRpYmxlLCBzbyB3ZSdyZVxuLy8ga2VlcGluZyBpdCB0aGlzIHdheSBmb3Igbm93LlxuLy9cbi8vIEluIEFQSS1oYW5kbGluZyBjb2RlLCB5b3Ugc2hvdWxkIG9ubHkgdXNlIHRoZSBTY2hlbWEgY2xhc3MgdmlhIHRoZVxuLy8gRGF0YWJhc2VDb250cm9sbGVyLiBUaGlzIHdpbGwgbGV0IHVzIHJlcGxhY2UgdGhlIHNjaGVtYSBsb2dpYyBmb3Jcbi8vIGRpZmZlcmVudCBkYXRhYmFzZXMuXG4vLyBUT0RPOiBoaWRlIGFsbCBzY2hlbWEgbG9naWMgaW5zaWRlIHRoZSBkYXRhYmFzZSBhZGFwdGVyLlxuLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG5jb25zdCBQYXJzZSA9IHJlcXVpcmUoJ3BhcnNlL25vZGUnKS5QYXJzZTtcbmltcG9ydCB7IFN0b3JhZ2VBZGFwdGVyIH0gICAgIGZyb20gJy4uL0FkYXB0ZXJzL1N0b3JhZ2UvU3RvcmFnZUFkYXB0ZXInO1xuaW1wb3J0IERhdGFiYXNlQ29udHJvbGxlciAgICAgZnJvbSAnLi9EYXRhYmFzZUNvbnRyb2xsZXInO1xuaW1wb3J0IHR5cGUge1xuICBTY2hlbWEsXG4gIFNjaGVtYUZpZWxkcyxcbiAgQ2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICBTY2hlbWFGaWVsZCxcbiAgTG9hZFNjaGVtYU9wdGlvbnMsXG59IGZyb20gJy4vdHlwZXMnO1xuXG5jb25zdCBkZWZhdWx0Q29sdW1uczoge1tzdHJpbmddOiBTY2hlbWFGaWVsZHN9ID0gT2JqZWN0LmZyZWV6ZSh7XG4gIC8vIENvbnRhaW4gdGhlIGRlZmF1bHQgY29sdW1ucyBmb3IgZXZlcnkgcGFyc2Ugb2JqZWN0IHR5cGUgKGV4Y2VwdCBfSm9pbiBjb2xsZWN0aW9uKVxuICBfRGVmYXVsdDoge1xuICAgIFwib2JqZWN0SWRcIjogIHt0eXBlOidTdHJpbmcnfSxcbiAgICBcImNyZWF0ZWRBdFwiOiB7dHlwZTonRGF0ZSd9LFxuICAgIFwidXBkYXRlZEF0XCI6IHt0eXBlOidEYXRlJ30sXG4gICAgXCJBQ0xcIjogICAgICAge3R5cGU6J0FDTCd9LFxuICB9LFxuICAvLyBUaGUgYWRkaXRpb25hbCBkZWZhdWx0IGNvbHVtbnMgZm9yIHRoZSBfVXNlciBjb2xsZWN0aW9uIChpbiBhZGRpdGlvbiB0byBEZWZhdWx0Q29scylcbiAgX1VzZXI6IHtcbiAgICBcInVzZXJuYW1lXCI6ICAgICAge3R5cGU6J1N0cmluZyd9LFxuICAgIFwicGFzc3dvcmRcIjogICAgICB7dHlwZTonU3RyaW5nJ30sXG4gICAgXCJlbWFpbFwiOiAgICAgICAgIHt0eXBlOidTdHJpbmcnfSxcbiAgICBcImVtYWlsVmVyaWZpZWRcIjoge3R5cGU6J0Jvb2xlYW4nfSxcbiAgICBcImF1dGhEYXRhXCI6ICAgICAge3R5cGU6J09iamVjdCd9XG4gIH0sXG4gIC8vIFRoZSBhZGRpdGlvbmFsIGRlZmF1bHQgY29sdW1ucyBmb3IgdGhlIF9JbnN0YWxsYXRpb24gY29sbGVjdGlvbiAoaW4gYWRkaXRpb24gdG8gRGVmYXVsdENvbHMpXG4gIF9JbnN0YWxsYXRpb246IHtcbiAgICBcImluc3RhbGxhdGlvbklkXCI6ICAge3R5cGU6J1N0cmluZyd9LFxuICAgIFwiZGV2aWNlVG9rZW5cIjogICAgICB7dHlwZTonU3RyaW5nJ30sXG4gICAgXCJjaGFubmVsc1wiOiAgICAgICAgIHt0eXBlOidBcnJheSd9LFxuICAgIFwiZGV2aWNlVHlwZVwiOiAgICAgICB7dHlwZTonU3RyaW5nJ30sXG4gICAgXCJwdXNoVHlwZVwiOiAgICAgICAgIHt0eXBlOidTdHJpbmcnfSxcbiAgICBcIkdDTVNlbmRlcklkXCI6ICAgICAge3R5cGU6J1N0cmluZyd9LFxuICAgIFwidGltZVpvbmVcIjogICAgICAgICB7dHlwZTonU3RyaW5nJ30sXG4gICAgXCJsb2NhbGVJZGVudGlmaWVyXCI6IHt0eXBlOidTdHJpbmcnfSxcbiAgICBcImJhZGdlXCI6ICAgICAgICAgICAge3R5cGU6J051bWJlcid9LFxuICAgIFwiYXBwVmVyc2lvblwiOiAgICAgICB7dHlwZTonU3RyaW5nJ30sXG4gICAgXCJhcHBOYW1lXCI6ICAgICAgICAgIHt0eXBlOidTdHJpbmcnfSxcbiAgICBcImFwcElkZW50aWZpZXJcIjogICAge3R5cGU6J1N0cmluZyd9LFxuICAgIFwicGFyc2VWZXJzaW9uXCI6ICAgICB7dHlwZTonU3RyaW5nJ30sXG4gIH0sXG4gIC8vIFRoZSBhZGRpdGlvbmFsIGRlZmF1bHQgY29sdW1ucyBmb3IgdGhlIF9Sb2xlIGNvbGxlY3Rpb24gKGluIGFkZGl0aW9uIHRvIERlZmF1bHRDb2xzKVxuICBfUm9sZToge1xuICAgIFwibmFtZVwiOiAge3R5cGU6J1N0cmluZyd9LFxuICAgIFwidXNlcnNcIjoge3R5cGU6J1JlbGF0aW9uJywgdGFyZ2V0Q2xhc3M6J19Vc2VyJ30sXG4gICAgXCJyb2xlc1wiOiB7dHlwZTonUmVsYXRpb24nLCB0YXJnZXRDbGFzczonX1JvbGUnfVxuICB9LFxuICAvLyBUaGUgYWRkaXRpb25hbCBkZWZhdWx0IGNvbHVtbnMgZm9yIHRoZSBfU2Vzc2lvbiBjb2xsZWN0aW9uIChpbiBhZGRpdGlvbiB0byBEZWZhdWx0Q29scylcbiAgX1Nlc3Npb246IHtcbiAgICBcInJlc3RyaWN0ZWRcIjogICAgIHt0eXBlOidCb29sZWFuJ30sXG4gICAgXCJ1c2VyXCI6ICAgICAgICAgICB7dHlwZTonUG9pbnRlcicsIHRhcmdldENsYXNzOidfVXNlcid9LFxuICAgIFwiaW5zdGFsbGF0aW9uSWRcIjoge3R5cGU6J1N0cmluZyd9LFxuICAgIFwic2Vzc2lvblRva2VuXCI6ICAge3R5cGU6J1N0cmluZyd9LFxuICAgIFwiZXhwaXJlc0F0XCI6ICAgICAge3R5cGU6J0RhdGUnfSxcbiAgICBcImNyZWF0ZWRXaXRoXCI6ICAgIHt0eXBlOidPYmplY3QnfVxuICB9LFxuICBfUHJvZHVjdDoge1xuICAgIFwicHJvZHVjdElkZW50aWZpZXJcIjogIHt0eXBlOidTdHJpbmcnfSxcbiAgICBcImRvd25sb2FkXCI6ICAgICAgICAgICB7dHlwZTonRmlsZSd9LFxuICAgIFwiZG93bmxvYWROYW1lXCI6ICAgICAgIHt0eXBlOidTdHJpbmcnfSxcbiAgICBcImljb25cIjogICAgICAgICAgICAgICB7dHlwZTonRmlsZSd9LFxuICAgIFwib3JkZXJcIjogICAgICAgICAgICAgIHt0eXBlOidOdW1iZXInfSxcbiAgICBcInRpdGxlXCI6ICAgICAgICAgICAgICB7dHlwZTonU3RyaW5nJ30sXG4gICAgXCJzdWJ0aXRsZVwiOiAgICAgICAgICAge3R5cGU6J1N0cmluZyd9LFxuICB9LFxuICBfUHVzaFN0YXR1czoge1xuICAgIFwicHVzaFRpbWVcIjogICAgICAgICAgICB7dHlwZTonU3RyaW5nJ30sXG4gICAgXCJzb3VyY2VcIjogICAgICAgICAgICAgIHt0eXBlOidTdHJpbmcnfSwgLy8gcmVzdCBvciB3ZWJ1aVxuICAgIFwicXVlcnlcIjogICAgICAgICAgICAgICB7dHlwZTonU3RyaW5nJ30sIC8vIHRoZSBzdHJpbmdpZmllZCBKU09OIHF1ZXJ5XG4gICAgXCJwYXlsb2FkXCI6ICAgICAgICAgICAgIHt0eXBlOidTdHJpbmcnfSwgLy8gdGhlIHN0cmluZ2lmaWVkIEpTT04gcGF5bG9hZCxcbiAgICBcInRpdGxlXCI6ICAgICAgICAgICAgICAge3R5cGU6J1N0cmluZyd9LFxuICAgIFwiZXhwaXJ5XCI6ICAgICAgICAgICAgICB7dHlwZTonTnVtYmVyJ30sXG4gICAgXCJleHBpcmF0aW9uX2ludGVydmFsXCI6IHt0eXBlOidOdW1iZXInfSxcbiAgICBcInN0YXR1c1wiOiAgICAgICAgICAgICAge3R5cGU6J1N0cmluZyd9LFxuICAgIFwibnVtU2VudFwiOiAgICAgICAgICAgICB7dHlwZTonTnVtYmVyJ30sXG4gICAgXCJudW1GYWlsZWRcIjogICAgICAgICAgIHt0eXBlOidOdW1iZXInfSxcbiAgICBcInB1c2hIYXNoXCI6ICAgICAgICAgICAge3R5cGU6J1N0cmluZyd9LFxuICAgIFwiZXJyb3JNZXNzYWdlXCI6ICAgICAgICB7dHlwZTonT2JqZWN0J30sXG4gICAgXCJzZW50UGVyVHlwZVwiOiAgICAgICAgIHt0eXBlOidPYmplY3QnfSxcbiAgICBcImZhaWxlZFBlclR5cGVcIjogICAgICAge3R5cGU6J09iamVjdCd9LFxuICAgIFwic2VudFBlclVUQ09mZnNldFwiOiAgICB7dHlwZTonT2JqZWN0J30sXG4gICAgXCJmYWlsZWRQZXJVVENPZmZzZXRcIjogIHt0eXBlOidPYmplY3QnfSxcbiAgICBcImNvdW50XCI6ICAgICAgICAgICAgICAge3R5cGU6J051bWJlcid9IC8vIHRyYWNrcyAjIG9mIGJhdGNoZXMgcXVldWVkIGFuZCBwZW5kaW5nXG4gIH0sXG4gIF9Kb2JTdGF0dXM6IHtcbiAgICBcImpvYk5hbWVcIjogICAge3R5cGU6ICdTdHJpbmcnfSxcbiAgICBcInNvdXJjZVwiOiAgICAge3R5cGU6ICdTdHJpbmcnfSxcbiAgICBcInN0YXR1c1wiOiAgICAge3R5cGU6ICdTdHJpbmcnfSxcbiAgICBcIm1lc3NhZ2VcIjogICAge3R5cGU6ICdTdHJpbmcnfSxcbiAgICBcInBhcmFtc1wiOiAgICAge3R5cGU6ICdPYmplY3QnfSwgLy8gcGFyYW1zIHJlY2VpdmVkIHdoZW4gY2FsbGluZyB0aGUgam9iXG4gICAgXCJmaW5pc2hlZEF0XCI6IHt0eXBlOiAnRGF0ZSd9XG4gIH0sXG4gIF9Kb2JTY2hlZHVsZToge1xuICAgIFwiam9iTmFtZVwiOiAgICAgIHt0eXBlOidTdHJpbmcnfSxcbiAgICBcImRlc2NyaXB0aW9uXCI6ICB7dHlwZTonU3RyaW5nJ30sXG4gICAgXCJwYXJhbXNcIjogICAgICAge3R5cGU6J1N0cmluZyd9LFxuICAgIFwic3RhcnRBZnRlclwiOiAgIHt0eXBlOidTdHJpbmcnfSxcbiAgICBcImRheXNPZldlZWtcIjogICB7dHlwZTonQXJyYXknfSxcbiAgICBcInRpbWVPZkRheVwiOiAgICB7dHlwZTonU3RyaW5nJ30sXG4gICAgXCJsYXN0UnVuXCI6ICAgICAge3R5cGU6J051bWJlcid9LFxuICAgIFwicmVwZWF0TWludXRlc1wiOnt0eXBlOidOdW1iZXInfVxuICB9LFxuICBfSG9va3M6IHtcbiAgICBcImZ1bmN0aW9uTmFtZVwiOiB7dHlwZTonU3RyaW5nJ30sXG4gICAgXCJjbGFzc05hbWVcIjogICAge3R5cGU6J1N0cmluZyd9LFxuICAgIFwidHJpZ2dlck5hbWVcIjogIHt0eXBlOidTdHJpbmcnfSxcbiAgICBcInVybFwiOiAgICAgICAgICB7dHlwZTonU3RyaW5nJ31cbiAgfSxcbiAgX0dsb2JhbENvbmZpZzoge1xuICAgIFwib2JqZWN0SWRcIjoge3R5cGU6ICdTdHJpbmcnfSxcbiAgICBcInBhcmFtc1wiOiAgIHt0eXBlOiAnT2JqZWN0J31cbiAgfSxcbiAgX0F1ZGllbmNlOiB7XG4gICAgXCJvYmplY3RJZFwiOiAge3R5cGU6J1N0cmluZyd9LFxuICAgIFwibmFtZVwiOiAgICAgIHt0eXBlOidTdHJpbmcnfSxcbiAgICBcInF1ZXJ5XCI6ICAgICB7dHlwZTonU3RyaW5nJ30sIC8vc3RvcmluZyBxdWVyeSBhcyBKU09OIHN0cmluZyB0byBwcmV2ZW50IFwiTmVzdGVkIGtleXMgc2hvdWxkIG5vdCBjb250YWluIHRoZSAnJCcgb3IgJy4nIGNoYXJhY3RlcnNcIiBlcnJvclxuICAgIFwibGFzdFVzZWRcIjogIHt0eXBlOidEYXRlJ30sXG4gICAgXCJ0aW1lc1VzZWRcIjoge3R5cGU6J051bWJlcid9XG4gIH1cbn0pO1xuXG5jb25zdCByZXF1aXJlZENvbHVtbnMgPSBPYmplY3QuZnJlZXplKHtcbiAgX1Byb2R1Y3Q6IFtcInByb2R1Y3RJZGVudGlmaWVyXCIsIFwiaWNvblwiLCBcIm9yZGVyXCIsIFwidGl0bGVcIiwgXCJzdWJ0aXRsZVwiXSxcbiAgX1JvbGU6IFtcIm5hbWVcIiwgXCJBQ0xcIl1cbn0pO1xuXG5jb25zdCBzeXN0ZW1DbGFzc2VzID0gT2JqZWN0LmZyZWV6ZShbJ19Vc2VyJywgJ19JbnN0YWxsYXRpb24nLCAnX1JvbGUnLCAnX1Nlc3Npb24nLCAnX1Byb2R1Y3QnLCAnX1B1c2hTdGF0dXMnLCAnX0pvYlN0YXR1cycsICdfSm9iU2NoZWR1bGUnLCAnX0F1ZGllbmNlJ10pO1xuXG5jb25zdCB2b2xhdGlsZUNsYXNzZXMgPSBPYmplY3QuZnJlZXplKFsnX0pvYlN0YXR1cycsICdfUHVzaFN0YXR1cycsICdfSG9va3MnLCAnX0dsb2JhbENvbmZpZycsICdfSm9iU2NoZWR1bGUnLCAnX0F1ZGllbmNlJ10pO1xuXG4vLyAxMCBhbHBoYSBudW1iZXJpYyBjaGFycyArIHVwcGVyY2FzZVxuY29uc3QgdXNlcklkUmVnZXggPSAvXlthLXpBLVowLTldezEwfSQvO1xuLy8gQW55dGhpbmcgdGhhdCBzdGFydCB3aXRoIHJvbGVcbmNvbnN0IHJvbGVSZWdleCA9IC9ecm9sZTouKi87XG4vLyAqIHBlcm1pc3Npb25cbmNvbnN0IHB1YmxpY1JlZ2V4ID0gL15cXCokL1xuXG5jb25zdCByZXF1aXJlQXV0aGVudGljYXRpb25SZWdleCA9IC9ecmVxdWlyZXNBdXRoZW50aWNhdGlvbiQvXG5cbmNvbnN0IHBlcm1pc3Npb25LZXlSZWdleCA9IE9iamVjdC5mcmVlemUoW3VzZXJJZFJlZ2V4LCByb2xlUmVnZXgsIHB1YmxpY1JlZ2V4LCByZXF1aXJlQXV0aGVudGljYXRpb25SZWdleF0pO1xuXG5mdW5jdGlvbiB2ZXJpZnlQZXJtaXNzaW9uS2V5KGtleSkge1xuICBjb25zdCByZXN1bHQgPSBwZXJtaXNzaW9uS2V5UmVnZXgucmVkdWNlKChpc0dvb2QsIHJlZ0V4KSA9PiB7XG4gICAgaXNHb29kID0gaXNHb29kIHx8IGtleS5tYXRjaChyZWdFeCkgIT0gbnVsbDtcbiAgICByZXR1cm4gaXNHb29kO1xuICB9LCBmYWxzZSk7XG4gIGlmICghcmVzdWx0KSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgYCcke2tleX0nIGlzIG5vdCBhIHZhbGlkIGtleSBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnNgKTtcbiAgfVxufVxuXG5jb25zdCBDTFBWYWxpZEtleXMgPSBPYmplY3QuZnJlZXplKFsnZmluZCcsICdjb3VudCcsICdnZXQnLCAnY3JlYXRlJywgJ3VwZGF0ZScsICdkZWxldGUnLCAnYWRkRmllbGQnLCAncmVhZFVzZXJGaWVsZHMnLCAnd3JpdGVVc2VyRmllbGRzJ10pO1xuZnVuY3Rpb24gdmFsaWRhdGVDTFAocGVybXM6IENsYXNzTGV2ZWxQZXJtaXNzaW9ucywgZmllbGRzOiBTY2hlbWFGaWVsZHMpIHtcbiAgaWYgKCFwZXJtcykge1xuICAgIHJldHVybjtcbiAgfVxuICBPYmplY3Qua2V5cyhwZXJtcykuZm9yRWFjaCgob3BlcmF0aW9uKSA9PiB7XG4gICAgaWYgKENMUFZhbGlkS2V5cy5pbmRleE9mKG9wZXJhdGlvbikgPT0gLTEpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sIGAke29wZXJhdGlvbn0gaXMgbm90IGEgdmFsaWQgb3BlcmF0aW9uIGZvciBjbGFzcyBsZXZlbCBwZXJtaXNzaW9uc2ApO1xuICAgIH1cbiAgICBpZiAoIXBlcm1zW29wZXJhdGlvbl0pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAob3BlcmF0aW9uID09PSAncmVhZFVzZXJGaWVsZHMnIHx8IG9wZXJhdGlvbiA9PT0gJ3dyaXRlVXNlckZpZWxkcycpIHtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShwZXJtc1tvcGVyYXRpb25dKSkge1xuICAgICAgICAvLyBAZmxvdy1kaXNhYmxlLW5leHRcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgYCcke3Blcm1zW29wZXJhdGlvbl19JyBpcyBub3QgYSB2YWxpZCB2YWx1ZSBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnMgJHtvcGVyYXRpb259YCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwZXJtc1tvcGVyYXRpb25dLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgICAgIGlmICghZmllbGRzW2tleV0gfHwgZmllbGRzW2tleV0udHlwZSAhPSAnUG9pbnRlcicgfHwgZmllbGRzW2tleV0udGFyZ2V0Q2xhc3MgIT0gJ19Vc2VyJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgYCcke2tleX0nIGlzIG5vdCBhIHZhbGlkIGNvbHVtbiBmb3IgY2xhc3MgbGV2ZWwgcG9pbnRlciBwZXJtaXNzaW9ucyAke29wZXJhdGlvbn1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEBmbG93LWRpc2FibGUtbmV4dFxuICAgIE9iamVjdC5rZXlzKHBlcm1zW29wZXJhdGlvbl0pLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgdmVyaWZ5UGVybWlzc2lvbktleShrZXkpO1xuICAgICAgLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG4gICAgICBjb25zdCBwZXJtID0gcGVybXNbb3BlcmF0aW9uXVtrZXldO1xuICAgICAgaWYgKHBlcm0gIT09IHRydWUpIHtcbiAgICAgICAgLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sIGAnJHtwZXJtfScgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yIGNsYXNzIGxldmVsIHBlcm1pc3Npb25zICR7b3BlcmF0aW9ufToke2tleX06JHtwZXJtfWApO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn1cbmNvbnN0IGpvaW5DbGFzc1JlZ2V4ID0gL15fSm9pbjpbQS1aYS16MC05X10rOltBLVphLXowLTlfXSsvO1xuY29uc3QgY2xhc3NBbmRGaWVsZFJlZ2V4ID0gL15bQS1aYS16XVtBLVphLXowLTlfXSokLztcbmZ1bmN0aW9uIGNsYXNzTmFtZUlzVmFsaWQoY2xhc3NOYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgLy8gVmFsaWQgY2xhc3NlcyBtdXN0OlxuICByZXR1cm4gKFxuICAgIC8vIEJlIG9uZSBvZiBfVXNlciwgX0luc3RhbGxhdGlvbiwgX1JvbGUsIF9TZXNzaW9uIE9SXG4gICAgc3lzdGVtQ2xhc3Nlcy5pbmRleE9mKGNsYXNzTmFtZSkgPiAtMSB8fFxuICAgIC8vIEJlIGEgam9pbiB0YWJsZSBPUlxuICAgIGpvaW5DbGFzc1JlZ2V4LnRlc3QoY2xhc3NOYW1lKSB8fFxuICAgIC8vIEluY2x1ZGUgb25seSBhbHBoYS1udW1lcmljIGFuZCB1bmRlcnNjb3JlcywgYW5kIG5vdCBzdGFydCB3aXRoIGFuIHVuZGVyc2NvcmUgb3IgbnVtYmVyXG4gICAgZmllbGROYW1lSXNWYWxpZChjbGFzc05hbWUpXG4gICk7XG59XG5cbi8vIFZhbGlkIGZpZWxkcyBtdXN0IGJlIGFscGhhLW51bWVyaWMsIGFuZCBub3Qgc3RhcnQgd2l0aCBhbiB1bmRlcnNjb3JlIG9yIG51bWJlclxuZnVuY3Rpb24gZmllbGROYW1lSXNWYWxpZChmaWVsZE5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gY2xhc3NBbmRGaWVsZFJlZ2V4LnRlc3QoZmllbGROYW1lKTtcbn1cblxuLy8gQ2hlY2tzIHRoYXQgaXQncyBub3QgdHJ5aW5nIHRvIGNsb2JiZXIgb25lIG9mIHRoZSBkZWZhdWx0IGZpZWxkcyBvZiB0aGUgY2xhc3MuXG5mdW5jdGlvbiBmaWVsZE5hbWVJc1ZhbGlkRm9yQ2xhc3MoZmllbGROYW1lOiBzdHJpbmcsIGNsYXNzTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmICghZmllbGROYW1lSXNWYWxpZChmaWVsZE5hbWUpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChkZWZhdWx0Q29sdW1ucy5fRGVmYXVsdFtmaWVsZE5hbWVdKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChkZWZhdWx0Q29sdW1uc1tjbGFzc05hbWVdICYmIGRlZmF1bHRDb2x1bW5zW2NsYXNzTmFtZV1bZmllbGROYW1lXSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gaW52YWxpZENsYXNzTmFtZU1lc3NhZ2UoY2xhc3NOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gJ0ludmFsaWQgY2xhc3NuYW1lOiAnICsgY2xhc3NOYW1lICsgJywgY2xhc3NuYW1lcyBjYW4gb25seSBoYXZlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIGFuZCBfLCBhbmQgbXVzdCBzdGFydCB3aXRoIGFuIGFscGhhIGNoYXJhY3RlciAnO1xufVxuXG5jb25zdCBpbnZhbGlkSnNvbkVycm9yID0gbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgXCJpbnZhbGlkIEpTT05cIik7XG5jb25zdCB2YWxpZE5vblJlbGF0aW9uT3JQb2ludGVyVHlwZXMgPSBbXG4gICdOdW1iZXInLFxuICAnU3RyaW5nJyxcbiAgJ0Jvb2xlYW4nLFxuICAnRGF0ZScsXG4gICdPYmplY3QnLFxuICAnQXJyYXknLFxuICAnR2VvUG9pbnQnLFxuICAnRmlsZScsXG4gICdCeXRlcycsXG4gICdQb2x5Z29uJ1xuXTtcbi8vIFJldHVybnMgYW4gZXJyb3Igc3VpdGFibGUgZm9yIHRocm93aW5nIGlmIHRoZSB0eXBlIGlzIGludmFsaWRcbmNvbnN0IGZpZWxkVHlwZUlzSW52YWxpZCA9ICh7IHR5cGUsIHRhcmdldENsYXNzIH0pID0+IHtcbiAgaWYgKFsnUG9pbnRlcicsICdSZWxhdGlvbiddLmluZGV4T2YodHlwZSkgPj0gMCkge1xuICAgIGlmICghdGFyZ2V0Q2xhc3MpIHtcbiAgICAgIHJldHVybiBuZXcgUGFyc2UuRXJyb3IoMTM1LCBgdHlwZSAke3R5cGV9IG5lZWRzIGEgY2xhc3MgbmFtZWApO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHRhcmdldENsYXNzICE9PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIGludmFsaWRKc29uRXJyb3I7XG4gICAgfSBlbHNlIGlmICghY2xhc3NOYW1lSXNWYWxpZCh0YXJnZXRDbGFzcykpIHtcbiAgICAgIHJldHVybiBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLCBpbnZhbGlkQ2xhc3NOYW1lTWVzc2FnZSh0YXJnZXRDbGFzcykpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuICBpZiAodHlwZW9mIHR5cGUgIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGludmFsaWRKc29uRXJyb3I7XG4gIH1cbiAgaWYgKHZhbGlkTm9uUmVsYXRpb25PclBvaW50ZXJUeXBlcy5pbmRleE9mKHR5cGUpIDwgMCkge1xuICAgIHJldHVybiBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5DT1JSRUNUX1RZUEUsIGBpbnZhbGlkIGZpZWxkIHR5cGU6ICR7dHlwZX1gKTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5jb25zdCBjb252ZXJ0U2NoZW1hVG9BZGFwdGVyU2NoZW1hID0gKHNjaGVtYTogYW55KSA9PiB7XG4gIHNjaGVtYSA9IGluamVjdERlZmF1bHRTY2hlbWEoc2NoZW1hKTtcbiAgZGVsZXRlIHNjaGVtYS5maWVsZHMuQUNMO1xuICBzY2hlbWEuZmllbGRzLl9ycGVybSA9IHsgdHlwZTogJ0FycmF5JyB9O1xuICBzY2hlbWEuZmllbGRzLl93cGVybSA9IHsgdHlwZTogJ0FycmF5JyB9O1xuXG4gIGlmIChzY2hlbWEuY2xhc3NOYW1lID09PSAnX1VzZXInKSB7XG4gICAgZGVsZXRlIHNjaGVtYS5maWVsZHMucGFzc3dvcmQ7XG4gICAgc2NoZW1hLmZpZWxkcy5faGFzaGVkX3Bhc3N3b3JkID0geyB0eXBlOiAnU3RyaW5nJyB9O1xuICB9XG5cbiAgcmV0dXJuIHNjaGVtYTtcbn1cblxuY29uc3QgY29udmVydEFkYXB0ZXJTY2hlbWFUb1BhcnNlU2NoZW1hID0gKHsuLi5zY2hlbWF9KSA9PiB7XG4gIGRlbGV0ZSBzY2hlbWEuZmllbGRzLl9ycGVybTtcbiAgZGVsZXRlIHNjaGVtYS5maWVsZHMuX3dwZXJtO1xuXG4gIHNjaGVtYS5maWVsZHMuQUNMID0geyB0eXBlOiAnQUNMJyB9O1xuXG4gIGlmIChzY2hlbWEuY2xhc3NOYW1lID09PSAnX1VzZXInKSB7XG4gICAgZGVsZXRlIHNjaGVtYS5maWVsZHMuYXV0aERhdGE7IC8vQXV0aCBkYXRhIGlzIGltcGxpY2l0XG4gICAgZGVsZXRlIHNjaGVtYS5maWVsZHMuX2hhc2hlZF9wYXNzd29yZDtcbiAgICBzY2hlbWEuZmllbGRzLnBhc3N3b3JkID0geyB0eXBlOiAnU3RyaW5nJyB9O1xuICB9XG5cbiAgaWYgKHNjaGVtYS5pbmRleGVzICYmIE9iamVjdC5rZXlzKHNjaGVtYS5pbmRleGVzKS5sZW5ndGggPT09IDApIHtcbiAgICBkZWxldGUgc2NoZW1hLmluZGV4ZXM7XG4gIH1cblxuICByZXR1cm4gc2NoZW1hO1xufVxuXG5jb25zdCBpbmplY3REZWZhdWx0U2NoZW1hID0gKHtjbGFzc05hbWUsIGZpZWxkcywgY2xhc3NMZXZlbFBlcm1pc3Npb25zLCBpbmRleGVzfTogU2NoZW1hKSA9PiB7XG4gIGNvbnN0IGRlZmF1bHRTY2hlbWE6IFNjaGVtYSA9IHtcbiAgICBjbGFzc05hbWUsXG4gICAgZmllbGRzOiB7XG4gICAgICAuLi5kZWZhdWx0Q29sdW1ucy5fRGVmYXVsdCxcbiAgICAgIC4uLihkZWZhdWx0Q29sdW1uc1tjbGFzc05hbWVdIHx8IHt9KSxcbiAgICAgIC4uLmZpZWxkcyxcbiAgICB9LFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgfTtcbiAgaWYgKGluZGV4ZXMgJiYgT2JqZWN0LmtleXMoaW5kZXhlcykubGVuZ3RoICE9PSAwKSB7XG4gICAgZGVmYXVsdFNjaGVtYS5pbmRleGVzID0gaW5kZXhlcztcbiAgfVxuICByZXR1cm4gZGVmYXVsdFNjaGVtYTtcbn07XG5cbmNvbnN0IF9Ib29rc1NjaGVtYSA9ICB7Y2xhc3NOYW1lOiBcIl9Ib29rc1wiLCBmaWVsZHM6IGRlZmF1bHRDb2x1bW5zLl9Ib29rc307XG5jb25zdCBfR2xvYmFsQ29uZmlnU2NoZW1hID0geyBjbGFzc05hbWU6IFwiX0dsb2JhbENvbmZpZ1wiLCBmaWVsZHM6IGRlZmF1bHRDb2x1bW5zLl9HbG9iYWxDb25maWcgfVxuY29uc3QgX1B1c2hTdGF0dXNTY2hlbWEgPSBjb252ZXJ0U2NoZW1hVG9BZGFwdGVyU2NoZW1hKGluamVjdERlZmF1bHRTY2hlbWEoe1xuICBjbGFzc05hbWU6IFwiX1B1c2hTdGF0dXNcIixcbiAgZmllbGRzOiB7fSxcbiAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiB7fVxufSkpO1xuY29uc3QgX0pvYlN0YXR1c1NjaGVtYSA9IGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEoaW5qZWN0RGVmYXVsdFNjaGVtYSh7XG4gIGNsYXNzTmFtZTogXCJfSm9iU3RhdHVzXCIsXG4gIGZpZWxkczoge30sXG4gIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczoge31cbn0pKTtcbmNvbnN0IF9Kb2JTY2hlZHVsZVNjaGVtYSA9IGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEoaW5qZWN0RGVmYXVsdFNjaGVtYSh7XG4gIGNsYXNzTmFtZTogXCJfSm9iU2NoZWR1bGVcIixcbiAgZmllbGRzOiB7fSxcbiAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiB7fVxufSkpO1xuY29uc3QgX0F1ZGllbmNlU2NoZW1hID0gY29udmVydFNjaGVtYVRvQWRhcHRlclNjaGVtYShpbmplY3REZWZhdWx0U2NoZW1hKHtcbiAgY2xhc3NOYW1lOiBcIl9BdWRpZW5jZVwiLFxuICBmaWVsZHM6IGRlZmF1bHRDb2x1bW5zLl9BdWRpZW5jZSxcbiAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiB7fVxufSkpO1xuY29uc3QgVm9sYXRpbGVDbGFzc2VzU2NoZW1hcyA9IFtfSG9va3NTY2hlbWEsIF9Kb2JTdGF0dXNTY2hlbWEsIF9Kb2JTY2hlZHVsZVNjaGVtYSwgX1B1c2hTdGF0dXNTY2hlbWEsIF9HbG9iYWxDb25maWdTY2hlbWEsIF9BdWRpZW5jZVNjaGVtYV07XG5cbmNvbnN0IGRiVHlwZU1hdGNoZXNPYmplY3RUeXBlID0gKGRiVHlwZTogU2NoZW1hRmllbGQgfCBzdHJpbmcsIG9iamVjdFR5cGU6IFNjaGVtYUZpZWxkKSA9PiB7XG4gIGlmIChkYlR5cGUudHlwZSAhPT0gb2JqZWN0VHlwZS50eXBlKSByZXR1cm4gZmFsc2U7XG4gIGlmIChkYlR5cGUudGFyZ2V0Q2xhc3MgIT09IG9iamVjdFR5cGUudGFyZ2V0Q2xhc3MpIHJldHVybiBmYWxzZTtcbiAgaWYgKGRiVHlwZSA9PT0gb2JqZWN0VHlwZS50eXBlKSByZXR1cm4gdHJ1ZTtcbiAgaWYgKGRiVHlwZS50eXBlID09PSBvYmplY3RUeXBlLnR5cGUpIHJldHVybiB0cnVlO1xuICByZXR1cm4gZmFsc2U7XG59XG5cbmNvbnN0IHR5cGVUb1N0cmluZyA9ICh0eXBlOiBTY2hlbWFGaWVsZCB8IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdHlwZTtcbiAgfVxuICBpZiAodHlwZS50YXJnZXRDbGFzcykge1xuICAgIHJldHVybiBgJHt0eXBlLnR5cGV9PCR7dHlwZS50YXJnZXRDbGFzc30+YDtcbiAgfVxuICByZXR1cm4gYCR7dHlwZS50eXBlfWA7XG59XG5cbi8vIFN0b3JlcyB0aGUgZW50aXJlIHNjaGVtYSBvZiB0aGUgYXBwIGluIGEgd2VpcmQgaHlicmlkIGZvcm1hdCBzb21ld2hlcmUgYmV0d2VlblxuLy8gdGhlIG1vbmdvIGZvcm1hdCBhbmQgdGhlIFBhcnNlIGZvcm1hdC4gU29vbiwgdGhpcyB3aWxsIGFsbCBiZSBQYXJzZSBmb3JtYXQuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTY2hlbWFDb250cm9sbGVyIHtcbiAgX2RiQWRhcHRlcjogU3RvcmFnZUFkYXB0ZXI7XG4gIGRhdGE6IGFueTtcbiAgcGVybXM6IGFueTtcbiAgaW5kZXhlczogYW55O1xuICBfY2FjaGU6IGFueTtcbiAgcmVsb2FkRGF0YVByb21pc2U6IFByb21pc2U8YW55PjtcblxuICBjb25zdHJ1Y3RvcihkYXRhYmFzZUFkYXB0ZXI6IFN0b3JhZ2VBZGFwdGVyLCBzY2hlbWFDYWNoZTogYW55KSB7XG4gICAgdGhpcy5fZGJBZGFwdGVyID0gZGF0YWJhc2VBZGFwdGVyO1xuICAgIHRoaXMuX2NhY2hlID0gc2NoZW1hQ2FjaGU7XG4gICAgLy8gdGhpcy5kYXRhW2NsYXNzTmFtZV1bZmllbGROYW1lXSB0ZWxscyB5b3UgdGhlIHR5cGUgb2YgdGhhdCBmaWVsZCwgaW4gbW9uZ28gZm9ybWF0XG4gICAgdGhpcy5kYXRhID0ge307XG4gICAgLy8gdGhpcy5wZXJtc1tjbGFzc05hbWVdW29wZXJhdGlvbl0gdGVsbHMgeW91IHRoZSBhY2wtc3R5bGUgcGVybWlzc2lvbnNcbiAgICB0aGlzLnBlcm1zID0ge307XG4gICAgLy8gdGhpcy5pbmRleGVzW2NsYXNzTmFtZV1bb3BlcmF0aW9uXSB0ZWxscyB5b3UgdGhlIGluZGV4ZXNcbiAgICB0aGlzLmluZGV4ZXMgPSB7fTtcbiAgfVxuXG4gIHJlbG9hZERhdGEob3B0aW9uczogTG9hZFNjaGVtYU9wdGlvbnMgPSB7Y2xlYXJDYWNoZTogZmFsc2V9KTogUHJvbWlzZTxhbnk+IHtcbiAgICBsZXQgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIGlmIChvcHRpb25zLmNsZWFyQ2FjaGUpIHtcbiAgICAgIHByb21pc2UgPSBwcm9taXNlLnRoZW4oKCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2FjaGUuY2xlYXIoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAodGhpcy5yZWxvYWREYXRhUHJvbWlzZSAmJiAhb3B0aW9ucy5jbGVhckNhY2hlKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZWxvYWREYXRhUHJvbWlzZTtcbiAgICB9XG4gICAgdGhpcy5yZWxvYWREYXRhUHJvbWlzZSA9IHByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRBbGxDbGFzc2VzKG9wdGlvbnMpLnRoZW4oKGFsbFNjaGVtYXMpID0+IHtcbiAgICAgICAgY29uc3QgZGF0YSA9IHt9O1xuICAgICAgICBjb25zdCBwZXJtcyA9IHt9O1xuICAgICAgICBjb25zdCBpbmRleGVzID0ge307XG4gICAgICAgIGFsbFNjaGVtYXMuZm9yRWFjaChzY2hlbWEgPT4ge1xuICAgICAgICAgIGRhdGFbc2NoZW1hLmNsYXNzTmFtZV0gPSBpbmplY3REZWZhdWx0U2NoZW1hKHNjaGVtYSkuZmllbGRzO1xuICAgICAgICAgIHBlcm1zW3NjaGVtYS5jbGFzc05hbWVdID0gc2NoZW1hLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucztcbiAgICAgICAgICBpbmRleGVzW3NjaGVtYS5jbGFzc05hbWVdID0gc2NoZW1hLmluZGV4ZXM7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEluamVjdCB0aGUgaW4tbWVtb3J5IGNsYXNzZXNcbiAgICAgICAgdm9sYXRpbGVDbGFzc2VzLmZvckVhY2goY2xhc3NOYW1lID0+IHtcbiAgICAgICAgICBjb25zdCBzY2hlbWEgPSBpbmplY3REZWZhdWx0U2NoZW1hKHsgY2xhc3NOYW1lLCBmaWVsZHM6IHt9LCBjbGFzc0xldmVsUGVybWlzc2lvbnM6IHt9IH0pO1xuICAgICAgICAgIGRhdGFbY2xhc3NOYW1lXSA9IHNjaGVtYS5maWVsZHM7XG4gICAgICAgICAgcGVybXNbY2xhc3NOYW1lXSA9IHNjaGVtYS5jbGFzc0xldmVsUGVybWlzc2lvbnM7XG4gICAgICAgICAgaW5kZXhlc1tjbGFzc05hbWVdID0gc2NoZW1hLmluZGV4ZXM7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgICAgICB0aGlzLnBlcm1zID0gcGVybXM7XG4gICAgICAgIHRoaXMuaW5kZXhlcyA9IGluZGV4ZXM7XG4gICAgICAgIGRlbGV0ZSB0aGlzLnJlbG9hZERhdGFQcm9taXNlO1xuICAgICAgfSwgKGVycikgPT4ge1xuICAgICAgICB0aGlzLmRhdGEgPSB7fTtcbiAgICAgICAgdGhpcy5wZXJtcyA9IHt9O1xuICAgICAgICB0aGlzLmluZGV4ZXMgPSB7fTtcbiAgICAgICAgZGVsZXRlIHRoaXMucmVsb2FkRGF0YVByb21pc2U7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH0pXG4gICAgfSkudGhlbigoKSA9PiB7fSk7XG4gICAgcmV0dXJuIHRoaXMucmVsb2FkRGF0YVByb21pc2U7XG4gIH1cblxuICBnZXRBbGxDbGFzc2VzKG9wdGlvbnM6IExvYWRTY2hlbWFPcHRpb25zID0ge2NsZWFyQ2FjaGU6IGZhbHNlfSk6IFByb21pc2U8QXJyYXk8U2NoZW1hPj4ge1xuICAgIGxldCBwcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgaWYgKG9wdGlvbnMuY2xlYXJDYWNoZSkge1xuICAgICAgcHJvbWlzZSA9IHRoaXMuX2NhY2hlLmNsZWFyKCk7XG4gICAgfVxuICAgIHJldHVybiBwcm9taXNlLnRoZW4oKCkgPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlLmdldEFsbENsYXNzZXMoKVxuICAgIH0pLnRoZW4oKGFsbENsYXNzZXMpID0+IHtcbiAgICAgIGlmIChhbGxDbGFzc2VzICYmIGFsbENsYXNzZXMubGVuZ3RoICYmICFvcHRpb25zLmNsZWFyQ2FjaGUpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShhbGxDbGFzc2VzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLl9kYkFkYXB0ZXIuZ2V0QWxsQ2xhc3NlcygpXG4gICAgICAgIC50aGVuKGFsbFNjaGVtYXMgPT4gYWxsU2NoZW1hcy5tYXAoaW5qZWN0RGVmYXVsdFNjaGVtYSkpXG4gICAgICAgIC50aGVuKGFsbFNjaGVtYXMgPT4ge1xuICAgICAgICAgIHJldHVybiB0aGlzLl9jYWNoZS5zZXRBbGxDbGFzc2VzKGFsbFNjaGVtYXMpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGFsbFNjaGVtYXM7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgfSk7XG4gIH1cblxuICBnZXRPbmVTY2hlbWEoY2xhc3NOYW1lOiBzdHJpbmcsIGFsbG93Vm9sYXRpbGVDbGFzc2VzOiBib29sZWFuID0gZmFsc2UsIG9wdGlvbnM6IExvYWRTY2hlbWFPcHRpb25zID0ge2NsZWFyQ2FjaGU6IGZhbHNlfSk6IFByb21pc2U8U2NoZW1hPiB7XG4gICAgbGV0IHByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgICBpZiAob3B0aW9ucy5jbGVhckNhY2hlKSB7XG4gICAgICBwcm9taXNlID0gdGhpcy5fY2FjaGUuY2xlYXIoKTtcbiAgICB9XG4gICAgcmV0dXJuIHByb21pc2UudGhlbigoKSA9PiB7XG4gICAgICBpZiAoYWxsb3dWb2xhdGlsZUNsYXNzZXMgJiYgdm9sYXRpbGVDbGFzc2VzLmluZGV4T2YoY2xhc3NOYW1lKSA+IC0xKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICBmaWVsZHM6IHRoaXMuZGF0YVtjbGFzc05hbWVdLFxuICAgICAgICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogdGhpcy5wZXJtc1tjbGFzc05hbWVdLFxuICAgICAgICAgIGluZGV4ZXM6IHRoaXMuaW5kZXhlc1tjbGFzc05hbWVdXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlLmdldE9uZVNjaGVtYShjbGFzc05hbWUpLnRoZW4oKGNhY2hlZCkgPT4ge1xuICAgICAgICBpZiAoY2FjaGVkICYmICFvcHRpb25zLmNsZWFyQ2FjaGUpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGNhY2hlZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX2RiQWRhcHRlci5nZXRDbGFzcyhjbGFzc05hbWUpXG4gICAgICAgICAgLnRoZW4oaW5qZWN0RGVmYXVsdFNjaGVtYSlcbiAgICAgICAgICAudGhlbigocmVzdWx0KSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY2FjaGUuc2V0T25lU2NoZW1hKGNsYXNzTmFtZSwgcmVzdWx0KS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIENyZWF0ZSBhIG5ldyBjbGFzcyB0aGF0IGluY2x1ZGVzIHRoZSB0aHJlZSBkZWZhdWx0IGZpZWxkcy5cbiAgLy8gQUNMIGlzIGFuIGltcGxpY2l0IGNvbHVtbiB0aGF0IGRvZXMgbm90IGdldCBhbiBlbnRyeSBpbiB0aGVcbiAgLy8gX1NDSEVNQVMgZGF0YWJhc2UuIFJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGVcbiAgLy8gY3JlYXRlZCBzY2hlbWEsIGluIG1vbmdvIGZvcm1hdC5cbiAgLy8gb24gc3VjY2VzcywgYW5kIHJlamVjdHMgd2l0aCBhbiBlcnJvciBvbiBmYWlsLiBFbnN1cmUgeW91XG4gIC8vIGhhdmUgYXV0aG9yaXphdGlvbiAobWFzdGVyIGtleSwgb3IgY2xpZW50IGNsYXNzIGNyZWF0aW9uXG4gIC8vIGVuYWJsZWQpIGJlZm9yZSBjYWxsaW5nIHRoaXMgZnVuY3Rpb24uXG4gIGFkZENsYXNzSWZOb3RFeGlzdHMoY2xhc3NOYW1lOiBzdHJpbmcsIGZpZWxkczogU2NoZW1hRmllbGRzID0ge30sIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogYW55LCBpbmRleGVzOiBhbnkgPSB7fSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHZhciB2YWxpZGF0aW9uRXJyb3IgPSB0aGlzLnZhbGlkYXRlTmV3Q2xhc3MoY2xhc3NOYW1lLCBmaWVsZHMsIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyk7XG4gICAgaWYgKHZhbGlkYXRpb25FcnJvcikge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHZhbGlkYXRpb25FcnJvcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2RiQWRhcHRlci5jcmVhdGVDbGFzcyhjbGFzc05hbWUsIGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEoeyBmaWVsZHMsIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgaW5kZXhlcywgY2xhc3NOYW1lIH0pKVxuICAgICAgLnRoZW4oY29udmVydEFkYXB0ZXJTY2hlbWFUb1BhcnNlU2NoZW1hKVxuICAgICAgLnRoZW4oKHJlcykgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2FjaGUuY2xlYXIoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlcyk7XG4gICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvciAmJiBlcnJvci5jb2RlID09PSBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLCBgQ2xhc3MgJHtjbGFzc05hbWV9IGFscmVhZHkgZXhpc3RzLmApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIHVwZGF0ZUNsYXNzKGNsYXNzTmFtZTogc3RyaW5nLCBzdWJtaXR0ZWRGaWVsZHM6IFNjaGVtYUZpZWxkcywgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiBhbnksIGluZGV4ZXM6IGFueSwgZGF0YWJhc2U6IERhdGFiYXNlQ29udHJvbGxlcikge1xuICAgIHJldHVybiB0aGlzLmdldE9uZVNjaGVtYShjbGFzc05hbWUpXG4gICAgICAudGhlbihzY2hlbWEgPT4ge1xuICAgICAgICBjb25zdCBleGlzdGluZ0ZpZWxkcyA9IHNjaGVtYS5maWVsZHM7XG4gICAgICAgIE9iamVjdC5rZXlzKHN1Ym1pdHRlZEZpZWxkcykuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgICAgICBjb25zdCBmaWVsZCA9IHN1Ym1pdHRlZEZpZWxkc1tuYW1lXTtcbiAgICAgICAgICBpZiAoZXhpc3RpbmdGaWVsZHNbbmFtZV0gJiYgZmllbGQuX19vcCAhPT0gJ0RlbGV0ZScpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigyNTUsIGBGaWVsZCAke25hbWV9IGV4aXN0cywgY2Fubm90IHVwZGF0ZS5gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFleGlzdGluZ0ZpZWxkc1tuYW1lXSAmJiBmaWVsZC5fX29wID09PSAnRGVsZXRlJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDI1NSwgYEZpZWxkICR7bmFtZX0gZG9lcyBub3QgZXhpc3QsIGNhbm5vdCBkZWxldGUuYCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBkZWxldGUgZXhpc3RpbmdGaWVsZHMuX3JwZXJtO1xuICAgICAgICBkZWxldGUgZXhpc3RpbmdGaWVsZHMuX3dwZXJtO1xuICAgICAgICBjb25zdCBuZXdTY2hlbWEgPSBidWlsZE1lcmdlZFNjaGVtYU9iamVjdChleGlzdGluZ0ZpZWxkcywgc3VibWl0dGVkRmllbGRzKTtcbiAgICAgICAgY29uc3QgZGVmYXVsdEZpZWxkcyA9IGRlZmF1bHRDb2x1bW5zW2NsYXNzTmFtZV0gfHwgZGVmYXVsdENvbHVtbnMuX0RlZmF1bHQ7XG4gICAgICAgIGNvbnN0IGZ1bGxOZXdTY2hlbWEgPSBPYmplY3QuYXNzaWduKHt9LCBuZXdTY2hlbWEsIGRlZmF1bHRGaWVsZHMpO1xuICAgICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3IgPSB0aGlzLnZhbGlkYXRlU2NoZW1hRGF0YShjbGFzc05hbWUsIG5ld1NjaGVtYSwgY2xhc3NMZXZlbFBlcm1pc3Npb25zLCBPYmplY3Qua2V5cyhleGlzdGluZ0ZpZWxkcykpO1xuICAgICAgICBpZiAodmFsaWRhdGlvbkVycm9yKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKHZhbGlkYXRpb25FcnJvci5jb2RlLCB2YWxpZGF0aW9uRXJyb3IuZXJyb3IpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRmluYWxseSB3ZSBoYXZlIGNoZWNrZWQgdG8gbWFrZSBzdXJlIHRoZSByZXF1ZXN0IGlzIHZhbGlkIGFuZCB3ZSBjYW4gc3RhcnQgZGVsZXRpbmcgZmllbGRzLlxuICAgICAgICAvLyBEbyBhbGwgZGVsZXRpb25zIGZpcnN0LCB0aGVuIGEgc2luZ2xlIHNhdmUgdG8gX1NDSEVNQSBjb2xsZWN0aW9uIHRvIGhhbmRsZSBhbGwgYWRkaXRpb25zLlxuICAgICAgICBjb25zdCBkZWxldGVkRmllbGRzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICBjb25zdCBpbnNlcnRlZEZpZWxkcyA9IFtdO1xuICAgICAgICBPYmplY3Qua2V5cyhzdWJtaXR0ZWRGaWVsZHMpLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgICAgICBpZiAoc3VibWl0dGVkRmllbGRzW2ZpZWxkTmFtZV0uX19vcCA9PT0gJ0RlbGV0ZScpIHtcbiAgICAgICAgICAgIGRlbGV0ZWRGaWVsZHMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpbnNlcnRlZEZpZWxkcy5wdXNoKGZpZWxkTmFtZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBsZXQgZGVsZXRlUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICBpZiAoZGVsZXRlZEZpZWxkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgZGVsZXRlUHJvbWlzZSA9IHRoaXMuZGVsZXRlRmllbGRzKGRlbGV0ZWRGaWVsZHMsIGNsYXNzTmFtZSwgZGF0YWJhc2UpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkZWxldGVQcm9taXNlIC8vIERlbGV0ZSBFdmVyeXRoaW5nXG4gICAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5yZWxvYWREYXRhKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KSkgLy8gUmVsb2FkIG91ciBTY2hlbWEsIHNvIHdlIGhhdmUgYWxsIHRoZSBuZXcgdmFsdWVzXG4gICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcHJvbWlzZXMgPSBpbnNlcnRlZEZpZWxkcy5tYXAoZmllbGROYW1lID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgdHlwZSA9IHN1Ym1pdHRlZEZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbmZvcmNlRmllbGRFeGlzdHMoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHR5cGUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5zZXRQZXJtaXNzaW9ucyhjbGFzc05hbWUsIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgbmV3U2NoZW1hKSlcbiAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLl9kYkFkYXB0ZXIuc2V0SW5kZXhlc1dpdGhTY2hlbWFGb3JtYXQoY2xhc3NOYW1lLCBpbmRleGVzLCBzY2hlbWEuaW5kZXhlcywgZnVsbE5ld1NjaGVtYSkpXG4gICAgICAgICAgLnRoZW4oKCkgPT4gdGhpcy5yZWxvYWREYXRhKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KSlcbiAgICAgICAgLy9UT0RPOiBNb3ZlIHRoaXMgbG9naWMgaW50byB0aGUgZGF0YWJhc2UgYWRhcHRlclxuICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlbG9hZGVkU2NoZW1hOiBTY2hlbWEgPSB7XG4gICAgICAgICAgICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lLFxuICAgICAgICAgICAgICBmaWVsZHM6IHRoaXMuZGF0YVtjbGFzc05hbWVdLFxuICAgICAgICAgICAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IHRoaXMucGVybXNbY2xhc3NOYW1lXSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBpZiAodGhpcy5pbmRleGVzW2NsYXNzTmFtZV0gJiYgT2JqZWN0LmtleXModGhpcy5pbmRleGVzW2NsYXNzTmFtZV0pLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgICByZWxvYWRlZFNjaGVtYS5pbmRleGVzID0gdGhpcy5pbmRleGVzW2NsYXNzTmFtZV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVsb2FkZWRTY2hlbWE7XG4gICAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLCBgQ2xhc3MgJHtjbGFzc05hbWV9IGRvZXMgbm90IGV4aXN0LmApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9KVxuICB9XG5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyBzdWNjZXNzZnVsbHkgdG8gdGhlIG5ldyBzY2hlbWFcbiAgLy8gb2JqZWN0IG9yIGZhaWxzIHdpdGggYSByZWFzb24uXG4gIGVuZm9yY2VDbGFzc0V4aXN0cyhjbGFzc05hbWU6IHN0cmluZyk6IFByb21pc2U8U2NoZW1hQ29udHJvbGxlcj4ge1xuICAgIGlmICh0aGlzLmRhdGFbY2xhc3NOYW1lXSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzKTtcbiAgICB9XG4gICAgLy8gV2UgZG9uJ3QgaGF2ZSB0aGlzIGNsYXNzLiBVcGRhdGUgdGhlIHNjaGVtYVxuICAgIHJldHVybiB0aGlzLmFkZENsYXNzSWZOb3RFeGlzdHMoY2xhc3NOYW1lKVxuICAgIC8vIFRoZSBzY2hlbWEgdXBkYXRlIHN1Y2NlZWRlZC4gUmVsb2FkIHRoZSBzY2hlbWFcbiAgICAgIC50aGVuKCgpID0+IHRoaXMucmVsb2FkRGF0YSh7IGNsZWFyQ2FjaGU6IHRydWUgfSkpXG4gICAgICAuY2F0Y2goKCkgPT4ge1xuICAgICAgLy8gVGhlIHNjaGVtYSB1cGRhdGUgZmFpbGVkLiBUaGlzIGNhbiBiZSBva2F5IC0gaXQgbWlnaHRcbiAgICAgIC8vIGhhdmUgZmFpbGVkIGJlY2F1c2UgdGhlcmUncyBhIHJhY2UgY29uZGl0aW9uIGFuZCBhIGRpZmZlcmVudFxuICAgICAgLy8gY2xpZW50IGlzIG1ha2luZyB0aGUgZXhhY3Qgc2FtZSBzY2hlbWEgdXBkYXRlIHRoYXQgd2Ugd2FudC5cbiAgICAgIC8vIFNvIGp1c3QgcmVsb2FkIHRoZSBzY2hlbWEuXG4gICAgICAgIHJldHVybiB0aGlzLnJlbG9hZERhdGEoeyBjbGVhckNhY2hlOiB0cnVlIH0pO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgIC8vIEVuc3VyZSB0aGF0IHRoZSBzY2hlbWEgbm93IHZhbGlkYXRlc1xuICAgICAgICBpZiAodGhpcy5kYXRhW2NsYXNzTmFtZV0pIHtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCBgRmFpbGVkIHRvIGFkZCAke2NsYXNzTmFtZX1gKTtcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAvLyBUaGUgc2NoZW1hIHN0aWxsIGRvZXNuJ3QgdmFsaWRhdGUuIEdpdmUgdXBcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ3NjaGVtYSBjbGFzcyBuYW1lIGRvZXMgbm90IHJldmFsaWRhdGUnKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgdmFsaWRhdGVOZXdDbGFzcyhjbGFzc05hbWU6IHN0cmluZywgZmllbGRzOiBTY2hlbWFGaWVsZHMgPSB7fSwgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiBhbnkpOiBhbnkge1xuICAgIGlmICh0aGlzLmRhdGFbY2xhc3NOYW1lXSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSwgYENsYXNzICR7Y2xhc3NOYW1lfSBhbHJlYWR5IGV4aXN0cy5gKTtcbiAgICB9XG4gICAgaWYgKCFjbGFzc05hbWVJc1ZhbGlkKGNsYXNzTmFtZSkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSxcbiAgICAgICAgZXJyb3I6IGludmFsaWRDbGFzc05hbWVNZXNzYWdlKGNsYXNzTmFtZSksXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy52YWxpZGF0ZVNjaGVtYURhdGEoY2xhc3NOYW1lLCBmaWVsZHMsIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgW10pO1xuICB9XG5cbiAgdmFsaWRhdGVTY2hlbWFEYXRhKGNsYXNzTmFtZTogc3RyaW5nLCBmaWVsZHM6IFNjaGVtYUZpZWxkcywgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiBDbGFzc0xldmVsUGVybWlzc2lvbnMsIGV4aXN0aW5nRmllbGROYW1lczogQXJyYXk8c3RyaW5nPikge1xuICAgIGZvciAoY29uc3QgZmllbGROYW1lIGluIGZpZWxkcykge1xuICAgICAgaWYgKGV4aXN0aW5nRmllbGROYW1lcy5pbmRleE9mKGZpZWxkTmFtZSkgPCAwKSB7XG4gICAgICAgIGlmICghZmllbGROYW1lSXNWYWxpZChmaWVsZE5hbWUpKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUsXG4gICAgICAgICAgICBlcnJvcjogJ2ludmFsaWQgZmllbGQgbmFtZTogJyArIGZpZWxkTmFtZSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmICghZmllbGROYW1lSXNWYWxpZEZvckNsYXNzKGZpZWxkTmFtZSwgY2xhc3NOYW1lKSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb2RlOiAxMzYsXG4gICAgICAgICAgICBlcnJvcjogJ2ZpZWxkICcgKyBmaWVsZE5hbWUgKyAnIGNhbm5vdCBiZSBhZGRlZCcsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBlcnJvciA9IGZpZWxkVHlwZUlzSW52YWxpZChmaWVsZHNbZmllbGROYW1lXSk7XG4gICAgICAgIGlmIChlcnJvcikgcmV0dXJuIHsgY29kZTogZXJyb3IuY29kZSwgZXJyb3I6IGVycm9yLm1lc3NhZ2UgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBpbiBkZWZhdWx0Q29sdW1uc1tjbGFzc05hbWVdKSB7XG4gICAgICBmaWVsZHNbZmllbGROYW1lXSA9IGRlZmF1bHRDb2x1bW5zW2NsYXNzTmFtZV1bZmllbGROYW1lXTtcbiAgICB9XG5cbiAgICBjb25zdCBnZW9Qb2ludHMgPSBPYmplY3Qua2V5cyhmaWVsZHMpLmZpbHRlcihrZXkgPT4gZmllbGRzW2tleV0gJiYgZmllbGRzW2tleV0udHlwZSA9PT0gJ0dlb1BvaW50Jyk7XG4gICAgaWYgKGdlb1BvaW50cy5sZW5ndGggPiAxKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb2RlOiBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSxcbiAgICAgICAgZXJyb3I6ICdjdXJyZW50bHksIG9ubHkgb25lIEdlb1BvaW50IGZpZWxkIG1heSBleGlzdCBpbiBhbiBvYmplY3QuIEFkZGluZyAnICsgZ2VvUG9pbnRzWzFdICsgJyB3aGVuICcgKyBnZW9Qb2ludHNbMF0gKyAnIGFscmVhZHkgZXhpc3RzLicsXG4gICAgICB9O1xuICAgIH1cbiAgICB2YWxpZGF0ZUNMUChjbGFzc0xldmVsUGVybWlzc2lvbnMsIGZpZWxkcyk7XG4gIH1cblxuICAvLyBTZXRzIHRoZSBDbGFzcy1sZXZlbCBwZXJtaXNzaW9ucyBmb3IgYSBnaXZlbiBjbGFzc05hbWUsIHdoaWNoIG11c3QgZXhpc3QuXG4gIHNldFBlcm1pc3Npb25zKGNsYXNzTmFtZTogc3RyaW5nLCBwZXJtczogYW55LCBuZXdTY2hlbWE6IFNjaGVtYUZpZWxkcykge1xuICAgIGlmICh0eXBlb2YgcGVybXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuICAgIHZhbGlkYXRlQ0xQKHBlcm1zLCBuZXdTY2hlbWEpO1xuICAgIHJldHVybiB0aGlzLl9kYkFkYXB0ZXIuc2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zKGNsYXNzTmFtZSwgcGVybXMpO1xuICB9XG5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyBzdWNjZXNzZnVsbHkgdG8gdGhlIG5ldyBzY2hlbWFcbiAgLy8gb2JqZWN0IGlmIHRoZSBwcm92aWRlZCBjbGFzc05hbWUtZmllbGROYW1lLXR5cGUgdHVwbGUgaXMgdmFsaWQuXG4gIC8vIFRoZSBjbGFzc05hbWUgbXVzdCBhbHJlYWR5IGJlIHZhbGlkYXRlZC5cbiAgLy8gSWYgJ2ZyZWV6ZScgaXMgdHJ1ZSwgcmVmdXNlIHRvIHVwZGF0ZSB0aGUgc2NoZW1hIGZvciB0aGlzIGZpZWxkLlxuICBlbmZvcmNlRmllbGRFeGlzdHMoY2xhc3NOYW1lOiBzdHJpbmcsIGZpZWxkTmFtZTogc3RyaW5nLCB0eXBlOiBzdHJpbmcgfCBTY2hlbWFGaWVsZCkge1xuICAgIGlmIChmaWVsZE5hbWUuaW5kZXhPZihcIi5cIikgPiAwKSB7XG4gICAgICAvLyBzdWJkb2N1bWVudCBrZXkgKHgueSkgPT4gb2sgaWYgeCBpcyBvZiB0eXBlICdvYmplY3QnXG4gICAgICBmaWVsZE5hbWUgPSBmaWVsZE5hbWUuc3BsaXQoXCIuXCIpWyAwIF07XG4gICAgICB0eXBlID0gJ09iamVjdCc7XG4gICAgfVxuICAgIGlmICghZmllbGROYW1lSXNWYWxpZChmaWVsZE5hbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSwgYEludmFsaWQgZmllbGQgbmFtZTogJHtmaWVsZE5hbWV9LmApO1xuICAgIH1cblxuICAgIC8vIElmIHNvbWVvbmUgdHJpZXMgdG8gY3JlYXRlIGEgbmV3IGZpZWxkIHdpdGggbnVsbC91bmRlZmluZWQgYXMgdGhlIHZhbHVlLCByZXR1cm47XG4gICAgaWYgKCF0eXBlKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnJlbG9hZERhdGEoKS50aGVuKCgpID0+IHtcbiAgICAgIGNvbnN0IGV4cGVjdGVkVHlwZSA9IHRoaXMuZ2V0RXhwZWN0ZWRUeXBlKGNsYXNzTmFtZSwgZmllbGROYW1lKTtcbiAgICAgIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgdHlwZSA9IHsgdHlwZSB9O1xuICAgICAgfVxuXG4gICAgICBpZiAoZXhwZWN0ZWRUeXBlKSB7XG4gICAgICAgIGlmICghZGJUeXBlTWF0Y2hlc09iamVjdFR5cGUoZXhwZWN0ZWRUeXBlLCB0eXBlKSkge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgIFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLFxuICAgICAgICAgICAgYHNjaGVtYSBtaXNtYXRjaCBmb3IgJHtjbGFzc05hbWV9LiR7ZmllbGROYW1lfTsgZXhwZWN0ZWQgJHt0eXBlVG9TdHJpbmcoZXhwZWN0ZWRUeXBlKX0gYnV0IGdvdCAke3R5cGVUb1N0cmluZyh0eXBlKX1gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMuX2RiQWRhcHRlci5hZGRGaWVsZElmTm90RXhpc3RzKGNsYXNzTmFtZSwgZmllbGROYW1lLCB0eXBlKS50aGVuKCgpID0+IHtcbiAgICAgICAgLy8gVGhlIHVwZGF0ZSBzdWNjZWVkZWQuIFJlbG9hZCB0aGUgc2NoZW1hXG4gICAgICAgIHJldHVybiB0aGlzLnJlbG9hZERhdGEoeyBjbGVhckNhY2hlOiB0cnVlIH0pO1xuICAgICAgfSwgKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvci5jb2RlID09IFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFKSB7XG4gICAgICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgd2UgdGhyb3cgZXJyb3JzIHdoZW4gaXQgaXMgYXBwcm9wcmlhdGUgdG8gZG8gc28uXG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVGhlIHVwZGF0ZSBmYWlsZWQuIFRoaXMgY2FuIGJlIG9rYXkgLSBpdCBtaWdodCBoYXZlIGJlZW4gYSByYWNlXG4gICAgICAgIC8vIGNvbmRpdGlvbiB3aGVyZSBhbm90aGVyIGNsaWVudCB1cGRhdGVkIHRoZSBzY2hlbWEgaW4gdGhlIHNhbWVcbiAgICAgICAgLy8gd2F5IHRoYXQgd2Ugd2FudGVkIHRvLiBTbywganVzdCByZWxvYWQgdGhlIHNjaGVtYVxuICAgICAgICByZXR1cm4gdGhpcy5yZWxvYWREYXRhKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KTtcbiAgICAgIH0pLnRoZW4oKCkgPT4ge1xuICAgICAgICAvLyBFbnN1cmUgdGhhdCB0aGUgc2NoZW1hIG5vdyB2YWxpZGF0ZXNcbiAgICAgICAgY29uc3QgZXhwZWN0ZWRUeXBlID0gdGhpcy5nZXRFeHBlY3RlZFR5cGUoY2xhc3NOYW1lLCBmaWVsZE5hbWUpO1xuICAgICAgICBpZiAodHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdHlwZSA9IHsgdHlwZSB9O1xuICAgICAgICB9XG4gICAgICAgIGlmICghZXhwZWN0ZWRUeXBlIHx8ICFkYlR5cGVNYXRjaGVzT2JqZWN0VHlwZShleHBlY3RlZFR5cGUsIHR5cGUpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgYENvdWxkIG5vdCBhZGQgZmllbGQgJHtmaWVsZE5hbWV9YCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gUmVtb3ZlIHRoZSBjYWNoZWQgc2NoZW1hXG4gICAgICAgIHRoaXMuX2NhY2hlLmNsZWFyKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBtYWludGFpbiBjb21wYXRpYmlsaXR5XG4gIGRlbGV0ZUZpZWxkKGZpZWxkTmFtZTogc3RyaW5nLCBjbGFzc05hbWU6IHN0cmluZywgZGF0YWJhc2U6IERhdGFiYXNlQ29udHJvbGxlcikge1xuICAgIHJldHVybiB0aGlzLmRlbGV0ZUZpZWxkcyhbZmllbGROYW1lXSwgY2xhc3NOYW1lLCBkYXRhYmFzZSk7XG4gIH1cblxuICAvLyBEZWxldGUgZmllbGRzLCBhbmQgcmVtb3ZlIHRoYXQgZGF0YSBmcm9tIGFsbCBvYmplY3RzLiBUaGlzIGlzIGludGVuZGVkXG4gIC8vIHRvIHJlbW92ZSB1bnVzZWQgZmllbGRzLCBpZiBvdGhlciB3cml0ZXJzIGFyZSB3cml0aW5nIG9iamVjdHMgdGhhdCBpbmNsdWRlXG4gIC8vIHRoaXMgZmllbGQsIHRoZSBmaWVsZCBtYXkgcmVhcHBlYXIuIFJldHVybnMgYSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aFxuICAvLyBubyBvYmplY3Qgb24gc3VjY2Vzcywgb3IgcmVqZWN0cyB3aXRoIHsgY29kZSwgZXJyb3IgfSBvbiBmYWlsdXJlLlxuICAvLyBQYXNzaW5nIHRoZSBkYXRhYmFzZSBhbmQgcHJlZml4IGlzIG5lY2Vzc2FyeSBpbiBvcmRlciB0byBkcm9wIHJlbGF0aW9uIGNvbGxlY3Rpb25zXG4gIC8vIGFuZCByZW1vdmUgZmllbGRzIGZyb20gb2JqZWN0cy4gSWRlYWxseSB0aGUgZGF0YWJhc2Ugd291bGQgYmVsb25nIHRvXG4gIC8vIGEgZGF0YWJhc2UgYWRhcHRlciBhbmQgdGhpcyBmdW5jdGlvbiB3b3VsZCBjbG9zZSBvdmVyIGl0IG9yIGFjY2VzcyBpdCB2aWEgbWVtYmVyLlxuICBkZWxldGVGaWVsZHMoZmllbGROYW1lczogQXJyYXk8c3RyaW5nPiwgY2xhc3NOYW1lOiBzdHJpbmcsIGRhdGFiYXNlOiBEYXRhYmFzZUNvbnRyb2xsZXIpIHtcbiAgICBpZiAoIWNsYXNzTmFtZUlzVmFsaWQoY2xhc3NOYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSwgaW52YWxpZENsYXNzTmFtZU1lc3NhZ2UoY2xhc3NOYW1lKSk7XG4gICAgfVxuXG4gICAgZmllbGROYW1lcy5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICBpZiAoIWZpZWxkTmFtZUlzVmFsaWQoZmllbGROYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSwgYGludmFsaWQgZmllbGQgbmFtZTogJHtmaWVsZE5hbWV9YCk7XG4gICAgICB9XG4gICAgICAvL0Rvbid0IGFsbG93IGRlbGV0aW5nIHRoZSBkZWZhdWx0IGZpZWxkcy5cbiAgICAgIGlmICghZmllbGROYW1lSXNWYWxpZEZvckNsYXNzKGZpZWxkTmFtZSwgY2xhc3NOYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoMTM2LCBgZmllbGQgJHtmaWVsZE5hbWV9IGNhbm5vdCBiZSBjaGFuZ2VkYCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcy5nZXRPbmVTY2hlbWEoY2xhc3NOYW1lLCBmYWxzZSwge2NsZWFyQ2FjaGU6IHRydWV9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLCBgQ2xhc3MgJHtjbGFzc05hbWV9IGRvZXMgbm90IGV4aXN0LmApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLnRoZW4oc2NoZW1hID0+IHtcbiAgICAgICAgZmllbGROYW1lcy5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICAgICAgaWYgKCFzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigyNTUsIGBGaWVsZCAke2ZpZWxkTmFtZX0gZG9lcyBub3QgZXhpc3QsIGNhbm5vdCBkZWxldGUuYCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBzY2hlbWFGaWVsZHMgPSB7IC4uLnNjaGVtYS5maWVsZHMgfTtcbiAgICAgICAgcmV0dXJuIGRhdGFiYXNlLmFkYXB0ZXIuZGVsZXRlRmllbGRzKGNsYXNzTmFtZSwgc2NoZW1hLCBmaWVsZE5hbWVzKVxuICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChmaWVsZE5hbWVzLm1hcChmaWVsZE5hbWUgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBmaWVsZCA9IHNjaGVtYUZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgICAgICAgICBpZiAoZmllbGQgJiYgZmllbGQudHlwZSA9PT0gJ1JlbGF0aW9uJykge1xuICAgICAgICAgICAgICAvL0ZvciByZWxhdGlvbnMsIGRyb3AgdGhlIF9Kb2luIHRhYmxlXG4gICAgICAgICAgICAgICAgcmV0dXJuIGRhdGFiYXNlLmFkYXB0ZXIuZGVsZXRlQ2xhc3MoYF9Kb2luOiR7ZmllbGROYW1lfToke2NsYXNzTmFtZX1gKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgfSk7XG4gICAgICB9KS50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5fY2FjaGUuY2xlYXIoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLy8gVmFsaWRhdGVzIGFuIG9iamVjdCBwcm92aWRlZCBpbiBSRVNUIGZvcm1hdC5cbiAgLy8gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgbmV3IHNjaGVtYSBpZiB0aGlzIG9iamVjdCBpc1xuICAvLyB2YWxpZC5cbiAgdmFsaWRhdGVPYmplY3QoY2xhc3NOYW1lOiBzdHJpbmcsIG9iamVjdDogYW55LCBxdWVyeTogYW55KSB7XG4gICAgbGV0IGdlb2NvdW50ID0gMDtcbiAgICBsZXQgcHJvbWlzZSA9IHRoaXMuZW5mb3JjZUNsYXNzRXhpc3RzKGNsYXNzTmFtZSk7XG4gICAgZm9yIChjb25zdCBmaWVsZE5hbWUgaW4gb2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0W2ZpZWxkTmFtZV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGV4cGVjdGVkID0gZ2V0VHlwZShvYmplY3RbZmllbGROYW1lXSk7XG4gICAgICBpZiAoZXhwZWN0ZWQgPT09ICdHZW9Qb2ludCcpIHtcbiAgICAgICAgZ2VvY291bnQrKztcbiAgICAgIH1cbiAgICAgIGlmIChnZW9jb3VudCA+IDEpIHtcbiAgICAgICAgLy8gTWFrZSBzdXJlIGFsbCBmaWVsZCB2YWxpZGF0aW9uIG9wZXJhdGlvbnMgcnVuIGJlZm9yZSB3ZSByZXR1cm4uXG4gICAgICAgIC8vIElmIG5vdCAtIHdlIGFyZSBjb250aW51aW5nIHRvIHJ1biBsb2dpYywgYnV0IGFscmVhZHkgcHJvdmlkZWQgcmVzcG9uc2UgZnJvbSB0aGUgc2VydmVyLlxuICAgICAgICByZXR1cm4gcHJvbWlzZS50aGVuKCgpID0+IHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLFxuICAgICAgICAgICAgJ3RoZXJlIGNhbiBvbmx5IGJlIG9uZSBnZW9wb2ludCBmaWVsZCBpbiBhIGNsYXNzJykpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmICghZXhwZWN0ZWQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoZmllbGROYW1lID09PSAnQUNMJykge1xuICAgICAgICAvLyBFdmVyeSBvYmplY3QgaGFzIEFDTCBpbXBsaWNpdGx5LlxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgcHJvbWlzZSA9IHByb21pc2UudGhlbihzY2hlbWEgPT4gc2NoZW1hLmVuZm9yY2VGaWVsZEV4aXN0cyhjbGFzc05hbWUsIGZpZWxkTmFtZSwgZXhwZWN0ZWQpKTtcbiAgICB9XG4gICAgcHJvbWlzZSA9IHRoZW5WYWxpZGF0ZVJlcXVpcmVkQ29sdW1ucyhwcm9taXNlLCBjbGFzc05hbWUsIG9iamVjdCwgcXVlcnkpO1xuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgLy8gVmFsaWRhdGVzIHRoYXQgYWxsIHRoZSBwcm9wZXJ0aWVzIGFyZSBzZXQgZm9yIHRoZSBvYmplY3RcbiAgdmFsaWRhdGVSZXF1aXJlZENvbHVtbnMoY2xhc3NOYW1lOiBzdHJpbmcsIG9iamVjdDogYW55LCBxdWVyeTogYW55KSB7XG4gICAgY29uc3QgY29sdW1ucyA9IHJlcXVpcmVkQ29sdW1uc1tjbGFzc05hbWVdO1xuICAgIGlmICghY29sdW1ucyB8fCBjb2x1bW5zLmxlbmd0aCA9PSAwKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMpO1xuICAgIH1cblxuICAgIGNvbnN0IG1pc3NpbmdDb2x1bW5zID0gY29sdW1ucy5maWx0ZXIoZnVuY3Rpb24oY29sdW1uKXtcbiAgICAgIGlmIChxdWVyeSAmJiBxdWVyeS5vYmplY3RJZCkge1xuICAgICAgICBpZiAob2JqZWN0W2NvbHVtbl0gJiYgdHlwZW9mIG9iamVjdFtjb2x1bW5dID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgLy8gVHJ5aW5nIHRvIGRlbGV0ZSBhIHJlcXVpcmVkIGNvbHVtblxuICAgICAgICAgIHJldHVybiBvYmplY3RbY29sdW1uXS5fX29wID09ICdEZWxldGUnO1xuICAgICAgICB9XG4gICAgICAgIC8vIE5vdCB0cnlpbmcgdG8gZG8gYW55dGhpbmcgdGhlcmVcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuICFvYmplY3RbY29sdW1uXVxuICAgIH0pO1xuXG4gICAgaWYgKG1pc3NpbmdDb2x1bW5zLmxlbmd0aCA+IDApIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5DT1JSRUNUX1RZUEUsXG4gICAgICAgIG1pc3NpbmdDb2x1bW5zWzBdICsgJyBpcyByZXF1aXJlZC4nKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzKTtcbiAgfVxuXG4gIC8vIFZhbGlkYXRlcyB0aGUgYmFzZSBDTFAgZm9yIGFuIG9wZXJhdGlvblxuICB0ZXN0QmFzZUNMUChjbGFzc05hbWU6IHN0cmluZywgYWNsR3JvdXA6IHN0cmluZ1tdLCBvcGVyYXRpb246IHN0cmluZykge1xuICAgIGlmICghdGhpcy5wZXJtc1tjbGFzc05hbWVdIHx8ICF0aGlzLnBlcm1zW2NsYXNzTmFtZV1bb3BlcmF0aW9uXSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGNvbnN0IGNsYXNzUGVybXMgPSB0aGlzLnBlcm1zW2NsYXNzTmFtZV07XG4gICAgY29uc3QgcGVybXMgPSBjbGFzc1Blcm1zW29wZXJhdGlvbl07XG4gICAgLy8gSGFuZGxlIHRoZSBwdWJsaWMgc2NlbmFyaW8gcXVpY2tseVxuICAgIGlmIChwZXJtc1snKiddKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgLy8gQ2hlY2sgcGVybWlzc2lvbnMgYWdhaW5zdCB0aGUgYWNsR3JvdXAgcHJvdmlkZWQgKGFycmF5IG9mIHVzZXJJZC9yb2xlcylcbiAgICBpZiAoYWNsR3JvdXAuc29tZShhY2wgPT4geyByZXR1cm4gcGVybXNbYWNsXSA9PT0gdHJ1ZSB9KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIFZhbGlkYXRlcyBhbiBvcGVyYXRpb24gcGFzc2VzIGNsYXNzLWxldmVsLXBlcm1pc3Npb25zIHNldCBpbiB0aGUgc2NoZW1hXG4gIHZhbGlkYXRlUGVybWlzc2lvbihjbGFzc05hbWU6IHN0cmluZywgYWNsR3JvdXA6IHN0cmluZ1tdLCBvcGVyYXRpb246IHN0cmluZykge1xuXG4gICAgaWYgKHRoaXMudGVzdEJhc2VDTFAoY2xhc3NOYW1lLCBhY2xHcm91cCwgb3BlcmF0aW9uKSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5wZXJtc1tjbGFzc05hbWVdIHx8ICF0aGlzLnBlcm1zW2NsYXNzTmFtZV1bb3BlcmF0aW9uXSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGNvbnN0IGNsYXNzUGVybXMgPSB0aGlzLnBlcm1zW2NsYXNzTmFtZV07XG4gICAgY29uc3QgcGVybXMgPSBjbGFzc1Blcm1zW29wZXJhdGlvbl07XG5cbiAgICAvLyBJZiBvbmx5IGZvciBhdXRoZW50aWNhdGVkIHVzZXJzXG4gICAgLy8gbWFrZSBzdXJlIHdlIGhhdmUgYW4gYWNsR3JvdXBcbiAgICBpZiAocGVybXNbJ3JlcXVpcmVzQXV0aGVudGljYXRpb24nXSkge1xuICAgICAgLy8gSWYgYWNsR3JvdXAgaGFzICogKHB1YmxpYylcbiAgICAgIGlmICghYWNsR3JvdXAgfHwgYWNsR3JvdXAubGVuZ3RoID09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICAgJ1Blcm1pc3Npb24gZGVuaWVkLCB1c2VyIG5lZWRzIHRvIGJlIGF1dGhlbnRpY2F0ZWQuJyk7XG4gICAgICB9IGVsc2UgaWYgKGFjbEdyb3VwLmluZGV4T2YoJyonKSA+IC0xICYmIGFjbEdyb3VwLmxlbmd0aCA9PSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgICAgICdQZXJtaXNzaW9uIGRlbmllZCwgdXNlciBuZWVkcyB0byBiZSBhdXRoZW50aWNhdGVkLicpO1xuICAgICAgfVxuICAgICAgLy8gcmVxdWlyZXNBdXRoZW50aWNhdGlvbiBwYXNzZWQsIGp1c3QgbW92ZSBmb3J3YXJkXG4gICAgICAvLyBwcm9iYWJseSB3b3VsZCBiZSB3aXNlIGF0IHNvbWUgcG9pbnQgdG8gcmVuYW1lIHRvICdhdXRoZW50aWNhdGVkVXNlcidcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG5cbiAgICAvLyBObyBtYXRjaGluZyBDTFAsIGxldCdzIGNoZWNrIHRoZSBQb2ludGVyIHBlcm1pc3Npb25zXG4gICAgLy8gQW5kIGhhbmRsZSB0aG9zZSBsYXRlclxuICAgIGNvbnN0IHBlcm1pc3Npb25GaWVsZCA9IFsnZ2V0JywgJ2ZpbmQnLCAnY291bnQnXS5pbmRleE9mKG9wZXJhdGlvbikgPiAtMSA/ICdyZWFkVXNlckZpZWxkcycgOiAnd3JpdGVVc2VyRmllbGRzJztcblxuICAgIC8vIFJlamVjdCBjcmVhdGUgd2hlbiB3cml0ZSBsb2NrZG93blxuICAgIGlmIChwZXJtaXNzaW9uRmllbGQgPT0gJ3dyaXRlVXNlckZpZWxkcycgJiYgb3BlcmF0aW9uID09ICdjcmVhdGUnKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT1BFUkFUSU9OX0ZPUkJJRERFTixcbiAgICAgICAgYFBlcm1pc3Npb24gZGVuaWVkIGZvciBhY3Rpb24gJHtvcGVyYXRpb259IG9uIGNsYXNzICR7Y2xhc3NOYW1lfS5gKTtcbiAgICB9XG5cbiAgICAvLyBQcm9jZXNzIHRoZSByZWFkVXNlckZpZWxkcyBsYXRlclxuICAgIGlmIChBcnJheS5pc0FycmF5KGNsYXNzUGVybXNbcGVybWlzc2lvbkZpZWxkXSkgJiYgY2xhc3NQZXJtc1twZXJtaXNzaW9uRmllbGRdLmxlbmd0aCA+IDApIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLk9QRVJBVElPTl9GT1JCSURERU4sXG4gICAgICBgUGVybWlzc2lvbiBkZW5pZWQgZm9yIGFjdGlvbiAke29wZXJhdGlvbn0gb24gY2xhc3MgJHtjbGFzc05hbWV9LmApO1xuICB9XG5cbiAgLy8gUmV0dXJucyB0aGUgZXhwZWN0ZWQgdHlwZSBmb3IgYSBjbGFzc05hbWUra2V5IGNvbWJpbmF0aW9uXG4gIC8vIG9yIHVuZGVmaW5lZCBpZiB0aGUgc2NoZW1hIGlzIG5vdCBzZXRcbiAgZ2V0RXhwZWN0ZWRUeXBlKGNsYXNzTmFtZTogc3RyaW5nLCBmaWVsZE5hbWU6IHN0cmluZyk6ID8oU2NoZW1hRmllbGQgfCBzdHJpbmcpIHtcbiAgICBpZiAodGhpcy5kYXRhICYmIHRoaXMuZGF0YVtjbGFzc05hbWVdKSB7XG4gICAgICBjb25zdCBleHBlY3RlZFR5cGUgPSB0aGlzLmRhdGFbY2xhc3NOYW1lXVtmaWVsZE5hbWVdXG4gICAgICByZXR1cm4gZXhwZWN0ZWRUeXBlID09PSAnbWFwJyA/ICdPYmplY3QnIDogZXhwZWN0ZWRUeXBlO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLy8gQ2hlY2tzIGlmIGEgZ2l2ZW4gY2xhc3MgaXMgaW4gdGhlIHNjaGVtYS5cbiAgaGFzQ2xhc3MoY2xhc3NOYW1lOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5yZWxvYWREYXRhKCkudGhlbigoKSA9PiAhISh0aGlzLmRhdGFbY2xhc3NOYW1lXSkpO1xuICB9XG59XG5cbi8vIFJldHVybnMgYSBwcm9taXNlIGZvciBhIG5ldyBTY2hlbWEuXG5jb25zdCBsb2FkID0gKGRiQWRhcHRlcjogU3RvcmFnZUFkYXB0ZXIsIHNjaGVtYUNhY2hlOiBhbnksIG9wdGlvbnM6IGFueSk6IFByb21pc2U8U2NoZW1hQ29udHJvbGxlcj4gPT4ge1xuICBjb25zdCBzY2hlbWEgPSBuZXcgU2NoZW1hQ29udHJvbGxlcihkYkFkYXB0ZXIsIHNjaGVtYUNhY2hlKTtcbiAgcmV0dXJuIHNjaGVtYS5yZWxvYWREYXRhKG9wdGlvbnMpLnRoZW4oKCkgPT4gc2NoZW1hKTtcbn1cblxuLy8gQnVpbGRzIGEgbmV3IHNjaGVtYSAoaW4gc2NoZW1hIEFQSSByZXNwb25zZSBmb3JtYXQpIG91dCBvZiBhblxuLy8gZXhpc3RpbmcgbW9uZ28gc2NoZW1hICsgYSBzY2hlbWFzIEFQSSBwdXQgcmVxdWVzdC4gVGhpcyByZXNwb25zZVxuLy8gZG9lcyBub3QgaW5jbHVkZSB0aGUgZGVmYXVsdCBmaWVsZHMsIGFzIGl0IGlzIGludGVuZGVkIHRvIGJlIHBhc3NlZFxuLy8gdG8gbW9uZ29TY2hlbWFGcm9tRmllbGRzQW5kQ2xhc3NOYW1lLiBObyB2YWxpZGF0aW9uIGlzIGRvbmUgaGVyZSwgaXRcbi8vIGlzIGRvbmUgaW4gbW9uZ29TY2hlbWFGcm9tRmllbGRzQW5kQ2xhc3NOYW1lLlxuZnVuY3Rpb24gYnVpbGRNZXJnZWRTY2hlbWFPYmplY3QoZXhpc3RpbmdGaWVsZHM6IFNjaGVtYUZpZWxkcywgcHV0UmVxdWVzdDogYW55KTogU2NoZW1hRmllbGRzIHtcbiAgY29uc3QgbmV3U2NoZW1hID0ge307XG4gIC8vIEBmbG93LWRpc2FibGUtbmV4dFxuICBjb25zdCBzeXNTY2hlbWFGaWVsZCA9IE9iamVjdC5rZXlzKGRlZmF1bHRDb2x1bW5zKS5pbmRleE9mKGV4aXN0aW5nRmllbGRzLl9pZCkgPT09IC0xID8gW10gOiBPYmplY3Qua2V5cyhkZWZhdWx0Q29sdW1uc1tleGlzdGluZ0ZpZWxkcy5faWRdKTtcbiAgZm9yIChjb25zdCBvbGRGaWVsZCBpbiBleGlzdGluZ0ZpZWxkcykge1xuICAgIGlmIChvbGRGaWVsZCAhPT0gJ19pZCcgJiYgb2xkRmllbGQgIT09ICdBQ0wnICYmICBvbGRGaWVsZCAhPT0gJ3VwZGF0ZWRBdCcgJiYgb2xkRmllbGQgIT09ICdjcmVhdGVkQXQnICYmIG9sZEZpZWxkICE9PSAnb2JqZWN0SWQnKSB7XG4gICAgICBpZiAoc3lzU2NoZW1hRmllbGQubGVuZ3RoID4gMCAmJiBzeXNTY2hlbWFGaWVsZC5pbmRleE9mKG9sZEZpZWxkKSAhPT0gLTEpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBmaWVsZElzRGVsZXRlZCA9IHB1dFJlcXVlc3Rbb2xkRmllbGRdICYmIHB1dFJlcXVlc3Rbb2xkRmllbGRdLl9fb3AgPT09ICdEZWxldGUnXG4gICAgICBpZiAoIWZpZWxkSXNEZWxldGVkKSB7XG4gICAgICAgIG5ld1NjaGVtYVtvbGRGaWVsZF0gPSBleGlzdGluZ0ZpZWxkc1tvbGRGaWVsZF07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGZvciAoY29uc3QgbmV3RmllbGQgaW4gcHV0UmVxdWVzdCkge1xuICAgIGlmIChuZXdGaWVsZCAhPT0gJ29iamVjdElkJyAmJiBwdXRSZXF1ZXN0W25ld0ZpZWxkXS5fX29wICE9PSAnRGVsZXRlJykge1xuICAgICAgaWYgKHN5c1NjaGVtYUZpZWxkLmxlbmd0aCA+IDAgJiYgc3lzU2NoZW1hRmllbGQuaW5kZXhPZihuZXdGaWVsZCkgIT09IC0xKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgbmV3U2NoZW1hW25ld0ZpZWxkXSA9IHB1dFJlcXVlc3RbbmV3RmllbGRdO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbmV3U2NoZW1hO1xufVxuXG4vLyBHaXZlbiBhIHNjaGVtYSBwcm9taXNlLCBjb25zdHJ1Y3QgYW5vdGhlciBzY2hlbWEgcHJvbWlzZSB0aGF0XG4vLyB2YWxpZGF0ZXMgdGhpcyBmaWVsZCBvbmNlIHRoZSBzY2hlbWEgbG9hZHMuXG5mdW5jdGlvbiB0aGVuVmFsaWRhdGVSZXF1aXJlZENvbHVtbnMoc2NoZW1hUHJvbWlzZSwgY2xhc3NOYW1lLCBvYmplY3QsIHF1ZXJ5KSB7XG4gIHJldHVybiBzY2hlbWFQcm9taXNlLnRoZW4oKHNjaGVtYSkgPT4ge1xuICAgIHJldHVybiBzY2hlbWEudmFsaWRhdGVSZXF1aXJlZENvbHVtbnMoY2xhc3NOYW1lLCBvYmplY3QsIHF1ZXJ5KTtcbiAgfSk7XG59XG5cbi8vIEdldHMgdGhlIHR5cGUgZnJvbSBhIFJFU1QgQVBJIGZvcm1hdHRlZCBvYmplY3QsIHdoZXJlICd0eXBlJyBpc1xuLy8gZXh0ZW5kZWQgcGFzdCBqYXZhc2NyaXB0IHR5cGVzIHRvIGluY2x1ZGUgdGhlIHJlc3Qgb2YgdGhlIFBhcnNlXG4vLyB0eXBlIHN5c3RlbS5cbi8vIFRoZSBvdXRwdXQgc2hvdWxkIGJlIGEgdmFsaWQgc2NoZW1hIHZhbHVlLlxuLy8gVE9ETzogZW5zdXJlIHRoYXQgdGhpcyBpcyBjb21wYXRpYmxlIHdpdGggdGhlIGZvcm1hdCB1c2VkIGluIE9wZW4gREJcbmZ1bmN0aW9uIGdldFR5cGUob2JqOiBhbnkpOiA/KFNjaGVtYUZpZWxkIHwgc3RyaW5nKSB7XG4gIGNvbnN0IHR5cGUgPSB0eXBlb2Ygb2JqO1xuICBzd2l0Y2godHlwZSkge1xuICBjYXNlICdib29sZWFuJzpcbiAgICByZXR1cm4gJ0Jvb2xlYW4nO1xuICBjYXNlICdzdHJpbmcnOlxuICAgIHJldHVybiAnU3RyaW5nJztcbiAgY2FzZSAnbnVtYmVyJzpcbiAgICByZXR1cm4gJ051bWJlcic7XG4gIGNhc2UgJ21hcCc6XG4gIGNhc2UgJ29iamVjdCc6XG4gICAgaWYgKCFvYmopIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiBnZXRPYmplY3RUeXBlKG9iaik7XG4gIGNhc2UgJ2Z1bmN0aW9uJzpcbiAgY2FzZSAnc3ltYm9sJzpcbiAgY2FzZSAndW5kZWZpbmVkJzpcbiAgZGVmYXVsdDpcbiAgICB0aHJvdyAnYmFkIG9iajogJyArIG9iajtcbiAgfVxufVxuXG4vLyBUaGlzIGdldHMgdGhlIHR5cGUgZm9yIG5vbi1KU09OIHR5cGVzIGxpa2UgcG9pbnRlcnMgYW5kIGZpbGVzLCBidXRcbi8vIGFsc28gZ2V0cyB0aGUgYXBwcm9wcmlhdGUgdHlwZSBmb3IgJCBvcGVyYXRvcnMuXG4vLyBSZXR1cm5zIG51bGwgaWYgdGhlIHR5cGUgaXMgdW5rbm93bi5cbmZ1bmN0aW9uIGdldE9iamVjdFR5cGUob2JqKTogPyhTY2hlbWFGaWVsZCB8IHN0cmluZykge1xuICBpZiAob2JqIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICByZXR1cm4gJ0FycmF5JztcbiAgfVxuICBpZiAob2JqLl9fdHlwZSl7XG4gICAgc3dpdGNoKG9iai5fX3R5cGUpIHtcbiAgICBjYXNlICdQb2ludGVyJyA6XG4gICAgICBpZihvYmouY2xhc3NOYW1lKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICAgIHRhcmdldENsYXNzOiBvYmouY2xhc3NOYW1lXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ1JlbGF0aW9uJyA6XG4gICAgICBpZihvYmouY2xhc3NOYW1lKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdHlwZTogJ1JlbGF0aW9uJyxcbiAgICAgICAgICB0YXJnZXRDbGFzczogb2JqLmNsYXNzTmFtZVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICdGaWxlJyA6XG4gICAgICBpZihvYmoubmFtZSkge1xuICAgICAgICByZXR1cm4gJ0ZpbGUnO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnRGF0ZScgOlxuICAgICAgaWYob2JqLmlzbykge1xuICAgICAgICByZXR1cm4gJ0RhdGUnO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnR2VvUG9pbnQnIDpcbiAgICAgIGlmKG9iai5sYXRpdHVkZSAhPSBudWxsICYmIG9iai5sb25naXR1ZGUgIT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gJ0dlb1BvaW50JztcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ0J5dGVzJyA6XG4gICAgICBpZihvYmouYmFzZTY0KSB7XG4gICAgICAgIHJldHVybiAnQnl0ZXMnO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnUG9seWdvbicgOlxuICAgICAgaWYob2JqLmNvb3JkaW5hdGVzKSB7XG4gICAgICAgIHJldHVybiAnUG9seWdvbic7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLCBcIlRoaXMgaXMgbm90IGEgdmFsaWQgXCIgKyBvYmouX190eXBlKTtcbiAgfVxuICBpZiAob2JqWyckbmUnXSkge1xuICAgIHJldHVybiBnZXRPYmplY3RUeXBlKG9ialsnJG5lJ10pO1xuICB9XG4gIGlmIChvYmouX19vcCkge1xuICAgIHN3aXRjaChvYmouX19vcCkge1xuICAgIGNhc2UgJ0luY3JlbWVudCc6XG4gICAgICByZXR1cm4gJ051bWJlcic7XG4gICAgY2FzZSAnRGVsZXRlJzpcbiAgICAgIHJldHVybiBudWxsO1xuICAgIGNhc2UgJ0FkZCc6XG4gICAgY2FzZSAnQWRkVW5pcXVlJzpcbiAgICBjYXNlICdSZW1vdmUnOlxuICAgICAgcmV0dXJuICdBcnJheSc7XG4gICAgY2FzZSAnQWRkUmVsYXRpb24nOlxuICAgIGNhc2UgJ1JlbW92ZVJlbGF0aW9uJzpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6ICdSZWxhdGlvbicsXG4gICAgICAgIHRhcmdldENsYXNzOiBvYmoub2JqZWN0c1swXS5jbGFzc05hbWVcbiAgICAgIH1cbiAgICBjYXNlICdCYXRjaCc6XG4gICAgICByZXR1cm4gZ2V0T2JqZWN0VHlwZShvYmoub3BzWzBdKTtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgJ3VuZXhwZWN0ZWQgb3A6ICcgKyBvYmouX19vcDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuICdPYmplY3QnO1xufVxuXG5leHBvcnQge1xuICBsb2FkLFxuICBjbGFzc05hbWVJc1ZhbGlkLFxuICBmaWVsZE5hbWVJc1ZhbGlkLFxuICBpbnZhbGlkQ2xhc3NOYW1lTWVzc2FnZSxcbiAgYnVpbGRNZXJnZWRTY2hlbWFPYmplY3QsXG4gIHN5c3RlbUNsYXNzZXMsXG4gIGRlZmF1bHRDb2x1bW5zLFxuICBjb252ZXJ0U2NoZW1hVG9BZGFwdGVyU2NoZW1hLFxuICBWb2xhdGlsZUNsYXNzZXNTY2hlbWFzLFxuICBTY2hlbWFDb250cm9sbGVyLFxufTtcbiJdfQ==
|
|
1567
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfU3RvcmFnZUFkYXB0ZXIiLCJyZXF1aXJlIiwiX1NjaGVtYUNhY2hlIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl9EYXRhYmFzZUNvbnRyb2xsZXIiLCJfQ29uZmlnIiwiX0Vycm9yIiwiX2RlZXBjb3B5IiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiUGFyc2UiLCJkZWZhdWx0Q29sdW1ucyIsImV4cG9ydHMiLCJPYmplY3QiLCJmcmVlemUiLCJfRGVmYXVsdCIsIm9iamVjdElkIiwidHlwZSIsImNyZWF0ZWRBdCIsInVwZGF0ZWRBdCIsIkFDTCIsIl9Vc2VyIiwidXNlcm5hbWUiLCJwYXNzd29yZCIsImVtYWlsIiwiZW1haWxWZXJpZmllZCIsImF1dGhEYXRhIiwiX0luc3RhbGxhdGlvbiIsImluc3RhbGxhdGlvbklkIiwiZGV2aWNlVG9rZW4iLCJjaGFubmVscyIsImRldmljZVR5cGUiLCJwdXNoVHlwZSIsIkdDTVNlbmRlcklkIiwidGltZVpvbmUiLCJsb2NhbGVJZGVudGlmaWVyIiwiYmFkZ2UiLCJhcHBWZXJzaW9uIiwiYXBwTmFtZSIsImFwcElkZW50aWZpZXIiLCJwYXJzZVZlcnNpb24iLCJfUm9sZSIsIm5hbWUiLCJ1c2VycyIsInRhcmdldENsYXNzIiwicm9sZXMiLCJfU2Vzc2lvbiIsInVzZXIiLCJzZXNzaW9uVG9rZW4iLCJleHBpcmVzQXQiLCJjcmVhdGVkV2l0aCIsIl9Qcm9kdWN0IiwicHJvZHVjdElkZW50aWZpZXIiLCJkb3dubG9hZCIsImRvd25sb2FkTmFtZSIsImljb24iLCJvcmRlciIsInRpdGxlIiwic3VidGl0bGUiLCJfUHVzaFN0YXR1cyIsInB1c2hUaW1lIiwic291cmNlIiwicXVlcnkiLCJwYXlsb2FkIiwiZXhwaXJ5IiwiZXhwaXJhdGlvbl9pbnRlcnZhbCIsInN0YXR1cyIsIm51bVNlbnQiLCJudW1GYWlsZWQiLCJwdXNoSGFzaCIsImVycm9yTWVzc2FnZSIsInNlbnRQZXJUeXBlIiwiZmFpbGVkUGVyVHlwZSIsInNlbnRQZXJVVENPZmZzZXQiLCJmYWlsZWRQZXJVVENPZmZzZXQiLCJjb3VudCIsIl9Kb2JTdGF0dXMiLCJqb2JOYW1lIiwibWVzc2FnZSIsInBhcmFtcyIsImZpbmlzaGVkQXQiLCJfSm9iU2NoZWR1bGUiLCJkZXNjcmlwdGlvbiIsInN0YXJ0QWZ0ZXIiLCJkYXlzT2ZXZWVrIiwidGltZU9mRGF5IiwibGFzdFJ1biIsInJlcGVhdE1pbnV0ZXMiLCJfSG9va3MiLCJmdW5jdGlvbk5hbWUiLCJjbGFzc05hbWUiLCJ0cmlnZ2VyTmFtZSIsInVybCIsIl9HbG9iYWxDb25maWciLCJtYXN0ZXJLZXlPbmx5IiwiX0dyYXBoUUxDb25maWciLCJjb25maWciLCJfQXVkaWVuY2UiLCJsYXN0VXNlZCIsInRpbWVzVXNlZCIsIl9JZGVtcG90ZW5jeSIsInJlcUlkIiwiZXhwaXJlIiwicmVxdWlyZWRDb2x1bW5zIiwicmVhZCIsIndyaXRlIiwiaW52YWxpZENvbHVtbnMiLCJzeXN0ZW1DbGFzc2VzIiwidm9sYXRpbGVDbGFzc2VzIiwicm9sZVJlZ2V4IiwicHJvdGVjdGVkRmllbGRzUG9pbnRlclJlZ2V4IiwicHVibGljUmVnZXgiLCJhdXRoZW50aWNhdGVkUmVnZXgiLCJyZXF1aXJlc0F1dGhlbnRpY2F0aW9uUmVnZXgiLCJjbHBQb2ludGVyUmVnZXgiLCJwcm90ZWN0ZWRGaWVsZHNSZWdleCIsImNscEZpZWxkc1JlZ2V4IiwidmFsaWRhdGVQZXJtaXNzaW9uS2V5Iiwia2V5IiwidXNlcklkUmVnRXhwIiwibWF0Y2hlc1NvbWUiLCJyZWdFeCIsIm1hdGNoIiwidmFsaWQiLCJFcnJvciIsIklOVkFMSURfSlNPTiIsInZhbGlkYXRlUHJvdGVjdGVkRmllbGRzS2V5IiwiQ0xQVmFsaWRLZXlzIiwidmFsaWRhdGVDTFAiLCJwZXJtcyIsImZpZWxkcyIsIm9wZXJhdGlvbktleSIsImluZGV4T2YiLCJvcGVyYXRpb24iLCJ2YWxpZGF0ZUNMUGpzb24iLCJmaWVsZE5hbWUiLCJ2YWxpZGF0ZVBvaW50ZXJQZXJtaXNzaW9uIiwiZW50aXR5IiwicHJvdGVjdGVkRmllbGRzIiwiQXJyYXkiLCJpc0FycmF5IiwiZmllbGQiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJwb2ludGVyRmllbGRzIiwicG9pbnRlckZpZWxkIiwicGVybWl0IiwidG9TdHJpbmciLCJpbnZhbGlkS2V5cyIsImtleXMiLCJmaWx0ZXIiLCJpbmNsdWRlcyIsImludmFsaWRWYWx1ZXMiLCJ2YWx1ZXMiLCJsZW5ndGgiLCJqb2luIiwiam9pbkNsYXNzUmVnZXgiLCJjbGFzc0FuZEZpZWxkUmVnZXgiLCJjbGFzc05hbWVJc1ZhbGlkIiwidGVzdCIsImZpZWxkTmFtZUlzVmFsaWQiLCJmaWVsZE5hbWVJc1ZhbGlkRm9yQ2xhc3MiLCJpbnZhbGlkQ2xhc3NOYW1lTWVzc2FnZSIsImludmFsaWRKc29uRXJyb3IiLCJ2YWxpZE5vblJlbGF0aW9uT3JQb2ludGVyVHlwZXMiLCJmaWVsZFR5cGVJc0ludmFsaWQiLCJJTlZBTElEX0NMQVNTX05BTUUiLCJ1bmRlZmluZWQiLCJJTkNPUlJFQ1RfVFlQRSIsImNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEiLCJzY2hlbWEiLCJpbmplY3REZWZhdWx0U2NoZW1hIiwiX3JwZXJtIiwiX3dwZXJtIiwiX2hhc2hlZF9wYXNzd29yZCIsImNvbnZlcnRBZGFwdGVyU2NoZW1hVG9QYXJzZVNjaGVtYSIsImluZGV4ZXMiLCJTY2hlbWFEYXRhIiwiY29uc3RydWN0b3IiLCJhbGxTY2hlbWFzIiwiX19kYXRhIiwiX19wcm90ZWN0ZWRGaWVsZHMiLCJmb3JFYWNoIiwiZGVmaW5lUHJvcGVydHkiLCJnZXQiLCJkYXRhIiwiY2xhc3NMZXZlbFBlcm1pc3Npb25zIiwiZGVlcGNvcHkiLCJjbGFzc1Byb3RlY3RlZEZpZWxkcyIsInVucSIsIlNldCIsImZyb20iLCJkZWZhdWx0U2NoZW1hIiwiX0hvb2tzU2NoZW1hIiwiX0dsb2JhbENvbmZpZ1NjaGVtYSIsIl9HcmFwaFFMQ29uZmlnU2NoZW1hIiwiX1B1c2hTdGF0dXNTY2hlbWEiLCJfSm9iU3RhdHVzU2NoZW1hIiwiX0pvYlNjaGVkdWxlU2NoZW1hIiwiX0F1ZGllbmNlU2NoZW1hIiwiX0lkZW1wb3RlbmN5U2NoZW1hIiwiVm9sYXRpbGVDbGFzc2VzU2NoZW1hcyIsImRiVHlwZU1hdGNoZXNPYmplY3RUeXBlIiwiZGJUeXBlIiwib2JqZWN0VHlwZSIsInR5cGVUb1N0cmluZyIsInR0bCIsImRhdGUiLCJEYXRlIiwibm93IiwiZHVyYXRpb24iLCJTY2hlbWFDb250cm9sbGVyIiwiZGF0YWJhc2VBZGFwdGVyIiwiX2RiQWRhcHRlciIsIkNvbmZpZyIsImFwcGxpY2F0aW9uSWQiLCJzY2hlbWFEYXRhIiwiU2NoZW1hQ2FjaGUiLCJhbGwiLCJjdXN0b21JZHMiLCJhbGxvd0N1c3RvbU9iamVjdElkIiwiY3VzdG9tSWRSZWdFeCIsImF1dG9JZFJlZ0V4IiwidXNlcklkUmVnRXgiLCJ3YXRjaCIsInJlbG9hZERhdGEiLCJjbGVhckNhY2hlIiwicmVsb2FkRGF0YUlmTmVlZGVkIiwiZW5hYmxlU2NoZW1hSG9va3MiLCJvcHRpb25zIiwicmVsb2FkRGF0YVByb21pc2UiLCJnZXRBbGxDbGFzc2VzIiwidGhlbiIsImVyciIsInNldEFsbENsYXNzZXMiLCJjYWNoZWQiLCJQcm9taXNlIiwicmVzb2x2ZSIsIm1hcCIsInB1dCIsImdldE9uZVNjaGVtYSIsImFsbG93Vm9sYXRpbGVDbGFzc2VzIiwiY2xlYXIiLCJvbmVTY2hlbWEiLCJmaW5kIiwicmVqZWN0IiwiYWRkQ2xhc3NJZk5vdEV4aXN0cyIsInZhbGlkYXRpb25FcnJvciIsInZhbGlkYXRlTmV3Q2xhc3MiLCJjb2RlIiwiZXJyb3IiLCJhZGFwdGVyU2NoZW1hIiwiY3JlYXRlQ2xhc3MiLCJwYXJzZVNjaGVtYSIsIkRVUExJQ0FURV9WQUxVRSIsInVwZGF0ZUNsYXNzIiwic3VibWl0dGVkRmllbGRzIiwiZGF0YWJhc2UiLCJleGlzdGluZ0ZpZWxkcyIsIl9fb3AiLCJuZXdTY2hlbWEiLCJidWlsZE1lcmdlZFNjaGVtYU9iamVjdCIsImRlZmF1bHRGaWVsZHMiLCJmdWxsTmV3U2NoZW1hIiwiYXNzaWduIiwidmFsaWRhdGVTY2hlbWFEYXRhIiwiZGVsZXRlZEZpZWxkcyIsImluc2VydGVkRmllbGRzIiwicHVzaCIsImRlbGV0ZVByb21pc2UiLCJkZWxldGVGaWVsZHMiLCJlbmZvcmNlRmllbGRzIiwicHJvbWlzZXMiLCJlbmZvcmNlRmllbGRFeGlzdHMiLCJyZXN1bHRzIiwicmVzdWx0Iiwic2V0UGVybWlzc2lvbnMiLCJzZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdCIsImVuc3VyZUZpZWxkcyIsInJlbG9hZGVkU2NoZW1hIiwiY2F0Y2giLCJlbmZvcmNlQ2xhc3NFeGlzdHMiLCJleGlzdGluZ0ZpZWxkTmFtZXMiLCJJTlZBTElEX0tFWV9OQU1FIiwiZmllbGRUeXBlIiwiZGVmYXVsdFZhbHVlIiwiZGVmYXVsdFZhbHVlVHlwZSIsImdldFR5cGUiLCJyZXF1aXJlZCIsImdlb1BvaW50cyIsInNldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsImlzVmFsaWRhdGlvbiIsIm1haW50ZW5hbmNlIiwieCIsInkiLCJzcGxpdCIsImlzQXJyYXlJbmRleCIsImV2ZXJ5IiwiYyIsImZpZWxkTmFtZVRvVmFsaWRhdGUiLCJjaGFyQXQiLCJzdWJzdHJpbmciLCJleHBlY3RlZFR5cGUiLCJnZXRFeHBlY3RlZFR5cGUiLCJKU09OIiwic3RyaW5naWZ5IiwidXBkYXRlRmllbGRPcHRpb25zIiwiYWRkRmllbGRJZk5vdEV4aXN0cyIsImkiLCJkZWxldGVGaWVsZCIsImZpZWxkTmFtZXMiLCJzY2hlbWFGaWVsZHMiLCJhZGFwdGVyIiwiZGVsZXRlQ2xhc3MiLCJ2YWxpZGF0ZU9iamVjdCIsIm9iamVjdCIsImdlb2NvdW50IiwiZXhwZWN0ZWQiLCJwcm9taXNlIiwidGhlblZhbGlkYXRlUmVxdWlyZWRDb2x1bW5zIiwidmFsaWRhdGVSZXF1aXJlZENvbHVtbnMiLCJjb2x1bW5zIiwibWlzc2luZ0NvbHVtbnMiLCJjb2x1bW4iLCJ0ZXN0UGVybWlzc2lvbnNGb3JDbGFzc05hbWUiLCJhY2xHcm91cCIsInRlc3RQZXJtaXNzaW9ucyIsImdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyIsImNsYXNzUGVybWlzc2lvbnMiLCJzb21lIiwiYWNsIiwidmFsaWRhdGVQZXJtaXNzaW9uIiwiYWN0aW9uIiwiY3JlYXRlU2FuaXRpemVkRXJyb3IiLCJPQkpFQ1RfTk9UX0ZPVU5EIiwicGVybWlzc2lvbkZpZWxkIiwiT1BFUkFUSU9OX0ZPUkJJRERFTiIsImhhc0NsYXNzIiwibG9hZCIsImRiQWRhcHRlciIsInNjaGVtYUNhY2hlVHRsIiwicHV0UmVxdWVzdCIsInN5c1NjaGVtYUZpZWxkIiwiX2lkIiwib2xkRmllbGQiLCJmaWVsZElzRGVsZXRlZCIsIm5ld0ZpZWxkIiwic2NoZW1hUHJvbWlzZSIsIm9iaiIsImdldE9iamVjdFR5cGUiLCJfX3R5cGUiLCJpc28iLCJsYXRpdHVkZSIsImxvbmdpdHVkZSIsImJhc2U2NCIsImNvb3JkaW5hdGVzIiwib2JqZWN0cyIsIm9wcyJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9TY2hlbWFDb250cm9sbGVyLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIEBmbG93XG4vLyBUaGlzIGNsYXNzIGhhbmRsZXMgc2NoZW1hIHZhbGlkYXRpb24sIHBlcnNpc3RlbmNlLCBhbmQgbW9kaWZpY2F0aW9uLlxuLy9cbi8vIEVhY2ggaW5kaXZpZHVhbCBTY2hlbWEgb2JqZWN0IHNob3VsZCBiZSBpbW11dGFibGUuIFRoZSBoZWxwZXJzIHRvXG4vLyBkbyB0aGluZ3Mgd2l0aCB0aGUgU2NoZW1hIGp1c3QgcmV0dXJuIGEgbmV3IHNjaGVtYSB3aGVuIHRoZSBzY2hlbWFcbi8vIGlzIGNoYW5nZWQuXG4vL1xuLy8gVGhlIGNhbm9uaWNhbCBwbGFjZSB0byBzdG9yZSB0aGlzIFNjaGVtYSBpcyBpbiB0aGUgZGF0YWJhc2UgaXRzZWxmLFxuLy8gaW4gYSBfU0NIRU1BIGNvbGxlY3Rpb24uIFRoaXMgaXMgbm90IHRoZSByaWdodCB3YXkgdG8gZG8gaXQgZm9yIGFuXG4vLyBvcGVuIHNvdXJjZSBmcmFtZXdvcmssIGJ1dCBpdCdzIGJhY2t3YXJkIGNvbXBhdGlibGUsIHNvIHdlJ3JlXG4vLyBrZWVwaW5nIGl0IHRoaXMgd2F5IGZvciBub3cuXG4vL1xuLy8gSW4gQVBJLWhhbmRsaW5nIGNvZGUsIHlvdSBzaG91bGQgb25seSB1c2UgdGhlIFNjaGVtYSBjbGFzcyB2aWEgdGhlXG4vLyBEYXRhYmFzZUNvbnRyb2xsZXIuIFRoaXMgd2lsbCBsZXQgdXMgcmVwbGFjZSB0aGUgc2NoZW1hIGxvZ2ljIGZvclxuLy8gZGlmZmVyZW50IGRhdGFiYXNlcy5cbi8vIFRPRE86IGhpZGUgYWxsIHNjaGVtYSBsb2dpYyBpbnNpZGUgdGhlIGRhdGFiYXNlIGFkYXB0ZXIuXG4vLyBAZmxvdy1kaXNhYmxlLW5leHRcbmNvbnN0IFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuaW1wb3J0IHsgU3RvcmFnZUFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9TdG9yYWdlL1N0b3JhZ2VBZGFwdGVyJztcbmltcG9ydCBTY2hlbWFDYWNoZSBmcm9tICcuLi9BZGFwdGVycy9DYWNoZS9TY2hlbWFDYWNoZSc7XG5pbXBvcnQgRGF0YWJhc2VDb250cm9sbGVyIGZyb20gJy4vRGF0YWJhc2VDb250cm9sbGVyJztcbmltcG9ydCBDb25maWcgZnJvbSAnLi4vQ29uZmlnJztcbmltcG9ydCB7IGNyZWF0ZVNhbml0aXplZEVycm9yIH0gZnJvbSAnLi4vRXJyb3InO1xuLy8gQGZsb3ctZGlzYWJsZS1uZXh0XG5pbXBvcnQgZGVlcGNvcHkgZnJvbSAnZGVlcGNvcHknO1xuaW1wb3J0IHR5cGUge1xuICBTY2hlbWEsXG4gIFNjaGVtYUZpZWxkcyxcbiAgQ2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICBTY2hlbWFGaWVsZCxcbiAgTG9hZFNjaGVtYU9wdGlvbnMsXG59IGZyb20gJy4vdHlwZXMnO1xuXG5jb25zdCBkZWZhdWx0Q29sdW1uczogeyBbc3RyaW5nXTogU2NoZW1hRmllbGRzIH0gPSBPYmplY3QuZnJlZXplKHtcbiAgLy8gQ29udGFpbiB0aGUgZGVmYXVsdCBjb2x1bW5zIGZvciBldmVyeSBwYXJzZSBvYmplY3QgdHlwZSAoZXhjZXB0IF9Kb2luIGNvbGxlY3Rpb24pXG4gIF9EZWZhdWx0OiB7XG4gICAgb2JqZWN0SWQ6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBjcmVhdGVkQXQ6IHsgdHlwZTogJ0RhdGUnIH0sXG4gICAgdXBkYXRlZEF0OiB7IHR5cGU6ICdEYXRlJyB9LFxuICAgIEFDTDogeyB0eXBlOiAnQUNMJyB9LFxuICB9LFxuICAvLyBUaGUgYWRkaXRpb25hbCBkZWZhdWx0IGNvbHVtbnMgZm9yIHRoZSBfVXNlciBjb2xsZWN0aW9uIChpbiBhZGRpdGlvbiB0byBEZWZhdWx0Q29scylcbiAgX1VzZXI6IHtcbiAgICB1c2VybmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHBhc3N3b3JkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZW1haWw6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBlbWFpbFZlcmlmaWVkOiB7IHR5cGU6ICdCb29sZWFuJyB9LFxuICAgIGF1dGhEYXRhOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gIH0sXG4gIC8vIFRoZSBhZGRpdGlvbmFsIGRlZmF1bHQgY29sdW1ucyBmb3IgdGhlIF9JbnN0YWxsYXRpb24gY29sbGVjdGlvbiAoaW4gYWRkaXRpb24gdG8gRGVmYXVsdENvbHMpXG4gIF9JbnN0YWxsYXRpb246IHtcbiAgICBpbnN0YWxsYXRpb25JZDogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGRldmljZVRva2VuOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgY2hhbm5lbHM6IHsgdHlwZTogJ0FycmF5JyB9LFxuICAgIGRldmljZVR5cGU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBwdXNoVHlwZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIEdDTVNlbmRlcklkOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgdGltZVpvbmU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBsb2NhbGVJZGVudGlmaWVyOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgYmFkZ2U6IHsgdHlwZTogJ051bWJlcicgfSxcbiAgICBhcHBWZXJzaW9uOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgYXBwTmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGFwcElkZW50aWZpZXI6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBwYXJzZVZlcnNpb246IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgfSxcbiAgLy8gVGhlIGFkZGl0aW9uYWwgZGVmYXVsdCBjb2x1bW5zIGZvciB0aGUgX1JvbGUgY29sbGVjdGlvbiAoaW4gYWRkaXRpb24gdG8gRGVmYXVsdENvbHMpXG4gIF9Sb2xlOiB7XG4gICAgbmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHVzZXJzOiB7IHR5cGU6ICdSZWxhdGlvbicsIHRhcmdldENsYXNzOiAnX1VzZXInIH0sXG4gICAgcm9sZXM6IHsgdHlwZTogJ1JlbGF0aW9uJywgdGFyZ2V0Q2xhc3M6ICdfUm9sZScgfSxcbiAgfSxcbiAgLy8gVGhlIGFkZGl0aW9uYWwgZGVmYXVsdCBjb2x1bW5zIGZvciB0aGUgX1Nlc3Npb24gY29sbGVjdGlvbiAoaW4gYWRkaXRpb24gdG8gRGVmYXVsdENvbHMpXG4gIF9TZXNzaW9uOiB7XG4gICAgdXNlcjogeyB0eXBlOiAnUG9pbnRlcicsIHRhcmdldENsYXNzOiAnX1VzZXInIH0sXG4gICAgaW5zdGFsbGF0aW9uSWQ6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBzZXNzaW9uVG9rZW46IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBleHBpcmVzQXQ6IHsgdHlwZTogJ0RhdGUnIH0sXG4gICAgY3JlYXRlZFdpdGg6IHsgdHlwZTogJ09iamVjdCcgfSxcbiAgfSxcbiAgX1Byb2R1Y3Q6IHtcbiAgICBwcm9kdWN0SWRlbnRpZmllcjogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGRvd25sb2FkOiB7IHR5cGU6ICdGaWxlJyB9LFxuICAgIGRvd25sb2FkTmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGljb246IHsgdHlwZTogJ0ZpbGUnIH0sXG4gICAgb3JkZXI6IHsgdHlwZTogJ051bWJlcicgfSxcbiAgICB0aXRsZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHN1YnRpdGxlOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gIH0sXG4gIF9QdXNoU3RhdHVzOiB7XG4gICAgcHVzaFRpbWU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBzb3VyY2U6IHsgdHlwZTogJ1N0cmluZycgfSwgLy8gcmVzdCBvciB3ZWJ1aVxuICAgIHF1ZXJ5OiB7IHR5cGU6ICdTdHJpbmcnIH0sIC8vIHRoZSBzdHJpbmdpZmllZCBKU09OIHF1ZXJ5XG4gICAgcGF5bG9hZDogeyB0eXBlOiAnU3RyaW5nJyB9LCAvLyB0aGUgc3RyaW5naWZpZWQgSlNPTiBwYXlsb2FkLFxuICAgIHRpdGxlOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgZXhwaXJ5OiB7IHR5cGU6ICdOdW1iZXInIH0sXG4gICAgZXhwaXJhdGlvbl9pbnRlcnZhbDogeyB0eXBlOiAnTnVtYmVyJyB9LFxuICAgIHN0YXR1czogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIG51bVNlbnQ6IHsgdHlwZTogJ051bWJlcicgfSxcbiAgICBudW1GYWlsZWQ6IHsgdHlwZTogJ051bWJlcicgfSxcbiAgICBwdXNoSGFzaDogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGVycm9yTWVzc2FnZTogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICAgIHNlbnRQZXJUeXBlOiB7IHR5cGU6ICdPYmplY3QnIH0sXG4gICAgZmFpbGVkUGVyVHlwZTogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICAgIHNlbnRQZXJVVENPZmZzZXQ6IHsgdHlwZTogJ09iamVjdCcgfSxcbiAgICBmYWlsZWRQZXJVVENPZmZzZXQ6IHsgdHlwZTogJ09iamVjdCcgfSxcbiAgICBjb3VudDogeyB0eXBlOiAnTnVtYmVyJyB9LCAvLyB0cmFja3MgIyBvZiBiYXRjaGVzIHF1ZXVlZCBhbmQgcGVuZGluZ1xuICB9LFxuICBfSm9iU3RhdHVzOiB7XG4gICAgam9iTmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHNvdXJjZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHN0YXR1czogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIG1lc3NhZ2U6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBwYXJhbXM6IHsgdHlwZTogJ09iamVjdCcgfSwgLy8gcGFyYW1zIHJlY2VpdmVkIHdoZW4gY2FsbGluZyB0aGUgam9iXG4gICAgZmluaXNoZWRBdDogeyB0eXBlOiAnRGF0ZScgfSxcbiAgfSxcbiAgX0pvYlNjaGVkdWxlOiB7XG4gICAgam9iTmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGRlc2NyaXB0aW9uOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgcGFyYW1zOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgc3RhcnRBZnRlcjogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGRheXNPZldlZWs6IHsgdHlwZTogJ0FycmF5JyB9LFxuICAgIHRpbWVPZkRheTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGxhc3RSdW46IHsgdHlwZTogJ051bWJlcicgfSxcbiAgICByZXBlYXRNaW51dGVzOiB7IHR5cGU6ICdOdW1iZXInIH0sXG4gIH0sXG4gIF9Ib29rczoge1xuICAgIGZ1bmN0aW9uTmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGNsYXNzTmFtZTogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHRyaWdnZXJOYW1lOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gICAgdXJsOiB7IHR5cGU6ICdTdHJpbmcnIH0sXG4gIH0sXG4gIF9HbG9iYWxDb25maWc6IHtcbiAgICBvYmplY3RJZDogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIHBhcmFtczogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICAgIG1hc3RlcktleU9ubHk6IHsgdHlwZTogJ09iamVjdCcgfSxcbiAgfSxcbiAgX0dyYXBoUUxDb25maWc6IHtcbiAgICBvYmplY3RJZDogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIGNvbmZpZzogeyB0eXBlOiAnT2JqZWN0JyB9LFxuICB9LFxuICBfQXVkaWVuY2U6IHtcbiAgICBvYmplY3RJZDogeyB0eXBlOiAnU3RyaW5nJyB9LFxuICAgIG5hbWU6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBxdWVyeTogeyB0eXBlOiAnU3RyaW5nJyB9LCAvL3N0b3JpbmcgcXVlcnkgYXMgSlNPTiBzdHJpbmcgdG8gcHJldmVudCBcIk5lc3RlZCBrZXlzIHNob3VsZCBub3QgY29udGFpbiB0aGUgJyQnIG9yICcuJyBjaGFyYWN0ZXJzXCIgZXJyb3JcbiAgICBsYXN0VXNlZDogeyB0eXBlOiAnRGF0ZScgfSxcbiAgICB0aW1lc1VzZWQ6IHsgdHlwZTogJ051bWJlcicgfSxcbiAgfSxcbiAgX0lkZW1wb3RlbmN5OiB7XG4gICAgcmVxSWQ6IHsgdHlwZTogJ1N0cmluZycgfSxcbiAgICBleHBpcmU6IHsgdHlwZTogJ0RhdGUnIH0sXG4gIH0sXG59KTtcblxuLy8gZmllbGRzIHJlcXVpcmVkIGZvciByZWFkIG9yIHdyaXRlIG9wZXJhdGlvbnMgb24gdGhlaXIgcmVzcGVjdGl2ZSBjbGFzc2VzLlxuY29uc3QgcmVxdWlyZWRDb2x1bW5zID0gT2JqZWN0LmZyZWV6ZSh7XG4gIHJlYWQ6IHtcbiAgICBfVXNlcjogWyd1c2VybmFtZSddLFxuICB9LFxuICB3cml0ZToge1xuICAgIF9Qcm9kdWN0OiBbJ3Byb2R1Y3RJZGVudGlmaWVyJywgJ2ljb24nLCAnb3JkZXInLCAndGl0bGUnLCAnc3VidGl0bGUnXSxcbiAgICBfUm9sZTogWyduYW1lJywgJ0FDTCddLFxuICB9LFxufSk7XG5cbmNvbnN0IGludmFsaWRDb2x1bW5zID0gWydsZW5ndGgnXTtcblxuY29uc3Qgc3lzdGVtQ2xhc3NlcyA9IE9iamVjdC5mcmVlemUoW1xuICAnX1VzZXInLFxuICAnX0luc3RhbGxhdGlvbicsXG4gICdfUm9sZScsXG4gICdfU2Vzc2lvbicsXG4gICdfUHJvZHVjdCcsXG4gICdfUHVzaFN0YXR1cycsXG4gICdfSm9iU3RhdHVzJyxcbiAgJ19Kb2JTY2hlZHVsZScsXG4gICdfQXVkaWVuY2UnLFxuICAnX0lkZW1wb3RlbmN5Jyxcbl0pO1xuXG5jb25zdCB2b2xhdGlsZUNsYXNzZXMgPSBPYmplY3QuZnJlZXplKFtcbiAgJ19Kb2JTdGF0dXMnLFxuICAnX1B1c2hTdGF0dXMnLFxuICAnX0hvb2tzJyxcbiAgJ19HbG9iYWxDb25maWcnLFxuICAnX0dyYXBoUUxDb25maWcnLFxuICAnX0pvYlNjaGVkdWxlJyxcbiAgJ19BdWRpZW5jZScsXG4gICdfSWRlbXBvdGVuY3knLFxuXSk7XG5cbi8vIEFueXRoaW5nIHRoYXQgc3RhcnQgd2l0aCByb2xlXG5jb25zdCByb2xlUmVnZXggPSAvXnJvbGU6LiovO1xuLy8gQW55dGhpbmcgdGhhdCBzdGFydHMgd2l0aCB1c2VyRmllbGQgKGFsbG93ZWQgZm9yIHByb3RlY3RlZCBmaWVsZHMgb25seSlcbmNvbnN0IHByb3RlY3RlZEZpZWxkc1BvaW50ZXJSZWdleCA9IC9edXNlckZpZWxkOi4qLztcbi8vICogcGVybWlzc2lvblxuY29uc3QgcHVibGljUmVnZXggPSAvXlxcKiQvO1xuXG5jb25zdCBhdXRoZW50aWNhdGVkUmVnZXggPSAvXmF1dGhlbnRpY2F0ZWQkLztcblxuY29uc3QgcmVxdWlyZXNBdXRoZW50aWNhdGlvblJlZ2V4ID0gL15yZXF1aXJlc0F1dGhlbnRpY2F0aW9uJC87XG5cbmNvbnN0IGNscFBvaW50ZXJSZWdleCA9IC9ecG9pbnRlckZpZWxkcyQvO1xuXG4vLyByZWdleCBmb3IgdmFsaWRhdGluZyBlbnRpdGllcyBpbiBwcm90ZWN0ZWRGaWVsZHMgb2JqZWN0XG5jb25zdCBwcm90ZWN0ZWRGaWVsZHNSZWdleCA9IE9iamVjdC5mcmVlemUoW1xuICBwcm90ZWN0ZWRGaWVsZHNQb2ludGVyUmVnZXgsXG4gIHB1YmxpY1JlZ2V4LFxuICBhdXRoZW50aWNhdGVkUmVnZXgsXG4gIHJvbGVSZWdleCxcbl0pO1xuXG4vLyBjbHAgcmVnZXhcbmNvbnN0IGNscEZpZWxkc1JlZ2V4ID0gT2JqZWN0LmZyZWV6ZShbXG4gIGNscFBvaW50ZXJSZWdleCxcbiAgcHVibGljUmVnZXgsXG4gIHJlcXVpcmVzQXV0aGVudGljYXRpb25SZWdleCxcbiAgcm9sZVJlZ2V4LFxuXSk7XG5cbmZ1bmN0aW9uIHZhbGlkYXRlUGVybWlzc2lvbktleShrZXksIHVzZXJJZFJlZ0V4cCkge1xuICBsZXQgbWF0Y2hlc1NvbWUgPSBmYWxzZTtcbiAgZm9yIChjb25zdCByZWdFeCBvZiBjbHBGaWVsZHNSZWdleCkge1xuICAgIGlmIChrZXkubWF0Y2gocmVnRXgpICE9PSBudWxsKSB7XG4gICAgICBtYXRjaGVzU29tZSA9IHRydWU7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvLyB1c2VySWQgZGVwZW5kcyBvbiBzdGFydHVwIG9wdGlvbnMgc28gaXQncyBkeW5hbWljXG4gIGNvbnN0IHZhbGlkID0gbWF0Y2hlc1NvbWUgfHwga2V5Lm1hdGNoKHVzZXJJZFJlZ0V4cCkgIT09IG51bGw7XG4gIGlmICghdmFsaWQpIHtcbiAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICBgJyR7a2V5fScgaXMgbm90IGEgdmFsaWQga2V5IGZvciBjbGFzcyBsZXZlbCBwZXJtaXNzaW9uc2BcbiAgICApO1xuICB9XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlUHJvdGVjdGVkRmllbGRzS2V5KGtleSwgdXNlcklkUmVnRXhwKSB7XG4gIGxldCBtYXRjaGVzU29tZSA9IGZhbHNlO1xuICBmb3IgKGNvbnN0IHJlZ0V4IG9mIHByb3RlY3RlZEZpZWxkc1JlZ2V4KSB7XG4gICAgaWYgKGtleS5tYXRjaChyZWdFeCkgIT09IG51bGwpIHtcbiAgICAgIG1hdGNoZXNTb21lID0gdHJ1ZTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8vIHVzZXJJZCByZWdleCBkZXBlbmRzIG9uIGxhdW5jaCBvcHRpb25zIHNvIGl0J3MgZHluYW1pY1xuICBjb25zdCB2YWxpZCA9IG1hdGNoZXNTb21lIHx8IGtleS5tYXRjaCh1c2VySWRSZWdFeHApICE9PSBudWxsO1xuICBpZiAoIXZhbGlkKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgYCcke2tleX0nIGlzIG5vdCBhIHZhbGlkIGtleSBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnNgXG4gICAgKTtcbiAgfVxufVxuXG5jb25zdCBDTFBWYWxpZEtleXMgPSBPYmplY3QuZnJlZXplKFtcbiAgJ0FDTCcsXG4gICdmaW5kJyxcbiAgJ2NvdW50JyxcbiAgJ2dldCcsXG4gICdjcmVhdGUnLFxuICAndXBkYXRlJyxcbiAgJ2RlbGV0ZScsXG4gICdhZGRGaWVsZCcsXG4gICdyZWFkVXNlckZpZWxkcycsXG4gICd3cml0ZVVzZXJGaWVsZHMnLFxuICAncHJvdGVjdGVkRmllbGRzJyxcbl0pO1xuXG4vLyB2YWxpZGF0aW9uIGJlZm9yZSBzZXR0aW5nIGNsYXNzLWxldmVsIHBlcm1pc3Npb25zIG9uIGNvbGxlY3Rpb25cbmZ1bmN0aW9uIHZhbGlkYXRlQ0xQKHBlcm1zOiBDbGFzc0xldmVsUGVybWlzc2lvbnMsIGZpZWxkczogU2NoZW1hRmllbGRzLCB1c2VySWRSZWdFeHA6IFJlZ0V4cCkge1xuICBpZiAoIXBlcm1zKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGZvciAoY29uc3Qgb3BlcmF0aW9uS2V5IGluIHBlcm1zKSB7XG4gICAgaWYgKENMUFZhbGlkS2V5cy5pbmRleE9mKG9wZXJhdGlvbktleSkgPT0gLTEpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICBgJHtvcGVyYXRpb25LZXl9IGlzIG5vdCBhIHZhbGlkIG9wZXJhdGlvbiBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnNgXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IG9wZXJhdGlvbiA9IHBlcm1zW29wZXJhdGlvbktleV07XG4gICAgLy8gcHJvY2VlZCB3aXRoIG5leHQgb3BlcmF0aW9uS2V5XG5cbiAgICAvLyB0aHJvd3Mgd2hlbiByb290IGZpZWxkcyBhcmUgb2Ygd3JvbmcgdHlwZVxuICAgIHZhbGlkYXRlQ0xQanNvbihvcGVyYXRpb24sIG9wZXJhdGlvbktleSk7XG5cbiAgICBpZiAob3BlcmF0aW9uS2V5ID09PSAncmVhZFVzZXJGaWVsZHMnIHx8IG9wZXJhdGlvbktleSA9PT0gJ3dyaXRlVXNlckZpZWxkcycpIHtcbiAgICAgIC8vIHZhbGlkYXRlIGdyb3VwZWQgcG9pbnRlciBwZXJtaXNzaW9uc1xuICAgICAgLy8gbXVzdCBiZSBhbiBhcnJheSB3aXRoIGZpZWxkIG5hbWVzXG4gICAgICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBvZiBvcGVyYXRpb24pIHtcbiAgICAgICAgdmFsaWRhdGVQb2ludGVyUGVybWlzc2lvbihmaWVsZE5hbWUsIGZpZWxkcywgb3BlcmF0aW9uS2V5KTtcbiAgICAgIH1cbiAgICAgIC8vIHJlYWRVc2VyRmllbGRzIGFuZCB3cml0ZXJVc2VyRmllbGRzIGRvIG5vdCBoYXZlIG5lc2R0ZWQgZmllbGRzXG4gICAgICAvLyBwcm9jZWVkIHdpdGggbmV4dCBvcGVyYXRpb25LZXlcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIHZhbGlkYXRlIHByb3RlY3RlZCBmaWVsZHNcbiAgICBpZiAob3BlcmF0aW9uS2V5ID09PSAncHJvdGVjdGVkRmllbGRzJykge1xuICAgICAgZm9yIChjb25zdCBlbnRpdHkgaW4gb3BlcmF0aW9uKSB7XG4gICAgICAgIC8vIHRocm93cyBvbiB1bmV4cGVjdGVkIGtleVxuICAgICAgICB2YWxpZGF0ZVByb3RlY3RlZEZpZWxkc0tleShlbnRpdHksIHVzZXJJZFJlZ0V4cCk7XG5cbiAgICAgICAgY29uc3QgcHJvdGVjdGVkRmllbGRzID0gb3BlcmF0aW9uW2VudGl0eV07XG5cbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHByb3RlY3RlZEZpZWxkcykpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICBgJyR7cHJvdGVjdGVkRmllbGRzfScgaXMgbm90IGEgdmFsaWQgdmFsdWUgZm9yIHByb3RlY3RlZEZpZWxkc1ske2VudGl0eX1dIC0gZXhwZWN0ZWQgYW4gYXJyYXkuYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpZiB0aGUgZmllbGQgaXMgaW4gZm9ybSBvZiBhcnJheVxuICAgICAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIHByb3RlY3RlZEZpZWxkcykge1xuICAgICAgICAgIC8vIGRvIG5vdCBhbGxvb3cgdG8gcHJvdGVjdCBkZWZhdWx0IGZpZWxkc1xuICAgICAgICAgIGlmIChkZWZhdWx0Q29sdW1ucy5fRGVmYXVsdFtmaWVsZF0pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgICBgRGVmYXVsdCBmaWVsZCAnJHtmaWVsZH0nIGNhbiBub3QgYmUgcHJvdGVjdGVkYFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gZmllbGQgc2hvdWxkIGV4aXN0IG9uIGNvbGxlY3Rpb25cbiAgICAgICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChmaWVsZHMsIGZpZWxkKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICAgIGBGaWVsZCAnJHtmaWVsZH0nIGluIHByb3RlY3RlZEZpZWxkczoke2VudGl0eX0gZG9lcyBub3QgZXhpc3RgXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gcHJvY2VlZCB3aXRoIG5leHQgb3BlcmF0aW9uS2V5XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICAvLyB2YWxpZGF0ZSBvdGhlciBmaWVsZHNcbiAgICAvLyBFbnRpdHkgY2FuIGJlOlxuICAgIC8vIFwiKlwiIC0gUHVibGljLFxuICAgIC8vIFwicmVxdWlyZXNBdXRoZW50aWNhdGlvblwiIC0gYXV0aGVudGljYXRlZCB1c2VycyxcbiAgICAvLyBcIm9iamVjdElkXCIgLSBfVXNlciBpZCxcbiAgICAvLyBcInJvbGU6cm9sZW5hbWVcIixcbiAgICAvLyBcInBvaW50ZXJGaWVsZHNcIiAtIGFycmF5IG9mIGZpZWxkIG5hbWVzIGNvbnRhaW5pbmcgcG9pbnRlcnMgdG8gdXNlcnNcbiAgICBmb3IgKGNvbnN0IGVudGl0eSBpbiBvcGVyYXRpb24pIHtcbiAgICAgIC8vIHRocm93cyBvbiB1bmV4cGVjdGVkIGtleVxuICAgICAgdmFsaWRhdGVQZXJtaXNzaW9uS2V5KGVudGl0eSwgdXNlcklkUmVnRXhwKTtcblxuICAgICAgLy8gZW50aXR5IGNhbiBiZSBlaXRoZXI6XG4gICAgICAvLyBcInBvaW50ZXJGaWVsZHNcIjogc3RyaW5nW11cbiAgICAgIGlmIChlbnRpdHkgPT09ICdwb2ludGVyRmllbGRzJykge1xuICAgICAgICBjb25zdCBwb2ludGVyRmllbGRzID0gb3BlcmF0aW9uW2VudGl0eV07XG5cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocG9pbnRlckZpZWxkcykpIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IHBvaW50ZXJGaWVsZCBvZiBwb2ludGVyRmllbGRzKSB7XG4gICAgICAgICAgICB2YWxpZGF0ZVBvaW50ZXJQZXJtaXNzaW9uKHBvaW50ZXJGaWVsZCwgZmllbGRzLCBvcGVyYXRpb24pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICBgJyR7cG9pbnRlckZpZWxkc30nIGlzIG5vdCBhIHZhbGlkIHZhbHVlIGZvciAke29wZXJhdGlvbktleX1bJHtlbnRpdHl9XSAtIGV4cGVjdGVkIGFuIGFycmF5LmBcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIC8vIHByb2NlZWQgd2l0aCBuZXh0IGVudGl0eSBrZXlcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBlcm1pdCA9IG9wZXJhdGlvbltlbnRpdHldO1xuXG4gICAgICBpZiAob3BlcmF0aW9uS2V5ID09PSAnQUNMJykge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHBlcm1pdCkgIT09ICdbb2JqZWN0IE9iamVjdF0nKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgYCcke3Blcm1pdH0nIGlzIG5vdCBhIHZhbGlkIHZhbHVlIGZvciBjbGFzcyBsZXZlbCBwZXJtaXNzaW9ucyBhY2xgXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpbnZhbGlkS2V5cyA9IE9iamVjdC5rZXlzKHBlcm1pdCkuZmlsdGVyKGtleSA9PiAhWydyZWFkJywgJ3dyaXRlJ10uaW5jbHVkZXMoa2V5KSk7XG4gICAgICAgIGNvbnN0IGludmFsaWRWYWx1ZXMgPSBPYmplY3QudmFsdWVzKHBlcm1pdCkuZmlsdGVyKGtleSA9PiB0eXBlb2Yga2V5ICE9PSAnYm9vbGVhbicpO1xuICAgICAgICBpZiAoaW52YWxpZEtleXMubGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgICAgICAgYCcke2ludmFsaWRLZXlzLmpvaW4oJywnKX0nIGlzIG5vdCBhIHZhbGlkIGtleSBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnMgYWNsYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaW52YWxpZFZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgICBgJyR7aW52YWxpZFZhbHVlcy5qb2luKCcsJyl9JyBpcyBub3QgYSB2YWxpZCB2YWx1ZSBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnMgYWNsYFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAocGVybWl0ICE9PSB0cnVlKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgICAgYCcke3Blcm1pdH0nIGlzIG5vdCBhIHZhbGlkIHZhbHVlIGZvciBjbGFzcyBsZXZlbCBwZXJtaXNzaW9ucyBhY2wgJHtvcGVyYXRpb25LZXl9OiR7ZW50aXR5fWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVDTFBqc29uKG9wZXJhdGlvbjogYW55LCBvcGVyYXRpb25LZXk6IHN0cmluZykge1xuICBpZiAob3BlcmF0aW9uS2V5ID09PSAncmVhZFVzZXJGaWVsZHMnIHx8IG9wZXJhdGlvbktleSA9PT0gJ3dyaXRlVXNlckZpZWxkcycpIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkob3BlcmF0aW9uKSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgIGAnJHtvcGVyYXRpb259JyBpcyBub3QgYSB2YWxpZCB2YWx1ZSBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnMgJHtvcGVyYXRpb25LZXl9IC0gbXVzdCBiZSBhbiBhcnJheWBcbiAgICAgICk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmICh0eXBlb2Ygb3BlcmF0aW9uID09PSAnb2JqZWN0JyAmJiBvcGVyYXRpb24gIT09IG51bGwpIHtcbiAgICAgIC8vIG9rIHRvIHByb2NlZWRcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sXG4gICAgICAgIGAnJHtvcGVyYXRpb259JyBpcyBub3QgYSB2YWxpZCB2YWx1ZSBmb3IgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbnMgJHtvcGVyYXRpb25LZXl9IC0gbXVzdCBiZSBhbiBvYmplY3RgXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZVBvaW50ZXJQZXJtaXNzaW9uKGZpZWxkTmFtZTogc3RyaW5nLCBmaWVsZHM6IE9iamVjdCwgb3BlcmF0aW9uOiBzdHJpbmcpIHtcbiAgLy8gVXNlcyBjb2xsZWN0aW9uIHNjaGVtYSB0byBlbnN1cmUgdGhlIGZpZWxkIGlzIG9mIHR5cGU6XG4gIC8vIC0gUG9pbnRlcjxfVXNlcj4gKHBvaW50ZXJzKVxuICAvLyAtIEFycmF5XG4gIC8vXG4gIC8vICAgIEl0J3Mgbm90IHBvc3NpYmxlIHRvIGVuZm9yY2UgdHlwZSBvbiBBcnJheSdzIGl0ZW1zIGluIHNjaGVtYVxuICAvLyAgc28gd2UgYWNjZXB0IGFueSBBcnJheSBmaWVsZCwgYW5kIGxhdGVyIHdoZW4gYXBwbHlpbmcgcGVybWlzc2lvbnNcbiAgLy8gIG9ubHkgaXRlbXMgdGhhdCBhcmUgcG9pbnRlcnMgdG8gX1VzZXIgYXJlIGNvbnNpZGVyZWQuXG4gIGlmIChcbiAgICAhKFxuICAgICAgZmllbGRzW2ZpZWxkTmFtZV0gJiZcbiAgICAgICgoZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PSAnUG9pbnRlcicgJiYgZmllbGRzW2ZpZWxkTmFtZV0udGFyZ2V0Q2xhc3MgPT0gJ19Vc2VyJykgfHxcbiAgICAgICAgZmllbGRzW2ZpZWxkTmFtZV0udHlwZSA9PSAnQXJyYXknKVxuICAgIClcbiAgKSB7XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLFxuICAgICAgYCcke2ZpZWxkTmFtZX0nIGlzIG5vdCBhIHZhbGlkIGNvbHVtbiBmb3IgY2xhc3MgbGV2ZWwgcG9pbnRlciBwZXJtaXNzaW9ucyAke29wZXJhdGlvbn1gXG4gICAgKTtcbiAgfVxufVxuXG5jb25zdCBqb2luQ2xhc3NSZWdleCA9IC9eX0pvaW46W0EtWmEtejAtOV9dKzpbQS1aYS16MC05X10rLztcbmNvbnN0IGNsYXNzQW5kRmllbGRSZWdleCA9IC9eW0EtWmEtel1bQS1aYS16MC05X10qJC87XG5mdW5jdGlvbiBjbGFzc05hbWVJc1ZhbGlkKGNsYXNzTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIC8vIFZhbGlkIGNsYXNzZXMgbXVzdDpcbiAgcmV0dXJuIChcbiAgICAvLyBCZSBvbmUgb2YgX1VzZXIsIF9JbnN0YWxsYXRpb24sIF9Sb2xlLCBfU2Vzc2lvbiBPUlxuICAgIHN5c3RlbUNsYXNzZXMuaW5kZXhPZihjbGFzc05hbWUpID4gLTEgfHxcbiAgICAvLyBCZSBhIGpvaW4gdGFibGUgT1JcbiAgICBqb2luQ2xhc3NSZWdleC50ZXN0KGNsYXNzTmFtZSkgfHxcbiAgICAvLyBJbmNsdWRlIG9ubHkgYWxwaGEtbnVtZXJpYyBhbmQgdW5kZXJzY29yZXMsIGFuZCBub3Qgc3RhcnQgd2l0aCBhbiB1bmRlcnNjb3JlIG9yIG51bWJlclxuICAgIGZpZWxkTmFtZUlzVmFsaWQoY2xhc3NOYW1lLCBjbGFzc05hbWUpXG4gICk7XG59XG5cbi8vIFZhbGlkIGZpZWxkcyBtdXN0IGJlIGFscGhhLW51bWVyaWMsIGFuZCBub3Qgc3RhcnQgd2l0aCBhbiB1bmRlcnNjb3JlIG9yIG51bWJlclxuLy8gbXVzdCBub3QgYmUgYSByZXNlcnZlZCBrZXlcbmZ1bmN0aW9uIGZpZWxkTmFtZUlzVmFsaWQoZmllbGROYW1lOiBzdHJpbmcsIGNsYXNzTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmIChjbGFzc05hbWUgJiYgY2xhc3NOYW1lICE9PSAnX0hvb2tzJykge1xuICAgIGlmIChmaWVsZE5hbWUgPT09ICdjbGFzc05hbWUnKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiBjbGFzc0FuZEZpZWxkUmVnZXgudGVzdChmaWVsZE5hbWUpICYmICFpbnZhbGlkQ29sdW1ucy5pbmNsdWRlcyhmaWVsZE5hbWUpO1xufVxuXG4vLyBDaGVja3MgdGhhdCBpdCdzIG5vdCB0cnlpbmcgdG8gY2xvYmJlciBvbmUgb2YgdGhlIGRlZmF1bHQgZmllbGRzIG9mIHRoZSBjbGFzcy5cbmZ1bmN0aW9uIGZpZWxkTmFtZUlzVmFsaWRGb3JDbGFzcyhmaWVsZE5hbWU6IHN0cmluZywgY2xhc3NOYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgaWYgKCFmaWVsZE5hbWVJc1ZhbGlkKGZpZWxkTmFtZSwgY2xhc3NOYW1lKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoZGVmYXVsdENvbHVtbnMuX0RlZmF1bHRbZmllbGROYW1lXSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAoZGVmYXVsdENvbHVtbnNbY2xhc3NOYW1lXSAmJiBkZWZhdWx0Q29sdW1uc1tjbGFzc05hbWVdW2ZpZWxkTmFtZV0pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGludmFsaWRDbGFzc05hbWVNZXNzYWdlKGNsYXNzTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIChcbiAgICAnSW52YWxpZCBjbGFzc25hbWU6ICcgK1xuICAgIGNsYXNzTmFtZSArXG4gICAgJywgY2xhc3NuYW1lcyBjYW4gb25seSBoYXZlIGFscGhhbnVtZXJpYyBjaGFyYWN0ZXJzIGFuZCBfLCBhbmQgbXVzdCBzdGFydCB3aXRoIGFuIGFscGhhIGNoYXJhY3RlciAnXG4gICk7XG59XG5cbmNvbnN0IGludmFsaWRKc29uRXJyb3IgPSBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCAnaW52YWxpZCBKU09OJyk7XG5jb25zdCB2YWxpZE5vblJlbGF0aW9uT3JQb2ludGVyVHlwZXMgPSBbXG4gICdOdW1iZXInLFxuICAnU3RyaW5nJyxcbiAgJ0Jvb2xlYW4nLFxuICAnRGF0ZScsXG4gICdPYmplY3QnLFxuICAnQXJyYXknLFxuICAnR2VvUG9pbnQnLFxuICAnRmlsZScsXG4gICdCeXRlcycsXG4gICdQb2x5Z29uJyxcbl07XG4vLyBSZXR1cm5zIGFuIGVycm9yIHN1aXRhYmxlIGZvciB0aHJvd2luZyBpZiB0aGUgdHlwZSBpcyBpbnZhbGlkXG5jb25zdCBmaWVsZFR5cGVJc0ludmFsaWQgPSAoeyB0eXBlLCB0YXJnZXRDbGFzcyB9KSA9PiB7XG4gIGlmIChbJ1BvaW50ZXInLCAnUmVsYXRpb24nXS5pbmRleE9mKHR5cGUpID49IDApIHtcbiAgICBpZiAoIXRhcmdldENsYXNzKSB7XG4gICAgICByZXR1cm4gbmV3IFBhcnNlLkVycm9yKDEzNSwgYHR5cGUgJHt0eXBlfSBuZWVkcyBhIGNsYXNzIG5hbWVgKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB0YXJnZXRDbGFzcyAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBpbnZhbGlkSnNvbkVycm9yO1xuICAgIH0gZWxzZSBpZiAoIWNsYXNzTmFtZUlzVmFsaWQodGFyZ2V0Q2xhc3MpKSB7XG4gICAgICByZXR1cm4gbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSwgaW52YWxpZENsYXNzTmFtZU1lc3NhZ2UodGFyZ2V0Q2xhc3MpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbiAgaWYgKHR5cGVvZiB0eXBlICE9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBpbnZhbGlkSnNvbkVycm9yO1xuICB9XG4gIGlmICh2YWxpZE5vblJlbGF0aW9uT3JQb2ludGVyVHlwZXMuaW5kZXhPZih0eXBlKSA8IDApIHtcbiAgICByZXR1cm4gbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLCBgaW52YWxpZCBmaWVsZCB0eXBlOiAke3R5cGV9YCk7XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn07XG5cbmNvbnN0IGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEgPSAoc2NoZW1hOiBhbnkpID0+IHtcbiAgc2NoZW1hID0gaW5qZWN0RGVmYXVsdFNjaGVtYShzY2hlbWEpO1xuICBkZWxldGUgc2NoZW1hLmZpZWxkcy5BQ0w7XG4gIHNjaGVtYS5maWVsZHMuX3JwZXJtID0geyB0eXBlOiAnQXJyYXknIH07XG4gIHNjaGVtYS5maWVsZHMuX3dwZXJtID0geyB0eXBlOiAnQXJyYXknIH07XG5cbiAgaWYgKHNjaGVtYS5jbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICBkZWxldGUgc2NoZW1hLmZpZWxkcy5wYXNzd29yZDtcbiAgICBzY2hlbWEuZmllbGRzLl9oYXNoZWRfcGFzc3dvcmQgPSB7IHR5cGU6ICdTdHJpbmcnIH07XG4gIH1cblxuICByZXR1cm4gc2NoZW1hO1xufTtcblxuY29uc3QgY29udmVydEFkYXB0ZXJTY2hlbWFUb1BhcnNlU2NoZW1hID0gKHsgLi4uc2NoZW1hIH0pID0+IHtcbiAgZGVsZXRlIHNjaGVtYS5maWVsZHMuX3JwZXJtO1xuICBkZWxldGUgc2NoZW1hLmZpZWxkcy5fd3Blcm07XG5cbiAgc2NoZW1hLmZpZWxkcy5BQ0wgPSB7IHR5cGU6ICdBQ0wnIH07XG5cbiAgaWYgKHNjaGVtYS5jbGFzc05hbWUgPT09ICdfVXNlcicpIHtcbiAgICBkZWxldGUgc2NoZW1hLmZpZWxkcy5hdXRoRGF0YTsgLy9BdXRoIGRhdGEgaXMgaW1wbGljaXRcbiAgICBkZWxldGUgc2NoZW1hLmZpZWxkcy5faGFzaGVkX3Bhc3N3b3JkO1xuICAgIHNjaGVtYS5maWVsZHMucGFzc3dvcmQgPSB7IHR5cGU6ICdTdHJpbmcnIH07XG4gIH1cblxuICBpZiAoc2NoZW1hLmluZGV4ZXMgJiYgT2JqZWN0LmtleXMoc2NoZW1hLmluZGV4ZXMpLmxlbmd0aCA9PT0gMCkge1xuICAgIGRlbGV0ZSBzY2hlbWEuaW5kZXhlcztcbiAgfVxuXG4gIHJldHVybiBzY2hlbWE7XG59O1xuXG5jbGFzcyBTY2hlbWFEYXRhIHtcbiAgX19kYXRhOiBhbnk7XG4gIF9fcHJvdGVjdGVkRmllbGRzOiBhbnk7XG4gIGNvbnN0cnVjdG9yKGFsbFNjaGVtYXMgPSBbXSwgcHJvdGVjdGVkRmllbGRzID0ge30pIHtcbiAgICB0aGlzLl9fZGF0YSA9IHt9O1xuICAgIHRoaXMuX19wcm90ZWN0ZWRGaWVsZHMgPSBwcm90ZWN0ZWRGaWVsZHM7XG4gICAgYWxsU2NoZW1hcy5mb3JFYWNoKHNjaGVtYSA9PiB7XG4gICAgICBpZiAodm9sYXRpbGVDbGFzc2VzLmluY2x1ZGVzKHNjaGVtYS5jbGFzc05hbWUpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBzY2hlbWEuY2xhc3NOYW1lLCB7XG4gICAgICAgIGdldDogKCkgPT4ge1xuICAgICAgICAgIGlmICghdGhpcy5fX2RhdGFbc2NoZW1hLmNsYXNzTmFtZV0pIHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSB7fTtcbiAgICAgICAgICAgIGRhdGEuZmllbGRzID0gaW5qZWN0RGVmYXVsdFNjaGVtYShzY2hlbWEpLmZpZWxkcztcbiAgICAgICAgICAgIGRhdGEuY2xhc3NMZXZlbFBlcm1pc3Npb25zID0gZGVlcGNvcHkoc2NoZW1hLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucyk7XG4gICAgICAgICAgICBkYXRhLmluZGV4ZXMgPSBzY2hlbWEuaW5kZXhlcztcblxuICAgICAgICAgICAgY29uc3QgY2xhc3NQcm90ZWN0ZWRGaWVsZHMgPSB0aGlzLl9fcHJvdGVjdGVkRmllbGRzW3NjaGVtYS5jbGFzc05hbWVdO1xuICAgICAgICAgICAgaWYgKGNsYXNzUHJvdGVjdGVkRmllbGRzKSB7XG4gICAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIGNsYXNzUHJvdGVjdGVkRmllbGRzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdW5xID0gbmV3IFNldChbXG4gICAgICAgICAgICAgICAgICAuLi4oZGF0YS5jbGFzc0xldmVsUGVybWlzc2lvbnMucHJvdGVjdGVkRmllbGRzW2tleV0gfHwgW10pLFxuICAgICAgICAgICAgICAgICAgLi4uY2xhc3NQcm90ZWN0ZWRGaWVsZHNba2V5XSxcbiAgICAgICAgICAgICAgICBdKTtcbiAgICAgICAgICAgICAgICBkYXRhLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucy5wcm90ZWN0ZWRGaWVsZHNba2V5XSA9IEFycmF5LmZyb20odW5xKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLl9fZGF0YVtzY2hlbWEuY2xhc3NOYW1lXSA9IGRhdGE7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0aGlzLl9fZGF0YVtzY2hlbWEuY2xhc3NOYW1lXTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gSW5qZWN0IHRoZSBpbi1tZW1vcnkgY2xhc3Nlc1xuICAgIHZvbGF0aWxlQ2xhc3Nlcy5mb3JFYWNoKGNsYXNzTmFtZSA9PiB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgY2xhc3NOYW1lLCB7XG4gICAgICAgIGdldDogKCkgPT4ge1xuICAgICAgICAgIGlmICghdGhpcy5fX2RhdGFbY2xhc3NOYW1lXSkge1xuICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0gaW5qZWN0RGVmYXVsdFNjaGVtYSh7XG4gICAgICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgZmllbGRzOiB7fSxcbiAgICAgICAgICAgICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiB7fSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY29uc3QgZGF0YSA9IHt9O1xuICAgICAgICAgICAgZGF0YS5maWVsZHMgPSBzY2hlbWEuZmllbGRzO1xuICAgICAgICAgICAgZGF0YS5jbGFzc0xldmVsUGVybWlzc2lvbnMgPSBzY2hlbWEuY2xhc3NMZXZlbFBlcm1pc3Npb25zO1xuICAgICAgICAgICAgZGF0YS5pbmRleGVzID0gc2NoZW1hLmluZGV4ZXM7XG4gICAgICAgICAgICB0aGlzLl9fZGF0YVtjbGFzc05hbWVdID0gZGF0YTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRoaXMuX19kYXRhW2NsYXNzTmFtZV07XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxufVxuXG5jb25zdCBpbmplY3REZWZhdWx0U2NoZW1hID0gKHsgY2xhc3NOYW1lLCBmaWVsZHMsIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgaW5kZXhlcyB9OiBTY2hlbWEpID0+IHtcbiAgY29uc3QgZGVmYXVsdFNjaGVtYTogU2NoZW1hID0ge1xuICAgIGNsYXNzTmFtZSxcbiAgICBmaWVsZHM6IHtcbiAgICAgIC4uLmRlZmF1bHRDb2x1bW5zLl9EZWZhdWx0LFxuICAgICAgLi4uKGRlZmF1bHRDb2x1bW5zW2NsYXNzTmFtZV0gfHwge30pLFxuICAgICAgLi4uZmllbGRzLFxuICAgIH0sXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICB9O1xuICBpZiAoaW5kZXhlcyAmJiBPYmplY3Qua2V5cyhpbmRleGVzKS5sZW5ndGggIT09IDApIHtcbiAgICBkZWZhdWx0U2NoZW1hLmluZGV4ZXMgPSBpbmRleGVzO1xuICB9XG4gIHJldHVybiBkZWZhdWx0U2NoZW1hO1xufTtcblxuY29uc3QgX0hvb2tzU2NoZW1hID0geyBjbGFzc05hbWU6ICdfSG9va3MnLCBmaWVsZHM6IGRlZmF1bHRDb2x1bW5zLl9Ib29rcyB9O1xuY29uc3QgX0dsb2JhbENvbmZpZ1NjaGVtYSA9IHtcbiAgY2xhc3NOYW1lOiAnX0dsb2JhbENvbmZpZycsXG4gIGZpZWxkczogZGVmYXVsdENvbHVtbnMuX0dsb2JhbENvbmZpZyxcbn07XG5jb25zdCBfR3JhcGhRTENvbmZpZ1NjaGVtYSA9IHtcbiAgY2xhc3NOYW1lOiAnX0dyYXBoUUxDb25maWcnLFxuICBmaWVsZHM6IGRlZmF1bHRDb2x1bW5zLl9HcmFwaFFMQ29uZmlnLFxufTtcbmNvbnN0IF9QdXNoU3RhdHVzU2NoZW1hID0gY29udmVydFNjaGVtYVRvQWRhcHRlclNjaGVtYShcbiAgaW5qZWN0RGVmYXVsdFNjaGVtYSh7XG4gICAgY2xhc3NOYW1lOiAnX1B1c2hTdGF0dXMnLFxuICAgIGZpZWxkczoge30sXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiB7fSxcbiAgfSlcbik7XG5jb25zdCBfSm9iU3RhdHVzU2NoZW1hID0gY29udmVydFNjaGVtYVRvQWRhcHRlclNjaGVtYShcbiAgaW5qZWN0RGVmYXVsdFNjaGVtYSh7XG4gICAgY2xhc3NOYW1lOiAnX0pvYlN0YXR1cycsXG4gICAgZmllbGRzOiB7fSxcbiAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IHt9LFxuICB9KVxuKTtcbmNvbnN0IF9Kb2JTY2hlZHVsZVNjaGVtYSA9IGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEoXG4gIGluamVjdERlZmF1bHRTY2hlbWEoe1xuICAgIGNsYXNzTmFtZTogJ19Kb2JTY2hlZHVsZScsXG4gICAgZmllbGRzOiB7fSxcbiAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IHt9LFxuICB9KVxuKTtcbmNvbnN0IF9BdWRpZW5jZVNjaGVtYSA9IGNvbnZlcnRTY2hlbWFUb0FkYXB0ZXJTY2hlbWEoXG4gIGluamVjdERlZmF1bHRTY2hlbWEoe1xuICAgIGNsYXNzTmFtZTogJ19BdWRpZW5jZScsXG4gICAgZmllbGRzOiBkZWZhdWx0Q29sdW1ucy5fQXVkaWVuY2UsXG4gICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiB7fSxcbiAgfSlcbik7XG5jb25zdCBfSWRlbXBvdGVuY3lTY2hlbWEgPSBjb252ZXJ0U2NoZW1hVG9BZGFwdGVyU2NoZW1hKFxuICBpbmplY3REZWZhdWx0U2NoZW1hKHtcbiAgICBjbGFzc05hbWU6ICdfSWRlbXBvdGVuY3knLFxuICAgIGZpZWxkczogZGVmYXVsdENvbHVtbnMuX0lkZW1wb3RlbmN5LFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczoge30sXG4gIH0pXG4pO1xuY29uc3QgVm9sYXRpbGVDbGFzc2VzU2NoZW1hcyA9IFtcbiAgX0hvb2tzU2NoZW1hLFxuICBfSm9iU3RhdHVzU2NoZW1hLFxuICBfSm9iU2NoZWR1bGVTY2hlbWEsXG4gIF9QdXNoU3RhdHVzU2NoZW1hLFxuICBfR2xvYmFsQ29uZmlnU2NoZW1hLFxuICBfR3JhcGhRTENvbmZpZ1NjaGVtYSxcbiAgX0F1ZGllbmNlU2NoZW1hLFxuICBfSWRlbXBvdGVuY3lTY2hlbWEsXG5dO1xuXG5jb25zdCBkYlR5cGVNYXRjaGVzT2JqZWN0VHlwZSA9IChkYlR5cGU6IFNjaGVtYUZpZWxkIHwgc3RyaW5nLCBvYmplY3RUeXBlOiBTY2hlbWFGaWVsZCkgPT4ge1xuICBpZiAoZGJUeXBlLnR5cGUgIT09IG9iamVjdFR5cGUudHlwZSkgeyByZXR1cm4gZmFsc2U7IH1cbiAgaWYgKGRiVHlwZS50YXJnZXRDbGFzcyAhPT0gb2JqZWN0VHlwZS50YXJnZXRDbGFzcykgeyByZXR1cm4gZmFsc2U7IH1cbiAgaWYgKGRiVHlwZSA9PT0gb2JqZWN0VHlwZS50eXBlKSB7IHJldHVybiB0cnVlOyB9XG4gIGlmIChkYlR5cGUudHlwZSA9PT0gb2JqZWN0VHlwZS50eXBlKSB7IHJldHVybiB0cnVlOyB9XG4gIHJldHVybiBmYWxzZTtcbn07XG5cbmNvbnN0IHR5cGVUb1N0cmluZyA9ICh0eXBlOiBTY2hlbWFGaWVsZCB8IHN0cmluZyk6IHN0cmluZyA9PiB7XG4gIGlmICh0eXBlb2YgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdHlwZTtcbiAgfVxuICBpZiAodHlwZS50YXJnZXRDbGFzcykge1xuICAgIHJldHVybiBgJHt0eXBlLnR5cGV9PCR7dHlwZS50YXJnZXRDbGFzc30+YDtcbiAgfVxuICByZXR1cm4gYCR7dHlwZS50eXBlfWA7XG59O1xuY29uc3QgdHRsID0ge1xuICBkYXRlOiBEYXRlLm5vdygpLFxuICBkdXJhdGlvbjogdW5kZWZpbmVkLFxufTtcblxuLy8gU3RvcmVzIHRoZSBlbnRpcmUgc2NoZW1hIG9mIHRoZSBhcHAgaW4gYSB3ZWlyZCBoeWJyaWQgZm9ybWF0IHNvbWV3aGVyZSBiZXR3ZWVuXG4vLyB0aGUgbW9uZ28gZm9ybWF0IGFuZCB0aGUgUGFyc2UgZm9ybWF0LiBTb29uLCB0aGlzIHdpbGwgYWxsIGJlIFBhcnNlIGZvcm1hdC5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNjaGVtYUNvbnRyb2xsZXIge1xuICBfZGJBZGFwdGVyOiBTdG9yYWdlQWRhcHRlcjtcbiAgc2NoZW1hRGF0YTogeyBbc3RyaW5nXTogU2NoZW1hIH07XG4gIHJlbG9hZERhdGFQcm9taXNlOiA/UHJvbWlzZTxhbnk+O1xuICBwcm90ZWN0ZWRGaWVsZHM6IGFueTtcbiAgdXNlcklkUmVnRXg6IFJlZ0V4cDtcblxuICBjb25zdHJ1Y3RvcihkYXRhYmFzZUFkYXB0ZXI6IFN0b3JhZ2VBZGFwdGVyKSB7XG4gICAgdGhpcy5fZGJBZGFwdGVyID0gZGF0YWJhc2VBZGFwdGVyO1xuICAgIGNvbnN0IGNvbmZpZyA9IENvbmZpZy5nZXQoUGFyc2UuYXBwbGljYXRpb25JZCk7XG4gICAgdGhpcy5zY2hlbWFEYXRhID0gbmV3IFNjaGVtYURhdGEoU2NoZW1hQ2FjaGUuYWxsKCksIHRoaXMucHJvdGVjdGVkRmllbGRzKTtcbiAgICB0aGlzLnByb3RlY3RlZEZpZWxkcyA9IGNvbmZpZy5wcm90ZWN0ZWRGaWVsZHM7XG5cbiAgICBjb25zdCBjdXN0b21JZHMgPSBjb25maWcuYWxsb3dDdXN0b21PYmplY3RJZDtcblxuICAgIGNvbnN0IGN1c3RvbUlkUmVnRXggPSAvXi57MSx9JC91OyAvLyAxKyBjaGFyc1xuICAgIGNvbnN0IGF1dG9JZFJlZ0V4ID0gL15bYS16QS1aMC05XXsxLH0kLztcblxuICAgIHRoaXMudXNlcklkUmVnRXggPSBjdXN0b21JZHMgPyBjdXN0b21JZFJlZ0V4IDogYXV0b0lkUmVnRXg7XG5cbiAgICB0aGlzLl9kYkFkYXB0ZXIud2F0Y2goKCkgPT4ge1xuICAgICAgdGhpcy5yZWxvYWREYXRhKHsgY2xlYXJDYWNoZTogdHJ1ZSB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHJlbG9hZERhdGFJZk5lZWRlZCgpIHtcbiAgICBpZiAodGhpcy5fZGJBZGFwdGVyLmVuYWJsZVNjaGVtYUhvb2tzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHsgZGF0ZSwgZHVyYXRpb24gfSA9IHR0bCB8fCB7fTtcbiAgICBpZiAoIWR1cmF0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgaWYgKG5vdyAtIGRhdGUgPiBkdXJhdGlvbikge1xuICAgICAgdHRsLmRhdGUgPSBub3c7XG4gICAgICBhd2FpdCB0aGlzLnJlbG9hZERhdGEoeyBjbGVhckNhY2hlOiB0cnVlIH0pO1xuICAgIH1cbiAgfVxuXG4gIHJlbG9hZERhdGEob3B0aW9uczogTG9hZFNjaGVtYU9wdGlvbnMgPSB7IGNsZWFyQ2FjaGU6IGZhbHNlIH0pOiBQcm9taXNlPGFueT4ge1xuICAgIGlmICh0aGlzLnJlbG9hZERhdGFQcm9taXNlICYmICFvcHRpb25zLmNsZWFyQ2FjaGUpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlbG9hZERhdGFQcm9taXNlO1xuICAgIH1cbiAgICB0aGlzLnJlbG9hZERhdGFQcm9taXNlID0gdGhpcy5nZXRBbGxDbGFzc2VzKG9wdGlvbnMpXG4gICAgICAudGhlbihcbiAgICAgICAgYWxsU2NoZW1hcyA9PiB7XG4gICAgICAgICAgdGhpcy5zY2hlbWFEYXRhID0gbmV3IFNjaGVtYURhdGEoYWxsU2NoZW1hcywgdGhpcy5wcm90ZWN0ZWRGaWVsZHMpO1xuICAgICAgICAgIGRlbGV0ZSB0aGlzLnJlbG9hZERhdGFQcm9taXNlO1xuICAgICAgICB9LFxuICAgICAgICBlcnIgPT4ge1xuICAgICAgICAgIHRoaXMuc2NoZW1hRGF0YSA9IG5ldyBTY2hlbWFEYXRhKCk7XG4gICAgICAgICAgZGVsZXRlIHRoaXMucmVsb2FkRGF0YVByb21pc2U7XG4gICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICApXG4gICAgICAudGhlbigoKSA9PiB7fSk7XG4gICAgcmV0dXJuIHRoaXMucmVsb2FkRGF0YVByb21pc2U7XG4gIH1cblxuICBhc3luYyBnZXRBbGxDbGFzc2VzKG9wdGlvbnM6IExvYWRTY2hlbWFPcHRpb25zID0geyBjbGVhckNhY2hlOiBmYWxzZSB9KTogUHJvbWlzZTxBcnJheTxTY2hlbWE+PiB7XG4gICAgaWYgKG9wdGlvbnMuY2xlYXJDYWNoZSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2V0QWxsQ2xhc3NlcygpO1xuICAgIH1cbiAgICBhd2FpdCB0aGlzLnJlbG9hZERhdGFJZk5lZWRlZCgpO1xuICAgIGNvbnN0IGNhY2hlZCA9IFNjaGVtYUNhY2hlLmFsbCgpO1xuICAgIGlmIChjYWNoZWQgJiYgY2FjaGVkLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShjYWNoZWQpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zZXRBbGxDbGFzc2VzKCk7XG4gIH1cblxuICBzZXRBbGxDbGFzc2VzKCk6IFByb21pc2U8QXJyYXk8U2NoZW1hPj4ge1xuICAgIHJldHVybiB0aGlzLl9kYkFkYXB0ZXJcbiAgICAgIC5nZXRBbGxDbGFzc2VzKClcbiAgICAgIC50aGVuKGFsbFNjaGVtYXMgPT4gYWxsU2NoZW1hcy5tYXAoaW5qZWN0RGVmYXVsdFNjaGVtYSkpXG4gICAgICAudGhlbihhbGxTY2hlbWFzID0+IHtcbiAgICAgICAgU2NoZW1hQ2FjaGUucHV0KGFsbFNjaGVtYXMpO1xuICAgICAgICByZXR1cm4gYWxsU2NoZW1hcztcbiAgICAgIH0pO1xuICB9XG5cbiAgZ2V0T25lU2NoZW1hKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIGFsbG93Vm9sYXRpbGVDbGFzc2VzOiBib29sZWFuID0gZmFsc2UsXG4gICAgb3B0aW9uczogTG9hZFNjaGVtYU9wdGlvbnMgPSB7IGNsZWFyQ2FjaGU6IGZhbHNlIH1cbiAgKTogUHJvbWlzZTxTY2hlbWE+IHtcbiAgICBpZiAob3B0aW9ucy5jbGVhckNhY2hlKSB7XG4gICAgICBTY2hlbWFDYWNoZS5jbGVhcigpO1xuICAgIH1cbiAgICBpZiAoYWxsb3dWb2xhdGlsZUNsYXNzZXMgJiYgdm9sYXRpbGVDbGFzc2VzLmluZGV4T2YoY2xhc3NOYW1lKSA+IC0xKSB7XG4gICAgICBjb25zdCBkYXRhID0gdGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV07XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHtcbiAgICAgICAgY2xhc3NOYW1lLFxuICAgICAgICBmaWVsZHM6IGRhdGEuZmllbGRzLFxuICAgICAgICBjbGFzc0xldmVsUGVybWlzc2lvbnM6IGRhdGEuY2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICAgICAgICBpbmRleGVzOiBkYXRhLmluZGV4ZXMsXG4gICAgICB9KTtcbiAgICB9XG4gICAgY29uc3QgY2FjaGVkID0gU2NoZW1hQ2FjaGUuZ2V0KGNsYXNzTmFtZSk7XG4gICAgaWYgKGNhY2hlZCAmJiAhb3B0aW9ucy5jbGVhckNhY2hlKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGNhY2hlZCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNldEFsbENsYXNzZXMoKS50aGVuKGFsbFNjaGVtYXMgPT4ge1xuICAgICAgY29uc3Qgb25lU2NoZW1hID0gYWxsU2NoZW1hcy5maW5kKHNjaGVtYSA9PiBzY2hlbWEuY2xhc3NOYW1lID09PSBjbGFzc05hbWUpO1xuICAgICAgaWYgKCFvbmVTY2hlbWEpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KHVuZGVmaW5lZCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gb25lU2NoZW1hO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gQ3JlYXRlIGEgbmV3IGNsYXNzIHRoYXQgaW5jbHVkZXMgdGhlIHRocmVlIGRlZmF1bHQgZmllbGRzLlxuICAvLyBBQ0wgaXMgYW4gaW1wbGljaXQgY29sdW1uIHRoYXQgZG9lcyBub3QgZ2V0IGFuIGVudHJ5IGluIHRoZVxuICAvLyBfU0NIRU1BUyBkYXRhYmFzZS4gUmV0dXJucyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZVxuICAvLyBjcmVhdGVkIHNjaGVtYSwgaW4gbW9uZ28gZm9ybWF0LlxuICAvLyBvbiBzdWNjZXNzLCBhbmQgcmVqZWN0cyB3aXRoIGFuIGVycm9yIG9uIGZhaWwuIEVuc3VyZSB5b3VcbiAgLy8gaGF2ZSBhdXRob3JpemF0aW9uIChtYXN0ZXIga2V5LCBvciBjbGllbnQgY2xhc3MgY3JlYXRpb25cbiAgLy8gZW5hYmxlZCkgYmVmb3JlIGNhbGxpbmcgdGhpcyBmdW5jdGlvbi5cbiAgYXN5bmMgYWRkQ2xhc3NJZk5vdEV4aXN0cyhcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBmaWVsZHM6IFNjaGVtYUZpZWxkcyA9IHt9LFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogYW55LFxuICAgIGluZGV4ZXM6IGFueSA9IHt9XG4gICk6IFByb21pc2U8dm9pZCB8IFNjaGVtYT4ge1xuICAgIHZhciB2YWxpZGF0aW9uRXJyb3IgPSB0aGlzLnZhbGlkYXRlTmV3Q2xhc3MoY2xhc3NOYW1lLCBmaWVsZHMsIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyk7XG4gICAgaWYgKHZhbGlkYXRpb25FcnJvcikge1xuICAgICAgaWYgKHZhbGlkYXRpb25FcnJvciBpbnN0YW5jZW9mIFBhcnNlLkVycm9yKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdCh2YWxpZGF0aW9uRXJyb3IpO1xuICAgICAgfSBlbHNlIGlmICh2YWxpZGF0aW9uRXJyb3IuY29kZSAmJiB2YWxpZGF0aW9uRXJyb3IuZXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBQYXJzZS5FcnJvcih2YWxpZGF0aW9uRXJyb3IuY29kZSwgdmFsaWRhdGlvbkVycm9yLmVycm9yKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QodmFsaWRhdGlvbkVycm9yKTtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGFkYXB0ZXJTY2hlbWEgPSBhd2FpdCB0aGlzLl9kYkFkYXB0ZXIuY3JlYXRlQ2xhc3MoXG4gICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgY29udmVydFNjaGVtYVRvQWRhcHRlclNjaGVtYSh7XG4gICAgICAgICAgZmllbGRzLFxuICAgICAgICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgICAgICBpbmRleGVzLFxuICAgICAgICAgIGNsYXNzTmFtZSxcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgICAvLyBUT0RPOiBSZW1vdmUgYnkgdXBkYXRpbmcgc2NoZW1hIGNhY2hlIGRpcmVjdGx5XG4gICAgICBhd2FpdCB0aGlzLnJlbG9hZERhdGEoeyBjbGVhckNhY2hlOiB0cnVlIH0pO1xuICAgICAgY29uc3QgcGFyc2VTY2hlbWEgPSBjb252ZXJ0QWRhcHRlclNjaGVtYVRvUGFyc2VTY2hlbWEoYWRhcHRlclNjaGVtYSk7XG4gICAgICByZXR1cm4gcGFyc2VTY2hlbWE7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciAmJiBlcnJvci5jb2RlID09PSBQYXJzZS5FcnJvci5EVVBMSUNBVEVfVkFMVUUpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSwgYENsYXNzICR7Y2xhc3NOYW1lfSBhbHJlYWR5IGV4aXN0cy5gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZUNsYXNzKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIHN1Ym1pdHRlZEZpZWxkczogU2NoZW1hRmllbGRzLFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogYW55LFxuICAgIGluZGV4ZXM6IGFueSxcbiAgICBkYXRhYmFzZTogRGF0YWJhc2VDb250cm9sbGVyXG4gICkge1xuICAgIHJldHVybiB0aGlzLmdldE9uZVNjaGVtYShjbGFzc05hbWUpXG4gICAgICAudGhlbihzY2hlbWEgPT4ge1xuICAgICAgICBjb25zdCBleGlzdGluZ0ZpZWxkcyA9IHNjaGVtYS5maWVsZHM7XG4gICAgICAgIE9iamVjdC5rZXlzKHN1Ym1pdHRlZEZpZWxkcykuZm9yRWFjaChuYW1lID0+IHtcbiAgICAgICAgICBjb25zdCBmaWVsZCA9IHN1Ym1pdHRlZEZpZWxkc1tuYW1lXTtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBleGlzdGluZ0ZpZWxkc1tuYW1lXSAmJlxuICAgICAgICAgICAgZXhpc3RpbmdGaWVsZHNbbmFtZV0udHlwZSAhPT0gZmllbGQudHlwZSAmJlxuICAgICAgICAgICAgZmllbGQuX19vcCAhPT0gJ0RlbGV0ZSdcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigyNTUsIGBGaWVsZCAke25hbWV9IGV4aXN0cywgY2Fubm90IHVwZGF0ZS5gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFleGlzdGluZ0ZpZWxkc1tuYW1lXSAmJiBmaWVsZC5fX29wID09PSAnRGVsZXRlJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDI1NSwgYEZpZWxkICR7bmFtZX0gZG9lcyBub3QgZXhpc3QsIGNhbm5vdCBkZWxldGUuYCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBkZWxldGUgZXhpc3RpbmdGaWVsZHMuX3JwZXJtO1xuICAgICAgICBkZWxldGUgZXhpc3RpbmdGaWVsZHMuX3dwZXJtO1xuICAgICAgICBjb25zdCBuZXdTY2hlbWEgPSBidWlsZE1lcmdlZFNjaGVtYU9iamVjdChleGlzdGluZ0ZpZWxkcywgc3VibWl0dGVkRmllbGRzKTtcbiAgICAgICAgY29uc3QgZGVmYXVsdEZpZWxkcyA9IGRlZmF1bHRDb2x1bW5zW2NsYXNzTmFtZV0gfHwgZGVmYXVsdENvbHVtbnMuX0RlZmF1bHQ7XG4gICAgICAgIGNvbnN0IGZ1bGxOZXdTY2hlbWEgPSBPYmplY3QuYXNzaWduKHt9LCBuZXdTY2hlbWEsIGRlZmF1bHRGaWVsZHMpO1xuICAgICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3IgPSB0aGlzLnZhbGlkYXRlU2NoZW1hRGF0YShcbiAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgbmV3U2NoZW1hLFxuICAgICAgICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucyxcbiAgICAgICAgICBPYmplY3Qua2V5cyhleGlzdGluZ0ZpZWxkcylcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKHZhbGlkYXRpb25FcnJvcikge1xuICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcih2YWxpZGF0aW9uRXJyb3IuY29kZSwgdmFsaWRhdGlvbkVycm9yLmVycm9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZpbmFsbHkgd2UgaGF2ZSBjaGVja2VkIHRvIG1ha2Ugc3VyZSB0aGUgcmVxdWVzdCBpcyB2YWxpZCBhbmQgd2UgY2FuIHN0YXJ0IGRlbGV0aW5nIGZpZWxkcy5cbiAgICAgICAgLy8gRG8gYWxsIGRlbGV0aW9ucyBmaXJzdCwgdGhlbiBhIHNpbmdsZSBzYXZlIHRvIF9TQ0hFTUEgY29sbGVjdGlvbiB0byBoYW5kbGUgYWxsIGFkZGl0aW9ucy5cbiAgICAgICAgY29uc3QgZGVsZXRlZEZpZWxkczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgY29uc3QgaW5zZXJ0ZWRGaWVsZHMgPSBbXTtcbiAgICAgICAgT2JqZWN0LmtleXMoc3VibWl0dGVkRmllbGRzKS5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICAgICAgaWYgKHN1Ym1pdHRlZEZpZWxkc1tmaWVsZE5hbWVdLl9fb3AgPT09ICdEZWxldGUnKSB7XG4gICAgICAgICAgICBkZWxldGVkRmllbGRzLnB1c2goZmllbGROYW1lKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaW5zZXJ0ZWRGaWVsZHMucHVzaChmaWVsZE5hbWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgbGV0IGRlbGV0ZVByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgaWYgKGRlbGV0ZWRGaWVsZHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGRlbGV0ZVByb21pc2UgPSB0aGlzLmRlbGV0ZUZpZWxkcyhkZWxldGVkRmllbGRzLCBjbGFzc05hbWUsIGRhdGFiYXNlKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgZW5mb3JjZUZpZWxkcyA9IFtdO1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIGRlbGV0ZVByb21pc2UgLy8gRGVsZXRlIEV2ZXJ5dGhpbmdcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMucmVsb2FkRGF0YSh7IGNsZWFyQ2FjaGU6IHRydWUgfSkpIC8vIFJlbG9hZCBvdXIgU2NoZW1hLCBzbyB3ZSBoYXZlIGFsbCB0aGUgbmV3IHZhbHVlc1xuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBwcm9taXNlcyA9IGluc2VydGVkRmllbGRzLm1hcChmaWVsZE5hbWUgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHR5cGUgPSBzdWJtaXR0ZWRGaWVsZHNbZmllbGROYW1lXTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lbmZvcmNlRmllbGRFeGlzdHMoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHR5cGUpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAudGhlbihyZXN1bHRzID0+IHtcbiAgICAgICAgICAgICAgZW5mb3JjZUZpZWxkcyA9IHJlc3VsdHMuZmlsdGVyKHJlc3VsdCA9PiAhIXJlc3VsdCk7XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLnNldFBlcm1pc3Npb25zKGNsYXNzTmFtZSwgY2xhc3NMZXZlbFBlcm1pc3Npb25zLCBuZXdTY2hlbWEpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC50aGVuKCgpID0+XG4gICAgICAgICAgICAgIHRoaXMuX2RiQWRhcHRlci5zZXRJbmRleGVzV2l0aFNjaGVtYUZvcm1hdChcbiAgICAgICAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgaW5kZXhlcyxcbiAgICAgICAgICAgICAgICBzY2hlbWEuaW5kZXhlcyxcbiAgICAgICAgICAgICAgICBmdWxsTmV3U2NoZW1hXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMucmVsb2FkRGF0YSh7IGNsZWFyQ2FjaGU6IHRydWUgfSkpXG4gICAgICAgICAgICAvL1RPRE86IE1vdmUgdGhpcyBsb2dpYyBpbnRvIHRoZSBkYXRhYmFzZSBhZGFwdGVyXG4gICAgICAgICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuZW5zdXJlRmllbGRzKGVuZm9yY2VGaWVsZHMpO1xuICAgICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB0aGlzLnNjaGVtYURhdGFbY2xhc3NOYW1lXTtcbiAgICAgICAgICAgICAgY29uc3QgcmVsb2FkZWRTY2hlbWE6IFNjaGVtYSA9IHtcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU6IGNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICBmaWVsZHM6IHNjaGVtYS5maWVsZHMsXG4gICAgICAgICAgICAgICAgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiBzY2hlbWEuY2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICBpZiAoc2NoZW1hLmluZGV4ZXMgJiYgT2JqZWN0LmtleXMoc2NoZW1hLmluZGV4ZXMpLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgICAgIHJlbG9hZGVkU2NoZW1hLmluZGV4ZXMgPSBzY2hlbWEuaW5kZXhlcztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gcmVsb2FkZWRTY2hlbWE7XG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGlmIChlcnJvciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLFxuICAgICAgICAgICAgYENsYXNzICR7Y2xhc3NOYW1lfSBkb2VzIG5vdCBleGlzdC5gXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHN1Y2Nlc3NmdWxseSB0byB0aGUgbmV3IHNjaGVtYVxuICAvLyBvYmplY3Qgb3IgZmFpbHMgd2l0aCBhIHJlYXNvbi5cbiAgZW5mb3JjZUNsYXNzRXhpc3RzKGNsYXNzTmFtZTogc3RyaW5nKTogUHJvbWlzZTxTY2hlbWFDb250cm9sbGVyPiB7XG4gICAgaWYgKHRoaXMuc2NoZW1hRGF0YVtjbGFzc05hbWVdKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHRoaXMpO1xuICAgIH1cbiAgICAvLyBXZSBkb24ndCBoYXZlIHRoaXMgY2xhc3MuIFVwZGF0ZSB0aGUgc2NoZW1hXG4gICAgcmV0dXJuIChcbiAgICAgIC8vIFRoZSBzY2hlbWEgdXBkYXRlIHN1Y2NlZWRlZC4gUmVsb2FkIHRoZSBzY2hlbWFcbiAgICAgIHRoaXMuYWRkQ2xhc3NJZk5vdEV4aXN0cyhjbGFzc05hbWUpXG4gICAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgLy8gVGhlIHNjaGVtYSB1cGRhdGUgZmFpbGVkLiBUaGlzIGNhbiBiZSBva2F5IC0gaXQgbWlnaHRcbiAgICAgICAgICAvLyBoYXZlIGZhaWxlZCBiZWNhdXNlIHRoZXJlJ3MgYSByYWNlIGNvbmRpdGlvbiBhbmQgYSBkaWZmZXJlbnRcbiAgICAgICAgICAvLyBjbGllbnQgaXMgbWFraW5nIHRoZSBleGFjdCBzYW1lIHNjaGVtYSB1cGRhdGUgdGhhdCB3ZSB3YW50LlxuICAgICAgICAgIC8vIFNvIGp1c3QgcmVsb2FkIHRoZSBzY2hlbWEuXG4gICAgICAgICAgcmV0dXJuIHRoaXMucmVsb2FkRGF0YSh7IGNsZWFyQ2FjaGU6IHRydWUgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAvLyBFbnN1cmUgdGhhdCB0aGUgc2NoZW1hIG5vdyB2YWxpZGF0ZXNcbiAgICAgICAgICBpZiAodGhpcy5zY2hlbWFEYXRhW2NsYXNzTmFtZV0pIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9KU09OLCBgRmFpbGVkIHRvIGFkZCAke2NsYXNzTmFtZX1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgLy8gVGhlIHNjaGVtYSBzdGlsbCBkb2Vzbid0IHZhbGlkYXRlLiBHaXZlIHVwXG4gICAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfSlNPTiwgJ3NjaGVtYSBjbGFzcyBuYW1lIGRvZXMgbm90IHJldmFsaWRhdGUnKTtcbiAgICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgdmFsaWRhdGVOZXdDbGFzcyhjbGFzc05hbWU6IHN0cmluZywgZmllbGRzOiBTY2hlbWFGaWVsZHMgPSB7fSwgY2xhc3NMZXZlbFBlcm1pc3Npb25zOiBhbnkpOiBhbnkge1xuICAgIGlmICh0aGlzLnNjaGVtYURhdGFbY2xhc3NOYW1lXSkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSwgYENsYXNzICR7Y2xhc3NOYW1lfSBhbHJlYWR5IGV4aXN0cy5gKTtcbiAgICB9XG4gICAgaWYgKCFjbGFzc05hbWVJc1ZhbGlkKGNsYXNzTmFtZSkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLklOVkFMSURfQ0xBU1NfTkFNRSxcbiAgICAgICAgZXJyb3I6IGludmFsaWRDbGFzc05hbWVNZXNzYWdlKGNsYXNzTmFtZSksXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy52YWxpZGF0ZVNjaGVtYURhdGEoY2xhc3NOYW1lLCBmaWVsZHMsIGNsYXNzTGV2ZWxQZXJtaXNzaW9ucywgW10pO1xuICB9XG5cbiAgdmFsaWRhdGVTY2hlbWFEYXRhKFxuICAgIGNsYXNzTmFtZTogc3RyaW5nLFxuICAgIGZpZWxkczogU2NoZW1hRmllbGRzLFxuICAgIGNsYXNzTGV2ZWxQZXJtaXNzaW9uczogQ2xhc3NMZXZlbFBlcm1pc3Npb25zLFxuICAgIGV4aXN0aW5nRmllbGROYW1lczogQXJyYXk8c3RyaW5nPlxuICApIHtcbiAgICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBpbiBmaWVsZHMpIHtcbiAgICAgIGlmIChleGlzdGluZ0ZpZWxkTmFtZXMuaW5kZXhPZihmaWVsZE5hbWUpIDwgMCkge1xuICAgICAgICBpZiAoIWZpZWxkTmFtZUlzVmFsaWQoZmllbGROYW1lLCBjbGFzc05hbWUpKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUsXG4gICAgICAgICAgICBlcnJvcjogJ2ludmFsaWQgZmllbGQgbmFtZTogJyArIGZpZWxkTmFtZSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGlmICghZmllbGROYW1lSXNWYWxpZEZvckNsYXNzKGZpZWxkTmFtZSwgY2xhc3NOYW1lKSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb2RlOiAxMzYsXG4gICAgICAgICAgICBlcnJvcjogJ2ZpZWxkICcgKyBmaWVsZE5hbWUgKyAnIGNhbm5vdCBiZSBhZGRlZCcsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBmaWVsZFR5cGUgPSBmaWVsZHNbZmllbGROYW1lXTtcbiAgICAgICAgY29uc3QgZXJyb3IgPSBmaWVsZFR5cGVJc0ludmFsaWQoZmllbGRUeXBlKTtcbiAgICAgICAgaWYgKGVycm9yKSB7IHJldHVybiB7IGNvZGU6IGVycm9yLmNvZGUsIGVycm9yOiBlcnJvci5tZXNzYWdlIH07IH1cbiAgICAgICAgaWYgKGZpZWxkVHlwZS5kZWZhdWx0VmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGxldCBkZWZhdWx0VmFsdWVUeXBlID0gZ2V0VHlwZShmaWVsZFR5cGUuZGVmYXVsdFZhbHVlKTtcbiAgICAgICAgICBpZiAodHlwZW9mIGRlZmF1bHRWYWx1ZVR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBkZWZhdWx0VmFsdWVUeXBlID0geyB0eXBlOiBkZWZhdWx0VmFsdWVUeXBlIH07XG4gICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZGVmYXVsdFZhbHVlVHlwZSA9PT0gJ29iamVjdCcgJiYgZmllbGRUeXBlLnR5cGUgPT09ICdSZWxhdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLFxuICAgICAgICAgICAgICBlcnJvcjogYFRoZSAnZGVmYXVsdCB2YWx1ZScgb3B0aW9uIGlzIG5vdCBhcHBsaWNhYmxlIGZvciAke3R5cGVUb1N0cmluZyhmaWVsZFR5cGUpfWAsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWRiVHlwZU1hdGNoZXNPYmplY3RUeXBlKGZpZWxkVHlwZSwgZGVmYXVsdFZhbHVlVHlwZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIGNvZGU6IFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLFxuICAgICAgICAgICAgICBlcnJvcjogYHNjaGVtYSBtaXNtYXRjaCBmb3IgJHtjbGFzc05hbWV9LiR7ZmllbGROYW1lfSBkZWZhdWx0IHZhbHVlOyBleHBlY3RlZCAke3R5cGVUb1N0cmluZyhcbiAgICAgICAgICAgICAgICBmaWVsZFR5cGVcbiAgICAgICAgICAgICAgKX0gYnV0IGdvdCAke3R5cGVUb1N0cmluZyhkZWZhdWx0VmFsdWVUeXBlKX1gLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZmllbGRUeXBlLnJlcXVpcmVkKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBmaWVsZFR5cGUgPT09ICdvYmplY3QnICYmIGZpZWxkVHlwZS50eXBlID09PSAnUmVsYXRpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBjb2RlOiBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSxcbiAgICAgICAgICAgICAgZXJyb3I6IGBUaGUgJ3JlcXVpcmVkJyBvcHRpb24gaXMgbm90IGFwcGxpY2FibGUgZm9yICR7dHlwZVRvU3RyaW5nKGZpZWxkVHlwZSl9YCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBmaWVsZE5hbWUgaW4gZGVmYXVsdENvbHVtbnNbY2xhc3NOYW1lXSkge1xuICAgICAgZmllbGRzW2ZpZWxkTmFtZV0gPSBkZWZhdWx0Q29sdW1uc1tjbGFzc05hbWVdW2ZpZWxkTmFtZV07XG4gICAgfVxuXG4gICAgY29uc3QgZ2VvUG9pbnRzID0gT2JqZWN0LmtleXMoZmllbGRzKS5maWx0ZXIoXG4gICAgICBrZXkgPT4gZmllbGRzW2tleV0gJiYgZmllbGRzW2tleV0udHlwZSA9PT0gJ0dlb1BvaW50J1xuICAgICk7XG4gICAgaWYgKGdlb1BvaW50cy5sZW5ndGggPiAxKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb2RlOiBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSxcbiAgICAgICAgZXJyb3I6XG4gICAgICAgICAgJ2N1cnJlbnRseSwgb25seSBvbmUgR2VvUG9pbnQgZmllbGQgbWF5IGV4aXN0IGluIGFuIG9iamVjdC4gQWRkaW5nICcgK1xuICAgICAgICAgIGdlb1BvaW50c1sxXSArXG4gICAgICAgICAgJyB3aGVuICcgK1xuICAgICAgICAgIGdlb1BvaW50c1swXSArXG4gICAgICAgICAgJyBhbHJlYWR5IGV4aXN0cy4nLFxuICAgICAgfTtcbiAgICB9XG4gICAgdmFsaWRhdGVDTFAoY2xhc3NMZXZlbFBlcm1pc3Npb25zLCBmaWVsZHMsIHRoaXMudXNlcklkUmVnRXgpO1xuICB9XG5cbiAgLy8gU2V0cyB0aGUgQ2xhc3MtbGV2ZWwgcGVybWlzc2lvbnMgZm9yIGEgZ2l2ZW4gY2xhc3NOYW1lLCB3aGljaCBtdXN0IGV4aXN0LlxuICBhc3luYyBzZXRQZXJtaXNzaW9ucyhjbGFzc05hbWU6IHN0cmluZywgcGVybXM6IGFueSwgbmV3U2NoZW1hOiBTY2hlbWFGaWVsZHMpIHtcbiAgICBpZiAodHlwZW9mIHBlcm1zID09PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgICB2YWxpZGF0ZUNMUChwZXJtcywgbmV3U2NoZW1hLCB0aGlzLnVzZXJJZFJlZ0V4KTtcbiAgICBhd2FpdCB0aGlzLl9kYkFkYXB0ZXIuc2V0Q2xhc3NMZXZlbFBlcm1pc3Npb25zKGNsYXNzTmFtZSwgcGVybXMpO1xuICAgIGNvbnN0IGNhY2hlZCA9IFNjaGVtYUNhY2hlLmdldChjbGFzc05hbWUpO1xuICAgIGlmIChjYWNoZWQpIHtcbiAgICAgIGNhY2hlZC5jbGFzc0xldmVsUGVybWlzc2lvbnMgPSBwZXJtcztcbiAgICB9XG4gIH1cblxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHN1Y2Nlc3NmdWxseSB0byB0aGUgbmV3IHNjaGVtYVxuICAvLyBvYmplY3QgaWYgdGhlIHByb3ZpZGVkIGNsYXNzTmFtZS1maWVsZE5hbWUtdHlwZSB0dXBsZSBpcyB2YWxpZC5cbiAgLy8gVGhlIGNsYXNzTmFtZSBtdXN0IGFscmVhZHkgYmUgdmFsaWRhdGVkLlxuICAvLyBJZiAnZnJlZXplJyBpcyB0cnVlLCByZWZ1c2UgdG8gdXBkYXRlIHRoZSBzY2hlbWEgZm9yIHRoaXMgZmllbGQuXG4gIGVuZm9yY2VGaWVsZEV4aXN0cyhcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBmaWVsZE5hbWU6IHN0cmluZyxcbiAgICB0eXBlOiBzdHJpbmcgfCBTY2hlbWFGaWVsZCxcbiAgICBpc1ZhbGlkYXRpb24/OiBib29sZWFuLFxuICAgIG1haW50ZW5hbmNlPzogYm9vbGVhblxuICApIHtcbiAgICBpZiAoZmllbGROYW1lLmluZGV4T2YoJy4nKSA+IDApIHtcbiAgICAgIC8vIFwiPGFycmF5Pi48aW5kZXg+XCIgZm9yIE5lc3RlZCBBcnJheXNcbiAgICAgIC8vIFwiPGVtYmVkZGVkIGRvY3VtZW50Pi48ZmllbGQ+XCIgZm9yIE5lc3RlZCBPYmplY3RzXG4gICAgICAvLyBKU09OIEFycmF5cyBhcmUgdHJlYXRlZCBhcyBOZXN0ZWQgT2JqZWN0c1xuICAgICAgY29uc3QgW3gsIHldID0gZmllbGROYW1lLnNwbGl0KCcuJyk7XG4gICAgICBmaWVsZE5hbWUgPSB4O1xuICAgICAgY29uc3QgaXNBcnJheUluZGV4ID0gQXJyYXkuZnJvbSh5KS5ldmVyeShjID0+IGMgPj0gJzAnICYmIGMgPD0gJzknKTtcbiAgICAgIGlmIChpc0FycmF5SW5kZXggJiYgIVsnc2VudFBlclVUQ09mZnNldCcsICdmYWlsZWRQZXJVVENPZmZzZXQnXS5pbmNsdWRlcyhmaWVsZE5hbWUpKSB7XG4gICAgICAgIHR5cGUgPSAnQXJyYXknO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHlwZSA9ICdPYmplY3QnO1xuICAgICAgfVxuICAgIH1cbiAgICBsZXQgZmllbGROYW1lVG9WYWxpZGF0ZSA9IGAke2ZpZWxkTmFtZX1gO1xuICAgIGlmIChtYWludGVuYW5jZSAmJiBmaWVsZE5hbWVUb1ZhbGlkYXRlLmNoYXJBdCgwKSA9PT0gJ18nKSB7XG4gICAgICBmaWVsZE5hbWVUb1ZhbGlkYXRlID0gZmllbGROYW1lVG9WYWxpZGF0ZS5zdWJzdHJpbmcoMSk7XG4gICAgfVxuICAgIGlmICghZmllbGROYW1lSXNWYWxpZChmaWVsZE5hbWVUb1ZhbGlkYXRlLCBjbGFzc05hbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9LRVlfTkFNRSwgYEludmFsaWQgZmllbGQgbmFtZTogJHtmaWVsZE5hbWV9LmApO1xuICAgIH1cblxuICAgIC8vIElmIHNvbWVvbmUgdHJpZXMgdG8gY3JlYXRlIGEgbmV3IGZpZWxkIHdpdGggbnVsbC91bmRlZmluZWQgYXMgdGhlIHZhbHVlLCByZXR1cm47XG4gICAgaWYgKCF0eXBlKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IGV4cGVjdGVkVHlwZSA9IHRoaXMuZ2V0RXhwZWN0ZWRUeXBlKGNsYXNzTmFtZSwgZmllbGROYW1lKTtcbiAgICBpZiAodHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0eXBlID0gKHsgdHlwZSB9OiBTY2hlbWFGaWVsZCk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGUuZGVmYXVsdFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGxldCBkZWZhdWx0VmFsdWVUeXBlID0gZ2V0VHlwZSh0eXBlLmRlZmF1bHRWYWx1ZSk7XG4gICAgICBpZiAodHlwZW9mIGRlZmF1bHRWYWx1ZVR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGRlZmF1bHRWYWx1ZVR5cGUgPSB7IHR5cGU6IGRlZmF1bHRWYWx1ZVR5cGUgfTtcbiAgICAgIH1cbiAgICAgIGlmICghZGJUeXBlTWF0Y2hlc09iamVjdFR5cGUodHlwZSwgZGVmYXVsdFZhbHVlVHlwZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLFxuICAgICAgICAgIGBzY2hlbWEgbWlzbWF0Y2ggZm9yICR7Y2xhc3NOYW1lfS4ke2ZpZWxkTmFtZX0gZGVmYXVsdCB2YWx1ZTsgZXhwZWN0ZWQgJHt0eXBlVG9TdHJpbmcoXG4gICAgICAgICAgICB0eXBlXG4gICAgICAgICAgKX0gYnV0IGdvdCAke3R5cGVUb1N0cmluZyhkZWZhdWx0VmFsdWVUeXBlKX1gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGV4cGVjdGVkVHlwZSkge1xuICAgICAgaWYgKCFkYlR5cGVNYXRjaGVzT2JqZWN0VHlwZShleHBlY3RlZFR5cGUsIHR5cGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSxcbiAgICAgICAgICBgc2NoZW1hIG1pc21hdGNoIGZvciAke2NsYXNzTmFtZX0uJHtmaWVsZE5hbWV9OyBleHBlY3RlZCAke3R5cGVUb1N0cmluZyhcbiAgICAgICAgICAgIGV4cGVjdGVkVHlwZVxuICAgICAgICAgICl9IGJ1dCBnb3QgJHt0eXBlVG9TdHJpbmcodHlwZSl9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgLy8gSWYgdHlwZSBvcHRpb25zIGRvIG5vdCBjaGFuZ2VcbiAgICAgIC8vIHdlIGNhbiBzYWZlbHkgcmV0dXJuXG4gICAgICBpZiAoaXNWYWxpZGF0aW9uIHx8IEpTT04uc3RyaW5naWZ5KGV4cGVjdGVkVHlwZSkgPT09IEpTT04uc3RyaW5naWZ5KHR5cGUpKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICAvLyBGaWVsZCBvcHRpb25zIGFyZSBtYXkgYmUgY2hhbmdlZFxuICAgICAgLy8gZW5zdXJlIHRvIGhhdmUgYW4gdXBkYXRlIHRvIGRhdGUgc2NoZW1hIGZpZWxkXG4gICAgICByZXR1cm4gdGhpcy5fZGJBZGFwdGVyLnVwZGF0ZUZpZWxkT3B0aW9ucyhjbGFzc05hbWUsIGZpZWxkTmFtZSwgdHlwZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2RiQWRhcHRlclxuICAgICAgLmFkZEZpZWxkSWZOb3RFeGlzdHMoY2xhc3NOYW1lLCBmaWVsZE5hbWUsIHR5cGUpXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBpZiAoZXJyb3IuY29kZSA9PSBQYXJzZS5FcnJvci5JTkNPUlJFQ1RfVFlQRSkge1xuICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHdlIHRocm93IGVycm9ycyB3aGVuIGl0IGlzIGFwcHJvcHJpYXRlIHRvIGRvIHNvLlxuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRoZSB1cGRhdGUgZmFpbGVkLiBUaGlzIGNhbiBiZSBva2F5IC0gaXQgbWlnaHQgaGF2ZSBiZWVuIGEgcmFjZVxuICAgICAgICAvLyBjb25kaXRpb24gd2hlcmUgYW5vdGhlciBjbGllbnQgdXBkYXRlZCB0aGUgc2NoZW1hIGluIHRoZSBzYW1lXG4gICAgICAgIC8vIHdheSB0aGF0IHdlIHdhbnRlZCB0by4gU28sIGp1c3QgcmVsb2FkIHRoZSBzY2hlbWFcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjbGFzc05hbWUsXG4gICAgICAgICAgZmllbGROYW1lLFxuICAgICAgICAgIHR5cGUsXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgfVxuXG4gIGVuc3VyZUZpZWxkcyhmaWVsZHM6IGFueSkge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZmllbGRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCB7IGNsYXNzTmFtZSwgZmllbGROYW1lIH0gPSBmaWVsZHNbaV07XG4gICAgICBsZXQgeyB0eXBlIH0gPSBmaWVsZHNbaV07XG4gICAgICBjb25zdCBleHBlY3RlZFR5cGUgPSB0aGlzLmdldEV4cGVjdGVkVHlwZShjbGFzc05hbWUsIGZpZWxkTmFtZSk7XG4gICAgICBpZiAodHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHR5cGUgPSB7IHR5cGU6IHR5cGUgfTtcbiAgICAgIH1cbiAgICAgIGlmICghZXhwZWN0ZWRUeXBlIHx8ICFkYlR5cGVNYXRjaGVzT2JqZWN0VHlwZShleHBlY3RlZFR5cGUsIHR5cGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5JTlZBTElEX0pTT04sIGBDb3VsZCBub3QgYWRkIGZpZWxkICR7ZmllbGROYW1lfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIG1haW50YWluIGNvbXBhdGliaWxpdHlcbiAgZGVsZXRlRmllbGQoZmllbGROYW1lOiBzdHJpbmcsIGNsYXNzTmFtZTogc3RyaW5nLCBkYXRhYmFzZTogRGF0YWJhc2VDb250cm9sbGVyKSB7XG4gICAgcmV0dXJuIHRoaXMuZGVsZXRlRmllbGRzKFtmaWVsZE5hbWVdLCBjbGFzc05hbWUsIGRhdGFiYXNlKTtcbiAgfVxuXG4gIC8vIERlbGV0ZSBmaWVsZHMsIGFuZCByZW1vdmUgdGhhdCBkYXRhIGZyb20gYWxsIG9iamVjdHMuIFRoaXMgaXMgaW50ZW5kZWRcbiAgLy8gdG8gcmVtb3ZlIHVudXNlZCBmaWVsZHMsIGlmIG90aGVyIHdyaXRlcnMgYXJlIHdyaXRpbmcgb2JqZWN0cyB0aGF0IGluY2x1ZGVcbiAgLy8gdGhpcyBmaWVsZCwgdGhlIGZpZWxkIG1heSByZWFwcGVhci4gUmV0dXJucyBhIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoXG4gIC8vIG5vIG9iamVjdCBvbiBzdWNjZXNzLCBvciByZWplY3RzIHdpdGggeyBjb2RlLCBlcnJvciB9IG9uIGZhaWx1cmUuXG4gIC8vIFBhc3NpbmcgdGhlIGRhdGFiYXNlIGFuZCBwcmVmaXggaXMgbmVjZXNzYXJ5IGluIG9yZGVyIHRvIGRyb3AgcmVsYXRpb24gY29sbGVjdGlvbnNcbiAgLy8gYW5kIHJlbW92ZSBmaWVsZHMgZnJvbSBvYmplY3RzLiBJZGVhbGx5IHRoZSBkYXRhYmFzZSB3b3VsZCBiZWxvbmcgdG9cbiAgLy8gYSBkYXRhYmFzZSBhZGFwdGVyIGFuZCB0aGlzIGZ1bmN0aW9uIHdvdWxkIGNsb3NlIG92ZXIgaXQgb3IgYWNjZXNzIGl0IHZpYSBtZW1iZXIuXG4gIGRlbGV0ZUZpZWxkcyhmaWVsZE5hbWVzOiBBcnJheTxzdHJpbmc+LCBjbGFzc05hbWU6IHN0cmluZywgZGF0YWJhc2U6IERhdGFiYXNlQ29udHJvbGxlcikge1xuICAgIGlmICghY2xhc3NOYW1lSXNWYWxpZChjbGFzc05hbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5WQUxJRF9DTEFTU19OQU1FLCBpbnZhbGlkQ2xhc3NOYW1lTWVzc2FnZShjbGFzc05hbWUpKTtcbiAgICB9XG5cbiAgICBmaWVsZE5hbWVzLmZvckVhY2goZmllbGROYW1lID0+IHtcbiAgICAgIGlmICghZmllbGROYW1lSXNWYWxpZChmaWVsZE5hbWUsIGNsYXNzTmFtZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVkFMSURfS0VZX05BTUUsIGBpbnZhbGlkIGZpZWxkIG5hbWU6ICR7ZmllbGROYW1lfWApO1xuICAgICAgfVxuICAgICAgLy9Eb24ndCBhbGxvdyBkZWxldGluZyB0aGUgZGVmYXVsdCBmaWVsZHMuXG4gICAgICBpZiAoIWZpZWxkTmFtZUlzVmFsaWRGb3JDbGFzcyhmaWVsZE5hbWUsIGNsYXNzTmFtZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKDEzNiwgYGZpZWxkICR7ZmllbGROYW1lfSBjYW5ub3QgYmUgY2hhbmdlZGApO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMuZ2V0T25lU2NoZW1hKGNsYXNzTmFtZSwgZmFsc2UsIHsgY2xlYXJDYWNoZTogdHJ1ZSB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICBQYXJzZS5FcnJvci5JTlZBTElEX0NMQVNTX05BTUUsXG4gICAgICAgICAgICBgQ2xhc3MgJHtjbGFzc05hbWV9IGRvZXMgbm90IGV4aXN0LmBcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLnRoZW4oc2NoZW1hID0+IHtcbiAgICAgICAgZmllbGROYW1lcy5mb3JFYWNoKGZpZWxkTmFtZSA9PiB7XG4gICAgICAgICAgaWYgKCFzY2hlbWEuZmllbGRzW2ZpZWxkTmFtZV0pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcigyNTUsIGBGaWVsZCAke2ZpZWxkTmFtZX0gZG9lcyBub3QgZXhpc3QsIGNhbm5vdCBkZWxldGUuYCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCBzY2hlbWFGaWVsZHMgPSB7IC4uLnNjaGVtYS5maWVsZHMgfTtcbiAgICAgICAgcmV0dXJuIGRhdGFiYXNlLmFkYXB0ZXIuZGVsZXRlRmllbGRzKGNsYXNzTmFtZSwgc2NoZW1hLCBmaWVsZE5hbWVzKS50aGVuKCgpID0+IHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICBmaWVsZE5hbWVzLm1hcChmaWVsZE5hbWUgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBmaWVsZCA9IHNjaGVtYUZpZWxkc1tmaWVsZE5hbWVdO1xuICAgICAgICAgICAgICBpZiAoZmllbGQgJiYgZmllbGQudHlwZSA9PT0gJ1JlbGF0aW9uJykge1xuICAgICAgICAgICAgICAgIC8vRm9yIHJlbGF0aW9ucywgZHJvcCB0aGUgX0pvaW4gdGFibGVcbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YWJhc2UuYWRhcHRlci5kZWxldGVDbGFzcyhgX0pvaW46JHtmaWVsZE5hbWV9OiR7Y2xhc3NOYW1lfWApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBTY2hlbWFDYWNoZS5jbGVhcigpO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBWYWxpZGF0ZXMgYW4gb2JqZWN0IHByb3ZpZGVkIGluIFJFU1QgZm9ybWF0LlxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBuZXcgc2NoZW1hIGlmIHRoaXMgb2JqZWN0IGlzXG4gIC8vIHZhbGlkLlxuICBhc3luYyB2YWxpZGF0ZU9iamVjdChjbGFzc05hbWU6IHN0cmluZywgb2JqZWN0OiBhbnksIHF1ZXJ5OiBhbnksIG1haW50ZW5hbmNlOiBib29sZWFuKSB7XG4gICAgbGV0IGdlb2NvdW50ID0gMDtcbiAgICBjb25zdCBzY2hlbWEgPSBhd2FpdCB0aGlzLmVuZm9yY2VDbGFzc0V4aXN0cyhjbGFzc05hbWUpO1xuICAgIGNvbnN0IHByb21pc2VzID0gW107XG5cbiAgICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBpbiBvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSAmJiBnZXRUeXBlKG9iamVjdFtmaWVsZE5hbWVdKSA9PT0gJ0dlb1BvaW50Jykge1xuICAgICAgICBnZW9jb3VudCsrO1xuICAgICAgfVxuICAgICAgaWYgKGdlb2NvdW50ID4gMSkge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoXG4gICAgICAgICAgbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgUGFyc2UuRXJyb3IuSU5DT1JSRUNUX1RZUEUsXG4gICAgICAgICAgICAndGhlcmUgY2FuIG9ubHkgYmUgb25lIGdlb3BvaW50IGZpZWxkIGluIGEgY2xhc3MnXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IGZpZWxkTmFtZSBpbiBvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3RbZmllbGROYW1lXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgZXhwZWN0ZWQgPSBnZXRUeXBlKG9iamVjdFtmaWVsZE5hbWVdKTtcbiAgICAgIGlmICghZXhwZWN0ZWQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoZmllbGROYW1lID09PSAnQUNMJykge1xuICAgICAgICAvLyBFdmVyeSBvYmplY3QgaGFzIEFDTCBpbXBsaWNpdGx5LlxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHByb21pc2VzLnB1c2goc2NoZW1hLmVuZm9yY2VGaWVsZEV4aXN0cyhjbGFzc05hbWUsIGZpZWxkTmFtZSwgZXhwZWN0ZWQsIHRydWUsIG1haW50ZW5hbmNlKSk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgY29uc3QgZW5mb3JjZUZpZWxkcyA9IHJlc3VsdHMuZmlsdGVyKHJlc3VsdCA9PiAhIXJlc3VsdCk7XG5cbiAgICBpZiAoZW5mb3JjZUZpZWxkcy5sZW5ndGggIT09IDApIHtcbiAgICAgIC8vIFRPRE86IFJlbW92ZSBieSB1cGRhdGluZyBzY2hlbWEgY2FjaGUgZGlyZWN0bHlcbiAgICAgIGF3YWl0IHRoaXMucmVsb2FkRGF0YSh7IGNsZWFyQ2FjaGU6IHRydWUgfSk7XG4gICAgfVxuICAgIHRoaXMuZW5zdXJlRmllbGRzKGVuZm9yY2VGaWVsZHMpO1xuXG4gICAgY29uc3QgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZShzY2hlbWEpO1xuICAgIHJldHVybiB0aGVuVmFsaWRhdGVSZXF1aXJlZENvbHVtbnMocHJvbWlzZSwgY2xhc3NOYW1lLCBvYmplY3QsIHF1ZXJ5KTtcbiAgfVxuXG4gIC8vIFZhbGlkYXRlcyB0aGF0IGFsbCB0aGUgcHJvcGVydGllcyBhcmUgc2V0IGZvciB0aGUgb2JqZWN0XG4gIHZhbGlkYXRlUmVxdWlyZWRDb2x1bW5zKGNsYXNzTmFtZTogc3RyaW5nLCBvYmplY3Q6IGFueSwgcXVlcnk6IGFueSkge1xuICAgIGNvbnN0IGNvbHVtbnMgPSByZXF1aXJlZENvbHVtbnMud3JpdGVbY2xhc3NOYW1lXTtcbiAgICBpZiAoIWNvbHVtbnMgfHwgY29sdW1ucy5sZW5ndGggPT0gMCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzKTtcbiAgICB9XG5cbiAgICBjb25zdCBtaXNzaW5nQ29sdW1ucyA9IGNvbHVtbnMuZmlsdGVyKGZ1bmN0aW9uIChjb2x1bW4pIHtcbiAgICAgIGlmIChxdWVyeSAmJiBxdWVyeS5vYmplY3RJZCkge1xuICAgICAgICBpZiAob2JqZWN0W2NvbHVtbl0gJiYgdHlwZW9mIG9iamVjdFtjb2x1bW5dID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIC8vIFRyeWluZyB0byBkZWxldGUgYSByZXF1aXJlZCBjb2x1bW5cbiAgICAgICAgICByZXR1cm4gb2JqZWN0W2NvbHVtbl0uX19vcCA9PSAnRGVsZXRlJztcbiAgICAgICAgfVxuICAgICAgICAvLyBOb3QgdHJ5aW5nIHRvIGRvIGFueXRoaW5nIHRoZXJlXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiAhb2JqZWN0W2NvbHVtbl07XG4gICAgfSk7XG5cbiAgICBpZiAobWlzc2luZ0NvbHVtbnMubGVuZ3RoID4gMCkge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLCBtaXNzaW5nQ29sdW1uc1swXSArICcgaXMgcmVxdWlyZWQuJyk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUodGhpcyk7XG4gIH1cblxuICB0ZXN0UGVybWlzc2lvbnNGb3JDbGFzc05hbWUoY2xhc3NOYW1lOiBzdHJpbmcsIGFjbEdyb3VwOiBzdHJpbmdbXSwgb3BlcmF0aW9uOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gU2NoZW1hQ29udHJvbGxlci50ZXN0UGVybWlzc2lvbnMoXG4gICAgICB0aGlzLmdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyhjbGFzc05hbWUpLFxuICAgICAgYWNsR3JvdXAsXG4gICAgICBvcGVyYXRpb25cbiAgICApO1xuICB9XG5cbiAgLy8gVGVzdHMgdGhhdCB0aGUgY2xhc3MgbGV2ZWwgcGVybWlzc2lvbiBsZXQgcGFzcyB0aGUgb3BlcmF0aW9uIGZvciBhIGdpdmVuIGFjbEdyb3VwXG4gIHN0YXRpYyB0ZXN0UGVybWlzc2lvbnMoY2xhc3NQZXJtaXNzaW9uczogP2FueSwgYWNsR3JvdXA6IHN0cmluZ1tdLCBvcGVyYXRpb246IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICghY2xhc3NQZXJtaXNzaW9ucyB8fCAhY2xhc3NQZXJtaXNzaW9uc1tvcGVyYXRpb25dKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgcGVybXMgPSBjbGFzc1Blcm1pc3Npb25zW29wZXJhdGlvbl07XG4gICAgaWYgKHBlcm1zWycqJ10pIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICAvLyBDaGVjayBwZXJtaXNzaW9ucyBhZ2FpbnN0IHRoZSBhY2xHcm91cCBwcm92aWRlZCAoYXJyYXkgb2YgdXNlcklkL3JvbGVzKVxuICAgIGlmIChcbiAgICAgIGFjbEdyb3VwLnNvbWUoYWNsID0+IHtcbiAgICAgICAgcmV0dXJuIHBlcm1zW2FjbF0gPT09IHRydWU7XG4gICAgICB9KVxuICAgICkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIFZhbGlkYXRlcyBhbiBvcGVyYXRpb24gcGFzc2VzIGNsYXNzLWxldmVsLXBlcm1pc3Npb25zIHNldCBpbiB0aGUgc2NoZW1hXG4gIHN0YXRpYyB2YWxpZGF0ZVBlcm1pc3Npb24oXG4gICAgY2xhc3NQZXJtaXNzaW9uczogP2FueSxcbiAgICBjbGFzc05hbWU6IHN0cmluZyxcbiAgICBhY2xHcm91cDogc3RyaW5nW10sXG4gICAgb3BlcmF0aW9uOiBzdHJpbmcsXG4gICAgYWN0aW9uPzogc3RyaW5nXG4gICkge1xuICAgIGlmIChTY2hlbWFDb250cm9sbGVyLnRlc3RQZXJtaXNzaW9ucyhjbGFzc1Blcm1pc3Npb25zLCBhY2xHcm91cCwgb3BlcmF0aW9uKSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIGlmICghY2xhc3NQZXJtaXNzaW9ucyB8fCAhY2xhc3NQZXJtaXNzaW9uc1tvcGVyYXRpb25dKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgcGVybXMgPSBjbGFzc1Blcm1pc3Npb25zW29wZXJhdGlvbl07XG4gICAgY29uc3QgY29uZmlnID0gQ29uZmlnLmdldChQYXJzZS5hcHBsaWNhdGlvbklkKVxuICAgIC8vIElmIG9ubHkgZm9yIGF1dGhlbnRpY2F0ZWQgdXNlcnNcbiAgICAvLyBtYWtlIHN1cmUgd2UgaGF2ZSBhbiBhY2xHcm91cFxuICAgIGlmIChwZXJtc1sncmVxdWlyZXNBdXRoZW50aWNhdGlvbiddKSB7XG4gICAgICAvLyBJZiBhY2xHcm91cCBoYXMgKiAocHVibGljKVxuICAgICAgaWYgKCFhY2xHcm91cCB8fCBhY2xHcm91cC5sZW5ndGggPT0gMCkge1xuICAgICAgICB0aHJvdyBjcmVhdGVTYW5pdGl6ZWRFcnJvcihcbiAgICAgICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgICAgICdQZXJtaXNzaW9uIGRlbmllZCwgdXNlciBuZWVkcyB0byBiZSBhdXRoZW50aWNhdGVkLicsXG4gICAgICAgICAgY29uZmlnXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKGFjbEdyb3VwLmluZGV4T2YoJyonKSA+IC0xICYmIGFjbEdyb3VwLmxlbmd0aCA9PSAxKSB7XG4gICAgICAgIHRocm93IGNyZWF0ZVNhbml0aXplZEVycm9yKFxuICAgICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICAgJ1Blcm1pc3Npb24gZGVuaWVkLCB1c2VyIG5lZWRzIHRvIGJlIGF1dGhlbnRpY2F0ZWQuJyxcbiAgICAgICAgICBjb25maWdcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIC8vIHJlcXVpcmVzQXV0aGVudGljYXRpb24gcGFzc2VkLCBqdXN0IG1vdmUgZm9yd2FyZFxuICAgICAgLy8gcHJvYmFibHkgd291bGQgYmUgd2lzZSBhdCBzb21lIHBvaW50IHRvIHJlbmFtZSB0byAnYXV0aGVudGljYXRlZFVzZXInXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuXG4gICAgLy8gTm8gbWF0Y2hpbmcgQ0xQLCBsZXQncyBjaGVjayB0aGUgUG9pbnRlciBwZXJtaXNzaW9uc1xuICAgIC8vIEFuZCBoYW5kbGUgdGhvc2UgbGF0ZXJcbiAgICBjb25zdCBwZXJtaXNzaW9uRmllbGQgPVxuICAgICAgWydnZXQnLCAnZmluZCcsICdjb3VudCddLmluZGV4T2Yob3BlcmF0aW9uKSA+IC0xID8gJ3JlYWRVc2VyRmllbGRzJyA6ICd3cml0ZVVzZXJGaWVsZHMnO1xuXG4gICAgLy8gUmVqZWN0IGNyZWF0ZSB3aGVuIHdyaXRlIGxvY2tkb3duXG4gICAgaWYgKHBlcm1pc3Npb25GaWVsZCA9PSAnd3JpdGVVc2VyRmllbGRzJyAmJiBvcGVyYXRpb24gPT0gJ2NyZWF0ZScpIHtcbiAgICAgIHRocm93IGNyZWF0ZVNhbml0aXplZEVycm9yKFxuICAgICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgICBgUGVybWlzc2lvbiBkZW5pZWQgZm9yIGFjdGlvbiAke29wZXJhdGlvbn0gb24gY2xhc3MgJHtjbGFzc05hbWV9LmAsXG4gICAgICAgIGNvbmZpZ1xuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBQcm9jZXNzIHRoZSByZWFkVXNlckZpZWxkcyBsYXRlclxuICAgIGlmIChcbiAgICAgIEFycmF5LmlzQXJyYXkoY2xhc3NQZXJtaXNzaW9uc1twZXJtaXNzaW9uRmllbGRdKSAmJlxuICAgICAgY2xhc3NQZXJtaXNzaW9uc1twZXJtaXNzaW9uRmllbGRdLmxlbmd0aCA+IDBcbiAgICApIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG5cbiAgICBjb25zdCBwb2ludGVyRmllbGRzID0gY2xhc3NQZXJtaXNzaW9uc1tvcGVyYXRpb25dLnBvaW50ZXJGaWVsZHM7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocG9pbnRlckZpZWxkcykgJiYgcG9pbnRlckZpZWxkcy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBhbnkgb3AgZXhjZXB0ICdhZGRGaWVsZCBhcyBwYXJ0IG9mIGNyZWF0ZScgaXMgb2suXG4gICAgICBpZiAob3BlcmF0aW9uICE9PSAnYWRkRmllbGQnIHx8IGFjdGlvbiA9PT0gJ3VwZGF0ZScpIHtcbiAgICAgICAgLy8gV2UgY2FuIGFsbG93IGFkZGluZyBmaWVsZCBvbiB1cGRhdGUgZmxvdyBvbmx5LlxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhyb3cgY3JlYXRlU2FuaXRpemVkRXJyb3IoXG4gICAgICBQYXJzZS5FcnJvci5PUEVSQVRJT05fRk9SQklEREVOLFxuICAgICAgYFBlcm1pc3Npb24gZGVuaWVkIGZvciBhY3Rpb24gJHtvcGVyYXRpb259IG9uIGNsYXNzICR7Y2xhc3NOYW1lfS5gLFxuICAgICAgY29uZmlnXG4gICAgKTtcbiAgfVxuXG4gIC8vIFZhbGlkYXRlcyBhbiBvcGVyYXRpb24gcGFzc2VzIGNsYXNzLWxldmVsLXBlcm1pc3Npb25zIHNldCBpbiB0aGUgc2NoZW1hXG4gIHZhbGlkYXRlUGVybWlzc2lvbihjbGFzc05hbWU6IHN0cmluZywgYWNsR3JvdXA6IHN0cmluZ1tdLCBvcGVyYXRpb246IHN0cmluZywgYWN0aW9uPzogc3RyaW5nKSB7XG4gICAgcmV0dXJuIFNjaGVtYUNvbnRyb2xsZXIudmFsaWRhdGVQZXJtaXNzaW9uKFxuICAgICAgdGhpcy5nZXRDbGFzc0xldmVsUGVybWlzc2lvbnMoY2xhc3NOYW1lKSxcbiAgICAgIGNsYXNzTmFtZSxcbiAgICAgIGFjbEdyb3VwLFxuICAgICAgb3BlcmF0aW9uLFxuICAgICAgYWN0aW9uXG4gICAgKTtcbiAgfVxuXG4gIGdldENsYXNzTGV2ZWxQZXJtaXNzaW9ucyhjbGFzc05hbWU6IHN0cmluZyk6IGFueSB7XG4gICAgcmV0dXJuIHRoaXMuc2NoZW1hRGF0YVtjbGFzc05hbWVdICYmIHRoaXMuc2NoZW1hRGF0YVtjbGFzc05hbWVdLmNsYXNzTGV2ZWxQZXJtaXNzaW9ucztcbiAgfVxuXG4gIC8vIFJldHVybnMgdGhlIGV4cGVjdGVkIHR5cGUgZm9yIGEgY2xhc3NOYW1lK2tleSBjb21iaW5hdGlvblxuICAvLyBvciB1bmRlZmluZWQgaWYgdGhlIHNjaGVtYSBpcyBub3Qgc2V0XG4gIGdldEV4cGVjdGVkVHlwZShjbGFzc05hbWU6IHN0cmluZywgZmllbGROYW1lOiBzdHJpbmcpOiA/KFNjaGVtYUZpZWxkIHwgc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMuc2NoZW1hRGF0YVtjbGFzc05hbWVdKSB7XG4gICAgICBjb25zdCBleHBlY3RlZFR5cGUgPSB0aGlzLnNjaGVtYURhdGFbY2xhc3NOYW1lXS5maWVsZHNbZmllbGROYW1lXTtcbiAgICAgIHJldHVybiBleHBlY3RlZFR5cGUgPT09ICdtYXAnID8gJ09iamVjdCcgOiBleHBlY3RlZFR5cGU7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvLyBDaGVja3MgaWYgYSBnaXZlbiBjbGFzcyBpcyBpbiB0aGUgc2NoZW1hLlxuICBoYXNDbGFzcyhjbGFzc05hbWU6IHN0cmluZykge1xuICAgIGlmICh0aGlzLnNjaGVtYURhdGFbY2xhc3NOYW1lXSkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0cnVlKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucmVsb2FkRGF0YSgpLnRoZW4oKCkgPT4gISF0aGlzLnNjaGVtYURhdGFbY2xhc3NOYW1lXSk7XG4gIH1cbn1cblxuLy8gUmV0dXJucyBhIHByb21pc2UgZm9yIGEgbmV3IFNjaGVtYS5cbmNvbnN0IGxvYWQgPSAoZGJBZGFwdGVyOiBTdG9yYWdlQWRhcHRlciwgb3B0aW9uczogYW55KTogUHJvbWlzZTxTY2hlbWFDb250cm9sbGVyPiA9PiB7XG4gIGNvbnN0IHNjaGVtYSA9IG5ldyBTY2hlbWFDb250cm9sbGVyKGRiQWRhcHRlcik7XG4gIHR0bC5kdXJhdGlvbiA9IGRiQWRhcHRlci5zY2hlbWFDYWNoZVR0bDtcbiAgcmV0dXJuIHNjaGVtYS5yZWxvYWREYXRhKG9wdGlvbnMpLnRoZW4oKCkgPT4gc2NoZW1hKTtcbn07XG5cbi8vIEJ1aWxkcyBhIG5ldyBzY2hlbWEgKGluIHNjaGVtYSBBUEkgcmVzcG9uc2UgZm9ybWF0KSBvdXQgb2YgYW5cbi8vIGV4aXN0aW5nIG1vbmdvIHNjaGVtYSArIGEgc2NoZW1hcyBBUEkgcHV0IHJlcXVlc3QuIFRoaXMgcmVzcG9uc2Vcbi8vIGRvZXMgbm90IGluY2x1ZGUgdGhlIGRlZmF1bHQgZmllbGRzLCBhcyBpdCBpcyBpbnRlbmRlZCB0byBiZSBwYXNzZWRcbi8vIHRvIG1vbmdvU2NoZW1hRnJvbUZpZWxkc0FuZENsYXNzTmFtZS4gTm8gdmFsaWRhdGlvbiBpcyBkb25lIGhlcmUsIGl0XG4vLyBpcyBkb25lIGluIG1vbmdvU2NoZW1hRnJvbUZpZWxkc0FuZENsYXNzTmFtZS5cbmZ1bmN0aW9uIGJ1aWxkTWVyZ2VkU2NoZW1hT2JqZWN0KGV4aXN0aW5nRmllbGRzOiBTY2hlbWFGaWVsZHMsIHB1dFJlcXVlc3Q6IGFueSk6IFNjaGVtYUZpZWxkcyB7XG4gIGNvbnN0IG5ld1NjaGVtYSA9IHt9O1xuICAvLyBAZmxvdy1kaXNhYmxlLW5leHRcbiAgY29uc3Qgc3lzU2NoZW1hRmllbGQgPVxuICAgIE9iamVjdC5rZXlzKGRlZmF1bHRDb2x1bW5zKS5pbmRleE9mKGV4aXN0aW5nRmllbGRzLl9pZCkgPT09IC0xXG4gICAgICA/IFtdXG4gICAgICA6IE9iamVjdC5rZXlzKGRlZmF1bHRDb2x1bW5zW2V4aXN0aW5nRmllbGRzLl9pZF0pO1xuICBmb3IgKGNvbnN0IG9sZEZpZWxkIGluIGV4aXN0aW5nRmllbGRzKSB7XG4gICAgaWYgKFxuICAgICAgb2xkRmllbGQgIT09ICdfaWQnICYmXG4gICAgICBvbGRGaWVsZCAhPT0gJ0FDTCcgJiZcbiAgICAgIG9sZEZpZWxkICE9PSAndXBkYXRlZEF0JyAmJlxuICAgICAgb2xkRmllbGQgIT09ICdjcmVhdGVkQXQnICYmXG4gICAgICBvbGRGaWVsZCAhPT0gJ29iamVjdElkJ1xuICAgICkge1xuICAgICAgaWYgKHN5c1NjaGVtYUZpZWxkLmxlbmd0aCA+IDAgJiYgc3lzU2NoZW1hRmllbGQuaW5kZXhPZihvbGRGaWVsZCkgIT09IC0xKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgZmllbGRJc0RlbGV0ZWQgPSBwdXRSZXF1ZXN0W29sZEZpZWxkXSAmJiBwdXRSZXF1ZXN0W29sZEZpZWxkXS5fX29wID09PSAnRGVsZXRlJztcbiAgICAgIGlmICghZmllbGRJc0RlbGV0ZWQpIHtcbiAgICAgICAgbmV3U2NoZW1hW29sZEZpZWxkXSA9IGV4aXN0aW5nRmllbGRzW29sZEZpZWxkXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZm9yIChjb25zdCBuZXdGaWVsZCBpbiBwdXRSZXF1ZXN0KSB7XG4gICAgaWYgKG5ld0ZpZWxkICE9PSAnb2JqZWN0SWQnICYmIHB1dFJlcXVlc3RbbmV3RmllbGRdLl9fb3AgIT09ICdEZWxldGUnKSB7XG4gICAgICBpZiAoc3lzU2NoZW1hRmllbGQubGVuZ3RoID4gMCAmJiBzeXNTY2hlbWFGaWVsZC5pbmRleE9mKG5ld0ZpZWxkKSAhPT0gLTEpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBuZXdTY2hlbWFbbmV3RmllbGRdID0gcHV0UmVxdWVzdFtuZXdGaWVsZF07XG4gICAgfVxuICB9XG4gIHJldHVybiBuZXdTY2hlbWE7XG59XG5cbi8vIEdpdmVuIGEgc2NoZW1hIHByb21pc2UsIGNvbnN0cnVjdCBhbm90aGVyIHNjaGVtYSBwcm9taXNlIHRoYXRcbi8vIHZhbGlkYXRlcyB0aGlzIGZpZWxkIG9uY2UgdGhlIHNjaGVtYSBsb2Fkcy5cbmZ1bmN0aW9uIHRoZW5WYWxpZGF0ZVJlcXVpcmVkQ29sdW1ucyhzY2hlbWFQcm9taXNlLCBjbGFzc05hbWUsIG9iamVjdCwgcXVlcnkpIHtcbiAgcmV0dXJuIHNjaGVtYVByb21pc2UudGhlbihzY2hlbWEgPT4ge1xuICAgIHJldHVybiBzY2hlbWEudmFsaWRhdGVSZXF1aXJlZENvbHVtbnMoY2xhc3NOYW1lLCBvYmplY3QsIHF1ZXJ5KTtcbiAgfSk7XG59XG5cbi8vIEdldHMgdGhlIHR5cGUgZnJvbSBhIFJFU1QgQVBJIGZvcm1hdHRlZCBvYmplY3QsIHdoZXJlICd0eXBlJyBpc1xuLy8gZXh0ZW5kZWQgcGFzdCBqYXZhc2NyaXB0IHR5cGVzIHRvIGluY2x1ZGUgdGhlIHJlc3Qgb2YgdGhlIFBhcnNlXG4vLyB0eXBlIHN5c3RlbS5cbi8vIFRoZSBvdXRwdXQgc2hvdWxkIGJlIGEgdmFsaWQgc2NoZW1hIHZhbHVlLlxuLy8gVE9ETzogZW5zdXJlIHRoYXQgdGhpcyBpcyBjb21wYXRpYmxlIHdpdGggdGhlIGZvcm1hdCB1c2VkIGluIE9wZW4gREJcbmZ1bmN0aW9uIGdldFR5cGUob2JqOiBhbnkpOiA/KFNjaGVtYUZpZWxkIHwgc3RyaW5nKSB7XG4gIGNvbnN0IHR5cGUgPSB0eXBlb2Ygb2JqO1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlICdib29sZWFuJzpcbiAgICAgIHJldHVybiAnQm9vbGVhbic7XG4gICAgY2FzZSAnc3RyaW5nJzpcbiAgICAgIHJldHVybiAnU3RyaW5nJztcbiAgICBjYXNlICdudW1iZXInOlxuICAgICAgcmV0dXJuICdOdW1iZXInO1xuICAgIGNhc2UgJ21hcCc6XG4gICAgY2FzZSAnb2JqZWN0JzpcbiAgICAgIGlmICghb2JqKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gZ2V0T2JqZWN0VHlwZShvYmopO1xuICAgIGNhc2UgJ2Z1bmN0aW9uJzpcbiAgICBjYXNlICdzeW1ib2wnOlxuICAgIGNhc2UgJ3VuZGVmaW5lZCc6XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93ICdiYWQgb2JqOiAnICsgb2JqO1xuICB9XG59XG5cbi8vIFRoaXMgZ2V0cyB0aGUgdHlwZSBmb3Igbm9uLUpTT04gdHlwZXMgbGlrZSBwb2ludGVycyBhbmQgZmlsZXMsIGJ1dFxuLy8gYWxzbyBnZXRzIHRoZSBhcHByb3ByaWF0ZSB0eXBlIGZvciAkIG9wZXJhdG9ycy5cbi8vIFJldHVybnMgbnVsbCBpZiB0aGUgdHlwZSBpcyB1bmtub3duLlxuZnVuY3Rpb24gZ2V0T2JqZWN0VHlwZShvYmopOiA/KFNjaGVtYUZpZWxkIHwgc3RyaW5nKSB7XG4gIGlmIChvYmogaW5zdGFuY2VvZiBBcnJheSkge1xuICAgIHJldHVybiAnQXJyYXknO1xuICB9XG4gIGlmIChvYmouX190eXBlKSB7XG4gICAgc3dpdGNoIChvYmouX190eXBlKSB7XG4gICAgICBjYXNlICdQb2ludGVyJzpcbiAgICAgICAgaWYgKG9iai5jbGFzc05hbWUpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ1BvaW50ZXInLFxuICAgICAgICAgICAgdGFyZ2V0Q2xhc3M6IG9iai5jbGFzc05hbWUsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ1JlbGF0aW9uJzpcbiAgICAgICAgaWYgKG9iai5jbGFzc05hbWUpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogJ1JlbGF0aW9uJyxcbiAgICAgICAgICAgIHRhcmdldENsYXNzOiBvYmouY2xhc3NOYW1lLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdGaWxlJzpcbiAgICAgICAgaWYgKG9iai5uYW1lKSB7XG4gICAgICAgICAgcmV0dXJuICdGaWxlJztcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0RhdGUnOlxuICAgICAgICBpZiAob2JqLmlzbykge1xuICAgICAgICAgIHJldHVybiAnRGF0ZSc7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdHZW9Qb2ludCc6XG4gICAgICAgIGlmIChvYmoubGF0aXR1ZGUgIT0gbnVsbCAmJiBvYmoubG9uZ2l0dWRlICE9IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gJ0dlb1BvaW50JztcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0J5dGVzJzpcbiAgICAgICAgaWYgKG9iai5iYXNlNjQpIHtcbiAgICAgICAgICByZXR1cm4gJ0J5dGVzJztcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ1BvbHlnb24nOlxuICAgICAgICBpZiAob2JqLmNvb3JkaW5hdGVzKSB7XG4gICAgICAgICAgcmV0dXJuICdQb2x5Z29uJztcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOQ09SUkVDVF9UWVBFLCAnVGhpcyBpcyBub3QgYSB2YWxpZCAnICsgb2JqLl9fdHlwZSk7XG4gIH1cbiAgaWYgKG9ialsnJG5lJ10pIHtcbiAgICByZXR1cm4gZ2V0T2JqZWN0VHlwZShvYmpbJyRuZSddKTtcbiAgfVxuICBpZiAob2JqLl9fb3ApIHtcbiAgICBzd2l0Y2ggKG9iai5fX29wKSB7XG4gICAgICBjYXNlICdJbmNyZW1lbnQnOlxuICAgICAgICByZXR1cm4gJ051bWJlcic7XG4gICAgICBjYXNlICdEZWxldGUnOlxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIGNhc2UgJ0FkZCc6XG4gICAgICBjYXNlICdBZGRVbmlxdWUnOlxuICAgICAgY2FzZSAnUmVtb3ZlJzpcbiAgICAgICAgcmV0dXJuICdBcnJheSc7XG4gICAgICBjYXNlICdBZGRSZWxhdGlvbic6XG4gICAgICBjYXNlICdSZW1vdmVSZWxhdGlvbic6XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdHlwZTogJ1JlbGF0aW9uJyxcbiAgICAgICAgICB0YXJnZXRDbGFzczogb2JqLm9iamVjdHNbMF0uY2xhc3NOYW1lLFxuICAgICAgICB9O1xuICAgICAgY2FzZSAnQmF0Y2gnOlxuICAgICAgICByZXR1cm4gZ2V0T2JqZWN0VHlwZShvYmoub3BzWzBdKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93ICd1bmV4cGVjdGVkIG9wOiAnICsgb2JqLl9fb3A7XG4gICAgfVxuICB9XG4gIHJldHVybiAnT2JqZWN0Jztcbn1cblxuZXhwb3J0IHtcbiAgbG9hZCxcbiAgY2xhc3NOYW1lSXNWYWxpZCxcbiAgZmllbGROYW1lSXNWYWxpZCxcbiAgaW52YWxpZENsYXNzTmFtZU1lc3NhZ2UsXG4gIGJ1aWxkTWVyZ2VkU2NoZW1hT2JqZWN0LFxuICBzeXN0ZW1DbGFzc2VzLFxuICBkZWZhdWx0Q29sdW1ucyxcbiAgY29udmVydFNjaGVtYVRvQWRhcHRlclNjaGVtYSxcbiAgVm9sYXRpbGVDbGFzc2VzU2NoZW1hcyxcbiAgU2NoZW1hQ29udHJvbGxlcixcbiAgcmVxdWlyZWRDb2x1bW5zLFxufTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBa0JBLElBQUFBLGVBQUEsR0FBQUMsT0FBQTtBQUNBLElBQUFDLFlBQUEsR0FBQUMsc0JBQUEsQ0FBQUYsT0FBQTtBQUNBLElBQUFHLG1CQUFBLEdBQUFELHNCQUFBLENBQUFGLE9BQUE7QUFDQSxJQUFBSSxPQUFBLEdBQUFGLHNCQUFBLENBQUFGLE9BQUE7QUFDQSxJQUFBSyxNQUFBLEdBQUFMLE9BQUE7QUFFQSxJQUFBTSxTQUFBLEdBQUFKLHNCQUFBLENBQUFGLE9BQUE7QUFBZ0MsU0FBQUUsdUJBQUFLLENBQUEsV0FBQUEsQ0FBQSxJQUFBQSxDQUFBLENBQUFDLFVBQUEsR0FBQUQsQ0FBQSxLQUFBRSxPQUFBLEVBQUFGLENBQUE7QUF2QmhDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTUcsS0FBSyxHQUFHVixPQUFPLENBQUMsWUFBWSxDQUFDLENBQUNVLEtBQUs7O0FBTXpDOztBQVVBLE1BQU1DLGNBQTBDLEdBQUFDLE9BQUEsQ0FBQUQsY0FBQSxHQUFHRSxNQUFNLENBQUNDLE1BQU0sQ0FBQztFQUMvRDtFQUNBQyxRQUFRLEVBQUU7SUFDUkMsUUFBUSxFQUFFO01BQUVDLElBQUksRUFBRTtJQUFTLENBQUM7SUFDNUJDLFNBQVMsRUFBRTtNQUFFRCxJQUFJLEVBQUU7SUFBTyxDQUFDO0lBQzNCRSxTQUFTLEVBQUU7TUFBRUYsSUFBSSxF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
|