parse-server 6.0.0-alpha.2 → 6.0.0-alpha.21

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 (191) hide show
  1. package/README.md +45 -17
  2. package/lib/AccountLockout.js +11 -26
  3. package/lib/Adapters/AdapterLoader.js +8 -14
  4. package/lib/Adapters/Analytics/AnalyticsAdapter.js +2 -8
  5. package/lib/Adapters/Auth/AuthAdapter.js +7 -16
  6. package/lib/Adapters/Auth/OAuth1Client.js +32 -57
  7. package/lib/Adapters/Auth/apple.js +6 -22
  8. package/lib/Adapters/Auth/facebook.js +7 -37
  9. package/lib/Adapters/Auth/gcenter.js +8 -37
  10. package/lib/Adapters/Auth/github.js +7 -10
  11. package/lib/Adapters/Auth/google.js +11 -34
  12. package/lib/Adapters/Auth/gpgames.js +5 -8
  13. package/lib/Adapters/Auth/httpsRequest.js +1 -7
  14. package/lib/Adapters/Auth/index.js +20 -65
  15. package/lib/Adapters/Auth/instagram.js +5 -9
  16. package/lib/Adapters/Auth/janraincapture.js +8 -12
  17. package/lib/Adapters/Auth/janrainengage.js +7 -11
  18. package/lib/Adapters/Auth/keycloak.js +5 -19
  19. package/lib/Adapters/Auth/ldap.js +1 -15
  20. package/lib/Adapters/Auth/line.js +7 -10
  21. package/lib/Adapters/Auth/linkedin.js +7 -12
  22. package/lib/Adapters/Auth/meetup.js +7 -10
  23. package/lib/Adapters/Auth/microsoft.js +7 -10
  24. package/lib/Adapters/Auth/oauth2.js +6 -18
  25. package/lib/Adapters/Auth/phantauth.js +8 -10
  26. package/lib/Adapters/Auth/qq.js +7 -13
  27. package/lib/Adapters/Auth/spotify.js +7 -14
  28. package/lib/Adapters/Auth/twitter.js +5 -15
  29. package/lib/Adapters/Auth/vkontakte.js +9 -15
  30. package/lib/Adapters/Auth/wechat.js +7 -10
  31. package/lib/Adapters/Auth/weibo.js +7 -11
  32. package/lib/Adapters/Cache/CacheAdapter.js +4 -12
  33. package/lib/Adapters/Cache/InMemoryCache.js +5 -19
  34. package/lib/Adapters/Cache/InMemoryCacheAdapter.js +1 -11
  35. package/lib/Adapters/Cache/LRUCache.js +1 -11
  36. package/lib/Adapters/Cache/NullCacheAdapter.js +1 -8
  37. package/lib/Adapters/Cache/RedisCacheAdapter.js +46 -87
  38. package/lib/Adapters/Cache/SchemaCache.js +1 -6
  39. package/lib/Adapters/Email/MailAdapter.js +2 -7
  40. package/lib/Adapters/Files/FilesAdapter.js +7 -21
  41. package/lib/Adapters/Files/GridFSBucketAdapter.js +6 -44
  42. package/lib/Adapters/Files/GridStoreAdapter.js +1 -1
  43. package/lib/Adapters/Logger/LoggerAdapter.js +2 -11
  44. package/lib/Adapters/Logger/WinstonLogger.js +3 -30
  45. package/lib/Adapters/Logger/WinstonLoggerAdapter.js +5 -16
  46. package/lib/Adapters/MessageQueue/EventEmitterMQ.js +3 -20
  47. package/lib/Adapters/PubSub/EventEmitterPubSub.js +1 -16
  48. package/lib/Adapters/PubSub/PubSubAdapter.js +2 -9
  49. package/lib/Adapters/PubSub/RedisPubSub.js +13 -10
  50. package/lib/Adapters/Push/PushAdapter.js +2 -8
  51. package/lib/Adapters/Storage/Mongo/MongoCollection.js +12 -37
  52. package/lib/Adapters/Storage/Mongo/MongoSchemaCollection.js +26 -79
  53. package/lib/Adapters/Storage/Mongo/MongoStorageAdapter.js +78 -209
  54. package/lib/Adapters/Storage/Mongo/MongoTransform.js +82 -371
  55. package/lib/Adapters/Storage/Postgres/PostgresClient.js +1 -13
  56. package/lib/Adapters/Storage/Postgres/PostgresConfigParser.js +1 -20
  57. package/lib/Adapters/Storage/Postgres/PostgresStorageAdapter.js +119 -446
  58. package/lib/Adapters/Storage/Postgres/sql/index.js +4 -7
  59. package/lib/Adapters/Storage/StorageAdapter.js +1 -1
  60. package/lib/Adapters/WebSocketServer/WSAdapter.js +3 -12
  61. package/lib/Adapters/WebSocketServer/WSSAdapter.js +7 -12
  62. package/lib/Auth.js +54 -121
  63. package/lib/ClientSDK.js +3 -11
  64. package/lib/Config.js +69 -113
  65. package/lib/Controllers/AdaptableController.js +6 -18
  66. package/lib/Controllers/AnalyticsController.js +1 -9
  67. package/lib/Controllers/CacheController.js +3 -23
  68. package/lib/Controllers/DatabaseController.js +147 -345
  69. package/lib/Controllers/FilesController.js +5 -34
  70. package/lib/Controllers/HooksController.js +1 -51
  71. package/lib/Controllers/LiveQueryController.js +4 -23
  72. package/lib/Controllers/LoggerController.js +15 -54
  73. package/lib/Controllers/ParseGraphQLController.js +49 -104
  74. package/lib/Controllers/PushController.js +20 -59
  75. package/lib/Controllers/SchemaController.js +154 -344
  76. package/lib/Controllers/UserController.js +11 -72
  77. package/lib/Controllers/index.js +19 -68
  78. package/lib/Controllers/types.js +1 -1
  79. package/lib/Deprecator/Deprecations.js +1 -8
  80. package/lib/Deprecator/Deprecator.js +9 -18
  81. package/lib/GraphQL/ParseGraphQLSchema.js +16 -100
  82. package/lib/GraphQL/ParseGraphQLServer.js +2 -29
  83. package/lib/GraphQL/helpers/objectsMutations.js +2 -12
  84. package/lib/GraphQL/helpers/objectsQueries.js +18 -76
  85. package/lib/GraphQL/loaders/defaultGraphQLMutations.js +1 -9
  86. package/lib/GraphQL/loaders/defaultGraphQLQueries.js +1 -8
  87. package/lib/GraphQL/loaders/defaultGraphQLTypes.js +9 -115
  88. package/lib/GraphQL/loaders/defaultRelaySchema.js +6 -18
  89. package/lib/GraphQL/loaders/filesMutations.js +2 -19
  90. package/lib/GraphQL/loaders/functionsMutations.js +6 -17
  91. package/lib/GraphQL/loaders/parseClassMutations.js +6 -44
  92. package/lib/GraphQL/loaders/parseClassQueries.js +1 -26
  93. package/lib/GraphQL/loaders/parseClassTypes.js +10 -64
  94. package/lib/GraphQL/loaders/schemaDirectives.js +1 -17
  95. package/lib/GraphQL/loaders/schemaMutations.js +1 -20
  96. package/lib/GraphQL/loaders/schemaQueries.js +1 -14
  97. package/lib/GraphQL/loaders/schemaTypes.js +2 -6
  98. package/lib/GraphQL/loaders/usersMutations.js +6 -28
  99. package/lib/GraphQL/loaders/usersQueries.js +4 -26
  100. package/lib/GraphQL/parseGraphQLUtils.js +6 -19
  101. package/lib/GraphQL/transformers/className.js +1 -4
  102. package/lib/GraphQL/transformers/constraintType.js +1 -20
  103. package/lib/GraphQL/transformers/inputType.js +1 -20
  104. package/lib/GraphQL/transformers/mutation.js +6 -51
  105. package/lib/GraphQL/transformers/outputType.js +1 -20
  106. package/lib/GraphQL/transformers/query.js +6 -42
  107. package/lib/GraphQL/transformers/schemaFields.js +7 -34
  108. package/lib/KeyPromiseQueue.js +1 -12
  109. package/lib/LiveQuery/Client.js +1 -25
  110. package/lib/LiveQuery/Id.js +1 -7
  111. package/lib/LiveQuery/ParseCloudCodePublisher.js +13 -19
  112. package/lib/LiveQuery/ParseLiveQueryServer.js +92 -306
  113. package/lib/LiveQuery/ParsePubSub.js +1 -12
  114. package/lib/LiveQuery/ParseWebSocketServer.js +4 -26
  115. package/lib/LiveQuery/QueryTools.js +14 -116
  116. package/lib/LiveQuery/RequestSchema.js +1 -1
  117. package/lib/LiveQuery/SessionTokenCache.js +1 -17
  118. package/lib/LiveQuery/Subscription.js +4 -18
  119. package/lib/LiveQuery/equalObjects.js +2 -14
  120. package/lib/Options/Definitions.js +79 -10
  121. package/lib/Options/docs.js +23 -3
  122. package/lib/Options/index.js +4 -12
  123. package/lib/Options/parsers.js +1 -18
  124. package/lib/Page.js +1 -9
  125. package/lib/ParseMessageQueue.js +1 -10
  126. package/lib/ParseServer.js +144 -182
  127. package/lib/ParseServerRESTController.js +6 -33
  128. package/lib/PromiseRouter.js +16 -50
  129. package/lib/Push/PushQueue.js +3 -15
  130. package/lib/Push/PushWorker.js +7 -32
  131. package/lib/Push/utils.js +9 -38
  132. package/lib/RestQuery.js +105 -242
  133. package/lib/RestWrite.js +212 -377
  134. package/lib/Routers/AggregateRouter.js +14 -51
  135. package/lib/Routers/AnalyticsRouter.js +2 -8
  136. package/lib/Routers/AudiencesRouter.js +1 -15
  137. package/lib/Routers/ClassesRouter.js +3 -53
  138. package/lib/Routers/CloudCodeRouter.js +1 -19
  139. package/lib/Routers/FeaturesRouter.js +1 -10
  140. package/lib/Routers/FilesRouter.js +29 -76
  141. package/lib/Routers/FunctionsRouter.js +5 -28
  142. package/lib/Routers/GlobalConfigRouter.js +4 -18
  143. package/lib/Routers/GraphQLRouter.js +1 -14
  144. package/lib/Routers/HooksRouter.js +1 -29
  145. package/lib/Routers/IAPValidationRouter.js +6 -29
  146. package/lib/Routers/InstallationsRouter.js +2 -12
  147. package/lib/Routers/LogsRouter.js +4 -16
  148. package/lib/Routers/PagesRouter.js +69 -129
  149. package/lib/Routers/PublicAPIRouter.js +3 -62
  150. package/lib/Routers/PurgeRouter.js +1 -15
  151. package/lib/Routers/PushRouter.js +2 -18
  152. package/lib/Routers/RolesRouter.js +1 -7
  153. package/lib/Routers/SchemasRouter.js +4 -34
  154. package/lib/Routers/SecurityRouter.js +1 -12
  155. package/lib/Routers/SessionsRouter.js +3 -19
  156. package/lib/Routers/UsersRouter.js +58 -155
  157. package/lib/SchemaMigrations/DefinedSchemas.js +56 -115
  158. package/lib/SchemaMigrations/Migrations.js +2 -8
  159. package/lib/Security/Check.js +8 -16
  160. package/lib/Security/CheckGroup.js +4 -11
  161. package/lib/Security/CheckGroups/CheckGroupDatabase.js +8 -18
  162. package/lib/Security/CheckGroups/CheckGroupServerConfig.js +5 -15
  163. package/lib/Security/CheckGroups/CheckGroups.js +1 -4
  164. package/lib/Security/CheckRunner.js +22 -41
  165. package/lib/StatusHandler.js +12 -69
  166. package/lib/TestUtils.js +1 -6
  167. package/lib/Utils.js +27 -66
  168. package/lib/batch.js +17 -28
  169. package/lib/cache.js +1 -3
  170. package/lib/cli/definitions/parse-live-query-server.js +1 -3
  171. package/lib/cli/definitions/parse-server.js +1 -3
  172. package/lib/cli/parse-live-query-server.js +1 -6
  173. package/lib/cli/parse-server.js +11 -21
  174. package/lib/cli/utils/commander.js +13 -51
  175. package/lib/cli/utils/runner.js +1 -14
  176. package/lib/cloud-code/Parse.Cloud.js +71 -92
  177. package/lib/cryptoUtils.js +11 -19
  178. package/lib/defaults.js +2 -14
  179. package/lib/deprecated.js +1 -2
  180. package/lib/index.js +16 -34
  181. package/lib/logger.js +6 -13
  182. package/lib/middlewares.js +147 -151
  183. package/lib/password.js +6 -10
  184. package/lib/request.js +173 -2
  185. package/lib/requiredParameter.js +1 -3
  186. package/lib/rest.js +19 -41
  187. package/lib/triggers.js +54 -252
  188. package/lib/vendor/mongodbUrl.js +125 -305
  189. package/package.json +22 -19
  190. package/lib/cloud-code/HTTPResponse.js +0 -73
  191. package/lib/cloud-code/httpRequest.js +0 -192
