appium 2.0.0-beta.21 → 2.0.0-beta.25

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 (93) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +1 -2
  3. package/build/check-npm-pack-files.js +23 -0
  4. package/build/commands-yml/parse.js +319 -0
  5. package/build/commands-yml/validator.js +130 -0
  6. package/build/index.js +19 -0
  7. package/build/lib/appium.js +22 -7
  8. package/build/lib/cli/args.js +13 -15
  9. package/build/lib/cli/npm.js +27 -16
  10. package/build/lib/cli/parser.js +7 -3
  11. package/build/lib/config-file.js +4 -7
  12. package/build/lib/config.js +57 -48
  13. package/build/lib/extension-config.js +1 -1
  14. package/build/lib/main.js +28 -28
  15. package/build/lib/plugin-config.js +2 -2
  16. package/build/lib/plugins.js +4 -2
  17. package/build/lib/schema/appium-config-schema.js +3 -2
  18. package/build/lib/schema/arg-spec.js +5 -3
  19. package/build/lib/schema/cli-args.js +25 -16
  20. package/build/lib/schema/keywords.js +14 -4
  21. package/build/lib/schema/schema.js +86 -9
  22. package/build/lib/utils.js +16 -36
  23. package/build/postinstall.js +90 -0
  24. package/build/test/cli/cli-e2e-specs.js +221 -0
  25. package/build/test/cli/cli-helpers.js +86 -0
  26. package/build/test/cli/cli-specs.js +71 -0
  27. package/build/test/cli/fixtures/test-driver/package.json +27 -0
  28. package/build/test/cli/schema-args-specs.js +48 -0
  29. package/build/test/cli/schema-e2e-specs.js +47 -0
  30. package/build/test/config-e2e-specs.js +112 -0
  31. package/build/test/config-file-e2e-specs.js +191 -0
  32. package/build/test/config-file-specs.js +281 -0
  33. package/build/test/config-specs.js +258 -0
  34. package/build/test/driver-e2e-specs.js +435 -0
  35. package/build/test/driver-specs.js +386 -0
  36. package/build/test/ext-config-io-specs.js +181 -0
  37. package/build/test/extension-config-specs.js +365 -0
  38. package/build/test/fixtures/allow-feat.txt +5 -0
  39. package/build/test/fixtures/caps.json +3 -0
  40. package/build/test/fixtures/config/allow-insecure.txt +3 -0
  41. package/build/test/fixtures/config/appium.config.bad-nodeconfig.json +5 -0
  42. package/build/test/fixtures/config/appium.config.bad.json +32 -0
  43. package/build/test/fixtures/config/appium.config.ext-good.json +9 -0
  44. package/build/test/fixtures/config/appium.config.ext-unknown-props.json +10 -0
  45. package/build/test/fixtures/config/appium.config.good.js +40 -0
  46. package/build/test/fixtures/config/appium.config.good.json +33 -0
  47. package/build/test/fixtures/config/appium.config.good.yaml +30 -0
  48. package/build/test/fixtures/config/appium.config.invalid.json +31 -0
  49. package/build/test/fixtures/config/appium.config.security-array.json +5 -0
  50. package/build/test/fixtures/config/appium.config.security-delimited.json +5 -0
  51. package/build/test/fixtures/config/appium.config.security-path.json +5 -0
  52. package/build/test/fixtures/config/driver-fake.config.json +8 -0
  53. package/build/test/fixtures/config/nodeconfig.json +3 -0
  54. package/build/test/fixtures/config/plugin-fake.config.json +0 -0
  55. package/build/test/fixtures/default-args.js +35 -0
  56. package/build/test/fixtures/deny-feat.txt +5 -0
  57. package/build/test/fixtures/driver.schema.js +20 -0
  58. package/build/test/fixtures/extensions.yaml +27 -0
  59. package/build/test/fixtures/flattened-schema.js +532 -0
  60. package/build/test/fixtures/plugin.schema.js +20 -0
  61. package/build/test/fixtures/schema-with-extensions.js +28 -0
  62. package/build/test/grid-register-specs.js +74 -0
  63. package/build/test/helpers.js +75 -0
  64. package/build/test/logger-specs.js +76 -0
  65. package/build/test/npm-specs.js +20 -0
  66. package/build/test/parser-specs.js +319 -0
  67. package/build/test/plugin-e2e-specs.js +316 -0
  68. package/build/test/schema/arg-spec-specs.js +70 -0
  69. package/build/test/schema/cli-args-specs.js +408 -0
  70. package/build/test/schema/schema-specs.js +407 -0
  71. package/build/test/utils-specs.js +288 -0
  72. package/index.js +11 -0
  73. package/lib/appium-config.schema.json +2 -1
  74. package/lib/appium.js +51 -8
  75. package/lib/cli/args.js +17 -14
  76. package/lib/cli/npm.js +68 -6
  77. package/lib/cli/parser.js +5 -2
  78. package/lib/config-file.js +9 -12
  79. package/lib/config.js +104 -56
  80. package/lib/extension-config.js +1 -1
  81. package/lib/main.js +94 -40
  82. package/lib/plugin-config.js +1 -1
  83. package/lib/plugins.js +2 -0
  84. package/lib/schema/appium-config-schema.js +1 -0
  85. package/lib/schema/arg-spec.js +13 -3
  86. package/lib/schema/cli-args.js +22 -34
  87. package/lib/schema/keywords.js +20 -4
  88. package/lib/schema/schema.js +150 -24
  89. package/lib/utils.js +28 -29
  90. package/package.json +9 -14
  91. package/types/types.d.ts +5 -0
  92. package/build/lib/cli/argparse-actions.js +0 -104
  93. package/lib/cli/argparse-actions.js +0 -77
