appium 2.0.0-beta.23 → 2.0.0-beta.26

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 (125) hide show
  1. package/README.md +1 -2
  2. package/build/lib/appium-config.schema.json +278 -0
  3. package/build/lib/appium.js +62 -71
  4. package/build/lib/cli/args.js +31 -53
  5. package/build/lib/cli/driver-command.js +5 -9
  6. package/build/lib/cli/extension-command.js +73 -64
  7. package/build/lib/cli/extension.js +10 -23
  8. package/build/lib/cli/parser.js +10 -20
  9. package/build/lib/cli/plugin-command.js +5 -9
  10. package/build/lib/cli/utils.js +2 -4
  11. package/build/lib/config-file.js +5 -10
  12. package/build/lib/config.js +67 -30
  13. package/build/lib/constants.js +60 -0
  14. package/build/lib/extension/driver-config.js +190 -0
  15. package/build/lib/extension/extension-config.js +297 -0
  16. package/build/lib/extension/index.js +77 -0
  17. package/build/lib/extension/manifest.js +246 -0
  18. package/build/lib/extension/package-changed.js +68 -0
  19. package/build/lib/extension/plugin-config.js +87 -0
  20. package/build/lib/grid-register.js +2 -4
  21. package/build/lib/logger.js +2 -4
  22. package/build/lib/logsink.js +2 -4
  23. package/build/lib/main.js +64 -92
  24. package/build/lib/schema/appium-config-schema.js +2 -4
  25. package/build/lib/schema/arg-spec.js +14 -15
  26. package/build/lib/schema/cli-args.js +8 -16
  27. package/build/lib/schema/cli-transformers.js +2 -4
  28. package/build/lib/schema/index.js +2 -4
  29. package/build/lib/schema/keywords.js +2 -4
  30. package/build/lib/schema/schema.js +136 -41
  31. package/build/lib/utils.js +13 -64
  32. package/lib/appium.js +74 -55
  33. package/lib/cli/args.js +36 -37
  34. package/lib/cli/driver-command.js +10 -2
  35. package/lib/cli/extension-command.js +216 -135
  36. package/lib/cli/extension.js +7 -15
  37. package/lib/cli/parser.js +7 -15
  38. package/lib/cli/plugin-command.js +1 -2
  39. package/lib/config-file.js +12 -15
  40. package/lib/config.js +111 -36
  41. package/lib/constants.js +79 -0
  42. package/lib/extension/driver-config.js +230 -0
  43. package/lib/extension/extension-config.js +459 -0
  44. package/lib/extension/index.js +103 -0
  45. package/lib/extension/manifest.js +590 -0
  46. package/lib/extension/package-changed.js +64 -0
  47. package/lib/extension/plugin-config.js +111 -0
  48. package/lib/grid-register.js +4 -4
  49. package/lib/main.js +110 -96
  50. package/lib/schema/arg-spec.js +11 -5
  51. package/lib/schema/cli-args.js +7 -30
  52. package/lib/schema/keywords.js +1 -1
  53. package/lib/schema/schema.js +206 -48
  54. package/lib/utils.js +27 -58
  55. package/package.json +29 -21
  56. package/{postinstall.js → scripts/postinstall.js} +1 -1
  57. package/types/types.d.ts +72 -28
  58. package/bin/ios-webkit-debug-proxy-launcher.js +0 -71
  59. package/build/check-npm-pack-files.js +0 -23
  60. package/build/commands-yml/parse.js +0 -319
  61. package/build/commands-yml/validator.js +0 -130
  62. package/build/index.js +0 -19
  63. package/build/lib/cli/npm.js +0 -220
  64. package/build/lib/driver-config.js +0 -100
  65. package/build/lib/drivers.js +0 -100
  66. package/build/lib/ext-config-io.js +0 -165
  67. package/build/lib/extension-config.js +0 -320
  68. package/build/lib/plugin-config.js +0 -69
  69. package/build/lib/plugins.js +0 -16
  70. package/build/postinstall.js +0 -90
  71. package/build/test/cli/cli-e2e-specs.js +0 -221
  72. package/build/test/cli/cli-helpers.js +0 -86
  73. package/build/test/cli/cli-specs.js +0 -71
  74. package/build/test/cli/fixtures/test-driver/package.json +0 -27
  75. package/build/test/cli/schema-args-specs.js +0 -48
  76. package/build/test/cli/schema-e2e-specs.js +0 -47
  77. package/build/test/config-e2e-specs.js +0 -112
  78. package/build/test/config-file-e2e-specs.js +0 -209
  79. package/build/test/config-file-specs.js +0 -281
  80. package/build/test/config-specs.js +0 -159
  81. package/build/test/driver-e2e-specs.js +0 -435
  82. package/build/test/driver-specs.js +0 -321
  83. package/build/test/ext-config-io-specs.js +0 -181
  84. package/build/test/extension-config-specs.js +0 -365
  85. package/build/test/fixtures/allow-feat.txt +0 -5
  86. package/build/test/fixtures/caps.json +0 -3
  87. package/build/test/fixtures/config/allow-insecure.txt +0 -3
  88. package/build/test/fixtures/config/appium.config.bad-nodeconfig.json +0 -5
  89. package/build/test/fixtures/config/appium.config.bad.json +0 -32
  90. package/build/test/fixtures/config/appium.config.ext-good.json +0 -9
  91. package/build/test/fixtures/config/appium.config.ext-unknown-props.json +0 -10
  92. package/build/test/fixtures/config/appium.config.good.js +0 -40
  93. package/build/test/fixtures/config/appium.config.good.json +0 -33
  94. package/build/test/fixtures/config/appium.config.good.yaml +0 -30
  95. package/build/test/fixtures/config/appium.config.invalid.json +0 -31
  96. package/build/test/fixtures/config/appium.config.security-array.json +0 -5
  97. package/build/test/fixtures/config/appium.config.security-delimited.json +0 -5
  98. package/build/test/fixtures/config/appium.config.security-path.json +0 -5
  99. package/build/test/fixtures/config/driver-fake.config.json +0 -8
  100. package/build/test/fixtures/config/nodeconfig.json +0 -3
  101. package/build/test/fixtures/config/plugin-fake.config.json +0 -0
  102. package/build/test/fixtures/default-args.js +0 -35
  103. package/build/test/fixtures/deny-feat.txt +0 -5
  104. package/build/test/fixtures/driver.schema.js +0 -20
  105. package/build/test/fixtures/extensions.yaml +0 -27
  106. package/build/test/fixtures/flattened-schema.js +0 -504
  107. package/build/test/fixtures/plugin.schema.js +0 -20
  108. package/build/test/fixtures/schema-with-extensions.js +0 -28
  109. package/build/test/grid-register-specs.js +0 -74
  110. package/build/test/helpers.js +0 -75
  111. package/build/test/logger-specs.js +0 -76
  112. package/build/test/npm-specs.js +0 -20
  113. package/build/test/parser-specs.js +0 -314
  114. package/build/test/plugin-e2e-specs.js +0 -316
  115. package/build/test/schema/arg-spec-specs.js +0 -70
  116. package/build/test/schema/cli-args-specs.js +0 -431
  117. package/build/test/schema/schema-specs.js +0 -389
  118. package/build/test/utils-specs.js +0 -266
  119. package/lib/cli/npm.js +0 -251
  120. package/lib/driver-config.js +0 -101
  121. package/lib/drivers.js +0 -84
  122. package/lib/ext-config-io.js +0 -287
  123. package/lib/extension-config.js +0 -366
  124. package/lib/plugin-config.js +0 -63
  125. package/lib/plugins.js +0 -11