@@ -3,16 +3,11 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = exports.LoggerController = exports.LogOrder = exports.LogLevel = void 0;
7
-
6
+ exports.logLevels = exports.default = exports.LoggerController = exports.LogOrder = exports.LogLevel = void 0;
8
7
  var _node = require("parse/node");
9
-
10
8
  var _AdaptableController = _interopRequireDefault(require("./AdaptableController"));
11
-
12
9
  var _LoggerAdapter = require("../Adapters/Logger/LoggerAdapter");
13
-
14
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
-
16
11
  const MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000;
17
12
  const LOG_STRING_TRUNCATE_LENGTH = 1000;
18
13
  const truncationMarker = '... (truncated)';
@@ -27,24 +22,20 @@ const LogOrder = {
27
22
  };
28
23
  exports.LogOrder = LogOrder;
29
24
  const logLevels = ['error', 'warn', 'info', 'debug', 'verbose', 'silly'];
30
-
25
+ exports.logLevels = logLevels;
31
26
  class LoggerController extends _AdaptableController.default {
32
27
  constructor(adapter, appId, options = {
33
28
  logLevel: 'info'
34
29
  }) {
35
30
  super(adapter, appId, options);
36
31
  let level = 'info';
37
-
38
32
  if (options.verbose) {
39
33
  level = 'verbose';
40
34
  }
41
-
42
35
  if (options.logLevel) {
43
36
  level = options.logLevel;
44
37
  }
45
-
46
38
  const index = logLevels.indexOf(level); // info by default
47
-
48
39
  logLevels.forEach((level, levelIndex) => {
49
40
  if (levelIndex > index) {
50
41
  // silence the levels that are > maxIndex
@@ -52,14 +43,11 @@ class LoggerController extends _AdaptableController.default {
52
43
  }
53
44
  });
54
45
  }
55
-
56
46
  maskSensitiveUrl(path) {
57
47
  const urlString = 'http://localhost' + path; // prepend dummy string to make a real URL
58
-
59
48
  const urlObj = new URL(urlString);
60
49
  const query = urlObj.searchParams;
61
50
  let sanitizedQuery = '?';
62
-
63
51
  for (const [key, value] of query) {
64
52
  if (key !== 'password') {
65
53
  // normal value
@@ -68,26 +56,25 @@ class LoggerController extends _AdaptableController.default {
68
56
  // password value, redact it
69
57
  sanitizedQuery += key + '=' + '********' + '&';
70
58
  }
71
- } // trim last character, ? or &
72
-
59
+ }
73
60
 
74
- sanitizedQuery = sanitizedQuery.slice(0, -1); // return original path name with sanitized params attached
61
+ // trim last character, ? or &
62
+ sanitizedQuery = sanitizedQuery.slice(0, -1);
75
63
 
64
+ // return original path name with sanitized params attached
76
65
  return urlObj.pathname + sanitizedQuery;
77
66
  }
78
-
79
67
  maskSensitive(argArray) {
80
68
  return argArray.map(e => {
81
69
  if (!e) {
82
70
  return e;
83
71
  }
84
-
85
72
  if (typeof e === 'string') {
86
73
  return e.replace(/(password".?:.?")[^"]*"/g, '$1********"');
87
- } // else it is an object...
88
- // check the url
89
-
74
+ }
75
+ // else it is an object...
90
76
 
77
+ // check the url
91
78
  if (e.url) {
92
79
  // for strings
93
80
  if (typeof e.url === 'string') {
@@ -98,12 +85,10 @@ class LoggerController extends _AdaptableController.default {
98
85
  if (typeof item === 'string') {
99
86
  return this.maskSensitiveUrl(item);
100
87
  }
101
-
102
88
  return item;
103
89
  });
104
90
  }
105
91
  }
106
-
107
92
  if (e.body) {
108
93
  for (const key of Object.keys(e.body)) {
109
94
  if (key === 'password') {
@@ -112,7 +97,6 @@ class LoggerController extends _AdaptableController.default {
112
97
  }
113
98
  }
114
99
  }
115
-
116
100
  if (e.params) {
117
101
  for (const key of Object.keys(e.params)) {
118
102
  if (key === 'password') {
@@ -121,11 +105,9 @@ class LoggerController extends _AdaptableController.default {
121
105
  }
122
106
  }
123
107
  }
124
-
125
108
  return e;
126
109
  });
127
110
  }
128
-
129
111
  log(level, args) {
130
112
  // make the passed in arguments object an array with the spread operator
131
113
  args = this.maskSensitive([...args]);
@@ -133,36 +115,28 @@ class LoggerController extends _AdaptableController.default {
133
115
  if (typeof arg === 'function') {
134
116
  return arg();
135
117
  }
136
-
137
118
  return arg;
138
119
  }));
139
120
  this.adapter.log.apply(this.adapter, args);
140
121
  }
141
-
142
122
  info() {
143
123
  return this.log('info', arguments);
144
124
  }
145
-
146
125
  error() {
147
126
  return this.log('error', arguments);
148
127
  }
149
-
150
128
  warn() {
151
129
  return this.log('warn', arguments);
152
130
  }
153
-
154
131
  verbose() {
155
132
  return this.log('verbose', arguments);
156
133
  }
157
-
158
134
  debug() {
159
135
  return this.log('debug', arguments);
160
136
  }
161
-
162
137
  silly() {
163
138
  return this.log('silly', arguments);
164
139
  }
165
-
166
140
  logRequest({
167
141
  method,
168
142
  url,
@@ -179,7 +153,6 @@ class LoggerController extends _AdaptableController.default {
179
153
  body
180
154
  });
181
155
  }
182
-
183
156
  logResponse({
184
157
  method,
185
158
  url,
@@ -191,32 +164,25 @@ class LoggerController extends _AdaptableController.default {
191
164
  }, {
192
165
  result: result
193
166
  });
194
- } // check that date input is valid
195
-
196
-
167
+ }
168
+ // check that date input is valid
197
169
  static validDateTime(date) {
198
170
  if (!date) {
199
171
  return null;
200
172
  }
201
-
202
173
  date = new Date(date);
203
-
204
174
  if (!isNaN(date.getTime())) {
205
175
  return date;
206
176
  }
207
-
208
177
  return null;
209
178
  }