@@ -0,0 +1,408 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ require("source-map-support/register");
6
+
7
+ var _lodash = _interopRequireDefault(require("lodash"));
8
+
9
+ var _schema = require("../../lib/schema");
10
+
11
+ var _cliArgs = require("../../lib/schema/cli-args");
12
+
13
+ var _cliTransformers = require("../../lib/schema/cli-transformers");
14
+
15
+ const {
16
+ expect
17
+ } = chai;
18
+ describe('cli-args', function () {
19
+ describe('toParserArgs()', function () {
20
+ function getArgs(opts = {}) {
21
+ let {
22
+ extName,
23
+ extType,
24
+ schema
25
+ } = opts;
26
+
27
+ if (schema && extName && extType) {
28
+ (0, _schema.registerSchema)(extType, extName, schema);
29
+ }
30
+
31
+ (0, _schema.finalizeSchema)();
32
+ return _lodash.default.fromPairs([...(0, _cliArgs.toParserArgs)()]);
33
+ }
34
+
35
+ beforeEach(_schema.resetSchema);
36
+ afterEach(_schema.resetSchema);
37
+ describe('schema contents', function () {
38
+ const extName = 'blob';
39
+ const extType = 'plugin';
40
+ describe('type', function () {
41
+ let result;
42
+ describe('boolean', function () {
43
+ beforeEach(function () {
44
+ const schema = {
45
+ properties: {
46
+ foo: {
47
+ type: 'boolean'
48
+ }
49
+ },
50
+ type: 'object'
51
+ };
52
+ result = getArgs({
53
+ schema,
54
+ extName,
55
+ extType
56
+ });
57
+ });
58
+ it('should return options containing `action` prop of `store_const` and no `type`', function () {
59
+ expect(result['--plugin-blob-foo']).to.have.property('action', 'store_const');
60
+ });
61
+ it('should not contain a `metavar` property', function () {
62
+ expect(result['--plugin-blob-foo']).not.to.have.property('metavar');
63
+ });
64
+ });
65
+ describe('object', function () {
66
+ beforeEach(function () {
67
+ const schema = {
68
+ properties: {
69
+ foo: {
70
+ type: 'object'
71
+ }
72
+ },
73
+ type: 'object'
74
+ };
75
+ result = getArgs({
76
+ schema,
77
+ extName,
78
+ extType
79
+ });
80
+ });
81
+ it('should use the `json` transformer', function () {
82
+ expect(result['--plugin-blob-foo']).to.have.property('type', _cliTransformers.transformers.json);
83
+ });
84
+ it('should contain a SCREAMING_SNAKE_CASE `metavar` prop', function () {
85
+ expect(result['--plugin-blob-foo']).to.have.property('metavar', 'FOO');
86
+ });
87
+ });
88
+ describe('array', function () {
89
+ beforeEach(function () {
90
+ const schema = {
91
+ properties: {
92
+ foo: {
93
+ type: 'array'
94
+ }
95
+ },
96
+ type: 'object'
97
+ };
98
+ result = getArgs({
99
+ schema,
100
+ extName,
101
+ extType
102
+ });
103
+ });
104
+ it('should use the `csv` transformer', function () {
105
+ expect(result['--plugin-blob-foo']).to.have.property('type', _cliTransformers.transformers.csv);
106
+ });
107
+ it('should contain a SCREAMING_SNAKE_CASE `metavar` prop', function () {
108
+ expect(result['--plugin-blob-foo']).to.have.property('metavar', 'FOO');
109
+ });
110
+ });
111
+ describe('number', function () {
112
+ beforeEach(function () {
113
+ const schema = {
114
+ properties: {
115
+ foo: {
116
+ type: 'number'
117
+ }
118
+ },
119
+ type: 'object'
120
+ };
121
+ result = getArgs({
122
+ schema,
123
+ extName,
124
+ extType
125
+ });
126
+ });
127
+ it('should parse the value as a float', function () {
128
+ expect(result['--plugin-blob-foo'].type('10.5')).to.equal(10.5);
129
+ });
130
+ it('should contain a SCREAMING_SNAKE_CASE `metavar` prop', function () {
131
+ expect(result['--plugin-blob-foo']).to.have.property('metavar', 'FOO');
132
+ });
133
+ });
134
+ describe('integer', function () {
135
+ beforeEach(function () {
136
+ const schema = {
137
+ properties: {
138
+ foo: {
139
+ type: 'integer'
140
+ }
141
+ },
142
+ type: 'object'
143
+ };
144
+ result = getArgs({
145
+ schema,
146
+ extName,
147
+ extType
148
+ });
149
+ });
150
+ it('should parse the value as an integer', function () {
151
+ expect(result['--plugin-blob-foo'].type('10.5')).to.equal(10);
152
+ });
153
+ it('should contain a SCREAMING_SNAKE_CASE `metavar` prop', function () {
154
+ expect(result['--plugin-blob-foo']).to.have.property('metavar', 'FOO');
155
+ });
156
+ });
157
+ describe('string', function () {
158
+ beforeEach(function () {
159
+ const schema = {
160
+ properties: {
161
+ foo: {
162
+ type: 'string'
163
+ }
164
+ },
165
+ type: 'object'
166
+ };
167
+ result = getArgs({
168
+ schema,
169
+ extName,
170
+ extType
171
+ });
172
+ });
173
+ it('should parse the value as an integer', function () {
174
+ expect(result['--plugin-blob-foo'].type('10.5')).to.equal('10.5');
175
+ });
176
+ it('should contain a SCREAMING_SNAKE_CASE `metavar` prop', function () {
177
+ expect(result['--plugin-blob-foo']).to.have.property('metavar', 'FOO');
178
+ });
179
+ });
180
+ describe('null', function () {
181
+ it('should throw', function () {
182
+ const schema = {
183
+ properties: {
184
+ foo: {
185
+ type: 'null'
186
+ }
187
+ },
188
+ type: 'object'
189
+ };
190
+ expect(() => getArgs({
191
+ extType,
192
+ extName,
193
+ schema
194
+ })).to.throw(TypeError, /unknown or disallowed/);
195
+ });
196
+ });
197
+ describe('(unknown)', function () {
198
+ it('should throw', function () {
199
+ const schema = {
200
+ properties: {
201
+ foo: {
202
+ type: 'donkey'
203
+ }
204
+ },
205
+ type: 'object'
206
+ };
207
+ expect(() => getArgs({
208
+ extType,
209
+ extName,
210
+ schema
211
+ })).to.throw(Error, /schema is invalid/);
212
+ });
213
+ });
214
+ });
215
+ describe('appiumCliAliases', function () {
216
+ let result;
217
+ it('should not allow short aliases for extensions', function () {
218
+ const schema = {
219
+ properties: {
220
+ foo: {
221
+ type: 'string',
222
+ appiumCliAliases: ['fooooo', 'F']
223
+ }
224
+ },
225
+ type: 'object'
226
+ };
227
+ result = getArgs({
228
+ schema,
229
+ extName,
230
+ extType
231
+ });
232
+ expect(result).to.have.property('--plugin-blob-foo,--plugin-blob-fooooo,--plugin-blob-F');
233
+ });
234
+ });
235
+ describe('appiumCliDescription', function () {
236
+ let result;
237
+ it('should be preferred over `description`', function () {
238
+ const schema = {
239
+ properties: {
240
+ foo: {
241
+ type: 'string',
242
+ appiumCliDescription: 'foo',
243
+ description: 'bar'
244
+ }
245
+ },
246
+ type: 'object'
247
+ };
248
+ result = getArgs({
249
+ schema,
250
+ extName,
251
+ extType
252
+ });
253
+ expect(result['--plugin-blob-foo']).to.have.property('help', 'foo');
254
+ });
255
+ });
256
+ describe('appiumCliTransformer', function () {
257
+ let result;
258
+ it('should use the transformer', function () {
259
+ const schema = {
260
+ properties: {
261
+ foo: {
262
+ type: 'string',
263
+ appiumCliTransformer: 'json'
264
+ }
265
+ },
266
+ type: 'object'
267
+ };
268
+ result = getArgs({
269
+ schema,
270
+ extName,
271
+ extType
272
+ });
273
+ expect(result['--plugin-blob-foo'].type('{"herp": "derp"}')).to.eql({
274
+ herp: 'derp'
275
+ });
276
+ });
277
+ it('should error if the value is not valid for the transformer', function () {
278
+ const schema = {
279
+ properties: {
280
+ foo: {
281
+ type: 'string',
282
+ appiumCliTransformer: 'json'
283
+ }
284
+ },
285
+ type: 'object'
286
+ };
287
+ result = getArgs({
288
+ schema,
289
+ extName,
290
+ extType
291
+ });
292
+ expect(() => result['--plugin-blob-foo'].type('123')).to.throw(/must be a valid json/i);
293
+ });
294
+ describe('when used with `enum`', function () {
295
+ describe('and enum members are invalid as per the transformer', function () {
296
+ describe('when provided an enum member', function () {
297
+ it('should throw', function () {
298
+ const schema = {
299
+ properties: {
300
+ foo: {
301
+ type: 'string',
302
+ appiumCliTransformer: 'json',
303
+ enum: ['herp', 'derp']
304
+ }
305
+ },
306
+ type: 'object'
307
+ };
308
+ result = getArgs({
309
+ schema,
310
+ extName,
311
+ extType
312
+ });
313
+ expect(() => result['--plugin-blob-foo'].type('herp')).to.throw(/must be a valid json/i);
314
+ });
315
+ });
316
+ });
317
+ describe('and enum members are valid as per the transformer', function () {
318
+ describe('when provided an enum member', function () {
319
+ it('should return a transformed value', function () {
320
+ const schema = {
321
+ properties: {
322
+ foo: {
323
+ type: 'string',
324
+ appiumCliTransformer: 'json',
325
+ enum: ['{"herp": "derp"}', '{"derp": "herp"}']
326
+ }
327
+ },
328
+ type: 'object'
329
+ };
330
+ result = getArgs({
331
+ schema,
332
+ extName,
333
+ extType
334
+ });
335
+ expect(result['--plugin-blob-foo'].type('{"herp": "derp"}')).to.eql({
336
+ herp: 'derp'
337
+ });
338
+ });
339
+ });
340
+ describe('when not provided an enum member', function () {
341
+ it('should throw', function () {
342
+ const schema = {
343
+ properties: {
344
+ foo: {
345
+ type: 'string',
346
+ appiumCliTransformer: 'json',
347
+ enum: ['{"herp": "derp"}', '{"derp": "herp"}']
348
+ }
349
+ },
350
+ type: 'object'
351
+ };
352
+ result = getArgs({
353
+ schema,
354
+ extName,
355
+ extType
356
+ });
357
+ expect(() => result['--plugin-blob-foo'].type('{"georgy": "porgy"}')).to.throw(/one of the allowed values/i);
358
+ });
359
+ });
360
+ });
361
+ });
362
+ });
363
+ describe('enum', function () {
364
+ describe('when used with a non-`string` type', function () {
365
+ it('should throw', function () {
366
+ const schema = {
367
+ properties: {
368
+ foo: {
369
+ type: 'number',
370
+ enum: ['herp', 'derp']
371
+ }
372
+ },
373
+ type: 'object'
374
+ };
375
+ expect(() => getArgs({
376
+ schema,
377
+ extName,
378
+ extType
379
+ })).to.throw(TypeError, /`enum` is only supported for `type: 'string'`/i);
380
+ });
381
+ it('should actually throw earlier by failing schema validation, but that would mean overriding the behavior of `enum` which sounds inadvisable');
382
+ });
383
+ describe('when used with a `string` type', function () {
384
+ it('should set `choices` prop', function () {
385
+ const schema = {
386
+ properties: {
387
+ foo: {
388
+ type: 'string',
389
+ enum: ['herp', 'derp']
390
+ }
391
+ },
392
+ type: 'object'
393
+ };
394
+ const result = getArgs({
395
+ schema,
396
+ extName,
397
+ extType
398
+ });
399
+ expect(result['--plugin-blob-foo']).to.have.deep.property('choices', ['herp', 'derp']);
400
+ });
401
+ });
402
+ });
403
+ });
404
+ });
405
+ });require('source-map-support').install();
406
+
407
+
408
+ //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3Qvc2NoZW1hL2NsaS1hcmdzLXNwZWNzLmpzIl0sIm5hbWVzIjpbImV4cGVjdCIsImNoYWkiLCJkZXNjcmliZSIsImdldEFyZ3MiLCJvcHRzIiwiZXh0TmFtZSIsImV4dFR5cGUiLCJzY2hlbWEiLCJfIiwiZnJvbVBhaXJzIiwiYmVmb3JlRWFjaCIsInJlc2V0U2NoZW1hIiwiYWZ0ZXJFYWNoIiwicmVzdWx0IiwicHJvcGVydGllcyIsImZvbyIsInR5cGUiLCJpdCIsInRvIiwiaGF2ZSIsInByb3BlcnR5Iiwibm90IiwidHJhbnNmb3JtZXJzIiwianNvbiIsImNzdiIsImVxdWFsIiwidGhyb3ciLCJUeXBlRXJyb3IiLCJFcnJvciIsImFwcGl1bUNsaUFsaWFzZXMiLCJhcHBpdW1DbGlEZXNjcmlwdGlvbiIsImRlc2NyaXB0aW9uIiwiYXBwaXVtQ2xpVHJhbnNmb3JtZXIiLCJlcWwiLCJoZXJwIiwiZW51bSIsImRlZXAiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUVBLE1BQU07QUFBQ0EsRUFBQUE7QUFBRCxJQUFXQyxJQUFqQjtBQUVBQyxRQUFRLENBQUMsVUFBRCxFQUFhLFlBQVk7QUFDL0JBLEVBQUFBLFFBQVEsQ0FBQyxnQkFBRCxFQUFtQixZQUFZO0FBTXJDLGFBQVNDLE9BQVQsQ0FBa0JDLElBQUksR0FBRyxFQUF6QixFQUE2QjtBQUMzQixVQUFJO0FBQUNDLFFBQUFBLE9BQUQ7QUFBVUMsUUFBQUEsT0FBVjtBQUFtQkMsUUFBQUE7QUFBbkIsVUFBNkJILElBQWpDOztBQUNBLFVBQUlHLE1BQU0sSUFBSUYsT0FBVixJQUFxQkMsT0FBekIsRUFBa0M7QUFDaEMsb0NBQWVBLE9BQWYsRUFBd0JELE9BQXhCLEVBQWlDRSxNQUFqQztBQUNEOztBQUNEO0FBQ0EsYUFBT0MsZ0JBQUVDLFNBQUYsQ0FBWSxDQUFDLEdBQUcsNEJBQUosQ0FBWixDQUFQO0FBQ0Q7O0FBRURDLElBQUFBLFVBQVUsQ0FBQ0MsbUJBQUQs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RGhCLFFBQWpELENBQ0UsU0FERixFQUVFLENBQUMsTUFBRCxFQUFTLE1BQVQsQ0FGRjtBQUlELFdBZkMsQ0FBRjtBQWdCRCxTQWpCTyxDQUFSO0FBa0JELE9BekNPLENBQVI7QUEwQ0QsS0E1VE8sQ0FBUjtBQTZURCxHQWhWTyxDQUFSO0FBaVZELENBbFZPLENBQVIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7cmVzZXRTY2hlbWEsIGZpbmFsaXplU2NoZW1hLCByZWdpc3RlclNjaGVtYX0gZnJvbSAnLi4vLi4vbGliL3NjaGVtYSc7XG5pbXBvcnQge3RvUGFyc2VyQXJnc30gZnJvbSAnLi4vLi4vbGliL3NjaGVtYS9jbGktYXJncyc7XG5pbXBvcnQge3RyYW5zZm9ybWVyc30gZnJvbSAnLi4vLi4vbGliL3NjaGVtYS9jbGktdHJhbnNmb3JtZXJzJztcblxuY29uc3Qge2V4cGVjdH0gPSBjaGFpO1xuXG5kZXNjcmliZSgnY2xpLWFyZ3MnLCBmdW5jdGlvbiAoKSB7XG4gIGRlc2NyaWJlKCd0b1BhcnNlckFyZ3MoKScsIGZ1bmN0aW9uICgpIHtcbiAgICAvKipcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7Kn0gb3B0c1xuICAgICAqIEByZXR1cm5zXG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0QXJncyAob3B0cyA9IHt9KSB7XG4gICAgICBsZXQge2V4dE5hbWUsIGV4dFR5cGUsIHNjaGVtYX0gPSBvcHRzO1xuICAgICAgaWYgKHNjaGVtYSAmJiBleHROYW1lICYmIGV4dFR5cGUpIHtcbiAgICAgICAgcmVnaXN0ZXJTY2hlbWEoZXh0VHlwZSwgZXh0TmFtZSwgc2NoZW1hKTtcbiAgICAgIH1cbiAgICAgIGZpbmFsaXplU2NoZW1hKCk7XG4gICAgICByZXR1cm4gXy5mcm9tUGFpcnMoWy4uLnRvUGFyc2VyQXJncygpXSk7XG4gICAgfVxuXG4gICAgYmVmb3JlRWFjaChyZXNldFNjaGVtYSk7XG5cbiAgICBhZnRlckVhY2gocmVzZXRTY2hlbWEpO1xuXG4gICAgZGVzY3JpYmUoJ3NjaGVtYSBjb250ZW50cycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4dE5hbWUgPSAnYmxvYic7XG4gICAgICBjb25zdCBleHRUeXBlID0gJ3BsdWdpbic7XG5cbiAgICAgIGRlc2NyaWJlKCd0eXBlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgcmVzdWx0O1xuXG4gICAgICAgIGRlc2NyaWJlKCdib29sZWFuJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0ge3Byb3BlcnRpZXM6IHtmb286IHt0eXBlOiAnYm9vbGVhbid9fSwgdHlwZTogJ29iamVjdCd9O1xuICAgICAgICAgICAgcmVzdWx0ID0gZ2V0QXJncyh7c2NoZW1hLCBleHROYW1lLCBleHRUeXBlfSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBvcHRpb25zIGNvbnRhaW5pbmcgYGFjdGlvbmAgcHJvcCBvZiBgc3RvcmVfY29uc3RgIGFuZCBubyBgdHlwZWAnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddKS50by5oYXZlLnByb3BlcnR5KFxuICAgICAgICAgICAgICAnYWN0aW9uJyxcbiAgICAgICAgICAgICAgJ3N0b3JlX2NvbnN0JyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIG5vdCBjb250YWluIGEgYG1ldGF2YXJgIHByb3BlcnR5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdFsnLS1wbHVnaW4tYmxvYi1mb28nXSkubm90LnRvLmhhdmUucHJvcGVydHkoJ21ldGF2YXInKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ29iamVjdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHtwcm9wZXJ0aWVzOiB7Zm9vOiB7dHlwZTogJ29iamVjdCd9fSwgdHlwZTogJ29iamVjdCd9O1xuICAgICAgICAgICAgcmVzdWx0ID0gZ2V0QXJncyh7c2NoZW1hLCBleHROYW1lLCBleHRUeXBlfSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIHVzZSB0aGUgYGpzb25gIHRyYW5zZm9ybWVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdFsnLS1wbHVnaW4tYmxvYi1mb28nXSkudG8uaGF2ZS5wcm9wZXJ0eShcbiAgICAgICAgICAgICAgJ3R5cGUnLFxuICAgICAgICAgICAgICB0cmFuc2Zvcm1lcnMuanNvbixcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIGNvbnRhaW4gYSBTQ1JFQU1JTkdfU05BS0VfQ0FTRSBgbWV0YXZhcmAgcHJvcCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10pLnRvLmhhdmUucHJvcGVydHkoXG4gICAgICAgICAgICAgICdtZXRhdmFyJyxcbiAgICAgICAgICAgICAgJ0ZPTycsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgnYXJyYXknLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB7cHJvcGVydGllczoge2Zvbzoge3R5cGU6ICdhcnJheSd9fSwgdHlwZTogJ29iamVjdCd9O1xuICAgICAgICAgICAgcmVzdWx0ID0gZ2V0QXJncyh7c2NoZW1hLCBleHROYW1lLCBleHRUeXBlfSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIHVzZSB0aGUgYGNzdmAgdHJhbnNmb3JtZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddKS50by5oYXZlLnByb3BlcnR5KFxuICAgICAgICAgICAgICAndHlwZScsXG4gICAgICAgICAgICAgIHRyYW5zZm9ybWVycy5jc3YsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCBjb250YWluIGEgU0NSRUFNSU5HX1NOQUtFX0NBU0UgYG1ldGF2YXJgIHByb3AnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddKS50by5oYXZlLnByb3BlcnR5KFxuICAgICAgICAgICAgICAnbWV0YXZhcicsXG4gICAgICAgICAgICAgICdGT08nLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ251bWJlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHtwcm9wZXJ0aWVzOiB7Zm9vOiB7dHlwZTogJ251bWJlcid9fSwgdHlwZTogJ29iamVjdCd9O1xuICAgICAgICAgICAgcmVzdWx0ID0gZ2V0QXJncyh7c2NoZW1hLCBleHROYW1lLCBleHRUeXBlfSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIHBhcnNlIHRoZSB2YWx1ZSBhcyBhIGZsb2F0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdFsnLS1wbHVnaW4tYmxvYi1mb28nXS50eXBlKCcxMC41JykpLnRvLmVxdWFsKDEwLjUpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCBjb250YWluIGEgU0NSRUFNSU5HX1NOQUtFX0NBU0UgYG1ldGF2YXJgIHByb3AnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddKS50by5oYXZlLnByb3BlcnR5KFxuICAgICAgICAgICAgICAnbWV0YXZhcicsXG4gICAgICAgICAgICAgICdGT08nLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ2ludGVnZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB7cHJvcGVydGllczoge2Zvbzoge3R5cGU6ICdpbnRlZ2VyJ319LCB0eXBlOiAnb2JqZWN0J307XG4gICAgICAgICAgICByZXN1bHQgPSBnZXRBcmdzKHtzY2hlbWEsIGV4dE5hbWUsIGV4dFR5cGV9KTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGl0KCdzaG91bGQgcGFyc2UgdGhlIHZhbHVlIGFzIGFuIGludGVnZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddLnR5cGUoJzEwLjUnKSkudG8uZXF1YWwoMTApO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCBjb250YWluIGEgU0NSRUFNSU5HX1NOQUtFX0NBU0UgYG1ldGF2YXJgIHByb3AnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddKS50by5oYXZlLnByb3BlcnR5KFxuICAgICAgICAgICAgICAnbWV0YXZhcicsXG4gICAgICAgICAgICAgICdGT08nLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ3N0cmluZycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBiZWZvcmVFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgICAgICAgICAgcHJvcGVydGllczoge2Zvbzoge3R5cGU6ICdzdHJpbmcnfX0sXG4gICAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJlc3VsdCA9IGdldEFyZ3Moe3NjaGVtYSwgZXh0TmFtZSwgZXh0VHlwZX0pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCBwYXJzZSB0aGUgdmFsdWUgYXMgYW4gaW50ZWdlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10udHlwZSgnMTAuNScpKS50by5lcXVhbCgnMTAuNScpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCBjb250YWluIGEgU0NSRUFNSU5HX1NOQUtFX0NBU0UgYG1ldGF2YXJgIHByb3AnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddKS50by5oYXZlLnByb3BlcnR5KFxuICAgICAgICAgICAgICAnbWV0YXZhcicsXG4gICAgICAgICAgICAgICdGT08nLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ251bGwnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHtwcm9wZXJ0aWVzOiB7Zm9vOiB7dHlwZTogJ251bGwnfX0sIHR5cGU6ICdvYmplY3QnfTtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBnZXRBcmdzKHtleHRUeXBlLCBleHROYW1lLCBzY2hlbWF9KSkudG8udGhyb3coXG4gICAgICAgICAgICAgIFR5cGVFcnJvcixcbiAgICAgICAgICAgICAgL3Vua25vd24gb3IgZGlzYWxsb3dlZC8sXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICBkZXNjcmliZSgnKHVua25vd24pJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGl0KCdzaG91bGQgdGhyb3cnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB7XG4gICAgICAgICAgICAgIHByb3BlcnRpZXM6IHtmb286IHt0eXBlOiAnZG9ua2V5J319LFxuICAgICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBleHBlY3QoKCkgPT4gZ2V0QXJncyh7ZXh0VHlwZSwgZXh0TmFtZSwgc2NoZW1hfSkpLnRvLnRocm93KFxuICAgICAgICAgICAgICBFcnJvcixcbiAgICAgICAgICAgICAgL3NjaGVtYSBpcyBpbnZhbGlkLyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCdhcHBpdW1DbGlBbGlhc2VzJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgcmVzdWx0O1xuXG4gICAgICAgIGl0KCdzaG91bGQgbm90IGFsbG93IHNob3J0IGFsaWFzZXMgZm9yIGV4dGVuc2lvbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qgc2NoZW1hID0ge1xuICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICBmb286IHt0eXBlOiAnc3RyaW5nJywgYXBwaXVtQ2xpQWxpYXNlczogWydmb29vb28nLCAnRiddfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICB9O1xuICAgICAgICAgIHJlc3VsdCA9IGdldEFyZ3Moe3NjaGVtYSwgZXh0TmFtZSwgZXh0VHlwZX0pO1xuICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvLmhhdmUucHJvcGVydHkoXG4gICAgICAgICAgICAnLS1wbHVnaW4tYmxvYi1mb28sLS1wbHVnaW4tYmxvYi1mb29vb28sLS1wbHVnaW4tYmxvYi1GJyxcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnYXBwaXVtQ2xpRGVzY3JpcHRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCByZXN1bHQ7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBiZSBwcmVmZXJyZWQgb3ZlciBgZGVzY3JpcHRpb25gJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgZm9vOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgICAgICAgYXBwaXVtQ2xpRGVzY3JpcHRpb246ICdmb28nLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnYmFyJyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICB9O1xuICAgICAgICAgIHJlc3VsdCA9IGdldEFyZ3Moe3NjaGVtYSwgZXh0TmFtZSwgZXh0VHlwZX0pO1xuICAgICAgICAgIGV4cGVjdChyZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10pLnRvLmhhdmUucHJvcGVydHkoJ2hlbHAnLCAnZm9vJyk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGRlc2NyaWJlKCdhcHBpdW1DbGlUcmFuc2Zvcm1lcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IHJlc3VsdDtcblxuICAgICAgICBpdCgnc2hvdWxkIHVzZSB0aGUgdHJhbnNmb3JtZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qgc2NoZW1hID0ge1xuICAgICAgICAgICAgcHJvcGVydGllczoge2Zvbzoge3R5cGU6ICdzdHJpbmcnLCBhcHBpdW1DbGlUcmFuc2Zvcm1lcjogJ2pzb24nfX0sXG4gICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICB9O1xuICAgICAgICAgIHJlc3VsdCA9IGdldEFyZ3Moe3NjaGVtYSwgZXh0TmFtZSwgZXh0VHlwZX0pO1xuICAgICAgICAgIGV4cGVjdChyZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10udHlwZSgne1wiaGVycFwiOiBcImRlcnBcIn0nKSkudG8uZXFsKHtcbiAgICAgICAgICAgIGhlcnA6ICdkZXJwJyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCBlcnJvciBpZiB0aGUgdmFsdWUgaXMgbm90IHZhbGlkIGZvciB0aGUgdHJhbnNmb3JtZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgY29uc3Qgc2NoZW1hID0ge1xuICAgICAgICAgICAgcHJvcGVydGllczoge2Zvbzoge3R5cGU6ICdzdHJpbmcnLCBhcHBpdW1DbGlUcmFuc2Zvcm1lcjogJ2pzb24nfX0sXG4gICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICB9O1xuICAgICAgICAgIHJlc3VsdCA9IGdldEFyZ3Moe3NjaGVtYSwgZXh0TmFtZSwgZXh0VHlwZX0pO1xuICAgICAgICAgIGV4cGVjdCgoKSA9PiByZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10udHlwZSgnMTIzJykpLnRvLnRocm93KFxuICAgICAgICAgICAgL211c3QgYmUgYSB2YWxpZCBqc29uL2ksXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gdGhpcyBpcyB1bmxpa2VseSB0byBoYXBwZW4sIGJ1dCBJIHdhbnQgdG8gZXN0YWJsaXNoIHRoZSBiZWhhdmlvciBhcyBkZWZpbmVkLlxuICAgICAgICBkZXNjcmliZSgnd2hlbiB1c2VkIHdpdGggYGVudW1gJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGRlc2NyaWJlKCdhbmQgZW51bSBtZW1iZXJzIGFyZSBpbnZhbGlkIGFzIHBlciB0aGUgdHJhbnNmb3JtZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBkZXNjcmliZSgnd2hlbiBwcm92aWRlZCBhbiBlbnVtIG1lbWJlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB7XG4gICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgICAgICAgIGZvbzoge1xuICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgICAgICAgICAgICAgIGFwcGl1bUNsaVRyYW5zZm9ybWVyOiAnanNvbicsXG4gICAgICAgICAgICAgICAgICAgICAgZW51bTogWydoZXJwJywgJ2RlcnAnXSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGdldEFyZ3Moe3NjaGVtYSwgZXh0TmFtZSwgZXh0VHlwZX0pO1xuICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PiByZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10udHlwZSgnaGVycCcpKS50by50aHJvdyhcbiAgICAgICAgICAgICAgICAgIC9tdXN0IGJlIGEgdmFsaWQganNvbi9pLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBkZXNjcmliZSgnYW5kIGVudW0gbWVtYmVycyBhcmUgdmFsaWQgYXMgcGVyIHRoZSB0cmFuc2Zvcm1lcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGRlc2NyaWJlKCd3aGVuIHByb3ZpZGVkIGFuIGVudW0gbWVtYmVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBhIHRyYW5zZm9ybWVkIHZhbHVlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgICAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgZm9vOiB7XG4gICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgICAgICAgICAgICAgYXBwaXVtQ2xpVHJhbnNmb3JtZXI6ICdqc29uJyxcbiAgICAgICAgICAgICAgICAgICAgICBlbnVtOiBbJ3tcImhlcnBcIjogXCJkZXJwXCJ9JywgJ3tcImRlcnBcIjogXCJoZXJwXCJ9J10sXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBnZXRBcmdzKHtzY2hlbWEsIGV4dE5hbWUsIGV4dFR5cGV9KTtcbiAgICAgICAgICAgICAgICBleHBlY3QoXG4gICAgICAgICAgICAgICAgICByZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10udHlwZSgne1wiaGVycFwiOiBcImRlcnBcIn0nKSxcbiAgICAgICAgICAgICAgICApLnRvLmVxbCh7aGVycDogJ2RlcnAnfSk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGRlc2NyaWJlKCd3aGVuIG5vdCBwcm92aWRlZCBhbiBlbnVtIG1lbWJlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB7XG4gICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgICAgICAgIGZvbzoge1xuICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgICAgICAgICAgICAgIGFwcGl1bUNsaVRyYW5zZm9ybWVyOiAnanNvbicsXG4gICAgICAgICAgICAgICAgICAgICAgZW51bTogWyd7XCJoZXJwXCI6IFwiZGVycFwifScsICd7XCJkZXJwXCI6IFwiaGVycFwifSddLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gZ2V0QXJncyh7c2NoZW1hLCBleHROYW1lLCBleHRUeXBlfSk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KCgpID0+XG4gICAgICAgICAgICAgICAgICByZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10udHlwZSgne1wiZ2Vvcmd5XCI6IFwicG9yZ3lcIn0nKSxcbiAgICAgICAgICAgICAgICApLnRvLnRocm93KC9vbmUgb2YgdGhlIGFsbG93ZWQgdmFsdWVzL2kpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnZW51bScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgZGVzY3JpYmUoJ3doZW4gdXNlZCB3aXRoIGEgbm9uLWBzdHJpbmdgIHR5cGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaXQoJ3Nob3VsZCB0aHJvdycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgIGZvbzoge1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICAgICAgICAgICAgICBlbnVtOiBbJ2hlcnAnLCAnZGVycCddLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGV4cGVjdCgoKSA9PiBnZXRBcmdzKHtzY2hlbWEsIGV4dE5hbWUsIGV4dFR5cGV9KSkudG8udGhyb3coXG4gICAgICAgICAgICAgIFR5cGVFcnJvcixcbiAgICAgICAgICAgICAgL2BlbnVtYCBpcyBvbmx5IHN1cHBvcnRlZCBmb3IgYHR5cGU6ICdzdHJpbmcnYC9pLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGl0KFxuICAgICAgICAgICAgJ3Nob3VsZCBhY3R1YWxseSB0aHJvdyBlYXJsaWVyIGJ5IGZhaWxpbmcgc2NoZW1hIHZhbGlkYXRpb24sIGJ1dCB0aGF0IHdvdWxkIG1lYW4gb3ZlcnJpZGluZyB0aGUgYmVoYXZpb3Igb2YgYGVudW1gIHdoaWNoIHNvdW5kcyBpbmFkdmlzYWJsZScsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ3doZW4gdXNlZCB3aXRoIGEgYHN0cmluZ2AgdHlwZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpdCgnc2hvdWxkIHNldCBgY2hvaWNlc2AgcHJvcCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgIGZvbzoge1xuICAgICAgICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgICAgICAgICBlbnVtOiBbJ2hlcnAnLCAnZGVycCddLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGdldEFyZ3Moe3NjaGVtYSwgZXh0TmFtZSwgZXh0VHlwZX0pO1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdFsnLS1wbHVnaW4tYmxvYi1mb28nXSkudG8uaGF2ZS5kZWVwLnByb3BlcnR5KFxuICAgICAgICAgICAgICAnY2hvaWNlcycsXG4gICAgICAgICAgICAgIFsnaGVycCcsICdkZXJwJ10sXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl0sImZpbGUiOiJ0ZXN0L3NjaGVtYS9jbGktYXJncy1zcGVjcy5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLi8uLiJ9