@@ -1,431 +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)(opts)]);
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_true` and no `type`', function () {
59
- expect(result['--plugin-blob-foo']).to.have.property('action', 'store_true');
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
- describe('overrides', function () {
404
- it('should set them via "dest" key', function () {
405
- const schema = {
406
- properties: {
407
- foo: {
408
- type: 'string'
409
- }
410
- },
411
- type: 'object'
412
- };
413
- const result = getArgs({
414
- schema,
415
- extName,
416
- extType,
417
- overrides: {
418
- 'plugin.blob.foo': {
419
- enum: ['slug', 'snail']
420
- }
421
- }
422
- });
423
- expect(result['--plugin-blob-foo']).to.have.deep.property('enum', ['slug', 'snail']);
424
- });
425
- });
426
- });
427
- });
428
- });require('source-map-support').install();
429
-
430
-
431
- //# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3Qvc2NoZW1hL2NsaS1hcmdzLXNwZWNzLmpzIl0sIm5hbWVzIjpbImV4cGVjdCIsImNoYWkiLCJkZXNjcmliZSIsImdldEFyZ3MiLCJvcHRzIiwiZXh0TmFtZSIsImV4dFR5cGUiLCJzY2hlbWEiLCJfIiwiZnJvbVBhaXJzIiwiYmVmb3JlRWFjaCIsInJlc2V0U2NoZW1hIiwiYWZ0ZXJFYWNoIiwicmVzdWx0IiwicHJvcGVydGllcyIsImZvbyIsInR5cGUiLCJpdCIsInRvIiwiaGF2ZSIsInByb3BlcnR5Iiwibm90IiwidHJhbnNmb3JtZXJzIiwianNvbiIsImNzdiIsImVxdWFsIiwidGhyb3ciLCJUeXBlRXJyb3IiLCJFcnJvciIsImFwcGl1bUNsaUFsaWFzZXMiLCJhcHBpdW1DbGlEZXNjcmlwdGlvbiIsImRlc2NyaXB0aW9uIiwiYXBwaXVtQ2xpVHJhbnNmb3JtZXIiLCJlcWwiLCJoZXJwIiwiZW51bSIsImRlZXAiLCJvdmVycmlkZXMiXSwibWFwcGluZ3MiOiI7Ozs7OztBQUVBOztBQUNBOztBQUNBOztBQUNBOztBQUVBLE1BQU07QUFBQ0EsRUFBQUE7QUFBRCxJQUFXQyxJQUFqQjtBQUVBQyxRQUFRLENBQUMsVUFBRCxFQUFhLFlBQVk7QUFDL0JBLEVBQUFBLFFBQVEsQ0FBQyxnQkFBRCxFQUFtQixZQUFZO0FBTXJDLGFBQVNDLE9BQVQsQ0FBa0JDLElBQUksR0FBRyxFQUF6QixFQUE2QjtBQUMzQixVQUFJO0FBQUNDLFFBQUFBLE9BQUQ7QUFBVUMsUUFBQUEsT0FBVjtBQUFtQkMsUUFBQUE7QUFBbkIsVUFBNkJILElBQWpDOztBQUNBLFVBQUlHLE1BQU0sSUFBSUYsT0FBVixJQUFxQkMsT0FBekIsRUFBa0M7QUFDaEMsb0NBQWVBLE9BQWYsRUFBd0JELE9BQXhCLEVBQWlDRSxNQUFqQztBQUNEOztBQUNEO0FBQ0EsYUFBT0MsZ0JBQUVDLFNBQUYsQ0FBWSxDQUFDLEdBQUcsMkJBQWFMLElBQWIsQ0FBSixDQUFaLENBQVA7QUFDRDs7QUFFRE0s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QUF2QyxDQUE0Q2lCLElBQTVDLENBQWlEaEIsUUFBakQsQ0FDRSxTQURGLEVBRUUsQ0FBQyxNQUFELEVBQVMsTUFBVCxDQUZGO0FBSUQsV0FmQyxDQUFGO0FBZ0JELFNBakJPLENBQVI7QUFrQkQsT0F6Q08sQ0FBUjtBQTJDQWxCLE1BQUFBLFFBQVEsQ0FBQyxXQUFELEVBQWMsWUFBWTtBQUdoQ2UsUUFBQUEsRUFBRSxDQUFDLGdDQUFELEVBQW1DLFlBQVk7QUFDL0MsZ0JBQU1WLE1BQU0sR0FBRztBQUNiTyxZQUFBQSxVQUFVLEVBQUU7QUFDVkMsY0FBQUEsR0FBRyxFQUFFO0FBQ0hDLGdCQUFBQSxJQUFJLEVBQUU7QUFESDtBQURLLGFBREM7QUFNYkEsWUFBQUEsSUFBSSxFQUFFO0FBTk8sV0FBZjtBQVNBLGdCQUFNSCxNQUFNLEdBQUdWLE9BQU8sQ0FBQztBQUNyQkksWUFBQUEsTUFEcUI7QUFFckJGLFlBQUFBLE9BRnFCO0FBR3JCQyxZQUFBQSxPQUhxQjtBQUlyQitCLFlBQUFBLFNBQVMsRUFBRTtBQUFDLGlDQUFtQjtBQUFDRixnQkFBQUEsSUFBSSxFQUFFLENBQUMsTUFBRCxFQUFTLE9BQVQ7QUFBUDtBQUFwQjtBQUpVLFdBQUQsQ0FBdEI7QUFNQW5DLFVBQUFBLE1BQU0sQ0FBQ2EsTUFBTSxDQUFDLG1CQUFELENBQVAsQ0FBTixDQUFvQ0ssRUFBcEMsQ0FBdUNDLElBQXZDLENBQTRDaUIsSUFBNUMsQ0FBaURoQixRQUFqRCxDQUEwRCxNQUExRCxFQUFrRSxDQUNoRSxNQURnRSxFQUVoRSxPQUZnRSxDQUFsRTtBQUlELFNBcEJDLENBQUY7QUFxQkQsT0F4Qk8sQ0FBUjtBQXlCRCxLQXRWTyxDQUFSO0FBdVZELEdBMVdPLENBQVI7QUEyV0QsQ0E1V08sQ0FBUiIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHtyZXNldFNjaGVtYSwgZmluYWxpemVTY2hlbWEsIHJlZ2lzdGVyU2NoZW1hfSBmcm9tICcuLi8uLi9saWIvc2NoZW1hJztcbmltcG9ydCB7dG9QYXJzZXJBcmdzfSBmcm9tICcuLi8uLi9saWIvc2NoZW1hL2NsaS1hcmdzJztcbmltcG9ydCB7dHJhbnNmb3JtZXJzfSBmcm9tICcuLi8uLi9saWIvc2NoZW1hL2NsaS10cmFuc2Zvcm1lcnMnO1xuXG5jb25zdCB7ZXhwZWN0fSA9IGNoYWk7XG5cbmRlc2NyaWJlKCdjbGktYXJncycsIGZ1bmN0aW9uICgpIHtcbiAgZGVzY3JpYmUoJ3RvUGFyc2VyQXJncygpJywgZnVuY3Rpb24gKCkge1xuICAgIC8qKlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSBvcHRzXG4gICAgICogQHJldHVybnNcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRBcmdzIChvcHRzID0ge30pIHtcbiAgICAgIGxldCB7ZXh0TmFtZSwgZXh0VHlwZSwgc2NoZW1hfSA9IG9wdHM7XG4gICAgICBpZiAoc2NoZW1hICYmIGV4dE5hbWUgJiYgZXh0VHlwZSkge1xuICAgICAgICByZWdpc3RlclNjaGVtYShleHRUeXBlLCBleHROYW1lLCBzY2hlbWEpO1xuICAgICAgfVxuICAgICAgZmluYWxpemVTY2hlbWEoKTtcbiAgICAgIHJldHVybiBfLmZyb21QYWlycyhbLi4udG9QYXJzZXJBcmdzKG9wdHMpXSk7XG4gICAgfVxuXG4gICAgYmVmb3JlRWFjaChyZXNldFNjaGVtYSk7XG5cbiAgICBhZnRlckVhY2gocmVzZXRTY2hlbWEpO1xuXG4gICAgZGVzY3JpYmUoJ3NjaGVtYSBjb250ZW50cycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGV4dE5hbWUgPSAnYmxvYic7XG4gICAgICBjb25zdCBleHRUeXBlID0gJ3BsdWdpbic7XG5cbiAgICAgIGRlc2NyaWJlKCd0eXBlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgcmVzdWx0O1xuXG4gICAgICAgIGRlc2NyaWJlKCdib29sZWFuJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0ge3Byb3BlcnRpZXM6IHtmb286IHt0eXBlOiAnYm9vbGVhbid9fSwgdHlwZTogJ29iamVjdCd9O1xuICAgICAgICAgICAgcmVzdWx0ID0gZ2V0QXJncyh7c2NoZW1hLCBleHROYW1lLCBleHRUeXBlfSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBvcHRpb25zIGNvbnRhaW5pbmcgYGFjdGlvbmAgcHJvcCBvZiBgc3RvcmVfdHJ1ZWAgYW5kIG5vIGB0eXBlYCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10pLnRvLmhhdmUucHJvcGVydHkoXG4gICAgICAgICAgICAgICdhY3Rpb24nLFxuICAgICAgICAgICAgICAnc3RvcmVfdHJ1ZScsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCBub3QgY29udGFpbiBhIGBtZXRhdmFyYCBwcm9wZXJ0eScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10pLm5vdC50by5oYXZlLnByb3BlcnR5KCdtZXRhdmFyJyk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCdvYmplY3QnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB7cHJvcGVydGllczoge2Zvbzoge3R5cGU6ICdvYmplY3QnfX0sIHR5cGU6ICdvYmplY3QnfTtcbiAgICAgICAgICAgIHJlc3VsdCA9IGdldEFyZ3Moe3NjaGVtYSwgZXh0TmFtZSwgZXh0VHlwZX0pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCB1c2UgdGhlIGBqc29uYCB0cmFuc2Zvcm1lcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10pLnRvLmhhdmUucHJvcGVydHkoXG4gICAgICAgICAgICAgICd0eXBlJyxcbiAgICAgICAgICAgICAgdHJhbnNmb3JtZXJzLmpzb24sXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCBjb250YWluIGEgU0NSRUFNSU5HX1NOQUtFX0NBU0UgYG1ldGF2YXJgIHByb3AnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddKS50by5oYXZlLnByb3BlcnR5KFxuICAgICAgICAgICAgICAnbWV0YXZhcicsXG4gICAgICAgICAgICAgICdGT08nLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJ2FycmF5JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0ge3Byb3BlcnRpZXM6IHtmb286IHt0eXBlOiAnYXJyYXknfX0sIHR5cGU6ICdvYmplY3QnfTtcbiAgICAgICAgICAgIHJlc3VsdCA9IGdldEFyZ3Moe3NjaGVtYSwgZXh0TmFtZSwgZXh0VHlwZX0pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCB1c2UgdGhlIGBjc3ZgIHRyYW5zZm9ybWVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdFsnLS1wbHVnaW4tYmxvYi1mb28nXSkudG8uaGF2ZS5wcm9wZXJ0eShcbiAgICAgICAgICAgICAgJ3R5cGUnLFxuICAgICAgICAgICAgICB0cmFuc2Zvcm1lcnMuY3N2LFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGl0KCdzaG91bGQgY29udGFpbiBhIFNDUkVBTUlOR19TTkFLRV9DQVNFIGBtZXRhdmFyYCBwcm9wJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdFsnLS1wbHVnaW4tYmxvYi1mb28nXSkudG8uaGF2ZS5wcm9wZXJ0eShcbiAgICAgICAgICAgICAgJ21ldGF2YXInLFxuICAgICAgICAgICAgICAnRk9PJyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCdudW1iZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB7cHJvcGVydGllczoge2Zvbzoge3R5cGU6ICdudW1iZXInfX0sIHR5cGU6ICdvYmplY3QnfTtcbiAgICAgICAgICAgIHJlc3VsdCA9IGdldEFyZ3Moe3NjaGVtYSwgZXh0TmFtZSwgZXh0VHlwZX0pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaXQoJ3Nob3VsZCBwYXJzZSB0aGUgdmFsdWUgYXMgYSBmbG9hdCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10udHlwZSgnMTAuNScpKS50by5lcXVhbCgxMC41KTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGl0KCdzaG91bGQgY29udGFpbiBhIFNDUkVBTUlOR19TTkFLRV9DQVNFIGBtZXRhdmFyYCBwcm9wJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdFsnLS1wbHVnaW4tYmxvYi1mb28nXSkudG8uaGF2ZS5wcm9wZXJ0eShcbiAgICAgICAgICAgICAgJ21ldGF2YXInLFxuICAgICAgICAgICAgICAnRk9PJyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCdpbnRlZ2VyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0ge3Byb3BlcnRpZXM6IHtmb286IHt0eXBlOiAnaW50ZWdlcid9fSwgdHlwZTogJ29iamVjdCd9O1xuICAgICAgICAgICAgcmVzdWx0ID0gZ2V0QXJncyh7c2NoZW1hLCBleHROYW1lLCBleHRUeXBlfSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdCgnc2hvdWxkIHBhcnNlIHRoZSB2YWx1ZSBhcyBhbiBpbnRlZ2VyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdFsnLS1wbHVnaW4tYmxvYi1mb28nXS50eXBlKCcxMC41JykpLnRvLmVxdWFsKDEwKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGl0KCdzaG91bGQgY29udGFpbiBhIFNDUkVBTUlOR19TTkFLRV9DQVNFIGBtZXRhdmFyYCBwcm9wJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdFsnLS1wbHVnaW4tYmxvYi1mb28nXSkudG8uaGF2ZS5wcm9wZXJ0eShcbiAgICAgICAgICAgICAgJ21ldGF2YXInLFxuICAgICAgICAgICAgICAnRk9PJyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCdzdHJpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgYmVmb3JlRWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB7XG4gICAgICAgICAgICAgIHByb3BlcnRpZXM6IHtmb286IHt0eXBlOiAnc3RyaW5nJ319LFxuICAgICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXN1bHQgPSBnZXRBcmdzKHtzY2hlbWEsIGV4dE5hbWUsIGV4dFR5cGV9KTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGl0KCdzaG91bGQgcGFyc2UgdGhlIHZhbHVlIGFzIGFuIGludGVnZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBleHBlY3QocmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddLnR5cGUoJzEwLjUnKSkudG8uZXF1YWwoJzEwLjUnKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGl0KCdzaG91bGQgY29udGFpbiBhIFNDUkVBTUlOR19TTkFLRV9DQVNFIGBtZXRhdmFyYCBwcm9wJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdFsnLS1wbHVnaW4tYmxvYi1mb28nXSkudG8uaGF2ZS5wcm9wZXJ0eShcbiAgICAgICAgICAgICAgJ21ldGF2YXInLFxuICAgICAgICAgICAgICAnRk9PJyxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCdudWxsJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGl0KCdzaG91bGQgdGhyb3cnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB7cHJvcGVydGllczoge2Zvbzoge3R5cGU6ICdudWxsJ319LCB0eXBlOiAnb2JqZWN0J307XG4gICAgICAgICAgICBleHBlY3QoKCkgPT4gZ2V0QXJncyh7ZXh0VHlwZSwgZXh0TmFtZSwgc2NoZW1hfSkpLnRvLnRocm93KFxuICAgICAgICAgICAgICBUeXBlRXJyb3IsXG4gICAgICAgICAgICAgIC91bmtub3duIG9yIGRpc2FsbG93ZWQvLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZGVzY3JpYmUoJyh1bmtub3duKScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpdCgnc2hvdWxkIHRocm93JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0ge1xuICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiB7Zm9vOiB7dHlwZTogJ2RvbmtleSd9fSxcbiAgICAgICAgICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgZXhwZWN0KCgpID0+IGdldEFyZ3Moe2V4dFR5cGUsIGV4dE5hbWUsIHNjaGVtYX0pKS50by50aHJvdyhcbiAgICAgICAgICAgICAgRXJyb3IsXG4gICAgICAgICAgICAgIC9zY2hlbWEgaXMgaW52YWxpZC8sXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnYXBwaXVtQ2xpQWxpYXNlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IHJlc3VsdDtcblxuICAgICAgICBpdCgnc2hvdWxkIG5vdCBhbGxvdyBzaG9ydCBhbGlhc2VzIGZvciBleHRlbnNpb25zJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgZm9vOiB7dHlwZTogJ3N0cmluZycsIGFwcGl1bUNsaUFsaWFzZXM6IFsnZm9vb29vJywgJ0YnXX0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICAgICAgfTtcbiAgICAgICAgICByZXN1bHQgPSBnZXRBcmdzKHtzY2hlbWEsIGV4dE5hbWUsIGV4dFR5cGV9KTtcbiAgICAgICAgICBleHBlY3QocmVzdWx0KS50by5oYXZlLnByb3BlcnR5KFxuICAgICAgICAgICAgJy0tcGx1Z2luLWJsb2ItZm9vLC0tcGx1Z2luLWJsb2ItZm9vb29vLC0tcGx1Z2luLWJsb2ItRicsXG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ2FwcGl1bUNsaURlc2NyaXB0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgcmVzdWx0O1xuXG4gICAgICAgIGl0KCdzaG91bGQgYmUgcHJlZmVycmVkIG92ZXIgYGRlc2NyaXB0aW9uYCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBzY2hlbWEgPSB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgIGZvbzoge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgICAgICAgIGFwcGl1bUNsaURlc2NyaXB0aW9uOiAnZm9vJyxcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ2JhcicsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICAgICAgfTtcbiAgICAgICAgICByZXN1bHQgPSBnZXRBcmdzKHtzY2hlbWEsIGV4dE5hbWUsIGV4dFR5cGV9KTtcbiAgICAgICAgICBleHBlY3QocmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddKS50by5oYXZlLnByb3BlcnR5KCdoZWxwJywgJ2ZvbycpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBkZXNjcmliZSgnYXBwaXVtQ2xpVHJhbnNmb3JtZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxldCByZXN1bHQ7XG5cbiAgICAgICAgaXQoJ3Nob3VsZCB1c2UgdGhlIHRyYW5zZm9ybWVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgICAgICAgIHByb3BlcnRpZXM6IHtmb286IHt0eXBlOiAnc3RyaW5nJywgYXBwaXVtQ2xpVHJhbnNmb3JtZXI6ICdqc29uJ319LFxuICAgICAgICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICAgICAgfTtcbiAgICAgICAgICByZXN1bHQgPSBnZXRBcmdzKHtzY2hlbWEsIGV4dE5hbWUsIGV4dFR5cGV9KTtcbiAgICAgICAgICBleHBlY3QocmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddLnR5cGUoJ3tcImhlcnBcIjogXCJkZXJwXCJ9JykpLnRvLmVxbCh7XG4gICAgICAgICAgICBoZXJwOiAnZGVycCcsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCdzaG91bGQgZXJyb3IgaWYgdGhlIHZhbHVlIGlzIG5vdCB2YWxpZCBmb3IgdGhlIHRyYW5zZm9ybWVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHtcbiAgICAgICAgICAgIHByb3BlcnRpZXM6IHtmb286IHt0eXBlOiAnc3RyaW5nJywgYXBwaXVtQ2xpVHJhbnNmb3JtZXI6ICdqc29uJ319LFxuICAgICAgICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICAgICAgfTtcbiAgICAgICAgICByZXN1bHQgPSBnZXRBcmdzKHtzY2hlbWEsIGV4dE5hbWUsIGV4dFR5cGV9KTtcbiAgICAgICAgICBleHBlY3QoKCkgPT4gcmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddLnR5cGUoJzEyMycpKS50by50aHJvdyhcbiAgICAgICAgICAgIC9tdXN0IGJlIGEgdmFsaWQganNvbi9pLFxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIHRoaXMgaXMgdW5saWtlbHkgdG8gaGFwcGVuLCBidXQgSSB3YW50IHRvIGVzdGFibGlzaCB0aGUgYmVoYXZpb3IgYXMgZGVmaW5lZC5cbiAgICAgICAgZGVzY3JpYmUoJ3doZW4gdXNlZCB3aXRoIGBlbnVtYCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBkZXNjcmliZSgnYW5kIGVudW0gbWVtYmVycyBhcmUgaW52YWxpZCBhcyBwZXIgdGhlIHRyYW5zZm9ybWVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZGVzY3JpYmUoJ3doZW4gcHJvdmlkZWQgYW4gZW51bSBtZW1iZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIGl0KCdzaG91bGQgdGhyb3cnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0ge1xuICAgICAgICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgICAgICBmb286IHtcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICAgICAgICAgICAgICBhcHBpdW1DbGlUcmFuc2Zvcm1lcjogJ2pzb24nLFxuICAgICAgICAgICAgICAgICAgICAgIGVudW06IFsnaGVycCcsICdkZXJwJ10sXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBnZXRBcmdzKHtzY2hlbWEsIGV4dE5hbWUsIGV4dFR5cGV9KTtcbiAgICAgICAgICAgICAgICBleHBlY3QoKCkgPT4gcmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddLnR5cGUoJ2hlcnAnKSkudG8udGhyb3coXG4gICAgICAgICAgICAgICAgICAvbXVzdCBiZSBhIHZhbGlkIGpzb24vaSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgZGVzY3JpYmUoJ2FuZCBlbnVtIG1lbWJlcnMgYXJlIHZhbGlkIGFzIHBlciB0aGUgdHJhbnNmb3JtZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBkZXNjcmliZSgnd2hlbiBwcm92aWRlZCBhbiBlbnVtIG1lbWJlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgaXQoJ3Nob3VsZCByZXR1cm4gYSB0cmFuc2Zvcm1lZCB2YWx1ZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB7XG4gICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgICAgICAgIGZvbzoge1xuICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgICAgICAgICAgICAgIGFwcGl1bUNsaVRyYW5zZm9ybWVyOiAnanNvbicsXG4gICAgICAgICAgICAgICAgICAgICAgZW51bTogWyd7XCJoZXJwXCI6IFwiZGVycFwifScsICd7XCJkZXJwXCI6IFwiaGVycFwifSddLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gZ2V0QXJncyh7c2NoZW1hLCBleHROYW1lLCBleHRUeXBlfSk7XG4gICAgICAgICAgICAgICAgZXhwZWN0KFxuICAgICAgICAgICAgICAgICAgcmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddLnR5cGUoJ3tcImhlcnBcIjogXCJkZXJwXCJ9JyksXG4gICAgICAgICAgICAgICAgKS50by5lcWwoe2hlcnA6ICdkZXJwJ30pO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBkZXNjcmliZSgnd2hlbiBub3QgcHJvdmlkZWQgYW4gZW51bSBtZW1iZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIGl0KCdzaG91bGQgdGhyb3cnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2NoZW1hID0ge1xuICAgICAgICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgICAgICBmb286IHtcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICAgICAgICAgICAgICBhcHBpdW1DbGlUcmFuc2Zvcm1lcjogJ2pzb24nLFxuICAgICAgICAgICAgICAgICAgICAgIGVudW06IFsne1wiaGVycFwiOiBcImRlcnBcIn0nLCAne1wiZGVycFwiOiBcImhlcnBcIn0nXSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHJlc3VsdCA9IGdldEFyZ3Moe3NjaGVtYSwgZXh0TmFtZSwgZXh0VHlwZX0pO1xuICAgICAgICAgICAgICAgIGV4cGVjdCgoKSA9PlxuICAgICAgICAgICAgICAgICAgcmVzdWx0WyctLXBsdWdpbi1ibG9iLWZvbyddLnR5cGUoJ3tcImdlb3JneVwiOiBcInBvcmd5XCJ9JyksXG4gICAgICAgICAgICAgICAgKS50by50aHJvdygvb25lIG9mIHRoZSBhbGxvd2VkIHZhbHVlcy9pKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ2VudW0nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRlc2NyaWJlKCd3aGVuIHVzZWQgd2l0aCBhIG5vbi1gc3RyaW5nYCB0eXBlJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGl0KCdzaG91bGQgdGhyb3cnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB7XG4gICAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICBmb286IHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdudW1iZXInLFxuICAgICAgICAgICAgICAgICAgZW51bTogWydoZXJwJywgJ2RlcnAnXSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBleHBlY3QoKCkgPT4gZ2V0QXJncyh7c2NoZW1hLCBleHROYW1lLCBleHRUeXBlfSkpLnRvLnRocm93KFxuICAgICAgICAgICAgICBUeXBlRXJyb3IsXG4gICAgICAgICAgICAgIC9gZW51bWAgaXMgb25seSBzdXBwb3J0ZWQgZm9yIGB0eXBlOiAnc3RyaW5nJ2AvaSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpdChcbiAgICAgICAgICAgICdzaG91bGQgYWN0dWFsbHkgdGhyb3cgZWFybGllciBieSBmYWlsaW5nIHNjaGVtYSB2YWxpZGF0aW9uLCBidXQgdGhhdCB3b3VsZCBtZWFuIG92ZXJyaWRpbmcgdGhlIGJlaGF2aW9yIG9mIGBlbnVtYCB3aGljaCBzb3VuZHMgaW5hZHZpc2FibGUnLFxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRlc2NyaWJlKCd3aGVuIHVzZWQgd2l0aCBhIGBzdHJpbmdgIHR5cGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaXQoJ3Nob3VsZCBzZXQgYGNob2ljZXNgIHByb3AnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBzY2hlbWEgPSB7XG4gICAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICBmb286IHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgICAgICAgICAgZW51bTogWydoZXJwJywgJ2RlcnAnXSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBnZXRBcmdzKHtzY2hlbWEsIGV4dE5hbWUsIGV4dFR5cGV9KTtcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10pLnRvLmhhdmUuZGVlcC5wcm9wZXJ0eShcbiAgICAgICAgICAgICAgJ2Nob2ljZXMnLFxuICAgICAgICAgICAgICBbJ2hlcnAnLCAnZGVycCddLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZGVzY3JpYmUoJ292ZXJyaWRlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gdGhpcyBtaWdodCBiZSBiZXR0ZXIgc29tZSBvdGhlciB3YXksIElESy4gIEkgc3VzcGVjdCB0aGlzIHdpbGwgYmUgcmFyZWx5IHVzZWQuXG4gICAgICAgIC8vIHNpbmNlIGV4dGVuc2lvbnMgY2FuJ3QgYWN0dWFsbHkgY2FsbCBgdG9QYXJzZXJBcmdzKClgLCB0aGV5IGNhbid0IHNldCBgb3ZlcnJpZGVzYCBhbnl3YXkuXG4gICAgICAgIGl0KCdzaG91bGQgc2V0IHRoZW0gdmlhIFwiZGVzdFwiIGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBjb25zdCBzY2hlbWEgPSB7XG4gICAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgIGZvbzoge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICAgIH07XG5cbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBnZXRBcmdzKHtcbiAgICAgICAgICAgIHNjaGVtYSxcbiAgICAgICAgICAgIGV4dE5hbWUsXG4gICAgICAgICAgICBleHRUeXBlLFxuICAgICAgICAgICAgb3ZlcnJpZGVzOiB7J3BsdWdpbi5ibG9iLmZvbyc6IHtlbnVtOiBbJ3NsdWcnLCAnc25haWwnXX19LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGV4cGVjdChyZXN1bHRbJy0tcGx1Z2luLWJsb2ItZm9vJ10pLnRvLmhhdmUuZGVlcC5wcm9wZXJ0eSgnZW51bScsIFtcbiAgICAgICAgICAgICdzbHVnJyxcbiAgICAgICAgICAgICdzbmFpbCcsXG4gICAgICAgICAgXSk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXSwiZmlsZSI6InRlc3Qvc2NoZW1hL2NsaS1hcmdzLXNwZWNzLmpzIiwic291cmNlUm9vdCI6Ii4uLy4uLy4uIn0=