210
-
211
179
  truncateLogMessage(string) {
212
180
  if (string && string.length > LOG_STRING_TRUNCATE_LENGTH) {
213
181
  const truncated = string.substring(0, LOG_STRING_TRUNCATE_LENGTH) + truncationMarker;
214
182
  return truncated;
215
183
  }
216
-
217
184
  return string;
218
185
  }
219
-
220
186
  static parseOptions(options = {}) {
221
187
  const from = LoggerController.validDateTime(options.from) || new Date(Date.now() - 7 * MILLISECONDS_IN_A_DAY);
222
188
  const until = LoggerController.validDateTime(options.until) || new Date();
@@ -230,35 +196,30 @@ class LoggerController extends _AdaptableController.default {
230
196
  order,
231
197
  level
232
198
  };
233
- } // Returns a promise for a {response} object.
199
+ }
200
+
201
+ // Returns a promise for a {response} object.
234
202
  // query params:
235
203
  // level (optional) Level of logging you want to query for (info || error)
236
204
  // from (optional) Start time for the search. Defaults to 1 week ago.
237
205
  // until (optional) End time for the search. Defaults to current time.
238
206
  // order (optional) Direction of results returned, either “asc” or “desc”. Defaults to “desc”.
239
207
  // size (optional) Number of rows returned by search. Defaults to 10
240
-
241
-
242
208
  getLogs(options = {}) {
243
209
  if (!this.adapter) {
244
210
  throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Logger adapter is not available');
245
211
  }
246
-
247
212
  if (typeof this.adapter.query !== 'function') {
248
213
  throw new _node.Parse.Error(_node.Parse.Error.PUSH_MISCONFIGURED, 'Querying logs is not supported with this adapter');
249
214
  }
250
-
251
215
  options = LoggerController.parseOptions(options);
252
216
  return this.adapter.query(options);
253
217
  }
254
-
255
218
  expectedAdapterType() {
256
219
  return _LoggerAdapter.LoggerAdapter;
257
220
  }
258
-
259
221
  }
260
-
261
222
  exports.LoggerController = LoggerController;
262
223
  var _default = LoggerController;
263
224
  exports.default = _default;
