appium 2.0.0-beta.24 → 2.0.0-beta.27

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 (124) hide show
  1. package/build/lib/appium-config.schema.json +278 -0
  2. package/build/lib/appium.js +45 -66
  3. package/build/lib/cli/args.js +19 -39
  4. package/build/lib/cli/driver-command.js +5 -9
  5. package/build/lib/cli/extension-command.js +73 -64
  6. package/build/lib/cli/extension.js +10 -23
  7. package/build/lib/cli/parser.js +9 -19
  8. package/build/lib/cli/plugin-command.js +5 -9
  9. package/build/lib/cli/utils.js +2 -4
  10. package/build/lib/config-file.js +5 -10
  11. package/build/lib/config.js +50 -20
  12. package/build/lib/constants.js +60 -0
  13. package/build/lib/extension/driver-config.js +190 -0
  14. package/build/lib/extension/extension-config.js +297 -0
  15. package/build/lib/extension/index.js +77 -0
  16. package/build/lib/extension/manifest.js +246 -0
  17. package/build/lib/extension/package-changed.js +68 -0
  18. package/build/lib/extension/plugin-config.js +87 -0
  19. package/build/lib/grid-register.js +2 -4
  20. package/build/lib/logger.js +2 -4
  21. package/build/lib/logsink.js +2 -4
  22. package/build/lib/main.js +42 -71
  23. package/build/lib/schema/appium-config-schema.js +2 -4
  24. package/build/lib/schema/arg-spec.js +11 -14
  25. package/build/lib/schema/cli-args.js +2 -4
  26. package/build/lib/schema/cli-transformers.js +2 -4
  27. package/build/lib/schema/index.js +2 -4
  28. package/build/lib/schema/keywords.js +2 -4
  29. package/build/lib/schema/schema.js +61 -37
  30. package/build/lib/utils.js +1 -32
  31. package/lib/appium.js +50 -68
  32. package/lib/cli/args.js +19 -23
  33. package/lib/cli/driver-command.js +10 -2
  34. package/lib/cli/extension-command.js +216 -135
  35. package/lib/cli/extension.js +7 -15
  36. package/lib/cli/parser.js +6 -14
  37. package/lib/cli/plugin-command.js +1 -2
  38. package/lib/config-file.js +12 -15
  39. package/lib/config.js +55 -24
  40. package/lib/constants.js +79 -0
  41. package/lib/extension/driver-config.js +230 -0
  42. package/lib/extension/extension-config.js +459 -0
  43. package/lib/extension/index.js +103 -0
  44. package/lib/extension/manifest.js +590 -0
  45. package/lib/extension/package-changed.js +64 -0
  46. package/lib/extension/plugin-config.js +111 -0
  47. package/lib/grid-register.js +4 -4
  48. package/lib/main.js +57 -93
  49. package/lib/schema/arg-spec.js +3 -3
  50. package/lib/schema/cli-args.js +1 -0
  51. package/lib/schema/keywords.js +1 -1
  52. package/lib/schema/schema.js +67 -29
  53. package/lib/utils.js +2 -32
  54. package/package.json +29 -21
  55. package/{postinstall.js → scripts/postinstall.js} +1 -1
  56. package/types/types.d.ts +70 -31
  57. package/bin/ios-webkit-debug-proxy-launcher.js +0 -71
  58. package/build/check-npm-pack-files.js +0 -23
  59. package/build/commands-yml/parse.js +0 -319
  60. package/build/commands-yml/validator.js +0 -130
  61. package/build/index.js +0 -19
  62. package/build/lib/cli/npm.js +0 -220
  63. package/build/lib/driver-config.js +0 -100
  64. package/build/lib/drivers.js +0 -100
  65. package/build/lib/ext-config-io.js +0 -165
  66. package/build/lib/extension-config.js +0 -320
  67. package/build/lib/plugin-config.js +0 -69
  68. package/build/lib/plugins.js +0 -18
  69. package/build/postinstall.js +0 -90
  70. package/build/test/cli/cli-e2e-specs.js +0 -221
  71. package/build/test/cli/cli-helpers.js +0 -86
  72. package/build/test/cli/cli-specs.js +0 -71
  73. package/build/test/cli/fixtures/test-driver/package.json +0 -27
  74. package/build/test/cli/schema-args-specs.js +0 -48
  75. package/build/test/cli/schema-e2e-specs.js +0 -47
  76. package/build/test/config-e2e-specs.js +0 -112
  77. package/build/test/config-file-e2e-specs.js +0 -209
  78. package/build/test/config-file-specs.js +0 -281
  79. package/build/test/config-specs.js +0 -246
  80. package/build/test/driver-e2e-specs.js +0 -435
  81. package/build/test/driver-specs.js +0 -386
  82. package/build/test/ext-config-io-specs.js +0 -181
  83. package/build/test/extension-config-specs.js +0 -365
  84. package/build/test/fixtures/allow-feat.txt +0 -5
  85. package/build/test/fixtures/caps.json +0 -3
  86. package/build/test/fixtures/config/allow-insecure.txt +0 -3
  87. package/build/test/fixtures/config/appium.config.bad-nodeconfig.json +0 -5
  88. package/build/test/fixtures/config/appium.config.bad.json +0 -32
  89. package/build/test/fixtures/config/appium.config.ext-good.json +0 -9
  90. package/build/test/fixtures/config/appium.config.ext-unknown-props.json +0 -10
  91. package/build/test/fixtures/config/appium.config.good.js +0 -40
  92. package/build/test/fixtures/config/appium.config.good.json +0 -33
  93. package/build/test/fixtures/config/appium.config.good.yaml +0 -30
  94. package/build/test/fixtures/config/appium.config.invalid.json +0 -31
  95. package/build/test/fixtures/config/appium.config.security-array.json +0 -5
  96. package/build/test/fixtures/config/appium.config.security-delimited.json +0 -5
  97. package/build/test/fixtures/config/appium.config.security-path.json +0 -5
  98. package/build/test/fixtures/config/driver-fake.config.json +0 -8
  99. package/build/test/fixtures/config/nodeconfig.json +0 -3
  100. package/build/test/fixtures/config/plugin-fake.config.json +0 -0
  101. package/build/test/fixtures/default-args.js +0 -35
  102. package/build/test/fixtures/deny-feat.txt +0 -5
  103. package/build/test/fixtures/driver.schema.js +0 -20
  104. package/build/test/fixtures/extensions.yaml +0 -27
  105. package/build/test/fixtures/flattened-schema.js +0 -532
  106. package/build/test/fixtures/plugin.schema.js +0 -20
  107. package/build/test/fixtures/schema-with-extensions.js +0 -28
  108. package/build/test/grid-register-specs.js +0 -74
  109. package/build/test/helpers.js +0 -75
  110. package/build/test/logger-specs.js +0 -76
  111. package/build/test/npm-specs.js +0 -20
  112. package/build/test/parser-specs.js +0 -319
  113. package/build/test/plugin-e2e-specs.js +0 -316
  114. package/build/test/schema/arg-spec-specs.js +0 -70
  115. package/build/test/schema/cli-args-specs.js +0 -408
  116. package/build/test/schema/schema-specs.js +0 -407
  117. package/build/test/utils-specs.js +0 -288
  118. package/lib/cli/npm.js +0 -251
  119. package/lib/driver-config.js +0 -101
  120. package/lib/drivers.js +0 -84
  121. package/lib/ext-config-io.js +0 -287
  122. package/lib/extension-config.js +0 -366
  123. package/lib/plugin-config.js +0 -63
  124. package/lib/plugins.js +0 -13
@@ -1,408 +0,0 @@
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