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.
Files changed (240) hide show
  1. package/LICENSE +167 -25
  2. package/NOTICE +10 -0
  3. package/README.md +929 -278
  4. package/lib/AccountLockout.js +47 -30
  5. package/lib/Adapters/AdapterLoader.js +21 -6
  6. package/lib/Adapters/Analytics/AnalyticsAdapter.js +15 -12
  7. package/lib/Adapters/Auth/AuthAdapter.js +116 -13
  8. package/lib/Adapters/Auth/BaseCodeAuthAdapter.js +99 -0
  9. package/lib/Adapters/Auth/OAuth1Client.js +27 -46
  10. package/lib/Adapters/Auth/apple.js +123 -0
  11. package/lib/Adapters/Auth/facebook.js +162 -35
  12. package/lib/Adapters/Auth/gcenter.js +217 -0
  13. package/lib/Adapters/Auth/github.js +118 -48
  14. package/lib/Adapters/Auth/google.js +160 -51
  15. package/lib/Adapters/Auth/gpgames.js +125 -0
  16. package/lib/Adapters/Auth/httpsRequest.js +6 -7
  17. package/lib/Adapters/Auth/index.js +170 -62
  18. package/lib/Adapters/Auth/instagram.js +114 -40
  19. package/lib/Adapters/Auth/janraincapture.js +52 -23
  20. package/lib/Adapters/Auth/janrainengage.js +19 -36
  21. package/lib/Adapters/Auth/keycloak.js +148 -0
  22. package/lib/Adapters/Auth/ldap.js +167 -0
  23. package/lib/Adapters/Auth/line.js +125 -0
  24. package/lib/Adapters/Auth/linkedin.js +111 -55
  25. package/lib/Adapters/Auth/meetup.js +24 -34
  26. package/lib/Adapters/Auth/mfa.js +324 -0
  27. package/lib/Adapters/Auth/microsoft.js +111 -0
  28. package/lib/Adapters/Auth/oauth2.js +97 -162
  29. package/lib/Adapters/Auth/phantauth.js +53 -0
  30. package/lib/Adapters/Auth/qq.js +108 -49
  31. package/lib/Adapters/Auth/spotify.js +107 -55
  32. package/lib/Adapters/Auth/twitter.js +188 -48
  33. package/lib/Adapters/Auth/utils.js +28 -0
  34. package/lib/Adapters/Auth/vkontakte.js +26 -39
  35. package/lib/Adapters/Auth/wechat.js +106 -44
  36. package/lib/Adapters/Auth/weibo.js +132 -58
  37. package/lib/Adapters/Cache/CacheAdapter.js +13 -8
  38. package/lib/Adapters/Cache/InMemoryCache.js +3 -13
  39. package/lib/Adapters/Cache/InMemoryCacheAdapter.js +5 -13
  40. package/lib/Adapters/Cache/LRUCache.js +13 -27
  41. package/lib/Adapters/Cache/NullCacheAdapter.js +3 -8
  42. package/lib/Adapters/Cache/RedisCacheAdapter.js +85 -76
  43. package/lib/Adapters/Cache/SchemaCache.js +25 -0
  44. package/lib/Adapters/Email/MailAdapter.js +10 -8
  45. package/lib/Adapters/Files/FilesAdapter.js +83 -25
  46. package/lib/Adapters/Files/GridFSBucketAdapter.js +231 -0
  47. package/lib/Adapters/Files/GridStoreAdapter.js +4 -91
  48. package/lib/Adapters/Logger/LoggerAdapter.js +18 -14
  49. package/lib/Adapters/Logger/WinstonLogger.js +69 -88
  50. package/lib/Adapters/Logger/WinstonLoggerAdapter.js +7 -16
  51. package/lib/Adapters/MessageQueue/EventEmitterMQ.js +8 -26
  52. package/lib/Adapters/PubSub/EventEmitterPubSub.js +12 -25
  53. package/lib/Adapters/PubSub/PubSubAdapter.js +34 -0
  54. package/lib/Adapters/PubSub/RedisPubSub.js +42 -19
  55. package/lib/Adapters/Push/PushAdapter.js +14 -7
  56. package/lib/Adapters/Storage/Mongo/MongoCollection.js +137 -45
  57. package/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js +158 -63
  58. package/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js +320 -168
  59. package/lib/Adapters/Storage/Mongo/MongoTransform.js +279 -306
  60. package/lib/Adapters/Storage/Postgres/PostgresClient.js +14 -10
  61. package/lib/Adapters/Storage/Postgres/PostgresConfigParser.js +47 -21
  62. package/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js +854 -468
  63. package/lib/Adapters/Storage/Postgres/sql/index.js +4 -6
  64. package/lib/Adapters/Storage/StorageAdapter.js +1 -1
  65. package/lib/Adapters/WebSocketServer/WSAdapter.js +35 -0
  66. package/lib/Adapters/WebSocketServer/WSSAdapter.js +66 -0
  67. package/lib/Auth.js +488 -125
  68. package/lib/ClientSDK.js +2 -6
  69. package/lib/Config.js +525 -94
  70. package/lib/Controllers/AdaptableController.js +5 -25
  71. package/lib/Controllers/AnalyticsController.js +22 -23
  72. package/lib/Controllers/CacheController.js +10 -31
  73. package/lib/Controllers/DatabaseController.js +767 -313
  74. package/lib/Controllers/FilesController.js +49 -54
  75. package/lib/Controllers/HooksController.js +80 -84
  76. package/lib/Controllers/LiveQueryController.js +35 -22
  77. package/lib/Controllers/LoggerController.js +22 -58
  78. package/lib/Controllers/ParseGraphQLController.js +293 -0
  79. package/lib/Controllers/PushController.js +58 -49
  80. package/lib/Controllers/SchemaController.js +916 -422
  81. package/lib/Controllers/UserController.js +265 -180
  82. package/lib/Controllers/index.js +90 -125
  83. package/lib/Controllers/types.js +1 -1
  84. package/lib/Deprecator/Deprecations.js +30 -0
  85. package/lib/Deprecator/Deprecator.js +127 -0
  86. package/lib/Error.js +48 -0
  87. package/lib/GraphQL/ParseGraphQLSchema.js +375 -0
  88. package/lib/GraphQL/ParseGraphQLServer.js +214 -0
  89. package/lib/GraphQL/helpers/objectsMutations.js +30 -0
  90. package/lib/GraphQL/helpers/objectsQueries.js +246 -0
  91. package/lib/GraphQL/loaders/configMutations.js +87 -0
  92. package/lib/GraphQL/loaders/configQueries.js +79 -0
  93. package/lib/GraphQL/loaders/defaultGraphQLMutations.js +21 -0
  94. package/lib/GraphQL/loaders/defaultGraphQLQueries.js +23 -0
  95. package/lib/GraphQL/loaders/defaultGraphQLTypes.js +1098 -0
  96. package/lib/GraphQL/loaders/defaultRelaySchema.js +53 -0
  97. package/lib/GraphQL/loaders/filesMutations.js +107 -0
  98. package/lib/GraphQL/loaders/functionsMutations.js +78 -0
  99. package/lib/GraphQL/loaders/parseClassMutations.js +268 -0
  100. package/lib/GraphQL/loaders/parseClassQueries.js +127 -0
  101. package/lib/GraphQL/loaders/parseClassTypes.js +493 -0
  102. package/lib/GraphQL/loaders/schemaDirectives.js +62 -0
  103. package/lib/GraphQL/loaders/schemaMutations.js +162 -0
  104. package/lib/GraphQL/loaders/schemaQueries.js +81 -0
  105. package/lib/GraphQL/loaders/schemaTypes.js +341 -0
  106. package/lib/GraphQL/loaders/usersMutations.js +433 -0
  107. package/lib/GraphQL/loaders/usersQueries.js +90 -0
  108. package/lib/GraphQL/parseGraphQLUtils.js +63 -0
  109. package/lib/GraphQL/transformers/className.js +14 -0
  110. package/lib/GraphQL/transformers/constraintType.js +53 -0
  111. package/lib/GraphQL/transformers/inputType.js +51 -0
  112. package/lib/GraphQL/transformers/mutation.js +274 -0
  113. package/lib/GraphQL/transformers/outputType.js +51 -0
  114. package/lib/GraphQL/transformers/query.js +237 -0
  115. package/lib/GraphQL/transformers/schemaFields.js +99 -0
  116. package/lib/KeyPromiseQueue.js +48 -0
  117. package/lib/LiveQuery/Client.js +25 -33
  118. package/lib/LiveQuery/Id.js +2 -5
  119. package/lib/LiveQuery/ParseCloudCodePublisher.js +26 -23
  120. package/lib/LiveQuery/ParseLiveQueryServer.js +560 -285
  121. package/lib/LiveQuery/ParsePubSub.js +7 -16
  122. package/lib/LiveQuery/ParseWebSocketServer.js +42 -39
  123. package/lib/LiveQuery/QueryTools.js +76 -15
  124. package/lib/LiveQuery/RequestSchema.js +111 -97
  125. package/lib/LiveQuery/SessionTokenCache.js +23 -36
  126. package/lib/LiveQuery/Subscription.js +8 -17
  127. package/lib/LiveQuery/equalObjects.js +2 -3
  128. package/lib/Options/Definitions.js +1355 -382
  129. package/lib/Options/docs.js +301 -62
  130. package/lib/Options/index.js +11 -1
  131. package/lib/Options/parsers.js +14 -10
  132. package/lib/Page.js +44 -0
  133. package/lib/ParseMessageQueue.js +6 -13
  134. package/lib/ParseServer.js +474 -235
  135. package/lib/ParseServerRESTController.js +102 -40
  136. package/lib/PromiseRouter.js +39 -50
  137. package/lib/Push/PushQueue.js +24 -30
  138. package/lib/Push/PushWorker.js +32 -56
  139. package/lib/Push/utils.js +22 -35
  140. package/lib/RestQuery.js +361 -139
  141. package/lib/RestWrite.js +713 -344
  142. package/lib/Routers/AggregateRouter.js +97 -71
  143. package/lib/Routers/AnalyticsRouter.js +8 -14
  144. package/lib/Routers/AudiencesRouter.js +16 -35
  145. package/lib/Routers/ClassesRouter.js +86 -72
  146. package/lib/Routers/CloudCodeRouter.js +28 -37
  147. package/lib/Routers/FeaturesRouter.js +22 -25
  148. package/lib/Routers/FilesRouter.js +266 -171
  149. package/lib/Routers/FunctionsRouter.js +87 -103
  150. package/lib/Routers/GlobalConfigRouter.js +94 -33
  151. package/lib/Routers/GraphQLRouter.js +41 -0
  152. package/lib/Routers/HooksRouter.js +43 -47
  153. package/lib/Routers/IAPValidationRouter.js +57 -70
  154. package/lib/Routers/InstallationsRouter.js +17 -25
  155. package/lib/Routers/LogsRouter.js +10 -25
  156. package/lib/Routers/PagesRouter.js +647 -0
  157. package/lib/Routers/PublicAPIRouter.js +104 -112
  158. package/lib/Routers/PurgeRouter.js +19 -29
  159. package/lib/Routers/PushRouter.js +14 -28
  160. package/lib/Routers/RolesRouter.js +7 -14
  161. package/lib/Routers/SchemasRouter.js +63 -42
  162. package/lib/Routers/SecurityRouter.js +34 -0
  163. package/lib/Routers/SessionsRouter.js +25 -38
  164. package/lib/Routers/UsersRouter.js +463 -190
  165. package/lib/SchemaMigrations/DefinedSchemas.js +379 -0
  166. package/lib/SchemaMigrations/Migrations.js +30 -0
  167. package/lib/Security/Check.js +109 -0
  168. package/lib/Security/CheckGroup.js +44 -0
  169. package/lib/Security/CheckGroups/CheckGroupDatabase.js +44 -0
  170. package/lib/Security/CheckGroups/CheckGroupServerConfig.js +96 -0
  171. package/lib/Security/CheckGroups/CheckGroups.js +21 -0
  172. package/lib/Security/CheckRunner.js +213 -0
  173. package/lib/SharedRest.js +29 -0
  174. package/lib/StatusHandler.js +96 -93
  175. package/lib/TestUtils.js +70 -14
  176. package/lib/Utils.js +468 -0
  177. package/lib/batch.js +74 -40
  178. package/lib/cache.js +8 -8
  179. package/lib/cli/definitions/parse-live-query-server.js +4 -3
  180. package/lib/cli/definitions/parse-server.js +4 -3
  181. package/lib/cli/parse-live-query-server.js +9 -17
  182. package/lib/cli/parse-server.js +49 -47
  183. package/lib/cli/utils/commander.js +20 -29
  184. package/lib/cli/utils/runner.js +31 -32
  185. package/lib/cloud-code/Parse.Cloud.js +711 -36
  186. package/lib/cloud-code/Parse.Server.js +21 -0
  187. package/lib/cryptoUtils.js +6 -11
  188. package/lib/defaults.js +21 -15
  189. package/lib/deprecated.js +1 -1
  190. package/lib/index.js +78 -67
  191. package/lib/logger.js +12 -20
  192. package/lib/middlewares.js +484 -160
  193. package/lib/password.js +10 -6
  194. package/lib/request.js +175 -0
  195. package/lib/requiredParameter.js +4 -3
  196. package/lib/rest.js +157 -82
  197. package/lib/triggers.js +627 -185
  198. package/lib/vendor/README.md +3 -3
  199. package/lib/vendor/mongodbUrl.js +224 -137
  200. package/package.json +135 -57
  201. package/postinstall.js +38 -50
  202. package/public_html/invalid_verification_link.html +3 -3
  203. package/types/@types/@parse/fs-files-adapter/index.d.ts +5 -0
  204. package/types/@types/deepcopy/index.d.ts +5 -0
  205. package/types/LiveQuery/ParseLiveQueryServer.d.ts +40 -0
  206. package/types/Options/index.d.ts +301 -0
  207. package/types/ParseServer.d.ts +65 -0
  208. package/types/eslint.config.mjs +30 -0
  209. package/types/index.d.ts +21 -0
  210. package/types/logger.d.ts +2 -0
  211. package/types/tests.ts +44 -0
  212. package/types/tsconfig.json +24 -0
  213. package/CHANGELOG.md +0 -1246
  214. package/PATENTS +0 -37
  215. package/bin/dev +0 -37
  216. package/lib/.DS_Store +0 -0
  217. package/lib/Adapters/Auth/common.js +0 -2
  218. package/lib/Adapters/Auth/facebookaccountkit.js +0 -69
  219. package/lib/Controllers/SchemaCache.js +0 -97
  220. package/lib/LiveQuery/.DS_Store +0 -0
  221. package/lib/cli/utils/parsers.js +0 -77
  222. package/lib/cloud-code/.DS_Store +0 -0
  223. package/lib/cloud-code/HTTPResponse.js +0 -57
  224. package/lib/cloud-code/Untitled-1 +0 -123
  225. package/lib/cloud-code/httpRequest.js +0 -102
  226. package/lib/cloud-code/team.html +0 -123
  227. package/lib/graphql/ParseClass.js +0 -234
  228. package/lib/graphql/Schema.js +0 -197
  229. package/lib/graphql/index.js +0 -1
  230. package/lib/graphql/types/ACL.js +0 -35
  231. package/lib/graphql/types/Date.js +0 -25
  232. package/lib/graphql/types/File.js +0 -24
  233. package/lib/graphql/types/GeoPoint.js +0 -35
  234. package/lib/graphql/types/JSONObject.js +0 -30
  235. package/lib/graphql/types/NumberInput.js +0 -43
  236. package/lib/graphql/types/NumberQuery.js +0 -42
  237. package/lib/graphql/types/Pointer.js +0 -35
  238. package/lib/graphql/types/QueryConstraint.js +0 -61
  239. package/lib/graphql/types/StringQuery.js +0 -39
  240. package/lib/graphql/types/index.js +0 -110
package/lib/Config.js CHANGED
@@ -1,28 +1,19 @@
1
- 'use strict';
1
+ "use strict";
2
2
 
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.Config = undefined;
7
-
8
- var _cache = require('./cache');
9
-
10
- var _cache2 = _interopRequireDefault(_cache);
11
-
12
- var _SchemaCache = require('./Controllers/SchemaCache');
13
-
14
- var _SchemaCache2 = _interopRequireDefault(_SchemaCache);
15
-
16
- var _DatabaseController = require('./Controllers/DatabaseController');
17
-
18
- var _DatabaseController2 = _interopRequireDefault(_DatabaseController);
19
-
20
- var _net = require('net');
21
-
22
- var _net2 = _interopRequireDefault(_net);
23
-
24
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
25
-
6
+ exports.default = exports.Config = void 0;
7
+ var _lodash = require("lodash");
8
+ var _net = _interopRequireDefault(require("net"));
9
+ var _cache = _interopRequireDefault(require("./cache"));
10
+ var _DatabaseController = _interopRequireDefault(require("./Controllers/DatabaseController"));
11
+ var _LoggerController = require("./Controllers/LoggerController");
12
+ var _package = require("../package.json");
13
+ var _Definitions = require("./Options/Definitions");
14
+ var _Parse = _interopRequireDefault(require("./cloud-code/Parse.Server"));
15
+ var _Deprecator = _interopRequireDefault(require("./Deprecator/Deprecator"));
16
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
26
17
  // A Config object provides information about how a specific app is
27
18
  // configured.
28
19
  // mount is the URL for the root of the API; includes http, domain, etc.