264
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Db250cm9sbGVycy9Mb2dnZXJDb250cm9sbGVyLmpzIl0sIm5hbWVzIjpbIk1JTExJU0VDT05EU19JTl9BX0RBWSIsIkxPR19TVFJJTkdfVFJVTkNBVEVfTEVOR1RIIiwidHJ1bmNhdGlvbk1hcmtlciIsIkxvZ0xldmVsIiwiSU5GTyIsIkVSUk9SIiwiTG9nT3JkZXIiLCJERVNDRU5ESU5HIiwiQVNDRU5ESU5HIiwibG9nTGV2ZWxzIiwiTG9nZ2VyQ29udHJvbGxlciIsIkFkYXB0YWJsZUNvbnRyb2xsZXIiLCJjb25zdHJ1Y3RvciIsImFkYXB0ZXIiLCJhcHBJZCIsIm9wdGlvbnMiLCJsb2dMZXZlbCIsImxldmVsIiwidmVyYm9zZSIsImluZGV4IiwiaW5kZXhPZiIsImZvckVhY2giLCJsZXZlbEluZGV4IiwibWFza1NlbnNpdGl2ZVVybCIsInBhdGgiLCJ1cmxTdHJpbmciLCJ1cmxPYmoiLCJVUkwiLCJxdWVyeSIsInNlYXJjaFBhcmFtcyIsInNhbml0aXplZFF1ZXJ5Iiwia2V5IiwidmFsdWUiLCJzbGljZSIsInBhdGhuYW1lIiwibWFza1NlbnNpdGl2ZSIsImFyZ0FycmF5IiwibWFwIiwiZSIsInJlcGxhY2UiLCJ1cmwiLCJBcnJheSIsImlzQXJyYXkiLCJpdGVtIiwiYm9keSIsIk9iamVjdCIsImtleXMiLCJwYXJhbXMiLCJsb2ciLCJhcmdzIiwiY29uY2F0IiwiYXJnIiwiYXBwbHkiLCJpbmZvIiwiYXJndW1lbnRzIiwiZXJyb3IiLCJ3YXJuIiwiZGVidWciLCJzaWxseSIsImxvZ1JlcXVlc3QiLCJtZXRob2QiLCJoZWFkZXJzIiwic3RyaW5naWZpZWRCb2R5IiwiSlNPTiIsInN0cmluZ2lmeSIsImxvZ1Jlc3BvbnNlIiwicmVzdWx0Iiwic3RyaW5naWZpZWRSZXNwb25zZSIsInZhbGlkRGF0ZVRpbWUiLCJkYXRlIiwiRGF0ZSIsImlzTmFOIiwiZ2V0VGltZSIsInRydW5jYXRlTG9nTWVzc2FnZSIsInN0cmluZyIsImxlbmd0aCIsInRydW5jYXRlZCIsInN1YnN0cmluZyIsInBhcnNlT3B0aW9ucyIsImZyb20iLCJub3ciLCJ1bnRpbCIsInNpemUiLCJOdW1iZXIiLCJvcmRlciIsImdldExvZ3MiLCJQYXJzZSIsIkVycm9yIiwiUFVTSF9NSVNDT05GSUdVUkVEIiwiZXhwZWN0ZWRBZGFwdGVyVHlwZSIsIkxvZ2dlckFkYXB0ZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7OztBQUVBLE1BQU1BLHFCQUFxQixHQUFHLEtBQUssRUFBTCxHQUFVLEVBQVYsR0FBZSxJQUE3QztBQUNBLE1BQU1DLDBCQUEwQixHQUFHLElBQW5DO0FBQ0EsTUFBTUMsZ0JBQWdCLEdBQUcsaUJBQXpCO0FBRU8sTUFBTUMsUUFBUSxHQUFHO0FBQ3RCQyxFQUFBQSxJQUFJLEVBQUUsTUFEZ0I7QUFFdEJDLEVBQUFBLEtBQUssRUFBRTtBQUZlLENBQWpCOztBQUtBLE1BQU1DLFFBQVEsR0FBRztBQUN0QkMsRUFBQUEsVUFBVSxFQUFFLE1BRFU7QUFFdEJDLEVBQUFBLFNBQVMsRUFBRTtBQUZXLENBQWpCOztBQUtQLE1BQU1DLFNBQVMsR0FBRyxDQUFDLE9BQUQsRUFBVSxNQUFWLEVBQWtCLE1BQWxCLEVBQTBCLE9BQTFCLEVBQW1DLFNBQW5DLEVBQThDLE9BQTlDLENBQWxCOztBQUVPLE1BQU1DLGdCQUFOLFNBQStCQyw0QkFBL0IsQ0FBbUQ7QUFDeERDLEVBQUFBLFdBQVcsQ0FBQ0MsT0FBRCxFQUFVQyxLQUFWLEVBQWlCQyxPQUFPLEdBQUc7QUFBRUMsSUFBQUEsUUFBUSxFQUFFO0FBQVosR0FBM0IsRUFBaUQ7QUFDMUQsVUFBTUgsT0FBTixFQUFlQyxLQUFmLEVBQXNCQyxPQUF0QjtBQUNBLFFBQUlFLEtBQUssR0FBRyxNQUFaOztBQUNBLFFBQUlGLE9BQU8sQ0FBQ0csT0FBWixFQUFxQjtBQUNuQkQsTUFBQUEsS0FBSyxHQUFHLFNBQVI7QUFDRDs7QUFDRCxRQUFJRixPQUFPLENBQUNDLFFBQVosRUFBc0I7QUFDcEJDLE1BQUFB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QUNMMkUsTUFBQUEsSUFESztBQUVMRSxNQUFBQSxLQUZLO0FBR0xDLE1BQUFBLElBSEs7QUFJTEUsTUFBQUEsS0FKSztBQUtMbkUsTUFBQUE7QUFMSyxLQUFQO0FBT0QsR0FsTXVELENBb014RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0FvRSxFQUFBQSxPQUFPLENBQUN0RSxPQUFPLEdBQUcsRUFBWCxFQUFlO0FBQ3BCLFFBQUksQ0FBQyxLQUFLRixPQUFWLEVBQW1CO0FBQ2pCLFlBQU0sSUFBSXlFLFlBQU1DLEtBQVYsQ0FBZ0JELFlBQU1DLEtBQU4sQ0FBWUMsa0JBQTVCLEVBQWdELGlDQUFoRCxDQUFOO0FBQ0Q7O0FBQ0QsUUFBSSxPQUFPLEtBQUszRSxPQUFMLENBQWFlLEtBQXBCLEtBQThCLFVBQWxDLEVBQThDO0FBQzVDLFlBQU0sSUFBSTBELFlBQU1DLEtBQVYsQ0FDSkQsWUFBTUMsS0FBTixDQUFZQyxrQkFEUixFQUVKLGtEQUZJLENBQU47QUFJRDs7QUFDRHpFLElBQUFBLE9BQU8sR0FBR0wsZ0JBQWdCLENBQUNvRSxZQUFqQixDQUE4Qi9ELE9BQTlCLENBQVY7QUFDQSxXQUFPLEtBQUtGLE9BQUwsQ0FBYWUsS0FBYixDQUFtQmIsT0FBbkIsQ0FBUDtBQUNEOztBQUVEMEUsRUFBQUEsbUJBQW1CLEdBQUc7QUFDcEIsV0FBT0MsNEJBQVA7QUFDRDs7QUEzTnVEOzs7ZUE4TjNDaEYsZ0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBQYXJzZSB9IGZyb20gJ3BhcnNlL25vZGUnO1xuaW1wb3J0IEFkYXB0YWJsZUNvbnRyb2xsZXIgZnJvbSAnLi9BZGFwdGFibGVDb250cm9sbGVyJztcbmltcG9ydCB7IExvZ2dlckFkYXB0ZXIgfSBmcm9tICcuLi9BZGFwdGVycy9Mb2dnZXIvTG9nZ2VyQWRhcHRlcic7XG5cbmNvbnN0IE1JTExJU0VDT05EU19JTl9BX0RBWSA9IDI0ICogNjAgKiA2MCAqIDEwMDA7XG5jb25zdCBMT0dfU1RSSU5HX1RSVU5DQVRFX0xFTkdUSCA9IDEwMDA7XG5jb25zdCB0cnVuY2F0aW9uTWFya2VyID0gJy4uLiAodHJ1bmNhdGVkKSc7XG5cbmV4cG9ydCBjb25zdCBMb2dMZXZlbCA9IHtcbiAgSU5GTzogJ2luZm8nLFxuICBFUlJPUjogJ2Vycm9yJyxcbn07XG5cbmV4cG9ydCBjb25zdCBMb2dPcmRlciA9IHtcbiAgREVTQ0VORElORzogJ2Rlc2MnLFxuICBBU0NFTkRJTkc6ICdhc2MnLFxufTtcblxuY29uc3QgbG9nTGV2ZWxzID0gWydlcnJvcicsICd3YXJuJywgJ2luZm8nLCAnZGVidWcnLCAndmVyYm9zZScsICdzaWxseSddO1xuXG5leHBvcnQgY2xhc3MgTG9nZ2VyQ29udHJvbGxlciBleHRlbmRzIEFkYXB0YWJsZUNvbnRyb2xsZXIge1xuICBjb25zdHJ1Y3RvcihhZGFwdGVyLCBhcHBJZCwgb3B0aW9ucyA9IHsgbG9nTGV2ZWw6ICdpbmZvJyB9KSB7XG4gICAgc3VwZXIoYWRhcHRlciwgYXBwSWQsIG9wdGlvbnMpO1xuICAgIGxldCBsZXZlbCA9ICdpbmZvJztcbiAgICBpZiAob3B0aW9ucy52ZXJib3NlKSB7XG4gICAgICBsZXZlbCA9ICd2ZXJib3NlJztcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMubG9nTGV2ZWwpIHtcbiAgICAgIGxldmVsID0gb3B0aW9ucy5sb2dMZXZlbDtcbiAgICB9XG4gICAgY29uc3QgaW5kZXggPSBsb2dMZXZlbHMuaW5kZXhPZihsZXZlbCk7IC8vIGluZm8gYnkgZGVmYXVsdFxuICAgIGxvZ0xldmVscy5mb3JFYWNoKChsZXZlbCwgbGV2ZWxJbmRleCkgPT4ge1xuICAgICAgaWYgKGxldmVsSW5kZXggPiBpbmRleCkge1xuICAgICAgICAvLyBzaWxlbmNlIHRoZSBsZXZlbHMgdGhhdCBhcmUgPiBtYXhJbmRleFxuICAgICAgICB0aGlzW2xldmVsXSA9ICgpID0+IHt9O1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgbWFza1NlbnNpdGl2ZVVybChwYXRoKSB7XG4gICAgY29uc3QgdXJsU3RyaW5nID0gJ2h0dHA6Ly9sb2NhbGhvc3QnICsgcGF0aDsgLy8gcHJlcGVuZCBkdW1teSBzdHJpbmcgdG8gbWFrZSBhIHJlYWwgVVJMXG4gICAgY29uc3QgdXJsT2JqID0gbmV3IFVSTCh1cmxTdHJpbmcpO1xuICAgIGNvbnN0IHF1ZXJ5ID0gdXJsT2JqLnNlYXJjaFBhcmFtcztcbiAgICBsZXQgc2FuaXRpemVkUXVlcnkgPSAnPyc7XG5cbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBxdWVyeSkge1xuICAgICAgaWYgKGtleSAhPT0gJ3Bhc3N3b3JkJykge1xuICAgICAgICAvLyBub3JtYWwgdmFsdWVcbiAgICAgICAgc2FuaXRpemVkUXVlcnkgKz0ga2V5ICsgJz0nICsgdmFsdWUgKyAnJic7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBwYXNzd29yZCB2YWx1ZSwgcmVkYWN0IGl0XG4gICAgICAgIHNhbml0aXplZFF1ZXJ5ICs9IGtleSArICc9JyArICcqKioqKioqKicgKyAnJic7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdHJpbSBsYXN0IGNoYXJhY3RlciwgPyBvciAmXG4gICAgc2FuaXRpemVkUXVlcnkgPSBzYW5pdGl6ZWRRdWVyeS5zbGljZSgwLCAtMSk7XG5cbiAgICAvLyByZXR1cm4gb3JpZ2luYWwgcGF0aCBuYW1lIHdpdGggc2FuaXRpemVkIHBhcmFtcyBhdHRhY2hlZFxuICAgIHJldHVybiB1cmxPYmoucGF0aG5hbWUgKyBzYW5pdGl6ZWRRdWVyeTtcbiAgfVxuXG4gIG1hc2tTZW5zaXRpdmUoYXJnQXJyYXkpIHtcbiAgICByZXR1cm4gYXJnQXJyYXkubWFwKGUgPT4ge1xuICAgICAgaWYgKCFlKSB7XG4gICAgICAgIHJldHVybiBlO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBlLnJlcGxhY2UoLyhwYXNzd29yZFwiLj86Lj9cIilbXlwiXSpcIi9nLCAnJDEqKioqKioqKlwiJyk7XG4gICAgICB9XG4gICAgICAvLyBlbHNlIGl0IGlzIGFuIG9iamVjdC4uLlxuXG4gICAgICAvLyBjaGVjayB0aGUgdXJsXG4gICAgICBpZiAoZS51cmwpIHtcbiAgICAgICAgLy8gZm9yIHN0cmluZ3NcbiAgICAgICAgaWYgKHR5cGVvZiBlLnVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBlLnVybCA9IHRoaXMubWFza1NlbnNpdGl2ZVVybChlLnVybCk7XG4gICAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShlLnVybCkpIHtcbiAgICAgICAgICAvLyBmb3Igc3RyaW5ncyBpbiBhcnJheVxuICAgICAgICAgIGUudXJsID0gZS51cmwubWFwKGl0ZW0gPT4ge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBpdGVtID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5tYXNrU2Vuc2l0aXZlVXJsKGl0ZW0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gaXRlbTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZS5ib2R5KSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGUuYm9keSkpIHtcbiAgICAgICAgICBpZiAoa2V5ID09PSAncGFzc3dvcmQnKSB7XG4gICAgICAgICAgICBlLmJvZHlba2V5XSA9ICcqKioqKioqKic7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGUucGFyYW1zKSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGUucGFyYW1zKSkge1xuICAgICAgICAgIGlmIChrZXkgPT09ICdwYXNzd29yZCcpIHtcbiAgICAgICAgICAgIGUucGFyYW1zW2tleV0gPSAnKioqKioqKionO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBlO1xuICAgIH0pO1xuICB9XG5cbiAgbG9nKGxldmVsLCBhcmdzKSB7XG4gICAgLy8gbWFrZSB0aGUgcGFzc2VkIGluIGFyZ3VtZW50cyBvYmplY3QgYW4gYXJyYXkgd2l0aCB0aGUgc3ByZWFkIG9wZXJhdG9yXG4gICAgYXJncyA9IHRoaXMubWFza1NlbnNpdGl2ZShbLi4uYXJnc10pO1xuICAgIGFyZ3MgPSBbXS5jb25jYXQoXG4gICAgICBsZXZlbCxcbiAgICAgIGFyZ3MubWFwKGFyZyA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgcmV0dXJuIGFyZygpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhcmc7XG4gICAgICB9KVxuICAgICk7XG4gICAgdGhpcy5hZGFwdGVyLmxvZy5hcHBseSh0aGlzLmFkYXB0ZXIsIGFyZ3MpO1xuICB9XG5cbiAgaW5mbygpIHtcbiAgICByZXR1cm4gdGhpcy5sb2coJ2luZm8nLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgZXJyb3IoKSB7XG4gICAgcmV0dXJuIHRoaXMubG9nKCdlcnJvcicsIGFyZ3VtZW50cyk7XG4gIH1cblxuICB3YXJuKCkge1xuICAgIHJldHVybiB0aGlzLmxvZygnd2FybicsIGFyZ3VtZW50cyk7XG4gIH1cblxuICB2ZXJib3NlKCkge1xuICAgIHJldHVybiB0aGlzLmxvZygndmVyYm9zZScsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBkZWJ1ZygpIHtcbiAgICByZXR1cm4gdGhpcy5sb2coJ2RlYnVnJywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIHNpbGx5KCkge1xuICAgIHJldHVybiB0aGlzLmxvZygnc2lsbHknLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgbG9nUmVxdWVzdCh7IG1ldGhvZCwgdXJsLCBoZWFkZXJzLCBib2R5IH0pIHtcbiAgICB0aGlzLnZlcmJvc2UoXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHN0cmluZ2lmaWVkQm9keSA9IEpTT04uc3RyaW5naWZ5KGJvZHksIG51bGwsIDIpO1xuICAgICAgICByZXR1cm4gYFJFUVVFU1QgZm9yIFske21ldGhvZH1dICR7dXJsfTogJHtzdHJpbmdpZmllZEJvZHl9YDtcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG1ldGhvZCxcbiAgICAgICAgdXJsLFxuICAgICAgICBoZWFkZXJzLFxuICAgICAgICBib2R5LFxuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBsb2dSZXNwb25zZSh7IG1ldGhvZCwgdXJsLCByZXN1bHQgfSkge1xuICAgIHRoaXMudmVyYm9zZShcbiAgICAgICgpID0+IHtcbiAgICAgICAgY29uc3Qgc3RyaW5naWZpZWRSZXNwb25zZSA9IEpTT04uc3RyaW5naWZ5KHJlc3VsdCwgbnVsbCwgMik7XG4gICAgICAgIHJldHVybiBgUkVTUE9OU0UgZnJvbSBbJHttZXRob2R9XSAke3VybH06ICR7c3RyaW5naWZpZWRSZXNwb25zZX1gO1xuICAgICAgfSxcbiAgICAgIHsgcmVzdWx0OiByZXN1bHQgfVxuICAgICk7XG4gIH1cbiAgLy8gY2hlY2sgdGhhdCBkYXRlIGlucHV0IGlzIHZhbGlkXG4gIHN0YXRpYyB2YWxpZERhdGVUaW1lKGRhdGUpIHtcbiAgICBpZiAoIWRhdGUpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBkYXRlID0gbmV3IERhdGUoZGF0ZSk7XG5cbiAgICBpZiAoIWlzTmFOKGRhdGUuZ2V0VGltZSgpKSkge1xuICAgICAgcmV0dXJuIGRhdGU7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB0cnVuY2F0ZUxvZ01lc3NhZ2Uoc3RyaW5nKSB7XG4gICAgaWYgKHN0cmluZyAmJiBzdHJpbmcubGVuZ3RoID4gTE9HX1NUUklOR19UUlVOQ0FURV9MRU5HVEgpIHtcbiAgICAgIGNvbnN0IHRydW5jYXRlZCA9IHN0cmluZy5zdWJzdHJpbmcoMCwgTE9HX1NUUklOR19UUlVOQ0FURV9MRU5HVEgpICsgdHJ1bmNhdGlvbk1hcmtlcjtcbiAgICAgIHJldHVybiB0cnVuY2F0ZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0cmluZztcbiAgfVxuXG4gIHN0YXRpYyBwYXJzZU9wdGlvbnMob3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgZnJvbSA9XG4gICAgICBMb2dnZXJDb250cm9sbGVyLnZhbGlkRGF0ZVRpbWUob3B0aW9ucy5mcm9tKSB8fFxuICAgICAgbmV3IERhdGUoRGF0ZS5ub3coKSAtIDcgKiBNSUxMSVNFQ09ORFNfSU5fQV9EQVkpO1xuICAgIGNvbnN0IHVudGlsID0gTG9nZ2VyQ29udHJvbGxlci52YWxpZERhdGVUaW1lKG9wdGlvbnMudW50aWwpIHx8IG5ldyBEYXRlKCk7XG4gICAgY29uc3Qgc2l6ZSA9IE51bWJlcihvcHRpb25zLnNpemUpIHx8IDEwO1xuICAgIGNvbnN0IG9yZGVyID0gb3B0aW9ucy5vcmRlciB8fCBMb2dPcmRlci5ERVNDRU5ESU5HO1xuICAgIGNvbnN0IGxldmVsID0gb3B0aW9ucy5sZXZlbCB8fCBMb2dMZXZlbC5JTkZPO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGZyb20sXG4gICAgICB1bnRpbCxcbiAgICAgIHNpemUsXG4gICAgICBvcmRlcixcbiAgICAgIGxldmVsLFxuICAgIH07XG4gIH1cblxuICAvLyBSZXR1cm5zIGEgcHJvbWlzZSBmb3IgYSB7cmVzcG9uc2V9IG9iamVjdC5cbiAgLy8gcXVlcnkgcGFyYW1zOlxuICAvLyBsZXZlbCAob3B0aW9uYWwpIExldmVsIG9mIGxvZ2dpbmcgeW91IHdhbnQgdG8gcXVlcnkgZm9yIChpbmZvIHx8IGVycm9yKVxuICAvLyBmcm9tIChvcHRpb25hbCkgU3RhcnQgdGltZSBmb3IgdGhlIHNlYXJjaC4gRGVmYXVsdHMgdG8gMSB3ZWVrIGFnby5cbiAgLy8gdW50aWwgKG9wdGlvbmFsKSBFbmQgdGltZSBmb3IgdGhlIHNlYXJjaC4gRGVmYXVsdHMgdG8gY3VycmVudCB0aW1lLlxuICAvLyBvcmRlciAob3B0aW9uYWwpIERpcmVjdGlvbiBvZiByZXN1bHRzIHJldHVybmVkLCBlaXRoZXIg4oCcYXNj4oCdIG9yIOKAnGRlc2PigJ0uIERlZmF1bHRzIHRvIOKAnGRlc2PigJ0uXG4gIC8vIHNpemUgKG9wdGlvbmFsKSBOdW1iZXIgb2Ygcm93cyByZXR1cm5lZCBieSBzZWFyY2guIERlZmF1bHRzIHRvIDEwXG4gIGdldExvZ3Mob3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKCF0aGlzLmFkYXB0ZXIpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihQYXJzZS5FcnJvci5QVVNIX01JU0NPTkZJR1VSRUQsICdMb2dnZXIgYWRhcHRlciBpcyBub3QgYXZhaWxhYmxlJyk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdGhpcy5hZGFwdGVyLnF1ZXJ5ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgIFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCxcbiAgICAgICAgJ1F1ZXJ5aW5nIGxvZ3MgaXMgbm90IHN1cHBvcnRlZCB3aXRoIHRoaXMgYWRhcHRlcidcbiAgICAgICk7XG4gICAgfVxuICAgIG9wdGlvbnMgPSBMb2dnZXJDb250cm9sbGVyLnBhcnNlT3B0aW9ucyhvcHRpb25zKTtcbiAgICByZXR1cm4gdGhpcy5hZGFwdGVyLnF1ZXJ5KG9wdGlvbnMpO1xuICB9XG5cbiAgZXhwZWN0ZWRBZGFwdGVyVHlwZSgpIHtcbiAgICByZXR1cm4gTG9nZ2VyQWRhcHRlcjtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBMb2dnZXJDb250cm9sbGVyO1xuIl19
225
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJNSUxMSVNFQ09ORFNfSU5fQV9EQVkiLCJMT0dfU1RSSU5HX1RSVU5DQVRFX0xFTkdUSCIsInRydW5jYXRpb25NYXJrZXIiLCJMb2dMZXZlbCIsIklORk8iLCJFUlJPUiIsIkxvZ09yZGVyIiwiREVTQ0VORElORyIsIkFTQ0VORElORyIsImxvZ0xldmVscyIsIkxvZ2dlckNvbnRyb2xsZXIiLCJBZGFwdGFibGVDb250cm9sbGVyIiwiY29uc3RydWN0b3IiLCJhZGFwdGVyIiwiYXBwSWQiLCJvcHRpb25zIiwibG9nTGV2ZWwiLCJsZXZlbCIsInZlcmJvc2UiLCJpbmRleCIsImluZGV4T2YiLCJmb3JFYWNoIiwibGV2ZWxJbmRleCIsIm1hc2tTZW5zaXRpdmVVcmwiLCJwYXRoIiwidXJsU3RyaW5nIiwidXJsT2JqIiwiVVJMIiwicXVlcnkiLCJzZWFyY2hQYXJhbXMiLCJzYW5pdGl6ZWRRdWVyeSIsImtleSIsInZhbHVlIiwic2xpY2UiLCJwYXRobmFtZSIsIm1hc2tTZW5zaXRpdmUiLCJhcmdBcnJheSIsIm1hcCIsImUiLCJyZXBsYWNlIiwidXJsIiwiQXJyYXkiLCJpc0FycmF5IiwiaXRlbSIsImJvZHkiLCJPYmplY3QiLCJrZXlzIiwicGFyYW1zIiwibG9nIiwiYXJncyIsImNvbmNhdCIsImFyZyIsImFwcGx5IiwiaW5mbyIsImFyZ3VtZW50cyIsImVycm9yIiwid2FybiIsImRlYnVnIiwic2lsbHkiLCJsb2dSZXF1ZXN0IiwibWV0aG9kIiwiaGVhZGVycyIsInN0cmluZ2lmaWVkQm9keSIsIkpTT04iLCJzdHJpbmdpZnkiLCJsb2dSZXNwb25zZSIsInJlc3VsdCIsInN0cmluZ2lmaWVkUmVzcG9uc2UiLCJ2YWxpZERhdGVUaW1lIiwiZGF0ZSIsIkRhdGUiLCJpc05hTiIsImdldFRpbWUiLCJ0cnVuY2F0ZUxvZ01lc3NhZ2UiLCJzdHJpbmciLCJsZW5ndGgiLCJ0cnVuY2F0ZWQiLCJzdWJzdHJpbmciLCJwYXJzZU9wdGlvbnMiLCJmcm9tIiwibm93IiwidW50aWwiLCJzaXplIiwiTnVtYmVyIiwib3JkZXIiLCJnZXRMb2dzIiwiUGFyc2UiLCJFcnJvciIsIlBVU0hfTUlTQ09ORklHVVJFRCIsImV4cGVjdGVkQWRhcHRlclR5cGUiLCJMb2dnZXJBZGFwdGVyIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL0NvbnRyb2xsZXJzL0xvZ2dlckNvbnRyb2xsZXIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUGFyc2UgfSBmcm9tICdwYXJzZS9ub2RlJztcbmltcG9ydCBBZGFwdGFibGVDb250cm9sbGVyIGZyb20gJy4vQWRhcHRhYmxlQ29udHJvbGxlcic7XG5pbXBvcnQgeyBMb2dnZXJBZGFwdGVyIH0gZnJvbSAnLi4vQWRhcHRlcnMvTG9nZ2VyL0xvZ2dlckFkYXB0ZXInO1xuXG5jb25zdCBNSUxMSVNFQ09ORFNfSU5fQV9EQVkgPSAyNCAqIDYwICogNjAgKiAxMDAwO1xuY29uc3QgTE9HX1NUUklOR19UUlVOQ0FURV9MRU5HVEggPSAxMDAwO1xuY29uc3QgdHJ1bmNhdGlvbk1hcmtlciA9ICcuLi4gKHRydW5jYXRlZCknO1xuXG5leHBvcnQgY29uc3QgTG9nTGV2ZWwgPSB7XG4gIElORk86ICdpbmZvJyxcbiAgRVJST1I6ICdlcnJvcicsXG59O1xuXG5leHBvcnQgY29uc3QgTG9nT3JkZXIgPSB7XG4gIERFU0NFTkRJTkc6ICdkZXNjJyxcbiAgQVNDRU5ESU5HOiAnYXNjJyxcbn07XG5cbmV4cG9ydCBjb25zdCBsb2dMZXZlbHMgPSBbJ2Vycm9yJywgJ3dhcm4nLCAnaW5mbycsICdkZWJ1ZycsICd2ZXJib3NlJywgJ3NpbGx5J107XG5cbmV4cG9ydCBjbGFzcyBMb2dnZXJDb250cm9sbGVyIGV4dGVuZHMgQWRhcHRhYmxlQ29udHJvbGxlciB7XG4gIGNvbnN0cnVjdG9yKGFkYXB0ZXIsIGFwcElkLCBvcHRpb25zID0geyBsb2dMZXZlbDogJ2luZm8nIH0pIHtcbiAgICBzdXBlcihhZGFwdGVyLCBhcHBJZCwgb3B0aW9ucyk7XG4gICAgbGV0IGxldmVsID0gJ2luZm8nO1xuICAgIGlmIChvcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgIGxldmVsID0gJ3ZlcmJvc2UnO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy5sb2dMZXZlbCkge1xuICAgICAgbGV2ZWwgPSBvcHRpb25zLmxvZ0xldmVsO1xuICAgIH1cbiAgICBjb25zdCBpbmRleCA9IGxvZ0xldmVscy5pbmRleE9mKGxldmVsKTsgLy8gaW5mbyBieSBkZWZhdWx0XG4gICAgbG9nTGV2ZWxzLmZvckVhY2goKGxldmVsLCBsZXZlbEluZGV4KSA9PiB7XG4gICAgICBpZiAobGV2ZWxJbmRleCA+IGluZGV4KSB7XG4gICAgICAgIC8vIHNpbGVuY2UgdGhlIGxldmVscyB0aGF0IGFyZSA+IG1heEluZGV4XG4gICAgICAgIHRoaXNbbGV2ZWxdID0gKCkgPT4ge307XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBtYXNrU2Vuc2l0aXZlVXJsKHBhdGgpIHtcbiAgICBjb25zdCB1cmxTdHJpbmcgPSAnaHR0cDovL2xvY2FsaG9zdCcgKyBwYXRoOyAvLyBwcmVwZW5kIGR1bW15IHN0cmluZyB0byBtYWtlIGEgcmVhbCBVUkxcbiAgICBjb25zdCB1cmxPYmogPSBuZXcgVVJMKHVybFN0cmluZyk7XG4gICAgY29uc3QgcXVlcnkgPSB1cmxPYmouc2VhcmNoUGFyYW1zO1xuICAgIGxldCBzYW5pdGl6ZWRRdWVyeSA9ICc/JztcblxuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIHF1ZXJ5KSB7XG4gICAgICBpZiAoa2V5ICE9PSAncGFzc3dvcmQnKSB7XG4gICAgICAgIC8vIG5vcm1hbCB2YWx1ZVxuICAgICAgICBzYW5pdGl6ZWRRdWVyeSArPSBrZXkgKyAnPScgKyB2YWx1ZSArICcmJztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIHBhc3N3b3JkIHZhbHVlLCByZWRhY3QgaXRcbiAgICAgICAgc2FuaXRpemVkUXVlcnkgKz0ga2V5ICsgJz0nICsgJyoqKioqKioqJyArICcmJztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyB0cmltIGxhc3QgY2hhcmFjdGVyLCA/IG9yICZcbiAgICBzYW5pdGl6ZWRRdWVyeSA9IHNhbml0aXplZFF1ZXJ5LnNsaWNlKDAsIC0xKTtcblxuICAgIC8vIHJldHVybiBvcmlnaW5hbCBwYXRoIG5hbWUgd2l0aCBzYW5pdGl6ZWQgcGFyYW1zIGF0dGFjaGVkXG4gICAgcmV0dXJuIHVybE9iai5wYXRobmFtZSArIHNhbml0aXplZFF1ZXJ5O1xuICB9XG5cbiAgbWFza1NlbnNpdGl2ZShhcmdBcnJheSkge1xuICAgIHJldHVybiBhcmdBcnJheS5tYXAoZSA9PiB7XG4gICAgICBpZiAoIWUpIHtcbiAgICAgICAgcmV0dXJuIGU7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2YgZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIGUucmVwbGFjZSgvKHBhc3N3b3JkXCIuPzouP1wiKVteXCJdKlwiL2csICckMSoqKioqKioqXCInKTtcbiAgICAgIH1cbiAgICAgIC8vIGVsc2UgaXQgaXMgYW4gb2JqZWN0Li4uXG5cbiAgICAgIC8vIGNoZWNrIHRoZSB1cmxcbiAgICAgIGlmIChlLnVybCkge1xuICAgICAgICAvLyBmb3Igc3RyaW5nc1xuICAgICAgICBpZiAodHlwZW9mIGUudXJsID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGUudXJsID0gdGhpcy5tYXNrU2Vuc2l0aXZlVXJsKGUudXJsKTtcbiAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGUudXJsKSkge1xuICAgICAgICAgIC8vIGZvciBzdHJpbmdzIGluIGFycmF5XG4gICAgICAgICAgZS51cmwgPSBlLnVybC5tYXAoaXRlbSA9PiB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGl0ZW0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLm1hc2tTZW5zaXRpdmVVcmwoaXRlbSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBpdGVtO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChlLmJvZHkpIHtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoZS5ib2R5KSkge1xuICAgICAgICAgIGlmIChrZXkgPT09ICdwYXNzd29yZCcpIHtcbiAgICAgICAgICAgIGUuYm9keVtrZXldID0gJyoqKioqKioqJztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoZS5wYXJhbXMpIHtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoZS5wYXJhbXMpKSB7XG4gICAgICAgICAgaWYgKGtleSA9PT0gJ3Bhc3N3b3JkJykge1xuICAgICAgICAgICAgZS5wYXJhbXNba2V5XSA9ICcqKioqKioqKic7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGU7XG4gICAgfSk7XG4gIH1cblxuICBsb2cobGV2ZWwsIGFyZ3MpIHtcbiAgICAvLyBtYWtlIHRoZSBwYXNzZWQgaW4gYXJndW1lbnRzIG9iamVjdCBhbiBhcnJheSB3aXRoIHRoZSBzcHJlYWQgb3BlcmF0b3JcbiAgICBhcmdzID0gdGhpcy5tYXNrU2Vuc2l0aXZlKFsuLi5hcmdzXSk7XG4gICAgYXJncyA9IFtdLmNvbmNhdChcbiAgICAgIGxldmVsLFxuICAgICAgYXJncy5tYXAoYXJnID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBhcmcgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICByZXR1cm4gYXJnKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFyZztcbiAgICAgIH0pXG4gICAgKTtcbiAgICB0aGlzLmFkYXB0ZXIubG9nLmFwcGx5KHRoaXMuYWRhcHRlciwgYXJncyk7XG4gIH1cblxuICBpbmZvKCkge1xuICAgIHJldHVybiB0aGlzLmxvZygnaW5mbycsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBlcnJvcigpIHtcbiAgICByZXR1cm4gdGhpcy5sb2coJ2Vycm9yJywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIHdhcm4oKSB7XG4gICAgcmV0dXJuIHRoaXMubG9nKCd3YXJuJywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIHZlcmJvc2UoKSB7XG4gICAgcmV0dXJuIHRoaXMubG9nKCd2ZXJib3NlJywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIGRlYnVnKCkge1xuICAgIHJldHVybiB0aGlzLmxvZygnZGVidWcnLCBhcmd1bWVudHMpO1xuICB9XG5cbiAgc2lsbHkoKSB7XG4gICAgcmV0dXJuIHRoaXMubG9nKCdzaWxseScsIGFyZ3VtZW50cyk7XG4gIH1cblxuICBsb2dSZXF1ZXN0KHsgbWV0aG9kLCB1cmwsIGhlYWRlcnMsIGJvZHkgfSkge1xuICAgIHRoaXMudmVyYm9zZShcbiAgICAgICgpID0+IHtcbiAgICAgICAgY29uc3Qgc3RyaW5naWZpZWRCb2R5ID0gSlNPTi5zdHJpbmdpZnkoYm9keSwgbnVsbCwgMik7XG4gICAgICAgIHJldHVybiBgUkVRVUVTVCBmb3IgWyR7bWV0aG9kfV0gJHt1cmx9OiAke3N0cmluZ2lmaWVkQm9keX1gO1xuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgbWV0aG9kLFxuICAgICAgICB1cmwsXG4gICAgICAgIGhlYWRlcnMsXG4gICAgICAgIGJvZHksXG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIGxvZ1Jlc3BvbnNlKHsgbWV0aG9kLCB1cmwsIHJlc3VsdCB9KSB7XG4gICAgdGhpcy52ZXJib3NlKFxuICAgICAgKCkgPT4ge1xuICAgICAgICBjb25zdCBzdHJpbmdpZmllZFJlc3BvbnNlID0gSlNPTi5zdHJpbmdpZnkocmVzdWx0LCBudWxsLCAyKTtcbiAgICAgICAgcmV0dXJuIGBSRVNQT05TRSBmcm9tIFske21ldGhvZH1dICR7dXJsfTogJHtzdHJpbmdpZmllZFJlc3BvbnNlfWA7XG4gICAgICB9LFxuICAgICAgeyByZXN1bHQ6IHJlc3VsdCB9XG4gICAgKTtcbiAgfVxuICAvLyBjaGVjayB0aGF0IGRhdGUgaW5wdXQgaXMgdmFsaWRcbiAgc3RhdGljIHZhbGlkRGF0ZVRpbWUoZGF0ZSkge1xuICAgIGlmICghZGF0ZSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGRhdGUgPSBuZXcgRGF0ZShkYXRlKTtcblxuICAgIGlmICghaXNOYU4oZGF0ZS5nZXRUaW1lKCkpKSB7XG4gICAgICByZXR1cm4gZGF0ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHRydW5jYXRlTG9nTWVzc2FnZShzdHJpbmcpIHtcbiAgICBpZiAoc3RyaW5nICYmIHN0cmluZy5sZW5ndGggPiBMT0dfU1RSSU5HX1RSVU5DQVRFX0xFTkdUSCkge1xuICAgICAgY29uc3QgdHJ1bmNhdGVkID0gc3RyaW5nLnN1YnN0cmluZygwLCBMT0dfU1RSSU5HX1RSVU5DQVRFX0xFTkdUSCkgKyB0cnVuY2F0aW9uTWFya2VyO1xuICAgICAgcmV0dXJuIHRydW5jYXRlZDtcbiAgICB9XG5cbiAgICByZXR1cm4gc3RyaW5nO1xuICB9XG5cbiAgc3RhdGljIHBhcnNlT3B0aW9ucyhvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCBmcm9tID1cbiAgICAgIExvZ2dlckNvbnRyb2xsZXIudmFsaWREYXRlVGltZShvcHRpb25zLmZyb20pIHx8XG4gICAgICBuZXcgRGF0ZShEYXRlLm5vdygpIC0gNyAqIE1JTExJU0VDT05EU19JTl9BX0RBWSk7XG4gICAgY29uc3QgdW50aWwgPSBMb2dnZXJDb250cm9sbGVyLnZhbGlkRGF0ZVRpbWUob3B0aW9ucy51bnRpbCkgfHwgbmV3IERhdGUoKTtcbiAgICBjb25zdCBzaXplID0gTnVtYmVyKG9wdGlvbnMuc2l6ZSkgfHwgMTA7XG4gICAgY29uc3Qgb3JkZXIgPSBvcHRpb25zLm9yZGVyIHx8IExvZ09yZGVyLkRFU0NFTkRJTkc7XG4gICAgY29uc3QgbGV2ZWwgPSBvcHRpb25zLmxldmVsIHx8IExvZ0xldmVsLklORk87XG5cbiAgICByZXR1cm4ge1xuICAgICAgZnJvbSxcbiAgICAgIHVudGlsLFxuICAgICAgc2l6ZSxcbiAgICAgIG9yZGVyLFxuICAgICAgbGV2ZWwsXG4gICAgfTtcbiAgfVxuXG4gIC8vIFJldHVybnMgYSBwcm9taXNlIGZvciBhIHtyZXNwb25zZX0gb2JqZWN0LlxuICAvLyBxdWVyeSBwYXJhbXM6XG4gIC8vIGxldmVsIChvcHRpb25hbCkgTGV2ZWwgb2YgbG9nZ2luZyB5b3Ugd2FudCB0byBxdWVyeSBmb3IgKGluZm8gfHwgZXJyb3IpXG4gIC8vIGZyb20gKG9wdGlvbmFsKSBTdGFydCB0aW1lIGZvciB0aGUgc2VhcmNoLiBEZWZhdWx0cyB0byAxIHdlZWsgYWdvLlxuICAvLyB1bnRpbCAob3B0aW9uYWwpIEVuZCB0aW1lIGZvciB0aGUgc2VhcmNoLiBEZWZhdWx0cyB0byBjdXJyZW50IHRpbWUuXG4gIC8vIG9yZGVyIChvcHRpb25hbCkgRGlyZWN0aW9uIG9mIHJlc3VsdHMgcmV0dXJuZWQsIGVpdGhlciDigJxhc2PigJ0gb3Ig4oCcZGVzY+KAnS4gRGVmYXVsdHMgdG8g4oCcZGVzY+KAnS5cbiAgLy8gc2l6ZSAob3B0aW9uYWwpIE51bWJlciBvZiByb3dzIHJldHVybmVkIGJ5IHNlYXJjaC4gRGVmYXVsdHMgdG8gMTBcbiAgZ2V0TG9ncyhvcHRpb25zID0ge30pIHtcbiAgICBpZiAoIXRoaXMuYWRhcHRlcikge1xuICAgICAgdGhyb3cgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLlBVU0hfTUlTQ09ORklHVVJFRCwgJ0xvZ2dlciBhZGFwdGVyIGlzIG5vdCBhdmFpbGFibGUnKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB0aGlzLmFkYXB0ZXIucXVlcnkgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRocm93IG5ldyBQYXJzZS5FcnJvcihcbiAgICAgICAgUGFyc2UuRXJyb3IuUFVTSF9NSVNDT05GSUdVUkVELFxuICAgICAgICAnUXVlcnlpbmcgbG9ncyBpcyBub3Qgc3VwcG9ydGVkIHdpdGggdGhpcyBhZGFwdGVyJ1xuICAgICAgKTtcbiAgICB9XG4gICAgb3B0aW9ucyA9IExvZ2dlckNvbnRyb2xsZXIucGFyc2VPcHRpb25zKG9wdGlvbnMpO1xuICAgIHJldHVybiB0aGlzLmFkYXB0ZXIucXVlcnkob3B0aW9ucyk7XG4gIH1cblxuICBleHBlY3RlZEFkYXB0ZXJUeXBlKCkge1xuICAgIHJldHVybiBMb2dnZXJBZGFwdGVyO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IExvZ2dlckNvbnRyb2xsZXI7XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUFpRTtBQUVqRSxNQUFNQSxxQkFBcUIsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJO0FBQ2pELE1BQU1DLDBCQUEwQixHQUFHLElBQUk7QUFDdkMsTUFBTUMsZ0JBQWdCLEdBQUcsaUJBQWlCO0FBRW5DLE1BQU1DLFFBQVEsR0FBRztFQUN0QkMsSUFBSSxFQUFFLE1BQU07RUFDWkMsS0FBSyxFQUFFO0FBQ1QsQ0FBQztBQUFDO0FBRUssTUFBTUMsUUFBUSxHQUFHO0VBQ3RCQyxVQUFVLEVBQUUsTUFBTTtFQUNsQkMsU0FBUyxFQUFFO0FBQ2IsQ0FBQztBQUFDO0FBRUssTUFBTUMsU0FBUyxHQUFHLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxPQUFPLENBQUM7QUFBQztBQUV6RSxNQUFNQyxnQkFBZ0IsU0FBU0MsNEJBQW1CLENBQUM7RUFDeERDLFdBQVcsQ0FBQ0MsT0FBTyxFQUFFQyxLQUFLLEVBQUVDLE9BQU8sR0FBRztJQUFFQyxRQUFRLEVBQUU7RUFBTyxDQUFDLEVBQUU7SUFDMUQsS0FBSyxDQUFDSCxPQUFPLEVBQUVDLEtBQUssRUFBRUMsT0FBTyxDQUFDO0lBQzlCLElBQUlFLEtBQUssR0FBRyxNQUFNO0lBQ2xCLElBQUlGLE9BQU8sQ0FBQ0csT0FBTyxFQUFFO01BQ25CRCxLQUFLLEdBQUcsU0FBUztJQUNuQjtJ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