@@ -31,15 +22,19 @@ function removeTrailingSlash(str) {
31
22
  if (!str) {
32
23
  return str;
33
24
  }
34
- if (str.endsWith("/")) {
35
- str = str.substr(0, str.length - 1);
25
+ if (str.endsWith('/')) {
26
+ str = str.substring(0, str.length - 1);
36
27
  }
37
28
  return str;
38
29
  }
39
30
 
31
+ /**
32
+ * Config keys that need to be loaded asynchronously.
33
+ */
34
+ const asyncKeys = ['publicServerURL'];
40
35
  class Config {
41
36
  static get(applicationId, mount) {
42
- const cacheInfo = _cache2.default.get(applicationId);
37
+ const cacheInfo = _cache.default.get(applicationId);
43
38
  if (!cacheInfo) {
44
39
  return;
45
40
  }
@@ -47,8 +42,7 @@ class Config {
47
42
  config.applicationId = applicationId;
48
43
  Object.keys(cacheInfo).forEach(key => {
49
44
  if (key == 'databaseController') {
50
- const schemaCache = new _SchemaCache2.default(cacheInfo.cacheController, cacheInfo.schemaCacheTTL, cacheInfo.enableSingleSchemaCache);
51
- config.database = new _DatabaseController2.default(cacheInfo.databaseController.adapter, schemaCache);
45
+ config.database = new _DatabaseController.default(cacheInfo.databaseController.adapter, config);
52
46
  } else {
53
47
  config[key] = cacheInfo[key];
54
48
  }
@@ -56,85 +50,318 @@ class Config {
56
50
  config.mount = removeTrailingSlash(mount);
57
51
  config.generateSessionExpiresAt = config.generateSessionExpiresAt.bind(config);
58
52
  config.generateEmailVerifyTokenExpiresAt = config.generateEmailVerifyTokenExpiresAt.bind(config);
53
+ config.version = _package.version;
59
54
  return config;
60
55
  }
61
-
56
+ async loadKeys() {
57
+ await Promise.all(asyncKeys.map(async key => {
58
+ if (typeof this[`_${key}`] === 'function') {
59
+ try {
60
+ this[key] = await this[`_${key}`]();
61
+ } catch (error) {
62
+ throw new Error(`Failed to resolve async config key '${key}': ${error.message}`);
63
+ }
64
+ }
65
+ }));
66
+ const cachedConfig = _cache.default.get(this.appId);
67
+ if (cachedConfig) {
68
+ const updatedConfig = {
69
+ ...cachedConfig
70
+ };
71
+ asyncKeys.forEach(key => {
72
+ updatedConfig[key] = this[key];
73
+ });
74
+ _cache.default.put(this.appId, updatedConfig);
75
+ }
76
+ }
77
+ static transformConfiguration(serverConfiguration) {
78
+ for (const key of Object.keys(serverConfiguration)) {
79
+ if (asyncKeys.includes(key) && typeof serverConfiguration[key] === 'function') {
80
+ serverConfiguration[`_${key}`] = serverConfiguration[key];
81
+ delete serverConfiguration[key];
82
+ }
83
+ }
84
+ }
62
85
  static put(serverConfiguration) {
63
- Config.validate(serverConfiguration);
64
- _cache2.default.put(serverConfiguration.appId, serverConfiguration);
86
+ Config.validateOptions(serverConfiguration);
87
+ Config.validateControllers(serverConfiguration);
88
+ Config.transformConfiguration(serverConfiguration);
89
+ _cache.default.put(serverConfiguration.appId, serverConfiguration);
65
90
  Config.setupPasswordValidator(serverConfiguration.passwordPolicy);
66
91
  return serverConfiguration;
67
92
  }
68
-
69
- static validate({
70
- verifyUserEmails,
71
- userController,
72
- appName,
93
+ static validateOptions({
94
+ customPages,
73
95
  publicServerURL,
74
96
  revokeSessionOnPasswordReset,
75
97
  expireInactiveSessions,
76
98
  sessionLength,
99
+ defaultLimit,
77
100
  maxLimit,
78
- emailVerifyTokenValidityDuration,
79
101
  accountLockout,
80
102
  passwordPolicy,
81
103
  masterKeyIps,
82
104
  masterKey,
83
- readOnlyMasterKey
105
+ maintenanceKey,
106
+ maintenanceKeyIps,
107
+ readOnlyMasterKey,
108
+ allowHeaders,
109
+ idempotencyOptions,
110
+ fileUpload,
111
+ pages,
112
+ security,
113
+ enforcePrivateUsers,
114
+ enableInsecureAuthAdapters,
115
+ schema,
116
+ requestKeywordDenylist,
117
+ allowExpiredAuthDataToken,
118
+ logLevels,
119
+ rateLimit,
120
+ databaseOptions,
121
+ extendSessionOnUse,
122
+ allowClientClassCreation
84
123
  }) {
85
-
86
124
  if (masterKey === readOnlyMasterKey) {
87
125
  throw new Error('masterKey and readOnlyMasterKey should be different');
88
126
  }
89
-
90
- const emailAdapter = userController.adapter;
91
- if (verifyUserEmails) {
92
- this.validateEmailConfiguration({ emailAdapter, appName, publicServerURL, emailVerifyTokenValidityDuration });
127
+ if (masterKey === maintenanceKey) {
128
+ throw new Error('masterKey and maintenanceKey should be different');
93
129
  }
94
-
95
130
  this.validateAccountLockoutPolicy(accountLockout);
96
-
97
131
  this.validatePasswordPolicy(passwordPolicy);
98
-
132
+ this.validateFileUploadOptions(fileUpload);
99
133
  if (typeof revokeSessionOnPasswordReset !== 'boolean') {
100
134
  throw 'revokeSessionOnPasswordReset must be a boolean value';
101
135
  }
102
-
103
- if (publicServerURL) {
104
- if (!publicServerURL.startsWith("http://") && !publicServerURL.startsWith("https://")) {
105
- throw "publicServerURL should be a valid HTTPS URL starting with https://";
106
- }
136
+ if (typeof extendSessionOnUse !== 'boolean') {
137
+ throw 'extendSessionOnUse must be a boolean value';
107
138
  }
108
-
139
+ this.validatePublicServerURL({
140
+ publicServerURL
141
+ });
109
142
  this.validateSessionConfiguration(sessionLength, expireInactiveSessions);
110
-
111
- this.validateMasterKeyIps(masterKeyIps);
112
-
143
+ this.validateIps('masterKeyIps', masterKeyIps);
144
+ this.validateIps('maintenanceKeyIps', maintenanceKeyIps);
145
+ this.validateDefaultLimit(defaultLimit);
113
146
  this.validateMaxLimit(maxLimit);
147
+ this.validateAllowHeaders(allowHeaders);
148
+ this.validateIdempotencyOptions(idempotencyOptions);
149
+ this.validatePagesOptions(pages);
150
+ this.validateSecurityOptions(security);
151
+ this.validateSchemaOptions(schema);
152
+ this.validateEnforcePrivateUsers(enforcePrivateUsers);
153
+ this.validateEnableInsecureAuthAdapters(enableInsecureAuthAdapters);
154
+ this.validateAllowExpiredAuthDataToken(allowExpiredAuthDataToken);
155
+ this.validateRequestKeywordDenylist(requestKeywordDenylist);
156
+ this.validateRateLimit(rateLimit);
157
+ this.validateLogLevels(logLevels);
158
+ this.validateDatabaseOptions(databaseOptions);
159
+ this.validateCustomPages(customPages);
160
+ this.validateAllowClientClassCreation(allowClientClassCreation);
161
+ }
162
+ static validateCustomPages(customPages) {
163
+ if (!customPages) {
164
+ return;
165
+ }
166
+ if (Object.prototype.toString.call(customPages) !== '[object Object]') {
167
+ throw Error('Parse Server option customPages must be an object.');
168
+ }
169
+ }
170
+ static validateControllers({
171
+ verifyUserEmails,
172
+ userController,
173
+ appName,
174
+ publicServerURL,
175
+ _publicServerURL,
176
+ emailVerifyTokenValidityDuration,
177
+ emailVerifyTokenReuseIfValid
178
+ }) {
179
+ const emailAdapter = userController.adapter;
180
+ if (verifyUserEmails) {
181
+ this.validateEmailConfiguration({
182
+ emailAdapter,
183
+ appName,
184
+ publicServerURL: publicServerURL || _publicServerURL,
185
+ emailVerifyTokenValidityDuration,
186
+ emailVerifyTokenReuseIfValid
187
+ });
188
+ }
189
+ }
190
+ static validateRequestKeywordDenylist(requestKeywordDenylist) {
191
+ if (requestKeywordDenylist === undefined) {
192
+ requestKeywordDenylist = requestKeywordDenylist.default;
193
+ } else if (!Array.isArray(requestKeywordDenylist)) {
194
+ throw 'Parse Server option requestKeywordDenylist must be an array.';
195
+ }
196
+ }
197
+ static validateEnforcePrivateUsers(enforcePrivateUsers) {
198
+ if (typeof enforcePrivateUsers !== 'boolean') {
199
+ throw 'Parse Server option enforcePrivateUsers must be a boolean.';
200
+ }
201
+ }
202
+ static validateAllowExpiredAuthDataToken(allowExpiredAuthDataToken) {
203
+ if (typeof allowExpiredAuthDataToken !== 'boolean') {
204
+ throw 'Parse Server option allowExpiredAuthDataToken must be a boolean.';
205
+ }
206
+ }
207
+ static validateAllowClientClassCreation(allowClientClassCreation) {
208
+ if (typeof allowClientClassCreation !== 'boolean') {
209
+ throw 'Parse Server option allowClientClassCreation must be a boolean.';
210
+ }
211
+ }
212
+ static validateSecurityOptions(security) {
213
+ if (Object.prototype.toString.call(security) !== '[object Object]') {
214
+ throw 'Parse Server option security must be an object.';
215
+ }
216
+ if (security.enableCheck === undefined) {
217
+ security.enableCheck = _Definitions.SecurityOptions.enableCheck.default;
218
+ } else if (!(0, _lodash.isBoolean)(security.enableCheck)) {
219
+ throw 'Parse Server option security.enableCheck must be a boolean.';
220
+ }
221
+ if (security.enableCheckLog === undefined) {
222
+ security.enableCheckLog = _Definitions.SecurityOptions.enableCheckLog.default;
223
+ } else if (!(0, _lodash.isBoolean)(security.enableCheckLog)) {
224
+ throw 'Parse Server option security.enableCheckLog must be a boolean.';
225
+ }
226
+ }
227
+ static validateSchemaOptions(schema) {
228
+ if (!schema) {
229
+ return;
230
+ }
231
+ if (Object.prototype.toString.call(schema) !== '[object Object]') {
232
+ throw 'Parse Server option schema must be an object.';
233
+ }
234
+ if (schema.definitions === undefined) {
235
+ schema.definitions = _Definitions.SchemaOptions.definitions.default;
236
+ } else if (!Array.isArray(schema.definitions)) {
237
+ throw 'Parse Server option schema.definitions must be an array.';
238
+ }
239
+ if (schema.strict === undefined) {
240
+ schema.strict = _Definitions.SchemaOptions.strict.default;
241
+ } else if (!(0, _lodash.isBoolean)(schema.strict)) {
242
+ throw 'Parse Server option schema.strict must be a boolean.';
243
+ }
244
+ if (schema.deleteExtraFields === undefined) {
245
+ schema.deleteExtraFields = _Definitions.SchemaOptions.deleteExtraFields.default;
246
+ } else if (!(0, _lodash.isBoolean)(schema.deleteExtraFields)) {
247
+ throw 'Parse Server option schema.deleteExtraFields must be a boolean.';
248
+ }
249
+ if (schema.recreateModifiedFields === undefined) {
250
+ schema.recreateModifiedFields = _Definitions.SchemaOptions.recreateModifiedFields.default;
251
+ } else if (!(0, _lodash.isBoolean)(schema.recreateModifiedFields)) {
252
+ throw 'Parse Server option schema.recreateModifiedFields must be a boolean.';
253
+ }
254
+ if (schema.lockSchemas === undefined) {
255
+ schema.lockSchemas = _Definitions.SchemaOptions.lockSchemas.default;
256
+ } else if (!(0, _lodash.isBoolean)(schema.lockSchemas)) {
257
+ throw 'Parse Server option schema.lockSchemas must be a boolean.';
258
+ }
259
+ if (schema.beforeMigration === undefined) {
260
+ schema.beforeMigration = null;
261
+ } else if (schema.beforeMigration !== null && typeof schema.beforeMigration !== 'function') {
262
+ throw 'Parse Server option schema.beforeMigration must be a function.';
263
+ }
264
+ if (schema.afterMigration === undefined) {
265
+ schema.afterMigration = null;
266
+ } else if (schema.afterMigration !== null && typeof schema.afterMigration !== 'function') {
267
+ throw 'Parse Server option schema.afterMigration must be a function.';
268
+ }
269
+ }
270
+ static validatePagesOptions(pages) {
271
+ if (Object.prototype.toString.call(pages) !== '[object Object]') {
272
+ throw 'Parse Server option pages must be an object.';
273
+ }
274
+ if (pages.enableRouter === undefined) {
275
+ pages.enableRouter = _Definitions.PagesOptions.enableRouter.default;
276
+ } else if (!(0, _lodash.isBoolean)(pages.enableRouter)) {
277
+ throw 'Parse Server option pages.enableRouter must be a boolean.';
278
+ }
279
+ if (pages.enableLocalization === undefined) {
280
+ pages.enableLocalization = _Definitions.PagesOptions.enableLocalization.default;
281
+ } else if (!(0, _lodash.isBoolean)(pages.enableLocalization)) {
282
+ throw 'Parse Server option pages.enableLocalization must be a boolean.';
283
+ }
284
+ if (pages.localizationJsonPath === undefined) {
285
+ pages.localizationJsonPath = _Definitions.PagesOptions.localizationJsonPath.default;
286
+ } else if (!(0, _lodash.isString)(pages.localizationJsonPath)) {
287
+ throw 'Parse Server option pages.localizationJsonPath must be a string.';
288
+ }
289
+ if (pages.localizationFallbackLocale === undefined) {
290
+ pages.localizationFallbackLocale = _Definitions.PagesOptions.localizationFallbackLocale.default;
291
+ } else if (!(0, _lodash.isString)(pages.localizationFallbackLocale)) {
292
+ throw 'Parse Server option pages.localizationFallbackLocale must be a string.';
293
+ }
294
+ if (pages.placeholders === undefined) {
295
+ pages.placeholders = _Definitions.PagesOptions.placeholders.default;
296
+ } else if (Object.prototype.toString.call(pages.placeholders) !== '[object Object]' && typeof pages.placeholders !== 'function') {
297
+ throw 'Parse Server option pages.placeholders must be an object or a function.';
298
+ }
299
+ if (pages.forceRedirect === undefined) {
300
+ pages.forceRedirect = _Definitions.PagesOptions.forceRedirect.default;
301
+ } else if (!(0, _lodash.isBoolean)(pages.forceRedirect)) {
302
+ throw 'Parse Server option pages.forceRedirect must be a boolean.';
303
+ }
304
+ if (pages.pagesPath === undefined) {
305
+ pages.pagesPath = _Definitions.PagesOptions.pagesPath.default;
306
+ } else if (!(0, _lodash.isString)(pages.pagesPath)) {
307
+ throw 'Parse Server option pages.pagesPath must be a string.';
308
+ }
309
+ if (pages.pagesEndpoint === undefined) {
310
+ pages.pagesEndpoint = _Definitions.PagesOptions.pagesEndpoint.default;
311
+ } else if (!(0, _lodash.isString)(pages.pagesEndpoint)) {
312
+ throw 'Parse Server option pages.pagesEndpoint must be a string.';
313
+ }
314
+ if (pages.customUrls === undefined) {
315
+ pages.customUrls = _Definitions.PagesOptions.customUrls.default;
316
+ } else if (Object.prototype.toString.call(pages.customUrls) !== '[object Object]') {
317
+ throw 'Parse Server option pages.customUrls must be an object.';
318
+ }
319
+ if (pages.customRoutes === undefined) {
320
+ pages.customRoutes = _Definitions.PagesOptions.customRoutes.default;
321
+ } else if (!(pages.customRoutes instanceof Array)) {
322
+ throw 'Parse Server option pages.customRoutes must be an array.';
323
+ }
324
+ }
325
+ static validateIdempotencyOptions(idempotencyOptions) {
326
+ if (!idempotencyOptions) {
327
+ return;
328
+ }
329
+ if (idempotencyOptions.ttl === undefined) {
330
+ idempotencyOptions.ttl = _Definitions.IdempotencyOptions.ttl.default;
331
+ } else if (!isNaN(idempotencyOptions.ttl) && idempotencyOptions.ttl <= 0) {
332
+ throw 'idempotency TTL value must be greater than 0 seconds';
333
+ } else if (isNaN(idempotencyOptions.ttl)) {
334
+ throw 'idempotency TTL value must be a number';
335
+ }
336
+ if (!idempotencyOptions.paths) {
337
+ idempotencyOptions.paths = _Definitions.IdempotencyOptions.paths.default;
338
+ } else if (!(idempotencyOptions.paths instanceof Array)) {
339
+ throw 'idempotency paths must be of an array of strings';
340
+ }
114
341
  }
115
-
116
342
  static validateAccountLockoutPolicy(accountLockout) {
117
343
  if (accountLockout) {
118
344
  if (typeof accountLockout.duration !== 'number' || accountLockout.duration <= 0 || accountLockout.duration > 99999) {
119
345
  throw 'Account lockout duration should be greater than 0 and less than 100000';
120
346
  }
121
-
122
347
  if (!Number.isInteger(accountLockout.threshold) || accountLockout.threshold < 1 || accountLockout.threshold > 999) {
123
348
  throw 'Account lockout threshold should be an integer greater than 0 and less than 1000';
124
349
  }
350
+ if (accountLockout.unlockOnPasswordReset === undefined) {
351
+ accountLockout.unlockOnPasswordReset = _Definitions.AccountLockoutOptions.unlockOnPasswordReset.default;
352
+ } else if (!(0, _lodash.isBoolean)(accountLockout.unlockOnPasswordReset)) {
353
+ throw 'Parse Server option accountLockout.unlockOnPasswordReset must be a boolean.';
354
+ }
125
355
  }
126
356
  }
127
-
128
357
  static validatePasswordPolicy(passwordPolicy) {
129
358
  if (passwordPolicy) {
130
359
  if (passwordPolicy.maxPasswordAge !== undefined && (typeof passwordPolicy.maxPasswordAge !== 'number' || passwordPolicy.maxPasswordAge < 0)) {
131
360
  throw 'passwordPolicy.maxPasswordAge must be a positive number';
132
361
  }
133
-
134
362
  if (passwordPolicy.resetTokenValidityDuration !== undefined && (typeof passwordPolicy.resetTokenValidityDuration !== 'number' || passwordPolicy.resetTokenValidityDuration <= 0)) {
135
363
  throw 'passwordPolicy.resetTokenValidityDuration must be a positive number';
136
364
  }
137
-
138
365
  if (passwordPolicy.validatorPattern) {
139
366
  if (typeof passwordPolicy.validatorPattern === 'string') {
140
367
  passwordPolicy.validatorPattern = new RegExp(passwordPolicy.validatorPattern);
@@ -142,18 +369,24 @@ class Config {
142
369
  throw 'passwordPolicy.validatorPattern must be a regex string or RegExp object.';
143
370
  }
144
371
  }
145
-
146
372
  if (passwordPolicy.validatorCallback && typeof passwordPolicy.validatorCallback !== 'function') {
147
373
  throw 'passwordPolicy.validatorCallback must be a function.';
148
374
  }
149
-
150
375
  if (passwordPolicy.doNotAllowUsername && typeof passwordPolicy.doNotAllowUsername !== 'boolean') {
151
376
  throw 'passwordPolicy.doNotAllowUsername must be a boolean value.';
152
377
  }
153
-
154
378
  if (passwordPolicy.maxPasswordHistory && (!Number.isInteger(passwordPolicy.maxPasswordHistory) || passwordPolicy.maxPasswordHistory <= 0 || passwordPolicy.maxPasswordHistory > 20)) {
155
379
  throw 'passwordPolicy.maxPasswordHistory must be an integer ranging 0 - 20';
156
380
  }
381
+ if (passwordPolicy.resetTokenReuseIfValid && typeof passwordPolicy.resetTokenReuseIfValid !== 'boolean') {
382
+ throw 'resetTokenReuseIfValid must be a boolean value';
383
+ }
384
+ if (passwordPolicy.resetTokenReuseIfValid && !passwordPolicy.resetTokenValidityDuration) {
385
+ throw 'You cannot use resetTokenReuseIfValid without resetTokenValidityDuration';
386
+ }
387
+ if (passwordPolicy.resetPasswordSuccessOnInvalidEmail && typeof passwordPolicy.resetPasswordSuccessOnInvalidEmail !== 'boolean') {
388
+ throw 'resetPasswordSuccessOnInvalidEmail must be a boolean value';
389
+ }
157
390
  }
158
391
  }
159
392
 
@@ -165,17 +398,45 @@ class Config {
165
398
  };
166
399
  }
167
400
  }
168
-
169
- static validateEmailConfiguration({ emailAdapter, appName, publicServerURL, emailVerifyTokenValidityDuration }) {
401
+ static validatePublicServerURL({
402
+ publicServerURL,
403
+ required = false
404
+ }) {
405
+ if (!publicServerURL) {
406
+ if (!required) {
407
+ return;
408
+ }
409
+ throw 'The option publicServerURL is required.';
410
+ }
411
+ const type = typeof publicServerURL;
412
+ if (type === 'string') {
413
+ if (!publicServerURL.startsWith('http://') && !publicServerURL.startsWith('https://')) {
414
+ throw 'The option publicServerURL must be a valid URL starting with http:// or https://.';
415
+ }
416
+ return;
417
+ }
418
+ if (type === 'function') {
419
+ return;
420
+ }
421
+ throw `The option publicServerURL must be a string or function, but got ${type}.`;
422
+ }
423
+ static validateEmailConfiguration({
424
+ emailAdapter,
425
+ appName,
426
+ publicServerURL,
427
+ emailVerifyTokenValidityDuration,
428
+ emailVerifyTokenReuseIfValid
429
+ }) {
170
430
  if (!emailAdapter) {
171
431
  throw 'An emailAdapter is required for e-mail verification and password resets.';
172
432
  }
173
433
  if (typeof appName !== 'string') {
174
434
  throw 'An app name is required for e-mail verification and password resets.';
175
435
  }
176
- if (typeof publicServerURL !== 'string') {
177
- throw 'A public server url is required for e-mail verification and password resets.';
178
- }
436
+ this.validatePublicServerURL({
437
+ publicServerURL,
438
+ required: true
439
+ });
179
440
  if (emailVerifyTokenValidityDuration) {
180
441
  if (isNaN(emailVerifyTokenValidityDuration)) {
181
442
  throw 'Email verify token validity duration must be a valid number.';
@@ -183,16 +444,65 @@ class Config {
183
444
  throw 'Email verify token validity duration must be a value greater than 0.';
184
445
  }
185
446
  }
447
+ if (emailVerifyTokenReuseIfValid && typeof emailVerifyTokenReuseIfValid !== 'boolean') {
448
+ throw 'emailVerifyTokenReuseIfValid must be a boolean value';
449
+ }
450
+ if (emailVerifyTokenReuseIfValid && !emailVerifyTokenValidityDuration) {
451
+ throw 'You cannot use emailVerifyTokenReuseIfValid without emailVerifyTokenValidityDuration';
452
+ }
186
453
  }
187
-
188
- static validateMasterKeyIps(masterKeyIps) {
189
- for (const ip of masterKeyIps) {
190
- if (!_net2.default.isIP(ip)) {
191
- throw `Invalid ip in masterKeyIps: ${ip}`;
454
+ static validateFileUploadOptions(fileUpload) {
455
+ try {
456
+ if (fileUpload == null || typeof fileUpload !== 'object' || fileUpload instanceof Array) {
457
+ throw 'fileUpload must be an object value.';
458
+ }
459
+ } catch (e) {
460
+ if (e instanceof ReferenceError) {
461
+ return;
192
462
  }
463
+ throw e;
464
+ }
465
+ if (fileUpload.enableForAnonymousUser === undefined) {
466
+ fileUpload.enableForAnonymousUser = _Definitions.FileUploadOptions.enableForAnonymousUser.default;
467
+ } else if (typeof fileUpload.enableForAnonymousUser !== 'boolean') {
468
+ throw 'fileUpload.enableForAnonymousUser must be a boolean value.';
469
+ }
470
+ if (fileUpload.enableForPublic === undefined) {
471
+ fileUpload.enableForPublic = _Definitions.FileUploadOptions.enableForPublic.default;
472
+ } else if (typeof fileUpload.enableForPublic !== 'boolean') {
473
+ throw 'fileUpload.enableForPublic must be a boolean value.';
474
+ }
475
+ if (fileUpload.enableForAuthenticatedUser === undefined) {
476
+ fileUpload.enableForAuthenticatedUser = _Definitions.FileUploadOptions.enableForAuthenticatedUser.default;
477
+ } else if (typeof fileUpload.enableForAuthenticatedUser !== 'boolean') {
478
+ throw 'fileUpload.enableForAuthenticatedUser must be a boolean value.';
479
+ }
480
+ if (fileUpload.fileExtensions === undefined) {
481
+ fileUpload.fileExtensions = _Definitions.FileUploadOptions.fileExtensions.default;
482
+ } else if (!Array.isArray(fileUpload.fileExtensions)) {
483
+ throw 'fileUpload.fileExtensions must be an array.';
484
+ }
485
+ }
486
+ static validateIps(field, masterKeyIps) {
487
+ for (let ip of masterKeyIps) {
488
+ if (ip.includes('/')) {
489
+ ip = ip.split('/')[0];
490
+ }
491
+ if (!_net.default.isIP(ip)) {
492
+ throw `The Parse Server option "${field}" contains an invalid IP address "${ip}".`;
493
+ }
494
+ }
495
+ }
496
+ static validateEnableInsecureAuthAdapters(enableInsecureAuthAdapters) {
497
+ if (enableInsecureAuthAdapters && typeof enableInsecureAuthAdapters !== 'boolean') {
498
+ throw 'Parse Server option enableInsecureAuthAdapters must be a boolean.';
499
+ }
500
+ if (enableInsecureAuthAdapters) {
501
+ _Deprecator.default.logRuntimeDeprecation({
502
+ usage: 'insecure adapter'
503
+ });
193
504
  }
194
505
  }
195
-
196
506
  get mount() {
197
507
  var mount = this._mount;
198
508
  if (this.publicServerURL) {
@@ -200,11 +510,9 @@ class Config {
200
510
  }
201
511
  return mount;
202
512
  }
203
-
204
513
  set mount(newValue) {
205
514
  this._mount = newValue;
206
515
  }
207
-
208
516
  static validateSessionConfiguration(sessionLength, expireInactiveSessions) {
209
517
  if (expireInactiveSessions) {
210
518
  if (isNaN(sessionLength)) {
@@ -214,13 +522,117 @@ class Config {
214
522
  }
215
523
  }
216
524
  }
217
-
525
+ static validateDefaultLimit(defaultLimit) {
526
+ if (defaultLimit == null) {
527
+ defaultLimit = _Definitions.ParseServerOptions.defaultLimit.default;
528
+ }
529
+ if (typeof defaultLimit !== 'number') {
530
+ throw 'Default limit must be a number.';
531
+ }
532
+ if (defaultLimit <= 0) {
533
+ throw 'Default limit must be a value greater than 0.';
534
+ }
535
+ }
218
536
  static validateMaxLimit(maxLimit) {
219
537
  if (maxLimit <= 0) {
220
538
  throw 'Max limit must be a value greater than 0.';
221
539
  }
222
540
  }
223
-
541
+ static validateAllowHeaders(allowHeaders) {
542
+ if (![null, undefined].includes(allowHeaders)) {
543
+ if (Array.isArray(allowHeaders)) {
544
+ allowHeaders.forEach(header => {
545
+ if (typeof header !== 'string') {
546
+ throw 'Allow headers must only contain strings';
547
+ } else if (!header.trim().length) {
548
+ throw 'Allow headers must not contain empty strings';
549
+ }
550
+ });
551
+ } else {
552
+ throw 'Allow headers must be an array';
553
+ }
554
+ }
555
+ }
556
+ static validateLogLevels(logLevels) {
557
+ for (const key of Object.keys(_Definitions.LogLevels)) {
558
+ if (logLevels[key]) {
559
+ if (_LoggerController.logLevels.indexOf(logLevels[key]) === -1) {
560
+ throw `'${key}' must be one of ${JSON.stringify(_LoggerController.logLevels)}`;
561
+ }
562
+ } else {
563
+ logLevels[key] = _Definitions.LogLevels[key].default;
564
+ }
565
+ }
566
+ }
567
+ static validateDatabaseOptions(databaseOptions) {
568
+ if (databaseOptions == undefined) {
569
+ return;
570
+ }
571
+ if (Object.prototype.toString.call(databaseOptions) !== '[object Object]') {
572
+ throw `databaseOptions must be an object`;
573
+ }
574
+ if (databaseOptions.enableSchemaHooks === undefined) {
575
+ databaseOptions.enableSchemaHooks = _Definitions.DatabaseOptions.enableSchemaHooks.default;
576
+ } else if (typeof databaseOptions.enableSchemaHooks !== 'boolean') {
577
+ throw `databaseOptions.enableSchemaHooks must be a boolean`;
578
+ }
579
+ if (databaseOptions.schemaCacheTtl === undefined) {
580
+ databaseOptions.schemaCacheTtl = _Definitions.DatabaseOptions.schemaCacheTtl.default;
581
+ } else if (typeof databaseOptions.schemaCacheTtl !== 'number') {
582
+ throw `databaseOptions.schemaCacheTtl must be a number`;
583
+ }
584
+ if (databaseOptions.allowPublicExplain === undefined) {
585
+ databaseOptions.allowPublicExplain = _Definitions.DatabaseOptions.allowPublicExplain.default;
586
+ } else if (typeof databaseOptions.allowPublicExplain !== 'boolean') {
587
+ throw `Parse Server option 'databaseOptions.allowPublicExplain' must be a boolean.`;
588
+ }
589
+ }
590
+ static validateRateLimit(rateLimit) {
591
+ if (!rateLimit) {
592
+ return;
593
+ }
594
+ if (Object.prototype.toString.call(rateLimit) !== '[object Object]' && !Array.isArray(rateLimit)) {
595
+ throw `rateLimit must be an array or object`;
596
+ }
597
+ const options = Array.isArray(rateLimit) ? rateLimit : [rateLimit];
598
+ for (const option of options) {
599
+ if (Object.prototype.toString.call(option) !== '[object Object]') {
600
+ throw `rateLimit must be an array of objects`;
601
+ }
602
+ if (option.requestPath == null) {
603
+ throw `rateLimit.requestPath must be defined`;
604
+ }
605
+ if (typeof option.requestPath !== 'string') {
606
+ throw `rateLimit.requestPath must be a string`;
607
+ }
608
+ if (option.requestTimeWindow == null) {
609
+ throw `rateLimit.requestTimeWindow must be defined`;
610
+ }
611
+ if (typeof option.requestTimeWindow !== 'number') {
612
+ throw `rateLimit.requestTimeWindow must be a number`;
613
+ }
614
+ if (option.includeInternalRequests && typeof option.includeInternalRequests !== 'boolean') {
615
+ throw `rateLimit.includeInternalRequests must be a boolean`;
616
+ }
617
+ if (option.requestCount == null) {
618
+ throw `rateLimit.requestCount must be defined`;
619
+ }
620
+ if (typeof option.requestCount !== 'number') {
621
+ throw `rateLimit.requestCount must be a number`;
622
+ }
623
+ if (option.errorResponseMessage && typeof option.errorResponseMessage !== 'string') {
624
+ throw `rateLimit.errorResponseMessage must be a string`;
625
+ }
626
+ const options = Object.keys(_Parse.default.RateLimitZone);
627
+ if (option.zone && !options.includes(option.zone)) {
628
+ const formatter = new Intl.ListFormat('en', {
629
+ style: 'short',
630
+ type: 'disjunction'
631
+ });
632
+ throw `rateLimit.zone must be one of ${formatter.format(options)}`;
633
+ }
634
+ }
635
+ }
224
636
  generateEmailVerifyTokenExpiresAt() {
225
637
  if (!this.verifyUserEmails || !this.emailVerifyTokenValidityDuration) {
226
638
  return undefined;
@@ -228,7 +640,6 @@ class Config {
228
640
  var now = new Date();
229
641
  return new Date(now.getTime() + this.emailVerifyTokenValidityDuration * 1000);
230
642
  }
231
-
232
643
  generatePasswordResetTokenExpiresAt() {
233
644
  if (!this.passwordPolicy || !this.passwordPolicy.resetTokenValidityDuration) {
234
645
  return undefined;
@@ -236,7 +647,6 @@ class Config {
236
647
  const now = new Date();
237
648
  return new Date(now.getTime() + this.passwordPolicy.resetTokenValidityDuration * 1000);
238
649
  }
239
-
240
650
  generateSessionExpiresAt() {
241
651
  if (!this.expireInactiveSessions) {
242
652
  return undefined;
@@ -244,50 +654,71 @@ class Config {
244
654
  var now = new Date();
245
655
  return new Date(now.getTime() + this.sessionLength * 1000);
246
656
  }
247
-
657
+ unregisterRateLimiters() {
658
+ let i = this.rateLimits?.length;
659
+ while (i--) {
660
+ const limit = this.rateLimits[i];
661
+ if (limit.cloud) {
662
+ this.rateLimits.splice(i, 1);
663
+ }
664
+ }
665
+ }
248
666
  get invalidLinkURL() {
249
667
  return this.customPages.invalidLink || `${this.publicServerURL}/apps/invalid_link.html`;
250
668
  }
251
-
252
669
  get invalidVerificationLinkURL() {
253
670
  return this.customPages.invalidVerificationLink || `${this.publicServerURL}/apps/invalid_verification_link.html`;
254
671
  }
255
-
256
672
  get linkSendSuccessURL() {
257
673
  return this.customPages.linkSendSuccess || `${this.publicServerURL}/apps/link_send_success.html`;
258
674
  }
259
-
260
675
  get linkSendFailURL() {
261
676
  return this.customPages.linkSendFail || `${this.publicServerURL}/apps/link_send_fail.html`;
262
677
  }
263
-
264
678
  get verifyEmailSuccessURL() {
265
679
  return this.customPages.verifyEmailSuccess || `${this.publicServerURL}/apps/verify_email_success.html`;
266
680
  }
267
-
268
681
  get choosePasswordURL() {
269
682
  return this.customPages.choosePassword || `${this.publicServerURL}/apps/choose_password`;
270
683
  }
271
-
272
684
  get requestResetPasswordURL() {
273
- return `${this.publicServerURL}/apps/${this.applicationId}/request_password_reset`;
685
+ return `${this.publicServerURL}/${this.pagesEndpoint}/${this.applicationId}/request_password_reset`;
274
686
  }
275
-
276
687
  get passwordResetSuccessURL() {
277
688
  return this.customPages.passwordResetSuccess || `${this.publicServerURL}/apps/password_reset_success.html`;
278
689
  }
279
-
280
690
  get parseFrameURL() {
281
691
  return this.customPages.parseFrameURL;
282
692
  }
283
-
284
693
  get verifyEmailURL() {
285
- return `${this.publicServerURL}/apps/${this.applicationId}/verify_email`;
694
+ return `${this.publicServerURL}/${this.pagesEndpoint}/${this.applicationId}/verify_email`;
695
+ }
696
+ async loadMasterKey() {
697
+ if (typeof this.masterKey === 'function') {
698
+ const ttlIsEmpty = !this.masterKeyTtl;
699
+ const isExpired = this.masterKeyCache?.expiresAt && this.masterKeyCache.expiresAt < new Date();
700
+ if ((!isExpired || ttlIsEmpty) && this.masterKeyCache?.masterKey) {
701
+ return this.masterKeyCache.masterKey;
702
+ }
703
+ const masterKey = await this.masterKey();
704
+ const expiresAt = this.masterKeyTtl ? new Date(Date.now() + 1000 * this.masterKeyTtl) : null;
705
+ this.masterKeyCache = {
706
+ masterKey,
707
+ expiresAt
708
+ };
709
+ Config.put(this);
710
+ return this.masterKeyCache.masterKey;
711
+ }
712
+ return this.masterKey;
286
713
  }
287
- }
288
714
 
715
+ // TODO: Remove this function once PagesRouter replaces the PublicAPIRouter;
716
+ // the (default) endpoint has to be defined in PagesRouter only.
717
+ get pagesEndpoint() {
718
+ return this.pages && this.pages.enableRouter && this.pages.pagesEndpoint ? this.pages.pagesEndpoint : 'apps';
719
+ }
720
+ }
289
721
  exports.Config = Config;
290
- exports.default = Config;
291
-
722
+ var _default = exports.default = Config;
292
723
  module.exports = Config;
293
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9Db25maWcuanMiXSwibmFtZXMiOlsicmVtb3ZlVHJhaWxpbmdTbGFzaCIsInN0ciIsImVuZHNXaXRoIiwic3Vic3RyIiwibGVuZ3RoIiwiQ29uZmlnIiwiZ2V0IiwiYXBwbGljYXRpb25JZCIsIm1vdW50IiwiY2FjaGVJbmZvIiwiQXBwQ2FjaGUiLCJjb25maWciLCJPYmplY3QiLCJrZXlzIiwiZm9yRWFjaCIsImtleSIsInNjaGVtYUNhY2hlIiwiU2NoZW1hQ2FjaGUiLCJjYWNoZUNvbnRyb2xsZXIiLCJzY2hlbWFDYWNoZVRUTCIsImVuYWJsZVNpbmdsZVNjaGVtYUNhY2hlIiwiZGF0YWJhc2UiLCJEYXRhYmFzZUNvbnRyb2xsZXIiLCJkYXRhYmFzZUNvbnRyb2xsZXIiLCJhZGFwdGVyIiwiZ2VuZXJhdGVTZXNzaW9uRXhwaXJlc0F0IiwiYmluZCIsImdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbkV4cGlyZXNBdCIsInB1dCIsInNlcnZlckNvbmZpZ3VyYXRpb24iLCJ2YWxpZGF0ZSIsImFwcElkIiwic2V0dXBQYXNzd29yZFZhbGlkYXRvciIsInBhc3N3b3JkUG9saWN5IiwidmVyaWZ5VXNlckVtYWlscyIsInVzZXJDb250cm9sbGVyIiwiYXBwTmFtZSIsInB1YmxpY1NlcnZlclVSTCIsInJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQiLCJleHBpcmVJbmFjdGl2ZVNlc3Npb25zIiwic2Vzc2lvbkxlbmd0aCIsIm1heExpbWl0IiwiZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJhY2NvdW50TG9ja291dCIsIm1hc3RlcktleUlwcyIsIm1hc3RlcktleSIsInJlYWRPbmx5TWFzdGVyS2V5IiwiRXJyb3IiLCJlbWFpbEFkYXB0ZXIiLCJ2YWxpZGF0ZUVtYWlsQ29uZmlndXJhdGlvbiIsInZhbGlkYXRlQWNjb3VudExvY2tvdXRQb2xpY3kiLCJ2YWxpZGF0ZVBhc3N3b3JkUG9saWN5Iiwic3RhcnRzV2l0aCIsInZhbGlkYXRlU2Vzc2lvbkNvbmZpZ3VyYXRpb24iLCJ2YWxpZGF0ZU1hc3RlcktleUlwcyIsInZhbGlkYXRlTWF4TGltaXQiLCJkdXJhdGlvbiIsIk51bWJlciIsImlzSW50ZWdlciIsInRocmVzaG9sZCIsIm1heFBhc3N3b3JkQWdlIiwidW5kZWZpbmVkIiwicmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24iLCJ2YWxpZGF0b3JQYXR0ZXJuIiwiUmVnRXhwIiwidmFsaWRhdG9yQ2FsbGJhY2siLCJkb05vdEFsbG93VXNlcm5hbWUiLCJtYXhQYXNzd29yZEhpc3RvcnkiLCJwYXR0ZXJuVmFsaWRhdG9yIiwidmFsdWUiLCJ0ZXN0IiwiaXNOYU4iLCJpcCIsIm5ldCIsImlzSVAiLCJfbW91bnQiLCJuZXdWYWx1ZSIsIm5vdyIsIkRhdGUiLCJnZXRUaW1lIiwiZ2VuZXJhdGVQYXNzd29yZFJlc2V0VG9rZW5FeHBpcmVzQXQiLCJpbnZhbGlkTGlua1VSTCIsImN1c3RvbVBhZ2VzIiwiaW52YWxpZExpbmsiLCJpbnZhbGlkVmVyaWZpY2F0aW9uTGlua1VSTCIsImludmFsaWRWZXJpZmljYXRpb25MaW5rIiwibGlua1NlbmRTdWNjZXNzVVJMIiwibGlua1NlbmRTdWNjZXNzIiwibGlua1NlbmRGYWlsVVJMIiwibGlua1NlbmRGYWlsIiwidmVyaWZ5RW1haWxTdWNjZXNzVVJMIiwidmVyaWZ5RW1haWxTdWNjZXNzIiwiY2hvb3NlUGFzc3dvcmRVUkwiLCJjaG9vc2VQYXNzd29yZCIsInJlcXVlc3RSZXNldFBhc3N3b3JkVVJMIiwicGFzc3dvcmRSZXNldFN1Y2Nlc3NVUkwiLCJwYXNzd29yZFJlc2V0U3VjY2VzcyIsInBhcnNlRnJhbWVVUkwiLCJ2ZXJpZnlFbWFpbFVSTCIsIm1vZHVsZSIsImV4cG9ydHMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFJQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7O0FBUEE7QUFDQTtBQUNBOztBQU9BLFNBQVNBLG1CQUFULENBQTZCQyxHQUE3QixFQUFrQztBQUNoQyxNQUFJLENBQUNB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bUQsZUFBSixHQUFzQjtBQUNwQixXQUFPLEtBQUtOLFdBQUwsQ0FBaUJPLFlBQWpCLElBQWtDLEdBQUUsS0FBS3BELGVBQWdCLDJCQUFoRTtBQUNEOztBQUVELE1BQUlxRCxxQkFBSixHQUE0QjtBQUMxQixXQUFPLEtBQUtSLFdBQUwsQ0FBaUJTLGtCQUFqQixJQUF3QyxHQUFFLEtBQUt0RCxlQUFnQixpQ0FBdEU7QUFDRDs7QUFFRCxNQUFJdUQsaUJBQUosR0FBd0I7QUFDdEIsV0FBTyxLQUFLVixXQUFMLENBQWlCVyxjQUFqQixJQUFvQyxHQUFFLEtBQUt4RCxlQUFnQix1QkFBbEU7QUFDRDs7QUFFRCxNQUFJeUQsdUJBQUosR0FBOEI7QUFDNUIsV0FBUSxHQUFFLEtBQUt6RCxlQUFnQixTQUFRLEtBQUs5QixhQUFjLHlCQUExRDtBQUNEOztBQUVELE1BQUl3Rix1QkFBSixHQUE4QjtBQUM1QixXQUFPLEtBQUtiLFdBQUwsQ0FBaUJjLG9CQUFqQixJQUEwQyxHQUFFLEtBQUszRCxlQUFnQixtQ0FBeEU7QUFDRDs7QUFFRCxNQUFJNEQsYUFBSixHQUFvQjtBQUNsQixXQUFPLEtBQUtmLFdBQUwsQ0FBaUJlLGFBQXhCO0FBQ0Q7O0FBRUQsTUFBSUMsY0FBSixHQUFxQjtBQUNuQixXQUFRLEdBQUUsS0FBSzdELGVBQWdCLFNBQVEsS0FBSzlCLGFBQWMsZUFBMUQ7QUFDRDtBQTNQaUI7O1FBQVBGLE0sR0FBQUEsTTtrQkE4UEVBLE07O0FBQ2Y4RixPQUFPQyxPQUFQLEdBQWlCL0YsTUFBakIiLCJmaWxlIjoiQ29uZmlnLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQSBDb25maWcgb2JqZWN0IHByb3ZpZGVzIGluZm9ybWF0aW9uIGFib3V0IGhvdyBhIHNwZWNpZmljIGFwcCBpc1xuLy8gY29uZmlndXJlZC5cbi8vIG1vdW50IGlzIHRoZSBVUkwgZm9yIHRoZSByb290IG9mIHRoZSBBUEk7IGluY2x1ZGVzIGh0dHAsIGRvbWFpbiwgZXRjLlxuXG5pbXBvcnQgQXBwQ2FjaGUgZnJvbSAnLi9jYWNoZSc7XG5pbXBvcnQgU2NoZW1hQ2FjaGUgZnJvbSAnLi9Db250cm9sbGVycy9TY2hlbWFDYWNoZSc7XG5pbXBvcnQgRGF0YWJhc2VDb250cm9sbGVyIGZyb20gJy4vQ29udHJvbGxlcnMvRGF0YWJhc2VDb250cm9sbGVyJztcbmltcG9ydCBuZXQgZnJvbSAnbmV0JztcblxuZnVuY3Rpb24gcmVtb3ZlVHJhaWxpbmdTbGFzaChzdHIpIHtcbiAgaWYgKCFzdHIpIHtcbiAgICByZXR1cm4gc3RyO1xuICB9XG4gIGlmIChzdHIuZW5kc1dpdGgoXCIvXCIpKSB7XG4gICAgc3RyID0gc3RyLnN1YnN0cigwLCBzdHIubGVuZ3RoIC0gMSk7XG4gIH1cbiAgcmV0dXJuIHN0cjtcbn1cblxuZXhwb3J0IGNsYXNzIENvbmZpZyB7XG4gIHN0YXRpYyBnZXQoYXBwbGljYXRpb25JZDogc3RyaW5nLCBtb3VudDogc3RyaW5nKSB7XG4gICAgY29uc3QgY2FjaGVJbmZvID0gQXBwQ2FjaGUuZ2V0KGFwcGxpY2F0aW9uSWQpO1xuICAgIGlmICghY2FjaGVJbmZvKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBDb25maWcoKTtcbiAgICBjb25maWcuYXBwbGljYXRpb25JZCA9IGFwcGxpY2F0aW9uSWQ7XG4gICAgT2JqZWN0LmtleXMoY2FjaGVJbmZvKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgIGlmIChrZXkgPT0gJ2RhdGFiYXNlQ29udHJvbGxlcicpIHtcbiAgICAgICAgY29uc3Qgc2NoZW1hQ2FjaGUgPSBuZXcgU2NoZW1hQ2FjaGUoY2FjaGVJbmZvLmNhY2hlQ29udHJvbGxlcixcbiAgICAgICAgICBjYWNoZUluZm8uc2NoZW1hQ2FjaGVUVEwsXG4gICAgICAgICAgY2FjaGVJbmZvLmVuYWJsZVNpbmdsZVNjaGVtYUNhY2hlKTtcbiAgICAgICAgY29uZmlnLmRhdGFiYXNlID0gbmV3IERhdGFiYXNlQ29udHJvbGxlcihjYWNoZUluZm8uZGF0YWJhc2VDb250cm9sbGVyLmFkYXB0ZXIsIHNjaGVtYUNhY2hlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbmZpZ1trZXldID0gY2FjaGVJbmZvW2tleV07XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uZmlnLm1vdW50ID0gcmVtb3ZlVHJhaWxpbmdTbGFzaChtb3VudCk7XG4gICAgY29uZmlnLmdlbmVyYXRlU2Vzc2lvbkV4cGlyZXNBdCA9IGNvbmZpZy5nZW5lcmF0ZVNlc3Npb25FeHBpcmVzQXQuYmluZChjb25maWcpO1xuICAgIGNvbmZpZy5nZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW5FeHBpcmVzQXQgPSBjb25maWcuZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuRXhwaXJlc0F0LmJpbmQoY29uZmlnKTtcbiAgICByZXR1cm4gY29uZmlnO1xuICB9XG5cbiAgc3RhdGljIHB1dChzZXJ2ZXJDb25maWd1cmF0aW9uKSB7XG4gICAgQ29uZmlnLnZhbGlkYXRlKHNlcnZlckNvbmZpZ3VyYXRpb24pO1xuICAgIEFwcENhY2hlLnB1dChzZXJ2ZXJDb25maWd1cmF0aW9uLmFwcElkLCBzZXJ2ZXJDb25maWd1cmF0aW9uKTtcbiAgICBDb25maWcuc2V0dXBQYXNzd29yZFZhbGlkYXRvcihzZXJ2ZXJDb25maWd1cmF0aW9uLnBhc3N3b3JkUG9saWN5KTtcbiAgICByZXR1cm4gc2VydmVyQ29uZmlndXJhdGlvbjtcbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZSh7XG4gICAgdmVyaWZ5VXNlckVtYWlscyxcbiAgICB1c2VyQ29udHJvbGxlcixcbiAgICBhcHBOYW1lLFxuICAgIHB1YmxpY1NlcnZlclVSTCxcbiAgICByZXZva2VTZXNzaW9uT25QYXNzd29yZFJlc2V0LFxuICAgIGV4cGlyZUluYWN0aXZlU2Vzc2lvbnMsXG4gICAgc2Vzc2lvbkxlbmd0aCxcbiAgICBtYXhMaW1pdCxcbiAgICBlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbixcbiAgICBhY2NvdW50TG9ja291dCxcbiAgICBwYXNzd29yZFBvbGljeSxcbiAgICBtYXN0ZXJLZXlJcHMsXG4gICAgbWFzdGVyS2V5LFxuICAgIHJlYWRPbmx5TWFzdGVyS2V5LFxuICB9KSB7XG5cbiAgICBpZiAobWFzdGVyS2V5ID09PSByZWFkT25seU1hc3RlcktleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtYXN0ZXJLZXkgYW5kIHJlYWRPbmx5TWFzdGVyS2V5IHNob3VsZCBiZSBkaWZmZXJlbnQnKTtcbiAgICB9XG5cbiAgICBjb25zdCBlbWFpbEFkYXB0ZXIgPSB1c2VyQ29udHJvbGxlci5hZGFwdGVyO1xuICAgIGlmICh2ZXJpZnlVc2VyRW1haWxzKSB7XG4gICAgICB0aGlzLnZhbGlkYXRlRW1haWxDb25maWd1cmF0aW9uKHtlbWFpbEFkYXB0ZXIsIGFwcE5hbWUsIHB1YmxpY1NlcnZlclVSTCwgZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb259KTtcbiAgICB9XG5cbiAgICB0aGlzLnZhbGlkYXRlQWNjb3VudExvY2tvdXRQb2xpY3koYWNjb3VudExvY2tvdXQpO1xuXG4gICAgdGhpcy52YWxpZGF0ZVBhc3N3b3JkUG9saWN5KHBhc3N3b3JkUG9saWN5KTtcblxuICAgIGlmICh0eXBlb2YgcmV2b2tlU2Vzc2lvbk9uUGFzc3dvcmRSZXNldCAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB0aHJvdyAncmV2b2tlU2Vzc2lvbk9uUGFzc3dvcmRSZXNldCBtdXN0IGJlIGEgYm9vbGVhbiB2YWx1ZSc7XG4gICAgfVxuXG4gICAgaWYgKHB1YmxpY1NlcnZlclVSTCkge1xuICAgICAgaWYgKCFwdWJsaWNTZXJ2ZXJVUkwuc3RhcnRzV2l0aChcImh0dHA6Ly9cIikgJiYgIXB1YmxpY1NlcnZlclVSTC5zdGFydHNXaXRoKFwiaHR0cHM6Ly9cIikpIHtcbiAgICAgICAgdGhyb3cgXCJwdWJsaWNTZXJ2ZXJVUkwgc2hvdWxkIGJlIGEgdmFsaWQgSFRUUFMgVVJMIHN0YXJ0aW5nIHdpdGggaHR0cHM6Ly9cIlxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMudmFsaWRhdGVTZXNzaW9uQ29uZmlndXJhdGlvbihzZXNzaW9uTGVuZ3RoLCBleHBpcmVJbmFjdGl2ZVNlc3Npb25zKTtcblxuICAgIHRoaXMudmFsaWRhdGVNYXN0ZXJLZXlJcHMobWFzdGVyS2V5SXBzKTtcblxuICAgIHRoaXMudmFsaWRhdGVNYXhMaW1pdChtYXhMaW1pdCk7XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVBY2NvdW50TG9ja291dFBvbGljeShhY2NvdW50TG9ja291dCkge1xuICAgIGlmIChhY2NvdW50TG9ja291dCkge1xuICAgICAgaWYgKHR5cGVvZiBhY2NvdW50TG9ja291dC5kdXJhdGlvbiAhPT0gJ251bWJlcicgfHwgYWNjb3VudExvY2tvdXQuZHVyYXRpb24gPD0gMCB8fCBhY2NvdW50TG9ja291dC5kdXJhdGlvbiA+IDk5OTk5KSB7XG4gICAgICAgIHRocm93ICdBY2NvdW50IGxvY2tvdXQgZHVyYXRpb24gc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiAwIGFuZCBsZXNzIHRoYW4gMTAwMDAwJztcbiAgICAgIH1cblxuICAgICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKGFjY291bnRMb2Nrb3V0LnRocmVzaG9sZCkgfHwgYWNjb3VudExvY2tvdXQudGhyZXNob2xkIDwgMSB8fCBhY2NvdW50TG9ja291dC50aHJlc2hvbGQgPiA5OTkpIHtcbiAgICAgICAgdGhyb3cgJ0FjY291bnQgbG9ja291dCB0aHJlc2hvbGQgc2hvdWxkIGJlIGFuIGludGVnZXIgZ3JlYXRlciB0aGFuIDAgYW5kIGxlc3MgdGhhbiAxMDAwJztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVQYXNzd29yZFBvbGljeShwYXNzd29yZFBvbGljeSkge1xuICAgIGlmIChwYXNzd29yZFBvbGljeSkge1xuICAgICAgaWYgKHBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkQWdlICE9PSB1bmRlZmluZWQgJiYgKHR5cGVvZiBwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEFnZSAhPT0gJ251bWJlcicgfHwgcGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRBZ2UgPCAwKSkge1xuICAgICAgICB0aHJvdyAncGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRBZ2UgbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcic7XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbiAhPT0gdW5kZWZpbmVkICYmICh0eXBlb2YgcGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24gIT09ICdudW1iZXInIHx8IHBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uIDw9IDApKSB7XG4gICAgICAgIHRocm93ICdwYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbiBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJztcbiAgICAgIH1cblxuICAgICAgaWYocGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yUGF0dGVybil7XG4gICAgICAgIGlmKHR5cGVvZihwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuKSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuID0gbmV3IFJlZ0V4cChwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmKCEocGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yUGF0dGVybiBpbnN0YW5jZW9mIFJlZ0V4cCkpe1xuICAgICAgICAgIHRocm93ICdwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuIG11c3QgYmUgYSByZWdleCBzdHJpbmcgb3IgUmVnRXhwIG9iamVjdC4nO1xuICAgICAgICB9XG4gICAgICB9XG5cblxuICAgICAgaWYocGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yQ2FsbGJhY2sgJiYgdHlwZW9mIHBhc3N3b3JkUG9saWN5LnZhbGlkYXRvckNhbGxiYWNrICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRocm93ICdwYXNzd29yZFBvbGljeS52YWxpZGF0b3JDYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24uJztcbiAgICAgIH1cblxuICAgICAgaWYocGFzc3dvcmRQb2xpY3kuZG9Ob3RBbGxvd1VzZXJuYW1lICYmIHR5cGVvZiBwYXNzd29yZFBvbGljeS5kb05vdEFsbG93VXNlcm5hbWUgIT09ICdib29sZWFuJykge1xuICAgICAgICB0aHJvdyAncGFzc3dvcmRQb2xpY3kuZG9Ob3RBbGxvd1VzZXJuYW1lIG11c3QgYmUgYSBib29sZWFuIHZhbHVlLic7XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEhpc3RvcnkgJiYgKCFOdW1iZXIuaXNJbnRlZ2VyKHBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeSkgfHwgcGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRIaXN0b3J5IDw9IDAgfHwgcGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRIaXN0b3J5ID4gMjApKSB7XG4gICAgICAgIHRocm93ICdwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEhpc3RvcnkgbXVzdCBiZSBhbiBpbnRlZ2VyIHJhbmdpbmcgMCAtIDIwJztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBpZiB0aGUgcGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yUGF0dGVybiBpcyBjb25maWd1cmVkIHRoZW4gc2V0dXAgYSBjYWxsYmFjayB0byBwcm9jZXNzIHRoZSBwYXR0ZXJuXG4gIHN0YXRpYyBzZXR1cFBhc3N3b3JkVmFsaWRhdG9yKHBhc3N3b3JkUG9saWN5KSB7XG4gICAgaWYgKHBhc3N3b3JkUG9saWN5ICYmIHBhc3N3b3JkUG9saWN5LnZhbGlkYXRvclBhdHRlcm4pIHtcbiAgICAgIHBhc3N3b3JkUG9saWN5LnBhdHRlcm5WYWxpZGF0b3IgPSAodmFsdWUpID0+IHtcbiAgICAgICAgcmV0dXJuIHBhc3N3b3JkUG9saWN5LnZhbGlkYXRvclBhdHRlcm4udGVzdCh2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlRW1haWxDb25maWd1cmF0aW9uKHtlbWFpbEFkYXB0ZXIsIGFwcE5hbWUsIHB1YmxpY1NlcnZlclVSTCwgZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb259KSB7XG4gICAgaWYgKCFlbWFpbEFkYXB0ZXIpIHtcbiAgICAgIHRocm93ICdBbiBlbWFpbEFkYXB0ZXIgaXMgcmVxdWlyZWQgZm9yIGUtbWFpbCB2ZXJpZmljYXRpb24gYW5kIHBhc3N3b3JkIHJlc2V0cy4nO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGFwcE5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyAnQW4gYXBwIG5hbWUgaXMgcmVxdWlyZWQgZm9yIGUtbWFpbCB2ZXJpZmljYXRpb24gYW5kIHBhc3N3b3JkIHJlc2V0cy4nO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHB1YmxpY1NlcnZlclVSTCAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93ICdBIHB1YmxpYyBzZXJ2ZXIgdXJsIGlzIHJlcXVpcmVkIGZvciBlLW1haWwgdmVyaWZpY2F0aW9uIGFuZCBwYXNzd29yZCByZXNldHMuJztcbiAgICB9XG4gICAgaWYgKGVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSB7XG4gICAgICBpZiAoaXNOYU4oZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24pKSB7XG4gICAgICAgIHRocm93ICdFbWFpbCB2ZXJpZnkgdG9rZW4gdmFsaWRpdHkgZHVyYXRpb24gbXVzdCBiZSBhIHZhbGlkIG51bWJlci4nO1xuICAgICAgfSBlbHNlIGlmIChlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbiA8PSAwKSB7XG4gICAgICAgIHRocm93ICdFbWFpbCB2ZXJpZnkgdG9rZW4gdmFsaWRpdHkgZHVyYXRpb24gbXVzdCBiZSBhIHZhbHVlIGdyZWF0ZXIgdGhhbiAwLidcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVNYXN0ZXJLZXlJcHMobWFzdGVyS2V5SXBzKSB7XG4gICAgZm9yIChjb25zdCBpcCBvZiBtYXN0ZXJLZXlJcHMpIHtcbiAgICAgIGlmKCFuZXQuaXNJUChpcCkpe1xuICAgICAgICB0aHJvdyBgSW52YWxpZCBpcCBpbiBtYXN0ZXJLZXlJcHM6ICR7aXB9YDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBnZXQgbW91bnQoKSB7XG4gICAgdmFyIG1vdW50ID0gdGhpcy5fbW91bnQ7XG4gICAgaWYgKHRoaXMucHVibGljU2VydmVyVVJMKSB7XG4gICAgICBtb3VudCA9IHRoaXMucHVibGljU2VydmVyVVJMO1xuICAgIH1cbiAgICByZXR1cm4gbW91bnQ7XG4gIH1cblxuICBzZXQgbW91bnQobmV3VmFsdWUpIHtcbiAgICB0aGlzLl9tb3VudCA9IG5ld1ZhbHVlO1xuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlU2Vzc2lvbkNvbmZpZ3VyYXRpb24oc2Vzc2lvbkxlbmd0aCwgZXhwaXJlSW5hY3RpdmVTZXNzaW9ucykge1xuICAgIGlmIChleHBpcmVJbmFjdGl2ZVNlc3Npb25zKSB7XG4gICAgICBpZiAoaXNOYU4oc2Vzc2lvbkxlbmd0aCkpIHtcbiAgICAgICAgdGhyb3cgJ1Nlc3Npb24gbGVuZ3RoIG11c3QgYmUgYSB2YWxpZCBudW1iZXIuJztcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKHNlc3Npb25MZW5ndGggPD0gMCkge1xuICAgICAgICB0aHJvdyAnU2Vzc2lvbiBsZW5ndGggbXVzdCBiZSBhIHZhbHVlIGdyZWF0ZXIgdGhhbiAwLidcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVNYXhMaW1pdChtYXhMaW1pdCkge1xuICAgIGlmIChtYXhMaW1pdCA8PSAwKSB7XG4gICAgICB0aHJvdyAnTWF4IGxpbWl0IG11c3QgYmUgYSB2YWx1ZSBncmVhdGVyIHRoYW4gMC4nXG4gICAgfVxuICB9XG5cbiAgZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuRXhwaXJlc0F0KCkge1xuICAgIGlmICghdGhpcy52ZXJpZnlVc2VyRW1haWxzIHx8ICF0aGlzLmVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICB2YXIgbm93ID0gbmV3IERhdGUoKTtcbiAgICByZXR1cm4gbmV3IERhdGUobm93LmdldFRpbWUoKSArICh0aGlzLmVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uICogMTAwMCkpO1xuICB9XG5cbiAgZ2VuZXJhdGVQYXNzd29yZFJlc2V0VG9rZW5FeHBpcmVzQXQoKSB7XG4gICAgaWYgKCF0aGlzLnBhc3N3b3JkUG9saWN5IHx8ICF0aGlzLnBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuICAgIHJldHVybiBuZXcgRGF0ZShub3cuZ2V0VGltZSgpICsgKHRoaXMucGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24gKiAxMDAwKSk7XG4gIH1cblxuICBnZW5lcmF0ZVNlc3Npb25FeHBpcmVzQXQoKSB7XG4gICAgaWYgKCF0aGlzLmV4cGlyZUluYWN0aXZlU2Vzc2lvbnMpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHZhciBub3cgPSBuZXcgRGF0ZSgpO1xuICAgIHJldHVybiBuZXcgRGF0ZShub3cuZ2V0VGltZSgpICsgKHRoaXMuc2Vzc2lvbkxlbmd0aCAqIDEwMDApKTtcbiAgfVxuXG4gIGdldCBpbnZhbGlkTGlua1VSTCgpIHtcbiAgICByZXR1cm4gdGhpcy5jdXN0b21QYWdlcy5pbnZhbGlkTGluayB8fCBgJHt0aGlzLnB1YmxpY1NlcnZlclVSTH0vYXBwcy9pbnZhbGlkX2xpbmsuaHRtbGA7XG4gIH1cblxuICBnZXQgaW52YWxpZFZlcmlmaWNhdGlvbkxpbmtVUkwoKSB7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tUGFnZXMuaW52YWxpZFZlcmlmaWNhdGlvbkxpbmsgfHwgYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9L2FwcHMvaW52YWxpZF92ZXJpZmljYXRpb25fbGluay5odG1sYDtcbiAgfVxuXG4gIGdldCBsaW5rU2VuZFN1Y2Nlc3NVUkwoKSB7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tUGFnZXMubGlua1NlbmRTdWNjZXNzIHx8IGAke3RoaXMucHVibGljU2VydmVyVVJMfS9hcHBzL2xpbmtfc2VuZF9zdWNjZXNzLmh0bWxgXG4gIH1cblxuICBnZXQgbGlua1NlbmRGYWlsVVJMKCkge1xuICAgIHJldHVybiB0aGlzLmN1c3RvbVBhZ2VzLmxpbmtTZW5kRmFpbCB8fCBgJHt0aGlzLnB1YmxpY1NlcnZlclVSTH0vYXBwcy9saW5rX3NlbmRfZmFpbC5odG1sYFxuICB9XG5cbiAgZ2V0IHZlcmlmeUVtYWlsU3VjY2Vzc1VSTCgpIHtcbiAgICByZXR1cm4gdGhpcy5jdXN0b21QYWdlcy52ZXJpZnlFbWFpbFN1Y2Nlc3MgfHwgYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9L2FwcHMvdmVyaWZ5X2VtYWlsX3N1Y2Nlc3MuaHRtbGA7XG4gIH1cblxuICBnZXQgY2hvb3NlUGFzc3dvcmRVUkwoKSB7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tUGFnZXMuY2hvb3NlUGFzc3dvcmQgfHwgYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9L2FwcHMvY2hvb3NlX3Bhc3N3b3JkYDtcbiAgfVxuXG4gIGdldCByZXF1ZXN0UmVzZXRQYXNzd29yZFVSTCgpIHtcbiAgICByZXR1cm4gYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9L2FwcHMvJHt0aGlzLmFwcGxpY2F0aW9uSWR9L3JlcXVlc3RfcGFzc3dvcmRfcmVzZXRgO1xuICB9XG5cbiAgZ2V0IHBhc3N3b3JkUmVzZXRTdWNjZXNzVVJMKCkge1xuICAgIHJldHVybiB0aGlzLmN1c3RvbVBhZ2VzLnBhc3N3b3JkUmVzZXRTdWNjZXNzIHx8IGAke3RoaXMucHVibGljU2VydmVyVVJMfS9hcHBzL3Bhc3N3b3JkX3Jlc2V0X3N1Y2Nlc3MuaHRtbGA7XG4gIH1cblxuICBnZXQgcGFyc2VGcmFtZVVSTCgpIHtcbiAgICByZXR1cm4gdGhpcy5jdXN0b21QYWdlcy5wYXJzZUZyYW1lVVJMO1xuICB9XG5cbiAgZ2V0IHZlcmlmeUVtYWlsVVJMKCkge1xuICAgIHJldHVybiBgJHt0aGlzLnB1YmxpY1NlcnZlclVSTH0vYXBwcy8ke3RoaXMuYXBwbGljYXRpb25JZH0vdmVyaWZ5X2VtYWlsYDtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDb25maWc7XG5tb2R1bGUuZXhwb3J0cyA9IENvbmZpZztcbiJdfQ==
724
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbG9kYXNoIiwicmVxdWlyZSIsIl9uZXQiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX2NhY2hlIiwiX0RhdGFiYXNlQ29udHJvbGxlciIsIl9Mb2dnZXJDb250cm9sbGVyIiwiX3BhY2thZ2UiLCJfRGVmaW5pdGlvbnMiLCJfUGFyc2UiLCJfRGVwcmVjYXRvciIsImUiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsInJlbW92ZVRyYWlsaW5nU2xhc2giLCJzdHIiLCJlbmRzV2l0aCIsInN1YnN0cmluZyIsImxlbmd0aCIsImFzeW5jS2V5cyIsIkNvbmZpZyIsImdldCIsImFwcGxpY2F0aW9uSWQiLCJtb3VudCIsImNhY2hlSW5mbyIsIkFwcENhY2hlIiwiY29uZmlnIiwiT2JqZWN0Iiwia2V5cyIsImZvckVhY2giLCJrZXkiLCJkYXRhYmFzZSIsIkRhdGFiYXNlQ29udHJvbGxlciIsImRhdGFiYXNlQ29udHJvbGxlciIsImFkYXB0ZXIiLCJnZW5lcmF0ZVNlc3Npb25FeHBpcmVzQXQiLCJiaW5kIiwiZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuRXhwaXJlc0F0IiwidmVyc2lvbiIsImxvYWRLZXlzIiwiUHJvbWlzZSIsImFsbCIsIm1hcCIsImVycm9yIiwiRXJyb3IiLCJtZXNzYWdlIiwiY2FjaGVkQ29uZmlnIiwiYXBwSWQiLCJ1cGRhdGVkQ29uZmlnIiwicHV0IiwidHJhbnNmb3JtQ29uZmlndXJhdGlvbiIsInNlcnZlckNvbmZpZ3VyYXRpb24iLCJpbmNsdWRlcyIsInZhbGlkYXRlT3B0aW9ucyIsInZhbGlkYXRlQ29udHJvbGxlcnMiLCJzZXR1cFBhc3N3b3JkVmFsaWRhdG9yIiwicGFzc3dvcmRQb2xpY3kiLCJjdXN0b21QYWdlcyIsInB1YmxpY1NlcnZlclVSTCIsInJldm9rZVNlc3Npb25PblBhc3N3b3JkUmVzZXQiLCJleHBpcmVJbmFjdGl2ZVNlc3Npb25zIiwic2Vzc2lvbkxlbmd0aCIsImRlZmF1bHRMaW1pdCIsIm1heExpbWl0IiwiYWNjb3VudExvY2tvdXQiLCJtYXN0ZXJLZXlJcHMiLCJtYXN0ZXJLZXkiLCJtYWludGVuYW5jZUtleSIsIm1haW50ZW5hbmNlS2V5SXBzIiwicmVhZE9ubHlNYXN0ZXJLZXkiLCJhbGxvd0hlYWRlcnMiLCJpZGVtcG90ZW5jeU9wdGlvbnMiLCJmaWxlVXBsb2FkIiwicGFnZXMiLCJzZWN1cml0eSIsImVuZm9yY2VQcml2YXRlVXNlcnMiLCJlbmFibGVJbnNlY3VyZUF1dGhBZGFwdGVycyIsInNjaGVtYSIsInJlcXVlc3RLZXl3b3JkRGVueWxpc3QiLCJhbGxvd0V4cGlyZWRBdXRoRGF0YVRva2VuIiwibG9nTGV2ZWxzIiwicmF0ZUxpbWl0IiwiZGF0YWJhc2VPcHRpb25zIiwiZXh0ZW5kU2Vzc2lvbk9uVXNlIiwiYWxsb3dDbGllbnRDbGFzc0NyZWF0aW9uIiwidmFsaWRhdGVBY2NvdW50TG9ja291dFBvbGljeSIsInZhbGlkYXRlUGFzc3dvcmRQb2xpY3kiLCJ2YWxpZGF0ZUZpbGVVcGxvYWRPcHRpb25zIiwidmFsaWRhdGVQdWJsaWNTZXJ2ZXJVUkwiLCJ2YWxpZGF0ZVNlc3Npb25Db25maWd1cmF0aW9uIiwidmFsaWRhdGVJcHMiLCJ2YWxpZGF0ZURlZmF1bHRMaW1pdCIsInZhbGlkYXRlTWF4TGltaXQiLCJ2YWxpZGF0ZUFsbG93SGVhZGVycyIsInZhbGlkYXRlSWRlbXBvdGVuY3lPcHRpb25zIiwidmFsaWRhdGVQYWdlc09wdGlvbnMiLCJ2YWxpZGF0ZVNlY3VyaXR5T3B0aW9ucyIsInZhbGlkYXRlU2NoZW1hT3B0aW9ucyIsInZhbGlkYXRlRW5mb3JjZVByaXZhdGVVc2VycyIsInZhbGlkYXRlRW5hYmxlSW5zZWN1cmVBdXRoQWRhcHRlcnMiLCJ2YWxpZGF0ZUFsbG93RXhwaXJlZEF1dGhEYXRhVG9rZW4iLCJ2YWxpZGF0ZVJlcXVlc3RLZXl3b3JkRGVueWxpc3QiLCJ2YWxpZGF0ZVJhdGVMaW1pdCIsInZhbGlkYXRlTG9nTGV2ZWxzIiwidmFsaWRhdGVEYXRhYmFzZU9wdGlvbnMiLCJ2YWxpZGF0ZUN1c3RvbVBhZ2VzIiwidmFsaWRhdGVBbGxvd0NsaWVudENsYXNzQ3JlYXRpb24iLCJwcm90b3R5cGUiLCJ0b1N0cmluZyIsImNhbGwiLCJ2ZXJpZnlVc2VyRW1haWxzIiwidXNlckNvbnRyb2xsZXIiLCJhcHBOYW1lIiwiX3B1YmxpY1NlcnZlclVSTCIsImVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uIiwiZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZCIsImVtYWlsQWRhcHRlciIsInZhbGlkYXRlRW1haWxDb25maWd1cmF0aW9uIiwidW5kZWZpbmVkIiwiQXJyYXkiLCJpc0FycmF5IiwiZW5hYmxlQ2hlY2siLCJTZWN1cml0eU9wdGlvbnMiLCJpc0Jvb2xlYW4iLCJlbmFibGVDaGVja0xvZyIsImRlZmluaXRpb25zIiwiU2NoZW1hT3B0aW9ucyIsInN0cmljdCIsImRlbGV0ZUV4dHJhRmllbGRzIiwicmVjcmVhdGVNb2RpZmllZEZpZWxkcyIsImxvY2tTY2hlbWFzIiwiYmVmb3JlTWlncmF0aW9uIiwiYWZ0ZXJNaWdyYXRpb24iLCJlbmFibGVSb3V0ZXIiLCJQYWdlc09wdGlvbnMiLCJlbmFibGVMb2NhbGl6YXRpb24iLCJsb2NhbGl6YXRpb25Kc29uUGF0aCIsImlzU3RyaW5nIiwibG9jYWxpemF0aW9uRmFsbGJhY2tMb2NhbGUiLCJwbGFjZWhvbGRlcnMiLCJmb3JjZVJlZGlyZWN0IiwicGFnZXNQYXRoIiwicGFnZXNFbmRwb2ludCIsImN1c3RvbVVybHMiLCJjdXN0b21Sb3V0ZXMiLCJ0dGwiLCJJZGVtcG90ZW5jeU9wdGlvbnMiLCJpc05hTiIsInBhdGhzIiwiZHVyYXRpb24iLCJOdW1iZXIiLCJpc0ludGVnZXIiLCJ0aHJlc2hvbGQiLCJ1bmxvY2tPblBhc3N3b3JkUmVzZXQiLCJBY2NvdW50TG9ja291dE9wdGlvbnMiLCJtYXhQYXNzd29yZEFnZSIsInJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uIiwidmFsaWRhdG9yUGF0dGVybiIsIlJlZ0V4cCIsInZhbGlkYXRvckNhbGxiYWNrIiwiZG9Ob3RBbGxvd1VzZXJuYW1lIiwibWF4UGFzc3dvcmRIaXN0b3J5IiwicmVzZXRUb2tlblJldXNlSWZWYWxpZCIsInJlc2V0UGFzc3dvcmRTdWNjZXNzT25JbnZhbGlkRW1haWwiLCJwYXR0ZXJuVmFsaWRhdG9yIiwidmFsdWUiLCJ0ZXN0IiwicmVxdWlyZWQiLCJ0eXBlIiwic3RhcnRzV2l0aCIsIlJlZmVyZW5jZUVycm9yIiwiZW5hYmxlRm9yQW5vbnltb3VzVXNlciIsIkZpbGVVcGxvYWRPcHRpb25zIiwiZW5hYmxlRm9yUHVibGljIiwiZW5hYmxlRm9yQXV0aGVudGljYXRlZFVzZXIiLCJmaWxlRXh0ZW5zaW9ucyIsImZpZWxkIiwiaXAiLCJzcGxpdCIsIm5ldCIsImlzSVAiLCJEZXByZWNhdG9yIiwibG9nUnVudGltZURlcHJlY2F0aW9uIiwidXNhZ2UiLCJfbW91bnQiLCJuZXdWYWx1ZSIsIlBhcnNlU2VydmVyT3B0aW9ucyIsImhlYWRlciIsInRyaW0iLCJMb2dMZXZlbHMiLCJ2YWxpZExvZ0xldmVscyIsImluZGV4T2YiLCJKU09OIiwic3RyaW5naWZ5IiwiZW5hYmxlU2NoZW1hSG9va3MiLCJEYXRhYmFzZU9wdGlvbnMiLCJzY2hlbWFDYWNoZVR0bCIsImFsbG93UHVibGljRXhwbGFpbiIsIm9wdGlvbnMiLCJvcHRpb24iLCJyZXF1ZXN0UGF0aCIsInJlcXVlc3RUaW1lV2luZG93IiwiaW5jbHVkZUludGVybmFsUmVxdWVzdHMiLCJyZXF1ZXN0Q291bnQiLCJlcnJvclJlc3BvbnNlTWVzc2FnZSIsIlBhcnNlU2VydmVyIiwiUmF0ZUxpbWl0Wm9uZSIsInpvbmUiLCJmb3JtYXR0ZXIiLCJJbnRsIiwiTGlzdEZvcm1hdCIsInN0eWxlIiwiZm9ybWF0Iiwibm93IiwiRGF0ZSIsImdldFRpbWUiLCJnZW5lcmF0ZVBhc3N3b3JkUmVzZXRUb2tlbkV4cGlyZXNBdCIsInVucmVnaXN0ZXJSYXRlTGltaXRlcnMiLCJpIiwicmF0ZUxpbWl0cyIsImxpbWl0IiwiY2xvdWQiLCJzcGxpY2UiLCJpbnZhbGlkTGlua1VSTCIsImludmFsaWRMaW5rIiwiaW52YWxpZFZlcmlmaWNhdGlvbkxpbmtVUkwiLCJpbnZhbGlkVmVyaWZpY2F0aW9uTGluayIsImxpbmtTZW5kU3VjY2Vzc1VSTCIsImxpbmtTZW5kU3VjY2VzcyIsImxpbmtTZW5kRmFpbFVSTCIsImxpbmtTZW5kRmFpbCIsInZlcmlmeUVtYWlsU3VjY2Vzc1VSTCIsInZlcmlmeUVtYWlsU3VjY2VzcyIsImNob29zZVBhc3N3b3JkVVJMIiwiY2hvb3NlUGFzc3dvcmQiLCJyZXF1ZXN0UmVzZXRQYXNzd29yZFVSTCIsInBhc3N3b3JkUmVzZXRTdWNjZXNzVVJMIiwicGFzc3dvcmRSZXNldFN1Y2Nlc3MiLCJwYXJzZUZyYW1lVVJMIiwidmVyaWZ5RW1haWxVUkwiLCJsb2FkTWFzdGVyS2V5IiwidHRsSXNFbXB0eSIsIm1hc3RlcktleVR0bCIsImlzRXhwaXJlZCIsIm1hc3RlcktleUNhY2hlIiwiZXhwaXJlc0F0IiwiZXhwb3J0cyIsIl9kZWZhdWx0IiwibW9kdWxlIl0sInNvdXJjZXMiOlsiLi4vc3JjL0NvbmZpZy5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBBIENvbmZpZyBvYmplY3QgcHJvdmlkZXMgaW5mb3JtYXRpb24gYWJvdXQgaG93IGEgc3BlY2lmaWMgYXBwIGlzXG4vLyBjb25maWd1cmVkLlxuLy8gbW91bnQgaXMgdGhlIFVSTCBmb3IgdGhlIHJvb3Qgb2YgdGhlIEFQSTsgaW5jbHVkZXMgaHR0cCwgZG9tYWluLCBldGMuXG5cbmltcG9ydCB7IGlzQm9vbGVhbiwgaXNTdHJpbmcgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IG5ldCBmcm9tICduZXQnO1xuaW1wb3J0IEFwcENhY2hlIGZyb20gJy4vY2FjaGUnO1xuaW1wb3J0IERhdGFiYXNlQ29udHJvbGxlciBmcm9tICcuL0NvbnRyb2xsZXJzL0RhdGFiYXNlQ29udHJvbGxlcic7XG5pbXBvcnQgeyBsb2dMZXZlbHMgYXMgdmFsaWRMb2dMZXZlbHMgfSBmcm9tICcuL0NvbnRyb2xsZXJzL0xvZ2dlckNvbnRyb2xsZXInO1xuaW1wb3J0IHsgdmVyc2lvbiB9IGZyb20gJy4uL3BhY2thZ2UuanNvbic7XG5pbXBvcnQge1xuICBBY2NvdW50TG9ja291dE9wdGlvbnMsXG4gIERhdGFiYXNlT3B0aW9ucyxcbiAgRmlsZVVwbG9hZE9wdGlvbnMsXG4gIElkZW1wb3RlbmN5T3B0aW9ucyxcbiAgTG9nTGV2ZWxzLFxuICBQYWdlc09wdGlvbnMsXG4gIFBhcnNlU2VydmVyT3B0aW9ucyxcbiAgU2NoZW1hT3B0aW9ucyxcbiAgU2VjdXJpdHlPcHRpb25zLFxufSBmcm9tICcuL09wdGlvbnMvRGVmaW5pdGlvbnMnO1xuaW1wb3J0IFBhcnNlU2VydmVyIGZyb20gJy4vY2xvdWQtY29kZS9QYXJzZS5TZXJ2ZXInO1xuaW1wb3J0IERlcHJlY2F0b3IgZnJvbSAnLi9EZXByZWNhdG9yL0RlcHJlY2F0b3InO1xuXG5mdW5jdGlvbiByZW1vdmVUcmFpbGluZ1NsYXNoKHN0cikge1xuICBpZiAoIXN0cikge1xuICAgIHJldHVybiBzdHI7XG4gIH1cbiAgaWYgKHN0ci5lbmRzV2l0aCgnLycpKSB7XG4gICAgc3RyID0gc3RyLnN1YnN0cmluZygwLCBzdHIubGVuZ3RoIC0gMSk7XG4gIH1cbiAgcmV0dXJuIHN0cjtcbn1cblxuLyoqXG4gKiBDb25maWcga2V5cyB0aGF0IG5lZWQgdG8gYmUgbG9hZGVkIGFzeW5jaHJvbm91c2x5LlxuICovXG5jb25zdCBhc3luY0tleXMgPSBbJ3B1YmxpY1NlcnZlclVSTCddO1xuXG5leHBvcnQgY2xhc3MgQ29uZmlnIHtcbiAgc3RhdGljIGdldChhcHBsaWNhdGlvbklkOiBzdHJpbmcsIG1vdW50OiBzdHJpbmcpIHtcbiAgICBjb25zdCBjYWNoZUluZm8gPSBBcHBDYWNoZS5nZXQoYXBwbGljYXRpb25JZCk7XG4gICAgaWYgKCFjYWNoZUluZm8pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY29uZmlnID0gbmV3IENvbmZpZygpO1xuICAgIGNvbmZpZy5hcHBsaWNhdGlvbklkID0gYXBwbGljYXRpb25JZDtcbiAgICBPYmplY3Qua2V5cyhjYWNoZUluZm8pLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGlmIChrZXkgPT0gJ2RhdGFiYXNlQ29udHJvbGxlcicpIHtcbiAgICAgICAgY29uZmlnLmRhdGFiYXNlID0gbmV3IERhdGFiYXNlQ29udHJvbGxlcihjYWNoZUluZm8uZGF0YWJhc2VDb250cm9sbGVyLmFkYXB0ZXIsIGNvbmZpZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25maWdba2V5XSA9IGNhY2hlSW5mb1trZXldO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGNvbmZpZy5tb3VudCA9IHJlbW92ZVRyYWlsaW5nU2xhc2gobW91bnQpO1xuICAgIGNvbmZpZy5nZW5lcmF0ZVNlc3Npb25FeHBpcmVzQXQgPSBjb25maWcuZ2VuZXJhdGVTZXNzaW9uRXhwaXJlc0F0LmJpbmQoY29uZmlnKTtcbiAgICBjb25maWcuZ2VuZXJhdGVFbWFpbFZlcmlmeVRva2VuRXhwaXJlc0F0ID0gY29uZmlnLmdlbmVyYXRlRW1haWxWZXJpZnlUb2tlbkV4cGlyZXNBdC5iaW5kKFxuICAgICAgY29uZmlnXG4gICAgKTtcbiAgICBjb25maWcudmVyc2lvbiA9IHZlcnNpb247XG4gICAgcmV0dXJuIGNvbmZpZztcbiAgfVxuXG4gIGFzeW5jIGxvYWRLZXlzKCkge1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgYXN5bmNLZXlzLm1hcChhc3luYyBrZXkgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXNbYF8ke2tleX1gXSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzW2tleV0gPSBhd2FpdCB0aGlzW2BfJHtrZXl9YF0oKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gcmVzb2x2ZSBhc3luYyBjb25maWcga2V5ICcke2tleX0nOiAke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG5cbiAgICBjb25zdCBjYWNoZWRDb25maWcgPSBBcHBDYWNoZS5nZXQodGhpcy5hcHBJZCk7XG4gICAgaWYgKGNhY2hlZENvbmZpZykge1xuICAgICAgY29uc3QgdXBkYXRlZENvbmZpZyA9IHsgLi4uY2FjaGVkQ29uZmlnIH07XG4gICAgICBhc3luY0tleXMuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICB1cGRhdGVkQ29uZmlnW2tleV0gPSB0aGlzW2tleV07XG4gICAgICB9KTtcbiAgICAgIEFwcENhY2hlLnB1dCh0aGlzLmFwcElkLCB1cGRhdGVkQ29uZmlnKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdHJhbnNmb3JtQ29uZmlndXJhdGlvbihzZXJ2ZXJDb25maWd1cmF0aW9uKSB7XG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoc2VydmVyQ29uZmlndXJhdGlvbikpIHtcbiAgICAgIGlmIChhc3luY0tleXMuaW5jbHVkZXMoa2V5KSAmJiB0eXBlb2Ygc2VydmVyQ29uZmlndXJhdGlvbltrZXldID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHNlcnZlckNvbmZpZ3VyYXRpb25bYF8ke2tleX1gXSA9IHNlcnZlckNvbmZpZ3VyYXRpb25ba2V5XTtcbiAgICAgICAgZGVsZXRlIHNlcnZlckNvbmZpZ3VyYXRpb25ba2V5XTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzdGF0aWMgcHV0KHNlcnZlckNvbmZpZ3VyYXRpb24pIHtcbiAgICBDb25maWcudmFsaWRhdGVPcHRpb25zKHNlcnZlckNvbmZpZ3VyYXRpb24pO1xuICAgIENvbmZpZy52YWxpZGF0ZUNvbnRyb2xsZXJzKHNlcnZlckNvbmZpZ3VyYXRpb24pO1xuICAgIENvbmZpZy50cmFuc2Zvcm1Db25maWd1cmF0aW9uKHNlcnZlckNvbmZpZ3VyYXRpb24pO1xuICAgIEFwcENhY2hlLnB1dChzZXJ2ZXJDb25maWd1cmF0aW9uLmFwcElkLCBzZXJ2ZXJDb25maWd1cmF0aW9uKTtcbiAgICBDb25maWcuc2V0dXBQYXNzd29yZFZhbGlkYXRvcihzZXJ2ZXJDb25maWd1cmF0aW9uLnBhc3N3b3JkUG9saWN5KTtcbiAgICByZXR1cm4gc2VydmVyQ29uZmlndXJhdGlvbjtcbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZU9wdGlvbnMoe1xuICAgIGN1c3RvbVBhZ2VzLFxuICAgIHB1YmxpY1NlcnZlclVSTCxcbiAgICByZXZva2VTZXNzaW9uT25QYXNzd29yZFJlc2V0LFxuICAgIGV4cGlyZUluYWN0aXZlU2Vzc2lvbnMsXG4gICAgc2Vzc2lvbkxlbmd0aCxcbiAgICBkZWZhdWx0TGltaXQsXG4gICAgbWF4TGltaXQsXG4gICAgYWNjb3VudExvY2tvdXQsXG4gICAgcGFzc3dvcmRQb2xpY3ksXG4gICAgbWFzdGVyS2V5SXBzLFxuICAgIG1hc3RlcktleSxcbiAgICBtYWludGVuYW5jZUtleSxcbiAgICBtYWludGVuYW5jZUtleUlwcyxcbiAgICByZWFkT25seU1hc3RlcktleSxcbiAgICBhbGxvd0hlYWRlcnMsXG4gICAgaWRlbXBvdGVuY3lPcHRpb25zLFxuICAgIGZpbGVVcGxvYWQsXG4gICAgcGFnZXMsXG4gICAgc2VjdXJpdHksXG4gICAgZW5mb3JjZVByaXZhdGVVc2VycyxcbiAgICBlbmFibGVJbnNlY3VyZUF1dGhBZGFwdGVycyxcbiAgICBzY2hlbWEsXG4gICAgcmVxdWVzdEtleXdvcmREZW55bGlzdCxcbiAgICBhbGxvd0V4cGlyZWRBdXRoRGF0YVRva2VuLFxuICAgIGxvZ0xldmVscyxcbiAgICByYXRlTGltaXQsXG4gICAgZGF0YWJhc2VPcHRpb25zLFxuICAgIGV4dGVuZFNlc3Npb25PblVzZSxcbiAgICBhbGxvd0NsaWVudENsYXNzQ3JlYXRpb24sXG4gIH0pIHtcbiAgICBpZiAobWFzdGVyS2V5ID09PSByZWFkT25seU1hc3RlcktleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtYXN0ZXJLZXkgYW5kIHJlYWRPbmx5TWFzdGVyS2V5IHNob3VsZCBiZSBkaWZmZXJlbnQnKTtcbiAgICB9XG5cbiAgICBpZiAobWFzdGVyS2V5ID09PSBtYWludGVuYW5jZUtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtYXN0ZXJLZXkgYW5kIG1haW50ZW5hbmNlS2V5IHNob3VsZCBiZSBkaWZmZXJlbnQnKTtcbiAgICB9XG5cbiAgICB0aGlzLnZhbGlkYXRlQWNjb3VudExvY2tvdXRQb2xpY3koYWNjb3VudExvY2tvdXQpO1xuICAgIHRoaXMudmFsaWRhdGVQYXNzd29yZFBvbGljeShwYXNzd29yZFBvbGljeSk7XG4gICAgdGhpcy52YWxpZGF0ZUZpbGVVcGxvYWRPcHRpb25zKGZpbGVVcGxvYWQpO1xuXG4gICAgaWYgKHR5cGVvZiByZXZva2VTZXNzaW9uT25QYXNzd29yZFJlc2V0ICE9PSAnYm9vbGVhbicpIHtcbiAgICAgIHRocm93ICdyZXZva2VTZXNzaW9uT25QYXNzd29yZFJlc2V0IG11c3QgYmUgYSBib29sZWFuIHZhbHVlJztcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGV4dGVuZFNlc3Npb25PblVzZSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB0aHJvdyAnZXh0ZW5kU2Vzc2lvbk9uVXNlIG11c3QgYmUgYSBib29sZWFuIHZhbHVlJztcbiAgICB9XG5cbiAgICB0aGlzLnZhbGlkYXRlUHVibGljU2VydmVyVVJMKHsgcHVibGljU2VydmVyVVJMIH0pO1xuICAgIHRoaXMudmFsaWRhdGVTZXNzaW9uQ29uZmlndXJhdGlvbihzZXNzaW9uTGVuZ3RoLCBleHBpcmVJbmFjdGl2ZVNlc3Npb25zKTtcbiAgICB0aGlzLnZhbGlkYXRlSXBzKCdtYXN0ZXJLZXlJcHMnLCBtYXN0ZXJLZXlJcHMpO1xuICAgIHRoaXMudmFsaWRhdGVJcHMoJ21haW50ZW5hbmNlS2V5SXBzJywgbWFpbnRlbmFuY2VLZXlJcHMpO1xuICAgIHRoaXMudmFsaWRhdGVEZWZhdWx0TGltaXQoZGVmYXVsdExpbWl0KTtcbiAgICB0aGlzLnZhbGlkYXRlTWF4TGltaXQobWF4TGltaXQpO1xuICAgIHRoaXMudmFsaWRhdGVBbGxvd0hlYWRlcnMoYWxsb3dIZWFkZXJzKTtcbiAgICB0aGlzLnZhbGlkYXRlSWRlbXBvdGVuY3lPcHRpb25zKGlkZW1wb3RlbmN5T3B0aW9ucyk7XG4gICAgdGhpcy52YWxpZGF0ZVBhZ2VzT3B0aW9ucyhwYWdlcyk7XG4gICAgdGhpcy52YWxpZGF0ZVNlY3VyaXR5T3B0aW9ucyhzZWN1cml0eSk7XG4gICAgdGhpcy52YWxpZGF0ZVNjaGVtYU9wdGlvbnMoc2NoZW1hKTtcbiAgICB0aGlzLnZhbGlkYXRlRW5mb3JjZVByaXZhdGVVc2VycyhlbmZvcmNlUHJpdmF0ZVVzZXJzKTtcbiAgICB0aGlzLnZhbGlkYXRlRW5hYmxlSW5zZWN1cmVBdXRoQWRhcHRlcnMoZW5hYmxlSW5zZWN1cmVBdXRoQWRhcHRlcnMpO1xuICAgIHRoaXMudmFsaWRhdGVBbGxvd0V4cGlyZWRBdXRoRGF0YVRva2VuKGFsbG93RXhwaXJlZEF1dGhEYXRhVG9rZW4pO1xuICAgIHRoaXMudmFsaWRhdGVSZXF1ZXN0S2V5d29yZERlbnlsaXN0KHJlcXVlc3RLZXl3b3JkRGVueWxpc3QpO1xuICAgIHRoaXMudmFsaWRhdGVSYXRlTGltaXQocmF0ZUxpbWl0KTtcbiAgICB0aGlzLnZhbGlkYXRlTG9nTGV2ZWxzKGxvZ0xldmVscyk7XG4gICAgdGhpcy52YWxpZGF0ZURhdGFiYXNlT3B0aW9ucyhkYXRhYmFzZU9wdGlvbnMpO1xuICAgIHRoaXMudmFsaWRhdGVDdXN0b21QYWdlcyhjdXN0b21QYWdlcyk7XG4gICAgdGhpcy52YWxpZGF0ZUFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbihhbGxvd0NsaWVudENsYXNzQ3JlYXRpb24pO1xuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlQ3VzdG9tUGFnZXMoY3VzdG9tUGFnZXMpIHtcbiAgICBpZiAoIWN1c3RvbVBhZ2VzKSB7IHJldHVybjsgfVxuXG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChjdXN0b21QYWdlcykgIT09ICdbb2JqZWN0IE9iamVjdF0nKSB7XG4gICAgICB0aHJvdyBFcnJvcignUGFyc2UgU2VydmVyIG9wdGlvbiBjdXN0b21QYWdlcyBtdXN0IGJlIGFuIG9iamVjdC4nKTtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVDb250cm9sbGVycyh7XG4gICAgdmVyaWZ5VXNlckVtYWlscyxcbiAgICB1c2VyQ29udHJvbGxlcixcbiAgICBhcHBOYW1lLFxuICAgIHB1YmxpY1NlcnZlclVSTCxcbiAgICBfcHVibGljU2VydmVyVVJMLFxuICAgIGVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uLFxuICAgIGVtYWlsVmVyaWZ5VG9rZW5SZXVzZUlmVmFsaWQsXG4gIH0pIHtcbiAgICBjb25zdCBlbWFpbEFkYXB0ZXIgPSB1c2VyQ29udHJvbGxlci5hZGFwdGVyO1xuICAgIGlmICh2ZXJpZnlVc2VyRW1haWxzKSB7XG4gICAgICB0aGlzLnZhbGlkYXRlRW1haWxDb25maWd1cmF0aW9uKHtcbiAgICAgICAgZW1haWxBZGFwdGVyLFxuICAgICAgICBhcHBOYW1lLFxuICAgICAgICBwdWJsaWNTZXJ2ZXJVUkw6IHB1YmxpY1NlcnZlclVSTCB8fCBfcHVibGljU2VydmVyVVJMLFxuICAgICAgICBlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbixcbiAgICAgICAgZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZVJlcXVlc3RLZXl3b3JkRGVueWxpc3QocmVxdWVzdEtleXdvcmREZW55bGlzdCkge1xuICAgIGlmIChyZXF1ZXN0S2V5d29yZERlbnlsaXN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJlcXVlc3RLZXl3b3JkRGVueWxpc3QgPSByZXF1ZXN0S2V5d29yZERlbnlsaXN0LmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICghQXJyYXkuaXNBcnJheShyZXF1ZXN0S2V5d29yZERlbnlsaXN0KSkge1xuICAgICAgdGhyb3cgJ1BhcnNlIFNlcnZlciBvcHRpb24gcmVxdWVzdEtleXdvcmREZW55bGlzdCBtdXN0IGJlIGFuIGFycmF5Lic7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlRW5mb3JjZVByaXZhdGVVc2VycyhlbmZvcmNlUHJpdmF0ZVVzZXJzKSB7XG4gICAgaWYgKHR5cGVvZiBlbmZvcmNlUHJpdmF0ZVVzZXJzICE9PSAnYm9vbGVhbicpIHtcbiAgICAgIHRocm93ICdQYXJzZSBTZXJ2ZXIgb3B0aW9uIGVuZm9yY2VQcml2YXRlVXNlcnMgbXVzdCBiZSBhIGJvb2xlYW4uJztcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVBbGxvd0V4cGlyZWRBdXRoRGF0YVRva2VuKGFsbG93RXhwaXJlZEF1dGhEYXRhVG9rZW4pIHtcbiAgICBpZiAodHlwZW9mIGFsbG93RXhwaXJlZEF1dGhEYXRhVG9rZW4gIT09ICdib29sZWFuJykge1xuICAgICAgdGhyb3cgJ1BhcnNlIFNlcnZlciBvcHRpb24gYWxsb3dFeHBpcmVkQXV0aERhdGFUb2tlbiBtdXN0IGJlIGEgYm9vbGVhbi4nO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZUFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbihhbGxvd0NsaWVudENsYXNzQ3JlYXRpb24pIHtcbiAgICBpZiAodHlwZW9mIGFsbG93Q2xpZW50Q2xhc3NDcmVhdGlvbiAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB0aHJvdyAnUGFyc2UgU2VydmVyIG9wdGlvbiBhbGxvd0NsaWVudENsYXNzQ3JlYXRpb24gbXVzdCBiZSBhIGJvb2xlYW4uJztcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVTZWN1cml0eU9wdGlvbnMoc2VjdXJpdHkpIHtcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHNlY3VyaXR5KSAhPT0gJ1tvYmplY3QgT2JqZWN0XScpIHtcbiAgICAgIHRocm93ICdQYXJzZSBTZXJ2ZXIgb3B0aW9uIHNlY3VyaXR5IG11c3QgYmUgYW4gb2JqZWN0Lic7XG4gICAgfVxuICAgIGlmIChzZWN1cml0eS5lbmFibGVDaGVjayA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBzZWN1cml0eS5lbmFibGVDaGVjayA9IFNlY3VyaXR5T3B0aW9ucy5lbmFibGVDaGVjay5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAoIWlzQm9vbGVhbihzZWN1cml0eS5lbmFibGVDaGVjaykpIHtcbiAgICAgIHRocm93ICdQYXJzZSBTZXJ2ZXIgb3B0aW9uIHNlY3VyaXR5LmVuYWJsZUNoZWNrIG11c3QgYmUgYSBib29sZWFuLic7XG4gICAgfVxuICAgIGlmIChzZWN1cml0eS5lbmFibGVDaGVja0xvZyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBzZWN1cml0eS5lbmFibGVDaGVja0xvZyA9IFNlY3VyaXR5T3B0aW9ucy5lbmFibGVDaGVja0xvZy5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAoIWlzQm9vbGVhbihzZWN1cml0eS5lbmFibGVDaGVja0xvZykpIHtcbiAgICAgIHRocm93ICdQYXJzZSBTZXJ2ZXIgb3B0aW9uIHNlY3VyaXR5LmVuYWJsZUNoZWNrTG9nIG11c3QgYmUgYSBib29sZWFuLic7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlU2NoZW1hT3B0aW9ucyhzY2hlbWE6IFNjaGVtYU9wdGlvbnMpIHtcbiAgICBpZiAoIXNjaGVtYSkgeyByZXR1cm47IH1cbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHNjaGVtYSkgIT09ICdbb2JqZWN0IE9iamVjdF0nKSB7XG4gICAgICB0aHJvdyAnUGFyc2UgU2VydmVyIG9wdGlvbiBzY2hlbWEgbXVzdCBiZSBhbiBvYmplY3QuJztcbiAgICB9XG4gICAgaWYgKHNjaGVtYS5kZWZpbml0aW9ucyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBzY2hlbWEuZGVmaW5pdGlvbnMgPSBTY2hlbWFPcHRpb25zLmRlZmluaXRpb25zLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICghQXJyYXkuaXNBcnJheShzY2hlbWEuZGVmaW5pdGlvbnMpKSB7XG4gICAgICB0aHJvdyAnUGFyc2UgU2VydmVyIG9wdGlvbiBzY2hlbWEuZGVmaW5pdGlvbnMgbXVzdCBiZSBhbiBhcnJheS4nO1xuICAgIH1cbiAgICBpZiAoc2NoZW1hLnN0cmljdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBzY2hlbWEuc3RyaWN0ID0gU2NoZW1hT3B0aW9ucy5zdHJpY3QuZGVmYXVsdDtcbiAgICB9IGVsc2UgaWYgKCFpc0Jvb2xlYW4oc2NoZW1hLnN0cmljdCkpIHtcbiAgICAgIHRocm93ICdQYXJzZSBTZXJ2ZXIgb3B0aW9uIHNjaGVtYS5zdHJpY3QgbXVzdCBiZSBhIGJvb2xlYW4uJztcbiAgICB9XG4gICAgaWYgKHNjaGVtYS5kZWxldGVFeHRyYUZpZWxkcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBzY2hlbWEuZGVsZXRlRXh0cmFGaWVsZHMgPSBTY2hlbWFPcHRpb25zLmRlbGV0ZUV4dHJhRmllbGRzLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICghaXNCb29sZWFuKHNjaGVtYS5kZWxldGVFeHRyYUZpZWxkcykpIHtcbiAgICAgIHRocm93ICdQYXJzZSBTZXJ2ZXIgb3B0aW9uIHNjaGVtYS5kZWxldGVFeHRyYUZpZWxkcyBtdXN0IGJlIGEgYm9vbGVhbi4nO1xuICAgIH1cbiAgICBpZiAoc2NoZW1hLnJlY3JlYXRlTW9kaWZpZWRGaWVsZHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgc2NoZW1hLnJlY3JlYXRlTW9kaWZpZWRGaWVsZHMgPSBTY2hlbWFPcHRpb25zLnJlY3JlYXRlTW9kaWZpZWRGaWVsZHMuZGVmYXVsdDtcbiAgICB9IGVsc2UgaWYgKCFpc0Jvb2xlYW4oc2NoZW1hLnJlY3JlYXRlTW9kaWZpZWRGaWVsZHMpKSB7XG4gICAgICB0aHJvdyAnUGFyc2UgU2VydmVyIG9wdGlvbiBzY2hlbWEucmVjcmVhdGVNb2RpZmllZEZpZWxkcyBtdXN0IGJlIGEgYm9vbGVhbi4nO1xuICAgIH1cbiAgICBpZiAoc2NoZW1hLmxvY2tTY2hlbWFzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHNjaGVtYS5sb2NrU2NoZW1hcyA9IFNjaGVtYU9wdGlvbnMubG9ja1NjaGVtYXMuZGVmYXVsdDtcbiAgICB9IGVsc2UgaWYgKCFpc0Jvb2xlYW4oc2NoZW1hLmxvY2tTY2hlbWFzKSkge1xuICAgICAgdGhyb3cgJ1BhcnNlIFNlcnZlciBvcHRpb24gc2NoZW1hLmxvY2tTY2hlbWFzIG11c3QgYmUgYSBib29sZWFuLic7XG4gICAgfVxuICAgIGlmIChzY2hlbWEuYmVmb3JlTWlncmF0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHNjaGVtYS5iZWZvcmVNaWdyYXRpb24gPSBudWxsO1xuICAgIH0gZWxzZSBpZiAoc2NoZW1hLmJlZm9yZU1pZ3JhdGlvbiAhPT0gbnVsbCAmJiB0eXBlb2Ygc2NoZW1hLmJlZm9yZU1pZ3JhdGlvbiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhyb3cgJ1BhcnNlIFNlcnZlciBvcHRpb24gc2NoZW1hLmJlZm9yZU1pZ3JhdGlvbiBtdXN0IGJlIGEgZnVuY3Rpb24uJztcbiAgICB9XG4gICAgaWYgKHNjaGVtYS5hZnRlck1pZ3JhdGlvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBzY2hlbWEuYWZ0ZXJNaWdyYXRpb24gPSBudWxsO1xuICAgIH0gZWxzZSBpZiAoc2NoZW1hLmFmdGVyTWlncmF0aW9uICE9PSBudWxsICYmIHR5cGVvZiBzY2hlbWEuYWZ0ZXJNaWdyYXRpb24gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRocm93ICdQYXJzZSBTZXJ2ZXIgb3B0aW9uIHNjaGVtYS5hZnRlck1pZ3JhdGlvbiBtdXN0IGJlIGEgZnVuY3Rpb24uJztcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVQYWdlc09wdGlvbnMocGFnZXMpIHtcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHBhZ2VzKSAhPT0gJ1tvYmplY3QgT2JqZWN0XScpIHtcbiAgICAgIHRocm93ICdQYXJzZSBTZXJ2ZXIgb3B0aW9uIHBhZ2VzIG11c3QgYmUgYW4gb2JqZWN0Lic7XG4gICAgfVxuICAgIGlmIChwYWdlcy5lbmFibGVSb3V0ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcGFnZXMuZW5hYmxlUm91dGVyID0gUGFnZXNPcHRpb25zLmVuYWJsZVJvdXRlci5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAoIWlzQm9vbGVhbihwYWdlcy5lbmFibGVSb3V0ZXIpKSB7XG4gICAgICB0aHJvdyAnUGFyc2UgU2VydmVyIG9wdGlvbiBwYWdlcy5lbmFibGVSb3V0ZXIgbXVzdCBiZSBhIGJvb2xlYW4uJztcbiAgICB9XG4gICAgaWYgKHBhZ2VzLmVuYWJsZUxvY2FsaXphdGlvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBwYWdlcy5lbmFibGVMb2NhbGl6YXRpb24gPSBQYWdlc09wdGlvbnMuZW5hYmxlTG9jYWxpemF0aW9uLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICghaXNCb29sZWFuKHBhZ2VzLmVuYWJsZUxvY2FsaXphdGlvbikpIHtcbiAgICAgIHRocm93ICdQYXJzZSBTZXJ2ZXIgb3B0aW9uIHBhZ2VzLmVuYWJsZUxvY2FsaXphdGlvbiBtdXN0IGJlIGEgYm9vbGVhbi4nO1xuICAgIH1cbiAgICBpZiAocGFnZXMubG9jYWxpemF0aW9uSnNvblBhdGggPT09IHVuZGVmaW5lZCkge1xuICAgICAgcGFnZXMubG9jYWxpemF0aW9uSnNvblBhdGggPSBQYWdlc09wdGlvbnMubG9jYWxpemF0aW9uSnNvblBhdGguZGVmYXVsdDtcbiAgICB9IGVsc2UgaWYgKCFpc1N0cmluZyhwYWdlcy5sb2NhbGl6YXRpb25Kc29uUGF0aCkpIHtcbiAgICAgIHRocm93ICdQYXJzZSBTZXJ2ZXIgb3B0aW9uIHBhZ2VzLmxvY2FsaXphdGlvbkpzb25QYXRoIG11c3QgYmUgYSBzdHJpbmcuJztcbiAgICB9XG4gICAgaWYgKHBhZ2VzLmxvY2FsaXphdGlvbkZhbGxiYWNrTG9jYWxlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHBhZ2VzLmxvY2FsaXphdGlvbkZhbGxiYWNrTG9jYWxlID0gUGFnZXNPcHRpb25zLmxvY2FsaXphdGlvbkZhbGxiYWNrTG9jYWxlLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICghaXNTdHJpbmcocGFnZXMubG9jYWxpemF0aW9uRmFsbGJhY2tMb2NhbGUpKSB7XG4gICAgICB0aHJvdyAnUGFyc2UgU2VydmVyIG9wdGlvbiBwYWdlcy5sb2NhbGl6YXRpb25GYWxsYmFja0xvY2FsZSBtdXN0IGJlIGEgc3RyaW5nLic7XG4gICAgfVxuICAgIGlmIChwYWdlcy5wbGFjZWhvbGRlcnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcGFnZXMucGxhY2Vob2xkZXJzID0gUGFnZXNPcHRpb25zLnBsYWNlaG9sZGVycy5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwocGFnZXMucGxhY2Vob2xkZXJzKSAhPT0gJ1tvYmplY3QgT2JqZWN0XScgJiZcbiAgICAgIHR5cGVvZiBwYWdlcy5wbGFjZWhvbGRlcnMgIT09ICdmdW5jdGlvbidcbiAgICApIHtcbiAgICAgIHRocm93ICdQYXJzZSBTZXJ2ZXIgb3B0aW9uIHBhZ2VzLnBsYWNlaG9sZGVycyBtdXN0IGJlIGFuIG9iamVjdCBvciBhIGZ1bmN0aW9uLic7XG4gICAgfVxuICAgIGlmIChwYWdlcy5mb3JjZVJlZGlyZWN0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHBhZ2VzLmZvcmNlUmVkaXJlY3QgPSBQYWdlc09wdGlvbnMuZm9yY2VSZWRpcmVjdC5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAoIWlzQm9vbGVhbihwYWdlcy5mb3JjZVJlZGlyZWN0KSkge1xuICAgICAgdGhyb3cgJ1BhcnNlIFNlcnZlciBvcHRpb24gcGFnZXMuZm9yY2VSZWRpcmVjdCBtdXN0IGJlIGEgYm9vbGVhbi4nO1xuICAgIH1cbiAgICBpZiAocGFnZXMucGFnZXNQYXRoID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHBhZ2VzLnBhZ2VzUGF0aCA9IFBhZ2VzT3B0aW9ucy5wYWdlc1BhdGguZGVmYXVsdDtcbiAgICB9IGVsc2UgaWYgKCFpc1N0cmluZyhwYWdlcy5wYWdlc1BhdGgpKSB7XG4gICAgICB0aHJvdyAnUGFyc2UgU2VydmVyIG9wdGlvbiBwYWdlcy5wYWdlc1BhdGggbXVzdCBiZSBhIHN0cmluZy4nO1xuICAgIH1cbiAgICBpZiAocGFnZXMucGFnZXNFbmRwb2ludCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBwYWdlcy5wYWdlc0VuZHBvaW50ID0gUGFnZXNPcHRpb25zLnBhZ2VzRW5kcG9pbnQuZGVmYXVsdDtcbiAgICB9IGVsc2UgaWYgKCFpc1N0cmluZyhwYWdlcy5wYWdlc0VuZHBvaW50KSkge1xuICAgICAgdGhyb3cgJ1BhcnNlIFNlcnZlciBvcHRpb24gcGFnZXMucGFnZXNFbmRwb2ludCBtdXN0IGJlIGEgc3RyaW5nLic7XG4gICAgfVxuICAgIGlmIChwYWdlcy5jdXN0b21VcmxzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHBhZ2VzLmN1c3RvbVVybHMgPSBQYWdlc09wdGlvbnMuY3VzdG9tVXJscy5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHBhZ2VzLmN1c3RvbVVybHMpICE9PSAnW29iamVjdCBPYmplY3RdJykge1xuICAgICAgdGhyb3cgJ1BhcnNlIFNlcnZlciBvcHRpb24gcGFnZXMuY3VzdG9tVXJscyBtdXN0IGJlIGFuIG9iamVjdC4nO1xuICAgIH1cbiAgICBpZiAocGFnZXMuY3VzdG9tUm91dGVzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHBhZ2VzLmN1c3RvbVJvdXRlcyA9IFBhZ2VzT3B0aW9ucy5jdXN0b21Sb3V0ZXMuZGVmYXVsdDtcbiAgICB9IGVsc2UgaWYgKCEocGFnZXMuY3VzdG9tUm91dGVzIGluc3RhbmNlb2YgQXJyYXkpKSB7XG4gICAgICB0aHJvdyAnUGFyc2UgU2VydmVyIG9wdGlvbiBwYWdlcy5jdXN0b21Sb3V0ZXMgbXVzdCBiZSBhbiBhcnJheS4nO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZUlkZW1wb3RlbmN5T3B0aW9ucyhpZGVtcG90ZW5jeU9wdGlvbnMpIHtcbiAgICBpZiAoIWlkZW1wb3RlbmN5T3B0aW9ucykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoaWRlbXBvdGVuY3lPcHRpb25zLnR0bCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZGVtcG90ZW5jeU9wdGlvbnMudHRsID0gSWRlbXBvdGVuY3lPcHRpb25zLnR0bC5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAoIWlzTmFOKGlkZW1wb3RlbmN5T3B0aW9ucy50dGwpICYmIGlkZW1wb3RlbmN5T3B0aW9ucy50dGwgPD0gMCkge1xuICAgICAgdGhyb3cgJ2lkZW1wb3RlbmN5IFRUTCB2YWx1ZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwIHNlY29uZHMnO1xuICAgIH0gZWxzZSBpZiAoaXNOYU4oaWRlbXBvdGVuY3lPcHRpb25zLnR0bCkpIHtcbiAgICAgIHRocm93ICdpZGVtcG90ZW5jeSBUVEwgdmFsdWUgbXVzdCBiZSBhIG51bWJlcic7XG4gICAgfVxuICAgIGlmICghaWRlbXBvdGVuY3lPcHRpb25zLnBhdGhzKSB7XG4gICAgICBpZGVtcG90ZW5jeU9wdGlvbnMucGF0aHMgPSBJZGVtcG90ZW5jeU9wdGlvbnMucGF0aHMuZGVmYXVsdDtcbiAgICB9IGVsc2UgaWYgKCEoaWRlbXBvdGVuY3lPcHRpb25zLnBhdGhzIGluc3RhbmNlb2YgQXJyYXkpKSB7XG4gICAgICB0aHJvdyAnaWRlbXBvdGVuY3kgcGF0aHMgbXVzdCBiZSBvZiBhbiBhcnJheSBvZiBzdHJpbmdzJztcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVBY2NvdW50TG9ja291dFBvbGljeShhY2NvdW50TG9ja291dCkge1xuICAgIGlmIChhY2NvdW50TG9ja291dCkge1xuICAgICAgaWYgKFxuICAgICAgICB0eXBlb2YgYWNjb3VudExvY2tvdXQuZHVyYXRpb24gIT09ICdudW1iZXInIHx8XG4gICAgICAgIGFjY291bnRMb2Nrb3V0LmR1cmF0aW9uIDw9IDAgfHxcbiAgICAgICAgYWNjb3VudExvY2tvdXQuZHVyYXRpb24gPiA5OTk5OVxuICAgICAgKSB7XG4gICAgICAgIHRocm93ICdBY2NvdW50IGxvY2tvdXQgZHVyYXRpb24gc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiAwIGFuZCBsZXNzIHRoYW4gMTAwMDAwJztcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICAhTnVtYmVyLmlzSW50ZWdlcihhY2NvdW50TG9ja291dC50aHJlc2hvbGQpIHx8XG4gICAgICAgIGFjY291bnRMb2Nrb3V0LnRocmVzaG9sZCA8IDEgfHxcbiAgICAgICAgYWNjb3VudExvY2tvdXQudGhyZXNob2xkID4gOTk5XG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgJ0FjY291bnQgbG9ja291dCB0aHJlc2hvbGQgc2hvdWxkIGJlIGFuIGludGVnZXIgZ3JlYXRlciB0aGFuIDAgYW5kIGxlc3MgdGhhbiAxMDAwJztcbiAgICAgIH1cblxuICAgICAgaWYgKGFjY291bnRMb2Nrb3V0LnVubG9ja09uUGFzc3dvcmRSZXNldCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGFjY291bnRMb2Nrb3V0LnVubG9ja09uUGFzc3dvcmRSZXNldCA9IEFjY291bnRMb2Nrb3V0T3B0aW9ucy51bmxvY2tPblBhc3N3b3JkUmVzZXQuZGVmYXVsdDtcbiAgICAgIH0gZWxzZSBpZiAoIWlzQm9vbGVhbihhY2NvdW50TG9ja291dC51bmxvY2tPblBhc3N3b3JkUmVzZXQpKSB7XG4gICAgICAgIHRocm93ICdQYXJzZSBTZXJ2ZXIgb3B0aW9uIGFjY291bnRMb2Nrb3V0LnVubG9ja09uUGFzc3dvcmRSZXNldCBtdXN0IGJlIGEgYm9vbGVhbi4nO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZVBhc3N3b3JkUG9saWN5KHBhc3N3b3JkUG9saWN5KSB7XG4gICAgaWYgKHBhc3N3b3JkUG9saWN5KSB7XG4gICAgICBpZiAoXG4gICAgICAgIHBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkQWdlICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgKHR5cGVvZiBwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEFnZSAhPT0gJ251bWJlcicgfHwgcGFzc3dvcmRQb2xpY3kubWF4UGFzc3dvcmRBZ2UgPCAwKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93ICdwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEFnZSBtdXN0IGJlIGEgcG9zaXRpdmUgbnVtYmVyJztcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBwYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbiAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICh0eXBlb2YgcGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24gIT09ICdudW1iZXInIHx8XG4gICAgICAgICAgcGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24gPD0gMClcbiAgICAgICkge1xuICAgICAgICB0aHJvdyAncGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24gbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcic7XG4gICAgICB9XG5cbiAgICAgIGlmIChwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuKSB7XG4gICAgICAgIGlmICh0eXBlb2YgcGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yUGF0dGVybiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuID0gbmV3IFJlZ0V4cChwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuKTtcbiAgICAgICAgfSBlbHNlIGlmICghKHBhc3N3b3JkUG9saWN5LnZhbGlkYXRvclBhdHRlcm4gaW5zdGFuY2VvZiBSZWdFeHApKSB7XG4gICAgICAgICAgdGhyb3cgJ3Bhc3N3b3JkUG9saWN5LnZhbGlkYXRvclBhdHRlcm4gbXVzdCBiZSBhIHJlZ2V4IHN0cmluZyBvciBSZWdFeHAgb2JqZWN0Lic7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBwYXNzd29yZFBvbGljeS52YWxpZGF0b3JDYWxsYmFjayAmJlxuICAgICAgICB0eXBlb2YgcGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yQ2FsbGJhY2sgIT09ICdmdW5jdGlvbidcbiAgICAgICkge1xuICAgICAgICB0aHJvdyAncGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yQ2FsbGJhY2sgbXVzdCBiZSBhIGZ1bmN0aW9uLic7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgcGFzc3dvcmRQb2xpY3kuZG9Ob3RBbGxvd1VzZXJuYW1lICYmXG4gICAgICAgIHR5cGVvZiBwYXNzd29yZFBvbGljeS5kb05vdEFsbG93VXNlcm5hbWUgIT09ICdib29sZWFuJ1xuICAgICAgKSB7XG4gICAgICAgIHRocm93ICdwYXNzd29yZFBvbGljeS5kb05vdEFsbG93VXNlcm5hbWUgbXVzdCBiZSBhIGJvb2xlYW4gdmFsdWUuJztcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEhpc3RvcnkgJiZcbiAgICAgICAgKCFOdW1iZXIuaXNJbnRlZ2VyKHBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeSkgfHxcbiAgICAgICAgICBwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEhpc3RvcnkgPD0gMCB8fFxuICAgICAgICAgIHBhc3N3b3JkUG9saWN5Lm1heFBhc3N3b3JkSGlzdG9yeSA+IDIwKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93ICdwYXNzd29yZFBvbGljeS5tYXhQYXNzd29yZEhpc3RvcnkgbXVzdCBiZSBhbiBpbnRlZ2VyIHJhbmdpbmcgMCAtIDIwJztcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBwYXNzd29yZFBvbGljeS5yZXNldFRva2VuUmV1c2VJZlZhbGlkICYmXG4gICAgICAgIHR5cGVvZiBwYXNzd29yZFBvbGljeS5yZXNldFRva2VuUmV1c2VJZlZhbGlkICE9PSAnYm9vbGVhbidcbiAgICAgICkge1xuICAgICAgICB0aHJvdyAncmVzZXRUb2tlblJldXNlSWZWYWxpZCBtdXN0IGJlIGEgYm9vbGVhbiB2YWx1ZSc7XG4gICAgICB9XG4gICAgICBpZiAocGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblJldXNlSWZWYWxpZCAmJiAhcGFzc3dvcmRQb2xpY3kucmVzZXRUb2tlblZhbGlkaXR5RHVyYXRpb24pIHtcbiAgICAgICAgdGhyb3cgJ1lvdSBjYW5ub3QgdXNlIHJlc2V0VG9rZW5SZXVzZUlmVmFsaWQgd2l0aG91dCByZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbic7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgcGFzc3dvcmRQb2xpY3kucmVzZXRQYXNzd29yZFN1Y2Nlc3NPbkludmFsaWRFbWFpbCAmJlxuICAgICAgICB0eXBlb2YgcGFzc3dvcmRQb2xpY3kucmVzZXRQYXNzd29yZFN1Y2Nlc3NPbkludmFsaWRFbWFpbCAhPT0gJ2Jvb2xlYW4nXG4gICAgICApIHtcbiAgICAgICAgdGhyb3cgJ3Jlc2V0UGFzc3dvcmRTdWNjZXNzT25JbnZhbGlkRW1haWwgbXVzdCBiZSBhIGJvb2xlYW4gdmFsdWUnO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIGlmIHRoZSBwYXNzd29yZFBvbGljeS52YWxpZGF0b3JQYXR0ZXJuIGlzIGNvbmZpZ3VyZWQgdGhlbiBzZXR1cCBhIGNhbGxiYWNrIHRvIHByb2Nlc3MgdGhlIHBhdHRlcm5cbiAgc3RhdGljIHNldHVwUGFzc3dvcmRWYWxpZGF0b3IocGFzc3dvcmRQb2xpY3kpIHtcbiAgICBpZiAocGFzc3dvcmRQb2xpY3kgJiYgcGFzc3dvcmRQb2xpY3kudmFsaWRhdG9yUGF0dGVybikge1xuICAgICAgcGFzc3dvcmRQb2xpY3kucGF0dGVyblZhbGlkYXRvciA9IHZhbHVlID0+IHtcbiAgICAgICAgcmV0dXJuIHBhc3N3b3JkUG9saWN5LnZhbGlkYXRvclBhdHRlcm4udGVzdCh2YWx1ZSk7XG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZVB1YmxpY1NlcnZlclVSTCh7IHB1YmxpY1NlcnZlclVSTCwgcmVxdWlyZWQgPSBmYWxzZSB9KSB7XG4gICAgaWYgKCFwdWJsaWNTZXJ2ZXJVUkwpIHtcbiAgICAgIGlmICghcmVxdWlyZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhyb3cgJ1RoZSBvcHRpb24gcHVibGljU2VydmVyVVJMIGlzIHJlcXVpcmVkLic7XG4gICAgfVxuXG4gICAgY29uc3QgdHlwZSA9IHR5cGVvZiBwdWJsaWNTZXJ2ZXJVUkw7XG5cbiAgICBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGlmICghcHVibGljU2VydmVyVVJMLnN0YXJ0c1dpdGgoJ2h0dHA6Ly8nKSAmJiAhcHVibGljU2VydmVyVVJMLnN0YXJ0c1dpdGgoJ2h0dHBzOi8vJykpIHtcbiAgICAgICAgdGhyb3cgJ1RoZSBvcHRpb24gcHVibGljU2VydmVyVVJMIG11c3QgYmUgYSB2YWxpZCBVUkwgc3RhcnRpbmcgd2l0aCBodHRwOi8vIG9yIGh0dHBzOi8vLic7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHR5cGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aHJvdyBgVGhlIG9wdGlvbiBwdWJsaWNTZXJ2ZXJVUkwgbXVzdCBiZSBhIHN0cmluZyBvciBmdW5jdGlvbiwgYnV0IGdvdCAke3R5cGV9LmA7XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVFbWFpbENvbmZpZ3VyYXRpb24oe1xuICAgIGVtYWlsQWRhcHRlcixcbiAgICBhcHBOYW1lLFxuICAgIHB1YmxpY1NlcnZlclVSTCxcbiAgICBlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbixcbiAgICBlbWFpbFZlcmlmeVRva2VuUmV1c2VJZlZhbGlkLFxuICB9KSB7XG4gICAgaWYgKCFlbWFpbEFkYXB0ZXIpIHtcbiAgICAgIHRocm93ICdBbiBlbWFpbEFkYXB0ZXIgaXMgcmVxdWlyZWQgZm9yIGUtbWFpbCB2ZXJpZmljYXRpb24gYW5kIHBhc3N3b3JkIHJlc2V0cy4nO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGFwcE5hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyAnQW4gYXBwIG5hbWUgaXMgcmVxdWlyZWQgZm9yIGUtbWFpbCB2ZXJpZmljYXRpb24gYW5kIHBhc3N3b3JkIHJlc2V0cy4nO1xuICAgIH1cbiAgICB0aGlzLnZhbGlkYXRlUHVibGljU2VydmVyVVJMKHsgcHVibGljU2VydmVyVVJMLCByZXF1aXJlZDogdHJ1ZSB9KTtcbiAgICBpZiAoZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24pIHtcbiAgICAgIGlmIChpc05hTihlbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbikpIHtcbiAgICAgICAgdGhyb3cgJ0VtYWlsIHZlcmlmeSB0b2tlbiB2YWxpZGl0eSBkdXJhdGlvbiBtdXN0IGJlIGEgdmFsaWQgbnVtYmVyLic7XG4gICAgICB9IGVsc2UgaWYgKGVtYWlsVmVyaWZ5VG9rZW5WYWxpZGl0eUR1cmF0aW9uIDw9IDApIHtcbiAgICAgICAgdGhyb3cgJ0VtYWlsIHZlcmlmeSB0b2tlbiB2YWxpZGl0eSBkdXJhdGlvbiBtdXN0IGJlIGEgdmFsdWUgZ3JlYXRlciB0aGFuIDAuJztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVtYWlsVmVyaWZ5VG9rZW5SZXVzZUlmVmFsaWQgJiYgdHlwZW9mIGVtYWlsVmVyaWZ5VG9rZW5SZXVzZUlmVmFsaWQgIT09ICdib29sZWFuJykge1xuICAgICAgdGhyb3cgJ2VtYWlsVmVyaWZ5VG9rZW5SZXVzZUlmVmFsaWQgbXVzdCBiZSBhIGJvb2xlYW4gdmFsdWUnO1xuICAgIH1cbiAgICBpZiAoZW1haWxWZXJpZnlUb2tlblJldXNlSWZWYWxpZCAmJiAhZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24pIHtcbiAgICAgIHRocm93ICdZb3UgY2Fubm90IHVzZSBlbWFpbFZlcmlmeVRva2VuUmV1c2VJZlZhbGlkIHdpdGhvdXQgZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24nO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZUZpbGVVcGxvYWRPcHRpb25zKGZpbGVVcGxvYWQpIHtcbiAgICB0cnkge1xuICAgICAgaWYgKGZpbGVVcGxvYWQgPT0gbnVsbCB8fCB0eXBlb2YgZmlsZVVwbG9hZCAhPT0gJ29iamVjdCcgfHwgZmlsZVVwbG9hZCBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgIHRocm93ICdmaWxlVXBsb2FkIG11c3QgYmUgYW4gb2JqZWN0IHZhbHVlLic7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKGUgaW5zdGFuY2VvZiBSZWZlcmVuY2VFcnJvcikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aHJvdyBlO1xuICAgIH1cbiAgICBpZiAoZmlsZVVwbG9hZC5lbmFibGVGb3JBbm9ueW1vdXNVc2VyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGZpbGVVcGxvYWQuZW5hYmxlRm9yQW5vbnltb3VzVXNlciA9IEZpbGVVcGxvYWRPcHRpb25zLmVuYWJsZUZvckFub255bW91c1VzZXIuZGVmYXVsdDtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBmaWxlVXBsb2FkLmVuYWJsZUZvckFub255bW91c1VzZXIgIT09ICdib29sZWFuJykge1xuICAgICAgdGhyb3cgJ2ZpbGVVcGxvYWQuZW5hYmxlRm9yQW5vbnltb3VzVXNlciBtdXN0IGJlIGEgYm9vbGVhbiB2YWx1ZS4nO1xuICAgIH1cbiAgICBpZiAoZmlsZVVwbG9hZC5lbmFibGVGb3JQdWJsaWMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgZmlsZVVwbG9hZC5lbmFibGVGb3JQdWJsaWMgPSBGaWxlVXBsb2FkT3B0aW9ucy5lbmFibGVGb3JQdWJsaWMuZGVmYXVsdDtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBmaWxlVXBsb2FkLmVuYWJsZUZvclB1YmxpYyAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB0aHJvdyAnZmlsZVVwbG9hZC5lbmFibGVGb3JQdWJsaWMgbXVzdCBiZSBhIGJvb2xlYW4gdmFsdWUuJztcbiAgICB9XG4gICAgaWYgKGZpbGVVcGxvYWQuZW5hYmxlRm9yQXV0aGVudGljYXRlZFVzZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgZmlsZVVwbG9hZC5lbmFibGVGb3JBdXRoZW50aWNhdGVkVXNlciA9IEZpbGVVcGxvYWRPcHRpb25zLmVuYWJsZUZvckF1dGhlbnRpY2F0ZWRVc2VyLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZmlsZVVwbG9hZC5lbmFibGVGb3JBdXRoZW50aWNhdGVkVXNlciAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB0aHJvdyAnZmlsZVVwbG9hZC5lbmFibGVGb3JBdXRoZW50aWNhdGVkVXNlciBtdXN0IGJlIGEgYm9vbGVhbiB2YWx1ZS4nO1xuICAgIH1cbiAgICBpZiAoZmlsZVVwbG9hZC5maWxlRXh0ZW5zaW9ucyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBmaWxlVXBsb2FkLmZpbGVFeHRlbnNpb25zID0gRmlsZVVwbG9hZE9wdGlvbnMuZmlsZUV4dGVuc2lvbnMuZGVmYXVsdDtcbiAgICB9IGVsc2UgaWYgKCFBcnJheS5pc0FycmF5KGZpbGVVcGxvYWQuZmlsZUV4dGVuc2lvbnMpKSB7XG4gICAgICB0aHJvdyAnZmlsZVVwbG9hZC5maWxlRXh0ZW5zaW9ucyBtdXN0IGJlIGFuIGFycmF5Lic7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlSXBzKGZpZWxkLCBtYXN0ZXJLZXlJcHMpIHtcbiAgICBmb3IgKGxldCBpcCBvZiBtYXN0ZXJLZXlJcHMpIHtcbiAgICAgIGlmIChpcC5pbmNsdWRlcygnLycpKSB7XG4gICAgICAgIGlwID0gaXAuc3BsaXQoJy8nKVswXTtcbiAgICAgIH1cbiAgICAgIGlmICghbmV0LmlzSVAoaXApKSB7XG4gICAgICAgIHRocm93IGBUaGUgUGFyc2UgU2VydmVyIG9wdGlvbiBcIiR7ZmllbGR9XCIgY29udGFpbnMgYW4gaW52YWxpZCBJUCBhZGRyZXNzIFwiJHtpcH1cIi5gO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZUVuYWJsZUluc2VjdXJlQXV0aEFkYXB0ZXJzKGVuYWJsZUluc2VjdXJlQXV0aEFkYXB0ZXJzKSB7XG4gICAgaWYgKGVuYWJsZUluc2VjdXJlQXV0aEFkYXB0ZXJzICYmIHR5cGVvZiBlbmFibGVJbnNlY3VyZUF1dGhBZGFwdGVycyAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB0aHJvdyAnUGFyc2UgU2VydmVyIG9wdGlvbiBlbmFibGVJbnNlY3VyZUF1dGhBZGFwdGVycyBtdXN0IGJlIGEgYm9vbGVhbi4nO1xuICAgIH1cbiAgICBpZiAoZW5hYmxlSW5zZWN1cmVBdXRoQWRhcHRlcnMpIHtcbiAgICAgIERlcHJlY2F0b3IubG9nUnVudGltZURlcHJlY2F0aW9uKHsgdXNhZ2U6ICdpbnNlY3VyZSBhZGFwdGVyJyB9KTtcbiAgICB9XG4gIH1cblxuICBnZXQgbW91bnQoKSB7XG4gICAgdmFyIG1vdW50ID0gdGhpcy5fbW91bnQ7XG4gICAgaWYgKHRoaXMucHVibGljU2VydmVyVVJMKSB7XG4gICAgICBtb3VudCA9IHRoaXMucHVibGljU2VydmVyVVJMO1xuICAgIH1cbiAgICByZXR1cm4gbW91bnQ7XG4gIH1cblxuICBzZXQgbW91bnQobmV3VmFsdWUpIHtcbiAgICB0aGlzLl9tb3VudCA9IG5ld1ZhbHVlO1xuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlU2Vzc2lvbkNvbmZpZ3VyYXRpb24oc2Vzc2lvbkxlbmd0aCwgZXhwaXJlSW5hY3RpdmVTZXNzaW9ucykge1xuICAgIGlmIChleHBpcmVJbmFjdGl2ZVNlc3Npb25zKSB7XG4gICAgICBpZiAoaXNOYU4oc2Vzc2lvbkxlbmd0aCkpIHtcbiAgICAgICAgdGhyb3cgJ1Nlc3Npb24gbGVuZ3RoIG11c3QgYmUgYSB2YWxpZCBudW1iZXIuJztcbiAgICAgIH0gZWxzZSBpZiAoc2Vzc2lvbkxlbmd0aCA8PSAwKSB7XG4gICAgICAgIHRocm93ICdTZXNzaW9uIGxlbmd0aCBtdXN0IGJlIGEgdmFsdWUgZ3JlYXRlciB0aGFuIDAuJztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVEZWZhdWx0TGltaXQoZGVmYXVsdExpbWl0KSB7XG4gICAgaWYgKGRlZmF1bHRMaW1pdCA9PSBudWxsKSB7XG4gICAgICBkZWZhdWx0TGltaXQgPSBQYXJzZVNlcnZlck9wdGlvbnMuZGVmYXVsdExpbWl0LmRlZmF1bHQ7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZGVmYXVsdExpbWl0ICE9PSAnbnVtYmVyJykge1xuICAgICAgdGhyb3cgJ0RlZmF1bHQgbGltaXQgbXVzdCBiZSBhIG51bWJlci4nO1xuICAgIH1cbiAgICBpZiAoZGVmYXVsdExpbWl0IDw9IDApIHtcbiAgICAgIHRocm93ICdEZWZhdWx0IGxpbWl0IG11c3QgYmUgYSB2YWx1ZSBncmVhdGVyIHRoYW4gMC4nO1xuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZU1heExpbWl0KG1heExpbWl0KSB7XG4gICAgaWYgKG1heExpbWl0IDw9IDApIHtcbiAgICAgIHRocm93ICdNYXggbGltaXQgbXVzdCBiZSBhIHZhbHVlIGdyZWF0ZXIgdGhhbiAwLic7XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlQWxsb3dIZWFkZXJzKGFsbG93SGVhZGVycykge1xuICAgIGlmICghW251bGwsIHVuZGVmaW5lZF0uaW5jbHVkZXMoYWxsb3dIZWFkZXJzKSkge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYWxsb3dIZWFkZXJzKSkge1xuICAgICAgICBhbGxvd0hlYWRlcnMuZm9yRWFjaChoZWFkZXIgPT4ge1xuICAgICAgICAgIGlmICh0eXBlb2YgaGVhZGVyICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGhyb3cgJ0FsbG93IGhlYWRlcnMgbXVzdCBvbmx5IGNvbnRhaW4gc3RyaW5ncyc7XG4gICAgICAgICAgfSBlbHNlIGlmICghaGVhZGVyLnRyaW0oKS5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRocm93ICdBbGxvdyBoZWFkZXJzIG11c3Qgbm90IGNvbnRhaW4gZW1wdHkgc3RyaW5ncyc7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93ICdBbGxvdyBoZWFkZXJzIG11c3QgYmUgYW4gYXJyYXknO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHN0YXRpYyB2YWxpZGF0ZUxvZ0xldmVscyhsb2dMZXZlbHMpIHtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhMb2dMZXZlbHMpKSB7XG4gICAgICBpZiAobG9nTGV2ZWxzW2tleV0pIHtcbiAgICAgICAgaWYgKHZhbGlkTG9nTGV2ZWxzLmluZGV4T2YobG9nTGV2ZWxzW2tleV0pID09PSAtMSkge1xuICAgICAgICAgIHRocm93IGAnJHtrZXl9JyBtdXN0IGJlIG9uZSBvZiAke0pTT04uc3RyaW5naWZ5KHZhbGlkTG9nTGV2ZWxzKX1gO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2dMZXZlbHNba2V5XSA9IExvZ0xldmVsc1trZXldLmRlZmF1bHQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc3RhdGljIHZhbGlkYXRlRGF0YWJhc2VPcHRpb25zKGRhdGFiYXNlT3B0aW9ucykge1xuICAgIGlmIChkYXRhYmFzZU9wdGlvbnMgPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZGF0YWJhc2VPcHRpb25zKSAhPT0gJ1tvYmplY3QgT2JqZWN0XScpIHtcbiAgICAgIHRocm93IGBkYXRhYmFzZU9wdGlvbnMgbXVzdCBiZSBhbiBvYmplY3RgO1xuICAgIH1cblxuICAgIGlmIChkYXRhYmFzZU9wdGlvbnMuZW5hYmxlU2NoZW1hSG9va3MgPT09IHVuZGVmaW5lZCkge1xuICAgICAgZGF0YWJhc2VPcHRpb25zLmVuYWJsZVNjaGVtYUhvb2tzID0gRGF0YWJhc2VPcHRpb25zLmVuYWJsZVNjaGVtYUhvb2tzLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZGF0YWJhc2VPcHRpb25zLmVuYWJsZVNjaGVtYUhvb2tzICE9PSAnYm9vbGVhbicpIHtcbiAgICAgIHRocm93IGBkYXRhYmFzZU9wdGlvbnMuZW5hYmxlU2NoZW1hSG9va3MgbXVzdCBiZSBhIGJvb2xlYW5gO1xuICAgIH1cbiAgICBpZiAoZGF0YWJhc2VPcHRpb25zLnNjaGVtYUNhY2hlVHRsID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGRhdGFiYXNlT3B0aW9ucy5zY2hlbWFDYWNoZVR0bCA9IERhdGFiYXNlT3B0aW9ucy5zY2hlbWFDYWNoZVR0bC5kZWZhdWx0O1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGRhdGFiYXNlT3B0aW9ucy5zY2hlbWFDYWNoZVR0bCAhPT0gJ251bWJlcicpIHtcbiAgICAgIHRocm93IGBkYXRhYmFzZU9wdGlvbnMuc2NoZW1hQ2FjaGVUdGwgbXVzdCBiZSBhIG51bWJlcmA7XG4gICAgfVxuICAgIGlmIChkYXRhYmFzZU9wdGlvbnMuYWxsb3dQdWJsaWNFeHBsYWluID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGRhdGFiYXNlT3B0aW9ucy5hbGxvd1B1YmxpY0V4cGxhaW4gPSBEYXRhYmFzZU9wdGlvbnMuYWxsb3dQdWJsaWNFeHBsYWluLmRlZmF1bHQ7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZGF0YWJhc2VPcHRpb25zLmFsbG93UHVibGljRXhwbGFpbiAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB0aHJvdyBgUGFyc2UgU2VydmVyIG9wdGlvbiAnZGF0YWJhc2VPcHRpb25zLmFsbG93UHVibGljRXhwbGFpbicgbXVzdCBiZSBhIGJvb2xlYW4uYDtcbiAgICB9XG4gIH1cblxuICBzdGF0aWMgdmFsaWRhdGVSYXRlTGltaXQocmF0ZUxpbWl0KSB7XG4gICAgaWYgKCFyYXRlTGltaXQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHJhdGVMaW1pdCkgIT09ICdbb2JqZWN0IE9iamVjdF0nICYmXG4gICAgICAhQXJyYXkuaXNBcnJheShyYXRlTGltaXQpXG4gICAgKSB7XG4gICAgICB0aHJvdyBgcmF0ZUxpbWl0IG11c3QgYmUgYW4gYXJyYXkgb3Igb2JqZWN0YDtcbiAgICB9XG4gICAgY29uc3Qgb3B0aW9ucyA9IEFycmF5LmlzQXJyYXkocmF0ZUxpbWl0KSA/IHJhdGVMaW1pdCA6IFtyYXRlTGltaXRdO1xuICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIG9wdGlvbnMpIHtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob3B0aW9uKSAhPT0gJ1tvYmplY3QgT2JqZWN0XScpIHtcbiAgICAgICAgdGhyb3cgYHJhdGVMaW1pdCBtdXN0IGJlIGFuIGFycmF5IG9mIG9iamVjdHNgO1xuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbi5yZXF1ZXN0UGF0aCA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IGByYXRlTGltaXQucmVxdWVzdFBhdGggbXVzdCBiZSBkZWZpbmVkYDtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9uLnJlcXVlc3RQYXRoICE9PSAnc3RyaW5nJykge1xuICAgICAgICB0aHJvdyBgcmF0ZUxpbWl0LnJlcXVlc3RQYXRoIG11c3QgYmUgYSBzdHJpbmdgO1xuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbi5yZXF1ZXN0VGltZVdpbmRvdyA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IGByYXRlTGltaXQucmVxdWVzdFRpbWVXaW5kb3cgbXVzdCBiZSBkZWZpbmVkYDtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9uLnJlcXVlc3RUaW1lV2luZG93ICE9PSAnbnVtYmVyJykge1xuICAgICAgICB0aHJvdyBgcmF0ZUxpbWl0LnJlcXVlc3RUaW1lV2luZG93IG11c3QgYmUgYSBudW1iZXJgO1xuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbi5pbmNsdWRlSW50ZXJuYWxSZXF1ZXN0cyAmJiB0eXBlb2Ygb3B0aW9uLmluY2x1ZGVJbnRlcm5hbFJlcXVlc3RzICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgdGhyb3cgYHJhdGVMaW1pdC5pbmNsdWRlSW50ZXJuYWxSZXF1ZXN0cyBtdXN0IGJlIGEgYm9vbGVhbmA7XG4gICAgICB9XG4gICAgICBpZiAob3B0aW9uLnJlcXVlc3RDb3VudCA9PSBudWxsKSB7XG4gICAgICAgIHRocm93IGByYXRlTGltaXQucmVxdWVzdENvdW50IG11c3QgYmUgZGVmaW5lZGA7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIG9wdGlvbi5yZXF1ZXN0Q291bnQgIT09ICdudW1iZXInKSB7XG4gICAgICAgIHRocm93IGByYXRlTGltaXQucmVxdWVzdENvdW50IG11c3QgYmUgYSBudW1iZXJgO1xuICAgICAgfVxuICAgICAgaWYgKG9wdGlvbi5lcnJvclJlc3BvbnNlTWVzc2FnZSAmJiB0eXBlb2Ygb3B0aW9uLmVycm9yUmVzcG9uc2VNZXNzYWdlICE9PSAnc3RyaW5nJykge1xuICAgICAgICB0aHJvdyBgcmF0ZUxpbWl0LmVycm9yUmVzcG9uc2VNZXNzYWdlIG11c3QgYmUgYSBzdHJpbmdgO1xuICAgICAgfVxuICAgICAgY29uc3Qgb3B0aW9ucyA9IE9iamVjdC5rZXlzKFBhcnNlU2VydmVyLlJhdGVMaW1pdFpvbmUpO1xuICAgICAgaWYgKG9wdGlvbi56b25lICYmICFvcHRpb25zLmluY2x1ZGVzKG9wdGlvbi56b25lKSkge1xuICAgICAgICBjb25zdCBmb3JtYXR0ZXIgPSBuZXcgSW50bC5MaXN0Rm9ybWF0KCdlbicsIHsgc3R5bGU6ICdzaG9ydCcsIHR5cGU6ICdkaXNqdW5jdGlvbicgfSk7XG4gICAgICAgIHRocm93IGByYXRlTGltaXQuem9uZSBtdXN0IGJlIG9uZSBvZiAke2Zvcm1hdHRlci5mb3JtYXQob3B0aW9ucyl9YDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBnZW5lcmF0ZUVtYWlsVmVyaWZ5VG9rZW5FeHBpcmVzQXQoKSB7XG4gICAgaWYgKCF0aGlzLnZlcmlmeVVzZXJFbWFpbHMgfHwgIXRoaXMuZW1haWxWZXJpZnlUb2tlblZhbGlkaXR5RHVyYXRpb24pIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHZhciBub3cgPSBuZXcgRGF0ZSgpO1xuICAgIHJldHVybiBuZXcgRGF0ZShub3cuZ2V0VGltZSgpICsgdGhpcy5lbWFpbFZlcmlmeVRva2VuVmFsaWRpdHlEdXJhdGlvbiAqIDEwMDApO1xuICB9XG5cbiAgZ2VuZXJhdGVQYXNzd29yZFJlc2V0VG9rZW5FeHBpcmVzQXQoKSB7XG4gICAgaWYgKCF0aGlzLnBhc3N3b3JkUG9saWN5IHx8ICF0aGlzLnBhc3N3b3JkUG9saWN5LnJlc2V0VG9rZW5WYWxpZGl0eUR1cmF0aW9uKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBjb25zdCBub3cgPSBuZXcgRGF0ZSgpO1xuICAgIHJldHVybiBuZXcgRGF0ZShub3cuZ2V0VGltZSgpICsgdGhpcy5wYXNzd29yZFBvbGljeS5yZXNldFRva2VuVmFsaWRpdHlEdXJhdGlvbiAqIDEwMDApO1xuICB9XG5cbiAgZ2VuZXJhdGVTZXNzaW9uRXhwaXJlc0F0KCkge1xuICAgIGlmICghdGhpcy5leHBpcmVJbmFjdGl2ZVNlc3Npb25zKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICB2YXIgbm93ID0gbmV3IERhdGUoKTtcbiAgICByZXR1cm4gbmV3IERhdGUobm93LmdldFRpbWUoKSArIHRoaXMuc2Vzc2lvbkxlbmd0aCAqIDEwMDApO1xuICB9XG5cbiAgdW5yZWdpc3RlclJhdGVMaW1pdGVycygpIHtcbiAgICBsZXQgaSA9IHRoaXMucmF0ZUxpbWl0cz8ubGVuZ3RoO1xuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIGNvbnN0IGxpbWl0ID0gdGhpcy5yYXRlTGltaXRzW2ldO1xuICAgICAgaWYgKGxpbWl0LmNsb3VkKSB7XG4gICAgICAgIHRoaXMucmF0ZUxpbWl0cy5zcGxpY2UoaSwgMSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0IGludmFsaWRMaW5rVVJMKCkge1xuICAgIHJldHVybiB0aGlzLmN1c3RvbVBhZ2VzLmludmFsaWRMaW5rIHx8IGAke3RoaXMucHVibGljU2VydmVyVVJMfS9hcHBzL2ludmFsaWRfbGluay5odG1sYDtcbiAgfVxuXG4gIGdldCBpbnZhbGlkVmVyaWZpY2F0aW9uTGlua1VSTCgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5jdXN0b21QYWdlcy5pbnZhbGlkVmVyaWZpY2F0aW9uTGluayB8fFxuICAgICAgYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9L2FwcHMvaW52YWxpZF92ZXJpZmljYXRpb25fbGluay5odG1sYFxuICAgICk7XG4gIH1cblxuICBnZXQgbGlua1NlbmRTdWNjZXNzVVJMKCkge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmN1c3RvbVBhZ2VzLmxpbmtTZW5kU3VjY2VzcyB8fCBgJHt0aGlzLnB1YmxpY1NlcnZlclVSTH0vYXBwcy9saW5rX3NlbmRfc3VjY2Vzcy5odG1sYFxuICAgICk7XG4gIH1cblxuICBnZXQgbGlua1NlbmRGYWlsVVJMKCkge1xuICAgIHJldHVybiB0aGlzLmN1c3RvbVBhZ2VzLmxpbmtTZW5kRmFpbCB8fCBgJHt0aGlzLnB1YmxpY1NlcnZlclVSTH0vYXBwcy9saW5rX3NlbmRfZmFpbC5odG1sYDtcbiAgfVxuXG4gIGdldCB2ZXJpZnlFbWFpbFN1Y2Nlc3NVUkwoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuY3VzdG9tUGFnZXMudmVyaWZ5RW1haWxTdWNjZXNzIHx8XG4gICAgICBgJHt0aGlzLnB1YmxpY1NlcnZlclVSTH0vYXBwcy92ZXJpZnlfZW1haWxfc3VjY2Vzcy5odG1sYFxuICAgICk7XG4gIH1cblxuICBnZXQgY2hvb3NlUGFzc3dvcmRVUkwoKSB7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tUGFnZXMuY2hvb3NlUGFzc3dvcmQgfHwgYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9L2FwcHMvY2hvb3NlX3Bhc3N3b3JkYDtcbiAgfVxuXG4gIGdldCByZXF1ZXN0UmVzZXRQYXNzd29yZFVSTCgpIHtcbiAgICByZXR1cm4gYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9LyR7dGhpcy5wYWdlc0VuZHBvaW50fS8ke3RoaXMuYXBwbGljYXRpb25JZH0vcmVxdWVzdF9wYXNzd29yZF9yZXNldGA7XG4gIH1cblxuICBnZXQgcGFzc3dvcmRSZXNldFN1Y2Nlc3NVUkwoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuY3VzdG9tUGFnZXMucGFzc3dvcmRSZXNldFN1Y2Nlc3MgfHxcbiAgICAgIGAke3RoaXMucHVibGljU2VydmVyVVJMfS9hcHBzL3Bhc3N3b3JkX3Jlc2V0X3N1Y2Nlc3MuaHRtbGBcbiAgICApO1xuICB9XG5cbiAgZ2V0IHBhcnNlRnJhbWVVUkwoKSB7XG4gICAgcmV0dXJuIHRoaXMuY3VzdG9tUGFnZXMucGFyc2VGcmFtZVVSTDtcbiAgfVxuXG4gIGdldCB2ZXJpZnlFbWFpbFVSTCgpIHtcbiAgICByZXR1cm4gYCR7dGhpcy5wdWJsaWNTZXJ2ZXJVUkx9LyR7dGhpcy5wYWdlc0VuZHBvaW50fS8ke3RoaXMuYXBwbGljYXRpb25JZH0vdmVyaWZ5X2VtYWlsYDtcbiAgfVxuXG4gIGFzeW5jIGxvYWRNYXN0ZXJLZXkoKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLm1hc3RlcktleSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29uc3QgdHRsSXNFbXB0eSA9ICF0aGlzLm1hc3RlcktleVR0bDtcbiAgICAgIGNvbnN0IGlzRXhwaXJlZCA9IHRoaXMubWFzdGVyS2V5Q2FjaGU/LmV4cGlyZXNBdCAmJiB0aGlzLm1hc3RlcktleUNhY2hlLmV4cGlyZXNBdCA8IG5ldyBEYXRlKCk7XG5cbiAgICAgIGlmICgoIWlzRXhwaXJlZCB8fCB0dGxJc0VtcHR5KSAmJiB0aGlzLm1hc3RlcktleUNhY2hlPy5tYXN0ZXJLZXkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFzdGVyS2V5Q2FjaGUubWFzdGVyS2V5O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBtYXN0ZXJLZXkgPSBhd2FpdCB0aGlzLm1hc3RlcktleSgpO1xuXG4gICAgICBjb25zdCBleHBpcmVzQXQgPSB0aGlzLm1hc3RlcktleVR0bCA/IG5ldyBEYXRlKERhdGUubm93KCkgKyAxMDAwICogdGhpcy5tYXN0ZXJLZXlUdGwpIDogbnVsbFxuICAgICAgdGhpcy5tYXN0ZXJLZXlDYWNoZSA9IHsgbWFzdGVyS2V5LCBleHBpcmVzQXQgfTtcbiAgICAgIENvbmZpZy5wdXQodGhpcyk7XG5cbiAgICAgIHJldHVybiB0aGlzLm1hc3RlcktleUNhY2hlLm1hc3RlcktleTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5tYXN0ZXJLZXk7XG4gIH1cblxuICAvLyBUT0RPOiBSZW1vdmUgdGhpcyBmdW5jdGlvbiBvbmNlIFBhZ2VzUm91dGVyIHJlcGxhY2VzIHRoZSBQdWJsaWNBUElSb3V0ZXI7XG4gIC8vIHRoZSAoZGVmYXVsdCkgZW5kcG9pbnQgaGFzIHRvIGJlIGRlZmluZWQgaW4gUGFnZXNSb3V0ZXIgb25seS5cbiAgZ2V0IHBhZ2VzRW5kcG9pbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMucGFnZXMgJiYgdGhpcy5wYWdlcy5lbmFibGVSb3V0ZXIgJiYgdGhpcy5wYWdlcy5wYWdlc0VuZHBvaW50XG4gICAgICA/IHRoaXMucGFnZXMucGFnZXNFbmRwb2ludFxuICAgICAgOiAnYXBwcyc7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQg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